summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile71
-rw-r--r--lib/Makefile.inc3
-rw-r--r--lib/compat/Makefile22
-rw-r--r--lib/compat/Makefile.inc3
-rw-r--r--lib/compat/compat1x/Makefile28
-rw-r--r--lib/compat/compat1x/libc.so.1.1.gz.uu3921
-rw-r--r--lib/compat/compat1x/libcurses.so.1.1.gz.uu428
-rw-r--r--lib/compat/compat1x/libf2c.so.1.1.gz.uu787
-rw-r--r--lib/compat/compat1x/libg++.so.1.1.gz.uu3530
-rw-r--r--lib/compat/compat1x/libgcc.so.1.1.gz.uu133
-rw-r--r--lib/compat/compat1x/libgnumalloc.so.1.1.gz.uu142
-rw-r--r--lib/compat/compat1x/libgnuregex.so.1.1.gz.uu270
-rw-r--r--lib/compat/compat1x/libln.so.1.1.gz.uu13
-rw-r--r--lib/compat/compat1x/libm.so.1.1.gz.uu538
-rw-r--r--lib/compat/compat1x/libmalloc.so.1.1.gz.uu183
-rw-r--r--lib/compat/compat1x/libreadline.so.1.1.gz.uu1117
-rw-r--r--lib/compat/compat1x/libresolv.so.1.1.gz.uu153
-rw-r--r--lib/compat/compat1x/librpcsvc.so.1.1.gz.uu165
-rw-r--r--lib/compat/compat1x/libskey.so.1.1.gz.uu247
-rw-r--r--lib/compat/compat1x/libtelnet.so.1.1.gz.uu63
-rw-r--r--lib/compat/compat1x/libtermcap.so.1.1.gz.uu75
-rw-r--r--lib/compat/compat1x/libutil.so.1.1.gz.uu208
-rw-r--r--lib/compat/compat1x/liby.so.1.1.gz.uu18
-rw-r--r--lib/compat/compat20/Makefile25
-rw-r--r--lib/compat/compat20/ld.so.gz.uu702
-rw-r--r--lib/compat/compat20/libdialog.so.2.0.gz.uu486
-rw-r--r--lib/compat/compat20/libforms.so.2.0.gz.uu78
-rw-r--r--lib/compat/compat20/libg++.so.2.0.gz.uu4306
-rw-r--r--lib/compat/compat20/libgcc.so.261.0.gz.uu174
-rw-r--r--lib/compat/compat20/libncurses.so.2.0.gz.uu562
-rw-r--r--lib/compat/compat20/libreadline.so.2.0.gz.uu1199
-rw-r--r--lib/compat/compat21/Makefile24
-rw-r--r--lib/compat/compat21/ld.so.gz.uu702
-rw-r--r--lib/compat/compat21/libc.so.2.2.gz.uu4566
-rw-r--r--lib/compat/compat21/libg++.so.3.0.gz.uu4253
-rw-r--r--lib/compat/compat21/libgmp.so.2.0.gz.uu426
-rw-r--r--lib/compat/compat22/Makefile38
-rw-r--r--lib/compat/compat22/ld.so.gz.uu702
-rw-r--r--lib/compat/compat22/libalias.so.2.4.gz.uu218
-rw-r--r--lib/compat/compat22/libc.so.3.1.gz.uu4571
-rw-r--r--lib/compat/compat22/libc_r.so.3.0.gz.uu5062
-rw-r--r--lib/compat/compat22/libcalendar.so.2.0.gz.uu44
-rw-r--r--lib/compat/compat22/libcom_err.so.2.0.gz.uu47
-rw-r--r--lib/compat/compat22/libcurses.so.2.0.gz.uu401
-rw-r--r--lib/compat/compat22/libdialog.so.3.1.gz.uu809
-rw-r--r--lib/compat/compat22/libedit.so.2.0.gz.uu681
-rw-r--r--lib/compat/compat22/libf2c.so.2.0.gz.uu714
-rw-r--r--lib/compat/compat22/libftpio.so.4.0.gz.uu137
-rw-r--r--lib/compat/compat22/libg++.so.4.0.gz.uu2472
-rw-r--r--lib/compat/compat22/libgmp.so.3.0.gz.uu975
-rw-r--r--lib/compat/compat22/libgnuregex.so.2.0.gz.uu252
-rw-r--r--lib/compat/compat22/libipx.so.2.0.gz.uu41
-rw-r--r--lib/compat/compat22/libkvm.so.2.0.gz.uu156
-rw-r--r--lib/compat/compat22/libm.so.2.0.gz.uu1018
-rw-r--r--lib/compat/compat22/libmp.so.3.0.gz.uu456
-rw-r--r--lib/compat/compat22/libmytinfo.so.2.0.gz.uu659
-rw-r--r--lib/compat/compat22/libncurses.so.3.1.gz.uu573
-rw-r--r--lib/compat/compat22/libopie.so.2.0.gz.uu339
-rw-r--r--lib/compat/compat22/libpcap.so.2.2.gz.uu640
-rw-r--r--lib/compat/compat22/libreadline.so.3.0.gz.uu1225
-rw-r--r--lib/compat/compat22/librpcsvc.so.2.0.gz.uu127
-rw-r--r--lib/compat/compat22/libscrypt.so.2.0.gz.uu63
-rw-r--r--lib/compat/compat22/libscsi.so.2.0.gz.uu128
-rw-r--r--lib/compat/compat22/libskey.so.2.0.gz.uu247
-rw-r--r--lib/compat/compat22/libss.so.2.0.gz.uu143
-rw-r--r--lib/compat/compat22/libstdc++.so.2.0.gz.uu1885
-rw-r--r--lib/compat/compat22/libtelnet.so.2.0.gz.uu39
-rw-r--r--lib/compat/compat22/libtermcap.so.2.1.gz.uu138
-rw-r--r--lib/compat/compat22/libutil.so.2.2.gz.uu249
-rw-r--r--lib/compat/compat22/libvgl.so.1.0.gz.uu198
-rw-r--r--lib/compat/compat22/libxpg4.so.2.0.gz.uu102
-rw-r--r--lib/compat/compat22/libz.so.2.0.gz.uu465
-rw-r--r--lib/compat/compat3x.i386/Makefile24
-rw-r--r--lib/compat/compat3x.i386/libf2c.so.2.gz.uu791
-rw-r--r--lib/compat/compat3x.i386/libg++.so.4.gz.uu2613
-rw-r--r--lib/compat/compat3x.i386/libstdc++.so.2.gz.uu1981
-rw-r--r--lib/csu/alpha/Makefile26
-rw-r--r--lib/csu/alpha/crt1.c103
-rw-r--r--lib/csu/alpha/crtbegin.c77
-rw-r--r--lib/csu/alpha/crtend.c31
-rw-r--r--lib/csu/amd64/Makefile27
-rw-r--r--lib/csu/amd64/crt1.c102
-rw-r--r--lib/csu/amd64/crti.S38
-rw-r--r--lib/csu/amd64/crtn.S32
-rw-r--r--lib/csu/common/crtbegin.c59
-rw-r--r--lib/csu/common/crtend.c33
-rw-r--r--lib/csu/i386-elf/Makefile27
-rw-r--r--lib/csu/i386-elf/crt1.c102
-rw-r--r--lib/csu/i386-elf/crtbegin.c59
-rw-r--r--lib/csu/i386-elf/crtend.c33
-rw-r--r--lib/csu/i386-elf/crti.S38
-rw-r--r--lib/csu/i386-elf/crtn.S32
-rw-r--r--lib/csu/i386/Makefile58
-rw-r--r--lib/csu/i386/c++rt0.c107
-rw-r--r--lib/csu/i386/crt0.c359
-rw-r--r--lib/libalias/HISTORY134
-rw-r--r--lib/libalias/Makefile15
-rw-r--r--lib/libalias/alias.c1335
-rw-r--r--lib/libalias/alias.h166
-rw-r--r--lib/libalias/alias_cuseeme.c120
-rw-r--r--lib/libalias/alias_db.c2394
-rw-r--r--lib/libalias/alias_ftp.c231
-rw-r--r--lib/libalias/alias_irc.c318
-rw-r--r--lib/libalias/alias_local.h172
-rw-r--r--lib/libalias/alias_nbt.c711
-rw-r--r--lib/libalias/alias_proxy.c807
-rw-r--r--lib/libalias/alias_util.c141
-rw-r--r--lib/libalias/libalias.3884
-rw-r--r--lib/libatm/Makefile40
-rw-r--r--lib/libatm/atm_addr.c328
-rw-r--r--lib/libatm/cache_key.c114
-rw-r--r--lib/libatm/ioctl_subr.c481
-rw-r--r--lib/libatm/ip_addr.c168
-rw-r--r--lib/libatm/ip_checksum.c100
-rw-r--r--lib/libatm/libatm.h119
-rw-r--r--lib/libatm/timer.c263
-rw-r--r--lib/libbind/Makefile88
-rw-r--r--lib/libc/Makefile44
-rw-r--r--lib/libc/Makefile.inc56
-rw-r--r--lib/libc/alpha/Makefile.inc9
-rw-r--r--lib/libc/alpha/SYS.h130
-rw-r--r--lib/libc/alpha/gen/Makefile.inc45
-rw-r--r--lib/libc/alpha/gen/_setjmp.S123
-rw-r--r--lib/libc/alpha/gen/divrem.m4197
-rw-r--r--lib/libc/alpha/gen/fabs.S35
-rw-r--r--lib/libc/alpha/gen/flt_rounds.c57
-rw-r--r--lib/libc/alpha/gen/fpgetmask.c49
-rw-r--r--lib/libc/alpha/gen/fpgetround.c48
-rw-r--r--lib/libc/alpha/gen/fpgetsticky.c48
-rw-r--r--lib/libc/alpha/gen/fpsetmask.c51
-rw-r--r--lib/libc/alpha/gen/fpsetround.c55
-rw-r--r--lib/libc/alpha/gen/fpsetsticky.c55
-rw-r--r--lib/libc/alpha/gen/frexp.c53
-rw-r--r--lib/libc/alpha/gen/infinity.c33
-rw-r--r--lib/libc/alpha/gen/isinf.c52
-rw-r--r--lib/libc/alpha/gen/ldexp.c134
-rw-r--r--lib/libc/alpha/gen/modf.c104
-rw-r--r--lib/libc/alpha/gen/setjmp.S127
-rw-r--r--lib/libc/alpha/gen/sigsetjmp.S62
-rw-r--r--lib/libc/alpha/net/Makefile.inc3
-rw-r--r--lib/libc/alpha/net/byte_swap_2.S47
-rw-r--r--lib/libc/alpha/net/byte_swap_4.S53
-rw-r--r--lib/libc/alpha/net/htonl.S32
-rw-r--r--lib/libc/alpha/net/htons.S32
-rw-r--r--lib/libc/alpha/net/ntohl.S32
-rw-r--r--lib/libc/alpha/net/ntohs.S32
-rw-r--r--lib/libc/alpha/stdlib/Makefile.inc3
-rw-r--r--lib/libc/alpha/string/Makefile.inc3
-rw-r--r--lib/libc/alpha/string/bcopy.S288
-rw-r--r--lib/libc/alpha/string/bzero.S110
-rw-r--r--lib/libc/alpha/string/ffs.S91
-rw-r--r--lib/libc/alpha/string/memcpy.S4
-rw-r--r--lib/libc/alpha/string/memmove.S4
-rw-r--r--lib/libc/alpha/sys/Makefile.inc17
-rw-r--r--lib/libc/alpha/sys/Ovfork.S35
-rw-r--r--lib/libc/alpha/sys/brk.S50
-rw-r--r--lib/libc/alpha/sys/cerror.S54
-rw-r--r--lib/libc/alpha/sys/exect.S35
-rw-r--r--lib/libc/alpha/sys/fork.S35
-rw-r--r--lib/libc/alpha/sys/pipe.S37
-rw-r--r--lib/libc/alpha/sys/ptrace.S37
-rw-r--r--lib/libc/alpha/sys/sbrk.S50
-rw-r--r--lib/libc/alpha/sys/setlogin.S37
-rw-r--r--lib/libc/alpha/sys/sigreturn.S38
-rw-r--r--lib/libc/alpha/sys/syscall.S32
-rw-r--r--lib/libc/amd64/SYS.h92
-rw-r--r--lib/libc/amd64/gen/Makefile.inc5
-rw-r--r--lib/libc/amd64/gen/_setjmp.S84
-rw-r--r--lib/libc/amd64/gen/frexp.c67
-rw-r--r--lib/libc/amd64/gen/infinity.c9
-rw-r--r--lib/libc/amd64/gen/isinf.c68
-rw-r--r--lib/libc/amd64/gen/ldexp.c74
-rw-r--r--lib/libc/amd64/gen/setjmp.S115
-rw-r--r--lib/libc/amd64/gen/sigsetjmp.S126
-rw-r--r--lib/libc/amd64/net/Makefile.inc4
-rw-r--r--lib/libc/amd64/net/htonl.S53
-rw-r--r--lib/libc/amd64/net/htons.S51
-rw-r--r--lib/libc/amd64/net/ntohl.S53
-rw-r--r--lib/libc/amd64/net/ntohs.S51
-rw-r--r--lib/libc/amd64/sys/Makefile.inc28
-rw-r--r--lib/libc/amd64/sys/brk.S91
-rw-r--r--lib/libc/amd64/sys/cerror.S70
-rw-r--r--lib/libc/amd64/sys/exect.S56
-rw-r--r--lib/libc/amd64/sys/pipe.S51
-rw-r--r--lib/libc/amd64/sys/ptrace.S62
-rw-r--r--lib/libc/amd64/sys/reboot.S47
-rw-r--r--lib/libc/amd64/sys/sbrk.S95
-rw-r--r--lib/libc/amd64/sys/setlogin.S59
-rw-r--r--lib/libc/amd64/sys/sigreturn.S52
-rw-r--r--lib/libc/amd64/sys/vfork.S72
-rw-r--r--lib/libc/compat-43/Makefile.inc16
-rw-r--r--lib/libc/compat-43/creat.262
-rw-r--r--lib/libc/compat-43/creat.c50
-rw-r--r--lib/libc/compat-43/gethostid.376
-rw-r--r--lib/libc/compat-43/gethostid.c59
-rw-r--r--lib/libc/compat-43/getwd.c54
-rw-r--r--lib/libc/compat-43/killpg.297
-rw-r--r--lib/libc/compat-43/killpg.c59
-rw-r--r--lib/libc/compat-43/sethostid.c57
-rw-r--r--lib/libc/compat-43/setpgrp.c50
-rw-r--r--lib/libc/compat-43/setrgid.c50
-rw-r--r--lib/libc/compat-43/setruid.380
-rw-r--r--lib/libc/compat-43/setruid.c50
-rw-r--r--lib/libc/compat-43/sigblock.285
-rw-r--r--lib/libc/compat-43/sigcompat.c111
-rw-r--r--lib/libc/compat-43/sigpause.275
-rw-r--r--lib/libc/compat-43/sigsetmask.283
-rw-r--r--lib/libc/compat-43/sigvec.2327
-rw-r--r--lib/libc/db/Makefile.inc11
-rw-r--r--lib/libc/db/README40
-rw-r--r--lib/libc/db/btree/Makefile.inc8
-rw-r--r--lib/libc/db/btree/bt_close.c182
-rw-r--r--lib/libc/db/btree/bt_conv.c221
-rw-r--r--lib/libc/db/btree/bt_debug.c329
-rw-r--r--lib/libc/db/btree/bt_delete.c657
-rw-r--r--lib/libc/db/btree/bt_get.c105
-rw-r--r--lib/libc/db/btree/bt_open.c445
-rw-r--r--lib/libc/db/btree/bt_overflow.c228
-rw-r--r--lib/libc/db/btree/bt_page.c100
-rw-r--r--lib/libc/db/btree/bt_put.c320
-rw-r--r--lib/libc/db/btree/bt_search.c213
-rw-r--r--lib/libc/db/btree/bt_seq.c460
-rw-r--r--lib/libc/db/btree/bt_split.c828
-rw-r--r--lib/libc/db/btree/bt_utils.c260
-rw-r--r--lib/libc/db/btree/btree.h383
-rw-r--r--lib/libc/db/btree/extern.h70
-rw-r--r--lib/libc/db/changelog103
-rw-r--r--lib/libc/db/db/Makefile.inc6
-rw-r--r--lib/libc/db/db/db.c99
-rw-r--r--lib/libc/db/docs/hash.usenix.ps12209
-rw-r--r--lib/libc/db/docs/libtp.usenix.ps12340
-rw-r--r--lib/libc/db/hash/Makefile.inc7
-rw-r--r--lib/libc/db/hash/README72
-rw-r--r--lib/libc/db/hash/extern.h65
-rw-r--r--lib/libc/db/hash/hash.c1001
-rw-r--r--lib/libc/db/hash/hash.h293
-rw-r--r--lib/libc/db/hash/hash_bigkey.c667
-rw-r--r--lib/libc/db/hash/hash_buf.c355
-rw-r--r--lib/libc/db/hash/hash_func.c212
-rw-r--r--lib/libc/db/hash/hash_log2.c54
-rw-r--r--lib/libc/db/hash/hash_page.c944
-rw-r--r--lib/libc/db/hash/hsearch.c107
-rw-r--r--lib/libc/db/hash/ndbm.c229
-rw-r--r--lib/libc/db/hash/page.h92
-rw-r--r--lib/libc/db/hash/search.h51
-rw-r--r--lib/libc/db/man/Makefile.inc10
-rw-r--r--lib/libc/db/man/btree.3234
-rw-r--r--lib/libc/db/man/dbopen.3477
-rw-r--r--lib/libc/db/man/hash.3160
-rw-r--r--lib/libc/db/man/mpool.3220
-rw-r--r--lib/libc/db/man/recno.3217
-rw-r--r--lib/libc/db/mpool/Makefile.inc6
-rw-r--r--lib/libc/db/mpool/README7
-rw-r--r--lib/libc/db/mpool/mpool.c463
-rw-r--r--lib/libc/db/mpool/mpool.libtp746
-rw-r--r--lib/libc/db/recno/Makefile.inc7
-rw-r--r--lib/libc/db/recno/extern.h54
-rw-r--r--lib/libc/db/recno/rec_close.c182
-rw-r--r--lib/libc/db/recno/rec_delete.c197
-rw-r--r--lib/libc/db/recno/rec_get.c311
-rw-r--r--lib/libc/db/recno/rec_open.c241
-rw-r--r--lib/libc/db/recno/rec_put.c279
-rw-r--r--lib/libc/db/recno/rec_search.c126
-rw-r--r--lib/libc/db/recno/rec_seq.c131
-rw-r--r--lib/libc/db/recno/rec_utils.c122
-rw-r--r--lib/libc/db/recno/recno.h39
-rw-r--r--lib/libc/db/test/Makefile23
-rw-r--r--lib/libc/db/test/README74
-rw-r--r--lib/libc/db/test/btree.tests/main.c765
-rw-r--r--lib/libc/db/test/dbtest.c753
-rw-r--r--lib/libc/db/test/hash.tests/driver2.c114
-rw-r--r--lib/libc/db/test/hash.tests/makedb.sh13
-rw-r--r--lib/libc/db/test/hash.tests/tcreat3.c105
-rw-r--r--lib/libc/db/test/hash.tests/tdel.c122
-rw-r--r--lib/libc/db/test/hash.tests/testit147
-rw-r--r--lib/libc/db/test/hash.tests/thash4.c132
-rw-r--r--lib/libc/db/test/hash.tests/tread2.c105
-rw-r--r--lib/libc/db/test/hash.tests/tseq.c88
-rw-r--r--lib/libc/db/test/hash.tests/tverify.c107
-rw-r--r--lib/libc/db/test/run.test705
-rw-r--r--lib/libc/gen/Makefile.inc121
-rw-r--r--lib/libc/gen/__xuname.c125
-rw-r--r--lib/libc/gen/_rand48.c46
-rw-r--r--lib/libc/gen/_spinlock_stub.c64
-rw-r--r--lib/libc/gen/alarm.396
-rw-r--r--lib/libc/gen/alarm.c59
-rw-r--r--lib/libc/gen/arc4random.384
-rw-r--r--lib/libc/gen/arc4random.c172
-rw-r--r--lib/libc/gen/assert.c52
-rw-r--r--lib/libc/gen/clock.369
-rw-r--r--lib/libc/gen/clock.c57
-rw-r--r--lib/libc/gen/closedir.c62
-rw-r--r--lib/libc/gen/confstr.3126
-rw-r--r--lib/libc/gen/confstr.c86
-rw-r--r--lib/libc/gen/crypt.3297
-rw-r--r--lib/libc/gen/crypt.c100
-rw-r--r--lib/libc/gen/ctermid.3107
-rw-r--r--lib/libc/gen/ctermid.c61
-rw-r--r--lib/libc/gen/daemon.380
-rw-r--r--lib/libc/gen/daemon.c71
-rw-r--r--lib/libc/gen/devname.369
-rw-r--r--lib/libc/gen/devname.c105
-rw-r--r--lib/libc/gen/directory.3198
-rw-r--r--lib/libc/gen/disklabel.c177
-rw-r--r--lib/libc/gen/dladdr.3121
-rw-r--r--lib/libc/gen/dlfcn.c168
-rw-r--r--lib/libc/gen/dlopen.3230
-rw-r--r--lib/libc/gen/drand48.c22
-rw-r--r--lib/libc/gen/erand48.c23
-rw-r--r--lib/libc/gen/err.3204
-rw-r--r--lib/libc/gen/err.c208
-rw-r--r--lib/libc/gen/errlst.c148
-rw-r--r--lib/libc/gen/exec.3291
-rw-r--r--lib/libc/gen/exec.c315
-rw-r--r--lib/libc/gen/fnmatch.3149
-rw-r--r--lib/libc/gen/fnmatch.c231
-rw-r--r--lib/libc/gen/frexp.386
-rw-r--r--lib/libc/gen/fstab.c256
-rw-r--r--lib/libc/gen/ftok.383
-rw-r--r--lib/libc/gen/ftok.c47
-rw-r--r--lib/libc/gen/fts-compat.c1112
-rw-r--r--lib/libc/gen/fts-compat.h128
-rw-r--r--lib/libc/gen/fts.3755
-rw-r--r--lib/libc/gen/fts.c1112
-rw-r--r--lib/libc/gen/getbootfile.370
-rw-r--r--lib/libc/gen/getbootfile.c55
-rw-r--r--lib/libc/gen/getbsize.380
-rw-r--r--lib/libc/gen/getbsize.c106
-rw-r--r--lib/libc/gen/getcap.3529
-rw-r--r--lib/libc/gen/getcap.c1046
-rw-r--r--lib/libc/gen/getcwd.3156
-rw-r--r--lib/libc/gen/getcwd.c288
-rw-r--r--lib/libc/gen/getdiskbyname.365
-rw-r--r--lib/libc/gen/getdomainname.399
-rw-r--r--lib/libc/gen/getdomainname.c61
-rw-r--r--lib/libc/gen/getfsent.3151
-rw-r--r--lib/libc/gen/getgrent.3205
-rw-r--r--lib/libc/gen/getgrent.c553
-rw-r--r--lib/libc/gen/getgrouplist.394
-rw-r--r--lib/libc/gen/getgrouplist.c91
-rw-r--r--lib/libc/gen/gethostname.398
-rw-r--r--lib/libc/gen/gethostname.c55
-rw-r--r--lib/libc/gen/getloadavg.367
-rw-r--r--lib/libc/gen/getloadavg.c71
-rw-r--r--lib/libc/gen/getlogin.c80
-rw-r--r--lib/libc/gen/getmntinfo.3110
-rw-r--r--lib/libc/gen/getmntinfo.c70
-rw-r--r--lib/libc/gen/getnetgrent.3129
-rw-r--r--lib/libc/gen/getnetgrent.c634
-rw-r--r--lib/libc/gen/getobjformat.3124
-rw-r--r--lib/libc/gen/getobjformat.c119
-rw-r--r--lib/libc/gen/getosreldate.c63
-rw-r--r--lib/libc/gen/getpagesize.361
-rw-r--r--lib/libc/gen/getpagesize.c61
-rw-r--r--lib/libc/gen/getpass.395
-rw-r--r--lib/libc/gen/getpass.c95
-rw-r--r--lib/libc/gen/getpwent.3219
-rw-r--r--lib/libc/gen/getpwent.c860
-rw-r--r--lib/libc/gen/getttyent.3210
-rw-r--r--lib/libc/gen/getttyent.c266
-rw-r--r--lib/libc/gen/getusershell.399
-rw-r--r--lib/libc/gen/getusershell.c139
-rw-r--r--lib/libc/gen/getvfsbyname.398
-rw-r--r--lib/libc/gen/getvfsbyname.c82
-rw-r--r--lib/libc/gen/getvfsent.3163
-rw-r--r--lib/libc/gen/getvfsent.c177
-rw-r--r--lib/libc/gen/glob.3447
-rw-r--r--lib/libc/gen/glob.c864
-rw-r--r--lib/libc/gen/initgroups.384
-rw-r--r--lib/libc/gen/initgroups.c60
-rw-r--r--lib/libc/gen/isatty.c63
-rw-r--r--lib/libc/gen/isinf.373
-rw-r--r--lib/libc/gen/jrand48.c21
-rw-r--r--lib/libc/gen/lcong48.c30
-rw-r--r--lib/libc/gen/ldexp.378
-rw-r--r--lib/libc/gen/lockf.34
-rw-r--r--lib/libc/gen/lockf.c10
-rw-r--r--lib/libc/gen/lrand48.c23
-rw-r--r--lib/libc/gen/modf.373
-rw-r--r--lib/libc/gen/mrand48.c23
-rw-r--r--lib/libc/gen/msgctl.3210
-rw-r--r--lib/libc/gen/msgctl.c15
-rw-r--r--lib/libc/gen/msgget.3137
-rw-r--r--lib/libc/gen/msgget.c14
-rw-r--r--lib/libc/gen/msgrcv.3209
-rw-r--r--lib/libc/gen/msgrcv.c17
-rw-r--r--lib/libc/gen/msgsnd.3164
-rw-r--r--lib/libc/gen/msgsnd.c16
-rw-r--r--lib/libc/gen/nice.370
-rw-r--r--lib/libc/gen/nice.c58
-rw-r--r--lib/libc/gen/nlist.379
-rw-r--r--lib/libc/gen/nlist.c413
-rw-r--r--lib/libc/gen/nrand48.c21
-rw-r--r--lib/libc/gen/ntp_gettime.c55
-rw-r--r--lib/libc/gen/opendir.c274
-rw-r--r--lib/libc/gen/pause.384
-rw-r--r--lib/libc/gen/pause.c49
-rw-r--r--lib/libc/gen/popen.3200
-rw-r--r--lib/libc/gen/popen.c189
-rw-r--r--lib/libc/gen/psignal.3110
-rw-r--r--lib/libc/gen/psignal.c63
-rw-r--r--lib/libc/gen/pw_scan.c165
-rw-r--r--lib/libc/gen/pw_scan.h40
-rw-r--r--lib/libc/gen/pwcache.395
-rw-r--r--lib/libc/gen/pwcache.c119
-rw-r--r--lib/libc/gen/raise.378
-rw-r--r--lib/libc/gen/raise.c46
-rw-r--r--lib/libc/gen/rand48.3161
-rw-r--r--lib/libc/gen/rand48.h30
-rw-r--r--lib/libc/gen/readdir.c125
-rw-r--r--lib/libc/gen/rewinddir.c50
-rw-r--r--lib/libc/gen/scandir.3107
-rw-r--r--lib/libc/gen/scandir.c146
-rw-r--r--lib/libc/gen/seed48.c36
-rw-r--r--lib/libc/gen/seekdir.c54
-rw-r--r--lib/libc/gen/semconfig.c13
-rw-r--r--lib/libc/gen/semctl.c42
-rw-r--r--lib/libc/gen/semget.c15
-rw-r--r--lib/libc/gen/semop.c15
-rw-r--r--lib/libc/gen/setdomainname.c57
-rw-r--r--lib/libc/gen/setflags.c174
-rw-r--r--lib/libc/gen/setflagsbyname.c174
-rw-r--r--lib/libc/gen/sethostname.c58
-rw-r--r--lib/libc/gen/setjmp.3174
-rw-r--r--lib/libc/gen/setjmperr.c53
-rw-r--r--lib/libc/gen/setmode.3116
-rw-r--r--lib/libc/gen/setmode.c457
-rw-r--r--lib/libc/gen/setproctitle.3101
-rw-r--r--lib/libc/gen/setproctitle.c162
-rw-r--r--lib/libc/gen/shmat.c19
-rw-r--r--lib/libc/gen/shmctl.c19
-rw-r--r--lib/libc/gen/shmdt.c17
-rw-r--r--lib/libc/gen/shmget.c19
-rw-r--r--lib/libc/gen/siginterrupt.3112
-rw-r--r--lib/libc/gen/siginterrupt.c62
-rw-r--r--lib/libc/gen/siglist.c110
-rw-r--r--lib/libc/gen/signal.3232
-rw-r--r--lib/libc/gen/signal.c60
-rw-r--r--lib/libc/gen/sigsetops.3114
-rw-r--r--lib/libc/gen/sigsetops.c108
-rw-r--r--lib/libc/gen/sleep.384
-rw-r--r--lib/libc/gen/sleep.c69
-rw-r--r--lib/libc/gen/srand48.c30
-rw-r--r--lib/libc/gen/stringlist.3122
-rw-r--r--lib/libc/gen/stringlist.c120
-rw-r--r--lib/libc/gen/strtofflags.c174
-rw-r--r--lib/libc/gen/sysconf.3187
-rw-r--r--lib/libc/gen/sysconf.c299
-rw-r--r--lib/libc/gen/sysctl.3746
-rw-r--r--lib/libc/gen/sysctl.c182
-rw-r--r--lib/libc/gen/sysctlbyname.c37
-rw-r--r--lib/libc/gen/syslog.3274
-rw-r--r--lib/libc/gen/syslog.c365
-rw-r--r--lib/libc/gen/tcgetpgrp.380
-rw-r--r--lib/libc/gen/tcsendbreak.3155
-rw-r--r--lib/libc/gen/tcsetattr.3331
-rw-r--r--lib/libc/gen/tcsetpgrp.3101
-rw-r--r--lib/libc/gen/telldir.c157
-rw-r--r--lib/libc/gen/termios.c245
-rw-r--r--lib/libc/gen/time.386
-rw-r--r--lib/libc/gen/time.c52
-rw-r--r--lib/libc/gen/times.3138
-rw-r--r--lib/libc/gen/times.c67
-rw-r--r--lib/libc/gen/timezone.368
-rw-r--r--lib/libc/gen/timezone.c135
-rw-r--r--lib/libc/gen/ttyname.3127
-rw-r--r--lib/libc/gen/ttyname.c222
-rw-r--r--lib/libc/gen/ttyslot.c68
-rw-r--r--lib/libc/gen/tzset.3326
-rw-r--r--lib/libc/gen/ualarm.399
-rw-r--r--lib/libc/gen/ualarm.c65
-rw-r--r--lib/libc/gen/uname.394
-rw-r--r--lib/libc/gen/uname.c125
-rw-r--r--lib/libc/gen/unvis.3164
-rw-r--r--lib/libc/gen/unvis.c247
-rw-r--r--lib/libc/gen/usleep.381
-rw-r--r--lib/libc/gen/usleep.c54
-rw-r--r--lib/libc/gen/utime.388
-rw-r--r--lib/libc/gen/utime.c57
-rw-r--r--lib/libc/gen/valloc.376
-rw-r--r--lib/libc/gen/valloc.c50
-rw-r--r--lib/libc/gen/vis.3265
-rw-r--r--lib/libc/gen/vis.c187
-rw-r--r--lib/libc/gen/wait.c48
-rw-r--r--lib/libc/gen/wait3.c50
-rw-r--r--lib/libc/gen/waitpid.c54
-rw-r--r--lib/libc/gmon/Makefile.inc17
-rw-r--r--lib/libc/gmon/gmon.c261
-rw-r--r--lib/libc/gmon/mcount.c325
-rw-r--r--lib/libc/gmon/moncontrol.3106
-rw-r--r--lib/libc/i386/DEFS.h41
-rw-r--r--lib/libc/i386/SYS.h92
-rw-r--r--lib/libc/i386/gen/Makefile.inc5
-rw-r--r--lib/libc/i386/gen/_setjmp.S84
-rw-r--r--lib/libc/i386/gen/alloca.S60
-rw-r--r--lib/libc/i386/gen/fabs.S49
-rw-r--r--lib/libc/i386/gen/frexp.c67
-rw-r--r--lib/libc/i386/gen/infinity.c9
-rw-r--r--lib/libc/i386/gen/isinf.c68
-rw-r--r--lib/libc/i386/gen/ldexp.c74
-rw-r--r--lib/libc/i386/gen/modf.S79
-rw-r--r--lib/libc/i386/gen/setjmp.S115
-rw-r--r--lib/libc/i386/gen/sigsetjmp.S126
-rw-r--r--lib/libc/i386/net/Makefile.inc4
-rw-r--r--lib/libc/i386/net/htonl.S53
-rw-r--r--lib/libc/i386/net/htons.S51
-rw-r--r--lib/libc/i386/net/ntohl.S53
-rw-r--r--lib/libc/i386/net/ntohs.S51
-rw-r--r--lib/libc/i386/stdlib/Makefile.inc4
-rw-r--r--lib/libc/i386/stdlib/abs.S51
-rw-r--r--lib/libc/i386/stdlib/div.S47
-rw-r--r--lib/libc/i386/stdlib/labs.S51
-rw-r--r--lib/libc/i386/stdlib/ldiv.S47
-rw-r--r--lib/libc/i386/string/Makefile.inc6
-rw-r--r--lib/libc/i386/string/bcmp.S70
-rw-r--r--lib/libc/i386/string/bcopy.S103
-rw-r--r--lib/libc/i386/string/bzero.S87
-rw-r--r--lib/libc/i386/string/ffs.S59
-rw-r--r--lib/libc/i386/string/index.S69
-rw-r--r--lib/libc/i386/string/memchr.S64
-rw-r--r--lib/libc/i386/string/memcmp.S81
-rw-r--r--lib/libc/i386/string/memcpy.S2
-rw-r--r--lib/libc/i386/string/memmove.S2
-rw-r--r--lib/libc/i386/string/memset.S95
-rw-r--r--lib/libc/i386/string/rindex.S70
-rw-r--r--lib/libc/i386/string/strcat.S106
-rw-r--r--lib/libc/i386/string/strchr.S69
-rw-r--r--lib/libc/i386/string/strcmp.S125
-rw-r--r--lib/libc/i386/string/strcpy.S95
-rw-r--r--lib/libc/i386/string/strlen.S59
-rw-r--r--lib/libc/i386/string/strncmp.S172
-rw-r--r--lib/libc/i386/string/strrchr.S70
-rw-r--r--lib/libc/i386/string/swab.S105
-rw-r--r--lib/libc/i386/sys/Makefile.inc28
-rw-r--r--lib/libc/i386/sys/Ovfork.S72
-rw-r--r--lib/libc/i386/sys/brk.S91
-rw-r--r--lib/libc/i386/sys/cerror.S70
-rw-r--r--lib/libc/i386/sys/exect.S56
-rw-r--r--lib/libc/i386/sys/fork.S51
-rw-r--r--lib/libc/i386/sys/i386_get_ioperm.284
-rw-r--r--lib/libc/i386/sys/i386_get_ioperm.c51
-rw-r--r--lib/libc/i386/sys/i386_get_ldt.298
-rw-r--r--lib/libc/i386/sys/i386_get_ldt.c49
-rw-r--r--lib/libc/i386/sys/i386_set_ioperm.c45
-rw-r--r--lib/libc/i386/sys/i386_set_ldt.c49
-rw-r--r--lib/libc/i386/sys/i386_vm86.296
-rw-r--r--lib/libc/i386/sys/i386_vm86.c44
-rw-r--r--lib/libc/i386/sys/pipe.S51
-rw-r--r--lib/libc/i386/sys/ptrace.S62
-rw-r--r--lib/libc/i386/sys/reboot.S47
-rw-r--r--lib/libc/i386/sys/rfork.S51
-rw-r--r--lib/libc/i386/sys/sbrk.S95
-rw-r--r--lib/libc/i386/sys/setlogin.S59
-rw-r--r--lib/libc/i386/sys/sigreturn.S52
-rw-r--r--lib/libc/i386/sys/syscall.S57
-rw-r--r--lib/libc/include/libc_private.h66
-rw-r--r--lib/libc/include/spinlock.h71
-rw-r--r--lib/libc/locale/Makefile.inc26
-rw-r--r--lib/libc/locale/ansi.c151
-rw-r--r--lib/libc/locale/big5.c120
-rw-r--r--lib/libc/locale/collate.c211
-rw-r--r--lib/libc/locale/collate.h67
-rw-r--r--lib/libc/locale/collcmp.c84
-rw-r--r--lib/libc/locale/ctype.3145
-rw-r--r--lib/libc/locale/euc.4242
-rw-r--r--lib/libc/locale/euc.5242
-rw-r--r--lib/libc/locale/euc.c223
-rw-r--r--lib/libc/locale/frune.c103
-rw-r--r--lib/libc/locale/isalnum.388
-rw-r--r--lib/libc/locale/isalpha.386
-rw-r--r--lib/libc/locale/isascii.359
-rw-r--r--lib/libc/locale/isblank.356
-rw-r--r--lib/libc/locale/iscntrl.376
-rw-r--r--lib/libc/locale/isctype.c233
-rw-r--r--lib/libc/locale/isdigit.371
-rw-r--r--lib/libc/locale/isgraph.388
-rw-r--r--lib/libc/locale/islower.375
-rw-r--r--lib/libc/locale/isprint.388
-rw-r--r--lib/libc/locale/ispunct.379
-rw-r--r--lib/libc/locale/isspace.371
-rw-r--r--lib/libc/locale/isupper.375
-rw-r--r--lib/libc/locale/isxdigit.374
-rw-r--r--lib/libc/locale/lconv.c70
-rw-r--r--lib/libc/locale/localeconv.c49
-rw-r--r--lib/libc/locale/mbrune.3158
-rw-r--r--lib/libc/locale/mbrune.c112
-rw-r--r--lib/libc/locale/mskanji.c107
-rw-r--r--lib/libc/locale/multibyte.3242
-rw-r--r--lib/libc/locale/nomacros.c9
-rw-r--r--lib/libc/locale/none.c91
-rw-r--r--lib/libc/locale/rune.3272
-rw-r--r--lib/libc/locale/rune.c173
-rw-r--r--lib/libc/locale/runetype.c64
-rw-r--r--lib/libc/locale/setinvalidrune.c44
-rw-r--r--lib/libc/locale/setlocale.3336
-rw-r--r--lib/libc/locale/setlocale.c321
-rw-r--r--lib/libc/locale/setlocale.h34
-rw-r--r--lib/libc/locale/setrunelocale.c140
-rw-r--r--lib/libc/locale/table.c162
-rw-r--r--lib/libc/locale/toascii.370
-rw-r--r--lib/libc/locale/tolower.389
-rw-r--r--lib/libc/locale/tolower.c60
-rw-r--r--lib/libc/locale/toupper.389
-rw-r--r--lib/libc/locale/toupper.c60
-rw-r--r--lib/libc/locale/utf2.488
-rw-r--r--lib/libc/locale/utf2.588
-rw-r--r--lib/libc/locale/utf2.c150
-rw-r--r--lib/libc/mips/:errfix5
-rw-r--r--lib/libc/mips/Makefile.inc4
-rw-r--r--lib/libc/mips/SYS.h80
-rw-r--r--lib/libc/mips/gen/Makefile.inc6
-rw-r--r--lib/libc/mips/gen/_setjmp.S132
-rw-r--r--lib/libc/mips/gen/fabs.S54
-rw-r--r--lib/libc/mips/gen/flt_rounds.c27
-rw-r--r--lib/libc/mips/gen/fpgetmask.c19
-rw-r--r--lib/libc/mips/gen/fpgetround.c19
-rw-r--r--lib/libc/mips/gen/fpgetsticky.c19
-rw-r--r--lib/libc/mips/gen/fpsetmask.c28
-rw-r--r--lib/libc/mips/gen/fpsetround.c28
-rw-r--r--lib/libc/mips/gen/fpsetsticky.c28
-rw-r--r--lib/libc/mips/gen/frexp.c73
-rw-r--r--lib/libc/mips/gen/infinity.c15
-rw-r--r--lib/libc/mips/gen/isinf.S95
-rw-r--r--lib/libc/mips/gen/ldexp.S217
-rw-r--r--lib/libc/mips/gen/modf.S75
-rw-r--r--lib/libc/mips/gen/setjmp.S128
-rw-r--r--lib/libc/mips/gen/sigsetjmp.S78
-rw-r--r--lib/libc/mips/net/Makefile.inc4
-rw-r--r--lib/libc/mips/net/htonl.S69
-rw-r--r--lib/libc/mips/net/htons.S65
-rw-r--r--lib/libc/mips/stdlib/Makefile.inc0
-rw-r--r--lib/libc/mips/string/Makefile.inc7
-rw-r--r--lib/libc/mips/string/bcmp.S120
-rw-r--r--lib/libc/mips/string/bcopy.S127
-rw-r--r--lib/libc/mips/string/bzero.S74
-rw-r--r--lib/libc/mips/string/ffs.S57
-rw-r--r--lib/libc/mips/string/index.S56
-rw-r--r--lib/libc/mips/string/rindex.S55
-rw-r--r--lib/libc/mips/string/strcmp.S66
-rw-r--r--lib/libc/mips/string/strlen.S53
-rw-r--r--lib/libc/mips/sys/Makefile.inc0
-rw-r--r--lib/libc/mips/sys/Ovfork.S63
-rw-r--r--lib/libc/mips/sys/brk.S81
-rw-r--r--lib/libc/mips/sys/cerror.S51
-rw-r--r--lib/libc/mips/sys/exect.S53
-rw-r--r--lib/libc/mips/sys/fork.S56
-rw-r--r--lib/libc/mips/sys/pipe.S56
-rw-r--r--lib/libc/mips/sys/ptrace.S54
-rw-r--r--lib/libc/mips/sys/sbrk.S64
-rw-r--r--lib/libc/mips/sys/setlogin.S55
-rw-r--r--lib/libc/mips/sys/sigpending.S55
-rw-r--r--lib/libc/mips/sys/sigprocmask.S63
-rw-r--r--lib/libc/mips/sys/sigreturn.S48
-rw-r--r--lib/libc/mips/sys/sigsuspend.S55
-rw-r--r--lib/libc/mips/sys/syscall.S47
-rw-r--r--lib/libc/mipseb/Makefile.inc1
-rw-r--r--lib/libc/mipseb/SYS.h80
-rw-r--r--lib/libc/mipseb/gen/Makefile.inc1
-rw-r--r--lib/libc/mipseb/net/Makefile.inc1
-rw-r--r--lib/libc/mipseb/stdlib/Makefile.inc1
-rw-r--r--lib/libc/mipseb/string/Makefile.inc1
-rw-r--r--lib/libc/mipseb/sys/Makefile.inc1
-rw-r--r--lib/libc/mipsel/Makefile.inc1
-rw-r--r--lib/libc/mipsel/SYS.h80
-rw-r--r--lib/libc/mipsel/gen/Makefile.inc1
-rw-r--r--lib/libc/mipsel/net/Makefile.inc1
-rw-r--r--lib/libc/mipsel/stdlib/Makefile.inc1
-rw-r--r--lib/libc/mipsel/string/Makefile.inc1
-rw-r--r--lib/libc/mipsel/sys/Makefile.inc1
-rw-r--r--lib/libc/net/Makefile.inc59
-rw-r--r--lib/libc/net/addr2ascii.3217
-rw-r--r--lib/libc/net/addr2ascii.c92
-rw-r--r--lib/libc/net/ascii2addr.c72
-rw-r--r--lib/libc/net/base64.c316
-rw-r--r--lib/libc/net/byteorder.377
-rw-r--r--lib/libc/net/ether_addr.c226
-rw-r--r--lib/libc/net/ethers.3192
-rw-r--r--lib/libc/net/gethostbydns.c773
-rw-r--r--lib/libc/net/gethostbyht.c202
-rw-r--r--lib/libc/net/gethostbyname.3305
-rw-r--r--lib/libc/net/gethostbynis.c145
-rw-r--r--lib/libc/net/gethostnamadr.c224
-rw-r--r--lib/libc/net/getnetbydns.c313
-rw-r--r--lib/libc/net/getnetbyht.c173
-rw-r--r--lib/libc/net/getnetbynis.c177
-rw-r--r--lib/libc/net/getnetent.3159
-rw-r--r--lib/libc/net/getnetnamadr.c190
-rw-r--r--lib/libc/net/getproto.c55
-rw-r--r--lib/libc/net/getprotoent.3147
-rw-r--r--lib/libc/net/getprotoent.c119
-rw-r--r--lib/libc/net/getprotoname.c62
-rw-r--r--lib/libc/net/getservbyname.c79
-rw-r--r--lib/libc/net/getservbyport.c74
-rw-r--r--lib/libc/net/getservent.3157
-rw-r--r--lib/libc/net/getservent.c278
-rw-r--r--lib/libc/net/herror.c109
-rw-r--r--lib/libc/net/if_indextoname.3142
-rw-r--r--lib/libc/net/ifname.c212
-rw-r--r--lib/libc/net/inet.3210
-rw-r--r--lib/libc/net/inet_addr.c196
-rw-r--r--lib/libc/net/inet_lnaof.c66
-rw-r--r--lib/libc/net/inet_makeaddr.c69
-rw-r--r--lib/libc/net/inet_net_ntop.c147
-rw-r--r--lib/libc/net/inet_net_pton.c214
-rw-r--r--lib/libc/net/inet_neta.c91
-rw-r--r--lib/libc/net/inet_netof.c65
-rw-r--r--lib/libc/net/inet_network.c99
-rw-r--r--lib/libc/net/inet_ntoa.c64
-rw-r--r--lib/libc/net/inet_ntop.c198
-rw-r--r--lib/libc/net/inet_pton.c221
-rw-r--r--lib/libc/net/ip6opt.c386
-rw-r--r--lib/libc/net/iso_addr.3111
-rw-r--r--lib/libc/net/iso_addr.c117
-rw-r--r--lib/libc/net/linkaddr.3138
-rw-r--r--lib/libc/net/linkaddr.c158
-rw-r--r--lib/libc/net/map_v4v6.c128
-rw-r--r--lib/libc/net/ns.3131
-rw-r--r--lib/libc/net/ns_addr.c227
-rw-r--r--lib/libc/net/ns_name.c593
-rw-r--r--lib/libc/net/ns_netint.c54
-rw-r--r--lib/libc/net/ns_ntoa.c100
-rw-r--r--lib/libc/net/ns_parse.c190
-rw-r--r--lib/libc/net/ns_print.c743
-rw-r--r--lib/libc/net/ns_ttl.c151
-rw-r--r--lib/libc/net/nsap_addr.c114
-rw-r--r--lib/libc/net/rcmd.3204
-rw-r--r--lib/libc/net/rcmd.c520
-rw-r--r--lib/libc/net/recv.c50
-rw-r--r--lib/libc/net/res_comp.c267
-rw-r--r--lib/libc/net/res_config.h8
-rw-r--r--lib/libc/net/res_data.c83
-rw-r--r--lib/libc/net/res_debug.c987
-rw-r--r--lib/libc/net/res_init.c492
-rw-r--r--lib/libc/net/res_mkquery.c206
-rw-r--r--lib/libc/net/res_mkupdate.c414
-rw-r--r--lib/libc/net/res_query.c421
-rw-r--r--lib/libc/net/res_send.c910
-rw-r--r--lib/libc/net/res_update.c516
-rw-r--r--lib/libc/net/resolver.3352
-rw-r--r--lib/libc/net/rthdr.c298
-rw-r--r--lib/libc/net/send.c50
-rw-r--r--lib/libc/net/vars.c42
-rw-r--r--lib/libc/nls/Makefile.inc10
-rw-r--r--lib/libc/nls/catclose.355
-rw-r--r--lib/libc/nls/catclose.c25
-rw-r--r--lib/libc/nls/catgets.368
-rw-r--r--lib/libc/nls/catgets.c28
-rw-r--r--lib/libc/nls/catopen.399
-rw-r--r--lib/libc/nls/catopen.c26
-rw-r--r--lib/libc/nls/msgcat.c451
-rw-r--r--lib/libc/nls/msgcat.h170
-rw-r--r--lib/libc/quad/Makefile.inc19
-rw-r--r--lib/libc/quad/TESTS/Makefile11
-rw-r--r--lib/libc/quad/TESTS/divrem.c78
-rw-r--r--lib/libc/quad/TESTS/mul.c74
-rw-r--r--lib/libc/quad/adddi3.c60
-rw-r--r--lib/libc/quad/anddi3.c58
-rw-r--r--lib/libc/quad/ashldi3.c66
-rw-r--r--lib/libc/quad/ashrdi3.c75
-rw-r--r--lib/libc/quad/cmpdi2.c59
-rw-r--r--lib/libc/quad/divdi3.c65
-rw-r--r--lib/libc/quad/fixdfdi.c62
-rw-r--r--lib/libc/quad/fixsfdi.c63
-rw-r--r--lib/libc/quad/fixunsdfdi.c96
-rw-r--r--lib/libc/quad/fixunssfdi.c100
-rw-r--r--lib/libc/quad/floatdidf.c74
-rw-r--r--lib/libc/quad/floatdisf.c76
-rw-r--r--lib/libc/quad/floatunsdidf.c59
-rw-r--r--lib/libc/quad/iordi3.c58
-rw-r--r--lib/libc/quad/lshldi3.c66
-rw-r--r--lib/libc/quad/lshrdi3.c65
-rw-r--r--lib/libc/quad/moddi3.c67
-rw-r--r--lib/libc/quad/muldi3.c246
-rw-r--r--lib/libc/quad/negdi2.c57
-rw-r--r--lib/libc/quad/notdi2.c58
-rw-r--r--lib/libc/quad/qdivrem.c279
-rw-r--r--lib/libc/quad/quad.h115
-rw-r--r--lib/libc/quad/subdi3.c59
-rw-r--r--lib/libc/quad/ucmpdi2.c58
-rw-r--r--lib/libc/quad/udivdi3.c53
-rw-r--r--lib/libc/quad/umoddi3.c55
-rw-r--r--lib/libc/quad/xordi3.c58
-rw-r--r--lib/libc/regex/COPYRIGHT56
-rw-r--r--lib/libc/regex/Makefile.inc17
-rw-r--r--lib/libc/regex/WHATSNEW94
-rw-r--r--lib/libc/regex/cclass.h62
-rw-r--r--lib/libc/regex/cname.h141
-rw-r--r--lib/libc/regex/engine.c1092
-rw-r--r--lib/libc/regex/re_format.7273
-rw-r--r--lib/libc/regex/regcomp.c1777
-rw-r--r--lib/libc/regex/regerror.c177
-rw-r--r--lib/libc/regex/regex.3541
-rw-r--r--lib/libc/regex/regex2.h173
-rw-r--r--lib/libc/regex/regexec.c181
-rw-r--r--lib/libc/regex/regfree.c80
-rw-r--r--lib/libc/regex/utils.h57
-rw-r--r--lib/libc/rpc/DISCLAIMER28
-rw-r--r--lib/libc/rpc/Makefile.inc119
-rw-r--r--lib/libc/rpc/PSD.doc/nfs.rfc.ms1372
-rw-r--r--lib/libc/rpc/PSD.doc/rpc.prog.ms2684
-rw-r--r--lib/libc/rpc/PSD.doc/rpc.rfc.ms1302
-rw-r--r--lib/libc/rpc/PSD.doc/rpcgen.ms1299
-rw-r--r--lib/libc/rpc/PSD.doc/xdr.nts.ms1966
-rw-r--r--lib/libc/rpc/PSD.doc/xdr.rfc.ms1058
-rw-r--r--lib/libc/rpc/README233
-rw-r--r--lib/libc/rpc/auth_des.c554
-rw-r--r--lib/libc/rpc/auth_none.c136
-rw-r--r--lib/libc/rpc/auth_time.c501
-rw-r--r--lib/libc/rpc/auth_unix.c349
-rw-r--r--lib/libc/rpc/authdes_prot.c82
-rw-r--r--lib/libc/rpc/authunix_prot.c68
-rw-r--r--lib/libc/rpc/bindresvport.332
-rw-r--r--lib/libc/rpc/bindresvport.c107
-rw-r--r--lib/libc/rpc/clnt_generic.c137
-rw-r--r--lib/libc/rpc/clnt_perror.c254
-rw-r--r--lib/libc/rpc/clnt_raw.c242
-rw-r--r--lib/libc/rpc/clnt_simple.c122
-rw-r--r--lib/libc/rpc/clnt_tcp.c580
-rw-r--r--lib/libc/rpc/clnt_udp.c567
-rw-r--r--lib/libc/rpc/clnt_unix.c635
-rw-r--r--lib/libc/rpc/crypt_client.c90
-rw-r--r--lib/libc/rpc/des_crypt.3128
-rw-r--r--lib/libc/rpc/des_crypt.c153
-rw-r--r--lib/libc/rpc/des_soft.c67
-rw-r--r--lib/libc/rpc/get_myaddress.c112
-rw-r--r--lib/libc/rpc/getpublickey.c172
-rw-r--r--lib/libc/rpc/getrpcent.398
-rw-r--r--lib/libc/rpc/getrpcent.c303
-rw-r--r--lib/libc/rpc/getrpcport.331
-rw-r--r--lib/libc/rpc/getrpcport.c63
-rw-r--r--lib/libc/rpc/key_call.c425
-rw-r--r--lib/libc/rpc/key_prot_xdr.c166
-rw-r--r--lib/libc/rpc/netname.c136
-rw-r--r--lib/libc/rpc/netnamer.c324
-rw-r--r--lib/libc/rpc/pmap_clnt.c149
-rw-r--r--lib/libc/rpc/pmap_getmaps.c86
-rw-r--r--lib/libc/rpc/pmap_getport.c91
-rw-r--r--lib/libc/rpc/pmap_prot.c59
-rw-r--r--lib/libc/rpc/pmap_prot2.c118
-rw-r--r--lib/libc/rpc/pmap_rmt.c415
-rw-r--r--lib/libc/rpc/publickey.346
-rw-r--r--lib/libc/rpc/publickey.537
-rw-r--r--lib/libc/rpc/rpc.31740
-rw-r--r--lib/libc/rpc/rpc.535
-rw-r--r--lib/libc/rpc/rpc_callmsg.c193
-rw-r--r--lib/libc/rpc/rpc_commondata.c43
-rw-r--r--lib/libc/rpc/rpc_dtablesize.c61
-rw-r--r--lib/libc/rpc/rpc_prot.c297
-rw-r--r--lib/libc/rpc/rpc_secure.3239
-rw-r--r--lib/libc/rpc/rpcdname.c77
-rw-r--r--lib/libc/rpc/rstat.158
-rw-r--r--lib/libc/rpc/rstat_svc.822
-rw-r--r--lib/libc/rpc/rtime.345
-rw-r--r--lib/libc/rpc/rtime.c157
-rw-r--r--lib/libc/rpc/svc.c494
-rw-r--r--lib/libc/rpc/svc_auth.c211
-rw-r--r--lib/libc/rpc/svc_auth_des.c531
-rw-r--r--lib/libc/rpc/svc_auth_unix.c148
-rw-r--r--lib/libc/rpc/svc_raw.c168
-rw-r--r--lib/libc/rpc/svc_run.c87
-rw-r--r--lib/libc/rpc/svc_simple.c150
-rw-r--r--lib/libc/rpc/svc_tcp.c484
-rw-r--r--lib/libc/rpc/svc_udp.c480
-rw-r--r--lib/libc/rpc/svc_unix.c530
-rw-r--r--lib/libc/stdio/Makefile.inc45
-rw-r--r--lib/libc/stdio/_flock_stub.c81
-rw-r--r--lib/libc/stdio/asprintf.c81
-rw-r--r--lib/libc/stdio/clrerr.c56
-rw-r--r--lib/libc/stdio/fclose.395
-rw-r--r--lib/libc/stdio/fclose.c76
-rw-r--r--lib/libc/stdio/fdopen.c89
-rw-r--r--lib/libc/stdio/feof.c57
-rw-r--r--lib/libc/stdio/ferror.3101
-rw-r--r--lib/libc/stdio/ferror.c57
-rw-r--r--lib/libc/stdio/fflush.3111
-rw-r--r--lib/libc/stdio/fflush.c101
-rw-r--r--lib/libc/stdio/fgetc.c57
-rw-r--r--lib/libc/stdio/fgetln.3125
-rw-r--r--lib/libc/stdio/fgetln.c165
-rw-r--r--lib/libc/stdio/fgetpos.c58
-rw-r--r--lib/libc/stdio/fgets.3157
-rw-r--r--lib/libc/stdio/fgets.c115
-rw-r--r--lib/libc/stdio/fileno.c57
-rw-r--r--lib/libc/stdio/findfp.c186
-rw-r--r--lib/libc/stdio/flags.c95
-rw-r--r--lib/libc/stdio/floatio.h46
-rw-r--r--lib/libc/stdio/fopen.3242
-rw-r--r--lib/libc/stdio/fopen.c84
-rw-r--r--lib/libc/stdio/fprintf.c73
-rw-r--r--lib/libc/stdio/fpurge.c74
-rw-r--r--lib/libc/stdio/fputc.c58
-rw-r--r--lib/libc/stdio/fputs.3108
-rw-r--r--lib/libc/stdio/fputs.c70
-rw-r--r--lib/libc/stdio/fread.3107
-rw-r--r--lib/libc/stdio/fread.c90
-rw-r--r--lib/libc/stdio/freopen.c164
-rw-r--r--lib/libc/stdio/fscanf.c77
-rw-r--r--lib/libc/stdio/fseek.3230
-rw-r--r--lib/libc/stdio/fseek.c269
-rw-r--r--lib/libc/stdio/fsetpos.c57
-rw-r--r--lib/libc/stdio/ftell.c114
-rw-r--r--lib/libc/stdio/funopen.3170
-rw-r--r--lib/libc/stdio/funopen.c81
-rw-r--r--lib/libc/stdio/fvwrite.c213
-rw-r--r--lib/libc/stdio/fvwrite.h56
-rw-r--r--lib/libc/stdio/fwalk.c64
-rw-r--r--lib/libc/stdio/fwrite.c79
-rw-r--r--lib/libc/stdio/getc.3137
-rw-r--r--lib/libc/stdio/getc.c62
-rw-r--r--lib/libc/stdio/getchar.c61
-rw-r--r--lib/libc/stdio/gets.c75
-rw-r--r--lib/libc/stdio/getw.c54
-rw-r--r--lib/libc/stdio/glue.h47
-rw-r--r--lib/libc/stdio/local.h87
-rw-r--r--lib/libc/stdio/makebuf.c118
-rw-r--r--lib/libc/stdio/mktemp.3216
-rw-r--r--lib/libc/stdio/mktemp.c196
-rw-r--r--lib/libc/stdio/perror.c67
-rw-r--r--lib/libc/stdio/printf.3661
-rw-r--r--lib/libc/stdio/printf.c72
-rw-r--r--lib/libc/stdio/putc.3133
-rw-r--r--lib/libc/stdio/putc.c63
-rw-r--r--lib/libc/stdio/putchar.c64
-rw-r--r--lib/libc/stdio/puts.c73
-rw-r--r--lib/libc/stdio/putw.c66
-rw-r--r--lib/libc/stdio/refill.c136
-rw-r--r--lib/libc/stdio/remove.379
-rw-r--r--lib/libc/stdio/remove.c53
-rw-r--r--lib/libc/stdio/rewind.c58
-rw-r--r--lib/libc/stdio/rget.c64
-rw-r--r--lib/libc/stdio/scanf.3440
-rw-r--r--lib/libc/stdio/scanf.c76
-rw-r--r--lib/libc/stdio/setbuf.3203
-rw-r--r--lib/libc/stdio/setbuf.c50
-rw-r--r--lib/libc/stdio/setbuffer.c66
-rw-r--r--lib/libc/stdio/setvbuf.c169
-rw-r--r--lib/libc/stdio/snprintf.c89
-rw-r--r--lib/libc/stdio/sprintf.c81
-rw-r--r--lib/libc/stdio/sscanf.c97
-rw-r--r--lib/libc/stdio/stdio.3291
-rw-r--r--lib/libc/stdio/stdio.c111
-rw-r--r--lib/libc/stdio/tempnam.c96
-rw-r--r--lib/libc/stdio/tmpfile.c80
-rw-r--r--lib/libc/stdio/tmpnam.3220
-rw-r--r--lib/libc/stdio/tmpnam.c65
-rw-r--r--lib/libc/stdio/ungetc.396
-rw-r--r--lib/libc/stdio/ungetc.c166
-rw-r--r--lib/libc/stdio/vasprintf.c65
-rw-r--r--lib/libc/stdio/vfprintf.c1278
-rw-r--r--lib/libc/stdio/vfscanf.c786
-rw-r--r--lib/libc/stdio/vprintf.c53
-rw-r--r--lib/libc/stdio/vscanf.c59
-rw-r--r--lib/libc/stdio/vsnprintf.c72
-rw-r--r--lib/libc/stdio/vsprintf.c64
-rw-r--r--lib/libc/stdio/vsscanf.c78
-rw-r--r--lib/libc/stdio/wbuf.c93
-rw-r--r--lib/libc/stdio/wsetup.c95
-rw-r--r--lib/libc/stdlib/Makefile.inc39
-rw-r--r--lib/libc/stdlib/abort.371
-rw-r--r--lib/libc/stdlib/abort.c85
-rw-r--r--lib/libc/stdlib/abs.375
-rw-r--r--lib/libc/stdlib/abs.c45
-rw-r--r--lib/libc/stdlib/alloca.379
-rw-r--r--lib/libc/stdlib/atexit.378
-rw-r--r--lib/libc/stdlib/atexit.c69
-rw-r--r--lib/libc/stdlib/atexit.h45
-rw-r--r--lib/libc/stdlib/atof.374
-rw-r--r--lib/libc/stdlib/atof.c46
-rw-r--r--lib/libc/stdlib/atoi.374
-rw-r--r--lib/libc/stdlib/atoi.c46
-rw-r--r--lib/libc/stdlib/atol.375
-rw-r--r--lib/libc/stdlib/atol.c46
-rw-r--r--lib/libc/stdlib/bsearch.391
-rw-r--r--lib/libc/stdlib/bsearch.c81
-rw-r--r--lib/libc/stdlib/calloc.c52
-rw-r--r--lib/libc/stdlib/div.368
-rw-r--r--lib/libc/stdlib/div.c79
-rw-r--r--lib/libc/stdlib/exit.396
-rw-r--r--lib/libc/stdlib/exit.c75
-rw-r--r--lib/libc/stdlib/getenv.3152
-rw-r--r--lib/libc/stdlib/getenv.c91
-rw-r--r--lib/libc/stdlib/getopt.3262
-rw-r--r--lib/libc/stdlib/getopt.c123
-rw-r--r--lib/libc/stdlib/getsubopt.3147
-rw-r--r--lib/libc/stdlib/getsubopt.c99
-rw-r--r--lib/libc/stdlib/heapsort.c183
-rw-r--r--lib/libc/stdlib/labs.367
-rw-r--r--lib/libc/stdlib/labs.c45
-rw-r--r--lib/libc/stdlib/ldiv.371
-rw-r--r--lib/libc/stdlib/ldiv.c58
-rw-r--r--lib/libc/stdlib/malloc.3448
-rw-r--r--lib/libc/stdlib/malloc.c1138
-rw-r--r--lib/libc/stdlib/memory.371
-rw-r--r--lib/libc/stdlib/merge.c350
-rw-r--r--lib/libc/stdlib/netbsd_strtod.c2517
-rw-r--r--lib/libc/stdlib/putenv.c58
-rw-r--r--lib/libc/stdlib/qsort.3236
-rw-r--r--lib/libc/stdlib/qsort.c178
-rw-r--r--lib/libc/stdlib/radixsort.3162
-rw-r--r--lib/libc/stdlib/radixsort.c318
-rw-r--r--lib/libc/stdlib/rand.3103
-rw-r--r--lib/libc/stdlib/rand.c105
-rw-r--r--lib/libc/stdlib/random.3190
-rw-r--r--lib/libc/stdlib/random.c494
-rw-r--r--lib/libc/stdlib/reallocf.c39
-rw-r--r--lib/libc/stdlib/realpath.3126
-rw-r--r--lib/libc/stdlib/realpath.c163
-rw-r--r--lib/libc/stdlib/setenv.c117
-rw-r--r--lib/libc/stdlib/strhash.c410
-rw-r--r--lib/libc/stdlib/strtod.3134
-rw-r--r--lib/libc/stdlib/strtod.c2443
-rw-r--r--lib/libc/stdlib/strtol.3169
-rw-r--r--lib/libc/stdlib/strtol.c131
-rw-r--r--lib/libc/stdlib/strtoll.c138
-rw-r--r--lib/libc/stdlib/strtoq.c138
-rw-r--r--lib/libc/stdlib/strtoul.3164
-rw-r--r--lib/libc/stdlib/strtoul.c109
-rw-r--r--lib/libc/stdlib/strtoull.c116
-rw-r--r--lib/libc/stdlib/strtouq.c116
-rw-r--r--lib/libc/stdlib/system.3101
-rw-r--r--lib/libc/stdlib/system.c92
-rw-r--r--lib/libc/stdtime/Makefile.inc15
-rw-r--r--lib/libc/stdtime/asctime.c70
-rw-r--r--lib/libc/stdtime/ctime.3349
-rw-r--r--lib/libc/stdtime/difftime.c77
-rw-r--r--lib/libc/stdtime/localtime.c1770
-rw-r--r--lib/libc/stdtime/private.h218
-rw-r--r--lib/libc/stdtime/strftime.3254
-rw-r--r--lib/libc/stdtime/strftime.c442
-rw-r--r--lib/libc/stdtime/strptime.3139
-rw-r--r--lib/libc/stdtime/strptime.c543
-rw-r--r--lib/libc/stdtime/time2posix.3116
-rw-r--r--lib/libc/stdtime/timelocal.c245
-rw-r--r--lib/libc/stdtime/timelocal.h54
-rw-r--r--lib/libc/stdtime/tzfile.5138
-rw-r--r--lib/libc/stdtime/tzfile.h190
-rw-r--r--lib/libc/string/Makefile.inc33
-rw-r--r--lib/libc/string/bcmp.372
-rw-r--r--lib/libc/string/bcmp.c59
-rw-r--r--lib/libc/string/bcopy.372
-rw-r--r--lib/libc/string/bcopy.c139
-rw-r--r--lib/libc/string/bstring.3110
-rw-r--r--lib/libc/string/bzero.369
-rw-r--r--lib/libc/string/bzero.c2
-rw-r--r--lib/libc/string/ffs.362
-rw-r--r--lib/libc/string/ffs.c54
-rw-r--r--lib/libc/string/index.381
-rw-r--r--lib/libc/string/index.c57
-rw-r--r--lib/libc/string/memccpy.374
-rw-r--r--lib/libc/string/memccpy.c59
-rw-r--r--lib/libc/string/memchr.382
-rw-r--r--lib/libc/string/memchr.c59
-rw-r--r--lib/libc/string/memcmp.383
-rw-r--r--lib/libc/string/memcmp.c61
-rw-r--r--lib/libc/string/memcpy.384
-rw-r--r--lib/libc/string/memcpy.c2
-rw-r--r--lib/libc/string/memmove.376
-rw-r--r--lib/libc/string/memmove.c2
-rw-r--r--lib/libc/string/memset.371
-rw-r--r--lib/libc/string/memset.c132
-rw-r--r--lib/libc/string/rindex.383
-rw-r--r--lib/libc/string/rindex.c59
-rw-r--r--lib/libc/string/strcasecmp.389
-rw-r--r--lib/libc/string/strcasecmp.c76
-rw-r--r--lib/libc/string/strcat.399
-rw-r--r--lib/libc/string/strcat.c50
-rw-r--r--lib/libc/string/strchr.388
-rw-r--r--lib/libc/string/strchr.c2
-rw-r--r--lib/libc/string/strcmp.395
-rw-r--r--lib/libc/string/strcmp.c55
-rw-r--r--lib/libc/string/strcoll.373
-rw-r--r--lib/libc/string/strcoll.c85
-rw-r--r--lib/libc/string/strcpy.3123
-rw-r--r--lib/libc/string/strcpy.c50
-rw-r--r--lib/libc/string/strcspn.385
-rw-r--r--lib/libc/string/strcspn.c68
-rw-r--r--lib/libc/string/strdup.365
-rw-r--r--lib/libc/string/strdup.c54
-rw-r--r--lib/libc/string/strerror.3128
-rw-r--r--lib/libc/string/strerror.c71
-rw-r--r--lib/libc/string/string.3156
-rw-r--r--lib/libc/string/strlcat.c71
-rw-r--r--lib/libc/string/strlcpy.3157
-rw-r--r--lib/libc/string/strlcpy.c68
-rw-r--r--lib/libc/string/strlen.371
-rw-r--r--lib/libc/string/strlen.c50
-rw-r--r--lib/libc/string/strmode.3151
-rw-r--r--lib/libc/string/strmode.c152
-rw-r--r--lib/libc/string/strncat.c68
-rw-r--r--lib/libc/string/strncmp.c57
-rw-r--r--lib/libc/string/strncpy.c68
-rw-r--r--lib/libc/string/strpbrk.380
-rw-r--r--lib/libc/string/strpbrk.c57
-rw-r--r--lib/libc/string/strrchr.391
-rw-r--r--lib/libc/string/strrchr.c2
-rw-r--r--lib/libc/string/strsep.3110
-rw-r--r--lib/libc/string/strsep.c80
-rw-r--r--lib/libc/string/strsignal.c72
-rw-r--r--lib/libc/string/strspn.380
-rw-r--r--lib/libc/string/strspn.c61
-rw-r--r--lib/libc/string/strstr.389
-rw-r--r--lib/libc/string/strstr.c65
-rw-r--r--lib/libc/string/strtok.3169
-rw-r--r--lib/libc/string/strtok.c163
-rw-r--r--lib/libc/string/strxfrm.396
-rw-r--r--lib/libc/string/strxfrm.c85
-rw-r--r--lib/libc/string/swab.366
-rw-r--r--lib/libc/string/swab.c65
-rw-r--r--lib/libc/sys/Makefile.inc151
-rw-r--r--lib/libc/sys/__error.c47
-rw-r--r--lib/libc/sys/_exit.2120
-rw-r--r--lib/libc/sys/accept.2201
-rw-r--r--lib/libc/sys/access.2135
-rw-r--r--lib/libc/sys/acct.2115
-rw-r--r--lib/libc/sys/adjtime.2112
-rw-r--r--lib/libc/sys/aio_cancel.278
-rw-r--r--lib/libc/sys/aio_error.293
-rw-r--r--lib/libc/sys/aio_read.2200
-rw-r--r--lib/libc/sys/aio_return.295
-rw-r--r--lib/libc/sys/aio_suspend.2105
-rw-r--r--lib/libc/sys/aio_write.2192
-rw-r--r--lib/libc/sys/bind.2147
-rw-r--r--lib/libc/sys/brk.2150
-rw-r--r--lib/libc/sys/chdir.2133
-rw-r--r--lib/libc/sys/chflags.2169
-rw-r--r--lib/libc/sys/chmod.2223
-rw-r--r--lib/libc/sys/chown.2169
-rw-r--r--lib/libc/sys/chroot.2125
-rw-r--r--lib/libc/sys/clock_gettime.2124
-rw-r--r--lib/libc/sys/close.2157
-rw-r--r--lib/libc/sys/connect.2171
-rw-r--r--lib/libc/sys/dup.2204
-rw-r--r--lib/libc/sys/execve.2288
-rw-r--r--lib/libc/sys/fcntl.2530
-rw-r--r--lib/libc/sys/fhopen.2137
-rw-r--r--lib/libc/sys/flock.2172
-rw-r--r--lib/libc/sys/fork.2127
-rw-r--r--lib/libc/sys/fsync.2104
-rw-r--r--lib/libc/sys/ftruncate.c68
-rw-r--r--lib/libc/sys/getdirentries.2204
-rw-r--r--lib/libc/sys/getdtablesize.261
-rw-r--r--lib/libc/sys/getfh.295
-rw-r--r--lib/libc/sys/getfsstat.2172
-rw-r--r--lib/libc/sys/getgid.283
-rw-r--r--lib/libc/sys/getgroups.296
-rw-r--r--lib/libc/sys/getitimer.2177
-rw-r--r--lib/libc/sys/getlogin.2186
-rw-r--r--lib/libc/sys/getpeername.2114
-rw-r--r--lib/libc/sys/getpgrp.2123
-rw-r--r--lib/libc/sys/getpid.280
-rw-r--r--lib/libc/sys/getpriority.2143
-rw-r--r--lib/libc/sys/getrlimit.2188
-rw-r--r--lib/libc/sys/getrusage.2177
-rw-r--r--lib/libc/sys/getsid.277
-rw-r--r--lib/libc/sys/getsockname.2113
-rw-r--r--lib/libc/sys/getsockopt.2397
-rw-r--r--lib/libc/sys/gettimeofday.2132
-rw-r--r--lib/libc/sys/getuid.292
-rw-r--r--lib/libc/sys/intro.2712
-rw-r--r--lib/libc/sys/ioctl.2144
-rw-r--r--lib/libc/sys/issetugid.299
-rw-r--r--lib/libc/sys/jail.2105
-rw-r--r--lib/libc/sys/kill.2142
-rw-r--r--lib/libc/sys/kldfind.274
-rw-r--r--lib/libc/sys/kldfirstmod.267
-rw-r--r--lib/libc/sys/kldload.283
-rw-r--r--lib/libc/sys/kldnext.270
-rw-r--r--lib/libc/sys/kldstat.2116
-rw-r--r--lib/libc/sys/kldunload.278
-rw-r--r--lib/libc/sys/ktrace.2167
-rw-r--r--lib/libc/sys/link.2168
-rw-r--r--lib/libc/sys/listen.2142
-rw-r--r--lib/libc/sys/lseek.2141
-rw-r--r--lib/libc/sys/lseek.c69
-rw-r--r--lib/libc/sys/madvise.2154
-rw-r--r--lib/libc/sys/mincore.288
-rw-r--r--lib/libc/sys/minherit.294
-rw-r--r--lib/libc/sys/mkdir.2110
-rw-r--r--lib/libc/sys/mkfifo.2121
-rw-r--r--lib/libc/sys/mknod.2125
-rw-r--r--lib/libc/sys/mlock.2173
-rw-r--r--lib/libc/sys/mmap.2290
-rw-r--r--lib/libc/sys/mmap.c59
-rw-r--r--lib/libc/sys/mount.2324
-rw-r--r--lib/libc/sys/mprotect.288
-rw-r--r--lib/libc/sys/msync.299
-rw-r--r--lib/libc/sys/munmap.283
-rw-r--r--lib/libc/sys/nanosleep.2104
-rw-r--r--lib/libc/sys/nfssvc.2252
-rw-r--r--lib/libc/sys/open.2301
-rw-r--r--lib/libc/sys/pathconf.2165
-rw-r--r--lib/libc/sys/pipe.2122
-rw-r--r--lib/libc/sys/poll.2190
-rw-r--r--lib/libc/sys/pread.c54
-rw-r--r--lib/libc/sys/profil.2136
-rw-r--r--lib/libc/sys/ptrace.2152
-rw-r--r--lib/libc/sys/pwrite.c54
-rw-r--r--lib/libc/sys/quotactl.2222
-rw-r--r--lib/libc/sys/read.2266
-rw-r--r--lib/libc/sys/readlink.296
-rw-r--r--lib/libc/sys/reboot.2163
-rw-r--r--lib/libc/sys/recv.2294
-rw-r--r--lib/libc/sys/rename.2199
-rw-r--r--lib/libc/sys/revoke.2108
-rw-r--r--lib/libc/sys/rfork.2145
-rw-r--r--lib/libc/sys/rmdir.2105
-rw-r--r--lib/libc/sys/rtprio.2110
-rw-r--r--lib/libc/sys/sched_get_priority_max.2121
-rw-r--r--lib/libc/sys/sched_setparam.2172
-rw-r--r--lib/libc/sys/sched_setscheduler.2167
-rw-r--r--lib/libc/sys/sched_yield.259
-rw-r--r--lib/libc/sys/select.2194
-rw-r--r--lib/libc/sys/semctl.2177
-rw-r--r--lib/libc/sys/semget.2138
-rw-r--r--lib/libc/sys/semop.2192
-rw-r--r--lib/libc/sys/send.2198
-rw-r--r--lib/libc/sys/sendfile.2155
-rw-r--r--lib/libc/sys/setgroups.284
-rw-r--r--lib/libc/sys/setpgid.291
-rw-r--r--lib/libc/sys/setregid.293
-rw-r--r--lib/libc/sys/setreuid.291
-rw-r--r--lib/libc/sys/setsid.283
-rw-r--r--lib/libc/sys/setuid.2161
-rw-r--r--lib/libc/sys/shmat.2111
-rw-r--r--lib/libc/sys/shmctl.2137
-rw-r--r--lib/libc/sys/shmget.2139
-rw-r--r--lib/libc/sys/shutdown.2100
-rw-r--r--lib/libc/sys/sigaction.2577
-rw-r--r--lib/libc/sys/sigaltstack.2165
-rw-r--r--lib/libc/sys/sigpending.273
-rw-r--r--lib/libc/sys/sigprocmask.2121
-rw-r--r--lib/libc/sys/sigreturn.2113
-rw-r--r--lib/libc/sys/sigstack.252
-rw-r--r--lib/libc/sys/sigsuspend.280
-rw-r--r--lib/libc/sys/socket.2300
-rw-r--r--lib/libc/sys/socketpair.292
-rw-r--r--lib/libc/sys/stat.2284
-rw-r--r--lib/libc/sys/statfs.2183
-rw-r--r--lib/libc/sys/swapon.2112
-rw-r--r--lib/libc/sys/symlink.2137
-rw-r--r--lib/libc/sys/sync.275
-rw-r--r--lib/libc/sys/sysarch.279
-rw-r--r--lib/libc/sys/syscall.277
-rw-r--r--lib/libc/sys/truncate.2129
-rw-r--r--lib/libc/sys/truncate.c54
-rw-r--r--lib/libc/sys/umask.288
-rw-r--r--lib/libc/sys/undelete.2104
-rw-r--r--lib/libc/sys/unlink.2119
-rw-r--r--lib/libc/sys/utimes.2187
-rw-r--r--lib/libc/sys/vfork.2130
-rw-r--r--lib/libc/sys/wait.2299
-rw-r--r--lib/libc/sys/write.2289
-rw-r--r--lib/libc/xdr/Makefile.inc43
-rw-r--r--lib/libc/xdr/xdr.3825
-rw-r--r--lib/libc/xdr/xdr.c775
-rw-r--r--lib/libc/xdr/xdr_array.c155
-rw-r--r--lib/libc/xdr/xdr_float.c314
-rw-r--r--lib/libc/xdr/xdr_mem.c242
-rw-r--r--lib/libc/xdr/xdr_rec.c596
-rw-r--r--lib/libc/xdr/xdr_reference.c136
-rw-r--r--lib/libc/xdr/xdr_sizeof.c163
-rw-r--r--lib/libc/xdr/xdr_stdio.c189
-rw-r--r--lib/libc/yp/Makefile.inc17
-rw-r--r--lib/libc/yp/xdryp.c119
-rw-r--r--lib/libc/yp/yplib.c1115
-rw-r--r--lib/libc_r/Makefile45
-rw-r--r--lib/libc_r/arch/alpha/_atomic_lock.S45
-rw-r--r--lib/libc_r/arch/amd64/_atomic_lock.S45
-rw-r--r--lib/libc_r/arch/i386/_atomic_lock.S45
-rw-r--r--lib/libc_r/man/Makefile.inc44
-rw-r--r--lib/libc_r/man/pthread_cancel.373
-rw-r--r--lib/libc_r/man/pthread_cleanup_pop.362
-rw-r--r--lib/libc_r/man/pthread_cleanup_push.365
-rw-r--r--lib/libc_r/man/pthread_cond_broadcast.370
-rw-r--r--lib/libc_r/man/pthread_cond_destroy.374
-rw-r--r--lib/libc_r/man/pthread_cond_init.379
-rw-r--r--lib/libc_r/man/pthread_cond_signal.370
-rw-r--r--lib/libc_r/man/pthread_cond_timedwait.388
-rw-r--r--lib/libc_r/man/pthread_cond_wait.381
-rw-r--r--lib/libc_r/man/pthread_create.3114
-rw-r--r--lib/libc_r/man/pthread_detach.383
-rw-r--r--lib/libc_r/man/pthread_equal.368
-rw-r--r--lib/libc_r/man/pthread_exit.3101
-rw-r--r--lib/libc_r/man/pthread_getspecific.382
-rw-r--r--lib/libc_r/man/pthread_join.3102
-rw-r--r--lib/libc_r/man/pthread_key_create.3100
-rw-r--r--lib/libc_r/man/pthread_key_delete.394
-rw-r--r--lib/libc_r/man/pthread_mutex_destroy.372
-rw-r--r--lib/libc_r/man/pthread_mutex_init.377
-rw-r--r--lib/libc_r/man/pthread_mutex_lock.374
-rw-r--r--lib/libc_r/man/pthread_mutex_trylock.375
-rw-r--r--lib/libc_r/man/pthread_mutex_unlock.374
-rw-r--r--lib/libc_r/man/pthread_once.3102
-rw-r--r--lib/libc_r/man/pthread_rwlock_destroy.380
-rw-r--r--lib/libc_r/man/pthread_rwlock_init.399
-rw-r--r--lib/libc_r/man/pthread_rwlock_rdlock.3122
-rw-r--r--lib/libc_r/man/pthread_rwlock_unlock.379
-rw-r--r--lib/libc_r/man/pthread_rwlock_wrlock.3102
-rw-r--r--lib/libc_r/man/pthread_rwlockattr_destroy.368
-rw-r--r--lib/libc_r/man/pthread_rwlockattr_getpshared.380
-rw-r--r--lib/libc_r/man/pthread_rwlockattr_init.367
-rw-r--r--lib/libc_r/man/pthread_rwlockattr_setpshared.386
-rw-r--r--lib/libc_r/man/pthread_self.361
-rw-r--r--lib/libc_r/man/pthread_setspecific.393
-rw-r--r--lib/libc_r/man/pthread_testcancel.3187
-rw-r--r--lib/libc_r/sys/Makefile.inc6
-rw-r--r--lib/libc_r/sys/uthread_error.c51
-rw-r--r--lib/libc_r/test/Makefile8
-rw-r--r--lib/libc_r/test/mutex/Makefile8
-rw-r--r--lib/libc_r/test/mutex/mutex.c1549
-rw-r--r--lib/libc_r/test/sigsuspend/Makefile8
-rw-r--r--lib/libc_r/test/sigsuspend/sigsuspend.c282
-rw-r--r--lib/libc_r/test/sigwait/Makefile8
-rw-r--r--lib/libc_r/test/sigwait/sigwait.c296
-rw-r--r--lib/libc_r/uthread/Makefile.inc117
-rw-r--r--lib/libc_r/uthread/pthread_private.h1182
-rw-r--r--lib/libc_r/uthread/uthread_accept.c109
-rw-r--r--lib/libc_r/uthread/uthread_attr_destroy.c61
-rw-r--r--lib/libc_r/uthread/uthread_attr_getdetachstate.c58
-rw-r--r--lib/libc_r/uthread/uthread_attr_getinheritsched.c51
-rw-r--r--lib/libc_r/uthread/uthread_attr_getschedparam.c51
-rw-r--r--lib/libc_r/uthread/uthread_attr_getschedpolicy.c51
-rw-r--r--lib/libc_r/uthread/uthread_attr_getscope.c54
-rw-r--r--lib/libc_r/uthread/uthread_attr_getstackaddr.c53
-rw-r--r--lib/libc_r/uthread/uthread_attr_getstacksize.c53
-rw-r--r--lib/libc_r/uthread/uthread_attr_init.c60
-rw-r--r--lib/libc_r/uthread/uthread_attr_setcreatesuspend_np.c52
-rw-r--r--lib/libc_r/uthread/uthread_attr_setdetachstate.c60
-rw-r--r--lib/libc_r/uthread/uthread_attr_setinheritsched.c51
-rw-r--r--lib/libc_r/uthread/uthread_attr_setprio.c51
-rw-r--r--lib/libc_r/uthread/uthread_attr_setschedparam.c51
-rw-r--r--lib/libc_r/uthread/uthread_attr_setschedpolicy.c52
-rw-r--r--lib/libc_r/uthread/uthread_attr_setscope.c63
-rw-r--r--lib/libc_r/uthread/uthread_attr_setstackaddr.c53
-rw-r--r--lib/libc_r/uthread/uthread_attr_setstacksize.c53
-rw-r--r--lib/libc_r/uthread/uthread_autoinit.cc88
-rw-r--r--lib/libc_r/uthread/uthread_bind.c51
-rw-r--r--lib/libc_r/uthread/uthread_cancel.c188
-rw-r--r--lib/libc_r/uthread/uthread_clean.c69
-rw-r--r--lib/libc_r/uthread/uthread_close.c105
-rw-r--r--lib/libc_r/uthread/uthread_cond.c622
-rw-r--r--lib/libc_r/uthread/uthread_condattr_destroy.c52
-rw-r--r--lib/libc_r/uthread/uthread_condattr_init.c58
-rw-r--r--lib/libc_r/uthread/uthread_connect.c78
-rw-r--r--lib/libc_r/uthread/uthread_create.c343
-rw-r--r--lib/libc_r/uthread/uthread_detach.c83
-rw-r--r--lib/libc_r/uthread/uthread_dup.c70
-rw-r--r--lib/libc_r/uthread/uthread_dup2.c86
-rw-r--r--lib/libc_r/uthread/uthread_equal.c44
-rw-r--r--lib/libc_r/uthread/uthread_execve.c113
-rw-r--r--lib/libc_r/uthread/uthread_exit.c240
-rw-r--r--lib/libc_r/uthread/uthread_fchflags.c25
-rw-r--r--lib/libc_r/uthread/uthread_fchmod.c51
-rw-r--r--lib/libc_r/uthread/uthread_fchown.c52
-rw-r--r--lib/libc_r/uthread/uthread_fcntl.c145
-rw-r--r--lib/libc_r/uthread/uthread_fd.c946
-rw-r--r--lib/libc_r/uthread/uthread_file.c475
-rw-r--r--lib/libc_r/uthread/uthread_find_thread.c100
-rw-r--r--lib/libc_r/uthread/uthread_flock.c50
-rw-r--r--lib/libc_r/uthread/uthread_fork.c223
-rw-r--r--lib/libc_r/uthread/uthread_fstat.c58
-rw-r--r--lib/libc_r/uthread/uthread_fstatfs.c58
-rw-r--r--lib/libc_r/uthread/uthread_fsync.c52
-rw-r--r--lib/libc_r/uthread/uthread_gc.c253
-rw-r--r--lib/libc_r/uthread/uthread_getdirentries.c51
-rw-r--r--lib/libc_r/uthread/uthread_getpeername.c51
-rw-r--r--lib/libc_r/uthread/uthread_getprio.c56
-rw-r--r--lib/libc_r/uthread/uthread_getschedparam.c58
-rw-r--r--lib/libc_r/uthread/uthread_getsockname.c51
-rw-r--r--lib/libc_r/uthread/uthread_getsockopt.c51
-rw-r--r--lib/libc_r/uthread/uthread_info.c311
-rw-r--r--lib/libc_r/uthread/uthread_init.c368
-rw-r--r--lib/libc_r/uthread/uthread_ioctl.c79
-rw-r--r--lib/libc_r/uthread/uthread_join.c127
-rw-r--r--lib/libc_r/uthread/uthread_kern.c1135
-rw-r--r--lib/libc_r/uthread/uthread_kill.c74
-rw-r--r--lib/libc_r/uthread/uthread_listen.c51
-rw-r--r--lib/libc_r/uthread/uthread_mattr_init.c58
-rw-r--r--lib/libc_r/uthread/uthread_mattr_kind_np.c79
-rw-r--r--lib/libc_r/uthread/uthread_msync.c40
-rw-r--r--lib/libc_r/uthread/uthread_multi_np.c45
-rw-r--r--lib/libc_r/uthread/uthread_mutex.c1406
-rw-r--r--lib/libc_r/uthread/uthread_mutex_prioceiling.c110
-rw-r--r--lib/libc_r/uthread/uthread_mutex_protocol.c69
-rw-r--r--lib/libc_r/uthread/uthread_mutexattr_destroy.c52
-rw-r--r--lib/libc_r/uthread/uthread_nanosleep.c123
-rw-r--r--lib/libc_r/uthread/uthread_once.c51
-rw-r--r--lib/libc_r/uthread/uthread_open.c77
-rw-r--r--lib/libc_r/uthread/uthread_pipe.c54
-rw-r--r--lib/libc_r/uthread/uthread_poll.c99
-rw-r--r--lib/libc_r/uthread/uthread_priority_queue.c335
-rw-r--r--lib/libc_r/uthread/uthread_read.c103
-rw-r--r--lib/libc_r/uthread/uthread_readv.c93
-rw-r--r--lib/libc_r/uthread/uthread_recvfrom.c73
-rw-r--r--lib/libc_r/uthread/uthread_recvmsg.c73
-rw-r--r--lib/libc_r/uthread/uthread_resume_np.c67
-rw-r--r--lib/libc_r/uthread/uthread_rwlock.c335
-rw-r--r--lib/libc_r/uthread/uthread_rwlockattr.c95
-rw-r--r--lib/libc_r/uthread/uthread_select.c206
-rw-r--r--lib/libc_r/uthread/uthread_self.c44
-rw-r--r--lib/libc_r/uthread/uthread_sendmsg.c72
-rw-r--r--lib/libc_r/uthread/uthread_sendto.c72
-rw-r--r--lib/libc_r/uthread/uthread_seterrno.c61
-rw-r--r--lib/libc_r/uthread/uthread_setprio.c53
-rw-r--r--lib/libc_r/uthread/uthread_setschedparam.c114
-rw-r--r--lib/libc_r/uthread/uthread_setsockopt.c51
-rw-r--r--lib/libc_r/uthread/uthread_shutdown.c72
-rw-r--r--lib/libc_r/uthread/uthread_sig.c584
-rw-r--r--lib/libc_r/uthread/uthread_sigaction.c108
-rw-r--r--lib/libc_r/uthread/uthread_sigblock.c49
-rw-r--r--lib/libc_r/uthread/uthread_sigmask.c93
-rw-r--r--lib/libc_r/uthread/uthread_signal.c58
-rw-r--r--lib/libc_r/uthread/uthread_sigpending.c56
-rw-r--r--lib/libc_r/uthread/uthread_sigprocmask.c92
-rw-r--r--lib/libc_r/uthread/uthread_sigsetmask.c49
-rw-r--r--lib/libc_r/uthread/uthread_sigsuspend.c70
-rw-r--r--lib/libc_r/uthread/uthread_sigwait.c149
-rw-r--r--lib/libc_r/uthread/uthread_single_np.c45
-rw-r--r--lib/libc_r/uthread/uthread_socket.c58
-rw-r--r--lib/libc_r/uthread/uthread_socketpair.c55
-rw-r--r--lib/libc_r/uthread/uthread_spec.c200
-rw-r--r--lib/libc_r/uthread/uthread_spinlock.c106
-rw-r--r--lib/libc_r/uthread/uthread_suspend_np.c72
-rw-r--r--lib/libc_r/uthread/uthread_switch_np.c70
-rw-r--r--lib/libc_r/uthread/uthread_vfork.c9
-rw-r--r--lib/libc_r/uthread/uthread_wait4.c69
-rw-r--r--lib/libc_r/uthread/uthread_write.c139
-rw-r--r--lib/libc_r/uthread/uthread_writev.c203
-rw-r--r--lib/libc_r/uthread/uthread_yield.c64
-rw-r--r--lib/libcalendar/Makefile20
-rw-r--r--lib/libcalendar/calendar.3197
-rw-r--r--lib/libcalendar/calendar.c329
-rw-r--r--lib/libcalendar/calendar.h42
-rw-r--r--lib/libcalendar/easter.c100
-rw-r--r--lib/libcam/Makefile40
-rw-r--r--lib/libcam/cam.3416
-rw-r--r--lib/libcam/cam_cdbparse.3543
-rw-r--r--lib/libcam/camlib.c785
-rw-r--r--lib/libcam/camlib.h178
-rw-r--r--lib/libcam/scsi_cmdparse.c827
-rw-r--r--lib/libcom_err/Makefile18
-rw-r--r--lib/libcom_err/doc/Makefile7
-rw-r--r--lib/libcom_err/doc/com_err.texinfo615
-rw-r--r--lib/libcompat/4.1/ascftime.c52
-rw-r--r--lib/libcompat/4.1/cftime.399
-rw-r--r--lib/libcompat/4.1/cftime.c53
-rw-r--r--lib/libcompat/4.1/ftime.385
-rw-r--r--lib/libcompat/4.1/ftime.c3
-rw-r--r--lib/libcompat/4.1/getpw.389
-rw-r--r--lib/libcompat/4.1/getpw.c58
-rw-r--r--lib/libcompat/4.1/gtty.c5
-rw-r--r--lib/libcompat/4.1/stty.396
-rw-r--r--lib/libcompat/4.1/stty.c5
-rw-r--r--lib/libcompat/4.1/vlimit.3126
-rw-r--r--lib/libcompat/4.1/vtimes.3144
-rw-r--r--lib/libcompat/4.3/cfree.349
-rw-r--r--lib/libcompat/4.3/cfree.c45
-rw-r--r--lib/libcompat/4.3/insque.389
-rw-r--r--lib/libcompat/4.3/insque.c57
-rw-r--r--lib/libcompat/4.3/lsearch.3104
-rw-r--r--lib/libcompat/4.3/lsearch.c93
-rw-r--r--lib/libcompat/4.3/re_comp.3125
-rw-r--r--lib/libcompat/4.3/regex.c96
-rw-r--r--lib/libcompat/4.3/remque.c55
-rw-r--r--lib/libcompat/4.3/rexec.3133
-rw-r--r--lib/libcompat/4.3/rexec.c389
-rw-r--r--lib/libcompat/4.4/cuserid.382
-rw-r--r--lib/libcompat/4.4/cuserid.c59
-rw-r--r--lib/libcompat/Makefile50
-rw-r--r--lib/libcompat/regexp/COPYRIGHT22
-rw-r--r--lib/libcompat/regexp/README84
-rw-r--r--lib/libcompat/regexp/regerror.c18
-rw-r--r--lib/libcompat/regexp/regexp.3321
-rw-r--r--lib/libcompat/regexp/regexp.c1333
-rw-r--r--lib/libcompat/regexp/regmagic.h5
-rw-r--r--lib/libcompat/regexp/regsub.c81
-rw-r--r--lib/libcrypt/Makefile67
-rw-r--r--lib/libcrypt/crypt-md5.c187
-rw-r--r--lib/libcrypt/crypt-shs.c190
-rw-r--r--lib/libcrypt/crypt.3203
-rw-r--r--lib/libcrypt/crypt.c49
-rw-r--r--lib/libcrypt/crypt.h39
-rw-r--r--lib/libcrypt/misc.c46
-rw-r--r--lib/libdevstat/Makefile24
-rw-r--r--lib/libdevstat/devstat.3541
-rw-r--r--lib/libdevstat/devstat.c1128
-rw-r--r--lib/libdevstat/devstat.h115
-rw-r--r--lib/libdisk/Makefile51
-rw-r--r--lib/libdisk/blocks.c41
-rw-r--r--lib/libdisk/change.c82
-rw-r--r--lib/libdisk/chunk.c433
-rw-r--r--lib/libdisk/create_chunk.c396
-rw-r--r--lib/libdisk/disk.c494
-rw-r--r--lib/libdisk/disklabel.c33
-rw-r--r--lib/libdisk/libdisk.3331
-rw-r--r--lib/libdisk/libdisk.h325
-rw-r--r--lib/libdisk/rules.c285
-rw-r--r--lib/libdisk/tst01.c298
-rw-r--r--lib/libdisk/write_disk.c284
-rw-r--r--lib/libedit/Makefile70
-rw-r--r--lib/libedit/TEST/test.c241
-rw-r--r--lib/libedit/chared.c654
-rw-r--r--lib/libedit/chared.h159
-rw-r--r--lib/libedit/common.c995
-rw-r--r--lib/libedit/editline.3548
-rw-r--r--lib/libedit/editrc.5296
-rw-r--r--lib/libedit/el.c358
-rw-r--r--lib/libedit/el.h132
-rw-r--r--lib/libedit/emacs.c504
-rw-r--r--lib/libedit/hist.c170
-rw-r--r--lib/libedit/hist.h77
-rw-r--r--lib/libedit/history.c685
-rw-r--r--lib/libedit/key.c728
-rw-r--r--lib/libedit/key.h80
-rw-r--r--lib/libedit/makelist188
-rw-r--r--lib/libedit/map.c1397
-rw-r--r--lib/libedit/map.h77
-rw-r--r--lib/libedit/parse.c250
-rw-r--r--lib/libedit/parse.h50
-rw-r--r--lib/libedit/prompt.c123
-rw-r--r--lib/libedit/prompt.h59
-rw-r--r--lib/libedit/read.c446
-rw-r--r--lib/libedit/refresh.c1015
-rw-r--r--lib/libedit/refresh.h60
-rw-r--r--lib/libedit/search.c632
-rw-r--r--lib/libedit/search.h68
-rw-r--r--lib/libedit/sig.c193
-rw-r--r--lib/libedit/sig.h70
-rw-r--r--lib/libedit/sys.h115
-rw-r--r--lib/libedit/term.c1378
-rw-r--r--lib/libedit/term.h118
-rw-r--r--lib/libedit/tokenizer.c386
-rw-r--r--lib/libedit/tokenizer.h53
-rw-r--r--lib/libedit/tty.c1144
-rw-r--r--lib/libedit/tty.h481
-rw-r--r--lib/libedit/vi.c1002
-rw-r--r--lib/libfetch/Makefile51
-rw-r--r--lib/libfetch/README10
-rw-r--r--lib/libfetch/common.c284
-rw-r--r--lib/libfetch/common.h59
-rw-r--r--lib/libfetch/fetch.3406
-rw-r--r--lib/libfetch/fetch.c314
-rw-r--r--lib/libfetch/fetch.h95
-rw-r--r--lib/libfetch/fetch_err.et50
-rw-r--r--lib/libfetch/file.c122
-rw-r--r--lib/libfetch/ftp.c520
-rw-r--r--lib/libfetch/ftp.errors44
-rw-r--r--lib/libfetch/http.c471
-rw-r--r--lib/libfetch/http.errors41
-rw-r--r--lib/libform/Makefile23
-rw-r--r--lib/libftpio/Makefile30
-rw-r--r--lib/libftpio/ftp.errors44
-rw-r--r--lib/libftpio/ftpio.3212
-rw-r--r--lib/libftpio/ftpio.c882
-rw-r--r--lib/libftpio/ftpio.h68
-rw-r--r--lib/libgnumalloc/Makefile37
-rw-r--r--lib/libgnumalloc/cfree.c5
-rw-r--r--lib/libio/Makefile11
-rw-r--r--lib/libio/alpha_sethae.c50
-rw-r--r--lib/libio/bwx.c242
-rw-r--r--lib/libio/io.c151
-rw-r--r--lib/libio/io.h48
-rw-r--r--lib/libio/swiz.c246
-rw-r--r--lib/libipx/Makefile9
-rw-r--r--lib/libipx/ipx.3126
-rw-r--r--lib/libipx/ipx_addr.c227
-rw-r--r--lib/libipx/ipx_ntoa.c98
-rw-r--r--lib/libkse/Makefile45
-rw-r--r--lib/libkse/sys/Makefile.inc6
-rw-r--r--lib/libkse/sys/thr_error.c51
-rw-r--r--lib/libkse/test/Makefile8
-rw-r--r--lib/libkse/thread/Makefile.inc117
-rw-r--r--lib/libkse/thread/thr_attr_destroy.c61
-rw-r--r--lib/libkse/thread/thr_attr_getdetachstate.c58
-rw-r--r--lib/libkse/thread/thr_attr_getinheritsched.c51
-rw-r--r--lib/libkse/thread/thr_attr_getschedparam.c51
-rw-r--r--lib/libkse/thread/thr_attr_getschedpolicy.c51
-rw-r--r--lib/libkse/thread/thr_attr_getscope.c54
-rw-r--r--lib/libkse/thread/thr_attr_getstackaddr.c53
-rw-r--r--lib/libkse/thread/thr_attr_getstacksize.c53
-rw-r--r--lib/libkse/thread/thr_attr_init.c60
-rw-r--r--lib/libkse/thread/thr_attr_setcreatesuspend_np.c52
-rw-r--r--lib/libkse/thread/thr_attr_setdetachstate.c60
-rw-r--r--lib/libkse/thread/thr_attr_setinheritsched.c51
-rw-r--r--lib/libkse/thread/thr_attr_setschedparam.c51
-rw-r--r--lib/libkse/thread/thr_attr_setschedpolicy.c52
-rw-r--r--lib/libkse/thread/thr_attr_setscope.c63
-rw-r--r--lib/libkse/thread/thr_attr_setstackaddr.c53
-rw-r--r--lib/libkse/thread/thr_attr_setstacksize.c53
-rw-r--r--lib/libkse/thread/thr_cancel.c188
-rw-r--r--lib/libkse/thread/thr_clean.c69
-rw-r--r--lib/libkse/thread/thr_close.c105
-rw-r--r--lib/libkse/thread/thr_cond.c622
-rw-r--r--lib/libkse/thread/thr_condattr_destroy.c52
-rw-r--r--lib/libkse/thread/thr_condattr_init.c58
-rw-r--r--lib/libkse/thread/thr_create.c343
-rw-r--r--lib/libkse/thread/thr_detach.c83
-rw-r--r--lib/libkse/thread/thr_equal.c44
-rw-r--r--lib/libkse/thread/thr_exit.c240
-rw-r--r--lib/libkse/thread/thr_fcntl.c145
-rw-r--r--lib/libkse/thread/thr_find_thread.c100
-rw-r--r--lib/libkse/thread/thr_fork.c223
-rw-r--r--lib/libkse/thread/thr_fsync.c52
-rw-r--r--lib/libkse/thread/thr_getprio.c56
-rw-r--r--lib/libkse/thread/thr_getschedparam.c58
-rw-r--r--lib/libkse/thread/thr_info.c311
-rw-r--r--lib/libkse/thread/thr_init.c368
-rw-r--r--lib/libkse/thread/thr_join.c127
-rw-r--r--lib/libkse/thread/thr_kern.c1135
-rw-r--r--lib/libkse/thread/thr_kill.c74
-rw-r--r--lib/libkse/thread/thr_mattr_init.c58
-rw-r--r--lib/libkse/thread/thr_mattr_kind_np.c79
-rw-r--r--lib/libkse/thread/thr_msync.c40
-rw-r--r--lib/libkse/thread/thr_multi_np.c45
-rw-r--r--lib/libkse/thread/thr_mutex.c1406
-rw-r--r--lib/libkse/thread/thr_mutex_prioceiling.c110
-rw-r--r--lib/libkse/thread/thr_mutex_protocol.c69
-rw-r--r--lib/libkse/thread/thr_mutexattr_destroy.c52
-rw-r--r--lib/libkse/thread/thr_nanosleep.c123
-rw-r--r--lib/libkse/thread/thr_once.c51
-rw-r--r--lib/libkse/thread/thr_open.c77
-rw-r--r--lib/libkse/thread/thr_poll.c99
-rw-r--r--lib/libkse/thread/thr_priority_queue.c335
-rw-r--r--lib/libkse/thread/thr_private.h1182
-rw-r--r--lib/libkse/thread/thr_read.c103
-rw-r--r--lib/libkse/thread/thr_readv.c93
-rw-r--r--lib/libkse/thread/thr_resume_np.c67
-rw-r--r--lib/libkse/thread/thr_rwlock.c335
-rw-r--r--lib/libkse/thread/thr_rwlockattr.c95
-rw-r--r--lib/libkse/thread/thr_select.c206
-rw-r--r--lib/libkse/thread/thr_self.c44
-rw-r--r--lib/libkse/thread/thr_seterrno.c61
-rw-r--r--lib/libkse/thread/thr_setprio.c53
-rw-r--r--lib/libkse/thread/thr_setschedparam.c114
-rw-r--r--lib/libkse/thread/thr_sig.c584
-rw-r--r--lib/libkse/thread/thr_sigaction.c108
-rw-r--r--lib/libkse/thread/thr_sigmask.c93
-rw-r--r--lib/libkse/thread/thr_sigpending.c56
-rw-r--r--lib/libkse/thread/thr_sigprocmask.c92
-rw-r--r--lib/libkse/thread/thr_sigsuspend.c70
-rw-r--r--lib/libkse/thread/thr_sigwait.c149
-rw-r--r--lib/libkse/thread/thr_single_np.c45
-rw-r--r--lib/libkse/thread/thr_spec.c200
-rw-r--r--lib/libkse/thread/thr_spinlock.c106
-rw-r--r--lib/libkse/thread/thr_suspend_np.c72
-rw-r--r--lib/libkse/thread/thr_switch_np.c70
-rw-r--r--lib/libkse/thread/thr_vfork.c9
-rw-r--r--lib/libkse/thread/thr_wait4.c69
-rw-r--r--lib/libkse/thread/thr_write.c139
-rw-r--r--lib/libkse/thread/thr_writev.c203
-rw-r--r--lib/libkse/thread/thr_yield.c64
-rw-r--r--lib/libkvm/Makefile20
-rw-r--r--lib/libkvm/kvm.3104
-rw-r--r--lib/libkvm/kvm.c543
-rw-r--r--lib/libkvm/kvm.h96
-rw-r--r--lib/libkvm/kvm_alpha.c212
-rw-r--r--lib/libkvm/kvm_amd64.c194
-rw-r--r--lib/libkvm/kvm_file.c188
-rw-r--r--lib/libkvm/kvm_geterr.381
-rw-r--r--lib/libkvm/kvm_getfiles.386
-rw-r--r--lib/libkvm/kvm_getloadavg.364
-rw-r--r--lib/libkvm/kvm_getloadavg.c106
-rw-r--r--lib/libkvm/kvm_getprocs.3164
-rw-r--r--lib/libkvm/kvm_getswapinfo.362
-rw-r--r--lib/libkvm/kvm_getswapinfo.c420
-rw-r--r--lib/libkvm/kvm_i386.c194
-rw-r--r--lib/libkvm/kvm_nlist.389
-rw-r--r--lib/libkvm/kvm_open.3186
-rw-r--r--lib/libkvm/kvm_private.h82
-rw-r--r--lib/libkvm/kvm_proc.c784
-rw-r--r--lib/libkvm/kvm_read.393
-rw-r--r--lib/libkvm/kvm_sparc.c236
-rw-r--r--lib/libm/Makefile168
-rw-r--r--lib/libm/README279
-rw-r--r--lib/libm/common/atan2.c281
-rw-r--r--lib/libm/common/sincos.c98
-rw-r--r--lib/libm/common/tan.c74
-rw-r--r--lib/libm/common/trig.h215
-rw-r--r--lib/libm/common_source/acos.389
-rw-r--r--lib/libm/common_source/acosh.382
-rw-r--r--lib/libm/common_source/acosh.c102
-rw-r--r--lib/libm/common_source/asin.391
-rw-r--r--lib/libm/common_source/asincos.c169
-rw-r--r--lib/libm/common_source/asinh.370
-rw-r--r--lib/libm/common_source/asinh.c101
-rw-r--r--lib/libm/common_source/atan.375
-rw-r--r--lib/libm/common_source/atan.c87
-rw-r--r--lib/libm/common_source/atan2.3189
-rw-r--r--lib/libm/common_source/atanh.384
-rw-r--r--lib/libm/common_source/atanh.c83
-rw-r--r--lib/libm/common_source/ceil.366
-rw-r--r--lib/libm/common_source/cos.374
-rw-r--r--lib/libm/common_source/cosh.375
-rw-r--r--lib/libm/common_source/cosh.c133
-rw-r--r--lib/libm/common_source/erf.383
-rw-r--r--lib/libm/common_source/erf.c396
-rw-r--r--lib/libm/common_source/exp.3285
-rw-r--r--lib/libm/common_source/exp.c203
-rw-r--r--lib/libm/common_source/exp__E.c136
-rw-r--r--lib/libm/common_source/expm1.c167
-rw-r--r--lib/libm/common_source/fabs.367
-rw-r--r--lib/libm/common_source/floor.366
-rw-r--r--lib/libm/common_source/floor.c137
-rw-r--r--lib/libm/common_source/fmod.376
-rw-r--r--lib/libm/common_source/fmod.c155
-rw-r--r--lib/libm/common_source/gamma.c336
-rw-r--r--lib/libm/common_source/hypot.3125
-rw-r--r--lib/libm/common_source/ieee.3268
-rw-r--r--lib/libm/common_source/infnan.3181
-rw-r--r--lib/libm/common_source/j0.3127
-rw-r--r--lib/libm/common_source/j0.c439
-rw-r--r--lib/libm/common_source/j1.c446
-rw-r--r--lib/libm/common_source/jn.c311
-rw-r--r--lib/libm/common_source/lgamma.3124
-rw-r--r--lib/libm/common_source/lgamma.c307
-rw-r--r--lib/libm/common_source/log.c486
-rw-r--r--lib/libm/common_source/log10.c95
-rw-r--r--lib/libm/common_source/log1p.c170
-rw-r--r--lib/libm/common_source/log__L.c110
-rw-r--r--lib/libm/common_source/math.3631
-rw-r--r--lib/libm/common_source/mathimpl.h98
-rw-r--r--lib/libm/common_source/pow.c216
-rw-r--r--lib/libm/common_source/rint.3116
-rw-r--r--lib/libm/common_source/sin.373
-rw-r--r--lib/libm/common_source/sinh.376
-rw-r--r--lib/libm/common_source/sinh.c121
-rw-r--r--lib/libm/common_source/sqrt.3121
-rw-r--r--lib/libm/common_source/tan.374
-rw-r--r--lib/libm/common_source/tanh.371
-rw-r--r--lib/libm/common_source/tanh.c99
-rw-r--r--lib/libm/ieee/cabs.c230
-rw-r--r--lib/libm/ieee/cbrt.c120
-rw-r--r--lib/libm/ieee/support.c524
-rw-r--r--lib/libmd/Makefile180
-rw-r--r--lib/libmd/i386/rmd160.S2018
-rw-r--r--lib/libmd/i386/sha.S1951
-rw-r--r--lib/libmd/md2.copyright17
-rw-r--r--lib/libmd/md2.h45
-rw-r--r--lib/libmd/md2c.c208
-rw-r--r--lib/libmd/md4.copyright20
-rw-r--r--lib/libmd/md4.h47
-rw-r--r--lib/libmd/md4c.c288
-rw-r--r--lib/libmd/md5.copyright21
-rw-r--r--lib/libmd/md5.h4
-rw-r--r--lib/libmd/md5c.c342
-rw-r--r--lib/libmd/mdX.3167
-rw-r--r--lib/libmd/mdXhl.c71
-rw-r--r--lib/libmd/mddriver.c70
-rw-r--r--lib/libmd/ripemd.3110
-rw-r--r--lib/libmd/ripemd.h89
-rw-r--r--lib/libmd/rmd160c.c545
-rw-r--r--lib/libmd/rmd_locl.h216
-rw-r--r--lib/libmd/rmdconst.h399
-rw-r--r--lib/libmd/rmddriver.c51
-rw-r--r--lib/libmd/sha.3151
-rw-r--r--lib/libmd/sha.h96
-rw-r--r--lib/libmd/sha0c.c452
-rw-r--r--lib/libmd/sha1c.c486
-rw-r--r--lib/libmd/sha_locl.h243
-rw-r--r--lib/libmd/shadriver.c61
-rw-r--r--lib/libmenu/Makefile24
-rw-r--r--lib/libncp/CREDITS27
-rw-r--r--lib/libncp/Makefile16
-rw-r--r--lib/libncp/ipx.c351
-rw-r--r--lib/libncp/ipxsap.h95
-rw-r--r--lib/libncp/ncp_mod.h16
-rw-r--r--lib/libncp/ncpl_bind.c267
-rw-r--r--lib/libncp/ncpl_conn.c519
-rw-r--r--lib/libncp/ncpl_crypt.c137
-rw-r--r--lib/libncp/ncpl_file.c263
-rw-r--r--lib/libncp/ncpl_misc.c294
-rw-r--r--lib/libncp/ncpl_msg.c131
-rw-r--r--lib/libncp/ncpl_net.c150
-rw-r--r--lib/libncp/ncpl_nls.c272
-rw-r--r--lib/libncp/ncpl_queue.c223
-rw-r--r--lib/libncp/ncpl_rcfile.c407
-rw-r--r--lib/libncp/ncpl_rpc.c136
-rw-r--r--lib/libncp/ncpl_subr.c473
-rw-r--r--lib/libncp/sap.c302
-rw-r--r--lib/libncurses/Makefile520
-rw-r--r--lib/libncurses/ncurses_cfg.h129
-rw-r--r--lib/libncurses/pathnames.h38
-rw-r--r--lib/libncurses/termcap.c265
-rw-r--r--lib/libnetgraph/Makefile18
-rw-r--r--lib/libnetgraph/debug.c301
-rw-r--r--lib/libnetgraph/internal.h67
-rw-r--r--lib/libnetgraph/msg.c311
-rw-r--r--lib/libnetgraph/netgraph.3267
-rw-r--r--lib/libnetgraph/netgraph.h66
-rw-r--r--lib/libnetgraph/sock.c264
-rw-r--r--lib/libopie/Makefile35
-rw-r--r--lib/libopie/config.h379
-rw-r--r--lib/libpam/Makefile31
-rw-r--r--lib/libpam/Makefile.inc28
-rw-r--r--lib/libpam/libpam/Makefile123
-rw-r--r--lib/libpam/libpam/pam_get_pass.c93
-rw-r--r--lib/libpam/libpam/pam_mod_misc.h48
-rw-r--r--lib/libpam/libpam/pam_prompt.c62
-rw-r--r--lib/libpam/libpam/pam_std_option.c62
-rw-r--r--lib/libpam/libpam/security/pam_mod_misc.h48
-rw-r--r--lib/libpam/modules/Makefile38
-rw-r--r--lib/libpam/modules/pam_cleartext_pass_ok/Makefile39
-rw-r--r--lib/libpam/modules/pam_cleartext_pass_ok/pam_cleartext_pass_ok.c67
-rw-r--r--lib/libpam/modules/pam_deny/Makefile41
-rw-r--r--lib/libpam/modules/pam_kerberosIV/Makefile47
-rw-r--r--lib/libpam/modules/pam_kerberosIV/klogin.c204
-rw-r--r--lib/libpam/modules/pam_kerberosIV/pam_kerberosIV.c108
-rw-r--r--lib/libpam/modules/pam_login_access/login.access.554
-rw-r--r--lib/libpam/modules/pam_login_access/login_access.c239
-rw-r--r--lib/libpam/modules/pam_permit/Makefile42
-rw-r--r--lib/libpam/modules/pam_radius/Makefile42
-rw-r--r--lib/libpam/modules/pam_radius/pam_radius.8128
-rw-r--r--lib/libpam/modules/pam_radius/pam_radius.c300
-rw-r--r--lib/libpam/modules/pam_skey/Makefile40
-rw-r--r--lib/libpam/modules/pam_skey/pam_skey.c108
-rw-r--r--lib/libpam/modules/pam_ssh/pam_ssh.c328
-rw-r--r--lib/libpam/modules/pam_tacplus/Makefile40
-rw-r--r--lib/libpam/modules/pam_tacplus/pam_tacplus.c258
-rw-r--r--lib/libpam/modules/pam_unix/Makefile40
-rw-r--r--lib/libpam/modules/pam_unix/pam_unix.c164
-rw-r--r--lib/libpanel/Makefile19
-rw-r--r--lib/libpcap/Makefile42
-rw-r--r--lib/libpthread/Makefile45
-rw-r--r--lib/libpthread/arch/alpha/alpha/_atomic_lock.S45
-rw-r--r--lib/libpthread/arch/i386/i386/_atomic_lock.S45
-rw-r--r--lib/libpthread/man/Makefile.inc44
-rw-r--r--lib/libpthread/man/pthread_cancel.373
-rw-r--r--lib/libpthread/man/pthread_cleanup_pop.362
-rw-r--r--lib/libpthread/man/pthread_cleanup_push.365
-rw-r--r--lib/libpthread/man/pthread_cond_broadcast.370
-rw-r--r--lib/libpthread/man/pthread_cond_destroy.374
-rw-r--r--lib/libpthread/man/pthread_cond_init.379
-rw-r--r--lib/libpthread/man/pthread_cond_signal.370
-rw-r--r--lib/libpthread/man/pthread_cond_timedwait.388
-rw-r--r--lib/libpthread/man/pthread_cond_wait.381
-rw-r--r--lib/libpthread/man/pthread_create.3114
-rw-r--r--lib/libpthread/man/pthread_detach.383
-rw-r--r--lib/libpthread/man/pthread_equal.368
-rw-r--r--lib/libpthread/man/pthread_exit.3101
-rw-r--r--lib/libpthread/man/pthread_getspecific.382
-rw-r--r--lib/libpthread/man/pthread_join.3102
-rw-r--r--lib/libpthread/man/pthread_key_create.3100
-rw-r--r--lib/libpthread/man/pthread_key_delete.394
-rw-r--r--lib/libpthread/man/pthread_mutex_destroy.372
-rw-r--r--lib/libpthread/man/pthread_mutex_init.377
-rw-r--r--lib/libpthread/man/pthread_mutex_lock.374
-rw-r--r--lib/libpthread/man/pthread_mutex_trylock.375
-rw-r--r--lib/libpthread/man/pthread_mutex_unlock.374
-rw-r--r--lib/libpthread/man/pthread_once.3102
-rw-r--r--lib/libpthread/man/pthread_rwlock_destroy.380
-rw-r--r--lib/libpthread/man/pthread_rwlock_init.399
-rw-r--r--lib/libpthread/man/pthread_rwlock_rdlock.3122
-rw-r--r--lib/libpthread/man/pthread_rwlock_unlock.379
-rw-r--r--lib/libpthread/man/pthread_rwlock_wrlock.3102
-rw-r--r--lib/libpthread/man/pthread_rwlockattr_destroy.368
-rw-r--r--lib/libpthread/man/pthread_rwlockattr_getpshared.380
-rw-r--r--lib/libpthread/man/pthread_rwlockattr_init.367
-rw-r--r--lib/libpthread/man/pthread_rwlockattr_setpshared.386
-rw-r--r--lib/libpthread/man/pthread_self.361
-rw-r--r--lib/libpthread/man/pthread_setspecific.393
-rw-r--r--lib/libpthread/man/pthread_testcancel.3187
-rw-r--r--lib/libpthread/sys/Makefile.inc6
-rw-r--r--lib/libpthread/sys/thr_error.c51
-rw-r--r--lib/libpthread/test/Makefile8
-rw-r--r--lib/libpthread/thread/Makefile.inc117
-rw-r--r--lib/libpthread/thread/thr_attr_destroy.c61
-rw-r--r--lib/libpthread/thread/thr_attr_getdetachstate.c58
-rw-r--r--lib/libpthread/thread/thr_attr_getinheritsched.c51
-rw-r--r--lib/libpthread/thread/thr_attr_getschedparam.c51
-rw-r--r--lib/libpthread/thread/thr_attr_getschedpolicy.c51
-rw-r--r--lib/libpthread/thread/thr_attr_getscope.c54
-rw-r--r--lib/libpthread/thread/thr_attr_getstackaddr.c53
-rw-r--r--lib/libpthread/thread/thr_attr_getstacksize.c53
-rw-r--r--lib/libpthread/thread/thr_attr_init.c60
-rw-r--r--lib/libpthread/thread/thr_attr_setcreatesuspend_np.c52
-rw-r--r--lib/libpthread/thread/thr_attr_setdetachstate.c60
-rw-r--r--lib/libpthread/thread/thr_attr_setinheritsched.c51
-rw-r--r--lib/libpthread/thread/thr_attr_setschedparam.c51
-rw-r--r--lib/libpthread/thread/thr_attr_setschedpolicy.c52
-rw-r--r--lib/libpthread/thread/thr_attr_setscope.c63
-rw-r--r--lib/libpthread/thread/thr_attr_setstackaddr.c53
-rw-r--r--lib/libpthread/thread/thr_attr_setstacksize.c53
-rw-r--r--lib/libpthread/thread/thr_cancel.c188
-rw-r--r--lib/libpthread/thread/thr_clean.c69
-rw-r--r--lib/libpthread/thread/thr_close.c105
-rw-r--r--lib/libpthread/thread/thr_cond.c622
-rw-r--r--lib/libpthread/thread/thr_condattr_destroy.c52
-rw-r--r--lib/libpthread/thread/thr_condattr_init.c58
-rw-r--r--lib/libpthread/thread/thr_create.c343
-rw-r--r--lib/libpthread/thread/thr_detach.c83
-rw-r--r--lib/libpthread/thread/thr_equal.c44
-rw-r--r--lib/libpthread/thread/thr_exit.c240
-rw-r--r--lib/libpthread/thread/thr_fcntl.c145
-rw-r--r--lib/libpthread/thread/thr_find_thread.c100
-rw-r--r--lib/libpthread/thread/thr_fork.c223
-rw-r--r--lib/libpthread/thread/thr_fsync.c52
-rw-r--r--lib/libpthread/thread/thr_gc.c253
-rw-r--r--lib/libpthread/thread/thr_getprio.c56
-rw-r--r--lib/libpthread/thread/thr_getschedparam.c58
-rw-r--r--lib/libpthread/thread/thr_info.c311
-rw-r--r--lib/libpthread/thread/thr_init.c368
-rw-r--r--lib/libpthread/thread/thr_join.c127
-rw-r--r--lib/libpthread/thread/thr_kern.c1135
-rw-r--r--lib/libpthread/thread/thr_kill.c74
-rw-r--r--lib/libpthread/thread/thr_mattr_init.c58
-rw-r--r--lib/libpthread/thread/thr_mattr_kind_np.c79
-rw-r--r--lib/libpthread/thread/thr_msync.c40
-rw-r--r--lib/libpthread/thread/thr_multi_np.c45
-rw-r--r--lib/libpthread/thread/thr_mutex.c1406
-rw-r--r--lib/libpthread/thread/thr_mutex_prioceiling.c110
-rw-r--r--lib/libpthread/thread/thr_mutex_protocol.c69
-rw-r--r--lib/libpthread/thread/thr_mutexattr_destroy.c52
-rw-r--r--lib/libpthread/thread/thr_nanosleep.c123
-rw-r--r--lib/libpthread/thread/thr_once.c51
-rw-r--r--lib/libpthread/thread/thr_open.c77
-rw-r--r--lib/libpthread/thread/thr_poll.c99
-rw-r--r--lib/libpthread/thread/thr_priority_queue.c335
-rw-r--r--lib/libpthread/thread/thr_private.h1182
-rw-r--r--lib/libpthread/thread/thr_read.c103
-rw-r--r--lib/libpthread/thread/thr_readv.c93
-rw-r--r--lib/libpthread/thread/thr_resume_np.c67
-rw-r--r--lib/libpthread/thread/thr_rwlock.c335
-rw-r--r--lib/libpthread/thread/thr_rwlockattr.c95
-rw-r--r--lib/libpthread/thread/thr_select.c206
-rw-r--r--lib/libpthread/thread/thr_self.c44
-rw-r--r--lib/libpthread/thread/thr_seterrno.c61
-rw-r--r--lib/libpthread/thread/thr_setprio.c53
-rw-r--r--lib/libpthread/thread/thr_setschedparam.c114
-rw-r--r--lib/libpthread/thread/thr_sig.c584
-rw-r--r--lib/libpthread/thread/thr_sigaction.c108
-rw-r--r--lib/libpthread/thread/thr_sigmask.c93
-rw-r--r--lib/libpthread/thread/thr_sigpending.c56
-rw-r--r--lib/libpthread/thread/thr_sigprocmask.c92
-rw-r--r--lib/libpthread/thread/thr_sigsuspend.c70
-rw-r--r--lib/libpthread/thread/thr_sigwait.c149
-rw-r--r--lib/libpthread/thread/thr_single_np.c45
-rw-r--r--lib/libpthread/thread/thr_spec.c200
-rw-r--r--lib/libpthread/thread/thr_spinlock.c106
-rw-r--r--lib/libpthread/thread/thr_suspend_np.c72
-rw-r--r--lib/libpthread/thread/thr_switch_np.c70
-rw-r--r--lib/libpthread/thread/thr_vfork.c9
-rw-r--r--lib/libpthread/thread/thr_wait4.c69
-rw-r--r--lib/libpthread/thread/thr_write.c139
-rw-r--r--lib/libpthread/thread/thr_writev.c203
-rw-r--r--lib/libpthread/thread/thr_yield.c64
-rw-r--r--lib/libradius/Makefile41
-rw-r--r--lib/libradius/libradius.3387
-rw-r--r--lib/libradius/radius.conf.5167
-rw-r--r--lib/libradius/radlib.c864
-rw-r--r--lib/libradius/radlib.h183
-rw-r--r--lib/libradius/radlib_private.h92
-rw-r--r--lib/libresolv/Makefile39
-rw-r--r--lib/libresolv/fakelib.c1
-rw-r--r--lib/librpcsvc/Makefile36
-rw-r--r--lib/librpcsvc/rnusers.c68
-rw-r--r--lib/librpcsvc/rstat.c67
-rw-r--r--lib/librpcsvc/rwall.c52
-rw-r--r--lib/librpcsvc/secretkey.c85
-rw-r--r--lib/librpcsvc/xcrypt.c192
-rw-r--r--lib/librpcsvc/yp_passwd.c90
-rw-r--r--lib/librpcsvc/yp_update.c204
-rw-r--r--lib/libskey/Makefile25
-rw-r--r--lib/libskey/mdx.h19
-rw-r--r--lib/libskey/pathnames.h6
-rw-r--r--lib/libskey/put.c2293
-rw-r--r--lib/libskey/skey.160
-rw-r--r--lib/libskey/skey.3161
-rw-r--r--lib/libskey/skey.access.5136
-rw-r--r--lib/libskey/skey.h60
-rw-r--r--lib/libskey/skey_crypt.c38
-rw-r--r--lib/libskey/skey_getpass.c37
-rw-r--r--lib/libskey/skeyaccess.c487
-rw-r--r--lib/libskey/skeylogin.c342
-rw-r--r--lib/libskey/skeysubr.c133
-rw-r--r--lib/libss/Makefile39
-rw-r--r--lib/libss/copyright.h19
-rw-r--r--lib/libss/data.c16
-rw-r--r--lib/libss/error.c101
-rw-r--r--lib/libss/execute_cmd.c221
-rw-r--r--lib/libss/help.c148
-rw-r--r--lib/libss/invocation.c84
-rw-r--r--lib/libss/list_rqs.c94
-rw-r--r--lib/libss/listen.c163
-rw-r--r--lib/libss/pager.c91
-rw-r--r--lib/libss/parse.c138
-rw-r--r--lib/libss/prompt.c31
-rw-r--r--lib/libss/request_tbl.c66
-rw-r--r--lib/libss/requests.c52
-rw-r--r--lib/libss/ss.h69
-rw-r--r--lib/libss/ss_err.et39
-rw-r--r--lib/libss/ss_internal.h115
-rw-r--r--lib/libss/std_rqs.ct46
-rw-r--r--lib/libstand/Makefile124
-rw-r--r--lib/libstand/__main.c40
-rw-r--r--lib/libstand/alpha/_setjmp.S116
-rw-r--r--lib/libstand/arp.c310
-rw-r--r--lib/libstand/assert.c37
-rw-r--r--lib/libstand/bcd.c35
-rw-r--r--lib/libstand/bootp.c396
-rw-r--r--lib/libstand/bootp.h137
-rw-r--r--lib/libstand/bootparam.c449
-rw-r--r--lib/libstand/bootparam.h5
-rw-r--r--lib/libstand/bswap.c37
-rw-r--r--lib/libstand/cd9660.c401
-rw-r--r--lib/libstand/close.c96
-rw-r--r--lib/libstand/closeall.c77
-rw-r--r--lib/libstand/dev.c62
-rw-r--r--lib/libstand/dev_net.c268
-rw-r--r--lib/libstand/dev_net.h7
-rw-r--r--lib/libstand/dosfs.c695
-rw-r--r--lib/libstand/dosfs.h120
-rw-r--r--lib/libstand/environment.c219
-rw-r--r--lib/libstand/ether.c151
-rw-r--r--lib/libstand/fstat.c60
-rw-r--r--lib/libstand/getopt.c112
-rw-r--r--lib/libstand/gets.c113
-rw-r--r--lib/libstand/globals.c33
-rw-r--r--lib/libstand/gzipfs.c318
-rw-r--r--lib/libstand/i386/_setjmp.S81
-rw-r--r--lib/libstand/if_ether.h263
-rw-r--r--lib/libstand/in_cksum.c83
-rw-r--r--lib/libstand/inet_ntoa.c65
-rw-r--r--lib/libstand/ioctl.c89
-rw-r--r--lib/libstand/iodesc.h54
-rw-r--r--lib/libstand/libstand.3474
-rw-r--r--lib/libstand/lseek.c102
-rw-r--r--lib/libstand/net.c503
-rw-r--r--lib/libstand/net.h122
-rw-r--r--lib/libstand/netif.c332
-rw-r--r--lib/libstand/netif.h65
-rw-r--r--lib/libstand/nfs.c659
-rw-r--r--lib/libstand/nfsv2.h166
-rw-r--r--lib/libstand/nullfs.c105
-rw-r--r--lib/libstand/open.c137
-rw-r--r--lib/libstand/pager.c160
-rw-r--r--lib/libstand/printf.c361
-rw-r--r--lib/libstand/qdivrem.c303
-rw-r--r--lib/libstand/quad.h116
-rw-r--r--lib/libstand/random.c72
-rw-r--r--lib/libstand/rarp.c225
-rw-r--r--lib/libstand/read.c96
-rw-r--r--lib/libstand/rpc.c440
-rw-r--r--lib/libstand/rpc.h68
-rw-r--r--lib/libstand/rpcv2.h89
-rw-r--r--lib/libstand/saioctl.h52
-rw-r--r--lib/libstand/sbrk.c60
-rw-r--r--lib/libstand/stand.h350
-rw-r--r--lib/libstand/stat.c53
-rw-r--r--lib/libstand/strcasecmp.c74
-rw-r--r--lib/libstand/strdup.c56
-rw-r--r--lib/libstand/strerror.c88
-rw-r--r--lib/libstand/strtol.c133
-rw-r--r--lib/libstand/tftp.c407
-rw-r--r--lib/libstand/tftp.h36
-rw-r--r--lib/libstand/twiddle.c54
-rw-r--r--lib/libstand/ufs.c717
-rw-r--r--lib/libstand/write.c96
-rw-r--r--lib/libstand/zalloc.c302
-rw-r--r--lib/libstand/zalloc_defs.h87
-rw-r--r--lib/libstand/zalloc_malloc.c197
-rw-r--r--lib/libstand/zalloc_mem.h55
-rw-r--r--lib/libstand/zalloc_protos.h35
-rw-r--r--lib/libstand/zipfs.c318
-rw-r--r--lib/libtacplus/Makefile41
-rw-r--r--lib/libtacplus/libtacplus.3347
-rw-r--r--lib/libtacplus/taclib.c1053
-rw-r--r--lib/libtacplus/taclib.h105
-rw-r--r--lib/libtacplus/taclib_private.h152
-rw-r--r--lib/libtacplus/tacplus.conf.5114
-rw-r--r--lib/libtelnet/Makefile18
-rw-r--r--lib/libtelnet/genget.c104
-rw-r--r--lib/libtelnet/getent.c71
-rw-r--r--lib/libtelnet/misc-proto.h79
-rw-r--r--lib/libtelnet/misc.c93
-rw-r--r--lib/libtelnet/misc.h42
-rw-r--r--lib/libutil/Makefile44
-rw-r--r--lib/libutil/_secure_path.373
-rw-r--r--lib/libutil/_secure_path.c72
-rw-r--r--lib/libutil/auth.361
-rw-r--r--lib/libutil/auth.c71
-rw-r--r--lib/libutil/auth.conf.533
-rw-r--r--lib/libutil/libutil.h81
-rw-r--r--lib/libutil/login.369
-rw-r--r--lib/libutil/login.c68
-rw-r--r--lib/libutil/login.conf.5366
-rw-r--r--lib/libutil/login_auth.370
-rw-r--r--lib/libutil/login_auth.c107
-rw-r--r--lib/libutil/login_cap.3398
-rw-r--r--lib/libutil/login_cap.c799
-rw-r--r--lib/libutil/login_cap.h156
-rw-r--r--lib/libutil/login_class.3188
-rw-r--r--lib/libutil/login_class.c411
-rw-r--r--lib/libutil/login_ok.3138
-rw-r--r--lib/libutil/login_ok.c250
-rw-r--r--lib/libutil/login_times.3155
-rw-r--r--lib/libutil/login_times.c161
-rw-r--r--lib/libutil/login_tty.366
-rw-r--r--lib/libutil/login_tty.c63
-rw-r--r--lib/libutil/logout.371
-rw-r--r--lib/libutil/logout.c78
-rw-r--r--lib/libutil/logwtmp.373
-rw-r--r--lib/libutil/logwtmp.c149
-rw-r--r--lib/libutil/property.397
-rw-r--r--lib/libutil/property.c224
-rw-r--r--lib/libutil/pty.3144
-rw-r--r--lib/libutil/pty.c135
-rw-r--r--lib/libutil/pw_util.c262
-rw-r--r--lib/libutil/realhostname.3106
-rw-r--r--lib/libutil/realhostname.c73
-rw-r--r--lib/libutil/setproctitle.3101
-rw-r--r--lib/libutil/setproctitle.c162
-rw-r--r--lib/libutil/stat_flags.c174
-rw-r--r--lib/libutil/trimdomain.386
-rw-r--r--lib/libutil/uucplock.3183
-rw-r--r--lib/libutil/uucplock.c229
-rw-r--r--lib/libvgl/Makefile35
-rw-r--r--lib/libvgl/bitmap.c364
-rw-r--r--lib/libvgl/keyboard.c92
-rw-r--r--lib/libvgl/main.c477
-rw-r--r--lib/libvgl/mouse.c283
-rw-r--r--lib/libvgl/simple.c403
-rw-r--r--lib/libvgl/text.c244
-rw-r--r--lib/libvgl/vgl.3405
-rw-r--r--lib/libvgl/vgl.h142
-rw-r--r--lib/libwrap/Makefile29
-rw-r--r--lib/libwrap/libvars.c2
-rw-r--r--lib/libxpg4/Makefile9
-rw-r--r--lib/liby/Makefile36
-rw-r--r--lib/liby/main.c42
-rw-r--r--lib/liby/yyerror.c46
-rw-r--r--lib/libz/ChangeLog471
-rw-r--r--lib/libz/FAQ72
-rw-r--r--lib/libz/Makefile37
-rw-r--r--lib/libz/README148
-rw-r--r--lib/libz/adler32.c48
-rw-r--r--lib/libz/algorithm.txt213
-rw-r--r--lib/libz/compress.c68
-rw-r--r--lib/libz/crc32.c162
-rw-r--r--lib/libz/deflate.c1350
-rw-r--r--lib/libz/deflate.h318
-rw-r--r--lib/libz/example.c556
-rw-r--r--lib/libz/gzio.c875
-rw-r--r--lib/libz/infblock.c398
-rw-r--r--lib/libz/infblock.h39
-rw-r--r--lib/libz/infcodes.c257
-rw-r--r--lib/libz/infcodes.h27
-rw-r--r--lib/libz/inffast.c170
-rw-r--r--lib/libz/inffast.h17
-rw-r--r--lib/libz/inffixed.h151
-rw-r--r--lib/libz/inflate.c366
-rw-r--r--lib/libz/inftrees.c455
-rw-r--r--lib/libz/inftrees.h58
-rw-r--r--lib/libz/infutil.c87
-rw-r--r--lib/libz/infutil.h98
-rw-r--r--lib/libz/maketree.c85
-rw-r--r--lib/libz/minigzip.c330
-rw-r--r--lib/libz/trees.c1214
-rw-r--r--lib/libz/trees.h128
-rw-r--r--lib/libz/uncompr.c58
-rw-r--r--lib/libz/zconf.h281
-rw-r--r--lib/libz/zlib.3109
-rw-r--r--lib/libz/zlib.h893
-rw-r--r--lib/libz/zutil.c225
-rw-r--r--lib/libz/zutil.h220
-rw-r--r--lib/msun/Makefile171
-rw-r--r--lib/msun/alpha/s_copysign.S45
-rw-r--r--lib/msun/alpha/s_copysignf.S45
-rw-r--r--lib/msun/bsdsrc/b_exp.c203
-rw-r--r--lib/msun/bsdsrc/b_log.c486
-rw-r--r--lib/msun/bsdsrc/b_tgamma.c336
-rw-r--r--lib/msun/bsdsrc/mathimpl.h98
-rw-r--r--lib/msun/i387/e_acos.S56
-rw-r--r--lib/msun/i387/e_asin.S55
-rw-r--r--lib/msun/i387/e_atan2.S44
-rw-r--r--lib/msun/i387/e_exp.S96
-rw-r--r--lib/msun/i387/e_fmod.S48
-rw-r--r--lib/msun/i387/e_log.S44
-rw-r--r--lib/msun/i387/e_log10.S44
-rw-r--r--lib/msun/i387/e_remainder.S48
-rw-r--r--lib/msun/i387/e_scalb.S45
-rw-r--r--lib/msun/i387/e_sqrt.S43
-rw-r--r--lib/msun/i387/s_atan.S44
-rw-r--r--lib/msun/i387/s_ceil.S58
-rw-r--r--lib/msun/i387/s_copysign.S48
-rw-r--r--lib/msun/i387/s_cos.S56
-rw-r--r--lib/msun/i387/s_finite.S46
-rw-r--r--lib/msun/i387/s_floor.S58
-rw-r--r--lib/msun/i387/s_ilogb.S53
-rw-r--r--lib/msun/i387/s_log1p.S55
-rw-r--r--lib/msun/i387/s_logb.S44
-rw-r--r--lib/msun/i387/s_rint.S43
-rw-r--r--lib/msun/i387/s_scalbn.S45
-rw-r--r--lib/msun/i387/s_significand.S44
-rw-r--r--lib/msun/i387/s_sin.S56
-rw-r--r--lib/msun/i387/s_tan.S58
-rw-r--r--lib/msun/man/acos.396
-rw-r--r--lib/msun/man/acosh.388
-rw-r--r--lib/msun/man/asin.398
-rw-r--r--lib/msun/man/asinh.376
-rw-r--r--lib/msun/man/atan.382
-rw-r--r--lib/msun/man/atan2.3196
-rw-r--r--lib/msun/man/atanh.390
-rw-r--r--lib/msun/man/ceil.368
-rw-r--r--lib/msun/man/cos.381
-rw-r--r--lib/msun/man/cosh.382
-rw-r--r--lib/msun/man/erf.393
-rw-r--r--lib/msun/man/exp.3323
-rw-r--r--lib/msun/man/fabs.374
-rw-r--r--lib/msun/man/floor.368
-rw-r--r--lib/msun/man/fmod.385
-rw-r--r--lib/msun/man/hypot.3134
-rw-r--r--lib/msun/man/ieee.3182
-rw-r--r--lib/msun/man/ieee_test.3107
-rw-r--r--lib/msun/man/j0.3155
-rw-r--r--lib/msun/man/lgamma.3139
-rw-r--r--lib/msun/man/math.3644
-rw-r--r--lib/msun/man/rint.368
-rw-r--r--lib/msun/man/sin.380
-rw-r--r--lib/msun/man/sinh.382
-rw-r--r--lib/msun/man/sqrt.3134
-rw-r--r--lib/msun/man/tan.379
-rw-r--r--lib/msun/man/tanh.378
-rw-r--r--lib/msun/src/e_acos.c111
-rw-r--r--lib/msun/src/e_acosf.c89
-rw-r--r--lib/msun/src/e_acosh.c69
-rw-r--r--lib/msun/src/e_acoshf.c57
-rw-r--r--lib/msun/src/e_asin.c120
-rw-r--r--lib/msun/src/e_asinf.c92
-rw-r--r--lib/msun/src/e_atan2.c130
-rw-r--r--lib/msun/src/e_atan2f.c105
-rw-r--r--lib/msun/src/e_atanh.c74
-rw-r--r--lib/msun/src/e_atanhf.c58
-rw-r--r--lib/msun/src/e_cosh.c93
-rw-r--r--lib/msun/src/e_coshf.c71
-rw-r--r--lib/msun/src/e_exp.c167
-rw-r--r--lib/msun/src/e_expf.c103
-rw-r--r--lib/msun/src/e_fmod.c140
-rw-r--r--lib/msun/src/e_fmodf.c113
-rw-r--r--lib/msun/src/e_gamma.c37
-rw-r--r--lib/msun/src/e_gamma_r.c35
-rw-r--r--lib/msun/src/e_gammaf.c39
-rw-r--r--lib/msun/src/e_gammaf_r.c38
-rw-r--r--lib/msun/src/e_hypot.c128
-rw-r--r--lib/msun/src/e_hypotf.c87
-rw-r--r--lib/msun/src/e_j0.c487
-rw-r--r--lib/msun/src/e_j0f.c444
-rw-r--r--lib/msun/src/e_j1.c486
-rw-r--r--lib/msun/src/e_j1f.c444
-rw-r--r--lib/msun/src/e_jn.c281
-rw-r--r--lib/msun/src/e_jnf.c212
-rw-r--r--lib/msun/src/e_lgamma.c36
-rw-r--r--lib/msun/src/e_lgamma_r.c312
-rw-r--r--lib/msun/src/e_lgammaf.c39
-rw-r--r--lib/msun/src/e_lgammaf_r.c248
-rw-r--r--lib/msun/src/e_log.c146
-rw-r--r--lib/msun/src/e_log10.c98
-rw-r--r--lib/msun/src/e_log10f.c67
-rw-r--r--lib/msun/src/e_logf.c97
-rw-r--r--lib/msun/src/e_pow.c312
-rw-r--r--lib/msun/src/e_powf.c253
-rw-r--r--lib/msun/src/e_rem_pio2.c183
-rw-r--r--lib/msun/src/e_rem_pio2f.c196
-rw-r--r--lib/msun/src/e_remainder.c80
-rw-r--r--lib/msun/src/e_remainderf.c73
-rw-r--r--lib/msun/src/e_scalb.c55
-rw-r--r--lib/msun/src/e_scalbf.c52
-rw-r--r--lib/msun/src/e_sinh.c86
-rw-r--r--lib/msun/src/e_sinhf.c68
-rw-r--r--lib/msun/src/e_sqrt.c453
-rw-r--r--lib/msun/src/e_sqrtf.c97
-rw-r--r--lib/msun/src/get_hw_float.c50
-rw-r--r--lib/msun/src/k_cos.c96
-rw-r--r--lib/msun/src/k_cosf.c64
-rw-r--r--lib/msun/src/k_rem_pio2.c320
-rw-r--r--lib/msun/src/k_rem_pio2f.c213
-rw-r--r--lib/msun/src/k_sin.c79
-rw-r--r--lib/msun/src/k_sinf.c54
-rw-r--r--lib/msun/src/k_standard.c782
-rw-r--r--lib/msun/src/k_tan.c131
-rw-r--r--lib/msun/src/k_tanf.c101
-rw-r--r--lib/msun/src/math.h277
-rw-r--r--lib/msun/src/math_private.h250
-rw-r--r--lib/msun/src/s_asinh.c65
-rw-r--r--lib/msun/src/s_asinhf.c57
-rw-r--r--lib/msun/src/s_atan.c139
-rw-r--r--lib/msun/src/s_atanf.c119
-rw-r--r--lib/msun/src/s_cbrt.c93
-rw-r--r--lib/msun/src/s_cbrtf.c83
-rw-r--r--lib/msun/src/s_ceil.c80
-rw-r--r--lib/msun/src/s_ceilf.c61
-rw-r--r--lib/msun/src/s_copysign.c38
-rw-r--r--lib/msun/src/s_copysignf.c41
-rw-r--r--lib/msun/src/s_cos.c82
-rw-r--r--lib/msun/src/s_cosf.c59
-rw-r--r--lib/msun/src/s_erf.c314
-rw-r--r--lib/msun/src/s_erff.c223
-rw-r--r--lib/msun/src/s_expm1.c228
-rw-r--r--lib/msun/src/s_expm1f.c133
-rw-r--r--lib/msun/src/s_fabs.c35
-rw-r--r--lib/msun/src/s_fabsf.c38
-rw-r--r--lib/msun/src/s_finite.c35
-rw-r--r--lib/msun/src/s_finitef.c38
-rw-r--r--lib/msun/src/s_floor.c81
-rw-r--r--lib/msun/src/s_floorf.c70
-rw-r--r--lib/msun/src/s_frexp.c59
-rw-r--r--lib/msun/src/s_frexpf.c52
-rw-r--r--lib/msun/src/s_ilogb.c50
-rw-r--r--lib/msun/src/s_ilogbf.c43
-rw-r--r--lib/msun/src/s_isnan.c38
-rw-r--r--lib/msun/src/s_isnanf.c40
-rw-r--r--lib/msun/src/s_ldexp.c32
-rw-r--r--lib/msun/src/s_ldexpf.c35
-rw-r--r--lib/msun/src/s_lib_version.c39
-rw-r--r--lib/msun/src/s_log1p.c173
-rw-r--r--lib/msun/src/s_log1pf.c112
-rw-r--r--lib/msun/src/s_logb.c42
-rw-r--r--lib/msun/src/s_logbf.c39
-rw-r--r--lib/msun/src/s_matherr.c30
-rw-r--r--lib/msun/src/s_modf.c83
-rw-r--r--lib/msun/src/s_modff.c64
-rw-r--r--lib/msun/src/s_nextafter.c79
-rw-r--r--lib/msun/src/s_nextafterf.c70
-rw-r--r--lib/msun/src/s_rint.c93
-rw-r--r--lib/msun/src/s_rintf.c77
-rw-r--r--lib/msun/src/s_scalbn.c66
-rw-r--r--lib/msun/src/s_scalbnf.c62
-rw-r--r--lib/msun/src/s_signgam.c3
-rw-r--r--lib/msun/src/s_significand.c34
-rw-r--r--lib/msun/src/s_significandf.c31
-rw-r--r--lib/msun/src/s_sin.c82
-rw-r--r--lib/msun/src/s_sinf.c53
-rw-r--r--lib/msun/src/s_tan.c76
-rw-r--r--lib/msun/src/s_tanf.c48
-rw-r--r--lib/msun/src/s_tanh.c86
-rw-r--r--lib/msun/src/s_tanhf.c64
-rw-r--r--lib/msun/src/w_acos.c43
-rw-r--r--lib/msun/src/w_acosf.c47
-rw-r--r--lib/msun/src/w_acosh.c42
-rw-r--r--lib/msun/src/w_acoshf.c47
-rw-r--r--lib/msun/src/w_asin.c44
-rw-r--r--lib/msun/src/w_asinf.c48
-rw-r--r--lib/msun/src/w_atan2.c43
-rw-r--r--lib/msun/src/w_atan2f.c47
-rw-r--r--lib/msun/src/w_atanh.c47
-rw-r--r--lib/msun/src/w_atanhf.c52
-rw-r--r--lib/msun/src/w_cabs.c27
-rw-r--r--lib/msun/src/w_cabsf.c21
-rw-r--r--lib/msun/src/w_cosh.c42
-rw-r--r--lib/msun/src/w_coshf.c46
-rw-r--r--lib/msun/src/w_drem.c15
-rw-r--r--lib/msun/src/w_dremf.c16
-rw-r--r--lib/msun/src/w_exp.c53
-rw-r--r--lib/msun/src/w_expf.c58
-rw-r--r--lib/msun/src/w_fmod.c43
-rw-r--r--lib/msun/src/w_fmodf.c47
-rw-r--r--lib/msun/src/w_gamma.c49
-rw-r--r--lib/msun/src/w_gamma_r.c46
-rw-r--r--lib/msun/src/w_gammaf.c48
-rw-r--r--lib/msun/src/w_gammaf_r.c51
-rw-r--r--lib/msun/src/w_hypot.c43
-rw-r--r--lib/msun/src/w_hypotf.c47
-rw-r--r--lib/msun/src/w_j0.c41
-rw-r--r--lib/msun/src/w_j0f.c45
-rw-r--r--lib/msun/src/w_j1.c42
-rw-r--r--lib/msun/src/w_j1f.c46
-rw-r--r--lib/msun/src/w_jn.c42
-rw-r--r--lib/msun/src/w_jnf.c42
-rw-r--r--lib/msun/src/w_lgamma.c49
-rw-r--r--lib/msun/src/w_lgamma_r.c46
-rw-r--r--lib/msun/src/w_lgammaf.c48
-rw-r--r--lib/msun/src/w_lgammaf_r.c51
-rw-r--r--lib/msun/src/w_log.c43
-rw-r--r--lib/msun/src/w_log10.c46
-rw-r--r--lib/msun/src/w_log10f.c51
-rw-r--r--lib/msun/src/w_logf.c48
-rw-r--r--lib/msun/src/w_pow.c61
-rw-r--r--lib/msun/src/w_powf.c72
-rw-r--r--lib/msun/src/w_remainder.c42
-rw-r--r--lib/msun/src/w_remainderf.c46
-rw-r--r--lib/msun/src/w_scalb.c60
-rw-r--r--lib/msun/src/w_scalbf.c65
-rw-r--r--lib/msun/src/w_sinh.c42
-rw-r--r--lib/msun/src/w_sinhf.c46
-rw-r--r--lib/msun/src/w_sqrt.c42
-rw-r--r--lib/msun/src/w_sqrtf.c46
-rw-r--r--lib/msun/src/w_y0.c50
-rw-r--r--lib/msun/src/w_y0f.c54
-rw-r--r--lib/msun/src/w_y1.c50
-rw-r--r--lib/msun/src/w_y1f.c54
-rw-r--r--lib/msun/src/w_yn.c50
-rw-r--r--lib/msun/src/w_ynf.c50
-rw-r--r--lib/ncurses/form/Makefile23
-rw-r--r--lib/ncurses/menu/Makefile24
-rw-r--r--lib/ncurses/ncurses/Makefile520
-rw-r--r--lib/ncurses/ncurses/ncurses_cfg.h129
-rw-r--r--lib/ncurses/ncurses/pathnames.h38
-rw-r--r--lib/ncurses/ncurses/termcap.c265
-rw-r--r--lib/ncurses/panel/Makefile19
2398 files changed, 455514 insertions, 140 deletions
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 0000000..66fb360
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,71 @@
+# @(#)Makefile 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+# To satisfy shared library or ELF linkage when only the libraries being
+# built are visible:
+#
+# csu must be built before all shared libaries for ELF.
+# libcom_err must be built before libss.
+# libcrypt must be built before libkrb and libskey.
+# libm must be built before libstdc++.
+# libmd must be built before libatm, libcrypt, libopie, libradius, libskey,
+# and libtacplus.
+# libncurses must be built before libdialog, libedit and libreadline.
+# libradius must be built before libpam.
+# libskey must be built before libpam.
+# libtacplus must be built before libpam.
+#
+# Otherwise, the SUBDIR list should be in alphabetical order.
+
+SUBDIR= ${_csu} libcom_err ${_libm} libmd ${_libcrypt} \
+ libncurses libradius libskey libtacplus \
+ ${_compat} libalias libatm ${_libbind} libc ${_libc_r} libcalendar \
+ libcam libcompat libdevstat libdisk libedit libfetch libform \
+ libftpio libgnumalloc ${_libio} libipx libkvm libmenu ${_libncp} \
+ libnetgraph libopie libpam libpanel libpcap libresolv librpcsvc libss \
+ libstand ${_libtelnet} libutil ${_libvgl} libwrap libxpg4 liby libz
+
+.if exists(${.CURDIR}/csu/${MACHINE_ARCH}-${OBJFORMAT})
+_csu=csu/${MACHINE_ARCH}-${OBJFORMAT}
+.elif exists(${.CURDIR}/csu/${MACHINE_ARCH})
+_csu=csu/${MACHINE_ARCH}
+.endif
+
+.if !defined(NOLIBC_R)
+_libc_r= libc_r
+.endif
+
+.if !defined(NO_BIND)
+_libbind= libbind
+.endif
+
+_libcrypt= libcrypt
+.if exists(${.CURDIR}/../secure) && !defined(NOSECURE) && !defined(NOCRYPT)
+# Build both libraries. They have different names, so no harm,
+# and this avoids having stale libscrypt.*
+_libcrypt+= ../secure/lib/libcrypt
+.endif
+
+.if ${MACHINE_ARCH} == "i386"
+_compat= compat
+_libncp= libncp
+_libvgl= libvgl
+.endif
+
+.if defined(WANT_CSRG_LIBM)
+_libm= libm
+.else
+_libm= msun
+.endif
+
+.if ${MACHINE_ARCH} == "alpha"
+_libio= libio
+.endif
+
+.if defined(RELEASEDIR) || \
+ (!exists(${.CURDIR}/../secure) && !exists(${.CURDIR}/../kerberosIV)) || \
+ defined(NOCRYPT) || !defined(MAKE_KERBEROS4)
+_libtelnet= libtelnet
+.endif
+
+.include <bsd.subdir.mk>
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
new file mode 100644
index 0000000..62677fd
--- /dev/null
+++ b/lib/Makefile.inc
@@ -0,0 +1,3 @@
+# Default version for system libs (override in <lib>/Makefile if necessary)
+SHLIB_MAJOR?= 2
+SHLIB_MINOR?= 0
diff --git a/lib/compat/Makefile b/lib/compat/Makefile
new file mode 100644
index 0000000..7d8bdfc
--- /dev/null
+++ b/lib/compat/Makefile
@@ -0,0 +1,22 @@
+# $FreeBSD$
+
+SUBDIR=
+
+# Note that compat21 is *not* for the 2.1.x branch!
+.if defined(COMPAT1X) || defined(RELEASEDIR)
+SUBDIR+= compat1x
+.endif
+.if defined(COMPAT20) || defined(RELEASEDIR)
+SUBDIR+= compat20
+.endif
+.if defined(COMPAT21) || defined(RELEASEDIR)
+SUBDIR+= compat21
+.endif
+.if defined(COMPAT22) || defined(RELEASEDIR)
+SUBDIR+= compat22
+.endif
+.if defined(COMPAT3X) || defined(RELEASEDIR)
+SUBDIR+= compat3x
+.endif
+
+.include <bsd.subdir.mk>
diff --git a/lib/compat/Makefile.inc b/lib/compat/Makefile.inc
new file mode 100644
index 0000000..23e2711
--- /dev/null
+++ b/lib/compat/Makefile.inc
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+LIBCOMPATDIR?= ${LIBDIR}/compat/aout
diff --git a/lib/compat/compat1x/Makefile b/lib/compat/compat1x/Makefile
new file mode 100644
index 0000000..07be405
--- /dev/null
+++ b/lib/compat/compat1x/Makefile
@@ -0,0 +1,28 @@
+# $FreeBSD$
+
+DISTRIBUTION= compat1x
+
+LIBS= libc.so.1.1 libcurses.so.1.1 libf2c.so.1.1 libg++.so.1.1 \
+ libgcc.so.1.1 libgnumalloc.so.1.1 libgnuregex.so.1.1 libln.so.1.1 \
+ libm.so.1.1 libmalloc.so.1.1 libreadline.so.1.1 libresolv.so.1.1 \
+ librpcsvc.so.1.1 libskey.so.1.1 libtelnet.so.1.1 libtermcap.so.1.1 \
+ libutil.so.1.1 liby.so.1.1
+
+CLEANFILES+= ${LIBS}
+LINKS= ${LIBCOMPATDIR}/aout/libtermcap.so.1.1 \
+ ${LIBCOMPATDIR}/aout/libtermlib.so.1.1
+
+all: ${LIBS}
+
+.for lib in ${LIBS}
+${lib}: ${lib}.gz.uu
+ uudecode -p ${.CURDIR}/${lib}.gz.uu | gunzip > ${lib}
+.endfor
+
+beforeinstall:
+ ${INSTALL} ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} ${LIBS} \
+ ${DESTDIR}${LIBCOMPATDIR}/aout
+
+# Get all the fruit, even though we don't set PROG.
+# XXX bsd.lib.mk has fruitflies, e.g., it fails if LIBS is empty.
+.include <bsd.prog.mk>
diff --git a/lib/compat/compat1x/libc.so.1.1.gz.uu b/lib/compat/compat1x/libc.so.1.1.gz.uu
new file mode 100644
index 0000000..f2e0046
--- /dev/null
+++ b/lib/compat/compat1x/libc.so.1.1.gz.uu
@@ -0,0 +1,3921 @@
+begin 444 libc.so.1.1.gz
+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
+.!&D%@O\';ULWR:(F!@"^
+`
+end
diff --git a/lib/compat/compat1x/libcurses.so.1.1.gz.uu b/lib/compat/compat1x/libcurses.so.1.1.gz.uu
new file mode 100644
index 0000000..db25272
--- /dev/null
+++ b/lib/compat/compat1x/libcurses.so.1.1.gz.uu
@@ -0,0 +1,428 @@
+begin 444 libcurses.so.1.1.gz
+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
+*_PV+62([R<4``,+_
+`
+end
diff --git a/lib/compat/compat1x/libf2c.so.1.1.gz.uu b/lib/compat/compat1x/libf2c.so.1.1.gz.uu
new file mode 100644
index 0000000..eaea7ba
--- /dev/null
+++ b/lib/compat/compat1x/libf2c.so.1.1.gz.uu
@@ -0,0 +1,787 @@
+begin 444 libf2c.so.1.1.gz
+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
+:ZD-;/8/G!4>S[:>_ZZ'R./,_"Z[B"V9S`0`G
+`
+end
diff --git a/lib/compat/compat1x/libg++.so.1.1.gz.uu b/lib/compat/compat1x/libg++.so.1.1.gz.uu
new file mode 100644
index 0000000..f32ca72
--- /dev/null
+++ b/lib/compat/compat1x/libg++.so.1.1.gz.uu
@@ -0,0 +1,3530 @@
+begin 444 libg++.so.1.1.gz
+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
+FZE-(8[Y^>F3">O&X8B^-'M)/+!_$)-J]Q\>O3/7_*2>&+A5C!@#$
+`
+end
diff --git a/lib/compat/compat1x/libgcc.so.1.1.gz.uu b/lib/compat/compat1x/libgcc.so.1.1.gz.uu
new file mode 100644
index 0000000..3a20167
--- /dev/null
+++ b/lib/compat/compat1x/libgcc.so.1.1.gz.uu
@@ -0,0 +1,133 @@
+begin 444 libgcc.so.1.1.gz
+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
+==O9EC;/+^OWIYVU88>%O"O\*(/0#Q4I#3Q9A``!H
+`
+end
diff --git a/lib/compat/compat1x/libgnumalloc.so.1.1.gz.uu b/lib/compat/compat1x/libgnumalloc.so.1.1.gz.uu
new file mode 100644
index 0000000..bc63c8e
--- /dev/null
+++ b/lib/compat/compat1x/libgnumalloc.so.1.1.gz.uu
@@ -0,0 +1,142 @@
+begin 444 libgnumalloc.so.1.1.gz
+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
+H-E^KGN,HRH9&/BISL*ECY3HT4VX]"!%2)'@[\8V7X3?0Z7W,^$P``(`?
+`
+end
diff --git a/lib/compat/compat1x/libgnuregex.so.1.1.gz.uu b/lib/compat/compat1x/libgnuregex.so.1.1.gz.uu
new file mode 100644
index 0000000..14b5a9e
--- /dev/null
+++ b/lib/compat/compat1x/libgnuregex.so.1.1.gz.uu
@@ -0,0 +1,270 @@
+begin 444 libgnuregex.so.1.1.gz
+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
+*_PM)1.Y1!H8``+D)
+`
+end
diff --git a/lib/compat/compat1x/libln.so.1.1.gz.uu b/lib/compat/compat1x/libln.so.1.1.gz.uu
new file mode 100644
index 0000000..14a62ce
--- /dev/null
+++ b/lib/compat/compat1x/libln.so.1.1.gz.uu
@@ -0,0 +1,13 @@
+begin 444 libln.so.1.1.gz
+M'XL("#\3%RX``VQI8FQN+G-O+C$N,0#MF3U+`T$0AB?Q(VHA*=.IA9`B1`B(
+M"*)>-)'`:81$4$36>'>$R.4B&"4!"VT$L4GIO[%()?@3;(5H(UB*H+.7/3>(
+M0@K!YGU@;CYV=NZN'-Y[NCRG*)%OC,LV29JMJ\="1P:[%^TY[NDLR4>*']=[
+M[W=M\C@*$R5.V4?8#W#K$%N(;9#\,Y\/)I@YK,XBJC>HC:A:@!^K[QI3^;[*
+MI]0[`N)JEJV*,S(/ZW^95??/U/T%MM&>W/@V3XC5G0UC/;?"T9J93QNFR&>S
+MA4Q1%(VTF1$DFDW7:9!PZDZC3J):JGB<V*5ZB9UG\[5N[>'VA0``````````
+M@']&[MQ1WH'CT?[OR!W<9EOF>)/M1M7E3A_C)=J4"9_'E&\]O?G;?ZOSJOPS
+M^]"/LP$``````````/#WR)U=:N]R3Q\GK;%/D];3$Z2U]!1I'7V>M(:^R'Z"
+MNCTY-5?&VSWQ(?6CJ_\FJ+N5`UE+'M>H;%DI8=6J1Q77L9-2:B][)U\%8=$G
+(L6!$I=8@``#Q
+`
+end
diff --git a/lib/compat/compat1x/libm.so.1.1.gz.uu b/lib/compat/compat1x/libm.so.1.1.gz.uu
new file mode 100644
index 0000000..07ba894
--- /dev/null
+++ b/lib/compat/compat1x/libm.so.1.1.gz.uu
@@ -0,0 +1,538 @@
+begin 444 libm.so.1.1.gz
+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
+@OFR18Y*M8+AP_D8Z.K17HWCU1](!*_PW"GMBI1G=``#O
+`
+end
diff --git a/lib/compat/compat1x/libmalloc.so.1.1.gz.uu b/lib/compat/compat1x/libmalloc.so.1.1.gz.uu
new file mode 100644
index 0000000..468d9f8
--- /dev/null
+++ b/lib/compat/compat1x/libmalloc.so.1.1.gz.uu
@@ -0,0 +1,183 @@
+begin 444 libmalloc.so.1.1.gz
+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
+('3(EEH]B``!S
+`
+end
diff --git a/lib/compat/compat1x/libreadline.so.1.1.gz.uu b/lib/compat/compat1x/libreadline.so.1.1.gz.uu
new file mode 100644
index 0000000..680c543
--- /dev/null
+++ b/lib/compat/compat1x/libreadline.so.1.1.gz.uu
@@ -0,0 +1,1117 @@
+begin 444 libreadline.so.1.1.gz
+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
+1,)'P20W=E.>?"MZ>E&CO`0"^
+`
+end
diff --git a/lib/compat/compat1x/libresolv.so.1.1.gz.uu b/lib/compat/compat1x/libresolv.so.1.1.gz.uu
new file mode 100644
index 0000000..2ff9c90
--- /dev/null
+++ b/lib/compat/compat1x/libresolv.so.1.1.gz.uu
@@ -0,0 +1,153 @@
+begin 444 libresolv.so.1.1.gz
+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
+H:471X]9OYO3K.E9UG>J%KS0]O)"Z'#SM\_.O!E+L_Q<9C<FN?D@``*^@
+`
+end
diff --git a/lib/compat/compat1x/librpcsvc.so.1.1.gz.uu b/lib/compat/compat1x/librpcsvc.so.1.1.gz.uu
new file mode 100644
index 0000000..b9c2570
--- /dev/null
+++ b/lib/compat/compat1x/librpcsvc.so.1.1.gz.uu
@@ -0,0 +1,165 @@
+begin 444 librpcsvc.so.1.1.gz
+M'XL(")0.%RX``VQI8G)P8W-V8RYS;RXQ+C$`[%P+=)1%EJZ0$`)&004))($`
+M>9($$D(("0$2()T$\B2!\`I-2#HDT$F'3C<DBB,<4&0P8\9=9Q9QSH`KZXJS
+M(^JXPJBSJ*,.KG,$'S."Z\KH<#8,NN(;@9BM^NM6U>V_.YV*Q#UGS^8_]JG<
+M^U?=NO75K>?_R>ODKNUD'2%D%#&>AA&$1!'U+-MSKJ*+_;%ZQTL9-%^/.[3'
+M'=)U._WSSN.NX4<#Z*L+09V=J<?W5E\]\1++7[5<EAA*L^V]/62O.[2!!!&R
+MO*HKFVIV_CZ4EBWLL`25575-,10A5#&[PQ)*%2.D(J[#,HHJ/K,*Q2T=EM%4
+M<=9J5!["*P^D=7?8OER]UDJK-]5_IU743ZL^*.UD\:H/2$5"AR6$*G9+11CW
+M90NO:02O:6AGI[DN65.X56)SXKN>'@ULSJ]%OMU/R_":;]XY+\`]ACLXO8=9
+M<@]+/7XAA-9M&%35F^SMP_:>7BM:$LM-/2P58WA;*[B7P[B70WK',!?;K5Z+
+M^H+9#>5F>NL+:>5*M<3G='<O^)CC[55:9F,4E`I?:W2%\M<7IO=7(U^/50M?
+M*:9$8+J_3TREM7QJP(A;<&%[M3GNI`^RS,VL3`^198HTRGRPAF9_*I0*&T.A
+M6$RUUO@ZM`:UU]TC8@CZ/$4JH,]W]_CK<VFUU/`GA/D3`O[<OT;+GS'8GW,R
+MIB%6_J%'+U;>6,WJ#\)XC-&K__[5J/[4[TQXA/4##Y_SWVHU_ZWNW1^9?YC*
+M7ZR3_\^K4+PGKM:(]T.K4'M/K#*-S:.K=.?):FPG4\`T<M?7;'`8MNS"^,A=
+M?S&4#+\JI7S=4+(Y<X%2/F,HV1R>K)0/&4HVCX<I98>A#*/*0-F*;1V6"*KX
+M?*50;.JP1%'%7Z1B58<EFBI.2@5=4^*IXM]6HC4EB2I>D:%`UY295/$TCLUL
+M-C_ZG\<05JDK$5;+L"\,IT78%X91VDK3^C9YI6E]2\"^,`C"-.?41U9XSC5G
+M5_0]U[2N\)S3?M5[&=3FN2M0F\]?16N5G%<?Z^['6O5)%;+W[574?M;!]VCW
+MQ2%LYPFSG9/:=JJQG48O.U=U[8S!=EZXX@NGG?U9TU]>CNQM]FEOXG?]L.?&
+M]G9(>UF\G7<O1_LA-K"V+D?[(3:PZI?WL1]"=0W'=77(NB8TL/UEAV5168>E
+M@)I<LMPTS_5F[]@R9,]VV1<6M_4'VT9LSRWM+>58;%LFFI[+L=@D%2D<BU52
+M,1&:E$2;E$+?M"W3G7?/52(?)G6CN&-5[KJB&W>_P'9.7S79^8-V_"[#=FJ^
+M-8V#[=IVKL=V"J^B=9CY8[^"UF$&Y?[+6ON29RKH^A@$$]=UE1KKXYT5R(^?
+M7D)^L/8<P/L!YMCN"LU83,9VRRM$("S@8;A"!E,J7P,R9$51/4^Q@];&47PM
+MF%>A/YZ.+15U"ANT[NZEK.Y1:LU_;JEN[#4N16T8\\TUCZ=QV-[<I0*3Q=Q4
+MDE1D<DS"I2(>SGU2,9:OB]^6>^V9>HW_<AQO7_MJ2ZG_MOC:[^67RV6RP]L7
+MG_M?[$=JN0F#E'(3!G'E"`/6Y.!RA`';(GU5IHW!OC)4=WJ/K_-D'QC@MB\I
+MDVT_KW>>'8?K+RY#>]$0&&MZ<7FJ%-D9:K83HFUGC[0C[AZ.EXJ[AY4<CT=*
+MA?4"'H,_DXH,CO_M4A'+]V9U4C&&;T\K2C7GC&]+4+N22]&^D;4KJ!3M&YDK
+M7Y2@?2.+C0D]:`_+EIE3)0@;MJD]6:([]INP+P>EG2SN2UL)V@<P7S:4H'T`
+M\^4^'A):\U8`KBN]!.')Z@HM07BRNC)T[R4>+49VWR\VQ<G%;KT]=&VQC'-F
+ML,\S6IK*W^XG/VY_L3D.9Q>;[L`F%J.^9B#<(!5Q/`X+>TQGA`;M<;"C"-\+
+M%9GP+S.O@;<5:<9S`K9;;;;[F\O(+FM2FJ[=4TLD7@$<KY`B@9?8\_JU)2WM
+M7N)YUCF^1.>L4[Y$K;.CV3H;M+%G.:_W\27,D3!V8#U`Q"'XQ^JXO)>(0["Z
+MB[F5CY@ZJ6A49EG?\NY<)BRSM8)-*U<7H[6";58N+$9K!>NH,XO16L%V42<6
+M:Z\538M1W^U;C,:.<6^@?6Z*P78*I9VI&X.XI?K%HN?&<K!B]'T\48AL?U(H
+M;(_?&,QMCUBLOW>Z'=LZ6*C\!%N_*T1^LOYC!33]G(1M%Q>:L,PNU)V33Q?X
+MO`_.X@Z=E8H$'C'A,J#@;/9:@3\\T/X&U6DK4'-3@#'6'BP02.0:*MZ*NZ0V
+M$;2L,UL*T+AD3I86:([Q3_+Q>1O/;6RLD`*_F*G[#V8ECP[3"&,[O+&N;.?Q
+MH#(VTH-]8.$]EV\0Y<-8^=&H_"OY?LKC^,\WS^UK\DUSU9Q\34Q.6_"^)]]T
+M7\9,G;68[LM8)[PEE.R^C'7"BU*QB</YA%2LXHO)`:DHY+%TKP6M/VSV^9$%
+MK3]L]FFRH+AFL\\:BUX?!5KD]%MHT5HO3^7A.QT9&_%[@W=>&N**NV/XSDL!
+MKM`+89V=.R\%NL9>&-G)T?DUOP@)IIO;87[W]SC^<5U[\DQCMRU/=^Q&YJDU
+M(XI/[D'4XF[#XFC68;,#V)VV>,<[ID&]'F<,*H9T8)[LY"!#R=#^[T52^:G1
+M\VS`GU;*,X3?/U1U_5XI7S:4;*?XN%(>,91LM_B04NXWE+.ILD,I[S*4[&ZT
+M32A=[@Y+#ML/2D4=N\BIZBJ1B@K9R$!^O[-S$322Q58E5=R*[V+74$4COO^L
+M8WO\1;JX'UKH$_>1BR2PT3YPO[A0OAXJ<=^[4+;\(A&X;U'*]R3N-4KYBL2]
+M2"F?D+AG*.6#$O>I2KE;XCY&*%U;..9!4F'CF'^Q0"@J.>9GI&)ASU/1'IB/
+M%`UD>P6&>;"\6AK+,3^T0'M]RUW@$^/'%D@0WR7>&-^C7A\C`N.X!;+I#TN,
+M;U+*>R7&W;FB<3_B^'XL%4T<V_>D8@W']4VI6,(Q?4$JLCBF1Z0B@6/Z2ZD(
+MXYC^)+>O-13/;7&YGOO+=;DZ^\O/<LQK1GRN6#,R^<0S3/H5SR?YKW/07H]-
+M\N=RM/MOAU=]1W-,:]1JO]\%D:WT'+Q'D7/S>':?Q5:6+3FZW\LOS)>PC?-N
+MB_=:_:S*'^`G/S[_S_>YCL#<_O!\W3DF=[X9O[;Y`K\$;JQJOHPCA@3K,;L?
+M^_CQK.N=>?B[R#S3>M0U3]?G#FSG";.=NS6_P^;/,_9'#1V3"9%;H_WS?-Z[
+M^F[/4.D'/4-5=<V?)X!SL<./<2\H534<N.NDMV4\U"_/%8KYK!";7+Z9*PHE
+M\4-45==?I6H<4[%=S:FYVF.D>JZ'GS^7QL*XE[$]_NX[3/VIOO_.5=]_O7WQ
+M%;/O9)MC+52Z`G<%7V2;[@K.2`5\3WPA&_4WP^9(MF[<+,M&<;,Y&\V?K.J6
+M;#1_&M]_L]'\R7RQ9&N/_SG]Y<L<FS.P?)E&;._..>C^@IER245_^3(W8KO)
+M<TQC3Y<O\^]9_>?+_#P+\0<N9&E\'[%EX?UOEO#U>_)EQF9YKH=E67U_C_XH
+MT_,;=H1&F<<SO?@R7V5JC2]WY@_!EYF8Z<67L>GY<V[V0/!E?CG;BR_##&O4
+M;\/U#SA?9MAL-?_Y\4?Q7S)D_DB=_(]DH'B_DJ$1[^X,?.^585X7,W3GR61L
+MQR=?)EL8QWR9.*54?)F;E%+Q9;IGF<[_;![O4DK%EWE+*`5?YD6I`+[,$U(!
+M?)D#4@%\F7MGH35EH/DR`;,05C'8%X;3:.P+PRAPEFE]^SS=M+Y];[[,UG3/
+MN>9(>M]SS<)TSSEM6^]E\/?O]('ERSP_<V#X,FYLYQKX,LG8SC7P9<ZE#2Q?
+MYGYL;P#X,GG8GA=?9D4:V@^Q@96?AO9#;&#-2M._HSX]0XLO$YZF>9^X!]L;
+M`+Y,)K;GQ9<IFB&:#GR9.5(!?)FI4F'FRQ3,T)UWGTX=&+Y,$[9S#7R9&&SG
+M&O@R[Z?\$'R9W2F(+_->BL;ZN`S[T3=?ILILL[?V=4_'_98B`J'??)D;4O3'
+MTQY9)^++_'$ZJQOQ9>Z9KAM[F;@-`\"7.3\-V;M^NL`$N")7IZ'O?PR3"U(!
+M?)DS4@%\F1/3]+__X;H'C"\S=II<)JN]??&Y_TU&?@1,,V%`S!A\DXPP8$W^
+M4S+"@&V17D[6QJ`1UWW-?)GPY/[R9<XGH?HCD]%>M']\F8/8SCM))COZ?)F5
+MTHZX>^A,$G</P)?9*JT#7Z9>*H`O4RP5P)>9*17`EYF2I#EGG$A$[>I.1/M&
+MUJZW$]&^D;GR4B+:-_KDRQQ,1-BP3>V!1-VQ/Q?[LEG:`;Y,02+:!Q@<ED2T
+M#^@O7^;45/P=,!'AR>KZCZD(SW[Q9=JQW7^9:HH37;Y,VE3%?YFJ<48+5/D+
+M_>3'[4\PQV'(5-,=V*<)IC/"?TK%M?-ERA,03G<FF/#WXLLL2=#E?\7C>R&S
+M72^^3*"NW8/2KN#+O!MONM__-%Z++U,5[WG6Z8S7.>M,BE?KK(DO<X?AR`_!
+MEXD1E@5?YO4XM%:PS<JS<6BM8!UU.`ZM%6P7M2].>ZV8&X?/.W%H[/2/+_-5
+M++(S3MJ1?)E9<:+G@"_#"FCZN`_;?CY6V)9\F3.Q^GNG8FQK<ZSR$VS])!;Y
+MR?JO6-_/SV+PNA=KPC(T5G=.?A3;^1Y\F0=B^L^728]1<Q/GR]AC!!*8+[-<
+M:C%?)B<&C4OFY,08S3'^?+0_OLS):#TNQM;HWO@R?XK6X<MDB/)>?)F?^2N/
+MXW^*>6Y/BC;-5==%:V+RZ!2\[YEBNB]CIHXHI>++_*-0"K[,?5(!?)D=4@%\
+MF1:I`+Z,=0I:?]CL4S(%K3]L]ID[!<4UFWV2INCUT5N3U7?1*5KKY<')_WM\
+MF71<U\K)IK%;,%EW['XRR2>GH&JR)`WXXLO,5J\57^:M2;*3%5_F=TJI^#*/
+M*J7BR_R]4BJ^S!U*J?@R3J54?)EJI51\F0*A%'R9#*D`OLP$J?#BRU1,@D;J
+M\V7>C=+%W1WE$_</HB2POO@RQ]5KQ9=9'25;KO@R%J54?)E4I51\F0BE5'R9
+M84JI^#*7)TJEXLN<$TK!EWE;*H`O\Y)4`%_FL%1X\64^F"@P[XTOXYZHO;[=
+M.-$GQK=-E"#ZXLNL4:\57^:;";+IBB_SH5(JOLP?A5+P99Z3"N#+/"85P)=Y
+M2"J`+_-3J0"^S':I`+Z,0RJ`+[-V0G_X,M]$>NXO4R;H["]?B#2O&9<BQ9H!
+M?)D_1Z*]'IOD7Y$*V)\\':G=?^5>]=TMZ^LO7V9H)-ZC>/-E+)&ZW\N?C5#W
+M"Q$:YZZ]*O\I/_GQ^3_"'U_&%:$[Q]P88<:O($+@!WR9N`@91X(OD^W'/GY,
+M_+]PY/.)</.^/%S[_W_'=G:8[>CR9<:&^^#+;`KO!U_FG?$>/)21X0(XR9>Y
+M.EZH@"_SWGCA+?!E7I,*R9=Y51:2?)G?2)7DRQP<KSU&DCW]W""-]9LO<]\Z
+M0NAV,ND!FMY(TX=H6D+3PS2ET9/T)$W3:?I;FHZAZ8LTG4[3.II:"8EHH"G=
+M)T78:;J`IJ_1=`E]WT)3&Y7?I.DX*I^A*44SZ4.:AM#41=,-]'T;3>E9,F(;
+M38?1]&\TI<?-I.W<CXA=W*^("NIK+?T-)49]+"]AVVCVU9\.8I;7>$;0'YW6
+M2!(Q_&-U&,]-]#<7WF40HVV$V60`3:6_F^DOC?YNH#]Z*B`CZ6\1,7PF=<3P
+M@7TT(4/HCRX5A(88*::_8/JC1R9"`6=?-@V?$NAO+/WE$@,+X[F%_C83_L_\
+MS*:_0+#!;&;2WW#P^3KZHSL0PM@5.?1W/?W-(@8F9"DQ^H#00RKK,U).#&P)
+M6TQI!+#K6@.+>/!Q+=@B@%DZY$V$-A+P/1EL3H>R<Z`-J8!-"I2IA+PSH*Z9
+M4*8%\LR',OF09QY@F@5Y%X`/RZ%-1=`7V8#)0L""0)DR\*4`\JR&/B1@VP)U
+MY@%6]8#Y8JBK$&PN([PO&R`O@;*B;TK`YVJHJQ3*5H$M`KZN(+S/">19"3X2
+MZ(M&PONH";`B4/<&:/,JL+D&;*T#&^OA'8$V.B"/#7QB#^O+&L)CV@EE">B:
+MP<9&PL?()L)CU@XV"&!#``,"OA(H0Z`,@3($VD#`-@&?V-,"Z6:B'C86A4-L
+M_`VE@V342"Z/`_GMF[F<!')V`)=9/P<@6Q9X?W8XERM!/A#*Y5J0+XY5?N+R
+M;?"^;B*7=X)_Z\"_!^#]/;=P^9]`3AK-Y:,@;P/[)T#N!'_.@&R/XO)_@5PV
+ME,N?F_SIAO<I4-_P`"YWC0%\`CSSQYCDZ9!_5""7LT$^$L'E(E/^Y2:Y!O*+
+M.'68WK?#^X^OY_(>D-?<R.7](%="_QT6]0\#O$!>!/Z]"/*[T-XWA/^3N?P^
+MR#E!7/X8Y)/0O]T@SP[G<N@0B)<;N!P)\A]@8DL&N2&,RW-`WC:.R_D@;X?\
+M*T&^.)[+=I`?A/:W@]QR'>`!\G,`VOXAGOC],[S_>`27GP%Y%\33JR!7WL3E
+MTR!W`;X70(X&?*^8[`\+Y.\OA7!Y+,B=0[@<#?(:D&>#G`/CKP#DT=#^2O$>
+MXGF]>`_E72"W07_N!/DHX'\?R,^!_8>%?]"_3X+\.OQ[=L=!/@+VW@#Y5X#'
+M1R`?A_H_`_E!P/,[82^*RR.#8/P!2)-`/@+]/PWD!R%_!LBAX$]>D">^Y?`^
+M!>*E#N1HB&^'*7\;O(\"^SM`#H/^N1?D,L#C%R`70'S_&N1=$'\O"'M@_R3(
+M1=#^#T#^$O#Z)(CO@5)6</E+>$_`_I"A,%Z@O2-!W@[S4SC(1\#?J2#?#>,Q
+M`^2W8?Y<"'(E^%L!\G'(7POR+JC/!7(0S&\[00Z!_/>"/'H"EQ\`.0K\>P3D
+M>!B/3X(\$^;CET`^">/K39`O0O]_)-H']BZ"G`+MZ0;Y$KP/">;KPTE8($<&
+M\[V8D$<'P_P">$T!^23T5QK(?X5XR0'Y*,P?5NNBE26YQ84+B;6MSFEMMC=9
+M6UTUKE8D-M0X;37.#:#:!#D@@\WE6+^1_TUSU:E\S?6MM0['ID8;%]VNIA;^
+M5XW36=/._VQJMS;641?RBTH7Y!992RV6BKQ*:V7N@J(\*\_AJJ6UFYUQVEI%
+MC6U6EZN]R5%G4R[8&YLWR1RMV-EZ5WN+<,?:V`S:U@W4Q'IED)9UV^'=%ENM
+MR^'D?]N:W4W\K[I&9TN-JP&*,[1:MU)'N;S>X;##7^TN&P+-[JC=Q"6[HWF#
+M\I=:D^XV0SX$HV@T-*'1;FNN:0))_67'0+6V4(0IS%S:X'2X6YH](*)5JAJ,
+M!K@:A24FUK<Z$(3,6JV[R6U7/=E89Q?F-KL=KAJ4DUG:4@-YG<R:U4-%Z[8W
+MM@*^M=0;ERFX/-O?XJ`=98.F;'4VXMP,FV:'J[&^7<D4<I=GCMJ:YEJEJ6]M
+ML-;4UMI:9>N=C:(WJ&N.%M3R^H::9ME0YIJ[V;MS&ASV.N$?:ZV[%1ESX@#P
+M=*W)X6YV*20X[!Z!P/([6^S0N/:6EAH:9W6>@8)LK7?4(1S,KM8W8.=8$)C'
+MB-7+654YZW,94!Y.JM'E:*G9[`:P-MA<1EQ849C5N%Q@0`Z])D<SS`GTG;+4
+M9L5-;6UO8D-:69+&G:UBG&[RG+98\W`_TC[G<X3-96N#(IXV65-4N^I;*5ZH
+M&U4^6UN+P^F27=ALS%^&4YL]NY]G5,-.=BB>NU@\N-`HQ2-2NJ)PL36[G.T>
+M,U]KXZUR6+?A4!:#5'8:-83&>!.:.NIYQ]CJ:M@XMC77H?[R')DXU*D]-0<Z
+MC3G)R#SX##Z#S^`S^`P^@\___8<=*T>MH^?==?IEV%WFW?2WW4++Y=.S.%Q2
+MLRO!L^6$E+&/$NO@KE?3;N?YR\87C,ZNSR']&TT#:/HA38?0]`Q-`VGZ)DV#
+M:/H:38?2]$6:!M/TMS0=0=,G:1I*T\,TO9ZF#]'T!IH^0-.;2'1A7584V^RT
+M.!VN:6U)6Z)2IZ5&I69FIDU/R9R>.C,J-2-KY@SZ7]1&5VU47EM+5+2'GT9Y
+M8S_NIW!:+X5%>;8![:/^F?[J;^[;_W1_Y>EFTD_16;@HS]_L;K4Y6W7+>-=G
+M[.?]%,_L%3!>GNV1H7@:+YZ:.CTM)6I&2E9::M;,U"BZH?:#MW-KC=W>>_7I
+M*7WT%]U/&Z=4/R92_>%M')S]%.XMV$1Y<3;T8\)O?P_&^V"\_S^)]\%G\!E\
+M!I_!9_`9?`:?P<?_PSZ+L^,Z.Z<SBH7@3D42Q9M*(8HS-8\H?E014=RHU43Q
+MHFQ$<:`87TOPGW83Q7WZ.Z)X3X>(XCS]*U%\IU>)XCJ]313/Z0.B.$T7B.(S
+M71'^!Q(2@GA*88B#%(OX1K,0UZ@`\8RJ$,?(AOA%#L0MVH9X13]&G*)]B$]T
+M&'&)C@4H'M%K`8I#="9`\8>Z`A1WZ,L`Q1L*1IRA<8@O%(NX0O_3KMF$1!5%
+M<?PRWQ\D%4)(+B8D"2$IB>C#P.R#;)$&45#8F&.((8TD%5*!!9$EJ-A*VVA!
+M&"Z2PJ@VE8L*"HO*110T"&&+D"*K19O.\9[;^;>Q>!*!S$;_/,YOSGOWG7=G
+MX/U6@R>T#9R@/>`#U8,+Y#PC]H#:P0&ZY%/?9]"GKL]MGWH^3WWJ^+SUJ=_S
+MP1VG>_?-'6?W`IR>1>#S%(++LP8\GJW@\.P"?R<%[LYQ\';.@K/3#;[.%;^Z
+M.L/N<VB=1UP]U3SQJY_SVJ\NSD>_>CC?_>#<@&^3`ZY-/G@VR\&Q*0._IA+<
+MFOW@U32"4],,/HUS>]BEZ0BH1]/KG",ZAVL!]6=N!=2=&0FH-_,BH,[,N#LW
+M^LPO`75E?.#)Y(`CDP=^3"&X,2O!BRD')V8G^#"UX,*DP8,Y"0[,N:#Z+QU!
+M=5\N!M5[N>P^WZB/P[[+O:"Z+L^"UCGF=7X7M/L:YTG(O-&%:!8^T5X4#EEE
+MB;W@G)!E><X7AVP]YR+(I<*N.&#,)F'9-=XN+*_/7JGGW`#YA+!-Q)Z!ON>%
+MY?VV1^HY#T"^*^P0L0^`?2PLK_E+J><\#GG*72^Q/X1E7]H7MBSOU0O"MIYS
+M`G))V+*)6F/6ABW++G69L/R,[)!ZSM60T\+6$'M,6/:Q3[F^-),77"_*/9`'
+MA>TC]D98U_F.ZTM_'KI>E,<@3PB;(782V*_`!B-:GPNY,"+7FZ+G-Z+KO"IB
+M6=Z'-TH]YRK(M<+6$-L0T;Y-PO+^T"KUG#LA]PO;1^P`]+WNV`*:<U=/>11R
+M1M@,L1/`3@I[?RG==ZGG'(MJSH_*]=894Q#5<RZ*2M]EQJR3>LX5D/<)6T-L
+M;53[-@A;1C>[1>HYMT'N%;:/V'Y@!X1E$?^FU',>@?Q*V`RQ;Z(ZS^/")M8;
+M\UGJ.;,,[O+"F&7GTX^3O)C.<R)FV9I28XJEGO,&R)7"5A&[.Z;S7"UL@GX4
+M'7*]*+=`;A>VB]CNF*YSC^M;;LQ5UXOR,.1'PCXG=A38,6#?0_T4Y%!<KI?V
+MTGEQ7>?<N&6'-ANS)&[K.:^`7"YL%;$5<>U;)6SK%NHA]9S3D$\+VT5L&_3M
+MC,_:1?Q+__#_28<SF88S.H6_ZX-9:?!/TN`_\`2S;N!LW,"9?<"L!CCG-$#W
+M1I&/%S>G37TJ59),I>EL&@_6%=/NFZP_?/37@63*)(^DFGD1[;_IH?7(NI>)
+M7O'9G3G?$8^D?:GHE;;/@D=X^AGWR/*[1(^L>X_H%>>O#H^LVS(]XMGYSL[W
+,7)[OGZ.=52GWA0``
+`
+end
diff --git a/lib/compat/compat1x/libskey.so.1.1.gz.uu b/lib/compat/compat1x/libskey.so.1.1.gz.uu
new file mode 100644
index 0000000..91d8512
--- /dev/null
+++ b/lib/compat/compat1x/libskey.so.1.1.gz.uu
@@ -0,0 +1,247 @@
+begin 444 libskey.so.1.1.gz
+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
+L;!T*WIZ>;?ZTN3.N_865A?$EU/]NWYW/5R)UM+1AY!<6^O\`!^*N:-QF``"P
+`
+end
diff --git a/lib/compat/compat1x/libtelnet.so.1.1.gz.uu b/lib/compat/compat1x/libtelnet.so.1.1.gz.uu
new file mode 100644
index 0000000..0cc9cb9
--- /dev/null
+++ b/lib/compat/compat1x/libtelnet.so.1.1.gz.uu
@@ -0,0 +1,63 @@
+begin 444 libtelnet.so.1.1.gz
+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
+LLP8QW!Z^"[!:F%^&I_N\`<1TLAY_)PN<NGEYM9-UKP[F\'\#[[3E%#\D```-
+`
+end
diff --git a/lib/compat/compat1x/libtermcap.so.1.1.gz.uu b/lib/compat/compat1x/libtermcap.so.1.1.gz.uu
new file mode 100644
index 0000000..54a3cc1
--- /dev/null
+++ b/lib/compat/compat1x/libtermcap.so.1.1.gz.uu
@@ -0,0 +1,75 @@
+begin 444 libtermcap.so.1.1.gz
+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
+!`'3Y
+`
+end
diff --git a/lib/compat/compat1x/libutil.so.1.1.gz.uu b/lib/compat/compat1x/libutil.so.1.1.gz.uu
new file mode 100644
index 0000000..53f55b6
--- /dev/null
+++ b/lib/compat/compat1x/libutil.so.1.1.gz.uu
@@ -0,0 +1,208 @@
+begin 444 libutil.so.1.1.gz
+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
+J&"^%6PO%*3H-=4_)+8;L[R9?17SG"_4)+8+R5'8NK^Z_`=`L!/1I80``
+`
+end
diff --git a/lib/compat/compat1x/liby.so.1.1.gz.uu b/lib/compat/compat1x/liby.so.1.1.gz.uu
new file mode 100644
index 0000000..7f8c710
--- /dev/null
+++ b/lib/compat/compat1x/liby.so.1.1.gz.uu
@@ -0,0 +1,18 @@
+begin 444 liby.so.1.1.gz
+M'XL("-,.%RX``VQI8GDN<V\N,2XQ`.V9SVL341#')ZT_TE8DX$D0C$HA%4FR
+MC4&"($W:IA2C*;0>Q!_/97=;%],D[*:0>*H6!`U"S_X%'CQZ\!CH1<$_0#R)
+M($0OBD<1UIGM;#9=+Q5/RGQ@]COS=N:]Q]YFYRT\VH0$@&_(.[0DA%Q[_&FY
+M3\Z-!SL7,*=_F1Z7\+'4S^)STAW?DW,,U[R-^-.M#U\];ZF[=0"7#SX'2C^.
+MK[1>]];/-SOA_@XN'@8X=Q]U!/4AZ@3J$]115!,5]SCA[X,6`S^F=U1'-0/&
+M..<06YQS@/UQS@'V)]@"_-Q$^)[B.QR?XK,#SD;B7"0NT%WP<G,<E_ANY_G"
+MBY'\*N<G@^_.YW_C\V_RW8-8C]0K-7?]:O'*XBQZ"Y5JJ5A1U7)Y>7Y%K11+
+ME7D%JM-IZHYK@5IM.G:]M8J)RBW3NN4X#0>4U;+:+92VC<]UW:ZC;^HM':5N
+M4K:_)@B"(`B"(`B"(/R34%^<P)XRE=A_#?7$=]$VT:?6/LZ-*/7EK]&O44![
+MLA+;GW]XGH?:_\[Z!36&^A%U!/4]ZBC,I,Y,49^9-L;RZ5PR5;*<>U;-ZDPE
+MM8R6RQ2TR%THGSM8OV1ZN"2?T?*90O9OOH\@"((@"((@"((@_`]0STZS<NK3
+MCT(X\YZ$<'Z=AG!VG8=P3GT1PADUS;>#^?0"ZDG8S:GR&>3?'O*;=&X,8!OS
+MV^@?03L-N_\4J'8&K<OYY#\;\E]P;0]K7PZMO^)]Z.X]V-],?._L^[>IM_\K
+MPFW`FF%,*Z.QWK1KEIFF8?A:?6.PH`Q0KF&XMCG0X)_$G]169K,#_Q?(]\^5
+$F"$``&%,
+`
+end
diff --git a/lib/compat/compat20/Makefile b/lib/compat/compat20/Makefile
new file mode 100644
index 0000000..f416b33
--- /dev/null
+++ b/lib/compat/compat20/Makefile
@@ -0,0 +1,25 @@
+# $FreeBSD$
+
+DISTRIBUTION= compat20
+
+LIBS= libdialog.so.2.0 libforms.so.2.0 libg++.so.2.0 libgcc.so.261.0 \
+ libncurses.so.2.0 libreadline.so.2.0
+
+CLEANFILES+= ${LIBS} ld.so
+
+all: ${LIBS} ld.so
+
+.for lib in ${LIBS} ld.so
+${lib}: ${lib}.gz.uu
+ uudecode -p ${.CURDIR}/${lib}.gz.uu | gunzip > ${lib}
+.endfor
+
+beforeinstall:
+ ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} ld.so \
+ ${DESTDIR}/usr/libexec
+ ${INSTALL} ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} ${LIBS} \
+ ${DESTDIR}${LIBCOMPATDIR}/aout
+
+# Get all the fruit, even though we don't set PROG.
+# XXX bsd.lib.mk has fruitflies, e.g., it fails if LIBS is empty.
+.include <bsd.prog.mk>
diff --git a/lib/compat/compat20/ld.so.gz.uu b/lib/compat/compat20/ld.so.gz.uu
new file mode 100644
index 0000000..a689dae
--- /dev/null
+++ b/lib/compat/compat20/ld.so.gz.uu
@@ -0,0 +1,702 @@
+begin 555 ld.so.gz
+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
+EL.&[&=%WO^]^W_V^^WWW^^[WW>^[WW>__YM__P\[+-(F`!`!``!F
+`
+end
diff --git a/lib/compat/compat20/libdialog.so.2.0.gz.uu b/lib/compat/compat20/libdialog.so.2.0.gz.uu
new file mode 100644
index 0000000..f3231e5
--- /dev/null
+++ b/lib/compat/compat20/libdialog.so.2.0.gz.uu
@@ -0,0 +1,486 @@
+begin 444 libdialog.so.2.0.gz
+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
+<?`)I/GQ"%0FS(AFNL$JYK+SS_G_RJ@X[1N<``"X1
+`
+end
diff --git a/lib/compat/compat20/libforms.so.2.0.gz.uu b/lib/compat/compat20/libforms.so.2.0.gz.uu
new file mode 100644
index 0000000..0baf3b4
--- /dev/null
+++ b/lib/compat/compat20/libforms.so.2.0.gz.uu
@@ -0,0 +1,78 @@
+begin 444 libforms.so.2.0.gz
+M'XL(""*>)B\``VQI8F9O<FUS+G-O+C(N,`#M6W]L&]4=?W:<Y)JZC9.ZC=NZ
+M[96&T5&O*Z5C#:#1)G779DGQ3#,VH/5<^Y*X=6QCW^&TFZE6+W2N\>2136-H
+M/Q#3M(D)P1@MK$-32"="4<6OH5*A::#0B3/.M(A%PW2!V_?].-_YXA0J3=H_
+M?NKE\_V^^[[O^[[OO?>][[OGGD/WC2$>(61#I)1,B+!JZ8I*X6#D&I&/QH0(
+MGPQ%@M&DBP^$HXE09(#OC\:'-!%_.!P-^$6!'Q*&HO'#!K&^R*%(-!GA^T-"
+M.,B+AV."00#U9?Z>GK+<_K7;9-SSG=\Y\_P:A+)N+NOA,GVS\MU@EQSD697#
+M2\!.P4;!ZI5O`H'TGVV9L6P?E^ET0G5ZV(FDE;G1L;<4)?.*1WYN(9:P/*-`
+M*>PP$7T39+`'342+TRO_8PV6X;+NV?16)#44%H%8GG!US2,/(MQF%O<J/TL$
+M+;B[V6RW*[.=(W=<Z2,<DJ[-C;[#.NVAG8)^CWP!Z0PX`TP^GV>M;D1B"R6S
+MG=SS"!4W:/>.6)#H5&]:/&4QC_QY:FWQ2WEJHTG<0M`BN@B:Q?;<:-/;U)+Q
+M)LV2/3I+BC=#E4*<V\ME6S+G<U8).\7T:N;%YR8MV6'.]$8F-5N0/U84W`\T
+MO\E$FE\W5D0Y8?K._;ZS9\@SY'3/T+Q:]PQ5]]ZSFC2<<)<0HK?[2AVVH^;B
+M-NICJ54WNNVK58-!:CZS%'>I^#3X*B=,J7;HC$BM(KUXY`PJZX)!?M4R1]TN
+M+FMI2<NF=*DN^97,6QN>3;\P"<YYM^1$B`,M#KC6J]H2]41;\2KFCVNH:XNM
+MC+_%0GDS\*,<'JD9TSEA1O.5?KZ?AT[R$^[9LE-FP2GUA1)C/<Z)3IMV;X[M
+MV[CL7AOGO=Q=BU=]!+]U8MNL\P@S-Z!TR9*,$3>\\@YV0_[<2H2<T/1MP!FX
+M."=9"QXRWN.(SL-.,@]IW0<F6K=17\?D5NCJOF6F=0WY//:1XIXM?`@S3347
+M]P6N5*?9[G!8&/"'^40@'@V'^5"$C\5#$=&7$`$&4)58<F0E\YMUOBE$IIR]
+M[*`'5JHA`$]$,UUO5B\!CH+FS<<:L+`],Y8N*5)+;O3VBW2Q]356F%W%KLD5
+M5VC7I14ZNW#`V&6("?/9N&`>&W_70&?I3FW-75;/<_75]80:/FFL_UY^A6-=
+MS,8*D:/312,L7K2OYNPYL@Y@3MMMWLM:NV0>:_]87V'M'%N[K]36`\NO8+ZD
+M+-6MNKJ^F@_U\?1)!T+SAR]FVB!"%J3V==;!#..8!1YY,:QEU=8YMOW`48X,
+MF(T[V!LNXRYETU;L=@C6'IMD9T.-6Y3SQ>LA]A8_@]=SB:[G(EWWF;&1,:E)
+M7@5*BHU8IBF?+^Q3\"ND'*O1KI#(BX,"GXCY`P)_P!_GQ2C\&Q@("U`?CTH#
+M@Y!_B*%H)(%0%9_\O.U*?7*R;8Y/]GQT&9^DVBI\LK]-YQ-W*5WB17/QYMQH
+MNTP?X_XZ]IK!#E(Z+143>)NEPW1T$;TWT6G!IA:WE/WV>Z3Y;45N]&JFT4HU
+MRJ\O`^D&YL?/5OJQRX^SL($H+\7X_GATB!\4X@(JUP9)]C6W'GP=$8;%:K?B
+MH8'!JC?"0K^^OLI:;UKV*9Z).I^L'3:I`[_ZAYV*Y,R-A@MTU,O,+,$@>5IQ
+M,7FO$C<Z,[LLA383S9W*6CP6Z4:BAE>D5;G18TS-RVJ>4O@(9UMZ/3S6\S(R
+MZK$Q/0ZBYR&FYWA9STFC'@?6<WR.'D[:3/2L5Z3EN=&33,\MY;PIIM>Q'G04
+M=U:TM[+V[:3]2ZR]@M3VF_3MVW%[F!M0[]#FXFLLQS/A>5:9IUG*3^LN.PBE
+M'$AJA/0#9X-9M\,C_]A.ISE,5;<-IJ>53M$8J;;2X-5$D\<!&'=>Z;6G4W9%
+M,A?W@M5*[^S(V+W7@J;F/]F\BMM!&A^RL_F-&R^@C:^%^;PZGS_($XG=>HE&
+M*L$5?TG&A;+[2F?/7)W`\ZUL_"^60.J.LFD[]IJMVYM-VPCEE9]?HK/4)K^!
+M!4WR"Z36DM?D7J(UV5%289[8!F@B.5YNM&^*^%$3_HE>:;-\C"I-5%$!1+G5
+M]>S^OED<UNEZ<>K6RYNM^O72=S&;NIBSIJJLF0GW-*Z=<$]1D)&Z':'I\F0K
+M>VBEBHAWIG5.Q(M]0",>SLM+'9W65%VVTYIQRUFWG'%/T4!8UR<;8^'=K16Q
+M\([6<DJ-V:[6<FB<R;IGZ(SYVW](3SBHB;WJ:X/+3..N>TL=W=:C"RFYH=MJ
+M>N'RK\Y.$J?MA1-FO-BT-,C*(JJ9^ITNH9D.CU-<F$[-F,3ZXAJ8HF7OR3HG
+M%AJI+JT1+S9!HWK1PO94Y)5GA:A-?+6ATUJTX/F8<4\#BYUE]&'AJ<K8!#K7
+M2SNQC'L*WH>+6F`Q;B9[N](&]Y2VF:LS,#F/R2N_:R,>5WI+A7VFBL'9Q64Z
+MKEWDP&HSO(MBZ=04@GY^!2V+=U;:T8YC"NX5ZZ[L2ZG@/7*DW+'2.Z7TRNG4
+M-#@ZG9)1JD'IG59@G.>0<9P.XKL&\!W)^:<ZW"6)DU=B2QR0UY.)U2=#6QS>
+M&A3W-"@NC$!K-E]G//+'VDM0#*GNM]V[?SZ[30:[3S6S*:I59L9/N&>^9X;^
+M8:NHX$F.K0`34LR$8KV<;-:MI#KW].4GXA\NT8GX%PB8\`Z^H,;5\I)NQ.K2
+M>-\W@7#TU:W]LLP[BS49$G?U\4'_/CV-!5-<5K*.**GZS(?-IS[,E)Y`X"#G
+M[?*IQ731C6=>63L],M;\H_'F4^-DOF>S.,'(],+BFH5-_?2Z':>WJ`(9W;X=
+ML8*_KT"D<AX#A$7A&@1L!_X$X#K@'^#Q0T*N,.!2J'\($(;I>@009H#K44#(
+M]5Q/`L)NV'4:$$;GB@&"D<YQP#7`OP@(*8WK-4"(&*XW>?()RB4"PI[).0D(
+M:\3U'D^^1[G>AS^PU71=`EP`:%Z+$,1[5Q,@9!JN5D!(REPK`&'CYKH*<#4@
+MZ,+Z$>35V#[<!NO!8T,+V05V85NP'CPVK!^/%8^;/#?0AV!O@\>#QT(^E6&9
+M9E:WB.EN8?02IA,QF:6LS2HFLYS99&>R#B:[@LFV,5L0HU?K9);K9-<RVW@V
+M)L3Z6,/:($8C)G,5:[..T8B-42V-JB`;5STXR6.F?"OSA5K6&/AK#/Q&IN^;
+M3)];9PLN>PSR?09^GX$7#'Q$M:^%\H<-]]/L_OV,O]]P_X<&_J<&_M<&_G$#
+M_XR!/V?@7X>K$2K6@\-=0/_5</^B@9\R\/]B]E]@_L<W\1S^31MEL6Z]?+.!
+MQZDQ;B\R_[0;[KL,_&8#O]5$G]_7UU(>IZP+=/P.@WRWB=JT=RU=0S[?CF_L
+MV=Z[NPOYA$BP/SX$-3Y?7(H(^,LOJ4R&(LAW(!"-'89[7^ZYM7-[C^_6G3MO
+M<^_U[=W>V>/V(?Q9.+$Q$46^GMU[W+<A_'DG+$0(!G"SI%\4XU&H$(9#HH]\
+M1?8EXT)_7$@,(E\H$A))SPDQF`C$X=:`(`;@1C(0CHM1(1K&&H)!4D6^'R7!
+MDBXI'A<BHA=,[8D&_&$P=HA\V4:^0\+A(7^,8,P?1+Z(D"2#2`Y%[P$Q*1;T
+MBP(S0Q!A3P4B42$P"`,("F$B&O!'`D*8R00.Q`7_(6H]\H'5V#&@PT_\`\X1
+M!.@M&(T(J%9JI59JI59JI59JY7]5R'Z&ASR5__1M<$X_#)<--@5OP\79:3W)
+M#V'CXL&)(=Q_`J'*'Q/H2KX`NV<%4'X?T`3X'F`=(#YNM0"^"=@`^!I@(^"+
+M@!S@..`"P-.`38!/`EH!'P5<!/@(X&+`AP";`1\`;`$\`=@*>`QP">`10#M@
+M''`IX$'`98`'`-L`[P!T`'H!EZ,Z&).9Y<#89WA_9,$Y-EP-<`VR_+?;5'V\
+MM5(KM5(KM5(KM5(KM5(KM5(KM5(K_\^"SVKPV2;>I^,S2_7,#Y\_JN=WGT/:
+MV=T-2#MWVXZT,[9NI)UW>9%V=N5#VKE5/]+.I!)(.U\Z@K2SI:-(.T<:8?V"
+M">C[S%9,_TQ'/ZZCGV5T%UQG&7T0KO.8AGZ?L=)S-TQ_NPZA?S*9]4#/LOJG
+M8'//F2@]O`BAI8Q^&(Q=9Z+RF^#/)E9_`>B;&'T7.'(GHV,P:"^C.6CK8VV?
+MAC]A5E]:"&-G]*XFA.YC,M\%&T89/0+TPXP^!TYZC-&30)]F]"6@)QB]%/2\
+MSNB-0$\R^B2,?9KU]2#X_Y*I^AG=)YS#Z<[9RJ=KZJE8M>.OBN,N_=$6.=0J
+MZQT(!#;[`M&A6"@L!#?BH\*!B%2N\`7*DAM[NC;IF>OTS&;D4W\%[A>E!/(E
+M!J-)VK<FM64K\I'_@N(;$B*22H<B,4E4&7\`_]14U^8&T!P,)6(^.BA"TM:$
+M9(T)/:=MU_6:5>2WZ3[\8TO:DUYLBY[Y@IZY0<]\4<]LU3,=%7ZI]-)UV*6A
+-!#EZ_2^C!929\C,``#[\
+`
+end
diff --git a/lib/compat/compat20/libg++.so.2.0.gz.uu b/lib/compat/compat20/libg++.so.2.0.gz.uu
new file mode 100644
index 0000000..d835d3b
--- /dev/null
+++ b/lib/compat/compat20/libg++.so.2.0.gz.uu
@@ -0,0 +1,4306 @@
+begin 444 libg++.so.2.0.gz
+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
+FS'-?I3.Q='RITTB?!Q,G04Z`/`V9V-KEA>J6Z/\#C*%HA.C7!P`Q
+`
+end
diff --git a/lib/compat/compat20/libgcc.so.261.0.gz.uu b/lib/compat/compat20/libgcc.so.261.0.gz.uu
new file mode 100644
index 0000000..65766d6
--- /dev/null
+++ b/lib/compat/compat20/libgcc.so.261.0.gz.uu
@@ -0,0 +1,174 @@
+begin 444 libgcc.so.261.0.gz
+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
++RO\&%(^I,PAG``!+
+`
+end
diff --git a/lib/compat/compat20/libncurses.so.2.0.gz.uu b/lib/compat/compat20/libncurses.so.2.0.gz.uu
new file mode 100644
index 0000000..645c357
--- /dev/null
+++ b/lib/compat/compat20/libncurses.so.2.0.gz.uu
@@ -0,0 +1,562 @@
+begin 444 libncurses.so.2.0.gz
+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
+L<NE1P-E4TN=8IY.CDN'FH[ZSP=)GWXK8)CY<\Z+B.\2R-7P'BQ7]M@4'`0`I
+`
+end
diff --git a/lib/compat/compat20/libreadline.so.2.0.gz.uu b/lib/compat/compat20/libreadline.so.2.0.gz.uu
new file mode 100644
index 0000000..6e030c5
--- /dev/null
+++ b/lib/compat/compat20/libreadline.so.2.0.gz.uu
@@ -0,0 +1,1199 @@
+begin 444 libreadline.so.2.0.gz
+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
+A0UZ[*LNNP,X$:]$R&=Q/&&+96N.7;>9_`8NWL`*8'`(`
+`
+end
diff --git a/lib/compat/compat21/Makefile b/lib/compat/compat21/Makefile
new file mode 100644
index 0000000..652bbb7
--- /dev/null
+++ b/lib/compat/compat21/Makefile
@@ -0,0 +1,24 @@
+# $FreeBSD$
+
+DISTRIBUTION= compat21
+
+LIBS= libc.so.2.2 libg++.so.3.0 libgmp.so.2.0
+
+CLEANFILES+= ${LIBS} ld.so
+
+all: ${LIBS} ld.so
+
+.for lib in ${LIBS} ld.so
+${lib}: ${lib}.gz.uu
+ uudecode -p ${.CURDIR}/${lib}.gz.uu | gunzip > ${lib}
+.endfor
+
+beforeinstall:
+ ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} ld.so \
+ ${DESTDIR}/usr/libexec
+ ${INSTALL} ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} ${LIBS} \
+ ${DESTDIR}${LIBCOMPATDIR}/aout
+
+# Get all the fruit, even though we don't set PROG.
+# XXX bsd.lib.mk has fruitflies, e.g., it fails if LIBS is empty.
+.include <bsd.prog.mk>
diff --git a/lib/compat/compat21/ld.so.gz.uu b/lib/compat/compat21/ld.so.gz.uu
new file mode 100644
index 0000000..a689dae
--- /dev/null
+++ b/lib/compat/compat21/ld.so.gz.uu
@@ -0,0 +1,702 @@
+begin 555 ld.so.gz
+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
+EL.&[&=%WO^]^W_V^^WWW^^[WW>^[WW>__YM__P\[+-(F`!`!``!F
+`
+end
diff --git a/lib/compat/compat21/libc.so.2.2.gz.uu b/lib/compat/compat21/libc.so.2.2.gz.uu
new file mode 100644
index 0000000..2c1f1d9
--- /dev/null
+++ b/lib/compat/compat21/libc.so.2.2.gz.uu
@@ -0,0 +1,4566 @@
+begin 444 libc.so.2.2.gz
+M'XL("#L'OC(``VQI8F,N<V\N,BXR`.S]#7P4598PC%=W*DDG-'0##02)TBHH
+MR%>"*#2B)I%.@*$A1+K#J*@1$D($@DE5`@Y-@I7&5,H:>P;=<69\=MV=CW5V
+MW-4=!?$#3)!-P'$U,(SB#,YDE-&*G9F)F"$M]E#_<\ZMZH\DJ+O/L^_O?7__
+M!^U4U?TX]]Q[SSGWW'O//?=-;F\[5YK.<04<UW*8XYYJYC@WE_@W;?G&Q>[-
+MUR^Z\9[Z2N&>+1N%N1MF-[CSYU[OSO=X;IB7=\.\Z_/<>3<L7I"W^/I%[KI-
+M=9NW5M:[O3NVNZ=Q?OF/4I_]=@WAW+GG]>CJ=$[QVA2_7?$Y9>^`[(_*OICJ
+M'2BML6BGUT#D^O[CKW.I_Q+E;_K*\A=^>?D[+ET^IZV[1/D`(PY@(0+PVQ2?
+M7?$Z9:LJ/3F&X^0B7EYA[RIR8:*N(B<^E/4Q!)2<]XM55+B^W:Y-H*(@!<0'
+MX@E^PQ(HHAW2U%AJ^(!V%OI%BEK$\4K&WIZ.8\Z]/7+&00LDCZ2%\]O5RNB=
+M=Q.^5$\^#BF\*E[/<7O/=;SAW'M.]L=4?\P`7*9)!N!L!BT]'`9XROHH0$O&
+MN605JZ_7&6H7+M/K('>I+MJUE2R[D)G?'K%!7H(R0ITS+Y&?_YKYNWSQ-CN^
+M.M%F\?A_9O$UG$Z-ICT)B0:[.[2I"5CY[4-Z-#G_)E^\/ZV(SZ2Z+"EJ%7(C
+M5X7#2A&_IDPIX/7NR$3VSL'KJ'"B_5DAU/:V\D0_CD.@0:BT79DD7;`(Q74V
+MZ8)5:(P$PW)GES=&]%'.J\5\:3D`UKNEHS9HGDE*"1\HIP)#[8['VZ?KD$[V
+MQA1O+.*%-L*\T92\5C/K1):52\T95;S1%'S5RKX[[[YG*('7-VP0-FR_9^X&
+M]QRWN'&[N[YVP_V5@GM#766%L+EVFWM[7>U]6RJWIJ3;4+%M6ZW@!H;$U-LJ
+MME:Z:^O<6S;7"Y7;S(0$H'*QNU84W+55[JV56VOK=F8;M.I*:J\/OI'.Y>M=
+MWC[D'"EHT\4Y-1E`IE;M7X%\9*]-.FH/M0?'J])3SU_02[5:".T=`[4*AU_#
+MNM4X5;$_H#DAN-/[J36@BS;M?OB0CB+53:CJ\I[C@$#Z*&(%1=A5;U\I?<]G
+MWZ%V<6R-%0,F4P"VZC6J=(P*O.C#(#ZD.UJ^QR$HF_8\!/6V<8A#C4W[-7S)
+M791$N!>(27:@?%G-URS07L:H3HPZ+WB[BO.PSO+NV<H^._:D52YV`PG(Q=.4
+M(IM</$.53J%`*;95*=YS>WNJY&)>\=GD,0'M#H33'\D-AU7I4\1*D6P`(?TY
+M^%.JK818[-\>HW^3:5Q:D0XH.Y%#`/'K3$:#7KH'NFFQ>VO%_955&^_9L;U.
+M&-99`">IHSP`":KT\<IXE<0K5.E[^X=B<Q@2]'X;&Z?Z.>@@[<#*>/.(TT?*
+MH$*"@%8.?_//1]8!K7=E6B%"E58>A*2JU/(B/`*L$FJ)K51;"TD3C2EUN>7=
+MT[J*L4DATZM&$W85\QQRMSPQH$U!%/K5R@'60,-H\.[EP+.B3=D]VZ!#)!#5
+MVU^JWZB]^PV#1';EZ8V\OK!4^^-%79<[%6^_7.Q48!@I=@&KR<4YP*IR<:[B
+M[9.+[9$Q4`]%XI&F%_'"T\G=@^4?Q!H:?96$R*^7,>'1.+M<"T#!^D*MA,JW
+M54E-/"=D5765`,S(Q+`2L$L/YG*"72VVE2I%N2@,8,@8"ZG+M5'P-UY;@^=*
+MDXK9AL7X;$J6['NUQJUZ>TJU[A4H2U_MT-(5\57IHZDO(V_)G_[J@ZRUH1XH
+M7_8>E/TO`/T%VU6Q)_82]M]G/U&E/FAN&#]KH,G:2[6'`$JI)JQ`E%VA]J91
+M\280KU'\+RB^@Z&U:KOPLDF1KVH%*Y#)@55WI\,X$1F+:!7.[B+9=%"'?VKE
+MCU/JP2?5XZ<E3(`'[8KH#)W?/3\<#I3K\V&TTWJ64[<I_A@(CW%*43+(R.AP
+M>&:GI2MTOJD;"E4K^^-T$0?]C1(VB!;,EA9Q8CJ,5)>%I78@OB8`#.(ADWHP
+MDCYD[$I"+LN`L&.VVFCK*K%APH"V:#GRHSV@74MP1!P#G4@K,%I;Y1*>X*7V
+M71SBB\7FP`[MAY@!/OK)^#@43_=H/!U+U,5927`YXZF'XKH^.8>ZP]958*.Q
+MIH"7K67E6OTRY/D:2[E6L2R%DS@.QH)K!3<(^_KZS9MHN-A0N5&LJW1O$[?>
+M5UGGGKXQF]M0*V[9B,G8H."NV.:NV[[!75]9UU!9EQ1=5[D)QY`ZA+()<KHA
+MNIX@F#&0;?B0,J0NW_$R'A+M4M#)B5<!:4H]+PT5.CE0D=Y?D@@/2Z^47@]O
+MXM0:7:O&"DKXC1*K71RE2OS+%W02:(%RK1"B:\:JTL%74":5Z\]C2NWJ94AL
+MN9`\-U"N2E>_/+2T?P%:B-RK/(]*8DV.]B/XE(_($[&(DT*>XG/)V?*#/`X;
+M*T`=R0&%4O'ERBN<BK3R>E0Q7?(^?`%:<8=Q#"@>5L(R`&GP"^N;'3MV9'-"
+M7:T(PS>T[/8M.S=OV^06:LW&S>:V54+[QAN]<F,BAK7IGKY[K^*XI)9=N)2H
+M1-IAX\2;0.MZWDED9=>FE!@RTA&R6U`([WQE*'Y/`X6!FM\+C[`"Q&M3GL<:
+MA<X[6C"!>NBI]W4=ZN8)\([0/@CQ%-L<(1QCJPD+;1Z2*&AJA;9RO<&^!B"@
+MR`,AXV@)0ZIR)4/OEH]0BXH@=IP$PBDVE>D-*&NTQF)SJ)^F-_"JM'L8BND,
+MQ6)$,9Q2E!-4OQLAK,$%^(:^":U<IDH_'`;@J)<`()PP%CD`W^I/'H.*)10O
+M''CKQ&V+08VJK]Q2N4%P5U5LWE*YD3/EFSNIP3N+$!60N3W*\SD09(I=E+=`
+MUF(/Z#U>E+A6+TE<*:H+XT`XO170GJ80/O)ZRCBT7Y6<AU"IF8FH59X:KA"F
+MS$F*H7SE^;743^+DZB73.*S?>B_3`&P0R`-)>KOV8A?AOZJNO1NO8N-P#,?A
+MO=7PI?[=,_!7_KL6^%MCI>X,J'L?NPJ;+`OQH.S&=&;(V)C`Y>5"P$4B7-J%
+M&]3G,']7,_XE"=S\!$+G`DJ!2^\F`=MY&PGJE#E.RIPI6?X5)BHJ+%4/$W!"
+MD<3@7@:\W`0.<O`V4\.<R&++B4I2RQH801_[K`"'+'N\)@X0R^G4%OK)"!].
+MGE?$\[Q6P$A_'^4Y*4Q1'R($Z6]<M)^(S^.,_(DQ,R^IJG4(+)C7Y3V%TN+E
+M6@C=>PY&W2IYC57UGRI3]KD='`>/7'Q`?SVUU\*MT8[=QCH]!QIH$RJY/@W%
+ME:\/A9>O'\65+XJBRQ>3@Z<5WS39UZ/XW++OK+**5_RS%>^,LE+5?[I,?SX7
+MZ<.OP=LT%(?I`66L?A(U1+<2X`-*F5,_B92;$7Z-R9=3VFU%I*]4=15";>6H
+M6GF46I;JYDRJV]_=RO2XH+T\H&7<9JCRCI:?8XDE?&E`^[0H'OAW%&B#P#.)
+MP#W8W<6`!?8F3+_4<KOL[R\+:`>+#/$A5"3%1_5&9T`I<:$HPCAO4MR`?&26
+M/RJ7VR%,%V,F9<)<94N1H1\)$RAN@,4QXN$9[9Q-T$ZJSO.+6\SA3<D`!/7G
+MW=B(O.J-E99KEQ699'DU31(UBUDU81RJIQEZ@ZU<*;:#/#/*8:K/?76U%1LW
+M5-3#'&!S[09ABWL&3.[<F[?!N%!5L:'2O:%V6]7F36(=S0EG<E^5O&I+Q:;Z
+MF0SW@B3<S]^,_>/L\A[#@"[O:61\63RC>D^75D_;;&M'J5E<:+0TSOE^VH'2
+MZEL%.,'I'81,\KDT_VG9_Z8L=GO><4A_(%KJD?U'4=7WMX,>U2W[3S4_.-;J
+M"'T?(T%VBMVFX-3%H]5C-[NIG-\5))7S:RIG?`$3FAO"89B"]5=)/6E54C1-
+MO!WS76WD^VD\WZP:8.5NO<ZEM;&,I=I.8N]VV2H=X0$=W7L,6C\R'F2P=R`U
+M7$$LG<Z&<8X#14X`HRYU.F5O-Y!]6/)VNQ7_FQY_M^.AV<"DBO>86OD"==1M
+M;.IM*%+&9+T*9M_Q+D'5BC.2U4.DD:9V.TWG;U]]3U'9ZL*EMQ7>OC:1:MO&
+MI/S;*S`#5Q0/,,8I<R7`R%57N:%R<X.A6J!>$8?`=(>\F2FZPQ<WI7/:[<"?
+M<JC_'=!2@II\J`]>ND+\N[J.E-\5.@/?F+P&)N,X_[\%4_=`(&MNNRJM?AU4
+M,4P=!HJGG*4U[FK,I>_'A%KO+09K!<>H4@.F/D%+!6&<YAPKU7J1`A_'I!V?
+MI"L,>,]46DB0.W[UL1S-6OKX,76_#2`'&$@UM`ZZH%2;]S>8]87.0DB-4PTM
+MH[`?`K3.T')XMQXD00IS]M`*[#&JB[EH%UH)03!>AV+O8*Z;"<=IVAQX7D]A
+MUX>X=Q'ZZ7?P;\]%;!8,(2X)G;UHOFGP9J6W/GA#P=P5ZH^'#<!;.LHO%5M8
+ML<BA*(0HA;P<BM&+30YQB%RA70[Q].*40S9Z<<DA.[X$;?(A-[Z`A%>G48A3
+M/C2#0ERRNH!"<N1#>:AIJE'$5W528*Y\*)>2N64UA^I;O0.P44/5GT.E]?W8
+MV=IET&`J5=`,<2_!QL@!`359#6')9L34"]CO(+G$&8>Q>WI_:L6.5*4G7T=6
+MK89\A],X4M-[%8H"'NMCF9D$#FGXZNV#%-(.F"J/,2/99+F+FIXGY7,1%"P?
+M.H75V=_]#BJB^><]^[&S=Z\`N"W[D0:,?C1['Q3@_1H1B%%#(L!25A\/%>X(
+M^2!E,8/4=%`*3N,<+9U0F_@"$'4DK@%1/^(R$'6C2HTJJ]1O$@Z8K.M4[].J
+M>$SNBL^_&4FQ^??3H`?>A-K@P.*X-NA$??<P4D5O&3%"7!=TM#0B0.DE:,[(
+MLC"0#T"BM0]Z@_I@<]0P]5NG5C&J6'F3T67!:Q*:Y6NJ=)(ZYFTH_#!O=,PY
+MFF"!"'7LS<*VLY2:D*B/1]TTE!RR%IOD4**HR`X>%:-%CW0(B9\3\Z1#47JY
+MMDH)18G)@.<6HRY#".NB6PE.T]^5B0.!@!25Q(P%>81-"XRF9.6NT?[.@S-R
+MMT$<P5S]798%&`>&4J*<K#4FT4B'2$@Y6A9#YOSS$9=$/6"5#N%CC./;1_\6
+M;R<5`"N'B!=+W$P_A*GS3XZ^DSP?V+ZU8CMN;<"CGF;%II@U=;=D_>;`C>F<
+ML0S<!4,__#N\!-[SAZAQU0/0U37S57\LH;_E+,9UE@'6ML7*,E`I5'\4=+`9
+M*'"-N5P-7XJZ&&ABJ#"H^]S'+^AEH)]H)SVD1BB^`64-O\94T4"KT9Y>E*2:
+M*=YH0G.)SR>@#HDJ?'9#.BVA/N7!*3";`,_3Z^RJV(\[,4J14\_3ON5AB[GF
+MXJV+K1<%M#L@(F)%O45+Z/%QV-^[`:<(L[&CG3`+G%C]'$\3EF<685DL1G;*
+MW:0A3]_(07//O6\G6ZB(XYJ3U-[%`%#[`7*BMX^MU?2>1\I^93;HQIPC=`2+
+M\O:E_YC'N<QH#ULH!C7R9Z2XVE3I^V_@$B8J?9.0&B#M,Y@67Y[&E[QV>3#V
+M$O;DN7^3CPUV+RL-@(3#3(J_3_\%`M9^O8C&"T"@"`*5[V)&V:_A^T//T"*G
+MULD[.<J`W_HO,(5V-TA'N9-"Z?L\$$]DD12%^36*\2X)*T$KZ)SV3XQ?089J
+MKULP&VCY-M"H/`&;^"?-C4']:N69A$Z:U$A7+DA'$/<P$)J$B;M"NG`S-("^
+M4',L,C70R4HC+]W""6<PXD;M_$(C0LR4HY&)N`[3B?%B3^1EP`-U]L0DRNR?
+M1+'_<CWTS44<E!'9G4:?X+J$UK+0Z`AACG08Z\X)H_0#U`B?0H]V[:4P9**]
+MSQAOD46X[DQ-@O\0C<FJ5/(F+4#G.;![)P)4.2.2%0X#\OD+:>4Q*\`GYJT)
+MW,8@;O>9N-68N-T*N&DWFKCEF[B-E7;SG&ABN/I2&%Z=BI\PGK*-!F2>1+&0
+M@>%#]@23]Z4>G`\XO15#G(Q=*%Q[F6E)(F=<(E7W,F(NN#%.S+BX8>`J+I(.
+M$T+B/-4;+<5)ATH8PH/HV2!>_0!1+C([2)R(!\;M$9/K!XA@J>:I69^CK""'
+MQ.DP<5'\T4[>"BP519G3@GS<B6]7+:!]D6H<8WCQG@1-8P?F#NE`_PW8@8P6
+M%^@W5G-0SI[.ISA<ELV_P9S>738"2VKCL`.LB3VTJ[,Y=];PN=G$?)S?V+5-
+M7Z#(B`'R-A`97^`@B-M-2C"VIPO+*]=>6H#T$^MLF8C?V5!T\\OX=K4P3Y7>
+M>0NP+M=""^+K+,+DS@QHH/=8Q)9$A#A*&P<C42_N3(4A33$`E5]^C-`-%S??
+MXA8N--^2)?PUH-W*2I0?>A);KUMJM\D//8&O70;<@.8RX-HCUX>;@<(68OYY
+MF/\ZZ(-T7&;S=-6GRPNE+CZ>Z??7)[#,0`S$HUV9'`G&6/IC1)/]22/"L#6N
+M#^8!7J^LPY4-79Q:DP/R.C:?[1C9(`1EKA]%"B61FER<>%DU=K%V-Z8J<74"
+MDY2@-JOC\-SDY(1KH`L\C3;Q"IAJ>AKMXD24-XTN+71]?)J/E-Y50GOU>B.O
+M?0C]E@3D5DYP*9.4%7R9L@9&.E8=&N]LFH:E=B!G'!=''1R-BM4!;/LN;Q\;
+MEC54MO0':$#S#Q"$^=J_S$\>T-1R'D;5/EW4S'&M!J%F,B$_6MF'6UN*-7(O
+MRJ02)ZUOB7:Y$2;]3KG1;E3GK?E4G2YOSV0J^"PU.J*MBV=UL4<7IZ%:(^;J
+M8@X,H66TRG($AMM,H^9R]P@K@!NV;!/NJ:MHI(W>X@JA8HN[NK)B8V4=+M=O
+MKMBR^4&V+UQ95U=;-]?HSP7)^]]S<2GM+N@L=;==%M\$&IU>_=15-!!?G9\@
+MW&SH6!QV<&^;DG=Y3[$6/$VJ&D[GSRA^N^SO`?4V1]V+RX=`_._F@<[H[8:W
+MO^8;NJ+H4*7G3J#R699'4DLIX0U]:^^3D`L^S3E`5KFIR1DKD6KQ-`#U$`*5
+MECBPW#?E(E[[#G(RO%H5[YMJ97O2ON&RI+I>,P=2*8B\[&N7WY(Z[4`5HP]B
+MZ_96LWDGD\M*,6^N32J^=GT/UD4)\/J_(WKRL72J6T`ILAMKVL)BB%6]=@R+
+MFPA<@WMC%J74'2A-"@4"<@44GU,_P093MM[9V\LE+61!TQ_,PS'",@07<QKB
+M/8-S$&\/3D"\9VDQKX\6\_K58'=Y0*N;:S;U*%J=99O?JO<HM%T@#Q>DCC)V
+M=2..8Y45,-L^4UH&4TX#3=']&G)1Y':S#J5&97&$";T+(@PRWVA&JKXSLN_5
+M-9`FGC^=\DO!'DYP=&6P1<]7`]H)D!ZX(/A,TG[9,+VP:19;/Y6(*DM1RCN[
+M"NS&RFF9?B*2$:9.2^SCF3#(?L3\'E%^736+*;1OSTWLBT]D+-QE1?D`='X#
+MHP5IM\TJ7&'&4=.S]R+;/&R<7T.:MH"MU?\IDQ,U-C78+P=[4%'7Y@&MZ0UV
+MDBD!E"F!N5BP2SL_EVG2.:#RCC6!C\5.>IK8J0_%FE)FDRYD",NE"V,=H18F
+M+]*9O"*]P=]7!FJDXCM;ML;<F^W13LV)K_DZ6FY`G=%[%F4-#`]AFG)"KD3J
+M`\FI,Q.IC2*0H'UGU]18`DJ92S])-C8CM<1<Q/S819R#H\XY5$"EV/_,I/TH
+M6=KN,/JN0A2JQ6V;=US2_(2M375;4M:F[D$X05?-#"U[-BXY+;A(XP`.%#=#
+M2F;&\)=9\?YUM%Q#NUQW8;$JII8+W?(#TQ)F'78RZW"268=+*;;+A7:EV"D7
+M.I5BEUSHZBK&W1QLP=`BG(1JUT&Y"KW+7@UM/I#][+2N[I1],&NS2:]@)3EA
+MDASU4'V#&0H]96\4%_[EH+'Z#C/V,&*GKD-H:A[\7:,>*H!'N?;#62@[-6#:
+MX[--AL[0_F,V[LF%EF(2)C6[Y-TV)BS*M<'KH-[%/!,V^>4P44>0VFGDJ0RC
+M]A:0*7(AKQ3;Y$+;&FT9S#P4:L7(9:JT[9VA^V1/7D?V*C^9=C$Q$Z9^:4[M
+MEZYKT[EJ7/I2:<9>JMU$6-LDT`(SM3&(=KC3JW/:%.RV+LV.CTXUU(QM6N/4
+M!F:QL=H6.A[,U'XW"]-+GSMWI[^$S)Y_TO-&<+S2\C@FEUL>;X='D>>-77]2
+M0^VT,A`H-\OM`E5>_8E@HCN2C)ER;6('?1J.P<\]@ZIU>RY*09!T2?ON4E]N
+MLOYS#=0I:+<Z0M]EPYY2-ZW&PN:\:E`KUSZ:26OZTFY0;<;I#4YMSDPT?W$:
+M2HD:@"'R;%FYUGF=.=&:!!2'XZ<5::Z(1YHKLD7F@HZB,9EWMEQ[XKHX$.A&
+MEIBGQ#9(#'!0IC5!%0R#A-/)^Q'):_I779-N8`TT[RGFQ2P0>*02A?7BG+A:
+M1#,.J%>##7=?85#1QD`U5+\F^]L!>0]2F?<H6YXHP]6L8Z6:B_C[&+!$E[>;
+M,/6>2NS"M9=K:<FY<D>H1YGV*FLE`$`V14#\JM@=T(X3Z%-(3*@69`1(+5"\
+M1\V%]M0Y[LW3#;L<W#O6GKF6M`SJD5'8(S]D`7KC-"ULQ#517*-3:V(!Y5K#
+MM0FC')13]VRKW5:9I&9MK:BKKZ[8L@6WZ1.+0,/HY1?3"!55U)3R:=#S!K^C
+M1I\+ZOA!*`4&[)=FF.MH8]424".TIV>8L^VQJC3QMZ@L38>DD0ELW93I"8K_
+MK/P0T2WH4,5\<M.8%)!,\]<B*GXG2*JR-6B$:0-<<&='^^&,=',L)?O=^IWU
+M&Z!F<V\GT]WY<Q?,G8_FNS?.RX/_;W#GS5^\8.'B!3>Z:^ZO-DQWP]]<M^8'
+M6$PFMZ;.\GKOFAGI3/XS>)LWU54*8MVVKX"X(`EB[Y@9R/]J^B:`8H"N^^1U
+M$][VRFT;H>6_`N#UR0`/0?L!O`5)\"+*RFF\;,EOCX]8#'ZEL*5VT^:O0G=^
+M,O1[KF5[_^GSD^#WQMO^YU>E<R!5L7!FV;3NSM?CY=55WE=;*YBE&9;2^?/F
+M7^_.RU]\?=[BO/GNC14-FS=N,@L[=PUKFX7);?-V'-YVH:YB0^578)^?W'WA
+M_/8XJAR@JNS#50/9>J>:?EE2&="SC=>D<TG_J+S*'94;A"\O[GI/2G&`^TV0
+M^\D[]KR!D\.R_V64T)N3"I[!OZ_N_B3HU\>AS[_!G;]H\0U$.?=MK#2A1ZX#
+M'EDZ+6%A/?=*K!$NO2K*(@SR6!HR%(L,:=3TL4GULV,VV7H0/U_O?02D"*.'
+MQHK[+M$[\SV+`8N4W@D'RA5AFEW9-<T)Y.6*G>@=[$!E6'!!O:O^M:KCF*WJ
+MY\M9F/B7CMXTP9L(_^\^EXN'[KG;7.M31%M;1C'P>81?=$08:!M;V')2_"L,
+M=P4S.U%)BZ;,[R$][D\[0^>%Z?(%R-4,$VH'X%K4O)@3+T3XHE5"5INEU5K8
+MTBY^UFDE!=X$P=I'J-M2N>W2+93O&=)"X7`Y-(\MEM]N+-P,GE`+]7M>3ZR#
+MH8V@UZ9NMZ".[6SUQPKDS]O&MOJCA8O\,2$+ZO-IY&.(FPG5Z4]2.0D?4!\W
+M;-U^:7SR\H;C$P"$[-!OSAAV6D>O];-_%JG_I#^D??93T9G??O<]K[^$7#'S
+M[9EO??93QX$2W7$@H,_LOON>UX?0:U55_:4*!W)=,+1PQZM`=4)Z`8))$D5F
+M_Z3:OMYW!8TG9"N'<_*_<6PO#;K-PP'&?AOT$(3_T0B7"G!$7<0):_+:H5&3
+M5\K4[;I'=#:X#&/C.5?AXESO,Y01Z&%5P(AX%=G'1Z"79NN8II72X.[Z#LSD
+M[5?$_B[O`*)H['?`B(1+4F6J;P"48]#C@DY+PU(,FB4%HYPX*XSY^\QEQH!V
+M+0!*$V.@.6&B#$PD_([^9K5YHZV9);H/8\0#G9DP=/5K[T[%F>0LH)&$H2XW
+M@OW%_,M)T8.!U*E(]Y(1CYB1WQZI@G8_G%>`3)*)=FSO"/V.PV,+85(V`#-"
+M9Q>EY:A'(HM!7NW0Y6`LGB>,:3WG1)S$H4T5WUD`#4-Y\`1`5AC"ST1.0KZ4
+MU33"3_':JW#.\,:>#[A^CMMS@;L7A$-9DQO>W/!6T)0-;Z#J"7='-L(;=*`P
+M+7)'.`SO3\'[(HIOAK=K(DOAK1W>9B..G=Q&-'N#YP;0'O%Y7^0:>LZ)7$'/
+M+;1NW\G5D[US)[<=S1?@>6O!^?^P")F=,"*F4_J"EN-!6R?7:,3/*4!LT<A4
+MNE`@7-N4%3HI3,9I)>($H4+NG@L%],2"L#Q6S@ZCG-L-./4%YSO<*>6<[W#B
+M=Z/YC>78>"S'-K0<GI5CX[]>.?R0<JS#RL$]1CSR,:0<*RO'8KUT.6N-<H2"
+M3L[=66#A4M<;DNVW?G$9T[=%>X(5QP3*M!*@W]Y\6FCH\O:3084WQAX]C(]H
+M@;!,FXB$[CVC!,\$M&QZ/ZV(IT$W!#'M:/D'2$,\=DKU:;*O&UC$T1*B_'U)
+M[(@B_29=/&7R6[GV(LB1M"#Q&\1-9?P6F:2+W:8Q?4#;AVG$_@1/]ID\>0V]
+MNQ5OU./M$XMPG4?,4GP#LQ")'L0L5`=R!E[$B9C7[CB0,7A:]IY%PL0"<Y&7
+MQSD.W"H'ST8N0_D5G>7KBXS&'*,P+D/Q]<B^L[IX1NN;@BLGI[6S4Y"5SYKF
+M9"G\K@1=(1T0HI9N\SE;?;%P6T:KM;AHD3<FILMHJ+-:_!/M4`WAQ\3YI\GI
+MW&^]]M]LM9FS/T.>5]QGRO/KA\OSZ_.'RG-4(D+M.ZV#IU_GYFS@ZJNY>?=M
+MWC8/G@:^]B3Z^&X.SB=MG#B:+00>87(;TMHX[8[+L;^CN$]7<CDMLNNZ8,.*
+M1E:A_(QJSLO3:;;6!#,__-/[$,N/<0.YN--'^YJE']/&RNWL$<"']B>,;M)^
+MEXNZ))W@>267-IWA/4U[-I=LR#E&+?^.7UT(]!]R::-'%P<@0QM\!"#Q0[F&
+M-3/BEP82D#9\XVNP2Y/J^T^3TMEB<0SF,;$VKM7;KWMCC@/'E'U+44$;U[:V
+M[8:.3S+D$](?+.*9YF#_''%<E_<,+87Z8VWC6OW]P(T00G0=[)\ECDH"A.,B
+M4JK3*5X+D7GBE9"I>?$.(;UY\3K1A2D++)!4\L:L75XG.\0$0ZD+/K(9P#PQ
+M$SYP_4/Q.O-/PG16]O>Q]?\:KD;7?CV%)OBR]TW9WXV+SOX>LF([:Z31(<W/
+M4M+`7^^IU/&QRWL:'XX#8O]@9S.^A:Y%82!_&CH?S&CUO>HX<'RP`Y<SQ!QE
+MWS)$\\@":!I+QR=6:AH\(W8\=%S(:/;V=T=6.`[X^N,MN++M!DCA:/FU48()
+M]!@`36WF3((EI*NKCD?2U%4_:_7U(R2/S^GX]O>H;4YSN^;`/-/CCS9.!^;S
+M>*.B3?'W>/P#C1,4;X_'.R!.8O&BP^,[%<R&FM&AC4+HH]/4:]Z!P4I-[I3?
+M5?P#CF?]?99W%:_F>-8;M70Y#OC[Y>[OR]Y797^[W"]?2/.^.A[>Z+2GV=U$
+M'^>,9FKY#:[V`5K!7&A1G=8MH[1D2E.6+BL:`4><4O`,)V0/KA^0_%%N<'U4
+M"MHY81P,NYA5X!5?;#F,P[*-[/Q`GWTN>;UD21*]GG/]?Y)>811A;7,6_C91
+M:XQ)&5F:S1TMW'O2/L\QZ/542O`G9G`/D/=7$C"NLIJD=O1_@GZ[_]]+OT=E
+M_S%&OT?'P]O7H=^\%/J-]U%2(S?_[]'TP1'.C\[EYIGCWIZ^:CYE_39S'(X7
+MJM3S)QP>YD["M?4GOS#,^H(3JA2*4?SV*MG:>YKMD53K:60Z@W.!QR:0K7SG
+M0SHS]+/7S,/@]R>:"YV+U1T6C]<N9JO2!P`I`A/B9?!=G]Z\:)[P5]2C`/]2
+M[;&)IBW#(\NA%-*U8.J":D.%ZGT*]_],D&)IE>)]NFHZUU]U,_>4.)V,!,CB
+MOWRB><;E$1XM^``OWLGU;H:FAJ0%XJ1R;7:B'+)+?N4L(%6N/OX4F@,\_@3\
+M+=-RH$XF4.VS"8:Y-C.RR#\/4)L7SQ.SFQ^T<(['VAT'^IL/86Y.J$J=;;TQ
+M>%(YA!!3YE]+K1<M_04W(_B&,<PVKXN[%?MZ+<Q!QK%6HB/8#U#)-GT_PL"`
+M>\T`["!MQ02C)D'C!)^2%[DV;$3N'X=JDSTRRXPRPB>P3,;7HYB*$LAYN-C_
+MR!?)9F_Q?REV,^\X2#9*KY2B7,)C/"N=:+(5:0B;KV0+ZGE^+7SLO@K[<1^&
+M;U[ZB]C659V%Z9X\2,3_HIBE:/J#HJR#I\JK6$(:@R$M=:(I('M?YL1VCV1H
+MMP.-%2O26DK>;&GW=.Z*&.8T=17;-M9N7>Q&L^?*;;7BIFIWO8#VUS.F;W3?
+MMU.HK)]YDWOSIFVU=94;YV8/M8^R.-AL]WDL4.J,F;4;RU#H*J"E\<A4LRX*
+MX32SNR-J!432)$PM%\6DSS.;KEJC2D?[AVZG^,:2=?QD8B#I\ZE-5W=1)N)[
+MJA![6V>\T>:M]/FM9CI+/%UF/!TR7*02]RP_;VJ:Q-)9X^EP)RIR<WC/Y[@Y
+MT^1FT6GQZ*FI8*Y@\7P\_M9X/(G#H%WJXN57J.ZOL/8_E-Q==SG9J>L3?P/1
+M832>,[7QKOCRMDN<6#2[DO7?YFU5M>X-M75UXG:A<N--U,$;JBNV;8KW8^I:
+MR8VC::T$)NY*)HCD@YNJJJH&MP[()TY\K@0'.O2I\ELS+\J?JKRLB`,S.W$7
+MCZHE=<7D8/02N$\/,ZQG42A@+GO[U27-:93:(-,=,>DBWS0K='[7M?+S&*Y*
+M3^+F(_^<S"A6>L[\Q&:-3`ZKTJ/GAA+*-*1$F**9K6T@)"Q2O'T=/5AN6A)7
+M*/Z^M'T(#<:C0>J7C@^L\KMIE%5^A3$1!:=DQ=XB.]">8?L%@Z/2S3+%J0;C
+M6N-L.QT'+=DJ'T%S+NC/I?'^5#B+56%<ZSSQB41O/`OP4'DP\B:QMD29^,B5
+MQ@L#8J2T)S.^W)V8F"7D4<+_!>"[6=H""1.RA3X)U>'GM":-,O:C,4W"EF!/
+M'Y>ZK_F7;.P'I^*'*:9XB[H?M9K\=L^[]>/"X=:.BQVMC\S`H`)/=UU_9PN]
+M<VAWV,K>"VY&MMO]:?[)R,RPXX!KL7PQ=%*X8L\%#!8FFG)_(F<>=\9UXK(`
+M<Y,!?#360I:5/QE(VL_<TV=+Q?$;V<QF`M`4$<W;U,>Q;/EQ-$D'9`?KQX9;
+MCUP\TOJ8@6O_E^-Z/C('<%UPBWP(`83.`[X7+X5O%<F=\4V3`OI^3%W#K4&\
+M>S.`LI?A6C\3YZ6RBJ;@FM]N.!A0Z!N0S69P<(TJ`:(<852DX9YV9!3;@.Y+
+M;$!3&\S(36F#DBS&[H<X34<U17Z<UXP3$39X41^W:]@B_1^B-3FF\70[I,_8
+M600IA,$#RB%\*+?*09M""94R7O;;C>`F$"5.Z<+XILG,1JN\#'&T9*"RX^K]
+M'D+"#>6@375]3W[\[(<H_S;B'HTC]`C)T&KXP%941)OGG?IBY)L,P,]Q@,\$
+MZG(<L#NE3EZ5-EX/R?A6:4FK19SL\>4(+H^"67=GR/34)83JV8\E-!Y2Z$OE
+M"QB6*O^P1VN8RC!,N)+X)1E)N'H_97H;JYW\^!GZV_<A'F'1/F1'4Z1@#B=>
+MIKR":!BR'1"V=,K[!R!%Q(%']JAVT)8?0[.\4KTPGE!])`>SF?7^]L.8V>\L
+MDA_OP;QI4@<O>3@A*GDLNV]6#F&1'L]NES)6?AS?617D0XB6@>)\Q8+[PX<P
+MO_R@33IB-[J0FDE^8^:1C@M6Q6.4#UB^\#BBJ2N(`1;'4&EJ5:B:>(ACX&/C
+M$$?T8^,01PQ?6*F9LE4IH2WI$MR25BBUG*E08KF$5RBQ7(+VUJS]E$/8&)X+
+M#@GM)[%M*72<_/CI#XG^H'\G&?V+!\*ASP]AC'R+'*(4?DQA58*88I'4HB+^
+M,>4%>GKV(["Z7[(L#+2\6-V'E5>6M)G5#F%X%]]&G46=XZ&DCH>VZ7%R)QIW
+M/.PD\X@W/S29B7AI6BHO?9&>S$NB4][/>,EE\-)^XB7"S0#>[Y#Z3%XZPWCI
+M3)R7**'2P,LPFK)@Y"67=)%X"4T>R\G!RWXKXZ4P0I)>V7(3,<\^8I[M-YG,
+MXT066_EBS/-YW6U(RQ:0>=""P$HY(%\7J=(69!(^+"T)(P/Y<X&!]F%V8"!Z
+MZA)"ECIB'I^MH5VA+V0@5A]^+S#057%+S`0/_8IX**?WG,%#5!/Y4!_][1_"
+M0[F<>(WR_!9BC?W4+3Z;I4.F3NTB#$F=F()KGS8@$I5_20XA/X&8N(E%*L]O
+MORF>76W)P4QRJ(?D"FN:;S]/&IFK1"8:!%C[*?H63AP/_8#O!NN@E>R?6:PR
+M4;I@V;W00QP7'&=R7J(RK!WD,7*`9[0M[[9)G7:CNPEW!@FW$U%WLW]'?B0T
+M0%`PF%G@Z@HU,F@OAY)1?A3/XRO[2:!F&+Q8;/)B<9P7^Q@O9B`O%A,O%G\9
+M+XK.>"O;+1W`FI8C'I^]W@%]+!V)`=-;X+/N4QH?[>K*PS'/IW5S&>T@VX'\
+M%8%V^#RI)<2X[S%6'XML)3*Q-_S:9")BJX<G$1-U?Y@8DVE=%V0CB'!9C$(Q
+MJV0Q%CJ_^P$E&$6!/]AP!_:U,PT$J#.M,2:+`XX#2+J12;C?!A\9\+'(E2>.
+M*]2]&-?FRG,<..+QYH@]R?$-XQ2'4A*3,^75H!S&/$%;W=.2-\KKOI@4C'%-
+MCZJ5?>;,+75N,]W*C!]K,A,ND.;5W%RNK<DTY^B7=:+=3P%,LF_`1)WEVE:>
+MC/;MX7+M/GZ(UXKA-K9'++B>[;0T3AZF*/2^P3,;6[;&`7TQV(4S#M$%S3/8
+MB:\PB3;\80W`/,/Q+(S=P8-R5&KG2[7+>=K\,/Q\,(@[$"+DEL5329QZ.J#A
+MTH82/)@6/"T'WS26K/)/@FA1`$)[VK289Y&C90S#1Q%/R>(9N9_"9>\Q!3-U
+M*[[3BOBF9]#1<@CMX[S=%*T`"MU*\(P<[)_E/9WF/85K8]X^3"EV"Z-3DWF[
+MS31GE&"/)P@B\FT\=B6>\8A]#LE&2R=]NM@O^X_*OG:@1/U=/+;E/ZKXVD/M
+M3=<I8I\LGE70JO2@(O;(HF:<(XO,H#615^6@UCO:0FW03RG[*.49EI(C013E
+MQ+N@K2T8H7G$@PY)L!A[!`=U\>Q(97N\,8>Z"E(5H17J)*!7BWA0"6J>(.2^
+M$==D7J=^C+)53B>VX4'+.[+X*B:Z6)<_"SON50@$JI]2CJ4D%6'`OQGE@/BJ
+M+!Z,^`"75R^-RZ[+*9WF@8$RA/O31H?V/L7&6VR'@Y:3O7A"DNRCG&G>@QZO
+MYMB+IK/PK<WR'LP_.2@Z3V@XV#[;G>8_*/M?+3,0`\IY)X[8+AMKUT@&0RX.
+MK?'%R*+PB0M`599WH7+E"7S-_'%\TUE^P@N0KCL.+8^@_#!R]7N"9\6-4G"`
+M$]!'B=@'4M!",J,/M!6`#NW7B_T9#^]'+>9(3(STAHSZ]K5EMEI*Y&!?(35Q
+MW9\@K-\(ZR]<(7X:N1O'82QC?G@8K$09J653&9%I*;`2\!-E`GP@1H_8[W@H
+M_V^H%)SQ!/OJ;Z;BIH9'JM,9+`^WL#&N+:/54@PQA2S\3Y$B"D>`]0L)R!58
+MQWZ0_A8</8*$,\0/`HR)1/?)^&'XGX#DE>`Q>6$R$[_I"78[0K?%\)#S*44\
+M#3)"!I[V@ECQ.BW'<&_F&&-62+K($?KK%TB/ISVB#91?EJI4%T\%M*56U(5.
+MR4&0/2A=M#MUGLZZ/9,D`Y-M_@['>!B'7);C,DID9WKCG"1-PJ8MH*.7=E8V
+MDJ/?E0:S%6>OTSP7[91Z+.IVGN7"TP(S/Y7?<CPKNM)$6T##XZ+0?C)(('2&
+MJ"ZU)0!9WI"=Z.L#/1JZ+-'2<L67@T<-<D+MCG^(^QH$J2;]B(3`83J\X8M9
+M/I=]`Y$\]'N0YG5!O0>,C#`F[,X&(6(1IZ#S1Q(G8Z5.*^;Q0:(^CV^@[KAT
+MT=&T4O%KTI&TY@_0":(%33/2O';9*GLUS+3;#1JPY0+P"LPK';+O;)NU-;.D
+MS7NVU5JT2NR;%72E!6$H&VA\J3=&*`V0.;6!F(`(>0=F`6K#\,J.E#*\A&5)
+M&`P,+7^&XA^8Y7<1K5T"!W_,\V[='Y3@@%FY?JQ<"V6?SK)_=5[@A<;QY6B:
+MDH+KN#AN9+42&8<^Q.+80M]Y72:ZS6+4`E`<#]^#1\OCIKS#]XX#%WA<?TWS
+M.VFWP;Y"]L>$VP%N5/8/X'%0?[3!0[K%+*2\@0!T`9X$1GRNQ,/!06?;Q#9+
+M:T9QZ]C"U>)G0$,SC8P#C<?AR^*/@E(A_EM\.W>(?=;W!W6@)AD$?PSWL'=E
+MXSZ-[HW.#$*=</\CU3B+,^Q?<#O!.G@Z#B^9=Q[ZG$?[:HMC[[568Z]KTG!-
+M8C1R"K"39@-6D[W]3"E@ZPB]:$T!#$!C$'2B_42OH^48\HPOIB[QT<!AC`M1
+M9/(T[P".X$&[)QBMGRIWIHG.0"GQD#E>:8!O!G"<CEXZ8_$\9X%-^H8FW'T3
+MC)8HH\ZV32*A"6]`*'(0!^?622A`5XE`)U$Y&+/H>`R`"G;LQ7G:<D>H'&MP
+MF<6PP0(2)%'4"=1G.8*V<-962U'A*G$0(UF,;P`5W@'+N7B<[K/'C4FBY/=N
+M[4AUG6S4U<1_6"T)`8+>ERAW*.8-/U:"N%PJ1SNTJ9;HB:CL!1)/*BRYQ23=
+M(J!4[4\J,X>*Z5/\_<GUBTP.F^%G4\*_$R;R>/AW%W$GI%][ZW,FC!F;3%M&
+MI]\6N^=5UVZMG+=M0T/]O/JZ#?.V;+X/?QOFU0L;\;U>J*NNJ*\VO!,O2#$K
+M94:K-^0MGI]L(SM4EW[O/(_+(C4VK04P,+7IJ:'SNZ:(Z8<KN/C$K53;@`E*
+MD$+15FQ*_DG/N>!8Z-\2OHO'4YI<D>?<KD]A](HFZ]5)96W%LLB)4.B\`/K4
+MC5HUL+YQT@IT\^RPTH"']/Z8[,8JR;;3GG\<K7!R<"V.&,!Q8&+^&W)'_HEB
+MM+7Y1#X&VM&@?$(^9EIV#K.C^^2O/"Y(PEQ5S]?^B<[8Q\CY(^X[*@M:\W5V
+MIG0+:N`W:L<^-_%;A*G6H($_))3Y-GDP,@_JOMO&YG21*]".$&+U/&V?F4GH
+M@?I(NVV<^"&TZ63:)!]-[CS-DW/EVCN#?-)9U2'V_P:R?IL^7_LKGA?I0LN@
+M(EY?<!!WS_Z>7(+B5MYYX7(IZ.+$3)B#1M:"3MS`DY`$X0>SWT@!%;VXQJ[]
+M`Q1GNH:]#BTCM3D<>02[G"5E\!7^(,Y3BWAYP4'HE[2A?L62</S^`-$/;>)Z
+M`.@-0P\REVJS!E&^PZ#`3J"/AZE9`"JT$9HIV4_PP!#9G-C_&*#\ANO06.BD
+ML"1?][P=O)&M.4#7+3@()5])<P$G5%V_$082'"&@Z:)0XFA&5A^4>(*QIC?-
+MT]3#RGGK,QJ'E'$P_D`![P97AXWF(/@WX9G1?JKH>%8(C@UV&HEPF&BPE6JV
+M\SS'#N/]FF7MXLD*FTK^A5GRUHHM6VHWN-EA@GIW7C9WGTCNDJ;/W[C8S;FG
+MUW.XR3<SF\OFN'IN^D9WY9;*K97;A.GU[LW;W/5";5W%ILJYV1A36X4N*V=,
+MGSN_:OKTF6X&J-Y=48?[3&ZQOC*;$ZHKW5LK=FS>*FXU_6-"+@,D0:PP\KDW
+MUS-H&]T">C0'#"H:*K$P]W;(E92H*IM#WTY0$W<C.M)TWU=)@?%_WRR@]IV=
+M[/_U')\PNS#L`_K9H\]86<(.ULR%=NW<`&_XPYRJ2G]O_V+(QM(O(;K&HMG_
+MRILG?6#H\OBB#K4#]<,NFMN=-2&;',Y6=:`_OT%SB[.<>!6D0CK4O0/4NS-U
+M,:9*SV%YVJ1!XF4*'ZO?J$J'*)ACP7HFHZR#BL."?NCZ/8[=3@74JGZH$I&V
+M'6D4@L4TW=N'BU>3#%`+5:F#0.T_STKHXG4415"!F..1I>0DYQ@E>`P3D(:H
+M2F]`".JOJO1+C-/%J"K])Z7:1F"<J.0Y6O9"T;_U#KR__HRJ[!K]A?Z^Y3>^
+M@=^(&M#[^[G3R#!F0)4^IHPWG.>-Z;LJC1Z-(5<3*/=OO='W_:?.B&=8+E5:
+M0;'I*,1!&3UJ]WBCP32@_/>]ITI_LV`:GC\R4FZDE+_]*XJV8R-LOP^1(?Y^
+MGKJ('.HJTDHD"3K`S,Z8A(X[6M[!-0`/5.T_L3O'-B_FA,NA_YH7SQ:RFQ>[
+MT<XH2\P@4_\(_LF6QYKGO!E`V8D&TI!*F("IA+N-K#=C5K?X$8:M@$]Q1J>5
+M*Y(G1C(PK9/2SL>TE`QA"U='>!"**R$=JK\CXR"/S3^/W0U"":0]80`CP\[/
+MS)'A,/1W,200_Y"Z$&7^FUZ_V+UYRY;*3<!@AA.U.7/<TS=D4XP14E?Y@+BY
+MKK(>7=M6U&T2D9_-9$/;^-,_&V.O4]F';C^EQ63I<-3)<<V+./&.+BLQBK06
+M_GH6!><KM`_'[Y&-)'/$J<T[+)R``R1MD9K!;I9'YU2IW?F%SM(S#?8NIO_M
+M*^7,#([#G&QE$*3H8F%,:4`[9+:)>+<B84H)@!KK8E-H32B.I,TL2I'NI81`
+M#[AOT'S+8D?+"U1(*36T(MU%3^`Q0*GW82($0'^Q<)4BK8L35ARR(X2N<WJ?
+MY!B^%`H=/9HE!M+9273$"O<LVK4VN:Y0NIAY<#%R^[8X8L*,X;C\UCE4@F4!
+MX1\D2YD%6.ZZ>`_$6]^:7%*B^M2BW/`Q\W]C/I,Z)SO21W-_\H2`$RS07SPX
+M_D5/:(YG.V`J9NG$G0[TONG/84.@+XIG$H`S@"E@`I%A>4L6!U:?^(OXAN$Y
+MZ1+VRN50%-GW:B]_RG/Q_>VD\;^/5`Q%0LMC\K%D4_<)-T&K+90>Y*?NOKX:
+M#W)H1X'"T=.$N0^+:XM=13SK:,H*M,?>9"?J-L)#-KV(3W;/FMP>YAE\J>^N
+M\L3YMPC/575Y7^!IQ]W[M.P]F'<2V*JU.Q8_`B0?6X:&H-YG5*G`!5WG?=,P
+M,C2&.<.E/#I..]&/T[X?*]X?JY5/WCG4?]6Z>+$+(E0@EFRSLF*[O,^A.4"7
+M]U5\),$,H3#U/PW225G_XY3S)`EX9S]AFH[7#ATURP#K?UKV'P34GP/LC8/`
+M".^&.#ST5T`FJ@FX(_7GPY_PQIZ__CS2NA;YB]FM(Z8OCZ=GO"&UKRO57DO-
+M,Z^AHFZ>L'7[/!!_\)@[?8LX=QW]&V++E?T)T0J,R1GJ\]P2:.WG8[CY)'5/
+M^`)MQG^##[*$"VCW0QFZA-$!K?PO?)(;(XZ5A249I33.&NZ#X>][>71&@(;3
+M4L%$[.F^-FDIO+1Z^Q6IF$(^5:05]/+7*D5:!6]5LO?S-JF44GW1Y=5(^HMG
+M`WA&&)29C_^,C=&C_>7/;#+F1%/T41CRZS^3,E1#ENKM]&''R.M4:0U`*RW7
+M?O1G4Y+FF#9RY=IN))V$09SAV0!KQJWUE2Y=7@:5A4;%_XRJ)K=U(I`"AL^G
+M?J#QS+!0\T:0EF-,7T/_.2OP1"\H.V*6JK@G01OX[*HT?1)J!I.)59D;-C_T
+M/<P9WDV>,S3OLEZ<A_K.[$FFOC,',Y:ITKQ)9@>2'[@_\?1\XD\,8&[HI"-T
+M@J,3[0![S?\.[)4&["4)V.).==\22`1@R]3GB^$M$$]^N9%\M)$<SU2M4/>M
+M,9(G$@[TL81G^Q()I\:-&B'B]=[D+B/_RN@T9X@_HX3]S\<T/0)^A<H;&T^6
+M]E(RZCC8EV"CY#P??H0RM\;"Y.YW^X8R:(K_?TB+3F$2#'W9EZ9_^".>H$Y+
+M+5OJ<\63;$20:(W>!XH[+8IY^\DE)G+3@+$A@X[Y<((:0PI>KZ6(G&P3ICLA
+MFQT`=(@P)H-5%-1GU2+T<:%*/9.)3XVS2GA!D?>L[!TP%IC(%V!""#U$)-WS
+M,I8&.EOZRPA5ID/I]PP;+Q(\L?>/3+HJ"$A]8)V^_-Z=HY7">SV%VYO&-5_(
+M!KVB<%VK4R]<YSAP))(9*-.NC*1(GR'W/QG@?'9]N0T!V3R%.4UC$9!=L0`<
+M"X*QA=>4:>]]PL?O*TJ^FVG@+'4)7L.$!V$T"Y`,50:O8TI#_US=[!ZFI/HD
+M,?G^LZ0[2J_@(3Y.O+SF!E5ZTXDW<%BU/T.K=TD800[0CMKEBZ0K8=WU9?S.
+M"0;-%']"XDL^PNZ=H'C%Z3@P3N<DJ,E$Z8(N9GDNBJ.!XL>$6[M;,XHC+Z%O
+ML:35I)''CTF(G5G>CK'*/@)M=1S@="O>N6$@\!^]242;G/_=#ZE]]17\#KN9
+M+0MMU[3O]B;I(ZDVF?_T(8W(H&_1MJG3\>R@C'N7,=77)_M22=BE>0`0KD/@
+M7D<,UZB0J>D.D)[A=X"4$&@[L&8>LM'-?QPV>HY@(SH.,^&('2.>B6H\.W&%
+MH\&8@-;_$:XN]IYD^O0NCG14,5T[!NFJI-T@I"=7=17;W8F).?GOH3VM\\5V
+MFY`5T![3>.9_PLTE[GL:<+P6&`-\'#H9G(C>._6&7*78K7<;<"!]]0$+R3VL
+MRS]^S$8U>T@/+J8]L@6&X`.&ZP5B1$\7*0"2<V\P<CO-/+ABCD!&F9GPN"Y4
+M)DCN,7:=)7R[BFU4HV+2!(UY)7-!TE7,KD]C?G&DW7F<<)E:7.`ISD.0>=IB
+M$T(>2[:`)5M*'E&6:E,@NJMXJ5'/KF(\'L)!S296T;5`!I;^?MD)-'U'&,\:
+M[KK"$^P3)L-\NUQ;\K$Q7._**M>("(-]58H_6B4'[%7R[C$R5$K:@:U</$V1
+M!'J9K4C;Z06F%UOHQ8U6QCTC\$>2__,>THE8/T\P=R&R.-/P\2;T$05UGV34
+MW89UO^5#WKSM"/VY9!CME]\.Y)`&,J/8)1?;XKHSVP]QO%8P)LY?J7I"70\;
+M%!H_B"_6R)WR(!HOGY,_1S::)*_F40C8I<]UQV-''`=.@G2F,WC]PU<04OB_
+MYU+\>_*/2?R+^K-28*_JT#*D'LMP>(GX]$O%-]]K_X?A\N-[O\?Q$;<#R+HJ
+M=`E^W=.'QI/)_I\P'YZ[.X9K'\O=A;@'CW?_3`,%'"ITOBB'%_!,%/6!+P?/
+M`D_"=5"O*\TI^Y^#`2%M&<S`#J(MMQ?DT'-*\+F\]OC8]]8@3``?4[S/J4OS
+M8,P[J/B?\_@/UMN9H[B?I-%<UV>3=B[AA$8%U?ZCBO^@I[N^0%F^1/:]H'B/
+MMD'#OK#(*EZM^`[.\AT%[#S+"IHF*.)1)?B"4EH@^Q^33\2>YC[[*3`,9$<#
+M@Z-UG0C&?U2\BAT%O0GM3GS']`=L6B]TU4'T5M5[31I;F\%)R#&8COERY&6\
+M<?]/5T$N51GFGJ5VQ?><O,P)$.525U?!-!8_@SUFLP<1:9C97K23-<ASNGA,
+M*\6K0#K1L=UY1\L#.-CA+MQHJO(RSM'R!$D6(P]@H6_/*=6N'QO/)&8K_F-Z
+M44[D-^S<?U+6];@UYSU&5])<K3B5%4L+._[`K]$*>U#L/@?YR)L1^?)"!^?D
+MZ1W:0,GR[%Q:EX?SZ(X>'I*E%>&E1W1\JL!.#XY]D%?($B4;TM>?I-MOEG%X
+MJ.[8^:)T'O?3$>^`7I=3IFFX)XCNB%R1>PG#E=SN)81=+HS5RIJ51:K]<6RB
+M-=H__A[Q>YKPRT7392/Y:".YH^5VLEHVP&/]L82B=*.$'"EXE!/OP_:`YQU0
+M(\\#.?6+6?)50&T!_8&<-=J?'?%&%"Y/0#.:>(`WH44.$IQQ4(Y2EE,$--V[
+MD%RPA6F_XE9LL<*<685V^8A\HN/SJ;+_*=GW8UR6\#XE6V#6C-Z__,=FU=GE
+M_N_+WB=D_Y.*_PEYC4WQ/RFOP8N8+(Z]6'5J?T_0Z=A+AKRB2^ITP@3:R3$>
+M,/KE%L!0*0!M\1E@%<7EE"<"\2DK;;R"7>J25UJAP9Y15EIL\`IE/*.LM=K1
+M0?U:BSTR+=R505U73%W'LG0MM;+.76JEWH5B)2BV!%!I;(5RI9TV'+V`,]Y^
+MGX8:HQ]`!&_/U5YYG[8$?U*M)]N+IY[+O^RWN$YCEWW=4"N/F./X]L/(6:"(
+MX&+?K4H)K[B>V_,!)([*?FW/!7A9)TQN'$5ORP1'9&5X3Q"![1"F1@IH/R5+
+MV0FM&E-<W]OS`92<:?''R/\"+I_;6_?\@<+@/1A3EAS<\S&"WH/*0%A\'U>P
+M<0,%]TSLS^WY`Q7KT_9\#B^ECI8>T+$;[Z6O&8Z6'\.C<1Q].=F]*+VOX7XX
+MPV>1H^7?,?E8]IDG[.C]1V97P@(*'"W?@6_VL<S1\AO,WY3(O\/1L@EZW?'P
+M_?%4]SI:[D:08]CG.F%.[ZIX9+6CY3.+^;'=T3(&8GKGT?Z\M[OW&K)U<8;Q
+M1A40]-THZ&VCR0B%K%MB=!<.!'YF1V5@AL?K%#(5;W19Y#_#Q;(XH(@Q]$,R
+M0*Z$*?<;E)!N8TF-F,PLW&F#NKOW7RVF+4U*V8_81RB[\=)ET\EN^+^/SB8D
+M%U<4QV.\Q]L-`XRO6P85UML=>9?*[29CO&[,9!;>B-92:)R!7D-[1Y%..02_
+MOE$CX/?NJ&'XJ:LL,AIP(*F6`\W\@I&7*N3K0_#\`65V>;Q186ZQNMN"-A%$
+M:BMX9<F_[_F8J/*BXOIW1NQ$WZWB*ZLB!U/AO$R&5$"5B'QD#=:1?PY/UF22
+MIS4;R>7N6>5V)G%<&?+*##XR,SD=\,@#E"[8/6NG7;[`4J[-`+&088?61C9\
+M]$$LQ]N=Y.5AF,_:N]\E11]%B_>,H>^BSB/F>,280WTFC>P_E$QE&8\7&@%+
+MV_]=]O60QQ6SBGELX;MQ,7WE.%HPJM%)7TYA8^_M;)RE;[>C!<^0TOL,84OO
+MPJ2X9D<+FKT#/UY@G'(E1/9.P!04\D12WJ<<+7@NO'?0L/,*.CW!,XX6;P:.
+M<6?:QH(B<V:1O\?1\C[RT-P,LNMT>D1(<V4&;K.=Z7T=^<G?PP1,QP=\6BDZ
+MR#<`Q=()D.-`EN*$Q&T%?`L_UA%Z%*'UI!MEGD%;Y-U.,?M\,6]QM-0Q@U3H
+M&\\#+L?>ER!9\VX]VQ%Z%M[.%^38'*'5F/\I([_O##2M9[4+\I?P5D?+?,QO
+M`(7\.S'_K9!]>SP[6K7U5J0GBG&*&><+>8M0'P?68&_>J6=#,&1`8U4#1X=T
+M73IN?93HH?9@>BNHMD=^AL.\,+94V_1;DOOGCZ8['H>IL7DL_/S2AV[`$-""
+M<47K$YY:!*#?`ZW*IZ#Z%H^P,X>`'E>JV5-`CPU?`O8B"X/M`="SL5N#R?"A
+M,L6\56A(:MOU/.YY)*IIUMZQ]S9"Q3($E?&EVI[?)*,R+GPI7*P\-6_S+8#+
+M>5(;&6QHPH_3$';AT":$>D[[S=>HI[@6X>[6[Q&^T?LDHWO:;@5N.ZO8OXW7
+MAGG/HC[:$Q_TV'@WE.'"XF\C-K3]9CO&,9R`.EJ6Q5"]'.#$B0:EAQ:2M?69
+MWM>H,-U'X_$DI8QVH5UM,A84![K.T7(%P&O,8\.RHZ740N,4?BT25O4^&.=#
+M&$578B=5)_$NC%;="=Z%@6PQDFIQ/`\,A4]BG@6&SBWV[/D(ZRB+/8A4B4T^
+M!RPH[7+:='$4/.RZHV6'U=@UMT'RCH]XM,I>F6=3@F=GV1?1KH]SYAL>_QG'
+MPZL8Y\DB66N6VR%)FFL1WDW[KMQ!<P-'Z#H#VEA4#*#F;^``CI+2]9PP1N6?
+M"TOMN/OM<8KGV7D5T#^*T,DO##-I_C-EO;CKFQJCBWBA@_;/%W3=6$1UA&Y/
+MEBH*6JO'U+6++;W_ZP*=*4$#GERB[%QYUR]X^5P1'EE("?<L^84X13ZWHBRI
+MI'+0ZP%`[U\M!N_GR@O:UE`"LZA@;.:[\@5*3>=_QB9C]12=V\]-@4FI(I\#
+MU']@>Z3>6$$"G`_0SM:!1,)4YY[21'U?_#P)<C%A9%,FTO&^LTJP1X%QPO52
+M,KDZ6OX5'B5RM(`BB+;?E2%E2K)6\?'5$!AY=$3ZH/[O4>QY>+1X91Z/)JW^
+M,SA&OL.F\"):%5/QIV3[(L5W6EZYB!^QOP:CB#\B_U..(1^P4<8^V;Y8\?7+
+M*Q?S^>V],D5>`@^@0X:(?3@B;^*1!X3W)J!@0V5FY2+[B)AL-3`1,B-7A.7N
+MR.049%8NMC%L[+C&T9XRAB?O`?W@;9Z\Y(O1+N_99IKEX=`@9#H.K])AU#9F
+M?JY??5Q>C=::Y8#(&H5N(CF%LZHN.1@S]@6A4Z'[:/'0@$3G;5:YA`S'X2R`
+MY0G&Q`Q%C,IBGV$XDW\2A$ZV.(H\F),X'K<G.("9H;JB#8=&T0%I]S#$T,OY
+M;"EX%G-`93/,'%2<>"VD@`'-*EYQ$+TO[0E2-C']H(1Z"3K'@RQII7G09#-W
+M7QL.0U7ZRYEM-YG3`;UJ'-4):^+O61$ZV?1;`XK@-_""&2:QPT#H9#"C#8\'
+M=0\>(4GN*M/N.)60Y.UX?5U8D4B6<^>7AE&6LU7'4+NX'NI]CU!NH"Z`?GN6
+M`3R;`#B^3,M*`3CNTO`RH%7N00<T_2&JNH'K/W.7Q/7??O5U<<U`7,5[H"6P
+M6875)M*^D9`>5Z:M38$\]I)P1R/.N$#4C^8^BK<__5ML1;_QLN2N(5K#X8+U
+MBR_'\:.WZV;1,!45KI:CI*"?+5UC=J.VA-+JWFAOS=^8W.S#HTFK<O!LV8\&
+MZ_#NZ$R:&T0+S/W$87SQT)O,I&=Y'@X6R"`#(S/(89-!/H(Y:X!X)$`\0K@\
+MAS=O>I,Y)'@V#F<@E3T2/*&G$/C8/;K!$43?21R!21(<D<Q#)D<0#UV:(S`+
+MXXC9NZ^CANRGO_&&1Y[HH_696((IWC&98C7#S-'R#4QR(:2#:M.=0@O+3GP]
+M6E@O@6:SSJ2LU2-1%M#LA>[_`LTF\X.!)L[8AZ,)?/:/W5^3S](!3_%>DQ5*
+MOXI_EW]=N)?FA:E#NX7HBLQZ6)_`M`IYXJUZ$*T#(%I!['I\,6$.<<B`@/<`
+MK4$&2<X^F677O0.]U8Q'O'WQ2P/,O1E0)W!=.Q@SQH#8KSXF:W.GYW-'RZHT
+M)I&7PV`Z@/.9&-*SZR6Y>SH.RC<S5>\/J`8VXL<,1\LN_)B+'TY'RX?8(7O/
+M`WM@`,S[_LRQ5YCD9:*R]UN:G&'((D?+?Z!Z.!X_\@S]\54V=\.@`D?+3PPX
+MH'G^`'7'O\?8FYGJB#=9-MZ$'S`KW$5ZYLU,9?T>`JJ/EP.*YWH##FBD90@G
+M8,(!-01O:FN<@A_-3!_%UU9'"ZI5O7.,C$\(F_'QE/!@[V68%^CL<+O'F^,(
+MC:(5&-?5()9B%F,=*(>X:#2\($,Z0A];XFE.F^LF.>F[&24X'CZ6B'Z)EGIR
+M0I3MN43X/[+PO13^1")<)EN&G";'HU(BT#A_"%U&LUA<$+"EE3AE;Q]+N@[B
+MVP#W`]TH0BUMR_D6.TPU"Q,0YK.UD^B5_9;VK$ZFG<G^?ES[.?&KO\C!/OG"
+ME><H_E=:5B=J33@)#UV$.3*1>6S9S&-`AXF+1(/17E3J$C#I13[!EE5^U6/Z
+M9;QDO&$S&1*CCA:\I\G8*,=)2W!`6?LHGT2@8;Q#GI%P7Z(=+"`7O;$T^!OL
+M4UP/)Z<'Y1F+`\7J5SV1FX;4&T];=6,A_,-))4PR$(0,V<EXPVSA1"4Q4S#F
+M"!W""\;ZU<JS\;%H>_+]O__!<VKPF!Q\.K[1\BK*_H9I>)@Q:#M?,GRC92(9
+MH[K2;I&#+^!&RRI0.9^+N&DD>R&O71;#25;N;PR>5-=.U&E/Y@6/[SESCZ64
+M9^=?;-+N)9QPCQ)\00ZV*[[G/&_7WZ(4+R%=N[UMXB*G.$WQ/S?S',YURPN:
+M)N&5O=ZPLKI`]OT8--NN^`X+9?:UUQU3Q.<\8KMH9SLLFKF7HP2?EATP3,N-
+M?%<)VTLI87LI/KN\&BKT@MSHQ!V5U7C35%ENQP?6,NV1+CS6,8T9[JQ@VS-_
+MA^))?%IOF*;=T&68Z??N,>:/P:?UQFF1L8KO:5RYGM#%FTFSN\SMG0"M73W=
+M5>*FTLNGR>4S]!(W%+K:[7AV1:[\!L2F8?!L%MP(P76Y\CDS.(\%-T'P@[GH
+MSOOIM#73Y#4+]$*W,E:ORZWA]`<6:/EOD!F4<0;X5=KX>4$7G];N'6/NB>`6
+MS'QS\\=)?8$[.#],.CN,^:A2.>7:*V,3&<5TO20G<F;(WD\%3;J>IF,=E^/4
+M:VD1S)[+-&\G-&.QN>N#=PMU></,T]334!-?V+-B:=U"VO,*0P8`D1:P=16Q
+M_8$BMOEC91^T@Z`#!0`5ACT/+JU_TRA=O!JRG2].Y\7+3,R/Z@TY`:V?=(QV
+M7-*\$RTUFE9RNV^`1I-VYN*:1/G*(NKJ?_P/ZBNYF#9_C'2CC72.ENN,S1\#
+M,O4J`%^=;@#/D8+MG+B!]F?::?_G*%3.LSJG?B'+)+\!LUQL1L&9:$;A,A-F
+M*<5Q<7"X_]..^S_BTTI#3C%P5N_U2?L_R['ERG.2IW=/RL&GE"",PD\"G?N>
+MDE?S>%I9?'I6()'F,3GX!*5Y3%X-D[@G@/#93A`YKS'Z!`?W<'T0TDE=3CGX
+MS$%S+^AI9:PBACUU2T%'WFE37#`;?T8>JZS-A!YSR6LS>'BUX6(O/.WPM+.]
+MD>`S79G4>>P^-U!HNY9:C+T?"]O[\3[CE-J=V*U4>-T^J)[41!M`C3;MK=?9
+M!A#K"]P4RM5>-L(8=SWS.CLAUG*IO:`Q'6A#8,<9\-"]H$MMRK"]('P;82_(
+M7)7'=;"V^+Z/45^V^4-A\([;1>&453+:"Z+=I$)>6?(<VR>2@QIM%27V@G0N
+M>2](Y_X_NA?4,M)>4.WHK[D75#SZ*_:":+/E4GM!_]5]*-KAZ69C=FIQAX?N
+M!06[40=)V@M"^[SA>T'F=LK(>T'5(^U5W3X<OTMLZJC"PJ%[01/MR7M!`0N:
+MJ)L;EZX7C46N=Q3[BXS8B;XON1=$^VS#]H+P:B':X_%USUIAE]](V0VZ]O_\
+M7E#9H?^[%_3_[WM!=W;\C^T%<1W_K]D+$MO_!_>"<MK_[U[0_]T+^K][0?]W
+M+^C_H;V@:4EC^+?WLW-J#3-0Y<:EAMFT^`TA>:A[T=6:7=Z^9E9;SRI:!5^N
+MR[3`KF3HVW%:*\:T.U[A:<5%='7R8RQK:%$<B2S`5A\;,VCUT<Q#6E54F_`*
+MS86-$\_2T6F(ND\SR_/UIZR6LQ+1E0%(NV!4*<U%QUS,EA,O+>D'+2-?Q_TE
+MS93NXT`?1E`HU]C6TNC74C>6^H9N+%'1XG1S8RF7+:/KR:OH74G;2G-VL_N4
+M8N6IR[6R_XSV4'IB%?T,KJ*?9G"$VPVTV"JZXM?80K*6LH[.O?SUUM'OA/K>
+M@YM5A+FP4B'+=@#7E[(N_>\O??U]I;Y[Q/37V*Z2@>>/N$OBN>ZEKX=G!N(I
+MKM^CF^OH7XZOY>OB.PKQ%=)?PP50]6%S#?WRU"ZA':5S:?'^0$K-:5XRAA/7
+M*3ZGQ]<OE*;0YH"V\R#1IA&$6TY:%0NB!'VDE9-KJ1NU[Z<9:^O]Z*-RX=^8
+M+S08<GPV^8'DPA+[4/T%:F5W8A]J1A)/7OAW8Q]JANPCCFE8@%X-C9VI`5K/
+MB_-DRL[4$)[L?/%+>?)#<Z-*,[B/]LV`N2[%?XRY>H9R3(_!8<96E<%A\8VJ
+MOJ$;52:'&1M5(W-88IMJUNZ9X>&=*?M/:U=9$_QU>@A_]23S5P\CL)X4NGWJ
+MP-?FKYZOP5]K#ORW^*LGF;]&Q#.Z_VOS5\]_@;_^<?__2?XB@L)K>9-WJ)J7
+MY'-"!OE'U)C$%6,RNHM#V6T:X:\EC;-?6%EF,!ZWGS$>9DCPWB<OC,1[C*\O
+MXY+9;Q%.[[V:6OEFJH\X)9A+1\.9UNSTG'.TD$:)\V;4/Z*(M.L7LE]+W=!"
+M6_7&!F-#ZUOX,<?8T$+]P['W]XD-K3]Q\0TMO!.Z]ZBYEV2N!J7L9_TT93_K
+M.XG]K+VH_[8F[6<=3][/JD[>S\(UX=[UR?M9RQ/[6;<@G(*D_:PYR?M9K8G]
+MK/<0RJ3A^UD\YD5Y;VQH#1`WN=I<8WO_2'K?\/VL$XDD1T;8S_I%(OI'R?M9
+M/TB$*\G[60\EPNOC^UE;$X%WFV5H\0TMT996["37<YBVD&UH&4>_^O#J=FL;
+MS&+$OA97AJ/EJ@2H\9C2Y;&M=0"=:J;JILG'9O8[#KL6R?Z^-M>B;)>GU3_0
+MZEJ$)Z,<(=S2;#GI:/DM9VQM]9-OIE@OSA#0=Y8!ST"O%^^,&QJF8'<L03\A
+M:/9O.&'!U4F0^6O_CD^EQ[!P'0C_>'TMY.0K#>O5K_`/0:V3=JY^HWC[(GGA
+M$>J$^U;]C.XA5Q+PB7*_Y1AF<"VBO2LC+\QM"HE-8X[0?^*^552M/#/\[N?"
+MGQL'#&'>DZ,LL^]95'D.9/J8/1[O27AFG"^<P0NV@^06[?JP]$&FM#/7W3@%
+MJP=AXK@R=.RNB_8U6O,O=1T/729"?G-VJ,>1ZZZ[SBUNNW];;2-Z%=E4N6.[
+MN[*NKK;.O:%V8Z4;8CEN\[:&BBV;-R8<C0BU+*F[KE84-F^KY,J\)?<L7Q4H
+M+"OAKMI0L>U:P5U=L7U[Y;:KT"?)SEK1754K;MM(SH8V4>+"VV_WEJWE*K=N
+M%W:Z9]2+]\V$@NLJZ^LWUVZC!%Y?Z=IO<G65VRN%S>CQ9$[M]LJZ"@'PHA<`
+M9F!%J8L*EY:5KN4`&_1OM+5R:VW=3@;F]M+"V[SQ&FRHKJBKV"!4UKGK\-(-
+MEJ2L<%5)(DFB2&@!<9LPHWZF6411&7<?WDM<3_=VW%>QI6+;ADJ&@+>H#,O9
+M7E$'[5-=63]BFM+",N\J`D&.FF;<Z5X_\Q*@OA''YSY(75=950F`-U0:3IR,
+MJOF+X,D)=16;Z0YO3%F_I:*^VCWC+H:SUWO[;86E(U5_`Z2K9VEN6_O-Y"2U
+M6[94"`C.\!)E)%J]<F7AVN16VB1NJ:AS#^DU:*32PK4<$4?EAADSW56`6^5&
+M))BM%<*&:DJT:K6O<.UMR^@];\?T'2.LB=[R-!T[EB\T?W1QCXY"1QRO>M^D
+M`Z[H,!SGOK;(G:ITUUATU8]_07J&/4[!)K7;\8#KP&`7'DL6%J!'EO'Z=AZS
+M:Z.>H8.7Z(2U3)7^I1P=0V!XY.<T+*K^-]E=3:6V%-\!;P^^BS[6A-F>H*MA
+M#,X>M0[($<DEF>E:5DI!`>1;',2=G4OS=3J]S&:,>=STC4/.5:__9ZJ@^GQR
+M!1;IC7A9O>;[N>DK")V6HROTC^"/,!F=4#V^[@MVH=(BDA)V.N^H2OL@>(3#
+MTCA,YL^_?L$--RY<Y"DLNFVIM[CBO@T;*ZNX'1LW;]HL<"RL9-GR%=]8Z5NU
+MNG1-V>UK_8'R==^\@Q.!@>NXK.Q1]M%NKGX[T#UWY5573YM^S;4S9EXW:_:<
+MN?,6W[3DYEMN+;CSKO5WWW/OMW8%=W/;Q6T;O@PH*WQ3]>::^[=LW5:[_8&Z
+M>D%L:-RQ\\$$FE]5B)O;7K<9Z/+2L+@MM8V`^O\L&MRFNHKMU4G-R[$6S;11
+MDUFL:7QZQAB'<^RX\:X)$R?E3+YL2N[E5TQMXC9L$^JV<.XL[CY@^OO_6UAR
+M%5NV5U=P_YLU!"@@3KBEWI6<L'G+QDJN;O.F:F'.!K%NR\XYAI0RPDCL<0V5
+M=<+F#15;YFQ!F;^ELFIH8@IB::%U&BKG5&S8@"($^H/E@4&@LJY^0VU=);=A
+M<]T&<6O5ELH=9JI$B%%J_0,BR-,$*I6`0'WEG/I:D$!B/1>7=ZS<(:DWU&[=
+M6EFW83.@6R%P#XB5]32,;*VHNQ^0JZP`*3A'J*[8-J=^\Z9M7"5DWE+/WK>`
+M0$N*JJ_<NAFD(D@X]G<;5J02$82HADI(L'D'5[6YH9*#0:Z.$ZKK*BLYH;&6
+MJX5T#U;6U7(FP@S9*G'+ECGU0NUV#OAK<^U&KGKG]NI*P&SS-DC#/@C["F[[
+M%M'`J:(>\-U<?[_1,O%Q9G,]JWQR0,7VVGJAKA;@<!5;H8QZ&"VQ+&QD!FTC
+M"ODZ]LY&%/;^@%@K5"2:J7('#!-;DP+\MW/+;\_GRO`QGRO!Q_5<,3X6<##4
+M<#`B<5X?=UOA*LZ[MHB[_9NKN%6%W^"6WK8`?M?#;S[\\KFE*[W<[<NYVU=S
+M&RKJZC97;*J<PQPB<K>502/6;9U350F#87%Q@N*$BONXP%IN6V4CT='*8@Y#
+MEJUE1$#"J>AV(&A(SQ4!0>,(ZEVUAO.N7@NHK.-NQ]_J9=PJ/_ICH_%F1[+_
+MQW_D.=47EGVMBM_9_$&3['_D_!&+D'[^B%,<K_@>.=_A%JY"OUQ^FV>%K7X4
+M,_*YPFK,>QZTS0K:(Q/"PR\HWZ%7H]6S=M6/X\XWQ=',4*;'L"&+GM#4I046
+MQ=<J%SH[>JREVE]_A,?:6^4B>U>1BRTJ\-*#=A@#`]H__L@TM'G*T-DAWP,T
+M)1L+KVD>>2??5<@,@`K)N4%^.Z;I6KK'38%+]Y"S@@(IFK7[8_208!GN%`'A
+M`P:/R(&<KF)VXKJ8G;@V_2$L88\"]EC*'@M0Y5:_W8T#]*I%U0BYAE.+2TLU
+MZ:?H4H`*KN'0#9=-%UNU_"NQE%:ES+5"#KAI/0E:VB*XJG'*C2FZJ/(V\K>*
+M7>(4G!C<GTEM$LG!^QLQ;3S#%39V;V.BD#?=N`33JBQW+9=730M@T$^FDJ5Q
+MJV:_RG@IOXI6;NC]1U>C<X6571FH;2O%2_&6G")>KK-W65$/!W3.%X,"/KK&
+M@:DMDRD(2J`3O39<4S[T$^H_I<BF_F27/N1^C3C-W?$/M&9L["&%E=TNNC>+
+M)HEV86)`>XOUO)+A*>8;,MJX);O$#W`O;E3-F(`FY[!R*;*Q>=$NL4[/()<8
+M5Y<KQ:Z9T8)2;((=`6TJ-(!,#H[CGCF<D&*6-T8IF@/:SZ`]E(`+G6]31!2]
+M2P:T!]T4#%-ZUIRM`:UI*K53[VK=L-49X,2KDO,48YX$\'!`6PE93!]PU`8Y
+MR?Z__]YL`Z*XC#:;G@$-`>@Z#G>HI6>D"^L<#^/VLWQZ5LN^LQ5?Z'H/E#OP
+M0YZ;D/0[^"1[MAL_,_RY(>G^.[_V_P,P_BN_%OCM,-[=3_X_6S;^[H)?-_R(
+MLAI'U=@"VN43&:T5Y^H%2^&O4K`4+5VC64W9T-=X2GCI8;<N]F&/5P>T.R[G
+MV)(ODF9Z\Z*9PJB:F0'MBQA=Q`HS_N1\RXQ\VP/:5<GY1ND9D-/1,AV%".#P
+M_0EHB&`QY4=.0/LL%TDMMWG9#`MA-MO@)`#1^Q>V;L#2N@-:5SRME=+F82*V
+MN(#,M`2!'S3RC`YHL_'[:?8-Z7'%57``SXTCANS]#L8PV#,"VOVY5&9D=QBH
+M_<\V)ID>")OMEQ[0WG<9O(KD'5D>9G$-!8[#SM#)%(MZ]-&"4E)J7]"V-&SI
+MT*Q2CR5BS6^'N<!8P$SV]6N/&M!\_<`CI0&M9"S[GN@)\(Z]OX0QJ2V[]1C_
+MSA)+PYKFSV\55C9__BU'Z'E<Y.TN@'(=>__9BIOH99:AA>>,5#CZ(,/R'2W;
+M(9LA8TQ<TN*X-'\^R]&"4K@IN_GSZX3+:64+BG>T_!"%#*#0<A%'K;<LY/>>
+M"9H8$U++0-9,29$;4"W7%/+^DYQN74`KFX(%SDY*>F]`Z[V,]7K=R+"O&`;[
+M(&7([<55K2'I06#^^;*4]"`@6Q,A:-ZDW4M8S(B+Q>K+\,HA2+$,@-\&D356
+M0_JMNHP)S'>)F`+:C;2!%XV+]<W-BV:+&T'H98Q`#%_:'\(U`4U+9U-AWN./
+M[KZR)CL@^S6M=ASK$[\6&0-I7\9A.,+CG0IE;!$8VM;)1@%"86;SHJ"8#H1Y
+M8Q@_+Z,[_2!,R$*TD(C[35K."FAC&70H2\L8ER"\AD"<Z)8BT=T*/2X6,8)K
+M6#P2L4T:J7*\43<;<N%/Q^+(<29A\Y@8-ZYX@NVW$EZCD85W0N+(6,+=<9@K
+MU3,"VMPQB2&R43.=K`WS_7WR>PS6*I?L8_;TAJ=JUCQW-R^Z6YRJ9\3ESK=R
+MALB=N,RZOF&*DD$U'J],=!RVXDW168[#11:T=9M8'M#0=ROT/GF:9VB]3==^
+MN/55KKBLFI(S7%8IOIAGE4NT84T?Q>M7#7?BIBZ;K%=8D^HS0*V!B_H94O0N
+M<6J24%KF-%K'<8!K?M-":?8$8S/16I)L)IMND(*QN4)MTUAX7N=H>1%7MU\G
+MI1,"[G2TL(-1L1F4`Q==>W]":\XQ7-T7&INNA%</1CZJLO!\_'BD&>&,,]:]
+M8T'*/8BY-S$;B(2\G3R:R5M:G8[+VR\F,FY?QO1?D!UI+-E""D#*V>(`<-,M
+MIOPV1JT=2R4]JRD3_5?!>%5NC%;/,'",BJ]J&&_0[*CFQ7>)&<T/6F:"IC>S
+MYJZ`]CK>!HR.-^,PEI4;(U=U,HPK#`@3$<)8A"".DC*LO4\8XPL,9F\"91I7
+M(='WJ_`=V4'V'\UG+ZH[NJ5=AY=Q0A[!7Q30;`!?%PXO4P#O`A`QC\#X1'$%
+M`:UO`DD8XO4:H/KM8\S!NJL`FXB+7!4F7YRCL&7*C%@J""!ECTH>//"<4?/B
+MZ\0[]0R\K@8EWD!<C+X[P1""`Z88?6`"BL^4=""BGYV0$-$#IH@NQA%U#O8(
+M%82;!(Q5''LSJ="['"$<'Z"Y8+!";1":+*!E6E+%916*RPI#+C64_I=EYA4!
+M#>TDZ:X+3S"Z>S+*L5M&LTF&/?R:*2N#T7*2E0,@8[.9K*2^76;T[3CLV]&`
+M;%#,!$0C`7-,O[9A@B$"1J,011+:84D2I1\DB=).>UR4OF(GZ05\-4W,9C<C
+M,)Q3[JU)8O++]]'F=O[Y?#VR(OQ?;P=V%V[31)4_H(QU'!ZG"D7=NJ5$L7@*
+M^<;G0OIN&TNQ&]!;H^6B'6_\2NL[%R]9O'X]=^?B6_`Q3/X\]%WF[VT*9NHR
+MW?.CL);:T['=H7'FUF2HTGU;<2GS1FWO$[3X&FH7)S$F?R*@31R/%)#1&[*:
+MYULLD!N0:[@>LVZFK/G:-^)9<UG6I[#D]\91@9C?F\@/F1U[?X$T!@(]7<?=
+M&',(<>S]`86O%\="1V6VK>9MR]8WEZ2OCRS#,SR(\2YT>+XX'CL'8N=$KF-V
+M8YXU*/$M!8@>R(TY)#?6XS4G@,R;%L9AHC%07M^\>+WXAHE1PS2$.T:W),,U
+MT6K(1"5X/0B@3(3T=]F&LF7#J:8CM!F9J!"EI97)7Z7`MDSV#NQXL,T[8%Z4
+M17`5,=IBSQ#6LP/-::`*&!O88\JTGK^C#>P.#1C`W+L&DKD!Z$68C1O)CY+5
+M:KO!AKX!SS'!U>:-XMDVPMEN;?-%N=7INF]@YUZIR<X)=JKXMQP<NS\AQ@D/
+M8I5PXL`0O!7WQ))PG`1P6NQ.87SKL?/=@*R;G]CF&YBQ.CWB##/T;78,,4HY
+MRJ#1,#$&,I?PY[O=1=G0=.>3RO^,B3IZ?Y>Q&OH\G4H!#T(`6:-G9=#)?)O&
+MCZ)KS,/TL0$^2'21'T[9F9C"#J?W[S[*QML@R/_\=NSB-!C[I>@<P25%[P0]
+MA\D#1UN1!>^$J!G%9B=Y[4L6"]E+;A;J>O]$\W]@#ZML2(?,@/:TS9PT<$OF
+M"/R2]2#`^8#V'18,RD2))4F]&8=91%LB)%4.+28YM%[84L-'A/"PLI:,4%9:
+M0)L>+TL?5E96<EE3C;(F85DWBTXL2\S&0>\';(X%P$YGP@B@<,:8_1$`;"67
+MT8PK;D"VR3.DZPQBGZMD-A%$!LG0,WXQ)S(^H/T;YD.-E_9IVORQ1?[8[C$U
+MHT#SC6IB)JXG11V'T;9MP''XG.?3IEQV>C]!JD1$W@&/.+#[;,JZA#/Y_CN5
+M-^\DH1,NZ/V0;R@$03E$S@K.,NWO]YD<)!])XJ&UP$,?6`2Z<,BBC`4AT?@:
+M;NOFS1)CZBNS47FFOYQP;0#M,19JP7VF-+,IF<U+,CC!)G79\:J(W^&?T34\
+M4N.C>"MY=5AIY-O&M/H&BEN."V@[YSC@'\!C!.QTNKUM.577B[:'7&%Z6T:K
+M%Y*VBZ>51AO>I(1EDM-*>S;SW3N8\!\Y>$+V12UOX<5*[ZF59T>ZS^E_/4+.
+M+VINICN/.;R/Z5A;@%=NL;D\7'%ZZAU.4A^?R+GAD235G4CI<'H2*>4:I.1"
+M4KH3QM@=EKELC!UCZ/8P4T'Y43,7Z)8SJ,B0K5,,`AK?O'BN.`:I"$<!:V14
+MF-'@6A)EZ%AT8.2Y0*=B7E.E.#RK86X$))U9X"D!]E4FH4;?;\CV+#U3R83P
+MQA[V2*_)Q+%BTLPWU.>/4=<>HZZ=$RY;@U960)!1[7]]AYGDH.U,E'HYHWF)
+ME1-RI4X;[O*=DBY8A$DU:>7:SWE<MR6=SG&XF,>!VW'8$M?ZA_AX=BI$K?(;
+MH>-`G,<2Q#FI#.A7NQ@VZ-,!,AUF$I%QR7*^0\N$8-`)Y@_//ZI,^P-D[L5+
+MN<T\2DMX`6!']V(,SS&92GS$+-%NE.A*V$6Q,ODO*[,2LJ,H#B>7:3-T(DA[
+MN-UP63VL_S+:&'$!']RB!-`:286FGZCZ+\H!'BBET_NW]9W>BUQ`\P[B]>5X
+MO"K`#VG7)'@'Y#@]E.0JRQ9!Y7"X%5;)YT+G4P6!HTQ[_-'X4#HZ/'0LG0)E
+M7M1U0!YUH'YA5*!<6P(9([.A'3]M/4:#(8TYSG)M4C8=O"9C1RRZK71!JVN,
+M7K`@Y;ZPU+IGRZSNM^!EU-ZHZHW)&:I7EXOY3F_L;JAY-M0<:J]#[4O.4^V]
+M48@=.I=,J7]K?&RCZ3$>?76$TJUTKZ&ER:'XG"J/5OD<W6M*VR)[@DY4H\7T
+M@[C](`5=%I@O^5V6(Y'Q>X(NBLI42].P,]52JW1AO./A9RS&"N_11EKA[7N8
+MY\XD_9[<._SW&/RV0UQTA#CSUPV_5_?B/GEL9G1FL:OW&VQ..&2%_&\VG,>X
+M:BQJB06F->?IZ)V;TI@K0'MM-/F!`!@-*[+,9<A6F&O20#@MOORS-"N^_-.+
+MIQF'E/6=."`#\NQDR)E9J0M+#EO2PM(GMJ2%I;]F,DMO7+=B:#=FXF(0F2/4
+M6"*ER>7"[&UR2KF0_`5('KF%V5P'M,6)S!&G$78-A:%YH->YK+0LH+T/,V`F
+M2V%RCEM,)C4F^T26]IH7C$@/VC@Q32ZRJ1)?`*"L,EZYDGHO0!*MK=C+>`T8
+M;;M=A@&Q@)@.O;(.>!IS'(^FH;Y;GB,=L<GE.7)WAY;F>!;O9(PJJW.EG4Y.
+MQ,`>OE3;CU1;GBL7.5%1R$7_!!BN/^#4K(^P0HQ8&],DI1TN3IR(IO0/8M8`
+M1+HPZS?))CVJ;W=IQY5$1A?>PVWS@.:QB,[X*ZMRE9U..=@OOT-G$_KD;E2S
+MU:+,CBCAF%:(J]UHP<G?4@3YFMY@H*0'G9QPA?2@BQ-R0-6N`4*-PJ0YK<A5
+MJI5"@>BHQ9A`U=!@O>\BWO!+!7IC4*>T0B>[H#+4'DR3VK$\T/'Q>N@UM+X^
+MJ:,G#>3(S`Z:4_ZJI[6$[RQ)Y^(>`MA&'WHPZ1FZGH0\CR=_<I52NW$T#\8M
+M[(UH_GE/9_VUX22YA;>=,ST<)@AN?JS\*2COQ1XQVG@&D)/:^SU=8A8#IR^S
+MQV]W'^8[J+B%?-JV+4]O93;;Q<G%1Q5T>CV@['!ZWG5([,HFT@'+T\4Z3]`N
+M;.WR]E"-8);BZZD/*`MEL1_]9H]C_D_;O#T&NF=I6M'?8L]+.+37("7:-*+]
+M]]D6UQ@SQN/5Q%&ZMX=!K7M9$4%[[!'L4I<3[SU]^$&0XGB-Z!A#HWH9[V8,
+MVND6P%RHS:QE3OE81Y2/NXE)W-F$/K^!W&UXH6;]=;C!#!IG--SJCSD.'&%:
+MG!*$N=LBP>8X?(1L"8L\Y^I^CPL#_9>`91`,@!1C]==@-]XJ!P%F-U4F!6@:
+MS($1WH?,V?K(8^`O'B)53PG8@`!PA]N9O,.=5HQW8))_^;&EVDTA](1@1][!
+M^]%*]0:[]FBK$<92.1@E'P=!'[F"W=N(MI?%]F6EVA84`0'H=7OG4J>>N!QS
+MV%AWQ4/FQ4':,]1WL;R3:!4]F'0!R%N#[ZS":Y`_Q98IM:^0W\;364#!,[OE
+M(V6%:]`<>M;#!E?;9IZ3RVUX`OJD.%9OM&L>H$2#/R(3R@"$OMVN'7V8[E9`
+MR[02>^JXF9!_>^*HH5%7J-TD(T/P#6O?LCTD,&F#/R.R0.Z/S%?J[*BCSZ!;
+M.F\-F=9@9X<JZ3&FI)\F<DC0EHE3ZAVJ)780$#M12LB='1?3VKQV0BO_I++:
+MY3D7G(+WV<%$4##6GT8CK:6MMGG.[=+(V7^R?+!]*4CHCC:OTYS=YQ^G%G9Y
+M/@U>Q?P'M/&3@``7\9.$C'RRF2]$]SGE-L^GN_Y`A:?08O)^\37-S#06&&4Y
+M*F/DAGUGEU=K1LOHCF8\N^'OPVOXUM%5AW;M;S288^L5$^DO:/71U9U%"R!A
+M:[8B:L72Q::FF8"69;`99EDY`2/G>)W6>_'VES9?M-51@@EWG]&]?3I:16M-
+MNQ\S=R>&T>?N)J8WX>YY##AF%@BG17(TK=@)(R^=UPNX#-?L::M`4MA5GGT4
+MVU47WFO'E96NT6Z&GK?L=A%S)M-:HIR)K!SR2)(/P[NGV-DT22EV%LA'.CZ9
+M:ND^$55Y7##^%4=%`F-!(XSR.65[6"]VQ>^=29W;=>QF=[XT`=#M2B.[]-U>
+MKCV$WBU*[,J"YPX:^ZR*S^59^;![%Z\O?=C-/I;1QS(R+^E12ERSO"Z5#\4@
+M:RDD,.[WE(^DE=O+I'8^K<1>JOU4@O)*R)WZ@M;D^X-93U,?CP4.5O@VLK$>
+MY77*?-MPO+-VF\JJ9[<S.%/EJ2%)!HUJ,>_'LM?8`]I*4/[Q_B<02_)NYZ7N
+MMWTI&%=^BUTRJ"+09ZR;".:+$MV);%RT@F#_"EHU-#$$#IW_)M/&?4&B8:R6
+M(S0+6C+_/!91SDM'>.2/;'C*Q^+6Y.L$+SOOX!1FT\$&87>DRCCOL%VH:QQ%
+M!Q:$S>C$@,XY"!,BQ>C'">]!>Q#-/HHC*]%6XT@L#&#)KX+K(24[J8A[A0G,
+M;CV3#C*(:YGA^PELR<8"P(UNS$;_(HT%^>>3,MH<(1\21=`N-15P0H524E!0
+MJMW8A`VS!-=SNTH*2(*6(-_;FU?/X"/H^XBNST6`2F-!Z/SNJ^/80-6IJN*?
+M6H]!J73M>'15Z'S3^_#5F3ELWXNG<2__>+Z.S2G@N;!R\K-C5^IXJ9/:,P.>
+M\A'3$7[,<']O9^>H!9RJA0N!&#R?[[;*;R]/U$W\C]!Q`68N]N85,WBZBBBQ
+M#L+(0NZ'\<3KS.^_WN^*"\BD>,7O1*9XNVY2XVC/.W5CB6T\[S1D,]M]=O>Q
+M*5?-?W'Y2O<^R>_,$IVR&)6/`2-Y_-$&RS(\&C'R58YF_F3\Y/[![L&32<6P
+M>`:\>_"TW"F_,?@;$'*6%?*[F&$H1L/N\OVG!^E^>V[7!!P'Z1)U\F1*AT\C
+ME[&B!W\GO<L-_AXQIS@2&##[V^54\%+[TTK0)0?/X"0?KR4-NN+I3T-PLWC6
+M@LO&XE0I>(83)^OB:=3-CS`M#52YWD<XPX<31?R,(OKINLJH)QBK<YAZH#<V
+MRQN-C(9/.@V"VC6HE6<\XNFZ48K_]"S_&1KG\/2P_W2SV&-Q/'L$6M;QK/^,
+M`NH\X(F.`4])P1X8%V<>L5RPG$,ES'(DS7\ZS7\*4*%D&@PC@+H"FK]X!B\6
+M%K('UY^6_&>XP?6@`)\&^/';<,TQS>B"=SO^XD1SIQ=/@HZH.1TO'I??<3S[
+M*31<2!?'`P\Y%#&:KV//].)5DF&8/M2-9T?-@YKA'3/B"(=G^6.R7S/.O7@Z
+MZC+E-V8>B62%Y2,SWV@6^Z!F?F@ZC6K7+9_HZ(69^UAX_L&)9W"$V31T:AT?
+M.&>>@-IT_!FH3O/X^NI'J:6ZW#VS'R_5G.75(GC7=CRMY00^/W%"PH8,=:G5
+M$K%:NBDV:L1&C5@;Q0)#6KK3T,TB4'(!S!KPZ+875/0!F($DZ;,X__"BRRYR
+M7(,^=J7HU`:W%+VU<92ZK`?`_NH3Y)^3[,XX:H-9>/>H,!U[K.-7?X8)Y,MN
+M")YY!-WFGOC51_*Y4=A"&+DUJL!\Q1^-ST.&\,_7*'_@5Q\8Y9M6=8GRHU#$
+M1\GE#T#Y?S;*Q\C*@2\O?XA\R>H?E21?V+_^PM2Q:G2C.5;)%_*/KRG[_>QI
+M,#"I4D_K%_K[W.^.R^<2H;_K&'Y2@."ECE,O-YB7SX6.!R?([\AO&TQJW'`6
+ML8<QT&C^U&+S9%;L>^MC[WECJ863Q8/UO9XD63[\GX%/LIY\W:7QB:7@$QN.
+M3[L\4C/0UA1ADGK/U._A=T^R3O^LR'/O>6WO_?GT>[_O:3[K%1>K2D';%_I[
+M%A:0+HY]_S3=]OXR_)HC>+_X>SV`_GNYT[07O\5S@Z>ED]S@;R+SPV%569J4
+MTWOQS>980=T8(ZT":4$B`3!4\O&>OJ9A%TK1OQXCJ.>V9#PS`<_WA^#9TX:7
+M@'\YGGAUMS9I*)Y:4LX$GI0V\N`E\1QA_-LUJ>F_./XY$_S7SUP((__-@!DX
+M^E@"O3]Z:T,&B#*0;P8[7D#GF7@N=B!RG<&'_4P.1%/XD.0`Z`$8&1PP98^6
+M<K_F_\OX_\K^JU/U"T,_P,:5WTE#)$&@V2W'0#^H1ZGZ5?I!XO[#NOA<]<J=
+MB?LC$_=_4KPQ`<!4:6:JD>$]7,>V_L_N2"2;MGSC8O<VH;:Z?N[MLQO<^7/G
+MN_,]GAOFY>7/FW^].R]_\?Q%B_,\[HT5#9LW;G)[=VQW3^,<+RZ=QN\]2J7$
+M\V_YDOPWI.97*'M'NQ-@4/YJH7;;EY5__5>4C_F_K/R\2Y<_?<?BU/_=T^OC
+M=):3$&_?>("66?#N9;^&ESFJWF@IWB*I>OOAUX>WU(:_38>_;-H/&^D"V0N9
+MXOC\D^%PV]+'M59^?I%T(7WW9\A4/3BO&U9RZMSQ-]MY3GW>68![=]*$`CRD
+M?4!R&<_QQG.<\1QK/#%YJ2IE/VH@,@X0D:(98KK<;_*S<95I2EG;MI/L=APH
+M2@<H13S^2<,_5OQC@3]6$ZKZ?$X!7LN\3D#(V;LS`;)I"T.PZ[AYE<(&^%57
+MUM5S[#'WOIT5&S?6&>VZIV]:>LI]>W^IA:I*?R#PTH?XT%ZJAQ8,:1>,U0%'
+MRVT@G-3]',Q4U5`4'?>$SEZ@]R_PO8=\!^G[,8-QAW1MO;%;RUSR-A_"O%<+
+MOV4OLQRA,(2JH0'(4:K]1J2M(=#G7L&UA=_C$F'H#!;P>!_\+5,?[\='WDGE
+M$(:FWF.[HDS?3VFEOU"[[T>8VCRJP1FJ02Y@$;H;<^Q'</I^A!;0CB(_TKNV
+M^0%$P*GO/TOQ/12_XV_&$H<C="6$UF0@FU.<EB^:M0O1Y68L'_3X,8*)[:`]
+M7H=N*2-CC7;10G6&OUCU)]T7C&,/\?[95K&U,MX_[M3^6;UM6/],KAO2/U,3
+M_?,X]<_CU#^/4_\\/D+_O/U`O'].C]`_XG:S;VX1S+YY30UA\Y6J(6RS4ESL
+MM"4O=BY#FE>E1[^3Z(6?42DYD/FAU+9?]D"\[?]4.T+;Q[Z(M[TWI8%7/V"L
+M53A"LX=TRJGM\;:?_$!JVV<]$&_[4Q?BE\8-D<\?;Z&[GU-E>N;V%)E>MV$K
+M"+SZ6CQ$M]A=N&6+>WMMG5#OWKS-+=979@^)GUZ?S6VHW;:M<@.="D<FK*RO
+MA^#%;FYMW4X\1SR]?N[<N=D<!F%J/`O+8#36;18JW3/J*P4Z;RQN=]<+&ROK
+MZF:RA"R14(M'A[?M=%=MWE(9#ZVOW((E7C(OBU_LWEY7*]1NJ-U"YY#%NDJL
+M!1TSW"P`#$'<;@+$(XC;C?J8=?O*S'/-W&;=B+8?XU)HN_Y^%'U.V?]CQ>N2
+MO4\I_AR\K-";*WN?J%+\]BK9_[2V;QLN+(=QF3E/.[^-77;+PPQP+%YO.E\;
+M!=S0^TUR6JB@ATK96LTU<YSV12WF>ZS+V\KLEE_5F2TLNQ0Y_3D.)\8M8=7[
+M:JDVB]PH/4*4'O0J"E[J*GFN%B]3I8)]),Y;M/JM1'N]'_%L?IU/<@.8\EXS
+MQ1I*X>P]RI.M?1C)\Q%M`Z1J*[>U^C_5&^VJV$^W:9<[`?,KH3)5BO?I*ME[
+MK@8=GCVBS7T`65N@Y=5I0.;JKSG<?WU$^T\@3P.OH[SDR1-'Z;Y7>V\USAIY
+M;A:G2,%69],$/'?U!Z#:$Y6M:/=[!2502IP2J!W"IL1]Z@/:\]L)^SH3^WU;
+M$O>KUW#:8_`IE3AY1!HQ+G%"\]=2#=V876#9V\SL:[>PRC^#VW`$!M*78")]
+MH2H]82:;`\EZ?P0]`>A+P2<X\>H:BRH]Q:(?T0[<CQ?AOLIQS(YY$_-?0GWT
+M,'E`:C8NJ&0.I1]9DX:;P*7:G^]'[>I5==\_`J2R&ILJOA#0_A&))75;0,6F
+M74--_8W[S:8>FF8+:WX/)19NC-=F9RU5^<>(;!(5E6KKJ/1F;<;]V`:NWE?(
+MF=\CBK_9<R*8IOB:"V45#[OM^1RW^'?/4*7CPV"X#!AG:T@T]S8"C!JW*K8'
+MM(X:7!5]I$-+ET-;R(WR(](?IKY,VY8?9*T-@2AN[OA+.I0#P<9NIAS:`2FS
+MEAYJ5_;1S<8XK2`!5\,%]/V(C?;-F@2QP2BYVZY0IA!D$M>:3,`)TX'4=V^C
+MJO]^&-KK"5UG9(HJI3\V-+*`(FU0+78B4_4^!^H:.NMKUNQ8>">^G=M,($+G
+M@POC33V&E9<W#.2?-B<1B+-W#;.+]S\ASP=.^F!O#_#2!\W!/UC%T?C=?/1B
+MU<VZI>$J52H:!NJ?-C.&)B>`827XXQ$H11=_C+0R=3,N^S\U8H*G,,'%:DSP
+MY(@)GL0$[U?SS!1"%9\E\CM5G6A\NQ2U`)U11X%<&+O5C"HEJ:?NVP;(EZ4@
+M_T>"YXH4-`>?Y83KPN$:"X$-4C@"%*=#4(U5V\!"(%VV^)L(C&R/:0<90>&T
+M+"P%7^6$T=""4'`U)>41SOIJ),?'-!62TD16_<F]YG'-^#PT+LC_I9*V13J]
+MGUJ-*1_0F04*;ZAF9WOMH?.[;@]7*9G40R#M4',/:"75AAZRBP=5UNA^:5&>
+M>*7NV',KN6SY94`[L<F43%W<U?"7_#H$M)<WF:@EV>&EKHN,([Q<.)2_6FUJ
+M,EF1Q:0S1Q8IVYWH/&)6#4\WQ-^H/0J)RLWA/T;V\,0:P@FIDT<SM%\;!;)%
+M$4/=KJZM%^KG5CX@;F[@YLVMHT_.>+JWU`L5@N'K(QZ(CDU,-R$X>,<CJI)3
+MWU>QT6U&U#9NJZR+)R/UH.*^+97N^W:Z:U&-=..A?",5&VM!]":/M9D;@7%"
+M3X!FQ=:;[9R8JTJE/R2]L@P?6L<F8@BYB\X:Z2%=F$=M@>U7KGV+[%R=T(#.
+M<NW`)E2Q>N\P;(:TGU)67CI$!3A"2W`?3VJAWN3$;"S.T7(M'J<F%#@:U5S:
+M5))`3Y*Z1Q<$H`=EY7$,T.MRU<>?(@46B%\OT^[?A(KPAA^2?HE!F@=Z2WMF
+M$U*8F<>F'=V,R4J3DGU2A3I#0/L7XG=W2'>T_"\.MY94_U/RXV$$;J2T51OJ
+M93!+?7X+@(A4A&F`GL[U5]W,-0O9ZO-[,'@%ZM.8T_%:R9A2;=GFI'P_P`0S
+M@:^>X82)BO<9AIJGR";8U.>?Q4C[>>_3XX0,]?D.^,)KN+]+8V8S#;WEVAU5
+M<99K^2+YCN,]?8]84_KT^ONP3W&F@@%=(<%X4T.[_H;:>[-)\T)V%P419UJ1
+MW.VE6EMU?!)P&P[(>6JHF;)9JJ@ZN(=@JVZFN47S1=3+GZB,YQB+`V]V0)NP
+MR=P]G$OV_OIR?J=]C;:-T4-D%#M?@-?/6V#&*ORK%-7%TY&?AL/-AQ!FMO!#
+M]G*U\%TCQ-'R,YJ2X(?;T?+3^$>6H^51$M7AYEN`FL@9V.&)0XV.'67:S$VF
+M46?$&1YNSRDL&"&;O4P;9^`\*3S4GA/GV&T9K1G%S;=D"V.:;W$+XYMOR7*0
+MB,:O=/@2%W=F(&[%&'`!`H2_RH/-MV8+TYIO=0M3FV_-$BY#PX4)!,2!J;(Q
+M57JD-RP/0MZV$%9RR2PA:\D<P=_[&-5[#P1QHH-U+3)N4GB!>"T,Y'_#RRF,
+MGE-##UW$#GRZB@80FL$Z(Y5A-83I(RN^*M_V*C82MPOYO7G8[Y2/7.KD,ROW
+MR(<JH4EAEZ-IHE&,K2T34,\&U%?U(G>%FYLLG#B.42<AWF[T79.E0+R*(8"&
+MA9Q:8BW5SE<BQFS.[>S%C62UQ!+9AN/3(:)J1TLM/!`H.\]!8*8.!?-LI5D!
+M?Z0.],822RF*F9P-)I'>$KDS&>84<N3G;+Z5$ZQRE-+VW9?`!">:CQDF4"S(
+MS/@!'M@^M(-]_!H^8#C)"!M<BY=?F;8/"6;=>S<M8@VGO:\^E]6]D4G7J"XX
+M/5Z;B5.DD,;!#RK,D6U49$Z86:A<&S;&MMP:7K]1]=G6:-_::#"O<,88S,XF
+MKTGAO^E;=G!S\[BYTW=PT_/F[QA^GN/(>IJQC*-1/*8&[:I_'&XM>FU[>SJ.
+M.??VP%CB_B=:J9I-*U7_!K@%-)IK==*5!%'HGF8<?-!^VQ,<:,@HP=;_*[R*
+MN56TZR"HTC2$$="V8\TZK4AW-SL.9):6J-*U$$.^((K1NN>"$3J+I2^@EK`#
+MK,8_X.;G(BH7VH8!GN)X$=<."0:D'@>IU6*8/*`MDBHAPHDC94/L'8[?!>.=
+MGG\>I%DS^M$;30,?VIV7OBU=N,'Q\#G.,-/=\B/FB.&%.WGNJW[/?LGOI4O\
+MOBS/_\G?JY?X-5MZZ"`PW5!8B(T1^BL(A-!Y813,R3,[+<L*.RV<?&PDCUM$
+M3XN2FK4.`-;D@RQ1@V^6:_GW\%RG]V]<S=7EVJ%[F>+H`L"@5QZ[&O==:N:6
+M:S^FB)K%Y=H/[C69?3PDXCW]]:/D3DBZF/S?PLM<#`;)6JR^LK8`]9%[X:\L
+ML?>-]+Z.WJOI_2[X6\.7D].SPVP"&CHOCE=8!I]-MBB4/E+H..P]!@0T^5Z>
+M>5L+G13&=UJYHAJK6I)=6D8.C='32H9:PN-94!Q,DJ"4\'(AKU!Y<J$-F$>M
+M?!7;Z@C/3=\X)^E_;OJ.N:G_<\,7KJ?OF$W_<].OQU\M_#::;5V:;/]_!^GH
+MQO9_E_<,>^#Z']=\ZQRA2!6UH>OJ`57ZIY\`LY1K7J.NN=(%R^Y)3$4N"Y`?
+MFVJ\:*NW`?ZH/DWVG4+K>F]WJ8KWG[RY1D4SY&/PU2_[CJY1Q3Z8IIQ2I7__
+MB;%*WG</`^Q&P)<9@"$)`XU_>J>DT7I*MRZ^J8O'=/$H`_&Z">)GR2"FC`CB
+M-"TDQ+/^VLRZS<CJ@JR.;^,Q;A!OVMZ>Z:@KR5X-OOKB7WWPU1__ZA]6$/SM
+MK<6"'(<S2]327TD7ON%X^![3?K_EGTDP3"_GN9G&;_I7_%8:OYE?\EMRB1_&
+MY7U%WJ_Z%7R--/_3Y0.ATHB&]K"K.S/S#'L5.O]CO$,P4#`(HA8T:$1[E'&J
+M\COH8MGW'-K>."%Y'IG+7`;,U@S32XC_(!$/719QJM)'&.+%$(W=*U/"I+V0
+MK7M/MV66M+2+YZ7@:0XO`#W-)E&GQ^W&#SS.I'A/+Y.]+[P<\/O]@Y\HOA<Z
+M/I\Z\XTBLM,[K>ZR_$WU:A"O"N&8I[/A&MG;3O<,/5<N^U_5/H;A!2HA=<:D
+MKK_1,:A7/6)[W>\#='>;#9,<O0LGY$AQ$%D&P$J)ZG3QK):%XU?ECU/M@:5@
+M+K?[&Z;!,^@G=/M5+#A#\3D=SWIM:990^VY+R?<'@W;<>;5('7B_!.Z.4KI=
+MO]5]N>AC5<QMY2>&]*9GS=/*_ER//Q:<H-!U`9W\?*Z(;N3)]9S;%1FRK3KL
+M',-#?ESPM4M'<`L7QFX+N^B9K"3RSR\K5;SV@E+9WZ^]54[&[IV%EG&*OU_Z
+MZ#/HCK9,OGM)5N,8X"ZIO5OV#I"M'_116U9SQS^T^OJ:/T]O=$)"2O`S3.!E
+M\1;^M27IC:-AN);:CV/X'%SOL:%)JTUZBR?:`E'O6C*Y(:,YV#>Y,1OO?.+H
+M'*7TEDWWVJ2+=L?#LC'&/U_Z<S;&[UK+<\O@=Q?\`O!;`#^W\7/`;[L19OXP
+M/>)3J+=:BR+?#!\&.N-:N_GH=5X[-$AK27ID:9LW"I'&_;\#LB\:R0\?MA*!
+M1?%4`YWJB%S.\K+$II6/C7U&LJ"#'`]W723K0\>!DG1U:::M]<2,CM;5&3,O
+M@+XF77`UI+?Y!EH=B<,-PW2]=VZG?4F8"!?@-NB*='57-NY29EBBY-*=#%V:
+M'TSGA)HU`;7(!OTVH*W"?O,/X&:FI;/YP0Q.\'5F+$8;1S)MR39130]W9LPM
+M=AQPE$B?.W9/E8])/0YUWYD)4"7>VEILZ?B<;^.S6S-`^X,Y9%O+9(R""9@G
+M&&O<#T.Z*FU)5==,>@.,]Y[K>,.Y]YQ\(G1R5Q:>A<DY_CK=PPDIVLDSM9"-
+MP38,#I-I66(_2.KCC1,Z%YH:1W5\D(-6H5QD>GC/!13[C?:.#YPT`*!M-H;I
+M7*.MXP,;*>191Y`5O#%#&89F&J;_#,>/"CC^>@I^&8X#1P`[QXL=*0!6)7:1
+M*NKK:S=LKA`J-[H;-PO5;MI"]!N^BNLKZQHJZYBO8FY9;;U`T>XMM;7WB]O-
+M+9MX:EQ2XLHJZVNW8"8O.3C.<\_85LL`S.06N[GLX?=Z'%A#Q*R*/:'C0C[*
+MR=FRKR?OI/QV8H=V\(1\#*3B655:^&\H7-$&#VE9%?L5"?>`]3SM6\A5WC-R
+M1MY))7AF:-YB7NJTJ=)BS)[15<S3-IZ_9^8[<G]'-*V@M*S&JHU=!XJ\<=5!
+MO!Z;MPF5==LJMABMX(^[<3;B67#J'N"'I43R,#_+4J4/H4B0#(J$!I4>9U.V
+M*GV!0:/P[&4K,B0?'F[OD=1`CY?2Q8.*]`2)39OL5"2<O<N+%#J@@_LIY31U
+MT^XI1Z46U-5<]*(8L(E_"L%4KQQ-J5&VL+GK>RP;+JBE:Z@>,,A=5#0#S=X3
+M[BBXU'^I^/UU-8)X*A4Y=);HC./W=H#A]UH`E]``)Y^^$-6FKMO-<Q?3E$:<
+M2PIG]!LQXM_B$:.,2>;'D0[RL2*,PT751KNFF$G$IY,KM#9@8C-"A:(C5RBU
+M/M.I/C]FF,]AF(?#VA03]QL`07VA-FH$W-G='64CX<X@,AR/P?"5C$MJ^3]9
+MQ0[,F"C\B]]`(:Q]SV_T;[IGMPUI/P%3P*A+=%C*^D'Q*F;C)]I'.&=_(U!)
+MJ-.X9B&^?A42P@O,(S9)/I[B(#_SF?2>LAZ1&U^/`!(/>>TF"&--@A%],IR?
+MCPS'-?2,,J[;EVG_=+NYJ9X,8]/7@,''853=S@\UMH)_I85KE]VS<O5MA2N]
+MW#RQOFY>?75%7>6\+;4;*K94<BL+5Y5PMQGMFFK/^<E*))T7C$Z9J4H]O\`%
+M\5:@"&4?><6QLA66,>Q3E?H@`00&;>F.AT-68T%]"GQSCI:==!6FK:,G/4UZ
+M&E+W;H4`FC3C>'.AXX-TN9O%E*;MPS-:9=JW2XGV2B0]???[H/C0O/H_B`UP
+M\0075A>T:M$UYDK/'!8.5'8V'C99E2X2VB?B01FJE/;\%WK-5+QZIN.C=+D_
+M3<("2[7_(&;!]\ZE>5-IRPAQ#[59#%2-`A8<U!Y*@&,Y`)Q\,05:XS!H5)-7
+M>F\P?&+9.&%NS5147H?@<?.PG+T6YJMJ'BXQ'BAERP`V4,\\A!=!&5)\=-6(
+MQ9_J/<#:G#(V[[;,$VWA8GP*G\-?Z*E?&GUR;A8HI1>F[DY_>2IV!Y80I>XC
+M^"4PJFN/K4+>CP>2[FOE2F31CIMKM\P3)^%]>7;JNWG"7_$(31B"A0Q:J/HK
+MZU/Q<<"KZ6I"'_F4>E]=.K&GU'*N3)-7$1$@ZG^D)AN%(O56Y+RYX?SSC(+*
+MM;F<L?TMI).:2'75H('X_/9(NG;[&CY^%J1T]>W+UXU`[Q>6$[.AB7NZ[(O)
+MQPQRQ!>J,KH,^<#',V=Y45SP_QN6>L$J+E2>QQ129T%`ZRDU*>-;`84@2.T%
+MI5H'LK+YV?M;UL8PP4[D=0>T)\V\NVZ-YW67:J&DO&ZZS(+RIHNWLKQ[.G&(
+M"&A^,WL0S\D]"',IEBO]*:*(6^)@*`!T;3Q(2763.]57D"E>0D6$71#CPK!/
+M]T-8AADF3BFE'-0LVE]6TD%Y]AD!4N&;,J4+:;NLN(*:,-7^;\N?FF5#Y,^]
+M+R(CVU9=4OYL>3$A?W:;\L?!>'@;7LJR\2MESF4KOX[,:?$-ESG;?4DR9S>A
+MNMZ7)'.D%T>4.6N^\;5ESAC?5\J<M&'0OJ[,.;[B2V5.T<JO(W-:A@'YFC*G
+M^^O+'/>*_W&9,V'%2#+G)B3SZY)DSG67D#E"NO;ARI'E3?(^?)N7CF#@+9KI
+MZ/#%)$5\8<TI+C<M^UI0U9`N6D5/DJ29:#%-?D(1Y/\D:7/[\F1I\S;B*UVT
+MB#<ER9J\E;QI,/2OR;E!WDQ8GBQOOF/(FXOI9GY3WOSQ&Z:XVI8J:4XM2Y4T
+M=%]RLJQ!9A@J:RI>OK2LD98ERQIKXOSR/&[>RMON85>2U'&K5J_R&K)D3Y\M
+M=:]_RE(\AF;CQ.R#8R"D]PN.G+X-PV4"!0Y!9J)Q.RSI@#*4WXO6-F$FGO0\
+M9F<:T,Z4X#[[X5=H*^79963<'M!^N@Q#VUGH]Y?1AKLJO<&^*TH2C&7<T;,Q
+M'-!^@51.ML2,XT<'M')(>7`U)K@MH*TH8?>]DSEK\X-`HU.4_90<9H:OO`FP
+M\2YCHTJV@Q-)1(=U2J+Y`+CZD[XODLT^X_^@.=<N]WGQN<KO\Y8MOPU??="R
+M:PO+OLG%6QM?C$M>X+5PY4INWO"UK9\60;\]_[1!<_KS>)9$.U#,<WAE.PVD
+M)I'B*03C_5X\[LFHIYDC7Q$&OQ,M!+2[B^-L@9V8;*F&UL]*,)9\YKU/73L6
+MK^Y.";.\H00'AH8D"!9=8@7[$V!GOK'G0B>$-V1#SW^/\8-9&\V+9O$K#GVA
+M)]</'72QKZ?ARXQYLM@P%8P:`4I29!-E&S"^'DB*J32S]1L!:R$`?<.AQ'%\
+M^W=D*8$126XYXO]NXY@`^O)Q.)6/_&N+YS-F\OIONP0__;(@E9_0%(98I^?P
+M"/STP>&OX"<TC@FG#/?:8;+K+K[D<#]P&(?[H3RX;BER6\9KQ%VSO`8/7H6]
+M)-E8Z`2OP8/CV/?[MR5XT$X\V/NO'/._?%U)*A^.#6AOWV;P82\N>$":P[<-
+MY<7)<K?4;D.AYGHMF1/%,08'?H@=N#*,*2:GIG`:*7Z&*=!?)*:Y`M/PE^1G
+MM7@(/R?/(:^^E;E`,*ZWEHOR4N>(P\:E<[>81P/-.;,3+<%J,@)*T0R]FVV7
+M7^Z)TAF.:\(>,29D@FPF_TS%%KDS<CSL.)SAZ3)WY`=/7]F?=&)N6'D/L?+R
+M]?"7E#<9?2-;Y4$L+1U+2V-E_2>6)5]@L>?D[B'^KI+M\2Z#<M#KASW9ZX>Q
+M&#>``W%J\%NK/.*`X^%'N+@K,Z<:Q+L7!U![*ILA^_OUD^3DTH[N_KPQ\9[(
+M?33.V2)WA5/K@O<V4V5P6\T>.BEX//ZH.-YTJ;?_-M,*X0C>6QZ,B1FK2O"@
+M,9U'MLWL5/`Z!AO@T_`S'/K.)C-Y<E\OO!G'71R:E/A*P-Q4\3Y<1EMOIB6:
+M_/.T.=D/LC"LK^9WCBK7#A4QXY],)1.-E3+13@FW?^\AFP[T*>CK:[440H[B
+M1&T'L+;]1FW-A0HT0"C-$S+E;MRRAGS]'M^`.`ETBMW[(LYPN>/PTKE1T!NH
+M(6QX@+\OOL91D!<7:\/F",5+C.5$5GH-5Y.ATM42T-RS`8%.M/69&H<O,/A8
+M#QNK0W98[E\5:F]Z/V72,FS=_W<W?7DYWH'\\U"4IS-8Y#B\=FY47VW;.5HI
+ML7E*<IK&-5_(%D8KF:U.'9KQ",KM\C+MFX5Q5+),5,+%T,5-AY.]^(Z`2QGB
+M(AWCV,YYX0Q%.HK2L7"V]-)*W*$1L];TOL/&*%P:^P4&1JS)-E@UT[0C-_.&
+MHV00:F0+NN-F\Z*8OU%FY,<:CJA76XK#N#\J\R]C1P(+;E/$&"BZFX;`-9)/
+M,)(O?=EII+^%I5^8FAZ&K[3=/S1S_;X0U\Z!!`?D0K>1+X..]><@?J>7H"B/
+M:MU+3#5H'=9/>KD4D+ZZ(5=Y&2NJB#"LX][?9S_!Q#]:0N=.5?3A8I/;*(7?
+MUO40YID6YVQ<W&WG<&$5]X^2FG\8O;WC,>X?H6T_6L(M=AS(:&D/3KL9[?"$
+M"62!?O.WL1_&OVQE8CK\,L*E\Y]QJFY&7-!%E3WL\=GK)TM!)P>2+>B4%R91
+M?F03[A&E-2Y"EQJG9[6\\D(G[K+-!#3PM\3X+8\XPN3@R^8X,#$+R#%6+!];
+M#F3]R4A@P]0,1>[![JM!Z0I&1T$_)8A_6)T_6,366%,Q]T;E=Z[>[D9W$5?2
+M#D\PZFETB=],3:9LYSVBL^Y^N@TO&SC(,HB'4#UJ`&T\O_T;',=Y/,[!H8CK
+M^)4N1^W-,$4CJ6*7NU=`'7[7BS?X@<R(>AYPBDXE7SX',!VTW8#W\F)XCCA;
+M>0`$I+,^!XMB-TLH05=7)L*.B"1S[)V6;R/8R'Q"-M<1PFMIE$8[YG,1BBL!
+MNRX+Y2DDWT/VSLQ'2^2@'1".7!8>BNL03'L(!GD;"KID!ZY@#S^R/M2_J;20
+M2`JGC3A!Q?6J_.2Q`T0N&PC-$=Q3E`=-Z8W-[*>YK=P_*^Z@=-C8>LU"TQ]E
+M,OR%J?"=@2'2&D0U#(<(%X@WI`M6>1*5E^I?*ZD.K]W(5`8?C@ZX]G1S.!PZ
+M+MH[,]@9,]I;3BJ3L9N>%UA#XI/D'UFCI1OE#,3]#*728N!&5A]H8=%I[)L"
+M@CP4MH1)T5M3=8@U1M6@!JE#T0FIBX>!>+3BB^E`RS@(B$<5;S35MV=RV;^Y
+MP6S+_./0FHZ0+JZ.9(4[,[F(#WU94O'>,&Z>1(8T<+E^H]3)0UUE7Q0U&B?Y
+M<Q7>I#H[R=NDI0.H"KE5/(QV8GU?(O\1#R^/$R8_AU?)OO(FRB*T]<!;$KK0
+M!SXWJ]SM*9_A>*@?T2B9;6G'651W_LE!]'9A.2X?2RNQ`P\[7K1!TRU52EQ5
+M>H'-\>(RFV=UKN/;.*!`6U3)-M6^'`1RDALF]"XE6[N*:-.QJJO(9GII'C&E
+MQRIFZD5\9$LX7$7N'6>F%K5[O<HO[^BQ#H,<N4Y^Q_%B,?IR5/F"I!0`<3]`
+M=+RXRE:E%-FJY&(;8JIP57*1C>%L,#TP1U<F;:RF[(AOK=U6+U34">+VQ>Z4
+M^U^S,;:Y9+C\NQ[GL&]2D]BFQ>1B-UEKI#5_$),#TV8%W')@QHE/Y("MJW@V
+MV204SSBAR<5.9=6,EZ>&(FOD8X,?='S"RX%<Z4)^D[VK.'<^HC<>:&;/[EST
+MFM^0"8'XH@1R55=9QP=6.9"C!&QI`6=:(*=,^^-B9I#%2Q=T<7S-%'5?_R_Q
+M1)=5^R'00F1W6`ZX(*$<X-,"-CE@K^&T7RS&:1/9>EJ5@(MUE+)[VJS=;G0G
+MN]M6OQ`*2#BW*/_-`GCPJF1_\PO]/?3$$41'U@?0#N:]K='?_O"9`HY[;VLL
+MDMTEX2O:==58M-]:$G>+W+-UPY;*BFW8KD)MO;NVH;*N:DMM8S:W"9I\+C0U
+MMY4NR%WLC@=06]^;U-8-\P%MHF<Y^(QTJQ5J.UF5EO\G3-.@MO^Z@/3D+F\[
+MGG;K\AXT#C&BUH)GN%1O>ZGJ/0I)5>_!4NVG'N.H[:[Q4K";$R=(P:,<SE6.
+MHC&DUDAW171#8^$U4=4'\(\E`R>6]V%YVM2%J"*]0-:4P;&J=#^%?@=PZ*5Q
+MRW]*\3VC%+IE[RFE<)KL/:WLM$E=;CEXILO;LS,G'<@%1N*S->XR77Q!^Q2I
+MR/>,_H!-?X#'@!X,"#ZC-#E/_$4./M?E?8I4BJ,YGN!30?2Y#L#7P$#R5)6T
+MY$%.*)>CCF<+@9'3L,0?.UYT/0CBJQ#3_1A]7`*D$I>ZH*SC(ZO"Y^$*2HE+
+M69J'8J*&#BMBF5NN9PZE2UR.%]?FV4(GQ0[=^Y3B>\[C>VK7MS'%@]?CPN5C
+M(^[EOI=G,H(\2,NBN?KS2`MZ@UMOH(MH9X.JT)5!W#>^QCA8ITW"P,PT8L2!
+M)-GJ3$!NRD.;-I15G'$IER';36>F:!P1`%BO0Y\$".I+"W'Y8<"R>]3!@B('
+M]_W!X`!;%]22;+?Q'_EC$#=N;JC??/VE/#(L7)P_?[A'!I"6PC3;4'L!@E>U
+M>8>XK7YC5?UF`^3U0T'>N/B&(2"!W]\'J._MFL8C].8W[?+2:;;WMDRS@;SY
+M_9)IZ^Z`=]ZX]P_8KPJD7=5HSEXE>R^^M_7B^U[;;]</``LJWH'D"A(^7UZ]
+M&Q<ON'%X];X_N`MK1_GK-V^JKQ1JMFXW0"R`_PC,C?/RX/\;W'GS%R]8N/CZ
+M?'?-_=6)^@`8F[)R&@\*.UTXQFD_N)ZMA5!@CN*:)H^5O\G+%39YLUU^P"GO
+M=+VW,S>__77(NW8:+SWHQL7UNAQML9%O+36.3<E6[N"5^VQ*C5VI<RH/NG[[
+MX7LUN3!$6PID^[37A_5'"O+77P+YO!3D`=D_@;2Y`U$="4]`WT25<$4L'X,,
+MZ_Z+.!)^6VLW5IF],S)V\SU)V#'^>"\X4*7X!ZKVO(%$X.]_;VL_.NN)O;\>
+M1/(`^IN!Z8,O)COE93Q$G*F,1KCCS'])5<5]EW1?`M2P:`AE$EW^X?4$OA5;
+M<%WP2R`L&$;;=ZR3_R"UITD]L9E'Y1Y#SN67ZA^,Q#_W?)T.2VD2I#7J)Z>\
+MCI?OM<G5=GF[4][A>F]'@IZ^3K>D^#^:;4QM3I,RPXVYWGB52ZWLK>."$SYX
+M13K%4FS]R'PML/;]+O[.@[27NEF24:E&&"GV*G\WBQ1E57H.Y*:RC\I2QE7)
+M^Y*_RZP0\(OD`!X"7L``A05,K)+'FN\!2+W&&O^"I&MX91_#RPKH&J]%B*[Y
+MCNCN8^A:1W&IYUU2\/WH.L(WH-4`Y8,^QG?T.*C($Y\X7CQIZ4[-:N:/9_]G
+MR*X_CYAI,W%D-^I3!&"<CA?+K);NX?8J*?8OB?R]^69^QXM%#(VR.!K)4)+S
+M7WL=ZU^C<:"E+.9[$7P4QINM")JMD%>44^PK@Q(:'S:6T/C*9@F[V9<=$PZS
+M=TO:_YAIM-]U^7A(J)A5/&!-:KED?!MGQNMKR1_!OU+Y3-/>61=M-;IV-F^X
+MQ4]*_6>:_CLP]8$14H^T_CO#G,PI0>>>SW$)M['@4G=%G)QK'"L<-?)=$6ET
+M;X.X9+`+EZ_%=.ESMS!OL,MF?&0)5PUV.8V/;&'"8)<;/H1Y:N'G4M32`(&C
+MQ:M:C[5F%$N?W^4(X1V1@UT%2`2A]^"],^.NWFX*0\7;T9*+.Z*?NQT/CS<.
+M&"AGW\7UDD77\ISK$C\!?LWPNPM^3\"O&GZE\'OD2_+\5W]+X0>X%G=F;.MU
+M,[SAO:[7%7^_K]<6?Z_H1:6'O3?T]L??A=ZS\?<J<N[(WNM[WXR_YQ6W>5U\
+M]Y),Q\,'*3`/`WM_SK']]6-23Y,4=0NV05KE$*["7*W'VK4,>QXT,KZE3<LT
+MWO$E4L?:6^0Q9<OQ8(;<T9GA*[X4/1P!B=JA926N\4@Y:WI"8]=X3.K,N!MZ
+MM$G,Z,RX-3(VW-Q1T#H&Y](9<XJIMSLSR/XO92T_F49774-VMKB8#\5,*G8<
+MSL!YMN/PD=(UVG5_TW6Y`_3VMHDM)\4/Z>05K9%<>@_BXG0&+XCK"N@O[J*E
+M82J>99M4XCB<B6<@R]9H)V,&W%40W?AAZ#QJ/!"%*=9H+U#L\,*&V+].)^;2
+MYL]!`TQ56*@'M!N!X=2EF?K@[Z\<P::3Z0)Q`&NGTVD!T/VO4*RX3UF$EW<8
+M>K+A9T#U]J,N3(=Y3N`0M[YOR/F#)<GK_]-I70,T;#P%CC=>&&#B&KD!FS1R
+MU=]3AIJX9[9Y[/F1',CRLO2[*;?)49SICI/]1_'T!-I1S3PAO]'Q0<;,-V#2
+MI;JZ\?5=&=<Y-$[,(#^B98I?P\T0N^+O\_ACN[(BUX3#$!"<JA3;9J*/_;Y9
+M`9B%]NV<L<?;AZJ^[M/PC@;(I_CZ8-HMKX(9H<90['.O`A3W59_Y0I?]IU+/
+M<ZG^8V4P:2NK&:,=A6&XF@-1HWTR`_NA2SI8P%JG!J<7VEVSL'*YTBL4+%XF
+M7]SSD?Y[W%W\[BQVZI3%"'^N(;``\@&(*-?J9Z#`Q38"*!-GX5SJX`A[<H]>
+M#?,=*I,L?+Y\/^Z^JY-H\[S791%FX'U<7X"`=.QUP;R*+9_=`C*Q'K]PIM6[
+M.8W\=TR4_3'I0H;CX55IQHFKZ!GC3NR^JWCN3?@);I!W\%L"OUSX]4T%667A
+M)/TNT=F5@?CEM_=>EF;83/5>P+-<:OEY`KS%\?!?K0;@TO<9X!:`<6SJ__SO
+MOUI.O_O+?_\='![YBGQG_C?:(F;DO3,)Q@OP_NH0F$]^11EO#HD_"M^/P>_'
+M1O@S\)0OM([M/6Z,$1>:CW2WCNW*P#WI7NXB^DKJM#1W9="^>/_?V'<VW=36
+M:1G=^UUZVNC.ITY+9N]#]!P5">)Y4TL6K;UW6NR1K?1T1RKI.26R'L^JT5H!
+MH]@7X8^DSQ%'=670]UX\6J[?[0CM0Q;.0/6AMP["6![Y@HVY!^UMHGRWBIG-
+M64WDHSTZ;:K-8D"FI<1[(0R'Q,:<MK'M'Z3A!W<$:XAI>J^(PV36-_/C>!FY
+MM)1<\<L.C#S)KD^&K]7^=&K<S:YH"NF(S]A7H^NX9=^`EH5#QQ%:%AZ0+J0U
+M3B.&>JJ'&*H`0)3";R7\\+T8"B^.'#+6FZ\)MSE*6HZ+_UICB8/47D)SA:A%
+MM+!Q=!:N:FLI8U_ROKAUJG$&=LCZ"WO$4"$S762Q1;98:3FNL`V4:DNOH14V
+MW,2<9/JIL8OI<AYT!,!###M+IB;!S+XT3+7$76J`_=/T.-B<!-@,`)L53L"]
+M-0FN]<O@%IAP'_]:<.])@LM_&=Q[3;@W?RVX39Q:?F\DI\W*#RZQ-#JD8,S2
+MD-%I=4?X,)Z3UD'K",9T\?=0>L97]H#Z<#-\FPB\.@U]7^KBQ$3I/)2>:9;]
+M,-H,<XJW?XCM0'R\23[#="Z7?#*\1B-Z_^#'Z/M['`[CZ3/?P(N1,F9VJWP'
+M/CMED3GDMGU)*ME[!A+,\IZ1O7BI';JZPI/4,#Z>OQH76,^`/IC)B/DRQ:>-
+M!"(-+QSJOI0N6`3X:E=!"^2?#VCCIL5]X0EK:N:5:Y]?G3B/SA=%TD"^D;%F
+M&&U)3^'0ZH\!!K/*]#P,L;H-^^X8WOV@_1QS]S/?"I'_#!=+%ZV[?Z`]?C7/
+M)5^ADO)O7D-%W;PZ<=N\C94-<S?>QVRG\&A+$LJ/3@'-@#FS0AT-X9%!VZXK
+M5>]3%)1]E7D@:$R2LQVWD`6#\;,DJ,F9%%*#5'H6%Z:77<UJ[D(M#HFCQ@:1
+M^]$W6D"[_DJ8?G:1HS3.K7A?D$/;T<?;_HWPMRM4#7]MI/RHH;MT\GV"$:7E
+M2HD=MZMP]62&OA]]7:G/[\H!5:HXO53?CTFU!ZX`O4<IX?5N:*<<NBL-/W`O
+MP:C*>`Z=3)::CK*P7>:9=)>\]O_@96BBM?V/6)GZJQ(N#<?EMT?N1W]*Q5>1
+M"\M[\'W%5<:6"'3K'Q4K3%8]A;SXL>-`469!:0))/(*IO74Y``9D`IJ=6M4%
+MU3F$TUN+Q_N4^+Q2R'N\/Q9_7J[]\4IV[.BQY'Y=>\>J0I]WJ![_GY,16?='
+MB&S#5&8^QL.,H+!F=D#[ZQ4,>QL0X2PR$L@HD:.1/-PKK,9;JP/J\Z\6H`7M
+M[8!:I_1R(8Z9F;.A!>UAPR8(?9^:DX'RV]=RY=ZU[J7LR94NA1^\^^#I@^=M
+M\+P-GEYX>N%9",]"_#;RP)/S&>_PY$I\:Z=OF+YQ\?2\^1N-?<Y$S3[+8>JF
+MWZX^_\ADO)D2_^K"=/1-,D:<"`UNQ_MC!#LHZ)&:L+2;Y\2)4J==ND47?P>S
+MPG&#[W5Z8[/H_LUB/K*,_$[$YAR46UM;!WLM;W1<2,?KK:;./$+7K,WLQMT]
+M;W1F!TB'-65XW6:I*GWV$3E,8:T4S.7-Z:"QQRTD\S\@K/H/ROYG4.E>@^H,
+M>JU$^]!'\.9<Q7>PXP^9KZ7U>_8JWE<'_X(NL%_%DY)X:+SCPM29W98.D%"R
+M3?&U0T*8J;`T1XTT1Y/2+.-U\9D:78M,32Y%CI?RI04L^UHEV''^\%R9=O`R
+M*H+.&'B?Z^C)A`_%]X)\#/-:WJ*L>)S^F.)_Q')$]C^"SNLRC7UHM;(Y9;S/
+MB[>6:Q)NM9RFT<1O6R%=N,SQ\..F#N_J93I\\T2>VP*_E?";#;\<^!7`3YO`
+M<Z?@UPZ_9^#W!/Q:X+<=?G?!;QG\%L#/#3\[_&(NF$_`[PS\WH3?J_![!GY/
+MPL\)\&(3$)EN-LZ=0A'4>SG-+V"0J,G45.`C]!6OHXG[##Q`YN_I=</S(,JW
+MWASR7Y'(CX*F]Q_0CC01AEX(>H];3)BVR+]`G"TI_;\:Z8TP%X9]/Q4&A96D
+MAJ%[G-X'4O.2@KP^-8Q4V>6I8:3*WI`:1LKVE:EAI)Z.3@W#K>W>S[F4,&JW
+M/Z:&H0E4[XG4,%2^>@^EAHV"1V1;XIN.^-^=^!Z-WZL2WVCJ&[DE\>W`[[F)
+M;US+BUR1^,9VBHQ)?(_CS*W:TZ`&G"$%IKM4^V(**3#"9>B10G`IWC-H0A(V
+M'1RBN2M3$:X-CY#[T!2#3A!$FN(_(W<KZ]],/K]N3XB+\2ZV!`]Z$TSVM?Q<
+MT]MB`4GJ'&4?+AJHJW3#:6B65:J,_2TR,1$.4R+]5^U76IM],2OB,H!W;4XQ
+M#GQ\J?_\[XU/7K]-TUZ=\N7KMYLHO:W&JGTWGC(YOB0%'J]M^0IXDU+2<]J2
+MD=/3'*8*=,`J68S1I0;1*MQH.B<=L885,=J6L623L+HI?\D<1PO>1=XTJ<4X
+MHK)DEJ,%96XONGX*AY>L8[ZT>S^DS_"26F'&$M$1PK5T^5C5]':+W%75\9<,
+M5!S@6^I91-]I-(][NTKZ./-\D6X1UE2!3IS)P;M5Y*ODX`"\.86QH!@-5(%Z
+M6'6UM6JPN^K*#@CFX\%IR<$V830%)P59A6\2&+L<-8%D,0@L)"T>8A/F00A]
+M1::'<1N!8$0FAZL&O;'E!8*S:E0VW7/J>+$#K]8)2T=X"28/O=T7413W)>:&
+M><GG?\;2YD3S8L[1XK"2ID^B6XP&R';)HJ5/PM4D[>]!UZB2O1JY6"C5'L7/
+M0;^&2U5IVA\FDCL89"_IJ+O&K6G0Q[A*R8>..UK0>8_\MMJ8@\[T#X^3_7C1
+MZ*@V;[=QV5[WH+>;CA1/3AQO]G<G>5Q+(W]KCA:\F1852G2\XCNE70]CKN'R
+M9X#N=3MU_FB_(U2$SE>\-E8K83+:9\)TAU:CT<]ED4P1HN;YM&X.WG'$/X[R
+MHK0<03XQT3#"!V"HPL:(1F9&57N>/.AXT:N!,CE0K8/`J;EYC78W"(;>5>A3
+MVO$BWE-T.FS,7\-44ZO4_@]0.RGJ<CR,ZP?R$1K?!O["QK>##IYK'>'WU"7"
+MS=]CEPA_!GY[?/TZ2,O(5+3K\?6W9YDV/K[^17A&&_UO-?OZ,Z%]>M>AW2&T
+MS;A6?Q]\-U^8)>0T7Y@CC&^^<+/@*M?ZQI(GT>VXZM8<[+L9O>O0=5E[*OMU
+M7*\P%VA[J,KQ.C]-=78['EYHC==9ZV=U+AC#<_WV_]YOQE?D38Y_#-Y;X;=E
+M3")\)3P7C,$V&IB&GJ>J`;U!;W\4FL'1<B=\0`0'0T_O:N;;.AYW*\7U<T82
+M/,.)-E;-OH'O]E[-TD(C+$<1XV+ARWM'L7`I.,`)ZX'2/)+W#(_4MH#NX@L0
+MM5WG0NVJ.T%N*MZP`.2F^%`1"W:KPL(H71<VH(O]H)3VE:[1>I&;.HS&AWE$
+MO&OH6&.P;Y9X+WE:NN-2I;XP?DBIDRY5:@^46K-NC=9@%-EC%'DIR'<,A7SH
+M;R-"IIJ@?3Y1#-1I`A6`#KI_Q<7;3;13U3;CU63BAI1J7@J!]\8-06#)R`BD
+M-"BZZJ#"J=DNV5G!H;![8E_1;+>:@"/HJ*CW3(SX#862JWGQ;$>H"0)0&O6B
+M.36N1W+EVF<<<ZIQ-+Z6QRY=P[.D3D5T*<$<*;I)J&^:+D5O%O*:QDG164*)
+M%)TC%/4^8[1==)UP@W%`6XK68JP(L6@-'NZTS@D=%[*JY!56\M>`6_+Z:!@I
+M#LZ"Z%8K1-JKKGRK2JZS1N[%^"LOTOM:O,,>8Z]"KSR\U.,\W^$6K';^?`</
+M#UMKD85`Z;A_5F3)K9(?M$H79XF9S2LLULC$L'1Q#KU;(MGP?K/(PWN:6L2;
+M%P3%[R_RV>2W8""6+JP3IBH9L@7]?73`_-K1@N>?'8<G2B"FTJ4+<\0SJ=99
+M!D/@^(>)YH@NQXO%UBQO;+#[2N_`E=YH9"Z=5Y\ECF<1`Q@1PX@)&+Z.A2O^
+M@<&35W9G>:-0<N0%LHT=UVF9TUEHX:J48*Q*WFD%A(BO(7R6$3X0#X_"0.K'
+MY2[+.B,N:L3UWJ+3G0`C7:"TI7;;IIJMV]WWU0H;JN=FI]Y_D04#L$.5N//,
+M`'&V_1+ZDBV>Y84L/FGI#E5N4]N"_ZQX:$0;,Y8IN^D)_ZC*^KA-UQ!X&U/@
+M31P)WF'G5\!+Z']8GR0-T*JM&#NT1BGUMR7KBQ8M=UCJU/0OVG"EQ56:K&-J
+MSM0\*?<_V5+OBP)]YJ4AR;EA\_TR&[LT:K63[L!@)[!O4_U/E2EB6+]1>WN,
+MN9HV%YH(-)]39:#3E&FU3G*-*7L?4UTAA%6FO9J-()YDIV"RJ>5Z+Z,-T">(
+MHG4QK/4X^/@U&(Z6-U`,XYF*T:4@%?03K/1W%?$1QX%`)G!S\P<QZ8BM3*O(
+M3BQ$_E29*$]J"V2TEF<P"YUROBV0V5J>Z3APLJA,+;>5H6H-F::-@JIYGR"-
+MZC&/[XFZ58EJ14>;IUX?N5U'/\4U]GC54"])K9HN/JD5CS9J1T=E\=8+Q?>$
+M(CXI[_IVK!?O[Z'Z]8]A.YK!)SAA(AU@0._F-;PN/H%`\ATX77H2KY[,5[Q/
+M)!86DOOQM0QF9P.B$E1(6ZEBQ;_:_NP1#$Y2_?]FT&1,;\@):+\?@VYQ3XS!
+MV[]S4NZ%2MB_9+"N?PSHN%0[,&8D>Y;IXM"UNBLS:(-#CDH]MW;T\.H+.:\6
+MPD!VBYC1C&M7E=(KK^*I<:BT17MH#.[,XC<Y,SS*EVN;QIAN%V:PM3Q@LP7A
+M<+DJ=7^.8L&A/M_NQ66JXE&T6(QSF5MJ\(J"8KY4>P!0[2RV<_!Q*1])>]*'
+MXM?M3<6O>[F)W\G1B!]^Q_%[<?17XG=J.>+WT^P1\#MA&P&_E/XR_:=MWK2M
+M8DN2W[/D-?C#/!&`=&%JXRA%ZH%`94$XDJ$^[_[B"W2XEW('Q!LKA"O0M0.(
+MG]]"UX`4D^9]P03L+S-H)V7(Y2/'EI7BI0W_AHDMJC3?2/SW&3PW?!%^S@:N
+MOIJ;=]_F;?/@.<+YB7&$J[UY<9V0WKRX4;P,/QZT<.+8&KOV+QD\F]-@>]I`
+M!\=Y4IC$;*W=]'8P0_NYC;@;?:0#?T_KQ3D&W2\;U181C<:T/'H.:&YX1@[0
+M'<-0I.C&?1]A0HT%TZ!PQR=/U08)&(U<03X!)]306;>E6>S,V]ET(SZFO4>O
+M/,W$H(>_H*L*?L4>[^!#RP3<:IJT:*993=%9AD">M;'+16(1\RJ'_V6$1#4I
+MG5P4RG6\_*!-D<XNQW,#\CYZ]B<V#X?M'79:B73+M9<S>--"1'D>L['E<%<X
+M[-G-"UEXX^"-H?/B.?@Q.1MY`-JK)E/;G&DVN(K7'?:'L6;]>H--FY?))*@=
+MFED<9>YL\<+OL%6S,PVI%>7$T:"M$,IXA#*L9.#10VM`^V?>N#(`NRF-+D4?
+MMODU1+X,6FC"_>L,%"__G#62>!F^7W;$8NR?GL&%PL3>X61ZT%6C;,WJ3*DJ
+M]L"<G;;LLK+8EIWM("[]19QXSLH6HX/@G_V$=NJZD_30>&%^2]RB3]N=8310
+M2-\U@6Y<S^70O4:Y]D(:<7JZL1:<?+?XGKYP7LI>5!I`5!]_ZFV\\0&`?B?3
+M'#VOD@Z=@E"N:;0X23K4#:]3&R^+V,VK<Z9PQII<K\@;^U$<TTLL^GY,#0VY
+M,@M/SS_V-EVF@RK*6XJ*7XX7+6KX<W1,>\'2<-_-HZ"-A#MO1BLV8:TRUO`%
+M6;7G0J9%6)K\;;,("Y*_1UF$:<G?;X)^SPI?HQT#XNZ]D^E]RLX<^=`C$*P\
+MD"OO;R4,//(A`5[VZ%3Z[#TZ%3]M"'A7*GA'".=+R@,V>?_V$:#,,*"XAT!Q
+MID(1:Y5"WO'B6(R#U#=C&#PG#\F5I8:GHIO>J\-J&-<]]GS`]4,5#F')ZF.3
+M,`C/)(;UJ?&X_2QN8B)Y;R$B7,CO(3R-\NB=RKQR2)EC3?"+J.BIT'8&S`PJ
+M;TPXGB!1;._[R/8[;3)%)94T.ZFDKVJ3;Z2TR<RO:!.'T28PQB35/^UQ1""R
+M)K6^-R1A<?D0>*.-ZJQ=Y(:V5"B_Y0@NXIGUSD-7R6F/(_6D/8ZD([^3K\O[
+M$:)\:`?2U'*GK(;Q\RV(."=_GO8X1HY7*?(0TKOE7?G0$_BU'[_26.;]3\+?
+M_.-H&W)H%[+(K9QP/9:+'\I$G*Q.ZRS&T3F=J^HJS@"F*\9E/JY0ZK3+E`K]
+M,;XM'<+"8>[S%O;"(80J=:6SOL!Y5PBC!Q0J3KE1WM_RMDX7K+10<DQUOD3O
+M$7>@,:4)5:B!?B8\)B$>=Y4ICS]!#8"9RV2U&1[:.QS;*Z<O&"ZGL293`FER
+MN:TMH+>6\Z#N6D#=S6B;V%J>OCQT?/<X*81@[8I99?%[4@ASV:70D_0P:A-:
+MBK*%>%FG5C,*_11';WJ5CZD_V?CV,!\V*?;/L;3X)4F<(8>U+MZP",#3=!/,
+M<843C'$)?47*W6E>6RFE_@X_?#X2A]_U15KJ_,6J/?!EZ;]'Z7.&3'EN2<GR
+M_Z/N7^"C**^'<7SV0K*$A5T@0I0HJQ#E)B2(P*8H26030`(AD(UWN20!8B`Q
+MF>%6$I;O9)%A&%T;:&FUEE9MK;5*C2#*Q00Q04LU4*K4HD9+Z\2--FJ$0%?V
+M?\YY9G9G<['V?;_OY_/_H=F9>2[G.<]YSG,[SWG.B9'_4WIM\S6\.^2>\*=1
+M^NC>ZYRE9Y:4*M<J\LX8\92XHK)<J*B:X!*JT#5BR:K**MZ54L15%?,L1IOS
+M9ADFC;<O6=B<=P@%N.B*#IVRT1P4L&@>"*J'AH5#L`KML(9@5?(@!=LAS2'U
+M7HL^Q^!:=2CLR\4K^V&B&9:(]ZJ],7.6S1;K_Q.+]SCEZD246BA=%W!K8S_?
+M:!*N9)<_FW,0+^Y\HUF(;\ZA7H.&O_YQ65I@EW(2FW.PT6':"UU`@7L(,[]A
+MY>]S?U5UGTS@'/M-F0PP;._FBEWW"%<;@P3[@7L`P!SV[3N142*9Q:/FX!'H
+MOSWS)[!8]U>5GY2@ICKZ^MCD*%3\6'R>BEX"@@,CGW@DISS=?B'J+R5VK9U_
+MT4*V*`1;B7CK#X51)6*-N1K]A.!FX8I"KWH]PKNY$&=S]!(0'!<H_:%7;1W`
+MZ49N^+^3$A<9QKF"TSU8O2]WUY'>TNZ,I?M[718R;TQTDW9U(-T%N_MM_II`
+MH`067A2"E6W"^K($[K>%<RQ"VM5Y`=5-D"I$_@UFZ6()#GMWHKQ+G'FW<)UT
+M&<]^*-`A-IOAY5[A2_P4)D@7@F-8NA\*"6&"$AQ.W]6"0SQ,4/FD,!&=9>6$
+M9[5P(8X^T0^"3F:.SI,3)7/;8+)S%\5+>MM]F3DO<;P<)W;=S2=O3A"[)O!W
+MDHA4[/HA/TGLJN:GMN$UZ8#T91"`PY`Y%&H-+X0O*N/^FD"1-)!A2VZ*`CJF
+M5S%,F?ZB%H:`)O`5,A$*.D:);(K2M-%`TR\KSY7(.>9(I++`&AP<Z#-]"33O
+MWPUU?P9=_&#=E?GH2`80AQIO'42G$HG,*V):@_+T.9T'9R_(U>VJ&?V_G-=Z
+M(3#BS!IAS?F,@39^)?`EP(.=!X5O-L-F!MKHUDG\H.UQVY`SLI`\0GN3&;D8
+MS<V/5<31_;'[WPC#M:;4(XQ7%X0ML`IONVSA\&XA-C7JQJC<MQ@@H(N0X#1<
+MV^4E8]=.IW)*'$?22R1W%E0>#YK^%2"^+$%A)A($Z?`OV6/7E\3$XTFQ//[U
+M-S3F*ON05&BX1T5_QE(S*@SU9UT:C2,N,%%;JO`YD]DAVWP%^QSGJ"7W&B--
+M3"9,@7<[_`X3,I1#4O!;O'BM8-&XE$\JO5<IA*;"/I^O3K-QFNJ7JZ0Y[FYR
+M]D,PKG7X_XK,TGR9G>RC##GN;E\T'D:$YKAK,2!2CGP8@98X]N]2B2V&$9/.
+MO%$8XWAY@5G'Y5[^2LAY(^:,32HV6Z,H-YLAI5`/3;MEKAVK"'GN]3%_`O8M
+M<_2@F3YFXR>2C'&=NXFWE6RIN3S.QP^#5.-\07L`"E-888,(Z>'2+JTD_RF'
+M_PG8()2@FBTVA\:Y3W`Z<5:R@1:*<2<(UYW/LCL%AYQE3T$;+K>0E\2!FBK5
+MK3@(NG&,S[2[A(F*.,$.W%9JE4WCJ5_FR0MMBI7.&RR93@96L6[+4V\&?L1^
+M<-8P%D?MGWUM(;M:!?;PY'"J^N8%2^2^UI9V*[1A).4O6<H27&3@/BU/JTR>
+M2MH25K(?_7,L-;+'+C/J_W_-QOM<9[/G<1HWA3V2L+M$1-.D6SFD>3S'EB&[
+ML;HY_3C-FA3*+]Y#3I&%Q//9=AN?`QWR\B0^PZ!2F,'?`+][A`E>+?L2/;MP
+MI3&9,`"*F01EY>"X"85E6ZES?&S2[*M(U3NEMQ`I?@+T]_1)?`K\<M7Q@#29
+MBI#-LK"S1(J#00G:6H)WB!;^(E8_S@DWR)#Y)&2>Y/"/AMX&XUB)%(\C&/80
+M]R3^B[:!3%Z9F+^0)C84K"O%VXQ^`+O9IQO_%<Y5]A*\Z&1<`X:9.:$_X(4(
+M/W.JC>PT6\Y-$C<D<OPTS9`<)D)5'=W]JA<2R)F)X1;TE@GOP$Q66#.B,@AU
+M1Z`U"H<#:6$6F<'WD^<D!^-D&4]N8>!`7XS[L$"9O9_4]1<K?!MM$Q&F$^HZ
+M$>9AP0X=`^\=`K'ZHU`#/LWPE87]$XKOB"P@U?DFO;4&Z)4-_C3`UIABTV6J
+MQ;-X$M>,DWS84;N!Q,`,0:>&3V92N(5\Q[!O]0.8YJ4N@T6YV''_9`=15LZT
+M64R*U8^K*ZC*!B=,V7GA!YWJVS`OH'NRA$"^>M?7^&Y%.^_"0"8NT.R)`@3,
+M(XP0-]BXFBL`FC)E*YY1-868:OWL#9TH=7[0B8+%HV98=Q!W#:(Q'><V),4W
+M4LMXC^UD5Y[:`>VM"]R'$8\,LW`1/*496\,F_:/9BMV&`W)$3-3%R&:[V?_X
+MET6S^X)FA[;2*"</H_'JZ"TS?2BSV#SHEG'X,K3M;:K<+7?C5RZY]X-,*`8+
+MH)V=0O6)L.;%G1_`KB^0/E:)'(^<COX,@(V>)1C1L&W!S^B<FP[;2F1'B93;
+M15%O\B=+MMQZK4^O!D"=BLY!TB#T1I]P=8F[H*MR<(F<VU7BGF^NC->D47B\
+M-BB`D8(>Q"H$6^)[?<)1MR?D\#NQJ<JI+Q(>[A:''Q6`VR[@J(S69G;J-O3;
+M>U^G/ON%A63"&X$Q9LAS;;IIF&;+1J<\.3@"Y\:9>-HP#16O+W80H\@%(9AS
+MYHN7P\(GX4JG^@D$ZXO2B:R?PZZ3BY8RBY6"?0;'$ZBM^.S@$,PH?NS%L"A2
+MZ"4O7XVGKF*#@3!#&*2%J@G`JT&[]B5GN\(MRM-=Q/:1<86+'5?^_#D-QX91
+MXGDV)\D%3IB%,H0$6(+_&9@Q.""`!\A..6LT0NTTF%OM#>X/>\#U]H1[^S=&
+MN&-Z@8NTR+63+I+9?1RUH?2N\D5:`_/Y0FW%5'S1AZ=I&RZ-LFH;!#HSM$3W
+ME;%R\_?;`<$ZY]!06)83X5<J0$\\$0L=I1R:1Z1#2:'3JX[M9&NY)/^I31O$
+M@\E702)^4+@>7U3[OZBQ40;M_A>FD^HPG`V'MR.LPOQ2LU<]]W44R$A@C5=^
+M]^RSSTHM%SYN_*R?5.>Z2K_A<Q7V+P;Z#\`/S2(5Q_6TY6;DSP2HCX:8,$@=
+M2&JF`IZA+@O(XA@(=HM8PMK/E3HU%^V4932V6J7WI"8+E11Z!74EOWXZ3&G%
+M@YB&X]\0#XXFB",8/LC:U\2@)*.IY^^ZBUH9C.(U4!4ND_IK+5ZO2COEIDJO
+M79R&<Z%-ZK(06+'!FH<%>8BL[/(";Q>;4[-8^G5_UO(E*]9\/&$B9%E>J4FO
+M2"^8%WW>#7,-7CQ0"748%)$HT_<]W5]_1F.G7IW^ZJ^_I1WQ9MUQEA!RUQ-J
+ML](:T`XWIG-O,H_F!XL-J>A[2T^P[N_1M$F*=6VD&J:6GE6X0F.&I]IC\(_`
+M^@[\#?XOVBQX-JGS[I4P@^EPY\7`E>JQU&;B`UJ?]7IV^5A;I%EY'8XU!DX4
+M`BTDR4AOV0.K.?J9=WONK#GY7$K5I)2J^U>7%TTL[XUWID(ABOB;8;B;^NB+
+MZ(0X4C7A]-BD_@A:U-TD.-0OOZ1M5)QT<,I5Z`M-/#B!4,O&<Z6Z"8P!PE->
+M5<3G$=I*'*V4>I4.$N\%R*56K_K&E\AOR02F`Q<0.3A\SWB5$UXU6.C&^QY8
+M@V[TD%4+4V$0EPQ'=/=^;M$4<:_.4[_^S$)''".8\G<OOE86Y^8A/>BV#;^Z
+M8A+'?I$T0*24*N[&![D;!>[&<N[&8@X"R\J7%G&3JO!84/_J98P[_ZF%V6OX
+M%2IF>;I2&Z0+$=O2QR^T*+,M4BX>5HD-\:/1T,FG=`(U7%]@XM:9K7+&XNY/
+M?:P#!S#_J6IM[3.4[0G]IVIFLWM<^>ILX('SGM!FX1IVLH)V'+MLDEFO](4S
+M)%[OJ0O=UL0Q_7>F-BJ^3&2\ELVCI#TS0Q&/4.`4*$/RA)BRPO6*>)Q"KS&&
+M.O5UKOHI\!#UC;<QE5<1_XQ/V=.9D5>H+FNWT#E/ER*>P6!%_!L^"A7Q0^WY
+M,0L^QQ[M5!(?U$J:@=(P[2X;V7'/4]<CRQHLM-')[?*8(]P8OEGT3^Q'2?.Q
+MGP^@N5<2\4MFO[@(BA?IW=K#?L9PRIL\7Y^+X$7UJ40PZ(;S6><3#[HHP8!P
+M/;ZH]ZO825WS]4Z:--_02;OIO_S#PJDCHBAABDIN4C&_'"I27%96I?/<2J/]
+MXW_T1"KX:1](#=*0>DM/H.,%W>@JHO@R?*@);9:([@?LGL49T*';;F'W(/9`
+M8S[N>"UC4)[Z)#7,;F:(%C>G+>HS`%DBL.P0?"AJ@?Q-Q7&%@.`9+^R="UH.
+MX&1\X9.3GTD%N_/5MD^U>7P^VZ"?$L9AQE]!1@WEX9\:Z:A!8VM=Z3V9TD".
+ME29<WJE9JC8:\.N"\>C;G!^0[;MU%/\!>GCHP+<_8^#;TC18+@9Z\5V._I\^
+MLS#;)(-0-A9KER0.EA6?F(1!"*D_0K)F!U\)H%_<MG7LS)`)DK$.'^*@0"VA
+M%._HS9ZGH3'W_9TF//56.A,EGQ'DX\H1GEJH/DV-ABWR3_5!J]$G67E)"5>^
+MAJLJ7HY.Z-:M6E-4OJX'[#O_CHSR%''^8/6LA>,T'84/4.,U7(\QI45*_8SY
+M2$'N4YV"'Z!/^J6J7O:M2`M,&YYMW7`%RZ:>8KU`.AIT!O1XV>G8/R3,B9<2
+M^%_A6<F;P<>8CE\OM'Y+_0Y:HW]YH.\;S$<]:B\!V1VU<U%73]PSGTVAA/0(
+MU%MNDNK',/9#@Z7#F\4)D;XW1GL+I@:\ZA<FEGA"-/&@:&*\H^U5WS)IWJZ;
+MQ=0(E"G:&T,'4I1:%-&?C*.=.E9G/"';<<1KZ5[5P?GJ1Y]&JFKT*V:HJUU\
+M$@N[3-<><(:3&.P_?6J$;>X%MOB?8?MDA&UJ>PAAQRGB#@;[P1C8<;W`ON'[
+MPC:3OB;"KF.PKXC`'NNKB;M%&.55KT>Z$B$!I%==SFED1I+Z?P^3I^\@-NPH
+M-#H[2AB,]V=).=3%7Q`O]>>_4@YB@TOUT^=3,P@)S>)TK5606^O_86']QH(W
+MV+L,\EI#?YC32J<1:>>E=X(U`?'2=4*\>-Z$/N[1UXG=Y[Y'B/=M,%TGF#)A
+MDQ.?`Z%\@7AIE&!G7#>JR<0%\Q"=!$2L'S"Z</.V.HR"F$S'D<$8-P#CXC`N
+M):"'7<"PK[!C?$[W/3`<)9;KZ:)W.,;3=\SYWT<P>]Z""YM3YTBL'9=A7--H
+M4P7/;ZB*S7?_1]&>/TH191>-]`H^5-??<;S&.'1/D$;.[K1.?2-$'3!:&#'"
+M'&"`&<^V42XMW^>?6%`W15^!-!-TPY07\X_FLV1#L[SX(0)NS^=HP?\&#5/\
+M1O'@F$4X@4U7ZAL@2A+:Y>IV1>S*9UL0//3Z^FE%G+`(K[B,B=,]Z_27/>W,
+M>Y!2UP%IPR+^-GFZ)I=:%5B%>"["$NKSCX$$0D>SIQ/59_!VN;K&JA]KX5I_
+M/:YGM')56<07W_3QP)O3;Q3NU):V6+(DG/.J*Y"MZC`-K/[>,Z[^9N=Y\U4?
+M%*8<1+QECQI%'7T./TBBTR3<KLU',9M'58K/$!M4+*VJ6E<T<=D&<DG:TP9_
+MS0=1F@U1'S538_:/.!MI\G2FI3;`O!+!YIT+[RDY8;'+5M/O``K@\F#3K7B^
+MH0O7'[8B.=JEZ@YT5ZXNM["^Z80-S!C8(5$SC%#$XNM"=/U<(7KDJ>$$E@Y-
+M10_I1B1SVGEUA0GWTQ`9QW+H5OE3!"Y2/6%5480GC#I23YS5]H&LBD/5YTU4
+M1?2G0J=B6,>NFZ3JSDBSDI;44%:59D\':UFHSDYSM#INO3H38.&9.0JE^DY%
+M..M5#V(CB;-&L04LJ]](K7[)?=0/!]38^K48]NA1^<_?2)K?3(RHS4J+V)LD
+M=N9SQAX7L__[&RY_>F9JIDSX+YK1F&]Y'_DT6O)7RB*^Y,D9UG!+,[U3-!HI
+M6DQ;.I<LXHN>8G%DNWE'S'83AYX*:,6B9=J*5?M(J4IWI:S6>-;@_^5]6.O>
+M]A$-8P.4>EM**,SVU/6)\*I;)_"J>S_!\0G1HIOWCEJT1=;D"4]1<L.PE])T
+MV^4Z3%%*38PMGR]GD>D!Z,'\P&9QM%;IX,T!&!`<1SBQX;)$H6K#A[21A;U.
+M:B%2!7\YX8H\]2>M%FT0L;'AK0#&18Q57XG'MII02%1"^_S-],&H2N01_J26
+MH2B]"<92\1F<Y0[BKTEP`#M=FX*,9E$O?T+'0ZA5V)OMEV?_:C%4BYQ%&&HE
+MH$E_M&<M/@>`J])D>O;#L4BBU[QP_5[:GWR$]-L[7S_W@O&L[3A1#,,D&JBV
+MQV\SYZ`$[[Q4=RSF&[H3C7M*MBVO$)U1-T)/A"4SA&?;83_WHOXI-J%X^DGV
+MB:J@=:>IR48;89_I5M;9;M^M?90]&DJ:'2UI#)3D/JO-3?K>S\CSY6<LD99(
+M0E9:>8<95U*EG+H41P3BX>C^2VQ/,M!],F1..T].[<<[_,5X7%5MB^H3BQ>_
+M%8;J8\)-,":T_8;9RH(,ZTT9#C^Z=V/=C(3E!Y<@&HY:\JHBXH><9Q?QTB:*
+MY.0$\2!U(_YV*;>K5T?/(;D.T45+'?.P&R(OY,OY=JE`10<R*F,'.X,M9MBM
+M05D;G+7B,NSA5!WAN_KA(!9-*W6TJ>R^FSJS%0>*>R*]>TE$!MKV!CI#/'@/
+MDXU!1<4&<YXZ#=*'*3T9ZV@GLRPTZE[1JJ_WTO7$GQ$7+KDJXG'N'*SQC*7I
+MPQ*45D@(R;D=.FEN^[\BC:/V?I)O:/-5ATZ*!5;MZ,M1B]=[V''*WTS:?<@L
+MO?`<M$7W7C=]\N_;*C@_;6,R&[U-/+:,/!V%$Q:\S,CB(_R#Y_PZV?[\H:4'
+M=5_^4-^8S9,]'>C_FP9B1!\E3J?D:K5/0MEBL742MH!J=O!Q_WF'']V*ZD5/
+M_Y!MR/4V.\586-QH!]9]D<VY$0;KC@7@T"?%^L(ARI3:VWH[)_P\.)?1)N-_
+MH:(XV)ZEP2*]%]E=^FEV3N>Q8\>OE4PXO]_HJ/6A87<<5_.4^I=HE_G!>[BJ
+M""EU^\;C,497OB*$O*H#UV!LBLK%W4V\;\$84UCH\JK?G+7H#N=N@ICS.6/,
+M0KR48X4$9DIP.II@"$M@%9QYZFHL)\<&R:QTV@$IGXVF1+PAI0U3WD8I[9#2
+M1L([)\>OI_0;H^D/L/0N+#H14KHHP9W1!#]A"9P(<.Y9!.B$9$XRZX\U17]H
+M>FI^]?F<L69A*.P?*.7H+0O&H/02$VMDZ61DZ?J;GB4=@&=@Z4D`-B.,ISQ_
+MBT1>[=L\AML$D<D0Z:/((WHDK<''`A]`F28A0<IQ86FX[TX(KW.I_WR/%A&6
+M)BYV1EB]M(HOKIS8V]HY:@]SUBD+IW<M9!8RCB7^[$:VME6'O&MA2W+!@=<&
+MZDYKLP[*'LDL9DH5IY4#;W0N-R7V7.[O)Y&MG$J=<7D!V^GI9RSZ6/@"#`.P
+M``UCH;H;NC?_0KU</$@K"WXPQ)LG4AN\P&(4\BJ'NB#XP-6]/7:O@8Y?M`4+
+M_Q>M%@[_;1;$@D9;A]\#'Z7IVJG]+Z"JDO^,KM'@J!V(Y]\4T(0OF$CRG_XW
+MJN#AR3[6+TQO37Z\(WXSS-?^+RE1"V%V&.,*U4>`9@JED/SG*+<*O[0>WX??
+M7M6$RGW^$U0R+6T80-BBA?>U$(S;N\'PJG\Z'Y/'4>O%B9I6,[[T\?Q@7_J-
+M#O^]*.:^G8VOQC$<YG!V-]RW$4?<GV--B%+A?5B_4HXM[VD<W$L<@&CE&T*O
+M^JM%M]GDJ#T/<QF=1[/LX<GJO_^L\W62F`T#FA=G?*%5_1LT>ELSV414WZ%%
+MRAUL=?`B#OI$7,F/%C9A=#N,7]M:T)$0*S@CC\%7?ZY#=_A_B)<@=""KNP%A
+M(+H/Q'ZT"]A]]J+T;`+;A42%.<Q(W$0HIFT0$1)))JSMDUQ;_J*3J\(0&GS/
+M0*[F;X%<21%:O7.J=UJ]`'G:'B-[D>J3\!X<V9T.NTY%Z%"%5@TBTT/OE.R;
+M#+8>9'#J9,")2>L#>D=YN`77[2CDBL;43R!R8#P.&[^X",4W:>GO@_12A_)T
+M0^2DO<>:\\B?<+^)"P3)T]YCJ!AX.C)4'*0E)1L3^K-Q"G)H'5I8I-0?0)(?
+M/$!;NT%A^E0_>$=;1>C#VR%<?7C#0KLV/DPXR8[ZDOQAX9[HVC68A>N6.H0A
+M$Z1N$/+#]?@T`/I;"P/D\JHK6:'^,#\X9G7W2X[&'"&D3CQEB6@45S3%<7)N
+M2%]T94NY';VN^#I[++LZ>EEVQ3?%I0>O#@3@H;6,$,)FL75IVC/"8$3@C;<)
+MQ;8KF6Y82'WI[<BFXJR^=U\WGJ,C2)[?P*'6&+7==*/]RQ/8=JTWD4SM[_A0
+M3[R#-9.$%N83=+`LHHQ%V8:>N*7<%JEII1DF2_7W2"W/":7Z=*'CM>Q!D._/
+M*)%L%3^V2;G'$=$W^42QN/5"8>D0EN#/Q`GVL-""U?G3:3SE;%'][Z!(:0KM
+M1^WA^=8-#J^:>5(7R/?'.VV._<YPG'@I#'WL4@(/^Y>7(+6[N>KDMI9M\3G!
+MMP)H6PXO1[9C!>3<%L=KF5#>#__$9J'JXQP_W)?;:E,\I_-T9+)U9$ZH!UEC
+MN^NQGGR<5_WL;20*HJ04'XHY\^@V_QY[RX*&HMF=M\XD+F(VLU3;]I(M&S,)
+MY:XX17)%WH8./&VZSZP8Z]0<DSVLT>X><)5<RG*MS"*C_>^W+,QIFJ.VQD2"
+MN@O1N>&RHW85ZOH<Y(D7AX?KUU^%R[[KWXXLE?`D3#U"FH$(DFD&XLF8(@9N
+M1@[XY*26MCIR\]#,V\F-4+)8?9I#4YN44SQ4R#I;,_TJXA,W$R,Q,.*?V")\
+MTU7ZJ=A0ED^<#N,]FKSUG^)_H'A^`3GV8(Y\]?@I/#'##.IJ:CVGK_H7X_LJ
+M+P*-'RD>;*!A99AX<!-5?(4&YAH`$[S+J[YOU:6J\>I1'!ZN[WZ\G:<^^T?<
+MYQ&]\M2!&O=H\`9H\-X^@>=A2%Q)K+@*.230F_[$L\>99A;SU28V1"0L%;0/
+MQ34AZ6\3##G#BJY\V:M-,NFO=BE.>]4*T[IWERYS,3"%&PL\6'85N82[5KHL
+MS\1KI'N`5<)K[>IN>'K5'[W%-E]H9U4LNTI':3U5,(EQBKH:>9J(0+''K#*Q
+M$D#-AG4(P,6K%D".M58UZRUVW%Y#7N*AN#0]P$X!=M7%`KSJ\+>T`54XU$S4
+MXR+M2=P7/>/H9O^[&7G=#J0,>//57[98(O9,QW2[)YT;4A8GA'WI$_!B,R><
+M9"M=TB_6M3'&<2E5N-*%WW'<.'P;!R^Q=/RRR1(U."Y[$L-X[;8&Y4XUR''.
+MN6BC^$$R+C3+'4+C0L]!CAWPYX._HB:<+5$G1!&_F,YT`CKPN5#=!Q0(3@_0
+MW?3S$!0<1OX+#6D5\=\LZ79,.E`1.3=]_O"MR,#.J*0/$"ASKBJNY`S?*\NK
+M>$[3L4/3](::#0?<T'.5H[:>1@V#1)V&C9^3Z*=!ZV$X1/\/+G@CO*OU-FA>
+M[+ZH[MOL#UW6;K.(!PI1)N`Z$9GL43D7]@.:[1%*B:X$9`_.<1;8J,)N8,OE
+MR")M).G*=UZF74'79=H5Q/;/V7E>VAL.4,3];EW>*C8AC6"I@!/XW#?U_<XC
+MX7T("BH1WH?`U">_96L:^M@.3(6C)PICV2&#XE=9R>WLT8$/=5Q(UU?=3,8%
+MKA$/8P2J,.WK(/!V]>WC^C[O(&$':=KU-.V4QJD^&TGS$[(Q<9UX6*4T5X;W
+MJ90F4=UZ/+(<1,53]9J0)M6A>]VJ`SY)&_^RM@P;RTW@7/VY":[^D7G)>*8R
+M[ABP<3T-!^?YJP/HH@P:]%J]$#Z.;J2K.+]C1$`_*<83`.K@`YE(:0G;?S1G
+MDV-".=LN>4+87-FZW"?D0VZ81O*&,0[_ISCY.=4EV`\\':6P&;^B21\PY>H.
+M*5ZBT23L"2GBJS]`IH<94GWT!";OBAJ7@C4:BT2_Q2>BG?Z!H#F0Y4M''[KI
+M_?EO%/$()LN7"MK5;YHT_;]V'.-ATS>V)3BXQR&6OZ'F9J7"Y,4<!]_`KMZ)
+M:,UZQ.K-@ZSYZA,$QHD^92FJ&:)HL^CI%*L[S8Z'E^(]R>N(]QHC%6C!F>-H
+MOLI?UM=HUY`2TG4P`*$B'Y+)Q7_CFSZ![_!-[\\',=;A/WR96E4[2XK,^RE5
+M+GT_/CUV/[[H*&XE0Y']@7B01E!A(IN=2-(3WH<QZK=O6'0)81QMFRFEHQ;/
+M$V%93(OT`Y1Y8+ZZ\KC6;X7?*PHJU2[4=N@QTF/IK0NG)-J<VQ19N2447JAU
+MO)-OX.Z[A;9<T/WX"9IO]FN1"XW#AG^KV3CLM\V@>ZY=;..AB#^^!3LSP]\/
+M,#4P[[].PBF%=B2^P_@['F=5?370]@UN2EG$*$?MIY?U5"X^@;WT%^Q&W\O2
+M/MR-:[HU@RC"MCV.3)-_+ET8?YABK7AN'\WCNS7!4;L#0:/BA`@OP.?K7\>*
+MXV:L.8/=JLPQY:G+7M?)(2L8)V7:"J%:"%6]%4G"MF\9MB9K/&><QHC`[RU(
+M@XU;8L"W:5HX03`MP.<]PL`%S20\8$,">\<"_>&::L4ZG,D^,O*D7;2Y;#V*
+M&+13@UAE"O.?JKDA'[!`^866ZL77D<08H*X[2FS/DA9:=K53*JQ"OE?=#NGD
+M76>H/B0RL29PDJ(2=+MXF%#A[^[!@EHI/+6>7<.B@1\AL]C8Z?N=!706%:F7
+M!M;AQ[:5J2HZ,>VRC`,;HZ)DDV@I@T-]A4V=^7J4$VDP?1^MGU%*5%;0%G&#
+M7V=WFP[]N]L-ZMBUP#^.Z)<?Q(/'D64W)^$Q3"FGCCF.*\7CA9H0?M,8\>`)
+M3%!SO3=<CV_A^F/8,;C8=-7Z>;Q,8<'%XL%CM&P=I*7O:&`7`2@ZH[$5*G>"
+M)E9'(P(Z5J@O8E_6RLE3?]X<B\K/(9>;<JW]I4PYI'@&KQ<3-S'V/PYC9YW"
+M5M1"2JE=$5NHA-MPNF2X7T^X3S&L^#&)[V`+C2V[CCKVG[KP_K51EV0]]"-^
+M=)@4_9L]YYC7`I4]VO$R&&V:8`Q6"CKR8=-4<"Y?;3U&16O^ZJ<R7^)BV+S.
+M+%V2WDMK<*.K',$6D!?[.Z+^7-\70A]<(S;9,MQ=F_Z!"C1G8O3-C?.D&?'Q
+MV'7K+;F)<G]T*%K@E,SZA9&+IIH$*<L*GXBKZJ$%8@B2*/;ML-,/J.-QLFN&
+M!;*0=MXMA&JND@MM,+_`2@?FD':WC?]`;+!F0\SF#KF@$_W\N*`\JM%M2,\<
+MV"9T2":QT0K@8+8(_CZ0=E[.L>/&YE=X=\86GK)7+6[0Y^ZWLS%RQEY..!?\
+M'U@;W(;S6$$(?8L/)B?.K9%FUI>%3'K<;8\2=PAE>.K]'.FJ-))2`C]*/,@M
+M09:T*?7M$!6<K7DR_8=9OVR%]];GX5DWQLLB_OJFCQ=N\JTWP9)&$5MOH^,[
+M#,^`15YM'$`9AOIH$^-U]OV=U*&MWS!5C,ZXH7&*#S)]PNN9O@26NQS6SW@F
+MJGHU30@[WI:Y23QH1:0W#>3'1!&Z6D.ED)62IU[J%U7R>$4\&**:]U/_:-#M
+M8.BP?I)2%*'?BE5%O=C_>96AA[H3FIR_%'7'N$+`;[_)@)];PX]/!5RN]FBJ
+M&AU>U=F`D@:7AZEJ,"P7]XNJ:M1'L4SI@24SZ*/I3;&5`]L_13`<_6JTA=<J
+MXNL>VF6\@0_U'X=QW,`XMC1%W^C+FD7"$Y?$`7+?78\)U#M?UWDO%0G[#VKI
+M$?";SE^A54VPL[PT/QUC[\CB&H1?'(YH8W5UTPW9_`IJ5:O]N*C^AV'_]PK)
+M.M11I`O/#Y?JD1[-(J>A&3G/Z/W>P:A7+(;$&BGP!@(AA9V_F4C`Z86G)_0\
+M6_OP`)ZRA"1/9T`;)UA^37=JS'*4KSQ\2#\VQKWBCY$[A1!J\R&=#;JGF%'3
+M/24<O$=B=4\QT*![^C#3/7V(^LK@'#K8Z527XFS0*,GM6NN]Z:@=C0<"[O$.
+M/U[EC94^XJ'_-6SG]QI2H=IF<O@+\=28-.D_0TD0]>5L<FQ\%>UC\(ZE5^TX
+M&-F5F.@<FCI4A%5_JX\)CMI/<.6+V:\@/^X.&%3=8N?]>%"#1P9A3Q?%CB3@
+M5^(%3BI2?3A:PB_08'2TDIL:(A)683@S<#G3I+4XLR`?"'23?:%;M2Y.B)/J
+M.["'1&&E&F`Y&*PT//=XD6R^0A:'5SWT*G:(SOO98K7WJH30+Q,NW6M?XF(*
+M>.<UIK/IJ'V,ZR&2$Q*H2'\FD="V!!G8IO$D<$G:>4GLNA_OD2K_DPP3G/LH
+M/Y_NB(9\[@F"$[K\9/2L-UD\:DT['[S>Y^9@6>M.X/OYW"YA,$2[8'\!&QY*
+M$1P*531+;],.:_1RA";L8U8-8LX7TWO>GSF_#R6QE^:$PE)UJ%`1[%ZUZTAT
+M[Y6%9OJ&A_%8]&-#\'@,+K12^)N&\*'Y:NDK-$!*.39RVD?WRQZ$N8W10*MT
+MH[*%*MW(WQX(^-(G"%`!_N8F,R>EP8P(%<:S4[1PD.!+QSJGLSI?HZ<@_S14
+MYW>SM!HW"B^3AT>]QAU1V9+Q;FO</I(M*>*8%72LN`*'L8%YZMT']<T0K\MP
+M>Y%%$`MC'O7/!W2QPZS2!)3$#WE5'R[Q6'=+=5<8*KCNAK#0!;%*?6LA#A@%
+M!RQD_N[;_1:.;CR676:;#AS+VONZCYO_$DX81H0'YZG/OAJ1NNRE88X&/,$+
+M1=V-G_A+:TQ\47?L[W:@<NYN/%#1^K96I_=>CAZJW,]&4!II/7BF@F!D`M8-
+M2'ZX'I_=8(DO1\Y5G/L-YRKZL`Q<@39_@4XXH*YU(%4^W4<)@S_"]0_03$6P
+MZH:7&<W>A%@<6W][0+M:DZC1F@@YZMO(*7">KAL3)6GLOZQY"VZ[?=&<NSQ<
+M#G<[ETOZ?H)F]'%96?GR!ZI6;2SF5B]=OVJUL#H:@E:$4HIRN-6KUO2,N#EM
+M,I=2E%)U(POEN%[T-;:_".TH<[G0UW*[%-&4BU/RN`.&@T:\0T5;31?I"B"5
+MO>J!5_1-_8Z_T[*`S:D%(=9!-II@E-D!(=N'^"[E\DLW#_==RN'';;;5GN++
+M@FNA'UVZG;\IN!J>#_#C-_?W75K!VX/W8?AJ""\(*/(`AA+J@7%'X"\CB/9I
+M%'F@%LYQ3@A'F^Z9%.[0PZV4WLE1?\5Y)N,(NYX*W#"8JO<`L.D!U+,XPLQW
+MVMQ=-4/QV.8&BIZ'XV\7!$M''2^\N^42;G4WIRIB!L5.?-5`,(+RJJ:R@?O&
+M:`!T,N#&.S%/::)2/P$8T(NJ?[\&SNO1B]&`D@G6Y'C5?K#1UJ/^;](#Q95K
+MBLMZ^-'XXUX+&8"V&FT>HE0[XJ*L/@-+UER477F`G?U88=D+RS?7@E"X=W\9
+MW,1>]BCW[:5QZD*3#R\S)!KOPK6%V#Q8.D;]_,7HA39'+9HK+QU32KWEIOVX
+M/W"B$XN%+NE!V"'9SV>.-O-6WYS15NPPEQQ$R%NH^SDQ1&4A[)R*U(<0T%0'
+MI\_5FTSL'#.P@";`D#I_$"HV=6BK@05D#25C,EKKUZQEDVA/4^E&'35Y<H_F
+M<-1B6AQ:0^KE@;@*+FG.GHS\W2%YK<K\#&E^(FYTLD:+K2941_]X`+HKSYX"
+MXU2)V-5/B(/T4TS,1K%=SNV2YJ/[CN`U`<UX'$WU\1AD0QS:I4J(;Q<]-FO8
+M`TQ@(ZLB>-&?(,!"J--4DTA&VW'D5D_927D+ZAA3]44#V<5F,Y,5WX8%S[;)
+M9B#`E/[<^:S15N$:YJSL4<RBOEY/^S4I"T:M:JMO[F@K'@E.,UZC1+.D.P?B
+MLT,]NY<)-H&ET;[$WLCM\=?W,A7<UC[N>%__/#,"(F=>7R)ECG:\W*%DF_+$
+MQ@PI-[00:HO@"@&7TDD(+:6>S=V),'??!)M4M,EA]VW(Y/B4K.YB5*4B#&,]
+M9$JJ9T5(#UZ/AR:93NQ)F4E29J*<.0%[5Z8]UC^D$;^MOV=Z\3,Y?K(\K42L
+MF<QM<@4"TE=RMHW."+*M4E.^>O8%JC'%5W_B54^P;W$S'4.MLZH/V-F2;3,=
+M0ZVSJ<^R%.%U3O47[/5\#C1":GA=HCKH15TQVJ%?Q81>PWP5TJUL3/0@RU6H
+M+H$7RGL5B7.UOH<]21-)Q)PO39RHC?6&2O[R.3I/0LZJ?0S5XS)38/7]**ZY
+M@6!NQ\N%TTN:<Z9#>9=,0B+L'1>J`_HC5^=,:5M.NKGB);-052+G3"GIUQD&
+M-C>M*RXUD8V/3VPL(?`=ACO\D\GHAPUZM]7A3[%HPY'&=O/^@+IN+N"Y*R,U
+MSTF&PJ?$<VU=3(_6MV"JN:V=O9>(FZ<`3!.>)E^R\H,9X`Q^IIPSP9UIYZ>=
+MSYEJ1H*[U,SGF=@*ZKD!6F5(^$&K^I<$PJ4YD^2B6$P<UX:7._14Y;X-H[GJ
+MY"U+1V]&4D*67\5D,0"<A3422K!I2O;J[5=HJ`7@;4)Z;L"E!>ZS<JQR1J*4
+MDRAOML$*IB,X#L9("])L(R.1E&EEF[+!U""U7;2[;OM::Y<-5@V)MKTT8$E=
+M!,A1B[-NGCKG]QI+;I[,">,UB@M#PP\FJL^_$%F+;<3S-RQS60@MO^!(#3FF
+M6_D_X,,LW*$UXXCXF&84TG6`:<;F4UZ@YF-RQ*$]6C!HQ;9CK(0U6.@$&I2(
+MZP%!!SQ&FP2;G)'DFSZ)[P\1CI<S1IN.-IDG93E>SKD^@_R$YJMSH8BV-JRP
+MO-Z:IRY_+E++L'!MH;KHN5B#DMA4M,QN.XKR=V#ET6P0:+*:.4:;X8P5MV"_
+M`N(\"GP27$:ZD,`ZM^KU'(L\)#RO-^Q5NK]/TH_\G5ZHE!H<CR&G(02-;`$,
+MDS!.AW&M(LY?A'3R/,]LID'$ECFCR1C9*-)9.X"&=<3-R1S?[P!>;T62(R>X
+MHU?L8NW_/\,L_10XT5#OM4K696B<M5=B7XB9@YD((CY0(BV<KMUEZS8&_/P9
+MFL!AUS)BRV4?KL6'QDSB[W.:WK:<;J3O^2P<*M!&#G;%_D*"G&/3^%'KF[^D
+MQ9]-W$A#8:557<(D;*P483"Z_9@[VG>$?/OB7$XK+]8T@^6<1,8.!3:<H_BA
+MM'B^BX&4LLAYH9$![;^W1"PNCZ>T$R-I"]7]S^GR#T>AFO8LTWX`(!8:'V/L
+M"TTQWO_^#6-7E+HBAZQ#+O>TL^U7BEAMMSC\+V*7+>@L:<Z:8N4BC)^5W/93
+M-CY6V\U"0K.G!4$&4P/$@[!"2!*[DM"^>:?CY?Q4J:`%V`2VCN+1R_#.QOL6
+M''<TYT*DW1*'!0KWZ3PU!Y8(X<GJWWZG<^9T3,4G4JI!.B9R;J>4F0SE^.9.
+M-6G.:J)3RSDZYX?@R%FNGB07$,L<C63*3T)WD+,ES^D2<0/KL!NHPV92AQU$
+M2>>,EG+/,KS)L;O>;`/EW+.6N<XFTZ1,*?<$5O>UK,D9DN=,Q"]\+X[LPT*[
+M:GT^8B+#4?N"29\Y7,((WV;;1.$*W^;^'/\N\%P*%PYSM^#2E&]V[,^)A]'"
+M1OK%=UFC\M0K,<;M.5V]E*(&]-.6BOP4C1;3(5%_KSKHF<CZI=[*$'G@]Y$N
+M/KWM1?T.`]-[Q\8TX6@E+XP2"8LJL7C.EF3`XH_&').4;2V1"\Z42-[)Z+>'
+M'T<MY<3U8`)4[)PT/YEL:\+W`&0F.2M1RDYLVZ&U/#^H9H)O<YR5OQY^\=(8
+MXP`^7LY.PDNJ2G8&)&>Y@W<1?D3\D1`/$8Z7LW$0S<[(0WTRR[/4%;`\MF8M
+M9?M25)]GJU72I:H94C(;Q_NU\;"TF=)/L(1S6R+KU!`G#)"$#DD(X?8F@"M@
+M7*MVA#U=;3-I.`L@Z5+9$"U6J[B_%U0LIL7"+"=I51@B>T[,=F<ZJRR2!]CC
+M1).9(X=#1<#%)IX)S"J`PQCK7:753/"$*Q/5CY_1)2'7!*?HO6*\/M+^38_E
+MD[3N&<]%1UW8U:<SV=H0ZB__TM+$<<%S`9K8721AZS+5.-CZ>J&*/B4E.BY7
+MBAMBSFR,-B/F/\F,#U;;SV>,MO'QBK`'VTA>-P.^S=B)8?$^QXNKA:3?Z9*8
+M5=$N^3A%W?B,+I<=9AQT#Z#31V;3N^!QJ3`Y.()2AW^C`W(9IM[2)7C)[\\`
+MZ0#YET2KIX$26+Y&#`>6R'%2S@2I$=>R.6,DSVZ(38"9)]6W.6.BD.S;#.MK
+MAYR3$>UC0CPSBG^O/G]ONA+;?[<[;XS0SSU[`G^3G,$BJMO8U',3\#5:,4PX
+M0`XL1P?HV\</(]_R)!^3X@]$Y@"Z,FLPYM!-_^F7VIFGT[TNN?H&)7L,U+.Q
+MU9R'"^LO?T-W.AC9!C3G)-.0.P?P6X!73X`Z@Z`L/,F2,S!))\S7I58O9OWG
+M;P$NI!HL%=B#`^3!<J95RK)!ROG"5[*I.8.9*8Y:)^UA_^&7["9"SBS&H38A
+M3GGH-[0:^_K)B-B$SH@60[_+,>$5`NR1*O]K"Z?GZ:_,NM4S.B1ESRB1:JZG
+M*<HI92<U9R>S16KV5/J%-51SMIW&RVRRI1PU5M'M#.WH'CJ?('^_:VUYZJ0G
+MF3B_`W#Y(N9,(IKG898'AHY^V%$L'CN@D!=>ZU0?!52E;-2'BMB7B^CZ>3$+
+M+$>\:"8,?4W#$#8^*\ET'/:1TMPD.1\5+(/RL!)Q(_#,J![Q66Q/E665CE*2
+MZH]D(7J'T$KNOM+.B^D<CW;OTXV'\W/<7ZXU2V^C8\=T3O@[$8/1PM6?2T_@
+MUJ_GJM9Q0DD5/)960&`"-X&K7,=5/LA5EC,]EL18/1;Y%U$]%E0W"==GE.L'
+M*F+&`]BJMSQ)VJ.[F)5*%!_C?32+E?D:$0]=A>?.F'04W\A>$O@#D'D)*9)^
+M^JO(L<(8U"RKOPW"O>%]6)AZW3,HZ9]5CH7AKT27,_18*\7.+D=I(@OYZC=,
+MD75Q.;OB?LI1^P#>*W]7.9@-8%_!;A9ZAOOZUX[:FZ`N4ET>))1W(5"Y'C,I
+M!^?$I.,'*/*\);H.FYP'K])<6RR2U;^)JG"0+!.W:'GJL%\A=G<8L%ML2$C"
+MEW<HX>>_Q(3WE.LG)F_BKH[5H4V)OH=)SZ?MAV;MGE_!$E+!(<B7?AV#`MX6
+MY_BS3!F#T0^+RT"=F.FC'+73V+P4"V/_=\*836U@3+_U.]//ZY'>^YWI\S0<
+M#Y%N(U*-.C61!?_%PDKH!BN/8,%+3I[ZQ!Z=[M"]N]7QU-.Q^9+T?(X\M62/
+MW@RXZJE'A/1;4K_#*-)I:J9&8`C=:0"\P0"8M"31=RS>"6F/N1,B7@PY_.BD
+M5-Z'$4K=W<A0[QGYTH):-%KL?3UB__%M-'9IC]AF0^R<'K&_-<1F]XC]R;=X
+MY&6LT]-/Q?*U?P+*VPYW,6V?KS&<JH<^"6AZ0S^BI0O4?63!TMIV$N("RM.M
+MQOLHD7'EIL?PP!O'$E1I.,612D-_=<._(_8-XP.LS_>V3_OF9^Q`_V<LWSB\
+M5\QTED86*O68*TR_ZE^?T-<.'TH=N@RH]WGKEQK,["C,X*5N,+$7J/Z^86I'
+M_"55_-)EL>?;M_TL6M^;%/'7Q73`_PP^5.L3R'D9Y?H!_S41(V>E'"W/DE$?
+M"N-5TQ-X$'Y(4\ONPX;#>S^-E(4GZ)2QX>>8,4/K392'L$QW<>E<2E'47Y;1
+M'L;#`*@T7A$7E83(E=6?'\/3'`UM^'X=OTV*>+<67X^->FQTN!X15,1[,1B=
+M":G+H/3>O67Y'F,F],[\`K>39^7JL[%*=G/SP\)92'<'@1Z#I2W32O,\9HE:
+MOQ@]!^I04EF\OF+B\@EK76D3)[O2W.Z;)Z6F39I\DRLU+7WRU/2;;W85+5V[
+MJFB%R[.^PC6:YNH//+B"^NL7'[1]U.H[-\O7F2'8/SC#3/O^]8O@)+'=]D'R
+MZ#ONDDXVMB5N^3@,V_8MC69T[#EHRR?AL,.WY2V.:YV9G_>!%16:M)FZEW.D
+MK-VZBIJ<ZX3=`MHT'9[CNS23G[YY4.TI_CK?I7'\QC8T7^*[=+>C=@2]W,,4
+M>-OR<+.%ATR:L1LR[$Z'3IGT,DGH?[[1[/#?1%\3'?Y^*,%LM#('Q6XAY*A-
+MHA"SH_8S"/'5A"<Y:C%1&][&#@1RM@]'!+H@LW`U^NQ,HDPH18-,?`++@*-:
+M[2GA.H+S6_@HG>15__0XRG$BF.TC>+Y+DX2%F',>))%R.]7?/&[1'2=WXB7P
+M,-[UJZ6TTO'1_\[S%N(->$AXE&GFR@5=F+*!]R"H?N@CX\[L[<.@])9@7H#T
+M0>=@O2EFYD+'D3ATT-S)?*HVDV_"3G^83\ENVX6S'?2BD>AY(P&(#C`L+]ZS
+M8'M<]O2CCMJUER,GCT8;K#9:9VF;<5_ZM7B@?5_$$C$)F4U9:>>WF[-FW,NO
+MA@6O^*E)JNZ:<8_0G_92ENUHK!:VJ>DW"NG;YYIJW^1O\EV\EY\H'C7[+D93
+M)635ODGCW?2`XTB#VV/?=*7C2",\-P]&(00+$_J1/(@*$Q['EHF87;P6K;3V
+MZB\L]CSZZ"X+EW8J+9QV/N"^O&F&,J,:;>`H5I1:<:B8'5(//:8I9H?0ID"^
+M:M]--Q"G2D?1'QH>&"2P`T&/S4JRFY!D?1'/<[.#S]%6+H%V^,C?)C0>V][K
+M..O>A4HZ3CSQLN>IB\/,ZC<ZJ$N4Q78:]TC8^N,GF#:J)F(L5*M_$A4PQK@,
+MZW%>\>Y.**+`27I1@CU?_=?E:"%X:$WPIW:'?W5/^!%]!`/P#3N-^.\T@+83
+MW!]Q;%<?@?O&C_O&.ZK_M!,3L>IK#@%VP:"I73V#024O<_%LCHRM+ENU)AU_
+M8.">R!6O+UZ^M@)'<5?%4GXEN<M!7[$)7`_;E%O:7;%K^Q?JV)&23?ULM[YI
+M'D6N:MK_K5^@IE48K?_QC8:G@*+@LHBE4D13&<YA23_%Q0+3-+:2,4<Y#B*8
+M\K&FNKQCMYZ&F;1OIM4\*Z%3UR:F-5LBPM3NG*M7X\A!ZRYM?3T%-:BF<\)0
+M11Y&96#<J[0$&9[:(-,*)>80+"\<:Y8*P]:'%?MP24'=9>FXV&!F9ZJS\))N
+M4AE-,-(N7+JH'V++T&L^TW*'J><M""MU*N*U+*7ZZDZ:^-JRZ!)-OFX=FY)K
+M8/ZU2P?35#L.HR<5*OQD$\F;_HQQA$I3[5@3Q.'FQ<@-M&I3:Q\S<JQ3/'I9
+MO)3D>`CO[]`UIPEKZ)I3(!':M2[0\V_)HSW#*GH)^T]_Y^"/M1CM5W)I?$77
+M1FCX'I6P4%>KP9J#VLD78(0ARU_J^3J#SL3/:`4]&5LOCJFJ2_.M^F"$5H``
+M"MJ+5@\8^H57$6\F9OOAS_"2W.HZ)$=R<*%(UP#,CD?>1/TU8BI-A_]'/V%7
+M;_?2AD<\3%RFGR<V<RA!"@X)1)QK"7'L4%<\3*S/#]`8UU*G]43EZ=/=%=&U
+M?[?=-HLK*2NOJ-C`\1LJBEUN;G;>C=GS\'=.%K=H\<VI4SG/HEESN$6W+9K#
+ME9<5N69Y;N-R%]V6QRW*G<5IFBS<LO)RGINS:(%[ZM14R)N]B)LR<<H\>.0N
+MFK4`/R9G+9K%>5:M6`E]W5.TBE]5O@9"TS!TT88JOGBUR\MYBRNK(-PU+?(V
+ME>WWA35"57$16Z,6K:IZ`%>IRU*Y96F`,U=9O+I\[=)E9<5<U:K50ME2'E)6
+ME7!5Q=P:GEM3Q:U9SA7Q7-5RKDK@*E=SJ\JXJ@>XY57<RBJ.K^*657%5R[B*
+M]=RR]5S)>JY\/<>OYXK6]_2+G/X(JH<LP<U\[FZYKF@$FG!NE>M6TLLYO%U2
+MT)JO%*CYZJ'=VDE%-=J8J^Z':X65B2:41>]65SR*YQ&[Q4:;E'M6QBO9L+;:
+M+38-=W]9=?-V)T1M6XC:-&-]&VR;8%@K..M+3^='2._E2-5G,]P7JIS;G=N&
+M0P(;16T2/H`G>OLIV"T>3<I7ZNZL"*&O255-P94;AB9#Z#UZJ&,WSC%G(>A^
+M/2A$W#;:WU!SK2R<50XN@XA74-Q(6RQ<^.WVS;G#%$PA7<:S')],R<IBD\6S
+M9+;2=*5NK0[ZMS_1K?%HT5:EX`R4O4%/L)XE8*HV7>A)M.`,I)06CI'>$H^F
+M0M)->M+<GVCUF0"AF_70:7KH%`C]'SWT6E8EJFB]OP*%'A`Z5,>F)EFIZ[R*
+M'#F?5?]!![:[2]B)+?J#+#B=3^G_]F-*GW:*5&M*Y(+3E&XA5*(%2MNFEU;/
+MTJ'#40<Z@5XXP?'"PM1@',G56Z@ZTY6"$Y!%UK/XHEGLE&4Z9)D2A.J?H/0S
+ME(+CD/YA/7T>2_^J<Q"C$V)SG&$S6RDX!DD?C;2[EI26/%K28RSI7*6@`9+N
+MU)->VM6M@@TLW3REX!"D^XF>[E3W=(=8NOE*P0%(]S,]W;/&=%"7`U27/*7@
+M)4CU<SU5;;=4+U&JQ4K!7DBU1T]UWRZ-,UP1SMB+"1_%(Q6EX#E(^Z2>=G+/
+MM,]1V@"'WC?J?EV!/BL*0MOKGH&W;067(>RW+*QK>]WO*.P2A#W'PCJWUSU/
+M8><A[`46UK&][@\4]A6$O<C"VK?7O41A7S1Y`DND=[8TH[7%)L_.I4INNY2[
+M`SKVEJ8]M%?8GKMS6^[GVW*_W);[S;;<B]MRORU4"D*$O+`SP@H#F5GDMI<H
+MCU)HI:LJU/XLD5+P#`1U4M`M.V/)^(SD#?EAX%`*GH(T793FRIWZH>D@V?-4
+MVJD+ZVS;LDW!?H&F;),-O9^'A1V8[DN:D^RI#-;V@CW;<,<R#ON/EN*].KWO
+M)"IU8T9H?0?W4MOBH-M0_0*7/3O%)J?8[/15[USI>#@^C,ZQCA0$2L2C>XAC
+M'MW.&F1?I$%>9@TBO2,VWP.42PUHM/I6*7@\7R=1?EUL51^7AF-1S58H9TK-
+M.P"ZV53H\?Y/\Q;<F>$;YK+NP&.<J%/U'NOM$DG?V\+&%IW,)070D'1(T5>5
+M5XM-5G2GUN8X$I^G'ON1?E@UF!PK2AWCT9J\&0\]"M4/=T1]J6B3%"UOR2Q&
+MS[(_VT8R^M+^BGA^+5N-39!A=697Q'D5[#L9O\V*R*UCWW:9!C6ONOP1TL1#
+M&U^AJ)!.%SN$(.G'VYF$PZ)E/;D]BES,_$\6_BN%-6C$`\U1KEM:N6;5FA7I
+M>#]TYLS>[/\!WB5RM5T\R%=`B#!;/+@>7QQ^/T?J0&284JG?`R5[U<$!%!%A
+M2E*A%5!7<R_BI+X0("L`%;JK=9L&1\@LM4%^-+YU5J&C>RDW5`([5&:"%M=D
+M<AT"1#5(5;-P@G8?\?X.S*<D?SNT#O4?S_:RX)G$S)6L$<K*8L],[GK(PJES
+M`TR-<C@*]4HY=<@.--:O?LV"==_:2V@>M'&"0Q$#Z[$RDW=HIZ1V3LA@;A=^
+M1!'N'9;()1W^>CS+>V<'MHQ7;<:GV:N^1EF3Q,OFFCBO>J?$-.[T8YU8'/=O
+MU>QRX%76,NB#P<&E_;WL-4_U;"=#.M&\^*\P,W_^G/DYU[I<1<55]U<5\P\4
+M;QASTUC7FG+>55%97%6\AB=OI2N+756T#KLV(5;^MQ75P7T;Z,(5$K_?7EH5
+MG]F&B-(.+[:(Y:LJ5A97_J<BNNVM/_#K'5$1_]ZCK#(HJ]3F+527:]1AV]!H
+MN=^O6C'U>L"/];I[8_>RN-[J5;QF>>6&"OZ_H=L`@G^P!_P]#T7@<Y%QP7CG
+MZU2M1;M`@V.KQO&:&5?J6;DA*;=C8<03T$B-?X!K;R=A1AE9$BA!_8<?/!3U
+M43*1>1#O*$2F^TS6,^E"6]SPG][:;<,?G!:0/<[9Z,O4KL9MTY1\[4VS!H>Y
+M0O5I3.X)9:!)^AC_&9K55NI[Y17%:SB4V/+<ZJ5E9>7+8;V.SD%Z^.%[7[1H
+MCM?[2;K7!+0/`\/?IE"X;889)WV<KW:K\[;KUF.NP,\48M%^F&H8'3*)!S?A
+M2(+W$?!%#?F9\F!!BWC4G$_IR6I,A6:Z41B&8#ZD%AN`8-YA.L]AH87*>]Q/
+M]HHN-(9'H@-JZ,WN@A:AGSOW-#]&*^*G?AS-J%B.K?,?(7!#$)Q/6_IO0BZ7
+M,1&@TF1-2)!S6V1"HVE6@HECKU*=#W\+'D=S[V@']15:"\C5CTO5NWTS$_C9
+M`5A6.(X,\K]9W6_;6X[];UUH9#;H%ZI/;J.*-JJ#Z+:77$<VZ(=L7[S]YL;/
+MXL1/3+`S].R6"8[P"H!!Z_%7XI62Q]77'HJZM.!GA#V/!Z>QB%]3Q&Z6<7SU
+MX\`,CX?K$4EU/)5G-QW$+P`G"9@?4/7-A/E@#HJ`J#:X/3%4CABT#*J(=PJ*
+M`@%6SJVL',>1V2:Z<19;NZ$+U3<>,M2.;.SWK%\<8-$4YP),8;OT.-:PQL0)
+M3R!';NLANUJQ!<\;&*\,T!JR130V9+/HT]X,-MX-^L\$P,<`R)06Y3OZ/4T6
+MXCCB[.XN8%"^VK55KTS0T8NO`%N8\@8/R41IO(IR#;(MA>+DU(3&VHE3HB-^
+M[)@J^72]8/YVV80'AK.DYH#CR/!>_$N41K'IP[]$#OJ7F,GJAO<UI,OP!;S8
+MN[^*J_X#/"$N&]T2'"77(.@6!*?Y-(.:9.0?C1/SC/;O-Z,8\T`>S,[''B+;
+MU/-DSX'&UGC)`_N(0Z]9.MQ;I>,7_F5ZJ_&2O?'BR+%O60I>DF"/(30T_A,V
+MH<=B(TWO6H27).$EV?-2U&:64OR,CL;2JJKB2I16N*Y+J;K.5;)T55DQGMC`
+M@T(FN,I6K2EVI11UFU\&;-9]BZ-C8+'!UWTB^,D67&^(N+XPKD^HOJZH_:\:
+MTD2"78!VOT%3MB-;)B3B5SRM>?E`C/BM[`X]&[CM8G4[QUO"'A661/*]9R,D
+MC>%_`%Y*!OFNVF;IY3PN)Q)O[C7^AAJ]CFK;0U'_K&*[+9+$6F/1)R_`%VWY
+ME\+FV99?RIQ3H?65^_QLS85G"7&ZS;).'>$8_S_51`RQR\2C=\X+9_+4P5!K
+MTC_2YQ\\&8X*G[OUU[75M'XB+1"O*OQ/-_VL<*K:'V;?/*]:N:7;,BRV?:+V
+MV497&^VS#>"^RSZ;4&OYS_;9C/5MWF3A'"][['DK37',7M)G6RS=O$3@FIW9
+M8NJF_[*)M)E01=-)]@_&,.;1,&6LI%V<8;<28$U)4D.OROMPZEHBDCW5G"T6
+M;:F-JP`O\9GR]-E_]^*S=_@F:A]F"=]H/SS*#YT_9-JX!7986$@%=@D/)'"S
+MJA38\Q?*"^WA4ZCC%8N:[.G"2SG$%-WH_Q2#5VK!?3+"`1B)!"->M[B@96[7
+M>#.:=Z66-_Y[YHUDG-1[):@"-@0@Q/!R#S]6_]K8([]<D"A[DJ2"1,F3)%8G
+M<XZ=:.FB\1,+():H$\<9/J7W,=1.S$B6?1.@/2.^*2FLF<+P'SJDY`QI$_6T
+M/?@Y*8+:XHW4A)*G`SG'1)QCZXME&%NL)`O09K0@SZEM(DY2FT;@A'DNTO[&
+M]>U7&VC213=>_'S4[2[H,E[^(3MKL(XU"3<#?:2"CMBH3E@_C2"3I-$V`[*@
+M$SC^>E0(U>(Y0[R=Q0NM,JJ[P@ZCEE8K-JF>O=BE^FT547,'W?0?#.C",($O
+MNJ<'"N2ZN6U1^J7!+QX3</'<ZW@?K9KY>^LW.QI>V19)W[9.C]_>>WRA'C^L
+M]_AI>OR,WN.'Z_%/]QY_89,6/[KW^/?T>'?O\2_K\06]Q_]$C_]Y'_77XQ_J
+MH_YZ_,U]U%^/W]I'_?7XW_51_Q]J\</[J+\>O[&/^NOQJ_JHOQY?UT?]]?C7
+M^ZB_'E_31_WU^,U]U%^/7])'_3=J\?E]U%^/S^NC_GK\OC[JK\>_W$?]]?C]
+M?=1?CT_NH_YZ_&_[J+\>_^L^ZK]!BY?ZJ+\>/[V/^NOQOC[JK\>/Z*/^>GQZ
+M'_77XW?V47\]?D(?]=?C7^NC_NNU^+U]U%^/?ZR/^NOQ)_JHOQZ?V4?]]?AG
+M^ZB_'C^WC_KK\5?T47\]_H]]U'^=%C^HC_KK\;5]U%^/W]9'_?7X^7W47X^_
+MO8_ZZ_&E?=1?C^_?1_WU^(-]U'^M%O]J'_77XU_IH_YZ_($^ZJ_'W]A'_?7X
+MI#[JK\>O[:/^>KS01_WU^*-]U%_0XHOZJ+\>?T,?]=?C%_91?SU^9!_UU^.]
+M?=1?CU_01_WU^$E]U%^/'])'_7DM_I=]U%^/O[*/^NOQX_NHOQ[_1!_UU^,;
+M^JB_'O_#/NJOQV_JH_YZ_*@^ZE^EQ0_LH_YZ_`_ZJ+\>?U<?]=?CQ_91?SW^
+MEC[JK\<[^ZB_'N_HH_YZ_'5]U+]2B[?W47\]?D<?]=?C;^JC_GK\-;W&5ZU=
+M+A15W+^\LG@I7YSNJBI?_D`Q[Z)/%+I45)8O*RM>'9O,=:-K^=(U*(E?4<QC
+M#C(^UPU2N<"[RDM<JXM7EU=N2.AI\Z)T-6SQPYIA0+':%A9N+!U<:BXUJS=7
+MH"#2IMV#5D37C_`DYT*YA6L;1H)A,EVBV5?;#<%-GB_-I`_U=3G9N(0=Y!4E
+MS9ZOZ/(A19PJ9Z>WGO8\^GZU7%>+N$$1<PC^3\HUPS6.6IR),=4\+/))CMG?
+MF**N+H]*\]>O?`EMK-]5'M%-XHO1BI3'N=8"FTJQP3(Z),7EJ6Y,D#.!7:*[
+MK=04GDI:2NJC$-Z\=:^V4Y36I8I-+FG=:$7<@>HL.;82V?/5UM82*<>*6[3A
+MA>J9-6@[)7B5(I;^J+LHZ\2:&#,1,?LG2YF%6[D$>(]^L%:5E_5-,:2C2V.1
+M?:)1[_BM!]@F>4.JLLY&=_;MV%*H\V;/$QN=L!=<6,J%IY&9B0GA-/7M-<R\
+M1!(:-(N8E;?RKXN7'#77-L<Q\\+64LXK9R2&6TB8\:O56H.17',.RI%R[;()
+MJBV^1L3A4W4ASD)J1]WO)9]$Y=K#0B?YZT8/"FGJHC7=O*[UHL_Z52F[N5R9
+MJM38]/TTNY0I9]M+N4+"#A#%[:\YOU`]7Z8SU3Q(`-'.<`M>82RPA2OM4HO8
+MX,PC*RSAR@GAR6H+U2C9[0D)5VN"-_$(J\I`?\.F_G1W]DDSR39T3=<8_]^E
+M[.IC`53-*6>DB@VV/$WL$-.NXR/I6"+=JH@SDKJ[//KB*G;&MRZU4-T(=0I/
+M4Q^`!SHT.683-R9SO)T4Z+*2T8>?-;QN@GI;&>K+W0*_A>JT,DO$;F+Q&M3W
+M6KYT^4KHZ/1P+2W#<Z4-+A:%3NH3N-ADY4)9$1W?T3$4#B,4\_U2N8J6\DN_
+M9]*2527E/<_[+ZUD!,M(11LZ![0F4<2"'X=T??+2":KT0/2FH4T1-T%DL!0Y
+M89AV75!ZK_%3:Z&Z%--E6YDVP@!%_!4F1'M)A7EJ/^PY!79E!AKJ`\K=3&G9
+M>,8/AP3G2IEYF!?WZM;N@M<JXI]^3%<[UO^X>_?^O)1U;Z8]0'7$@^1TU]I5
+MR_E5JXD$)>7"FB*N9QR11I.:&Z-[(=Z:XG6NRHKE]R\32DJ**SFNES%A_PHV
+M)LQ)E7)#\BN(OEQH1_.F4P(P`MXF.QH_-DNY7?(PJ27MU(4O&S\Q6PKQ2B$_
+MU#V93Y"'B$?'X`7#K_"GOR*>_`E0[=:`G#U&,LM>5S"?VJ!?:4P;?(Z)KD3C
+M.&GJ9ZO8&(.'ABF*:-_=!\E>A71M*/`(R'CWDFZ0SYD@S7>A;"UO0BE'X/+%
+M1MM"-8YZ4@A=-,3)"Y*D^58Y)Q':2U[@E.9#Y9*E;*>\P(66B7)&2]E)\H(Q
+MTOQDQDKR-J*!J;'5C&[E6+6%+GF!5;8_*LT?(^=8I2D!I-$"FS3ET7".'=XI
+MT32IT&[P#1D[-\XO86/4W%2-R/%:`0]:I0Y6`DP,1'.TM2''N3.MPD(8L]PY
+M2<(<.=OFSDD4,F&T<N<X!3?,E#G),.TX\Z#5U!5E3!DX%Y7UKP:JHPS4*:\=
+M+0D=<D&B-)DQY.T(=^T8:()?`@G)U$H2#C;Y3JDPD4+L4HY3N\5?R,@!:5S,
+MVH%4.)I)/:6<,<:9J9?Q>%DQ&Y:FB0=WD/[)4#H>4,,K4)*Y@YT1J[^%+W=3
+M]4TRA4@S]DI?-K;U0RZLPWT+7@'I$%M'DLZ=U/CG3Z06LN#;U=^ZO9NM/>.8
+M\,\BK6QU#H,_F<%WS]@KW-!LW4L=/J8@\9\C#Z"RL/3EGQN@A&L1?(?AGG4W
+M^T<$'_U,D'&W0O5M!'B4+KNB68=$]UP[/PEFOML#I4YUX(H(<_-!::-5JK2A
+MQ=^Y=ED,8*7-4EV`3F^3.,&FWYP#SG:\G&F%:24)X%]:;50SZFG_<7E$S8/A
+M<RN1B[GR&<]L$L#L2\4%;0&4O9LD,S,!LU"]&;@2\APIZ5:&H8!=R]G%9YC$
+MJYUIIQCB,.H-#;@KK'BYW<;;I*,RGAI^(0V/N8>1&H6R8#EC?[KRU.PYS<Y,
+MSM`4G>7"VUY9HR5/JYPU1O*<TXQ@2+GMR,!S;8JG)2]?SK2'6Y3BXY%S68`?
+M`=^QC,!_#\!XF!4#4K[WA'X&$H6WYWO#LWXO>'G?&UZ_[P6/6\9&;32"K8-D
+MC[/470#@0H*QD/2X(C`B`%Y;:N%*^^'"Y5=AP]K16,;C2[\OSJ;OPCG*`[<O
+M-;K7^<]@S=^'!UQ&_;\EU!=*7731<"&PG%0-+\QTPFF=+[>TN_K%G.O5+R$.
+M5Q0.[Q[DMBM*`.^TY'8IB@NO].0>5[]=1O=?+\'7OHY+="'F$KNDXJ8WA_(L
+M7EC/;9&4<Y?P?H&L8#*YOZ1TP5/TXY?5<:A1Z,?L]Q;@%+`+LUIV=6)*&J3D
+M38$0V18/[T,PA3(7;M$NNK0B,:I/R)ZSDF>O[&G%HWG/.<ES`'VZ>P[)GG;)
+MTT#>68^QS(IG;YZZ;Y6N=CDDKU!]F=G8U/V7-_M#6B6.D$T=?ZOV*=.@!$.6
+M.R!G6=V>O<(X.<OF]KS$SV)YL.7<E;8JL]0D*YC+/=>V-DXB`/(0F,B/BX<)
+M-C\JO`\#88SY@@JW!Z\*%")JFE]I6S`A4*C^S[?,YT&.K9`.@M@:S,&^$^D;
+MTJ&UM-J/R+,`DFRVXZ`?B>LX1`^-LAD213K\3^#=06H<EZQ@R[D5:JD=2R_3
+MY8U+D<L;/<;47]T7,?_FSR$;._8M&USH;L7QT`"K]CV!??_;PHR/S;'BA`*L
+MO=`E'K7X/@G)F1-HRZC,,H_!'0).7IE)L,]@%HT=M9]S!$DV;6UM/.[<VBK%
+MB4U6.=-J_$1#:@[_3RPL9:8M-LYF=OA_J,?98\$X8S\38S^38C]=L7!=')\<
+M?M#E#3^8K-ZVE!G4RG11;4Q-M-"`[]&Q(";$@IC`.6J=:-GSP0D`9DQ;F)DJ
+M$MTFA]^*6Z5,:ZEKH9QA)$@[IL'L&BB\96@R!DB99*)MF[EGNDP;(T=9;W'V
+M6"#.V,]$.2[RG@0+KLB'"[K-ADC##R$K>'9Q0S(G./+4F^XGNDB9R<SD'53(
+MV/KY83+=%JF=<`W$`DV!I#CHXKS+=,B3VEY!`4@DUJN>O)^MYJKM8C.SS68M
+MM<602DBCVX5JL6XNHU8PD1T6L6$";48_U&.$46UW,=M,<4:"C#96<P+98"S9
+MLMG&*HHV;-%.HS`(3<#<?A]*.ZS12A;:M!K&HG05)`ZO(\ND=Q23#E%BVT=L
+MG&$Q7K7K/FTK3][@41>0]%S^<%^D&L]S6C6L5(WX:`5W<AKUL3_@L28*+9A!
+MJP?U_'PEI;"9A55,I(&QBR*QBPFRDT)OB83>2J&)%'I#)'0,A291:&,D=`B%
+MCJ;0WT&H9B>MNPIX3_O/=^G^T,1TLV-G@V-_ETCWMV%I^(E)*@BQVZDV=6*1
+M7M1-M'+KSY:$MP8"?M1Q&28>=<*R.%R/^DJEB23V^N&]NK@%?0$D4CJA*_@+
+M7.M/%9N<P5V![F:4;V."OLKB%:O0C;"KJK@2MI;%#.\)!KQ_=B?II2?"JH)4
+MN%`X]QC,JBN14>@'+S/(=7OQZH)<]QP^2LTK]VPU<5ZU=#G;\HV&'<T:4CDG
+MWLL]AW>"<U7'RV&INEV&G5G=`51M$%_"W'EXE2E<CXH1>/5+JZG)*P]&OZ@N
+MTBOR6KVP00F?PKL2U7?C1N],T*'49?PZA&YO?G@/VUD?-]Q/,-:IZ0Y:(QBK
+M='S9]ZS23Y9%JW0?+"U8?2(FV]II[OQ>-3+K-8JIS0MWL=IH=B2T*G`KBOG[
+M5V]86E1465Q5I<MSNX>N*E_.E[G&0*AKU1IHU9*ERXM=R\O7E*Q:(522X'=L
+MKUDXKE<?TK\HM)`Z6:E9W7`7KGU.ZZ9JJA,5L>,W*%Z=?A>JW:NKX`%K"?0T
+M1*:`M!O!J,ZD4&C>RM&K;`V:!]V#=^D7^3(4,>X9A--Q)\&Y%N'(64YFWSDK
+M$49[.2L)1G8Y*QG&\`-HKP+EIYGFMB=H_)!WD<MA!<N0%'0?A#X5_H?BE,/D
+M9^C=T"NX^OOZ:86\">6M'+S*I6'"W.VJXQD^,GT!5L,4T4U8W<6PDN\D6?MY
+MNDIJ0G/=@\V.V@+@'<?^+*?8T,';3$?',N=%1UTBO;0*/JVV']R!FET-L1=%
+MR3Y%Q:J*XHF+F'F*B5.8B8JIDU+A_YM=J9/3ITQ+GY+J*GU@I6:?HNW)NS29
+M_SC.(/.7YXVV2B9IH15/"CDC_)+RR@?^&_BWZ?#-1OCB)32\:8`=@;]@[7\N
+MX:9IAA+N/)!E@!P/D(61P>LB##>Q`'B_CA3ES7?32B[\,14<_IC*J^(K*Y>O
+MK-0+[&[1PYT.+S$6/0*!1?+BT;;M\T;;TQH"VZ^:_E?!++5DU?Y-^/KN6(TM
+M@E^Y:DU1\?J^P:=.[0[^OX,/^)?PJU87ZR9)@&(W=:/8S:GIDZ<:*)8Q9M38
+M:+;^TR;>-+U[V,T3I[C&9!57/E!<5KQAK.NF26E3)DUW<RE+72G+7"G%KI0[
+M7"EWN5+NY/)RN<S<V/`[N935DU**)J5LX%)FIZ?DIJ<LXA8MY87*HJ4;N.S*
+M5?A8O%*HK,*7PN*B-<7TMEA@S]SR-?A8)+#'4A[S8`9,BZDP!49SLXJ7%Z]>
+M5ES)S2]?RUX6+.?+\;FHN()G(9G""J&*Y^8*91O@9TTQEUE1N:J,RUT*C<YE
+M%R^K%)960LS2-?0$B`@,X2`,S(U9,2=DV8"9,2MFQ#SDD;>[7.-P/IN4JQ/5
+M]V#.L`@VG$\+F:O+.$6<_'L<!5!#QPU]O(GCQGMLS&<-DW#,Y%)2)Q=Q*?B7
+M>E,1E\"HR*7,8;1TI51P_;D4B"V^,679C4CNU"E%O:X/)N<SF5(N"M_H@L))
+M&\DY;;[I*0[_,S;T9&B#.,>1R>+E#8Z'?FQCU_SK$Y]GU_P#UCP+5S3G_QM_
+M._\?P0TML'`[X"\9_EZ:;^'L^=&X"OB^8WYL>CZ7/8WISLZ#O/"W`_Y6PI\5
+M_NRWP]`XU\)U0/SI[RC_&)2[&/Y:H9P]\+?-4!Z&XY.#L'-0[@GXNP?^,C0<
+M4K7G<2CO<?A;#W]CX,\%93\#91?!WW3X"^?:VG:3YG+B0G%S4MRZZ\2#LQ_D
+MR#>[O+N";!HK\B%<?^0DR?.V;*+OK<#+"]M&_1?YEACR!?OI^9P#OBN?$_*E
+M&O+5?^]\]BUD=U7+]T,MGR)NPSXH%R9N.5H63Q+A`R/]P847/I-.-EXD`:ZG
+MJ[%KI/36V*/YZK.0JVTM&@;`O(5Z<0E:<00?RPO_80]N07+Z:?>1(*TBSGD.
+M"FJ[*1JFE1U>9U<7(N"K(S@I>K@;P_O%XHH[IFLQ_'-K;!T6V`[\[MEGQUUH
+MD]X]>5D2NJ3C@/C8)GA3$M<J5CI6DMX>VR070$"^%N!N%/H=P2,JKWH"X+7M
+MMAKP>Y3@YB1GY*DO8.0/K6Q/9<#1IN["F*4Z+G48GO]_C0LZS6RS6WO2RJJF
+M8-27EMBZYS@!1Y2;M+UGB>+X8XAK>\2BM1?L00?4],TCTC.X#[H.[Z&Q%`.T
+M%,P6(TOS%$0L;+LE4@:TZVY$H.UNB[&MGZ"P'$L/_*>IL"OGVB;K.!6J/\;O
+M+\WZMR+F$Y\,,.9]%NO1K*=1ZK81C7.2Q(:+<F'RV*/(M76CY_P(N=:22\0V
+M`V4;+XT<VY*G=D+&M@:S`=YSC%^2_&\*_5[!J^L+5;0-V?88)9+7)8M-"="#
+M.=Z5+76,STF2/"$&?W5(>M<BA*0.*B`4O$ILN@1MRB*_P+@N+0X+EYK&OBO4
+M`)X94M-X`'JY'[\4MC4KY'6)6YJPMUUH0E&Y,(9UN2\:+_7#W".I0L`6>-9M
+M;5$2_<0<[PJC(^GB>TG7V&IU-PD)1U#AF-DT1W>4!N)[5?1HUH8.^'1:OT#M
+M]`M3]W:2%R2+C?%$@FLSI;?&%R;!#MI`XI!&XA#:RA,;+Z'K&8IMZ]X`4N/8
+MD\Q^<=LM)AV=YQ@O)ZEW8GB*%OY=X\EN'$\N<%$>^XZTCV/:/W(]ZY2XI1&I
+MSJ@(/;/Q<C^]:TI?C3VJ6/.5Q*-:7QS;N%!%U<.VA[AH?SK`^EIB/P23IZ)J
+M:;`T(&X>`WA@BO"Z,<'1P#\N\;)IG1-#9!$U)<)3]@;M&HRMM.;!O2J=(`5O
+M_8_U>8[#.XL78#O5B`Z8![IS$_GAL%+9/F3;X$Q<M.`:AG/X4S')\6[G=L9S
+MZ(ES<`V42)>[['0+UPU38B$YM,/5FWZPFE(674---^3_8C;LM*J/RX(M],H`
+MMN7S'(>ZP-R>IXC?[B?S@P#U[_/P@I635%4&$-Q#AK,^KW:'1'"ZOZK".[C;
+M3=O,F;4-?+\L]U>57TDM9-1OWFWW+YZ3Z^%NX_(6+)IS!Y=2-8G^U_?2Z[OY
+M?YZ-]Q^)A!S=DE`.2B^'PJ_@3DNSN+G,K$7(&!$7C9ACYC3_[_>;R7P\+0\7
+MX;NX$T\0_;N9L<LU>?GJA=MUL=\2>=]N,NZ)[27M"N!^]^261CS]=+_E$-O0
+M3)2RLZ=#7V4;[G+?EED.=$W',LM^3.P^6OE.V^^I0\8:T7KGPGM*W9:7R7*(
+M3:Y#4QOAR4K=HQC"[`-KUE/_,@_%"EY5F(<RA<=)IN!"QUA;4/*R:P]:ULI3
+M7\N-V`&^#X61AW$OS6T>ZO`OH,\6,CNZ-0MK<=%"._]FH@;^$P_O)H--@Y2Z
+MLF2H[B[\%`8L5+?,8=[)'`O#1!SUS#PJ1FJ4E-V:\.!?-"K9%JK'8*W%:&BZ
+M+%VP4)'A?2W,XC#BK;X/K?I3R;^-1`D[J":)\B[\=),+9H>?9)9^C'*3^,3A
+M1]F$EOWUV;KABPK?YG""4&ILJRU'J:7HO>HF]V5^GNRG%DGUW9K`XYR7#2_"
+M);SF*5*,5:E#!F-9*O\D4ZVE.B0*8ST4)*8UD#Z+5GTWPT##YR;L/T0QEDLY
+MB.@H]=C-0Z],H!ZEV;W:U,WN58^^O,Q#LG&?^Q;!FBGAP;&]AS]R">:%W!!I
+M@"U9$'5`N`#OVSMJR[!IWS-D>OO"NU+';#FWRWW<\3]H]%WVV+=SV\QACSVK
+MML%1^P-V3+.]_[8$"GI3^++M!A.GV0N34]/":(LD(2`V67/0^L@%\>`\&M/&
+MR?680C=-%IZJ-D+32W&L'^6RTSHFR&X6YVF$C!@RNS$GJBQX6K=9YM6-E*EQ
+MLW6+95(J66LC9+CF60?(3XU4'6(]FA_@2[^%C\N"5^&;\7B!JQ/GS5E.<Y[Z
+M5C86@>?V,N4V2:@D`D,&JBQ\!>,5J[.M]DU^&/I<O(5W9,&HRXACJVT0VIO,
+MMV3%T(9W!F+()WR)VUHU5N<AVIQUM]'Y:(!YLWM1[YS\>*T^N2$E4<&T%B=:
+M*C=#U&D8.;1WH3/8!/,%[IHUCB'X=QCWO[<Q8^]'+<)PV'\_8Q&<8I=5MVLI
+M><X&XYL]9YG3:3HN%JOM<8Z',#MDLQ20SPF/W?&"QRDU6G)M.,1]BAN&W--R
+M@4I>G6WNHXZM>_1YMUW.;1^?ZUQ(OC<2PZ<D3P-9(SWA;ZBI07-<B$<[NATX
+M+@_&HU78F!^7!@?ST%:7:?,X0+)1-4N>8[+0#FNR8=`H>*0D#18;K>'<8V+U
+M,6YS&RY7`^B4NH`E"VP?!K-)7#9.C%J:SP'06"BHP.8N:'<\M!R/XCU.DT>5
+M"TZ["U3'_]R"W)<<3^Q^4L4*6O`FH0H$B'=LG4,ZA_`-$.QS'2\4.$VPZCH'
+MD6,<6Y]A1T*-JH7HXFF%)C0!']F4Q"Q`"84=LH?.5@%`@[^A.C4L'/,2.?2@
+M31@4FP[X#9).EW./!6_JD;ZFG_0E++IZR70,,EGH$`!05<<7M!)15(O0&A;4
+M_&YXH)VP;GA`T+$>`*=!:3<!77NDK^DGYZK!I&Z9I"\9$L>D7$C>:CHE%33(
+MGG-C6Z@=SXT76KUY,6"J)X>%<]X8Y#9A$(*-IF.XI,NYYX(W(V]URQ&A28]L
+MYR+HG",G(.VQ9+B9LG0C!`MLCR%%.R2>B<6G$V_WR%03C]2X6HN+S:OAT`XD
+M(;9/1OV,(5+!<;SB3FZ"S#)]2,[@(N+]B0;>AQZC!KX?_V/27OG?9D'F["+M
+M6\;#%AS_.F@(['1[NAP/V<A#)*P+NUAGU<Z+'\$EKL,O<A'M%ZK"U:CX1SVW
+MH$L>`A_0>>E#,@<7![0Z%#@;/S,38B&84_Y3'1!#+6EO=8!N!Z,S]MLN<A7?
+MY=B:2SV9H3^'[6D`_\X8_'?TB7^GAG\'XM^IX=_1._Z=<F[']\0?D_:._U@H
+M"D>BSM[PEW3,1A!%D3DX(B=Q!J`7+`@$>O`&6FS^GKR!27O!2R,*(RS@UM9.
+M?IS/`,T^^ZZ1_W-<.^2V(/S_CX[]+=&QW\5&\<C(?PYX<'QN")AQO&!SOUUC
+MEM[VGZ^9!Z%COR3\KF_\PBP)V./ZQ.T:P$=+TBM>N1WC<Z'SG1OOZ9":QL-6
+MZ,LJ5DPN#!A:,3?HQ73U38-(.5V]ER-TC1=";L%9=27L,F%/QO1@V0']F0OD
+M/D$6.L8+G9CF*ARJ.R2@`4LE>>QMQR\PWQ7%C\><;\?8OT]',_7,"%)J5G=+
+M#Y'TAL7(T^EDY0%M@H7I3/U>=XVM*E/JLF3;Z$*JE&W##ZOV8<4UHY(1L7L!
+M7Q_-@`T?F8UGED-&`!WBY#C(,S[;5DBVHF=!AK$UMACS+#W6T5<!*BNQ%/6-
+M&7A_II/=.<EK]G3Y:-0(X8.Y>\M[`ZW2<>2Y=O@LMBI-1.=U^F9W[DR\ZN)5
+MC]["%`;"U0[T@7[3#,V>;?`FL;J3X[^&KCT>A[-.=`@(J]#QGE`&>4O_[4QF
+M.LZ$QABPXYL0^^[.=UD]=#L)8OL]A5']/[>%*VGVO&1EBY9G),\!-+=GBYK;
+M(U\`DN>0Y'E.$?<TA<*2YX2VY-..UQ6/DWP$>9[)4RMN1:(\)7N>0@[HMA^)
+ML?\UG?DLW3R&$X:Q0\9F\]5Z\[3AF20T]_GL@4[A!F9K+[PV6?:.P<$!)R*Q
+MNB,L)`-YPL(P1JM2NG61AZJ)ZQ9+,+)6V\[GV*W\!+G0*KU+9JW&"AU75G=2
+ML:D</U4NG!$3@;(8RF3CKT)GJE?(PP&'\5ZGELHD=`R&[)Z.J`V%WOC[PC2+
+M3A-D\7MOZ87%8^RU-$VC.Q-;IA=_Q7%"L5R!?N#NVW*KYQ0Z'V?NM!COBC7D
+MH'"M576D,U-\-4X*<*J7W5I`(@4DJI_K`3,H8(9ZE@5XU3^[+5QO1E^XCMO8
+MLS53^X9G*]#V7YD]VF\(X/Q7C^VO7YSY*WIF\/##%+GA>"C\@4D+N'S"%\JH
+M&OK!&6J=5ZE591KP%?DX2]BFR"WT]N'%OU:CL[*7[+#L^.OJKH^J._ZZ.H3S
+MZWMIYPN]'TU`WPT?MD4*$P8L4.0S+&NC_G;F),7Y0B:A7\Z';4'S!V=BH8KM
+MMH]FC+[KSK^B5%;JD"[U:,;_IOY3+=P'5/^3T?J_27B\'UO_&`K@Q`WU9PD_
+M@_J_^?WK_UE,[=^,U/[-;K6/Q]I;`X'_IO[S,N?G<+=Q\^<MBAJRKUJYM+)X
+MTIJRJDDI\R:ES)^X?"F?WCUB/L2Q0+S>4M9WGA[1F%.3S6V*E<V]/`7MES^N
+M6YPG2=M)CK95*+>L?0,'6+*+_Y4[HIN%PQ?E4?PHL<K31"A+<)#VUT:-TW],
+M'O7:4#]:$1O>0MEJR&W19':Z;7SQ#8A@08K83(G><T>OQ,0I=>]`8.J;TGO;
+MCALE=5B.]/9\Z7A&GD1B)W7/5(1-4CV2":'.'L5`.2/94'<OZ1J23(K5H&T(
+MDZ_GA_=A1O4$#@\$H\D:E]XT*]7$R;MVLBH103Y!IO*3B@^!P74.E>:;GN[P
+MOP"Q3;JX#P4;&P,HDT@15O@VFN8)5V<QV9-7P_@^+(WD=3A'0I+YPM0L(+8>
+M?^LT&KAC1918<84?A!BQZ@4=@4!37$HP'M=99EAED!Q%:HKC(NV#F*H-Z1%U
+MPHNH14RRLJRPGPDX61U@<7DC%L6H,>QF&L728!?%PR)"C6/?XF%B&$?M2+PW
+M@C;YJ?W14);R]'JCCZ/8<_ZYD\D.)<=?B^;Z:D9$;#'99^,R,,M6`ZM8N=H.
+MFS5@FX=Q`,/]V$98)C2J(TU=4N/)B[C>L4J-K1:4"=DLE7;8-KF'\8NJKU86
+MHBHA`!L?I\RRF=S-L#AL)B<=05M`>H=TO-W5H>JGI$LPP4L%7>B\.M[T9?`%
+MVB-@$19/U\DNQPM-IL;@SV!-7S.:X_N3EN&#5F85KSUFK0)UH^J,(W>VHSFA
+MCWJY:NRL7E>B[Y5-5"=7;)VDXXVM>"_6DD45<O+>:I=6H0+[>*?4TKU*_0/&
+M.CWS?>ND.TB)F1-?3$4!5R);*6%UL\COC"U/O8*$;.C71,ZSHA\3@V_`V+9=
+MDTHR+$`8.FU_;96`>X"0F&YB?GY;)C-N"D.@>Z.M9JIN$@LWMB%H2B2X,!3G
+MTY]#TO!:N[J+LMA$3]>8')9K\TEXABOMZD9,(H34RLE,X9$U36YQ5=72%<6N
+MVY;R2\O*5[B8(P`NI0KO!U96"A4\V=F;F,"-6[-TXPJA;!S%I52Y5E6YUFHN
+M`E**)KC6X>W!XB)XA[1:DI5+J^`;3<-67<L"UY2[5I=7%FM7PB<F]-2W]$[2
+M[R>5)JF7T\BSDS;TL2%I`#O7S#TKI95RA>K=4W#LP\^%Y.S[5+4-^L(_<92"
+MI9DY7WT?^B"[X0&)T`'YPC3-\*K+X4=EYU*;4I?=0LJ@@V[6E`T=_@P\.:A6
+M3?R-I::PH!8J=<F81JE;@`^Y#N6Y3.R>KRY(0Y*V/4A9.KG-$V'Y&\U0V3/#
+M-2Q#!AM+T5,MXF^#%R7Q1VAQ3+6FX>+YK)1I9Y4?'P'W4$]P[Z1J:_*V+V@,
+MR.U"228:J3V3%F[[`X;ACN9,6#BMT>#&Z4C8TU+!&5C:B]6GP^A0]4R8SU42
+M7X/RI7?1W_"#]M(Q7DP],E6SCCY&F$"=O-^"X$)J`]%M$C*\"]4M'*>+Y#=/
+M$R^%';7S4/2OXWQ33YQ'I)*#H`R\5Y(]FJRTS;<BVO-M@'8.P'9OL#D>F841
+MK!QR.']H$M&E.=-*63QGHVJO/?=#"3?BZ1$J;7F3\F5O8CY=&+>JDZ9A[;N@
+M[U'MT:JT6!T*,UU02`ZK>56<1!9JO8GL,MYR4KA/SH<U-ZYP!T[2;E#:W9G)
+MPGRM$"<48M<+>6MJ]T+BL!#^6DKJ:OS$"GR`A63;C?P=O`O'O(*T<#!=N@2)
+M(+7%:R]U:F!A=Z$&)K+"8:/1Y11.BAOM'&]9$.R/@-<FFBJM.8C7!M?F(Q`"
+MQ$5J=+L2'_,/=?JJ.$VKNVKBL@T5Y96\\9ML.Z1,'%>5T*N?SR?'XZD%GEZ%
+M4V413[=+9&YK:PJND?(4T74:UBCL5(_6`7EJ&,<^2JCYF*?,[%VI:TDF2^7B
+M07SAA,'YZ@MIVMF7P_\H+2?(-PYYD<G3'8QVT`>M(WKQ%J>(UR,6X7J$J<9/
+MTLP40,/.%2]9A5N9VT+F^:77[%,-V8]/C#HW3$)3A=!@-]$Y68B`=-'2+#M2
+M;9PA[%!E%J]^.4&W4!#U;Z@?!S/ZVF+I>]LXM`5)9-%IDJ<^EAJAR7,1$B+]
+M]]!3$9_\2X3LVF'J-NP[%-\+V8FFNM^DU`;I@M'C40\2O'$CECX!N';R=]5Z
+MV*1(K?\]7JLUZ40^W6XX$^QY_V%L]PHGYJG/3M(=40.]Z81-/'B((@N5^M.4
+M%G_)Y#2^J-)XRJ`;CU#$O`?QL"VV(J<G,(,>2?XP[&9%!$A(WHWKICJ$(Q.T
+M;E#RP_7X[`9LLP;,Y57MXS53(OQ@!A7_`9^,(YEB*"QT=:?59S>R^?G4N(@!
+MBW:C8TB]/\;NYV\8@[81&X@.(Q3QM??H-GPC/E1U/%Z?QKC@@'`]/M5OJ:NB
+M4@FL/?H[>_'_>$,$'OI_I$P-XU$?H4&K!,NN<1#F'Y6`'H(G3.HF%U,($E6=
+MOUJI7XSD4@=?UC8R?()TH0U9,8`Z6@Q_5S?\QT3PUYQR,WP83VL`0^,8R>W0
+M?L@7D]&)X<SQPFQ8?7/C=8Y)9VPO3N?X!*^Z&WH#ZOJP(0@#^WO54;@QB`]X
+MU37?:B@Z:E'&ZILYBG]($>\_`Q@5JL(XS1,AGJBNAFC8-$@'[Q!PP[:,)<G7
+M,+*A&9FYF"0>*IGCF^GB+_EF]N>_4<1BEG*,$9B+`<LN5*\<1VAK`Z@D+@'H
+M4GT1E;$2W\5[\+<Y>&V`^3*\V7>KB[_1=VM_?HPB=D"<N[FJGS1-;+9J2'G5
+MPV,C1?%Q6(S0Q-R<*"(A'V/S66.XBLIROGQY>9D^+D7OOZ9@RY[5>2[U?6JS
+MR?A0>2Q(/*OQW%GJAV.1YY[JF^>61^$ASU&F>6.1Y\Y&>.ZIWGB.Z^4NYC`#
+M<JYNR+TW1D<NPE!G(PPE=@IX0O^[,5&&0E_4[S$>138XJ8A_?I]:;LV8*#D/
+M$@MT;4`0[[+H!8;HQR&:Z5]@^]]*[4_)O.J8,1%.X:W`)3E>]6K"D-N(P*P;
+ML:U#&SAM;Q_FLZ3+V-X_0%@W(:R)BK@#4KF/0GNC\HT.&CTROG6#[C03MAAZ
+MJS>@XB$")WRUFV@H5;E_WH+;,N=YC,(5DHH4H[>.>;?=?]N">?,R%WNX2GV.
+MXKK=_QG%ENUB!C44CE_(_Q-Q27PP@'8[T5B'ZRSU:^(1#(S(-"9`!`L*U^.O
+M/F6MO@%G@EO/$KTR@#B%7M4]!L,R6-@$'/^.04//8]^=UT=(+XQJ>X$:SZM>
+MOAY9,"/"0]"N/V7MZBTUK43O,.%Z*QIS^F8T";O%+I-0$8VR8]3[T:@"BD(M
+M^WK<N*JO1:/2,:HE'J.0".I3T:B1T2@;1DF1*$?MG6&L;>'U$5]QG9'Y\?[[
+MH0^B2[7[JX1E5?PJ7N"+N9ZVM*ZYSJ+;!-:VB:EOHJS<*`-Z:RXL']/.TQY<
+MT[03ABCBX0^P5:Y!I='?<TR&X-@_1"KH4*P_`B!U6'UE1E8,J-P.U/9=G!"&
+M/;2[(+0Y!V@))'>6FE#2#Q.E^BI4+^B`1:H)]I]"R*O^](9HTS@5\0B66IJC
+M?L+NFWJZW)Y0S2%CV5K)UJR\L,?F53.OMS`7HZ33YO?B5KM#MRO2XV[_H&M1
+M;FUGK"@7)#+&ESU.;131R@E1.=CVOAE9G*.6ID9J'_*0B_I=@6X+PK?FYGN!
+M>([]Z/]'2?3)(F97$O/RU;>O)Z=`S,R/4VQ*1`O[#6V_9;PF9]OQB,\LKW7B
+M$8`G44HEH4V/!2>9G8*MA&:6!5*WDUF6X/*`3&R%H\#$WO#"A<0<(Q)/:DC\
+MF6$LUR&'R(E'&6@B@BQ2V.(6*Z+DU"T?&/B.KRP2*F+G@!=&,M_+G:,C_IA@
+M+=3*FM2AU1=':LWY4D_Y!P"0#Y(UC)FHUR3>@Z]TFM%]^9U?:E9W7DM^F.JK
+MH0CT_5Q[+1E8,NI\11.ON):<-)6:,>5=U[)UU8LIM*'K`_Z4:\E9TT$?P"^$
+M[]$$8@Q6\15X[>X?(%*-WUS#;%2(:-E;RAHCBTYZF<`<+@"-Q09.-XJO.9V)
+M72<57\-,<PA.\LDQ;+NI0;4ZCK0H8@A7G]:`VV.O<N(2`4>SMF>T-5.7F9^T
+M>2#:X4]L>T0/L_"WM;'[C##B]U,VF*1;'?M-;5M8_/9,4PHB<XL/A^-[61*S
+M=.MVD]@ZLK$U;OM"$^W'8]/=O#W3;/B\GF6S1++9(9OXR<S&3^+ZMVQ?:(;7
+M_BW!(9#*DBD-TMU.R!FI,;[3O1';Z[*0>/Z-+OYVJ-#:R;`?<Z$*LWVTP]ZZ
+MS8RO<:-GVGW;LDS;CK,7,T!.%(]:I&'!@33F\'':T2E2F'Q^7&CTP2C+SP#B
+MK!T%(!,9G)'VAFUF'8P),@X6CYH!3((!!@X2P>L1+O1?R&K>AK'.+$@VP%@6
+M#2JZO^Y\84UQ[M(5JSA];D1"&5I83&;V0CQ[\ARO90_*4QVC=,'RCCT6E!F=
+M)F75G?"^I;IED9WC'%L?HDL1+>J_K]%\PM"*]$$++GJGN2R<%\52+>BT)?,:
+M"^V781[QXXTA<E-3*UVTY+:@F\S<VBV-BP&D],@\.R)=JXA+_AX*OXK"&*E9
+M.DF*P_R`L%#;-HC=4X`L<F9JY+Y_JKPESXY7:=DW?<A;IAB#IE#0#&/0#`J:
+M90S"CV8/[CEACJG>B<7,>F6*'@VO<NTK>*U8#V%?&&B+"82O'*EZYQ8Z@ZG9
+M)V_!BDE;ID?P:FRU6NA3HBBY>K?[%7QQ/#26C#+42ELR(AA3XHS>$H=,6N+9
+MD;J@T#FWUD(A/=*?,$7J)^?NE*MKW8\@-HZ'/Z))>1N+J)7_0)A6;Y.MM^JU
+MLMXJS[HU8F(!7J5+IJ\@*&+`(PMU!=;*\VZUCD^0<@.94JX/"I`?(A1RMTFS
+M!L'<XM/T_2WP)6E1N]V/,.QP*297!Z1JG_]4S33,D[L#?1KM@&+L,H!+W+;U
+MJ\:WG%N_DA*WR1[?'"C"W[#YP^``0+49TB!DT;/-&?;LC*G>(V/0&$QLO9&P
+M-;=KO/0'(G;!3I1F68=%JCQ,GC4L6N5A5OBT13]M6$SU3O<K"&KS@6[P9\7`
+MG_U_`W\6P4<XU)X6XF^W9W>5'3O7K!$DIKP;2A5?PQA.2&@FTFJM*;XR10LE
+MCJ-03#M#3YMA3#M+3SM;#_74*D_SX1@%Z1C_+TDTO_3BWR<=NOWY8_T<NQK0
+M$9,^T)Z?%;BYGZX)VXO?BPO#>X5GSU<_N]K"-:HV&%6-OH+$5I,^9UV`!2->
+M8]_)@,?:K/Q%GW!_1'`'!QU&N%-/JCKD6/P*^X0SE^#TCX5S<U]P'+W"$9)D
+M$7U`B`U3(+.I435#[F"_`-I/Z+DO_>.POG`YDHRX#$#_7C%^E2P19(QPQ#[A
+MK"4X]AYPK+W"^4&?<"82G"&Q<*:RZO6$\_45?<'YYPB$,[`'/OUZA?.[/N$\
+M07`&]8`3URN<Y7W"\1(<1P\X\;W"&=$K'"'1V.;4X-:8]D9W1JV;N\%Z)[%7
+MG&SYZB=7T;Y&7]C4!FB2TOI()/\C?>;_68_\-BY6!X?I<QCDOXFT?O"JS4".
+MTA;'RW%Y?[..QG/E=ML'R:/5E3`2?'!O5VFKX^5L<VQ4+D5UE'9`E#4V:C)&
+M>;K.>CH^;*2#@5A]**._T:-#<:U^&A<,U5V.EZ?AON%EV#QU2B<=+[PMBRT0
+MXWB9,S662+FAQC8G[#L=+V\V2]4=$IZDPD[1\7*^&54OJSL=+UPR=9D:\?S6
+MN:48_=5S_3V4"8%F61TO=,C5JN.%Z@[39<J(09Y.4U,)7FFHMI5(PV5(KSI+
+MI!QSB>GM$FF=M9N;46,[Q`]E+@WUD]J=5_54>!*J*B?C3QJW:DU).;=NU9KE
+M*[F*RO(2;BV_M*QR-;>^I&HCMWYYA<"M*N=XOER`GU5KN.4KRXJXY>5K>(ZO
+MXBNX*KZ\@A,J5W!\,>2AC&BT@ZO:@(<K*]9RRX0J[H%5965<"806K^:YI<LJ
+M(6_ET@H.0Q\45O&``<^MA,W6HE4KUBPM<Z5R!57%E:ZBXI)5:XJ+7%4L='*O
+MH6G<'$"_<C6SVEU9_*!07,5SA:O6%)6O@S0;BUW+5RY=LZ*XBLN#NJTJ6[5F
+MA0O-0E2ZBM=7K*HL+N*\JRIY`2#%AF:O*BNF[&6K5J_B(7AY<7$1A-]6(6#"
+M[L%S)BUP59175:U"=_"+@"85@.(8GM^`YL`AR]C8P%5K*.RVE:O*B@#(*G0=
+M?QO0=-4:`=X6"545Q6N*C&^N,:R^8[F"RA7H`A0+A%;0'-HO!N*O6D,>Z#/+
+MEE:N=BTO*U_^`)=56?Y`\1JRHL)E+2W2'(:ZEB\%PB\J7K$:`#&ZE2P5RG@N
+M2ZAR%5=6EE=RMT/3(!'*RB$>*%91#DU$M:V@\CRYBUW4A)G+RBMY]KJX<NGR
+MXDE9>5K,'("P`LBZ:@WLI(7EE&TA-O8<-+R#9^S<;&@80;N0QDW2]Q&[8_<1
+M/W"22(/$-[<U^S>%F1(2[KV-KC_;GL<]19=)&*J'HMGYMMVTN$>E8#^N-X+K
+M`PQ$",)7XH\:&*(97<?M_-RV%72O.7>'G+NCR31)IEQCC^?1=;=[A^+!3AF$
+MJ-<-(07!MG2"'U-DG+Z?L&UIQ!(D!6'(]#L'?7/36U-FF&OVKX]!I1^BXD?X
+MVL;GH!GOF&YI1+&CI%2@[,>SK8F;V)1AXG!CI8A[_X52+/OPR%5`,ON6NT>"
+ME5WN4[A>UE##?\T>--V$^G["'J]6$5-B)&LN985,.PG`;G=N+1HBW>G.]3EJ
+MVU`7R+.MG\6$UAP1E77NDT^O)RT@]DO@GDV,5H%TB-`0."`M-5H43,9J`>OP
+M)M/$3/R3\%6GZN)AQFW?8<CJ#:>J[T91?)8V)Y!C$F9,.X\K_=P]P@UTOO2X
+M:A\6,53OJ%U!:7>Z'<(Y3<V1TJA7&-+<AF*ES;:)PA6^S?TY_B,YQY8"4Q9W
+M"S<1]M(PA>7$HUKO-B7'EJ?>-]A"5->0;1YB8;ZE^62TUZQ[LS42//@P\@&A
+M6$N$?,I!38YPY8(=XPML8G6`XVT9[J.;$H(;`F*#V7VT^D'Q,'&YH_:I;Y%6
+M.\;GVB1E)=)M'[+.>&''R:<W$<WI%P;XFX9J3$PT1Z/>2'#,`@R'KYN(]IC;
+M._9+Z6UO6-BA/@P]2Q)VH(X#8"'TCW`]HC?6LP,JOH,J7NQ$8=+CZL]Q2J;V
+M$H\Y@9FPBFU[$4?-YCTGV*54($8<,\JNU0.WV3:U8Y!VD9*(]\D@TL=Y^IZP
+M00_,T.L]=MWA]"3QX&Z4I*.C5'Q1?S,(#TDH#`DM[M3>8,-R3P#OW'8[Q94H
+M14:>^NM!*('?K4O@^:N;Q<>UO%X-]M<.VO@8_3KBED7SS6G402_T,OO&,(&C
+M[A['7[?=G#4C7>B4+@;C\=N6F;7=--W,?^US<\*'OO0,\LTW(2!>3A<<F*"?
+M+SU=>$-J"28%'$?,[@[AE2Q(I>]B+IRY%A6IC+8W(\09,X#,CN$$CUXR[;IA
+MO,&T^^G"@W7TSLCK]GRVM!?%VG+]-`&IZQ2KDUTU`PY\BSHT9K2E0PX`_2B=
+MU8CNJ$4I&NP@&'VD7<]<@L;;8J.S))F^Z!XUD;@?#E-YZLR!.`2$+D=&L2R2
+M_F/^//5'V'C^<YH)56D?&AN5*;&%8"AYIGXF'.W(C"R:86VU:&=56N&M=@-X
+M'05'[0=Q4/?#&+REF5(?;B<+M&=CBD*#@K5H#%11T/*JI!PG.[11HZYB=2*W
+MR56JD3=1O334B"^P?=NM.*P<1F#A:8H8ZL33;(Q4]N%:UZMA.<1AB;BD]ZJU
+M@Q'G#JK1Z"C.>.X0WH<XJZ<&8!=+4JAB,,)@6G5#'!+B#&5SHMQL-`2D-LB[
+M,%'4/:%T7&JZ\*XR'ZJ#]EJ]ZN$!6-R>2W0-FP"JEZCWV1E@^3#]YEAUN[D[
+M/NV'E<+<:*W/+1_>0Z\V>*7RV_Y.1E^P-C(9B`VG:14]B:WM223C<*Q>U5?H
+MPX'947L1S4,\BID9%>F(GZS>2H<?I]\36!+5".T!GR`3M!A36<.4!/9A$T%3
+M:.5)"9I?>ZVX\YMO%0]3^_##HZGD!.9X6TOCV#&H'TY_B4@PUMAD81/O3%BH
+M`&D?X7'X>`0SF;!P'#%E2O0F=B4((]V$J$/\!63T;0S?X_"CZ&ENVVUATO'=
+M9LYR[T*^<SR4A@,UI9:)E<=3RRI[R0,L:Q4-UW6&_A+M4V.,XX]60T>MA1FI
+M47_7W\*UG6=K&P9K7SM92<;WMGU(S"8SER4>)KX65K,N1JK)`7H9Y:A]B-1R
+MD_(T-)ZSQG1JAW\%8E3MXO@4AFY8<&E)B^W=DLZXK'<UNJ!WF#J=,)89%K:R
+MWB*B9^XZV/KHT0E,>4]"X2T5T.QOT?I9Z2V*:/Z&SG2U]KQ$JMC4$^S1#K03
+M5RS[,!C/A@8'ML=ESTAG_0J/?SI8&XJ-WTK*(81P8>P[TN$&:NX#\`O,[$G.
+M0,5TQF)A&B,4,HV<IY"]9)TZ^PD!ZA5DJUI2CA&_=$;X13R6K"/&/R!VA:NG
+MZGPY`%OL8KPV_5%W_WL\*I`CN#8)ZM"4'>;:%C`>$JGOF80$1@Y&T#T,04B7
+M/C\:WG8:V6O?,:W^`UG]86*!NG=*'>/]&#.6R"91*@NC54TXG>_?%)<>]D<9
+M?;Q"=%&HBL2Q8UO<C8X=J-K/^%C:]=*E;MS\D@G963Z,Q!U/@Z]T>"^!/$`@
+M*41Y+CH0J=L3#,P.;'YC+VS."'8\3B,8DKMML:D[K\N$#N-XF4JU:!@<(@RP
+M5(N&`6(C[SL4H8#4,MZ/87F`%CZU1JZ.Q_4],0,E#A/1U!)L+$IAV44-02AI
+M>:X$-.='VKXMZUMLQ%Y&I(O]#",2EH^8S88UA!3/AHRUD_70/(U6]_77:85V
+M@F/6(]@=@_D!UJWINIEXF#J/,!T6&>X>PSP;Q8,NTM?#.@3CM$+N!+Q(#UQ3
+MS@M<BOI7CCUK?]',7!S0360\9G?V.&8/X=6ZCCQ4&_/*V?9P"]F[$2^&^?[B
+M11-O1YDMPWTZ\U$<3`W(G@[?=#-L-#P=&1+=#0[NDPLZLM!_B9,B3>23^"A>
+MX/>T1UQJ1-9@N;:`=)ET@H2A/O<F/L'GQCX`JZY!N.#:/BQ[NRES>@O_X9P`
+M!&),NC;VX)6(`$3.V"3\(WB0[DAV];(6?<6D*V?3&:^W4%W"1;6'8N1?)E3#
+MV4/+U2O"]?BBKN^'R]4]D>7J,Y&WQR-O3T66L"2ET7W0;&FWV6+6;9,(/D$0
+M^N-,+>.[5B*JFAR\3`YA,!0V3A]8<<&[9R.G7^@X98JL[/B1XD%"0!C&,*'#
+M/8IKFX:=#98B%Y`762TF)T2T=H15>A67:)&[K*1BR1;6YS/L&0[_2BR)\+#*
+M=81D.FP.U'>@\=,:VD[071]"-CQ9G=H-33_JA;1=C^LLPJ%I5GP8Q@9\-0G.
+M*+7:<(Z%M?/P7LX)AK#1`\6Q@P.]R&.!56:F\X-0P:F_>)`@\E>SXGR;XB_?
+M(^QFY=`P^R;.I\9(1S22SF.C.,$JL`OZ]R5<X`^#?4$Z/\*7?@\_('KC)ICV
+MIO]-?F!3'!<L@C$X._A-H!NMFVQ16J?IM!ZC18ZU=*,U_R-U`PPZC*'7!@(&
+MFK7A?H\I%2F[$"_?8?SE^"2Z;[2)=R*"1MP`*[HHRU26V>;"WT6XH0WRKZ%J
+M34JV!<8[L<NTKI\:1M#9)N7I]@LQ]WF,X\;&RV:8T#5)Y-&O$`1J:9P7!K(%
+M0!6SZU9:I/8SD?(X$\4,[S'@M:$ECT"S)X2VK>2"+M^M,->C)5Y26@F1ALA]
+MPJ1L"O]<5V8Y1R\SA0%-YLU9V6V/(6]O'^3[>.2VA+8=%`>KN,WPPO+MT_,]
+M!R_;XZPM,^+736_V=##Y2:>%!`F.(W%R=8<RJZM%\G1DAW,[>1M+NO8?VST=
+MV\QM4]@=!TB7+38<@41BUV3'0X-1%M*()DGEI\S?HDG2D)E;`G]WP-]*^%NO
+MO??UY^OV7:$]M_V'?'W]_6^6WV2VD1Y%D[D_C.[X3(#1'9_VX!AZ#J3YI\D\
+M(IA$S_2@$\??[/`V<S`.UB[;S-E9X=R0PS\*6GM\09>2501LUR45M*N+S!IG
+MV.2"=AS)@M_BZ2MQ@NEHVU?PA>M=F$$]74H%+%M#)AZMU7>I5[*<F.=EDJ9T
+MP<0E.;KI4,7X__NW@5^'=*#,C:D5Z7=Q=A,/`+\6`&?C#&?UO]G;_%P5.(+X
+M26\%W2A/J`[Y9G+\U.WQV\PY4G4H:[YPW=BWL(X+\7K#@\C[C53!3A@?#E-6
+MTUN4*UTXRFHW]KBR/BQ5=XF73?S`O(7J#,H$R1^F2I%GO;[]_UV">HW2ZI7^
+M+S1&!WAK==I&=?*Y4X51F3[W>IPE[Q#LF<V>+O1]&+P"QCA/%RI/!!,"])Y`
+M_8$T[W`.!>;OO\X&NR4EKR5X#7S_8D8_[?NWP4'P_1I\)]/WF^Z"KIK!LB?D
+M>,'394*/@IG!(T`?(825F!:]I=73QM(DJ`),PU('=%7>1OJEZ<*E[5[3MH)0
+M4[:)HU%J.+3*]H+0-J_):$XIYGSDTXMX:1^58?M+XG,;F3\IPT4=J0X#>YZU
+MO<#R2>+>C;V>,S\"\89[YNC8-8`7P#CX/X7=(S$TR%*$!@L837`H'GR.YF.\
+M0KF`R8"9?AC>:]@6]RW.#YA"?1<8E%1U^=%AP5FHA0:@VHJH&-(]3^D2O>KO
+MPV:\DA(PQ/V(XISBP;TTNPQ"4T14*^8"$9`_`"EB])^[8NJ&'I@"FHZ;4?^]
+MRZRME8S5\5W^CNK$:]4YSP]!.X9::..W%*J(1?'1I&<OF>FBGX:UO="`<Z$:
+M!X`"`2/.X0N(,W-Q@:W;NW_(OUY@./?2#LW??@?B\R\9VL&NMX/MV^[M</TE
+MK1U2+O=HAP2(B]$1BYY_]HV[0?\541=L1I03OPOEQRX::&W7:5T0ZH76%<C+
+M!I,$W>Q_G*>"PVN3O.H7'"Q);FV.(^%*-MELPUN986`%KWJ1?E_GT)/F-UV&
+MRK9=N&1FMO11);\W_[]Z_)'>XU_6XUV]QL?0Z?PW9J9N:)>SD]#5378R>KC)
+M=J%CFX7)LFBG]:&4Y9(SDYLSQF`V>:%=O&1>&\_4XP8JXKQK8/&_4+8&POH5
+M5]V&AU;>EO;IEICU^N9OJ(=+ASM#Y`TKQ,0;S?YSD;?6R-M9[0WGBEV8`55U
+M=YV&E[`?/_VG'+55L`&1%0RK[K_=?YH2'8^N;K=IJUM^+LXW-O1/LWEPH5H0
+M-NNWIB8[2`M8-COVVWK)MS5,J$'>\`)K.#[X*NYEL9@4AW^$&;'LT+!,>[-7
+M),5+ZQT/M5F8X?6Z'0-HE1,X\@\SM[OC_[_^`E_U#,OK)0S_4K_Z?G_?M^P)
+M\+?^2_;76WR&`9;:1QKCWU.&-(O_0_HDB!\+3^'+Z-]T*,]I*'.V]GX&_OX!
+M\58#S"+MO<$0]LLOS9R!W_X1BO#;\_8(OW%NQK`4%IYK#9L9L[4-(IF)[TU;
+MVV_AS?>FJ>V7]#2W_92>UK9'OR5I!FXVK*_)Q&[*K*P6B;BQK>I;)L/'8')<
+M6)>$"^U=9ZG3Z1VLC:G<0SDF0]*#R9CT<#2IC886U&DTP$N.P&O[$4(!&+X_
+M?2<87#6U56AI64(<&)EI"0U7'%?:YI'=LWW8=V#7%4:)HW(&/M3'!Z#P'\-E
+M"O"]Z6+92")XS*;;I(B$4R6_I0%DRYO./FM@P`\U6`+G&VT.O_SO</A\HY6_
+M2O0XK6C7*2=4(N_"UBF1G&VKT8)%-(9%0'@!ALLT/DB'C^,0%:X>S(8E9I/2
+MCX$7Z)<VYJ/"^XZ3VQNJX9KS9K9'=Z!B$X4%KXSLU>5=F#2J^83F!;JU75(W
+MHN-RA(PL`!M>G:^5<@?-OE8&'UER!"0[W^@22FB,E./Q2@.AV%O)-"K.,(Z*
+MR.0U<3`V'L7S9)M6RE<7NY6RKS],&K\(Z..GU?'0#22T)&+AV/B,DXV-L_YE
+MYG9^`7NKS^&OW<RUJ@")>!U5)HG#L<6AF?BR9O^)R"2!N"^PNA5,L':<2<&8
+ML?1E<A2JRRYJ79!_3SQ,F1RUUR%*B?(N2K/K!*O1V$*K:;A,7R9JU[;-%TD.
+MC;;X]F'24I/6].%U(?6M#C-SI.6H_;,-+?O3YKT;OO@/\5V2]F9P1J8^F80)
+M.?X6&B52"C7"O=(50SC>C@:&U]L0TT!`'SE\A\8@_W#"BQB[A@I&[M=Y<G-(
+M.MQ.7(CD#<YC1<KQVZ$M,7R;.1R?)=&KAL4/"(M1A:J[2R?4,,;);H+DJ.V,
+M[P.'7\D*IAA/T["CMA7MCE*>IG@N3'-\\(%`GS2Y)^W-",S4Z`R\5Y=+I6:B
+M?W4:'1FF(XF=_Z2SLW0AEEXOF11JM3<O&/IH+#TBY?4RXPM3_S.MAA*M#A:J
+M`R_HM'H^4F.I:SP;E:B+L/JWS;B@9]Y"5$`.7JL3`FW%T]N6-]&DO[(KA)A2
+M@1K-'+5W,9E0M']2MSDJ'OV+1)U3O)3K>.AFL[;,Z!S*NE)@R6<P7[69.?V)
+M?Z?A?>]W_`6T/SU];W]EG_7^]UUYON_?XN\!Y_]U^>)AFB6%@=$Y$.:W\V^8
+M^9%;/IX)Q`U6!Q3QGFN0TS&!XS7K>HF20C3L[8+W!?3X75I\'HL7NVR.AW?@
+M`OHOU"=HF*ZI"3;#O)/!K_5]_!H:@3S_AHDO5?S?8O?S(R,(]T2G*=\_+K,Y
+MA?'<MO@<QMRLGV#OJ(D/F\F.8G0\7M89TTU@STKLZ/#C$J/VS>H;%7\H4IIC
+MZPAV'9V5X-B?$\Y37;"F:;-8M?4X"\\/L[4NK'+Y?N*E.X1181H+:*P\'9W9
+MSM$H:6.E0Z\7*J(CQ#ZL%XI8L7QMLI=I9F9&3^UZ+J=P)4[)#NK4!4XY*U0B
+MI09=YQM-6AA-QB1_CB:14ED7E*EB8U7Y,'9+Y5"\%=?D]-'VQ-<X)GRO_FGI
+MHW\^:_I/_3/=\9#?I/7/G<.U_KG^4S/WS3]AW0O/,NW=]^GW^\.TW_?OGO\R
+M_?_V'Y;O^WAF<!KZQ`,^KT$^'\?XO'++QZ]=9J:\`M+Q%!\,8K>@MI1PIW3<
+M=RXD-?K>;/CO^;WRRS[X_<[+R.\.Y45<0T"'GA7+^->12!KYEQA9[P#Q^BKT
+MJB\,G.Q^9]U?VE`2KB76>L40O5,4\Y/%2Q[^1@"G3U?OPZJF]]0ZT.Y]YYG/
+MN_6=>9&^TZW7J$HP)JG)V%<^2(*>$>TF?TWJUB]HK:/L-%._8`N?K1TT5U(Z
+M(*&3':GT#^AARM.'0CWM=Z#=V?VIDA#*$"_?)PQN]J#&(^?8/UVJ#F4$;0'=
+M?%6!;<M17+IMS^W:EC#776"K^8:\EUIF!RO0N2TW'@T8=04@'D]9JT/;[-,<
+M^YT9XJ4;^:&;^_M/\>\&9V)?OW0O/S-X<P#B\+6?NR!4,Z#9$[H1!UE8DZ(,
+M/NP)&<&XW]OT>;`>^:T@1&M2W;Z7\5\/>XI'SY',1,G,<&>F"C.8#E9NIWH_
+M,#?:GNH$E"JEA:G-F5,P:LO1;X&4K^&F)K!]EB-CFW7X@@WGI<%I#<&%\H8I
+MRI1JA`MT\H8?3$4XFS\S,^M)#-0-RI3AA?E>J:`+(^=^AH5W2FEH0WEAJBR$
+MI`>G`*BX@*:+=RY&%R^"],!S$?DCK%R*9'$3QQ03^ZD?P61W/MMN%2;!KY.?
+M#;\V?J17?:U-6]4(-_M*[!>:LVTDC\E.PH=OOMTJ7<+#Q2ZQ)I7CQ\K95G?V
+ME,V#O>H?Z6">CV=L<G=XD!P'*9WA;&MP'N[+2NP?D2W087*<.]M9Y7#LSPB[
+MNX3X\"!,@H"D[!F0)WNZXLV0O*G-V5-P6P,PO%F*-TL:UIR-5ZRY&.NWW=K+
+M>&XQY.]FO/(-_.YXH1H-.2#I*_".^=@N-`9L#R['P:,ZOCE+\ZO01;;F0\'Q
+MWO#D,%"XH%,]I9HU*TNFR28A-/9"OCK\<S:T%'0"B?X@5UK=%]:]71C)L4?%
+M8CO';K2:TF6/,W(`$=LNPB<D+Y2K[>Z:V95H.PC/@@K#:V>IZP``T'&`E#U+
+MJIEM;..^;?Y>_PGQ)CHZWCQ\(3+,@^T,2^`EV'VAGZ'P@];2A'`:1MX#D63>
+M`J/#?'*.;)(NH^LNNS2Y9,L<.^<:^Z!5<I/+(?E!:^1<0\G.RR/HDYA"LP8=
+MK2C(GI`E<Y;TU?B"4'XX+0\3_?A3HIV$)M`[%ZH?!:,8"?<9L'D[:,1&B+,\
+M:`WN"N1(E\8/!NXWO>NE(@]=CA8IC&/%A84NK:QQGU+_@-XQ=B%@3C61,V<%
+M[;#6M[-;_S'>*KK)0__9RN2A;#^0NJ4)K^C)7JMX,6*\=QS-3Y8LVW@VUZ0U
+MN.-JA@8"[H3-`]USK=5_SQ"/.MUQF_^%#HMZL5Q+_CS+BHK75VC./&_J[BYT
+M6GKJY%AWH8#CWSQ.-.+Z[0=_[<GO4?L_@+YV#K$%V4^[AR2V%QEXQ-Q*0P'J
+MNA>JGU';D';!QQR:ZO(\4Y+"=93<PF7PD7L$B2@4.0H_I=9"M0M&$M)%MXE=
+ML,W['5(T[$4UZ.Q_:K"$'QKA"$O1]!XFN)<2V"$??V=ILCKQ$[.N<<[/6<G!
+MFE8=@4$Y]N8<)W[B]:3-=HZ?(!<\+@UOSJ'NV9R#Z'"%ZD]PO,U)DKJ"$XR(
+MZL<5A>J//S:3>C8^6:B4BHT?B!DTEBTM<BT5^)7WEQ6O<:U8540V"OE*?&`P
+M/#6[A*D&&A[Y$`^\4,=&GI,DY;:B8^J"5O%HDK00!H36+4=)!+,P49[MDG+/
+MEIH6ABN2E6JU4'T6<?&TAX6SA1$'Z$EXG?\;1-KH>KZ@53+'N)KWG+D%Y\G-
+M)6'AC)S;"AW'J_X=P16TREG0G<XTP;"(KLLM&_KA(VYT"/*8FKI#S;+%@,V*
+M]6^/_4\,.VOL9"BS[4DF4X$:;G`V>_#2%^>N/EU]'>Z=S\GYB3'`<T]+UNV9
+M4NYI]\5-4-099=:KB6[/V:K94-W\0D5T7OLM;"`^@C8^PH1USF`V^I4H5/_X
+ML<XZR<T>%;LI!;_T<22I#1>&Y$0^N3G#12N'R(E$VGFYNEW<G(RN_SPJNC4$
+MPG8HQ<<,XR2=5FAG28:&_.:L/B]"9RANU;#@[V.JR]E6M-_#AB\(G:UDVR!@
+MJMYG^&E*MAT"4B(!UX?KT>9^J;74J60[\Y3L1(B^_$\:R!.8P3-VOS3F;"OV
+M?MTRAI*V/@IL=^0X]G_9BT3DG[Z+-PK]M755L)_OXGC!`HG1!1(?![].(=EW
+M,548[IN)Q]8S[Q`&;E]@$IO-S1XG;A\QG3`4/E`ZB`GCX1VG>!KF-"OY,)-U
+MI)UO]J!3-Z[M&.(C>51_0[5-<ZZC7O"HW>[2R@6JX3JMF<S?QOD:6X+YL#8[
+MB??^='DB)<1+Q?QZQ_XWI5S5_V9UPK;C.NANZ9BXDX]7,M]$(BJ9O]W6Z-C?
+MZ/8X:]QH:'.3W2V$*N.%06Y/1S70I9.&:^#:3EIXOB`X(;6IB>C9^(S/43L9
+M)R_(6)U(EF"-EY5@=2M6=W&\^<*'9(=C,%X+10/W%B4G3`99D+_.]F8_,9:_
+M=KU/\WMIHIKQ`8YV,-1-E<67\'"6?J4<J^Q-E`IM,,E(A79IG1-&A'^.5.0#
+M>)*>^`=IN#3C#^3SL->YWZC',.Y]QLH>N]0H?CQ2J4,02N)VM(([V7^>KX`Y
+M*MO*]\=Y>*K_O/`5A-TC>^WN0BLL0+PV=V$B/[,49CL;.D@=N3`_/$T=BLM&
+M""A,U$9?/!NOL7,UPP*%ZOZ/=;&732ZTNKWVS4%Y&!H:A47@56?-7(R^@@'1
+M+7\UPY2AB(3?E`/R,%CE7@M=VSW7*0R6S5)<OOJWOT&YP]#?VM^E=^4AP0\"
+M@1PQ/++FK9Y+OEC8*7\E>N-^H,:*!LF@!X;7.L-K[>AG`5:"4K:-Y+0UTVG%
+M:ML\0#N:#;X-XXO7;O%:T9/4526X)N2'.EZ>:X6$L^4:Y]AFJ<O=6(-K-)0M
+MF.9;Q72.WXUV?8TXM4W[0#M_Q>[2\_QU?5'E_4LK*Y=N2,<KD*[R$LW\;:]V
+M<;QGL#I.-(Z2KO5TLNKS@T_T$:=,GBJA'XS$*K2%)*:;A;M@4P#<CC8,[R4!
+M)YJ%Z8\F8A)P`4Z;*S86D748K_KK]Y$SD:O3:3(6DA71=\.WJ#")XT$_U/S(
+M4]=#*JAZ/HR3-[]/I:>=APZW=A32&OO*5:7A0I05%22CYX,N2W42C)K9D&1=
+MJX;94"@C/%F]C&VDK\9(-Z=W/KGS/3HEQF*<:Z_5H2>A;R+4.HH#;)R!@*4Z
+M$0IQKOM(,Y/8"W^([<G&]0^!M94T>SXCQQ#8KUXMA[BM7Y5(A>:5>!>0?I2"
+M]GRY+G`-Q\%C!SY*S2OW;#7!VN./,%/@U.W"J1NMD*+2:6Z'G.N$1:B<FP@;
+M5MV,]7RK7+?[&K*OB2#RE(+/\L/UHPE^![RAW*#4XI4'8[U<.(?(=:DX$)D'
+MZ=GQ4SQJS??*"VWDF0GUCDK$ZL\XP:XG1@U<&$.\<KX3DUC#0KOZ<^">DN8<
+M,][']GRF%)_YS^/5/_YBF`\+_JISV40V%<Z*!%S-IL*;(@%V-A5>!P%&/^<<
+MMV95%;>AN*RL?%W%4KQNO*&"*RI?O735&JYH316W;-6:(FXEOQ2O!Z\LK^+9
+M&UD<Q,\JCOWVP/,6P%,\N`<HRO&3TLYC?SOX^#7HCW0:]H\_ZG@!Q\R:9@T.
+M`AYMLHF;IL&8\&X4N\IH21.7EZ\IX1)<_2>D_X#I+#AC;=K]\30;M>SCOT4;
+M@H/PH=8!A24RELI*NZI9G/Y#CB[Y-8LS?JB-"%>2WK!"UF@5M.6F*&2F5NF(
+MV$K5[O1@I#KUC+;@<-3B=4DQ;'8\@KH>OL,(813_)YF`2`0DH(A7(RK,6JV:
+M_H$Y8FSP:;S\T(I6!QU'AO6B"QSWOG;.:$/Z=+/SP0_WJA+>9:C#"DG65]E(
+M;\J)+>^ML^:HU4K4.\8RS^('6G$&U&O$MJOH`H="E&FV'D"2L$JK/'3%9K'S
+M&LTOXM/G8NW`&JB?^V>@_OFTL'@04Z/8X@Y$CF#*B0?$2Y9U.21352=H,E4;
+MY.@Z9>:L\&P_16/7!/(-!!0*#B,9H7H,WQ/8^UZ-<M8<H-BO<7J/Z+$;\'CC
+M5'<\6K[MAD<^X5%QHX:'#W*4P=\F^+N'X3%-VZ/=C,4S>25]7XW?@Z+?_?3&
+M1)0>BZ(4NV>=?,K,#$*\?195BAK.1O63C'O#`9!,?0PBU8?/F@U6#]!R9@^[
+MF1^>))B*&+H&->-#5->!>>I-9W29T$W,_NULJ'=O!H*Q!O6837T&>RI91NZ?
+MUD!24K)YJ]3?\T.Z7XH0U!&02'MMA?:2Z+4TP:O^[%U&@B0T(88^&43G1-+%
+MHK2=IS$6;5G*A(DDSOLAVRR8C38VO6H0UA.2>`<RH+A8ZZ"*>,]FS)*'&9LU
+MP%YUSVE6HCV8UM.>ZKG-,?94M2RK3YO[LJ>*^.B6-=<4\^O**Q^(V-".W;L_
+MT(+Z<1LG?<MTRE?A!19LI!2!2Q$FZK_&%WR?F,H9P"XM*HK>D<`MJ*%)!P!\
+M6,O"*@":X79V3O$J;95S;:AX/Q=6Q=*L71V-;3;A:^!CQT-[..V<8D:JQLN+
+MWS%SZ^%O-_R]]`[NKD.*N!=15OP==)_RZ)]I[`JNB-@UKC=&/TG1SN!LW>YQ
+M6.A4Q%>,27R4)#&8$C"D"0L=BGC4F.Q.2I:D[,+/GOY-5!P=9B5\*_E5N@M&
+MW^+;`$'RM^,QPXTRQ33%>HKM*ZM\&#.]@G)(9B&M41%/(CKY:@-)P,]>UD<N
+M;4[16R6FC1]Z&V<M=3/';.4N2:.I9!D^U-FGD$4Q#FWEXE.]%WMV@:U_W8[:
+M&#W'"+QI47AXKX8RN4[AF$IA-`MA7EJ(&"SE]NCO7_PIBIBK&V(OG-01B]C)
+MQ0_-3F[[9EP<BB?-,79R_\$9[>1^BW`*U>R3YFYV<CM$!,%-IN@;#-&]V<FE
+M9%Z5TXHRV,D=B+.P&!*QNEVBWKNY6NS=G6*,Q=S@K=BG;S':S-U6&V,SEQ6#
+M-G-_W&(VVLRU8<^&?=,1W6HN8:_U[>[SU<]/X("&M%<WOT=CIHKW2FD#>#,>
+M[4RC^C**CI;76='!\%F,F*H.BD0,$)LP0O@TV!@0#U)+PHQS/0","K^[[7].
+MT)I9*]K*B@ZH`[#L)JC$0'>-3>A`ORI>NZ!&89["<;:C-X$ZC25X4FTHY;4_
+MPEB%4J]M2D&#5%#;Y/'A,&+!1?#C`+Q$SHK3+59[=L.7=6NKX^4N19[@Q[.2
+M@/2NV(2L,OY\EMGJJ,TDA^1H-H$9:&V;03X['_>J#P!:"A^'OCRDK@7^ALUM
+M2MT>;->"'<WB'HVSI;J=M1%;>VVOP(];>-RQ%5]6FN@`&YV\/HZCZM!WS<PV
+MA6,'[LQ,34V>/1B/YBO403"B.?;'-;;:'/N])JFY_WMBD]FQ?UCC)Q"0;>I_
+M%)>0QVSH)*90#-N%_.[0]_TE`GVC":'+!0$Y=P<Y-I1R=Z#7\X!QGD1_NX%F
+M<7<M8]FP9V<X=[=#NI7D$CLY1^T8O.L%526&(\'.6/@U.?R7.=I0U))RKABH
+MI6MS&CG:/N:8[146K>3ND61,T>1IT"RK8*J`U)QVWC=](H_W%G*R?3,G"A?%
+MRR9A@&]ZJA#GJ_9Q_'IH5I-$IC7$PY2/[Z\`87;Q9&,#?YGU&#TV?C;[9G%A
+M89NZ_$],XLL2"/&R9YNI(Q@O`^/,&F1J(@N47DQ8^39*E6LE81M06,DQA0E1
+MEL_B>'@!P:M51^%,2S55J-8B5=**^T"=@9!6:$$#C7P0,Z=.Q/]@NERUYD:<
+M("<NK:Q8RFEA/8,CLVM,N&'.C8VH+*ZZ_T&AN'*#JV3IJK+BHH1(GW'&VI:0
+MCS-=4)R"T3;].&A;FG^E+A@3!@5@_CTNS8/Y5^TQ_QZ:ILV_IX$3NN`O"6!-
+M.:[-OU].9=,BWMM5LTY$Y]\NBHZ?9H@>=<(P_W;J2:XQ)N%.&.??#D.RJ<9D
+M?_TCS;^:2PG<"WA+[:4F/?I7I[2N4#U*%I&-SV?8S(Y:]-.BB`L0D/H>%-3V
+M-=DW*#7!P%Y'OL;X*Z1+M:<$>\!_BH]O_,Q6>XK_1LJSP][@4LS>8$L[%TO?
+M\<U(#YNRCT-<U$S`CR%'NZ9"1,ZK6@BM9$`K.8H6[%TUE&:=H/5Y_U(.YB/+
+MO\GTMN'>;W3\:S(S5UP#&90MLVUH)+J'W;>?-.')`Z588KN`UXHWGC1WLSC6
+M0SZQ##(IU1U2M8J2UW92WJRV^6:F"@/@$R4R.1+LT#%H/=_?-_,.AY^9%&V/
+M**\ZCIS\+VP=`M&'R`7MCA?>=1QI5'AG2]L.&F[:G0[_CWJ'-J2'%3TFYRU!
+M"+,3&O]IE8YVWW%>E2_EGE,?_:.VZ;2C<FON.11E]&+O$&7&"I_VBZ`5?E\+
+M>["^VQVU;SK\Z!J!*C]12'*O5JN*Y6J5EN-`,$C7UGQ9B^?X*;W<@;7GJX,`
+MA;[L$?+#")S4-585&Q*EQL:+9O&B=:UV+SH9Z74^[93[[2I'XS]A5H#U<O^F
+M+/=;E5_BY-FK?.7_D?SC&"[8G",Y@_S#/C(J_SC^OR__>%V3?\Q@\H\9)/]H
+MCI5_7-\LIDIL-]\L3I%T2<AT29N:1K!]Q_>7A8QK_B]E(3.BLHF))[Z_+.32
+M\?\@"ZDF60A6+E868BCOR!^_ORP$`<7*0E8VX;J]:.1_EH5D'M5E$)@:5V_S
+M:'>#,&-D(9VW:/-&J-',M<-?%_RU-D9E(??\*2H+F?VGJ"QDRI^^CRSDE<;N
+M>!S[MAL>!83'IELU/'C(L03^*N`OC^&1'K7&N/\$BD.BWT_@]Z#H]U:M/>V(
+MU6[C:C5&'G)=HR8/F7\"Y2$9)WJ7A_R[P<RI(R!2'73".";K>R/2X0.61GD_
+MZJM)GE#`<20U0\ZUPW-PIOLK(<E_BGP\6YLRPCA&2["^"2$-(?QL\!3J$W7V
+M&!$B^Z\8^_<-FKRE;"3*6\J(G@/SU->;='E+JNYSJ"]A"^91?W!,%[:@WSO4
+M]L!U@%*_6**#@Y#ZXNNT:E`W`@])0@A%+-/>Z"YB\<TD(41(W?FZ+E]11.O#
+M)"R1<.G5JN`[AF"JJ3C+U6&,/$0R-XOSX(V.TL39V@B`*Q)K['Y.JL\@4(L)
+MU"RI;Q\V9Y48F0LAYU4O'NU3YD*`M3,%&CXC`I>8]C^"\I8O,KK+6_0<!EE*
+M)$_S$=J0*Z(K\ULRT5#U!K5/GCI.S\Y5&D?O;OD?.H*C]B9J7=S_9[)M=B;M
+M_[%"(L;A_A^?ZKU'M?V_;V0?^_\H//X:\:"/`%^AY1Y^%`<4BN1BM__=QI,O
+M#T>Q<G7#ZL5&':O(YA\_M,W_<P_CYG]K8W3SCS(^E?8?N/<_I8BA3-K<SVV,
+M-M<A8K(PBT@S1#S)..WTCY`EDA_&$O;2.X84JF^_CGR&X8S/DA[6^2SQ89W/
+MK#WYS$Z`7,2^SH?[YK-G'H[A,\+/JS[:T">?$6#C&&3<_Q\R<Z6<.H!-*ZK<
+M;>\_OK&/O?^0QM[V_NK!9N.6OUM9:8=P9^&$XAYOUO;[(_3]?C+M]]D`*F<[
+MPZGJ^J/:C"K\52UJ[KGK7U',(^\NVS!NHO:Z=$W5NN+*=-?2J@>*BUPEY96N
+MZU*JKIO@6E'.TUNW\?=7!_5%+RVN1^@*.=HHWMH0U<;1QN7_KLC;YF?F>B)A
+MWQ=?%_VO@>`W5!2SW&3*=DQ*T5@77U[N6K9J10*W&%Y6+UVSP84C0'%557$5
+M)4C@YJS6+=E&+<RZQB"L6RA>VY?,CI6[UKT*W=#?<IEMN]'ERZX3:-1++*O3
+M>J;'9O'8)7_G9=)E+I'SX[9^Y7CYJ.0_&PFQXMGDK@::YNT[\089BCTE_W$R
+M#]:*P%WLCM=1N[2K"[Y+Q,.8W,0/U3?&*+QL>S$.^^9*3`VKELNTY*+?3K)D
+M9E._/,;X/=%_OCHQ)NNZ.*;;[L<,"I]JE2BK6)UD$C)2WY0/([BH%%9Z^\*[
+M,DEGI3JLJNDKB;X.8-EC.R3"6MZ%-9`*G#"NUY%U0R*-3R.-)%;4H1/(LS@*
+M[%(I#M\IKFY3'=[E.W-9ORA\6J<Q$4[RHZ;@;$9%\3!^<(Z'[6C0;Q=6UDUD
+M<HB7<"0C>U&2_QB1HI5^>R/.Z=<CQ''L0`,J)BT!_JKS@70EDA_)[GBY2R0Z
+MF;6XR<:X%FG7.42*4L1I*9S&%!U:;E2&]"2Z_9C<X:\G]R!))H=_`)H1"O=S
+M^,UD,<BV$XW/ME-]\`[@2A->5MAWK)<J##96X=I(%6#-@33G;]$J7H^?:NTA
+M?31*,88K8MTL&!Q+4]1@`\D3VK9KMGV)+>5=B(ED%H]:)7IEK!&5LB-KF`C>
+M6"*V?!@Q-<:Z*=RQP\=%ZX'IU5(<7`Q<U;:5(_N<27:V5R6BX&[C.T@PZ&B$
+M!)NN8]5G&,1BR'"H'A`FQFK[C;D;*A^]&D&%>K3.X*Q.>!.5Q]M:[NHD?F:A
+M.A8*A85&DNHZRI8,:,O-'GF'#M"BT?0GKYGU1CF6W)9J9O4S.6I_S%'S0TW;
+M3='NBT6K?WM5;RBG%BY`H]`\_%W\;&V,=G:]GGN)H\JH-QZBUHQ26Q\/6"_#
+MV+;E9KJG:V":!1%<QL0RC4NKX/XCT0HZVQ:@X>3Z]9#"X3^%-3Q,/5HHE"A0
+M/(R\;Q+LS2)?QV;Y8`)[)RR,V'5C,SS,01Q-;VD-HQ"S$8^*#5:65?S$,K9%
+M&TZ;31=@>'T)EP&5R5[8XWIP"33R(M[?.ZVUZ1XDJB(6U6&/PQ&I<ER81G?Q
+M<`LA.KATE")>2SG_T45Y6%V#JP(!K]Y!5.H@>=1#U.@(DG@`VH-JH=/''AQ%
+M<K@D14PGF(]VH:::85AN)9K1V"?$A6DX9`-@6,%??T/-"..`5S502^RH'8+;
+M=D9M1ZU"34K#KT98&FZ9C@Z;S7U%\-O!CV-Y3#77BM6))F$$30!7A/>=H=D)
+MA^<\]2<66C`JU/+:V")<A5LYUG>>?#FV&QL92^I`TV0]Y+G/7=;VPRAQK2I>
+M6KE\I29RU:9G??[MYHMP:#W3L-=7)";A:G43KIN[PD)D;D2&82:P`LTBLAVN
+M3THG>M7T`[H@9;!7+3@2L6O$FZ6W>TH2A&&]2=DL)&-SU'Z)E?L2C6CYR4YJ
+M37BBH_8L\=-!Y+I"KQH\K*MCU^))^4J4!7B5>ISRO>JP_6:N2;3OXB(=E'6L
+M.IHZZW"JC$Z=T>X2K9`VD1[$WV:Q-68BE>N($M3>;0@#]KC_E0Q1Z.=S3Q2<
+MF6A@\'7?!JB;/R6L"7-T&:P)9;";#VFBX4TN"H!-P+'ST#^NC;8Y:;0Z`@%T
+M_CH/N?ZQ;]`^GL$1XO>6QT>8@WC#&BLSOK#7L%0U"<GJ\D.,,8;$,,:K;(YQ
+MFOE!NI(H6N4/OB_GVAS[37F._9GT8\8?"R#=-!^W4/O0G*]7?>&EWB316PXB
+M%28`%?(I`*APY!N\*^@_Q><V9]FP(5"I;*Z=#4F2&-MJJ`IMDB@JIO.T8.<!
+M%#Y"%-3EG8QN'5'A.<D>EACM7[T`"U3/<P2TVB95[VWVO,0^[.[JYQP*SK!*
+M]7ZI^JF`7(>TVOX_.!`TJ-:T-VL;^)OEZKWHM&\/RDC>E:OWR/&C:M\JPU&]
+M]BTT=\@/S=R^5<M!JKWNQDI(]U*)-*_Z@%C]'"<D^L,U3KGZ*<=K\>[&ZCB(
+MDZJ?$SU/F<.>ET3/7BMA\M*F+9B8KV)X53^@5+\J53\3D'.?F[-^$5YHF/$(
+M8"%7/Z-,60"XE,BS<@^4N..JISE>ZY*@.#FN1,(@*OI61'0XRGAF/0+P]TCQ
+M6/?%CUA%SYZ0V'1YSH;7PI[G6%&;'E>*=^KRKRC=7GT>F*>>F"<;F"=!O?Y5
+M8AX^B8X&AC#&DM?:MKR-AP-2A2UR'\2XAZ]ZOOL9@?>5;O(HH_WWYS7]/*=[
+MG;7:`IM'__D:)TF`IJDW`J>9IHU=9^VF7Q[U?_)\C*VJ.SE-+E"UH:JL?$6Z
+M2UCSP)KR=>CV8OFJLE7\ADD5E:O**^$EW96RGIN14G0KES(Q[>8JM-K%W9U2
+M="\9\%K-)7"3BHK73H)=455Y63$W,-+?\/J,`?N'?D_87VC&CL`G%2IB8CZN
+M"4:IZ+]SRZ=AFC;LTD7QXWA9?&XDQ_VYZQE8^=QDB=SK@%7)L:_#X0O-71`F
+MQ`TX^,Q(O(M+UB5W=7V-VZ$0_*(_5K+8*.Y=B"6@2_.O\6#*_3)*K`]]C9,K
+MGM36OH=W[?=U?HU=]3D8[0&I]'P2ZF(B=<L+*$24<1IHL$*_FFF(*WX!^[#K
+MO+@'<'#QR5IP$U!9^FS\+L0#-FU4E%4\^!0)6(9HOBVA0V,`K))&A.OQ31&S
+M#:`3"+2=@3;Q(]1'7R`;67,,:?[Y/#M<99#Y*Q1QOB'V.,7:%'$A!0IVU;LO
+M,KF@)6@@6B==8":B=7P=)O,AW8C63D2S[H^L$X7;-?@'`*&VGS%Y_HP48;1<
+M8/=M-*T61F1)!78OK)0QT>TO:O*Q4R^A=-GK.-*0ITY]F?`(>^R09[NYMD%X
+MS5O*J2-?1DHO!;!-_O`%:$(-P0([&FAG4F!6]&$8MK77R9#\56QLG=S'B=Q.
+MO4UR96H`:=?9K\F0#+#)V*-2BTSIX&U7*X:+B_-1,>@<44+]FED6*34K?LR5
+M5VI6Z_^@D=J)0Z-P92G:&H4"[+8\UGKJTQRQ;BD:9D>09%&T,%S_.$;.V*]9
+M!ZDN8XB9^>5H!5\1O=@XZE,O:))MV)',+;VU4'T=`C(D_PE$LBN*;`LANYR0
+M/4W(GOF:V<M!9#%UGE>-_P/2\9?/05=_>N_7VKA/_1/Z>#?_;[\E`2/,,[('
+M'5S&2758&4G>PUASX&_CT>A`G"0^0W)IK$Q8*&P2KP`RF$H'*>+Y`A(6#GL)
+M5WW"[PU,:^.OARJ:2TWJVN?HT)YDB'3YZSZ\$):GSM^K$97`\K-UZLXLA=U0
+M(D+4R'?U7OW>F'"E%G3T=RC<I(QX,&?'=1OF-NE#6JS_M]^B-@YEE&(RLDR<
+MGLF8YV_/,-K0,,1H\YQ!#!OY1_?Y-E24K5JFW>=+2YTX9>(TO-0W=5):VJ34
+MZ:[4R>FI4]-O2G6MJU@JE$7O],7J8)4^P^[EH;OD42_AW')L'W/)<9Y'>RO9
+M26Y/:'.<?G=#&%^:K`:?1<8I38;V?E8C)F9"A\XBODAQ$H-28T/SX6MMZA9*
+M9\5+'!A@5RM80.1Z+[DBA.ZF/O*L=EN"G%7X*31)W4"A=@)AXV"WPZD3(4C+
+M'EP:0`F7URD7)$G>1+IY8<.Q)QW('EZ;B/<P8-\[X7=T3(%7-&`6"*^UJAM_
+MIV\:!^/GWZ#!"M6GD7&RK;)81'HP(0M`3M(UKGK0;]QO2`RJ44`8`1LN\K&<
+M*)GE[$1$R,QN8"T*$(U?>S&6QNF!@+O&*>`M?41!?59?^8\HQ*$':'?+[W71
+MJ4WVA-S92=5/4&L<Q_F68;5(6+Z\N*J*.7-"/UP;*O"(5W,?-8L.?EUKRGG7
+MLG)A31&WB#F>@D5KN5"YO-BUM`S]K&NNIU:5"97%7($V)QL!I;M&X;7$6+GK
+MN%\3P^*QVP_HV*WC3CQVXR"XZVDSUP%_ZM-XYG$?A`<G*F()/J]7Q$WXO$81
+M%7P.RX?1_T[LU/6C7\)=1\=OF8R8EBZ3UBZMG+2A8A*BLFK-"E@&3$JIFIA2
+MQ"TO6\/SRRON7UY9O)0OYN[,2W=5%5>N+:XD^2L[\$81+%8=:EM13ODGP#M?
+MN0'>$@B"4!2!4+)\#5^6[LJ^?Y%G<?8L?3VQ.'9O-^UIE*WN_;<N`7Q.>U.7
+M/X.S_$NXP3UXG$:7;+>(+_RM<MT]R$WI_C!_O;AY"<<[Y,(E\EQKOKR0W9R0
+MIQ6J=P,O21?8;9CW60YM*ZP@4$E&6'0S#,V--R-;,860(:CD9=,E$.+%R\(`
+M=M7F8Y20&<J^6BFTYN,BS/>,SOEQ\DPH[E/XFU!:ICH1A>;2LD*U"5JP.><>
+M&J]R5K*:8IW9Q4A[F*HM'L;?1,<C:%U$W+R28Y>]\>*M3:F[Y:YOP_E*72X]
+MR/"U5QW^C)F<L-SP6S;Y)(N7PT+_TG#;RQS9\8WSJL=>8'9%N\(._QZL?1TY
+M,$D?Y?#CI1=%::*S]]/_IJGHWVPJ4I3C%'J60EOAU\XFJ%V8+M^KEKR`FW],
+M;MG52JH#=G<+/\"K?@[-V;848,`$4#@[7_T3?#?ES#$WY<QVRKM.(-3">27R
+MKI9_H_VUPKGP=X=7?1ES_9(6(E[UV:?9Y?+"E5GB)9/CH5^9"-J^<Z04M`D!
+M^O^!B+X*$9MU%[>[5,*U`540PFB%!I8^N_`+;_S\9JL)J+3JUY$;/T*&=B4G
+MW<%?):;;^2O$C;9;!(=2YT7ZJC7/LR'V,#$F'U>HVJ'<`[@H;GN?\)1E-(0M
+M#V[\;*1E\,E+TJX#5/XAC7WE^598WI`^!$8HNW#;FQ^N7V(B:SSA^@E8*Y/A
+MSM!4:N5B+-YHKS=?/?J4.7HM"+@G'&92MV;-'P-"-O&3NB?IAF"^^B/&I6V/
+M4+Y(<JVA1C_%&@K:)J2UC;RK*])>6M@=T-``G]WNM2'_JX\]S2R5?#<]>NVF
+M6H]0"N_)-Q(+&NPI:#!"Z^FG\(;X$CH0%T8H=;NI>3YZ#KN31@EKVV$T.X07
+MU-?=HQ[Z362A85?J?D/)`T^B'2C6E$.T#CQ$&L[>I'0:!/J1=R#<:._YM\'>
+M>W2@>G@/LT=;`Q6QR]E+Y#QKGISE#+<T9R]ATRZK3"]Z"HOVF,GGDDV]=$D_
+M8^YV_K<'-7-@7X&HI<),-AMO:V$.;!?=GXBA4*8-'2?'2?'!!*U*<9+9JQ;]
+MBNF`2!=H7CN@[R(W5-R_>BF_?&6Z"T?I^\E/(LV_$PQH//L+K&,2\XDN"\GL
+MA;169^&HZ#2,BOQD="A5,X&H=SULLXUQPV@D=?8^CCY)=B&1VX^]A`R>^:1>
+M1:]2$,I7"KKRT6,-;1?4,Q>T;1[O1G^A0K(T3!Z6E:^^]$M"58J#H/!4LH?^
+MTU]1D#P(@N1A3=8$+JVA;2K=TFNE<7K314W)B1](SN79K2[H"W53&$L4G&GV
+MG&5UMTG".;3'+:BP49>$=EE(E(2.4KLB='K5"WO8G?VY2^1,:U@X&Q;.>,/U
+M=U!1YZ"7HTN74LM"&=@<3]7'0%/=H-1-68)]NZ`U7+E$_<LO"4)SEL;$MK;"
+ML&:;L%/=AL[(F54%84E,K8_LZ5'K)W_9O=8&TO[SEYHRB9`4GBKC3Y2RMWY#
+ME%4*.O,9[NIZ7&,+K:H51@@\JC[>FV[.UI]3/V"LH8A8CN_@,5KU#R=A9YXZ
+M_;=T6]YV`&>-X(``2R7%X1J+>@<P8\FJRBK>R(P<UY,?K_JYIJ0YION<C!QF
+M)PXS\ITPD'%8H=:N459V=N-I:$ZM!@4J\<:2"]UX8^AW\D8K\<:YTD1%:)>$
+MTU[UW!/8H&HWELC3N:]^!MD4B&&)T4I=XS)B"159XN@O"`*P!'4Z8(DEI#+=
+MKJY/B/+#"KF@$WF1\</S3]#E8N2'1.*'#K7N%^R^,?!#(N.'&`[:]$0/#EKZ
+MB^X<!#-26#C-T%>7_0:Y0E6_N&3D"FC"-<7K8UN0VF^*H?WN>LS\OS=Z:&V[
+M7&];E]Z2D48>W:V1E8(SU+:UWW1KVY'=V[9%,XQ!;7N6VK:5^OTYZO>JULXG
+MO&KH<6RE,WH[GPX++9%V/JMW_7[=V[FVB-KY#+;S^S\G"(:NOUAKYX"M>SOK
+MK=;T>+=6ZU!_]_/NK4;M/%K+L9-RN##':*V=-U`.%^88;6CG$UH[;WP:V_F,
+M&G>1M7,#M7/LKB"J(=_#GLJ:G_Z?]=7AFCYI03NUU9FON[45:<`9V^ITL^<,
+M3;@>E=8YN>WRPME208>\<)X$-%N8)Q5TR0L72P6ADF;/5YHX#'JYOJPHZ,A7
+M[WN<Z3OA#?LKE;JR$EPF](>N<0!UJ]I$K4Q#3Y=E-&>,'6N8-%B644,$[3T,
+MEA<`%YP!1E"$L\`(LV([O*U06^#)A=9"6FYI:53[4TCM=G4WC3M.L?HL1WJ*
+M`V@..*O6QJ%FTC&]KY57%J$^3+>YVZAS_L5/_L_H_RZGT3]$]+_CJV[TW]^=
+M_N>`\)&^TD[4Z2BU*=6=A>I'/S43%VJ=0T4+,.'Z#.TBOD:3!-8YCD+G$"\E
+M"`D'L*\&\P.H<XE]I6,%]940]I7G?T8`N_45&1H8.N<P#;;:\"LFC11"ZISS
+MV)4Z54\_)-^9Z-('-ND]Z><RT._Y'_^?T>]L+/V2ONQ&OT/?DWY")_":5_W_
+ML?<VT%%55\/PG9\DDS`P`XX0-<HHH1)!3!"%081,S$R`DC`$)M&JU0@9(4*(
+MR;T)6"8_W@3FSF5T6L!J:Y_:/K:UUK:V*J"")I1FP(?:B%1I2]MHJ=XX:8T:
+M(6#,?'OO<^_\)-'V6>M[U_K6MUX6-W/N.>>>GWWVV6?O<_;9^_%'QX`04&9A
+M*@@S1].7ZS8F8/;`8Z-AQM:1027?F*`O5J0(&=]5EP^R-M#+ZE'N_P%3,/U\
+MD!&"DPDHUFW:V#`.S4_VB>3;J_\W<O1/$2(:O)0/1\%+'@VO?M5%$<&H0OG&
+MMQF`RE&4H-LM_0"@_!2Y:D(YFW:ST!9#:+=0DX#.'8^.ADY]C-D1'L*AF(H=
+M-PXR>.'IO.9+IYRY7[=7U=\KH'/Q!OL]5>NY<L\M\5V>6ZIJK^;MM,/#;]&V
+M3IHV;%RW@;TTV/D-&QO4C12N#+((D`0PM6^L5;-?/2;YOFKTJ(ZYN-L\6J%L
+M)VKE%AB!+]UW@D(V;ZFOACSK@'XTJ`79UU?Q5?=4-6@M7K=E\V:A=N,Z).]-
+M&_D-]KHM]3SDJZNN_Z(<;"/KBU.QG6K[U'TC5-ZEG:.&:IY;P[J![;!C0^P;
+M&303/82G`7NR>6,#22WV:[64=51G@U!7MVD;Q6U<5SV7<]*6G;UQXY9-!`*N
+M6.TC%2TT;,.RM:,Q`A\9!>-&\;9/?TO=?[-:=OZ=4Z]N\9MQ#VX9)"V&)Q^>
+M7'ARX+'!8X;'",_P-_7<(#S]\)R!YS0\)^$Y#L\1>`Y^4]NWZ_L^X;_(WP?A
+MW2P<Q/!.%GX$PM%FX)GQMS$D_AU_:T/B6?SUA<3T3?#[]9`X"W\K0N(R_"T+
+MB37XZPZ)`?Q=$A)_C+\WAL3.36RO\-0FME<X93/;*YRQ6=TKG+^9]@IYVBL\
+MLC=IKY#!!PTG#5W@-S=-1PLT[B:TH[40+=)<AWZ]AX;0)^AY_NO13>+0Y_S2
+MIHGBT&?\,G%HF+\I>ANDC_`S\,1@:G0E.A2A/91COPD?,*F_1O77H/ZFJ;_I
+MZN]$]5>G_DY*21_C1^G],(DGFDABI7WBFSY1/38+.7@+6)-'V*]'\0S0M36\
+M!Y"6,$&3.".@\X&MZ^NWQ>W]S9W/;/[=>%T^_+\!CP=NF+<HWV&ON6^#>CC`
+MI9[3K()VU11J7F]>^<Y8>V)CSSPN"^N9_HCVV4[V60;[3#_>-^\_3&;MF+:"
+MQUA.W[W]W7_[W2\?3F[?%5_6OB1BO^UAS=9,[,9*Q1S3:/G,6*.Q4GD\_GXQ
+MLS6S)J;:%=7:\46ZUU>FE/O\2+P<*K>8%6-BQ1A&VV)+G/\\!'TRJB?EOWGT
+MBV"05.]/'TJRG?.K>/,OK=$SZSG-C_X;.W#QDNYZ*&['T<D^RF0?&<<?Z^L2
+M^2=_2?ZDMGX>2FIK6[RML^1TG)L7P5P5<EBK>V#)Q/,U]I9%T"/;2QF:;]11
+M_M_C=3R67$=IO(ZIK*3VS[]T')+*69U<SC^&M7*^$G(70SE;1Y+P9"5$3'ML
+MU%A]4;GG=R65^_.1I'+1DM&9X:1RL<%O#O^'^/>#Y'(?>T3;WK]$3H>_V0!?
+M81(K<3,#9AJS[3H6EJD\Y@HHMB8[)"@5RO,/4:'`\R&_WXOCODV#KW`%,6.H
+M@*.<078'SR?(,WEG'UH4%/T*)TQ-Y.G\-M[#ZOL+KA^RT(\N]*SBB-[2CJ8?
+M^WY!#)7L&BST*,T/X1WM,\#<D`QY+Q&+0;GT3+?1A'9?(<OMF*4[AL:,@4-T
+M48[A;F,^$Q:U*DNQ6;M))!)1%HKELR\&@5^MT<GZ6(\4H6:S$P[X\HQR+$3^
+MLD(,FC%VE1@O*2>*/0N@CEZ4>'_O$>J]5*""]N0X=]@^#2:-U4_C0WXIHYS,
+M_N/>+\.G>$D_@Y)JG!H-O'3O?T8#A>3Z?QZ?(U?$GD/5J9IE#,=7/J+NB?W;
+MN3(SN;P_?C9.>=BEX;W_:7E_D)+*DSX;-8?GA[ZTG(3_/RE.G^[?_1_1ISN3
+MZRW=K<TAM=XGOIR&)Y5SL92\%CPUI'7@2EH+%L;W=">S-6;=+FTW&==S2ZS1
+M7*G\9(AF:?+`I];QJT!26_WQ,5R$%D`K%:M6))_'S('&9"TB.^3.A@C?GO]T
+M72@)Q.&8]ZW_"(X7)[>M0_Y?P%'[A_8*ZZM]U?75M>NJQ[=9F.S_;B<=PJ/!
+MPGD=9P5/W`"A&9<4)ZMH7:4R+XB$@LPST^D[VAS,WSK:YJ`Q2'=$KZ^L4+HD
+M:GL-FAHVR5X;DV#-JF5!2X7RE)1D53#UKE2JGH!^9]P4^A+.LK=3.BR^JY.\
+MP\CL52I]80T#<(V;R>PEHE=`W/D&&$Y$LH,VNM@NH4I:!A)`2SW''@LP:D]Q
+M4GOJ=^`UVAJS<H6$]+6372Z>*WOMXF%#Z[O#DM<N>W.U<*[LMX?63EM?KGP8
+M4"_I`O26A';?O6W,X=]O<?!5^X#DR$_&,#O$!>%X-5HS(5^_<FEN:.VDNZ6*
+M6W&WZVBY,IM!&\TDBBUZ3KBJ9C+;^*]4-DC,/+W5AX[WRG2:W<30[M.H'E/:
+M*:TV2O?CI_(TJ0(M@TH59KG2A$HAE6:IPA9Q9Z.A`E3,J,@A/1%[Q)U+I]ON
+M66Q3SBZ5K97]N5+S'<ICT(?K74>O=QV77-I&:\1U2E./+3V-SE']O7A"9H\U
+MWAHJ6RB5'ERM%,%G(6]/>4PXJ'Q=4L\Q+.TH/<D5BR&6]M,DMP</B_TYXE+.
+M[XNXCI#>U^0:?8U>Z=R)_92FH<+'"?^57PK'Z(IPN`8`WKX3:SU2OJ'99VR5
+M2W-B!4IF`)5CC&PELZ'?`V9N%"H%^$Q57L0Q`J#I9!>S_0XR1F:%\J<=[`S9
+MW\GQIIC0J1Q#+('I^6P2?Y#@_]J!U[_[*H[]B0D(5KG45KXZ<7FZXW/U\)#T
+M*(YR*7H4'XIL2K28I$.XWQ/I6!ECA_EBRRQ`?1R14#$-3:X46H93(%NFG/*J
+M7#5EU2R6$NGPQ#1]C+5JB.45(PNE0WC.*8>H$N="2EN].':_IU(NARFMEEEY
+MJR^FEU<M#GG-Y;$7Z(O51MR2L<+$R"?,DE?864JYFL08?)BE++_?&GN;3>-I
+M6FVXN</F:]\5!JU-<N5B]0O"AXY;V:DP^R9V?[;TFGC85(Y:?;=2Q*TPI",=
+MA$\.RLS/T/"`%2A5YD=*YJ`\RG:DGJ/[.X<01)PP43R$(.(L[6B<37Z9D&F:
+MY-V%L\0;QEGBW0-X@U:4_-F2_XD:>\C;6:X<@?%E39(G2V]W?9@F'2K$AKX[
+M_57LC_3&F^]+%^00QF6N#0$%,0&_[N\-"9W#+R)!^.1'\EX:@<,YY6Q'N[=<
+MN1<*]2BWM;/I;!,O`%/U70YUW2P=/XD/FMR2HSODB0^:O-RN"^&PMAW"OTN+
+M+%SSY>$8C7D;C7?GH8&DQ)8S,O7=0658=OTW7D\AA'&$,$8`L"VC]+64+HXD
+MT&,.2O,DTO=MULY<F/Z)T=)^.2+A5Y$.=ZR/,8=(H;T8*@]YGX5.:B-XA_2Z
+MV'UW!0S;TG:5#/CSX^7P7:C,THXW=U('$--I=Z'O8\PY9+#L^-E(`@BW:MAS
+MMV.RI>.;(ZA"X*D(O8#[@A7*;T4TC]4JA1;#ZVIX?S!.@!["X;H@'IX#B(VI
+MRD_;F8I-RQQ.6*:A=DC855&N&7L%'+:QZJ!=>/4X4I*?3HQ\F./+Y!!B;T2'
+MD[5BM5(.Q44=XB&<OUQS?*Y`86;2FB!]XQ"F]MU++M#"\:*)I++^.>>$?C0G
+MEF)_0G:1FJC')!?-`6)5E"\YC7+1?,EI&B6+_G<+,OV4N=`4\BR,%"YD&A_6
+M\M@;"=_08WWVUK0PA4O!*A?AY\O%\\8FO_2GV7OD@ZU`O=X-A_,ABQV>@68]
+M9X5?#C^9*I<9)4^NM&Q6=`WVQY,K+YLE397*C-%;\)VEYTC+[-'K*3T'K?)3
+M^@QZ-TE390^L3$;98\45RP,+DQG%VW#2GH[FUS;9_D4SHYI-)E)DS(K=J,QN
+M8^I'%8O%!W(X-(J[T",7Y9#*1862UH9:C;'69-?&HS3GOH!?6)Q4;1&KEEB&
+M:"NR#$?8P%IKUBM_:DTP!3>'Q'#;:);J5ZUXW8#6,G+)SM:UN')]$?$$>Z#/
+M;.&_NB9=6_BW4-]@V>\4)E0H#BBGKP57_UZ?5**'U49T</Y[:M)1ET81L992
+MFZ2K@2IK6^G"#\NR?7*-M1)FX_)V59?2?]67-J</[;2I"RCSL:ZNGZ4V62>E
+MJ_JJ$;>5(C,DMTTN,4KN;+G$)+ESY!*SY+8#P7,=]2@5T`YE>>N_XR?0AC/P
+M$R!JN_,]H>:5E<JG+7AMH@>XPXL(!G94B:`QKX5F0&?FM]"P1^]"?'+#8E9H
+M!1G6O4PF_D+<BIX)()+A04@,!$AI>M-.M#``JW5,R`8Y`2L1AXF'.@*3"W@H
+MY7$"XQ%D#HY$IVN\P2O-*F]PA'B#(\K/FQEO<"!E[V!9$LY,VL[\FFPSA5:M
+ME$J/AU;E2Z5'(JZ#;(VWHB%I6.-7F7"!7V6.N#HYHC#9D"#Z[9R0+OIS.3X#
+M$DC#NO0XTWF,E.2RP3@2RY0G:^ITWJ.005YNC#4M"U7F`P]V7"4_N/E["TNC
+MM1T3XJOW-=C`R;BP"\>35W7&>Q^'<8F]H?J($%MR.2$#*B=^30>IRFU^P,>O
+MT4%.)[XO]VM\_!3(EUB/%^GH+E<G1W8JY[!UA;IX*791L$'NQ+IC5M<=["_6
+MA6&9\'2RY#T-C92\O4"GZ5RNGR"Q&Q%1\@Y@&_ZR7;7>8FE'>(;PM!^B]VW7
+MFC8!.\+_O.^'!,.CCM(>X8E096YYA?*M9G59@"95(V`R9:<=E016`[W2E@4K
+MM)4M"+/H&'0ZX1)`*EN#U,0XI&B@_;T<[Z#.D*(F%J?8H:9H;C@<*STH^@_&
+M^$NT84A:,RP=6;CXE>2&JI\9?TW(Q35A%JT)<\:N"0]O2UD35D8*5W[IFJ#>
+M2:"50#ROYZ]NR13/@PR)?+9XWL!?'75J=-TD+3-'"JU$'O*Q*<O,R;0==5T\
+MV43;<XBVV\?0=ED8'KMO\)>M8VC[JF^HM-VCT?:52;0][QM(VV=\0S]F#R]9
+MUMNQE>FTD)V4CPFA@,5S]7J4=Q[0JW?Z#G=]D"9Y#XJ]TU\BYJ[KS7>E'KGT
+M8&9QJ!<O]/@[0T)OG*]SF<1.DX>8.E>G1_G6`\C4M3]`%)<NHP$6+`9X1HH8
+M6B-3%/T&W:\E'FBAD?\YU!MQYAJ3":]S%LNY.LS(/SK9FZ?D/H#+C17+11I8
+M0!_.NA%1D'T?<5GILVE:^>B]PR05S8+JZ14=83T[OOY^31-;__TX\!UGFQ>%
+MPQ65L7EHB?7);;18R-YAN@.26!ZP7$.\6Q/RNG61CK,M1ZF:@;C\G[C_UH26
+M;H[2_0`K;?$I/]V&EU,P2F9_R>9RPR([=Q.>]=5NL=]LG]D`+YNV-,5/%B%J
+MDS#'OF'CO1M2XR!?TX9M$,8+<K.T,T/T(U1=RV]43UC9$>*U]IGK\R!_0X%6
+M7,,\M1#M;#%51V-%(QU.*;.1277UXRT$0")T;H+ZN"'7H*="+@?:@+JK8JY$
+ME[[ZE0+$*W]_RJWX4D7V]H<`J?&<^J2!G*UX*I1).+KG1N4,\9-BJ()2.BB>
+MGVS9N4+'#C9E3U"UZ;6<UW/:LT%@#X87PJ]9#3^1E.>+'MPPSME.E]SR)#*]
+MTPA#,]K:58A/C_7]DR,=4&9?^D:6>?D79>XD0C.D\&G8SX&0^'7V0?87?(#Z
+MO_X!O!R#-J?OA<S13*JHAGW7NY5P<;Q/HU^+VZR.M^M76\>O)CH[D7?W0Y`7
+MB'['UB\<`&M(_&]6X-U;R8-4W-I@,GY?S<?W!P_!\'A8^U,9P&<;U=NEY9Y;
+M%MG=ZB5IH;:AKGK=1M_&:O6*21Y'Z9[Z+??65VU6[VW<NQ$U8:K7JVE;ZGD[
+M.^N/:PU0@G9EI:Y^"[]EW99-J;%HHH?%E`./RU?;&]@E&*:80`EKDH_KUU>O
+MV[*^.J$[$6_8NNKU4*5=J*UJA-K)<&)RFZ\;K0>0VJ,QGSG'F:4L97GMNBV;
+MZR`:3?^HI38@DPZI+,?:C9L!<,"Z:UW%8E&3H[YZ7?7&QNK1T0W5M2H0;TGN
+M8WUU@[")3TZHKAVO\]HM(WJ9E:J:@/GS1LM6D^J)=A1TAL,A\V\Q,K0[Q\YQ
+MCOE90KI<G&6,F@O%H<F-[X;$XZ'/Q]5#_Y_[R;ZJ\F3L"Q"KDE<1"T@;YU+5
+M)$:OJQU0BK+Q`K-.A3IK?:<X=AV`D:P*I570!)18OK(@1E<:US:2`,VB91#'
+MS7R^.#3)TH&&2D/B/0_1EW,;XU_6&16TZ`.1ES0R<[;5\6P9C=JN*#)8#YBX
+MYAQ9K,/]F'*3P]IL*5?VPC(!&?\*+8E>HY4(+?1A`6,F<W%ZS*.\QA-5B,_2
+M'PK)EK62X2C6,3BB69-QX6AI4.'X)7-S>6UCU::-ZY,T7C"YGKMETT;`$CO(
+MDNL1E:LVD5FKINJJ^S2]F?KJFNIU/)04_T8K:QW[-AX_^H-$H:,_24H9-8E6
+M?764_O>6L7CX3`H>F@`/,QK?C6M[C]41*]I")L[17V5KBT[/S])L,LS5&(&^
+M;BS8/P"2IB(!PG6[/M+#6/O$EX_3TE^DW%*/C$S_2_]L6%8*Q/3<!^CR*@-6
+MQ:X+T_/>"-F6AVS?A/]=[QH@-:\'LOH@X$N[5>^31"SD)=JH5BM&!"$;K!I/
+ME2^X?#+E\\7HAPG)OC9J0,S0G.F+4/RM>I2&`1N*[F?;<&9WV\A/\&J2L>/$
+M]F?1MU3O>/Z,DOW%S:O%>XP]4!K,J.DUA34Z9>7]<:-U-,?0SY-$6<3FQ9S`
+MR[M)AM%+;K-<!-(R\MDH.;O-4KKLMN*=2[=-<@/*]\/@@`0=\BO`8MI"[ED@
+M!+\'&%Q1J;P/E;"C\K_<3U(Q0$B3?!=#6)-\TYGDF^PP+<7^P68ZI95%ZD$G
+M?Q&*?G6+Q<Y9GM5RD3G60^=2\;.MN#\_IM)#850-2DY+M:TY93,S`.,U![,"
+MI<-%[<?X13")WTZ9Q%MCP71W.SN+OR*\T#4L?,B<[BJF!I7W'`*.ZT]EV(W^
+MY"$A_9Z-M>NKM\Y=0_H]\T;[\URXZ(8;4_UYKI&+<TW!E;EFP)E@]L(_\AF%
+M[7\6/BWHO/TWK+Q[UFVN^^+BYB](+2Y<62%OSS7+?*ZUH'-87IEKZ^K3?_(3
+M80(&Q7<,G_R8UQ5^_:[Q[$E\>A^R)TFJEFCYJD+979MPS3D)3]PJE1[$J:'4
+M\V_\5U*ZELEL@@E-VSS>238^SITJ.!8.@RR#MO.-!9D]3I#;FC],R%JI.%P+
+MS0@]=_(%<H0LBT-$&*Z\$EZM[$WR&`MBCI=/0X[F1:H_0I3+AV5A,+1KTDH0
+M@^7[C?+N(1(RAM-67L9Q!J=),OY:=`W:2B"C8YNIY?<%,:V6`<?+I["P6]JZ
+M3R%G*`R1G#\$K76$C*VR=Z#M,)8:,C[(PE@@B)=U1EFF!ME^52)#*<W&EF,:
+M8I/A3U2DW,0#/\!=)S347]>PH:J^^KH'MM16;ZSU;>&N8_=89\U(.7_94D,H
+M"K-U4NBYV_=^'D.CP;<`+6E=LDC0N5N77&?9P^`J=0R<QC-;2P<Z7@W)-9!9
+M"IW"N&.6=C39#*.Y%]^3$/RU<R>D%TYCW*B52Q^[&56]+#O?-J!!,?Q,,\>,
+MX=7*9YMQ4ZIY+YF5P"CE&&!&A1H^!&$TDG3Q%G57C,^*4/M(K*8\XB%\Y_B+
+M:D!&[JC7#%!T^,C41(7R=*U*J<21F*7=@[;K3&@,HV/P-"W?O[X/Z6*%M/<,
+M5GC\/MJ"E.D-BYF.2K:'3'^!%A_"ZBK5C/?A):2.?NJ/^2^)_JRA>`7C#UD3
+M7RDWX>E8J5G2A0[9DJ)SU6BG,70H.RG>K,6;0H=RDN('T:IU-Z;<;PX=LL=3
+MD'>AAHF.>9:=->CNPFE:1NY<+3MOA]>V;<9Z';Z4P8LX`IE<F.D0]@`0ET>-
+MEXYY%(6-AQKBL3EZ#5PR=3*O2SJ*MB)PO%&6;C&&;(<0S^`CPVHC5!PR%H:,
+M10:G67:$;)]CDJ['0,`R$&@<'?BM9==A:%'!":QKM;%Y+AMS%;X3R'']&5:%
+M5/QMJ]B!J4:@&$6.2F/+B?AW^3)!()@![X'V+)QK)0PHEGWLU>$T61ZJ@+J*
+M(']+#WSI-SLJ(0XO4D2H+32]!;.!D#BE(0\BLJ:KM3,`6/;I8`%SLB''#1L&
+M^2&=92>J@E.R24U&5QU_YIBMHQ*S9=?O<?FF*FU%U`%3RTZU0>9F>YA5$-1!
+M1*!]$9($M1SHM+GE'?BBNST+HP%NCLG-)9`O]/S;*R_7)I?:Z-]=2&JT.I=>
+MQ#BW,0Y'$VMVD6-:RXLJ,$W-:U]!2`"=\IMUYZ1#IVF"]=,$LZN=?T4GE9BU
+MS@_I&B]F6R-\6*;LD1+:+Q>[X_U[3@-X<QF5#M&ZCZ00*UNALG/8&%I>R9"<
+M5G7TL.S)T1]"6RAKQ&F-ETNEM>S'Z[#'3\</D=!&30['?J\8]?M%<9?_+_+C
+M$6&M;I3<,[6:=M6"D]M/\,7R<V2]K'M^V/+*X8Y.?QI1U)^2:;.)P>(=J?;:
+M!%N@QWARL:[1W'IA-I_AQ#*$[H13[S'[5T^OIRU#U$U#3S1C?0_\&Q\,]Q2<
+MC;K"T#;O\.@/IXWWH5'][M*0;9_E%==PB/?T.`3;]DM+@A;@<]J/"<\[!&O+
+M!%*!@Y7;R/2*DOP5I;;_@W7$5V_`L]\:+D0:>2;E8MQMZL*C]V.\5_8.AXQ_
+MP/QY/5V]:3KX8Y0R6AV+!+>SYJ8:/(#\QT@B_TQ8B2'';/RKUU&^*YPUBRG?
+M(<K7<8SN+>&Y#I2MFX;@'1A/QZIT'=L>]9M;'=<*$\@IM#.Z)(SP^E_:J<L(
+MZIR+9PN6@K.5JY6S6C-0WPMM/.O/3<=&Q.6V1!->NT<]GS2W+EJAW0`MVH!X
+M5Z,CEQGAUD6E0DDD'?>VB\@;"K#'Y<H)7'108Z;C!/^-H+YH\5R!KTG#5!.D
+M/I^4>B=+K:A)C]YL>26KXQCTZZAEW]%S76/Z%1B#/_9(.D*%-8AT%\N5RD3A
+MI,\T/0QMO$ZP%*%N6KDR1,G1C(C;:L]!XW&)<\Y4_NSU*@*_ZI-:<VWJ-:.K
+MW-D'IG=$5X,(]5;72!I>2G*9NX:F2Q_G'0X9RT,V^(L6"SF'RRS,8EDWFS%O
+MQCAYN]XU.KQF=$4]3#R$RRKGHT:JK\6,5G#ZKM.S\YH1/=_2=Q6]R%ZK7&Y<
+M(7D'H`C)-4`(-P`2&P7@;X:N2RH=0C4N2_N'.C+!+#Y@O,GRT+OPTN8::EVM
+MX_K>TC$]5ZM<:)1<2LA6"`5":V9[!R20"C$`?S-T;T!1?3_%S!`H.(8?;#6O
+M<ISWWXCX>P(^,GB'H7?O&>7V*[9^Y_,8++;(!1O1ZA2T".=-ALXU)'8;G8[S
+MV_^$!2PSBUV9!W[V]-/7G.N3WGIC!)A3Z:@*%M:MD*V#)MT;H?MUS%B3N-6L
+M;]$M9_#LD][NBJ5)_G[Z+"\2LODQN^0=U%T(&=].?&UL#,W?`<6';`(:"(7"
+M#]SK\_G8V.EI/`:T\>"S=(!_!K'+@*7J0^9\::3C+$1T&UA>6"6.SG8-`J0/
+M[,Y=_JUSF_NE-PREU`:]7-K?=7YZWE&I*V3['57^&D3EO;$-RLO`/M<9\UZ'
+ME^Z,%VF<O5;'"E/SS4`O=)U0H('H!@1``%1;;_#VA_9<R@-$83Q"S5!(OV-A
+M\P1IQ,D^;HE"[\:#--[-<ED-'JO!:\.+GJZX'%JWI6'CUGIA4[5FIU_LOR,)
+MY__T=;2+>)0PW6627,?IX";7HWP'[[AV2^=F^X]+?CQ[%V/ZIOELY^$)(^(1
+M2E3'4YPT2*XCLG!<UWTS\L:-@-]',(`VZ".H=UBA3$1&1K4S_SQMX6?]`$V#
+M_0ZME[F>8D>AF3!?F)U'%+7:]^+6O7"T0C'%6W14\G>R%EEVU,28"Y*9K4OF
+M\/;6)3?QEZ$3B0KE!Q?B=0D7]=T28WH@(#4-?(25#6'^3,AOZ<"M"'?(=08^
+M&DA\9&FWP#<@,"^>8^D@ETZN'LCQ>G*.?XY0Y18R70UD.U)")BTC)<8``73H
+MW"EI)_(;D9V>#-5NE^M(H;1S;09)<)A\-R6OSV""9F3G!C4D1JR2_R!,A+8N
+M9"`CK@.,*CWUZPSR2($-C@E/Q80#4NFSRG4$6=QGAU:R:.6RSQA=M,NESSK>
+M:KY,]A^4IHD18[=.YU2="1WLUG'12Q`N!Z5\L1.2@-FS0D!R'<1L!6=E_U/G
+M(GCZ).2R>?AAUX6TKMCTO`NAQ3!E+TC>9^*T[REAADK[GNJZD`%?LGQ$]&#V
+MOF]T^)\2TFA9"XFG`,MEX[/CDXX#,==3;?ZG/H6N6A["<>C[+=$N`G;3YVB0
+M_2F.O[9O$\HH+K.\2X=0/O='J?3Y*-K%1)E@ET.+>RK:@#H5S.(G<((NL\-C
+M;+Z:Y;/LV[4(`1PR2U+I,UWOZ,6##APLCO\Q<?FG`>3_J^^$!]EW!2?ZT$9W
+M2EZC%)I/,SW8O@0S`X.-\>+!)7?0IW,*8AUX.NTRBP?3;Z4HL^P?FNU_2K<]
+M;(U.!)R9[7H>.6,01UC-(6.(8\R]O&LAZ[%X<"'K@0G[GHXV2TN?+V+-MSR\
+M"3?U$/=0JDG"3H9^:]60BKP)[$P@+V)H=&%8U9]@:*]C:,^^'$Y%^]$%'RG$
+MFDO,I/<Y46XQEQC\G=`Z:2OTU=S68D:+OI:=84!?X$/:NE'6B`E'8FA<X-R=
+M>LX@'$$?%72&!25<1,H00"#^?"<>&G7B30SD`1\=5U>^[S9B8"M#SWGV?!ZK
+M4,KCMVLS:W25%<J?+J"%FG%][OSB-CQ8W87;,MNOC8@80.+'-EO0N&-ZHJP*
+MI8,I62J?_C-N\F;MUU0:G.S__3;<?'CDQT@&]7<E])HF*JV(]G_B&"_`JFW.
+MK@B)NS[!#?2Y=\;M7.+]\S$.<YC<_8BZH4*-1>VI^/?I['N84$)11,0>T#")
+MI^(A^R$M-$L-A42$F2<DVM_`(GYS!Q41G8]^N;`$`)_A7_';&*U+%O'6&HS<
+M03<04"\FLU+9/,+@\I?^)$#3NF1.WO^^E2E3<!+P_%2X2%M9@-,.\0SN:<TI
+M."&^G(LMXUVXU1X6.VU%*.%9-/07_DGGCP4GHKFD9.#839MA%HASP/1I2:=Y
+M.FC9MV?1VS@Y;=\"9B+T_+<1<R6\IV.MC-U(MR,=.K)7!=P0W@4OLZM;<*6#
+MLM-$NW`Z2!B2C+^.OT=0PVK;K%"U,LY]G.I*PD'E8_0D]=R>0<*>2@7MXJ;Z
+MOTZV?U2I&OX+(R((ET1$##!2^NQ)'`[;YP18P&Q\KU"/2)LYU88;++:TUU@R
+M"R01-JFDIEFI>AR)Z@Y7X%ZEVC0LIS;&&A>7"Q-Y'TGDU>[S)6<><\;OJ]!K
+MW+7*:^-EBFDK+(%.QH;(^1`1.DA["I)_P+'`\C#JM%LZ'DI\@KR^V&+D6J8`
+MLP/\+'SA:'][&7SA!\9CB%31_4,<__6.$\U?"\TG>6X%,F7M/5AL(>5?@D'A
+M)CRG^0.C39"N\R32,2A<%G,-02DVZ?45<CLUJE#]E(_(_@&Y!1;2X6C&"HOD
+M(M)JDDT',EQS#Y_KT[V&3*M5>JWKPG1I).^M).X-E\,\^).1=QY('TB/NJYM
+MV>&V+F34RSJ.;?^4Y$5X_\5(S-UVO@6B6SXZ\-OG?OA-++;KP@3I][2ZRBZ;
+MY#&%%C.!%0I,TUU@*VG7`2D0"&B-2*-&Y+V-^;<:I0O8"OBCSWM#,A&@TF"=
+MT2T,E1D9HTN5Z-5*XO)P7I?LMTFKLK<9Q9+LC!>1%>DXNWUS6#5`<+;+(,Q4
+MV75@$^)?$P,`<VLQ8Q3."_9XIHS43,0EG$?9:(!P>S>Q":X!Q_P'6S8[9\]_
+M,+IG^?^QRAA/XA\PS#^P];&VKCWHA0#`M<PFU>5`M"XF^0<-_@'X*K1G.LH]
+MD4+:$'+,:R$>RB876J&)`*)8B54NL4*CF_O<"+$F6"/M#,-@Y<L=5Z]AU1IV
+M9HJ&_SQ*V5WZA(U7Q"FO63;IK`Z3=OC0]<'T@IYQ]SC2U^!&NQDHD+B$VVZ6
+META#CYT[C]=;PW+ZN1X(G^L!L@KKM.6777GII)]A4O;B4I:T+X$;$5"GTS:[
+MR";DRD[K["*KD",[S;.+S((-"-WL(A-4XC3.+C(*1EDW6\^^:^M'WC>I.4WE
+M2,IMC*4/>4^B58^WAU^<P*%J5\WBD.N4!RW#*/-)Y:>=.4+LF`>\1`TL=Z@V
+M=FE,73\L'9=AM!EY7[HCRB52T$WQADT9>$/_->V:JZ4C:F`:@9:'R4I.#7#Q
+MBD?Y:2+#:P8\UI1+E2]'I_;_')U2&%Q_KV'QLY*_MR/6+$:;PO\':S(^F^?J
+MK=%1_XY]'N_?![CQ[N_%3<.6MO\S]=L$S*_[&$B*[#K3U:N'442OS^WRKDMQ
+MECA*>YOGY97VQEQG1/^9"9:'&E$7WW4&OU(;G!UO</MMR/;,AU9OP/D7$DY2
+MAG/#\1YEXPF!2TG#L;[Y5_"GI:#FMQ7*'Q(YSN)R[3\I^1^/N$[>!+603U/9
+M]83D>K+O>Z1+YCHIN1Y7-:,+CD5<3S+%5Z?L?S(TGVTL"$]VG&WY5\$)('`9
+MQ#^\^:[D?3+D>DIR/1H3'D5W-OXG*Z72`,SI6$_(?[(28I7#PTSHLLFE@8X3
+M_#SIZ'+<?T>;7!W'_!FQTB>CA]&.3[.9#G??[,US/1E]5@WK(/RDZ!_D++O.
+M$K$XZG`-6MH_8*O\3P"4+K,P@3&<T4RTJ4-K?<$Q1YG)\E",5L<P(S-AN3T?
+MN2`LH`.=ZA2<<%1`)IF6V[#DWQ/IV!Y3W62'90HG/N&_)KN>E`]AI*%]`>V8
+M^_?,9B')]83:?=<3'LF["R'@-\?>#KE.>A`":%*4YK%-]NY"*'0"F5![0O?8
+MJ2[@U2I,+3M%5]CFQ-8_O!QW\)?2^>3CAM(GI=(G'*5/6K[?:=G7([L>[U*F
+M.PX+=JGT2;1APT!/<`?J&LE@LLF3T33:GPC]:%,LX<\XE??XH)39+WG`KFO.
+MB!39"8&!Q6,*H.62MU]92!>`K;*WG[;3.M(@#^1'OJ+(SJ4,A4D=BG0V#AHW
+M4SI$XQ&A\1A@40-R>P$!M\ANZ2!U?S8!Y-(SE'DGRR65#A:@K9WV!6IF?IVL
+M#D#IX.SV`@SI]-@<RYY.J4M\1R>ML(_J0-.%Y`X(R\84D#>Z`#%B@\G)FM(B
+MBJX!>!U2N_$P7KAB<$WX_DWE_U8RG<T9GZ!5608=U'$:&=_6Y[TKB;6/%**3
+M8UCIGHUI%C]3=2:6QO,1H0!>X,A3G\?*/<K5(_$/4NR?I^0GXZ;J!V>U:X&I
+M[?[K5^D#-H;R;OR[8FNV;,)YU?X6\G<.4TL:\);1M!7;_AE7UDFN\[M0A#+[
+M8^BHUU2N_%>,7-F1[?T[$SH`2;97[L/\GWVDYD>>VH"[;L-X$*'<19\/X^=`
+MR!PN4W-NS`7Q)<GQ1HAO4>`/?STLX,NB^6$(^W%/(E8*>2\;G7<[Y46?K851
+M(^Y_C;+<POZM$6I+M]2N%:HKJ]>OW2"XZS>NJ>)75-6ZJ^\IK:IWUM675FU;
+M(=2N$#8YA7O75->M6L>7;6DLKEZW=.E2;N;<ZQOL^&?F]>OM,_/GK5\4_S.N
+M#2'?"G;&4)0M#J4W`OPWOO!Y+)J%)[;/9^=#6"ZRBD,3&K-",J6@70Y(VY7M
+MHC0;47Y/;%ZLWABK-\7JS:M!JMW\`IGHZ40I1+FR+-5$3VK][RTG?*VALWE$
+M@E:?^?N:FA--\,2'ZK]%]B1]Y=PD>O*=Y71F$!)Z.X[Q!:T.CI\CE?;FGY!^
+M'^A)TG`]NDQRG0'Q>=_G0!J5B*N?KB8(`ZS66+Z2X4%=K=-2>OX)V7]Z]+=N
+MH]AM"HEK\/-T]9Y0R-N;]Y8TT#5D*/24U^B53U>A5G[/>++CI\N8[`ABH'!Y
+M1TR8K'5V*JZ->+_P%53-BUK"KR`_"SG27L$,RAMKZ?Y]GD^J,_LBA9,(O25/
+M#EYI]^1*6^?@_6;/++S?[+%K9V^C[];'X;8]V?\[-FGW=@XO**)3Y:5EZN7<
+M6;!J=Z"/*;J]&-'CZ2C;=5YB)$.[.OZJ%BON4EO:T651'^Z\D]\B2_O3^(X[
+M`FB7\*Q[HE6XND:'PQQK!/[]\=C;L"Q)W@`9$VR/"9>(_D!,N"CZ!-DQE)L]
+MDK]=;EXK^0/TN=G(YZ(!PS=PD]_;?DEI0&S.Y_@"N6)Q4EST2FCVV1*SB<\6
+MEW+\1?(T^'AVA96RZ+SMDW%U;-?YS1$7R0H1URZZQG$MR$SM+"*@QN-/].*P
+MUG,<G#Z=NF^-9I7Q1D6%XEK#;FCX3;YS)>9+398.=-IWMF2B45@K"X\[GJOC
+M<"/1)[9,XK;/#'F?*+>\6CFI7`F5:A=RK#[9^Y2O[5UNP-=V@6OE)V%9;:O,
+MG*GO#N2MO+W(HE>L]+65F3DC'0A,0,MOYX`%C%X?QB+A"U;J@M*XMHM=3_H+
+ME$WZ6#HOO27]WB#T7`2,F+!'\C\J^G=QPD:"UD0K/UEN\DA"N]RT5A("`(UP
+MF`T5I,>:<J`CL;=21RL+1PO&G'@[NG&?-#`M,#!?E2N3!X9`!M'SM3%4!Z-Q
+M(7P^N\DJ"0#5<$$,FZI^@?BWF-VI`7Q8,KO9*OG'S634^544LPO;9?^C#G^@
+MA9>%1QU"`#[T[W'XVYO6QS\T>-LO*@TX2A_=GB&4.;Q[&I;+WCVS@3W&JS=6
+MW5O2`L@*<[G)2/W(P:NSA8[*?!X@D:^\4$(S(U*23^R"8`)J];>^Z]0[6PB)
+ME>?^1!V4A3U7OH4P]3]ZY>\)B]OQ30@`A'$3!Y"]/1F\;]"AJ7@!IKMX/@:,
+M!M;"MG`KK=(T:LST>&,F8&-FE3#D$TP1-VN/W]1ZK_EO4/5LK"UL:4?AH5+Y
+M6YGFT]OL:#+69Y#'INAV%#17KM`NC'7,&,837VLRUJPN'[^)F=!$2_O'N"?L
+M-XT'IY";65V.MXLZH78(VXBJ&EN3[ON.HD\)_]>W:/YB8LM-VR:"I.MP9K=,
+M;KV0Q9ME7<`:TUGV'8Z:PJO+E8W+52']IIOL<9]LLV8VS(%U#Y^\+"XY99%]
+M\WW);MM&IZ+"/%-^9BFD%7\SE555NVZ+4,O?G%A/V_I-J7XB++<PL\9^6^N]
+MAH$DCV]7*?>7,8]OV<D>WQA5#;`S81ES2Z06=]9ITO-3U:V\D%AW$+>F+<M(
+M*8T930NA;P4IA+;O5]>0]5@U=PVGO%+&]K!S07C*DQ,%FD-BD$KZ+>)SLF]'
+M(]UGS(X)MHK8"UBF4J^68>TXZQ]5QE-41EM2&;B2TOV7LR4&BV#QR27I.WI]
+MFO)@TM?36=),E'D\P1*#V&OQA,3#5&`^%!BL-(CO6L0+:4U59-5PY2OL\@_O
+MU'-WPQ.`YW$UC$^R'[^^7XXP.IW<J.^FQM%%^YVI<02`!A8'#,N/^C]+N8^>
+MJA,^%RO%\]UA53=4%2ZT6YG)/OY:5H[GX^]O)/LF<3K)?2@X"\QPZT*.GQ0.
+MMRZ<*^C<A?`F@#P"'&1#5NO6V%P0&2S[ACK."E?C1/Y,S[S*=/+9;/R8#.)1
+MO@Z`Z]N*=8%$Q'3(R:4>^=8$L#NZZZ]+_H+M,+=C(AD0>'BQ3FL:'@`,Q5S]
+M>(C+2FG=:N*V3^_#TU"0HV.6CE\D]3T3N(#_8GVAF-#68G%K,;`*=!)'/D;C
+MM<86D)_<1*W=G'8W4%QXLZ7]QURB$6C6<5I+)MKXF1F]*AP6AXRX+3Q(=P"]
+MP\$B0ZYEL1XD4]<`\\V>:!#`48P8D3>@(^,'<,?*WT^.0D=#`#78.SI;G*)_
+M*,9;U;J]0Y(UFD?W=P<Y],V8P*;H%+K$94[&.E528PKUB\LV;EJ20F28L5%&
+MHI+)U,RYUS3,Q3\:;=&GT);GEC#U<K\YM'?X<_)"][DVK"J-F;CB"VD,\[62
+MY"Y]!NNX-`2<7GI(S.A"@3$D3NPB/V&W,->9,6'YF&LH6T?$6(S/:UV\8*XP
+MHRV&/6ZZK#+4@6T"D?-%F"'=[=?A&ZJS1Z^17L!V1J^J9$Y&F<$SL0#K43]2
+M/G72M1MV0UT=$/I*^38>!?ZH_W-U2BY;M6:M<^5RYQK7&J[^"VBP?#-C8[71
+MMUHZ3E.5:P]CUZZ\A5V`,*)5H=]0PMV84*Y<YT1?/L.?Q;?!?D0*3K$7,$JY
+M;3G>[XB1JSMR;,/BB1I7*-%"U<J`I1TGF/11*_G@!*SWXAP<JSO&V\L9]5:4
+M(EJ+NY1)8J].ICC@0'&LB@GO@\7A&[J4=$A$6U'D]O19^&-I_PR2NW70=;6@
+MI4YF2XG>D/A^C1A7YSB53]<JOV^<RFU?4/<^JA6/SD/;=*W;=!SO&:M[F.B7
+M]7_5KY+6I="OT'/&3Z%3&5RW:,#=MPVX-[:Z0FE?JM?&X:=+4:Z,3@JK[X\M
+M)9L$*62;_JE33EWN9]$T2YYNWM'^2<MO0L29E32C[,K+;C:CIHZ=45<BKZVY
+MY=3SER6(&B[9K4<0V>XH9/>CT:;!,3$VH?E(#23G*G<@CGIS)>\SK#9?K+#0
+M)Q<6XO4=?=!ERK5T]AI:[]'O-!7I9;<)P)2K@]<1>&V]QS`@O25VF\7(H.35
+M?*A*FU%S1_2;=);V3^"]92)9MY[<YR$<@!>CI0.MX8B184O@)NR`\%3(^ZSD
+M?;*\$CD'Y0=NU5NN95<.I.JZ\R(5/MEE8VNU4H_)W7J,LE*4Y'H"^L=B:>MT
+M1Z_L?<8G%1E)6C`!JES@F&D'YF-8C)PEI9@GL;YLI2!1'WI<UG57U&0I9K66
+MF/"$PJEA8&@^=V'0B,$/7&-KS.HC*NW*$3LG."*677?@YI0WM[O(S"&D)B;W
+MXVD74M%<L=N2Z(I'V:/%3L8Z'M+>+L8\.6J>.BUVFGC$+OIS.-X"!(OZ\MO%
+MJ!&1$V]4+C0J71J8[<K5'+IJO(0I@6Y_7ZAN@:"NE'+58A3S_5E,B]K"['.E
+MR:XA*1W^T*'0*(YYC+V6;[$"0_X!7.30:\QH'B7YO!=-,U5"9X\MU>RC9$D#
+M??]@:[0D#)'YSG1<)OFELE=Q>(>$B;*WW^$=WIX5O0C/[[U#_@GR*E->J1*]
+MG/1J%;FT7ZHTD5T/19?@BD*[GSJ*ZG0G5=\DJFL$-``7\IXLKYFD[%J*-H3M
+M'*?\>C$9FHF(QK.LFS4<MG(&M3)'?)FBA<MEX4C;>[&_(6Y7*!5+F9T2ELC_
+MB]F6@V)O0+(A'%%N6*Q7C5%!4:>6I!HQ23G_6X!.&[$8VLY.<<'(]"/B67,7
+MD`EC`#'KZ1#N%4BN868A`3>#335ZO"RO-"UA[GHU6[;$C=TY,,[^3&(LNV^D
+MTM%`02=O;*TSZ2O(W.>?ER":X`T>B&TTZ9//]XWQKP,WZJD-N,-98U"F$FX)
+M!MDU+-\YE-@3C>>_-3F_3GGOIG'RQS//QLRX==I4I$\&4=]/%NG)QT#:&GC#
+M[74N@ZOOB_>R;Z>6OG7\]'NU=''\]!(M?</XZ5=KZ5>.F[YU?7U]];HO-'\T
+MVO_Q#:2D7E.L#"R(:P3QUU8JM^'Q2T1J7HRN*]E9C%5R%X:*%QH]RI$%Y$B2
+M^6Z\-"2&7QM]Z?8[D"/Z#<EM?LK`9X5C;O-9M]D@G),KS+H+4L6LD'C'E1PS
+M96&4ZLFIY%1FNE#VDET1MUG"&Y-6"F2+;JM1UVR+N/'"`T<>,7-E]RS)G2_U
+M&.`/_I\3<<^G6>=>R"Q,?9&]RO+Y&H,)K9%7S!$?F&]HO%(NRL\[*@X9&J?)
+MNAV]74>M.WJE#+%H_K!8-,>(?'B-D2F6XMZ9:L]T,F!./.]HRY6C[)]<SY2,
+MH-(ZJ-<J]:#FH]OJ<-L:<J%[P]`W,KX#3-9[!JH!YQ&>]5=8L?MRAE:3_L"7
+M]Z]>K<J+JM0=)_ARN6D^WF056T#$NJ@2[7\<,9(X!>($U',:+8("+>QQ?-RH
+MEP:D;EPG*=N5E,U,V?@_Z@1S7M/\O(^C/PN/T]?4-OQK7FH;OB8WV7`C+*F.
+M)N0AL)8M-R*G8RBQ2B56'5I&&<[[&%T8EMB$WT9*5*A0>WY'4J")-?NG>,$@
+M'!ZO+<GZ3_-4NS-F=7OV1N5A)+U=N`UUK0QL'9\E7M#QDZ.7A0G6LP%#WT#"
+M+U?DSZZ8D_<&TC*2"Q+7&$;5H9O'$*K97*$T8\;#L[WDE]=#%JJS4)2[DME.
+M*['F]3A*LAMNA-XU%D"'F0'7/$J;`VF5\YLO=93DUU_L*)D%\(*XROE?:,>V
+M0C,89`8AE&PJ8U53HW.DHX8BJZ/(5G^57&^5BJS12V$=6S%_^T68,,=1E%^?
+M*=?/R5LQ7[=BCC3`+I&FT.6Y!6S\ZLSHNO5[UZ.MZ&]?KT^RVY9D_S6>E^S!
+MQ1KG5RBOLI'"VS3JM!2;$?LJE.6:)$_X#>T2F^=S+:]A,G\$YB[F3381-^K\
+M+S]>U[5:76OB=<U/KFMBA?(7G;9K<"G5TD.UO":[YSC<^7RJS?4QYVVSU:J6
+MF>DP8[*X+0<WIYVHLNQPVIHNBCB)&M7H5BM8*RH`HNJ*,UOL')979Z.KA-;X
+MG(44"5*<5N.!I"5WE/V[ZPA7H3H='9AVO3,=$&9V27:H;EBNS)8&,H\FRFNR
+MSFXRPRPRQQ;():98CV-`N`2MLY5DRY5F\;!1JK1^(=XDTW]6IUR2+_8:Y*99
+MNFZY,A>/]#P56+`]UH.(;)&:YNBZI:;\\6UVI\[]C^>J=H>L';'F4KD^?W;]
+M'.&2<IS`K4Q1E4W@=U2Z,^0XUQRG.['Z.9CQ]GGD&$97/P>ISCD4L'\]_EQ/
+M.?-LFLMX39545\7(''->$IEV#:,]J.E2Q4(HONU=R-`B5<P?9:]Y'#IR^5S-
+MR'''V>9\`-?LDCF"K5+YQ8CFS.)]Z`[J?D@?.[JA/P!"'<S>[NCOP^/:]2<_
+M'NN:T@X\8<$;2(9<C<%(P?<?7ZMM$.-VJ\LFZ4/B=E2MA&5SA55:89;J;0G<
+MC9?-OBBR`29*1;:M.7*16>8T$.C$(K-1\^"!N,'F,RIAH9(5?>2T;;U,7FV6
+MT^,()SK5CU3;V,)8V]CGYZ@+*ZS:MKPA6,"W3F6NGLU*$&:33E5$^3);_R^,
+M6P9ZN38K[B\K`Z>JQSS;`VL,]0=AX#(#&917F`TK;(ZC+5.D(G->E[3"-J;O
+M3.>MX)C#8]N>F>>QP9S7><S2T7'PX.(Y2?:_/[TAV;8U"/T;PKC1XC9YF#GP
+M?R[0IZS3\5)^/QL8=9.JP;K_!OWX]."GLY/J$F*:MO-29B1BJU8Y/Q>8)+;.
+MZ&$=8S386@GPB_5$KPDSJ^E_FJLU%>\'VI!_)./IAR$^V<_*>&OHE<GMT,6K
+M742KFPF7G!E`C5F7Z[5Z^,N8!?@JK&!R6/-W<1B8KR\=_VN2ZIH9+VR>ZN-B
+MOA9QI=ALU`F7H0[(XS`?/`@35F$/L!.CSX=3ZU@=KT.U?1EQTUT:<2DGE$*U
+MO[A6JV4IJW9BO-JYK(Y=\1R7L\'X1CS"S.!=<^TX_4R,?QZ[?0ELPOFT)B\S
+M`/86.P.H@[1'X0G#$X"G%9ZM\$3T='"^,*)'KWC1_(@>N?GHK(@>U1NC=F9*
+M.YK-#+9'K1$]'@)'BJB'T@I3DMX+FQO(]DP2+Z0+DR.<ZM\GPF50(,+1MX5T
+M^B]Y3&-A.#%/@R&L/JAMCVA@!W0+BRW9G)#%;G-&OPYR:ZPI6XD!F01F%M<K
+MY1LH^4\,1]+):CF:%36BEY0,_O(FX%_2^:SH+'$HDY\6O1+Y)4PML46GJ.$H
+MU)=#<7:TIS*.!D"*_L\LO$9A(EDZ1WEE/IJFP[>;4>YMSHK0"T<G`!@B$)&]
+MD(:-]S8(#775M>LUJR%SYS/+(4E.AN8O6#3_AB0G0WTA(`YAN3C7*',2_#VP
+MA4L(:.\6=+)FLO+Y^B^Q2.)85#!_E$62,"MW;:X)<;NP*&AJ/\;?NC!+6*N&
+M5T)XF1HNA/!B-3P?POEJ>!:$<]5P#H2SU;`5PF8U;%R8Q3]AV<=9]DW)Z_E-
+M<GNK^"]N;[YC3'LKY>VY)FBPN7*XH%/=6`^MBH6#^H"NO9-?&2S2!9P8*@H6
+MZ0-./806!HL,`:<!0G.#1<:`TPBAW&!16L"9!J%+@T7I`6<ZA*S!HHR`,T,\
+M;!*[3.V=PC.WWO6;\<?_*^3#@#:O.TYH-C]TG1[R=I<^1S]J[P/_X68JGHXN
+MLL]LL,^Z?6;#G7-G"GGXEI6Z-F=AX<QR8G[2@</U*##_-Q3M\<FNJ=HA(&Z?
+M/3*']F\\=!NQYX]D4-"DU,W2BI'RU:4\N0FLXM%\P4,SQZW[,JS[:JR;ZECS
+M)[4.\]@Z4O7?9A*O*XE'KTSF3>/IT[7TXRGI8K\UB21<R&6\BEYR#:`5)-<@
+M6D%R#0'S`6Q7P=F"8_)N;*FCWMR\2/8/M+V/N\QAZ6A7KS&TUFJ5]<]RCB'A
+M(O$!(\>;H`2':U!(<Z-S"*?ZY0IS"]D].I.@J6W]:%,VJ1D-V`R_38S@KH(/
+MBE&'0.H8POU2^AL+X=^.3LM#>,TCM!=MFTE[!^EP=`,:IHV]@"^5[)A&N?8Z
+M=0]7V[>\$_!;%ZE4GH$$R_X!,:*O5)Z`,%4$;ZA3)YB%7(?+*DQ'+5(J3NF8
+MI2W"JF\2.B=(:5%+*V[R*R,I9[-C^OCP#"8I8!]-8_OHM2;%.2B.MQ5T]F%G
+MV;Z<ZE15J[6Y_LM@P/RCS%5AL/T5[/FOYR9Z_N.YB9ZSTP$0'EB/;R?V.`<6
+MB-91_7R<\1R)KJKG&(CWLY@RPVH\T-A8>Z]FE6W6##S1L%>M7U^/_@5OIIG1
+ML&7=?=7\K,9U>=RZ+;6UU>OXZQK7<4WU&^/^<6%&5ZW7PJR6NBVU#=5VOEZH
+M14>)Z[,H"Y6A%K?^WGAQ%";[@OB'WP(_FR`:2T*K1%L$'C]?U^BKW[(9([=L
+M6F^OJFUHJJY?1+U`2X];A'JU$RRNJ7X+=(OI9Z`S1HAM&&4=CNEI4.YX.]5R
+M*?)>*#9>#>'(W:GGJ/==23R&%#I)%U>M4D</!DC[XJS3I!,F*;^=0SNVEO;T
+M":B52BE%)KV0>?;!*@A;^9DA<=E?<&OO.>0]Q.Y;*Y2N&?KXW2N!N!Y;I./@
+MYZI?"HT4F83,-C]=KH15EI)I][CC^.>:*XNC\=`1""VFT//QN$ZM0&J43-\Y
+MBHR6A\YDHKL0:DW7K5+H63H:CN\[2AU/?8[X&^DXH!40PA`0#ICJF4R/B=*0
+MYA1;K7@WA:IE^2S_?;1A@I(%]+;/A;G%EY$@<GQ508SLT>$1!L/P4*EY=<@%
+MC'[I\&J9R&:L!X];L\4+1LO.?9FJN\K<7F+J7IJNYZZSZ[FC\/O!5#TW#QZW
+M.))G>7A7)BI!\C].(N(HKJ+!15R\/*RUA9Z06/D7,AJ%/5867\7.VPX1X"WM
+M`WH-]FAN@:`7Z7A&!8'X\D'LQ/;+Q)>/8,#2\=VDV#3ELDQRRXQFYG.N0@X)
+M$]@A[ZZ?F30]!:;$46/%*SS/80[E[9G:B4JQ+--2E"F%CA"R0?O-L3H3]"*6
+MOSHD!Z'IJV,OX-@H+^)-)^J4Y6<$^;XA`XU+1,36$5$0WJNP['>9/<H9X-0E
+M05-B):L!`WBMR36(9PZ*1VU)]4Q:YL7#0'AMCAY^?FI[5H?$O0QXU(+GAN+#
+M_;,0M>"XD>Y.6WT1UWNTMPZUO^>I5$MOL;.-<93\+]*=@U7]/5_>@$]RO2>\
+MW7&VI3)N/9DP&4;JATF5N8>PSQD$4/$09KC1TO$=O()RB&:`I2-$@W54G2)*
+M"/+V;?B<E-64E<!E^Z2.)^%5/8P<PNV34A!GFZ]/0IF+0^(ODM#C<CNM,PP%
+ML%0\&,3+V?`[A`W'OHK^]SA^]JB^[I[^I7V];$Q??PO5]K4:R"?+,PP9KT_#
+M:8?$IG6Y7D]5SG;9L`Q+^[0T&NM7D#+XVJ`%^B:C93^,=ZCC#!:H-L.<:(;E
+MH;\;J0/QAASN>\-(<Y,A<*:*UOQ\+9"F+$LGE$:W0\NGCT+I8;1P('9>R;@]
+M!D1QJUG'7RH>ZF1#TH7SX]`!]O(\31;*+]R9@O]7:?B_6"X=CMUOCMUOBMUO
+MC!5HFM8A^8])B-_YZ6C$C]$:S-K"=KD9757+K[R:].`<+K.E_>_85$+J6$%(
+M_$<2@OWCT]'8/*)3[W%3F_F2[HZ+88W51SJR1QA!\$4ZIE*PQAKJL(TDP)YV
+ME3X%-(EY#_VDKH]J8O$5S'./R\P7I\[Z1&,_2&KLP<%1C57^BXX8<OK>,B3T
+M=F2K',*1>/-=:>]I]&IYK-G.4MA4D'KD$/X^=FZ;6>J67CA-TPG_<BVPVIR.
+MKS:]*@6LL8=>0/2J4/XG!QEA;#LS"]\EOC-=O1"5V;X7\X3H>S(`7\%R%GJ4
+M]AR&CSD=9_T7Q8=7_`B1'SFICK-"?NIT'$J:C@_EJ-/QN-JROL?.)XR=L@7O
+MU.>JSQT*>4*'C,A[(;A)VX*!^W?8#"0!V<!`79UHA_&O"1#_X1/XL\Q`0];7
+MJM<67=IT[D!6P">KL]/GT/%?25KU)[)5WVYI/X[7:<2)4"HS*Q'6]#\RC4)^
+MI:(?U/8\9ZB?NU,^#]'GE\/GT=*D;TW">C0<X[+A!2*@Y0;5M>-EG](=(BBN
+M>-SBEE!Q!7]-`/3FRU!-YEDBDD-()_MS:3WLNX@X?.Q<T&-H?=?2>D'/FP(]
+MQN'%NJ;*I`'Z2D@L22KOGY>.*N]Q5EXJJGZBBY.+`W<C/"WM>*<K#D&[L)@!
+M]JQ3K^?S$::("7<E5=1^J8H)&D>D_!?\[=MV#IB6L?R7'=O))WWN&MW.P1G)
+M?`!_<8+_XB]6"9A@CFN(Z80T92XV_^7C1!EN)ZXFP=.H4QL-AAX?Q="@O@0Q
+M-(,*,C3(PR`_,S1U-#]SD"-^YFF@^GTO,!F#:)[&R!$W5F2V/"R<I<WY1!)-
+M><<*H^7A)6=15B(:3/T2[A`/$>,H6+1)<S-*3VOB^J7(/D:+-7O!."5:_C+Z
+M1/K@``AN]N0\KT.>Z)_4)8TX!<FDWNK;\WE<`$N6@Z=-U<<9ISQU4@:RD6AB
+M$#]-D$_&SQ`A3=EC^-JJ,E>YRTV_R\N6K^6\GF+G6E>I4PNHO\5:1+'ZZ^06
+M<@NX&[D;N+)5:Y>[;^-N6>UUE=_F57]+N>7TR[&_9:MN6>8L*W%Q!?.Y@NNY
+M@GE<00%7D,\Y.*C<NP9*Q5)*/5S9K<6K2IW+R[@UKO(*MW/Y2LZ]JKS455X.
+M&>#OJG*NOJ::JUZW80NW?F/#NJIZ$(2V-?!5/+>^:AO99:VMYNG]_BW\>F[=
+MAJKZ>ZMK.1]?=RWZE,<`QU=O@DQ<PV8,XR?UF^HX%'RXI@U;-C9P3%64JZKC
+M&^"/KX&[9\L6OD[]6<?Q6(8/),'J>F[3QMK[N`:A;KT`)50W5:T#40PMX&-I
+M#=S&ABW7\@U5==S6^?GY].?:!I#<UC5`]=?6-G!U6^JNG0>?U]9#L>A&@FO`
+ML@5A7=VU=57P6EL+K]68B@'L5D-](U=7O\4'XB-75EVYAFNHW5Q'?Z[EZZ&F
+MNOJ-M?RUF`NMLX^^_W41N[.U^K.V"S]"DK%3,JHSJ;"?[??.L>JY8HN>FS69
+M_>:HOU;UUZC^#JGY^M7?7O@]"<]1]?V@^ONL^ON?/D^J^1]-^FX7A%O_PW+X
+M4?DVJ.]W_)OO/9@.S\)_DT^#C_W?Y+/]FW33..G#\`S`<P:>4_`<AZ=S5)[G
+MU=]G-'BIOX^KOWLTF*F_[>KO]O\0_GQ2>-._R;O^?S&N7_3<`<_:?Y-GI04M
+M!;WW`3``:.$O'!*C&/X["W^"X;=9^`*&_X>%]5$(O\K"61A^CH4M&/X)"T_#
+M\'=9V([AAUDX%\,B"\_&<!,+YV/X/A:^`<-WL;`#PVM8>`F&2UBX&,,WL?!7
+M,7P="WLP/(.%O1B>QL)W8'@""Z_#,#'E(?%=[-<G++P!X]]GX2T8_C,+\QC^
+M/0M_`\._86$1P_M9.(3AG['P(QC^/@M_%\.[6?A)#.]DX9]#.-H<$I_#W\:0
+M^!+^UH;$5_'7%Q*/X._78>W"WXJ0^";^EH7$4_CK#HFG\7=)2#R#OS>&Q'[\
+MG0NL*OX".W$6?Z\(B1Q0G^A4D(RS^NDRJ_DLJG>OO2CI,NO&=4#G-MX+?^Z]
+M%TDAQZ\#2KEN$U=]+\8#^6VLNW;Y<JX.*#%0_2T-G+"^;C3]FZ32OYAXP6K9
+M^:S&1BS^B(A?*R1OA:<.'CL\&^"Y&YY;X?'`LTR-+X1GH1K6GGQX9DU"//WC
+M`(/17P<8C/X^P&#T_@"#T0<##$;_&F`P^GB`P>CL`(/1A0$&(]U'#$9I'S$8
+M3?@H%49V@E'^E-0+OV/U'R:RRU&,K2G-GA%$;E$J'48I?$>O9?\0FK1]%?F;
+MEXB/Y"=V'./O9SR?CM^`CG>%'.56*S-Y=6M8DXM4MI-/)Q?*%]$U`E.%,@TW
+MF[KI+F%H!Z*OIT(1@2D)\?F0FGF)NCD+KWJ0"5!=UP0"V_;K5VU[*K5<"Y6;
+M=[:5-<2.#G>7F[9.DG7=7%9,%[6@CR]@$7-JLI0_J5`8&../XQ,SBEBT0]=Y
+M*S'XKZ=QR5?7[%OJT)=%PR(.'4&-/O\UDSXB$(%/`.:52KF%^6WSFS@ADX%4
+M\IK(&`CIXIHZZDW\M`KEZ6P\!!9O8E_ET%=6W5GA+[%5IJUF.0-[D!&=@.=2
+MT/J<*8F#>6C4M4N6+',YBUWEBQ=?"ZW#NW"+2(D>UW^A@84WXG',>NXFNV]3
+MU;W8^/OK.7M5%7#IZS@[,$7V^BJ.]JP;*-\<N[,V'@)&0PNN7[^19P5!9J]K
+MS=KEJ\K6T#YO)B3SV^JJF8.L.?9UFZKBN]R0V5FVIM)5SK+:G=ZURU:5+U][
+MF[W<=<NJ\F(MNKAX.1;H7)D4GP4)<^?.3=KM5F,V5VWR;:G?7+T^<=\\V2[:
+M-1/H*G?2/8%)RNZIZH[QA^CQM]0DE0ZA/U@S,W)=.IR*4%,8*IE@Y$I-9YT&
+M"W^G7#KD0P5+]6K<:KP')XMX@2LV/QQTZCL5`_H/ASB>Q87$3C:FRR:2K),R
+MGI/4\5S)Y@JD;3/))29'278+Y;DIGN<F91;+D]K"B:R%>A!:4?@6/V1UG3:S
+MO*5#K=OTG-\*\CQ+^$T\`80\(P\)PRSAZ>0$/29P@Y3PS>0$'2886<+6I#H,
+M5(>))=QE'J>AF=JL;"0(.K73'<!Y,_ML%LX<2DM/I$UC:>9XFBF1=B5+&YB`
+MU>6RY*Q$\AR6_,8$YJYCO-9,X"_!X<B,3R\<B\Y)6K^2FBFY!O'.D&VT"(T#
+M@`$K8!0-P$)6Z^U0JVJ0$$1U%E="+3$YA&'+CMOA&_5DJD)Y!(D"N\-I:5\.
+M+Y1EX9BZ,M6Z^*LJE(\O4LFB1XE.I/Y^E=7R3A83J;OU5,K'W)>5\DRB%.]%
+M5$HE*^6[\5+&Q=?')S)\+1VT2'@+A:K:20"HI@)J[.@Z8[\SW:.=M>P]SXS!
+MYG2<Y3=`_L;;0V(]RUO(\IKB>3<FY5V,>:\+B1+EW=#*D=$8R)X5S[XH*?O$
+M:#:N(^(/('LT'?@0UI__R42"J8SG*]V003[2-N"6+I;V_&<I-E;:^E&))(FL
+MO)E.F_6R8&-7Y`ZAW(P^>Z0>@PN-:+\ZF>ZGT<DAGKFB;M62<+B5,G+"C%@9
+MSG*WR>'.;LF2T[NYN;'TJ"U<43-7*08\1V-%%97*KRQT9&V@@D(_&HB?J":W
+MO20=VVY5VT[`6*Z9B!FO[=/2:6D?U7"H)HW67512TXUJ/>J)5VEMMV#;':SM
+MS071A=#.3`LZC$F^>8BF,@^FC4`)<_DKDCN;J776A'V]=<+X'<Q$CX>9L(+`
+MDWD3\QE'M\'JT+T<+#R9=/<2UX!KKKG&7EE57XMGK!A>M>9:6H`V;VQH@#C.
+M/BN+R\S$`J&@ANKZC56;DB+JJWVPFF^PSYK9D)<2S==O&QU9O;5N8WUU2JP]
+M#^(W;ZS=N%G83`G0L/5V+O,J^*4.D/Z%G<N"[%SFTIGKE^(*5U>%Y[/VAHT/
+M5*O^V6;YM@BUZZF'ZS=5U]J;JAK8Q3=M34N^.U1A3+DT27??7K6,<_>MH+.O
+M(%.]Q\O<-:.XCBY\T%'6.PR_5-+6R\[_+8D3\?56W*@]+D:,E4H@D?$T)$K^
+MDRH].6(=14Z-_,4QX7A(#%\@M0VKXDT?G_;>39DOJ5!Z)Q'1V:M]D$L?0'M[
+ME8LS4Y,R69+L[5TA7JBV[#R?H;+B1X?9/L03.CV7#<_*SW3T8'@KQ^*RD]+6
+M#K.T?DA;^;F.RX_IN*=&="EA3,-P^'-=O#Q\AD=2W__O,_[3"3!N51\TUY\F
+MCAB%1E1K/@/$>$D:H87H/VT4`&/.*#>;]-I8]QG3R$;-Z0Q+Q]QTI&IGE"M,
+M='H1,:(?BZ,EE<JGR&%$]&SELNQS'<4;T8]IF/(W`]U!Z_N0G=49_*?[SB`'
+M7VI%(Q4FU4B%%=Y1,,B,Z?HN-9+_4&M-9E^&D?F1.JT[+Y7V6/8M*(%%96HE
+ME/\KK?P6*%]W#D^V_#V-,]4LEZ=DN4/+TE=#C1#]O1,M'5]'R[GB?BW3`FJG
+MJ:\D3?4IG=(^<Z)]T8G4-N4KZ6S552?T91?B$]K2;D8'/*DE3%)+L)/H0_VS
+M*^^FI93Q]OFD,HY^1J>V(?'/V$3ENDST8'R;604^].]O6M.WZS%I23Q)N0QY
+M$,@QH.7XFA[KR:]4+DED.FMFF3(^4S/=0,6<FQ#/<5+-D:/EN$@KYD0BTR_5
+M3/.T3/_2T2E>WPB=P54J;V5I7$U(7*%E.J;3,_T>UO&_#K&.Y_3-1;43Y8?C
+M?;,W]9NGM6\06-^]H`'<(N&>$0.ZY2'<,^H[J"-GUB%Q%1:E_",#V=>3AM+3
+M@%/(`O[>(N+!69@ACZ7]5[BO()RR//04DPL!LRP[<+^U=6D6G]:Z]"IA^:C!
+MG:@.[ATPN)-H;.]0THTTMEBHFGNNFOLFZ:/6\UG"].B\<#@IV:(FYU`R?S&6
+M.5GZ*'`TH,<<A#98=H7R,X/*\)T2_:<XR\.W(],'C=RY*#8&[Z:H3;L*9M9]
+M>FT-JKFJ[R9Z"9:>#I0JK>=MC<9NEV*#Z:N@@=*0JP](PPP=WM3Y9Z8^A?9/
+M!'(,TQA'ZU+FX^/?SI4+^A0\__!L$I[W#OUG<V5?:AD_2RJCXULXS-\>PG.O
+M?]N6VG@YE<J?TM2NF/I6J>?<0`8M'47(J"G]C!"6:PAH@S4(+6(`(;E2Q^BB
+MT?+05`AJM/1CEL.R+\.C%/T3C\*!8/Y3SQ0U0V*%5M)KL'*5%)PM."$>L?>U
+M,=RS2*6G2L*M,*!^7\<)81IA[-V$L==#,U]*HX-S;'>%Y#VB_/U].C;U*%/3
+M5`D).RY[CXSI.T+Q(H(A?K=%Q[)[CZQXH_J4^UPW&1P/R*Z3!M=I1\3R8/U8
+M'-+&(P]*NH:-1Y[R%590]!)X[P5)(S[_894FF)I9*2"OJ#L^5A7WLI0/./I6
+M&IKM.NEPG49.Y33`YSZMC*>AC(*8-*3=-W9R96NX6\J<I2YNS2HG5UK$E99P
+MI>5<F7?E2J[RJVLXS]IR;MGR,O<JKI3]O95;>^M:KMS#.=UKBHNX6^?=P"U?
+M4US&E:^%HIP>^G,7?K5F>0GW5==MG.=6KL2S:@WGA'_<RE6W<,Y;W>5<J7/Y
+MRB+ZZ^2<9;=Q7BK=N[R8*UE>/.9\QGU!I^Y/MET8H?.9C6DJ7]2;-D)\4>Y9
+MX'?@.3+('C.:?(5G\%,=I\!S&IX>>([`<P">9^!Y`IX]\`3@V0Y/'3SKX;D5
+MGI7P%,(S'YXY\.3"DP./#1XS/,9/$W7]WR?U.0W/27B._W^@+?_W^?_?,PS/
+M(#S]\)R!)R1.!2J@G3]E8U@]?[H,P^KYTY485L^?9F)8/7^:A6'U_&DVAM7S
+MI[D85L^?KL>P>OZT`,/J^=--&%;/GYP85L^?2C"LGC^MP+!Z_E2&8?7\:36&
+MU?.G2@RKYT^W8U@]?[H;P^KYTSH,J^=/&R",YT_WXV]C2!3PMS8D;L-?7TC<
+MCK]?#XEM^`M,Y`[\+0N)0?QUA\2'\7<)\![X>V-(_"[^S@V)W\??KX3$'^'O
+M%2'QI_B;=+8RG\Y63@[I$F<KR\NX96M&V_^%0:&;DT9^.K.198U^)1PF#R3\
+MQ72'.R3>-H'5=<<$5A>U8:HG7M<RJFM#<ET;:S?RW/KJ>X1[N:JJ+;6;MLT2
+M:C=NKMN4QPD-U8WK\)!_<WTB<N.]M?PZU/H6ZAO@,U]MU6:N@=^VI:Z66U_;
+M4+]N`[>QM@%3JPOBH7G<TORM,S=M73IZ#3K\B=HGNZ7]88AJRL/NU35-P>[=
+MAI?Z[NC[)>-KQ2$3?Y<X9.7OZ?L>QM`])EYHND@<*N2_?C-N[O%WD7=J@`E>
+M>N$W-DVX&7>W^%NCM1AG@N"=T74$I]].8&/[V@0VMCT3V-C^;0(;VW],8&,[
+M.(&-[84);&QU9C:V)C,;6XN9P7NJF<';;E;A?0T$`-YW$+R'SB;!.]\.0&G@
+MN`9NYGK[^JIM,RFP88M0ST*;-]:R`&2#P)B[)@]]K%,=_,X/B>UX=6OW#1-'
+M8M)N#/ODW0YX\4F[`_`6W'T3O`1V!R',+,6%PR^BNPIIX-P[J`/H'9:]PW&/
+M4'A[):];$H:EM^(9T.?9F`Q#TEOH8^[I<^]);W=]:)308'U7KP%2I7-Y$?0*
+M\1PVIN,$?YUX02>80KL70SNBZ:'=-\-O>4P8#(E+(>2I4/X"2S[PJ.&P&WWD
+M7.B(\0O)`INQ.]WN%F,Z88+Z,=EA9]]7AL1E[.OOLZ_9M^1?8PE^+:"O:5:"
+M?VB\^H>`468EW)E:/YGRME(9KHZ8@#;B..$F>L]"*VI4AUKRL$[(4DLVQ=N&
+M+L/$VUG9ND^1C"(D$M=V4OZ-&=M?#^@XU9B?:MA'%FS2QP9O-@V5U;(O2WJ[
+M#]5RP]+1F9UT<GDS_=S1]TU5_A-L_$3:5,<IT9T^UQTR%CA<PXV\#..R=K(.
+MAF?YUON!AY\F>0=*Q`MSA8FAX@(]9EG=G7Z'.^@:"*2['7YS8]'R;7^,EI"<
+M,<3Y,Y$!MA9*KB'IJ-B[M*L7I,5IF3VRWZ2+./RF)AM^8A%=@WKRM&)RN`:W
+MJW>&[D>]\GV6DHYCS$)5=SKV*^H\YQK`:_'"`KETH..8/QVJCGNHY">M5IZE
+MP4'[8E%+PJ980+4I)OS0;7EE*G0"!)`7J(GIL_U6R3]$UI3.)-_1MR?!N.Q#
+MFC^2T(O^L<X;2JU2Z4"JX231;^/X1=!$^49)Z!==-C0,4R"7VJ328=$!,$>8
+MN(:-LC`L`M8,RJ7#4NE0U+*J[U*:9)JI2*'7LF^J&VI"0W0QE8ZAN:4-I,1H
+MBZ&7Q-YE'LFK*.A+1W*=H7U*I:-S^XQ0I<[A';#LP!6O:\AD[@QDA![0!5UG
+M`OJ^-[6RLM&CK@O-+L#X-4S&ACC$+B.T,X([IISD'V1#G&A+=&%8O'"'`&(2
+MQ$QV2J70.C[7X1]H7!+H"624I,2;\>,>]1T18#"T+":5GNDX!A0(.I6%5[,[
+M1\2A)8U3J&?YLC"D7H"="?+Z&5D8#$R"G.3;#RIIFD;9,N72(=9"AB%981#M
+M2K`"<ZCZ9,I=;';5%DTE-,PF/+(60L/LTAMM[Q#F9[6=I]_TJ$W7$S461M/"
+MCH'Z4XZ!)F/>D.:KH'HH[J<@81.I^)\D`9WK(B2LEU[3G*1JANZFE0,@E6L^
+M4;'0@E;N2H>C4U+MVV60?3M^WMCO)Y0K$S]AKO_B-O'D]O!\HVJ;0CK*C"^-
+MH0-/]R..6H$4TV0G^P3#B(Q#EGU+I(_[VMGX2T.,!BS7:,!N%M_JF,M_H]5Q
+MAZ!S6O;I/$Z8\H#CRN<CY%+<.VC9I_<40:0291Y:(`IFH*-;<*_:]AO+/H<3
+M;9.W+N+X:\787'Y:]#JJ2YOT4V#2>\VZPY9]BXIP/P/]C*#)PDR8=S!^T:GJ
+MW+`A%7HPR:_!F60;$%Y34.^#\GR6?>4Z7V8/[:#%?>($=5V]V99]JW5=[UHS
+M`?]6Z[O>-5'`D-D3+Z/4[$,[2CV^+L44T`56ZY)]ZDA'NY3L@!Y_K($B'?Z:
+M`D7ZP`I#G`Z/L?TZ+ZK#>YPA\1DDVEMUH647XU1BT[G@;,W%'H1:&^*-=S`<
+M#NJ-/8LSF\R65_1B9P]01IA;$/?]Q6EJW$\Q+A?C7HW''<,X:QC`*V2(KQL1
+M$<37347B2'K3*I2^G[L#[RST/OB!CN/A"<!S-SPWP;-2?8*N?IBHI`D"\T@J
+M[8\6A%]AUX305:T!2+2K/WIYN.`LRZEV@'1`6$PTT^$?MNQ$*X&LLX'#(X>E
+M\[/>",C4==6R*3>.CL\D:`#,R1+)/QR2CYPE*[!^4^M2CE\I^X>#&9V*D:X:
+MAW;?<16P($9]0.<,PARQ4!`_<Y[KQJ8+DT,5.C1QOB_#<=AO[-;-=;K5U^[M
+MSW?CVGGD;(K-DYGKYVK_4_G(!_ITG&6?:P+NZ&?AGTS\8P(^K&XJ+,4U4T+/
+M<>>0$_OKOY(XL=0R;NPC:J#.T_RV[L5F^*TPBN=CPE1&I:ZA.6LH,LW61Z\@
+M&QJ.].:+8,W-:IGH6&'T_[U0/&QUI+=\F'#MG?*O[U[`'+)?5L6-;_],2[]\
+M_/2KM?1[QDUGOI;C/5JO$#9'7`KB!EZ+QGMC)^0[S["^J\9`4L^TKX./U//@
+MF9RJO)3B_R.1[ATO_</W=:K9%G0Y,%$N,JXNEPN-L9[H56%Q$?!S+(:#B,GB
+M(CV?D6S+:IS[U]]/*D^GE8=?7PWS9A'JQ2=J0-L>7U)FBKV<DO?9<`MF64=V
+M/.HS4=ZX/KH(UIA7@=0.RZO)ELYJJ`#*GHDT7(O1QWK0S:-/=@W[I/0DVS`I
+M-G12ZGO[O2^I;___^_7=B_4)9N*0AE5KA<I%=`&9MP1=PX'T,3:2QBUG^GCE
+M1#__#\M)HAMO_2,5`-?4FQ``SNCR,#!1EKV=4D1\7P?D(14.UXZ%0S9Y#-(^
+M6)):_\`X=Q=N_T<<9U=_GM!Q2&J<XQ]$U(#%!MYBN_26^)Z!SWP1;T?D?22]
+M+B[5";/E$F,Y;N;+A:98#_.SN1+8PE5R)9YOV8"\>"KE(DB+.M&:2E)^LY8?
+MM4RFL_S;KV+YS30/EH["64U!;^OZ^KONV<:C7MUH8X:I[=]V1D<*:UZS/*^2
+M=#GB?KK:=^`D6.KPVQI,Z)-ID5YH(EL%.`B9]24X"&71];#DFQ@D;P_CG:Y*
+MY4\P\L@NF*5YS%EJ3DBLNFQDU-V29R`7[D.@R5>3\F,T=G(I^IVN4.Y!S/&:
+M5:,L_SW6%E>\]2__';<!F*T*C]AI9'>C$@Z+4OL:^CL;*^2?S96$T\S^S'3L
+MOEYL-J)Q=4<Z;Q.[3?@F?(*,LG`Q6:FJP7/*2MF-N(4Z2>J[-SMV(AGJ#7S]
+MQMI[Q[<AF8K7(^\B7IOE`D1N9`0G`D2%'#R;PZV+,2YCT0^1.HV>O!`?I!"M
+MY59'*:S*>,8"<GD1%8BC-*%^&8[2VF@-^C3C;\?Q*5<6_8/&I]0L%<3'Y^V<
+MT>-CAEQX=@>D`UWV@GQ*`_4YX`?9=*U07CI#'5#9\63:,MY<LD!W$68TFSXD
+M>B*,1V_Q7W[!O.OGWW#C@H4.%6YSDN#6_0X-HS0BBW6HN+:PT2R+V_$XU'@@
+MNB$<*CW5$?.G22/G_AH^\+OCQX^?>Z_K`T/(^"WTZGX2=R%.!MNOL%\Q$@/^
+M0GH+NO]'R`]<Q+7.T.Y=,+N6!W6!(@LLR"'AE..CQHG0/HS2%SD^:CK;C<K3
+MF"M4?31),M?I#<:T]`Q39M8$\\1)%NOD*1?9+IXZ+?N22R_+N?R*Z?8KKYJ1
+M._,K5\_*NV;VG&OG7I?HWZ*;%M^\9&EAU3WKUE?[[MVPL>:^39MKM]3=7]_`
+M"XU-6[<]</L==W[]KKN_./T;V_W-+:UM#XKM'3MV!J2@O"OTT,/A;WYK]YZ]
+MCWS[T<>^\]W'O_=?WW_B!S_\[R=_]..?//73IW_VS,]_\<MG?_7KYYY_8=_^
+M`R^^]/+!0Z^\VMEU^#='?ML=.7KLM?\Y_KO7?]_SQHDW3_[AK;=/_?%/?S[]
+ME[_^K?>==_]^YA_OO:_T?1#M_^>_/ASXZ.-/!C\]>V[H_(7/AD$Z2)UG,WN!
+M!7NY!R#,R';4'-0YVSN%-!CM*T$.TZ%`&30N7&A<Q/^#7HT++?LJ8I9]MD5Y
+M/=ID&J-;^_K?=.A@B.-7L<*1XJ,X#B((^<[T@WBR%*1X%#I!Z@D:%RPTSN.M
+M4/H"8/^Q]'EYL-1#OF`&<).#[9U\6JS4*G0CQBHIVRRI_?'^3:?9;7)G2V[T
+M/63BT\GAS\0*Y6!4IQIG=$OG48@;DJ?.KK`Z*FPME@IER3M:ZJR"$[$RDYP.
+MF4RQ]")(YR=`23I^JAC+$B97*!=!5K1'R5A&/9X+IM@+O#7>H"-_I=U/7\3U
+MO$DOH<?#`Q$7^FEKB;@.XD_(925K-JZG/(H-9ZGWJ6ZTV_-DPEY>*FSK_ZIC
+M9A2M>FB/WZIK2L>]#-5V2]]:7=Q@=*4R^PQUB9R\7!HJ*724J-YGGNZE!-45
+M3J0DF_V0,2W+JTUFZ:/V8W[(:55:6<ZV]^[X!-TM0*7WX)5*)&^52@/("9G=
+MI*QC`PA'7&BCBZ.M$AN9E;P+[<L(4(3D,C/8@J`R2*:32VU`"'D+R[Q:\:B9
+M\*L9/O%UO8]<O2*5XT(EMT@94HDU4F(CTE6'_GQ?;Z6JJ)3TMM=QZQ>A(1C$
+MUW7X+1)-B[3*BELZJVSGNK$D_DHFEO"3U9)E2/FCM"H[:J%LIFB&EK"[G11L
+M6W'+1B^[!I/\3P/_79FP_WU:QRPW]*._,=,87V4#M!;T2ZY!U9<R&I-&3<HM
+M[V*'%=FEH"06Q^AD.KP3RE;Q`RGQITA-1QMT2LY?"?G)"FS2?5>EY6\I7UWW
+M%3Q,=JY4;T76<]=5\^NNJZ]NV+*I<>ZZ+;4^[;:B/1.MME3A;C]=/B0#+ES#
+MEGI^T\8&GE-O.7#TB6K<!H\99N7-G3O7#A2P2MC$V]EQ@1V_8)<`F+9_YMRY
+MKK+BN7.SN'+7FKM6>>B6`%==VZCJU.:G^H)H^;..BW0,?*:93^F/AY1XZ,QG
+MR39:Q(6<D![ATA(16X%'R(@4&HWQ*-*/A"A39]R\B$_<6@CBAO+5+.WBLT\J
+M*F1ID4);HOSNPLEZEN'`#1Q:BX=\4[1\9ET\7^L3Z$=BH#6`/SHU`RDX$EZ+
+M;\Z`M5Q9B[C/;%-;VO%DBQPF5*@M[[S;HZSXJT[M=Z+L4-W=4EUQ:.NR2$>/
+MVGF8B:U;[^;XS?$[-9UW."(-:UN79/&K6I?8^;36)9F"M3N=8]_0;)H1%@]1
+M`?PET@(Q8DP4Q^"+F6CG_!G<7`BF&\\MUC5.P!@LSB[\$XO+8/WY&_8G)+Y#
+MW?K17Z!;'8,)3QR_2$NX/#J-VF0O#&J^-V(O8(12\Q>=YH!C*61F[C=NXM]B
+M@1G\[VK20^+'6+KZP6-_TSX@UZRMA](AGYV?R`*9E@ZD$N(APACAX=`+&*ME
+M,JN9!.01W0B>"P`>_E/HF:7];MSQ6I)E::^$@#H>=-5?[+X;^"F<F>+Y&70&
+M\+W3;/ALP!,;"+8:6O9=2GX;L-&?)S7ZS%_CC;Y8-UZC8XE&6SK>0@7HE(9/
+MT!H^<6R[GQI1V_W]D7':K4<*D56A?.LOJ4W^0HPB=+H]G(I/SC@J34Y%);1W
+MK.*2910N$0:]%$W'EB8AST`<>1+(UH>&*FJR0J(Q-P&S9^.8T?$"#726!K,L
+M!K/O$\R02.@M#W\+L?&%+()9E@:SK"^"&?^Y"K/[R$(&.B2!87WH79WJD*]]
+M3=RTE+P7:T#_S)1-*IYL4RE"L15(@IQ"$HHG3XD1V>J;0G:;:DPAT9+4I].G
+MXWW2Z;%/)JU/)M:G*`[*"_@B'D("EVEY^"AJ<H;P);08'39R4?V8_CPYK/;G
+MNQ2XR=+^+9QS+_1^AJ\<7X5[[*^DPT3MH8G:_F>UIT()Y.:+(,_VFRVO3!WM
+M%,92KNA.QX]KK./X@!'2:9Q_:'EEDA3"H8?A#76@TQCH,U:O+'PG#M4!+F$!
+M"[-([8LVH&;D"_BAUC;E3_'\Z`\O2`@52'>SWD0=XS336JY\[<_Q9DX>SU>-
+M0.>)?!9V%_"0\Q_XXA;OZ%5;P$\;U=I-\!+-U>9&[/F%V'SEL$'KEIH%.;"(
+M*49+5)#J"$S2QO,A)TS3OD\ND-^RFHR0F)V$'P?_%,>/-RX@*F=H^)'!\.-E
+M]*LDVO&34`?&>103,Q?>]P3*G30==,T6U?!,"%^E9:K&?7`O-J'S72-;I"RF
+M\'J"/M)D)?,4`5#S_74WT@'A1J(GS&]2A5)[2L.:*VKF5BA+_\A("CJUF!AR
+MZX`]['^;<HB'%$;)CB?6KF5W2\N(TA0N0R0N.!&G0$1Q)H9;E\P5=$6$38/Q
+MM.B<L'A!UWPMU"?M/87M/`:-"-7IB-C(%+4B<;FLT^.(U+_.R$N2>91E(7%F
+M+N$]?)SP;@:CM+68XR\+AV,+0N)*RG$/ZR-S.R:\'Q+74/17&71"XEWTNN=4
+M?/V&KHOWY=*RT)S@`I:9=&CW\,AGHXT!\BH;->NJF0U7S;'C7^2?LKC:]5OX
+MAD7(*E&(O!4R!8Y_\RVQ5Y0S:Y1LY#A!AZ()0%C:#:2(;*X(B=YKL2,--&#F
+MOBA'9TQ)=`67L*9KJ5]?.:5BI7!7R)WN47[\!QUSQ25>L+1DJSU^UZ*R/@RK
+MHA/5>&*$+$F#L2WNRP[(43.UXI]O$="C7Z])"XDRJ_17;VN5+I-?IH]+3'HA
+M5_/3]$WZ\/FWM/&46TSB[_725A-\$Q)_3:F/4+'&:$8XL09-HC4(B6:'E<ZO
+M1MDP5^V#=W1NMZ";O)CZ?NPW8=PX[T0[+:V\]0"2G412^``:2XF_:SZ#X@/Q
+M;(^.4_T%??RFCE/^`7]\LG?(=[UWV%=PV++_L'SG8)(\D'R>R??H-+\TRL4<
+M.=+(9%)H&NW_T&'C&-_*2WIHZ$/H%5T)APMB$5<_;G2U+LFW=&3I:'7>BH3P
+M5L$"26BIJ>]CA@/P:J(U&;/[>[GM;LLKWMY1)%>X6!9Q'HN=\X'&ZKH4/=!8
+MM`\-1'.J[.VW_/)MRRNNWM!V:T_?=SCMC-S*3/5AJ99=J-HP7LD7)9=,Q:(=
+M>RAW'96X+$LJ/=WUOE$Z/'H5F%2NK/V#N@J8DW4+<`TP0D$\B(BG0]L=WX]F
+MT?T*#+_J#DX*E/:V'[-T6(@!G"M<`^!VN!2+^`I\WT;,C&7GKTGV5-2#>,7=
+M]U,T+(H8=9-EUU[JRIAE:6*Y\IN3.NX+UR3^[I!K``K-ZY*.2H>[+NC%"X:F
+M#:2LNZN`E'6S7]=QZ^%9"\]B>-IPX+FF6;)KH*LW.[H(WSFN*9N]R][!KG>M
+MZ-N%M;H1[^H5)*?A(>\0';IF1E#PYB=)0RK:HO2L4_>I>Y(W7%+M'_Q.)2G4
+M%VO;X?EXGE9D%$=BPJ1HOO3Q;*M<:):-X>A7"HXYLIJO"(<=^2W9CCKC]@GB
+M5I#T_R(7FJ)93K'3ZLAJ.1-W#)\JWR;[:^)_ITOUUX1H/*Z_I@C`^C_PU[2\
+MMJJNKGY+7?W&*C2ING%3-;NEOJ7>CK?'JWC.+=2N0T)+IDY10:YZ<W4M7[V>
+M*]MBW[1EW7T-]JK&JHV;JN[95,T55:W'*XGKJM<+]=58`+[=6U^UF?.P7SL(
+MT0U8&-E(Y<H]MU".N50XE4-Q8W,U\/7".JB_P7Y/U7IN[98M]LU5M=OLFZH;
+MJS<UX/9U??7F+="#C;5VLO2SAJ^"KI2YU[`^;:BJ70_M*][8L,Y^O["%K[)7
+M;UU77;V^.JDL`63\AL0K]:.AH;H!OJJO7L=O06NNT,KJS77\-NQ\_18!*N2W
+MV-%`$;<,_F#SUF]IJN7<6"=N&T`R0@DZ,4Z3&[9MOF?+IHWK[&CUJ(&[A5FD
+MQ7[75_N@->NY5775]544@W:5UN-6?:(@R%1=7UV[#H].UE757LW;&^J@M&KN
+M%O:"/H"K?'QUO9V9O;4W;!!X:MX:]@ZMQ0ZIEG"AND1\U2:TF;LM*0TZ?(_@
+M\V%I=57KJI,&/:7=L"[;[P'@55?70W$^OJD*$&%=%?9&*PPS5MVSI9[GRJKY
+MIBWU]]G7`P+6I6;0"HOG@48)M="H=1NHTJ1HZA+K<U5#P\9[\<O[A>H&,JG+
+MK`ES3M6JL-8O0!-H4CS:5[5YXR8VO`U"'5ZEA6_OV<:NUZ[;LDG-@%B<_)[Z
+M0=)HI<:K8*5YE9H2+^]+HA.`CD<S`\-4'LXQ-KQ<*?2DZMXDE"L&&&RL92W2
+MS"HC:`"=XXW:$F\S-;OV6K6P1%^20$:3&<&9W-.FE)3RZH8M0CW@!P_S9$M]
+M53V"2:A-=`(RX,X8-1)MB7%EPN;J^HWKJC;9X55`VJ*=2*D[<47U6^ZKABHV
+MUE4GS2*:,N70LFM1H9?-<K1<5KV96[YI4_6]4%Y#=?5]B+<,83=5^WCLY/KJ
+M1IPD-$43K5A;O95GA=PC-&P;118W;EG';R)0JQ_'FP'@JZ7/&L:+0\AH;:IM
+MK-JT<7V\C]QR0$;[>HVR0#/YE/<OP"5$2K4-M]1O:6BXEKT0.%B7JK=N;."!
+M9K%XZDP1DFGULP0"(*W6IH>GNIYNA1-X:C="*LPG0KY-\"V"@)T.)H9W/4">
+MBJUJW+)Q/:,/ZS9LW+0^B6YB#032]=4-Z^HWUD''.-?6ZG7JRL)N>'-.;=1Q
+MES09>:FY*H'R;;Q7P$8OKZT3^.L`/^!'_7XY+$;U]4(=0H<!&^C-IDTT\,*Z
+M#5I[XN_4(AS*+X!U'<*"QVGHK5U?[=M86ZVZ4E]DS^<X3^KRR?4UO:;JJZ!)
+MPW'T62JU='[<=.VL%9AM=#$5EKUFRRM911W'^,M#6_'@"/5=/T(K!,-D3YXE
+M"OV65_(+.\X*/73>G,J?,'U".N;/E<[+@CF8'M"Y\5AKR@I^"I31K>.<*X3S
+M:#(XO$)X!X]OAK0BXOX@ZK9]B?^*!6/]5ZQD_BM6H_[5_PD?$&H'X^W;4/\E
+M[9LWIGUKY.)<4W!E+IZ_!;,7_I'/*&S_L_!I0>?M8_R1QIFMC".X6\@\:M_]
+M/^,</HS*__9O4#@ALZ<)$TG*DF/)7XXY6__A;S2)QJS(D!7O4)HZ8OPLY7N_
+M1[$:;T]OV$>"ZC`VY"='54G0;_9%W,!O`G_G"H=]DGN23VHV2XTYLHBN*25W
+MKBSR%)@CBW44F"6+FRA@/^L:-O'F&CT9PE6>^[TNR=S3Z/ZEZFU^?!C/W_`N
+M84=,N+:@L^]I#@6:0JE[MC"0=[]1TE7$A`%HK/*[HWB<-]QMG,JQ2PNHR.@=
+M7L77([[<C\?YN:NETD%E^#C;;"D=!+EF$N1R>(>%4NA7.>63)TO>`<=(HUX:
+MJ:C)@L+QFQ[ZQDS?"`]"O;H"M5Y,+6=`T@G#>><@B_!-;`<9U!BMICY&=WH*
+M]<^DJDF'@Y82R[XW)&^O_!PQ^3?*KMY@\0Y59D'K$""^"7]L/7^M8%9/N$A/
+MH/7\;,$`'],Q<#K\M0HYK>?SA6FM2U'27'JK,#&X2B=&]!&7%>5-S"=<!"\D
+MET+&#`B;B,='+]TMI)6?P72X6X$8%)PX)Z!]>P!-Q-7+<?%33\N^+LFE/-5J
+MZ3#I".:*Y#T#LMB$H$LAI47)=>:<ZPP)EU?(SY%PV3U?=IV!7JF2*^0@F3#B
+M0JD7FG8&JF[MZHE6H6XR`.-,`ACXV0WL&\QG:?\6M>$8*5#[LP)'M3KEW?3)
+M%/KD056G6/V*3Q.[CD4-8M=/U>(%J^-C_U?Q3L)V],+I</4V90I661AP?-R<
+MJ9Z@1B]1I2`8$<LO75:J5-$=A3'1!DTY>[C5TGX>M6>@*/\,@%0R+'L)EJJ1
+MV:MPY++H'@!O.'=G+PF$D^52$]W5,(16Q5!%>Q)4EJ2]/6K^O\KT^,1=N/E9
+M!+,M0($Y3$"4K++8275AJPLZQ^@5?EO]WF6E8V`;S`8]?J1J51?F1R>&(2XM
+MM$(GF2S[],D^GT@?6';9"-^F`.G7![(@[Y0BR1I%O1`(IS-KU'&5R`3^)Y^O
+M3WE5QWPPYJ#:`#\5R%^C-7:C\FT@@!&WE1""#KRS+#N_S=$1-#FXRG>2C+[U
+M%1WW)#S+U&<//%N3WC>HOQAW=@>J!.GX-7)S3M2'>Q!F62<O!+IRVZM,O+7A
+M"6;TJ^&D-'YF]*:4]XL=K[1"KOH"ZEC?%>P.D#:LZ,^8:0:D40++;!'10!^K
+M/U>PP(KI7H\:;":4F'MDNE=2Z(A8=CP:SV;BY\?VH5*Z\J-.W/"3O&BL'P#]
+M`WE'.Z'XL,>R;T<`@IYRY9W?$`&*3E+IB'KY(EYRX]P0:C4/AG%U&8SMP^@*
+MY3X"KA4WO)>AN*[E;OJCUH8),6%(Z7^5Z*7JJJ($]P<+M"^%*W%H!(/4G-/V
+M$#JSY0I5T_.52.G/PPH35R$9LT\V]1#1/LO^DF6HJ.4T-A:34F*E\N(QZ@\9
+MAWL.,H?\@Y*_/^(:,-$$'$9W0*56V6F47$-`-FCCQ-\O^:UXJ4FE([1JF!PO
+MTFA-0%SM'!:'=$VJ3EYZ^`"JT6FG_4N/J>L<[Y;S?7*AT8<6=OPV(U\(?]/X
+M)<G%->8SZQ05JY784:VEZ#\._1[&"I0_023#@K]RZ*?>=1HU"4N,8J<I%]JN
+M6/:[IUCVEUFETMZ\HT`RQ<-Z1T_#=9;]KM/0'B4FG$'H8;,>/8JJ+^RT%4`5
+MVXG5]P5H#03:(';VOZ'X'*[3#9=;]O?@]WF'=2?*0\5NFT?LU'L44Q<USR>Z
+MK7K+?N]IG^R>XIOM4F#]GN*3BBMLV!3=``)SM5%";Z3!TC,!4R&T-]9DC"WP
+M*-V=I&0::\.:6R4<8U,-++H%RF!$1S[!DS>LZCE5IP#S)0WU[)=QZRH;+2_R
+MTQ/:$LL1MSNVDS="\J=PC0%(58QN"]T*4_V<#F]N63K^B*;GV;J#[?2>B;@4
+MAN?L6M!J$RU,JN/V(1:'_H`KT'_Y!E0KJ=''[L\F&QH5-9P:4\,I6R*,![*A
+M+8IF5$UHRJ'J\7+269V.OTS%:_1=LMHJ/8*3#^_IN/5$C(*K;8%'<#RB&=TT
+M&[-:*7\K&9DTJQ_G0GJF',*.2F6;5,_3F,/2?AONG^\FZD%JG:IGX1<PKU)P
+M!.'#XV=[MQ*4K.(A?(T)@GAH*P4VL:_%19<+54"FSG89+!T_A4+5JEOQWD!G
+M,5ZD8V7>`--9<F]03_GD1$Y]@O:8Y-TX2Z+I\N[G<4VI6-_W*X9S7K/XK@$O
+M,>GYR7U%1..2*O*V:K6\_:IVD-A!AT/^9SEABNA_/@$3O+)SE^Q]5JK8GN@Q
+MC(D._<T_T45$KX)'__478&@6(@PJZN0RWE#ZK%2V56MIEKS[61UC@N3=S["V
+MJA58$;!/852E4=[])`6@8T]0P"[O?IP"9GGWHQ2PRKOW4,`F[PY3(!L=V<!:
+M=,MO-=IPM^R!_D^'W@N3(=CZ;F_K:U;)8Z[!??(:("8W*G\]HE-7+(Z_DG#(
+MR%^BD7YK3:Q"KE@?.Z'2?JLT%%VLC3ZN'2PLSX.%)K-2.7R$*93AK)F@`M;W
+MDD[-)<W#4ZX-L21;=(D)]]+^E'7U(FU=77HDOJZR1MF%#-F]B7Q4JVN87EO#
+MQKEQD:+_A%5XT;!K^6HD^=G)BE`PQWZ+J]>K+Z<(,F/DD2E0B/AR[CEX$R8H
+M&V$=DT1\TV24]P\F9)0;8#P,2#9^?4BG>739;I<^!HQ$?+P,%@:QU^`X#'Q4
+MTG(,C+TWK+QZ&!$*UL\!G_2`F>2124Q+34CWM:TP<SH?4#F?M&*25*Z)-$6:
+M2%.DB31%FDA39)=ZQA-@QO`W\_:-S]_L/YS,W\A>VPKQ@LFR$QD`.H.PKB#^
+MYO@+.FX]/,^HO_@$X#FHAI]\@:E*,][DSF@#T#>-S\D`/J<$F&AB;J*WQ>,O
+M@OA5PG+&O[Q#TSJ<@J!)S,DTF1@8YL]\#(_S)'TL4A:.-S%FIV%NO#"5T<'C
+M2E/'"6&KEK-=98L>W$I3GO$4AW#*NP;91/N^.H=Q'C;GJ$9_@'6I4'[<Q<X_
+M;6=W/$3=@5D*,E>L('8C^GJ^JXND0!0H(%;626XKCI22K"^:C'_?>IZ-#ZSN
+MHX?(UC6*!>5`T,X@AM$V!A;1[2JOUV!7N\]G,$9CW2@HK%E5HZ^L4%[O9(AM
+MAN+4,T4'LX^##NHKE%<Z1_73!NU:P#KY0"?K9'I8SE`[.)#$8V4GWW]^CMT1
+M<2YTM.'2U3@[]BO\C=T_7RKM5YY]$9/[)>=\=3U`>4JFG))SH>R<CRX7VU2&
+M4_X5=A#UB@6S0QBTB(^P->%%3)>A0$&1G1MBRXS;LF/W;\#B,U\D`B8=ACI(
+M+H!T&42G*3$.J#J?ODJ$!6PV.YV%T5T-JSA^]BXM'E;9"XQ)/V##Q0P^-X?#
+M@1Y94`+I[NANP#LHP1)S::UY$-=%%J['LS=+FZ2M,^K)VNDD&.4DW___->-#
+M]SV,"[A4.B`_3!TM105J1RET]"_84;EIOKQJ(4B:V(\2ZB<P21N4W`-J)Z,3
+M,#ZI?VD.[X"P6"Y!*$H#L_%W&.(%=")_?[S7E9*W7_GP%;7+V%\OZZ\?SVW/
+M<,("W^RF^<C5(JM0LC"-9D7)0D^L:3Y^V@\D5"J93[=.\>O#EOW=4K>A:7Z@
+M!R`5*SW35T9Z<7%XL4X].(?T@C&LPNOA4?`ZE02OY#V9K_^*J7V7+'3L))Q:
+M'MM/.-4T7[DKWA@0#F8R,K&?T1CX9%05S.X$%D7E0)^H6$*ZG1K2-=7)+5LE
+M_R`FO4KCXA^(5M*]_,'&GV'LMPG_5LW'_47LY`2V`PGI31^6T\#N)#EIM?+B
+M/DT7("8,5"H/'$*@YR"34HXM=0T`'7#X!^J?Q&L4377(W9Y)UD-.P.!KSS+A
+MN;Y.7K%5*E4L^X(!%6=>PD;BU?T[L8U*TT5MP91>1U>$PY(PA#IA#M<@G^[&
+M3!]+'\U&$6V8-:^R'*:"\J>#VCQ`W]@,*2:&W250>-./I'IJW^DOT<]_X9<J
+M<;..(6X+#B83-V0WQ)B.SZ4],+SS(Z/&O<M!(F']]&5`GZNPZ25)Z\O5*CG7
+M_(\Z<(S=.9@75?)@_*^.E>5$QZ&5EC!Z+64DWE28["P\M?V?_D(7]V.F?.]E
+M32=%M8&P!.O+M^PO-'I(5IJ/\%<IZD4@HL#PQ.8I92^CE((Z`"B>4=1-$)5T
+MB6#,G>7F7]">HT\6K#Y)&(;I9-E?7&(+V1:"%'ZVR`AP"A6EX;XK3K^;J5TX
+M]U`(5.\%/(X8*0S)Z:K(-PA"[A3=4-[A<H\!C\OKGD,E%&'0IVL"2=`U[)/Y
+M$AM4-A!:90-"<C&D#?@<!0T9+%.!V*67>GPK?-#[,U`4"&K]N2.AX@Q;WE'I
+M\!L?H"IHV"<[]>R[@0:C#ZKQ23KXSK="^(>OK<0Z`L31%'L(APSQIE?#ZZ2.
+M=_Q<1>I1R)+U4C*RL!WJ(+V8$GV.;L'[:#&&'58^)]:X/=;(*Z^_H`D">YG#
+M9"ER[F\:ZSF+!?3`W39N4`Q`5T"`CS5N4EI_J=X.X=->C9&88U*>?Y%4#`06
+MDQC`^!VR_*2NO/0,HU%-H[JR],741=T\0;#`>JOLA/B^Z23/R(\@7K:]R_7"
+MWPNXH<&;"CK[])C(VFL4;*F,O*7];QPY"41TA>9OVX>\3(_D/8D2F[^'LW2@
+M/HOH/ZGZ``SMGK]F)`;H%'$-TZ9B68Y4>@JD6IPJ(5B02\_4&**S8"Z>!D(@
+M>WLE+WJI]`Z48_&'<<'R]A9!#QP]PKTU&2'OZ?*0]TQYI5QIBYU`M@&/8V#5
+M/265H?S$WZ**E?#Q7UY(;1O98#D9X^TQX61,Z,$L]0=PUT&8U/9CA$3L5;1@
+M'+?[<"29X/2]_TOUO&D;-^YY5$1+7SYN>LKYQ\^P5U98DI@\@3+$,4A2OO%+
+M7=*=XZ3[KT^3/DR%<LT+=$$H2Z.0P$>5&>5TRSXNEIXJQ*3L?SZM(TSFGTV(
+M*"GE-SZMZMMLY]@=AS3%\RRB#UW<.>LVVX5L^&L4EL-?JS!-(W29&J%C-K3H
+M5M3T"L7\K';CZ=U6G_E<Q$U77R)NN@W46F8V1F\(B\WY'#\WY"YTN/'N4&.^
+M4OL,NSODIKM#LGNQY,9ID26[%TKI9'N)[EME5BAG:*89H3H#;PF)=WM1#6__
+M/G;8`5QB>JS1YHDUYLCN7.!&W49?F\\<^QM>YVS)$;*@`?8^-S(*:O\@HK#O
+MAAB.?8I_DN3[7S]E`/*;@^GNQ?7\Y):,Q57\;&#4%C?QUNB-X?`!+*K@1,$Q
+M6!T.8']?0FQ_D4N']>)JO-^8B$-56A1#PZ.$MRM:E\SF)[0NN4>PMC;K9@.U
+MP=G[$DJIF:])TY*4",>N?T]1^WQBLYD3LL<.#[FP9N,SJ4+9]`O&QT50YRTF
+M-MLYWD;@LJ,X!$#W,\K3"J7Y86RLRHFGF7S>3!>^D@;MQ:>3!TUL+N:`\VHL
+M5G[P-*(/68YDIVEQ)""0)]]L&Z\___@)(VJE9KQ^:VE')7Q99]F_V@@+E,<&
+M3%_!63<L3P4AX`Y#)?,]9,C&Z`FYTSR5RO//8Z-LR.V@FTG@LV1OMJ2/WH%K
+M^DXF9-PBIQ<Z2A8V7(+,I?*MGVNZV%[@Z>2I15+EPMB-6!JF/H,D-AW+*#(B
+MTX8.87"#38L3N].D>;0/LDQLR3<TS:PQQIKF*#=KA6KKQART`5$R)U*"]Y#(
+MEJK5@QE78OE>6Z2(W2(JF2/IDZ\[:_!)Y<L._YCDG8@SE^#*J*MVNA:F_>]A
+MQ@5L?BZ^B6!I/\4FM)6_`OV0W&_R`1/DF^T=\DFKS=)16,3[ODIK@X\V'BW[
+MW;@"2Y$W/F3^?16`O]NF&Y!<_;Z82_$Y_`IODX&++>TWZ!PN<WT&FBAY"_/Z
+M%11WU=/5O.<2^]S8`V`BY'(CB'AXMXZ_M-Y,5P"_TN?">0EU-$^)F?-K=-&I
+M+&S,U]@<E'?CV\^W_YKI%5N([0_'W>R"<(W%-3%?-^(#N1P_+;8B5UZ1&S+2
+MY08I8GC`SN[]QX`E+$.)DP&K\-=Q8/$+Z.+?9&!#C-1M:!+MJR8B6+NH+;__
+M%3N9>"C>#N^@9!W+N":/9XK_HR=I/'UR@66_SB=O=QII9!XPQNJ-L7F6_1'=
+M48]R%4PKGQOX--K"6>Q$G_6CLL1^FIK%)Q6$;"XTJP30EB[`6`_[I+7`0$E0
+M1<H][539YYXGR7B#W&RU[+>@CQK@$<7M37I#D[:GO1=ZW(<[T32&67*IU2<7
+MKQJ)9B`EDMUXE.V;7;P*:@+\<`TO<W0Q@P*6_1G(9AKQ$F,75&$H@RJ\0[K7
+MH`I(:-+/=@UX5I<K-T!/I(_QR,`[O-T3,E>"P!J&-E3JD<8!^R>G^Z3B2F`I
+MBROU&!J)7@&\(3"CI0,^0X%/XC&M=,AG6(GI*RM'1->`D97GWP^M4!-+T!B7
+M3S(WD=-E`S3`![0$"FP:\6&*V#WBDQ;@*"]?",UM+;/I1LE+Q<G^?_Y;'<?E
+M9I]4>AJ>4S4)WM[Q+-W.I",E_A*68,4$.R7TL[.F18QJHU%OF',G/>IY23\=
+MF5`Y/T`)V:^TWFL[!U.OM<IVKJ^#\700N<J6B9'+X:?)*@D]\C:KY#\#,_HD
+M4HB#C%#TZF@H0#([:`E9\:Y"F5XJ/2Z5'H4R#@*8F_6&QC:Y]+AE_V2#%[BH
+M(9C2IR1_)Z!G7D0:PG.Y<FQ*,W&P9IC\0B-`\+1OMNL4OU8N/0B@+,/!/VW9
+MO[9,+[LZ\WH\4%(Y]L;@ZO$H:W^"L@&>&1WW&3+PB]GPA5QZ%/AY&!N([X5A
+M:];(+;5+AG;Y)/]IT774*+IZ]=&%N/]U$/"F3`^%HJ=S/S1Y&D7D'4:#@H!-
+M3!`^H^P8CL5\HNNDGE0<H+25V,+24Z+K.)1V4*_"8]>%$?3XZS_IRUL"4>K\
+MP2;Y\MZ`)KDQ(Z3#Z&YW&^52!0=`]O?C<"!J/)LD;ZU-MG_T`\0-*Z"%?#\,
+MS"FYU"8OA]>3,$@1UW%:+64A&\2C3N!H?7*F;SFT[J@LG/(Y)EEV/*%'EKE7
+M*CT8$A1).(!YQ&U&0U,S_G!\$W85$$063L<:S17:+K5)^?O/X^+_9#K-&91*
+MK1W'+.T&?!.L<B.A":KQVS"Z7T?6`RGZ))F).HW1!93[-$5#VT\#NM#&!@PH
+MM5'<[M8#VQ^D;AC=,/3/PO#FP&S2^_+2+?NGAHQ>%9"=OKPN`&0%`R2\`E"-
+M.!D`65S/TC6$23_7D?,/.K=EIT>)NK7YU1EQJ4=,QSE^4DPXCE]ZS"2Q079)
+M.)[(>P1FP%'$N`1$RVC.`&*K[0><M^S(HVEG;D;77,_CCL=^X0B`VK+?N`UM
+M1_0#:FW3DSZ$9;]M&[TAHIT!W-R&N'D$(/\\MF/],_&9<;<L]`!W9C0T7B&[
+MSAA@HG>:`"`P,RKTCIZFS)AP,"8<J(C.5$=LFQ[WA*R,)[D;3RT13WI8MM7*
+M*^?I(!&&#JE1M!KGP$G"A93R8>E:NSJI_-71.804)N42*M_&V!/5WD!E?,C5
+MUBB5:C6E-B`F.I@X1_5)T-MYA&9)XGT3>A3'@9B@#D0DBXG@3R3-A^0S@Y'O
+M,9VG55;U'-\G.CAFSI5U)@O70G&Q4T5Q@Y`..?3\_0SM89)/AM35'#\1)%L8
+MB-4CGNCU.)X%DC`(?;\?J(Y-+C0".0=0&=Q&QV'+S@O(>W&5,FY5K'2.2*5#
+MJ[&MWW^:;5-;\7ST/5R_5UFI.1WWQY!H8'.^@A!RJV6E0ABZ;*N(-5FCR_%<
+MGI@Q,J9#OAO9L0[K&!6+A5W[Q85-P<)6*Z?.$?C)!B";S%1D&O'<N$X4`:G7
+MX6:'>R%9'YTFNV>AE4VY8J'4\]@Y_Y#4Y2B;[Y]!8P&K:?0RM9S5RM8L4LMA
+M]Q?H[LNHLP-3LO^?QS5#6D"WVAZ8C\<5PN6X_KZA2%UM[\1:H),KYHOG#2T9
+MD:+YQ/V4FA%GRG$7_V0:@P%P-,,^8+<NJ=$!E0)^Q5.NS/HIG>M(3D1$O%-Q
+M2SC<N@R039YDV?\&48=B-R[&%2;U1>]+&XYA!*S^VROTODAQA1'QI0OFWB1L
+MHM,4JNY/L4%7F-27X'=5<T<F^5MH]D%"`X8FH!#`7=!6/1G\F26[S+X(<7%`
+M/LK-OK;#%Z!2CSY.3I89^S[6J?8^OR*-H$^INL70N<H2R=];J2Q[BLE80!F]
+M)@/_8&%T25@:Z?K7!-I"E#YZLQ=6^V5H(\EDJ%_<]GXL`\OJUZ&+@'XE*_%U
+M*7S=5J@;J>&D@<<DUQG)JZ`!Q')KP'L4IKKL58*E1WN.67YT^,U>^M/9ET&_
+M+"_3LH@)@\KK3R)G*[V-FR$C,2%-C,7X:TFUSXS)OW^<\!\B@;?"?=++'?X!
+M_G+MS'957)8<X9A\D(X-SN&$`A\:,IV-W&J$%A<&H+8N!-@*/5HID0L!8$7&
+MOBY.\S_9]H#IA!%]P?^"8\7PY?(#YJZ87M5I<?C/6$)T1".8P_(DX#^#KE@@
+M/>@=D4O/P-@$U@9T0>_G\*,/`F_J/1-8&3:(W<8BH,.."]M_%[V-]@FG^B3O
+MA:#WL\#4H/="H$*':]`#>E61!NIHF4=<SU'4,3GJDSED58/>\T#3`I.#,(^@
+MW.(*W%N$/*SHYK=PICR?X/V2_63-?8SAEH9/:)_Z@(UT3"=[%'\ZQ[9%+!V_
+MUA%F)6-@VS85(C\EB&2C7LC]YJX1O:KZX8"%)T2FGEQFR75<]AZ7I\#D"I;&
+M9-?Q@(D@TS\.9/H),L#?0/O['1]O[XY^%2:)97\F>J!,*KQE/BN8QN>X3YY"
+MH"O]3"W]@E;Z,AT4IG=*I?V.CYK_0.A_-:`_H3%@S:T,_9?_2$7@XRH"1Y>&
+MQ^#_\3'X?YSP_[B2-?KS<?'_N(;_Q_\C_/_!E^)_Y#$2_$8`_QW"`-FE0IN`
+M8_!?<]7!C4,GYWZ;J1#=;U9.87&N8;:UVX@T>L<!XMFMJ[IB:24AVR&20[U#
+MY36<1\G"A=!MG@UL*MV%!I[+4#J\6OD8"2^P`;W37Z&MX*XWWT/#-OR+PZV9
+M0"(%/$\G.>_YU4=HL@Q+SW\373A"Z],U>W#)M!`RO\2T)%%W\0W>I#M1*`Y-
+M;QP\]IMESC7+%ME7L2LB6QJKZWV;MC39ZZKNK6Z8:[<OKUU77UW54$T1Y$@N
+MB_5_5G+_'V'K1+D=K7_#+%CYS>+E$DQ8W)^VBMT&V7\&ACXF^?LIFSED_`-^
+MNFP&C!5>4C3)VW)9AE-X$`8(^[;E850I!/[F%):RZV'L'9"#CF/H.>94I8*R
+M-@&:3G67(P7R]SO\IX1,V3L`"!"=$F;S417]EZ%Q'/\@YIB=V@@TB&::<7^N
+M-+#-$')/[QI*0S7:]WJCJ-M><%:C3(*R_4KH!ZQE(>-+87%AS-(QFVZ%&V.0
+MO=L.&?Q],1<PJ?T.X!H?*L+31_\0UE7\4K%4E!N#'YE_J1@-C<_F7RIL&T'D
+M;UX<<PV)_J'IS=DU!2'Q6QO1^*A>R0>4ZFM0=2]+A_"X;I4]9'Q8]A1*:Q\N
+MCBTK5&VY)G?1X1H0?#%@`OW]TUM^!0M*C0Y$VZ[>";H!8JUO^9PTK)`291-2
+M8NNP66ZU+>4PBX?$V'3+PW5T=CI>O05G\6(%'B6Z!CHZ_0:QDT#6U?5.FNP?
+MR/N]=)[T,=Y\'R"5N?A!%*[['N.8'R7`B.'8_(>5&FB(KCL)X(>[WDV3/LI[
+M(^73E,Y9?NDZ%>+3T?JKHRFW)3U4$9,J<R,NW-C">0,P]U^"LN(I5'@',/LG
+M0&=.8<KOM_>A'RD^BR4RV(]`?ULNAM:=\@&`?+H!TGB,VX0\_D4\4=%N]>RL
+MQ"P=]G5],($8(2C,UW&"GXR7K0638>6.0NEHR`,,5FAU#%M<F=ML@.;B7G*9
+M5>PR2&\#LI^7&Z%WG]+078D*L(CI!QFF^X<[8H*%.-3'=!JF`RB3((XP@^[E
+MO?$2\..Q-Z'BX2MM.]2-@@/?U\5)P!C^N_E;JD[^,%$V[Q`L1>6HD%2C4V*`
+M>*'G=N6C_JSA42!F.VTZYGYQ"$ADA?(^I-?H:O2Q_1BOF!XCII34;FL,2A>D
+MBJ_2TF?9PX[#SIU*L765?`YY]IOJGDDFB&E#`!QB]=8"JP<KG&7_,5AL?#)?
+M-N)#E0QDR+87:;MCN-<D;2\;B6^!#7B482)#M#,&D]`G+2Y+3OWK(^JU>/$P
+ME#_51Q:L(=?:,N0ERW`-WC\)=[N`.<>-(*S(4&3T(?.:=YCJ@ZS80A3^QS]?
+MG/E-[;S`\0I2X>:5()`K1W:3KM^>5Q8RZQV`*/,!A+H:J+&]&0FXI[Q"6?$I
+M3LYL8(<GR.V4%1U*Q9ZGH+)L-]-%'1RUJ3C&1N(/P[1TX!J!^K<#LA76?Y"%
+M4-.`6:=7</'`3=BAOJM4.3CB<`W[#60J%K=M8(DI=AI]LUVG?72R*YP&T;:?
+M)HC!->"12GN5\%X=ER<,ZX1^-/Z^WU&"\/1)MFTE/LEAV7\N9/23R)]W&,!V
+MOY[*Q`QKH=R(<5O<N*KG>ZHQ-UC/>I&2>TD*=Y!<LPU$<Y"(^1H2MAVN(6SC
+M$+81T&*;T9?7C9CAD^:#-([G?>6PZEOV=VMM[-^#HW%2)RAYN#G8"\.\;=C`
+ML;:<]N6M=;)V81&\TX@B5P;E82YW5R#X6E?8=.K&K-[7%AF*D2'9CF-H9N5W
+MM`<226X7>Q4L@&=HS;S"*!A]L=(O`JF2`M*;]R!(AZ"Y_VN0TDGO$,<7(&SU
+M&FP'OZO"-NDLX@9<3S3<B&:$\0,#=G><C@Y!1W/4\[&C7[1?/.\AVB^6A.&(
+M:X!H<9E5/8Y`C]:^M!$0HH=T31GJ;1XFST\@`1^JXH12%3@CN*51PU4PS7-L
+MO_&[;$_>*OH':)=G`&._\ETZ7I&$@8ZS_$(DI]CSW:S<70`WX""@O&W`FP[#
+M&(HQ??.E/@DZ%7$:\7S1)!69HE,8-!IAO1A63?2)KL$1!E"BXO[!T&*"-S$D
+M3!B<S<"-H`?RZ9-;S+Y5M)\.52'\H$%FTM1X\#LZYGQ[`/=$J-E;OD,T-[9J
+M86(3F1L'GN_N8OOO.$##LC\;G5,(-B2`6&.)&3A)WVPC(KS#.[3]?MS%\P_3
+M#KU.6&?9;VS2'06$!NA(;P!CXQ\8?HK[Y,="K<X[F.<=HOUH]@GNN#.KN=][
+M3$43W)M>)2^SDOUZ*[$7;$??-QO[#!5F^Q]F%0N7H[R#JB/&9J@0;R]0A50;
+M/^4`KDAD*_?`YQ@R@IQEC?<ZE69^)&LT4\Z`RFEO!X?2ABJOL]@^SY70P=6`
+M*Y<`T\SV>RJ4]QY5MT/X"=%(6,K`':(FU/,RHB?P%%NBR>=G#\H,OD`BRZR$
+M@CKA>CI;@E&%LITC!)3`H[J$E_2?Z0BM#S#\Q4_XW].O7KAE](>KDC^L9Q\"
+MS?7)S2`+(V8NQYWG(1_M?/7]$QFCQ%QP^F2;$Q:_(9^\3>_+>QN^&*:/*^!C
+M[R#5I57TWK<3%76@]\X^(Y%.HU-R]4N'=:_)?ILT#6"AGPWO)49VHOI[MMNF
+M%ZY"!F"G7<>6D=C.7`A%=J(J.RFN_81VRU*[QG^;V'SI0?P*:37ZCJ!BM,]D
+M*E`N!,`NY(`554O5:HFN#<>$;,M^+UZS*Z>9<C<58</VP3QO,<9XIV6_"V:<
+MXB@R"WDP>>!UR%!D]>#DV8]LJV)[&-JQDSA8KPW/3)'7'ZV#E73^-I;_D1C*
+ME9KE;8!P)7JYS)S7A2P(NH>@36.84BU&@Z7C*>(NK0:Z722^@I4B*=I'#7E.
+M5B\.#2J]$)1V9.LT49_T95!*MK3C5GEDAP8BG[A4+UP<V1&'_`Z$4?0;ZMFM
+M63TE0PPW/H)EVG7:):9VF4L`=P7[,%%0=.'H[X_L91JVJ"JS!G5Z758#2)K`
+M:WR`;CU0%1F*;5Z(^EFH)^DT"_:8,(0`,3@!X)"=>N11?AA"IF)P?#@G^[E/
+M`O(E`=5VKI5ISK-+4\K52%+=1N0F+?+.'.1MTS5;T+$Q-I-2>>_NG4P97!TT
+MDN)P"WY8'32@E%;=6T`E$\O.&CP(?BE'';9?8T`9EFC8*I390>(_I;:<Q+CA
+M7JW:8)W&2W^FNJ?G;R+]\U0X8XZO[=%HT1KV;05%HZ\,U2QB\R+$8UAG$:VO
+MBB'E!"@7$91QKX.:X%$<N_#F\/AP3MW;3-;O_<4.Q&<;:E:R,R^:6IM'U&8+
+MM]%I_!!&'MVMGDWDQ-757/TAEXW:NPZ]#'OM/JD(F08?=&<.67^U["^B6]A*
+M/0H_I7;):6(;T=/8UN`Y3MW?LT>*F+E;M+S;S_'`%EEQ5U>J,\EU5N+N5^*N
+M;ND9MJ,+,KE/7N(K`;8)EMYL8';<["5B=*.QU"48QB,B=ERD^-JZ<`]XI1L]
+M!D-U4A;N(:\PXG9_'=7D$Y?H&\N!VB;+$HJZF>PZXVM+'XEABG@8WM>J!WK0
+M'*Q$/2,Y]"VZDM9NQ_U_J=E$]_KI*BCT*`-KU4?3"0I&7,I/?8D^R\4=JH\`
+M6G2AD:79YPX?^R@V75B'1MJ_POP9W!3UAJ4>M`#6ZUE=`:$;T5%]I?(\2!/1
+M9>%QT\+`=J%BR7AI9N@`R@ZI>D8I.J@T;J/MM-_;KKJR:?_&2`RX)+P$4F26
+MBJQ2D4TJRB85LIFY#;4;[]U4S7_]*PP/UR=U]ROM)!NCWQ\#]$^8DMR"ON^A
+M,^4-I_%BFDZ9M3-NWL_2+N+MMQTD->*,>05YCXCK<>+*\&K05\Y%4+E8N"+D
+M>H+P\->RIK<S@U4A+M1K^D\85*_F0ADZK8P%VC'*O@!252;4TK5&JZJWL;#O
+MGVR_!<5;CS(WJ-YS>ISC+V>H4:%LQ/,S5:>F`Q=OM!5`FZ&3Y%*;N,W*\6FR
+MTQHUR2*>M\M0$YKOW8!+<T5L'XG,=W;@CGN%\MAD)E?'8L+$>!-NQ>MJ,<PN
+M7-.VI.KB=`Y6:K=Q&=*R2VK,(;'S&VBNGTJE2RP.=R&?]2IN4_8A"9'=V0;W
+MK,?.-6='=AC5E0&6@F].XK3;:E,IEQV6O)"-=E8,:W<4KY!1X<<@=;UY07H$
+M^9RN=_7E0$]V+"2R=$\@<>=K,G74S/&XWTET>P.N;!7*/Q]F>L*ECTL/Y=->
+M)+O7%=R!X_F&@O?3=\RG-2M7'>J:7.4G[:JYOXX3&K[("RN4;`/`U@?X79\3
+M$I]J1GPT0N?;"3%#HD(Q=@B(&`"XS*<D:TB\-8`!6TB\^T$,9$?TM//<$[T*
+MV/-)ZACHVM4E8$!$&W]TVXP8\_"X>MJE;32/.V+\M%A3CO(-PH)*Y3F1J/47
+MK%T)_P=MI*4.V'JE7)BCG@SPF7(K!I)H??Q>6K+_F>3YU=VJLLI6%;,C[H6$
+MYVXZ0T"%.RO^6,T<T[M$8+MSR.R!V\;>Z!!O%':V$K,7<A=[E*VPE-04XLC3
+MOH2R80<"*IMN[^>QZ6=6K@_$[SX^2=2^5W*;/<K*$%Z\M.)8QOAOB$M!'HTM
+M4&[$V"ZIS$H;T&^^*U6@Z?:V"]B.9FLRA8A^#>92BY'CTV$%E]SSQ18KNGTK
+ML;)FBBTF3*HT2=['Q1;`Q.RV%ML[T&$^$P((`.%7<HE-<IMBPN,5"I:(9XLP
+M0*IOBO'']OX6!E27>1E,F_F%0)']:>SJM/(`+L==ZJ9DR*F3BA\JAF>95&:/
+MN'/U!#:/=+2K=T(A3+(SNU3]0UZ][_35<#A4&9,J\J6*62"]$W%SST%)`@T3
+MOZD42N[%>&#;G%WH4291721CO-D+$'*X;7Z#Y+9!P6]F)5\A&*M#]HMF;3^/
+M.,K]\XG&5BI?W:7=ZYR0T)$;%E\]1>R06]Z)@5A^=%HX''L8J87\;?K+XN>'
+ME1.MC,%]&&U?B*^:Z$CK9&P_IBLOL,1*!85]=N`QF;9MDBLK..O83SMAN3"V
+M!_<OI)HML><II-2S(MPL3\M?U:U#F*9L=_%K6A7+,8!EX_E,0H<6#T5,ZM0;
+MT.2])/^W?N8K%I%WZMA;&HN8'8>/\>[(*_.I93-Q5ZY"F2)K5S'^4*%<PA#I
+M?R([\E6"FJ0P3'?!D;XE#<=T/W.I\"J5:6E_!^O-0%H>*3$2TIA#NY&.E\O?
+M)CI^0BHIE!^F,\'0$)GG'H:_%95*,#.N=/\")B@Z7#8[!I!]WSM(_)U=/(2O
+M,2%3/(0Q,=ZAKC;LB_>;&7TUXR'W%6T7,"WU>#>R<P[$Q0^ZH@L*SB:-U95L
+MGW)/$]*#<G7@*A5%4G%=>,TMCDQO_CU>U3TSHEW53:5_V]DM'0]=/$=Y`%4)
+M:[AR!7U?1B]+'IG(@]B8^!B-L>GQFV^PLDIM4%S',7Z&>-[$7_$E)<`"??9!
+M'""#,%W+IHMGT\6S74%W$Z%=-`.A5$$E`N4*7I%-TI^/MV7!-Q+]LNH:L\=O
+M172N6C]O(<&AQE"ND'&4R[ZD.5J_4VWI=#_`2%6SF32#T%0H\I4W2L(9Q)'5
+MQ/;7TW$SX]</([JXAABSGLV8=3RLQ[,8]#_:5XT<CRP,2<)@:YD-#R=(B6:`
+MCKY[(R[4"&-'T#=I9U&]/G&;WM!89-D_61K*ZW&X%.%RV75&>AN*,32C*U*I
+M6WJ#-H(L[:N1G.!NYC8]F3;M%5W]^KZ_<ZPL`<IJUG-"$0(&Y,YT:O3$I$9;
+MVC_$$I:-URPZ-C3WJ7<T65D&RTY4-=5.?_M5J6?>3E7+$I7#'SZ(`SPT8NGX
+M;YWJ#3'N7@GG%Q-]+.U_!&PF=>K$CF3]CN2FH:%A$FLFH0Y)MUX2XDUC@R0,
+M(.AV'26#.69#4RU**VC<Q;P3+S_OV:KCSJ@/AC7%/6KRO3N888P/J:>#I.J9
+MI5-MW9JAGZ]3`BOO#BJO%<J8HY;%;454&6SUV<ZQFX@]7/PL$57*>F6AWR=N
+MOU]O:"+)W%:AUGL.N-/HO6$\]A=Z29L2#Z6=Y/=$![&6_;8R5<D2]R4KC-&Z
+M!)R?[M#HYE=3.O.=#KJ_XH[.3^1M9G'SV/3#NXW*5[?K&%ZP=E/"973/&;O/
+MWB?$TY$*G_S"?=3O-+')Z;7)RW(Z3O#7B!<,_$SQ0@9O3YFG;2G4HD_!A>Y%
+MY$^Y[6GPB7!%I"U7)?N1-FT3)]*F[;H4Q*`];6Q#3*B1OXEY':MGU1?2/@'0
+M.';E=TA9T)ZX\CL$_0Y+])6\U>I#6^#6HD3I\'W#;R2M*/\TU@)L'AO*8O:=
+M_$WF8X04HXNH/H]EO['2LQKKBR!C"[C=EK1_=`E2EJW61$TOL1TI+('O8NU(
+M="U&U:+^VF6D";<4EK+)&))_Q5R9X";&63R`8?KA.;AA@A34LUIY3&0R-%HT
+MZOLA(*?\3>HMJN<9FPQ%>#XEI=.KK<F'CK$;,W%'>H3L3CO->3V8`>5^%U2R
+MMD0O_PJ_-U18T<?M5/BJ!'=?4`&SPN@37<-Z4MEV+&BX8G0'$KW%`WW+?F%8
+MHO:/TN5.WA_\ND!T-N:>)9?-PFVELEDSRO)Q/]Z=(Z-VW9L?.E[!A;3E;D>S
+MK66V[+:%;&BOD".7YH.>\M".4R0X21RG<F!VU+XML]488XW9RC4X.Q_!+)+Q
+MI93S&0_J_.T@1HOD-]3L\R@?MZE"DJ/"[I^$TEOQ#F!$'RF6*NQXPETVIV&"
+M[)XCN?,S@=.>0S-LN$*9\&"2=:(Q_O]X$M9AR)0930F#\W,JZ4)$A?*+;720
+MF#?D`6G`N,"CW/D`;0_$YBDO-[*-X'EHY&YP+-]U!<_@1]B@R:HSW',<[EE^
+MPPQWOLH]C>%CWVL@Q@FOT=B4=&P4<:),TK^DQBBOR@$V_<U>C]+7&-\^$-3Y
+M+.=7*N\.`J8Q:2Z?P=-)=M>8L2B\"C[LOS8LE^2@#_LND$5Z0L8=L!3*WV9C
+M$73"(,=V$N"]9L<;VT^.\FE7P;:-@VY#0!=TZP-.^*L+./7!](#3$'1G!)S&
+MH!O":4%W6L"9'G0;`\Z,H'M"P&D*NK,"SLR@.S/@S`JZ30'GA*#;$G!"69,"
+MSHE!]\2`<U+0;0XX+4'W10&G->B>$G!.#KHG!YQ3@FYKP'E1T#TMX+0%W5,#
+MSHN#[HL#SJE!MRW@G!9T7Q9P9@?=EP:<EP3=EP2<EP;=V0'G94'W](`S)^B^
+M(N"\/.B^/."\(NC."3BG!]TS`DY[T'U5P'EET'UEP'E5T&T/.&<$W5<'G+E!
+M]U<"SIE!]\R`\RM!=V[`>770/3O@G!5T7Q-PY@7=>0'G-4'WK(!S=M!]7<`Y
+M)^B>&W!>&W1?&W#.#;KG!)S7!=W7!YSY0?>\@+,@Z"X(..<%W?D!Y_5!]X*`
+M<W[0?6/`>4/0?4/`>6/0/3_@7!!TWQ1P+@RZ%P6<CJ#;$7`N"KH7!IPW!=U+
+M`\[%0?>2@//FH/OF@'-)T+TXX%P:=-\2<!8&W44!IS/H=@:<14%W8<!Y2\&)
+M<#A8_$A)H/B;Q?#KAE\7_+K@UPV_Q?!;$FRO0+,M@792G(*W(^P-(XO$"].;
+M7P$ZHNDLKR1WBB#%H!*B+N@:P?%V?8[C[1J&`6?VN8*NSW#871=PV%WG<=A=
+M0S#LLM,$M"#H.H>#[SJ+@^_Z%`??-0B##T1.<@T$79\@"K@^1A1P?80HX!H`
+M%)"=5N!7@JX/$1%<_T)$</T3$<'5#X@@.VV22PFZHH@.K@\0'5Q]B`XN!=!!
+M=F9+KC-!U_N(%*[W$"E<_T"D<)T!I)"=.6C1S_5W1`W7NX@:KG<0-5R]@!JR
+MTRZY3@==?T,$<?T5$<3U%T00UVE`$-F9*[E.!5U_1C1Q_0G1Q/5'1!/7*4`3
+MV3E+<IT,NMY&9'&]A<CB^@,BB^LD((OLG".Y>H*N-Q%E7"<095QO(,JX>@!E
+M9&>^Y#H>=/T>$<?U.B*.ZW>(.*[C@#ADIN-HT/4_B#ZNUQ!]7,<0?5Q'`7UD
+MYT+)=23HBB`2N;H1B5R_121R'0$DDIV+)5=GT/4;1"77840E5Q>BDJL34$EV
+M%DJN@T'7JXA0KE<0H5R'$*%<!QE"R8!+DNM`T/4R897K)4(JUXN$4ZX#B%(^
+MF2&33W+M"[KV:ZCEVI>,5OL3]@W;^D]S*?+BA[7HC6MQC'DV4KYG`E)$!NO8
+M^1$:I@H=6H]KM\LF=0^_B/LYG_SH7`=&H<1GZ?`AST]VLSA^ADSVM-(X2+J9
+M&T'W`B60?)9B=9:.192WCO).9@&=Y:'<=+8^1CHP`@4?9GZ+$ZZ4162*I`ZR
+MSW5H.T6:9?$,19)I,W\K)U3*U&3)U1I=2?J3]!$9]8IT;(AI'L#6JR'Y!<HM
+MM"8J3"XR0JW%C&W^5MKCF0@!4I3MV);&<1O""*G[ZE`:1L"IAS<'M214KOPY
+MKB9[,3521+[6(D6+2;826J7ZE9$B,CTL4[>DHCODO5BO_`)FD2KNCK@WJ1N4
+MZ5A)1&HVJG<$IJ;A#N8NQF)PK-<.]TH^BT7BW5W510S5+57FR,_AI2NIR2B+
+MN/LME9CDW;3>5-KEYTY2$L"SAY*L\N[C.F:DZ[FCE,1LRMV%=V+?,8CG=9;V
+MK0"&EBP0?J?T;89@6#ROYVU]]QA)#B)PM`:P*84).W1=]R.DBK&'K%5%BU6#
+M=.BD$;AO/+'!37N]I>,2B%%XU-UG'S"0N!?3)<YL2&0&X/2X3<ZJB]4M5F+U
+M6@W:?<]_&M!@VA/EK(!8XV+EOY/RT.[A:P;<G>_AA"RR'-!^`C>N<D*N=@]K
+M9JQ^L3*W%O?%L+7'++L>PP_.YU@ZV@V(&NWW%*1QPD6L!I$N\W](V^`I<`"F
+MNUW:BQ[8@AWKX&_`U1[<>P\&O!W!CBJ*V1&D#`'O3ED(2"_<09GOHJ1`<._7
+M*4D*=MQ),<'@WCLH1I:%7=(+MU+FVREI5W#OUR@I%.RXC6(>"NZ]E6(>EH6P
+M],):REQ)2>'@W@I*^F:PPTLQWPKN74LQNV5AC_2"AS*OH:0]P;WEE+0WV+&:
+M8AX)[O50S+=EX5'IA964>14E/1K<6T9)CP4[2BGF.\&]*RGFNRK8+!V%Z-O)
+M'S!8.FY$]5G7KF2:,0.MY;EV`<'`.T/G7(_>193&3'?!H--DC,C[*(-S9G@7
+M2;UAJ:Y0=NU1<>S!5F2Z:\,J91+R<:.8)O;-N/_9E*7.<BBRC64!-KU1BX7P
+M62(7Z,*=!ICAG9U5&2DLI#G=VJK.1#;61GDOGS2/B\5#1'OX67((XY=WA/"=
+MOT3>B[]%,I&F<SU7'M4=EBB*4<^0N=5!.1O2)?J5U40LUN`IEMY8+AUEE12<
+M.-=8+'448G)9L=C5+QV%J!>0JC%<]\GL)^WCF$]R+_.)S<LN;TKW1=S+KN!B
+M+Q3&YV2LOACPO893#B)SVZ5V81*2G6/L*OQ9HC!Z86I%[+DCR%0_UPE_5RMB
+M(\F6,?I"^2W'?(0-Q?C-LBL;[Q78>2NK0[74PY&QRG/=2"0@B7K5%F!)>KJ%
+MX!_U@9&3AJ+WI)XIHH*/]KZ*5@Q:PWB'.A_1J_:$6*-1D6N8C09&JK<NCD$T
+MD(SM+%IMMJ^&-!Q_E!U+LO>7*A]TW\L<DC(I),3'#8SQIAJNLF\G+2+L#'"J
+MI0-EKQ"(02QWI9"PLU>OQMTB)'R,?1V%4.'62#H[5TFV6@!#9;6Q&T%%Q6A8
+M-.+&:<#!@*%E%==FU(AE8I/2V8`O:OG/-9!IGJ3S(29*K"WU%"\OYZ[C-]=Q
+M,QNNNX>?>RO]T_@#<ZJ_TM_[T#MDVF-H[F+K)K)<DAX2S8^1;\S)^$,^+S5'
+M:M=N0G8"W0E2G7O)N]Q>=,-6KCHCK-$IV9L0]O8*9?HF!A<CWHO(K%`R*`'O
+M9)+GMAJ#\L_[R)K0CQ3-W1@;%Y"JC`:]SK+/A59G^2QQR,A/I+WY`[A@'_M-
+M^`"NU_!;T#E*/ARI'M]VHUB?9+N1H7J&[%[\9;8;&9^>K/^JENVUGFTEXF]I
+M?X;HG)D3)I4KC\*ZUO==V@(-2][G9;W*W>N1NR\B[KZ(N/LB@URD<?=%Q-T7
+M$7=?1-Q]489<I''W1<3=%Q%W7T3<?=$$N4CC[HN(NR\B[KZ(N/LB"^"1%;C%
+M?R%_7T3\?=%DB)OB(Y[_GX$BXO.++K+L+]+,,$"!8N]T`+2E`^=WP5F?8\0B
+MGM`Q_=VWY-+G?7+Q:AN4\`'*!1!$P:!X]<6H+F>37M,=QJZ25*!'H0"[^@_J
+MZAGHJGC8B,DD%NA1*L#D=RBYER6?U>OYQ468B:0#/0H'F.DOE.ETH@P2#_0H
+M'6#R'RGY%"3[W-CB!W'!ZKM,W<=$;L.BB_>&Z:\E]^4ME":H+V^-Z0O)$GH4
+M);"B-ZBBGD0[2)C0HRR!R;^CY.,L.9@5*#V`9F3;D6(4G>W2\S?A)R1AZ%'`
+MP$^.T2='$R62B*%'"0.3?TO)1R`YB(7I^"5J-I(U]"AJ8+8NRM:9*(6$#3W*
+M&IA\B)(/)N"#!S^AZJ<2\\R33/_N&8/;G4FX?1#"?;_4</M9%7O>4`"0!Y+P
+MYYB*/\(!"_JB1/W#$;GT6=2QC@/WB^:$V@F:%7J:%#J:%'J:%*F(0I-#3W-#
+M1W-#3W-#*X-FAYXFAXXFAYXFAP&:@NJ[-FV"0!!G2/&VBQ%$T.B=R,?T?24)
+MAR[5)7HTB<63(0SLDS/>)Q*8]3@ML,(^JE!)M.=+Y@8BS//C(,R7S)<OFRE!
+M+"R!,%\T8]1DDJCU.`,P^0^4?!*2::8\J\V4$S@;:*:<P)FB@>I3W'HM?18W
+M,6A"Z$BXI@GAI`FA;F(PX=I(PG4:"=?I)%RS30PF7)M(N,XDX3J+A&NVB<&$
+M:S,)UQ-)N)Y$PC60.2>2N5=(O+:2>`UDSHED[B")V5-(S+XH5/UDDJXN(K@5
+M;SAZ8P%KT#L2\-"]1H\^Z!T.>`RR!V\NX-U.CQ$O=WK2@M[S`4]ZT#L4\&3(
+M'I/D'0QZSP4\IJ#W;,"3&?1^&O!D!;V#`<\$V6.6O`-![R<!CSGH_3C@F1CT
+M?A3P3`IZ!P(>B^S!JQ)![X<!#]3[KX!G<M#[SX!G2M#;'_!<)'MLDE<)>J,!
+MCRWH_2#@N3CH[0MXI@:]2L`S+=5?3$+_ZRYV,>Z!'-)E0"-M3=;8`N4[L*1&
+M2C0C;6=WXF36\9-#)39/I?*739K]H"N9);I63K-$QUO@XQ?8"HVJ2ZJ>P:VH
+M-V%'9JO)KEQ1Q9);YE#$'&6B%C&?(N8KPW<S=JQI<:4R<#>S$:;<C2H\']Q-
+MV_9[$S=W!K_H'M2BKX]O]_?5FE'VYSA^VIBC=^815*8U7NQ=(0Z9^*R"SCZ\
+MCT?V%XF31Y-5OTOPLMTL6L=7HJ&INKO5DSA4._@95FZ#RA^H2;"$CT"V2C3O
+M_P^@FI;][FR@I,K]]ZG7,[.QR)G`ML%79N)#S1!:H26C$;,,)E">T^I=H-5B
+M2]1B:9]#LFTQ5%2I?.,>!.:0\MV[B".$K+_:B%`:3BAOCM'=_/@.MN>-9_P+
+ME!<W)LP0K8RXSJ"@%G$I!N1L2XJ!/9!+"O'&))G)1R<!WV:F_)[@Z%(IRLYG
+M/!7*QU7$A4*!^1N)!=5LVYT:=7V(Z\NH4NW7H97!<>S;O7^WFG['N.GD/VAS
+M]>:&:OZ+_0?ESQ_C/ZARC;P]UVS95YQKE5?FVBJ'Q?.6YMS`$>EP5Z\ULT>Z
+M<.Y/XKL&Z7_RWI3>^.1IZ8]=??I/?B;]47S'\,G3M]Y^URA_3W%H/GE[PI\I
+M^KI(^"]-T?^^G?1^.X[QVV2QGV.V[ZZ,;B*]$GR?O5`:ZAK2RUZS!'\&0\7S
+M=%%/6#K:ZN!X<[AUX<U\>F$K?/-IWE$<!/I&7AB=B3H$@ZLK\/QM597J4&<(
+M?:I"(:V+Y]W,/X%^A1=TG!7>3C:\D/0OE7[\X6MT6<'R2]0]]-^I<NJ`W!D5
+ME<JU=^K&&E2COMX:+V#/UYAU9)>YH[-Y=LAK\T5<SYOT4NE34NF!99+K62#%
+MY>CUPO641SE#U.JI;CVGXHM\YY.C#5B-@O?\KR7@C0807\+/8$8:\("EAZ`_
+MRN:@GKID0BT;M`N83&VN[,;S)*980_5L2@+%:[?1/%$RL->N/=((>D?-#Y-'
+MYPO1JP_\[OCQX^>J]W1]8`B9OQ4REN)G<ND>5.M_-.AZU)@?2)>\>\I:E]S*
+MOQDJTTFECSM&&F\.MRZY3K@.?72[G@#2^[6JN&(;ZC3[9-=3OIG<@.]FKM#2
+M\4>(Z4Z_+FHJ<XPT1=@Y/,<7D:N%#?HLU(KYVM>Q<8^2MU/:7]M^$3NR_1E2
+MMN[TJNC_Q'67Q(63^;P^W*QD=?_U;DVG]:*X(JMVAS):*PN/R[O)N=#A^=CS
+MVUN7/""D0XGNZ(#EE72`2$<G^B3:H^IT[SGGVD,^B:8`$()K@[JN#_3BNSIV
+MO_5$QPE+1RVDCJ3W+8@EV5"+<+A1BJ@92-"KQ-UQQVL-Z,=(=Z+0\5K]^11=
+M-!B:@F.`JBBKA6S'0K9O6O9EB)V]TAL%725E>/&^[X`N'(N=>Z?K`YO4T]4[
+M6==#AZ7#>3WHH5;SND9G;*4FZ76#8"XXX?B(GQ$.!W7H;,WH^*AIZL83?US<
+MO8[Z&-JCO_DWCL<='PE_`TP3AD??Q7RL$K'9C*TRH3\+U,(*%65(D:X/#>*[
+M&>*%#,M.7%[(&OT33Y$U^G"X$+YZN4+'O0[/._`,PI,!<9?"<RT\EGU34=\O
+M2P=_TO..ALQ6]_\GHE99:".3`#G^>:]40;2DX`12OK.6]I\C/-PJ/-[+$$<`
+M'H^I\'CNV9^J\,B'K_[@U7'OPO,A/,/P9$+<5'AFP(-#F:;KL>R;K#OL_#_X
+MLDK8BU;@1U]_':OW\4-HH'H343WW)1=.,U!CZG[<Z*';N<UF7E]PEM31[H#<
+MN*L0Q:LB<E'VLAEH#V-(+LI!5?:N-S^4'\3->MEX`$F]=TB>'Q;?&Y;-8?$=
+M/=V4H[HZC@EFTODC'4'T-C:``:#TMR5VX5%ZT%;W7.3M!K!MVB0G3SV-9`;J
+MW7M(-P8OQI0BG;%RPBVR?SCS'-9?.B@M_B;:.T(K0E/1-F6Z7&:4=&1F'+<%
+M);>Q+8([@](2/*7_]1'2(S!*^4A>SR3MK27S<S5K=1R[E(;KQ8N=I`=#-N.$
+M]+,E-A._NB9;N5"16((N4RU>O(=Q)5;&,UDKE?^J0(ZC;[^F+V92B[&TWXE;
+MEA*^])73'OTTU/.%]E<:Y0Q)+[:`&)L%=1DM[?.PR956G[@(%ES+?CV(.44C
+M(#<,0[*.SZGA@B4VL=?HB369R1C=;56:.F([%L"7D$N`[&52]XPFL^S,D2MQ
+M*#_`V#8VFF'Q11HJ_F(L$OIH?%;/9T;@+^)"!@00,-((:AU;VG^(]%MVF]2-
+M0:G[K!N:V8$7LBS[297.46866N2*\9KLAB9?QFS^#5%K?W9WW%#I"9AG9"@5
+MUA:WC9.GXD`!2"I@5"4]M1>'`B]PPVA36$I7?^N,-*IB,[20SBIPW5EEUNZS
+M(MJCHJ"TS=1=8N.B1OAKI!()24J,;5U4C`7I[8N$)#`<"Y&EB-L-P(W,T*^I
+M!2ZSH<B\3%YA?7-('$KWIQV@R[$/XG`R%)-8/F%XK([UQ')5([:3$&I*'QJT
+M87NB?6C;'O!D/R9%:\F2;3I"EY]%/;B*P(<C[F8CWHB3I%*Y]RYMQ`_0.CR/
+MQ!"R6INSELDWJ;"L4(P0S^J!U*@A+-\8VHEOCN[_A[U_`8^JR-J&X3X!#31T
+M`Q&B1HT:%`0Q(`I!U'!(.$@@(`%TT!"2-`GD1-*=@)(0;*+9-*U149D9G&$<
+M5,9!145!14T8AH.B!D0)"A@0M4.B1HP0,-+?O6JMW>D$G)EGKO?[KO^_WF=#
+MY>ZU:^^J6E6K5JVJ70=W>;OU,3-X1OC.6!X'CN4"BD4!6:D#.M7B'6]!+[6'
+M]TG%\S2+EFCAWYI#$!'C29/D1QM]-3[4_D_D?M2B=EW$HGM"NXC05$97U_S!
+M0*MK`!K94P_Q'O6=]<[C^?.;Z^:AV\#>L2Y[Z&33^B\K=L;M8@L)M<-""QQ'
+M6>R;B\;'--H?Y.VO;#'YEL*)-'ZNENU9[]$W<G4]XXMK0D]$#BN;;YF1Z'\`
+M2G>^A;XATF:\<<V)_CS<*4W895);?=O0WU(KZBW>)(=YHH4.1(NI*DRAT*?-
+M]&^8W;I)+.V:XJ-=80[MC*L-AG^5A._@\/V)?@>';_31_N$."A^<3+"8::XI
+M!6Y_:%1`?4`WNOM1EH8A2V?/)NML"W_X7%ZC=K&;&>[4DJKYH!?/TD3:YCBN
+M)E'.8_$/4MOE[>?YLY>R#V[?J6S0_1+0(VJ,9;^W,TQJ;])^)Z2!PJ2B<L>J
+MC4?R]4*ZV#LN+,;H[NF,F1GNMGF>I[OGZJ^3-85;D,92=$W89/R;4J#J_2'\
+M?J2KOWUS7#72L&6F__E@IKE[Z2^/P<MU]`V/]*Y#%:P-!>NIM-$6_7N\25OL
+MFT?WM&_.=_1O]";L\5298G85])4P]P3<NYAO%(GQ=SQ_STS*FG:-]\7S06S5
+M!=>KZ;#H-]![WJ2M_;?Y;$DD2U,1OF_L:#F8+?=.Z?]L<7I&J;/9JK6D[6KX
+M9T#<'J=&PT!CIX;9-R_L:?R(Q5#KZ-E!$D(#[_1S1<*N\N[Q$!RUC<<,?\2=
+M:OFG>2$])/>L=_+Z%!2=.P&1>19;#>ZK[)M'\=#G^)BX[>Z;=HY+-"ES/JG:
+MJ<V<57\%Y<\6VCO3?;%3?7_NB4?47,B=XV;1EM/:N.DTFY$R]?N[:.E!6!=8
+MTDG[Z=P(;5R8$TET:N/"2]5Q'U92'AM^8Z_#G@G2WPD43@_<[*^YJ_40('?W
+MG?%J$D+=0=:!Q4U:B=7IG3Q++4#6)MOX5#W8(>9Q7(IH_.V;IZ((:6O7YOYG
+MD=4QV^P/T)QG3TFBR1V+-LJS"%E09-\\@Q;B<29L<\_SQ5M)>&?X'[Y;%@24
+M[5LRU65Q!N)M:HV_%C^K_OH*];Z%CF11RRVB@Z_-;'UMZ27.G?&SU"EQJRIA
+M#GQKI,G!,7BT_B+AB(]AO-G_RBS>MB38TZU[*E'&$V@6]@7&&XIT_PX7]-?/
+M*\Y)S<Z3`8<;SQ]P&#*X_8"#.J_8.RG*YIT>Y2C;I]9TQHZ:Z%JZ(GSY%Z[L
+MX1>[,XG,4^2](.\F,D614T#>0>0T1<:"'$GD&$4.!GD]D4,5>17(RXGLJ\A>
+M(.U$]E:D9?C%KG+[&^A&=.Z_ZW?_H'5);0],5OS-O2\]/_>WAE.&C[BIW7',
+M/)8"YAPM@RMI'.72?SE\$C)ZTJYO[IRHN@AD4+@N48L)+DXTMOL86M]%WS\_
+MN`I&?;.<U?:;Y:43@]LAEQ[]%?*\B;^?=J=94K"MM;CMWM$#H41]9>OI^V3<
+M>FCFG7$;Z4/FSKBM#)44&.LD7_'ZF?[3K:LOE]AG^@_=H:SD#FJ/M%-QFV)=
+MG1!EZ01;+`S=9]?\\IO?D4LF\*@(;0=)NQYZ`EU<5RUU>`)6^W+:.;[N554?
+M/0$'[W%0]PS39SH7=9U<6A5=WKV.SC%;=@;Q+BV\<C(//AREL0?+8\9*ZM16
+MJ:T+6]2PP][WYCF=SHJ*R=JNTS]4G36A[]9\!=3F!9]%1^)`_:T5D\MW176R
+MX4Y5G=E]4BV\[#<RVA4U>4?':%JK@K`\M?85%@<]87$WTIZ>_JX)JNZ$'CU]
+M_OX7XX/;;<1%J$V)F\K0/";RNO6I,_P?T=8VDZCQ(:VG\@4MF7WY/LJ(_G(?
+M&4/[J=9=3#3>'^CNX#G7N:AO(*$)AFZ7F3/\G1+4D@LUWMY0NBT:FJN\1]V/
+ME)'+`BK?1K8^_/DD-8'AO.?%^Q^AWEYW@[>XL?7=;Y+^Y;O?3CGO773**LL"
+M[JVTOA3A:">U,Z7'.I6^S^_9-YPSHTN,A[["0U^J+1EO+8V)=@V?@+S:88RN
+MOZ%"WO,<LZ^PT0!A>1>\9:GZ@<[@_AIO':5E"A7^^^_@]0QQ3?IN%!-RG(;)
+M*9,-T8.'W#CTIIN'#8])F9N:ENXT],MQ9V7U#[D_:O28L7'QAFA#]"##()D7
+ML,34IHYMCN>M3!*LIT;9K*Z.M/S8?0E5VZONU$^7Z<JFX+U]^+QPM8V-Y]@E
+M3L_9+F[JP3D]B[L;EO1`)9LQU7]C"QZ]D1ZMT%X?25\BDS9H3T33:K.DAN#I
+MH]RW+NMWCB?HD87G:_H51H?WB9%J8=I0_+6_VT7S#<>/LMVNOC16]@X1?5T7
+M!\KH(7[4_FY/[0GUT#[W$:^*<<#K]+9KLE>%XO6IR'MH"RU&=Y.GRJJI&X$X
+M=)P;.Y5<%7B=(E9G(_T2G%1V;V]*U`9^U/@ZI9-C1S^N+_PX!3O+!I[3)R5:
+M@K^B@K\BS_'\B1UE8^A>NP0+%V7TVU-9ZVF>97^H;Q=HI\\'K/(TT(9LQRHJ
+M-HXQ&EI&L%L5\KN]*X??;/'/`";*[PVCC8:U_X'[K7#;NS`\&S>*?\\:=;[_
+MG)"P%MUVX3#ZW=KZ>\W(_SSN:(3=3>(G1_%/EWOZ,^/EM^5VHV$AXF]`7"/E
+MWGJ)]\J0^%<B_M)W5/'8RWYW3B^KR+HIR@2N*/51$1OK8JF0XAP6M6BN1?-%
+M*;&T^T@R3A]DFI^UU(4%@QE09SU?4+G</6>O<U^GA[BP17N=A,5S+F#W??HK
+M298N.W4[J%I4##[E52][ME5[SG8NBO8-?4-[O>%7"IQN^USYU5X?1].9*XU$
+M4U6-)J>P.B3\%6W#OU^%SVDOK9L%BM9N_L_#IQRH&T2!<5C6.MNO>I[$UAF"
+MOQUU32WZ[\@Z?PM-+TH,UGG)D1436NJ&=X(2D7>\3Q"<VA;I&H$GK.HHYF;M
+M"96[4UNT)VRJ@M)?0W')Z:?IOD?=-)Q^FH"FG55X55BGJARNBU0TZ"5,P[L.
+M\K\QQ#\VZ&]_+_A`3^B?D/)WJ`@=*L)NIY]V!(O\^BWT$:SN\0XTEXTRV>#N
+MPKE-?0.^%=!OT?"'SIK5U0L1T&#+%YE-AY\.ITA[5"ANDQR'1S?SK<#K$>HO
+M_?9?.T4?[A]X\/M#RO_+VM+C<>Y.DA;?XX$MYR1GWZ,/@'4_(UUMPOABLAY&
+MN,]K?A-/^UJ?WME!G5VL\H5Z_;XGQN+7M,#K2B:>&$^$[XDI?&^@"C2R?2*'
+M]*!9P*IL::$QO3G/U9E_C'/?ZGF'0FDIZ>Y]@EZ-48&61&R)4[FEGG9WV))N
+MH$"(0JNX4_V8%WP@?6E"P#=>Q:@$\_7QJMEIGN9_2<5-]5';:7YG[#F>6*Q^
+M&.V/J//"I<R-]N5T-&'=`\%0G>Y;.&V&DFN\ZH=>GEWU(C.Z9GI]=,^W),98
+M?X=7^7MVFNIC*[QE]$9,&46UM*>VL_65J/HKU9KQI6%>E9N>;2;MP``50;VU
+MPJL2-Z[TG2G<V,3!B)7"K(NQM*8WTG6E+L.C6[Q/D!K2]E:=N4)ST.[B;S2K
+M_GM0WB]NE7>O4EE:E[K'^!E)5ZP\H\3;R0$ZM1YU6<VA>D\BZE&7U!RLYX[6
+M)%TNTNJ=V*SY5-V<B*JBZM^=%:UQZ?4OI"IQ_0NF1?>W;PX^H->_D$JKSL6J
+MNTI-5FH?H#K_RO=X)Q+H)YI)C[&"._IEZ6Z3IGZS&-$AQG5'C,$P)'R25U@4
+M-I\W/%@GI/R7W,)23M,;Z;:_9IR^14*8MG/`.W0O1CUJ]RVEJ<[J=YU+I3.Z
+MTJL>:'F3E._)E[3W3^_SW1>HFP'?\W3=Y;^IZS@__^?Z;/._TF>LN?:I?HKO
+M\2N"64=S='U>E94^E97!!%[VVPF<]O]"^APAZM+H&D@IZ.-YQZHJ91]1_^[N
+M:OZHZ&97)\Y4DVZ"J>JJ^<A:*]N]I,NR9\EW:4#,5+87=7&>HH?=4P\;:DO9
+M>:Z%@==;<\)SS#@MD64A\+I-_:7W_-M/TO1MUGSA];?I:6H-9<!OAD(/^LM_
+M;'T_3#LQ0"7/=]\&RKR@-?I45U++K0WH"M4XE_OHCMIT1#C7WJ%!/3%U7%;?
+M3",=]QDL`Y.KLV^F27O"H'+`HC*I1:6-[L3L+>ZH/4'T*67R+K>7;:&R4(W^
+M@-?)H^R4_6$:`?6<<Y3,)'G9$$V%I6SO+CM'6ZCL/'%-#L\V*W<'+F"`O_9#
+MT``_W"7$`/?L:$2P2__N>UP%^A\;]*FMX?DH/+TGHN?"#-\38\ZU]A!VCE*[
+M'07BS@O4_O#+Y!$,N$MKP$-#$UI';4A0CYE<2W:4D>$8K1<*&53E[SNKCEF=
+M]C=\L4K',G1^@L"GB)!<,W&NF?Y5KA5_'TS,\YU#N.1D+#M&'T>6G2TUT+JG
+M-RY0:L](J27YO%O_YV46^"X8>__.%RRSK?^C,GNY-;R#UE!N7K>H5),XGB=K
+M_T6ZQ[7&L]#Z?R#=IQN"X5W9)MU<P?YI=$=Y52NBIU.[SV(L;@HFL4Y3:Z_$
+MHH'`@3SX_>$RLJ$^KR.S;FQI4ZR][!>E`Y5QH<R'I1<'-:*[N\\;#2U=-\&L
+MOIOZ'A\"*D2Z@]+T+_BXH96/NSJUR7^*;3)E_;4=.>MG5?R7>?]!?3".GSO^
+MAWE?-\?,^:-,,OLCM&^^SZL8_)]5E\FMD2\*C=RKS,;31XC#OXIPS:AHFQ3D
+M89"_?Y&']2>"45S4,20/@_RUR30M7\G6OTCR'UO#^V>'T"2W$2@V)R6I4RU,
+MUHVQ\#?T$'O4_LA$^N#X[U\V)OU+D;>T)FM0A_-R<H`2&,K-9PTA\O+?Y.<?
+MZUKYM_P?R,\[6L-S6T(3KM<D^_(QM/#0>U-;\=);AV"=/<G[X+2MUZ,M7#\I
+M]\KHGO4"2=CE#R;AI+E-$M2KW-3_N_@O$&Y>:[A_,/\;41F@X@J6^05*V_[P
+M+:;0=J]G:^@CS2$%41=&&2$=JZ7VD$Z5VM^&#9.>Y:J-"RB+9D?9*/P=Y%.W
+M_H<J:N6WP52\80KAL:VZC"MMB74-;<>WCU(X@7;[3&J::%:YH`6+J4XS<%UI
+M574_!MO&_T9NO_HFF-!NIO]6;A>VAO=X:WCO&$,8KT]H)X/_F:R,;0TNQQB2
+M/'2==4:]3X3]IG"$!G7FZV!05QLO4*,L]N5_N8#IX6O5L_^-O>AIC57-1/M/
+M[$4]F(M:@QFI!^.>[U6CMS%EE,"2CEZ%1C5,[2EN,KA"7NH4?.DF&<YNK0W#
+MZM38H7K%X4MJ4!-V/CM.LUK5K"YZFB?'JF'W6#=BHCA\SR[Z-71]7.@Y%]UO
+M,!H.TZ9EX9[B2*>[TULT0%,?!B*=SAV+C'.;`W$.=>+SP>]K#O(X4.>#M3N,
+MU].$S1TTQ[8YD>?91@3<CFF>!NOAL*@OBAO\U2-IK>@7V0T(9IX*;)R[J]<=
+M=GJ'FMPT'1TSX_LJUKZE,='N2U'/6FM8-W6&S`#:#SY"&X8_YCX'OV\U6-QV
+M+:FYODN%-ZYYAR$Z$-<<D]2<?[+>=+C&6]S<_V.O.TJ[C28<UK9^:UK60)L3
+MS9SA==M6Q"%8:WFGLE/%/4\?V3'.>+UGITE[I_*<&AOSQEEWQ!H'>"I-6AG=
+MTNH\YSJ7W%4Q80M]*SO]/7TF.UT5N*+_69_E,=](&E$R]#^GO4Y[::THH[^6
+MZ'*C]AG>6OK!!*V1J)BZ@EM6&+TJBO).H\9Q9#%U^2?JK_:J6,!&K,2'-_0G
+MY4%^9$"<U??L)OSXC>]GHZ_G;X=)-L]]-#-L,ZV3;OW\TF>JEM#@?R:&9R`E
+M-)!\KS&I"35T;E>S.KR+9O'=9Z':D=2,=TVN=-J"L<)[`>^R@,NO-2\+T`?1
+MP@Y;"-39R@LC:$.-A(9`M?H@2C&A3M)\%:.[I?]IBFZTM7^C-MKJWEK7B]>$
+M(2JCO>R(DKW?BLN[$%+=S>2Z.N9T@4D[-X/B&DPL31DB\SD:^B^T&@=KY^KO
+M]QIC1CD*!L><+KR>GDNDQ_H%'S,.GNH?,2@T'RJ,O%^N=V%8S.G\*V?\-A].
+M>O+2T.BK![>)OCV3]K+;:3S\.C46U/9+545%6<`=*?=^,X^IOKN'S)S?!3%2
+M?)4WT4(,E1Q75SK%F(X`;:SOB+ZWEM2(T-2(\':;UAQ3W%A@]L8U(N?,"\.\
+M/;0D?\Q41\&@F,:2ZRC]TRBX'H-#L^7JZUNSQ5U<3WMW49XT+KGL-_.D9`;R
+M8T=K?E1&M\F/_NY&]R5*]'8.#`G[2F'[_.SRGZ-S/>H[T]?R]OOEAUX\3S0H
+M_6.1PS0ZJ\X?<TR;2F$F6*=-]6<,IVELS73FQCU-(:&$[I?8Z3JC6KS=[M7K
+MZ5797M%PGN[<US]X!B7IJ;"RW<5]3G_NV6LX?5#MK-8D6^[5=Z\(TO1J6:"X
+MZ^DCG@.&TU^6NAN,E.B9,VA2BKO1__8P"K/9F]#">WKKX55K[[=J,[[4?(S,
+M@LP<YZ#4"\_'&#8B.KKM?`SP,'B?TQO7W=FW<:GSUL:E4,=Q-MCN!G='M9E'
+M!S6?7JOFN0F#]WGC;'WID_BM!@,>[D+/V%=5VM^H5H^<7QZA9P^^VH\^`D<@
+MNDBG%G?*6VSSW&YTA\_PQ9U*U%L-M>]U1_1LZ]O>U\_@43M&AFMQVSW%VZ'2
+M;NQ(LUJ33GD3>+Y6_\:0Z5JC>FH?&7=`LY>^IW8&*.Y+>W&.TF=LA=.,K>*P
+M0)$E,&R&?_[U?#CZ[3(?C6=X%8?11-/0YQWR_`@\;RZ"\(8%%EH"@V?X^ZL`
+MPH4K6AE0^B9'>QUO<C9SJO\HNKJT%7H%S=C:3L=$#//'#.43XG^E'A0_*<S>
+M;]5/L[(OC^H0G*.\6)T5/R'*NSC*9_F58M!VF!?*6?&G:+[\JQ;>;Y8.I&O6
+MBO?/-P1NYB/@+4-IJL-VF0[X,9U*ZBVT...=FON4=QRMN_4E!CQG[?:'>AIE
+MO8&#-I>D^?4;KS$:*N`:^I[OFB]PK[V_MWB_??.X,&.S%E?K3:CU&F6R7W7=
+M2P:>4Q;T/T1':P?]:3KNTCD&U_Q3HZPF=QK*6LV'Z^3T%)\R%D[W%M?@/9I$
+M%W7.OGGZ\)[&LVK1KF=;9SI/BD*B\\RK.FL)QVG-F2^N@4[H\(Z;`ZT5MT?%
+M0KN3QU476A%;_=5J'S9UU+5JZW;&5=,7`)XG<>=U/$\B83M/;EOHZ'_2&U>M
+M)K<5W$7S1V.,[LL"[NI0X55GHPU&"=9?IL[)K;Z`9!>:=<FFD@DS4Z.P2VF+
+M6ZD_*W,:3Q5$VC=7VS?'G>J_S;AOFK=XNV_L.)G&N/XZT;/;U31&?=IL\?ZV
+M!7NE20K6_SD7;$V4T;`:SG+U^<[P&_=U5WJUL4W]&Q!7'5(!:0D\:B`8#KAK
+M9_A)J5)R.M&A&I#X/^OKG__-^^K`YL[>XCW:;?6=*>^I1+EZ4F#J5\*A%1.L
+MI4=-5$?C]J`]Z>`M/N3ME.B-.^2I[)PXP[^BO^3.(9(B^W(Z3RRPL#-E_=5=
+M]$6K]N5_I%FD'57"2+Q@BU-F(Y]I#\>>VCGCCOI+U#R9%OOF1/0:&DJ/0>C&
+MFGJB#E+%K?%?UD7->T?=,ZI=(9/H;:=WG#`WCIB;2<S-#*/@`N[]_A.=^97]
+MZA4D1<TT_R_B5V>`RWQ2!/@?)0#1MG^GWNI?<*V1]V_=!2T[^1<Z'U+IM6$A
+M>JUG4*]UIBWPPY1LA^BOM\W!T_C&D<*K884W_@9:\4F;<P_SC[Q!*<VZ*-J_
+M`_=:6$WUE4>:^8W>-ZB5H9-9;];P,T8]&'[FI++?PM4NN/Q`[2`C+V3@!_:"
+MA.[V+X8YTN:8U//FP7:YJG6EX)CHX%XL;EKW.U?6BL2U:)V<.\>%;K8RKB<?
+M[4R;9AFU<1;O5)OGV!7:3)N:Z'LKNE3VS9UA2@0W.XBI<E\+^1UMI8!Z0V.'
+M.W<:U1D^Z!$GA6DCM.:ZDP9=[P<6CO7WC6I=2NSN0T>$J\U;3EVOUK'LT)^U
+M>8VP&323"IS:LM$6Y\[1E%::YC@*:1W=4TURMWF.7D%/3K1))\%U"W(LW\H9
+M>.#ZX`I?=W=:+)QSM2J'%,1!=7B^03:/*>2V4_7XPF<J&5`"<$Y-@N2T\UV_
+M^1IZ-"K&W>PV>^FI9G_XU7Q43I)#Z\)L-P9GX9ZW]B<GLK5LGA_4ND_.1:1.
+MZ>9C@UJWV^R`Q#JYK&#P:1VI9"CA^C31<2%[YK0KS/B>JD#)#B7EJ<7;M''"
+MX(R9JJ-]I>HJ.;01E.8A[<^\"9W#^=85?(9\DD//_P[-`:Z(XU`/Q_7T#1U^
+M:K3-X>H6%`WZ:*8.)O^X@UH"0FM4.Z)5B[>HBMSZ?F]Y'W8(^DP.5_=@759G
+MF@7<8?Z5'`0IF#!5O8G5<(-GGJVV=(K-2OL!J>+>.(`G0#?^UCKZDY>WY\-3
+MV=2.#SIS&]'MH/T@.NZ(MQBX\:%M=Y:J#3#>HC8I@:PSV>U"6OEFT5#-[1DS
+ML8)GC;^CHR$^,,0W&AJ=<N?UJUFI)[6<&FTUN3(#^4JA3[/H"MT]@[<=4.NE
+M*=:I8<;W_VV<M/AIAG^6DLLPT<DV:?^O4GJQ318:@UF8?1UG85M9B`X]_^`R
+M6O-7JUIF=[C3>S,LKP:>[3C6N6Q;0T`=J;;W!)VAYE3G^3I5YU"M6+5OC@]N
+MDT+60*/=LY+UD=.;U.B,26IP]X2!K;FK=\;1QHV&.HHV*,2^10%/`!;`!P:V
+M`-[V'R,+H";":-@.-^L";LUOW-?=D@AJ_ZM4VL;&AVFGC3N]G>HOJFA_;YS%
+MW$DWYU;,M'J.F;2D0_4)[9\34TM27W^]\B>-.79TF':`PO946E4@^B,TE_B]
+M2"X3KQMYX&XHNAA-YG%S',RDI.:8:KN'5C23A^M&YRC<:^234Z4YI(H^=D88
+M;)29R-Z>1CK@LL8_^TJQ%FK42@QCTG%U]F:,^WB^W5-\"`:XI[C6[.H1B*MU
+M!N(0;8+?_E`1??38'-?HL\2I32*3'$XC;1]M]<:'T2HED_L6A-;@C)D1GD^+
+M&<+IS,*8R>$%%U&50N4.4VV[,Y#06+^9]@X/\W:D59&CPYS])X8'V;,[5;^1
+M=$]22WVW"G7F8@N=2=6_"PN+2LZ#5QK5KP9W%Y5$?LEM\\:'RL)KNBPTT8D(
+MM7LN,1HVP:5=P*W^C?NZ*[V$9:%=>=GJ)U;\ECRH^<GMWM'-[:CSY$HO>QB!
+M_@\NYS*7`@W[=P7JO4(5*.4$%:HJKR_/T;(J9(VQ$CJ<R@IY[*<\=G=P>D8[
+M3&H[C.TA=3ED_^>+];4R;MJ-8\,U^MR<BTK'VR+G&Q-Q,_F:]GNJZ6L0>!'Z
+MJ<'[I..B5>VM<\:\7X`.Q38R],+,0X<[1^-._O=JGP&5`GW_BM2,?%EP<=,%
+M%EP,/W__"N^2**MW+"^[*#O><O(EM]4W+I#\#W5^=)O]*4(458>+U3I(WVO1
+MIR$V8>^6[7-U@8Q:WE7SRM1HK';FDV]\EM=I'7ZB?\6EZN3@^RQ:OA6VAFI?
+M1ZNUB*&+H4/'6/X:KF]M09URW^,J(LL#FI$L%ML#K>=*A*Z9S@GG8\J*')J[
+MV0<+ED:XU-IIU(-&;T?[YEWVEQ-LY@1'E=]A?SG.IKU?=<)AK-9V5'V/5QQ5
+MM0[[YMV==]')ZR;/-@O>#]!QP\TQ[I8E[ZAEG!-BBJQ+;X:(QB;Z:>P)74FM
+MRE-E\\VT(5HPK%JX2FOBM*G^XY>I<I_IOYJ&V8M)M9`]Y7HJ;+0VTT'K4T/V
+M;0^U"9[K(VL;PM12070\6]Z*>?BKX:=/[#T+L5.K+@;O!FMJ\.ZLL:1+Q=[T
+MEE$Q22U+3D_U3Z5D(;/#D-/TP'N=#;SY3+&M<\G5GAV=[>]V]%16)\;/[S+-
+MOT4]C%2.BRFV+?TZOCX2=OV.+O474]T+>:XBY#G'TJ^IV!I#9!^::'#EZ6VT
+MN[_;JN9(51US$(TJ@$"L5<>LBFHDRE)US**H2J),5<=,9?N6](Q5MV+=G;=$
+M&M1V>Q6M^S9X>YS:ULEU+<VXZDB[\%54T,R6KGM/:#W4(L/=_Z@Z8<)OD_H]
+MN-)9MD]/Q@G'\GV<A!/64]OL'/\)RZEM9H[\A(EF+=AB]YYP=Y*8M1[M]OGK
+MW9OKL]'_<PNR(2]L9ZS*V="]^X:'[O]^47!M2KPC9IRCQ`H=K)WS%K?04G<Z
+M$;?9"P%(:C+NU1(:8R9;BXT0I]]3V#!'(4YA6L)Q"*$O[%$MJ39F;T$?.G-^
+MISH.0!T_`D_<SC_AV0'M7NM-:/;9'M82#GEVAM%1\4E-OK"GM*3]-"Y(057'
+M'+![>DK?)`F=P)Y:DA]5=J$WH9;"*JZ6L4;E?]R^V82ZX;=OMAMWF>,:M+@]
+MVC9DHQHN.>XU<M7Q>_NHJN-U-Z`/KM*D_5A5YZ"CSK4B$YJR/4ZM#^T2DW`H
+M)N%X_O-HV[0^U/'MK)[RN_+`@Y84$KMWF++#CM-9K:T12`JJ)&P5[DR34QNF
+MPFY-CWUSGPNFQIMT*"8)\>.%N!J+)ZX:;^V/05?X@1_I6PD=8]'B6_)H6-F^
+MDBC/SA8Z.R)B(BH^Z#`8$&ANZ=3F$BO[N7[@-[2I#J7_MUYXCXJO>ZD].SS'
+MS*Z+YQM\GEW1ZAPJ->='K1*SHB95%=M,K@7>M_-.TRBO^[*,A1!?O^=7^'OH
+MGK:3]U]&U57]-MIK[6(U!.JE9W;0K]UG:?-I"FUOL<UUN;<3NGX]9\[T9](3
+MG?CT0#ID>F?]N]0OM0:5[7GCTT-ZJ44X5><ZD`9=:M&*&[1&.M%SE".6SEP?
+M98V):RGI$HAK,%;BU])3`7>#_YLSQ$PS^EDD>8V#*^EHA\;BWI3>QA!Y;8R-
+M:5Q"EJQG6Y@*'IKR'?*%[HUK\J3;KG#=]B95O@$)-I39X%,57A,X_J2V<R/T
+MIM8)98W@O4.\"0V??`_%')/45'18&U9VRA4!!4T#<7A>/;C-PL_2$_6H<%/H
+M[)#%:C.*I\_0SN/-;;[SS9RAUL_94!V]HQS]J]TQOH5A/LL3E#9?6+1O[/`P
+MZ,-M+9[*%F^7&*LK3(UXQU@+.Z@=@K1J:L!C3A8=4HL(0^WZJ)"\_:P'GYE-
+M:ZX?HM>JJ`NZVWWY?(/_K\VJUHM&V1FK=OBNZZS6H^TN1JZVJ%Y5BY9D>U.-
+M^)DK!N\.%"%3#_GG\;NH8MIX&[=Z*`A?V&:U1,RFM$,#6?C3',*3L1&=`]8+
+MTM%0-E8G5!S[YIO[-YKC:E$@J.]G4=]KO9U0N6BMV<UH'_LW&JL]<0TJ?\5?
+M'4>NCIT?C&*FLXZ3&O)?B2EN++P%84I8.ZK..4A)45C&QM]\&V\5O5]O#B0T
+M>ZI:/#$&U\_J[/D6;0;7M.K0/C]]:*!O#+YR-"(M9;M+;&H'$W5:>_T4;=?I
+M&BB,,V&>,[V6]D:?TFKXY"S,8?V!0:UG:7BJ&CQG+E]ZT5M7@.C_OK97/]PO
+MJ;E>/^G]<%SS!<[?-CG4?@>^\5"P3=Y8V`XFWQ)KB[</'0GMKZ.2V?$6B73_
+MD[2=10_/N2Y+1[S9E6[\"+/R$W\W,'`[2B^FN*F@@W=<2[T),C09UG[C)\?D
+MN4_\G;?Q%A,5]%17Z""O'?4#0B<ZT[/C9]<<,E=^I#3[50/6OY%T;=4G)[1J
+M%4?7.+]$T\6[M`5U@\9)]4/N\62[5QOY5?56,WIKJBXOVZU2F]!"+R0U'Z9J
+MU/9<ZM"\^:8[C;[Y=_VL3F<6[8#6P[;L*'T]0O.W+-U&'XH@VE4_D.:0W<"6
+M)333SO/(5Z08]G(*C>;XFT_S\<-TK,O5>CK5\37?:LU=2?Z;M%%AX".[F;;^
+MIS$=6H(^+HP^Y"4T:*,LJE1IB:V:FT">U/SZZ_M7J$T>GE(1J*<II)VCN"[&
+M^95]M2-2&4^-!NC7XD;?\F$?THAG@D,SOGD3%R>JJ;V^7\6R'1^IL5"'-LR;
+MX/<6-P1<C[3XCYRB9L9?=:Q#_VVTOKQ'R#+*"^3="]WDN&F;^N*EVH/#]S2J
+MTY#]A8KP0QT,0.48YQ@0[U!["Y55EG2IJ@TSQC61/L*O_G$-A^,:#[G][3Z'
+MQC(TOL=8>_L3-ZU=%0A\>?M-7[]\4RO]\>UJ#@1MZA62-'LWHUK3K/)F"\,F
+MAF8&/I^FV*H5;U3G7VU<T;OT[`#7)4MMR_?9E_=%YM.:W]*SU[O[X%6>'K31
+M6[RQ%*UNW[H.-&A6O-'^AMW[^%@*J.>*Z2MNJCK1T7,,=A^>K'^1PBR]+=I]
+M+1)`K\=K3'?5PXF&WJ!;=$1\%Q6<5KRA]12&G7'K&"H5J#,;Z)?]W4Z>YAM*
+MIE9XFF.6WL&G25B7]O2ZU_G"WO"-340SM8ZV6ZA@+_O27EZUT[LO[#WEJR((
+MJ.`H)>Z-9#LWW[!THU<]KQ5O]S0/LI>=$8Z5?UG`7D;C%)[F:'>/0-Q69D&E
+M)-KU@R_Q8\]9J_TA&K?%\YI[@[=XJ[&X4@H`S\,VMR]_3'EO-;HK5>L0\V/Q
+MJ`KO$WG!U"",I79O,=AXS[A/2UI7'Z'SX%C:P_LZ\_`&O-1V\Z-B$K8NK?R-
+M]WUAB1R`_G[/X/ODI0((IDY8\2724D'[@PG*KUJIK.9T5V=/<YR][)@A>(*'
+MNX^G>*O!W<-3O(76-KEA,&^LZ]Y9"M`J7]S&:9(_`UQ63_/UZ%S'[0EFIT2E
+MSLVC++57M,G0DYRA1??ZQE>K_%Q/LL/%5'*I*O>+?&&:;U)B=<A[-RS]QINT
+M<4#2>LH'Z[(S5TPV&$JZ@A/Z01]585VK+U`7G[ZGFCYR").D8BN8#9W#*XE#
+M>UD,?;<%E_:R&ZQZ7:F+LO+9?Y7]W=7TP;!XN\'=.2@Z7MZ$W[V+IJFA5=JE
+MUJ"XUPT.T)+OJ=.^'!@%>^)P4K.G>%?GDOZ^QRMHQEGQKD.VLUQ";1\\4G7X
+MGF8Z2_9PC2[-Q;1YB'WYT[`W2Z;B=^^E?7R/UT2KM@\&.@+"*W4E\'[33E::
+MCU[S3>T=DU2]=%3_A.K@PX=L[Q^F9ANOG*17[NBDUME7GUARB3>A^O3!U@>'
+MOD_^`SJIM0H4W("D7:3([`_3OLZPD([:7?8VX=[3'-5(GS\U"/JM="1IR57Z
+M\9]T#J7W<9H_X>U"NZ[`YHMKJ?NH(_I_S1;[\IFTK_)N3[.QY-+U1@JU8G!(
+MJ*/V-L-KZ=?+2'UM;&GG"QMRV;=D:VBJPB^#NEB[I.A!PHHEA;"BT&O[82DT
+MH%K(2D=I5ZB`$LUUM:K1L?MJ#+0KY'DL#6UEB99$(*5MTKCE0FG$C<-)_C:>
+M2<T'OS]\5)_K=OB@.^-@U9%M!W?#@[U#)L+=VDY3AV1?W5HUB8`FOB0T3YOJ
+M?QS-UB'$=D\S?7+\'7G*6V(6U5L.UQRN";C7!91X!MS;`^X-_N@?J,U?32<$
+MNE?3F0G_^(YNK/%4VK0?/54V;XG#%Z9,?\\VZ[2IB?[W;&J0Q`>KR9?4-"T8
+M__/4)L>MA1FQL)%^K5*G-U<;EEP\N+)5GT/2-/<AS5U#`T^0U--?<C'QZ1<[
+MXVHXP6HXF*9&+8%N:3*J2E'?$79`_^)#7$4T]W[TF\WH<T\,+#MC0J'"ZDYH
+M6E9UHT75YC=O)KE/:#2JXS>,"8?X'(Z8A$/%9M7%W4^XGTS1_LJG?\*A_J`K
+M2_HF!MRK_(=^5$P$W&L3_7M^X.[;6G\7RASW6L_V,#E;I"0LH))#GG>=5#E`
+MWRJ*:PPE/0)NY/8:_V,_<H;2[4/J]B&Z/>!DZ^W]ZO9^BC?LI&0>'29-H2;_
+M1#<JO(MLFJK\LB<8GDWTUY_DOHD#/8_1U#REJ7-MFJ&L[C;3X2DM9+[9RQ+,
+M!O5UM<+_NDI,A7K[Q9,T&]515KGTGKH!9M5_X25:^BE-PU"XRXY1$,O.JEE$
+M=R/L@'NZNDU5;-DVLOY:+?6ZXVK"G\3K'D!)<?<-/NY;@;^!9;O9IFS1ZZ#:
+M.?X4A-2^?)TI&+N][$I:2J:+UR9DPZ'L9E*:VZWZ9%&:3&I?7D.[1\PWJ3PA
+M'N\ZI6;9^E[;>/)<X'!'GM?:P9VILV4]7'/0?["R/E<EK[.DUG4EU&MQLY&F
+M0;5`MSZ`NP?]OK>W4""=U%RY@WY]CFRWPS6^URI5\/5=*WQOJY^=CNQ&J.C;
+MZEY$ZZV)Z6!MJV8J7D?JJ':IO8P.;SRXF^>$P<!%7T&TFL[X%\7+OU`'8OE?
+M17%]\2+]/+*;*WHP8\'M%]G+J9#^O*2P_^&:93!EH>2(%7_`OOS!LU2UVNB]
+M7L96O5=?`MZ6%</0BC47Q8/)SQ63Y_8@=PMN;N6TINI@\7%OPO'7T7FK/9A=
+MZVFP?!$1=??![./3OK!$D<W=RBOQU)Z!'W]LSP"GNYW&CBE>YW933$G'W["A
+MVRDQA47=A9BF?AX5&I.];1%>YWMM5TB9Q[F2?&]7<]$<%'DQNL:HL5+?:S5<
+M1O+D]>BGDW9<Z[^FCJKS&O_E"E?Y>RNL\'<'UNU'5LISY_S\W"D_/_>]PM7^
+M;_S\_!&_.GT7\@;SA;;T'(8&P%.\R>!"_OB>I1.&0OL4H>,/,XS\;7:I@X83
+MXJPQBQS%-%_!SO-I:?8&]=#\`?3OXEK0D]7B:HT[->19L97[;FHN2-QQKR&6
+MYF?UUJH'[SOM1O=>M5Y[0[L`/#T58?J]?=10C)\^6[Q,7U::C%4TCGC`_G)Q
+M(X^\HU=^2*NN\CMH2]+B!OOFV^V;]_8_@((VGJ'=A1RT@2EZCK=7_>"P;TXZ
+MU/^`=M:X#6_H/CP6:%<1-2"!,7'^PN6>VPSNV&#2/3M:8LX57DLWKP*#3(83
+MV4OM?Z/NN!L*.N"6JU'U':W:.'VKTYKO:,:\?>519=4VMF63SF2O#*/=S/4<
+M1-_3[Z7=_30:D3Q+/)\AGG?1X,<VXO8`6-&*F[QQX-9`W%83MU7:QU4!V@H-
+M][T&&M(D;JNU;<BB`T$?IY8(;JTJ>,1Y/*;87_AP2"):?$.W$&/#B*4=PO,4
+ME#G3?8CN^2]X]L8UZ@,M$W*<F3F9KL6\RX_T'@W-MZ>,R4U]_J%]M[^V:XZW
+MWXH=M_^R^,^)O<9^<CO[1TG_,D(P+%;O9ZK^9'G;_N1[YZ@!C_"\W8\VJ7;=
+M[GV<?GB]`VGP<Z)%2`^1:A6QZO#?9PV\1O?]'WT-+>11KQKT[QN&8CL??"3C
+M"_4=><J!-\DF+<Q9-34UR9L0OM-HOY9:-ZO!W5N?UMK-]W:M@6SNE?1!W^>M
+M(R)AI:<XTN":YBU>6;K4C/JGG87M4M\)MM)*SS:T^I%:#W7N\^$XJ[XL05E;
+M`VB!0?C.3NI3@?>[D+`ZCO(61VIV;]S*NO[=>)UD4C/LGQ:U(B(BRO^W[U5K
+MCG17G0A#F]F)ML6OIM9UGVL@3R/F6<++TIM4@YK01`,TR^*JC2VDG->J3DBV
+MFHMO3FKQK1@",X;Z*F<B2_IMH5+IOXNW!?Y6*RY=MJVGA?LB>S_Y03O;-:FT
+MWH$TR8AL->+[Y-C@W<&.QCV-RTC^'><0'8V%(#IFL1$L'C8>RF[TO=U,/]&"
+M^;P&(]T\4N5[VTJ_.GV>4'T$FK_!F]1`^MA_,-O_15+EP>R&UB4CO;^(JPQ9
+M0-4YD%#)_17I]7N**WL71>F6-#*C\E#$^[I"=ELF:`F5,D`!]@<D5?OR`V6G
+MEMC$#D17NMYV^@CLQIUQ&]@PK#0LZ2G&HK>X4BM>;RS>4-\3X<**.WU02T#$
+MZ_E)1^="],#X"Z8ZX9'3X^A0TMT3YVCA>ZPB-NE>]H<>5@$[:%>EMV,M>.+8
+M^E\,!G+E<&EPR^#N^85>VQY0ENL>ANJ>*BPU*DS?RF7$A3926XJ$A%$<-*J4
+M4*TE;-<2]M1?$WS&FQ1F3JKTW6?4BJNUXCU:TO:R`+U#!S0:WE66OZI;'%YU
+M>*'2A^J6\91O1A@Z=T6-@=>(]O]ZE+Y*4&73XLJUN)6JNNWI;G]H"%F(?)BF
+M?7E?-3&UFB.WTB!T$DJX"?FH)6RE*9K%NSB#:!0.IO)\^*!3)`5I>1\=X*IS
+MEM,[*'M=(SW?V%&XAU[;2'V=>ZS\IEIQ!%M?U@7U#*B[W&=##Q,]GKWG`G'5
+M9:?<A_'RD1_QHCJ+VAM7>;K&%:\Z84'!47TK*XU06UP#@F&&AX9)XB4=8*L>
+M\@'JO[MB#OH/W6-E@;V>Q@!*KE73SA\VTC"6*@S(K>]MAY+Z0PFH-U8.&6%^
+M[E-1>,.E<AR^IW89S>>I;*&0W'$[XU:Q$-$0G,'W=J0*A#@Z>CC)>BBI5L5K
+M7_YB!TIB[<%:L3OLRWUT,%B)[+FZ"85">P#Z'J^.I@K:3T6'DC@T].RA]%K$
+M*L4%R]2K$FH4/=:F?K)E=B_J*+QFL,E$&?=C:54TM&*Y?1PT)N7G/;5Z+;0O
+M[VY%L%6'TMO>I3XZ<M&;L"<FH=KN(],!Z:_9C:0@`$)K'>=^M2JC6DHLY7ZM
+M"*[.Q'^=3H[:/9JBK:(X]ZK4'3YH7S[%2-8S,D9RTQV#QG-EZ>TTOIBPTJM^
+MNGX.0&O?1.,6X$//-2[>NOD!6G1'_6)O<3G%!1T-99W4I-$BD:W02][B7:B+
+MJDNPDL8PH'NZVQ^A]3XLE:@1J`A4O8M'DB@LO;FM*-`]^\KGS*U"`>.7Q;"#
+M?7F%F4Z%,ZN^NLHMRJ.:'W\KEPY6SOC<1IET*-OZ6_DTGT*HA-!)/KFN#]T)
+MX'HTKUQM[,NOI*-W>ZGO!>4Q"2M=4;0YJ1HCD+R+<7WM35AYSC@*S6#=3[QF
+M(1"'+"G?T2FZ_GA%:&8FM>N4;>N@Y*9NH)I*<4@KWNA-J-%4+=H9MYHS:!5G
+M$`G]`ZQZC4M1)]<:7#VH3["3NO+0A;0MC-Z?;X;BY'5+[CV38]PU2^S>XIK^
+MIS6ET>CCQP!WC=&]WNBN:=7LR!B\A2YRE_X)&W5U5UQM+#Z$5F.^T5_UI72Y
+MH2(W&DJN\A1O,)1$>!,VXBUO\8:8,R5FI`+*2@T1;.R?L$'U[^]6MOP84:8E
+MUP5>7Q+@GL#:HS)VL";17_$ECQVL\7]TB,8.T.$/\[IK!JB'7;UGT)BD#!1D
+M'M5'!)"H@2I1%2I1ZPTE]H![?:)_W%&Y:55Y-4@90U?JQE`X?I"UY+('X@X%
+MXC;LC%NGQGTZR2`Z!>2ZUEM<09]S>4S'FU`1<'5Q^$\<5D<9>Y,V>+9%]M^&
+M1.'G:)KP3/M)5QM<7=]3M@4U3'3#4M++$U>-#EZU,>&0,6&C,6$#.K[P,"]U
+MP"-"S]Z-R.$VHQXW'6T=]=B@;F^@OM+E(8Q!5<?A'CW=]9BLERV^$:J9-M:D
+MNZ]_(6'85`GTY/NK_$]_(>5H8VVNJN.=R"E320+]7M(73W:@Z`K4DQ6)%-KS
+M1]56.6652WNSS>(M#CM]0"NNK/L'];9`)ZS<81Q,=0"R7_>221?9;Y0VV*B8
+MV$CQWU6K#]UXBU=IQ:L]Z%*[;J%9ZKF?LT^E33M#8VI+VXVI+3BCUO31$,TJ
+M?T\]&)NN$R0W/OV1]GR,UN+VHYM)-QIJ6;;4J,>PHVK"SWTV@_O2:?#E([#]
+MNVI5%GH5A0JN[+%I6MQR_VV?DT^$-VYY6:5;[7GOONI4G-4(`[]X?XS+57:J
+MQ!R(V[^"YJ6L+.]1]X!JHV"7=7=/5D^/5T^/+JLLB::4K_'/4C*[!JE)]"?6
+MZH-+7=P]O`G[:3)$9P2'L$>XPBE0Z*T^=;>I[^:5)?TH3CHS!GD=H_2-F>>_
+MK$C8?ZY*Z;@Z-2-&3PX]@Z8FIKC:OIRD6Q>.U0=UX?`FK(I)6.WN33Y3_:7J
+M_BHUU&FKOZJ"GU_MSU#W5^LR=-=!?>R2E)?GG%J3W:X<$AKU<M#9(/5+F:PT
+M<'&XGA9;,"T(K+ZJ@G-IR)'67+KN2_Y2ZB@[M?0B]RV23S?6=]9U<GBK+OXN
+MJ(MIT9FNAP=3W/675M!S"2MIJ;6MHFW;1\(QK4;5;T_Q*H,+ML]J@ZL79X^K
+M*V7"C>Q-&="/?Z*W)&T!4AQ60SJ\/*9XI;L[-#_%*!_D5'E1&XC^43BZ]=17
+M0C:LE-Y2N>_9K-9ACC87SZ%K[5NF-O*AN?[-Z&3.[SC#_SRA8<9\L__KG^F.
+M_\&?:&;B^F:J*I'SZ<[Q)OV1;?Q(JGJDK)E&._T=?R(!"HFO-;)3/QC4?"_/
+M$@.?P=7!7XT03L7;K)#J>)O#;>69Y@LK0%E<T9Z2:-JA/SXV)CZ:SGJ(]D>?
+M5'W8G?&JKUWJM'TANU-[XQU:Q]+)-BN="^$&(\_]HD(VNL)DI8)W1MCIS[49
+MX6HOK<&5\#.YS=[X,"W>&MS:^OSY^J,YS>KIOOIRLQG^+.H@[0RX6_R?_:@^
+MP]!@L/LB),#DBQ^C==3B'3OC5:^C?H37LYR^N#Q>JHZ+6/9Q*;W;79M,$S:T
+M^#`:2W/UL+\7WSW1'_.K^OYN]GQL='8NL;4[1VY.Z/?O[PTR=\[I*>F.?AF=
+M*L6!#/R9`J%Q>0?/+:J/K`@YVBJ2=G&'?6]4BT4\Q;7HS^_L1"O-MQAHS:@Z
+MMKL3_8F?I+_V'OG@W5*WP^O)0Y`Q\?W<'=ZCEVA^YJJ@J)V7?Z;O52?'9YE6
+M56OJ7^VS_).^C"5J2<W^-8W43:*EV73"\>#*^F%J3H*GTDX;W[=PVK6I%FV4
+MM;XW[7.]T_>:"UVKEC?IS(N?GO54SIJX^$2;X_;:RMN#W]&X2*NPJ?V87FLR
+M\MDNWAF6^BY.SR*;P=57!?43C?LXYG?QTQE96D?>4+FC]^;Z?20O]5.=.V-M
+M1@-/%@N>%&)AX)XNSTK:&4LGG1GP>'?Z;A#-]X8RC&48K_HKP7F1(>N?&]"-
+M'')&3^B`>"2"OKO>1JOW;E;DTI.X94WDN:8==<EM.R_8VT#'A=.91'[ZFJ[/
+M`P[Z+Z!Y[&WDDC.*#PP)+L]N$^:P!C64A\+J)D%?=X9ZF:=B;>&N+HG^"`,;
+MMOK1(S2?5LZ5:PG*<.C\W6_JE6S8WQMM6V]UW>F]SU$6<$WR#NE_3ANQWNSN
+MXQT=IHVVUM],>_M.E'7K]8,J=HY6>4]3)"IFS`SD1]#.\DDM@6I>Q8+,V=M_
+MAW$G=/O1T*4X.C]@@<M0SJE6-`6MTVK8:()JL3^I[6RBVX:0^[2_R2>55_[&
+M_3*3?L!=R)R?5I9_.L'5ELZ<:FK_E9&&77R3`Q)SF8DV(&FA,0`Z`L47UP2]
+M4WN2ZO82!.`/G1-?*R+`\0T,1K?\!+V\7RWJ\I'J;`[HR?/>0XO-ZTY_S^-J
+M'089+G@^PP'=O^^%_3?K_F$7]G]*][_K@OY\OD/FO+S\W-3LE((%^BD(@X;R
+MRON;;XC&_YLBHX>,&#ILQ-"AD?,79,BL_+J1I%HF15D]9VC?WK%1:A^=^H[>
+MSAIN;HD.B6\_G02!QUPFS3BXLMUY8B$"F51'M2*#<F<X1/%BR'*1A><HC-UL
+M#51/7GS:>WM9P%W'50=:Q67Q&@+5E+W??$>,LOYK#=%<I\J;#S6POS>C^S1_
+M0KTJPA[:-K4+K'%&8H_)TZDPG<N<ML`/2F#/UV5O^:4=ZF9T]9IOHN.E6-L?
+M42VB@U_6XR&/PR>"&J9=6#E^25286H9FFS:54_8X@M+VPIH]&W!W]YP)N#MS
+MJ/7=D+;)-H-#FY&H39[.^R8$V\M@L'W\2C_8WXM%[(^<"%4CH?G==IWHL6];
+M/Q,\3AJO;)_K!N3W?59OOJ4^PDFGA+EZSJ0M/!*L@;V=Z2P56LGGV3EK\N*C
+MWIYE^]R?J)EB?GV-0##HA[ZE;Y.VC%ZN@;%40@TA2>)Z$I*.N[]59UXA0]8[
+M7&&^XOW:9RUJ>N%/SY:BK^5+VA_U`RW`NV0I[;]LHT-\/,TF5Z_Z*RNF982Y
+M!I;6=Y^6<1%AQVD9O8$4XWV(L;['>2<U^=)WM5WG&$S%_F]4*M`JDIF14>BR
+MJ'"&G)"C3<\[__0;@UK)F5'DLB@>K2=T_=#2JA]:S^6DDZ=B^XG>HM]1K3H,
+MT8[N%Z(#B8YJ1_>36_+^LD@C;-12J]$SQW)NV1Q;RMGWDI?-L08:`H%EXZT&
+M,YVA%6G<$7NEH74M9&N6?_NU$L-6+5AZ24>(=<;]+D/D#/]M=0;]!*KKR.XB
+MB:=__HO\9'YFW*>>"J]32LW5J>T:H49I5X-QW?^U>NE>O$39=-3?VB:&YN?T
+MKU7^4\E>MK03E7>7^H&>9K/KTOJ^%;*01*VW$L4L^QRTJ.'6/B'G:@;+NKYG
+MA2H@AQ3E/+]>E.>O:_SLN&[3^68&/&?-18O5'@.3+@VH/0;6P7LU7+DX\),+
+M?FCY'OI5&3DJ0SHAL/II%:3T9_B_;U&]4,J@$9Z`V=W!%_=CO=D7U[C"4![W
+MR<B`J\=\HR_N$SRY\1O.QU[(Q[`+\1&RABOT\G4PMNI9>-8][Q=]?\^%VX.'
+M=/^;+^P_3_?O>$'_\^S+9[Y22H?6`+4_FCJJT1!R-+7*4FN1D\__C.`LK8C$
+MZU8X'?7?(^4WX:D'^>RU7C-Y=NEXLX'/@ZZ_OF(FG56C[MYGX+N.WY"#.VE?
+MHDERNHUZ8S;U'';2=%H#N@$PM5N<6GPX0CCUX,,JPNYJY3TXN?L'U;#%-:-;
+ML>QAM7&`D2WO-OV#4+VZXICZ4J6?1-:+/L:%39OI_T+M)T!&W`QO0M@$SQFK
+M_:$%)C[)PKOI,OKFT@^O-GQI,.0=922WM;:5IM]>MX-,THZ>$HO!W5N?(-5Z
+M%MTE:@^]EFF*7ZL_4YGZS;RZ[["WN-F^>8K%VTFV7]A[(F:O>XI61?DVU3K?
+M,)4:IYNUI"9_RO<&7IO<1$>Z/FLDH9^&#%GV/7>Z;&6[70_;-T_E4%Q5"-FI
+M5J2C&TP'=#9[^WBG6+3>VF1+71G9_6J&LZHOTU0D_F&M(=F7QR+IIT;9>KHC
+M:9&S=WH7"Q+#*3GPG9Z2^G^HM0`2IWMR!6U-X!HN*:=M$NCYY[\SJ,V/FJ8%
+MAOGW?<>1A%,D7Z@5KGJ2MP5_VI>K?9J+;9J=>:C[A--Z7IH]WX6D>>4Y27,_
+M"4EM9C&]2\\VR0]O3?Z6UK2G5-`F,)1V2VC:ZQM"TMX[-.U7_$;::1\%+C7_
+M2WA96;!JOH=B)_B8<Z)3FVD)/2#L/+G=]Z626]\46B^@2Z_-.S/,.R4<G48M
+MH44_WJ^XP6"0/7AH@P>GMRC<4^SHY++1UT?7C+I'*=><\?;-'X6*60G2E(>2
+M2D0(9@GAE'TY?;:<;Z`3U*]I#?:/!MH82=YU[1I\JCY6.^F<3*OFU!JL/`N'
+M\W:]A.-*XS".R8U*U^]:WZ_6/G-.5D=%.[6%%IVUT7(J()_T&M/#W=T)Z\89
+M,]52:'$&)EC41E9^,KYI7:Q:/\^YVY7;.EKGTC8_0S*3-G^C>I!D]3RC8J%-
+MC`)#_*/K#?J)]JXK[9OC+;QEU)@&VFJ"%N*K'2F.PY;0&H-GR9]W%N\%[;F>
+M1U@?MU?&3YT(5<;J@*L^YQ]A25M#5OAHUZ6FJ>H8NIJ0E!Y21]1=A!"'(<#X
+M$[J<W4][W3W(V7D[*KPI)C[,?;/3.\[BC(D/=P]DE='[A$$=4D>A3A9='8Y0
+M'U2A=N*@HJ&OYAMFSO!7UHO""BKC;A+O1W4THYFVP'"H55+^UK6IH>L3NAS6
+MCS*CG.W1RH;;.KBRSDQCW-X$AR?&8%_>I/8KL9Y:QBR$>2>HM3+J-+5PIY;0
+M6-]=W^..EZ:S4E.5P3LL9$TBY*>[NXO3F]#HC)EB<8V@IL7N=<3T<$5"4'EW
+M!3MU2/K0SH0S$42+OB>#$Z13S2A4NZO![(9>+X2-"_UN7T[3Y;P)S=[>",I!
+M.Y:HH+;[>?@<)6SA.R?\P0/;W'TI]HLH:3$.>YDU0(<P2!J\>*SNE!KDU8;9
+M-\\0Y0#5@*KE6ND,3+',E(RKK@O61FJ;SD_$[7X1J`:#O4R=$N)N5C5H-+%C
+MW_Q^,'Q4_H0*[PRK_JJ6Y/<;_:(6:9WG%%*P*M"K6OFP+T]0.B^82`2-9S?3
+MRNDD.MY7);-_G:J?%[<.N5VESN04XB*:7Z+UH>5I,RWJMIJGTWS^)GQMZ^\_
+M/Q?CQG%>?1KW;6A]8O&/A>R$'/O*^F$.[`Z7U1,PNNSU-U4H\;_3H';$TNV:
+M*Z3RN+O[XL-@ETSR\^`*5XG("]@RM@K:';5462+MUDJ&]JDZ?JX;`2J3;"'2
+M(>>45:J]B*D"7M.ZOUK6-U*SZ_ZB)MX%W,=GUFW09=RJJD=C:_5H\':GZC*9
+MIK.KS3Z09[?MC%.)H(5*"8>4C5ZK:@GJ1HS=?3WJ2(,S9K+%?75KQ7-W+]74
+M#UG0Y`S$6^HS55L_PS)-*4BR:EBOWX`ZF'`(DM@CX*Z5C4LV?6W@'7R.!]R'
+M^-9?<*NN!PDN/^[NBA2J;%5KRVI#UD_9-T^VV#?/U&6UH/\,R;8/OPE6@=MH
+M%4+;Y_(75'BG6#6:4NV:<X%$7?&U7DG=^_E.W-=!761?/D6%**&Y7M=N<ZKQ
+M=#WNJ:UQTR%GR$YOG[;AOW><:Q`RNCNM(9ULJ7"2TJ"31B=;O+<Q4:0':`@&
+M6/:**A\JCJN"Q1$>4ARW2G'`R@XM@R<->K_0OOS8K\$TT5C9\9#LI-C=&NE)
+ME37C2(@XQ=V.TT-*3D)RY0;<T+9IO:E1@*EYSZ^4+]/T2C_#4G>-FK/0&LP.
+MU?'P#S4&>_/GM84=#Y!94NQP:L701#MA"ZE]*6ASOB:ON^E4O-7DZJTUTMYJ
+MQ-GVK_0==UR7P\_HNLK;$7[&1N7[7-#7W84KS^\I`^,MYH[T@7,''5)/$8SK
+M:6R&Z=9_V[1$O.D_\`728"SJ:=^,[H47L3MI(3)U!I#I+<X)ZMQ75[B3+.>8
+M$05FIW$(G7*T"SZHXWX.4C8VJW(.2&BI[^WTCC;Q\\WT?*.3-H$P.2>XOZ&O
+M$<O&.<X%VIP!>YZ]$+J>^MBGRM[;.2Z*;J@M,3P[K<@PLG=E:ZS'CX78NS<;
+M>0K>%"OOQB)[-6D[]G[OA`663.=A.O?ZG6::!QK72-L"::-MO*':-"@*?_%7
+MNL32(<^T'Z]]^7/*\G;P'$1TQ-3).F65)3:U)Q`U)0VP^_9^[_ZKVK\WD[:@
+M02+09-G4:TK7)%E//:#.;7;?[J3V2&WC99NJ(IUC5*-T'"EZ%TD-P3VF8K:Y
+M[6PIJ"T.YQIDPJR:D.54DW>+&YU0XA;:U,:^V=TX(S`83U*P;Q[5>5%2`_%:
+M&.9U694UK[(NDA^HVZCV?VVSIKMM/_KN_0:U@=AB*ZD%=3XV;8VF1+W7T:#B
+M=I4$FT)W'V^))=@.;Z[EBAUP[T)2YZ%Y;&TS)U*KR:VEZ@W^<E24@/MVM?<+
+MA^"N-?!.R\W:5"LUE5/A$<9-)3=%O?C<;'F>-/KY^T2%\O3@)\*3Y7R>;J_]
+M]SQ]]>5_SM.U%^3I+U_^SWA:^.7Y/(4P]/H^)?N\_YW%VP7E/2I,VV$>HM3%
+MC;YQPQ-]XX8F>N/"Z.!T77O,]*]0C(21UOV8Q&O<4*2B?@'9S0^Q=3L%BB0V
+M9MSP@LL3`T5#_9DU,DI@7_XGLE3PPF3+*&W*<#+U=*6$YQ8?4"J(9E:.LB!8
+MS4@&91C:Z>!-?AH>Q0Y8DF1Q*+UWG6]<-!([,%$_Y3V^,Q)Z]`A5._?UWG$#
+MU<IA6"^M:1SG[1@S+KH@$C$/].\\H(]CR#?CX14:7NJHC8L.W$R!T4.??X;D
+M=:20*'4#$1[-U]7O>'9TU@93;H?:+Z'R$[]7/M8XO`ZG.B8[S',?_G8_-=IF
+M0KRJ`(LJ!N\FVA5FWQQK43LP&:M/Q5I-[C#T@-O=<W7RC>]<WZVBPK>H,\U5
+MI^^?:)VN]<6CY.*'\D:G,_R?'Y;R<G62041O_%#H;=Z?S^:-GQVH;C/VH_9"
+M@@D/!1PSTU)@5C^M,/Z+;=YA]>$5%2N,PSNZNJL//_8W>O>OI@^JH^(GTDC_
+M<;6/*[TZ8)Q%WYU!_U8G8YX7#'T8A6ZO[[JBXW"C^_+X48&X%A7@#\$`8\99
+MBKK1\6#T75>-4[)7+/+\0OW53S]6&4YMIC<^BKXQ7^N-[^>I'*+%]ZNJ-2<&
+M"B/]'Z'!T.(C4?!=/?']/N+\B?#.B/+&1U+OVE;-OYW:DFI+(#XJI(`-%^BO
+MSE51TD[3\RT!7DSN_RMTX7P+C0.38-+*]T=).]+NA[0Y<4*XUQ@3UUQX-0W.
+M#?/?2@GJU$86BRK4WMCAFDG9JV,]50UDHMZN%=LJN+ZWL'I^\XO6[NUVM8%2
+M$[+7W33#-XZ.:+;YPRDINLZZ\PN5BOZ-JF<:3M\AC)"&<;0+0/W?VH\#M.V/
+MWO<1?]\(2<_@?=[A)(2Q%K23-.;*6T*BK?,_>HBU(U1-`ZSU;FQP_,$0W+>S
+MHTR["!X6;B,2QF-/W@M2F78:K>YOBCE3:*9%,V[\;Z8>!D40^XETO!K0F;H$
+MU7:T=;Y1>E]9GRL_EI>.-!^\DS?!WS^AT=4-P1F+F[63=8G4GS2*GK[E<]::
+MAWZC'I=\:)"]`N9;9J@2KMI')>S9022*]]5];`NVT/C/YP9U\'U4V3YW9RY.
+MM,.HX9$T'DLC8GL.TJP.^C8XUK.C`3B:"F#:3/_C7RB=%.-N+KQ4#^[`00[.
+M!CY?Z>]NKM];$:K@0[]1'-@CC85MYVB>TS(JEO8>-6FC8I$Y8'3:0?T+5MMZ
+M\_0>_<.!IR36X**^5&$LC1N'1-[#&Q^+C$1:@=64N3/Q1#1UT=K7CXS0^2][
+MJ`^WEOIP_D_VZ3HW`@;0>N>R8X9&Y[*SAE+T.V4$^#*#(;B+:@;-D?"_\1&-
+MI*SAV13'O>XUWN(U6I%-*U'K0QS:C`AM1KC,3?7&K5%]O-551Z$^UOBFVR.U
+MQ(%:8C\M,4J;'A/IJ70$XE9[BE<O+?E\YT.15K8I:>^^S;0T'/58VSR0?^AK
+MN;TT<:UZVE3_1V0,(.J'^JD';-KF:/S8^=!("67G0\.#OX;J(<>M\:6O#)U;
+M0KUQFJ/LH$@KZ#FMG-[3-HY4P9Y?-L8/5-G,\+]#H^Q5T/9W>A^D-&BCPFAT
+MM%-`43M'A:L]-T:%C??4+JVJM?C&=HST.K0>U'0YM(D6S>J-#]=&67TE#FVQ
+MC7Z/MVF3P[VC'#1_,E3+G:?C2MY7'T+)3%E%WR[H&RI]Q1SA'6_S)EK)-!EO
+M]2;:R#HA11^N)5H].QW:(AL)U8QPV,]:?'CI^'"3-]91UT_-GZ'1=6O,9DIZ
+M49OQ?Y0^;_VLMG&BW;=5?%+Z-MI4I"ALYSC%K782@=A??HK*3/L,1>9NAN7/
+M58>W'%:%Y#_[B7R8WNZ(26IVKXE):'$_1</-;ZC2+FX*%#D";ZA'?_A`1#[F
+M2?)S78+>W,H,ZH%+&J?@;]U,ZLPA`,^[JJA=?22,HK#`&ZH@GZ3[@7U0Q=X9
+M81,]QY96':,VSS>]3Z2WB]8='4+`0HLVA')KALJM$LDMXO`^R'>X=YPC=`]>
+M:D_FM/SJ37)XCAD[)[;HWU%#V[]=K`%&16COHV[$5+LNT@Y4>/-LB?YA'_`&
+MM(TQS>[O*6>O^8"57I,^_A@2CF\7*[RB"%H#<BH^W.CJ/6.F_TM#L`LI=L65
+MWD*;;YPC9H?[<\GJ`Y^IQ?@R2>1T38AR:!M'?XE#5<.8AZC^%4VA&,<@/I-[
+MA(K5AE@S#?QI<987F=8136)O&(=T\M8,2+&5%-P,B+:-A*RQ_B:J_WJ:WO`^
+M1&7HJ8Q(].>^3RT2C/4>OLD1VF1'0,7+^_6WE_U0W?_`3I5,SWNJ=J.I03TH
+M=`0*PP*;54$_-5P5-+5%8.8IEB>;_>698?]*(#/WMA'(P220`T,$TM8JD#-V
+M(WL>I-ON+IYYX><&5](D3QE3#[7S8;SX1@6X\GLJ(V$@T,Z^D`':@SAF?)C+
+MZC7$5+M_5G*C7W4D%^I[*4GW!;ZG]M']S1?V/_V^^"=?V/^`[O_.!?W;S/_8
+M06HF.*>$<LTZWY!!DZW\Y>]?<#K(^>6U[Y\H\+<CSH%RY_DS/Z12UUZ+4+-2
+M_2,^5#,&??&!JVF>H*4_[W94W-&LGH!T])SAO^A#7N9(`T34JLC\@K>H_#ED
+M:V$WXSXZW^AQHHI^HG$K;R2MLE3!J$6?UJ(P]8:\_6Z+,C,KO.H5KWI:2VA6
+M-HIQG^M&A.:S](Z)LQ;]Z'MMW:\D`\W>D>]">-![O(1VZ!YAX#'TH0]K[A;9
+M5SNRPN?AAUMHZ*Y9"RO?T>F'%0G-Y5.,6C,8#$K(>?GTPG8UXN#99N8UGWL_
+M^;8L4#(]1C%8XO!Z"&$G_OYT0-M1[]#.F+T1G&8UQD(I:F!5>3;@NDR2D6!%
+M"A1//DL?S:1MFUQV:FF3GHAV]7^[:M=H;SE?24MI2<L/[E[V-R;_ZGM<!659
+MH<6W:"-7_*;^(!D:'%!+*;J3<7'R5UB87QE4VV)%$=`>^8L1:#?%G_V-J;_2
+MQ`O8?/Y=!E;QUK)]Q1%>#^VR$8B>X7\EY':'MRX'Y9MH5LQ^\DV,*MC"#@BW
+MOJL/"=LA$A-PC85M%.6;:)(=S5@F2CIYMK6H?MKH%FV;6=V+<=N*;#%)ML).
+M,`+J1W+[1GN;JBG<-O]@VDMPI]JARVU!X5X24VQU]8+6CVDL-&F-_(EM[0X>
+M]V^ZX/>Z3[?IANK@W=!K^Z18+.5T7G5%S$F7'=K?HNVJ[SG:2_WD[T9YSEQ6
+M<N!??*`[SQ;(WV;X[?-UFM7V$.JL(W6^CM#T:EF@N!=95/)LJ;O)2.N6Z-9\
+MP]1IK"#]4ZM%+])Q:FW/V0GY3N8(IN9XE3JWJ:.J:$V=N+Z1)J.9/OILZ_DF
+M7UQCHO^FW=R.M)_;U!#*<]VU.T1?[;B@ON+YAG/S_]U$PR$A$PV]DZ):9P@-
+MJ:*):B.I,IM^9QP;9?%UZ!$2T\7!!SN'/&CL\KM_U/G^J<<_-S4W;_&_3L"-
+MH3,=U3Q7KRO*YET2Y4!JPF).%_1LJ:HS_?0L49ZCYI_6)=_[#^/'QH]^!3%E
+M\D_KZ#X>\'QO]OQ@_NG9Y'M;@O-YE1Y16R=#HDN&OTG?D`8D.%#4U!E,:+9O
+M[@'[]I-C]LUCB]!_;?FDV=F9%M\[-:.GR@0%$H_WEGYFWVPIHN=JG9JER)?>
+M&'(F7*FAS?KUP'MZ%QMJ;P1JQ\U>[\@;21>M5$,H@_>=_E&+VZ_%U7B*PPWV
+MY0O5R3OAM#2V!ZV,G6JINY?.]8DIMN5W<O>';BZ(HB==W=L^I58ROZ6D8*A%
+M?4=NTA*J?4E^+6F/+^&0EK!+K;;=KU;;UCB58'L3:M3^IRO1H5GIU))..6EG
+M:]IX-FF_VLP5'O#4$L[B@?TTYJ>Y]]/FL>W>.R'O-;1_[WMYKW%GW!;51?84
+MGY##G0,)6SS%6XSVLJ=4T[#'OGFAQ9M4;=\\VH0L.:4=<&IQ&ZJ^=6C%Y>C"
+MV#=/L&C-G7<%O=:'>G4,>NVL.N;@>U:M6NY]IK*K]^#=6E*IEK!<95LI9=MR
+M9!L2NJ'J*.VDL+[S7BVA1CNCJ&JUJXPG;@]D8(_3L]B$DIF("O<6<3$@:8N6
+MM!71*`]WSXI`PE9/7+6)]GGWW&<RN'YXC^R-`<5;%X5Y$W;Y+(O5?O_4`E>>
+MF[+X9PED*_G9IJ)D@FNQD0OYIF7G`DO1,-MIO<TFXRDF"W^B!6`EUP3<F[Q)
+M6\U)6Z!TJOT#U!F/N+-E(OIZ>SS;3-/\?7ZEU8X;#9RM3N\$$PIBNWWS7BUI
+MG<IGY&3"6F_2+BUIE9=6A-/Z_PHG[9NZD3CPCIUH<GJ73+0X8]S;W3:UZ(:V
+M96^L'ZC]B,SI2PL<5=:ZUVEQE=IGWKBU]I?C*I'S]LT?=]X;LZOP&K5G1J79
+MO0Z)Q]-%%WF3\$Q2I0K`OGEGYZJ8]XL.#S[E+=Z"=GL\DNX+NT]+6JW&5S8:
+MFU41VD9YDU;;-_>D%_OO[?^C]A%EN39TE-J'>^5;E*S^)^V;3WKB5I^;4A98
+MNMU+QP%T5D^"(VT(/^A*1%KTN&Y#%OALB[4$U==.VDB[BZSDZ*9ZD];8-YN,
+MN[2X<CK49B7EAC9T(D+QQ*U1,2`%%4[C8`A-I3=IE5/K0E^+DE9YXBI,M!]<
+MTM:8I(WVAU]4IW!29:9#>-1ZP43M@+EX2\R!DMO>51H'98;*28)AWPR!W41;
+MCY8K\9]^WSG>;),K5]>D<J?F(+F)*=ZZ9!_EP$[+8OJREG1*Y7A"<^?WJ4)[
+MD\XRW4(TJGFX-V&_UH46P$XD*3_"4EZKI!ST,::/$[W?&X<7:GS/NMHNG+K!
+M79!_P]S,G!'\AZ@"]4O];=]^7_2V/@Y#1G!<&)T`>IO5U3/@CIB:.&WF##_M
+M#UHW@68Y[V[[K;[N!NXS>P(F>UD?^EA48C&Z^\(VZ>`9?GEAWYT&VGD59/3\
+M*WR>RK&!0.(T_R]0K/575."NPS/<7-1U"VU157>";*B=M#0'SZOS=FC#!BKK
+MR19/U3G/F9[VAVC[=9H(Z5T?QQ,A;9"EAC<-!D(+W'[\;GZ3[VV%JWV3[_TK
+MMTN>W6E*)0/BP9TF/ZVSOI_ZVCM-D92V7/Y-JXGJ4OGWP"YFZ8_O-"G=?0?_
+MIO4$=;?S;^J*UMVH^NSGSTMM8_;47?NNM/_O_W;[GYJ>GY^K[_]_XV\TP,-#
+M&N!@`0]]DXQ_2H)F_)V*7^UOW&J`Z.<+9.<6IO^;%OZFT!9^!ATP8$,;K[?O
+MO=NU[W3VP+]NX_F)EK8&H'-:!\/5)L/`'.`4LV%@(3`,6`*,`#X('`-\&%@-
+M?!)XQ&`8^"?@*+SW''`>\"7@5;C_!K"+T3#P76`:[N\`SL1[:8D=#,O-AHB/
+M0-^`^Y\!9P./`*^!_S?`;<#O@;N!IX`C$,XYX"R$V_'.#@883`.[`U?@O=[`
+M*<`,A/NVR1!Q.>C[06>!WHEXK@'MQ_N#@.6X?S/P3="W`2]#./%`]&@'3@8>
+MP_T9P/5X[E[@:XC?"32"SD-X'R`\%[`3XLG!_2-XOA"82OD$_!+A/`@\`%R$
+MYUXU&B(>!OT0Y1<PG_(+^#>$MP3^TQ#><Z![4KX!KZ5\`PX`O@N$C3QP!_`/
+M>/\CX"6([S-@#O`(L!?E%W`"GOL>>#7HTD1%1RP'SD7XIW`_F_(/:$$\Y;AO
+M1OH[3N]@F`ZZ.S`-_KV!4Q#.Y<#W<?\:8![E&_`-A'LS\"'*-R!4QL!XX.>X
+M/QDXF_(-^`O>OQ>8BO>=P";XYP!/4SX!3\*_!/A7T`\"HX$KD9Z.2,_#H"V@
+M*T#W1+X]"=J.>/X$W$3R!1Q*^00<3?D$O!/TN\!K*)\H'<"/@%`:`S\#K@0>
+M`:)5'O@-L#O"_QZX@N0*V)GR!1@!7(5XOT"^K08^AOC7`+\&=DSJ8'B9\@D8
+M@W#6XO[=2&]OT+MQ_W+@2WC_&N`5H`<!:TC.@(?Q_&U`%^*+!SZ"^Y.!F7A^
+M'<*)0CCK@6N!,W#_%,D=<`[)'7`#Y1\0G=V!A<`%E'_`8U0?@3>!?A@8`7P2
+MZ$2X?P)V!?T<\$?0+P%'X_DW*'U4'X%UP!W`6.`&Q'\<<K(1V!_\;P)"9T9L
+M`?:Q&"*V`N]`/E0">X#^".^AJSEP.^B'\-QGQ#_H7:"KP<<1T*\@W&^`?Z%Z
+M#'P"?)T"G@.>`^['_8XSD$X\UQWHI'H,O`[TY<!E".\:8"7E)_!9RD_@1\#;
+M@.\`]R"^SHBO&O@E<#_P#:2S!K@/=#R>ZPCYF0P<A.=G`!]$O(?@_Q<\=R_H
+MPXC/"?R8\AGX&)XK!(ZB?`8^`/I!X`^4S\#%E,_`(7C^3\"7\?YSP#+<?PEX
+M.>@W@.LHGX'[*9^!Z+P,_`@XDO0=L#?2=03X(]5?X-TDE\"S".<4\`622^!-
+M\*]%>M&B1W2<B?A`=P?N`O8&?@T\#O]=I/=`]Z=Z"[R,ZBUP'>4;<#_E&]!/
+M<@A\'K0?[WV(<!N`'R$_)N,^^D4#&TEO01Z:@!,1;C-P"\DG_!O@WP+Z[Z#O
+M!;V-\@\X&FB8VL'P,\+)`3T?M`7T,81?"+H+Z4?@/Q&O%??OQ',V8!;P0=R?
+M1/D+]%#^`MUX[D_`8J`#S]V$Y\*`D<#G<+\#PGL)^"(P'/?S<?\-T`]3OA/_
+M>"\"]V<B_AV@KP(="=J$='\$>@WBB0*-YCFB'_`,<""P/\+Y#/Y7(MPCP!22
+M8^`8*A]@$>Y'4[H1SE`@^NP1PX$^TK/P'TSR#1R)YSO.0GZ3W@">(/D&FDF^
+M@;^0O@!.(_D&_DCE!/10.0$_A'\\T$?Z`CB+Y!<XC/0#\`SI5^#SX",'>`FU
+MU\`.D*L2X&O4#@$OQ7,/`UT([TG@,\"12&\OI/]/H%>3_`(/D5X%W@%\`YA/
+M>A5X-^E5X'W4_@!74OL#_(SR!_@'TJO`O90_P`+2J\!!H&,13R;RY1SH.ZF^
+MW]7!L)GD%_@*R2_P=6IO@"U4WX$K<7\0<"*U-\!HTI_`7Y&>>"#ZF0/'3E5\
+M1TP&#;-ZX`S@&L1W+[`7:"?P+LH7X+64+\`:JL]`+^4+\.]DQP"_0'A/`O](
+M\@:,I_P`/D#R!70#QR.^/<BO-T"_1>TR<!'9,\!GJ+T!_D3Y`GR#VAM@!OR_
+M`:XG_0>\'#@)X823G%#\>.X<\'ZR9^Z&'D2Y=0<N`MT;6$CY`GR+Y`38E^HS
+M,!EX,_!UDA/@[TE.@,]3.PS\F-IAX(/4#@.7DIP`W:`3$7\WZ.\<T(^`GCY5
+M840AZ#P\5P)LIG8%^"+H6?"?0O8+Z%LHGX`C2.]1.BF?@/\$/9OJ#_B:`SP+
+M3`.B=Q&1`;P4F`6\&N'D`2]&/KJ`CP-?POO74[L$G$_R!CQ!\@9$1V?@HJFJ
+MGD8L`9;B_8]P?S/I3^!P/%>*^QJU-W<K'/@-L)+D$'@<N!S^6^%_"G0QZ5-@
+M#ZJ7OX,^H7H)'$YR"-Q#]1+X!>AK@#]0?@/K*;^!;^'^;<`>)(?`>RF_@5&4
+MW\`QE-_`"+*O$.\2Q.L$O1;^.4`_M=_`?B2'P`=(#H$WDAP"3U']!`XA^Q"X
+MFNP=X%/4?@.]E$_`STB_`=^A=@683?42>);D#SB+[$+@$]2N`&\A^0..Q_U3
+MP.4D=\"-E`^S88]1/@`O)[D#CL/SEP,UR@?@:JJ/P`3@2O`U`.50`0R@G%<!
+MGP+>#/]#>'\UR3?*:PVP`??7`N\"K@,6XKWUP+'(EPVD9\G>`":2O0$L`MZ&
+M<,*1KBV@OP.]E?0WWHO'_5ZX7PFZ+]Z;#/HPZ4/@K62'X/ZON'_O;%7>`YW`
+M)7A^%^Y_@??W`(=0NX3[3^+Y:M#?@RXDODGN@5^1/0K,H'8(^#F5![`SR3OP
+M.Y)WX'W4S@,?H78>N)W*`_@IGML!?!7A?01,)#D%OD/Z@-ZC=H32B_O[$7\?
+MI+<&V(C\.`2<C/1\#__?P;\6]!C</PX<AWPXA?OOD_S.5G;.0#_NKZ5V&[B8
+M[--[.ABFDAT%G$CE"$PANQ3X9](?P&54CL`<TJO`=))GX#CX-R*<EQ!?$S`7
+MZ6H&/@IL`:X#&M#OF@I_"S`/\5J!+M`V8'?X.X`O`,.`MR,]X<!PLK\0_@]4
+M3X!EP!F43JHGP+?);@#>0GH:.)?Z!\`=9"<`!U+]`!JI/(`NL@N`^Z@\@+E4
+M/X`74?T`OD;E`?P)_N\"5Y)^!I90>0`?I?X`\&%JMX"O4_T`6N'_/7`CM5O`
+MU50_@,^17KX7_0YJKX![J?T&WDOY"CQ(=A;P+L0;`7Y'@]]!H#^E=AS8C_I)
+MP'\BG$CXST&^10&O)'G&_3[P[S=-\1\Q$/@B,)KZN\"AU(\FNP+8#!Q)_6:$
+M'SM-E5O$6&`\Z/%``W`RPMM->@CX#=)[+_!5:@>!JTC_`(^070O,)?T#?)/R
+M%]B!\A<XF?(7&$_Z!_@NY2\PF^P"X,/4WP+VH'8,\58AWG=!)Y(>`J:3?0OL
+M2>W,-&5O1TP'3D)Z/\/]#,IWX`MD+P`K2"\!TX"S:+P`^7(*]&GXAR<KNVQL
+MF*!#T"9H%;0(&@1;[F4<+_389-4/M,4*CA0<+OY#!:,%!PKV$XP2C!2,$,P3
+MS!+,$$P3G",X6W"CX`;!]8+K!-<*KA'<([A+<+M@I>!6'>>@?T/A"JX77"=X
+M:([PD<*X?"YCJ>`B09=@EF"&X!S!V8+3!1,%QPN.%1PI.%PP6G"@8)1@I&"X
+M8)B@3=`J:!!LD?0W"38*^@6/"QX2K!&L%MPCN%VP4C#<*?(E:!4T"#:G2WR"
+M?L%:P1K!:L%=@I6"6P0W"JX77"NX6K!"L%RP5'"18)Y@AN`<P5F"B8+C!6,%
+MAPM&"_83C!0,%W0(6@4-@LUIPK^@7[!6L$:P6G"78*7@%L&-@NL%UPJN%JP0
+M+!<L%5PDF">8(3A'<)9@HN!XP5C!X8+1@OT$(P7#!1V"5D&#8'.J\"_H%ZP5
+MK!&L%MPE6"FX17"CX'K!M8*K!2L$RP5+!1<)Y@EF",X1G"68*#A>,%9PN&"T
+M8#_!*,%PP3!!AZ!-T"IH$30(MDB];!9L$FP4;!#T"QX7K!4\)%@CN%^P6G"/
+MX"[![8*5@EL%MPAN$MPHN$%PO>`ZP;6":P17"ZX2K!!<J>M#T0,9@FF"<P1G
+M"U8(KA0L%UPN6"JX1']^'NOGY8*E@DL$%PFZ!/,$LP0S!-,$Y\P3_C+$?[ZD
+M4W"VX'3!1,'Q@F,%1PH.%XP6'"@8)1@I&"X8)F@3M`H:!%LR14X$&P4KQ'^E
+MX%K!-8+;%TAY"VX1W"2X47"#X'K!=8)K!=<(KA9<)5@AN%*P7+!4<(G@(D&7
+M8)Y@EF"&8)K@','9@K,$IPL:LB1?A&X6;!)L%&P0W"7/;Q>L%-PJN$5PD^!&
+MP0V"ZP77":X57".X6G"58(7@2L%RP>6"I8)+!!<)N@3S!+,$,P33!.<(SA:<
+M)3A=,%%PDN!XP;&"L8(C!8<+#A6,%APHV$\P2C!2,$+/GQS)'\&U@FL$5PNN
+M$JP07"E8+KA<L%1PB>`B09=@GF"68(9@FN`<P=F"LP2G"R8*3A(<+SA6,%9P
+MI.!PP:&"T8(#!?L)1@E&"D8(A@N&"3H$;8)608N@0;`E6^1;L$FP4;!!T"]X
+M7+!6\)!@C>!^P6K!/8*[!+<+5@IN%=PBN$EPH^`&_3[26V0RV#8"36:#;0/P
+M2=!C<R4?!8<*#A2,$HP0#!.T"5H$6R0_-@F]07"=X!K!58(K!9<++A%T"6;I
+M\>9)>@03!2<)CA<<*Q@K.%(P3S!+,$,P37".X&P]O(42CN!PP6C!?H*1@N&"
+M#D&KH$&P6<)M%/0+U@K6"%8+[A*L%-PBN%%PO>!:P=6"%8+E@J4Z7Y*.68+3
+M!1,%)PE6+.1V=:5@C=S?+U@MN$=PE^!VP4K!K3K?@DV"C8(-@G[!XX*U@H?T
+M?,SO8/@:\FD`5AL-MBWY(E^"&P4W"*X77">X5G"-X&K!58(5@BL%RP67"Y8*
+M+A%<).@2S!/,$LP03!.<(SA;<);@=,%$P4F"XP7'"L8*CM3?=\G[@HF"DP3'
+M"XX5C!4<*3A<<*A@M.!`P7Z"48*1@A&"X8)A@@Y!FZ!5T")H$&PI$'D0;!)L
+M%&P0]`L>%ZP5/"18([A?L%IPC^`NP>V"E8);!;<(;A+<*+A!<+W@.L&U@FL$
+M5PNN$JP07"E8+KA<L%1PB>`B09=@GF"68(9@FN`<P=F"LP2G"R8*3A(<+SA6
+M,%9PI.!PP:&"T8(#!?L)1@E&"D;H^57*>J'<I<9E;<M=:ES6UE(JZ?>H>2FV
+M.1Y^;JA'?:>V17O4>*YMH$=]K[;U\ZCOV;8H>?[0`_Q<S0/\W/X'^+GJ!_BY
+M/0_P<\OEN5)Y;HD\MTB><\ESTQ]0XU]C*Q#^]VCG5@IZC`;##).!ODVK:PY<
+M.=VCJ4MT9I\<TC#`R/[U<*GX?37<!CC:X^Y%N+4RCX@VH)J$^_%PF^&ZPQ4B
+MG-7`SGAN._!D2+COPKV(>[?`W0M_VEN8C@W93_'@.=K:[''09^"^`WT;Z.'X
+MW1_N>SC:>9,.=R\"YL,_#;]/&5O#I^ER#\/15C9O`Z.`=#K(*>`R8"+<5XAW
+M&^C%>/]GX#]QCXX)HAWU^P.O`MX*-P+^@T'3;BQUP`.@PVCZ*@HZG?(.]Y^&
+M&TO\@?X)OW.!N10NW'UXE@[VNACWLVG.*7">@1?X'P>.QS/?`.\%3;OLA@/I
+M/*'#N'\-<+21'>U;<C'H+L!,^.V'*X;+I7+`/3LP3<KS;W`?XMY9*;^_PUT&
+M/UH;48%[;P(OPO-+Q9_./TZ$?W<@'?PX%OA'^"V5\J4SAA\!?1'\+L=[5X+N
+M"CI?WK\$;BW\K@>]#VXZZ"-`.MD;\D9S6`R?P)]6ZD\$TNZ/5QI5%M)W&@,=
+M8),"[`WW.SR_`O3-(?*R#*[8R#*P'O<C*4XJ#XF?3@]IPOUIQ"?NO6#@S4+Z
+M`&.`0PPLDY3GI^%HAZ^^)'_"W[.4[X@W!7@I[M/6["_0-$O0]P&O!=HIWX&1
+M0-HJ_$7$][V\?[7(7"GEM9%EH`#^I7#_A/L,]VD;1=I';@;\:$.1AX#_-//[
+M<?C]-R/[76JA28E<U^BHD&2SVLY1U2TZA>@>X(=49D!:6_`DR2C0;:)C/PV&
+M&X%1N+<$CG:.3B`YQ.]T$]?=KK3W(N[32=<T(]0&I!F9=-CHM?!KA.M!=0MN
+MDZ2/9DI.I[H'/XN%Z]ZYD/*AI5#1H&_'_==-G(:%<+3)7B[N?0W\"O11N%YX
+M_Q$#R\IPX`_`Q<"1P&(J=^`BX&1@%N*G6:)Z/)?"O8K[+B`=4D&S0$<`:=N*
+MV4#:'24!^!#P+I)%X&O`@\!"XA?Q5YGH$PK2#)KVJB==0.N2:<DI[3I*97\1
+MG`^NH\@7'7)!\]WOI'M(_WC<NYSDE^(R<5A_ANN`^]<":0>/2C@Z+N,HTD][
+MGW?#[YEXMH^%\W(/7#<#Z[1/2?>8N8P>@*/=X,?2N\"[@5V`ATF/27G08J9L
+MT+2+-1T:6@A$^V-(([G!^[1+6R1P*N@K*'\H3_%N'&@'?CLD'#U?[Q)=H=/D
+M3;S/1AB/PVW#[\N!OP#I#%M:?T=UOQ&(_A/-L3#$`3OBF2%PM+KF`/S7X%X5
+MW/6@:4ML.N-HH(GSEG;+^H#*E&2.ZAB>&P;Z(_RN`O[5Q+IZ#_`ET`^2'@0.
+MI'P$1@!I%B_IWG+@&&`L\!I**Y!6;-%A`C=1.H`3@;M$/]+&<[29S^-4+XVT
+MG@AZ!TB[1T63O%#=0GI&&;@N;97\&HS?J^`2J)X!>P&3S+RL)`OT#4!:`/TR
+M,-;(,A)'[2#H/^$WK9)\#O@7()U;]3N*%_ZTPJE'2/X7X/>/1FX+Z*)=5O93
+M>0#O!SX*YT2\[U&^`@>!?@WA/"_II'5%I$MK#5QV-!^:YI7?*&$G`FOQ_``@
+M32>GNO0'T+=2/<7OJPS<-EL1WF"XSAPL?>M7=8%FFU,=Z4?YC_>N`](IP0,I
+M'X`QQ`]P#-"%Y^*!R<!QDH<3J/[!?R)P-^@[@+1]ZR0#UU%:A3T2\28!I^'^
+M+.`*(.T23S;)W<"7@/<"Z8!`6ITZC/+$P'F1`9Q%^H/X0W@YP"]`+S1P'<X'
+M+@06`.F4-[>!=1?MTCL*>#^0-H0M`>8`'Z!T(CW+@>-`TXZ'SR/<!X&WTL)]
+MX#S<I_V=_@JD`TZJ2%8,K,.?,+`M\93D(^W-13J9MA!]"O@T\!&$\V<#VS+/
+M`#.!?P72&OEUP'\`GS?P(9ZTW=T30-H0DV1AHX3[&AQM<T:K9>X`TD3^]4!:
+M3_0FPM\,)-N/UD*1CGC;P&W/5@/;@I7`CX`T2YSJP';@>""M3:,#XVF)#M55
+M.ES^$ZJ;0#IQZ2.@#^]]"IP+^@"0CHNGI05?(]\^!TX%_86DDXXRH',E#@,_
+MAO\1DBN\3TO08;_2W%=#$OR_!7X*FB;8SP=-BQ?B2;\!5X*F@^)/`'^@_$`X
+M/P+30=..K]WPW$_`^X"T1M&)^[18EVR>,\`,TGG`.?#_%1A&NH'*D-H'8!X<
+M;5^]R,BZ@G0TV5X3S&S[T$5MYZ]&UNTI9K81W$;6L<\;63>3;49U;+J);<`O
+MC6R[T$6VQB$CZ[)C1K9=IIM99V\UL:WQOI%MI5>,;)/>86+;A70IZ;HU1FYS
+MGC&R[KG:S+;N#C/KRJ4FUFD5)K:U?F]DW?6=D770*!/KR#M-W/:6F+@N336Q
+M[?2!D=M8:C2IC5YF9MWV!R/7E2XFUKWO&+G-HD-0J8Z0S4^R\[J1=<\",^M@
+M.BZ99+/,Q'V&X29NLZ\Q<9M/?0;J"[QA9)EYU,0Z@,X2)YFH,[%L76_B.DZV
+M.+61?S&R#K_2Q+;`(A/;2B\;V;:F`R5)!]UD8IO]:R/;G.EFEEFZJ(^SU\@R
+M--7,,A-AXKIM$)FALTJI;GYA8IFD4ZBH#;G;Q&W`.2.WS;U-K#MHDT^R@3:*
+M3%E,K'O(]G-)N"0SSYC81EEC8MMKJ\C>GTS<MM.Z6[)%^YJX#:`V?8F\3[9Q
+M!Q/K,K*)J6[=9N*^S%5F;GM_;V:=1GT&:DNI+2<;=(6)^WZ_FKF.WVYB7?N(
+MF?LJV2:N:[0I+?6ISIBX+S#:Q'V)7B:V1>N-W&<;9.(V<K.)==0D$]NHGQM9
+MU\6;60;7F5F&AIFXK_&<B67Y,R.WE1-,;%,9S5RV-2+CG4RL8Z-,W&9\:^0V
+ME?I:5.>.&EGG76%BFYIVWR=;OI^);7.R8:GO66[B-L1D8AG9:.(R^KN)ZUJL
+MF6W-:2:V(:DO2FT-[3I*,DVV$<FHT\1]7KK(ICYI9-NCNXG[GD--7)8#3%Q'
+M8DS<-Z&%Z:3+>YG95J2^%;498TRLZ[>9N$]*-B/)T,4F;@N6F;C-?-+$NF&Y
+MB>LHV5YD4]*.7-3W>\/$MM2#)I;1)!/+=I&)^VB_-[$.?]_,M@5=GPF2[?:4
+MB?,\P\1EEV+B-G2OB756J9EMTG$F[NOU-K-NH\-EJ:_L,'%9'#*Q;J.^!=D6
+MW<S<1E6:N0YN,7$;DF#FLJ33-ZFO.]C$NOT&$\O6C6;6618SCP%07Y?Z#A^:
+MV%:ZV,QY_YV9ZTJAF<<$Z"0&ZO-=9>(\[V_B/+K.Q+I[B8GK[,<FKMOJPF^/
+MB77&O2:6D2DFK@-_-G$=7FGF.I=C8IF<96:;)L_$;5B$A77C9!/WN0S2)M%%
+MLC'/Q+KPK(GS:K6);2;:]);:PB=,7+=>,7';1&<<DDXY9F*;AB[JL]QB8MF@
+MOA79U+$FMJEGF41WF;GO_X.);?B[3%PW.IFYCW#0Q#KS!1/GT6PS]R%6F;B.
+MT<9$I'/N,;&.OM_,=8GZ9I27_<V<ET^96<8SS6SCOVUB'3W7Q#IANXG+DOH>
+MU%><8>8R_MS$?0:ZJ*YT,;..IHO&``K,K"/HHK:"QCZH#ITT\]C,HV;.@],F
+MML623:S[:+T@Z3*7Y`E=HP1)=]G,7-?^:.*Q&^JKDZW^KEEL#!/+=C<+C]'<
+M;V*=1`=03I1P[A`D'=?/S'WMQZ3,.YI99JC/06,K7<W<IMYA9IU29N8V]UL3
+MVP9OF;F.;C+QV!Q=5(97FKG,-IBXC:&+^@S#S5PF^O6EB67U,\D#@]@V=%'=
+MO=7,93'6S&-L7A/KKH=%%E7[!JPV<5M;;^(Q"[K(IA]HYK9@G)EE_@$SCW'1
+M*;HD\Q^9N<]_RL1C<F8SCX$,,W,9/&OB,0JZ:&RPQL2ZZ"T3M]6WF'DL[F\F
+MMMG>E3R?8^8Z2A?9)A^8V*;9;6)=V-W,?>8<,]?9<C/K1+K(QD@SLPX\8>*^
+M.EVD^Q\W\UCGLV9N`^FB//G&Q#8@7633>LR<1]>;V49_V<RV5**9;9,;S%SF
+M/YFXKSS(S'6'+JK#KYI85U-?F'3J8V:NZXO-K(/I&&_J>^T36?2:V0:@B_I6
+MOYC8!OC:Q+J'KK6"U!:]9V+;8;29^\P3S=P7\YDYS[/-W+8>,7&?Y7T3CZ%1
+M)Y_R>H>)Z_[E%F[[Z")9FVGF,:X^9M8]=-'8X%UF;BNGF5DWT?6J(/5!(\TL
+MPWO,/!9$%[5%\\UL$]!%.C_&S'V2'A:6`;I(9UQF9MOW1Q/KGHLM+`MT$:]#
+MS:PC_28>RZ&MBZBMI+XJU<U19M8U]68>>[O.S#Q.,;-.H(MDYTXSYP5=)%._
+MFGBL03-SFU)BYKX07=0V7&KFNG'$S&W@&#.7&5TTMMELXC'9)6;NL]!%==%D
+MX3%CNDCF5YA9Y])%NH_&=,B6I+$V:BL[6WCLERXJLRO,7+?-%NZSTU@$M0$'
+MS#RF]F<SCTUEF%E&[C&S#.\RLVZARR](MO,6,]<%NJB.OV1F7;?=S&/M=%%;
+M,=G,8X%T_2AX4I!DG0[(;A*:ZKS1PCJ8+LJ+"#/;BO2M@-JX2\PLRW2U"/XJ
+M2&.)0\Q<%]2%WUTM;/O=9.8Q)G6;=(V9;0#:JX[*_C8SZ]HF,[=I='46I+8D
+MVLRZ=X29=?X?S&R#_&1FW4$7C9V_8^8QGX?,/!;7U\RVV35F'BNGBVR<5\Q<
+M)SXS\YCQ91:V/>@B'O/-+"MT10B23*\V\]BYP\)E^K:9Z\I&,^MXMYEM=;JH
+M#W>SI(&N:P1IC.R<F=L:NJCMK36SC-,U0)!T]20SZZS;S:R3-IM95WT@>5)M
+MYK$=NBCOB\QL8]$U5)#R?H.DY4$SZW*ZA@O&"%+>?F)F'4X7C=TL-'.;0]=M
+M@I26I6:VK>FBNDI;@Y+N>LW,=8K&L*B-*C;SF*++S'V&A\W<]M!%??!4,^LZ
+MNNX0G"28(#A9D.K^7#/K[-?-W+>C:YK@G8+4]_[6S&-Z=,T0G"E(-AYMI7:7
+MT#06^JF9OUE\:&;;Z2]FKH-TT;>M9\P\AD\7M65OFGFL@*ZY@L3+,3.W5711
+MG_1G,X_QU9G9AGO:S'5\OYEM++I(IYXP<]^:KFS!',%<P3S!A8+Y@F1;/2EY
+M_(7((%UD.Z\5F:!KD>!B0?JF]5<SVX)TD<Z[PL)E]H*9=><_I*Q_,'-?X:"9
+MQPZ.F]EVH(O:UF_,/(9)%]E$KXJLT?608+F@)KA"T"M(MOB?S-SF_4UDA2[J
+MPVXS<Y]BIYEMQ<-F;H/I>ER0=,D^,X\AT?6D(-FTZ\U<=^FB/O0;9M8A=@OK
+M0+JH;/XN::#KSX)K!?\B^(S@7P77"3XK^)S@>L&_"5*>[I4XK!:NDW2]*/B2
+MX,N"&P5)5[TG>4H7U;$P"]<!NHB74V;6#;TMW#8<$AG]W,PV*5VDJ\Z864<V
+MF-E&INL]0>K+?6GFL?XN%L[S7T0&?C1SVT(7C4F=E;*XQ,)M%%V[!:DO6F-F
+M'=5L9AN"K@\%R<8,M_"8(5W5@GL%]PE^(KA?\%/!SP0/"-8('A3\7/`+P4."
+M)#.-9F[[Z?I2L%;PJ.`QP:\$2=8[67@,E"Z2]=-FUC%T^07K!$\(DNURD87S
+M.M+"?5JZOA?\0;!1\$?!DX*J;;-PFTC7SX*G!$\+-@N>$3PK^(M@B^"O@N<$
+M`X+J`ZZ!VWZZ3()F08M@!\&.@IT$K8*=!;L(=A6T"783["YH%W0(]A#L*=A+
+M,$SP(L'>@GT$55KH3V('CM_`?7J+,'BQT+H=%"5TQE$>*.@O=%X?IH<+73&5
+M(X@5VEK+_N.$/GZ$PYNLAY_,SR<)O4LZ@'?KX>7Q\W.$+I>,I>\=1CWA!OY>
+M3_[];F!ZN=#KAG-X/CV^2$[/:MU?TO-GH8=&,/VBT-7I'-_K0F^5B05O"YUV
+M-=-50CO&<GST?8[&SB-Y_8WZ'JORJY+]#PL]YY],-^KY_P^FS3*N.?Y+#I_&
+MV^E7=2=.WS7BWT\ZQM<+O>42+K\;A5XM#>MM\KY>_`GBGR?YFR3T.NDHI`D]
+M_0I^OTCH-5E,>X0N%WGP"EV[C^G'A(XV,OV,SH^34_""T&O%0'B]7?K>$?_$
+MY?S^#J'72P.X7^C24G[C2Z%;Q"#Z5G]>\IO&Q:@\ULSKH+Y1_ZKGW^<</HU?
+M$;U'.EQA0J_Y"]-10L<>YO0-TNE,IF.$+O^"PQLC=.,U[#]=Z$-BJ,X3NJ6(
+MP\\7>N@@ILOU\(YP>!5"AXNBH_XR\?-,MIIGI?JSJKRE_#<*?3R:PWM/Z/$6
+M]M\E=,8A#O]CH?/$0#DD=.0Q?O\[H:-*F&X6>H.)WZ?^B2HO^=#57>B\:[E\
+MJ!\16KZ1^O,B+P.$WI+!\0\3>JV\/T9HR_?\?)+0+9TX/9E"^P^S?Z'08^7]
+M8J'7/\+T<J%G2WU;+?3^!]C_>:&WBW[9)/1P,;PKA4Y[C-_?(_3*&*8_%3KL
+M`*>'VDTJKPI>OZ+:/Y7_Q]B_4>@:*;]FH6M]G!YJ7Y1^D?RV"3VG@..+%+J?
+MZ(O^0KM$/F_2WS_*SX\1>J,TO).%WO0ZOW^7S,69(^U#GA[^-GY_B=!+GA=Y
+MU?V%GT>%3AS&\?]1Z-A\YN=9/3TI3+\B]$BIK^\)O:N&P]LM=)@,:.[5W^_.
+MX=<*79W+M%]H]2$.UX]"VY9R?+\(O58,U<X=)#\^Y?=["5TJ!L2E0CNV<'A1
+M.BV&Q$"AQ^OR*_3`.$YOK-"'A+\I0F^5]F*6T'FYHG_UYT5_YPD])XG]%PO=
+MLHCI,J&7M'#Z*X2.3&?Z#T*'5W'Z_R;TK&^9?D?G7PRG?PI=*1VU_;K_0(ZO
+M7NCM/45>A:X(9W]C1TG??/;OVK%M_;](_&=G</R7"[U?ZL^U0L>.9/^;A"Y]
+MA/UO%7J]R/MXH=-2./Q$H;=X.,:[A5XBZ4D3>H[(>Z[0CG?8OU3H71)^N="6
+MZT0?"QTE[_]!Z`PST\\*?4@ZJ!N%CI[,Z=LB]'3IH%3IZ9&)>;N%7OD$A_>)
+MT`W2`3ZLYX]T^+X6.B^2W_]>SX\'.+_."#W\+BF?3L+/H_Q^#Z&C/^'X(H3V
+M"__7"AUY(X=_@]`;Y0/:K4)7B[S%Z;1T@.[4PY?V;K;025?R^TZA#XE\N(1>
+M6\SE5R+T>)&/AX1>?X*??TQ/3Q8_OT;HV#%,K]/3<Y:??UGG1]KS-X6>(_QL
+M%[KT(7Y_K_Y^!M.'A$Z4B<+']?PZ*/I&]U_%]"]"K^G!^6&S2GV4#G"8T'GW
+M<?A7"AW[%?/;7^CC;S`]6.@Y8M^.$+I?'(<W3NA=GTI[*738L\SOO4*/%_M\
+MGM"-)Z3]%#IZ(#]?*G3S#HZO0@]?Z#\+/;",T_^BGOXL?O\-G;Z*Z1U"1^K?
+M775^I/]Q5.@,T:?U0J\5`3FEI_\@TQT[<_M*ZU1I;F2/SA)^-/M?+'34?$Y?
+MW\[Z^YR`P4*7WR+Y*;1?[,/10H?_CL.;(O2L04S/%'KH1)%GH=>+?94G])H?
+MF%XJ=*/(AR9T7CS33PEM$'E?V[FM_MRHOS^/\^>MSGI^\Q-50@^,9/]/A9Y^
+M7.15Z.IQ3/\@=,1L#O]<N_CL7=A_47\.KX_0Y3(Q\QJAUXN]<X/0&\7^'R5T
+M]0P.[PZA8[OQ^S.$CI3V=X[0T7G,?Z;0VT4_%0A=VH_]EPJ]5>R31X3>]30_
+M_WNALU8R1\_H\4M]?U'HY2]Q_&_H[\N`\[M"+Q'YV"GTI`_X_6H]/)EH>5SH
+M+5(_OQ.ZYDF._[30L_2!CZX2?F\.SRYT[5+VOT3HX:]Q>%%"6T4_#Q:ZWTI^
+M/D;H.8])?T3HO%N9GJ2'+_IGIM"[I+XDZ^_+Q(@,H<NE?/-T6@8B%PD=)O6K
+M3.A*B?]1H2/*F?Z3T!NO8?IYH6L>YO=?U=^7_N>[.BW]QP^$7MF-T[M?YU_T
+M7:U.BWZKT_D5_Y^%3MO"^1D0.E+:RVXVEG\'!V^(L+'__B_9_P:A9S=P>+<+
+MO5$&!A.$=DCYS]#IY9S^N4)'RP>4A4(W2OTO%;KT5X[_$:%KT]C_::*!USPE
+M[9OX'W)R>"\+'7LQQ_^.T'..,_U/6]OZO4_\5\J`VQ$;Z],E'NZO_&AK.][2
+MK9O(O_0'PX5>+_KT*J%CL_GY`4)GB7P,%WJZM!=CNG%\&S+4/GB&*>(?*0-W
+MLX2VBOV<(72YQ%<@=(;T%^X7>KE,-'M(Z$H9[WA4Z`KY,/`'W7\_^Z\3>I/T
+M#S?IX25Q>)5"ATM__A-)/^U[0'.%:\6_.9/Y^TY_7SY(G-7Y*>;PK=VE_#_B
+M\'L+G54O]I?00WLP/4QHARQDBM7?'\SIGR#TIK_R\W<*O?UICG^.T*6B+S+T
+M\&2\JT#H:%V_"AW[!/L_)/1PX?\/0F_X)S__HM")SS#]NM#[I;PKA0XKY?<_
+M$'JU].\/"6W9R.]_W5WD3ZX?Q;]:[+=?A!XOY6^V<WG0NC6:L^D0FM:UTIJ-
+M<+OH!^'W:J$SQ-X;)'2YC"<,D_=7.=7^NH9)XI_E9/^90N<]S_0<_?T_,YUM
+M;UO?[A/_V=*?>5#HJ#<Y/YX0VBH3GI[6PX^0_IO0S9O8_U6AETO[_:[0X3*Q
+MX7VA=TE]V2_T?K%7CNO^,G[5H,<G]FZ3T)%B?P6$3EPL^M(A]HKDY\5"E_\B
+M^D#HZ1.8OT%"KY?QK1%"MX@^'"MTTW4<_E2A70&.?[:#\[-2\C-;_/OMX>>+
+MA8X5_:D)O7$XTX\)72GCB7\4.FT,T\])^+LD_'?%OWH^TSN%]DOZ]^GAG>'X
+MOQ#:NIWI'W3^I?_8+/0<^7!O["'O5TA_3.A-TO^_5.A::2^CA$[<S>$/UM_7
+M1!_HM(R_C!<Z]GJFIPO=*.-']PB](5KZ`T)7B'YR"SU2[)^E0J^7\<5'A9XN
+M]?=/0E<?$?D4VB'VPMMZ?.DROB/T'ND0'!"ZW^><WN-"-TE]^E[W+^3PFW7^
+M1/XZ]!1YO(B?=PC=I.>GT+4B']<*/5[:UR$]>?R+UHW2%2/^Q^_AY^.$KE[(
+M\=TIM.U2]D\5NE+ZRUE"5SPJ^2>T7_350T(/E`]_JX3>(Q.P_RKT)">']W<]
+M?)OH5Z&E^AO^(?1JZ1]5Z_'+A]4C0D?9F3[1LZU^.B7^5K&WC+VDO$4?=Q4Z
+M]A*F+Q8Z4>S'JX1N$/OZ!J$KHT2?"KV_@^2GT*LGL'^BT,-7R'BDT,U5'%^.
+MT'-NE/ZJT%NEO2_5_44>RH6ND>]'C^KI^1WSOT;H:OF>LKX7YT>DY,=K>GKD
+MPVBET+7"[VZAHZ5^[A-ZS3P9+Q#:(O9/G=#KKN#X?A)ZO#[1,4S:(]'75J$3
+MQ5[O)70_D9\(H6>+?-T@=&P]!S=<:*N$%ROT=)DX,4GHB#'\_`RA=TG[/U=H
+MA^B3!4);9$*'2_>7_L]#0N>)0#VIQR_Z<IW0XQO8_R4]/FE_WQ)ZO8P/[]##
+ME_[+1T*/+>7X:H7V2WOC#^/V.H_WH3(TBO^64^Q_5N@-TG_M?I'HAR?9_U*A
+MU4(57%<);8GG]`X2>O6E'/]PH9>(?(X3.DHF1-XE=,/['%Z*T+.N8CI3]Q=[
+ML5#H1NEOEPA=^T\.SR=T8B\9+]#3*POA_B+T'K$?7];3MX##WZP_+_V[2J'7
+MWL3\[=;YD_&%O4)7S^7W:X3>)>-YWU[$^K)"].7WXE\AXYUGA%XG_=G.O:4\
+M.DI[)W2Y]&<N$7KUK]+>"=VPE..[6>A*&1^^K;>N[SF\.XBF\D?[3B$FB7^T
+M3)!U"ITGXY4+A6[LPOZ+A>XG]M`RH1.E_[M2Z*WR/6UU;Y:W*-YGQ_"B^$?*
+M]Z&M>GS"[W8]OF;V_UAHA_27:O3\>9S]3PA=(?;12:''R_C46:'7[A;[MX^$
+M-Y1IF]"58G^$";U=OH=<*;3E._:/[L/\;.)]'0RWB;]!ZL\DH:,/B7P+G7$W
+MIW]>G[;M25X[VB7/CY2),!ZA8\7>]`E=:^?G_RCTAG<XOK\)72W?MUX1.ES*
+MXTVAU[W)SV\7>JV,=^T1>LW%_/[G0F_Q\//U0I>+??A3N_3_*O[6S_GYKN%,
+MKQ1[)USH/<]P?%<+/5[D:8#0:]=P^,.%;I0%`>.%SI#^QU2A=XG^G"UT[`CI
+MOPF]<3"_[]+#Z\#^Q7IZ1'XTH:>/8GY6Z>%/YO?_K*<WB^GGA?:+_&\,9_G8
+M*/*Q7?S7R/L?"SWP!::/"ET:R_&=T/,K@<,[J=,R@:]%CU_RL\O%TIX/X^=[
+M"KWJ8J8O$3I*YG]$"IV5QB5VG="S9'QTB-"Q,?S^+4)72'\Z7FB_E%>BT'DB
+M/[.$SI#QW#2A5XO]7:#[R_C3$J$WRO>7!W5^I%?[A$Z/Y?0_+?02Z2^]('3+
+M*7[_%:&/B_VP5>BQ,OZS0\^?.SC\CX4VB/U8(_1ZL1^^%GJM3+S]Z6(N7]G7
+MQ6"^1.0GE?.OVR5MZ\,EXK]+^OM7"QTN\S.BA=XH\R'BA=8W6DD0>DX<^\^Z
+MA./O)_HT1P]?]%VAT-4R'K)4Z(I4?K]<:)N,SU?HSQ<P?[\7.D/LV_5"KY$)
+MCZ\*/5"^QV\5VB(3DG<+[9")\`>%#GN#T_.5T.O3./X&/7UNCN^,T,UY_+SE
+M4I$?^=[2[5+F?Y+P?[7XSYDCXQ-"-U[+Z;E=Z/'R/7Z"T%&;V3])Z,ATII.%
+M5AN<4/X*O5\F;-XO]"P9WWE8Z*SW./S?"[U+X_2L%5J?W[Q!Z.:?^,8FH3?^
+MR/Q6"5TC]M8'0B^9Q>'OT],C_;OC0@\7^_D'R9_UR!]ZHD7\$RO8OU.$\#>'
+MT]-3Z":9Z'B5T+72?[Y)Z(J3_/QM0D?*PK4XH1.E_S)9Z&J9V/H[H9?;V7^^
+MT!MD/IE;Z.G2WRX3>HY\+_<)O3:+WU\M]$89KWQ&Z-(5,G\J@NN?3$<P;-3C
+MZR;VG-`MKW'ZJH6.D._1AX0.$WO4K^='$X?WH]`9,A_@C!Z>I,]RF>A#F:_7
+M4^CE8L]>*O1:&6_H*W2CF<.+%GJ]M&_#A>XGW_M&">V0!06)0L>*?I@I=.0V
+M]D\7NE+LG1RAM\N$]$5"]Y;^P=++6'YH'UG*T7+QMXH^_[W0NCWZ%SW]TKZ^
+M(G3TQ_S\NT)/E_'J'7K\TI_[5.@TF;]3*W2U]-=^T/F3_LTIH6NSV=]\N>B?
+M!V4\0VB;S`>X5&B_V#_7"FV5]FN0T(WZ?(K+Y7NIJX-AN@WZ0OQK+N/\G2YT
+MK+3GR4(?NDSD6^C*/O+]0FC'U3+?2NA2Z<^4"[WF'(=?(?0FL3?_+/06Z6_\
+M3>BU,C_LE<O;MC=5XK]HC_0']?2(?'TF]&J9<'Y,Z+$W,#]-.C^B3W[5\T_:
+MZTY7B'Z3^8X]A=XD[>>E0H\7_7N=T%9IGVX4>KW4CU%"]QO&\4VX@O-_H.CW
+M>\5_3BV'GRUTV@A^OU">GT7[F@&7B/\2*7]-Z%(9'WA,IZ^1^1!"-PZ4\22A
+M:^7[QP8)/\O#X^-;Q'^6?$^H%-HO\[OV"=TDZ?M"Z'4R7NN_0F\?^?D?=?XF
+MR_BGSK_TS[M%2GV2[R,7"QWV,(?73^@,^7YW8V1;>1@E_FOGL_\4H?6%'[.$
+MCI"-JYSMWL\3_[Q_R/P?H1-E_$83ND;FJSRATR*O?Q+:)A/%7Q!Z?0H_OTE/
+MGWRO>$</_U;F;X?0X^7]?7I^2/Y](?2&AT1?"[U+[/$?A%XD]LHIW5\VLC)=
+M*>4G_'05>F-?Z0\*W2+V].5"1\EX7W^A2^5[]Q"A$Q^7\22AAXK].%WH2AFO
+M3Q6ZHHR?7RBT5?3C(J%CQ;Y>*G2>?`]>*72YU,^GA'8,9_I/0J\7?;=>:+5!
+M"*Z7]?B^Y/2\?:5\K\OO8(@%_:'X3UK(S]?HX<M"J&-"-XK^_D[H2!E?/2WT
+M!JD/M)&0>E_J7U>A#?*]I:?0$?+\I4)GR/CDE4*7BKQ<)_022?_-0J^7_L`H
+MH<.D?S%>Z$J9OSA-Z+7R?6..3DO_>9[0ZZ3_E"WTJH4<WA*A^\E\EN5"-^YE
+MVJ>G5[Y?_%ZGQ1[^J]#5,K[[DM!SQ'Y_0^CC@V1\5>B1`SC^#X4NOYF?/R!T
+MXF"FCP@=W9?37R]TLRQ(.BWTKID<WCFA8R?Q^QVN%GX^X.<=0L^1^2A7"+U(
+M^H_7"%TJW^>N)QIX_`X>_QHJ_N.EOW[[U2QO(T7>$JYN^SUSACR_23;4N$?H
+M1)G_XA2ZG]B?>4)OE/E5B_3TROS74OUYF9]?+G2D]$<JKM;;6Z9_+_0LT1_K
+MA!XH^F"#'I^,[[XM]`89[_Q8?U_FW]3J_,@"F&^%'OJ4M`=Z_DG^_G)U6WW<
+M.4K2NX!IN]#ETSG\BX7.D/DOUP@=)OEUO=!KMXJ](W2CZ+O;A*X<*/5#:*OT
+MAV?I\8M^3Q/ZN*P'<`G=3\IWJ=!KI+UZ6(]/^G._%SI6UE>\('3U,J:W"#U>
+M[*]_"+U?[.^/].==3-<(/><Y?O^HT%OD^_,/>OQ2OW\6>H_8JZ:^3(^5[YE6
+MH<N%_S"AC\O\PTN%CA5[]"JA^XG]?IW0:V7^RC"AF\3^N55H@Z1_C-!Y7W'\
+M$X0^]#:_/U7H6=(?G"FT+8S]4_MR?:)]9FDOQRP]/+%'\X7VB_S?+W2C?&]]
+M0.CE,I[QL-"U4G^>TOGIP?3S0L^6]3\O"KU+].$FH:MEX[JW=7Z.\_M5>GJD
+MO[Q3Z"7"[\="E\I\RJ-"KYK-Z?U.:(O8-[\(O4;LD8[72'L@WTM["-THXU%7
+M".V0_E-?H1.E?8H6VB_\#!-ZJTR`FB#TRM/LGR2T5?JCLX6.E05Y&4)/DO8A
+M7^CI81S>`T*/+Y#\OT;LP9P.AE+0?Q3_<K&GUPF=]RC3&_7T2GNX5>B13XL^
+MTI^7!:6?"QWY!Z:_%KIRNK3G0D>+O?"3GCX9CS1?*_JL@/V["1TAY1<F=)Z,
+M+UTJM$/6BUPK=)2L/[E>Z*&BGX8*/4?BCQ&Z4C8.&2VTVB",RD/H73*^E2AT
+MN>C#WPD]7NKG7*$KA-_Y0ENE/2D0NF89IV^IT,TR'K_B6IF?E<WE\]2U;?7U
+MG^3YD;*P^`6A&Z1^O2;T1EGHOTWG1[Y'?:"GSR;VK]"ULA[I2Z%GR48@)W5^
+M15[/2OK6R'HH:S_);UG8'"9TA<P?O53H4ED?<(W0L3(??K#0N_3Y/[J_U+\X
+MH:,E/^\0>JC,YYDIM%7>O[>?K`?,D_%,W5\V@G`+W23C)_<+7=Z/\W>5GAZ9
+M?_&TT/WD>^[?A5XG]LTK0D\2>=DJM$':_VU"1T[AY_<(O5H6I'XF])*[^/FO
+M]/R3_ENCT)6R$/P7H=>*_=RAOY2?K`>S"SU'[/W+A1Z8P_0U0A?*_(_!0C?)
+MPO);A2Z]B)\?([15]/L=0N^YD?U_)_2NV]@_3>A^HJ\6"-WX=PZ_4&BUT!W7
+MDOYMY;M,]Y?^DU?H-%G?\+0>OBQ,_[O0B3*_[A6AATO__$T]?OD^L4/H2ID?
+MO4?H*-'?1_3G1=Z^T?-#GF\0>I7,/VH2.E*^#]-&I<H^D/DY=J'72W^JC]`-
+MLB'-U4(/E/G2_84>WI.?OT'H-!F_N4WH6,G?.*$;9?Q_ZG6<GS;)SWO$/T/T
+MNU/HU6)?9PN]4<:/%@D=(>.##PB]Y`I^_V$]/+''GA0Z3^R]/^OI[\W\O2!T
+MI.3_JWI^R'K>M_3X96'X/X4>*NN']NK\BKP<U..3^>)?"]U/OB_4"QVVGOG_
+M64^O]-_/Z>F1^:4=!TC\(C_=A-XN&SE=(72%M*_7#.#O[QOD^_OUXK]+ZL=0
+MH=?)_(T8H1/E>\EM0J?)>N@XH:TRWC-)Z+753-\YH&W]N%?\]\O&Z!E"3UK,
+M3[B$]G>2_HC0X6+?/B+T>-'GJX6>(_;_GX16&X7C6B?T4.E_O"YTK(R7;QW`
+M>_<NG]Q1T55Z>+)AP1X]/GT\2P]/YD?7Z/Q*_$?T_),-&^IU?YEO\9/0ZR6_
+MS^K^-?Q^AX&B#V5^L4/HC<W\_!4#I3]HE?(9V':]]W1Y?I%LH'JOT/ME?"YU
+MH,P_D/9EH?A;)3]+A(X6^_(QH>?XI+\N]"897ULG=,LNZ?\)W23SJ]X0>JO,
+M?ZT2.E;ZS[N%'B_Y\;'0I=)?_53H7:)_#@N=(>,WWPB]7O3##T+73.7T-^OA
+MW\;AF:Z7^G<?^]N$CI3\[R-TK,SWZ2?T(OG^,?1ZF2\LZ_5'ZN\+_W%"1TG]
+MF"3TG$N8GB6T2_HG<X6NE@W"%E_?MKXD)X^]:_*HA`EC\"LY/STU*R4S.WFN
+MVVE(7I26G^S,RDUQ&9+3W'GPCDL:DUR0YW;ENW/2Z>DT5VZ*(7E>NLN984C.
+M<.7F9!F24^;FYN.%]/Q\0[(S/1?!Y.:EY]#3J;E962FN].34C)3\[)2\9%?*
+MW"P$,S=_@2$YLR"E(#4SDQYS9BY*<Q9D<H`%*OC\O-2YBW-2LM/5@R[78@2=
+M2Z\Y4^;BB50\4I#NHIA<F3EIG/"T%)<[FW\NSLM/+\A+SDXI<*7GZ[?FXLED
+MO)66FZWBR)N7GQ>:2HHN.2\_4T]F5H&+,F*NBH!>*,A0C"+/4K/3B-\"EV(Y
+M/S\WOS7>A<F+G$PB:Y,+%F3B7FINOB0R)]V5.W<^.,C(S\UUJ704I7%R\G/A
+M)4P3G8G[:3G)Z8OR4B@%8!7_V2NE@+/)E9F-#$]+64RIFNM*SG,79-#/O.1\
+M21&RG4,$GZ[%>?B!')B7G^O.0PB+\RA2+CFZGY%;X$K+*4C/45RFI*6E9=ZH
+M7H!P."DC\]-3TK(R<U`.*6Y7ACLG<U%R*NZYTEF2"E0>9N8L=*?G+^;X4_+S
+M.75Z+A>XYQ:X,EUN%W/I)BY5V@L6YZ3B9SZ8'3H\.=N=A41`%E,7A+ZMDLI<
+M0\ZRY1V\!?ED]BAA.;DYZ<&$(?GP$YY<8#R/.!&I2\LD`<O,<:I(LM)3<DCL
+M)2LRI<S<R5FY.?/T9.9E92*H@L)4I`6)AH1E<P:J=.'1E#3\24U1(N0L0&#S
+MBE+HE<R"G!14B[FIN7F+VXCI@O3%R84I611$;J$S*SDM/2N=4IZ?/B^3!!B5
+M@0O5N3`H'90^Q5-FP;S\E#RJC6GID,=<E=E9J;DYA<B+U-1T$AE"DAC4W\Q"
+M5:;)>(_S2Q627IAYJ*<L67E*_)`1*.YTI1NH'B"YA7E2"4C<YF7FL#8H<&82
+MO\GC)DT9/6I2\I3X^#OCIB=/'S5Z4ERRSBM7)PHR=QYJ)@E1VGS*,XAYIM/)
+MOU2X\])5#`79*0O2@WHI+ST]G]DOR'"C$A=QU*E4?5`:^2E%P2*GQ.3DXG8J
+MA"DS7T)-S<X3A1?,X622,Y4A*"\4&E[-R4YQI:I*A&0.T04@D[*:M([*\]:J
+MCJ+C^ZDI*O!0`8/:%(U!#^3HNJDP/=5%^H+J47*.TJ>%!5`[.2ZG8B@MLV"!
+MK@;`ESLM+SD]AS12:DIJ!A=^.A5N,BD'4B_!^BUU1$F@TF&JR$E24K(R4PJ4
+M0#GSTZ70TU6*H%)0J)3?A<X">I,D*BNWB%@HR$3YDORY28@@7`7I>2I^77_@
+MIU))*GMSTHLXX+FYN5DB%05YZ4IT*58EVWDI\YB%>4J\7/F%F07RK,I9)1U<
+M=U10BUW$!')26(9.2L]2+[IR%TI:YNGUE)H9\<OB$E4U9UZK`B@L2LG/682`
+ME(9H;=CFM59X3C>+*H4$,4V;FPV1@K97I5U(4J7TQ=S,><A2ESL_AS6CB!KJ
+M6`&)5.:-PV^FX)*STO0\RD]7-38-&8L?^>VJ4T'Z0HDT3<0#8:H@(<9*2E5*
+MTI5\9N<AFZ&R<@N0?A=)&)I)/.PNR$I/9QT&H<K-SZ2V4^63R@%2TDH]HQ5,
+MH=I;A"?2"X,I2,FGP*FL*;#%><G(1=4&9^5EI*BBS$O6]3NEAG1FOM)_$*[T
+M1>F<W^E<)GGYKJ`20R*1UZFJ?H;H/KVM!(V?G._,&BJQ>HTJERK8U*P<5V@M
+MQUMHKC)S0YH@U01*!=5U=DI!1I;H/&7:N'.0_VDHP`QJ3;*0..8W#YF1"C%T
+M06C36?<5H/51`@Z!XBJ1KS(5[R+48&ZA"J6DIE/6I\-\RL_-3E:M6C8UKJCL
+MJAHKHR9]H:IIJC10:PTJC?.S\\2"R"Q(!8?4#D#U*&L$K8(NW%QQ80UDNH+&
+M17I.6JY3MRY$5[0V>]EH!)R9\R2Q2&-A>CX)2[*R-,!SRF(VU,!]:HKD&AJ1
+MY+G<ZKISLG/=.:XVQHD[>RYE0T9Z2EZ!$MR@/"F%[9XK%D/Z`E492$(X#B05
+MN5/81GVB^%6SA_#G%F3>IUH\4<,L6DJV(4"IN:2Z*9F$4)EL.:;GI.8OS@L&
+M2,9/JTQE%LS-2LE1Q@,:Z517ELB',TTW:ZE$5.U'"^>2J@:!5S5=F-;K#T6=
+MP;*(HI%&+SLW30E=07XZ9)6U4A;QFJ$+AIO:M`)^G=I\)5Z9(E\JK)2TE,)Y
+M*G=R@E5T/IM`>LI5!=0+G*QKJ&441RHWH21:X()S3&_6J`8J$50W,_.=U!B"
+M-<B):IHXN@S6B="1(C2J&E,M2\X+WB"YI#C<.:T5F35?)@S%?!?K!M64<+7E
+MXIZGS&PH&&G'VI(JPZEQYTS'PVA\I,U+U2L#/</-H[+54&T+E+F&S.2^26**
+M*V.2-!9BCN2ZV3YG,4+)I&9DM>V*M)J?NIG/F:&W/OF<<:A5S(@K%0U3VER$
+MN$#G4#5TR?.R<W-@+E$MSEY`1F">5*"V;$/!9"M[$9K-6<!J&=:[BBXEV.P'
+M?R0G+T(A41T*J22L@G,R@^TN53I*%H6V,".7VJADTJSS(*XD;ZG.>:URAOR"
+MVBU(5W6'VT+=O&`%H5<TI:Y#RYF$-4>I(*XGZ;I@(DC4,7#N=!6HED^WJPKS
+M,LFF#+*5.0\EK'0>:5.]_NOU,92-?&:#N4:GA?1RLFJ#\#3JG)[YRC3D"HO.
+M8M`.+T+YD!6KQ%QZ;*3GY@FCL.F8R8*BE#SUWN*"5O7OND_**W,>JI!*+\>F
+M&I/LE#18*21DJ>Y\JJ)M\KI`":_BBW)#5_`P@EQB$W//DV,"MT'+/5F5*5+K
+MRB;CL4#L"L@5A"7?13(.9G+2%[E$A>>Y\^=Q@)`R9E))K&ILE6QPZZ-H,(_X
+M\;2S*"5K@32$+%J4OTJ_*0T.IDE]<2FY\EG1J79>]/J\D(80#TOK`$Y4HZ!8
+MR<"+4F^I>K051BB4T(:)*S8L1Z<8.VZV>O+4L`!U<_3V1,]NM@CIF4QJTE$H
+M;!#,:ZU>N7K_H6VU"9I4*$"8?4YWC@Q-L/T7;`%8&5/@:;J,JRY'KK)_@QI3
+M[QMSKX\U,7Q4JI@5;@7<.;I9JRH;:SFD0.R^$&TDNDRDF"58:>""=BJ8*G'>
+MXE9=R9TW73/R\(D8.&S=D#`*L\'FF`SZ@NQT;L-5(T@2*'T5YE^53E9.2JY3
+MCXLXSL[,4:7#9@]468'>I\HOR%<6>7#,1BP$)%C:1[&MX8660N5$008Z[MPW
+MH?`XE8@I4W5`6"N[LO.4A03FI+^CS.F"5G-:>"UPZLI';W59K?!O,(_L8"Y)
+M&Z6Z,JGV+Z:Q(>GFZ3DH;4N.,H6HX:2:IRQ^Y!^KO<)49UI0CI5%S$80]#VU
+MWFT&FD@$N9#<*5DII"Q)]1>Q_&1"+V5)=-PK1?W(2N$^>@&R@E4!-;Q.UI_)
+MJC^C,HSM"66O4C]_GI@*RI`7&R-7=#]51*J^P4H<;)<*5"O7:I(7+,[F@9TV
+MY<6/YY-A2]JY0,9KB$V]-E)8KA2Q.H(J'D*6JN05?52VWEIM-"5`[@+%GBNU
+M53'(8(D:A4&>!F-E5:P/]1049:2XU*``Q(C-NF"CI@L84I:6OH@L_!QETRB%
+MI[)1C7:H49%T*J*\K,6M`V)*T%/9Y"W(3TG+7,2E2YG(,LH\H+BE7Q;,J@R7
+M2':Z+C&N^<2T:HAS6SL4P<&,8!N'0FC50LD%SJR4>05BU;5VG%(AZ[`Y,H*V
+M/<H_5UF<*%(9*W'FR>@!J4RE>:$^5:7-3D>S4:`/7:)RD(K+S5:-A*@7%%=V
+M;B&'K`_$A.2J/NR2K5I?"B)[@2AI:D<YDX,OZ)E16)`3-`2D#N>G%^8N".I;
+M94A3;$/R<@LR%ZGQ$Q$BME"03:Q[*9=U<S6]2+5\JE'@I)+$(X2V!1)LT0NI
+M3UH@(PZIR%#%N<M%9@4-"4B/0ZFSM'2GJH^4_V29B(0D)V?/I=8(2F.1M`S!
+MXF-[6?)1Z;/@.!P48EJ*"P9L7I9N-$,Z^!9*3"P2)9SYV2XV]!?GJ6%%J5SY
+MZ5PLQ.>\;-%;NG'&TJ\WYH""-H6@5_6<-%<N-0)J,"<_V+Q(BH/)IRX"M1G!
+M7I<^K$2JU<EV77+2]/@A(<,F:!;0]^2JC^JJQG:4>$@@_#QK7_39N+20D`)*
+M+O5>R$NTAQI$X]?<.?1;R99H\3%L"4Q#K+K%3\]+5XTU;FB^%;"((W=TLR]H
+MG[2R3QS#]$,WP)!<E.K*S08FBQ&"BJB&T@O0HTH5DS57C?JDY>H60A[Z'WP3
+M9:%J1FL_G\?30TP&I]X!4`E2K7$;43<DZTE6;4&:]"!<]['V;S5@,PMRI5N4
+MIS<CA:'V=A9E:*J8TDI^LPO4.`AD.\6=Y9(FI'6P6ZPE%LM"W=K6JT.><Y&J
+M/:J;"/%7FI(EW\WE&:HI0^HO#S(L5B-1W-QGS\UGL9G;VE+/51]!G*'#GSQR
+MJ88#1/C2V-)*<1>(@4=5)2--"C.T"2D(#B06%K0.T[F"'6/XH^('.R&JQK4;
+M.-7-6#0TU-R1`B+60Y.E2D)R"74AF0<UJ6!8\4$)I>>K<5?519$A9^2W4]?`
+M>-:=KQK+?+;G4S/2J<RD#>=^I%L90NX<;I=UOE5I%@0'"]2(IJ'U,YXK/2M+
+M25>JDSK8^2G45Y5O*D@=)6!A6F9A?CI_`T-W6$9P^3.3WBG6C78T6'K>YA2(
+MW"WDPBYH':8@_O2*QHV9/HA;H,Q"[NZ@=I"!FRR#XKJ1,T^5B3+V6@<3LW6M
+MG*\&L:4GD!7L[8.5D/%DRIO<O!0T208U@*4WPT@REPC:-[UCII>_4A>0:^ZD
+MR4"<_GE";YA4A#062UTVCB<SIW7\+2AV^2G<XR05K\L:,Y7.%9JK2B%_P^0O
+M<<E!LY_ZJ30VQV8364VB:(.6@734N2^8O8!'&X(9FN-F.<XLD$]\^@<L:3+1
+M<*>PD9`U5_^:R-I)A$C9<UPJJB4>(C4[FWL-&=G*XA[+"B14"<]K+=Y4U0:Q
+M39W=^B6-!Z-)H1:*<-.(BGQ[S6@=8*)\2$M/55T&9&TA=60-R0O0,<V;IQC*
+M+PP9L93\8`+YD=G:5.EV8FNESEU`*7&EHFM'Y>I,S1`K2WW:R5$=`G0WI+=.
+MIDI^?HAMF*<,!UU<>/R5RHF[R2$*#_FG]!U7?]05*@+2"WDPLCG_X_7O2<%/
+MR07Y\K$+O275.9>^(PTK*&N11@F<U$XNYFC%/&E7.3,+Y+-3@8S5!L>S>#"`
+M=6<RZYGD?$I9@8B^&OUM'1X2VU])+O6""ERJA:?![>3<G*S%HM)=9)T79*2S
+MY!44Z6E5PT7DIVJIB[.+.EG0+7-)B?,WD@(>-8):#]8\E&E..N<3`A.K`=YS
+M>>0[V).ACZEY\M48S[%O4*3FA<JUFZT,BDM]X:"/,:PQD`+J%2-+=2V6/1><
+M%J6JK^(H!!Y>(3E3@U#Z1R]N^;AIG8_4MO8BVL@!?QH#DUEIJG@HS4-52YB;
+M)U_PYTECXFPU(V2T>*$[%RTXV7;TVHVZ0-&'6#&OX%`1J;(4J($87:<I32,#
+M`\%/%B@4&5+,+"C(4Q\J4)JZN*%.L%6AFF`>IS2T]G@X:AYJ4[9(D6HSY3-:
+MJX&OQHN0+/EP)MW7(C*M@FJ*OC!#)SL+<$,:"E6,:BR&BQN\2/O-9K[2/[`;
+ME!+4APM;/TBH)RG7[LO-44TE#_:1A1<Z+2$UN5"-L$''YB\B%2?34]+F0A=F
+M*FVA)@QDYZ'I'(+,R%6Y[W0IZ88^(*U+O=.Y"*90RB`W+YC_A9GYE#^0Q$5Y
+M//F%OP0&1=LIJL\I(WCTG8S,>KU^D#Y7#2"-N!(_BFL21UW6G.F0Z-3T-B,,
+M]$=9N^U&'6!@W8>>L\I-J0@T*C=/\=8Z-N;,X:$T5MUN7<Q;/[-GI2E^5&*!
+M6:'M/7_T02]35'YP(D:KV$FW33>`*?^R4_(7%(9H&>DT9\[3OZ(&N\;Z3`1I
+MIZ0AHQZ9;DTHE2*=R@(1'\IZ99>ICDQ&9A8Z<,QE4;#-H"_FZE:!WGUFG21#
+M!DY63-D+G)G.7(/>D'*&%"K3A$60VBC.FZP\K@]J>#&T+S\ORRU=-YKN(VV.
+MD]6.$XV^_JW+.4^ZKZJHN2.HS![N=,E'N.RYZDL&33TRR)B[BKWMF*?^A0>*
+M@*9&Y?*GF!!=S;VO^3SHY(3ASE-@9$RV2-DGNC7CUF>+9/.0;TCZDE/RB1M5
+M5&J(CC@3&:!A0>G_)=.GCGR]ESPW'P8VVAK]>[=TWV@(@1H"_A*K?SPF<R+'
+MA;8O-Z1%30GMXT.R0ONH^>FNUI'`A30Y:%X^E1%/OJ&T%^6CCRP]1,KS(J5_
+M5"ZJNLFCFJKWQ7UGU1E4\H_"IU8Y:%WGR'#^(M5BS0NIMCS2BL@+5":V9K::
+MVJ,^*"@+B+_6"^\<G]XG53QDYO&WK`(6;:0?K7]0K=&0D.J@.KD*SPN5TS99
+M)`8PTJ.&7*4K4,##@RHF,:DH9+U@^%NS\E7)X"X(!#]$DJ`YTX,5A`?]%N30
+MS`7(8E;F7)ZE12]+OQ\MCO.\>6-ZK]30.G&FH,VT-E;9$-4TR?(4]>%`S:A1
+M>KDPV'E4@R_!WHHK3Y\@IW,R3WH`,@B;3`I?Z425*-S+Y*%0JH]9.7H%*."I
+M`ZHCJEJ1%#6[!%8D*_EIJ(K)9!,GI,S+5*GG<6\G-X74[\YB#9.M7L_0B[F-
+M:92%6M%JFM`4,Z$0&T+-=N?P-Z+,>6@J7(M5A<M24R&#(S[!ZH"R5JQ"4DG9
+M9G,><-^)YX6)O9V32ST/Q8N:3:5&E_11224"V7-I4"3T\52:%ZE4F$@TFZ_4
+M!9'/%P7ZQ^?0N2ELG*GI3[EJ;D1N#I+BRJ>L7"#3)W+T!J:P]<.H4\1<J<H4
+MW88+#J.Z9<Z/,TUF,D"[N0ORE(9>H+[)TZP4[F04ZI_QD#_<OHL=$)*!7%ED
+MO#Z=AT12,[))JE5FJQPERY[F%[$`I+)NY(XTM**(F&K.>>Q!.O[R42]TBI,S
+M-8<2@M+E0&@R*-N\H7/,<G)59];)@V+I.?J$24Y^2BIIH+FZ^5Z@=T-EGJ)3
+M2D&*&$9)ZW08MUX!*$^S56LLTP1#)^Z&3HEMXY.9$^H%TYF&T*B)HV$N40(R
+M9XUJ8W"R7YL)NB&#X`7<X9#B2DN!L<P31Z3"XI?^I35M+C.?YL[CY*<J*58%
+M12VS#)+DI*D?:K:PBZ>O9I&YW3J&*SG2^LF=AQ%$E&DL(34S+X/4$DI7-?]I
+MZ85<S4@,@I.5V>AW!D=&%ROM$QQSTR=;B8C\[_6_U_]>_WO]QD7+<!R)'0S]
+MY/RS_^2BL])F3^M@J'W*8JAYVV*H/<2K/3K2.O7+.QB6TUY8>&:MS1`\=_-_
+MK__[KHJZLX%``.@_*7@":`0>`YJ`GP/-P'U`"_!]8`?@-F!'X%O`3L!7@5;@
+M"\#.P&>`78!_`'8%/@:T`5<`NP,?`-J!]P$=P'Q@#^!\8$_@7&`OX-W`,.`T
+MX$7`B<#>P-'`/L`1P(N!0X"7`J\#1@"O`EX&O`1X.;`G\`I@%V`DT`2\$GCV
+M7"!P%?$/O)KX!UY#_`.O)?Z!_8A_8'_B'SB`^`<.)/Z!UQ/_P!N(?V`T\0\<
+M3/P#AQ#_P!N)?^!0XA]X$_$/O)GX!PXC_H'#B7_@+<0_<"3Q#[R-^`?>3OP#
+M8XE_X"CB'SB:^`>.(?Z!8XE_8!SQ#XPG_H'CB'_@>.+_UT!@`O$/G$C\`^\@
+M_H&3B']@`O$/G$S\`Q.)?^`TXA]X)_$/G$[\`Y.(?^`,XA\XD_@'SB+^@7<1
+M_\"[B7_@[XA_X&SB'W@/\0^\E_@')A/_P%3B'YA&_`.=Q#]P'O$/S"#^@9G$
+M/W`^\0]<0/P#LXA_8#;Q#\PC_EL"@87$/S"?^`<6$/]`%_$/=!/_P$+B'UA$
+M_`,7$?_`Q<0_\#[B'W@_\0]<0OP#BXE_8`GQ#RPC_H$/$?]`C?@'KB#^@5[B
+M'[B2^`?ZB'_@P\0_\!'B'UA!_`,?)?Z!CQ'_P,>)?^`JXA_X!/$/_`/Q#_PC
+M\0]<0_S_$@C\B?@'_IGX!ZXE_H%_(?Z!SQ#_P+\2_\!UQ#_P6>(?^!SQ#WR>
+M^`>N)_Z!?R/^@2\0_\"_$__`#<0_\$7B'_@2\0]\F?@';B3^@:\0_\!7B7_@
+M)N(?^#KQ#WR#^`=N(?Z!;Q+_P+>(?^#;Q#]P*_$/?(?X!U82_\#MQ#\4X`[B
+M'[B3^`?N)OZ!'Q#_P#W$/_!CXA]83?P#]Q+_P'W$/_!3XA_X&?$/K"'^@0>)
+M?^`7Q#_P,/$//$K\`X\1_\"OB'_@<>(?Z"?^@77$/_`$\0^L)_Z!#<0_\#OB
+M'_@]\0_\@?@'-A+_P!^)?^!)XA_X$_$/;"+^SP0"/Q/_P%/$/_`T\0]L)OZ!
+M9XA_X%GB'_@+\0]L(?Z!YXC_,]2`@'^@P0C^@4;@'X`FX&-`,W`%T`)\`-@!
+M>!^P(S`?V`DX'V@%S@5V!MX-[`J<!K0!)P*[`4<#NP-'`.W`(4`'\#I@#^!5
+MP)[`2X"]@#V!8<`NP-Y`$[`/\&QS(!`./`F\&'@">`GP&/!2X.?`".`^X&7`
+M]X&7`[<!KP"^!8P$O@J\$O@"\"KB'QA%_`/[$O_`:XA_X+7$/[`?\0_L3_P#
+MKR/^@0.(?^#UQ#]P$/$/O('X!T83_\#!Q#]P"/$/O)'X!PXE_H$W$?_`FXE_
+MX##B'SB<^`?&$/^G`X$1Q#_P%N(?>"OQ#[R=^`?&$O_`4<0_<`SQ#QQ+_`/C
+MB']@//$/G$S\`Z<0_\!$XA\XE?@'3B?^@4G$/W`F\0^<1?P#[R+^@;\C_H&S
+MB7_@/<0_\%[B'YA,_`/G$/_`%.(?.)?X!Z82_\`TXA^83OP#G<0_<![Q?PKM
+M!O$/G$_\`Q<0_\`LXA^83?P#<XA_8"[Q#\PC_H$+B7]@/O$/+"#^@2[B'^@F
+M_H&%Q#^PB/@'+B+^@8N)?^!]Q#_P?N(?N(3X!Q83_\`2XA^XE/@'EA+_P&7$
+M/_`!XA_H(?Z!#Q'_P`KB'_@X\0]\@O@'/DG\_QP(K";^@;\G_H%KB'_@GXA_
+MX)^)?^!:XA_X%^(?^`SQ#_PK\0]<1_P#GR7^@<\1_\#GB7_@>N(?^#?B'_@"
+M\0_\._$/W$#\`S<2_\#7B'_@)N(?N)GX!VXA_H%O$O_`MXA_X-O$/W`K\0]\
+MA_@'ODO\`]\G_H$?$/_`/<1_4R#P(?$/_(CX!WY,_`.KB7_@7N(?N(_X!WY"
+M_`/W$__`3XE_X&?$/_``\0^L(?Z!!XE_X.?$/_`+XA]XB/@''B;^@4>(?^"7
+MQ#^PEO@''B7^@<>(?^!7Q#_P./$/_)KX!WY#_`/]Q#^PCO@'GB#^@=\1_\#3
+MQ#^PF?C_"?J=^`>>)?Z!OQ#_P!;B'_@K\0\\1_S_1!T$\`\TF,`_T`A\%6@"
+MO@`T`Y\!6H!_`'8$/@;L!%P!M`(?`'8%W@>T`?.!W8#S@=V!<X$.TQ+T5[<;
+MZ:QQ=%--?/8\;0-*1SW,QOU)G0T&6V<^D[09;A=<:2>#H:DCG]L;>M']J]OU
+M?]9T1YAP:7:\#UP-K+&W^ILOT&>Z(=V5>@,M)<4U\&K>GZXZBO?!B\+OB+ZM
+MSP[M;S",A,N#B[Z.SNAK&U9LOZO[ZZN=!Z5V'C9HZ/GQ$1N4I"O@;@])E[$=
+MQE0,_D-4Y<$A#PQV_G'T3W^YIW;9+4=>S^WRI6FK^<=?8G\:O^#K":Z-7[SR
+M;OA=L__^Z_3T5?:,02O_O/C6^LVUE[_RX((QUU\W:-[GY>^77W1/0>97IV^:
+M4O'9(Q<=F-KX7.Z3"W)2#OVP:L/CMX^Z>?6VJW9LN6[=S_<?*%_1_>D7?^YZ
+MU>^U-\?]<NW0.1T,_<29):V$Z^:T'5LP&MI>D7>=GQ_!>6C(D.&#!D?V&YV>
+MOR`]*WUQ_\B;;QAZ0\R-[<(C%YG"-'UYS<R9-R+2E9%9$$G?,_)3LB/=!>D%
+MD11LO_X#(XLR,E,S(N'KSBE(<:8/ZM8E)+RH"6DC(O7O#8-2!Q9&#D8*!L?$
+MW'Q#]$TW#!D6.3AZQ-"8$4.'1.;1Q*#(N$5YD5'G%UF;])U[WF`X#D>[;QP$
+MOOL\Y\TKP*>>YWTX5@)=<)1;&<"I<+1;3!RPW_,L`Y<!C<_S>-"IYPR&P\_Q
+MOC+[@.\^Q\=A;@*N?DX=X6KP`=W/\3Y'\X&SX>B(TJG`Z^'HN/JKZ=YS+%^F
+MY^@,5CYG]%/@:W(^\ZO`"OGM_3OJ'-P=<'%P#OG=!:Z3_#;"U;[`OS\'?BR_
+M=P/GR^\TX`3Y/0;XU=_X]V'@5OG]!O!E^?TWX,/R^R%@GOS6+_I=(N?EWO<2
+MYWOA2YSG^2]Q?N>\Q'D]_R7.9^=+G,=S7^+\G2UXUTN<QU,$)[W$^3Q>,.XE
+MSNM;!4>\Q/E]O>!U+W&>1PI>]A+G>S?!+B]QWG=ZB?/=_!+G.;I#!MKB\1=@
+M3^!I8"_@3R^J([@,/P`O`M8#>P._!?8!?@54YWP"Z0B90T#:"J8&2$?`[0?2
+MUO][!3\$TM:>[PON`%X._(?@>R]R_=TJ2.40"?P[Z"N!:UY46PH;*EYD?;H<
+M2'6@"$BJ+QM(1VO,!5Y+\@:DK>-N!T(-&FY^46T!9A@()'5X#9"V)KT"2,.2
+M/06[`FE+0:/@+QN@>RD_!+\'TI%G)X"T]=`WP"&4#T#2$5\`29U^!J2CI/8!
+M;P;N`=+64SN`=`1C%3`&^#9P!-5+X"W`9X`C@4\";R4^@;3%3^$&UL,9P%C@
+M="`=Q3UQ`Y]Y-T*P+Y".Z+L$>"_0*O@K9#49V"3X[=_Y:(A#P/N!NP7?!BX!
+MO@PL!OY1\`F2=>"CP*6&ME=[_1H]>,B-0V^Z>=CPF)2YJ6GISG;>AOO/H5[`
+M)<'%PD6>X[JA7W_M9C2LAGL$S@.W""X/;DS[@-I=_[_N'WK%]C(:9L_K\&_=
+M4KGFS`O)H4C]ZD=7Y'E7N:/M90E><F.4NHP7N-A_M+I,%[C(-_)_P.?_6]>:
+MD/RXD+WTKZX;TM(+;_@_FYS_O[ZVP[B>,LQH&`=7CM]C@+?`-<)O&/!&.#HV
+MX0;@`+@,_+X6>#7<.OR^`G@I'&UEU@?82\ZHL@,[P:W_-1"@=\GMP&]ZEUSD
+M.5CM\FQ`?0FX\&6:9S2<<;9JF3.92%MF>ZWSWU]B_ZG]'_X#\^^"[]...5DI
+M<].S_D4`MU<B7^%NAAL$UQ\N"NYRN'"XGG!=X2QPADKF[UG@6K@GX5;">>"6
+MP&7#.>'FP-T%1V%/AYL$-T[>W2"HY)WV+_N-J_PXPH2S?(/POD99`V=_TYJ_
+M>DT;*?CPKT;#"K@'X1Z`*X&[#ZX0+A\N!VX^G!-N+MS=<%/A[H"+D^=CX6Z!
+M&PIW'=Q5<!?#.>!L<%8X"YU]"-?28C0TPS7!?0?W#=P1N/UP'\!MAWL;[E6X
+MO\']`>XIN%5P#[2<WVXH>[NPG<%]HQC<PVX8,CQR\,TCZ/_@_]#@_C=7>TDU
+M_AO7_C*)T_5<]QL__/O0GMG?-!SIH&R_L-M,!@><#:X3G!GNW*TFPQFXG^%^
+MA&N`\\-]!?<EW.=PG\)5P^V!VPFW#>X=N"UPK\&]!/=WN.?@_@+W![@GX!Z!
+M6P%7!E<*1_&;8Q'?[29#$UPMW%ZX'7#OP*V#>QKN<;A2N#RX-+A9<`EPP^'Z
+MPET*UP/.`M>(,+^`^PAN,]R?X32XA7#WP$V`NQ'NLMM,Y^57%^0B4@2[F_9"
+M[@1[NC/N=85=W`TVL-W@:/=\>_FVWV]2^6T1/'L?XT^"WP.IG$X(?B58>Y])
+ME=%^P6K!?W?95TI\@F>]$I_@]UZ)3_`KP5JOQ"=8[?W/XOMW5Z@NIKY(>\6\
+M\7F3ZH-TD&>KWVM;!G/VF`S'JTV&57";X-;LA?Q5MSXS=K_)T/R9R;`>;A?<
+MH@/P.]`VC"N.,(_F(YP')PXS;Y\!J3_U'I#BWPBD_M3#0.I'N8"4YM\!J=]T
+MZV%.ZU5`JBN!0R;5/_H&2/VB_4#J_[P+I/[1LT#J'VE`DI-,.=_SW5I.S[I:
+M3H]6R^E96,OIF57+Z;FUEM/3MY;3TP48\17RXYC)$`6,AAO^55M>J?T(+B7F
+M`9FAAID3)HT=-7KT-/@O6]A!N=#G92FK>OJF]@48838L@JN%2[O,;&B$FWZY
+MV5`#U^\*T%>9#5%7FPVSX=;"'8=K@HN,,AO\5[5*D*Z+VK?-_ZJMINO'$6;#
+M";AC<)_#?0*W%^YCN`_A/H#[!]S;<*_"O0#W%[C5<!5P(VXQ&X;`]8>+A+L8
+MKL<M;=^W@[;!=8;K"&>&,\"=AM^_ZW^TOY)R%N3D%N5$JEE_(R+_W>.&V2O,
+MAK%PU\%=`F>"^T$S&P[";8/;"+<&3H/+A9L%%P\W`BX*+AS.!G>V'&4"MPON
+M3;CU<"O@"N%FPHV'BX&[$BX,[MQ#B`?N*[AM<*_`5<`5PLV"BX&+@.L*U_"@
+MV?`IW+MPZ^!6PN7`W09W+9P5KKG,;#@*]P[<&C@/7"9<`MQ-<&%P)Y>;#4?@
+M/H#[&]R3<!K<(K@TN*EPH^$&P87#G?)`GN#VP;T+MQ[N8;C[X>;"Q<+I,Y5I
+MT<V_S6Q<OY*TF?X#-QI_1AO:NO_DO?_$Q:)6][/\]\[6P6"$,\&9X2QP'>`Z
+MPG6"L\)UAOM78731T-[#V>"ZP76'L\,9Z$R-_Y/NM^*_&/'#V>"ZP76'L\,9
+M+K;\GW7MXSZ_B?_?Z__"B]HCW0ZF-I=:1&IKJ9VE-I_:>VKKJ9VG-I[:=VK3
+MJ3VGMIS:>1KCI/%-&MND<4T:TZ3Q3!K+I'%,&L.D\4L:LZ1Q2AJ;I/'(2`./
+M0](8)(T_4G>`QAUIS)'&&VFLD<89:8R1QA=I;)'&$VD,D<8::,R0Q@MIK)#Z
+M@C1&2.TVC0W2N""-"=)X((T%TC@@V:(T_D=C?S3N%PM'GQOFPM%'(#K&@I0G
+M-6XTF3L#CHXZHN.,:,MVVF:<CE+/@:,C?6A;^(5P^7`%<"XX-UPA7!'<(CCJ
+M(-YGX'%%&DND<40:.Z3QPCG_'\9/XY`T!DGCCC3F2..-I7#+X!Z`\\`MARN#
+M>Q#N(;AR.`UN!9P7;B6<#^YAN$?@*N`>A7L,[G&X57!/P#T)]Q3<:KC?P_T!
+M[H]P:^">AOL3W)_AUL+]!>X9N+_"K8.CSQ//P3T/1\<:_`WN!3CZ1+`![D4X
+M^CSP,MQ&N%?@7H5[#6X3W.MP;\!MAML"]R;<6W!OPVV%>P?N7;CWX"KAJN"V
+MP?T#;CO</^%VP.V$VP6W&^Y]N`_@]L!]"/<1W,=PU7![X?;!?0)'V_#3T6.?
+MP1V`HVWBZ2@_.CZ)CBPY!$='[]%V[W3$4"W<40,?ETQ'5M&Q3E_#?0/W+9P?
+MK@[N!%P]7`/<=W!TW.0/<#26]",<'2_\$QP=L_LSW"FXTW#-<&?@SL+]`M<"
+M]RL<'9>J&YO_M]?_408V:6@\8RP<'645#S<.;CS<!+B)<'?`38)+@)L,-P4N
+M$6XJ'/4G[H2;#I<$1\>GS(2;!4>?1>\V_';]__\J_O^M__];_R]4___51><X
+MZ_U5ZA_+$EPU&CLD=#0VYH9A[8=SU:K-6>I2])XS;4=1VG]>B6YWD1XBW5$<
+M?*-1IDQ$Q3+>Q1C["&/Y/QCG-RLL73Z(JI:ANF>JPN4'GE*8_N&'A)'):TU4
+M[?R%XX<1/K/JDFQ@[-=KHI\932=);]_Z&7#H-3\OL(TQE-8.6_R/46,,:VO*
+M9@XM'&/8-7E>=M7?QQAN?73.\5E'Q\2N?'W192]?-#;QAV.?';_DCK&/?9K0
+M\>/&TK'Z>WUR.KS^^I;'XW\^<WN=><KPA"&719\97_3`W2/?*UAZ>,I%[JU:
+MS5.O[ELS\L;GUW]Z]:D),;<^WS3V_V'O_N.['O<^@+^NZ_HLTUE:-5HUFEH9
+M#8M01YW[VUTTA#G"5%BLK%I\8TZ=<^:T,@S#*,EMF$2+<8_26><D0S'):8>A
+M&$8[QR0LBC"Z7]_/]W7=<WO<_]WG_J_OX^'A^;@>U_?Z7)_KY_OZ;.WS8\]'
+M3WC@WHJMB7^9,F3<U;4%F=T:?_[K#>$GMO9FY73['VG!+S/]BSZ)OWB*FO<O
+M*K?[+PXB=?^'LB8N2OC%L[J.__ZQZO]7NQSX'/@<^!SX'/@<^!SX'/@<^!SX
+M'/@<^/QOG]@9)#RMY2:$S]!B[W(,]KOPF5CX7EL;?^85OK/R(Q,^ZPK?/]G7
+MA,^NPG>SGA>$SXG"]W"VFO"Y4,QM'\2?`X7E7!:$SWW"=V%>:,/G3>%WH_%G
+MS.$[H(,@?*X<GNJZQY__A.^6/3[^W"=\+^E(&S[?"<M,-^'SFS#]@_CSFO#=
+MIFGQ9S#A>RFG!^'SEO`=GM^;\!E+^/[7P29\KA)S\G@;/C\)WUL]+2%\5A+>
+M8X,-GX6$[[_<9,-G&6'[O&3#O.%[.3\T2#9=[S`]1NF9DRV&R_7]'4Z1EQ4X
+M_+OI>D?F>4J/LATNEE>\8L/?O8MYTD"'/\I510XWR^7LBSOEUC<,ELK9QN`Q
+M7[<9`9Z2JR]S6/>SZ[Z@]-PR@\URS:T.V^32T@`[Y,ZS'#[S>=@FL5>YAN\@
+MOS(!QNI^WS5(DK=LL$B5JQZVR)0C[P,G>,\$QLCE[QE,D#N&\APOMPQSF"UW
+MSK/XG3SB.(L*_]T/#);(J5\YQ%Z;'JO;\CD)>%+IR]C^:^2V;(N7Y)S`88M<
+MV&+PIAQ=Y-`JIW]LL5O.^)-%IUQK#0YR:L/W@-YR]*@`_5Q7.V?X/.RCX^7Z
+M0A?[%89XOS#_!#GXPN!BN?,@BSER^_L&?Y#',_]"N>;.`.7R5-Y4E=R\*,`3
+M\D;.HWIYY)D.&^6"NRV:Y(I1%MOEE'<,=KAX&U:R?W<IO?!C@SWR-K9GI]QZ
+M>X!N@>81VR19SK_6(D/.Y!PY5BYFOX_R^3^RF"#7[73XK;SF68-+@OCS_MC?
+M&BGVY;QH42J7K.08\.FLVSUR[BG`0W+DF@"K_+6F!7A6'LTQ_)+<R`'_NIP2
+ML7C+Y^=BV"8W70WLDI%CL%=.6A!@OUQ=[=`C0??R%M!7+MWK,%!.KC?(]-[G
+MD"WGQ,:#G'6:Q7BYA?4\7U[/-6JJ'+V:ZX//P_6D6,Z_P.)ZN7.^Q2UR22>P
+M1$Z?#CPHIW(1>%+.^\3@!5]_=O2K<L/E7!-\>I;%E_)&#OA.N9*3/:&;KCO+
+MH6>WKO'?3^E3N:`-DILYWH;)D=$&H^32.RW&RC4<,Q/E@FE<!^7Z&P)<*I?P
+M6H5R/L?,M7+R<PYE<B/+J9`#+LY+Y`SF?U`N=`:KY);97"OD['/8[O*D9QPV
+M^6N="KPN5]QC\(Z\:Z;#1_Z^[G#X5(ZF`U_Y>UED\:,\\F*VVT&JVUT.A\K9
+M;QJDR^VL_S`Y_43@1+FNV6"LW,0^/<.;$_PB7P[7S'SY@B,-9LFQ9_[SY>KK
+M`RR2<]@OM\DU.X&E_EI%`:KER+@`-?Y:WP.K?=VXMC\GY[-NC7+IS0'>\OD+
+M`[3*N<,,VOT];N><\NE+#/;+5;T<DA,U5A]U2)6C?P@P1([LL#A6;EMK<9*<
+MSSCA-W+F:0YGR8UO<8V54QX%+I=S&+?,ECMV<KV5L[.`,GG?RQ9+?#GT(W+6
+MC0&>]O4I`O[B/0C8+#-4P7N^;HRO_B$7<NY_*5>S8[[W]=G.$.C@^#H\=48"
+M#CU8Y60#A\L9LP(<?;#/;W"27'XJ[UUNY[Y\NIPZ!3A?SCL.F"*/.)-C0Z[A
+M/E@L5WUI<(/<P7ZY78Z>;G"_#(Z9%0=WS?<U/O^5#AL.]FT28).<E>ZP79[4
+MQC$@-TTP^%I.FPK8[EUE]ND>3Y]_M,,`N9P;ZS%R#?>L$^4ZQC^GR4T7`N?*
+MD1X.D^5TKL\%<G:4^ZR\D?-NGES*H.4&>3WWG<5RXP,&#\A%W(`>\^5SS#\M
+MESW%,>#S9SJ\*)>P7UZ3)[YFT.R_VVC1+M=SW.Z6MRT-\(.<Q_TQ^)7*.<R@
+MC]RZP.$(>>1JQEIR(M>-D^3,"H<Q<O[=C+7DZ!B#7%\.Y]<4N9%C[`J?_VV#
+M(KF<[5SL?9M#B9S"<7B+W,#R[Y'3R@V6RW5##9Z0M]T18*W/S_CV16_&JUOE
+MBA[,Y^O/.=OFS7GZN:\ST[^3"^HM7)+ZEVMLKZ3X^(G]/D"ZTIL_M#A1GKK+
+M8)Q<][S#>7(RVW^R=UF`&7(V@[KKY`Z._S*Y]$=@L=Q:8/!PS+SFT'NY3BJ]
+M98;#:CG2S^(%.;_-XM6DKG'^MM(K/G?X."D^]TMN2,#>I*XS4:\>&C^,1=/D
+M&L[]H7)D#G"\7,1^&2U/XAHUH4>\S%H&#^<K/?T;AZER(N.-(KF<9<Z3"QDC
+M+9#+B@UNDQMX9KE'KISK\*!/;V:=Y#6,2^O]=R\PV"BG,K9_1_4IX?K6IO1]
+M,P/L]OFC#C_YNEUOD72(VO]O!OWE(AY,ALDC>AF<*B>/9ASE\P\'SI;7/&)P
+MD;SQ`8<"N91SI,A_EV?&>7)V;!V0(PPR;Y-'LOX/RK6;+)Z6<Y=;K).;V>8;
+MY912AZWR,L;YK7)09_&IW,0]]&LYAVW^PR'Q]DF[-@&)/>.NF)N`Y)Z:"ZSG
+M`+F0^^Q0N9SGA>.5?PG;=KS2BV88G"M'5QKD^?P/&4SOV34.KU'Z5,9C?Y(S
+MUCG<+B?VM;C'EY/&,2_OXR'K<;F,:_A:.?4)BQ?E1HZK+7(S]YT6G\XS8)LO
+MDW'"+CF=>^*W<N[O&2\E:]_AO?>2RW_@>)`GG>$P5*[AV?`$N9/S=[2\YQB+
+M,^3B_?Q.<OS>&V+%*CV3!\/KY`CG^$*Y;B1PJ]S`\_)BN6`<QX/*B?V.QEJE
+M-\T"GI?;69_-_KO?6;PI)VZT^,37GS%JAYS/`^9W/G^EP\&]-(89\_>16[FN
+MILFYKUH<+3?<8C'2FV>BB!PYEFN'W,$SV@5R;;;!97(EY]H<>33WK'ER#<_.
+MM\B3.(:7RDT?L-_E9.X+JWV9TWFFD+<P`-HJ9[[+-5'>P['W3Y_.`WZ'KR?[
+M]T<9AQHD]E;^V+W+K>R7@7(.U]YC>L?/C!5<,X<KO>T28(S<-#?`67+2`,8_
+M<@/CZ@*Y\B[>K]P>6_?DK"T.%?*6*QG_R!-G`(_X<I(LGI1COU?U5WD98[E&
+M7_XJA[?EC)Y<YWMWS;LOE)[(??`[N8;K@^NC-NG/?4W.Y1[=7][%V.,HN2&#
+M<U]NYD8T1EYVAD&.//)6@_/D?2]8S)#S3S2X2E[/=7Z^3V=?E,K;`N[U_EI3
+M');(39,MJOOH[V7POR?\M5H<ZN56UOD%.9OC=K-<=66`9CG@GO61O&*@Q6=R
+M#LO?)Q=R#8G]8E_8#HQ;?B5GLK]2Y*GLQZ/DR&>\GIS([XZ4)\UQ&"^GC0/.
+MD1NYYD^6DSEWKI"#:=PC?#ICM@5RE)UWAR^?<[Q*SMD%/.;+Y/K\C%PS+<`&
+M7PYCL)?E\:46V^1VKFFM*?$U/,HUO%WI]=\8?"77,@;N=JCFQ5+&A#(&<#V4
+M@],9B\C+!EADRR7L]W^3,Y98G"?OVLSSD9PWR&":3^>^?)7<P3C\=W+K)HL;
+MY=P^!G?Z.JQTN$_>PCUZI;_N[`#_Z?,PMJR7JT_BV/#UY-GA5;GI\@!-<B//
+MLQ\>&I_CE9SC_U1Z)<_IN^45C(?-86JK;EPSY7+&8[WE93]RS91W+;`X3FX8
+M;7#R87[-<1@7<ZS]N<Z?K?3L,HM+Y2C/W3/ECNX6<^5,[F6_EW,9,Y?)ZP.'
+MRL/B?9HQ)P&/*CW];HLUODS6>;TO<Y_%*W(RX[HF?U^++3Z6*[FO[91S>-;[
+M2JY^E?&#_^X(@Z"O[I'[2Y*\<4&`?G+PN4%FWWC=UI0FX&2E@^-MO)S=PG$B
+M%TX&+NO;M785_LQ%RC.ZT>&/<H1[^HUR*_?SQ7+M<Q8/RTTS@55R*MOJ:7G%
+M.HOU<C7/B1OEJG[`&W+]#18[Y'+VUV<_J\]>I2>^R[4T->X*[EG)\I;E!@/D
+M'/;=8+FZRB%;[CC!(B(7,KXZ0V[D?)\D1W[MD"_7#6<L[;^;P+.#OQ;[:Z$\
+M:2SKX<LYQ^)>7X<BBX?D=HZ?FM1XO]2Q7]8KO8KY7Y&S'K?8+I=&@(_]/9YM
+ML-/[*H<]OOS8O[7LI[7]%(/N\I)^!KWEC./9!W)108!!<A[/\L?(D5$\=\N5
+MC+=_([>S#7/D*/LK5R[\TF"JO(SQR6R?SC-=L5QW,6-.7S?VX.W>XWG6D$L8
+MXRV7.[^Q6"6W<;]8(X_GF6N#OZ^S#%Z18_^0H4FNX7[QOEP]A&.F7[R=.]G.
+M/RA]RQ4!$OIWC:7>_=5?C/,'R*FE`3+ENJ'`;V0,,SA-SC^-:T'_>/F9G/LS
+M?#F<LU?)33R_S),KKV!?RDG'<4S[/-<ZW"47,DZHEJN6.3PN9\5^WB$'0QU>
+MD)/?L/B[G++6X#VYIH!MYZ]['<]?\KZH0:>\+(O_'Q"O_T36?\``W5<^SQUR
+MQU$.I\@Y*RW&RAE_YOHIIT]WN$B._9+Q#+GY88=KY3R>K6Z2BYZWN$MNO"7@
+M'J:QY[@NR/N^=JB5ZW8;K).W<4]\22[)L]CLK\4XLT4>R7CC$]U7#>]KC])S
+M*P/L]_7,Y]$[+>X][SKTEUL9;Q\K5WX%G"RG][`8(^<R'CM=;EKN<+Y<UM/@
+M<KF6_Y\C3V),?KV<G\J]5:XN,JB4ZWCN_@^Y]-8`R]/BX[,^=@^^S![<6^7.
+MU0Z-<MILAV8YA7M]J[^7/<"G<N$>A]W^N[QNIQR]T*+[X:H_8X,^<C7/%(?+
+M'<XA4Z[A.IDM9Q8ZC)*3!SCDR!'.BW/E]!<=+I$;N&?-D#=>XA"5#V-<-._P
+M>']5%R:@5.F)7%ONDF-[_7V^/ER'5\G96PW6RI.^X?K@RV=L^;I<8`VVR4V,
+M(3_Q]62<]H7<.L?B!SFXB6>3(S1/9_)L(K=S_QHH)W(]'"IW,,8X]@@]URU.
+MP%BEQZXY48YP;;](;CF<XT1NZ.LP4TX>'.`ZN92Q6:E<]1/O7U[#/?U>N9XQ
+MU<-R]1L&JX[H6M/6*7W^%L:B_EKLQ[_)RQYQ>%<>?[S%+E\WSIV]_GZYAN^7
+M&XL<N@]4';C>]I%SN#X,DA.Y[@V3:SBN1LF9IP08.S#>/EF<CQ<J/;^59W.Y
+MX-<65RE/WJ($%"N]A.V_4"[EN>!6[Z$!EL@=63R[R:US'<\8\7**&$_6*3UO
+M.-M+;O^8YQ1Y#Z_[IKSB&(O6@7Y=-?C4U_,<GM]]_1FW)Z1K[$4=>LDI=UBD
+MRX5OL1W2N_IBE-*K9QE,D,%ZYLII7P"7_BQ_H=*C+SG,EW-YGEHH;SN2>Z@W
+MQ\!2.>DG[J%RS32#6G_=]X%G?3EC+#;(.<R_V=\+[_=-N?9FKB%R(V.53^3Y
+MW(.^\.EK'+Z7VUDW=Z36L2&,1>5.QAZ'R1D\\QXIE[[&<[V<NYAG-WD$]^N)
+M<L-^GN7ERAL-9LJ)G-=1.<(X9)X<O2-`F5S.<7NGG#S28*E<PSE;+>,HGE]\
+MF1\"JX_4<\MK$K!)Z1/G&C3Y<B[D?)$[N)[\0T[?#GPIUW(L[?/Y.3[=(%WK
+M3,9C<AKS])$+>>[N)Y>RCP;)):S/<7(-8Z%1<@KCJ(C<L-?A3+EZG..Y3F:\
+M?9F\@O'>='G)7(MB.;/%H$3N^+O!C;X.E8Q#O!E+W"\WG6'PF)S/>.8IN>TX
+MAWIY]#"+37+YR09;Y=SA!F_+V4.`'?*^AQR^E!LOLOA&CDPT^-'7[36'Q,&Z
+M;NSG[_)\QJM'R*5]+8;$S&9N.RLA_/NJX=AF#'_*X'B?CF:?GJ;T-7\VF"CG
+M1BTND#.YIU\FUQ4!5_KK7@U<[?-\Q/$FIS.^6C#8K\.\9SF/<V2QG,7Q?[\O
+ML]'B<;F6Y_0-/O^+%EM]W1("O"V/N)=ST-\C[WWGX*[U89^OPVS@)[E\DD5B
+MAL;5AP:'RBF\QS2Y>KU!AMS!>7JLW)#E,%9.9/P\04[GVG*^W/:PQ15R)MOV
+M*KF*Z][UOLRLV,_PU(^O6-PG-RVT6"G'8H1GY&;&),_Y/,4.K\CYC]GP[^.&
+M;;O2X`-?/L=VF[R%^_YN>?PLX%NYG/5W0U3G'8QMY`CW]UYR)F.8?G+UZ=S'
+MY3W<L[)DL#XGR-$=C"GEEK\:1.0\QI^GRTDI!K\=$A]O^=QWIOCO<G^?)K=S
+M_,R2.PYRF"N7\3QRO=S*\7:3KULO8*D\]7N#*KF1\_<1N2G5X'%?M[;8^JMK
+M,:Y>*Y>PSAODTI?9MO*2J0XM<L"]::=<Q?UEKUP3^T>%0U5GGN\.D9,9XZ7(
+MN5SK!LKMK-M0>7TRVTVN^-9@O)S(^/:_Z#H/.*FJZX_?F=E%5#388L-D5114
+M6+<#8EFJ2!%01%1PF)VVPT[;>3-;L"T!%1451"S$@L:"2A056T!=VU]4C&@P
+M045!(?:"$4N,FO_OW/N[,V\&\_DH^WUG[COOEG///;?,FW'DQJ\Q=R"/AR\*
+MD*?LBR&2/,9!_1S)\3=9KBZG?#[BC<7D]"*/NM7F`?[S/O+Q-Z.OV33+?>HE
+M<L52Q,SD[BD>M8E<A7'A`_M<S*__15[E(&8F]T%]^OI1)^9NNY%[C_6IWY+[
+M7EVF^I#KT.\.)\^$_O[D[IQ759/51(R#Y+68&YY$GH^^/)8\!G8[F;P0>3Z+
+MW!.^JXF\<4Z92I)_:"Y3G?VX/XBXZY)^!1]R)=,<O]BG;B1_#CN\G;SR,)]Z
+MT.:MI4S]Q3ZW%^:>Y"U_0#Q)GG:K5[UO\PP;^(3/O0G/_=[6R1*?\O6GGK]A
+M3"1WS2U3^Y$;%_E4!7DMRGNDE<,^Z\A5*/MQY+JKT0?)/9%^0G^>^4R7JQE6
+M_K-7A<@[,,>919Z/OW/MLX9ZU0)R_[<\:BGY#HQ-R\CCT4;WD>6`ZX/DBHE>
+MM9I\PZYEZ@7R^6<I]88M+V+(S>3N/_K4I^1EB#%VD+>\`W].GHDX9X^C.(XD
+MO6H_<EN%1U60=]SB4P/(7?MY50VY)_S,<>1UM5XUEKSV1(\ZG=P???!L\O;[
+M?"I,5C?Z5,M1!3O)6CEBO-GDT/,^M<#J^;-/+25/6N!3R\B#$:LOM_I#9>H1
+M<O=4I5:3^\*?O&K3H$W?M&5!FG?(U_[;J[:2*_;QJ*_(CW_I4;^0ER/>ZW$T
+M;?@O7K4W><"",G4`>?#>'O4[<@ASJ('D1M1#'7E[5YEJ/-J47=Y!,)[R9OB9
+M,\@W(/:83EZ).5J4W`=SX5;R^;_WJ`OLO1@K+R:G,>9>9?/S6XR/Y`K4SVWD
+MY8=C'F?U_^A3J\AULWRJV^89;;36ZNP//T;N'RE3;Y/W78[QS^8!,?P7]EEG
+MP+=;_6BOG\C/7PK??@QM%7YXOV/,FOP*C&5]*%\+NSJ<?,<@/(\\*:C40'+H
+M/>25W!/SK*'D9>L]:O@Q!;N:0/F&C$>=21[?6::"Y(_1B=O)!R!.N)`\!K[E
+M4O),Q#]7DM54C`7D.L17=Y`;TQ@+CC'OEYAW:@^UTM[[OD^MMCJ1SV?LO=N\
+MZD6;9^A_U9;W)<3_5GZW3WU`7HXZ^<3*-Z)/DK=L4.J_Y)4_>-2>`WC>HR?J
+M;4#A;/F(`29-QT'P7>0-F*N>-H!["O!C,RGOB;(GR%48Q^>09U[I4_/)JS#W
+M7$S^:2WB3_*.K$?=25X3\:B5Y$;$V(^3QZ`L3Y&[$`,_3UZ+_K6.W(PYU)OD
+MY>@7[Y$W3O:JCZR>$Y7ZFIR>[57_(5>@?GH,Y'/[^M3^Y(Z785<#>2XB4*Z.
+MH;P"^:\C]X5=#27//$BID\E9Q%V3R>L?\JKF@04;2P\LO/^CB[Q,]IFL'`EO
+M'FA^X_"G<\O5XY3+]R->((NB]4S3QU^N/B37@7>IY/>]\<]OR?+*JR/(D\OD
+M7+OA[S%!&2$,W2MZFK-ZPMM@`_%*HW,\=%Y<:9[;N)M2BWFO\)UD.>/V&%G.
+MLKU$EC-K[U2:=ZFL1)_]FOH/@"/;[5@CE[Y\Z+$F_5N[*U5+?@\\BOP?\)G'
+MFCRD]U"JB7+A5LKE'/7YQYH\3T>>%U/_*NB_GVED/ZC;Q>N8_GRD?Y\Z>^P-
+M.R'7RYYYE>$']E%J+_+?P8>2?P)7DP]$?#B,7`.>7&6>U76@4@'*A7.4B\W,
+M)7>#%U:9_"Q`?NXA+P0_R7O_C31_M<\%;R;?W0?V06Z`,D\UUWC`>U>SWF!P
+MAU:;.GD<=3*,\MZ'P>]5FV?=A&>%>:_(<TR_!NFO87J9+]].ECV(!WCO&MS[
+M"GD]^"OJ^:N\T*;&<!M\SUXUU(/^=PA9?$E_LOB`>K)\"6B$30.>2!;;/XM<
+M`9L*DA>"X^3M8(><1GN>9].CGBXFR]F&A?9>\%*RG!^XTZ9'.1X@+P,_:O6#
+MG[%I:I5ZI<;453?JZEW*Y;S'Q_;>>J6^(<M>_R\V#^#=:IE/\%[DE>"#:TV]
+M"1]%?A@\B/PH>)1-/QBZR')N_&QR(_Q>A.F%V\C#P9>01X*O8_JN1N2UEOX'
+M[?@PN??,<O4<67X/Y6_DY>"MY!7@'>25X%WK#*\"'T)^'%Q-7@,>6<?OKPS#
+M^$+^:CC*4,>ZPIRNF>G7(7T;Y;+/-;?.U/GSJ/,;+5]:KE:0UX*?(:\#;[1\
+M1;GZG+P>[*VG39Z*&(LL>_W[D27V.X0LL>(19#GW6TV6WX`YOM[D_Y?I2HTC
+M]YZ!MB`?`HZ1#P5WD/N#+R4?#;Z.?`SX3O)`\"KRR>#GR`GPW\CW@K>2GP=_
+M0]X$]C6P3\U$GLCR>S,'-9@TPOT;3#WWQ7@WE/)#(3^%/!1\)N^5^.I<LNPA
+MQJQ^S$%:K7[P>0VFGC>@GJ^A?!GD-S>8L4#X09L^K-239#GS\#)9OG>PP>J/
+MP.^1J\"?4/_T!>7JO^298.EC94SS._)QX`&#F(>(O(O>R(5'D^\"GT%^$!QB
+M^JZH4BG*A2\D7PR^DKP`?!/Y2O!]Y*O!?R'?!'[)/@N\T3X+_!&?)=]9VV'S
+M"?Z9+.<6=AE,_P/^#;EQEE+[#V8?!Q].N9P)K"3+NEP#66+4$\D23XX>S'I;
+M6*ZF#38V,``V$+;Z$7>ER1*#=9!E3?(/9#DW<J5-#[[!/BN%\<+F![R"+&M*
+MC]GTB(>[R?+]Q)?)\IW--^RSP)O(<A[X8UL/X&]L^CL1WS+_:Y#_O8>8.MD-
+M\X[#R=^`Z\C?@D<-X7/O@4T/X?C;A+*3^P?+50?3CWP(_93\[),H(_DE\#WD
+MOFN5>F*(J<\0ZO-EZI>SRAO($H=O)LMW!#XARWKR-V197_V9+-_SVN4XID>\
+MNC=98OM#K/PMI?J1&\&#CJ,]@,=1OA`\C7+AF+WW;8P+E`M?:O6#KZ%<^#;R
+M'>"5]EGO8.YLGP5^F3P&_!;3R!K"5ONL34I]:?6#_VWE[\)'#:5.\!YDV8,X
+M@"Q[1H>3Y0SSL>3MX,'D*L3DP\AI\%CR2O#I-CTX,-3D4]@9:MHKC?:ZA/)9
+MF]&^E'=`?A_EP[;`1Y%'@%\C3P2_3_[J?;2CS<-6Q*\V_V#?\:Q/\&_(W>"#
+MR6^`^Y$_!=>2?P"?1):7I8TC>\!GDLO`0?)1X!3Y)/!YY#!X/GDA>`GY=O#M
+MY+^"'R"O_`Q]B?P0^"7R<^"_D]>!MY+?_TSVG@W_"/Z9_)O/T0]/X)@"WO\$
+MMN^_E#KL!%//"U#/]4PC\I'D>>#3R9>"F\A7@%O)Z[[!/=0I9PRNH,Y5T'D3
+MN1O\$--[OT/\1MX+O)Y\.'@SN1[\)?E$\,_DX>!>)QH>#3Z8O.U[C-\GTCY_
+MA+^E?.5_D.Y$XT^.CY2K<TYD'(+\I)A>SGY?0);O>EQ%EK/'-Y'E=XWNHL[K
+MP:O(2\'/DD?\%\\FGP-^C_?*WN579#GO)"^!U/W%XU&]R?*=ICYD^8YM?W*C
+MSZ/J3V(?!X\FCP>?23X7W$P.@CO)DU'HRZFG&Y/I6RD7?IR\#OPZ^3WPI^2M
+M8%^CX6=V0][(O^N%_)`KP*>2CP9'R0/`$LOJ/KB'1UU+^;W@%90W_L:C5E$N
+MW$T>#EY''@/>2)X"WD:.@+>3F\$_D3/@GL,,9\'[DCO!%>0+P0.&L2WV\J@&
+MLJPECB3+[SE-(,MYUZED.:,^@WKVW1]U3KGLN;2ZN-.F/]BCYEH]?3SJ"MXK
+M?#TY#O[3,&.3O1:5JU64WW,(ZH3\+'@=^17P1IO/"H_:2EX(_IHL[TSXR9;K
+M4(_J,9SE!>]#KCC,HPXA=X./(%<=[E$#R6GP(/)Z\'"RG'>:8.\%GSG<Y+\W
+M\C_+WGN$1^7(<@:@BRS[C%?89QWI4=?9-.#;R/)]AQ5DV9=_Q*8'/VG+`GY^
+M.&.#_A[UFLW/T1[UEKWW&(_ZP.89_/EP$_>N'>!192-,G@]`G@\8P;Q!?N@(
+MHW/:0(^J)*\$#R7+"Q_&,+WL94\FR[GZ<\AR%C="7@EN'6'\SZ;F<C7'ZH1\
+M(7E]/?HFTW<U>-1]E`NO9C[[()]_I9[/8YCW,<WI@SQJAWWN8(_ZF2SG-GN.
+M9%\`[S^2\N,]JA]9SD)7D^7,TG%D.:\^TJ8'3R#+=PFG4>>41O1W\IAA'M7.
+M-#/E>W.4"R^A7/95[[#/`C]B]9_L44]9_>"U-CWX#;)\;W0S6;Z;_ZF5G^)1
+MWUOY6(]^B:VV$_#NHUAOUY2KWUN^KES5D2O`)X_B/`7IIU)>!?DLRTO+51>Y
+M#GPM]7>-0WOQ7N'[R5>#GR1?`UYG\S/>H]ZTSP)_0*X%?T5N`/_$9XW$L_8<
+MS?H\%6U'ECVC(\FR/W@L6?:_!MDTX&%DV<<<1Y;]E#/(LN;O)T\")T;3+X$O
+M(G>"%]EG3?6H&RF?=Y9'W3G:]*,%TSWJ4<IW:_*H9YD^'41_',WUO5GEZD-R
+M%UA>,"P\#]R'/!]<?[+1(_>./MG4PYA;RM4,IEF`-.U6COJYBNEWB:(MR'N"
+M5Y*[P<^0]V^&+9%_!]Y*[@_>0:X$EX]ANX#W)P\&'T4>"AY*/A$\@3P,[">/
+M!+>2QX/GCF']QSQJ\1BN]:$L?Q[#^!9E?)%\/G@SN0O\`_5TS_*H7J=P+`!7
+MG,(^$H>O/L6DGX?TP\DW@:<Q_3^1)D;^!#R;_#GX"O(WX)MX;]FMR!M9@9]C
+MFL_2'K6!_`7XGS8/K1AW3N$:%,I5-I;K3N"#R(^#&\;RMU#_5*[&DN>#H^0*
+M\$7D:>`EY`7@>\B3P,^,-7EX(8.XA?)YD']*^6V.1_U(O@.\VSB39@K2]"7W
+M1+F&CF/\D$,?(6?!YY#G@%N8?N'=F)N0%X!O(?>"GH?(O<$OCN/\%^5]E]P-
+MWLXT^R+-+N.-_OW.AXV1?[P`/IGLOQ!]F=P$/GD\QRGD_QQR'W!F//WG/(^Z
+M@/)KD;>K>:_(;R&/`/^9/!Z\AO?*.;IUY.W@=\9SK0]YWD%>#^XUP?`&\)'D
+M3>"A$XQ.N?=4\B_@`%E=XE'9"<SS\G)U';D"_!#3G'J91[U`G@3>2)X*_HQ\
+M#O@7\DSP7J>R?<%]R;^]'/5&/A(\]E36&Y[50OE!"^#?R'W`B\F_`]]-/A2\
+MFOS%E?!CY._`6T^E?UL$FZ?^OM"_ZT3#_<&'D0>`ATZD#Y?OXU->!?FYE,OW
+MZ.-D.?=X/KGQ6H^:/Y'M"+Z!]XY96:Y6D&>"7R*/!V\AA\`_D:>#?SO)Z+E@
+M"<8.<A>X@7SX=?"WY"/`4\FMUR.&F<1^^G"YZB`W0^>53'/V4H^ZF?)&E.LQ
+MF_ZQ<O6&E:^`_R>/!/],'@/>?S+KYV:/.GPR^Q?N'3*9;0WY*>0`^"QR"SA&
+M3H`[R2GP9>16\(WD2\'WD)>!GR`_`7Z)>>BZ%;;'/"Q#'K8SC<A]I[&/@'<[
+MC38/WH_\-;B"?/^?/.H8IE^VTJ/J3N->84NY&G4:]:\N5U.97M($R7\"I\EW
+M@2\@WP.^G+P"?#UY)?@.\B/@!\E/@)\BKP:_0GX*O)'\#/A#FY^GR]7WY#O`
+MNY]NTO1XU*,.)/<$]R,_#*XGKP:/(#\)GDQ^%NP_G77[&.9*9'D_DD->^!>/
+M.H_I`VL\ZE)R!+R8G`7?2FX#WT?N`#]&G@-^CGP-^#7R$O`[Y`5/>=1'?*[\
+M'N>.TTV[3$&[[#F%<0BX_Q2N5Z`>3IC".D?ZB5/,._2>1YH`Y4]`[I#7@"\F
+M/PV^GOPL^![R.O!J\M_!KY+?`F\F;P)_3=X,]IUA^`/P?N1_@ON1/P8/(7\&
+M'D?^$CR#_#4X1=X!GD/^'KR8_"/X3O+/X,?(\A*YE\@^\#OD'N`OR+N"_TON
+M!=YKJN'?@`\G[PVN)^\'/ID\]47T:_),<`LY"+Y@*MMK+?SA5.YE=)>K&\D;
+MP0\PO:1YBMP;_"JY#W@3]6P'?TBY\`[RO\#>,]EG7_*H/<[D.(BV_CWE6R#O
+M?Z9)+UQ/'O$RYL7DU>")Y(-?\:CIO%?.MT?),]<A/F0:X8O(8?"5Y!;P'\D9
+M\#UGFO)N0GF?)&\!K[-Y7H_Y!;GB==@2[Q7^@G(YP_,=6<YX>Z:Q/[Z!V)(L
+M9_[W)\N[[/J2Y;LDE61Y#^$@F_YOF">2Y?S>!'(W^(QI)@_"`<KEN\#Q:8P?
+M4+?G3S-EV8:R7&V?^P^4W<7+R3/!#Y.[P$_:O('7VN>"7[?Y!&^RS]WH4=O(
+M%>"OR(W@?UO]<D[X+.H'[T5>!JX@=X,'D+>`&\CJ+8]J)%>`)Y$;P>>29X*;
+MK7YPSNH'S['ZP5=:_>";K/ZW$9]8_>!55C_X*:L?_)+5#]Y@]8,W6_W@3ZQ^
+M\#=6_SN8>UK]X!YG4S^X-WDF^&!R%[@?>1FXEMP-/H&\!7P*66WRJ&GD"G"3
+MU2_GEZQ^<)O5#^ZR^L$+K'[P$JL??(O5_R[JQ^H'/VCU@_]B]8-?L/K!ZZU^
+M\-M6/_@#JQ_\M=7_'OK+.=0/WI/<"#Z8/!-\!+D+?"QY&?@$<C=X+'D+^$RR
+MVHQ8R^H'MUK]X/.M?O`55C_X!JL??*?5#W[`Z@>OL?JWH.Q6/WB]U0]^Q^H'
+M?VCU@[^Q^L$_6_W@7:93/W@?LGK?HPXA5X#[D1O!QY)G@AO(7>!&\C+P*>1N
+M\&E6/WB&U?\!ZL?J![=:_>!.JQ\\U^H'7S6=:V7P,W=,9RP'^</DN\'/DE\&
+MOTY^Y$./VD+>"/Z*O`G\"]G[$<:(&88'@ON0JS_VZ',#PA/`QY'CX+$SZ'L_
+M18PTP_B]S^'W9I*W@UN91K[?VD66[^9?15X&_N,,4ZY>\7+U('E?\,M\EJ1Y
+MA^DG_>!1GU,N[#F7\17XM^0;P<><R[K]$7V9W`4>2MX"'D6>]!_X-_)*\-GD
+MWC^AC<YEK(O\S*%^^1WO:\CR>]Y_(E_S,_P8^4/P"^2/P7\G?P'^B/PU^`?R
+M=^!=_89_`!]$_@5\#'FW7SSJ>'(O\`3R;\#GD@\`I\A9<)??M,7R9\K54O(/
+M:)<'F6;&+E[UK##*^#[X;:;9@33?^ADSH.Q[SS3I/T&:P\F?@>O(7X-'S:0]
+M[.95$V?R/!Z>&Z)<OE^<(,M9[AQY)?@/HL=K>"GE:G^ONH-RX<?LO>!NLGS7
+M^&6RO,_S3?NL`[UJ*_,F_"VY/WB7@.$J\('DP>!C`KSW(*\:0KGP.')_\`Q[
+M+SAE[P7/L?<>[%57V'O!-Y*/`-]-[@=^A'PL^#GR^15>]3IY,7@S^2[P%^0'
+MP/\AOP'>M<GP1^#]FU@_?;WJB";:;0)S-'(%^&QR%=CAO9+^8O(EX.O)UX'O
+M(=\%7DWV'>E5KU)/'?1\T,0SF6CK'YGF]_V]JE?0\*'@WY&?!E>1GP4/)[\`
+MGA+D'BOT-),??P$Q%7DM^(8@V_IHU&>0>Z#(PU/4(_+7R=>`MY%KC_&J[\D-
+MX-U"7$/[/\3#Y&DOEZMZ<@A\>HCU.<"KSJ5\.^0=(=8;Y)>2%X"O(]\"OI.\
+M#+R*O`+\'/F02J]Z@_P[\/ODZZJ\:COY7?!_R5O`>X;97ZJ]ZK=AGDU%V8^F
+MO+O6JX:&&:.")U$N[P8\Q_+Q7A4AR[LO6LGRG=GSR5W@2VWZ1J]:1)W"MUKY
+M2-A&F/X$=;*:O`.\GOP3^)^\=_HHK_J&W`3V1+@>^TJYZDWN"?X]N0PL9ZWT
+MO&.B5YU(+CO=JR9$3![D>_U3F+X7TH?)O<%M3/\QTLPA?P%>0-X.OI[\_)E>
+M=3MURGL\[B>KL^%SR!7@;G(C^#6R?(?EG0C7BI/EZE^4RWNE?J9\#>3[1LVS
+M/C\'_I/<,^!5M>0I(:\:0=X1]:K3HVRC%O@<LGR_+T*6[_*GR?)>Y?.L'#R/
+M+.\(O9HLWP-=:M.W>M5]?)9P-^7R[NO7R?*.M4UD^0[71U&N]Z)N?R8?`-ZK
+MF<]J]ZH^Y&[P0/(6\''-M&'P.,KEG7CG-#.>0?UDR3O`"YE&SM7?3%X/_C/3
+M_(0TZ\A34N7J4^J/GX?^0DZ"]XT9O@!\5,SD^0;D>0SE8R[PJNGD]>!TC,^]
+MT*LN8OKE2'\C>07X_AC['9Z[EO(UD+]//7+O#BM_#?4SR\C?OLBK^I)[=WG5
+M(/(^X+'D`\$SR(>!T^1*\%QR-?@Z\DW@>V:QSN?`5BD7?HG\+/B=65R?7%^N
+MOB)_OJ%<]6IA#/`'^&?R3'!5"]=@D7XD>1+2GTF>"<ZTT#[GH7]1OAWR6\CJ
+M3<SKR0O`_Z#^R9=ZU:?D*/AG\H7@WG'Z0/#AY`?`#>0^\[WJE#CM\S*O.HN\
+M_@JOFA4W[1)'NUQ.?AY\#^^-+_"JI\E)\)OD"\"?Q;DG\E:YVCW!_BCO.B!O
+M`M<GZ!NO]JJ3R%O`$Q-<;\2]X03C)3RWB_)5D"^E'DE_/^6A]Q#?DAO!VVSZ
+M=\N5-VG2G[H(?I[<!3XZR;8&#TERS0'/FDC>`FYF>DES'OE9\%7DZ==XU6UD
+MO[R_*TG_N1E]BERWM5Q]1(XC;S^1>T.^7XI[>9#7I%@GUV(<3YD84MB?,OJ_
+M`3ODJB484\A)\!_)<\`/D)>"GZ/^=7C66^3X-OA5\A;(>Z<-'P\>F&:,<;-7
+M#:,\7M9#3:?\R%N]^@RH\$G@>6F.7[>C3M+T)ZBWV\@J7:Y6D<O`_T?N"7Z7
+MW`LLYT0E+A4]Y:V,M\'[D)>"#R7?"CZ6?!?X!/(]X''D^\%GD1\$1\FKP#GR
+MH^"YY.?`BUI->=,H[UV43[T+L27E6<A?:>6X=K=7;:"\;X\>:BMY'M)\PWN?
+MNL>K?P!;^/_`>Y`W@0\B?P'N1^Y]+^)_\B3PL`S/N*)^3J/\9LC]Y#^#X^1'
+MP9WD%\"7D'\`7TO>Y3Z,R^1K5WK5R@SS7]Y#O4#YH0][U=_(VU8ACB*O>]2K
+MOK)Y>QQ^AGSU$UZUNV/XS;\@_G>X!HMZ.)KR#:N]:C#Y4_!H\G?@*>2^:[RJ
+MB3P"G"9/!5](CH`7D.>#EY*7@Y>37P8_2OX8_#RYQY.(#\D5X"WDP>`OR1GP
+M3^2YX-VRK"OP`>0-X".S])-/PP[)"]=Z52/3")]!>?=+7A7(,JY&.[8QC<@O
+M(?=Y'6,0TV\'W\[TTY'^,:81^8M9TT<^WNA5[Y+7_<.K_L5[)[V%.##'?4;8
+MY'XY<^\\R/N3+P,/)5\'/I7\%#A`?A&<);\,OI3\)7@IV?<VX@?R2G!WCF<Y
+MD.=-E`]X#[$W^5EP61O[`OB`-O;]5LP1VNA#WL><MXU[H\C_C#:[GH/QB.G'
+M(_WY3%.%-']D&GG__YWDE>#[R6H;[($L[]GNMFG`KU+G'.C<UF;\K<B_H_XZ
+MZ-^]W>1Y]3\1CY%?!@\DOP<^L=W<N_%3KYI&'OP9?#73S/H:?K*=<<+('NIF
+MRK_[#OFT\A$]U(OM]($_>-5[E.]`^J\H[_MOU&$'8P/(#R'W/J*'JNF@'9;[
+MU`D=)@_"4\EW@I-,7S&JAYK78?+P$N2+R:^";Z<>>?_D"O)*\*-,(_P\^6'P
+M&TPC[RA^ERSOJ?C0YJ>73WU%7@_^B?<*[]%)GP#^';GG'CYU+/DP<"-YQ9X^
+M-9D<W<NGFL@)L$->!)[7R7@`95Q*^:J]?>H^<C=X32?CC7U]ZA7*A=^C7-Z_
+M\2%9WK7U5:>I_YX'^E2/V=0_NH<Z<#9C=<B/)LM[.`>1)QWD4R/):?`$FP8\
+ME;P2?"YY/;B9O!WLS.9\!_9Y^6SZ`<AOM/<>YE-W,,TFI%E-N7Q/]D7*?X)\
+M"^]=>:1/;;?Z^_F4]SSNUZ,L?<YC6?JC+.2%X#IRXU$^=2)9WOLZQJ8_VJ>F
+MG,>UD4RY"I(KP+/)?<&7G\>X!>F7DA\&W\LT_9'F2?(`\'JF63[0I[:0'P-O
+M)V\&RX_&:_L!]R9_"ZX@>RM]JHJ\)[B1?`1X$KD2'"`/`6?(H\!SR6/!UY(G
+M@^\D3P,_2@Z!7R0GP!O)%X`_(2\"_TB^&[S[!8:?!O<A;P`/),^K0E\F3QGB
+M4Z=>P'8YSJ?.N8"Q&=HNS33#A_K4'\BCP=>2QX'O(I\.?IQ\-OAE<A-X$WD6
+M^$MR2GZ@ZD+#[>"]R5W@ON1YX`;R%>`QY(7@L\E+P''RC>`+R;>`%Y+O`-].
+MO@^\BKP2_'_D1\`;R6O`GY*?`_]$7@O>\R+#KX$KR!O`->1WP"/)6\%3R5^`
+MF\G?@6>3_P->0"X[WJ=N(>\!7DG>!_PL^2#P!O+OP1^2^X)_(%>"=^LR7`ON
+M0QX,KB0?#VXDCP2?1AX/#I$G@]O(4\'SR3/!2\FSP"O(R\!/=G'>`?MY@_(A
+MPWQJ&_E$\'?D$>"><PR?##Z(/!8\@'PJ^$3R:>!)Y*G@)O+9X"PY`+Z$'`;?
+M0&X!WTN^";R:?,4(GWJ5_$?P9G+%2)_ZFCP1[/L#^R9X/_)T<#_R3/`0<@@\
+MCMP,GD&.@U/D=O`<\ASP8O("\)WD&\"/D^\&OT*^#_P>^3'))_D%<-E<PV^`
+M]R=_`CZ:[!F%OD_>!SR)O'VL3P7)WX+;R/\&7T;>:YQ/W43>'_P`>2CX6?))
+MX#?)D\`?DZ/@_Y#/!^\YS_`UX$/)]X+KR`^`3R8_!#Z;_"@X0>X&=Y%?`"\F
+MOP*^B]Q_`NIP'L\HPB;_2GG;&3[U/KD#O(-\'GB7B]DNX(/(%X,'DN>#&\E7
+M@$\G7P6.D!>#.\G7@Q>0_PB^E7P;^"'RW>`7R/>"-Y+O!W]&?A#\"_DQ\%Z7
+M&%X-[DON!@\B/P<>2UX+GD%^'9PFOPF>2WX+?!UY$_@>\OO@->0/P:^1/P5_
+M0/X*_"WY6W#/2^G?P`>3_PNN))=/]:EAY%W!4\B-X,BE7--#>YU/^1/G^-35
+MY#7@VYEF#=(\3OD1T]%'R$>#WR-7@;\FGP0NFV]X%'A_\A3PT>2SP2>0`^!)
+MY&9PD)P"MY';P)>1N\`WD2\'/S"?YTR0SQ<H7S(#[4N^"?P9^6;P+^1;P7M=
+M9G@YN"_Y(?`@\FKPV,NX/^O'6$.6=R`W7<;UHI-[J-E,OP;RRR]C[(=8Z%:F
+MZ8LTC_#>]1'T9<IG0KZ!]XK\GU9_%/$2>2'X1_)*<(_+J0>\%UE^J^N`RQE/
+MXKE'7<YU#^@?<KG1_TP+QDWRH(1/3>2]74G$)+SW<]R;8AJ17\0T52F?NE+D
+M'L-W4"[O-5U!EM\/>HPL[V5]EBSO3'O%YAG\=WMO%O9C]8,_M?K!GBLXMH+W
+M(I\$/I0\#%Q-/@T\C'P6>#)Y!CA`#H%;R2GP''('>!&Y"WP;^6+P0^05X.?(
+M#X,WD)\&_Y/\"O@[\B,7P+\M,/P/\`'D]\!'D3\#'T?^&CR.O/>%/C5]`>OP
+M(I^*4?[Y',0SE,MOFUYBTX"7D!OGPN^1NRZ';R$O`S]!EM^[>9XLO_/R&GD2
+M^"WR=O!6*U^`OF-U@K\ER[ND?B'+^XAVN9)YN`KM19;WBQ[DXL-LFD7P\U>:
+M<BT$'T]YQ1+$GY0+3Z-<WE$VT]X+GG4EU^M@VQ?:>Y?"/_#>-/@&RN7=:W\B
+MR^][/DB6]W@_Q?37_@GU0'GO.U$/Y"KP5K+\1LEV6Q;P#U8_V'N5TG-,X7VO
+M8I[O]JE#R/+^J'YD>2=A'5E^1V8X>>9]Z(]7F?S\ZPF4]RKVQZYRU<DT\AMG
+M\\GR'J>K^-QMX)LIKUB'V(9ZA!]DFIZO8>PC5[SI4V^3QT#^F>4-/O4S^5KP
+M;ZXV_/A&]#MR]QO(_]5&?_P?Z'?D->!3KV99WO>ILR@/?X*8W*8'MY-;P9<P
+MO?QN["*RO!_R9O+V;WSJ;G+O'8C5R57@O]A[P<^3Y7=:_TJ6]^6^39;?1]MF
+M]?R`<<KJ`?_"_*A_H[P+#??^$?..A=0/'D"6WWQLL%Q6IDXD=X%'DY>!)UMY
+M>9DZF[P='%G(=;,YY>H"<A_PM7RN?]<R=0<Y"%Y%CH*?)W>`-Y`O`F\C+P3O
+M(%\#+EO$<1"\+WG\[F7JB$6LA\/+5)7E(\O44+*\VW,T6=ZY/<FFZ5>FSB++
+M[QV'J3-]5)G*D<<<4Z8NMEQ;IJXC3ZDO4W?SWNT-9>I!^ZQ!96KU(NXWH2^_
+MMHAK"*B3]RE?#_EVR@=#KJXQO!V\#_F`/Y2K?M>P[4:4J7KR`>`1Y`KP9')_
+ML)]<!4Z0!X//NX;?<<!S%Y(7@.]FFL;)9>H1\BG@Y\@3P*^3)X$WDZ>!OR3/
+M!/],;@;W6LPZ!!],[@`?3>X"#R'/!X\A+YM2ILY<S/KTEZF99/D=AUED^:WD
+M''E24YFZ:#'7]E&6:RB7]Q#>9/6`E[OX$:LS7*:>)LOOL+]$5I$R]7>K!_P>
+MN1'\L;U7?@.+W`7N>2WOC9:IWF1YS_F!9/G-N,/(\CNS`Z_E^-M2IHZG7'Z'
+M=)2]%SS1W@N>1EX(#I#E=V];J$<ERE0G>=]DF;K4ZLR4J47VWER9NL7JG%VF
+M[B/+;^P^1I;?57^.+.^0?,/*YY:I=\GRNY,?DKLO*U-?D;>`O[?U<#ERLH1U
+M"-Z5+.^HW'N)'<?+5)\EINW./[6'JB1W@4>2R\!G,+W\EK>?+.](3Y+7@\\C
+M;P?/M6FN+E,+K!Q\_1)^AW%NN;K7YFT)?-$2.RZ7J6?)/:\K4^NM?O`FJP?\
+M(7G2]67J:[#?/_*L4X=-.&4$R)\)!^.!6,+?E(LH?T<HXX_$4X&L\H=R:7P\
+MZHP1?B>=RV9RR;"D#F53`>6/AK.19N5OSJ:2<>4/-*4RN"&<R2A_))R"FE0Z
+MG)34P50\'LB&_<'F0"812/NS@:8XU#1E6I0_Y@2<8"PFR2*QCE#$B1F%CE:?
+M20>;.I.!1%@GS&8[H3HEMT4"34@11!(GG)4G96/)D,EX*)#-)0QVIC-A)^U/
+M!)QL.&-%34CIQUVA5$(_(QW-I-VYE,?YTYF8S6;<R4I%-.D'R`U.LRXHZBR8
+M"$EYG:PN<B:3RA2>V^KOB)A+5*W?:8E!%DQEF,ED.)MJFH42-&=2J:S.1WO(
+M9">3PD<LM%S'(`\E_>&.=$!R@*+B/_-1P#'5E(TE4.&A0*?DJBGK3^><9L&T
+M/\,<H=J-1I0SVYD&H`:BF50N#0V=:7FH:3F1-Z><;"CIA).ZE(%0*!2KU3?`
+M.")2D9EP(!2/)=$.@5RV.9>,=?B#D&7#QI(<78>Q9&LNG.DTSP]D,B9WMI:=
+M7).3C65S65/*G)12Y]WI3`:!&12V;K`_D8LC$[#%8(O[;IU54VK868+WX"[8
+MIRF>9"R92H;S&4/V\1G+E$7!TU(26ETH)@862T;T0^+A0%+,GE418YOE_/%4
+M,FJSF8['H,II"R(OR#0L+&$J4.<+20,A_!,,:!.*.%`6;0_(+3$G&4"W:`JF
+MTIU%9MH2[O2W!>*B(M46B?M#X7A8<IX)1V-BP.@,IE$CK7GKD/SI,L6<:":0
+MEMX8"L,>4[JRX\%4L@UU$0R&Q63DKU@,^F^L3;>I'_>9^M*-9!LSC7YJ+"NM
+MS0\5@>8.:]\@_0#9;4NS$XBY16-)XPV<2$S*ZS]Y_,3AP\;[)XX>??JH*?XI
+MPX:/'^6W937=252FHNB98D2A65)G,/-8)&)(ZXV&]1.<1*`EG/=+Z7`X8XKO
+M-.?0B=O-HX/2?=`:F4![OLDE,\D4Q$$84RQ#K<%$F@XO7\-^L3-=(6@O-!IN
+M328"V:#N1,AFC36`F%2U>!U=YX6NCJ8S\F!`*W<;&-PF/88D2%K?U!8.9L5?
+M2#_R)[4_;7/@=I+9B"Y0*.:T6#>`<N5":7\X*1XI&`@VF\8/2^/ZQ3F(>\GW
+M;_81;8':A^DF%TL)Q&,!1QM4)!-FHX=UCN!2T*A2WVT11^X4BXJGVJ4(3@SM
+M*_:7$R."<3GAM'Z^]1]`[9)T]2;#[49Q4RH5IU4XZ;`V77FJMNUT(&J*$-7F
+ME<VTQ1RFU36KK</T':VJ,RN%0$VRR/!)X;B^,9MJ95ZBMI_*,,//XJ9%=<^)
+M%AQ`6WL@D^R`(NTA"@-;M-#A3;Z-J8HFF&FH*0&3@K?7K=TF5J7]15,LBBK-
+MYC))XQEI:NACCIA4K'9P@ZCSQT.VCC)AW6-#J%A`IJ0[.>%6/C1$\X!.K1)F
+MK*U4YR2L[3.11C7#9:4<Y#\K%H9A$HES3CP<-CX,1I7*Q&3LU/6D:T"<M';/
+M&`4#TGO;D2+<EL]!("/*I:U%66?:CUK48W`\W1S039GV6_\NN1&?F='^#\85
+M[@B;^@Z;-DEGLGDGADRBKH.Z?[I\GQTK<0TT]6Z*ADZL;Y/.I1LV&$]FW;T<
+M=V&XBJ5<0Y`>`ME!K<\..,UQ^CP=VN22J/\0&K!91I,X,F?*FT9E!&&&61AM
+MV/@^!Z./-G`8E.D2&5VIN!=:\[6%+A0(AJ7JPPB?,JF$7X]J"1E<T=EU-]9!
+M3;A5]S3=&NBU2N=Q5B+-""+F!%%"&0?@>G0T@E'!&K?IN(@&8ME\<!%.AE(1
+M&UW05Q2&O00&@4@LRLPBCVWAC!B+7T<:*'.@TP1J*'TPP%K#(.)O,J-N+IE(
+MY9+9HN`DEVB2:F@.!]*.-MR\/6F'G6MBQ!!NT9U!+,0\`UE%[;05N4\TOQ[V
+MH+_)B<W6(Q[=L#$M;=LPH&!*7+=D4_["99K(,9P,9CK3>842_!1L*N8TQ0-)
+M'3Q@D`YFX[2/2,B&M=(BNO=CA,NRJ\'@=4]GH6W_D4<W&UM$TW#02Z1"VNB<
+M3!BV:KQ27,K:;`TC)V.:8VZ7,5^;5XSVI74%0H&VJ*Z=9+Z+SC(AD,VY[H"V
+MP26ZAEM&<P3-$"JFA5*8&K/#FO1`;8):&,M$9#!$T6`G>F@RCVLV/A$^DD:C
+MN['T,G\Z+Q"[E&?DDH6.;#Q?#(%B)FM\@QY*3+<US1W5838<#,>QXDM=X3*X
+MFTI'8@P^'/."MC-(&C,\ZE@-W=;1X1HJT\Q-)@6RS>,Y6#`<2>5,?&[,""T3
+M;(X73T4*X:<-\TUEV-$G8RH.O<H4)!O$P!1J@L866T(]T/FCB502X9+TXD2+
+M!(%I=J#B8L/!)'2\",\6<8Q;1O2N'Q?(#_MY\/L[T$C2AUR=Q+C@9"P_[DJG
+MDVR)MM;FE(Q1?O&L49BKV%LP$BW8&>H+;M<)Z[YCQD(;7A@'83N:=M?N=A9C
+M36H79/I)V!HF5**/H>21K*-'/AM7M:5C$E/FBQ6+HH6USQ-O:ON_[8_N8F1,
+M,4RI,6D1O^S78Q!2H\_9RM>AH>FPF"SFX_!VM(]$L=K,S8P-%<*".>V!M$[;
+MZ11<?G8VVR@61;?1>31/T`-((A!"9"*&%<QEI%L6U:^C#5:716K`.G4$/EG&
+MP6:V:9Z$$N:C=;]N1^0PFY"`T6$L`5N"@62R8M<H0#+<D:7;3N<R4:,0EF4*
+MIJU4#[#:'LR(HZ_A%O!\I(ZT!^(M'/R,.4F=:I^FO38*+2[+M$PV8YR;'MOI
+MRZ.NP0^).2*@)'H@T$5IQHWLJ](EB@T03L0]&)G.C&@QP@`G9R*=M%X*D*F-
+M'4-L=9LH4-+$9!A'HY@@(%KH4BD[9RCN*ODP"@V(4"^22W(YPL1\>:]O'+`H
+M#UF[UM.,E(YY\U[2SH?-3,]X7WRB<V6*8CQ_+FE#6=W!C&=##ACKN3P0_1<M
+MUUBM]KI.B=N5CION+/A',V&SWM`LF3"H,1&-&",+FQ^")8AW$F$S;NN!3RR0
+M\Q-3?MTZ\60@%;'/DA(G8DG=.B;4@?MR[#PJXV1T%)Y?IV%4@`QS3&0\C8\P
+M.NB:<)HQ63?S$=%G<HDGQ?2DPWCB;"*MHR(4CG,<'4([A1":974BUN'8D=:X
+M$L,H/*K#E%(\4#`;D][?*>M!G-K9&N1XDM3ACPR6TO-TE(_Z,ZZN+1@)Y>U8
+M1\$F\(&/EQ&[:'%)3-`T4BX0#XB#%'??;NPGAI`NSL>9F2CZ1SQ@YN4.JL*X
+M`AEL(\9G^O4<1E>8B2%TC"IS^RC#`QV\,ZY(T=]+1Y3NF^_$^;'(T2-;(0QW
+M.A-F,:>HO4SRC`2SXI$=KM%(,6UO%%W9`".-O%N'D06UO6)>:B*V0ERF#2CG
+MZ.)E@P7'P`42O?*".LT_U;ABN[SCM#<'LGHA`&9D0KG\0&8-##D+A3LDJD_J
+M.$8[/%V->H5#KX2$I8G2\<["(I@V]*`)<YU,(!3K,*TKE6ALU)0!S<VY6+ZJ
+MFK.T[+"UF.PL*;0>?%.%241^`2,_KJ$1"E[([T3B@:C#2*XP60K"UA%G-.?C
+M>;1_2D>9:%*NCT327#$0EZD]+]RG[K2),(8-QRY7HG.(BTLE]"!!]X+F2J3:
+MC&:[^.*J5;O4DM`CKJA(M-!)RSAJ*CE_@ZV,-B>9'_S9AS/AME1+WM_JX%F>
+M5I-..;$.O69"(S)1":K)^%ZI91NBAMOUR*<'!9-5L7AH*&Z0_(C>)O-0AZL,
+M052H+GDV*Z&$+`-PEJ'=62@<T?U1ZE^B$5J(WY]HDM$(3J.#(T.^^4R,S'K4
+M_BR_]@:'&`ID$;2FXS90AG48$5J,$8DVSDPB:X+[SK1>2F3GRH1-LT@YHPGZ
+M+1N0&>NW@SG^.$6-8+MZ,I1-R2"@%W`R^>&%.<YG7Z8%,F;D9UIV*4E<:\3$
+M<OXSIHRN<2V58%C`?--T?717O9ZCS8-*3'KC?3%/,ZV%C#B279FQR$?T'GKA
+MS-R62PIKVZ(7'V$B@=/P5!OE2WI.SXS'==>;8TP<M6/#OGQ\4BB^E!BA'T)_
+MY6\/9E,)_/4S"$%'U,OG#F9108:I*;W2$TK9""&-.8<1HBUTSRC,[<T:NBMD
+MB-B@7V=(C\9%IJ[\-LMZ+`AQUI"=;;Q_(8"-.2E.A=)V&&ESQ]AQJ=`@PV=M
+MOPE'KWW`M@.Y>)9#2&&!F]&2,<LV&V';[I".=.C>HZ>&,'_M*8WEYTQ[NCVE
+MJ_^:A85.O?IDAOM$4\:835-AI&[2&Q\1]Y*G6:W42P`TOI")M`(YAP&>=)7F
+M$!O3/80X^<7#-J>P-)?-3X;Q.3I^?N*A>US)8JD-8S'0R'`G#DB*[LZ6;@G6
+M$OJ"WRQD2L,8QP<G%,[HM58]+>$R,^H[8CTPTN8R>K#,F'@^V!R6-N,8;N:.
+M.1T(Y9)F7+;EUJWIY!<(]"JF*FS=9</QN+:N8$0FU9F`S$^YCX+<209:0[&V
+M3-CL>V$*S%5;L[5D)\(V:,>`9>LVZ=#N6DUC.X6E"2F?[6AF,+,+MXX."\UT
+M![U#`EP_%\)MD!/5;:*#O<("8L)ZY8Q>N.9,()Z?X:,HKC5DJ9M4.H`A2>E%
+M*SL,(\NF13"^V8F9;7_M+F#79I+&Q3>[)6$')OU`67^5*9MY3BQ96'/+FUU&
+M[\H9%V]MS10J;#JTZ2IM9M_2[+[Y\V$_NDI4UN-,V"11$QUM/C+@Y-S,!1,M
+M9H4A7Z')G+'CF,-M/;MIQ2$3`W?`!`GQ)KN#:+P3C4C'<Z95]$A<PYZ=,+.&
+MYH2.N$<:!^)VPM%"\P;U&&1BZD1A]\PL0(M#;:-QRRH*]UN;"XM*4@^A<%!/
+M&5"U;3*15?X63$S345V@3)MKE9+U82Y0'['"4&7CQ$*G3K5(3K)!3.VD72/!
+M9D99>CLGJ2<$F&YPMBZA2B;CB@W3.G"PYF+67*6=S#39Y?!0?]K?F>Z/OB)-
+M('XAC2#;U/]HNX>4WSYV,MS@PFQ)3\XY=Y1E!1TMRBI!1,;)3O-8AB<EG3/F
+M<*O)X?IL?@W++`88W^DW?L:?D9PY-'V]XEM8$F+LKRU79D%.5H_PLJ#M3R7C
+MG73I68G.G>:PL3RGW>95+Q')9[J79DUUR20+OJ5)G+C9%W',2A'<>K[GH4V3
+M85-/4,:H`1\WF=7N_$Q&-E#3W"E&.O-IWJ2B;KO.F2A#GJ5W-60#QG@,Y$!F
+MQ:A2Z\4232AI>U#OA*,1N&X$.],+3W:CRXQ\9FB=A=P69A%%=F"VPU#(>$@W
+MC^2Y3H^$J31W[:,<3"*%,((KQ*VY%$9PB>WDMEIK4++YRO`*_Z,C2F=Q]$*,
+M]6G:TW!A(+]-@4;A,F+,<=)Z<P*M:<T-?<)$%7H(-FN3JC#C,8\VRVLZ%FG7
+M8R:WS@H!OEXO0K:X6<;I:[N$5GDW);O*\,D1!P(.%+H9]5J,:6Z4A>.W"?.U
+M_T'<H)V@72(L;$+HE%)KLU-)/52:E4R)\-Q'$8+^-KW"!A^;Z1`7QR,IH2;X
+MPICV%OJ00"*-H;,&E9'2M1_):NN&/Q"O*[/3)JAI8QNDTJQ_&&!'VIQS,9M^
+M>8N.T.-%N'`G6V(2S=MN(6Y<CWNRN"K%T(45*[0F%@G#D(/AHH4%^4<'N26+
+M#8BK9F/"K"N1]B^+<5%=I,*26"1I5M",Q\Y9ZR[LJ,=#NCPZL_@;=P_S9G\'
+MDTMZ^OR9BX*U<;9FXUZIMD0@T]+F<BZ<*\>B=L,T/R.VAPXX/''\DHF8#2*T
+M)^%<TJ'52-7K<$S/7YIC<<S;3"G;\T.%;(YKD6-GS<85<:4@8OQ1HB42BZ24
+M'3]-A;3IB,18G@Q-IF[B:=,-]*JB>PH?C><X8Y.3/1QJ(L;;1##6VVVM2)2S
+M5MW49OZGHQTSU^)^6Z));UK(*2/%Y77]].*E3KN9@_XOIZ!29M?%Y:+-I&N6
+M66N*(%XWIUVX%-NNPQ(;Q.3LP9"$6>EUY<\?R$AI=%/IE3DI&6U`5@,Y[?/+
+MKD;&3HZ;,HBK,<38K6W.VF3E0/R_V72U^\02122S&/)2KH$TX)[:P[+<4]-,
+M.%M8`&R5<T#1C+21.6<C>6_/8&K,B:'4>;MV.[H6==\TBYEZTF6FS'H.J.T?
+MC2^#<3ZH3G(5OT,/5%%7MS4+K'BXHRNQ4-GZ%(_>1]"!C]F89]G-\^Q45)<A
+MEC;;5HXQ;>0?@W[>F\E*D)Z71DP7CKKMM*B*&/<B/WJEE3,`QZP*ZB<QDA+-
+MMF',MK+^5&?#S#Q@^"Y+@L,,YSN(6>MK2<HA!=AB/-9D#F3)S9SN8Z")['1$
+MS$Y&5>&,C%-T@LUX:IAJB%4>T/L%^O",=L=M^3FC7G/)3U*R:7L6SI8DRL"?
+M:Z]^\?/:)^I,018S*Z#2'^-)VP$<<TI`SS_UX!'0!TD0/!HG?QJZHE]"X0F!
+M:$SGWBQW1\P(*-/MN/$P"7U[LVWFHH@HCEY1B$CD-!FO\#1H3>229FLH%L50
+MD>W4'2ZN3SWF%WKRW0%MK8L*2Q5GFS!U8*9,Y@@8P^QD2B8<NBSZX)1>5+*+
+MD=H$$DVR%N).'I0CD-J%T:)-U"HS#^Y:.':?V7T,Q<1D^J132A^#2"61E6Q&
+MJK*%)R62=H!I*^R!1FCFVE4&;.B67SW-\7A/),1#"_!N.2>M/72+WGZ7`RAF
+M;M%F=^]0/V98Y_#OJD#36;A,'S8K(<'FA%BUKFQ=HQ+0RU$B8P!!XQO-_!E>
+MD2:FAW.SY,#Y/O?RW*>9(L&D9`2M:Y3(N4\3ZKJ/DR53>@X;,6MAX:0]&VFR
+M'PB*!VJR4;MC9Y\\DAAA*[")$9043K[D;`>0.DWHT9@G`MUG=-VG7XL^B27=
+M'R%BEI4S&>)D=8M.@,?3I#?FS_45G<5UK7T[9I[!Y@H%$".;,R+LL""[P1IJ
+M,H4/Y=(F^T%MQ;JA9&3FVD@RI$$?#,Z:DZIQB;(+2[>LD<+NNED]H"G+$D(P
+MEFX6MX36U<-_*-QFNIF80?Y<LHGU(_D%T4[M??)+;?9<%4W$O8-5Z:24^U"8
+M7)MME5`L57I163C?E$H[*G\R6]+)FF,VF"[&2KNW@NG&KT@1'H7"L]M2.:<D
+MP?@15<67U<67-<67M47*=;2+BR*AA"RE,AF:9<W9G\UTZ@^<&$+OL"U"_BJ?
+M';>D>B=)S4Z2VA*)''A*.NE2*08D678)Q$L_$/\8AWV6ZJW;25*_DZ1!\1B.
+M+8[!?%DR@?;\)QHK_68A4#=MD=@<9$5G:Y,!2I_-2270.\1!B0Z[<U#"E?DQ
+MV"V4YQ=?5Y=<UY1<UY9<UY5<UY=<-RCW7D0^4X5KG8="QY$4^06DTHM*OUX7
+M3::DMQ9_<-JD$2.'%\L*BO."ZE)!3:F@ME10I\SF0-X:BR\K[3'2?)/HS]F@
+M+D;">$P.+DB+NN62S9)TYAACD<)H.(DY5E"4YN?-I1>5_OR5?LK.G^F/BA;L
+MB])(5DH$U<IN!VL#->OC&NU,C1<\\Z"ON%PJ;%;S=;OKH5U(1\H"B*EU^O9`
+MD_ZK#UF2Y)E$3'9(07YNUKR$,,#P,SEP1,RF6HJH4L=4E36*!Q"LMI0I"O>E
+M!>TY<UVU30[+C#EY$9E^Z[JJ+KJJ43S"DL]$JZD*,^*4L%96?%U=<EVCS#Z0
+MOM-2)484-`$FARZ1$TX774=0Z^[K3,FUV6=S)]#K_;)<5"K$TW:2R7EOETR.
+M:A4_0)?-=56MKVPY]$TZ=,_O%YF/"A?H#C+GK6PHD2:#E8-*1$T)F-S@7[V[
+MNGKGVZMK?NW^:C@X?9C<&$8FJDU!PF?]ES9AC[>R@66V48S&)MR7-<67M<67
+M=<67]<67#<67@XHO!Q=?#BG)1E7)=4F^JDLR5JT]H`EAZ7]+R7I67OG3<>G8
+M=44)JHNN:A0KD+M\NGMA\F;^RNRGB"KSR\15Z+3<M9,4!:R4HZYZZ<-^-\)\
+MGG1?Y&\K",T1HB*JE(5^8R=U;BEF%I7U+H&4VGU5K;A!0&U$FZYP65U\6:.X
+MQJ?O"Q?K#Q<_P'U94WQ96WQ95WQ97WS94'PY2.6_LZ7MUE:4.5J@O74NV\Z_
+MCNNOB1C,63N*@[2-=OYU7'\K]6I8.&2,@Q)4*H_L,Z768-9%-9F3&QK-*5N-
+M>KU4D_[RCJ9H(65>CYXS&#(&%HS+]J$V,)>I\-L(%NU-+I8X-9-QBD2H]KI2
+M07VIH$'Q2#H5$N&,]'&NL%,LE"E$D6C\D.JB2_39(26"FJHB0=V@P44Z,07'
+MC$"O\$L>.+G33:U/X`LE4UG*S'JP=GCZRT[:TYF)$-%*8WF5[F]*_,JUMI/\
+M8;Q\`EZX/PVY/W7=:Y8C37M;+/E$=Q%^2X\)0\4)0ZZ$A3H(%,H6*)3-?(5&
+M4\@2MSR(UKCMN0M==S+SLZ"C"?T=50M:POT23*EWNM(9+9;X4QCL2A-5ER8*
+M5`[9*5'-3I+:G21U.TG$?(/:.<MZLNNO&;SS7.WB&A?7NKC.Q?4N;G#Q(!</
+M=O$0][.*'NQ^<K7[T=7N9U>['U[M?GJU^_'5[N=7NS-0[<Y!C3L'-=6*!QUT
+M2^<1;26#1)U;))56=%E=?%E3?%E;=%FO+ZVE%+#2'%EP"V1;9R<I'^ZVFZ++
+MFN++VN++NN++^N++AJ++^CHE"\$VJRZN'%\SJ.C:WQSNT'.-(B%KKG#P6_L7
+M]_<^\@)]\ECWJ+R;;G;YV_JBJX:BJT%%5X-5T8:L':CRYZTHT-N(I=?&928"
+MP8P9</)+=Z479G)0+*@N%=24"FI+!1(1EBP2ZB?]BM`\\=<_J/Y?']3\KP]J
+M_]<'OYXC1JN_^D'#__I@T/_Z8+`RJQG%A?X5F7$JN:3^G'^-P\ISM8MK7%SK
+MXCH7U[NXP<6#7#S8Q4.4V836]I]?4==7%B+V\W`N6/A3.;ZA0>E3.6;<<?3H
+M94X9:Y-#85U_3;B=Y^H\^QW95(^'71_6N+C6Q76*^Q<<)_GU@$H[:AHL),EO
+M#=*Z2;)OH^_A/,@LQ0OY7<G-VKVY,UQ*E?J010AQ?;*0+E'`N`O-07;!605I
+MJ(#Z*(0%^=L6<PI_$!95*7.25X0Y.Z\W7X`MHDIS)JD9FN/AC%LN.X1ZEU`?
+MP=$W):WZAEK71=T@U\5@^80.Q)ST%^+Q8J+]O(!ZRN&^UC,"]R5F!#S8H.\L
+ML$GJNO8']?&'(I&`'&PMO@]CH#YCHEO)G&@MQLKQ@^J5^ZO>^F-][IL4LA#,
+MQDE<O#$[8,4(?75%E]75U;0QQNGN"^M.[98F/R]\B\X($BF::CY;X7QN[!==
+M*SG5"<48ZO,TB;Z0(R\"Z7:]3U&,J$[YRB[&*[<LW:Z#P_HB85+&M0:W2$^9
+MBE1%H6I(D2R:T:JJJW;6A<KAH5Z=ISP:O>[+ZN++&I6VP:L%<T_AHMI]44B/
+MHL7,=]/T&;%*'=[F]U#UI7RJ(6;6],PF-RECXDFS^4AB8Q2^I;C3E<Y<J03>
+M+I[2JX/\:[PA67^-))`)NS[4"P]F;ZC2#-_YBTJ_?H>!E.O7Q7*J8N=/_"UP
+M!O_C+AX5*?J`JR,E*?5IKF*QW!]OD?.43LDG:=WR@QM*%=>6"NI*!?6E@IUT
+M#"H5#"X5#"D55%?M)*G>25*SDV2GW%;OE-WJG?);K3.</UO`-G1?(W9LT>SL
+M_$DPQR,).WWRO^XPAT!V_H![`R4R721SLHXYRU]4RN'>2E-$EU!.Z%6:8A:D
+M-!&WH+I44%,JJ"U]7*1$,#N0UEO@)??5E0IT9O1&*LM@N=*O3Q04B_R=:;-S
+M6RKUASN"\9P3DU<R%7^6;O>'FG:6.=EP.HW*EM.B.WTH7WIN#^TLUR_#*7VT
+M[*COE+(E+%\T+)*SGDNRK5^6$BI)6%UR7?-K^>=1XZ)/N,)E[-:EH+;DNJ[D
+MNG[G!^CO\.K=X>*/_K^O*UER'#>B^B*$$MRDX\1$V)>V'?;,R1>%5%JJHE6+
+M)57/M+_>S,26F8_E2U6^!PI\V`@22^+R_L@[?`S_NO\ST-9R4MVB2_65%^:%
+MZ"Z]W$+G+KR=[OS@Z2:GU:?-AV\<=G>:2R;T/7`\K].G;)@+O]3%9*;AUUXS
+MI3`K)`NEQ.KZVAQ=6?>+,.75,P\A^P">DN!%*IZ7CNF+7Z36J,FLUU*$5(38
+M=H)<7;57R([#M,$4(NR0ZI$:D!J1FH`:MGC5!BFX2J6J57*7.4L9MI!C!%E6
+M>AO'+20[/8KS<L)<*QJ:&]4;#XR'N,#SVNS0^8#Y:@F0>]5Y3V6'XJVE7"(^
+M/?)%=2:VXE99?4U263GGX_D#.?>$M8%R*Z1M+?/QM2>>K\2^!OL*Z&N?KWJV
+M'5HF;4>_NY^-]J*TX%T**RXFJU6S%L2/HC@`QX^B^'7\T@K$!4TNFF+SX-;^
+M>+JEHJUL+C"%R>'H<.>PCV]P>'1X<EA:9/$W440W&,017YBBYV7@/`USG]N,
+M3S6IF7'%RQKEU;P88?=M+LJ_:T+ZH[X1$EL#I$'4H-/`1#!H,&HP:;#18&MN
+MJB3L=O-+^-R4','(_,0():.4C%0R6LF(G=\19&.`Y%GR(\=FF8?*_R6/FDW*
+MCLKNE-TK>U#VJ.RIV0.MV(G<=7\XR0NV!F%W_,Y#4VE6RH:<[U^%,)J+V9"S
+MW`&8$9@)F`TP6\_,+RZ>(6`B,!TPH+D#S1UH[D!S!YH[T-R#YAXT]Z"Y!\T]
+M:.Y!<P^:>]#<@^8>-`^@>0#-`V@>0/,`F@?0/,R:TX)*J9/5G&O7@>N6(L[[
+ME^OG[10&S7*S,9`LG&7*.E*)O5CI5PK1*KL#X,N:R:MM^'U4'(I)4#8D`@5(
+M@ZA!M\H[Q^3G=42J6BDFA<B@:%"GD.S9D[%#Q?$Z'%F/'&2:D[=>&$ON5H<F
+M\\:K8EZJR8NULYD<(#)(.S!SK_+',1LM7!;>L_%V/+RJ_W+/Y[8$I)E<QA\&
+MWTX/]OTF^[0/GW*SZB""05["'<K(;AZ;?2V#Z++-+Z2!S'(_WI62_HM?$S'%
+M]5-(,RN/O)BL;@4*:2B\[)\7F'V+)ILWL>?L:=E7MRQDG!TE%=2R6?P4%7!2
+M^7]2!9!]S-7RJ"%M&"TYLLB6BJ=%(ZN?DUDD)T^%8KW6$5'VQ)&LT@[S$NID
+M)N>^;)?]B&PGKU)BY6V+(8\8YG7>`F6+'UMYB;N8I432GA2QLE-$L4MAOM8?
+M\+:29/"FK&1E]=GQA)BM<J1MVLE*TI7/705E=W+!LCFM`-G@)]6^KF"\U.*^
+MF.*]%)<7!=02OMB2O"0'NL7,C>S2MMQEF+82!?6M4+Z3+_77R1MI`<_9.#6!
+MI1J<6Q4_ZY)*>SZR]9KRMVR(SG;.XK1941Z@GQ\Q_Y<6+]ZJDY7CJE&IF&I$
+MJF+PIH7\_Y0;";L3/'Y8,Y0-SGEQ>F;+"NH*R<)H86=A;^%@X6CA9.'&PJV3
+M(;)R$D3^GSSE?*^0KY:A!%G"G7PX2!.2'8]S&X@5\0)@#]QZ[L:^/Q8#\A=)
+MV]J1ZX8A%J\J'R^>C"O>DRCUXSVMX_W'CV)EEW'RT)`1\DS6M;7*#KM?BV-L
+MF<S40?*JY8B-(_K.$[TG!D^,GO!WZ>$N6T<,:T^0)Z(GO-+!*:5HB=WGG3_F
+M%S(F<]SGNR@'=]V39"Y_(B_\7@;98O=5T.[7$'UF#C[O!I]WPV:57#N57DBL
+MD/9MR<SO?\K:6=X_%Z0SUXLX%<@;2,3W8UL&NK`*5/9EIX=<6\PHSJR%K.Y!
+M`86\5,PP!$P$IELU)W$MUB/$>H18CQ#K4<7*<V7I<5XMB4TC,B@:U!G4&S08
+M-!HT&;0Q2`;SLA^WTNM5%(HC#C/VY,//GC0#-"H@/X,,0\!$8#I@>G]+'OS9
+M+)`\^K.%GP_`C,!,P/CX(?/:>)?/HL5L%<_LIS3#DMT;A/(^46%(+IO/GBY#
+MYH8BI")2'=RBR,;[+K-5>MXG*"\`U0SB*BL_;/C#JH6D[R`%R<)H86>ABVJP
+M<+1PLG!CX7;^M#A+/YS_A]UNMM*F`GD=EG,E7O>7EY#?CS4A"<G^=SC\U%:N
+M[.PBEOPJF'>^Y_)]JE]6R2JE^;0O+XO)XDZ?CQ!!)L]G%_(ROQOX*TV<I7*4
+M'WRD,>8"^1--P?N5G8;I'T>-XC2L\GJ.O))#_.6(?QE-R-YGM=:CFM3,V,QN
+M59REE<SKV;BJ=^#BTS+D%TC>TN3L4!R0W/]8_6A=1C/#[C#7W?GIS/M$%,UK
+MLS6,P];B]=KBGI<"7<KB=*XB8O"GK+PFY[WNDH9C'AO,OEG9S!Y$M/RZ]\L3
+MH>S?2D=UW-(+>?9!*_=*+@NL.9>KG$?R-%=IQXI7N'QP0<[;YDJ2B7J`BP>A
+M[BR\))?"X?[NL7N%-0'N+;:D)<WFS&6[/]X6<'IDOCREHWKN7P<?W].CS(2J
+M^2=#TA(9OXX\^=V`WXP;Y#9E@DH\:K84%5@F(4*]7PMY#G7*JY&I1PWDX^7N
+M5A83#3Z@S5*JJ-_O#]WQV.L)*5#7)B$5!:+:)*2B1J0FH(9-I9X?.M^>'SY1
+MSP\O^QGF;"O'I)GU,E%$8#H?0>DDW8T6*,C@XYNI`0FF2[G)_=250`?F>'1U
+M4,%2ZKT/T1E4*4(*[JB37"F,?II6VH],3E=>P]<:KR$66N\7X:7YVN#2?H&E
+M13;^GQO4)NQ^E=JP(S?RB70_?:A$Z?:LL33;B&QIMQT&Y8;;0T@N0Q>]--WY
+M._V^'"8[!K[X5:N/[CZTP*E$U!:H8(KS#*QN6SK`),8T64OYVY8*";?F3^,E
+MWF>."EHD;8:9B'Q^M0:L<=C]<O]^.O[E_?;7]P<$FG3;ENBXN,!U"UR/`FSB
+M-&MR20=\E;HY5'*0YQ<P,#_0EZ(SV5@O'Q>X:97\S<K+2['"[MO[Y2_\[FBI
+MW]BSCJ5^WU_\[_9/+U=VEFCIO[$C0$6IH89*YIW>%9%!T:#.H-Z@P:#1H,F@
+MC4%;+3![0SP=K22M</>;F+]P=HO;%<[%8O##Y/5)07ZKWC3,R5,@:M!IT&LP
+M*-"KRW@1,:]>5I>.&DP:&!5;(VEMD(F/E,2=&E'0EQCA9)338)!11T8>;5RN
+M=?9BHS@:Q='FJ<G4:,1%(RX:<='<+QIQT61>-%HZHZ4S6CI;P$9+9[1T6@MM
+M!W[7_RG]G7%)N$2$ZM\B#^DK.^S2@/[=D.X'\C(A.'NT47;8)7\V=T/6",`)
+MC6&+%QKEK+U&_]$V`<N\JN7J#31%2$6D.J1ZI`:D1J0FH#JXH_BI+F?:H,"%
+M6"-&RS7,QRL?GB5B??0CYZ'#\Z.`C9B<B[SE[2L:A.:PI#+UH,[B""4=.L<_
+MK7,*A^P&))V9PE8]`L"#N1J\7(_[P^'FZ,OKPS'7I^OKZ=627.:.($]$%P]O
+M6KN>WBZ/Y[L+^7G:WY:#N(J`FMU+.D3(7=DO7/G[O\4EE0M@=/\\./KQBEF!
+M5\WDXOTY@+,I._&7(JWFG-O'_<^TRFQ^2NL`SI7$=X8OG[J]9F5(0T/*^W;X
+M=JW1VK9IFV4^X"?(Y,#I)!\CY^*XH!Y/YT%(;ED,09Z(GN@<T4W^BMX3@R=&
+M2^SV\OZ_\9=!S.F*?`A'24Z#H6P1D_92ML!]L0-N80/<!39=O8C#@;K3J\U5
+MBV]ER>8R;W_()98.FFW]Q),U0W&B7CR:W=J*.#FL.#GB:68HSC#Y!\D+4QHI
+M4G9(WIAWQ_O3[=4$?.N'E?7C7WYJF#EOV(BKYE(P/W/:T^>I9@.75L[\>[Y2
+MV7-<%K9W.D/_>#*X5,:&R5[_3WEO-=2_@"H5MN'.X=[AP>'1X<GAC<-;KQJ2
+M09[P$LEK)"^2O$KR,LGK)"^4O-+HE4:O-#JED[LK3>D7=?V2!GES7V])>7MS
+M3+<&AH")P'3`P+VZ`9@1F`F8#3"@N0?-/6CN07,/FGO0W(/F'C3WH+D'S3UH
+M'D#S`)H'T#R`Y@$T#Z!Y`,T#:!Y`\P":1]`\@N81-(^@>03-(V@>0?,(FD?0
+M/(+F"31/H'D"S1-HGKQFG_&IA8'&"5(V0<HF_!6D;(*4;2!E&TC9!E*V@91M
+MH#0VH'GC-6.6;2`1&TC$!A*QA41L(1%;N-<6$K&%1&PA$5O(^"UHWH+F+6BF
+M-8BF-:BF-<BF->BF-0BG-2BG-4BG-6BG-8BG-:HG5$^HGE`]H7I"]83J"=43
+MJB=43Z@^HOJ(ZB.JCZ@^HOJ(ZJ-7W_D^,C7]B/HCIG+I*DPE]L*$W3!A/TS8
+M$1/VQ(1=,6%?3-@9$_;&A-TQ87],V"$3]LB$73)AGTS8*1/VRH3=,F&_3-@Q
+M$_;,A%TS8=],V#D3]LZ$W3-A_TS801/VT(1=-$$?W?D^(-76A>J$G3GYWCS_
+M%E.%G3QA+T_8S1/V\X0=/6%/3]C5$_;U_J58*"PY[.X)^ON9&A8S`]5B#T_8
+MQ1/V\82=/&$O3]C-4R[CX@6PG`/G[+![_TQS(_/7I>:_S8]0<UWQH67(Q^M'
+M<E)9ST*7^!4(NT-ULJ4<E.636?CJM-DAW--*?SYA*\@Z+?DJ#>ECN_V3[VWQ
+M/5:)I]OGD1^U?S879-64);%UD$;987=*GS^:2VZLRL%3H7Q8%Q3$!3V[?OXC
+M?V.K1:/Y:*R0QW;R(G<5W+[$V<6(L^>O<CZH2TZ&TG3Y[&Z8'(X.=P[W#@\.
+MCPY/#F\<WGH](-`K)"^1O$;R(LFK)"^3O$[R0LDKC>M4#XUKMUK?Q^1]JRR5
+M:[/L>>7<[7I_E()\E'W;=J--.BT\FV_9H3/7H&:E)>E\C@;_;]7C7`<(+]G'
+MHZR:2HNF>"2(C3)NG4]"L>;<8N.JG*!2@K37'3[Q0^YPK/<Z5G<[;^^R_[9?
+MY1-K2@3)Y%5EJWQJ20E)!PH65-U1:B"WE:F/Y(U'S@V1&VN7WK<:*1_X;JRP
+MNZ8C-]1.$'VCS\?+]=ZDUEU=<BQ]W@2C@0@R1%KI\;CQ\T,"#B\77J0[__!X
+MJ'^#',O%)RX41\O-7?&ZVOG,%SGBPG+Y\$5+GH^.F//!,7S<C67X,"''\$%'
+M50YWL0W,74P^FH,U-U-D&T@61H;%AUPY0HGM=.YG*HFW1W%>?C^5!1AYT?U3
+M=7JF_2&G(R)KH5S?+[&"\V?:AZ7!_*:R=D1?BBD]:6=IN2&4U9<EL?D0<[F(
+M>PLV?JCGL;+G+NJZ?_M^3PLM%<V_2\N:-,UY9S$Y'!WVO^\='AP>'9XLCO,W
+M1#ZW4HHD'9HG9CHC2_*ZDB_WE[>267(.B[-ETL[@^1758/YDM,3\NI<.FZQ/
+MJJ.Q@AS9(^\+BOM8#^SC0#/#7<.Y^A@\-T9//5[>?CHN]]H5D4'1H,Z@WJ!!
+MW^>6YH+2OAQ+[KZ'M#NG_G(T:#+(7KFU2IUPJYRL=++:R8JGP4(CJ9^_"O:'
+M/#6:#A"6.K+_?BJO+"]OQ_.'L;(O)O:=(`]AJ4OYT,]P+QX:W_,&T.H?[N6^
+M?]0+]D]\[!N#[R_5E5;;=FBG/?@,A]O[4]DV6YRRU[-GSG_LKQ(B>Z*3$]1F
+MBE^87?V1G)`M>M[S)M'Z#..JG'JX:LU5>M!H_G8Y/$IO5T]JKC\I'<T,:A=T
+MD&6;>;)I?I;^.-W.\SMN>4KEWNCUXSUUZK7YU@7992?JN3S*KF6N\+4^3:L5
+M),;[?SUS^.27:<VR*Z'SJCT8+NV83X:[G3Y2([^^'-CG%1OY4&9KI@=CD.5%
+AQ<-AL4)>KE30_(&4[I#+H+Z*SX^/XNG]?[9W/ZV1I@8`
+`
+end
diff --git a/lib/compat/compat21/libg++.so.3.0.gz.uu b/lib/compat/compat21/libg++.so.3.0.gz.uu
new file mode 100644
index 0000000..b378641
--- /dev/null
+++ b/lib/compat/compat21/libg++.so.3.0.gz.uu
@@ -0,0 +1,4253 @@
+begin 644 libg++.so.3.0.gz
+M'XL(".%'0S,"`VQI8F<K*RYS;RXS+C``S#H-<!ME=KO22EX[FY.<Z,"`N3AW
+MYNZ"0VO3<*!R!5E$4I+!SLI8DCNDG-LZ:?!PK4EVXR07.89%G7SYJE9#(/1F
+M*.6F9=IR-Z6%&PYR<XGLY*PX#3E'Y4(""1<@(6MD0`G&5CPBV_=]NY)6_@/N
+MH&UFXMW]]KWWO?>^][\ZROQUDLG:&*:1H?^2CS!,'5/Z%T+GE;&N2/@>E3S=
+M^]#!FP$XOJ=F&</$'V8XAFE0>JH8YH\T>+O3CO:0!XS)7]3R9/QYS<HPRX[%
+MHT]W,Q&UXY*-P0K@,,B750[QFOQD&/Y'U%OAA7+(&?<)HB;S$74)?1:P[Z=N
+MWTN]3H++T24^4YE()(881O/]-"X_'5;/7[0Q5M^3B#+1;0FK1V$!^YZ,KT_<
+M>]_WA@_J_`LF_C=]"``RCT-"+"T[]WT=5I6HJZ+/MN\K<!O'5+*'B&3(E]>%
+M<X^`9%0F_'/R-W[W'[+Z\Y`O![LYE:3%/;C#YF[);^9@B>V/YAC)UI3,1!*K
+MAU@F-B%S<&UL3,<F))O[LN.)P4?2TO4HVY2>E%UH2)FJ[*M0!B,96R*A##:N
+MWE6=>56).AF)8-VD1`5&YM'A3!4\U;DO]^90+KY>U<4C\A5%>^(#(CL5+1FM
+MZJ[J9MLF3V;L";ACVD3UXA5-PW^2'SYHQOGS^7%^,1O.[P,.>:_)`AR7^L/9
+M8!:4P\BSP5QX'V"<19C@;#`'RV%NF@WF'\MA*F>#^4$YS/E/9H&)$!B^"#,P
+M&\P?E,/\PVPPCG*8;;/!9,;*8$(F&).Q_A*@&I,XQ*/7\B]K\._2OZ-CDR=:
+M<52(K[R5%;47>`!4*\"FT0`Z@G++LK%DGT!\Q%+G715+[IS$4;[_3D9RP1K<
+M[J[890F@*.^%-?G#(0N##L?7CQNV5/1W+A(&%XE-["0VW)!0KK!RQ4LLO,U\
+M#4T>UU#VAY,:>(<[%P4?S;,YE,J,`GUBE^,E4@5Z16DF,S:0M\:QW^<"/W<:
+MHK<1"R2BSX!/4?@"W,U%.#/,/P%,W.<4#:"%9<1T>F>(>3O!VRO.G#RE#A],
+MG/K@S.AOSO:?6]D_[I'ML/C!\$$T,J`N>20IV2=?/Z6^>?&4FK$F3@U/#+*2
+MY>3P\2FIXM3PR<.9]Q-G3M$S`AWA%B.(\%0U0'?(EV<,.C(7&Y8A%N0A%N1I
+M+(#W%`[T1*A:'<\-`%G>\=QPYD-8,^G??/[OZ<$J*I`8TI3.6/!56*DE$=1;
+M"TLV6+(FR%J=OJ9<R5,X*PYS6*DO`A9QOZTO3:8L<".YF]*`(>G0-?HK[!4&
+M5,<*]E]9Z5I<%1N67+A9[+8Z#HB-[)$V[%FAC4`@GDP1821[6'T=;+1D0^7\
+MVX!_$K^D91!CE*0`.D/-'&)QD$.OX18G;LJ_7`&@'SU3VA[4&BSQ3H":>8K'
+MX^HB_^2VKG1K:`0V*7!2SD=T=#8]"K/HT3F;'EW_&WI\-#.W'G^A$OZ=5)7?
+MI*KDRU7YG3GUZ"IIR:0[9^E6^!3=-:O&&7YKQAD6-^MF(%NHR?=HVB9!C5=_
+M3!_X:<>9:B8!BYGC^*+.1&.R_\XZR=9_9Z5L^0^6.&0@DP'_Z+]SA[RUNT-=
+M"60A8Q[BPFH3W,:5?E)J^$5809?(9BQXI'W(LXC+</"7&?(L9I`SY2%5!Y/R
+MT-TWI#S..G@0JNF:RTXO1!3@W!4/L&*;>@XL9O1#W5\#)%A.)1*-:>!NIU8G
+MV>&OP9],[JMDR_,LI'3[VLP;A->=V@ZY=2VZTB`[XWZN/K_L$+H`E8XSHCXS
+M2E4TQ-W!@#"]HT5AND;+A0%&(F'U/EB-):7>S`/=[>IJ>!#5VXDI@YS5H-Q8
+M4JX8\H*HM@1<F"$OR&I)>759O8:L7B*K5Y?5J\OJ-62M@5V`+:HVK5$]J9+=
+MY$KZW+]J$3>G3=ST;LD>OS7#'J>9Q;^I)K-X3"TS"]=\)HDF$_/:PV90X0JU
+MJ,*EZI=H#Z]>L#&9C8D$G,/`!7(.+USX8L\A7#B%M@MSGT)Y?OR7<SH+(0$K
+MI'Q'S6);4'WX@BE/FLYLVSE:Z:$4EH7\RRX]6NSY+L$31;RGT;AI$7"P'3_8
+M@<1VU-.!@^N0N`X'.Y'8B8-=2.S"P8U(W(B##R#Q`5/I0/>:0?[S$<N5:)&2
+MU-.IRT#OU^GW)7&>?8>&]&XFK#+$&G4-^,64_P&J=G^G?FG7+QWZ91TIHE`6
+M]KKWOL)>I?J/D`SQA&OE-FJ"HD'6*P;;U&7O&HHMU^O2=[YPO>(]MQE8P1XD
+M]I3YX.^DXP*]7*$WHKJM-=W73:NO[GJ[I)/E,W7RU?.SZF3AVU^"3I:;=8*#
+M$A(E'-R*Q*U?M'[*:1=U98Y_;WT)\JV8*=^T>N`+DZW,UTAM:KZ:Y/2=U;M#
+M65"N:'(%=`,>TD>(4,=TL]U:M^8XL*:.'0CBMGHMC8ZCP<:D,J7)=N6RYG@L
+M"=E10)-HRO'B8(8'O)>(\Y7'C,*>Y3WZL=\0HW/%TI*@3+'2DM%!FHA)K),%
+MJ!(:'FR_;EL'`NI19^;&!*GLMHB.`WO_'L"L(;X-[WV2Q-4T&D*3`]H25A:J
+MHT[("(UI:*NU';S,0^;2-M.D+=\/#5:4QY%U7G2"@B-Y'$5S.)IS1YT[(3GF
+MW"U.N0K+XVY9V*(G_5L(QD[2=#@.//%T8=<G_MF\*TF(631E;6Y?'.S(+"S(
+MOT]7@JE_5\9XD^SI-W6'@]9*AGZU#87RZI*W"@$.A_+@>)!R4EX]S'GU,.?5
+MPYQ7#W->&N:*00RR"WLE'&E3UP(==$4YY`0R>$T=:LE!?G7+N2WV_CNJ'(_#
+M@4E6?V8,75QV&:U9-^%E64F@#-@)`[#U=@%MY]`F'HW$UX\5?$X9<YGX7T3X
+MC_(3`4"VX\#R#)?``1X-$;M9"UMFEUV,#3O^EJC*C[(XE$6A,=*O^K*,6Q[;
+M4DDX>6Q@5TNV/YIE),Z?.9^`]=X*)(\1(XJ'64"(K])02Y[NX8@@7TY=?Y:4
+M%9`J<X3-B(`"T)^-H;4\&FR(U*+C`Y>7H$@[6ML!L@V@M>NT0"?%YG&@/F,G
+MO`4X=];QR!^#WG2RY,5"X\PR%>2]8S_4YV=+YP:G1%7$8Z]!PRLHVSL9B?50
+MO<SRGD,#=,E&EJP`#\P<UG%638^APZ<+/0L.@W$_3(R;S8KX86K;(^@RP9WP
+M`[4*UE]/9D>LGZ,M>%E.+N7_`CTGR9E'WS3E3&)/GYXVL;)"!T=]$D0>U-JS
+ML9],'ZX!;^UFXPGRT":&U5$@35*LF8\2&Y?>T-DH$%/Z)$;ZFM+7PT@UV-]#
+M8XOC@+?1ZN\1L5=ODHJ,@L.%U1^]21HE(X%3^ZLWB?FH07]++9)/IZ`C)UY3
+MM,=(/3E+4GP*:`3`=/WA<#VQ+1H&./?(YJ4`,=%,SRD(1T?(A;G^[5#G5P!%
+MEHX,H:NOPM'30Q55`10]34BN[@&'PG(.8-UAOG=A6/WP#+5*-)BI=+RX""**
+M%N!0:!Q"I'0_9:+.'3HMKVH(UJ+0Z?B*$.$UK/XG8*%!V@.<!I:TWEKPP3&U
+M^XQ>1K,X-,:>"+=%U/XSQ"O'K*'3@`Y>O3LTCEM.[ZIN1BVGE>AXE2/VE^38
+MHGD0P-I7BZ)G<;@8Y6!_]L'VZFT=.'2Z(706!==![(Z.:S(72_<9I3;@:?Y.
+M&NL`.UO0BCVH?DR,"59D'O5!1W@6M7*@#-3'T_#F_I5D=>RO)E%BQ.0OD$C$
+M6F5K)[N%]:*1.7VD`=KO[01HU6RYX?E3!;=0^CH9N3*L7OY$TT!;\`@X`933
+M!SF6)HT>KAW[:0SR0RB@"S;L)[[G%Y8-HA%WJL\"*;6U%L()]N4I`(];E^N\
+MM/)PHFP.^<9U4F'U$V)=+7G4"D*/$Z%;<@B@2@/9PORLR*_EE![/:>(RXOG:
+M-WZ[>&X48&B3A+;WI+Q=^LN-Y-+-Q%]X[,8I+=['1L)MZOHWZ$0=R)NBN.<-
+M/8IOHE%\.^RYE:"28\J:?+7(>N`D95W9WL70W-])9E=>JM,U5*=K^+CR.&SJ
+M'I`6E\4U.,.N3).R?2LXB1Y!ZTVX]127P]Z-`!;?0]A>=AP=84>,R5VA%NTJ
+MZ+/.?/ZOT?R"?61@O5K):5$;W2$5V$H<T]`"R1(Y=A"DIHXO0)(XJWI>)]7,
+M6=0KT"3!X5`.1?A13(H+0*>1(K*Q(=(%/NH>V;D"]W:A0?82"F5A&5S01.KC
+M4R5264IJ#$AE[DHT^,9CR3[;2R9>7'844BE'YTP47C!14"F%<T#!ZAN/KW_5
+M7!LX3;*_>(+:OF'78:K',(>.&W8=7D[F5;S[^.9*LB)[,K[$--CXSRE+`9:,
+M;P>EIH)=WP#<@">C/DBA>>0WQ47(*X#GV&\9?8;H2>DC9YKR4VUE[H?G+D9:
+MH&WI4M\[28.=MJ4'AR6H@GQ9Y.^"A5@22L%=OASXI&$+WR.^12(12<MLN+VZ
+MM0-BR6Y?KCCC/C*97H/"Z[`ORXX@_T82A/JZL']CP1/!ZS?KVQ68'@>F1]^Y
+MHFE`.[[^7*$V*<W_?VUCU%L!!]Y7E<^G2_H-_UJ/+?;^K8N@]@"3OU'9RA'Y
+M>CC5JV](3S:6E)S&U!G;H6??^YJ>\O2D5$;3,H/FLA+-#UXKH^G0I]V4Y%UF
+MDC?TS.#UV5>GT[V]1'=O.=VE0#2N^!NF-$C/51H)E[#)A&=A)SG[/S7O1'U/
+M*+N6Q]^;8=_=+<Y=$"];^%0SIX_S^K<#$]?UKUED:4J.OD"6C.F%83909RK;
+M@3L'MN!5?,,J#AVF=@%&L4#;Q*GG3Y0Q+%%TW`AVTL<W]'$Q;:<KK([H0.#S
+MTCWZ>L2QWY<7M2V<^A-X!]8!@@&Z#:7@)>V.Q`B\A7I"9`]#.=%.R@D!ZB22
+M_9HY=\X1NX>H(SK.2(_3.8MZ;_D'#+,-W?K?>C<$=/>0^(R<:!5'8M8@5P;G
+M,,&)\\!=2)?@[IX'[H`);M4\<$^8X%;.`_=7)CC/3#BB>Y^@Y*JD:W?R2HZ7
+M%F26)I2<4UJ<N2:QCXQM,XL3^\BX+K,@L8\0R%@336G<+-3_7>4(:A;08<-^
+M^`V._2%A`Q*=IKF.XV<A`8FNTLR!//*FN!\2*D6A['DRO534;=%D_\=U^_<)
+M8/#:=S`IB<OG.B78OL\!V_8Y8+_YJ;`Z_[C%275<DAE47XV<9'8O<F;8N=9_
+M)QK,'-_C_F*$E"',5Z"=H'\+'\[*YC\`4_AN%5,X@)+Y2GK-V-FD/-:4+,X:
+MR_O`JA&C#J]!<C[ERY'EV`2DHE9.+Y.AFW;\S8]IJ!"4@2K4,@XU4MSU,2EY
+MVM2?I&WZKP0X6FI[*0^0)904")A7!J`R&W/[<CNNP_(8O@I=3?)@A(.WRA`/
+MK:(G\W8B03%Y3<ZK3U&+SWG<OO$=W\`MV;AK@.0@.9M:.:1/:<EG'$89Y`E(
+M]%UH]@$*/<C1KS-$#M1:0TI$T*V<CZ\\QA<Z0;.NKOZ5K?`]]WW(1$J2F_F]
+M\J-C19AATW?JL#YEP9Z:IC0$,"L6N:9A]XDHA^_.@C_!ID9>F0>.+\!-.V_3
+MH<C'"L6S>U+Z`;[*](WJ:OJ-JGK&-RI<`6!T($TGW!6D5__\,VYL?VB5P/23
+M7I)B3.\/33P>?\7$H_1_P:.9N7+>;GEEWKE?AWGNA\1V'.Q`HC&6^VRS\AE(
+MN5GJ\N>.ZG/_YG80^6JB#=9Q($'G`Z"0?GT^4*JEBWB]!;R.`IYE/KQ9YH&W
+M'#7/$'81:U(Z]-:<A/%P>TR3;2C<D;&B/F@L75##F919%CO?^R^=E*ZTL#CA
+M7\=*M^'6]MBP?#T1:/K``YHD-##79U3`MDBWX]8.P*[#?I-DEXJ2S4N`3A8"
+MQXJ3A3)>[S!XI>1KYR,/!8=>PYE+#E-=6/K]QQ'3&5X[QQE2O@@U41U[Q6:.
+MS^4]YE-'*']DJ"G?`5Q"I"):G(=1'X2R/&66<.JDG+JTD<QJ'.Z(I>>5<1!O
+M<KDWU?16[_8)-Y"??8EMZ@:PB\Q"6-AEITN:US5'3_G1\&>3&P*;6^1[0?)G
+MCY)Q")G/.%Y<I'DX-%*F!W-MNA>(&R.?E&_<2N<T-0SDG&@-BD)Z&9\<HE_;
+M?X].>MJIH!'*P6[*P>4@?E2?'%-!H87,5$$L,;(7Q;>4\#L*^)8Y\<<-_'$#
+MWRWGY(4XFL-K0?,U&3_)43E&^@:9&K4"(_KW6'HHP3JB]R"9J_ORRB$7F5U#
+ME5H!24US/$Y^0%:'0::UL'TYUE01"[*!/M#.HJE"93M#9W]VF.J,MM`%G;FH
+MSES_#W7F@A9;UUE=26>&Z-^F"EMN*,PY4V'7EQ161)DJHLRFK5E\[>:4/G\(
+MZ`8<,!GP5)F?#$&U<PWX$02:VPAGGN^2=0YV(C]B+$PFU^HA)6!RMW(R`XU)
+MB%DV]T5]/K\87(92/*)3A+8^T91L2I-:1^9([[./G6^FLWF(^A_T38+XJ4XH
+MJM\?GOE[*O+;L*9T_QV,]/6!MSG'?CL[Z$?''WH+WF8E%1T>4&N:1M!@TQ'R
+M8P@R935JE_M]_,^VW?I48>Y'1L@CZ$C3R/3?BTVO87&0UQN$3WD7+A;*6';1
+M6AGU\(6*J#R/??^7\^;Q=;/F\0V0DS<4/[!]SGP^'7FN;]TATDT@;V>I_YGP
+MT)FDQYB/>LA`Y?$D#;-%G1@PH@$C<K&T]%6Z6`&(PP<I'KG`U?59^HVYUCV<
+M<I8US^BXXZKI_?1O&+9#NK/(0K<E'J@3U1]5DY_IQ@,UHKH7;HW88H^HCPV5
+M?OTTYSF3J;T(:G5"1XF#+N@B<;`&B34X6(O$6ARL0V(=!#\DUL]V+E7T7`S5
+MZWLH6WF&Z):G:J$Z,LDJ%/6K)&M,]W4E6Q0%JY.,LLW/E.@"G6CAS,BLN4B;
+MC%3IOEX*0N>E%A,-9X,H%.;CIKU+]=^@/E+V"0T62+[;6*;X#=YP`7(L5LN,
+M^L_`\[9C!I*K7`'(9#YARJ>EHULSJ-<\_G:MA]<:U0LDTVM;7&2A48V1/`$!
+M0G]R"`S3E#1_DS'ZE,9A++K<86YS%?8+5OO_\/;\X4U56>8E(4WAT3PPM)%6
+M+(B[V^VJX+I"YE-L69.R[!322A)F='?T&XE2'09*TX)CBA@*?7T&`H@B@K]!
+MF?4'*MK146CK;@ON/Z7N('4H@XJ[KQ9G"C(0,$/VG/M^_TBB_\SW\9'DO7/.
+M/>?<<\X]]]YS;[T]KBW=ZPXWV=B0771,K;W\KEO._5N<T<GA$+\/%[[];A;_
+M,:S?TU=#TGAU3ADFI3,Q.KZ:Z+U:T7NUW=O74LBF*BFR_LRMH&TS"52A"&5'
+M&+:G<@)6SE+]BFTH\]]N2=>B4D%G[1EQXJ:+K27=4JV$2?]ZNV/CZNIY7,(?
+MF09C&$*,%2'&"/L>`--:`#!I;9]H]X??ZB(N%5]#\&MD_!H[V\N%:5L)>>,4
+MW]C@.=H>-8J#HA&GLH#UI2"[NG;M)4O,8FD=\SY^5,`@/CZ9S-2F%W0X(%%L
+MI^:O/LL%4Y5!.GHT,TMIIE`DAGN\I)V`:1M4%\;2A+T690B$^3NL9-9O<[$+
+M[4"^$CYI:4/93.8#!X7\MI70]LNT_=AWQ>3Q./$QZ7=XWDT,CNH'L2$E@6=!
+MNC*8:OH[C9Q4,#5_U5=)+I;N*&BG:MA8NGK^ZC,CGP"-S,U<B+:9TJ[H#V1_
+M!SJP^6@0F+PM%-_:!9XJBQ1$K1RDCPX!6HB_&=TY1MOFX+IV+%T)GRKE&/*W
+M%PX(+C,'N#>V6>F`_E4:U;PC^U\^VK7Q?:"TMI7A(?EK';?61_<7X.H.V*B/
+M!G=G*D&3OI0-#V?<S#_8C:7F6/-V.%K`_V\7+JCGH%\!@UD1^[$MQ$!_4T<$
+M:NRG%7V06WH_74DG_V5^A[6=\@;/-?X9A*9::<CTB.B9:!J7PEN9A#V&HE8%
+MX(WX';3$D.4@0&!RU%*L_Q"3'7?B%F)X$"6(\]-UF15./OX=+H-C(6*\V\/6
+MIIKN@7A%7>9J4S#BM&5:I\SH\@89"%P^ADIAX,+LJY0+,M2E$3>N9WO/-CN\
+M0=JU%5]8V;,(3Z^$1XSXB+J$NX-U=JX0R(.Z7L(PM<*-BKB(I1?)MO.N=:\`
+M8](^Y71!;Y#$31+W7_RD!@&>B?;E!GL/>H"[LES<X;O42H4Y&[BN*7=.VP1#
+MVU)N$:@/\7]KMY!S.,V+AP.D:D55\Z'><Y_R`;'!#O]=N$SC:MN$VO8OXF:+
+M^ZG^Z9)_0+XY":*ZXU(F`YE[LSO$?V3#-G!8(2,FQEB(26D=7\K>+>YQ^9W>
+MGI57*CH2?,AUP#*\&YPGJ</U^M)1FNP\#:_'UTF3&`4P+;=K\6CP'&D_6.0?
+MER[E#:BS'PHE)[@#C+O!PZ4F;;,]QC@)O"_1\0YMC1ITQ?I.$V1:0&9]/-8N
+M+`0>>(F'91(/HX2'TV1'FF<7.(<_N)S)?"]>HA70'\TIP1D68DRN/261=TGD
+M3P'YD3D&_9PTT<]Q"7G@`Q'Y).'M..$MC;R57T9;ZE=L23V_&GB/C&^1^)J[
+MJ.AXH=N>)-T&_"[B9H3"_,X+A%NRW%$PLVL8-WZE>J/I@ES@0Y,;A(=C\"&.
+M@S#PA"C!H&L48W/@U*_&[:WQN#9T``LS!L`6FASQ-7=;FDB!F&M=.R8[&-Y*
+MN)"2/8V%3&"BP$F?7ZAJ#[O%-*=Q3*40_RH=$*N."5`-5(B_%0Q?&3<"XK@!
+MV1#BL6$W&V;8&@_;"N.WNZ.6;G=FX%-<9QE.2GQHQP[@M_E>:-ML/`);NU9Z
+MY11?V=`6I*:&+1FR9YH5/UI(>!/\Q,WB/P;[<:%G^+](/XZ:U(>/_XU<I('G
+MV*Z7MID/O"]M,X.(?7ZW4%W$"!]D$7;D'Y))"3H)T'U^6G@K+.(*BF9;W6PK
+MP[9Z-.NTVOV'CDYAZA%>Q$UD@^GZ,+_YSZ0;Q+JO\'1REE"H[8'I4K%4)#0&
+M7Q4)ST<<A(2['C<1$!]'4WRS*-.((Q1_A#P[1QZ0G88N\F`T_I^>>,Q--;D;
+MQ\*GM<F-"2@7/3=21-I,"?J-C@HK#F?9BU20GE#+]/I.XWFOZ#GYN;>6>;@@
+M6H#!6R@]+,?WH^KW:X3W0FEBDQUH4(_$3ENB]V/E3P&,VV*\"SNY^6Y2YQ1-
+M@ZMZ#S5/00A,YBJP^*($GL-`[>UO=/#CP0N3DD8*4"-.15>N;3VN=P?J\:PF
+M;P<;4-<UGLRV;G+I'6GIF+U8"5-_7*)T;1R43%IG=Y4.R$Q::;(J^XW0;P8;
+M!IB^V%B(7L?.$0!URJ:&J^CA?.D+QS1IF_8]Y%XIS%&SYS'D?8C?`9Z<,_>C
+M^D@]%&TK@G!G[AMG]DN^D8DR(7[3MYE,`(38\"T1`AKIOJRJDE7/+SH!DU_9
+M26H8#/K=L5^>:EO"_#?OXM(\6<>HP?*B"%?+1-B%=[$MBW!'!9QX,?L01"L[
+M"8)LMVUL7PVI/#KO8R:['A=3@+HP/SU-J@7.U]S%-!6&^<$SI-8*?MJ;BAIL
+M#58\XA'F6P$*BZ!D>57U#Z*X`C/^0"3>>I<5R[8V"J1PX&?B/6[OC4UX;I&;
+M&.]9[+TQ>H'S+V:M9'H9XC\](W0P6L.+[YJOT>]XF[0#T<2%Y5`N_E$`9!UB
+MD.$<K-\NA6F<2-*)4#D;\O3YRX2X0LX\<R'(-DD5'DVQ_NFZO5R26^+J4HP&
+M7YGKP5U!!]OH(5.Y<>)43JIALU)=.+`\1-M^Q,92AOD@A("*7G84@5+4873I
+M-'2>M\7>,I8]9".UJ$]BFN:TU:;(W!5/@:9MP11"A>V-(E2_D/C9*B$).815
+M?A#9H4^!P;#3.]?>,H&KMS_RQ67HY_A)JK`'I]U8Y#"JKLF+SP;6DIP%/J,7
+MXUTG#>>_WI+L-<1_C*<GNF<,)*H]T'7>WJ:"1'6YMU<\_E3`']V/QIFH\WA7
+M>&`TG@@=>0E4;U5.N;VZ7[/.(^@T2MRQB`O8CWPMVR29)*3P3*5M`LG;G>*D
+MW8;S^IYFW/+E'"#@D:]M#+>*MLUF(1-N5`Y=PJ0]-5*!_>'(N2X#\PIH*B6K
+M1>CK,I4*YKPI;EK8N0GB,@#T&Y8L$Y;$!Z=,YO1>WRE@%.8`E!FCHQ0I<KZ&
+M(V<;!3J5,!_WI?M\O+B+00;%&Y,<I5ZK`AU4V05(H%SG),2YY;1M!AL]AZM'
+M01Y"NRW&L['3;*HJP$??QNWT4V12E0KP4]XFM:1D=YVWM$Z$`&G#MWPF>B[`
+M6X@KG>)BIWOML^`;S<[A?*<22XXIL7WMZ7[@2Z6BTGV2E3180XG:G6QB!MA*
+M';_H.[':R%L0G97P;8<D;!?$-SRRY>2"IS/1[2'<*K.U(;A<H1/B=[Y%LL>1
+M5=!/#50X\<Y-\#[$CQ'(@6[;9F.A:=LM\']+48A?)\)C#'&]:\F0UU@I]#>)
+MV$XNN,\;W-]RA1#5PGSGF\)E`N\GD^W6C&_?R)O)!FNB#9L(\'.$B2$\\.T,
+M\#/@5V+W='ASI^K,3*5/7!MT'?0Y70>#=(6X!N@Z`+\/*+^%I2/H[7'@SV3I
+M5#H'\/W>1P`@`A`1`'%*(*KW'4$GI(>SL^(/^IR#/OK8$3SN[&LJ/C%(OCR2
+MIB#&SQR`T$'/'2D<.C9TC`S?RAKED,\YY&-^.)YR_O]UN<ZA^DW5'H(P;BEV
+M\^5K:#<TR-$>3"?\5NE(^TW[<)UAQ-Y+E5<O:#N_YD)',-T^H;>:$J*'O&<@
+M\#KXQV,"AT))F77PI&BG@SG>1;`8Z6!_I)MWX?,+GREKKFU=,>N%8TJ=/^2'
+M$XE6VP9:QTG'O9.X02ZU/_2YJ*&JIG*-MHB"@#Y#]F5(SHEZFSD@*$VLB7I#
+MW&L'6L<.B<\[?,Z;*'&Y78K5Y)=Q__=5:>R'V=%G;Z"KI]G44Q=B:;;;]<89
+M',=&M778M31AYY,OV".%3NUS\,[,)SU3&4$7*L"V6J=JX\&L?K+X5:6P[%ZR
+MAV(G2_A;[Q9_0*1:@=5>[')<Q>=6N-D`PR['57QN11D;\+#+RU1CN[B8/9:%
+MQ-7)-=+L/((XG^$:W>P\@CC?PS66L?,04=YG`K1!_OARY]!B1KN6V_(?A+TA
+M'SWD<P\>YFK+9#:A"8G)H<6`Z9$HJ-9A$;5*V8>"[V)9%L@SCU::E-][U-\E
+M6`\[KTQ?"W'BU^):NQLRD$!]YF;^NM=).!OD3WP.0^10V73^"O+$.7CR^`*/
+M^"CUFNH@A%E_K/]UEOZX_Z_9'\K]#WO),"KHGPN6<7'"5+6=G<#%[Q>^BB%'
+M\-6Q@X>'ZISD[!A\#AX67PJ.A0<4AH[A_N?0X-!/F*%JYO@]SJ&?>"`1^KY]
+M-E3%'+\;>UOR>WB@@F4D6(:=Y];"*CJ>MI?T'?39:K!^Z)SC?J>J4U3[8LJ>
+M5@0R@HBPLY;GN<75:5'O25DBD*9)^;G*;RWQ+LW>%>!5657QI;/*(==DQE<Y
+M-"0D'`:@[$#'9M7UVVVO"&:T]4%2+"K7K"GK?Z_(=9`S&BS\NFL!S)&E'OKL
+MR\*YW4Q#)H-S%?[U:5IHG0WWO"S29@(!`2&F1]#`;Y'@:5=GP%%?KQ(K`,A5
+MTPR\:<:C.P1T+&7Q91JH!BKARR">4\8[)^&I`O!5+\MGM>*H)*^C:2Q8Q,&]
+MQ(N5[/?UO;H['HQ]#Y\.^'28[FE'V'D`M-QA]*VG]XR!N1M-8;VCD_?O59T!
+M5]ALWJ/T$[!W_)H<_31_C[J?`-HQ-6<_3=Z37>^`?:@\M]Y_O]M$[X"7+#?H
+M74':LUODD1A&B&^YP6+1VH6FC19M&T+/AOCJ&^22/YU=^W=+=T5Q8UV=5(`]
+M!/($ZD)\D:8A#<[$W1H]:-1P8XC_G^LU+&IQC[XD'^B/,IP5?#_`6;%)CB+?
+M*?P.2EE(.DXMI\H6-[\D,QV#QN<Z`LC\7,(#%>`<A)*#4)K%CT%*!=G.ZOE?
+M$L\N,43%:HZ`B\/35%SH=3U.1E6K6T=A@TCAG(D??_RB?/`<=*&2WR`2$)JC
+M9D6GC[4OYM*'J],/#XKA0^JD6?SH5*U2-'S=^*)&)V;<[)NJZ1Z#'?[I!3/=
+MF%&*3%4K2%O_3HCH#05YPK'HNJG:OE'=?R;C&1J4D$?+#?RKY'^!7/TA^)R(
+M<+!<;X\:>3//F\G;D,%$9UVYQ@3T]Q\]+_0=&$&0X6+N;#ZAL^H+V@XTY,O+
+MGI?R92";TT6X`O*]@'RO=6=F\D]/Q9U$-TMI<FJ5_S^O^+`;%93+D1=,U=FM
+M1F]]SZE(=?@84S?244SGU&?T.=D7:HD^<_F53JDOE*N5:M#IY.=RZ=3@9D;%
+MSBW7*U;+^WO/*GXL*#8?QZ-7&_Q8RW-$35*MX'R4GQ`IFZQW3GQ6[#0<L?6N
+M2>O[_^KL<>OP,R)SV%&FODKKN+)<G2-N/?2,Z(2"[LP">M>4W'%KUC-9[!%<
+M62=8=(K*#+7YWRXD0AOUHZ8@!9;KIV37S]Y=9.4@BW[4JA&HS>)/7I5#/S_=
+M)<9%H]-*W#QW56[]E.SZ'O[:D*D#4L&KLNEG8*?`!\GX<OJGQ%;A5=I8K])1
+MV\Y<.C(XI:2HSC)]_%3%_YT:/67E:F69R9B@8NWKIX5X85"6"<4PT+M&I#=J
+MPM,S2,O<X21V3I7F&-/^7<8W]S.)R+.E>IE4\0]IJ)U+0FHHS17CO]R1W:<$
+M4_G[TJPYP)X=<OQ2.Q+TJ#7`]N/W>OZ:*S6)MP8_LB-KKJHE<L*3,_>?LD/)
+MP[6(NSW&N9I6_J<,.;F6PL\]F@F`UKYW/Z7.#WY+YJ=SL@65,%^BIO4S/.YH
+MM,OZI^2P*](SQI9:6DOW8(E$=U1%5Z%Y>;O<3SZ&XPC9H@9M7*CC5Y>H=26<
+MQ=3HJG.[)&T'<$<FFJRC/2BI31N!*TO4>D.6=/%SZ79U+B#I+E?`"?-'B_4*
+M-.AOXG8YY!":>`V.-W_H"?,/%0O`E+!%I=!7$7_G2;4B19X;,F:L5A9GZ6N%
+MVGTRM8Y:19^U.?+QHY/T2M7R-^E)>1T@*'>T-B:%Z_CD)`-K1CU^_$1>.R3^
+M%N:K)QFL3W_^]0E9;:*4,!?E/[S5:&^J^;\ISN<Y<8I-<7XQ)Q?.%]O,<"[F
+MQ'E]FUG<@_[YJ4<7:U7YSS8E1@'D#$_NL?Q?MQGB$F!=*LD:BR=ORS[OOYGO
+M+LDV'_OB<?$<?R#`5]Z2?7QY7P5W9PZX+2JX;W/`-:C@N%M5<$N7-=_SX-)[
+MRY<NNW?)*OWYO\=E^\;\RMO7.#X1?^L!<J_`QB*+)5%CMSFTM=DR[L6MV7'K
+M\^!^F`.W&$\N.UP';B^P9UO':!71';AZ&E50?S]>0*VR9UE+\4F(T&AB54;7
+MC'K]K70K2:^%<S7$*"$/J.?K)BNU^<K\?PN!5:7@!#9A!OO1%CD_,`QK@%7'
+MAR?+Q>)J/$[$,QO:%>3),K)@_S+ZCP46`2CA2VN7;:(T?Q!M_=]2^C9+MNAU
+M@-=_+H`$Y`+>BFR\_WNS7@\(OSXK?.?F[+IHL-3Q/]9@:GG[U>8\^D`"X[0$
+M=#J9O5E<D=(N8U@$9K!N7T$WZ.:[I"*KA$)ZO<_0IC+_3YK)"]A*![(ZD37X
+M&Y)99=80N=VH-[7<52+K%C-3V`]VGTWF@J1D1'JLC0J6KH\_V92=9TK%<]*3
+MO:\W;3+5FQJ]SI-#;PLWJ?J*4O55J2>7?7@VF=H')=O'\1*#?2BAYK.-TKI!
+MVT"LD#UZX02I92`\L[T51[4S;-#A?/`V[ZBTD6-VQGC#1D4.5^=\.R80U*%`
+M'8RO4XMSR;_13'^NSCJ@4.V@^@/UF9G\'R9EM5O7QJQ]J".R8U(V7__OA!)+
+M=+S_Q6WD7=T/R83*7HU9'*@ND]08K?;^CX1XKZQQ91@P?P>8KLZ0P]NO4[Q&
+M_H2\Q)%MH2[JY']TI<7D/OM/'I.G_SG7O('`18_)>+'U,6$JJW4X!&\L-6OO
+MYT9X(44"C.T>\SM!;@`<99Z+D,L\%K/])L=C4DY$-BAAQ$ULTMXUI.S_<'*]
+MR*T3\`X@2;\F_OV&`CM!@-V6%3:NP'[%$-AGL\*&%=CWF!S^<8,"MQG@3'U@
+MG`+S"Z'=9[*V^X<.&3;!Y)'];07V'B:/[!L4V'_*)_N="FQA+MG_48'[W)5%
+M=I<"\Z$KC^Q?LC+L7XKRR-ZIP!XIRB,[I\#N+LHC^\\4V-5%.62?I<#5%661
+M_0H%YKJB/++_7SO"8EDKORV?[+]58)?FDWV3`GMK-CX?4&"NS,?G;0KL-^/S
+MZ/(*!;9[?`Y=CFQ0_".?[`<5V.I\LF]58"?EZ_?[%-CA7+S>IL"A3*;Z+%5@
+M=HW/H\\_K9=A!\?GD?TC!?:U\7ED?U*!79NOGQY08(.Y9/]G!>ZZ;+)?K<`4
+M9I%=N[;QQS8A08C16-[+19FV\P\7X8X0P_G<U*BWOUFIXBWFXGCY'4M%R&5S
+M\+_#8ADI8KT1=H4]P@7=$;;.@7_%1EK\N*.I<>FR^_1W7?T*FXP_3*[;IQ-;
+M&Q^ZE*GGE.MNM'4T]4M61)>L;%IR;_F#2Y;=UW1_^2^C3>6_C)0WWK/LOB4F
+MYPRGM)&U;"]9J,$[8H4Z<Q\C7$5:0?Z$$_XMG3(\ASH7<H-'O):F@@[KW'5=
+MT8LP/%9A'3+K8[@8XXVY8S8V1N[[((>_:IV0,%F]/G>K4&4=!!W%NXH.X*D9
+M;^]*9S))G??V-EZ*]Z;67KZ\QF)I+N6VHJ")^#L@92`11V%A;"=7.L!<&RPU
+MLK;W4B;"+K>2JS+PQB1@GXVE([@G6)N.L%Y2ZH!7--2FV%YO-SE;B(=7N%BJ
+MHZ#=4</&4O[YJ\_T.BPC!9"L]-HI/+@22WMC3KQRPVD1KJL@U2B_68_U0VGY
+M$*M!?R?BQ!Z\G$9_2"5Z!UY%ITCK^&&R1M9K91U^$6\R`UE=G356<O;U,=)1
+MZB8*?J`^K>L-^B2J@S8FQ+OMD@*+1V@3W=E[[5;A[V*`"9$S-K5.%CH`TT?H
+M#M:ETYMZ_^M1:5&#FTVN"-J-==6."#M;LT>KOC^T^5%AAB+4*/5$K3,'0`FH
+M<'+(RANDHZZV`=>ZK\@-(L,G_I^YZX]NJ[KO^O$L*4'QDQW%-ID!4SA@AZR3
+M,R!6R@G8)Y(=$P7;1':@30>D$260+;'U$F"68[!-_?0JIC.VGL,?Z];^T;&N
+M6]M1XG.ZG<3V*7;"6F+<X)B1<`Q-V3,2H&2J(SAJM._W>]^3WK,DQRZT&R=$
+MT=.[]W[O]_NYW_N]]W[O]TM"`.B63S1Q,/),]/0DB\4>`N/^;H#,A"=I&)H.
+M0F^;3.[)/ABX21BX24-P#SQ=U2'_^Z`2F3O]&7C\[4$=CU,QL^A/!?#VDB^E
+M`2NQ.Z'B-<WPFE!XGM#@-8UXE3PI-5)H@5BKK<]\7F/:4\6*;,#`.H(%BER'
+M]]&=33#8,#57KHQ3*5,%(\KLPX!SR%U%$URCPG:,*0+A1M<TA8?@0#=T.PAP
+MQL@V(W[E_QKCW>1DX=>S?\4ZX_H!/?\U.D,C!DP30!)POPYJF^D+C!^0&#9Z
+M&^$Q\!\4'+P;V>;F*+X0RFH2955%LO(EPL9A"[Z:DU6H:H*SHF[!./SYNN4K
+MSY;H!)EW#_#9H_^7<O349,M4:\I40SO5^G:JE3(U0)K94V7VU(`NP?R">,TD
+M.QFHFBN]`@RP6R;:5ZOA5:S)&MEFQ:_95Y74A9UZN*#/^LKP\E&_#B])!2^H
+MVY(!C#P62J)N`[Q,<F(H[KZBQ4LH/FSUPH"-(UX$)WFJ)",[>`Y#/KX>="):
+M[(O?(Z9)OB1V7@I5X[T7A%:UY*^)\;B/XHLKV(IKL%6C8BM9"%N&?L16,GNI
+MD;!5I<'6+2%*SZ>B*\@-990L1579,&0V]D'1L&)KHQ1O@,-0DBB`NS'1A`K%
+M#03%+$:6MA-2YI!##"7IPJBJ'Q1+83(?&W:]P.U9@;.KHJ@?DI]%/USIT\D[
+MH9%W`N2=!"V,\L8K22DQ)+,GD2"/!EPJT(27D(+K%#G)**?MHD_>&6A]*D%Q
+MTQ,$$QD@`DAQTGNH5V2F5V20)THA4<CVN*L/99B([#NGD:&C2_6K;:":T](6
+M^DR0OS7>\3719Y*%'SMJD804YC=,[!P:[=N.X4)X#!9"<PO.+`UCP5^YIOL_
+M>:C/TO_)T_RWD;GF_K$YU_1=#_65W*4\,7%SM6/#)X&R8_SQ4>2/)W4;PDO6
+MWCOCB#3'P#@'71]:$$K[MQA4FS]V0]0U&EZ]H738E_8.GA)LA`SJK?`^AD(&
+M.G,^!DH7$6_2IH$)3N`!3=FJ:O!.8;AL0\6P'^J:AKJ,C<7JLK$0.U!9O;1%
+MV802+S(<\R-WBD)*'#/S_$BW1;R$_+H>I!J[EL55V6!L1%ZA/+#7*#MQJG5H
+M].B[T/VZA'KK+ML.F"?J/A?*GBJ?-+OYD0Z+Z$_CHU+LD)!B#4-+;B%]M`JG
+M^[6("VH0[P9@:Z5*6_.@T&[SJ%?\-'W"_4C&:FFKLM,GU9LK^)'M%NB;V4JA
+MH_B1PQ9LRD=-K0/]%7.$31NLS4V:=DYN+]1.)\M9@W+$;<_85GS;K>SK4M-F
+M!S6&Q8/0`:C7XL7A/L-J_+A_:U9FEV>S?M\L1Z='<14.^YP8CQO!/+30=]?0
+M=&^-\5/C%?>E'A<@I,&3#MK<E[J3&'>H59RJ2\6NCT:V;8*)HB'C3G7;P[YT
+M@RTHM[A3/4DU1T^63U5=:LQ9T,.X/,([A_ZJH>F0A^;!+]13AS(^6?+(MX&)
+MS9+F><4$?GF/[.TEYLAQ#&_75P)6Y]\#\OC!'U"8X-[=XLFZ*;,G#6/1['>*
+M_J192(N"3.L/=TCFOS%(K@5RY"DC*@;!Z0T;X2NTTF`5,`>?6TCRSST*?0E7
+MP$^-#5/!#V-X-R[2A`DQC),P:LT>I^B)1[:5&JDAF?J`6D3NKI,$&6>,LNUA
+MR\Z&*>'74;?/R7_C5JQ/>0;UG<[E-)K3XXK<<G$62N&\'ZK%,)0"QFA'4P=X
+M4:7G196BUU,8/`^G@CLB7#WBJ,7HFE:>"668G\-I")8,G6+ZC2T':UA,?8'N
+M"-,+J\5$W4FW)\7&\APNL3%S(09?QLB)2M["5<I;RF3!N2_V9A?=PC]'&C&<
+M5,AFW@RHCY4CWZO"E3"0J\(6+S`DO/VI#R7/XCNS6OMY]6%<<!]DV5?<5GZP
+M$8,^>9S9N<ZAF>L<3<`PC"B8XXE#X8D3G<2L$FICT,G\2)<%@0&22\/T1CF9
+M@JM@Y*)-U*O$ZWB)&L4D3ADAO=\@?_,B!6D0KX`2%(6$.(8*!*?#+@YF+S`I
+MRF!M)B3"%IA/X/=&LE/1T`*]X(`'9'[`O$FVA[/PNUT<O&\Q3@%:03=%=E@X
+M++6KDALZ%<3<3S"IF1JQ:PL9(25_[TB)8;X:HYK`"H[.$_Q.X7940!@?`?.J
+M)+$*]VE^<`$ZT\H/?\S"7RMQJJC=^;=IS>8,/4J5Y)5%F\J96P-ER[$F.3S?
+M8/2R[C%B^4$,[:92&_S+'-VQOX":^9&*@(1!,0*W-7/POR6RHP*C5$5ZM^+\
+M"9U=+XX'0`&1+C8"IV`NWPF,HKF\`%.!1.0KF_OU?`W0I7@P%#<S"`A)T:6W
+M\UW:^`<]):J917Q((\)"R[>ITK_;.LW&#N@\21QB%'#4@J$XC[)!9J,=D62(
+M`7/H72-+C+"*+9,FP7@CXU"YZWV!?<RQCW,&%<:S9!>EW;Y9_INS\+"=-MN2
+M&6$.+9S.3Q'=9X#V@9\Y084.O8*;7&##>,Z9/;-@%8,>=GODHU\<0$MO-9AC
+MY\!T!G.L+2/$Y8,?8>DX/_*D"10I#0W1=P$O9X?FZD)G0"08$^N"V7=.]$VQ
+M==T9U4Z?8O;W%-G?T!B\[31[+HB>*?=$<!V:Z6O(3IMB=AI[+PWO&3US=9Y9
+M"5<Y\.]S\S>P&#1(H'`#ZBA^\!@MTK`'1.:I#XE,I,MSP>R!'B3,H3EHFZS\
+M]9)_%MJ"EA0;?TICX\^BC1^`N@)0&2CU@&A$/%4&W$VF[FT!T215H@6`_NC4
+M^2EQQOU&\(\B;1F`,5^@3FZ"<QB0J#F`7,P1C7;(,SVX@17'!3%/:O%GNEAV
+M6IQ>.JC!J8V:%3%GC+"J?G3^3TRTMZ)JR5K2DLJ\`3K2Y]!C5Z<C[V8F[')`
+MY4N*OEEEA4)\GS7PSW]`>Z-S>&A*X$K0>6</7B8^XYI6X24H\&:`/J:'FG-)
+MJ)7$28;B)!%Z@1]I,8'Q7AQJE0@UQ=8OA#6'%FO.0E@[`Q.[BC6G@C7^JEC;
+M$_M_B+7@(15K^P\MB36P/UP44`2,SEX+`DC1164*W!P8,P[WV$T_-L(:X@'E
+ML4T\?1OI30PB=PFC8MC,5O-FL'L'/"D.\S-%6M#L=E\,KH6U"Q$*5%Y&*E>1
+M73;!;6&0#M#698,VSHC^_M,!=F56<2[27F(`R#UR"$\3TFV=\D8U763>WN>_
+M'&#.XSX[IEFO7XA51-J-VK$1:32*,W43G>WLG@GE7O[CWV0RG6U=\IN+XNMH
+M\O\<T/L5JB?W%J6.3GF>0@TY@;B_HEKR_?G*#Q2_!ZFIZ!^R%7ES%2WV6YMX
+M@ODB&)E+5:[TIQ0LR`&E;9K2>><LSSWQ>SQG*7"N4_%[;T]S_^WQQ?<#W1.'
+MKU4J-04HZP/\C972FG.U\DB$1>I4UJUTD?P?S^9J\SD:F:OAV.&J@I7"'"AN
+M4NML75RG_GSCRO[<51Z[HO)3+9%68]T4V;&JB;\:ID<C&N4L-6F61Y8`Q3^#
+MO[%E&,AV<6M`W,FQ@=9'?K)QG>^OOOV^_>H%/-5U'=<:DW6744QB@C5NBW";
+ML>F<B"J+=!R/A58#([F`^+0EFPJT2-NF_<J],(?N7IT_Z_GH[)!?0`-]#']W
+M$44*.]:J;P&U$:Y43YS*&VM@LIF(:T;BUF`:BLJ`>!_0=L2"07V6HBWPF$H;
+M.?NH&P`5.%1U!%Y*((&X#X#T+8.ZJH+4\62#+DV?-K;KQ-=SH<*<I"LUM^9`
+M$<AW/H%14C";G3^%1P6,,G7(I0!+-.244X#*@G#BHRJ8_*F`V$E@DO5C7,NS
+M35]75*\#5.\J=6.S,E__UF$N`%CLM$OJ137,<B[_X\?(RAP;2_$W+;%+RK<,
+MHQ%M)O[!7%2,AUJ=].RC*@]!B3K:U/G`V26_\I&>$AJ9#J"\(!UZIJD#$+X9
+M#5K7^T7QSQ_5W@?0.H/ER/@6DC%.#RBJ5:'FUJ",V`-%0LF"[?UM(-N>QY'O
+MZ)IK]$9=H\7[6*Q-/8^O#UP%I\\_ACD\5MK'PCS]\;YB`KT0UW;JVB)HCRZ3
+ME]NS[3"LXQE19;0@SJ?:VC5DO!K_/'D[_K7L%:>00W=K5O%F=;:+OK3<QAKU
+MI<&0M-)KQG$V*R[![]*B_-;3L%5+`^YSM$F5N)+7^Y,S0B9C.4(LM"?R^=%Q
+M;.]5<';+HX@S:-EL]J=5"505;+8TNDR\->XMAK?@!]A5:,W8M.*VBLI[^A&]
+M?DTOI5_38"@OTJ_-*E'$`N4G#0X7S4A,G[)'8I<E&\2QH!USYR-J#$_]]6U[
+M#@+RY+S2?A:%.I/C+$WP4UF3H[+PO)DW:-'F*`7F<<NQ=YY_6*4S'ZPZ8M>K
+MQ*I(_</3^MY#1"O#EHZX=7(.7G\8NK2V1^M#RB*-#33]E4<<:S_=JQUK60*3
+MC,#4(@*3/;GCY<HB@R2//GD)OGW_SSZ;'7+#?^?&24KYR2:^7C<#*UX=?\6$
+M<<I]\O#5;+NUN'])MDG7DK:)M@_O?S6[+M#:!CH4''F?Z=,5`&#9_%V*MM:O
+MJG&7\NT('8$SOUXQ@87GQ#4KPN?W]UP%G^L?)IMC)<!<+EU+X;)\3['Q[+FP
+M8D85MF$<T17JF+ZO*//W,NP898'*9KA/?Z6:,C;Q=-U9)1YK;FBD%@V-PO0Z
+MH^0OAB9S)ZY94\5HUOKMO/9E%G1,8#'%7&_AIER:,F(QKSHFU$E/`@O49\1+
+M&"/7YW#[$B&+.Y2D\\3@UR2?4P^,9!?B1?3'Y>NP<Q-L8U/RQRE1@I`4$W6I
+MMC9<CZ3:,IOPO34SF0SF]S8-C',9]&UPJ)5&[G+%PM`WYD^'QZP8`OS4'L7E
+M0!<+6^LW\M&#NK[MFEW4MR3U3=W*U?8MCGU+L+[M@IX`C;A1FP1IB7Y9O@4&
+M;:Y+,NM20NU24NF2+&]Y$[LD*UV*BY?-H13T*_;BXK[\%I'CB6?=)_+E]`7J
+MBY,%A\--R4KJ4_]9M4_UI]3M;C_&;14<;B$58@K/.$;MIV+S4<F39EN3+?P/
+MQXUC@$,,1#$-=(I61<9*-;@O"XI62$;Q;3SGC`S0!FZ"MBPQ=6N%M)4Y%D5:
+M.'ZDW'TZN);.P82X<KX49^=V26:B0$GX(]C,%EQ)GUU45#V;TI=%<K'D@">)
+M/9@_B#F!0BE*87M<"E%U6Q6G$NRJM!HE&XJ[/PG6L.U>!YZ/H0]38];7*8Z;
+MJ38\KYO@&@R+1-'-!H0"J_R[YR_NIM_YD0:WQQXLZ^I2-U1]OT11V(<RP?7H
+M<37!179LS;A?[[&'*W`7USM<MCT&'+`7N7O;J*O7F:OW-]-4+XX'JM9X&<_=
+MK_0$^>,5"Y;^8,GP%']LZO(X9A@(\AWR8U\F3]`QV0X:3!H(HM`,X6W1.\9D
+M#$^M.)\$-Q4J;N^0FUAQ35EI,'J[S6"`+L2&B]/_3%<1^N]8(?W_]*!"/Y]'
+MOW49]#_]8"'ZN<+TZ\_2CW<6Z4+W&XN[((;24;>0YI^[U60P%**DM$.>>R`K
+M"+Z('/AC*<#+ED(5K.F01U@%L;)HOBSFGZ5#I?I,H;)E'?+>![)<+(]&B_'Q
+M):/04*`"`6RO)U$'C-X.!8QCL@D*8*CM:/VH4BY8<H*2R&?X03Q@]Q(SRHV%
+MF0'T_'+W<NA!GXPB<OWN[J)RC3T353TXBV#*O_MJ8X("G=ZU<EY0N5R,\57]
+M6V_->7CR@Q>N9#+>^>G?XF$88>]"D5AI3;O4/5+,1^)+*U$:K)UM\NU3J)W%
+M<5#B%-<X[$L/KVXB+[FC_S-A,F@7DWGVVP?W0[VY24,USND@WL'_$.9HD,UI
+M;$`YV4RAOL^`"3/:MRGK!H;NA$G0J97H_\4K/@=)/)J""8)T?-H82L5>Q9P;
+MH%Q)?\JZ]:UV+NN\GUW<I"Y*?IMHDLJ@<V`$H(F./G22WVD&4P`6/*$TF0!F
+MF#T]*3`(C!=5,]XX`6W7+T2CY+D[Z@ZE#EO<,*=30/_2<%ECV-K<,"7D9&/V
+MQLYT=H*.Q\O2F^2_^P5.SMBX3ML7L(&_UU&$WF267D8C^G@8)R5_$BE7R(2G
+M$;L+5CM(:I0<S8'6]!&@-<5_B\+OAJT-1B&W?VR];[LW-A.-=G8V=S%2+_U<
+M2ZJLE;56?UUI+S'0B1">#O8_66X(VOI;RDU@B.X=>)(S!*_)'.3D]W:QBP+X
+MSL(]=F/0WB5_T<_&EB5*0;>'0+OB@,J^(US7):]G[U`^=)/D"'>4+XQ;-,[,
+M.>N4I[/8<%.YW31_$0VKA?U.W$O:+.__!0$-JT7S`HTOLED3F"*IV79D39=\
+M$R,O=@W%EX>?,LT<F&N?@)[IQP'Q&CNR+QD^F1O@ZSO`EI,/[5+&>"D,4,F7
+MC*W+TS.6G)X1[J#\$GB=HL4]T;LNXC6V4343/T<:*659DJSTX1T6SCO?I>3O
+MP2<3VRR<0;(&1!?UE#_65#ZT()CL)B`3/HP#6PSPP0TWE9.\+A2SZ7:VX7D1
+M6)2IL-\QC)"Q22:=W.IS<MMP/Y,;OL/DUB$?OG^1W"A/TW^0,;L?SU8`.PO_
+MB=BQ`W:P)/;+Q1_'DXPDYAWRVH[8.^5_[6#U6"FFOY<Q/'@O`-67%#3>;,$_
+MQ<.8<ABHC&^3O5619N);0GY>;8=8EZ!3F^$=5JX9Z_@;^CJQS0I\,P7$!F14
+M!1$4;BGO/V7$>"'F_E/<<$LY:K,Y7=Z*W/[W?>S2MNJXRAQ6FRQ&3-``-D4H
+M??A+X<IF%DGD^#3P5;))[4YW>]61RK`GI21;D6O:65H"]"N$Q\.F3*,S-H[Z
+MV::_.Z75S]_=60),I3%,=,-2#6R[VX$<=FF\G(:\776I]:<I^D-[)[H.W7L6
+MCY&KAD9[C<W>V&@N@TN!<Y0MFG:8UY/#/=-3NVCAO=_0035?G-'6_'HTNF3=
+M[_CH?!*K)]7DGNBY28F4T=;9`1V0O\/J`_*5*L]&"]2IE4G81V?1+!0#(UPE
+M^B8U<D='9SLL).5M2N6^E%+Y#*N;L1SCX70_]O"?!VL"#S_VA-"]+\^?X08?
+M+:_)T?+4P%9TQ:\(`)S<3:8>YF3!HJ+U]SHXK3Y:$QD8_S<6_V8RDZ&1HK@[
+MW"\\PJXQUN2WOMCN_\X.FJ#W&T"/_?0-RETQQ$RX!#S!O'TW3F3]$\?1E9(V
+MA'M+!MXWQDSU"S"^T#TY,G#GRT`+%'EU`A1-0A]+)W?_&UM[@=PZV?+$%+3"
+M8'YS9TE^+`+KHG=AJ&M32>?'JY^Y-Q>O?I!"U-^LI`"6#MDP2O]!3`$L'7*(
+M;7;Q(*8`E@Y5B6U.\2"F`)8.U8AMU>+!&NF%858X(+77!L2V6JE]H]BV46IW
+MB6VN(O'L.:G;IF2,;K5+W0ZQA5IH=4K=56(+M=!:+777B"W80D!JA8I;:J76
+MC6++1JD#*];F'^!/W%.;BZ3TB+#W\7W!FH?W[MW7TY,GOW=;27[HS8HN.U"V
+MN184/_,``(BD?P)BZ9('D,/-KO-<HL@ZY\7EU?,EJF>CQ/TH6P]F?,#_F$02
+M)]CGS??DS0MW0A,8NG^`O*\%F^B]N?/M4%R>]+$I8(#X[KWY[0/Q<WZ[/E8_
+MAOU_Z]3Y/?;(RS]XY=/,><MY3_5_S>,[V_J3]PCE\//L?.3EG]!O[WQR?D\U
+M/'EG_IQ0_1;Z)*6/V4%MOG4@!2/O[>J;=[]U(!T8&#4!$0'16\N?\-:.S9G:
+M9`$@)WHWLN_F-GD??7=!5?73@8&^6D/?C2R/F7?C)!=EV:!<YYU3YSS535@(
+MQL6[YV=Q_^[$SEJITR4-X.0NN:0G.3'X6DKL?2V=L\KRX^NNVYZ+`Z_P@K6Z
+M-G-XH_PC@'?FL$M^Z5[2\XR-\$HN/OSS]RZ*#Z^-?]M"\J6N\">.U+HOA=9+
+M][E`#YXK4UD=M/TO:\\"'56197?RNM-`D[R$)@D?(4"`-!#2@4Q"\T^T$S9'
+MI),QG5'(.!P(`QG#SVY@&`)JFY'GLST]ZOR<<73/T3T[ZMEA1D?1`22L"X0=
+MW<!1#$H81,_LPT8W9#")T/#VWOJ\][K3G<#H.6*JZMVZ=>O6K:I;U;?N#;;9
+M*MP]NR[!$*M"F`:*J%<6WSD`KXX*Q.1(RTSI*$&FXZ+#-@*X@=(2CHP,,]QG
+MNSI)L&=$-MRT,*]Y]8Z\^7DF_+<PSS2`)V9*=W'ONN">`E/&$[^D[T>K7/)3
+MR%L0Z+-9V*:%-CBAJS,4_-L;^+H(NE"R+Q3\!#.P&9!W$W'?/L<,[64H^"4#
+M5*93!GN5Q21A]RJC>4D^3Z321"6=)AF/_T@U6(7%K4N+J\BP^I1S,`'H@$[@
+M\C0:8[]Q8>(R](5FT/7=.^_<\(`_[OU_9<Q;=-.;"=ZB+[<5'Y8S\0EM.+Q4
+MSG)G!KY.(&\O5M)@T$M,_CFPLMN.D9E[+(T:=K:V^\?+Q7*]4)/Q=H7-W.^5
+M*^QJAW09=8Q/D9?)?#G?5<G-ZX)N4\!!\46\,KZ<E6R1*GK_+)MA7M0+H4K!
+M"_A%@M^ADHC+5$VUNXO]_RV7)H"1<Z24R)G$\?%.>G1?;^XT_TB?8H.AJ?<I
+M=>K`?<E@_\VJ^03T=H1M==.V8'M-B_'30Y\RM9Y"G93$2\).IDF94A8H]]`I
+MW*?,DJC%YS&L?]]&&R.-;62RF$-D/J*?'!<=0AS1]-9>OQU'5<X&R'2IC,VY
+M^/W_#HU?E0)ZY'W;*YI[:N6E.!9'0!V!=K.AW=O"K<1E-&G;*HD1P"VE2#GN
+MQ8$4`.C@C%VS>N/&3?Z\M8WWW[=ZG;]Q:][]JT&`8]LLO(,[^W8=1E(%=QE3
+MQ,50\$]_(1O-\.M4%X$#B%PF9[M/!T8P0<+W$'**9'7G0,ME<,2J!9IMYJM`
+M,\AGK']F9G9@=>'QCCQ]P:=TH\+NXP';?A9123:YK8$OBP^3'7AK8_.F;8WW
+MK=NZ:2/QV=#8O-G_X[S[-PSHPX;;M;E3#5SFHDQ'-I=(ZG@2C`SZ-HQ1GA:6
+M<S">'=#L,]),*<DE=L4B4>RV'"!,L$15%1=+VB7D:2+"XF7YO0H:[QS&#O@Y
+M\B#1$=]B`:O3Y4SW">"EE5%$>&F&L:=<[.%<U)PYQJN/<7Q874'X<,C,Q&ZZ
+MG(%/BO:$P\OD8<CVW19W!F%[X$O(6%%M3`T7]\+`0C_W'"3]O.W:(#JC6D[4
+M^U#P^0S8[RH$$J?$6JL\?X<A,)BN#QK]_Y=SV8;6X(@?29&SY2#Z;)`JQD.1
+M!8I2PU@6IF4AC$\:L!:WD_A[=X%*\C2)*S0^>+4?YF([C?M7#7NO@Y8#-,6;
+M)0?S$^`MH&5]Z/S`Y'<7GPK>N.)/E7VPP>?23["HMBD9&/C:/U8>#FNN0R[W
+M-J7"8+C,)V`P2L@;67V/?^GVY'O\!TLMQ.."?Q9YN>O`%[3E=HR09`;%5_H0
+MW^`51]]$8?S'BSH%RXE:3+L$65"7>5^P0KF-H+&1\J=9>:;6-4R&]>3CAHHB
+MJ2@2C2>1O?2TI51.D>+\4*5#JK1+<$BW&MF#`4)KE1<KR$:,X5:>1'GSZ23R
+MJ)P^0P]\!DKUP36,O=&'&*KQ6MPF:A%<(4K58J+X!TN8/#EN@N;+Y81F-3!>
+M#>2BMS,@OO#V;X/XW6+\7#'N?XMO@<;EG$9"W:,5WSIU<?Y?.6TB88F#1&0=
+M5H%!G<4D?O53:!586M5M(O%3<K(\U@><X?RWB,':.>RS26%?HK!-J4UX]9+Q
+M!Y\HG6S[>F)-K9P-Y]$&K'<27Y<&KZH!*U[3T8AA<O:#U5E"3.P>/083S!`:
+M%4WRVH;^YM-,Q66/0TIQO]=BE;8*$2$L50N0L4C5MDBJ!,?*#GHT-,BG1Y12
+M6MOW6`$R8@L3ZVJ3"=_!8IVT8Q4TRG6'3D.=71*/+:4QL)?::`!"S6>1(9;4
+M4D/L,"WN&6TS11H>.T<$:%W3-UF9#0A(().+%G+#?F)L+XNH4*(G=%0HG3<J
+MBT_U]9H_Q#N3Q.O:]074`'TG'K/E%!F.5^4VM"0IO[GZ!Q=HAOF`XM;KMRSX
+M9O0O^H;T7Y__S>@_./^;T=\R_U;I-^S'/'Y=`KF8.E^+\[[8Y%\H6X/[PV2?
+M2U?W84+Y8"&]&8`/O^(?,*$<H!_44N49F@KN)A?*VP1%6A@7-6W'0GW'K&W\
+M8>..`70\Z]8WHC'H"\(>?1-O-'K^0SK>UQ':H=+?Q=3UKV#;)MJ`9"79)I-7
+MV0V+29-=^=\%^$&$M9:H<3GK30CN1N'/EAY&NDF(6=EZ[$'2&Q)86EZ>*^U]
+M!++<<Q<6.:2]3^-C3ZNZ#_\J7RV@.)`I:FD]'E)3%J%]$C0'A[S1]#A8&WK*
+M>Y0=!B/I5)=,`Q;]ST*+*7Y-UFV"ZQS!J[=MP_>JLT@<<E@$X+Q.5$*,%BR$
+M9YHE.(;`"637"%#P,I[5')<FW']JYG%C(70&YL$[7*MTPGDD8C4?EX[T?50#
+M8U3KK2&WLTW0&<6)U+6UMN\:A2UZ<1&2LV:*4@[ZLZ**,[[CN3(P5L[?RZA8
+MTW`!'D?KX98,<X>[8\\DK[I%@(&)#(>,HQ8RWEH?::Y8^1.P,F)A[^Z3*KFQ
+M_K_+R+TBAD[$T/4]LHG+J0VU62(;J,_F<B<G:X\3)R<X&,3)2<Q^H:&=#FB;
+M4M17?X4!:S\%31\SO\7,:99Y'C/M+/,"9@Z0>.IYF,=GZLHK["/Z/5">8YE]
+MF'F295[#3"MDB*J\,F_XL)$C[`TS385+5KH*W22QJF!5`<VLFDW^SECE7+5+
+M*R-I]@5S3OC2Z&E865A8.+-A"2]>8EI97GCOZL*=@'(E^P,%^`<@]$\T=5\#
+M2\"W^QIFQ/K_+`6^F)H*FLS`PG:\DZ&=6(8]8N7WTG+24Q?A24&3:3WZ%L.O
+M:^A7PI0L0ZU7:#GAW-5KK!;]]#K]1)C\MVMZE8.TG(S$L=@J[]!/9,1>,50Y
+M2<O)L#Y]C3%>7P_U\?\.BXNYG\;%?.H`"ZNJW^,8_=^7\+42E!*RV,%T61?<
+MD<+<U9"U+U1&EB:`6(RAQ*V&[QA0<F-9W-+84&8X3,2V)VGMJ65-)N4_85I+
+M5CB)J-MA9BFO8;922'Z?4ET2&].35)>#I(N5@E$G,]Y_:I501<1Z=VK-(A&+
+M::O$9]`S5I-A48L]_\YEMIT8[O/SLL0MQ]__&.N\/E@=`[V-<W5]%NOM+F/4
+MUD-F2YE.[!<6([$#QO:V.#RE1CQ.`YX7!\?SP9Q8/%^6&O#\S("G87`\H3@\
+M/B,]OR[5\8P>'(\G#D^Z$8_90,^[PJ!XKA?KL@AB7%:JRR)*_?32`<(8I_]@
+M_19[<:]:1@T/FDO)[6WKX4`VX,"RK8+R/2@DSE0S7N].CFM+/*Y)&JXL'9>=
+MX/);R+5([-ZKS_]BW5^T+8EOU%0=YN>V(?S"?NC28#?8AO#?^K(.N\@VT'\K
+M\2&U+CC?Y,\F.^6ZX$[!'+!KH<MY[')#_#.7'@_D[1)+TK@A<RB<CQS]#J4F
+MC8,ZW`CW;T)2N`M%!K@G+$GAWC+"O1X/9XBQ3",A&WFUIXC>/U5@/*G;2RP&
+M?AKDXIXB(A>@8/OJE8M6$Y6)/=EDX6J=:Z$&-E1H(PZU%$HW&4NWX;+:P$HJ
+M!/W2)$'LI2]F&]IJX6WMHFV-2=A6ZH"V+L])WI;A_>-L8XBL(-FJ])715UNC
+M?&W6F3FP?L60]=M3!JN?,F3]7Z<.5O](X5#U?Q];OW:U?\.FC:OOC_/_6QCK
+M__>4\3>7>QNW;LI;V[AQ4_.&C:O]F[;.'NBS8$$AO_HGL\IAF%7#Z>WO&)A3
+MN(:$@B^>(A>V+>B7:2K,-6H9-`&V>YA;:XKYJDFFVMW%;"ED7?-$87!AB12P
+MG-A/JZ_F%IK@C/*YBRU3_GRHB1X2E!6L,M[\TY)%'#LJ&6AC,$+V1`U*!+$D
+M+BBRF`Q^%>+BG\WBHNDZ[`[8_!;W#5KU'K44E\?E-M#!C[I8PTAL&99M$90_
+MNGC;<G9M$PWF\BX#="`@K0V0CVJ0%UN(=0#KNE?#U>ABW;<;6O7R5@$U\>SD
+M59H3XI_N&IP+(Y`+DV<37<JG9!(7"MW)[!]GW@0_7B]*P(]_+3+RPTSX<;`H
+M$;W;BX;B1UU1`GXL+=+X86;\:$B(/Z?H)OB15<CX8;X>RP_C_=\,S@P@@VV?
+M;\TV]%W;/U^8S9OT*?NB^D^K`_A[P9F$OX6TIZ0-W^P8_M(FRK4F(HUA`\]X
+MI4FS-9YM8V2I9<H(K19T&B;:RX5L`@["FKZ9C#5_OV9@S<#XGTZJ@N)R?7>A
+M-G_)?+Z#-X.M@LI34LB7`8Q)Y7>\1=>3';B>O,77DU.MIPSK22$T'IE._"?&
+MK"B9A3$K2LK@'2(KP+29^@J0P*[TK@(Z)G`TSR3+W6C#<C>"+G<"ZA#H(C.'
+M0(PR0`RC$"GXB]P5YU%T/1=(0]]8A(*,1Z18&>?BO&46'R_^L5^?`'>3C_TH
+M[-B!9LP>99WL)YWLCQVU?J5\!C]+)6/#Q!GT7D4Q7GJ=IW8O!<;WS]/ISYV4
+MK#3VMTH@-E?5P$OR@S=,PNV"L@"S53@:9[[L\MB[/F'V%$LS'G$`6SI/<ON*
+MKC/<[;_D46!5'W;F?%>#'?G:U4F=,*'2K?P$UY]`E#ER@OZ'PZY3@/HBQ^NW
+MRY[/5,]GP?Y1U,_H^I#\2N=5M<M\KCWDN<*L(Y291(;M<IJW*</[<4NGTC.#
+MTFWO\EPYTX)/8%ZS2YY+9YHO41.;>\\T=P,TKN3*(08K!H]>_KBY\^).8G3:
+MU=G:NSL=8'Q>Y04"$1G'O(GX1TL]?1_)5:!Q>96],QA+[,31JP-J>)65#*4M
+M(G1U=G76*X_UJRK>0/YUX'GPT%0]1N!^%B,0)O,<Y2Y$8@P3&+=>M4[5@E)[
+MX#RJ9%.1\(+6]1O4&OJ-:E/\^_^I,>?GH#/F_.QWQDRZD-,R(*1C_/D_G]-"
+M%HBY3M9_JLSE.[G8L`DU4&]GMOV4OR,($[,)$F,WXOJ?K]LCQ6E.:BG!$"W0
+M5U8<+M`S"O25N[?7\+-N8I\_D[5NQ4T/3Q2EN!Y_4_<I(4#J:L=W*MG)]*=4
+MK6_3Y;IH,AX,(SQ`4V\TK/1GH3RK**+C"IB(#C+?BZ998AXE).I/[92;Z<_!
+MZ4/V)XW0N6L:[TR"-=0VL"]F[,N*Z4/W9<W4H?ORT\DWTY?+T\BM-[0!S7N5
+MCZ89MDVO\L`TIG;N6DSC)R;:J]+(7K5K..D!=BNLC4MPVM!]^65^HKX8S_^3
+M-"="6D<.T#6XM7?7%+4,?:["%I+.&K/#)"5%L'-<!49%&OO.>1G,YU/Y:L2J
+M`<SIJ:R>7"\,+9_CR,QYAM6QT6DC4[3&N5B4:$QZ\OB8A'R"5!>%70/4`<]4
+M?@=A]:';R3"L4$XH"P6CYXB!Q=WY9)"`6_6*:!SZ1.]+GV!MQ+ZU*-1M]K=-
+MH3_+T(<6(^J5_Z(%$0NWU\]A#R7T)P,7UZ*_4KR$5^KSN7*#\JHLRV=[LXU(
+ME?(#0JLM]D5&X.ZCGCY3R-,'`%44X,&6OB+0;V";KU=FT:+(;&+[WN<Z)6<\
+M^.,L4\"1<>BP%T;ML\GD>[!?S7@:-SFKG'9T:980"ERB/EX_FX(T7"(*5C_D
+MWR?Y;G(YY>K!:U]!#5PBBZ^R?XJFBW4C\_]]"E_+44:[B8QVQVH3W<H_)FG:
+MQ"4"<2D6XI)R4H=(HI'\8=)0&DEH$AW:LTE,SQ/8_T]@YI7U2B?AD0!<=X1`
+M)I7C/$^MP5M[_2U<OD6#?%OY.J3;]NB'T>VH,V^?''\8;9BLR2NO,XC^_$8>
+M)818#"WZA`CT?=UT:^E.$K?AQ&WH)Y,]@%YO,HGSFDRA0+]/^7XOCB;>?/F4
+MBJ^8O?N>$O+J;[VJ_E_5>E3B0H%NGS*7@I(7"3D<E%_`@;2TJOX[F-=6(/M*
+M+-E7%%.>-EQ)A.+<Q$$&E'3]P,1!A`)E57EF(GMB?3[&CZ.1%X?&Q_'"Q'A1
+M^Y7.B](KG!?%&B_V-*F$$3.^TAF1?N66&=$W82A&?#!A*$:\.F$H1OQL0APC
+M8N*?C<-0"\&_H/B9_.ER$!,Q;1#)5.Z<8$D8L_`G4)\L5K\!=DND-G^O8'C_
+M-TY_?["6_9:#IA]/'6:9&IN\Q2YY;=)F>]P[`FXDH@-H[P$T]'UC"7HX%:`#
+M`=Z"9-/P=WW/%GN'V[54MT.!-`T,B>B7V1/-F5^,I2;B5;8SYYG:OQ:ZVU77
+M7]Q[!CVMTM.'A1P]@&D3P^%*M0PM^`_";/NX^=(Y4&F$LW7]!,K_*1Q$*E7O
+MQT(^E!KDTY347F_TV$3V>N\DL*L3:5GP1I3`I1*[)(<&J-5-8'\7]5/H?]+^
+M;L;XY/9W=6.0?I'8$4PC=\G4=H[8WPG2AW)I8N,[G?8XPSI13S(N&(SI8N._
+MYNHF#)-"E39F\"7$&7RM&J<9TOW+.&;MY=!MN$0]^4Z<I5Q\_.^;:^_26*.!
+MV;3QM]AD;)N].3?5Y@[>)C4Q(RV_=HN=';!/[LRA.E&5D'$(]&%\VB,MC[JK
+M<[<[I,M[C],W>+7*;T$"B+\N*).71_>:U0K'H&_7)N?P0/%`'B@K<I:..8MC
+MK1Q#M9MA88Y3]H#4VK0J.QWNG;G;TSE\-E)AV9N&C<?LD0;[MVS^>R=J\4K)
+M6(.A7-S:MR<;?RO*XX:,#GJST+0:=X/W;Y#=P*M,45EB+$]D\H2-)U0.W'N#
+M_RH>-_^SV65>KJ\>?>YB"T_`Q/.ARR62>Y`8T100$AP^0HQ-^1%:Q1!PD97<
+M8S:9$O[F]NIH[`OOPAH2`Y93]0.>J.>)NXQT:C@V$1P$P49$T'&=@4_D];*3
+M].\[HY'IN7++>)].Q%K$\3C'\3%/G.*)=I;`I\-AM2QX3,`*K])2^EK^HM'$
+M-C;^HP/VK4:L,.,ZHVEXO!W"<PX\*'PW0E^_-/D1.AIEK1_C9!RZGH@7:QS(
+M"X-4W(^U#_':(WEM@2>N\4\]T43X1L72L@ZQ;>95%G`D<Q+2\N$H;5R:L=X\
+M7N]1GMB=L,WG]'J;2=PF#KZ")RH3UOOAJ+B^/X"UCUSC\L]KVWA"Y9]ZKQGP
+M&?P?CTJB/QS_5O2'-[*2Z0_'_UG]P?#[;Q:[O%;^"$+.M(??0;*K$K2)<^T)
+M8C9/S]*[V\%,8/Y*_QJ,9=%PW6N7:Z!=4>,9JY8$S&##:H^?_YFTS3H[UK1E
+MO%TCFCN\<KF#_9079P^NZW^&>K;$]?3XYYG46M)#N(5VLAB3Z.URT7RD5J\1
+MKSN,R>2ZCT_IQ74B2'AA14O#W8)<)TH^T-+ML>8$"?P_BG2?VFZ35PBM[2VC
+M'VK[O:KND4[PV#`I?1]))[5KUH>.DJ\]O`"_GG:=:FW?90U^/9%>"&>$@E[8
+M*V5AKU1ECV2%I1/!"Q-IV5Q[6%IA!WCT%7\C'GZ?5"4B?(\.7Q*6MHOR"OO^
+M$7`,Z;O8=G4<T-4_$9V'M9W/=7:$A(?Q/P<ZIW2>+`?D\@IQ_Q*3*0^!QQN`
+M<YSP/ZNY(^1XF,.*`]]S(RN@M;ICTJB^B]+IMAMV#`A%L!P-.;:%A%_`P;3M
+M?)I<%S4?"96<E@+1D/!G8G/X'H&0ZOH1J*WMDS1S&^S+(<=[(>'GQ'2SWNX\
+M$K(_V?9)JO,DH#P_S-QF;I?K^MLN6)T]#,C9'7+\5$L[VZ!#THFVSR<"R>0-
+M=]I#5?:7803VOSMLYXJ^3<0(/5VN$H%`)&!#[[3W@)1`5-XNS@Q$-YS&+'P&
+M1CD>;+M@<1YINR``%4(XY,#`*Z:0\!5MJNV\Q=F-9`N$;.<)J5Z4Z\78IL4T
+M:!KX,W.%B.;D#[6]A,)P7`_+$SO'MZ4G69\Z:>:Q&MM>[\T]L:[)E[<42-Y\
+M:7.!_-3[?'F;)6]Q2=Y9TF:77%,B;YDG>4NDS?.,]ASZF^O'JFU[E]W4:VNY
+M.E_>6B`M(XU5SY*WNJ1EI(WJ$GGK/&D9ML%,[)G<Z%T.CB2SLJMR5N=Q.`>=
+MK2QA2]L:6+S.MO2SW)]AUG5]W]'E08BS`5[\.U%;"N=F_3]S3QO=Q'6E)(]E
+MV1:6("XX"1N<C9V$&$[LF!)$LPF0RH&T!N-%8ML>0CC@(>D2((X%A(-L$QVV
+MF<S1KC8DV60W'V?[H^W9=M<MI,T'/<%R<S!VLZEM/FR!;<Q'8(2\(!K%DHUB
+M[;OOO9EYHR^TN_FQ_F%),_?=>]]]7_?=^]Z]`%&!>ZB2KTRE<^<,ZJ*8*WJV
+MT%-G2"\=(E_!$0382T>>HCJ8='$FQG>LSD3N`I]D(!=@R$6I3/_'3)9I77JF
+M@Q:%Z59"A.J0ZCV!D64+E#A3:AW6FV59C6R(P>R'YJRZ!8*SFC(25AFIQ(R$
+MZ:_=%LI(&#,B/WY:9>0KS&K%".2KD-1[.R/+%J7AXT_%E(]%#!^+!.>25#[>
+ML;)\7"])R\=0B<+'<VGX4.M?C'.72\O45J^T)EU1(S?ES[4EG?\C'`>N>8_T
+M1:82(P66#XS>E8F`A'TV@5XT':_X6-=.?3B!WD`OW8F3??@L\("-#)'+YB.Z
+MT!T^WU`G?V#=:F.+8:B+[[_J^FQ5Z",?P/!P=-1E"(PQ9^T8GI+L_T7Y.N!I
+MRU?`$\T`N3,!/L9`#YKR=S$\]4#X"M4[V?)`=0_Q7>+K^67@Q&TK@L1/!];M
+M1FSARY[$;Z$&M"@"#FLZP4D=Z!GJ5*"Y@#3JAVJ\M3KT=SY<#QKM(JRMP_4V
+M^IG`=9G+U.7CPGS5::PXB,%X['7%G?0HW+VHI9W2IPCWR(9P=4_U@.?34N^1
+M^R>@^L,;PKARTY^UQY<US_$>J68?TY8@R=`J(!1^!I]-$;&5NDC=OY_%VNLO
+MOI6U][UBB*<0#A;I<1Z>P+7`M6[[)3V.B47"<.).)+IBM-]`LKQ]>:_8+R$,
+MFTCC<;@_=0WY1T**1W@IZE^=&`62_TK<B5"'M/G=%F@6I6,%>J!-_!3WJM![
+MZ)/ZF4/7?=!.6>3`J;Y(U!M';PS;PR,;I"SB.%1T*W'XBD`<DK=I*'7?=Z0`
+M+UV):NFEM+K\ORCO)^+LB6WM^E>08?T;3M7/D28J/E^*E%%A9ZFXMDQ\?J[0
+M4";LG)LA?HA);#8+*W'!)ZUB<ZFP$A=\LDQLGBNLA(+R"H7/&#Q&SERHK)TU
+MTCG/-'1\N-4:D`+^H?.H&?VC4X$>,AF==4>D?R\&.UUD]+S78YU$W5<WVC/R
+M5!D.52,C3\7=1G&CI<5>&NA)7J.&Z<KSE&G$:<4,C$YFHK]0H2]NFR1G#!!]
+M&LN575],R74M9?+_Y,MU9>9WD^`T9Z_]N-111*R4J/9QM?8C-/VS9M]CS4)_
+MATS?RM!'ZGGIK>@_J-+?-Y61OD8OR,N7MU4_-.'^/_Q4&1ZG-"I*0!KFR]!@
+M&JDK0\P@L%J3LOB4FY3=%Z(QU#DZJ2SC6OLKJC%.5"H;)^G5GFSO-C:L^>M5
+M?[-Q3<.Z56M6;US3^%U[8]+Y?TXYRN^`@+?==69\%!H+2EA=)AX<Q\=X`+Z[
+M#E])[-;A_P8\@7G&\!-\8[$.NW3;;0M=IFXC&')#=WD];]Z<2C1($1,^9VVB
+MU]F-W4;YP#5CQV/C.AW*RZ=4*0?550_Y+QOF1X2FN#B+:NIY=K,3GQ/ZMI&<
+M>O%@4)U_S"!TY[G-D':9X#!Y2[VXA`.2:XMMIOE_$F(02J81YJR)?$UQL=Z4
+MMQQMMZ%DE0%-L%[N)TY\[O(_H9D9B8!5>)6IRB0<UQL(/+8]F@2#'%9JX4)=
+MY0M+RUW;FYLV[]BZ_=F]35O*=^R$HZL+RC<_LZEYTV:(O;!YQY:F\NK*'469
+M@,N?7EBY^3[R>ON.\DW-6UW/-8'#<$<S>47ABM*=\^(-^;KJ`=)4X-DO$'7M
+M2Y!V0=)H_IM>1Z(0Z"T'1`11W2,>P34D]2FP&5I,HL%69[*\[D=+X4SHYKM*
+MG=(J8D4+644(SX/>MQA%-+P+?"0IE$ETFFQ.:^M?('QUI2+G:U^RT&5LWZ/7
+MN5+T"4!99PH=\_DH48C<@X2(@P#*F%K^DN#Q'KG]ZZG$1WG0?X[%?Z'[\F=D
+MC.5-VV,X$N!Z@JZZ4U,/BZU(J0>`*_783ZQ5(;.M")$BE`MH\P)M*UHYZF#F
+M4CAQW4Y["L$,P;&JT/O0O3X?JBQ@2%??:AKJP8P7V6`+5@8(/=&)"KP$IW7J
+M3#6=P1\0/4$4QV0>*,IE@IZTHFA]I2BALWSB;\"U*(/`@4(^#H1.WNM(`$%H
+MYCPLBP,#+?GMDTMI^(ZG@9=6LPYB[+5/SFM%KUI;R:MO4:R(8J+:ZYF+9!VZ
+MS:=]N.IKN##G`14B'ZYV-4@<(@[;?UWP;1R3IGVO?JGE``RY]KV&I:YRF:UV
+MW/U<IM!F7'<Z981^E/+^<2(;(N^%F->[,1.$@V=2.'@)362_>0S'JI5;@`B4
+MG:(0AJ1C@.GBDRU.<.GUA_`W8M\;G.8RV/?"_UO['C/87P3L-,X'V*&E'CU9
+MD#::M"&?N+K0>9]3]OHE70AF[EHH^H_8C)@4=G+,'CS;.X6C*U]S.AP+!&=J
+M?U4G;[68.^_L?1;E-_U[5*/_?8UEYSVXSG`S,6(X8U)M=.@Q:63FGCR.%FE-
+MR?\'2'#.`P30T.B41HMTS/E"#2]J^<SXC,GX_CY'?/+^6*FNIJX=<5K797EI
+MZBKC4LY1R<^B9^C3E'WB4W%.OF.!6+7E+1'<<6&J=J;HCM<N$6('^MQ%<+)G
+MK;1X)@1:CPN:=#FI^$JT^*H4?+KH4`V#[HHU'3J&YWJKI0.IUTEU@2QVZ9[C
+M4`RS3ER0*Y_T?.J0CKQ)UM$VWN1D5:<DSR34QX3>VMEB?:P6+=^$V5B#4UJ*
+MF86(G@J_:>Q`MS&XJA1<4&\&U75+.E2INLZQ*8S,"XFLS<[UTL4B$OX>%37^
+MV+!>^B.]N:.)#:H6_PDM;H]#\0;I[6)&W!&&)J<463>ES'!6),A^`0)^B1MB
+MJFZKPM[/PH)P'7$TPZ6'C4]RU/QNZ;"R@&H;H=52/A"M&5?P_/4,S]_-\/R=
+M#,_?SO#\/?:YM@U63'+R>3U\4.U[:!K%;1!'FV,8TQ\;\9A6XH6FGY]NQD``
+M9N_!B)&,6:+CP\3W%HR69!_$'V/LW+CK)J=C_)%JKW;!15O!A11:I(T(*SGU
+M4C_E@7RT/T)_+]/,3SQF"N[%[[O/>WA/`>+,B&:3!JZF9VWCN045<*+O<#M^
+M/-HSZ@_]%5I#K8=T[-L]]&W&0M[#+Y/O0?8<@C(GTZ`FN:P;ZMS&%$H>?P>C
+MG)Q2I][<N-8I/6[$AB+H<T;!R3'#[1NA=T\RO1/YV>BEG=NSME'7!-M&<PO3
+MME%%8;8VFEN8MHW40M[#"PI3VPAL"*QXT%P&(<IC$`00^IKH"C-GPLU*M]S+
+M1<\)D[5/<FC)P8ZH_5VP,10@LQ(L!-7"'M1/QY7SZDS\GZ\X>J8!9[GM,VDO
+M!B;+_N<$W.O`TV.C]'(!1$''_,T65JNB3RZW(ZG<R1S+/9Q4KMJ46[E$1%NN
+M+\=RW4GES(49RSE)&(V:`5%O,Z))83EGJ^/P3>@^)?R0+@7.1.!:\O$I;C9.
+M$7&\U9MK)M`^3]]Z6_6`3>\JA&CHRSG+&^`D5&]&,[8&IHQ;6^9@+F7V:<N\
+MFDN9-FV9?TI?1AN/?ON7RISNB#6NEW;'R)P.><QB,(A+X$JK/2PX(F00Q]1@
+MZ;F,V9(O\61/QVR?.>V8'3)G&[-]YK1C5BWD/3Q&O@?5E60-FBN4$3P&=O3'
+MM#%]=RZ7;6+T\RB1C;K^_YD#US?$ZI5&U.B\,T:&/M0E$FW!4[!Y\(I[9B#2
+M^J&`=N-PYPA.*H_@O#A]0T,!UC>"$'O#*[:S94B!.Z``)/5IA[6U49J'"\1"
+MS3Y$XV4,'_"/]@2N#9U13?<C`<NK4+C0*_H02*@`P;Z)84?]`7=$=$0@5'`X
+M\%Q8"14<H6<8,[T&__&&<6;9E.4UMER6&Y93!=.''KC!Z8B85"_);.S%.0@U
+M$@UB(Q><CS?LK)R@>U8I0$40A:L>%$'HB-CW9,0B0%TQ.$YD_>L2C=P`P0.`
+M(*XB"`OVB-<1Q@@2^207DB,2_"6"0++KETM:?C<@."YI,($C2?P04T!R=H^+
+M]>._-0OU4N`Y"<13"K?`QH73^R^#@\9YI@+O"<5.IH!]'*Z-08%S[F$$+#J&
+MA;Y?ZX1NC_N2KN4^82HZL$(8W'\%$`@WHDBC'!:Z:J;V&(7>%2'.A\`/P=(0
+M%J:\37V,'KL`#7.BXRR-#OJOSX-$2K-<AN@9_8!PVG\-*3WCE@]0?2311M]?
+M$O7H_9#@]P>ME1#-6K`/B0BJXX;H0/_[+!WUDKY7Z+9TN"7AAO^\=?]Y"'HM
+M]%7"A][OOV[53Y*:^J]:]U_0(13Z/PN.D^#PI[_ST"]4P5[_!9/@&!-=EVRN
+M<,M=T0UCHGTXVE?K&-M3Y/7!:@?^$:$+E.)AT3T,]D;W&%K\\`&18>%1^-5*
+M[NU_IKV_P\Y3QZ[!`H`-L"71?G]P'NHKHA$JJ0@E`@'^PZZ\Z(:PS1[>?;]8
+M'['5QUQF.A#!7>4C243;85`ZI2-YB+E5])E.Z/JD'-L#;([P"W/0?L_+P0UD
+MG5F/^F25(XSC9?8WQ?4#JP],M)W9;X_C>-B82`LBBB;,^&]P!A>+FE(B;6Z5
+MJ?_BU*MXXFK.'X0)T7_5I.\79^=9HWX$IF^1=05'S'\>[9[B8DDMJK*UUA$[
+MT(MV3VB0.*53!F49=(2%^@C]/D=8PRDY&E2]A.5A%^;!+*[!U%U6T0D,S.\7
+MYU3-9AB`GBHS4-TI6H`%!#P[>H;P8?0\*L?D(>O'X\D<@4*HK-.:-"XI=W4N
+MC,MM+`S2-I6$?M3&@?V3T(EWU>!+D\6B)R;??Q,]>.Q;Q94<XA/.M&"YY",N
+M0JO1>\AC;NGP6SYP&BT=_9:.$N%SH1_U=WR0!%48NC+J\*"/`6[7':@=T385
+MKW[1?LB&NM^/6P'5FZV5V\2(&M=J.$76J'%K)FH2!SKW/>&)S6FK)H8O/]I+
+M.L(?P2G?^7X8UHW<B:N'4+W#^M,`\2*'0*Y`HD!/[,&V&9Y."9X^#T\O$ZT1
+M`ET\).PE9"\QLM30W`<TES!TP!K@&*='S?Q`4QC,<X_+7$W)4UMHA8_0OH_2
+M)F_IO`4/"OV39<+G%+K4AY'[I\I@A(^+"*-KG#):;Q)JA!<UC";9O:Y?14WN
+M,>-#KV8F\+=F_X=A3%EA?HYAN*PP'@RCRPJS\2I>]$416!+UPLPT,-^184PI
+M,,SYQZNX+\,R]#:L%]+':I"V)!F$@A0?EYEFMPRCRT+SI\%;T40HL/+B6:IK
+MS8=S`^V"07[7\X?=FYJW/[M]Z]+RNF?W/+2HO+GI!=>VEO(=+ARCN7G3]JU-
+M*>=M'T0DO9Y_G7T3HH1%($K8[\:9_3EC_PL2!5X#^PJ"=4I;5"Z;FIMW-/]/
+MZ'=(0/^>.2K.Q0BG](,0I_,Q<1J9^'<21^-)MQ:3R8/.(S%E'H&)BO+#2F31
+MD@P<L?S,P_P<9OCY62BM/":N4'FPL'M#((_OIY-'1NI)YY^O`/W:,A7GO0BG
+MM`KU1M\\1:>3=3GY$W3X%!VY';LP46?!W_'?TX_3]TFZM&8/T*Z0D<N3?!KM
+MNM3[,JK]^[+&_AWD-$>-J-_:I(!_>)EHG->H!H>U8:(+S_`>7'0[V)709J+8
+MI_P(9DJ=\::X(2+;(7@TE?%:6S:O,;0_ILG_<AF;(RQ'==Z#O\=4&LZ802O4
+MV*#Y;L:F0W&*LWC5GL^L?U\DV<C?*()4Y$;MO97L.-Y-QM&8`4<:/T`6G\(3
+M7U`[^R_NR&)G_X.&/_\%:ZH?8/I2$G^?9/,#^*>L?+)O(=VSW&B_E$Q[10;:
+M*78I3;M_YY+:[N_?F:G=U3:B.J#Z+'J&9^SR2?F?+C+^`EZT\7E+>,$]+4SQ
+MM3-YT3W-@Q>"O[MKXE@[4KGLTPUKI7UFU,*B?9I/YXM@[;<O763T3EZ<S5<A
+M23JFA7Z^M@35)CID.3I0TW?W\8E/*6ZG5*[@+M!D\-;X)8[.LAPM1.H5VHY8
+MT_@AT/L3%WC%WZ!Y/L6G]T,,7I!]![Q8PN>9>*%^2NCE:V?S8CT2A4DXKLI@
+M"O&YIQCSB=#9XSSC24C-_\P@?I2O`N%."9.J``89`0#B>:F(QS/$O+F'HG:8
+MO?5QRU$CR*6C2]\)I[)C2-+&'QO62O<9E$/OZ7"<.Z_U4Y058O(RZ8A2)]6?
+M\*OSLN_!<M0*@G;$>0BTP/H56/A]&OBIM/!R7]7Q&D]$ZKO7L[Q[-\N[=[*\
+M>SO+N_>T[[1M^],QK7_BEU\D^2?J\LE<F.*@T(SO'XUADQ4>WZ_-8\:W:EVZ
+M<5'U4ZCCVM+AL";U<RM];F;[N=H6X7.X+7C12H&2VD'5_\ZQZV/SA5NLCV^>
+MR[(^BNO*B8D(UD?Y!UX?[7$P8*CKXP_1^BCTX04RB\U>H_^<H^M$7_DWXX_]
+M?#1'?^P_%^3DCVT=S<T?^[V"6_ICL_E7-?,[:_\>R<6_^KDQ%__JX9$<_*L>
+M8V;_*C/O;!U)FG>X3/Y1M4QM4IE'\F_I4]6-Y.Y3/3G,^E091^G_>S_I'</:
+M>>B>\TGS4*\^%S_IB;/43SJW(ME/^ORYY/DG]_,!K(QWGLW@B\:S2HK-?&R9
+M]ERMZO\^F]%6#ON'X/O$?ONKB@RV<K[;/@VF\NF&1NFK/)W.<M0^'6S#MO+W
+M*]+9RGDPVK43V_JGI$`\M!9LY;^OH`;9]'/?IQ7,W$=_H+D/K#NP-X@$GHLH
+M>X,8VAN$,_D/E#W48TE^@[EG,LL"_`:_);+XL#*SWR"A^`W,><1OT(YET5EY
+M2[_!60/Q&S2"+(Y79I5%7R4C"_HC"(X!>P36`=4Q@-:!"*P#XYIUEYZ'78)-
+M=:(.;+%(V0&3,QK6U.H<$Q^*GO9?FR<:M/9H)&Y+1]_^+M@5^J_B)-?Z+L2W
+MI</O?<T*3R&R'WI>']<?MT5;P,Y;;Q+TV)04UMJ\U/5_B,,)4([.`F\5,2&*
+M]1$P(,*=-@NPXP"U4SA-F`(M&"D$]K"K@(\.P1?+40>XNFS]^^ZV15V%I%^&
+M"GSP!40\C9/J-8)5>S%B]ZVH.R+8(TB#AE`A`M*314>8]U^U\'GHLW_*<K3+
+MYM_'\0G[-*H$QT<W`,0T+/F"]98YK0<&%9OWH]0>FFKS+H+JV8XW5XKNB,T=
+M<Q72_A,JT-BZH>%"CZ;:NGMWE2:9NN?WACC5SCU*T!(#-YK`W'#P4Y,Z7&O_
+M`)8]<[/:V&Z>!IBRK#"#&*8T*\QA#&/-"O,/IZG=;&YFV]K?RC!E66QK=:=S
+MMN?=*>,KS4PS>HK"6+/0'#B5BST/)EB>&O3:$PD>6_12['DUBW.R'VT\!?:C
+MYQ]0[4>7A]+:KQ:?HO8K%O;CH8SVO!SIGSL)]+]D</((IR0,:NUYN-XI=DRV
+MOK4/Y41O!Z:WJ4JE-S&8MKYU)VE]6=C>0:COMG3US9'^]1-`_R*#<Q?"*;UU
+MFM3W_WJ^E+G_=H(HBT8<K*YU%I]8R8G&!DA7+1TLT27%.,?G"GCQ8<]E2\LL
+MRP?K#1^")4^X<4+B[_[N>DZ3+P7KUR1IDL=O]#8;13?:#3V!<S[OYGAQA8&N
+M!?&:`5N7^RX?CY@0])YC!H_?L,+FB+=="Z&)%H)AH-^HL.6#)PRVKGWC&(_%
+M<][28E58H`R`6M0447E(/B/+Q'\;(/7VE","N+:V&1JCS[/;MC5MW;2M?%O3
+M]JTMSY0_N[U\2]/F;9N:<>CLI'/#RP<X)=?C@8E6T_YIJ!D]%&[Q>MY8B-I1
+M\IEQ<APAC.O=(!TWZ]C(E-I8-]?Z-38IAL^9)4G&*<T>BD^LX%+S7_:3!<-M
+MS<9?N!CSEWA8X?!5LXX$5$^.O<'F/^C/I>ZO4=PNJX+\VTG53X[_WI<+WD<(
+M7M%>BE;#AD8%^7BJ;!G<_]C'*?E3H<-#W]>U0?:0ZA.<-GO(/!B(FIP-6IV^
+M#J.R`BH+I#37\S:#JQ):02Q041<D'I9.02>!02`4!-^`19;WO(A&W+?XQ"H.
+M7T0D@^ZNXO_F[6FCFZJR3<(E"6W@!BP%O]94!QU=J*\5YF$<Q+:+E,HC-NVC
+MJ<[38>I(9H%%L.2"8$.[5JC#]9HQ+L>E:_Q"1T?'41%Y8T;?$TC%EC*H%1%;
+M*4X>TX6WI&+$/`A8R=M[GWN3>_-1<(WK\8.D)^?L<\X^>^^S]SG[[$VQ&[&B
+M-"=XLSEXKQFV=Z_D`<9QF]:8Q3Z\</9*E7KV^4DH)&$U"[)0CPF:J%PD8U"5
+M-!_QX1IDHJ^\TB2%@SP:#O*PD=!N[DU5LANZD;QQ4UT?,IHR\^'K]#@<^8A3
+MUL0-Y.L6D\J:W%),T561GM*P-3%9TY"_^8!38DNDRE/7RC=-,K"4%87R/+RK
+MKW\^J_]HP?J/Z.L/3RR0E^(N?;W(Q+/DIOB9OO[#$\^2GZ)87[]Y8MX<%=GY
+M_]Y7C?OEAE2Y_-*%AJSHOEER[H_OJX>/L!;8!'HJGI332->F-4^;C\_29EZ>
+M-A_R8[<ITLY%P.##_SLYJX4^_M=>528NI\0>Y?)[8]9_>:]N3,JHQ"FY;;3Y
+M+_>F#\.5/7&J=D]LMQB49`1F-XB<U+5N^;]12IH9PQ2.,WSQV'!_D@OWEQ//
+M!>Y[?QL3[H?F'+C733H7N"O&AKM6`Q?6SLU\__-`S8E_-S;<'ZEPEQLR(SXP
+M%FS].=Z;>[CTRW"Q>YPPYHYWALO>\3:3:_(H>3JFY=1H1K[1(^SB]]EAIO[\
+M3Y/_94\V73\\=2PZ->U1Z10F[;2?['<#F?XBNTD6'M_O'1./GW)9ZS-IZKFM
+MCS`VW/8TW-(&-M8&>5M)(=#9\7]Z.357TAR8+<RRA9+XM!./FC#NH44T$YAX
+M(;K\9'<VC"L(1MOW@/'P;G6.J6V5E&Y0_H=%S3!C5Z?Z.W0#@[V3,OC=6$J_
+MX\ZLW=;_53X#BY>#STS\I]U$*DHWY7(;LGE7YS[?%'K)V+EO@S96@.YM%VI[
+MN7KK@1Y%7Z>XQ5S%SMC,3,SBKCVT\RH!BGV3I<!BZA9C/\C-I09=GMB,_TN/
+M;A]JG&K(?6NQ!.NX%%&*U5(5\BZ+(6\<T5EYZO[.FK^N)4_=QR?HZFKD?S>G
+MR7/C+&'U80W>M!D,^6WN%[N5N2%P`:G%/$6%;C20_X'F["Y^8Y$!;+3KR_3Q
+MW[K1%GO0@;886GJ_=62LLF@O'>$"OZE?/H`O\M>P["&"1.9=&=E_:$-DVWF6
+M+-C]&M@;59#WJ5]:>S4V:$;_>4\Y,W`7/E=X1JVSJ'"=^[!.P$WG)M8"YR9-
+M5&=1OCIZO?@:J.B%'O'JB@]W!7;R$9D3G4G!TN-,TNOWQF1P;B,^:6^2#P,5
+MB-U-&,1R6B^U&_6*H$PW)KTBZ+T]-9Q1\X@KYWRO:Q?)?%*3P3P5_=!CC]IC
+M`GM,L(`AB>!</^MQ5:;'%W9CCW[H<1Y\)+SB!J5'4+Y!I0[T@/X]XI5J3*A?
+M.Q:8UEI(T5Z@ZM_QC/X]HM&_1YC^'?^>^C=.DT61U9J;63[7ADK]N7N\,L?W
+M^K5WZ:;/"\SE%5T)/OQ1H(N/'.70$Q80$B>$N.+!V2Y$B.>@?TB^#6A1[/$L
+M!_0\W(,X<0$R>/B(>\4ZP,D"P$E@EWU`/KAB2./1/9MB[O0L,*?:2?"@3>[H
+MXX-)LG%ZYL,/J4I6V!8?/DS'BZ%N9]00E&;,U9Q;^\Y3W+`Q]"XZ7D\`67YH
+M`&H:._Q1@Z_D4'_PD6G0HD%>_ETJ-8RY)T/I$VS6I"@H7367'5X'I=GL6V_%
+M"6^@W63PU02EN50$<`=Z!R+9-YO6O\^=\?-;!U:,#O1ZQ<5KP;#9U\#<N?M[
+M:V@"!]IZ#@VD`>N.SFG`6,F;FM_$`1T$HKQO.A^N,XFNP;?IE"3R\5')->B]
+M9#%SPNW37_'$Y^5])W$D0AO(P#')RH>K3$$W[!EM,X+;#//P98,2EVB@EP_/
+MKS>[/^/8:!>NBQT:&-CY>61`5I%;%-QFG:=_P)3#L^LCQ$<4`_HQX%]-_/I-
+M]"?&K\<G)7RXTN3H]L^C?`B@6^Q1*]ND:7QX<:N9I43YLUH,PCI)%9]5P=AJ
+M8G]E$8KH^)ZR,R4I997\SGL<*PSL*ADC5L[][W)GB95SY[N*FC:2=98^73V7
+MPD,HKZ/*),P/MIHQ+-XZ6/16DRC(_(X&,[^CRHQQ^,I[4R[9-QYMT,C&7GXC
+MKEG`.6J2!)`SI<#L?-@2.P`\#I!6TQ6#*ZX(N9@=<Q&Y$L!U4$+Y>+&C$>A(
+M$N)\>,W8??E*`LX1$SKHI_OY+!2"G=T6JPJ%F.+PTQ!!`O$D)%"8!!?5`*38
+M1#PC,(+$\7;N%#Y9B"G>OZ*@3.-!9>!"$@9DB6K\5;3W"ZT[2#WR2NUF%*9T
+MWD9?DU1JP0*'96TQTUF9GR1>1U@Q&[,PE0^;W8`%63X%1.^TXU%`8P+T-3R_
+M"]:F,'0PR$H[B(8ZD#TWD42,^+_$\`,PYODH=>U>$7Z$GZKQIZ,5)RKPE1S)
+M6&`#^,G81P>"B^O,P=DF\7CDJ)T:^:#1NH-\N'&TXC@?=B8KXLP;:*(4F,$"
+MZ-*>Y;2KD0QRWA.LV:Z?NP!S7P-?!77N4.`PKRW&MQ8P=QO-Q49_L>E/I^5@
+M&#B2S(\!FW;^RO+A/&-702<.?URP`Q[J@$00#S>;T9<:UP!FYSWY>7JB"G;V
+M5NP$>8[#!Q1=#>-YG)"TF)`D())N-E_9!_M41`:P0CR#J`.(J%F-<<34R;Y9
+MSL+(&M*=?VGWF9IW@`UQWA?C3B,9D:O&&15KZLC)]/P1>0O,WLL,'<JVF2#G
+MF&IM$0QD#IIKO@+F6MU)2E*1-M9^0^!'$;P+YEDQ5MOSLMK^&[5-HO<.AO2?
+MC#G'!*M\"WK^.:V81@/C^$,Q/BR4JZC8!L5*C@%$(FTJ%\+ZH_<\+F<]+&>U
+MV#B"@AKV^"]H'1:8:C'IAG_$P#_X'+[F=1+J\#X2U@]^BP9@=VMKE5PCDC\:
+M7,0;1=<0@<1%K#?3U.:#8-K2)3H'C3O9-:D@&[L5@G(XA_R\U#@$M9K,QFY8
+MVR8SWOK#("KQ-[O4.!@YRF/T4[NQ2VR44ZYH3")><\GHEH_.28O6F^M`9QE>
+MC*[\_KC#G_!-HHB_=MDY07U1GS%\2`)SVY5SOFS[./8."EZ[NL6M$%I\RU:U
+MK"N[8QVHP+ZRJZ^F#]_*E66@X/QZ:=Z\/,?>5DPTH%FG[7&'TX9K&9V/:WD7
+MI6K`7!F30"2"30I_8Z8S#OD(=DB02+`:'EB-A>S.P!]7[C?!WKHX1(CBMSAM
+MX]!_#NI%DG8@HX6=^]J'^!T+,C_5F"_#F[/R?3?@!TGE1W&?OP!)N2/1X9T%
+M"A;48OSB06[)A"*_<]F:9:LQ^A!,-_T=,+!^:>M*@UJ0RT\GWJ+=SRM5Z3B#
+M-BM=T0AQW10B$R/8"(DTJP70U@0*"$3,H'L$5R$U>*7ZG/-C/IP$U?6T_QJB
+M!3/J)NKU"[2K=IQN&XY-0?D&/RCJ*Y8KM`4$?H0`5^!E$`C]^LQE$)9?,K\>
+M6*O$(/Q(*QB\M0K__>T;'&\)\1\PVGE*4/-^ENAU^'[2#$K8%-`OOQO&5P(H
+M,"$TV&A!"R<LI6=QU?>;0TEF#B4%YE!"<SB[:/GK<;UHB1]7Q1+EP;&3:P"^
+M.<3S@YY8N]@-E@5.RV\#XX(L"\"-,B=<9M6RD,FRF(F[#IM73WI>C3+8%9-S
+MYJ58%\->:5[@"[JB4ZP+\91J7YQD9Q%-\M<GE"0GF#_Q@!-G,@5&/KS=!'HU
+M!:+_4*W!/]@"3;J=0P8J#Z=;VD!J.5QQ_M'()M=0AW_(P&^\%(DO4#L&"5J`
+M!"VA_R\:5-FA1#.6DA]V++FTQ&^\CZ[K\M#3<#,^>`T&OB&,;XX#QA<I,:M<
+M):(K.7P*[1H".B;55<?U5+<^KFYHA)P*29I/[].B8P'Y[BLE[5,T#>=I@I.`
+M]57"((4(GA'T_3N:EJ>:Y/<H07"R"2/TO@.4H)QMP8;P#*7-*0-ZV5@.Y1LN
+MQFLY5U*$>8'RB[M)`C>4!UFF'<F9<"^',0@L9V--[#'J"^DIO?=@WF3:>Q*Z
+MO2<A;PHK>T_VIK0R7&!3\H1UFY*ZYVAS6*[_3T67F<+BP+KER[Y2I2HFY.`[
+M'S5HR%H12Z`)2`LT8HDT'96%^XF%\\NFQOZ\/*QNZUK:YC=NS:$GOYVNO(<?
+M0^I!$5,"6X<8B9SB1%=_`+V:1G'0&V9CMA8<IS785H=G&70\(<.2J.<B+C(M
+M9SK[:^DT(W8KZ>=\N!WJ#08Y/T>AU.S&[G'H=MD?+'%1_&W0*66Q)]!S!F"^
+MA8E&9KI&@8`!:HJTB,&9_OXZU(P9?/'TE5T[J)H_*?J'=I`>XQKZ.`5Z=K3'
+MB2$V#8[&0?\EDBL1Y*@+/#>!#2$%>D^WT3EB=,I0H2U&"LJ@'S@O8>R%R9(.
+M#EH7B,GDQU')+_/A:0CYM/?'C5&OL<LKE@*(<4*_Y.\W^D>,?F#&N,,UV-9+
+M"#I/T]@KFF/3"9Y,14,?XYE2U'M)CU><AP-C<S<>`(!I_6O07TKC9*6*:'(.
+MMATE>MNKH3<-L4U\@RDX+EMGKU!,U!8>P5."[>P0A6Q]RH>A:)9I7:9S7]M%
+M8!\T@3'01V1FC(,:4V\6NR/'[`MC40QNGLB*$9_)?[15U:N09`;>Y`R';D^2
+M'5WXFN33F"(E0$5.I@6%^"6,5O_Z(\_[[,NWIGV59@`S83314H#EE1:"J'2"
+M$KWS.\8JU2#P3@&7U-KP':W;UG'DBXX/,,3ZP+'!VY/97HK%R\L\\GEO,O]9
+M,['D&;'6RH;HD9<!)TNERLTS@,8J";'6EK9D:)SE6O_OUVF<P)Z>U#8K'K]^
+M\@:>5>P/^OM%/Z9'"N+K]$'ZOS_8&%42\CA'64*>+][@*.D0-!?VXT%&G]SR
+M%\X0%`8#NTI``\]DY6GLEP+7&>D[^D<C9KHQETI@+N5]@9(^%&#"?FW-'`BS
+M->6Y69ZF49:GR3E9GE`]W:63?UJ[?_V6[W%WUC5,1$&Y7],TT7P4:`+S&N"R
+M\(HWQ,QL;XBBU!RY9ZLJIYE'!`M]J/A$3,_RB2A"L!;%55KK%Y$8PR\BF3F7
+M36C.91/L7#;Y3_I%9&\O)U]7#IMD_=VDEL8N>(TS5*3PNL-(MS=%2M;)6:%0
+MY@[GS.L,,5B+4D_:ZN6%#%DP037WY(64>#H[_60*5;=0MS,.NMH(:&'E[)R>
+M$10VZ%@_Q2#T`IZ#3KIPD*,$.2L/)=^)#_T[_*FK!4<':.=\YU8#JG]QH[3M
+M*@#Y@"NU"4S'&ENEH\:^NGBYT2/?^P9CQ1K;`RYYDS558X/FUPBS.T`#%M;`
+M:(S2(U=1A"-J/`2T6NFHIL8-\L\TC8=B\\IW0MM_V6"!_QW\T\CM/Z5L?9K.
+MH[K.O]V::1^ESH<OPAU(Z5'7UX?INMV`FQJ;1_[+5N3S01V*9CW@3'4[]QOH
+MCVF47_-:>>,6+IU?$_3=_1W^_0;?!%HHS+/9F1+.S[LJ<S!14V,BX\*5$@8;
+MY#M.DQ*-EUD54F,"G=_2O&+4\DJ%_,1K"J\DH+9H''Y)Y94-P"L7>E,WHY$B
+M&1FO?'Z$'N/C\:F5M9`JR-[H`XY)LXM6[]6I*E=C&6Q\?1I[HT^KJ_1E=)6^
+M<[`W:&0BJFG(-=EJ7.35`FK<2\H/`5K"[O)]H"0Y:KFU9D>MG04PF@@E&$V\
+MUH9\#"CUR/_8HO`@$W$M2^\NNZ',L'K9>OQH7>K%CQ7-5+BFN04_<F7@FI=!
+M:/\77L@U!0.W--)MW!5&]/]\E1&.8)5*^?"4!K?<LD6YECL(/T'M)9K:NY7:
+M4+7!!'4KU;I;6%VOINZ3Z;H[&CBH^_RK2MW`JW@YN$)3]9Y7\?H-OV*4VC)I
+M%:9ZP<WR\$,=>RHQ.9!T!0M)C'Y9;I-DC!PVB6YKD$ZW//($.97R*+"^I&YL
+M8^2C_/$KRB(03+NTT-;Q/P_!6@6BJR9$Q(6V)@720:A'AF'U%[0GL/<HP8!/
+M,_+P*^K]*'VQN>477D'/.CDWCOTW+REWE3.T=Y6Y_IAXOWK]ZJ6^)7<N]38+
+M+;XE[*<L/>N%ES2.GE[INCQ[FBT8N+P)][1CAW$?IHIB.1_NR?)Y1-4^T&XV
+M;+@2K[L,'6\S38VT,C?I:4UX`JAH[_'87"S#>S&6`5K1Y9K,J52ZSCGZTN;>
+MA7_P(DW+(U^.UW?R;1E?8[IV7KEF::NW9>7:,L7WN2CKWOFA%Y&TZF[)W#:7
+M_EFY6]:WIYOK(EW;?Z>V#VG:?@9,(W_W)\X0RO$_N_S%`O&`;S&>+9^`Z-;E
+MT]'E:"P0+WA,`-KL`IFWD9FAWO='.GH[5(41[N^Q![>MNI4NS"(%GT#63V?[
+M\;X-)K%/K)H.3=V?S<4[N$.W7I05B#ZWOV*EOYR<`U4<T'R`$%0%D*R'ZNTT
+MJ,^_#FZ+_E-CHKQ'VMPR.3D(-..[ZP45'TH"@"JK6&_+H*?CYS\,>@KF(]",
+MY>_/*V.QJV.QB_4EF;'8_N,'&TM6_/?GR5X:D"M..-9.WW`AY2?$-`^O`6%C
+MF@=,!UL#/[7+2DJ"(/PP$!U<>Y'FCDD3_^7Y`OQP6YH?M)G>TN1<*%9VWLKI
+MN-F:B3SU!^9I@ZDGT7E&Z;X>\[8&;F.TYCCI-XOKK#$N)-YCA3_&B_?88N/$
+M=3:IRC:SREJIQ(@[=*L]R\:D?')JG&WFSH/$@D.;66^M;DBWT]:WZ>O;Q#R5
+M<][_/\<IN2*N`>X9O-FNYH$`*5\HDL>X&FLZ06]V;@C\-W_1HF6K?5GO/["?
+M0!L===F"CW3<_FVJ0>/NHHR[8J<TN7.?KR@4JI0:.,=D(9G7YK[T.=7)";5"
+M*_F6&V+-..OKI7HNN,#JYG=4VXV[W5(UYD4%.ZT;8TA52.T<>2+:'-?[KBQ0
+MLX83RZ$ZJ^D:C7T4@BVS!G1(L5SSC#3+_^U9(NK`C0;?M:#LU7)*]-8>"[M&
+M]('0Y*0FKAXZLQJ3T)D->OH:(_T?!MLAKT_]#<]F?.H=%M]$C[P)]J0FC_SE
+M&9;%7.M#KXG_HS2KX0#18*K:C<?!5"V![KHPX'^Q6"I.$1LXS/<DF470C<V2
+M0331_\`L9M$.%?H*Y-)]>?.YP2Y!V`B6@:QF</NT.=DR\<\WL[6D6!F=)WR7
+MPK)HU@1@ETL>2MD(_YM@(6(6=[T\(;,]WRVTM)2YE]V;O2;?/:/Z)':>$.S!
+MP+$EWV(.^%^S#`NP&"G!3OTDE7ZZ8)0FL14'Z^;$4L<<P21.PU%K^-*CO`-7
+MHKK@K,>+DV(7AV"-ITN3:=:U#*=&G#2;O?8-$7.W,Y>C@3B^LY==@)6$'+L%
+MJYKL2:KD'&;A2V`&(4_.Q\O2\\+>,Q/[+<L8*DURW,0)=D9Y2H83S%_@M+/$
+M244.W@<61&PJE%D<5J%(J0/&BU2%J9$GXP<,NAY)WN3@A?%88)$6(/6ZK<;3
+ML.1`O87H[_ZG5=];XDV/C,E58I62";@")LFS[BBUMB%V?BB[NTFL.S/0&.ON
+MN-H=+7;KTA6@22WQMJZ\FQY[+5VQRK>NK(7$3?;Z/Z4&H,+[F(/-@"2/O.S;
+M5"JV&,\CYP$](?L3)5=/-\:!"BX">63&DW0WY^@2U/PP4Q4&L<.Z,(:I9`-L
+MT@\PH7B9M108GAY/O\@,#];0?P<-;X]BPTX"=#CVI-=F6@AE4-XQC(&DUJ7-
+MK6?!T<"3JMQ"'!E^183DA$'@LV:@#ZD<^"18D\%24L&2!;$$9&J!,1*ED2WK
+M0=[!%.HU-,@%G"<?Q2"&"HU-\_[A22U^GOD5X>?E4PP_9LG*F$1=(UZAGS0Y
+MY<?,LKO7-+<N:\9<-<W+6H36I;GWY-U/<(;MRBE^P&'P_5*:O`-?0`(^ZB23
+MP\W!F(X8R4^LXH14S3GL@@4+./J[`1/)&.B&:'QGBG^&3#^`Y)B<23$CA#M3
+M&S)M0#KQP<`%=S*/5;DGR:1[/->.F_D$V7'!P&9\I5'-49P2<X.\]RE]E!+=
+M^]??<P9^N]/JE@(MS&/Z@\W:N.X9^^?W!'PY#%[\=/0MO'$X_IJX^V1?+3Z6
+M4]I>OYD%^UV2XQ?\T/_1]BS04519=B=-4F!#"F@@H@/A<U1$G8"[L.WNNB'8
+MA%%Q.L%.1D=0/DD@0@))5QH'`B%-@*)H#'\0P9F=XSCHKCKN^MT]0J)#"/X"
+M.H=$NC-!V&-!,IZ`$5J)]-[[7GU>55=W=.:,GM#=]>[OW??>?;?>YUY$5\%^
+MJ[%0[I"2[.M.*3?;F2/F9K>\!WTE-WOB$?+=2">/I3/70$>/_\/"W&H-$]O/
+MP'SPG"7,&1;FM#7,FRS,2\\EK%<*4Z_O+>I5P=*9:<WK`8#!4\`J6/<AA^'<
+MMN+8@;<)SGJ*-,,%%D`PG2M/U_A(-FDV+WDG2JXMTFR7E)N9\89C=MPY]-/[
+MS/UCSR&K,]&O[&/D/W`HD1YJ/[131>#W\]>I(@SYK_<Y;#1QHD;MFX,6N0C^
+MC>5W[6!"O6<Q>O^SA=ZO[F7[Y4%+O7_*PFPR\@*_.EZ+%GDOGMY+S-46GVNS
+MKX^F]BZ4;SI(EF9@IN=!QQ@=(!^>4-MQ5`O=8K[_22@IZ<'1(OSI697*>#(Z
+MKQI')]GP^,VS1KJ/Q]UQ_VJ/$N>>BE:K$1U8*+^$V*D$U]+O>\V(>Q^+&^@'
+MM]J(RVFX@V."B_ZF=S42X$\SXA\'&PC(F5(A+\V:*#D:,%U5#K:*5ZM_E'WW
+M9-JH:[=%&P4.F-MH]P'K-C+0>@YH;?'Q0$@9;=FTM0KE6S2"&0K!QP[H=;1N
+M\_S=VJC5Z'0\H]*9@,TNU?#&=B?I"@X_TU^[7]D53SJHD88?+R.)E(3Z?\,"
+M?R:+7YT<O]H"/U7#ITD7\'>R/C35@L:1_:0CC++J"([D_>#<SD1M5[;?W':;
+M]R=H.SW'X8`D^0_-9>0>$GU3U^R+35)6C?3?-YM^9QI_>S,G>SFQ-8>YVR1Y
+M;Y[L=6K/=/NW@TSK4!O>"_\X<=_ECOT.R[M#'^Q0@Q3%IH(E_'Z?A5U^P0AS
+MT@HF2&&@^,5]5G/)(JV\SK)\)BW/>-?G+`"@GS`\V/N?I&9.:X>%K&ALW:M?
+M-6?IG]NN\O]NK^7]'ZW\E&7Y;[7R%RW+@UIY@67Y(JU\H67Y3*W\'LOR";K\
+M>ZS*4Y5R<J/WA3WF^<QF/:,9^\*1!D,;K-]CT<X'&E0YMEC*L5HIIS-9MNS<
+M8]WOYC:@3Y`94R<]^6Z#S(:Q>VM#G`V'EGYMMW'<PJ,O=VLVI=?*IG0\S<PK
+M`%^Q6[=)T^3?[&;L:M329A]\FIFG88C!P)JLT9AH.5-3J&]V]6>S<TVR?;J+
+ML9<N>'!J5U*;FV+"W[E+L95I%DV?A,X[VXQT'MC%ZDC89:TC0WL%MEFU5\JN
+MN/8:N\NJO?3XU]O4OO;53H<Q9Q]/O,%!^MN%Z=U"AQG">J@-9A_51"M+H_5G
+M*UJ#=*_?Y/.KZ\G@I_-2+B_:<6DQ35_+T>-?AM0Z#=MI-7[^62N_N,.J_"8L
+M#RZAOK[%N+JV%<L7F\L-:\7L.C-^5]:(UW<O<=AL3&]_92O="O;QXNYGK\5B
+MH=VV/GA1W;T/OJ.!R-F!=]UP-S]F%QX*O?YK>(Z7`=NVD7CQN#)>WW.-O+V7
+MV9;8X$'L=<0%_V,;]@6,0/`Z$B9.V<7M2*TLI5!>L8W<!GY^*Q0QZTUQ\F5L
+M5?(695+YM*ZV=SL5S(F"+3.*/4T6MUN+/:Y?L:^&3&*#,WNW)O;;(9/81&:;
+M4>9?2C`_><AQYM#K*%>A?!;,6Q+3\0X4AY[O->O"1#<5Z:(]U2W3]@8RX()1
+MN_!3>&%PJ?Q6)N=WOY'?S`7EY17^K$45Y57^2F&1/RNPM'QQ1<`V4ZBL*JXJ
+MHC_,_M\69;OX"3M)^"L,D,\_;;+W9^`!WH'GZX\*F=).W"4(!1\1KL6\H>!*
+M_)!28JWD"BDF=N9I?F>.?CC)Y0]"/6;,X<QHY)*HK:4S<CR&9C)=3%,2O_9+
+MN==:"57"PH!:=7/^4YWOG$S)=W-M358E_$Q/G<VE@K<6#:[C\,1+#A=<Q=F$
+MJP7YBDZRY;>V496X6)7,KS:J1%S+27E.3(\=<"KR*EJ*%SMN_MM,';D5SOHK
+M_KL;X'TC1L\:K'78_".#]X*%@_$QB0Q.AZHALM@F5?/U5X2/%4T_7%&1M7Q!
+M^5-*7ZC*6EP,>JEXJGBQ.?[%9E47A7*ER@NJ?SOF',YQDA-38QK</0)??TIX
+M$-,,Y_!BKK-K4(/8!&84]'`N^RB1CLF%`B)N#"F'*DB-F8[&RXN@J.O.!D*(
+M[VJ4;'0)_"95G\L#1GW"*-<#%6''C4M%R^2CC=C,N>>3QA&[GY,JG7B^1LW"
+MJ^%BJ"620Q<3W$5^P<7?_]_$QB3N$-FX:3^<#X!%4L*V2&8DEPOG<`HC508G
+MEK"Q5R.V\'B`S>'""TVPMG"QTP2;`C3;&\/X-YOKN-#>`E]/X->F]A9`CF0:
+MZNML/QJ&9U!.";,YXB+V2-KG%YCL5C.XR"R./O'@:=7X_')TRQ]09W#M7S&X
+MKHC=C->5$FD36[5YVIKG,#-/BUQUB7CR+$__0.2GX!KUU=Z)&NL$[62B#O0X
+M0PH`%NJ-BCF8@343#YY$;(C8PRD@0!B`S72T]O;P$4.Q6N;")D^Q+%-ICT?:
+M"Y/0+DY&>WQ\!=D8NM!E[`"!^GNO[8/VIK83T&T^[&AI;^DXT=&8B"?4)J4-
+M8,+WQ_/%%-8^%W2M00G*K<:K-L8^"5)SZ'5*L[F"?,GKD.!#'KC%$/\W8FL[
+M#KAMQSL:3?A/J_@$3R4C7Q!U?.,>]OP@>7V0:C*+"N5W`"P\QQF9%X4?SRL_
+M,(@J%QD=>90S7+H>9)NUP+]@6=;,BN4KEA6OREI0N=2_9'FQ?^DB>K;HKKB8
+M&%_7X?FBCC5J3(S.-?I)HQ4;E6-DI>J7^?"ES"[G@13@([-T7JI3SI&M2!SS
+M8A/"!%>88H7.\/MQIZ=X<=S-O;NL<F;EUM%ST^!!SW)XI32O+&Y6SM7C05,O
+MS!A>N1H?>:(=C?"P_2LF`/#P4'!'#>YDG:GIEI^`F>;,\NY(>MNE2![7=CF2
+MUO8U#.Z.WO:CT)'>;_L(.MM[;2?@[^..QK9+[1]TG("_#SO.M9_HN(1GB)@6
+M,.338N7=L5X+\3/+(8WT%LCMFQAY82Z#1\<V_1!Y7[W^H^2-C`4Y6^#O`Q@X
+M7W1\&WF<T_*1Q?>YB[6*G"X@>QS(8D<&,4$<3Y2Q8H,5B<`/!G%P-`\)"U'\
+M?`C&-'R%P3568=6=*#91C<K,B>1Y2_)-WR-Y/GPO_K.68\@R<8:8_(>UQ(5`
+M>DY+>I7?4W'OC8S!C[5<9#YG\`F-=RD^7V=NM\,;XMIMS$8<CM'(O![VJ4UY
+MZNG11#;FH6/SK57&\3E;'\?GC7H#'PKW!P(GLW`;"9S,<@['QV/0UW_7FGG/
+MB^=]CQ7O?XWG/>C'\?X5PUNA(#,*IFS>W6"EW[<VZ,PIW+8-Y!A8`NYQO*_7
+MQ/%>%L?['DO>_Q+'>_2&A/5>H)FV916EN*6-5@T\XM+RI7YA<7%6N;!\87'E
+M799W>1Z-DU%EN#VHB,IKMW4&T#CD/+BM=:2SU]/#`O2*CEQ:BQA,^VG5*49:
+M%OU4EWQ%1:"X,KGLC.]KO(.Q9XT:"E6US*K-_@BL>,2'=0CM?#AX+18>;;YT
+M!'6Y-4CJ\K:RL4]1-1O_8IU2*5[*@Y)TKU)9'%"DA7BH6#@C,J\3C"7E`HZ%
+M[H"YPW-ZE`-MGX!^PC4R;5>`CLQK4XC=N0X;MRWLZ00Z>"0+U[0B4'H^)G3*
+M8^MHT\]K51ZD*0\\K8;)X7W3.&#OH%>N3M3.A]<G:6=%-P>C2CO3UV4B\\JU
+MFF),K1U8C^*18WRNB6=JPO)\\J`'*GYF>5A11J[RS"-KO:)5E]_XGYJ#@(W_
+M_BOU52[[5"0]).748_R>".M"@X(-WC>><IH0:5-._Z@OW.R;]H6M>`M#$7!_
+M+3W"G^>4BE!=>0YIE+<`CXD&:NDQT<:0-!O8A@<J&.G8)?(XF"8OJR6J:.$;
+MF3C^:9'VKC$8XX<MHSH7B,-*G-8QRL0A&^P+V^\//:5>-P0W!=Z'QRLGKO(<
+M&/:L.8]6+8]6[4YR(;G]*_+"P.AIA,4K2BKTO?I3?I8>?ACH1<B%%25*2;.G
+ME[`DV0EL2F`&R8[9)SV=HN^\-(.<:/7(HJ\;@U;@*W#VU8Z0KS7DZ?0N05R\
+M</?QU5A,PD[]F8+F:<.\N@2MH>'J,?)>?$L$1HE'AO>\.3WX3Y2\[,'W$_@=
+MW_;FH34]>5V'!&>ED7CW+?`-P&0*!B.JL^MP`TT;+*:+&&L:4Q"+>9Q8Y,0>
+MJ8ZH2;8[LFRWF>/?KR*[/Z'@)YOPY3W7"2^^WOQ0\"3]Z9`&X:_/-BFG:L35
+MBG?[Z]7*;8F`^F2;^J1X->NKL^/WM0`;(Y!3;IG=J=\Q>^97=`TBC5PPNZ%0
+MOD`?=`U0[Y>-DD::KS%]0^ZEDSME](IBJ`:/=QZB@M76Q&X35H8\O6`!'D`;
+M2P"A@,("H*`!WB%,#'FZ`7"\)>"#`(B!DY10*TJW`;Q)_KG2R%>I3*^F@4Q=
+M,[=X8MFGI'MKUPVS"2YR3VNZ''Y*OZ>%XSA-2L/[652V5X"XD7#$TQOQ=$,;
+M^\+8T.=AB$1NE#SG)9],3[SCP&*#=1GS'6E'L1W:Z6W]W3E1F7[^I=IATX].
+M#)MH8\XZZ0UZ5E`-&*CG3ZBN9D=1""8?^;C=9E@THWP;Y0&:#,'.L2:>.P7Z
+M[K?3C\B\VH<8^R^H\4MCV64VF1]F##ANC'^OPZ[`U\E4+U<`74S""TI'.2^@
+MG[6(5\[4;8"@KW6B0.XTLDSV0L`4B'M/@%W?,I\+/^(G5#!1(R4C>OI([NMH
+M&0__VS`)"LCB&Z*$=W7AK^E#U5BFE+.GCP8.FPRLU)Q(%CGHYOJUL,(J*^23
+M!?^K?/XRF.7S"6_-Y[UJ,Q_F_$N5W@:X-\S'M8%AW^J(!HXWDNT8LRU$-ZH6
+M:F'M+?<5-U8E;3\@,&ZP=;SY1'V[4$]X);C((J&X@F/6O_3[+U7L.N$;@L.R
+M[_]?I9;-JH8G_;$V0U%G;#K\JL1?LQS,(##=_ZI4^Q<!GZDA!QSP\Q_BL(TR
+MEE8:QPK]]#J8_2F&E[O2U)=G.<#@5COD=K^RZ,OT\#_Z33W\O_V&_7\F_^=*
+M-4`K7MN?1J*T_GR8.3<#8_\MX,\E@:^S@.\:GAB^P`+^:U=B^/$6\&=&)(:_
+MO((JG0"3K7C[*`;:`'ML!:6-L,"`QD[>PH(;:>^)HSTO(>TR%=:)0LNK>(/(
+MIO._*S2CD.;%F-4O\Q8Y1'7X(6;XW*%)X3LJ3/#W#TL*_[("C]&?P5E8-3*)
+M#:]38#&BLY-$=/[9R/@QS[2_698KR649;X;O&)X4_G*Y07;'B"2R']-@O?+I
+M(8G[U*%R-G8PM=LH3&R*[,CH)X;^PL2X6_O#O24Q[F:^']R+RZUP"P#UL"M9
+M//'7EK.Y#*G)&EF`0V.*7.%*'I._>GE">?FA_<A[3V+<[OYPKR]+5-<!PY/5
+M]=@RTV2,#.6/G/$X]"R133_7%OPGFSF'J7[^>9D6ESH%)QV<"R4[QI#F\^7_
+MN<DZ_X."XW'&SZ,:[CIKW-B3UOS*;/GR@S<9$T,8\G\^F9PGXCN3X&^RX%MF
+MTZ1]_C:+6.!SK7#L&LY**YRQ2>1D^/VC%>ZYLB2X.M]O;[7`?:&,3@^:H+A_
+M?^MX@T)8^$"9<JT`,8"LBO*_DZSCE^<I\'83_-8$\*-T>1CH/>-LQC-"S/XL
+M;K7KW=1P_G&I>C9=GL3UDR/E.0*+9^SD@YR%GM;IY9.LRA^GO,IBR.W+$=;]
+M?ZEZCD\B61ON&V6M@^%+M?;T\?6GUF1X0[DQ;[[<,(+>RX&.F\J+K3GPR#Y*
+MEX7)?[:$WK7!D%Q*E;U26BR[4#X)\U8..JWAU"1S]0X+_+)8H9R!]1HB#9W4
+M!';'*Q['YLF7QZ68_`/%O\UVCZS.PFR$`\23P;-CR;[IIU_4/[R14W//D/-A
+MVEU<L\]LRFFN;*B;^N.7I:R/O*/,O)?.2[,=TE3WD.HQXG&0Y(?(H>MA2ZGJ
+MWQ3"D`(/YW:>21&@!EQ8N-2?M;1\<?&J^#V3GY7JN2*@+=U\8'`HN'<?60;$
+M6*?B=+RJ7625LX/=YTDI5:XFN^AM)+)"M<91'UM'XC,(PT*NZ?"&10R.Y(NZ
+M^2KM<I)_M!1<A6;?WCR#KCS-("M/&/\8,W\-%5<ZQ*<XO*ZL[OSD+O7/]5<N
+M+2\U[SNN+C'<^:W8S][Y+2A>*117D75S&H""3=]F$;_TKA+2Q]S_A9,21EPG
+M8DF>3+J@!0\RM0<#0EY[=DNPAL,P'`*7\>8LA[MI;<H?[!M:_"4*A*,>X8\@
+M%7=S59H]YFZN_"[8'%T?NQ:SVZJU,R+/[R=G1%!X]8Q(D5RW1(MV_R8,OE!>
+MM%%.*<'WGJO!]WE<0":MF"E.SV[!>"!.FS\=8W?2"V&9V:=">9S;XQ32,#K>
+MVI37[!M.^:EX4T,!3A3Z))]K,J9DX$%43&_KW-C8"5_X2<?$G@)O/@WL_1]/
+MX@N/"T.CC_6/DD8U7ASP-F[^3FHDN3`^E<?=MY?+/NJNX9`[IX?RYN3]I33)
+M1D_"/%SO+L8^Y!3GD*!W->GJNJ*G3]'O446_<SBW1-J$QOY8J$#\3?H=7ZKI
+MMV@)J]\++VCQ]:!),[;MUD4R,L08VC^.Y\LE&L]SI2Q/W,!X"-,^X\6C)H[$
+M)Z(,<8"`2R5$Y1DE9!$157MO"1YD):Y7GS@$C!XVCGC"HG'V<$ER,-R[B(QA
+M:+XY3F$@5;'2@.+Q"[5VLG9(WGX;A90I+=B;H(W(\C`VF%!6WR(4OJ6IY,?I
+MXM^+-5V<+F%U0?9&Q(_I,OZ%SY5XEB13GJ^/V.X<T1/%@%GU+1B^'UK)$UWK
+MP%!7)/#5AMI$#<;%M]<X:QG%.;U$3&E.;Q%\E[]9K`E[>XFIX0`&!`%GYO>+
+ME059(C^T)UY0;N)$7S?FS7!@/\(X4MWY<C5V?*C,2"F-CJN1"9NNDXE]A[D9
+MB;NM#A2\26USIP@3<`A/"Q[CQ-/!9B[D)+VF[_>VKW]'-R128QX,L:&D6:3W
+M1Z@S:)>RI11W=M4-75.4V/23&Z2!P48.5_$'A-:LAYD*Z#:XOZWJQ-#T#FED
+M\)AC8*N[U=]-SF2S8]M%R=J51+S$]I=(V25NH2>P2G*#:.0<&5#/>--#Z-^W
+MR4$6_8Z1'^L=-,`E#2/9X*[IJYX@30\V.PAG\?+`)M"ENTFXPWW9_X42"+.K
+MO8$$`Q].I1^.?06AZX\*?W'/B08NHY3GX^ZYSGR"]8=5SQL_Y;,EEG=!ACZA
+MS9OIJF,J_R<.Z*;Z*WC@4L+HFDW,97XC_LG'-6^M"L\'-X>*`(G4N\[1X&ZJ
+MXJX."S8YNKYIH,;V1F)L26K?2<=(I\`P0VANF?2+\?N]98^CF#P89-5-`@6[
+M:YSZKRA9-B#SO]CH/A%($4_F0R?OD1_[3A5K3@_Q3%`R#"N+<W::>+*+PUAB
+M'#0?2?#@$%N[1H%#"(KHRI"F3,@6IP:/.D#U4`NWKS?0G7S2T+:)X^W2[^;3
+M]\-I.$N!G-,P8!;X$$)?92H,&YBCW`)3O6ZWP%2OMZ!0WD&S&&"@4X[$<W:(
+MWW:E4=D5RT`Z6P_I.NGB=S0?`AFNDB>J5;U;$I!K8+9[3D^U2YIRPU1Q.M0.
+MZ]CL@&>!;O=I_P-N7W?U+,1/$=.Q%(I\W8%+75/QF0D'"KK=G_A'(4$2E]@.
+M.!JY2W@<*:E)(-%)69O`ZJU\WM^HMT>C?Q^]W?U7Z.WNOZ_>V',<TQXC&WV:
+MZJ:"WMP^1E.RV\<SFB(;Y#S8(GG255UADJ\[6"/_`)VE@?PFA<F*PJ9@_>XG
+M.KG:.L%.]:)5\V+73^.?^^3`1=#,",3D_SJ]A!/TIS&_)+8DKDL)?:E"5!2Z
+M#4:F%XU,_5::Q2RKL$@>?$4Q)S0&*-;567?A,+7M^%YJD\N(^GI@3BR2.S`A
+M0#.H%O/I<72-`1S50GG2`C35/6AVWI^H$')17[4/?562A"8?STLM(+YJ3.B1
+M?P(CH>L7A`^0#A+2)#]$KTT8;>*1!W;\CT]0-U?IR83'@YLX$Q/PBN4#.`WT
+M:]@Z$_J\)QXQZ-2@PJC8D^,MDC_KU<2-VH01A69A,U%8]/='PZ`&$<`)A'=(
+M,O]]VCD0).C*;#"47$?9CJ)L_4O>S?0%]CS&L$>8>27C#0P0+0T$SST5_?<H
+M<0>'P_16)._Y?^;>!["IZGH<SY]'FI;`"QA+U0I%4&%%;165L`IM;5I@!-)"
+M6N?4B4JGJ`@ECS^N::MIE,<S&D6FV_QLSNG&-C^3*0C^0=N.M<7QV4IE6K5H
+MY[KYLG1:7%<"1O([Y]SWDI<T+>S/Y_/]N96\]^ZYYYY[[KGGGOOO'&)VZ!/6
+MSEB%QJD8GNH4!@_H4$\<T,PJU$9`Y-#Y>G1/+K]'0/YA3T9@N3DQWH`)!J)`
+M<F1)-+_3,KM5[*36C`E#(`"QFQ0!L*"AE@DC8?A6H`'0S0*H&OG;A!V]F_.`
+M#AK[^/OHWK^+1/.!\(4D+T#%"H)+!0%2`DOO0YF8W09@5958R$,WG8DX,)]B
+MB]-,SD?,07]>0V>=_,/>R0'?W)W*V8+,8^SL$M@?4^R7;[($RO50WU]\3MZ<
+MC[6&QD%+B(-`!D&0YU6Q]>U/Q`A(0&;9-K/6UT>R/,Y/6]YW!].5]U4J#^>3
+MGHO/I-3P]""9D;Z_,(@.1^04LV/`"/%&IM??;TZ:FVCY\$QUPK62UZJ05B/K
+M%,(T5#UWC+B@%@2E1-52HD#(]*7W)ZJ?9`,NK&;K>FR*8_#PB15'^=`-7/IX
+MAEG5S'!DF?2>:Z5)J#+T>/&#E#E8<GPPV&%`"4!+J*WN[U+AV$HXL4ZEC?_M
+M3LN`V*<C&/#L8)P!XC'H[](4_C6J]%#RW"&Q_P^H<<4&,->/LPM6+YM6:P7@
+MR4\3`B`YK?:L3;S860R%73T8=^MLG3U8C``+8?##<$[C`D5/M'X\;O8[+M#^
+MOF_@QFCRW%]+0]O*T])@4VA`_[RH>N9OFBQ&D(:7/D-WN6;%7>Z89'`:,D;0
+ML.#T-`3_-@H-EYTY#9NO3Z)!0\#^%:R-W59<PV&$</9WF(M3P21EV`LVT9J-
+M,&WVYZ42'Y^76>Y#-=1>55TI3[Y>O:>;-"?(11<!EF*R]>T&_H%OXH);*TH'
+M3*-E\=W6S\:)WDB%Z,6Q3G3TTX"$,TAA2+(]\/9?J9<+P8(6WXEIF\;YN]FZ
+M@'6X3<_['P'J#_^U!/W*Q2"G%T:Q?C[P)44<Z,>(C7/WBH*,_OBE*84'4W%8
+M`(>P'//_!72_0^80!XR$0G_]_X0HNIQ7]GTR#8,0H%'4+\RWG^`#/V3CR=8N
+M])4N6"$[&#B-@Z$'E?4!1S]P1-\9;HS##``,%+QQ$/$[HHLPKM)7T3;U0G%#
+M@:(W1"_0*,@PHST9\TPN/*CDVZWF4VGS@J'37_\'5C?)MK?P(!3=,$DMIUFE
+MA7HT6%/:&&4P@BS!T6-:<POOGTVNK5L_98O/,.6*BXPW2A-GNW731$FW"(,"
+MC`.%`::1"#!1J>A!$4H6!IF*/08JUAO!!N*;F^%#03>(30;:-LS3VUFX(N&,
+M"+=BH(6A9>&/@G@N"T_N-2WBMSY+'(X&$.<@C*^#.(P/O3&-\7$D+N^0WQL1
+MINAC0`+#Y7,,1A=M^4WX1GA&I@^"I04Y8IYLR#L9QVPLWM//BM\RJ):]>0Z6
+M:WM0RH+OOA,`STIE17AVLR*V#/K:`/W["C?EN$S?-X`^M%D80$>N-)F65J)B
+M6[X[9Q$&4<&=@0#'8>TL1J\5<(F1V5W%HL,"DM<\;"1OZ+IV_VV`%WBF+NL*
+M662(XP(O+9+BNT59\&7`^J;]E`>77JQVIZ4^L=;D7X?Q=`4+MJDP@,&!4'!E
+MR9E#HR,(6@Z,2:+0!W6D'M>+4P1A$@8.`X/:\K`8N`Y0AQ=)0J]=&/#.41)L
+M#TM.^>V_[J.AHA,_>A[F8&S]BSB8V2;NH#PV!78NP7XJ[KF.(GA$J)P>L')(
+MQHY@I#(PW%%X;=+<O>%K@=\](-!85C_>#L*R^C1E]2>5Y>Y"5XM!!78NP7XJ
+M"ET,B3!^'S9AON-(.!?[8+'=T2-<+#F.^%KR\AU];TREU0MQT-_2,*G#<8A6
+M,5K?OOM0.(MDDCX`^T2A,YY'=+1@@#,G2.@KXO[;$<!Q:(8?*V=W=/%^D2(#
+M#8C.`U`G<<\-5.D64&2O`S,"<Q\6]ZS#3_LIP6DC+'?!<Q#UD!^?N)B?)?;8
+M`_C0.-GG7T??'0>H'0XP!<S[G\$`4-A@5FD_85TH[B?>?PU=FSL/>`ND`'V?
+ME-Q<![!=1K88^D-D\(6:)J,&&B\1D=*4<'DP3ICW$BEPEX)>TT*4AJVA*2',
+M(VX-L"3TV(DY@NU-:B+O$7$_WE3RQQKRPK,D8@$UUV74"_.%U\4]E#[<F$5]
+MC^)@TI,4N)G9*JP5J#)\\W^CE>7L]'D[=?Q#>%4^YI0EA\RZ#K2VC&A]?FS!
+M:,Q)<V.@>0^UZ%6LZB&\^P/RV&OW#GCG2H';T_!R("TO0Y]\B4T:5/)H^1DZ
+M]"6*A'6YZ-WG[Q8RH3N'<&LQV.[8#=W_YG^F^]_,NO_-J=U_-W3_W=#]UQL3
+MW7^7VOV?5[O_3K7[/RMY]U&W?-KG?5XG3)2<NY3N[WPJ[)"$I^W"+NR/N]2^
+M_[R&`;N2^^-32G_<I?;]Y[$_/M7A>)+%.'S:[MWEG:RD0TX%X$E5,SRN:@;0
+MV<\B+<).13,X*(;.XW;O3J1EIZH;GM70LC.9EH<46G:JNN%9+.HAAB2N&X*D
+M&W:"L#V.NB%(_?S9%-VP5=4-6Q7=L#6N&YII?']JAF.KW?$0[W\(%8!WE^AM
+M@H)%UAE4I,6BOYZR@29X0]RSF90#Z(!'Q/V>N`[P:'7`XPD=L)GI@"9JCR95
+M!WP'C^YBJX$.V)RB`YZV.YM0!VQ6Y%;;;$UCZ(#-BLP^G]`!SY(.\"1TP.,)
+M'>!1T#][)CI``RP)CZ?H@&!<!\S0Z(#'51VP!YD75P,93`U,.)T.<#1+PCZ[
+MT-Q8&W,\#ZS*$Z[I<#R/TAAS0*?8!;I<`BWLC<LH\FT7'YB%$72PVP"?]G(@
+MHJ%L5`?!PW<_)7F?5,Y89MSGQ#`S38?O?C)TG/5Y1I8%9**9UM(D1V?@.1=\
+MT_JK>)S9"G1J4+(R6T%:Q-%B0D2:)RU<+K+F+.;0XG(,^8?YP,L&G<XHV,0]
+MR,39I\2(8KB]"-_;:8S0*;<;!)@OV!HSV$?0$)3&^S-AP"#[7W0/TEQ,!/U%
+MK4I]3Y;<0Y38SV2`M$2?W3O8D%'8$KZ9UDL&L$]2H%J)>S6\E/J7#/8E5`,-
+M1OCZ""C%M^5PH?)>1.^?L5$N+GZ45/\(QR;DXVG@D]P1M/Y[L4$R139:4*X9
+MWEXP&40,7X11*P.V1\4=]=1?9CAZ88S@_1$R[L&4ZV(M:`E8?B4R6?-&16\S
+MH!;=3=2_',V<S]$$':D+!B*[LZMQ@M+ERNV"[%5ZU2`J3F^_W=O58`$[0*?&
+M6I#<34CB(985TSH3:5#,0M';B6B07RM5?F5).X@20[@$T@1>Z01ZQB>U`]G3
+ML0EX]*L4'AV:W@82-<-QR-[&-\]!64,CZ@@,<OE&'.0&),=`?)`;8(-</1OD
+MH-5DNWNP(;.P)=1&LJRT9X"TDC[TWVR\DS%>L$W]2F2&'B-XY9O]3)LT](U3
+M;!QTVY:([@,2*3%&'4P50P]A<*%V@APAN7<QR;V+2>YR/#'#UG1:Q.,TCKTN
+MN0^0M.X#BYY2=C,52+*\R^YNP?:ACA[^%K7%ZUA7=PNR%43(_7S8)3GWV9TM
+M4%=GBRJKKT/%O,]C#.SD;\F5;4E36='QO"+".U&$]3,<.T7'LQV.I]G(M\_N
+M;<&13\VJ%/4TC(Z@(YX':+OC6=Y_@D2Y155&;A#W%T4F0!@+#T:OB.C=&F2R
+M_!#(\E:0Y2<E-U3X2:TL[U-E.9<LTMUVYY/(C\<U\KH5Y?5QEA73@HDT*`?F
+M74%$DY#EUU&6V2"0@;*\3RO+KR?+\NMG(LN/HRQ#)WX\+LN.IZ!5[>ZG&E?%
+M'*]#B7E"48?C=::L6Q3>61X1G<\GL94/O(;*FC7MRD<YT?UTZ&<H>8?O!FOG
+MZ>%6/2KJYYFB?CKT,`EE0D\_I>CI(X'G;DO2TW3?#9?#'7F)!0B:T^7"S$.=
+MUF%X08O^!$QFQ$XVH\.3(3:=YP*:].UH"9\3V!0#]:5\'B\.YCLL=D>$%AQX
+M?Q,-X5TP7?X>A40=@K\NG6KW:2P^L.RZP++KTD$G\9*A-P2O,!?V7Z,G46&:
+M':A15+LW%_J").22E0?:_8BBW9T1IMHE(4))O8H>P+Q1ZAM'PHMA3@5Z'>P'
+MZ-F*+3=`<RM-C]?:$.,=72),M":EPA\ATWJ"Y,Z1;*_BA*T8]\[[&O+1(=#<
+M5YAIK,&:(WE>T:+L`L,A&11R"Y->)9/`W2NZ>_S=#=/#LP(5>KNC3[A$<O22
+MM26K)IS0`]9"IMK<RIS!V0/&@N.(!-B$(QZ4\0NI3U4`\OKQ,3P>T(^ZDG6B
+MY@]`9&@+(["Z,U4^<!!'+Q82VPN(2E9I\A(\7*:,YT/J(#Z(BR+>\R2W5?^Y
+MZ![(QT$)`^+%/%-I]2D\);`L!NU&G\:+G?D.:T)*/J%C(^J0?YRBIQW1J4[M
+M46U:42*.Z#&&&._?QP)L@ND/Q?D^GB:Z98P3-Z!,_-T1$H4^:"SZTHMMTNL=
+MW^'H494`QI?'!NNQ"_U>$S#H:Z@#9-0!T,NX7X6_"GF$?M`!](J-(X<Q-AZJ
+M5WK]*[2VIONOI.[_L=@%S3K#T0,M"[SV<H#9A&+'O0(?80[MP;*FQ=O"5([E
+M*\V`9IVV&:@-\C1+EED+\<#=9E)Y9KN>;SY%YCB=?Q!QP9V=*0&;#B/OY5>8
+M]8/0B]&W;-1N]^!"JGV]>8-26CM;BQ*]0[2_QOXGW]9#L9@!-+:>6P,`0[1$
+M-EBS!E<PL<'[*^6S'&SIM(;S'9BE[,_T*^NB;13XS]=BKEZC<U55RI^4L=T]
+MI]FXGJ(`>,U&/.4P)&7F+^?REP/&/EI7!8LD4/0@+:TJ*`=5E#&AKZJRND;^
+M?IFRQS0D[ROF=*'?*^N/7K-]DUF8!_0H.:.X602(DPBB.IG7T(FN/GDYX`H]
+M3`A8?OX!.KODC+):JL@"14JUD+EJM6IDJU(MJ,TFC/R!]:LT(^L7YF_A\K<`
+MSY1JQ3FC5"M>3:I6376E?.!:9"=NW(AV&EMQOR)7FI3F"`H40%N)N&")C3>/
+M[J8?T>PU%&G]7Q3%Y44PVTU\\U:#5EX*NLD_61;>OA:B=M,FFH3S_EL(*BY$
+M,`\TEIM1D+HE$XK2/,]X].D%*,M!FBA/\V!::<I^ATF38(YM3)6F=AIO!JKE
+MWY0R:5K.L7.QN`DD.@Y(U21=G<2S`5HR[42VM3(V"@<"<Q]0VS>VR5Q571D3
+M.N7-I:Q=8$#;R!GQK.4!)JDH=,*0-)$)G>0XH,$KTU[S@7@+#:HM5`GM$Q-D
+M^8+2N.`M7`!R<S;=]Z90*7AYS5YA%I9(RSCDJT(\2`]1#I-ASP-`19^&=.\!
+M%3_>E-IHKJJI1(G<7P*87R,^6J1&8!,&3+8W@&#^A#&7>->#Y:3PB1T88CA'
+ML`>#)U97UL@WE:@2*VW"Z)PCF!--94X/,:<KA3D]R<SIDL>5,/$%VV$!8AG[
+MS`-)'X`6D.3N&W6O?NK\_\LSSBGGQ7YD9[N3Y*.HX*!_N('V@S:P,[SG*>@-
+M':4,?2E#S^/9P_G*1['.'#^.%K\3J]W_LJO;3TQMZQ8%ENAA>BRVSWZ':MR-
+MK8J#'P<#/%L>`QLFHO^<X-/6-R/9FP`N(N(17QYWW9=SXJ84ASXC:/KY/-R/
+MMN+5`.BL)CJ9AX7AW0M;I3ST"6WA8_`;/`-*-"IFG(G.&FBH/$DRFD1E;GSH
+M&M$PDVE<%<SB1+&!0VJ7)?O$2FT?_;SXO5'@7^("4`916B,O04K;H.&ZJ>&L
+M2L.I?#(E.Z@(3X1V6Z!\$ZO-\<NM:KMISV(\<+4:#YJQB<IE)QFAZ"KY]W_!
+MI33_P7I.,AG9&4>I8/;OD%WMCHA.VZC`F@BP)H+!66P31;!(F#`/);'MG%$:
+MUT*R/"71L,F^++3MVGU5/(;U1M3$BO)(:MPI2+<C(FTTLY;]WY<]#8&%5\7;
+MTV&-K3-K+V6I;;KQS_]K;?KBE:/P1].NQ_N5=C4:E_TGFG4TOBDZZHS:]>1<
+MYIO'1#2R#AL3K/*F`7;6QHIZY?]U7W7/C;<M:TJ5RL/AM`UZSB@-.N',V_/C
+M*^)]--Z"D@'+K9:_$?[_1__4^A^Y'.EU*K<XD;4F981'VXDUH>2P^5N\DV#D
+MU+?C,0%HMC8\HR4ZX'D(A\>H71C:,,[NCFQ2ED8^H#G5$#N*;Z89D\5HPK/A
+M!6!W^1R#8$<,P<R9F;D,1.PPVJ6K1:'?U\'!!`KG*819WI!)!P+ZF&.G53`!
+M@EDXQ5&"J:S0*SG[-._')*'7+PSPC[?XG?W\XVW\R]WSVH0Y]YW"-0K<#QW$
+M\W=$PGTGZ)M9+33FD&..OO!6R2'G.X9`3F0PNH@;BG>,7_\6%ZZ112AT74D\
+MS=7P],-"M'U',K2?-+<TCS'4*@G]R-!HP#:/SM,BQ]W1@H/PW2Y$-W#VDW4D
+MEKR_1WNS0</."+)SR.>(1-&L$0:3V0FE&1=@Y09\'5&8IN(JR:`.=_EE'?]?
+MR,L;\7REAI?]R;P%7O;[A2'BY4"<E[-\I_3(R`@RD@KWG=`S+F)!,>=@S"F'
+M'\-UGVB^8]`%/\7PSR#\H^'EIK>TO.Q)XJ7V7/MC!4S/,'9B3'=%.!'),[^E
+M@8,.J@OJ,1868<L=7:),R"*!,IB0.8`Y8!QJ#JL5=MO=T8T+V+F%0@_:WID9
+MJISX'$,<(0H;@_IA]&T]`8\_X.2_"6-V')9+(?>F`S1W,L/<"6O1G^*G2SM_
+M?NLR-3#(-J=MJS.B5,AM%@TX2;8D^<B&GD7R]A8=DU4.L/+-]Y$C'/*'0U.8
+MPI8.AXQ$%L:@OV^S3=GJ[F]W].GFN2.>S'GN*+^C=:NSKPGWF6TQQ\`V=S^D
+M",;Q#KG"[AT2,D13>`;(W?$.7/$1K*+)U\[%<8:?/[Q:#O^4G:7%L[57,FIH
+M+<LL3DK,_N+M-D<[_[LT7E_TSQ_9YL[9BG'5$[V"70$OY])5?Y!OGJ:/5Q8O
+MB>X]"*6;@`YTT?%S?$'G9+2_(\-TBYJ^O\-Q!.$+#U(S=P`K<)7^@)7=(Q+Z
+MMMFRM[I[VAV]8-0CDTS$)#J<M,W=,\\]A"N!O:!;>W6>29+[B`0:*AN/&TP,
+M;\0S3P,$%1'&97J/A,WT$A4,F2=`;8!B`14E\!)NILCBY9*[7\P*%T.AQ]N)
+MO9>H*;XV#FG&='I,H3I4B1LP^EAH,?X"[UG`D;V=K/X#5/].5G]L@LYDFUJK
+MAZHOH7MVVF:(S\"'I"G$O$%<MBD\V.'HUREG<NS>_@TK@;SAMFG">-R1XE$A
+M>P>W.:*XWFO<YHCP;[1(U3:HA;TZ9U,.NY1;+3H'Y$LN8[[5G`.@T22OO#4C
+M5FX['(HY^L//!95NSM:6YFKH_.4<D!6G9:OSR#:G=:NSBRTQ%/C:#=6QEU"7
+MR?\`:1(=AP+>'L`></:)SE[ZMR?@[I-\.>RV"T[[J^0L(L&R!O(*A_``\J.%
+MZ+*^EXYY]TH^&P*7YDKN'LDW3T_/_!N.+HQ@<X0%O-J-2]Z^(O)T966>KB3A
+MD#;#"$1S-=]SE.^EEE:9QY-B,"&=[X^!0%6XUACY-UT%%+5P;JP+#8F6^/J)
+MQO]%OM8G&*[C79SP![;M4KIMICC_\DQ84[BFH!IO%WWY)8ONIYXI]0W,T_!X
+M27XRCTD+'6*<MDHE8//:VS898-JX+L[TIDN0Z9UGPO0=ER28WHE,SRTX`Z8?
+M<J5POH[<RS/.VU3.=_XO<?[UI/F_UB::^A7U""[Q2M'8VYPY6YU#T'O0821V
+MH4'@F!%[D$DJ8&<TG0,8VQ>72F2E0Q7&.D#;*&N%SD&[LW>#1W+V#K=.$Z;@
+M&9=,T=GO<PR`,2M+=KSLYI25#?#SM^%2:']REX/^MM$:OB`8!)X-L?=--J7_
+MR;ORJ?.A:1;<:L".=W?_X<]BCMZP/ZAZ14N.?S8[5<YF)^3L@CE)<L:ON2XN
+M:;\]I9&TM'$O-?._69P2[A(4+=X?F"09\"HGO[>*LW<U)L6JG!#P37[W"W0O
+M,*E-4P)>`A=N8??`\T86EV+SKYI%C1>[6L8=,[$=&LM8@:>9)]L-=9KXFE`W
+M*')BP.?!(@'\OUJUL8^A4!=Z,:U;FZ[(E#+_=C&563A<(\=.4?@!X)@M4,&Y
+MY,_4=U9]5LO0NW2F.S^IQ*0SZM]'C-MI'J0>4\^(72Y?\Y4TL9+N28$5#8F(
+MG6/&#=#&#AX]+>'_[F*M_[L7STWV@]$J<QH_=GQ*?7Y[D>*;JWX4/W8_ORC)
+MCUTP<X0?(:W_YXL2OKOJ$UZZILU.\=(U<7:*'SK-_8>+DGRVY8TL+Q'_Y:*X
+M[XXM6:?QW?&G"^.W/8^.3^.;X]>)]!-9Z?QE/'.AQO_6FHL4#UQ73AS-[U5=
+M$GR]`C]N5/C2)/B;%/@_3!@-?G(2_"4*_'.CPG\\,\D/UR'+&+X]7IZ9Y$>(
+M1,.TYB+FA:AT0JH7HJ2\]Z;-6\_RFL;.NR!MWIM8WK<L8^8UI,U["<O[\-AY
+MVV<D_!_5Q_T?_6S\6#Z3'HOG67.1XI%KEF4,'UNW).#K%?C(^#'@+T_`WZ3`
+M=XX%;TC`7Z+`/SD6?/<%"9]?;V:E^OPBWT[\WF(NM1]]_P*-#YN/;$I/&7F3
+M*EDOK+Y`O=3$!WP-1Y6[''/PB,OQUL\XNLW![S78.^HS^+VE7-@:Q,-:/+^W
+M[%[3VQ%?GUZKBS7^WU@=P-31H[F#?A93_,S\2_YB]D[7^HNY9:;&7TSR?96'
+MI[,^17O@ZV#8\DY0JE<I+]?'*Q=5*V>BRO$CZC:8IFZ73U?[JW_8,X&YE@E/
+MH(UJ]O+81)TNU9>EAK;/\S"_14.;-4[;2S3[,J>2-PKOQ7:@@&>[O]"7:I&(
+M"?'7\0H9K`YGX._FZWG*&&'UQU`<'OR(Q,$BG\]._XC98@.G7<I#,V.U)]7_
+M45Z2GYD//OKG_,QHZ#DXC0PANU2O=3)3T$VN3BS,[XC![LBI9RY;;I&<.0'.
+MB6&CWK2F]3OR)0Q!"5\;$_K(CP42F/"U<=4%<?<5=\Y`]Q4G#\NU8KD!'<EP
+M0?+!ZLRI%2?"CZU67,;A"I%5Y\D,E)OL#@N;&9\;J#:!``,MBA\+2Y7\R^ED
+M[M=2R*2IDB,GWV'5M[ANC\5PW=8:*%MF<LDG+B"@@A:[,-))C&<ZE^H+-UFN
+MOC<5[VAI_,#4)_S`K,%SB/\N;\Z='N?-\@LTO*FEA=[0EZK-KK2+A7]HGW("
+M,KGDC'^RW&?R$OY/IB>W26"9"7L1NH(Q4<%Z8&H5NN.Y)H]X"1]K8:Z&#DAJ
+MP<(\G]\["?K>["Z5]X&5U:8JN6EZW&',!,@7OC)(^\7\WFR[V])PL9J#6D]U
+M.W6\YT)$X`J454/3+0`,(!,6$(WD>/')>P##N6AXD@'F-B=$FCDE&@>%J7Y[
+ML!F%1<2Q,V73MZ?%V;0K3\,F16[12XS24N0I!HBU.\UHSYE#OV7MQ._%>\HC
+M.EA4\8FT'H]J)#>E^9^5H7>FQHD<GY?<EE2JE?R#3V7N8=!O#[5PA*Z;FUCY
+MNKB?GZ]/):9'@>G(>J6=$VY\XOX+%,LW6^)AME@KE7*U]A).:.3WHJ,<F$A2
+MQ2.X.&;"6V8FT3MD=T8;BP$W7LT:%-_!^VR.0;&5N8K!7BD42XXH^M/YNN0>
+M-+J':M%Q]QQ?FZ$8/C8>"Y=27XA@_@$E_X`V/YTMN@#7?"/(XK.,[H$@X9`9
+MCFCC,>5X45^B+GA/CBZ:0FUXM2)UE:PB5`NZ*7>UK]U$(+Y64Z"H6O1&Z)C$
+M%JA7$+5+9*/)[ASBGT`RSJN53+YV0ZTTR==JJ,WLJK5W>3X`TA;369U!NS<J
+MY+`U,$`XI58JAC)+.7X[$L_2ZRVT781&2?@L\K6548NS8M7HCU]-2]RW1!II
+M]E0KE5,=-I@+6]A->'XOWO976H3=^C/1>7`+^M<Q2>YHP%8CNH<"1<M$[Z"R
+MWDGGY7"OQRUO,-F%05:U`LD+K<W[.@PB/F`UQ;=J,]MJ17=_K;U->*C6_I:G
+M`U#0ZNT;6-\(UK>H<)B\&"I<AAJ+CGZD<M,4[*H#H&!K)411R3&O0>-HX5L<
+M#,]2<0!/</MI#)[T)GA"A6&R7AA7V'+PUT'T_`,F"6BGDE/VM^J`!H.O[10H
+M,*'/_M8&)A<)/^',E]`DM!'0\91R)ZDA?I=1)Q4"X\"2"'#EZ+;;:]$+A4&[
+M$-U84XM.B@R%!]D9WA/\)E.M>OGTH^$V/;I#BM3B!=0_!E_1-3%?0Y!OFI*O
+M!=YK_8<%`M-W%_LB_,;/PD=1ID$'QL<IC0+\QY3X;.XC<J*#JHG4ZN,M8GNM
+M[R_Z6G$3%Z@!<C,"7&FM;Z%.R*SMJ##A]0KR_5.+SG\,X2%^[Y3`TAJNUM?(
+MZ82I2+^_NP&4@-[7BIQB#7/!DO`G025M@I)V32RFM-H2O%=;*T[1N@D:N2Y?
+M.@77`6U;89Q)\1842?(6-$0*<S%'?1!T:2,GXNT\,XFR3)\6BMXCDG#$?J(>
+M5)M<C?NJ5RJ.9-I`]P3FUM&.TA&[4VZ\EEP'C1/=/>%,D!_J!3WH;\C9A]>%
+MG3W4GX\P7RDPTR0_=X(%NPC>^>O%"Q&4:$(464&\<Z7@&"`<1S0X(EH<9L(!
+M!?4V>:.7"+AY6@9/97SS/##B&[/A^2+/'$SCFW\`HAAZ&,_.P_M-?'.6'F,9
+M1.O9?=N0QT`R`TJZMW8&%FJM%9=SX7-(-_;42IFU,R;6BED@2SY'#\@X=+DC
+M=F]/W<=XU<\ST^[NYQ\H4'&8:D4#0K89X/NFST)3*(%@+`I,!_PJZ7\/':=S
+M7[62M[=VO+</K*Q:<8M2MA?*7E@[?D&M.%]3-C)>+3N/\.[6JWC118&"]X?Z
+M>+F/ZT>A[=M*V5#O*]+6^XHQZCV+<,]3<4^L/7Y8`6;H!T*Y+(W@K*/1<%S'
+M:'#TUA[OJIWA8&14<*R>&V:R/,?Q@FKMC`PE,^K*'H49OZ_[4$//3IU2SH+:
+MX^\JC%/I>4B7H*=)-[(MPFN1CCY&1R\U10G'ZHQT$$_TE*I6HM4@.GL4QIQ0
+MZ$!YV#AS!.[)(^L.)8"E%_!4@G[8DJP?8!0853]06HI^(*9-(>\_G1H=H5$0
+MT\_2.`:)SZ'ES\D?`DWE?'_A-3/I[%K?O4#3!8$*]$DQ=TAQCT`0^Y1[ZWVU
+MF3#+2^LO_\7)ROI`K6^>SF.#(<8`MBD[`@:6Z.YL2#;5=A1S:._14)/8W]#.
+M%]9,IKA^HI?YE-32/H?1+@G1UD\3:P#M"N6>KS!O&O?^'>\TX?XR#"I]K(9O
+MGF*7$SO$2.WTLCI3DC^1Y/+_.BG)IZ6V_.>/:<M'@X>5K[CQT*/7F:12$WO4
+MM86:4D?X:=HX:30_%O&R"UC9>,,'5/D`-!V8([CC"E2PZIN1F%8Z#\#['U4/
+MMP.?K#`[!ZN%T<HS6MV?JTQR#H#QBJX:Q38\B#QE'YO[1=_N>Y.G*X<1\<2;
+M^.WM6"T:H,*`,+YV>J0VTQ"^#&4^$Z4[P`DFYG33J`?--E2;.8^Y44GHJ+:Z
+MH:28@TGUMYZ^_H.GJ;^05/_OGJ[^Q_[=^H-6F&X(SV6_"1:([<B$0E`K0Y1D
+MLG^N\H'IAL]3^*`]<[26/RT?9GV6Z+_81Y`/D>2:#HT4S5IR^L(F*B/K&HG7
+M=2BEKE%6UT)#.!_K4)BVK0OGH8[5V$"JOR1U;H"7M2W^%JB2`ZK$SH?_EKH&
+M->8@]!<\,H/6*+_7:C]<GX4&:NCG-!],KIK]G?I)9+$*GD!=K,,QQ-.QYL$`
+MYU7J!61-&M&&2?6*@"4NG%4[PU#KC\2]-1=C_69@_=">G9+:FMY(K7^!YVSF
+MH])&XXT*&X8F/8;N6^04OR&E>&Z%0U<AO#H!XO=.!,5B[ZRWD;]AAY7W3\)U
+MOZ[0A7HJ+3ZS`''E-F%U!M\^B=XVO%8]Z]7,)O8.:8WBR>35Y3"D@E4<<PR!
+MK5L.C=>P".@.%&U2_(3`7"KAFW,4'`$M#I]CT(!X&ML2,P7AWO`MBM^4VQ@@
+MXMDX0.45X2$=RWJH+<[!:J%GW@?6M.<\I5@EWQQMOG@9OV.>1VG?,IO-%9#/
+MXF!K'V<$<C*4YU0^TQ)VPD5+.;$SP?>H-!$F+3AI6\#OO=H^6)_+[ZU`S@N9
+MP/7SR4@)E(,D17EVULH9J94L6VI%NJ.5&/?(C2:VP8,:/RLP1T`G(N1H);L6
+M6>QW#@DWU.H/8OYEX?>QWT/=FY;S6_^;^DPDP&T!V3%C^AN\ZOLE/1Z;%H^O
+MY=3R+>WA-6($>*`?#->B#-[GA7[MR0$,-C67YT,UUY8!I>S-5V*Y-BPW"U-J
+M[SL!N<ZEXH/Q?#])Y(-)W?(MW2/\MVCV/[+B>R?9-+]K]9P%LWT#D.:JEE?!
+M8$M[UPJ&].<8[L\:[1Q#(;\W.U!?S=$$3&LC9?@Z1K61*&W$'"J;A(K?6U#>
+M^A=.<PQEK>6,3T3X+"DG(K+X?^5$Q.W&__L3$2-LFXF9M+T-@Y,%!/J4LGF5
+ML<:`.R(!QRD\J\:'R!E9.S;"4K41SO\WYK'9<1_B\?-E6IKN-3/?G40+#<EB
+M%Q`7O>]CG0Y0[8W`*)?ICJXQ`HV&`#LN>*>LC-XI9/Y;\^UL.H4UJ#T/K#V#
+MU9V!\CKB%`FMFM(YNE&.OTV$=%!'Z'*L3U9M:COH^%HZ64)+-.V.`5UAMW)>
+MC\Z\;^.RYCDB0F9MIM`?QO%UGF-(R"=IWN8<F`?6S.-MM?S+W;6BBP,5[IDJ
+M#M8N0H-CO*._5LP(%\]S1(7,K8Z!4KM[4,B"7@Z?^?#LX'`;+YRGO,*L2D-$
+MS"&'_<%:_7"(;K`S/]!.N58TC^R4Y_];?5)[4#1)KZPUC7&.Y?K,E',L7XF?
+M8QFOTVYMC3P'E&U*VW9L1";Y$9U]K&8S5/HG2]X^5@41'M0:SEP2_B-+/TN"
+M+"1*F#=>2^.2<!_6$9<>I0)RLDGCSZ!BWN@"926GT(F9<\#N'-QP`XV3"\$J
+MZ<.1,''&R.?MY3>]O\T1A3;H&W%V*'%6J#DCY:Q0[>&[^_"HT!M![?J>OYF&
+MGT&<XX.RHSG:#<JY2K(%^OA-.`KU*GL[Q52RMU<Y@I%<^%EJX1E*X1F)LGOQ
+MY/4OZ5Q35(0Y->7@'\"KZ*'GDVD`>8_%B)*-*B5!E9;QM;A(:@<F$#ENQHC>
+MD8R(T_)M4PHMN,!P6&[J;P1MT@MO<OR-3H=_AVB,Q&G<-$G%5*A@,F]S]!(J
+M/*.5!BX3X,@7@`JGGLT:Y9R1YOZ/,?4L%9B3M?;2I'--A=VJ.92A+,)2E)'I
+M[^#!HQNBM#%[[I\TQZMT*3&8-?)O9'O#,%YOOTW'8NGA%O?V)B6P'D42E"HM
+MTGJKZ+*(ZZQ)\;RTF^*I@-JS1PG_WP9U+_JHPXHWT]5209>H98KKS$>OLZ2>
+M(8C'X'%3D:5F<8E9LP=_M-@2/YL$SQ\X+(`CO7_*"PQTWJ4P5CALO]?<,`?/
+M/U\NNJ/RFG$L+*`[VGN]18FKJV>=5U]1;J\S-[Y;\P$W$V.M)MQ?)L=_TB?8
+MB>Y4D)-;V7$H36!&C*?KLDB5P"AKK51I`U4-0EF9#;_94F6.Z,J!MUQXRX7?
+MJ?`[5>.O5$'_;Z%+SY<LO7HFLD;^9!QNBA/I&5!?<1-7>+"P)8CW6`(OY4T&
+M6Z7(%/-,P"@S*TT<_U3;5G>4[JMD^EHL)>%W@:<!;K&O_@$N)N@7B\O-\%8K
+ME3W`U8H5-JD"7HOQ%:S=BFS^S0H;_V9-MKZKM<_@DF\#D10K+/@5WHT5%K'"
+M"K85<C,RJK_/93JBW=?(3=LT4:KA`KYZ/%$R-QB>C/?(/YZF?-C$73$WR,H/
+M;,=ZU$K<_3`^BA6Y*E4K[^=JE]2*-5,+#P:1"'NK-Q?G%QEZ^"=3JK$$=IOT
+MB_XFBW.WE80_A/YX,(APV:EPUA0XQ(6Q20<+NX\+42R`?W.Y34M+ON7^6JEB
+M:NWL3J0''G-KP:9#DX=8"]99!5C^%;GBIIQD_ZL:1CABQOBY.6H^DZ_!@N/D
+M1HO\L9[D6XF8G3A#]Y9^9"Q7[?F/4T;D+=`_%6H/1.=*1?<;B[:!^246W8]6
+MHZ\Q5]>8@>3!:$-F))"^"!^P'K[&J;K&3$K-8O?IJ99*^E1:-`,1K<BN732]
+M76JTXNZ?92]='<Z!"1LP%/[)##0;B)L5.>C%A=L+O=3W<9'D:X9:!&Q!\?<S
+MYN-9^\[6EIP9ALP.Y=F*SZVMYAE+N,S?HR].#)4QH(D>S/YK:KZT)"G^VY=&
+M78<O[VR=CG8T?;F78$PJG;R3`TYM']1'8T<-[[^6!U_?I[3$:4S\;_#-=#A_
+M`3A]KR%.G3`^(!49`(D^?'<PX+M-P;X$L+_WZ5%08']4HWH??<]S7D`J(]CW
+M7[N="D3P#_\8OH+BS(,"A=?\[42%#P'R?4B7FLGU?A$JK*KW26\ET\G^6[&X
+MXKKR%=?3[[4N-_ZZJI:7XV_URI*E54Y\6KERN9O]+EZ&O]<N7[:2WE>L=.'O
+MBI7+Z7?Q<OS7756!/S6+EUV[B*`7+2VC[RNJ+E=^"RFW@V%72W$M=CD(V]=7
+MT(^CHAI_2]WT^K7%2Y?B;SD#<CB)@I+2JI6L9$9050DCA,%6NA>S5$;N(K<K
+MI;^<'<56*<BF^QN!EPJ@>7ROS<5&\L"<03+9?9C6F"EV5(@$YFLWDSG8[WMM
+MX!+,5271]\#<_8BR6GX=NHOHPS1V2/AR].D@_P[Z93+Z<[$O3)2V(Z14SHG<
+M-A5U*.UYX3N_0$I9F>/DJ]`2]\V%@AF%#2:)?A=1$Z^XXUMK5]V5=^%M(^)?
+M`A(8^_S=]6;[=LS=B+9TON1#UWM`K,E7%-0).54!H#T:<P5>>OX2K-,^/9[E
+M"1LE+I@^GN?O3I+:2=#WG5/H:`Y*>8GXAV<'K@3;E:5[0#D1@XIVZ83SJN.%
+M':+"OL8*([]"W*Y1XE3?>-+(SF/#5+=8+?9">1JN,$P-)M![K+&YNVKD>[#S
+M'3!##3/+%9(^8+^"H7`X*=ZP8P5(O4/G6+P,ND%%E6/%"IT#!-114O9UG6/1
+M\A4KW<O@!02;7LJ6URS3.:`[P,=R]PI'F<ZQ<K'34;;<O1*>EB]WEBS[.J0`
+MCA6+W`KTLN4K,0,4L8+]+EM>ZD80AF:%8R5[+"E=7K42,2YSK%0^PU.\>'AF
+M^$K*RJH`9TEUR>*E[&WQ,B`%'LN7+5_A=KD`C<[ATKXL=T$&?`.ZEE_[M95:
+MN*KE*Y=KWI<MIR_+76K:RJ]#!W0X5U2L6'P]/)0APZ#,*D<E50WQZ1Q0?M4*
+M>G<X72N!<TL!`[YCWW8L*W$B<Y8N7U:A<U0YG`"%:4LQ9QG48"G\5I4LJT#T
+MRYU0[F(J<NGB99BPG-C)O@%"U[4Z1WGI8L"T\KJ5I2N^3J5BD<[RQ=B0R]C/
+MXF75)4N1YV6+JPA$^2US5.L<U]&_CNL6KX!:@KYA2$J1CO(2]U+X6'+MM0ZJ
+MD-,!!)54E(`B=-0L=R\M*UU*-;YVT6+0<H[2DK)R!'-<YP"Z+B>ZEET'>M%!
+M?\M60J$KJJC]ECN6(4]1"8X8Q[W'L;=OS5'T4C%JGM?*LC5Z"=,4O82/&KUD
+MO5312_@]KI=FGD2]A&E:O735%ZB7M.A5O8209Z*7WAY&2EF9JEX*XM*'CM&(
+MF@E_F69RU-7=4T>**4E_/#RLZ`\5SZ=Q_4'UC.L/2D?]0151]<=-F:0_!DE_
+MC(>^?EK]<?YPDOY@Q5XH;U+UAXI>T1^7G=#J#R+I`_8[0G\DGW__AY'%P[9(
+M]S])*E8`=NQ$PXSVG>WT5>"'[W\*?O6"J4J>"=\['L!9.2X8=3RP51FG.QYX
+M2'E*.FN/89KV(;2N_FQI*SD9"N+KMB;,N)7+2KN7.17I$G+"DX-!D?`6MH2^
+M8/ORT@-*I)>)OHB>;[X?#TSTX>ID0['.4^IK*,.KP>7S^)==,18CJ'PN_[)5
+M_`ZM(U"E^#=L!O$[6+ST'2*(:M/.6?7A[&`P7=VD\@([H'S@;"JG3,_[[\>#
+MA&]0NF<V_[*"J:G(JN/]\XG06'D!9(,D_.@Y%IJ),O<PV\Q7$\PZ80K+.0*>
+M/=N)&.8AC`$@'<VXV1%^%?`TS%V.>VD*(7-8)BTMOV2XER73@OX'QZ1EV:BT
+M"-]42A.J$<H;M3<4"*_1Y11;H+S`)7FML7?%-M\!B^^D<=,2L2>_>?OKEF@L
+MU@=M,??O1MTL^).'C+H<^*4EL="YS&<?[5"=$]QGT%%@UWU&'6.V,(X^:>96
+M]PW@&0V-N'SV.8B+HP"D-[.P.\3J'-B1@UOG[XKMT5?FPY>_/R<)CXO"'.9(
+M4@3SG?F<!6GQ-HEX%[Y91%]O6T5OCB0\)`JYDC<H>O.8A\_P#3[O7)UGJ>28
+M&]A#B/=@1!&Q(X%\CKBN'M=V-]^,OH/7W0:<$#??+@DV<=U=DC='W+Q.$G+%
+M=1[)FR=NWBRZ;M@713>:N:C;3AKY!S>A!U=DESP!V66&.F5\:M0]/V#4K?@;
+MV/OD\)7DTC\+/6=BG_//C#_EQ9]RE2><9[V,AE.Y2"23R\*'7.3_-`>/6CU2
+MAL\.B]%A]45BW@E`]_%W1,&*876#=D>.-Q,`\_%(`T8-&G[@/M0!GBD4UG,2
+M87O$8,1;SM@<.I]W#FH^KWGXP28"/%NB8@/<'@JY\WG<7]FV!Q'33)-PI_0F
+MTE>!S%O@6S!U@ZG#-)4HGR-=I>1SR5E#J`OGX$F;J^,?_P'B(U9@9!X\L,8W
+MQT@I\,W':5O5W/13+.)$TR/X8PC?%`P6&027Y$>"B@&]W<3[L`^+)IS4XXWF
+M?D18SDD+`MQ^=LY\HUG^/7TTXVE:/%/7_%TJ1>!#0:I,$<?['\`"-7@W7"KM
+M9]4F-+,/B!^+SV$SP=-SV'#BCKGX[W/S4*RR@UA7&,;\^%$J-XO^>>0<=P2*
+M7`4%MK-O/P+I/!-\^^?2`^?O%K+V?4D^R,]"&2B.RTJ1\H32\$!S7,<_C3K>
+M7P8)A2TI+6?UC&/;A^1!'1/I,*'O+WIQSUWTQ:JKGRFY+48,XIIC[VHPB%W%
+M(KDL[R#/SM25T5\@BX=`GI]]L9@WJX.`8G%`"E5##O/UPF00/SMY@.8?^@5S
+MHH/>Q2@S_\AW%8%^``F7BLV2R^Q[8S,M$4R2'L`'^SJ;8!);PP7!8!5=DA',
+M\IU?17/"0@<0_OY5BD-RP.(_Z%F&'76+37P$,_JV@)++D2JMDH$\Q4'OW8'.
+M0F.E7+@X&--70FXQ,`C=77[I&F0+)N)Q&OH&[+30?F&H:C+ISF(.,\A;KZ2K
+M)QU^5[QC+HT_K8P_7:=V5NAF^Q=AHY,L$<65$>"3XUGF0L`<3Y@5$W)!VR+$
+MKR-(B<T7,7AF-&;"H#@I?!ZNP4>,?/-)YC>&UEY#"[X@'[]^+"&?"#$2$:+#
+M8J<VX9O?2OAV"(65M7Q0X1>33JJ?C#K)`WK("G^WP]][H)=>1<4<^O@DX29_
+MW_H]B^(Q$/1>"Y$Y*T#%ND#]Q=Z)#PU7$-XCA#=7P<NI>%'WA[817J;W4+3#
+M^:JHG*41C#^C232)SFJJTM-]*HF-&X^CD%$@#4^F1*T76\1)A#?T7U;R.3`@
+M[K>1>W+>_S*U2T&\A>:H+42*%75[`4,B.G9NHRZRU;%+HK:#P7BW1-P5'?LD
+M:GG1\;JD<+I%HM86'0<Z')W,/03YM%:\+Y"*Q?Z7YSE+42@![C=%V(JT)UU$
+MF[L]K7TFT=&K[#MT./H-]$,CH8_J`$/)ZQ,!';T@DU\KLBGC[^XP\!G^'OK8
+MJ&LZ:M3Q+SMVM?9QOI:91G1H_+P$_R\&762EBN[TM<\4]UB0+:K'S/V8(NZW
+MD#_?W9)CM]WQ.N^_CRXG44L[=J<T\^W,`F`4S(6R%W\$X_]?C;HH_$F$"2/,
+M["'$PF"'WZ;HC]#?)[+Q8@1,>'NBV@3YT_'8AH[=VW30$K3)@4<O_!;%<;-:
+M(ZB%?SY))Z;X.GI%[TZLL=5WTL0_B"?MB-;;SR9:=_W1J*L'&J\#/LV!O]*/
+MV"_^$9]`59L1V[JBT)-FY`U'WI.AE,`<C-X1.=%XCR]RG`^L-^/;YWSS!!#K
+MQBM\D<^@L^$CC+J?\LVA+*B"TTSQZ"*#?/.#J)(BQ_AF$]0Q-!<3?)$AOEG"
+M&,D/W8VGL2+_X)OG&O%AF&]>B!;P!"7_*<_RQMF^R!=\\UT<@F_C$"K*-[<2
+M^)=\,XY<H0\S6/^.F!IY)/C;%OAXD#Y>@[=.^.8[\,M>C#&S!VOI:\\5A>>E
+M_?3<F*<3KI+<.T%!`B=BZ\PH1]#5=J*BW#&$BG+J`O)=(=$;BL^)3)"1)5R[
+M8Y>'29FOI1<Z4&@+>M9'%\F>+,G1)2TRTUW\@_0E$[[X-G/\IJ]2I)))Y/[7
+M.#.*`Z+BL[U/,HB.OD"=1:PS2]Y>7T>_>"\0U24:T!WQ1*QCL=F*>(JY02R@
+MV-RA0U<E=)X3JGBED<E.OF.?T=$"9A#OOPY(#;UNPN_NG"7Q-'L;[[\&DWYD
+M(CU/`K]&'W#NKF2C@R3,C+T3V&Z[E%6=OC45&6"V8,I$.TM31O.-)K7+K-%5
+M,I[%WHDSC.6R`TSHM^94^IKWF1-Y`][=XGZT1&M8Z9)2>E.1'C`\C'*94H?F
+MC\?%L^MK&.6L:(5@S/@&P(1<)%,LK]AF=+?X3D+I/QY'<>@7V;OXYB?&)5'"
+M:!#]%`5/+2%!5)ZT/THEV/7\XVWAZT?B1K%4<7=G:'`+NZLE[TR86"3AKHZ]
+MF\"]A^$NU/,[T$T4U4.Y2X`M-X`7M1HRDMM!R(X;/0;>?S.DA@YPC-\XC]J!
+MYM$VSCJO-(OWEV9H5+29]W\?$5Z2H<0(3^(Q3*14M&`@9B+:N[DDF2$U";QB
+ME_BI'&@!M:AW363#,@Q05`$6U6;2T"[ZL<VIDXQ7N@WMO?[O]AN<KTALWK..
+MZRBFNW;B(DLHF.A#U)8,WN[B^&:+B?9,0W<;V?F0+K'3UV*QEYCYYFGP*72I
+M4?%!++WY+%JD)"$!KABL<E9'B<L`ZX9O7@^IC>>!A?,U_A'TFH:J\Z$IB.)-
+M59>-XYM]>*'B'#)_GB<U"B14H!K]FX'I1Q/(/[YG,WLHA9_[T6S6U4\0VTHE
+MLL/M5J]0>-`>0!N@/A?L)[+2=Y`A8-LFVK:6L#3OGR6R$T0RMS$'V@_U4Y'7
+MS*#?D:?-4Z#DF1?G:#E:%06$HIB,8A8=H7FN@49Y&N?>)-ET[\YW[T,N4[]G
+M<B\M7<`Q^Z04"F`T\8$(Y(H17>J7ORAK*#OPE67HX()DAFO@ZC\*[6<^?D<O
+M*R]>5@%A?HC**B`<[,N]:ED%5%:>MJP$')15R<K2%K%R`6>G?/Q#.%*RW+CV
+MSS^$MB'K1[$]97',L;E!5AUXP-[%5"I,M6/O^@[D,*U*<H0^<1K'@QQ-";W'
+M8L"BL*Q&03I([Z([PHP0LFW7FA@?(F&)X@ATP;Q#@F&/VHSI,WO9U2#-,Y"L
+M4B[43&=_J4NB3Z-D.(Y_Y`N\M_^6;PNZG@Y*56;?O6:=<-S?[3'Y[K7HA$)-
+M%Q%LDAYZJCA)<G>)\.OH"L\&>DO,@ZQ?6L.T%EIE`8+P^H<!O572WJE8:9;V
+MD#FRD1/IP3_,^Z\_CJ30"-Z1*WJ?#V&<Y"`&&`$EXCXBX76WGH8SU!F.WGQ'
+MCZ]E2$0;X`BJC2-A7O+VZ.^%M".2T#-['2:0F41-ZMC)V(#3>,=.F"7Q+PN[
+MR#DDU#;@WBUVB.]$7\E@BRDDC$P6Q/)92L<HG\/L+JDX5RR?*Y;/2^B_8D7_
+MM2AE9$B.?K&B0&-2W^GK*&(C96&WG<2_/D\*1)08)LRTYX*BWM?*E;)T;XB)
+M9*#HB41&$MEI:D8F>YI\!2P?$^+JN9+!7CY/N-%W;Q'263[7US*'_"0S*J4*
+M^)!+9O=.G)!@D`FEY;/C+7^$6OY(:-40QF\!MJXG_@*C-W.AI4/*('`/DSC:
+M(4/%/Y\:T9K4B%G_DMX'<=>+!A!E:&AQB;FCE`1,J2'4:',1+AU0U4*O_AUI
+MU-0MM//OQ%\P_!1O5"AM@M7G[=?Q_@M0$4\R4'])"`K5IYP5X%N`9J&[2S+9
+M2\V>T_2-]N2^L9?.HO7KP5+5,/;L$8Q=0Y&$>F9O4>16OXX+5<?43BM5%*#7
+MS(I9(A/)BCDB"2/43]*)\$\%A]/`"C/.`>/2QAPEDL3IE/&`).XK3)""R@C"
+M-%X&;F%T<"Q)'4^.2GLP)T45U&F'E'RV\(AZ-6]T'"2'1YF:E!A;6RPI,[-2
+MFNU<=X$R-WSR*)N;>91?I2=YHTP;THS\9G*=&!6I<<)/HZ95&JK=@DNAK/>&
+MHE&L8^K,0,ZZ'">PSX.A@S.QX#&8??^%Q=5B<WRRQS_`+VS-HN$SBF.TOXA&
+MPH?>5=88^>;=RA)A-0P2."![YB96[:IB>_"3_-]_@BK$UQ`E[YS8)G-L#XZW
+M\F-_PLV2G'ASZ85:2,?H:L@].RV];;1(FF5>3%[.2:"LF-SO0)*@NV-:P^P`
+MMP,+T;?J![$N;.]`3TM;K3#-X13`QC\KYH-.I.JR18[O?HKUI;'FX4^I7=F\
+MW3M0V!VJAR^!Y_HA\\A]K2\^P'VM9VD'[J;;\2!(P(>VL$M^%6;W^U;A.-3>
+MG(.?],6^R+T-G^\K2?EV/7PK2/EF;_B\W;<!7SI\B%RO2_B(8G>CW>1:&"^5
+MXRF>JX^_@PO=5P=*I_E;O,9`Z8+6R+C`HI@2+TRPVKF'A9D!+D`L:A>%B'A2
+MWT:Q7"-17UMT,5X+C]@S/)]AT`7!*BXH;/$?%'`MVKX@<;M[,.XW!LI/*>L4
+M1G2=I12!!JA%;#<*&$-2,LPPV0V"!<KQM4<7`YPP`/_$O6<)BN\K/.V*]^$[
+M#'2>IH2A+T'TBWQ%]^N$B0'N?J2Y)8JG/B/BY3">:I&DG+/[YONTK99$)ZTS
+M"Q8Y]X]&;7QO5G12D>',>`SO13A).386[#B\NL3@_I'PI49;>DG%+]J<"Q0$
+M;":QU>@DWH!:1[ZT1NV?>S]GM5#S.E/SYE!>O=%A#4H%F9=COI:H_:U_+M_T
+M4?.-H'5J*JW'NZ8GJ!U,\AN7+G]>2G[#\:X9VOI^^L_079B6[H3_LQYU#S4@
+M-5\<C25+IROF[ZX_&^\#=?F[\>LT^'J%Y8$E6S[%$`P:GT9:G\-3>]@Q.;<-
+M8XY%"\%\LLSPS3J';LGO6SYP8-GQU1'Q<&O($.`6!RSWX3%M9P27OH.2YV%S
+M16`[PF(F[E71,:3D&$K-,93O'/35/PP6Z$'(5N0?]LP(HG\]T'[N:*R;>?X%
+MHR)#'&0VX%7^8>%#O#+6GSCGJ+T;4_LN;M78,/A85'66D*!\4*%CD.@0G4.!
+MHL4![A7)/3B[370/*='X\)QD_1-@'R]]!<$E]/%MELKN-XL.<\P1B5<-U`;5
+M;N#X'S&TM4'$T-H;`]P;DGN`\,4<AU1<PBL*&L_]6,L+R*<PU=,;C;T+9@#5
+MD_>C+RNJY!]]WD,&_A'4!RRGK_[^=4;^X6-LJ1/KV,A!SE8\K'"0;\:YQ.VX
+M4E\I.GOD>;A&Z.R1''AEPCTDK0P6B>Y#@=?F$.41B7M0=,A89+>G4G(?PC;N
+MEQRRY#TTHP*JV:?PJ8_JA96:^P:&2!3Z\N'?LE\501XPV%;^JDA<PDG>?M%[
+M*%;VJW6Q$LX?$U[`$[B;.49U/E!=`19>1]G]ZVB]N.S^(M*22X&=3O2I-\,A
+MBXY>I<#>U(;I98Q$EXNLSA:LL_^@YQ+(*I:8T7LT1C4:DNI?+4(?U$.`N2@&
+MI<%<2.PD'^V#+$;\Z]KSF[.T_M__``,9^F9JYID_:@DLTB7HS<NW$/>TKT8K
+M\!S)!/*$PR0JX*GPC*,GQC2%1]INRDKXYPB0O*&_+W=DAB4(]6'U8W(2L&Q$
+MLPK=&@_E"P.!LKU%T!I0KMWJF40Q+R5R,.$PV_7",:1G,GP3)S$'C"AXQ=98
+M5VSIWG6QY5S83<X>KD,_$`MCSKAT1J$[SN"V:64^I>Q!*!L0=)3MI744PMY#
+MV,WDVP>W-3W/!%8?&NV^]\FWC;H.1Y1%Q22?3?7;H-?D*PXR/=O,<B<.(QB^
+M$Y/Q"_K9+R'\-KP$+;DI^GO]HT7^F&<:M-4I:2%>`(UU0ZYJ`K8BL`7DZD\Q
+M='42M30\EG0'74/0'6_3F16IPNQKF;;%"/\HPYZ\Z!TC^@M'?Z>>S&JPQ.3?
+M1;2.1U/N_S,\-?)_D?M4E@VX8Z&<UYU(<EF:-.Y^THUK\Q:<!KGD7_S!F,X_
+MYJ\!AGJJ_&(<(-G_)2(1+&ML\J,``+BRQ'66CF*K+NGN?QQ\`X"C=5OTAZ1Q
+M/9Z^0DG/34[7QO_``KV6-18Y[P_(IS66:GD8!@"HM4%<D%)73?L?9G02]I_3
+M_H;'**[C$C1JRO@?!@RFVAH]PM_+X$T`+VXVIV^'[R;R&#!/^6AY-/I?H<F(
+M\-D,/BNQ6)C>_Z.2A\,\'Y\:(X^&MB^[XK2-H_J?.BUM;[$L:TQ4_U-G1-MW
+ME#P95/\SI&U5EU&YJ``M>*N4[3N9L:F:)EL'+F.3K5R`,*?Y^_OOV1]YM9L1
+MV\C5R.=_27O-X;/I;3MVZ(W0-;:Q%>-J^3<@/-IS;QHZWOL]R94_QC?_##7,
+MU5B)^[YD?<H,%FSS8Z@[I@!]_(-H/+/MKP)&XV;(?4.:O]O@+P?^8INHP4JB
+MY`@>29P?Q-EP.1<N4]+NIE4;#F=>\/9->J.S%*C:3%3)+`K"=A:>J:#;IB_B
+M.DL+[@&ER+TV_A'5R[PF1QX\G-`KYZW)J9;?Q$[VX%WDUM\J[J4'9?Q)IR_V
+M_H[US:;#R38Y\YG9=!<[=&P)PLB0"5H?J/P'^I-*H6?][XP4.,IK6V.5;T22
+MVF!@GX*G.@QB-8<^.99PXKUFL8OVMD:A)5^A9:@KB1;-_9??,5FTR">Z2"^=
+MK4AA!YU1`ZE4UL"2SM\E_!__#\/_>-=H>NAG_T-\];UY%QVKJ`_/P6TZO#IO
+MB:VSU,B/G63''HB_TB*\B>7B*N6K210Y]IG`.Q60=2!D'G877KK*):]E@&!=
+M?28]00"E5I$@J^1:YJ1:*5MX,>6^A]9_E`')Q.@^T!SCL48??LD(<%I%/6XU
+M?HA;G5X+KG\Y;:*>'3+[+>U1.&V);#]5L]DP&\:ZM,8*Y:/P-?24D?SW29.H
+M:SQL5+I&\Q7*6LD-AXRZN6\9=0,'C3H;//<#]B+XFPGOT4XDSQ8K)'Q,.Q]2
+M.IT5.]U"AAR=BD*2'H>S<HMB?^*)@6KYSTA##H`5#M,2CC4!_BGQ"1=0FCLQ
+M4&&\H-!/::,@RDX%D!E4.!QP1%QX\SB1_Y>)_!@.$>.6\,T-]!2!)_0O%1-@
+M+AEEP\197\;!OTY)458K2AR.QA.+5%HP_B$EOI=(G,9R0E+(P/Q**6X5.AR#
+MNL2A$^40`U(]"%0/::B.),CHQH4.APP``PR`=,N["8!?4<A=#%;R4WH:A*?_
+MHB<9GK;3TP`\B?HXR4.,Y(L2)*,48NB=1&4S$XG+$SD'6>+`%_'$RRGG0#SI
+M<")I"D,:$^3029W"!\5%?T#HKTYJ9Y-:(<^Y(`+5B9K^+4K[Z7C[,B)&0D.$
+M*'X:I)?]]&B.E2`_>X%=?1I^[DQ4!@_!!1Q'`*!'P\\'50#/ZIC0IV&#0:V.
+M9RF:JXF$T$DUX0J%-[TLH2N><*Z2<(0E[#T9K\D@*.E+R)=7O-^0Q?$XNK1#
+MI[SHCQ+7H,LMH4NB.$(DG$?1'![L\H>QS3K*<UC4+-H*PH->0<@V7&(Q>`J;
+M%ENX<'Z0--0%4GF.J(^5YTB5'.CJZ5AVJ;EID863)ON[A;]C7&(\*-<ME><"
+MW+)<:;'5?U!XZ?A-N>G6>^ZA/H^#AOVPYU(H]@)`FBWI[89&:WUVK(X#OLN_
+MQ2-,9RGG7,<K,:J-N&>AVJ!Q?-,ZC:J_]QWLX,H(?^\:A7BL(VX+F>6C;]'8
+MD"D6B)NY-.--\MVYES&KF_1D5V&GZ([`K"NP?1Y,8:H"WD@-+5A-&8PK+T&)
+MWVMOL`AG0V'KWL+L%+L5O4M#\TCE%LT%MF0Z%W>0/0)#96$+M"DPW16[J@8K
+MR0[4X?@Z#@HP!Z6-.$K\,;TO;$.'4?'A8?^=IQ`07>C'N&DF:9*D`X;S]6>C
+ME&_DY'9D\.21_$X_/OZB/<[SP"@\3^;=O>V,=PX;\LT1#4A+@6^5R+?6D^;"
+MMBIDWON?QIGG.0O9-@W89C^(ITHM>!`3JDNQ@>(\3&+@B#F?J9VQ$(8_P08H
+MQTO9Z'$5!*V!KZXD7N)9L_"E-+>S&\B(9-]W,1[;RSG/1)7O=!RU/>%@=T0=
+MO_,;-M:B%T94_<,E-CWOKR$%:&U:;-/[[#IO%O0O/=_\0YTZ'CE@`IA'1^^^
+M^)+%541?B69R'VRAK<^+</TE(F6@>X272-?`\->0(2U$_Y1_QGD_YV_QGB-=
+M38.16?[[,/GV*,!Y,21>AFZ5[+KZRQ"#N1(*''>`N8:&.2\NT$\12\U2!IJ:
+MF\TZ`7VADK<]-MP]JOBJB()J\$7TGDP\/CDS?#>=SX#/I`-)$`;4T5)PA5]+
+MZ">`H&08TV)D/N`,N<7SW<JDS"^HF3U-:'=,PEU:?95LZS#2+6XH'KT#^P_R
+M_O7DML+:M,IV2G%1.S"*'Q33`3:U(,M6G?S[;L;5M8P8_=+4-E"1YY)?>DN9
+MZ`8>).;(S[R%):,D7HIC#XLL.%QNX3Q3T$BHKJZA]F(5QGMW%FDC=OH_*$0-
+MIIDC"K\VTHWR?60KQSQ?#08V<63??P7YE0V5!NYNR@8^UTV2#**I2L[X!]E=
+MJ)NDJWP+=,)[4J/5'Q/:D^>YBA%NMF=YYN'Z;ZL\3;H<X^I.LW=Y)DMZVB.R
+MFQK.?Y4Z=C;]H#A:*(79PMUBET9?)_/RU3:C>L_>5_\B".4Y,<^+9KQH?Y@9
+MJOH.Z$/HEB%HK']Q7;GOE*7AG:0[W@G]WT9<`"M9OO(WQI$Q-Y8GTL_6I/L&
+MEFKH^4J;4;7<.AR[J671#W=>E5Q"!QEQ/>^^-FS**OFR&(N$YE6L<444V&KM
+M)4')Q8'Q'7-$81A"^SL&71#'M>-A4Q#/;>(*YW$VH3F"OM5LBP/<']C::T2Y
+MD(7#6244CPLY;=-:3X[C7WA'WP;IK9]P^I,8GMSVENC>)WEW!VR-DG-?P/:H
+MY!T*V$Z*[U"T<QLZ=[UZPU78X^TZSX1JL*WO.T"WE,*9U?)5],BA.S>+.`5(
+MPS[Z'K/1K6(AZKB%HG<`'14S^FSOXAJI.]+Z,6=T]V-X>RBMZ"3&B7;N)H`G
+M1'</N64^B5YAG5&[=#OT!^]M@9=N.P>OC^&_.D].P$;[1%4Q^BS_[=>,IK,D
+M+Y1#5:^2G_RU0IV8K>03;!T^1*=C=Y$N,RJ^V:,BE:*<Y(VW!UH[F+[]-EJ(
+M[!*Y;26BLXNQ/!38WE\4C57ABD=4(6-BAU%%@D?QO%&[MXL/W(AFM8I#LFV3
+M8!+I/83G3YRRZ.P4?^_KR,%(3RPXJ1*J%`,/VMU='I.XQ0KCGN3L["BAQ2L%
+MDQ<PO8IKFIWB).63[=5M59:FC_5-JRRGS)66Y*\&^/HE?$7UA!;CD\H]#I=9
+MFB]Z=_MC4&EGU)@E.G=+0G^@P2IZT>>NZ-Q'=^2U,@2?`Y9'1>>1F(")L4UF
+MT=$BM_7C\9`6Z!WP&9?XA#^C/NQ$)Q+9XGH.TD"@<2:M"-M`P'98K#9+WGUB
+M@T5"OU0X=[J3KB8<TC%#&^K=*SH/((LL)"2`#G(<$*>(6\P43FZWY#PDK<>E
+M@RK%Y*F6LJ^HYJK4;E?[%U*&OLU6G6><M,X:_HKD[8,!=PH&':_AQ,U@-^T6
+M[11MJP],%G2.A'BA<_T24T"*#U`B*PDGPW<&@X'M2Y6RP$I0BE.[]="?$R5F
+M8(E?)=^ZB3)!H4X.V*H4%DQ)(J%'+9]93T\H)!S"CG0(#[;_%8]..KJP:SB[
+M^(=^#+I>M?6V;[T&!))<%>=5RX^&8C$:.:KEM=!/%8H#VW<J0/>U'Z#$.T)(
+M;IX">NT!ML#PT\]BM/L[!3U&/8J]01D_=J89/Z[<K_J#L#?D>M''NZ\AATZ4
+MY$A@(^5`=\FNELIGDM\Q3!(R8&":0??Z<O!D=WFN5)V#<02K\P!#?>OLAERI
+M/$_?D*=9`U1"Y>A%@S@I,198R&^ZKV-FX4$P27$@LOC:.1$>6_/"U4%UDQOF
+MJD3^^CQ1B-B/>>>);X$.POL&0WXAZCF?0HJ*'"WWE$WA\`I/V10SF''P8_&U
+M64L.KQZR.R.-O_<YK-Q])]"B;'@$1O@X;6;F&.J@ZJN\TFQ_RY,9+):JX$&(
+MI+4#3[W&[(":16C^;5H:VU0LO\!&+7N[)VN-3CZHK,JXH[,_%]^);2J2'XFG
+M9T#ZS\C#W>`H=L8/7F,3FLJE]LI%?/-?4'N4%)%/'_*Y7&P62XI**0VOC="<
+MZJ_2EB+H[E*%12RU2#46J<(,5EAAB[W1[#'B"R#84JP3)HI;BL5&L]AH"=/Y
+MR))BJ=@B5L#\KEBLH.R;<0]!W&SIJ,@E_UXE2Z5-:+;<`EQ5UKS8AT64_V8D
+MISRWHSR/UL$VSO0U%.F$"T$NI-)<F!.4Y@HYL;J<0'FN*[;1"C:7'"4SQX(V
+MV$;HEL)K@`Y;;)UY#/^ZVUXEV]O7")WS1JG""E0G$5-,L3J('`N0$U@^4UR6
+M1Z1,TY(R.4&*[%'H("+:I!JK5&I!CSE.LWU+,4Z3[(T6Y!W&CA"!3R.XB[Z8
+MMA0A3QLMR-,M1>'I086.(N1F29'"7&(H8RZP51GA8XN7IH_)\X-7U#F6;TNN
+MSC.^LIILX7`%S/V6%0GCI1+@>!'Y=Y/*B^R++)Y+4+V6$'$P@)00<>5%N$58
+M3B24T,=%%H199$Z[1S'[%77=/#91N);\PEAB&RTU\A_8?:N.<G0RJ*N!?EO.
+M75%NOJ+<X@I4W.:2]_>1VG3)3_\I%JL.5,QUU<CCHBC?:>Z#_WH?L\5P49.C
+M?1!-S".M;]_O[2-RE-4I7^,BG3`!AGZ\E7&XT76X<:54X3)6K+177%?_&7OD
+M7ZA8"EV2?Z%FI;W+R]?(SP(1-?(/V`3'UUBL\WP]*%444S\Z#XA\$J\U.0;(
+M-?.`?=,BSP\12.@ET$NEY<4XZQK!UT**2KT>>Q4HFXKBV/*EX16`E_5/:O^*
+M(NP3%44QYJ]M.?13-"*IGWXL;2K"PSO5I*0`;[4%\1!>&!J6(=X2S`RE^!I`
+MV!=(U2B8BK#C<HE407VN-+>CE/6YJID=I=0XH+3`F/L(>U:E*LU0UL8<4)ZX
+M^/F$,O>*X.1G"$,X;\P5A4%H4+:*#?WHZQ2G$B-9%D**;XM-!TJVTF9?8A7.
+M)@98I1*;?9%5R%`VY3"*Y0@F508J"H##ITY0#\-E0.%G,)D,5,R!K_()O*TQ
+M!#3AS&V8V0XT(4Q&#.;91EN-[/Z2Q&H6Y/SE";SFM4B-)))V?V+5RZH<XZ""
+M=B#(P)=J4,9QN)W]*?Z3*9DDJYBMK$FDW^LX.PF7-298:^17(\J$6<B`*5M3
+M+"'H*?L_>U@G+K\!O<]NGNMKF*43LJ7R1?;RZQHFUE3+Z^.(I@7*9[FJY;DQ
+M]0,F5T78GF*L_+I8^2+MGAH[,U,X#`-5#LC#.?Z#GK/Q^'`))TR`1K>76`0U
+MA$?\C%4B_L,>];S,FCF!TKFN*CD39S.X9W(U^IIF;AW`QBW'&*>EBI1VE+(F
+M*;?$F+C-H@VXTAQUC2O=FLZ[NZFOLUFP:UZ52_[!*4U_C\.]@'!NG+4'2N<!
+M09W'52C"1[_?MOVRXH_W#B[\WG?QORN+V5I)HEIW4EF6#QSF@&L:'?5Q+0"3
+M-V#;D4>AE2NK/IHS$Z]QOK3Y:]'84=.'!P,O-;&G5K$-3`I?V]P$U(>M'QY\
+MSXO1V%^VB.[(>W='8##Z('?F=>_='265G69]+?024+#]68K"N?4<C-C94.NC
+M)ZODH\_D[[/D.O%WOG9;;/T-:ZSD#T/LH(#)9NIJ&6Q.?B)087;)09`^T00R
+M,)7U3C!T-G.2B;#DL&CG8!9MR=7(AF]@3H*BFI?8Z@`%H,/8;-U"$1@Z\WP-
+M93HA'YJ_?"Y(718N$I67T2(*K3M<NV:.2Q["T:"\K$,GXWY)>1DN$,,,#T-M
+M&$1';S4N6HM=5Q@*.UV!<A@$UGV`)[117B671>RB@Q-IQ_&V%ZFQP;Z#01=]
+M*?O8/0!TQ7YN;"-7A49L.UT>O0H?+\;EA5N"*-\F81P8U^$.NVE#;G6L#@4&
+MUPN^2TS$PQ2E&)T&YML*EB:68*(3%)[<&EJ@>I?6A;"N$V(9M`QWXPFVI#V8
+M%#-%>QYLXHMLW<]AQ9Y3Q:'5M\B,!X]L.-=1-E*@C$RI0M&DXBEXG<?&YQ+.
+M<V%L/8?%8_[[*4:K<XB.=F#L^9;&$EH3>!NRC,--W'FH%%\`+&LP*I.OI0"R
+M1B&'?-,7;#V3L@T+DV%`?)S-!T%7%PZ'WPCZ862%9_&XV,B)"\-GD>HUB=[!
+ML#EH]PX*!O&XY!X4<64(@TL52+1GO]$B;E0'>,EM$ZNIHO??SBY[)UEWZE?(
+M/J>CO(!]G4N[`T52)JZG_0T/+D?40VJZ-&NW;^PRT@8?'3;"^]]\,_D#66^5
+M3':#YTY?0ZY.N-Z^J4B81&-LD7T01H4*.CLU<N"D07L\JP.S:2N*Q7*PU<BR
+M+2>H=19F8(J;BF,52Y49.?H;B56XH%A0Y-\>CL7(TRA^6UF#=NH<VO^`@0E8
+M#?,>\CK@:R1[CPH3-Q71?6\8[ZF\(A3]:J4\/.&/@9!$4T>YE>V*<,KF"/%L
+MO55<9HOIE2V3PH/V)>:&`FC'3APMRDPS,?-CQ.HJLVA5]YK9M<D2/"ZUQ-S8
+MG0@.IL8&B_/X^A>8S#;FB-ZH>B'_?90?.E-&T:#0BK:)#AR&R=MK\\O,/O!&
+M,,+U(CI:QUPM!&/KZ;#>IAQEX<"-)H+\U[>9!>T>!"L`.O\-,/JS?><JLDTY
+MG%E6%`D+1+<<VVC&7HG9/B$R2(P'_-WLN'[,$!-DZM&$N?,?;+<;C`M`CKWC
+M5TRZ-M"%@8@$%K<W0LXGZ,:WW3T$AKX7)RUTO[2"Y+6C8B8=:]]*E:ABZ.6[
+M:#\8\)*6N.D?>#^']@+NP'5[2Y*Q-2VP;*989Z.E)2;X('NYXI(\9FKU$QO1
+MK$=;31@G-EC#4]%@6T).%MDL`>8-Y5:06'$Y3!$LBO'2^XVD.&B)\T__;=1M
+M<^=L!17CMDE5N+N!6Y-N<ZS.+"\!?@.%;)Q&]K@CJ#CY9G0!LLT1;9''J>&;
+M@FQ?`P9R#,K)-W^@K!LMLVQ#WXC3`KZ=('D2!U!#?NY1OOD'+"RF-!\WO3>:
+M235^?I+*$PUL57J->$IK*E:CWCD&`Q$S$K?8[,L5([%BA)$($Y!*,_;:$O)(
+M"A8B"G@I1\JMCI./?,;4\K#PWQ2M#68>B6J?!]4.6X.5B2\EBN!=A9H2]U&P
+MKE4X5A,__'C^7V%T?QK;[)KGTYR5"W#^/+JM4`%4S7'%-G'RI_]0]"W0A7MC
+M-P=I)S1'-(GK<Q2!0+<ERFH^J`7<D%B6&RC/$\MS@%P7+JCABK;/"SR:ADU:
+MJC`0>%>7P]:%<8.B!.-N)\4"9^?]!5N@(8^=Y]6S::.O=:;]E/=J\7-<"(&N
+MX/=:@?OH.%KD)N'P43:)0\DKFT3SU;))EL.K([XV*X5+^+URF)_\^&!7T7#E
+MXE\PE>&VH=/K0`1ZZ=;.N$CYA[#7[HC"O]!G_2\`-5O?2@B2+2CNP(UXJ28'
+MN_0S2&MICA2@;WLPK]^RBV\FCT]UN>(>&;'M06SJW-PS/K"$$P.8$+Y,(@"<
+MOWML4@#!?*USE,3)*,>4%>_%$Z!$U+7VC7-1H?@2F[LU1FDUM!<D^?$YU(A-
+M-ADK<)/BE:4\Y;SD-7A!?2/J^Q5XV"&`]V[%P"!BK.#XE_W(%E=-9<"/!)!)
+M,8]FF+@*VGR(_$!@B@ZLV>V/GPNC3&6,:(WM01S4K>[YDND_*W**7*NH+##[
+MVKAP'MV)H_KA_2XS1E.;@S'/B/F^MEQ-;8FS$B-O[J^J:L0=_?`H[\>I[7).
+MHC<PLD@!^NX%&3Q7*K7Y-N?J//>XH/:X4?OHI\#35:CC*YC=M.N$.@_)!!P@
+M]DXM/<(5DBNQGG)1>LXKX"VY,&DK5&A1/P6>Z_E"N5+C7GOW*L^MMZ^^+6]V
+MWCUU>3?,UE6M_I9PUZJZO-6;U]6MWK#ACGO6YGGNN2?OECN^I7/5K09HH6YU
+MWNJUMU&8W1&PNL5K-ZZZZX[;\N##K:MONV/MM](!.5???4_=%OAR^RH!H_?&
+M<U'<7L0>_W+K/6L]J]=24-\;OGV#5Y<@^(9O:UYF$?6S-%^^@5^^<5,<T2VK
+M;KT3:*E=7;=Z[:VK=2OK5MUQ%Y*'WS?<M6K#[8DB;U]5M^I6S^JZO%OA^X:\
+MM:ON7JVAYZZ[5GF0*W&P!/4C:[KLGCPB2-G3<Z+9'2@Y5=!M=Y@W9#1M^?(&
+M_O&VPI:F+:=F"9;C[3K0?\)9S=T"#U_JA8FU_N%ZKKE;<4BDSB7)GJ<3=^:F
+MA8"@=:LS&JC1V]T6_@DUF.QTP,KP>3*;%L[V7(8^8I@+:!A4QS7-G^W)!>R(
+MH=XS.7PV2YL(:5E-\^N%<8KN'DJ_/MKP$W;D#]?9M+V7?\&1$RAZ@"8\.4U%
+MDW3"ZFV.'':,P&WC7^:LHB-:0R&ES?);OP6S?UC\?&L7`W`B@-GNB`KGBX-`
+MFC%0CC@Q2/6TP':FX[9EVAXLO^\4K2+_AA73SDW2)[8EE?,P-LEM7;+Y7)RI
+M=8$]9_?H+4(F.PJ1$0PNV1*B1:2TYQJ>>4XYSI@C9?,OEY[:QLW;ZHC8W3;!
+MO`_C%82_&>1?-FRSS8N9YKDC&\^2'+FMLM77IS_>X^L;'RZ!?LR_+$0@;1/Z
+M`*X&A9,7$V8J<Z5?G2*=95%XL.VWM(50#I,G_N4V>_O&+IP(#:1="\E\3CWG
+M`D/_.G:N]@XZF)?[#78P;^NS1MV!-'\[X0_3:D#;H'YY-H9Z<",==7H2IW<7
+MX+X#IZL_%ZP+YGW`5Y1A%,9+91D8KZV=,^N3YKA:6:A[EJV5XTE;80([;?B*
+M8NNPL[4_4\_6'E#HS(4L9OCK^;%1MTOSM^I9]H?G9W^%7AB11=]Z"PB\(U@X
+M#%\K<59PK^)^"J8%+9Y),+Y7RM^*)9VEN@9UJ0)-WHC:`0K@*^4%Z%VG/1X\
+MRL;@:(X;PA5"MI:2_GR_^&-:3P)+9#QYY`N]0'?=LZF./U+KN/,&5L<#SQAU
+M\R!''OP-/</^\+T'?C$-%V!!]W^75<87,0BW2C!]^I'R_3Z:.L-\E*</9GD=
+M+1*%#87=8L3>Y;U*[`I?KL"ZU=I3I?0M%!>22,1#0LLX5?(-8YZ%^ODS2I^V
+MH;6*KAZE!;X85`UC<)(?I>8;E?.?YP+H#<K?P(_8'S[O@U],JR0YH^4!9T1^
+MC*T".".5)')T.*2!-O"C(/I010X//OD6Z#UGB0VX8R-6@R$6VJ&<$626G3)Y
+MHT/2@<,XOX5,`DS.P^N"P41Y\H7*@HX5\)H!77@/X4AD=D'F\'R:&_E;ZI]`
+M[^Y%?K*0.?LB7T2_J=E7;P<+]N$M:)Z4V8$@"[F!;`VAE`5'[Y]W_"@A']0+
+MCFOD(Z3*1^=-C(DW/&W4Y?R(_<E/LS]\[H-?3"N,*:W[A+HHZ3E+$05_+.D,
+M))L@XL),<U"M5R;4"T<;[KZ`:[+OY)1-=U'A9=^DPK\!Y9SN[P:%#NVS]B\5
+M3OLW0LZT^J+TZ80:XYO1EXG"HD]5%@U\4_67^4/H-\K?;OC;"7]/PM_-\(=I
+MRK$/F"^IFNWA^$FZL]A7TG&;V4V,#("G<=0198M>P+/"6$B@?@_/%/8Q5$NO
+M0>2_;8U>P7M5'*]-^4R(IS'$XUC`2+J`B/R/>2Z$-IC.-"ET*%^]GM,U3)(X
+M/4D8V_%4UKW3ZYKS?VAD,4`]]S!%S_R(<:N(,T__P*@[HOSM5/[PN1?^,(WA
+MOQKKP,C_87QAFU<H#Z10GH7R$PP&QUB+%W^@T,0W_RG1:CUJJSW-:'O\OXRZ
+M+OC3`?13\*N^%_^`/>,XTW`!&V=P592[K^GU'/D\=/.J'#@,4:2V@&\0/N:7
+M<TWSXBG8U[%=K$JU;HBI2XF3Z2/5K(+5;"[5+'R)%GZ."N_)3L!/2>I-X0E!
+MDH70V3&V*)F>%][_4MOGVZQ]/,2#9V\A'@P]9=1Q`%$`?_BL_A4I[U![.M"%
+MP0OC;?1]33]GE(G)E)T55"`/@ST?O^N0GKZC3VD[V=N)YNI4F\MU*^MD__@^
+MV`8`?1?\!94_?,?O^(<]"R=\:@][7&,[;$7;84LB#?M9#<SG8NLH^0ZJ40Z8
+M!46)C[M/J:)X<>)C3#T#*>0KJ/X6_W(.@$DN,PP*RJ(03?G$WR:V?5;=M5:X
+M6[?JKG6WK]+=<M>JM7?J;EWKJ;M+=]L=W[K#H_M6W:IUM^ONNF<36.KKZNY8
+MZ]&M$];>ZM%M6+<*Y@'"NG7P?3,#I3GY=;.3YN3;OT\K%>+^@7=C,2-ZJ3ST
+M+JYVV*3'T)NHN*/S79R/`Z]?(Y^B^_&]PS_X+G/H$-B!3^*.??3OZY2VZUW5
+MM^+.^-.SRM/M.JACP*_K`3-1'L01Q?<4Q5>SB;3:<;L.QG7Y.`B2Z!]Z5Q%G
+MOGGB3$02@0]YA"ZJ%N][Z!RVHES*H9^"5S'J6=,SB/)4TS/H_>$+]O,E^_FL
+MXW[T9(3_R0^_@:X>L+;V'5AYOKES&KK&VS8#/1+AEVWF&/WR+[=*5.]MEGGP
+M'%@W[#M5QS]X:"J3M9=>7\UD37[0J/-_^W__+_?)Y'?K5J,N"F7O>0)TT1.)
+M[^;'__VRM/C^+_Z"VXVZ9Q4^;G[R_[9L_#L`91]YD/:UBNW4^IY+8;(UW&86
+M+JJ*[<$/Y"]VWSNQF)QQC*T2TELSR.DKN3K=FG_`$"K?W*%T<+ZY<CJN;NV&
+MG"'+^<P7%DD==3G/'`7[S*H:AE[!_??!%-PW(N[/PL^`31]`N-"5=`[.:SU.
+MR[6\OR@7P^K@ZA+O+X#GV![L?Q+US=CE"MI9PXIS6WP#97P>(<@C!,UYB`#7
+M4_GFSV!T:O<_C?VLW?\4_F!<,OK0="+?8[#HM](+?'N*OBUDWYYZ-[57/4[X
+MYN8E>I787B[N2>U832>^XOD!\<(@3,0B'D6<#X6K8%Y_X@;A:UJF\<W_`UUU
+M6_;6';O?P4&$X6I3<,&$UH_?B_(]YJ*%O/]_0"5O"^"7T'PR?AC_?/N1,4#:
+MF^>ADSY\D2:+.YXD'?:XHF":]C_%@%"Q,(968?.V'H_KINLA94T4/][U&YR+
+MK?F"VA^?_4&`7W,*WUWT_A")CTU^I@W?MKY+DV6;;#R`K\VD[V:Z8GM4L"GT
+MO8G`]@25CP;Z6(^83^+[,+UOILQYL3V8$-OSI`+\'"4^#W7'<)\V^3>_QGCC
+ML3T(7@D?%*GXY:^I:$4J8$C]KZFXSHCYH.Y!>GF(,<)'+\WL92.]-+&7.^BE
+MGKW<0"]!]K*<7C:SE]*I>!R.;YX_E;GTOGPJGEV-X/K'?N1(9HU%HJ81,\(E
+M8"<=N#0:"YL"OB#\JL*,6PA=2O?Z_'S,R3(0-Q_%175J08!HVD\R+%RNR2J_
+M=(`XJC)I5UM\??4Y#3+?_L<9Q3_`,6;/LR0S-*1YS@F4;322RQ<2"?F!)]@Q
+MX_'!-1;9_@0[7DS#'R)UG8_.\S!_@-LH[<#/'=S]%,=Y,+1K"MO_`CH>:D'Y
+MH78ZUHKMQ(ZO-%O/9QPSPV\U#)6X/\;:[7NO:'KS\(,HI,5"EN3K`FX>[YIN
+M@I&QB<9$73U\W:E\%0.DC!IS4'\D=:LUN=CK/5A'I.*+-Y&3ZU0QO4$EBG7D
+MIGDWJ9:KZ+\+ZPHTWI:+3;V.,:X&7EAAOOUW$>-,K+-*I!O$'5W(D_VZ/O0Z
+M?#L^[T#+0-QQ&WWO1YC]-[S+_&%I=4K;>:?1)L,.J][S-50<Y?9WH`7/2Z,N
+M^)>Y>2Y0NK=3C[E-$8;/PB0;6`/&ZE!&%O"IZ<2-PEF2'PE6Q@7>'\U$!4'<
+M\MB:3EPB;%09<R/OSX`B\=LM[)NOY93=8=ZDLF[SJ6]X%JDI7V+*9#7ERV\(
+M)DB_R3,KCLUSOD(?HQ5L^SV=](H\"7]5A;M$<#=MUM_H6:XPJXMOWG\NBMY`
+MHH;)&*H"E*;4%ZM_*$QZ!,56!+T9RH`F!&9R?//OS%BA;_#^WYA5YC?-F\_[
+M7R;OR%1@A&]>&B^PG92P3A4M_ES%7Z2V':>>.Y:MU71BON<R8+SG*PS><T'3
+M?L1I\IS#OTS8MSXT"X7D%+V$?TQKD_3<WDP)0#!0V)21(!A:9CVY/4:Q"FP_
+MZ[8HB-MUV-A^_/<5ZI4=T9VZO_^$?[QMZXZ;,8D!^\Y!8%*F(\!6)L!>FX9@
+M^Y>2\,:!$Z`N#>B%!%HV&N@B#6@^@1:-!EJL`2TDT+FC@<[3@%Y-H'-&`RW0
+M@%Y#H#-'`YVE`;V60'-'`\W3@"XF4-MHH#D:T.4$NNN=44"M&E`W@9H36#.2
+M0"UQT*2&;,[3JY(A43F:$IHY3=J<=Y/39%TBK2@E[9`F[;J4M%V:-"160R:9
+M36J:+2F?IU[]/C/Y^VWJ]]SD[TO5[W.3O\]5OY<E?\]5OR]-IM>_,!LM)6T'
+MOC%;[>[JEXNS\;1)L&G_S:075XJ_\Q_TCMO:R;\\>+P=G>=Y9E8KH]?6(`V4
+MPP?&J8N[;"`+3P$]X?/@NVZX;->5\62\!W*C$97N2D*^>"3R:2KR?(:\53;[
+M^O0*WDD)O-L`+R0@QO&$T34:QO-5C.\]HF"<I,&HP7?585G!^(H!,2XBC%\;
+M@\8'58R9"8QG)=,8Q[F:<!83SKDC<`I3)-]FW!MNF0NY]*VR`;*QLY.8>19E
+MGC<:05-5@H8?5@@:KR5(2T^K;%0(.H)3[?T%I\7YC(K3,CI.3L'91#AGG1;G
+M,A7GY%%P7L4X@#CG$,Z\T^(\&5!P3AB=SG$*SAZ:&N2<%N=/5)P31\=I4G`V
+M$TXKX:P8`V>5BI,?'6<&X13F-NVW$+YOC128R5J!(6DQH*QXBBI5XR+)+E(*
+M/_QQBG4D__0%,A@8(27L!@S_\)=?H`&`II$^5()^B+>1[<4LL*:3,4].4)V'
+MG:*I&1O98T)XS3?2EB_7C"CY$E;RFODC,]3(LQ+@"*M_0:4'O<F'?OD/M"F5
+M#V!RN-*7^:<_)LITV_!<T"N_I#)#=R,"Q:CEFZ^<@)-##6F7_I+9Y3"=;=?S
+MS6=/P$.[S"B7R#B>GA'236"^IP$DC_<;T5ONO18EAA),R7%O&SH9?K[5@FM<
+M`&?F_77H++Z*P=5BJ![^H6_BIX4(0_D,.-TNL-!:@!5Q7(3>_J=94E7W-FL:
+MVRNP[CW?*3?_8/]X96WKR<UL;>OF>J/.^H!1-\MOU#WZ;:/NZ6^SW]2_E?6G
+M_U-AMRK/3?7)^-;5I\?][_RM])X>YG:EW,W_!^7ON]^H:_89=9JV7I=%2YFQ
+M^YFS]5UDE.)*IYU6/H4Y$OWB49C8'EP<E7DQL4Y*<^&_3-3I#C\7H<$;)[%X
+MF_Z"->0;RB8??"F^9O'&1`JMW6(6_?OBQ;3V<=+^UVEVABC%(H/F^[[$]WH#
+MITG8I4VPQ"A!TJP'AV[.8F<^X_7<FDEGF&A:G@MR?;Q-!T++^^OA^SY<?0H]
+MQBNQ85XG"X[#[AB()A%*)4HV`RM$VD^O]1F<J*%4*C-8F+W.9N_B\0IQOTXS
+MC3\7IO$FS33^S0?9--X2#*[)D=<_F#*/WPH]UD?S>`-,Y''O2YG+DU]9B2Q-
+MXLX.'<WUJQ!D/P/)H/WJ'02R,H.C27[12^KB3&R/3E$YL^A;%&FF>F,+3H'V
+MVT-@N%;T(K6BV!XV2>SC'H0FA)_\"M-RXPLW[UJ(T^SE+0L>JH2YLX6MN[Q*
+M&@'+$`VAU\SJ6B);/^P'2U11+^]E*-J'X_WXO$;'VH4)U<Y?Q84*8\IHA2II
+MQ>2\E!63E0\P5N-^U!J+/.Z!%%[G6D9;,Z&:ZE^DI3;V,KB+K=]`Y?X\'H-\
+MJ!0;^.;SX'FXW<K[)\<G@6PJ#@-@TM+'YR;<6""&PG]O4$PUTI1+Q!W/DX@E
+MH(5S"#U@?12XM2^38NXHNGO4V2S.30^+.W!>(?GQWUWH@N:\^##,IAS;RO:I
+MUAL;CV]26A.CJ]%#7(X"ML=08Y>YNA0AURXK7\PWMV:EFUSO8.180VMI+;3I
+MQ!S>_YHN/H57N/%?M&C;.":&?ZT^Y?YAKZ%P.##W97$/`F`5/.NZM&.3YP*8
+M;F6-M3(0;@8L$]^(-=*!)]8/%#[56^\[A=\;S7;ZW!!OJS]#%]R7A6UU^7AU
+MG+WO$QPCV:Q2N++IQ`V\_Y)3J2O8FS/'7J7P>L[Q$0;H.$WQ0OZ']%[R(KS\
+MLP_575#MPOOXS,3"^T(#=E/A,I;%-Q\^3<4X/+1P6?>"JMD[,I0CVB'=.-*O
+M.TC#[8B\@X$[=@R]D^AZ>=)^ZD=EC5I=]_;]6EWGOS^E_SUECNLZB9"FJ#,N
+M29V)G@PSZ&`":]0JQG%)BE'T&,QKOL2*E/R2CBWMB2A:K1#?_8/O)%A%*X[9
+M_XV?!]Y15]&S"$Q^AU:K\</7?X$?^M]15BA??1Y?^^AUCZS@/DP?>]G'`>7C
+M0X2YAV%B:^,_([@CI%*'%+#O(E@KF,1'WM&:P0W/:XQ>U#MW9Z"F'62:]F9Z
+M&6`O*^A%9B_E]-+'7NSTTLM>YM!+#WN91B]'V`LJ+EQ9S<I@>MN0D5@OQXIK
+MULM#0P8F"\^3+`PDU-9)OOE%TUB=F>E^LA>'F)]>1?H?^+,^OGJV.78#WWP0
+M`Y)UX=Y3@A_=/U-'LOC&T@6N1/*,7Y#4B_ZN.`3*70>],SGFXH/6!2:L?!=[
+M.=N$BXXU@HT-@(IY_>-G%//:)M69PY<,-T\E__:>&2,/5KY&!RLMCS!9+;3<
+MO\P_W/@[B?"+^VD=?!/69=\0;O9?%-QW+$8QF/?]G<7OW/<Y_DX,[AO&7U-P
+MWR!>'0N=TX\Q$%"Q%/-^O(/4U-JUE28RP%0[V6[\_4O'X6[^GBC-*2+T+YEM
+M\TCJK,TPZ9L]+G5KX=R4@3*_,=%/+?+1AI1^.L1IQDEM!T4'ROS+--^B'CH8
+M0@>OVOW"WC\EBT"BO8P[XQL1M\=;-KX9B?+NY9@P"F@MQ.=/`3\NY;N4_7W,
+M_J,CN/-$\0MD[X]0')^/,QX[D*KD/)?%]NR.[\],^UG<J+!QF@T9U;1`_VV$
+M0C$TYR?I:_^"OE3K(W6_YAVO9K]&]*;P]&FCUO90&/J@3K4]_#]CW-DSJ-AL
+MZW;&[0^,-(0H<)5*I%,2BJ7KR<*X;KK07FPO)@8AF&9(ROF)`PHJ\2?([D.*
+M]ODVO772"$O5P6@OP!@,%(M\[/`?4#I0C*K+.HG\9)-1V:M4:&2?`T?P4?,9
+M=1YQVNQ*V)>_QO;QM["]2)@ZQ$'O[04MK(_M:5'>U_12?Y3V;D6GBP=R?*?T
+MPMDCBZT)K_4/>S87'F0CE'T'DNQU=)#)P.ZI,$N!C1D2-Y\.D=FDLOE<4U&!
+M3LAB,M/.V?4^RF0IL0<056/'R-+(-J0:$.\/6!5Z]Z@L??(G2H7A>=]/:$A@
+MN3L5@$T:@"?HV4+/;U);''B'G?F!)L8`6+[]AYB>NIM>.A7]CQJ3*9X=^"ES
+MOO3:\_1VB+T1#T1J^@Y_7_R03*]ZJH6>H!MADHOVF__P\[A+1P,[+R,]&*08
+MOSW(M`<?I^<CU"6>C4\^%)5,Z)H66?02880G0XW\XU]B"KYCQ)(6;"GYSI?B
+M,\FGV,%#>>`EULI)-YD4^Y.['\_M5-@"5##0B[2X:F3='O4TX>IP#9[5Q7/E
+M2LRQ?6@XA'[%GM&&"3W'GL=1N!3V/`&?`^QY(C[?QY[1_`\)[!D#%87N8+'%
+M=O2PI1?QB2`-5DB.R'A28\'+8IOPTI&QSII?9Q-??):V\I^G21-3!]\$#6!4
+M!QAQ+QW-WL-8<NBGB.II$G%;C"7!"/0W/,ZVYP`M-1T\'(O-U.M:FGZ*YXZ^
+M-#_X5/RL`/8?!G3D#PC4TC>NZ:>XR/F1F:+_T8Z]"MA"@+]0`$T,\$T5T#I,
+M>`V>20DJOO]]:J\U_V"ER/G=L5A+7P;N^M)QIT;S_?BS9EA)']^-N*&.+'[V
+M*3-%ZJ9>,DB%3WZ.'==6U.9XA3\+-].AU^>>>D<-53/R?/42`0_U!NE:Z9/(
+M>7=4C/AC,!I73!/;6T^-PY1M2+EX4GL]T,_]BM_1(KFC6[DI%?=1!VAX%6";
+MMF%U]9K[I]7,90F,NNAD4'!(IOQR;O,X>PGGG4#AY$-_8F>JC7K1).DQVC?>
+M&K8:)TEZ8PEG[]IH$+O$<G-'.06Y"CU#=Y;L>.$(,1E+S)`-/9]PZ&P"\J'7
+M";.QQ)*:,WPGR!QF@:(;+CVSTEC<>T<02LD'N*2"Q"[V5:HT&RLM]C;(V88.
+ML,@CJF2B2$+V<O/&<11(*,7G79&F#=HW&'4!;S\&IFB/!UO#`/!ROF-0=/13
+M9.F<@*/?)3^/H<^\G<F@@M4H',H7!D6A4P7M=,GW4?!3<\S$OE7+ZTZQTR*.
+M?KNCT[,FB.V2;:\V>VK@$_\R&`23)<&VC2N8QUTNU,8<_92;P`?P*&N<B(O9
+M77G,;X(*"KQ:PD0E@4H0?JC\GH=X)JHP?_TR%F-<I?C)1KK0LT]S)QQ=$SBM
+MY"HZ4P*B=`=_#>UFM;O,GG'\RX:#OX8VX-_0*7<^K`DV-M:1KP?F.542<D1@
+MGGM(=$9$0;GI/).<&/L6!:*@]GQS'J*?'`E^])]740CO/"+3+,]IQ)H4!%P<
+M!N6ZG!T`#[`U50[*B:XWZH:4/[G#8T3YW7=*L35CY/Q#3HU)\-%ZO%\Q-R84
+MQ(0Y5-I,M<`<YE%:]5'9$'=TH<W_P_58/ZLKG@-O[*A7N#\[I<V3?.>[=CT=
+M%MU&:J-+%EM]?S1B+`TA#V:L,P/HUB42<`Z(SKA;+6&(J9H338_@#P>D5J-_
+MX"12:\A?O]AF%_(\MFT.>:81E2EE8QK*WUW/XS'9:D[2Y1OH;#"Z@.A-XV?]
+MU^O4NB%^K)1+8<:EL72^0;:O8^Y*)-19T(TG:7WP)IQ;8'R4'/]!3T[3TZPZ
+M6_''(&:)=>C[/7R>\IW=G.XH99<Z2CDEC$"<3O1(V>+O]DP`F[=>7RQ5H=.,
+MOZ?S3W3R'CKB7$V^*D1'%%@EOT:/$=30WJA.R,=[`';!ZCF73L3#$_\`7LI@
+M\>K_1LJPL"74SWRC1L"48A<WZ+RT-QK@]B-]8$RN'I*@X;B`^CHH?HZQNB*+
+M-N>C'T:,9S,0YH)`+9(=D0P2-+(>7UNCZ,G'.V0_@5X!H_#4P3V"XBLY(/=T
+M<B1Y'S:8M)'S+<"\)M&`SVU1NWNP80!OVCL'.[A7D.3"80PUDV'7"^<B5O<0
+MQ1$;`&"NG,JTZS&.V)#$[7V5W54>M'._`K6(F5$@^D;Z@WII+<F#VFQ/XWAX
+M"D]:XZ[@5HK`V]&DG@GN:'HZ_O2L^E3,?$X7Y[+OM\<A[E*>`MLCCT1C8A#=
+M;G0T;5:^NB0?BE2L0!&_1AA[I>UHDTA@-XV0P_%KF7N]9R-X+E_U3I,2_^1N
+M!M/I21^+I`/2`PXT5\VQES!`KGSIN@2D3L6G$;(==ZO^A\#`RZ_@_"T-X^V#
+M,/X,ZBNXV>2:NT86U]'\"&.0O0=J<;8F<D,:.Z#T[OC%%0S[XS&1`LZ1?+N0
+M/;KLN'P:F.WFM`WK\X0!],H(TT`S<RB*^P*6#@.N)*[9+,OWT!4\=,2++I9:
+MV+P_OXZ#J?R4*CETCTJ?YSE4V.O-^>LY\K>.>W:<W`KI>&?*0@Y4G#88:0/K
+M]&!Q!,JR]7B%3+_A<G],F"A-TG>+[HB]:X,1HS@Y+:+>A>X`+I=_FB"`C..O
+MDH!CU!VCH1J]!J_G7/+)M4@&&IKZ.DXO1`'EY"IY:9PXWO]-\B.`,7DZN$=9
+M\*RHQIWVB/8^?B>YLEFCDY9PDJ&2+@8<@3%#/"RV^4[&A&D8\>Y<:3MR%I@G
+MF#IHO8VYPJ:]_^2V3\7_Q)TH+]:$BJ2!+SE+LKRLOE/U\<V_<%SQ67!^$"^>
+MX5QA,W#`WHY!E*SD5[>P^_AQK:SH4F->9-_)8EY,4`<?DZ9VYV/M<D:I78:8
+M+2[CM(ZATM*[9PW=62N,#9?K\SSCJ^7_7L]D@9/*YU5+Q;/(\:3])=2+GEP[
+M=1J/S?[2;ORU=)AHSB\7@TCC%=SDFHSD9P64)AOOIC%<^_TR_/YV+.U8?-8:
+M-O[X\)"HN!W_'>%?^+,[%)B5!+,R'<QO$8:0Q+K2Z89?4/K*I/14^A\$F-A+
+M+:@X`J@X?*_KU?`C\2QQOQ$P)W186N5QXHG6T#@8\6'X[MQ8BBZ5K\'KLH6^
+M5@Y#D,'8F0E6`7K'M/_.,STH?N[[6`_=R]>GG]TF=N'!![Q;>OC3PW='PA\'
+M@TM@/'RSM6_<;+"_'%%\Z$`%XL'89V>)D>,]=H<E?K]U#8P/JRW3?)],(ZF`
+M+OMVW_$N=*ECGE%(G\03^`6HF*&'@1.$\SR[U^)A7N/A:<,L)D[3H:^$<T?0
+M)F0RNOX2#*HQ*G5ZO4%O,!CQSV`T<B/UW^WJU21%"^*RT'=PF."N]D6F;2QG
+M=!U[NT]L0SHG,48IKJ$QL`#8-KX^GG^Y.>?I)Z(QO2/2^E=.",,(K7=&`_4+
+M^L)?0QL1=PYF1]C0U_KVQ^Q]<'8$7OX*4P3$7#B,_A\>9KY`DG"V(\J!\$:,
+M"=;ZZ;CP7/(I.8*4*<&Q:%FVY2W@O&?NJU3T25:OPV_+2KVP=(\M7;F@'--H
+MOK@\)L<<_+Q6]2?G.\GS;%*/1G3!=YD1#<GU\'<;_*V$OR+XFW^S49<#OSKX
+MZUUMU"V"OT/PMP_^=L+?4_!7#W\WK,;Q-!>#H<ESH=N&'";E+';"/*V6OX<I
+M^2;RPQ6EX*^,/^%;DN'>OPO@C,EP[$<;#86,KQ%E7(IE=(Q+EY?]L+Q/J'%%
+MM##A!6H=;D<*[AN7#F:^(HQ*'#UM/1)E$.15:=(5^IDG=H5V*&\=EC>)E>?S
+MYNKX9@Z7L[TY^5XKN?;.-3JMHK/3=R)OTR:2DGQW;EQ,H%-"'W#TH2:90JZ-
+M;1C$I1&&:/GX>V]_')X)#V__57+D&ATYODC>1AN3\4X<X^T@YI^(D<PV$*3I
+M75<X(C-,,]Q#5[@'"[MF`$IW7V@]I]`EZWC_8WHTCVW\`WO(+,G1>=:_R31&
+M#J#!:3",RK89>D($AN>,281J>D0\>;Q[1G9FEVCRM7/4/6`BD`O9`O7V/M&;
+MBR';*<Z>US9CRA7NR(QLR3$T(^,*QV`A>A>'/*QBCMP^X-"T34<8GWI!.*DV
+M^8[<#D>GTHGO)CH`4T:<CBFA'S!?Y$B][SGTE>?.,;ISQ2Y0O:U]!GV[WF'S
+M?3Q-=/=Z%C#^=(V-4.%1I^3N5*LF.7MG.W-][5&?PQ9%,C=>,E:=HKZ.:$J=
+M<J!.9B#N3)D:>ALWJK!.]R]7EC,7BMX>*)]34%@1Q1%LO087-G@FRA$F$]>\
+M,GHA=_2@A,A0$U#S'V=V`<W3VXC@&8XA(G>&^XCD.'*\:X8I$TB7O)U02+B0
+M!$QT]OL<<AX@>;OO=!FA':G5K4JK^V+3-J(_8"0;B5(I$4]*SO[TE!`2JJ+"
+MM38F"1CP*"$)76K#=2&^NWLD;[_=FTM>GV!N"F-9)I3DZ)GAB"I,[4E(/13:
+M%?HVNQ.6`WTOL-(>(S$!,@-%#V*+H9SD`+N6T/?`W`?HBQ4:;/9AG,>C*W&4
+M@7W3%$$:4.D9P);P+E%K'$UFX2'HR">IMZ9OA`'),:#R$HH(7QD,)K7C(:4=
+MQ\X)D@?*8%&^PRHZ<G$H+0DFVB!*6/K')(104!6U;>"I4OG_IE);$E[`M?J0
+MY)63^"]G0BF.0PG^'TKP7]NCDN*ADB-R]$&.=HP#K";](%"_:?HKU%V/T1"N
+M#.#Y#HO8.ON8V!4NPS$^;M3,R``]@@<Z,9:QI[!/_+SUK^-P2S`H*2GG+MDR
+MY/O+-,]Y"E;*^[;LS_`HWC%4/ZHI0ZX:KQ6=PU,WCAJI/^9[T?\=2(81YD'.
+M'E3AMRLJ/$>CPBVHP@?!V%%4N!77&1JSP$`@%7XA^@)&'9YC!#65I,.M"1T.
+M+>0>E!R#H<U&16='0&>?2SK;NM%+KLT<"C-LT%NA(UMG3)G>INF>K'`0?-9#
+M<S!T;)",S^D3,1G,3Y\C!UH]9]HFF57T+"AL9(U4W*$!@Z)WK;Q/-M#)/*,[
+M1ZMWK=1[!CRS%"P#(['$-8]S8+8SAS2L-8I$;#R/G3^1%DY?H'[6T&<#^C88
+ME,E.<J5#*X@PI.M^GD7JH8"V6,4W58$!">Y'+C84*\D]E,SZ7$3T#DEN66F9
+M'E(KU`;0$_L3NK('AO#P=&I)T3GD<T3R(-/;'Z<"DF[,0;EDG$?=6,#JEJ&T
+MBE(6.DD9>ON3S)/321<ZY'B-NUF+W)?0A3D=CCY5]_1A[KME7&7RYFRDY3A%
+M%X+*D)&>/LG1%_HJ6T\`?0"C<T+W64GWL;:R@<),UGW8LU'W15#W]6(SQ'5?
+M5"T_BISTSJ?60HADEO2^_;$800IEQD0T;1.ZKA>Z0#")[[W$BU1(TFTYB[#_
+MH[$S;6-A,,[#*/&P%YGW,3F:>?LSQL.HZ.A-YJ&G1.6?1I?U8,[5O9(WDL0_
+MT&6]@!8IP3%%I22PNBMEOJZ=_W\#IX6=*'8%@:)=&,L+"8QU+?.=B@E_UTR1
+MD^;YEU*V`^CN;AV%G/18)#2H8/:]0"<,:>*LQK-\<;U1YWMMW?D8G(7O\.$#
+MJC'R[91N?OM;@)>7:Q+3TO_<]72S&[@H6**OV-BNQW;T^RJZ7-)V3GEP6J3*
+ME:)KI51YG>BZ3JJ\073=D%PW6AM.1I,^4R1I/\*W^;JXMX\4O]E9U]-2Q1I=
+MM7SS#<@N(J;<Y3M@OAV=&N(22;7\YPEX:32M?_V#7U=C;2!@;@J.&I;_.27_
+M4/H8;GX5AQ6!>[Z1AHX:C-0LWS@VGFM4/#;$$TS!4\.6_:OEO<E8DG&<N$Z+
+M8^EH.#:,A6//==KZF$?B``37)R%(B7^5E+_S^G3YSQTC_Y5)==AZ_2AU>,$R
+M1AV.U6AI*$M+PW<L*32`K&W3^?KT*;+GX<D(,369(27HRSN5INWN4\M#IZ1<
+M87?8`&./;R[.NTMSV=DAS]6%W1B^&A-P=1P2I%)+J\S/U>_4>\Z5LOP'/3:I
+MQ+7&R+_I*M"_5245SZ7[VL<[*/:LJ5H^\O5$8..4^+\U%'B/")U!P>8X6GN%
+MWG9Y?*>2BB5'Y7FT<A$G$#)H^8@[.#HIM:_]H)JJ2$7D!*HY4:U'>1YVDRKY
+M(I3?1*WC/2Z55^[J=+PZPG+Y3D7IFQ'WK7PS&9]&YZF]L!MR>!CTO\C5ANLT
+MX:)3X_^ZC10WUS.;F,J"CG"B'N,PO8N#0F$R=[%XC!&3H)V%EZ=\22R?%*^R
+MEONIY<]VI^/5O'2\LOU?\*JJ9G1>>5>2LSABUT7$+G,RNZX:E5<*[2G\F3<*
+M?S3Z?V5")J<'RO%T`,S,-?5CDOE0->TRQ->.4">LQ).=&KYI^*H=*Q+[ORN8
+MWWY=K$`NR]"EW4OZM@;&D@RC]*DQ]8D"DZ2#M/Z_5J23A1Y&,W1(?[=@*CQ(
+M^X;+H%YX%U8LR?6=C`@9\-F$MM$2LU+?DER`9C@F:[O9.!2GX"BR,X2R8_F7
+M92?;/;KLE%0I_6P."8Z5!,>BR(YES*YF233A:-VN4F7'"!'K&2%B*?V_DL7_
+M1M)F!BJL8H5%K.#$#(PVE"QCLU:RG:PI"?PU"7(Z*EA4I!H-M34:JJ;$25ES
+ML_R;%4H(=QK_5HQJUTS`A<,,\7-HRLSVXLD<[1_!@ZZ]^"P=NJ=GONV9AZS:
+MCF)K'KQ8)M$WFRFQ39NT39/4OW[N2O2OF8%RJUAN4;I8:O5GKQC9Q8X9E"ZF
+M,H&Y;:3,*A.J-4Q(2'/RV!$GYSQ7HG^U&-/WP>/+$S!;C?^1/AC'_?WE;"_9
+M4Y5^+_G;K&Q_B\?DDA])`*6,?\L3,C4]$!>H5*7U;N69"-24^#`"@O-0I49P
+MEE<F"XZZ;/Y#8UQJ,DAJQOTK,B-E2%;)UT5%SV,OA^C%I9&FY'K?N"RIWN91
+MZOV1*VV];8F>,B]>X>^[-!6^R35J3_F3_O]1G>]P8@?*876F((IDETU2ZERB
+MF$[AY:S.259908OOE-DSSG>*$PR[],TM'O@"!FV4CGU\_DNQD_;H`O5Z<OR'
+MIN[-\K;E&H8XEX\P>YD(>/0LF*G^W]<=A$;+%KV&+2/M2NI[1NAU4G&N:G-+
+M+EN^RRIV)8^WERV-QY[VKD@3/Y9?ROKB=2N2^F*R7]&_?HWM@SF4\T@=I2OI
+MC,4IOG'<&U:2J.MPQS+@NV%7-`8OXI(;_`?QO9[>;ZB6X)L;YNIBQQJ]_E1U
+MC>2.5LEW+</FLJ%;VGMMXKU6L2YGN%2O]UBJT)WS`I1S3+*(]^(YIR1_GHGX
+MMU]#^C7GSAY,TA<)__\$IP)='P=*CO_]-68:J(T-HM.0"^IMV*2'F3.(SOC8
+MQERI_`;:N5>"G=`<Z%4GCLGIXD2]L`1U6<[6MJ;/]7C>I$T/[7:0$]_::1",
+M36^9J^BDGZ6J$LEZK3(M[7<NB;?AHY6:4Q)UNDVIX_\2Y4R-M49^`UHVX+L9
+M'056@-ARQ]O)@L@*^';MB<;PX&+`]R(\N>@47%-E\CD#;?GAQ48=.35*FQ?)
+M*JW4\#-Q_FDQDZW<RB39TM#[Z&+5%E,H+7=5RW\FS07R)[_MTIHZ2;AK(.<:
+M7>PE]+`@;UB6EF]7(`QW^R"O4P&?<6D/F<3]O6/()C/>#3S^H7C,WPV_[]O?
+M:N#$P]2Q.;$SG.T[J??P>*ZX4WSWN\<QHENX'X]]#6D6K%+F_XO2V9FS=/_9
+MN:SY:Z/-9:]<]"_-914"QYC+*L]2<1%Y6DW6)V]6*'8#Z*\E+M;C^#=+%NG;
+MJJ22I4GG0Q0P6F?VW5NDJS=*I45JC.XXPK45C(TF0HAZ7HMNE/4H>T4ZWN?I
+MSFQNG-Q&_XGYWBV+1[?9`^7_Z;GQK(2-GJ<[W=QO8GG2W,\RRMPON(B&5AP/
+M5YG3VZ,)#B?;G1K__XXS*FOF(L4()O/W_G^FN.3R+C^S\G97I)G79IYYJ4EE
+MOE%V1F46IRESKOF?*C->Y-?*4L;`:S-UZ6WFZ67I^H55=V;K(/_Y?K&D?/1^
+M(5S[GU@'T?0%ZVG[@N':,UH':7;$^X)[W,CE#^N8\O&#TC,J(\^A[0,-9U),
+M<CE7G5DY^\I&RN%UIM.7EE366R5G5-;2-&45CSNCLN)%?;,D1=9K3*/(^I4E
+MZ60]J/O?6>=)TS?^S76>2Z\=O6]\O?C_<)U'TX6"NC3K/)KXEPO/=)VCI#3>
+MA2;_\\L;P=/H_?EG3,<K)=IN-N7?)R6)CA<7G"D=A24CN\:%_PG&)-%SP1G3
+M\Z/BD?24_(?H2=Q_N2:E+TL&;5].T+WFF@3=YZ7;,_E\(9OXFZ3M)*VN7/GW
+M.-1EXZRTO52=EY?"O+P4YN4&Y7:,<E>FMJ,4Y^6E;%Y>RN;EI6Q-+VV[OE]T
+M&GIN&4G/PO\(/7BSP!0KD$.@'-+3MN!TM+4O&$';CZ_]S]"F"`M1>#44`QA-
+MDJEIT60N/:V/??4TM)X[DM;CI?])/OZHU*C03:_;2C5L39;!O\QGPTDVND5Y
+MO*6ES["U=')<>BEWV37:*H^BFWZ@X,$,7Y1H,AC2W2?0W'^;SR963HNTO9EX
+M,5.:)%I16:\WBRY.7$?*?;U5=%G$=?#=)JW/$5TV<5V.5)DKK<\#YHGK\K1U
+M4ZZ898EFO.119Q87$98E%JG.*BXB+$ML4EV.N(BP+,F5ZO+$18B%W0)-HJ_=
+MKJR=$''E,ZOE0F-R_Z'YGGH7S6$^6FR+SRV/XC)6DF[89&>AKX`^AK%D)JZ=
+MF"KE[")E#I^E*U_E6757WHI5=Z^[:_4*SRK/'1L\=]R:M[JN[IZZ2_-2UG_L
+MN!KR0CNM69@#OE_1TTM#=*ZCB#PRN.3OJP^/P<,:O?SMA2/N4WPT3[FSUSOB
+MSEX<YC6$\2$`2D;*I0==W\*/[LYS?S']Q$+E0S'[&5R8]<'R]LBNT,+OE=3?
+MW#&-*UYPX]%?]5SD7_CR#Z;GOC0PO'#[@<?JCML[%]YSRZ)E%ZUU+Q0N]+G=
+M[C\K>&862^_7__SG/__KPA'W`KX"!!VE&ZF!UV[NB,:.9O2\]U%?4[_CU*&F
+M:#'_&,;V\@][N/?D#_]8T/W>IRQUG(?S'VPTO*AO[O98C_9(/EP(/JH++<;#
+M3BJBHR$$+6L:*A8L1WO>^S24KV?GZ$[HA1GOM7S8&GCM=@+\\"#0=#1WIKP`
+MF`H%'0OI$=)WPB!,>Z^EI_4]N??C]PY^^-:'QP*OK6,Y0LJ!]<H/N)F^`]S1
+M&R.`\&#@M<V0W+M00?=3Z!?*8Q&T&J`"B"96R;<"KVUEJ(",H/(-GY]DS[]5
+M<&4$7GM:^8*I.UF>W[[W%KRW?7CLPU#@M5WTK??N2."U?>S1&5$I^;#UO8,]
+MG8'76E28#P^^UXHU4>AZ"-2<`GOQ44<DS@G\#D:DX;V^I+A7FOAO5Y&PJ1<[
+M+>S'JKG?J6@ZM6W>ZSMZ?2Y[D<S2.DY<8A/K<C1]'K`==5ABAO=:>DNYH]=S
+MR*[>4LO1ZRV]5382B::HLM9I/%IEZZW*I8_L2P8@QWO,1WO4_NR;IVL<]]ZG
+M\/%H,?=^06)]>IX^\;VG\_V"WMNA(RQRO3\7&S(1NRI1U0>O)/71[HCJ?`MT
+M#>=4RR]2B!ONO4\_9-+(:.``0H\!%86SJ^5'$(3QLAC$`,^9OO<I6:;4W;YM
+M^V7%'^_UL/Y@2Y1UWI6*"E[D;VG,4GD7OM4E.2R^EML"V[O>@H8TN-ZW(+6J
+MG$5C,9!`!@UCTE'H49'W0PK/BCT75,L8J_<#$X/_P#L@/P\ZYX.[!T!2/CR&
+M\PS(0"%[M;H@E;;&N6EI^X8+^H?#$MA^UV^1M+@(33H-57G5\F.GDJG*UE)E
+MU-+$VBZNJV&D80,,C"X8X-AE3JP%CI:F/9MFHMF'<@SMM&F)\P]7J/="U^AJ
+MY.<Y\C2F+%Z;:N0I5Z6N"2,]Q1K:BBV:9YMF_3)11\EER7>9E;T2>K?FP[#9
+ME4K+L<O5\T]BQ%ANL9=;-V355,L_94354-`XBUP/\J1OL"3'-];NG_P\CF:;
+MV[85G5,`LF+$-B%0H7=5R]7)"/.OQ,5X(UKG&-%ZJS56;DEL?Z3,!9T,.6YJ
+M61*;6F+;\>Y`:4SL4$O*JJJ6/S,F%7-@;J*8=ABLRBVIL>42I7Q22*5L<ULP
+M>K>"T[Q&7RU_#S="M70.C5R/_5FA.A>/\S$#^/A-R*IA7&J9&]*5.1[+O(A5
+M1%,LR+E1ITOT_93S/X5IV_$C0Q(_=E]![0C=J%HN4[&EB\OY?L%IVO.!9,3?
+MN&)D>U(I'QJPE/1QZH2",V[7*<G%#5R>VJY4V'I#HDHCVC>C8#1>OZH?R>N+
+M#*/S>O]E(]H:>;V!H0'^5LN?Z'6C[>LT7L;L/H>EH-M>PFTRV4NL_!-M8()D
+MBB6XR!$V!UV5\@Y=XAXJGC<$?>2R;,V*:?N^VZ)W61*^#_!2=:>QU&POM=09
+M9R^QQ/L^>5E8C$9NRGYM1S$;<5F8]X._OFWU7:LI/O$]M7EK[UF[>C/8FQ1`
+M^98UNN6W;/"LNO7.D7W_EY<JUY;1A40P6'#0W^V97-!B/[F)L\_?P':D#;_2
+M-Q_TY$AUG"A$(3VS2GZRD#;!\$[K(;S+"/G%!HO88)8,Z+6EF@N?'_3'(,_V
+M>HI%EG>8_(`4X8]DB'6I4D7T6#3T3+V4&;!+.-$9!5L_?PE&$@7.P.A2Y$`@
+M^_P&@S2_1G0/R=T%N`\NN8?$.DYR1L5E7("[6BRUXI4T<TR(Q.K,U;(710=!
+MS'@W\YBXQ$)^0Q+KJ]B>ZW%V8H1)28GM>-?T-K'2D@\SEQ)K?@EG;VLPP1.T
+M+;JD@48>3,0/ICD*&-'%'#"N!1C7;6^OX^P%FYA92HP3_IB(T$HY[UB[<57=
+M':N@96I7W7&74+<Z=2YU[B4D9#Z[CO\AVKZ^+3:=9YSO+^@G=-BWA=-YS/A"
+M<0"'I1+.UV*VEYCK,O`CQ[Y9X,,F$WXPJN_6NL0[U<UN$+1X%G-XW:819*#%
+M?]`SSM\-1$/C9RZ!E#`&B/1W-VC@P3*,MVYG=W+K:E>^1IDO7C4G,5^\C>:+
+M'`W9VWO8R[9*\U;7&4T9I<J9TOI9,-\4U\U*6E=*&`+_&C*-+R%-_.M\4A]@
+MI1YUV-X[*+G!GB7ZRVEYH(<]'KW)=K0Z5S&"RD``C]XTL[W<G#K?3)YCVEA7
+M1Z(6Y8R<>P*V!!G'OQ(GHSP7+*Q$:>]<1J61X32H;8,6=I\I@>,EAJ.IP:P7
+M)B%U1\LMH?O8/=JC/;&KY+^#',:N^L#;+X<N0:.LOZ<%S+S0>P>/NB,P^6CI
+M^>-1]R`\=.+?AVV@/GNTMO!K2)$-C+H>^4>0/[!]WA^8<?C!W3T?GE#(O1C)
+M=41Z#KYWL-<Y"%3HC]YDZ5TVL[?<%EC=E21#&OLOOC:`.LDLKN.T;35&6KSN
+M>V>3^,4*Y*EYNC1G`YZ(IS=,2Y>^B:5+V_=A@ULUNAZ*%JTCY:9\-C&;O`G)
+M\]%9@6G4]>%SM;`3QX;]=)8&-GMLV#8&"X-7K`"@EYZ7#)WB_V26.DX6M,"4
+MQY,EF6I]FPTZIA6R0#SFY-,8D-@2."\_U?;5U%]3-N3M.G=$V9KZQ^L$D!-S
+MT]2)S>U4K9K2-A]<S-K&;8E=#@T8F)K&)\3>9)ACZ6"V,Q@DHT"^;)HNW1F.
+M>[0P'Z6'^1K!X`HRP'P")1WO&5'6Q5J8)Z9I833[?Q?'SSD)UMA5:W38C+'+
+MY2^F(8O2KZG_[J+D/'HE3\<8>;Z7G`<:['+YVEFCPZ])`_]!X>CP\]/`K[AF
+M=/@L+?R:BY0<LQV:',GKWQ=JX>L5^!-EH\'_/`G^)@7^X*CP]UXXHAT`?M6H
+M\$LN'-$&`%^8`J_I>^=<R.:8<0;)D7/)$[`K=K4\?1G+E[Z??3B3"3;E0Z4`
+MF3==,#IO?SE3\2$!\%#>\1X7B4=9<I;D//<FEP$EW/B5T>J^;`3LA9>/!GO!
+M"-C_N68TV.$9*BP)!$'?Z1B]GNT)^'H5_JMCP'\G`7^3"C]^#/C:&:FTO[)P
+M--KGSTCE.7!\FQ8\1?Y'X#Y_Z6BX/[Q`@;60W.QTCM&.+R;#=HT%^T`R[,SR
+M,6"OOX`Y"63TFDD&_SZ&OOE*"CST#_G78\"?G)X$#]!'+QZ-'[^+PS(Y0>AK
+MKQT=]P\2\/4J_%ECP*]-P-^DPO^I-!4^#KYPNJH*2`<<FT(^D95KCVG&#GZZ
+M9GSY1<X(:"WLG_*2<.]@N'>,BONE/`WNY3DCH)/\'R7CM@/N5GG:2+OHFUJ<
+M7VBADLN^.AE?*)M*_\&HM&9H\?YXR@CHI/%_6A+N`,/]PU%Q_V*:!G?%E!'0
+M2?/_9-R%V1BW:)0ZKM#B_2P9,EG^IS';"(Q6$ZG?-3J7?%'.F+;<\%1E(98Y
+MJ'3)C^6."=\>AU^C1_!;D\&3Q_^I6GKTC)[O3!D3?ZV2)[M*'46JY-AYHY=Q
+M58*>&*)_>PS8+"T]L<M=\LO3QJ3E_?,UO'')+3/&L#5_>;Z*>\U%"O:NHC'@
+M&Q@\`T;LPPO&I&59`G^]@G_=6/BG*OCK5?S?&1O_I[EQ_#<I^*UCX7^#P3-@
+MQ'_5V/@?SDWAO6'6F/`WY2;Q?MY7QJ#E\MP4N7?)N5\=`]Z0C/NZ>6/`OG->
+MB@R#',P?`_XGYR7+;Y5\XNJ4BJ:L?YZG^OL#M7^U?/%D6C\4/_>W-!K$D]AG
+MY/`$=GA9GSB0U,:EXKDD&<]'D^)XZE4\/QX5CV;__UR5-R[YI3'LE#<T<!^-
+M9?]HX*Y>D`J'EH"U%KU29M/YZ%K?O9Q>L)`[%=R""Q:VJ//APFY)5PN3-8]I
+MN-BD%\:1>U+<RM"EIF]SF7P?ZRDIV?_GN8H>M3)5^NSB]'?"_G2..F?_7JDN
+MW?V)MG-8G<A1MN2CJ;NJ<&.%\N[)V@9OXT:L6=V?-G\593YKRHC,R?/?<^+R
+MZ$S-^V[VV'FSTM.M5^B.3CH-W6_EQ/,[K,J21785,_4+Y:^GEI[<_W/2TZV'
+MG--.0W=53CJZ8<)=*`^=<QJ:L]/FK8*LQ\X?B]X/IZ2E%_*],F:^GR3RJ9DD
+M`\C^U\X9NXYKIZ2A<\U%K)8/7)6:.5G_C9(7J?WAO+'+'<Y.4T\E[ZVGR?MJ
+M=KIRZQG-W5>.27/#*'FQW/#58Y=;FI9FEO>%T^0UI2WW)D;SU+%I?NOL]'FQ
+MW*M/4^[#9Z>CF>7]XJK3R/_9H\K_ZWFGD_^S1Y/_/U\PIOS;1BUS,/\T93YC
+M&ZU,QZ5CE;G&-II>A:Q+KABS;2X=M<PM!6.5.7S6:#H1LKYS^9AEOGK6*/H0
+MLAH+QF[3AK-&HU<L&DFO9IQWG*5NRK*UVJLR$!R/<]6X9&<\;WQT3[43QJGY
+M4QI6/FJ.+PV91J!)'O\FC]!QD-]_S9CZ/VV>Y\;,<WW:/,>N'"O/19/3\+6J
+M4KZZ>.SV^'12FGPD!*U7CRPO:4_YI4DI9#JBV%&NDCMFT0N%M[E*OI!3&JJ@
+M!5W+>\9+CJAF)1SLDJ@\W694G<R,/"?PM33E5`'BP:]HBWG#>/IB4'#CQ=RS
+M;G7=*K;?NS9/6'O'VCL\=ZRZZXY[5]^6MWBM9_6W5M?IU-^JU>N%U1L\D'+7
+MZK7?\MR>=X_@P5WBNE5KO[5ZY)[P]ZQ&74$WN2C'ZU[\WA*#W9'3P/8TOXX^
+MQ#@G[CG3W5I[^P9S,*@?MK?7G?2U1^X[]65,K]MXGKHU./\SVAJ\_#-E:Q`J
+M6"V?"_4(5)\\_-=:T64@G]/L;K.Y%I#7BCS\V&K%Y9PD6`++3;@1[+:&)]=*
+M)LD9K17UOG:#K]4`GY=L">.AP97+3?S>C$!9A<G>MF%"L!8/I/G:#/:VNJ&"
+M[H(6N]?LR<#:,$YBE6I]6PPZ#ZN0&8]VWSR9W2]-?]9!Y-FLWVNA_7'@2*G!
+MWM'`]L7O*L"H!8#R7K6M,JMDZV3:&PEP7BVC,OY)/GT^2<NGUK`Q*!ZN%>VU
+M'26<7A>HA%KK`V4E6&L>8QYKZBUVIIR5T9ZW?'6BD1S0"ZMJR?<M>JA+;E'3
+M/T?GDB0Z.VH[*H"^T%YV=[-6RJS%)E0%R<(__#U=ND(S@_^L''5;4^4(CVNW
+MFTAH(OQ>=S1L`[Z@W$0T<A,AN0'"2KA:L8)CPF"IE+]AI4-Z3`XM((?\7D<T
+ML+("^-RJ2-<(/D>2SD8F\[EJ`HF-W6T1,L0N\L)''O_7^KN%!53K,ZUHB$\6
+MA%SQ<%+S6[0TU>*&').1T&\HGH6%W[M0]$;3".\]Z81W!<\.=V`<C']+?B_G
+MT\@OH`49!J)J)>"]6,+Y.DRB-Q)8;Y)8>TG>2*V440O*L,,`"=!JT%XHT`/Q
+MLT$:_3^>UE_%]N/OM'XZ33#@*`[]&4_&U(KK.,U<WS=@U;3-R^-)*=>2)V?T
+MJVG1><ZM!1T-;0ZRLA*4;\P1:;W;8@W_*4AG(H8]6;5(FKW!H)R+J:.OP+R&
+M./.JY>R)Q#Q$$^`<_YY\?SY!RS_'4-@H"D.U%!AD**$'A*BO%>1]D-_[+OGV
+M)'D?U,C[(,J[8X@.4GXS>3WSA2R:,Q=T^UL\&33<"*05A8FU'<PE!)2`<61I
+MY$HSIUZ;I>X+C,#AN90^F951#`])F5SRL(5.%6=)OCX0T_`YT-Z^U]$+*X_M
+M!:7JL5237I>TWH`JVV[8:$,JFJ##<GIA'*X\-![\=;`6HV*8<,4!X[[;]9NR
+MH6/P>\M*.`+T@$S0F@2H'_,U&/]VX]GIT`3%MM:/K0!DRNS29%3/9_%[#;Z(
+M?N.5OHAAXS@J##J-6>>=6=""JQ\Z(;/V/GAO8F<?IA2V0'I]J4DGO%WL^4=\
+M8419%V%Q`L!F\9KY-VLX_LT23G&K?PN_=PJ0+[X[NT.,P'NY^$YA=X`3Z!BU
+MUQRHGP>=)1I8:D8-A^>UQ,%E_I:&<WR.Z"GH69#;YXC`$VB_C-EM_..MS0>%
+M]\4NU&F^1J`2ZJ3ZZT_$*X#*\=""_%Z3^-;L-N&K&*N(<^(A6'T'E"8>UW=@
+M'S@H.2(Q)U#5<#85)T!QV;Z.4YJB/D"G`X,:?6AE_@NPB*OY-QLYZ-"@_6:!
+M!)@+6T+/:>+O4.03O)S%(O%L4WSSTZ*Y>!@(?P]JI7!E7:#\E+^E<55A-YY+
+M.NBQBIVU8ID[6MH:LH8_PQA(@[.[A-*1G!L*E,V*BHY!#=^&@%M#Q+=!>!I,
+MYAO11CR3$SRSX%%AI4Y`3(8X&-Z`9;;Z#WJ!S'^5M@BC;4A#F]*24^)4:FD#
+MA9B@21L7X'V3,K['M0L_4KM@!/,Q`:A^.&R`\<7OG2RZ(VB9@IH<YX\Q;9>M
+M2I6Z)84J:CS&N>/?K.)$]Q!FL.G0^(HH"G(*S']2L@RBLV8L@_(,2MX<,-@@
+MF7]YT.ZU)N`&J"VRP0Z."4,QC)-@]K687#7A7/*+'-4)%^"1/V$0_H5Y':;%
+MA!QYZC\P,%1.:#8Y4);<@W;W$._'L$:HO063SSL`EB#I\ZGD!S9:;P+3&^T`
+M1Z284+PV3'%O)7?$[H[6FS&5[M^JZ;]G1<#H,034UXHU;$B3%737PB"1(0DR
+M^B5A]@D&V+%5B^Y^*GP\9*(,G>%,](C19A+=G:CDW9V!HGM%;U^X*(CCC.26
+M(0%@O&8&3H[H.P.V&M'=1YC&24).V(BWTJ$,D*>B!M';7WB0_/#WV=V=&V9!
+M%X<LT*[ZB+[5Y^@TP!@A`B*Y5C2`^2"Z9932P^P,H,DN]/-/8+/E0CZ`)U@O
+MP&;0T$RP?U!DG.$(M>D5W]`RW_PRN:GNYQ_X;_J(XQ++#.,2Y8?$3:'0(W03
+MR8K#]AU?("=[*9:0<!;R=OD)UGQK&-X1;98-K6!W1.N-$L[>(,-$:(RP+?7K
+MG"%"([ESB+T]/F^OKJ$<N&J2A!X<WUB[@&9%GAU1VD6!)IY;59Y'5)YW88.'
+MBUG;H$]H:C^SVGY1M?VZ1K:-.T+M?P0P#"HB\PIJ/;!]NNS>S@USL)W<T$Z3
+M9W<%'M)CZ,=$8WE[U`;HP08XA&TE0%L=86V5!WD#6RD+:]L>M6U[6-O:A1[/
+M5`#?>([2)CV:-NF!A$TAJ#F,=X&EI2CG[8Y#.E!'$WRMIW"HY1]OV^H^U.0]
+M!'5:A'%IJ`(9M7A3D%G^DB-']?(^0C<M,"AN$TZCGFC$35(ZRGG4L],IG:R$
+MSI&\-J8_5/4B?GZ\N_6OZ(Y<%&3!>/Q&&41H!JF*(5(59J8J;/+?!U%(;*&)
+M"5_KPF2*:RS^@Z50$'').V`'7>S/)7M^$.Q&BK`(X/H&3E$*-OF!ST$.<]*E
+M/'V,D-5BN#8WS'/OY9C($"Z0Q\Z$/"IRPOHPS&2%_HT9%+:#6'%IK>20+\26
+M%AV'6N^604V;C(Y#\8[:J<I))S9\RQA]VMVIRDAG4I\F%*%3:I_NY)L_5_MT
+M*-ZG6>9V)3_KT[_%\$B./AT;WV6=)QMIE;Q],!1ZHQ6@U)#><+\D1/*%/N$V
+MT$^BN[<#)(W"`;F3!L;.@&=6E-D?O3%G+\AB#O2&4ZR#^-K!_C"!]>0^Q$;&
+M'DDX!"T\"5D]26FW(KK+A_P%?=%G=T10,T2H-3X<9/HB^6OT,\H(PD3=OL<_
+MW%"@MD_/B/8Y$@`C"75#GT8Q7$GP68IF&(\ZV#Q"MW>!]4[9%&TP`"4FM$'P
+M_S_ZP/;/Z`-;JCZP)>F#E1I]<.DIPYG8*I;3:`L!M,55HK";YKJ\_G<BL!5F
+M=U(Y5VNOX!+:`)2WU7Y*HSKLD"&A*R![(A67P'9C>*V#RGQF,@::?.-SE`QK
+MZ`)2$@2C%\9C8;X&],.&TYQQ,<$2/@?23F`2S'1]C6I2-@6$L\J__XRA^8#%
+M4J"9$HQK0\K<B6_>1A8*?3&1)+'Q;C+9/U;1^;P\\U.07"O&'%*_E/^-D$K.
+MYYD=`19Z8&Z=*`P@&L\,R;L[4'_O*1AX0:5`%\3`4>TF4>@-6):)SI[PO4'6
+M1R8'EBXY)3H)RMD7KL2^[]S=>!GFY[P8PE(/W4UF?4`4^O6#%*O(0ET%D"U'
+M9)<$80JA@;4DP3(+IE<2=@?F;A(%%LVEC[\?70I*0A\UYA&?HP^L7EGT[A)/
+M03<']5W;D8'J]/]C[FO@HZBNQ7<V2[()2V:#JT3E21!0,7XDE0K+0PDI&RAE
+M89/F@^?35JU$3?W`L).`+QM")ZN9#*O;(FH_M<_Z2M^SU;8"E@HD*4T`+2X!
+M-=B@*4UUUDUUBS%9Z)+]GW/NS.[L9B/8U__O_]??DID[]^/<<\\Y]YQ[SSWW
+MF,%]N/B@[.F7/"^C3@5$^O+Z:P`\4)#Y%QW'9.$EL$RX`(@WI.&740//1.H7
+M7D*2/ZR><<@F2?X2_QU@$[YU(T;(QX(@%5,*'%%QK/QRB!`L]1#X>-NPJL2C
+MG?0Z,*MO:1:H\"\1OK,TOE?Q!)SZ,DAW7U,S#$&'Y-F/_"T$[-#FMXZ1O(/$
+M5V5A/]`Q68&9_(L!J>H5V?,2]9L!)SM?4>&33@$7`WBJ7`?Y1_P.#&!D.8RA
+M=Z%)N^?5AC7_2%G1\>J8Z'C9R.JHM\G"JX!50C&"%;P/$>8Y8/?L;S"+COUC
+MJ!2+C@XH\])8<!9\I+4(D'6"M59J-J$86EF6R6B].2<A/8`K3,M#03_ERU3E
+M1AG)#:MO[;,)N3%/)S=&3AOQ+KESZQ&J%0-ZA#<&O#PBQ/G(JISZB#'ASV@N
+M$\<XU#F)/8O80)-NJBH09*NC`3ML?ULG0#`B'QJGQ2-Q6T^(EFFV'LP0W"F8
+M$5#L)&DEP.Z3*VJ4VS\$'IZ"/!S`9KU!E8&M8B<(_(#/5@YZ"S'E3%3HFS82
+M]SJ1>WU549@RB;_[0E^G^3FRJ1!SJ3S:B?<6J7/.(!<`OJ-IJI]Q7.@:(-UX
+M/JJ,94HP)\YN,)WUT3R$_%F_`>8J4LL8;PJ*#VD9V#*3+L4[#DQ9U0_=A?Q]
+M=D]@_6SH`Y`4\B2_ZV:R.7#B"6C\A6@ZINDE0XP&GTCB0,SQ+M$1*$M65);(
+M'#W_N<B:.A<!375H-+5Y"(,WX!*(5<8#9AOP'A(@0]F];JQ6$E`W7RUYAC+8
+MI6T"-.Q>%P7D<3')\X3L&.(Z)(<?U7M^RX>XZ"K#%"(\@1JJW31?R*GM<0S"
+M^%Z#?$ZILFU^YTEH2N%W+5TVEMW%[\(;Q?NE0''OZ(C460LCRW+ZW/.AG0-^
+M?E?5H.SLXU\\!-\B@`Q^ER?,O_@VX)`[`DEG(`G^O%Y+%TOO1VVSN-?G&),<
+M6T#4D-AI`[W)LQ\D#O1DO^CI,.#"PI8QV;&%WV45'6TPC&T@;^>>8NK3$6]O
+M<W9MS#D8$FG<+9)G"^C(&0Z_Y&CK<>#*F8&T$X!]$"05YH%9=,OZY7+5*YT?
+M6JE>8,V7^1?#2/JO0&-&T&Q`C$$SB_E=O7/?]FVQHSX"0+?*CK9:"31P(]2.
+M8_TKQ-4KG1]9*?NTN:=\6_+4O"VU$@]9A']'Z'#-%_MHSA#\T$=4D%4XYD$>
+MJ)6`V(+3`,P_3W-'2)IOJ95\322VH%6>)H>V4`_9\FVTX$GK%;DPCC`.3)$Q
+MS1<=_K&8<TAT/`%_E.`48!J_[WDW5*-;Y\I7K[("M=YI[7:$6?RKS%I4`4SP
+MSK4@$^.:UX]0LP.;L1)UE"J+SU9%7/@6]S9(J1X'"3A^UVGDYVCC-X%6.@>L
+MP(K`=MD!NADH,H:WQR*UY*+R^^(;$EZAI(3>P+4EH%\@9/>RL41-=F&X<1:8
+MY[2ZB1?95"E0#BK&:O@7>^8ZE-`?25:KUH1O[0#V[`ZW>^W]ZW#7\*Y[&^Y=
+MCSN-=VXL>'AM_8-JGZ?K[S\'TPB-Y/^]*N<`@8W[HK0@"6I`!&1VO,"ZR6=3
+M"VAWF(?P4A\LO<^%&X?\O@83?+6?8DM)DC`L'<"51(?2@O9(;HTRK$")GN`*
+M%/Z@XUG!'JQ19@0I\8L<,]N$*Z#N&F7F^YCJ:\S$A3]^ERNS`FBSHEKA8.B"
+MV5S\"LL>QQ!9+FA66E!8F,I`:]F-%_1H/"X=*CI8*Y[AA$F@>@IL%V9N3`CS
+MNTZ!J6E1IM*"1S@F#.'=P4H&O0Z)^_-#I:0O6%`L.:)H2@XI57^FKW%-3.J$
+M>8.LYV@(F&"P5C;@/H!C$#<"5FS\*R@LA4*DK+I&N11+]E3[EJ'I"U-T&"J`
+MS@VA+:R</!.+@?:Z?SHT9Q?"N!<=UJWB3P9PE>L^-=(FD3!$^Q]T_@N2@(B&
+M<5.-WS4?X/&M;,PD'7G0D#+C9Z*$^0O2W&"R@,8=M;[$G#];1V/&4^<YYZLD
+M="[*D49'W^[\>`;P#.AJIRA6$\SU[ZACZ8<)+;\6IECL/&X(E<"P@(`+?<#F
+M]<*JL."0\>JJ(5S+]229K`/,9"6;=0B$!ULSARG3,8!2%VW6F^>>4=?,B6A+
+M3"B_(D2M$9SD:=W;,=@"N'-;43E8^C[322[@<++%T$X*)M^O)D>9K1WFA*M5
+M)>:;?TYHJS6X&PI4:P6EXRM_!ZK]`QF8T#>8BAQGH&^#"3)%0I(.(96Z;^1W
+M'<*B_(M'I$`ML"5@@-_E`+'36<MU`7K&Z@P4'/J6$6QL0-QOP3L,:;&CSJ"\
+M/$"I*H'&J3,2RB5;,[Y)M6+CWV@I(%R&MY,K'BIFK6:@`[GY'%&7[!G`-V5I
+M!".O3`=4$DWBIM*/3Q'E*33=$_$1Y9&N.9*J:ZX"71,F]T'*/+\6%Q1UND$@
+M07LE.MI[Y&,CN>EBH`ZDK(YSV*-6&407R.((46+8&_ML2ARC[4NPU-R3I#.A
+M27[I#-*AHJ?#UZ%_&ATJ"3H,%U8I0(>H1PPF]A0$T!6+,MF&0D"EPT%@.:)#
+MW+&9)CH",/,'=#/_'Q%:H$,:KR%[6!.<_2HI'FM!PVLFB`OEWD$<GP,PW4F9
+M(#:5GQ&E#0=_3[*T%R_![<?T(RQ==MC87=G!GY!<53CA"VP!3NFAD1Z6ND!-
+M!?(4HM6`,%>%\M,(IN^G%H(/L/OK2&TB6CVFH]5CI#?UX4SKGL?O.G@>U!I1
+M7O@$Q1\2ZP*0J4!U0*OF=S$-+[GNR`2L^58S6@V'II*=5BO?6"L5`]KBLC1<
+M*"A(K\/*'TY0+T"`#K/%1`4)%H6K\N2G1*VUHJ>/<[O`>L*J5R[+9&L'@31R
+M,<#D8B!9+F)ET+4^FGE<RJ.C6*V5Q&R`$?OGJZ]&^<E)!+J#4`R2O%;<9*00
+M-I5(Z@Z;;!47&##6.&:X2/0,X$;89;6RT$\B?AUPV0+?R@THW[VQ5!Y;33SF
+M.499%]0"^6>RO61(`.9`;_*7=><7Q:%K=+QVR9!1BTEQ(T:<&/EL7D/K3L]?
+M:6<$*[(M-&V3;X;9DS$E<`EI&$/GU#`BZ'WU.N(+;U5F3*)@<57)B//*H,HK
+M?2V>/H/[7Y`V?(S"H88:Y?@)TBYZB)X9GPP2_[`\8`\.4(;_8NN50YRP@NUW
+M*<^<T/$)`=Z0J;)*$RUR'G/5*">)@G%]A&_]!MDC`HB,1E.PFJ/[LVD]5D9]
+M`<HO+3,!)_7I.*F/.*F_J!<U%$\_)V3!:-F[F9*"^DI$70B;$\,E&J&_&EGI
+M#EHU'ZBI1AQ5AAE?Y8<6`<]$)&$`9I@2`.U_WB'F$J*DJ!Q+,%<>\/4Q34\Y
+MIN>M(<9;#[V3PEL`_@!J*\1>\T_%596(71A`564@65494,0A4E6H3^Y5Q#+'
+MXO,#8FL\SQQC/',L+0_VJSR8,1R+`8H'X_P`1'5,%H;9,L=YU.WH@]PI:QXX
+M:5BE(A(4QTA0?#X8D5MO]JT]H(NCH]?3]RK_C_7T1]YC7&1F7#0LL8E/@1RD
+MF.>1POT2D4NP79U/K#5*&6.=#9RV-\,)-]<92,TN0:J(,AVC6KF?%F@'@>:.
+M_I&QPR"P0PDSSTDW#=Y`E:AZWF<IZ\`.0T6]9,0Q=9W(_PI2UTE!MRAWTIIK
+MN(:T]:J_:N1_4Y*N#O3_-J-_55'7Z#]*]#^AGEYGH!VJ,!(^6A_*\H\9N=L`
+M9+L#-7,AK/H?Q37S)X(:N0]Q[J\0(0TB(7T^/5RE]2&5UJ?]+1;[9^GT>GJ\
+M[OU_KD[O'6E*UN6']3H4WI0+.A3M0`TGZ?+#H$,Y(C"0H$.Q.$-XV&II5B8B
+MSWV]ILN'8\XPT^4'QV3/(.I1ZOZ3ID-IJX3:3##4@KN_VKIBW]M,6;^%Z?"D
+MU]_W#DLK(]UHF!,6UAG0\]"5V)U4GL;M@F[2C<_V47;O"-]J(Z+V`+8WF()9
+M=+^Y8UC3D89TDGV(K2V1CK3@G#H2M$(J_:,?4DNH)=V8\'>P*N\=8ZN4XY3Z
+M*>-T>D>DT#&,E@!(<M+AF6.&TC*$ZHL-:'00M"(02*K*_AGZ^A"4K96*5'V=
+M=`G:E$?+9K`"/C+CYH&/<'GG'ZL/]7\=G>IUDD?^_/G6FZ,IZ\W:OL_;;[+!
+MOHKM^\A.J]UI3MJ?TE:9I5-2&"@(XV^-OB,=Z0R:)&=8/,E+5:"O\(_M)7,S
+MZG/S'&Y4NZ<0<5AA:'#/@5[F']6M)N,BK_NA,=Q6P>SP/AC*\6N+O8.R,PJ$
+MY'.O'B._)=S%O1(H>``0B5=T'SV9W85;,$#35MESC#8<QT"_"[V%/EJR\QB.
+M>N>8Y#R&]\*?YK]EX=3^'2-W5-VW]:'@Q\SV1"$7UCJ9AQ#?H;+'8<TOS)U+
+M/;%#3^A.=WK[>B_E^@WZ518ZAR3G@.:><8S6MONI)(B,8Z%LHEOD(=D9]LU;
+M3CZM&V#B15^W+NS8AT"LV-^^AEFT0S*`5W[C8F%`ZZ<1ZD59@6MDB;X:H3\,
+MD[3#VR\[^^W.8^NGX3KD,;9/124Q_8WZ4*WL'":#<[4)?=7=-*_3/D@WT.;-
+M2?L@:=>L#XR/9W]J`&D2SY,H?6]1-%*\K6>T+R;8R`EV_ME8+'&>FM8H$_ZO
+M4+;=:6MS1O\)J@!YPLE.F$2ST>^:Z%=))>UANU._U9IF;Y-\>;J;C%*8Q,S2
+M([@S3W)'EWIG@`8?\*FH^)3.@$Z,2#65@E:.NR#%ZOY;U1#MOZDTSO91)DD!
+MW+_'4*KH%@XT$2I$?6(8>2)`/EI$+[YYZ]3\4$NVMKL)TCSZ-;[U&>C#ILGP
+M?(7[RN"OT9G4$VURNX+;R8?'.80^[[/,M5*.V&$4'4.XW6X/U[]OKU+X1W#'
+M(>%#7J4T?A)RHT])K;RX=O*"6FGAN#(-E:Q.#C?ND?"&U)+!T$):HZ>R-Z0O
+MFS]161*2C!+]$].B$U#,J;2X1*/%_O1S^9WODHPDLHJ<DZQ@IIX$,_4D=9X>
+MU.9I&W+>H.8G,HB<AW``B15#.J3P^[X,HG`XW98:J$6#.EHQO@$4-#4Y[?+#
+M*OUXAJES&TW2(:(?CNAG""3?IIDT\D`_"M&/TZS*3P?)R'D;0I<R7Y`4>O$Y
+MHY"KQ1,!"ODQ4L@4>+["/3>X@^0=O"1HQ*/@F,V*CYF2&+.A<30RQ&C$J2!=
+M38[3E;X,T@C6F87C3,YU:DF51EC9&]*7S9^H+&`($>->\IDTDE9>]:6Y\VM)
+MOS%QY\EGT49UC?*+P^J2.QWM*1L#&=V]WEP[>A'(YM!PK7Q1\<%:H)8+_?Y:
+M[F!;@"XNR6@YR-4>^5#X:ZV4B\56ZFE[W'[S>!U5%T]5?XZC_8]&-1R3MZ/I
+M/Z3NSH],X@"/1[<6&]S9<A8H'A1WL==^:M,%OC+.W@74%L`#>9M?ATYDR=/(
+MI1FFV*,#M=E+ZS/E^;@97@E68K<CPO8ON\9J*7)_)[!."TXK;/\RV3A,.6NB
+M/[/U_CLZ&.\&P`3MM%E6:"[Z)I/^$)6ZQ?=Y>1J_RV@_T)SW"NX\27\[VH'G
+MJF8N7:$"UE26J>*L!Z!:G(RS9'C"*?#(51:,"&M&S*#+W@_)3PUM/!.I+E%T
+MVS`S`+H]>:"KUJ/7)?]<A,*\'Y`.A(S%'8E[Z\;M`8P=/T\2.L>*$+\K%]#!
+M[^)APO(>%'@P(.LX^,=7EAFZ0/4GO@04<$R,H"U49U".'HC%@C>0XJ;+CE]^
+M<T!=XTG*_QREAK5-(6<$I(/=&=V$Q]C@$60>DD4Q3-Q7X2DUI3FCW3$(^*HH
+M'K%[HLUF4!G`+-V8V>/HI\"GGDCS9!G/>:S<".*H'Q4UV=&?'=Z.?@N.H2,?
+M';F_OU0\PS<$EX5^@?8MR=30*;*7P0@!NW58%H9&WZ5UE8L_56$.5Z/5F$.O
+M8;!=H=F1)9F<^U)J*Z\"#T/$O2U=%>ARY"?0.!>_K]Q4X9(.H$X/'?Y5#UHI
+MH-?[242T'L+N=:C])(P/%,>`'^V>`>AKU2">$8'>-+/>@*8TTLD)UI(C07BG
+MC@PM"QV)]^,3]*?O<//5HWVN:N668=:6!<Q?$R=<07W:>(BM%>$HA/%2F($`
+MRS4]6$<.*:#-5F`!77]P"!$!GW83`LCF'L:R/U'+7A6\CLJR?:[L:N6&=]C6
+MES/,CHYEERL%+(G0G$>.I4,(SXY/U/7O86UC(?7\ZG5O$SWKHZFF4BO`#*;B
+MI.*.4($?57*3;_G'M?+2:E,M.I$`7$>4)<B4HWA&*G%F)CFN;O=;)!_.P15X
+MEF63B<-E!0N+:8[F"YAX?^*(6\#^CZ#I;P&+%B^NY=#M;9-V_2A;';&IOE)O
+MOL9T^7=Q+L-"$?2&=%A4FX;=VT#VKYH19TGR]N70$\X24RTG6PUF>N8`R^1G
+M?I$URLXQW.]=PK_HM(!H(]5FN%S/?7-^CQ-(K2Q$:J7Y-"1694ZW:M$6U'$N
+MY8;7U#<ST+,%:(^\@JBYRK<UT_>(Q^+.JZFI49:\K6T9]"(MJ(OE5_;ASA,8
+M3^B\M,JDBD__1/(SO8^3DF:NO/!-HQIG_AQC9A]U9]=4*\W$>ZS2^`GPE#H[
+MCWV^.J]F=6+XSZD:UTB=M4`-V-=$*TOBG@+K'Q+NJ%];4/_@@W3`^(&U=]_A
+MOK=A;?Q$\KAYZSH5)*<E5@R#]@H.4!;:%$X+Z*P8%\:VET68V0!<GK,7:9)B
+M&&MVXU2?^+W"LW35J_(+"P7/P:61'[$CIK%BQ1<ETTCJZOQP!A<X$I&G55!\
+MGXO#K"G]Z>_YK,AEN$9))[-C\W%5>\4AK,+L[?`4REFTF!'%F%7BZZP&FZLN
+MYE(.?JS6!U]=H9WH8SCA0>Z_P>#&CQNK\0F2^?6BH]I0:=,X"\.*MZ3@>3?&
+M&U9U]*J57T]F8="UOG0[A@WR112BYP)=B)YLTD1"F<4=(#MF8TB+O(GRY&`>
+M]%T9YEK0.K+1A*<T=ZNX,8=6^?U:>Q&H*E8<NU'Y"NW;13"N`>96]FNY$1L1
+MPD9$AXW)N(/PYV,D/`G74,6S)U1$NJA2E])S5$WX#(P^<XQA5$F*GY",TZXC
+M1D-1+X8J'VT+Q&/6'QY]:Q42CQ,TBQ+^Q3"H*K0=>+H3!0RT2D?'6V>R/4BP
+M./9.&\EJ<4]J"_`[`Z-=!JC%/;T"U`CE*.M'IY(K=8DG.9CP0]-PKA3=2(R&
+M]J7^+W8JF?2M53W-D!5SF$/_339$RX)K!0M>,%(B0=HEU%;+XD)*X\`2,J-_
+M)3Y#%S#W]<V9+0OL_(]0ME@)KL7H)AL(E9'.2WENQSP/C\OSL]#EB3PEF.<6
+MEF=>(L]!NV!IGET.F"E7FM]"5)0#5LJ5JU$O[P2P<5)]""?&=AR-`0Z/\N(,
+MI"3MZ^GUZ-*`NJ]GK5'>@WD/R0:7=:VEG2=-;*$R(G7Z5A:;,.2[,UH>^S4&
+MNE?6]U+>.D/=FKH"F)GK##6^JF@%K7'4<(S\')'TYX,/O\'TQ<R6#5,-;A-,
+MHLM!D@`-Q=:9E-V]-&!$[\`/U\F9<HEE>X&0MSL'4K:7N*?LMA*[^'<C(')F
+M;)VY@E;]+?K+UPQI_*&JL5VZ*$"VRJ46R3$H]1SY6!SEQ`^X.0:3"O3@G!:V
+M-M)>86VK"G<[AC9`XLA^(UXD,[1&S@8UD?R.WT(,#-(.N`Y;@^CP9/.MY$SH
+M$@H(4SJ`Q*5N8"I^KV/(!?^$7>P^>)S^<`$6H%>4RZG107%_$<HJ[$\+8`)T
+M*BBM66YJGZ[2]>E;AQ&7UTC"<+MS=ILSVNZ\"JP5%OTR(].W/"8YP[X-8]TE
+M8W2T&L25P/LVG.TN.5L4G,'6`RD<J-+;06Y+/0X%,<^B/3@'7T'?,^R6#<1%
+MK;T3U])P>ZV6?U&PH<-&S*'4VKOK0[)SB`SR`:QO@-_E&'2!6@M3KPMW^^ZG
+M]?$^VAPGCV-0)ME\G"LZ^L=DH3_)?OT+K8\DKW&@3Q,`OQ#UYCZ#^S+9T??=
+M48\-MW7/9#=GM7358+R*EJZBU6W30OU8GO3`F\N5?"!Q7"Q757:8[Q6[T,_[
+M*M'I,*F625A+!JLCYN@/O4GSA<TL9(F>?";9A(LIR:I+<N>L;G=&VOC5W5E%
+M[,R!R2!DPMNUH1Q:PS+!<Z'L",^-+(>&L'P!31K3[<Z^)C9IS`IE^:&6:!L/
+M$,4<?7;']$T?LR*T-2]%0BOQ-@IGOW2F!>:&63!N[4;`6UMF:9DD]$.:\'%H
+MBK\=M9[^MEQ,2]04!#4>-,=")U*%E(O>B&M?'W?N?/[K1C4V9EU.K$@Y\G=`
+M3VJLS0L2>3"HV\_3Y?GXM7@>*^21='F2^;'[-3:?9I$<L."%=L4=P08\Q)&0
+M!_]]F"GVF&^D!/102XTRPM)`!JAB@F\MR4!/OV@!<_B2L^2B'D<DA]S_:+=)
+M+C/9R\R-DZL5NU:8WVF(E9FD3O(,/1USKY(.D3LB#,>DM@.)B60:3"2*TGY8
+MFTA`KLI.)30U90Z!Y%8,UKJ=<R><2R>S=AO:0M]&6CI=Z)XDGKZ6:0I\ZR/(
+M\S!B<=A^^(=QL`V=!VP?_>%SP3;$M;"SE`G8H`V^]1-.0UZ)11Q8QWL?0^_;
+MTT6\]\<)#$ZI5D9?9U":P793X408-V$'-V`'UZBJ4#&,@351-+=:>54MBGL`
+MNK)\:R,&'KC)#WW;VP&JTS'(!X51PO^FB.ZI,H=FH,T<*1$FJ[6BOYH8*1"R
+MU(PPC<7F(SI>W,MT$[`&%;I7#NH?98;,:9BAQ=,P0R/?9OHV!D+S:%Q*,+F,
+M)6?Y-AX,_0OIBJ=OQ_1:2`>#]P,@,5;J9[@Y@P>)!YLNTR"^G'IF1H;G6R7T
+MJ_+AI9&.85"QS.[)\*_5?6%H%O/?1HTUPZ5<_9=8+#1#?3>YE$OPG6?O,%^X
+ME.\>UO1A-6T0==Q_515R:P*O=[TV'J_!#';>@[$8,!<H:M<*E["J7(J`=G`6
+MVV^B[QD4RI+--!/<AY*LNV4>(/Y%:ZKU?W``IO&[%DJ>*+_O88PI4#Q"84T<
+MT>8LBF4B3")+H9@IG9GD+C")&'AF-\*P6*+3]*I_Q03G47"O.&E=$X'G=QF@
+M&2%QEPHE[BLQV1T1(>E^%'>F%,:U))_8-Y\,%+,RA6!*UI'B79S5`UT4F^CZ
+M3XMO*]IC%?KK&<?93J>Z:?\'UPY2KF$:#?C6Q8#<_-X1SW6[4=T`.3P)_]H=
+MEO6@6VX^`SDS-EFY7F]O,UKE7`"^U"O26W5(V]PHH+9&]=A8>9BI;4ZSM-$J
+M;;1(&TWD)G^!#)/91IOLB4H;\^$YE,?H#?/9*`D^T*7-#U7V+%E#)SNU!</D
+M^,?4#XP33IM9U<I4`*XEUZS?N]+';CGS>Z-Z+VLLL?P?E5?9"E=907.45YD*
+M5\'T-3R2:7;GS.-&^X)OLGV9B'U5Y?H,:56EG#G'`"K<38@18:KL'(9BFW,-
+M>,']JDK<6Z@N**R>#F8&HB52?]=()B?8N%ZI*EPAEZV)!2C6$-C09C*;0AO]
+M<EE!8=ET5ZQA>HUB.8#\81&;IX/9#"ERV:VQ0$_9=`/)%E,=!W,M%W&!?7T*
+M^%AJ!M8JD,KR`;R,5=.E53:Y;+I4!F@<IE>3O&IZ!@"URDQKDB!(;>U.2YLY
+M5F:CN34>TP4#5)7:"DNM]E+L9&FE;%0["?\(ELV7QT9A<BS-ETIM\@I+QHI*
+M:044,-D/U+/8&RQ&REY#_(X-77T-&7)I9=IUYP?V&PU()*_%R-##*X1B1(:@
+MF(H#&4`6HSUHC0G_)D8XMTV,&(59LA"51CMC,Z13TND03S*AQE188Y&.=)Z>
+MP559\L#$]5@-3?=!1K!"&N_"'(V6#,$B-=+D+$0S&N%9B\J(;:!0%O[]L]NP
+M%=984]LPLS8:<@D'!'XHG\FQ1BNUJ%W+$Y`.):UWQU'PS=\9U9C@(T:S>XH8
+MB;E5NC#[717*)-0\QMWE<>/O&`TCD5B1O"9KE`(DHA)+M=)YR&B8(/[PIUU,
+MH:FIE!MMA8U68,?2!=6Q1FN%7&*.!>8VVE"4U]CL-?D->>T.2YN1&"6VC/@4
+M$MCR9XWRZ7YCTKUKFX=N->&9J'A+,FO)MVT[1F?8$X5_?5Y#%)Z]KV"*]U7\
+M]^<=\&^/%_.8##__NT^T8HA+[P"\,[:N4&1D5.]/4$?;@64*=V!Y`-,[TGR9
+MO`R@IX0:ZH`][&9TR?;PJ9CO^:?A7X+TJ@>$^^Z;:R@J_L(-\[YXX_P%]B6E
+M7UKJ*-,EW''G-^Y:6VNX4[B[X-X'"AIJ'ZR_?V'!G7?<!;_U:]7U@<U#/^"2
+M^OI,)XZEI<?;-(;6".DH(UE&-P]]J*A13N!YCWM!U9.V_6`,N[M%RT;O_%YC
+MZ&*_N.=I>)[COCCFQ439RSY!US$=II-WY1V8-/<M]Y4X@IL65%<`"\G+H->2
+M=\,8H<0>YKU_SS88N!W8!*L2IKX!2&+5]GC]:ML]WM;X4UO\Z2[<VX'_NKW/
+M85H*%"IHV_!9[!H0SZSA'[T'(U+V%;9N7;?X;"PVX+]FG]$P[S?L9]4]I_Y,
+M\"VPEST/PM_]ZO-L^&LZC]]$]:;^6O<8#06Z7^KW_;JTJUY-7\?TWR:>`[O/
+MO^UGH6Y/2ONOJ&E:GA?4YRW0]DSX]>O:>EE]OC"E_98]-#J\]]8Q;:@*@JXQ
+MTJ5:?#C"YN`2'".'U82'%#=%I3TXQMX8[YL+?T??8^\LKU5\'O^\%\S%&EAU
+MA4%N/!&RX1<C5PM7ZVM&FA$AF^_P620PC82"^\XB0*#K4.'0U:#3S-LI[=A`
+M%6.2S[TND+Z)CH`8R6X(2#NH[C&H^]'DNC=0W?(>!'RT!W5MWKL:TL0W"B1*
+M#"Z!M^*1?Z1-Q$QP&C;`\&,,?AK5<&4*!N//7/`$//OV_`3W%/8\H>';86TO
+MB0;7@314RW,:F'3C%:]FDI='<8LUW@><[MRYZD=^'WR=[->PO#KJ/>C)'CW.
+MQN9:"H8>W,5\P2`/.JJ?*(G\ADQ+JJ[S@TG2F<TG#6@N$<=OM[HS6PX90]/B
+M[6%FM[GED)FLEW)^+]7MJI"W(9*]O9Y)NS&45T6,\!';09B"J8==P-:\'U>,
+MQ/VSO2/\%FF2)G&"5_^=QH6UR;DO2=")3%)/R@IF_9WI_/I^7Z(AI21:*^_!
+MC+72@N`)4#?]B2_L`Z3__DQ\;+AX4WP"6:$Y_C@,)A6GZ+:R.HY30G]Q;_`^
+M3L.A6G0WWDK-JB[I(>K8@+A>JLM'L$C>)YA4MOA^.^7FL]KX$R\8FE;'B'!!
+M-=V!R8H?Y)74A5-6KWM&X39,D[8U$4UB/GL7_Y@+&L8COX"7NXB>\'-PH1KG
+MH4.F^O6J^G*)9IL@7I/ZO\<%D53H=MVX<'IZ1&*]:B):W95"JX1#M4FSV^(]
+MZ#9;2B1ZUZ85M8^M)).:LE0!)/V<D'I0F"+2)YBYSJ#V>X9SE]?SXADCVZ!A
+M>GG,AYG;#LS.LA0Q[+1E@4$I?*"US+?NP;%<7,2WO@P/J]D0=6<5J?'C3F<W
+MW+3W#Z^__KI?K0NP^G[GAQF^1=]1S^7-[91\*#G::7HUQ9N1CD#AQD.L5$MG
+MD4S$T&8.K48:H4EWC3#9M]4&A(&N0'[?UCGP&&_G#?$#OMTT+0&U2?@+FGQ@
+M\]V(M$35A9;[_=+'A92'44/HQOB$SN-5M5X2/)2YG4BUC5*8%H+#%\=V$]5Q
+M%Q$<(G9N1/*VP-^-.3WT%SNKSBGNR3&B251GX^-=@N.=)=('HTQ%.'H9(5P7
+M"9?+)"4*B>RKZPI0M_]J!QDTH))LN8=+U'\]J9\+ZC@?$S@U<H59VH8(CO7&
+M]1C0R'GO%W#!Y9XD&&[I]CZ+#6K]Q>RUG0/F6G[GGF=):K`_V92-[L!>4&?T
+M46*-*WU+1MY[($ZPXD`1+MBD]*<(^R/NB_?G:52)=R`:V*=[U$^$F4T>NJ-[
+M06Q'$PG.)YC@E#>88V_'FV5C8H\(KKA\OBP-#GFMS::KY&WXU4[2N3F326EN
+M&PG='9^"/&3R-42!*4'E73.FJKS7?L.P_A[#]7?>^\#U\%>UQ71WL_]Y)VTY
+MB!L7&7C?++S#V!%Q*>_OI=4:;P>_A<=)I,K:LK!>F$;>*&$9PSX,]3B&T7S"
+MX*'DF0+)$9:,XD'Y`<J\;F;'PR3A;3-HU;!33^@\L9RU8A>&W+9J/)G\];UH
+M%PXIU^]EQO!O;Z=IZDK:#\/GV+I%RM2]N.*!;W+)&HD>"%2AOX[60$3#E\G!
+M/X/]R<0_REE0L^HV*1_!'US_'U)>W\-Z.-(T%\.I`9SEBUBMTI(UDDS5<[,_
+MF>P8IAM4,-R&G\Y)0#E<C!E,>T_TMAW0S*W*HZ]@YZ51:D#`_:.;T3?DGCT(
+M.?JU2&4+JI5R>.TI<QG8V@V,=[7R-2*/?.C,Y&KEXE>P*8Q_&TF]PUS7Y.4[
+MF*&U%4&FT=?0EFM?Z"Z0IXI=:\2%!@'OAED2:URD]+ZJCJUG<JC(+R];(QE#
+M'_A]0M0/,,8:*Y6?O<JP#R;I)`Q;:)7%E]`;>X')?8*15^+:]OA^#RVMY(-L
+MBN+5Z1Y;(<:`B,C._`S<%.@33Q<TWK,;P2JLRJ=*I"-'%=EI.3I`$92L\C2Q
+MQR3A&:.(85,.$-KH\:,G8?:"IZ,?RH[\#`>8Z`4-ME>PCKD'T(*W2YU'/Y`B
+MV5TW7#0+AM`1#FY(Q&#CO9=0T#%K@X?6G1S4J.RT'1V0+X+V;I@VLVLT,`LC
+M&UPD=IM8X[(GW]=D'Y`\^103%QO)+L[%SS"[B8[\`>CBC$:%=?0":&Q\C[2Z
+M@T-&-?Z9E1<5(Q*_+:,J'WWA)W4.&+ENSF$53V*`.?=5:BU#XVO1()0Q6$.^
+MV!T%0*((1,.EM&YJE1<7WZPEZ^"S`7SKC2H])'<Z^%4"#.'Z%O$V=E)R*MC%
+M?2R[!=#J&40L-I>HG_OH,\&)A]>'Y2I%'9D^Z30ZO^,8#,J.P3C$Z-^NA&;2
+M2$K.8=$1*8!"1T^F9@3L`MHQL#?#O!B;T5#$^I:ECHK:EM0C.X>/?I!]IA@+
+M450+M<>];$0V0W>(/@H=^3V.`<)FY]'[![#T_0I%^LAOH,4?CH!V*%`UPC,@
+M.P8HTC;%(<-8]97V&`T5@.%;]"C2)8Z53:[J6T'IOGF/4`K49IM[!-</%TN>
+M?AR&5V8@@09Z'%&M_2ABTK.01@MS)*.D_^A)*8(0*@R)46`Y#3=0)2IP27CO
+M)URDY@0:`"997H@!3O+%R(R&8G\<AU'"83\B[R3B,'+T8X;#*$;-3,*A>XF&
+MOWTJ]$`)?5AR;3_M)^CPIV0[^J%:A*0/R$"#Q+<VH,F&^'T4;/_>&W,O\9EN
+M!N@:9S(V#N]66SG)WB-SP_#RH10(,7;%40+1G,V)G2;)B?%M!J13G1]."N62
+M_[3#;.K!3:;8BHUA\?T9[@N)D>:>TLD7*.M;&]$!]`_"\R4]/,5Z>,)`#2$+
+M^GN/YK'DY1M/301-<0HT>OEI943\IV3Y:<EPYJOR<\W$\A,9PAO;E".=)K%9
+MX-?DIBT#R:&@(9>LPT*@TTSD5E5>UNGE90[)2_-Z@>3EEQ*B0^J:==$H!H.>
+ME04#S.2TF;%M0EIB^'"SI"*&)*9*5^^S;N6DDY98<_`OJCPR\X_\9;R<=)BY
+M;E5.7C%.3J9`IDI)ASF*(I%)20Q-:)88%YA)4B;@0BE9GR0E":!*!`CA>93D
+M8RX*Q^ZTLC$71Z;[,^6B)NQT0/9!A2'2:3R1T?>@D"H;H<#)<=F1R$$@`<7Z
+M5O(#$G3O](R&^5!6;5O7(+(IM(C]50>)M17O\FML*#:=CYC,EC,3,E(G(0%-
+M..Z5?"Q)#B8D(Y"!S[(9B8#)1X]M+L8H0GC[`?]IQ*,WYKE)OAGD#`JQ"66C
+M)N^2$=D?NB*M?!R7&ZDB64+>J.$PJ@E'PB$UIN(PJN&P/QF'[L7G%),,?ZJ,
+MU"1D')J$D&3RJ(KD4:_[2S[317IYE*B>+>_`5'-H[JG0,K]?XX$!JG4FFRI!
+M(GU!E9!6]0P;R4C\3Y61TU*EDEI>DTML#Z>X`ZSN!K1=CWQ8`H^-$4UDZ?<P
+M?OK?H.T:57^KW_W*F.Z>5!'SV-0\3R7R:/\YZNL?K%]88,@9ITM_^;_97L6O
+MT9%[<_=+N+?A$Y^M0G7^:U!1=8U2@W]\XG9*6P$ORILO)/8E"K2ZD^O]V\_8
+MSJ2^7C2V<EAE?Z?*SOZ2&ACYI:Z!X"]1+RY0'GHA>>\C7O-3/V-[.C)NQ\(<
+MF9?2UU3\W?TS\D-!K]6M=^$VA\LDYTE6;=^'734O3Y6L*>U</[Z<9$[@GL+-
+M).X@P*!G1OW\!]_3UI_FG>T_J1]RY'IH1UIGDH7XWO)G?4O<?[N=P;LU@,#J
+M^Z>!-;!8!0_-_,7,#R<Q8HNW,[<XD<IS+;\=**`5WZLHAE:$Q="*&@SAQ;Y?
+M/UMS-G8B\WB'[]?;Z0G/V!P_=,(1.7&;`O_V_>[$;9'CA_H.%O5BFD-Y)_C>
+M0,N@HR5:XKX(O_]1?=6\T\>Z6GN%O2?Z\'_RU&F!1EZ"JH]G:HW%F\(]_..'
+MCCN&C]\V"/_V_>[X;</'.]]]#=)N"Q]WA(MZ\9MC4-\FYDO;YD[6IBRBNQMC
+MX9X2$W:2)<F"4ERD/0X5`^;%(35GRV+V+`N#Q47=(F*+0R?+?K19Z]>N%^YS
+M7[>^8%%!\75%!5=<41!/N?FF@B+#]<+Z^NO7UW_C^KL?$*Z_[]X[\7=W8:'V
+MIV+5LNN^\0W-3S,^1#_X+S;$9GY?N9D+N.0EEEA`WHI0S#).09`D1^2X<KRC
+M[_[(\=LB1;U]MT6HUZS+^<<_TA+&7@>\4'15%1$7^L2\?P/^JQ-\8C$^*/?\
+MPF@X[HC(MPW'NW/7N.[<Q;K#X$S0TB?/TQ9J,MG(%_'[2LU<V"67$M@*@8W.
+MENQ#=[7^0ZDIVQ$]3M3TIQ/8E_[4OO1/U)=\GSB`7;BGA9SH67>^^W.CX82#
+M.7:GBHM_!A^JH@(E2[D)94RY67*9$SP_T3>=S-SS$\VQW&?Z%--<BOQ3HT'*
+MDAI-/<M0MAN*>^TUIN:+Y:P>4X`V-[-ZE@;(I;H4/FSZ0+>(0?`ZZ43!"%YZ
+M8E]B:K;*>7[[%]RY8I>Y!-XW?<*4,B$Z#I9B!DOQB+W1U'P-&#B+P@:W+38O
+MK`20"*']L.HT@2"$"80RR+OIF`JI'@Y=O<>?HWIC@J5&N27&3O'@>=,+Y"RL
+M?+V^\J3U&/WZSW,:GFJ4LA@=(6`G8O#41_%_33!O?/TYH[H"I/P)%SM3[@9/
+M7N_YPG-&]6(XL<OT"G;('L`[ECKL@?HSO@U1=`8OZI!7F<$H6'3(X,ZR-QTR
+ML2-U>3[3'CH3MO20R6-"K_`6](RWR-5F4),M@1`8C?0L+@K@2O"\@.)YGA:+
+M:I0?P(/425\E2X#];0J88F5FN<QL+S-MRNHI(^RBH$DL#^GI%R]`,6,X$TOT
+M-UGPZ9/G5:7C'-\8:;=/;4N:IQ+O^O,O_TEB**DB>6L^S9'3];BG-5I37-]!
+M'B@U22M,.I[A]Y58M?9K99>UMI;?BQ=\+;?R^[KTO%5B2:['(JVP)'VWQ=N$
+M>FS\+J=%6@Y_NG1S="F8U9;L1+EJNI[0*I=9I$.CO3.[9L'70U*UA1A"7V;T
+MR,P5%EV?S,FPF*459JU./4R&<7<WO_,LD^`@1(HD*WKQ9>O=U5F=[0X+KB4:
+M+::VTJFZ^MJK+&;7U(3^D?J._K.:UY6&T_:2J>(`IRN#[YDI[Z;$.[^S9*JN
+M[/9,K4*Z<"E]'5#F@CB^'):VT@M2]=,_/P/Z*:?LV)[PMV']'`D4E$Y-Z"G)
+M][\_8]3?'TGT53:]HKQ:^4-F"L[^0=FKZFVE9A5>]2ZH5'DSYQD]O=M4>E]$
+M].Y*EG.IV9+X2^QPQ6$2.^;%GT=*.,X-5#6;_+P8QZ2C:RW?-6H^<U*^?!U]
+M6B>L.YEGINO*%"2>706%KNEXV[<ZWH`_EZTM)Z:#)4GWA>]&*4<O-[*M\79@
+M"JJRXF51L[A9\"$@<3IY0^!-XEP`'N=*ZG>5A7/9=+HV\_1RV22755J>/TXF
+M;?ZA=OAXI`RJS*Q6%CR+'GQXCZQ49I(=-JG,G"*;Q([5NO[,P8W\\\+;9XV#
+M]LVB?IN=A.^KQM5O5O-=DY1OMFY<KDG`NV$V'C5(XF]Q0]&X-.R+6=<7V7!$
+M84)`>^]4LBE!K0,/C9I;S$:"12PXJX.%?=ML-ABQPLT%L;/HCJCG[:P?D-U0
+MU"%NG&X0)HUP1A8S1)@JE[M`L<OG#H#&-ST60)_<CO@]=?'R/=\G[A(W0.E,
+ME_++3(-!;YNYS(5@>`42[[9"H(!`,@SB]YE-N,+%'-KX?4M<7%>%O*0RR4<W
+MGO^KWT==P,KO=5C8G83/&=/>6U_(\JEJPZH?&0WCX<_Z?OPX4;G-7I[?F,O<
+M]\J5&X$F0SF:=]\2V_BRKWV/P5UJLI>:&[,KE.>P2!;Y;I>:XOF3[JQ]ZGM$
+MZ:B!)$X,?!_*X5920M\`C<$$U6A[E1/<?\OJ*NI5:^*KE?(?LN/2D1CY6PO7
+MQ,I,R6U=?]YMQ;O6D`'=&<>S?_CN9\A5>>LPER1@SRU?Y9)%I-5I;;-]NH<7
+M&9HRY-)%"7DU4DJ\5SJ;W14&JD0G)4V22Z\)05:SO3/!4LG\ZE++N"S2$2:[
+M9!>6<9GM1]P74DJ6*C1(CA-OV\Y3=C`9Y^V%P2V9:J(SA253#=TE%X`Y+RTW
+M]920ZE?;4V(M`"O5DD?&JBV3_N#L:$BS5WKOTYI<C,^@H.YT*CQ%Y;A$SO4>
+M=-OD):ZZ#'Z?JX@[5"&7S*-SQJIS"@C2][ZGTZB3^6/RT\S%^-BSZ?DG]!3[
+M_L($WU]3O[=.\/U_U._W?2_]=_DIIDXM=Q'3EUO)*+;%F1[G=.9`/>XY7L>R
+MI_0\?NJ9=#P^*RE/MSY/LMUPYDG--/'+R\R%RTS>CN;)]G"S40ISRTQSNS'H
+MF1MO;H@JRG?9B::J*#"3&K[P-9`B<\-)OLS$0U9[J<VM\P57[ZI,R+\GX[9-
+M\8\2.I8.L#N>C--!-4KE!62'+R*?9FP?8QC4^RDR6B;=/ZC>Q=&2:ZPS^,J`
+M#<M6NT)XQZYXQ5D,[FAE?O*[R0BT]I39R-(OL[(_1([:3/R+IW$+WL*^F-@?
+M9L6$D^DJ`>ZOMC&AN@2O?*I#GP9`:44UT&@!=Z0<V##6J[L_-E[L/[!8E:WM
+M2,O?./%/7.>?C"-=1B&CY:"Y'*MP6BHH>I[C!PD<)=:_MB$.;8EA_O@':==:
+MIVUC-/G*#]/3Y.@3[+M_@N]O/W%.FDW0?SQOTHK/./H4G_B<\]_X_&LH_ZWI
+M\\_2P?%MC/.`H&S&&T'3Y_]D:U(?O]VF%=F2**+/_[NMNG[F4S^GZ_JIN_]\
+M*R-C4.>Z.C\TMISBQ)/<=K.0(789Y56N"CS!G5&!8^VP5&!E!=RI"KE<1R[)
+M]:U0ZW/:I$/Q^D8Z$Q7JJKJ*JKI&5U52GV/?21[7$NK&TK3C>C2>M\X(68LH
+MZ[STN/SI=\:-U3H:*W?Z_(WC\F_&=3`LLKE5-V+Z,E_ZC@[_"PB:16GQ?\EW
+M='RIX\H-Q)5-$^'FS]\>UX?EU(>5L8"W(V%BZOJ3:/._OLW&2"3-H,Q%YY"^
+MA;J#&&9>/GI;4"?S[O]V(E`#E5WFJE&RF=A-+!@9GDA,;]H<L5N=*/1]F(&U
+M.?+;NH!(@%Y&NBBHE4DZM!TES"%SA5["?/)46MGQ1[_1$%<Z[_YNVCR[_$Q^
+ME'PWO?QXRD]#4"MN7*G=S<O\",NM($;F!EP5_*XE*Y>[E-&G]?73NDB5I;:T
+M5G*M3)T_O@1U*ON>3@O/E?CM^^F_3498R&^IQS#)H.WQQO-A,_J_J;C5TA-#
+MMOMQ&FL:XAG0INX@?_+8?OOQQ!K@1T^E#.FUWYE@#?#?'X_/D[]\*LT<\*^/
+M,]QO>2H][B]]7*\'?.VI=+K"Z&.LC@7)=9#=A9:7<1ZGL[U86D926G&OC#$/
+M<F6#.&`1(Q901OF=@52;YW%H1WGMR;3CLOZQY"U`_;>:QXA^[/*SEQL,PA19
+MQ+_JG<Z@#"Z2MT9Q5T,T@\4GE9KEK5?1JXE>3:"6X[*S:-!>(YSV&EKHU\KB
+M0HJN[`M<4MF7N:2RVBL!(A%8J5MZ233RI$\]GS6;0CZY_$R/JEZ`(LF)XKK<
+M52U7+$J6^3K:J?*=C]TA;[48V8,3++M*R569LA[--':I1WHK7DD%RY9DDU0F
+MV>'J0(_3TSNWZ(*GF8I[0T;Y(EFT$9:GUQE]96:7\HA)C:$C9$$&W`?#/+,-
+ME&<40Q(:W/.+4<.DPOGL`]@W"74_Y]SJ?OBQ)'FH@_%?MAC9W4E7T.+)[>2+
+M@KY.5KDXO@Y,S>*7)4TX4>3%`<1L2TSTQ83):M^D-\0>,]V]:XZCD:0UY5PC
+MBS0<^$##`0]8SZWT]58ZJIQVG^$AF1U*1G`O]=7<+DU3$;*LJ<Y09ZA03OO(
+M_U*>%@>P9QGIIIBBPH:!.1K-U<KOT6,F2SH%IEDVF688PSIAF]&.(1IAY[+/
+M]"ZF\34HLWY=64<@>IY]KIWD%LOO4MXT&=+I^)[V=#1D3="0R:64&M/1D.V?
+M3$,O;)F(AHY+231TZSEH:(-*0RJ`^&A-T(V)Z,:4AFXJ-;JIU.BFDNAFC4I5
+M$]*-74JBFUL3=+.!T4VG'*<;#:AI<:"(8$S5RA.&.,&DL>7_=_1BTN^M3$`O
+MZ]L2]`*#_KPQ+;TXVS1ZX?<MRW55*Z0P,7R5N?#NF^9*['2ULO+;QB1C+;F>
+M26V)-0:UL%QF*RRSNF(-UFKE`Q+0%C`6;WH\>5[6Q7]ZE"F("+-5C'#"37)I
+M96RY";K(PEU,B=57*GO\>,0'[[$OK92M_,ZI,8-XAMFN%_O;+F+!L=!&A<RN
+M.JY::?4G#NF.BWFTZE$5;&NLH;(&0VA9E%D(:_-R0],4Z0P[CUR]-&_5<BV`
+MD1['_*.J?X@-^.$R#-^>1X=RQ--&=YYTB'S9=VLQT7HK4&=85ZE\""CX[O@S
+MQUV/,+VGH5+I>!RMY4JV`9K.9GF2Y=6CN/5Q0K&W0Y@F9Y(Z`9QZ$=9V"WP!
+M74+5$RG^04>2CJY#R$V/:#I5=8TR]W$6R"(2$[)981O>PQD3)J/W>@9\19_Y
+M9)K0Q3_PQL<3V,Z(9+J=`\6IOK(<Q^75QW!EU.\OKZY0MC^6-$;Q*E[TLC,3
+MR(F3<55YECCS;.@RO\RQVMP7H`P"\@0IM)RDT$J]K:6[_\ZKCS-E9O%E0C<G
+M8LNL:F,:1"8%EL'X*RPA-$D+/Y7G`]T^TT6#6*3L;=<KIDEMG6E-U]9-B;9.
+M/IK25G%J6]B0JF,6*5]-:BK9GU6WCBM2LS9RM,##)5%70DN]'0061KQHKXJ:
+MJZ>JB[,I.N&7H+S/@?N1:J%".4F!I//8P!KZ\]A\*WEX27N>IE.CK6>UX\TM
+M\:>F^-.6^%.;^N27?5B0WYDM^=:=Q0.B^.H]R+<&K'AH&],\5[9[UU&F0&@Z
+M1NG?@6_*6UN(-$-[_#%J(O3R^#@W?&N+&@-HF<F^S-R85Z,L>X0P+5&5(9[?
+M:6"/0&2Q)29Q#T'A?H$U[>WU9,<;5Z/LY%4H\B-:B!V\>LJ?KEV,)Q6C;H9:
+M6*5S>.^E1NS[$VK?BT?2=EX\O8%_]-],[*BW?*N'CGK[[VDV&M;\?_;K:$F3
+MWI(^K[GE_'[GVW8^_$HVL5^Z[T6ZNE[:=.[Z[M/E*3A'_C#\+M2UC[_IT%Z?
+MKMQ2M?V7X/=S2._7PZ;F:]N4W'X2G3XCJG3J3M"I6T>G^!SC6UNG`.41]=A]
+MF,3NL=B!C\K+H,4$FZ:PN&Y$BT&,M>G',V)K(7DO:A[!1CK?/=J]"^OS.B%=
+M/,P%[X!4+<U.:<:@4Y<VA]),0;LN+8_22N0]2.$^TSX&EV_IDH!$1!^T4%/^
+M'N(HO`I7EO-14_"U)`F/X%[U#/!A3I?UM],QZYY$5H)^*ZXZZ.J;'J^/74JW
+M^;`A.<>X:G"M.KB2[M^B7*B5!1<EWG$V#UZ#[[$=R)\^+XH!EU)MP6`9Q+&'
+M"UA6C@6G"HX95/C5=.I4D!(W'[9."+$.GE<Q\VBWF7PO^\X@CNDD\'3M[.^R
+M:*WLPR&ME<S!76<(KXEO[!-\^2%^88*7#O,_/!EE[F?)MA<WJ[*-3R/;LD"V
+MN3-2QB4_!:$Y3/T&,\^^Q-PXM5PQ;8YO)K8>R]'D,5`TI71!RF@W\S)]D@*0
+M$)EO<\=A=*?".'GS.>2OV\78A%&]"DENN?)PBP:)>VH<"I7%)@.>W"J>XNPU
+M!X`+KJ,4H@W^T:^<A@J)L$D^1[_%Y'.X">0&_/H?-AJV;P2,-$!+Q`@&(8?)
+M?*0.-J3NAS!<`IYCD;^,EW,4KC9)Q+V,=>RG/47<X;EO2/0&W[G5IAIE[R8-
+M=J$;`^BV4Z01FOE`)\O807E]B1+<#N+X[T=8#``<D`4QRJ722:PQ6BZ76-!H
+ML]@)0M[[Q6P4)P0MD5",2"=8396D]`?_4_OC8:@S&'2#V_+J53A>!O=78CK!
+M%:/*W?,38_)^<WQ,<O64(>QEHV#@6Y\Q:UV-)ST/2<$OZ&(%@(+YY:CD\V-+
+M._P,"RF`K&%4V8Z1&\[B<7"`9YE$SRI8-R;`6JT'B\JI8+UDI^KYUNPX5*R^
+MN:,20<>WFC%.%8'2S1E4%#ZBRH0)<;@Q@4,U3AM";QU/W,+-:1!Z=0+R;9X)
+M$/H_*K1$:FQ\@TTCR;%+$OA3:68"&%:RFMO5?K9QL66F)0S]<8C87)9;HV1,
+M!-$/-8A47$D'YH8YKX[P3N!Y:Q5G;LMF>K@-1KU!Q1\^;S[<@6?T]SR+/$D=
+M4`NP$T>)?JB:'E[1^*9XQLD_BL<S*:!.QR/(Q6V-1D,$^%;[BS_S!N#IQHE_
+MKZH_+7^ZW].-Z7^?5>9\?^[SJ.?_=OOB'IJY!6MB7F;3[F@WK@B[9VY^'P,6
+M!1\C1^R"*S!T"F;D]YDV2%0$,N")^G48EX&^^]3OR]EW,6+F'\-8$J$WB8=H
+MFN$?VXHIOX-Y$H\R@"Z$T^_[^RC6"S0-`+C=/N^/4:)ZD2R$VL0,N_G]&`5S
+M6!=GW[8L518PODKPD^/A":AWLBI^::W!QP0H5B#]K?6@YVJ?]]EXR_PCGV;@
+MR7,S:XK?N0P4B`MA,@J>R-!$!;_SRS%F!\0#9TZ+,8:*VSPG:0XP,XDAW,]J
+MZ\XRQ'9@O^H,K$V73.I$[`@%0AGMQOX*EZL:Q%1-6BZ)UDI6BD&I;IE8$OI#
+M*">12[(R7I2I)W,5>0_RI^_5K-MIWB<I<N,IW?SP&7P*G?7YB$]]27SZ*RUV
+MMS8CZ_AT(?\H*GG$I_>T(Y_^Q&TT6.&'?_WJ\POG^;-^CE_+Y\S_S_YA^\`9
+MN.JR6*/Q-I7&KTO0^(;-[^]#[KE4"L\!DC+<A$PGW"F%6P:C4C=@'8JHA*[*
+M:E50HP?^,E-"3-_:.,&4EZ,2>FZ"SC$$%M(Y[]MJB#/ZPF2:YW#8NBFF-"-D
+MC?JS7$H^30EF^VCCGX+'<3^:95`Y(5MCA+7N*\33#KS3VERN#()^E3X?7EZJ
+M\<C>)CV/..(\$N<.Y0DM!Y%]7H+43^0SWY8X'QS/3Z%]FC1]6SBB?3:#+OP8
+M:5]33[9HL[NF<M,)WTMECZV%-](S+^ZA%1%WINRTM61S,F7U/7_7636,2'R-
+M$F\]W5DD"=$2<>QK0EZ/(T+7M.Q<('FB)2&S7SU8(U>9-W>AWH"!IW-6V*O,
+MS9]2*,J,Y:%UO^'8663)&?'#=UKIC+99YL.L7B*>N=9]P:9L;Z_[K=!B[/>9
+MV]R+0U_TPS=\G&2OBC9/[G%$KT4QV^7WEZ"<<T3UU=C?;OIKZ-=X[UY5-/0,
+MQM59&]:?1XBO$WWP$//O!-JR,L](7&BM`]&J^@NF/[^7[%?UGP_1W;CL6CR@
+MT)XEM(3NC6VRR!RNL@7_RN*(FN6\EH>G&MQ36E90&.F=I%05=8@/FV``9*.\
+MW%RXW"0=(*\#NN6@WJ0XW?I@\WSK9M6.X>2BNAB_E^X+CS&_@_;U1K;#8,*;
+M7N.QD$/K4V,A]X@@O6?L9K=+F?&>'F'2[@RM8K-K*@I@?J<C:N]Q7TQIV(UJ
+MA4/$0#5^]2BTF3;-+-TFLX'E%C+5:0KW,,(ZNM''8:U?1XL*#%_JQA:Z=6V:
+MPF(`![O8/8_3"%D6%5G/T7TPGXVKF>N3`O.OQQC;*I)DAW4YP])=]70M`-YT
+M`6CR=@@+,+IVPH5TJ#[N0JI&R,Y674@SV9E;E#V)^RW4P,0AO!506HUR2\4(
+M;I`,)M:?-P]9D]<HO_F@MC/1[K2V^:(X50*LG:Y[#!3<R8#!D:J5'4!=DC="
+M\D0;5%NU<E&]NA`SK,WU-$/A&XRPS$N^,$DD+,CQ@+<]],EMY?=ZHR0-\9T%
+MAW?&LM14])ISJ2>?\&C6`_(VK(8[Q<")[<#J7!7*[4CR7OR40:"U^["V-DL1
+MWM^=5>)2'GR(A8?#Z#>9Q1UXV%W.ZC85&:1P1E8AE?%M2U19X5*F/$2KR<\/
+M:@)GW)[(P@=4NK'B]0&,.G(8=80:SLE'DQY*H@V'NAZ-)`($$G'1+0?*5\?H
+MB+_$%?="I@P,=%1C&LFTNN?0,'/B)N"5BQF=AO+\VK:LTT+;BS3F0_^>%-XA
+M91]#N#_M7OH_>8_SP(,3[7%^>A]N?EAIYV(6VX/3MCF_D&:/LR!ECS-Y;S)1
+M[8_NTV(K&]SYOFJ3I,%>5L"V)J]`:D_T--EW)N'_<1_;MS+0%@7NG=E8G'TS
+M[D^T7VDPL"OQ4GUC9MS'MG2,(R53;G=G5B@/SC7H?$]2XE]_4XWIS^\5\)J-
+M%3;)&;6OR&^\4/I;VP'U>B_E0J`VXBM,E)U1L"5+;?'+=]+5^[WSJG?/_9^W
+MWM+SJG?M>=2;N/^@3N\K].Z5AC2^0J\EY=F=-L]/D_(\F3:/6*?S*WON$D,Z
+MGZ"OZ_-L2I_G7^OB_E%S+D]#`Y<FOD]*]_WO]T(;^]0V9ER6MHVW,<\N#8[T
+M>7Z->7:J>=[^E[1Y'K\7SR=;6*Q,S/>5@F1ZM,2SWG4ODCP=(W/:\&+[*KS#
+MYH_W#[/":VYA%];D4`7A%-Q>R0JCFAE(ZY^8>:]V5A3$S22*)89;>+W)_*?Z
+M>J7*BH/WI)-5_VR?GNG?G$A6??F>)'\,\SG\,68SM6CK;';8,\FG9R*Y]?[=
+M27++G)!;LYG<>J".R2W-#X?YB*?<X9/P?[R;Z-BFV^+$>6<<+3YX=YQ6[\])
+M0ZNKQ]>S8UV:>JY,U#,G73U9X^L1TM7S7NVX?(YT^7;5)LF$R>GX?6M2GB?3
+MYGDP*4^]/D^R["NKC;O)LBM8LM5MZUO\10=I9K@<#P`!">8"!:OGL>QAW=EF
+MXR^YUH-N4"UQ!ED^DXZ%%W6@CY&<U5YBF8TG"<PU2BZ(#'6?6W=Z.=G_<VVZ
+M_?.YB?WS#_\/;U<#'D5YK7=V-V$3)MD%%HB5`B+^I!%<4#'+CR:12?AQ81/9
+M!%$$!8/-HU>D.S=BLR0X1#,9U^ZM/_?Q/KV]?:[M_?$BTLI%L!22/+A)N"D&
+M&B5ZN952:P="ZZIILL0U>\_YOMF=F=U9HFC+\VB2F6_.^?[/^<XYWWEI(D+5
+M?WX0V!%]6:&;B`-6\W\\2.6=@R@S.8HR4W@)7<:&NLS.F5I!J+_;J]8W5ZGO
+M%$+<IA"_<0P]Z1K:"$5/2L17S`EA'B7H8:O;:ZMGO?*+6TBX"SE33(R76#'6
+M)1NZ!G0DL3=U;TG<L];D_]],ZM;*L:Z34G[3]HDF?@*"E,3GR0U;B/Y-$36`
+M),8HI:PWE<ZUFQ.7Q,BH\'EQEWS/(Y<DH%__FS+68[!VS'IH]TUU_F]*KLF7
+MC-;D]]3WVXW>WZ6^_W6.P?N;U/>O:MZK;9JXZ<OL^6K\^P.&,D0;__F`D1QX
+MGNZ(PFB4/+-@1H"$>I=97KCGG80O_+3T94J,\YO-&?,O3'Y`D1F%1&806)%2
+M$!MXM?J4@>0@P9\V>*N+X\L0%OI\NA:<&O]TORI/I@?+6;'<)F9KVTJE2L%F
+M(ZFB[4%-#V>,,R^\WU`^FQ-#D(7#\E>)PWUHDTYF:]J_<0QY.GV38<O5>F>X
+M+[%DXU?7!3(/I,)+-Y`I]S\W&/7M3(.^_:;/;NP#&?IVX88QSE@=]^O.6)H*
+MI^Q;FG;^X;ZO=1Z<D&21VI?Z'%.9<W>0>]-LT]D?-!USB%Y6O4M-GY48/)N9
+M>*:-_[XO$3"9>>[]ZT;=W).RF^-&,=/%J(A_F2NM4O;.9:RI*7ES4(>?J\LY
+MU+B>U"ZDV&_8:KEZ(S7*C0NI.&HQ@J.V0CQF@*)V!8$*_8^-.A2U*/K8#7'4
+MB#Q7E:"GE9PLZ?/\#_<FXV/U>D+M&'K"%U.U>H+_5HUZD.>5ZS<0]8!B?2GZ
+M@3^O92K!&::!L$19L*1UG<'Y]UZJ`U*+CX*1LV4L>\_ZJ4H&(,FEOR+.;DB]
+M(D[M>P[$ZR3V/:+*C$NH,A'#_>'5>Q+H5HJY-\6V&_HRMMV#4W1]N$&QZPH!
+MT(RGU8#^N#EAT!VX(Y2PPUH&;@VM%J-DCO`WJ/AJUOM2\=6PE=W4(.OF'/RQ
+M-+FE:<__K4NLGY1Y<.<8;?C+9%T;OBUEU]#PT$,PYT6H712C1DF];:'TT4Z1
+MG]6T&G5,XL*:-"4^7_X'$!KB";$#JH)C@VAYI`+94-<56JU,K_\J3?(YFXX5
+M5.D(1C9^.8+Z/CIXM]E4EX-["=D%@0ZN1S$LGG*=Q.CC;`1!(>IB#C7V$U+B
+M2"89\]V[DVM/?Z98IYXI7G2FG"D>I/VMQN3.T:R\\5[YBWO(RANGT<MSE/ZW
+MA%JFINQ16KO\^VMIT&P@(@9B%&31:U-V0=$73<'`'#+I,##_/,F4AH'Y)JV[
+M%@.S306_5/?"%?>D[H4P(`G_1"#F#D02[@G\$MT3#6CG,H:;+("-<E!NO$>W
+M40X.3`IEP)N$130+<?[\DUJZI$`$_>V!2-P3/7=OG$;K$%MO`D+Q`YQ3@4AX
+MG(DLI@^U-KMB35\^6T,P]M`FN;"ID>P+JZ';XN=>(;$?:$:&?JNWROLGTGZ#
+M^9(S5`K]YD#%O@EZDX#%0=\=(7T7M^]Z%&]*D!.'0_3%]-BA5;)XD>+,6W$2
+M[KH58WJSB6<E7N0?+\3G\),ZLQF2:#XFK]>5'6^FCI\<Z3%6^&BKO;F#?.:R
+M-R/.AL3%I*U6]U;88[SR3^ZF7H?P0"Z,U0+)%XN76<5A="=-2QK!E0V1C/FY
+M0\2''N;Z@2+&#\37HN^D'S;>?I._.`&^J>6Q.",/^ZZ-B`A1!F-_L<5S&GTE
+MV)J5=R>!.(\D@#BGXWV`%!S.40T.IX\EZIJILXRZGY#X2H2]XOK@CQMWY`AQ
+MM_W'[2V>OJ9`'PQ5L*)7Y/H0DB-$BY1@D7+[CSM:?+2(+;BZ6_3T#5P3YF1X
+MOQ'?(RIG"R=W<GT(S-D4D$'!"];\I^CK0U!!3U_###':PD%#>JNP(4^N11UW
+MT.1_^-P1BN44YP8E+OJ2R%T0,5_S!4SW=15N./"[_;52*],I^2+VUR8P\*#O
+M)71<S!.W6QEF0J55UZ=RC6&?GK,J;KP<T7.Z:?E$,_83F6(B=QJW#+R/<4@[
+MQ[78FJ^L26Q?0=]@5=`7K:J6/XLA*(Y_*FE&[O#ZJ."+F8;7QVHE7[16)+N/
+MG(G>.@-Z+W\->KD&].ZB]":GTD/H"@VU-%J'[TJG->XR:6TSH/7+SR^/UK4&
+MM!Z]3%KO5Z73NIK2NM*`%F)^3!576R\Y!D\9T'Q[Y.O1G&]`\_N4YJQ4FB"8
+M`U$32&9B"OP%TZ+I@&L>WI)V?_?=RC'NR&3GI<CC=_)2Y+&#0)!<L><+]-Y^
+MO"[UGKC*JVXL7O_$IO#Z[B5Y"5I>UZ2W;<0[!K_OI/*[R!KR&Z+\)JV[Q!WX
+MH#>A'X/2JM4;7M#K#?O')^4?0]@65,I/*FPG)G5>9N#^A`[AKU&T9%5_R+U+
+MKS^@WOL6Q;"LGY#`J^2JZ,6<7!71$AWY!Y/A#2D^`KWO^?!JQ??,8HP'U830
+MK[TUI&G+^5R=*KR&>.QBBL<NBAZ[J5J/W>N5M$:3$CZ[:`M#JU9&JD;/(%;4
+MI]"I64/F@\;#G`IBZ5J;!F/I>EQ9/WZM_W,5S@,6@2U\HZ*O/RCT[_TB#N*M
+MD^NE*7%[E``>::*T@A6[A#-;16X?PB+5H$SR]*-22V"W?/TM9OON44O[QQ97
+M-QI*FN/4X,Z_Y^I6'+FL*9`#!9L6NNPOM._JMN^:#/T#1"2N/VQRG1N'"H(0
+MV%?"UPZ]9?;G!*7WH#9PB@E*%_82S"S@]ZEPUMYJS4WPL[9_#$K$/I/"$7\'
+MA6*?B?\-X0GSJ,F^:P_*]78'R&1H%[DN\2.:1R!N?P%U]-N!,.CRN7#.*B7B
+MT2%R!T3?H5;?@:8.%]2NQ:&\_I;VM<0?D`*'!@Z&CE#H,-H?PW\43[2?LP2M
+M8M#)$>BP=T5^7RNWSTH[23P.=7W'U8VQ5ICWC]0RSTIZQ`]:20_.&?%\D:]?
+MZ(`QZ:)ZWM:D^GW"XNF!@TS[^1FB;Q\VU<^46CR]\^+N3QI!D!>^33]P25Y6
+M.)LO^HZVECA:N#97-^FF."@C(V9H=HORL4T('+4IKI&I-?;#OC:4M6LHUE34
+M_LPIA"+OI@QWG<3MLR?A25E*G_Z\"+K0_/,Y]L.@]>R35CG=JPKJG:V^??;]
+M)X'6J55D;HOM`^/A6<L$^_YC\7*2QP;I?5\(])K\4TA:A-XXWU<M5=GB)\DE
+M4?\&[*2C-CX+QNE?L'<F)>IG2=2O81'YLBO.]R>_='-=_&SRJ5G]=$;BTZZ[
+ME$]A1\)I+?I">#A+C,-&/T;JR0MST$G39'A6^]5*K1$"[Z?[,#;M";+VX1C\
+MYVRR]LF9I?FDOYAL`JZ3H)(U=R/6B$V:,E3&;J3'PW'#[Q$KAE<\/B^.4,.5
+MB.0J5\4(9%G&,[H[K0[S=76HT]=A<ATN<RV#3SY/89!R_WW%I=N8^PVT\>\^
+MOW0;?2LNW<:GLL9H8]ZEV_B7Y8G-3XW'0UNN1\-CEI['?*6=S7$JSR:HC62'
+M?RN<,@U_0%M:0U`$GAG15T`G@_]^N=8GAW;E[ZA\7['J^#IH;C$T6E3+"X"J
+MSLZAMY%-7ZZ3[2!G_Z27LZNL)ET8X7'<X?$#J805.W:>-1683#M'3'!8XG./
+MU.*1"6-YX0GL/[SS""(?#QTU^Z\X@KL;N=]T9(OR+.M(A4(L7WK,*?(Q=*\V
+MYDJE;+O,WLP0#RML<3$\CMJ/E#J\4B6+0"&Y<`0?[A?.%.'=Y9A4:NLL)9N=
+MMX94+.Y"W$D?"Y)R`B@3<-07CLXF-AJT9F23,E0R5LM-62:3)N9007DVI<OQ
+MH0J:(XI)]M.@OI^NM>C[Z1T2G,B:>!!,G[T!8M+#NMI`L=$B<0:WQJE.DC27
+M2$SK,@=J"C80_+!)?[K#*IXJ'(:U4L(J-\3))H5S:'(-"5",\U'YJM7*-L6O
+M`&U`*BV&"<56$EQK`@+(WX2KC6I*9D,*'ZQ*4$`/R0"KW+%BB"+!T.ZJE"NM
+M2G==T,8G6O7XW?]3KL14)6.QGM#TTRB38KK$DG!N;"8XW[]"G&_@_9`):6),
+M[9[E-"`0HPJODE[`4@@\7E.EMLY_@K+#JFICN5ZVT-K^+/*Y)A994].KRE-M
+M_^F^D7];IO>-?&.V_\RVS%:.VC+-.M/C6ZLNQY9Y&Z?:,IUZ6^;L.R_'EOFG
+MI69379;6EGEZY5>V96KB_Y8J^QI:B;VPRHLM9IJHK3FQ8JT9_,^;EBIY.#7A
+MUCK:94N-XAA\8]G_:?+]Q`2]%C<4>?-'Y"%JUS8:K#"0AX8]\M)2D?FL=O@.
+M97^%<C.21/Q3DQ^'80[2'!^(F4,-KFHV"QVM;0E::+9UNKT%]2PF6_\I1X.K
+MP]`=)<X,\V!!VK>.NERO_!!'CQ)H^P^;,1EVM4S`KE4:6OR;LJ2MG\H+Q*>\
+M15W;LT9U77<EY5:,Z]@KE<%R=4>5,37K_38:^Z?"`G?HF9@)ZS@)8"9GR[P2
+M_TQ)0.P=H6VM5UZSDF!BPI]9>PFNQ!TKS2;#.>LNTZWS2_C7#RS]"O[UO\5>
+ML*-4R8N2]`5/(^EMW6F^8(2S"DGY0Z7,3+^M4MX#^];`)"AIAY)0KIB4@W6U
+M<Q5U/1(C;[A\HE4SUD2O;<6C`*/DSU[&,ICG1]C(CF*NMDQX1*=*E/RARW3Y
+MX=1V["^A>YJI6F9Q*M),1B0A3[7\Y+*4W".J_Q,^JULCY\`G7OF_<*$_=SU)
+M8%8L/=>CI#1+SP&TO"1AZ$%^/RI+Y3<1^,'Q[/4*<XK_4)O_1T=C;1J-XQ6$
+MQJ,5B02KU?(?F51_I*;]MROY'A4:F-$FFXPGSG&2O\I:+8O+B4&"7#?@R\RZ
+M7#EZO:WV=NHG"-B$1L3?99GD;6R+<-R,!U^+,&+A\P^:$V`UL,7<,APFP08.
+M<H\&GN+T'IBAWIF;UPT/"3AO;HC\SA(-5KETER6,FI6DOI:F7UL5?KE-W;:=
+MGABJ@*XV`B'6]"F#F22SA5&&7A2`TF9ZY0M_A3.3LQ)E^P]QW-O)X0X$.9SO
+MEB-ZVNK%DGWG[S[[&`;;%]MYE@6Z.2=$^W`8Z^*?4V>I,^-BK9%O*DL*L*-.
+MO0P;!QM3/L'=M<G6"K,IY5Z)&O]]FS:><*3"*/?AYTN2<5,[.;-!W-3[2Y3\
+MC@XR<&LXS$ZDYO^\*FP\MU]>0M=,0X5Q7D9!Y5M981!3N4GY_H8,W]^Q1-NV
+M!>5&;9NAT#A3;DPCOO@KY`=]KER;MU$3_[B8]$^U_.8=F7M&S_?IQ=JZSS>L
+M^R92QJFM`5-NE/]21^M=SHC6U,5J;!QG0&-X$>VG%BY#_N-%6A[K#'F\KBLS
+M-UGFIXS1?8_F19?,Y]CSE?+(JV3G+DKNP[MPV@H]=#_*H&/%%](X4V\QD>%F
+MHSR[_YLL`T+>:IR_]PT-'0=5!PQS/O\@O9S-J-P6+<^"3/&'I0O5'&Y*.Z7R
+MXFJIY'J2(ARV;\<27<R4&O^LI3\[0XS\6;<BFY7*`N&9^M2_N@FNK]O/W-1>
+MP15(]<5CKZ\:M%R=-)8MZ]P)'5^3(_S$>647QD3A\'&E8191;9LGN75C73;-
+M(*?UQ\5IX^,PS*D<+E:2(Y,$IASF5/965TF5-QOG./_'=+I.HW%_M%A?1Y=!
+M'5<6:\;N!N/Y>!V4D7^_$"'=0[K\=\5TG?<:7.$D,GB-9@C/WHK]/FT>'.)G
+M"K_+%ST?=G)GB%['S6R7;<(91N1.=W*'J%'<*73\4AB997\:`R#H]>\NDFS%
+M!&3V+(#Z+*`__];_(7_V5LJ_D^O'>`EBOT,MUG,(GJ#*L',4/=%^KGQ@(;2(
+M(\8-YQ;TBQ]"$P\&-AYF:-.'CC+X_`Q5,9Q;R`\-$3Y/"/1;T++33Q*[>>3*
+M('?!&_1$*JOC?+_D8V'6VZKD725XW_*HY)$+VT5/C_@(B/EI\*F)MTA\#]*P
+M[\+;VCL#$?MU>)G\*<(_LDSD=F/E,.>_LYP?+P1VQQJRW/SNAH?@5U/#N#!W
+MH`A.//!CSO#ZW:&XI^W`EMK:VN%'=K>/F"7/[O:+,PJ/!:T_#+(<'<W=A5TB
+MM[?5L[>IW25Q;2TVT;=;&,EI?&M9JV<W/&NQP2\'X/\BU];J.03OY2*N3>3Z
+MH)*,TC$"^OJAS9C=.U%EWBY!NSR1>4.=W&EZF_4,'*44=\K`2L17=M;R4T2^
+M5^)ZW%PD<`W\+.(BA5SOP+>0(I\/%-R>2$-V$1\9L(:*^!XHC%;RP#B%#/Z!
+MR>7)]_#P-*W-;!,_10A<2.+L#/>+8>&C.0.%P'-V$3_Q<!$I=L'DGWJ8W)AV
+M'IZ9>))%GB#H@^3ID[C>X)TVQN(Y+?EZF&,#^?#`PO59./)W!V6\(Q<&IHB#
+MOP?RA4#$U&@+EC%B1Y$OTLEU$6`Y7\$.F^0I0$3T+B'09=I1*`0^Q/R(@0]M
+M_F];`EW$;G\];`_R38NIK8KKLC?7F$E%2G"+H>?::>(G+9Z]]OT8X^&0GUZ`
+MDVBOXBX+D7<MN?`6ML-XJ1,VZV<P+VX%LN&O)HSUS,*+5&;GT78%M;<_>YK,
+M"VQ9XS2)CS##)&$/FMV.PD=2*0@MX#JPT!+HH6_B?(_^':9;A:$#JL\3O,U(
+MX7%FN+K.A3RK%)X1>W,]87D:9G<6%DNV<DK=7*_\RBWD](Z-6,T0G3ULGDL;
+M5D%K9P^BO58,%R7J6`GBCSMJX2+>2JD*YO'>^$E:&62&.-[G_IG>.7<HP#^3
+MZUR5<JG*Z".<"SEA,QI9XR7."JR<_V%M^;F5\@2U_'ZE_%Q:'AHZ_-M@PVV,
+MTE04Y`IWA%$8N[_XARR!WCC?2S^_7OF<Z^6]9(7-M@3ZL)=*@$)?G&]#"LML
+M\1,)"GU`X5J<6?PT,MA3=(/]'HA`=`A9Q6@2]^<GFG.Y_@QV=AX5--0K`!L\
+M'+D>GVWR%PHC#$]Q<^S*U2+,NEKX[A5O>T4N)G_O9IHNDXL1.>:LJ?9*542Z
+M1[17@&>F_'.E_"/U*=#4IVI>`K1I7AR=KKG!YYJ.?Q$?F`W[2-3%CP\^%\(_
+M)\,Z.&RG>9E:ELZ-K-I^,>B+8-;A4?N.&V#?+RVN<U2A]5CT71`]<KR7Z<2^
+M\UV`K5B(.O@KA'`$RC:^VSRT(P^-S574U,QTHI/YM*Z_M/$7OW!1G<##BIX8
+M\-EF*]IF;1YJG%XE^@;E5V]2H&,&21XULIF3$F[>40\[OJ,:S]G;K%AV.Y05
+M::4&F^-^M^2)%2'5J#@*'R#.=H.M`G_L8,JKX9LX'\//SL['"@R*3T#?1YG(
+M0%%(\_*M^30'LF^0V69E^%@A[[`WKT4]@(L5<:P:5Z+'5ZWM+(&S=V>)U4*S
+M']O(#X=B^<E7\8MTN4W__4::!_:BN3'K('Y)9,1O/@I:_QMU=R]TD-R`M?7$
+MQ&56$?VY&I+(4T$23=&/5M](IF1SFS^O5GB<)>!C['S=F87F>/>PTF..6JDR
+MOU;TYHM;'<''G<%*)\GO*YG%<4*'5>BTKMK^F19G,\GEW%Q%=V6;05GRRM,Q
+ML'J6N\(:N-(K3R!I`$"W#L$O-?)]^">*II`V\7-:#.F+"DE0=^L=(A\-UCM%
+M/J+8+:!.?$3*MK_197_-PS(GVF6'_36.1<.!@^E%T!1'^QF'_8WNG"XQ6PA;
+MX<LX+"X^ZN9C#4>;3_JO=M?;&B=)%=82;PV.]1RL5"<,-901U[SA+!>!J2;M
+M0OI:'YJCN/\*),XIM-E@';_I?O;WQ</G3XS`!&F/SBCL(`83(EU'F!VYH1,/
+MQDK=OEC#,#F:OHD99N"`]K@3AA(+'<FA(8="P)&SXSHAG&,_G"VT]7K+ZW*Q
+M_/NT/,S("G?`T7BV')=Q2`CG#DS#.&U=V3W:LL[&LUIKARF)RS[<8?I_UMX%
+MKJIB^P,_P'DJ"1HI&B45E285*BD4%3[`1ZB$H%86(@\YBH!P0"I0#"Q/2%%A
+M6=?*V[6RLK+2LM)"K]='U\K*2@O+R@J3BHJ*#.6_UJSO/F?OP\'[^_\___/)
+M%M^9V;-GSYY9KUDSV\2'+VWAD;3]ZU#&)G::--FW?VU7J(V1>?O79H6:&`5N
+M_SIP^8>5_1)54F*90WU?GC_8I.W74"N;.VRNBY7/AS]_T=#PQXY`5^\/?G#W
+MQ=<GM_\02'\'JK^'-^7Q$>+2C!]"59@`->$'^Q\[0N3^/YC_V!$D-_\AD&HM
+M"T[\X(<R&^[L[NMCT]X8K=X-'W9M;TGCHY:*M4XVK'O&ZN/?HCW+N<FA\1-"
+MEUC=;>Y3-":2S7530VGZU<T,=6=T!)`ZTAX_U5X5D*AV4[=WREO<7K.=E.,6
+M&D'U8?>Y,X[&?U#:G[BCQ+'6;#>K/$HM^:%F%PWDHS2/ZX/O<4\Y4K,[S%U%
+MFE%'?=A#[HR#S`.XI@/QGX;4])/S_^HRFD->ZT>\EP;NHKHI1[FNJ@.D.6IG
+MZ66TA+P62!.@->2UD(`]),O=23().-:3"@?(_&BM&Z#F!^LGNZ1-[E^V'Z.'
+M:\MS+P[,J\O8G^<>P`?.3SD2/Z6EY.FZC#;W@#K2XQRJ5*NKF)[!G:&[>]UH
+M91?0_0-T-T`+MJ-N5>_,P#SW:%6WMSTAKPWPVYJZC"/Q&71_NB"IV5R3=("N
+M.A@_I3GDCE_X5`V:I5/L]97WA2W_<$E4S>[.FFM-91&3:1H3#B.=IVM*.T?O
+M+;%+GNMGN<)]?:B:!TU^_>H77:*=Y5USRKIDT'Q3ON-JCH;._EN=U+4SN&;7
+M"<I9^ATIE_WGF^IK$DA?[XK=F-8RYF^<.:[;KBKC*TPWOG8-E?I+0NNJ@K=W
+M6>HFTQ.WUJ=?$T"CBGWK(;4[M8-%[?%)'4MZ-W0EM08TT9]+_^@J:^7!=M<)
+M&6P[:G:$N3,ZZV-?KD]XJR8W>+!KSNN1ZAPD$GGM-;LZZ_JSI-[_48O;1IP_
+MNBNI@\]-X0PR2MNH6Y3L#OZ(&`,-D/:/6AS[W39^VQFMQ"%+/M&5<`\X'LE\
+MAKJ2+K>Z;5S@%[4>3&F[;4I7K^HL^96&\&1=+Q_1?R]VBG*YS"3=+73H_K+X
+M^D5A]>95RM8+BZD?'\=GKN_HK&GJK.L5;W>%J;"%>'NY16VB<>_GM:SX7Q<W
+MJU4P/3^.U/N_AZ@P05+:9K;<Q9=M9WUS;]GY\Y7]GO*7ZCIP@=V)ZD-NQWH%
+MR/=@JHC9T\QW)XD?G,^RW]NUF!0!.\W0EE"YEF9%GGMB'R6..FG:UH>]YF:!
+M$:IF=!M+JK10/%<`38!6F<N[DXYBGH:\9J/!'O+:J*%M04E'W4D=-$=/T!P]
+M6F>C"<$2;=3VGT*'M@7LKTEJ8W&KY>>YQ]#L+.O(<P^GB4)O)CZCK>2E^*KV
+M\JNH3M2U:_NI4&8L7%=`6X]7TU6+WSD>U#6ELV9[9TV\R?5[709)1KM[AKRW
+M`_JX11+H%Y(06%J_@IA_Y_*]2UA1P[%<QZ>Y]Y"-N'W[7V$U?YVYM/\;)I/=
+M]-$)V5!@TN(^(+!KMK?6_'7NTK/>&,P1;>^X/U#OF$971L=Q&P[^.IS4@5AB
+MO0Y[ST7BK)](3+&]+I'D>F!]I;VS;@#QMK26X?QJ=KW!@W_HKZQ']JTYU6OI
+ME:_WYH1?:'1_U'(&/<"U))WIP4LM?/9?((VCJ6?1:/_H:Y2C\;_C6+UZ25RJ
+M-P__$)J=Z@RR5M7^7;^[YO`$^87;W*($SU!ZY:WN[1_]X-ZO[M$[J06WZ<5'
+MC5:U\2*JQB>II,^E;7*INJI#Z>!U4]J6[56MG<+3C_J&NL17?];W3<F%_,%I
+M=?;#'SQ$VTD%9G%"(R]TV5==72$FTH"7Y8;2=%A*PWO[SY37QM.BRV5;-H5>
+M4BCOUZ9&$Y.XA8\M:KFZ0XYL(BW<%:DUM:J#FOJ]NZ,WJ5!3VMUCPNA1%G8<
+M=["]4M7NGA!&RG/=E%;W&`0<-;DLZAL1G,E"L^7XT(;ZI([4EB__Y-I5::YF
+M]QB9C$DM2D?:%<EKX7Q,UKEU56WUM:/?Y=".*6'N@->OD-=9%>X..3ZD8=FN
+M]SBG*LP]FJ5)56N7Z][.EHO^9-'0LOUKR]`==5/"W7WKDMJ]G=>M[T9%:>=!
+M\(//;*DA->'PS6W<SADMY0J0Q.X<EM%1-R%T6#*-.TO`_N5-2WIM/Q(6D-3.
+M/(G^&IK4>CBIK;FL1?>:^)<HI.UMH4>N777%VL:NKB^OO>+;%Z_PXO>O5?$R
+M.P,,\3+_N"#05)^Q+ZWEN=^HOY87\_+[JAQZB6DM#ZN4`I42HU+N4BGY*J7S
+M%*>4J90<3LE8G=:2I^`<56"/*I"N4F:?X@.M5YS2/EE0Z_FKVO-7D^>OG:<\
+MQQ^[MU6J9?WPNLW\1\A;?6K^NC3D+MX3Y/YL6&-=S&'JO:]I/)\\+]!T\'_\
+M.^KGW\'_G_[]OZFKS_E"PXE*#Z@M3LOY">O4`U>3EG&AMW.89:KG/_8[GT`O
+M)8\=X]TV6OF8LGCI5JYJ@MN3&J;.JU<UJQJJKXDA'46[24CM.C[S7N6X-U>H
+MMY3H>0\NSU\K/7\EX"^V`3HN7W)C34?\THR:;9QL7]J_;AM?4Q_V=OWXU/UN
+M5<'Q<QHD.X1LH,V)*OM5R6;0I6K4/WO(6S:J>>E3=9L35*L:>`!T7!:R_(H`
+M8R=103Y]GQ57]C"<S>?R>^O">*%6QKB^JT]]O^:$/>2N7[DSU<7N;16J%%\1
+ML'FE87Q*/63BA-0^I2Y0A;9Q(26RX_^JFE"W*L'3>JJ:GTT>_=6`#]VKU(,/
+MDN<.7=JW;IL\]]N<QW^.B:_G.I>^[EM-F*>:^K!4U'.V5D\_3STJ,]&GT8;'
+MKD_=7W/"$7(G3]S=R]>@4$U'KLM1TY$4LIP=>E(ONV+5$[)O?)N:F2&UC@#/
+ML"BS[UZ^&M<GN[W=RAOT.BXM.ZM+Y?J\&-S^KE4F>3EA?MY*J[R5Q?G4TV[5
+MQ+KZ2O7`K._1N+JX;O,:_7A9XW^D'*A;Q6CH.U39DE[RL$L?7$V/IYKM.N?/
+M1SGI^%G>?B!YHDTIK1,N02>$++^/-T2@(Y;7]M+QH6/EO90_0(V7H:IQ=:K.
+MFFT-JI+@.E6;6T%M`#=R@5.AW#3^4VT=5&]9"P#^,CJ*!.7A54VJ)B[C6')Y
+M_0.A?#"9@LW!)V3J&*_X8OOA1_D:]F\</HA9%G+O\]SGV];(B]Q)AOZ2$H']
+MEYY7_\`LJO6P8K9U*I'JEEJ./4Q%&UYGW]RP>JZJ_OK^\:M49]XRM%Z]"-W%
+MS<'O2(/E'34'_XI:ICMP-CLG_U!Y09VZ],]#AHMCWT'I"QWJ&PI\NV&K^%%9
+M[H7<HU:IMM=\%>(ZR_>FZKJH-HYR;:5!>G4L_6_)T+H'U"<S`\_GSGU`?:BF
+M5]U8L[N>2[N51#GVNIWNM;W#'%+["I4=OK>F(V#)>>L#^!:A0[K=8LP''51@
+MZ9?+((XV=OHM5K>-LY=]SYJK6TW/951X;67(7<XN^;NALGR0R+2NKI^7BIQ3
+MWX^X5'U3`]6G!AT[AS$]5WU8@%H1\?/\L<;G9Q]&AUF>Y(*&!GF6N)Z?19(/
+MK]JH7J:QH'J9AWXZ_-671ZJ/CJ]N3SQ\*&0Y^T$/;?]BQZ&]DN\I^-DQK5C9
+M%+^B6_<^CB7:^/-#.]4$YZ)IU[<XVJDR:8UJ(7_IXU.K^D[(3H-&H$PD*X_O
+MPP>[U*SI4M.J2\F%+B6SNC:S2M+RGU9-.^DJ-G=M9L6E9?MQ38>IV1DA\T1*
+M(]]YG%65+=RH^E5;F1@;VK69-:*6G]HUY8A4X,VL[K3\^:.F^=3LC,)TJSQO
+M>)-71,K,<*N)Z]Z\CB?JT`:9=']^Z5:SM4X5WKU\G>>9->E;LVVKJC&D;O-6
+M):*XX/$SZ'J&0]5(TQC,6OY;M3Y(/4K]Y*YE?P5V=G55]:VKY^1EVT>:93MQ
+MP^NCU/SF8@%JE@?4JZK4W_'J[RIKG:+Q]6N!F))!UF^H*C54Y0Z5U*8E\:GH
+MD8$_:STBO4;IK`FVG&SE:5*L^.*<4UI'<M24L-XE@[17JOKZLI^]1>PUV]9I
+M1=9YW]J+/WG?*A5)U(HD>HNT&(NLU8JL5454>__SD_<-VN4R:4+79M976RQM
+MFNH:\G9Q'[=JH[C`I8+4EKJ?Q?8/(ZL^C761,-ZOL*U)1(>-P)^8^"&$_PPR
+ML04EE4_\2:M<J^R:G[DAH<N;EKJ.[0L27T'(\A:31TZ[)LC87/8UU[?L!/^_
+M;+'<KJNL4,MD3K1L!]M;;I7BG9['RE2U#=Y&E<6AM667ZR^OOYO^W[5LK[+J
+MZKV5*+85HRKY0V9G2.UY09X&ABSOSWN!C#-],/5B\_/"=S#3#_TD[".INC,Q
+MI'8;V5?'/@]4WP3*\?;^:[^JLO5O1C6?[#IL.WB(K[#P\TIG]#I\\%#+H:;C
+M52QKY!F"O0_FNI@%HFHB:S4[11BFT:T.M=2_$LU56GE+?L.A%JDYJ>R,PP?K
+MWXQ5-SO>NZ'^%?6G]8N]=(\!#0U:%F--90@\=*1NL^JU[Q3[5^QIV2DRN9:&
+M+'^36>?>.I&1J@_=BN^ZZS=Q*8]4,7;7Y]OX,/C/MXWG+CA*8^3SY_G/+_;J
+MF:7^55$7??X\7\/CX?'*\M&'#R[;M@G"AA^=[]D54OMY![]$/U+H1_G>D4X.
+MK67GQ+)MHOTG!BW.H#[Z3/71J7WTQDJ3O!UU</NA;1M4\_G_FX/=]>M9BCS/
+M_Z]I-7\>$77CH><Y*^US<Q1;W-Z>X[[I\<E_^-'_DWN>UMCOBENIW@]9?C8]
+M#QJUBO__:K![E;%185$W2*.N_RQ*WZBS_(VC8?5O)N@&8))K1/TKXV5D',(8
+M#G!%'GOZ+^K%^C=39(Q(#FF2E'H\2,D<Q=K>/^KA3SN/>OC0ZT<](NR%HY[Q
+M_R_UIV*@JX_RT??\T4;1>^O*@MW7B.2NV:9L1!=U:/V3,:>TG2;P043IUS_/
+ME!-;$T/=[$JQQT\(K>HUO.E82*#X]9.":YK"W$DM75,HMW/[]X'NJB,!'>ZD
+MH^IXK3`^S&%7P*FZJJ-UUTZ@K+K^[OW#/_SS3W>24D4^5+Z5#I/W;`_UW9V6
+M.G;QNZM:0E[;$?*B\O\&;.>U@D]#7JQJDR6T$^Z,9MY81>UJKZMJ#7GMVI#7
+M/ACZ:=V4CH"_W'NV=U!Z!Z777;O]Y]"0US*:AW[J/A&P@Z[0<L3?'Z)NU%J7
+M=#0^J:6\MN8:4UDB!R@K'U7-KL[X4^47<^+Y[(U4,)SAF6HOK$HI:RVU4)*K
+M3?F:[.X)6K3DNF,LZ$)6?L5F5E*;\3D]W5-7%:QNUD)]V5(76M-DIMX,>>T$
+M/_-?_,Q[V%FZ@Y_V4WH4=U4['X?QFHF?=C\_[7;W^]N[*+V#C\PP\;(%/^U^
+M]P[JHD\].7GN5'I:NZJ>[GDTOJJE_!Y=(SKK8[?P@XWF1]J%9Y[FKNH4/(!Q
+MO],\<UU26WWN?C6,)A7F.0N=KEM-4[.FFF*TE>>.:[/&%64_?=>'U[ZR9T[=
+MD+MW7?OWK8^GGCG^HVLE/PK^J`C0L$3-+Z7\3RN-_J>S^[)K+$*YH(9\Q3)Q
+MM>9,&JA@H\[;9%,I#4H>>5T2F@7,ZR9OSAG"<=HCZQX(NYP_",?0?;VY[@'^
+MHZZ&$]5BMWO[1]^Y2^R2GK=[;+#LEZL*W6U3(5*YP>S'/&YKD$6'NHQ@"-83
+M_/^R*753PG<'<!15396=OP>3%*S$Z<#Z5VI_.DDJ&5N/-561)M?,FEUV)3]>
+MJ3=F7%.S*ZAN2J1[^/'8PTDD$@][->K+#Q^L*PN7@V_JZ^[CZ^H]UUG'U)5%
+MNOO4*6?/L4UD33;4KVH7!;:#"8YO5F9GRQ4_:'U(C[#]AS#WI\N^[[*9U#<$
+MNEQ7(B!B5:L23&W,4I]L`^M;IC"[B)?M#NC4>Q'X(*,Z=<\@=<OZ-T:PWM,5
+MN>32+?RRAW8PA^(>5NKYLAW]S.+#^N"CG]R_]E[%B:R,JG6DH7]1(S[Z>OA>
+MCQW\:*L2D'+WT%/+=K-O5NXN/=)(/7(XH/EY+E?_RIJ?1$[7UZU3Z5]LKW]E
+M@TJ;^5DP\_<O2$BU*'G0`GEP5,D#_O_G8O8\WZ*,'TT5&/3Y<J^1PUJ*JU>7
+M$E/'`P\?W+U\"UHB\J+_XDMAHR7919@U1[RCB88RVR2Q0>4J-994SPT],5G<
+M.Q5G[5Y^$%EN);&4_T,\!']^X=Y\4%V]P6,7*!E5.7CW\@-:A6+D*M$;H`3Q
+M\<%T?9/R41Q$+0=4+>NU6JI"'>6VW4FA,H/6:@]4%6I9TJ<F*;13TB1WDRXW
+MY*['U,)AJ/*^;OA5>5\3S@@T\;]P^M<6'&CJ0_2[X$"3IF_PG??AK[?[26"F
+M"8&>4KVT*<RTE-H4)@=HA;F5UN;>QE<>'^8M5Y<1%J3>6OUM`9(K>N[RKJ46
+M=>J4."YY;.U6$SY('94TLGQ@EX(?/.E2@X'_7[,C+/Y$^?<:V^@K#$.81_SU
+MYJK!7:]P0DO_P]3T5SBUY<5FNF$-I])8K5/9[LW5R@Y3<U2UJ$_(78>47KQ6
+M%$_6YX?3%+3+5*.YZ%[5YE%^W,I(J]NLGF7S'O6F]I^2KV62V559\U4(1ICY
+M';EB^U_\D4/ZXX_MH:Z)E"^(1F#S*S%LUM]LERI4/.W%WO$D.VU"NE2F.#2:
+M@T]\H)2]"36B\Y5]1/5\\0O5<?SFACHU$_X\Z$I3_@C/2&=/P,WV[1UF\?*Z
+M1O(]T*0`UUGZ&ZC2)ZBTSVWVUVQ3<\(U\5!+\\UVF7H)TH&F)2,UK?V>&_BD
+M+Z7ON547R52LK]LD;&"*G:J6^]&=/JM7-WYEJW"%[8<?;5;<Y(@:/4V=J+[L
+MJOJZG>IZ?M:O#F?8FU=Q05'<:B^QL6N$$PX=T;2YVB!*/+9/^4TWR6OE`R?J
+M'TBE'JE_99^Z85W]/O'3-#_9K+369N6U8Z-#-=?*O+YG;O2HR\.-^%G42*6G
+MNUMU+,?_JC&VHD^R##;NV4<]S29V$U*;WXL]-LVYW3*F<:!IO'KZD'L"`[3G
+M.[A7VDA5T9\WVX_=U*7L`7DL*8.'8F\20S7)M`?^__5YI'EET]&T[=RH#]0C
+M'#X44EL?P!:5="Q>2EGB5+FR^IJ8LKY=2DK6J?]7Q\>X?NX2(3G+08^NO0`9
+M+\?&TV.R3ZFN7LU=N5+D(,E$-3G=&<'B?'%O%B-NCRJY3\WR#C4"5F8%:"RY
+M3\B]Z0$\''B""/<];/Z5F5K5Y1AT2R\*6;G5S!),AA[9-C+L+2&U3U'ZL<UF
+MI3>K#B;*C__+_ZUW#S5]IOJT>:']?_9OR/(:M0)N/]A$XQX=[!KA=>F%++](
+M?703LSFD=@#!XV<U2%_%J[YR77;<K'QRTG-X"?&NSZ7[3_%WT53G?V[#-Y/%
+M6<PU[++&'#_(8TPWA3-\O`)/T&43CIU0!\K5*2GFWKQ1O84#ZBTH[JW-P[=%
+M.@4L'0I'G"NT3KVA9;N5XZN<^E3YO;:QZ#T^3_%#[HJI8K/'*_%8>:94/O07
+MJ9Z/CZ=R*DD5DQX)$$'[GB93M56R.M6YR[NJ[$.5T3V\*V#;0;5PM$'Y#;5E
+MU;&?J#W%J2V;#[%NME)S46U4;(_&BA+U2RZJ4RGQ"E99ZQ0=JFJ4^H>JE)IM
+M!X1++C-Y&)/K%K#8)==H+E.^2TO%Y]H-13M,[=K,RG;+[$/\9AI5'Z\^I2F,
+M_.$FU1_#U&-+G[C.N?ZXM4L].33,"S[W7F!G]Q:KYRV'#FJ:NGHVI7<L.:MK
+M\WKEZOKY,WTNO[@KE1Y]B:9'GT=_L*+M"N]2RE&7TG_$3ZH\PKV\/E/4[AI>
+MIVY=5QY:'[99]"+E(G;U"FTI_U3V<2O]JF9'Y%!UR*_`L>Y/:[X?['*H'09#
+M3_&9C685SJ7VQ-=T!2T]JV9WA/8N-WK>:(U*44[%@][N*/Y,UQW:NZ0B&SP^
+MZY8IAJ>'#,S6'-JJEA&?J\SE3577B;3C,YV0=\W'WCL$:V\\7`JHUWS.Q]YQ
+M%0S7$[B6L*$BZO+`)4[`RLOH6@O:]M4!K6VIN-W3GZFAL+QIZ2#QG]>5A?WY
+MB;#$8_]4OD#FHCS7=P4,QZR7V7[LCB"L!6&>9O-68PQTZI.-WJ$9;YP+ZMVZ
+MKI6%MJYRLQ:`8/T(<^?81UR>+;\9J2WK/N+Y-:.E_:"WDG#VE=>O5,^^0A-:
+MS(?TW?SI3[S,&^->+JL(*[PY+ZGV>.>.=IF:+ZV'-#LUKZ:BCZGL3*VO;C^D
+MVL\;\K?(]\LCEC>51?-GXLHN^B/)'E`66:/6G>-#:AO4T)5I.J]+M>!X)O>5
+M2JKL4Y:K+LM4E]VPO&G)6)Y<ZC;!![41(,U*;0D\I/F.SR@;5%=?`34L1.J5
+M>U[IBKQ[586'6:_H?^S%``Z@61*'-I4-T%YCO,:\9ZN8M;M5A:>V:]+D6+G$
+MBJ(Z571%7UP#&:-T(]VH7?&A;M3*>XU7'5YV#I>:T3+O0^WER7NE8L<O;VB0
+M*CBA)>E#+4\WV&,^U+WS"<?.88'A]UT?;]6]:[\MYT]HJL8O.5?7\/<_T#5\
+MPO'GJ%[/BZCYQ/=%W/JI-F[D=9Q;-L/[.JX['F*4H>?[2L^O?*3G\7%&N3D<
+M@OSX,!]=1^(\#+5Y]!^,VK3]'@XT83_FF7*BN*["TK<K0F:,!">X^J#?!ZK2
+M9G1X;T'>-3G5$[^_K]UXEQ7:3S('1@U7/HO>DJ7<'74JJJ7^R7R=L[+;]Y^(
+MR=>5V7<GCU<6:/)$)LOZ!$>93#-:7K:199F<(/MC_)RWL?=4@$D[F6"E^N[D
+MA+!A$T)3NQ:'SFR9PE\S;/G9&DBI<3/K$J.[]KMW\89^WM*?2LF[)P2K>\HG
+M\G9/L`L)$R+V\H1P<3=%S6RYE!MC"XYZ_N_=$U23=D^0-D^8*$>&*UX@;?5_
+MQL:@4^I9:Y8DF"JCZI+#AB534\M#9[0\H<XJ"O[#FE@6+!N'H]7&X1DMJRV!
+M)O]GI+Q[4CT[V>?#F^1HAH_X6Z9]QU2?*'&%+>U5?2++=:GZ/FGUB<6ND.-7
+M-`S_\"UUXL)5E*8BZK:8K";36V;-;I0T>R"GT=.K?6S:XFY_RAK>=+RT.GZ8
+MJW=U_-RROM6W!@PKZZT"\I9]QV<RY+]*)1T[TOC`A?-L?,8W'Z;T8>4>]\R$
+MN@'+ON:#%AR_N@?\N8M+NR+K9L;A@`6U*<FM/KL<RL<K6/@K`_?-;'F%'EZW
+MF</S;8::B@13U4!W:D)-Y&_5]L3=B>/5ZTB<R(3C_GWB]I_H#-"?F[#5*N?K
+M7U"7'.%.#G<GA[F30]7?P>K_9O5_.SVN57N?VM@S[M68+/4JYLW^]?\*+_HC
+M.2#4U8]&M&I5LFK5\43JRQGV^!FAKE'TAN<'U,T('3;#KO9K79\VHRXUUM`#
+MP7R^N$T^)%#AGC'>/76B.E%0=G^GA?%FND[JWKR:)2DFUP#)"'EM1LKDM):K
+MS8&FO,0\=W)*W8P(]XQ@]7^S^K]=_3_,/2/T3VL@?WF8$WAZ4]LBW3/"ZZI"
+MXZLZ0U;M"'EUQY\'M:T=OM^*F/ZW>NP_K.:R<CGCM-P>\JKIV+T\4Y9$F,H<
+M,UKV!ZE-5KB-I64UX1DMG]'_Z3GJID8.FQIQ?5=Y!#U+:->'Q#R#RRS5?4*/
+MT_\BAS?538UP3PUV3^5&!^S@9G-"J'MJN'LJ?P^UEW3,^:QO+!G/.TN63.QR
+MG>'>H;HS8,;XOMQ=YI!7`WOXIL1])P*P7_\/JSUD^6M\3EQR@+TL135_P(R6
+MOMQ0-0K4_\,4%Z1GI3_K,%PB:>C4)=O=G!B,Y[2JS/!E??A0.CYS/$P_R[>>
+M%+E/:?')D65G>3+^=5(4/!J3EW,-)U:$=B6'_6$-+.M-S0ITG5_3U:OL''U5
+MBT[*5U[QK8E>#73-?K6]ULA[C&?+/?*7L`P^>#:T=!!1ZH1A,T+35)WG2"NH
+M?T=QH6GF8=/LKK$\2P/4"8EE'>ZJSJXR^D\=3I6FC5@:KF?P<$5;^O'WR-TS
+MQ[NG3:R;:7;/M'-X?:NN3<M:61_2-2N(FY41QKIYD'M;)57RQPZSZYP_=MA=
+MX;N7,Y9P7N'6XLA4GT0*B[\^M,3ZQY@`N^M,7KRY/4`-NN5-(<NG!YJ$U=+[
+MO&1&RY@`'G@8^^J/\.Z30ZT/JMNYPD+NN4LI;0P#76/4>?ZJZ^S#Z*$^<?^Y
+MO6OPT++@@55R,@X-PEXU2R>2+O01SJI?-#Z`>/FBB7W+0ID)\[5+X^HSUO(1
+MD'4S8_A(4-ZVNOQ?5#ZO+F-]WK*O36UYRTZ8JD.6WZOJV!\PA?>1]IT2JAY$
+MW6()WV*KQ,O6+.7-'2_RV)T0$!"R_$ETB]IL-&S1^+-OG>@NJW97U?*WH_@]
+M!Z/=[LW%O)%AFXOW')95UU75!JF4,U6*7%-356NJG%&G4N*K:I=>1P8Q_SFE
+MMHPD/)>.+ZM>?(7JD@CWS&`EB:J#ID7P%X9GTON7]##WS%#U1[A\0?+8^?)>
+MB-T,HS[_],\OW:>D3=+2JNH+^/L.*^JFU%XP)=0]965=V0IWV8JZLI7NLI5X
+MLK(59U<1;'!7-?I[(#2Y<6E_K<F-91=J36XH'U0G-Z@*=5>MW)W4(&.JT3.F
+MXGA?Q\JNLA77RPA/6NW.6,-<N6J-J:JO&N)J^\BQ64HQKJEJ,)7UJZEJ-)4%
+M[UY>T855DSGJ&9G14<<,FT:\;G'$3,7KW*J0>Y<TO,U]@G<59S0NM95%QR<U
+ME%]<5T4/1L_9Z*X*)66=;^6R#DT*'I@1ZIT+QXM56R/<UZOS/LL:@A9%N!>I
+M,ZK5)4&W1KAOE0)AO'&&_PBOVZSNW*W#JE8';5/PUO%U56LP"&Z=6'/>S_+.
+MCB_"^4;K6.-0?=2UF5LB4L?03U6KF1M7K:$V\Z"]Z&<U+E:[IXVOF[)&<00U
+M6/C_9O7_[L-D=5W&FOHGV7_B__S5C]L#U+G=9:$S^*#MKD4)+=^07B5[J8@7
+M]:ZK896E)L[L^H)W3G4_<^4!KB&##X?2CBKI*DEH>9"5L^[GOW#9)#NO#A<G
+MM,SW6V8<RE"!@9T!GC-]?,X_Y4)30I?O73**CZ2B?NE:G,"[;_MHC:^;TLG?
+M('(,_2`@(_CX)YKN57.EV;6W.B1R*/C`1%/E6?3P\AY_=?]%-07,'-^7^C8I
+MU.<;O?I]8H_])MV6Q#$!6-8F5C^`U)8@CK#?,[2COC@`6V:.CU);RL*'E835
+M!5YHZF4R7<W_*QM<5Q)):;Q1FOLNX*_XO\I[-TRJCN_E>BO^K\5_+/_#E1Q?
+MUED:5%?667,JK/PL>D7<,6$M^W\/8`TWX,_C$0WJN):P^N0N=U+K\J;*WG?;
+M5@1,&-,UI?76WRDKH"1L:%EG75)G4%*'*W<^;R1MN41=;6<!.9U5P(F1PR9&
+MU/RUM)R>IW/XAW_^XLYHY_T^LDI?UCFLK'W&3+YPTA\>R3JH+JE=MJ2$IM:;
+MKU&[+,>2)C,TB6X6.BRI4[^WK*8U1]=W<W\5N5FS50TLD\M<9R+]G)3NRC"2
+MC_5):U-GJB-BQ(_3>W?2&L4%(AL:\NJ2UN==2)S]:E.D=ER/.VE-7=D1=9()
+MGSXZH^7O=AD"YN4?:KI-C+(]Z\W]4]-FMOSK+WY\Q8)<_6C8M`32,.-C*Y>%
+M\)?8\>W.!MU\\>[__B5`=Q;4KW_[&[\UAC*[_);)5&4,9V"M^CN@^_E5HU4Y
+M>TNQIQ9C>P:H?/E^J[_K_VQ3/*8ZWE0UI.Z!:'8B74D*;D-\+V*H8V+=@<=[
+M-]3UJ]D12\EE/RP[;ZGQ3$Y//2^VJ3E>?:6ILG]UK^JZ&JZJSN0>&RM_ND,]
+MSZB.\+$/2PVN2XRA3@UIB$^U5P514AU/D%_E-$(IMRRRBVW;B71!M#O5[IX8
+M73<QN"XURIT:[)X854?_3S5KWX);9C=Q8'V/9>U:6=WW#WX6M93UP]#2<+83
+MNF:HH48:%[YS>J6R+P)<O>J2AY#BR4::9KK05?;2(*6SABFU%*;-LHNZ_NSJ
+MZN&LSSOEGJI.TMO#Y%#2KO*HEJMIU.].CA*S/%K($)-QK[.GFFM_#NCI_"[C
+M_OO^/\L`J3FE=L;ST]J')0</[>!0I>1H>O?#QO!*?GQ29\@]3TFH48Y\@:>F
+M*2>UY7T:0.ZD=J7FE9VA^N18H/BHEG=5Q=:5M=?LRG&?H'J"KH]V=_QY,#5M
+M1DO:+XK[##W%^RFU6Y(F3>.P[?B9?!+$CAQW!U\SAI(Z4]-:(N4*Q7&C^.ON
+MU"'1OW!7J2V_BZ+<;<2?@I(ZW6.BC\]I:"#^X4[JH!:,4O=$9=&I=51H3%1J
+M2W4'C\<.JB]H1M30$]0"]:34B$7!QP>Q'M%I6A+N*>'N"$I&2QZ4&5%7UA%$
+M=UTTA+2Y823VQ_!8[=4P%,/T3WZ]1_V<V?74C]K[M;OZS&A9>=)S-.RU.MOM
+M^/0&C*O^,UI"<1*J9%M"WC(=CZU9$F/BO&@Y>97N'2[CD=O./41C9YUV'3LP
+MS%W[_8ZW_L;V='9ZVC-.UYZN9//Q=-6>03-:JCOU[7%0>SC[B@:M3:M/]MRF
+M4'V;$@UMT@W*9:V:/<@&@^N,/ZP!9?3*(UKB:;2ZET2PU$R.Y`4^E[7FHE/'
+MS0W5?0+\GY$VJC7`8WA<Q"9<7[EWN'+H\$0.G6^J3TY-K4^>ECJCQ=5E.`-W
+MBW@P?,]_.PZ^@([EWNJC/@FH>D)]O]G73Z&W^YXX+K(_@S_+Q3*&A+Y;V^,/
+M.;_\CR73=:)[R2`2W:0CE82UG/431+<(Y^-#E_^QU#S\C^/G08[/Z')G="S_
+MT"O'.Y0<=T]F.:X^:S,HY%5;Z@2>]7O_%F\D/8"E:TKG\6I-].K.^?8T^_@/
+M`:<[R\_G^R=<6#T@/2F>2XY]\7TN]5CFF2U7_ZA_+K//<YEUSQ6PPC9F@O>Y
+MS-ISJ2^AW>,9P65W&Y]&SL.H&VN.'VLOZU,W-BQ^;&@9SJW07K1Q'/YU3!N'
+M\JZC/(,&OJ`;EW?Q:6.A9'-4]PGT#B3^7&5#S44GY_/)30$=J?Q-D)/L?`H7
+MOBT^S63Q:2:+HU..'-Z=K,QJ9A]^S\W..Q;@]WR]./_GZXVFXNI,]9:+6CU*
+MC6L@J3)W<&JJ^@+"4NHR.8I:SC[RGN4I_KUE[YA,S__M#MV=&*&:F!@I1!P`
+MB=)N.?08Q]5@XSV..]Z=&"M$A%?B$"$BPQ)C<+Y-BDF^B\TOQ.?\ZQ;/'':=
+MR[Q@(/."2X^S/)2F)$>(6Y@8"_/A/@UHE>+%ORGFTX]%QE\_>&2H<N?V_=,[
+MW3WS_0WO6/">?_A]`(XP4N,GN+1?W,2NLC.Z)IOQ>1[6@\;&79]6EQCA[_S"
+M%W&]NKCD#"HZOTO*'G=0)91.S,/0[WG4\7EC\]RI*9K_E&]>%EH?UB?^G?(S
+MW?L;)E=?V:O,.G3_Q..]&N+?6=Q&%P60..WTG;<CY=YY-;>EF#1]-IQYS=BP
+M86-#R=@*#7EM;,K$U):'#.]>?_[W=P$<0R5*6PQ9%1=!)QJ@TXD4&RFSO*U&
+M4'DLZ=.?>9W%1O\O5:>K[!R1=8&N,PRU21W?]?`=]UN,=0SF.HB[AW(5IODF
+M.9*3-095RU%_<^-LJJ+E3&IMRQ.>!_>9_]\&8/.X>[%9B4CKC)9#OW=U*5'8
+MNVZ&>=@,.4-=_1G,]G-RC-OF7A)C]/LIMFFNV1'#VG-_*A\?6,8?S0MDWD/Z
+M,RG//^K+9I#R:Q\VUJX[QX?/KH=/CRZB`:/.&>M=-]$\;"+:P'\&N_?4I=F'
+M[L"AW3[?__Y6XV?QB\TN\+#+:Y;:397]U"/1XSW13GTQ(_AXJ-(_RBAEJTJQ
+M!\VTNV>8=8Q)WY?O'U6RH:8BA@\[E#FMSD2SIK9$_&ZP"0S3*(@&/Z\N!->E
+MF4/>"HS?XPI<T0M3RN^WW/*.RBN98(Z?$!QRQS-\GZ5TG[/8Z5;FF-G2IUWX
+M/R66#<WG[8@MP[X/$#^DZQKWA"@+I[DG1+LG#)G9<N0W"4J1^DINKIMF'S:-
+M#Q0+V.N>TGE]2]MW.O46<X>_::6,VHZ@LG;VOO(GQ99^IZ07_=W2R$-S2KM[
+M&H^:H"F=[FG<7+I=US1S355PERNT;J9ZV*1@EX4_$-:+LFGZZ[ZSY\N']'J(
+M_N_NO#+Y&_6*:<SW>PM?%ZBKB5'&5M?^&2V1WVE=<<SON;^V;\0<:/C6O[WX
+M_=?"Q^I4E0&DO%CK'HAE`ZZO*C[#6>(JRRJ(7)B[L*CDULC<BNS<W)S<G$AG
+M8>2<PMS%%_?RJ>\AJF_^^?4U">><ZDJ=']ARD*34_*Z66XE/-_@[;W[>UP$X
+MYXP&UC!=(WLXGW[TU_(\+4>]18O+2G(CRST-=>47Y41F9Q44Y.;T,I[__16U
+MY>SZFB-H6X*T[?`Q7=OX%SO0RK(T,0XT`301=#SH1-`4T%F@LT'G@.:`YH,6
+M@!:#/O&KQ?2+V13]+-$VHB\3I2D<_0;1@Q93]`ZBEP>9HG/:+*:?S::(=P@_
+M2OD?$IT=:(K.I_1V2O^,\-F4_C71Q93^`]$\DRGZ5Z*WV$S1)X@^3SCP-XMI
+M)MVG@*Y;93)%%!/-#C!%N(C>3;07Y6=3?C^BQZE\!:6?3?4/(EQE-457$FZD
+MZZJ)-CA,$;5$YQ)=0?13BRGB?"HWE]I["5$2Y]$CB)X;8(J^DFB$PQ0]EF@6
+MY:^D\G:K*:*!Z.]V4\1D2L^A]J<1?97HC43G4_E&RG^'VC67\$_4'ZL)Y]!U
+M:XA.I/O.I_0SJ7P)T6>H?;<1?8?H'7P_NL]:*G>8KE]'M)GH>J*[B&X@.IN*
+M;"2:1/5M8DK/=3===S[UW_U$7Z=Z'R'Z$N$ME&\*-$5L)7HFW?<)2G=0^K-$
+M>Q%]F>@>ZN<WB-Y#U^T@2E=$OT-T"O5G$UUW)]UO)]'O@TP1>XC>3_7L(WH;
+MU;N?Z&!JUX=4?A4]]P'"O_)[)5Q#]7Q-]#.B!_DZ:N\/A-^B^_U*]"+JWQ-$
+MHZ@=S90_ANX3V&XQT;2.[D4TG^KK1_1QZK]!1"=0_YQ/=!C1(U3^.-5W">%O
+MJ=U'"3]&U[<0S:1VC:#TUZF>*XF^3^7'$GV/VC&9:"K1-*Z'VM%*Y8NHGC:B
+M6?0<[43'4W_>2/G+Z;JY1-^A<AT\?NCY.XE^3=3T"_4+W<=,-)G*VXF>23B8
+M:`/EAQ+M3S2,Z#74'_.IGGIZWA*BVZE=MQ$]C^J]@^A3U/Z[B5KI?O<3G4KY
+MCQ#]D_*?(/H'T7"JYT<:;\]R^ZF>EXE>2^_G#2Y/XV4'T9.$WR&ZF?KK0Z(%
+M5.]G1+^D>K\F>@==%T'U/$K]]`/A`U3N5Z++^#T0C:?K`W^WF&[D_B?Z'=7;
+MC^@-A`<1_2?5=S[1]=2>2XC^3G0$T7E4[DJB;]#U8XE&4OG)1.^E]Q=)]WN+
+M[A=%]`GJIR%$_TW]'4WTA,T4D4;EKJ!VQ!">2>5N)'PS73^7Z`&J/Y;2KZ7R
+M<42?H?P$HA.I'Q*)!E!_SZ=R:73]>,*'J%P)X7"Z?B+A=NK_%*(;Z;ZW4?HD
+M>LY4PJ7T/M*)#J;T641743VSB=83G4,TD>Z3P_<EFD_T`(V+`J(?$;V#ZBFA
+M^Q7S>Z5\%]&KB580_9#R*XE^0+2::`>EUQ+=3W@%T6*:-W?3]1TT_NXG^@.]
+MEY647D']\`CA<=3N)XC>3OW9\(N:-Q&-1#^A>E83_8V>>PW1&82?I7)O,M\E
+M.I+J>8,QSU_N#^KWM53.1<^_CNC/]%SKB:ZEZS8036#^0;07]<,FHDU$MQ#]
+MF]+?H>L74/NV$AY)UWU(^'["383-=/_/"$]C?DTTA_DUT>-$?^7Q0.TX0?1C
+MPH%_$/^G_NY%-)#>8S^BEQ$>1'0+E=M)]0VC^^TA^CGUS_E<GI[G$J*#B(X@
+M>B_/7Z+O\;@B:B$ZF>@"ZI\THJ\0O9'H2'K>N42S"<\GFD?OIX3HA]3.VX@N
+MIO0[B"XB>C?13J+W$PTB^@C1$J)/\'V(/DOT<6KORT0+J-Y]W#_4#V\0OH_P
+M#J+1S!^)%K,\(UI$Z9\1'<S]0K20Z`]$W92^GZZ_BI[S5\)?4?H!PL_3>SE(
+M-(7&ZPE*SZ<J`_^D?J#\7D3)CHSN1_0HX4%$K^!Y1W0HE6NFZPKINB-$'R1Z
+ME&@TC:L6'F_T'B^A<GNY_XC>3OW7RN.8WEL;T2LHOYWH$.KO#J+-U(XKJ=R#
+M=+^Q1-^@Y^ZD])4T[DPD=U=1.3/1B40G4_Y_Z%9VPJUTWS3"?]-]@@EOI/X)
+M)5I$][F1TJU4SURBWQ"=3W0<M3^,\A/H?N%$WZ#R)92>1?T303B?\&V$-U+Y
+M2,+?T?WO()S'?)&?A]+O)WH>E8^B_$`J/X3H=FK7(Y1>2^E/\/U8'R$ZG9[G
+M9:*DET>_0;2&^F$'T:TT_J+INEAJ1PS1HW2?6-9CJ-UQ1'\E^@Z5.T#E/R1Z
+M$]WW,Z)[F'\2_8KP#T1367X1S:3^.$%T,>%`FNP;B/8BNH#:G4#U74FOLA_A
+MM803";])]QM$N)#:>S[1(]2^2XC6T?U&$'V-QSO1*AJ'8XEVT7TG$SV'[I-&
+M]'K*'T_U7$7]?R/AGYA/$B4=.WH^T2S6)XC64/VW$9W+^@31WMR/1&]B_8#H
+M'93^"-%L2G^"Z)5$)U*]6^CY4XC>Q7*F0[V'Z)>)=M!U;Q"U4__N(-I&U[]#
+M]`JB'Q(=0OF?$;V?VODUT5E$?R`ZG/D"T8M9OA!=3S3P+XOI7;HNE>[S`[W'
+M7H3'$NY'M(#H(**9=)_SB?Y%UU]"M!>U;P31F2QGB#Y`^>ET?3;UYUC".ZC>
+M680?H'DPF^AU1.<0O9MH#M$<&O?Y1,?1^YC,]V=]C>@S]+YN)#J:^0?1NZC=
+M\XE>3.DE1!=R/Q+]F^4TT6^)WDWT"+6S@.I[EL;1_81+J-PC1,,HO9CO0^UR
+M$1U+]`E*OX+Y"M$KJ=T5E%[`<H+H"+K^94H/H>O?(-K)>C/1X=2^=XC.H_M]
+M2/1&>K[/B*ZF]&JZKI;>3RW1&J)?4WHV7?\#T1RBOQ*]B,J=(-K%\OP$M9OJ
+M[47T-JJG']&M+,^)CB%Z/M$+N)^)VEF>$YW)>B_1`90^ENAF'H=$0XBF$3U%
+M]=U(]'P:'W.)GD'W74'MR:#^G4]X,#UO"9=G/8>O9_Y+="!==S?15WD<$KV)
+M^2_12ZB>)XA^0NU^ENBE5-_+1(=QOQ`MY7[A^U#^2KK/)'JO[Q"^D)ZO@?!+
+MU)^-_-Z)[N?G,)G&-Y(P<YI-P;5$*QVF8!?1*0&FX`*B5YA,P3E$&PG/)GHS
+MY:<3=1%-(5IH,P6/)]J?RB40+:7T6*(/4/GHO]7[#HXBNI#*11#]B6@8T3.M
+MIN!@HB<MIF`ST8\(=U)[$NRFX/83:GP%MQ(-H/*SJ1.+J'WI1"\DG$*TD/!X
+MHN=2_0E$;Z'RL43?H^NCB<[F^Q*]F'#$*6EGV"EI9_`I]=Z#S:?4^`[NI$:T
+M!=)]B<[C^Q(]AZX_2G0"W:?YI+3S`/WO0VKG/J+/43T[B:ZAZ[<2W4!X`]'Y
+ME+^.Z&/T_&N(+B#<>%+:N?*DM+/VI+2S\J2TTW52VEEP4MJ9<U+:.?NDM#/]
+MI+0S!>T<CW8FH)VQ1+/I/M%H9Q3:&8%VAJ&=P42=W,\T>8*)MA,=1NUL)=J;
+M\-%.:6=SI[3S0*>T<U^GM'-GI[1S:Z>T<U.GM'-#I[1S7:>T<TVGM+.Q4]JY
+MLE/:64O41O>I[)1VNCJEG06=TLZ<3FGG;*)G4'H*WY_:-YYH+=$$HN\3C44[
+MH]'.*+0S`NT,0SN#T4XSVMGYM[2S_6]I9^O?TLZC?TL[F_^6=AX@NH_NLP_C
+M<^??TLZM?TL[-_TM[=S`]5"YX"[23RC=W"7MZL1X;,=X;,5X/(KQV(SQ>`#C
+M<1_10=2.G43'4GU;>9Q3N4U$IW+_$OT/T75$_TUT#=%R*M=(]`-JU\I3TJY:
+MHE.(5A+=R>71GC5=TI[&+FG/RBYI3VV7M*>R2]KCZI+V%'1)/^5T23_-[I+V
+MI'?)/$[IDGX:3_1LGG]=TD^Q1/?S..R2]D01_0>_%Z*#J-Q6HA?P>"(:3/5T
+M$OV+GJ.=:#8]?RO1N42C3,IO,CZ"Z'F$PT"#01.(-A)=270>CS>B3Q/>0'07
+MW7]\@-4TBN<'T47<?J+/\C@C.H6?GZB5\M<0C:/TU42#J'V-1$<3;B!Z&=='
+M-)#2UQ/=RN.;:#2EKR5ZC-I]D&@YX0-$RXAN(?HONKZ5Z%.$.[D^?IY`/$\@
+MG@<T&#21Z#RZ3R71F80K+%;3]=2^8J*S@TS!^41'\?NU2CV5H"[0`M`<T-F@
+MZ:`IH.-!$T!C0:-!HT`C0,-`@T'-H)T6H>V@K:!'09M!#X#N`]T)NA5T$^@&
+MT'6@:T`;M?KLJ`]T'^A.T*V@FT`W@*X#70/:"+H2M!:T$M0%6@":`SH;-!TT
+M!70\:`)H+&@T:!1H!&@8:#"H&;33AOX$;04]"MH,>@!T'^A.T*V@FT`W@*X#
+M70/:"+H2M!:T$M0%6@":`SH;-!TT!70\:`)H+&@T:!1H!&@8:#"H&;03XZH=
+MM!7T*&@SZ`'0?:`[0;>";@+=`+I.H\%"UX*N`5T-V@C:`+H2=`5H+6@U:"5H
+M!:@+M!BT`#0?='QOH8F@":!QH+&@,:#1H$-`HT`C02-`PT'#0$-!@T'MH"F]
+MK&RG!H?V0G\[A':`MH.V@;:";@7=`KH)="/H!M#UH.M`UX*N`5VM74]"?1'Q
+M_8U$"TBO:CH#Z7VL2DYM(,IR:AU1EE-KB+*<:B3*<FHE4993M4193E4293GE
+M(LIRJH`HRZD<OI[U1J(LI]*)_D+W2R'*<FH\YQ.?3B#*<BJ6KZ?RT42/4[D(
+MHA-9/R4ZE/DXM?,ZED]$RXCOIY-RS_IQ"E'6C\<39?TX@2CKQ[%$63^.#I'V
+M1H5(>R.(LGX<1I3UXV"BK!^;B;)<[:3[L7[<3I3UXU:T]RA1UH^;B;)^?(`H
+MZ\?[B+)^O)6N#R&Z@>CU)"_6$,V@^E<2_8JN.T+T6[KN(-''Z;K]1!\FVD0T
+MC_45;C<]WYQ0J^ER*C^;Z&XJ/RL4\Y[H<.J75*+W4_TI1(\0G8C\\<")1,E.
+M"4Y`>AQ1LE.#8XF>2_>+(1I!]403);LU>`C1OU@^HGPDZ$:T8P/:L9ZHD_49
+MM&,MVK$&]UU-M)#'"7`#VK&2,5VW`NVH13NJT8Y*M*,"[7`1'477%:,=YK[2
+M#E-?:4<GI9/=%]Q!=`S;"T3)3@QN([J'WQ?1*Z@=+43)+@P^RO73_8Z@'<U$
+MJ:N##Q+=RGH#4;(G@_>C'?N(DAT:O(?H`-8'B9(]&1Q)]_^;QVM?T1=R0&>#
+MMO6SFM[A^_23>72PG\RC_?UD'NWI)_.HJ9_,HRW]9%QN["?C<GT_F4=K^\D\
+M6MU/YE%#/QF7*_K)/*HF.I]H13\9E\5$]U&[\OO)/)I#E/7B6439'II(]`:Z
+M/K&?S).X?C)/8OK)/!G23^9))-H3CO:$]I-Y8N\G\\343^9)1U]I3UM?F2<M
+M1`_0\Q_I*^TYV%?FR?Z^,D_V])5YTM17YLE&O,\-?<&W0->!K@5=`[H:M!&T
+M`70EZ`K06M!JT$K0"E`7:+%V/4WN8GJ>%43O9CV<Z`-$YR!]-M%QU.YTHM<Q
+M/T%Z#,I'$QU,_60GFD/CQ8S\36=9>4/B^(U$#_%S$GV6QG,CT1^HGQJ0/POY
+MZ<A/0'X<\DW([PR3_*-ADG\D3/+7$XWE>48T@^T[I*<C/0'I<4@W(;WE3$EW
+M]:?G8'[=7\9%#M$V2I]-=";S:Z(M;&?TEW$QOK^,BX3^,BYBB?Y"Y:/[R[B(
+MZB_C(H)H%MOY1+>Q_==?QH6YOXR+SK-D7+03#>+Y>I:,BV:B"ZE]^XA:B'9R
+M>>;W1#\EW$ST-;9;B*:Q'4@TG>WZ`33.V0XA>A[KYT2?H?*51-/9KB?:3O47
+M#)#GR!D@SS&;Z*^$TXFN9WY*]#=^3J+WT_M,(/H<U1M+]!'*CR9Z.3\GT?^R
+M74_T6;8CB-Y'Y8/YOH1#!\KX#AXH_,H^4/B5>:#P*]-`X5>=X5;V<P5WA`N_
+M:@\7?M46+ORJ-5SX54NX\*NCX<*OCH0+OVH.%WYU,%SXU8%PX5?[P\&OZ#[7
+M47V7\`<7+";3OXA>&60R9=!@^-UF,@T@7!1(Z0$FTZ]$>8W_4Z+UZK/C)M-:
+M2E]HYL^6F$S_H'3B;:8/Z#JR;?GY3,6$^:B4RZCL16;>6V%B/F3B$Q9X"7</
+M_7N'\'"Z]@%*XZ^7%E':AX&R_G\A3T+"*72?KRC_)4HOHS0^SOMLPC;*JZ-_
+MW_.7(J@1(^CO50Z3*9_R!M'?$RC]/KKF2Z+T'DP#*/US^L<?XJRF>OY)-)OP
+M3/IW)Y4_Q%O,J!R'OCU$]'FKM&,BW3^>RG,H*=FSIFA\7_HO^O<8E:D@W(N?
+MUR'I%^&Z7TSR[!=2_K=TW0U$\^@^'=368"I[!N574CK'\MU!]7/8WZN$QU&Y
+M,ZD<G\UX.UW?G_"[W'[ZUYOZ,P/Q$87T[P%*^R^WE3=8$"6[WK2.TLFNY340
+M7O\S':3K6ZB>%53F,JKW.I.\`XX%BB<ZD.@]1,U4;@;1LX@^1'0574ORU\2'
+M>$\@_`_ZET#XE$WNSZ$J*ZB^G42'F^5>S91W,U,JNXFNNX'H=BK+6_UZ49D7
+MJ'V/4#I_H^\%2G^3\&_T=SRWB_ZNINM_YWXANHWH)AY7?(@)OSL\-[_3PY2_
+MF>KYDM)'X7U\0_5/IWJRN3^I#(<J$O]@'Y_I)@M_EDC*#4$];V*<74G_.BDO
+MFD_\H_*7$GV4_IU)^3]:^!MOLMN-MPQMH7*KZ>\RRN.#P%=2_A^47L!]PI_^
+MI?Q;B(X-4M!42'01Y5]`]<ZD?_7T[S6JFU@3QRR8_@[RUE]*?W]/>5/I[Y>(
+MCJ'K)E+]$RG]9Z+KT?[WZ.\E=+^]=/U0JF<CI6TP>^OYD?XM(IQ.Y?<2?9[J
+M>83G!-%TNO8CO+^AA%^C.GZEM(<HC;^S%$KE[Z7T<XCFT[^/^1]=.YG*N"G]
+M<[.,>37.";]"Z>]2_@A*NXVO)WQ5@.RV[T=U[Z&Q?B[1)BHS5NMW^O<TY:^Q
+M"_X/_9M'F+]L>AO13+.D+Z5_/]&U@ZF^)RU\^K/)E$7WN8?H9"I30G5:"#](
+M-(#J.D9EKZ-RE92_CM)*B%Y`=`Z5X=//'B9<3F7X@*M.'A_T[P!=-XNN^9+^
+M/<=;_(F>X&`@NN9J]--(^K>'RF;RO"'Z#95QTG5\$$,'U7\NQRH1C:'K+J3K
+M7J0R<^COGRDMG\KRZ7_\N6;^KO-NHKP/[3^!,N8>H/QD2G^9QQ//-:KW4OI[
+M".7=1?A2RN?C;,<0C@5_X<\#,,_B<]N"^+[HU]OI7PF574"T@M)?HW]Q=/U"
+MPE64OH;^#J?ZXSG$C/*>H>O'$5U"_X[0LQ9Q_U,>'Q<:2/?^DM\?Y?U)Z=<1
+MW477GT_EJ@/D63G-0C2`\`<L%P@?I3)\*'@&E?LWQNN%E/<)_;TN0'@(G\!_
+M$5$^-G%1H'?<]J5_WQ,>0;0@4/)V47_R]X3Y2.[#)FG30SQ7F+_1LVR@?R[F
+MQ?P>F&]1>]XEVDB8;!'3&43Y@]DC^#O91*\-$A[[,M%Q1).I_C_X0]S4[MYT
+M[2P^2)2NW\=]C_&Y@,I-"9)WUD7E^=BMU^GO?U*YOI1^B/Y>0N4G\[,2Y@]"
+MLPRZB=(W$'5SW]-U^XF:J=S?=*__4MV\I?EQOB?S9VX'X<U4AH\8^H32$P@_
+M3#B490Z_)\*?$?V8`["9QV(>IO*GBJG=`[D=5/<`PFNHW!E$IQ'EXQHV<G]1
+MG==0N?64/ICY/*4?I+2CE$>J._MV32<H/8_R=P2R0DASB?(OXOG)LH7KLXD,
+M^YC^-?")&50^G,<SE3N?GFDL_9M'>`ZEOT%IU53N8GX/=!T?:;:,ZLG&.+Z:
+MROW,\HO*#*;[[^//MA+^#Z67T_6S"2^DO&_XV:G>.80'F:5/>&Y]'"B\9RF5
+M'TKI5V&^\NY(TH=-OZ!_^%T]1IB_AUP=*#*#><*[5/=FNQRFN4W'A[^A^B;Q
+MV*:_>Q.])$C:P!]@MQ&]BM+?I\P(PKP-_@:.A>6^Q_VF0Z[4!0CO?HYH,Z4M
+M,\L]U]#?5UJ]]SN.^<LZS:4V&8L)5@X0I+YC'L(?Q"/*'T%Y.U!T$/Z=3^7B
+M>&&0ZK=3W6.MTH9@PB&$^5/T-4&R;W(0T6-$'R;Z3H",!7ZG+'M'<'FBIZC.
+MFXE>Q^.)\O@3V'_1/?@CG.V$7V1=@>J/H+]_HO1THO,('PK@114:%X2OH73^
+MR'L2\P!*_XS2/N6/'!&-XG'"IX;RL0A4[BC+3<)WT[4QA*OI[_?I;_Z.SV]4
+M/H?^S6?91W@SZPC\#1%*XP_YL.PC'=_T7^JO$,(Y=/UL],OM+*>IGDGT]P&Z
+M;AOA5L)SZ>\LHINI[#-V>7<L.UC<#*'_\2[D!813*/U-HCMX'+-LX&UWA/]B
+M/9CH]<SWN0ZB]W,;Z=HLPH,(K^=Q0/^*S,)SK41K*7T77=>$\1%'_YR4]P7K
+M4)3^+-5[#>4-X78SKV,^1=?=C7'!G\!E67<F_9U+^6?S^3.4_P/S2:(GB4XQ
+MBXZ[B^><273"7[@.FFNO<)^P_D7_^ICY@PTFML=-8TS2UK.H[@^I'V]E?9'H
+MXP'"T_KP_"/Z`OU[E9[O)QZ35-^M5#Z5,-E@IKE$QV/>-=#?N53F'W3][W2?
+MH3SFJ<P"_@JZ6<9N".L]5-9!9?G[MV<3?9HH?RR!SWMXD=\;E0_E?@Z0>_`G
+MZ5F6\=Q-I?R+`T17&T/_(NCZ^^FZ:RB_-D#FQ`FBSP0)S_]!-Z_/H.MG$>9#
+MJ)D7\TE@E=2>4I/(JCD!_&T`>8>Y5#<?EL!?H;X`^LAAC*_Q1#,H[7[>3TYT
+M'*5]P7.-_HZB^Q>P?D-X.5$^-RB.RMUJ$1ZKXO=9UCJ$E_U)__I"SM2:Q89*
+MH/S7Z-^+Z-='Z-]BYAGT[RK6:ZC,':Q'LCU%:?P1L;V4MH)HI.YYGZ5_=[+=
+MQ+H4E;N0Z%2V`XBVLL[$^BO=,Y+N<Q>UH8`2XBB]#U$KST6BR42?L$@[R@A_
+MS_HNGN,S^G<#77]%D-AJ_#50-_T]B^4:'_?!6^\#Q?:YE>YQATET@WELV]A%
+MAO./;%X3?^8[AJZ?3O64LWQG>X+P2RP+^=W1/3\/D+''8_<1RN?CJ-YA&<"V
+M%NNZ//^L(BL'TCT6<TPZZ^2X#Q\<\A[]7<QZ#I7A[4I\+,DVZ"FI)HQUYMM4
+MOXW^OCQ(YLS?+'<HW4ET-[\KRKL1XV(4RQZZWP.4/Y#*7X/[W89ZI_&G.G7O
+M)0KONR-0=.OQ=/TS;+_!CN$C=KZC,C?SMY!8=M&_6K8KP`\N@$["P^-WHF&4
+MY]#)$Q[C;&N-I;PGS?(QQ1_H;SZWZ&NSZ(PSB?Z7_B51N^>S;LOOF_)GTWV'
+MLKY$>;S=^!OF&R;A[;E!8F/]Q'M(Z.^S><X'BDZ[DO!TYG.LXU!;<MC>,0EO
+M6,_/3]?=%B"\DG<[KV7^3O>JI'\\G+@-R]$ON<S/V?[DOF(]%_VX@?Z=2W]7
+M85Y,L,B]YE+Y%(OH:`?,PCOY=Q[1ZZGL/93_3[;/*9_/0.-#_=L(\UE?G[).
+MQ-_^X[-9F7\$B4U]*Z7OI'^]:9Y>2ODK*/UW;@?K;0%B2_;A=T!EOF#;AJY_
+MAOT1_-R4OU3W/E9#I[L9[W<UT2<(I]/?HWG^F,3F81ZXFO5^MNOLWNMY+CY&
+M=?-)/<S3;PH07C2#]6=*+V7[@NY71?15]LM0VE:Z?B6E#20ZDLJ^0NFCV1YE
+M/PY_8XS[@^T\'BM\#>$TS/,Z]@>PCL6`TF[D,<6;&JG<2?KW)%V739CW&?Y(
+ME#<AOD+E[V-^1_G\Q2`KU1>+]UD%VY:WMS]#Y1("I2_9IW`WCS\>\T$<H&GB
+MN%3E&_C#++HR_QH#Q)9?AO>>QOX1GF<!,@<WTM\OLC[*[\DA,O>(6?IB/?L$
+MT([/J,QO5`=_0_=1]J6P?\$BNO(E5([/A5M%]!"5OY?JX2\K5A$^B_DN4=YZ
+M&4YESV&^26F7$<UG'F&2.1Q/]$'"*41O9?V$=5RV`_CFK'MP/]#]YC(_9[\`
+MZYU4KH+H<RP_3.)S><`DMNP_V,_&M@/;<T0?-<G8X./J5Q!]W"2V!7_<YDZB
+M3X`_O,SZ.OM?F/^RG\0DOH`M1$]Q__(\HO?S!L\I/@6/91+;Z,P?J1Q_1_L)
+MUB5,HAOL,8FN_1[1Y]D.X//WB'Y@$EV6/Y1R.ST_G\N73<]W`&.>C\OL3[C9
+M)#SL"-&3A+_F?F=>PO*5\+<FD77?L?U'Z;Q/B&W?8T13B+;BN?A+P.S#^XWM
+M$J)\MLLZMEG81B?\-\M*MJLYG<<RO<_O*-T>(.^^-_L1V)[B><AR-T!X)W]M
+M<P;[>XCV)SHP0.9$9(#XB,XC^BCA\XEN97V`Z&WL4V"_$I4?QGHUVXO,ARC_
+M,M;7"%].=`_1X>QW(3HR0'P#HP/$EWDEVT]LYW%Y>OYKB:;1]8E$VYBG\/VH
+M7!+14KI?,MOE]!R3`T1V3"%Z"Y6;RL])Z=-9+V2^$B`^N1M9[R5Z2X#P^DRB
+M[[/]Q?.?QG@.RVNB^>P/H7PGT2;V%Q#]-Y4K)'H]X:(`\<F6!(@.[2*ZGM+Y
+MR-2GZ/K%K">P7A@@MF0ET2NIOB5$C[`.R'8$\\``X>7+B0ZAY[D3_/`NUO.H
+MOKN)GF190G0L77\?T>TL!XA>2O1!HI^P_<_V/?N/`L1F>)3H`*J/3Y=\F^4+
+MOT=*?YK[A6UP]A^S'DMT*N6_Q/X*NM_+1+]FWDCT#$I_C>CC=!U_$/5?A-\D
+M.H^>CT_#N<(N7UEA'LAGL4YF?9YH/_9OLCQ@>4'T)_:3$/V4YPW+'4K?2_1'
+MMG/Y;%I*?X^O8U\YOV>>/T1_(?H1^XEI'!P@>CG[W9B_L?Y#]`3E?\;OD?T@
+M1!^@]GS!GWPD_!7;T53^ZP#Q,7Y+]&_6(0)$-_D>_<R?B>Y-^3\$"*\_SOR.
+MKN=O3NZB^_[(^B/K^6S_TW5M1#/8CF;[DNBO1.^A]-^(]B'<SOH:RT6V_]A/
+M1#26=24>?RPK>+RPOYCH>-9_B`YCO9/]MVQW$^W+?)[H*+:WB<93.ZRLM_"\
+M95\9RV#X"(+9]N%YRS*$_>)LH]+SA+.?FOV;1+^BZ\\F>CWS:?CP![.OAM(C
+MV7]#UY]']!3/9_:-4SLN('H_ZX-L][&_@],)7TST=KKO$/CF+F&_'HWS842K
+M>)X3O8WPY=#W1@2*KX"W;;)/[8I`\=G&L>[%?@.BAW@=A-<Q"%_+:RO4KB36
+MO]@/&"@^J`F!XN.=2/0Y*C<I4'3LR:Q3LWT.7QL?_-K"_F*6%50/?P[!R;89
+MT85L/P6*#I3&.CC;X[#A9P6*3.2/4+Q%^$;VAU$_91(]RG80T3:V:7E,LGY%
+M-,`LMN>B()%YESG$AKTI2'QULZUB*SYM%1UCDD76CB*LHH.S[LB^2;9Q6*:Q
+M+L8^]/,LXI-=:!<;QP19%VD6&;HT2'R2C]O$AKW2)FLFP3:Q:4SP*?%70>X`
+M9EG&9^2SCCX[2&R0$S:1D4\%B>S,"A(9=E>0^-),D.EW!XGNL]8A:Q8FZ+C/
+M6\367VL6&7^U6=:(VH-$YOS;+&M@46;1+8J"Q`;BSQ^L13WL.SYA%=D:9Q7;
+M@VU+EF%U9I%-_(D57KM),HL-^;M%=*9I%M$1^ME$9G\0)++X$;OX]L98Q(?<
+MRR*Z6(M%UDY,\"FRCLJ^_O-LXF,XTRRVZ3M!(F-BK:*+U)O%!_>%670Q]AFS
+M#?(OB_@$MUI$-K"NR[I^CEE\X]LL8HNQ#<PVZ2FSK%EU6L3FNB](9,_70>(K
+M_E>0\/)_6F1-<9Q5?.0;S>(S:K6)SVRP36SKM4$B2VZQ""\/M@COGF<3&X5]
+M2,SK/[&*#WFP17QRK!NR[7.C17Q:A\TB$Y\/$I[<QR)K#-/,XHNL,`M//LLL
+M//D.BZQ]\IK0;^A/]H4]'22VUUB+K!FRSLN^J9T6D75L.S#/?LLFO)C76'C-
+MX84@D7')%M'%U&>N>?Z:14=\.TA\?8<LHA/O"!(?1)Q9?(_A5N'%UUI$UA^V
+MB(]RBD5X\-\V\7G/MPB/OM<JOKT"B_A4AIG%9[W>+K+K3K/HTLO-(C-'VT7'
+MY37@@;"[V'=X.$AX+/_89IAM%EMLO4U\R556\3W<915?_1-6L:78M\YK,.5F
+ML>4^#!(?^?M!L@:P/TA\G%^99<W#A+6^Q\PB*\ZTBNP/LH@M7F@6G]DY5I%]
+M/P:)[K?<(FLP_%DNEB7'@F0M[ENS^#1,6.L\$B1KW/QC7\IE9I$EMUI%5W_%
+M*KZD2ZRR5K#3)CZA+(>LP32896WO.;.LG:RPB6S[P28^ST*K^$Q.V,6'?(U9
+M=(4-%M$-S[:*#^9ZL_CF!YA%5NVPBNZG_,?<)V:1O>PSY#790*NLI1ZSB$Z0
+M:A/>^[I5>%RQ57RW_&.=<(!%;/H*B_CB*RW"\TQ8\VXWBXW]+ZO(E)_,8C/P
+M-UM8AO`W7=CW>IU9?*+;S.*KY<-T6+:P[<UKF_,=PNMN-HML.&F6V(!WS2+C
+M-IG%E\]KB6SS1-ED;<J$M>WM-M'E^4/)+%.O,`O/?]PBOL,\L_BP%YO%!_*S
+M372H<+/XM@::A8>;8*/_8!8?U+EFX>5/F&6M2_%WHFEV6>L>;!:97&P6W^Z_
+MK<*CGK.(+O"Q36(2&BVREN0RBZ[$OC!>&]]D%5O]88OXU,^PRQHK_]A6V&^6
+M-8<DJ^B4O2W"PY::Q?9O,@L/?-PA:Y615M%Y`BPBH]JMPF,NL(DO<YU9UC2<
+M%M$)E#^$;4BK\#+^,6]AGRC[S%Q66>.JL8CMGV86FVN857SI9UEE+9O7/MEF
+M'V<6G_>G%K%QOK");A!L%9[$/U[#O<\L.OEJL_`F_K&N-\DLOOV1-O%U\QHW
+MKPUUF&4-<89%?$;\8YGS7ZOHLN];Q>9\PRX\8:%5>,*75I%Q[`MEGG&.17QH
+M3UG$IW^+6=84!]E$U^8?ZVP+S")#.=:!U\J66B3F@W\<DW"O67C9^W;A!<.M
+M$EM2ZA#9])!%=*!WS*(S<8P*VY"=5K%-7S=++(7Z]C#'1%C$Q[S:*CY5M?X>
+M)+$O/P&S+7>N17R4]UMD#>$6F^@.OYEE#?D_%EG#Y!^OP9VT26S`JV;QN8RR
+MB,[ZG5ETG1,6L6&'V44WN\4J:[9W641GYK4F7IO]MT5\5'TMLD;TBEG6#MXS
+MRYK--JO8/K_89,W(A!B`>+OHYGE6X:GLI&.=H<0NLG&(36SE3*OPL(>M,B?#
+M+#(GU7H6^VBM$D.RP"(Q!?>;96[^:I8Y^+M5=#U>*V3=*=DFL4(/F(4'-IME
+M;>9EBZSQ55O%5[/&++(LW28\/-XJ-M,'=HE%,<&':;.)+IA@$=MDAT5XS$M6
+M\;T=M8EL?=8L,3XOF\5VS;>*S^=#J\2\#+**SO>V17CZO1:Q44=:9>[PCW6V
+M%5;AD<H_R6LT%O$E?V21.?*"66(71MB$M[YN%Q\'QS+Q&LX;5K%1ASI$)U%^
+M:6ZO363&I5:9RQRCP+[R1RWB6WC3+FL2_&-?Q@]6\?'.L(GO[GJ[^.K5$2Q$
+MPRTBP_G'O'N[6>;4/^P2N[#/(FMEN1:QX6QV\?G]91:=CQ=Q>(WD/HOPZ+>M
+M$L/Q@5E\Y#=89"XN=<@:U6=FB17[TBPR7*V!$+W`(CSX!8O$K'QH%M_)<8NL
+M`?"/>>\&J\1^V2VB2SAL(A/FVT5G^\,B/MLDA\20M%K%)Y7@D#7LJ5;QY3UH
+MD;5ZCF5@7GS$*K%@UULE!DL=%\SCPBRZT4U66>.YT"(ZN@EK)NI\4%"VB=^T
+M"6^ILHB.\*U%>.5DJXSYJRTRID,LXKO@&#'V-?YFD9B%8IOPU#*+^)+.LL@:
+MQY-6T0W[VV3,?VV5V*0HJ^A()L00C+.+;=)B%Y]#HU5DWQ2;^#(.V$2&%-AE
+M3>!=J\AZMT5B<:P6\94^;Y.U"#YU[EG4S[K.+*O$&`7:)=9LG$7&L@EK=OQC
+MW=ULD]BE!5:92_QCGG.&170!98^P[]@JO.U9BZS5;K4*;PVUBPT^PRHZR&:;
+MZ!Y];!)39+>*CV>7763H<U89NX]8Q6=1;A5;S&63F(1HBZR)YMK$U\9K9^R3
+M6V>5V"@ECUBGM$K,Q[DVT5V>M0N/W&^1->F++"+3AUIDC%]LD;$ZQ")K&[P6
+MS6L/EU@D9FJ816(X+K?(&L-PB\1:<(PB^P!&6F1.Q%HDINH*B_"ZT1:Q4;98
+MQ`;+L,B<F6T1G_;K%M&5O['*6@ZO^?-83;&*KGNE160$_SB6K(]5?`1*7A%]
+MW"HZTBBK^*QJ+;(VSC[O'[$6R+I@C$U\2ARKPKZ`J1;AV7ML(K.RK:)#UMME
+MK?=IB_CL=UMD33/5+K)?Q4F:94V"U]#L#O$UWF`579%_IT#9-[/*(FL.TQRB
+M"Y5;Q.>I7.A$1UO%9_RZ37R&2QPR=F^V"&^XW2IKRS=;Q1;F'^M>\ZUB,WY@
+ME;$XT"&V'W]'D><DK\%R[!JO3;*LO,TB/CJ.%>!83%[;#D-]/#>?LHIOVVH7
+M7?LRF_!4_O':XQ<6B4$MM,@:]U<66:O^QBZZ3+U#=((--K%5^<>^MZ^LXA.9
+M8A7>N-TB:\H=5N%!S189BXLM,@976V0,*KL)E,?@V389@]=:90[PUP\YENP9
+MF\2`+K++V+19)?8BR"%CE-=L>&R^9)&Q^8!-QN8VF^@@?:TR1ANL$EOVID5B
+M-SDFCL?>MU99"^4?R]PM5N%]]1:)#;G'(K;K63:).?[0(KX+_HT%9=[RFE5B
+M?WO;98VRW28V\R,6B8DLL(J/B7\<F_BC36+_3EED+?`&N]C$%389NR,=XD.Y
+MRBJQ"_R['I1C1@.L$ANYT2)S[BVKZ*P7VB16A7\LTZ;9Q9>PV"HQI6]89&XJ
+M.6J1-:I;@-FG]YI%8DB^MDB,"/_F@O):R62;Q*Z$6476%MHE9O!GJ^CZX['6
+MWF41F_ZX572I!ZQBT]]IDQ@I%0_,.J9%8JC'V&5MT(0U)[5^S\^%.37?)F-H
+MJTULQ&,VB5&XQ"YC/]TJOL]:J]B.:AT/=`DHZ]9#;1+C94+LY!&+^$P.6L3V
+M.&8'C[&(C7Z956*M`VVBJY98)89XHU5D49E=U@0/(+;[$XO$V(ZQR1BR.F0,
+MW6X3'<QI%1VDU2ZZ]8,.B:G\W"*VVY5V\!23R/X_+:+CJW584+;A9CID;/&:
+MZ3^0SKK58INLO;9;Q":=8!6?U1=6\8F]:I6UIFOM$J/ZHU5LE.^LPA/YQVLE
+M(^PBZ[ZWBHW),0#L$W!;X5NTB@ZDY"FWTR9CD6.B>2Z.<8@.S!_O>@7E-H%R
+M;([%)F/M'KO(#JM-9,455AFC*NZ6:'^'^/#:[>*S^X=5Q@3_W@9M`F7>$V$3
+MG9E_;$O<8Q,?UT:[V"SJE%A0CD&9;A7=D;\QSS%R%]E$ALZURIK+^S:9\[]9
+M12<.M<J[SK9)3.%S-GGG1ZUBBRJ[#I1]8H_9Y=U>81->R#'W[`-[T"H\EW]?
+M@O)8Y`\<,^\]SRIS<))58E3YQSK:5+NLG159);;E?*OX3LOMXFM991<=?K5=
+M=-)4JXSEBZT2&S[*)K%P_[%*C':P7?8VY-ED+O[')CJ>\AMR^VWBTWW.+CHK
+M_WA,'K))3-G3=HFY*[3!QC.)#]6$M=-4A_"XEVW"$V;8Q3:[VRH\["&K^(J6
+MVB7V_9A58J0_L\J:_&B;\/R!-M&E^,>Q(V.LLH?A'JNL$37:Q/;?;I?8&_ZQ
+M+C'8+C%<%]ODW:FX7=;-K>*K&V837G:G57P,RZT2Z_ZP3=;HOK:)#U/)2;9E
+M;&);O6T3WUB73=8,'G"(C^]&JZQ5%]DD1O0/F_A*5'P'\V"'O+,\N\38[[.+
+M;JSBCJT2Z\[O:IU=UAR?L4K,_!&[^/C.LXM/Y$R'Z*19=K&Q?K4*K^)8D\M1
+M'^N(]UG%9^"V2<P[GS$]$OGL0X^SR9S[PRXZUI<VT5E>M8O/7_DAV==MDQA0
+MY8<$30#EV(SK'1(3R#&^+,.7.20F7<5+\3MUB,^\PBHR8IE5?$U.F\0T<RS-
+M!&W_"L>*V67L_VH7F^24573&W5;1-3BFBVVD&VRRIC;')F-=R4FB33:9V_QC
+MV7#(*CKZ!)O8!ODVT>D^LLL[B[6)[?2-3=:&E'P$95_%;(?X#AZU2DS_33;A
+M$;?91+=,L4D,42^;Q!2NLHHOHM$N,:?\8QO]@%5DP'";Z'C\C66V/3ZVBHZ0
+M:1.?TG_LXIN]WR%S_6^K^$S#;>)#.\<FLDC)2]:9;.)#>Q%CN\`AML7Y#I']
+M40[I^W\XQ'=\G5UB`IZUB@YZ@T-B"]^PB6_\-KO$!-UK$Q_&`IN\LU=L$LMG
+MM\G>$Q4'"+H<E.?29JOXUG=:Q<>PW2JR8P_FOHK;86J3/2;-=IG+[]ED#2#"
+M+CK;U0X9P_QCF7/8*KI$J$ULQIEVZ>O+;<)3^<<\Y56;^+B4O.1858?87-_;
+M1(;LM4J,>X--WFF236R-+7:)+7K/*C%8?UIE;8!_['N^V2:VV"2;V+I[[:);
+M.QRREFA"3%^=0^:NBFLDNL@AMA_OT6#?`,=Z\]ZB7+N\L\^MHE/P[R70ET'9
+MQW_2*C[<7^S2MY?919:?:1/=\UV;Z*X!-O&Q\UX`]LU\9Y,]2_QCFS7+)CXT
+M_K'.^()-?"%*?C*_=8AOGV-GV<<\P";O,-,A,H-_NT!W@_([[6N3/DVPRQZY
+M.VSB,S5A#]U?5K'A^]FE;_GW/BCO`;O6)K;..IOXL*ZSR5HN_WC.7&"7.<*_
+M3T#9![_2)K%DTQTRQWFOUV?(_QR4Q\S]-M&!;K2)KU;)6WY&F]@P_&-?Q6R;
+MV*I#["+3_V47&^%+N^A(83;1B5;890^$LE.9G]G%A\4Q_:SS3K2)3T?Y5T%9
+M1RZU22R?V2X\N]`ANL7G=O&A/VL3'^,]#AE[*NX2E/OP9[NLR2;:A"=,M8FO
+M=[]-QHBR3WF.V63OA_HA#HW'AMDANNQ[=M$U)MK%!]++(3I9K4UTL3L=XHM<
+M:9>YWF83'Q;_F,<-=LC>OH4V6=LV8<^$DKM$S[)+C.(XF\S5S^PR1OC':\+1
+M=AF[87;I4V6G$KW0(;XC_O'8FVL7GG>+772`.IOXT&?:Q&9<:Q.=[TR[\$3^
+MG0O*:['WV60-^3R'[`52\:A$G[+)VHZ2NT0WV43WL]A%5XAWB,^XVBXVP],V
+MV9/%OV&@S',[;+('8KI-;&K^,2^ZT2X^B2=MPNOOLXL/]5R[K#G4V$7F\(]U
+MP[DVT<WXQSI/I$-D\R*;Q)C\8)=8`O[QGI@+[3)G^,=C(=LN-D>.36([E5T*
+MRKQMJ4U\U>_81`;>;I<QRC_F99TVL>TB[3+W+K>+3'O4(3ZY+389:V4VV5-S
+MED/6]$;:)68UQBZZ$>]QXKYXQ2Z^[G*;[*U2?EY0?G=[;;)W2=FI_"[M,C<7
+MV$6V[K/)7!SE$)ZKY#`HR\B+[2+S'[$)3U-V*K\OA^CFG]JE+^ZRB2]MI4-T
+M7/[-`\T'=8*RC7FN0V3=:AOV2)IDC+]@%QV7?ZS;K;*)#_3?=GE'_"L!Y3G^
+MNUU\>@^BS_C'?=%B$QMMG$-L_5YVB36_RBZZQ!J;V(J/VF1/J;)?F0?;Y1U>
+M8Y<]IT%VX;%*_H)R[.2?=K&Q59P:Z`I0-RCSAB?L,I>4?QB4]U)LM(G-9'.(
+M[-]A$QFI]K&RS6T77LJ_!T`;05>!\C-?ZI`]FLINY6>VBTZM]@<P/[!)#!#O
+MP5J#='[FHW:Q.1KL$D/S">;X(+O$1/&/=:8,N\0B];&+S*BRRUSCWU.@/&=Y
+MS^9ZX&=`F<<F.L1V4^N21-T.\24_;!>9J/S#H"^!L@WSJTUTH$_!,Y1_&)1U
+MCOYVV0LQW"YS1NWGXCW&=M&ME%W+<\DAOHSG[>*K4O*88]KL8EN\9!<=EF/.
+M><V9]U+N0+E_@_):_]UVL=F^M4M,G)++H.S[O-(A<TWYC4'_"[H/]%W0]T#9
+MYOW))C+E'(?LD=]OESTW2A[S>'7(FO,PA[RCO]`G(7:Q%93]"\KONM8A>^O5
+MNB;1>0[9$\T_7KL-=XCMD>*0O9UWVB4VKMPA-IC:YP;*:V#\Q6R./6QPB(ZC
+M_,>@+:#L(WK<+K$.X^VRY]!AEU@=)9=!?P+EM?H!=I%U=]AEC9%__,XGVR46
+M^R:[^/8FV>7,@04.L?&47<S\RBXR(=<A?:+61T$YUB7)+KQ6V<>@;$,N=$BL
+M_MD.V1O\CEW6+K;99:[SSPQJ`;6"VD!Y3\JC=GE&):=!>X,&@_+:_XMVF3O\
+M"P$-!>T'RC)UCEUDM)+/H/U!!X#R'MTBN\3NY]MEKJKU5-Y?Z1!=_EJ'[!5.
+ML8L,5/*9Z$,.D3G*/@9E7>]=N\@XM6^;:)5#>'Y?A^AF']IESX'R'X/RVG*)
+M0W0+_K&.?(E#9-DLN\@H]4TEGF-V\7$]9!<95FN7F%FU/X9]L7:)+5KLD#V+
+MR@X&O1*4>;;+(3IOL5UBE-/MPJ-==O&Q\=D)B2@_!G0L**^!53AD;*YQR-C@
+M7S(H^\XR[:*C5=AES"G_,>AUH"F@W.92N_B(`AWB^U7KL:#7@W),29Y#VJJ^
+MDP$Z`W0FZ"S0&T!9IZFSRQPP8>_-?0[A;4H^@V:"S@%E'T63772YW^RBJ]QK
+M%]OG(H?X0I1<!LT'=8+.U_8U$]UDES5!)9<YEL`A/N@!#AF#:0YY%_SC-8,X
+MA\0`?(&^4>NS1'^RB^]6R66BC0Z141$.Z6O^W0K*MO`_[:(S\:]2VR?"LM`N
+M>WT_L8L/BW^L,SYI%YN`?\Q+UMI%YU/R&O1.T+M`V::XW2$Q[DI.@]:!K@3E
+M-:Q!#O&=\H_[LLPA,O-6A^B:?Z%M2DZ#-H*RCW`WQKZ2SZ`/@SX"^@_01T$?
+M`WT<E)_I9?2-DLN@_P)=!_HDZ%.@3X-R3-]C#MG;>H=#UC#5^BWH!M#G05D'
+MF^L0WJ7D,]$==I&52CZ#O@+*8^5[N^R95O(9E'U+']O%UE?R&?0-T#=!>4_2
+M<?#@&(?('.5W!FT"W0ZZ`_3?H#NU\R)`=X'N!MT#NA?T'=#_@NX#?1?T/=#W
+M05DF?VV7&!+^,4^\W"$^+26GF7<[Y%F=#AFC5SA$-U9^:FV?$>CGH,V@AT&_
+M`&4;^)1=?)'\^PKT:]!O0(^"LDYRTBY[`Y5\!FT!Y;66O^UBVW2BKX<[9&UD
+MA$-T(26?>6^976S?NQQR=HXZKX;W'#K$1\@_YBV5#EDKX-_OH'^`_@G*<^,,
+MA\0\]G%(&T(<TH90A[1Y@D.>=:)#[CW)(3$DDQW"<ZYS"(_MYY"U2"6?02V@
+M5E#6I6]QR%JR\E^#]@+M#1H,RFT;[Y"V7>R0MLUP2-N4_YK/#,*]+W"(+SC=
+M(>]:R6G0_J`#0,-!!X(.`CT;-`+T'-!S00>#1H*>!WH^Z`6@4:`7:N<*@5X,
+M.@1T*.@EH,-`HT'9=KC&(3'[RIYF&]0A<U#);]`1H+Q6^K!#QK:2WZ"C0>-`
+MXT&O!+T*-$$[WP&4[WVC0W0695^#\II6C4-T&B6_0<>#<BQ/AD/V%CWBD#&D
+M_-F@/(:R,8:4_`9-`9T".A5T&F@JZ/6@+.-R'.+S4OYMT`S0&:`S06>!W@!Z
+M(^A-H+-!;P:]!303=`YH%NA<T!Q0UG7_Z1"=0LEQT'Q0)^A\T`6@!:`+0=D7
+MMMPA>\V5_`8M`2T%=8&6@9:#+@:M`+T5]#;0VT$K0:M`EX`N!:T&709Z!V@-
+M:"WH<M`[0>\"70'J!KT;E'W"JQWBBU!R'/0>T'M!&T#O`[T?]`'01M!5#N/W
+MSM1"GDGV/_/>I#D'92-5#/#69Z$_`D<^AW5]X#4ST9^R%='SNQWY*Z^7@,][
+M@5<#/P&\"7@S<!/P7N!FX,/`$0@@;P,>`LSG#3$.G2YX('!#NN#+@>?<)'@"
+M<,$LP3<#A\T1[`+NW"%/M0JX#?WQ.G`Z^J,9./$\P3\`-V4&>?:[,]XR1^H[
+M#[BQ'?P(N#A(\I.`XUZ6ZV\$;G$+7JB53Q1\JU;_JQ@_P!//P?H&SCSB\QJ'
+M8&^P_GVMT^I_3>I[RR=_)_+#'I,-'5\"YTR04KVPMZT%&_S/`C[R*^0!L*O#
+MN_]!O;\-X(?`:X!O"C+>/UNK'QNBRGSR;T?^EMH@3QP\X]1>4NI![7K@M<`=
+M#@G,>AEXY7*Y?@]PXG*YW\?`U2]#7P$VKX4<-Z/\)KE^$/"<7^1^0X";%T(.
+M`#=<@N<#W@!\%W#E-=[X1\;K<##?2\#YSWCC^]3]E@K^#C@4S_,G</4OWG@Q
+MU5_8G],?./99*<]Q4CQ>]I]E56>2309N`L[6\OL+7HSK0\\%WT'^')-5G9VX
+M%OEK'I3Z7P*.P?S^+W`.\#'@??GRO">`&Z:BO5;!X5'PAP-ONA!R$/CH4,@1
+MX!S,SPK@BE5!GG5%-1Y>D`[Y)W`S^F<#</0E4O[?P`D_!'C6@=1X<P=XUET8
+M!_]#,*]WJ/8#GP<<MB;`X[]7_!$X!3CVU0"/'UOA78+O`$Z9'^#QGRI^`_PL
+M\)P%`1X_H>+GP!\"QQ0(_@[X8%&`Q_^DYJ\KP./_X?>YJ:]5G0W(?AK.7_M>
+M@,>?HNI[$'H-<.O&((\?0+4'&P47``>W>NUBQK/L,A_O!V[&QA:V"_7S_3GD
+M5_PWT&,?,5X/_(UV/7`7L'U?H$=_5?T)/!IX#O!TX`;@0N`FX+N!VX"?`8YX
+M5_`>X!3@H\#JH"+VN_5">>`8X*W`4X#W`.<`'P"N!)ZU"7(=.'PSQBOP0>"=
+M6GV/2W]^"5S[C.`36OXVV!F]P0^G02_O;>S_D<@_LD&>+P6X[4<I=:.&WQ6\
+M`+CEL.!*X/PO!-\#S-^.5?P.N':6X.>!-Y4+;NHMXW&?PZK.%CV$?/M_)+\3
+M>.WEX!?!D+<X2'`X<"+RKP/>.!SZ:;#Q>1<B?T@.]+Q@N?^*ORV*_ST(7`'\
+MG,_U+^-Z5["D_@<X^@S!![7[#Q!\'+@B1/`IK?W`?<]`__05'`4\!->/!JX.
+M%SP9V!XF^&;@2.!BX-!&&0_59\CS-)B$OS=J]8$_/P.<`OUK&W`+]*^/@%.A
+M?QT#=LT0?!)X)?2O<_I@_@T5/`*X"?Q_''`B]+>;@#MP?0EPZ!G"/Y8!QT!?
+M>@!XUJ^0_WWD^5P!ZAQLTVO(WWD=]#G@E2E8!P^!?)X">Q?X*'""AB&?LD,T
+M_1=ZO'9]&OQ-P+73X4<!WI(.?P-P!_"@4&EO:*C(TR&AD(\;89\"MZR0YTT!
+M7C,)_`,X\@+8(\`NX/7`ZX'_#7P$^`O@`LC;-N"<B\`O^J)^R-O!P&&ITIYA
+MP*D#X*?6,.;37.#UU?)^RH$/`-\-'`SY^BCP)LC'EX';^LK]W@?.P<;!H\![
+MI@K^#;C]-_A=^F%^8=8.!%X9(#@:^,@?4OY:X`[@-.!9@5(^%[BR$_H&\$;@
+M.JW\E5A?["<A%W-@CVU'?M@&:>\'VOVAOYP`CD+_]CH3_/X0_"[`ZVW2GA'`
+M!Z`/C@=N[2WSY2;@T)^DO!.X<PWT4>`-C\(_>Z:,1_Y.`I^AN0GYS5]@_``G
+M])+Z]P-WX/Y?`\?=#_LM#/+P!<$7`J_'\XT!7CM3<!:PVDC*=CYP_KF0+\#I
+ML#_N`>[\!N<4`.]'>U_4ZCL;[0?>-TSJ_Q#8[I3ZCP"'38,]"IRR1N2AY2ST
+MU^."PX%GXR#G,<`13\KUTX'77PJ_!G#39?`;:'BV7/\T<#/PN\`=P-\`VW$@
+MUU_`X<`A_2$O@"\$C@.^&C@%.!WX`'`!<#OPG<"N6S`_@1N!7P/>!/R!5A]P
+MBU8?<.``]&\FYB-P+'`,<`5P,O!6X#G`0^8*OA6X$_@!X(ALZ!?`"<`[@6<#
+M?P9<"?P+\`I@1SB>%_A\X(IYD%_`+<`S@&-,,C\6`8<>DOS5P*FW@;\!5S\F
+M>$^X-C\%?P$<_K#@WX'WH_[>`V6^'NRRJ)0!`S'>OI7Q>1EP(O2W9.`5P'.!
+M([<)K@%VO25X'7#UG3*>7QUHU']V(+\=^OW':$].L/"/;Y`?AOG;"EP+_TK0
+M(,S_</B/@;=\(.43@:.K!&<"[U\@[:D<9&S/G<AWP=YNU##LF1>`Y[PO>!]P
+MW$3$`0(?@7SM``Z%_G#FV>#W.,@^&K@5_K+)P.MOA+X);)^+^0Y<FXTX%.#B
+M>5@/`EX#_"WP'N"@"-P/^#S@\'S(+^#QP#<#KRB'?U,K#WOZ8>#9@['N!;P%
+M_&X_<#/P-\!1CPK^"SAF#-8WSI'W?U2^QV0:<([Q_0P^!_T+_CX<N`GZW43@
+MZ&LQ/H'7/27W6PP<NE?REP,?A#YY'W`*#N18"[SOB%R_&7CU5X+?`6[!?/D*
+MN!CO]T_@6-A#EG/Q_B'O!@%O^4/P4.`Y$Q!7K^5#OB0#M\V'_0Q\!/)F'G`C
+M_#]+M/L!/P"\XGG8@\#MP&\#-^\0_/&Y\CZJ0T3?;]'R\;[^0'X#\GL-QOB"
+MOVXH<!@.P!\-O!7R=P)PVY]89QBL^4OD>18`5P#7`!=_+/UY/W#H6U@O'NSC
+M#T!^%/Q[;VKE>PO^[V!I?WL_J[KN$^0GX/F.`N]_7,H'1,(>`#\X"[C@#L'#
+M@-<!CP&.PWA/!6Z[&/XGX'",QUK@6.`G@/>-P#JO=OW?TA^?`G>"'W\7J?FS
+M!;<#']P">^4\S-<_I#V1P*DXD.?*\[3^DOK3@?<%"UX$O!('Y-0#K[A([O</
+MX+7]$8<&/`?V^C[@Q!NP[@O<H)T?H=WO<OB/SX<^<`SK@>?+^VJ#?S'N?#DS
+M.]@1H/C%..#QA-D>FHKK6Y?(\]T('/8*[$/@N+%R/S>N;[?+]8W`H:C_<>`4
+MU/\LKJ^&?[<).`+X$-H[D3<6\9F$R&^&_MKG`NAGP+'`4;"G4X!W8OTA$S@"
+M!]J4`ZN#:-D>`MX"_>`1X$C89Z\#KSP3]B7P6LROGX$;*^7ZH"C82\L$AP-W
+MX`##RX`C[H(^`UP+?#/P3N!RX/$-@E<"KWM>\#/`ZZ$/O`I\$/-A!_#L%8*;
+MM?:%0C\`/@K_12=P`OR+H1>B?N`HX&*LAXP"WO>H],>D"V'/#!1Y-`OYU?"'
+MY0/O1/]5`H??(;@!./TQV'/`D;C?:\"S8"_N!H[X&_L2-`S]Z3AP$^SY+F`[
+M[C_@(M0'?_10X(Y_"$ZXR,@?QR$_!OSX.N`$W"_S(CGS-6:@;``H1+XZ#)/U
+M)>!U_Y9:GP3>"OUG$_`*S/=]P)58#_@6>.=*J:\#>"W65\P70U\/01S>Q?(^
+MUOYM4=]^24;^>N2[@'/"8$\#-P$_"YP/_K0/N!+X)]2_!?X?ZQ#<#_A<X'7`
+MHX`;@*<"-P+G#<%\6H/U..!]\"^L``X_@?4XX".[Y/G_!1Q5#_T9>/8JR=\Z
+M1-XGCA$P_1OY:]"_WP&O!+8-A7Z$\3T(.&<;]'TM_VW!8X%=3V(]'G@K\'+@
+MB=!/'P>.LTJ+GM'RX=_<`CP;_LG=P',^1IPO\*;%>!_`&P=AO>02S)^SX;\`
+M-J-_DH`;L1XX#7@+^%<><#MP%7`,Y'4C\!'@YX`C:L!_@%>"_QT"WG^/X#;M
+M?LBW#0-_N5?PN<`'D7\%<`3R4X##P!_G`:]Y&O$#P.W`3P%O@'_B=>U^L'<^
+M'2;RR@QY]35P-/"/*-\!_>R/83)^BT]9U-G*CFA@C.>(:.$'Z>`'PZ+!;S%_
+MKP$.!G].`UZ_6G`.\$;8HQ7`FQX17`\<]IK@?T8;^=6S/OAEE%^)^;`E6IZO
+M$_+[W\!1>-[W4+X8ZW<'@0^<DO9_`SS[(]COEV*\PS\X`#AVIN1??JGTSRRL
+M9\8A/W0<XGR`FZ"?3P&.@#]M-K`<L$[MNM3X?!7(/S(>_`RX`/;7D\`)_Y8'
+M>N52>=XC=M%7FI`?>:G4OQ]XY\5RE\/`<9!GK<!KCDI]ULO0'WUD/O<'C@2.
+M!JZ&/GH5L!GZYG3@)HROV<#:=USR@(_`WKD=>"/\@_<`JX-&F;\`;P!^"[@9
+M]>\&7@_^\"UP:(3@WI?C?E;!0X%3X0^=!CP;'QR;"YR#>(!%P(DI4O[ARZ&/
+M!H@^NO%R;7T`^@EPY!3HX]K]@,^(@?P!O@BX`0>ZC@!>#7MG//!XZ%,W`;=M
+MA3T!O.D=V+?`1X$?!P[[K^`WM/J`/P%6!YBS/@B\$^_W%/"*#/#CX;C?#FG?
+MN<.U]0')'PZ\HA'K[\#A\)?<"+SF)L1S`>\$7@*L#H3E^`#@*."?@:/_H1U$
+M#/X*/'B$]O[A;P'.Q_@>#UP,_T$&L`GS-1LX]1?8"UK^/^7ZNX#7M""^&7@K
+M\!;@3:\AKA:XT2;U_0@<`WYP"GA6+?3MD;!?_I;[C02.^A7KT<"KK\-X':F-
+M-]@'P&O_(^67`U>O0SST2!F_1[HLZMN/.Y'?@?PVX%3(^^!8C'_(G_.!P^%?
+M2(@U\J_QR*\^7U)3@<V(ERH!K@5NC$4\B7QWV[09^<&3,;^!-P(W`Z^=A7,F
+M@/=G8?_H%7C?3JQ7`\^&?C$&N!'Y-P`W`2\";@5V`X?-QWH!<!SPZ\"A^&#.
+M3N#VH?+\1X%3+X%].PK/<YF\KW#@.5#H8H$KT'^)HQ!?0^^+)7#**&-_9Z!\
+M)#XDF@L<\X7@$N#.^^1^2[7[?2#Y]P''?03]$]C^EN!7@8]`/]P+7(GUD&;@
+M-0[88\!;89]UHOWYD)>.T=`/8?^'`:^'_!\.G+X%^@3P/N`2X`-!TF&5P&M"
+MI,)'1HL\G`WY_S1P..SY3:.-_?<6KL_?(\_W"7`#^N<[X";PXT[@9JP?#(A#
+M^1<P/^+D?NFX_^7`8;A_`LI7P[Y-`2Y`?\R,T^2SW&\A\'C@*N`Y-7)!(W#+
+M,:GO1>!9\"_O!';E0=\&7EF&.'C@M<BWQJ._@<\&[@".`8Z$/SD)>#SPC<!-
+MR=*^)<"MUT'?`T[\!/M$@(=LEO+/`5<"[P1N`_X"./55P;\"!V\1W/M*R),7
+M$6\''`YY<(66CP/#K[M2QJ<YS*J^43,+^046&5_9P!T3I/XRX%FP#U8"-^&@
+MY8>`@R/AWP#>"'WS%6#MH-EMP,U8SSX`O.8U:=\O:-_&,Z5])Y'?VB[E[5=!
+M/^T$/P%>"WMR.'`3<!+PGF<$WW*5T9[,0_Z!*LDO!=XR2>J_`S@=X_%^X-7K
+M!6_0,/RS.X"/`A\$CGD;]AZP>0_LU034C_QS@*N!1P)O`)X$W-F$N'/@_.V(
+M\P8^`%P''`9_]S^U^P&_!MP(_"[P6L2G?9.@V8M8[]7R$=]V,L'(7WI=C?$&
+M_><\X$KX2ZX"3H!\FP$\'NM'+N`VK"\T`)LPOU_0KH?^M`^X&1_0:@6NR$5[
+MKL'\Q?K.,.!UR)\$O!]X'G`G\'+@*/"#?P%/!-X.'/M/[/L!W@C\-W#<#,CK
+M:]%>K']=H&'(U]'7PA[M*^N#*=?ZR#^45Q]TY/$+/*0+<?W`^3;$`Z&^?0$B
+MCQ[1K@_%OC#@`LB_[<"5D*\?`1\$_A:X`_+S3V#[EX(=B1@?B-<[#_@(\%C@
+M%8B_F`&\$1^$FI^HR7/L1P!V`=\#''T6]'W@N/Z"-P(WP-_\#K`)ZQ-?`6]`
+M/'<;<"W\I98Q>#[HO_W'&/L_$ODFR*]+@`_F2L+5P)5Y@N<`[YPG>#'P?N#[
+M@1MA?S\.O`+Q8INUZX'?!][R,-8;@??=C/6/L:@_$_(9N'8.^A]X?`W6/X%;
+M[\3X`6YR([X2.&PE_)W`.^\1_`&P_7ZL;XS%>@#TGW;D5VR'/34.\PG]UQ]X
+M)_C9I<#[@).!#P+?`+PQ4,9+'G`T^',U\#J,EWN!8[^4&SX,'#<0Z]W`K;#/
+M=P";P;\^`=[T+^S+`XZ`_1(\'O4M%QP+[`*^";CZ=<3G`$>]`?\/\%K@_P"G
+M+\?]@9NA3W\'K#Y,Q?H9<"S.D;,F0?X_)/UQ#K#]2<'7`J_X7:Z?!)QO0;QU
+MDG&\ST/^$?"'VY+D_?*!;QP/O1+YF_`AO]5:?9C/+P)O/`#^`AP*?^=WP+7`
+M?9(Q?Z,0+PZ<>"'Z-QG^*.@O8Y`?6@-_*'#D;,C'9"W^2W`1<"7L%3?P$2@$
+M#P"/OU/J>P)XZT/8QPH<MAK[/K7Z@3N!&Q^&/)^`^9@$>0X\)!GQSL"-P8B'
+M``Y%>XJ`BR^3]BX%GHWQVZA=_SG\I<`K,<&V3Q!]O'FHZ.<?(K\3^L2WP!'0
+MCWX#;D'[@B9B?L`?,FBBQH]@OP#O@[]P(G`"UD/G`*_OPOX=X&+XLQ8#3X0_
+M8CEPRJWP-P#/AK_])6!S&^+[@7,P7_<!F_"^OP3>`G_5W\#K/L/^T$F8+XBO
+M'0+<!G_)E9.,\R$)^6NA;\S6KL<'^HJ`5T,^+@.N.";X,>!H^"N>U_*A_WX&
+MO&&AW+7+Y_ZVR9A/B"<X>[(6?R7MOPPX+D?P]5H^Y%,^\%K@FLG&^N_QP0^B
+MO`OZUOK),O^V0I_8/%EK+_9M:[@6^J]/?=\@7SM_\)16'OR%XXA4^[<+O@`X
+M%OZWN.MD/+?"_ST>^<6PA]*`$^%/S@=>#7P'\$JLYSP"O/$#^-^!&S_"\P#7
+M(O[T8^#J(?)4/P*W8C[V2X&]"GYV)7`'^&LF<`'\LW<!%V-]\G[@E7B_CP*W
+MHO]?!EZ+>+MW@=MS!!_3ZH-_HAVX`?Z)KA1Y?ZF:?V(*^!/V'UP`W!8LX_^*
+M*=IZ!];KIR#>']??B/Q*Q)/,!X[#^+X-V([VUVOW0_S`<UK]L'??!0Z#O?L%
+M\&K8HQW`:X$OF0K^##QGJA:_AOTUP"EH7SUP`OP?CP'GP)^R3<O_$O$HP`=1
+M_R?`ZZ%O'`>N@+^(/PBLVH=XOC[`<9H\`]Z#Y[T*N`G[#V=-@[_R+)&O\Y!_
+M8#+B"X!CP2_O1/G40*N)1<BJ:5H\A.2O!QX/_"9P/O![P+/1/U\`5[?(_7Z=
+M9IR_)Y!O@CUG3<5\`W_O"[P3_3L$N`4X$7CB^X+3@=<!YP-W`%<"I^X7W`"\
+M`7@=L!G^JRW`!SX1O`]XY:>"CVCM/2BX'3CJD&#[]5H\N>`(X)6?"8X!3OP<
+M_G7@3<"S@(=@`UT!\!K@:JU^X`>`.\^2_GL6^`#VEVP'#L-X^^!Z+1X5_CKM
+M>OC7.ZXWOJ^@-/3WLU*^+W`.[*,HX&KPKP3@V="?I@`70][E`+L@[Q8#1STG
+M];N!8U\6_`CP2GS(Z6G@C>"';P-OP?[,#X"W8CQ^!;P6\9==:3+>U\-_WF\Z
+MW@?:=S'P'K0O#CBE2=HS";@9]O%-P/L?!+^:#OL;_.U.Y!_\3O+_`3P$\6'/
+M`6_"?'\#>!;*OX_Z8OK*^EDS\E>C/3\!M\"_9DU'>V!?G`=LACUQ%?`&Z(L3
+M@6>#W\X&7H?WZ0)NQ?K!W<`)NR%?@%=\B/4<X#4'<&Z*=C_(OR_3P?^Q7OX[
+M\L-@/UDST%\[$?\///%GR!=@,SQPB<!-]V(_.G`$_/>W`;?58GTGPSB^ZY$?
+M@WCF-=K]$0_RII:/\?,9\";@$\#[@/O/@'Z&]<K+@6<#3P+>@/U4M\PPMB</
+M^9L0OUT[0_05^U/B<URCU0__Q[/`:Z%/;YXA_7L`_?L.\D,1__8I<"3FRR\S
+MM/W6@D-F8OQA?I\/7`S_TTC@,.A7DX!GOPE__$QM?$A^#G`;^&LY<#KLN17`
+M[5B?6P-<F2)X(W`'\!Y@$^)AO@!.!.Z8Z<._9B%>NI_,GS-F@=]!/QD,O`'G
+M"0P'KD:\T3C@VO-QC@9P.O9+W`D<@_,#[@,^B'BNIX"#X:][`S@1>/\L8WL/
+M(3\%^M9QX'V(USL)/`3]'W8#]$WX;X8"-\!_,P9X#_PWLX#W0;]<`+P6_*`&
+MN`7ZQGTW&-NW!OGA_X8^"7P$_;E3NQ_XQS'@!-RO[XW@WTG0OVXTUA^+_!CX
+M%ZZ]4<;_9V1_\A-?C_P-B-_,!HXSP_X#+EXB^#ZM//;3K@=>A_VT6U#_4=BW
+M>V^4\9((_OTARJL/B;*^#KP>\>5!-T%?03Q5/^"X:'F>JX'W87_2;.!T[$^J
+M!ZX&WJUAQ*]^"KRQ-^QMX&+HDUW`%<##9X,?`\\#/I@HSUL&/'X__!?`<R;#
+MOP4<AOT`SP`?@+V_#7CU.UBO!P[^+^+I@&<#_P6\'SCX9KS???#O`IO>Q7H3
+M\#[@R<`%:,\MP"G0STJ!6W^$?7:S=AX+_(_`![$_[@DM'_NO7@=>BWB8?<"=
+ML*^^!&[$^M9O6GVHWWP+KK\*XQ=X/=[?..!6Z#,9MV#]C/1S%JFYR#]Z&/$<
+MP#L'P[X##H4]MU8KC_V0KP,WP'^W!U@[1[(9>$@OQ"MH]<$_9<G4XO5@/P/;
+MX=\?"EP)/!;X(/Q)&<`;L;^Z$#@._.JN3.R/0/S/0\AOA+_E*>`*K.>\"MP,
+MO!<XN`[\'OC``Y!?P$,PW@/F8/P!#P)NACXR`CC_!FG?=<#K@'.`(V^$OQ5X
+M#?3)E<#5B%];!;P:^''@"L33/P_<!OO\;>`8Q+=^`)P(_+U6/_!)X';(I[`L
+ME/\=ZU'`*X''`N\#OD'+Q_DQ"X#7`U<!=P(_`!S^%_9/`6^`/&P"/@K\*?`L
+MV*-MP.-AC_::B_D&^VX`\`;LMQT&O`7^QT3@\<W0)X`GPC^S$'@?SEM9"MP,
+M_OB05A[R[!7@H_!GO0\<@?63X\`K\?[:YVKGG<C[MV2#WR"^I#_P4>"+@9N3
+M!(\"GHWSAR8!5\)^S0)>"WP;<#CLU7N!7<#K@/<#OPX<"?OU/:U^X&^`#P)W
+M`!^!OG5&#N8+XC/.!VX$/QT-G`)[-P78#'LW"[@%N!QX#>S=.N!4V+MKM>MA
+MWVX&K@!^![@5^$O@.;!OV[7Z$"]DS]7.OX!]#9QPCO1W#/#J[[#^`]SZ!.0'
+M<#/TMW+@"IPO=1]P>A;BFX'7`._*Q7DNT*^_TMH#^^5WX&K@,_+POK"??C!P
+M.\Z/&0:\'O/]:N!&S+]IP&;HX[.!CV!]IC3/J#\M0?Y$[+]:"5S]*?87`^]O
+MQ?,!KV@2O-VGOKW(GX/]89\#KP/^!3@6^\6"YF'^`I\U3UNOQ7P!7@-\]3Q-
+MOQ$\';@)V`D<@?CXVX$K<?['_<`'@)\!CNF#\TZ`7<"?`L<AOOX8<'H_/'4^
+MYB?P`.!6X,N`(\_$>6/`,9,$WP#<`+P(^"CBO^X`KL9Z1SWP1L1GOPALAC_A
+M8^`XX%^`4X"#G'@?JW$^#[!Y'?Q-P!.!KP..JT#\/'`4]K^[@&-@SRUS8G]/
+M'_$GKD)^..I['C@=ZX,<%Z@?/P>0WP#_TM>H+[2O^!O;D.]"?%?@?,Q?[/\)
+M!F[<*/4/G"_7S[9853SF!<@_@OUUPX'M18C/F&]LSW3D[_]:L!.X^`'X"[3[
+MPW]5![P)\4)K@"-QWM4+P&'78OT(V(7Y^HW6?NB#OP%'0'Z8%V`\(-[\+.!F
+MV.,7+Q#[)`'Q<;'(WX?WDP(\"_%"^<!16.]>OD#S7PE^`M@%_#;P&N!FX!R,
+MI]]P?S/\#[T+H'_`'W0^<`'V0\<#MR->9CKP:N3/!]X)O`RX#7@U<#CB25\$
+M3@#>!5R->(?/@#L0+_8M<`36:WX#COL6\3P+T7_`YP%'0C^)!K9C_>Y:X'"L
+M1UX';$H%?UJH^4L$K]#*XWRI=<`'@=\&7HWSI0X"S]DJ_?T'<#YP3"'\#\"%
+MP$WW8#\=L.DNR5\)'(7]T`\7&N/5'D?^GK_`+X$K$<_^&G`,]+.]P.DXG^<P
+M<`[L'5L1^A?G@T0`[X$_;6*1MK\'\8[`:_'^Y@&'(<"U"+@:ZR=513+^8C'^
+M[T9^&_QMJ[7K([&^6(3XZ!"1S[N!$P,%?P%\$/+[+^#UP&'%@C<`7PZ\&G@R
+M\!K@7.#(OH(KBC'?H3^ZM?K"Q-Y;C?QTK+\\!=R!\^=>!Z[$>7/O`A\$_@HX
+M%?K#[UIY8/LBR%O@0<";@"\%W@-\+7`^SJ^;#GQP$<[C`>XH$;QXD7:^*.P?
+MX%"<U_C8(B._?1KY!W#>P*O`1[#_>O<BQ&N'2[S:I\@_BO-[CB$_M:^<5_:;
+M]CS8;Q)2@OG^%/@EL`O^M6N!C\"^NPFX`/[=2N")V']X#W`*]A,_!;SI-\&O
+M:?6A_%[@!OC?OP!N>EOP'\`'X.\**<5\03S;4.!$V+-7EAK[;RSR0V%_WP!L
+M&H/]%\`M6-\K!8Y\#/XPX(GP1ST`W(KS))_4RF,^;@>.`?X*N!;^LS^`]YR#
+M_1C`;9C_H2[4C_N?[S(^SU#DIZ(]5P$W`M\$W`R\%+@#^&'@,/C3-KNT_5OP
+M1P%'`_\('`=L*4-_`)\+7`P<"[P2>#+P&N`<X*T)B)<%GHWS`>\"KG@(_C0-
+M8S_I<\";$#^Q2[L_]*^/RQ"_W"7GX7V#_`.P)SN`\\$_0LHQ'K&^<T6YYM_!
+M>8+`B<!5P+/>%+P&V+05ZVG`Q<!?`<>ERO/:%X/_XSRVBX#WXSRV"<"SL3]M
+MUF(M'AWKE\`IKR+^&;@!>#OP5N##P'N`?P<^`'Q&!9X?^`+@E6\(3@!>!YP.
+MO`^XJ$+ZVX[SX2J`=X:(?GDORA]]'?Y0+1_Q*Z]I]2$><E>%=MZ0O)^#P.NQ
+MO_P'X-58[SRIM1?Z9.BM:.]+L,^!YR">Z@K@(0@72+P5^^MPOL@4Y$?"GS%3
+MPYA_.<`N[`=V`^=C_>`QX-E8/W@5V([]0N\"K[\#ZWE:_2O@7P2NKL=ZWFTH
+MWR!X$/#J][!?'7A%I+1G,G`#]A_/!=X)_KH8.!S[8>\&7@MYLAIX#N+-_@6<
+M@/9O`=Z/]NX&#D-[/[\-_DJ<WW@,^9'0AP-N!__"_J\!P(GH[_.`*[#^?J56
+M'O;>>.`4+=SC=B-_G('\E?!/EP!O!&X`/O(5XHV`"V#/[+E=.R\)Y]\!QR)^
+M\!O@]3BO\D_@=5@_LU>"/^+\QO.!<W!>X[7`K>`'N<`)F/]W`.?C_,4G@!.Q
+M__)-X+"?L'\(>`[.G_ZN$O9A'^E_4Q7X(<9W>!7&!Q3:&.`FV(OC@5N`9P!O
+M@+PO!S9#?WP0N!AX"_`*X$^`VY^#/@+LPOZ<D\"KX;_IMP3Y\-]<#-R$\R:O
+M``Z#/VFZAF%?9@-78G]H*7`P_!\K@(?`?_$HL#D#YT,OT?H3^W^!([&^^IEV
+M/7#H4FW_!.;?4N-X3$-^#/RO3F"S$_%_P#E8#WL$N`GKOT\#M^&\C"W`J;=#
+M_P.>C?R#6OWPQ_T&?"07^\VK,1Z(__(=!E=C_-X-_S[P$9R/,A;ECV#]85JU
+MMG\"]H=V/?`2X!6_0A_4RD,?6@N\%O;]B\`51^7^_P'>B?/'O@4.1__\#=Q8
+M!__2,KPOG-<U9)FQ_V.0']8'XWL9].%..=_C!N1/1'X5\#[@)X%#<?[;3N!&
+MX&^`UPQ$?`SP'KR/T#OP_D[B?$G@<(S/4<`;@"<`;\3Y]G.!=V+]K@@X&/M_
+M*H$;,5[N!PZ%?WP#<#3B!W8#;P7^&C@%^TM.`J\'#J^!_$(\[4C@?."IP'N`
+MG<!1\)?7`E<#/P[L@K]\(W`C_-,[M/J`/P;N!&X!7@O_=5`MQBO.5QL(/!'V
+M^TC@8N"IP&N`G<![@&N!FPJQOP4X]FG$4P"[L)]]/W`;Y-<7P.OP_G_6RB,>
+M/W`YULL1/QL,'`'[O/]R\"_$HT0!-ZZ5^JX`CD(\QT3@9NB+F<#[L$&F&O@@
+MSA]X"CC.CO-&@/<C_S#P'.3WOA/Z&LY;/?M.E$=\=`QP)<X3':/E0[].P_6I
+MX!]SD=^"^.\RX"U8KW(#1Z*_'@8^"/_S,\#5\!^_#CP+\NECK3[L5_T:>/4Z
+M^`_OU/8+R/BQW05_`O;S1`-O`!X/O!/Q$FEWP7\*?\A<Y#?#_^4"CL9Y2[7`
+M*W'>4B-P%/://`F<`/UQBW8]XK$^!@['`6;!*\!?@8<"%R->:PYP/OA!(?!&
+MQ!_=`5R)\X\?!#Z`_;G/`Z]'_G8M'_AC8!/VYQT#'@)\$C@%N*\;\\,%^Q6X
+M8QCB@X!#89]FN8W\.Q_YIC.P/N/&_I>3PK]7(3\6^=N`-P`?`^X$#KH;_`S\
+M_5S@Q'XX7P`X#N>7W0P\"W@)<"3B%Q\$;H6_ZNF[\?V)0+%O7@6.@3Z\&^7#
+MX8_Z#+@8_J0?@2N*$2\.?`2X7QWD/?Q+%P*GP[\T&GAC&<Y?!PZ&_I@%O!_Q
+M)TN`<Y:"WP$W`.\`;@+^%K@5N/=*X_LZ<R7>+^*/!@-W(A[^$N"FXU+^&N!F
+MX!E:/OA;+O!:^&]O!]X*O`JX\A7!ZX&#L;[VBM8>X+>`YV!_\EY@$_3/`]K]
+ML9[_)7#D4:S7`6_Y&NMU]>!/WV-]&W@U]K]%`:]`_X\`3D4\[C3@\;`G"^J-
+M_5F-_/60+V[@-NQW?Q0X'/$:F^L1/QLHXVTG\M<A?N)]X,X7$;\,'(?SCP/N
+M@3ULMYKX2+.P>R"_T'^#@6=A??$2X$;4?\4]VOO!_`:VP]]U(W`L<!7P%N`&
+MX(G7(![S'FT_(,[#`JX&_@MX!?"%]T*>`T\$-F,]T0D\!/RF%G@+[)-5P":L
+M;SP-'+87_C+@V5@_?A?X*.(A6H!K<;Z6O0'R`_QA(/!&K%]=`IR`]:NK@#<A
+M7GPR<`3\&;.`Q^/[&.5:_3C?R0T<#'OYP0;1+PXB_H_]"/KQ]1+*\[J8F@_`
+MG?#??@.\#^=M_0E\`/'C`^Z#?`..O4^S9[!^`;QO&>(G@1.P/\EYG_8]'KF^
+M&C@1\5Q/W8?S\<`_MR*_&OG?`1\$/G6?IB\BGOA^S&?$$UP,''.5/-]HX(,8
+M'Y/O]['?D+\1^V%N`QZ"[VNM!<Z'O?0B\'JLYQX"CD-YTP,8GW$X+PAX*[YG
+MD`%<"W_U;<"S<)[H8\";$%_U/'`^XL^V`>^'O^<#X!3X>[[6ZM\-^_`!X_/^
+MA?R<'V"/-V)\`U_>J'T/#>NGP(EG@U\#AX5!_P1N1/Z:1N/]GD1^)/C1R\"=
+M3TNI][7ZH2]^`]R.>*<.X#;HCWU6H7WPOT6MTM87X)]>I>UGEOLE`[=A?]ML
+MX'6(#RY:Y?.]KU58[PJ6\U;O0ODA^*#5_<#[,=[6`\^!_^AU[7[0U_\+O.)!
+MG&<#?`#[VP(?Q'COB_V&P+-@'USTH+%]EVGE7T3\,G`H_%$W`T?!'U4)O`;^
+MJ'7`6W">P%O`.9`WWP(?A/S]%;@!^FS(0[@?XB^C'C*V[U+D%X.?)`"WPS]_
+MO4_Y6<BW@S\M`(Y-Q/H\L`O[+]<`-^'\T&>`AUP-_S)PRI_PEP"G(G[BIX>T
+M[TE@?09XZQ[PN]6XO\9/@+<\+_TQ"G@_UL\G`Z_%>6*S@2-Q?DD5<`5P(W`M
+M\//`^X!W`;<`?Z;='^L#;<#YB"^)>!@8Y^U>"7P4]DPZ<#B^=U(*/!'X?N`*
+MX)>`S?`O[P>.!?Y9N_XEQ*L_@O;MQ'X.X+6(GYD,G(+SZ&X!MJ/_"K7KL5Y^
+M'W`QSH/\%W#S(.C_P!/A/_I4JZ\=XQ>X$^/A+^!:K.>;_P%^`W]5/^!B]&\T
+M<"K\+PG`+9#W-P-ON`_Z#?#1^[&^"QS1B/@JX-A56"\";L9Z11MP\%[8JVL@
+MOX`'`[<@'G$$<"C\*TE:>>"96C[B$Q<`[P%>"ER!^,0'@#<"/PD\!_&*KP.'
+M(5[Q7:T^X*^`HR*DO]J!<_(P/A[%_%V"\U:!UP&G`1\`+@4VP_Y8!1P+_"KP
+M'JQ?;`=NPOAZ%W@EXON.`H=-Q?YTX)W`H8_!?DC#>8[`X>DX?QUX)7`Z<`/L
+MB7S@`OBS*X%3(5_N!MZ(\Q#6`D=A?>15X"WPQ^P'-L.??10X$O[L#N`P?%\L
+M_'&,7_AC+@*V8WTC`7@.]@-?#]QP+OSIP&N@?[B`6Q'O4@-<#?G[(/#:%[%?
+M`'@KUG.V:/7OD_:^\[AV'I[D?PZ\$_%"OP/G0]\)60M[%_%J@X';<![MY6NU
+M\]4$CUUKE"=3M'S$U^0"-Z!]MZ[5OI>%\^?7:N\;\0S`L<#;@0_<@//8@4W0
+MGW\%/H+Q$/!/Z.^(_PX%'@+][2+@#<`C@*/NQGH'\&R\_[G`Q7C_B[3RB.]8
+M!KP"\1?W_Q/^B1")!_FG5A[?&]D$?"0&WX<#;AX.^_`)\*.1L%^`35A_NA)X
+M([X7,!4X#-\3O1DX#OU;!CP1YX>ZG]#V&V!]!MB%_)>`"S[!>2W`C<@_!+S^
+M8_A3@-?"7QOP+^W[C(@7!`['>!P*G`Y\-7`HUEMN`MX/>5JEY6/\/0Z<`OPR
+M<`/VDQX"+D`\P:_`%<"]U@&_`O\J<#OT]23@2.R7FPD\!'@A<,SKV&\*//$-
+MV+/`!Q&?N14X%/['_<`I6(\X`MR(Y_\3.!'G'?1_4O/W83T#.!+?JYW\I$_\
+M*.<SG_M&-MS<B/)K84\7`\?`?GH`>#S\*T\#[T1\YQO`4?B>UV[@.5B/^PJX
+M$KC+ISW6IXRXSU.X'_33(<#MX)^QP`?!WY*`31@/-P&OAWY8`!R+\XMN\[G?
+M'<B/QGK=8\#-6-]\`W@?OC?XL9;_I>1_#WST"+Z?"KSS*YR/]#3>+_2]0<!V
+MM.\2X&;X-U.>]GE?R$^'_9(-/![Q:\N`8V&/W.MS_3^0/Q'K?>N!$R!_W@2N
+M!7X?>`/T\6^`(S"__P;>B?D9MA[O!_A2X"C$6R4#IP-G`J="'W<"-\$?4+)>
+MBS_%?GK@E8@77P.\">L'FX&'0-_>#]R*\=NJU8_UY`[@%'Q?UO8,Q@ODW=G`
+MJ=,0CP2\`7CJ,\;^34>^"_KJ'.!TZ(=5P"N`'P'>"OP:<"OP@6>T_D:\/'`*
+M<)]G,9^`+P'>`#P!N!EXWK/:_D:<9PR<`+P.N#@>YU4"K\3^RH^!$W%@Z=?`
+M$V^#/_\YG_,/G\/S@_\,!&[`^=P7`S?F2WW7:ACS/1TX`OL7EP$G`K^@U0?\
+M!?`FX#X;M/A$J?]<X##X5T<!K\;^F:G`4=!G;@%>B_U@BX%=\#\U`.=C?]AS
+MP$.^Q_HI<'I_\`O@C<C_$3@<_,#V/.8O\(7/8[TB0/2#F.>-_3L:Y>-.X'LL
+MP#MQWDLF<#7.D[P-^`#\#ZN?U[XGA7ANX$[XDPX#1R'^Y11P*OS;_5Y`^[#^
+M-O0%V#^83U>_H'TO0MHW$[@`>!%P(_!*X"W`3P'/1L3W6R_X?(]>NQ_.(SCL
+MD_\-\N.@#_T&7`U_?Z\7,9X0?WX!<#[\S['`^XL1WP2\!_N?Y@(?P7F$Y<!M
+MP,N!0_']S%7`V)YD>AQX*_SK&U[4SO>1_+>`BV$O[0->B_-C#VGE;=CO!YP*
+M_39H(^0W[)U^&XW],Q#Y:^[&_G7@:,3?)&K7P_\U%;@"\N<6X(GPGU8#MT/_
+M?@@X%O@%8!?T\=U:??@^]M?`ZX!-+Z'_@<\'[@2^!CCZ/7SO"7@V<#GP"N#[
+M@;<`/P_<`KSW)9_]/EH^^/EWP&OASS:]C.?%1;V`0U=(?6<!;\%Z313P`:S7
+MC`1>#7XX!7@3\(*7C>TI0[X=ZQ=W:.7AKUL-O![K\^N!T[$^O\6GOO\@/V<5
+MUF>!\S%>`UZ!?8MXQ#.!B]^2^T6^HIUG)/GQP';P\VG`;1A?<X"/X+S\.U^!
+M_8-XA#7(C\/WOW:]HIT7)_AKX%3XOT\`[P?NOPGY6+^\#'@(QNNUFXS//P'Y
+M^['>D0W<@N]Q+09N!ZX##H6]]!AP!+YWO1EX(O`>X&K@SX!7`O\(O`G8M!G\
+M`7@@<`?P<&`[[-WK@#<!9P''8'XM!PY%/.K#P";$0SP#G(YXB-<W&_NG2;L>
+M^PT.^^0?17XJ]A?]J6&<O]/K5;SO:^7^9P)O17SF!:]J_G')'PD<"OUU#/#1
+M%JRWO6J\_\U:>>27`J>BOEJ?\G?[X/M\\(.X?O41K(<`'X`]LQ5X#?KWT*O:
+M_@+HP\#AT`_/>0WO"^<QC09.Q?DEZ<"5B.<M!LY!//)=KVGG1>%\(N!8Q`>^
+M!KP&Y]%^J-T/\<G'@=?C/-J@+6A?`/:;;)'UR#V;@I2$O0#YL3A/9`1P"LZG
+M'+<%^Y'P/;X\X(W`;F!S;XE/>@C7'T&\Z'KDIV!_T5O(7XEXK_W`,;!/OMRB
+M?:]!\._`8>B_OJ]#W\'YA3'`9OB;I[[N8S\AWP7]J@QX(_P##P!'P+^Y3LO'
+M?H2]P)&P_X\![S]/VN=X`^M!X`_G`N<#CP).A7R=K)6'?,Q\0XO?1OP;\$K$
+MYSP!7#T*^AJP&==_`KSQ%OC7@;?@_(8VX$V(7S@!W(#]/$%O&OO+\2;F%\9_
+M?^!@?-\T&G@GS@,9`]P)_]7UP.N6X?L46GW8'W8;<"WPO<`)B,=9![P:^'7@
+M#N#WM/H0'_@-\-92^$>TZ\%O;%LQ'O&]E/"MFOXH.`[8#'D_&W@/]KM6`!\%
+M;@3.N4+NMQ7XX%58/P!.Q/<J?@!N1'Q)QU:9#^/[2GQ2GVW@!UB?O@AX/_2!
+MV&W&]W,E\CMP'M%4X%3(W]G`:W!><`&P">NOM5IYG'?]#PWCO.M7@1MP7LF'
+MP!$X[[H5N.`^[$=Z"_($WR<[^RW-_X/]YL!M.+]V''#B0_A>VUO:>B2^YZYA
+MZ)^UP`<@[_X!W`GY]L9;FKS"]]J!*\&O?]2N1WR>Z6W8Q\!1P*W`*6\;^WLF
+M\J-+P:^!M\*?<<?;VOGO""_PN?X1Y&_!_MJ7@!MQGO4'6C[PG\#I6,^T-($_
+M-L#^;]*^)PI[L4GC/[`'@2NGX_QAX-DX?^<VX(DG$0_9Y-->Y&^`_?X,\($W
+MH2\#F\`_#@`G8C_2S\#56`^V;,=X<*/]P"OA7QH(G(+S#X8!YP!?#1R%\PNF
+M`2<`9VU'/"+V/RU`?B?.\UD.7(OS?!X'KL!Y22]IUV._QA[@(V<(/@S<!MR.
+MZ\/@#^FU`_(0\9`#=X#?8G_'Y<!QZ+]IP/NU]0-@.]I;!AP%O`(X$?@?P+.!
+M7P`^@/6'[<#KH?\?`&X"_A[X(/`)X#;@,_X-_HC^.0]X".*3KP!>#W_L..!H
+MZ*LS@'.`G5IYX$K@`\`/`N_$_'X1>"7DY;^!MP)_`FR'O?T#<`K\LZ:=&+_`
+MYP*O!7\="3P'_'P:<!3VA^<`MV!]ZNZ=V,_395'G1ZQ%_GC(YW>`JX&_!UX#
+M;/D/^A\X$O@(]F..`P[&^6F9P+&Q6*\$3L=^S?O^8YRO#R%_"_C?,\"-X']-
+MP'L0#_0Q<`'.6VT%W@_^\COP3IS79-L%?@D\$'BB&?,5>"OPU<!MV!^<#FS&
+M^0$%P*N![]REG;^$_7O`M2\)?FZ7S_<@=\G[:`Z2^)]=/OGOXOI(?/^G!;@3
+M_KN`W>!?X$\#@5.!KP!N0_Q>XFX?^Q'YP;!O9P$G8+^-$S@&\1&W^5Q_!_+7
+MH_X&X/'HWW\!5\->>Q5X-?!>X(W`S<![@'\&;@Y$_-(>[?M^DG_6'NU[<X*'
+M[-'V;V$_,_!$X*G`L4.Q'@W,\TP]#W#H?P3_$SAR%^Q)X&+@+_?`'N@GY['\
+M#+SI++$/3J)\/O2?D+V2GWZFU11CDCA0U;^P+P8#1^*\U9'`*X&OX^M9C\/W
+M3-.0WP'[(P<X&O'=Y7M]XLV0'U$!^0[<`/_OFWNU\VSP?33@</@33^[5]L-@
+M/_D[Z&_X%ZY]1]O?B?@]X#C$\Y8"UV)_UMT:QOS>"-P.?_<![7J<3WU$RX=]
+M]#>P">T]X[_H+WS_,/*_D'^P[T8B?R/.HYP,?&0ISJL%#D9\VAW`,3C/_T7@
+M'.Q7.?!?[;QZ^)^`$_"]HR[@%M@S??:13<+O;["\OS/W&=]/N`^.W`=]'?L#
+M8GWRX_?!7J7Q-(3['^73UR,>%K@2_K4EP.L0G_$`\'[T][/`LQ>`WP(W([[F
+M,^`.Z+,_`T<AWL3Q+O@/\`7`^8B/'PU<"SP-^""^'W`+\'CXWPN!MX#_+`>.
+M1+SF&N!*R.]-P%MQ'N\^X*/5.%_N76/__8+\UFC)-[^'ZW$^5W_@?,0?1@(7
+M0![$`\?`'W_+>\;Z<][#_AZ<+^E"^5B<)WLG\";H<ZNU^RV'OQEX(LZ3:/*I
+M_S^H?RWVXQ[RR3^"_":<7_`3<"W&2SOJWU(IY7N_#_Z,\SXR,\??,'7,E$GC
+M3)ECG:[IN:[LA<4%F9G)J>/B!:?E%J=Z_S1E%I?D%N<6YF1F#H\9FU6:.STE
+MQ5GJ2AU7;LK,*NXA(S-359DV;M1T5XFS<%ZV*;.@:)XILR([/\M9F)D97^HJ
+MR<U:.+<LSY0YK]A5DIDY3I]4W#TIUT^Q7'_EZ/\^27,+<@M]DDKSBTI<JJ0^
+M-:N@H"B[6VI.D?_TS`)GX8),WZ?)*R@KS>>:C,G%U`NN(M4,[EG5*6FCBZ1$
+M=G9/G:R!J44YN3UTM[&(<W%1"948Z2PJ=5+7YKHRLXL*RA;Z-')A>59.3BGW
+MW?`1X\I*2G-+9SH+<XH6.YVIX[+Y[2V4MW=%LK-B1*S3)R4VCE**BKE31^<Y
+M"[C'Z;+TX:9,N@'=?+13;I5:SE>.G4Y]5)Y;XN):KDC+G9=;0:6=3BY?FNNB
+M"KAF*IF=6U)"SSBWB(N6WEJ:6>K*<O'#SBUS%KB<A7R;<KDQ5\7/(_=QIHWS
+M`E5I9A'=,*^@:'%F?E9A3D$N/>A(:GAJ<NKU(_B/D32N,\M5_V3GT]W5B)6'
+MU?Z*C:,WGUN0F97GXLL-7<ZM6%Q82B_3-]E9FN5RW<H=H9I1DCN/,G)+2FE<
+M9,VE_Q>7T1-IKSTC6[O9\%':7R-'T%^3IF66\>/FT9UI))DR%Y<X7;G>"U/'
+M3<]V2KD\>H3B(JWF*Z8GT_O@AO";H/&9RR]->Q]IVF1TZOO7\PIY/I>F%!7.
+MH\X:,VZ"*7-Z=E'QK<P8^#IF"N/P!S=V^/#<'*>+ZE`C>9P!<GY6Z?\J0[-R
+MGBN?.]&87IB[F,9#A;RRC-(<FM,E)44EOKVM!NJ\TK*YF9EX+AJ=GN'ET]73
+M55?'3\@M6IA+9;-S4D>F3:5'S,^E^R1G%*@AKA5VIGKG2FIZ#&65NZ*&CZ";
+MYCA1)(HGF)91Y#\CSC<MTUFT,*O06<Q#8RX]"+\;3-2T6318<TNR*=64Z<HM
+M*)CGG4;:8)<&I1GXF/1S3[G.A5E4S[C1XXJ(P^=6T!3C%^[ERE-'Q&AC@OES
+MT8*RXDRYG-\=<01G26XVLTF>[]J,ZI93/#<K>T%>EK/`3Y:!&_EPAVP/%XDK
+MRM,&-C$&SUMQ8HPSHW(6.EVJ@J+"@EOU['04!)67E_*KIF&AV)N7V7)E/"5]
+MDK(+<K.ZE1-^Y9OJRBUU&?@W)V9U*^9M&@U7IRN5&$)N2:%/^S)S%ZD7H;V:
+M'$Z3V6I,@Q@UI"UT^DGS4RZGW#>MF-^?3S$:J1H+(!25"<E/_S=ESB]B\28,
+M@!_/,W+\\'_5P:K/=;R8YN:$7->T8I<S-35;IBR]T)S<O*RR`IKQN;D+BO)8
+M!<@N*BMTZ8<\#;4BE@8Y.=+@284NFMHE!6G:7Z9,-?5[R%M85M!C7HZSO.?K
+MBGJ^7U9ASWG,GGK(JCA-7D%IOC//U6-VR>FS/6_33Q[-Q9%IU.*BA4@B]FM,
+M\##I_UEN7FYA;DF62UBP;Z9B"=V3\YWS\OVE:Q+&3V.R"_PD9Y5.XH'AIWA)
+MJ8Z7&'EB0:E.5AJSXM*R7,ZBPJR"#):K/OPP/2;;RP_Y%F6%N:Y;BW/5A1J/
+MHDG@^9N$%>6,=186+71F%7A8!'B2E[UX$S36XDTIR/*YAL0R/2I++]9+?*<L
+M\]&*3&<.U41M*,OFI\ET99&.J]1YL!M749:Z2L^"%.>9EU5,@I<'%:2NJ!E.
+MR2FAM^8G:R$Q?Y5OS*$'7IBUH(<<4E07.TE1,TAHJ(G,<^*=Q7G=1&9\D4_B
+M7%9!='Q0E"4ED_4:J98$CJ=/FN?JEE30/4E7_<@1W:K7DG35:TFZZK6D`M^D
+M8F)S!G'.RD%J09&+E37OT_,[-*KI%7D%6?-*?0P)&AC$I7+]6"Y9+I_44E=1
+M:6FV3]IB)^N\KB)E''2OR2!P64-T9BO)76!0)&`3=;MC66&.IB88YQUT>%;N
+MQ"SQ]$<:ZV9T(YH5+N="-;<A,Z+RG"1(,@N+"HN*7=TF*ZDZT\OFXF_/K-4*
+MZ?(\%_@4HL%X^KS3U>_A&/^G8O^C.D-+_E>Y_]N3<<-.G^OO-IE3G(5EI=,*
+M<Y623^I2J?.V7,VL</J^.+%?NM>C]#:C+LC*OPYZ#833E>&[^55'91;TD$4J
+MC$^*;E#ZY)3>6IC=+7$N:ZGC-)U]^,B\,BI4G$56,BLZR:GEF:3*E&MR)MFC
+MV>F4(WHZSM,IABJMI'M:>;9/TMS<O**27-]$IZNH6+VZ420!Z>44I.*/;#_&
+M(2O6X!S\%!D%/AQN1&PW#J<EZ3B<EJ3C<%I20?>D8KU[H-N%6E*!;Q)9V+G4
+M^)*LPGFYOC*$FSTA9=K8,2F9TY*3IR>E9Z:/&9N2E$E/7*HW:[7!-&($\RXD
+M9A*;R\\J+77.*]05+,EACI;K>;U9)=3]'E;L5#]3IGHL<43P?9R^*D6&CQKK
+M,8!HJ!G4@>RBA0M).A>7Y.:Q/:MG&TY/;BD]K9]<C0_/+UM87,IS,3=G1&9F
+M[)24<1.0R[I%85FQ;^O$U-6>V6#+:D64/N,L^A\EN(O\YRG9<)I\G^Y2XX^-
+M^1SM58V,RHQ-&\?_)Q6"GH*&>TK1O*E%)0NS"G*,#TM#F9(-PSO7VSO*;E#/
+MJUDT.>)5TH:^W'QX3)'76Y2:+0PJWC>)#`,GBT/E*AKG]12E#]>YC=)'=GN^
+MGC6DU&RQYOTD^[K>B/L9L(=%_H]2<W/G5?B64JFW=D]=F%51X3?53]G\7.B"
+M/NF+G3GLM/%-+LTN*5+/Z9/N*BK+SE_,5J1O#E3C[LDEKJ*Y1:X><G*+_-R$
+MN$AVOM]D8BX%?NY-Y@R[7WR3X0[T3786^D\M)4W>7^TTW4MR2_UUDD>S]YLC
+MOEV?'';BE?KIC*("?ZGYS@(_=9#PRBWT=U?G7*I^7O>,!>R4)<5]L<)^;L1"
+MUC>)IZ1'N6266%9,##8W2UMF@`3SKBRDQ^B6&<0%7NXL*BLU.EDRG)+3/;4P
+MM\+5/568OD&`9FC.TI+<7&/+,@N=!9K0GJ3<G;?EEA0IEX?(5\4J-8Y.EI^7
+MN<OT])_7G?%[6],#[_<IX,-BE"K"DZFX6&G(]#!9.?/+2C7WOC(*Q4VZL'2>
+MQF^=F@='[SA-8[G+GA=>NA`7L8^.X]3>&(UBI?\EZ]Z3Z'8C&'OT/J,#K+PT
+M.\NPWD`LFS0FD;CEI<H_Q@LE104Y)*'9_:[D@M?OE#9.[X."B[/'W%$^RK!V
+M14_I?O1GE<4:C+]KH-GXO<RS:-/]PNRB0E>64RT2^+W4QW/=0ZO@)NPA%P[#
+M'G+GN4Z;>]IK"TY[;<%IKJ61S>RFYP(5I:2\%_IHW:*TT@@?5:I<Y,-OS"A(
+M%>]X1D%FFJ;&%L-/J)?G\#H:D_)*BF[++?1-];;-*6Z4[*SL?.((5&F.XOZY
+MA>7=IEZ%THNAZO':!):4])Y>GFP>.P"K*]D%12QC1A>7J+5#W1`'6_%:T].N
+M8^/:X]N:E*V,:QT7HBHG>2>C+E&QK*)"GV2=G:=W:$5EZAQ7W:R&<HU)DB:L
+M#"-M<J&Y6>QVUCF.999[/'!*+9M75.2UG;SK.SKNXY7[AD1>::-W)N]6GZ&Z
+MQIBDK09Y7'GB5U9^;(/SR/NZV<>LO"Y%QA(EN4IQ\W-GM7;IK2!'L:BB8GXZ
+M[SJA%_-JH<$X3IV>S8X32A,6ZY.>-9>'F,Z;J?-+\D"GPJZB`N,]9)'0BWFI
+MT%G$0Y/JTC>V5-D+9-OD^RQ7I([+*!#=MZC8J>5Y&*E8L^-\#-02?ZE1F<8%
+MU]P%Q46^YGR%TSCDT\89A[^.JW?+A6Q;F%6R(+>DU$=[YAYRIF;K1RL9=497
+M+*ODY5`+U617XTB6!]7J@,M97'"K7XM:6R#PER/+`_YR/)Y\?YG%O+;70QY<
+M!1#7/G)YE+C>"_2BV:LJ)GL#+?0>)##$9.&IGF'1W:I1DCQVXJVD4G@71K65
+M436?C`N88A<O+)VK_HR-DS^I[H59K/6-8+>@AZ_H%H:\P\CC.N)&:!52=VM_
+M%GCK5G]JLL)8&W-7O[<1Q[BK)*NPM$!-)]%5Y)XRF-B`TF.OF77Z4J59Y="4
+M?:Z.ZI9$P\Z5Y:>D9[Y[7[Y,JDPU>9*[>\UTUG7Z\.ZCXPI9,=</#I\EU@SI
+M_"R#WRG#Z=%WC(GB;M6SC`SO^H0Q418*""[TK40M+OC+@.CVJ4B&CI%->?D4
+MFQ1EA6R6J9[&&HF'K[A*6!_T];*Q6TOXI1&/'.'T:A#Q?I0%GR`24NZRG:6\
+MO()WHU]Q2A.]P*`/Z+BX8N(^+T/%;-"SZ->M4F4UV&=V>">R)U#`^"B(R?%@
+M%9'CL^XU+B/;5R9E]""3)%WSJ6@K_=T?F:V0W`J1%N*\\;VG.)_&IT]+RTR9
+M-#V=Y9+RL;(W+E.%27BB`3QO35NK\K[';'G=7O71R.>,Z;J@BL6ZB`J?!4+-
+M9Y>GU#(UT[HQ5YKUW=(0X^$O7?C&_[66J$Q_R7K7M)_L[+(29;GW)`[@73J-
+MP#`)XX_R#8A2;';XJ$R_Z2-'^$\G#NTWG=AU]W3?P>/47J).@?)`UI^,"I'A
+M8AI6E['3T42C:FK2=/UK)[4XE^9<*1S>R6E>E[=N9/@O8&P@)<TKX3<Q>MI<
+M$K+9"T0GEB`H8]K<LNP%N:[T?';S%"F/RQ73LU@QGDBU%<TK44:`LW"L*N8_
+MU[]]J-SD/`^A?WLZ2)0_#U1A8IFC4XN<I:5%A9K,]BA]GH68[&[ON33+55:B
+M?.#)::7=<A=GE12R2/$IY=M5V5ZQKR9"3C<7AE(R2_PFY_I/1E2+;[)F?OLD
+M:Z:O;]V+_"9KIK!/<H'_Y'G^ZR[PEUQ@L'=]KE`RMMO+9]O)N=!9D%4B&:7^
+MR_BRUG)Q9.M"BO3W&^Y1SWC1'>H9_ZDLC60M5LUGJ4Q;:&5/6G9^EIIXX_3,
+MVX>+3L_V%P;5/;#*7UR5W[`JDQ9?:4CCY68R@)4BF[VPV'19'DU^SP-F57@>
+MD/^48+$"J`M*+_0$-B-^41?7;#`SP!)@KY)<O)6K2HW+S!3'9YH*4DV;E550
+MG)^E=64!'A=RILQH=7AL$@]GEZ?(%PUP9JYS;EE!@4?+KBBENW9SAF3#8-&8
+MCO;HRL;P"FKNE=)\K5T31*?6*2%.CX>@K$`%W7A\!%@2+*-Q6^XL<96)/U-;
+MHR_/S8;O7/<\K,SH.(PWTC)-A<&I)N1H;\/IU)G_!G%-U<'HUFO0,4Y#S)@>
+M.SF(19\MM\KK)JCT+,O9+=<?8W-V$VJGS^VA#M^)JFD:6B"X>J(KQCM+LTNH
+M2S,*G;R@14_EFX0IZB=9-(W_4Q6B2G1/EW@LOY6KN"L_&?0,FJ^V,'>>>EZO
+M@*;ARF_:H,T[C2IP@3=D#HI[>DR:1X6'</"34]%S5HXS+Z^G//U";MHXS]]Z
+M-P&93RJDT&,?FS"']%,-;%NY],;)G"HM+G`:XSDT`2M\WJ.OEQ5G*W7=DT!,
+MI-`G25O3CAH?E5E66I)96I*=.:^PC#2XN?QO'H\G(<ZBHKF7*5U8NV12U/^7
+MJZ-\W*`^ZZ$\P8S9A8M5^"T'.0C_\&$?8($&XT>_Z*KK<]':?*:T6.LTJ'.*
+MRE30D\[YF><D`XF8D)\LL16=A7E%'@;$'-K9S2^3'J/WK_#X-JS->!4O[U8,
+M%8Q@]/OH:_'G,3+>)7X,BZPT"#7QWQK2I"&C9)%;>(*/T.<)[9.D\83NR>`)
+M_Y<J1%OU5UP&1_=4I53[+2^+@IJ^)M-#Q*QAC<G'98O6GJZ$-Z`!NR9*%!^A
+M09:;DYOCLZB#72K&Y1PD=ENO4>E^U6U<T6V1!5?X6\C`)84]I'=;<]'2>RA?
+MT$/Y`K_E)TDP*'-6;4%"G.'&72Y<5,N7R)J>2G&OE^=I7+[4XQG0K=UE9SBS
+M/:8;5`Q9-)48,>UB&A`+]0(BRU4TR>.$S,G-UBPO#X/U1"VK%.;YNA1?0RR[
+MNQVF\UCH=*T27LO1_#\Y!CQR1`XK<VH)539:%&6[M-T?QCA^'W]W]Y@LGP+=
+ME%A?ASDW--<UUT\DEY>+9'O46H\2S^JN@,4(*I#@&]8U;\O-,7!'>D/%^A>0
+MK59J%JJ%_]&Z6&ZEY/I$E2@]EUB!!/KIVI%5H6L'`Y&V7H\ENE!MI<@O*UR0
+M*8M47G'JBW7;;-+&^88,&8+IO(+=N)?0.&M']3!E1_F;KZ/\3=91_F;J*'_3
+M=)2_.:I/9*[)DMAGOB6G\CR@_S++/7(@J:0@2UN5T^DJANUN1O^0(4,?@&O,
+M04RC3YIG/=*8H;E?]7:E>%\E.K'0HPBPC8+%,W9).IVIV9XH-173`L#VC"?,
+MBVP<TJ%D/:&[):^%911K6_JR2HUZEU@+;'>H8EDYA=[5/V\UJN>1K$FLZ1RX
+M7.IR9NOX1`YI%3P>YQ46R5CV*"DP&C750[0=W=2B=G5+XP@ZW8X`9YYW-3J'
+M-&EL`536T@BN(;F@B'F,=$9)4=%"PR3)E<VHABZ6#M;&N4>O-O@_?%(Q3@VI
+M^DGA6]QOZCR7WU2_97ECJ9_4"G^I>/^^99U^4_V6172J(367MQ2KZ%$X,U)3
+M1>?5\9:H3-T.)S+C<G+FWNK*+35$CQB=ROK(!6..(;2D>]9I+C0$F/CQ;?L-
+M`?<78Z+/U>DU/=1MY).^5W=CF+Z7%YXV=Y[KM+FGO;;@M-<6G/Y:'V&ASR4Y
+MN:CG[M"_!L4<?/M7STZ,'%^T#=&+M+A<EL9JNFMA9^+<SC$FQ,:!A\$<4BYY
+MWH.\J*S(Y601/9>J\_*!.$^XN5HS,BA#V9Z5'Z,&I=::#"D\78PI"WW+^.RK
+M@E=*M^'+?P'9H5R:Y7'CE!HCHF7=EF^@8GC3QB&45^:(,4W?3TIETR<HG8WN
+MI#G<A@^7`.[RK(*R7/6J<V_+];%G?6)[O:7BC65\+M(B536=IL")U5W]]EY9
+M4-:GL/GL4Z0D1YBY3[)$+RBMS3=+-L%[]AQHW(H4)!W?XJ[SGS-\I.=!E&SV
+MNF?\3`+G_V(:VJIL;L_Y'*Z3Z3^+A9S_'$V+]I_KRB=5G7U4/50K&K;_S+P2
+M%J?^\])F.3E"G$:S5\,1NT3MAY-WS=I.8=E"SRY'CX3A1V7'06'W#"T4QY"D
+MLT1(19]7J-3OA5FE"XS2/C=GN#&6/\=5E*7?8XTU'UY[R5U8[+K5QXW*OOI2
+MGS05X:)/Z.ZBXZ&J#]QT]N0-Z5[..R).6\S7C.I6P)\IU;V6[N943V5&>1+`
+MLCVVK=[R]:9Z+6A$:.@L764%Z?:]]5""DUB)[/:^1L2F.1&Z55;0W;6((#6C
+M`@ZAXBK*,7)0W4#"QB$=W_9_P@59&6FEF>7T?R?;&>K\"7_6OT\Y"!.#WBVR
+MPU<5)Y9%54'1)SV?N(!SH;:):93_V:C;5I$L=:7'J.B?]!':R\C!$]'[5!.-
+M^/KTDEQZ/!7XX#ET(M43BSA=<[/ZS?2Z7/UF9V<5.UW*?/9?@#K:XU\?[>."
+M]Y>C'";$.^9RU\9YE]U+%ZG=0_1L2E9Y'K_;J!DY(LWIV9%@,`5]HD)TMH?2
+M'Q;R4HW(0<T_K^=%49DZHT3=3FMT#I;GBA885KN<.+RF>S(5+L_MGBQ[/KJG
+M\_#`V3C,JGC(L1J#G2.0<IKE.4H7]:-9E-[S`62=$NY(.97$J*CYB@VGW]66
+M@@(H+MG.DNR"7..>+U&[C$XOY57VKHAIJV&+M4T??F4HFR,^RB?6@7.-WBTY
+MU<#C`G*FQSAUKF:U'\KC)^8G][%I_;L7M#F/"-V>"RU6VUR\Y]Q,B',M+F+[
+MMA0*C[.;PN/T57B<_A4>9\\*CS%KL;;-1QM%_)(QY;TK)1XU.<;C4A_5DSKA
+MU"K-E;A9[_YR/A[(`_@TJ*Q"G3CFUY]?XO1)*LQ=+.XL?2(<830R99@6E;GR
+MV*K7K^P2:\!?'J;A)\>O-SH;,EPWB;LMANCR<-+3.$^\DZ]-A+4K&A+^0WI$
+M$GADA13J46+HR_F)`_);Z/25L;]1BP2*\IRYI.?/WCBX["Q>DS)Z+27D7/F?
+M>\A#M2IV)LISO%+:+.E.S9FIQ9_!X2@'M.BYD`NOV.GU6WIVE))Z21JBRYGG
+MU'RN8D]GJ$U'AKF<T]W6S/;U^/&RB$$]P,+):4I$9?I>,B(FM<193@*!6-YX
+M]:CI.,3"?T[:N)ZO4!MK_U]?Y3L4=</6VT73LZ=[5G%TS+%[)+6!/6IZLQKR
+M>@=C]]BM;'_!6]G:YBB=LJ,M96E)GBTJ^J/'?$./NV>J'0:*S8EO55Z^YNA5
+M5JQ^B;3062`*K@2=RQ*)Q\/H\:T;DB2\PI"D&W,JZE0L'7;2>ZT<=GD)R]<-
+M//9^RMC6NX%T;Z*LAW3OZ47ZM$(_Y0I<?M+\E)OGI]P\/^6*"[JG::<A&=+\
+ME,O*Z9[F>S2/+CS-D)93[N<>?NK#%@I#6DFWM&[G]DA0U5QGMUZ@$3//J)A,
+M'3&<3R@H-:RIJ(V0:G.C,8ZA5'0F&M9*<V*>#5>WWGNM?*BYQ3Q!2[UG=>FM
+M)YTU*LK^N%&G\25(7(5!#\**B?>>6#W('.V3$*4[)J5[$\3`PH9QSY8%PQ3(
+MED,IO/O(G-A&YLQ,\QQ#QFLDKJP*,N#50_M[B&Z/T(V9^$H)1&SZF(PD"#)3
+MR]6I$>6>4#(R%TR9DYRE6EC%..\V$A^,C2$:8YKD*NI^#;.=4>*E\ZA).JW%
+MCQL`6U#]QT'T9.QC6ZK.Q"G/*G%F%6;GZB5<]Y<F]HV?=?EL;T2@'Y4G3]9+
+M#.X57>R+_I)B'TU(BVI4.Q>TTV,D`$IG`GE;[=GRHF9+AA;&Y]W,O)#/+.50
+M>FP:[O&H":<WL\AOIFQ"YA6MQ<H$HW9EE>87SU^LQ2-UEYVZH>S'*/3-YCFO
+M2^J6WW.>_\BQ@AY#QY3*[BHK*<S,+<@J+B4UGX_OH0=3VZ[4_GC_AV>J4%:?
+MP)(I617.A64+M97RW`7L5O98Q6JCDS(&#+JD/F3<:3S?D<:9CC]@:::'7#WW
+M&V<(4?!.?:5<Y*F=,/KY'V6PN'V=[4[?E`*CII/G9%70&R3$RZS"Q8UIWIEJ
+M3/<&@)/0P%\>A<I/SF+M_`'A&7A4'0_#6JN(3V>:+E!?GR*Q^MX35XK\G+CB
+M,?1XOTOW<V:Q1*?MQ_-Z>W2;V#Q.'EV:SK>C2UV8NY`C2GW;*2'S^A36_L7\
+M,[Y*/PYS7Q8YRC]_-"1++#V[!DNTP'GE'=(B8>,,FT<TIYM3>S&YO`FY4+$D
+M9?WHAY;/H8D>(\O/#@Z/@T]?Z'2.0"-CY>C!BHK,O(6N1:+N%JIC>>'T5(T1
+M[Q/)3WDPSS8V]&&RT>>G#?CT&(\'*]USR*UL[4(,<J;2@+R!'\;#\_0WAMLK
+M;=;B?*7.3/*<5"M"42<=O4X(CVKN])S/*WJ`]O:)R>/0W<QXM=^4F5"J8>\I
+M"1O7:;,EZI</P$!-PV.UPVVA$?A<D$-<M:BP,)=T?3X_1CE/55#"_[R29ZN<
+M&8>9'&4<87KS;#H-4O]FH#?':-`9K_`U`_^/5[&.C#'N65&5MZF$75;I>#@V
+M-`&L[9:'M:76`9,-]J.KA(^J\$GL'D:@Q8D;DDH7E?@FJ7-&?1.S<YT%OFD(
+M)#,FXA!40Z,G:?X$CVCR!G^*8F*,5<;1J0C/P;&'1=UBM+*SM9AV+X/Q^*0,
+M2<:%6(G'R>8WX;EGMIH6VN%;6$Q*-HZO5.\89T^&LQ0/ZSD7S1`-9(@$TEF_
+MPV.GLFO:69Z;5%%<Z&(-D8:I9GC[Z#)><>,G0TF=J$R])\_@Y$,W4EI1]S2M
+M.W1+#(8_]7OHXGK:?J?+(*W)14(U2^?5]]MH$4%^,M3^+3[PTJ"E>*TEIT^H
+MB9]PU^QN+E"<_*9??M&J@GW0?7W?F*$/--?+GX7EB[7-]#I/O]IDOU@[0[U;
+MAAR;Y).N,]5*>3^I3$D^+[2<1U>RTBIY([?$3GG/9==K(_H4KS;2O9QO*LH6
+M%_@MS"S$7[+_TNP2\-^RV#C]W?0IQE89R_FFHFQQ@=_"6EOUR;H3NG6N*9\#
+MNHTY(H358HUF>GB8A.+0!5ES>:G?)Y&F@XJX-R9+.%V%YR13X13J<`AOT&>%
+MP88D9NJ[H;:G/)]%B-31F9FER9-2DOQ$9.CR9'CEZ'Q6L@2I<S!Y$R!#M(32
+M?/AI9()GN4A5S/>&8#C]^\WXRK*>,KIYS@S!?,9$']^9(6+/F#C/7\EY_DHB
+M7,\GL<)/HH^GS=!!/HG^2OHXVPS[07TZQ%^BC[\--_)7IX_'31)+NB?Z^MPX
+M;5YV]QH+LA=V2U,[$?S<QC?L1DX15)O;NGU7@SFBW^/E),O?$7-._2$FW;-$
+M&_:<0<G+(++$JCNW)TW_Q09-G!C3R>HHT#L<N*L*LDIPYHUW[5KC2<84YCO"
+M6;P'IAH=8.,R<.Q!25EIUKQ<;)[TZ/1:=(LG02V!>1"<V7+.!?S9L@SKE0W#
+M1^GM/8V/&E/AB-+MG=:G>,MH5TD9W[J,J<;Z?%.Y3F-?H7W%!7Z;K7%TWV3_
+MI37IHT\VW@VM*B[PVUCM;K[)_DMK=S,F8V6#QI(GEEW&6/=T[-/PG/>OWA^'
+M!70?,#AZI=LW+OY7*6>I)VK'3PV^*9[SP7S2X:LP)NJ#\+O5[.NN\Y[JI<WJ
+M9)^-D=IG0XPU>8XV\[U#5/>D<:*7II45YJ8496=)M(C>TV^TXK$<I#//<5:&
+MT04/KQ""+)1-`-MM.@X4\WP')ENVW?&%;-:I"J?+R;K>@UQ]CXMF5UM![D+#
+MZH$G!-\;,>H]:%_6!)1IK^*U?3\5D^KLX701.=W,8!MK0E(G[2M\$MA"T^OC
+ML@F&-P46&-Z?C^6IE):>\GCZ]9C)D[#GS--=R1.RITQ?_JN.G?%UMSH+X6[M
+M[I8W'J1@2/:_)<YX((-/<K<-<<8C%GR2"_R7+O!7VN7$V]4?/,R11^(@\ZZH
+M<<`%&>5:#(5^Z622L]1?LFQ&E'-B=,8TULY*<+HK>Z6[.;G'ZYW<G*O9:'ZR
+M>_H8AMHYW7.6WR]E2,;U(S27YO#8S"+Y2_9EG3XW;=SIK^0Q_O_]:N]1T_(Y
+M,,^9&3&RXN?AF..FI4S7N`K'5^K=)-WL$_TYA[I3#D]SHKC.I2&'G^D.G?:N
+M`1E93(\5C/`-056VMXKCYD%9JH4G>*+7$.[NY2IEILP*+-?!Z\.!+SI\VK`O
+MD_]`+TTO]./P-?7L"S;U'/UCZCF61WL8OUG=ML'IF(2'YWKV92FYA@!!3T"3
+MSW>./-PJQYBFBOFF=2LGW\(R5*=Y"+TIA>JH<6.ADGG=6J',$T/MV46^5144
+M^5[7_9L0Z<,-IW.*Z/5LQTV&(Q%"6-D/<G*!TWC\(;:BD"9?:M3DE3SW;-CP
+M?IF0#7C-+^YW)WH.Z_Z&2%G]<HOR^>`,!9US1TXUUQVZI#]`S?^Q7&F&+]'I
+MXAS*#<<V:)^,,%PJG+#(9T^A<3%)GZ[W;1G4(S^\%,S`X$I3(:QJ0=+@48G3
+MG;['S$T^6&.(_<GIUO:YBOMXF$FW_&QAU]QGL9,*^<QC'?`RY)[R]5M_==MH
+MQ8_A>]Y^MYOGF#1)ISZE85AS\.&HGF_Z>?.S2O]7&5[FD.^]9/K)X?`X'"9J
+MR),K9+=1MTR^J(<LK4Y_Z;(WV?=&E#C<;^J(;JE\3QI,I=T?Q4^"H9.[C>?4
+M[&YE*O2K5S[^+S$O2F%?:.??>@),O;Y`G;M*!4LO5O8ZG_RCF>P];0'1;0GN
+M>0.(L9#?+2?&(MUVB!BS_>X/\:G!S^X08XG3?"E(SW*[?WRGAUS_EVO[^;PG
+M&77??NP]C\.3Y'MVQ_\JZR>QU/?<,%W>0G7>NY_TK`J_Z;H#0/2E9?6F>T9Y
+M5HG_)KERQO,9_?[NH'U/2'^4B2[?Y[`1_96>`/"%PPT[RYS=)4GW*59J##GS
+M+`9Y#4Q/TNCN*5J@D*882GRF!`=QP)4G/E_6*`NT[Y0D(_38.+F]RS^9NL_1
+M^`0=:`?V^@FH\Q=TH!VM4>"SVJ/K)TGPW2.!8@;M%=],A9?4>XB37Q>'WS,F
+M]++6>_:7+K';D7`ZGZCRD:@@5?$*=7M8GP?S]UA:"*X^%,;'&)XN.[@,RUP>
+M3RC>9`['_^:ZNGUZ33X,JGTN&,.!$Q>5JB\6,\LMR.KV)16U!<03>>DW5R^-
+MB=D8)+-:\^LI-PJ&@@HJU)TN9_(L"'MBUCUQDYXS([NQR>S3?44MN\=OFYVV
+ME)ZY9O\/WFKX]J+.N^%QN@_OOG-&?\BV_GN_VEX[HX=>_]5>_?(UTLME!OM\
+MN,+4[8C1#(G,]4DY7>1>1L'I0_<R"KK'[F44="]QNEQ1[PWZORY`TZ.)&I:N
+M-:=^MT3VZ^N__:8W/[I],EQOBWB.U]7BKJ!T^MZ`'=;=$MFOS*=\Z-^!YT/7
+MI?C0-2N^WCBXX3'JS^OEZ^<]Y[&&W/-5HD[_O[]R(<ZI]%WZA&:EVRW@"3X2
+M1JOM,/!)9F^([H01_;F")=Z/\QI.0=#R>4M=>7:9G_>#S_'Y2S4L(6G17#Y1
+M!=G>\XL\'YM1$E#S[I=ZSO_WOC7M+'L_R9ZADB?'ONBL1,\:DL&:\8YB@V_9
+MWY>_]=\G]FC`^KBOL1RGYO-9&\7^NYWCJ"REA:7*<HKR_4*.QEU\$WW+\<=T
+MNY61C^[^KW(^!SO[9ON<#.V;K5^RZ-X"_7/FZ=Z(]U`AW<*NUT&.55G/^C@-
+M"./8\2P8\#C6??=$;X-X!GB:X3`=_28@GQS]86$^6?H06]^LGJ_2GY3ADZ4_
+MALPG*[?G+/U!&SY9!3T_5TD/607S#&O-.C^5[FJ?I7B=+\38"ST^JN:7,GJV
+MU&OPGZ->@_\L_9=A?+-ZODKUFM\L_?C,,6J9WGUZWI,_V4$D>V>\^JIV^5R?
+M;?6RI5Y<FGFEF@>3__)^+2ZYVT>`LKW:JT<22,7P.O#!I&2G%[+J[R?VU?ME
+M;G9;^9R8KC].5K<55TII9\[ZR_-&_77+.NV9M?K]ONJ0UZ)LCP\149K:V]#M
+M2=#Z0I0??$=3\^IQ*)N..6>K[^GH-EFS:>'LEJ;>C/`<C3>6E!H_WE!2JOMX
+M@\&[*+YVG6-1]_TE8XMQD(M1%_07P,%LV*>0MK6Y^\4&45SH+,C48UZ'RLTJ
+MU?L&/(^B?;RAI%3W\08^2S69/P7''#2CM)MM".V@IXTGI]V4DC;N-)=%]1C%
+M?]J]+%J=_B_31KOAT[.C_*POCO*_N#C*S\KB*#_+BJ/\K"F.\K.@.,K/:J(N
+M+:_'>WM]M&2I&/RURC#K(9<-B05PK?A\HT7S@G1/[EZ6'4)^RHGSZ/]25C[T
+M[B\''WKWEZ57';KG^N@=W0OXZ"U^'D#'CHT*1X'/ZA`VR.9ZM[F),>+YO%?A
+M?)\E%OE.N2$IMZ+8=QVF2.PD75*IL]!/DF^*G.AA%%5^[%0_;A2#SR3+U>T<
+MQ#3#`H:V`=IPB*BA2,'_+N(C-'7>4H,#)G=A-J]7J"-H<*J-QH#E?#P)6:=I
+MX8U=5T$^W=/_'_;.!LZJ:?__WWW.-$5/4X:2,#)(#TPU:DKTJ$(/(T519J9Y
+M/#4U<V>FFBA&1HHN@T$R&&YN<>/.)<2-1KINR!5""(-0A!`.8GZ?M?=GG[WV
+MWN=,N/?_^U__?^?U.GW>K;7.GOW=#^MY?5>RNW",K*Z!\9Y%J=%C//XEG1,)
+M.?.UK,G,SNK(B+<US<\:-PME]2#D;!2JA:CB3ULG;;7H':],;D?F/A?O5J&3
+M$?%GZ^GJ<T4.MQYU?:Y.D=F)4:C-R\9EM!=P\O+ZP]7B<GWW4:THZ>=XNN@7
+MF1UO^SGW.48P]\E28V2JS54::4Q&_*]IGM?LO^*>`&-V1BJ75J97)6=',7N%
+MK'>G,5>2*+^RO=<T^;LHU27?@9Q:3XG:BKF)>%^M:/]IFTBB.YG2$UC>8IPQ
+M#:V(8&^-[@#7G'_DZOR+7/&<*'V9$ZV^3'V$J,@]0I0]DWLF.<U<K<6K%8].
+M$Z_8V^;CC&$G0%O#[5[`[>L8G)"B.OA<PR5F*]/97\H91L[6G1K9'1$<9E83
+M(2+[83HST$(Q=EJS?>Z4ZIN$38RZI#TU3:\+>_PRN2.5XW/S7+41"+WK75OD
+MXTF@3_P9;VXKZ5\6@]+;$\)Z@C_4*OY_P>^C+\")3!_RA=L^Y5PWS&P;L$_/
+MF>,7Z?I1Q4=!B=@3.]WK"\JM7IPT<]>ZG%!)2$NG=0GY4YF]3<6SRZ99JVR=
+M@[M>@&B'_V7'=P[H66'79%K7WI9-)(Q,"&@JD=TC$B7-S#GV.(@YKJMZ65!V
+ME!?C+ZO9&A%W@%HI[ME^Q_8%Z.HK+!WA/!*>+1_U+K8HD?YY*]I;;?5-1#KD
+MG>YXL_X1/<K.[Z/%X41+\MGIYI1ED6UG_'ZJN5A.=^@5$GO%ECNPM#@KVQ\:
+MQ?>#Y]W.#HG'NX9[5;8>&B5AAMJR0@T4SS-+WE)D,3.S8&K9'+.RFF/O%V'M
+M=Z"]@--RR]RC.GJ'@\KZG($4)UN?&'+E\9%K;>7AX^W%:KZ*>;J=H]HC7&B1
+M<J<'J]:MUE!S+,#_1#0U=!0U.LK@D2O=F=XMD'&W2T/6*7(MW]PB<W*6;U&S
+MVO;8>GXT!RFNUK5>R8CXV'`'SLT*E16'<O1.=W.;7*UUY'A@G6LO/R]2)9-^
+M"VU?MNY)A6;OJ2JJK86^PS2G0;;_`PYU^!<:6X<H]&QK8\ZJ5Q7?4-'L4G=5
+M5U]O8992NA<-=W5`%0RZST-M*K:>_6L>SI+=M79_-5[-_LF+TJ'B#8ZL+_5&
+M*!-S<DNS,[Q_J21KKB_,]G'O.;::I)$S;Q;LR&[204N4S5(]<\B:B#&[E9N(
+M+BII,CJWZ6C5Q=I$M'LS5U^TN7Y"=Z#J3>'SI^V*]3JBU-K;9CYOCN9DE9:9
+MV9K94>KJCXVUD+W47@5@^@%PFE#9WIUN]3EVGG&?OL[^=U9OHCUWS;^2W^S=
+MC/C^-[LNQW/$R7KTW-[WG;DA'+PP5R-8.UKI&2ZJN?I;5%32='SY_A)PCZLF
+M4O@S?4\"E[=/O6?-U1$Q.T9X9-6]$\3%N7J0U8AUCRF8!7YAE($*;Y@OG;TR
+MWSVLXO^E>?$\8;DE48Y6YCN<9^*%,W/5V:9,W[_1U4T292=+5WSY_A)$-BZ+
+MF<+?+>1-8`U`C.#46*OS7]MB756,[&Q>FX&C-S\B!W$'JKI.7HG99>^/*(GR
+M`[-ZZ0[2Q_*CS2K0-GFUG:Z8GC?M;BS+S15K)WH)%9F>8PUL9$TKLNZMUC;S
+M_AWOW`)[:H'9-1ES28!3-%EY`DHDY6'#;/H[1;VVDXH3J/8Z,BLISJ[KWB2>
+MD0]KD:A[,$3_*[EEQ5Z'M-H0GS/R9>[UHOL<G#/7;CWH4[.SN2"_-%I,9+VL
+M/7CKVF74N=M:4$;&[)G(`$)](CNCA;+-QJ3R9F4M+,M7.QJXYD^I:=/^L-FS
+MG!X,5X0^2=UWG,CT:U>X,T7!$V%E0[H_HY!KXV''Z[;3T-+9G#80J9%JW2G.
+M5CF1(]+M4$C?J=?RE^U,G["K;M::<F>]7J@HHVB:JQ)BOM<A3GSR=I!-Z.7J
+M;D+)6%:2I9Q&[B>ALYO=?A(6%>>5NSNIG+U.(RMFDEUE;+F:AZ7Z$ER3>/1Q
+M''OK1GT82`_++_.'%48)RX]RO,(H85DY_C#O%I/:2G17&(?976&QW=)'JS[Z
+M4WAK8KX4R1G>H%_DI5_/]#T1=J=!]-/=WPE9&8#OI_:4&]N+%]=`>T/US#QF
+MY)E1(O-"J*9;3Y+3H%(^_;QAKJDJ9JF",L*]<'RB.3TJJAMAT_&X.<$MNBMA
+M.]ZJ(UI-8+-R&(K,^<0%+LLM+XNV^C([Q/:'*DN*9A7.BYY$.V5K0*+4[^<R
+M)^(1UAYW<,9;4&]PC;UDE<:.S2M!Q@:)N`)UVK>1ZH?9ULTMRM/F9*DVM%9$
+M.2,HD6M<J"WG=ST[3G,8ETD=.=+'Y;W4V=JZABAQ&5HG+?)A/8MW.PL+:=M-
+M:T'<NUIO#;N:P&XGD>;][&LYRRET.DI<?W;:Q;DE1=ZNFJAKO5*T3A#Z*;>G
+MFF0HMYYSN42NS%F8,;O$<C?F7'6SU/"$12QT[9EGCB)%"U?98=2(HI(8$;FQ
+M(E3NZ(^PW&J83;^AYZJJL;]7(-*X<K\+VEX]O@C-NXTW2O=OXXVSIH[BO<_S
+M+$<WO4AXJD.:@V[7<EVU6#>K.$:$:FQP-3+O6U9.3BS/=V8A'3L2!7/L2&M[
+MVEB_+&KB;]KMFZB1/J\L6EQY4Y':('34^)+]Q/M=LNA;7-B##]8D4>O9<M?`
+M<EW=@M96IKS3=K>;WKFH#1V)[835?"*8I<_AQ%.G.C7/:@'HLW0M;UI%Q1-#
+M3E%LYI5TM:A/O7+Y68PT5VR_C#$=Z$=+''.=;8R#-^5XWY?>;$-HC9EH.7-V
+MQ&>'+SSB@X>E;V1+>]T_>G9(V^30%Q&YT+XHIXM"\P9O9S&NH-DQDNH9_/AA
+M[OY.K:[FCYU3ELRY`'ETN:GF2$16IGOZQ'3O@=YAT*8ZQZ/%1ENVEM+DLK64
+M_2U;TQ+XG;^)]ZXFF[Y(S"45*FMU]<Q%=H[Q%,_:+C&^&&>C&%]49,<97XS;
+M!;-Z4V>:<^Z+0\JYI#V,Z\Z.LX4^;(M*W0V7(F?CO@S7KK-IVK8F:<[^)*JK
+MH%@_0'07**87E)PBWY]S>K.UHCO']5\4-&:C.9>[XU@+BJRMB(M&1#H2(E5Z
+MU["LXWB%34O56/8X/\3]+])])3K.\'+<_N;4EGME6;/03@VAN9>B%Y%\E?6.
+M"'4[\V>Y'!^:PP:1JH_9".<L,7_7KYX1>`Y;'N.O17('3X1W6K16>FBC7E%B
+M/5.CHJ2P2O#"J'%6`1X]SBJ_H\=9A7#T.&^WIJ\(CAZ7D3$;E0*S&T9;11&9
+M$.MSONE:RAB*+%@WWW7=VU6.VZ%5CKMD'.\9/>-:])BQ:@Z,OKMOCGOW8M<6
+MAX6>Z;^%^O1?TU-`*+_0['`LQ>OCKF/;$R^<%J3^CHW7O`Z9S8^(*X7(WI[V
+M.)JK5>HN,9R:@.-C4+TUO?2WQC^*KN9GN$/L^1V^4,[OV/_OG?$X?UST@?ZF
+MQOF=>2'><,_B0K-7V!P85KW#47S?C%<UJ6)KBXIA_36W5;E66>(*BY),>0-!
+MPMFNCD+\>J3E>5D+&NH+R8T2--875*#V+8WV-Z+W1<;NBC1/-FN.IR-28GC:
+M<*>AFV!G*:/[@;<GB1?JD\1SRW.S"^U.WB@..,R--U!HE^I[E\W!VXZV>Y3M
+M&JSWWUKB9&7BD96S9I>%]FK:VW59+=9H=2WEFCEK5M0:FRH49H2*M=6HUHQ;
+M#LB9_W$\'K'29?YB;JF[G1]I,D9F>[DBK>F'KH?1,TQA[Z<4.X5OYU0K,XFQ
+M:VHD,LJ.J9$X]VZID6#73JF14-\NJ9$8_PZISJ$\NZ-&(CP[HT;",[19>)';
+MG*SJ+&ATE7DF#;AOJC6[`IE7K$4%VBK;6&L$F*3$;J/,+,W7)IK8O6NF_Z3D
+M4M.E^!B.Y_B6(N5PWL4<UZI+CK]H(R.Q[UZ,[=B<:,WU19388N[16>H>-QGO
+M&S)I,C;9,^CR"YQR1!NW]QQD3IDWFTG/'J^F/86RS1J7?Y%[K,7O8L[(R_:$
+MV2N07('F8(GMD%\?*]&+4FMJK-EQZ*TCNCM[FHKTC/&X_FMZ^+=<2%L^7571
+M56CW4Z(ID1?934N?`Q"9WLHN*GIX=P=RQ]/(ZZ%-@RAV[HWMZI</JMO5KRNP
+MN#!*H,?[E=O9KBO0]I:K!4;Z5K0P]_I_JU,N0TU5SPOE%N:4^@+4U!U/O.7<
+MI\DT>G=_K+@S_7&QAZ1"[C$NJT^IZ409]CH_<Q-4I[5GYB>6PS\G/XG,-/4,
+M6,V>%?K#[%S;:Q(:97FV`S5M31ZW7=#F;]ENBMD;XL[[^T;?)KMO[#VR^S:Q
+M07;?F+MC]XVU-;8306<'D34-EJL#G\<`_]XCYLPT;9,^;0VU9W:Y5MS;S=A(
+MJY'KW_M[QD',(1AS%J33W"ERYJ"5Q_B9MM#>&Z76[IUIET`ANL_R!*EU?[XT
+MUC+M_:6;:R\;E8QS(YW'KFX"#F1IPPZ61PE5(8QL9<B-^*87F=Y[].J)O=+:
+MTYEGO@#ZMJ]1N_Q<J?3Y?%;5+VO6/.1P<\U2QNV?4IVB.4<ARKP0+=8_.21]
+M3K1BR1EXCQ:CQN"M<2$K8[6J`=8RTCRUO:;98/&Z!\IA\]7:1HNU@FBIM&UH
+M]1<5OYUF[N2JNTAC5Z;6!"WQA6AIN""IQ!MR06Y)D;W$(HK!UA2!:#%JMH"5
+MR40FNM@.2U)"D:$-K8;5/UI@KY0B;[#J&/>\'+E<5.0LS8OB_R1W/W=!=]1H
+MF>8:V->#9N7Z@O+]087^(.WP?7K[#F\'S<KU!>7[@PJ]09;C2RU+CVRJX@[C
+M^"([5T9:#5=7:]0?--8?9+8]K:9+J3M&[9RB9AV;?U*/*%6S9K(]8<IODB=(
+MK7+SA-F;.WB:IVJ*.MN_:D<[SW&L79F\+>/2F"<>Z7'6>YG]-3?5A^$.L?M`
+M?*'L`]G_[YNH1;HG</EC8W91_H(]G+@+$3M?O''Z`EJ_;<G1_B!NB#T0X[H5
+M3DO&%1SQ=Z!M)J=/N]5WG3.S^1Q/OL7>A1)?B);&['%PI3%#Z%/$[3`SLDF@
+M+SR6'^-8;HRU9J"YCL,:>BFQ-JG)+9DYNRS+WK/36I7D]C'NJL%%'-"X5B6%
+M7/UXXUUE@N7,.VJ<-6-OA+4I`QX>J]_/5<EQ/-N@;E!:X)O7C!MM/EKV<^OX
+MFM!RN-ZIOAS.#IJ5ZPO*]P<5^H.TPZ>F^0YO!\W*]07E^X,*O4$1EQ&\A=;.
+M7CF>O;*0-^@;<7$0/$:T/0P>(]H>"(\1;1>+D5=..6-0/CK-I;Q6?A\I757.
+M[EKEHFT,BNJRVQ&;/SPW)ZLLR^?H),?GWR3''*[0%C)%5@DZ%5ASSGN3*^BL
+M1SK?>:*B)]"WV_$GB/RER,,=[2AE&45Y>99?1E=_&Q>QF8Y/M4QIO"\5BLKD
+MC%14]_%O=!]..?K)Q%ZPIZ>*M6S.S%>=$4Y]B8`^3NJ_?E[/91DA;HYIIV#U
+MB4-LNKM6U3?N>KVM(+NI5(34,98G.8F:]/#M31S5W[>=R.RC4E-.S5XI>T\Y
+MNV0>VSO%Y6G:U4&N2H=I16K"712?]W96EFUY7%![AYIMM*&SLV?DEI5&\1VM
+M^9^S!_KLV^8:YG,%.H-\KN`Y5K4U<H6M1FH4)XIFEY:3[5C+E3F=W)D6ZXUQ
+M.AV\,1$G`^/UO9C-/,`?GIRAC[2&2O5B0>P.4@X]1X)SBLH\2Q'3AX4B<]#-
+M?0V\F=BL(E;:(A.>U+KD:>:%LYY.O:]\?*%Z=F87]W;V7]%^Q]U&M#8IE\'E
+M1'.('7&.[W&#8&.&=M.5>XV(:W<\JQEVOTBAMR&EA9C-)K;@G2Z)B=R\CLX+
+M[?%+<_JBV72Q.^OXEA;,*RZRWU]G]4MAD7KHO9F"-7;O##-$[HPL^Z"9&"(2
+M$.N3;3YJ<N!SX'/@<^!SX'/@<^!SX'/@<^!SX'/@\Q_[M,`W84\SZ8KO_CZ+
+M/[#29"+MLJ^:256;.`GWC),6E\29X;EHO!0D-I.D%_$?I$EK8>F!SX'/K_U4
+M[?JAL;$1NO,K:!OH)]"VT/>A"=`WH>V@+T/;0Y^#)D(W0`^%/@[M`'T0VA%Z
+M'_1PZ-W03M#ET".@-T`[0Z^&)D$70H^!7@P]%EH"[0J=#CT1.@W:#7H!M#MT
+M/+0']"SHR="AT!3H`&@O:&]H'V@W:%]H%V@_:"=H&K0]M#_T8.A@:``Z!/K#
+MSXV-0Y7]T#.4_=`1RG[H2&4_=)2R'WJFLA]ZEK(?FJ[LAXY7]D//5?9#)RK[
+MH><I^Z'G*_NADY7]T`N4_=`+E?W0*<I^Z%1E/S1#V0^=INR'9BO[H3G*?FBN
+MLA^:I^R'3E?V0V<H^Z%ERG[H;&4_=(ZR'SI7V0\M5_9#YRG[?VILO%C9#[U$
+MV0]=H.R'7JKLAUZF[(=6*/NAERO[H0N5_=`KE/W02F4_=)&R'WJ5LA^Z6-D/
+M7:+LAUZM[(=>H^R'+E7V0_^H[(=>J^R'7J?LAU8I^Z'7*_NA-RC[H;<H^Z&W
+M*ONARY7]T#N5_="[E/W0%<I^Z/W*?NC#RG[H(\K^?8V-:Y7]T,>4_=`GE?W0
+M]<I^:+VR'_J4LA_ZK+(?^KRR'_J"LA_Z+V4_]$5E/W2+LA_ZDK(?^K*R'_J*
+MLA^Z5=D/?579#]VF[(>^H>R'OJGLA[ZE[(=N5_9#WU;V0]]1]D/?5?9#&Y3]
+MT/>4_=#WE?W0#Y3]T!W*?NB'RG[H1\K^'QL;/U;V0W<J^Z&[E/W03Y3]T-W*
+M?NAGRG[HY\I^Z!?*?N@>93_T2V4_]"ME/W2OLA_ZG;(?&E;V0[]7]D-_4/9#
+M?U3V0_<I^Z&&`?NA`>@%T.;0\=`6T+.@K:!#H6V@`Z#MH+VA[:'=H(=`NT`/
+M@W:"=H2VAW:"'@P]`AJ`=H;^@`SP:.A7T"3H)]!CH.]#NT#?A!X+?1F:#'T.
+M>B)T`[0;]'%H=^B#T![0^Z`]H7=#3X(NAYX,O0&:`KT:V@NZ$-H'>C'T%&@)
+MM"]T.K2?LA^:INR']E?V0P<H^Z&G*ONA`Y7]T-.5_=!!RG[H8&4_=(BR'SI4
+MV0\=INR'#E?V0\]0]G^/_$[9#QVI[(>>I>R'GJWLAXY6]D/'*/NA8Y7]T''*
+M?FBZLA]ZCK(?.E[9#SU7V0^=H.R'3E3V0\]7]D,G*?NADY7]T`N4_=`+E?W0
+M*<I^Z%1E/S1#V0_-5?9#\Y3]T'QE/[1`V0\-*?NATY7]T!G*?FBALA\Z4]D/
+M+5+VAQL;BY7]T%)E/[1,V0^=J^R'EBO[H?.4_="+E?W02Y3]T/G*?NAERGYH
+MA;(?>KFR'[I0V0^]0MD/K53V0Z]4]D,7*?NA5RG[H8N5_=`ERG[HU<I^Z#7*
+M?NA293_TC\I^Z+7*?NAURG[H]<I^Z`W*?NB-RGYHM;(?>I.R'WJSLO\[Y*/*
+M?N@R93_T5F4_=+FR'WJ;LA]:H^R'WF&4'Q[OJTNT_R^MXZC^_G"C^_][&_WI
+M#OV=U=T.G.^!\]4_C9YG^I#_\O-M_U]^?D:3_S=\Z8/[.5[<?N(G/>#_>[L;
+M_\_:X\T7[<^'(S<_,77%`Q,FAUOOOB2[\LUQSS^SR3C[_%,6M#R^Z_J?FK>N
+M^_R^.T,OG9;5<=O[4^(_?NS*MT+)?]E>%WAS5NMGSDBX?4?CGWY.+GEV7,'W
+M90V7[NNVJ[#WPX?,[-MKY7T=9O_YBD][/W_YW)[/_G/L,;,[7K9FQ-<]VO8Z
+MY/[NC35KWQMS6/L_'I:[ZMW"AWNK<PC\6_=G_^F;^B2PS\9BP_PMM8(Z^->>
+MS_[N?X^)QK]Q/XTFX]6SV9QVJ?,X"-\DAA],5NE;:MQ6+"-5FG;X5O`8[<DJ
+M/)$<8'Y9P=\>1E:]4AVT](=KZ8_4PH\FM\;W&)Z\2G,L69U7,KD-Y`2R^NV)
+M9&53+RT\E=P1TH^LSK\_6>6/`\C'0R;SH5.V9I!5+2>+K,YA&KG1\_'GPXWZ
+M?QNU_SK_<:!1B_9$F>`<T9/)FW^[T8YO=!V#(8VNM*Z_XP2XX[0_Y_I3_A-4
+M\M^05P1_0U[8?Z]A/F.]H>KWW:#JW3@6JI[;(Z#J_B=26T'5\],,JO*&G[\V
+MS&?N6ZAZA[Z`JF?D8V@K:`-4/<_;H.J9W0)5[]0FZ%'0>JAZ[M="U7M4!^T,
+M70E5[VDM5+T[RZ'JF;P!JMZ]JZ'JV5T(5>_<Q5#UOI5`.T$+H$>H_F.H>O8G
+M0=5[E_ZU.X](\ER/%\/6]=@4MJ['AK!U/=:%K>NQ-FQ=AP?#UG58';:NPXJP
+M=1WN"%O7X1:H>F^OH5:&K>NQ(&Q=CSEAZWH4A:WKD1^V[,T*6W9>$+;LG!"V
+M[!P3MJ[/&6'+WM/#EKW]PM;U20E;=IX8MNSL$K:N0Z>P=1T2P]9U;0U5>4Y\
+MV+K^$K:N__??&>:U^!JJ\I[/H5W4??S.NI_O0L>H^P@=J>XC=!#T:>A8=7V@
+MIT,?@0Y5UP4Z''H/5.4K-5"57UT'[0I=!%5YUB70;NHZ0+NK/`?:`SH.VA,Z
+M''J2LA-ZLGH^H2DJKX2J?*X=5#W\+:!]H/N^-<P\[ROH*:H,A_:%O@E5^=_+
+MT#3H<U"5!SX%5?G?H]!3H?=!!ZKG#GH:]$:HRO^70(=`YT./@Y9"55Z<#QVA
+MGK-O_67/R+$3D\:7)W$GFJ24DU+Z1IZS`,N@%BR/DEC.5/PO)#BF<E3[T,VA
+MFS]]?<&3*L]+ZQJ0ZB,#L@/?-?C&'160U2?ZPZ+E'P'F.W$LYRH8US`@(!6G
+M!F05OHGX;CG5__O"@8%?77^K^+65F/_+GVCUG39G!N3K40%Y'=_'\5V);Q6^
+ME^);B&\&OB/Q/07?9'P;1P;D+7SK\7T`7S$"P;AF\<U;''1PRU:MV[1-:-?^
+MD,1##^O0\?!.1W0^\JBCDX[I<FSR<<>?T/7$;MU[]#SIY)1>O?NDGM*W7UK_
+M`:<./.WT08.'#!TV_(P1(T>=>=;9H\>,'9=^SOAS)TP\[_Q)DR^X<,K4BS(R
+MLZ9EY^3FY1>$IL\HG#FKJ/@/):5EL^?,+9]W\27S%UQZ6<7E"Z^HO'+158N7
+M7'W-TC]>>UW5]3?<6'W3S;<LNW7Y;36WWW%G[5UW_VG%/7]>N>K>^_ZR^OX'
+M_EKWMP<?6O/P(X^N?>SQOZ][XLGU]4]M>'KC/Y[YYZ9GGWM^\PO_>G'+2R^_
+MLO75UU[?]L:;;VU_^YUW&]Y[_X,='W[T\<Y=GWRZ^[//O]CSY5=?[_WFV^_"
+MW__PX[Z??FXT#/,!Z-#:L!]#P_YT^T]<7^/_\T^L9WG+HL`OJE/L:?SE_4[J
+M__L:?S_MX?;R^_[\N_?GU]8S#0\[7T,,3XI)W8(ROWOTH^_NX80G]72GV1'C
+M-YD]@R+_#]ROICY-O9$5%P9E-;Y;\8V;$I2ZJ4%IP+<:/`E:=E%0$O&M!*<B
+M+`??@?C_.FBKJ<'_^F>^_>_LGAE1Z@-&A54QB]]/O<&HC9ZN1;2_$^.8\BO^
+MOOHL3KK_Q__TM:G\#<>L.R2^R>NZZ#<<,RXQOLGWY^K?<,Q)B?'[3?-;SG5U
+M8M/V3_JMU^#0IJ]!';Y3#HWW/<,K/.5#[>^D_#Y85-L>>2%:*O%HO;=`B_U@
+MM&Y;H47>!JWPA!CO[+Y?65Z&?Z?UFV;LFUR`[Q_P4)S22N2@T^S8/8,L36:?
+M[V1+!U]GZ>*G+9T>-K6B\J0A9IVQ?;:IE:_?8FKN"R\H3<JH#:AN@IUS1O53
+M>G=UIYG0P1_6I-P-K3IJX[K7H*G'?S.CU3"I:.@W[^DAPZ1VVY7GI\X9)IO&
+MYL]\ZB_#Y+3K,W=,>F_8X*4/EQ_YUT.'IW_Q_FL[.IT]_(97Q\2_N*=BN/V[
+M#K.:/?SPVAM'?//]H%W!<6EC>A^9\OVHN0LO&+B^]+*WQQTZ>]V2;;<\^'+-
+MP#XK5[UZ[+=G]C]MY=[A/[6]I_?MMRQ]L<7C%QXWK&AU3M?X30?_;]\/U;^4
+MO$(DY3&1FJTBZS;A:5H9D+HS@K(I*QA)DXXTHQX7V8XT.Y$F&6FV(LV.K-]_
+M_>?`Y\#GP.?`Y\#G]_^)L^NP>YJ98Q_-4,?(W&;UURM>=Y^88PF*D_XBDD^N
+M.5_D8O+2<X)R+7D9^"[R&O`:<CUX$WD[>#NY\_B@?$'N"@X8%B><&Y2.Y*H)
+M03F)G(EV\PARX:2@3"$G9@:EE+QO@R'5Y#TX_[7D"3C_M\B#CQ'91:[/"(H1
+ML'AMIB%)Y.J](KW)Q4%#AI/3'@S*9/+.)4$IM-,,#DJY?9Q'1):01QTI<C.T
+M.?Y>#[2;:NS?/AJ41\B)=P3D)7+.2$/VV6G.,Z1YT.*&KT3:D<O"(D>0NZX6
+MZ4NN`8\A[[PL(!GDM95!V&!Q^L&&7&RG`5>2PP?%R<WDI5<&935Y\)4!>8Q<
+M\:#()G(<VK\[[31K@O(S.?-+0UK%\5[/%#F!7-5-9"1Y-7@&>?[I(E>05_0P
+MY"9RP;TB#Y`S+Q-YCIR`<WN+7/&ER!?DM?C^0$Z]+RB'-K.N^1:TETXBUX-'
+MVN&'Q<N%S7C,HT3F,CP3+9%*AM?@@MQ$3L%S^U=R#O@%\N8"0]XA5^%E^8'<
+M,1EU]WB^"\>)]"'O.!'O%#D'S^$4<OE-02DBAQ\(R)7D[>JXY![=@K*2//`3
+M0YXAIR\QY&URJ]L,V4.N`C=KSF>LQI`CR,O`*>341PP9:O,SAN211T_'<T*N
+M!U]+SIQAR-WD=>!'R"F%ACQ'WE:$:T)N*#/DR^;6M5W3+EX:&5[[+T/:M.!O
+M;Q8YD;R[+BBGDS-K`S*.W&JW2!9Y4HLXF4/>?DU0%I/+GP_("O(J<+V=!KR=
+MW&)S0,+D5'#B0?Q;X!1R%?AL<CTXG[P'O(C<^86`W$,>#7Z*+`^)?&BG`;<^
+MF-<*W(V\"3R$O!4\F3P)&68)N>/#R$/(V\!WV;^],RCKR)7W!N5U._P)D8_)
+M2\>)!%OR^J\.2&?RGL\,Z6;S"X:<2M[YMB&CR07O&'(1N>I#0XK(E9,,64!>
+M,\>0JI;6/=U\4+S<R_`6_S!D,[GV9)&/R-4I*&=:,:]`^!'DNEY6F];,QW)$
+MSFQE'7/QC\WD(G(YN)1IREH9LHC<H[4AM]K'Z6#(:G)Y6T/6DZO!+Y,KVQGR
+MH?VWD#Y,KD!!T[(USS_1D*/(2>!>Y(3JH`QI;9U/%?*'B0RO0#XPG3P:Y=>E
+MY)THOZK)Z2B_[B.7G1>4)\E+47Z]0\X\,2A?D^N1G\2UX;5">=>9'$;Z/N2$
+MUG$RE)R",F@">=)7AF2UL<ZSS(B7<H9O/%OD=O+2T2(;R*O'B+Q#W@'^R6;D
+M8\EM[?(=MI%7C\=QR97G(G\DKYT@\C@Y#'ZKK74."0GQLHOAF^M$?B3O7!R4
+MU@G,8\\4.8Z<=*S(&>0R<(B\"EQ);@#?22Y$'OLW<L[Q(L_;QT$>VT!.3`_*
+M;G)Z!]SC=F0\;\>25U48TH^\%7PVN17RU8O(:Y!/EI+WH""N(N?<'Y1[R)O&
+MHLY#WONUR#_)U:AEO4E>:ACR&;GA6ZL#RKQNX$/(DU`1.IX\?Y](?W(=>+2=
+M9@#*T/96?X-:D[F0X8DHN&\@-Z!\^3LY&=?A>?*V-T3>(Z_"C?J:O!5E:[-#
+MF`^WC)/.Y(3/D6^0]]6@3D->?;M(WB'6O4["O9[-\.WOX'Z1!QX<)]>3PSC^
+MG\AI-P1E([GS`T'YB+P*YQE(9!YR?E"ZD.7/04DE%QQER&GD":@7C2/O^T!D
+M&GD+SJ'8_NT1.!_RYNY!N9'<(F3(7>3$<4'Y&WDT*FG/D%??&9`WR%/Z&A(X
+ME.=\3U`2R:MZBIQ,KC])9(3-J*`6D+>#KR6'P2O(+:8:\CBY(W@+N2OX(W(:
+M^&?R:/"AA_%^@7N2]X)'DLLNPG-+K@:7D]>`;[!_"[[7_BWX:7)B!IY5<BKX
+M2W(YN'D'EF7@8\A=IQDR@+P//('<.=N06>2!X"O)4\"WD>>#'R0O!C]'K@9_
+M0"[/1W[8D?D&N`,Y!:V7WN2$-PR93$Z_&.\IN>(.0Y9TM)];0^XD=[P5]1;R
+M%AQG<T?K&=[6V$RV,7S5AP'Y@CP8Y6;SPWF>X&/)24^@74`N>]*07'+%HJ#,
+M)>]%7>7JPZWCY[2*EV4,3\0S?!>Y$FV3M>1:_,UMY+4O&?(-N<<"0Q([\9QG
+M!*47N0QUZ4$VHTXUF9SYHB%SR6FC1*XA-R"__1,Y`>7"D^2ZB2*ODW>C??<-
+M>=4%2'<$G]5IN.[DRFR\>^1B-`Q+R#7@*O(F\`/DW>#-Y(X%(I^0AX-;=.:U
+MG8-Z(+DCZLS#R5..%LDEK\6[>0EY._A:<O+MJ/N14X:(/-C9NN8[4#_9P/`&
+MY"%;R?4H0S\E]QB$>O*1;(/\.2"=R`G/&M*5O`WE<BIY=->@#"-O;@C()/*R
+M]P(RD[P3ST\EN1C7=CDY%?6Q5>0ZY(=/D-=^&Y3-Y,R1N!=V./*H7>0]TX/R
+M$[D!^=7!1_%]05OI&'(=N"]Y\?W(&\E[P=/(VS?@O3K*NCX5;>/E&CL<U^U6
+MAE<A_'Z&[T:[<C,Y<:C(F^1UR'L_(>_Y#FV?H^SV2%#:',WW%WP\N?C5@)Q"
+M3G@2^20Y&>W0\^SPEFB#'&V=P][V\?('A@_$N5U&WG*G(37DC7CFZ\B%"]$F
+M(J\`;R>GX=GXE+SG!&@2GS'<WZ/)J>#3R)M[BV23]_P8E!+R/KS[ER?9?1&&
+M7$?>MA;//7G*MP'Y.SG]YX"\FF3;&)0O[..W"DJK8U@?.#PH7<F+CS>D+[D6
+M^>YD<B;JWOGDP9.1;Y*KT.9>3-Y\LB'WD+?NPO-]C'4-]Z"=^XH*![<Z".TR
+M\G#P+J;??6E`OB$G/H2Z61=>MZ&&)'>QTN]M8<C)Y`3\=@!Y-/@,IJ]8$Y0+
+MR9W!95VL<QC5,EZN8OAVE._WDL/@%\G)J$M_3-Z8&90?[.-D!:7=L2S'_QF0
+MX\AKD<^?0DY"/7`">2GJ$7/(M7CVKB97SS?D#G+.Y88\1`XO,N19<N>K<'W(
+ME>`P>2.X73+SJRI#3B"ON!_Y/WD5\OESR-OP+$TE3UF,?)B<DV#(5>0=:%_<
+M0AZ(=NY?[..`UY.+\:Z_1-Y\>U!V)+.N=7B\?,WP"K3[@L?Q/&%O!W+'A4'I
+M3IYP!^K5Y"0<<SQY$NJ<T\B=?T0>;C/*KT7D>M35EY-;X/@/VK_MAOH;.7P;
+MVJ'D%.0)[Y('XCA?'V>MJ4C!.0>.YWV<%I1.Y!5/&]*?O`YETRCR8CSGF>3Y
+MR%?FD3<N#<I2<NV5`5E&[HJVQ8;CK>M3BS;CFPQ?A?`6)_#ZHQYW-+D>?#JY
+M`.]:)GD^>.$)UG'6H@VUG%P+?I"\`OP<N0K\/KD:_`./4UV#]Z@K[QW:`IW)
+M'7\0Z4YN>"8@_<C)?PS*6>0I-P4DO:LS/^5\AM?@.EQ,7@J^C=P#S\8#Y)PG
+M`K+!#E\?D-?(9?>@_45>!S[\1/9/HDSO0TZ+CY/3['"TM4>3IZ#M?"$Y\U61
+MF>0U<W&MR'6=#*DE)QV!?)@<![O>(%=?%I`/R&OQ#OY`W@MNUXW/#_+MKN0&
+M\"!RYRM01I"7XIV=2=YRK2&5Y+4(OXU<?!WJEN1MZAVWCX/P!G(BWN4?R34K
+M10[KSO,!#R"O1CUE#+D8=;`9W:U\+P[YWAQR#_#E3!-&^7AU=^MY*/ZYF=QN
+M,YZ-NN[6NS`![\)ZIM^!Y_EE<BOD%1^15RU#_D.N0WVU50]>\^6H>Y,3'T4>
+M2%Z*9^;4'M;Y[$->/8*<C',[AVF*\;V0O/7GH.21I[QBR%+R.K1AEY-3S\<U
+M[&&=_R2)E[\S/&$8WD-R/>HA6\B=T4Y\ERS?X-TG-PP7B>_),OHX-5^0^</3
+M`3FIIW6>#3CG4QFNYA.>3=YX@B&3R&G(Z_+)-3L"<CEY2ANT,>W?@E>2*U!V
+M/T*.0QG]+W(][M'KY&I\WR,WH-[U+;D.[=:#3J(MRU$G)*\&]R=OQW&&DE?A
+MF<\D)W0V9!&Y(1YM/7(Z+N1SY"FK@O(V.>>@.-E-'CP:]?R367;CF>E^LMUO
+M8\CYY*0QAA21T\&+R?/!=Y&K%@;D?O(RU+O6DX>C+'N-O&>=R(?D-<\9JE%E
+M/9/@3N3$Y_&,D8>#SR'+ZR+3R1MQG>>1%T]$&4=>LR$@MZ;8_3:&K+;35(L\
+M1^Z(MLFKY)H+13ZRCPG^WOY;*P/2HQ?S2?!T<H_;T!8@;P,O[V5??_R$7(#G
+M9#VY&'7^+63!<_L..?W+H'QFA]\5D$!OGL].G!]Y';@/><VCR!/(U<V#4D!.
+MP?,_CSRITI`;R;M_#,@#Y.2O`O(O\K*S\0STMN]I4+XDU_X#__3A,[P"95L?
+MZWEH0/MT$,/#")]!3D=^?A5Y,/*NV\D=T19XU#Y.%[3QR7'WX;Z3*\'-4SD^
+MTCI>NJ8R+SH+>2"Y#CR.7#L)[R!Y2Y;(Y>2"$-H.Y"DH%]:0JQ&^F5P/WD'>
+M#=Y'3IR.[RE\Q\$]R`EOHWPD[ST1SS\YO9LA"\AU)P7E&G(F"LN5Y'+8^]`I
+M'.O!=5O/\*27`_(B.>6=@&PG[[L^*+OLX[P4D!_M\WDE(*W[LO[S9$"2R`TH
+M6_N0U1SI$>0:Y+?GD=>AOI?7USJ'`N2?I0P?A7K[I>15R,-O(T]8:\@Z\F;P
+M=O+68)Q\9!^_;5#B^EEYYA3\K7;DCN"C^O%>;`I(7W(5;!E!KD<^,(6\?1KJ
+MI7::!U".\S@3<)SKR(G@&J:I0)UV-;D0Y_]H/SM/#L@+Y.'@M\F95P1E+WGG
+M+D/:IO&].!_O`+DL3Z0_>>ELD7/(M0C/(V\&7T(.@ZO(2?DB]Y"'@Q\GUX_`
+M>TW>?;8AGY$'OX;Z#[GKPT%IV9_W#IQ,W@,^G9S^2%#&DUNM#<H,\L:_(K\E
+M=T0^<Y,=O@9U^/[6O59S6=<RO+!9G#Q-#H\,RJOD2:C/[";7#PC*=_;?2C+D
+MH`%\ME%&'T*6]4$YDKQ]B2&IY)I'`W+.`.OOJGFY4QF^>Z\A!>34?4$I)]>B
+MSGD]N1Y\#WG3O0%Y<H!3YWR&X5L7!.05\MHS@_(^>0+N]5?D9:L"TNI4,MKU
+M7<@[P&GDE/4B8\EQFY"'D"<@?`&Y`GPC>37X7O*^>IA/+G@*Y05Y*_A3<N(&
+MG/M`'A/<@5P-[DFNW2TR;*!=MPQ*NAU>%Y2IY(THC\K(\]$>N98\$'G@O>3A
+M9Z,I2MXS4>0#LN#9-DYC>I1?1Y.W7R0RB%R>*S*5G#0'^0!Y!<)KR%O`CY/W
+M@;>1D_'\?TL>!4X\G??W+I'>Y#KP6'+:>2)9Y.T7H%UL,_+8JT]GO;1=O-S)
+M</D9OR=W;11YBES0/$Z>9_K-J)/LL-,GB/Q`+D3>V'(0KQORV"/)V\`GD\/(
+M2X>06[P;D'/)M0^A+",W@)>2%[>,DUIR75R<K!EDY]NX3^0R\#9RCT,-V45.
+M.PSM"W)5>E`2!_.<;P](=_+J.P(R@%RIQIK)8=0!,NWTR.NFD[?E!F4!>7Y>
+M4&K)&_.#\BAY"_AE<C7JTN^2%Y\7E&_L]."V0_A.W1J08\F;IXH,(6_)0#.9
+M7)F)_)D\_`J80-Z]"/DPN7X)W@MRXE*4E^2-UXJT&\IK?@/>A:'LDT%YE,KP
+M\J?0UB,GP][SR!OQWLTD;P8O(F\#WTJN"\3)G\D]D"?4DU?@OKQ(3GT7;4!R
+MVN&&?$[>C?IV8!CS!+QWAY'7_$GD!')GU*-&D].N-*2,7`:^C5SQ&,I-<O+C
+MAKQ'K@4W&\X\X4H<G[P=]8?CR=+=D('DU&8B(\@=;PG(5'*+>P)R&7GQ-X8L
+M(1>@D+R#W(#G_V_#K6LK'>+E:8:OV1R4%^WT>(8_(M=M#4B8G("V\Y%G\%Z#
+MSR!7):/M0QY\'-J>9[`MAO*EG.$)5P3^A[/S@;-ZRO__^W,_TVP($[%MPM@=
+MQ(:I1DU;7SM,?S75-7\2.]QN]]Z9N77GWNO>.S5E$(4PK5(8N[&S*X2B922$
+MK$&(QIH(E4$(L4F(S?J]SN?S.O?_M/OX??>+Y[S/^9S/Y_Q[_SGG?#Y7KB/G
+M5XO<-EKOY8G<2VZ"[[2!W`7E_@IYU'4.>8>\_G:1[\E]6O#/&)8#'D)>=@?:
+MD=R!O#/(`_#?!3I/+^@Q<A[N=2\Y?*8A:\G5&`.OZOSOB6PG-V/P[1]C^Q[;
+M\,R'C*4.A"WH3^X/.W4Z>1?R_HZ\&W''!6/U_(+M(V]"#'L5>>140VXGK_S9
+ME!7D,,;C0^1QB`O6D\OFH/[DZMP<V47.V6/(MV0OQJTYCF-)C3'R.L1K@\DK
+MWD6YY+Y_,,5%WH-XY#)R*VS$0IWG;R)_)K=`9ZXF-W[FD%?(`Q$CO*/E\`%R
+MQU.GU1OR6_*:[V%WQNL]-?@SY&*O*0U:#IW63&X%WT>.P7X],=X>;^NA\U^,
+MEX_03_,"D<_(SERTR_F48RX<2RY^SB&GD8L0#YYSOMV_NQ'OGT]Y&/[55'()
+MYD20W`)>2&Z>CN<CKWG#CDFLYW\3?4Q><)+(>^1Y`PSYAKP;XZWO!/JEF%\E
+MY/UX$!\Y@#A]$3F\5\5FO"_:\&[R;K3).G*KQY`WR?N\AOQ+7PN?^4?R8OC_
+M/<KL-G1"WQY9QKGSL2&GD??TRI$197K]!WW$_(W(/XWR)NCR,+D8_3Z/W!//
+MLU27V6;*WW4Y\&/?)/>!'[N3W`+_\S_D5G#A1,Y]<,U$O6\H,I]<AOLN)8]$
+M3+&"[$4,\KR6OR_R.GDKRME&7@E;\#6Y$;%2[B3>]P1#^I"+H=].)6_$,Y]+
+MWO"X*9=.8LQ[3*[44]YYOB%-Y"+,TV;F<3IRY<^3]%Z`*0^11X&?(]>!.\G5
+MY]IG7*QQLLN0_63!6,Z9S'$(_7`DN1UU/X6\"WP.>=QFAY235X!KR/O!<\G.
+M#H?\D;P*_#=R#N*RM>3.MS"OR<UO.V2'?H:M\+')!>^@#9WZ_(9#^I&;WW7(
+MF>22]QQR'KD-/(4\8)M#9I"7@Z_4Y8"7D`\<8\I*<F>Y*<^2^Z`?-SOU?K=#
+M=NK\7QGR'7G<`P[)N8!C`[[6+\GS,._.(E?#-I60P]!U%Y)CT'4SR`4/.J2)
+M7/2(0Q:1FZ\WY4_D-9BSCY#7?8V^(:]'GW:26T\4V7N!/396'IXK/<K9/KAO
+M/_)&W/>WY+(-#AE)W@9?=Q*YXS:'U)?33\9\G$/YUD_0I^0!OS+E+G(;QO9J
+M\E3D^0>O+82/O9GR%MSK`_(NQ(`_Z'O!S^E3P;$!W^9,LCK7-H)<C;D_F;P"
+M;5M+WCT5,11YY$O0.^2%_Q1YD*S>5WI>EPD]^<\*ZAGH]EV4]X%-^X&\M1W^
+M?"7[]U^&'$O.P?^&D#?<C!B*W'^)*?7D/0L<TD@N/%WD>O+6$^`/:#GZZ`5R
+M&_AC\B:P444;-]&0?N1J<!%YU5Y#QI/;U+GT*MNF]+Q7Y"I]+6*'1>16^`,M
+M579].U'?U93GO>20)\GY&$N=5?H,,\8/>2K&<X\I'+?X[['D/K!K`\G53\$/
+MF:+;WR%CR7LPQR\B5\+?FTG>-\&4J\A-9:8L)>\'/TB6+8B_R"7@]Z;P/,-1
+MN?(QY0=@.[XGK]HG<LB%G'<_BAQ'7O!KZ$%RI<N02\F%:T7\Y*T7(0XE]T*<
+M>`NY!+R27`9;]B1Y4Q\#?A7'/]KA(_(RQ"_[R8L1O^1-Y5Q#_'(J>1/L[^_(
+MK1C;Y>1=L`73R'V?1ZQ*[D(=%^IR,.97DT>BG"UD]?[=5^1"^.<_3+7'P[OP
+M(0^[B.TS%SXVN3C'E-^3PU>:,D'G><V0Z>05VPV)7&27LQ/ES+_(;O\2Z(%F
+MYI&/''(?>>4,4YXFMU_ED$WZ7@/A5Y,WG8'Q<S'[XDR1L>1YX*LUNTU90EYS
+MF,A?R&'8UB?(C>`OR`O!)_V!_5@"?4L>U6%(*7G:^:94D/O<ZQ`/N1-^]6QR
+MRRO0L^1>KZ)OR-7@1\D=X!?)A9LP)LGRFLB_R)O`.=7TJ7"OON0RV+@SR+N_
+M1/]5Z_=-1":3MSYD6G;"DE]B2)3<>IPAUY$/P$^[@[RL1XZLUM>BG&=T_A$B
+M7Y%7HCU_TO>%33GR$J[1P:\X\1*N4VU79^S8=R<:<BXY#[[?Q3K/`9$H>3'B
+MQ&O(?7HBYB(/.%3D`7TM8JMG+]'[E;#OY)YY&#;D)O`!\E;$1T=>RGX_TI`!
+MY&+,M7,OY5D=Z*X+*%\&WW\:N?%\VZ9:]@L\G]SK)O0KN7,I;`%Y`,;,4^1J
+M<*>^%C9B-[GN(OBN+LX%\`GD_(L-&4I>#IL[ACP/,?=D<@OX(G+CE0ZI)>^!
+M7SV'7/B-R$WD$O!?=3G@Q\G[H-->UWF^A8T@-X,/D#>!CYY&^7Z1D\DKP</(
+M!\`3R7U_$/&05T%/SB7O!"\A3X4O^@!Y%'S1=O(T^(1OZ&O?P?.0UR&&_5'G
+MWR;2VTV[B;CF5/*F!TP93MZ&>7V!S@,=6$_>B;CL!G+_6E/N(3>C/1]RZW=&
+M#'F67/9KP]J#L:X%?Z#+'VW('G+U(Z:8TSG>X+L>1VX%%Y'[PE\=3XZ!+R5W
+M@*/D?/BN"W4YX#O)6\&/D+M@XUXB#]CBD&WD99C[7Y/+X-_F>NA+P+\]CKP+
+M7$A>#O]V--D)__9BG1\^;8C<"%Y`W@V^@SP-/NU#^MKM\,$\^KT&A[Q%'GF\
+M*9^36SZ!_O*RG+]!7Y&WP586DANG&3*!7.E&S$A>#I[GY;LMF)M_IERM/3Q,
+MG@=^B9R_VI1WR/L"AGQ,7HDQ_SUY&<;G(3[6%[['L>2NVZ$_R>->-V0$>=[;
+MAI21.W8;<C%YX09#PN1IAQIR#7D%N(5<=)@A#Y!'@=?K:\&ODY>#=_JT/4)L
+M2]X`SJOA6.UER*_)38<;,IS<"7:2"X^`OTJ.@:\D%_<V9#&Y\BA#[B.W@I\A
+M[P9O(><?;<AN7>9XPWHIT=+)X+YD]?VAT\CS+H3?2%YS*V(B<@Y\^R9R,;B%
+M7`9^@+RB!>-'YU_AD+?)X\![];6-AAQ1Q_BEVI#CR(7P"0?4\;S6$;DRDO*^
+MN+:27'D/="-Y,>*I!N;/0[PPG_+8RX;<2FXY'OX`>=D:AZQB_NH>N;*6\JY3
+M#&DG]PQA'),[/H1/2PXOA4[PLTS8QC[DM@.FG$S.?\@AP\A]?B]218YA3`;(
+MRV!;F\C]H7\6D>>=:LA=Y&WPI=?X;3]JY"&&/$WY)K3/%O+49T2^)A=L$#EB
+MAH[+$*.18^!QY.5@']F+/FJ:P3,Y\/^745X"'_!!<@#U_@=YWRQ[_\.J.^3?
+MD%6;'3J3=@I\$KDOGJN8/!(\F3QODBD>\O[_F!(D]Q^%.4`N_EAD*7D3^`%R
+M/NS(8^2>A^?(1GVOJ89TDL5IR-Z9.@8QI'>`>=I$SB!O!8\CMSPFXB9/6^^0
+MJ\AUX"?("\#?DS?\$7%-/>]UO4..(1?X,9?K$_N``RC?^(,A@\E-;Z-]R86P
+M@^7DRDDB-60O?+#%Y.*/1.[1Y2`>?*->G]&"+T1N17ON(?<99\I^\KSW17*#
+M=O\68?P<'60?(4X\B=PG7V10D&<8CLP5)[G$D2NUY*W0S]>05X+O)*\"KR.W
+M@-\D+P=_1<['?#1"'/.POT>%>&V?7#F)\LK)IIQ%WC_#D//(33,-F4+>"IY!
+M=D+_7ZGS@)>0%X+O)K>!UY(W@C>2ZT*&;--E7F;(5_J^$6NA@N]9BYQ`SOO:
+MD%/)G;^'_T;N^H,A8\,\(]$W5RZD?.<J4_R4.U'W*.5MA^3(S>3^F&OWD6.(
+M19[59<)7?(\<0+Q_@#QNN2E'7,9Y/<V44\AMWY@RC-R%/./)B^<C5B5O>-:0
+M663U'96;R<6/BMQ/+H%_^R0Y#W[U&V0YUY3WR+O.-^0+<OY=B`O(XQ"C'1:A
+MK;G-E./)^1B3P\F%X(O("Q`G!LD;C\>SD?=@G"_4Y:#\/Y&=*'\5>1EX$WD;
+M>`]Y/_C0*,<SXL13HOHLG$@I>2#X4G(Q>!9Y'/AF<AA\#[D9_!1Y.7@+>?U(
+MD4_(U7_!7",WWF[*H3'RG:;T)[?YT$?D,&S<F!C/&_S<0RHI[X2?Z2?782[,
+M(W==:\B],1T3&?(JN03\%7GJ4X8<WL#^6@^_BQP&EY.+G8@=R-YRD=O)'17P
+MO\G5A^;(RPWZ+`=\3G+96H<</XOC"CR8O!X\B;P17$/N!%])[@(O(S<_Z9#5
+MY!7@%\B;P%VS[#;IJ=YY)+=#%\ELSJDG'-)O-N70+0,HWS0?<<IL_;X2QC]Y
+MY9]-^0.YY4&'!,G-L,M7DU?\W2%+R=/&B-Q+'H!__LY[[<$S/$-Y/N*(C9K5
+M$A,YMLB4'\EUB$>/;&1[(L8ZE=P3\<0YY)778$R3\Q?"[I#G+4)U=9[%B._(
+M+:_#;R$OS$?L25Y\M2%ODMLQWW>1^_[)D'^36Z&C#IG#.E89TH<\$L]S&KD#
+MSU!,[K/(WK>SXF7)E8LISX>?$"&K[S,M))>@36XA-Y:;\J#.`[_Q,7*9TD'D
+MYDN@>\EKP#^2NS[`O>=2[\'7&CQ7OTMER@ART6C$H>25RTQQDU=L$8F0QY7A
+M'F3O1.@W70[&_V;R2(SYW>2Z2L3YE[,NZQ'_DOM\Y9`2\K0%IC@OIV\)7W0&
+M>0W&QC7,LQC&_D_D#?`S'R+O`F\@KX(^[R+GJ(^4-W&>@G]-7@@N(>][T)0*
+M<FP"_']R"^*=)BU'O+.$O&$-Q@FY#V*KIS7#+WV-W/0;0[:3>R'NV$L>@#CB
+M%U?PV:I,.>X*77>'#"#G3S!E%'D`>.X5^CR/*6WD0L3LK^IR_*9\3/;.,.4`
+M><-+#CGD2NJ9ZTSI1W9>;LAIY&K(?T?.0?Q81>[R&3+S2K8_],#5E*^X$;9!
+MY^F9(RN8IPMY_GZE/L-CRLLZ/[B+O'`O?">=!W;*<17G#GSUWN3&G9C+Y';$
+MOF/)?5&O2\C+;C)D#GG:O:;<2.YSA,A=5]$?.-!#'J5\'.1ODS>!?R;G]87O
+M,8]E@O^/O/Q7(A>1-Z)]9I#W_&3*5>2^Z-_%Y%7@OY+7C$5\2FZ_UR$ODWNM
+M,>4M?2_TRVYRWD:'Y%Y-N_F&0TXBKP>/))?]TR$7DE>"(^2>;SID$;D.O)*\
+M$?P\N:#3(3O(\\`_D&-O.>30:_@\VQW2G[P1?!;Y`/@\<NL.AUQ"[JHS)$H>
+M!S]\$3D,7DE>#GY>EPG>0=X0-.0'<M%]L./S^3RO&G(Z>0]T73%Y!=I_O,Z3
+MDR/5\[G6W=.0&G)_^-MAYFF:`G^5O*P5/ABYH,R4OY&WP?X^0=XDIKQ+WJH&
+MS@+:<93?G]P!^3#R-,A]"V@?U;OD.D^](3>2F^XQY<]:#A]C%?,[,4?64[[K
+M7>A)\KIMB"_(^:CC-^2M1QAB7LN^.QHQ!7DJ]-M9Y'7S31E);EEARL1K]7D8
+MA[C)E7<XY#KR*O!=Y/:YAJRZEK$Y8I#UE&]#W/<Z>>!W(CO(S?\6^8I<\%M#
+M?B:/A"T^ZCKFOQGQ!;GO8E-JR`O!\\GA):8\2:[#7-A(7C,%]R8W>97.8EW@
+M'_WB>HY_R(\C=X+/(HL/_B=Y`/A"LEISFDG>`S]N/EF]LW(G.0\^[5.ZG,/A
+MDU_/\U$_]9!=E!=!GK>0;0@>23X`GD+N"=UR&;GD*/BZY.*C43?R5/`;Y/Q?
+MY,AGY-V(UWY<R&_[H"\.N8%[LO`-^MW`]D1<=@8YC#BKA-P8AO])[@+[R-6(
+MN1K)E8BY;B2O:3#D3G(OV.(V<L<K>#:R]RK8+/)B\#$W<OZ"B\F[P9>2]W^+
+MF)%\`/.Q0>?_0N0&\C;P7[4<\W$-N17Q_HOD]>`N<M.C#OF&W.M00_ZC[P4^
+MY";.QQ<=TH<LL-<GDC?L%SF=G+_3D)'D=1\:,HF\]5-#W.26'2(A\D*TR15D
+MI]K3)X^"__DX>25TU`;RGC&F=)+[CC5E]TW<BT<__IOR%7M%<IO9/@_#SR<7
+M7XKV;*8/W#-7)E`>4^\:DZ<>AN<D+T,Y@6;=5B)SR3T1WRTA%X';R.O`+Y''
+MG6/([F9]CM&0O$74+>!"\D)P-7DC^"IRSGA#6LD#U'PAKX/OM(DL'T-7D/N\
+MC/%!KK[=(3E_9'Q1:\J)Y`6+#?D]N1WCWTE>\VO4ESSR5$,BY+8'$%.0^R.F
+MN)D\:K+(:EW.MZ9L(/>";_S:'VT;L?4T0]ZGO&BFR/?D`XCQ>]],6[#0D)/)
+MG;AH-+D9//UF[5\AGM7Y84NO(X^$SK[]9OT-+D,>(I=L1UDW\]U,S.7/*9^W
+M7;W7QW$('KA8VUSU[B['\%B1*G+A"%-\.C_ZHI&\9JTIK>0!+E->)-?!-]M"
+M7GF/0WXF%R//*4O8O\4BY>3UIXA<3E;?L&DE3WW4E'9RV\6(@\AUUSGD(W('
+M8J+OR66(B=3Y7:N<EPSY%=G[.6(-\D[PY%OTM_4PGLDEQYER+;E/']2+O`SR
+M]>1\S)V7R0?N,^03?2WLZ8_D?>\A-ES*N0G;>C*Y/^+$$4OUNHW(A*7ZG#!\
+M&YW_'PZ)DE<\![NYE&MQO7+E%LH'K'/(G>0.]-&CY&F(F]IU.?`QWB(OO`WM
+M0^X<8,CARS@&>HN<0IX*OV60EC^,,4#.0YPUC5R`..LJ\G+$6?>1U[WOD.?(
+M7NBB7>2MT*7?DA?#7A]U*\L\T9!3R6&,^:'D?8^8,H'<$W/D4G)1B?KN&_62
+M!SX5><-T4Y:3!_R?R!/DLN\1FY"=+QORP:WZ>SN&?$U6WR0^]#:6CS;L1UZW
+MVB&GD3M&P2<GM][GD,GD_)4."9,;P=>3%X!;R9O`3Y!W@5_3Y3^&<4NN6^&0
+M(V\G-\&VDG?"+QI+[CL/?B9Y'/A:<B-X!3GG:OBZY"+PASK_WPW):>%]VPWY
+M-;FUT9#_(Y==XY`+R#U17[?./P+U(8>;3;F-O*T?YCQY'.*C5_2U^TS92CZ`
+MOMA-7O`#QAZY!#%7CSM8)MKA1+(3L<E9Y%W0R4[RJB7PJ\D[;X%](?=?9LBC
+MY*);#>DD;QL#/Y;<ZV6'_$@N!!_U)Y:_Q2$GD_,0@Q23"\'G:_G;#KF4O!$<
+M(3=NQ7PDKP&WD*>]XY!5Y#[O.F2#OA;<22[H;\JG9&\-^N7/',]70N>35X!'
+MDSO!->0<^#D+R47@^\D;JV!GR1O0CQO(S:\;\C:YSR1#OB*W@\WE]&'*$5^0
+M^U8:4D1N!H\E+X8_\P=RX`?X)V0G]-(5Y#6P:TO)ZIO?]Y/7(4YYGIS3"\]#
+MSN]MR!=D]?[N87=R/"!.^16YYX48#^1I;::,(B\^P90IY.6P"[7DW6_#)I+G
+M0=_>0&Y]V)1;R>O5FI4N9Y,A3]^IW[5$K$%NGVK(+G(=;(WC+OJNIT!WD?=<
+M@7ETEWY_T)"S-9\N,I&\&/=RWZ6_!6=*PUVZG4WY([D(?#^Y\R)3GB,+_(%W
+MR5UH_\_(HWY$GY$'P/8=\1>6#^Y'+KC1D!'D:K3Y^>0PVOPBG>>0'/&3%WYC
+MRMR_T.<_,E=NT'DV&[*<W%5HR`;RMD&&?$;N-01MTLIG7F#*K\EKOH0^)ZOW
+MKD:3B]$.EY#'O6+(9:WZ+`UT&CD&^1WDP%N&K"8O@_PY\LHMAFPAMR)F_TR7
+M`_Z)W!?]V_NO[#OPR>2\RPTI)7=`W_JT''UZ/;D,_"?RX@6X+SEPG2'ODAO!
+M>S4_:ECO(5CV"_[&&>3\M2*_)P\`5Y'5-_$C9/7M^YO)6ZLQ_\EYB&?7D<M^
+M8UAG<*UVP/._3R[Q(A[1>7R&G'`W[_L(_)R[[=]$:/VHAPRGO!4^\&1R(?RQ
+M"'D48I#KR.U?B]Q!+KC%E'O)TR;`IR4W@7?H:V&[]Y/W8?[FK&!=,.^.(0O:
+M^;?DE;"S(\E%N.Y\\L!IT'7D;6Y#KB%OFFK*G5K^OB$/DW=V&?(/<OL'T/_D
+M/-C-#\D]<:^]^EK$O'WNX7B`CU1`'G6!R'GD(O@_3O(X)\8J>21T49B\`+R`
+MO`I^10NY/\;G&G([QMO+Y'W@#\D%KQGR;_T,X#[W4I?"KSB!O`$^]JGWZOUK
+MAYQ#;KX--IK<UN*0&>0!\!^N)>]&G_Y5E[/`(:O)93?!=R6OA'[KT/>=;,CG
+MY%5@\S[.0=CH(\F5L)L#R0O!X\GKP37DW>#Y]^EV@/]#+@,_36X"OT->!?Z.
+MO`U\[$I]EM(A0\DCP17D\'!3II.;.PSX6!S_`5.6D,?-%7F$7(GQ_QQY<7]#
+M-I.7U<'^:L:X/4#NGVO(:?>S3/`4\F+P=>0V\-K[]5XJ8AQR'\3..\@M+D.^
+M(Q?`7N0^P'GW&.)-<@RQ4C&Y[G%3*L@#/D6?DBN/->4*\AK(;R7WQ=A^F%P$
+M?NT!KL\8N;*5\N(?#=E);M^,N?<@;>($D>/(G?#GAS^HOXV&N4T^@#CH2G)!
+MI<A?R,ZQICSZ(._ER)57*-^%<;7C0?UM'.@!<@!\U"JV,_@,\CKP6'*UY(B+
+MO&LB8DER,>S(0O*\ZTWY"[GDCZ:L(]<AWG^9W!%6>_#TA5:;\CVY:XHIAZVF
+MO0;W(^?![SB=O$&=DR"O/\>0<U?K=W]$*LAA^%1N<NNSI@1UGE_`QR`[8:-;
+MR(7PD>XC+[\1STP>6`4?0^=!_+6-K-Y-W$T>AUCXB(>H-^`/G$PN`H\DQ^`;
+M5)$;7T,,0EX!_B.Y`[R&?`"\B3SP=8?L(E>#<Q[FO`;GD]>!1Y!W@2_4#)W@
+M)[=N%YE/WH<V7$3.6PA_6)=SJ"'WD3L/P]PAMV`^=I#;P%^1>YX$W:CEB`%[
+MKZ&^.L*0D\B51R,^)7L1PU61Z]"G]>2</QAR%3G\C"G-:_2[2(;<0^X)/?`4
+M>0_Z:!.Y:Q?LQ1KZ0IA3/?_.,?D9[.G?]7N%(I/(SL]%:L@=X&NT_`N1/Y$'
+MH'\?U'DN,.0E\JX+3'F/O`_\+W*>^K;_(]1+%?"'R>/``\GSP.>0F\$7D-O`
+M7O(&\!7D_>!;R3WA<SZL\X-?(!=B7'U&SLLWY2>R?"=R^*-L_W^+'$_.N\B0
+MWY&=A^?(1,TO.&0:N>OW&#/D]5M$YCRJUQ9,N4&7`YM[.WGG+H<\I.7@=ETF
+M\F\AMW0A'[D3_LF_R<OQ_.J\EWW^!,]&[@N[5DWN>2EB!+)SFLA2<I-;Y&&R
+M]QJ1%]OTNU2P3^2B&]$4Y.7-(KT?8YF+H4_(*V^!+T'N:^3(I,?L=;^-B%^F
+M4UZT'7XO6;U'?LUC/(MU;*[<0UX#WDC..2Q7WF+^+HS-3RDOZYTK/U'>[#?D
+MR+6L._R6$];J[\F84K16_^Z#^DX'[<)TQ''D',3OB\@Q95_(:^`#OT;NCSAT
+MAY9?"S_A<?J9\'5_0^XXR912\E2,X:GD.G"8[(0.7*#S0*?=\;@^AV#(,^3F
+MWZ+-R?.&BOQ`SD'^O'5\ADMA3\GKKG3(Z>2V4K0O>?%H4_Z/G(=Q<CZYURJ,
+M3W+[(PYI(!]`O',M><75#KE#7SO#D(?("\#/DT?.-*QO65IC$OPE>3_8\02O
+M#1KR2_+Z*'S@)_0WID1&D+LFFE+VA+:#I@3(.="WB\GJ][)6D=7O8FTD>\\V
+M9`]YZPA#CGF2MM+,D1/(RQ9!;SQICYE1&#/G4=[D,N5B<@?T<!UY?S]#FLA.
+MZ,D;R<M/1DQ$EOGPM72>ZT1>UGP#GH^\^";D>XKCYX\B_<B!)2)#R.J;N..?
+MTO&%8;T;9NGDW!RYC%QRNR'+GM+KA*;\53-LZ"/D3NBQE\D'H+MV/:5UE(F&
+M9WVA'XXC=RXQY4SR-G`Y>3=X+GE@%/J!O!Z^^CWK];<X1-:2USDQ1\C+3L<8
+MT'+PT4^SCJL=<A*Y<#'&ZM/Z>Y[P-Y[6\\40%[FI`NU/KOY>Y#;RN)\P[LFK
+MH)N?)7<^Y9#WR8(Q_SFYY$F']'B&\\B#NI.GW>"0`G(SXI>SR&6'XWG(7G`%
+MN>`HQ,CDD>#9SW!?,B]7KJ;\P)&&_)F\H(\ACY$;CX.]T_F/R)4=Y*[#<^4;
+M\A[PH<]2#\"?SW^6.O"G'G(6Y6TYJ!JY&/7UD3MZP6\D]\0SW$0N`-]%+@'_
+MG5P-;B=W]C;D;?)*^!6?DS>`?R)O!>=MX)@$_X:\"_4:1AZ`AYU`7HGX]R+R
+M0-C<`-D+ODKG`=]"[@2O(K<K6TQNAIY\A[P>O)O<$WZL/,?^0EQ\+'D5N(C<
+MBGD]GCP-NL)'+I@D,I>\ZW3D>XYGG'[N(6LI'P7=VT6>!_Z)O!Q\W#_8/N"A
+MY*XS1"XB]SI3I(%<5"1R"[ER)/QA\CK,QR?(RS`?.\@;^YCR,3EPC"D'R!V8
+M+SV>9_OL$_DE>1OX-/*X'$-&D->#)Y+WP"_PDG-@MYO(+>#;GM?O+HD\1%X`
+M_^NIY^TVV6;FRF;*\_N+?$X^@-C-;.=<4W.*[`0/(^^YT)#SR+W@6U:01^Z%
+M;T8N;#:E@;P2^>>31Z%>MY'GP>^ZG]P"7D]>`]Y,W@C^L%W_]HTAW[;K;PRJ
+MWQ?1W]-#W[V@SX:)G$D>!SZ77'2:*5/(@C(:R'GX[S)R_HLBCY+#X'^^0#_D
+MJ%SYD-QV3*[L89XZV!3'B[:\\NA<^<6+K#M\F*/(^>T..87<##[G1?LW&AI_
+ME2NC*=\/W^9"\L"P(7YR_T:1J\F+$4??_Z)^)\645\A]$2=^\:(^(P3_X26V
+M`_SM,U[29R/11^3BO2)N\H*=>`[-&*MWD?<A]O^'SC]>Y'4MAQ_U&5G].-2_
+MR<U?FW+$1NH]^'4G;60_7FE*,;GK*E,FD'N-@;]$+GS<(7>2O?6&_&.C_@:(
+MR-ODD54B7Y)WP2\Z`#Y$M>&)N6*\3)_A%SERS,OT)]$7QU%>N1)ZE=R$F.MB
+M\@KXJR%R!^I[';EZIBG+R=MJ$-.1]\,6OTHN.,V0C\E.\,_DNA<=<O0K;$_P
+M;\E;<T5^1QYU$_PT\CK,$3<Y_SW4A]P$';N8O/ZP'%E)WCG/E)?(ZO?6W]5Y
+MWC9D-[GN1$.^(P>@'XY\E>U\/?3GJSR#A#$\BO*B/$.FD-M@U^K(==>:<B5Y
+MW/F&+.:UK4?FR@KR!NC51\@+T.;KF']=$^8ON665*1^!U?%0=<;X2W"N>K_@
+MQQYB;K)_'UO-A6,VV7G4-\S[D]7W@@K(ZEN.@W0>\`BR^G[1>5K>`W'K)KO\
+M+I1?1[EZ;WHV.$=]M[R?R,V4J]\!N6.3_5[+O>#[]'VA#Q\B*]VX-HF?TWR\
+MR":R>O=D*^\[[3\]Y"NR%]SK-3[G29BK9/6[-B>3U?<0SB"KWT0KUO)S14K)
+MZGM$YY/5][2JR.K;.-/(ZOM+,\GJ]P(:7K/K=50U7%GR/V>(+"$?,U/D+^1?
+MWRVRFGP;^"F6H[XU^A+EU?=@/I)[W8L8C:S6=[\G_QYS[1>OVWPN^)?D\\&G
+MDB>!A[W.Y[P?^2A7/)FLUM4N(;\!GDFN7XWXFOP^^/K7[796OXY^-\M4WZY<
+M15:_O;66K/8IGN6U:\";R.W0,^]H.>*,3\A/@K\A/P^6S:P[?/_#R<>"^Y&/
+M!Y]*+@`7D0>!S]W,/H7//I'R?\+^7T)6]K]^,^?"\;DR7]\+>F4IN1K_O9M\
+MYQNH&LM4WX5XAJR^:?D*\SP*??*NEF^'[M#/L`.Z8[/=;FO0;C]3KLZK']K!
+M/!^C[SKL<A0/(+>#AY,7?H)^)2\&_X'7JO6E&LK#GV$<DC>!%Y"K/T>]R-O`
+M?^.UZ@S;*LKW@Y\DS_D2?@"Y"?P6^7[P3O)&\%Z6H[[=\:.N"^R=^8:=IPV<
+M1V[]!GU&KD0,<CIY*W@8N0L\BKP+?`&YZ0>12\D+P#/)S>!&<B%BF6O)Q>"E
+MY!+P7_6]P`_K>X&?UO<"OTK>`WZ'O!_\*3GO9Y%OR7W!YC]MS@?W)AM0S">2
+MYX//(!^MOJU-7@H>_T_JF4,,*:=\&=A%[G^H(0%RS\,,F4/NHWY_C;P/<<=2
+M<AML2BNY$#'(:G(3[,N3Y%['(&[2Y8`[];W`'Y(+P'O(?8\UY#^ZCN!>;_)]
+M1'`_<B%X`/D-Q/A#R16(94:1GP.7DTOAOTU[DWH#7$OY=\<;$B'OAGV_@OP5
+M>"&Y&/'O4O+L@8C%R`O`]Y.;P6WD9>!GR<O!KY"GG6G(%G(=^`-RR=F(M<E#
+MAQKR@ZX+N$>GS>M&&]*;_"SX>/*+X-/(KX'/)G>"SR5?-Q9Q!/GA<89<1/X7
+MV-?)N3/>D!#E'>`KR"7P!VXB=X'O(`<F&'(?KU7?+7^4W#71D*=U?O"KY$E.
+M0]XACR@WY%/R=O"WY&D5AIA;;/X9W)L\MQ)C>POUOR-71FRA3:DR9`SS/.$S
+MI(K\!MA+?@9^793\6JTAU_!:]5M[BR@_![[H<G()^$'R7O"3^MJ((2^3KX\:
+MLI7<!OZ4W-H`?XR\$MSC+9O/:C2D#WD0^#?D(O"0M^B'S#4LG:[DWR\TY`+R
+MYAL,F4[N<2/J0E[68L@"<N0E0VXE=X+O)8_?:,CCNOR7#7F.\AVO&;*9_.EF
+M0[:31W08\@6Y'OP#>?UN0W[Q-OOZ2T..)JOWUON];??+//3+$/*V',0[S./<
+M:\@DG:='KDQ_VRY3R4-OVW:P"7;P&LJ70WXS>05X.?.T(\_#NLQO#/C!=IF+
+M4>;;FG-SY3OR,O#A6^UKRT[(E0'D7N"16ZESOL6S43X0<L]6CJOO\&Q;[7):
+M4<Y"\JZ>N7(/\X>1_QFR$_P&RWSF!^@TEM/ZHR&[*.__DR%[R>/^8\A/Y&T.
+MA_1\A^/!1$Q!7I[CD!/(_>%<GT;>""YZQ[YO#/>=0/FZHQPRY1W[.7,.R16?
+MDJLXXI<.N9SRGI#?3EX(7L4\>TYPR+/D@A,=\B;++,AWR`Y]7_!GY)V_<<@^
+MEM."<HYXU^95X`'D#>#A[]IECCK#(6/)N\#5Y)YG.N0RYF]'_@7DC>`[R;O`
+M3[Q+&SK"(<^3N\"O,<]NY/F0O.]0^#G,TS3!(8>]Q[J4.>27Y)X3'?(;\D[P
+M6>0!DQTR@KP"/)9<YG1(Q7MV^>-ZY4J8[`1?RSS>"QRRA"SEB'/).14.N9^\
+M!OP8.5KID`WD.>!7R5>!WR)?"_Z`?!-X-WD)^'OR[6#'-OJ*X,/)=X/[DN\'
+M_X;\,/A,\F/@X>3^4QPRFKR_SB$7;+/[J/%RAP3)S4T.:2:OO,(A#S!_V94.
+M64OYU'D.>6,;?8QK'/(^6?TFQ1=D=:[O>[+ZAFV/[9QW"QQR%%F=]SB!K+XI
+M=QI9_2;U4++Z#:#SR.J;2V7;Z>L>GBMUY#;PM<S3@3R+R>J[!\LU+W3(RNUV
+MS*BX73_/#0YY?3O]7O`VRM6Z]R>Z3/`>_9S+T!<[&//BOOUV,":]U2&G[K#;
+M9WVK0\:1MX'KF"?O7H=$=]#?`U]#/@J\A&5N.")7'F!^];L8CY#5>9LGR.I,
+M;SM9O0?=P7*.?-PA7>3>X#WD#6!YGW,<G$?N`.>3MX(+R5W@$O(NL).\!SR-
+MO!\<)JL?Y[Z:W!-\"SD/?#>Y+[B-G`]^@5SX%.8">1/XT_?9+^L=LI?R><\Y
+MQ.BBS@3GD0<\[Y`3NQ@CM&/\4-[R@D.&4:[><SF/\M#[&//D6\#3R'\"A\@=
+M_W;(E>0?CS-E$;EX@"G+=9FGF7*OYC-,:>NR^RZ<ERN=S%]_IBF?D&/@_>1K
+MP8=^P-@<W)_<<98I9WW`,H>;\KL/.!Y0YA3F47(?V0..D6O`\WFM.HNUB*SV
+MLEO(ZO?K[R&K;R:LT3S:E/5DM?_X#[+ZYMXK.L\84][DO11WD7N"OR3_`?PC
+M\ZOW>G(^Y'W'FG+8AW9=2GKGRHD?LIQQIIQ.[@D^FYP'+B%?-MZ4">0EX"D?
+M:G_5%#?+5^_\!C_4?JDIEY/5;Y#=P/O*T;#IE*NS]X_H/!Y3-B3Q9K+Z'<9W
+MR.JW.#\BJ[-;>UCFO&-SY9"/Z#O5F]*/7!TU92`Y?[8IYY`WSC7%^1';Y$I3
+MJLEJ3=5/5K]9T,#\<^XRY5KRE+^8<BNY^*_H1_)P\&/D,O`+Y(J5IFQAF>K<
+M0A=9?4/X*_T,Z]!?^MG`A^ZD_!E3?DGN`I^TT]:9BH>0]X!',X\Z7U1.GK?!
+M%-=.^E2_S)48>1WX>G*X+^P^N07<MI-QUB8\/[D9_!9Y&?A3\G+P?O(*\"$?
+MV[P*W(^\^#6T_\><.RA_U,?THT[,E4N99^<.4T+D+\'SR%^#EY#W@?]&/@!N
+M(^>\;\J+Y%[@K>0^X,_)_<$'R`7@(SZQ>2`XG]SK(U,&?T+=_K4I_T=6[TJ7
+MD=7O@UQ(5M^F<Y/5[X,'6([BRY-XD2X3?`?EBE<F\9/,HWXOZ17*%;^3Q%^0
+MEX/_I9\-_!/EBGM]FN`3/N5\/")'3J=<\?`DGL`\)>!*RA5[DK@AB>>`7:Y1
+M%TTZ=^+X4G&=YX]5^&*>^G#`Y1KC+!UN_UWN"SL3**YPQ!?V!;TNUZ#"\]Q1
+M7T59F3\:<Y;.$I<[W$V"RV4565XZM"(6\0=K/>)J]-2Y_4&7:W@T%O&YZZ<W
+MU(BK-AR+N%RER:)PILB7)9LO6S[\.TTT/>`+IHFB=:%(S,J9+'4'`B%/AM0;
+MRBYW!?S!F:[TVM0$&J)UJJ14<1@-$`M9CZ$:U6J/\F$A.X?'TUW[ZC\FA;R^
+M;EHZ-8M_=BB"'$/\H:@?3>N+N3RA0$-]VD/6SW)[O5'5=H,&ES9$HK[HA?Z@
+M-S3;[W>6>E3'U=L==_88?^/@(G^:I*@8DE!8->JP&G]`M3@NJQPD+MP`-Q_F
+MMV_EG*6N/*\";33+%XFI4LXN]]7Z&I';[U?YH[X8"E`E(Z?'%XE`-"?JBL;<
+M,57+Z0W^0,P?5.5;PTE5P2[:7UZ:^,,JQQ7"/6H"H=FN.G?0&_"A;D/PK,XQ
+MS@L&*QB"4>R:936)IPXWM`JTZZ>IJ!B=[0NXW#4Q=7E**R-[:'8PBOY+%T=\
+MUNTCOEH(?)$HNK(!3Z_[MLJCBQ\T5-.0P:#QDUT-JFHUN!>&B[AF1_PQ7^)"
+M9VF%QV_GJ\%#AT.ZY+,KQJ#1[5N[O1B$/M4SNM'+]63S)[=EO)_4?(V6A8*U
+M:)YS2\>*J\(3"L]1$U]=IR9]*4$][*!!/J\_AC*LX5J:\J=*=T?_6QY,O=I8
+MG6JV5'G0-QN=WFAW4E74BXD;B80BZ>UKC<;::,-TEXOUPA",CZ&TIJZPFGKX
+M6%^HWH>\'J]S2/DD5+'.A_N,J0I8XUAG]CL3$\)968BD6;&"08-Q4Z^?60K4
+M+-()H>P)Q>DRES]4[P[ZPVI03$=%5-]P-I9/Q?#T13R0BBOF"P1J$W-%#V_[
+M@<I3E)7=SMVE^NO=**=T6&D(&MS7B'FD.CRA=2<-+M1C`MT1"LUL"+OLRU7?
+M8=K[(SZ/TH5J4NLYE)$2GN[VS*QQ^P-9DE)43IH*\,1517&H1@]LS/YXK_@Y
+MQI4V\@?],:N`4#`P)UEG#J4A2BA,U=48%I8.2VA459B:C&DB3\#GSLAG*Z5T
+M:<P7C:4H:25T9V1+/!J&JS_F=,<P]8-IS^?R769UA.X:KY+9LS551C.9(JOW
+M9Y%ER>>=E2X+J_Y+RX:1JE4`_BIPT;+CW^*:$5(VS%8`JGKQD9-%R5L-;+5Y
+MDO;%W!SKBTT.Q_Q.I\>>LNA0KZ_&W1#`C/?Y9H9JE)WWA!J"L>0A#R-D/^GX
+M8`QS.A(HUR0N:\YWDU;?$.@VS>N?U?UUH>[OYPYVGZ;T4C=)C0=)"T3K_#6Q
+M;I,C!T^.=V.6-$S"(>5XXE`]1="[J8*X=OZO^6I]05_$';-U;WJBI0LRQ77^
+MVKIL<FU:LCR,)Y!%[(Z.5R,B2_9(-$F)I"K#0#3)2*8F%9>[8_Y0T!VH4@8U
+M31%6%GH2BC!)'V'`QQF&"2GG^8.A>K\[$%<'U#\)59(0:#62D`3<:=?`!*-V
+MRE(IKR-]>BJ=V>CR>U$2GJ'!HRK@BKGAM%JN.55++.2VKDI6-Y:6J76'8635
+M.**%M5T*OYT204=E2:J'HK?24U-0X7KWS&Y24JPP_3VE5X;[PS499G%X*%VH
+ME9SM"5D&-]FGU"*JLV11;2Q#%,@4)14_9'!&\5J45+P6)16O18%T41@Z+,56
+M*\OO#(1BRA-+5%MU6JJCW5@3<-=&TT(!C`1H(E^6V,,=2Y-&8Z%HU),FF^U7
+M+FPL9+GWF26E6%/E_OD]EED.I'@)C&HR[M@0]&H?('5NT1E7GIL=6,3;HUPY
+M7K@1ID',7V_-7QJ$@AH_K(0K&`J&PK&,"0D_IJ)A.CD^,W6FI+3X!6F9,`H/
+MGG:P\N-:X7_*]E^*2WF2_Y;O?ZN9>K"#IV:[C6NB/]@0G1ST61X\?*&H?ZY/
+MQPS^](ZS@Y/,<BRG+-714YY]TI\)[_]@>=3=LOJ:]BSH)@G^29HD:5"FI43G
+M!#T9PNG*!2W5BF?0D)H&9`J[$><J+V:,<Y8+?LHL;4O&Q-VV),\'M5-I25Z?
+M)8MDRF9YTD33?36AB"]=Z(^%PE;7#8650^<$G`1/ELA/><W4'*H658$T#3>X
+M*$/#:5&2AM.B)`VG18%,43@YP,^X4(L"Z2($S#X\?,0=K/6E&PWUV&/+)I]W
+M;IEK\I@Q%:,K797GGE<VVH4:1Y-C5CV8!@]6NHM"%]1<G3L:]=<&DS)&O$JC
+M^>+=ZXZ@^>.JV&_]G[BL:KG<TT,1ZW']Z6Y#59J/&H]N,-12[+\G5%\/<QR.
+M^&I4L)JL-OSQU"AJFR55Z^$9#?7AJ)J+/N]@EZMH8EGI6*8J9R+8$$Y_.CN.
+MU75."51U%LN!\8?^2P[51-G3+-MPD/2TYK+&GXK4O;JKAA2XBLI+U;_A,Z`6
+M&.YEH=I)H4B].^!-K2R&,L0IP]N7:!TK*+#JJ\,5K[TNI(>^??-!A:'$XH_3
+M8RNHX>DB./]^90ZME9_2Q,)/Y:"D5:#*(1GUZ]XE<GKL4#V+.'WQ#-HOY>^X
+MBOPON:;[:AO3<UG2.9G2>G=C8U9IEKQU/CI_:?+9?J]:D4D71SV1D%7/-'DL
+MU."IFZU"Q/04^L*9XD@L-#T4ZR;%%\IR$V@13UU6,91+(,N]$;*HM95T,5?W
+MTL7^8'9I%*Y[MM(QW2.^:+9&BKOR65/LU=FT%+5"%\W2&*%`-FF=/Y"E#!@O
+M7S#;7?W347QM9L),M:P*CWVV]7>6&RDCFRY24S+N7"J5V!"&@O6Y]1X!+5AB
+M6Z"R,&F/P%[$GN4/-4135U"J_'9*IC3H:XQE2FVEGV)`J_1*:,3G2WTR5]`?
+MT$9[O+66.=<7"5GK&;9]M52EUN@(]1+*W9Z>V=,R%7_B:;K1_6D9TE1,U*Z`
+MVSNC(:H7Y:W(SU[WK(_6:AWKUTLRR2NAY<K6JJ44M>%@K_FF^35^W4L8N9;/
+M-R:I;VQ_;K#Z.^[KI:YHS8IZW"F[!%#3\))L*UL3"GAAB]6ZN64!$LM'Y:7)
+M2TE<J>PV=6B:VZNOZ$Z>Q5.VDI2ODNT:^C!9+XMOL&1>Z`D%8VZ_M;J?]=*T
+M!>ANGHJK?=VD<MVOF]3:V$%3#WIMX*#7!@YR+<:P4BS=9VB,PDT/IOG7MGOJ
+M<L6&1JV5[D$75P6<]B)W5<!5KAW6,)?[DBTW%P]31361T%Q?,%V:>#:_O4+B
+M<7OJ,/=1J#=C<C5:GB^=.;6UP#V@Y(5:-;7BGCXW1SR!D+(BP\(1:W\O:6A3
+M<23BY<D35/@<7Z$:[['"YR0]@R+')Z9>DM!22J%@FC@IDDM>EBIP):U%9<0%
+ML[0:A*]KA3YZ4O%QW6K5.&G=UY[3\74TR_&J#842T5%B>R9)UR0L>XI0;8VA
+MK^P^34ZPFB95I#=SX@MR]K*PM0R=LBZ4Z&:U1&RMJX12<T1\EFN6Y<[6_F*B
+M`*\U+D)A5;O$QE[B;[6]EQ+^.BL\:FD$,ENAILG=T]402UJ33%I=M)W21-GV
+MWE[B;[7#YP^I(8DRDA\R:D4"B%KJTG89G*55`=NK#87].BVN..TXM30M](QD
+MDQ:X4G=&?3/#H?1`O=&?.M3+2U.'?9(6STBE!:MW1V;Z(M$TOUBUC-_I21ZE
+M"-=25U65LSV+#I\UN:WQ8^_J66O[,7\X,"=KK*R7][.EV(O[V5+BZ_#9$L-J
+M2ZZ;-"X"T"BG6=^A]L)Y(-D`)YS`,8GS#\EK0U2`8VP=&A\6F?&*9:^+QLT)
+M^R*)_4R]H6G-H]1]1SOBK8].M["HV$:47>]6_MQ@M>`7UR=)^SF)811?%%(/
+MH0M$<VL,),JV4-N&U-*45LUZ&WN-.Q9Q!Z,!:QK9'HE]3WLPJ=`H^>]$`'7P
+M7%'W+/K`:5<79(@P[&+N+#GC\SS1^?:D<EF39TSF>EA2W%PY*'-TG&UO="</
+MCK2=T2J[\=TI*TI5_KA_DRJT%U*354958JLA56BO^>//^O1"K'V";`DTU6D%
+MV4,G54TE])0*%AJ"*N"R6IK;'7&]$HLH_R]]_4PM6-GZ,O7O(8/]"8]A>!;G
+M(.VT!YPYCS^J=DK8-\G[1>6V/Y#B!R1I;TMYIW6&==0"=4G>=7+:F[AILR,Q
+MD>/[^ZE5X7F9^-_6:9FT7:O2*D^Z+:KJQA;9<KU:HC?H,ZML+77:ZS'I-[/7
+MDT953BYWE8VOJ%0&R5HV50ML+NM80WSW/MY=>K\IT8$>NY\3?F*J@DN5)QV"
+MF)UT`B)M7T\OP]58?I@UQ3*T*J9[AHQG,K+);87QOY92X,HF3EYMSI+L:8A8
+MP7AW=H`+1@>Q%&)K_(+T(TN6?ATTU)55/F1P=CE4<U8Y]'2F/'W4^'4G)GE,
+M\3^5PY3J`:5<C&%UIEI'%(RJ2:,KDKL=?K`/DRW*->PQY8E5[*21D3U#Z@.J
+MC<>(ZHEADZ?#NGIFVDZP?6@I53:]P3/3%ZNL4RLW(6L1Y>P*M_*$QZ&T4&W$
+M\OK]P?.L;-E3LP>"ULJWFH!TN.,-9'M]\3^M8UVN8<Z0/QH-!;6QCGM[\;T5
+M3T8_1]VQAHBUK#VF/)J1.ML="2I;DI8KO:D\"7MO301OQJJ$Y5U&LHI]V<4\
+MA9(NUG%VFEC'N.EE7Y95K&/>-'$@N[@V>]F!;.)`2F";=H5E7#,Z7P5+_GI_
+MP!VQ$Z+9\Z2KUEGVVG32$:#D^PV*^V7^8-PO4VB%%F/TV;*TW2^]=ZH6QSQU
+M;FOBE28K[S0M6N')=FPI\R!4MG-068]!B3X!F2P[LP9S/5X?=V.\/@KMLUP!
+MN@66_Q<_5\SCA4G'BE/""6H`QJ.P?W-44<YBE\M>NBRW#HJ63W4'PG5NW7(!
+MUHYFI2$UNHC''G%%;LW+"WW^Z0V!0-R+;HSB;AF+&QX&)%JWZ"I;,43"$*O6
+MB-;IYQEK^\Q)3H8_'ODW!*PC,?'8GYMY#1B>L_R16(.]$JEWUV?Y/%SU3JJ'
+M<E:2%$GB`&2Y=3K->@2O[@6_/RFL3['**([!=+*'7.A/.<J5_+=?G3=)3K9O
+M59-ACY(UDS\C-9O^\F?8KH.G=E-&^GS4#H4^A&W5Z.Q1_J@G@B:M"OK55A1J
+ME2[B3,PBMAV*_ZD(VV/(E-NGI;(6;IV*RI*`.E@K5S5JC;S6JF_"#F.XJIY.
+M\=;]J2YN('&@C8YY96%YW$6G#<B2TMA]DM=?4]-=6O(6;'EIG).7`1`>60?^
+MXO&O<`XE3S5J9VNIKM2>4]%PP)]Z$D/;45N=Q_WQAK#'<L?C`BB/8)I([T87
+MC"IP-40CKFC$XZH--L!1FZ[^J57CR?Z//Q2:?J;E\NI+QA?\_UQ=D+:LF;:3
+MJ298:G)PMG4J5AU/L/5'FOJ@ZDL);I*W2Y/:W';.TJ:T'8UC4'M##=9QI:1%
+MS1H_`B`HH2Q)=BSH#]:$X@I(:69_QKI+96'R^HD:WRF[*@G_*O$:A'6,('5=
+M)[F4;"M"J7<9?JY:BRVG[;+795-D]H,,M;>G;9V09MO5A$X3:9V0*:9.^%^*
+ML)W2;-GMP9$IM7SG[/DM=\R>%K993=DA2EN"Y5,>+$?B"`)?7XA8^@.#R^?U
+M>=,V9_AF2.JV#(49^RZ6/*LWS2LR-DMX1;8-"5X2[$:>L7>BY=WD#W23/Y`U
+M_WC[O*;2J'J#P5[<3GW-1&75Z?99F.YRJ5:?5:.U>S0>\2?MO'FJ_)YX9$;7
+MPM[FY("OKT^V!^Y8:'Q\3='K\^AX*JY/XT>(+8E2\4F2]/#*DQE=)2U`)+E4
+M$;45HY=SO"E_#QGL53Y;0SBL7W<(>6+Z'8S4T_1IR]>9AZ?2,F2XINGKW^I!
+M?;'I68Y<)92&)^Z]QEUSY=7:?RBUJ1S)N3YOB@I$=X23F]UC;;/46_ORPY*.
+M4UL>;-JA#\N)Q7RWS^$EW=W=F'1W]8=M4A/+CFPXZS6&NH;@3)>]PY2PF>E_
+M)[WB4EZ:?J(GY:Q;PGJGOJ>7.D6'=C,_AV:;G$.SS<RAV:;ET&QS<FBV"9DL
+M5*I1F=NTR37&J48__M\U*Z[L1T<";KVEEN20I+Q6EKK6DY*0?#XV-85'#M-D
+M\<W$U`2]AIH<(]I+J/;AP6#<VJM`A#M?:EW1[W=ZXH?(K",G_$,%+?%36`AD
+MX"C9FP*94;D^-1%6[W'$KTERKNR00`475C:W-YC8NDL48[4\Q=HL5:ASQ=&8
+MWY.D';QP'=1XK`V&[+$<]T08$6K_PG9IDJ86GBM#I@ZX)9W0]]<DMI"]<)?Y
+MXIT5$@U6)8P)A)1FL1LC$@K5ITP2G_VV9TH3VPVLQWG<>4Y9RTB3<IRF2),G
+M17KVK-+:6%9IUKSJS<TLTL9L4O9_>EY_5FG6O#P\FB+UJ7=VK<.=7)AP.FW'
+M-DFW%+B2WB[*=E`B[9AQ6DK*$9#,I(-<F'(0),O2=-9#V=G.@B2G)ODMW92=
+MJAK3K\[0D>F7!P^:6AL[:.I!KPT<]-K`P:]-LP_)J3415>7NKDSN!DL?I+=O
+ML@9)5?*V6V'[/?JDK#[_92])>U,%1<745HQNK(5T]6[O90VAF%\9X^DH)3'C
+MB^/GOJTMGA1GQQ/?J$GUD*RMH12)FABIDOKT/&DO,7&1*>GMJNP9[/>`H^[X
+MJDPT]6BRO<VJ;F`=IBTOY9E:>VJDRI+;R7+)D@663X8[Z76S08/LD]2SW($&
+MG]7#OKF^M/`T[9!M(M?PU#QI%]D^2\#/+=CD5V?M7=]DB8J!T[)$O+:R3A/;
+M1PPLKRP]R7Z+/'[D7VLC.$!)>DDU6/:404/BCV_9WL0:2Y81[_]O&D)OG?JZ
+M3U=G:5S9DY01RYZB?>/LJ;$Z..!JH:F;8FV_.7MB3429R^QIY5/]ZH`VQG#"
+M@[&C#>O],[NOE3<3;*B/OT@8MR"JJBKZ#V8FZ/,R*:*D^`(N>&W0<J_KW=&9
+MJ=;<YQV4>I3>&PNYD]]?YOZ,VB?QU8=C<]+60M6Z>C1-9AU#219DKK.IH9I\
+MAM+?W9)&9K[$B#AHMO3@*"-#M@`ILY3,(*F[/$/C`NKG>*":',8FI(EPF,<H
+MDL)6*\I)>NVLFQQ*I)S$C/X:7%3NSUP6Y,&Q5+^:AB,6\J:JRY0E?ZN/DY1T
+M]L]$('@HC[IFX=]^%3Y8'W/(%L&GY:/E2'&G;4.1[F%#4Z$H^N]PWS'Y_?7Z
+MU:&AV2=ATLL,8^RR*@NMDSF5@W4?>%DC=*,UOZ#$*R(^5,\ZE!#_CH,S?CZP
+M0B^19DU,+)=F3?:XP_Z8%17_O\ZNK;EM'4GKQ_AMJSRF+,OVXQQG<C959S(9
+M)ZZ:VA>53%$.)[2H0\JVLK]^T3>@NP'*V7FQ@6Z0!"D2Z.O7Y0'A04?;^+4S
+MGY<X:/0(2\8C/-J;Y!D?_\2<G7!ON#'%V\]>ELOY?1OS`(R&YR(VE$J!PL(S
+MN%EHTQ/;NEZ"SE9*U\#+R:0W[$'K?Q@/5<N@+SDY#'YM<C)E6N1T>#T84P96
+M*'CE0&;A?`W>W$2A7*J('%$44\H]N1+9E$A`'U88\[M%6_24=!U+*74[U%UC
+M,ZU(QK*&*[0()V^6>+(*^R6H%DZJ9/]L8^U3!!(0C3CMMXM6V88Q]2@:=N%V
+MG7Y:-A7(A\ZALM.#1.C\_>;PUH...K)0TV9"3>N%FK8LU+330HT[0C[FY+^(
+MTNY%-'0OI^0#DMYB=C9`YL0.@"*M=VI3A5_S^]`ZTJYY(Z.3)K*Y*KQH]-;U
+M+X<MZ-[:R1J^=&[%-:#`*1J(:]Z)U3>9^244CP&/[F*$D5=CV(T4?NQR$`TM
+M[''IIT&3&X`>5XB\*0XZ?3*P"DKLS5G$(=++;0HYJ]?@'K*V18KJ1GOR!(]/
+MB]$J9Q&`Z/Y?]#C%Y"@17VP6)`@3O:@<^"=NDW4QIF4&(3'(>8=VVXIEE%3@
+M!\S<,5_I)E</:V^7`T^%V>W9EW%BQ-G*'S*_^#*TKV%]#RO8![S5;S_WS33G
+M_F[Z",Q._7\?Y5]%]=JF1_2U_AH=*VK9RX.6S<(GTB^^\MH,F$=+U:5PJ5JR
+MC93L(MXE(<7L#PW$Y:-\<R8&\>-"1A90^O'%'(L:J/96[MJ.Q%2*[R;W1;0#
+M1FW2D"C2P9#4.X<!GJ2O@"D]Z2KFA0/;)+W3VF*C?H&7"7K"]=&T76%<=RC0
+M"N.>"N.>"N/V74X3G"!#*XQ;;W*:QZY1@6"&MGDM7*-P/LY2,+0AHV7`-A2^
+M]-AF3R&\*4]6OO@\KR"]?S0>#\PBQ,Q`&THPDN@37F<6@))!&<V:S1Z^QC%!
+M5VF%1RF0)*C?+4^H_Q3/8,09=F*D:[)!?W7M"&<*6"2?`NE$G&(=4P',^UX3
+MC$/*QVHY':M=W4=4+G!;'-;'H'/C39=N(KN%;.7P6P('1#HM+ZSZJR^OB+/P
+M&D.W@J@_6WUJ1PEGN$OI&:[/"1>R"GTZ]/DQL,8LR9P6!2$EHA0T=T[:+,<?
+M3.GGG,BIU)/7]="N=W6CM[/\1R/=I.`7KU/`74&^V9(+PUA$5,R)/F3OQ!X)
+M&L2,`,%;H<`CI;ZD6<=4$OQ$'B1L+J7_/@-.)X2H<YKM)#A#FYA]D4EIN^!D
+M@A32_;_?)/XGWR#5*UQ0Y#P;/G!%ROC3O'*D5C<9JH4)`X>78;=JNO5^#-(Z
+M`-U@!GD9+1(C0UT`Q]_7Q_;YY5E<U,T/L/=&#183AE"\-X*BCL!N+;QA>*_4
+M>L"ND@FN7NWN3&Q`^M11<MAB1HG^WL^,=NRMX*VG=%:,V;8@YZ5@'/!TTE)M
+M:>G+M/043QUV!FY%::G$"0L#WY]:J-C'21MC>Z^"W36%XMT3$$E?`"*)RADD
+MB^0`JNP:DV2V9(Y1&6#1"J-HROABLG?U]"C:7%-`C"<]SOYL!?NU7_Z6Y;7/
+MD"D,'2QU@\2<H]5&HDMO3-Z%&,-`;<0U!G47_>XX4,"H(A4R'J*U30\Z996S
+M*R6$X1V/J^WSX<]H;L0ID`$H;(-T#S'+BQ_71VMVD_?XVT4T(GV+T*V4^<0A
+MO"N47E)(A86)TQ=FR]/]O]Z^HT_\4\1?I;U-;7+)-!#%Z3;BS=)V+C]T6*L9
+M2G9UB^F8L+9\,:F98<\XG&13T"P@/_"9JH5`MO+&[@[8A$6RW^V:()\#<`K:
+M+]'=_^Z1\#T26!I_JV?V9=(JU=?P/I95M\2Q2I@]PJMNOW@4R+?\.D?')?V:
+MN'>MQP]LC)!]5)+(64-"O]M'H_,=!L!K<,3<02]AUH8T_CEX4OA>^HQ8-VWG
+M:1R898D,[6DF_4EL`'''2;&3)%_84%\&!.7`%_HI'_LL^JFN)20\K271CF1(
+MUO%)D2XU_!+QFC5^%H(ZQ6Z<C_;]^I+><;`^M"/?;`0$,W$V)L9&::S5XC-8
+MA]O7YF_'_>X`@EYX3459=J))VE`*#-Q7SE;:^F8,<_P8`ZW/:?(XE)7?-'6F
+MV<U4DIIB!"'H$/;*M3*L%R=-NTV!@5E.`/%HA(^D]+0NHJ,0-5IGMDJ&/-,>
+M$#D5B_FY/]TR=)RVWG6>7]\DUUP9VS$'_4VPP#,&X04YNM*X1DBWI$\R7")L
+M\CMJ!>YPY*BDA"^NY0U-2?)&/LY3>>R^*PZ&):1$+H\&=;X\L\6-OIJFV%G9
+M<9[*8_==<;#,59,5[K0R)SG8:<NA31C]):))Q$4"5^AN_0A.=D<,GP,&K%LR
+M!:H=(X0GK12(G9#"*8]&%0R+J4\[G>(YU\"7Z]5J_/CIC[\58B$4CUZOC;(W
+MD1=0&8<2@?<0(8S?V<9"'_CZ$*3"[RGXH2W;O.#(ERE&9O4R87*6Z.Q>)A;.
+M$I]*(Y]*(SD0SA&/!:*SDID'Y(BED<Y09K(FW0,I$9VMC"]4.J>SEA%QR(G>
+M7@:TISH_8U<_9S0,Z"]<Q@>\$'P>YH9E)2%@12SBJA&KA*W6:HR/G$72<`1?
+M!-<%>3D5G,V]KD,@VXFE-T$%T/8#>%3=>F`HF.0^EC7)4F#=H94E(85:.]8=
+M0C2@"S4*\A),$@GHJXH]MCH3]@,;GE/]!ZW'R:)IJ6P\4NG$FI+&R%$TQI_+
+M4NWY/!7.:1\,SV_?%:<MR[<GET?+5J/)]FH\JWU7G*Q<S9/+H^5JELRNA_#B
+MQ)!P>J%R.B<Y1,CZH"NC(%"P<C(,25:FX;U1[1B#8PIG\)2(C>7H;'JP1!W+
+MGIW9F]H2LI5\PA]=$J%4OK!GBK!>_@IGA8L:\[M1RMDWH_1NAHJP)G(VZ+#]
+M'H5]5LJ^,H!6+%M2MXS#<OA*"+$)D-3#'H-!K&N>C4T_QJJG@,N$$$^6>M34
+M'W\>T%)BZIE\:2<@-0C#RZBZLN>IS?OH"*!P:?&:LD4@1:XSOY!3)%$&F>+!
+M!S;)A,]LFGGJ2/CDIIA^.460%6\4;7=L%,V-Y18]P)#+B6(6A<"1LS0QBRO@
+MR%UY=%<:?6CYU]4`NA#+0U:NY-R"F(>@8TL8@W9H?&K'$IE2]`@<1>G&G$\Q
+M,$HIV(XS4_0';8H&KJA<!?94X0;,(YYF%:LZ$..?<S%&5HM53RU*8#K-O;\[
+M?22\X__YT0DRF0I31:"("_+#Q37Q[A]_?,55MAD&"%345H],W=!H?@K+[P0R
+MMK)0$-27`D].GAF[Q$R>8.YC.5&5QH!H>"E'B1"(\6`<+9Y6E9?9ZLA.-#;B
+M0.R)ZI^,J9J5HZA$S"M8;6?3!MW9=`#.;#J<1FZFR,KRQ=0B$=?<F,"$.Q>'
+MW,68(E>,)ZY6&TO#89Z6C:."3>9T8O!+E!U"9MM!PU,V"]0VS-GKWI^JZ_UQ
+M>6V#;Y7!H*0-]R.;`WG'12V`TO=;B_''>1M!'A^M/(Z;=TQS2*7Q0`T7ZW8Q
+M'7L#$KP).55N$;+<,)"`,M$0*+<"&-(H864(JGM3)4U%&KP:[`*I>&`.I06P
+M=SEWUNFCZ=I"962APA+*:X`QB-76'G*CH.5@+0/IQ$7;;+(Y/^)B$]>.C%_3
+MZ@S/:O%I!P"^JI/6WRF^3HE5Z:5DA?`P\=G%-USZP;@*W,H9"\PE_GI\;PQX
+M)Z@^R:K`@4@TAL@T/#J"DG(R)APTP9)SENB4K.LO%(A5D3K/J'#-\/:,^:T4
+M".;I9B_PESH;<]1.)V>V(D5A9$U!T%QC+&<RX2DK$X89OZ&:#7@WHFE/Y4RH
+M'-GIC`D[J)BC88=D*16674RH<&<HI%/8$2<JV^BE-2\6,\$M'RYI;PF_)\_'
+M32@4D>01*]X;6R".'A1+\9X1J[Q`7Q^+=`5[H4>3TR5GO*Z'\I0.FP^`*5^Z
+M@M2_T0`>BN\@-O21,<#ZN3*I6&V^=>2?V&@#OJ(/)RF2D72=4R1,1P1`"H6D
+MT!P(=XI![N1:[*2NQD>.\K4?=_+:K%3Y%!<6(#"TA7"V4EB`($QTSDFCGA,1
+M?'8!#S-2*A?P9.-F@BXJ&BN*H`MZ<TV(5XJ8X9TI4R9:.]:;C=AWLIMU-U:Z
+M+8EVU8$I3NG]2BE/QCL5#9C\2VX@U+8Y9*7"J$JE5*OEUZ'E,IW=.BOY@0D4
+MP)/0W)RK]]^PRIB]&'UT4]PSU@0PED^!J<VB`S?&A<=PQ8B$F*V/]:ER7_5D
+M$:Z3H_2J6K^SJ-I"@,E\$8WD59YWHC&C==5924^S%G5=.U:[FYG^2I^NJ[8P
+MRX`S'R@*UE%.!<X]=*<CYQZZ/'3NH<M'G.*2(&\D?147&65/XVH6(WQ&!#N\
+M+E*F%8VL.K76.B)HK(1$L9CI+P`VYXP(IF'`N]"_02RW/'*Y91!U4SA:=8'-
+M?U*A[6D>R,331Y$`_1\<Z5R4+$JI2/P8)$0KJT3O.S*8.13&AH;/&U)I6`,*
+M('S(/GNM7PJ_"]>+*U&-JT>BKISWOTZX/;$R"FYY8I@?(XQ]^K4$DKU`CJ_(
+MEH!/E!X8?3U&;TEOKS$:E^I.Z^JX4>35\5F_03R9J\&"ZWT&5W@D6<B6<9'5
+MQ!/].*CDFHVABJ_OC7/PQ)[M\(T]6WL9\AGH^]NJ7R+!Z2C':[)XL]<T^J_#
+MBV#?F6CWA_=7E>O0RD9\L>\-C(Q.K'$<#8[E6#JRU;.FC]+($8ZE8;<<JYEF
+M:>`)Q^JF[VN88'5/QA>L#$_J:.<J5U8.^Q0F;U4,3=94A3]#F8,_0YFE"YIX
+MUO11^-2*+/U^;JPXF7+?$K`EF'XH+R4)IG+XH\L\IZQSLE%N1S%)0BN5,?OX
+MZL]2)S$UKOQT8C8O`.YF4,AW(.,78E-366@P2#G<;XV6JA)8:91`JI9X*2HO
+M8YV$9-59LHAAVM?1.LA1E/)KJ!0`>18D['"!1['70:B96I1K+`.C\I!!AV@S
+M&OXRM.;(VCB,MO;`,*K:`\9N2,9S93)498/LC!GBQ,I^I0`+6(;=($D(S@\V
+M6_"N[5:Z#XZE9CUJ(T"\%:D],(RJ]@!`A7Z$&F6P@D+@FE,"62J8RN\XF?MQ
+M?W?BL+/)./J3*2-RSO)A\K:;FJC+@L-P6?86+@NNPF7!3[@L.`F7!0_ALN`>
+M5+3MY+63%39H)L8BBXK8%/<LKRTB=HZ<G(\%DT]A')F'?F4LU1HO<;C6>(FE
+M98:<ZP2.?(`36`HWH-9A*VETSL_#V:9-2B,CK2.6H]K]VSE+J'*V(37'O?>H
+M]*00*=+8[@HD3R&T"[M'%132@J'$6$76APSZ[][X)"2;V*!EFB'=^T/<;JGL
+MH7H4PK(PP(NLN"AR<PQY^`Y2,#D&XN3T,[L;QLR6<-,NP[/,<5"*:2)MBJFB
+MZ.*4=1CAQA30&)>M9'F@324K%07V.Y5L3"I[`BBRP-P99#GM,JL(V.J,>)K9
+MHT6B4T'1X9%)$B0_RIP.V=BZYJ7:)ZX3-,1U#$T7C.X,20!K.(%K"Q2I,6J(
+M$6Q,P8S)56RX"IH4`<D)P812M2O),O55L,R0PE&"WG+RN((LE)THB30#%``^
+MP<]$GO?'GABBL97T`"I,FSP3:OUGTXO&=<5H(6/)BT]\4[!(/I!%4OMY>NOG
+MJ9^YK$_2794:J_:^I+_MO4+'X;J)H/*@;1)T9N7[=@'6.N/T0!4RU3Y*WM]:
+M@_J(=>%K*LV8@L/:B>)?@CHSZKI5#\5L\,6-EF\=')%E0NE=G*)R'VB[N4JL
+M<0-T=,X]5CC,4U'"QNPH+`+D5-K9?^'X<M)+C/')Z(*@9GXGE/?9+I<"\9(9
+MA^(J;2S_D2PQ-UA`;=,.K1JGS#KY*+08[5\.CY2HFDYNWO?2Z7_M_.F$+IOM
+MY%A39O'$P.B^/S5(K!N%,<^OXKQ`9RQ83%["WK0/5X:8B@AZIS?FQCE-"/%.
+M>T?X)7!U![6!K,#,PTG4YTL6AFA&3T9T%";*+%G82SS$FDV5X+@D2@ZOS)EH
+M&K"JG4DZE"6.^W6=4POX".XCKMN9@YVPF<R:6A@(F4)A_7A>A[LZO**0N9'Z
+M!83#K[ZNQ^9@W2[:0@#K6O)TI*7ZH37K=GRLM"[?2_97)E!_D>52?$]BFX>\
+M8S;2YS_Z*9].D5WPZIAQGWR)W?#+CBU-C9/BWGH,B\IR@J&L+KTK"B7$J,%:
+M8(B8$XYXIK8$H\1H[-`>MA?]4PGHJ@W?0[,F;+.4(7NG$'($#X!]#GF&+IVB
+M<^54,$)=55Q7(JG.6<"M1J-(V*T<5G>-UZ>"GO4:KN"\SJQTG8O;$'^S+5@Z
+M/#DF9GH&W.*F&>N5O]*P?LMH`KONS@UA$IN?NW`?]4F`DD(13A>V=8*#]MX3
+M['XXR6Y.L\'V>8)MBX1F[#$K^'Z7NW8,WK/A>A!%I0_CTHWNE?5XP.4++9C&
+M4#J5`3Y*O#TFT"=5I_855'5XFW/$+%-Y-3+S23QTG@*/9L<(1X\VQ7MV`=&K
+M9P'A4W0&>Q4P[I\J*>F%-8BH^BOJA]/\XWL#N+;2B1'YXNX&&*1*;?(RAH*7
+M"7I,5T\DSFK5)%)`K;$?]_"NX$'PM&R<I+1;?T=^)#X\1VN&PMD.V>E<!$0*
+M%DWEL71Y0&/&*!1*-/SC>P-BP:S)$;G9Q@\@S\!'CD8EJ[PJW0U"CRSS63'W
+M#Z5B[A^FBKEKQE`X0!5Y%Y)VJI?<^ZJ&J`"3(,RDF)D(YHFE$+U#Q0`9\CBL
+M'WOZ;96"Y:_CG?SBXT?3X63P?=J::$T(.Q)`4Z#:GO9X5=PC$:'H#@HEJ9JW
+M'^)<$I1=:;T4^BK-8>_!5)7O+;FDL/R(!MA[?1-50$=#UYS)/I8X,=%4O*JF
+MB&7ZM16)RW"U-:J!`.5$V5I/@+=OPI8@3#FGO>R2R<$P=#!X=IX8[FSH*5#`
+M,6CMT?@^K2EFFV"BDZJDV^B\CV*GLG^DDBWQC(S'T^KJKP3PG((81%ZC#.R4
+M!-?VJ_[12![X,;<<=I37@S?VH;`='H8UP"*^,S"53GMG8+_?'JU5*174C`DI
+M9V9C/4(4%%@!3`B-]JI(G4#ME-&TIT-.ZPJTI\+YN@)MO<EIOIZARMLV-'9Z
+M&]HT?'I)9LQ'>/$K&W&V\J1?0I/7*[UCB-I?GNY[$Z*O/CM4`E\$U8J3B#U5
+MK^"3S$\%)M:VIS<I:5$`9.=I)G`$MY*P,=B,ZP<,4BH"Y2)2-H:7E<%RA4^"
+M(>FY*!$"!-"A.1Y*.8UUR[H&[!O]KOM9'J)F2DZ",<=TW$2H4_$%)!](D!&,
+M/V0]GN(FK37*%JC!-OU614"!0JSVG^3&B,^R4_GNYAU1J3B\]?A'6:MT@0)O
+MI<RG89W52[B%SFI5B6)%XGK'6L4U>JU%/BQ7EK>7M0:68H[4A3)A=,.A;_I.
+MS",@1TERP\M`2%OIT>(6X&CQ=DPA-O3AE.BPMA49_3#!:*88L-3E#$*40.7M
+MMZ\@W.9Z?52/[!NNRL)D#`7LXED:VL7S*`HS?,1;E[H-J7D>FT?A29O45DAL
+M7>\G&)BSR[_8>K.9@GO#O7::&?;7:2:5-)TZLC]Q3=%-BLP,BD3QCJ>8RL%;
+MY`_O\',<$EU:0:S_%'%);Y45I!ICPJ,RF/P;B\E,&P*5[X9?`EZ27SE\,XE#
+M/TELU[&NA!W5[Q_:M)7B&LAP@CJ0R6`)1AU#L`<G(=Y+@R?34"=.?@H:/AN/
+M@K_20$HK;QU!*S)Z1)SAW3/6/]<(WHQX0I%)&2,^Z(R5[`H*KUQ6%4-ZF1BJ
+M%_#[.VND5+)6SGT]G+&C'2,/8L:VLV!ID#SO<#QENBYQ2VE>%R?3O"[>2_-2
+M`W*,LYG_.<\0A0,S$6`9-7:T6*/$[;NJ'DG&225),E:L;9)Q+&`P?*+/&*HN
+M/E.[Z$*MJ-%J&7TJ_;8RI4IO5!V-FU00`Y3YO3Y!&00$<4`V?7:Y9&]66_/&
+M=,-&@AINP[57*.F&JM;V'Z.J'^5OX_TDN(!^B'H@:+8.UR_\YKV&`4PX;QL+
+MI0:9-4$IN]!['W^PVD8`O]W3SH#YH44_RC&H*G.`56Z5U9^[.^UQXFIQ#7`,
+M'TJL-@?E>"IP7511801MT%V11_MSF4?;<YE'>VR9YRV.V0Y;YJDT@Q@YFJ%(
+MFN2^-N9NX]>LD9PV%JQI8S>]>^>]XK3L$USH;VQ96U,;KW/1L9V.CAW#5V'%
+M80E;2%J<_G3N%;`.J@@1-B`6?10'EM$,[:J?=O.$B@??1*6_B=PC#=$-EB+1
+M$1F5HR/>/SXYPG)>V6E^RF>>HBH\W:77D3FV`.MR#U+0G@HAW-TJS*6&M@-#
+M*PP#H(LP\,48Z<+1OQ-&L"+]EE&:`NES1OH.%2U+URC;`:?-@#C9]:LS`LXF
+MT"3L&`:T34E\]MV6<.E.ATN3.;6`+D'QZE+:ZC5\P$&#+E0$H$]Z)&T+%^.8
+M'HJ6`O7=H1KYV!](C2Q)1EU1M()U_4>[5TF7":='9"'@OXU6O8[*6PQ_,DP*
+MPS/OF3/Y2R&>Z1%9X4Q:'R:*9D9FH6!FY-EBF9%L"F5&:E8D,W+R`IGI5*XX
+M9F2XPIB1OE+1:/'W/`/I(BA!!^>`MS\A12:$]6@J<EZECDX%PO.0052'Y_%)
+M!6F(T0I1?\Y&Q+7^._M&LGR;#<<PO)J40O9E*"_#]*\W4<<KL1600X$;7ZGH
+M:[AWGH=WN&?.=_$+Z!(E][<[R>O!+QY?ZGN(#&IKE([R;.VI+.X91JG5CB89
+M-H:([@<!A-?>![TQ4G0HFNB\/&<M+J>8SFMBNK&PNF"*PD;4B460:R]I)WJ,
+M[60+$6.+6R*7NXS?A(HCV*=?14!F^>VT(+.&N.\*1`?49&%>#5%P6A4Q&C@4
+MS6:RDTUL!3'9V[;I-F-&@-@7QR=\FI-CM.E\BO<IYTV[=UKK+R+#SNE!*\E@
+MPPJ821G#182PZ=(B$N,NG?/G9=?^^=((X@^A?*D\,X;Z5Z%/`HW+-@F[U"_+
+M19&7TQ61ER?*(2\G:R$OIPHA)P8G[,>P?4K7S[+>\RH7&-2EBKFI?&`75*WV
+M<M$OHU;'N=RWSJV`C@P,%$SJ2)_"MXX3AZFD<<^"?+1/LN%PB75/@ERV;`RE
+M'K\W[FLTU1JEG7U`RJ)/4`@@S\4Z=__N$6A&RQZ2*^P,:/BBZS*?13.;&:4#
+MWTB`6^]^AI7L#?<1"YD(<T-G?B&`0G'S*(HOKZ6-)SFK2QSR6\/22;L[I4!N
+MH=PBJA8>PV;#&B48@>)F7QJE"H_J#S(<^XB5/36`%QL.E7XX9!0UAG-K!D_Y
+MGV;H)8.@<*OD4"]QP+=.BTF,!1%PC8LV^@Z4X'1;(NHJ]4P&^[/["!K.F4G9
+M906LCN:=7T&C!M*M&3>X)NV:C/24D[J<I$Y_.<].+Z1=DY&><E+G283"J);N
+M6+##TMA;Q_:.WTG5-/IC3OJ<DU!;)(UDM!RHRO&V;DG>T8P18DQJ1P-P'T>"
+MA"U'D\(!3J&$"&W66*'HF3L/5?SQNNPX.?%HYM6FW5PJ`VN#I8BU(J.RM>+]
+MXT](B#;&*>=.F@I_H3X05[AA,XGGZ1S0_-[."D1R>)@?(:DFAARS]%7E,1V3
+MJDN4X=*^<2L66P*&C*+&H'7`C$$*(V%8`,=822ZC3\'I3J'I*KVNI:PDJ'G2
+M#,\OAS57<K3@UD8>BP`I)N.F-=:U>[/^$XITD4<!;&BT;"E>*$DL"7(E;/3C
+M]RR^5U[*!(*@EJ_Y(EN^A+1K,M)33NIRDCK]XB8[O9!V349ZRDF=)T4L`_Z5
+MJ"34QA59"A^^KN#$CN0)MKB2)]CB3)Y@RYX7OR<L)1\D*DPYI<4\;IVP;+<[
+M]6*IPI!!YK6(8#F]V:P/ZPR!8Y,!;VQ4?D[,<DL"*(9[G\P$H]?W*;U$Y0&Z
+M1$L^(%XIOLBELQQ6_79+H(#&/,;)6(BZJ9:<^VQ4V`+/5HL@KH>_93RAC9[,
+M=.*9'C65_H7K97(7ZNAX[73,GY]'SUJA[`X(=JT1B]AWI;%"P3IMOF@BB:K3
+MA]$3F3AIT$D8:3^X""HM@]"D!(&7:$22.F2RXWZ>7Q@X8V.JWFVLDB8+5ATD
+M#=:H?GNI?S2'L8!+K!#/Q&TF/Y)QFAEB<ID9\BL)G_%YDDI9@.U#HU-:7RBG
+MEN.F4RBHYR3C@.?$K/=[7707/_:<?K;2#LMVU.O^3*R7[,&-Y$U_</ET7^[:
+M&&R-4/E^M=KU+'K%N"#(HGW$!T?OHC9DWW=U*M>ACN#B%$J-Y,RN30EF.2*M
+MNXQ\::[N+:!_6$'"V[@2RT7G52!%086'=>QD-'C@DF8,D1<C:T'?$!N:4EA4
+M.D?7PZOL/W5R=2=;?_P%Z-_YV*?6.4$7$!:^HOY&<,&!@L/_'`[X_Y'7`.K`
+M+*"U[]_PWS9=0+7/:=8"SX4:E!IHNN>KS\W;'^`@[T<Y>VR=_W%W,=LU>*WP
+MJ7^'_RU\6N,C-@FJAYKAIL(W[=IA)@QI[ZDO4+UW^QR^>S#4!BY9U/'XW2;-
+M%@+<X3\(I>%FH,E6?&Q^QZ?%>Q<TV6,'3?[5H$F_E&GAO>E>97IST[LTO<7L
+M:UB-8#'",Z8VG=/T*]>?N_ZEZR]<_\KUES.J;8Q7EA9=5_4JTYN;WJ7I+52/
+MM?-40'F&<@E<ZGZW"5\KMF"EUPV\N.I4NC/7G4O=6>C.E>XL=>=:=VYTYW8F
+M<A?.)K5I0J9?F7Y81,+J](_PSMM1<]>_=/W%C.W/<$%955T;+_ZY>?K;$;\+
+M,)JI_^<(2?(-H"-G+)$`-TR'++N^@V=SA,H3YIYP.?OOGWOP9L/I4A-/9KJ5
+M[<YM]W)&.#!PEMC"D^A>97IST[LTO<5,YH3Z@6[@656GTIVY[ESJSD)WKG1G
+MJ3O7NG.C.[?FHG8*9@Z5F41E9E&9:51F'I692&5F4IFI5&8N<S.7N7T>9BYS
+MG$NUY,>)#7F<TJET9ZX[E[JST)TKW5GJSK7NW.C.K;FHG8*90V4F49E95&8:
+ME9E'9292F9E49BKT./FAJ$>B'HAZ'.IAJ$>A'H1Z#.HAJ$>@'H"^?7WS^M;U
+MC>O;UC>M;UG?L+Y==[/QS8GO#8DX\!QB"Q^%[E6F-S>]R]F'=JQA*X5S?(A[
+MSP>S]WPP>\\'L_=\,'O/![/WZ-Z5Z2U53^U+'-[`DCE,)#5Q)J9;V>[<=B]G
+MK-O@:6*33J.[E>W.;??2=A>V>V6[2]N]MMT;V[UUT[B813\Z3%EW<-*.4'G"
+MW!,N/6'A"5>>L)R12"\3:`[ZZLU!7[HYZ.LV!WW1YI"N2`EN<,:_TF[Y5]XL
+MR<J&$5^T9_XUVT4/[7.#,J`TSE??H+4"ETFDP?S2@']T&QRD^97NS-7@(![3
+MX%B_GL7YV#E?47.%D-".M7MY%O9N_=R,_LB@D^Y"OWS"TA$@!-]86GBF56%4
+MA434VT4#X?8Y:_-QPHD!\R5FO+@_JL"(DXJD\&[/9P-^6@.]OS?7TJJN4W-Y
+MF:B5-!=75]*<7RP35<9B:,3/W6%]Y%N0$0LY+JB^06<*:Z$<<(1B6F!9`H5"
+M40$@*E`I.N<`=MS$P^1:@$K3Q.<?JV'5[P^>!&5J9![75;RKZ\O8O+FXD8/&
+MALR">(7AI6OB%7;;]4JF:3GA0NWFO(KG@Z'U\UZ=\KEY[M%],OBS&>)8#V"V
+M.:\62T>BE-O`N%87%0--O:Z_-ZNG7NX<OJDAKI#RV/7@>/;O:W!P8I+1=@AO
+M3_AA;N+/OEBDMV&QG*?V31ISE1YH=75UK=II_-5-_+7;3?.\[P_@0*G9?#4V
+M!68DAJ-OT]6683]-[^=5:J>KP?8[I-UW2)OOD/;>V$R'S2]3<Y&:5ZFY3,WK
+MU$Q7F]^F3R,]B="^T!\'&7SG:"I\#)O>H<1\I*)\3?VCQ-UB@0[(_8P7J6[C
+MR[?OQ_88W^-^V(3WBZ)59+UI>S3B;:E-<5;4#I/:-%W[3#V&^9<.9")Q&VQ.
+MW'S28]!FBD:!8]V0?A);8%LX-,-SNP/_%^"B6U[*,B<FN*=V+ZBKA04""Q%R
+M&VU8KGV^VO8O`RPE'"L>6H^=C*)6>%%NH;?>_63ZFNPB?WD9A[]T[>-?ZO_Z
+MK^%P<=[/I'&.81DMUEC;G"]GT3TN6TVRUL@')CE=#^W$``*Z^OCE=<9V(+3]
+MQ"9^OJ9;Z:ZU(+5]CP:?IQIO1%F=P#@!^[-K1T-(ZE>N/W?]2]=?N/Z5ZR]=
+M_]KU;US_UL\GFZ"?8>6G6/DY5GZ2E9]ED-X9<P.>4&KB`S+=RG;G,W)7P&&Q
+M)>8`L)JRJ8";CB-F@M2=V^ZE[2YL]PK>J7[/W]OK5G_(JG>.UMCO3;</\A;!
+MBUL^3,I3JHPRSRB7GE(M;F$]@8!&7EJX>4[9CN1*^;YN=YI'EU?=RG;G\'$>
+M:;4BZ:#B)J4ZQX]_+U\R.K.AW:$$#G4#<?61-4^)/Q>Z4^D.F)E`KD6SU>??
+MTS^S#`@-C5G2K%)SGIJ7J;E(S:M93$9/!FA>!\8#FUC'K'<.IME5]#:'-9U\
+MUVE@($M/XA/),`QK-]FII04_HUK14^<<LR&V05&M+BSCC[`16\(\2(Z.$C9,
+M1[F&TU!L2+12B]W<S#*U^?W0_<KUYZY_Z?H+U[^:L6=)6:6YU[\<MEU/*Z5J
+MAW?[DA]RO^7'!`5Q3"L\K:"1_Q@UY7^;H6]&VDWE1O&D=;][]9WPF5Q<G0>)
+MPQ*#$#0ZTF/[5*"&V_B9D^'Y.4+E"7-/N/2$A2=<.<)\[LX*,8EABSM?7!7I
+MJQ_G0;)U)\T(UYYPXPFWV<WEMYO=;Y7=<)7=<97=<G654?R$%U=+?+EX649L
+M/DHBB\(6?<U/S8['!#5EQ=Z;I[J>2YSWYASC*W8OD;"J<>SK+P\&S`IV!?_2
+?`?"FP!6H`L>O3RB,_[7!^Y>A^>69_!^!7='O.8P'`+"J
+`
+end
diff --git a/lib/compat/compat21/libgmp.so.2.0.gz.uu b/lib/compat/compat21/libgmp.so.2.0.gz.uu
new file mode 100644
index 0000000..520442d
--- /dev/null
+++ b/lib/compat/compat21/libgmp.so.2.0.gz.uu
@@ -0,0 +1,426 @@
+begin 444 libgmp.so.2.0.gz
+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
+E2%*;GN2XS9#1*/SJ%R<CU-@N#+JI7^CLE/X2_P0U&_WFG;0``.P%
+`
+end
diff --git a/lib/compat/compat22/Makefile b/lib/compat/compat22/Makefile
new file mode 100644
index 0000000..94457f3
--- /dev/null
+++ b/lib/compat/compat22/Makefile
@@ -0,0 +1,38 @@
+# $FreeBSD$
+
+DISTRIBUTION= compat22
+
+LIBS= libalias.so.2.4 libc.so.3.1 libc_r.so.3.0 libcalendar.so.2.0 \
+ libcom_err.so.2.0 libcurses.so.2.0 libdialog.so.3.1 libedit.so.2.0 \
+ libf2c.so.2.0 libftpio.so.4.0 libg++.so.4.0 libgmp.so.3.0 \
+ libgnuregex.so.2.0 libipx.so.2.0 libkvm.so.2.0 libm.so.2.0 \
+ libmp.so.3.0 libmytinfo.so.2.0 libncurses.so.3.1 libopie.so.2.0 \
+ libpcap.so.2.2 libreadline.so.3.0 librpcsvc.so.2.0 libscrypt.so.2.0 \
+ libscsi.so.2.0 libskey.so.2.0 libss.so.2.0 libstdc++.so.2.0 \
+ libtelnet.so.2.0 libtermcap.so.2.1 libutil.so.2.2 libvgl.so.1.0 \
+ libxpg4.so.2.0 libz.so.2.0
+
+CLEANFILES+= ${LIBS} ld.so
+
+all: ${LIBS} ld.so
+
+.for lib in ${LIBS} ld.so
+${lib}: ${lib}.gz.uu
+ uudecode -p ${.CURDIR}/${lib}.gz.uu | gunzip > ${lib}
+.endfor
+
+beforeinstall:
+ ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} ld.so \
+ ${DESTDIR}/usr/libexec
+ ${INSTALL} ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} ${LIBS} \
+ ${DESTDIR}${LIBCOMPATDIR}/aout
+ @${ECHO} "libcrypt.so.2.0 -> libscrypt.so.2.0" ; \
+ cd ${DESTDIR}${LIBCOMPATDIR}/aout ; \
+ ln -sf libscrypt.so.2.0 libcrypt.so.2.0
+ @${ECHO} "libtermlib.so.2.1 -> libtermcap.so.2.1" ; \
+ cd ${DESTDIR}${LIBCOMPATDIR}/aout ; \
+ ln -sf libtermcap.so.2.1 libtermlib.so.2.1
+
+# Get all the fruit, even though we don't set PROG.
+# XXX bsd.lib.mk has fruitflies, e.g., it fails if LIBS is empty.
+.include <bsd.prog.mk>
diff --git a/lib/compat/compat22/ld.so.gz.uu b/lib/compat/compat22/ld.so.gz.uu
new file mode 100644
index 0000000..a689dae
--- /dev/null
+++ b/lib/compat/compat22/ld.so.gz.uu
@@ -0,0 +1,702 @@
+begin 555 ld.so.gz
+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
+EL.&[&=%WO^]^W_V^^WWW^^[WW>^[WW>__YM__P\[+-(F`!`!``!F
+`
+end
diff --git a/lib/compat/compat22/libalias.so.2.4.gz.uu b/lib/compat/compat22/libalias.so.2.4.gz.uu
new file mode 100644
index 0000000..a559174
--- /dev/null
+++ b/lib/compat/compat22/libalias.so.2.4.gz.uu
@@ -0,0 +1,218 @@
+begin 444 libalias.so.2.4.gz
+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
+G&^`_,PG@K_7Q?ZP/_'^]3_O_7WS0_S_XAC_&1_M_!X]?/@H[:```
+`
+end
diff --git a/lib/compat/compat22/libc.so.3.1.gz.uu b/lib/compat/compat22/libc.so.3.1.gz.uu
new file mode 100644
index 0000000..678f283
--- /dev/null
+++ b/lib/compat/compat22/libc.so.3.1.gz.uu
@@ -0,0 +1,4571 @@
+begin 444 libc.so.3.1.gz
+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
+I^1C&PBP+E$G<G*RJ66F6RBUL-IG.<3QL>L1V8Z5:W/\",$-+/.V%!@`T
+`
+end
diff --git a/lib/compat/compat22/libc_r.so.3.0.gz.uu b/lib/compat/compat22/libc_r.so.3.0.gz.uu
new file mode 100644
index 0000000..b5e6a2f
--- /dev/null
+++ b/lib/compat/compat22/libc_r.so.3.0.gz.uu
@@ -0,0 +1,5062 @@
+begin 444 libc_r.so.3.0.gz
+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
+$]$H'`*02
+`
+end
diff --git a/lib/compat/compat22/libcalendar.so.2.0.gz.uu b/lib/compat/compat22/libcalendar.so.2.0.gz.uu
new file mode 100644
index 0000000..37b040e
--- /dev/null
+++ b/lib/compat/compat22/libcalendar.so.2.0.gz.uu
@@ -0,0 +1,44 @@
+begin 444 libcalendar.so.2.0.gz
+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
+26;7JS]'_IU;]#SG]_MR$(0``
+`
+end
diff --git a/lib/compat/compat22/libcom_err.so.2.0.gz.uu b/lib/compat/compat22/libcom_err.so.2.0.gz.uu
new file mode 100644
index 0000000..e22382f
--- /dev/null
+++ b/lib/compat/compat22/libcom_err.so.2.0.gz.uu
@@ -0,0 +1,47 @@
+begin 444 libcom_err.so.2.0.gz
+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
+7^E8T>VEW]W_IXI9U;_\+<CT79<`A```C
+`
+end
diff --git a/lib/compat/compat22/libcurses.so.2.0.gz.uu b/lib/compat/compat22/libcurses.so.2.0.gz.uu
new file mode 100644
index 0000000..04a65b2
--- /dev/null
+++ b/lib/compat/compat22/libcurses.so.2.0.gz.uu
@@ -0,0 +1,401 @@
+begin 444 libcurses.so.2.0.gz
+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
+$@+X``%[I
+`
+end
diff --git a/lib/compat/compat22/libdialog.so.3.1.gz.uu b/lib/compat/compat22/libdialog.so.3.1.gz.uu
new file mode 100644
index 0000000..c0dcadd
--- /dev/null
+++ b/lib/compat/compat22/libdialog.so.3.1.gz.uu
@@ -0,0 +1,809 @@
+begin 444 libdialog.so.3.1.gz
+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
++;_\_G`,[YH5*`0#W
+`
+end
diff --git a/lib/compat/compat22/libedit.so.2.0.gz.uu b/lib/compat/compat22/libedit.so.2.0.gz.uu
new file mode 100644
index 0000000..d2794c3
--- /dev/null
+++ b/lib/compat/compat22/libedit.so.2.0.gz.uu
@@ -0,0 +1,681 @@
+begin 444 libedit.so.2.0.gz
+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
+5IMQA[+C,?>O'!_N_`?*?S.:-$@$`
+`
+end
diff --git a/lib/compat/compat22/libf2c.so.2.0.gz.uu b/lib/compat/compat22/libf2c.so.2.0.gz.uu
new file mode 100644
index 0000000..24cb150
--- /dev/null
+++ b/lib/compat/compat22/libf2c.so.2.0.gz.uu
@@ -0,0 +1,714 @@
+begin 444 libf2c.so.2.0.gz
+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
++J/\70]PS!Y,W`0#^
+`
+end
diff --git a/lib/compat/compat22/libftpio.so.4.0.gz.uu b/lib/compat/compat22/libftpio.so.4.0.gz.uu
new file mode 100644
index 0000000..b61824d
--- /dev/null
+++ b/lib/compat/compat22/libftpio.so.4.0.gz.uu
@@ -0,0 +1,137 @@
+begin 444 libftpio.so.4.0.gz
+M'XL("#S*_38"`VQI8F9T<&EO+G-O+C0N,`#M6WUT4\>5'QG9%L9@!PP8,$'A
+MPWQ$@$U(&R`0/BP3NC@XLBTG9(LJK"=L8TN.]!XV-.8C#Y,(5:RVE#1GMQ]I
+M-\FA+<VAH<FF34O,Q^*D35M"\]DF#4G3G.>8]A"64H<8O_W=F9$E"TA[3O_:
+M<_P.?K\W;^[<._?.G3MWWHB7V9Y.5L(8RV?\*K,P9F?)JR;RIUIWE4&/]^TZ
+M<2LHH[H-A6A)[/;#/;9X-%OOZC-/WZ7WF]K_QI2+]VWPO'1"M$LVZY]/S:PH
+MQ%JL>IN5J;G1+/V4U3RM+V/:Q9C2>]\&M$*;@2:_1!/]>1]ZP[2\+IT>Z-EX
+MW#3-Z!?[$C(&Z/\3],:Z9"7J$C2EG8)WBA[-U"'-%G7F1MOSN\H+Z'4\OJA7
+MLY9V]CB6OH^B.FKIVP392U_D?6AD;N.67'3JI*WG]7@\4E[P''4HH7+UO95.
+M^XIT>V62'*<MVE:D[RAD:FE,-TZ;9F6M<?<HQB*GP*OCT@/Y]23!76O<@^YW
+M=*K6R/F>X5VK"XE':><@`6O2^#\Q+Y6_!OYK7N'\/QYY#?Z]_8/X6P;Q%[8B
+M9C6YT>5%D4K[2R=6U9;99X339)8.R#2UW)C^<R%PIQ28RP5>%@(?$@*S(3`S
+M'H^G"I.REA=%EQ>\=*(N&`@H=6I#,&!O"-A;0\'`)GM8]:H*JPEL#@1;`W8E
+M%`J&TOWJR;E\&,GW1L3TXC.FV;,2<O3^NAUCW,8[Z&C/`I2C939KSVS(/],S
+M)I;[&C6.ZN3DBQ;:U/=71O4B>L[?\<>8OAP\I#M6K5GOA/8C<UB5$O`UH$<P
+M!<G?=<X&5TZQR!3J1HTMJN5&MQ6YC&]B?KAC^W\*5J[8,ZS/--W&HGGD.?GZ
+M#CM3)Z/R)%5&]Y/C[3I^&'>743Z72')C!ZB%RVRU&O<,Y^[6T:FMCQWH^Q1O
+M:XW#>%=/*L#FLZZ8IGZR`/6+H_O)7;HRJ$>-.;$#O41M/D.-C%_-I:&)O!'E
+M;W<N9MH(0:XOGJKE/0>G,W]*MYYLV"IR/G(Y]L0Y$/*!JBBKKA!&F%&RT#>C
+M9,%5?TS:9.%@FXQP\*%I9%RO2,?+X!C=7N0V=F0SQAWGA=_"<1+VF<"5+^#V
+M*7+'=+)/950G^V22>2J-F0YAG@YJ4$GF6623YLGKR($OQSI.?\I=,69+FBBS
+M3YHHK^-#&G9.$SF^\S:6MYM(HD<H[NFG%N8=S5AJXK%UU-ZR/99C1H9^UM)C
+M)9^%>6\P>;OH@=/2@*\(1IS-/HH"7+]*XPND]?+I0MW8,Z_B[HYUO$EUL8ZW
+M!9P5\($`@X/^$AG#?(:8&E=NAH5B5+^+5W^MUS2[.BY^:O*KJX-&D:RLGYSN
+M-EX$\3`N3@@5?8X]T9D8P1!S.:M=-$;Z.6O*`#7.$2&0QJ0G$QYK?.=3LA6Y
+MVU13RX_INUZCKCG[*OEPZ:]QX]Z#$$@Q!'%R6-39%U/.BPE]%?\<XM]>U&&J
+M65W9],ZX_S*/!L-+.[N_Q>.ML<E*GMGE[*/ZCDOJ:E,K-+4"2(=(4[/!+W)(
+MST+TZ>:87OU[=*&1Q73[[[G1SOT.X#9^#DD19Y\_6FZ-5O3Y(RM&0>CM'9>T
+M25$=O67<N?7;F)KYTR?@)Y'Q/5,0$\H+]-Y2-5/OO5T;T95-%5C-^/M(=HIB
+MK:RJ>IV+7:W?G-DB#&+2MQ55&@>A"G6M\W5I-#CQ\=>YR6:,X";+A,FL\136
+ME2NJW(/CV>NS!$]$X):B1>XBC=HLB,?T26]P32?9B-,#]J5_I"6I0-]>Q/*^
+MUCF#O"%27@3:K#B?SC*"\7EIS1@T+\,0H;<7,'5XM**@BY8`%OLY0YRNC77T
+M71$S$AS<L+YQT<*#%DV>C\G?GE>)7EVO/_\V!1KU;K=YA)Z,6V8G`M6D1E9K
+M'B$Z8R^XR14AK^,'H)?O+\VB1][N"!Z[=,Z,^[,-@]_($+;05#@!IKM)$^N;
+MQ.QX9+]J$?YP1MT(:W=0QRM=QI2D*&T!UVZ,%';@$TS;BH*(13]IE:^V<*%<
+M%5P]!?%X0H@/-1'>'2Q8<AZ=OR+G42+.V0;;<]I,<O."I)OKS[=Q*Q6:1^C!
+MR.;BVBP)':T(\.AUY$#O%5H?KC+Z#B:-KOEJ!]O";7P=T2S">?$YH:XTGR$N
+ME<8&:0`L]]IL]"5?"G\$H2.2S77GY6TS4SL#+3-(QW,)'?UJR^+Y\X6>;'`\
+M7U(LXGD6_/J';Y',XID\(*,;([C3=5,@C-=3.[>,TL;E8G*O+#PW+JXU/B@6
+M.4(!IOJ84UFLO)%15N4LYHRH+WI[/J9IM"8_DM$X/W(>1LB(]%8:/R@>R&94
+M*S74VW.10];"*,9#Q<+W+JEYPJ]AQ0+C_F*>VSQQ,1$&!\VSP`Q,UNE&F61K
+M1>//-TZGOLS&JZYR*P^T643=55XHH$B`74!!BOUD]CHX'QTQ0TSEY59,V%%B
+M`"N-K^)M3R8W5S)/'6CSQO1KM?%?JTW*R'QG.A\9MW'O,'2IRVU\$0TBO8E4
+MJ[RZTH-(4[7&[?14K"MSIO6S#JT1ZBF@&D4SN(-B1',:+>2+GD^OV<_Y))&'
+MUBZ>E',2DE.]IL*YKJ::I<DPIR7I><#9?S:+I+[X>W)G>FYDKL91QF[>EV[>
+ME_AT.0W4D97&EZ?+CFF9S[7Q;,`[78I-E?/U:<3)<'(VQ+:+WWE.Q"HA8%JB
+MU37B^7KJI)9;TAGY6]]/R-@7GHJ\^+?3=V)E,>936>OC\_.-:>0TQFX:#JX3
+M5A8M<Y'6I]KXAJ!G&,]S18B?$<YA4I8M1=9?IJ)OSCX^I/MY`G)\8:2FM_02
+MUL03"`Z-EMCN&\\BT%0BK31#5H,Z%^DR\I)"3^:2W'K=M&AU4!:T.V\O&:EF
+MX9ZC+2:'%F]/64LH-]6WV2U:B=YIQ;+9_W9Z;O7+J6(&YL7CY;OZ3?A1WKXP
+MK2-'B`7%%-+\$Y881EI,<YZC-;/[=13%]'^9K^EY1[-$'C4Z6M.[M^S!1"HE
+M\G\L);O'@3CO:+E%D.4-)LL0-!?Z.4W&9]'\&C1Z>Y^I%>W</FRN-DX$D]Z;
+M>#(`;;I_"((XZNQJ#N[#\SJ^0:;E5&=N$B9$<W7X(F=?7L=.S@U1Q89]*1;@
+MR(*8<HZ/X=TU:ZK3Y]S<F_B<>X%G%LLL6D57%BUBN[87D%'4T5C[_\!7[`:Q
+MKF'^OH.G>KKA;?!CRK1R*;R5FN86JY%STT#801:B+\N@BN0<%C[$S?S2B6"+
+M$F!US3Z6W)DLYEN3:\9MVN=$VVTQ9SZE<3PZ)X+S%;O8D]S!M+$QW?4NSZEJ
+M"8Q]U)%M,?V^=U-R]/_A]+:!''W#N^E^I-O3<_0#?3*G5"<F72>;NT[/1*Y0
+MSY@X<@;C34$H]MQ_20G<6)-86%&UEN6LILKI(DTIG,E]J7XN/T791Z9P9:-:
+MH6$]SY/-7.&;U1;R36BJCJ@U2C'4W?]%?<%JHPV/15><11RJR*?E@XI.7L0B
+MI64>'<OX;L4X-H5'(+W75&\XY?PXHVLUY0'PM(L]=\2)X%$01(Y3D#J#?'(U
+M7Q]Z'HS']ZZT/>S\6*1HJS&7<V/.BY71E?EFB>'D/',CY_><]4><%^"9%K/5
+M9I1/&=A)MX\$)Z[`K;C%&_-CSO-P'^L4N?*V3W`;O[F19B4M4E%(*.@>0938
+MQ[5:N[)Y<*XHBJRS\X1^[5F>C[[&DX78GE?[N1?JO76M8[%F(K\6]<\DLJE=
+M_7/`84MAK=&/T4$:M^\IREQ:"[J?I*G%X]P'B4'R^!N:%$^P96"W3.EM#HV5
+M&X[J<E95VV?XV(PP'\!U+BHY!O\3X_FO*>-Y:K)(5O-V+[/0A"L0:S)M^9=9
+MU,+8?G):5VS_A^\!C+?0R>Y<GH<W6D!C;D',FDR!DXQEMN>+76]T=/>^8>0.
+M<>)#*?1NDS*J[>36L?T7WKMJ9WYH,G?\V'[V/M419ZOQ_"<)S\8N[`^T4.[G
+M_KT8_HW\@#Q<1,AM7%BLYI"+@NAY-(LX#]93!E])+^K^+'>H2-I0_!IQ<A[L
+M+AM&WQ0.15[!=E-=$M7Y*M&Y$/'UAEV7>50<N;<Z;CGV48;^OH76G#/D>*;S
+M4+3BT,Y%3'L#C6FG.H:8W@&F8B+\&5X;-RL.=3D/\I58.Q31'D>KQAP3J!TR
+MGBLBN0<?+IO3":N9SH-Z^\',[>]`Z;UNV\,U/VJTQK3#L9H?NV(UG2[C05`W
+M9L1JGD;QI,L(4S'?76ML+.+;4X3IK_3QB5;$U.:H5D2?^[+T[5:F>E"*NJW1
+M4:Z[8_NSR:[4T<6?<NOPA?^!T0,6U;*7DBFU.;7&V4F\?^A/Q%T`'HDLS<H=
+M`X8;D<''5FX?]N<E6+][.<%ZZ<W@E?<0W;'?K.T^1L$!!B$3QVH.NJ`@C.*6
+MX_P0!/J[G$_3BLU)&L'X\5JC=9+,PA^8S!O5'';5&NOQLM%2:WR!5V)0VQ%O
+MYJ+0W=Y/&Y$?[^D^]E+^GFY_M.;I/1?RGCWC$D_^8Q_9\O[[C"OOV5=<D5]0
+M`57TD$\/Q[H+8:2Q"4W&)C2Q\P][W(LF]\@511U5:_QLHC`%)6?<].%!IE>N
+M:?H7/OE,TX^O-13!EDQ?7L`#*.R\J_W@!EKR\M/'XJH!V/#)H`'8,K;6&#,Q
+M93"[UU^A&,=H-<B82+'U<1'D$'\^FL!G/>;5O].4*KG"8URM<68"'T,,B/$"
+M)RF(9.$&7?-VCP`11:A'$TLHO\H1I>P!;S-N0=7N;6H*MBH^YFRK4Q2?XK.'
+MU6#(NTGA%75>^B#)7,K]FA)64>D57RB]&X,A%.?9*XE2W=JBV#7QE5)PUP+>
+M+=Z&)N]&/,]2YFV:Y[#[N50(]`>U@,^!1S"K4\+AV>PNA7.N0P55AW@7*'Y2
+MFS"["XV:@ILV@:@AP%8%FYN]`1]GU=#<TJ0T*P'J&;53Z[VJO<4;@FZJ$F(K
+MO="&NAZH4^Q!O[U.-`U?CP>KVAI0O6WB0RM]A1U@%;;CA3>T22/"\"`Z1X(M
+ME`XI=<%-@89M8+4F$-;\_H:Z!C08,&FXQ8N>@'%X*ZS9?%V[+K:3Z9M2.A(*
+MDJE@D\^V[T8MO'4VU!OXE%S7%`PKOB5V->0-A/U**"&!K?(&9JIV2J3L/J_J
+MM2<_/V/U"FUIJ)/>D1#CX*QH4$"IAH)-J2V2>O!>2&5:Y"KHUT)JO4)Z8(R:
+MA4==->088`QN31ATW#6#F[U;X21$UN(-AUN#(1]7?;ZO`5:&/;?:ZT**EU2Y
+MMG3!`&.#X24JSGK`C1S"I.3W&'GN;)40T[!%L5<$?8K].DS#&G=9O];$R@9;
+MC9MR"7GU@*G%N&T*H<&`33_#B`D2:.7;RFT24%KM&KJ-*E6Z#)]K[$ZEJ<7>
+M#+YP*N$0=%*@A5G9@''DBRK12I0<Y,623SVQ""DM35NO-QL<T+9%"?F;M*`6
+MMF-BJ?4-87NX054&6I"-4^7S%TO(QS20!Z_M7NF&\S8)C84!!ZP'CB&5''ZP
+M76!4K]T/PS0W!#05T<&E<$I[LS>T&<V$2FQFROG=K%L8Y?QE"R7Z2K#V,594
+M#T2(+]H'7,Z8XQ'@'<!O`3.!3<#QJ'\2.`_EIX!8U!W/`I&:.(X"%P)/E7"^
+MCE\#L==UM`#G@_1U8#'**G`!RFW`)<`_`)%..3X$HDN.OP!'`R\!1P+[@<AH
+M'5FEC"T"CBKE^CC&`;$H.&X$K@`6`Y<"YP&S@9\#+@,N`\X%E@-G`^\"C@&Z
+M@9\#;@!BI7#X@5B7'0%@&7`+$#F?8WLI/PIU[`$B6W3L`Y:2?7`;1_8!(OUV
+M/`D<2W8!?I[L`AP.?`#]MT'/G4!D(D5'\1Z;=T>AM'^^1)M$)K%W@<#S$@V)
+M9R6^*?&TQ!<E=DI\3N)AB0<E/B;Q48EQB0]+W"FQ36*+Q'J)7Y)XC\1*B7=*
+M7"[Q-HDE$F=)M$LLE)@OT2:12>PME?I+-"12QH[Q))]C-S!N6_)+\A%V*^.^
+M0^-(8\'/K4<P[E_D@VPQ$X?&8^0?'7.#+?D-^2IO0RG+!,9]GL:??(G&G>8&
+M^3N-(9=!.0W&G<:8S6'<5\G_V2C&_8SF%/D'/T:?*/LZ3?*\4=9-E7V_2<J\
+M6=(62QUF2IE+I`[3I<Q54K=;9-OEDM<,*6.6I%T@WWU.\DQ<RU@R)A"M0_9Y
+MGM1EONP+DW6W2YN72AHF;<>DC$6R+[=)&WQ>C@63LIE\QR0-DVU6RC&Y0^K(
+MI*PR.28K9%^9I&%25R;KF.3!I$V8;)NXLE,Z2N.;B<$KLXHRV9OVPQ]`J=LL
+MPDZ6E+8WIY47I)472_Y?DOSO3JN_E^3AQ:N3A*]L3JL/IY6_+/N7*P\_'DJ,
+M^2VB_$@:_;<D_5=D^7%)7R+ICZ31/R_I?R;+Q]+J7TXKOYI6?CNM_*>T\I]E
+M69J774ZK'V897,Y-*X]/*]O3RG/3RK>FE9>GE?_%(O1U#!=EMRQ/E_;]DBR7
+M#!/EIK3V6V3]SFQ1?E"6S\KZ?TNC?S2M_&U)?Z?\X/R]M/H?R?I9DO]/9+E-
+M]N^$+%?*1K]*:_]:6OF=M/+'LKV1*<J?I-5;,@:7L]/*X]+*4S)$3/RQ#!S%
+M:?5ST\JW9`CY;TO]EJ75E\GZP_+ENK1Z=Z)>VL.75M^85FY)*[>FE7>DE?=D
+MB/E[NYPOL0P1R]?*0/75-'J/I^S>NU94K%G%/'ZU9;6B(C-6&YH57G2&0FL;
+MPBKS;&P(^'"O"[9L91[:T;7@I6?UVG4K5ZSUK"LOKW)6>ZI7K%SK]##/)F3B
+M@2VI[=<J@4UJ/?.$U9`:O%]B$Z=P*Z&-V+R`F:>L>IW+LW9-5;7'PTFP+67S
+M&@(-),FS*KVRN87-\Z.6>1H"BNKQ^GPA44$]!/JT%F`+DG[5CX=PG3<`+%=;
+MJJ&<;YT&KGXMP+\Q$WE`M&O8)/8`\AV$D#KA8-UFVJ_@+9X4--T2#B18\TW<
+M@,4J-;7&M98_KJK'+B9AU2KL%SE3\?L>3BJV(LR#_F/GLWD-5]6?X-L:HB2<
+M"-?R79.GF>_5$U(2]@T$^=.*<%T#;-&L-(>I?TVP.FGF*5/\7JU)=6D!92UU
+M5$ET"+2;1:\]GG`Y5[,^&%8W;A6*RM2=>3"8;2H9V:>T,<^`GN#`]:1\G;]8
+MV1#PAF!"9:!+Z%R52ILN>(P:1.?\(84X-_'Q]ON$[;U-WE`SFM$&`D!NYA<D
+M0]?0-70-74/7T#5T#5W_W$7?4_*QIYU5\H^WH3WP;OS16=QC-S+VHOP/`_3-
+MHQ`;ZV]DB'TX[='8/\`WWGW9I)^TQHT+0"OP(V`F\'U@%O!W0!OP#'`X\!?`
+M'.!QX`@@_<0S%_@T<"3P^_0;$^!W@:.!_P$<`_PJL`"X%S@6^"!P''`;<#PP
+M!"P$-@(G`#<")P+7`R<!7<`BX!>`DX$K@3<"%P.G`!<`[<`YP)N`4X%3@1.!
+MTX"C@=.!.<`9P`Q@,?!ROVG.)/V!LTA_X&S2'SB']`?>3/H#':0_<"[I#_S[
+M!@[@[RC&BGXZ]6U@.S`X27QCN`-(IX@+@+]@XD/4;VG_/U%\$_@ED'XH_0*0
+M?NOS-/`-X'<GBF\$#P'I5RT^X'OT_0=(_WUB+)#.N/LG,$:_O/YP@OA&T`FT
+MP"^^-T'LV:/`M72`"*2#Q)5`.G#,GR#VT'\M9.S[P%>`QX%/%8J]\C;@26`-
+MD'ZGN@#X5V`.\!+PPGC&_@9\"]A+[8"CX9>/`0N`N\:+/>U=P)G`J<!9P"S@
+M;.#Y<2E[9_R]>8WGH6OH&KJ&KJ%KZ!JZAJZA:^@:NH:N_T\7G=_R(\L2\5N&
+MQ)DYG2TGSLOIMP*)L^_E+'G.[6+),^P-+'E^W<R29]5AECRG?I`ESZ0?9LGS
+MXP,L>7;[&$N>VWZ?)<]LGV7)\]GC+'DV^QN6/'=]BR7/6-]CR?/5'I8\6_TK
+M2YZ37F'),TZK)7E^F6=)GE5.M"3/)6=9DF>(\RW)\\.%EG_TO/`Z1X-7'PE>
+M_PCPFD=_\LAO\#'>WSMUN_Y9V\#9VF>=J27.R^1)6,KA5\JQU^#SKI33K/\#
+(UPTFR'A"``!O
+`
+end
diff --git a/lib/compat/compat22/libg++.so.4.0.gz.uu b/lib/compat/compat22/libg++.so.4.0.gz.uu
new file mode 100644
index 0000000..12bf748
--- /dev/null
+++ b/lib/compat/compat22/libg++.so.4.0.gz.uu
@@ -0,0 +1,2472 @@
+begin 444 libg++.so.4.0.gz
+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
+?1>S<ZHK-5AU;^RG62+".@/JK11SD?P'E>_A'JGX$`#3<
+`
+end
diff --git a/lib/compat/compat22/libgmp.so.3.0.gz.uu b/lib/compat/compat22/libgmp.so.3.0.gz.uu
new file mode 100644
index 0000000..2e65e47
--- /dev/null
+++ b/lib/compat/compat22/libgmp.so.3.0.gz.uu
@@ -0,0 +1,975 @@
+begin 444 libgmp.so.3.0.gz
+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
+#90$`
+`
+end
diff --git a/lib/compat/compat22/libgnuregex.so.2.0.gz.uu b/lib/compat/compat22/libgnuregex.so.2.0.gz.uu
new file mode 100644
index 0000000..c4d3e25
--- /dev/null
+++ b/lib/compat/compat22/libgnuregex.so.2.0.gz.uu
@@ -0,0 +1,252 @@
+begin 444 libgnuregex.so.2.0.gz
+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
+4-\KZ]O4M:EFVM/\!812%W`MR``"S
+`
+end
diff --git a/lib/compat/compat22/libipx.so.2.0.gz.uu b/lib/compat/compat22/libipx.so.2.0.gz.uu
new file mode 100644
index 0000000..6b49e03
--- /dev/null
+++ b/lib/compat/compat22/libipx.so.2.0.gz.uu
@@ -0,0 +1,41 @@
+begin 444 libipx.so.2.0.gz
+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
+HB1+]X/THT0NN1XD^;@M*]'#?1HG^;2=Z\OW;![NS_P*.XB>$^B```+M0
+`
+end
diff --git a/lib/compat/compat22/libkvm.so.2.0.gz.uu b/lib/compat/compat22/libkvm.so.2.0.gz.uu
new file mode 100644
index 0000000..2d3f72a
--- /dev/null
+++ b/lib/compat/compat22/libkvm.so.2.0.gz.uu
@@ -0,0 +1,156 @@
+begin 444 libkvm.so.2.0.gz
+M'XL("#W*_38"`VQI8FMV;2YS;RXR+C``[3I_?%/UM3=M@(B!A!(@0-``+;2T
+MTA886B8.D8O31S%4$N;<C*5-:4N;=LF]%?P0+5RB7"_W+:/B]GR^]_%M<\_G
+MWF?/J65%Q17T$7_PM#+GF,-9%=WM4F?5#B)&[COG^_W>Y#:RS?T](O9\?YSO
+M^9[O^9[O^94<X^[JYZHXCG-RY--LX3@OE_OXY?<V!6[4L'GSSF>_`IB*9(..
+M4J5>^6C*EE`F2,F,/K!>.J>+GZBAT9MO";[P+%V76W:N$I=9H:-V6J5M5DZP
+M*^.EHU9]0+J*$T?54/KF6V`5K,DN>0F62$^M`VXXT9&4L(%M[<>ZKBO?SAA[
+M9/'_%?"U&W*3,$=PN&!3M*&^+<0%Z[M"$3$<KM\,G9+H"F^XPQL5&YJ]T>WM
+MFSO:N(;Z\$+!&PG5-WK-F$!'&G:;1+`$SR(ZE9A-^J43);'#&=!%NW8MC`^=
+M@'XBH3ZU!WB58]HF7;1I"_`DS]GB_<)2Q:]UWPZGOSB1D([8L2F>T9>H/?<-
+MZ'H=4-0OWZ1]N)CC^N`<^I""Q%J=JG^D3G\\`121VO.+D9I32CL%C]KS7Z:%
+M!XR%*7\BD6BUJOYA6/<`6Y?`=6FK.%[Q#\O^S).%0%PZ5W!;@?RQ_'IU?\U(
+M;$Y"V1@?J7YA0]U;%<7`\!MB1HG9W_0D5]6,[#@ECZBAD\;EFCXFL36UM(6:
+MH6$>V]K4R;6$&SK"T9:H4!\6O&'$BG)4KC:37-^X#.1::U-^7@Q"3?)I'%8.
+M>FW(IK5K&9R'S_ATT;5!^]_+F`BLPD6J-/@JG+@A(1W-2$DK$O@>KE'XC%P`
+M?T#JY0GI7''7I:W%FWPHB+N-U<7BI=+1DW):W5:L\VF%B_>+KRNU[IK:M#A9
+MX=VI.0E5&D7BXU6I\+BN^X"X7KU!6P\$JOO5T#"1QM:N]N"6D-`9Z6B(<JQ#
+MCQC,RB/(#OW7M<Z0#)/-,I-LGJE`G;-)SQ"%<^QU6%!$&9Q-\J,6`M(.`*WP
+M'\H)8('*C_JT5ROPM&XIK8N30%9PC*'=1$>E9U!,G#A#%S,![7Y`D^\BPG[.
+MEEH`^J/<A?=0PV?N<`.&?@#G`EJK"<_.2`A?0V$3=&-[BLY86)]E01@OQ3*%
+MM[E5Z0.4I[X\H)55H#"'ZBS(DT(H*YQR']GAB%4A.Q3&,DG^&!XVWN_8/1-0
+M:\XZI"D`E0*=/R8=*4Z]#W=U%FC*_(`J67^%C9-)GHA/C0UL"FC_46X\PD5R
+MNCOV&GV#_?;N;>0-5JF2_5>,I3"@#C7#.\(WQ!\#I3D1T#:49W5NFBI=:N"N
+M1MPK$5<!1OHGJM9^U1I'0R?S&4/$+E]`JRDW"[CD+\EW8OD7Y>O8_;MS8-8,
+M&>OB,5T\I8M.,#H!K3>#9SV&@NDE6,>46I=LH9)40_U?>+$FA4.=]=8+WI)M
+M7)CHK[>A(Q(1.X4Q2%LBG0S)-!H-1:,M'>$O3@C"]O,,&D06;$/=WCF\%ZR/
+M2;W?*B/JK<1<R;@`!\+AH>)"5(E$7'?L+H5FLPWN6XUO@VD?W.?A,G(?*W%4
+M<&Q2I<2O0;5_1]0HT>I6XS\XAU?4NP?P`UI/&;L]M^AN7:?&'Z63B!/0NMAD
+MS#Y.*+OS8H`685)J-="!YGAA4>IRI=99HSX,E!SQ/04<1]\'CCUQ#L<$'"LR
+MQAX@8[<6H#7SU*AXGAVS5.DGOV8JXR@S[/LFP$G(AQ*P`#G>1IFZ]7-DZNU2
+M@V-A"AU3I5X\(MI%9?]NP)7WWXLW'M^#;;ZO28GOA5:3S#_=ZE'CWT)J=0'M
+M!P8AC^#2>W&=*KV$A/Z'F(&$$F\CZT\I\4[2T)2X0!K#I^,/`O,%CMV/HJ\X
+MU`RCH(P_PB#A)#ZL>/?GA.-F(L9*NM%*G$*>F\E6IV"KU+5DGQ.?(]5^)3Y,
+M&L]+AS1H<,)UIL-KY/"G%F8/[Z5CJO2I(;]7%AKRFX&W;9S_N90KD>2?(_YO
+M(NR7Y/NQ+1UJ)&SO[R_1R:L<K#ET*XR(UN[:P0+IT$E4-V%:ZP3RTGM/$G5I
+MI/LW]Y%39IBRD*GKZ%13DC^!1O<U5%7HG"1_WX"YF+U`0!VR"E-27J83M7WB
+MC:FIB003J+"6#/:+5Q&EUD4WTVLM"M2;.]&P\>YQ..=3XZ@>/NTFF-G)N[>!
+MRNCDC8!%50YU0R.K98Z]`]@EL^I#S?"7/'YXA^$.([!I:\.'SIG';N]HWTP&
+MS^.3URX`5F(VY?L>L":R/YUUPINT50NR!M&F2CM_"V+_JBYZ=#&-YHQ8ITV:
+M`ZW346`U?GK'-XW%[DU:86[Q#%7:_UL4,$0PHR5&!',9V%-/V8A/M1XX/&@M
+M&U'\:=5ZQ&<B_<1GNA[OCQ54]UM&SNN+B76+MMP>\K:W1-OK!?"YI25@BSJ$
+M^K8*+[0:FL7PUF@9>&>Z(&A()Y@5R=]PV'0=D]M&D]PFES!_[2$.TJT?P(:V
+M%X:3=Y$Q?%'/6;,.?1%QZ,/4H8]0ASXZ&9\Z;Y<A.*EURK49ZEV'P;D_B1X&
+ME(P3QY%`KD[E1WS:>\5P24?0U9[5A3MS&R4PY!LX.!&:U<?/?"0G"V/#<NP)
+M.3:LBT]0U@+:`$:L1^3[/-3WQ(\+ZXS]ZLZ_79=I.[%4D>R(=(5=^![VP<>W
+MO<%>+%],?/P<ZN-A[_1!U&/D!;:9U8P=L.#;#?P/YH,]?1G?#N';P)63<JQO
+MZ`5\D](/W\`W_[0J/4(:SZO2XZ3Q6I(?I$[_:7`2_SW?</IE\MGN6#\G3!P3
+M=TN'C"UO!\RA;Q@^OP\4[;F`]NWY9I\_8."N1]P*XO/]?:IU'RKHP.'!0K"8
+MX.A]\]&#4RG:T"T7H$*+?;IX4A<'#+>]C[CM/@7^47?M(>[Z0>JNQ^1.1^:-
+MT:5I3)=6S3?K$LN@.D3!V]'D;0^U=T2VY^=NV^>1QTQ9T-+0PZ=IBY\6':K4
+M_B9[@YTX/I)+Y(AN>\WYSSRBJGBJG3$7!Y?C^*X'KG9GS*F_]<L/'7=C<*KX
+M;=*3I23Z6:+PKE52VAL;UX=Y)031\LX*F#D\6.#;H,V=1Y#E7:4L-+H>[UUT
+M@8FTU?P<\6*KE.\A5*U^Y``2E0)Y9`P5_>>X>(,V";._'"T[2G\7W5(Z2$.Q
+MTF;,<S=HC\QEVWJ-BQ)N!K3D3HRP$(4<H(JLF4W6U&E=<QGW5=DU"Q6_2UVV
+M'_D*8'9`&*$"WJ`MLB*:JV9$F`#:_R25BK+/2TQI1O;C(92#I23;(<)%8E9"
+M;*B#O!7I:^!O([C0L?-M;@14IM8);Z+F56$1X8EL667:\A>%9,N5."G>H_B=
+MLG\8U^J0&Y"UML)[$%^N33^#..4BA#UN[@X[^)MR7JLY>D>!?#30"O32VBM>
+M=)>C1([">/EHN9A>J_":!=FN(7**M=%<2_:?4N1B<D6U]!P@6.S[],=PODZ+
+M?HY^"D3GS=V,AL$+65_N/R7[!Y6=*(J:='02^,Q!BTWJM]:D(Z.*?]#B'['X
+M,P'J6K1*+R%A$3,649-BHYS@5&I'9`=F?T2LJ0++Y>147I+-:3O<B"5>!K-'
+M"S@#%]*[1$[@P%PAW3_IV!4'SI(3V$D4HDUJZ+7<>\"K5OQV+`)8(,F\VBJ/
+M5\0,>[>YN:MM.&EGDR3N19>>>TG:):22P"+;-`DS1#OFJ._"#`UMK=7]J?G5
+MQY6U537Q4C0DKNY#Q0#'B>.[[Z@8!P89G84\H#XT<@X=OE$7D89+36_V#K*3
+M"]+YK),9I$[FE)<`S9I-'C4?\3&0NPWZM'V7D-PMWK\#4K=A3IP`ZT?@E7??
+M63%.J&YUHB/0Q6%2YUAA(<HGI9WB#)4_`61.^LC\ZYC+Q$[`:CC,&GC?1%U/
+M@$4DZ^[_C`8)KOAIH9B\.UI6<6\"0>J/V5@!XZESZ/#%@NK3:)Z.F>I,V6-^
+M?P[ZAH%!(D@GD^6'Y\PUH2SN5H([/!;W60/7'"")T5#$&^VL;PAYFR(=[=Y&
+M4M<(1<*A-JX20X#*DL9*,+E&5-71&0I[2Z)<2[BKOJT%@J[&Q@BD2Q!];"OS
+MMI"I4"32$2'46\);<("C>9'=.B8O2GI0!>VYS#\V4^TY\(ZNUZ$?.NHA;M5+
+M<QY(GN1#&1"E'JE2>WZ/2&HOAVZF=_0SC%P_]-`;#FAO0DN.IS\C020\117E
+M&%![4N_DBDDM@*/W(HYV']VGC^8+ZGXD6@<R4WO.D@6B#;FYPD-N?RB&WHCB
+MJ#W3WLU1G$$0G*D@Y&>H]M6Z_+'\Z88ZMLLJ#W.V0!D#B(N5'A)0K.#$O1!.
+MZ+WD;!37[F%69,=^2QS'+;RSC'?CHQ=_Q'`&9X/LR&0Y[U(?TCYCX?`8W]HT
+MF_G69<2W>I6[L"%=`8&"7J6].9L$:?H!'-1>F9UUL^RB(5[L:*@70MZN=BYX
+M76-;R+=Q#;<9`\/Z]E!;2U08$V<;".8Q['/G\;$OSR)\M5H#&C>;9"W$WXB3
+M5>FU4Y#Y_`O+W?R#\GW(7+*`!`'2'TZ1#`YB1]*'MQS0_G.6X:T@3A\!A-0M
+M&..<\BG\R#AT=H`3G96-="Y6I<\1J0;H$R<3T&(P*R=)!Q[LJ8"VAJ"[J9N9
+MB%RL@)<]+:%*4]XSZCJS6"AO6,ZN>J&CT]L`,@LUXBMH:^D*L5<TEPMBY$XP
+M5GC;HJ'0UC$C**KSOB;N?#G+OIGF6MF.&6J/[7W00E3\>V%JZ#=,=D1P2JW=
+M\(YI5+5),*#$G+)CJ)MX!?OAH>E*D>*ZY_01BV/W/<;8Q)WOH#O>^78&EEI>
+M;.6P:JH?L*.>W#8SJ\@.5.2):D\),("&#VNR&0/OVIFTR).VBO-/\QF+4`D.
+MBM(M]*>1B1E]Q$?SZ50IO+N>R]]G#__/;K(2;);:\W7C;'UN<U5RK*V[TVV$
+M"&CD7LP91"H_A0=G:WOA6<QV\F)&WDU2$#7F`OVI\JG23_^`A=#'\<N"G4>Q
+M+A#0)L\D>N$,:.N@%6B=2&!J1B*!H\T<J<;B#CYM_DQ\0S2T7`%V;R*'?^D=
+MNLSZ/X-N*^*VUV6W[2';'L%M(1FMT^X%[@+D8&EM`#DE.0B\7,F-J;,T4R/6
+M/:UMA7[J&PET+D=LLG\T8#!6IR5@JJI?B8UF#J*Z?ORS,Z_*+UX/`5J6V')*
+M[%(DUH>+RB&-5?RCA7"7VD<S\$2#1J:]T&052D3OYNU"*$J.F"?7#Z9C+&YO
+MM6S2)KAS@?C<[*:'@:X/DJ(4[@I\ZTOJM'HL=&1#\]"V4`,IN1-S`WEMA[>M
+M([R%&*"FMOHM46]]9`M7V1CJ(LZ)-!HC8CLDM2RO%;R=S=NC+?`F6<8`KJVK
+MI2%$<;?B*O:^;C7'_]-)7)3<A>\+19;<9<^V7-F6.]M:QG*4Y"Y;MN7)MKS9
+M5JF1%T.B*13CG=B-.Y&?/S/P]94Z1+==4U7IIB&0"<9OVK/3T3C:S_!N"#!U
+M8;8J?6<H)Z_JS]'#V8=$])!2S,F)%ZD]=P*"[(>PUT6Z>TC7A2&O&Y1".SR-
+MQ:]V(U*-703C0QB%)%3^04+[,?*`KYK.#&ML*GI#:1_;>NA=M#!-"O]P4PDW
+MTK22\SKBCW`DU%.?PNT/7@2]S,/<)S\1YI"5^TU,[R"U'>=0/T<K0X\_,83>
+MN\S@RVDD'[%Q@92(OI1P[M(F&!BN+.<38#RU`>,M\O#W%QA+ZS$0P"SPN(LM
+M<F<7\2F/,?O$%V?=:'7H49';U91;L/VX0?$TXC#!+X^#%Y^:)\4\G%#$'K\N
+M>K3/7(0#Q$6!HKVZ-V>O3$KV?U/Q?;B;KT!!'W+1%V*%`+&4#*'!^RZ,)L<C
+M/I@95]:\!;3KX=I3T[,OZ387OB2MVT7WHX^G)$K-3_Z^?O.^?&Y?L2JN0[9G
+MT)SOHJ_SOF&\.`G-TCBT2C[-0K9)%2>R?/X!2,I7H4#-3#Z$13HCR1X3DQPO
+M8O[+3OS79.8NG%/-%2,<QH;V:1$;=AO#V-#>,89=QC`VM)>,8?(2!8=R%S9\
+MRBK\)A;':1QT$>B;L1VM.DQF58<7#0*EQC`VM,?I<$![I(A*F81)E5WUD<K&
+MS95@;M";ET07-V[F`GS=C=?=L)X+=H4B^!4"9\2^;M>8V/>E*2@&>VME0-M?
+M9$0PA6JG):!*GWT`8E<EZY\`-',0,ZN]HRE\)0U%),:UT#BWMHBIKXVH;REF
+MG5B$4B4GK)3CP[`F&1^!OQ.,7,]&+DWMQ:E```1C1\$X864\28K@.`%)^9/H
+MB`[A4G0(CKOQ?>N]V%?WCY[!VKR60F]-"&D/X%D(MBJY\[:VC=TZMZD'XKT`
+MVU"HE<ARN[BFU8Y?JC'"UTS!REGOZ(?`+:F-VK0G2!;FJ4F+,WT!O1?9T*Z<
+MPIZO.`YT<UXBNQ^]>6+-#=M,@[:'3J98O$S+GM2]@$,)96,NI^FR+G%2']]'
+MJ(A+4<L?)8IXT(E%PJ$_TN_%I?X/\<'P-KT*<DN0$RWD'Z/U3I)QBW;I*A!P
+M#ZE;3NZN@?;=T*XZ+K^R9V",C]YY%L.C.Q]1QLM\&ATV;U,2[`+YM,]7I]39
+M9?^(?AR+E,[X<7&Y%$MS0I44R]C%13H_VFI1UUJ!F[34;_5I9R"4@P!MK8V.
+M0+3RGH-^<7F4L!0/Z^A^RR$L<76KK@3\DP<.#]HL1Q`X$9PY<3A=4,Z/JJ%3
+M1';GC5GQ*9"(-MK<$:%Y0%:F=I-,7YP\]CO?MU`Z)">BT3XF478CB<(<ZQ?$
+M(*0G9\//"@P_%V;S*,%#(L;,"(D8-VE%IW4=\KKE-'^DY@F3.6I8'IZ<*__$
+MBM2>*1^Q0/,&6)9*8KY9$QN-PLRLCW)9X#-_QN\@1X?>IO=-O&U=*\G?9\"Z
+MH6?9.*'&$L-SL&;H$7+?HE,6T^B:';LQQ2'1,O5=+29V'+MYK/0!`^FN0CDV
+MFB<5?P:C<7(28CG?GY25B`LEXLA*Q!'_)BG.CD*,2"1(\'\VR;357A\&%@X+
+MG[;P]C+>Y8AOP;WY=#GO5$-:]FN'VR(M0HA=*6UG1TFDU=+>V19J#X4%R'Z:
+M(/<W%1%8_&LUQ[_VL7?_HR]W]QE[]J3%>-)+<W?O&GOWTT?A$C?GWSFNQ^^M
+MC3M_]V-VYS<C^E)ZYQF\\P\^SMWYBY^0;Z<Q_^OY]./<O3[V">J7&AH9\QWT
+MP!(.+?::DPPV5G$<^&%/,T#@P7,'P&*.J[@+(*2^%?\,<"'`^P#">ZSX=X#E
+M`'\"$"ZJXF=5Y/=*%0<`@IFK>`;@%0"/`JR`?VT`X9_G9?AS.?1?KR(_)*KX
+M?16I\U:\#W`^P#\!+`%X&N#%`,\!7`YP?#7'0=Q9,1G@I0"G`P1/57$)0#A"
+MQ0*`7P6X&."5`)<#+`5X%4`(ARK6`JP$N![@/(`!@',`=@+]!<#7+="'7+FB
+M">!<@&&`H.L570`O`W@'P*^@/``6H3P`3D!Y`)R!\@"X%.4!L!J/S.0Z6DVA
+MQB`J$LB3_+8+SHECY"=?6`:$]1Q&4A#0(L_<3(QGX/^I#*>4([)'/K'>3]H@
+M`^0/[P[EC3RA_$G,S[&]0%XH.X*+,2_PC[)%OCD[VPON$.6,9T:Y$!H>AEO)
+M>'`SWCBV=B$;JV*\7L)XF\?6>AFM*]G<(K9V+N-I/FL7LS4+V%@9&UO)9+28
+MS96S/9<P67`,]ZN,=@7#^0IK5S/9+&,T.':6&L8SQW`X1I-C=\"Q-9<S6AR3
+M#<?&.";K%8P6Q]H<XX5C9S8^I(;--IS([MKXD)@5+G//5-J?G3<_C\U[+3D^
+ML;][/NVO9/1O9?0WYJW_%KN#8^R`6]GZO6S^.VS^!)OOSELO,_RG6?^[K-\\
+MD_8?R,/_<5[_T;S^P;S^X;S^RXS^FHMI_R3KGYA!^T-Y^!^Q^7L+:5_/FY]H
+M8?.3:'\6ZQ/%1;VRC,6O8O-.-K_"P)]#^VOR\&O9_!X/DW?>?`.;W\WH=>;-
+M;\OK=^?U]QCTY]+^OKSY^_/Z#S+\9>S'HS_-F^^U4)OB8@_B:88_7$3[+[#^
+M22:OW^2M?],XSS3:'V;]?K;^4]8?<=&^K6#L>D=>?WI>?VY>O[R`[<?DOSQO
+M?F5>_YJ\_O5Y_0T%]+V<8OK^C0)J$XW^M_/P&_+ZP>":F]9?77O=-5P0OV"@
+M!5*11(_!S0T=G=OIR):0T-91WUC?M87V:2P2#%Z[[H;55Z\+WK!V[8W\QN#&
+MJU>OXX-<L($4JV`ZN&;C#77!==?=N#$8Y!:WA%L$'+S&-(@Q*T%>W`33,(O4
+MV]GZJ!!I0`[,NT<[(RUAH0D:VZ,-0AN9W-S107X<F>65_?*"=+>2<B]LU!)N
+M#&W+HK`?4W9%PP9!,M,4"878:H88BD0()^3+%89%QK!!9=9DD#"&&'%#2C@,
+M[))5QMG:0^W1D$!@@R%E*G8<:<:=@M&U=#Q,JO[!'*O`U38AQV&XJXOM8DB3
+MD2)C*/8N(@*&#_E6E^FX=`Z8"W?@442!W%Q3(]NU:\SI&MHZHB'\\;-0#W.X
+MG`NRTCJ;"C76"_4`PD2#VH%TXV8BI@N??Z`/^;T#^/#2JB^_!GV^`/]W0K"D
+M0:!T8B&SL?#_PQ`(M170N.,*BRG@,7T20V=)E)C0(%W0K0#_B%]I`WP'X'B`
+M;^A8E$EHQW6LD"2T%P%>!/`(P(D`GP1X,<#'`-H!/@)P$L`?`G0`O!^@$^`^
+M@%,`W@.P".`N@%,!W@[0!3`"<!K`5H#3`6X&.`,@YH5N@'4`9P*\'N`L@*L!
+MS@:X`J`'X!*`<P`N`G@)P'D`+P4X"Z`78!'`>0`G`IP/$'\,5`SP[#E=+\'S
+M`UR`YP>X$,\/L!3/#[`,SP]P$9X?8/D7Y+BJ='[96*._N.&B*Q97>TM7AR);
+M0VVA[67>Y97+*FN6TOC%^+QM:@^>AQY:Q;],Z8OX:(<)_E(S?DWEDJ5C%QCX
+MS9U+JZJ^Q`8,GV`N,6,NJ:P&TLORY8'J=N(\[0N?"Y\+GPN?"Y\+GPN?"Y\+
+MGPN?"Y\+GPL?^CT0^15-%?T.QOA.8":7J_^7<;G:/R9=1MW_G[A<C?^;7*Z^
+M?RN7J^UW<+DZOLCE:OB[N%R]/<'E:NW_QN7JZC_E<C7TI[A<_3S)Y6KEKW*Y
+M.OGON%Q-_(]<KOY]ALO5LBVF.K7=5).>:JI'>TVUZ,6FNO-*4\WY>E.]^29+
+MKE;<:,G5>;=:<C5>K+^;:KBFZNW?7[;]$N7:\U5I_TK-=6RM]:\56,]75LVK
+@IHXIH^;*I:8"Z=\NB_X=!5%3M=-4TOQ_24*.)MA"``#-
+`
+end
diff --git a/lib/compat/compat22/libm.so.2.0.gz.uu b/lib/compat/compat22/libm.so.2.0.gz.uu
new file mode 100644
index 0000000..b0c71c8
--- /dev/null
+++ b/lib/compat/compat22/libm.so.2.0.gz.uu
@@ -0,0 +1,1018 @@
+begin 444 libm.so.2.0.gz
+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
+#N`$`
+`
+end
diff --git a/lib/compat/compat22/libmp.so.3.0.gz.uu b/lib/compat/compat22/libmp.so.3.0.gz.uu
new file mode 100644
index 0000000..6c60c81
--- /dev/null
+++ b/lib/compat/compat22/libmp.so.3.0.gz.uu
@@ -0,0 +1,456 @@
+begin 444 libmp.so.3.0.gz
+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
+!`%)M
+`
+end
diff --git a/lib/compat/compat22/libmytinfo.so.2.0.gz.uu b/lib/compat/compat22/libmytinfo.so.2.0.gz.uu
new file mode 100644
index 0000000..0251b03
--- /dev/null
+++ b/lib/compat/compat22/libmytinfo.so.2.0.gz.uu
@@ -0,0 +1,659 @@
+begin 444 libmytinfo.so.2.0.gz
+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
+>[(CY&VTP;3TO+VUS>97M+:_4UO+_`'`]P`@.2`$`
+`
+end
diff --git a/lib/compat/compat22/libncurses.so.3.1.gz.uu b/lib/compat/compat22/libncurses.so.3.1.gz.uu
new file mode 100644
index 0000000..9b5e0fd
--- /dev/null
+++ b/lib/compat/compat22/libncurses.so.3.1.gz.uu
@@ -0,0 +1,573 @@
+begin 444 libncurses.so.3.1.gz
+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
+3F]EISNI\3RF=_P'H*8=5#PX!`(#V
+`
+end
diff --git a/lib/compat/compat22/libopie.so.2.0.gz.uu b/lib/compat/compat22/libopie.so.2.0.gz.uu
new file mode 100644
index 0000000..da9f863
--- /dev/null
+++ b/lib/compat/compat22/libopie.so.2.0.gz.uu
@@ -0,0 +1,339 @@
+begin 444 libopie.so.2.0.gz
+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
+67XA[OP!7/_VN_^3[?P%<-+:;?X0``/VW
+`
+end
diff --git a/lib/compat/compat22/libpcap.so.2.2.gz.uu b/lib/compat/compat22/libpcap.so.2.2.gz.uu
new file mode 100644
index 0000000..cd1dff0
--- /dev/null
+++ b/lib/compat/compat22/libpcap.so.2.2.gz.uu
@@ -0,0 +1,640 @@
+begin 444 libpcap.so.2.2.gz
+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
+GFX(&#].E2[#`*R+@KNC??^!^_X!?XKUPO0QZ8Y#W-ZNO\>;A"P$`
+`
+end
diff --git a/lib/compat/compat22/libreadline.so.3.0.gz.uu b/lib/compat/compat22/libreadline.so.3.0.gz.uu
new file mode 100644
index 0000000..91c664c
--- /dev/null
+++ b/lib/compat/compat22/libreadline.so.3.0.gz.uu
@@ -0,0 +1,1225 @@
+begin 444 libreadline.so.3.0.gz
+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
+$1B0"`$MA
+`
+end
diff --git a/lib/compat/compat22/librpcsvc.so.2.0.gz.uu b/lib/compat/compat22/librpcsvc.so.2.0.gz.uu
new file mode 100644
index 0000000..0673074
--- /dev/null
+++ b/lib/compat/compat22/librpcsvc.so.2.0.gz.uu
@@ -0,0 +1,127 @@
+begin 444 librpcsvc.so.2.0.gz
+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
+)`;)Z-O3/6P``
+`
+end
diff --git a/lib/compat/compat22/libscrypt.so.2.0.gz.uu b/lib/compat/compat22/libscrypt.so.2.0.gz.uu
new file mode 100644
index 0000000..76732cf
--- /dev/null
+++ b/lib/compat/compat22/libscrypt.so.2.0.gz.uu
@@ -0,0 +1,63 @@
+begin 444 libscrypt.so.2.0.gz
+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
+,GO;^&RIY.DXC,0``
+`
+end
diff --git a/lib/compat/compat22/libscsi.so.2.0.gz.uu b/lib/compat/compat22/libscsi.so.2.0.gz.uu
new file mode 100644
index 0000000..b2fd880
--- /dev/null
+++ b/lib/compat/compat22/libscsi.so.2.0.gz.uu
@@ -0,0 +1,128 @@
+begin 444 libscsi.so.2.0.gz
+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
+>.^.7=7I9A?>3GTO$G&?A\OKM.]'V#CZ3='']0@``
+`
+end
diff --git a/lib/compat/compat22/libskey.so.2.0.gz.uu b/lib/compat/compat22/libskey.so.2.0.gz.uu
new file mode 100644
index 0000000..90005d8
--- /dev/null
+++ b/lib/compat/compat22/libskey.so.2.0.gz.uu
@@ -0,0 +1,247 @@
+begin 444 libskey.so.2.0.gz
+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
+9-"Z\DKCT!<3YEPX7O5KX?P%9&V!M=F(``)Q_
+`
+end
diff --git a/lib/compat/compat22/libss.so.2.0.gz.uu b/lib/compat/compat22/libss.so.2.0.gz.uu
new file mode 100644
index 0000000..63c43aa
--- /dev/null
+++ b/lib/compat/compat22/libss.so.2.0.gz.uu
@@ -0,0 +1,143 @@
+begin 444 libss.so.2.0.gz
+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
+`
+end
diff --git a/lib/compat/compat22/libstdc++.so.2.0.gz.uu b/lib/compat/compat22/libstdc++.so.2.0.gz.uu
new file mode 100644
index 0000000..621bd26
--- /dev/null
+++ b/lib/compat/compat22/libstdc++.so.2.0.gz.uu
@@ -0,0 +1,1885 @@
+begin 444 libstdc++.so.2.0.gz
+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
+4T;_[9'&U_]NO\?\'+AXFH3\+!`!X
+`
+end
diff --git a/lib/compat/compat22/libtelnet.so.2.0.gz.uu b/lib/compat/compat22/libtelnet.so.2.0.gz.uu
new file mode 100644
index 0000000..123e6dd
--- /dev/null
+++ b/lib/compat/compat22/libtelnet.so.2.0.gz.uu
@@ -0,0 +1,39 @@
+begin 444 libtelnet.so.2.0.gz
+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
+'].KW'2(``.7?
+`
+end
diff --git a/lib/compat/compat22/libtermcap.so.2.1.gz.uu b/lib/compat/compat22/libtermcap.so.2.1.gz.uu
new file mode 100644
index 0000000..65df85a
--- /dev/null
+++ b/lib/compat/compat22/libtermcap.so.2.1.gz.uu
@@ -0,0 +1,138 @@
+begin 444 libtermcap.so.2.1.gz
+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
+1/M:XB(VZ@OT?W_*:[KI!``!_
+`
+end
diff --git a/lib/compat/compat22/libutil.so.2.2.gz.uu b/lib/compat/compat22/libutil.so.2.2.gz.uu
new file mode 100644
index 0000000..329234b
--- /dev/null
+++ b/lib/compat/compat22/libutil.so.2.2.gz.uu
@@ -0,0 +1,249 @@
+begin 444 libutil.so.2.2.gz
+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
+?C[^8(R:*Q";R*")TARQ,".3@HP2>!]ZLWXCC0V4``(E1
+`
+end
diff --git a/lib/compat/compat22/libvgl.so.1.0.gz.uu b/lib/compat/compat22/libvgl.so.1.0.gz.uu
new file mode 100644
index 0000000..fb1288e
--- /dev/null
+++ b/lib/compat/compat22/libvgl.so.1.0.gz.uu
@@ -0,0 +1,198 @@
+begin 444 libvgl.so.1.0.gz
+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
+J_S''XO]_GH#_)T^\\X^Z/_&,^W+GV9<YQ/[4L^J\,^K_`%`?F*OH5```
+`
+end
diff --git a/lib/compat/compat22/libxpg4.so.2.0.gz.uu b/lib/compat/compat22/libxpg4.so.2.0.gz.uu
new file mode 100644
index 0000000..910f21a
--- /dev/null
+++ b/lib/compat/compat22/libxpg4.so.2.0.gz.uu
@@ -0,0 +1,102 @@
+$FreeBSD$
+begin 640 libxpg4.so.2.0.gz
+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
+'"AV0L#(``#\T
+`
+end
diff --git a/lib/compat/compat22/libz.so.2.0.gz.uu b/lib/compat/compat22/libz.so.2.0.gz.uu
new file mode 100644
index 0000000..212acf7
--- /dev/null
+++ b/lib/compat/compat22/libz.so.2.0.gz.uu
@@ -0,0 +1,465 @@
+begin 444 libz.so.2.0.gz
+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
+F!C<2*(T#WV85&-P<<*D!8##5/U/Y7U['_ZVZ_?\'I'1.W)"W``#`
+`
+end
diff --git a/lib/compat/compat3x.i386/Makefile b/lib/compat/compat3x.i386/Makefile
new file mode 100644
index 0000000..e78ee00
--- /dev/null
+++ b/lib/compat/compat3x.i386/Makefile
@@ -0,0 +1,24 @@
+# $FreeBSD$
+
+DISTRIBUTION= compat3x
+
+LIBCOMPATDIR= ${LIBDIR}/compat
+
+LIBS= libf2c.so.2 libg++.so.4 libstdc++.so.2
+
+CLEANFILES+= ${LIBS}
+
+all: ${LIBS}
+
+.for lib in ${LIBS}
+${lib}: ${lib}.gz.uu
+ uudecode -p ${.CURDIR}/${lib}.gz.uu | gunzip > ${lib}
+.endfor
+
+beforeinstall:
+ ${INSTALL} ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} ${LIBS} \
+ ${DESTDIR}${LIBCOMPATDIR}
+
+# Get all the fruit, even though we don't set PROG.
+# XXX bsd.lib.mk has fruitflies, e.g., it fails if LIBS is empty.
+.include <bsd.prog.mk>
diff --git a/lib/compat/compat3x.i386/libf2c.so.2.gz.uu b/lib/compat/compat3x.i386/libf2c.so.2.gz.uu
new file mode 100644
index 0000000..1d591e8
--- /dev/null
+++ b/lib/compat/compat3x.i386/libf2c.so.2.gz.uu
@@ -0,0 +1,791 @@
+$FreeBSD$
+begin 444 libf2c.so.2.gz
+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
+EW@<P23F:=U/]:(\',262`HH;4IQQK*/P(/HQ_`_R+]Z>-$D!`*1R
+`
+end
diff --git a/lib/compat/compat3x.i386/libg++.so.4.gz.uu b/lib/compat/compat3x.i386/libg++.so.4.gz.uu
new file mode 100644
index 0000000..951ee6f
--- /dev/null
+++ b/lib/compat/compat3x.i386/libg++.so.4.gz.uu
@@ -0,0 +1,2613 @@
+$FreeBSD$
+begin 444 libg++.so.4.gz
+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
+@,.2E>WVCQQ,KWKH6,X5O52$%RU)K^W\#V&LVV9*:!`!!
+`
+end
diff --git a/lib/compat/compat3x.i386/libstdc++.so.2.gz.uu b/lib/compat/compat3x.i386/libstdc++.so.2.gz.uu
new file mode 100644
index 0000000..47c5c12
--- /dev/null
+++ b/lib/compat/compat3x.i386/libstdc++.so.2.gz.uu
@@ -0,0 +1,1981 @@
+$FreeBSD$
+begin 444 libstdc++.so.2.gz
+M'XL("#$0`C<"`VQI8G-T9&,K*RYS;RXR`*R=#WR7T_[`]WVV6(R&,!3+C3M,
+MPK`R),/4TF)(5JU:M;+:JJE5P\H02L,P&BT6<QL6ZYJ,)D5J91A*0Q*&81'F
+MRO5[?T[GV>?L>\-U7[]YG<[S/G\^Y_\YGW.>\WS=>&'R18%`(.2BJ6/']K\\
+M,224_P(A(2'SC@F$Q(D](C1$_N)"HO&)"3DJ),KXNW^MWWO&=!*(##'^QBTT
+MU)B0$2$A46-"0O:Q_AY6YI#0D,Q1>\P\22=DCW\89E_^^05S-H(>)OJMN#W-
+M<ZRW)[VE/-^,O0J["/_W,%^%[?'[A.=S;+[.MQF]$+O9^L]%QBZ>^Q,N!??K
+M,7=AGL8OUL;;(O+Q;[#I;>6YACBG6O^Q^`]Q*F$*X:;9L+-QOY+G?_$\ASB;
+M,$?BU@>NXOD9GN?9L#_"+R*[-K1C??8@S*.X=2'<==AECO^%Q'D<][]AJD0F
+M88_"_WW,:-SNM.$N=N(D$^95FV8:\9<[>2^%O\0>A_]"XGBVGA9AKX6O(.Q7
+M5M8_,7?S_!UV(^%[$>:WH+Y0:,/>2+R-F(\)\R!A;\7]<<SWF'UQ;\7]>YN/
+MYW@NY7DW?L\1=@7V(?#?,$=C4IW\CK/R_T:<3[`CX#K\1V/*X%W8T9B3\5^'
+MO<66^S#,B[@M)GR%E?6ME74WX39AWL(<0?@',&MP_R9,T]WEE'$3_D_9N$\2
+M)M.&^Q=N%V.?A)RWL<?;\*%P-ZE[_-_D^2&>/T1&P.:M/V[9V/.1\X2-\Y7T
+M3>R!F/ML6I?;=-ZQ86;;^*N"VN`E&^Y:D6'#G(*YE>=^3EV&PP4V;%?LG[R.
+M<GZ6/H#;/IA'>$XG[@+L-'@X9J;3QV9:^TXK;[KE:L(LP>U3&W:ZM:?A]BS/
+M+R+G2+B9YV^Q7\`>@MNSI/44YALG/Q[\.N8GQ^T(S&?$^1QYLZQ;EM0O;E?A
+M-@#[,N)\8LOV@>0%^U`G[__$[2*;[R>EC]DZ6N&T_RK[?"=^-V"Z8+ZVX<[!
+M/@?Y,3R78Y^.&8L9AJDAG:>P,_'KAWTW=B?<!LH<866^Y+3)K[@_B'\R?A_S
+M_`)^8^!&F??@FV2\VK*\C/L_;+PZW)=B+\?\@^>5TG>(^SQAMV.VX#;(*?-G
+M^%V#6PSV3NQ7<$LEW*5P!O8VPDZQX6-QVRSS`,^3\+N$\`'\NN-VJ<W+^;B-
+MQMP@\QKNMV-/M6DM(^QNW/XI[<=S-$;6BB3"K^)Y?ZE_&W8P81+M\RW(_KOT
+M85M/"3R?BNF+^P?$>U;*)',5;G.PO\`M'[>C,?G^&.?Y"-S/)\X[00N7AWLZ
+M_J?C?I'UVV'+?"#F65NV^Z2<-@]CL`]P^D4!X5_&+L:M";LGYDR9L^!"S*7P
+M``D7-$8_)MX7$@]S)>%76YE)F!+\BFQ^Q%IG\_$F80['X7V>;Y(U"_<F&V^&
+ME7NYC3<%\X#,IY9OD?D,'D2<FXGS$.8"_"ZSLF_R]JS+V4X=_2AYL_(?P`QW
+MRMV9<#,L3R9B?YZOX_EP["),+&:]E?6]C;,#M[ZX_8!=09QNV$_)^+%U?BU<
+M8F7>CG\\]G>ROEFWSD[_G6[S/536+5E_\0LC[-^#YC#Y.T[F&/R_P>Z-G2?K
+M"S*+9=V4>8-X"PFW`?\&&^<T67]DKI?Y0^:,L(XR3[;V)3:]`K^>"5<GZX?T
+M6R>_V_RYR<G?.$REC&?"EDL_XOD>?UZ3-1&W^3)FG#B)N/>PS]OQOP3[49NW
+M$VQZ9Q-^B<QYUOT2GJNE']MXQ]J\]K'V2X2?:,-.148\O`QSHE/>];BO(\PQ
+M-HT[1$?"'$BXCX/&52+<D[#?$78Q?#KV#,*%8C9B(G`[1.8_S*,R1V%Z$&9.
+MZ'^VW4Q;]N4V?V_!8Z2_>2%&/ST`\X,-\YB3CW[67HW?/9AK\!L.WX^<^:23
+MY(0=)#J@4\=O8G*=/)R/N4?Z+F8?XL81?C'F7*=/K,-]D>@6N(59]RI1?0FW
+M3.8`W$[`'(19C=N^TD=L>6=@9^!V#,^?VGR<:^U2S`29FVW8C[`'X-=G+_U\
+MO>C)?E]`WH6$/4ST:.R5F#=P6PH_AKD:?E[F6Z?.;^$YRW*ZE9\//R;M)N,`
+MKN?Y/>P<6W];X2=D[</_8,QYF%ZR]EHY);).$78N]MO8W7$_1N9O^!?I8[(V
+M8C8X[7$*O(!PMY'/9)['8XZS_@_)>F&??^2Y&K_#L<\F[.TVS>]X?L[*FF##
+M+B%<<E#_6FYY7ZD'Z_8XYB*9(YS\K."Y3G0DF9>L^\O(NX)P.YQVZ&W]XD@_
+MQ[H];],X%SM@VZ:_]7L8[H+[JYCC98U$UG),"W)>DSK"K'?D/TF8@S`W./VN
+MC]2[Z)9!8W`?>)1]CK-Y&$&\X;C_*KJIZ..B#V,:,;M(YV+L,_SYW:;[M(U[
+MAN@$F`^#YL%K<#N3,/?:\&=*^Y'&8S;>U80O@]OP[^K/-S;NG,!_]N$$PN=:
+M64_Q/!6SW::9@KW1/K]+W-\PIY#.L;AULK*>@(^#)U@95=8^7O1PI_W;)(SE
+M4;+^8C]H91^)W6#E39(QB(QZRU_B]P_1[\+^,^\-LD\471_["!N^E><S,+_"
+M=Q/G<QDCHD_)?&CC379D'25[)_M<*7W,^CV"62"Z/VZO8$[V\X.0OK)'Q.U3
+MW`;+'M`*[KMGNQVRWLK(QN\L[+6$2^#Y6FD+POX<-"Z&[*5LE80YBWCQF%ME
+M;R>ZAJW;\ZR=ARD3G4S65IN_T_SVPCZ3<,^)[L?S(IDW9"^!WTC"3N?YGS)'
+M[65>>\_*^@8[2M8=)\QK>^E#GUO_\*!RK,!\31I3]Y+&G_T-L?85CML(:X]Q
+MW#[;B^Q\Z[8),]K6]4\R=Y'W+,Q*)\YM>TG[ZR"^F/"=@M*Y5W0?6]X/>?X%
+M^8=B3_3[IO7[=^#WRQAA9=[Y%^OG83F'^9,XB?AGB%Y-ONIE?28_0X/:YPYO
+MC\+[;UM']V/_AMOEHJ=AQ_KNOLX:&O+_]C<"F2/)SUC_S,3:%Y#&1TZ='?4[
+MY9Q`W+<(NQ_/W:W;Q*"ZOMKAF7_0#J&V7E9X(?^O?UUD_?P3F:_^!7FS;#[O
+MMC+KG/9X<R_I[(]_M@WSJ,P_LB=SX@R4=J9>GL']7?@8Y%_F^/^$WTC1Y_\D
+M7R<1[Q293VP>EHD^ZN3G9YX_L?6_6?8=I/%P4'X/P_]$6[[C\!^ZE[ZVSM^S
+MX]?'AKV+Y[OL\WBG?Y]DY7?!K4;F3-%=G31[\'RHOU<@[1S"S;7QQV%'8&9+
+M_POJ-[UD3B?-ZQSW[ZS<>XES+NZG6?>M_AFB]&M,O.B2-MY73EXR<#\2?MSZ
+M'23SFLS3_EF:O_?"_XZ@>ED6-*;?Q#]B+WV]_K\8N[G$FTVXX3;L;3+_\WR!
+M[.]%1_H=&:_;/.19>XJUY5PY6G0SXG6U93A5]$^XF\WC_C)'!?X\;Z])^_U!
+M&<H=&?.L?32FUN;E(R=LBU]>*^]>.4LD?@UYJ\0^%CZ+>._(&8.OGP>EEV/+
+M,XSP84Z^SK7V_9@*Z_ZBS=M":[^ZE_(N^H.R+Q;]!UDG8<9(F\"ODK?ITA^P
+MC_?7&AD/HA/"$PG;6<Z']E)GO:U],'):G;RLL7(:';>5N.V4<V%;W@3DO2U[
+M>.R3I2UMV.Y[T6&RPO[:?/G(7NKE29ON/)D?;%F:>/["NG>VX3X(BKN%L`>2
+M?E<;)\^&[R[GJWO)UZ6$6RA[-]&]K:P31;_SZY9X5V/N#:K/V=9_B.,^S)'?
+MAHP#Y+Q!SK]L'K[P^[XS![P5E)]7Y+P(_Q<M'\_S+T%E_!&W2"OC?M$QK7M4
+ML"R;MW?=^>]WVB9@T_B[4Y[/9:]JW0^W,A;`Y\O>/&@>?_`/VO?*/_`[V,J/
+M_),^4_LG?>@%XD^SLOKMI>_/)[]76O>K>*X(JM./?1W8*==#A#G!/N]GPW^.
+M?8]]OM'*2Q*=G7BO^6=XUO[-^J^5\P@K]P'B;I?]#GX;9$\B')2783;>J=8^
+ME+@GV/C1<B;V/^IC-R"C6?8Z5M;I-I\[;/KAV#<Z[?"*["]_1]8^_T/Z*4Z^
+M"YUZ_HPT[Y-W'];_^Z"^,,N&O7PO,L-MG'"W_OQUV-<]Y*Q$SN6LW"6R+LB^
+M"/\6[(%RCL_S#E^?_!W=[9$@]\-_IYP]_\?V.?:_C+?!EN-;6[Z9?S!V"IWG
+M-X+"_?P[<<8C]Z/?D9FQ%_?YHG?).9/L%60>)<P;_MF#/_?A=ILMW\/6+SM(
+M5BY<2_CSL"=A"KP]+ZI[DI](:2OBI\K<ZL0Y2,Z/Y:P+N]*?>^'-0;*W.3S9
+MVFOE3%/&LZ\KR_[)/C^SE[9(\O4RZ4_RC@X^QWUW^3^T^U`YKPN*]X/E_>0=
+MCDWS75\W@[]W^N%HV;?*^V[,?IAO\=LI[_)MOJZ1,V%9Q_\?]W#M_3!(YD7R
+M'IUT?][+>O[@7MR^#AI/E_P7>6SV]5K2D2L3^UD9;\$'VS(7X[;;B?.AJP,1
+M9HKL;^3=C^,^RJ8=:>UF_US)7Q>L[%7(/LV&F>?D]W5Y'VCCI#CE*B?>9'FO
+M*.?]3E\9]1=TI&.#ZBE,WL-(VTK^K-^^<LXA_>"_E#DW\-?;.]V6]UG'[9"@
+M,#O_9-^[6NZ#.'R5M`EQ2OQS;LIPFKS;==,@3@QN/X@^1+@F2</;<X?E/\IE
+M\[A4WMG*V8S<)\&\8#;\I$?\6LS%?Z'\A;\3=M)>W._82[BK@_@-V0?).'7U
+M7='O_7=RUG[>*>!4N>M@Z_8GQ_U">2=@N<3ZCY+WT*+7RWMMS(V8>81IL>&N
+MD_>]-OZ2/QAS4KQ,.S`."MGYFYRY;+M&6721NBY[*N'@D/W,V6_7%L_R`>:>
+M3WJY9^;;@T,BS'VA@L<\,^Z$!SEIR?FIS.V[EGGF/:;XRSE65G3`O!<7EG<;
+MNTL]\RY76-[A959YYOQ56.;OW@]ZYAVPL(R%A.6>N=LAO-8H4`%S5B<LZ_T:
+M%I<>5OZ_@O+CW[DY-F3/V7]HH".'!['H^_DG!<P=%)$G^X@TY(^U+'="4DX)
+MF',58=G7SR=0M65Y/]KS[P'SCEU8]HU=8P*F3PG+?:RX8P-&[Q"6]UN]D7>T
+M9;E/U4AEG699]GC=G/!R#K*9_`VQ+/O)$@K?P[+HF"7X'V)9SIL;_J;IR[V%
+M,O*SP+*<_??NI>D7.&/_8*OC)9ZL^9&SZ!S"GV%9WOM7P-&6UP?%WV3Y1,MR
+M%RJ6\IUIP_M[0;_^Y;US..GUL?[R#C'1R;^\+R@Y1=.3=T5E3GW)>Z9(ZFM_
+MRW)>E>ZTI[S/;#PA8-YY"<N[Y-H>6K]R3Z0W_H]8%KTSSTE/[BVE./4E[R@K
+MG?S*>\L$)KC/_?X2UK%\\DZZ^3AM/]EO-O?2_B3O<,+(_WZ69<Q7DO\3+,M[
+ML$BGO\B]FQKX=,NRQO4[2?WE7E8%_?%:RZ&=*+]3WFAXG5.>L^"6'IK^0+B9
+M\G6W/`H.)WR,Y1F=.K;O]7`&[7&V];\;3J8\/UBN@/.<_K0*;NNA[?4VG-0[
+M8,X4A7?"#<[\X[%I::&\5UON`4?UU?Y^%EP"QUI.ALM.5?GI</W9FOX,N/6<
+M@,U_1,@#\#;";[3\-%QU6L#<&3'S#[RKK\9O@KN=J?/13CC^'!V/G?=E?DK0
+M\=(#+G;\^\!YYVC_3('3S@B8>VK"X^%YR!]N.1\N<?)_#UR8H/WS'W"-4]XZ
+M."<^8-[5FOX,-Y^IY?D&WIV@[=^)35CEJ=K^1\%I9VO_/AV..5WC)\%1?0+F
+MW;7P1#C]K("YXR9\(]SHE&^);/(25-[S(M_Q;X#S3]7^^35<U4?+%]89W0'Y
+M=_OY@R.HKT&63X77$/](RY<*TUXG6QX#%SOEFP''XO\WRPO@<J<^R^&&/NJ_
+M%BZC_"F6M\+IR#O*<@L<X[1/*`FE(#_)\H'P+D?>27`WI_S]X80$'6]#X5;2
+M.\*.A\EP6H*.OT*XQHG_F,@[-V#>MYG\POV6ZOAY%\['?[?E77!YHK9G9SI.
+MZ7G:?[KS4'&)EB<.;AFH_7<@7)BD_6<4G#Q`P^?!><@[U/)M\#;\#["\&*Z%
+MC_7G,S@U2>OS+;@?Z?GZP9=PTR7:?[P(\M]/U]LHN&O_@+F7(MP+CCE?_2^`
+MRRX,F#VNJ5^XCOSML#P93DO6^BR"XYWTED;LN21TEN65<,5YVI\:X$K2&V_Y
+M,[AU@,[OOTI^J._9E@^F(M90ON-]?0..&JCASX?CDM7_:KCG10%S5B><`T<F
+M:WO<"E<[[?<07#!`\[]"PB>I_'JXVX5:/]OA>*?^0P^DOISV/A(N3M;Y,@'.
+M2=+Y]S(XU^DO$^`\IS[O@.O(?Y6O[TE\%/DRO[_"14Y];H&;^VM__A9.NB!@
+MW@D8_:`+_7F@CJ?N<)33_^+@<O)WC:\/P96#=#V]'LYE0S'%<C4\=*;7/O[6
+M=>FH3S;"=93G*^M_*(X%5P3,W3OA(9$=PV?P3])HS^BYXI\%;R;]!!O^"3CZ
+M&<^<(0B_",<-"YAW%L*_P84C=?XXZR#Z6WK`Z.'"V7#]\(`Y.Q.^'9Z7J>W]
+M"APU4LO[+[AHO/KW9='>G14P]P=-?X*KIVE[EL.-XW0]/1B/F)R`V7N8\0_G
+MPZ=8G@NGC]#TGC^D8WV\#*_)5'D]NU*>B3K?7@WW&ZOMOP".':OY606'71TP
+M=U9->>!HI[QG,]$4X'^IKT_!#4,"YJZY<!6<.5CK[RTX-CM@SA:%3SN,\"D!
+M\YY%>"Q<<DW`O!L2?AS>?*WRIW`JFX`<R\>P<#4[[7,57$G]]+=\)YR:J_WU
+M17C=1)7W'1P[0>LG-8KYE/P>;'DZ''^-]H]:N&6PUO=VN)B-9K(_?QR!_&E:
+MGWEP^+4Z/BKAW"$ZOIO@FER=/\)92`NS=?X]!ZX?K_E[7-CI7Q]*>/I3@C]?
+M,)&DD[]]+<?#::07Y>OG<`7I'>CK7W#EE(`Y)S;[";AXE-:GQT22F*OK1QS<
+MZK1_%APU7.>+!^"Z;,U?@S#U>Z$_OS'0&T>I?U\XX5K-[[7=]VS<+[)<*OXI
+MVO]?ADO&:?J=6`B'(K^3/S_"VZ9J_N^'PW*U/=;#4=37>99['Q,2LH/VZN+K
+M*W"=4Y^+X%)GO+]RS)[#7C_]<`92]#3E,^$DTK_$GX_A^2,T/TN$)P?,V:^)
+M3T?83/]ZQI]?X/H1VI\>AQL87QG^>@QG3%9]Y#@6\D3JKY^O#\!58U5_+88C
+MG?IZ`T[)T?4DCH%10_D.\O,+%P_3]*K@<,;+:+^_PSV=\1'6D_$]7M>W_G#S
+M9!U_>7#B2"U_%9PW7,?C;Q*>]2#+GV^/ZSA_G0NG4;]7^NLKW.:DU\1#1HJ6
+M+T(6[M&Z7O>'LR;J>)H.QTW2_O04G#Q.Z_MS>-ME`?.-C5E?"-A(^I'^_A`N
+M1?XRRR_!E<@;;/D'>'Y:P'QC8.8W&JH@7=.;`/=SYJLE<#+M-<:?'^'R":H/
+M[,=`R61\GN_O7^"*P:J?C(:C4K0^Y\$-@S5^)9R6K?WE([AM3,"<^P@?3D>H
+MF:SS\4"X9(B>%]P"IT]0?;$6CJ)^7O/G3SAZBL[?5]&Q6W-4_R^"=T_2_O8Z
+M'.V,AP`36[G3__K":<YZM92'7<[X?!].(O]/^^LC"24X\^,<N)#QD.K/]W"\
+MTU\_@M<,U?%RJ!1\B*Z'R7#,9-U/WPR77QXPYT1F_,-MCG[P2Z^._36"A;F0
+M^CK&/X^`RYSU;1I<FA$PW\*9_2/<.%S[W_93.LIKA8=F:?V=B*"\7%W_KX2[
+M#M;ZR8=CG/GUV=X=Y=7V#C'?/4::\\@N(:UP]!`=']&G4KYANCZ.@=,FZ?ZK
+M%$YUUH=&.#)7ST-.9J%+F:+[R3O@%F<]6WU:Q_QL@-?DZOYK,YR6$FK2D_SM
+M@'?DZOCY%JY]`_VU\Q[>#=>,\LPW$F8^)2,1UVE]'G)ZQ_2.#.(>07Q"$)\*
+M#T7>Q;;]SX7+I@?,&;SP`+@ES6NOKROAI"@OY.*#[/B$VZ;K>)T$1\]0_6@&
+MG)OAM9=O#IPY0]?3!7#L<*_]/.D!>!W^_OZR'*YTZJL*WK'*,]]8F?J6^G#\
+M-P:5[RVXYDO=S^^`M\T*F&^%S'D%'#9;^2?)K^,O'SK$./Z=X13'_Q`X+%_G
+MDZ/AGNE>N_\)<*P3_G2X.%_GLP%PK>.?"J^9N>?[7^'A/.0XZ8^'DQV>`F<.
+M##7GYU+^0KC$D;<`GI?GM8^G17!"OLXGY7#6E]I^:^$V)_U-/,3G!<P=;3,_
+MP?._T/5BIZ2?K^M]Q!FD3WN^Y>^?X9I\S<_)</Y*KWV_&W^&?/^HXS49#F_5
+M_?#(,^1^@F>^>3+[";CE,@T_%TZ>J_I%$=Q$>O(.S.P'X:S]//,=KEF?X?H;
+M`^;>@YGOY"#M)HW_YAGR#8G*_Q0N?\$S]^K%_V>X(EG](VCX-J?^CX"C.VMZ
+MQY_9L3^>?:;HWQH_$2YQY%T%-SGEFP"7%JK^.`>.F^6U\R)XW7S5KY^'RPOU
+M_.$#B7][P'P_(?QON)\C[["SI'^JO%YPMWU"S7>ZDGX"G%6DYXUCX/B%SOH'
+MMT[7^$O@\B+M/_^$ZQ<$S'?$IG[A%,+[^NKG9W6LGZ_AI$(]SPYE(YFY4-./
+MA:MNU_$S"`XC_[Z^E`$7(-_WGP4WWJKC?Q&<[)1W.=QS7L!\YV[T$[C,*=_/
+M\?)>6>OC`!2Q1M)_TOJ?`D<7:OTGP;F=-/P(N/XF+<]$N/KF@/EVU.QOX03R
+MXZ]OC\.QCKR7X;J;E#?#32.]]OGU:SC-*6\8"U'T0MT/=8?3;PF8[T6-_M%7
+MO@_3_`V!"VY5_6`*O+E(RS\?#G?:<W'?CNVU'*ZD_H99_]?@1OICFW]>!2?E
+MZ?G'KW#A'0'S38^9'U!$$@E?Z.\OX)Y._TB&XYW^.@H.ORU@[EN9\V"X!OF^
+MOK,`CH;]^>Q1N,'I/Z_"U4Y]?@#WGJ[Y^Q:NFZ'S4R<V2F6W:OF/@^?=K//=
+M:7#X72K_$CC!J;]<N.$N?;]PB\2_2]?'17#>,UZ[/O<DW.\NU;_JX-B[`^9W
+M`LS\"^\J5OWW)[C^7M6'#D5QB;Q7_>/@7,?_,GA-L>J+N7#;O7J>6@SGW:/Y
+M7PIO=M)[5>3?I^$_@:N+=;\=BJ(0Y<3O`A<7J_YV"ESA^,?#24[^KA)V_,?`
+M98[_7#C6*=]#<'FQKD<KX/ABK;\&.+Q8Y7T,%Q2K/KX;WNSFEXUS\GVJ[QT-
+M)]SOG*_#%?>KOM8'3K]?Q\]%<('CGPK'W*?G(:/@WB6J7]T&-]RO^M!RV;@O
+M#ICOL(4W2'X>U/.%'7#2(CVO^16.HK\N]?41!L*\$M5'3H9S%VO_3(8K%NE^
+M<Q2<_$#`W),RYUO]]EQ(]/?W17`]ZT&)G2\>@1,7:WVMA7L^%#!WK<QY#=Q6
+MHN-U-UQ,_I?[_9.-7N+#`?/]H]&/9.-7JN_;A\!Q,[WV_5@FW/:`GM_,A>N<
+M\I7"K4_I?+<![ET9,/>AA7^$NRU1_2.2C7OTHP%SS\*D#]<]HN<)_>'*Q;J_
+MF017/Z7[I?O@?H_H_JL2SERA]?LFG+&OZ@.?P<V+M?^$7L!\5:WCOZM\#+!$
+M^^\)<+\E>CYY,1R_0NL[!RY^1/=+"^'JY0'SC;AY7P.GENEX;(!3G@F8^W)F
+MO8`+JO7\/)*.-J],Y\.3X%+'?P"\HTS'VTBXLDS'\W3IJ"O4_Y[$/9>W_?.G
+M>KCP\8#YW0KA9CAUB8[G_>C8]8LU_>/AW&<#YCM3D_Z%<E]#VW<X7+!$S\_R
+MX-HR/2\I@JN6!<QO(9CQ!)>MT/U7(QQ9%3"_"6'&$YQ1IN=?.R^4_8S7/I[#
+M2:B;4[X><,63`?-=A3G_A\.?#IC?%3'C"<Y"WA&^_@%'E&G_*(;KG/P\"Z<N
+MU_'\,MQ[:<#\;HV9[^'()5H_W\-YY/\5?[ZB(Q6[[0=W+=?X%\+;G@B8;RI-
+M_N"*I[7\U\'KENAX6@J7.?)6P<F/!<RWAZ:^X$2G?_T;WKQ8^2@FWI;G-'X,
+M/,_1;_O"$34!\XV+:=\DN2/IM;^/3(/K'?TW&VY[3L=#`1SSHNKKMPNO#)AO
+M2LSXA#,7>>WOBRM$_KXJKR9)QJ?7OCZ\R4-IK>Z'/H(3:O4\^SLXLI-GONDV
+M_8&)<5VMMM=A<&2X9WZ31/A8.,>1UQO>1GOO;_/7%XYY5<_3!L.M:W6_,UIX
+MC<XWTR7^*P'SS9`Y;X"[KM;U;1%<41<PWS(:_0%N6*/SUTMPC2._`4Y;K>=W
+M'\/-E9[Y9MGT+[B)^AUC67Y`(^]5K>\#X/Q7]#PO&NZY1N6?!G=]1=]77@SW
+M6Q4PO^MB[M/`8>':'IEP[%JMCWPX#7E3_?L></-JG2^62OIKM7Y>@"/6!<QO
+M!@BO&=!1/]T(-[RFYS/O!?E_&,2?P07(F^3/!R+_=3WO:8-;U^GX_DWRNU[W
+MSW\?2'T0_EG+B?#FU_5]Z%5PP7Y:_G2X2"[U]MO#4^&J]7H>.0LN7*_]:2[<
+MN%[/[V^'(S?H^+M[8,?RE,.Q&U6_>!;>L4'?3[XN\C?H^K<=WCTNU-RC/`@M
+MKR5(7I=DQF>]RNL.#ZU7>7%P-/)&^?H&/'^C<K8<7(U7^;/@,(?G)G=,KP2.
+M8C._Q__`D(?@BDTZ7S\!ESF\`BXZV`M9T<F>#R7+^T:OO3^]DRSO"[SV]:-%
+MRC-.]X._)LOYI6>^T3'K(QO'G#&Z'SD>KAFCYT]]X*2Q7OO]D62X9Y;*&S%(
+MWL=H_&RXB?"G6KX)CECEF6^^S'Y+V`G_$)Q/>GY[/RWIC=?]XBOP[FN5&^'6
+MB5[[^O2EI/]!P'Q_;<H'QV[5^:3KI:R?7^AZU`M>LU7Y(KATBY[/#X5[OJ_Q
+M)\.QW^KZMA#NVAPPOPEF]!&)_X7JQW5PTD#M_^_"-9^J?OPE7/F^GE__!A=_
+MJ?I3#R:*E@BO?3R<!8=_I?NQ=+CV0,_\7I71E^!NSWOF6TSS?A[.:`FTG\\L
+M&"SW53W=W\+%3GZ>AG.V:G[6PO%._K?"40=XYG=73'^",YWZ"4VA?Y-?__[>
+MX7#\QP'SNSUF/PGOWJ;IG0WG..E?"N_8JNOI6'BHD_X-<-,7>O_R";CBDX#Y
+M_34S/\(-M/]JRQLD_<\"YKLYL][!Q1\%S.^VF?D?KG;R$SZ$^>AKK:\HN)7\
+M'&?Y)/'?JOO)_G#:%CT_OQQN<=IS`MQ$^0[SYWLXQBE/$9Q*>_KKZ</P9B<_
+M57#>%WJ>M4;2.U#7\W?AZ(]5_E?PMBWZOJ[S9=3W-ZI/]X+COM+^>0E<^)+J
+M?R/@]%9]_S81KOI6]T\SX?P7]?Q@`1Q/?/]]5!6<](+7?CY2"V=\J_/Y:W#:
+MBYK>5KCK2WJ>LQ-.<.3OPT:H&?;[^V%PU(L:_D2XU`G?!U[CR+L43G=X'%SK
+MR+L-+OI6Q_\#<'VKCN^G)'TG_FI)KU7K<RO<KU7C?PO'17KF=W[,_`.W'.29
+M[ZW,>3$;J=Z_:7_M#J=^%S"_/6C*`\>TJ3X;#S?_J.OM(+@2?<Y_OS<:3MC'
+M:^^?,^#,G:K/W0ZWU6I]EPJ'>.WI5\)1J[WV\[I:N&E?G:_?ADMWZGRZ`X[>
+MJ>^K?H5SO]?][/Y7H"__K..K&UR#,NCOK\^`PW;J^!XH_HZ^/!K.^E7';S9<
+M^4O`_/ZF\&RX\!>MCR(XXU^:WB-PRDX=#ROAR)\"YK?,3/^[0GXS2\_+ML(M
+M+^O\^A5<LBM@?@O.[.<E_D[=KW9E(-3]H/['P^N2=?\;!^_JHN^/+H#+&:]^
+M?H;`3:/U/OZP*SNN_Z/ALCI/[]_`/==Z[>^G"^""]7J_?R%<2/\:Y_=?.'*]
+M]N_'@^0_&<3/P`W(_S'4KJ]!_NO@A/7:_]^%TP9I>3^%4U_QS.^-&'U1\KO&
+M,[_[8_:[<O"SP3._KVKNL\`5JW1]CX$3ZCWSNW;FO@>\[G6O_?QGP%4=\Y,2
+MQ%?"0]%G?'UX)%RZ4>>#"?#\`5Y(^L&V/H/BSPKB.?#F,[V0A^S[OODB_T2O
+M?3S=+SQ>\[<T*'X57#/!:]??5\/5([SV\[5-<$RF]H\/X(P).OZ^AFOQ]^?O
+M\*'TA_'*7>&BB3H^_SY4[GNI_M4;3D2>OQ]*@#,S5?Z`H7+?0N>/-.$)VAZ3
+MY"(=[*_G-\`[8'\_6@PWC]#QLU3\D>>O3]62WDC/?)MEUE\X9HR>W[\/KR'_
+M_GG.3CAAI(Z__:\F/T-\_;A+2!2<-4+KNR<<Z83O!\<AS[^?.`B.G>2UG]<.
+M@],&[_F=89&7`5?C[Y^O3(5K+]7^/`<NF^*UG^?<!U>BO/CS506</TO/RU?"
+MY2]I?]L$)Q'?GR\^A?-(S]^OM`H[\L)8*#,F:?U%PCE9ZM\=3B6\K^^?!)=F
+MZ7R2`.^8[;6O5T/@KM.T/<?`C;,T?S/AE&EZ_CX?;INAZ_>C\*X<G3\VP+VS
+MM?VWPYG.^XV?X9Y3/3U/IB'2B>_O%WO`L4[]]KI&[F-X[>=MB=?(?0&O_7QF
+M)%PS3>MO*CS/J;\;X)Z3O/;[8<7PMFDZOIZ`"Z@/__[Z*KA^IO([</QLK>\=
+M<'Z6EN\[.-5)STLC/S,U_)'P_&PMW\EP5([N1RZ`U^1[[>?MH^'<;.UOL]+D
+MOJ>V[QUP1;:F]S"</EOKMQ).G:7C;1U<Y/2/+9*^$WX7O&V*OH_OS$:W:++F
+M]RBXVBEO#%SOE#<.3IRL]3\(+G'\A\+Q3OQKX<(IVIXWPVF3-?R2X7*_1=?_
+M.KA\NM=^GZ,1;KM.YX-OX`;JPS_O"&/C70/[YQ%'C)#[`-H>,?!FI[XO@)N=
+M]AX'MV3I?'"=R'/J8QX\U!FO2^#2V1K^.3B#]/W[DIM&R'U$70\^EO2OT_K_
+M-YPU6?>SAXYD/Y:OX^,T.'^JKJ<7PX7Y&C\+WC5+_>^"H[,U?X^.E/NH.OZ7
+MPSVOU_GA9?'/TO<)#7"+4]Y/X-H<K;]?1LI]-/4_))WQBCS__<6)Z7(?3.>'
+M"\2?\@[P]3>XB?X1X9]7PV%3G?$+-SO]IS!=[C_I>"B"PZ_7_O.TQ">__O[G
+M5;A\FO:W+7!REJ;W*5SBU/^_X!W.>.PRBOXU2=NC&QR>K>.G%YR8K?[GP_.<
+M^>MR"3]3Y\.9<(0S?N^$NSKE?0RN<?*S%JYRPK\'ESO\A<1W\O,+'#E)RQL^
+MFOIVQOLA<%JNYN]X.&R2^I\.5SCMT7^TW#?7\*EPHM,>(^'4J7J?8"I<!OO[
+MV9OA<J=_/@:G9.MX6PEO<]:SC7">4_[M</4LW7_L.X;RYNIZ?@2<Z.3O)#@Y
+M7]>S1+@M3]MS`IPW4_6G`K@E7_O/HW"#T[]KX4(G?V_`C0YOAZMGZ_C\!9X_
+M.-3T=UFOY.)L-=S;<AB<@GZ2:OD0>(<3/@K>G:+^Q\/E3O@SX`PG?-^,COKC
+M>7"WRW2]'`07S5%];%B&W)?PS&_5F/D";L3?/W^^"1YZDX[/$CC">;]0!4?.
+MT?ZU'FZ:J_/O1T'Y^1QN87SZYQV[I3Y6:G["QU*_-^IZ<^S8H/MW<,:-6M_G
+MP3WG:/BKX:0Y>CXY&=X]1/-["YPP5_65Q6/W_(C+*%O^E7#Y39J?AJ#TWX6W
+M7:_IMP3Y?P?WOEGK,VQ<1__]X8Q;M#\>"\?=HOWEG*#PB7`6^^G/?'T,KJ#\
+M5_OM!8>37_]^3C[<#/OGC7?!.3=J^RR#P^9H_E^&B^;J^ODIG'^KQ@_0$2)N
+MU>_5#H-+R6^V_[X5KKM5]8ESX6VW>>;W4LU^8+S<-_',;^*9]H";">^_[RZ$
+M=]WNF=_2-OLA..\1S<\3<-<57OO[S+5P6+G7?A_D7;CU'U[[_=//X<A'-?[/
+M</'=RIU1#".+-?R1</I=NCZ>+/[WZGPS!-X,^]]K#H?G+7?Z%YQ[I\Y'<X3O
+M4?G%(F^!GJ^5PY7+E%?`W:I4GUD+-RS7_?J[<"'E\^^_?P:O6:#Y_468^-/]
+M_?$$^DNI]M\3X=YWZOI]-ESTD&=^1]N<M\-#G?REP2W%.I[RX'YWZWB9!Q?<
+MY[6?3]\+SR_6\C\.-Q/^1K]\PDY^7X>+G?QL@=NJ=?[?/4'NJVG]1T]$7_BG
+M_GY!`ES\E&=^+]WD=V+'\3(.SJG6\Y"I<.D#^KW77+BWTYYWPN5W>.W?]SX8
+M)*\<[OJ<9WY3R^B;</Q=JK^\!\<Z_;49[K=,VZL-KG3FRR.O93VG?*_ZZRU<
+M7J7EC8<KG/XX`,YRZC<-GK?0:1]XC9/^;7`:_?\ROSPBKTCC+X-C%NI^]`5X
+M\]/:7[;".^[7]>YSN,QIO]UPO9.?`REH/?GUWU\=#<?4:'OUA5N?]-J_)TB%
+M8VD/__W@Q"RY?ZG];R8<7:+C_0$X\QZ=K_X!1SC]YP6X:8F.EXWPMKMU/]<$
+MUU;K_-0B[+3'@62DR9%W-%SUH&=^Y])\OPRON4?'Y_GPNB>T?8=(01:J_%%P
+MG#,?385K'/DWP05%VG_N@U.=^>,)N-*IWQ<D/Z6:_@:XU6G/)CB]6/6S[^#Z
+M9SSS&XY&OV/BGN_43T^X<J&&[PL7.OUM$!Q;JO<!1\`1)=H?)@JOT/U!/ASI
+MC(>%<-52S_R_"$QYX++Y6C\U<,G3*O]UN,WI;^](?*?_?@[O<.:'`UEX=BS2
+M^;<[G#%??Z\D%E[GU.\%<!OZA?]^_#(X?;W6WRBXL5;+?QW<6N>9W]TRZQ,<
+M\YV^/[T_N^/\4`JGK=3QNPS.W:CIKX!K-VIZJ^#=CCZV*5O>+VOZ[\$I#G\<
+ME%XS//]R/<\*SPEZOQS$AP;Q44'<(XB/#^)8.&^8ZJN)</PF'8]7PKE7AIKR
+MF?L(<-0;JD_/@HNVZG[@<;A?D_)Z.,Z)OQF>][[Z_R;Y>5_OW_=DHJG9JCP(
+MWO:FMO]8.&>3[J=GP3%;5-XB.,,)7P6W71%J]'U)?S6\R\G/%KA\D^IK7\*9
+M39I^YZG,KUN4H^%N;VGYX^!41]XE<'VJIC<<3G32SX;KFC3_\^!:Q_]A>'Z#
+MRJ^"NSKR7X:K'6Z4_#GM]]54^3Y:Y?T*AV_2\]O]I[$>O*7ZWY%PYB:=3T^!
+MZQLT?Q?!)4W:W\?`\4Y[SX-3&K2^'Y:#W#>U/I?#7:_2_*Z!R][4\KT#%SOE
+M^0(>^H;*"\TEOT[[QL*-CG]_N&F3\E"XMM$SOWEMQCM<XK377#C%:<_%<*J3
+MOZ>$G?9[`8Y_4_<[&^%BI_]_`J>][9G?B3?W@:ZC_IW\'@47.?)ZP>E._QX,
+M-SKE'PTG;M+U)!M.>TO+5P"'.^U[%QSER%\"1SK]YUFX['+U?QENVJCE>5OD
+M7:/]9SN\S1F?^Z)X-CGQH^"ASG@]"^[MA!\&5SG^U\.1SGAZ&.[VMN;O*3C.
+MJ?\Z.-RIGX_A9J>_[3.#\CK]O3N\JTG?9YPG/ZRQW6O_OOXJN/>'_\?;NP#&
+M55WGPGM&8WD`!2O$"0XAQ2%J8HH#DG&"G9(@L&6;^#7(EFT>SG@\,_*,&6DF
+MFAE;4)R*FK06@W/5A#9.ZIOZ;VGJI+2_T_H2)Z54!B[(QJ%J<,(HDHP(IAUC
+MA0CB&H7?17=]:^]SSCZ/D3WBYK^/?/[VV8^U]EI[[;W./B.L_>0AXHN'K?G]
+M!O'`JW[S>\$CQ$O_X>>_T\??QQ*/O6;)^[Y.TO\5O_E[V,\1?W"]-3_+B<\]
+M;=6/$%^PP7J^G?C!EZWUL9OXXE>L]TD_('[H#DN_%X@'ABW]SA)?-F+5_]B]
+M%$^T\6\D/G3:ZC]$?":-]VW#?X@?T.3Y)O&UU)_Q^\0GB-=HX[U&_$%MO,ON
+M(_N\;.T/-Q+O&;'JAXGW#EOQ9@?QL6&K_R>)G]/L-4@\=8<ESYO$1U^V[F<^
+M_P>TGE^Q[+F.^!RM?IKX[!-6?WN)+R;[&]\C/$D\,6R=3_J)+_B%I<\[Q'/:
+M?-3>3_RDG__;;OR^F'A)L\?-Q(N:_]U!O$OK;R?Q4:V_;Q%?IM4_2+SSA'7^
+M>9[X3&V^!HC/T?3Q[:#YU9Y?17R7)L]GB(=>L>K?1?Q1S?XYXHNI?M!X/T+\
+MX5]8^>3CQ`^^;M4_1GS/B/4^8(+XL1.6_2[_,NGWNN7?GR)^[H2E_WKBP5>L
+M^7^$>!^M+^/W/'W$4YI\)XB?T?P_2(GE.<V??X?XH[3^;C&^C_Q#Z^_EX>_I
+MW4U\3/M[>U$'3Q,/;K&X""^^8]4M*V];),)+5ZR^]985X=5+EJQI6AM>>\NM
+M*YK"(IQL3^9$N)5`A,,=V7#XQF0VUQ&/M#5W4$$*!6E9$!5M\;9HYEY'<4RU
+M6])LMLS=&$VW95+QSH8[.YR]1D5K*I]-6.U%)AZ_QZH@PME[DIGP]JQ>Q`/2
+M`*I)\R+;")GT=CRU%29%:V1S5J326T3V2QTY$4UG$]2/7L6S%V=I.)Q)N3I?
+M6T_ED=BV2?NCH5T-60QWJ:V?V(5(@.+VN&>QQEM=*J8B'5#24:^#"MK3'6UN
+MR;+)=D\EO'1H2WG,']6E1_$O>4YM6YFI;4MZ5"=11"07:9\G(AU;/"5->$\*
+M=8F'7B)',-(D-E3].8N3;9$MGMUES],;7,9+X;*-6HU&[KXB<(M)1VOS]ALV
+MADL(KT5$Q?'.C.>C#L-,KA:T0%->/M.^U6O*,BEOY=I2E4]E!Z0]S^JR=Q3S
+MUJ)#*>&:T&19%1REB7LSZ9R@".3AJ!2.O+KQ,(OA:8L\`JIWN(TYPVUL\N`9
+M\USW,:\E%O,0)N8I=RSF8<&8HS.O:8AY+M28L0R=77A$6&^#QF1427F79RZ\
+M/.:U%F)RF7B)PG,3<TN8\BCV"BHQ3T?'@%X;B:F\LVNO)1GS#)8Q&2R]*COW
+M.^<@'KM"S"/$QIHOP(&L^7=7+]M7J_=DF7/H[,K+E+')-M"8UX*.><2*F&>X
+MBWG[8,R]<7A+.OE4Q,H8-&;N^K%)9Z_,RBE3[#EY2>]%X[%7N8>>)$:U.F-:
+MZZ0AL-5K,;9Z!*]6SPEK;36T:'7TX&735D__Y3YLO-5S:EH])[=U,A]L]72B
+M5EXP'LJ4.?NT>MFO->FU]%N]%G:K9_AN];"T4WJ/%=3JM=NT>@8M0^XR<^(L
+M]M@@RDQYF0VBG-VX.@<5MR09KUZ\@GL9W['Z=G;B%?-;W=&C]4(4;O78HIT-
+MO8X&YJ)QC^*,]*T7$)U;/5.I5D]7.+\#>Y=:*46K]_RWNGQ,!DR>)%=@:IBW
+M.9)-1L-4D&S?,N_.Z)VYA@62A*,):ICKB"1SV88[HR1W-GD?358%;5J249'-
+MMV^)YZ+A\$(YZ.8\!`EWY-OCN7LS<4$/4TFYV*T`>.%#0*Y,*A*M5##\WZ@(
+M+\IW=,3;<\TDS8IT-)**DVSYUE1ZNT=4KF"NMG<D<W'KK4!H4912^&1[+)R*
+M9'/A="OL?^'=47.(2R)M09@B6IGEK&!:T9B(W&6=@;6I7`OX8,6RD,^_Q\DC
+M)VE+;ZO,1T)1$6_+Y.ZM;#A-TO9TY=)6-"^D5R2;36YIKTPOGI!()A.'!2M<
+MS>2"4S%?6[P-\S\5MZET1L+A;='*1J!&F^-;<%BHR-#Q2C69\J)I4<&C-=DQ
+M]050^=AH%DW$H_>$L66ETI5/:S(;CL53Y<-(U#QC_9;\@4X9F7NQ&X?#F[.T
+M44PNKYRI][:`9;"I?$<*1=<V:.-/<7_@.%_Q_C"%6(#MH2.>BD>R\0N<7I&-
+MIUJ3./-5'$U_J_$BE2OOG\V+R"KOT2$,XRA/+&M^8WO\[:E*W;=%.L/R%%>1
+M@^3;DU_*5^;/<,;M%[SR2+18)!>Y4%=264)E[CKU(T3E6]"6W!0VR:D>9*%<
+M/)V=Y+36VI'>K.Q^@091V^B%UZ[X',')2L6ABD29RGEL"AMF-)5NO^#8-H5C
+M&&8ADJMX2[6R[(I\2_E')<NWPN65C><F"V_-_Q?V5N,HGXUW;*MTF?P6(ZL*
+M797Z\92.")4)-H50/Z5$B3;)"UTIVD%VZB[PVW7E*6:I6`3)=O+-7(6N6?DV
+MCM<[D8[X;W47LV:AXB#]7I,59`Y3F4@C/DQM:2$@JSRPL@QC"K90.7CEN\94
+MC#A97[_%50H%*[6@P.9VH:?QJ:1FE>>;\D58Y0<Z]0+M0H(BWMA>2.PT4H@*
+MW%J>^N-MM#M7?FK^_VW5PS+R_'!AYTUI2>-NHI*7Q>I86Y%/3F%+Y&G/YC?3
+MPTI/>%.,8&@XA8TDDHE$DQ6_XU1S7Z&#3"&FAZ+O)<#*+6PJJ9AJ5O'.5^EK
+M%)&+=[0EVR.Y2H]IX;JI;5*3S!=V0&%X^N1O*5+Q]BVYQ*2]51YM3+>:POU&
+MI4$]RA^)5OS*RUB>4[@($^H-:D6--D_EU5SE46!J[_^F>DK3KA&F8NGL>SW0
+M_+;?_AB+8RH1M>(3QGL\J%6JVWMXLRW:XQ=TM*OXX!#OC,:SV7`VE<Y4\KYQ
+MJAG&>WE--\4-28;3S?ED*D?922R>BN?B@AM6Z&4JNE=R&S(5Q^0-=$O\O:G9
+M'M\^Y:F.BBT=D<V5O[PKXYQPSRE=HLOO0;)P-%&)#G7MR51S/".B'7$^&ESH
+M:]CW&`VF&-)#^AO=BBU.6N4SE8UW@?=-VR.5]5O1%QY3NW@7^!ZDHR/=(<*W
+MK0X[2"R=SX7YWQEJG6OE?VYK-4@XWQZ+=\AO4^@!C9[NB(LV/E?PCUD2_.$U
+M=Z@N;+GBEGB.0D:RC4DKI5D9_(H!(\;C]QC_WM::C4;:6U4=ZY_444Q6IF[:
+M9=D6>Q?I5E4WFDIGXX8N)(?4I369BH?Y41B_S9%/:7T+ZCN.<VS#/)H'Z]N@
+M1+R3W*@EF13I*")E*JF*4D8)/8K%HZH2!\$E_(%-.$SA34Z0>DY-MK7R=U_6
+MQT=4-10U1DD979F=6P/C87A;KLY3OB2&LSK%13GDB&(!)7.D8B1'/N'0+11-
+MTBXG!Z0.I&20/2XRT72^/>=L(++FUU&:`EAN2<.T>"H\=,2'3#=B[OE[*U)C
+M83+3*BO4W9`D\Z7IS$=5,AWIJ&P!C1H:5!WRZ;A4W_B&2;8B>RU,&QUA"LQ>
+ML5]@5NK""Y+:\[3[N=5&"I;V%$S)KEI1/;-;)0ED4]+SJ&EK5&,/V493K;9+
+M5#?;F76UKI)Z251^%A:6<[^`<J<L3V3VWFQ8?=MEF^VDHT7##:WY]FC8:B?7
+MB=95Y^WS,-("/`G'DAVN'CZS)=X>[XBDK$YR\50J3%IY"85U:G<2-6EF+>KR
+MTRHL&67-BUQ%ZH3M'IWJNB7*WMON^+"OSCV*,..6>UZ,!6M?2Y'-:=HP,YLC
+MT7M:(\F4IBO[Z(7)9I\M3^&SO$YMT[9-='*D<\XEF\GJS:ECDGN34<[^H:-[
+MX)"NJIIN^[20/HYYXCCDX5.3*8A,I!47C!Y&1G<>II_46T)8B#QI_!-'2PNG
+M*XN.Y):$]\`LJY$@::/)K28>ALGI-!"AGLD0F;S#$(M<EM`\0W<S;XW=/N!8
+M<V56PP++,)K,=2YOM@<>'&!1R</S[):S]T([4IHW[TC.Y4OVFJ$EH6WA4)1\
+MUN'K#K&TB=&ZHX,`@:8<W%R?0[?<B-WV#NS+9&U#4ER`,[.4[?FVS?$.W0GR
+M'B+R`<7F:TFGLFZ;U=G\V-MX<ME=6$#4?Q\<6K3-.%)H'_?2@2*6#J>SK9W:
+M+X%=M?A;9^V7'Y96?%/PF6Q;I#V9:;BS)46':(VY/T76'ALA1"MQ/G9]]&U[
+MFDPS">-:/4?+N#45V<(-L*9Y<%V6D%$>-I[C0-D1CR:SR31^;N&6QT,=30+5
+M85+VIPOD+0Z\CC\Z6^*HJPNA^J+2[:IB^3F0?=)I(Z6JEI]KI^SEIE*-ZZ61
+MDMT24%.1N]?J*IE47:=]J/;F9$Z]5>1#2W)[NB,F_YT4&4D6V9@D2=NC3KT+
+M:;MY\Q"0U5R%MR=S"9GMF/-GJY?TJ&?\UEW;PQL:*#E-DI%R'.2,;=96[`Q!
+M^C,S8-DW9BPI)8"COH/3VK8]SGN-@7@]62?:WLW!#KN*HSX'ELD&-J.:K9@"
+M6RJ=QN;GJ4U2.RHY'LA#F'L,/F_:QW"=.;'%PD2V4US4W'KMNF/WI?(RTPW;
+MR+,VI[UPT5!#0SQ&V1`]:HUWA!8R:8MTW-.2U"2<S\5E3Q/J3F(+DGE[?U&!
+M0GG(L3TIVR0ES`(9YLM*N':>4,IT1-KQ*JMLQ0:Y(;ED<VM&CN`HD0[D+$S*
+MXSQVH;"[19U])/[&9YYC>)%!5FP):5?3<-+SB^>EF=6K]:;;-J>4`<<H1Z8=
+M6K:81!"^T-Y\;RZ>=782,H_&>H/F1?;VL#!N+M1RLNLX:4O,6H.SC=%=V&NZ
+M+"6:%VES$$MFH^GV=EH$[&^M'>DV^<K#-;\.W?4XYYQW^4=%<FES!MT^PJ_I
+MO%W$>#7EZ>G*1F[3B%P'G=+XT.GJ$9K).R_'+%+P-8[0;GVC#AO*H9L=WN*>
+M;4TF;?^P9TWEK%%^S:92HKQ-I"Q)J6@NTN&,***LEN)\ZM7I^K1%[O&.2WA*
+M)]IL;K+IL$M+YQ:6%$_81UR^K/(P1VS4-A*'+OQVIG)G=#@V5I"W3)'8UGS6
+M$-BY8EM2+:EDR/Q*8'.<SL]QFS-,XO-)]:GCI]<L2:;DRYX;[:]XU"/Y%LK]
+MJLMXQ61[V47NK7?+TV.,8)0E<3+#NQ?CS&.\>9'/]5=:MA'E>RULIZHG2N-D
+M-46]Y52OP_@K%EDQ!:D,966&879H29[-\#W*@E`JG5-RT^CI)%Q:*Q2IR&;\
+M8,<LPCOK:+(CFG(T%M&VF%:"[<YZ+(6DW#&KMU*W3_IH\EQNE;B2+7N_G-J9
+MW6U.=SH5HDCLT"?2$754XF%M0L#P!I?V4N\6;'W'TCE'46B12P-(C,9MZ9BC
+M5+[K;T_S&Q3*JVF=@))G=^)9M"U#-I)O^HGFTK)R1[SM2_DX/!]@_-&KNMOJ
+MZ'2$?6I!&+$N1GN.3-9SZ0[.9R9Y2!*G:0FI)RKKZ-@<7G7;"OI'-I<*Y^)M
+M&7/)\B_<C;\58?SBW2A/\:W$=KYUHLV#TI-VVM?BG1G:#B'"DFV\16@?N2P)
+M+=D6AF/&XJV1?"H7=E0/A^,4:_"[X'!8N\W"'6\&W8=SD<WDBVV17#2A?SRC
+M1K+UYAS*7EV;S+)5(,RV2`I3CW]FX(X=\2VTTBFXF3)EQ:K0ZC58E.U\@<`+
+M#S]^4?]&+I7/4<B-R/L/8S#\F3+\'2^MR'KU8RO&$=]6T&E=QU@3J=\.615Q
+MDK=W%L\9[]R,(GZE;2LQ[WVL5M9E4282<W29<ZB6=PFBWQ3I9;8"<[N7;]>L
+MJY`(+I:<MREK^#I%/T?9+T_P1I'/++;BI#A_B;RH<9;2UFX?(.R4,<GO2+4-
+MUCD.COOU2;-01AM#SH5FN8=$BXRK)5@FW9ZZU[.&NE4,VVIJN9:MA3O3,IJ;
+MQL)ECIGSDTGJTV8'9F7+:'P7MU"KX1)Q3=28A+1C$HS>S"L\5^,6:11=0WG-
+M)NQ39YI=&R-I7K!IXG7$^'V"R\_X7;NM3(K(0\;N;:?NW%=[M-;#H6W\2G9;
+MTBY12&[9=GG`DUH==?^FU^%VYL6@;>KK;*T]'!$_^;J/#QTNEYV\(+2H)6JU
+MUHV)JSJGT>KT&FQ^FYRRQ#&@,J`5KTQ1;2I.-L%&7C'Y\M1?/CD6HG7W8]XS
+M;N-SE'FA:+\9U8*,>:EJ78481:Z+$#Z9&7>P5N=6@#">)K5+/%.BJ/TJP.Q)
+M73-9@J@78WI#^5+(K&*\T-%O5?7+3'NY$2[*Z94T17!/5_,BL]!XQ:?+)0WG
+M45F[/[-ZY4\ATM$P#L864]\9F(=>\U!LWA`S,>YX$9'Y8&T^EO75:+;SM3LO
+M@-`=D>W.>I%<+A)-Z`;4Y.%&YK</:K\U6CBOV.L</1O6M&<+4;M^#@7EX];-
+M,BHZ.E1A;I%#47YUV>J,<;H6.C&F,&V;0ET(60*-8_%LU#VO5DWSAM_6E3%=
+M<I[LVD*_9#8LVRUR]9QT.(**,%OS;1EK8]%.6Z`<5M4W++G-8GLDF<LD8Y88
+M6G5I1>,(QLPZ,&5,WU3&IB--O#,>38E8/C//_@!;:B:9B6NEQL&)'=L2F!_:
+M3W1<9.V.1HEVP&,N_P*NP1SG22[CHQWNL.CL%>]4M<UFUD<\L5PZ(G.1?$IB
+MRIB]7%K.E/S3/K+4>).,.XQVS%[N7GZ@?CTADWXNH00)UY_&%RQDBE2^K=T4
+M0Z\JWSV0#GS;)W.2N/H@21L\WYZ-F&,HDQOVHM0UTI[/V+MCIEY':,.KUQ:Q
+M>"H741VKEQY&&Z-&DB5IC\JIPM]!L,F=M:N5W9ZD?`7O4*`O)8=JAJ5UC%#7
+MGE;7W]HQV-98OQV7$TFC&I+E^4;T'D>3MDBRG0<U&\$1^74*)J;#O!-*XQ!.
+MH1E?465HCY770^:N;[Q:]+J8SO#;YD6.ST#F2:HF10_OQJ9D3&[<]N6*B/-G
+MB\;HG.[IC[>DT\;EE5!W8:IR6&Y3\V^#+VO7@<8UG#$P[3KFUNGZTU1L^[!+
+M?,HK'16SWK?3F?QF<_]<.,E1NQ.O?OC[0-O-B^42]L$\/X6X5=XF+K3?)V@'
+M%#H#X%:.O[A+FU=\`.TB*V3>ZEDAUNQ#'I_4!.<2'71H05&>?X\C3\7:;85U
+MV#&2Z\5UN63<,I>QFG69T5I:6;>I==V+&!DWK&@M+/L;X2V;*7;:BW`!(1>,
+M_2L*'$`T3VE>I+M-)^Y=I01:7S35F5R'W>D]!C2F3\VSW8=">F/+.>7,V`.8
+M;2!/?]CB6G*0VYRU<!@I@]DUW@GBWPT-<B[E*XW-$7,=L8W8+4Q?T..M74UT
+M1^[-O=I55!GJ)`[&WZPZW^5;Q^$E(<=`6^S7O:OF-?#W!L[/3OCOK6D^-(F!
+MO7<4V^3RC%F3&7=/=MFFVDLES>^]G4IDX4+VH.+\",H>!"+;Y,MO>VQ2UU-:
+M'K30_@&IZV,V+7LRNU'9DQ;RU#YAZ]II;YKR=OO4M,;T\(%C8)BF@$X>\50L
+M:_-23"U4M;=/8!UXK%OOS2+I'>3,,.R.S[0UL4VLMW=F(&L/1[8YKIILU63/
+M\JL,_#OK5`]W/[JVZN3M6`YTEJ*V#KMSIRK,JO.1/=SDY;G!'CG5R9Z;R;U`
+MG\I.E\^)N"N.92]HM\HFTAW.KR\$/E?'N9F=4N_2==JQR[#**<,JUSX6EXII
+M)=N3,5PU2QOH>PJ.M-RAZ72JJGS>$5/[AZ1+74.9T9&<)A*SS7I4?B`1=0:L
+M\ZR<3H^UGG&;QSBQG?_XX5AVN(QTJ!Q?ZIS3\A'A0NR]Q7.;-:]S)_'Y1+E]
+MK),..PZGCGN<'.7[`?=)+8HKDZC*&M1O)=3+D"W:KPJL-TS\"P2N055QL[%$
+MWO1PF#"^$]1)P[PT4^/=E?E"QJR%V&EM5F:Q\3.!I-9<9M-6R%KDT;LZ#VM"
+MA+,=-/-Z,_VA]:[!JF`?E:(3[V_FJTW;4UNSM*V9KN2-F*O;5C0IK=(NK;3W
+M1E8K]?[2+H[5E_$"RMZ@E=-E+I+?3&CZJI^>U#F5,'YF8G75;)LE_F#7ZU&K
+M=LN1-C)XYTQ8$LLW:%9S:_(TP]L,;!/3M(#+[/*=H=F)ZZ7A-OS\QO6+E1!/
+MO7IFWC7SIZ>NLKCPZ(*4S6YFCU9_;E?;DII34?NWJ>3I4>LO\SI+M3]?'@KQ
+M[[9M?]&<?S58[AM"UW^89[/CTM?\WM7J+R62F=;.!NV_H<.YO\6CSCOXEJAS
+MG)#U26?8^CX1+V@-V\3;8[:/1%V7T6NB0KWDT$?F*WQ3^*A3FT[^B"H3MHV3
+MFF2<E/N/!^/69+OMJU2.XELL,=QOGFU]KG':*.20VUU!?G8JO\KEZ:^W_2>,
+M%NBQP]9PC<.5W.IL<][S\T'JAML,9TGRH=U1X+2&-7]A;2;KROJ=L-HF/7.3
+M<#A/1Y58\@;CQ3!K;O]BF__N@C8+-VJ3D(\EMZ%U^<]BDQXK:DTTZ5H_SNGI
+MY$A<3C'SO6W2W`/D?Y)*\S#'ZMCF,IK+;^WV=PCH6J&=CGER=2?3"6T5N!Q6
+M_BI.#N?R&/=R;B8W@U?J>IO63WI9WZ:=?AXR_@-=2T*.\[;VWPK3AO%TGBWJ
+MEL[Q'_FRA05[3,.+$UU\*8>NC6GS9%F;ZV-L-K-KLX^D,TXZFC@=S?ECAQ9G
+MA1;'@D"<=7G.(@]MHQP%M8#E<!A8TYQ6))!>D:;,LK6-E!5I6S]E5L`:=<VE
+MAU#ULT_#XYWQQZZXQ[K5W<?Q4Q"G\ZL?D7HN+MHQC!^%G2<BJCL^8ZK2&=N8
+M[EBCC&4>(VVW5/)4Y?KMI;IQEU<B\JK#>%H'FNE(Y[B5>O5C9?YX/VU^X-%J
+M7G1P3]9%A_F=B3R/);.1G+HW4._MU?<V'1'^^J<]'H_%8X(2.EQ<R/YE2SD"
+M=Z<.B#B]TFDNFJ(UPY\4X5XB+;8G^*]N+C0S>W45)K\95;_'QJDSEN:7YZI$
+M_2PRV;XMDDK&PI&.+?DV_(<#%KG+S#2)4I-D5':`-$FC,A7!&[AH)&LVN*&#
+M@DBR+6XVL1?P]ZMF_F'4<92("J1T]R:_N'-(;OTUGX9ZB(RY3,:H3XUQ*VT*
+M9:NUB^N<\\B_PW/+4A=VS,]YIB]L3AX=\:UYK`N[YX,_L7<40C"OLGE(*].M
+M\@-B_O;6\))FW6-0U5L)1P?\J8L^2S*E<M7Y#)T?LO$.S4U9&O6!O>F4NM/:
+MC(&?GW5$DOQJPU;'Z5*6+<NH9KP;U(?&&PZ[*`Y%5;]U89?'LKYV#Z@+.Q8;
+M?V_C\G0/)]8<\8+6@4,)Y=PV<52I_BV@/C%*+7VE3K8&<%EF\Q);0Z>.=6$O
+M)[)N3CQ$D=FME^O#7]R3>!XSLG4<EK7Y@C:4L9YMMD.!;0;J'&.BAJU'ETJ8
+M,\OM#?>S>Y=CR;`8SFAA"SX.#U/Q>-(J%Q)]':[CX=FNQ>Z4<W+-#/4G'T=%
+M#-HJ]8A!YXA<+LGO7-OQSI6?T$:GUT"S3*ZMU6HFW8I;6G]HKV&A]5-FLV:S
+MO:N%KI'YHURT=N^Z>EO^)E9?<.<5F^;58R-W2^V:$YO(\$1[IU2??YELC[KN
+M4E77$:'+".YE&64P^\R[%5A8;JZ]!_*8$R6_4U*2W\NBWE-H;^R<0G3$OQMP
+MS(5G>7-Y)UE8WC?*J%MF8*MRI,U;!:]*93IKG]0,GI-X^SS/XH;/V(HHRGN(
+ML=!E.7*1F'U>W5;&6[^0U3247'M#B*1P5VQHB$3Y;Z/A#B:IEK_=MXVH/IE[
+M>%G"J[);?LW^E$BXE9YD"3G6BIH>5\B3GR1PB?0L=&@N..<Z1G%%FKHM`D&\
+M@I'JVLNI6B/\E9%:8_A[/_B[8'7AA>?S4"\Y\4>VRGJH%6=BYUTCSJFL"Y>3
+MWS@#A-.;M\:C.>^HX3#\(G>H]9;*ONFX(XA[_[(O;N/@63:\>MG4%1_<$T(+
+MRE6V@"DMY4GBVGFU2,HOC2]\`R^_33D5UH^.Y]M44\G-;==ET]?-$^$X9=-D
+MU3C^,P8P=S8K?P,I\&-85,SF8M%KKY6UA0A4B2!!+:'O(9^8#?RJ3]0#G_*)
+M!<"_\8E&X!&?6`9\P2="P+_UB0W`'_G$)N#?^40"^!<^D0'^FT]T`OM\H@OX
+M5SZQ"_B,3_0`O^T3>X#?](E]P,=]8C_P[WWB`/![/G$(^%V?Z`5^WR?Z@'M]
+MH@CL]8D1)5\)^*A/C"GYQI5\8IJ4+SA-RE<[3<HW:YJ4;_8T*=^<:5*^^FE2
+MO@73I'R-TZ1\RZ9)^4+3I'P;IDGY-@&?);V!3Y/>P&^1OL"_)GVG2?EZ@$^0
+MOM.D?/NF2?GV*_D.*/D.*?EZE7Q]2KY^)5]1R3>BY"LI^<:4?.-*/E$MY0L"
+M^TEOX&.D-_!)TA?X[Z1OM91O`?`YTK=:RK>L6LH7JI;R;:B6\FVJEO(EJJ5\
+MF6HI7V>UE*^K6LJWJUK*UU,MY=M3+>7;5RWEVZ_D.P#\GZ0W\)]);^`>TA/X
+M+ND)#/A%"?@;TA/XWZ0G\&W2<SIAT"^"P''2$UCM%[.`?K^8#7R']`5.\XOZ
+MZ<J^TY5]IRO[3E?VG:[L.UW9%UCE%QG@Y_RB$WB37W0!Z_QBUW0Y7SW`Z_UB
+MSW0Y7_NFR_G:#[S$+PY,E_-U2,G3.UW.5Y^2IU_)4U3RC"AY2DJ>,26/"!+>
+MYA>UP$VD9U"NW]D*YRBL5[A`8:/"90I#"C<HW*0PH3"CL%-AE\)="GL4[E&X
+M3^%^A0<4'E+8J[!/8;_"HL(1A26%8PK'%8J+)`85UBJ<I7"VPCD*ZQ4N4-BH
+M<)G"D,(-"C<I3"C,*.Q4V*5PE\(>A7L4[E.X7^$!A8<4]BKL4]BOL*AP1&%)
+MX9C"<87B8J6_PEJ%LQ3.5CA'8;W"!0H;%2Y3&%*X0>$FA0F%&84]7R`_V^D7
+MCP"_[!>/`A_VB\>^()\?!._QBR>`>_SB&>!?^,4QX)_ZQ7'@__"+(>`W_>(D
+M\,_\8A3X-;\X`_RJ7YP#[O:+P'+"1_RB!OAUOY@)_)9?7+E<UJL#?L,OY@.?
+M\XO%P+_WB[7`7K^(`??Z10Z8\HG[@8_ZQ8/`;_O%P\OE>GV$T2_V+I?K]='E
+M<KT^!OR>7QQ<+M?K$\OE>GUFN5ROQY;+]7I\N5RO0\OE>CVY7*[7T>5RO9Y9
+M+M=K8`7B+^D#_!GI`_P)Z;-"RE&W0L:-N<`AT@OXBE_<!#Q!^JV0<JP`_IST
+M!`[ZQ=W`(ND+?,DO4L!ATAOXHE_<#WR5].;V9#]@,]D/^'6?.`A\F/0"ODEV
+M`M*>.03\1[(3\"C9:86TZQG@/Y"=5DB[!E9*N]8`_X[T6BGM>N5*:=>ZE=)>
+M<U=*N\Y?*>UZTTIIU\4KI5U7J'IK5TJ[)H"TYC/`F56B$_B!*M&U4LJQ:Z7T
+MKQ[@!ZO$'B7'/N",*K%?R7$`^"N_.`2D-=0+O+Q*]`%G58E^(/EX$5A3)4:`
+MK]$^`WQ_E5BPBO"X7S2NDG9;MDK:+;1*VFW#*FFW3:NDW1*KI-TRJZ3=.E=)
+MNW6MDG;;M4K:K6>5M-N>5=)N^U9)N^U?)>UV`+BH2AQ:)>W6!SQ*^\,JN4\7
+M5\E]>D3)45)RC*V2?CR^2OJQ6$WX0UJCJZ4<M:NE'\]:+?UX]FKIQW-62S^N
+M7RW]>,%JZ<>-JZ4?+ULM_7@#\&M5(@9\MDHD@$]5B8>!O56B!_B_J\0CZOE!
+MX.$J\02/0_.ORD\"GZX2)55_5)5O"!&V4#_`K;1O*C["2'HI7G\[88+D`O95
+MB17`YZK$@[?+<?:J\GVJO'B[E'-,E9]1Y>.WR_&#S9C?*C$+^'*5F`,\0N,`
+MCY$?-$N[-S:K<U&SG.\0<)#D;I9VW]0L[9YH5N>B9FGW3N!_D/\V2[OO`CY/
+M>@('R'^!KY.\W([\MUG:_1!P9D#T\7@!400^1OX)_'!`C`//D?QKY'JI72/7
+MRZPU<KW,7B/7RYPU<KW4KY'K9<$:N5X:U\CULFR-7"^A-7*];%@CU\NF-7*]
+M)-;(]9)9(]=+YQJY7KJ`=P3$KC5RO3R\1NX'3X!_C^0#_D-`S%\K,;-6EC\&
+M_*N`*"FL:Y'/-RG<J["H<-8ZPOT!,1OX3P$Q!]@6$/7`AP-B`?!_!D0C\%L!
+ML4P]#ZGG&X`/4/_`/PR(A'J>4<\[@7\;$%W`KY,^ZGF/>KYGG91S'_!/`V*_
+M>GY`/3\$_*.`Z`5^A>REGO>KYT5@=T",`+]+>JOG8^KY./#!@!#K"?\R((+K
+MY?/:]?+Y+.!]I#\P3?JKY_7J^8+U<IX:@?>3_NIY2#W?L%[.^R;@0Z2_>IY1
+MS_<!>P-B"-A'XVV0N':#+.]1>$R5!^^0?(7"AX''`^(1X`C9#_AB0#P*/$WV
+M!OXX(`X"1P/B">!_!<0SP$'J%_AO`7$<>)3D4/5/`G\5$*/`IP+B#/!,0)Q3
+M]0-WROHU=\KZ,X&'`^)*X!#Y%?"9@)@++)$?`O\U(&Y2]1<#?TUZ`)\G?8$O
+M!,3=P/Z`B`%_&1`IX%L!D0.>"HC[@:\$Q(/`YTC_.Z4\CRAY]@*?(/V!3Y+^
+M=\IY.P@<(_U5_6=4_6-*GN/`ITE_X$ND/[!(^@-?(_V!/R+]5?W`78A3I/]=
+MT@XS@8=(_[OD_-<!GR7][Y+UYP-/DMYWJ7.@PA4*0PK7*MR@\&Z%FQ3&%"84
+MIA1F%.84=BJ\7V&7P@<5[E+XL,(>A8\HW*-PK\)]1OFF*E%-^TU]A/`'-"_@
+M*5J_P)MIOP"VT_P#?TS[%>K1_)3`.V@]@),_+0#^;_('E'^`SB/`Q13'44[V
+M&@D3TKXSAG):?_W`/R"_`/X-Q6$\IWVH$_SCM/\`*68U`I=2/$4_Y%>UX'_I
+M$^=0_X\IOP2_A\YIP-^I$@%@-YT?@5U4'^TH7@6!%%<$D.)#(Y#663WJ#=/Y
+M%4C[VBX@[;.CP#^F]0RD_;4(_!-:Y\"K:%\!%JO$W<#OT_D6.)OB#W`7^1/Z
+MISA5`_X_2![(2_OP,I23/Z90?AGM'T#A%[W`N55B+9[3>IL//$&(\E_0N0+\
+M9?)O\*]1W`*>I',LRFG]#($_0OX)_@OR6_`#/C$3^$\^D0"^3?L1\(=^480\
+MARBO`J?]>Q3\/CH7`/^4\FJ4+R1[HK__I#@(OH+R$>!>\GN4OT[Q#4C[Q5R4
+MOT[G(>"_T'F)Y:1S$?"T3SP,I//$3-2G^+^6YY?.R<!':9Y03OO&E4#:G_:B
+MG,X3FX#/4CX$C%.<AWQ_1N=\U*,XO(++Z1P-?(SB.LHI?@?!_YSR"=1?3OD#
+M\!O4#N6_I#P&N(#.#=P_V1'M*([V@1^D.`.D\\U!K/,..C\`'R0Y@%UT_@)^
+MD^(.\%_(GX%W5XGCP'VT3P'/4KPAG$YYTQBP0.=^()V'QH%U5>(<\`D$!L+?
+M)?\%7DUK$U@K1`V0\L-:X/N%F`F\C/)4X$XAK@1^@/)5X/0J40>\A,XI0,H3
+MY@+?1^<5()U#Y@,O]8L%P%E"W`1\EO)9()U'%@/7D)\"CU`\`_X3Q3/@7U->
+M`:3SS@:6A_(FX#0R-S#F$S$@G6<2P&J*9\`7*)X!^ZM$#KB>XADP3/$?^$DZ
+M__!SBF?`/Z!S'7`.G8.`7_&)'B"=T1X!+J'S/O`TY9O`ERB>L?Y"/`JD?&H_
+MZTMV9/VKQ`$@Y5$'@==0/@#,4C[*\T'V!.XG_P:>$*(/2.>Q8T`*E/W`.RE/
+M!?X>Q0/6E]8=\"<4)X&_I#P/^&&*9\`_H?P5^*H08\"-0ISA>19B'/A=\EL@
+MG1O%1L)=E-\"+Q$B"*0\L`9(Y\A:X'%:/T`ZM\X"?HC6"_`.OY@-W$+[%/!U
+M(>8`KR3[`V=1G`.>)OL#*4]=`/P(K6]@ELZOP._XQ&(@Y:7+@"]1/@"LK1(A
+M'I_L#_PXV1^8](F[@5?3>0BXD?)G()U?$RQWE4@!\W1^!X[1?@9,T#D1V$5Y
+M-?!-VL^`<RB_!LZF.,S]TWD`^$7*\W@^*$X##]*^!;R&[`^D_'H?\`'*QX';
+M*#X#*9X^!KR6\D#@$*UGX#"=,X%TKG\"2/EH+[!.B&>`?TYY(I#._\>`=U&^
+M"-Q$YPH>G^(GMZ/XPGJ1_8&?HGR,]1"B!+R.XBKP;EK_+"_9'[B5]@E@@/8Q
+MX+=H_7^1\'\)$0!6^T00N)/L#VR@?0SX`UK_P#<I+P%>7R6N!%Y+ZQ\XC=8_
+MUZ?U#[S()^8"ORU$/7#`+^8#-Y+]@3T^<1/P1V1_(.4SBX&7T/H'OH_V%V`]
+MV1_X,=J?@,O)_L!YM/YY/(K3P/ETG@&>(/L#?^@3*>Z?[`_\$*U_X`;:YX&4
+MS]T/I+RJB\?WB0>![72>8?EH_0,?H/,,<(36/_"C/K&'^Z?S#/!SM$\#;Z9S
+M"LM%]@<N%.(QX"]I_0-?\HF#K`?M;SR_M/Z!;61_8`W9'WC8)_K8#F1_X%T4
+MWUDNVJ]X7H0H`EMI_0,IKQL!KJ3U#Z3\K@2\G]8_\,.4+P/_A.(_\.NTSP(W
+MT_F3[4C[)>U/TS_C%P'@(V1_X`39'W@CK7_@J[3^@4=HGP7^,\5_X'S*3X$1
+MVM^`)RGO!AXE^P-O(?L#0V1_X/-D?^"GJ\1-P-\G^_,X9'_F9']@E/97X'HZ
+M9P%;?6(M\/,^L0'X95K_+`^=\X"-%/]Y7,K;@2LI_@,_YQ<9;D_G-.!TRN.!
+M5U2)^[D_LC]P$]D?V.03NX#_2?8';J2\"?A1LC_P(Y3G`[_@$WMY7%K_K#>M
+M?^!K%/^!2\G^P&9:_\`$Q7_@0HK_0,KCGP#>0_DF\,HJ\0S7)_L#/TOVY_FH
+M$OU<C^(_\`&?*#T]0XBGA9B@')K^]Z_YG3+_JP:G>?SSU,@$_9^_KN5;`/!^
+MYC/!47BJE_DL</S/J0/,KP2?#;Z/.?Z9F`/>P[P.O!Z\BSD>)1:`9YC/!6\$
+MW\0<51/+P$/,YX.'P!N9HVEB`W@]\YO`-X'/9HZN$E#H5"WSQ>`9<,$<72<Z
+MP<?>!5\!WL7Z,\=0B5VL/_.UX#VL/W,,G=C#^C._&WP?Z\\<HB3VL_[,8^`'
+M6'_F$"UQB/5GG@+O9?V90]1$'^O//`?>S_HSA^B)(NO/_'[P$=:?.51)E%A_
+MY@^"C['^S*%:8ISU_V_PA]G^/NC/O(?M#][/_!&V/W@O\SUL?_`#S/>R_<'W
+M,=_']@?O8?XHVQ^\B_E^MC]XAOEC;'_P3<P/L/W!0\P/LOW!&YD?8ON#US-_
+M@NT//IMY+]L?O);Y,VQ_<,&\C^T//G8._!C;G_5GWL_V9_V9'V?[L_[,BVQ_
+MUI_Y$-N?]6<^PO9G_9F?9/NS_LQ+;'_6G_DHVY_U9S[&]F?]F9]A^[/^S,?9
+M_JP_\W-L?]:?.4R9*+'^S`/@8ZP_<Y@V,<[Z_W_@->"4T9'^S&'J1!"\G_E,
+M\%KP7N8P?6(6^`'F5X+/!M_''*Z0F`/>P[P.O!Z\BSE<([$`/,-\+G@C^";F
+M<)7$,O`0\_G@(?!&YG"=Q`;P>N8W@6\"G\T<KI1(@-<R7PR>`1?,X5J)3O"Q
+M=WC]@W>Q_LSA:HE=K#_SM>`]K#]SN%YB#^O/_&[P?:P_<[AB8C_KSSP&?H#U
+M9P[73!QB_9FGP'M9?^9PU40?Z\\\!][/^C.'ZR:*K#_S^\%'6'_F76Q_UI_Y
+M@VQ_UI_Y+K8_Z_\;7O]L_RKHS[S')V^!27_FC[#]P7N9[V'[@Q]@OI?M#[Z/
+M^3ZV/W@/\T?9_N!=S/>S_<$SS!]C^X-O8GZ`[0\>8GZ0[0_>R/P0VQ^\GOD3
+M;'_PV<Q[V?[@M<R?8?N#"^9];'_PL7%>_VQ_UI]Y/]N?]6=^G.W/^C,OLOU9
+M?^9#;'_6G_D(VY_U9WZ2[<_Z,R^Q_5E_YJ-L?]:?^1C;G_5G?H;MS_HS'V?[
+ML_[,S[']67_F6,J)$NO//``^QOHSQ]).C+/^;_/Z!Q<!Z,\<2ST1!.]G/A.\
+M%KR7.99^8A;X`>97@L\&W\<<H2`Q![R'>1UX/7@7<X2&Q`+P#/.YX(W@FY@C
+M5"26@8>8SP</@3<R1^A(;`"O9WX3^";PV<P12A()\%KFB\$SX((Y0DNB$WSL
+M+*]_\"[6GSE"36(7Z\]\+7@/Z\\<H2>QA_5G?C?X/M:?.4)18C_KSSP&?H#U
+M9X[0E#C$^C-/@?>R_LP1JA)]K#_S''@_Z\\<H2M19/V9WP\^POHS[V+[L_[,
+M'V3[L_[,=[']6?__XO7/]I\&_9GWL/W!^YD_PO8'[V6^A^T/?H#Y7K8_^#[F
+M^]C^X#W,'V7[@W<QW\_V!\\P?XSM#[Z)^0&V/WB(^4&V/W@C\T-L?_!ZYD^P
+M_<%G,^]E^X/7,G^&[0\NF/>Q_<''SO#Z9_NS_LS[V?ZL/_/C;'_6GWF1[<_Z
+M,Q]B^[/^S$?8_JP_\Y-L?]:?>8GMS_HS'V7[L_[,Q]C^K#_S,VQ_UI_Y.-N?
+M]6=^CNW/^C-'*$^46'_F`?`QUI\Y0GMBG/7_-:]_<%$-_9DCU">"X/W,9X+7
+M@O<R1^A/S`(_P/Q*\-G@^YAC*TC,`>]A7@=>#][%'%M#8@%XAOE<\$;P3<RQ
+M5226@8>8SP</@3<RQ]:1V`!>S_PF\$W@LYEC*TDDP&N9+P;/@`OFV%H2G>!C
+M;_'Z!^]B_9ECJTGL8OV9KP7O8?V98^M)[&']F=\-OH_U9XZM*+&?]6<>`S_`
+M^C/'UI0XQ/HS3X'WLO[,L54E^EA_YCGP?M:?.;:N1)'U9WX_^`CKS[R+[<_Z
+M,W^0[<_Z,]_%]F?]W^3US_:?#OV9][#]P?N9/\+V!^]EOH?M#WZ`^5ZV/_@^
+MYOO8_N`]S!]E^X-W,=_/]@?/,'^,[0^^B?D!MC]XB/E!MC]X(_-#;'_P>N9/
+ML/W!9S/O9?N#US)_ANT/+ICWL?W!Q\9X_;/]67_F_6Q_UI_Y<;8_Z\^\R/9G
+M_9D/L?U9?^8C;'_6G_E)MC_KS[S$]F?]F8^R_5E_YF-L?]:?^1FV/^M/O*7[
+MM75KD$*(NQYX>A7M?;MW(DW?G0GLI#TM5[OSV<#.SXO\^.GJ[K.%ZHG^G<^>
+MDS46/KO]5[OCXW=]\<C3MCXNYCY&M3YJ9#ONYXQJTF-K\[/?]XM"OF;K-5OG
+M;ITSD0^6OD,SN_.98/?AP>MVC@:'KZS;<&=SZ/;25;]&<4VH],?F\_8:O<*[
+M;ZD*<:J@ANH^2V/M')V_WAJOE<9[K@F)%$%)`M(F\6S3A"BT!`O^KL[+1.Z2
+MKF67^4_].963[BAE=2Z9R`1*>98DP*5G&VM\N4N:2__/.UQV>AI.E.(KO;DP
+M5/E]6;IS?$Y^QNZFB1#*WF8Q@[N;QICN&F/:M6-B3O[:W?F)=2A\\2VC<&[^
+M0^MV-YWDJAMEU5#I(#VF9R)W&?WO-33'+#7)>WI>CZE!_A.#;2<+36.%EC/=
+M3<>Z6_H+3>/=3<<'=Q0+.VIVYX^=^R$M6_'KORDT!7?'>^_Z8IAM65@9'&R;
+M56BB/FN[?=VW!PI-,[MO"0[>6]/==^3IW=L$ZM`0334#8O"S`XV!P?MJNONE
+M367Y,)4/-P;U\J;@X!QE"_P[47.><NYG<,[`%50T<&?`WO_@G&&4#]\9-,HU
+MXW8O)&=:63.85)[QQ?#@-8:/K%_7'"K==@YS6#OPQO"IUI='NDXN[CK3F)\^
+MT,N61LMK!MXH#O"CIJYSOGS]B<.["S?U3$P,7G/BB.5MI>__<F)"#E1\<W=A
+MF:SPF].W]PP7N9<3ISR;W4?-!MZ0#4]HP_@'1CQZFT;S/7`$)EE(!F!#G6%#
+M23OL'+U24_VK=)8M[`C24M+736D.G5.&-XZ3W]B62PG[Z]#*\<$=HWBDMS@[
+MBA8G72W>Y18G!]M&!V\>_,.:[O'=\2)+T^.2Q6_)8NOB+T9-8?01'[7)8FN1
+M/&,*H[?XQ5N3RE*GR;+M1BD+NW1AY<Q"?E9WTU!WRT@WV@]IG?[X-*^OP>N*
+M1TB($T<'=Y0&=YS9W50*K2]]C-(=C-)OF_]EVCB7TC@[=]2*?`/YZ7-^#BRW
+MXOUHUW.W!B=N!JN1A;429O)[TJ/..-3U7-,85V\Z(PO')>#5C-B]HY\FU5BZ
+M&&[')][>6+L[?XB>K$^@'5X)=FT5ZTJ?IZDS:B*&U9Y]RI>[=K"M--C6?^+(
+M8-L9TG[HR,#1$Z]0&6F+`GIPXJF!(Z0V*7]X1ZTO=Q45%ONH:K'OQ"GZ-_WK
+MQ)%B[^".H<$=_:>_VT-3NSM?L@63QVQS5&]-T>E/(]13Z.N?R%.<_N_7Y7RW
+MU2J):KES#&],_+K2?LHSNL=VQ_L0SLT^M7G_\T^?9\FO&^<E+\M*I5.TN':<
+MH7%YG5KF-SM@7[CE350K43N:E\+*6JQCJH&9.G+BE%9Q_->H.,3]U7*-,U3S
+M&EGQL"'2^G6EZREZLWXT;T0/F+2MW[;"G]'\N$;3\Q_FGT?/]K=U/<6%Z7D'
+MBW'&)D')9K]9F@R_-Y_W:MM2Q'XF!S)7+NM[\Z^X9^A;(MIKTK:2;;2A,C'D
+MR1L\X]F&DG<\ZW^C7#S[Q)AW/+ON5Q<<S^;=X!W/GO]/SWBV^(VR\>R;O_*,
+M9W]%+09&/*4Q[*#[PE_-4_+,LO4R^A\N4W#Y\?^0<Z\VG'>/=9UKS/X.U:%0
+M]^9`;_%(\>B)IP;;:FAAOTDP,'+Z=WH&KZ/GMJ?%M_C9B:,#1TZ\90HIG46=
+MLW09WVV`C#6%?*U-QF5E9*SWDO%JIXS7#Z9K!@X7GR\>+IXA,9X__0FGG%RC
+MM_C\P%,G4.?HB><'2&!$N1-O>7BY>YTM:?#TNY[7O.7N?,U#;BG5T&](U*-%
+M"@.#UQ>/DEQ#AP>.%-^"W(/7GSA]^N.LG58K74/5KB>YWZ3_?9[HB5=)\#<I
+M(-IGVSH+4<B<0[43-621SZHC%]MB_3I2LOLY;;.@$[%J.]DS/I-1O$_44+P_
+MK,[J%+,Q&!W&1@JUA66![@]UKPH40L'N=<'!+]=TCQ7RY[SCQ3O7^P4=)[6H
+M<,UI3%<-HL(9HM\S*<6@EB#KH$4%V:?9W=]=CQ`8+!_-"M1=8>,Y<P[,EE]"
+M2SYBFL%SCBUX-KR%G.&,Z1.#;10W9];_9/":GVL'Q<MHN($W5`D=W!IS_G_T
+M[3+FG,_.-96U64>-R!!H-'B=WNP#V$O::USMM+GVEG&F/AZ7^-]]ZCPR3MZF
+MK(P?M,EHM=-D-,_R(^P^Y,J&F\KGEHE>^!0?#K;.HK/!NM(#)^6V;^28<(XV
+M<HU9Y)U'X.]'[?ZNKP?/YRO5"7!PSN#OT?/!K34#3R-*4-`X-7`,IXX31T_0
+M^N0`X<AU9M'0@W/H^.-00=./1I;/C[C';2&Y:VE4]+`5RXA&G&R<PU[]:.,<
+M/N\XA]4X9?2I494^:U1SZ2.%-9Z?\GQ^1#Y51\C?HQG?"NGE`?*^FL'/&OF9
+M=?Z[%JN04OU"J*:P+-A\^]:YA5"@@']PYO_8*RK!O>%5E<I_RRCYF%&RZQ6U
+MQ(UXHY_U'[J68[=*Z.D@;>;UTSFIOYB3^C_!)\*%Z59"_^BK,J&?SMG\^]:7
+M7GQ=9O/3N\\:^7S+^E+;ZV8V_SYD\^M+U[ZJ<ODS1-X8M3+Y3R*37U^ZY%4K
+MCY])>?PH57MN5*GTQB]4%E_+6?S%)"-2^,_069VES<\=;AHM-%'V/L2I^PB=
+M&PKT[Y::;G^A::3[5LK-3W;?2O8H==]:8R4G/3W2'X:;9FIY_/`=07A!CY:_
+M#U]!^;N61U.`'!96/DY)_.3E.T<#1LH_<`65JE3=&7O_ZQIC0QU>$I1!M[`D
+M4/A0J+GTSZ,>V?BT@=[3?]`S7&U/Q*^E1/SK:RDS'O8;&75I[@FB2X*4,W_]
+M;OGD-Z=O)K\8+@Y]PE5Y8ABI]]`7@[)/I-S.MC+?'KYJ.!S$=)XI>PZ^VE3)
+MT.3P:\9)L+"DIK`N2$6?/\FGP.&-8UPJZWUS&/5*>KWO<+W2<-.8.;)^)M;'
+M_=X<:US5>MFP-;`<8IU]7%5O]FO6P++>MU^==-Q:_?QKC$L>54L.2*WW#;$;
+M#U<7*70.K0K2O&T<(T'P7FM]R3\BT^63QGG%GK/]XI.ROQ8<#[]R-G_U<]-Y
+MP2ZE?'GLYN>6!B7C?/G4C_D=G%K,G!53%5M67/#3ZBC<&NAN.EFX-=C=5"K0
+M>F@:_<K9'0UOG]C=TK^[:2240+.MHKGT`YJ(0E,_6C0=1XNF(EHT#5$+LO7;
+MSV+!YZZF:1E:.3+<-$Y3=.(4LQ*SD1.'24U2]O"[OMQ'AYM&BGW#325DQ_1O
+MJE3LI6D>WCAR^G_U%)K&NJ=C!2\-8`4OI;5RKGLI+]5G;+XUVYJ:YSZA<N01
+MSI&/J&ENJF5IZ']+^DRO*^TY(3?*HIX?S]'??W"'-84=M?KR"Q6J0Z6;3ND9
+MXPL_USP)S\EWZ/]3I)K_"SPA=ZK%#,S`9*P.&EEPZ>Q)P[/P='40CV=@DHJ%
+M?+&P8XB.>3>\(EUMXPB1QQ4A`[0$AZ^@`,0GOF.:[P4U^1__W;+AX_Z2+O^E
+M/W>L!-/W<S0BR6:Z^:B>L^A^_H7?E7.EYN?*DV:/7ZXI;".I2LD18W$1&54$
+M+UDU34Z6C1NOUSGC1O>`*VY4CWC$C<@KKKC1/G+!<:.CSA4W:@><<>.K+WO%
+MC=*(,VZ<?5GFJAXC&SKK]CO[<3-VJ`Z:BBZ=YU'1T,9Q#LW3\E>1I2FPF$G=
+M<!.GI@24FE[5?7:XFB.W]KCX%C^4N:FWG769-G_<R$T-4W__)4TFZ?7??DF7
+MZ>-.F:8/+PW:4M%/]CCEXBKE<E'=8T;+^/Z/KG;ZRT4ON>;N[,_L<E8/;<.H
+M",I#2TC$H1E#2R'545J;0Y_D^5L2'/H,5[ETJ)HJ4/ETKC!C*!U$ONF80>O=
+M?E/ML*":1X8Z$?"O4(<'Z_SI[_8A#M\20!R^)8@X?$N->>ZXD#HX:U!$;0RZ
+M\D^<,+3\<_B+095YNN?MCSZ&=3RSL&,6XLT0_+J&9HW(PF%)FL8]#*"?56_^
+M&&>,ZGQJ'%A+UPRKXZ=>]P.R+@FHXI-L5!IZU796'6[".\+ZGPS[;/GA\"W!
+M27-*\NS*VICYVK!ON-J64U(SLOUD.:6WC#/U\;QR2@\9)V]35L8/VF2<)*>D
+M0^<(NX3FB,Z<\KZK9$Y9RSGEIW[FRBE)[D+3S('>(7+GH65.G]9\_HC7<R.G
+M'!;#?A)E^-:@=TXY_&%U^M;DGTE##\UV*J#E>L-B*%Z+YU[KC&3R4^M;@T.;
+M@I/T+]SMC;Z;)N];H._&,GW7<(4K9!57WQ#L"BF:QS/,$LTDG9;\!"!!.BO<
+M26N1TQ#[W?"//NJX&W[H13X.#53+A18J7?13E1=FU),E`>/1&\?5HY87G??!
+M,[58L>ZC*F<\8R:+EW?=1\GB15U?H&3QCW&^O'SG?9PK=@1*G3^5N>+E9V^5
+MN>+?#GGEBK<,:;EBRT3S^M+$<9DKMHP3:1YTY8HO'[?EBBUGJ-JU@RI7?.JX
+M(U>\',*=KJ-<D87-7S'0=*;0,M[=,CJP<:RPDKQRM/O]A98QROP0QT>T.#Y`
+M1_@FRB%5NJ;LVA0<T'(\2@S->.Q93N<F:PH_<"4O,YK[@>H!E6^I0]G`"9GA
+M;3PWT'1NH-<>$'#O^H?4Q8`CU[L>EZXQ9&4^,WUK[*=3Q\;Q@:9Q&@:WI"EZ
+M/N"CK*VQ9[A8_(2KP0RKP1O%+P:LK,_1GC;D(S1G`QO/R,MR?LFJ<A;M7'[]
+M1Z2.RO-*_;P1C^HN5UJ!G7@E6:"D^6CI._^&FB.VFO_(-4=H4++;0%,)@FX\
+M5\"N=,YQEM=D^+LKC'E6W2S_-U,(8[0--AG,FA][R13"J/GMGUZP#%=:,GR2
+M9:@9:%)[7>D;+V">1P>:I!B(E,55`<SI21*BT'*RL++438ZX\LSNEK'FTBZJ
+MWDW)4(LYTI#Q38A-UW_]L-Q_\S64'U[!^5[7S4:^QRU/?1WO<3@OQ!->OO)X
+MT%+J7HGL[^/(_DK-"50HA1']FT:Z2:"6D<+*D[)6CY'O#32-%2FW:CI37#E*
+MT1MLE%F)(CA-D<KW!I#JD:[(]_#OE:/%7FB_L23S/78@N_U,E49G^06"V`=_
+M"DEH4FC&`@-T>,6X-1B/)HWL80IH3MJ:']LGK;!QR(QE"_3W7[/80>AHZ[46
+M5PYJ:]%8G\=@/=TO+)_YW'$\&T(3RG)G##0-%5<'S+1OXF?&^D)CJK`Z@!HS
+M>,/;>'QX8U\AWU?8<8P.7?-?A*<=']B(B\\?&.3D0!/]OWZ:.IK``J7@%+(H
+M8<8$/J'G,9K_7UXVSGSIYTHW.+,J^^_G(6')4[?(BX;7NCQ_Q/+'N=K<7G>Y
+M/0!,_!0]\'"4^6Y$6"&U"_GCA1U%4K/Q)VIU(?]]VB`EC-8TQ!XS5F@:181F
+MN_(%=]AC'?S@0_9A-SSOCCO'_]TK[ESWHCON?/8G4XD[-WS($7=>/.J*.Z%_
+M]XP[W_V)*^X\_N\R?YQ4"M<>\_]^4,8=HQ=Q%-,_9AML]`C*X-W%C6-&+LG>
+M8B5E%+B02Q+(7)(\"?N!]KCX%C^4N20O_?$";ZYJ9_!X;W#9!XT\S91OTQ&W
+M?"L\Y/NX4[[I`TL#CKS2*2-7*9-7V@76WK_9\M^9+GD/]/%RMLF[M\^2U\PO
+M2=AM`19E5:"X!*+.*"Z%=$<I`A0YOX2TG%\6+RU2?HERSB^I9CJ`_'+@JH%P
+MP)9?THA\-*D9\"._+-['.XCE%N;9'N&-#JD7(X6\M'M)0,L!)WO&YQB*W(T!
+M*Z]48]X:H+3RXNZ5^F#*QK/U]?\!OR#'&$;0H&1RI)`?*>PX28M[W0N&YQ,9
+M,(BG:Q_7UGC`[/GX9;S5#0@5I!J-^7_B!6/^"QO'W>WVJG:-@0'A"(>;?VIK
+M*>=N`+D=I5P#]EQRX);`I/GG0%.%;<S<;L`W8,\_T6Q)8++\TUO&F?IX7OFG
+MAXR3MRDKXP=M,GKFG\IO<)2$[S@=U<SA_(7F@-8&JK7@VX2+R;^_4,:_]75P
+MY+SU:*I(#!_$(*D]<T\/V;@M3G#%JST5T-:&OQBO09VR,G#*.."CGFX)%#<'
+MSC.>?]*^>+RF"QO/C_%N#92=>YY`,7`%=5:D]2%3'?W9;/ELD]<SQ(3B,CKJ
+MT+^7!4`H1Z5Z`U:.2NM0C_\S_.*AE;6[5IZ#@#[<WLWXRC_R%Z7!POLY>?PP
+MN<.RX+5T.NW[2F^>4\E//<<Y8L,$-RK4;Q5;Z7Q84_KT,YRX4FZW)+!P27![
+MS;I2\X]EDGEQ#Y7->%Q,4'![:N<[$_E9/^*<<R(_[4=5:CQ?,'39Z9N6SGBR
+MZ=S"IW(W[.J?\61O:*MO*[X>*_AV]HY-U-]>>N4H.IQI%.U<\&[^3Z7LRR[S
+M\RNQ,3-6F6I>>RD%'+S!XTXFYN$P>^@%QWVL/B_OO,\O12J$@L\U\JT.SK`\
+M091?XS+V54-JZSKV@\_*%!NE?"/[R=M+MZ@)^)@AI._4=_E>:'WI$[1+G<(/
+MAWM4_CWCP:\:G186&),Z\A1/:D]A:6#A4IK3]:5WGS?G="G/Z=)`][,[WYW(
+M[9WQ9/\#[TQ0']O>UUS:?D16NY3LL1,_=2N(PN*>^;\K&H7(/]#]YJX^K_E]
+M@%O-G%AY;N<.RFB[K8D6^8N\)EKN432[#UVVJ];<L\#%`O^,1WJM'-PH^S./
+MLK\TRAIZ';9+U_C%C"=;@DJQ8'/IVS1OIVM<.E&_FCW7KY/Y1&%E[;F&WE]_
+M)W?QC,>73,QX?/7$-7WJJR%YWUO?2P>*<S_$K^+?^H?NOK?[EQ5VG'-^Z__Z
+M)7R0G,C+%W)[G])>R#F^]?G72Y`LH1Z\[++#RLML.OW%)?P]`56;\:3@3^2/
+M'M'JD2]:0Z=1ER-F(3_SH:;:74T3N]>^OW8=C-=<^MH1]?F/2XX;+Y%Y*%ZI
+MS/S*3W*7[E[LJVVF(4.E';T>[X*GEZ__]X>M^M)F.\=KMUWLZUW8/^-KL-?.
+M=V;/^$:OXS<5CU_,'3;2>$_3=#V[;FMMZ>N8N$R`EA0\_MG&&J&_WR(U#^$;
+MXX7]V>D]Z+WC';N,4=EE55--J+3_F'/]RF,4/I5^J*F&IJG[[,*CV=J'`O,6
+M-$WD*5:>ONC6T[_L.01+%_+C9HP/2)5N?99R](*`JW<&?=NO+C0&%CZU_2/=
+MAW>^0[KN#ERVL(^4/5V]\S?0]<'>7(`:^!YJ.N?ZEO]?+C(.J;N7^.J/%"[?
+M^=38SONXS^;`PO[M'\'LU:C9.WT1R2_GC_KT?]_WX)%<FMJ%2DN?,F9MXV'G
+MK-%Z?Z:F:T>MR,TI3">1"S,*M6RS);7-MX=*Y_Z58X9\)+JK3P>[SSY7S>\9
+M4#2Q+)BO#I5^AE#Z;&WWC?KW8_KW#T'H<26Y`P?.0OW.'34BOU[^J(1X2^W"
+M_\/:TT`W56;Y7I*FCQ)(@`AUJ$-Q6==:AJ6N9R"L8ILAJ3`4TPQ).K.<<>?,
+MC#O3=5Q^\EID"70,'?OZ-F.Q#J+K#ZNH%1!$I2HPT%8W!796:QU!1L[0<52>
+MIK@!:QMJY.V]WWLO[[WDI65W/(=#FO>^^_/=>[_[W7N_GS@:;XM&BBG6[1I9
+MNQA>N`+.<`6BG^`3&D_(ITTD\*;U-BI<Y!-V0+>0'[&2B78Y``8WA3")2A=;
+MW%`<BU);1=%7'XE%[?B',/6_I"DE6>XI=O4VF+C>$.\I!IQFDT\=96>.JYO@
+M<G*&>8RD#ED8,+EX;`TS8]$E2.!G>(N/0NSI$Y+8/.ERC\WE<328.=PUD"X/
+M.%[%6R.0AQX$K26@CVE`ZV702+H\XN`B*3Y23,/_GE0E&``0_[_:@'W+'JE>
+M!,-G<9=B""N/&AJ"1`"4$W:``8!,_#[ATF_EOMC,I`]E/>3/8AS?$<9L-]>@
+MP=AC2^83BSDA-4=EAJ?C.9LE"P!1L<@Z?<)>&94L0]EZMA\CU@-/N06)[\(<
+M`Z\7&)&C+TBT)M%)I$0=5BF1?3[`3:%"ZCM`*J.K2(I;J%GD,EJ7]ELQ?BEN
+MJ4EI-3RDT_`1C9I>/R9+94BGX2%5PTZMAKLUH"TR:,U0>0WTVDE?XFJ2W+'*
+MN&=0CI9D#9=*&KY:ZR,3A6T9_8+?&*2;(H.4?<L+1,=)T/$/CB@Z7OW;*];Q
+M58=U.AZ2A>XDTQYC=L'<1[_%182,HD,^X4^'"$QK3:JE1D1%KT1%.^U'NF$V
+M6?*ZW$=&B@<D3>^-:S1-\H\*(Y+TB(8>*ANH33N8,1T<`1JJ,U2J;_:(HD*2
+MCR1EI9_1KH%K8[,?6A3WVAIPM`32T<N746.KB<;^H-'8R;C&"S*N-QL<W,6R
+M$QA>^OSU5&V":<,8JQ[7,/@N="!)C9UI")XWX^2/.E=<GVOA.J`8)10_UE#\
+MB4Q1\9!46<H5!Z<5)T_H5-"'$=T/#TK1@\9?V2!<"3@PQ,R`<IY4&W@BD*W+
+MDUI[2]PS!&:&[\U%K33,5PM-[%3N3:)J9[J#^OP9UGS9,]04&:+"N%TGX8!^
+MB/!Y"#[)G`?C*$//0K92MX(O<(!:^(78O:F@&FCK.HESYF)ISDPF)GB5.1,8
+MUOI7,M/*2JMQNIBUP<Q7"H81^MD^&%Z!-#`!_$!`V=P5OC'N25%8!P;SG-)J
+M`N^PD(9NG,SJ1JHIDJ+"Q[$;!3+MI,J[E`([I$E>"4[!:Q':CF6NBR#QBVZN
+M;QGD*Q,(>,(._HFF^R#4A&Y]Q/5IYW_L"XD3,7RP9F3OJDDU+*CH)P];+;04
+M3P2<#1-;+8L`2WB:.Y$DR*,I,5S$'4,:$&-<J$K\9ULNSQ(-A0`#<N:.+04'
+MM.XF'0F4?SX:;P*-B1(-0WW\A7U@Q^T#QE>RT$'W4D=(C.7DK;)LPP4`7M3F
+M3GQB$&?]Y3)@QY*!%/_5*'9!B#BP[3+7L4:-'61XS;(#7?XGTI1JW0X7LZY8
+M&>\LK8[WL-9S.6`2`<;7F3'BD;,FGH+IQ,3UX/@"DZ_`YRX8$]S;.4D)&.NU
+M&#[-5.G:R*2"P\E1;DI8N.&*+L5)&?#L19X5Z6)LIO+<HN&Y"X-YJSQ,'2X/
+M,@S^>SI0(O['89Y.QB/7;<3B1!R\)F3(X]3QHHU_+]-2P`7SVKVO*//:]D[#
+M>2UVNX.?`1/&1#ETK3H`[!5R5OBJ>$CM/O'Q]N!HZB&M5(M)LTYL]$QNCW+,
+M<"]^15/S^T$`+7V9K/#$2/\R/TG',=K\#*9=KF>DG^OK%F:!GX,<`%F5SZBH
+M^0\@`JKSN[A3NO325T_Y<1IX%M!`SO]X%Z9`N6=&&@&\7LP0Y0#%"!+4YKCJ
+M_C]"RY:'%B/\O2$M7;\+Y7XS1OUFD.'A0V/T6\U_TSJ^WWY5IFS(]P/IL?F.
+M'B+03XS!]^WI\?A>3/CN_G06V+<QSQ/U/%_SJDPUJSZ4:?_^E^/9R(F#>6BJ
+M2+9].;9]W'?0J.\9\-"7.IY_#@--L8XV'9UY7XXMXUD2G=_HZ:CPGXV.S>?9
+MUXS@U?6O41V?W9UR:T-[N'=T;%[72;0>S,>K>QQ>_\X0/@-NUO-Z5:?<6F<'
+MC.KIWKDDN5QP+%A$39'R`4ET)_F$5UZ2ZF^97!>&3,R3MA\)I/RDZ@:A:T]2
+MO-$G3.J4:IJ>M`(^V2>LE\$Q-Y3AK5(+.2R?<4@*(Y.:M3UMWOOM2\0-0Y`'
+MG,78-!]-FRF*H)_H$ZZ6T5LSO$%@G/+5TT%A'GEEBP72DBP<P*M$>+Y?6/,*
+MOBS6\_J[%W-X+=3Q^L\'I6WU^?:+MJ9H$F)[I("T:0/B]0OA%W$4D4U*;:*;
+MB?9@B`PRA-AF?C\WDCWZ@JI0138EQ%^3Q$H>$91VOS`[@Q+U0G#BH4*'#+@,
+MV/4+AU_#K?99^UNU<^T?1HAL]5(%G;^^/U?GI&(X>E#>1&4DTVLZ#62Z?O\X
+M,IWQFB33I)9'E<4%(XIMJE8)>I^]/UOO6IYDAO[M0#9#T+=S+V3W36^/][V:
+M26NT:TD8:4PU.S1G=7@J-V;@AM7@!>MO#5.C;UR^LYX65UN"PF.=4EJ%+R%P
+MH*7P92%I9]>T8SLQM*%3VGJ62N*ZL4@L,B*10\!)".CJOJKOB7^1QW>!9(GS
+MZGQ9VLYW1^Y^S]8O)-Y48[+YA(9]\@:]-D7>D#(K)>CG7M3O"57Y6#P>'W?O
+MR>)#]7\2J+).`J3(4LDM>]3ZKTKGY-`X=*:_F(_.OP\9TOEHOT%=^E^@+2F4
+M>VRD4KYCEZ[NJ_+C'8^?8$<^?B8:\_/7'0;\G/U<ST_I@3S\='X^#C\?[\O'
+MS[]^;LC/@7U&>E@Q'IUO/I>/SC1C.N<[C.A\?'$<.@UYZ>R^:$C'\YQ*)S?^
+M!9C,3/S^L]KST7+-GI0N&',1=P(WO\9-%#J6MJSWE-E$WE)43GW[JHNTO.F,
+MC';7PD9(F%YMPX3I&I(P_0[_%NY_6>]5<NI#_WTA&\],!4^Q!D_URZJ+R?$L
+M!_?KB4AK_1D2]1>R?)<6=A.!-7ML66LIF$"2:A43+N)-]B,6&M]59*_33!X+
+M][7[Y6P1G:(6?P;\K21-*8X^"]PO_/D%K=Z4M3V-[+8F:;F8!P.J&$P)#^J5
+MX4F\NN>)]RN+!T/"X)ZL^KYV+EY!4."9&+24V0#&C9;UE%T&8%S;<V8;JS-(
+MK+5COUKRT_/TU?\H/$EE:86C^!Z5H_K]*D<Y^6\&7II7,PB:-0C*]NK/[6>@
+M-P,TR,()H9BZP)'8K;L?0*U_(ZF`,W=,^E78HR]DAF66_:M\4AB.2$P.[%:9
+M#._6R5T#>_HS+6P]'1(Z-'`WZ^$R4$]]AF.Z7KL^NEN_[JD]_Y<AT1IPM@32
+M(<$#C<OB0(34<$G``L3>VD7"O)!P';RFDQJ=ZO%=I\'G(/B^V*7%AS$YH&M2
+MT)W:I46GT]'[YV4=$1[DKE3O,M;1WO.H(X>!CC*@)>I,H*.S[CS.-4XME0M[
+M#>:D[Y)VQ5E-X[N-UIYG(3L>!M(0FY2&..0LY+[G\MQ!<7XPC^.'#BB.0YP?
+M%()[L\:$ZO\)!D9.K0#*)`>:?Z6S:W7^&R3RM:%."`PC?&(X)_GSLR;#=3^?
+M$:V>Q@R)A@-+\DKC+1UYYO)/$^/1^7X^.OL2M&SO2M-YSQOIY;Z$HFM-4_,N
+M0_G\0T+1(<Z\-HT2>Y[5X-;HL"QQ93I\8$\^'9[[E.A0YD]5X3_NT<E,W?^K
+MM'?F@'Q+,^\'Y8GJ1I[F3%Q%9M^CAO=??*J;7^7EY6+)F8[TDFWPUJ!0J&%=
+MW1.@[O^7L$AC7Y\+3]JISXFLLG^!,/O:G9JD)NO^QT\,8O:>IW)C=D#SY1Y-
+MM)XUM__:",\&`SQ2X-_V>,[>$Q67VPC7O*?&R"-^](P^C]"<?Q5R$\@BGS#P
+MI';]GK/FY:53R.:%\0E/(K0U#ZQ&Y_<(BLY=(^'Y6KV7[I+OO-#PM-R`)VWM
+M&'-.:9F(;$A"/9+EWJSW/!X2TGZG-#EK]O<</<;/J7&4G!*'T=`#-JQ;3-?<
+M(:K@RQDST7-D7,O0WW[.R$_<(;51;+?V/Z#K:HT@TQZ:P%<("M4^PO<L7-/.
+MT<3-K'I4H=2F>__YQS05D_(<\26\'5WP=QC[E^,?*Y,K7\V45UN:NS9-="4;
+M3%R2KH:8H'DX/#DD'-@IGRT3V=-@5F7)O'LV-@`Z^<Q,-,+`\"9;3XJ%[X&B
+M>ZGI^)/BZ,0^,6%\W8`AT+"IE$WP-4S4A>N?(/-%%%L"CJ67QI\*J5\O=#R&
+MNF`X$W#0W!4^BC<JKF'*UUB:AS?/J!6NSO`6WHD+.&N9\K66H(CK-DYQC47X
+M/LB9ZX7XO5D,3X`&Y6Y+;#7-UZ1C2R;C<JS+M.[&9I&=S!?1Q[F:E.L8+JND
+MR)TG/F!+K!!>>3+#`(-[_1;A^IB'+(72X`6=XEJ+3W`_*J_`.^DU%II-`\JI
+MM<+&IQ3F[,UWB/*:$Q](QW$I'*O+@[DQRH*/B,>O-_/+++RIEN2J/WE6NG<`
+M%#`'-V'.$DS0+=S:-U%([4#1%BBB)7>*5'3EVM_9#]$F(,KPR6'&_4]GC$=O
+M$P<^5`)S^[Z1YF&VH*(K4=(6)%5YIU#W"%['&V8J^D=&$@7<,,2?QG6;NQ$-
+MB3-I*79DA#-/DQA-TX]%.Y1^S,_J1Q&N,UJYH*6B2QF"67Q.(@2882]=&IX4
+M%)YX3-*T)6&K$(>MI>&"HV0IT[L\R%?:Q#YXXWK)`H,A7.(B@R+L=+V$/Q40
+MMDE[K(+"S<]*I;DA]5Z;Z.`J#<E'_@Q";,?[Q&/W(HKR:"D,K%MPA^-F*]>.
+M7W@>_^=J=L9>LA=15-F;L4A'/142*L$6^*@-@#AR@D=D=X)(=X:$<\2"'?)X
+M#0E_\YB\.^2PR]/5Z$#8)8^0*F3"AF/&<QB28M%S.,9V!(5'8!HP>W9RA(]Z
+M4U#X9!M:Y\[83[<;YCBG/Y"<7<#6W,\Z#EY+!JJS<%/!P<FX'X(G7?NEVC57
+M'_2+](@_A/_'EB^BY>\>1[3+Y.K96!2+.J"CKNX&4%5BQ=(X38'16.!S/KB/
+M4M>EAA(N"=;".KEX='3")FNT)Y2PM$5[YB]MF9(X@W>*AK'UMXBO8+ACB2+X
+M!G"-*2YE'--,^X#X4NQ%5Z2HOJB>]H^\E["VP5^4WR=,$(WJ/W\:$^;=RP8P
+MNP$&W\LC9K]1F_OT;6)&;7Z,;=0`_^=&;6[5M_$8M9FI;S/;J,W(@*[-5U\9
+MM'D'VS"9-J>-VNS3MSE@U(;7M]EJU.:?]&U^H6FCL<NJ`;*0X&)MF\RX`3/'
+M$&-!.ML6<7,AI!JE,#X@MJ(OD^\2&9^P'\9!W$JI%J3+"_K/RD&N460M_$C4
+MYP3:,S#;`;+5P[1X1(R-:;R62Z@@]I;*JG^>);F=DF[*W=_PN%%L\)VSM":W
+M?F:'8?YWEOAOQ7O_<H<J1_U=1\-_)'X7QEXM"1Y6P:S#5:WD:+YJ)=^.OX7"
+M^4KBE5,M\<II5"_Y';5>_`43_"`[YN_LK724PA?;%/+,:24?^*-ILAM_=QMQ
+M1SB;U:[DHTY$Z2[AV_$/O!HI2:Y&&B)7(Z7(U4AIH!VK27*W*:T\3'GE2N#M
+M3M[/W$GWW,D%4H"NMZJ.;':=PD>+%:3%EKSW+?%TK&:`X"2-I/T7.\NZN6,J
+M6H'L\>.C)1(^\$QNOKU$QME'</Z>X'R/X#R#./L(SI*\.-\#2TU8P!=[FQ:7
+MAD>;%D\(?]&T>"-[3WV=</P)>18*"7]L1X^//R[#52^')]PH00>.MQ#%GRAH
+M@P\*M<`YKE@#,`7C+F._D'P0XJA3%(FC@`^*'4W0*YHVB:7A2ZU>T3)R,]V0
+MA*\;V14KREE'S&N9DRY[@SN'H5%(:&\G<TS<LI@"GJ]"GK&>$A1N4'GV(L]`
+M+A04MCR("ZKA>Q)W<\/U/N&CQ[$N*CX@!3132%P$?7)+?7)#G]S0)Y-T&S75
+MZY;[Y,8^N:4^N:4^N>4^R2408J\03:U\&.FIYQ8LFHN*<^S=>D8)5R#$DTR^
+M[FLW^0_:=28_1['..5=D\G,T)E^G-WFTS>L5;-=?B:U?K]IEA[&MSY5M741;
+MGWLEMCXW+\[WN!$T\@(P<G9B==.M:.^WHKW?NI$-@^V<?C1C.Y^UZ6V'N_@U
+MV7LUVCL%YI;X&;&_GSZ*]K>Y[>NUOZ!B?2>WY;<^@[.XOSJ=*7-,U\J^2I6]
+MD758%>,@C2#Y[.`NZ$6?PDO570\3PQLA%[R'OXDD'!*)Z(9B*CP)+PF!_.KA
+MK*+*BX_@%/9A/I[[W]/R7*+EN>1*>"Z1>=YIR'/SUBOA^8GM63Q??ECEN4W)
+MMRM7J;EW95UVCE$D]0.)#CR$UC=?LKY>+_E1T%[O*NG#)WVLE#[J<+K/JF$0
+M_"4:6J72W\K:1\[YIOM/D7@2@E:1+83`]V\Q-O<MKS>3VJ=H/[JLDNZNY?U+
+MQ'[,=VR8[Q1*J8W%WNFQ:6IO"F[]O=#S3I$U@N;^,!,=I<,S$QO;I#.D?,11
+MOL8W\YZ5'&OC(H[$#6VHRH;E]J/;\.<OS0'&SV_#'[X4^[DX-](MSJ)9VY2(
+M`S/1B$/<>!.+:;FX=BXF_J$Z-W>2-.+8(7(`(N6*.#9#^IQRU3C8JWAV"(*R
+MADF$\X.$_0J\@Y_?O!PZ93_ZT':%Y$./:DFB!TYRH^8JW[3:E9I[I-7]7R>E
+MK9H!FZRUJN7^6N$;#QG7*6:?E.L4)!\:^DU&USBS,KW5DKJK)7572^JNEM1=
+M3=3-1V^2FL-(-[,VF`9M(>$,)DN@FC<<?'4I[E^-KV.:%A>%S=[$$'>Q/&#C
+M0G7#U30=MH:$IG92$^)"\,_"-3)9N4G6_7?O*JDIP/+!N8E"(K,0PP62:">@
+MKV!I>2#9W&__]>LH-@_901])PV.RCS:Y[AL\FP1>V$(OQR83YT''T(1Q-98V
+M%O"!9,("_[GY2/IVT!D7&%*(30@*IQZ0"FTLGJW@&F%B3'.-\'4(F,9#,:&2
+MC,(%+C)(I"IPC3Z>'>0:5P*9<@2H$ZM7D:X7\J$Y6*,C_%N`,_N66\@.88F@
+M@P_.24Q1]JKCV4;2SG[$I+^C#Z+M83>T9WCWG(059>"V13>LHL)TI;+W,_N]
+MA>LFCPKPD1G:HZN18&[+SA_HWV<<FA<&0AL.!/JBGV\BXZ"/NX2PA.%"VCL'
+MZQ:TU\+E7QO>_X[6WK:T_S_L;:'4G&M<S=?8N-OO(C_3*YQNQ7U,D#C<BU]]
+M_I`0>E!7=-#YMQO>D6NQ"^59==-J<*C137=1X6+>>Q?Q-_:C;L;LO<L'`L(B
+M!Y-Q@J1.?+P]^RXJ[1TC)_JE1>"U)7+53M4!UB9Q?%;9%-44\!M`-?CL'HLK
+MM6ZV^MPM/Z^R-*T7P60!&4TJ"VE([>/6(B_2\-\%TP/844V*7PK6FW(M8QHG
+M^P6A3:IR3R7T\)V]DX;7(IE^L*[W`T#M6E/*NLO7E,!8H(>#PH^WDKMU2("*
+M=V&*:TM$=D`XW$+"VGK:S`[`"!_`R"V%82J;A"<PS%L#0RW3O='(4)&]>1UJ
+M23K24%O"!0;XI755W`GN[>Y+L[C`AUP-B:8\'])5/MXC3(%H$M++`:ZJ#J!%
+M%@NE5B3LQO2*7UK"U0PJ\K#ZA>_=C[@'T0G6@OP&\%:L-0P9(JZ383,9'>K]
+M*^3:OY+H^E5T`^U6SX;GC(=RG$"QT6U&=^9>[E.&0'33*HH%3Q#9*I4?-R%,
+M=;,8,56(TAC@O7-)[<[+<#WD20'OQ3'FM97U<'VNWDTFKI</@E22V>UYB`!J
+MTO3H_[+W--!-E5GF-6F:E@<-&"$BS,"(KAB."\JB$4;;'I*R'5K23O-2M2M5
+M:T4$@9)084P00AT>CVA&!'6'&=V=GW4<1W%E4/&OK=H",EI9=]1=SQQVESF^
+M;CBSU>V4X.20O?=^WY>\I&GMN.,YGC-S#H>^O/?=^]WO[][OWN_>^^%8>H88
+M@X/QN!_W8BFU3H8AQ%S]M4-JG2V;D+?0G1)U_=FCZ(`^._X%EMB2[!+SV]7`
+MFK[J%O:]E>W<8\_M^QZ9#E1_J@']$:`2%?@B,+C0$$P'P=M_',/A2B)O!T[I
+M'U(#4'^0HL>3A637GG=HV42WM)A(]M\"[6-#K]7,2UCB6HTM%GT8JG9W!\_+
+MX6$PABV)*Z-;@J9@&>.8E^#8UK2Z:EKX>#?P\6ZPQ*)(/HZ(=,08QUO14NC.
+MD'-OT_BC%2U<A0(^#.M0QCKZO'@-KRGV$O5&-9J]I1Z,9O`DQ0#^XV[HF0A,
+MU92JX.),7`M`I(LKK2ZE!22,VR]OO5*+M"`PC/X@?%#]IP7\+0)^D.!/JPH>
+M0"5J\!Z@H;E^&:F*(#U90C@B/1:`X3DE$%T@$.F$Z!0A&B(GF0^R^I\Q3XKU
+M;:.LA6ELP9P%?-Y&V+R-V(!AE>*[T/)$?9R7C5#9B"6V!^G!&YKZ*]Q]P6]J
+MX9,@B@V]LT-C1.$,Q]X!HL2ZF,/6!0@\T\`O,"=`-()CRWLO<1?\;L$T`YM:
+M]-\P3I?>M$:K6Y]^%Y:/ZFVA3=F0*<280V)M7%-@1V9@0L"!O,2!O(WH%C-D
+M-%:I/36J`LKND/2N6M>:]C;#^*AAX]``%^C;Q;,;#,+R5"-\=`:.GT/!\-Z(
+MN?W\<<FD_V]G.FW(KX#LNVHY:`#J^W2)QTQ^]U)*A;?]/)AGA`Q=>YQ622X,
+MDV0<+/?,=V0]7QM7/<4Y]7`8QAM&UI/U?WI+$O'YHBSG/U7+ZQOT[^TVVM<*
+MT#9C7+3=\9:1-@[#MJ)CT':E@;:%(VG[O?8YM%TX+MI^=<Q(&X<1U61IB^?E
+MR-QWC)^7TIT!%X$:F$FD<7P[335NIM2LZ?GZA]IHY]1U.7B^8<2S@^%A)E%"
+M\Z`132X]UAP\"XUXE@@\,F/'/D7_<"?WYANNF-B":WM5IQ%S?*2/^T^/2ME<
+M*WV59%/@&44NI(PB+"]()L?&P*.9WZ-F8OG1MFS&$6T^\"";*V+I3&]U*/JR
+M[V8.-+_-W@>86\,FB[Y[!Z7EP]/,KF"QV@<?<8Y4+@_`U_+7?/.E8PU:Q4+<
+M!LJPOP7T4B5LU=CA8Q1C,_<:W>-Y6S,M??D(4\GVH'$&!7QM)OW?D"&.(E-^
+MMRB_='SEFT7Y9>,K/T^47SZ^\JD^7MXWOO+'1?G&T<NSG+O19%EP^E9;-&D+
+M3DC,CD>3]N!YB0OBAV<ACS\O?ABS7R0FQ`]7X%]S?,$)V#;/>:"TGP>Y,;G=
+MAKY;;:K/;K`YE#\/*J7/8;PG0ZW*Y+"EXZI2GYR39^A,_^RJ[#TL7S0_V1?^
+MEO5_Z15^)K#4THLT5+-&\RFYY8\HN^B/*%OVN64S.9/I4A)#7N$1[_-\*)YY
+M$U!'3SV)*^?4DX5]I30H0SF`X'UG5(=2(5LI_4U8I:[0:<,Y?"Y/:7B3S;S-
+M3JYW=:9A/[+"@C.P-N6NE>_9#`L[VHU9XN`AYO@5'HPTZ'?NX-96*'\IU>SV
+MI.YQ:(X^;7F?177TJLM[+17P+GP:,0;T:SK)62%AC_<M[67F4$LO_H%"R7""
+M[=9YBA%05C8XU3-8W])W"N8H__X;DCC'FXO]TF49>4[5D2U3G#;ZBU%N5:W"
+MN>`H,"^SMLRRX(3[[;!%:QR4U7[#W!N]G,U0CHV?^TBP5L/S(A,:;,D"7`)C
+M\05LP)RQXT0PW-\$^+U_&OPBUC5K_WJ=38%*'Z">!CQ\M23L%L<R=HL"/H33
+M!%RC@"L:"ZZ`[_:_]AAM&T]L1TVJB6E29.#RJ1V-G<,ALQIHU/P.-="4;R<Q
+MQ+_TL/6WA^"5Y</>)BEXM5;GZSP:FHD-VDZ$#?JT[8PPND>Y\VC0@82;0639
+M2&0QRP5`%P47:W6-`#U+\QI:EK7DC(F`+![O;\]8/')H_4TWHY70SQ@+/:!F
+M6P^C2#7L/;+KO]LPAM-'&4.BRTZ7J\SH&"-WV;7=&?T=^,@2H!.X`?;C&*2B
+M&U(*Y3]0:B=*'>G^1*WF;22"1@?LU;P.M]?9,5D]6WZH&_9%_P&D)1RH=RH.
+M]>S.(SN++D:OEK37D9M?P\#_N\;7>*R+TLI-4/0[(SSO`LLJ1SG,TVGC>&7S
+M7X\7?0](*7>5K:.L0=\/Z#'/`+S!_&I5%F/LB='V<.*UC)\:7L\;2L)\!^TT
+M22GMPDE^)C$/A\/+ZE>H_EU4_R?UVH/,ODYC,$2^2B(A-$+3N<=E!-THH(M&
+M@4XF;'%^NQ#9WH="I5H`YI\S<6T<-</@15IHB*K/>'_2V<(G[&P!I@!Z5.'>
+M[I)H.)4.S@(L@&!U46[QLYGB:/T@\^^@^EG^W:LY][^^2GW$TD$XOF)]-!'$
+M6Q/UDR.QF/73K&P_\58OHTY:SCO)3IUT$772S&PG9<J>S90MU$,CXQSN?X6Q
+MT6K6^&K#!/TL=_YW#H,.@&9I7Q,NPXIF<D:#BA*E>,\4FX8K&->K-BS9ST9P
+MO:GN3X)38"T0JF,,%>XWNQ:<0&,KFB6#Q92A$?6WP4*ZY?LOT[HB-_W/75P^
+M_<7(Y^B:T\:E:][\LE'7Y#!,ZA30-;G[,N6$(Q]`-";FY-;-G@OR/7-SUE]V
+MN(+L:!7<CE9AH;AU8F<9>%[&Q\OX+)TG@N?3RQ(`1%SD5$SPCIPS0DOTI&3P
+M/ZZP=.N&WV+?'KW;AOZL%38"%[@$C&SP]74:GF<9[,%R;NPM_B:D$QA2T3:T
+M#AK.6*);J-XJ*D+VQB(##KO+)V=UBTS=F5%ZZ3"S.WAD5Y&O07]E77[^0-9<
+M<U$>7)3#5?DTD]MG"Y7@?6WWY,@ZP_T7AYF<\_K2ZVV@VD]K!\4\O<F!+^;K
+M'ZYC-U"P7W_8E$YG_#^%+Q;+%R-3WC_%X:ZW;`056#9+[IZ-YG.>U+UXZF`%
+M^8;91C)Y8HS[GQ<S/NH=MM#T@*(/?0?]1!TJ_K.K7B>_$"XWOQX*(Y#-FVD,
+M*K-C`!IV7T>IFG1)B3GX>X-L7D"E2GDI2QS*J#VNR6IR[J#4G[W[-NO_]:+H
+M=]'!T('OW%4PAF3:B\(V5&"LW=WA"?4-^JFU(`>_H0Y3B3)>HICD(I:)E$`9
+MTY:\O8A1/_GG%XBW1;<2?'4&'C.6:@'9/(V^V/@7,[PG*_4@,MJ1,*X2S#G?
+MD[AXVV>FL,D4*3Z,?^;ZDS5WE\?3M:FZ75;8QNR4:C9_JOF3+K\<^G7ZJFPU
+MI1R9)<[K\16L0^KRH>IBJ<4V^`+Z8]C`6ME<KJZP`'H7_)7S<](9V_SJ\\Q^
+M'B'<W@QNS'SKFDJO)_#7-.[POEOSRF:KU(_<D,ZV_+++GPQ>FM-."=OYV[@6
+M3NTJV2E5J^%49<WF3Q+_@K[_BS1%-A?$/;??-_HWZ`.S1X8&T]=2_I7LWFJW
+M:U(6,+<=["0!P!1]^V9,V">;KT6#<#CE@K]RWOUE.?=_'V)+YEJ@?F2=+BNZ
+MB&0JS?E&YTD>N?S^PX!I6\2NP_8A,F&;1^XO,9D25IBC'AF6OMT%/0E["W2"
+M7J0OW0AJ;C?Z]1P-E>AMP!*`_M'QSP4!,$D]9E;LF+;P789-?7]NGQH><K^_
+M48[_;<VNHIV2VS_4_GM,>!>10?Q3T],A3/.@1>PQ2YBT8A]\X<_02\UW4R])
+M\'WT>\?O^R4*5$=L22W7HFGQR_7I#3;]#W<QMS%@S#U.4"5#=ND<TG@6+]J@
+M,[W.=&0BYM(ZWSVX<;(ZF(`?0QMMT&/M>.X!?S>6P.?V(BF)]Z].Z3P1.H:,
+M:(,#D_:=)7L!H8/=6?D.%.!YYR"P(3@_>U8QD>8!GT<.E\<)U4_!ZJ>[/:E-
+MYXO\<VY/,D-#,H>&'LH`-Z(.(5]]#8I^^SIF8=W4.+"*MO9Z]MS&>/9<=Y`%
+M=GF;%DI/2.6=#V#O>7W:U83=AMCY?(<]ROG`I9\&K@:[NTT.13>O8RE"H'@%
+ME\%F8#*IG+-,2_9L<Q[^MH&`N*#0N0T,H"F>UR;HCY#,@E7V26C/+<!SH$S'
+MTEPX.>\\U6(X)RU5],4;N-TW24>E0P,NPIU7M]HSDN\![6OS:)=5SWLC^JH0
+MK%;['N:\Q.M.=$')L^L-IT):[6DZM-5AGS6`$59XGCD>FD(+8%RFKF&3?`7R
+MVMJ3:NTI4<ER4<DIJN1DXKK\MA;HKX]4SP<"P02!X"-"\`%1F4(JIP"5<7&(
+M/F)O_NFS)+_:HEN;I!#S71IXC,<<5?NT^4I`-P6):N&_-7`O?&;GP5KU'-8^
+M6#O35[.7Q?@2Y1P(EOO6L`E>;9A\5E0;JAWN:F?Y=_<"#?.[T(ZWPA&T1K<V
+MFX)%!Z0=7>4[=J-3!+*P:9J2W2V5@;!OWTC4]'EIXZ$%'"19W#WMLHOQ.#:^
+MU0Z7%?C2G#8JC4E_-N.,RL@('Y<1BH7@U8!##=C5:J<:`5GMP)1"MG2U`]W/
+M!N*"EEP9@7R@%>HO)'=@#EXL/MGX)QHS4<W`639W1H4'W1;I8NO'H>(_.P[H
+M"N?`J^=&B^N_^$#&,(*Q(I>+4]G?K:5366#CT+P^KX,Y]]G9'S*Z)>:)^:;H
+M76OQ(%QF7YG1CG6V&G&H$;L:<>;Y<^7(OV<8"8I/FT*^!/KL.V@(^/I3N+\,
+M^3Z!*C%5'$@7XZ=)['W"2B@<#2!U]$]:Z2B'OOC2[2B)](FWX[LA>F'#%RD:
+M9V<T[)""%VXMA;_0IXG+0-]U%`6G)&:#QIN82/YD28K[XKYWZJ?J6<DO3\:T
+MDD.9-^Y:>_ENO%TN5.SVR^U;#87AT]9U]+IC%>P&M!*0PYS?!6Q:C8/\OT(I
+MK<[B/K+I:U@"-V=SCTG]VC1X#X+7W=]NU5\!^M'_*]=O#-L,?5*^MZ?\T(D&
+MBF=;"IV7=2C,DZW&=7S9TWSH[>I95ZU,!K'R^S\44S=O?KFL(*LB,ED!9S,]
+M8L1<A3)]X3+@6EVW4`'C%LQ8#A/DILY\D+,-R_T.>ZDD[CE'WY?0=^"/P,3&
+MW,M)?>1<()LG`7\KO`9F_T*L@73(KNC_!;/'!XWX]U:F+2GZNW>,DI?BXZ<D
+MDWY16\YY?M;_ZRFC#\X/UJ`IN#GC@],&>XPV=443.@=.U:I@L3:J6^A676)Z
+M:K>YC/OG#'OLT\L?XGN`^H!^Z^W$(H>KF^S!TH!NH9\6^&D)3EIM7EV$`8$!
+M?>;-QDQ8^7KBY4]QW[=FYL[6%HTT%:%;TZ$V)A1`^-NC/0[W%4&*BYL2[6ET
+M7Q$ZHWD;U2)2'Q7].[>Q0<89\=J:PG;AWI]3/<`YRM%IJ%Q?="N09>4,1;.J
+M7HM@RZ@<RC%EEJHX^[PS&`^9Q;QD8`?IIQVDZIUC/.]F.5YQ):*K=943?3)+
+MU"U.4LTF<-5,^'<525TH1]IE\Q5J*#E"OX.]*>QIDU@H*1W%91BRN2.6#KMZ
+MQ`S<-;FIQ%R;3,Q`/21E]B?QJV)IE]G7_HUF%VP[CF#>;E#C8%<0POM\W566
+MCLE:@^7>_SP'TBUZ4I)ZU`#S>!\T^*=AIEY;7#-AK.;9:-?)_/FY[4DQ/V%\
+MD+5UQRJ=&''9&RR)5<YR]\(^_H?8K\.Q>J=[@Q.D[!08K,^@>XNR'N"I.T?F
+M@R=3@0WZ;IFE>T#*3KYW<'N?1".`N4SM-]I;H*\J+.[N34X4@U9H6_=_2V:[
+M=K=LOEI-@DBE"P#(2E`"V]O$I9A;=DS["N]WWB.%\IEO_QDW5ENTR4*%AT'J
+M]0R:R`@@WNB<TC)>23'9F=P>'8BMMVA2AMCULGF^.LB('01B!TW!2Q!3!KL+
+M-&I/JL]S.G-)/8B[OT&:I1%]P<H"]GH;JX#U17@(S4'^T\C9PZ=C2Z^2?/HU
+M+715H)(.)=,A7;]S)4OZC@>.$3NEM=8#Z="03Z]?20>+9@^`Z[V6^1B"@XGN
+M=.'V"WVT[?01H,K033<^P=SUBY18^''UE:N!^0?TCV_C'AEHD"D)717S[(=-
+MUN2;V4DGZ$ZGTZ']2OEK5?/-G0CATZJ8AX.B[[Z3.,%`)RY<"=T\.I=@"7T/
+MPQG[)?Z$/NZL0,_+SJ7P?\<D10^V&7Q.Z1L>%]`#J)UGT\%+8O['-<]!M^>%
+MCG(\'VG0NV]B(;@'-?]!/!U)>PXFGEA=)"IL9]L!>.%YW*>W(C/^R3SX8K0?
+M>6QJ'YD_R\C\F;4#C?TMTWLS_RG#K(MBU;-\>NWM&/,;JW;Z]"KBL'9^N:0U
+MH#^[*E<>?-'S_H(V7^?X_+]^:K3Y<AC&S4?Z/A7.$YQ[7E_XN_#9\1GW_S_)
+M^$(&ZV+>5M7;K()8`+6C^?\?#Z;H[_T==&Y=HZ:,-_K1VQ@+#ZIWBU+>QFA7
+MDCA8TA`ZT^=ET8]*<X$`LT(A8=[F6/@D8:7B@RYO<[2KQ1@/A@2V"%0M8T2"
+M(8']A*I%$#@TMYNA.D8ACU.U:*O`U,HQ=1&F-PC3$<)T7+/&PEV$J)7'"#VN
+MGLEMZ!'$M8H'!&',=Z6V9Q7'>(`P'B2,+Q#&EQ'C`<*XBF/<GX_Q!92X/\[Q
+MIQ8^LMQNO:Q%];6(,_C<N=+[HR]MKJ1#,RBV#!->Z2M;_S)IOE*31@N#XM>2
+MG3I<_S#.C2?_X4N<&S0K/@S\959\I6=%KDQ[]#&AD(J@9=B&>%:B(:)EE!R0
+M;0PDYFU,;VHA-Y#?-H_F$WN-*-LLRAY=F5LV]\RB[#$6B-!#?J`A6_DS=2WJ
+MVSRZ*ZF&4Z!LF<C(G6S0;VIAES%,PE#$4KK;Y=X:'MUJN!?5&%/RY`^-<:*K
+MC'&BJ\83)YKMYD)QHM^\>3QQHATWY<6)_GIE7IQH7OZ#'PB:.]/!;\6\37S%
+M-OXI)/^_^5&7'V\$N#<G`AQ757X`^-1Q1G];<Z*_"T4+ZXAKC7&$UHRQ2*TB
+M\GO-:/@^P%GWAL'WP=C'#^[_DOJ8<\77&_X,NYG+'V,_7_;]+ZV?,UDG%?W-
+M&_\,>SN7KW<_RIT2&C5*L:E5.MR5SHY)Y8=Z?/7Z&SZ\N5(=WMFO;7;L+$E7
+M.O+N@<K)?_JH4-/43P$@T*B5E;]*=AV&<TKY(4\*D*[S,8URHCJ\"S[6.T"I
+M1,3=NHT##7((N_HIHV,)TC%)'2;$`B"9<Y]+EH[?/2*QNR]E$#T^W??MT>^^
+M?/T1]-F=);:K(O/CS6BK;:IG)D9]90-_4,1#K7A8*AX6BX<K&@K'<5__"$_6
+MX50"F(D$:_#>D$XKF("!?EU]`Z*XE$AP*$2,3;\(7K+B=OYF\@VCV#O//&S,
+MQWDKEMWKXU3M%VW9(QYVU1?*M?/<PYG<GW<A@D:!X$8!UU!?N'V;'\9.=VKA
+M&4J6B%;$81<XI@D<D\1#,7](3$"?@*NB?18$^!\&H`[6=79M'2`I72@75@G4
+MN/HV!'AZ1:&V?+Q/,L6B?X_1+TA+D/*EKN`UOW4]?^BYOA#LS_<9\M,B]!H:
+M+P%=*YJT5#PL%@]7^`KANS&7EC:*SZWC(-<)6A85I.7K^S)CLA;AN@1<GR#G
+MU<+MWYN!6X]P.P7<`P+NOH)PS^S-:_M&A*X1T/4">IEXN$X\+%J1DQO9N)^Z
+M8:]Q/U60L8VYGUHS9JZ0B?[Q[*?^RI^WG[I/R=M/&0C^V4.2*?K2_J?3:5-H
+M;NRYA9B\-6(Q!6?&-:L[BN^WEJI]U2H5B?;:\&/H5/2E^6C'"M5I]#ZV\!66
+M7^^C;P$/BN(WELSQ<F6U"?H?>(4!]07JL#9)VX.E\&S1LDN@'2BXWDN(0E9?
+ML7XMQ06OQVXR,?HB5HW^+LOZ4AG./_8P_2X#?^Y<.MTY?(_-_1RUS;J@*[%8
+M'>;?@YBJ`HE?<L`4NE")1?_Z(9C)L><P_9VBIQN0P;(<?51,LQPPW/.0K=2_
+MAP3$@F&0Z<NR54>AZ@7#K.+()?%L54%[>N&!@+Z"\5;HME(O)^__V'L6Z"BJ
+M+*LZG:03&KH#+48')?(9C2U,PB`FBI($.@U(0X/Y^(D.,QL#1L2`721H.@0K
+MC5T4A?$`KNYZSKA^YHQ[<(X[$Y15B('A)('EN!F.J_B=C)^QVL[1UF$Z#834
+MOOM>5=?K3S*M!LYR5@Z=JGKUWKVW[GOOOM_]?$"NG*$PK`](9#^,VB\S"(N-
+M8..23>L@FD0W)**_(B,8*/\C<!3B.,7B")=F8=M)=%-X%.*<GKZ^\>>239#F
+M/R'@"*EOW@"O3@P.PI#O."48GT0(\P^#,PKT?GZGX#67!H^VJWO3H*.;MF6.
+MJL5+;/WY0U.%WB@8T?8D@IIOVU8")FZ1>9L^4ARG@KT]VSYDR+^>;?WH[U2L
+MF#>@STOI<]HS3X"`F9L-3A:'1#^4+!5Z.U448>%=V+/<#\FBOY^\Q.E_`I7?
+MG9`B8G30];@AT;PSW[Q-?!+G-S^)\W(FX5W=*#P^_D,4_=IM`R]DN>5_74K[
+MV*3]R+E1UO<<)K2<^VC*#/EYAZ*\=_?0>XCH>#]R5S\!?F;`"8-[E?R((S:>
+M@CF:C7E"<V\HNJQ@6HS-V3YXX!3!</N=J]SRS;AT2-/G]'5Y#8,G5=HH_[_M
+M+"-_NP3VS4$_*VA`OR(AW"XZC.(N#^I94H,BS)%VM3XXK`A]@L,8O%P6D<01
+M>?Q2K(7T8X)5WF1@F!'LME8!CM\M`U\X(\+OI^#;*?A'-/B3X^''^(W^^G&H
+MBU>^0I^,HP^1VTH(&>08"K+M27%6-.@X7V-UG$4-*L[G6%4M-"G.1S#.#AUG
+M1PHX>RF<"RF<>S6<L^-Q4@T^2__*`N6=./A-BG"CM.N:#3K\3QD=OGF#"O\M
+M2M4U7E?VI9W1+QH)OI^"SU/PUVGPU\?#U\$O!?"[P)N#T(?:YW)R+#,O@4<#
+M%(ZI%(X^#4<V,V);^ZO$,L'E[:2(:%TEAYT8C7`8E.65?NQ3%4:CF11*E"+M
+MFK%Q&-/U]X6D0#CXNA"6JQ>CX4I]!Q0EJ]-G-NKT/HB')$)OZT:5WCMUHQ=5
+M7H/'9^I*Z[](9$%1[18;;?9&JV>26+:L2FFT$L.D_$8;')]5VXJK<S?E0!1-
+MU73':8.U!2C[N*ME=E'L?'GK`"C?4UC>W$%"8^W9>Q;5QL$A]%?R,4/HWG<`
+M4GQ=\/?E(^AOCP_R&)F7STK\_J_@7>0LGI]#>&/Y"Q>D_!:EB/N@C'T?E`>;
+MY7#+E:(348X3JC'QQ2'-#P;6G\'%I!>?.:N>G)&ZW#K0QL;0.FD'EHD]OF8T
+M9JI:EV'6X+%`V/N5\A6@[G5'%A+COF>&@=P=6K8]\&SIS`Y>ULX??`K=S_1<
+MIN!,HD1>90D2I/N.<A^+^R`I_QW/5'RTNZQJU4K-N+HX9/']#:VQV7T`FH!B
+M+&TG49*BXFQ7<?;XVJ)W?O4..R;N]CT/CW&(56KVP#U_N)\_<[OEL?]$"W?A
+MI+UM5\B#4ON%\%Z!96K;R*^=NH__M:%W;NT]NBY2[P_X6>:9%'XCP8W_V5#>
+M(X_IO_CW-12L@6W)89BI]..^U'$7(=CCX_"[U30MSR+U?BYZ]SG"LY?"U:;>
+MI\?A;SV(J\?BNVM8JZN\P`JBW]8J0>V:`B5020ZK$?0[E@P)DA^W'(MT#;H.
+MOD>>25XK_R)<_AP8#WJ+!)P]P"0V/%+__.EKN2LUR)N'?(I%>ON<HN!V$SAV
+M#L;FPK#H@P*@OR`9P]*BC#YQ'R2PW4E!"KU\5Q\?R=IT0A@$>$]'X3V.X8F8
+MSO`AJ\5W'TIH/9HGX)3`7>?P-Z,IYG?%LP^^/U!PCN*9(6`^I_'$&&"B]VS@
+M%!(UDO0"0)!VZWS=7CKD]T%JX&0:GC>J^35R6>YR[=;HL:B%+&^N'(+]&HV#
+M*X=\)[Q9@^\3OL_"AM,!EP'#0WD@^O!'I9'"$_M!F4<#9_*DO\ZP^K/58VH]
+M9@A.!CFE)N5!DFE_`6@]63HQ</<J(>)3O.G[8;/-K6`6*)A?:/FHSO8J;R*Z
+M#3-\8<N.O49-C`3N/@OZ<]$/FZE_V.7:EY0.U8D29*X33(%9D%]_0UZ@]$L@
+M/24^O1;/I\*NP&Q6XXN:MA^6DP1<20]N<^":/Y`1FP_:_VXB.<V2.'^W5H\^
+MI7EN=3VC[(,'^5@I&0JZ/#:[#U($+,.+(Y:=!H1&.`A/@4$6:]`>A`PQSIE)
+M[L"[+,-\O^_#51]<3M4ARUVF%YQ`%QS7'L<#O66,]YWP9+4>+2%=1)7DPL$V
+M\KV9:F<77L8,.,&94(=K@[D7'V$]31NM?,1@:7L,F-B)?84HF%/^OAF9Q@*1
+MW+.'ODSCOHABM+2]@`F`=ZW%!98V4#)>0CC<S18$ME%PA#ZL18(6*]^T'M;@
+MY0B'^3-9C1^1+%1Z<#GB#Q[`;N?&27]8N!M,:!%_I#]40!U&8?+]ENTT=4;N
+M\^`DR"?>&ZWKX&(A+`3LI(0$516<%QT<WX#V0G7P[5AH^'$*&<EQ@&EU5,0-
+M092`H_FG!:D573=G]_A:U1%4E<Z>=&?0JLNN$D\:WV-(.PBYPG@$+N"N%'$?
+MS!^NJL^#'9QK%N`6B$;P'86L#F@&&>/K66D/).A#/:HRBR\3Y0Q6MNMXEG3[
+MG@7P=40(UQWJ-]597I6>Q3V37+)P#NPQ>!DH"L&3>Z6FO`1-P/<*U"FFD^\O
+MX"-Y-+$%0.PCMT2);8,IW3[X,O)JM?H*LV3+?81\95\SEC?`7WVR@IG+E>N"
+M[/(XGM@T-,U7B7B24ASQ&H0(BR=.@>XPT:&"AV`ZL==^$2U.%&W_FXK_\6C4
+M'ZN[+!KO`+P!FW"\,93N7Y"P#TW-[(H?I152S3H,K)!:1?1&'0MHCXD),/Z^
+ME?9OT%L:"P/1@'U_,C%`XM<]_Z'!L&'_CW$PJLA<MUJV+XSWW4CK/\7`*!D)
+MQA=EH\#(C_F6H9($&`A`>1$-(+8\F#7HY0\D+9\Q2OF76NEO:"X9X1NFC_8-
+M]\;04)24AD=OB*-!=)@*3X09UD,\(D9CX32Y&23>01\CH]7$(EQ\WC"UK\5W
+M&9/MNWZR16M6OK"G7%I1(UC4O5%G4[=SO;';^:#N:I#V(5C7XUR7AQ[6XB,T
+M9P,^0B.N`<5+1?`TI7J5+Q5W-8VR@YNI[>#B3)G@.?ETW`ZNU&B$_I&[0.>/
+MF^HW[ODH/5/X%H83[$X[0PA_#W_:B3X9:3Z]WD+O3S?1^]--J>Q/-XWL%]H@
+ME1O=\M(YJ6Q1M]T2MT7]Z0)]BUJCFSXG-;00>U5H%[=*SM6"LT;(%)T_6$F'
+MJN.QJM^BFY/7;\.-8U*_8G6J*C_.&NWX%6>/V)WQ*C_HXYMC=6N:1SE]S=1.
+M7YM5%CP;SX*3T/ABSKII/XZW-,>>=:\&9:NQT;2BSKKO*(2S[II4S[IKXL^Z
+M8WF$S[J;Z6[2G,IY=W-4GRG^O!M&QD2?C-,?(9N[C%(@__:6Y+ZHE(?U/"_,
+MC\F#DT7F'\E.R),@<_F!"CK^T<-Z/ULN.=<*SEJUJ]5>P*[&A82&F*XVG-\M
+MA&*[FL#MA>H^5IR\MQEN@-XF5NY%W2T+=S?LU^F[]S<TEN`NEZ"[-T*7X_HQ
+M[3@7=+B(\%8L\;(Z`(G5M4D::;*.YZR5N#X,5>O(M7S76CI<"1"8H+N73.,.
+M".S"H%9K!,;H[O5"+;7&RH364?3M4%V]@L&UJG7U5'Q=[0>9\"PM$TIH_9>F
+M&/W+M0)1P412H79,I<+"6:"%68,%0VI:F#6Q6I@UR;4P5ZLN=%/5PJR-U\*,
+MK4D9$YB:%F9-K!9F33(MS!%J<E1=S%95=CV5H(L)LJLC07:MV:3+I8'BY+)K
+M(95'OF',9%<4_J<<B9=XW?7)\?^1P_A]79X,MYPY+_:,C9YG_`L7,\^H_3\\
+MS^B;FUSRF?`,S*I.-7Z0[/M.@D\=^FSZ7*,VB=!#?&B+;91MJ4PYVE1N/),P
+MY2!]7'*BN>>5=K+&H.((V6C_'P]AU1U<M\N@DGMPY*QB=89:VM1=BA8*I6BA
+M4$H6"J5DH5"J+A1*8:%02A8*I62A4.I1#R<@*D\3]5T+1J]E5A,N.%-B`*H(
+MG/&Z!OAADR>='S9R5Q1T@2?+F$!FHFM`6L0JP'TD0+MQFS@P1VL38(:(FX7"
+M#1`65<GWS(W.0#-PLS!^GS8!>DK],3%<<=]-0[T6!UC1?!'9[&ZKZHLH6@4W
+M;8SZCOS+=<GBWVTD_?BSG\?&>]8K\?0&];3<BI:L.`H4>+C*DGC;]F$%/6"/
+M_!70\"5^+DZJ\(5;2JJ(ISFE3^BI9]EAHHG6.8<XF4!%-MN$S59A0VZX%(S)
+M5\H/_0SO[`B;S<)FH[#9-((?Y_LW4+IH.![\=4E]^BS<0,=_J\JG](?T3[MR
+M@VH/J^VIM$QA/).V9X#W#'`P/D4LK\".Q5335*R:?JPP>LX8[_^Z0=-OPGZV
+MS*M6`N[+\Y/I0CW?$*V70#[M#XQ>.[8TT&O'5GI2W)K*VE$?6!)UFZ3R&K?\
+MNVN(GXG)*<K*U%>E'=-3695^];.X5:FKD%*<2N#'^@=I?B1=)(Q*]8B+A,@8
+MKU_&F)EKIJ7"S'^;'<=,ID!G9@(OIZVG>=E&\[(M%:+;1K1#^$Y3/BJ"H<K+
+MVO/+RY]<E0HO*V?%\;)C=APOD]AP3D[)AO.E=;0-IUJ&2*#1?,1O7(?KJTI^
+M?QH5$XZV8XEF=:XC,KTD?R29/G.=MG]8+6^?%AM3435XS9;XYMTDEKC$M^PF
+M^J75\M[9"7N\NOR[GP6W!6SRLD#1^MG)9.$_WT_H73U[)'JY^Z.-5?OR*OF7
+M6'BA>I#?G9$DWOWWK9^L^Y/53U[R^J'W1[&-Y/S!OD/RU+CX#_7$O]Q2M^8;
+ML]0M55B-J\32"M6QL.IW$9\$\`_/9YK3Q++Y";H]Z^LUGRDP\;2\6>:6%A48
+MW6)9!>6D.TELNGGU=%_WTWW=GTJG\JN=:N](G:HJ)6G/7!O7J7YA3]R#I/>O
+M6NZ+W;^J&4N[HU]=I9IHI&HC&">JXF*M:O:!DZ.!5@F#<U/9O<H=26I1NU=)
+M]O?N67N>^*.NX1^_\N)B4;(V=..:\\8C:K>#N^+BXE1[`I\FUET(/KW\TXN/
+M3[K^:VW<VN/7,V+W-6A^'JX]CS:3OYEROLS+"/]^H(G9:.WLW__I_-HY?G#9
+M1<*:)&UFYZ\NA&WBT=R+A$,)_%G_RPO!GZQI%P]_HJRY;76<;$K+BY5-]!G`
+M3U?'G`&L'F-?+J;<_\\.&+1=UA_HAD'?^F]/J+^Z>\Y;_:E]8(_MQRH<PRI,
+MT@>?JSF/=4A)LYNN^+$FQ[`F$^KQ_3LO3#U.ROFQ'L>V'G7__W?$C9T]N;%C
+M)[V7\N7ML7IO%;K>6T.WL\[8[5Q#!=6E`N[6]3AK0>]M-=%[6TOTWM9I9W1^
+M6N_-G\IYI5\]H=N;[+RR2O[]A#$X>QI=M^WCZHN$%[\93_R;$G9D8G:DMW\/
+M?F@'GXY+R3;HR+PY7'61\&:[><QXDTL=#7\Z45%\75R&F-FZ>*)Q=%X]67F1
+M\.J><6/8C@#@.1M8L0#?JF1V?&*;HO;_*\C:9S)_(\.EOV(,IK47=/G+)D8%
+M%]Z(?2!'Y7H&<#V9/ZQK*U1_6"CW5#JW@=X_INR_;]-]GJ`B>\<E*9*T_=]&
+M[SG7T@N@VE3VG&M'/*N#L\L*M_SMN.C9I5\;;L9F-]MO3F4W>\ZDN-WL)VRC
+MG5W^?A7-CZ0+PE&I'G%!&!GCM>H8,_.F<:DP\_.<.&8NFC3*V67=2IJ727?^
+M1B5ZQ)V_R!CN39X'7GZ=E0HOG[;&\3*2$\-+.*>R\EU&)+_*B/SZ[K$W=1^Q
+MM)^FMU9`O5B1O,V%P.IF6GE&:E""MPEA7]CKZF00_:\S1NP/(QVN$!!E2OO6
+M,RAWVI9)PCN2;9[O1$LV>LU"J)N-GPO?!BWM\!C""0\9V'<.G6%])[8$ZQD(
+MU_*-X!I:J<[>7IJ`HQ2!/LX*J[#"+*PP8C?_-@A]ML)&@B/@>U,P1\N(GG+9
+MMX1&U*A,/4XWB545TGW]ZO._Y:H]#I&Z57)]MJ*T3C#1_@1I_QFO+]?6!XKF
+MSAVBJF28/+F%71!ASN(SHHHB`37.D#C7&3,9,\/<#)SA)FZ=P)B(WY9RFUAN
+M$LJ-8I7-7F45R_/LY5/2'$/%ARV//@<>XS-8;K^X?(K@.B6VY-E;IDCSO:!(
+M50V>V_MPD&NPR=^#M5RN)L7="G=*X2+R_QBQN9*F\J+JNZ`"]:SHB+`1E"]2
+M):\8#T&]S';'J31'1"@W@_-_]=Z(2-/N33@0#KFWX<`L0*Q0GHL#ZHU#;TG8
+M#/@>6W&YZ:$T*.,P4W%M\-&MK;@,WI691(/*$#-FR#1E$-%19H/P/66Y0IE-
+M#5>9B9EX](\0J[*3B86S*0WU.7N9.6E,A,DN<@#]WUG@JGM(CZ,@<KGJ<?A=
+M.&+$)1`F@IL>C6;XK7`:VB6.16&O-@M_.G1Z*@D3`7$UFAM0QF(.1X`PB8WF
+M-,XL-!KQ1&<HK=$,C8WH57ESU2[]"XSE4HQE9@R6'"T6ALU>;8W'8R)X-DW0
+M*0_:4#L"K%:,U48PQ?@UT]<_R[18:6&#R3,>HHF2D^B@J=V]2K[,0L4<UNU_
+M;E5C>Z'&9(6FET1?JDJ>Q5!.&8A^H`[BU[<25YL/%S$6:3K8,CHB;OD,;HH0
+M`6F'!6R%7=;6XHW<I6)E1*@,0>=U#?0X3H&`"EZ"_?+CY`A)!O$E%XT#8V`X
+MP]_H]H4M/C^C@4$]T/)J2.%"<NT$C*68&_"`2[0!>:$!9F(#\JT3B'_V-YJ^
+M`2/&J['O(;A7&HKDV2!:\)-84B'@&TPJ]R'(`[/$MV+W13Q/+MO@(K_$*DK]
+M%OF$&=M^(A0R68WXPLWYHBL$="XM(E"%L@IA%P9OF/&W<8Y3@@$):QR/!&A^
+M93P)W?=94CN_E4M9IOYV^;]8^'AA$"/@C(5=P7FP?8#Z-J)\AZ8[,=,$7POB
+MLDI^#T]W<M%79%?+.S".H$%W?I2DO_QU"?@8`3J)PH+**QSKUF4JSO;,Q*$C
+M8*;ZM:^K^3:4J&PHDD-FE5W>G.`"DE<LK1`,P3\+8<D[U%Z/1!7D=,OEP\/8
+MG-O,#RN<15Z3C@H6&3T?HT=/.CA^46TF-0FMMJUE%(UE2Z!]3BE4Q,H\_I,)
+M0N5G/8Y^HCN:=RA@XO_""JX/>QP'<%*EC3_\AE#9P9^99GELD%%]0YA?([XA
+M:A:S3#;Z+5*O%_H'^->J^'L<8+3/!"LQ_VR"ZP!*`=FQ=?@+],+C*`_>B+[*
+M`=+;:UL#X64/W`O1T,-<>B=V0569%^YF(;V?Q7$.;&OPA0+"C>>])],\*,M)
+M/`XZ9+?D&$"_D!MUE9,BA#EUF-SRZFP0ET=$EXRF*Z[CP@-=_)$IJ"C#I8G<
+M<0RC;JLW9+D:T76WZ`@M!HH\&>AO.9?%1X::C<6AYD6H@61T._;;@R;T=];@
+M2=1'7%W8W/KIP=.H3K97=H!MM:O+G\-'LK9\LL18X&>7;*_<[\]9(KBZME<>
+M\.<(`;NK2W"]C7"RZG?RWK<9^(00/*A4<!:Q\C@2%X7A'@=V@<5[^QF/N<?1
+MAV,]+`/;>Z^MCILL<'VBZWBQ*^2=*?3:':%\1U_P)^T`DIN`0!17AIHS[%PH
+M:&RW<\=19M[;QW@S53CP`.$T<7F4^"$A9P;#912&P7\,NK=S$SOM.'F`\5S:
+M.0O0VSKSM)1TG((6PTAHORVZ^J2*'#:8(5;VI<'CA^PQ!)T]AIA#B&D9C[B;
+MWY?FZ,"^%'AOB-F")D\=)8ATB)WCZ.AQ0-P(-,_*;4&4Y4)]]?+>7J8EG_=^
+M9H`0OI^9/%>D>7L5#OT'5Y'R*I98,#MZ+;YR`Z;F)ABL8#C-;9PD?$.B.)P=
+M&L8^-R>#+(:WPC=^5X??9'G5T:&4V4",FU!I)V#@IF.<L7B^9'0\'[,,IMZR
+M\VW<5.'CMN2*7(@=Q`X9EJ'V=X1880>O;T_S'L<HERG<\?]E[EO`HZJNA><D
+M0S()AYP)#`\1%358TJ`F2JMC?23125)+=!)-TO:JQ:MR+5<KXAP>ELG#DRDY
+M'$?3"U';O[:T%6O_:RL5>6@-)"DW`X@0`25@T(BH)PS5B#$9XI#S[[7V/J_)
+M!.F]O=_WZQ=FYIR]UUY[[;776GOMO=<BSRN-V]F^W4)H->@.L9^,#S>$5[_=
+M:KU#O_H=$K&A'H?0F$YU#(L+.FWA917J;-HE0+T<;JD+,->P;YV.RTB?2NG8
+M"N$W0%+LR4/TR/O*>=6*;WLJF2:D-?U6.K0&;?3]FMIV1E.3%^97J*U?&4T=
+M!1[@]7;RH1W`,/!CL\H4P&Z56>4EJ#*AV8H;Z?+0>^$5UW.LSX]K(WJ?&TAI
+M(!D2DI*LPD(R\=[48)<F=M%ZM[-ZOBYQ'DXE,F@'=&H?T,0V"[4/B,A%X@P<
+MW2FVT>4)'#*T8KH<B[H('9G<?L$BMQM.-*788A&MO!'L`EYN>>8TQ#&H/ZT'
+M^UEA?%MF?&LROC6R;\U*&"H*FS+D\)K3$$0%?H9V"HWKW404G()"2[Y1H=Z-
+M771&+R-:4-L()=4G'#2`;&NSADU$7U$DR,ZM.)06**#<U#QWEJ.0R+,Z77\Y
+MO46NI=D5ZB,<C6@5@G+1B6AX0LIT^D`K=DJM^"6PKH%^`2RR6;OOC%!4)C4;
+M[85I>TVT/:&Q!@B'?8RNA#F.0&8)H7-3H._-K.\%$.<(.S]1;C$[+PTO$U;>
+MZ61Z[5@KU6L]UW&.W?^?_5U=./J9>D/RLL_<<'9_9]OV_:3L*]?3OV3OVRRP
+M9IX%W%X+G#77G[GLO>3]?9;VX>]%\KO,TLX!]CV'O#N/?/=;8#['OL>NM[=O
+M\NB$"G4O93.Y$^0,Y<]\X,P136A\:`)1#\B-$/.+F(6/G1[1^A:3I\V4[?K6
+MQ36M.:0)H3O)PVU@@+,X1T.1S9#O)^0CSZ6]7-]R\E1_5H#/4OKNLSP[#Y\Y
+M^RHLSS+P6:$2!DX..W=R[73&A>=E=LGXL.^BTQ";9R\7P1D%5I"B-`-/AT$N
+M].W&O)^6EZOQ9<L*FQ#I>XG%V+'#66/`H46Q=Q`BS0H/"O7]B-9OV.NPOQT%
+M`K(F]A5!'E1:"I8F?07F;["W^BZ$W]I&F*/AD`/S'EW!0Y0UG+5[9]*B:$!L
+M=_5]X6"XL^?8H?=0KS3L=2?!UMI[Q.<O(!^'(M`](71@&.@/>`5F6*,AM<!P
+M+Y#=?1N&,<Z4)1X2OB)O?D'>-%/ABXZ+ZO$$KD6PN9E@.WV*"K:)R>1:/6DX
+MU3X0H\8LD]WVHCP\L4+]*:H_)UFD"HU_A9"PNJ#%)W\D3X8B8$>)/Y8[89Q&
+M$!^^6EW,4)E@RMB;UC-I?AVL.XJ<E-%96UD5JF"T%1AO3)CHN*VXZ(%)<PUI
+M+OHK*HN=PDKI%`38@1\@9Y5Y?Z-R=NVU9"Y^A\B`:\A\]G*.M=_BB/Q&D2UF
+M4MD-(TR')7!W`>;[),TM=N4M=GHWPOO:/&XH%[]QBS&4=6!81TT\`*&0UF=`
+MG#S461-3$3:=2@0.=[.3:\49_&&,YA)E@6W@/8YME5M;'">VP+4LN`V\(-,\
+M`^,S09OA1E0E,-Q]OX[!G$_`'_YC^#]<,$AI%2TG;94PRB*<0)E)VPVG#-IF
+M6<=0S(:TRQ^XC.YXFNGXD]?UK\^&.>(0_PAEWB%E^LK`D*-]4"KC<LOCT.>-
+M^"_6DB.6>H$'FE>E*UBF*84B5DRK,/SFF?A-&@N_R5X$+S1>EXCC<E(DW<"Q
+MA3:4>U)^!["=#4Z\,#SIY!R,E`J;SV/2<GG!(.,%:/[J!CJYQM>HZP8I,_,F
+M+V^AO"QZ[23_IMFEPM@87?HU[0:W$;FD==`2`PUBD)DTE0>3X'+.V+C,HX.P
+MRJ$3?13%+>C]=LB"GC[D@)Y"T:,P.E,<2@@)V\^%+&R9/DAE%:5E@&_`+W<2
+M]EC"Z`K?&_:V08RZ\%KH#':,51`:%Z>@?6ZWV^1.J?-M::1<6'E;"K6>-LR,
+MP*R>?16Q+;[-.?1/^'N!?%]QAK\[V)]>/MG?U5<E_SM3G;/]\YP%G/_M]J56
+MU,2BV]2S5)4.16!7('!APR<WP'`^`5-#XD^"'(."PC9GF8Q52`&(FK4([A;A
+M^Q;VWD_?2S&7\,0Z6!F]C?R`6D1X8C4\^1O1?86@^QHA]I?TR;9H+BE#FB8(
+M!`+AT&]/0TY#8`MQ@:DU&S[1(+@:,@2=PDU<$9L652X-O-#H?\ZJ5(\,C,'#
+MXYFD@+4D97T!F5(>;MP7_&8XM-9H6?C9Z538(';1IH1-1<0H^/(+8HQ]!+.K
+MA3ZLU*A]3RS[P#AI^/OB5`V+FVN9CB]&Z&81T%A\T)0]&Z%?"QVT3;^"RE;;
+MA^ZVH0CT5[R(6043=<E:'%\@YT<O1EJA.YPW;8)HIEE*SJ>SD<U054'%$7Z<
+MFP^S!W_TW772HC_.,$\A-F4+SM,6VSQ]F:/K:$9<VSR]1E@)ZWZ<ISMVP3R]
+M:2[G6'\EYX#/?/9]WMRS^X.R9_LW\Q\L_\_^@_;)S`"G_?4ZCS<Q'K_4Y/%E
+M#9]L@]DS78[-JD^!+17RC_BOA,.)<4^(3FHP/F<"FTEKJE),6?WEYV.HDF1\
+M[H<`A:<:=PKA_^,P)GJQG><SP*S>B,,]"#Q,9Q=C]A2_.M"/W$QU[](C?9"P
+MFA5BTX2M]J53]P4ND4[Y`A<2,!7JZ_T07]8*C"V,\:*^/E>>ZK?.%9\Q5XQ9
+MHM[T=U8"V3_;9/DCT["OYGPX-"UA#J#-'%Z3@G,`?_3]\#/L)Y)*:FW2M;]N
+M3N-VY;E*N:<^(P6_"U(K>CP":4J5ISZ34[!H>-T#IRWY4&EN7Q\O;'+)Y?%"
+MZ=1=8G;$%P.$B=DJB_'"J*N990LHV$=P7E4."8V;^"N*&X9!F==^BAMTSK+H
+MP\VO0C7(;EP>:Z;EE&"\B;]*V.0NE(8O#4RJRPCM"[R-?GQI^,[`#=%O-9-W
+M\'6<MRI>.S[BBZ-7LT,>+`1>\,6M8+P'5_P]N@'RJU?%H[^!F)=F;F3##U17
+M@#%$@,G<-`^V)O+J:Q^-Z#$3S3P`I-B"2"'/P>'*5'H"QX4?;G80)POVK$?M
+MF9Q70(./:"EUX[9!/70=RZ?V?QQV;H1DU7[UI^J()B]SRHM<-F#06D(,=@-J
+M)%^/?3)A@;2,=XAI?G4N40RVNZVP"U_.*P^[%R@560MD?Y:\R!U>Y@E7>&Y9
+M)A#YEB*G2QU.*>*\9?D727/7WIU/#T'X^-"@Z/*K%\'<O\A;X@R>ZU<G0_SW
+M2'6-VDR^5*MWP<]8U"D/CMK7L9ZKR,IG8='=>.#)(XO]9!BI3ZVJ7TD1-N\0
+M7BKG4\O=[:I;>,G'RWO:/W5S_7)'^W%2Q=W>ZQ8V[^1V*&*_G"9U.DE],NY*
+M58QPQ(I6V*H,S/36N.HF**7.0G^-FH=88F2)F'S[9D^)O-1MGH`:G8OB)Y=#
+MEWDE.$WQ>:0V.$/Q:@;;*/#%6%H,@C%'X\+69LN#[??%.<TWH/CB7E^L[G/<
+M[G:I+X-$\KGD91XBO"+%L'1V;,N@JVR"9D;M;*DSHUG8FB:U=?E+%F9"G3VT
+M#M&2I=Z@N^YH230'>+\S,SJ#?-K+_LY:UE-W%$-X6/-;D&8+VH8ZB`PCQ;<`
+M7[4?=<-OHO@)(%?[41?^ZH=?SO:C3OS5!K]2VH^FA/:MF%B(CPK%#`RQ#..I
+MQP>!X"B#'>F!O,$.+I!6T`;/!SM2`D+[<4[.QGB]B$?[\13R,P5_%K0M@#!Y
+M%)7C[L9]%(WCKL$.@>)PW#G8D4H1.)Y"((ON0@)/S&3-PUS.3M@CWGHICA?D
+MD7:IUX-L7^0ALX@S,PO0,9YK&>-5E[(Q=BLE;F^INS9-[I='")?`N0=(`:'<
+MZB9""78_!KS5KB!7Z`?HO7$ZHAU2AP=.(9</A/E5<ODQ[ZY'IBA5*FZO.\B$
+MPG?DZ>+C4B?A[V-*53SL>4JNZI4B'CG8HY3'POR3<GDWIH`DD`YX]PK21([E
+M5^D1-F?(Y2=".P,/*U7'`%;P0,37;^1?487-')D7)X3-4[FN5%^_[.N2V]O[
+M",+]!`DEA4Z;$XI`GN$TX3HI3O))G$']"^2E*0N4\JX%LD"FOE+5ZZU2%_]!
+M*>^7!:6J1YF(I4X$%I$^R.66UI6K<)U(VD^Q-,`PZ&"P$>ZM*0ODJQ"VB8^P
+M64B*C5+>ZRTG[9,*OAZGY#M`:G5[JWJ$QS['.+P#A$KA%:L\H9VU.5(D+MW@
+M$&=\5RX?(+\]T<QFK7Q`"@XX:EWT7>`S6D.^V8WSH2WI.<=5>?0P@LA+(VFU
+MTQ<Z[L^XSN&H5&^%7`D=L"7<.4S>U'T<&@Q,(?I9FD/L26WN^DH58G='QP$?
+M=B6<2[3&)/HF@[_8K03Y=FV<<K.3C&CX]NLY(O/@F+G0N%WW.;F(S*@=WZSY
+M3G!M(#X&,;2/2WUDV,IL\?#<E\/7;I7NXR\(S']U)NI-GE!!ZHPK4\AHR5W[
+M53F=:(,YFB\6_0:Q?<F++,(2A"Q*U0FB!?83`4&(/;!?S>B2TXFH);6\8GSQ
+M.Y82\M3H3)`WA)2D>IJ<#@4^Q]Q(Y%DD';?W@O'%)XFXO1EC\K@M@8-8OO1R
+M/#-70\P4=VZ7Z`T_[`D[6Y![/?GAFZ[V$-PZXE);7,GTN@*>UV"B>EU+QN&)
+M$KD+XCEX3R[M@3,(,>M9WAD6^N[*Q71TD%I.70G5?,=PMTJ<M1#/V%QU"FG'
+MQ`"*7P_Z,;/0KI>"QQS!B7*,S'_9YX[XCF%T<;!;CN&YV:7H_3H90R`+%/'8
+M`GE1%BJL.)G!X;E/RR+A,3<.3+\BNI4E;J+*H2K7!?<7REU2NX<!$S8#K87-
+M$V'K]!C1(')G^X@;A$(ZF1B@\6"^Y79Q_9*O'U2Q_GZ!7$1F:55L@9PMM3L5
+MD0Q6_^*_>(,#2[Y#8#)8'>W#!"L*B^L:LS:IM717-%4KCTOM<<GK"'P):9+@
+M[`H=OV[[>5+""PT?$+U0U]!.]$&<S+1LPFI,"ASQ]4<KY,&A0^VG/-*I2753
+MMCD<+L=^K6"PIOJ(,P=VMJX`?FD_P=2Z=.K\NLFO0?J7W%WR6Z@9]O?2?3J.
+MYFPZXH/,3!9[89KU_/\WT-`)^V$6*(5$_Z>$5[CCBD`$=(4Z&4:Z$R=$[N>P
+MGY<IC6367;]E/#SHA_,\[?N/-^PBG;D!9'DP_DB:4AJ/IC83_KIELA*,[?_D
+M52S[.9D7D;X&]'-#L?$P+4@;*O(%(B-U?AFX'4!^3F9*U0#J)&A#A3;DK@G0
+M2(8/&\E0ZN)R,&;:PDI0)=4^,>K$:)V,2#0;UIFQAIV((I%=056I&B!\)0=/
+M'/&="-_78QD;*UTZ+^'(6/!ZGBCY'=FG4B7HA<#?O@&YG7`A$3OR$%EY:8*#
+MX-/P,9DL=>V?@M$%$V8PD-Y03O!S@UHA]CS1.3\*^^)^=7J,ICIPDB(7ZD@'
+M`>E/Y-AX8FX1L!SIT(.Q:";!GSP(GB!"Q1>#%T5.G-20IN<UC+\?')!A\JC1
+M.?(@'K_ZZQ`>GJ+%.?(^4NJF!T54-*LZ9\*Z+]A/3#FBEL*-!6]"6IJ@1T[?
+M]BW`94@IGR9[H_FH#^']'OV]`@KKA!9X,JX.`QDZ%)_:WCLNMPMJ<(IO0"?H
+M*+MTR2S]?@!0H$9]A)@21^[L!WRKU06X/(V3M8I2ZLXK(4PXCFLG\V(RR-2J
+M@?8//,16((JP:B`ZE<@7-B;D<>ZN2C^=%3W!?LOYV(83O?;<.$,YG"-<M;M2
+M7?T%9%>X`U:4+?>2X:I4&_#)]_%)/CYY")_<CD_B$/9>O1.?P"(X7/5,I7H+
+M_IR'!79@@6OQ21D&[9\Y*K.--=M-F_%MNYY_1W3)&,)>VCY-P2C]PE9!.G6I
+ML!*22<B'\]8H!]XE3X^2\?C!Q9QC[M?\%2;YF_M/^OM'8"UDGP'R1RD`W*=A
+M:'X%.UQ_O4.<91('3O%B__O^*.">)7[O@]PP>OE\T4O)"J!*9.,IG%MCD!%"
+M_0WYQ%;1&Q$:OT\`TC<TF48DE&.,PWSCV^/&MS7L&X[$Y;7SI5/>NG^1,/6&
+MJVZZLA'JA#V#W,GPO.PN.0P_HQ?2/7T8O[K)2FL.%M&X85HD!W/!K,%_30H(
+M6[,(_+JU-*N'W(I9#TY=)H2NY>RD(@5AW_8<V"LYE2^>A_V=:4(S^28_\'&X
+M8J\T[*+'X&AU&5,@**U0@VM]W,:G%([4WB4T_B=6P$*8?`55B+<_6*JTK#'P
+M)Z#K)BFM\UG_#LKX-3J=]MU=EZULS&'D>4?&KX5>;*+NU40PTRQ@N+T,T`4&
+M'=VD'1,6MX="LV)NZWNXHDL:SA!^!FO2"&:6H`KROD"&=,HGA'@@'@)VB%,D
+MI`4<E&MMHJDX0$8R'@FZ(IBV!^J7RB9M\P+CR<04)].D/@GCPYI?^2L'':.I
+M"3S)1N<$'9VE#Q"*TZ08"A:*GH?Y)+UUN4KK6COOK$W.-?N4%OB5VT'`U6;2
+M'M<]]0SI(^(>N&#H67@$,M,D1S3#F&8Z+;[):"&$"GB@$*5'*(>WR*:^*3SZ
+M;)%W<A%!9>-:Y"SD'N1<!UGT61A9P8P;,N;YD4;<@")\=2.3P5`7:'`PNJ+R
+M_3D@PH\\VV:D#<NH+0BO+EL#I(.?1YS#/>$V!)DSJMY[[7I-G'O"DW"F2D(4
+MR:C>1>R/V@#].:7NXO#J9@+U"(IA2N<>?IC6[[MR/*X!MPA@_R./AOU3O"U(
+MUKMRD8+6ZCU\QY&6-H,0/?Q)!B>:R?8$X?'Q%1<K.(!#AVR5Y^YBI5LSP3>#
+M$R,/$YQQ+92B=$R>N!O8DD[17B$P.1$#VO5U\+Y?:/P=L0@:L.9<4JUVMOK9
+MH1$MXK@(-^:?@>L:F7!]!6DIHP;JNP[:;\<Z3J'Q;CR+I`M'B@17>P.5',QU
+M>BX9FA:#B#@B1N<UK$O!<:QZ7;M"Z12&!L'J71^OJ*1ZFU*0`J0R$\8#'U(]
+M_\,?R'L:/@9SF<[^AA&'8^T*827XRN![\XHE%T5"-T'3VF=UD5#A"'7`'L%O
+M?2&V[D]`P)^J(]!W#YS?T*D=!FH//3L39V5RFL]-I#FDAF+T&TVY(I@S=MHM
+M^L=H1XL>>?9>I%.RRMBW0Y\>^6#!^[WUQVZJ'R@\<D@(P:+P2`AJ=;?1(D;9
+MPWU&2;$\F4FB;CFHLTW?>2[DS^U(OS;,`J06$'.GA^&%M"!TW)".YV*N-8!=
+MS=3T$?Q&"X+_\DBWAK.?)N31-C;COS1%#QA=:B2JVU_:(J>V$4PS]6_'=2M-
+MVCY#'J0EV;N'CH,AM@50"[>\#A]V=+6-8.^ITP9TTX\8\AO!F%.S_Z[;==+V
+M'"8R5EQ<L,]4,51&R*TOXK\O0!=F(3_AE#XLXUR-A%XP>OVBP0"O(S2B#5]'
+M?0H%Z3E4?).+(*FRE3<^APP'SU-#T)&RZU+BFA;TT+(-D2OA3`U.CVCVUF^#
+M?-JX!2OFC.CSAF/*_46#=[V(3#!-P4\O)HR#7_`9:JN=F(NE<O%M+GVZK_;Z
+M2D:;W$]UVE#ZT<?:1C![5=<)P/T.1&'>B$Y7:;N'3:3:Z1KVC)'>^ZE9Q"4A
+M&;'("^8@OO9W<X!)D1?U(B^:1;ZP%WE.+_*<@9W:91E0%ZVF8P_&N>K^3+?3
+MA6W+LF1$ENX&Z-W#8C__%#L3:@O^$*RN;B>,9QM5BV^0'T,X4V#9)X3^2GX#
+M0V%%_]]U^#9X10C/'6H3GH1DL'TK29UF\@OOC3&2!6HHUS8<!;APD0Z@/^G0
+MFR9X/(;9.DU)IB`:LT`XAIM@G5FPSY"K5+F<;T-6O(GU0OP.$X6&'Z)?:]B)
+MR]CP7&3H?$.,YAN3MZ\K%6R`09SXG-#8GFH@+X0.PQK1+B7&$V+W_`FE1`N3
+M$H<^9;+'5Q\O%!KK2:6^1U,3J+_M<V@Q0&N$-SP#(B^M!Q]@W7%"J,UATNV"
+M2"A@3+]E^*W_AB/XK.]O!OF(;6(2(G`C?<B!^;>=&@H#P]#OT9`BH0>,9XOH
+MLVW1`)G'AU0+3CYQVNC*O3=$KR-K\@UK:0_"@1&]8]%9HYZWT+</F+I?S**]
+M.-1+'RL;<<R8,IS/E&%OG1!Z"\6LJ2>4%OPW?/\8^I:E7%Q(N+4G#*"9,->'
+MR5"]NQJ.(H<0VOQFQ1*?#>XI4+ABAC2L"8UKAH!X<PPM/-M@G]DF^Y32LXAC
+MZV)6;AWUQ3>TTI598>K2G]AI/;*;<,\C/S`(2*G4^@J"A7\W\G)X/3S[TWKL
+MK?-=TIM#?X)7E>]"4\XC+59"\SJ)J7Y*X.,;3R202==Y]@$!(>S%81%"=YR"
+MOEO0:H%_-_%RBQTM3\X/*%H5AW,0+<KV#*W)R5AW;GC#"XDSPA>X.OS7]?`T
+MW?JT/LX%+NCK@B.#&[:,JB.$-L4,":T=-<3LP%%#G/8=-93R>T>-^;G_J*$'
+M=AR%K6[>$1A/5R9*D)>OHIPH8>)'1R#E4&]XG6?$EKM8.I%C<<[\<!(-3U_H
+MAKO409>WU!W,+&CK>Y_9;CY>:O/(/E4K)V_C[9^DR,%>+@9A;2"&OX<;DH,G
+M%$<A1+N9*G=!.OI>V==/Q&OC5O1ZQ>B>XH"^QQ-4E:G@S`VJPN8.X27TVW/M
+ML%]R4'@IV"_O(E^Y8;FJ1^YJ5R%MO+#Y>F'S6[D'E?(8=TK>T1YSP]7OZ]L_
+M<PN;JWIR#\K#7`<IBX\7R-4I"^0LJ=.I!(]Y@^J29L5W0KK:(7Z+8BNUQ67?
+M"6__DAGP$->(Y7')=R+N%4\L<2G!$[#-<@)]?BZY5`]GXU!!90N/[X15KZ_?
+MWB<*V""3O7]&W_82=/]YO?JEWF@\[/R93'MX^3_8-\77'[ZOR_39K;'[[&[,
+M!I?A#'3;];P/>G6M[H![$W_^RN*A^RL^>09UUQI##.OIIO$V:-E)8,<KE=73
+MQL-A;_@I5SB5U?!%D>`A/3K0OO]C>;&+/E\0*>;I`>5R/K0S.#>2CA:MC\C1
+M>I0$BU!0!%"7@O=7QN2<1W"Q?N1.%^RWT(T="L,4J/"O>(=2/BW"P;TV`(G`
+MI%94,N(L6F&H'17WU+#2UH+G':%(<*8C<+O4[HI.#BL[[8^OD]I3%7&FG!6]
+MDJP(?"ZKJ7\9MH9;MQO>A&H;C6II)4KY3+F`IK/L^YL;]'RX98":U#'XH(RH
+M8?9O]4U5IS^D@J`](_SE:?A$(YT->+$WH`.AOVC.T#V"EA5(G&5HTW)Q&*SG
+MV!#UK<8S"JW09FIK#$M<`7:7-K.V``D.=-D"QZ)R8\I&H#B.5#\E6_C67@5+
+M[#^>T1&=;I"3>M=C]!VI<+1@I^XWT)4<Z"#WB*Z#&B)O?J7C14G5A9+SO;ZP
+MT@W?N/=VAC?TTF?M847%9S6'>1#?[[4?:NU'<=_/Q/T)%/?P[[LMN_%[/R[6
+MN@\QL^&\=T.[S249F$4!7@OO-G01792AW[X5GDY9>AE;COJ(_H$G/3-.&N)>
+M3+]%QH<6]W)X@*6+!0VFX;_+SHV$5/W]Q@?0C`<M%#T7<P`_P#)UJPCH%6-%
+MLQM7-,3>.F;4W8UUU^,*!R%<T*P@]KE8&Z`<0RCK=2A!=\:2](C/36?H"WKG
+M@NYQM9!H.&Y=3+59W@HK?X>RS@T>\0W'3H)'O-DY@7/`7R_/.;:0OW?(WY_A
+M#%&HBUD@D5`W^[9M(KTLBUZP'X!/K,W`R>.H(SAY<#\SZ)%;NW"Y!S6CEYOE
+ME'(/[7%X119'7X=O);.O"S,<UXW;AKLL:"\"VT50J,"9)$F[<LET#7^VKWL`
+M,S13^Z/#XQU>\K$NF[*I5*(2REOA#%Z@;8`'ZMWO$OPWP%-UY##!3(*G8(#@
+M:YI2G,UFQ"I+6!E&X_P%:MO6I\*],N`8'!LYO`/-R6ZL=@#'IV>$WF<)[:Q=
+M(GT@,!YS[J(UVD\Y*?]`HMR;R'OZZU![SX;[6U#240AXL3D'<@_3PEQ`T/`%
+M]?#T\,/MK=C_4@D_'>+;/4$7",J[FA6<"$/=@=OD=A,#GZN'WT4*M,><,E*6
+M&$`ZCP+\R5;X6'H82B>TLI>9^8'O$DOR3A>;>]=2:CEJKY1PQ!W"$Y>GP(S!
+MX0\CXV#WPQOZJ?E4#KC2%D&XAK%I)4;E0CL5.0UL'=`6/Q):9`R)0[PRO,'Q
+M%$)YT'6DRJ5+`*$QE<C,0[T&6D+C>VE$'JZC?BFZZFS<#*)H==,::,X%4#@Z
+M?#US3[[W08%V2`TKB")'9(;/=28I](`AA0XC*Q)45B$UZ]OS%>2AIJP2RDS=
+M^PW!(C0^F(E:JCO:W6-Y"O0J]6(/A2>.$R0/O=&]$_X(G?H6P^&!08JV@N0D
+M8[F-2E7L1)J.]3\/9XJ+6'GDT*&.[@Z=R(@K^`(/[7SOZ'OF0['X2/<MM")L
+M(V5KJ$EISOAZ;W[@,XUJQ$<S2.>[2Z'_V+-YL+;IIO\K89Q^6(>\4S;NP&FU
+M&P$=,#A)0J7F$!Y_@--E:9;P)-Y%0TZGDN6(\R1(H^!EC&OJ9@F/[R5J,*P@
+M[Q#EH_/).*%Q"]QFVPF^!$K4)3A`GY^!DL^:E#S4=IBN:1X$GCXS.8600LV>
+M[C;@W+?8HN,[%NM""%7C]1@V+X7&4O(3]S0H?;Q(G\`5T4R=;D>Z&;49^;V!
+MMRGA1_!H/I`]U87[@$A*%'*=:?G1PYA?G?(-G9!62X<Z%G:0*57:]^D(WG=!
+M322'7T<HQW!PMN"`L+FUD6H8KBZ7.94";H59(.!WBSX@#VY#GQL:)]$[L4]`
+MEN]2*>@-`[@5XW/Q,YH'[[&%7%2ME"8<+D@YI@VW&.[%;M0=05<N>OH*-*Y5
+M13?>*^BGU#>I>P[@U62_^J-NL+S6Z#XP]#'67BYA<4?M)=1?Z,6?P30%/W,1
+M8B[S.KZ"/3]&I=U*TST2N%=J1:QJ;]00>>J>52\ZK#=(;3_=:PNVN,IU`TE_
+MA21%/ZEA$V(_\Y`@E$B!\RNBZ<T:TI]9D9%#9@T7N-#`?%>#!W5+'GNX7O?R
+MK<>*6.2)0]8B,'(^9J+O$PN8Q9RKV\]@:`?.U=#>T="8H4Y:/)4$<5FL/EML
+M+5"@8#MP\,BSD=I0\%L+9+K5E'=H_$!*R,C,W$@T`WS\\+-4^N2"0`;&@,@=
+MD8<DS5F;)D7BT8QF24NMFRQ%9NBC^[HQQA(^P1ZJ)FE<5M+HHTN*O&(2X:-N
+M&YVH>KN'OF10=AW2:)R!X/>H'EOH6)C)WG7L-UO@=1Z81@O@P/]VO\EIO%4E
+MZI+I(4+YE-H?LY\K+B-UQS'<[MNOX^9GS=UPB'E4ZV8P'XOH&7J'2LF^5]&O
+M2&4IS/M.KH!)`#KW^YY)M>K"I2F&>QUH\KK)K&\=M,T.'-?`C70?4EOBU`]X
+M//$6FTT/[H/RL$JLIOL0ZL7[8-I5JRLMD*9%2?]Q*S,,9719:R/U-SXC)=OR
+MY5"O94\#W_APG!ZP3)UGS`E4WZVO:Z7M,Q9(R[(<HD<G&=]-(QD89[E";>)W
+MX`2V^"W*VW""]YM2*[3H%1I_B0R,YDYMFH9XK&J!?_M^H]]1Q)<K)HGW(90?
+MF5!N#[75EL(,Q(:5=W36L'5QQ4'FQ*Z;($Y7PKVF@=>+7`'_7A.80AN-7MI,
+M8%[-L!.GZ@/KU47[?#PK2`N/=#"M,Z7O4>KSH<]II:9L5H?IHL:#&*3>X.18
+MEX63Z5A[<0#$\Z!4M7JP2Q]+.M:D6/1R>9""P%'?V*6_LTR`M5T6%BCMFP#G
+M4)*.?=[?+6.?%'.X]H+(UYYO0?P&*^*ET?\D<(TQ2'\[Z1C$WM:9B8[$>6*5
+M.1(W1[-LNO:B1/WZ08)^C=YHUZT%3.E'\Q+L('J^Q@;-L(T8)V_=8TBF#7O8
+M_$-'3*"('0X(S*"SR(NS*)#%:!_"TDY&]*7T5Y2G\H#9";3S_[)';[XSC2T]
+M2^#@60&Z,,;35\R/`1T*KYNONQWM\?]&J,^L-L<1R*A67W\=+T(IU?,@[6.Y
+M6_'Q%?YJI7*>ML\>]\QE<4X];X%Q*81\$V<,EG!<8(I2#?$'\VJ<\CL8^BU7
+MY,\)NL&'=SMK!VYGS#,B[4)*-J7R)FCKA/T>D)G_"-JJXN6J>+-QISPT6'=N
+MI5KPNGF37F9.)GKE7'0O325KY6K,9.G2%CO5^UX=T>0(X;20%KA6J8KG`<28
+M/$)>DPI2<)ICA:L4/FJYDFI:1Q/C:BU1.7"6]5$G1!'LC^8U6U[>_0J&F($;
+MZHN=G!C/%=U"Z/MPK<<7SX-H@*Q+MCM!_WX:SV;7>QW!V<KJ7X&/YQI'8&JS
+M-U-T*45SY93H^&8(/C87@H\=;[BP3DN>G_CBT]CA^FL<*Z;49]8K$H!2''+Q
+M7/I5=IMYV2"WJBO/SRN%^:&V@-#L];N"J>21`D+UI)$;F91KF`DW194R4F&.
+M['?)97.4,E[QY\A^7B[+4<B_?J<>@[/!!3?RQB[KTLM:[K_$D6\P:J+[D6E*
+MR;R%6K52Z-&ZX.H=B]GG;49>RE1*9LLE?'02L2]*9F"P1C/68HE'AGB2TV3X
+MXFZX!`(JXJEN_4Z&)?[O5]@FPB3\/F\;,HVV)$>]FWR-E.2@LZ5D#OV8[;#?
+M[3#`;/@*$]DJ?L*\O%\I]K#$=Z/.>J[Z"B^_JK>]!AP')]8?=N4]S!.32(PK
+M17/RBL!5YNT4GGB>NN<APJ7<+[7=ZU>[7AZ!P[4T(E\FC:B92FA,+.2KY>&A
+MPXHXD"K&\&3_'"Y6Z:]6W_L+LB``[T?"NO)*>#\&H>,UL1_N]5<-I%;AO;42
+MGB-$COLKU1=H+3A+OIS,8%(X1[U]ZPA>B!!=\BTY"@:_3/7%Y9(YT7]ISB-?
+M?#&"Q15R;*C;+P.XU)(Y?C(G4DMR_&KL)9@EL=3JG-QA@@*!FU?$^PD*T7.:
+MX49>[30%42`%+%A<])<1C'$@QE(?SI$?GJU4N/(J>,04V'2\/)C+6'2(!0T<
+M%<OT_&%];%V!K&JU[37C4N<-2HF3<,L2E[#)$;V-S!TJG\CXMU(Y1%^/$[8Z
+MHG.EVGP'O,L?8?']`M,H*TZ7!W4YN68SJS>/,.P,K2LIKSUQRH9/OHG/C19\
+MM!)G]';$9[HI?^GK#((/O/Y6LX[3KTZ/C9/#BE..#2=K_N.8@P4;QEB7$R#6
+MI4M;,D.]FS0MU\Y0?&ZY9"9>TTR3+AF).IOKLS@C2Z2M?W^..?28F>(E@VDI
+M8C9M^UX,F@ESV`W!K>?YPR7?(]S92_"SX,2BFR;$Y_XA0T\G++V26^)DA++$
+MW#+CTUKUPW2H'X2X8T1%D"40[)W);*\+%,*TO,6>T&#M;5XQ_@A1"G%IQ%,[
+MO;H&Q;A'??;/.!4@_AF1XIYH+E$MSH+!Z(68[](3KM:(F@CM6S%^57H35UJD
+ME<>6?XE7@#RY!!3A[<!T85.ZOQ1F_%\0%E[W'*>5QZ/UA+)DZNAZP'['\IXA
+M4YZXJ4BYUI)+T][';T-A["!L,0Y:]&!BOZAVJE'_ZT_6?CD3^N6T](MK2B\J
+M-?OEU/N%6GO/*T:4EE7VWA`<X6)>`J^%!W5>H^-YA\$8Z05MZ#L@^C<-#?")
+M]5DI)K/0.\B7G%Y(B.+F8OZ::O5W&T$\3Z-RV4,_J-^\Q$4_:*SG$AX3/=CO
+MA5KD_Y?4,K@9#!P$KQ!J5U<J%3<9)DZ";HV0*O=#\&+U>D)&N+3E#.T+G+.0
+M"S\&3_V5F)^*H(<+$^M=7EV/$H,%-GW^]!6$U)]!0^K/I!_\Z!0J[&)NI)#V
+MDD;8CQ3.I1]4017.IA]43Q7FLYN\90Z';2S,?J=\:<S5P/DPY\^!.?_@%B`J
+M1<6(D4P%;E8SPPIE[A<H9":"GO1N,?0D*5RMOFI.:^RO&;0W$8?:`<H.53S*
+M-_Z1"5?#94?M%C*[.Z)$P\^K)$PRAT[Z5.F2SVSC8>%_!H<"X4E]*B"B?+-N
+M0XP&HH_%`M+\@N(%LK\,B`1PX=ZRZ`Y[LKR[EDP*.[-NKK\F4TS+[2J+9C9[
+M=RWM)Y4XHDY'Y61_Z0MDI072HV4.II^CTT#.%'ORBMU^;;%;V%Q<5N97_^VE
+M$0L_6.;'@U]@B#MJK.6'!B&,]6A;"&6(.&X;LM62N:%!\9"9LCB1-M,!*1/@
+M^537I8`,M4*D<#Y*GB/AG9,V&'`&':2[&T!`1C2E$,,B\Q3(L63VT6H"0KV5
+M2$!U6.]\@FQX^*2#78*1ESI11:95JQ,VC&BH"L<KU<Z\:E<T`^@)7WFY!BP!
+M.5VNS;?W'<6F4^K(!\L9XH5Z4PAO..04Z!>QG8GA_'?+/64X7%%)S%\7&+HL
+M3['TJ-/![$WR3"EV#A8B#F7.O#(7WDDDS_`7+^\@M7,[H+*]/[_]7)=UWJ7.
+M`(W=';U<JG,Y5DS$+I'NO0?KAVH^ZD:;5B1/7GP9GKA2:UQRM1/LFH'1>3I+
+M/T?=("W+APBP=*Y+R\AT3/.K_$NV>_C4BX'Q6_A'4K6;G=(I+4#ZZQ2VIGAW
+M!%*:,H5-[<;=-ZM..=JOQQXC587'_@IM/$K:F#983##-J%137J;6!;42Q<ON
+MKX>SL7->&&'V2"GHB^(<I3AG'+R1B^?(Q;,KU3>(61==U*S'/.,7WZLL=\$R
+MZU$^S-\`8>Y5]0]@Y\:L=F[T'J`Y64.-$`N7*F>^6M6>UPU58DRJ?]D`!F,,
+MU10O+W:FEL?EFZ$#I%VH03H?Y+6`6UE,>I_F]?&!<1"GW8SO8=%=B3++:IM8
+MO^MR%7-C6_)D$XE6YB0+''F'\4S85NC6UT8+%+][@;"UG%\@E[F%;1U&WH)"
+MW@Z#A]72#DL;'N,[@>$1-I>3Q13YZ+#H%K*0*^<S2%7&SW@MMLJM/$R>#'5=
+MV']Q%9_1)1?QLD6&03VR.JOBA_9=2%LTYU*ARXZ3"U9S#"?[/(*IE<([FXHG
+M6NJOJN)=_HEF.XF_ZY=-=.B9`W0ZK"J<*/5RECKP.RWAM]/\+6PJG*C7+=A'
+MWKZ0)NJW>FTPTVQU)ADQ]'U\4_$D"RT<^G<J'S+E%,**Z>N=>/\:\]*8-#+E
+M_]_AL*N:\>*($4^>U%_EXP>[9A8;^%G:E(M=.D]Q+,:!GG-]GD%SJ6VN\1W%
+M$!F1'&P;.<XR3IY1Y>:P<BY;N6D6?G*/"9NWU9EAJ3/3XC>8F>>?8:$QD35^
+M3U.F9L%%<=CL'L4EN^W\1=C1;?Q&5@4^O9BC?,H9<Z.*1Q3'<7Z"(N=WVF%P
+M?H^]G7*W[/?(?K=<-FV4KAEW0I?-NB0^\$=8[/"XV'$J/H]<XK+*7AR'[UGZ
+M-`N<&V=%NS.-A?Z.9^]R;#2?/0J^BY6;8RN78QF;.2:^1",(+?9Y!2HC\1GT
+MQ:7WQ:#0A\?UA%<@.LKYR@HP:F]YT:*[C;*;L:RMX$?6.0!MM*L<SFCS=X;E
+M-YZ2=-6[4K!?TLS3EO[1=PTNB*JT\V\-,[73('VM[5]U''UF^6W2<K+P'#=(
+MK)N4]5QCFSA1*9HG;///YW95XB(4[UZ/QG^HC^G3&1C*YL=K[;B#;\QI\CAA
+M\#S"55UV'#;TF<L(6*\)VXKRN8Y*I6@N6[4ER`JI#Y-D"5M]/,;WV/[<2%(_
+MWK_0<NRD8]9ODM'_JCX6SP&#:$\0-A&8%6HQZ4;4K51XB`!J2L$AUXH\R=H8
+M4DU5[UI*5/M*HH")K4NU(L1_,VQ52_XKU;2Y74O'5ZL=H(R)B9W!;.^TYH1U
+MN5GW9[:Z6=7JSYXW/"'G:R5.$^B##*B+`1V7`--`>TDJP=,R#ZX>ZFI7+]#+
+MT#0.CU[M6)&J%%]MRG:P90CLXIQH&MITO-R.C\8IQ7.BD%'%VVY.%_M<]+,Z
+M1%N^1>62XH<Z?I?WK<!D?)*.4Y/8G$Q.HX0^*[E`Y1<$K,$4;&GRH)F#32YS
+M?GW^M='K@(F?Z,<L(6J$GE<IM%/,P"Q)Z:2\D2<IDUA/7Y\CR0A#8I>M?_S8
+M6./35DIF2+4L>].2:>J[=*C-[$W7O`#+Q61QIG[T,765WO_'Y'/C!O9^V2^3
+MO[^`O=_Q?/+WVD?T???OD[]__R/J@RF;AQ.ZPLUU^<DD8Q-ZE"UHU/L#@]ME
+MAYNT[$\_LL[OZW^5;'[7V,H<_F7R]5/!1_KZ22EUY942V[EVO+>_-D7NYTJ=
+MN9UDW995HY[W>\-A<X@8(+F&5\1BRYK]/P;M8J-?_L&4B98V6X]9_#E$TGZ?
+M.UEI]>J,*VB++FP^>Y].[3I`SYWHST%VTS7U-W\'[@;>YN)QV5T\B;P_Y9A#
+M#PJ,/AX(R,575A.$"[FW*A2_Z>FQ]__#47IMPO,F'4S]1\N90Y3^>^OZWBCW
+MY(>,GY])SF\/L?=-=EU@]N.6#RFYI;4TSPWFY]I%:`9=3^;;/>]#@R=HG=)Y
+M->KRI^D,I(F?TFK4+<^9,S#)VL>`MO=H,IO@FN>2\>SOCT)\`*;</GDJ*3WJ
+MCK+^_B(Y/7YT%(=M@;0\P9]2`0DC<KO\E<+F(O"G3/WUB-V_-LJG8\`<3V"J
+MD6>3XO/9!^3=]YY)^FX_O-OV+%S\'.=@Z<PL..MS1_],I.%H_]MC'SA8WLEJ
+M]0]/6X8PT2?T@P_T,:Q1?]*2,'2G?V<.G8W^%W]@S-V=OT["LZD?4-K_ZMGD
+MM/^PURIS2I*.\;9>"J/,SL]HWX&%ES+7;O/!LU3;LX)]X$P,C%<<4B\OQ?@`
+M5PR&50(N-:0=]<K_DW1<OD/>6=K&/$YH%,R3?7'Y(*%:_%40)E^L4\AO\I0H
+MK0%31ECH_/G[J"#M=:3G4$_2:K8[.O_M=N2D[:Q-W@ZNAW@E1>;`CU'DA,2*
+M12[+^NGKWN,Z<Y6C*<6D:[)G&*]1CB!*Z8B2-2;CV._T]:S1N_]\#^>L5ZG_
+M0M/$#'E'WRJ,:Q3:&;A66?T"N!"E%[&O+F7U>OSY"OYT*JNWX,_7]9]MQL_H
+M-<UZ7:>]KL->UV6OJ_^4`!D946(A-0T[T6]9TY$U"N-.Y@^;:1FV?4<<MAR^
+M=Y@Y?)=UEO[$V5GZD)ZU-U(ZGW[<RW+X/@`Y?.^G.7P7T1R^`3V'[UDEXTRW
+MYN*$_+VQ4?E[(Z5.'>1V:UK@[6=(=D[`]B+8[0SL<XE@54SDZZI6YX((IVF!
+MD]BD_U"^[0-V7ZW49O$O%;K,0;#)FMMZ4)[1\GYUG46FV<?IFSWV<?J^.4Z!
+MSM*%9)S^/2'),ALN,D[WPSC=2\?I`3I.BW2BGE4"VG1K_ED@:'S4.`&L'=8!
+MVG$V`[2#P7LA^0`YJ]75:XP!^A_D;4XZ/M9UE7.,\=EPV!P?IU\=]VQ2>S%\
+M6!\<85M)EK]&O?0_2#EI-S5-I.TN>:D?=A1JU$:B4\Q-C42=Z#MLKC%V4UL(
+M<G*6N/W:$G>U.O1+]`L3@_+9U7;]:-G_.NQ@<1B)]2G%./%;2K%?*W,NGZ`M
+M]JL?/0D;>W#6IMBON(5-$S6'-$SMV7.:FZ;0C3V,`;W8[X<CD8U/V_:R[;[T
+MIPY17;\$$F=!H#1>=?X2#QS5WN18,1T\7I#Q$DX<E<?A)%%)(=$BV24W`04,
+MG[3I_S]$UR7E'B)5SY=.<8%L#'8FG4H)9,N[\-PNAD$#?\<^O)RVR*].)`SR
+MB]%Y+H>[==S414^#9>VW''%)6//OZ=;/YQBD?OP72.I0FY@]F.8B1C"!,_OG
+M(QK1ZNR\#L:[L^[;60@3[-;YH;I&_>UJ?7]<S-BBY_B$!(GCM:5^=7_S",`:
+M<Q_WBFYC/,O=$/F3L.D+G"B0`:J``5I-&"J:T5Q17:G&6FQC9=I_!U%WT2N[
+MX$4Z7[KP-!EO\E6<1!8/P)EDS>!'=]+M-K^._8S/\P<=EOS-.ZSYFW><3:+D
+M'6/FPF:)DJN5$3TW^%G)I32;7$H#N90(^6N2+N<\G;!LEYX9T<Z4\_YW[UAI
+ML-U*@^UG@^GV,7-8`PV("JA<9=#@K'1HFDV'IH$._0=I,/.I!!K4/3V:!DGL
+MPLEG91<^_+;5+F1UJ'2SVH74=K&<?WR;TCD-]E$"+LA:'[T)<BQ+RYR$C;5%
+M3O7^,-VI2QLLY+G`A&KUZ34THTFZ/,C.3@>RPV1)E^9'89&O?AQ.6%-:XI\>
+M&-W>C?;V8H\GM/>-T>U!8VQ]D:\NM37'\FZ;3=9@DQX6TQ-"))HKDS@!311]
+MVJJJN*MZ(A)IU/IAZ@&HY5Z(\=6A4F3-B"6VNCWWZ_']()+<J\H]3406E[LB
+M1:@Z0UH=KW#0V[XC>!>7&-X<DB`#'[[`8NIFP]9QX!PE12ESY94YY1U$,HZ'
+M$Z8?*OIVJ<(I^0LULCB.^\.EFA]7@"W_@8?=B`4/]T.H^Y,\'ODY)5QFLW'B
+MB2@-8EC/1/F.>Z].ASCNM536/.?R3\2XW<(F7]P;(8@@G@3#:O6WA,IX7HH>
+M',`-6+**[W2Z6&DQC:5!@+BL_6.<M]VU#T4VI0\S.L&Y4S=!24=*/$7S0*9;
+M^&,%^3UU+,+L6D4)DVY0A2CD,DJ6VI^SG6`/*9UONH6KFY/ZFD%U9"(:J7"W
+M'+(FW^I42O5>FMH4=4?#";<]+^-G;R%KKZIR-[7$(8<(0:?#?S]L/(1##KBO
+M4:V>("W+H=AI>I&'(B14JU7--/-<)#H>SJ-"`B'P8Y?S2H8<'L`L#C%,I\)S
+MF1(D8A*VAJ`),D1%6HJ_LEJ]36$I@0DW_UAI@3K<2=JLMA'J^BM5H8EP20A>
+MI2(*\JDF/C_Z'5P!%OK5^N81(W+J)=`VU^G,=\C]J5P>%@^WF-`J_6K[2IQU
+MZXZ=-L^!V\?ZO2Y*D')W4WF,S?@T'-'[E2ECC>=P$Y*"S58E3;F:#&K,3R.;
+M/K@*^)R7N8)]1`BD0G;K:N=@NCOP#04`<U(M8>=S%=K()+A_1%U\I`Y*773R
+M6<Y-VW7.95UT%C#;?[E3]C)!7C2SLVB*L[-HJH/-YT@1/5I5Q%.+N,A#+.(B
+M-UK$1=/0(B["\T]*MJ%CJ;U^)CW+A8/]\C)=SW*@9_?F1N281<?(.ZQG50W4
+M']E+S9<4)#+8F5.:E124J2Z0J<^M9,?)DOA`KM+K#A9.F!](JU0CJ\8X7S1A
+M+Q/>BDO82KB&[A@)PJ8.?X6:_3,B'\!V;.I2EGN:TK4BCVSU#UO@_->>,\#9
+M&3IK.,$SP6GX&CAF__=8?56[GDCFJYID*_-\TC*?O6DM\UC2,F^\:?%K_D9*
+MZI/Z@[7,3Y.7D=XT_'-]*Y/XY^XQW^],]OY&:&.;[E]5DK9Q`939S,KL3U[F
+MJ]V0/47O3_(R!TF90WJX9XQQWF@M)YW@C:(O[G9@M!KP#WL@$#0N:=Y]<$"/
+M2UR)#0TB4?H3:/L0K0PG`+N2^[]W.UA*$.W;6I=A,9C^Q23G[:?OMLL$ERD3
+M<CJ+IA.9<&Z","!B@,F$:2`3/%0FS*`R8:8N$SQ6F>`Y&YG@83(A-DHF,)ED
+MB@8[_6O>0'[R6,R>+W^6A"<N?\/@F<F-2=X+H^&$D_'6)[L,.&]*2=Y'=HV"
+M<U\R?'XSNMQYR=I;NLLZ[X97)IMWM]G*O).TS.6V,B^O3+Y/EK'+6)A8;%@B
+M<(N8#7M!"$Z8._1]?V\L.$%)`QD\\S%ZMDT3LYEMFU&M?D\F4HK8'S3I1_+]
+MIZ=VCK*927NY5IMY>X/59B9POVBRPM7YW)S_.ZD/P%W_*-J@-R/(G&;%C7IY
+MBDTOXQ6G?VVP:A#+V2T3ST]W6/'D`4^Z$*]H'EO?9^J8*VYV@F!\I>HCQ-?/
+M2=(S!'('.%#2J)J7K7<1K&?G;';_CR@ZJWQ\)S$FE"G05=$C;&WS:U>HMZU"
+M$U!TDG=</9Q(3U>FK(>S9TQ),%E@@2=0>`@,NTAX)5]=]=C7`C+6=B:LOT7.
+M@-MF^6QPL\HL\_Y7Q)A[1;5)YLKWS/<7)GN?9[XOJ$OR?KSY/MORWK+^Z1Q+
+MQIKSOS.IG$Y8_W=:U_\>Z_K_?W>5_NC/$E;IAU::J_31-N/P?UGQS+'B^;_K
+M4=D72L"S8!2>^18\*__+HL>^%R[B89^'4XI<RFH$[I\!7E]P]T8<HZ\0G,'E
+M:U%F_RQ%IE2XDCBFDCFXBUSA8*]A,<L[\HI<4AMO<6\#=O.MJG8^@]:%T`X@
+MM&Z$U@,8=B&P^0S#@40,NT'';C=U++IJ^)PG>;=<S.MGO/1GA4F>S32?V?GH
+MY;_1\0FZT7]8$G[8)1?\,RT-`/OUMH;8+R^R#=&>W$ZYW[K_P!'FSL`=`CSS
+MH^\17*V('GG161PM&F6L).C7/W:@@P!D?ZG36^I:RM>HWVXP_!BEJ`]*G62A
+M.J(%OF'FKWZY=LS\U>+&Q+,=EO:\'<GT>?0.L@X?4V=5/YI$9_V\/E%GX5VS
+MIG2R!D5ONAO>@?Y*9:M2$ZL$&JQKIWYMZ@1A9_]O']L'TKG<\(&83HZ'ZY*=
+M?=/U:+JN1Y.MJV:UTTMOAOO*YJL*?IVOZJKE5E^5!#>TSZVI5M?^5'=21:_3
+M_4JIT2N:;UUV&<-Z`K&'ZN@PZGX0\%E!+_90WY+7YQ;WHH,I&=X/MK&Q=-O&
+MLOA,8[EJ&1O+&NI,/"Z.:#)!)Q:82`<KFFGZ$<8^(W1RF[$4A5T5>G+T^^CJ
+MOT/K(HW!FIQO1I!.ZRG$A'V(_\O@3%G(Z=?EB47P=@.U",;3P9M"[#6G5;>:
+M]1?2^K!+9!RS4:80$/OJSP`B@?]F;8.3Z.1_QT(ZTJ3^?]2#=T@^"#LJ6>!#
+MS,`W%(P\/.;\.K0UZ?RZU^[S=2Y-\/E>63O*YUM@GV\7!I/,-S&3#9I3'FQ*
+MMZWW[;D2B[>B5T@NQSTSY%2_BTDON6J`,CP-_HMO351_L,3D;L3VW`HU%*38
+M3M;YFF/G%ACN0N/C.B#E:E.NW;5B#+FVQ91KAY>/+=?2I.``)PKRY\+6=G^-
+M6D?F3G1RL_QYTPZE/`9)F,MC6OE`]`GP9<:]Y3$Z9NC/)04Z:78JEGB1K<7]
+M%AJ=WXHQ`<'0O+J^#N?_K63^KTVA_J)KI#JDR5*GZA,-FF0,%O$0N(18B`^M
+MH%$1G%$:O2^D"8WWI-"%AT.!^Z817RS3C+5:J9ZWG-60(!9)'N1+2$,/L0;9
+M0;1+Q4F1-$QT(\;5SY=9RT+((;WY12R&M98OA"!L&@1%+70J57'@G`F5ZB=4
+M?,N=48'01?DN(7T!*:,5.B&ND"9.5ZIXFA$Q4HS3'D>Q[_]";#$-\DEKWQ>O
+M)ZACL@T$`/DSRPALOZI88%?%X:;4IBM(&2*Z$+;06$V@1&ODF+`U)@=[:Z`G
+M$<(]!!SPWK9\FF4S^BUZ#W>B<C,O?;!(.E4H\JS%Z'2,VPLD]//2T472\$PQ
+MG54W_)RZW/;%?D'L)+FJ'\Y*0O,%('F6=DDC&4O39;$'\NV%:[9)P^.6NL(U
+M.^6JGNCD<,UO(KZ>3R#&(7F<%K[UCW)Y#X'D]?6LN$`>%K8.ZXAG`=L'!QR!
+M0-^A$8P_C;E$(2/?T(4@+,AWX:4B)Q>!1'(O97/D00]!J%>N.B:?3*WJE;/E
+MX4GD>X4SD8XW+A^;CGU78.P[I`$!AO(DB]%+KNHE(BD5]HR?L_*U=>Z7O*:+
+MI'#50&6X*E99K4*"9R)CIF)W,H?NC$E5<<?0G7&:B6XJ2!)U+'B#KXZ&]]+_
+M`-[S2>#]B,*;G`@/\K%9H(V"]<,DL";]-V%E)8$5^>J_!ZMCRVA8/_UOPEJ2
+M!-;E%-:Y26`1-B+@;G6><0PN2@+SW>'_&<P]FT?#7$EA7I0(,W^?%(RAA"?+
+M_Y27N28+`1)MCR6;OW9/];F'$O3K_B6C]U2)`126W$_A1M6D)8EG2LWVTKZ^
+MO;F)[=WS->W]7AR[O:<V?6U[VW^2T-X7XACM>6A[5XIG.#,[:Q,+^L`V5(30
+MLRP`4(K99`5KDNZ<D%:G5JI!UFHVK4KL@.C"9KW]^?C0,-&);K\K,'I_MAVN
+MV+8II1YOZ;2E;F$3*/9-#^!9A:B[6:GQ-.W0K^.4>L#B6:^WE6*WB^W[TI4;
+MV>8DWT3$*75?S;=2\+$']36-2]@:C+.]E$E$WN-NRI4,A4GRH#S<U*54>,Q+
+M08`%]<SA`,`F4K7ZV")*X'X3GQ76^?^*@^4Q#E>-D(5U6)E*!D8N/Q#Q=='P
+MZ[OUR-Z&#IPIEFGEW9">JOYH>GU'OE+>W90MO#B2VOY9*EG=?TA6IN]CA?I'
+M>8<0/DGJUWOSA<8^\N6[<GEW)Y>/N^^8>Y&8"DH13Y9#H$$+A1#8:X/;4P(9
+M86D:P22:T1R6\I["//2DS<^E#X15'DYOT=G^F1/NNY,6/["T"!>5I3:W[(->
+M@`$1?1CCM'=#8#*R`OH)$I&\?T6NVK*J_!4("5K5W93)7N]EKXGB#&E+=Q"S
+M&MI^-1,3T@]]+K^C]YDL)SZ&B"JU$['QP>()S@`Q`79CB/6^O/)NJ7U$+M_!
+MB.>2R]>SZS@*X1;?CE3?;HR#RA6F^KH*-&]_'5&JN1%:_`JD=I9<OGU5I;NI
+MJBVDU<Z$DV'G2J=<@2DUPM9]1&I5(>_SWICP^'H6XWD%$56['8&KUN<A[)3U
+MEPI;VY1JC[=ZVM)L85,7J?79CRD/0?[V6SQ-'824FSJT$D^H;<6#4K`+W,X0
+M)ZQ+$P]4*Y5SM7UX,BQ0(06WN\2I!)%)I/FJ-@+I[0=9^ROF8I4=FMAM5/'Z
+M=HCGD3HIXL6DS@5ZG=_J=>C$)I9"$RQ>F-%(F-8%-NL;I%1XW3+-W-.V[G^^
+MS!9GZ*Z]B2TJ<1EYXT*</M1#CO'L)\(*?NI@,3]?3!\ZA$L^O[Q'3Z^&^VYQ
+M".8UQEKVMW^QMC7;VM9!I*-S(4P@*[RGSP2OXB]CXK[RQ_\X[GEG:NNC]6/B
+M?NX8N+_[U1G@M:QG'@>&>[8)[XW[+;BC/`EIP:DTQSN@SP^])QUT#+U/^U!3
+MC>N246U9SO_:4+_8BOK\^W74V;JZ6IT%6;?[D]YC^^`EBP]'".UPX`E<0]Q.
+MNE]WV13RLQS3'([K',2X%].W+@"Q\6WRW,_+7>P-F;MB]M;[0$)UI@3.V>J#
+M,A.5]*W_!H\*)Z0$QFTMQ0:4,D]H9]UX\LPMCGLU#0\?"]N*W?Z"-I02X[;D
+MD6=^)5U;Q%>8*][*:O(D'X+75/'^2O62>P"YG%!;D#J*R+]4K->H_[G0>K!V
+M]/F>XW]FZUS:[8/H/#*[/>/?Z`4R<$9FA)7K4>;S^6U$V\9?A2$Z^6=YQU!7
+M>)&6L"97N%5E;CA2!5F7B<PZ6>N4#T(V7;H*3Q'/(7-]<@T>`-+$F+KAQVRV
+MBX40U*%H'AEYTN/"N1AIQ-LOYAI5`PE5EQE5QY$R46/-[(3B0(4*=1TI@AQD
+M.P\$EPLLI'C_3Y8S&>)BJ^TP>8%I.Y`>A>*$C\*MCCBNH3`V$'BCU+ON,0_U
+M7*BT0"FE>%YU3:79C\!;NOIWVLYPI#(,U_5_Q439Z+V+Z_^4Z'-V_C_BK@>Z
+MJ2K-)VG:AA)HT`I5ZQH5%;8*%!3;HS)-2=(6\J])FQ1ED%(HB)4_Y3T*VM#6
+ME+&/US!5<(89B^*,,\N(SL$MZS+*P>IR6ISE(./I'KNS>)9Q.+-AVS-VG)ZV
+M8"5[O^^]EW=?^A(RXK@]D'????=^O^_^>=^[][OW?I^L<_XV=KQ(.N?9J>B<
+MY3TOW[K.658V*][U)6]*NC8=I6M[<E.JNK:K1P1=FRY>UU;W=.JZMM\0(AMU
+M2EW;/4__#;HVRO[A$;$\H.5T9+]OJ4[3>7@+ZA\9<8"F'//&LBXZ(IS%:JI-
+M<';PAB.3Q^#+D^E5%]:*X\GH@HA]?>S8J*"?T\(8`%8[\7%??>*Q_T_?$'%)
+MNFA=[)CWK%CF/?62H:RI,?VZPE8C5=?.-T29S!L*1J7S[ALU%9&JFJN"_T#N
+M2W%L"[N%$IX?2)?IG(31F4AJ^L:LBDA6C3#(F=9)TPI$GJN-.Z=,T?N77RGU
+MUNP\>F0>J9%&YAK>XP@(UMS(^U\T+C:J3J'GE,FN$LG"F-P,FP)>J8G-DJ85
+M,V8^=`X,A/94>R+':N`@!=RFPX#.$_EYS56%33QZ+3'C5PJY\?^TFGC-I:IO
+MLIK(7HC)HN2KB9)H2[Z>R)Y#<O)Z8AR/`RC:,E"TZ;^97#LUN=WK_BG6[EHS
+M8_!$_&M)]YX96@)>4#)0-%14XV%T(AH$!6NO_09]W)X*TQZ8"&A%VQK+C%K<
+M$ZL)K39>A0."E'V;:Y\/E,[Y*<]:G?SEWW6_Y77OM01:_?3B<7^2SJ.55J+[
+M$]&+0'/U)_@6__,OZ'T$_?0^@OY4]A'T)]Q'\!V>\EBR+FY/PL&Z^#T)BO9_
+M_>^ZM^Y;VXY`2`[0W6`@E6XPD(@LU0U$'2'=#][X.=T/!NA^,)!*VPTDW/?R
+M'9YT65P;UP_`M67B/33O_(PN\VJZS*M3X7.UR.?(Y#+[#2EV?KN![OW<<+Y=
+M*?N_R^H;JXFK/G\M57V*/8O/OB:,VY@G$HS;'GM-&*-J_)$%^(U_73CO2(8H
+M_LB2)Q+;?KCC->EL'9RG'%D=RXL'+0,1'<GK#T0>KXF?#U(T/CM$TS@ZB<;)
+M54AC5@TX%``#&('(OZ^*IT?9/SXDVJ^0RK"K4--T+WV<\%&L.>-H1C&;C29B
+M6]I`10GV1/!`R/TU2MNBRKGKO$/">B<<BRD4%8ACO2!_F+3061WW9>CSM-"5
+M-'8Z'I<4_40./CC6BZUIPC,U)!:$QN#MW*AH9L%8\(FX.C>8U8EA$&7<7]H^
+M"F:T_@D,L(_U@E1CTT-7=6Q:RUF]B)G5\EM#JW,<]`)CO2#<6$/HJI8A*71C
+MO<7(5<M9`ZDX.'45^;Q&/$G9M`0]0!;RV:U_^.L7<&ADO/5S(R$RY;?<K+%>
+M`&?,&]/(G`-/RKZ[^BKZEH:QN71&U=@)?6JU3S')5?2[M%?IO;)UJ]3VT_[W
+M*[&]@@\^H;*7\/U7:!IW!M1HO/R*T+^MJ]3M3#PK8_QNA0K&XV)^9H5Z_H?%
+MYP_XU)_?^HJ:S9+%?HI7:O_K0>R?_L@/2%G@A`I+^HQBKZJ\__,@7?8??%^M
+M[*\>G&0_YOL^M?W/"EIO>%7W/Q^,U=/-`14:BPX*]=!1J5X/-RHP[(^IGG_H
+MHM.LH=LS-)1#O6>]7;@!M(#,D<WLE/`^!^C;[^H,C2]@IX;WK82[FPC^R6Q!
+M5]]NG3?LVGDY7#7,50V1]S-T-7O7/:+][1+'1@(X)"A$M."!(31N8O\AU#M,
+M4C5_MGM44)&7@/HGE@KDRP45^3*O"]NOSUZ,S@WM5KBT3C?.UA#IZ?7`Z>;"
+M>%OA]!K+GU\6;2(7:H*B?7U85:`%5-=*.)$VX8_XH"4I"<7UP>L(8GK*XPD,
+M%*F:-0J=FDWZ&WD[^C*,L]_Z2N10601NG'3%-'`G*Z[&Q,VQ%\M\*\7IGQ]/
+M*$[]D:UNI2RE];\_%>2^TU30$VH&4?HQ>;!GAJ7E2@.3TYS5<J6&N7_P>Z0-
+M6ZXT,MF##Q*Y>!(EY,/2V?/C&C*H.XFB]-Y8G$$'<:3X>+8KLMD/]G1FPO)(
+MS^"6SI:B?&9J2]$:=D;+3FT^.Q6E=.N?0'YN>(?DG_(A"LK?K)0$Y4<@)6>U
+M?@Y2<LJ7(!PA+?DL!QPQ^8CN0T3YF$[D([,_$"EUQ7^C!)MKH1VDX6_F/(4A
+M\U];#,5]Q4(C%%L%0SZ2?6AY_/L3T8:/"3].1SUX[GTV^J,0?4](OBGRP*PD
+M_!JX8=C;%'<F7MD/ZWXBJ1-`;U;0<^DX[D4:M6M-S`W*KH'[3/R&(K^)R0=S
+MS%K>;\KW&]">0(77SWN:H/2F6.GK.7LQY[?R?M1#^'DO$_V$]&=2GW6A764:
+MYB:(SOY7?]DR;Z2'R)*ZXCK.7L;[\SB_$7_U^&O`WQS.;QK+T)%F8C))Q&`Z
+M\&+F_+D%/47!"48RUC=,CY4-<C&;#PCN$#+T[';*_\&EE^&U`!\"4_R1IA7"
+M4$I`28^\29K.'QFM!BO)#MYESG?E542WYY&"U$>)P&XVLNDMTTV#Y,=<T".P
+M#3R[\K0?<"Z!:Q-AD/`NVQ:>!WMK=A63>7QHES7*W,Q]F,`<`^_79[^CPP)-
+M?F?>_G',IFB&(7MWGV"RS,"N"NTR:=A;_9&W@>E)W4%R[D`$J1"-_DOT4N\Q
+MDYY$QK88;Q1K(0/]F^2V3H=U!=`NWD"_\U>(W!Y<@7;#S>Q-L>@_!O"M`=W;
+M?,A_I=T4M>>`&>^I:`_\SE`TB[V-)O1V0%""BG8<,CIQ*3G>#A(]_OKUCX0J
+M@$5#T[9;R!6]_9B\T48R,JP)2*8B')#(I<]W&9CEI!DW:G%IBAWG@A-1EOP#
+M4-X;UW.GH6\@/1<P#,[D1B.+R&<R5'@;([;A3+0/'2?ZX263QSZM0["\2[$;
+M?0E6/G,U[$VB=]L^FR"U!?^[,+.MR"FJ,#5DC%JT!N9&U*_Z1?O6V;MM.MG;
+MQ3_Z(Y_`F$)Z*S"0._FUP:63'"V3D[WWA\*ZJXZQ7FJ3?*^3`D[RCD1B0\W%
+M,+AKMD:SV[IU`F=;B[6LD=]JG<&:!HO)>X>.D\+.0Q4!_D78JPB59P`VGR,9
+MZOBJPW6MGVN&ZUJO:%JR=V]"UL\!!;:?4!`=_\9!O2D=,3=JLMO`3QJI!FWV
+M[I<TTJR?"*C\K<6W[K1R;#L7[`!%'6L`T^P"_UJV?4:P(Q3LT#2ME<HF/>/8
+M%B[8Q@?;BH(=S7;>V5;D[""-SK84L>V-BS%U'A<PXD>H/<V=!P>Y`P:P^0[Q
+M.5S`A(%<X;#A)?BP=`JR)'MW)VPE])NQ[^5QOQO[3^ZLB(E<!MOO"AJY8"?O
+M[+C+:>*<^WFVDV-)[OT<NU\L%=MY:W"_D%Z-89/(\)T"P]MOX06*01,7W-]G
+M:Q=Z44>L%SDVDH'5_BC;68'=FK,=X*JZH','NS1!DVPL[E(Q^K4-MFM(&Y!Z
+M8_7DP[@!7RD0=E`B-Y%WC7D!E'=<+\4:&$)7<C=?Y.Y>4F2.S,U)68+P/C'3
+MQ(Q"!Q,[_^!*]5HGX<8\;2_7&%_U"G1(9FM)(P4K)<*R[49;%U=J#=W[A=`^
+M@T_!NV->)GCTJ7#$K"4JZB-X`$1PL"M*)!QYK^[Y`ODXP+F+>6<7Y[:*S,&O
+M'G\G=X8#?%57^!>,M/H_Z?SSBVC<@;QK\)E#,_*%D9N]XB(=K-9D17[O!,&B
+M9SZ+WRLNGW]Z`=<%*8=H0.:34M7YSPNX719M\!1&ICO5TC2*:4B"MRIINU:T
+M;/6^(&QI8DUD3'R_Z*"F,-+EC8EUP]Q>;=_@'XALG"46X3_`D]@4\UPR)0:?
+M!E9-TVUQMH9(:Y#OFP6_;Q8K;S-1]H:48_Y/.@5\FXD,%\2I,Q'EL\CH!'Q0
+M<:?GCH>W:,D#K;#^+?G6X75W:[)@#9S\L+?S#682!P[8H.ZTEXLN;Y_:6=Y2
+ME,6<++K<.`IJ1,IAS?:;2#FA8G(B.:6BPYK!O$[1]XZ=#,2'R"@PYGMG"'W4
+M:!O`]PXI4)IMG%FW,8KSO=*8ZQT?6G0UYY?EA2XW;R?EF<"M.54C@YGB+F:"
+MG<^.^`.0\2U/K'IOX6TCI.BP#\T3UB_!<\Q[[5>C<VT3DNN;"Y1^;"UM_^F'
+MPG`Z=!Z6:PHUC)Z'03@96#?-XDL=X:I#W@#?TB$.S<$EJ;'/UH7*B3M(WZOC
+M;8?K[B;"^U&-6;*4S]FZ>/;"[E$V_22L-OLCW?:8*QII7+,`?2:&]3,]WD!D
+MFPOW)H'$86Z(-A9&?F;'T6I&:S88N!#/F792-F;D\]]["6/=%\#AS=,N4`%!
+M,81UH4GST"-[Z3GDKY>I]??G%6GVE*FEJ=T[:>X\HU1EWOOP7F'>N[8BP?Q_
+M;VS>O+5,)?]784%$$S&U[R)HI6;P&LZBYTZKG(/_6$Q;9>1#F%8[^J$6=A,T
+MNN/LC\;.L\K^3\+"7@(AHXZC;`A/XGG])!Q>![8=0Q&\4>5M$56.B%`.L3R'
+MD<5^EWK]?-61%(LG$Y.$F.]3>8?$Y%(V1?T$7.KV7Z^%/9P8>RF5=S@9]G\Y
+M5;'3KH4]DAB[CY?SCB3#?D(=^WG^&MCCB;&74WG'DV'_T:&*/341]D1BS$_W
+MR'UK0J5O[7"H]ZU7]RCZO(BAZ/NR_9,]2?GB0V!V-P%_#U%YA61R-D6=?+Q<
+MM4[&N&M@ZQ-COT?EU2?#]JEC/\M=HR\8$F-_C\IK2$_2%SY=IK37H8^1F&A'
+M$N%]];"1JVI"R@@'.F*TC#$6QB>U\7OM,@_&9#SXEJF7'_+O,Z6#N=:<=*&;
+MY(K7/.&ZSYSTZ>RD3^<D?7I?TJ<+DCY](.G3PJ1/'TGZM#CI4VNRI[*^=B4U
+M_ICY/%0R9`SSC;AC[_5P]]&Q:#3\WC'XY8^/0>1$F#^!@?$8/8F^\W5NF5Y"
+MY1H,W#-&.#&QS`0VMI;EB!X!!-;#_&X)XSQB7$2,(20]$N9',#"<&L8(8@P+
+M&+A'%"LOS/](PL@=!PPS_/)SQB%R*,POP$`D-8PAQ(C0&(6(\4L)HQ(Q5B+&
+M6B1],<S78^!":A@7$>,"C?$`8G1+&)V(<0`Q#B'I\V'^,`8&4L,XCQ@#-,8"
+MQ.B5,,X@1C]BG$?2_6'^(@;.I8;1CQCG:(S[$./W$H;A,F"8X)?/O0R19\*\
+M&0.G4\,X@QBG:8PYB#$H85@1PX$8E4CZ5)A?B8&>U#!.(48/C3$;,;Z6,%H0
+MHQTQ.I'TB3!_``/'4\,X@1C':0PS8F3_6,0X@1BG$.,,DCX6YOLQ<#0UC&.(
+M<93&,"'&W1+&.&)HK@"&X0I$OAGF31@XG!K&FXAQ6,8(KSN@M'GI%[TX3H<Y
+MI8[+@%5UNYZ;#B[&)G\SGG\N]LV0#9=37YD)V1;,WT1WOBI=PW73_;15C:[^
+MNNDVJ]+57#?=>U7I*@9XWXCNQRUJ=,>OFVZC*MV1ZZ9[NRK=X>NFV]>L1G?H
+MNNEN5J4;4:$;\*-JS,C/@C&;EM^JYS*Y1CTW"U>U)NTGG-D<\[.:!62GP^J#
+M,(2?J;2[&N_'(OXJKW_ODL=]*$.D<=Y3Q:KCO'V[Q+F`('!4YP";=PE'RPWJ
+MOG9D^]=2.L$M3RXFS8--TMG[>U32STJ<_B6U]/\3E.<[R"Z9[Y3A5=8,J-0-
+M;?\C&/.[DI']OL>`;G&,:$8"O5Z5ZJ5U"_`G*+OYC%O77144VLUI+#J+^SKN
+MZ]P]RAJR3VH'[P1?R1]!.`/7/L@U^^0,BWWN.3:SPA^I>D2YMBO/_U3*ECNY
+M;''^"&/Z#*J,'S0)"D$XGF+0CGOX$B,N+'.]>/8H+K:HEUW.-^JE#"9\E"-D
+M^*#H+/,0*5@F%.P.\!61L%S!AU%I)=H'%]=1U7Q'W=4DES-7+*=07F'.>NI1
+MQ9R5*M>E9Z6U;Y[-$?MKIOB!S"3]'93/P@<RDW,;N$8C7Y4+&N@J4$7S56;0
+MC"O6EH_KY+J4[3\^.[D='"KMD";G5>EGCTJ\&OD96.&GZ690:8,\L(8+*K7H
+M5CUYFIM6JB>/\5U0VFM7[8]GGXG)$5([0M5D\"$/7CF_GG,98N)$]'FE3\I_
+M\!GU]P0/">C9.\#2AEW/WLR7&GA3=+M!8-D08_G:_>#69^+EE-B4PA2WDO[8
+M`K_I*FWUZ<ZD-*KC:63(-.2BOKA3M>Y6)JF[3)D.56?E.Y/462;[(+9P=+NR
+M>5&K_`WJ4;D&<7:'>#8,!:DG%ZWCQ*B3SIQS*80K7VCZMR`JG-,MVIF[JQY,
+M1#-3B$0//7)<PU:C]6DC><'2'CC.6TP0R>CXQ;@Z9.#U[^(I,;^@)"93S.SW
+M+>8T_;M$;,^.GH.U&M/N4>9&/%J?5<1.,`;<\\:Q$Z5H*T5V0Q_7WZ;M4)%9
+MY$V!PSG*]\=`7I9:$%CDT4[]I)HFQ9T6VJ6?P6:20@\^`F?95?KO3))$"V7(
+M"9!*CQQ:"!X9N5&X]T=>A#O=I/JF]X&L:I1-[P2PPK^D*WPJ;S-=>DM8.T8K
+MA)G(PQ6*!QUSGTJLEIFI$IO&EJB40L<L4(G5,K>HQ*8Q,8N'+$%`9Q?@9<V,
+M.*3IA/(.J[RGV[;+[UB.XAV+&U],+50=7RR"_/M6)]6<K,6G!C$V(BHE1>7D
+MO@U)\]8G?;HEZ5,FZ=,=29\V)7W:DO1IV[4T1=+\C;89]+\,5&0;SB%+R!PR
+MW+T?SLBR1\/O'8!#CMU=>#L>[CZ$@9'X.20U@>39H^(<DAWG&LCW=(1KD'5%
+M+8CA08P>">,T8IS#V^%P]P`&AE+#&$:,(0%#F`LW(48=8DQ(&'HXIMEMG(#;
+M2+@[!P,74\.((,9%&F,'8C0A1N&$B%&,&&5X>R'<[<'`^=0P+B#&>1J#08P7
+M$8.1,)H0HPUO!\+='1CH3PUC`#'Z:8PMB'$8,8Y*&,<1HP=OSX6[3V/@3&H8
+MYQ#C#(U1CQ@?(,:0A#&"&!-X>SK<K0?+]NRIU#!.(\8I&F,#8@P@QIRO18P%
+M7V/SX&U/N+L8`R=2P^A!C!,R1IC_"VI7)B29(B[J+=/+8D44,RB2POP5Y*9>
+MXH9!;IKP]CAI0@P<2XV;X\C-,8H;T5"2TO_?5GE\N5)M_+M0?<UF<(LLAZN3
+MR>'00E4Y?(3*7YDL_U+U_$]MD?GVJ/!M3,#W(BJ?0R5??T&"]<_-<KXRE7Q=
+M!3%7(9V1[D57H_^FD?Y:KGY/#H,Y-^'O@A1;3-T7WS%GR^9MYB6/FNO7;5K/
+M;##/F3M7,Y_=UC!_\YJ->-W64#N?>7H+AI_<5%O/KETW?WU^_OQMS-KY:VJV
+M,0U/;EH_;X/F6Z6ST+P$Z"S\)B1J:R5>@,1<<D,NYOO-FPI(S-,U.Y[8]N0S
+MZPA[$+40'F]2QL^ELTLER;I[BR9+8_-56APVC:W<Y?&Z2[TVGT]CLSB\-HMU
+MA<96YO955KG(S=(RX<;J#K@TMJ5N%XFT5_EL5HVMLMQIL[JK*DG([79:7"O(
+M$T+#5U8EIG:Y*R$#@?`)5Y>[I`J2"&1\MDHA:"EQ>RN!HLM6*4:34`R>A`5Z
+M%JO52VA:_)9RAW!7[B*LD*#=Y?95>3R$C,;FH6_<'I(![@A?[J7+*^ET7G>E
+MF[IWN3'&[9&>5:[P$-I.7ZFO_#$2L$*%$4ROK0*+!O0T-H+O]>&]S>FI)#7G
+M(!3@WK>"1)<[?)#:[;=Y[0YW@,1;G%!;#K>K5&/SVIPD&R1V`"DK*9*#7,NM
+M7B=$$F22QN(J!7`WB?*4(T..<A=)Y75C90MQ!,ZS5&.SEY23+)75E26^%<@3
+M,.2TET,SNX1+N<MO<4"+6,N]F$2\6FU^C:T:?VW5Y3Y2!R55(I$28,INJ7*0
+M2,O2I38LKM-&&+*46LI)NP3<50YKB0/K8VE9N8.T9(G%:H=DMFH;X6LA\N6J
+M+G<39/COJB2@/B^VKMOF@AJW0:$;&C8WF.]>JX%YTIQ-;'W]7,V"@H6+'GAP
+M\4.%19:2I5:;G8JH65.[=EV=9@V[WOSDIO]C[VR@JJK2/K[/N7ZFX6=%9HIE
+MQ11=T:S,%"TI+0UM8M+*^!`0*+@0W!3-T(H:IC&RAM*W,<8<2J<<I-(W:ARR
+ME;6HD,QJ7BM%^EQ41E36HJ;P_3WGG'OWX6*KIIEWO;76>=;Z\]S?.?M\[;,_
+MGGVX]^R810L+BO(GQBQ(ST3%6:I(+5:G9ZCB'#5F06Y@##YD[4[;,=II.ZZP
+M_=0[;5_^K.VOZ;#\BC+_>>)W#<ZP?-G_K+9\ULZ=XF-2UYGGXUL7S3A;_/K*
+M8?GXJ>^OC5^/7S5BQ[9_X,>?_.6U_:>I%2UG+WGVO&EJW9Y;YXY?-$TU)&7G
+M/_/(-#7YKK3WYKT];>K*K27';SXJ<<ZG[_SCO6$S$^]^_9)>+[>O2`QM=TR@
+MY]:M=7^X\,NOIWSHFSWADG''QW\]8_'-5TYZNGCYOME'T7ON6?W8[K63SMBP
+M\?43O[KHG,D;#B9^-^#!<?>O7OERGZ>N.FE:P:;,V%X-1T2VG?><N:[RT*']
+M4\Y\?_.9FE^><E%@86X@-[A$):4GJ?A0_G5,29]6D+'AM[NG/-Z0]OO8VY^?
+M\L\E?YHS)/'5B'P=[OBAX>.<E)>M3LI6W6YJ_+QNMS6^1#DE`*NF!XZ)L/@(
+MX\:G!I<49N5FJN3$T>=DE61D%09S"P)"8\?F%63G9J1F20&S%D0DGR"80:MK
+MK3RCZ/I`,#<_RY5^?,&BK**%>06+7<O&%J4'LMV)QA5<'TPM6)AJ+;>7V,VN
+M*\U9N8%%Z7FYF:GI1=G7YV<%["..RRS(3\\-..DB+D4^IN8&%A;8.TA-O;XX
+MJRBUV]+"8/["[DL77A_(Z+XT/1B,W,,Y[*$@-Q#LMNNS4U,S\M*+B[NG7W!]
+M;EZ0L]8KNF2C?4Z9KM4A,T(U,=VG-AZR/X=\=83WS+.?NQU:[N7!C[6UA[KZ
+MR/HO;4/?=E.^+JM,O#R;__934[Y_J[["R[/CS_'R_/<`7I[??H"7'\8UX_OB
+M]^"EDWL%?R+^.<?7X^7')T_@C\37XJ/P?\'+SR@?P,NO4OZ(EY<F5.('XROP
+M0_"_Q<MO.);C9>[($KS\L.XZ_#$2,N#EN4L&_EC\?/PP?#+^.'P27MZ_,1U_
+MO'3`^!'XB?B1^#/P\A/FT_&C\+'X$_"C\)?AA^%_+3TJOA^^/_X2?$^\O-GL
+MNS9322?<CD^6?,%?CM^/3Y)\P2?@=^,E6&G`)^*?P9\L/QW$GX)_!!\KP0Q>
+M.N#5^%-EV(^7-Z/=@(_#7XL_'9^&]^,OPX_!7XB7<.%<_%BY'OPXB0SP9^"C
+M\>/Q4?@SY9[CSY+[^XFISL:WX2?(^>//P>_#3\2_BC]7WL."GX3?AI^,WXR7
+M(.-!O`1E:_`GX>_$CY9?`.$OQ"_[Q.Q2%@VO.GKFF6>>>>:99YYYYIEGGGGF
+MF6>>>>:99YYYYIEGGGGFF6>>>>:99YYYYIEGGGGFF6>>>>:99YYYYIEGGGGF
+MF6>>>>:99YYYYIEGGGGFV2_*:IO^_]X6L.905[\NPD>^4\-[A\Z_9I'Y^4/O
+M)-H4X3W[83M"&4K>YM)#]52]5&_51_5E63_57QVIHM0`Z[TK\FX7>6_*C>@Z
+M4ZDS^RO5=[*7=S_5I,7J$;%,WFL3@WI%+.^6+N;PZ?H<YCC?MT_U+QR_/.:O
+M__Q/7GO93]S?][7RM_W$_9G?L_SV__#U_COG^'W7/.__X+IKU8]K8W]N]NVA
+MKKXCPA^,\)'K([?_V=E.TVLP/?/,,\\\\^P78F-?,E0BN@#=@ZK1@Z@#13<:
+MZEB4AU:B.U`S.H`^00D[#34+78+N1[7H460T&2H-I:-#$?9]YW&X=3GIOO#G
+MY@&&:D.=*&J@H48@/TI`22@%!5`IJD!5J`;5HR;4C-I0)XH:Q/;(CQ)0$DI!
+M`52**E`5JD'UJ`DUHS;4B:(&LSWRHP24A%)0`)6B"E2%:E`]:D+-J`UUHJ@A
+M;(_\*`$EH1040*6H`E6A&E2/FE`S:D.=*&HHVR,_2D!)*`4%4"FJ0%6H!M6C
+M)M2,VE`GBCJ*[9$?):`DE(("J!15H"I4@^I1$VI&;:@311W-]LB/$E`22D$!
+M5(HJ4!6J0?6H"36C-M2)HHYA>^1'"2@)I:``*D45J`K5H'K4A)I1&^I$4=%L
+MC_PH`26A%!1`I:@"5:$:5(^:4#-J0YTHZEBV1WZ4@))0"@J@4E2!JE`-JD=-
+MJ!FUH4X4-8SMD1\EH"24@@*H%%6@*E2#ZE$3:D9MJ!-%'<?VR(\24!)*00%4
+MBBI0%:I!]:@)-:,VU(FBAK,]\J,$E(124`"5H@I4A6I0/6I"S:@-=:*HX]D>
+M^5$"2D(I*(!*406J0C6H'C6A9M2&.E'4"+9'?I2`DE`*"J!25(&J4`VJ1TVH
+M&;6A3A0UDNV1'R6@))2"`JATI/=6U9_C<Z"9RY7UKN,@7MZ!O)UV6-Z!//2`
+M_6[E2N?Y6W+0?C93/5I9[U"^A?3RKF%Y/B>M><M5/FMLOZ>WLMZ%+,]SY-W'
+MK;T-Z_.>+Y3USN2!K!P2^;QH^K1I$V-BIR?]YE<QX_QG^\?YQWK+O&7>,F^9
+MM^P7OJR/JZ^)'^N/'^MJ^[UEWC)OF;?,6_;+7*;\Q4OR@^D+\,$BV^>$/N6D
+M%^<H?^:2`$EL'RQ2_J*L/']F>C#=_I2=D9%J3\B5RC9Y6<[2@J#](2-84%3L
+M;*,_%N:Q6J8?4_;'8%8)?V5",M87V#NW_W;?O;-'9V_6@3BS]/S<#.5?4,RB
+MC()\:_(M?Z`@F/6CQU''.6,DTQDOB0:.UO_K[.%(YF[IYZ23<92H=K8]?@K]
+M3U[&4[]RQE2F,^X2W;*\^_]EY1[T==+)^$K4/L#F`<[^Y+Z=ZTK7X#,L;7=X
+MH"O=I:YTY3T,2S$^FX>XTEWI2K>1\9THUN%!KG19KG2[2".*=GBP*UVA*YV,
+M%T4RCC2=_`JE6^)<>R]GG"KJ=9CO%"QWI6L@38.5MFLZ49DK7?E(PY(\#XW<
+MW^VN=#(N%AWNN*N<='+>PTDC>JUW]W1KG'1RC]M]/M7^A:EFS.V>KLJ5;@+C
+MZPDS?:KD,,>M=:6K)5TMZ88?)MT3KG2-I&LDW=##I*MWI9-Q?0OIRGMVS[]G
+MG3SQ.<]T<RXEG</*==\:'6]=+^G:21?=L_MQ7XGXSH&DV]NS>[E_$X6R5=8W
+MSCU\ND&N<[&^4W`UUW*8[S<8$=]+V+[`I^90&88Y=3M4+_M&[&_@%I^Z9OD/
+M?U]".6V"LK:W4TG=M]D^LM1QF^TC2%VVV<X=J;,VVQ<J==-FNR1*';39SIE=
+M8;9;[M8P][6O<4"([6D?&\+<S][_R!#WM[R4>9N/M/SP,$?9]\KG<]BN:%)>
+M;1YHE]$P#[)\8Y@'6[XES$.Z_(\@5$+;PWQ4EWSU63-MJ?#]]UE/G=SKHR/X
+MV`@>9MV1]AJ[;1K,]<H<5?-?-*RYKX3E^RXEZTTUR^%K)#^VFJJ?8?-M<-U'
+MAC7GEK#4[Y6S?5:;.(C\N%_*4+6IKG#6UTC9^;/>G[3%[0^;:H[#4@]6#3;5
+MUIXV-\/15_JL\Y+]?2GEZ6Z]?4_.HW^#H8(.1\$[1AMJE'-^?%2K;C+5-&?]
+M6+@NUY[#2W@://Y*0Z4Y?"L\L%*?S[UP]#Y#;77X+W!9JJ%F./PVO.D2([R_
+MD12-N#)3&<[QQ\);4NPYOH0GPP?WVG.T":=*47K'GMM+>#%<M\RPYN@27@G'
+M-]MS=0D_#<_+-M4%#KN_HB*E;3?\VD)3%3GKWX=;ENK]?>JD/\'IA[Z(X`ZX
+M.M%0BYWT1U+TX@_1CSC7,P).W&<ZZ?NKT^"-:88UYYAP!MQXM6'5/.%2..XM
+M(YS_]_BZ'N\^7]?S7R_I\^VYY"3]9GC==GNN-NOZX;2[[+GKA'?#Y3F&-2>:
+M<#]I,OYD6'.X"9\$E[C*SV0X?I.A%CG7DP.O+3/"]V.%\!3#:@F$*^'HB895
+M,X4?AN?/MELRV=\6>-EIAM7G6.477D/Z.(<_@(<_H/-?FK#Q2_7]'P9O^]"P
+MYKX3'@]OR3?#]?%\>.`]9GC]0CAFL6'-;2=<".]X2V\O?56/&_3Q[H*C4W7Y
+M;)#]+=3E:3^\A_UO</ACV?^?#?69PSUH8N=3B;)"YPN7/ZJW/PW>EN2S^G_)
+MCXEPCW=-JW^4]7GPJFQ]?S;!Z\;J_-T.3V@RP[P;;ERH\^==>.T;AC6'G?"7
+M\.CG3/6(PSX2KKO.GN-/.!I^C?J>[?`8^-L\(UR_LN`Y8PQK+CSA&^'MZPUU
+M=:B^PRM/-=06A^O@+<7Z_A^`@Q7VG(3"A^!-`7W^@RCXK1^8ZB6?S0GPZ%,,
+M=9.S_K(^4C]U^7@&CBTTK#D&A;^!ERVUY_P3[D^7M>)%4ZUP^#@X>+G/.K[D
+M]^EPYOOV'(:R/A&>=XNI+G;X"GCTF[K^%<#+.-X8AQ^"-UYD6',1"O^];]?Z
+M^+P<[P^Z/7P#3O[<4".<^O.!'.]M4RUPUA]-E]K_UW;/)^?GAQO/U?N_`(Y^
+M69_O7'C6?4:X/2N$XSXUK#D0K?(+'WA"EY<J>!/U>Z3#+\#MDPUK+D:K_,)I
+M*;J\G\"&J]XRP_=[-KR%_NY<ATOZ=;W>%?".''U_WH6CV^W_!PVBOV^%@W,-
+M=5VHO:=*#[S)#)>/<^"AK89:X.3/'.%80_T^5'_AZGI=GY?",ZZSY]BTKA=N
+MH7[L='@#7))OS\DI_!B\-M-4U0X_!Y?-M6->R>]7X:E[]?5^)=N[RN<1A#"Q
+M'88:YIQ?-+SB"'V_1L'C7>5KC*3/T?<K`0ZZ^I/IDOX$PXH\A#/AN(]U^J7P
+MQFN,<'W9#`^\PPSWGT_#Y6_J\_T`SLRWYQ05_AS.H3\\+=0?D1%3J:_)#I\(
+MQU.?1S@\$=[TB-[_3+AAI2X_N?"$>3J_ELO^L@PK$I3UCT?I^&N0^NS0-K@P
+M3^??"W`:\4S`X3?AO3>;X?+W*7Q@IF&-=X5[$1)NV6^&R_-P."Y+MR=)<,Y6
+M7=Z+X<2WS?#YW`\/KS7510[_%:Z[0O=G.^"R0:9:Z*QO@H.99K@]V0.W?J7C
+MN4_@V.<--=MADQM?-D/G7S0\ZV)=7\?`/?;I]GBN%)0WS7#[L0Q.#ICA_OYV
+MN)7Z&>J?-\"9O77_L`U>FV?/$6O%+_![-^C\>0>NIC]^+Y1_A,QK;S?"Y>$4
+MN':<CD\FP[,(TD+QU2QX4V][[E7A='C@BV:X_!3`Y;-T>;\)KGM+7\_#\*Y'
+M=;SQ-WC%0Z9U_L(OP4.+[;E6A??!/:XPU+)0_A'4E!'/YCD<"Q^<J/-SRN"N
+M[<UT>$:+OM]%@_5X0\K?$GCX6885=\OZ"GB[J[Y7PRVOV'/!ROIM<&&3&3[>
+M*_!K<?KXK?#>CW5^&Q3$X$Y[;ELK?H)?6ZK;IU%P[!NZ?IX/[[A#QU]SX1A7
+M_+4&SB2^OM3AC7`)\50HGGL27D%^A?*W'>YXR@R7QT/PKDMU?#.9&]^_CO;*
+MM/D2>$ZQ&:[_:?#\.3ZK?Y+\R(-S9NMXM`*>,%G7QX?@3%=^_0W>0?U:Y/"+
+M\,%"75X^ASL6Z_SIRX5,6JW+]]%PR\7V]P:$X^`#-]IS)`N?!\<5&.'R^,!1
+M7>__X_#:#W7[N!/N^(V^O_OA77,,J[[+^L%4G&TY]ES%PJ?#\06Z_TF$ESVE
+MXX?9\%17?)L-Q[KBPT)X>(*A4AR^$\Y;J\=+F^$&XLU0>_<4?-#5/[PBV[O:
+M_S9XCJM_Z)#SJ]#CA;XDS"G1Y2L&WG67$1X?CH,/^DQUK-,_)<)KKC+"_<EM
+M\)YK->^`R^_2Y>4-.,X57W\&3^I%^77VUXO`.GF>83UW$YX*%V;H^G<Y?+#2
+ML)Y]6.TQ/+K(GM-9^'=P6;V._ZK@NBWZ^)OA'O179X7R"ZYNTO7M)3ANI\[O
+M-^$9,W5[U`[G?*;KJX\A>_MS1OA^'BV\0\<OI\)#Z5^J'+[RV*[E*QW>1OD,
+MY?]BN([K?2K47L.;7/7G7KC5-9YK@M,*[;F[A5N$VW5]/P"ONI_[Z^3O=Q''
+M[S.,ZW6-#XX:UG7]<7#MB_K\3H1C`V9X/'4.W.B*)V?!,[),=7=H_`ROR];U
+MX5JX[GU=WY?#FXAW0^O_&]X1-%5.J'V4X[OB@8_@>:[XY!O97[&.SXZD8"2W
+MF.'Z&`]O(KZ>&HIOX1V3=']^-3PZS0S7AYSCNEY_OC#CP]#^;X:']_*IC<[Y
+MK((K/]+MS6-PQQ,Z?G@6+G?%AR_+^05U^DZXOZO_/H4+;;A&UY_Y<*6K?0S"
+M9:[^Z`'XO9=TO/L$W&>_CH?VPE,?T.?S#3PZWYZ37G@@%7T6[7&H/1P'Q^7J
+M^+H2/E"I\Z<6GGJW;M^WPRW%^OG)Z_"J%GT]W\$S_JB?WQQ-(+-]G^[_QX^0
+MYW%Z_5)X:`]=GBK@%3?8<]++^FHX[45=OQ^'&Y?H]2_`!XDOOPBU-W#>*GV_
+MK8&)Z_[VAE==8\_Y;HV?(]:/@K<\I=O;T^'&>_3X9>9(B4_U]2;#.7MUO%(,
+M=VS3YWLKG#Q#MU_KX8UOZ/1/P@=FZ_WOE_6K]?CS$WC%O69X_/(-7%EDA)^W
+M7<&!)MQIA-O#V^"5E?KX:V3]#3I^WQ#3]7IKX5;N[W)G?3U<,ED_/WD=+ENN
+MR\.G<$.QCL]/IJ"V+]+Y<39<RWCQ<H<OA%M=\<F5\(2M^GQO@8?OUN.3U?"R
+M/-U_/@CWN5:WOV_`E>OU^+)C5-?KD8:K3[MNGX?`R:[Z>"(<O\90<T/W$VYY
+M5H_'T^`MCQKJOT+M,USVDGX>L0JN=/6?Z_B0%T/]<>Y/_0GR?$C?[WUP\%)=
+MGX\D(Z8R'@G%.R?!\\\TU-,.3X++S]+'NQ1>XQJOY\#?$@]4.KP$/M#?#-??
+M.^$]IQGA>.\^>-=SIOK*>?[Q"-QJFJJO<[[;9'M7>]X$KRS0_<O;<-T277Z^
+MAJNI7^-#SW<I&'5!/9Z;"$<3GSWH\!RXS\=ZO+@$SJG5\=[OX,8[&#\ZYR/_
+MBTAVQ3-/ROIDW1_LE/W3_PT(/0^`.Y09?A[Z!;QCF6D]V;?B,P+EL@*=W]/A
+M\C4Z'DB'MT69RG2VOPZ._;NA'G/6WP!W;-'[JX(;LW5[V8>!7-DD'2^.A/^7
+MB_N/J[J\^SC^_9ZPL6)%C1;W:HLV*E0T75;D<))1H5+BCQ8J*B8I*K]4-%1:
+MF!C.6+(Z%BDE%MOH#A4+[]C"1"/30J/&G;3(K*@HF:-FCYA1]_VZZ'S/^SK^
+MQ_-Q?G^_UX_/YW-=%\E6O#@2=X[7_#P>-W<J'[@+1^]7?+X4=Q6J_]][96C[
+M+L79&Q6OU>*8_]'XUX)[W]-\.(@WNO2O]*_`[[L0-UG?+PX7YJN^F80K+U=[
+MG8S+V]0_YUUEZE6:;PIQ;([Z_P/F_:SQL@;W6_7U?;C5JG_VX9SI^C[G$=B7
+MYKC!?&X"SNIAO`M\_QDX]7[=GVR<MD+SX^]PYP\TOF_"TZK=8/_?BUO\FO\^
+MP)5#-5]^C?T[?$Y8X/,NYHMF3E*\?NW@T/LQ%D?MU_K#I#,>OP,7T'XF>NT-
+M9TS6^HX?ISWG#JR+&._"6??I^KZ*JQ[W.8\$?!1W$L_V!O*OSW%)@\;K'S$P
+M]FU2?C<,KZ]6_TS!Q66^8/TV"Q<]HO%X.<XYQQ>\WO?C$58]^B%<\Z`O.%YM
+MQFF3SQJ(#\S]>P8W3%(]9#NNS=?XVXRC['QE2.CU>A?''G*=Y[WV@:NLWW?Q
+MT-#G_PSW$/_,]-;#<*-5SR[!7=4:CS<--?F(\J&MN+90[>,P+DAP@[_W8URW
+MQ'6F>O$,';_+6D^[!*>4:KP=&6_ZI^*/&;C!^KVYN'B/^N\:G+E:WHC[YY\5
+MJ&]>Y#R.FS[0>M0N/(U\RJL?'<;U&Q1?GL3=UZD>$\:-K;#J91?AVF;7R0G<
+MWZMPU`ODQP'?A/L357^:@?USE7\\/$SKM1?2ZRIQW4C%`SL&'O<%YX=FG/!'
+MY>M'<>P:Q1-?X-;[7.=W@?8<1J`8;5V/RW!;B^K+(W"'E0].QGXKOYB+4]9H
+M/60%CK?62\MP>Y/BD2W#SUCOPH5;=?_VG?'X`5SPKO*+3MP_6?/G*5Q'>_/F
+MIW,)](XOT>^-P2DC7.<G@>O]&YSTK.I3M^/$^Q5O+\`)+^GZ;3"O?]$WL.]E
+M8'W$/&[EJW4FL.1BS@V\_ZNXSIK?/\/1.1HO3YOG[];UO)B.6Y.D]9%AN")/
+M\<!8W&#%9ZFFHQ./>>L]ZW`C\],!KWZ.N_8JOWW:/'^MQN]=N/0OKI,1N/^'
+M<=476M\]AMM^J7K]O_&T;9H_+F*@;[7BN\MQS!=:3QF-:[<H'IV$&ZW\?2Y.
+MSE,^N<JX4/6C.EQ3K_;X$L[XM>;SMXT9_S<$_*GY/&M]\SN<^)K:6P03?^M6
+MC4]QN-+Z_M?@X[\GW@K<O\FXUEI?G8=[K?K>%EQBS>?;L;]8XT$+3K#NUU&<
+M]2_%+Q_BZ%FJ?YQ/8A<USAU8]Q^(3Z\);?]#<>D2U0-N/N/Q;!QWH]K/O;CP
+M>3>X/V$;;L[7_>O`B;LT'Y[`U7&N\P<O?V,@R<C3];D4YUCYS7!<^&_M+TC$
+MS0NU?I6/(Q_5?%B.PX\H']V,PU:IGKH+5]_L.FL#/F`>M_+3?^".ZWS.$Q<$
+MY@<<4:;UA].CSLA'&$BZZWS.V5[\A8L*M7XP$D=8]9Y$7+)"]WL*3E]IK3?C
+M]C+M[RC#'6]I/G\4CQBN\7L[/IBJ>L^+^-3YBN=>PZF/NTY=P.^:]Y^K^W,A
+M@7+S6-7_XW`)_<\;7V_"B8L5'Q7BY/\0#P=^[SJ<?43UA\TX(U7S>1-NLN;C
+M`[B3^'M>X/5_QW%6?-B#8XXIGOPO.G+TCWQ.<N#Y0W"J56],PNLW:OS-,!V?
+MW^M=_U4XP8K/-^+65O6')W"+-7_LP!FWZ7KNP4W56K_^7YS\H2_X?E^;]SO[
+MK(%]..;Y/S03^5)=O]&X[57E)\FX9H4^+QTG;U5\MAK'7:/YO0(GIBE?V&V>
+MO]`7G"_WX=8VY1L=N/-NQ<<]YO/6JM[AXXLWGJOV>0FN[-3\DX#KGV6^]NH/
+M./L]Q2.+;PAM_TO,Z^?K^N[FCX0/-?^\CS.>]CE3O/4'\\3Q&I\'<6%J*]3?
+M?X(+K?I@/$ZPUI,GX[B_N4Y48#Z9A=,9#[SVY\?9UOK[L^;]NGS.2:]^9UZ_
+M4?L7_HZGO>QSCGCKH;CT-8V?)W''3EV_\W[-^+U4\=)"7+U;^T'*<5BAXJ6]
+M.++>#=8_W\#IK:KO?8(S]NCWG\;9]ZA]GIVHZVURFG,2S?RN^;@`=SVF_+T8
+M1S`?;_'F:QS;XG.^]>HOB:'W[TF<UJ9\O0'W+=?ZZA'<LE+U@*/F\Y8I_CF'
+M"]%MK8]>CI.'J9Z1@)L.Z_>-P]7V>A:.OL$=Z#\#]0/<X%>\_CANMO+%-W&'
+M-?^>P*W6?/$M#HOP.9]Z^T/,0/BFU@-B<5:U]DN-Q+%/$'\&QI<)N,K:3[44
+M%SVG>*T41]VI>/\Q',Y\_K:W7\T\_I)^WUY<8O6'SW#"!ZZ3%VB_7^/J-S5>
+MAW-C8]>[3EG`@\V-MO;SY.':L6I?I;B-_,M;G]B,ZYB?O?TX]3C:RO^:<"OQ
+MAM?^6G'1`<5K[^""X8J/OS"?-USUCW`"X^QLU3-^@@NL]:T8G&IY"(Y9IN^?
+MCN,:5<\HQ'Z_VI,?%[_,_.#5,W$CO\];[VK"F8_I^QS"O1,T/A\WCU_O#NS?
+M'MB_A'NL\23BQM#^%(E3EFJ^N`GW+5#\<,>-H?UE%BZ?K?Z_";=;]=07`L\?
+M$GC_/;C:JM]VF=?GJ5XV<5SH^Z>-,]=/_7D.CH]7/:L0^ZU\<SWN/Z[\Z$G<
+M,5/W<Q`#5XK57R[#Q^]5OG@M[MWN<Y[VXF?<.EOUYS(<Q^2[.N"JFT*_;ZUY
+M?IC63YIP._GJ=B^^QVW372?+B]^3Z<_$!R>\^A@N.J;Y826.>=UUYGKY!>ZP
+MZGUUN"='^Q5?Q-W6>L$Q'/^XS\D-^!3N6Z'QX5P"QZP\-SC?W7*SB:]=YTNO
+M'H(;K7QH$VZ9J/T<VW&BE=_OQ]W$A][XT6$"TT2U]UZ<O%CY9#R!0=]"[6<8
+M@]/?T/A[YRVA^S4S<(&5_^;CF%+E%^OQI59^MPW7G*?]'CMQQ3EG.>8+F/NS
+M#]=N=YV(P/=]'Q<.TOW[RCQNC1??X?J[5:\>>2OMR:K_I>'HB>I_"W#L+:ZS
+MV:O7X5&INGZ/XO!ANCX[;C7[(^7/C%/U>TWAK7N/]@=$IH2VOVB<;NWG&IEB
+M]A]I/3&)/\*^T/7Z+>YZ5\[%,97:7_T'W&CM5ZG!->3C5P<>;\2=GRE_^<A\
+MOI6?]Y_Q_<YG8&E=J_K1);AJM=KO2#/PO,[X'7C_&W'DZYK_QN.&=:[SWUX^
+MB[,8#[W\M0BG%6B]Y#WS?&L_[;]QXRPWV'_B)M`>K7S[-SAQE>KM\W#.MZZS
+M/_!]"K!_AOKO"V:CXT+%0P=QQ"'M1W@#9S^B\>4X3A^B^/2$>;Y5G^C'&=;X
+M^>.)S%_?N,[>P.=?ADLFJ'U<C_LJE8_<,='L_];OS<?%(_5]RB>:>$V?OQ5W
+M6/MK#DX,O5^'<>U'VG_]/FY_3?''IS@R1>W].UQYM>:C&`;.CN4:'\;@=JM_
+M3\6EWZ@_9./LB<HW5AMO\07GKS_@:FL_40W.R=/U>Q&'[W0']OT/W'_LW^PZ
+MN[S]B+CM/=W/LTDL$SYQG<Z`?XHC?Z'K-P)?6JS]%[<9WZQ\?Q[N6JAZPTH<
+M8:V7;<#%2Q7_;,7AB]S@?M4W<?EAC>^G<*:UG_NBVYD?UNK[Q.,4:SQ*P/[W
+ME7^FXEAKO3L/9R_0_:G#39>K/1S"[8/=@?-)`^L#N/.([L_7.(?XT!O_(R>1
+M;_/\I[SU?-RY3?O5;IATQGH!CK+6PV_#]3>H?63A[CSMC]ALWF^.3_M9\/&'
+ME4^_A$N+U9X^PAE6_>`T/K5*OBR-]KM7\\LP').O\7$L;ISK<S9Z\0=N:E!^
+M-Q-'[]'[Y:>9]6#-)_>:][?&QPJ<8*U_[\*Q]VI_XC[<8,4G;^,2:_V["\=9
+M^7X$`V7R',57R?A@CMK75!RS4?6D'-QCS=?WX2*K/V[#3>T^9V%8X'J:QV>I
+M?O8C`H]*:WWZI\96O>*7N/M.-UB_G3E%YX/,?L$%N,J*!U;@)JL>6XF3GW2=
+MOWKM$1?/T_UY:8K)SY0/MTT);4]'<<8RU3>OFTI[L?K;+5--O*KVO@ZG6?L/
+MGL)9:1H_WS*O)S[V]O-\AD>LT_F9;W!3@>+/'YO$YR[-Y^-Q]A)=[[FX?K//
+M:?3B4]SRB.H+I>;Q?VI]SX\S'R!?]M;#<,XBU4<^QA56_SGK#L9WVI,WGOT4
+MC\I5^YF"TSY0^[D'K[?RT8=PZGS%LZ_BI#^IGM>!.PYI?#N!(ZY5_<W][1G[
+MJ_"I'^C^1N-I5CYX%3X^Q75:O/@5MUCYX)]QM14_O8)3[M+ZWV%<8^T7_03'
+M6_L-W#OYO5;]+QK'+%']9B2.7Z[S"#?@]F7:[U2`LQ[0^Y?A@\]H?>(QLW%B
+MH\:#O^`J[K]W_N,]/,HZ/W82)T___N2?^?WF`%OW;+W^`CS-6M__.:ZSXK_K
+M<(U?W^]V7/ZA]H?^+MWL'U-]Y4&<>*4;S.^?2@^-E_^,$]Y4_:(1=^;Z!DX6
+M#M1#S>?G:C^V.YW?Q_7(#S@*-UK]ZPJ<]$>M_R;@B.5J3S?A6"O_F8'#EFJ\
+MS<<MQ"->?E*.3VWP#9S+&Y@?L=\ZG[$;EV=HO>%+7)*I]CYX!N/3+)_SEI>_
+MX21K_V`N;GM,]:--N*1"[:,6I]ZM_/H=W&?%'Y^8YY=I_#Q[)M]_M.;?2W!'
+MA7S=S-#^,0;7+%1[78Y';-9YFE)<;>W7WX+#K?TF.W"WM5[2C".J58_X!_:G
+M*M[MGVG&(YU7&II!^SZM^&`,]EOKEY/Q-.L\419N^%S]855&Z.\IQ[63%*_M
+MQ@4IVD_P.D[PJWU\@NO6N\'UNWX</UKSS84D4IUW:;_`);.T__Q"HOK+<<;?
+M?<X<;_T0]S;[G&^\>`*GYV@_QW3S^I=5[\G#T6GZ/#_N6J#Q_&D<_[#K?.Z=
+M/YH5^GM?P256?'P<]Z=I_?\D#F.^]>[?(!I:^+U:+XJ=;=9[]/NNQQ56_Y^`
+MVR:I?>3A[BN4'Y7BWH.*OQ[$-=;^FZ=FAW[?9W!&OO+Y3O/YK3YGGY=_X_9R
+MU^GSUK_F,/]8YP]&S#'G)90OCL>%UOFL3)Q&_NC%/T6X>[CFVXHYICZG]?PM
+MN.T&7?\F7+-,\?(;.,QZ_E%\\)#.EWZ,([\F7@W<_R]QY7'-5U=DTE_GN<%Z
+MS:Q,4Z_0?O<_XM0<C7=/X.IKW.!X_3QNM^I'!W"S5;_^&*=8^\7[\?HB7:]S
+MYH9>_\@S?"7NGZ+QY%K<2[[M[0=/P5W6_JY9N-+*EY;BL%^HOZ['222#\P.O
+M?Q0G']'X_#2NL^J_NW%?KO*C_;CTP>__!\7`_(7KJQ2?_!-GCE1[_,Y\7VL]
+MXGP2EV3:3ZD73^.8'VK_S&@\Z@'E2W?@\'SEOPMPQEO*+XKN,OO1%0^L,>^?
+MK^_KQ_7O*I]Y%K<>TWZOE\W[O:/QOAU7-5GKO;C(6G\+8Z`/M]:/+\*5DU5/
+M3,-U0Q6/S,<]UO[J8ISI5WMZ&$=:Y[^>,<__7//77O/\A=I?_A5NO%KGA2[.
+MHCU9^]L'XW(KGQJ-6Y_S.36!ZSL3QUK[OY;@9I_BBW4X?*7J0\_B"&O_6C/N
+M/Z;7?X[K-NKWF(.V4=9\'8WKK=</P8U6^QR/:ZS'9^+.CS4^Y.$$Z_S'6AQ-
+M//BJMQ_8V!H/#^%IN[1?^BCNN,TU)<3OXY'YY$?6_M"A\T/[6Q*.LMK;%-RS
+M3_M%[\(C_J3SAZMQC;6?:X-Y?ZM^]20.]VM^WSG?Q)<Z#Q/%1)-IQ;/QN+=`
+MS[\;-]_B#OR?D(%\$4?F:OS;@/MS-7^_;![?IGR_<T'H[_L(%]6[P?/-_X=C
+MK/K[]=GD*U9]<`:N/$6\%/B]BW'M$:WGW(-KK'I8/4X;K?G[15QJ[<<X@D]9
+MX_D)G&&=5_WM0K/^XSJ/!#ZO$"<-5?]X<&%HOO@PCJ%]IWOY`"ZXU76JO7H4
+M/F6MKWV+L^?XG&7>]5_$_-:D]G#5(OT_"_/^8\S!M2KME[@;AR_0XXMP/..?
+MU[]7XY1HGW-K8+]#&<[9[W,^\<8C7'N?SYD>>+^=N+%(K]^#*ZSUJ#=Q1*7B
+MC??,^S-?[?3J.XMY_K\TWUR!TXFG;PV\_Z_PM!/\_H"3<"TW<[$WOO)'^51O
+M_CS?68[CK?UO)=AO[8>LPHG6?MYS273"U_J"^=TE.*-0X]%P'#G(YPSVSD/A
+MF"*--S-PQ&[5-W)P]SC%V_?GF/,7ZD\/XG:K_E2+PW+U?7>;S[/VSQTTMO;C
+M_@.G+-!\>1)73]7XT8_CYJE^=&XN[Q^NS_\YKK7RGV&X99'RHV0<_H'V,ZS!
+MI8MUWG</CJK1^'$4)UCUMO_@@U8^&DF@DCA'X\\0?/`C7[!^/1NWI&M^\>-+
+MK?KOLWGF?+[NQQ[S?L6Z?P=PCI4?=^)D*U_X%$];JOCU-*XGWV_S^@^)7G.9
+M[N=@7+U"YP6NQ6G6_#P6'W_&==J\^0AW'M;URS6OY_.\\:C$V!IORG'X3-4C
+MMN!3UGGC5W#3&_3_'P;J,[C#JI=UF<0T1N=1SRJ@O9/_>?WA?-QF[4?]%8[\
+M0OGT!)QRD^N\[]5K<&NOGK_"',R;K/AZ.ZZ9ZCKO!'[OB0)S/DSGWV*7<#VL
+M\^/C<9_U_UG6X)S/E2\]A4N(Y[WUN.VXZ#.=+]ZWY(S_IX)+%VH_Z-E+Z9_G
+M*3Z/QFW6>?#!N.=RC3]C<+5U?K,`U^[4_HM2'/^*\O]*7&/55_^ZU)SW=YV'
+MO/P!%T_4^/\#!N)1*Q5__AQW6_/AKY:%_IX$?'";XJUL7&V-3_?C3JL_/X)[
+M,M3_M^*T?*U_/F]>7Z[VNQ^WSU(]XO09GQ]>:/)%S;?C</=:[2>[TWB8QN-<
+M?-SZ_P4EN,B*?S:9][/.HS?@N"_U_QI>Q0U6_?X8'K%"K^\U[U>H_9N7+F>^
+MWJGY9!AN_DKS]UB<T>(&_[_.';C/VH\RV]C:_[+(^''MYRY='GH]?H^CK?/V
+MU3AJDN;;`[BJ5_',^WB$U=Y]*_B^5OW[(MQ\C\[_#L7E$WQ.YH6!\W"X897R
+MB>DXSMI_5X%C/E#\^"></M\7_/]*.U:$?O\75GS__Z^\SS^!"^Y3?#7H'GY/
+MH?+)BW&R'6_CU&*-G^.,_^PZ"8'KO0!W6O7KE3CC;[I_ZW&]M9]K,T[J5?O9
+M@4=%,K]ZYX]PS&35=WMP_V+-9]_BOB+Y%T6TOW>T/I*$#S8I/KX=)R;J\[)P
+M^'#E_ZMPSP4^9YMW_@CWG]3]W(%+_(K_#N&^R8HGWC:OOUKGH[_"12O5'R-6
+M\GBQZAU7XS:K7IZ"J\O4/K-7ANX'R<-=UGFC3;AOALZ'=N"L>(VW_\1QCVH^
+M.(W#UJA_1JXBGUJG_20_PZGDSU]Y^XUQ\6]<I]^K?^%DZ[S,8EQO]>>'<&2X
+M+QA_;<;=^]5>M^,LZWS$<S@C5_6%$[C9.G\U:#7SL76^8`S.F:WV.1Y'6N<K
+M%^&.K?I^9;C?^O\+3^#>:]S_K^WZ?23)DG*>^`<P,<Y!*AMM]>SM=$LXN[W;
+M>X.6V=J>&8,54I*5/[K?3E9F;F96=?5QNT@GS#-`".L0.&=@X<!)Z(0%PD'"
+MX@R$,)``"03&V5A$Q/L5[T=6=V;?.G=;-5U5F>_%B_CBBR\B3;_Z7\+K;_^3
+MW9^_@]?GQV\E?ZOY%GC]X^]^R_2/_`O^WFCST6??A_UE>K7?@-<_!WRD]1&_
+M`Z]__)_@+[4^`%Z_R_C^/\/7_V/CYT_A]>9+B_=^Y2NP3\8W7<#K__B1[5_X
+M+KS^@Q]8/6@-K[__]W;_?P"O?Y_YXS_^RO4'/X+7/V/__A?PNF-\P-_`ZV\S
+M/N8?X/6?_*,]SS^#U\4/+3_Q[WB]?VCQP?_!Z_]E_77KK^$\,C[YN_#ZKW[7
+M\A\9O/YEAO^^@M>__>OV?/[1UZC'L?C@3^'UO_T$XH72P_TYO'[W"]OO\Y.O
+MW?O]*;S^:X87_Q6_[U=MO/DYO/YG5B_^I=\#?\'XZE^#US_\;XN//H+7_\7T
+MI<EV7Z5%69=CF>:W63^DZ=5FO2X+,:;P3U79;R[HQ2[KW[X12?KQ)Y]^\/XG
+MZ>K%:BC+(DW7YVG:9TW1[M*;LBG[;&S[-W4";\)7/1?#V)?9[AH_F9Z=I2\^
+M35OY5GHGQMML&,1-`_^V2M=G\+[\)_C=)"_[WO^2;?"M^#LUOJ.^%-_`G]B/
+M5=UF8Y(>QM7ZO33-QK%/Q_NN3$53M8GHJN/:?D^"_]?W39MT[1W<__7E^#QO
+M=UU='M>?]W1UY\-8B!8O#+^_+W?MH:0E*?ND$DV1UMDPIFV5II?C^FR;#2)/
+MX5M%<W/V>?[YN#Z7+VB)T['/Q#BL/\\WE_D;`4NS;V[*T5Y/3NOQS*Y'-I1P
+MHS<C[LUE?CWG)]0"75WK)9KY:=R8EFY>K17>?RV:M["2N!WC*%*\^*8M2KG"
+MZ>6%76FP#UC^;MQ5=OGA%I*J[7=I>F'V&]XK]=?ATF<]?M'Z(@4C%/4H&OOQ
+M:^?[X6J&;C]NL_PM?&NV'>BMHJRR?3VF.+IXN$UNRR,LP1LADKJ]288O^S$I
+MCYV_T["WZ?-*7I*`"Q)HL\Z]-*7\S*P=AL^=V!S7[#>O<O%ZG>0M7/0=_%$G
+MBB2O2_A,^@QV0-#-5:(N]9W!YPIK.)LWN4AZLL?Y=IATN(A5)FJXJC5\A^C+
+M?(2+$O(8/4_3'*Q\8.<(/,#;M@*C7[]+/L+<Q_&S,[S><_R#%+Y()/F^[\MF
+M1-.!13R'#1Y*/$YBE]W@Q?)M:,@XW,TI$M'BMH(MXX*R\^F>UB3K;\+/TG&]
+MR3J\,^[:\F2X']*[7H#W<ZT1#V51]N!&[OQ-@M]ON\T!KAKOT?-)&SAIZC]3
+M\U]RVW"O$OC?\GNE_Y4B:7,\W36:7#W;REZ_XUA]T69UW>;96.+YU0<_P?NO
+MRVKT%D$HK^<O9-D4CN,@*[C@JT"G=9>-^2V>U=`^^$D5F\-3'67$5HKD[C8;
+MT>7(8>2B;9R5&.Z;\)"Q4T3_KA>+6P#9A3Q<QO5O\'!)SY_.N7:\@JX.X@IL
+MVH198E3+BL-),R]WW7@_;Q&]6+FY?)4G70>!$9:/;:L-\`^[=W"GP7VQ;6[:
+M^5L]R_#!*"2$F+<C9$T:<\!]JT!NS((<@O1Z:\`V-V4*\*#MZ2,1-PB[J!R%
+ML141NG;R[%G7E>B=9]UCSD(/\Y.5PBUP82H".A`B/1<ZF$4B:P"*W+"*MWXF
+M6-Q?*5]7?AEXUT(N)2#`#.*TO*#C`%;3>($$#Y"_+->7GG,=!+K'[[RZ@HU(
+MS,&0*S,)3%^?X9'9U<Z1*;P@``AJD6=-LP%AC&@.62V*%`+,'A]D`%<>O)<H
+M)"V-)IV\W'6R*W=X^I=$Z[DGY.7FTU?@N.3"SC0\>>F(\R]]'.@C5+%!Q(30
+M)70)Z$WSNAU*1%BPL;C1^\9^.7>\@,["`%Z2&Y$VR/R[-+/D]8<K!Z?1AJW!
+M.<%]DCW"7O&7:-_XU`KGA^'`M/K`T(G9IB]??$)'X7P+@2`'CT8_COXP;^O]
+MKE'`DJ+VI.%)MP'GK=HW><HO\Y#/VWC$:/N193NYOM=G_;X9Q:XT=^N^D=RT
+M;:'7#Y=,HC`&>'"S13*6=1U"I&CTZOW,Z^A!O/4SNE\#]&"/(HNP+6_`9\P,
+M8Q_^ULOW?_/%95+5V<T0AV'7CLVQ[$W>2^4#?[E#^Z'D:6(Y]V0F(1*&O?#>
+MF<J:(GDJ[D=GU]BDLVX^14;9M1!89#I$1P)?LA`@TYFARW)<CDW=CNA?A:`3
+MVWP12X5"3U]582"YF`@@L!`F+&JC]-Z!/Y)IPKLO\)$S0@(N7-4T7#.\<__-
+M#N**&`#SF>S(>)?K2^-G3))BDHZ'LI/U>Y+)J*WU#J*Y#;W25HP$'N7O)\K:
+MUNN*Y^T&:\*OT7WH'%.'U$>&%K#&VL7CS@',Z6#GCDM;F@H26\._O-8()(RI
+M0P\_.VG3$;24EO18H0AT++23\,YAS)AD8NTY>?EF")5ZZ8-C;(+D,VAO(':/
+M61J`0NEAW\$0@)\2L`3\5:*R1PZKA<3`E>@7YSIX6?@DIM1<AG,0%^TM?:\Y
+M(ABOD_RV!-@(URW->&8TTCA-LB7@7QK86=<$R2.-10MQ"T\XK/$T'8*;MQ.!
+M51`&<X"XW.D[F9[J'+O;;\U1OSC!1`SXGUT[.'\%R>5=VQ?6D80AK^)@B$>4
+MK*MGX:JY_-V^N2-K@LA)":Y--_R\%H^/B\/SMKM'TP'+'_JR.[V?UO*J>@\P
+M#HR"/**^[^2(\(,^Q=8N9S8E$03\ND_S2'I#B!@=R9<8]^;&AG%_]^3%D9]5
+MP3!PD^Y!\9!84>:*"'3]&V3"BC1!.MQ%A6[.?$@\!R_$$Q->7'/8FII"\RQ>
+MX?5:[MA!LJGV(G-%;$D"@\,\$5[^1KNK97&"H7'#F.$FO#?LLD9TZ\_?U+`)
+M[%6"?&T3T&UXO<.(9(XVILV!O#9'HYCQ2A)<YN\.J-^#]^D@T\0#>G60]O&.
+M,"=$AML^N_,C=-<*"/T<%25UMD5'9=Z2@2620[N1RH%`D.'EW7W4I55>$H,+
+MHCTEW$NJ@]ALLO\#O"'7?E?I\ZXGN_:92KPEN%*,,O<*F*A37![+O$ZR+9[4
+M(D&2C*HU*3D]!78H+_+8`<Z\E:-Q_U3>R`WU>6&V1"SA0^1>X`]NF`D95(0^
+M$`(];:J#(IS4"0X\1",)DBU43-/H1Z]=8.O2.F2*Z:Z.ARWMJY-BWYT1MW'F
+M)5AR(2T?CC$?SVW;U/?1'X.5Y1P)'%ZB[&46U)=U22;P*)?O<[@7D]3M4-:5
+MP,Q^7NCJ)I8E#A:CVP:WF\([.]$017NUN3JD!^<KLEW\-";$;5K69>.M^WC;
+M0Q#%U=O3>:8%!---IP,WN-SDFR=L@HH"7EE*_TNERW=8Z9)G3<R.@]6)KBTO
+M<7"B3OF?J>3N:?'.1`XL)\#M.!Y$D\\?KD91<L:'4B@9^"TXF0[4F)FLOZ-^
+M7Q\N`.[^6\F.HC[]Q+X9,E/5A94>(!N_YX!9;8S%G#RPR5"H"PZGR"?XV@R/
+M&__>2<Q"O)2FGZXO+1.ED-TD.%`U/8EJ+S6L-1Z;?O0;,V$R8DF;^JDTYK9!
+M>NU9/'AG-&I)T4G2"M!!@Y(`IU`>]S`%`^HNB2U@NX^I])ZSXBJ%0-?:=%0E
+MGQSD@`>S`(_@@U9!?JNI+;QW0$S[1GRYGX<.HUR>]84(I,9V7RN>R+D9##`C
+M.5MM-7@C4^(-RT?DHL]KCUY*ZK*Y&:D^R(E\^$X+&EW4YASC(3QR+K-*E\8.
+MH7<BT^;NT=G/FW@<KR!@160A&,<B&H)"$V<A4>+0D[F">WWJ!'SXI1JSJZN^
+M=XFCEK@W%[E+S.8@L)OM?M=Q0Z7=5&RU^SY:7>`-\>'.C\4.$N'YZ865!#C(
+M)4S#I1>WW":/11YU+,D_[X0@SO/?@\03RV#[SC^KAM>7&1`:#:,>KR\Y#ZEL
+M:AX@1;>DCH8?2M4^FUU<L>+6LQ?Z0`FZ#N^-)U3,YV,.,OTB0LB=(7D#OT\$
+M3+P42:#.UN"O_7J\LF.S(!U<Q%@E%1F!GV-;<B!E9.=JT@,IV!Y0>Y^=1=]>
+MO^>\=<AJ$G@)GD"$M,(1KEXY97:*O-#=*Z+17;$/)`YU.3'M_E2I.61%'#?F
+MPSDG(;D9%U0U%=/:C;N"`<(E/`1Z3LK)X,;?:<VAQ]<7K89WC+3B3DA#(<^Q
+M@=671Z219-PZ!>)3T=(Z@0N%'8)-5)LD03/$SIB8"#^GEUI$L\BR'4[*MO:[
+MMBC$LR3?%2S@Y8EDDE4A@%QRU;=;!3D>&8@DM-O>C^7@Q\V-2/J"O*X+;%Q8
+MA-$EM=#::-ED690MW_6EOYJ<J-GH-4SU6J)4!=-U8D_=CQZ&//-)'0"A$KR5
+M(RO57$E!I:Y,$4-A\=QSBT\M<TR"4-$D71C>),O#Z'C8FT(<<&\>T*>>7(EL
+MV_88"B(%#+RQC3V`&_'ZV09<3?B'ZW66YR6\`[92:O62#Q?0,M;^8BJ:DNK*
+M6"1^K.$`JCK$$^Z99?\<=9),#VCX">(/'XGI24/B>$(6XTVN:F@8+3"YI154
+MRE&W7*R*/DZ!AAU?CWV.7%-,G5#P.J*N)5L,JP^/C#XB)EZ6#%\1!X+S!;L4
+M^;$D$P&7"DR8K4E,,9\E3XYNPY5MD*2U]3R#F_@ZH0J6;^"0/D#<(;NK@YTY
+MTE9`!V8\7+WXY",?#0N=AFCFEX@62E'D266`"D\JQU>=D,;B$658A%,6&*B8
+MM!OS3MT$_S^=?Q0><CER-:F]:\-N(_8U]QB6-E:,P"&OUGK<=9#.L@6%#TSA
+MHY"<)26JW$D;61&TV?0P4N^NDIM`+8BHR*2IA1CRMFE@8TC4")%O)Y%?D`4'
+M45POK_#(GA0!^8H%,R=/B&72#K4_H+@DT"=2YC&V!EU$%!I8$+C4P4L&7/[%
+MF$;L8\295(?R4@(<+HS-^%WKM<RK`5KN2\1:,UD(E3(Y$H`0C$N'CW9I+\,H
+M1_S*NL'F<&$`N^!?Q[@``R.L]H[#EBQ(^ITKYH"OZ]Q7I!\6%Y=D[J'X`YG?
+M'2)M`YL\(:J0"@)L84S5`^RH>30A'LGT*T7O)+P4ZH&0E-7[3>:32HT9D>LQ
+M2ZR,=C4J<E1,R0)]JQ7N\?.-P2^BS"LQ/E=DHVY@#7CH-ZZH%-'[`L4`2VP4
+MP!027Q(L9'FC+0BR_3[$[D+Z2QO6K,.C$%)H<&KNA*RF(IOWZ[NYK,!,UY<4
+M+(7M-")7CP&1Y2Y7U(A.W@(3GW<A5.6"6,K&?=&W#O]?``PV-ZA;0<CYN22^
+MEG#-R@QC`DR`5CT@,2(%`]>@<J4Y=2&FM,0E*UH`B((JEXPW4,**:69<M?40
+M3&:^3E4`(U*?Z;I37!>$JVLJ>$Q/.*T/<&HUOOS9?NSU6JCRJK_,K-)U\&%2
+MK;B3-E<6@%%6II9^/`US>U;$!&PEM>VNM<RDO*AC#CS+,0'_U/:E[Q)EMGD"
+MN45<8D'^Z$15X]I(5+`MJMEW243]2FF"4XLFP4]R5,H#%YJ!\]Y*%M97[BF`
+M%&6UB%95JL$0WL#7ADQ-1=S`+Z!X=DI!ZDM#70LZQMJC*H\]`#^OV"%/CJKV
+MU(G)J-]W8K2I2PN4M0"@.,REDT(T_X9Z)U)5L:4+DB5K7`;O"#+BW.I1Y%F3
+M?I@):D,,_DWJN!C](O_DVBN*2/9]KN#8U<>47D5%ELLM^\:*CKA,L/-X,G*2
+M#BS3(,U;!DEM7)L(W64%HXB-LT7QS"TY,H=!T!)/>S\<?@KU[1`0%M3X-$0.
+M9/H416.A6"*(H/;W1M88O`:ND![0S&6<MUS4::8]^U3XX[[@E5>#PIL1JO78
+M[1YP4*113SK._"B9\,=`;`CV<+='7];NZA8=C[1!1L/JV0Q+D#_D"0OG[KGN
+MB,"2T]H5H8L<TV((?[GCCK$ZE$3?N"CRY=E:I2)5^+=2XW4E2`OBI,XKAZC9
+M17L.%5L5M6<MK%!R3=1)JO^J9^H%;+U&Q.HUS/0Y,ZSR@&U[])L4\`_=)0)3
+M[US)[B[6V1%)%V15*];.3"WMBZ3:6?'%?C!M0:DQJGIAQWB&FW3">T"D:,Y,
+M]X]3+L4JHEL_E7G]S"@\7_%!K!)Z0Z;;B,`-J7CS?8SIBV:L%U9"M-CRF]6J
+M*)\949\A4I0<EJ/Y=D"_FPXL$FY&NB'PRU)8I%+2X;1F[KYZ667@OY[>A@!K
+M8PAFSH'.4#<COL[H:*BMQ,4A/Z3AN9_S3%;FB4JS=&-<I.[FW6_!R5"?`-\D
+M5MC@'G[1,=%^?5G=%)F:,F15HYIA6#/;V,\**&$%(*>.X4BG+GS%4I1'7<C@
+MZ"0WE%*OS$3O$GHPY(^3+F_WS>A4`^3\@8@.;Y*)UAB%O@O[C<8:+&;7V5K9
+M9,<M!#(Z-L&/@1G=4015[8=/G*?"RQ]1"5&E*W.AMJ^KXV**2!,3O+_('^J<
+ML8M=F-^5JUJ!)LE.5T:=ZW+TI9LZZR)U,,/&@)4XMT:L!/LBR>0%Q2$A)$M7
+MW$.6#6O@YXN`7-+-87.U@=Q'>7?W2A1#>"D3^&MPLI_`L2+49*78;!)"3(RJ
+M9/LRM:QC>E-JB(X+1Y;0NO/C6JSD7"6G!,[3:J](0:AG9:WICBM'?_4+@=$*
+M<^D&<D*LD"Y]N2^3&^5RG,DKJO_`H80D]]O5T<+M<S8X(=(&"P>Q;EN4F44E
+M7Q`.Q,WME)N;!'7@EE#>X.M,I8CT$;VTPY6;XY#U2>OLH\H`<DL^T/3S`L1E
+M6E0'GB?SKLXG@]#WJ];CUFD]ECF>,^G!JQ11-D=NS[^&(3O(HI3?F3E55I2K
+M+GBGG#?0R,.9^%JPI4->,'9XM.*4E;QXW([)"RHG;`KRJ$U>^NWSLGTW*"9D
+MXVSRC,]OF8)85,.?WG3"$UJY>\[#)GB^6DIXW!4D8\.C\HC>B45Z1E4\FKKF
+M*FKA,M]UJ05IH\2<CUD_AM0Y?4V0'GN#YU#7147TE3LA+**_*1:TB&H&VS]]
+MB1AXRF\867XNU$05>TZ.$PUWX)_Q+QQK#DJ`.MJ1*`7RNL9'JI9D);#-Z`A=
+M.>=\354X_5;40^:UPWNV&4*F]3K%&DLERKH8#,ATM(?":WN(M</$"++Y4DH"
+MNRPK006,DY8QZ50I9_2XZ^<7N0++X^>9%R/4:+G'<&[XE8]J!UO97A-571/"
+M=)K,R!>4FGX[#/*4J08*9^.GZ*&5:OC`#X12:M,V0":7MW[GYJ[<#>4"$??U
+M$R9I;9^29ZN"Q_1\`5D1>YP"D(D``U2S\C6CMRCZBNKE=:8P)\V/C_,1ICAH
+M_$(P[E(JAVWX=20^$01%BLB9!24,35/M;-'^UD6CWI39QUH3_5*:G>3"2>IA
+MOR7]W()N*R<^$1'5PI\JY2LRN-$NEB)AW?2R<+<R[;VLW+F4X)B?L^AHQ=.]
+MDXUWE'1+=Z"&?(0TWLD>H5ULNI&:)A'.B8#?D,->LB[+Q8(9?(9&O)YD%/V:
+MICF33W)3TB4K]YZVVR_`K<KQ)R6^H=#"ZP_YN*M(^B-!%6/P[RQS'^V1]W0(
+MP?A6,\0N,GQ7=EF%1?[$F*89`+6`OMN`WPJD00$T'Y)@OH(<ZR-=FSK+@=88
+M$$!V\$C&4YV>!3)Y7&^%5T>#J8)FE.4TD)SL,RX<,*JH1OT5"V81VTY"$>DD
+M%+%N!JS^Y\G<*0&R.<YH`-WY3D%0B6AQM$#VW-956"8T]OFNXVJ=6>O0226P
+M1?$1NE>J63W&GUN]/'&3&I3(0,3(U+.ELBV9U,MRYN4)2316P_5TM:`@JQ'X
+MH<PA\;^S9GW"A)&)CO;T5*Y34D52JRR,=@.$D\^4QAZ^("%A'6])C^!O,XZ9
+MQJ_)[!A_$BM?N5?$1'2J$,7IIFUU!;J:Z*IS^."=0?71*4N-M8E;N2)1+I*7
+M]<2-?DZ%NA2>8J6FC&),%BNHGD?6?,&I3"GFXK%M<T#N+CI%`TN=Y7%)6R;;
+M'380V:N9N>=+)`_*FR2YY8K!58<(<5?^&</?+\HA#\5EX9F7D;6\50+Q(!7V
+M(?TP@J'Y?"%\O&.WKJ3^]N3&IZR',T_<'D-"'TO\_4SB(U=G2(9T:2Y!)D-4
+MHB<Z.RVL:J,SGMU$!<7E;W%URANP<E@+ZVSM<BKE;3#[E,HBV.?E_H`:E.\.
+MY8MH0/K$S6(](:S+/=FBBU:9NE9,=0_P)0?JA[IQ`HUSM`K/M;S*_0XJOQ%[
+M90U).YT8FI7.U^4YF'?2GI-L\Q@41[!E\GMTRORQZV$'`^L(\TI4,IG9'"(<
+MMW]&T9FY8B#9LC`/7$ET%8LI?:0_"45BPKQ&4LR;:=''A\AZ^LY%8WTCT"`8
+M+QXV+;M6.#C#1*+5/);&L^_1Q3QG+NGC!O?=MOT8Z<^:$H!YO2ZML]KZ(E%=
+MB$]:H`(#;WQ[Z2_``$@UI[XA_+'@K+\,1F]I,V;E;TV)GK,28:)F+\[:PBT9
+MK=,RL.(JO;!M;9;;CG05%1Y@DW7WI)3KZ76WDZ^4S=W)+GL[,>3>#CS3G."%
+MU_'F2B,ATU\P+VP^!<&Z^!P68MFPLHF^7*PBWHD"$9/$J(OD)RC+(!*_AHWV
+M:QF5'BX0ML_+KZOU3/39D=T<V*EV1N'V"LGJWJ$A5>'&E*#FUZ'U@!2P1Z]^
+M2!V?I^#2$TC:N=,T.(,9FW84*56!AR]1`![JB:-R8C^&F3D[LPXZGL#`K2D7
+MK0*HG.RJLZ!/KZY>??0Z??W^!Y]\E+)A+XX6.#0%.#;!:$_Z]4.%_(NB]ELS
+M#<-K6F9]KJL02KD+(06KN@%G/I.-B$*+8LS@1,E]@,L3.WT)>E!$.`.HY_TI
+M"D[V&74$-B4D`T7"Y"2R"*G*P_[Y?9I68J[1RI*+17'DQ"D*\@&)SJ0.%;XA
+MJOGB7!&.MXDV5TJ_KW9K$I`4VE7*17/Y(6IXI_*&FQ-X'4`X?`<?%.`]*<:,
+M?9752`W"U;300DW"LMJ?IE4E$]N#+X&IR_!_=A:^=TXO(;GC`R6?,/J5JMA*
+M:^(]TJ<I'RK%1Q/0WG,)O/3L/^_GH:S1//%G03DL,@6Z2#X.$%9^BZ%`S8(-
+MBRRF\1K2LZQPLK`\Z&[E2"\<9:+FN`^R70;_6[HJIC#Q^#>1A'01EC9ROT\.
+M1Y2IH(@(Z.%VQ4B/"GE21091`<F=Q'-JYK+:<CMC[$$UN9F;ZH_1O8M+&;4;
+MO;XT#A77!6O#==O-F<_VA/%$;Y;K>XW*PNU$"N9BU8O$`ZSW)O[((.IAEH\G
+ME%OK9\4:E2M$3C^\!`C`I_@$9R?=*R*QMM=TYJSIXJN0J59"":?AXT%5RY+8
+M;MM?@K8:_0Q!=[*Y[O!V6HZ(CGQPB(0WX@(3AWB4)_;!>3B-.H_4LAJ1COK=
+M4PL>:R2M6AL.<N]+CQ8?->,\_2H275!X'Q!#^T:R9)ZNT!WW[]$S>CM6Z(C`
+MIXS2A)K];HOK:^LT^X!^N.FS[>,G'+K=HDY*(Z%/T8Z>Y6XN=1LB_+/4T$@P
+MJ@O;;D\XHGOYZ!99:JTF1D1,!G,,Y\I#11RM[CH]M9H(>]K*3;NCE6^$2V.;
+MQ1^4<1V<SV;)T[8,]^<$,/4P#+H==.+)'#-=-:*^+COW65:.$B;?]Q[0+3\.
+M^:\)T:=J_3+3DYS3C8(PL5'52,'76':<\Y'-#LE[=)Z9Q1,1ZO\GD\GA3\<9
+M<^5\1)P\BG8[J:Y7<AR9*]9QY!9_@)2]%R5`L5+&Z8?#.24^I46]MD]&)1($
+MU>`G$8^DO<.9J.:PG"B%W4X-RO*(\Z#"?'O?M:-IV'O,V,_EB1\]%G$;&?9R
+MY$\K,H,$W<>ZK;C@-S(*I#\Y$LLT&V[+2LZ$X)SD@\\IHQE8#FIU'L&0`^):
+MIO/`0(5E@8D9K0LFI>@BAHI?$9VQU])\8KJ28.,X.;L?4VQ)",697ZE.N:(L
+M1=-C^("@LD-AWYQ;>NQ#`R*B(#??9KDQ+Y\_^+1HZO_A6(@_D]A[V,UPE\V[
+MO9D<^`-X7RE:S2/$32>,04%!(PSZAEU;>$9]A%_V2H32(Y;APUF)^+"5+8S<
+MSH/)Y0?;S@.(40W+L@>G1MH-W\A^0T(@X>/77$*!S@/>A:(4NHDAAYH6-`^Y
+MT*"8/`G*XB/2:9_P#9\7W"?^F%A2#Y)3?LS3`HS8W`]+,G:=//__#Y+!Z6EZ
+#,P0`
+`
+end
diff --git a/lib/csu/alpha/Makefile b/lib/csu/alpha/Makefile
new file mode 100644
index 0000000..2c101c3
--- /dev/null
+++ b/lib/csu/alpha/Makefile
@@ -0,0 +1,26 @@
+#
+# $FreeBSD$
+#
+
+SRCS= crt1.c crtbegin.c crtend.c
+OBJS= crt1.o crtbegin.o crtend.o
+OBJS+= gcrt1.o
+SOBJS= crtbegin.So crtend.So
+CFLAGS+= -Wall -Wno-unused
+NOMAN= true
+NOPIC= true
+NOPROFILE= true
+INTERNALLIB= true
+
+all: ${OBJS} ${SOBJS}
+
+gcrt1.o: crt1.c
+ ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.CURDIR}/crt1.c
+
+realinstall:
+.for file in ${OBJS} ${SOBJS}
+ ${INSTALL} ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ ${file} ${DESTDIR}${LIBDIR}/${file:S/.So$/S.o/}
+.endfor
+
+.include <bsd.lib.mk>
diff --git a/lib/csu/alpha/crt1.c b/lib/csu/alpha/crt1.c
new file mode 100644
index 0000000..095effc
--- /dev/null
+++ b/lib/csu/alpha/crt1.c
@@ -0,0 +1,103 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ * Copyright (c) 1995 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __GNUC__
+#error "GCC is needed to compile this file"
+#endif
+
+#include <stdlib.h>
+
+struct Struct_Obj_Entry;
+struct ps_strings;
+
+#pragma weak _DYNAMIC
+extern int _DYNAMIC;
+
+extern void _init(void);
+extern void _fini(void);
+extern int main(int, char **, char **);
+
+#ifdef GCRT
+extern void _mcleanup(void);
+extern void monstartup(void *, void *);
+extern int eprol;
+extern int etext;
+#endif
+
+char **environ;
+char *__progname = "";
+
+/* The entry function. */
+void
+_start(char **ap,
+ void (*cleanup)(void), /* from shared loader */
+ struct Struct_Obj_Entry *obj, /* from shared loader */
+ struct ps_strings *ps_strings)
+{
+ int argc;
+ char **argv;
+ char **env;
+
+ argc = * (long *) ap;
+ argv = ap + 1;
+ env = ap + 2 + argc;
+ environ = env;
+ if(argc > 0 && argv[0] != NULL) {
+ char *s;
+ __progname = argv[0];
+ for (s = __progname; *s != '\0'; s++)
+ if (*s == '/')
+ __progname = s + 1;
+ }
+
+ if (&_DYNAMIC != NULL)
+ atexit(cleanup);
+
+#ifdef GCRT
+ atexit(_mcleanup);
+#endif
+ atexit(_fini);
+#ifdef GCRT
+ monstartup(&eprol, &etext);
+#endif
+ _init();
+ exit( main(argc, argv, env) );
+}
+
+#ifdef GCRT
+__asm__(".text");
+__asm__("eprol:");
+__asm__(".previous");
+#endif
diff --git a/lib/csu/alpha/crtbegin.c b/lib/csu/alpha/crtbegin.c
new file mode 100644
index 0000000..4cb2903
--- /dev/null
+++ b/lib/csu/alpha/crtbegin.c
@@ -0,0 +1,77 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+typedef void (*fptr)(void);
+
+static fptr ctor_list[1] __attribute__((section(".ctors"))) = { (fptr) -1 };
+static fptr dtor_list[1] __attribute__((section(".dtors"))) = { (fptr) -1 };
+
+/* Both do_ctors() and do_dtors() live in .text (the default) */
+static void
+do_ctors(void)
+{
+ fptr *fpp;
+
+ for(fpp = ctor_list + 1; *fpp != 0; ++fpp)
+ (**fpp)();
+}
+
+static void
+do_dtors(void)
+{
+ fptr *fpp;
+
+ for(fpp = dtor_list + 1; *fpp != 0; ++fpp)
+ ;
+ while(--fpp > dtor_list)
+ (**fpp)();
+}
+
+/*
+ * On very large programs, it is possible to get a relocation overflow
+ * of the 21-bit BSR displacements. It is particularly likely for the
+ * calls from _init() and _fini(), because they are in separate sections.
+ * Avoid the problem by forcing indirect calls.
+ */
+static void (*p_do_ctors)(void) = do_ctors;
+static void (*p_do_dtors)(void) = do_dtors;
+
+extern void _init(void) __attribute__((section(".init")));
+
+void
+_init(void)
+{
+ (*p_do_ctors)();
+}
+
+extern void _fini(void) __attribute__((section(".fini")));
+
+void
+_fini(void)
+{
+ (*p_do_dtors)();
+}
diff --git a/lib/csu/alpha/crtend.c b/lib/csu/alpha/crtend.c
new file mode 100644
index 0000000..d6228a3
--- /dev/null
+++ b/lib/csu/alpha/crtend.c
@@ -0,0 +1,31 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+typedef void (*fptr)(void);
+
+static fptr ctor_end[1] __attribute__((section(".ctors"))) = { 0 };
+static fptr dtor_end[1] __attribute__((section(".dtors"))) = { 0 };
diff --git a/lib/csu/amd64/Makefile b/lib/csu/amd64/Makefile
new file mode 100644
index 0000000..50686fe
--- /dev/null
+++ b/lib/csu/amd64/Makefile
@@ -0,0 +1,27 @@
+#
+# $FreeBSD$
+#
+
+SRCS= crt1.c crtbegin.c crtend.c crti.S crtn.S
+OBJS= ${SRCS:N*.h:R:S/$/.o/g}
+OBJS+= gcrt1.o
+SOBJS= crtbegin.So crtend.So
+CFLAGS+= -elf -Wall -fkeep-inline-functions
+LDFLAGS+= -elf
+NOMAN= true
+NOPIC= true
+NOPROFILE= true
+INTERNALLIB= true
+
+all: ${OBJS} ${SOBJS}
+
+gcrt1.o: crt1.c
+ ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.CURDIR}/crt1.c
+
+realinstall:
+.for file in ${OBJS} ${SOBJS}
+ ${INSTALL} ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ ${file} ${DESTDIR}${LIBDIR}/${file:S/.So$/S.o/}
+.endfor
+
+.include <bsd.lib.mk>
diff --git a/lib/csu/amd64/crt1.c b/lib/csu/amd64/crt1.c
new file mode 100644
index 0000000..0ee0702
--- /dev/null
+++ b/lib/csu/amd64/crt1.c
@@ -0,0 +1,102 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __GNUC__
+#error "GCC is needed to compile this file"
+#endif
+
+#include <stddef.h>
+#include <stdlib.h>
+
+typedef void (*fptr)(void);
+
+extern void _fini(void);
+extern void _init(void);
+extern int main(int, char **, char **);
+
+#ifdef GCRT
+extern void _mcleanup(void);
+extern void monstartup(void *, void *);
+extern int eprol;
+extern int etext;
+#endif
+
+extern int _DYNAMIC;
+#pragma weak _DYNAMIC
+
+#ifdef __i386__
+#define get_rtld_cleanup() \
+ ({ fptr __value; \
+ __asm__("movl %%edx,%0" : "=rm"(__value)); \
+ __value; })
+#else
+#error "This file only supports the i386 architecture"
+#endif
+
+char **environ;
+char *__progname = "";
+
+void
+_start(char *arguments, ...)
+{
+ fptr rtld_cleanup;
+ int argc;
+ char **argv;
+ char **env;
+
+ rtld_cleanup = get_rtld_cleanup();
+ argv = &arguments;
+ argc = * (int *) (argv - 1);
+ env = argv + argc + 1;
+ environ = env;
+ if(argc > 0 && argv[0] != NULL) {
+ char *s;
+ __progname = argv[0];
+ for (s = __progname; *s != '\0'; s++)
+ if (*s == '/')
+ __progname = s + 1;
+ }
+
+ if(&_DYNAMIC != NULL)
+ atexit(rtld_cleanup);
+
+#ifdef GCRT
+ atexit(_mcleanup);
+#endif
+ atexit(_fini);
+#ifdef GCRT
+ monstartup(&eprol, &etext);
+#endif
+ _init();
+ exit( main(argc, argv, env) );
+}
+
+#ifdef GCRT
+__asm__(".text");
+__asm__("eprol:");
+__asm__(".previous");
+#endif
diff --git a/lib/csu/amd64/crti.S b/lib/csu/amd64/crti.S
new file mode 100644
index 0000000..0038497
--- /dev/null
+++ b/lib/csu/amd64/crti.S
@@ -0,0 +1,38 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+ .section .init,"ax",@progbits
+ .align 4
+ .globl _init
+ .type _init,@function
+_init:
+
+ .section .fini,"ax",@progbits
+ .align 4
+ .globl _fini
+ .type _fini,@function
+_fini:
diff --git a/lib/csu/amd64/crtn.S b/lib/csu/amd64/crtn.S
new file mode 100644
index 0000000..0944ee3
--- /dev/null
+++ b/lib/csu/amd64/crtn.S
@@ -0,0 +1,32 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+ .section .init,"ax",@progbits
+ ret
+
+ .section .fini,"ax",@progbits
+ ret
diff --git a/lib/csu/common/crtbegin.c b/lib/csu/common/crtbegin.c
new file mode 100644
index 0000000..7c1f11e
--- /dev/null
+++ b/lib/csu/common/crtbegin.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+
+typedef void (*fptr)(void);
+
+static fptr ctor_list[1] __attribute__((section(".ctors"))) = { (fptr) -1 };
+static fptr dtor_list[1] __attribute__((section(".dtors"))) = { (fptr) -1 };
+
+static void do_ctors(void) __unused;
+static void do_dtors(void) __unused;
+
+static void
+do_ctors(void)
+{
+ fptr *fpp;
+
+ for(fpp = ctor_list + 1; *fpp != 0; ++fpp)
+ ;
+ while(--fpp > ctor_list)
+ (**fpp)();
+}
+
+static void
+do_dtors(void)
+{
+ fptr *fpp;
+
+ for(fpp = dtor_list + 1; *fpp != 0; ++fpp)
+ (**fpp)();
+}
+
+__asm__(".section .init,\"ax\",@progbits; call do_ctors; .previous");
+__asm__(".section .fini,\"ax\",@progbits; call do_dtors; .previous");
diff --git a/lib/csu/common/crtend.c b/lib/csu/common/crtend.c
new file mode 100644
index 0000000..4b33f0c
--- /dev/null
+++ b/lib/csu/common/crtend.c
@@ -0,0 +1,33 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+
+typedef void (*fptr)(void);
+
+static fptr ctor_end[1] __attribute__((section(".ctors"))) __unused = { 0 };
+static fptr dtor_end[1] __attribute__((section(".dtors"))) __unused = { 0 };
diff --git a/lib/csu/i386-elf/Makefile b/lib/csu/i386-elf/Makefile
new file mode 100644
index 0000000..50686fe
--- /dev/null
+++ b/lib/csu/i386-elf/Makefile
@@ -0,0 +1,27 @@
+#
+# $FreeBSD$
+#
+
+SRCS= crt1.c crtbegin.c crtend.c crti.S crtn.S
+OBJS= ${SRCS:N*.h:R:S/$/.o/g}
+OBJS+= gcrt1.o
+SOBJS= crtbegin.So crtend.So
+CFLAGS+= -elf -Wall -fkeep-inline-functions
+LDFLAGS+= -elf
+NOMAN= true
+NOPIC= true
+NOPROFILE= true
+INTERNALLIB= true
+
+all: ${OBJS} ${SOBJS}
+
+gcrt1.o: crt1.c
+ ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.CURDIR}/crt1.c
+
+realinstall:
+.for file in ${OBJS} ${SOBJS}
+ ${INSTALL} ${COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ ${file} ${DESTDIR}${LIBDIR}/${file:S/.So$/S.o/}
+.endfor
+
+.include <bsd.lib.mk>
diff --git a/lib/csu/i386-elf/crt1.c b/lib/csu/i386-elf/crt1.c
new file mode 100644
index 0000000..0ee0702
--- /dev/null
+++ b/lib/csu/i386-elf/crt1.c
@@ -0,0 +1,102 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __GNUC__
+#error "GCC is needed to compile this file"
+#endif
+
+#include <stddef.h>
+#include <stdlib.h>
+
+typedef void (*fptr)(void);
+
+extern void _fini(void);
+extern void _init(void);
+extern int main(int, char **, char **);
+
+#ifdef GCRT
+extern void _mcleanup(void);
+extern void monstartup(void *, void *);
+extern int eprol;
+extern int etext;
+#endif
+
+extern int _DYNAMIC;
+#pragma weak _DYNAMIC
+
+#ifdef __i386__
+#define get_rtld_cleanup() \
+ ({ fptr __value; \
+ __asm__("movl %%edx,%0" : "=rm"(__value)); \
+ __value; })
+#else
+#error "This file only supports the i386 architecture"
+#endif
+
+char **environ;
+char *__progname = "";
+
+void
+_start(char *arguments, ...)
+{
+ fptr rtld_cleanup;
+ int argc;
+ char **argv;
+ char **env;
+
+ rtld_cleanup = get_rtld_cleanup();
+ argv = &arguments;
+ argc = * (int *) (argv - 1);
+ env = argv + argc + 1;
+ environ = env;
+ if(argc > 0 && argv[0] != NULL) {
+ char *s;
+ __progname = argv[0];
+ for (s = __progname; *s != '\0'; s++)
+ if (*s == '/')
+ __progname = s + 1;
+ }
+
+ if(&_DYNAMIC != NULL)
+ atexit(rtld_cleanup);
+
+#ifdef GCRT
+ atexit(_mcleanup);
+#endif
+ atexit(_fini);
+#ifdef GCRT
+ monstartup(&eprol, &etext);
+#endif
+ _init();
+ exit( main(argc, argv, env) );
+}
+
+#ifdef GCRT
+__asm__(".text");
+__asm__("eprol:");
+__asm__(".previous");
+#endif
diff --git a/lib/csu/i386-elf/crtbegin.c b/lib/csu/i386-elf/crtbegin.c
new file mode 100644
index 0000000..7c1f11e
--- /dev/null
+++ b/lib/csu/i386-elf/crtbegin.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+
+typedef void (*fptr)(void);
+
+static fptr ctor_list[1] __attribute__((section(".ctors"))) = { (fptr) -1 };
+static fptr dtor_list[1] __attribute__((section(".dtors"))) = { (fptr) -1 };
+
+static void do_ctors(void) __unused;
+static void do_dtors(void) __unused;
+
+static void
+do_ctors(void)
+{
+ fptr *fpp;
+
+ for(fpp = ctor_list + 1; *fpp != 0; ++fpp)
+ ;
+ while(--fpp > ctor_list)
+ (**fpp)();
+}
+
+static void
+do_dtors(void)
+{
+ fptr *fpp;
+
+ for(fpp = dtor_list + 1; *fpp != 0; ++fpp)
+ (**fpp)();
+}
+
+__asm__(".section .init,\"ax\",@progbits; call do_ctors; .previous");
+__asm__(".section .fini,\"ax\",@progbits; call do_dtors; .previous");
diff --git a/lib/csu/i386-elf/crtend.c b/lib/csu/i386-elf/crtend.c
new file mode 100644
index 0000000..4b33f0c
--- /dev/null
+++ b/lib/csu/i386-elf/crtend.c
@@ -0,0 +1,33 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+
+typedef void (*fptr)(void);
+
+static fptr ctor_end[1] __attribute__((section(".ctors"))) __unused = { 0 };
+static fptr dtor_end[1] __attribute__((section(".dtors"))) __unused = { 0 };
diff --git a/lib/csu/i386-elf/crti.S b/lib/csu/i386-elf/crti.S
new file mode 100644
index 0000000..0038497
--- /dev/null
+++ b/lib/csu/i386-elf/crti.S
@@ -0,0 +1,38 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+ .section .init,"ax",@progbits
+ .align 4
+ .globl _init
+ .type _init,@function
+_init:
+
+ .section .fini,"ax",@progbits
+ .align 4
+ .globl _fini
+ .type _fini,@function
+_fini:
diff --git a/lib/csu/i386-elf/crtn.S b/lib/csu/i386-elf/crtn.S
new file mode 100644
index 0000000..0944ee3
--- /dev/null
+++ b/lib/csu/i386-elf/crtn.S
@@ -0,0 +1,32 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+ .section .init,"ax",@progbits
+ ret
+
+ .section .fini,"ax",@progbits
+ ret
diff --git a/lib/csu/i386/Makefile b/lib/csu/i386/Makefile
new file mode 100644
index 0000000..02f14f2
--- /dev/null
+++ b/lib/csu/i386/Makefile
@@ -0,0 +1,58 @@
+# from: @(#)Makefile 5.6 (Berkeley) 5/22/91
+# $FreeBSD$
+
+CFLAGS+= -DLIBC_SCCS -fno-omit-frame-pointer
+OBJS= crt0.o c++rt0.o gcrt0.o scrt0.o sgcrt0.o
+CLEANFILES= a.out crt0.o.tmp c++rt0.o.tmp gcrt0.o.tmp scrt0.o.tmp \
+ sgcrt0.o.tmp
+
+all: ${OBJS}
+
+crt0.o: crt0.c
+ ${CC} ${CFLAGS} -c -DCRT0 -DDYNAMIC ${.CURDIR}/crt0.c -o ${.TARGET}
+ ${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
+ @mv ${.TARGET}.tmp ${.TARGET}
+
+c++rt0.o: c++rt0.c
+ ${CC} ${CFLAGS} -fpic -c ${.CURDIR}/c++rt0.c
+ @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
+ @mv ${.TARGET}.tmp ${.TARGET}
+
+#
+# gcrt0.o doesn't really depend on crt0.o, but this is the easiest way
+# to get the dependencies mostly correct.
+#
+gcrt0.o: crt0.o
+ ${CC} ${CFLAGS} -c -DMCRT0 -DDYNAMIC ${.CURDIR}/crt0.c -o ${.TARGET}
+ @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
+ @mv ${.TARGET}.tmp ${.TARGET}
+
+# dependencies fudged as for gcrt0.o
+scrt0.o: crt0.o
+ ${CC} ${CFLAGS} -c -DCRT0 ${.CURDIR}/crt0.c -o ${.TARGET}
+ @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
+ @mv ${.TARGET}.tmp ${.TARGET}
+
+# dependencies fudged as for gcrt0.o
+sgcrt0.o: scrt0.o
+ ${CC} ${CFLAGS} -c -DMCRT0 ${.CURDIR}/crt0.c -o ${.TARGET}
+ @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
+ @mv ${.TARGET}.tmp ${.TARGET}
+
+realinstall:
+ ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m 444 ${OBJS} \
+ ${DESTDIR}${LIBDIR}
+
+depend: .depend
+
+.depend: crt0.c c++rt0.c
+ rm -f .depend
+ mkdep ${CFLAGS} -DCRT0 -DDYNAMIC ${.CURDIR}/crt0.c
+ mkdep -a ${CFLAGS} ${.CURDIR}/c++rt0.c
+
+cleandepend:
+ rm -f .depend
+
+lint tags:
+
+.include <bsd.prog.mk>
diff --git a/lib/csu/i386/c++rt0.c b/lib/csu/i386/c++rt0.c
new file mode 100644
index 0000000..39752d5
--- /dev/null
+++ b/lib/csu/i386/c++rt0.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1993 Paul Kranenburg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Run-time module for GNU C++ compiled shared libraries.
+ *
+ * The linker constructs the following arrays of pointers to global
+ * constructors and destructors. The first element contains the
+ * number of pointers in each.
+ * The tables are also null-terminated.
+ */
+extern void (*__CTOR_LIST__[])(void);
+extern void (*__DTOR_LIST__[])(void);
+
+static void
+__dtors(void)
+{
+ unsigned long i = (unsigned long) __DTOR_LIST__[0];
+ void (**p)(void) = __DTOR_LIST__ + i;
+
+ while (i--)
+ (**p--)();
+}
+
+static void
+__ctors(void)
+{
+ void (**p)(void) = __CTOR_LIST__ + 1;
+
+ while (*p)
+ (**p++)();
+}
+
+extern void __init() asm(".init");
+extern void __fini() asm(".fini");
+
+void
+__init(void)
+{
+ static int initialized = 0;
+
+ /*
+ * Call global constructors.
+ * Arrange to call global destructors at exit.
+ */
+ if (!initialized) {
+ initialized = 1;
+ __ctors();
+ }
+
+}
+
+void
+__fini(void)
+{
+ __dtors();
+}
+
+/*
+ * Make sure there is at least one constructor and one destructor in the
+ * shared library. Otherwise, the linker does not realize that the
+ * constructor and destructor lists are linker sets. It treats them as
+ * commons and resolves them to the lists from the main program. That
+ * causes multiple invocations of the main program's static constructors
+ * and destructors, which is very bad.
+ */
+
+static void
+do_nothing(void)
+{
+}
+
+/* Linker magic to add an element to a constructor or destructor list. */
+#define TEXT_SET(set, sym) \
+ asm(".stabs \"_" #set "\", 23, 0, 0, _" #sym)
+
+TEXT_SET(__CTOR_LIST__, do_nothing);
+TEXT_SET(__DTOR_LIST__, do_nothing);
diff --git a/lib/csu/i386/crt0.c b/lib/csu/i386/crt0.c
new file mode 100644
index 0000000..e1a5551
--- /dev/null
+++ b/lib/csu/i386/crt0.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 1993 Paul Kranenburg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+
+#include <stdlib.h>
+
+#ifdef DYNAMIC
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <a.out.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <link.h>
+
+/* !!!
+ * This is gross, ld.so is a ZMAGIC a.out, but has `sizeof(hdr)' for
+ * an entry point and not at PAGSIZ as the N_*ADDR macros assume.
+ */
+#undef N_DATADDR
+#define N_DATADDR(x) ((x).a_text)
+
+#undef N_BSSADDR
+#define N_BSSADDR(x) ((x).a_text + (x).a_data)
+
+#ifndef N_GETMAGIC
+#define N_GETMAGIC(x) ((x).a_magic)
+#endif /* N_GETMAGIC */
+
+#ifndef MAP_PRIVATE
+#define MAP_PRIVATE MAP_COPY
+#endif /* MAP_PRIVATE */
+
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif /* MAP_FILE */
+
+#ifndef MAP_ANON
+#define MAP_ANON 0
+#endif /* MAP_ANON */
+
+#ifdef DEBUG
+/*
+ * We need these two because we are going to call them before the ld.so is
+ * finished (as a matter of fact before we know if it exists !) so we must
+ * provide these versions for them
+ */
+static char *_getenv();
+static int _strncmp();
+#endif /* DEBUG */
+
+#ifndef LDSO
+#define LDSO "/usr/libexec/ld.so"
+#endif /* LDSO */
+
+extern struct _dynamic _DYNAMIC;
+static void __do_dynamic_link(char **argv);
+#endif /* DYNAMIC */
+
+int _callmain();
+int errno;
+static char empty[1];
+char *__progname = empty;
+char **environ;
+
+/* Globals used by dlopen() and related functions in libc */
+struct ld_entry *__ldso_entry;
+int __ldso_version;
+
+extern unsigned char etext;
+extern unsigned char eprol asm ("eprol");
+extern start() asm("start");
+extern mcount() asm ("mcount");
+extern int main(int argc, char **argv, char **envp);
+int __syscall(int syscall,...);
+#ifdef MCRT0
+void monstartup(void *low, void *high);
+#endif /* MCRT0 */
+
+
+/*
+ * We need these system calls, but can't use library stubs because the are
+ * not accessible until we have done the ld.so stunt.
+ */
+
+#define _exit(v) \
+ __syscall(SYS_exit, (int)(v))
+#define _open(name, f, m) \
+ __syscall(SYS_open, (const char *)(name), (int)(f), (int)(m))
+#define _read(fd, s, n) \
+ __syscall(SYS_read, (int)(fd), (void *)(s), (size_t)(n))
+#define _write(fd, s, n) \
+ __syscall(SYS_write, (int)(fd), (const void *)(s), (size_t)(n))
+#define _mmap(addr, len, prot, flags, fd, off) \
+ (void *) __syscall(SYS_mmap, (void *)(addr), (size_t)(len), \
+ (int)(prot), (int)(flags), (int)(fd), 0, (off_t)(off))
+
+#define _PUTNMSG(str, len) _write(2, (str), (len))
+#define _PUTMSG(str) _PUTNMSG((str), sizeof (str) - 1)
+#define _FATAL(str) ( _PUTMSG(str), _exit(1) )
+
+
+int
+start()
+{
+ struct kframe {
+ int kargc;
+ char *kargv[1]; /* size depends on kargc */
+ char kargstr[1]; /* size varies */
+ char kenvstr[1]; /* size varies */
+ };
+ /*
+ * ALL REGISTER VARIABLES!!!
+ */
+ register struct kframe *kfp;
+ register char **targv;
+ register char **argv;
+ extern void _mcleanup();
+#ifdef DYNAMIC
+ volatile caddr_t x;
+#endif
+
+#ifdef lint
+ kfp = 0;
+#else /* not lint */
+ /* just above the saved frame pointer */
+ asm ("lea 4(%%ebp), %0" : "=r" (kfp) );
+#endif /* not lint */
+ for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
+ /* void */ ;
+ if (targv >= (char **)(*argv))
+ --targv;
+ environ = targv;
+
+ if (argv[0]) {
+ register char *s;
+ __progname = argv[0];
+ for (s=__progname; *s != '\0'; s++)
+ if (*s == '/')
+ __progname = s+1;
+ }
+
+#ifdef DYNAMIC
+ /* ld(1) convention: if DYNAMIC = 0 then statically linked */
+ /* sometimes GCC is too smart/stupid for its own good */
+ x = (caddr_t)&_DYNAMIC;
+ if (x)
+ __do_dynamic_link(argv);
+#endif /* DYNAMIC */
+
+asm("eprol:");
+
+#ifdef MCRT0
+ atexit(_mcleanup);
+ monstartup(&eprol, &etext);
+#endif /* MCRT0 */
+
+asm ("__callmain:"); /* Defined for the benefit of debuggers */
+ exit(main(kfp->kargc, argv, environ));
+}
+
+#ifdef DYNAMIC
+static void
+__do_dynamic_link(argv)
+ char **argv;
+{
+ struct crt_ldso crt;
+ struct exec hdr;
+ char *ldso;
+ int (*entry)();
+
+#ifdef DEBUG
+ /* Provision for alternate ld.so - security risk! */
+ if (!(ldso = _getenv("LDSO")))
+#endif
+ ldso = LDSO;
+
+ crt.crt_ldfd = _open(ldso, 0, 0);
+ if (crt.crt_ldfd == -1) {
+ _PUTMSG("Couldn't open ");
+ _PUTMSG(LDSO);
+ _FATAL(".\n");
+ }
+
+ /* Read LDSO exec header */
+ if (_read(crt.crt_ldfd, &hdr, sizeof hdr) < sizeof hdr) {
+ _FATAL("Failure reading ld.so\n");
+ }
+ if ((N_GETMAGIC_NET(hdr) != ZMAGIC) && (N_GETMAGIC(hdr) != QMAGIC)) {
+ _FATAL("Bad magic: ld.so\n");
+ }
+
+ /* We use MAP_ANON */
+ crt.crt_dzfd = -1;
+
+ /* Map in ld.so */
+ crt.crt_ba = (int)_mmap(0, hdr.a_text,
+ PROT_READ|PROT_EXEC,
+ MAP_FILE|MAP_PRIVATE,
+ crt.crt_ldfd, N_TXTOFF(hdr));
+ if (crt.crt_ba == -1) {
+ _FATAL("Cannot map ld.so (text)\n");
+ }
+
+ /* Map in data segment of ld.so writable */
+ if ((int)_mmap((caddr_t)(crt.crt_ba+N_DATADDR(hdr)), hdr.a_data,
+ PROT_READ|PROT_WRITE,
+ MAP_FIXED|MAP_FILE|MAP_PRIVATE,
+ crt.crt_ldfd, N_DATOFF(hdr)) == -1) {
+ _FATAL("Cannot map ld.so (data)\n");
+ }
+
+ /* Map bss segment of ld.so zero */
+ if (hdr.a_bss && (int)_mmap((caddr_t)(crt.crt_ba+N_BSSADDR(hdr)),
+ hdr.a_bss,
+ PROT_READ|PROT_WRITE,
+ MAP_FIXED|MAP_ANON|MAP_PRIVATE,
+ crt.crt_dzfd, 0) == -1) {
+ _FATAL("Cannot map ld.so (bss)\n");
+ }
+
+ crt.crt_dp = &_DYNAMIC;
+ crt.crt_ep = environ;
+ crt.crt_bp = (caddr_t)_callmain;
+ crt.crt_prog = __progname;
+ crt.crt_ldso = ldso;
+ crt.crt_ldentry = NULL;
+ crt.crt_argv = argv;
+
+ entry = (int (*)())(crt.crt_ba + sizeof hdr);
+ __ldso_version = (*entry)(CRT_VERSION_BSD_5, &crt);
+ __ldso_entry = crt.crt_ldentry;
+ if (__ldso_version == -1 && __ldso_entry == NULL) {
+ /* If version 5 not recognised, try version 4 */
+ __ldso_version = (*entry)(CRT_VERSION_BSD_4, &crt);
+ __ldso_entry = crt.crt_ldentry;
+ if (__ldso_version == -1 && __ldso_entry == NULL) {
+ /* if version 4 not recognised, try version 3 */
+ __ldso_version = (*entry)(CRT_VERSION_BSD_3, &crt);
+ __ldso_entry = _DYNAMIC.d_entry;
+ }
+ }
+ if (__ldso_version == -1) {
+ _PUTMSG("ld.so failed");
+ if (__ldso_entry != NULL) {
+ const char *msg = (__ldso_entry->dlerror)();
+ if(msg != NULL) {
+ const char *endp;
+ _PUTMSG(": ");
+ for(endp = msg; *endp != '\0'; ++endp)
+ ; /* Find the end */
+ _PUTNMSG(msg, endp - msg);
+ }
+ }
+ _FATAL("\n");
+ }
+
+
+ if (__ldso_version >= LDSO_VERSION_HAS_DLEXIT)
+ atexit(__ldso_entry->dlexit);
+
+ return;
+}
+
+/*
+ * Support routines
+ */
+
+#ifdef DEBUG
+static int
+_strncmp(s1, s2, n)
+ register char *s1, *s2;
+ register n;
+{
+
+ if (n == 0)
+ return (0);
+ do {
+ if (*s1 != *s2++)
+ return (*(unsigned char *)s1 - *(unsigned char *)--s2);
+ if (*s1++ == 0)
+ break;
+ } while (--n != 0);
+ return (0);
+}
+
+static char *
+_getenv(name)
+ register char *name;
+{
+ extern char **environ;
+ register int len;
+ register char **P, *C;
+
+ for (C = name, len = 0; *C && *C != '='; ++C, ++len);
+ for (P = environ; *P; ++P)
+ if (!_strncmp(*P, name, len))
+ if (*(C = *P + len) == '=') {
+ return(++C);
+ }
+ return (char *)0;
+}
+
+#endif /* DEBUG */
+
+ asm(" ___syscall:");
+ asm(" popl %ecx");
+ asm(" popl %eax");
+ asm(" pushl %ecx");
+ asm(" .byte 0x9a");
+ asm(" .long 0");
+ asm(" .word 7");
+ asm(" pushl %ecx");
+ asm(" jc 1f");
+ asm(" ret");
+ asm(" 1:");
+ asm(" movl $-1,%eax");
+ asm(" ret");
+
+#endif /* DYNAMIC */
+
+
+/*
+ * Support routines
+ */
+
+#ifdef MCRT0
+asm (" .text");
+asm ("_eprol:");
+#endif
diff --git a/lib/libalias/HISTORY b/lib/libalias/HISTORY
new file mode 100644
index 0000000..575d1b4
--- /dev/null
+++ b/lib/libalias/HISTORY
@@ -0,0 +1,134 @@
+Version 1.0: August 11, 1996 (cjm)
+
+Version 1.1: August 20, 1996 (cjm)
+ - Host accepts incoming connections for ports 0 to 1023.
+
+Version 1.2: September 7, 1996 (cjm)
+ - Fragment handling error in alias_db.c corrected.
+
+Version 1.3: September 15, 1996 (cjm)
+ - Generalized mechanism for handling incoming
+ connections (no more 0 to 1023 restriction).
+
+ - Increased ICMP support (will handle traceroute now).
+
+ - Improved TCP close connection logic.
+
+Version 1.4: September 16, 1996 (cjm)
+
+Version 1.5: September 17, 1996 (cjm)
+ - Corrected error in handling incoming UDP packets
+ with zero checksum.
+
+Version 1.6: September 18, 1996
+ - Simplified ICMP data storage. Will now handle
+ tracert from Win95 and NT as well as FreeBSD
+ traceroute, which uses UDP packets to non-existent
+ ports.
+
+Verstion 1.7: January 9, 1997 (cjm)
+ - Reduced malloc() activity for ICMP echo and
+ timestamp requests.
+
+ - Added handling for out-of-order IP fragments.
+
+ - Switched to differential checksum computation
+ for IP headers (TCP, UDP and ICMP checksums
+ were already differential).
+
+ - Accepts FTP data connections from other than
+ port 20. This allows one ftp connections
+ from two hosts which are both running packet
+ aliasing.
+
+ - Checksum error on FTP transfers. Problem
+ in code located by Martin Renters and
+ Brian Somers.
+
+Version 1.8: January 14, 1997 (cjm)
+ - Fixed data type error in function StartPoint()
+ in alias_db.c (this bug did not exist before v1.7)
+ Problem in code located by Ari Suutari.
+
+Version 1.9: February 1, 1997 (Eivind Eklund <perhaps@yes.no>)
+ - Added support for IRC DCC (ee)
+
+ - Changed the aliasing routines to use ANSI style
+ throughout (ee)
+
+ - Minor API changes for integration with other
+ programs than PPP (ee)
+
+ - Fixed minor security hole in alias_ftp.c for
+ other applications of the aliasing software.
+ Hole could _not_ manifest in ppp+pktAlias, but
+ could potentially manifest in other applications
+ of the aliasing. (ee)
+
+ - Connections initiated from packet aliasing
+ host machine will not have their port number
+ aliased unless it conflicts with an aliasing
+ port already being used. (There is an option
+ to disable this for debugging) (cjm)
+
+ - Sockets will be allocated in cases where
+ there might be port interference with the
+ host machine. This can be disabled in cases
+ where the ppp host will be acting purely as a
+ masquerading router and not generate any
+ traffic of its own.
+ (cjm)
+
+Version 2.0: March, 1997 (cjm)
+ - Aliasing links are cleared only when a host interface address
+ changes.
+
+ - PacketAliasPermanentLink() API added.
+
+ - Option for only aliasing private, unregistered
+ IP addresses added.
+
+ - Substantial rework to the aliasing lookup engine.
+
+Version 2.1: May, 1997 (cjm)
+ - Continuing rework to the aliasing lookup engine
+ to support multiple incoming addresses and static
+ NAT. PacketAliasRedirectPort() and
+ PacketAliasRedirectAddr() added to API.
+
+ - Now supports outgoing as well as incoming ICMP
+ error messges.
+
+Version 2.2: July, 1997 (cjm)
+ - Rationalized API function names to all begin with
+ "PacketAlias..." Old function names are retained
+ for backwards compatitibility.
+
+ - Packet aliasing engine will now free memory of
+ fragments which are never resolved after a timeout
+ period. Once a fragment is resolved, it becomes
+ the users responsibility to free the memory.
+
+Version 2.3: August 11, 1997 (cjm)
+ - Problem associated with socket file descriptor
+ accumulation in alias_db.c corrected. The sockets
+ had to be closed when a binding failed. Problem
+ in code located by Gordon Burditt.
+
+Version 2.4: September 1, 1997 (cjm)
+ - PKT_ALIAS_UNREGISTERED_ONLY option repaired.
+ This part of the code was incorrectly re-implemented
+ in version 2.1.
+
+Version 2.5: December, 1997 (ee)
+ - Added PKT_ALIAS_PUNCH_FW mode for firewall
+ bypass of FTP/IRC DCC data connections. Also added
+ improved TCP connection monitoring.
+
+Version 2.6: May, 1998 (amurai)
+ - Added supporting routine for NetBios over TCP/IP.
+
+Version 3.0: January 1, 1999
+ - Transparent proxying support added.
+ - PPTP redirecting support added based on patches
+ contributed by Dru Nelson <dnelson@redwoodsoft.com>.
diff --git a/lib/libalias/Makefile b/lib/libalias/Makefile
new file mode 100644
index 0000000..e540648
--- /dev/null
+++ b/lib/libalias/Makefile
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+LIB= alias
+SHLIB_MAJOR= 3
+SHLIB_MINOR= 0
+CFLAGS+= -Wall -I${.CURDIR}
+SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \
+ alias_nbt.c alias_proxy.c alias_util.c
+MAN3= libalias.3
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/alias.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libalias/alias.c b/lib/libalias/alias.c
new file mode 100644
index 0000000..9c072df
--- /dev/null
+++ b/lib/libalias/alias.c
@@ -0,0 +1,1335 @@
+/* -*- mode: c; tab-width: 8; c-basic-indent: 4; -*- */
+/*
+ Alias.c provides supervisory control for the functions of the
+ packet aliasing software. It consists of routines to monitor
+ TCP connection state, protocol-specific aliasing routines,
+ fragment handling and the following outside world functional
+ interfaces: SaveFragmentPtr, GetFragmentPtr, FragmentAliasIn,
+ PacketAliasIn and PacketAliasOut.
+
+ The other C program files are briefly described. The data
+ structure framework which holds information needed to translate
+ packets is encapsulated in alias_db.c. Data is accessed by
+ function calls, so other segments of the program need not know
+ about the underlying data structures. Alias_ftp.c contains
+ special code for modifying the ftp PORT command used to establish
+ data connections, while alias_irc.c do the same for IRC
+ DCC. Alias_util.c contains a few utility routines.
+
+ This software is placed into the public domain with no restrictions
+ on its distribution.
+
+ Version 1.0 August, 1996 (cjm)
+
+ Version 1.1 August 20, 1996 (cjm)
+ PPP host accepts incoming connections for ports 0 to 1023.
+ (Gary Roberts pointed out the need to handle incoming
+ connections.)
+
+ Version 1.2 September 7, 1996 (cjm)
+ Fragment handling error in alias_db.c corrected.
+ (Tom Torrance helped fix this problem.)
+
+ Version 1.4 September 16, 1996 (cjm)
+ - A more generalized method for handling incoming
+ connections, without the 0-1023 restriction, is
+ implemented in alias_db.c
+ - Improved ICMP support in alias.c. Traceroute
+ packet streams can now be correctly aliased.
+ - TCP connection closing logic simplified in
+ alias.c and now allows for additional 1 minute
+ "grace period" after FIN or RST is observed.
+
+ Version 1.5 September 17, 1996 (cjm)
+ Corrected error in handling incoming UDP packets with 0 checksum.
+ (Tom Torrance helped fix this problem.)
+
+ Version 1.6 September 18, 1996 (cjm)
+ Simplified ICMP aliasing scheme. Should now support
+ traceroute from Win95 as well as FreeBSD.
+
+ Version 1.7 January 9, 1997 (cjm)
+ - Out-of-order fragment handling.
+ - IP checksum error fixed for ftp transfers
+ from aliasing host.
+ - Integer return codes added to all
+ aliasing/de-aliasing functions.
+ - Some obsolete comments cleaned up.
+ - Differential checksum computations for
+ IP header (TCP, UDP and ICMP were already
+ differential).
+
+ Version 2.1 May 1997 (cjm)
+ - Added support for outgoing ICMP error
+ messages.
+ - Added two functions PacketAliasIn2()
+ and PacketAliasOut2() for dynamic address
+ control (e.g. round-robin allocation of
+ incoming packets).
+
+ Version 2.2 July 1997 (cjm)
+ - Rationalized API function names to begin
+ with "PacketAlias..."
+ - Eliminated PacketAliasIn2() and
+ PacketAliasOut2() as poorly conceived.
+
+ Version 2.3 Dec 1998 (dillon)
+ - Major bounds checking additions, see FreeBSD/CVS
+
+ See HISTORY file for additional revisions.
+
+ $FreeBSD$
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+
+#ifndef IPPROTO_GRE
+#define IPPROTO_GRE 47
+#define IPPROTO_ESP 50
+#define IPPROTO_AH 51
+#endif
+
+#include "alias_local.h"
+#include "alias.h"
+
+#define NETBIOS_NS_PORT_NUMBER 137
+#define NETBIOS_DGM_PORT_NUMBER 138
+#define FTP_CONTROL_PORT_NUMBER 21
+#define IRC_CONTROL_PORT_NUMBER_1 6667
+#define IRC_CONTROL_PORT_NUMBER_2 6668
+#define CUSEEME_PORT_NUMBER 7648
+
+
+
+
+/* TCP Handling Routines
+
+ TcpMonitorIn() -- These routines monitor TCP connections, and
+ TcpMonitorOut() delete a link when a connection is closed.
+
+These routines look for SYN, FIN and RST flags to determine when TCP
+connections open and close. When a TCP connection closes, the data
+structure containing packet aliasing information is deleted after
+a timeout period.
+*/
+
+/* Local prototypes */
+static void TcpMonitorIn(struct ip *, struct alias_link *);
+
+static void TcpMonitorOut(struct ip *, struct alias_link *);
+
+
+static void
+TcpMonitorIn(struct ip *pip, struct alias_link *link)
+{
+ struct tcphdr *tc;
+
+ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+ switch (GetStateIn(link))
+ {
+ case ALIAS_TCP_STATE_NOT_CONNECTED:
+ if (tc->th_flags & TH_RST)
+ SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED);
+ else if (tc->th_flags & TH_SYN)
+ SetStateIn(link, ALIAS_TCP_STATE_CONNECTED);
+ break;
+ case ALIAS_TCP_STATE_CONNECTED:
+ if (tc->th_flags & (TH_FIN | TH_RST))
+ SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED);
+ break;
+ }
+}
+
+static void
+TcpMonitorOut(struct ip *pip, struct alias_link *link)
+{
+ struct tcphdr *tc;
+
+ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+ switch (GetStateOut(link))
+ {
+ case ALIAS_TCP_STATE_NOT_CONNECTED:
+ if (tc->th_flags & TH_RST)
+ SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED);
+ else if (tc->th_flags & TH_SYN)
+ SetStateOut(link, ALIAS_TCP_STATE_CONNECTED);
+ break;
+ case ALIAS_TCP_STATE_CONNECTED:
+ if (tc->th_flags & (TH_FIN | TH_RST))
+ SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED);
+ break;
+ }
+}
+
+
+
+
+
+/* Protocol Specific Packet Aliasing Routines
+
+ IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2(), IcmpAliasIn3()
+ IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2(), IcmpAliasOut3()
+ UdpAliasIn(), UdpAliasOut()
+ TcpAliasIn(), TcpAliasOut()
+
+These routines handle protocol specific details of packet aliasing.
+One may observe a certain amount of repetitive arithmetic in these
+functions, the purpose of which is to compute a revised checksum
+without actually summing over the entire data packet, which could be
+unnecessarily time consuming.
+
+The purpose of the packet aliasing routines is to replace the source
+address of the outgoing packet and then correctly put it back for
+any incoming packets. For TCP and UDP, ports are also re-mapped.
+
+For ICMP echo/timestamp requests and replies, the following scheme
+is used: the id number is replaced by an alias for the outgoing
+packet.
+
+ICMP error messages are handled by looking at the IP fragment
+in the data section of the message.
+
+For TCP and UDP protocols, a port number is chosen for an outgoing
+packet, and then incoming packets are identified by IP address and
+port numbers. For TCP packets, there is additional logic in the event
+that sequence and ack numbers have been altered (as is the case for
+FTP data port commands).
+
+The port numbers used by the packet aliasing module are not true
+ports in the Unix sense. No sockets are actually bound to ports.
+They are more correctly thought of as placeholders.
+
+All packets go through the aliasing mechanism, whether they come from
+the gateway machine or other machines on a local area network.
+*/
+
+
+/* Local prototypes */
+static int IcmpAliasIn1(struct ip *);
+static int IcmpAliasIn2(struct ip *);
+static int IcmpAliasIn3(struct ip *);
+static int IcmpAliasIn (struct ip *);
+
+static int IcmpAliasOut1(struct ip *);
+static int IcmpAliasOut2(struct ip *);
+static int IcmpAliasOut3(struct ip *);
+static int IcmpAliasOut (struct ip *);
+
+static int UdpAliasOut(struct ip *);
+static int UdpAliasIn (struct ip *);
+
+static int TcpAliasOut(struct ip *, int);
+static int TcpAliasIn (struct ip *);
+
+
+static int
+IcmpAliasIn1(struct ip *pip)
+{
+/*
+ De-alias incoming echo and timestamp replies
+*/
+ struct alias_link *link;
+ struct icmp *ic;
+
+ ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
+
+/* Get source address from ICMP data field and restore original data */
+ link = FindIcmpIn(pip->ip_src, pip->ip_dst, ic->icmp_id);
+ if (link != NULL)
+ {
+ u_short original_id;
+ int accumulate;
+
+ original_id = GetOriginalPort(link);
+
+/* Adjust ICMP checksum */
+ accumulate = ic->icmp_id;
+ accumulate -= original_id;
+ ADJUST_CHECKSUM(accumulate, ic->icmp_cksum)
+
+/* Put original sequence number back in */
+ ic->icmp_id = original_id;
+
+/* Put original address back into IP header */
+ {
+ struct in_addr original_address;
+
+ original_address = GetOriginalAddress(link);
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &original_address,
+ (u_short *) &pip->ip_dst,
+ 2);
+ pip->ip_dst = original_address;
+ }
+
+ return(PKT_ALIAS_OK);
+ }
+ return(PKT_ALIAS_IGNORED);
+}
+
+static int
+IcmpAliasIn2(struct ip *pip)
+{
+/*
+ Alias incoming ICMP error messages containing
+ IP header and first 64 bits of datagram.
+*/
+ struct ip *ip;
+ struct icmp *ic, *ic2;
+ struct udphdr *ud;
+ struct tcphdr *tc;
+ struct alias_link *link;
+
+ ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
+ ip = (struct ip *) ic->icmp_data;
+
+ ud = (struct udphdr *) ((char *) ip + (ip->ip_hl <<2));
+ tc = (struct tcphdr *) ud;
+ ic2 = (struct icmp *) ud;
+
+ if (ip->ip_p == IPPROTO_UDP)
+ link = FindUdpTcpIn(ip->ip_dst, ip->ip_src,
+ ud->uh_dport, ud->uh_sport,
+ IPPROTO_UDP);
+ else if (ip->ip_p == IPPROTO_TCP)
+ link = FindUdpTcpIn(ip->ip_dst, ip->ip_src,
+ tc->th_dport, tc->th_sport,
+ IPPROTO_TCP);
+ else if (ip->ip_p == IPPROTO_ICMP) {
+ if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP)
+ link = FindIcmpIn(ip->ip_dst, ip->ip_src, ic2->icmp_id);
+ else
+ link = NULL;
+ } else
+ link = NULL;
+
+ if (link != NULL)
+ {
+ if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP)
+ {
+ u_short *sptr;
+ int accumulate;
+ struct in_addr original_address;
+ u_short original_port;
+
+ original_address = GetOriginalAddress(link);
+ original_port = GetOriginalPort(link);
+
+/* Adjust ICMP checksum */
+ sptr = (u_short *) &(ip->ip_src);
+ accumulate = *sptr++;
+ accumulate += *sptr;
+ sptr = (u_short *) &original_address;
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+ accumulate += ud->uh_sport;
+ accumulate -= original_port;
+ ADJUST_CHECKSUM(accumulate, ic->icmp_cksum)
+
+/* Un-alias address in IP header */
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &original_address,
+ (u_short *) &pip->ip_dst,
+ 2);
+ pip->ip_dst = original_address;
+
+/* Un-alias address and port number of original IP packet
+fragment contained in ICMP data section */
+ ip->ip_src = original_address;
+ ud->uh_sport = original_port;
+ }
+ else if (pip->ip_p == IPPROTO_ICMP)
+ {
+ u_short *sptr;
+ int accumulate;
+ struct in_addr original_address;
+ u_short original_id;
+
+ original_address = GetOriginalAddress(link);
+ original_id = GetOriginalPort(link);
+
+/* Adjust ICMP checksum */
+ sptr = (u_short *) &(ip->ip_src);
+ accumulate = *sptr++;
+ accumulate += *sptr;
+ sptr = (u_short *) &original_address;
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+ accumulate += ic2->icmp_id;
+ accumulate -= original_id;
+ ADJUST_CHECKSUM(accumulate, ic->icmp_cksum)
+
+/* Un-alias address in IP header */
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &original_address,
+ (u_short *) &pip->ip_dst,
+ 2);
+ pip->ip_dst = original_address;
+
+/* Un-alias address of original IP packet and seqence number of
+ embedded icmp datagram */
+ ip->ip_src = original_address;
+ ic2->icmp_id = original_id;
+ }
+ return(PKT_ALIAS_OK);
+ }
+ return(PKT_ALIAS_IGNORED);
+}
+
+static int
+IcmpAliasIn3(struct ip *pip)
+{
+ struct in_addr original_address;
+
+ original_address = FindOriginalAddress(pip->ip_dst);
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &original_address,
+ (u_short *) &pip->ip_dst,
+ 2);
+ pip->ip_dst = original_address;
+
+ return PKT_ALIAS_OK;
+}
+
+
+static int
+IcmpAliasIn(struct ip *pip)
+{
+ int iresult;
+ struct icmp *ic;
+
+/* Return if proxy-only mode is enabled */
+ if (packetAliasMode & PKT_ALIAS_PROXY_ONLY)
+ return PKT_ALIAS_OK;
+
+ ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
+
+ iresult = PKT_ALIAS_IGNORED;
+ switch (ic->icmp_type)
+ {
+ case ICMP_ECHOREPLY:
+ case ICMP_TSTAMPREPLY:
+ if (ic->icmp_code == 0)
+ {
+ iresult = IcmpAliasIn1(pip);
+ }
+ break;
+ case ICMP_UNREACH:
+ case ICMP_SOURCEQUENCH:
+ case ICMP_TIMXCEED:
+ case ICMP_PARAMPROB:
+ iresult = IcmpAliasIn2(pip);
+ break;
+ case ICMP_ECHO:
+ case ICMP_TSTAMP:
+ iresult = IcmpAliasIn3(pip);
+ break;
+ }
+ return(iresult);
+}
+
+
+static int
+IcmpAliasOut1(struct ip *pip)
+{
+/*
+ Alias ICMP echo and timestamp packets
+*/
+ struct alias_link *link;
+ struct icmp *ic;
+
+ ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
+
+/* Save overwritten data for when echo packet returns */
+ link = FindIcmpOut(pip->ip_src, pip->ip_dst, ic->icmp_id);
+ if (link != NULL)
+ {
+ u_short alias_id;
+ int accumulate;
+
+ alias_id = GetAliasPort(link);
+
+/* Since data field is being modified, adjust ICMP checksum */
+ accumulate = ic->icmp_id;
+ accumulate -= alias_id;
+ ADJUST_CHECKSUM(accumulate, ic->icmp_cksum)
+
+/* Alias sequence number */
+ ic->icmp_id = alias_id;
+
+/* Change source address */
+ {
+ struct in_addr alias_address;
+
+ alias_address = GetAliasAddress(link);
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &alias_address,
+ (u_short *) &pip->ip_src,
+ 2);
+ pip->ip_src = alias_address;
+ }
+
+ return(PKT_ALIAS_OK);
+ }
+ return(PKT_ALIAS_IGNORED);
+}
+
+
+static int
+IcmpAliasOut2(struct ip *pip)
+{
+/*
+ Alias outgoing ICMP error messages containing
+ IP header and first 64 bits of datagram.
+*/
+ struct in_addr alias_addr;
+ struct ip *ip;
+ struct icmp *ic;
+
+ ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
+ ip = (struct ip *) ic->icmp_data;
+
+ alias_addr = FindAliasAddress(ip->ip_src);
+
+/* Alias destination address in IP fragment */
+ DifferentialChecksum(&ic->icmp_cksum,
+ (u_short *) &alias_addr,
+ (u_short *) &ip->ip_dst,
+ 2);
+ ip->ip_dst = alias_addr;
+
+/* alias source address in IP header */
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &alias_addr,
+ (u_short *) &pip->ip_src,
+ 2);
+ pip->ip_src = alias_addr;
+
+ return PKT_ALIAS_OK;
+}
+
+
+static int
+IcmpAliasOut3(struct ip *pip)
+{
+/*
+ Handle outgoing echo and timestamp replies. The
+ only thing which is done in this case is to alias
+ the source IP address of the packet.
+*/
+ struct in_addr alias_addr;
+
+ alias_addr = FindAliasAddress(pip->ip_src);
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &alias_addr,
+ (u_short *) &pip->ip_src,
+ 2);
+ pip->ip_src = alias_addr;
+
+ return PKT_ALIAS_OK;
+}
+
+
+static int
+IcmpAliasOut(struct ip *pip)
+{
+ int iresult;
+ struct icmp *ic;
+
+/* Return if proxy-only mode is enabled */
+ if (packetAliasMode & PKT_ALIAS_PROXY_ONLY)
+ return PKT_ALIAS_OK;
+
+ ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
+
+ iresult = PKT_ALIAS_IGNORED;
+ switch (ic->icmp_type)
+ {
+ case ICMP_ECHO:
+ case ICMP_TSTAMP:
+ if (ic->icmp_code == 0)
+ {
+ iresult = IcmpAliasOut1(pip);
+ }
+ break;
+ case ICMP_UNREACH:
+ case ICMP_SOURCEQUENCH:
+ case ICMP_TIMXCEED:
+ case ICMP_PARAMPROB:
+ iresult = IcmpAliasOut2(pip);
+ break;
+ case ICMP_ECHOREPLY:
+ case ICMP_TSTAMPREPLY:
+ iresult = IcmpAliasOut3(pip);
+ }
+ return(iresult);
+}
+
+
+
+static int
+PptpAliasIn(struct ip *pip)
+{
+/*
+ Handle incoming PPTP packets. The
+ only thing which is done in this case is to alias
+ the dest IP address of the packet to our inside
+ machine.
+*/
+ struct in_addr alias_addr;
+
+ if (!GetPptpAlias (&alias_addr))
+ return PKT_ALIAS_IGNORED;
+
+ if (pip->ip_src.s_addr != alias_addr.s_addr) {
+
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &alias_addr,
+ (u_short *) &pip->ip_dst,
+ 2);
+ pip->ip_dst = alias_addr;
+ }
+
+ return PKT_ALIAS_OK;
+}
+
+
+static int
+PptpAliasOut(struct ip *pip)
+{
+/*
+ Handle outgoing PPTP packets. The
+ only thing which is done in this case is to alias
+ the source IP address of the packet.
+*/
+ struct in_addr alias_addr;
+
+ if (!GetPptpAlias (&alias_addr))
+ return PKT_ALIAS_IGNORED;
+
+ if (pip->ip_src.s_addr == alias_addr.s_addr) {
+
+ alias_addr = FindAliasAddress(pip->ip_src);
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &alias_addr,
+ (u_short *) &pip->ip_src,
+ 2);
+ pip->ip_src = alias_addr;
+ }
+
+ return PKT_ALIAS_OK;
+}
+
+
+
+static int
+UdpAliasIn(struct ip *pip)
+{
+ struct udphdr *ud;
+ struct alias_link *link;
+
+/* Return if proxy-only mode is enabled */
+ if (packetAliasMode & PKT_ALIAS_PROXY_ONLY)
+ return PKT_ALIAS_OK;
+
+ ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+ link = FindUdpTcpIn(pip->ip_src, pip->ip_dst,
+ ud->uh_sport, ud->uh_dport,
+ IPPROTO_UDP);
+ if (link != NULL)
+ {
+ struct in_addr alias_address;
+ struct in_addr original_address;
+ u_short alias_port;
+ int accumulate;
+ u_short *sptr;
+ int r = 0;
+
+ alias_address = GetAliasAddress(link);
+ original_address = GetOriginalAddress(link);
+ alias_port = ud->uh_dport;
+ ud->uh_dport = GetOriginalPort(link);
+
+/* If NETBIOS Datagram, It should be alias address in UDP Data, too */
+ if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER
+ || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER )
+ {
+ r = AliasHandleUdpNbt(pip, link, &original_address, ud->uh_dport);
+ } else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER
+ || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER )
+ {
+ r = AliasHandleUdpNbtNS(pip, link,
+ &alias_address,
+ &alias_port,
+ &original_address,
+ &ud->uh_dport );
+ }
+
+ if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER)
+ AliasHandleCUSeeMeIn(pip, original_address);
+
+/* If UDP checksum is not zero, then adjust since destination port */
+/* is being unaliased and destination port is being altered. */
+ if (ud->uh_sum != 0)
+ {
+ accumulate = alias_port;
+ accumulate -= ud->uh_dport;
+ sptr = (u_short *) &alias_address;
+ accumulate += *sptr++;
+ accumulate += *sptr;
+ sptr = (u_short *) &original_address;
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+ ADJUST_CHECKSUM(accumulate, ud->uh_sum)
+ }
+
+/* Restore original IP address */
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &original_address,
+ (u_short *) &pip->ip_dst,
+ 2);
+ pip->ip_dst = original_address;
+
+ /*
+ * If we cannot figure out the packet, ignore it.
+ */
+ if (r < 0)
+ return(PKT_ALIAS_IGNORED);
+ else
+ return(PKT_ALIAS_OK);
+ }
+ return(PKT_ALIAS_IGNORED);
+}
+
+static int
+UdpAliasOut(struct ip *pip)
+{
+ struct udphdr *ud;
+ struct alias_link *link;
+
+/* Return if proxy-only mode is enabled */
+ if (packetAliasMode & PKT_ALIAS_PROXY_ONLY)
+ return PKT_ALIAS_OK;
+
+ ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+ link = FindUdpTcpOut(pip->ip_src, pip->ip_dst,
+ ud->uh_sport, ud->uh_dport,
+ IPPROTO_UDP);
+ if (link != NULL)
+ {
+ u_short alias_port;
+ struct in_addr alias_address;
+
+ alias_address = GetAliasAddress(link);
+ alias_port = GetAliasPort(link);
+
+ if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER)
+ AliasHandleCUSeeMeOut(pip, link);
+
+/* If NETBIOS Datagram, It should be alias address in UDP Data, too */
+ if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER
+ || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER )
+ {
+ AliasHandleUdpNbt(pip, link, &alias_address, alias_port);
+ } else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER
+ || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER )
+ {
+ AliasHandleUdpNbtNS(pip, link,
+ &pip->ip_src,
+ &ud->uh_sport,
+ &alias_address,
+ &alias_port);
+ }
+
+/* If UDP checksum is not zero, adjust since source port is */
+/* being aliased and source address is being altered */
+ if (ud->uh_sum != 0)
+ {
+ int accumulate;
+ u_short *sptr;
+
+ accumulate = ud->uh_sport;
+ accumulate -= alias_port;
+ sptr = (u_short *) &(pip->ip_src);
+ accumulate += *sptr++;
+ accumulate += *sptr;
+ sptr = (u_short *) &alias_address;
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+ ADJUST_CHECKSUM(accumulate, ud->uh_sum)
+ }
+
+/* Put alias port in UDP header */
+ ud->uh_sport = alias_port;
+
+/* Change source address */
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &alias_address,
+ (u_short *) &pip->ip_src,
+ 2);
+ pip->ip_src = alias_address;
+
+ return(PKT_ALIAS_OK);
+ }
+ return(PKT_ALIAS_IGNORED);
+}
+
+
+
+static int
+TcpAliasIn(struct ip *pip)
+{
+ struct tcphdr *tc;
+ struct alias_link *link;
+
+ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+ link = FindUdpTcpIn(pip->ip_src, pip->ip_dst,
+ tc->th_sport, tc->th_dport,
+ IPPROTO_TCP);
+ if (link != NULL)
+ {
+ struct in_addr alias_address;
+ struct in_addr original_address;
+ struct in_addr proxy_address;
+ u_short alias_port;
+ u_short proxy_port;
+ int accumulate;
+ u_short *sptr;
+
+ alias_address = GetAliasAddress(link);
+ original_address = GetOriginalAddress(link);
+ proxy_address = GetProxyAddress(link);
+ alias_port = tc->th_dport;
+ tc->th_dport = GetOriginalPort(link);
+ proxy_port = GetProxyPort(link);
+
+/* Adjust TCP checksum since destination port is being unaliased */
+/* and destination port is being altered. */
+ accumulate = alias_port;
+ accumulate -= tc->th_dport;
+ sptr = (u_short *) &alias_address;
+ accumulate += *sptr++;
+ accumulate += *sptr;
+ sptr = (u_short *) &original_address;
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+
+/* If this is a proxy, then modify the tcp source port and
+ checksum accumulation */
+ if (proxy_port != 0)
+ {
+ accumulate += tc->th_sport;
+ tc->th_sport = proxy_port;
+ accumulate -= tc->th_sport;
+
+ sptr = (u_short *) &pip->ip_src;
+ accumulate += *sptr++;
+ accumulate += *sptr;
+ sptr = (u_short *) &proxy_address;
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+ }
+
+/* See if ack number needs to be modified */
+ if (GetAckModified(link) == 1)
+ {
+ int delta;
+
+ delta = GetDeltaAckIn(pip, link);
+ if (delta != 0)
+ {
+ sptr = (u_short *) &tc->th_ack;
+ accumulate += *sptr++;
+ accumulate += *sptr;
+ tc->th_ack = htonl(ntohl(tc->th_ack) - delta);
+ sptr = (u_short *) &tc->th_ack;
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+ }
+ }
+
+ ADJUST_CHECKSUM(accumulate, tc->th_sum);
+
+/* Restore original IP address */
+ sptr = (u_short *) &pip->ip_dst;
+ accumulate = *sptr++;
+ accumulate += *sptr;
+ pip->ip_dst = original_address;
+ sptr = (u_short *) &pip->ip_dst;
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+
+/* If this is a transparent proxy packet, then modify the source
+ address */
+ if (proxy_address.s_addr != 0)
+ {
+ sptr = (u_short *) &pip->ip_src;
+ accumulate += *sptr++;
+ accumulate += *sptr;
+ pip->ip_src = proxy_address;
+ sptr = (u_short *) &pip->ip_src;
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+ }
+
+ ADJUST_CHECKSUM(accumulate, pip->ip_sum);
+
+/* Monitor TCP connection state */
+ TcpMonitorIn(pip, link);
+
+ return(PKT_ALIAS_OK);
+ }
+ return(PKT_ALIAS_IGNORED);
+}
+
+static int
+TcpAliasOut(struct ip *pip, int maxpacketsize)
+{
+ int proxy_type;
+ u_short dest_port;
+ u_short proxy_server_port;
+ struct in_addr dest_address;
+ struct in_addr proxy_server_address;
+ struct tcphdr *tc;
+ struct alias_link *link;
+
+ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+ proxy_type = ProxyCheck(pip, &proxy_server_address, &proxy_server_port);
+
+ if (proxy_type == 0 && (packetAliasMode & PKT_ALIAS_PROXY_ONLY))
+ return PKT_ALIAS_OK;
+
+/* If this is a transparent proxy, save original destination,
+ then alter the destination and adust checksums */
+ dest_port = tc->th_dport;
+ dest_address = pip->ip_dst;
+ if (proxy_type != 0)
+ {
+ int accumulate;
+ u_short *sptr;
+
+ accumulate = tc->th_dport;
+ tc->th_dport = proxy_server_port;
+ accumulate -= tc->th_dport;
+
+ sptr = (u_short *) &(pip->ip_dst);
+ accumulate += *sptr++;
+ accumulate += *sptr;
+ sptr = (u_short *) &proxy_server_address;
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+
+ ADJUST_CHECKSUM(accumulate, tc->th_sum);
+
+ sptr = (u_short *) &(pip->ip_dst);
+ accumulate = *sptr++;
+ accumulate += *sptr;
+ pip->ip_dst = proxy_server_address;
+ sptr = (u_short *) &(pip->ip_dst);
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+
+ ADJUST_CHECKSUM(accumulate, pip->ip_sum);
+ }
+
+ link = FindUdpTcpOut(pip->ip_src, pip->ip_dst,
+ tc->th_sport, tc->th_dport,
+ IPPROTO_TCP);
+ if (link !=NULL)
+ {
+ u_short alias_port;
+ struct in_addr alias_address;
+ int accumulate;
+ u_short *sptr;
+
+/* Save original destination address, if this is a proxy packet.
+ Also modify packet to include destination encoding. */
+ if (proxy_type != 0)
+ {
+ SetProxyPort(link, dest_port);
+ SetProxyAddress(link, dest_address);
+ ProxyModify(link, pip, maxpacketsize, proxy_type);
+ }
+
+/* Get alias address and port */
+ alias_port = GetAliasPort(link);
+ alias_address = GetAliasAddress(link);
+
+/* Monitor tcp connection state */
+ TcpMonitorOut(pip, link);
+
+/* Special processing for IP encoding protocols */
+ if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER
+ || ntohs(tc->th_sport) == FTP_CONTROL_PORT_NUMBER)
+ AliasHandleFtpOut(pip, link, maxpacketsize);
+ if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1
+ || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2)
+ AliasHandleIrcOut(pip, link, maxpacketsize);
+
+/* Adjust TCP checksum since source port is being aliased */
+/* and source address is being altered */
+ accumulate = tc->th_sport;
+ tc->th_sport = alias_port;
+ accumulate -= tc->th_sport;
+
+ sptr = (u_short *) &(pip->ip_src);
+ accumulate += *sptr++;
+ accumulate += *sptr;
+ sptr = (u_short *) &alias_address;
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+
+/* Modify sequence number if necessary */
+ if (GetAckModified(link) == 1)
+ {
+ int delta;
+
+ delta = GetDeltaSeqOut(pip, link);
+ if (delta != 0)
+ {
+ sptr = (u_short *) &tc->th_seq;
+ accumulate += *sptr++;
+ accumulate += *sptr;
+ tc->th_seq = htonl(ntohl(tc->th_seq) + delta);
+ sptr = (u_short *) &tc->th_seq;
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+ }
+ }
+
+ ADJUST_CHECKSUM(accumulate, tc->th_sum)
+
+/* Change source address */
+ sptr = (u_short *) &(pip->ip_src);
+ accumulate = *sptr++;
+ accumulate += *sptr;
+ pip->ip_src = alias_address;
+ sptr = (u_short *) &(pip->ip_src);
+ accumulate -= *sptr++;
+ accumulate -= *sptr;
+
+ ADJUST_CHECKSUM(accumulate, pip->ip_sum)
+
+ return(PKT_ALIAS_OK);
+ }
+ return(PKT_ALIAS_IGNORED);
+}
+
+
+
+
+/* Fragment Handling
+
+ FragmentIn()
+ FragmentOut()
+
+The packet aliasing module has a limited ability for handling IP
+fragments. If the ICMP, TCP or UDP header is in the first fragment
+received, then the id number of the IP packet is saved, and other
+fragments are identified according to their ID number and IP address
+they were sent from. Pointers to unresolved fragments can also be
+saved and recalled when a header fragment is seen.
+*/
+
+/* Local prototypes */
+static int FragmentIn(struct ip *);
+static int FragmentOut(struct ip *);
+
+
+static int
+FragmentIn(struct ip *pip)
+{
+ struct alias_link *link;
+
+ link = FindFragmentIn2(pip->ip_src, pip->ip_dst, pip->ip_id);
+ if (link != NULL)
+ {
+ struct in_addr original_address;
+
+ GetFragmentAddr(link, &original_address);
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &original_address,
+ (u_short *) &pip->ip_dst,
+ 2);
+ pip->ip_dst = original_address;
+
+ return(PKT_ALIAS_OK);
+ }
+ return(PKT_ALIAS_UNRESOLVED_FRAGMENT);
+}
+
+
+static int
+FragmentOut(struct ip *pip)
+{
+ struct in_addr alias_address;
+
+ alias_address = FindAliasAddress(pip->ip_src);
+ DifferentialChecksum(&pip->ip_sum,
+ (u_short *) &alias_address,
+ (u_short *) &pip->ip_src,
+ 2);
+ pip->ip_src = alias_address;
+
+ return(PKT_ALIAS_OK);
+}
+
+
+
+
+
+
+/* Outside World Access
+
+ PacketAliasSaveFragment()
+ PacketAliasGetFragment()
+ PacketAliasFragmentIn()
+ PacketAliasIn()
+ PacketAliasOut()
+
+(prototypes in alias.h)
+*/
+
+
+int
+PacketAliasSaveFragment(char *ptr)
+{
+ int iresult;
+ struct alias_link *link;
+ struct ip *pip;
+
+ pip = (struct ip *) ptr;
+ link = AddFragmentPtrLink(pip->ip_src, pip->ip_id);
+ iresult = PKT_ALIAS_ERROR;
+ if (link != NULL)
+ {
+ SetFragmentPtr(link, ptr);
+ iresult = PKT_ALIAS_OK;
+ }
+ return(iresult);
+}
+
+
+char *
+PacketAliasGetFragment(char *ptr)
+{
+ struct alias_link *link;
+ char *fptr;
+ struct ip *pip;
+
+ pip = (struct ip *) ptr;
+ link = FindFragmentPtr(pip->ip_src, pip->ip_id);
+ if (link != NULL)
+ {
+ GetFragmentPtr(link, &fptr);
+ SetFragmentPtr(link, NULL);
+ SetExpire(link, 0); /* Deletes link */
+
+ return(fptr);
+ }
+ else
+ {
+ return(NULL);
+ }
+}
+
+
+void
+PacketAliasFragmentIn(char *ptr, /* Points to correctly de-aliased
+ header fragment */
+ char *ptr_fragment /* Points to fragment which must
+ be de-aliased */
+ )
+{
+ struct ip *pip;
+ struct ip *fpip;
+
+ pip = (struct ip *) ptr;
+ fpip = (struct ip *) ptr_fragment;
+
+ DifferentialChecksum(&fpip->ip_sum,
+ (u_short *) &pip->ip_dst,
+ (u_short *) &fpip->ip_dst,
+ 2);
+ fpip->ip_dst = pip->ip_dst;
+}
+
+
+int
+PacketAliasIn(char *ptr, int maxpacketsize)
+{
+ struct in_addr alias_addr;
+ struct ip *pip;
+ int iresult;
+
+ if (packetAliasMode & PKT_ALIAS_REVERSE) {
+ packetAliasMode &= ~PKT_ALIAS_REVERSE;
+ iresult = PacketAliasOut(ptr, maxpacketsize);
+ packetAliasMode |= PKT_ALIAS_REVERSE;
+ return iresult;
+ }
+
+ HouseKeeping();
+ ClearCheckNewLink();
+ pip = (struct ip *) ptr;
+ alias_addr = pip->ip_dst;
+
+ /* Defense against mangled packets */
+ if (ntohs(pip->ip_len) > maxpacketsize
+ || (pip->ip_hl<<2) > maxpacketsize)
+ return PKT_ALIAS_IGNORED;
+
+ iresult = PKT_ALIAS_IGNORED;
+ if ( (ntohs(pip->ip_off) & IP_OFFMASK) == 0 )
+ {
+ switch (pip->ip_p)
+ {
+ case IPPROTO_ICMP:
+ iresult = IcmpAliasIn(pip);
+ break;
+ case IPPROTO_UDP:
+ iresult = UdpAliasIn(pip);
+ break;
+ case IPPROTO_TCP:
+ iresult = TcpAliasIn(pip);
+ break;
+ case IPPROTO_GRE:
+ case IPPROTO_ESP:
+ case IPPROTO_AH:
+ iresult = PptpAliasIn(pip);
+ break;
+ }
+
+ if (ntohs(pip->ip_off) & IP_MF)
+ {
+ struct alias_link *link;
+
+ link = FindFragmentIn1(pip->ip_src, alias_addr, pip->ip_id);
+ if (link != NULL)
+ {
+ iresult = PKT_ALIAS_FOUND_HEADER_FRAGMENT;
+ SetFragmentAddr(link, pip->ip_dst);
+ }
+ else
+ {
+ iresult = PKT_ALIAS_ERROR;
+ }
+ }
+ }
+ else
+ {
+ iresult = FragmentIn(pip);
+ }
+
+ return(iresult);
+}
+
+
+
+/* Unregistered address ranges */
+
+/* 10.0.0.0 -> 10.255.255.255 */
+#define UNREG_ADDR_A_LOWER 0x0a000000
+#define UNREG_ADDR_A_UPPER 0x0affffff
+
+/* 172.16.0.0 -> 172.31.255.255 */
+#define UNREG_ADDR_B_LOWER 0xac100000
+#define UNREG_ADDR_B_UPPER 0xac1fffff
+
+/* 192.168.0.0 -> 192.168.255.255 */
+#define UNREG_ADDR_C_LOWER 0xc0a80000
+#define UNREG_ADDR_C_UPPER 0xc0a8ffff
+
+int
+PacketAliasOut(char *ptr, /* valid IP packet */
+ int maxpacketsize /* How much the packet data may grow
+ (FTP and IRC inline changes) */
+ )
+{
+ int iresult;
+ struct in_addr addr_save;
+ struct ip *pip;
+
+ if (packetAliasMode & PKT_ALIAS_REVERSE) {
+ packetAliasMode &= ~PKT_ALIAS_REVERSE;
+ iresult = PacketAliasIn(ptr, maxpacketsize);
+ packetAliasMode |= PKT_ALIAS_REVERSE;
+ return iresult;
+ }
+
+ HouseKeeping();
+ ClearCheckNewLink();
+ pip = (struct ip *) ptr;
+
+ /* Defense against mangled packets */
+ if (ntohs(pip->ip_len) > maxpacketsize
+ || (pip->ip_hl<<2) > maxpacketsize)
+ return PKT_ALIAS_IGNORED;
+
+ addr_save = GetDefaultAliasAddress();
+ if (packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY)
+ {
+ unsigned int addr;
+ int iclass;
+
+ iclass = 0;
+ addr = ntohl(pip->ip_src.s_addr);
+ if (addr >= UNREG_ADDR_C_LOWER && addr <= UNREG_ADDR_C_UPPER)
+ iclass = 3;
+ else if (addr >= UNREG_ADDR_B_LOWER && addr <= UNREG_ADDR_B_UPPER)
+ iclass = 2;
+ else if (addr >= UNREG_ADDR_A_LOWER && addr <= UNREG_ADDR_A_UPPER)
+ iclass = 1;
+
+ if (iclass == 0)
+ {
+ SetDefaultAliasAddress(pip->ip_src);
+ }
+ }
+
+ iresult = PKT_ALIAS_IGNORED;
+ if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0)
+ {
+ switch (pip->ip_p)
+ {
+ case IPPROTO_ICMP:
+ iresult = IcmpAliasOut(pip);
+ break;
+ case IPPROTO_UDP:
+ iresult = UdpAliasOut(pip);
+ break;
+ case IPPROTO_TCP:
+ iresult = TcpAliasOut(pip, maxpacketsize);
+ break;
+ case IPPROTO_GRE:
+ case IPPROTO_ESP:
+ case IPPROTO_AH:
+ iresult = PptpAliasOut(pip);
+ break;
+ }
+ }
+ else
+ {
+ iresult = FragmentOut(pip);
+ }
+
+ SetDefaultAliasAddress(addr_save);
+ return(iresult);
+}
diff --git a/lib/libalias/alias.h b/lib/libalias/alias.h
new file mode 100644
index 0000000..9666b0f
--- /dev/null
+++ b/lib/libalias/alias.h
@@ -0,0 +1,166 @@
+/*lint -save -library Flexelint comment for external headers */
+
+/*
+ Alias.h defines the outside world interfaces for the packet
+ aliasing software.
+
+ This software is placed into the public domain with no restrictions
+ on its distribution.
+
+ $FreeBSD$
+*/
+
+
+#ifndef _ALIAS_H_
+#define _ALIAS_H_
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* Alias link representative (incomplete struct) */
+struct alias_link;
+
+/* External interfaces (API) to packet aliasing engine */
+
+/* Initialization and Control */
+ extern void
+ PacketAliasInit(void);
+
+ extern void
+ PacketAliasUninit(void);
+
+ extern void
+ PacketAliasSetAddress(struct in_addr);
+
+ extern unsigned int
+ PacketAliasSetMode(unsigned int, unsigned int);
+
+#ifndef NO_FW_PUNCH
+ extern void
+ PacketAliasSetFWBase(unsigned int, unsigned int);
+#endif
+
+/* Packet Handling */
+ extern int
+ PacketAliasIn(char *, int maxpacketsize);
+
+ extern int
+ PacketAliasOut(char *, int maxpacketsize);
+
+/* Port and Address Redirection */
+ extern struct alias_link *
+ PacketAliasRedirectPort(struct in_addr, u_short,
+ struct in_addr, u_short,
+ struct in_addr, u_short,
+ u_char);
+
+ extern int
+ PacketAliasPptp(struct in_addr);
+
+
+ extern struct alias_link *
+ PacketAliasRedirectAddr(struct in_addr,
+ struct in_addr);
+
+ extern void
+ PacketAliasRedirectDelete(struct alias_link *);
+
+/* Fragment Handling */
+ extern int
+ PacketAliasSaveFragment(char *);
+
+ extern char *
+ PacketAliasGetFragment(char *);
+
+ extern void
+ PacketAliasFragmentIn(char *, char *);
+
+/* Miscellaneous Functions */
+ extern void
+ PacketAliasSetTarget(struct in_addr addr);
+
+ extern int
+ PacketAliasCheckNewLink(void);
+
+ extern u_short
+ PacketAliasInternetChecksum(u_short *, int);
+
+/* Transparent Proxying */
+ extern int
+ PacketAliasProxyRule(const char *);
+
+
+/********************** Mode flags ********************/
+/* Set these flags using SetPacketAliasMode() */
+
+/* If PKT_ALIAS_LOG is set, a message will be printed to
+ /var/log/alias.log every time a link is created or deleted. This
+ is useful for debugging */
+#define PKT_ALIAS_LOG 0x01
+
+/* If PKT_ALIAS_DENY_INCOMING is set, then incoming connections (e.g.
+ to ftp, telnet or web servers will be prevented by the aliasing
+ mechanism. */
+#define PKT_ALIAS_DENY_INCOMING 0x02
+
+/* If PKT_ALIAS_SAME_PORTS is set, packets will be attempted sent from
+ the same port as they originated on. This allows eg rsh to work
+ *99% of the time*, but _not_ 100%. (It will be slightly flakey
+ instead of not working at all.) This mode bit is set by
+ PacketAliasInit(), so it is a default mode of operation. */
+#define PKT_ALIAS_SAME_PORTS 0x04
+
+/* If PKT_ALIAS_USE_SOCKETS is set, then when partially specified
+ links (e.g. destination port and/or address is zero), the packet
+ aliasing engine will attempt to allocate a socket for the aliasing
+ port it chooses. This will avoid interference with the host
+ machine. Fully specified links do not require this. This bit
+ is set after a call to PacketAliasInit(), so it is a default
+ mode of operation.*/
+#define PKT_ALIAS_USE_SOCKETS 0x08
+
+/* If PKT_ALIAS_UNREGISTERED_ONLY is set, then only packets with with
+ unregistered source addresses will be aliased (along with those
+ of the ppp host maching itself. Private addresses are those
+ in the following ranges:
+ 10.0.0.0 -> 10.255.255.255
+ 172.16.0.0 -> 172.31.255.255
+ 192.168.0.0 -> 192.168.255.255 */
+#define PKT_ALIAS_UNREGISTERED_ONLY 0x10
+
+/* If PKT_ALIAS_RESET_ON_ADDR_CHANGE is set, then the table of dynamic
+ aliasing links will be reset whenever PacketAliasSetAddress()
+ changes the default aliasing address. If the default aliasing
+ address is left unchanged by this functions call, then the
+ table of dynamic aliasing links will be left intact. This
+ bit is set after a call to PacketAliasInit(). */
+#define PKT_ALIAS_RESET_ON_ADDR_CHANGE 0x20
+
+#ifndef NO_FW_PUNCH
+/* If PKT_ALIAS_PUNCH_FW is set, active FTP and IRC DCC connections
+ will create a 'hole' in the firewall to allow the transfers to
+ work. Where (IPFW "line-numbers") the hole is created is
+ controlled by PacketAliasSetFWBase(base, size). The hole will be
+ attached to that particular alias_link, so when the link goes away
+ so do the hole. */
+#define PKT_ALIAS_PUNCH_FW 0x40
+#endif
+
+/* If PKT_ALIAS_PROXY_ONLY is set, then NAT will be disabled and only
+ transparent proxying performed */
+#define PKT_ALIAS_PROXY_ONLY 0x40
+
+/* If PKT_ALIAS_REVERSE is set, the actions of PacketAliasIn()
+ and PacketAliasOut() are reversed */
+#define PKT_ALIAS_REVERSE 0x80
+
+/* Return Codes */
+#define PKT_ALIAS_ERROR -1
+#define PKT_ALIAS_OK 1
+#define PKT_ALIAS_IGNORED 2
+#define PKT_ALIAS_UNRESOLVED_FRAGMENT 3
+#define PKT_ALIAS_FOUND_HEADER_FRAGMENT 4
+
+#endif
+/*lint -restore */
diff --git a/lib/libalias/alias_cuseeme.c b/lib/libalias/alias_cuseeme.c
new file mode 100644
index 0000000..b1b95f4
--- /dev/null
+++ b/lib/libalias/alias_cuseeme.c
@@ -0,0 +1,120 @@
+/*-
+ * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
+ * with the aid of code written by
+ * Junichi SATOH <junichi@astec.co.jp> 1996, 1997.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+
+#include "alias_local.h"
+
+/* CU-SeeMe Data Header */
+struct cu_header {
+ u_int16_t dest_family;
+ u_int16_t dest_port;
+ u_int32_t dest_addr;
+ int16_t family;
+ u_int16_t port;
+ u_int32_t addr;
+ u_int32_t seq;
+ u_int16_t msg;
+ u_int16_t data_type;
+ u_int16_t packet_len;
+};
+
+/* Open Continue Header */
+struct oc_header {
+ u_int16_t client_count; /* Number of client info structs */
+ u_int32_t seq_no;
+ char user_name[20];
+ char reserved[4]; /* flags, version stuff, etc */
+};
+
+/* client info structures */
+struct client_info {
+ u_int32_t address; /* Client address */
+ char reserved[8]; /* Flags, pruning bitfield, packet counts etc */
+};
+
+void
+AliasHandleCUSeeMeOut(struct ip *pip, struct alias_link *link)
+{
+ struct udphdr *ud;
+
+ ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
+ if(ud->uh_ulen >= sizeof(struct cu_header)) {
+ struct cu_header *cu;
+ struct alias_link *cu_link;
+
+ cu = (struct cu_header *)(ud + 1);
+ if (cu->addr)
+ cu->addr = (u_int32_t)GetAliasAddress(link).s_addr;
+
+ cu_link = FindUdpTcpOut(pip->ip_src, GetDestAddress(link),
+ ud->uh_dport, 0, IPPROTO_UDP);
+
+#ifndef NO_FW_PUNCH
+ if (cu_link)
+ PunchFWHole(cu_link);
+#endif
+ }
+}
+
+void
+AliasHandleCUSeeMeIn(struct ip *pip, struct in_addr original_addr)
+{
+ struct in_addr alias_addr;
+ struct udphdr *ud;
+ struct cu_header *cu;
+ struct oc_header *oc;
+ struct client_info *ci;
+ char *end;
+ int i;
+
+ alias_addr.s_addr = pip->ip_dst.s_addr;
+ ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
+ cu = (struct cu_header *)(ud + 1);
+ oc = (struct oc_header *)(cu + 1);
+ ci = (struct client_info *)(oc + 1);
+ end = (char *)cu + ud->uh_ulen;
+
+ if ((char *)oc <= end) {
+ if(cu->dest_addr)
+ cu->dest_addr = (u_int32_t)original_addr.s_addr;
+ if(ntohs(cu->data_type) == 101)
+ /* Find and change our address */
+ for(i = 0; (char *)(ci + 1) <= end && i < oc->client_count; i++, ci++)
+ if(ci->address == (u_int32_t)alias_addr.s_addr) {
+ ci->address = (u_int32_t)original_addr.s_addr;
+ break;
+ }
+ }
+}
diff --git a/lib/libalias/alias_db.c b/lib/libalias/alias_db.c
new file mode 100644
index 0000000..618162c
--- /dev/null
+++ b/lib/libalias/alias_db.c
@@ -0,0 +1,2394 @@
+/* -*- mode: c; tab-width: 8; c-basic-indent: 4; -*-
+ Alias_db.c encapsulates all data structures used for storing
+ packet aliasing data. Other parts of the aliasing software
+ access data through functions provided in this file.
+
+ Data storage is based on the notion of a "link", which is
+ established for ICMP echo/reply packets, UDP datagrams and
+ TCP stream connections. A link stores the original source
+ and destination addresses. For UDP and TCP, it also stores
+ source and destination port numbers, as well as an alias
+ port number. Links are also used to store information about
+ fragments.
+
+ There is a facility for sweeping through and deleting old
+ links as new packets are sent through. A simple timeout is
+ used for ICMP and UDP links. TCP links are left alone unless
+ there is an incomplete connection, in which case the link
+ can be deleted after a certain amount of time.
+
+
+ This software is placed into the public domain with no restrictions
+ on its distribution.
+
+ Initial version: August, 1996 (cjm)
+
+ Version 1.4: September 16, 1996 (cjm)
+ Facility for handling incoming links added.
+
+ Version 1.6: September 18, 1996 (cjm)
+ ICMP data handling simplified.
+
+ Version 1.7: January 9, 1997 (cjm)
+ Fragment handling simplified.
+ Saves pointers for unresolved fragments.
+ Permits links for unspecied remote ports
+ or unspecified remote addresses.
+ Fixed bug which did not properly zero port
+ table entries after a link was deleted.
+ Cleaned up some obsolete comments.
+
+ Version 1.8: January 14, 1997 (cjm)
+ Fixed data type error in StartPoint().
+ (This error did not exist prior to v1.7
+ and was discovered and fixed by Ari Suutari)
+
+ Version 1.9: February 1, 1997
+ Optionally, connections initiated from packet aliasing host
+ machine will will not have their port number aliased unless it
+ conflicts with an aliasing port already being used. (cjm)
+
+ All options earlier being #ifdef'ed now are available through
+ a new interface, SetPacketAliasMode(). This allow run time
+ control (which is now available in PPP+pktAlias through the
+ 'alias' keyword). (ee)
+
+ Added ability to create an alias port without
+ either destination address or port specified.
+ port type = ALIAS_PORT_UNKNOWN_DEST_ALL (ee)
+
+ Removed K&R style function headers
+ and general cleanup. (ee)
+
+ Added packetAliasMode to replace compiler #defines's (ee)
+
+ Allocates sockets for partially specified
+ ports if ALIAS_USE_SOCKETS defined. (cjm)
+
+ Version 2.0: March, 1997
+ SetAliasAddress() will now clean up alias links
+ if the aliasing address is changed. (cjm)
+
+ PacketAliasPermanentLink() function added to support permanent
+ links. (J. Fortes suggested the need for this.)
+ Examples:
+
+ (192.168.0.1, port 23) <-> alias port 6002, unknown dest addr/port
+
+ (192.168.0.2, port 21) <-> alias port 3604, known dest addr
+ unknown dest port
+
+ These permament links allow for incoming connections to
+ machines on the local network. They can be given with a
+ user-chosen amount of specificity, with increasing specificity
+ meaning more security. (cjm)
+
+ Quite a bit of rework to the basic engine. The portTable[]
+ array, which kept track of which ports were in use was replaced
+ by a table/linked list structure. (cjm)
+
+ SetExpire() function added. (cjm)
+
+ DeleteLink() no longer frees memory association with a pointer
+ to a fragment (this bug was first recognized by E. Eklund in
+ v1.9).
+
+ Version 2.1: May, 1997 (cjm)
+ Packet aliasing engine reworked so that it can handle
+ multiple external addresses rather than just a single
+ host address.
+
+ PacketAliasRedirectPort() and PacketAliasRedirectAddr()
+ added to the API. The first function is a more generalized
+ version of PacketAliasPermanentLink(). The second function
+ implements static network address translation.
+
+ See HISTORY file for additional revisions.
+
+ $FreeBSD$
+*/
+
+
+/* System include files */
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+/* BSD network include files */
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+
+#include "alias.h"
+#include "alias_local.h"
+
+
+
+/*
+ Constants (note: constants are also defined
+ near relevant functions or structs)
+*/
+
+/* Sizes of input and output link tables */
+#define LINK_TABLE_OUT_SIZE 101
+#define LINK_TABLE_IN_SIZE 4001
+
+/* Parameters used for cleanup of expired links */
+#define ALIAS_CLEANUP_INTERVAL_SECS 60
+#define ALIAS_CLEANUP_MAX_SPOKES 30
+
+/* Timeouts (in seconds) for different link types */
+#define ICMP_EXPIRE_TIME 60
+#define UDP_EXPIRE_TIME 60
+#define FRAGMENT_ID_EXPIRE_TIME 10
+#define FRAGMENT_PTR_EXPIRE_TIME 30
+
+/* TCP link expire time for different cases */
+/* When the link has been used and closed - minimal grace time to
+ allow ACKs and potential re-connect in FTP (XXX - is this allowed?) */
+#ifndef TCP_EXPIRE_DEAD
+# define TCP_EXPIRE_DEAD 10
+#endif
+
+/* When the link has been used and closed on one side - the other side
+ is allowed to still send data */
+#ifndef TCP_EXPIRE_SINGLEDEAD
+# define TCP_EXPIRE_SINGLEDEAD 90
+#endif
+
+/* When the link isn't yet up */
+#ifndef TCP_EXPIRE_INITIAL
+# define TCP_EXPIRE_INITIAL 300
+#endif
+
+/* When the link is up */
+#ifndef TCP_EXPIRE_CONNECTED
+# define TCP_EXPIRE_CONNECTED 86400
+#endif
+
+
+/* Dummy port number codes used for FindLinkIn/Out() and AddLink().
+ These constants can be anything except zero, which indicates an
+ unknown port number. */
+
+#define NO_DEST_PORT 1
+#define NO_SRC_PORT 1
+
+
+
+/* Data Structures
+
+ The fundamental data structure used in this program is
+ "struct alias_link". Whenever a TCP connection is made,
+ a UDP datagram is sent out, or an ICMP echo request is made,
+ a link record is made (if it has not already been created).
+ The link record is identified by the source address/port
+ and the destination address/port. In the case of an ICMP
+ echo request, the source port is treated as being equivalent
+ with the 16-bit id number of the ICMP packet.
+
+ The link record also can store some auxiliary data. For
+ TCP connections that have had sequence and acknowledgment
+ modifications, data space is available to track these changes.
+ A state field is used to keep track in changes to the tcp
+ connection state. Id numbers of fragments can also be
+ stored in the auxiliary space. Pointers to unresolved
+ framgents can also be stored.
+
+ The link records support two independent chainings. Lookup
+ tables for input and out tables hold the initial pointers
+ the link chains. On input, the lookup table indexes on alias
+ port and link type. On output, the lookup table indexes on
+ source addreess, destination address, source port, destination
+ port and link type.
+*/
+
+struct ack_data_record /* used to save changes to ack/seq numbers */
+{
+ u_long ack_old;
+ u_long ack_new;
+ int delta;
+ int active;
+};
+
+struct tcp_state /* Information about tcp connection */
+{
+ int in; /* State for outside -> inside */
+ int out; /* State for inside -> outside */
+ int index; /* Index to ack data array */
+ int ack_modified; /* Indicates whether ack and seq numbers */
+ /* been modified */
+};
+
+#define N_LINK_TCP_DATA 3 /* Number of distinct ack number changes
+ saved for a modified TCP stream */
+struct tcp_dat
+{
+ struct tcp_state state;
+ struct ack_data_record ack[N_LINK_TCP_DATA];
+ int fwhole; /* Which firewall record is used for this hole? */
+};
+
+struct alias_link /* Main data structure */
+{
+ struct in_addr src_addr; /* Address and port information */
+ struct in_addr dst_addr;
+ struct in_addr alias_addr;
+ struct in_addr proxy_addr;
+ u_short src_port;
+ u_short dst_port;
+ u_short alias_port;
+ u_short proxy_port;
+
+ int link_type; /* Type of link: tcp, udp, icmp, frag */
+
+/* values for link_type */
+#define LINK_ICMP 1
+#define LINK_UDP 2
+#define LINK_TCP 3
+#define LINK_FRAGMENT_ID 4
+#define LINK_FRAGMENT_PTR 5
+#define LINK_ADDR 6
+
+ int flags; /* indicates special characteristics */
+
+/* flag bits */
+#define LINK_UNKNOWN_DEST_PORT 0x01
+#define LINK_UNKNOWN_DEST_ADDR 0x02
+#define LINK_PERMANENT 0x04
+#define LINK_PARTIALLY_SPECIFIED 0x03 /* logical-or of first two bits */
+#define LINK_UNFIREWALLED 0x08
+
+ int timestamp; /* Time link was last accessed */
+ int expire_time; /* Expire time for link */
+
+ int sockfd; /* socket descriptor */
+
+ u_int start_point_out; /* Index number in output lookup table */
+ u_int start_point_in;
+ struct alias_link *next_out; /* Linked list pointers for input and */
+ struct alias_link *last_out; /* output tables */
+ struct alias_link *next_in; /* . */
+ struct alias_link *last_in; /* . */
+
+ union /* Auxiliary data */
+ {
+ char *frag_ptr;
+ struct in_addr frag_addr;
+ struct tcp_dat *tcp;
+ } data;
+};
+
+
+
+
+
+/* Global Variables
+
+ The global variables listed here are only accessed from
+ within alias_db.c and so are prefixed with the static
+ designation.
+*/
+
+int packetAliasMode; /* Mode flags */
+ /* - documented in alias.h */
+
+static struct in_addr aliasAddress; /* Address written onto source */
+ /* field of IP packet. */
+
+static struct in_addr targetAddress; /* IP address incoming packets */
+ /* are sent to if no aliasing */
+ /* link already exists */
+
+static struct in_addr nullAddress; /* Used as a dummy parameter for */
+ /* some function calls */
+static struct alias_link *
+linkTableOut[LINK_TABLE_OUT_SIZE]; /* Lookup table of pointers to */
+ /* chains of link records. Each */
+static struct alias_link * /* link record is doubly indexed */
+linkTableIn[LINK_TABLE_IN_SIZE]; /* into input and output lookup */
+ /* tables. */
+
+static int icmpLinkCount; /* Link statistics */
+static int udpLinkCount;
+static int tcpLinkCount;
+static int fragmentIdLinkCount;
+static int fragmentPtrLinkCount;
+static int sockCount;
+
+static int cleanupIndex; /* Index to chain of link table */
+ /* being inspected for old links */
+
+static int timeStamp; /* System time in seconds for */
+ /* current packet */
+
+static int lastCleanupTime; /* Last time IncrementalCleanup() */
+ /* was called */
+
+static int houseKeepingResidual; /* used by HouseKeeping() */
+
+static int deleteAllLinks; /* If equal to zero, DeleteLink() */
+ /* will not remove permanent links */
+
+static FILE *monitorFile; /* File descriptor for link */
+ /* statistics monitoring file */
+
+static int newDefaultLink; /* Indicates if a new aliasing */
+ /* link has been created after a */
+ /* call to PacketAliasIn/Out(). */
+
+#ifndef NO_FW_PUNCH
+static int fireWallFD = -1; /* File descriptor to be able to */
+ /* control firewall. Opened by */
+ /* PacketAliasSetMode on first */
+ /* setting the PKT_ALIAS_PUNCH_FW */
+ /* flag. */
+#endif
+
+static int pptpAliasFlag; /* Indicates if PPTP aliasing is */
+ /* on or off */
+static struct in_addr pptpAliasAddr; /* Address of source of PPTP */
+ /* packets. */
+
+
+
+
+
+
+
+/* Internal utility routines (used only in alias_db.c)
+
+Lookup table starting points:
+ StartPointIn() -- link table initial search point for
+ incoming packets
+ StartPointOut() -- port table initial search point for
+ outgoing packets
+
+Miscellaneous:
+ SeqDiff() -- difference between two TCP sequences
+ ShowAliasStats() -- send alias statistics to a monitor file
+*/
+
+
+/* Local prototypes */
+static u_int StartPointIn(struct in_addr, u_short, int);
+
+static u_int StartPointOut(struct in_addr, struct in_addr,
+ u_short, u_short, int);
+
+static int SeqDiff(u_long, u_long);
+
+static void ShowAliasStats(void);
+
+#ifndef NO_FW_PUNCH
+/* Firewall control */
+static void InitPunchFW(void);
+static void UninitPunchFW(void);
+static void ClearFWHole(struct alias_link *link);
+#endif
+
+/* Log file control */
+static void InitPacketAliasLog(void);
+static void UninitPacketAliasLog(void);
+
+static u_int
+StartPointIn(struct in_addr alias_addr,
+ u_short alias_port,
+ int link_type)
+{
+ u_int n;
+
+ n = alias_addr.s_addr;
+ n += alias_port;
+ n += link_type;
+ return(n % LINK_TABLE_IN_SIZE);
+}
+
+
+static u_int
+StartPointOut(struct in_addr src_addr, struct in_addr dst_addr,
+ u_short src_port, u_short dst_port, int link_type)
+{
+ u_int n;
+
+ n = src_addr.s_addr;
+ n += dst_addr.s_addr;
+ n += src_port;
+ n += dst_port;
+ n += link_type;
+
+ return(n % LINK_TABLE_OUT_SIZE);
+}
+
+
+static int
+SeqDiff(u_long x, u_long y)
+{
+/* Return the difference between two TCP sequence numbers */
+
+/*
+ This function is encapsulated in case there are any unusual
+ arithmetic conditions that need to be considered.
+*/
+
+ return (ntohl(y) - ntohl(x));
+}
+
+
+static void
+ShowAliasStats(void)
+{
+/* Used for debugging */
+
+ if (monitorFile)
+ {
+ fprintf(monitorFile, "icmp=%d, udp=%d, tcp=%d, frag_id=%d frag_ptr=%d",
+ icmpLinkCount,
+ udpLinkCount,
+ tcpLinkCount,
+ fragmentIdLinkCount,
+ fragmentPtrLinkCount);
+
+ fprintf(monitorFile, " / tot=%d (sock=%d)\n",
+ icmpLinkCount + udpLinkCount
+ + tcpLinkCount
+ + fragmentIdLinkCount
+ + fragmentPtrLinkCount,
+ sockCount);
+
+ fflush(monitorFile);
+ }
+}
+
+
+
+
+
+/* Internal routines for finding, deleting and adding links
+
+Port Allocation:
+ GetNewPort() -- find and reserve new alias port number
+ GetSocket() -- try to allocate a socket for a given port
+
+Link creation and deletion:
+ CleanupAliasData() - remove all link chains from lookup table
+ IncrementalCleanup() - look for stale links in a single chain
+ DeleteLink() - remove link
+ AddLink() - add link
+ ReLink() - change link
+
+Link search:
+ FindLinkOut() - find link for outgoing packets
+ FindLinkIn() - find link for incoming packets
+*/
+
+/* Local prototypes */
+static int GetNewPort(struct alias_link *, int);
+
+static u_short GetSocket(u_short, int *, int);
+
+static void CleanupAliasData(void);
+
+static void IncrementalCleanup(void);
+
+static void DeleteLink(struct alias_link *);
+
+static struct alias_link *
+AddLink(struct in_addr, struct in_addr, struct in_addr,
+ u_short, u_short, int, int);
+
+static struct alias_link *
+ReLink(struct alias_link *,
+ struct in_addr, struct in_addr, struct in_addr,
+ u_short, u_short, int, int);
+
+static struct alias_link *
+FindLinkOut(struct in_addr, struct in_addr, u_short, u_short, int, int);
+
+static struct alias_link *
+FindLinkIn(struct in_addr, struct in_addr, u_short, u_short, int, int);
+
+
+#define ALIAS_PORT_BASE 0x08000
+#define ALIAS_PORT_MASK 0x07fff
+#define GET_NEW_PORT_MAX_ATTEMPTS 20
+
+#define GET_ALIAS_PORT -1
+#define GET_ALIAS_ID GET_ALIAS_PORT
+
+/* GetNewPort() allocates port numbers. Note that if a port number
+ is already in use, that does not mean that it cannot be used by
+ another link concurrently. This is because GetNewPort() looks for
+ unused triplets: (dest addr, dest port, alias port). */
+
+static int
+GetNewPort(struct alias_link *link, int alias_port_param)
+{
+ int i;
+ int max_trials;
+ u_short port_sys;
+ u_short port_net;
+
+/*
+ Description of alias_port_param for GetNewPort(). When
+ this parameter is zero or positive, it precisely specifies
+ the port number. GetNewPort() will return this number
+ without check that it is in use.
+
+ Whis this parameter is -1, it indicates to get a randomly
+ selected port number.
+*/
+
+ if (alias_port_param == GET_ALIAS_PORT)
+ {
+ /*
+ * The aliasing port is automatically selected
+ * by one of two methods below:
+ */
+ max_trials = GET_NEW_PORT_MAX_ATTEMPTS;
+
+ if (packetAliasMode & PKT_ALIAS_SAME_PORTS)
+ {
+ /*
+ * When the ALIAS_SAME_PORTS option is
+ * chosen, the first try will be the
+ * actual source port. If this is already
+ * in use, the remainder of the trials
+ * will be random.
+ */
+ port_net = link->src_port;
+ port_sys = ntohs(port_net);
+ }
+ else
+ {
+ /* First trial and all subsequent are random. */
+ port_sys = random() & ALIAS_PORT_MASK;
+ port_sys += ALIAS_PORT_BASE;
+ port_net = htons(port_sys);
+ }
+ }
+ else if (alias_port_param >= 0 && alias_port_param < 0x10000)
+ {
+ link->alias_port = (u_short) alias_port_param;
+ return(0);
+ }
+ else
+ {
+#ifdef DEBUG
+ fprintf(stderr, "PacketAlias/GetNewPort(): ");
+ fprintf(stderr, "input parameter error\n");
+#endif
+ return(-1);
+ }
+
+
+/* Port number search */
+ for (i=0; i<max_trials; i++)
+ {
+ int go_ahead;
+ struct alias_link *search_result;
+
+ search_result = FindLinkIn(link->dst_addr, link->alias_addr,
+ link->dst_port, port_net,
+ link->link_type, 0);
+
+ if (search_result == NULL)
+ go_ahead = 1;
+ else if (!(link->flags & LINK_PARTIALLY_SPECIFIED)
+ && (search_result->flags & LINK_PARTIALLY_SPECIFIED))
+ go_ahead = 1;
+ else
+ go_ahead = 0;
+
+ if (go_ahead)
+ {
+ if ((packetAliasMode & PKT_ALIAS_USE_SOCKETS)
+ && (link->flags & LINK_PARTIALLY_SPECIFIED))
+ {
+ if (GetSocket(port_net, &link->sockfd, link->link_type))
+ {
+ link->alias_port = port_net;
+ return(0);
+ }
+ }
+ else
+ {
+ link->alias_port = port_net;
+ return(0);
+ }
+ }
+
+ port_sys = random() & ALIAS_PORT_MASK;
+ port_sys += ALIAS_PORT_BASE;
+ port_net = htons(port_sys);
+ }
+
+#ifdef DEBUG
+ fprintf(stderr, "PacketAlias/GetnewPort(): ");
+ fprintf(stderr, "could not find free port\n");
+#endif
+
+ return(-1);
+}
+
+
+static u_short
+GetSocket(u_short port_net, int *sockfd, int link_type)
+{
+ int err;
+ int sock;
+ struct sockaddr_in sock_addr;
+
+ if (link_type == LINK_TCP)
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ else if (link_type == LINK_UDP)
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ else
+ {
+#ifdef DEBUG
+ fprintf(stderr, "PacketAlias/GetSocket(): ");
+ fprintf(stderr, "incorrect link type\n");
+#endif
+ return(0);
+ }
+
+ if (sock < 0)
+ {
+#ifdef DEBUG
+ fprintf(stderr, "PacketAlias/GetSocket(): ");
+ fprintf(stderr, "socket() error %d\n", *sockfd);
+#endif
+ return(0);
+ }
+
+ sock_addr.sin_family = AF_INET;
+ sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ sock_addr.sin_port = port_net;
+
+ err = bind(sock,
+ (struct sockaddr *) &sock_addr,
+ sizeof(sock_addr));
+ if (err == 0)
+ {
+ sockCount++;
+ *sockfd = sock;
+ return(1);
+ }
+ else
+ {
+ close(sock);
+ return(0);
+ }
+}
+
+
+static void
+CleanupAliasData(void)
+{
+ struct alias_link *link;
+ int i, icount;
+
+ icount = 0;
+ for (i=0; i<LINK_TABLE_OUT_SIZE; i++)
+ {
+ link = linkTableOut[i];
+ while (link != NULL)
+ {
+ struct alias_link *link_next;
+ link_next = link->next_out;
+ icount++;
+ DeleteLink(link);
+ link = link_next;
+ }
+ }
+
+ cleanupIndex =0;
+}
+
+
+static void
+IncrementalCleanup(void)
+{
+ int icount;
+ struct alias_link *link;
+
+ icount = 0;
+ link = linkTableOut[cleanupIndex++];
+ while (link != NULL)
+ {
+ int idelta;
+ struct alias_link *link_next;
+
+ link_next = link->next_out;
+ idelta = timeStamp - link->timestamp;
+ switch (link->link_type)
+ {
+ case LINK_ICMP:
+ case LINK_UDP:
+ case LINK_FRAGMENT_ID:
+ case LINK_FRAGMENT_PTR:
+ if (idelta > link->expire_time)
+ {
+ DeleteLink(link);
+ icount++;
+ }
+ break;
+ case LINK_TCP:
+ if (idelta > link->expire_time)
+ {
+ struct tcp_dat *tcp_aux;
+
+ tcp_aux = link->data.tcp;
+ if (tcp_aux->state.in != ALIAS_TCP_STATE_CONNECTED
+ || tcp_aux->state.out != ALIAS_TCP_STATE_CONNECTED)
+ {
+ DeleteLink(link);
+ icount++;
+ }
+ }
+ break;
+ }
+ link = link_next;
+ }
+
+ if (cleanupIndex == LINK_TABLE_OUT_SIZE)
+ cleanupIndex = 0;
+}
+
+void
+DeleteLink(struct alias_link *link)
+{
+ struct alias_link *link_last;
+ struct alias_link *link_next;
+
+/* Don't do anything if the link is marked permanent */
+ if (deleteAllLinks == 0 && link->flags & LINK_PERMANENT)
+ return;
+
+#ifndef NO_FW_PUNCH
+/* Delete associatied firewall hole, if any */
+ ClearFWHole(link);
+#endif
+
+/* Adjust output table pointers */
+ link_last = link->last_out;
+ link_next = link->next_out;
+
+ if (link_last != NULL)
+ link_last->next_out = link_next;
+ else
+ linkTableOut[link->start_point_out] = link_next;
+
+ if (link_next != NULL)
+ link_next->last_out = link_last;
+
+/* Adjust input table pointers */
+ link_last = link->last_in;
+ link_next = link->next_in;
+
+ if (link_last != NULL)
+ link_last->next_in = link_next;
+ else
+ linkTableIn[link->start_point_in] = link_next;
+
+ if (link_next != NULL)
+ link_next->last_in = link_last;
+
+/* Close socket, if one has been allocated */
+ if (link->sockfd != -1)
+ {
+ sockCount--;
+ close(link->sockfd);
+ }
+
+/* Link-type dependent cleanup */
+ switch(link->link_type)
+ {
+ case LINK_ICMP:
+ icmpLinkCount--;
+ break;
+ case LINK_UDP:
+ udpLinkCount--;
+ break;
+ case LINK_TCP:
+ tcpLinkCount--;
+ if (link->data.tcp != NULL)
+ free(link->data.tcp);
+ break;
+ case LINK_FRAGMENT_ID:
+ fragmentIdLinkCount--;
+ break;
+ case LINK_FRAGMENT_PTR:
+ fragmentPtrLinkCount--;
+ if (link->data.frag_ptr != NULL)
+ free(link->data.frag_ptr);
+ break;
+ }
+
+/* Free memory */
+ free(link);
+
+/* Write statistics, if logging enabled */
+ if (packetAliasMode & PKT_ALIAS_LOG)
+ {
+ ShowAliasStats();
+ }
+}
+
+
+static struct alias_link *
+AddLink(struct in_addr src_addr,
+ struct in_addr dst_addr,
+ struct in_addr alias_addr,
+ u_short src_port,
+ u_short dst_port,
+ int alias_port_param, /* if less than zero, alias */
+ int link_type) /* port will be automatically */
+{ /* chosen. If greater than */
+ u_int start_point; /* zero, equal to alias port */
+ struct alias_link *link;
+ struct alias_link *first_link;
+
+ link = malloc(sizeof(struct alias_link));
+ if (link != NULL)
+ {
+ /* Basic initialization */
+ link->src_addr = src_addr;
+ link->dst_addr = dst_addr;
+ link->alias_addr = alias_addr;
+ link->proxy_addr.s_addr = 0;
+ link->src_port = src_port;
+ link->dst_port = dst_port;
+ link->proxy_port = 0;
+ link->link_type = link_type;
+ link->sockfd = -1;
+ link->flags = 0;
+ link->timestamp = timeStamp;
+
+ /* Expiration time */
+ switch (link_type)
+ {
+ case LINK_ICMP:
+ link->expire_time = ICMP_EXPIRE_TIME;
+ break;
+ case LINK_UDP:
+ link->expire_time = UDP_EXPIRE_TIME;
+ break;
+ case LINK_TCP:
+ link->expire_time = TCP_EXPIRE_INITIAL;
+ break;
+ case LINK_FRAGMENT_ID:
+ link->expire_time = FRAGMENT_ID_EXPIRE_TIME;
+ break;
+ case LINK_FRAGMENT_PTR:
+ link->expire_time = FRAGMENT_PTR_EXPIRE_TIME;
+ break;
+ }
+
+ /* Determine alias flags */
+ if (dst_addr.s_addr == 0)
+ link->flags |= LINK_UNKNOWN_DEST_ADDR;
+ if (dst_port == 0)
+ link->flags |= LINK_UNKNOWN_DEST_PORT;
+
+ /* Determine alias port */
+ if (GetNewPort(link, alias_port_param) != 0)
+ {
+ free(link);
+ return(NULL);
+ }
+
+ /* Set up pointers for output lookup table */
+ start_point = StartPointOut(src_addr, dst_addr,
+ src_port, dst_port, link_type);
+ first_link = linkTableOut[start_point];
+
+ link->last_out = NULL;
+ link->next_out = first_link;
+ link->start_point_out = start_point;
+
+ if (first_link != NULL)
+ first_link->last_out = link;
+
+ linkTableOut[start_point] = link;
+
+ /* Set up pointers for input lookup table */
+ start_point = StartPointIn(alias_addr, link->alias_port, link_type);
+ first_link = linkTableIn[start_point];
+
+ link->last_in = NULL;
+ link->next_in = first_link;
+ link->start_point_in = start_point;
+
+ if (first_link != NULL)
+ first_link->last_in = link;
+
+ linkTableIn[start_point] = link;
+
+ /* Link-type dependent initialization */
+ switch(link_type)
+ {
+ struct tcp_dat *aux_tcp;
+
+ case LINK_ICMP:
+ icmpLinkCount++;
+ break;
+ case LINK_UDP:
+ udpLinkCount++;
+ break;
+ case LINK_TCP:
+ aux_tcp = malloc(sizeof(struct tcp_dat));
+ link->data.tcp = aux_tcp;
+ if (aux_tcp != NULL)
+ {
+ int i;
+
+ tcpLinkCount++;
+ aux_tcp->state.in = ALIAS_TCP_STATE_NOT_CONNECTED;
+ aux_tcp->state.out = ALIAS_TCP_STATE_NOT_CONNECTED;
+ aux_tcp->state.index = 0;
+ aux_tcp->state.ack_modified = 0;
+ for (i=0; i<N_LINK_TCP_DATA; i++)
+ aux_tcp->ack[i].active = 0;
+ aux_tcp->fwhole = -1;
+ }
+ else
+ {
+#ifdef DEBUG
+ fprintf(stderr, "PacketAlias/AddLink: ");
+ fprintf(stderr, " cannot allocate auxiliary TCP data\n");
+#endif
+ }
+ break;
+ case LINK_FRAGMENT_ID:
+ fragmentIdLinkCount++;
+ break;
+ case LINK_FRAGMENT_PTR:
+ fragmentPtrLinkCount++;
+ break;
+ }
+ }
+ else
+ {
+#ifdef DEBUG
+ fprintf(stderr, "PacketAlias/AddLink(): ");
+ fprintf(stderr, "malloc() call failed.\n");
+#endif
+ }
+
+ if (packetAliasMode & PKT_ALIAS_LOG)
+ {
+ ShowAliasStats();
+ }
+
+ return(link);
+}
+
+static struct alias_link *
+ReLink(struct alias_link *old_link,
+ struct in_addr src_addr,
+ struct in_addr dst_addr,
+ struct in_addr alias_addr,
+ u_short src_port,
+ u_short dst_port,
+ int alias_port_param, /* if less than zero, alias */
+ int link_type) /* port will be automatically */
+{ /* chosen. If greater than */
+ struct alias_link *new_link; /* zero, equal to alias port */
+
+ new_link = AddLink(src_addr, dst_addr, alias_addr,
+ src_port, dst_port, alias_port_param,
+ link_type);
+#ifndef NO_FW_PUNCH
+ if (new_link != NULL &&
+ old_link->link_type == LINK_TCP &&
+ old_link->data.tcp &&
+ old_link->data.tcp->fwhole > 0) {
+ PunchFWHole(new_link);
+ }
+#endif
+ DeleteLink(old_link);
+ return new_link;
+}
+
+static struct alias_link *
+_FindLinkOut(struct in_addr src_addr,
+ struct in_addr dst_addr,
+ u_short src_port,
+ u_short dst_port,
+ int link_type,
+ int replace_partial_links)
+{
+ u_int i;
+ struct alias_link *link;
+
+ i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type);
+ link = linkTableOut[i];
+ while (link != NULL)
+ {
+ if (link->src_addr.s_addr == src_addr.s_addr
+ && link->dst_addr.s_addr == dst_addr.s_addr
+ && link->dst_port == dst_port
+ && link->src_port == src_port
+ && link->link_type == link_type)
+ {
+ link->timestamp = timeStamp;
+ break;
+ }
+ link = link->next_out;
+ }
+
+/* Search for partially specified links. */
+ if (link == NULL)
+ {
+ if (dst_port != 0)
+ {
+ link = _FindLinkOut(src_addr, dst_addr, src_port, 0,
+ link_type, 0);
+ if (link != NULL && replace_partial_links)
+ {
+ link = ReLink(link,
+ src_addr, dst_addr, link->alias_addr,
+ src_port, dst_port, link->alias_port,
+ link_type);
+ }
+ }
+ else if (dst_addr.s_addr != 0)
+ {
+ link = _FindLinkOut(src_addr, nullAddress, src_port, 0,
+ link_type, 0);
+ }
+ }
+
+ return(link);
+}
+
+static struct alias_link *
+FindLinkOut(struct in_addr src_addr,
+ struct in_addr dst_addr,
+ u_short src_port,
+ u_short dst_port,
+ int link_type,
+ int replace_partial_links)
+{
+ struct alias_link *link;
+
+ link = _FindLinkOut(src_addr, dst_addr, src_port, dst_port,
+ link_type, replace_partial_links);
+
+ if (link == NULL)
+ {
+ /* The following allows permanent links to be
+ specified as using the default source address
+ (i.e. device interface address) without knowing
+ in advance what that address is. */
+ if (aliasAddress.s_addr != 0 &&
+ src_addr.s_addr == aliasAddress.s_addr)
+ {
+ link = _FindLinkOut(nullAddress, dst_addr, src_port, dst_port,
+ link_type, replace_partial_links);
+ }
+ }
+
+ return(link);
+}
+
+
+struct alias_link *
+_FindLinkIn(struct in_addr dst_addr,
+ struct in_addr alias_addr,
+ u_short dst_port,
+ u_short alias_port,
+ int link_type,
+ int replace_partial_links)
+{
+ int flags_in;
+ u_int start_point;
+ struct alias_link *link;
+ struct alias_link *link_fully_specified;
+ struct alias_link *link_unknown_all;
+ struct alias_link *link_unknown_dst_addr;
+ struct alias_link *link_unknown_dst_port;
+
+/* Initialize pointers */
+ link_fully_specified = NULL;
+ link_unknown_all = NULL;
+ link_unknown_dst_addr = NULL;
+ link_unknown_dst_port = NULL;
+
+/* If either the dest addr or port is unknown, the search
+ loop will have to know about this. */
+
+ flags_in = 0;
+ if (dst_addr.s_addr == 0)
+ flags_in |= LINK_UNKNOWN_DEST_ADDR;
+ if (dst_port == 0)
+ flags_in |= LINK_UNKNOWN_DEST_PORT;
+
+/* Search loop */
+ start_point = StartPointIn(alias_addr, alias_port, link_type);
+ link = linkTableIn[start_point];
+ while (link != NULL)
+ {
+ int flags;
+
+ flags = flags_in | link->flags;
+ if (!(flags & LINK_PARTIALLY_SPECIFIED))
+ {
+ if (link->alias_addr.s_addr == alias_addr.s_addr
+ && link->alias_port == alias_port
+ && link->dst_addr.s_addr == dst_addr.s_addr
+ && link->dst_port == dst_port
+ && link->link_type == link_type)
+ {
+ link_fully_specified = link;
+ break;
+ }
+ }
+ else if ((flags & LINK_UNKNOWN_DEST_ADDR)
+ && (flags & LINK_UNKNOWN_DEST_PORT))
+ {
+ if (link->alias_addr.s_addr == alias_addr.s_addr
+ && link->alias_port == alias_port
+ && link->link_type == link_type)
+ {
+ if (link_unknown_all == NULL)
+ link_unknown_all = link;
+ }
+ }
+ else if (flags & LINK_UNKNOWN_DEST_ADDR)
+ {
+ if (link->alias_addr.s_addr == alias_addr.s_addr
+ && link->alias_port == alias_port
+ && link->link_type == link_type
+ && link->dst_port == dst_port)
+ {
+ if (link_unknown_dst_addr == NULL)
+ link_unknown_dst_addr = link;
+ }
+ }
+ else if (flags & LINK_UNKNOWN_DEST_PORT)
+ {
+ if (link->alias_addr.s_addr == alias_addr.s_addr
+ && link->alias_port == alias_port
+ && link->link_type == link_type
+ && link->dst_addr.s_addr == dst_addr.s_addr)
+ {
+ if (link_unknown_dst_port == NULL)
+ link_unknown_dst_port = link;
+ }
+ }
+ link = link->next_in;
+ }
+
+
+
+ if (link_fully_specified != NULL)
+ {
+ link_fully_specified->timestamp = timeStamp;
+ return link_fully_specified;
+ }
+ else if (link_unknown_dst_port != NULL)
+ {
+ return replace_partial_links
+ ? ReLink(link_unknown_dst_port,
+ link_unknown_dst_port->src_addr, dst_addr, alias_addr,
+ link_unknown_dst_port->src_port, dst_port, alias_port,
+ link_type)
+ : link_unknown_dst_port;
+ }
+ else if (link_unknown_dst_addr != NULL)
+ {
+ return replace_partial_links
+ ? ReLink(link_unknown_dst_addr,
+ link_unknown_dst_addr->src_addr, dst_addr, alias_addr,
+ link_unknown_dst_addr->src_port, dst_port, alias_port,
+ link_type)
+ : link_unknown_dst_addr;
+ }
+ else if (link_unknown_all != NULL)
+ {
+ return replace_partial_links
+ ? ReLink(link_unknown_all,
+ link_unknown_all->src_addr, dst_addr, alias_addr,
+ link_unknown_all->src_port, dst_port, alias_port,
+ link_type)
+ : link_unknown_all;
+ }
+ else
+ {
+ return(NULL);
+ }
+}
+
+struct alias_link *
+FindLinkIn(struct in_addr dst_addr,
+ struct in_addr alias_addr,
+ u_short dst_port,
+ u_short alias_port,
+ int link_type,
+ int replace_partial_links)
+{
+ struct alias_link *link;
+
+ link = _FindLinkIn(dst_addr, alias_addr, dst_port, alias_port,
+ link_type, replace_partial_links);
+
+ if (link == NULL)
+ {
+ /* The following allows permanent links to be
+ specified as using the default aliasing address
+ (i.e. device interface address) without knowing
+ in advance what that address is. */
+ if (aliasAddress.s_addr != 0 &&
+ alias_addr.s_addr == aliasAddress.s_addr)
+ {
+ link = _FindLinkIn(dst_addr, nullAddress, dst_port, alias_port,
+ link_type, replace_partial_links);
+ }
+ }
+
+ return(link);
+}
+
+
+
+
+/* External routines for finding/adding links
+
+-- "external" means outside alias_db.c, but within alias*.c --
+
+ FindIcmpIn(), FindIcmpOut()
+ FindFragmentIn1(), FindFragmentIn2()
+ AddFragmentPtrLink(), FindFragmentPtr()
+ FindUdpTcpIn(), FindUdpTcpOut()
+ FindOriginalAddress(), FindAliasAddress()
+
+(prototypes in alias_local.h)
+*/
+
+
+struct alias_link *
+FindIcmpIn(struct in_addr dst_addr,
+ struct in_addr alias_addr,
+ u_short id_alias)
+{
+ return FindLinkIn(dst_addr, alias_addr,
+ NO_DEST_PORT, id_alias,
+ LINK_ICMP, 0);
+}
+
+
+struct alias_link *
+FindIcmpOut(struct in_addr src_addr,
+ struct in_addr dst_addr,
+ u_short id)
+{
+ struct alias_link * link;
+
+ link = FindLinkOut(src_addr, dst_addr,
+ id, NO_DEST_PORT,
+ LINK_ICMP, 0);
+ if (link == NULL)
+ {
+ struct in_addr alias_addr;
+
+ alias_addr = FindAliasAddress(src_addr);
+ link = AddLink(src_addr, dst_addr, alias_addr,
+ id, NO_DEST_PORT, GET_ALIAS_ID,
+ LINK_ICMP);
+ }
+
+ return(link);
+}
+
+
+struct alias_link *
+FindFragmentIn1(struct in_addr dst_addr,
+ struct in_addr alias_addr,
+ u_short ip_id)
+{
+ struct alias_link *link;
+
+ link = FindLinkIn(dst_addr, alias_addr,
+ NO_DEST_PORT, ip_id,
+ LINK_FRAGMENT_ID, 0);
+
+ if (link == NULL)
+ {
+ link = AddLink(nullAddress, dst_addr, alias_addr,
+ NO_SRC_PORT, NO_DEST_PORT, ip_id,
+ LINK_FRAGMENT_ID);
+ }
+
+ return(link);
+}
+
+
+struct alias_link *
+FindFragmentIn2(struct in_addr dst_addr, /* Doesn't add a link if one */
+ struct in_addr alias_addr, /* is not found. */
+ u_short ip_id)
+{
+ return FindLinkIn(dst_addr, alias_addr,
+ NO_DEST_PORT, ip_id,
+ LINK_FRAGMENT_ID, 0);
+}
+
+
+struct alias_link *
+AddFragmentPtrLink(struct in_addr dst_addr,
+ u_short ip_id)
+{
+ return AddLink(nullAddress, dst_addr, nullAddress,
+ NO_SRC_PORT, NO_DEST_PORT, ip_id,
+ LINK_FRAGMENT_PTR);
+}
+
+
+struct alias_link *
+FindFragmentPtr(struct in_addr dst_addr,
+ u_short ip_id)
+{
+ return FindLinkIn(dst_addr, nullAddress,
+ NO_DEST_PORT, ip_id,
+ LINK_FRAGMENT_PTR, 0);
+}
+
+
+struct alias_link *
+FindUdpTcpIn(struct in_addr dst_addr,
+ struct in_addr alias_addr,
+ u_short dst_port,
+ u_short alias_port,
+ u_char proto)
+{
+ int link_type;
+ struct alias_link *link;
+
+ switch (proto)
+ {
+ case IPPROTO_UDP:
+ link_type = LINK_UDP;
+ break;
+ case IPPROTO_TCP:
+ link_type = LINK_TCP;
+ break;
+ default:
+ return NULL;
+ break;
+ }
+
+ link = FindLinkIn(dst_addr, alias_addr,
+ dst_port, alias_port,
+ link_type, 1);
+
+ if (!(packetAliasMode & PKT_ALIAS_DENY_INCOMING)
+ && !(packetAliasMode & PKT_ALIAS_PROXY_ONLY)
+ && link == NULL)
+ {
+ struct in_addr target_addr;
+
+ target_addr = FindOriginalAddress(alias_addr);
+ link = AddLink(target_addr, dst_addr, alias_addr,
+ alias_port, dst_port, alias_port,
+ link_type);
+ }
+
+ return(link);
+}
+
+
+struct alias_link *
+FindUdpTcpOut(struct in_addr src_addr,
+ struct in_addr dst_addr,
+ u_short src_port,
+ u_short dst_port,
+ u_char proto)
+{
+ int link_type;
+ struct alias_link *link;
+
+ switch (proto)
+ {
+ case IPPROTO_UDP:
+ link_type = LINK_UDP;
+ break;
+ case IPPROTO_TCP:
+ link_type = LINK_TCP;
+ break;
+ default:
+ return NULL;
+ break;
+ }
+
+ link = FindLinkOut(src_addr, dst_addr, src_port, dst_port, link_type, 1);
+
+ if (link == NULL)
+ {
+ struct in_addr alias_addr;
+
+ alias_addr = FindAliasAddress(src_addr);
+ link = AddLink(src_addr, dst_addr, alias_addr,
+ src_port, dst_port, GET_ALIAS_PORT,
+ link_type);
+ }
+
+ return(link);
+}
+
+
+struct in_addr
+FindOriginalAddress(struct in_addr alias_addr)
+{
+ struct alias_link *link;
+
+ link = FindLinkIn(nullAddress, alias_addr,
+ 0, 0, LINK_ADDR, 0);
+ if (link == NULL)
+ {
+ newDefaultLink = 1;
+ if (targetAddress.s_addr != 0)
+ return targetAddress;
+ else
+ return alias_addr;
+ }
+ else
+ {
+ if (link->src_addr.s_addr == 0)
+ return aliasAddress;
+ else
+ return link->src_addr;
+ }
+}
+
+
+struct in_addr
+FindAliasAddress(struct in_addr original_addr)
+{
+ struct alias_link *link;
+
+ link = FindLinkOut(original_addr, nullAddress,
+ 0, 0, LINK_ADDR, 0);
+ if (link == NULL)
+ {
+ return aliasAddress;
+ }
+ else
+ {
+ if (link->alias_addr.s_addr == 0)
+ return aliasAddress;
+ else
+ return link->alias_addr;
+ }
+}
+
+
+/* External routines for getting or changing link data
+ (external to alias_db.c, but internal to alias*.c)
+
+ SetFragmentData(), GetFragmentData()
+ SetFragmentPtr(), GetFragmentPtr()
+ SetStateIn(), SetStateOut(), GetStateIn(), GetStateOut()
+ GetOriginalAddress(), GetDestAddress(), GetAliasAddress()
+ GetOriginalPort(), GetAliasPort()
+ SetAckModified(), GetAckModified()
+ GetDeltaAckIn(), GetDeltaSeqOut(), AddSeq()
+*/
+
+
+void
+SetFragmentAddr(struct alias_link *link, struct in_addr src_addr)
+{
+ link->data.frag_addr = src_addr;
+}
+
+
+void
+GetFragmentAddr(struct alias_link *link, struct in_addr *src_addr)
+{
+ *src_addr = link->data.frag_addr;
+}
+
+
+void
+SetFragmentPtr(struct alias_link *link, char *fptr)
+{
+ link->data.frag_ptr = fptr;
+}
+
+
+void
+GetFragmentPtr(struct alias_link *link, char **fptr)
+{
+ *fptr = link->data.frag_ptr;
+}
+
+
+void
+SetStateIn(struct alias_link *link, int state)
+{
+ /* TCP input state */
+ switch (state) {
+ case ALIAS_TCP_STATE_DISCONNECTED:
+ if (link->data.tcp->state.out != ALIAS_TCP_STATE_CONNECTED) {
+ link->expire_time = TCP_EXPIRE_DEAD;
+ } else {
+ link->expire_time = TCP_EXPIRE_SINGLEDEAD;
+ }
+ link->data.tcp->state.in = state;
+ break;
+ case ALIAS_TCP_STATE_CONNECTED:
+ link->expire_time = TCP_EXPIRE_CONNECTED;
+ /*FALLTHROUGH*/
+ case ALIAS_TCP_STATE_NOT_CONNECTED:
+ link->data.tcp->state.in = state;
+ break;
+ default:
+ abort();
+ }
+}
+
+
+void
+SetStateOut(struct alias_link *link, int state)
+{
+ /* TCP output state */
+ switch (state) {
+ case ALIAS_TCP_STATE_DISCONNECTED:
+ if (link->data.tcp->state.in != ALIAS_TCP_STATE_CONNECTED) {
+ link->expire_time = TCP_EXPIRE_DEAD;
+ } else {
+ link->expire_time = TCP_EXPIRE_SINGLEDEAD;
+ }
+ link->data.tcp->state.out = state;
+ break;
+ case ALIAS_TCP_STATE_CONNECTED:
+ link->expire_time = TCP_EXPIRE_CONNECTED;
+ /*FALLTHROUGH*/
+ case ALIAS_TCP_STATE_NOT_CONNECTED:
+ link->data.tcp->state.out = state;
+ break;
+ default:
+ abort();
+ }
+}
+
+
+int
+GetStateIn(struct alias_link *link)
+{
+ /* TCP input state */
+ return link->data.tcp->state.in;
+}
+
+
+int
+GetStateOut(struct alias_link *link)
+{
+ /* TCP output state */
+ return link->data.tcp->state.out;
+}
+
+
+struct in_addr
+GetOriginalAddress(struct alias_link *link)
+{
+ if (link->src_addr.s_addr == 0)
+ return aliasAddress;
+ else
+ return(link->src_addr);
+}
+
+
+struct in_addr
+GetDestAddress(struct alias_link *link)
+{
+ return(link->dst_addr);
+}
+
+
+struct in_addr
+GetAliasAddress(struct alias_link *link)
+{
+ if (link->alias_addr.s_addr == 0)
+ return aliasAddress;
+ else
+ return link->alias_addr;
+}
+
+
+struct in_addr
+GetDefaultAliasAddress()
+{
+ return aliasAddress;
+}
+
+
+void
+SetDefaultAliasAddress(struct in_addr alias_addr)
+{
+ aliasAddress = alias_addr;
+}
+
+
+u_short
+GetOriginalPort(struct alias_link *link)
+{
+ return(link->src_port);
+}
+
+
+u_short
+GetAliasPort(struct alias_link *link)
+{
+ return(link->alias_port);
+}
+
+u_short
+GetDestPort(struct alias_link *link)
+{
+ return(link->dst_port);
+}
+
+void
+SetAckModified(struct alias_link *link)
+{
+/* Indicate that ack numbers have been modified in a TCP connection */
+ link->data.tcp->state.ack_modified = 1;
+}
+
+
+struct in_addr
+GetProxyAddress(struct alias_link *link)
+{
+ return link->proxy_addr;
+}
+
+
+void
+SetProxyAddress(struct alias_link *link, struct in_addr addr)
+{
+ link->proxy_addr = addr;
+}
+
+
+u_short
+GetProxyPort(struct alias_link *link)
+{
+ return link->proxy_port;
+}
+
+
+void
+SetProxyPort(struct alias_link *link, u_short port)
+{
+ link->proxy_port = port;
+}
+
+
+int
+GetAckModified(struct alias_link *link)
+{
+/* See if ack numbers have been modified */
+ return link->data.tcp->state.ack_modified;
+}
+
+
+int
+GetDeltaAckIn(struct ip *pip, struct alias_link *link)
+{
+/*
+Find out how much the ack number has been altered for an incoming
+TCP packet. To do this, a circular list is ack numbers where the TCP
+packet size was altered is searched.
+*/
+
+ int i;
+ struct tcphdr *tc;
+ int delta, ack_diff_min;
+ u_long ack;
+
+ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+ ack = tc->th_ack;
+
+ delta = 0;
+ ack_diff_min = -1;
+ for (i=0; i<N_LINK_TCP_DATA; i++)
+ {
+ struct ack_data_record x;
+
+ x = link->data.tcp->ack[i];
+ if (x.active == 1)
+ {
+ int ack_diff;
+
+ ack_diff = SeqDiff(x.ack_new, ack);
+ if (ack_diff >= 0)
+ {
+ if (ack_diff_min >= 0)
+ {
+ if (ack_diff < ack_diff_min)
+ {
+ delta = x.delta;
+ ack_diff_min = ack_diff;
+ }
+ }
+ else
+ {
+ delta = x.delta;
+ ack_diff_min = ack_diff;
+ }
+ }
+ }
+ }
+ return (delta);
+}
+
+
+int
+GetDeltaSeqOut(struct ip *pip, struct alias_link *link)
+{
+/*
+Find out how much the seq number has been altered for an outgoing
+TCP packet. To do this, a circular list is ack numbers where the TCP
+packet size was altered is searched.
+*/
+
+ int i;
+ struct tcphdr *tc;
+ int delta, seq_diff_min;
+ u_long seq;
+
+ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+ seq = tc->th_seq;
+
+ delta = 0;
+ seq_diff_min = -1;
+ for (i=0; i<N_LINK_TCP_DATA; i++)
+ {
+ struct ack_data_record x;
+
+ x = link->data.tcp->ack[i];
+ if (x.active == 1)
+ {
+ int seq_diff;
+
+ seq_diff = SeqDiff(x.ack_old, seq);
+ if (seq_diff >= 0)
+ {
+ if (seq_diff_min >= 0)
+ {
+ if (seq_diff < seq_diff_min)
+ {
+ delta = x.delta;
+ seq_diff_min = seq_diff;
+ }
+ }
+ else
+ {
+ delta = x.delta;
+ seq_diff_min = seq_diff;
+ }
+ }
+ }
+ }
+ return (delta);
+}
+
+
+void
+AddSeq(struct ip *pip, struct alias_link *link, int delta)
+{
+/*
+When a TCP packet has been altered in length, save this
+information in a circular list. If enough packets have
+been altered, then this list will begin to overwrite itself.
+*/
+
+ struct tcphdr *tc;
+ struct ack_data_record x;
+ int hlen, tlen, dlen;
+ int i;
+
+ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+ hlen = (pip->ip_hl + tc->th_off) << 2;
+ tlen = ntohs(pip->ip_len);
+ dlen = tlen - hlen;
+
+ x.ack_old = htonl(ntohl(tc->th_seq) + dlen);
+ x.ack_new = htonl(ntohl(tc->th_seq) + dlen + delta);
+ x.delta = delta;
+ x.active = 1;
+
+ i = link->data.tcp->state.index;
+ link->data.tcp->ack[i] = x;
+
+ i++;
+ if (i == N_LINK_TCP_DATA)
+ link->data.tcp->state.index = 0;
+ else
+ link->data.tcp->state.index = i;
+}
+
+void
+SetExpire(struct alias_link *link, int expire)
+{
+ if (expire == 0)
+ {
+ link->flags &= ~LINK_PERMANENT;
+ DeleteLink(link);
+ }
+ else if (expire == -1)
+ {
+ link->flags |= LINK_PERMANENT;
+ }
+ else if (expire > 0)
+ {
+ link->expire_time = expire;
+ }
+ else
+ {
+#ifdef DEBUG
+ fprintf(stderr, "PacketAlias/SetExpire(): ");
+ fprintf(stderr, "error in expire parameter\n");
+#endif
+ }
+}
+
+void
+ClearCheckNewLink(void)
+{
+ newDefaultLink = 0;
+}
+
+
+/* Miscellaneous Functions
+
+ HouseKeeping()
+ InitPacketAliasLog()
+ UninitPacketAliasLog()
+*/
+
+/*
+ Whenever an outgoing or incoming packet is handled, HouseKeeping()
+ is called to find and remove timed-out aliasing links. Logic exists
+ to sweep through the entire table and linked list structure
+ every 60 seconds.
+
+ (prototype in alias_local.h)
+*/
+
+void
+HouseKeeping(void)
+{
+ int i, n, n100;
+ struct timeval tv;
+ struct timezone tz;
+
+ /*
+ * Save system time (seconds) in global variable timeStamp for
+ * use by other functions. This is done so as not to unnecessarily
+ * waste timeline by making system calls.
+ */
+ gettimeofday(&tv, &tz);
+ timeStamp = tv.tv_sec;
+
+ /* Compute number of spokes (output table link chains) to cover */
+ n100 = LINK_TABLE_OUT_SIZE * 100 + houseKeepingResidual;
+ n100 *= timeStamp - lastCleanupTime;
+ n100 /= ALIAS_CLEANUP_INTERVAL_SECS;
+
+ n = n100/100;
+
+ /* Handle different cases */
+ if (n > ALIAS_CLEANUP_MAX_SPOKES)
+ {
+ n = ALIAS_CLEANUP_MAX_SPOKES;
+ lastCleanupTime = timeStamp;
+ houseKeepingResidual = 0;
+
+ for (i=0; i<n; i++)
+ IncrementalCleanup();
+ }
+ else if (n > 0)
+ {
+ lastCleanupTime = timeStamp;
+ houseKeepingResidual = n100 - 100*n;
+
+ for (i=0; i<n; i++)
+ IncrementalCleanup();
+ }
+ else if (n < 0)
+ {
+#ifdef DEBUG
+ fprintf(stderr, "PacketAlias/HouseKeeping(): ");
+ fprintf(stderr, "something unexpected in time values\n");
+#endif
+ lastCleanupTime = timeStamp;
+ houseKeepingResidual = 0;
+ }
+}
+
+
+/* Init the log file and enable logging */
+static void
+InitPacketAliasLog(void)
+{
+ if ((~packetAliasMode & PKT_ALIAS_LOG)
+ && (monitorFile = fopen("/var/log/alias.log", "w")))
+ {
+ packetAliasMode |= PKT_ALIAS_LOG;
+ fprintf(monitorFile,
+ "PacketAlias/InitPacketAliasLog: Packet alias logging enabled.\n");
+ }
+}
+
+
+/* Close the log-file and disable logging. */
+static void
+UninitPacketAliasLog(void)
+{
+ if (monitorFile) {
+ fclose(monitorFile);
+ monitorFile = NULL;
+ }
+ packetAliasMode &= ~PKT_ALIAS_LOG;
+}
+
+
+
+
+
+
+/* Outside world interfaces
+
+-- "outside world" means other than alias*.c routines --
+
+ PacketAliasRedirectPort()
+ PacketAliasRedirectAddr()
+ PacketAliasRedirectDelete()
+ PacketAliasSetAddress()
+ PacketAliasInit()
+ PacketAliasUninit()
+ PacketAliasSetMode()
+
+(prototypes in alias.h)
+*/
+
+/* Redirection from a specific public addr:port to a
+ a private addr:port */
+struct alias_link *
+PacketAliasRedirectPort(struct in_addr src_addr, u_short src_port,
+ struct in_addr dst_addr, u_short dst_port,
+ struct in_addr alias_addr, u_short alias_port,
+ u_char proto)
+{
+ int link_type;
+ struct alias_link *link;
+
+ switch(proto)
+ {
+ case IPPROTO_UDP:
+ link_type = LINK_UDP;
+ break;
+ case IPPROTO_TCP:
+ link_type = LINK_TCP;
+ break;
+ default:
+#ifdef DEBUG
+ fprintf(stderr, "PacketAliasRedirectPort(): ");
+ fprintf(stderr, "only TCP and UDP protocols allowed\n");
+#endif
+ return NULL;
+ }
+
+ link = AddLink(src_addr, dst_addr, alias_addr,
+ src_port, dst_port, alias_port,
+ link_type);
+
+ if (link != NULL)
+ {
+ link->flags |= LINK_PERMANENT;
+ }
+#ifdef DEBUG
+ else
+ {
+ fprintf(stderr, "PacketAliasRedirectPort(): "
+ "call to AddLink() failed\n");
+ }
+#endif
+
+ return link;
+}
+
+/* Translate PPTP packets to a machine on the inside
+ */
+int
+PacketAliasPptp(struct in_addr src_addr)
+{
+
+ pptpAliasAddr = src_addr; /* Address of the inside PPTP machine */
+ pptpAliasFlag = src_addr.s_addr != INADDR_NONE;
+
+ return 1;
+}
+
+int GetPptpAlias (struct in_addr* alias_addr)
+{
+ if (pptpAliasFlag)
+ *alias_addr = pptpAliasAddr;
+
+ return pptpAliasFlag;
+}
+
+/* Static address translation */
+struct alias_link *
+PacketAliasRedirectAddr(struct in_addr src_addr,
+ struct in_addr alias_addr)
+{
+ struct alias_link *link;
+
+ link = AddLink(src_addr, nullAddress, alias_addr,
+ 0, 0, 0,
+ LINK_ADDR);
+
+ if (link != NULL)
+ {
+ link->flags |= LINK_PERMANENT;
+ }
+#ifdef DEBUG
+ else
+ {
+ fprintf(stderr, "PacketAliasRedirectAddr(): "
+ "call to AddLink() failed\n");
+ }
+#endif
+
+ return link;
+}
+
+
+void
+PacketAliasRedirectDelete(struct alias_link *link)
+{
+/* This is a dangerous function to put in the API,
+ because an invalid pointer can crash the program. */
+
+ deleteAllLinks = 1;
+ DeleteLink(link);
+ deleteAllLinks = 0;
+}
+
+
+void
+PacketAliasSetAddress(struct in_addr addr)
+{
+ if (packetAliasMode & PKT_ALIAS_RESET_ON_ADDR_CHANGE
+ && aliasAddress.s_addr != addr.s_addr)
+ CleanupAliasData();
+
+ aliasAddress = addr;
+}
+
+
+void
+PacketAliasSetTarget(struct in_addr target_addr)
+{
+ targetAddress = target_addr;
+}
+
+
+void
+PacketAliasInit(void)
+{
+ int i;
+ struct timeval tv;
+ struct timezone tz;
+ static int firstCall = 1;
+
+ if (firstCall == 1)
+ {
+ gettimeofday(&tv, &tz);
+ timeStamp = tv.tv_sec;
+ lastCleanupTime = tv.tv_sec;
+ houseKeepingResidual = 0;
+
+ for (i=0; i<LINK_TABLE_OUT_SIZE; i++)
+ linkTableOut[i] = NULL;
+ for (i=0; i<LINK_TABLE_IN_SIZE; i++)
+ linkTableIn[i] = NULL;
+
+ atexit(PacketAliasUninit);
+ firstCall = 0;
+ }
+ else
+ {
+ deleteAllLinks = 1;
+ CleanupAliasData();
+ deleteAllLinks = 0;
+ }
+
+ aliasAddress.s_addr = 0;
+ targetAddress.s_addr = 0;
+
+ icmpLinkCount = 0;
+ udpLinkCount = 0;
+ tcpLinkCount = 0;
+ fragmentIdLinkCount = 0;
+ fragmentPtrLinkCount = 0;
+ sockCount = 0;
+
+ cleanupIndex =0;
+
+ packetAliasMode = PKT_ALIAS_SAME_PORTS
+ | PKT_ALIAS_USE_SOCKETS
+ | PKT_ALIAS_RESET_ON_ADDR_CHANGE;
+
+ pptpAliasFlag = 0;
+}
+
+void
+PacketAliasUninit(void) {
+ deleteAllLinks = 1;
+ CleanupAliasData();
+ deleteAllLinks = 0;
+ UninitPacketAliasLog();
+#ifndef NO_FW_PUNCH
+ UninitPunchFW();
+#endif
+}
+
+
+/* Change mode for some operations */
+unsigned int
+PacketAliasSetMode(
+ unsigned int flags, /* Which state to bring flags to */
+ unsigned int mask /* Mask of which flags to affect (use 0 to do a
+ probe for flag values) */
+)
+{
+/* Enable logging? */
+ if (flags & mask & PKT_ALIAS_LOG)
+ {
+ InitPacketAliasLog(); /* Do the enable */
+ } else
+/* _Disable_ logging? */
+ if (~flags & mask & PKT_ALIAS_LOG) {
+ UninitPacketAliasLog();
+ }
+
+#ifndef NO_FW_PUNCH
+/* Start punching holes in the firewall? */
+ if (flags & mask & PKT_ALIAS_PUNCH_FW) {
+ InitPunchFW();
+ } else
+/* Stop punching holes in the firewall? */
+ if (~flags & mask & PKT_ALIAS_PUNCH_FW) {
+ UninitPunchFW();
+ }
+#endif
+
+/* Other flags can be set/cleared without special action */
+ packetAliasMode = (flags & mask) | (packetAliasMode & ~mask);
+ return packetAliasMode;
+}
+
+
+int
+PacketAliasCheckNewLink(void)
+{
+ return newDefaultLink;
+}
+
+
+#ifndef NO_FW_PUNCH
+
+/*****************
+ Code to support firewall punching. This shouldn't really be in this
+ file, but making variables global is evil too.
+ ****************/
+
+/* Firewall include files */
+#include <sys/queue.h>
+#include <net/if.h>
+#include <netinet/ip_fw.h>
+#include <string.h>
+#include <err.h>
+
+static void ClearAllFWHoles(void);
+
+static int fireWallBaseNum; /* The first firewall entry free for our use */
+static int fireWallNumNums; /* How many entries can we use? */
+static int fireWallActiveNum; /* Which entry did we last use? */
+static char *fireWallField; /* bool array for entries */
+
+#define fw_setfield(field, num) \
+do { \
+ (field)[num] = 1; \
+} /*lint -save -e717 */ while(0) /*lint -restore */
+#define fw_clrfield(field, num) \
+do { \
+ (field)[num] = 0; \
+} /*lint -save -e717 */ while(0) /*lint -restore */
+#define fw_tstfield(field, num) ((field)[num])
+
+void
+PacketAliasSetFWBase(unsigned int base, unsigned int num) {
+ fireWallBaseNum = base;
+ fireWallNumNums = num;
+}
+
+static void
+InitPunchFW(void) {
+ fireWallField = malloc(fireWallNumNums);
+ if (fireWallField) {
+ memset(fireWallField, 0, fireWallNumNums);
+ if (fireWallFD < 0) {
+ fireWallFD = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+ }
+ ClearAllFWHoles();
+ fireWallActiveNum = fireWallBaseNum;
+ }
+}
+
+static void
+UninitPunchFW(void) {
+ ClearAllFWHoles();
+ if (fireWallFD >= 0)
+ close(fireWallFD);
+ fireWallFD = -1;
+ if (fireWallField)
+ free(fireWallField);
+ fireWallField = NULL;
+ packetAliasMode &= ~PKT_ALIAS_PUNCH_FW;
+}
+
+/* Make a certain link go through the firewall */
+void
+PunchFWHole(struct alias_link *link) {
+ int r; /* Result code */
+ struct ip_fw rule; /* On-the-fly built rule */
+ int fwhole; /* Where to punch hole */
+
+/* Don't do anything unless we are asked to */
+ if ( !(packetAliasMode & PKT_ALIAS_PUNCH_FW) ||
+ fireWallFD < 0 ||
+ link->link_type != LINK_TCP ||
+ !link->data.tcp)
+ return;
+
+ memset(&rule, 0, sizeof rule);
+
+/** Build rule **/
+
+ /* Find empty slot */
+ for (fwhole = fireWallActiveNum;
+ fwhole < fireWallBaseNum + fireWallNumNums &&
+ fw_tstfield(fireWallField, fwhole);
+ fwhole++)
+ ;
+ if (fwhole >= fireWallBaseNum + fireWallNumNums ||
+ fw_tstfield(fireWallField, fwhole)) {
+ for (fwhole = fireWallBaseNum;
+ fwhole < fireWallActiveNum &&
+ fw_tstfield(fireWallField, fwhole);
+ fwhole++)
+ ;
+ if (fwhole == fireWallActiveNum) {
+ /* No rule point empty - we can't punch more holes. */
+ fireWallActiveNum = fireWallBaseNum;
+#ifdef DEBUG
+ fprintf(stderr, "libalias: Unable to create firewall hole!\n");
+#endif
+ return;
+ }
+ }
+ /* Start next search at next position */
+ fireWallActiveNum = fwhole+1;
+
+ /* Build generic part of the two rules */
+ rule.fw_number = fwhole;
+ rule.fw_nports = 1; /* Number of source ports; dest ports follow */
+ rule.fw_flg = IP_FW_F_ACCEPT;
+ rule.fw_prot = IPPROTO_TCP;
+ rule.fw_smsk.s_addr = INADDR_BROADCAST;
+ rule.fw_dmsk.s_addr = INADDR_BROADCAST;
+
+ /* Build and apply specific part of the rules */
+ rule.fw_src = GetOriginalAddress(link);
+ rule.fw_dst = GetDestAddress(link);
+ rule.fw_uar.fw_pts[0] = ntohs(GetOriginalPort(link));
+ rule.fw_uar.fw_pts[1] = ntohs(GetDestPort(link));
+
+ /* Skip non-bound links - XXX should not be strictly necessary,
+ but seems to leave hole if not done. Leak of non-bound links?
+ (Code should be left even if the problem is fixed - it is a
+ clear optimization) */
+ if (rule.fw_uar.fw_pts[0] != 0 && rule.fw_uar.fw_pts[1] != 0) {
+ r = setsockopt(fireWallFD, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
+#ifdef DEBUG
+ if (r)
+ err(1, "alias punch inbound(1) setsockopt(IP_FW_ADD)");
+#endif
+ rule.fw_src = GetDestAddress(link);
+ rule.fw_dst = GetOriginalAddress(link);
+ rule.fw_uar.fw_pts[0] = ntohs(GetDestPort(link));
+ rule.fw_uar.fw_pts[1] = ntohs(GetOriginalPort(link));
+ r = setsockopt(fireWallFD, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
+#ifdef DEBUG
+ if (r)
+ err(1, "alias punch inbound(2) setsockopt(IP_FW_ADD)");
+#endif
+ }
+/* Indicate hole applied */
+ link->data.tcp->fwhole = fwhole;
+ fw_setfield(fireWallField, fwhole);
+}
+
+/* Remove a hole in a firewall associated with a particular alias
+ link. Calling this too often is harmless. */
+static void
+ClearFWHole(struct alias_link *link) {
+ if (link->link_type == LINK_TCP && link->data.tcp) {
+ int fwhole = link->data.tcp->fwhole; /* Where is the firewall hole? */
+ struct ip_fw rule;
+
+ if (fwhole < 0)
+ return;
+
+ memset(&rule, 0, sizeof rule);
+ rule.fw_number = fwhole;
+ while (!setsockopt(fireWallFD, IPPROTO_IP, IP_FW_DEL, &rule, sizeof rule))
+ ;
+ fw_clrfield(fireWallField, fwhole);
+ link->data.tcp->fwhole = -1;
+ }
+}
+
+/* Clear out the entire range dedicated to firewall holes. */
+static void
+ClearAllFWHoles(void) {
+ struct ip_fw rule; /* On-the-fly built rule */
+ int i;
+
+ if (fireWallFD < 0)
+ return;
+
+ memset(&rule, 0, sizeof rule);
+ for (i = fireWallBaseNum; i < fireWallBaseNum + fireWallNumNums; i++) {
+ rule.fw_number = i;
+ while (!setsockopt(fireWallFD, IPPROTO_IP, IP_FW_DEL, &rule, sizeof rule))
+ ;
+ }
+ memset(fireWallField, 0, fireWallNumNums);
+}
+#endif
diff --git a/lib/libalias/alias_ftp.c b/lib/libalias/alias_ftp.c
new file mode 100644
index 0000000..ca2d53b
--- /dev/null
+++ b/lib/libalias/alias_ftp.c
@@ -0,0 +1,231 @@
+/*
+ Alias_ftp.c performs special processing for FTP sessions under
+ TCP. Specifically, when a PORT command from the client side
+ is sent, it is intercepted and modified. The address is changed
+ to the gateway machine and an aliasing port is used.
+
+ For this routine to work, the PORT command must fit entirely
+ into a single TCP packet. This is typically the case, but exceptions
+ can easily be envisioned under the actual specifications.
+
+ Probably the most troubling aspect of the approach taken here is
+ that the new PORT command will typically be a different length, and
+ this causes a certain amount of bookkeeping to keep track of the
+ changes of sequence and acknowledgment numbers, since the client
+ machine is totally unaware of the modification to the TCP stream.
+
+
+ This software is placed into the public domain with no restrictions
+ on its distribution.
+
+ Initial version: August, 1996 (cjm)
+
+ Version 1.6
+ Brian Somers and Martin Renters identified an IP checksum
+ error for modified IP packets.
+
+ Version 1.7: January 9, 1996 (cjm)
+ Differental checksum computation for change
+ in IP packet length.
+
+ Version 2.1: May, 1997 (cjm)
+ Very minor changes to conform with
+ local/global/function naming conventions
+ withing the packet alising module.
+
+ See HISTORY file for record of revisions.
+
+ $FreeBSD$
+*/
+
+/* Includes */
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include "alias_local.h"
+
+static void NewFtpPortCommand(struct ip *, struct alias_link *, struct in_addr, u_short, int);
+
+
+
+void
+AliasHandleFtpOut(
+struct ip *pip, /* IP packet to examine/patch */
+struct alias_link *link, /* The link to go through (aliased port) */
+int maxpacketsize /* The maximum size this packet can grow to (including headers) */)
+{
+ int hlen, tlen, dlen;
+ struct in_addr true_addr;
+ u_short true_port;
+ char *sptr;
+ struct tcphdr *tc;
+
+/* Calculate data length of TCP packet */
+ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+ hlen = (pip->ip_hl + tc->th_off) << 2;
+ tlen = ntohs(pip->ip_len);
+ dlen = tlen - hlen;
+
+/* Return is data length is too long or too short */
+ if (dlen<10 || dlen>80)
+ return;
+
+/* Place string pointer and beginning of data */
+ sptr = (char *) pip;
+ sptr += hlen;
+
+/* Parse through string using state diagram method */
+ {
+ char ch, zero;
+ int i, state;
+ u_long a1, a2, a3, a4;
+ u_short p1, p2;
+
+ a1=0; a2=0; a3=0; a4=0; p1=0; p2=0;
+ zero = '0';
+ state=-4;
+ for (i=0; i<dlen; i++)
+ {
+ ch = sptr[i];
+ switch (state)
+ {
+ case -4: if (ch == 'P') state=-3; else return; break;
+ case -3: if (ch == 'O') state=-2; else return; break;
+ case -2: if (ch == 'R') state=-1; else return; break;
+ case -1: if (ch == 'T') state= 0; else return; break;
+
+ case 0 :
+ if (isdigit(ch)) {a1=ch-zero; state=1 ;} break;
+ case 1 :
+ if (isdigit(ch)) a1=10*a1+ch-zero; else state=2 ; break;
+ case 2 :
+ if (isdigit(ch)) {a2=ch-zero; state=3 ;} break;
+ case 3 :
+ if (isdigit(ch)) a2=10*a2+ch-zero; else state=4 ; break;
+ case 4 :
+ if (isdigit(ch)) {a3=ch-zero; state=5 ;} break;
+ case 5 :
+ if (isdigit(ch)) a3=10*a3+ch-zero; else state=6 ; break;
+ case 6 :
+ if (isdigit(ch)) {a4=ch-zero; state=7 ;} break;
+ case 7 :
+ if (isdigit(ch)) a4=10*a4+ch-zero; else state=8 ; break;
+ case 8 :
+ if (isdigit(ch)) {p1=ch-zero; state=9 ;} break;
+ case 9 :
+ if (isdigit(ch)) p1=10*p1+ch-zero; else state=10; break;
+ case 10:
+ if (isdigit(ch)) {p2=ch-zero; state=11;} break;
+ case 11:
+ if (isdigit(ch)) p2=10*p2+ch-zero; break;
+ }
+ }
+
+ if (state == 11)
+ {
+ true_port = htons((p1<<8) + p2);
+ true_addr.s_addr = htonl((a1<<24) + (a2<<16) +(a3<<8) + a4);
+ NewFtpPortCommand(pip, link, true_addr, true_port, maxpacketsize);
+ }
+ }
+}
+
+static void
+NewFtpPortCommand(struct ip *pip,
+ struct alias_link *link,
+ struct in_addr true_addr,
+ u_short true_port,
+ int maxpacketsize)
+{
+ struct alias_link *ftp_link;
+
+/* Establish link to address and port found in PORT command */
+ ftp_link = FindUdpTcpOut(true_addr, GetDestAddress(link),
+ true_port, 0, IPPROTO_TCP);
+
+ if (ftp_link != NULL)
+ {
+ int slen, hlen, tlen, dlen;
+ struct tcphdr *tc;
+
+#ifndef NO_FW_PUNCH
+/* Punch hole in firewall */
+ PunchFWHole(ftp_link);
+#endif
+
+/* Calculate data length of TCP packet */
+ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+ hlen = (pip->ip_hl + tc->th_off) << 2;
+ tlen = ntohs(pip->ip_len);
+ dlen = tlen - hlen;
+
+/* Create new PORT command */
+ {
+ char stemp[80];
+ char *sptr;
+ u_short alias_port;
+ u_char *ptr;
+ int a1, a2, a3, a4, p1, p2;
+ struct in_addr alias_address;
+
+/* Decompose alias address into quad format */
+ alias_address = GetAliasAddress(link);
+ ptr = (u_char *) &alias_address.s_addr;
+ a1 = *ptr++; a2=*ptr++; a3=*ptr++; a4=*ptr;
+
+/* Decompose alias port into pair format */
+ alias_port = GetAliasPort(ftp_link);
+ ptr = (char *) &alias_port;
+ p1 = *ptr++; p2=*ptr;
+
+/* Generate command string */
+ sprintf(stemp, "PORT %d,%d,%d,%d,%d,%d\r\n",
+ a1,a2,a3,a4,p1,p2);
+
+/* Save string length for IP header modification */
+ slen = strlen(stemp);
+
+/* Copy into IP packet */
+ sptr = (char *) pip; sptr += hlen;
+ strncpy(sptr, stemp, maxpacketsize-hlen);
+ }
+
+/* Save information regarding modified seq and ack numbers */
+ {
+ int delta;
+
+ SetAckModified(link);
+ delta = GetDeltaSeqOut(pip, link);
+ AddSeq(pip, link, delta+slen-dlen);
+ }
+
+/* Revise IP header */
+ {
+ u_short new_len;
+
+ new_len = htons(hlen + slen);
+ DifferentialChecksum(&pip->ip_sum,
+ &new_len,
+ &pip->ip_len,
+ 1);
+ pip->ip_len = new_len;
+ }
+
+/* Compute TCP checksum for revised packet */
+ tc->th_sum = 0;
+ tc->th_sum = TcpChecksum(pip);
+ }
+ else
+ {
+#ifdef DEBUG
+ fprintf(stderr,
+ "PacketAlias/HandleFtpOut: Cannot allocate FTP data port\n");
+#endif
+ }
+}
diff --git a/lib/libalias/alias_irc.c b/lib/libalias/alias_irc.c
new file mode 100644
index 0000000..8c52c1f
--- /dev/null
+++ b/lib/libalias/alias_irc.c
@@ -0,0 +1,318 @@
+/* Alias_irc.c intercepts packages contain IRC CTCP commands, and
+ changes DCC commands to export a port on the aliasing host instead
+ of an aliased host.
+
+ For this routine to work, the DCC command must fit entirely into a
+ single TCP packet. This will usually happen, but is not
+ guaranteed.
+
+ The interception is likely to change the length of the packet.
+ The handling of this is copied more-or-less verbatim from
+ ftp_alias.c
+
+ This software is placed into the public domain with no restrictions
+ on its distribution.
+
+ Initial version: Eivind Eklund <perhaps@yes.no> (ee) 97-01-29
+
+ Version 2.1: May, 1997 (cjm)
+ Very minor changes to conform with
+ local/global/function naming conventions
+ withing the packet alising module.
+
+ $FreeBSD$
+*/
+
+/* Includes */
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <limits.h>
+
+#include "alias_local.h"
+
+/* Local defines */
+#define DBprintf(a)
+
+
+void
+AliasHandleIrcOut(struct ip *pip, /* IP packet to examine */
+ struct alias_link *link, /* Which link are we on? */
+ int maxsize /* Maximum size of IP packet including headers */
+ )
+{
+ int hlen, tlen, dlen;
+ struct in_addr true_addr;
+ u_short true_port;
+ char *sptr;
+ struct tcphdr *tc;
+ int i; /* Iterator through the source */
+
+/* Calculate data length of TCP packet */
+ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+ hlen = (pip->ip_hl + tc->th_off) << 2;
+ tlen = ntohs(pip->ip_len);
+ dlen = tlen - hlen;
+
+ /* Return if data length is too short - assume an entire PRIVMSG in each packet. */
+ if (dlen<sizeof(":A!a@n.n PRIVMSG A :aDCC 1 1a")-1)
+ return;
+
+/* Place string pointer at beginning of data */
+ sptr = (char *) pip;
+ sptr += hlen;
+ maxsize -= hlen; /* We're interested in maximum size of data, not packet */
+
+ /* Search for a CTCP command [Note 1] */
+ for( i=0; i<dlen; i++ ) {
+ if(sptr[i]=='\001')
+ goto lFOUND_CTCP;
+ }
+ return; /* No CTCP commands in */
+ /* Handle CTCP commands - the buffer may have to be copied */
+lFOUND_CTCP:
+ {
+ char newpacket[65536]; /* Estimate of maximum packet size :) */
+ int copyat = i; /* Same */
+ int iCopy = 0; /* How much data have we written to copy-back string? */
+ unsigned long org_addr; /* Original IP address */
+ unsigned short org_port; /* Original source port address */
+ lCTCP_START:
+ if( i >= dlen || iCopy >= sizeof(newpacket) )
+ goto lPACKET_DONE;
+ newpacket[iCopy++] = sptr[i++]; /* Copy the CTCP start character */
+ /* Start of a CTCP */
+ if( i+4 >= dlen ) /* Too short for DCC */
+ goto lBAD_CTCP;
+ if( sptr[i+0] != 'D' )
+ goto lBAD_CTCP;
+ if( sptr[i+1] != 'C' )
+ goto lBAD_CTCP;
+ if( sptr[i+2] != 'C' )
+ goto lBAD_CTCP;
+ if( sptr[i+3] != ' ' )
+ goto lBAD_CTCP;
+ /* We have a DCC command - handle it! */
+ i+= 4; /* Skip "DCC " */
+ if( iCopy+4 > sizeof(newpacket) )
+ goto lPACKET_DONE;
+ newpacket[iCopy++] = 'D';
+ newpacket[iCopy++] = 'C';
+ newpacket[iCopy++] = 'C';
+ newpacket[iCopy++] = ' ';
+
+ DBprintf(("Found DCC\n"));
+ /* Skip any extra spaces (should not occur according to
+ protocol, but DCC breaks CTCP protocol anyway */
+ while(sptr[i] == ' ') {
+ if( ++i >= dlen) {
+ DBprintf(("DCC packet terminated in just spaces\n"));
+ goto lPACKET_DONE;
+ }
+ }
+
+ DBprintf(("Transferring command...\n"));
+ while(sptr[i] != ' ') {
+ newpacket[iCopy++] = sptr[i];
+ if( ++i >= dlen || iCopy >= sizeof(newpacket) ) {
+ DBprintf(("DCC packet terminated during command\n"));
+ goto lPACKET_DONE;
+ }
+ }
+ /* Copy _one_ space */
+ if( i+1 < dlen && iCopy < sizeof(newpacket) )
+ newpacket[iCopy++] = sptr[i++];
+
+ DBprintf(("Done command - removing spaces\n"));
+ /* Skip any extra spaces (should not occur according to
+ protocol, but DCC breaks CTCP protocol anyway */
+ while(sptr[i] == ' ') {
+ if( ++i >= dlen ) {
+ DBprintf(("DCC packet terminated in just spaces (post-command)\n"));
+ goto lPACKET_DONE;
+ }
+ }
+
+ DBprintf(("Transferring filename...\n"));
+ while(sptr[i] != ' ') {
+ newpacket[iCopy++] = sptr[i];
+ if( ++i >= dlen || iCopy >= sizeof(newpacket) ) {
+ DBprintf(("DCC packet terminated during filename\n"));
+ goto lPACKET_DONE;
+ }
+ }
+ /* Copy _one_ space */
+ if( i+1 < dlen && iCopy < sizeof(newpacket) )
+ newpacket[iCopy++] = sptr[i++];
+
+ DBprintf(("Done filename - removing spaces\n"));
+ /* Skip any extra spaces (should not occur according to
+ protocol, but DCC breaks CTCP protocol anyway */
+ while(sptr[i] == ' ') {
+ if( ++i >= dlen ) {
+ DBprintf(("DCC packet terminated in just spaces (post-filename)\n"));
+ goto lPACKET_DONE;
+ }
+ }
+
+ DBprintf(("Fetching IP address\n"));
+ /* Fetch IP address */
+ org_addr = 0;
+ while(i<dlen && isdigit(sptr[i])) {
+ if( org_addr > ULONG_MAX/10UL ) { /* Terminate on overflow */
+ DBprintf(("DCC Address overflow (org_addr == 0x%08lx, next char %c\n", org_addr, sptr[i]));
+ goto lBAD_CTCP;
+ }
+ org_addr *= 10;
+ org_addr += sptr[i++]-'0';
+ }
+ DBprintf(("Skipping space\n"));
+ if( i+1 >= dlen || sptr[i] != ' ' ) {
+ DBprintf(("Overflow (%d >= %d) or bad character (%02x) terminating IP address\n", i+1, dlen, sptr[i]));
+ goto lBAD_CTCP;
+ }
+ /* Skip any extra spaces (should not occur according to
+ protocol, but DCC breaks CTCP protocol anyway, so we might
+ as well play it safe */
+ while(sptr[i] == ' ') {
+ if( ++i >= dlen ) {
+ DBprintf(("Packet failure - space overflow.\n"));
+ goto lPACKET_DONE;
+ }
+ }
+ DBprintf(("Fetching port number\n"));
+ /* Fetch source port */
+ org_port = 0;
+ while(i<dlen && isdigit(sptr[i])) {
+ if( org_port > 6554 ) { /* Terminate on overflow (65536/10 rounded up*/
+ DBprintf(("DCC: port number overflow\n"));
+ goto lBAD_CTCP;
+ }
+ org_port *= 10;
+ org_port += sptr[i++]-'0';
+ }
+ /* Skip illegal addresses (or early termination) */
+ if( i >= dlen || (sptr[i] != '\001' && sptr[i] != ' ') ) {
+ DBprintf(("Bad port termination\n"));
+ goto lBAD_CTCP;
+ }
+ DBprintf(("Got IP %lu and port %u\n", org_addr, (unsigned)org_port));
+
+ /* We've got the address and port - now alias it */
+ {
+ struct alias_link *dcc_link;
+ struct in_addr destaddr;
+
+
+ true_port = htons(org_port);
+ true_addr.s_addr = htonl(org_addr);
+ destaddr.s_addr = 0;
+
+ /* Steal the FTP_DATA_PORT - it doesn't really matter, and this
+ would probably allow it through at least _some_
+ firewalls. */
+ dcc_link = FindUdpTcpOut (true_addr,
+ destaddr,
+ true_port,
+ 0, IPPROTO_TCP);
+ DBprintf(("Got a DCC link\n"));
+ if ( dcc_link ) {
+ struct in_addr alias_address; /* Address from aliasing */
+ u_short alias_port; /* Port given by aliasing */
+
+#ifndef NO_FW_PUNCH
+ /* Generate firewall hole as appropriate */
+ PunchFWHole(dcc_link);
+#endif
+
+ alias_address = GetAliasAddress(link);
+ iCopy += snprintf(&newpacket[iCopy],
+ sizeof(newpacket)-iCopy,
+ "%lu ", (u_long)htonl(alias_address.s_addr));
+ if( iCopy >= sizeof(newpacket) ) { /* Truncated/fit exactly - bad news */
+ DBprintf(("DCC constructed packet overflow.\n"));
+ goto lBAD_CTCP;
+ }
+ alias_port = GetAliasPort(dcc_link);
+ iCopy += snprintf(&newpacket[iCopy],
+ sizeof(newpacket)-iCopy,
+ "%u", htons(alias_port) );
+ /* Done - truncated cases will be taken care of by lBAD_CTCP */
+ DBprintf(("Aliased IP %lu and port %u\n", alias_address.s_addr, (unsigned)alias_port));
+ }
+ }
+ /* An uninteresting CTCP - state entered right after '\001' has
+ been pushed. Also used to copy the rest of a DCC, after IP
+ address and port has been handled */
+ lBAD_CTCP:
+ for(; i<dlen && iCopy<sizeof(newpacket); i++,iCopy++) {
+ newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
+ if(sptr[i] == '\001') {
+ goto lNORMAL_TEXT;
+ }
+ }
+ goto lPACKET_DONE;
+ /* Normal text */
+ lNORMAL_TEXT:
+ for(; i<dlen && iCopy<sizeof(newpacket); i++,iCopy++) {
+ newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
+ if(sptr[i] == '\001') {
+ goto lCTCP_START;
+ }
+ }
+ /* Handle the end of a packet */
+ lPACKET_DONE:
+ iCopy = iCopy > maxsize-copyat ? maxsize-copyat : iCopy;
+ memcpy(sptr+copyat, newpacket, iCopy);
+
+/* Save information regarding modified seq and ack numbers */
+ {
+ int delta;
+
+ SetAckModified(link);
+ delta = GetDeltaSeqOut(pip, link);
+ AddSeq(pip, link, delta+copyat+iCopy-dlen);
+ }
+
+ /* Revise IP header */
+ {
+ u_short new_len;
+
+ new_len = htons(hlen + iCopy + copyat);
+ DifferentialChecksum(&pip->ip_sum,
+ &new_len,
+ &pip->ip_len,
+ 1);
+ pip->ip_len = new_len;
+ }
+
+ /* Compute TCP checksum for revised packet */
+ tc->th_sum = 0;
+ tc->th_sum = TcpChecksum(pip);
+ return;
+ }
+}
+
+/* Notes:
+ [Note 1]
+ The initial search will most often fail; it could be replaced with a 32-bit specific search.
+ Such a search would be done for 32-bit unsigned value V:
+ V ^= 0x01010101; (Search is for null bytes)
+ if( ((V-0x01010101)^V) & 0x80808080 ) {
+ (found a null bytes which was a 01 byte)
+ }
+ To assert that the processor is 32-bits, do
+ extern int ircdccar[32]; (32 bits)
+ extern int ircdccar[CHAR_BIT*sizeof(unsigned int)];
+ which will generate a type-error on all but 32-bit machines.
+
+ [Note 2] This routine really ought to be replaced with one that
+ creates a transparent proxy on the aliasing host, to allow arbitary
+ changes in the TCP stream. This should not be too difficult given
+ this base; I (ee) will try to do this some time later.
+ */
diff --git a/lib/libalias/alias_local.h b/lib/libalias/alias_local.h
new file mode 100644
index 0000000..6b4389c
--- /dev/null
+++ b/lib/libalias/alias_local.h
@@ -0,0 +1,172 @@
+/* -*- mode: c; tab-width: 3; c-basic-offset: 3; -*-
+ Alias_local.h contains the function prototypes for alias.c,
+ alias_db.c, alias_util.c and alias_ftp.c, alias_irc.c (as well
+ as any future add-ons). It also includes macros, globals and
+ struct definitions shared by more than one alias*.c file.
+
+ This include file is intended to be used only within the aliasing
+ software. Outside world interfaces are defined in alias.h
+
+ This software is placed into the public domain with no restrictions
+ on its distribution.
+
+ Initial version: August, 1996 (cjm)
+
+ <updated several times by original author and Eivind Eklund>
+
+ $FreeBSD$
+*/
+#ifndef ALIAS_LOCAL_H
+#define ALIAS_LOCAL_H
+
+
+/*
+ Macros
+ */
+
+/*
+ The following macro is used to update an
+ internet checksum. "delta" is a 32-bit
+ accumulation of all the changes to the
+ checksum (adding in new 16-bit words and
+ subtracting out old words), and "cksum"
+ is the checksum value to be updated.
+*/
+#define ADJUST_CHECKSUM(acc, cksum) { \
+ acc += cksum; \
+ if (acc < 0) \
+ { \
+ acc = -acc; \
+ acc = (acc >> 16) + (acc & 0xffff); \
+ acc += acc >> 16; \
+ cksum = (u_short) ~acc; \
+ } \
+ else \
+ { \
+ acc = (acc >> 16) + (acc & 0xffff); \
+ acc += acc >> 16; \
+ cksum = (u_short) acc; \
+ } \
+}
+
+
+/*
+ Globals
+*/
+
+extern int packetAliasMode;
+
+
+/*
+ Structs
+*/
+
+struct alias_link; /* Incomplete structure */
+
+
+/*
+ Prototypes
+*/
+
+/* General utilities */
+u_short IpChecksum(struct ip *);
+u_short TcpChecksum(struct ip *);
+void DifferentialChecksum(u_short *, u_short *, u_short *, int);
+
+/* Internal data access */
+struct alias_link *
+FindIcmpIn(struct in_addr, struct in_addr, u_short);
+
+struct alias_link *
+FindIcmpOut(struct in_addr, struct in_addr, u_short);
+
+struct alias_link *
+FindFragmentIn1(struct in_addr, struct in_addr, u_short);
+
+struct alias_link *
+FindFragmentIn2(struct in_addr, struct in_addr, u_short);
+
+struct alias_link *
+AddFragmentPtrLink(struct in_addr, u_short);
+
+struct alias_link *
+FindFragmentPtr(struct in_addr, u_short);
+
+struct alias_link *
+FindUdpTcpIn (struct in_addr, struct in_addr, u_short, u_short, u_char);
+
+struct alias_link *
+FindUdpTcpOut(struct in_addr, struct in_addr, u_short, u_short, u_char);
+
+struct in_addr
+FindOriginalAddress(struct in_addr);
+
+struct in_addr
+FindAliasAddress(struct in_addr);
+
+/* External data access/modification */
+void GetFragmentAddr(struct alias_link *, struct in_addr *);
+void SetFragmentAddr(struct alias_link *, struct in_addr);
+void GetFragmentPtr(struct alias_link *, char **);
+void SetFragmentPtr(struct alias_link *, char *);
+void SetStateIn(struct alias_link *, int);
+void SetStateOut(struct alias_link *, int);
+int GetStateIn(struct alias_link *);
+int GetStateOut(struct alias_link *);
+struct in_addr GetOriginalAddress(struct alias_link *);
+struct in_addr GetDestAddress(struct alias_link *);
+struct in_addr GetAliasAddress(struct alias_link *);
+struct in_addr GetDefaultAliasAddress(void);
+void SetDefaultAliasAddress(struct in_addr);
+u_short GetOriginalPort(struct alias_link *);
+u_short GetAliasPort(struct alias_link *);
+struct in_addr GetProxyAddress(struct alias_link *);
+void SetProxyAddress(struct alias_link *, struct in_addr);
+u_short GetProxyPort(struct alias_link *);
+void SetProxyPort(struct alias_link *, u_short);
+void SetAckModified(struct alias_link *);
+int GetAckModified(struct alias_link *);
+int GetDeltaAckIn(struct ip *, struct alias_link *);
+int GetDeltaSeqOut(struct ip *, struct alias_link *);
+void AddSeq(struct ip *, struct alias_link *, int);
+void SetExpire(struct alias_link *, int);
+void ClearCheckNewLink(void);
+#ifndef NO_FW_PUNCH
+void PunchFWHole(struct alias_link *);
+#endif
+
+
+/* Housekeeping function */
+void HouseKeeping(void);
+
+/* Tcp specfic routines */
+/*lint -save -library Suppress flexelint warnings */
+
+/* FTP routines */
+void AliasHandleFtpOut(struct ip *, struct alias_link *, int);
+
+/* IRC routines */
+void AliasHandleIrcOut(struct ip *, struct alias_link *, int);
+
+/* NetBIOS routines */
+int AliasHandleUdpNbt(struct ip *, struct alias_link *, struct in_addr *, u_short);
+int AliasHandleUdpNbtNS(struct ip *, struct alias_link *, struct in_addr *, u_short *, struct in_addr *, u_short *);
+
+/* CUSeeMe routines */
+void AliasHandleCUSeeMeOut(struct ip *, struct alias_link *);
+void AliasHandleCUSeeMeIn(struct ip *, struct in_addr);
+
+/* Transparent proxy routines */
+int ProxyCheck(struct ip *, struct in_addr *, u_short *);
+void ProxyModify(struct alias_link *, struct ip *, int, int);
+
+
+enum alias_tcp_state {
+ ALIAS_TCP_STATE_NOT_CONNECTED,
+ ALIAS_TCP_STATE_CONNECTED,
+ ALIAS_TCP_STATE_DISCONNECTED
+};
+
+int GetPptpAlias (struct in_addr*);
+/*lint -restore */
+#endif /* defined(ALIAS_LOCAL_H) */
diff --git a/lib/libalias/alias_nbt.c b/lib/libalias/alias_nbt.c
new file mode 100644
index 0000000..b5afedf
--- /dev/null
+++ b/lib/libalias/alias_nbt.c
@@ -0,0 +1,711 @@
+/*
+ * Written by Atsushi Murai <amurai@spec.co.jp>
+ *
+ * Copyright (C) 1998, System Planning and Engineering Co. All rights reserverd.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the System Planning and Engineering Co. The name of the
+ * SPEC may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ *
+ * TODO:
+ * oClean up.
+ * oConsidering for word alignment for other platform.
+ */
+/*
+ alias_nbt.c performs special processing for NetBios over TCP/IP
+ sessions by UDP.
+
+ Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>)
+
+ See HISTORY file for record of revisions.
+*/
+
+/* Includes */
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+#include <netinet/tcp.h>
+
+#include "alias_local.h"
+
+#define ADJUST_CHECKSUM(acc, cksum) { \
+ acc += cksum; \
+ if (acc < 0) \
+ { \
+ acc = -acc; \
+ acc = (acc >> 16) + (acc & 0xffff); \
+ acc += acc >> 16; \
+ cksum = (u_short) ~acc; \
+ } \
+ else \
+ { \
+ acc = (acc >> 16) + (acc & 0xffff); \
+ acc += acc >> 16; \
+ cksum = (u_short) acc; \
+ } \
+}
+
+typedef struct {
+ struct in_addr oldaddr;
+ u_short oldport;
+ struct in_addr newaddr;
+ u_short newport;
+ u_short *uh_sum;
+} NBTArguments;
+
+typedef struct {
+ unsigned char type;
+ unsigned char flags;
+ u_short id;
+ struct in_addr source_ip;
+ u_short source_port;
+ u_short len;
+ u_short offset;
+} NbtDataHeader;
+
+#define OpQuery 0
+#define OpUnknown 4
+#define OpRegist 5
+#define OpRelease 6
+#define OpWACK 7
+#define OpRefresh 8
+typedef struct {
+ u_short nametrid;
+ u_short dir:1, opcode:4, nmflags:7, rcode:4;
+ u_short qdcount;
+ u_short ancount;
+ u_short nscount;
+ u_short arcount;
+} NbtNSHeader;
+
+#define FMT_ERR 0x1
+#define SRV_ERR 0x2
+#define IMP_ERR 0x4
+#define RFS_ERR 0x5
+#define ACT_ERR 0x6
+#define CFT_ERR 0x7
+
+
+#ifdef DEBUG
+static void PrintRcode( u_char rcode ) {
+
+ switch (rcode) {
+ case FMT_ERR:
+ printf("\nFormat Error.");
+ case SRV_ERR:
+ printf("\nSever failure.");
+ case IMP_ERR:
+ printf("\nUnsupported request error.\n");
+ case RFS_ERR:
+ printf("\nRefused error.\n");
+ case ACT_ERR:
+ printf("\nActive error.\n");
+ case CFT_ERR:
+ printf("\nName in conflict error.\n");
+ default:
+ printf("\n???=%0x\n", rcode );
+
+ }
+}
+#endif
+
+
+/* Handling Name field */
+static u_char *AliasHandleName ( u_char *p, char *pmax ) {
+
+ u_char *s;
+ u_char c;
+ int compress;
+
+ /* Following length field */
+
+ if (p == NULL || (char *)p >= pmax)
+ return(NULL);
+
+ if (*p & 0xc0 ) {
+ p = p + 2;
+ if ((char *)p > pmax)
+ return(NULL);
+ return ((u_char *)p);
+ }
+ while ( ( *p & 0x3f) != 0x00 ) {
+ s = p + 1;
+ if ( *p == 0x20 )
+ compress = 1;
+ else
+ compress = 0;
+
+ /* Get next length field */
+ p = (u_char *)(p + (*p & 0x3f) + 1);
+ if ((char *)p > pmax) {
+ p = NULL;
+ break;
+ }
+#ifdef DEBUG
+ printf(":");
+#endif
+ while (s < p) {
+ if ( compress == 1 ) {
+ c = (u_char )(((((*s & 0x0f) << 4) | (*(s+1) & 0x0f)) - 0x11));
+#ifdef DEBUG
+ if (isprint( c ) )
+ printf("%c", c );
+ else
+ printf("<0x%02x>", c );
+#endif
+ s +=2;
+ } else {
+#ifdef DEBUG
+ printf("%c", *s);
+#endif
+ s++;
+ }
+ }
+#ifdef DEBUG
+ printf(":");
+#endif
+ fflush(stdout);
+ }
+
+ /* Set up to out of Name field */
+ if (p == NULL || (char *)p >= pmax)
+ p = NULL;
+ else
+ p++;
+ return ((u_char *)p);
+}
+
+/*
+ * NetBios Datagram Handler (IP/UDP)
+ */
+#define DGM_DIRECT_UNIQ 0x10
+#define DGM_DIRECT_GROUP 0x11
+#define DGM_BROADCAST 0x12
+#define DGM_ERROR 0x13
+#define DGM_QUERY 0x14
+#define DGM_POSITIVE_RES 0x15
+#define DGM_NEGATIVE_RES 0x16
+
+int AliasHandleUdpNbt(
+ struct ip *pip, /* IP packet to examine/patch */
+ struct alias_link *link,
+ struct in_addr *alias_address,
+ u_short alias_port
+) {
+ struct udphdr * uh;
+ NbtDataHeader *ndh;
+ u_char *p = NULL;
+ char *pmax;
+
+ /* Calculate data length of UDP packet */
+ uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
+ pmax = (char *)uh + ntohs( uh->uh_ulen );
+
+ ndh = (NbtDataHeader *)((char *)uh + (sizeof (struct udphdr)));
+ if ((char *)(ndh + 1) > pmax)
+ return(-1);
+#ifdef DEBUG
+ printf("\nType=%02x,", ndh->type );
+#endif
+ switch ( ndh->type ) {
+ case DGM_DIRECT_UNIQ:
+ case DGM_DIRECT_GROUP:
+ case DGM_BROADCAST:
+ p = (u_char *)ndh + 14;
+ p = AliasHandleName ( p, pmax ); /* Source Name */
+ p = AliasHandleName ( p, pmax ); /* Destination Name */
+ break;
+ case DGM_ERROR:
+ p = (u_char *)ndh + 11;
+ break;
+ case DGM_QUERY:
+ case DGM_POSITIVE_RES:
+ case DGM_NEGATIVE_RES:
+ p = (u_char *)ndh + 10;
+ p = AliasHandleName ( p, pmax ); /* Destination Name */
+ break;
+ }
+ if (p == NULL || (char *)p > pmax)
+ p = NULL;
+#ifdef DEBUG
+ printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) );
+#endif
+ /* Doing a IP address and Port number Translation */
+ if ( uh->uh_sum != 0 ) {
+ int acc;
+ u_short *sptr;
+ acc = ndh->source_port;
+ acc -= alias_port;
+ sptr = (u_short *) &(ndh->source_ip);
+ acc += *sptr++;
+ acc += *sptr;
+ sptr = (u_short *) alias_address;
+ acc -= *sptr++;
+ acc -= *sptr;
+ ADJUST_CHECKSUM(acc, uh->uh_sum)
+ }
+ ndh->source_ip = *alias_address;
+ ndh->source_port = alias_port;
+#ifdef DEBUG
+ printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) );
+ fflush(stdout);
+#endif
+ return((p == NULL) ? -1 : 0);
+}
+/* Question Section */
+#define QS_TYPE_NB 0x0020
+#define QS_TYPE_NBSTAT 0x0021
+#define QS_CLAS_IN 0x0001
+typedef struct {
+ u_short type; /* The type of Request */
+ u_short class; /* The class of Request */
+} NBTNsQuestion;
+
+static u_char *
+AliasHandleQuestion(
+ u_short count,
+ NBTNsQuestion *q,
+ char *pmax,
+ NBTArguments *nbtarg)
+{
+
+ while ( count != 0 ) {
+ /* Name Filed */
+ q = (NBTNsQuestion *)AliasHandleName((u_char *)q, pmax);
+
+ if (q == NULL || (char *)(q + 1) > pmax) {
+ q = NULL;
+ break;
+ }
+
+ /* Type and Class filed */
+ switch ( ntohs(q->type) ) {
+ case QS_TYPE_NB:
+ case QS_TYPE_NBSTAT:
+ q= q+1;
+ break;
+ default:
+#ifdef DEBUG
+ printf("\nUnknown Type on Question %0x\n", ntohs(q->type) );
+#endif
+ break;
+ }
+ count--;
+ }
+
+ /* Set up to out of Question Section */
+ return ((u_char *)q);
+}
+
+/* Resource Record */
+#define RR_TYPE_A 0x0001
+#define RR_TYPE_NS 0x0002
+#define RR_TYPE_NULL 0x000a
+#define RR_TYPE_NB 0x0020
+#define RR_TYPE_NBSTAT 0x0021
+#define RR_CLAS_IN 0x0001
+#define SizeOfNsResource 8
+typedef struct {
+ u_short type;
+ u_short class;
+ unsigned int ttl;
+ u_short rdlen;
+} NBTNsResource;
+
+#define SizeOfNsRNB 6
+typedef struct {
+ u_short g:1, ont:2, resv:13;
+ struct in_addr addr;
+} NBTNsRNB;
+
+static u_char *
+AliasHandleResourceNB(
+ NBTNsResource *q,
+ char *pmax,
+ NBTArguments *nbtarg)
+{
+ NBTNsRNB *nb;
+ u_short bcount;
+
+ if (q == NULL || (char *)(q + 1) > pmax)
+ return(NULL);
+ /* Check out a length */
+ bcount = ntohs(q->rdlen);
+
+ /* Forward to Resource NB position */
+ nb = (NBTNsRNB *)((u_char *)q + SizeOfNsResource);
+
+ /* Processing all in_addr array */
+#ifdef DEBUG
+ printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr));
+ printf("->%s, %dbytes] ",inet_ntoa(nbtarg->newaddr ), bcount);
+#endif
+ while ( nb != NULL && bcount != 0 ) {
+ if ((char *)(nb + 1) > pmax) {
+ nb = NULL;
+ break;
+ }
+#ifdef DEBUG
+ printf("<%s>", inet_ntoa(nb->addr) );
+#endif
+ if (!bcmp(&nbtarg->oldaddr,&nb->addr, sizeof(struct in_addr) ) ) {
+ if ( *nbtarg->uh_sum != 0 ) {
+ int acc;
+ u_short *sptr;
+
+ sptr = (u_short *) &(nb->addr);
+ acc = *sptr++;
+ acc += *sptr;
+ sptr = (u_short *) &(nbtarg->newaddr);
+ acc -= *sptr++;
+ acc -= *sptr;
+ ADJUST_CHECKSUM(acc, *nbtarg->uh_sum)
+ }
+
+ nb->addr = nbtarg->newaddr;
+#ifdef DEBUG
+ printf("O");
+#endif
+ }
+#ifdef DEBUG
+ else {
+ printf(".");
+ }
+#endif
+ nb=(NBTNsRNB *)((u_char *)nb + SizeOfNsRNB);
+ bcount -= SizeOfNsRNB;
+ }
+ if (nb == NULL || (char *)(nb + 1) > pmax) {
+ nb = NULL;
+ }
+
+ return ((u_char *)nb);
+}
+
+#define SizeOfResourceA 6
+typedef struct {
+ struct in_addr addr;
+} NBTNsResourceA;
+
+static u_char *
+AliasHandleResourceA(
+ NBTNsResource *q,
+ char *pmax,
+ NBTArguments *nbtarg)
+{
+ NBTNsResourceA *a;
+ u_short bcount;
+
+ if (q == NULL || (char *)(q + 1) > pmax)
+ return(NULL);
+
+ /* Forward to Resource A position */
+ a = (NBTNsResourceA *)( (u_char *)q + sizeof(NBTNsResource) );
+
+ /* Check out of length */
+ bcount = ntohs(q->rdlen);
+
+ /* Processing all in_addr array */
+#ifdef DEBUG
+ printf("Arec [%s", inet_ntoa(nbtarg->oldaddr));
+ printf("->%s]",inet_ntoa(nbtarg->newaddr ));
+#endif
+ while ( bcount != 0 ) {
+ if (a == NULL || (char *)(a + 1) > pmax)
+ return(NULL);
+#ifdef DEBUG
+ printf("..%s", inet_ntoa(a->addr) );
+#endif
+ if ( !bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr) ) ) {
+ if ( *nbtarg->uh_sum != 0 ) {
+ int acc;
+ u_short *sptr;
+
+ sptr = (u_short *) &(a->addr); /* Old */
+ acc = *sptr++;
+ acc += *sptr;
+ sptr = (u_short *) &nbtarg->newaddr; /* New */
+ acc -= *sptr++;
+ acc -= *sptr;
+ ADJUST_CHECKSUM(acc, *nbtarg->uh_sum)
+ }
+
+ a->addr = nbtarg->newaddr;
+ }
+ a++; /*XXXX*/
+ bcount -= SizeOfResourceA;
+ }
+ if (a == NULL || (char *)(a + 1) > pmax)
+ a = NULL;
+ return ((u_char *)a);
+}
+
+typedef struct {
+ u_short opcode:4, flags:8, resv:4;
+} NBTNsResourceNULL;
+
+static u_char *
+AliasHandleResourceNULL(
+ NBTNsResource *q,
+ char *pmax,
+ NBTArguments *nbtarg)
+{
+ NBTNsResourceNULL *n;
+ u_short bcount;
+
+ if (q == NULL || (char *)(q + 1) > pmax)
+ return(NULL);
+
+ /* Forward to Resource NULL position */
+ n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) );
+
+ /* Check out of length */
+ bcount = ntohs(q->rdlen);
+
+ /* Processing all in_addr array */
+ while ( bcount != 0 ) {
+ if ((char *)(n + 1) > pmax) {
+ n = NULL;
+ break;
+ }
+ n++;
+ bcount -= sizeof(NBTNsResourceNULL);
+ }
+ if ((char *)(n + 1) > pmax)
+ n = NULL;
+
+ return ((u_char *)n);
+}
+
+static u_char *
+AliasHandleResourceNS(
+ NBTNsResource *q,
+ char *pmax,
+ NBTArguments *nbtarg)
+{
+ NBTNsResourceNULL *n;
+ u_short bcount;
+
+ if (q == NULL || (char *)(q + 1) > pmax)
+ return(NULL);
+
+ /* Forward to Resource NULL position */
+ n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) );
+
+ /* Check out of length */
+ bcount = ntohs(q->rdlen);
+
+ /* Resource Record Name Filed */
+ q = (NBTNsResource *)AliasHandleName( (u_char *)n, pmax ); /* XXX */
+
+ if (q == NULL || (char *)((u_char *)n + bcount) > pmax)
+ return(NULL);
+ else
+ return ((u_char *)n + bcount);
+}
+
+typedef struct {
+ u_short numnames;
+} NBTNsResourceNBSTAT;
+
+static u_char *
+AliasHandleResourceNBSTAT(
+ NBTNsResource *q,
+ char *pmax,
+ NBTArguments *nbtarg)
+{
+ NBTNsResourceNBSTAT *n;
+ u_short bcount;
+
+ if (q == NULL || (char *)(q + 1) > pmax)
+ return(NULL);
+
+ /* Forward to Resource NBSTAT position */
+ n = (NBTNsResourceNBSTAT *)( (u_char *)q + sizeof(NBTNsResource) );
+
+ /* Check out of length */
+ bcount = ntohs(q->rdlen);
+
+ if (q == NULL || (char *)((u_char *)n + bcount) > pmax)
+ return(NULL);
+ else
+ return ((u_char *)n + bcount);
+}
+
+static u_char *
+AliasHandleResource(
+ u_short count,
+ NBTNsResource *q,
+ char *pmax,
+ NBTArguments
+ *nbtarg)
+{
+ while ( count != 0 ) {
+ /* Resource Record Name Filed */
+ q = (NBTNsResource *)AliasHandleName( (u_char *)q, pmax );
+
+ if (q == NULL || (char *)(q + 1) > pmax)
+ break;
+#ifdef DEBUG
+ printf("type=%02x, count=%d\n", ntohs(q->type), count );
+#endif
+
+ /* Type and Class filed */
+ switch ( ntohs(q->type) ) {
+ case RR_TYPE_NB:
+ q = (NBTNsResource *)AliasHandleResourceNB(
+ q,
+ pmax,
+ nbtarg
+ );
+ break;
+ case RR_TYPE_A:
+ q = (NBTNsResource *)AliasHandleResourceA(
+ q,
+ pmax,
+ nbtarg
+ );
+ break;
+ case RR_TYPE_NS:
+ q = (NBTNsResource *)AliasHandleResourceNS(
+ q,
+ pmax,
+ nbtarg
+ );
+ break;
+ case RR_TYPE_NULL:
+ q = (NBTNsResource *)AliasHandleResourceNULL(
+ q,
+ pmax,
+ nbtarg
+ );
+ break;
+ case RR_TYPE_NBSTAT:
+ q = (NBTNsResource *)AliasHandleResourceNBSTAT(
+ q,
+ pmax,
+ nbtarg
+ );
+ break;
+ default:
+#ifdef DEBUG
+ printf(
+ "\nUnknown Type of Resource %0x\n",
+ ntohs(q->type)
+ );
+#endif
+ break;
+ }
+ count--;
+ }
+ fflush(stdout);
+ return ((u_char *)q);
+}
+
+int AliasHandleUdpNbtNS(
+ struct ip *pip, /* IP packet to examine/patch */
+ struct alias_link *link,
+ struct in_addr *alias_address,
+ u_short *alias_port,
+ struct in_addr *original_address,
+ u_short *original_port )
+{
+ struct udphdr * uh;
+ NbtNSHeader * nsh;
+ u_char * p;
+ char *pmax;
+ NBTArguments nbtarg;
+
+ /* Set up Common Parameter */
+ nbtarg.oldaddr = *alias_address;
+ nbtarg.oldport = *alias_port;
+ nbtarg.newaddr = *original_address;
+ nbtarg.newport = *original_port;
+
+ /* Calculate data length of UDP packet */
+ uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
+ nbtarg.uh_sum = &(uh->uh_sum);
+ nsh = (NbtNSHeader *)((char *)uh + (sizeof(struct udphdr)));
+ p = (u_char *)(nsh + 1);
+ pmax = (char *)uh + ntohs( uh->uh_ulen );
+
+ if ((char *)(nsh + 1) > pmax)
+ return(-1);
+
+#ifdef DEBUG
+ printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
+ ", an=%04x, ns=%04x, ar=%04x, [%d]-->",
+ nsh->dir ? "Response": "Request",
+ nsh->nametrid,
+ nsh->opcode,
+ nsh->nmflags,
+ nsh->rcode,
+ ntohs(nsh->qdcount),
+ ntohs(nsh->ancount),
+ ntohs(nsh->nscount),
+ ntohs(nsh->arcount),
+ (u_char *)p -(u_char *)nsh
+ );
+#endif
+
+ /* Question Entries */
+ if (ntohs(nsh->qdcount) !=0 ) {
+ p = AliasHandleQuestion(
+ ntohs(nsh->qdcount),
+ (NBTNsQuestion *)p,
+ pmax,
+ &nbtarg
+ );
+ }
+
+ /* Answer Resource Records */
+ if (ntohs(nsh->ancount) !=0 ) {
+ p = AliasHandleResource(
+ ntohs(nsh->ancount),
+ (NBTNsResource *)p,
+ pmax,
+ &nbtarg
+ );
+ }
+
+ /* Authority Resource Recodrs */
+ if (ntohs(nsh->nscount) !=0 ) {
+ p = AliasHandleResource(
+ ntohs(nsh->nscount),
+ (NBTNsResource *)p,
+ pmax,
+ &nbtarg
+ );
+ }
+
+ /* Additional Resource Recodrs */
+ if (ntohs(nsh->arcount) !=0 ) {
+ p = AliasHandleResource(
+ ntohs(nsh->arcount),
+ (NBTNsResource *)p,
+ pmax,
+ &nbtarg
+ );
+ }
+
+#ifdef DEBUG
+ PrintRcode(nsh->rcode);
+#endif
+ return ((p == NULL) ? -1 : 0);
+}
diff --git a/lib/libalias/alias_proxy.c b/lib/libalias/alias_proxy.c
new file mode 100644
index 0000000..02e1765
--- /dev/null
+++ b/lib/libalias/alias_proxy.c
@@ -0,0 +1,807 @@
+/* file: alias_proxy.c
+
+ This file encapsulates special operations related to transparent
+ proxy redirection. This is where packets with a particular destination,
+ usually tcp port 80, are redirected to a proxy server.
+
+ When packets are proxied, the destination address and port are
+ modified. In certain cases, it is necessary to somehow encode
+ the original address/port info into the packet. Two methods are
+ presently supported: addition of a [DEST addr port] string at the
+ beginning a of tcp stream, or inclusion of an optional field
+ in the IP header.
+
+ There is one public API function:
+
+ PacketAliasProxyRule() -- Adds and deletes proxy
+ rules.
+
+ Rules are stored in a linear linked list, so lookup efficiency
+ won't be too good for large lists.
+
+
+ Initial development: April, 1998 (cjm)
+
+ $FreeBSD$
+*/
+
+
+/* System includes */
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+/* BSD IPV4 includes */
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include <arpa/inet.h>
+
+#include "alias_local.h" /* Functions used by alias*.c */
+#include "alias.h" /* Public API functions for libalias */
+
+
+
+/*
+ Data structures
+ */
+
+/*
+ * A linked list of arbitrary length, based on struct proxy_entry is
+ * used to store proxy rules.
+ */
+struct proxy_entry
+{
+#define PROXY_TYPE_ENCODE_NONE 1
+#define PROXY_TYPE_ENCODE_TCPSTREAM 2
+#define PROXY_TYPE_ENCODE_IPHDR 3
+ int rule_index;
+ int proxy_type;
+ u_char proto;
+ u_short proxy_port;
+ u_short server_port;
+
+ struct in_addr server_addr;
+
+ struct in_addr src_addr;
+ struct in_addr src_mask;
+
+ struct in_addr dst_addr;
+ struct in_addr dst_mask;
+
+ struct proxy_entry *next;
+ struct proxy_entry *last;
+};
+
+
+
+/*
+ File scope variables
+*/
+
+static struct proxy_entry *proxyList;
+
+
+
+/* Local (static) functions:
+
+ IpMask() -- Utility function for creating IP
+ masks from integer (1-32) specification.
+ IpAddr() -- Utility function for converting string
+ to IP address
+ IpPort() -- Utility function for converting string
+ to port number
+ RuleAdd() -- Adds an element to the rule list.
+ RuleDelete() -- Removes an element from the rule list.
+ RuleNumberDelete() -- Removes all elements from the rule list
+ having a certain rule number.
+ ProxyEncodeTcpStream() -- Adds [DEST x.x.x.x xxxx] to the beginning
+ of a TCP stream.
+ ProxyEncodeIpHeader() -- Adds an IP option indicating the true
+ destination of a proxied IP packet
+*/
+
+static int IpMask(int, struct in_addr *);
+static int IpAddr(char *, struct in_addr *);
+static int IpPort(char *, int, int *);
+static void RuleAdd(struct proxy_entry *);
+static void RuleDelete(struct proxy_entry *);
+static int RuleNumberDelete(int);
+static void ProxyEncodeTcpStream(struct alias_link *, struct ip *, int);
+static void ProxyEncodeIpHeader(struct ip *, int);
+
+static int
+IpMask(int nbits, struct in_addr *mask)
+{
+ int i;
+ u_int imask;
+
+ if (nbits < 0 || nbits > 32)
+ return -1;
+
+ imask = 0;
+ for (i=0; i<nbits; i++)
+ imask = (imask >> 1) + 0x80000000;
+ mask->s_addr = htonl(imask);
+
+ return 0;
+}
+
+static int
+IpAddr(char *s, struct in_addr *addr)
+{
+ if (inet_aton(s, addr) == 0)
+ return -1;
+ else
+ return 0;
+}
+
+static int
+IpPort(char *s, int proto, int *port)
+{
+ int n;
+
+ n = sscanf(s, "%d", port);
+ if (n != 1)
+ {
+ struct servent *se;
+
+ if (proto == IPPROTO_TCP)
+ se = getservbyname(s, "tcp");
+ else if (proto == IPPROTO_UDP)
+ se = getservbyname(s, "udp");
+ else
+ return -1;
+
+ if (se == NULL)
+ return -1;
+
+ *port = (u_int) ntohs(se->s_port);
+ }
+
+ return 0;
+}
+
+void
+RuleAdd(struct proxy_entry *entry)
+{
+ int rule_index;
+ struct proxy_entry *ptr;
+ struct proxy_entry *ptr_last;
+
+ if (proxyList == NULL)
+ {
+ proxyList = entry;
+ entry->last = NULL;
+ entry->next = NULL;
+ return;
+ }
+
+ rule_index = entry->rule_index;
+ ptr = proxyList;
+ ptr_last = NULL;
+ while (ptr != NULL)
+ {
+ if (ptr->rule_index >= rule_index)
+ {
+ if (ptr_last == NULL)
+ {
+ entry->next = proxyList;
+ entry->last = NULL;
+ proxyList->last = entry;
+ proxyList = entry;
+ return;
+ }
+
+ ptr_last->next = entry;
+ ptr->last = entry;
+ entry->last = ptr->last;
+ entry->next = ptr;
+ return;
+ }
+ ptr_last = ptr;
+ ptr = ptr->next;
+ }
+
+ ptr_last->next = entry;
+ entry->last = ptr_last;
+ entry->next = NULL;
+}
+
+static void
+RuleDelete(struct proxy_entry *entry)
+{
+ if (entry->last != NULL)
+ entry->last->next = entry->next;
+ else
+ proxyList = entry->next;
+
+ if (entry->next != NULL)
+ entry->next->last = entry->last;
+
+ free(entry);
+}
+
+static int
+RuleNumberDelete(int rule_index)
+{
+ int err;
+ struct proxy_entry *ptr;
+
+ err = -1;
+ ptr = proxyList;
+ while (ptr != NULL)
+ {
+ struct proxy_entry *ptr_next;
+
+ ptr_next = ptr->next;
+ if (ptr->rule_index == rule_index)
+ {
+ err = 0;
+ RuleDelete(ptr);
+ }
+
+ ptr = ptr_next;
+ }
+
+ return err;
+}
+
+static void
+ProxyEncodeTcpStream(struct alias_link *link,
+ struct ip *pip,
+ int maxpacketsize)
+{
+ int slen;
+ char buffer[40];
+ struct tcphdr *tc;
+
+/* Compute pointer to tcp header */
+ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+
+/* Don't modify if once already modified */
+
+ if (GetAckModified (link))
+ return;
+
+/* Translate destination address and port to string form */
+ snprintf(buffer, sizeof(buffer) - 2, "[DEST %s %d]",
+ inet_ntoa(GetProxyAddress (link)), (u_int) ntohs(GetProxyPort (link)));
+
+/* Pad string out to a multiple of two in length */
+ slen = strlen(buffer);
+ switch (slen % 2)
+ {
+ case 0:
+ strcat(buffer, " \n");
+ slen += 2;
+ break;
+ case 1:
+ strcat(buffer, "\n");
+ slen += 1;
+ }
+
+/* Check for packet overflow */
+ if ((ntohs(pip->ip_len) + strlen(buffer)) > maxpacketsize)
+ return;
+
+/* Shift existing TCP data and insert destination string */
+ {
+ int dlen;
+ int hlen;
+ u_char *p;
+
+ hlen = (pip->ip_hl + tc->th_off) << 2;
+ dlen = ntohs (pip->ip_len) - hlen;
+
+/* Modify first packet that has data in it */
+
+ if (dlen == 0)
+ return;
+
+ p = (char *) pip;
+ p += hlen;
+
+ memmove(p + slen, p, dlen);
+ memcpy(p, buffer, slen);
+ }
+
+/* Save information about modfied sequence number */
+ {
+ int delta;
+
+ SetAckModified(link);
+ delta = GetDeltaSeqOut(pip, link);
+ AddSeq(pip, link, delta+slen);
+ }
+
+/* Update IP header packet length and checksum */
+ {
+ int accumulate;
+
+ accumulate = pip->ip_len;
+ pip->ip_len = htons(ntohs(pip->ip_len) + slen);
+ accumulate -= pip->ip_len;
+
+ ADJUST_CHECKSUM(accumulate, pip->ip_sum);
+ }
+
+/* Update TCP checksum, Use TcpChecksum since so many things have
+ already changed. */
+
+ tc->th_sum = 0;
+ tc->th_sum = TcpChecksum (pip);
+}
+
+static void
+ProxyEncodeIpHeader(struct ip *pip,
+ int maxpacketsize)
+{
+#define OPTION_LEN_BYTES 8
+#define OPTION_LEN_INT16 4
+#define OPTION_LEN_INT32 2
+ u_char option[OPTION_LEN_BYTES];
+
+#ifdef DEBUG
+ fprintf(stdout, " ip cksum 1 = %x\n", (u_int) IpChecksum(pip));
+ fprintf(stdout, "tcp cksum 1 = %x\n", (u_int) TcpChecksum(pip));
+#endif
+
+/* Check to see that there is room to add an IP option */
+ if (pip->ip_hl > (0x0f - OPTION_LEN_INT32))
+ return;
+
+/* Build option and copy into packet */
+ {
+ u_char *ptr;
+ struct tcphdr *tc;
+
+ ptr = (u_char *) pip;
+ ptr += 20;
+ memcpy(ptr + OPTION_LEN_BYTES, ptr, ntohs(pip->ip_len) - 20);
+
+ option[0] = 0x64; /* class: 3 (reserved), option 4 */
+ option[1] = OPTION_LEN_BYTES;
+
+ memcpy(&option[2], (u_char *) &pip->ip_dst, 4);
+
+ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+ memcpy(&option[6], (u_char *) &tc->th_sport, 2);
+
+ memcpy(ptr, option, 8);
+ }
+
+/* Update checksum, header length and packet length */
+ {
+ int i;
+ int accumulate;
+ u_short *sptr;
+
+ sptr = (u_short *) option;
+ accumulate = 0;
+ for (i=0; i<OPTION_LEN_INT16; i++)
+ accumulate -= *(sptr++);
+
+ sptr = (u_short *) pip;
+ accumulate += *sptr;
+ pip->ip_hl += OPTION_LEN_INT32;
+ accumulate -= *sptr;
+
+ accumulate += pip->ip_len;
+ pip->ip_len = htons(ntohs(pip->ip_len) + OPTION_LEN_BYTES);
+ accumulate -= pip->ip_len;
+
+ ADJUST_CHECKSUM(accumulate, pip->ip_sum);
+ }
+#undef OPTION_LEN_BYTES
+#undef OPTION_LEN_INT16
+#undef OPTION_LEN_INT32
+#ifdef DEBUG
+ fprintf(stdout, " ip cksum 2 = %x\n", (u_int) IpChecksum(pip));
+ fprintf(stdout, "tcp cksum 2 = %x\n", (u_int) TcpChecksum(pip));
+#endif
+}
+
+
+/* Functions by other packet alias source files
+
+ ProxyCheck() -- Checks whether an outgoing packet should
+ be proxied.
+ ProxyModify() -- Encodes the original destination address/port
+ for a packet which is to be redirected to
+ a proxy server.
+*/
+
+int
+ProxyCheck(struct ip *pip,
+ struct in_addr *proxy_server_addr,
+ u_short *proxy_server_port)
+{
+ u_short dst_port;
+ struct in_addr src_addr;
+ struct in_addr dst_addr;
+ struct proxy_entry *ptr;
+
+ src_addr = pip->ip_src;
+ dst_addr = pip->ip_dst;
+ dst_port = ((struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)))
+ ->th_dport;
+
+ ptr = proxyList;
+ while (ptr != NULL)
+ {
+ u_short proxy_port;
+
+ proxy_port = ptr->proxy_port;
+ if ((dst_port == proxy_port || proxy_port == 0)
+ && pip->ip_p == ptr->proto
+ && src_addr.s_addr != ptr->server_addr.s_addr)
+ {
+ struct in_addr src_addr_masked;
+ struct in_addr dst_addr_masked;
+
+ src_addr_masked.s_addr = src_addr.s_addr & ptr->src_mask.s_addr;
+ dst_addr_masked.s_addr = dst_addr.s_addr & ptr->dst_mask.s_addr;
+
+ if ((src_addr_masked.s_addr == ptr->src_addr.s_addr)
+ && (dst_addr_masked.s_addr == ptr->dst_addr.s_addr))
+ {
+ if ((*proxy_server_port = ptr->server_port) == 0)
+ *proxy_server_port = dst_port;
+ *proxy_server_addr = ptr->server_addr;
+ return ptr->proxy_type;
+ }
+ }
+ ptr = ptr->next;
+ }
+
+ return 0;
+}
+
+void
+ProxyModify(struct alias_link *link,
+ struct ip *pip,
+ int maxpacketsize,
+ int proxy_type)
+{
+ switch (proxy_type)
+ {
+ case PROXY_TYPE_ENCODE_IPHDR:
+ ProxyEncodeIpHeader(pip, maxpacketsize);
+ break;
+
+ case PROXY_TYPE_ENCODE_TCPSTREAM:
+ ProxyEncodeTcpStream(link, pip, maxpacketsize);
+ break;
+ }
+}
+
+
+/*
+ Public API functions
+*/
+
+int
+PacketAliasProxyRule(const char *cmd)
+{
+/*
+ * This function takes command strings of the form:
+ *
+ * server <addr>[:<port>]
+ * [port <port>]
+ * [rule n]
+ * [proto tcp|udp]
+ * [src <addr>[/n]]
+ * [dst <addr>[/n]]
+ * [type encode_tcp_stream|encode_ip_hdr|no_encode]
+ *
+ * delete <rule number>
+ *
+ * Subfields can be in arbitrary order. Port numbers and addresses
+ * must be in either numeric or symbolic form. An optional rule number
+ * is used to control the order in which rules are searched. If two
+ * rules have the same number, then search order cannot be guaranteed,
+ * and the rules should be disjoint. If no rule number is specified,
+ * then 0 is used, and group 0 rules are always checked before any
+ * others.
+ */
+ int i, n, len;
+ int cmd_len;
+ int token_count;
+ int state;
+ char *token;
+ char buffer[256];
+ char str_port[sizeof(buffer)];
+ char str_server_port[sizeof(buffer)];
+
+ int rule_index;
+ int proto;
+ int proxy_type;
+ int proxy_port;
+ int server_port;
+ struct in_addr server_addr;
+ struct in_addr src_addr, src_mask;
+ struct in_addr dst_addr, dst_mask;
+ struct proxy_entry *proxy_entry;
+
+/* Copy command line into a buffer */
+ cmd_len = strlen(cmd);
+ if (cmd_len > (sizeof(buffer) - 1))
+ return -1;
+ strcpy(buffer, cmd);
+
+/* Convert to lower case */
+ len = strlen(buffer);
+ for (i=0; i<len; i++)
+ buffer[i] = tolower(buffer[i]);
+
+/* Set default proxy type */
+
+/* Set up default values */
+ rule_index = 0;
+ proxy_type = PROXY_TYPE_ENCODE_NONE;
+ proto = IPPROTO_TCP;
+ proxy_port = 0;
+ server_addr.s_addr = 0;
+ server_port = 0;
+ src_addr.s_addr = 0;
+ IpMask(0, &src_mask);
+ dst_addr.s_addr = 0;
+ IpMask(0, &dst_mask);
+
+ str_port[0] = 0;
+ str_server_port[0] = 0;
+
+/* Parse command string with state machine */
+#define STATE_READ_KEYWORD 0
+#define STATE_READ_TYPE 1
+#define STATE_READ_PORT 2
+#define STATE_READ_SERVER 3
+#define STATE_READ_RULE 4
+#define STATE_READ_DELETE 5
+#define STATE_READ_PROTO 6
+#define STATE_READ_SRC 7
+#define STATE_READ_DST 8
+ state = STATE_READ_KEYWORD;
+ token = strtok(buffer, " \t");
+ token_count = 0;
+ while (token != NULL)
+ {
+ token_count++;
+ switch (state)
+ {
+ case STATE_READ_KEYWORD:
+ if (strcmp(token, "type") == 0)
+ state = STATE_READ_TYPE;
+ else if (strcmp(token, "port") == 0)
+ state = STATE_READ_PORT;
+ else if (strcmp(token, "server") == 0)
+ state = STATE_READ_SERVER;
+ else if (strcmp(token, "rule") == 0)
+ state = STATE_READ_RULE;
+ else if (strcmp(token, "delete") == 0)
+ state = STATE_READ_DELETE;
+ else if (strcmp(token, "proto") == 0)
+ state = STATE_READ_PROTO;
+ else if (strcmp(token, "src") == 0)
+ state = STATE_READ_SRC;
+ else if (strcmp(token, "dst") == 0)
+ state = STATE_READ_DST;
+ else
+ return -1;
+ break;
+
+ case STATE_READ_TYPE:
+ if (strcmp(token, "encode_ip_hdr") == 0)
+ proxy_type = PROXY_TYPE_ENCODE_IPHDR;
+ else if (strcmp(token, "encode_tcp_stream") == 0)
+ proxy_type = PROXY_TYPE_ENCODE_TCPSTREAM;
+ else if (strcmp(token, "no_encode") == 0)
+ proxy_type = PROXY_TYPE_ENCODE_NONE;
+ else
+ return -1;
+ state = STATE_READ_KEYWORD;
+ break;
+
+ case STATE_READ_PORT:
+ strcpy(str_port, token);
+ state = STATE_READ_KEYWORD;
+ break;
+
+ case STATE_READ_SERVER:
+ {
+ int err;
+ char *p;
+ char s[sizeof(buffer)];
+
+ p = token;
+ while (*p != ':' && *p != 0)
+ p++;
+
+ if (*p != ':')
+ {
+ err = IpAddr(token, &server_addr);
+ if (err)
+ return -1;
+ }
+ else
+ {
+ *p = ' ';
+
+ n = sscanf(token, "%s %s", s, str_server_port);
+ if (n != 2)
+ return -1;
+
+ err = IpAddr(s, &server_addr);
+ if (err)
+ return -1;
+ }
+ }
+ state = STATE_READ_KEYWORD;
+ break;
+
+ case STATE_READ_RULE:
+ n = sscanf(token, "%d", &rule_index);
+ if (n != 1 || rule_index < 0)
+ return -1;
+ state = STATE_READ_KEYWORD;
+ break;
+
+ case STATE_READ_DELETE:
+ {
+ int err;
+ int rule_to_delete;
+
+ if (token_count != 2)
+ return -1;
+
+ n = sscanf(token, "%d", &rule_to_delete);
+ if (n != 1)
+ return -1;
+ err = RuleNumberDelete(rule_to_delete);
+ if (err)
+ return -1;
+ return 0;
+ }
+
+ case STATE_READ_PROTO:
+ if (strcmp(token, "tcp") == 0)
+ proto = IPPROTO_TCP;
+ else if (strcmp(token, "udp") == 0)
+ proto = IPPROTO_UDP;
+ else
+ return -1;
+ state = STATE_READ_KEYWORD;
+ break;
+
+ case STATE_READ_SRC:
+ case STATE_READ_DST:
+ {
+ int err;
+ char *p;
+ struct in_addr mask;
+ struct in_addr addr;
+
+ p = token;
+ while (*p != '/' && *p != 0)
+ p++;
+
+ if (*p != '/')
+ {
+ IpMask(32, &mask);
+ err = IpAddr(token, &addr);
+ if (err)
+ return -1;
+ }
+ else
+ {
+ int n;
+ int nbits;
+ char s[sizeof(buffer)];
+
+ *p = ' ';
+ n = sscanf(token, "%s %d", s, &nbits);
+ if (n != 2)
+ return -1;
+
+ err = IpAddr(s, &addr);
+ if (err)
+ return -1;
+
+ err = IpMask(nbits, &mask);
+ if (err)
+ return -1;
+ }
+
+ if (state == STATE_READ_SRC)
+ {
+ src_addr = addr;
+ src_mask = mask;
+ }
+ else
+ {
+ dst_addr = addr;
+ dst_mask = mask;
+ }
+ }
+ state = STATE_READ_KEYWORD;
+ break;
+
+ default:
+ return -1;
+ break;
+ }
+
+ token = strtok(NULL, " \t");
+ }
+#undef STATE_READ_KEYWORD
+#undef STATE_READ_TYPE
+#undef STATE_READ_PORT
+#undef STATE_READ_SERVER
+#undef STATE_READ_RULE
+#undef STATE_READ_DELETE
+#undef STATE_READ_PROTO
+#undef STATE_READ_SRC
+#undef STATE_READ_DST
+
+/* Convert port strings to numbers. This needs to be done after
+ the string is parsed, because the prototype might not be designated
+ before the ports (which might be symbolic entries in /etc/services) */
+
+ if (strlen(str_port) != 0)
+ {
+ int err;
+
+ err = IpPort(str_port, proto, &proxy_port);
+ if (err)
+ return -1;
+ }
+ else
+ {
+ proxy_port = 0;
+ }
+
+ if (strlen(str_server_port) != 0)
+ {
+ int err;
+
+ err = IpPort(str_server_port, proto, &server_port);
+ if (err)
+ return -1;
+ }
+ else
+ {
+ server_port = 0;
+ }
+
+/* Check that at least the server address has been defined */
+ if (server_addr.s_addr == 0)
+ return -1;
+
+/* Add to linked list */
+ proxy_entry = malloc(sizeof(struct proxy_entry));
+ if (proxy_entry == NULL)
+ return -1;
+
+ proxy_entry->proxy_type = proxy_type;
+ proxy_entry->rule_index = rule_index;
+ proxy_entry->proto = proto;
+ proxy_entry->proxy_port = htons(proxy_port);
+ proxy_entry->server_port = htons(server_port);
+ proxy_entry->server_addr = server_addr;
+ proxy_entry->src_addr.s_addr = src_addr.s_addr & src_mask.s_addr;
+ proxy_entry->dst_addr.s_addr = dst_addr.s_addr & dst_mask.s_addr;
+ proxy_entry->src_mask = src_mask;
+ proxy_entry->dst_mask = dst_mask;
+
+ RuleAdd(proxy_entry);
+
+ return 0;
+}
diff --git a/lib/libalias/alias_util.c b/lib/libalias/alias_util.c
new file mode 100644
index 0000000..41ca6cc
--- /dev/null
+++ b/lib/libalias/alias_util.c
@@ -0,0 +1,141 @@
+/*
+ Alias_util.h contains general utilities used by other functions
+ in the packet aliasing module. At the moment, there are functions
+ for computing IP header and TCP packet checksums.
+
+ The checksum routines are based upon example code in a Unix networking
+ text written by Stevens (sorry, I can't remember the title -- but
+ at least this is a good author).
+
+ Initial Version: August, 1996 (cjm)
+
+ Version 1.7: January 9, 1997
+ Added differential checksum update function.
+
+ $FreeBSD$
+*/
+
+/*
+Note: the checksum routines assume that the actual checksum word has
+been zeroed out. If the checksum workd is filled with the proper value,
+then these routines will give a result of zero (useful for testing
+purposes);
+*/
+
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include "alias.h"
+#include "alias_local.h"
+
+u_short
+PacketAliasInternetChecksum(u_short *ptr, int nbytes)
+{
+ int sum, oddbyte;
+
+ sum = 0;
+ while (nbytes > 1)
+ {
+ sum += *ptr++;
+ nbytes -= 2;
+ }
+ if (nbytes == 1)
+ {
+ oddbyte = 0;
+ ((u_char *) &oddbyte)[0] = *(u_char *) ptr;
+ ((u_char *) &oddbyte)[1] = 0;
+ sum += oddbyte;
+ }
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16);
+ return(~sum);
+}
+
+u_short
+IpChecksum(struct ip *pip)
+{
+ return( PacketAliasInternetChecksum((u_short *) pip,
+ (pip->ip_hl << 2)) );
+
+}
+
+u_short
+TcpChecksum(struct ip *pip)
+{
+ u_short *ptr;
+ struct tcphdr *tc;
+ int nhdr, ntcp, nbytes;
+ int sum, oddbyte;
+
+ nhdr = pip->ip_hl << 2;
+ ntcp = ntohs(pip->ip_len) - nhdr;
+
+ tc = (struct tcphdr *) ((char *) pip + nhdr);
+ ptr = (u_short *) tc;
+
+/* Add up TCP header and data */
+ nbytes = ntcp;
+ sum = 0;
+ while (nbytes > 1)
+ {
+ sum += *ptr++;
+ nbytes -= 2;
+ }
+ if (nbytes == 1)
+ {
+ oddbyte = 0;
+ ((u_char *) &oddbyte)[0] = *(u_char *) ptr;
+ ((u_char *) &oddbyte)[1] = 0;
+ sum += oddbyte;
+ }
+
+/* "Pseudo-header" data */
+ ptr = (u_short *) &(pip->ip_dst);
+ sum += *ptr++;
+ sum += *ptr;
+ ptr = (u_short *) &(pip->ip_src);
+ sum += *ptr++;
+ sum += *ptr;
+ sum += htons((u_short) ntcp);
+ sum += htons((u_short) pip->ip_p);
+
+/* Roll over carry bits */
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16);
+
+/* Return checksum */
+ return((u_short) ~sum);
+}
+
+
+void
+DifferentialChecksum(u_short *cksum, u_short *new, u_short *old, int n)
+{
+ int i;
+ int accumulate;
+
+ accumulate = *cksum;
+ for (i=0; i<n; i++)
+ {
+ accumulate -= *new++;
+ accumulate += *old++;
+ }
+
+ if (accumulate < 0)
+ {
+ accumulate = -accumulate;
+ accumulate = (accumulate >> 16) + (accumulate & 0xffff);
+ accumulate += accumulate >> 16;
+ *cksum = (u_short) ~accumulate;
+ }
+ else
+ {
+ accumulate = (accumulate >> 16) + (accumulate & 0xffff);
+ accumulate += accumulate >> 16;
+ *cksum = (u_short) accumulate;
+ }
+}
+
diff --git a/lib/libalias/libalias.3 b/lib/libalias/libalias.3
new file mode 100644
index 0000000..f3f187d
--- /dev/null
+++ b/lib/libalias/libalias.3
@@ -0,0 +1,884 @@
+.\" $FreeBSD$
+.\"
+.Dd July, 1997
+.Dt LIBALIAS 3
+.Os
+.Sh NAME
+.Nm libalias
+.Nd packet aliasing library for masquerading and address translation (NAT)
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <netinet/in.h>
+.Fd #include <alias.h>
+
+Function prototypes are given in the main body
+of the text.
+.Sh DESCRIPTION
+The
+.Nm
+library is a collection of
+functions for aliasing and de-aliasing
+of IP packets, intended for masquerading and
+network address translation (NAT).
+.Sh CONTENTS
+.Bd -literal -offset left
+1. Introduction
+2. Initialization and Control
+ 2.1 PacketAliasInit()
+ 2.2 PacketAliasUninit()
+ 2.3 PacketAliasSetAddress()
+ 2.4 PacketAliasSetMode()
+ 2.5 PacketAliasSetFWBase()
+3. Packet Handling
+ 3.1 PacketAliasIn()
+ 3.2 PacketAliasOut()
+4. Port and Address Redirection
+ 4.1 PacketAliasRedirectPort()
+ 4.2 PacketAliasRedirectAddr()
+ 4.3 PacketAliasRedirectDelete()
+ 4.4 PacketAliasProxyRule()
+ 4.5 PacketAliasPptp()
+5. Fragment Handling
+ 5.1 PacketAliasSaveFragment()
+ 5.2 PacketAliasGetFragment()
+ 5.3 PacketAliasFragmentIn()
+6. Miscellaneous Functions
+ 6.1 PacketAliasSetTarget()
+ 6.2 PacketAliasCheckNewLink()
+ 6.3 PacketAliasInternetChecksum()
+7. Authors
+8. Acknowledgments
+
+Appendix A: Conceptual Background
+ A.1 Aliasing Links
+ A.2 Static and Dynamic Links
+ A.3 Partially Specified Links
+ A.4 Dynamic Link Creation
+.Ed
+.Sh 1. Introduction
+This library is a moderately portable
+set of functions designed to assist
+in the process of IP masquerading and
+network address translation. Outgoing
+packets from a local network with
+unregistered IP addresses can be aliased
+to appear as if they came from an
+accessible IP address. Incoming packets
+are then de-aliased so that they are sent
+to the correct machine on the local network.
+
+A certain amount of flexibility is built
+into the packet aliasing engine. In
+the simplest mode of operation, a
+many-to-one address mapping takes place
+between local network and the packet
+aliasing host. This is known as IP
+masquerading. In addition, one-to-one
+mappings between local and public addresses
+can also be implemented, which is known as
+static NAT. In between these extremes,
+different groups of private addresses
+can be linked to different public addresses,
+comprising several distinct many-to-one
+mappings. Also, a given public address
+and port can be statically redirected to
+a private address/port.
+
+The packet aliasing engine was designed
+to operate in user space outside of the
+kernel, without any access to private
+kernel data structure, but the source code
+can also be ported to a kernel environment.
+.Sh 2. Initialization and Control
+Two specific functions, PacketAliasInit()
+and PacketAliasSetAddress(), must always be
+called before any packet handling may be
+performed. In addition, the operating mode
+of the packet aliasing engine can be customized
+by calling PacketAliasSetMode().
+.Ss 2.1 PacketAliasInit()
+
+.Ft void
+.Fn PacketAliasInit "void"
+
+This function has no argument or return
+value and is used to initialize internal
+data structures. The following mode bits
+are always set after calling
+PacketAliasInit(). See section 2.3 for
+the meaning of these mode bits.
+.Bd -literal -offset indent
+ PKT_ALIAS_USE_SAME_PORTS
+ PKT_ALIAS_USE_SOCKETS
+ PKT_ALIAS_RESET_ON_ADDR_CHANGE
+
+.Ed
+This function will always return the packet
+aliasing engine to the same initial state.
+PacketAliasSetAddress() must be called afterwards,
+and any desired changes from the default mode
+bits listed above require a call to
+PacketAliasSetMode().
+
+It is mandatory that this function be called
+at the beginning of a program prior to any
+packet handling.
+.Ss 2.2 PacketAliasUninit()
+
+.Ft void
+.Fn PacketAliasUninit "void"
+
+This function has no argument or return
+value and is used to clear any resources
+attached to internal data structures.
+
+This functions should be called when a
+program stop using the aliasing engine;
+it do, among other things, clear out any
+firewall holes. To provide backwards
+compatibility and extra security, it is
+added to the atexit() chain by
+PacketAliasInit(). Calling it multiple
+times is harmless.
+.Ss 2.3 PacketAliasSetAddress()
+
+.Ft void
+.Fn PacketAliasSetAddress "struct in_addr addr"
+
+This function sets the source address to which
+outgoing packets from the local area network
+are aliased. All outgoing packets are remapped
+to this address unless overridden by a static
+address mapping established by
+PacketAliasRedirectAddr().
+
+If the PKT_ALIAS_RESET_ON_ADDR_CHANGE mode bit
+is set (the default mode of operation), then
+the internal aliasing link tables will be reset
+any time the aliasing address changes.
+This is useful
+for interfaces such as ppp where the IP
+address may or may not change on successive
+dial-up attempts.
+
+If the PKT_ALIAS_RESET_ON_ADDR_CHANGE mode bit
+is set to zero, this function can also be used to
+dynamically change the aliasing address on a
+packet to packet basis (it is a low overhead
+call).
+
+It is mandatory that this function be called
+prior to any packet handling.
+.Ss 2.4 PacketAliasSetMode()
+
+.Ft unsigned int
+.Fn PacketAliasSetMode "unsigned int mode" "unsigned int mask"
+
+This function sets or clears mode bits
+according to the value of
+.Em mode .
+Only bits marked in
+.Em mask
+are affected. The following mode bits are
+defined in alias.h:
+.Bl -hang -offset left
+.It PKT_ALIAS_LOG.
+Enables logging /var/log/alias.log. The log file
+shows total numbers of links (icmp, tcp, udp) each
+time an aliasing link is created or deleted. Mainly
+useful for debugging when the log file is viewed
+continuously with "tail -f".
+.It PKT_ALIAS_DENY_INCOMING.
+If this mode bit is set, all incoming packets
+associated with new TCP connections or new
+UDP transactions will be marked for being
+ignored (PacketAliasIn() return code
+PKT_ALIAS_IGNORED) by the calling program.
+Response packets to connections or transactions
+initiated from the packet aliasing host or
+local network will be unaffected. This mode
+bit is useful for implementing a one-way firewall.
+.It PKT_ALIAS_SAME_PORTS.
+If this mode bit is set, the packet aliasing
+engine will attempt to leave the alias port
+numbers unchanged from the actual local port
+number. This can be done as long as the
+quintuple (proto, alias addr, alias port,
+remote addr, remote port) is unique. If a
+conflict exists, a new aliasing port number is
+chosen even if this mode bit is set.
+.It PKT_ALIAS_USE_SOCKETS.
+This bit should be set when the packet
+aliasing host originates network traffic as
+well as forwards it. When the packet aliasing
+host is waiting for a connection from an
+unknown host address or unknown port number
+(e.g. an FTP data connection), this mode bit
+specifies that a socket be allocated as a place
+holder to prevent port conflicts. Once a
+connection is established, usually within a
+minute or so, the socket is closed.
+.It PKT_ALIAS_UNREGISTERED_ONLY.
+If this mode bit is set, traffic on the
+local network which does not originate from
+unregistered address spaces will be ignored.
+Standard Class A, B and C unregistered addresses
+are:
+.Bd -literal -offset indent
+ 10.0.0.0 -> 10.255.255.255 (Class A subnet)
+ 172.16.0.0 -> 172.31.255.255 (Class B subnets)
+ 192.168.0.0 -> 192.168.255.255 (Class C subnets)
+
+.Ed
+This option is useful in the case that
+packet aliasing host has both registered and
+unregistered subnets on different interfaces.
+The registered subnet is fully accessible to
+the outside world, so traffic from it doesn't
+need to be passed through the packet aliasing
+engine.
+.It PKT_ALIAS_RESET_ON_ADDR_CHANGE.
+When this mode bit is set and
+PacketAliasSetAddress() is called to change
+the aliasing address, the internal link table
+of the packet aliasing engine will be cleared.
+This operating mode is useful for ppp links
+where the interface address can sometimes
+change or remain the same between dial-ups.
+If this mode bit is not set, the link table
+will never be reset in the event of an
+address change.
+.It PKT_ALIAS_PUNCH_FW.
+This option makes libalias `punch holes' in an
+ipfw based firewall for FTP/IRC DCC connections.
+The holes punched are bound by from/to IP address
+and port; it will not be possible to use a hole
+for another connection. A hole is removed when
+the connection that uses it dies. To cater to
+unexpected death of a program using libalias (e.g
+kill -9), changing the state of the flag will
+clear the entire ipfw range allocated for holes.
+This will also happen on the initial call to
+PacketAliasSetFWBase(). This call must happen
+prior to setting this flag.
+.It PKT_ALIAS_REVERSE.
+This option makes libalias reverse the way it
+handles incoming and outgoing packets, allowing
+it to be fed data that passes through the internal
+interface rather than the external one.
+
+.El
+
+.Ss 2.5 PacketAliasSetFWBase()
+
+.Ft void
+.Fn PacketAliasSetFWBase "unsigned int base" "unsigned int num"
+
+Set IPFW range allocated for punching firewall holes (with the
+PKT_ALIAS_PUNCH_FW flag). The range will be cleared for all rules on
+initialization.
+.Sh 3. Packet Handling
+The packet handling functions are used to
+modify incoming (remote->local) and outgoing
+(local->remote) packets. The calling program
+is responsible for receiving and sending
+packets via network interfaces.
+
+Along with PacketAliasInit() and PacketAliasSetAddress(),
+the two packet handling functions, PacketAliasIn()
+and PacketAliasOut(), comprise minimal set of functions
+needed for a basic IP masquerading implementation.
+.Ss 3.1 PacketAliasIn()
+
+.Ft int
+.Fn PacketAliasIn "char *buffer" "int maxpacketsize"
+
+An incoming packet coming from a remote machine to
+the local network is de-aliased by this function.
+The IP packet is pointed to by
+.Em buffer ,
+and
+.Em maxpacketsize
+indicates the size of the data structure containing
+the packet and should be at least as large as the
+actual packet size.
+
+Return codes:
+.Bl -hang -offset left
+.It PKT_ALIAS_ERROR.
+An internal error within the packet aliasing
+engine occurred.
+.It PKT_ALIAS_OK.
+The packet aliasing process was successful.
+.It PKT_ALIAS_IGNORED.
+The packet was ignored and not de-aliased.
+This can happen if the protocol is unrecognized,
+possibly an ICMP message type is not handled or
+if incoming packets for new connections are being
+ignored (see PKT_ALIAS_DENY_INCOMING in section
+2.2).
+.It PKT_ALIAS_UNRESOLVED_FRAGMENT.
+This is returned when a fragment cannot be
+resolved because the header fragment has not
+been sent yet. In this situation, fragments
+must be saved with PacketAliasSaveFragment()
+until a header fragment is found.
+.It PKT_ALIAS_FOUND_HEADER_FRAGMENT.
+The packet aliasing process was successful,
+and a header fragment was found. This is a
+signal to retrieve any unresolved fragments
+with PacketAliasGetFragment() and de-alias
+them with PacketAliasFragmentIn().
+.El
+.Ss 3.2 PacketAliasOut()
+
+.Ft int
+.Fn PacketAliasOut "char *buffer" "int maxpacketsize"
+
+An outgoing packet coming from the local network
+to a remote machine is aliased by this function.
+The IP packet is pointed to by
+.Em buffer ,
+and
+.Em maxpacketsize
+indicates the maximum packet size permissible
+should the packet length be changed. IP encoding
+protocols place address and port information in
+the encapsulated data stream which have to be
+modified and can account for changes in packet
+length. Well known examples of such protocols
+are FTP and IRC DCC.
+
+Return codes:
+.Bl -hang -offset left
+.It PKT_ALIAS_ERROR.
+An internal error within the packet aliasing
+engine occurred.
+.It PKT_ALIAS_OK.
+The packet aliasing process was successful.
+.It PKT_ALIAS_IGNORED.
+The packet was ignored and not de-aliased.
+This can happen if the protocol is unrecognized,
+or possibly an ICMP message type is not handled.
+.El
+.Sh 4. Port and Address Redirection
+The functions described in this section allow machines
+on the local network to be accessible in some degree
+to new incoming connections from the external network.
+Individual ports can be re-mapped or static network
+address translations can be designated.
+.Ss 4.1 PacketAliasRedirectPort()
+
+.Ft struct alias_link *
+.Fo PacketAliasRedirectPort
+.Fa "struct in_addr local_addr"
+.Fa "u_short local_port"
+.Fa "struct in_addr remote_addr"
+.Fa "u_short remote_port"
+.Fa "struct in_addr alias_addr"
+.Fa "u_short alias_port"
+.Fa "u_char proto"
+.Fc
+
+This function specifies that traffic from a
+given remote address/port to an alias address/port
+be redirected to a specified local address/port.
+The parameter
+.Em proto
+can be either IPPROTO_TCP or IPPROTO_UDP, as
+defined in <netinet/in.h>.
+
+If
+.Em local_addr
+or
+.Em alias_addr
+is zero, this indicates that the packet aliasing
+address as established by PacketAliasSetAddress()
+is to be used. Even if PacketAliasSetAddress() is
+called to change the address after PacketAliasRedirectPort()
+is called, a zero reference will track this change.
+
+If
+.Em remote_addr
+is zero, this indicates to redirect packets from
+any remote address. Likewise, if
+.Em remote_port
+is zero, this indicates to redirect packets originating
+from any remote port number. Almost always, the remote
+port specification will be zero, but non-zero remote
+addresses can sometimes be useful for firewalling.
+If two calls to PacketAliasRedirectPort() overlap in
+their address/port specifications, then the most recent
+call will have precedence.
+
+This function returns a pointer which can subsequently
+be used by PacketAliasRedirectDelete(). If NULL is
+returned, then the function call did not complete
+successfully.
+
+All port numbers are in network address byte order,
+so it is necessary to use htons() to convert these
+parameters from internally readable numbers to
+network byte order. Addresses are also in network
+byte order, which is implicit in the use of the
+.Em struct in_addr
+data type.
+.Ss 4.2 PacketAliasRedirectAddr()
+
+.Ft struct alias_link *
+.Fo PacketAliasRedirectAddr
+.Fa "struct in_addr local_addr"
+.Fa "struct in_addr alias_addr"
+.Fc
+
+This function desgnates that all incoming
+traffic to
+.Em alias_addr
+be redirected to
+.Em local_addr.
+Similarly, all outgoing traffic from
+.Em local_addr
+is aliased to
+.Em alias_addr .
+
+If
+.Em local_addr
+or
+.Em alias_addr
+is zero, this indicates that the packet aliasing
+address as established by PacketAliasSetAddress()
+is to be used. Even if PacketAliasSetAddress() is
+called to change the address after PacketAliasRedirectAddr()
+is called, a zero reference will track this change.
+
+If subsequent calls to PacketAliasRedirectAddr()
+use the same aliasing address, all new incoming
+traffic to this aliasing address will be redirected
+to the local address made in the last function call.
+New traffic generated by any of the local machines, designated
+in the several function calls, will be aliased to
+the same address. Consider the following example:
+.Bd -literal -offset left
+ PacketAliasRedirectAddr(inet_aton("192.168.0.2"),
+ inet_aton("141.221.254.101"));
+ PacketAliasRedirectAddr(inet_aton("192.168.0.3"),
+ inet_aton("141.221.254.101"));
+ PacketAliasRedirectAddr(inet_aton("192.168.0.4"),
+ inet_aton("141.221.254.101"));
+.Ed
+
+Any outgoing connections such as telnet or ftp
+from 192.168.0.2, 192.168.0.3, 192.168.0.4 will
+appear to come from 141.221.254.101. Any incoming
+connections to 141.221.254.101 will be directed
+to 192.168.0.4.
+
+Any calls to PacketAliasRedirectPort() will
+have precedence over address mappings designated
+by PacketAliasRedirectAddr().
+
+This function returns a pointer which can subsequently
+be used by PacketAliasRedirectDelete(). If NULL is
+returned, then the function call did not complete
+successfully.
+.Ss 4.3 PacketAliasRedirectDelete()
+
+.Ft void
+.Fn PacketAliasRedirectDelete "struct alias_link *ptr"
+
+This function will delete a specific static redirect
+rule entered by PacketAliasRedirectPort() or
+PacketAliasRedirectAddr(). The parameter
+.Em ptr
+is the pointer returned by either of the redirection
+functions. If an invalid pointer is passed to
+PacketAliasRedirectDelete(), then a program crash
+or unpredictable operation could result, so it is
+necessary to be careful using this function.
+.Ss 4.4 PacketAliasProxyRule()
+
+.Ft int
+.Fn PacketAliasProxyRule "const char *cmd"
+
+The passed
+.Ar cmd
+string consists of one or more pairs of words. The first word in each
+pair is a token and the second is the value that should be applied for
+that token. Tokens and their argument types are as follows:
+
+.Bl -tag -offset XXX -width XXX
+.It type encode_ip_hdr|encode_tcp_stream|no_encode
+In order to support transparent proxying, it is necessary to somehow
+pass the original address and port information into the new destination
+server. If
+.Dq encode_ip_hdr
+is specified, the original address and port is passed as an extra IP
+option. If
+.Dq encode_tcp_stream
+is specified, the original address and port is passed as the first
+piece of data in the tcp stream in the format
+.Dq DEST Ar IP port .
+.It port Ar portnum
+Only packets with the destination port
+.Ar portnum
+are proxied.
+.It server Ar host[:portnum]
+This specifies the
+.Ar host
+and
+.Ar portnum
+that the data is to be redirected to.
+.Ar host
+must be an IP address rather than a DNS host name. If
+.Ar portnum
+is not specified, the destination port number is not changed.
+.Pp
+The
+.Ar server
+specification is mandatory unless the
+.Dq delete
+command is being used.
+.It rule Ar index
+Normally, each call to
+.Fn PacketAliasProxyRule
+inserts the next rule at the start of a linear list of rules. If an
+.Ar index
+is specified, the new rule will be checked after all rules with lower
+indices. Calls to
+.Fn PacketAliasProxyRule
+that do not specify a rule are assigned rule 0.
+.It delete Ar index
+This token and its argument must not be used with any other tokens. When
+used, all existing rules with the given
+.Ar index
+are deleted.
+.It proto tcp|udp
+If specified, only packets of the given protocol type are matched.
+.It src Ar IP[/bits]
+If specified, only packets with a source address matching the given
+.Ar IP
+are matched. If
+.Ar bits
+is also specified, then the first
+.Ar bits
+bits of
+.Ar IP
+are taken as a network specification, and all IP addresses from that
+network will be matched.
+.It dst Ar IP[/bits]
+If specified, only packets with a destination address matching the given
+.Ar IP
+are matched. If
+.Ar bits
+is also specified, then the first
+.Ar bits
+bits of
+.Ar IP
+are taken as a network specification, and all IP addresses from that
+network will be matched.
+.El
+
+This function is usually used to redirect outgoing connections for
+internal machines that are not permitted certain types of internet
+access, or to restrict access to certain external machines.
+.Ss 4.5 PacketAliasPptp()
+
+.Ft extern int
+.Fn PacketAliasPptp "struct in_addr addr"
+
+This function causes any
+.Em G Ns No eneral
+.Em R Ns No outing
+.Em E Ns No ncapsulation
+.Pq Dv IPPROTO_GRE
+packets to be aliased using
+.Ar addr
+rather than the address set via
+.Fn PacketAliasSetAddress .
+This allows the uses of the
+.Em P Ns No oint
+to
+.Em P Ns No oint
+.Em T Ns No unneling
+.Em P Ns No rotocol
+on a machine on the internal network.
+.Pp
+If the passed address is
+.Dv INADDR_NONE
+.Pq 255.255.255.255 ,
+.Dv PPTP
+aliasing is disabled.
+.Sh 5. Fragment Handling
+The functions in this section are used to deal with
+incoming fragments.
+
+Outgoing fragments are handled within PacketAliasOut()
+by changing the address according to any
+applicable mapping set by PacketAliasRedirectAddress(),
+or the default aliasing address set by
+PacketAliasSetAddress().
+
+Incoming fragments are handled in one of two ways.
+If the header of a fragmented IP packet has already
+been seen, then all subsequent fragments will be
+re-mapped in the same manner the header fragment
+was. Fragments which arrive before the header
+are saved and then retrieved once the header fragment
+has been resolved.
+.Ss 5.1 PacketAliasSaveFragment()
+
+.Ft int
+.Fn PacketAliasSaveFragment "char *ptr"
+
+When PacketAliasIn() returns
+PKT_ALIAS_UNRESOLVED_FRAGMENT, this
+function can be used to save the pointer to
+the unresolved fragment.
+
+It is implicitly assumed that
+.Em ptr
+points to a block of memory allocated by
+malloc(). If the fragment is never
+resolved, the packet aliasing engine will
+automatically free the memory after a
+timeout period. [Eventually this function
+should be modified so that a callback
+function for freeing memory is passed as
+an argument.]
+
+This function returns PKT_ALIAS_OK if it
+was successful and PKT_ALIAS_ERROR if there
+was an error.
+
+.Ss 5.2 PacketAliasGetFragment()
+
+.Ft char *
+.Fn PacketAliasGetFragment "char *buffer"
+
+This function can be used to retrieve fragment
+pointers saved by PacketAliasSaveFragment().
+The IP header fragment pointed to by
+.Em buffer
+is the header fragment indicated when
+PacketAliasIn() returns PKT_ALIAS_FOUND_HEADER_FRAGMENT.
+Once a a fragment pointer is retrieved, it
+becomes the calling program's responsibility
+to free the dynamically allocated memory for
+the fragment.
+
+PacketAliasGetFragment() can be called
+sequentially until there are no more fragments
+available, at which time it returns NULL.
+.Ss 5.3 PacketAliasFragmentIn()
+
+.Ft void
+.Fn PacketAliasFragmentIn "char *header" "char *fragment"
+
+When a fragment is retrieved with
+PacketAliasGetFragment(), it can then be
+de-aliased with a call to PacketAliasFragmentIn().
+.Em header
+is the pointer to a header fragment used as a
+template, and
+.Em fragment
+is the pointer to the packet to be de-aliased.
+.Sh 6. Miscellaneous Functions
+
+.Ss 6.1 PacketAliasSetTarget()
+
+.Ft void
+.Fn PacketAliasSetTarget "struct in_addr addr"
+
+When an incoming packet not associated with
+any pre-existing aliasing link arrives at the
+host machine, it will be sent to the address
+indicated by a call to PacketAliasSetTarget().
+
+If this function is not called, or is called
+with a zero address argument, then all new
+incoming packets go to the address set by
+PacketAliasSetAddress.
+.Ss 6.2 PacketAliasCheckNewLink()
+
+.Ft int
+.Fn PacketAliasCheckNewLink "void"
+
+This function returns a non-zero value when
+a new aliasing link is created. In circumstances
+where incoming traffic is being sequentially
+sent to different local servers, this function
+can be used to trigger when PacketAliasSetTarget()
+is called to change the default target address.
+.Ss 6.3 PacketAliasInternetChecksum()
+
+.Ft u_short
+.Fn PacketAliasInternetChecksum "u_short *buffer" "int nbytes"
+
+This is a utility function that does not seem
+to be available elswhere and is included as a
+convenience. It computes the internet checksum,
+which is used in both IP and protocol-specific
+headers (TCP, UDP, ICMP).
+
+.Em buffer
+points to the data block to be checksummed, and
+.Em nbytes
+is the number of bytes. The 16-bit checksum
+field should be zeroed before computing the checksum.
+
+Checksums can also be verified by operating on a block
+of data including its checksum. If the checksum is
+valid, PacketAliasInternetChecksum() will return zero.
+.Sh 7. Authors
+Charles Mott (cmott@srv.net), versions 1.0 - 1.8, 2.0 - 2.4.
+
+Eivind Eklund (eivind@freebsd.org), versions 1.8b, 1.9 and
+2.5. Added IRC DCC support as well as contributing a number of
+architectural improvements; added the firewall bypass
+for FTP/IRC DCC.
+.Sh 8. Acknowledgments
+
+Listed below, in approximate chronological
+order, are individuals who have provided
+valuable comments and/or debugging assistance.
+
+.Bl -inset -compact -offset left
+.It Gary Roberts
+.It Tom Torrance
+.It Reto Burkhalter
+.It Martin Renters
+.It Brian Somers
+.It Paul Traina
+.It Ari Suutari
+.It Dave Remien
+.It J. Fortes
+.It Andrzej Bialeki
+.It Gordon Burditt
+.El
+.Sh Appendix: Conceptual Background
+This appendix is intended for those who
+are planning to modify the source code or want
+to create somewhat esoteric applications using
+the packet aliasing functions.
+
+The conceptual framework under which the
+packet aliasing engine operates is described here.
+Central to the discussion is the idea of an
+"aliasing link" which describes the relationship
+for a given packet transaction between the local
+machine, aliased identity and remote machine. It
+is discussed how such links come into existence
+and are destroyed.
+.Ss A.1 Aliasing Links
+There is a notion of an "aliasing link",
+which is 7-tuple describing a specific
+translation:
+.Bd -literal -offset indent
+(local addr, local port, alias addr, alias port,
+ remote addr, remote port, protocol)
+.Ed
+
+Outgoing packets have the local address and
+port number replaced with the alias address
+and port number. Incoming packets undergo the
+reverse process. The packet aliasing engine
+attempts to match packets against an internal
+table of aliasing links to determine how to
+modify a given IP packet. Both the IP
+header and protocol dependent headers are
+modified as necessary. Aliasing links are
+created and deleted as necessary according
+to network traffic.
+
+Protocols can be TCP, UDP or even ICMP in
+certain circumstances. (Some types of ICMP
+packets can be aliased according to sequence
+or id number which acts as an equivalent port
+number for identifying how individual packets
+should be handled.)
+
+Each aliasing link must have a unique
+combination of the following five quantities:
+alias address/port, remote address/port
+and protocol. This ensures that several
+machines on a local network can share the
+same aliased IP address. In cases where
+conflicts might arise, the aliasing port
+is chosen so that uniqueness is maintained.
+.Ss A.2 Static and Dynamic Links
+Aliasing links can either be static or dynamic.
+Static links persist indefinitely and represent
+fixed rules for translating IP packets. Dynamic
+links come into existence for a specific TCP
+connection or UDP transaction or ICMP echo
+sequence. For the case of TCP, the connection
+can be monitored to see when the associated
+aliasing link should be deleted. Aliasing links
+for UDP transactions (and ICMP echo and timestamp
+requests) work on a simple timeout rule. When
+no activity is observed on a dynamic link for
+a certain amount of time it is automatically
+deleted. Timeout rules also apply to TCP
+connections which do not open or close
+properly.
+.Ss A.3 Partially Specified Aliasing Links
+Aliasing links can be partially specified,
+meaning that the remote address and/or remote
+ports are unknown. In this case, when a packet
+matching the incomplete specification is found,
+a fully specified dynamic link is created. If
+the original partially specified link is dynamic,
+it will be deleted after the fully specified link
+is created, otherwise it will persist.
+
+For instance, a partially specified link might
+be
+.Bd -literal -offset indent
+(192.168.0.4, 23, 204.228.203.215, 8066, 0, 0, tcp)
+.Ed
+
+The zeros denote unspecified components for
+the remote address and port. If this link were
+static it would have the effect of redirecting
+all incoming traffic from port 8066 of
+204.228.203.215 to port 23 (telnet) of machine
+192.168.0.4 on the local network. Each
+individual telnet connection would initiate
+the creation of a distinct dynamic link.
+.Ss A.4 Dynamic Link Creation
+In addition to aliasing links, there are
+also address mappings that can be stored
+within the internal data table of the packet
+aliasing mechanism.
+.Bd -literal -offset indent
+(local addr, alias addr)
+.Ed
+
+Address mappings are searched when creating
+new dynamic links.
+
+All outgoing packets from the local network
+automatically create a dynamic link if
+they do not match an already existing fully
+specified link. If an address mapping exists
+for the outgoing packet, this determines
+the alias address to be used. If no mapping
+exists, then a default address, usually the
+address of the packet aliasing host, is used.
+If necessary, this default address can be
+changed as often as each individual packet
+arrives.
+
+The aliasing port number is determined
+such that the new dynamic link does not
+conflict with any existing links. In the
+default operating mode, the packet aliasing
+engine attempts to set the aliasing port
+equal to the local port number. If this
+results in a conflict, then port numbers
+are randomly chosen until a unique aliasing
+link can be established. In an alternate
+operating mode, the first choice of an
+aliasing port is also random and unrelated
+to the local port number.
+
diff --git a/lib/libatm/Makefile b/lib/libatm/Makefile
new file mode 100644
index 0000000..218bf9f
--- /dev/null
+++ b/lib/libatm/Makefile
@@ -0,0 +1,40 @@
+#
+#
+# ===================================
+# HARP | Host ATM Research Platform
+# ===================================
+#
+#
+# This Host ATM Research Platform ("HARP") file (the "Software") is
+# made available by Network Computing Services, Inc. ("NetworkCS")
+# "AS IS". NetworkCS does not provide maintenance, improvements or
+# support of any kind.
+#
+# NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+# INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+# SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+# In no event shall NetworkCS be responsible for any damages, including
+# but not limited to consequential damages, arising from or relating to
+# any use of the Software or related support.
+#
+# Copyright 1994-1998 Network Computing Services, Inc.
+#
+# Copies of this Software may be made, however, the above copyright
+# notice must be reproduced on all copies.
+#
+# @(#) $FreeBSD$
+#
+#
+
+LIB= atm
+SRCS= atm_addr.c cache_key.c ioctl_subr.c ip_addr.c ip_checksum.c timer.c
+
+LDADD+= -lmd
+DPADD+= ${LIBMD}
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/libatm.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libatm/atm_addr.c b/lib/libatm/atm_addr.c
new file mode 100644
index 0000000..a7a3178
--- /dev/null
+++ b/lib/libatm/atm_addr.c
@@ -0,0 +1,328 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $FreeBSD$
+ *
+ */
+
+/*
+ * User Space Library Functions
+ * ----------------------------
+ *
+ * ATM address utility functions
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netatm/port.h>
+#include <netatm/atm.h>
+#include <netatm/atm_if.h>
+#include <netatm/atm_sap.h>
+#include <netatm/atm_sys.h>
+#include <netatm/atm_ioctl.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "libatm.h"
+
+#ifndef lint
+__RCSID("@(#) $FreeBSD$");
+#endif
+
+
+extern char *prog;
+
+
+/*
+ * Get NSAP, NSAP prefix or MAC address
+ *
+ * Arguments:
+ * in pointer to an address in ASCII
+ * out pointer to a buffer for the converted address
+ * len the length of the output buffer
+ *
+ * Returns:
+ * 0 error in format
+ * len the length of the data in the output buffer
+ *
+ */
+int
+get_hex_atm_addr(in, out, len)
+ char *in;
+ u_char *out;
+ int len;
+{
+ int c_type, c_value, i, out_len, state, val = 0;
+
+ /*
+ * Character table
+ */
+ static struct {
+ char c;
+ int type;
+ int value;
+ } char_table[] = {
+ {'.', 0, 0}, /* Type 0 -- period */
+ {':', 0, 0}, /* Type 0 -- colon */
+ {'0', 1, 0}, /* Type 1 -- hex digit */
+ {'1', 1, 1},
+ {'2', 1, 2},
+ {'3', 1, 3},
+ {'4', 1, 4},
+ {'5', 1, 5},
+ {'6', 1, 6},
+ {'7', 1, 7},
+ {'8', 1, 8},
+ {'9', 1, 9},
+ {'a', 1, 10},
+ {'b', 1, 11},
+ {'c', 1, 12},
+ {'d', 1, 13},
+ {'e', 1, 14},
+ {'f', 1, 15},
+ {'A', 1, 10},
+ {'B', 1, 11},
+ {'C', 1, 12},
+ {'D', 1, 13},
+ {'E', 1, 14},
+ {'F', 1, 15},
+ {'\0', 2, 0}, /* Type 2 -- end of input */
+ };
+
+ /*
+ * State table
+ */
+ static struct {
+ int action;
+ int state;
+ } state_table[3][3] = {
+ /* Period Hex End */
+ { { 0, 0 }, { 1, 1 }, { 2, 0} }, /* Init */
+ { { 4, 0 }, { 3, 2 }, { 4, 0} }, /* C1 */
+ { { 0, 2 }, { 1, 1 }, { 2, 0} }, /* C2 */
+ };
+
+ /*
+ * Initialize
+ */
+ state = 0;
+ out_len = 0;
+ if (!strncasecmp(in, "0x", 2)) {
+ in += 2;
+ }
+
+ /*
+ * Loop through input until state table says to return
+ */
+ while (1) {
+ /*
+ * Get the character type and value
+ */
+ for (i=0; char_table[i].c; i++)
+ if (char_table[i].c == *in)
+ break;
+ if (char_table[i].c != *in)
+ return(0);
+ c_type = char_table[i].type;
+ c_value = char_table[i].value;
+
+ /*
+ * Process next character based on state and type
+ */
+ switch(state_table[state][c_type].action) {
+ case 0:
+ /*
+ * Ignore the character
+ */
+ break;
+
+ case 1:
+ /*
+ * Save the character's value
+ */
+ val = c_value;
+ break;
+
+ case 2:
+ /*
+ * Return the assembled NSAP
+ */
+ return(out_len);
+
+ case 3:
+ /*
+ * Assemble and save the output byte
+ */
+ val = val << 4;
+ val += c_value;
+ out[out_len] = (u_char) val;
+ out_len++;
+ break;
+
+ case 4:
+ /*
+ * Invalid input sequence
+ */
+ return(0);
+
+ default:
+ return(0);
+ }
+
+ /*
+ * Set the next state and go on to the next character
+ */
+ state = state_table[state][c_type].state;
+ in++;
+ }
+}
+
+
+/*
+ * Format an ATM address into a string
+ *
+ * Arguments:
+ * addr pointer to an atm address
+ *
+ * Returns:
+ * none
+ *
+ */
+char *
+format_atm_addr(addr)
+ Atm_addr *addr;
+{
+ int i;
+ char *nsap_format;
+ Atm_addr_nsap *atm_nsap;
+ Atm_addr_e164 *atm_e164;
+ Atm_addr_spans *atm_spans;
+ Atm_addr_pvc *atm_pvc;
+ static char str[256];
+ union {
+ int w;
+ char c[4];
+ } u1, u2;
+
+ static char nsap_format_DCC[] = "0x%02x.%02x%02x.%02x.%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x%02x%02x.%02x";
+ static char nsap_format_ICD[] = "0x%02x.%02x%02x.%02x.%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x%02x%02x.%02x";
+ static char nsap_format_E164[] = "0x%02x.%02x%02x%02x%02x%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x%02x%02x.%02x";
+
+ /*
+ * Clear the returned string
+ */
+ UM_ZERO(str, sizeof(str));
+ strcpy(str, "-");
+
+ /*
+ * Print format is determined by address type
+ */
+ switch (addr->address_format) {
+ case T_ATM_ENDSYS_ADDR:
+ atm_nsap = (Atm_addr_nsap *)addr->address;
+ switch(atm_nsap->aan_afi) {
+ default:
+ case AFI_DCC:
+ nsap_format = nsap_format_DCC;
+ break;
+ case AFI_ICD:
+ nsap_format = nsap_format_ICD;
+ break;
+ case AFI_E164:
+ nsap_format = nsap_format_E164;
+ break;
+ }
+ sprintf(str, nsap_format,
+ atm_nsap->aan_afi,
+ atm_nsap->aan_afspec[0],
+ atm_nsap->aan_afspec[1],
+ atm_nsap->aan_afspec[2],
+ atm_nsap->aan_afspec[3],
+ atm_nsap->aan_afspec[4],
+ atm_nsap->aan_afspec[5],
+ atm_nsap->aan_afspec[6],
+ atm_nsap->aan_afspec[7],
+ atm_nsap->aan_afspec[8],
+ atm_nsap->aan_afspec[9],
+ atm_nsap->aan_afspec[10],
+ atm_nsap->aan_afspec[11],
+ atm_nsap->aan_esi[0],
+ atm_nsap->aan_esi[1],
+ atm_nsap->aan_esi[2],
+ atm_nsap->aan_esi[3],
+ atm_nsap->aan_esi[4],
+ atm_nsap->aan_esi[5],
+ atm_nsap->aan_sel);
+ break;
+
+ case T_ATM_E164_ADDR:
+ atm_e164 = (Atm_addr_e164 *)addr->address;
+ for(i=0; i<addr->address_length; i++) {
+ sprintf(&str[strlen(str)], "%c",
+ atm_e164->aae_addr[i]);
+ }
+ break;
+
+ case T_ATM_SPANS_ADDR:
+ /*
+ * Print SPANS address as two words, xxxx.yyyy
+ */
+ atm_spans = (Atm_addr_spans *)addr->address;
+ u1.c[0] = atm_spans->aas_addr[0];
+ u1.c[1] = atm_spans->aas_addr[1];
+ u1.c[2] = atm_spans->aas_addr[2];
+ u1.c[3] = atm_spans->aas_addr[3];
+
+ u2.c[0] = atm_spans->aas_addr[4];
+ u2.c[1] = atm_spans->aas_addr[5];
+ u2.c[2] = atm_spans->aas_addr[6];
+ u2.c[3] = atm_spans->aas_addr[7];
+
+ if (!(u1.w == 0 && u2.w == 0))
+ sprintf(str, "0x%08lx.%08lx", ntohl(u1.w), ntohl(u2.w));
+ break;
+
+ case T_ATM_PVC_ADDR:
+ /*
+ * Print PVC as VPI, VCI
+ */
+ atm_pvc = (Atm_addr_pvc *)addr->address;
+ sprintf(str, "%d, %d",
+ ATM_PVC_GET_VPI(atm_pvc),
+ ATM_PVC_GET_VCI(atm_pvc));
+ break;
+
+ case T_ATM_ABSENT:
+ default:
+ break;
+ }
+
+ return(str);
+}
diff --git a/lib/libatm/cache_key.c b/lib/libatm/cache_key.c
new file mode 100644
index 0000000..582604c
--- /dev/null
+++ b/lib/libatm/cache_key.c
@@ -0,0 +1,114 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $FreeBSD$
+ *
+ */
+
+
+/*
+ * User Space Library Functions
+ * ----------------------------
+ *
+ * SCSP cache key computation
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netatm/port.h>
+#include <netatm/atm.h>
+#include <netatm/atm_if.h>
+#include <netatm/atm_sap.h>
+#include <netatm/atm_sys.h>
+#include <netatm/atm_ioctl.h>
+
+#include <md5.h>
+#include <string.h>
+
+#include "libatm.h"
+
+#ifndef lint
+__RCSID("@(#) $FreeBSD$");
+#endif
+
+
+/*
+ * Compute an SCSP cache key
+ *
+ * Arguments:
+ * ap pointer to an Atm_addr with the ATM address
+ * ip pointer to a struct in_addr with the IP address
+ * ol the required length of the cache key
+ * op pointer to receive cache key
+ *
+ * Returns:
+ * none
+ *
+ */
+void
+scsp_cache_key(ap, ip, ol, op)
+ Atm_addr *ap;
+ struct in_addr *ip;
+ int ol;
+ char *op;
+{
+ int i, len;
+ char buff[32], digest[16];
+ MD5_CTX context;
+
+ /*
+ * Initialize
+ */
+ UM_ZERO(buff, sizeof(buff));
+
+ /*
+ * Copy the addresses into a buffer for MD5 computation
+ */
+ len = sizeof(struct in_addr) + ap->address_length;
+ if (len > sizeof(buff))
+ len = sizeof(buff);
+ UM_COPY(ip, buff, sizeof(struct in_addr));
+ UM_COPY(ap->address, &buff[sizeof(struct in_addr)],
+ len - sizeof(struct in_addr));
+
+ /*
+ * Compute the MD5 digest of the combined IP and ATM addresses
+ */
+ MD5Init(&context);
+ MD5Update(&context, buff, len);
+ MD5Final(digest, &context);
+
+ /*
+ * Fold the 16-byte digest to the required length
+ */
+ UM_ZERO((caddr_t)op, ol);
+ for (i = 0; i < 16; i++) {
+ op[i % ol] = op[i % ol] ^ digest[i];
+ }
+}
diff --git a/lib/libatm/ioctl_subr.c b/lib/libatm/ioctl_subr.c
new file mode 100644
index 0000000..82a31b2
--- /dev/null
+++ b/lib/libatm/ioctl_subr.c
@@ -0,0 +1,481 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $FreeBSD$
+ *
+ */
+
+/*
+ * User Space Library Functions
+ * ----------------------------
+ *
+ * IOCTL subroutines
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netatm/port.h>
+#include <netatm/atm.h>
+#include <netatm/atm_if.h>
+#include <netatm/atm_sap.h>
+#include <netatm/atm_sys.h>
+#include <netatm/atm_ioctl.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "libatm.h"
+
+#ifndef lint
+__RCSID("@(#) $FreeBSD$");
+#endif
+
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+extern char *prog;
+
+
+/*
+ * Issue an informational IOCTL
+ *
+ * The user fills out the opcode and any subtype information. This
+ * routine will allocate a buffer and issue the IOCTL. If the request
+ * fails because the buffer wasn't big enough, this routine will double
+ * the buffer size and retry the request repeatedly. The buffer must
+ * be freed by the caller.
+ *
+ * Arguments:
+ * req pointer to an ATM information request IOCTL structure
+ * buf_len length of buffer to be allocated
+ *
+ * Returns:
+ * -1 error encountered (reason in errno)
+ * int length of the returned VCC information
+ *
+ */
+int
+do_info_ioctl(req, buf_len)
+ struct atminfreq *req;
+ int buf_len;
+{
+ int rc, s;
+ caddr_t buf;
+
+ /*
+ * Open a socket for the IOCTL
+ */
+ s = socket(AF_ATM, SOCK_DGRAM, 0);
+ if (s < 0) {
+ return(-1);
+ }
+
+ /*
+ * Get memory for returned information
+ */
+mem_retry:
+ buf = (caddr_t)UM_ALLOC(buf_len);
+ if (buf == NULL) {
+ errno = ENOMEM;
+ return(-1);
+ }
+
+ /*
+ * Set the buffer address and length in the request
+ */
+ req->air_buf_addr = buf;
+ req->air_buf_len = buf_len;
+
+ /*
+ * Issue the IOCTL
+ */
+ rc = ioctl(s, AIOCINFO, (caddr_t)req);
+ if (rc) {
+ UM_FREE(buf);
+ if (errno == ENOSPC) {
+ buf_len = buf_len * 2;
+ goto mem_retry;
+ }
+ return(-1);
+ }
+ (void)close(s);
+ /*
+ * Set a pointer to the returned info in the request
+ * and return its length
+ */
+ req->air_buf_addr = buf;
+ return(req->air_buf_len);
+}
+
+
+/*
+ * Get VCC information
+ *
+ * Arguments:
+ * intf pointer to interface name (or null string)
+ * vccp pointer to a pointer to a struct air_vcc_rsp for the
+ * address of the returned VCC information
+ *
+ * Returns:
+ * int length of the retuned VCC information
+ *
+ */
+int
+get_vcc_info(intf, vccp)
+ char *intf;
+ struct air_vcc_rsp **vccp;
+{
+ int buf_len = sizeof(struct air_vcc_rsp) * 100;
+ struct atminfreq air;
+
+ /*
+ * Initialize IOCTL request
+ */
+ air.air_opcode = AIOCS_INF_VCC;
+ UM_ZERO(air.air_vcc_intf, sizeof(air.air_vcc_intf));
+ if (intf != NULL && strlen(intf) != 0)
+ strcpy(air.air_vcc_intf, intf);
+
+ buf_len = do_info_ioctl(&air, buf_len);
+
+ /*
+ * Return a pointer to the VCC info and its length
+ */
+ *vccp = (struct air_vcc_rsp *) air.air_buf_addr;
+ return(buf_len);
+}
+
+
+/*
+ * Get subnet mask
+ *
+ * Arguments:
+ * intf pointer to an interface name
+ * mask pointer to a struct sockaddr_in to receive the mask
+ *
+ * Returns:
+ * 0 good completion
+ * -1 error
+ *
+ */
+int
+get_subnet_mask(intf, mask)
+ char *intf;
+ struct sockaddr_in *mask;
+{
+ int rc, s;
+ struct ifreq req;
+ struct sockaddr_in *ip_mask;
+
+ /*
+ * Check parameters
+ */
+ if (!intf || !mask ||
+ strlen(intf) == 0 ||
+ strlen(intf) > IFNAMSIZ-1)
+ return(-1);
+
+ /*
+ * Open a socket for the IOCTL
+ */
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ return(-1);
+
+ /*
+ * Set up and issue the IOCTL
+ */
+ UM_ZERO(&req, sizeof(req));
+ strcpy(req.ifr_name, intf);
+ rc = ioctl(s, SIOCGIFNETMASK, (caddr_t)&req);
+ (void)close(s);
+ if (rc)
+ return(-1);
+
+ /*
+ * Give the answer back to the caller
+ */
+ ip_mask = (struct sockaddr_in *)&req.ifr_addr;
+ *mask = *ip_mask;
+ mask->sin_family = AF_INET;
+
+ return(0);
+}
+
+
+/*
+ * Get an interface's MTU
+ *
+ * Arguments:
+ * intf pointer to an interface name
+ * mtu pointer to an int to receive the MTU
+ *
+ * Returns:
+ * >= 0 interface MTU
+ * -1 error
+ *
+ */
+int
+get_mtu(intf)
+ char *intf;
+{
+ int rc, s;
+ struct ifreq req;
+
+ /*
+ * Check parameters
+ */
+ if (!intf || strlen(intf) == 0 ||
+ strlen(intf) > IFNAMSIZ-1)
+ return(-1);
+
+ /*
+ * Open a socket for the IOCTL
+ */
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ return(-1);
+
+ /*
+ * Set up and issue the IOCTL
+ */
+ UM_ZERO(&req, sizeof(req));
+ strcpy(req.ifr_name, intf);
+ rc = ioctl(s, SIOCGIFMTU, (caddr_t)&req);
+ (void)close(s);
+
+ /*
+ * Set the appropriate return value
+ */
+ if (rc)
+ return(-1);
+ else
+ return(req.ifr_mtu);
+}
+
+
+/*
+ * Verify netif name
+ *
+ * This routine issues an IOCTL to check whether the passed string is
+ * a valid network interface name.
+ *
+ * Arguments:
+ * req pointer to an ATM information request IOCTL structure
+ *
+ * Returns:
+ * -1 error encountered
+ * FALSE (0) the string is not a NIF name
+ * TRUE (> 0) the string is a valid NIF name
+ *
+ */
+int
+verify_nif_name(name)
+ char *name;
+{
+ int rc, s;
+ struct atminfreq air;
+ struct air_netif_rsp *nif_info;
+
+ /*
+ * Check whether name is of a valid length
+ */
+ if (strlen(name) > IFNAMSIZ - 1 ||
+ strlen(name) < 1) {
+ return(FALSE);
+ }
+
+ /*
+ * Open a socket for the IOCTL
+ */
+ s = socket(AF_ATM, SOCK_DGRAM, 0);
+ if (s < 0) {
+ return(-1);
+ }
+
+ /*
+ * Get memory for returned information
+ */
+ nif_info = (struct air_netif_rsp *)UM_ALLOC(
+ sizeof(struct air_netif_rsp));
+ if (nif_info == NULL) {
+ errno = ENOMEM;
+ return(-1);
+ }
+
+ /*
+ * Set up the request
+ */
+ air.air_opcode = AIOCS_INF_NIF;
+ air.air_buf_addr = (caddr_t)nif_info;
+ air.air_buf_len = sizeof(struct air_netif_rsp);
+ UM_ZERO(air.air_netif_intf, sizeof(air.air_netif_intf));
+ strcpy(air.air_netif_intf, name);
+
+ /*
+ * Issue the IOCTL
+ */
+ rc = ioctl(s, AIOCINFO, (caddr_t)&air);
+ UM_FREE(nif_info);
+ (void)close(s);
+
+ /*
+ * Base return value on IOCTL return code
+ */
+ if (rc)
+ return(FALSE);
+ else
+ return(TRUE);
+}
+
+/*
+ * Get Config information
+ *
+ * Arguments:
+ * intf pointer to interface name (or null string)
+ * cfgp pointer to a pointer to a struct air_cfg_rsp for the
+ * address of the returned Config information
+ *
+ * Returns:
+ * int length of returned Config information
+ *
+ */
+int
+get_cfg_info ( intf, cfgp )
+ char *intf;
+ struct air_cfg_rsp **cfgp;
+{
+ int buf_len = sizeof(struct air_cfg_rsp) * 4;
+ struct atminfreq air;
+
+ /*
+ * Initialize IOCTL request
+ */
+ air.air_opcode = AIOCS_INF_CFG;
+ UM_ZERO ( air.air_cfg_intf, sizeof(air.air_cfg_intf));
+ if ( intf != NULL && strlen(intf) != 0 )
+ strcpy ( air.air_cfg_intf, intf );
+
+ buf_len = do_info_ioctl ( &air, buf_len );
+
+ /*
+ * Return a pointer to the Config info and its length
+ */
+ *cfgp = (struct air_cfg_rsp *) air.air_buf_addr;
+ return ( buf_len );
+
+}
+
+/*
+ * Get Physical Interface information
+ *
+ * Arguments:
+ * intf pointer to interface name (or null string)
+ * intp pointer to a pointer to a struct air_cfg_rsp for the
+ * address of the returned Config information
+ *
+ * Returns:
+ * int length of returned Config information
+ *
+ */
+int
+get_intf_info ( intf, intp )
+ char *intf;
+ struct air_int_rsp **intp;
+{
+ int buf_len = sizeof(struct air_int_rsp) * 4;
+ struct atminfreq air;
+
+ /*
+ * Initialize IOCTL request
+ */
+ air.air_opcode = AIOCS_INF_INT;
+ UM_ZERO ( air.air_int_intf, sizeof(air.air_int_intf));
+ if ( intf != NULL && strlen(intf) != 0 )
+ strcpy ( air.air_int_intf, intf );
+
+ buf_len = do_info_ioctl ( &air, buf_len );
+
+ /*
+ * Return a pointer to the Physical Interface info and its length
+ */
+ *intp = (struct air_int_rsp *) air.air_buf_addr;
+ return ( buf_len );
+
+}
+
+
+/*
+ * Get Netif information
+ *
+ * Arguments:
+ * intf pointer to interface name (or null string)
+ * netp pointer to a pointer to a struct air_netif_rsp for the
+ * address of the returned Netif information
+ *
+ * Returns:
+ * int length of returned Netif information
+ *
+ */
+int
+get_netif_info ( intf, netp )
+ char *intf;
+ struct air_netif_rsp **netp;
+{
+ int buf_len = sizeof(struct air_netif_rsp) * 10;
+ struct atminfreq air;
+
+ /*
+ * Initialize IOCTL request
+ */
+ air.air_opcode = AIOCS_INF_NIF;
+ UM_ZERO ( air.air_int_intf, sizeof(air.air_int_intf) );
+ if ( intf != NULL && strlen(intf) != 0 )
+ strcpy ( air.air_int_intf, intf );
+
+ buf_len = do_info_ioctl ( &air, buf_len );
+
+ /*
+ * Return a pointer to the Netif info and its length
+ */
+ *netp = (struct air_netif_rsp *) air.air_buf_addr;
+ return ( buf_len );
+
+}
+
+
diff --git a/lib/libatm/ip_addr.c b/lib/libatm/ip_addr.c
new file mode 100644
index 0000000..81b9c77
--- /dev/null
+++ b/lib/libatm/ip_addr.c
@@ -0,0 +1,168 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $FreeBSD$
+ *
+ */
+
+/*
+ * User Space Library Functions
+ * ----------------------------
+ *
+ * IP address utilities
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netatm/port.h>
+#include <netatm/atm.h>
+#include <netatm/atm_if.h>
+#include <netatm/atm_sap.h>
+#include <netatm/atm_sys.h>
+#include <netatm/atm_ioctl.h>
+
+#include <netdb.h>
+#include <string.h>
+
+#include "libatm.h"
+
+#ifndef lint
+__RCSID("@(#) $FreeBSD$");
+#endif
+
+
+/*
+ * Get IP address
+ *
+ * Return an IP address in a socket address structure, given a character
+ * string with a domain name or a dotted decimal number.
+ *
+ * Arguments:
+ * p pointer to a host name or IP address
+ *
+ * Returns:
+ * null error was encountered
+ * struct sockaddr_in * a pointer to a socket address with the
+ * requested IP address
+ *
+ */
+struct sockaddr_in *
+get_ip_addr(p)
+ char *p;
+{
+ struct hostent *ip_host;
+ static struct sockaddr_in sin;
+
+ /*
+ * Get IP address of specified host name
+ */
+ UM_ZERO(&sin, sizeof(sin));
+ sin.sin_family = AF_INET;
+ if (p[0] >= '0' && p[0] <= '9') {
+ /*
+ * IP address is in dotted decimal format
+ */
+ if ((sin.sin_addr.s_addr = inet_addr(p)) == -1) {
+ return((struct sockaddr_in *)0);
+ }
+ } else {
+ /*
+ * Host name is in domain name system format
+ */
+ ip_host = gethostbyname(p);
+ if (!ip_host ||
+ ip_host->h_addrtype != AF_INET) {
+ return((struct sockaddr_in *)0);
+ }
+ sin.sin_addr.s_addr = *(u_long *)ip_host->h_addr_list[0];
+ }
+ return(&sin);
+}
+
+
+/*
+ * Format an IP address
+ *
+ * Return a text-formatted string with an IP address and domain name
+ * given a sockaddr_in with an IP address.
+ *
+ * Arguments:
+ * p pointer to sockaddr_in with an IP address
+ *
+ * Returns:
+ * char * pointer to a text-formatted string
+ *
+ */
+char *
+format_ip_addr(addr)
+ struct in_addr *addr;
+{
+ static char host_name[128];
+ char *ip_num;
+ struct hostent *ip_host;
+
+ /*
+ * Initialize
+ */
+ UM_ZERO(host_name, sizeof(host_name));
+
+ /*
+ * Check for a zero address
+ */
+ if (!addr || addr->s_addr == 0) {
+ return("-");
+ }
+
+ /*
+ * Get address in dotted decimal format
+ */
+ ip_num = inet_ntoa(*addr);
+
+ /*
+ * Look up name in DNS
+ */
+ ip_host = gethostbyaddr((char *)addr, sizeof(addr), AF_INET);
+ if (ip_host && ip_host->h_name &&
+ strlen(ip_host->h_name)) {
+ /*
+ * Return host name followed by dotted decimal address
+ */
+ strcpy(host_name, ip_host->h_name);
+ strcat(host_name, " (");
+ strcat(host_name, ip_num);
+ strcat(host_name, ")");
+ return(host_name);
+ } else {
+ /*
+ * No host name -- just return dotted decimal address
+ */
+ return(ip_num);
+ }
+}
diff --git a/lib/libatm/ip_checksum.c b/lib/libatm/ip_checksum.c
new file mode 100644
index 0000000..b9c7fa8
--- /dev/null
+++ b/lib/libatm/ip_checksum.c
@@ -0,0 +1,100 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $FreeBSD$
+ *
+ */
+
+
+/*
+ * User Space Library Functions
+ * ----------------------------
+ *
+ * IP checksum computation
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netatm/port.h>
+#include <netatm/atm.h>
+#include <netatm/atm_if.h>
+#include <netatm/atm_sap.h>
+#include <netatm/atm_sys.h>
+#include <netatm/atm_ioctl.h>
+
+#include "libatm.h"
+
+#ifndef lint
+__RCSID("@(#) $FreeBSD$");
+#endif
+
+
+/*
+ * Compute an IP checksum
+ *
+ * This code was taken from RFC 1071.
+ *
+ * "The following "C" code algorithm computes the checksum with an inner
+ * loop that sums 16 bits at a time in a 32-bit accumulator."
+ *
+ * Arguments:
+ * addr pointer to the buffer whose checksum is to be computed
+ * count number of bytes to include in the checksum
+ *
+ * Returns:
+ * the computed checksum
+ *
+ */
+short
+ip_checksum(addr, count)
+ char *addr;
+ int count;
+{
+ /* Compute Internet Checksum for "count" bytes
+ * beginning at location "addr".
+ */
+ register long sum = 0;
+
+ while( count > 1 ) {
+ /* This is the inner loop */
+ sum += ntohs(* (unsigned short *) addr);
+ addr += sizeof(unsigned short);
+ count -= sizeof(unsigned short);
+ }
+
+ /* Add left-over byte, if any */
+ if( count > 0 )
+ sum += * (unsigned char *) addr;
+
+ /* Fold 32-bit sum to 16 bits */
+ while (sum>>16)
+ sum = (sum & 0xffff) + (sum >> 16);
+
+ return((short)~sum);
+}
diff --git a/lib/libatm/libatm.h b/lib/libatm/libatm.h
new file mode 100644
index 0000000..836b19e
--- /dev/null
+++ b/lib/libatm/libatm.h
@@ -0,0 +1,119 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $FreeBSD$
+ *
+ */
+
+/*
+ * User Space Library Functions
+ * ----------------------------
+ *
+ * Library functions
+ *
+ */
+
+#ifndef _HARP_LIBHARP_H
+#define _HARP_LIBHARP_H
+
+/*
+ * Start a HARP user-space timer
+ *
+ * tp pointer to timer control block
+ * time number of seconds for timer to run
+ * fp pointer to function to call at expiration
+ */
+#define HARP_TIMER(tp, time, fp) \
+{ \
+ (tp)->ht_ticks = (time); \
+ (tp)->ht_mark = 0; \
+ (tp)->ht_func = (fp); \
+ LINK2HEAD((tp), Harp_timer, harp_timer_head, ht_next); \
+}
+
+/*
+ * Cancel a HARP user-space timer
+ *
+ * tp pointer to timer control block
+ */
+#define HARP_CANCEL(tp) \
+{ \
+ UNLINK((tp), Harp_timer, harp_timer_head, ht_next); \
+}
+
+
+/*
+ * HARP user-space timer control block
+ */
+struct harp_timer {
+ struct harp_timer *ht_next; /* Timer chain */
+ int ht_ticks; /* Seconds till exp */
+ int ht_mark; /* Processing flag */
+ void (*ht_func)(); /* Function to call */
+};
+typedef struct harp_timer Harp_timer;
+
+
+/*
+ * Externally-visible variables and functions
+ */
+
+/* atm_addr.c */
+extern int get_hex_atm_addr __P((char *, u_char *, int));
+extern char *format_atm_addr __P((Atm_addr *));
+
+/* cache_key.c */
+extern void scsp_cache_key __P((Atm_addr *,
+ struct in_addr *, int, char *));
+
+/* ioctl_subr.c */
+extern int do_info_ioctl __P((struct atminfreq *, int));
+extern int get_vcc_info __P((char *,
+ struct air_vcc_rsp **));
+extern int get_subnet_mask __P((char *,
+ struct sockaddr_in *));
+extern int get_mtu __P((char *));
+extern int verify_nif_name __P((char *));
+extern int get_cfg_info __P((char *, struct air_cfg_rsp **));
+extern int get_intf_info __P((char *, struct air_int_rsp **));
+extern int get_netif_info __P((char *, struct air_netif_rsp **));
+
+/* ip_addr.c */
+extern struct sockaddr_in *get_ip_addr __P((char *));
+extern char *format_ip_addr __P((struct in_addr *));
+
+/* ip_checksum.c */
+extern short ip_checksum __P((char *, int));
+
+/* timer.c */
+extern Harp_timer *harp_timer_head;
+extern int harp_timer_exec;
+extern void timer_proc __P(());
+extern int init_timer __P(());
+extern int block_timer __P(());
+extern void enable_timer __P((int));
+
+
+#endif /* _HARP_LIBHARP_H */
diff --git a/lib/libatm/timer.c b/lib/libatm/timer.c
new file mode 100644
index 0000000..e482840
--- /dev/null
+++ b/lib/libatm/timer.c
@@ -0,0 +1,263 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $FreeBSD$
+ *
+ */
+
+/*
+ * User Space Library Functions
+ * ----------------------------
+ *
+ * Timer functions
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netatm/port.h>
+#include <netatm/queue.h>
+#include <netatm/atm.h>
+#include <netatm/atm_if.h>
+#include <netatm/atm_sap.h>
+#include <netatm/atm_sys.h>
+#include <netatm/atm_ioctl.h>
+
+#include <errno.h>
+#include <signal.h>
+
+#include "libatm.h"
+
+#ifndef lint
+__RCSID("@(#) $FreeBSD$");
+#endif
+
+
+Harp_timer *harp_timer_head;
+int harp_timer_exec;
+
+
+/*
+ * Process a HARP timer tick
+ *
+ * This function is called via the SIGALRM signal. It increments
+ * harp_timer_exec. The user should check this flag frequently and
+ * call timer_proc when it is set.
+ *
+ * Arguments:
+ * None
+ *
+ * Returns:
+ * None
+ *
+ */
+static void
+timer_tick()
+{
+ /*
+ * Bump the timer flag
+ */
+ harp_timer_exec++;
+}
+
+
+/*
+ * Process HARP timers
+ *
+ * This function is called after a SIGALRM signal is posted. It runs
+ * down the list of timer entries, calling the specified functions
+ * for any timers that have expired.
+ *
+ * Arguments:
+ * None
+ *
+ * Returns:
+ * None
+ *
+ */
+void
+timer_proc()
+{
+ Harp_timer *htp;
+ void (*f)();
+
+ /*
+ * Reset marks in all timers on the queue
+ */
+ for (htp = harp_timer_head; htp; htp = htp->ht_next) {
+ htp->ht_mark = -1;
+ }
+
+ /*
+ * Run through timer chain decrementing each timer.
+ * If an expired timer is found, take the timer block
+ * off the chain and call the specified function. A
+ * timer's action can result in other timers being
+ * cancelled (taken off the queue), so every time we
+ * call a user function, we start over from the top of
+ * the list.
+ */
+timer_cont:
+ for (htp = harp_timer_head; htp; htp = htp->ht_next) {
+ /*
+ * Make sure we only process each entry once and
+ * don't process entries that are put on the queue
+ * by user functions we call for this tick
+ */
+ if (htp->ht_mark == -1) {
+ /*
+ * Decrement the timer and mark that we've
+ * processed the entry
+ */
+ htp->ht_ticks -= harp_timer_exec;
+ htp->ht_mark = 1;
+
+ /*
+ * Check whether the timer is expired
+ */
+ if (htp->ht_ticks <= 0) {
+ /*
+ * Unlink the timer block and call
+ * the user function
+ */
+ f = htp->ht_func;
+ UNLINK(htp, Harp_timer, harp_timer_head,
+ ht_next);
+ f(htp);
+
+ /*
+ * Start over
+ */
+ goto timer_cont;
+ }
+ }
+ }
+
+ /*
+ * Reset the timer exec flag
+ */
+ harp_timer_exec = 0;
+}
+
+
+/*
+ * Start the timer
+ *
+ * Set up the SIGALRM signal handler and set up the real-time
+ * timer to tick once per second.
+ *
+ * Arguments:
+ * None
+ *
+ * Returns:
+ * 0 success
+ * errno reason for failure
+ *
+ */
+int
+init_timer()
+{
+ int rc = 0;
+ struct itimerval timeval;
+
+ /*
+ * Clear the timer flag
+ */
+ harp_timer_exec = 0;
+
+ /*
+ * Set up signal handler
+ */
+ if ((int)signal(SIGALRM, timer_tick) == -1) {
+ return(errno);
+ }
+
+ /*
+ * Start timer
+ */
+ timeval.it_value.tv_sec = 1;
+ timeval.it_value.tv_usec = 0;
+ timeval.it_interval.tv_sec = 1;
+ timeval.it_interval.tv_usec = 0;
+
+ if (setitimer(ITIMER_REAL, &timeval,
+ (struct itimerval *)0) == -1) {
+ rc = errno;
+ (void)signal(SIGALRM, SIG_DFL);
+ }
+
+ return(rc);
+}
+
+
+/*
+ * Block timers from firing
+ *
+ * Block the SIGALRM signal.
+ *
+ * Arguments:
+ * None
+ *
+ * Returns:
+ * mask the previous blocked signal mask
+ *
+ */
+int
+block_timer()
+{
+ /*
+ * Block the SIGALRM signal
+ */
+ return(sigblock(sigmask(SIGALRM)));
+}
+
+
+/*
+ * Re-enable timers
+ *
+ * Restore the signal mask (presumably one that was returned by
+ * block_timer).
+ *
+ * Arguments:
+ * mask the signal mask to be restored
+ *
+ * Returns:
+ * mask the previous blocked signal mask
+ *
+ */
+void
+enable_timer(mask)
+ int mask;
+{
+ /*
+ * Set the signal mask
+ */
+ sigsetmask(mask);
+
+ return;
+}
diff --git a/lib/libbind/Makefile b/lib/libbind/Makefile
new file mode 100644
index 0000000..ba6da8a7
--- /dev/null
+++ b/lib/libbind/Makefile
@@ -0,0 +1,88 @@
+# $FreeBSD$
+
+BIND_DIR=${.CURDIR}/../../contrib/bind
+
+# contrib/bind/include/* must not override any real system includes
+CFLAGS+= -I${BIND_DIR}/port/freebsd/include -I${BIND_DIR}/include
+
+LIB= bind
+WANT_IRS= for now
+
+# This may or may not work yet. It's not compatable with the core
+# system components since it overrides the master.passwd handling etc.
+.if defined(WANT_IRS)
+.PATH: ${BIND_DIR}/lib/irs
+SRCS+= dns.c dns_gr.c dns_ho.c dns_nw.c dns_pr.c dns_pw.c \
+ dns_sv.c gai_strerror.c gen.c gen_gr.c gen_ho.c \
+ gen_ng.c gen_nw.c gen_pr.c gen_pw.c gen_sv.c \
+ getaddrinfo.c getgrent.c getgrent_r.c gethostent.c \
+ gethostent_r.c getnameinfo.c getnetent.c getnetent_r.c \
+ getnetgrent.c getnetgrent_r.c getprotoent.c \
+ getprotoent_r.c getpwent.c getpwent_r.c getservent.c \
+ getservent_r.c hesiod.c irs_data.c \
+ irp.c irp_gr.c irp_ho.c irp_ng.c irp_nw.c \
+ irp_pr.c irp_pw.c irp_sv.c irpmarshall.c \
+ lcl.c lcl_gr.c \
+ lcl_ho.c lcl_ng.c lcl_nw.c lcl_pr.c lcl_pw.c \
+ lcl_sv.c nis.c nis_gr.c nis_ho.c nis_ng.c nis_nw.c \
+ nis_pr.c nis_pw.c nis_sv.c nul_ng.c util.c
+
+.PATH: ${BIND_DIR}/lib/nameser
+SRCS+= ns_parse.c ns_print.c ns_netint.c ns_ttl.c ns_name.c \
+ ns_sign.c ns_verify.c ns_date.c ns_samedomain.c
+
+.PATH: ${BIND_DIR}/lib/resolv
+SRCS+= herror.c res_debug.c res_data.c res_comp.c res_init.c \
+ res_mkquery.c res_query.c res_send.c res_sendsigned.c \
+ res_mkupdate.c res_update.c res_findzonecut.c
+.endif
+
+.if defined(WANT_CYLINK) && exists(${BIND_DIR}/lib/cylink)
+.PATH: ${BIND_DIR}/lib/cylink
+CFLAGS+=-DCYLINK_DSS -I${BIND_DIR}/lib/cylink
+SRCS+= bn.c bn00.c lbn00.c lbnmem.c legal.c \
+ bits.c dss.c math.c ctk_prime.c rand.c sha.c swap.c
+.endif
+
+.if defined(WANT_DNSSAFE) && exists(${BIND_DIR}/lib/dnssafe)
+.PATH: ${BIND_DIR}/lib/dnssafe
+CFLAGS+=-DDNSSAFE -I${BIND_DIR}/lib/dnssafe
+SRCS+= bgclrbit.c bgmdmpyx.c bgmdsqx.c bgmodexp.c \
+ bgpegcd.c big2exp.c bigabs.c bigacc.c bigarith.c \
+ bigcmp.c bigconst.c biginv.c biglen.c bigmodx.c \
+ bigmpy.c bigpdiv.c bigpmpy.c bigpmpyh.c bigpmpyl.c \
+ bigpsq.c bigqrx.c bigsmod.c bigtocan.c bigu.c \
+ bigunexp.c cantobig.c crt2.c \
+ digrand.c intbits.c md5.c md5rand.c prime.c \
+ rsa.c rsakeygn.c seccbcd.c seccbce.c surrendr.c \
+ ahchdig.c ahchencr.c ahchgen.c ahchrand.c ahdigest.c \
+ ahencryp.c ahgen.c ahrandom.c ahrsaenc.c ahrsaepr.c \
+ ahrsaepu.c aichdig.c aichenc8.c aichencn.c aichencr.c \
+ aichgen.c aichrand.c aimd5.c \
+ aimd5ran.c ainfotyp.c ainull.c airsaepr.c airsaepu.c \
+ airsakgn.c airsaprv.c airsapub.c algchoic.c algobj.c \
+ amcrte.c ammd5.c ammd5r.c \
+ amrkg.c amrsae.c balg.c binfocsh.c bkey.c bmempool.c \
+ digest.c encrypt.c generate.c intitem.c \
+ keyobj.c ki8byte.c kiitem.c kinfotyp.c \
+ kifulprv.c kipkcrpr.c kirsacrt.c kirsapub.c random.c
+.endif
+
+.PATH: ${BIND_DIR}/lib/dst
+CFLAGS+=-DHMAC_MD5 -DUSE_MD5
+SRCS+= dst_api.c prandom.c rsaref_link.c support.c bsafe_link.c \
+ cylink_link.c hmac_link.c md5_dgst.c eay_dss_link.c
+
+.PATH: ${BIND_DIR}/lib/isc
+SRCS+= tree.c bitncmp.c assertions.c \
+ memcluster.c logging.c heap.c \
+ ctl_p.c ctl_srvr.c ctl_clnt.c \
+ eventlib.c ev_connects.c ev_files.c \
+ ev_timers.c ev_streams.c ev_waits.c
+# base64.c
+
+INTERNALLIB= true
+NOPIC= true
+INTERNALSTATICLIB= true
+
+.include <bsd.lib.mk>
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
new file mode 100644
index 0000000..8a2afa8
--- /dev/null
+++ b/lib/libc/Makefile
@@ -0,0 +1,44 @@
+# @(#)Makefile 8.2 (Berkeley) 2/3/94
+# $FreeBSD$
+#
+# All library objects contain rcsid strings by default; they may be
+# excluded as a space-saving measure. To produce a library that does
+# not contain these strings, delete -DLIBC_RCS and -DSYSLIBC_RCS
+# from CFLAGS below. To remove these strings from just the system call
+# stubs, remove just -DSYSLIBC_RCS from CFLAGS.
+LIB=c
+SHLIB_MAJOR= 4
+SHLIB_MINOR= 0
+CFLAGS+=-DLIBC_RCS -DSYSLIBC_RCS -I${.CURDIR}/include
+AINC= -I${.CURDIR}/${MACHINE_ARCH}
+CLEANFILES+=tags
+INSTALL_PIC_ARCHIVE= yes
+PRECIOUSLIB= yes
+
+#
+# Don't bother hiding any syscalls (like libc_r does).
+#
+HIDDEN_SYSCALLS=
+
+#
+# Include make rules that are shared with libc_r.
+#
+.include "${.CURDIR}/Makefile.inc"
+
+KQSRCS= adddi3.c anddi3.c ashldi3.c ashrdi3.c cmpdi2.c divdi3.c iordi3.c \
+ lshldi3.c lshrdi3.c moddi3.c muldi3.c negdi2.c notdi2.c qdivrem.c \
+ subdi3.c ucmpdi2.c udivdi3.c umoddi3.c xordi3.c
+KSRCS= bcmp.c ffs.c index.c mcount.c rindex.c strcat.c strcmp.c strcpy.c \
+ strlen.c strncpy.c
+
+libkern: libkern.gen libkern.${MACHINE_ARCH}
+
+libkern.gen: ${KQSRCS} ${KSRCS}
+ cp -p ${.CURDIR}/quad/quad.h ${.ALLSRC} ${DESTDIR}/sys/libkern
+
+libkern.${MACHINE_ARCH}:: ${KMSRCS}
+.if defined(KMSRCS) && !empty(KMSRCS)
+ cp -p ${.ALLSRC} ${DESTDIR}/sys/libkern/${MACHINE_ARCH}
+.endif
+
+.include <bsd.lib.mk>
diff --git a/lib/libc/Makefile.inc b/lib/libc/Makefile.inc
new file mode 100644
index 0000000..318ca70
--- /dev/null
+++ b/lib/libc/Makefile.inc
@@ -0,0 +1,56 @@
+# $FreeBSD$
+#
+# This file contains make rules that are shared by libc and libc_r.
+#
+# Define (empty) variables so that make doesn't give substitution
+# errors if the included makefiles don't change these:
+MDSRCS=
+MISRCS=
+MDASM=
+MIASM=
+NOASM=
+
+#
+# If there is a machine dependent makefile, use it:
+#
+.if exists(${.CURDIR}/../libc/${MACHINE_ARCH}/Makefile.inc)
+.include "${.CURDIR}/../libc/${MACHINE_ARCH}/Makefile.inc"
+.endif
+
+.include "${.CURDIR}/../libc/db/Makefile.inc"
+.include "${.CURDIR}/../libc/compat-43/Makefile.inc"
+.include "${.CURDIR}/../libc/gen/Makefile.inc"
+.include "${.CURDIR}/../libc/gmon/Makefile.inc"
+.include "${.CURDIR}/../libc/locale/Makefile.inc"
+.include "${.CURDIR}/../libc/net/Makefile.inc"
+.include "${.CURDIR}/../libc/nls/Makefile.inc"
+.if !defined(NO_QUAD)
+.include "${.CURDIR}/../libc/quad/Makefile.inc"
+.endif
+.include "${.CURDIR}/../libc/regex/Makefile.inc"
+.include "${.CURDIR}/../libc/stdio/Makefile.inc"
+.include "${.CURDIR}/../libc/stdlib/Makefile.inc"
+.include "${.CURDIR}/../libc/stdtime/Makefile.inc"
+.include "${.CURDIR}/../libc/string/Makefile.inc"
+.include "${.CURDIR}/../libc/sys/Makefile.inc"
+.include "${.CURDIR}/../libc/rpc/Makefile.inc"
+.include "${.CURDIR}/../libc/xdr/Makefile.inc"
+.if !defined(NO_YP_LIBC)
+CFLAGS+= -DYP
+.include "${.CURDIR}/../libc/yp/Makefile.inc"
+.endif
+
+# If there are no machine dependent sources, append all the
+# machine-independent sources:
+.if empty(MDSRCS)
+SRCS+= ${MISRCS}
+.else
+# Append machine-dependent sources, then append machine-independent sources
+# for which there is no machine-dependent variant.
+SRCS+= ${MDSRCS}
+.for _src in ${MISRCS}
+.if ${MDSRCS:R:M${_src:R}} == ""
+SRCS+= ${_src}
+.endif
+.endfor
+.endif
diff --git a/lib/libc/alpha/Makefile.inc b/lib/libc/alpha/Makefile.inc
new file mode 100644
index 0000000..5a4d48e
--- /dev/null
+++ b/lib/libc/alpha/Makefile.inc
@@ -0,0 +1,9 @@
+# $FreeBSD$
+#
+# Machine dependent definitions for the alpha architecture.
+#
+
+#
+# Alpha is 64-bit, so it doesn't need quad functions:
+#
+NO_QUAD=1
diff --git a/lib/libc/alpha/SYS.h b/lib/libc/alpha/SYS.h
new file mode 100644
index 0000000..6e0d522
--- /dev/null
+++ b/lib/libc/alpha/SYS.h
@@ -0,0 +1,130 @@
+/* $FreeBSD$ */
+/* From: NetBSD: SYS.h,v 1.5 1997/05/02 18:15:15 kleink Exp */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+#ifdef __NETBSD_SYSCALLS
+#include <sys/netbsd_syscall.h>
+#else
+#include <sys/syscall.h>
+#endif
+
+#define CALLSYS_ERROR(name) \
+ CALLSYS_NOERROR(name); \
+ br gp, LLABEL(name,0); \
+LLABEL(name,0): \
+ LDGP(gp); \
+ beq a3, LLABEL(name,1); \
+ jmp zero, .cerror; \
+LLABEL(name,1):
+
+
+#define SYSCALL(name) \
+LEAF(name,0); /* XXX # of args? */ \
+ CALLSYS_ERROR(name)
+
+#define SYSCALL_NOERROR(name) \
+LEAF(name,0); /* XXX # of args? */ \
+ CALLSYS_NOERROR(name)
+
+
+#define RSYSCALL(name) \
+ SYSCALL(name); \
+ RET; \
+END(name)
+
+#define RSYSCALL_NOERROR(name) \
+ SYSCALL_NOERROR(name); \
+ RET; \
+END(name)
+
+
+#define PSEUDO(label,name) \
+LEAF(label,0); /* XXX # of args? */ \
+ CALLSYS_ERROR(name); \
+ RET; \
+END(label);
+
+#define PSEUDO_NOERROR(label,name) \
+LEAF(label,0); /* XXX # of args? */ \
+ CALLSYS_NOERROR(name); \
+ RET; \
+END(label);
+
+/*
+ * Design note:
+ *
+ * The macros PSYSCALL() and PRSYSCALL() are intended for use where a
+ * syscall needs to be renamed in the threaded library. When building
+ * a normal library, they default to the traditional SYSCALL() and
+ * RSYSCALL(). This avoids the need to #ifdef _THREAD_SAFE everywhere
+ * that the renamed function needs to be called.
+ */
+#ifdef _THREAD_SAFE
+/*
+ * For the thread_safe versions, we prepend _thread_sys_ to the function
+ * name so that the 'C' wrapper can go around the real name.
+ */
+#define PCALL(name) \
+ CALL(___CONCAT(_thread_sys_,name))
+
+#define PLEAF(name, args) \
+LEAF(___CONCAT(_thread_sys_,name),args)
+
+#define PEND(name) \
+END(___CONCAT(_thread_sys_,name))
+
+#define PSYSCALL(name) \
+PLEAF(name,0); /* XXX # of args? */ \
+ CALLSYS_ERROR(name)
+
+#define PRSYSCALL(name) \
+PLEAF(name,0); /* XXX # of args? */ \
+ CALLSYS_ERROR(name) \
+ RET; \
+PEND(name)
+
+#define PPSEUDO(label,name) \
+PLEAF(label,0); /* XXX # of args? */ \
+ CALLSYS_ERROR(name); \
+ RET; \
+PEND(label)
+
+#else
+/*
+ * The non-threaded library defaults to traditional syscalls where
+ * the function name matches the syscall name.
+ */
+#define PSYSCALL(x) SYSCALL(x)
+#define PRSYSCALL(x) RSYSCALL(x)
+#define PPSEUDO(x,y) PSEUDO(x,y)
+#define PLEAF(x,y) LEAF(x,y)
+#define PEND(x) END(x)
+#define PCALL(x) CALL(x)
+#endif
diff --git a/lib/libc/alpha/gen/Makefile.inc b/lib/libc/alpha/gen/Makefile.inc
new file mode 100644
index 0000000..4e7fb35
--- /dev/null
+++ b/lib/libc/alpha/gen/Makefile.inc
@@ -0,0 +1,45 @@
+# $FreeBSD$
+
+SRCS+= _setjmp.S fabs.S frexp.c infinity.c isinf.c ldexp.c modf.c setjmp.S
+SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
+ fpsetround.c fpsetsticky.c
+
+SRCS+= sigsetjmp.S
+SRCS+= __divqu.S __divq.S __divlu.S __divl.S
+SRCS+= __remqu.S __remq.S __remlu.S __reml.S
+
+CLEANFILES+= __divqu.S __divq.S __divlu.S __divl.S
+CLEANFILES+= __remqu.S __remq.S __remlu.S __reml.S
+
+
+__divqu.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__divqu -DOP=div -DS=false -DWORDSIZE=64 \
+ ${.ALLSRC} > ${.TARGET}
+
+__divq.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__divq -DOP=div -DS=true -DWORDSIZE=64 \
+ ${.ALLSRC} > ${.TARGET}
+
+__divlu.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__divlu -DOP=div -DS=false -DWORDSIZE=32 \
+ ${.ALLSRC} > ${.TARGET}
+
+__divl.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__divl -DOP=div -DS=true -DWORDSIZE=32 \
+ ${.ALLSRC} > ${.TARGET}
+
+__remqu.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__remqu -DOP=rem -DS=false -DWORDSIZE=64 \
+ ${.ALLSRC} > ${.TARGET}
+
+__remq.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__remq -DOP=rem -DS=true -DWORDSIZE=64 \
+ ${.ALLSRC} > ${.TARGET}
+
+__remlu.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__remlu -DOP=rem -DS=false -DWORDSIZE=32 \
+ ${.ALLSRC} > ${.TARGET}
+
+__reml.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__reml -DOP=rem -DS=true -DWORDSIZE=32 \
+ ${.ALLSRC} > ${.TARGET}
diff --git a/lib/libc/alpha/gen/_setjmp.S b/lib/libc/alpha/gen/_setjmp.S
new file mode 100644
index 0000000..2aa8c55
--- /dev/null
+++ b/lib/libc/alpha/gen/_setjmp.S
@@ -0,0 +1,123 @@
+/* $NetBSD: _setjmp.S,v 1.2 1996/10/17 03:08:03 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ * _longjmp(a,v)
+ * will generate a "return(v)" from
+ * the last call to
+ * _setjmp(a)
+ * by restoring registers from the stack,
+ * The previous signal state is NOT restored.
+ */
+
+ .set noreorder
+
+LEAF(_setjmp, 1)
+ LDGP(pv)
+ stq ra, (2 * 8)(a0) /* sc_pc = return address */
+ stq s0, (( 9 + 4) * 8)(a0) /* saved bits of sc_regs */
+ stq s1, ((10 + 4) * 8)(a0)
+ stq s2, ((11 + 4) * 8)(a0)
+ stq s3, ((12 + 4) * 8)(a0)
+ stq s4, ((13 + 4) * 8)(a0)
+ stq s5, ((14 + 4) * 8)(a0)
+ stq s6, ((15 + 4) * 8)(a0)
+ stq ra, ((26 + 4) * 8)(a0)
+ stq sp, ((30 + 4) * 8)(a0)
+ ldiq t0, 0xacedbadd /* sigcontext magic number */
+ stq t0, ((31 + 4) * 8)(a0) /* magic in sc_regs[31] */
+ /* Too bad we can't check if we actually used FP */
+ ldiq t0, 1
+ stq t0, (36 * 8)(a0) /* say we've used FP. */
+ stt fs0, ((2 + 37) * 8)(a0) /* saved bits of sc_fpregs */
+ stt fs1, ((3 + 37) * 8)(a0)
+ stt fs2, ((4 + 37) * 8)(a0)
+ stt fs3, ((5 + 37) * 8)(a0)
+ stt fs4, ((6 + 37) * 8)(a0)
+ stt fs5, ((7 + 37) * 8)(a0)
+ stt fs6, ((8 + 37) * 8)(a0)
+ stt fs7, ((9 + 37) * 8)(a0)
+ mf_fpcr ft0 /* get FP control reg */
+ stt ft0, (69 * 8)(a0) /* and store it in sc_fpcr */
+ stq zero, (70 * 8)(a0) /* FP software control XXX */
+ stq zero, (71 * 8)(a0) /* sc_reserved[0] */
+ stq zero, (72 * 8)(a0) /* sc_reserved[1] */
+ stq zero, (73 * 8)(a0) /* sc_xxx[0] */
+ stq zero, (74 * 8)(a0) /* sc_xxx[1] */
+ stq zero, (75 * 8)(a0) /* sc_xxx[2] */
+ stq zero, (76 * 8)(a0) /* sc_xxx[3] */
+ stq zero, (77 * 8)(a0) /* sc_xxx[4] */
+ stq zero, (78 * 8)(a0) /* sc_xxx[5] */
+ stq zero, (79 * 8)(a0) /* sc_xxx[6] */
+ stq zero, (80 * 8)(a0) /* sc_xxx[7] */
+
+ mov zero, v0 /* return zero */
+ RET
+END(_setjmp)
+
+LEAF(_longjmp, 2)
+ LDGP(pv)
+ ldq t0, ((31 + 4) * 8)(a0) /* magic in sc_regs[31] */
+ ldiq t1, 0xacedbadd
+ cmpeq t0, t1, t0
+ beq t0, botch /* If the magic was bad, punt */
+
+ ldq ra, (2 * 8)(a0) /* sc_pc = return address */
+ ldq s0, (( 9 + 4) * 8)(a0) /* saved bits of sc_regs */
+ ldq s1, ((10 + 4) * 8)(a0)
+ ldq s2, ((11 + 4) * 8)(a0)
+ ldq s3, ((12 + 4) * 8)(a0)
+ ldq s4, ((13 + 4) * 8)(a0)
+ ldq s5, ((14 + 4) * 8)(a0)
+ ldq s6, ((15 + 4) * 8)(a0)
+ /* ldq ra, ((26 + 4) * 8)(a0) set above */
+ ldq sp, ((30 + 4) * 8)(a0)
+ ldt fs0, ((2 + 37) * 8)(a0) /* saved bits of sc_fpregs */
+ ldt fs1, ((3 + 37) * 8)(a0)
+ ldt fs2, ((4 + 37) * 8)(a0)
+ ldt fs3, ((5 + 37) * 8)(a0)
+ ldt fs4, ((6 + 37) * 8)(a0)
+ ldt fs5, ((7 + 37) * 8)(a0)
+ ldt fs6, ((8 + 37) * 8)(a0)
+ ldt fs7, ((9 + 37) * 8)(a0)
+ ldt ft0, (69 * 8)(a0) /* get sc_fpcr */
+ mt_fpcr ft0 /* and restore it. */
+
+ mov a1, v0 /* return second arg */
+ RET
+
+botch:
+ CALL(longjmperror)
+ CALL(abort)
+ RET /* "can't" get here... */
+END(_longjmp)
diff --git a/lib/libc/alpha/gen/divrem.m4 b/lib/libc/alpha/gen/divrem.m4
new file mode 100644
index 0000000..9fab00a
--- /dev/null
+++ b/lib/libc/alpha/gen/divrem.m4
@@ -0,0 +1,197 @@
+/* $NetBSD: divrem.m4,v 1.7 1996/10/17 03:08:04 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * Division and remainder.
+ *
+ * The use of m4 is modeled after the sparc code, but the algorithm is
+ * simple binary long division.
+ *
+ * Note that the loops could probably benefit from unrolling.
+ */
+
+/*
+ * M4 Parameters
+ * NAME name of function to generate
+ * OP OP=div: t10 / t11 -> t12; OP=rem: t10 % t11 -> t12
+ * S S=true: signed; S=false: unsigned
+ * WORDSIZE total number of bits
+ */
+
+define(A, `t10')
+define(B, `t11')
+define(RESULT, `t12')
+
+define(BIT, `t0')
+define(I, `t1')
+define(CC, `t2')
+define(T_0, `t3')
+ifelse(S, `true', `define(NEG, `t4')')
+
+#include <machine/asm.h>
+
+NESTED(NAME, 0, 0, t9, 0, 0) /* Get the right ra */
+ lda sp, -64(sp)
+ stq BIT, 0(sp)
+ stq I, 8(sp)
+ stq CC, 16(sp)
+ stq T_0, 24(sp)
+ifelse(S, `true',
+` stq NEG, 32(sp)')
+ stq A, 40(sp)
+ stq B, 48(sp)
+ mov zero, RESULT /* Initialize result to zero */
+
+ifelse(S, `true',
+`
+ /* Compute sign of result. If either is negative, this is easy. */
+ or A, B, NEG /* not the sign, but... */
+ srl NEG, WORDSIZE - 1, NEG /* rather, or of high bits */
+ blbc NEG, Ldoit /* neither negative? do it! */
+
+ifelse(OP, `div',
+` xor A, B, NEG /* THIS is the sign! */
+', ` mov A, NEG /* sign follows A. */
+')
+ srl NEG, WORDSIZE - 1, NEG /* make negation the low bit. */
+
+ srl A, WORDSIZE - 1, I /* is A negative? */
+ blbc I, LnegB /* no. */
+ /* A is negative; flip it. */
+ifelse(WORDSIZE, `32', `
+ /* top 32 bits may be random junk */
+ zap A, 0xf0, A
+')
+ subq zero, A, A
+ srl B, WORDSIZE - 1, I /* is B negative? */
+ blbc I, Ldoit /* no. */
+LnegB:
+ /* B is definitely negative, no matter how we got here. */
+ifelse(WORDSIZE, `32', `
+ /* top 32 bits may be random junk */
+ zap B, 0xf0, B
+')
+ subq zero, B, B
+Ldoit:
+')
+ifelse(WORDSIZE, `32', `
+ /*
+ * Clear the top 32 bits of each operand, as they may
+ * sign extension (if negated above), or random junk.
+ */
+ zap A, 0xf0, A
+ zap B, 0xf0, B
+')
+
+ /* kill the special cases. */
+ beq B, Ldotrap /* division by zero! */
+
+ cmpult A, B, CC /* A < B? */
+ /* RESULT is already zero, from above. A is untouched. */
+ bne CC, Lret_result
+
+ cmpeq A, B, CC /* A == B? */
+ cmovne CC, 1, RESULT
+ cmovne CC, zero, A
+ bne CC, Lret_result
+
+ /*
+ * Find out how many bits of zeros are at the beginning of the divisor.
+ */
+LBbits:
+ ldiq T_0, 1 /* I = 0; BIT = 1<<WORDSIZE-1 */
+ mov zero, I
+ sll T_0, WORDSIZE-1, BIT
+LBloop:
+ and B, BIT, CC /* if bit in B is set, done. */
+ bne CC, LAbits
+ addq I, 1, I /* increment I, shift bit */
+ srl BIT, 1, BIT
+ cmplt I, WORDSIZE-1, CC /* if I leaves one bit, done. */
+ bne CC, LBloop
+
+LAbits:
+ beq I, Ldodiv /* If I = 0, divide now. */
+ ldiq T_0, 1 /* BIT = 1<<WORDSIZE-1 */
+ sll T_0, WORDSIZE-1, BIT
+
+LAloop:
+ and A, BIT, CC /* if bit in A is set, done. */
+ bne CC, Ldodiv
+ subq I, 1, I /* decrement I, shift bit */
+ srl BIT, 1, BIT
+ bne I, LAloop /* If I != 0, loop again */
+
+Ldodiv:
+ sll B, I, B /* B <<= i */
+ ldiq T_0, 1
+ sll T_0, I, BIT
+
+Ldivloop:
+ cmpult A, B, CC
+ or RESULT, BIT, T_0
+ cmoveq CC, T_0, RESULT
+ subq A, B, T_0
+ cmoveq CC, T_0, A
+ srl BIT, 1, BIT
+ srl B, 1, B
+ beq A, Lret_result
+ bne BIT, Ldivloop
+
+Lret_result:
+ifelse(OP, `div',
+`', ` mov A, RESULT
+')
+ifelse(S, `true',
+`
+ /* Check to see if we should negate it. */
+ subqv zero, RESULT, T_0
+ cmovlbs NEG, T_0, RESULT
+')
+
+ ldq BIT, 0(sp)
+ ldq I, 8(sp)
+ ldq CC, 16(sp)
+ ldq T_0, 24(sp)
+ifelse(S, `true',
+` ldq NEG, 32(sp)')
+ ldq A, 40(sp)
+ ldq B, 48(sp)
+ lda sp, 64(sp)
+ ret zero, (t9), 1
+
+Ldotrap:
+ ldiq a0, -2 /* This is the signal to SIGFPE! */
+ call_pal PAL_gentrap
+ifelse(OP, `div',
+`', ` mov zero, A /* so that zero will be returned */
+')
+ br zero, Lret_result
+
+END(NAME)
diff --git a/lib/libc/alpha/gen/fabs.S b/lib/libc/alpha/gen/fabs.S
new file mode 100644
index 0000000..458e2fb
--- /dev/null
+++ b/lib/libc/alpha/gen/fabs.S
@@ -0,0 +1,35 @@
+/* $NetBSD: fabs.S,v 1.2 1996/10/17 03:08:05 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+LEAF(fabs, 1)
+ cpys fzero, fa0, fv0
+ RET
+END(fabs)
diff --git a/lib/libc/alpha/gen/flt_rounds.c b/lib/libc/alpha/gen/flt_rounds.c
new file mode 100644
index 0000000..b6246c9
--- /dev/null
+++ b/lib/libc/alpha/gen/flt_rounds.c
@@ -0,0 +1,57 @@
+/* $FreeBSD$ */
+/* From: NetBSD: flt_rounds.c,v 1.2 1997/07/18 00:30:30 thorpej Exp */
+
+/*
+ * Copyright (c) 1995 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <machine/float.h>
+
+static const int map[] = {
+ 0, /* round to zero */
+ 3, /* round to negative infinity */
+ 1, /* round to nearest */
+ 2 /* round to positive infinity */
+};
+
+int
+__flt_rounds()
+{
+ double fpcrval;
+ u_int64_t old;
+
+ __asm__("trapb");
+ __asm__("mf_fpcr %0" : "=f" (fpcrval));
+ __asm__("trapb");
+ old = *(u_int64_t *)&fpcrval;
+
+ return map[(old >> 58) & 0x3];
+}
diff --git a/lib/libc/alpha/gen/fpgetmask.c b/lib/libc/alpha/gen/fpgetmask.c
new file mode 100644
index 0000000..516ae98
--- /dev/null
+++ b/lib/libc/alpha/gen/fpgetmask.c
@@ -0,0 +1,49 @@
+/* $NetBSD: fpgetmask.c,v 1.1 1995/04/29 05:10:55 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <ieeefp.h>
+#include <machine/sysarch.h>
+
+struct params {
+ u_int64_t mask;
+};
+
+fp_except
+fpgetmask()
+{
+ struct params p;
+
+ sysarch(ALPHA_GET_FPMASK, (char *) &p);
+ return((fp_except) p.mask);
+}
diff --git a/lib/libc/alpha/gen/fpgetround.c b/lib/libc/alpha/gen/fpgetround.c
new file mode 100644
index 0000000..46976c2
--- /dev/null
+++ b/lib/libc/alpha/gen/fpgetround.c
@@ -0,0 +1,48 @@
+/* $NetBSD: fpgetround.c,v 1.1 1995/04/29 05:09:55 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <ieeefp.h>
+#include <machine/fpu.h>
+
+fp_rnd
+fpgetround()
+{
+ double fpcrval;
+ u_int64_t old;
+
+ GET_FPCR(fpcrval);
+ old = *(u_int64_t *)&fpcrval;
+
+ return ((old & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT);
+}
diff --git a/lib/libc/alpha/gen/fpgetsticky.c b/lib/libc/alpha/gen/fpgetsticky.c
new file mode 100644
index 0000000..c0ff4d7
--- /dev/null
+++ b/lib/libc/alpha/gen/fpgetsticky.c
@@ -0,0 +1,48 @@
+/* $NetBSD: fpgetsticky.c,v 1.1 1995/04/29 05:10:59 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <ieeefp.h>
+#include <machine/fpu.h>
+
+fp_except
+fpgetsticky()
+{
+ double fpcrval;
+ u_int64_t old;
+
+ GET_FPCR(fpcrval);
+ old = *(u_int64_t *)&fpcrval;
+ return (((old >> IEEE_STATUS_TO_FPCR_SHIFT) & IEEE_STATUS_MASK)
+ >> IEEE_STATUS_TO_EXCSUM_SHIFT);
+}
diff --git a/lib/libc/alpha/gen/fpsetmask.c b/lib/libc/alpha/gen/fpsetmask.c
new file mode 100644
index 0000000..05201ce
--- /dev/null
+++ b/lib/libc/alpha/gen/fpsetmask.c
@@ -0,0 +1,51 @@
+/* $NetBSD: fpsetmask.c,v 1.1 1995/04/29 05:11:01 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <ieeefp.h>
+#include <machine/sysarch.h>
+
+struct params {
+ u_int64_t mask;
+};
+
+fp_except
+fpsetmask(mask)
+ fp_except mask;
+{
+ struct params p;
+
+ p.mask = (u_int64_t) mask;
+ sysarch(ALPHA_SET_FPMASK, (char *) &p);
+ return ((fp_except) p.mask);
+}
diff --git a/lib/libc/alpha/gen/fpsetround.c b/lib/libc/alpha/gen/fpsetround.c
new file mode 100644
index 0000000..0d8f40a
--- /dev/null
+++ b/lib/libc/alpha/gen/fpsetround.c
@@ -0,0 +1,55 @@
+/* $NetBSD: fpsetround.c,v 1.1 1995/04/29 05:09:57 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <ieeefp.h>
+#include <machine/fpu.h>
+
+fp_rnd
+fpsetround(rnd_dir)
+ fp_rnd rnd_dir;
+{
+ double fpcrval;
+ u_int64_t old, new;
+
+ GET_FPCR(fpcrval);
+ old = *(u_int64_t *)&fpcrval;
+
+ new = old & (~FPCR_DYN_MASK);
+ new |= ((long) rnd_dir << FPCR_DYN_SHIFT) & FPCR_DYN_MASK;
+
+ *(u_int64_t *)&fpcrval = new;
+ SET_FPCR(fpcrval);
+
+ return ((old & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT);
+}
diff --git a/lib/libc/alpha/gen/fpsetsticky.c b/lib/libc/alpha/gen/fpsetsticky.c
new file mode 100644
index 0000000..ae0d742
--- /dev/null
+++ b/lib/libc/alpha/gen/fpsetsticky.c
@@ -0,0 +1,55 @@
+/* $NetBSD: fpsetsticky.c,v 1.1 1995/04/29 05:11:04 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <ieeefp.h>
+#include <machine/fpu.h>
+
+fp_except
+fpsetsticky(sticky)
+ fp_except sticky;
+{
+ double fpcrval;
+ u_int64_t old,new ;
+
+ GET_FPCR(fpcrval);
+ old = *(u_int64_t *)&fpcrval;
+ new = old & ~ (IEEE_STATUS_MASK << IEEE_STATUS_TO_FPCR_SHIFT);
+ new |= ((sticky << IEEE_STATUS_TO_EXCSUM_SHIFT) & IEEE_STATUS_MASK)
+ << IEEE_STATUS_TO_FPCR_SHIFT;
+ *(u_int64_t *)&fpcrval = new;
+ SET_FPCR(fpcrval);
+
+ return (((old >> IEEE_STATUS_TO_FPCR_SHIFT) & IEEE_STATUS_MASK)
+ >> IEEE_STATUS_TO_EXCSUM_SHIFT);
+}
diff --git a/lib/libc/alpha/gen/frexp.c b/lib/libc/alpha/gen/frexp.c
new file mode 100644
index 0000000..b05f2ac
--- /dev/null
+++ b/lib/libc/alpha/gen/frexp.c
@@ -0,0 +1,53 @@
+/* $NetBSD: frexp.c,v 1.1 1995/02/10 17:50:22 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+double
+frexp(value, eptr)
+ double value;
+ int *eptr;
+{
+ union doub {
+ double v;
+ struct ieee_double s;
+ } u;
+
+ if (value) {
+ u.v = value;
+ *eptr = u.s.dbl_exp - (DBL_EXP_BIAS - 1);
+ u.s.dbl_exp = DBL_EXP_BIAS - 1;
+ return(u.v);
+ } else {
+ *eptr = 0;
+ return((double)0);
+ }
+}
diff --git a/lib/libc/alpha/gen/infinity.c b/lib/libc/alpha/gen/infinity.c
new file mode 100644
index 0000000..194a9f2
--- /dev/null
+++ b/lib/libc/alpha/gen/infinity.c
@@ -0,0 +1,33 @@
+/* $NetBSD: infinity.c,v 1.1 1995/02/10 17:50:23 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <math.h>
+
+/* bytes for +Infinity on an Alpha (IEEE double format) */
+char __infinity[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
diff --git a/lib/libc/alpha/gen/isinf.c b/lib/libc/alpha/gen/isinf.c
new file mode 100644
index 0000000..11ab3ce
--- /dev/null
+++ b/lib/libc/alpha/gen/isinf.c
@@ -0,0 +1,52 @@
+/* $NetBSD: isinf.c,v 1.1 1995/02/10 17:50:23 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+int
+isnan(d)
+ double d;
+{
+ register struct ieee_double *p = (struct ieee_double *)&d;
+
+ return (p->dbl_exp == DBL_EXP_INFNAN &&
+ (p->dbl_frach || p->dbl_fracl));
+}
+
+int
+isinf(d)
+ double d;
+{
+ register struct ieee_double *p = (struct ieee_double *)&d;
+
+ return (p->dbl_exp == DBL_EXP_INFNAN &&
+ !p->dbl_frach && !p->dbl_fracl);
+}
diff --git a/lib/libc/alpha/gen/ldexp.c b/lib/libc/alpha/gen/ldexp.c
new file mode 100644
index 0000000..0cb9938
--- /dev/null
+++ b/lib/libc/alpha/gen/ldexp.c
@@ -0,0 +1,134 @@
+/* $NetBSD: ldexp.c,v 1.1 1995/02/10 17:50:24 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/types.h>
+#include <machine/ieee.h>
+#include <errno.h>
+#include <math.h>
+
+/*
+ * double ldexp(double val, int exp)
+ * returns: val * (2**exp)
+ */
+double
+ldexp(val, exp)
+ double val;
+ int exp;
+{
+ register int oldexp, newexp, mulexp;
+ union doub {
+ double v;
+ struct ieee_double s;
+ } u, mul;
+
+ /*
+ * If input is zero, or no change, just return input.
+ * Likewise, if input is Inf or NaN, just return it.
+ */
+ u.v = val;
+ oldexp = u.s.dbl_exp;
+ if (val == 0 || exp == 0 || oldexp == DBL_EXP_INFNAN)
+ return (val);
+
+ /*
+ * Compute new exponent and check for over/under flow.
+ * Underflow, unfortunately, could mean switching to denormal.
+ * If result out of range, set ERANGE and return 0 if too small
+ * or Inf if too big, with the same sign as the input value.
+ */
+ newexp = oldexp + exp;
+ if (newexp >= DBL_EXP_INFNAN) {
+ /* u.s.dbl_sign = val < 0; -- already set */
+ u.s.dbl_exp = DBL_EXP_INFNAN;
+ u.s.dbl_frach = u.s.dbl_fracl = 0;
+ errno = ERANGE;
+ return (u.v); /* Inf */
+ }
+ if (newexp <= 0) {
+ /*
+ * The output number is either a denormal or underflows
+ * (see comments in machine/ieee.h).
+ */
+ if (newexp <= -DBL_FRACBITS) {
+ /* u.s.dbl_sign = val < 0; -- already set */
+ u.s.dbl_exp = 0;
+ u.s.dbl_frach = u.s.dbl_fracl = 0;
+ errno = ERANGE;
+ return (u.v); /* zero */
+ }
+ /*
+ * We are going to produce a denorm. Our `exp' argument
+ * might be as small as -2097, and we cannot compute
+ * 2^-2097, so we may have to do this as many as three
+ * steps (not just two, as for positive `exp's below).
+ */
+ mul.v = 0;
+ while (exp <= -DBL_EXP_BIAS) {
+ mul.s.dbl_exp = 1;
+ val *= mul.v;
+ exp += DBL_EXP_BIAS - 1;
+ }
+ mul.s.dbl_exp = exp + DBL_EXP_BIAS;
+ val *= mul.v;
+ return (val);
+ }
+
+ /*
+ * Newexp is positive.
+ *
+ * If oldexp is zero, we are starting with a denorm, and simply
+ * adjusting the exponent will produce bogus answers. We need
+ * to fix that first.
+ */
+ if (oldexp == 0) {
+ /*
+ * Multiply by 2^mulexp to make the number normalizable.
+ * We cannot multiply by more than 2^1023, but `exp'
+ * argument might be as large as 2046. A single
+ * adjustment, however, will normalize the number even
+ * for huge `exp's, and then we can use exponent
+ * arithmetic just as for normal `double's.
+ */
+ mulexp = exp <= DBL_EXP_BIAS ? exp : DBL_EXP_BIAS;
+ mul.v = 0;
+ mul.s.dbl_exp = mulexp + DBL_EXP_BIAS;
+ val *= mul.v;
+ if (mulexp == exp)
+ return (val);
+ u.v = val;
+ newexp -= mulexp;
+ }
+
+ /*
+ * Both oldexp and newexp are positive; just replace the
+ * old exponent with the new one.
+ */
+ u.s.dbl_exp = newexp;
+ return (u.v);
+}
diff --git a/lib/libc/alpha/gen/modf.c b/lib/libc/alpha/gen/modf.c
new file mode 100644
index 0000000..47de384
--- /dev/null
+++ b/lib/libc/alpha/gen/modf.c
@@ -0,0 +1,104 @@
+/* $NetBSD: modf.c,v 1.1 1995/02/10 17:50:25 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/types.h>
+#include <machine/ieee.h>
+#include <errno.h>
+#include <math.h>
+
+/*
+ * double modf(double val, double *iptr)
+ * returns: f and i such that |f| < 1.0, (f + i) = val, and
+ * sign(f) == sign(i) == sign(val).
+ *
+ * Beware signedness when doing subtraction, and also operand size!
+ */
+double
+modf(val, iptr)
+ double val, *iptr;
+{
+ union doub {
+ double v;
+ struct ieee_double s;
+ } u, v;
+ u_int64_t frac;
+
+ /*
+ * If input is Inf or NaN, return it and leave i alone.
+ */
+ u.v = val;
+ if (u.s.dbl_exp == DBL_EXP_INFNAN)
+ return (u.v);
+
+ /*
+ * If input can't have a fractional part, return
+ * (appropriately signed) zero, and make i be the input.
+ */
+ if ((int)u.s.dbl_exp - DBL_EXP_BIAS > DBL_FRACBITS - 1) {
+ *iptr = u.v;
+ v.v = 0.0;
+ v.s.dbl_sign = u.s.dbl_sign;
+ return (v.v);
+ }
+
+ /*
+ * If |input| < 1.0, return it, and set i to the appropriately
+ * signed zero.
+ */
+ if (u.s.dbl_exp < DBL_EXP_BIAS) {
+ v.v = 0.0;
+ v.s.dbl_sign = u.s.dbl_sign;
+ *iptr = v.v;
+ return (u.v);
+ }
+
+ /*
+ * There can be a fractional part of the input.
+ * If you look at the math involved for a few seconds, it's
+ * plain to see that the integral part is the input, with the
+ * low (DBL_FRACBITS - (exponent - DBL_EXP_BIAS)) bits zeroed,
+ * the the fractional part is the part with the rest of the
+ * bits zeroed. Just zeroing the high bits to get the
+ * fractional part would yield a fraction in need of
+ * normalization. Therefore, we take the easy way out, and
+ * just use subtraction to get the fractional part.
+ */
+ v.v = u.v;
+ /* Zero the low bits of the fraction, the sleazy way. */
+ frac = ((u_int64_t)v.s.dbl_frach << 32) + v.s.dbl_fracl;
+ frac >>= DBL_FRACBITS - (u.s.dbl_exp - DBL_EXP_BIAS);
+ frac <<= DBL_FRACBITS - (u.s.dbl_exp - DBL_EXP_BIAS);
+ v.s.dbl_fracl = frac & 0xffffffff;
+ v.s.dbl_frach = frac >> 32;
+ *iptr = v.v;
+
+ u.v -= v.v;
+ u.s.dbl_sign = v.s.dbl_sign;
+ return (u.v);
+}
diff --git a/lib/libc/alpha/gen/setjmp.S b/lib/libc/alpha/gen/setjmp.S
new file mode 100644
index 0000000..fc2e16a
--- /dev/null
+++ b/lib/libc/alpha/gen/setjmp.S
@@ -0,0 +1,127 @@
+/* $NetBSD: setjmp.S,v 1.3 1997/12/05 02:06:27 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ *
+ * $FreeBSD$
+ */
+
+#include "SYS.h"
+
+/*
+ * C library -- setjmp, longjmp
+ *
+ * longjmp(a,v)
+ * will generate a "return(v)" from
+ * the last call to
+ * setjmp(a)
+ * by restoring registers from the stack,
+ * and the previous signal state.
+ */
+
+ .set noreorder
+
+LEAF(setjmp, 1)
+ LDGP(pv)
+ stq ra, (2 * 8)(a0) /* sc_pc = return address */
+ stq s0, (( 9 + 4) * 8)(a0) /* saved bits of sc_regs */
+ stq s1, ((10 + 4) * 8)(a0)
+ stq s2, ((11 + 4) * 8)(a0)
+ stq s3, ((12 + 4) * 8)(a0)
+ stq s4, ((13 + 4) * 8)(a0)
+ stq s5, ((14 + 4) * 8)(a0)
+ stq s6, ((15 + 4) * 8)(a0)
+ stq ra, ((26 + 4) * 8)(a0)
+ stq sp, ((30 + 4) * 8)(a0)
+
+ /*
+ * get signal information
+ */
+ mov a0, s0 /* squirrel away ptr to sc */
+
+ /* see what's blocked */
+ lda a2, (71 * 8)(a0) /* oset: sc_reserved */
+ mov zero, a1 /* set: NULL */
+ addq a1, 1, a0 /* how: SIG_BLOCK */
+ PCALL(sigprocmask) /* see what's blocked */
+
+ lda sp, -24(sp) /* sizeof struct sigaltstack */
+ mov zero, a0
+ mov sp, a1
+ PCALL(sigaltstack)
+ ldl t0, 16(sp) /* offset of ss_flags */
+ lda sp, 24(sp) /* sizeof struct sigaltstack */
+ ldq ra, ((26 + 4) * 8)(s0) /* restore return address */
+ blt v0, botch /* check for error */
+ and t0, 0x1, t0 /* get SA_ONSTACK flag */
+ stq t0, (0 * 8)(s0) /* and save it in sc_onstack */
+ /*
+ * Restore old s0 and a0, and continue saving registers
+ */
+ mov s0, a0
+ ldq s0, (( 9 + 4) * 8)(a0)
+
+ ldiq t0, 0xacedbade /* sigcontext magic number */
+ stq t0, ((31 + 4) * 8)(a0) /* magic in sc_regs[31] */
+ /* Too bad we can't check if we actually used FP */
+ ldiq t0, 1
+ stq t0, (36 * 8)(a0) /* say we've used FP. */
+ stt fs0, ((2 + 37) * 8)(a0) /* saved bits of sc_fpregs */
+ stt fs1, ((3 + 37) * 8)(a0)
+ stt fs2, ((4 + 37) * 8)(a0)
+ stt fs3, ((5 + 37) * 8)(a0)
+ stt fs4, ((6 + 37) * 8)(a0)
+ stt fs5, ((7 + 37) * 8)(a0)
+ stt fs6, ((8 + 37) * 8)(a0)
+ stt fs7, ((9 + 37) * 8)(a0)
+ mf_fpcr ft0 /* get FP control reg */
+ stt ft0, (69 * 8)(a0) /* and store it in sc_fpcr */
+ stq zero, (70 * 8)(a0) /* FP software control XXX */
+ stq zero, (71 * 8)(a0) /* sc_reserved[0] */
+ stq zero, (72 * 8)(a0) /* sc_reserved[1] */
+ stq zero, (73 * 8)(a0) /* sc_xxx[0] */
+ stq zero, (74 * 8)(a0) /* sc_xxx[1] */
+ stq zero, (75 * 8)(a0) /* sc_xxx[2] */
+ stq zero, (76 * 8)(a0) /* sc_xxx[3] */
+ stq zero, (77 * 8)(a0) /* sc_xxx[4] */
+ stq zero, (78 * 8)(a0) /* sc_xxx[5] */
+ stq zero, (79 * 8)(a0) /* sc_xxx[6] */
+ stq zero, (80 * 8)(a0) /* sc_xxx[7] */
+
+ mov zero, v0 /* return zero */
+ RET
+END(setjmp)
+
+LEAF(longjmp, 2)
+ LDGP(pv)
+ stq a1, (( 0 + 4) * 8)(a0) /* save return value */
+ PCALL(sigreturn) /* use sigreturn to return */
+
+botch:
+ CALL(longjmperror)
+ CALL(abort)
+ RET /* "can't" get here... */
+END(longjmp)
diff --git a/lib/libc/alpha/gen/sigsetjmp.S b/lib/libc/alpha/gen/sigsetjmp.S
new file mode 100644
index 0000000..8c79e0a
--- /dev/null
+++ b/lib/libc/alpha/gen/sigsetjmp.S
@@ -0,0 +1,62 @@
+/* $NetBSD: sigsetjmp.S,v 1.2 1996/10/17 03:08:07 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+/*
+ * C library -- sigsetjmp, siglongjmp
+ *
+ * siglongjmp(a,v)
+ * will generate a "return(v)" from
+ * the last call to
+ * sigsetjmp(a, mask)
+ * by restoring registers from the stack.
+ * If `mask' is non-zero, the previous signal
+ * state will be restored.
+ */
+
+ .set noreorder
+
+LEAF(sigsetjmp, 2)
+ LDGP(pv)
+ stq a1, (81 * 8)(a0) /* save the mask */
+ bne a1, Lsavesig /* if !zero, save signals */
+ jmp zero, _setjmp /* else don't. */
+Lsavesig:
+ jmp zero, setjmp
+END(sigsetjmp)
+
+LEAF(siglongjmp, 2)
+ LDGP(pv)
+ ldq t0, (81 * 8)(a0) /* get the mask */
+ bne t0, Lrestoresig /* if !zero, restore signals */
+ jmp zero, _longjmp
+Lrestoresig:
+ jmp zero, longjmp
+END(siglongjmp)
diff --git a/lib/libc/alpha/net/Makefile.inc b/lib/libc/alpha/net/Makefile.inc
new file mode 100644
index 0000000..b717813
--- /dev/null
+++ b/lib/libc/alpha/net/Makefile.inc
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+SRCS+= htonl.S htons.S ntohl.S ntohs.S
diff --git a/lib/libc/alpha/net/byte_swap_2.S b/lib/libc/alpha/net/byte_swap_2.S
new file mode 100644
index 0000000..fab3c58
--- /dev/null
+++ b/lib/libc/alpha/net/byte_swap_2.S
@@ -0,0 +1,47 @@
+/* $NetBSD: byte_swap_2.S,v 1.2 1996/10/17 03:08:08 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+#ifndef NAME
+#define NAME byte_swap_2
+#endif
+
+/*
+ * Byte-swap a 2-byte quantity. (Convert 0x0123 to 0x2301.)
+ *
+ * Argument is an unsigned 2-byte integer (u_int16_t).
+ */
+LEAF(NAME, 1) /* a0 contains 0x0123 */
+ extbl a0, 0, t0 /* t0 = 0x 23 */
+ extbl a0, 1, t1 /* t1 = 0x 01 */
+ sll t0, 8, t0 /* t1 = 0x23 */
+ or t0, t1, v0 /* v0 = 0x2301 */
+ RET
+END(NAME)
diff --git a/lib/libc/alpha/net/byte_swap_4.S b/lib/libc/alpha/net/byte_swap_4.S
new file mode 100644
index 0000000..8dbb83c
--- /dev/null
+++ b/lib/libc/alpha/net/byte_swap_4.S
@@ -0,0 +1,53 @@
+/* $NetBSD: byte_swap_4.S,v 1.2 1996/10/17 03:08:09 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+#ifndef NAME
+#define NAME byte_swap_4
+#endif
+
+/*
+ * Byte-swap a 4-byte quantity. (Convert 0x01234567 to 0x67452301.)
+ *
+ * Argument is an unsigned 4-byte integer (u_int32_t).
+ */
+LEAF(NAME, 1) /* a0 contains 0x01234567 */
+ extbl a0, 0, t0 /* t0 = 0x 67 */
+ extbl a0, 1, t1 /* t1 = 0x 45 */
+ extbl a0, 2, t2 /* t2 = 0x 23 */
+ extbl a0, 3, t3 /* t3 = 0x 01 */
+ sll t0, 24, t0 /* t0 = 0x67 */
+ sll t1, 16, t1 /* t1 = 0x 45 */
+ sll t2, 8, t2 /* t2 = 0x 23 */
+ or t3, t0, v0 /* v0 = 0x67 01 */
+ or t1, t2, t1 /* t1 = 0x 4523 */
+ or t1, v0, v0 /* v0 = 0x67452301 */
+ RET
+END(NAME)
diff --git a/lib/libc/alpha/net/htonl.S b/lib/libc/alpha/net/htonl.S
new file mode 100644
index 0000000..bacab1e
--- /dev/null
+++ b/lib/libc/alpha/net/htonl.S
@@ -0,0 +1,32 @@
+/* $NetBSD: htonl.S,v 1.1 1996/04/17 22:36:52 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#define NAME htonl
+
+#include "byte_swap_4.S"
diff --git a/lib/libc/alpha/net/htons.S b/lib/libc/alpha/net/htons.S
new file mode 100644
index 0000000..fb08222
--- /dev/null
+++ b/lib/libc/alpha/net/htons.S
@@ -0,0 +1,32 @@
+/* $NetBSD: htons.S,v 1.1 1996/04/17 22:36:54 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#define NAME htons
+
+#include "byte_swap_2.S"
diff --git a/lib/libc/alpha/net/ntohl.S b/lib/libc/alpha/net/ntohl.S
new file mode 100644
index 0000000..b571647
--- /dev/null
+++ b/lib/libc/alpha/net/ntohl.S
@@ -0,0 +1,32 @@
+/* $NetBSD: ntohl.S,v 1.1 1996/04/17 22:36:57 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#define NAME ntohl
+
+#include "byte_swap_4.S"
diff --git a/lib/libc/alpha/net/ntohs.S b/lib/libc/alpha/net/ntohs.S
new file mode 100644
index 0000000..6db9961
--- /dev/null
+++ b/lib/libc/alpha/net/ntohs.S
@@ -0,0 +1,32 @@
+/* $NetBSD: ntohs.S,v 1.1 1996/04/17 22:37:02 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#define NAME ntohs
+
+#include "byte_swap_2.S"
diff --git a/lib/libc/alpha/stdlib/Makefile.inc b/lib/libc/alpha/stdlib/Makefile.inc
new file mode 100644
index 0000000..dda8c76
--- /dev/null
+++ b/lib/libc/alpha/stdlib/Makefile.inc
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+MDSRCS+= abs.c div.c labs.c ldiv.c
diff --git a/lib/libc/alpha/string/Makefile.inc b/lib/libc/alpha/string/Makefile.inc
new file mode 100644
index 0000000..7bbcc8d
--- /dev/null
+++ b/lib/libc/alpha/string/Makefile.inc
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+MDSRCS+= bcopy.S bzero.S ffs.S memcpy.S memmove.S
diff --git a/lib/libc/alpha/string/bcopy.S b/lib/libc/alpha/string/bcopy.S
new file mode 100644
index 0000000..6a45ad6
--- /dev/null
+++ b/lib/libc/alpha/string/bcopy.S
@@ -0,0 +1,288 @@
+/* $NetBSD: bcopy.S,v 1.3 1996/10/17 03:08:11 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Trevor Blackwell. Support for use as memcpy() and memmove()
+ * added by Chris Demetriou.
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+#if defined(MEMCOPY) || defined(MEMMOVE)
+#ifdef MEMCOPY
+#define FUNCTION memcpy
+#else
+#define FUNCTION memmove
+#endif
+#define SRCREG a1
+#define DSTREG a0
+#else /* !(defined(MEMCOPY) || defined(MEMMOVE)) */
+#define FUNCTION bcopy
+#define SRCREG a0
+#define DSTREG a1
+#endif /* !(defined(MEMCOPY) || defined(MEMMOVE)) */
+
+#define SIZEREG a2
+
+/*
+ * Copy bytes.
+ *
+ * void bcopy(char *from, char *to, size_t len);
+ * char *memcpy(void *to, const void *from, size_t len);
+ * char *memmove(void *to, const void *from, size_t len);
+ *
+ * No matter how invoked, the source and destination registers
+ * for calculation. There's no point in copying them to "working"
+ * registers, since the code uses their values "in place," and
+ * copying them would be slower.
+ */
+
+LEAF(FUNCTION,3)
+
+#if defined(MEMCOPY) || defined(MEMMOVE)
+ /* set up return value, while we still can */
+ mov DSTREG,v0
+#endif
+
+ /* Check for negative length */
+ ble SIZEREG,bcopy_done
+
+ /* Check for overlap */
+ subq DSTREG,SRCREG,t5
+ cmpult t5,SIZEREG,t5
+ bne t5,bcopy_overlap
+
+ /* a3 = end address */
+ addq SRCREG,SIZEREG,a3
+
+ /* Get the first word */
+ ldq_u t2,0(SRCREG)
+
+ /* Do they have the same alignment? */
+ xor SRCREG,DSTREG,t0
+ and t0,7,t0
+ and DSTREG,7,t1
+ bne t0,bcopy_different_alignment
+
+ /* src & dst have same alignment */
+ beq t1,bcopy_all_aligned
+
+ ldq_u t3,0(DSTREG)
+ addq SIZEREG,t1,SIZEREG
+ mskqh t2,SRCREG,t2
+ mskql t3,SRCREG,t3
+ or t2,t3,t2
+
+ /* Dst is 8-byte aligned */
+
+bcopy_all_aligned:
+ /* If less than 8 bytes,skip loop */
+ subq SIZEREG,1,t0
+ and SIZEREG,7,SIZEREG
+ bic t0,7,t0
+ beq t0,bcopy_samealign_lp_end
+
+bcopy_samealign_lp:
+ stq_u t2,0(DSTREG)
+ addq DSTREG,8,DSTREG
+ ldq_u t2,8(SRCREG)
+ subq t0,8,t0
+ addq SRCREG,8,SRCREG
+ bne t0,bcopy_samealign_lp
+
+bcopy_samealign_lp_end:
+ /* If we're done, exit */
+ bne SIZEREG,bcopy_small_left
+ stq_u t2,0(DSTREG)
+ RET
+
+bcopy_small_left:
+ mskql t2,SIZEREG,t4
+ ldq_u t3,0(DSTREG)
+ mskqh t3,SIZEREG,t3
+ or t4,t3,t4
+ stq_u t4,0(DSTREG)
+ RET
+
+bcopy_different_alignment:
+ /*
+ * this is the fun part
+ */
+ addq SRCREG,SIZEREG,a3
+ cmpule SIZEREG,8,t0
+ bne t0,bcopy_da_finish
+
+ beq t1,bcopy_da_noentry
+
+ /* Do the initial partial word */
+ subq zero,DSTREG,t0
+ and t0,7,t0
+ ldq_u t3,7(SRCREG)
+ extql t2,SRCREG,t2
+ extqh t3,SRCREG,t3
+ or t2,t3,t5
+ insql t5,DSTREG,t5
+ ldq_u t6,0(DSTREG)
+ mskql t6,DSTREG,t6
+ or t5,t6,t5
+ stq_u t5,0(DSTREG)
+ addq SRCREG,t0,SRCREG
+ addq DSTREG,t0,DSTREG
+ subq SIZEREG,t0,SIZEREG
+ ldq_u t2,0(SRCREG)
+
+bcopy_da_noentry:
+ subq SIZEREG,1,t0
+ bic t0,7,t0
+ and SIZEREG,7,SIZEREG
+ beq t0,bcopy_da_finish2
+
+bcopy_da_lp:
+ ldq_u t3,7(SRCREG)
+ addq SRCREG,8,SRCREG
+ extql t2,SRCREG,t4
+ extqh t3,SRCREG,t5
+ subq t0,8,t0
+ or t4,t5,t5
+ stq t5,0(DSTREG)
+ addq DSTREG,8,DSTREG
+ beq t0,bcopy_da_finish1
+ ldq_u t2,7(SRCREG)
+ addq SRCREG,8,SRCREG
+ extql t3,SRCREG,t4
+ extqh t2,SRCREG,t5
+ subq t0,8,t0
+ or t4,t5,t5
+ stq t5,0(DSTREG)
+ addq DSTREG,8,DSTREG
+ bne t0,bcopy_da_lp
+
+bcopy_da_finish2:
+ /* Do the last new word */
+ mov t2,t3
+
+bcopy_da_finish1:
+ /* Do the last partial word */
+ ldq_u t2,-1(a3)
+ extql t3,SRCREG,t3
+ extqh t2,SRCREG,t2
+ or t2,t3,t2
+ br zero,bcopy_samealign_lp_end
+
+bcopy_da_finish:
+ /* Do the last word in the next source word */
+ ldq_u t3,-1(a3)
+ extql t2,SRCREG,t2
+ extqh t3,SRCREG,t3
+ or t2,t3,t2
+ insqh t2,DSTREG,t3
+ insql t2,DSTREG,t2
+ lda t4,-1(zero)
+ mskql t4,SIZEREG,t5
+ cmovne t5,t5,t4
+ insqh t4,DSTREG,t5
+ insql t4,DSTREG,t4
+ addq DSTREG,SIZEREG,a4
+ ldq_u t6,0(DSTREG)
+ ldq_u t7,-1(a4)
+ bic t6,t4,t6
+ bic t7,t5,t7
+ and t2,t4,t2
+ and t3,t5,t3
+ or t2,t6,t2
+ or t3,t7,t3
+ stq_u t3,-1(a4)
+ stq_u t2,0(DSTREG)
+ RET
+
+bcopy_overlap:
+ /*
+ * Basically equivalent to previous case, only backwards.
+ * Not quite as highly optimized
+ */
+ addq SRCREG,SIZEREG,a3
+ addq DSTREG,SIZEREG,a4
+
+ /* less than 8 bytes - don't worry about overlap */
+ cmpule SIZEREG,8,t0
+ bne t0,bcopy_ov_short
+
+ /* Possibly do a partial first word */
+ and a4,7,t4
+ beq t4,bcopy_ov_nostart2
+ subq a3,t4,a3
+ subq a4,t4,a4
+ ldq_u t1,0(a3)
+ subq SIZEREG,t4,SIZEREG
+ ldq_u t2,7(a3)
+ ldq t3,0(a4)
+ extql t1,a3,t1
+ extqh t2,a3,t2
+ or t1,t2,t1
+ mskqh t3,t4,t3
+ mskql t1,t4,t1
+ or t1,t3,t1
+ stq t1,0(a4)
+
+bcopy_ov_nostart2:
+ bic SIZEREG,7,t4
+ and SIZEREG,7,SIZEREG
+ beq t4,bcopy_ov_lp_end
+
+bcopy_ov_lp:
+ /* This could be more pipelined, but it doesn't seem worth it */
+ ldq_u t0,-8(a3)
+ subq a4,8,a4
+ ldq_u t1,-1(a3)
+ subq a3,8,a3
+ extql t0,a3,t0
+ extqh t1,a3,t1
+ subq t4,8,t4
+ or t0,t1,t0
+ stq t0,0(a4)
+ bne t4,bcopy_ov_lp
+
+bcopy_ov_lp_end:
+ beq SIZEREG,bcopy_done
+
+ ldq_u t0,0(SRCREG)
+ ldq_u t1,7(SRCREG)
+ ldq_u t2,0(DSTREG)
+ extql t0,SRCREG,t0
+ extqh t1,SRCREG,t1
+ or t0,t1,t0
+ insql t0,DSTREG,t0
+ mskql t2,DSTREG,t2
+ or t2,t0,t2
+ stq_u t2,0(DSTREG)
+
+bcopy_done:
+ RET
+
+bcopy_ov_short:
+ ldq_u t2,0(SRCREG)
+ br zero,bcopy_da_finish
+
+ END(FUNCTION)
diff --git a/lib/libc/alpha/string/bzero.S b/lib/libc/alpha/string/bzero.S
new file mode 100644
index 0000000..9897344
--- /dev/null
+++ b/lib/libc/alpha/string/bzero.S
@@ -0,0 +1,110 @@
+/* $NetBSD: bzero.S,v 1.2 1996/10/17 03:08:12 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Trevor Blackwell
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+LEAF(bzero,2)
+ ble a1,bzero_done
+ bic a1,63,t3 /* t3 is # bytes to do 64 bytes at a time */
+
+ /* If nothing in first word, ignore it */
+ subq zero,a0,t0
+ and t0,7,t0 /* t0 = (0-size)%8 */
+ beq t0,bzero_nostart1
+
+ cmpult a1,t0,t1 /* if size > size%8 goto noshort */
+ beq t1,bzero_noshort
+
+ /*
+ * The whole thing is less than a word.
+ * Mask off 1..7 bytes, and finish.
+ */
+ ldq_u t2,0(a0)
+ lda t0,-1(zero) /* t0=-1 */
+ mskql t0,a1,t0 /* Get ff in bytes (a0%8)..((a0+a1-1)%8) */
+ insql t0,a0,t0
+ bic t2,t0,t2 /* zero those bytes in word */
+ stq_u t2,0(a0)
+ RET
+
+bzero_noshort:
+ /* Handle the first partial word */
+ ldq_u t2,0(a0)
+ subq a1,t0,a1
+ mskql t2,a0,t2 /* zero bytes (a0%8)..7 in word */
+ stq_u t2,0(a0)
+
+ addq a0,t0,a0 /* round a0 up to next word */
+ bic a1,63,t3 /* recalc t3 (# bytes to do 64 bytes at a
+ time) */
+
+bzero_nostart1:
+ /*
+ * Loop, zeroing 64 bytes at a time
+ */
+ beq t3,bzero_lp_done
+bzero_lp:
+ stq zero,0(a0)
+ stq zero,8(a0)
+ stq zero,16(a0)
+ stq zero,24(a0)
+ subq t3,64,t3
+ stq zero,32(a0)
+ stq zero,40(a0)
+ stq zero,48(a0)
+ stq zero,56(a0)
+ addq a0,64,a0
+ bne t3,bzero_lp
+
+bzero_lp_done:
+ /*
+ * Handle the last 0..7 words.
+ * We mask off the low bits, so we don't need an extra
+ * compare instruction for the loop (just a bne. heh-heh)
+ */
+ and a1,0x38,t4
+ beq t4,bzero_finish_lp_done
+bzero_finish_lp:
+ stq zero,0(a0)
+ subq t4,8,t4
+ addq a0,8,a0
+ bne t4,bzero_finish_lp
+
+ /* Do the last partial word */
+bzero_finish_lp_done:
+ and a1,7,t5 /* 0..7 bytes left */
+ beq t5,bzero_done /* mskqh won't change t0 if t5==0, but I
+ don't want to touch, say, a new VM page */
+ ldq t0,0(a0)
+ mskqh t0,t5,t0
+ stq t0,0(a0)
+bzero_done:
+ RET
+
+ END(bzero)
diff --git a/lib/libc/alpha/string/ffs.S b/lib/libc/alpha/string/ffs.S
new file mode 100644
index 0000000..4c30a16
--- /dev/null
+++ b/lib/libc/alpha/string/ffs.S
@@ -0,0 +1,91 @@
+/* $NetBSD: ffs.S,v 1.3 1996/10/17 03:08:13 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+LEAF(ffs, 1)
+ addl a0, 0, t0
+ beq t0, Lallzero
+
+ /*
+ * Initialize return value (v0), and set up t1 so that it
+ * contains the mask with only the lowest bit set.
+ */
+ subl zero, t0, t1
+ ldil v0, 1
+ and t0, t1, t1
+
+ and t1, 0xff, t2
+ bne t2, Ldo8
+
+ /*
+ * If lower 16 bits empty, add 16 to result and use upper 16.
+ */
+ zapnot t1, 0x03, t3
+ bne t3, Ldo16
+ sra t1, 16, t1
+ addl v0, 16, v0
+
+Ldo16:
+ /*
+ * If lower 8 bits empty, add 8 to result and use upper 8.
+ */
+ and t1, 0xff, t4
+ bne t4, Ldo8
+ sra t1, 8, t1
+ addl v0, 8, v0
+
+Ldo8:
+ and t1, 0x0f, t5 /* lower 4 of 8 empty? */
+ and t1, 0x33, t6 /* lower 2 of each 4 empty? */
+ and t1, 0x55, t7 /* lower 1 of each 2 empty? */
+
+ /* If lower 4 bits empty, add 4 to result. */
+ bne t5, Ldo4
+ addl v0, 4, v0
+
+Ldo4: /* If lower 2 bits of each 4 empty, add 2 to result. */
+ bne t6, Ldo2
+ addl v0, 2, v0
+
+Ldo2: /* If lower bit of each 2 empty, add 1 to result. */
+ bne t7, Ldone
+ addl v0, 1, v0
+
+Ldone:
+ RET
+
+Lallzero:
+ bis zero, zero, v0
+ RET
+END(ffs)
diff --git a/lib/libc/alpha/string/memcpy.S b/lib/libc/alpha/string/memcpy.S
new file mode 100644
index 0000000..7f5527d
--- /dev/null
+++ b/lib/libc/alpha/string/memcpy.S
@@ -0,0 +1,4 @@
+/* $NetBSD: memcpy.S,v 1.1 1995/08/13 00:40:47 cgd Exp $ */
+
+#define MEMCOPY
+#include "bcopy.S"
diff --git a/lib/libc/alpha/string/memmove.S b/lib/libc/alpha/string/memmove.S
new file mode 100644
index 0000000..4e632d2
--- /dev/null
+++ b/lib/libc/alpha/string/memmove.S
@@ -0,0 +1,4 @@
+/* $NetBSD: memmove.S,v 1.1 1995/08/13 00:40:48 cgd Exp $ */
+
+#define MEMMOVE
+#include "bcopy.S"
diff --git a/lib/libc/alpha/sys/Makefile.inc b/lib/libc/alpha/sys/Makefile.inc
new file mode 100644
index 0000000..014d32a
--- /dev/null
+++ b/lib/libc/alpha/sys/Makefile.inc
@@ -0,0 +1,17 @@
+# $FreeBSD$
+
+MDASM+= Ovfork.S brk.S cerror.S exect.S fork.S pipe.S ptrace.S \
+ sbrk.S setlogin.S sigreturn.S syscall.S
+
+# Don't generate default code for these syscalls:
+NOASM= __semctl.o break.o exit.o ftruncate.o getdomainname.o getlogin.o \
+ lseek.o mlockall.o mmap.o msgctl.o msgget.o msgrcv.o msgsnd.o \
+ munlockall.o openbsd_poll.o pread.o pwrite.o semconfig.o semget.o \
+ semop.o setdomainname.o shmat.o shmctl.o shmdt.o shmget.o sstk.o \
+ thr_sleep.o thr_wakeup.o truncate.o uname.o vfork.o yield.o
+
+PSEUDO= _getlogin.o
+
+# Pseudo syscalls that are renamed as _thread_sys_{pseudo} when
+# building libc_r.
+PSEUDOR= _exit.o
diff --git a/lib/libc/alpha/sys/Ovfork.S b/lib/libc/alpha/sys/Ovfork.S
new file mode 100644
index 0000000..d8dd3e8
--- /dev/null
+++ b/lib/libc/alpha/sys/Ovfork.S
@@ -0,0 +1,35 @@
+/* $NetBSD: Ovfork.S,v 1.1 1995/02/10 17:50:29 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "SYS.h"
+
+PSYSCALL(vfork)
+ cmovne a4, zero, v0 /* a4 (rv[1]) != 0, child */
+ RET
+PEND(vfork)
diff --git a/lib/libc/alpha/sys/brk.S b/lib/libc/alpha/sys/brk.S
new file mode 100644
index 0000000..7dc3a40
--- /dev/null
+++ b/lib/libc/alpha/sys/brk.S
@@ -0,0 +1,50 @@
+/* $NetBSD: brk.S,v 1.4 1996/10/17 03:08:15 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "SYS.h"
+
+ .globl _end
+IMPORT(curbrk, 8)
+
+ .data
+EXPORT(minbrk)
+ .quad _end
+
+ .text
+LEAF(brk, 1)
+ br pv, L1 /* XXX profiling */
+L1: LDGP(pv)
+ ldq v0, minbrk
+ cmpult a0, v0, t0
+ cmovne t0, v0, a0
+ CALLSYS_ERROR(break)
+ stq a0, curbrk
+ mov zero, v0
+ RET
+END(brk)
diff --git a/lib/libc/alpha/sys/cerror.S b/lib/libc/alpha/sys/cerror.S
new file mode 100644
index 0000000..e5b18f7
--- /dev/null
+++ b/lib/libc/alpha/sys/cerror.S
@@ -0,0 +1,54 @@
+/* $FreeBSD$ */
+/* From: NetBSD: cerror.S,v 1.4 1996/11/08 00:52:46 cgd Exp */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "SYS.h"
+
+#define FRAME_SIZE 16
+#define FRAME_RA_OFFSET 0
+#define FRAME_V0_OFFSET 8
+
+NESTED(.cerror, 0, FRAME_SIZE, ra, IM_RA|IM_V0, 0)
+ br t0, L1
+L1: LDGP(t0)
+
+ lda sp, -FRAME_SIZE(sp)
+ stq ra, FRAME_RA_OFFSET(sp)
+ stq v0, FRAME_V0_OFFSET(sp)
+
+ CALL(__error)
+
+ ldq t0, FRAME_V0_OFFSET(sp)
+ stl t0, 0(v0)
+
+ ldiq v0, -1
+ ldq ra, FRAME_RA_OFFSET(sp)
+ lda sp, FRAME_SIZE(sp)
+ RET
+END(.cerror)
diff --git a/lib/libc/alpha/sys/exect.S b/lib/libc/alpha/sys/exect.S
new file mode 100644
index 0000000..345efb2
--- /dev/null
+++ b/lib/libc/alpha/sys/exect.S
@@ -0,0 +1,35 @@
+/* $NetBSD: exect.S,v 1.2 1996/10/17 03:08:18 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "SYS.h"
+
+LEAF(exect, 3)
+ CALLSYS_ERROR(execve)
+ RET
+END(exect)
diff --git a/lib/libc/alpha/sys/fork.S b/lib/libc/alpha/sys/fork.S
new file mode 100644
index 0000000..a8fa754
--- /dev/null
+++ b/lib/libc/alpha/sys/fork.S
@@ -0,0 +1,35 @@
+/* $NetBSD: fork.S,v 1.1 1995/02/10 17:50:34 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "SYS.h"
+
+PSYSCALL(fork)
+ cmovne a4, zero, v0 /* a4 (rv[1]) != 0, child */
+ RET
+PEND(fork)
diff --git a/lib/libc/alpha/sys/pipe.S b/lib/libc/alpha/sys/pipe.S
new file mode 100644
index 0000000..76f44c2
--- /dev/null
+++ b/lib/libc/alpha/sys/pipe.S
@@ -0,0 +1,37 @@
+/* $NetBSD: pipe.S,v 1.1 1995/02/10 17:50:35 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "SYS.h"
+
+PSYSCALL(pipe)
+ stl v0, 0(a0)
+ stl a4, 4(a0)
+ mov zero, v0
+ RET
+PEND(pipe)
diff --git a/lib/libc/alpha/sys/ptrace.S b/lib/libc/alpha/sys/ptrace.S
new file mode 100644
index 0000000..931b43f
--- /dev/null
+++ b/lib/libc/alpha/sys/ptrace.S
@@ -0,0 +1,37 @@
+/* $NetBSD: ptrace.S,v 1.4 1996/11/08 00:51:24 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "SYS.h"
+
+LEAF(ptrace, 4)
+ LDGP(pv)
+ stl zero, errno
+ CALLSYS_ERROR(ptrace)
+ RET
+END(ptrace)
diff --git a/lib/libc/alpha/sys/sbrk.S b/lib/libc/alpha/sys/sbrk.S
new file mode 100644
index 0000000..5f4e15a
--- /dev/null
+++ b/lib/libc/alpha/sys/sbrk.S
@@ -0,0 +1,50 @@
+/* $NetBSD: sbrk.S,v 1.4 1996/10/17 03:08:20 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "SYS.h"
+
+ .globl _end
+
+ .data
+EXPORT(curbrk)
+ .quad _end
+
+ .text
+LEAF(sbrk, 1)
+ br pv, L1 /* XXX profiling */
+L1: LDGP(pv)
+ ldq a1, curbrk
+ beq a0, L2
+ addq a0, a1, a0
+ CALLSYS_ERROR(break)
+ stq a0, curbrk
+L2:
+ mov a1, v0
+ RET
+END(sbrk)
diff --git a/lib/libc/alpha/sys/setlogin.S b/lib/libc/alpha/sys/setlogin.S
new file mode 100644
index 0000000..9657cb1
--- /dev/null
+++ b/lib/libc/alpha/sys/setlogin.S
@@ -0,0 +1,37 @@
+/* $NetBSD: setlogin.S,v 1.1 1995/02/10 17:50:39 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "SYS.h"
+
+IMPORT(_logname_valid, 4) /* in getlogin() */
+
+SYSCALL(setlogin)
+ stl zero, _logname_valid /* clear it */
+ RET
+END(setlogin)
diff --git a/lib/libc/alpha/sys/sigreturn.S b/lib/libc/alpha/sys/sigreturn.S
new file mode 100644
index 0000000..a186be6
--- /dev/null
+++ b/lib/libc/alpha/sys/sigreturn.S
@@ -0,0 +1,38 @@
+/* $NetBSD: sigreturn.S,v 1.1 1995/02/10 17:50:42 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "SYS.h"
+
+/*
+ * We must preserve the state of the registers as the user has set them up.
+ * However, that doesn't involve any special work on the Alpha.
+ * (XXX PROFILING)
+ */
+
+PRSYSCALL(sigreturn)
diff --git a/lib/libc/alpha/sys/syscall.S b/lib/libc/alpha/sys/syscall.S
new file mode 100644
index 0000000..2ccf4d3
--- /dev/null
+++ b/lib/libc/alpha/sys/syscall.S
@@ -0,0 +1,32 @@
+/* $NetBSD: syscall.S,v 1.1 1995/02/10 17:50:44 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "SYS.h"
+
+RSYSCALL(syscall)
diff --git a/lib/libc/amd64/SYS.h b/lib/libc/amd64/SYS.h
new file mode 100644
index 0000000..a5daa1c
--- /dev/null
+++ b/lib/libc/amd64/SYS.h
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)SYS.h 5.5 (Berkeley) 5/7/91
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/syscall.h>
+#include "DEFS.h"
+
+#define SYSCALL(x) 2: PIC_PROLOGUE; jmp PIC_PLT(HIDENAME(cerror)); \
+ ENTRY(__CONCAT(_,x)); \
+ .weak CNAME(x); \
+ .set CNAME(x),CNAME(__CONCAT(_,x)); \
+ lea __CONCAT(SYS_,x),%eax; KERNCALL; jb 2b
+#define RSYSCALL(x) SYSCALL(x); ret
+
+#define PSEUDO(x,y) ENTRY(__CONCAT(_,x)); \
+ .weak CNAME(x); \
+ .set CNAME(x),CNAME(__CONCAT(_,x)); \
+ lea __CONCAT(SYS_,y), %eax; KERNCALL; ret
+/* gas messes up offset -- although we don't currently need it, do for BCS */
+#define LCALL(x,y) .byte 0x9a ; .long y; .word x
+
+/*
+ * Design note:
+ *
+ * The macros PSYSCALL() and PRSYSCALL() are intended for use where a
+ * syscall needs to be renamed in the threaded library. When building
+ * a normal library, they default to the traditional SYSCALL() and
+ * RSYSCALL(). This avoids the need to #ifdef _THREAD_SAFE everywhere
+ * that the renamed function needs to be called.
+ */
+#ifdef _THREAD_SAFE
+/*
+ * For the thread_safe versions, we prepend _thread_sys_ to the function
+ * name so that the 'C' wrapper can go around the real name.
+ */
+#define PSYSCALL(x) 2: PIC_PROLOGUE; jmp PIC_PLT(HIDENAME(cerror)); \
+ ENTRY(__CONCAT(_thread_sys_,x)); \
+ lea __CONCAT(SYS_,x),%eax; KERNCALL; jb 2b
+#define PRSYSCALL(x) PSYSCALL(x); ret
+#define PPSEUDO(x,y) ENTRY(__CONCAT(_thread_sys_,x)); \
+ lea __CONCAT(SYS_,y), %eax; KERNCALL; ret
+#else
+/*
+ * The non-threaded library defaults to traditional syscalls where
+ * the function name matches the syscall name.
+ */
+#define PSYSCALL(x) SYSCALL(x)
+#define PRSYSCALL(x) RSYSCALL(x)
+#define PPSEUDO(x,y) PSEUDO(x,y)
+#endif
+
+#ifdef __ELF__
+#define KERNCALL int $0x80 /* Faster */
+#else
+#define KERNCALL LCALL(7,0) /* The old way */
+#endif
diff --git a/lib/libc/amd64/gen/Makefile.inc b/lib/libc/amd64/gen/Makefile.inc
new file mode 100644
index 0000000..f2506fd
--- /dev/null
+++ b/lib/libc/amd64/gen/Makefile.inc
@@ -0,0 +1,5 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+SRCS+= _setjmp.S alloca.S fabs.S frexp.c infinity.c isinf.c ldexp.c modf.S \
+ setjmp.S sigsetjmp.S
diff --git a/lib/libc/amd64/gen/_setjmp.S b/lib/libc/amd64/gen/_setjmp.S
new file mode 100644
index 0000000..c8a1d21
--- /dev/null
+++ b/lib/libc/amd64/gen/_setjmp.S
@@ -0,0 +1,84 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ * _longjmp(a,v)
+ * will generate a "return(v)" from the last call to
+ * _setjmp(a)
+ * by restoring registers from the environment 'a'.
+ * The previous signal state is NOT restored.
+ */
+
+#include "DEFS.h"
+
+ENTRY(_setjmp)
+ movl 4(%esp),%eax
+ movl 0(%esp),%edx
+ movl %edx, 0(%eax) /* rta */
+ movl %ebx, 4(%eax)
+ movl %esp, 8(%eax)
+ movl %ebp,12(%eax)
+ movl %esi,16(%eax)
+ movl %edi,20(%eax)
+ fnstcw 24(%eax)
+ xorl %eax,%eax
+ ret
+
+ENTRY(_longjmp)
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ movl 0(%edx),%ecx
+ movl 4(%edx),%ebx
+ movl 8(%edx),%esp
+ movl 12(%edx),%ebp
+ movl 16(%edx),%esi
+ movl 20(%edx),%edi
+ fninit
+ fldcw 24(%edx)
+ testl %eax,%eax
+ jnz 1f
+ incl %eax
+1: movl %ecx,0(%esp)
+ ret
diff --git a/lib/libc/amd64/gen/frexp.c b/lib/libc/amd64/gen/frexp.c
new file mode 100644
index 0000000..4834f17
--- /dev/null
+++ b/lib/libc/amd64/gen/frexp.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <sys/types.h>
+#include <math.h>
+
+double
+frexp(value, eptr)
+ double value;
+ int *eptr;
+{
+ union {
+ double v;
+ struct {
+ u_int u_mant2 : 32;
+ u_int u_mant1 : 20;
+ u_int u_exp : 11;
+ u_int u_sign : 1;
+ } s;
+ } u;
+
+ if (value) {
+ u.v = value;
+ *eptr = u.s.u_exp - 1022;
+ u.s.u_exp = 1022;
+ return(u.v);
+ } else {
+ *eptr = 0;
+ return((double)0);
+ }
+}
diff --git a/lib/libc/amd64/gen/infinity.c b/lib/libc/amd64/gen/infinity.c
new file mode 100644
index 0000000..ac92d46
--- /dev/null
+++ b/lib/libc/amd64/gen/infinity.c
@@ -0,0 +1,9 @@
+/*
+ * infinity.c
+ * $FreeBSD$
+ */
+
+#include <math.h>
+
+/* bytes for +Infinity on a 387 */
+char __infinity[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
diff --git a/lib/libc/amd64/gen/isinf.c b/lib/libc/amd64/gen/isinf.c
new file mode 100644
index 0000000..b2b63a8
--- /dev/null
+++ b/lib/libc/amd64/gen/isinf.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <sys/types.h>
+
+int
+isnan(d)
+ double d;
+{
+ register struct IEEEdp {
+ u_int manl : 32;
+ u_int manh : 20;
+ u_int exp : 11;
+ u_int sign : 1;
+ } *p = (struct IEEEdp *)&d;
+
+ return(p->exp == 2047 && (p->manh || p->manl));
+}
+
+int
+isinf(d)
+ double d;
+{
+ register struct IEEEdp {
+ u_int manl : 32;
+ u_int manh : 20;
+ u_int exp : 11;
+ u_int sign : 1;
+ } *p = (struct IEEEdp *)&d;
+
+ return(p->exp == 2047 && !p->manh && !p->manl);
+}
diff --git a/lib/libc/amd64/gen/ldexp.c b/lib/libc/amd64/gen/ldexp.c
new file mode 100644
index 0000000..e7e58f0
--- /dev/null
+++ b/lib/libc/amd64/gen/ldexp.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Sean Eric Fagan.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+/*
+ * ldexp(value, exp): return value * (2 ** exp).
+ *
+ * Written by Sean Eric Fagan (sef@kithrup.COM)
+ * Sun Mar 11 20:27:09 PST 1990
+ */
+
+/*
+ * We do the conversion in C to let gcc optimize it away, if possible.
+ * The "fxch ; fstp" stuff is because value is still on the stack
+ * (stupid 8087!).
+ */
+double
+ldexp (double value, int exp)
+{
+ double temp, texp, temp2;
+ texp = exp;
+#ifdef __GNUC__
+#if __GNUC__ >= 2
+ asm ("fscale "
+ : "=u" (temp2), "=t" (temp)
+ : "0" (texp), "1" (value));
+#else
+ asm ("fscale ; fxch %%st(1) ; fstp%L1 %1 "
+ : "=f" (temp), "=0" (temp2)
+ : "0" (texp), "f" (value));
+#endif
+#else
+error unknown asm
+#endif
+ return (temp);
+}
diff --git a/lib/libc/amd64/gen/setjmp.S b/lib/libc/amd64/gen/setjmp.S
new file mode 100644
index 0000000..c82b7f0
--- /dev/null
+++ b/lib/libc/amd64/gen/setjmp.S
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ * longjmp(a,v)
+ * will generate a "return(v)" from the last call to
+ * setjmp(a)
+ * by restoring registers from the environment 'a'.
+ * The previous signal state is restored.
+ */
+
+#include "DEFS.h"
+#include "SYS.h"
+
+ENTRY(__setjmp)
+.weak setjmp;
+.set setjmp, __setjmp;
+ movl 4(%esp),%ecx
+ PIC_PROLOGUE
+ leal 28(%ecx), %eax
+ pushl %eax /* (sigset_t*)oset */
+ pushl $0 /* (sigset_t*)set */
+ pushl $1 /* SIG_BLOCK */
+#ifdef _THREAD_SAFE
+ call PIC_PLT(CNAME(_thread_sys_sigprocmask))
+#else
+ call PIC_PLT(CNAME(sigprocmask))
+#endif
+ addl $12,%esp
+ PIC_EPILOGUE
+ movl 4(%esp),%ecx
+ movl 0(%esp),%edx
+ movl %edx, 0(%ecx)
+ movl %ebx, 4(%ecx)
+ movl %esp, 8(%ecx)
+ movl %ebp,12(%ecx)
+ movl %esi,16(%ecx)
+ movl %edi,20(%ecx)
+ fnstcw 24(%ecx)
+ xorl %eax,%eax
+ ret
+
+ENTRY(__longjmp)
+.weak longjmp;
+.set longjmp, __longjmp;
+ movl 4(%esp),%edx
+ PIC_PROLOGUE
+ pushl $0 /* (sigset_t*)oset */
+ leal 28(%edx), %eax
+ pushl %eax /* (sigset_t*)set */
+ pushl $3 /* SIG_SETMASK */
+#ifdef _THREAD_SAFE
+ call PIC_PLT(CNAME(_thread_sys_sigprocmask))
+#else
+ call PIC_PLT(CNAME(sigprocmask))
+#endif
+ addl $12,%esp
+ PIC_EPILOGUE
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ movl 0(%edx),%ecx
+ movl 4(%edx),%ebx
+ movl 8(%edx),%esp
+ movl 12(%edx),%ebp
+ movl 16(%edx),%esi
+ movl 20(%edx),%edi
+ fninit
+ fldcw 24(%edx)
+ testl %eax,%eax
+ jnz 1f
+ incl %eax
+1: movl %ecx,0(%esp)
+ ret
diff --git a/lib/libc/amd64/gen/sigsetjmp.S b/lib/libc/amd64/gen/sigsetjmp.S
new file mode 100644
index 0000000..22cf790
--- /dev/null
+++ b/lib/libc/amd64/gen/sigsetjmp.S
@@ -0,0 +1,126 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+#include "SYS.h"
+
+/*-
+ * TODO:
+ * Rename sigsetjmp to __sigsetjmp and siglongjmp to __siglongjmp,
+ * remove the other *jmp functions and define everything in terms
+ * of the renamed functions. This requires compiler support for
+ * the renamed functions (introduced in gcc-2.5.3; previous versions
+ * only supported *jmp with 0 or 1 leading underscores).
+ *
+ * Use sigprocmask() instead of sigblock() and sigsetmask(), and
+ * check for and handle errors.
+ *
+ * Restore _all_ the registers and the signal mask atomically. Can
+ * use sigreturn() if sigreturn() works.
+ */
+
+ENTRY(__sigsetjmp)
+.weak sigsetjmp;
+.set sigsetjmp, __sigsetjmp;
+ movl 8(%esp),%eax
+ movl 4(%esp),%ecx
+ movl %eax,44(%ecx)
+ testl %eax,%eax
+ jz 2f
+ PIC_PROLOGUE
+ leal 28(%ecx), %eax
+ pushl %eax /* (sigset_t*)oset */
+ pushl $0 /* (sigset_t*)set */
+ pushl $1 /* SIG_BLOCK */
+#ifdef _THREAD_SAFE
+ call PIC_PLT(CNAME(_thread_sys_sigprocmask))
+#else
+ call PIC_PLT(CNAME(sigprocmask))
+#endif
+ addl $12,%esp
+ PIC_EPILOGUE
+ movl 4(%esp),%ecx
+2: movl 0(%esp),%edx
+ movl %edx, 0(%ecx)
+ movl %ebx, 4(%ecx)
+ movl %esp, 8(%ecx)
+ movl %ebp,12(%ecx)
+ movl %esi,16(%ecx)
+ movl %edi,20(%ecx)
+ fnstcw 24(%ecx)
+ xorl %eax,%eax
+ ret
+
+ENTRY(__siglongjmp)
+.weak siglongjmp;
+.set siglongjmp, __siglongjmp;
+ movl 4(%esp),%edx
+ cmpl $0,44(%edx)
+ jz 2f
+ PIC_PROLOGUE
+ pushl $0 /* (sigset_t*)oset */
+ leal 28(%edx), %eax
+ pushl %eax /* (sigset_t*)set */
+ pushl $3 /* SIG_SETMASK */
+#ifdef _THREAD_SAFE
+ call PIC_PLT(CNAME(_thread_sys_sigprocmask))
+#else
+ call PIC_PLT(CNAME(sigprocmask))
+#endif
+ addl $12,%esp
+ PIC_EPILOGUE
+ movl 4(%esp),%edx
+2: movl 8(%esp),%eax
+ movl 0(%edx),%ecx
+ movl 4(%edx),%ebx
+ movl 8(%edx),%esp
+ movl 12(%edx),%ebp
+ movl 16(%edx),%esi
+ movl 20(%edx),%edi
+ fninit
+ fldcw 24(%edx)
+ testl %eax,%eax
+ jnz 1f
+ incl %eax
+1: movl %ecx,0(%esp)
+ ret
diff --git a/lib/libc/amd64/net/Makefile.inc b/lib/libc/amd64/net/Makefile.inc
new file mode 100644
index 0000000..96e559b
--- /dev/null
+++ b/lib/libc/amd64/net/Makefile.inc
@@ -0,0 +1,4 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+SRCS+= htonl.S htons.S ntohl.S ntohs.S
diff --git a/lib/libc/amd64/net/htonl.S b/lib/libc/amd64/net/htonl.S
new file mode 100644
index 0000000..48f1ca8
--- /dev/null
+++ b/lib/libc/amd64/net/htonl.S
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/* netorder = htonl(hostorder) */
+
+#include "DEFS.h"
+
+ENTRY(htonl)
+ movl 4(%esp),%eax
+ xchgb %al,%ah
+ roll $16,%eax
+ xchgb %al,%ah
+ ret
diff --git a/lib/libc/amd64/net/htons.S b/lib/libc/amd64/net/htons.S
new file mode 100644
index 0000000..68f2b5a
--- /dev/null
+++ b/lib/libc/amd64/net/htons.S
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/* netorder = htons(hostorder) */
+
+#include "DEFS.h"
+
+ENTRY(htons)
+ movzwl 4(%esp),%eax
+ xchgb %al,%ah
+ ret
diff --git a/lib/libc/amd64/net/ntohl.S b/lib/libc/amd64/net/ntohl.S
new file mode 100644
index 0000000..7be9dee
--- /dev/null
+++ b/lib/libc/amd64/net/ntohl.S
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/* hostorder = ntohl(netorder) */
+
+#include "DEFS.h"
+
+ENTRY(ntohl)
+ movl 4(%esp),%eax
+ xchgb %al,%ah
+ roll $16,%eax
+ xchgb %al,%ah
+ ret
diff --git a/lib/libc/amd64/net/ntohs.S b/lib/libc/amd64/net/ntohs.S
new file mode 100644
index 0000000..0f1d228
--- /dev/null
+++ b/lib/libc/amd64/net/ntohs.S
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/* hostorder = ntohs(netorder) */
+
+#include "DEFS.h"
+
+ENTRY(ntohs)
+ movzwl 4(%esp),%eax
+ xchgb %al,%ah
+ ret
diff --git a/lib/libc/amd64/sys/Makefile.inc b/lib/libc/amd64/sys/Makefile.inc
new file mode 100644
index 0000000..c1c3d2d
--- /dev/null
+++ b/lib/libc/amd64/sys/Makefile.inc
@@ -0,0 +1,28 @@
+# from: Makefile.inc,v 1.1 1993/09/03 19:04:23 jtc Exp
+# $FreeBSD$
+
+SRCS+= i386_get_ioperm.c i386_get_ldt.c i386_set_ioperm.c i386_set_ldt.c \
+ i386_vm86.c
+
+MDASM= Ovfork.S brk.S cerror.S exect.S fork.S pipe.S ptrace.S reboot.S \
+ rfork.S sbrk.S setlogin.S sigreturn.S syscall.S
+
+# Don't generate default code for these syscalls:
+NOASM= __semctl.o break.o exit.o ftruncate.o getdomainname.o getlogin.o \
+ lseek.o mlockall.o mmap.o msgctl.o msgget.o msgrcv.o msgsnd.o \
+ munlockall.o openbsd_poll.o pread.o pwrite.o semconfig.o semget.o \
+ semop.o setdomainname.o shmat.o shmctl.o shmdt.o shmget.o sstk.o \
+ thr_sleep.o thr_wakeup.o truncate.o uname.o vfork.o yield.o
+
+PSEUDO= _getlogin.o
+
+# Pseudo syscalls that are renamed as _thread_sys_{pseudo} when
+# building libc_r.
+PSEUDOR= _exit.o
+
+.if ${LIB} == "c"
+MAN2+= i386_get_ioperm.2 i386_get_ldt.2 i386_vm86.2
+
+MLINKS+=i386_get_ioperm.2 i386_set_ioperm.2
+MLINKS+=i386_get_ldt.2 i386_set_ldt.2
+.endif
diff --git a/lib/libc/amd64/sys/brk.S b/lib/libc/amd64/sys/brk.S
new file mode 100644
index 0000000..5726675
--- /dev/null
+++ b/lib/libc/amd64/sys/brk.S
@@ -0,0 +1,91 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ .globl HIDENAME(curbrk)
+ .globl HIDENAME(minbrk)
+ENTRY(_brk)
+ jmp ok
+
+ENTRY(brk)
+#ifdef PIC
+ movl 4(%esp),%eax
+ PIC_PROLOGUE
+ movl PIC_GOT(HIDENAME(curbrk)),%edx # set up GOT addressing
+ movl PIC_GOT(HIDENAME(minbrk)),%ecx #
+ PIC_EPILOGUE
+ cmpl %eax,(%ecx)
+ jbe ok
+ movl (%ecx),%eax
+ movl %eax,4(%esp)
+ok:
+ lea SYS_break,%eax
+ KERNCALL
+ jb err
+ movl 4(%esp),%eax
+ movl %eax,(%edx)
+ movl $0,%eax
+ ret
+err:
+ PIC_PROLOGUE
+ jmp PIC_PLT(HIDENAME(cerror))
+
+#else
+
+ movl 4(%esp),%eax
+ cmpl %eax,HIDENAME(minbrk)
+ jbe ok
+ movl HIDENAME(minbrk),%eax
+ movl %eax,4(%esp)
+ok:
+ lea SYS_break,%eax
+ KERNCALL
+ jb err
+ movl 4(%esp),%eax
+ movl %eax,HIDENAME(curbrk)
+ movl $0,%eax
+ ret
+err:
+ jmp HIDENAME(cerror)
+#endif
diff --git a/lib/libc/amd64/sys/cerror.S b/lib/libc/amd64/sys/cerror.S
new file mode 100644
index 0000000..31c3622
--- /dev/null
+++ b/lib/libc/amd64/sys/cerror.S
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ .globl HIDENAME(cerror)
+
+ /*
+ * The __error() function is thread aware. For non-threaded
+ * programs and the initial threaded in threaded programs,
+ * it returns a pointer to the global errno variable.
+ */
+ .globl CNAME(__error)
+ .type CNAME(__error),@function
+HIDENAME(cerror):
+ pushl %eax
+#ifdef PIC
+ /* The caller must execute the PIC prologue before jumping to cerror. */
+ call PIC_PLT(CNAME(__error))
+ popl %ecx
+ PIC_EPILOGUE
+#else
+ call CNAME(__error)
+ popl %ecx
+#endif
+ movl %ecx,(%eax)
+ movl $-1,%eax
+ movl $-1,%edx
+ ret
+
diff --git a/lib/libc/amd64/sys/exect.S b/lib/libc/amd64/sys/exect.S
new file mode 100644
index 0000000..9f90060
--- /dev/null
+++ b/lib/libc/amd64/sys/exect.S
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+#include <machine/psl.h>
+
+ENTRY(exect)
+ lea SYS_execve,%eax
+ pushf
+ popl %edx
+ orl $ PSL_T,%edx
+ pushl %edx
+ popf
+ KERNCALL
+ PIC_PROLOGUE
+ jmp PIC_PLT(HIDENAME(cerror)) /* exect(file, argv, env); */
diff --git a/lib/libc/amd64/sys/pipe.S b/lib/libc/amd64/sys/pipe.S
new file mode 100644
index 0000000..1684611
--- /dev/null
+++ b/lib/libc/amd64/sys/pipe.S
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+PSYSCALL(pipe)
+ movl 4(%esp),%ecx
+ movl %eax,(%ecx)
+ movl %edx,4(%ecx)
+ movl $0,%eax
+ ret
diff --git a/lib/libc/amd64/sys/ptrace.S b/lib/libc/amd64/sys/ptrace.S
new file mode 100644
index 0000000..7f5e149
--- /dev/null
+++ b/lib/libc/amd64/sys/ptrace.S
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ENTRY(ptrace)
+ xorl %eax,%eax
+#ifdef PIC
+ PIC_PROLOGUE
+ movl PIC_GOT(CNAME(errno)),%edx
+ movl %eax,(%edx)
+ PIC_EPILOGUE
+#else
+ movl %eax,CNAME(errno)
+#endif
+ lea SYS_ptrace,%eax
+ KERNCALL
+ jb err
+ ret
+err:
+ PIC_PROLOGUE
+ jmp PIC_PLT(HIDENAME(cerror))
diff --git a/lib/libc/amd64/sys/reboot.S b/lib/libc/amd64/sys/reboot.S
new file mode 100644
index 0000000..4e39068
--- /dev/null
+++ b/lib/libc/amd64/sys/reboot.S
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+SYSCALL(reboot)
+ iret
diff --git a/lib/libc/amd64/sys/sbrk.S b/lib/libc/amd64/sys/sbrk.S
new file mode 100644
index 0000000..f7aae35
--- /dev/null
+++ b/lib/libc/amd64/sys/sbrk.S
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ .globl CNAME(end)
+ .globl HIDENAME(minbrk)
+ .globl HIDENAME(curbrk)
+
+ .data
+HIDENAME(minbrk): .long CNAME(end)
+HIDENAME(curbrk): .long CNAME(end)
+ .text
+
+ENTRY(sbrk)
+#ifdef PIC
+ movl 4(%esp),%ecx
+ PIC_PROLOGUE
+ movl PIC_GOT(HIDENAME(curbrk)),%edx
+ movl (%edx),%eax
+ PIC_EPILOGUE
+ testl %ecx,%ecx
+ jz back
+ addl %eax,4(%esp)
+ lea SYS_break,%eax
+ KERNCALL
+ jb err
+ PIC_PROLOGUE
+ movl PIC_GOT(HIDENAME(curbrk)),%edx
+ movl (%edx),%eax
+ addl %ecx,(%edx)
+ PIC_EPILOGUE
+back:
+ ret
+err:
+ PIC_PROLOGUE
+ jmp PIC_PLT(HIDENAME(cerror))
+
+#else /* !PIC */
+
+ movl 4(%esp),%ecx
+ movl HIDENAME(curbrk),%eax
+ testl %ecx,%ecx
+ jz back
+ addl %eax,4(%esp)
+ lea SYS_break,%eax
+ KERNCALL
+ jb err
+ movl HIDENAME(curbrk),%eax
+ addl %ecx,HIDENAME(curbrk)
+back:
+ ret
+err:
+ jmp HIDENAME(cerror)
+#endif /* PIC */
diff --git a/lib/libc/amd64/sys/setlogin.S b/lib/libc/amd64/sys/setlogin.S
new file mode 100644
index 0000000..a4d74b0
--- /dev/null
+++ b/lib/libc/amd64/sys/setlogin.S
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "SYS.h"
+
+.globl CNAME(_logname_valid) /* in getlogin() */
+
+SYSCALL(setlogin)
+#ifdef PIC
+ PIC_PROLOGUE
+ pushl %eax
+ movl PIC_GOT(CNAME(_logname_valid)),%eax
+ movl $0,(%eax)
+ popl %eax
+ PIC_EPILOGUE
+#else
+ movl $0,CNAME(_logname_valid)
+#endif
+ ret /* setlogin(name) */
diff --git a/lib/libc/amd64/sys/sigreturn.S b/lib/libc/amd64/sys/sigreturn.S
new file mode 100644
index 0000000..7405c34
--- /dev/null
+++ b/lib/libc/amd64/sys/sigreturn.S
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+/*
+ * NOTE: If the profiling ENTRY() code ever changes any registers, they
+ * must be saved. On FreeBSD, this is not the case.
+ */
+
+PSYSCALL(sigreturn)
+ ret
diff --git a/lib/libc/amd64/sys/vfork.S b/lib/libc/amd64/sys/vfork.S
new file mode 100644
index 0000000..30d7fd1
--- /dev/null
+++ b/lib/libc/amd64/sys/vfork.S
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "DEFS.h"
+#include "SYS.h"
+
+/*
+ * pid = vfork();
+ *
+ * %edx == 0 in parent process, %edx == 1 in child process.
+ * %eax == pid of child in parent, %eax == pid of parent in child.
+ *
+ */
+
+#ifdef _THREAD_SAFE
+ENTRY(_thread_sys_vfork)
+#else
+ENTRY(vfork)
+#endif
+ popl %ecx /* my rta into ecx */
+ lea SYS_vfork,%eax
+ KERNCALL
+ jb 2f
+ cmpl $0,%edx /* parent process? */
+ je 1f /* yes */
+ movl $0,%eax
+1:
+ jmp %ecx
+2:
+ pushl %ecx
+ PIC_PROLOGUE
+ jmp PIC_PLT(HIDENAME(cerror))
diff --git a/lib/libc/compat-43/Makefile.inc b/lib/libc/compat-43/Makefile.inc
new file mode 100644
index 0000000..e901882
--- /dev/null
+++ b/lib/libc/compat-43/Makefile.inc
@@ -0,0 +1,16 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/2/93
+# $FreeBSD$
+
+# compat-43 sources
+.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/compat-43 ${.CURDIR}/../libc/compat-43
+
+SRCS+= creat.c gethostid.c getwd.c killpg.c sethostid.c setpgrp.c \
+ setrgid.c setruid.c sigcompat.c
+
+.if ${LIB} == "c"
+MAN2+= creat.2 killpg.2 sigblock.2 sigpause.2 sigsetmask.2 sigvec.2
+MAN3+= gethostid.3 setruid.3
+
+MLINKS+=gethostid.3 sethostid.3
+MLINKS+=setruid.3 setrgid.3
+.endif
diff --git a/lib/libc/compat-43/creat.2 b/lib/libc/compat-43/creat.2
new file mode 100644
index 0000000..7e9f099
--- /dev/null
+++ b/lib/libc/compat-43/creat.2
@@ -0,0 +1,62 @@
+.\" Copyright (c) 1989, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)creat.2 8.1 (Berkeley) 6/2/93
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1993
+.Dt CREAT 2
+.Os BSD 4
+.Sh NAME
+.Nm creat
+.Nd create a new file
+.Sh SYNOPSIS
+.Fd #include <fcntl.h>
+.Ft int
+.Fn creat "const char *path" "mode_t mode"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is made obsolete by:
+.Ef
+.Xr open 2 .
+.Pp
+.Fn Creat
+is the same as:
+.Bd -literal -offset indent
+open(path, O_CREAT | O_TRUNC | O_WRONLY, mode);
+.Ed
+.Sh SEE ALSO
+.Xr open 2
+.Sh HISTORY
+The
+.Fn creat
+function call appeared in
+.At v6 .
diff --git a/lib/libc/compat-43/creat.c b/lib/libc/compat-43/creat.c
new file mode 100644
index 0000000..a4f1234
--- /dev/null
+++ b/lib/libc/compat-43/creat.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)creat.c 8.1 (Berkeley) 6/2/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <fcntl.h>
+
+int
+#if __STDC__
+creat(const char *path, mode_t mode)
+#else
+creat(path, mode)
+ char *path;
+ mode_t mode;
+#endif
+{
+ return(open(path, O_WRONLY|O_CREAT|O_TRUNC, mode));
+}
diff --git a/lib/libc/compat-43/gethostid.3 b/lib/libc/compat-43/gethostid.3
new file mode 100644
index 0000000..df3644c
--- /dev/null
+++ b/lib/libc/compat-43/gethostid.3
@@ -0,0 +1,76 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)gethostid.3 8.1 (Berkeley) 6/2/93
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1993
+.Dt GETHOSTID 3
+.Os BSD 4.2
+.Sh NAME
+.Nm gethostid ,
+.Nm sethostid
+.Nd get/set unique identifier of current host
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft long
+.Fn gethostid void
+.Ft void
+.Fn sethostid "long hostid"
+.Sh DESCRIPTION
+.Fn Sethostid
+establishes a 32-bit identifier for the
+current processor that is intended to be unique among all
+UNIX systems in existence. This is normally a DARPA Internet
+address for the local machine. This call is allowed only to the
+super-user and is normally performed at boot time.
+.Pp
+.Fn Gethostid
+returns the 32-bit identifier for the current processor.
+.Pp
+This function has been deprecated.
+The hostid should be set or retrieved by use of
+.Xr sysctl 3 .
+.Sh SEE ALSO
+.Xr gethostname 3 ,
+.Xr sysctl 3 ,
+.Xr sysctl 8 .
+.Sh BUGS
+32 bits for the identifier is too small.
+.Sh HISTORY
+The
+.Fn gethostid
+and
+.Fn sethostid
+syscalls appeared in
+.Bx 4.2
+and were dropped in
+.Bx 4.4 .
diff --git a/lib/libc/compat-43/gethostid.c b/lib/libc/compat-43/gethostid.c
new file mode 100644
index 0000000..c4caff6
--- /dev/null
+++ b/lib/libc/compat-43/gethostid.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostid.c 8.1 (Berkeley) 6/2/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#if __STDC__
+long
+gethostid(void)
+#else
+long
+gethostid()
+#endif
+{
+ int mib[2];
+ size_t size;
+ long value;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_HOSTID;
+ size = sizeof value;
+ if (sysctl(mib, 2, &value, &size, NULL, 0) == -1)
+ return (-1);
+ return (value);
+}
diff --git a/lib/libc/compat-43/getwd.c b/lib/libc/compat-43/getwd.c
new file mode 100644
index 0000000..9f0e633
--- /dev/null
+++ b/lib/libc/compat-43/getwd.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getwd.c 8.1 (Berkeley) 6/2/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+char *
+getwd(buf)
+ char *buf;
+{
+ char *p;
+
+ if ( (p = getcwd(buf, MAXPATHLEN)) )
+ return(p);
+ (void)strcpy(buf, strerror(errno));
+ return((char *)NULL);
+}
diff --git a/lib/libc/compat-43/killpg.2 b/lib/libc/compat-43/killpg.2
new file mode 100644
index 0000000..365ab4b
--- /dev/null
+++ b/lib/libc/compat-43/killpg.2
@@ -0,0 +1,97 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)killpg.2 8.1 (Berkeley) 6/2/93
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1993
+.Dt KILLPG 2
+.Os BSD 4
+.Sh NAME
+.Nm killpg
+.Nd send signal to a process group
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <signal.h>
+.Ft int
+.Fn killpg "pid_t pgrp" "int sig"
+.Sh DESCRIPTION
+.Fn Killpg
+sends the signal
+.Fa sig
+to the process group
+.Fa pgrp .
+See
+.Xr sigaction 2
+for a list of signals.
+If
+.Fa pgrp
+is 0,
+.Fn killpg
+sends the signal to the sending process's process group.
+.Pp
+The sending process and members of the process group must
+have the same effective user ID, or
+the sender must be the super-user.
+As a single special case the continue signal SIGCONT may be sent
+to any process that is a descendant of the current process.
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned. Otherwise,
+a value of -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Killpg
+will fail and no signal will be sent if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+.Fa Sig
+is not a valid signal number.
+.It Bq Er ESRCH
+No process can be found in the process group specified by
+.Fa pgrp .
+.It Bq Er ESRCH
+The process group was given as 0
+but the sending process does not have a process group.
+.It Bq Er EPERM
+The sending process is not the super-user and one or more
+of the target processes has an effective user ID different from that
+of the sending process.
+.El
+.Sh SEE ALSO
+.Xr getpgrp 2 ,
+.Xr kill 2 ,
+.Xr sigaction 2
+.Sh HISTORY
+The
+.Fn killpg
+function call appeared in
+.Bx 4.0 .
diff --git a/lib/libc/compat-43/killpg.c b/lib/libc/compat-43/killpg.c
new file mode 100644
index 0000000..ac3ba6e
--- /dev/null
+++ b/lib/libc/compat-43/killpg.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)killpg.c 8.1 (Berkeley) 6/2/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <signal.h>
+#include <errno.h>
+
+/*
+ * Backwards-compatible killpg().
+ */
+int
+#if __STDC__
+killpg(pid_t pgid, int sig)
+#else
+killpg(pgid, sig)
+ pid_t pgid;
+ int sig;
+#endif
+{
+ if (pgid == 1) {
+ errno = ESRCH;
+ return (-1);
+ }
+ return (kill(-pgid, sig));
+}
diff --git a/lib/libc/compat-43/sethostid.c b/lib/libc/compat-43/sethostid.c
new file mode 100644
index 0000000..8122c81
--- /dev/null
+++ b/lib/libc/compat-43/sethostid.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)sethostid.c 8.1 (Berkeley) 6/2/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#if __STDC__
+long
+sethostid(long hostid)
+#else
+long
+sethostid(hostid)
+ long hostid;
+#endif
+{
+ int mib[2];
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_HOSTID;
+ if (sysctl(mib, 2, NULL, NULL, &hostid, sizeof hostid) == -1)
+ return (-1);
+ return (0);
+}
diff --git a/lib/libc/compat-43/setpgrp.c b/lib/libc/compat-43/setpgrp.c
new file mode 100644
index 0000000..dc0dd3f
--- /dev/null
+++ b/lib/libc/compat-43/setpgrp.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setpgrp.c 8.1 (Berkeley) 6/2/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <unistd.h>
+
+int
+#if __STDC__
+setpgrp(pid_t pid, pid_t pgid)
+#else
+setpgrp(pid, pgid)
+ pid_t pid, pgid;
+#endif
+{
+ return(setpgid(pid, pgid));
+}
diff --git a/lib/libc/compat-43/setrgid.c b/lib/libc/compat-43/setrgid.c
new file mode 100644
index 0000000..1d86642
--- /dev/null
+++ b/lib/libc/compat-43/setrgid.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setrgid.c 8.1 (Berkeley) 6/2/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <unistd.h>
+
+int
+#ifdef __STDC__
+setrgid(gid_t rgid)
+#else
+setrgid(rgid)
+ int rgid;
+#endif
+{
+
+ return (setregid(rgid, -1));
+}
diff --git a/lib/libc/compat-43/setruid.3 b/lib/libc/compat-43/setruid.3
new file mode 100644
index 0000000..843a59f
--- /dev/null
+++ b/lib/libc/compat-43/setruid.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)setruid.3 8.1 (Berkeley) 6/2/93
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1993
+.Dt SETRUID 3
+.Os BSD 4.2
+.Sh NAME
+.Nm setruid ,
+.Nm setrgid
+.Nd set user and group ID
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn setruid "uid_t ruid"
+.Ft int
+.Fn setrgid "gid_t rgid"
+.Sh DESCRIPTION
+The
+.Fn setruid
+function
+.Pq Fn setrgid
+sets the real user ID (group ID) of the
+current process.
+.Sh RETURN VALUES
+Upon success, these functions return 0;
+otherwise \-1 is returned.
+.Pp
+If the user is not the super user, or the uid
+specified is not the real or effective ID, these
+functions return \-1.
+.Pp
+The use of these calls is not portable.
+Their use is discouraged; they will be removed in the future.
+.Sh SEE ALSO
+.Xr getgid 2 ,
+.Xr getuid 2 ,
+.Xr setegid 2 ,
+.Xr seteuid 2 ,
+.Xr setgid 2 ,
+.Xr setuid 2
+.Sh HISTORY
+The
+.Fn setruid
+and
+.Fn setrgid
+syscalls appeared in
+.Bx 4.2
+and were dropped in
+.Bx 4.4 .
diff --git a/lib/libc/compat-43/setruid.c b/lib/libc/compat-43/setruid.c
new file mode 100644
index 0000000..1551abb
--- /dev/null
+++ b/lib/libc/compat-43/setruid.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setruid.c 8.1 (Berkeley) 6/2/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <unistd.h>
+
+int
+#ifdef __STDC__
+setruid(uid_t ruid)
+#else
+setruid(ruid)
+ int ruid;
+#endif
+{
+
+ return (setreuid(ruid, -1));
+}
diff --git a/lib/libc/compat-43/sigblock.2 b/lib/libc/compat-43/sigblock.2
new file mode 100644
index 0000000..f7809b8
--- /dev/null
+++ b/lib/libc/compat-43/sigblock.2
@@ -0,0 +1,85 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sigblock.2 8.1 (Berkeley) 6/2/93
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1993
+.Dt SIGBLOCK 2
+.Os BSD 4.2
+.Sh NAME
+.Nm sigblock
+.Nd block signals
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Ft int
+.Fn sigblock "int mask"
+.Ft int
+.Fn sigmask signum
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is made obsolete by:
+.Ef
+.Xr sigprocmask 2 .
+.Pp
+.Fn Sigblock
+adds the signals specified in
+.Fa mask
+to the set of signals currently
+being blocked from delivery.
+Signals are blocked if the
+corresponding bit in
+.Fa mask
+is a 1; the macro
+.Fn sigmask
+is provided to construct the mask for a given
+.Fa signum .
+.Pp
+It is not possible to block
+.Dv SIGKILL
+or
+.Dv SIGSTOP ;
+this restriction is silently
+imposed by the system.
+.Sh RETURN VALUES
+The previous set of masked signals is returned.
+.Sh SEE ALSO
+.Xr kill 2 ,
+.Xr sigaction 2 ,
+.Xr sigprocmask 2 ,
+.Xr sigsetmask 2 ,
+.Xr sigsetops 3
+.Sh HISTORY
+The
+.Fn sigblock
+function call appeared in
+.Bx 4.2
+and has been deprecated.
diff --git a/lib/libc/compat-43/sigcompat.c b/lib/libc/compat-43/sigcompat.c
new file mode 100644
index 0000000..0a870a7
--- /dev/null
+++ b/lib/libc/compat-43/sigcompat.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)sigcompat.c 8.1 (Berkeley) 6/2/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <signal.h>
+
+int
+sigvec(signo, sv, osv)
+ int signo;
+ struct sigvec *sv, *osv;
+{
+ struct sigaction sa, osa;
+ struct sigaction *sap, *osap;
+ int ret;
+
+ if (sv != NULL) {
+ sa.sa_handler = sv->sv_handler;
+ sa.sa_flags = sv->sv_flags ^ SV_INTERRUPT;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_mask.__bits[0] = sv->sv_mask;
+ sap = &sa;
+ } else
+ sap = NULL;
+ osap = osv != NULL ? &osa : NULL;
+ ret = sigaction(signo, sap, osap);
+ if (ret == 0 && osv != NULL) {
+ osv->sv_handler = osa.sa_handler;
+ osv->sv_flags = osa.sa_flags ^ SV_INTERRUPT;
+ osv->sv_mask = osa.sa_mask.__bits[0];
+ }
+ return (ret);
+}
+
+int
+sigsetmask(mask)
+ int mask;
+{
+ sigset_t set, oset;
+ int n;
+
+ sigemptyset(&set);
+ set.__bits[0] = mask;
+ n = sigprocmask(SIG_SETMASK, &set, &oset);
+ if (n)
+ return (n);
+ return (oset.__bits[0]);
+}
+
+int
+sigblock(mask)
+ int mask;
+{
+ sigset_t set, oset;
+ int n;
+
+ sigemptyset(&set);
+ set.__bits[0] = mask;
+ n = sigprocmask(SIG_BLOCK, &set, &oset);
+ if (n)
+ return (n);
+ return (oset.__bits[0]);
+}
+
+int
+sigpause(mask)
+ int mask;
+{
+ sigset_t set;
+
+ sigemptyset(&set);
+ set.__bits[0] = mask;
+ return (sigsuspend(&set));
+}
diff --git a/lib/libc/compat-43/sigpause.2 b/lib/libc/compat-43/sigpause.2
new file mode 100644
index 0000000..166fda3
--- /dev/null
+++ b/lib/libc/compat-43/sigpause.2
@@ -0,0 +1,75 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sigpause.2 8.1 (Berkeley) 6/2/93
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1993
+.Dt SIGPAUSE 2
+.Os BSD 4
+.Sh NAME
+.Nm sigpause
+.Nd atomically release blocked signals and wait for interrupt
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Ft int
+.Fn sigpause "int sigmask"
+.Sh DESCRIPTION
+.Sy This interface is made obsolete by
+.Xr sigsuspend 2 .
+.Pp
+.Fn Sigpause
+assigns
+.Fa sigmask
+to the set of masked signals
+and then waits for a signal to arrive;
+on return the set of masked signals is restored.
+.Fa Sigmask
+is usually 0 to indicate that no
+signals are to be blocked.
+.Fn Sigpause
+always terminates by being interrupted, returning -1 with
+.Va errno
+set to
+.Dv EINTR
+.Sh SEE ALSO
+.Xr kill 2 ,
+.Xr sigaction 2 ,
+.Xr sigblock 2 ,
+.Xr sigprocmask 2 ,
+.Xr sigsuspend 2 ,
+.Xr sigvec 2
+.Sh HISTORY
+The
+.Fn sigpause
+function call appeared in
+.Bx 4.2
+and has been deprecated.
diff --git a/lib/libc/compat-43/sigsetmask.2 b/lib/libc/compat-43/sigsetmask.2
new file mode 100644
index 0000000..ff1283d
--- /dev/null
+++ b/lib/libc/compat-43/sigsetmask.2
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sigsetmask.2 8.1 (Berkeley) 6/2/93
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1993
+.Dt SIGSETMASK 2
+.Os BSD 4.2
+.Sh NAME
+.Nm sigsetmask
+.Nd set current signal mask
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Ft int
+.Fn sigsetmask "int mask"
+.Fn sigmask signum
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is made obsoleted by:
+.Ef
+.Xr sigprocmask 2 .
+.Pp
+.Fn Sigsetmask
+sets the current signal mask. Signals
+are blocked from delivery if the
+corresponding bit in
+.Fa mask
+is a 1; the macro
+.Fn sigmask
+is provided to construct the mask for a given
+.Fa signum .
+.Pp
+The system
+quietly disallows
+.Dv SIGKILL
+or
+.Dv SIGSTOP
+to be blocked.
+.Sh RETURN VALUES
+The previous set of masked signals is returned.
+.Sh SEE ALSO
+.Xr kill 2 ,
+.Xr sigaction 2 ,
+.Xr sigblock 2 ,
+.Xr sigprocmask 2 ,
+.Xr sigsuspend 2 ,
+.Xr sigvec 2 ,
+.Xr sigsetops 3
+.Sh HISTORY
+The
+.Fn sigsetmask
+function call appeared in
+.Bx 4.2
+and has been deprecated.
diff --git a/lib/libc/compat-43/sigvec.2 b/lib/libc/compat-43/sigvec.2
new file mode 100644
index 0000000..f144efa
--- /dev/null
+++ b/lib/libc/compat-43/sigvec.2
@@ -0,0 +1,327 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sigvec.2 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt SIGVEC 2
+.Os BSD 4
+.Sh NAME
+.Nm sigvec
+.Nd software signal facilities
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Bd -literal
+struct sigvec {
+ void (*sv_handler)();
+ int sv_mask;
+ int sv_flags;
+};
+.Ed
+.Ft int
+.Fn sigvec "int sig" "struct sigvec *vec" "struct sigvec *ovec"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is made obsolete by sigaction(2).
+.Ef
+.Pp
+The system defines a set of signals that may be delivered to a process.
+Signal delivery resembles the occurrence of a hardware interrupt:
+the signal is blocked from further occurrence, the current process
+context is saved, and a new one is built. A process may specify a
+.Em handler
+to which a signal is delivered, or specify that a signal is to be
+.Em blocked
+or
+.Em ignored .
+A process may also specify that a default action is to be taken
+by the system when a signal occurs.
+Normally, signal handlers execute on the current stack
+of the process. This may be changed, on a per-handler basis,
+so that signals are taken on a special
+.Em "signal stack" .
+.Pp
+All signals have the same
+.Em priority .
+Signal routines execute with the signal that caused their
+invocation
+.Em blocked ,
+but other signals may yet occur.
+A global
+.Em "signal mask"
+defines the set of signals currently blocked from delivery
+to a process. The signal mask for a process is initialized
+from that of its parent (normally 0). It
+may be changed with a
+.Xr sigblock 2
+or
+.Xr sigsetmask 2
+call, or when a signal is delivered to the process.
+.Pp
+When a signal
+condition arises for a process, the signal is added to a set of
+signals pending for the process. If the signal is not currently
+.Em blocked
+by the process then it is delivered to the process. When a signal
+is delivered, the current state of the process is saved,
+a new signal mask is calculated (as described below),
+and the signal handler is invoked. The call to the handler
+is arranged so that if the signal handling routine returns
+normally the process will resume execution in the context
+from before the signal's delivery.
+If the process wishes to resume in a different context, then it
+must arrange to restore the previous context itself.
+.Pp
+When a signal is delivered to a process a new signal mask is
+installed for the duration of the process' signal handler
+(or until a
+.Xr sigblock 2
+or
+.Xr sigsetmask 2
+call is made).
+This mask is formed by taking the current signal mask,
+adding the signal to be delivered, and
+.Em or Ns 'ing
+in the signal mask associated with the handler to be invoked.
+.Pp
+.Fn Sigvec
+assigns a handler for a specific signal. If
+.Fa vec
+is non-zero, it
+specifies a handler routine and mask
+to be used when delivering the specified signal.
+Further, if the
+.Dv SV_ONSTACK
+bit is set in
+.Fa sv_flags ,
+the system will deliver the signal to the process on a
+.Em "signal stack" ,
+specified with
+.Xr sigaltstack 2 .
+If
+.Fa ovec
+is non-zero, the previous handling information for the signal
+is returned to the user.
+.Pp
+The following is a list of all signals
+with names as in the include file
+.Aq Pa signal.h :
+.Bl -column SIGVTALARMXX "create core imagexxx"
+.It Sy " NAME " " Default Action " " Description"
+.It Dv SIGHUP No " terminate process" " terminal line hangup"
+.It Dv SIGINT No " terminate process" " interrupt program"
+.It Dv SIGQUIT No " create core image" " quit program"
+.It Dv SIGILL No " create core image" " illegal instruction"
+.It Dv SIGTRAP No " create core image" " trace trap"
+.It Dv SIGABRT No " create core image" Xr abort 3
+call (formerly
+.Dv SIGIOT )
+.It Dv SIGEMT No " create core image" " emulate instruction executed"
+.It Dv SIGFPE No " create core image" " floating-point exception"
+.It Dv SIGKILL No " terminate process" " kill program"
+.It Dv SIGBUS No " create core image" " bus error"
+.It Dv SIGSEGV No " create core image" " segmentation violation"
+.It Dv SIGSYS No " create core image" " non-existent system call invoked"
+.It Dv SIGPIPE No " terminate process" " write on a pipe with no reader"
+.It Dv SIGALRM No " terminate process" " real-time timer expired"
+.It Dv SIGTERM No " terminate process" " software termination signal"
+.It Dv SIGURG No " discard signal" " urgent condition present on socket"
+.It Dv SIGSTOP No " stop process" " stop (cannot be caught or ignored)"
+.It Dv SIGTSTP No " stop process" " stop signal generated from keyboard"
+.It Dv SIGCONT No " discard signal" " continue after stop"
+.It Dv SIGCHLD No " discard signal" " child status has changed"
+.It Dv SIGTTIN No " stop process" " background read attempted from control terminal"
+.It Dv SIGTTOU No " stop process" " background write attempted to control terminal"
+.It Dv SIGIO No " discard signal" Tn " I/O"
+is possible on a descriptor (see
+.Xr fcntl 2 )
+.It Dv SIGXCPU No " terminate process" " cpu time limit exceeded (see"
+.Xr setrlimit 2 )
+.It Dv SIGXFSZ No " terminate process" " file size limit exceeded (see"
+.Xr setrlimit 2 )
+.It Dv SIGVTALRM No " terminate process" " virtual time alarm (see"
+.Xr setitimer 2 )
+.It Dv SIGPROF No " terminate process" " profiling timer alarm (see"
+.Xr setitimer 2 )
+.It Dv SIGWINCH No " discard signal" " Window size change"
+.It Dv SIGINFO No " discard signal" " status request from keyboard"
+.It Dv SIGUSR1 No " terminate process" " User defined signal 1"
+.It Dv SIGUSR2 No " terminate process" " User defined signal 2"
+.El
+.Pp
+Once a signal handler is installed, it remains installed
+until another
+.Fn sigvec
+call is made, or an
+.Xr execve 2
+is performed.
+A signal-specific default action may be reset by
+setting
+.Fa sv_handler
+to
+.Dv SIG_DFL .
+The defaults are process termination, possibly with core dump;
+no action; stopping the process; or continuing the process.
+See the above signal list for each signal's default action.
+If
+.Fa sv_handler
+is
+.Dv SIG_IGN
+current and pending instances
+of the signal are ignored and discarded.
+.Pp
+If a signal is caught during the system calls listed below,
+the call is normally restarted.
+The call can be forced to terminate prematurely with an
+.Dv EINTR
+error return by setting the
+.Dv SV_INTERRUPT
+bit in
+.Fa sv_flags .
+The affected system calls include
+.Xr read 2 ,
+.Xr write 2 ,
+.Xr sendto 2 ,
+.Xr recvfrom 2 ,
+.Xr sendmsg 2
+and
+.Xr recvmsg 2
+on a communications channel or a slow device (such as a terminal,
+but not a regular file)
+and during a
+.Xr wait 2
+or
+.Xr ioctl 2 .
+However, calls that have already committed are not restarted,
+but instead return a partial success (for example, a short read count).
+.Pp
+After a
+.Xr fork 2
+or
+.Xr vfork 2
+all signals, the signal mask, the signal stack,
+and the restart/interrupt flags are inherited by the child.
+.Pp
+.Xr Execve 2
+reinstates the default
+action for all signals which were caught and
+resets all signals to be caught on the user stack.
+Ignored signals remain ignored;
+the signal mask remains the same;
+signals that interrupt system calls continue to do so.
+.Sh NOTES
+The mask specified in
+.Fa vec
+is not allowed to block
+.Dv SIGKILL
+or
+.Dv SIGSTOP .
+This is done silently by the system.
+.Pp
+The
+.Dv SV_INTERRUPT
+flag is not available in
+.Bx 4.2 ,
+hence it should not be used if backward compatibility is needed.
+.Sh RETURN VALUES
+A 0 value indicated that the call succeeded. A \-1 return value
+indicates an error occurred and
+.Va errno
+is set to indicated the reason.
+.Sh ERRORS
+.Fn Sigvec
+will fail and no new signal handler will be installed if one
+of the following occurs:
+.Bl -tag -width [EINVAL]
+.It Bq Er EFAULT
+Either
+.Fa vec
+or
+.Fa ovec
+points to memory that is not a valid part of the process
+address space.
+.It Bq Er EINVAL
+.Fa Sig
+is not a valid signal number.
+.It Bq Er EINVAL
+An attempt is made to ignore or supply a handler for
+.Dv SIGKILL
+or
+.Dv SIGSTOP .
+.El
+.Sh SEE ALSO
+.Xr kill 1 ,
+.Xr kill 2 ,
+.Xr ptrace 2 ,
+.Xr sigaction 2 ,
+.Xr sigaltstack 2 ,
+.Xr sigblock 2 ,
+.Xr sigpause 2 ,
+.Xr sigprocmask 2 ,
+.Xr sigsetmask 2 ,
+.Xr sigsuspend 2 ,
+.Xr setjmp 3 ,
+.Xr siginterrupt 3 ,
+.Xr signal 3 ,
+.Xr sigsetops 3 ,
+.Xr tty 4
+.Sh EXAMPLE
+On the
+.Tn VAX\-11
+The handler routine can be declared:
+.Bd -literal -offset indent
+void handler(sig, code, scp)
+int sig, code;
+struct sigcontext *scp;
+.Ed
+.Pp
+Here
+.Fa sig
+is the signal number, into which the hardware faults and traps are
+mapped as defined below.
+.Fa Code
+is a parameter that is either a constant
+as given below or, for compatibility mode faults, the code provided by
+the hardware (Compatibility mode faults are distinguished from the
+other
+.Dv SIGILL
+traps by having
+.Dv PSL_CM
+set in the psl).
+.Fa Scp
+is a pointer to the
+.Fa sigcontext
+structure (defined in
+.Aq Pa signal.h ) ,
+used to restore the context from before the signal.
+.Sh BUGS
+This manual page is still confusing.
diff --git a/lib/libc/db/Makefile.inc b/lib/libc/db/Makefile.inc
new file mode 100644
index 0000000..8bd4dd6
--- /dev/null
+++ b/lib/libc/db/Makefile.inc
@@ -0,0 +1,11 @@
+# from @(#)Makefile.inc 8.2 (Berkeley) 2/21/94
+# $FreeBSD$
+#
+CFLAGS+=-D__DBINTERFACE_PRIVATE
+
+.include "${.CURDIR}/../libc/db/btree/Makefile.inc"
+.include "${.CURDIR}/../libc/db/db/Makefile.inc"
+.include "${.CURDIR}/../libc/db/hash/Makefile.inc"
+.include "${.CURDIR}/../libc/db/man/Makefile.inc"
+.include "${.CURDIR}/../libc/db/mpool/Makefile.inc"
+.include "${.CURDIR}/../libc/db/recno/Makefile.inc"
diff --git a/lib/libc/db/README b/lib/libc/db/README
new file mode 100644
index 0000000..bed2c92
--- /dev/null
+++ b/lib/libc/db/README
@@ -0,0 +1,40 @@
+# @(#)README 8.27 (Berkeley) 9/1/94
+
+This is version 1.85 of the Berkeley DB code.
+
+For information on compiling and installing this software, see the file
+PORT/README.
+
+Newer versions of this software will periodically be made available by
+anonymous ftp from ftp.cs.berkeley.edu. An archive in compressed format
+is in ucb/4bsd/db.tar.Z, or in gzip format in ucb/4bsd/db.tar.gz. If
+you'd like to receive announcements of future releases of this software,
+send email to the contact address below.
+
+Email questions may be addressed to Keith Bostic at bostic@cs.berkeley.edu.
+
+============================================
+Distribution contents:
+
+Makefile.inc Ignore this, it's the 4.4BSD subsystem Makefile.
+PORT The per OS/architecture directories to use to build
+ libdb.a, if you're not running 4.4BSD. See the file
+ PORT/README for more information.
+README This file.
+btree The B+tree routines.
+changelog List of changes, per version.
+db The dbopen(3) interface routine.
+docs Various USENIX papers, and the formatted manual pages.
+hash The extended linear hashing routines.
+man The unformatted manual pages.
+mpool The memory pool routines.
+recno The fixed/variable length record routines.
+test Test package.
+
+============================================
+Debugging:
+
+If you're running a memory checker (e.g. Purify) on DB, make sure that
+you recompile it with "-DPURIFY" in the CFLAGS, first. By default,
+allocated pages are not initialized by the DB code, and they will show
+up as reads of uninitialized memory in the buffer write routines.
diff --git a/lib/libc/db/btree/Makefile.inc b/lib/libc/db/btree/Makefile.inc
new file mode 100644
index 0000000..33c630f
--- /dev/null
+++ b/lib/libc/db/btree/Makefile.inc
@@ -0,0 +1,8 @@
+# from @(#)Makefile.inc 8.2 (Berkeley) 7/14/94
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libc/db/btree
+
+SRCS+= bt_close.c bt_conv.c bt_debug.c bt_delete.c bt_get.c bt_open.c \
+ bt_overflow.c bt_page.c bt_put.c bt_search.c bt_seq.c bt_split.c \
+ bt_utils.c
diff --git a/lib/libc/db/btree/bt_close.c b/lib/libc/db/btree/bt_close.c
new file mode 100644
index 0000000..27f9ab6
--- /dev/null
+++ b/lib/libc/db/btree/bt_close.c
@@ -0,0 +1,182 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_close.c 8.7 (Berkeley) 8/17/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <db.h>
+#include "btree.h"
+
+static int bt_meta __P((BTREE *));
+
+/*
+ * BT_CLOSE -- Close a btree.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__bt_close(dbp)
+ DB *dbp;
+{
+ BTREE *t;
+ int fd;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* Sync the tree. */
+ if (__bt_sync(dbp, 0) == RET_ERROR)
+ return (RET_ERROR);
+
+ /* Close the memory pool. */
+ if (mpool_close(t->bt_mp) == RET_ERROR)
+ return (RET_ERROR);
+
+ /* Free random memory. */
+ if (t->bt_cursor.key.data != NULL) {
+ free(t->bt_cursor.key.data);
+ t->bt_cursor.key.size = 0;
+ t->bt_cursor.key.data = NULL;
+ }
+ if (t->bt_rkey.data) {
+ free(t->bt_rkey.data);
+ t->bt_rkey.size = 0;
+ t->bt_rkey.data = NULL;
+ }
+ if (t->bt_rdata.data) {
+ free(t->bt_rdata.data);
+ t->bt_rdata.size = 0;
+ t->bt_rdata.data = NULL;
+ }
+
+ fd = t->bt_fd;
+ free(t);
+ free(dbp);
+ return (close(fd) ? RET_ERROR : RET_SUCCESS);
+}
+
+/*
+ * BT_SYNC -- sync the btree to disk.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__bt_sync(dbp, flags)
+ const DB *dbp;
+ u_int flags;
+{
+ BTREE *t;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* Sync doesn't currently take any flags. */
+ if (flags != 0) {
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if (F_ISSET(t, B_INMEM | B_RDONLY) || !F_ISSET(t, B_MODIFIED))
+ return (RET_SUCCESS);
+
+ if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
+ return (RET_ERROR);
+
+ if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS)
+ F_CLR(t, B_MODIFIED);
+
+ return (status);
+}
+
+/*
+ * BT_META -- write the tree meta data to disk.
+ *
+ * Parameters:
+ * t: tree
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+static int
+bt_meta(t)
+ BTREE *t;
+{
+ BTMETA m;
+ void *p;
+
+ if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL)
+ return (RET_ERROR);
+
+ /* Fill in metadata. */
+ m.magic = BTREEMAGIC;
+ m.version = BTREEVERSION;
+ m.psize = t->bt_psize;
+ m.free = t->bt_free;
+ m.nrecs = t->bt_nrecs;
+ m.flags = F_ISSET(t, SAVEMETA);
+
+ memmove(p, &m, sizeof(BTMETA));
+ mpool_put(t->bt_mp, p, MPOOL_DIRTY);
+ return (RET_SUCCESS);
+}
diff --git a/lib/libc/db/btree/bt_conv.c b/lib/libc/db/btree/bt_conv.c
new file mode 100644
index 0000000..1cb208b1
--- /dev/null
+++ b/lib/libc/db/btree/bt_conv.c
@@ -0,0 +1,221 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_conv.c 8.5 (Berkeley) 8/17/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+
+#include <stdio.h>
+
+#include <db.h>
+#include "btree.h"
+
+static void mswap __P((PAGE *));
+
+/*
+ * __BT_BPGIN, __BT_BPGOUT --
+ * Convert host-specific number layout to/from the host-independent
+ * format stored on disk.
+ *
+ * Parameters:
+ * t: tree
+ * pg: page number
+ * h: page to convert
+ */
+void
+__bt_pgin(t, pg, pp)
+ void *t;
+ pgno_t pg;
+ void *pp;
+{
+ PAGE *h;
+ indx_t i, top;
+ u_char flags;
+ char *p;
+
+ if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
+ return;
+ if (pg == P_META) {
+ mswap(pp);
+ return;
+ }
+
+ h = pp;
+ M_32_SWAP(h->pgno);
+ M_32_SWAP(h->prevpg);
+ M_32_SWAP(h->nextpg);
+ M_32_SWAP(h->flags);
+ M_16_SWAP(h->lower);
+ M_16_SWAP(h->upper);
+
+ top = NEXTINDEX(h);
+ if ((h->flags & P_TYPE) == P_BINTERNAL)
+ for (i = 0; i < top; i++) {
+ M_16_SWAP(h->linp[i]);
+ p = (char *)GETBINTERNAL(h, i);
+ P_32_SWAP(p);
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ if (*(u_char *)p & P_BIGKEY) {
+ p += sizeof(u_char);
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ P_32_SWAP(p);
+ }
+ }
+ else if ((h->flags & P_TYPE) == P_BLEAF)
+ for (i = 0; i < top; i++) {
+ M_16_SWAP(h->linp[i]);
+ p = (char *)GETBLEAF(h, i);
+ P_32_SWAP(p);
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p);
+ p += sizeof(u_int32_t);
+ flags = *(u_char *)p;
+ if (flags & (P_BIGKEY | P_BIGDATA)) {
+ p += sizeof(u_char);
+ if (flags & P_BIGKEY) {
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ P_32_SWAP(p);
+ }
+ if (flags & P_BIGDATA) {
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ P_32_SWAP(p);
+ }
+ }
+ }
+}
+
+void
+__bt_pgout(t, pg, pp)
+ void *t;
+ pgno_t pg;
+ void *pp;
+{
+ PAGE *h;
+ indx_t i, top;
+ u_char flags;
+ char *p;
+
+ if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
+ return;
+ if (pg == P_META) {
+ mswap(pp);
+ return;
+ }
+
+ h = pp;
+ top = NEXTINDEX(h);
+ if ((h->flags & P_TYPE) == P_BINTERNAL)
+ for (i = 0; i < top; i++) {
+ p = (char *)GETBINTERNAL(h, i);
+ P_32_SWAP(p);
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ if (*(u_char *)p & P_BIGKEY) {
+ p += sizeof(u_char);
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ P_32_SWAP(p);
+ }
+ M_16_SWAP(h->linp[i]);
+ }
+ else if ((h->flags & P_TYPE) == P_BLEAF)
+ for (i = 0; i < top; i++) {
+ p = (char *)GETBLEAF(h, i);
+ P_32_SWAP(p);
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p);
+ p += sizeof(u_int32_t);
+ flags = *(u_char *)p;
+ if (flags & (P_BIGKEY | P_BIGDATA)) {
+ p += sizeof(u_char);
+ if (flags & P_BIGKEY) {
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ P_32_SWAP(p);
+ }
+ if (flags & P_BIGDATA) {
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ P_32_SWAP(p);
+ }
+ }
+ M_16_SWAP(h->linp[i]);
+ }
+
+ M_32_SWAP(h->pgno);
+ M_32_SWAP(h->prevpg);
+ M_32_SWAP(h->nextpg);
+ M_32_SWAP(h->flags);
+ M_16_SWAP(h->lower);
+ M_16_SWAP(h->upper);
+}
+
+/*
+ * MSWAP -- Actually swap the bytes on the meta page.
+ *
+ * Parameters:
+ * p: page to convert
+ */
+static void
+mswap(pg)
+ PAGE *pg;
+{
+ char *p;
+
+ p = (char *)pg;
+ P_32_SWAP(p); /* magic */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* version */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* psize */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* free */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* nrecs */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* flags */
+ p += sizeof(u_int32_t);
+}
diff --git a/lib/libc/db/btree/bt_debug.c b/lib/libc/db/btree/bt_debug.c
new file mode 100644
index 0000000..3aefbe7
--- /dev/null
+++ b/lib/libc/db/btree/bt_debug.c
@@ -0,0 +1,329 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_debug.c 8.5 (Berkeley) 8/17/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "btree.h"
+
+#ifdef DEBUG
+/*
+ * BT_DUMP -- Dump the tree
+ *
+ * Parameters:
+ * dbp: pointer to the DB
+ */
+void
+__bt_dump(dbp)
+ DB *dbp;
+{
+ BTREE *t;
+ PAGE *h;
+ pgno_t i;
+ char *sep;
+
+ t = dbp->internal;
+ (void)fprintf(stderr, "%s: pgsz %d",
+ F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize);
+ if (F_ISSET(t, R_RECNO))
+ (void)fprintf(stderr, " keys %lu", t->bt_nrecs);
+#undef X
+#define X(flag, name) \
+ if (F_ISSET(t, flag)) { \
+ (void)fprintf(stderr, "%s%s", sep, name); \
+ sep = ", "; \
+ }
+ if (t->flags != 0) {
+ sep = " flags (";
+ X(R_FIXLEN, "FIXLEN");
+ X(B_INMEM, "INMEM");
+ X(B_NODUPS, "NODUPS");
+ X(B_RDONLY, "RDONLY");
+ X(R_RECNO, "RECNO");
+ X(B_METADIRTY,"METADIRTY");
+ (void)fprintf(stderr, ")\n");
+ }
+#undef X
+
+ for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
+ __bt_dpage(h);
+ (void)mpool_put(t->bt_mp, h, 0);
+ }
+}
+
+/*
+ * BT_DMPAGE -- Dump the meta page
+ *
+ * Parameters:
+ * h: pointer to the PAGE
+ */
+void
+__bt_dmpage(h)
+ PAGE *h;
+{
+ BTMETA *m;
+ char *sep;
+
+ m = (BTMETA *)h;
+ (void)fprintf(stderr, "magic %lx\n", m->magic);
+ (void)fprintf(stderr, "version %lu\n", m->version);
+ (void)fprintf(stderr, "psize %lu\n", m->psize);
+ (void)fprintf(stderr, "free %lu\n", m->free);
+ (void)fprintf(stderr, "nrecs %lu\n", m->nrecs);
+ (void)fprintf(stderr, "flags %lu", m->flags);
+#undef X
+#define X(flag, name) \
+ if (m->flags & flag) { \
+ (void)fprintf(stderr, "%s%s", sep, name); \
+ sep = ", "; \
+ }
+ if (m->flags) {
+ sep = " (";
+ X(B_NODUPS, "NODUPS");
+ X(R_RECNO, "RECNO");
+ (void)fprintf(stderr, ")");
+ }
+}
+
+/*
+ * BT_DNPAGE -- Dump the page
+ *
+ * Parameters:
+ * n: page number to dump.
+ */
+void
+__bt_dnpage(dbp, pgno)
+ DB *dbp;
+ pgno_t pgno;
+{
+ BTREE *t;
+ PAGE *h;
+
+ t = dbp->internal;
+ if ((h = mpool_get(t->bt_mp, pgno, 0)) != NULL) {
+ __bt_dpage(h);
+ (void)mpool_put(t->bt_mp, h, 0);
+ }
+}
+
+/*
+ * BT_DPAGE -- Dump the page
+ *
+ * Parameters:
+ * h: pointer to the PAGE
+ */
+void
+__bt_dpage(h)
+ PAGE *h;
+{
+ BINTERNAL *bi;
+ BLEAF *bl;
+ RINTERNAL *ri;
+ RLEAF *rl;
+ indx_t cur, top;
+ char *sep;
+
+ (void)fprintf(stderr, " page %d: (", h->pgno);
+#undef X
+#define X(flag, name) \
+ if (h->flags & flag) { \
+ (void)fprintf(stderr, "%s%s", sep, name); \
+ sep = ", "; \
+ }
+ sep = "";
+ X(P_BINTERNAL, "BINTERNAL") /* types */
+ X(P_BLEAF, "BLEAF")
+ X(P_RINTERNAL, "RINTERNAL") /* types */
+ X(P_RLEAF, "RLEAF")
+ X(P_OVERFLOW, "OVERFLOW")
+ X(P_PRESERVE, "PRESERVE");
+ (void)fprintf(stderr, ")\n");
+#undef X
+
+ (void)fprintf(stderr, "\tprev %2d next %2d", h->prevpg, h->nextpg);
+ if (h->flags & P_OVERFLOW)
+ return;
+
+ top = NEXTINDEX(h);
+ (void)fprintf(stderr, " lower %3d upper %3d nextind %d\n",
+ h->lower, h->upper, top);
+ for (cur = 0; cur < top; cur++) {
+ (void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]);
+ switch (h->flags & P_TYPE) {
+ case P_BINTERNAL:
+ bi = GETBINTERNAL(h, cur);
+ (void)fprintf(stderr,
+ "size %03d pgno %03d", bi->ksize, bi->pgno);
+ if (bi->flags & P_BIGKEY)
+ (void)fprintf(stderr, " (indirect)");
+ else if (bi->ksize)
+ (void)fprintf(stderr,
+ " {%.*s}", (int)bi->ksize, bi->bytes);
+ break;
+ case P_RINTERNAL:
+ ri = GETRINTERNAL(h, cur);
+ (void)fprintf(stderr, "entries %03d pgno %03d",
+ ri->nrecs, ri->pgno);
+ break;
+ case P_BLEAF:
+ bl = GETBLEAF(h, cur);
+ if (bl->flags & P_BIGKEY)
+ (void)fprintf(stderr,
+ "big key page %lu size %u/",
+ *(pgno_t *)bl->bytes,
+ *(u_int32_t *)(bl->bytes + sizeof(pgno_t)));
+ else if (bl->ksize)
+ (void)fprintf(stderr, "%s/", bl->bytes);
+ if (bl->flags & P_BIGDATA)
+ (void)fprintf(stderr,
+ "big data page %lu size %u",
+ *(pgno_t *)(bl->bytes + bl->ksize),
+ *(u_int32_t *)(bl->bytes + bl->ksize +
+ sizeof(pgno_t)));
+ else if (bl->dsize)
+ (void)fprintf(stderr, "%.*s",
+ (int)bl->dsize, bl->bytes + bl->ksize);
+ break;
+ case P_RLEAF:
+ rl = GETRLEAF(h, cur);
+ if (rl->flags & P_BIGDATA)
+ (void)fprintf(stderr,
+ "big data page %lu size %u",
+ *(pgno_t *)rl->bytes,
+ *(u_int32_t *)(rl->bytes + sizeof(pgno_t)));
+ else if (rl->dsize)
+ (void)fprintf(stderr,
+ "%.*s", (int)rl->dsize, rl->bytes);
+ break;
+ }
+ (void)fprintf(stderr, "\n");
+ }
+}
+#endif
+
+#ifdef STATISTICS
+/*
+ * BT_STAT -- Gather/print the tree statistics
+ *
+ * Parameters:
+ * dbp: pointer to the DB
+ */
+void
+__bt_stat(dbp)
+ DB *dbp;
+{
+ extern u_long bt_cache_hit, bt_cache_miss, bt_pfxsaved, bt_rootsplit;
+ extern u_long bt_sortsplit, bt_split;
+ BTREE *t;
+ PAGE *h;
+ pgno_t i, pcont, pinternal, pleaf;
+ u_long ifree, lfree, nkeys;
+ int levels;
+
+ t = dbp->internal;
+ pcont = pinternal = pleaf = 0;
+ nkeys = ifree = lfree = 0;
+ for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
+ switch (h->flags & P_TYPE) {
+ case P_BINTERNAL:
+ case P_RINTERNAL:
+ ++pinternal;
+ ifree += h->upper - h->lower;
+ break;
+ case P_BLEAF:
+ case P_RLEAF:
+ ++pleaf;
+ lfree += h->upper - h->lower;
+ nkeys += NEXTINDEX(h);
+ break;
+ case P_OVERFLOW:
+ ++pcont;
+ break;
+ }
+ (void)mpool_put(t->bt_mp, h, 0);
+ }
+
+ /* Count the levels of the tree. */
+ for (i = P_ROOT, levels = 0 ;; ++levels) {
+ h = mpool_get(t->bt_mp, i, 0);
+ if (h->flags & (P_BLEAF|P_RLEAF)) {
+ if (levels == 0)
+ levels = 1;
+ (void)mpool_put(t->bt_mp, h, 0);
+ break;
+ }
+ i = F_ISSET(t, R_RECNO) ?
+ GETRINTERNAL(h, 0)->pgno :
+ GETBINTERNAL(h, 0)->pgno;
+ (void)mpool_put(t->bt_mp, h, 0);
+ }
+
+ (void)fprintf(stderr, "%d level%s with %ld keys",
+ levels, levels == 1 ? "" : "s", nkeys);
+ if (F_ISSET(t, R_RECNO))
+ (void)fprintf(stderr, " (%ld header count)", t->bt_nrecs);
+ (void)fprintf(stderr,
+ "\n%lu pages (leaf %ld, internal %ld, overflow %ld)\n",
+ pinternal + pleaf + pcont, pleaf, pinternal, pcont);
+ (void)fprintf(stderr, "%ld cache hits, %ld cache misses\n",
+ bt_cache_hit, bt_cache_miss);
+ (void)fprintf(stderr, "%ld splits (%ld root splits, %ld sort splits)\n",
+ bt_split, bt_rootsplit, bt_sortsplit);
+ pleaf *= t->bt_psize - BTDATAOFF;
+ if (pleaf)
+ (void)fprintf(stderr,
+ "%.0f%% leaf fill (%ld bytes used, %ld bytes free)\n",
+ ((double)(pleaf - lfree) / pleaf) * 100,
+ pleaf - lfree, lfree);
+ pinternal *= t->bt_psize - BTDATAOFF;
+ if (pinternal)
+ (void)fprintf(stderr,
+ "%.0f%% internal fill (%ld bytes used, %ld bytes free\n",
+ ((double)(pinternal - ifree) / pinternal) * 100,
+ pinternal - ifree, ifree);
+ if (bt_pfxsaved)
+ (void)fprintf(stderr, "prefix checking removed %lu bytes.\n",
+ bt_pfxsaved);
+}
+#endif
diff --git a/lib/libc/db/btree/bt_delete.c b/lib/libc/db/btree/bt_delete.c
new file mode 100644
index 0000000..ece1ab6
--- /dev/null
+++ b/lib/libc/db/btree/bt_delete.c
@@ -0,0 +1,657 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_delete.c 8.13 (Berkeley) 7/28/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <db.h>
+#include "btree.h"
+
+static int __bt_bdelete __P((BTREE *, const DBT *));
+static int __bt_curdel __P((BTREE *, const DBT *, PAGE *, u_int));
+static int __bt_pdelete __P((BTREE *, PAGE *));
+static int __bt_relink __P((BTREE *, PAGE *));
+static int __bt_stkacq __P((BTREE *, PAGE **, CURSOR *));
+
+/*
+ * __bt_delete
+ * Delete the item(s) referenced by a key.
+ *
+ * Return RET_SPECIAL if the key is not found.
+ */
+int
+__bt_delete(dbp, key, flags)
+ const DB *dbp;
+ const DBT *key;
+ u_int flags;
+{
+ BTREE *t;
+ CURSOR *c;
+ PAGE *h;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* Check for change to a read-only tree. */
+ if (F_ISSET(t, B_RDONLY)) {
+ errno = EPERM;
+ return (RET_ERROR);
+ }
+
+ switch (flags) {
+ case 0:
+ status = __bt_bdelete(t, key);
+ break;
+ case R_CURSOR:
+ /*
+ * If flags is R_CURSOR, delete the cursor. Must already
+ * have started a scan and not have already deleted it.
+ */
+ c = &t->bt_cursor;
+ if (F_ISSET(c, CURS_INIT)) {
+ if (F_ISSET(c, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
+ return (RET_SPECIAL);
+ if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
+ return (RET_ERROR);
+
+ /*
+ * If the page is about to be emptied, we'll need to
+ * delete it, which means we have to acquire a stack.
+ */
+ if (NEXTINDEX(h) == 1)
+ if (__bt_stkacq(t, &h, &t->bt_cursor))
+ return (RET_ERROR);
+
+ status = __bt_dleaf(t, NULL, h, c->pg.index);
+
+ if (NEXTINDEX(h) == 0 && status == RET_SUCCESS) {
+ if (__bt_pdelete(t, h))
+ return (RET_ERROR);
+ } else
+ mpool_put(t->bt_mp,
+ h, status == RET_SUCCESS ? MPOOL_DIRTY : 0);
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+ if (status == RET_SUCCESS)
+ F_SET(t, B_MODIFIED);
+ return (status);
+}
+
+/*
+ * __bt_stkacq --
+ * Acquire a stack so we can delete a cursor entry.
+ *
+ * Parameters:
+ * t: tree
+ * hp: pointer to current, pinned PAGE pointer
+ * c: pointer to the cursor
+ *
+ * Returns:
+ * 0 on success, 1 on failure
+ */
+static int
+__bt_stkacq(t, hp, c)
+ BTREE *t;
+ PAGE **hp;
+ CURSOR *c;
+{
+ BINTERNAL *bi;
+ EPG *e;
+ EPGNO *parent;
+ PAGE *h;
+ indx_t index;
+ pgno_t pgno;
+ recno_t nextpg, prevpg;
+ int exact, level;
+
+ /*
+ * Find the first occurrence of the key in the tree. Toss the
+ * currently locked page so we don't hit an already-locked page.
+ */
+ h = *hp;
+ mpool_put(t->bt_mp, h, 0);
+ if ((e = __bt_search(t, &c->key, &exact)) == NULL)
+ return (1);
+ h = e->page;
+
+ /* See if we got it in one shot. */
+ if (h->pgno == c->pg.pgno)
+ goto ret;
+
+ /*
+ * Move right, looking for the page. At each move we have to move
+ * up the stack until we don't have to move to the next page. If
+ * we have to change pages at an internal level, we have to fix the
+ * stack back up.
+ */
+ while (h->pgno != c->pg.pgno) {
+ if ((nextpg = h->nextpg) == P_INVALID)
+ break;
+ mpool_put(t->bt_mp, h, 0);
+
+ /* Move up the stack. */
+ for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
+ /* Get the parent page. */
+ if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
+ return (1);
+
+ /* Move to the next index. */
+ if (parent->index != NEXTINDEX(h) - 1) {
+ index = parent->index + 1;
+ BT_PUSH(t, h->pgno, index);
+ break;
+ }
+ mpool_put(t->bt_mp, h, 0);
+ }
+
+ /* Restore the stack. */
+ while (level--) {
+ /* Push the next level down onto the stack. */
+ bi = GETBINTERNAL(h, index);
+ pgno = bi->pgno;
+ BT_PUSH(t, pgno, 0);
+
+ /* Lose the currently pinned page. */
+ mpool_put(t->bt_mp, h, 0);
+
+ /* Get the next level down. */
+ if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
+ return (1);
+ index = 0;
+ }
+ mpool_put(t->bt_mp, h, 0);
+ if ((h = mpool_get(t->bt_mp, nextpg, 0)) == NULL)
+ return (1);
+ }
+
+ if (h->pgno == c->pg.pgno)
+ goto ret;
+
+ /* Reacquire the original stack. */
+ mpool_put(t->bt_mp, h, 0);
+ if ((e = __bt_search(t, &c->key, &exact)) == NULL)
+ return (1);
+ h = e->page;
+
+ /*
+ * Move left, looking for the page. At each move we have to move
+ * up the stack until we don't have to change pages to move to the
+ * next page. If we have to change pages at an internal level, we
+ * have to fix the stack back up.
+ */
+ while (h->pgno != c->pg.pgno) {
+ if ((prevpg = h->prevpg) == P_INVALID)
+ break;
+ mpool_put(t->bt_mp, h, 0);
+
+ /* Move up the stack. */
+ for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
+ /* Get the parent page. */
+ if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
+ return (1);
+
+ /* Move to the next index. */
+ if (parent->index != 0) {
+ index = parent->index - 1;
+ BT_PUSH(t, h->pgno, index);
+ break;
+ }
+ mpool_put(t->bt_mp, h, 0);
+ }
+
+ /* Restore the stack. */
+ while (level--) {
+ /* Push the next level down onto the stack. */
+ bi = GETBINTERNAL(h, index);
+ pgno = bi->pgno;
+
+ /* Lose the currently pinned page. */
+ mpool_put(t->bt_mp, h, 0);
+
+ /* Get the next level down. */
+ if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
+ return (1);
+
+ index = NEXTINDEX(h) - 1;
+ BT_PUSH(t, pgno, index);
+ }
+ mpool_put(t->bt_mp, h, 0);
+ if ((h = mpool_get(t->bt_mp, prevpg, 0)) == NULL)
+ return (1);
+ }
+
+
+ret: mpool_put(t->bt_mp, h, 0);
+ return ((*hp = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL);
+}
+
+/*
+ * __bt_bdelete --
+ * Delete all key/data pairs matching the specified key.
+ *
+ * Parameters:
+ * t: tree
+ * key: key to delete
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
+ */
+static int
+__bt_bdelete(t, key)
+ BTREE *t;
+ const DBT *key;
+{
+ EPG *e;
+ PAGE *h;
+ int deleted, exact, redo;
+
+ deleted = 0;
+
+ /* Find any matching record; __bt_search pins the page. */
+loop: if ((e = __bt_search(t, key, &exact)) == NULL)
+ return (deleted ? RET_SUCCESS : RET_ERROR);
+ if (!exact) {
+ mpool_put(t->bt_mp, e->page, 0);
+ return (deleted ? RET_SUCCESS : RET_SPECIAL);
+ }
+
+ /*
+ * Delete forward, then delete backward, from the found key. If
+ * there are duplicates and we reach either side of the page, do
+ * the key search again, so that we get them all.
+ */
+ redo = 0;
+ h = e->page;
+ do {
+ if (__bt_dleaf(t, key, h, e->index)) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_ERROR);
+ }
+ if (F_ISSET(t, B_NODUPS)) {
+ if (NEXTINDEX(h) == 0) {
+ if (__bt_pdelete(t, h))
+ return (RET_ERROR);
+ } else
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ return (RET_SUCCESS);
+ }
+ deleted = 1;
+ } while (e->index < NEXTINDEX(h) && __bt_cmp(t, key, e) == 0);
+
+ /* Check for right-hand edge of the page. */
+ if (e->index == NEXTINDEX(h))
+ redo = 1;
+
+ /* Delete from the key to the beginning of the page. */
+ while (e->index-- > 0) {
+ if (__bt_cmp(t, key, e) != 0)
+ break;
+ if (__bt_dleaf(t, key, h, e->index) == RET_ERROR) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_ERROR);
+ }
+ if (e->index == 0)
+ redo = 1;
+ }
+
+ /* Check for an empty page. */
+ if (NEXTINDEX(h) == 0) {
+ if (__bt_pdelete(t, h))
+ return (RET_ERROR);
+ goto loop;
+ }
+
+ /* Put the page. */
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+
+ if (redo)
+ goto loop;
+ return (RET_SUCCESS);
+}
+
+/*
+ * __bt_pdelete --
+ * Delete a single page from the tree.
+ *
+ * Parameters:
+ * t: tree
+ * h: leaf page
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ *
+ * Side-effects:
+ * mpool_put's the page
+ */
+static int
+__bt_pdelete(t, h)
+ BTREE *t;
+ PAGE *h;
+{
+ BINTERNAL *bi;
+ PAGE *pg;
+ EPGNO *parent;
+ indx_t cnt, index, *ip, offset;
+ u_int32_t nksize;
+ char *from;
+
+ /*
+ * Walk the parent page stack -- a LIFO stack of the pages that were
+ * traversed when we searched for the page where the delete occurred.
+ * Each stack entry is a page number and a page index offset. The
+ * offset is for the page traversed on the search. We've just deleted
+ * a page, so we have to delete the key from the parent page.
+ *
+ * If the delete from the parent page makes it empty, this process may
+ * continue all the way up the tree. We stop if we reach the root page
+ * (which is never deleted, it's just not worth the effort) or if the
+ * delete does not empty the page.
+ */
+ while ((parent = BT_POP(t)) != NULL) {
+ /* Get the parent page. */
+ if ((pg = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
+ return (RET_ERROR);
+
+ index = parent->index;
+ bi = GETBINTERNAL(pg, index);
+
+ /* Free any overflow pages. */
+ if (bi->flags & P_BIGKEY &&
+ __ovfl_delete(t, bi->bytes) == RET_ERROR) {
+ mpool_put(t->bt_mp, pg, 0);
+ return (RET_ERROR);
+ }
+
+ /*
+ * Free the parent if it has only the one key and it's not the
+ * root page. If it's the rootpage, turn it back into an empty
+ * leaf page.
+ */
+ if (NEXTINDEX(pg) == 1)
+ if (pg->pgno == P_ROOT) {
+ pg->lower = BTDATAOFF;
+ pg->upper = t->bt_psize;
+ pg->flags = P_BLEAF;
+ } else {
+ if (__bt_relink(t, pg) || __bt_free(t, pg))
+ return (RET_ERROR);
+ continue;
+ }
+ else {
+ /* Pack remaining key items at the end of the page. */
+ nksize = NBINTERNAL(bi->ksize);
+ from = (char *)pg + pg->upper;
+ memmove(from + nksize, from, (char *)bi - from);
+ pg->upper += nksize;
+
+ /* Adjust indices' offsets, shift the indices down. */
+ offset = pg->linp[index];
+ for (cnt = index, ip = &pg->linp[0]; cnt--; ++ip)
+ if (ip[0] < offset)
+ ip[0] += nksize;
+ for (cnt = NEXTINDEX(pg) - index; --cnt; ++ip)
+ ip[0] = ip[1] < offset ? ip[1] + nksize : ip[1];
+ pg->lower -= sizeof(indx_t);
+ }
+
+ mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
+ break;
+ }
+
+ /* Free the leaf page, as long as it wasn't the root. */
+ if (h->pgno == P_ROOT) {
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ return (RET_SUCCESS);
+ }
+ return (__bt_relink(t, h) || __bt_free(t, h));
+}
+
+/*
+ * __bt_dleaf --
+ * Delete a single record from a leaf page.
+ *
+ * Parameters:
+ * t: tree
+ * key: referenced key
+ * h: page
+ * index: index on page to delete
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__bt_dleaf(t, key, h, index)
+ BTREE *t;
+ const DBT *key;
+ PAGE *h;
+ u_int index;
+{
+ BLEAF *bl;
+ indx_t cnt, *ip, offset;
+ u_int32_t nbytes;
+ void *to;
+ char *from;
+
+ /* If this record is referenced by the cursor, delete the cursor. */
+ if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
+ !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
+ t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index == index &&
+ __bt_curdel(t, key, h, index))
+ return (RET_ERROR);
+
+ /* If the entry uses overflow pages, make them available for reuse. */
+ to = bl = GETBLEAF(h, index);
+ if (bl->flags & P_BIGKEY && __ovfl_delete(t, bl->bytes) == RET_ERROR)
+ return (RET_ERROR);
+ if (bl->flags & P_BIGDATA &&
+ __ovfl_delete(t, bl->bytes + bl->ksize) == RET_ERROR)
+ return (RET_ERROR);
+
+ /* Pack the remaining key/data items at the end of the page. */
+ nbytes = NBLEAF(bl);
+ from = (char *)h + h->upper;
+ memmove(from + nbytes, from, (char *)to - from);
+ h->upper += nbytes;
+
+ /* Adjust the indices' offsets, shift the indices down. */
+ offset = h->linp[index];
+ for (cnt = index, ip = &h->linp[0]; cnt--; ++ip)
+ if (ip[0] < offset)
+ ip[0] += nbytes;
+ for (cnt = NEXTINDEX(h) - index; --cnt; ++ip)
+ ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
+ h->lower -= sizeof(indx_t);
+
+ /* If the cursor is on this page, adjust it as necessary. */
+ if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
+ !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
+ t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index > index)
+ --t->bt_cursor.pg.index;
+
+ return (RET_SUCCESS);
+}
+
+/*
+ * __bt_curdel --
+ * Delete the cursor.
+ *
+ * Parameters:
+ * t: tree
+ * key: referenced key (or NULL)
+ * h: page
+ * index: index on page to delete
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+static int
+__bt_curdel(t, key, h, index)
+ BTREE *t;
+ const DBT *key;
+ PAGE *h;
+ u_int index;
+{
+ CURSOR *c;
+ EPG e;
+ PAGE *pg;
+ int curcopy, status;
+
+ /*
+ * If there are duplicates, move forward or backward to one.
+ * Otherwise, copy the key into the cursor area.
+ */
+ c = &t->bt_cursor;
+ F_CLR(c, CURS_AFTER | CURS_BEFORE | CURS_ACQUIRE);
+
+ curcopy = 0;
+ if (!F_ISSET(t, B_NODUPS)) {
+ /*
+ * We're going to have to do comparisons. If we weren't
+ * provided a copy of the key, i.e. the user is deleting
+ * the current cursor position, get one.
+ */
+ if (key == NULL) {
+ e.page = h;
+ e.index = index;
+ if ((status = __bt_ret(t, &e,
+ &c->key, &c->key, NULL, NULL, 1)) != RET_SUCCESS)
+ return (status);
+ curcopy = 1;
+ key = &c->key;
+ }
+ /* Check previous key, if not at the beginning of the page. */
+ if (index > 0) {
+ e.page = h;
+ e.index = index - 1;
+ if (__bt_cmp(t, key, &e) == 0) {
+ F_SET(c, CURS_BEFORE);
+ goto dup2;
+ }
+ }
+ /* Check next key, if not at the end of the page. */
+ if (index < NEXTINDEX(h) - 1) {
+ e.page = h;
+ e.index = index + 1;
+ if (__bt_cmp(t, key, &e) == 0) {
+ F_SET(c, CURS_AFTER);
+ goto dup2;
+ }
+ }
+ /* Check previous key if at the beginning of the page. */
+ if (index == 0 && h->prevpg != P_INVALID) {
+ if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
+ return (RET_ERROR);
+ e.page = pg;
+ e.index = NEXTINDEX(pg) - 1;
+ if (__bt_cmp(t, key, &e) == 0) {
+ F_SET(c, CURS_BEFORE);
+ goto dup1;
+ }
+ mpool_put(t->bt_mp, pg, 0);
+ }
+ /* Check next key if at the end of the page. */
+ if (index == NEXTINDEX(h) - 1 && h->nextpg != P_INVALID) {
+ if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
+ return (RET_ERROR);
+ e.page = pg;
+ e.index = 0;
+ if (__bt_cmp(t, key, &e) == 0) {
+ F_SET(c, CURS_AFTER);
+dup1: mpool_put(t->bt_mp, pg, 0);
+dup2: c->pg.pgno = e.page->pgno;
+ c->pg.index = e.index;
+ return (RET_SUCCESS);
+ }
+ mpool_put(t->bt_mp, pg, 0);
+ }
+ }
+ e.page = h;
+ e.index = index;
+ if (curcopy || (status =
+ __bt_ret(t, &e, &c->key, &c->key, NULL, NULL, 1)) == RET_SUCCESS) {
+ F_SET(c, CURS_ACQUIRE);
+ return (RET_SUCCESS);
+ }
+ return (status);
+}
+
+/*
+ * __bt_relink --
+ * Link around a deleted page.
+ *
+ * Parameters:
+ * t: tree
+ * h: page to be deleted
+ */
+static int
+__bt_relink(t, h)
+ BTREE *t;
+ PAGE *h;
+{
+ PAGE *pg;
+
+ if (h->nextpg != P_INVALID) {
+ if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
+ return (RET_ERROR);
+ pg->prevpg = h->prevpg;
+ mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
+ }
+ if (h->prevpg != P_INVALID) {
+ if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
+ return (RET_ERROR);
+ pg->nextpg = h->nextpg;
+ mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
+ }
+ return (0);
+}
diff --git a/lib/libc/db/btree/bt_get.c b/lib/libc/db/btree/bt_get.c
new file mode 100644
index 0000000..74824c7
--- /dev/null
+++ b/lib/libc/db/btree/bt_get.c
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_get.c 8.6 (Berkeley) 7/20/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include <db.h>
+#include "btree.h"
+
+/*
+ * __BT_GET -- Get a record from the btree.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key to find
+ * data: data to return
+ * flag: currently unused
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
+ */
+int
+__bt_get(dbp, key, data, flags)
+ const DB *dbp;
+ const DBT *key;
+ DBT *data;
+ u_int flags;
+{
+ BTREE *t;
+ EPG *e;
+ int exact, status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* Get currently doesn't take any flags. */
+ if (flags) {
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if ((e = __bt_search(t, key, &exact)) == NULL)
+ return (RET_ERROR);
+ if (!exact) {
+ mpool_put(t->bt_mp, e->page, 0);
+ return (RET_SPECIAL);
+ }
+
+ status = __bt_ret(t, e, NULL, NULL, data, &t->bt_rdata, 0);
+
+ /*
+ * If the user is doing concurrent access, we copied the
+ * key/data, toss the page.
+ */
+ if (F_ISSET(t, B_DB_LOCK))
+ mpool_put(t->bt_mp, e->page, 0);
+ else
+ t->bt_pinned = e->page;
+ return (status);
+}
diff --git a/lib/libc/db/btree/bt_open.c b/lib/libc/db/btree/bt_open.c
new file mode 100644
index 0000000..1b034ce
--- /dev/null
+++ b/lib/libc/db/btree/bt_open.c
@@ -0,0 +1,445 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_open.c 8.10 (Berkeley) 8/17/94";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Implementation of btree access method for 4.4BSD.
+ *
+ * The design here was originally based on that of the btree access method
+ * used in the Postgres database system at UC Berkeley. This implementation
+ * is wholly independent of the Postgres code.
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <db.h>
+#include "btree.h"
+
+#ifdef DEBUG
+#undef MINPSIZE
+#define MINPSIZE 128
+#endif
+
+static int byteorder __P((void));
+static int nroot __P((BTREE *));
+static int tmp __P((void));
+
+/*
+ * __BT_OPEN -- Open a btree.
+ *
+ * Creates and fills a DB struct, and calls the routine that actually
+ * opens the btree.
+ *
+ * Parameters:
+ * fname: filename (NULL for in-memory trees)
+ * flags: open flag bits
+ * mode: open permission bits
+ * b: BTREEINFO pointer
+ *
+ * Returns:
+ * NULL on failure, pointer to DB on success.
+ *
+ */
+DB *
+__bt_open(fname, flags, mode, openinfo, dflags)
+ const char *fname;
+ int flags, mode, dflags;
+ const BTREEINFO *openinfo;
+{
+ struct stat sb;
+ BTMETA m;
+ BTREE *t;
+ BTREEINFO b;
+ DB *dbp;
+ pgno_t ncache;
+ ssize_t nr;
+ int machine_lorder;
+
+ t = NULL;
+
+ /*
+ * Intention is to make sure all of the user's selections are okay
+ * here and then use them without checking. Can't be complete, since
+ * we don't know the right page size, lorder or flags until the backing
+ * file is opened. Also, the file's page size can cause the cachesize
+ * to change.
+ */
+ machine_lorder = byteorder();
+ if (openinfo) {
+ b = *openinfo;
+
+ /* Flags: R_DUP. */
+ if (b.flags & ~(R_DUP))
+ goto einval;
+
+ /*
+ * Page size must be indx_t aligned and >= MINPSIZE. Default
+ * page size is set farther on, based on the underlying file
+ * transfer size.
+ */
+ if (b.psize &&
+ (b.psize < MINPSIZE || b.psize > MAX_PAGE_OFFSET + 1 ||
+ b.psize & (sizeof(indx_t) - 1) ))
+ goto einval;
+
+ /* Minimum number of keys per page; absolute minimum is 2. */
+ if (b.minkeypage) {
+ if (b.minkeypage < 2)
+ goto einval;
+ } else
+ b.minkeypage = DEFMINKEYPAGE;
+
+ /* If no comparison, use default comparison and prefix. */
+ if (b.compare == NULL) {
+ b.compare = __bt_defcmp;
+ if (b.prefix == NULL)
+ b.prefix = __bt_defpfx;
+ }
+
+ if (b.lorder == 0)
+ b.lorder = machine_lorder;
+ } else {
+ b.compare = __bt_defcmp;
+ b.cachesize = 0;
+ b.flags = 0;
+ b.lorder = machine_lorder;
+ b.minkeypage = DEFMINKEYPAGE;
+ b.prefix = __bt_defpfx;
+ b.psize = 0;
+ }
+
+ /* Check for the ubiquitous PDP-11. */
+ if (b.lorder != BIG_ENDIAN && b.lorder != LITTLE_ENDIAN)
+ goto einval;
+
+ /* Allocate and initialize DB and BTREE structures. */
+ if ((t = (BTREE *)malloc(sizeof(BTREE))) == NULL)
+ goto err;
+ memset(t, 0, sizeof(BTREE));
+ t->bt_fd = -1; /* Don't close unopened fd on error. */
+ t->bt_lorder = b.lorder;
+ t->bt_order = NOT;
+ t->bt_cmp = b.compare;
+ t->bt_pfx = b.prefix;
+ t->bt_rfd = -1;
+
+ if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL)
+ goto err;
+ memset(t->bt_dbp, 0, sizeof(DB));
+ if (t->bt_lorder != machine_lorder)
+ F_SET(t, B_NEEDSWAP);
+
+ dbp->type = DB_BTREE;
+ dbp->internal = t;
+ dbp->close = __bt_close;
+ dbp->del = __bt_delete;
+ dbp->fd = __bt_fd;
+ dbp->get = __bt_get;
+ dbp->put = __bt_put;
+ dbp->seq = __bt_seq;
+ dbp->sync = __bt_sync;
+
+ /*
+ * If no file name was supplied, this is an in-memory btree and we
+ * open a backing temporary file. Otherwise, it's a disk-based tree.
+ */
+ if (fname) {
+ switch (flags & O_ACCMODE) {
+ case O_RDONLY:
+ F_SET(t, B_RDONLY);
+ break;
+ case O_RDWR:
+ break;
+ case O_WRONLY:
+ default:
+ goto einval;
+ }
+
+ if ((t->bt_fd = open(fname, flags, mode)) < 0)
+ goto err;
+
+ } else {
+ if ((flags & O_ACCMODE) != O_RDWR)
+ goto einval;
+ if ((t->bt_fd = tmp()) == -1)
+ goto err;
+ F_SET(t, B_INMEM);
+ }
+
+ if (fcntl(t->bt_fd, F_SETFD, 1) == -1)
+ goto err;
+
+ if (fstat(t->bt_fd, &sb))
+ goto err;
+ if (sb.st_size) {
+ if ((nr = read(t->bt_fd, &m, sizeof(BTMETA))) < 0)
+ goto err;
+ if (nr != sizeof(BTMETA))
+ goto eftype;
+
+ /*
+ * Read in the meta-data. This can change the notion of what
+ * the lorder, page size and flags are, and, when the page size
+ * changes, the cachesize value can change too. If the user
+ * specified the wrong byte order for an existing database, we
+ * don't bother to return an error, we just clear the NEEDSWAP
+ * bit.
+ */
+ if (m.magic == BTREEMAGIC)
+ F_CLR(t, B_NEEDSWAP);
+ else {
+ F_SET(t, B_NEEDSWAP);
+ M_32_SWAP(m.magic);
+ M_32_SWAP(m.version);
+ M_32_SWAP(m.psize);
+ M_32_SWAP(m.free);
+ M_32_SWAP(m.nrecs);
+ M_32_SWAP(m.flags);
+ }
+ if (m.magic != BTREEMAGIC || m.version != BTREEVERSION)
+ goto eftype;
+ if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 ||
+ m.psize & (sizeof(indx_t) - 1) )
+ goto eftype;
+ if (m.flags & ~SAVEMETA)
+ goto eftype;
+ b.psize = m.psize;
+ F_SET(t, m.flags);
+ t->bt_free = m.free;
+ t->bt_nrecs = m.nrecs;
+ } else {
+ /*
+ * Set the page size to the best value for I/O to this file.
+ * Don't overflow the page offset type.
+ */
+ if (b.psize == 0) {
+ b.psize = sb.st_blksize;
+ if (b.psize < MINPSIZE)
+ b.psize = MINPSIZE;
+ if (b.psize > MAX_PAGE_OFFSET + 1)
+ b.psize = MAX_PAGE_OFFSET + 1;
+ }
+
+ /* Set flag if duplicates permitted. */
+ if (!(b.flags & R_DUP))
+ F_SET(t, B_NODUPS);
+
+ t->bt_free = P_INVALID;
+ t->bt_nrecs = 0;
+ F_SET(t, B_METADIRTY);
+ }
+
+ t->bt_psize = b.psize;
+
+ /* Set the cache size; must be a multiple of the page size. */
+ if (b.cachesize && b.cachesize & (b.psize - 1) )
+ b.cachesize += (~b.cachesize & (b.psize - 1) ) + 1;
+ if (b.cachesize < b.psize * MINCACHE)
+ b.cachesize = b.psize * MINCACHE;
+
+ /* Calculate number of pages to cache. */
+ ncache = (b.cachesize + t->bt_psize - 1) / t->bt_psize;
+
+ /*
+ * The btree data structure requires that at least two keys can fit on
+ * a page, but other than that there's no fixed requirement. The user
+ * specified a minimum number per page, and we translated that into the
+ * number of bytes a key/data pair can use before being placed on an
+ * overflow page. This calculation includes the page header, the size
+ * of the index referencing the leaf item and the size of the leaf item
+ * structure. Also, don't let the user specify a minkeypage such that
+ * a key/data pair won't fit even if both key and data are on overflow
+ * pages.
+ */
+ t->bt_ovflsize = (t->bt_psize - BTDATAOFF) / b.minkeypage -
+ (sizeof(indx_t) + NBLEAFDBT(0, 0));
+ if (t->bt_ovflsize < NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t))
+ t->bt_ovflsize =
+ NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t);
+
+ /* Initialize the buffer pool. */
+ if ((t->bt_mp =
+ mpool_open(NULL, t->bt_fd, t->bt_psize, ncache)) == NULL)
+ goto err;
+ if (!F_ISSET(t, B_INMEM))
+ mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t);
+
+ /* Create a root page if new tree. */
+ if (nroot(t) == RET_ERROR)
+ goto err;
+
+ /* Global flags. */
+ if (dflags & DB_LOCK)
+ F_SET(t, B_DB_LOCK);
+ if (dflags & DB_SHMEM)
+ F_SET(t, B_DB_SHMEM);
+ if (dflags & DB_TXN)
+ F_SET(t, B_DB_TXN);
+
+ return (dbp);
+
+einval: errno = EINVAL;
+ goto err;
+
+eftype: errno = EFTYPE;
+ goto err;
+
+err: if (t) {
+ if (t->bt_dbp)
+ free(t->bt_dbp);
+ if (t->bt_fd != -1)
+ (void)close(t->bt_fd);
+ free(t);
+ }
+ return (NULL);
+}
+
+/*
+ * NROOT -- Create the root of a new tree.
+ *
+ * Parameters:
+ * t: tree
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+static int
+nroot(t)
+ BTREE *t;
+{
+ PAGE *meta, *root;
+ pgno_t npg;
+
+ if ((meta = mpool_get(t->bt_mp, 0, 0)) != NULL) {
+ mpool_put(t->bt_mp, meta, 0);
+ return (RET_SUCCESS);
+ }
+ if (errno != EINVAL) /* It's OK to not exist. */
+ return (RET_ERROR);
+ errno = 0;
+
+ if ((meta = mpool_new(t->bt_mp, &npg)) == NULL)
+ return (RET_ERROR);
+
+ if ((root = mpool_new(t->bt_mp, &npg)) == NULL)
+ return (RET_ERROR);
+
+ if (npg != P_ROOT)
+ return (RET_ERROR);
+ root->pgno = npg;
+ root->prevpg = root->nextpg = P_INVALID;
+ root->lower = BTDATAOFF;
+ root->upper = t->bt_psize;
+ root->flags = P_BLEAF;
+ memset(meta, 0, t->bt_psize);
+ mpool_put(t->bt_mp, meta, MPOOL_DIRTY);
+ mpool_put(t->bt_mp, root, MPOOL_DIRTY);
+ return (RET_SUCCESS);
+}
+
+static int
+tmp()
+{
+ sigset_t set, oset;
+ int fd;
+ char *envtmp = NULL;
+ char path[MAXPATHLEN];
+
+ if (issetugid() == 0)
+ envtmp = getenv("TMPDIR");
+ (void)snprintf(path,
+ sizeof(path), "%s/bt.XXXXXX", envtmp ? envtmp : "/tmp");
+
+ (void)sigfillset(&set);
+ (void)sigprocmask(SIG_BLOCK, &set, &oset);
+ if ((fd = mkstemp(path)) != -1)
+ (void)unlink(path);
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ return(fd);
+}
+
+static int
+byteorder()
+{
+ u_int32_t x;
+ u_char *p;
+
+ x = 0x01020304;
+ p = (u_char *)&x;
+ switch (*p) {
+ case 1:
+ return (BIG_ENDIAN);
+ case 4:
+ return (LITTLE_ENDIAN);
+ default:
+ return (0);
+ }
+}
+
+int
+__bt_fd(dbp)
+ const DB *dbp;
+{
+ BTREE *t;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* In-memory database can't have a file descriptor. */
+ if (F_ISSET(t, B_INMEM)) {
+ errno = ENOENT;
+ return (-1);
+ }
+ return (t->bt_fd);
+}
diff --git a/lib/libc/db/btree/bt_overflow.c b/lib/libc/db/btree/bt_overflow.c
new file mode 100644
index 0000000..db28a22
--- /dev/null
+++ b/lib/libc/db/btree/bt_overflow.c
@@ -0,0 +1,228 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_overflow.c 8.5 (Berkeley) 7/16/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "btree.h"
+
+/*
+ * Big key/data code.
+ *
+ * Big key and data entries are stored on linked lists of pages. The initial
+ * reference is byte string stored with the key or data and is the page number
+ * and size. The actual record is stored in a chain of pages linked by the
+ * nextpg field of the PAGE header.
+ *
+ * The first page of the chain has a special property. If the record is used
+ * by an internal page, it cannot be deleted and the P_PRESERVE bit will be set
+ * in the header.
+ *
+ * XXX
+ * A single DBT is written to each chain, so a lot of space on the last page
+ * is wasted. This is a fairly major bug for some data sets.
+ */
+
+/*
+ * __OVFL_GET -- Get an overflow key/data item.
+ *
+ * Parameters:
+ * t: tree
+ * p: pointer to { pgno_t, u_int32_t }
+ * buf: storage address
+ * bufsz: storage size
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__ovfl_get(t, p, ssz, buf, bufsz)
+ BTREE *t;
+ void *p;
+ size_t *ssz;
+ void **buf;
+ size_t *bufsz;
+{
+ PAGE *h;
+ pgno_t pg;
+ size_t nb, plen;
+ u_int32_t sz;
+
+ memmove(&pg, p, sizeof(pgno_t));
+ memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t));
+ *ssz = sz;
+
+#ifdef DEBUG
+ if (pg == P_INVALID || sz == 0)
+ abort();
+#endif
+ /* Make the buffer bigger as necessary. */
+ if (*bufsz < sz) {
+ *buf = (char *)(*buf == NULL ? malloc(sz) : reallocf(*buf, sz));
+ if (*buf == NULL)
+ return (RET_ERROR);
+ *bufsz = sz;
+ }
+
+ /*
+ * Step through the linked list of pages, copying the data on each one
+ * into the buffer. Never copy more than the data's length.
+ */
+ plen = t->bt_psize - BTDATAOFF;
+ for (p = *buf;; p = (char *)p + nb, pg = h->nextpg) {
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+
+ nb = MIN(sz, plen);
+ memmove(p, (char *)h + BTDATAOFF, nb);
+ mpool_put(t->bt_mp, h, 0);
+
+ if ((sz -= nb) == 0)
+ break;
+ }
+ return (RET_SUCCESS);
+}
+
+/*
+ * __OVFL_PUT -- Store an overflow key/data item.
+ *
+ * Parameters:
+ * t: tree
+ * data: DBT to store
+ * pgno: storage page number
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__ovfl_put(t, dbt, pg)
+ BTREE *t;
+ const DBT *dbt;
+ pgno_t *pg;
+{
+ PAGE *h, *last;
+ void *p;
+ pgno_t npg;
+ size_t nb, plen;
+ u_int32_t sz;
+
+ /*
+ * Allocate pages and copy the key/data record into them. Store the
+ * number of the first page in the chain.
+ */
+ plen = t->bt_psize - BTDATAOFF;
+ for (last = NULL, p = dbt->data, sz = dbt->size;;
+ p = (char *)p + plen, last = h) {
+ if ((h = __bt_new(t, &npg)) == NULL)
+ return (RET_ERROR);
+
+ h->pgno = npg;
+ h->nextpg = h->prevpg = P_INVALID;
+ h->flags = P_OVERFLOW;
+ h->lower = h->upper = 0;
+
+ nb = MIN(sz, plen);
+ memmove((char *)h + BTDATAOFF, p, nb);
+
+ if (last) {
+ last->nextpg = h->pgno;
+ mpool_put(t->bt_mp, last, MPOOL_DIRTY);
+ } else
+ *pg = h->pgno;
+
+ if ((sz -= nb) == 0) {
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ break;
+ }
+ }
+ return (RET_SUCCESS);
+}
+
+/*
+ * __OVFL_DELETE -- Delete an overflow chain.
+ *
+ * Parameters:
+ * t: tree
+ * p: pointer to { pgno_t, u_int32_t }
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__ovfl_delete(t, p)
+ BTREE *t;
+ void *p;
+{
+ PAGE *h;
+ pgno_t pg;
+ size_t plen;
+ u_int32_t sz;
+
+ memmove(&pg, p, sizeof(pgno_t));
+ memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t));
+
+#ifdef DEBUG
+ if (pg == P_INVALID || sz == 0)
+ abort();
+#endif
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+
+ /* Don't delete chains used by internal pages. */
+ if (h->flags & P_PRESERVE) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_SUCCESS);
+ }
+
+ /* Step through the chain, calling the free routine for each page. */
+ for (plen = t->bt_psize - BTDATAOFF;; sz -= plen) {
+ pg = h->nextpg;
+ __bt_free(t, h);
+ if (sz <= plen)
+ break;
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ }
+ return (RET_SUCCESS);
+}
diff --git a/lib/libc/db/btree/bt_page.c b/lib/libc/db/btree/bt_page.c
new file mode 100644
index 0000000..ce9cbf1
--- /dev/null
+++ b/lib/libc/db/btree/bt_page.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_page.c 8.3 (Berkeley) 7/14/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#include <db.h>
+#include "btree.h"
+
+/*
+ * __bt_free --
+ * Put a page on the freelist.
+ *
+ * Parameters:
+ * t: tree
+ * h: page to free
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ *
+ * Side-effect:
+ * mpool_put's the page.
+ */
+int
+__bt_free(t, h)
+ BTREE *t;
+ PAGE *h;
+{
+ /* Insert the page at the head of the free list. */
+ h->prevpg = P_INVALID;
+ h->nextpg = t->bt_free;
+ t->bt_free = h->pgno;
+ F_SET(t, B_METADIRTY);
+
+ /* Make sure the page gets written back. */
+ return (mpool_put(t->bt_mp, h, MPOOL_DIRTY));
+}
+
+/*
+ * __bt_new --
+ * Get a new page, preferably from the freelist.
+ *
+ * Parameters:
+ * t: tree
+ * npg: storage for page number.
+ *
+ * Returns:
+ * Pointer to a page, NULL on error.
+ */
+PAGE *
+__bt_new(t, npg)
+ BTREE *t;
+ pgno_t *npg;
+{
+ PAGE *h;
+
+ if (t->bt_free != P_INVALID &&
+ (h = mpool_get(t->bt_mp, t->bt_free, 0)) != NULL) {
+ *npg = t->bt_free;
+ t->bt_free = h->nextpg;
+ F_SET(t, B_METADIRTY);
+ return (h);
+ }
+ return (mpool_new(t->bt_mp, npg));
+}
diff --git a/lib/libc/db/btree/bt_put.c b/lib/libc/db/btree/bt_put.c
new file mode 100644
index 0000000..952be09
--- /dev/null
+++ b/lib/libc/db/btree/bt_put.c
@@ -0,0 +1,320 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_put.c 8.8 (Berkeley) 7/26/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "btree.h"
+
+static EPG *bt_fast __P((BTREE *, const DBT *, const DBT *, int *));
+
+/*
+ * __BT_PUT -- Add a btree item to the tree.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key
+ * data: data
+ * flag: R_NOOVERWRITE
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is already in the
+ * tree and R_NOOVERWRITE specified.
+ */
+int
+__bt_put(dbp, key, data, flags)
+ const DB *dbp;
+ DBT *key;
+ const DBT *data;
+ u_int flags;
+{
+ BTREE *t;
+ DBT tkey, tdata;
+ EPG *e;
+ PAGE *h;
+ indx_t index, nxtindex;
+ pgno_t pg;
+ u_int32_t nbytes;
+ int dflags, exact, status;
+ char *dest, db[NOVFLSIZE], kb[NOVFLSIZE];
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* Check for change to a read-only tree. */
+ if (F_ISSET(t, B_RDONLY)) {
+ errno = EPERM;
+ return (RET_ERROR);
+ }
+
+ switch (flags) {
+ case 0:
+ case R_NOOVERWRITE:
+ break;
+ case R_CURSOR:
+ /*
+ * If flags is R_CURSOR, put the cursor. Must already
+ * have started a scan and not have already deleted it.
+ */
+ if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
+ !F_ISSET(&t->bt_cursor,
+ CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
+ break;
+ /* FALLTHROUGH */
+ default:
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ /*
+ * If the key/data pair won't fit on a page, store it on overflow
+ * pages. Only put the key on the overflow page if the pair are
+ * still too big after moving the data to an overflow page.
+ *
+ * XXX
+ * If the insert fails later on, the overflow pages aren't recovered.
+ */
+ dflags = 0;
+ if (key->size + data->size > t->bt_ovflsize) {
+ if (key->size > t->bt_ovflsize) {
+storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR)
+ return (RET_ERROR);
+ tkey.data = kb;
+ tkey.size = NOVFLSIZE;
+ memmove(kb, &pg, sizeof(pgno_t));
+ memmove(kb + sizeof(pgno_t),
+ &key->size, sizeof(u_int32_t));
+ dflags |= P_BIGKEY;
+ key = &tkey;
+ }
+ if (key->size + data->size > t->bt_ovflsize) {
+ if (__ovfl_put(t, data, &pg) == RET_ERROR)
+ return (RET_ERROR);
+ tdata.data = db;
+ tdata.size = NOVFLSIZE;
+ memmove(db, &pg, sizeof(pgno_t));
+ memmove(db + sizeof(pgno_t),
+ &data->size, sizeof(u_int32_t));
+ dflags |= P_BIGDATA;
+ data = &tdata;
+ }
+ if (key->size + data->size > t->bt_ovflsize)
+ goto storekey;
+ }
+
+ /* Replace the cursor. */
+ if (flags == R_CURSOR) {
+ if ((h = mpool_get(t->bt_mp, t->bt_cursor.pg.pgno, 0)) == NULL)
+ return (RET_ERROR);
+ index = t->bt_cursor.pg.index;
+ goto delete;
+ }
+
+ /*
+ * Find the key to delete, or, the location at which to insert.
+ * Bt_fast and __bt_search both pin the returned page.
+ */
+ if (t->bt_order == NOT || (e = bt_fast(t, key, data, &exact)) == NULL)
+ if ((e = __bt_search(t, key, &exact)) == NULL)
+ return (RET_ERROR);
+ h = e->page;
+ index = e->index;
+
+ /*
+ * Add the key/data pair to the tree. If an identical key is already
+ * in the tree, and R_NOOVERWRITE is set, an error is returned. If
+ * R_NOOVERWRITE is not set, the key is either added (if duplicates are
+ * permitted) or an error is returned.
+ */
+ switch (flags) {
+ case R_NOOVERWRITE:
+ if (!exact)
+ break;
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_SPECIAL);
+ default:
+ if (!exact || !F_ISSET(t, B_NODUPS))
+ break;
+ /*
+ * !!!
+ * Note, the delete may empty the page, so we need to put a
+ * new entry into the page immediately.
+ */
+delete: if (__bt_dleaf(t, key, h, index) == RET_ERROR) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_ERROR);
+ }
+ break;
+ }
+
+ /*
+ * If not enough room, or the user has put a ceiling on the number of
+ * keys permitted in the page, split the page. The split code will
+ * insert the key and data and unpin the current page. If inserting
+ * into the offset array, shift the pointers up.
+ */
+ nbytes = NBLEAFDBT(key->size, data->size);
+ if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
+ if ((status = __bt_split(t, h, key,
+ data, dflags, nbytes, index)) != RET_SUCCESS)
+ return (status);
+ goto success;
+ }
+
+ if (index < (nxtindex = NEXTINDEX(h)))
+ memmove(h->linp + index + 1, h->linp + index,
+ (nxtindex - index) * sizeof(indx_t));
+ h->lower += sizeof(indx_t);
+
+ h->linp[index] = h->upper -= nbytes;
+ dest = (char *)h + h->upper;
+ WR_BLEAF(dest, key, data, dflags);
+
+ /* If the cursor is on this page, adjust it as necessary. */
+ if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
+ !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
+ t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index >= index)
+ ++t->bt_cursor.pg.index;
+
+ if (t->bt_order == NOT)
+ if (h->nextpg == P_INVALID) {
+ if (index == NEXTINDEX(h) - 1) {
+ t->bt_order = FORWARD;
+ t->bt_last.index = index;
+ t->bt_last.pgno = h->pgno;
+ }
+ } else if (h->prevpg == P_INVALID) {
+ if (index == 0) {
+ t->bt_order = BACK;
+ t->bt_last.index = 0;
+ t->bt_last.pgno = h->pgno;
+ }
+ }
+
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+
+success:
+ if (flags == R_SETCURSOR)
+ __bt_setcur(t, e->page->pgno, e->index);
+
+ F_SET(t, B_MODIFIED);
+ return (RET_SUCCESS);
+}
+
+#ifdef STATISTICS
+u_long bt_cache_hit, bt_cache_miss;
+#endif
+
+/*
+ * BT_FAST -- Do a quick check for sorted data.
+ *
+ * Parameters:
+ * t: tree
+ * key: key to insert
+ *
+ * Returns:
+ * EPG for new record or NULL if not found.
+ */
+static EPG *
+bt_fast(t, key, data, exactp)
+ BTREE *t;
+ const DBT *key, *data;
+ int *exactp;
+{
+ PAGE *h;
+ u_int32_t nbytes;
+ int cmp;
+
+ if ((h = mpool_get(t->bt_mp, t->bt_last.pgno, 0)) == NULL) {
+ t->bt_order = NOT;
+ return (NULL);
+ }
+ t->bt_cur.page = h;
+ t->bt_cur.index = t->bt_last.index;
+
+ /*
+ * If won't fit in this page or have too many keys in this page,
+ * have to search to get split stack.
+ */
+ nbytes = NBLEAFDBT(key->size, data->size);
+ if (h->upper - h->lower < nbytes + sizeof(indx_t))
+ goto miss;
+
+ if (t->bt_order == FORWARD) {
+ if (t->bt_cur.page->nextpg != P_INVALID)
+ goto miss;
+ if (t->bt_cur.index != NEXTINDEX(h) - 1)
+ goto miss;
+ if ((cmp = __bt_cmp(t, key, &t->bt_cur)) < 0)
+ goto miss;
+ t->bt_last.index = cmp ? ++t->bt_cur.index : t->bt_cur.index;
+ } else {
+ if (t->bt_cur.page->prevpg != P_INVALID)
+ goto miss;
+ if (t->bt_cur.index != 0)
+ goto miss;
+ if ((cmp = __bt_cmp(t, key, &t->bt_cur)) > 0)
+ goto miss;
+ t->bt_last.index = 0;
+ }
+ *exactp = cmp == 0;
+#ifdef STATISTICS
+ ++bt_cache_hit;
+#endif
+ return (&t->bt_cur);
+
+miss:
+#ifdef STATISTICS
+ ++bt_cache_miss;
+#endif
+ t->bt_order = NOT;
+ mpool_put(t->bt_mp, h, 0);
+ return (NULL);
+}
diff --git a/lib/libc/db/btree/bt_search.c b/lib/libc/db/btree/bt_search.c
new file mode 100644
index 0000000..485afcb
--- /dev/null
+++ b/lib/libc/db/btree/bt_search.c
@@ -0,0 +1,213 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_search.c 8.8 (Berkeley) 7/31/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#include <db.h>
+#include "btree.h"
+
+static int __bt_snext __P((BTREE *, PAGE *, const DBT *, int *));
+static int __bt_sprev __P((BTREE *, PAGE *, const DBT *, int *));
+
+/*
+ * __bt_search --
+ * Search a btree for a key.
+ *
+ * Parameters:
+ * t: tree to search
+ * key: key to find
+ * exactp: pointer to exact match flag
+ *
+ * Returns:
+ * The EPG for matching record, if any, or the EPG for the location
+ * of the key, if it were inserted into the tree, is entered into
+ * the bt_cur field of the tree. A pointer to the field is returned.
+ */
+EPG *
+__bt_search(t, key, exactp)
+ BTREE *t;
+ const DBT *key;
+ int *exactp;
+{
+ PAGE *h;
+ indx_t base, index, lim;
+ pgno_t pg;
+ int cmp;
+
+ BT_CLR(t);
+ for (pg = P_ROOT;;) {
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (NULL);
+
+ /* Do a binary search on the current page. */
+ t->bt_cur.page = h;
+ for (base = 0, lim = NEXTINDEX(h); lim; lim >>= 1) {
+ t->bt_cur.index = index = base + (lim >> 1);
+ if ((cmp = __bt_cmp(t, key, &t->bt_cur)) == 0) {
+ if (h->flags & P_BLEAF) {
+ *exactp = 1;
+ return (&t->bt_cur);
+ }
+ goto next;
+ }
+ if (cmp > 0) {
+ base = index + 1;
+ --lim;
+ }
+ }
+
+ /*
+ * If it's a leaf page, we're almost done. If no duplicates
+ * are allowed, or we have an exact match, we're done. Else,
+ * it's possible that there were matching keys on this page,
+ * which later deleted, and we're on a page with no matches
+ * while there are matches on other pages. If at the start or
+ * end of a page, check the adjacent page.
+ */
+ if (h->flags & P_BLEAF) {
+ if (!F_ISSET(t, B_NODUPS)) {
+ if (base == 0 &&
+ h->prevpg != P_INVALID &&
+ __bt_sprev(t, h, key, exactp))
+ return (&t->bt_cur);
+ if (base == NEXTINDEX(h) &&
+ h->nextpg != P_INVALID &&
+ __bt_snext(t, h, key, exactp))
+ return (&t->bt_cur);
+ }
+ *exactp = 0;
+ t->bt_cur.index = base;
+ return (&t->bt_cur);
+ }
+
+ /*
+ * No match found. Base is the smallest index greater than
+ * key and may be zero or a last + 1 index. If it's non-zero,
+ * decrement by one, and record the internal page which should
+ * be a parent page for the key. If a split later occurs, the
+ * inserted page will be to the right of the saved page.
+ */
+ index = base ? base - 1 : base;
+
+next: BT_PUSH(t, h->pgno, index);
+ pg = GETBINTERNAL(h, index)->pgno;
+ mpool_put(t->bt_mp, h, 0);
+ }
+}
+
+/*
+ * __bt_snext --
+ * Check for an exact match after the key.
+ *
+ * Parameters:
+ * t: tree
+ * h: current page
+ * key: key
+ * exactp: pointer to exact match flag
+ *
+ * Returns:
+ * If an exact match found.
+ */
+static int
+__bt_snext(t, h, key, exactp)
+ BTREE *t;
+ PAGE *h;
+ const DBT *key;
+ int *exactp;
+{
+ EPG e;
+
+ /*
+ * Get the next page. The key is either an exact
+ * match, or not as good as the one we already have.
+ */
+ if ((e.page = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
+ return (0);
+ e.index = 0;
+ if (__bt_cmp(t, key, &e) == 0) {
+ mpool_put(t->bt_mp, h, 0);
+ t->bt_cur = e;
+ *exactp = 1;
+ return (1);
+ }
+ mpool_put(t->bt_mp, e.page, 0);
+ return (0);
+}
+
+/*
+ * __bt_sprev --
+ * Check for an exact match before the key.
+ *
+ * Parameters:
+ * t: tree
+ * h: current page
+ * key: key
+ * exactp: pointer to exact match flag
+ *
+ * Returns:
+ * If an exact match found.
+ */
+static int
+__bt_sprev(t, h, key, exactp)
+ BTREE *t;
+ PAGE *h;
+ const DBT *key;
+ int *exactp;
+{
+ EPG e;
+
+ /*
+ * Get the previous page. The key is either an exact
+ * match, or not as good as the one we already have.
+ */
+ if ((e.page = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
+ return (0);
+ e.index = NEXTINDEX(e.page) - 1;
+ if (__bt_cmp(t, key, &e) == 0) {
+ mpool_put(t->bt_mp, h, 0);
+ t->bt_cur = e;
+ *exactp = 1;
+ return (1);
+ }
+ mpool_put(t->bt_mp, e.page, 0);
+ return (0);
+}
diff --git a/lib/libc/db/btree/bt_seq.c b/lib/libc/db/btree/bt_seq.c
new file mode 100644
index 0000000..76e6275
--- /dev/null
+++ b/lib/libc/db/btree/bt_seq.c
@@ -0,0 +1,460 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_seq.c 8.7 (Berkeley) 7/20/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <db.h>
+#include "btree.h"
+
+static int __bt_first __P((BTREE *, const DBT *, EPG *, int *));
+static int __bt_seqadv __P((BTREE *, EPG *, int));
+static int __bt_seqset __P((BTREE *, EPG *, DBT *, int));
+
+/*
+ * Sequential scan support.
+ *
+ * The tree can be scanned sequentially, starting from either end of the
+ * tree or from any specific key. A scan request before any scanning is
+ * done is initialized as starting from the least node.
+ */
+
+/*
+ * __bt_seq --
+ * Btree sequential scan interface.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key for positioning and return value
+ * data: data return value
+ * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
+ */
+int
+__bt_seq(dbp, key, data, flags)
+ const DB *dbp;
+ DBT *key, *data;
+ u_int flags;
+{
+ BTREE *t;
+ EPG e;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /*
+ * If scan unitialized as yet, or starting at a specific record, set
+ * the scan to a specific key. Both __bt_seqset and __bt_seqadv pin
+ * the page the cursor references if they're successful.
+ */
+ switch (flags) {
+ case R_NEXT:
+ case R_PREV:
+ if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
+ status = __bt_seqadv(t, &e, flags);
+ break;
+ }
+ /* FALLTHROUGH */
+ case R_FIRST:
+ case R_LAST:
+ case R_CURSOR:
+ status = __bt_seqset(t, &e, key, flags);
+ break;
+ default:
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if (status == RET_SUCCESS) {
+ __bt_setcur(t, e.page->pgno, e.index);
+
+ status =
+ __bt_ret(t, &e, key, &t->bt_rkey, data, &t->bt_rdata, 0);
+
+ /*
+ * If the user is doing concurrent access, we copied the
+ * key/data, toss the page.
+ */
+ if (F_ISSET(t, B_DB_LOCK))
+ mpool_put(t->bt_mp, e.page, 0);
+ else
+ t->bt_pinned = e.page;
+ }
+ return (status);
+}
+
+/*
+ * __bt_seqset --
+ * Set the sequential scan to a specific key.
+ *
+ * Parameters:
+ * t: tree
+ * ep: storage for returned key
+ * key: key for initial scan position
+ * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV
+ *
+ * Side effects:
+ * Pins the page the cursor references.
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
+ */
+static int
+__bt_seqset(t, ep, key, flags)
+ BTREE *t;
+ EPG *ep;
+ DBT *key;
+ int flags;
+{
+ PAGE *h;
+ pgno_t pg;
+ int exact;
+
+ /*
+ * Find the first, last or specific key in the tree and point the
+ * cursor at it. The cursor may not be moved until a new key has
+ * been found.
+ */
+ switch (flags) {
+ case R_CURSOR: /* Keyed scan. */
+ /*
+ * Find the first instance of the key or the smallest key
+ * which is greater than or equal to the specified key.
+ */
+ if (key->data == NULL || key->size == 0) {
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+ return (__bt_first(t, key, ep, &exact));
+ case R_FIRST: /* First record. */
+ case R_NEXT:
+ /* Walk down the left-hand side of the tree. */
+ for (pg = P_ROOT;;) {
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+
+ /* Check for an empty tree. */
+ if (NEXTINDEX(h) == 0) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_SPECIAL);
+ }
+
+ if (h->flags & (P_BLEAF | P_RLEAF))
+ break;
+ pg = GETBINTERNAL(h, 0)->pgno;
+ mpool_put(t->bt_mp, h, 0);
+ }
+ ep->page = h;
+ ep->index = 0;
+ break;
+ case R_LAST: /* Last record. */
+ case R_PREV:
+ /* Walk down the right-hand side of the tree. */
+ for (pg = P_ROOT;;) {
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+
+ /* Check for an empty tree. */
+ if (NEXTINDEX(h) == 0) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_SPECIAL);
+ }
+
+ if (h->flags & (P_BLEAF | P_RLEAF))
+ break;
+ pg = GETBINTERNAL(h, NEXTINDEX(h) - 1)->pgno;
+ mpool_put(t->bt_mp, h, 0);
+ }
+
+ ep->page = h;
+ ep->index = NEXTINDEX(h) - 1;
+ break;
+ }
+ return (RET_SUCCESS);
+}
+
+/*
+ * __bt_seqadvance --
+ * Advance the sequential scan.
+ *
+ * Parameters:
+ * t: tree
+ * flags: R_NEXT, R_PREV
+ *
+ * Side effects:
+ * Pins the page the new key/data record is on.
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
+ */
+static int
+__bt_seqadv(t, ep, flags)
+ BTREE *t;
+ EPG *ep;
+ int flags;
+{
+ CURSOR *c;
+ PAGE *h;
+ indx_t index;
+ pgno_t pg;
+ int exact;
+
+ /*
+ * There are a couple of states that we can be in. The cursor has
+ * been initialized by the time we get here, but that's all we know.
+ */
+ c = &t->bt_cursor;
+
+ /*
+ * The cursor was deleted where there weren't any duplicate records,
+ * so the key was saved. Find out where that key would go in the
+ * current tree. It doesn't matter if the returned key is an exact
+ * match or not -- if it's an exact match, the record was added after
+ * the delete so we can just return it. If not, as long as there's
+ * a record there, return it.
+ */
+ if (F_ISSET(c, CURS_ACQUIRE))
+ return (__bt_first(t, &c->key, ep, &exact));
+
+ /* Get the page referenced by the cursor. */
+ if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
+ return (RET_ERROR);
+
+ /*
+ * Find the next/previous record in the tree and point the cursor at
+ * it. The cursor may not be moved until a new key has been found.
+ */
+ switch (flags) {
+ case R_NEXT: /* Next record. */
+ /*
+ * The cursor was deleted in duplicate records, and moved
+ * forward to a record that has yet to be returned. Clear
+ * that flag, and return the record.
+ */
+ if (F_ISSET(c, CURS_AFTER))
+ goto usecurrent;
+ index = c->pg.index;
+ if (++index == NEXTINDEX(h)) {
+ pg = h->nextpg;
+ mpool_put(t->bt_mp, h, 0);
+ if (pg == P_INVALID)
+ return (RET_SPECIAL);
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ index = 0;
+ }
+ break;
+ case R_PREV: /* Previous record. */
+ /*
+ * The cursor was deleted in duplicate records, and moved
+ * backward to a record that has yet to be returned. Clear
+ * that flag, and return the record.
+ */
+ if (F_ISSET(c, CURS_BEFORE)) {
+usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE);
+ ep->page = h;
+ ep->index = c->pg.index;
+ return (RET_SUCCESS);
+ }
+ index = c->pg.index;
+ if (index == 0) {
+ pg = h->prevpg;
+ mpool_put(t->bt_mp, h, 0);
+ if (pg == P_INVALID)
+ return (RET_SPECIAL);
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ index = NEXTINDEX(h) - 1;
+ } else
+ --index;
+ break;
+ }
+
+ ep->page = h;
+ ep->index = index;
+ return (RET_SUCCESS);
+}
+
+/*
+ * __bt_first --
+ * Find the first entry.
+ *
+ * Parameters:
+ * t: the tree
+ * key: the key
+ * erval: return EPG
+ * exactp: pointer to exact match flag
+ *
+ * Returns:
+ * The first entry in the tree greater than or equal to key,
+ * or RET_SPECIAL if no such key exists.
+ */
+static int
+__bt_first(t, key, erval, exactp)
+ BTREE *t;
+ const DBT *key;
+ EPG *erval;
+ int *exactp;
+{
+ PAGE *h;
+ EPG *ep, save;
+ pgno_t pg;
+
+ /*
+ * Find any matching record; __bt_search pins the page.
+ *
+ * If it's an exact match and duplicates are possible, walk backwards
+ * in the tree until we find the first one. Otherwise, make sure it's
+ * a valid key (__bt_search may return an index just past the end of a
+ * page) and return it.
+ */
+ if ((ep = __bt_search(t, key, exactp)) == NULL)
+ return (0);
+ if (*exactp) {
+ if (F_ISSET(t, B_NODUPS)) {
+ *erval = *ep;
+ return (RET_SUCCESS);
+ }
+
+ /*
+ * Walk backwards, as long as the entry matches and there are
+ * keys left in the tree. Save a copy of each match in case
+ * we go too far.
+ */
+ save = *ep;
+ h = ep->page;
+ do {
+ if (save.page->pgno != ep->page->pgno) {
+ mpool_put(t->bt_mp, save.page, 0);
+ save = *ep;
+ } else
+ save.index = ep->index;
+
+ /*
+ * Don't unpin the page the last (or original) match
+ * was on, but make sure it's unpinned if an error
+ * occurs.
+ */
+ if (ep->index == 0) {
+ if (h->prevpg == P_INVALID)
+ break;
+ if (h->pgno != save.page->pgno)
+ mpool_put(t->bt_mp, h, 0);
+ if ((h = mpool_get(t->bt_mp,
+ h->prevpg, 0)) == NULL) {
+ if (h->pgno == save.page->pgno)
+ mpool_put(t->bt_mp,
+ save.page, 0);
+ return (RET_ERROR);
+ }
+ ep->page = h;
+ ep->index = NEXTINDEX(h);
+ }
+ --ep->index;
+ } while (__bt_cmp(t, key, ep) == 0);
+
+ /*
+ * Reach here with the last page that was looked at pinned,
+ * which may or may not be the same as the last (or original)
+ * match page. If it's not useful, release it.
+ */
+ if (h->pgno != save.page->pgno)
+ mpool_put(t->bt_mp, h, 0);
+
+ *erval = save;
+ return (RET_SUCCESS);
+ }
+
+ /* If at the end of a page, find the next entry. */
+ if (ep->index == NEXTINDEX(ep->page)) {
+ h = ep->page;
+ pg = h->nextpg;
+ mpool_put(t->bt_mp, h, 0);
+ if (pg == P_INVALID)
+ return (RET_SPECIAL);
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ ep->index = 0;
+ ep->page = h;
+ }
+ *erval = *ep;
+ return (RET_SUCCESS);
+}
+
+/*
+ * __bt_setcur --
+ * Set the cursor to an entry in the tree.
+ *
+ * Parameters:
+ * t: the tree
+ * pgno: page number
+ * index: page index
+ */
+void
+__bt_setcur(t, pgno, index)
+ BTREE *t;
+ pgno_t pgno;
+ u_int index;
+{
+ /* Lose any already deleted key. */
+ if (t->bt_cursor.key.data != NULL) {
+ free(t->bt_cursor.key.data);
+ t->bt_cursor.key.size = 0;
+ t->bt_cursor.key.data = NULL;
+ }
+ F_CLR(&t->bt_cursor, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE);
+
+ /* Update the cursor. */
+ t->bt_cursor.pg.pgno = pgno;
+ t->bt_cursor.pg.index = index;
+ F_SET(&t->bt_cursor, CURS_INIT);
+}
diff --git a/lib/libc/db/btree/bt_split.c b/lib/libc/db/btree/bt_split.c
new file mode 100644
index 0000000..c7779b8
--- /dev/null
+++ b/lib/libc/db/btree/bt_split.c
@@ -0,0 +1,828 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_split.c 8.9 (Berkeley) 7/26/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "btree.h"
+
+static int bt_broot __P((BTREE *, PAGE *, PAGE *, PAGE *));
+static PAGE *bt_page
+ __P((BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t));
+static int bt_preserve __P((BTREE *, pgno_t));
+static PAGE *bt_psplit
+ __P((BTREE *, PAGE *, PAGE *, PAGE *, indx_t *, size_t));
+static PAGE *bt_root
+ __P((BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t));
+static int bt_rroot __P((BTREE *, PAGE *, PAGE *, PAGE *));
+static recno_t rec_total __P((PAGE *));
+
+#ifdef STATISTICS
+u_long bt_rootsplit, bt_split, bt_sortsplit, bt_pfxsaved;
+#endif
+
+/*
+ * __BT_SPLIT -- Split the tree.
+ *
+ * Parameters:
+ * t: tree
+ * sp: page to split
+ * key: key to insert
+ * data: data to insert
+ * flags: BIGKEY/BIGDATA flags
+ * ilen: insert length
+ * skip: index to leave open
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__bt_split(t, sp, key, data, flags, ilen, argskip)
+ BTREE *t;
+ PAGE *sp;
+ const DBT *key, *data;
+ int flags;
+ size_t ilen;
+ u_int32_t argskip;
+{
+ BINTERNAL *bi;
+ BLEAF *bl, *tbl;
+ DBT a, b;
+ EPGNO *parent;
+ PAGE *h, *l, *r, *lchild, *rchild;
+ indx_t nxtindex;
+ u_int16_t skip;
+ u_int32_t n, nbytes, nksize;
+ int parentsplit;
+ char *dest;
+
+ /*
+ * Split the page into two pages, l and r. The split routines return
+ * a pointer to the page into which the key should be inserted and with
+ * skip set to the offset which should be used. Additionally, l and r
+ * are pinned.
+ */
+ skip = argskip;
+ h = sp->pgno == P_ROOT ?
+ bt_root(t, sp, &l, &r, &skip, ilen) :
+ bt_page(t, sp, &l, &r, &skip, ilen);
+ if (h == NULL)
+ return (RET_ERROR);
+
+ /*
+ * Insert the new key/data pair into the leaf page. (Key inserts
+ * always cause a leaf page to split first.)
+ */
+ h->linp[skip] = h->upper -= ilen;
+ dest = (char *)h + h->upper;
+ if (F_ISSET(t, R_RECNO))
+ WR_RLEAF(dest, data, flags)
+ else
+ WR_BLEAF(dest, key, data, flags)
+
+ /* If the root page was split, make it look right. */
+ if (sp->pgno == P_ROOT &&
+ (F_ISSET(t, R_RECNO) ?
+ bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
+ goto err2;
+
+ /*
+ * Now we walk the parent page stack -- a LIFO stack of the pages that
+ * were traversed when we searched for the page that split. Each stack
+ * entry is a page number and a page index offset. The offset is for
+ * the page traversed on the search. We've just split a page, so we
+ * have to insert a new key into the parent page.
+ *
+ * If the insert into the parent page causes it to split, may have to
+ * continue splitting all the way up the tree. We stop if the root
+ * splits or the page inserted into didn't have to split to hold the
+ * new key. Some algorithms replace the key for the old page as well
+ * as the new page. We don't, as there's no reason to believe that the
+ * first key on the old page is any better than the key we have, and,
+ * in the case of a key being placed at index 0 causing the split, the
+ * key is unavailable.
+ *
+ * There are a maximum of 5 pages pinned at any time. We keep the left
+ * and right pages pinned while working on the parent. The 5 are the
+ * two children, left parent and right parent (when the parent splits)
+ * and the root page or the overflow key page when calling bt_preserve.
+ * This code must make sure that all pins are released other than the
+ * root page or overflow page which is unlocked elsewhere.
+ */
+ while ((parent = BT_POP(t)) != NULL) {
+ lchild = l;
+ rchild = r;
+
+ /* Get the parent page. */
+ if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
+ goto err2;
+
+ /*
+ * The new key goes ONE AFTER the index, because the split
+ * was to the right.
+ */
+ skip = parent->index + 1;
+
+ /*
+ * Calculate the space needed on the parent page.
+ *
+ * Prefix trees: space hack when inserting into BINTERNAL
+ * pages. Retain only what's needed to distinguish between
+ * the new entry and the LAST entry on the page to its left.
+ * If the keys compare equal, retain the entire key. Note,
+ * we don't touch overflow keys, and the entire key must be
+ * retained for the next-to-left most key on the leftmost
+ * page of each level, or the search will fail. Applicable
+ * ONLY to internal pages that have leaf pages as children.
+ * Further reduction of the key between pairs of internal
+ * pages loses too much information.
+ */
+ switch (rchild->flags & P_TYPE) {
+ case P_BINTERNAL:
+ bi = GETBINTERNAL(rchild, 0);
+ nbytes = NBINTERNAL(bi->ksize);
+ break;
+ case P_BLEAF:
+ bl = GETBLEAF(rchild, 0);
+ nbytes = NBINTERNAL(bl->ksize);
+ if (t->bt_pfx && !(bl->flags & P_BIGKEY) &&
+ (h->prevpg != P_INVALID || skip > 1)) {
+ tbl = GETBLEAF(lchild, NEXTINDEX(lchild) - 1);
+ a.size = tbl->ksize;
+ a.data = tbl->bytes;
+ b.size = bl->ksize;
+ b.data = bl->bytes;
+ nksize = t->bt_pfx(&a, &b);
+ n = NBINTERNAL(nksize);
+ if (n < nbytes) {
+#ifdef STATISTICS
+ bt_pfxsaved += nbytes - n;
+#endif
+ nbytes = n;
+ } else
+ nksize = 0;
+ } else
+ nksize = 0;
+ break;
+ case P_RINTERNAL:
+ case P_RLEAF:
+ nbytes = NRINTERNAL;
+ break;
+ default:
+ abort();
+ }
+
+ /* Split the parent page if necessary or shift the indices. */
+ if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
+ sp = h;
+ h = h->pgno == P_ROOT ?
+ bt_root(t, h, &l, &r, &skip, nbytes) :
+ bt_page(t, h, &l, &r, &skip, nbytes);
+ if (h == NULL)
+ goto err1;
+ parentsplit = 1;
+ } else {
+ if (skip < (nxtindex = NEXTINDEX(h)))
+ memmove(h->linp + skip + 1, h->linp + skip,
+ (nxtindex - skip) * sizeof(indx_t));
+ h->lower += sizeof(indx_t);
+ parentsplit = 0;
+ }
+
+ /* Insert the key into the parent page. */
+ switch (rchild->flags & P_TYPE) {
+ case P_BINTERNAL:
+ h->linp[skip] = h->upper -= nbytes;
+ dest = (char *)h + h->linp[skip];
+ memmove(dest, bi, nbytes);
+ ((BINTERNAL *)dest)->pgno = rchild->pgno;
+ break;
+ case P_BLEAF:
+ h->linp[skip] = h->upper -= nbytes;
+ dest = (char *)h + h->linp[skip];
+ WR_BINTERNAL(dest, nksize ? nksize : bl->ksize,
+ rchild->pgno, bl->flags & P_BIGKEY);
+ memmove(dest, bl->bytes, nksize ? nksize : bl->ksize);
+ if (bl->flags & P_BIGKEY &&
+ bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR)
+ goto err1;
+ break;
+ case P_RINTERNAL:
+ /*
+ * Update the left page count. If split
+ * added at index 0, fix the correct page.
+ */
+ if (skip > 0)
+ dest = (char *)h + h->linp[skip - 1];
+ else
+ dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
+ ((RINTERNAL *)dest)->nrecs = rec_total(lchild);
+ ((RINTERNAL *)dest)->pgno = lchild->pgno;
+
+ /* Update the right page count. */
+ h->linp[skip] = h->upper -= nbytes;
+ dest = (char *)h + h->linp[skip];
+ ((RINTERNAL *)dest)->nrecs = rec_total(rchild);
+ ((RINTERNAL *)dest)->pgno = rchild->pgno;
+ break;
+ case P_RLEAF:
+ /*
+ * Update the left page count. If split
+ * added at index 0, fix the correct page.
+ */
+ if (skip > 0)
+ dest = (char *)h + h->linp[skip - 1];
+ else
+ dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
+ ((RINTERNAL *)dest)->nrecs = NEXTINDEX(lchild);
+ ((RINTERNAL *)dest)->pgno = lchild->pgno;
+
+ /* Update the right page count. */
+ h->linp[skip] = h->upper -= nbytes;
+ dest = (char *)h + h->linp[skip];
+ ((RINTERNAL *)dest)->nrecs = NEXTINDEX(rchild);
+ ((RINTERNAL *)dest)->pgno = rchild->pgno;
+ break;
+ default:
+ abort();
+ }
+
+ /* Unpin the held pages. */
+ if (!parentsplit) {
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ break;
+ }
+
+ /* If the root page was split, make it look right. */
+ if (sp->pgno == P_ROOT &&
+ (F_ISSET(t, R_RECNO) ?
+ bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
+ goto err1;
+
+ mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
+ mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
+ }
+
+ /* Unpin the held pages. */
+ mpool_put(t->bt_mp, l, MPOOL_DIRTY);
+ mpool_put(t->bt_mp, r, MPOOL_DIRTY);
+
+ /* Clear any pages left on the stack. */
+ return (RET_SUCCESS);
+
+ /*
+ * If something fails in the above loop we were already walking back
+ * up the tree and the tree is now inconsistent. Nothing much we can
+ * do about it but release any memory we're holding.
+ */
+err1: mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
+ mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
+
+err2: mpool_put(t->bt_mp, l, 0);
+ mpool_put(t->bt_mp, r, 0);
+ __dbpanic(t->bt_dbp);
+ return (RET_ERROR);
+}
+
+/*
+ * BT_PAGE -- Split a non-root page of a btree.
+ *
+ * Parameters:
+ * t: tree
+ * h: root page
+ * lp: pointer to left page pointer
+ * rp: pointer to right page pointer
+ * skip: pointer to index to leave open
+ * ilen: insert length
+ *
+ * Returns:
+ * Pointer to page in which to insert or NULL on error.
+ */
+static PAGE *
+bt_page(t, h, lp, rp, skip, ilen)
+ BTREE *t;
+ PAGE *h, **lp, **rp;
+ indx_t *skip;
+ size_t ilen;
+{
+ PAGE *l, *r, *tp;
+ pgno_t npg;
+
+#ifdef STATISTICS
+ ++bt_split;
+#endif
+ /* Put the new right page for the split into place. */
+ if ((r = __bt_new(t, &npg)) == NULL)
+ return (NULL);
+ r->pgno = npg;
+ r->lower = BTDATAOFF;
+ r->upper = t->bt_psize;
+ r->nextpg = h->nextpg;
+ r->prevpg = h->pgno;
+ r->flags = h->flags & P_TYPE;
+
+ /*
+ * If we're splitting the last page on a level because we're appending
+ * a key to it (skip is NEXTINDEX()), it's likely that the data is
+ * sorted. Adding an empty page on the side of the level is less work
+ * and can push the fill factor much higher than normal. If we're
+ * wrong it's no big deal, we'll just do the split the right way next
+ * time. It may look like it's equally easy to do a similar hack for
+ * reverse sorted data, that is, split the tree left, but it's not.
+ * Don't even try.
+ */
+ if (h->nextpg == P_INVALID && *skip == NEXTINDEX(h)) {
+#ifdef STATISTICS
+ ++bt_sortsplit;
+#endif
+ h->nextpg = r->pgno;
+ r->lower = BTDATAOFF + sizeof(indx_t);
+ *skip = 0;
+ *lp = h;
+ *rp = r;
+ return (r);
+ }
+
+ /* Put the new left page for the split into place. */
+ if ((l = (PAGE *)malloc(t->bt_psize)) == NULL) {
+ mpool_put(t->bt_mp, r, 0);
+ return (NULL);
+ }
+#ifdef PURIFY
+ memset(l, 0xff, t->bt_psize);
+#endif
+ l->pgno = h->pgno;
+ l->nextpg = r->pgno;
+ l->prevpg = h->prevpg;
+ l->lower = BTDATAOFF;
+ l->upper = t->bt_psize;
+ l->flags = h->flags & P_TYPE;
+
+ /* Fix up the previous pointer of the page after the split page. */
+ if (h->nextpg != P_INVALID) {
+ if ((tp = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) {
+ free(l);
+ /* XXX mpool_free(t->bt_mp, r->pgno); */
+ return (NULL);
+ }
+ tp->prevpg = r->pgno;
+ mpool_put(t->bt_mp, tp, MPOOL_DIRTY);
+ }
+
+ /*
+ * Split right. The key/data pairs aren't sorted in the btree page so
+ * it's simpler to copy the data from the split page onto two new pages
+ * instead of copying half the data to the right page and compacting
+ * the left page in place. Since the left page can't change, we have
+ * to swap the original and the allocated left page after the split.
+ */
+ tp = bt_psplit(t, h, l, r, skip, ilen);
+
+ /* Move the new left page onto the old left page. */
+ memmove(h, l, t->bt_psize);
+ if (tp == l)
+ tp = h;
+ free(l);
+
+ *lp = h;
+ *rp = r;
+ return (tp);
+}
+
+/*
+ * BT_ROOT -- Split the root page of a btree.
+ *
+ * Parameters:
+ * t: tree
+ * h: root page
+ * lp: pointer to left page pointer
+ * rp: pointer to right page pointer
+ * skip: pointer to index to leave open
+ * ilen: insert length
+ *
+ * Returns:
+ * Pointer to page in which to insert or NULL on error.
+ */
+static PAGE *
+bt_root(t, h, lp, rp, skip, ilen)
+ BTREE *t;
+ PAGE *h, **lp, **rp;
+ indx_t *skip;
+ size_t ilen;
+{
+ PAGE *l, *r, *tp;
+ pgno_t lnpg, rnpg;
+
+#ifdef STATISTICS
+ ++bt_split;
+ ++bt_rootsplit;
+#endif
+ /* Put the new left and right pages for the split into place. */
+ if ((l = __bt_new(t, &lnpg)) == NULL ||
+ (r = __bt_new(t, &rnpg)) == NULL)
+ return (NULL);
+ l->pgno = lnpg;
+ r->pgno = rnpg;
+ l->nextpg = r->pgno;
+ r->prevpg = l->pgno;
+ l->prevpg = r->nextpg = P_INVALID;
+ l->lower = r->lower = BTDATAOFF;
+ l->upper = r->upper = t->bt_psize;
+ l->flags = r->flags = h->flags & P_TYPE;
+
+ /* Split the root page. */
+ tp = bt_psplit(t, h, l, r, skip, ilen);
+
+ *lp = l;
+ *rp = r;
+ return (tp);
+}
+
+/*
+ * BT_RROOT -- Fix up the recno root page after it has been split.
+ *
+ * Parameters:
+ * t: tree
+ * h: root page
+ * l: left page
+ * r: right page
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+static int
+bt_rroot(t, h, l, r)
+ BTREE *t;
+ PAGE *h, *l, *r;
+{
+ char *dest;
+
+ /* Insert the left and right keys, set the header information. */
+ h->linp[0] = h->upper = t->bt_psize - NRINTERNAL;
+ dest = (char *)h + h->upper;
+ WR_RINTERNAL(dest,
+ l->flags & P_RLEAF ? NEXTINDEX(l) : rec_total(l), l->pgno);
+
+ h->linp[1] = h->upper -= NRINTERNAL;
+ dest = (char *)h + h->upper;
+ WR_RINTERNAL(dest,
+ r->flags & P_RLEAF ? NEXTINDEX(r) : rec_total(r), r->pgno);
+
+ h->lower = BTDATAOFF + 2 * sizeof(indx_t);
+
+ /* Unpin the root page, set to recno internal page. */
+ h->flags &= ~P_TYPE;
+ h->flags |= P_RINTERNAL;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+
+ return (RET_SUCCESS);
+}
+
+/*
+ * BT_BROOT -- Fix up the btree root page after it has been split.
+ *
+ * Parameters:
+ * t: tree
+ * h: root page
+ * l: left page
+ * r: right page
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+static int
+bt_broot(t, h, l, r)
+ BTREE *t;
+ PAGE *h, *l, *r;
+{
+ BINTERNAL *bi;
+ BLEAF *bl;
+ u_int32_t nbytes;
+ char *dest;
+
+ /*
+ * If the root page was a leaf page, change it into an internal page.
+ * We copy the key we split on (but not the key's data, in the case of
+ * a leaf page) to the new root page.
+ *
+ * The btree comparison code guarantees that the left-most key on any
+ * level of the tree is never used, so it doesn't need to be filled in.
+ */
+ nbytes = NBINTERNAL(0);
+ h->linp[0] = h->upper = t->bt_psize - nbytes;
+ dest = (char *)h + h->upper;
+ WR_BINTERNAL(dest, 0, l->pgno, 0);
+
+ switch (h->flags & P_TYPE) {
+ case P_BLEAF:
+ bl = GETBLEAF(r, 0);
+ nbytes = NBINTERNAL(bl->ksize);
+ h->linp[1] = h->upper -= nbytes;
+ dest = (char *)h + h->upper;
+ WR_BINTERNAL(dest, bl->ksize, r->pgno, 0);
+ memmove(dest, bl->bytes, bl->ksize);
+
+ /*
+ * If the key is on an overflow page, mark the overflow chain
+ * so it isn't deleted when the leaf copy of the key is deleted.
+ */
+ if (bl->flags & P_BIGKEY &&
+ bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR)
+ return (RET_ERROR);
+ break;
+ case P_BINTERNAL:
+ bi = GETBINTERNAL(r, 0);
+ nbytes = NBINTERNAL(bi->ksize);
+ h->linp[1] = h->upper -= nbytes;
+ dest = (char *)h + h->upper;
+ memmove(dest, bi, nbytes);
+ ((BINTERNAL *)dest)->pgno = r->pgno;
+ break;
+ default:
+ abort();
+ }
+
+ /* There are two keys on the page. */
+ h->lower = BTDATAOFF + 2 * sizeof(indx_t);
+
+ /* Unpin the root page, set to btree internal page. */
+ h->flags &= ~P_TYPE;
+ h->flags |= P_BINTERNAL;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+
+ return (RET_SUCCESS);
+}
+
+/*
+ * BT_PSPLIT -- Do the real work of splitting the page.
+ *
+ * Parameters:
+ * t: tree
+ * h: page to be split
+ * l: page to put lower half of data
+ * r: page to put upper half of data
+ * pskip: pointer to index to leave open
+ * ilen: insert length
+ *
+ * Returns:
+ * Pointer to page in which to insert.
+ */
+static PAGE *
+bt_psplit(t, h, l, r, pskip, ilen)
+ BTREE *t;
+ PAGE *h, *l, *r;
+ indx_t *pskip;
+ size_t ilen;
+{
+ BINTERNAL *bi;
+ BLEAF *bl;
+ CURSOR *c;
+ RLEAF *rl;
+ PAGE *rval;
+ void *src;
+ indx_t full, half, nxt, off, skip, top, used;
+ u_int32_t nbytes;
+ int bigkeycnt, isbigkey;
+
+ /*
+ * Split the data to the left and right pages. Leave the skip index
+ * open. Additionally, make some effort not to split on an overflow
+ * key. This makes internal page processing faster and can save
+ * space as overflow keys used by internal pages are never deleted.
+ */
+ bigkeycnt = 0;
+ skip = *pskip;
+ full = t->bt_psize - BTDATAOFF;
+ half = full / 2;
+ used = 0;
+ for (nxt = off = 0, top = NEXTINDEX(h); nxt < top; ++off) {
+ if (skip == off) {
+ nbytes = ilen;
+ isbigkey = 0; /* XXX: not really known. */
+ } else
+ switch (h->flags & P_TYPE) {
+ case P_BINTERNAL:
+ src = bi = GETBINTERNAL(h, nxt);
+ nbytes = NBINTERNAL(bi->ksize);
+ isbigkey = bi->flags & P_BIGKEY;
+ break;
+ case P_BLEAF:
+ src = bl = GETBLEAF(h, nxt);
+ nbytes = NBLEAF(bl);
+ isbigkey = bl->flags & P_BIGKEY;
+ break;
+ case P_RINTERNAL:
+ src = GETRINTERNAL(h, nxt);
+ nbytes = NRINTERNAL;
+ isbigkey = 0;
+ break;
+ case P_RLEAF:
+ src = rl = GETRLEAF(h, nxt);
+ nbytes = NRLEAF(rl);
+ isbigkey = 0;
+ break;
+ default:
+ abort();
+ }
+
+ /*
+ * If the key/data pairs are substantial fractions of the max
+ * possible size for the page, it's possible to get situations
+ * where we decide to try and copy too much onto the left page.
+ * Make sure that doesn't happen.
+ */
+ if (skip <= off &&
+ used + nbytes + sizeof(indx_t) >= full || nxt == top - 1) {
+ --off;
+ break;
+ }
+
+ /* Copy the key/data pair, if not the skipped index. */
+ if (skip != off) {
+ ++nxt;
+
+ l->linp[off] = l->upper -= nbytes;
+ memmove((char *)l + l->upper, src, nbytes);
+ }
+
+ used += nbytes + sizeof(indx_t);
+ if (used >= half) {
+ if (!isbigkey || bigkeycnt == 3)
+ break;
+ else
+ ++bigkeycnt;
+ }
+ }
+
+ /*
+ * Off is the last offset that's valid for the left page.
+ * Nxt is the first offset to be placed on the right page.
+ */
+ l->lower += (off + 1) * sizeof(indx_t);
+
+ /*
+ * If splitting the page that the cursor was on, the cursor has to be
+ * adjusted to point to the same record as before the split. If the
+ * cursor is at or past the skipped slot, the cursor is incremented by
+ * one. If the cursor is on the right page, it is decremented by the
+ * number of records split to the left page.
+ */
+ c = &t->bt_cursor;
+ if (F_ISSET(c, CURS_INIT) && c->pg.pgno == h->pgno) {
+ if (c->pg.index >= skip)
+ ++c->pg.index;
+ if (c->pg.index < nxt) /* Left page. */
+ c->pg.pgno = l->pgno;
+ else { /* Right page. */
+ c->pg.pgno = r->pgno;
+ c->pg.index -= nxt;
+ }
+ }
+
+ /*
+ * If the skipped index was on the left page, just return that page.
+ * Otherwise, adjust the skip index to reflect the new position on
+ * the right page.
+ */
+ if (skip <= off) {
+ skip = 0;
+ rval = l;
+ } else {
+ rval = r;
+ *pskip -= nxt;
+ }
+
+ for (off = 0; nxt < top; ++off) {
+ if (skip == nxt) {
+ ++off;
+ skip = 0;
+ }
+ switch (h->flags & P_TYPE) {
+ case P_BINTERNAL:
+ src = bi = GETBINTERNAL(h, nxt);
+ nbytes = NBINTERNAL(bi->ksize);
+ break;
+ case P_BLEAF:
+ src = bl = GETBLEAF(h, nxt);
+ nbytes = NBLEAF(bl);
+ break;
+ case P_RINTERNAL:
+ src = GETRINTERNAL(h, nxt);
+ nbytes = NRINTERNAL;
+ break;
+ case P_RLEAF:
+ src = rl = GETRLEAF(h, nxt);
+ nbytes = NRLEAF(rl);
+ break;
+ default:
+ abort();
+ }
+ ++nxt;
+ r->linp[off] = r->upper -= nbytes;
+ memmove((char *)r + r->upper, src, nbytes);
+ }
+ r->lower += off * sizeof(indx_t);
+
+ /* If the key is being appended to the page, adjust the index. */
+ if (skip == top)
+ r->lower += sizeof(indx_t);
+
+ return (rval);
+}
+
+/*
+ * BT_PRESERVE -- Mark a chain of pages as used by an internal node.
+ *
+ * Chains of indirect blocks pointed to by leaf nodes get reclaimed when the
+ * record that references them gets deleted. Chains pointed to by internal
+ * pages never get deleted. This routine marks a chain as pointed to by an
+ * internal page.
+ *
+ * Parameters:
+ * t: tree
+ * pg: page number of first page in the chain.
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+static int
+bt_preserve(t, pg)
+ BTREE *t;
+ pgno_t pg;
+{
+ PAGE *h;
+
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ h->flags |= P_PRESERVE;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ return (RET_SUCCESS);
+}
+
+/*
+ * REC_TOTAL -- Return the number of recno entries below a page.
+ *
+ * Parameters:
+ * h: page
+ *
+ * Returns:
+ * The number of recno entries below a page.
+ *
+ * XXX
+ * These values could be set by the bt_psplit routine. The problem is that the
+ * entry has to be popped off of the stack etc. or the values have to be passed
+ * all the way back to bt_split/bt_rroot and it's not very clean.
+ */
+static recno_t
+rec_total(h)
+ PAGE *h;
+{
+ recno_t recs;
+ indx_t nxt, top;
+
+ for (recs = 0, nxt = 0, top = NEXTINDEX(h); nxt < top; ++nxt)
+ recs += GETRINTERNAL(h, nxt)->nrecs;
+ return (recs);
+}
diff --git a/lib/libc/db/btree/bt_utils.c b/lib/libc/db/btree/bt_utils.c
new file mode 100644
index 0000000..9c1438e
--- /dev/null
+++ b/lib/libc/db/btree/bt_utils.c
@@ -0,0 +1,260 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_utils.c 8.8 (Berkeley) 7/20/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "btree.h"
+
+/*
+ * __bt_ret --
+ * Build return key/data pair.
+ *
+ * Parameters:
+ * t: tree
+ * e: key/data pair to be returned
+ * key: user's key structure (NULL if not to be filled in)
+ * rkey: memory area to hold key
+ * data: user's data structure (NULL if not to be filled in)
+ * rdata: memory area to hold data
+ * copy: always copy the key/data item
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__bt_ret(t, e, key, rkey, data, rdata, copy)
+ BTREE *t;
+ EPG *e;
+ DBT *key, *rkey, *data, *rdata;
+ int copy;
+{
+ BLEAF *bl;
+ void *p;
+
+ bl = GETBLEAF(e->page, e->index);
+
+ /*
+ * We must copy big keys/data to make them contigous. Otherwise,
+ * leave the page pinned and don't copy unless the user specified
+ * concurrent access.
+ */
+ if (key == NULL)
+ goto dataonly;
+
+ if (bl->flags & P_BIGKEY) {
+ if (__ovfl_get(t, bl->bytes,
+ &key->size, &rkey->data, &rkey->size))
+ return (RET_ERROR);
+ key->data = rkey->data;
+ } else if (copy || F_ISSET(t, B_DB_LOCK)) {
+ if (bl->ksize > rkey->size) {
+ p = (void *)(rkey->data == NULL ?
+ malloc(bl->ksize) : realloc(rkey->data, bl->ksize));
+ if (p == NULL)
+ return (RET_ERROR);
+ rkey->data = p;
+ rkey->size = bl->ksize;
+ }
+ memmove(rkey->data, bl->bytes, bl->ksize);
+ key->size = bl->ksize;
+ key->data = rkey->data;
+ } else {
+ key->size = bl->ksize;
+ key->data = bl->bytes;
+ }
+
+dataonly:
+ if (data == NULL)
+ return (RET_SUCCESS);
+
+ if (bl->flags & P_BIGDATA) {
+ if (__ovfl_get(t, bl->bytes + bl->ksize,
+ &data->size, &rdata->data, &rdata->size))
+ return (RET_ERROR);
+ data->data = rdata->data;
+ } else if (copy || F_ISSET(t, B_DB_LOCK)) {
+ /* Use +1 in case the first record retrieved is 0 length. */
+ if (bl->dsize + 1 > rdata->size) {
+ p = (void *)(rdata->data == NULL ?
+ malloc(bl->dsize + 1) :
+ realloc(rdata->data, bl->dsize + 1));
+ if (p == NULL)
+ return (RET_ERROR);
+ rdata->data = p;
+ rdata->size = bl->dsize + 1;
+ }
+ memmove(rdata->data, bl->bytes + bl->ksize, bl->dsize);
+ data->size = bl->dsize;
+ data->data = rdata->data;
+ } else {
+ data->size = bl->dsize;
+ data->data = bl->bytes + bl->ksize;
+ }
+
+ return (RET_SUCCESS);
+}
+
+/*
+ * __BT_CMP -- Compare a key to a given record.
+ *
+ * Parameters:
+ * t: tree
+ * k1: DBT pointer of first arg to comparison
+ * e: pointer to EPG for comparison
+ *
+ * Returns:
+ * < 0 if k1 is < record
+ * = 0 if k1 is = record
+ * > 0 if k1 is > record
+ */
+int
+__bt_cmp(t, k1, e)
+ BTREE *t;
+ const DBT *k1;
+ EPG *e;
+{
+ BINTERNAL *bi;
+ BLEAF *bl;
+ DBT k2;
+ PAGE *h;
+ void *bigkey;
+
+ /*
+ * The left-most key on internal pages, at any level of the tree, is
+ * guaranteed by the following code to be less than any user key.
+ * This saves us from having to update the leftmost key on an internal
+ * page when the user inserts a new key in the tree smaller than
+ * anything we've yet seen.
+ */
+ h = e->page;
+ if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF))
+ return (1);
+
+ bigkey = NULL;
+ if (h->flags & P_BLEAF) {
+ bl = GETBLEAF(h, e->index);
+ if (bl->flags & P_BIGKEY)
+ bigkey = bl->bytes;
+ else {
+ k2.data = bl->bytes;
+ k2.size = bl->ksize;
+ }
+ } else {
+ bi = GETBINTERNAL(h, e->index);
+ if (bi->flags & P_BIGKEY)
+ bigkey = bi->bytes;
+ else {
+ k2.data = bi->bytes;
+ k2.size = bi->ksize;
+ }
+ }
+
+ if (bigkey) {
+ if (__ovfl_get(t, bigkey,
+ &k2.size, &t->bt_rdata.data, &t->bt_rdata.size))
+ return (RET_ERROR);
+ k2.data = t->bt_rdata.data;
+ }
+ return ((*t->bt_cmp)(k1, &k2));
+}
+
+/*
+ * __BT_DEFCMP -- Default comparison routine.
+ *
+ * Parameters:
+ * a: DBT #1
+ * b: DBT #2
+ *
+ * Returns:
+ * < 0 if a is < b
+ * = 0 if a is = b
+ * > 0 if a is > b
+ */
+int
+__bt_defcmp(a, b)
+ const DBT *a, *b;
+{
+ register size_t len;
+ register u_char *p1, *p2;
+
+ /*
+ * XXX
+ * If a size_t doesn't fit in an int, this routine can lose.
+ * What we need is a integral type which is guaranteed to be
+ * larger than a size_t, and there is no such thing.
+ */
+ len = MIN(a->size, b->size);
+ for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2)
+ if (*p1 != *p2)
+ return ((int)*p1 - (int)*p2);
+ return ((int)a->size - (int)b->size);
+}
+
+/*
+ * __BT_DEFPFX -- Default prefix routine.
+ *
+ * Parameters:
+ * a: DBT #1
+ * b: DBT #2
+ *
+ * Returns:
+ * Number of bytes needed to distinguish b from a.
+ */
+size_t
+__bt_defpfx(a, b)
+ const DBT *a, *b;
+{
+ register u_char *p1, *p2;
+ register size_t cnt, len;
+
+ cnt = 1;
+ len = MIN(a->size, b->size);
+ for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt)
+ if (*p1 != *p2)
+ return (cnt);
+
+ /* a->size must be <= b->size, or they wouldn't be in this order. */
+ return (a->size < b->size ? a->size + 1 : a->size);
+}
diff --git a/lib/libc/db/btree/btree.h b/lib/libc/db/btree/btree.h
new file mode 100644
index 0000000..36d35c9
--- /dev/null
+++ b/lib/libc/db/btree/btree.h
@@ -0,0 +1,383 @@
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)btree.h 8.11 (Berkeley) 8/17/94
+ */
+
+/* Macros to set/clear/test flags. */
+#define F_SET(p, f) (p)->flags |= (f)
+#define F_CLR(p, f) (p)->flags &= ~(f)
+#define F_ISSET(p, f) ((p)->flags & (f))
+
+#include <mpool.h>
+
+#define DEFMINKEYPAGE (2) /* Minimum keys per page */
+#define MINCACHE (5) /* Minimum cached pages */
+#define MINPSIZE (512) /* Minimum page size */
+
+/*
+ * Page 0 of a btree file contains a copy of the meta-data. This page is also
+ * used as an out-of-band page, i.e. page pointers that point to nowhere point
+ * to page 0. Page 1 is the root of the btree.
+ */
+#define P_INVALID 0 /* Invalid tree page number. */
+#define P_META 0 /* Tree metadata page number. */
+#define P_ROOT 1 /* Tree root page number. */
+
+/*
+ * There are five page layouts in the btree: btree internal pages (BINTERNAL),
+ * btree leaf pages (BLEAF), recno internal pages (RINTERNAL), recno leaf pages
+ * (RLEAF) and overflow pages. All five page types have a page header (PAGE).
+ * This implementation requires that values within structures NOT be padded.
+ * (ANSI C permits random padding.) If your compiler pads randomly you'll have
+ * to do some work to get this package to run.
+ */
+typedef struct _page {
+ pgno_t pgno; /* this page's page number */
+ pgno_t prevpg; /* left sibling */
+ pgno_t nextpg; /* right sibling */
+
+#define P_BINTERNAL 0x01 /* btree internal page */
+#define P_BLEAF 0x02 /* leaf page */
+#define P_OVERFLOW 0x04 /* overflow page */
+#define P_RINTERNAL 0x08 /* recno internal page */
+#define P_RLEAF 0x10 /* leaf page */
+#define P_TYPE 0x1f /* type mask */
+#define P_PRESERVE 0x20 /* never delete this chain of pages */
+ u_int32_t flags;
+
+ indx_t lower; /* lower bound of free space on page */
+ indx_t upper; /* upper bound of free space on page */
+ indx_t linp[1]; /* indx_t-aligned VAR. LENGTH DATA */
+} PAGE;
+
+/* First and next index. */
+#define BTDATAOFF \
+ (sizeof(pgno_t) + sizeof(pgno_t) + sizeof(pgno_t) + \
+ sizeof(u_int32_t) + sizeof(indx_t) + sizeof(indx_t))
+#define NEXTINDEX(p) (((p)->lower - BTDATAOFF) / sizeof(indx_t))
+
+/*
+ * For pages other than overflow pages, there is an array of offsets into the
+ * rest of the page immediately following the page header. Each offset is to
+ * an item which is unique to the type of page. The h_lower offset is just
+ * past the last filled-in index. The h_upper offset is the first item on the
+ * page. Offsets are from the beginning of the page.
+ *
+ * If an item is too big to store on a single page, a flag is set and the item
+ * is a { page, size } pair such that the page is the first page of an overflow
+ * chain with size bytes of item. Overflow pages are simply bytes without any
+ * external structure.
+ *
+ * The page number and size fields in the items are pgno_t-aligned so they can
+ * be manipulated without copying. (This presumes that 32 bit items can be
+ * manipulated on this system.)
+ */
+#define LALIGN(n) (((n) + sizeof(pgno_t) - 1) & ~(sizeof(pgno_t) - 1))
+#define NOVFLSIZE (sizeof(pgno_t) + sizeof(u_int32_t))
+
+/*
+ * For the btree internal pages, the item is a key. BINTERNALs are {key, pgno}
+ * pairs, such that the key compares less than or equal to all of the records
+ * on that page. For a tree without duplicate keys, an internal page with two
+ * consecutive keys, a and b, will have all records greater than or equal to a
+ * and less than b stored on the page associated with a. Duplicate keys are
+ * somewhat special and can cause duplicate internal and leaf page records and
+ * some minor modifications of the above rule.
+ */
+typedef struct _binternal {
+ u_int32_t ksize; /* key size */
+ pgno_t pgno; /* page number stored on */
+#define P_BIGDATA 0x01 /* overflow data */
+#define P_BIGKEY 0x02 /* overflow key */
+ u_char flags;
+ char bytes[1]; /* data */
+} BINTERNAL;
+
+/* Get the page's BINTERNAL structure at index indx. */
+#define GETBINTERNAL(pg, indx) \
+ ((BINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
+
+/* Get the number of bytes in the entry. */
+#define NBINTERNAL(len) \
+ LALIGN(sizeof(u_int32_t) + sizeof(pgno_t) + sizeof(u_char) + (len))
+
+/* Copy a BINTERNAL entry to the page. */
+#define WR_BINTERNAL(p, size, pgno, flags) { \
+ *(u_int32_t *)p = size; \
+ p += sizeof(u_int32_t); \
+ *(pgno_t *)p = pgno; \
+ p += sizeof(pgno_t); \
+ *(u_char *)p = flags; \
+ p += sizeof(u_char); \
+}
+
+/*
+ * For the recno internal pages, the item is a page number with the number of
+ * keys found on that page and below.
+ */
+typedef struct _rinternal {
+ recno_t nrecs; /* number of records */
+ pgno_t pgno; /* page number stored below */
+} RINTERNAL;
+
+/* Get the page's RINTERNAL structure at index indx. */
+#define GETRINTERNAL(pg, indx) \
+ ((RINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
+
+/* Get the number of bytes in the entry. */
+#define NRINTERNAL \
+ LALIGN(sizeof(recno_t) + sizeof(pgno_t))
+
+/* Copy a RINTERAL entry to the page. */
+#define WR_RINTERNAL(p, nrecs, pgno) { \
+ *(recno_t *)p = nrecs; \
+ p += sizeof(recno_t); \
+ *(pgno_t *)p = pgno; \
+}
+
+/* For the btree leaf pages, the item is a key and data pair. */
+typedef struct _bleaf {
+ u_int32_t ksize; /* size of key */
+ u_int32_t dsize; /* size of data */
+ u_char flags; /* P_BIGDATA, P_BIGKEY */
+ char bytes[1]; /* data */
+} BLEAF;
+
+/* Get the page's BLEAF structure at index indx. */
+#define GETBLEAF(pg, indx) \
+ ((BLEAF *)((char *)(pg) + (pg)->linp[indx]))
+
+/* Get the number of bytes in the entry. */
+#define NBLEAF(p) NBLEAFDBT((p)->ksize, (p)->dsize)
+
+/* Get the number of bytes in the user's key/data pair. */
+#define NBLEAFDBT(ksize, dsize) \
+ LALIGN(sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_char) + \
+ (ksize) + (dsize))
+
+/* Copy a BLEAF entry to the page. */
+#define WR_BLEAF(p, key, data, flags) { \
+ *(u_int32_t *)p = key->size; \
+ p += sizeof(u_int32_t); \
+ *(u_int32_t *)p = data->size; \
+ p += sizeof(u_int32_t); \
+ *(u_char *)p = flags; \
+ p += sizeof(u_char); \
+ memmove(p, key->data, key->size); \
+ p += key->size; \
+ memmove(p, data->data, data->size); \
+}
+
+/* For the recno leaf pages, the item is a data entry. */
+typedef struct _rleaf {
+ u_int32_t dsize; /* size of data */
+ u_char flags; /* P_BIGDATA */
+ char bytes[1];
+} RLEAF;
+
+/* Get the page's RLEAF structure at index indx. */
+#define GETRLEAF(pg, indx) \
+ ((RLEAF *)((char *)(pg) + (pg)->linp[indx]))
+
+/* Get the number of bytes in the entry. */
+#define NRLEAF(p) NRLEAFDBT((p)->dsize)
+
+/* Get the number of bytes from the user's data. */
+#define NRLEAFDBT(dsize) \
+ LALIGN(sizeof(u_int32_t) + sizeof(u_char) + (dsize))
+
+/* Copy a RLEAF entry to the page. */
+#define WR_RLEAF(p, data, flags) { \
+ *(u_int32_t *)p = data->size; \
+ p += sizeof(u_int32_t); \
+ *(u_char *)p = flags; \
+ p += sizeof(u_char); \
+ memmove(p, data->data, data->size); \
+}
+
+/*
+ * A record in the tree is either a pointer to a page and an index in the page
+ * or a page number and an index. These structures are used as a cursor, stack
+ * entry and search returns as well as to pass records to other routines.
+ *
+ * One comment about searches. Internal page searches must find the largest
+ * record less than key in the tree so that descents work. Leaf page searches
+ * must find the smallest record greater than key so that the returned index
+ * is the record's correct position for insertion.
+ */
+typedef struct _epgno {
+ pgno_t pgno; /* the page number */
+ indx_t index; /* the index on the page */
+} EPGNO;
+
+typedef struct _epg {
+ PAGE *page; /* the (pinned) page */
+ indx_t index; /* the index on the page */
+} EPG;
+
+/*
+ * About cursors. The cursor (and the page that contained the key/data pair
+ * that it referenced) can be deleted, which makes things a bit tricky. If
+ * there are no duplicates of the cursor key in the tree (i.e. B_NODUPS is set
+ * or there simply aren't any duplicates of the key) we copy the key that it
+ * referenced when it's deleted, and reacquire a new cursor key if the cursor
+ * is used again. If there are duplicates keys, we move to the next/previous
+ * key, and set a flag so that we know what happened. NOTE: if duplicate (to
+ * the cursor) keys are added to the tree during this process, it is undefined
+ * if they will be returned or not in a cursor scan.
+ *
+ * The flags determine the possible states of the cursor:
+ *
+ * CURS_INIT The cursor references *something*.
+ * CURS_ACQUIRE The cursor was deleted, and a key has been saved so that
+ * we can reacquire the right position in the tree.
+ * CURS_AFTER, CURS_BEFORE
+ * The cursor was deleted, and now references a key/data pair
+ * that has not yet been returned, either before or after the
+ * deleted key/data pair.
+ * XXX
+ * This structure is broken out so that we can eventually offer multiple
+ * cursors as part of the DB interface.
+ */
+typedef struct _cursor {
+ EPGNO pg; /* B: Saved tree reference. */
+ DBT key; /* B: Saved key, or key.data == NULL. */
+ recno_t rcursor; /* R: recno cursor (1-based) */
+
+#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */
+#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */
+#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */
+#define CURS_INIT 0x08 /* RB: Cursor initialized. */
+ u_int8_t flags;
+} CURSOR;
+
+/*
+ * The metadata of the tree. The nrecs field is used only by the RECNO code.
+ * This is because the btree doesn't really need it and it requires that every
+ * put or delete call modify the metadata.
+ */
+typedef struct _btmeta {
+ u_int32_t magic; /* magic number */
+ u_int32_t version; /* version */
+ u_int32_t psize; /* page size */
+ u_int32_t free; /* page number of first free page */
+ u_int32_t nrecs; /* R: number of records */
+
+#define SAVEMETA (B_NODUPS | R_RECNO)
+ u_int32_t flags; /* bt_flags & SAVEMETA */
+} BTMETA;
+
+/* The in-memory btree/recno data structure. */
+typedef struct _btree {
+ MPOOL *bt_mp; /* memory pool cookie */
+
+ DB *bt_dbp; /* pointer to enclosing DB */
+
+ EPG bt_cur; /* current (pinned) page */
+ PAGE *bt_pinned; /* page pinned across calls */
+
+ CURSOR bt_cursor; /* cursor */
+
+#define BT_PUSH(t, p, i) { \
+ t->bt_sp->pgno = p; \
+ t->bt_sp->index = i; \
+ ++t->bt_sp; \
+}
+#define BT_POP(t) (t->bt_sp == t->bt_stack ? NULL : --t->bt_sp)
+#define BT_CLR(t) (t->bt_sp = t->bt_stack)
+ EPGNO bt_stack[50]; /* stack of parent pages */
+ EPGNO *bt_sp; /* current stack pointer */
+
+ DBT bt_rkey; /* returned key */
+ DBT bt_rdata; /* returned data */
+
+ int bt_fd; /* tree file descriptor */
+
+ pgno_t bt_free; /* next free page */
+ u_int32_t bt_psize; /* page size */
+ indx_t bt_ovflsize; /* cut-off for key/data overflow */
+ int bt_lorder; /* byte order */
+ /* sorted order */
+ enum { NOT, BACK, FORWARD } bt_order;
+ EPGNO bt_last; /* last insert */
+
+ /* B: key comparison function */
+ int (*bt_cmp) __P((const DBT *, const DBT *));
+ /* B: prefix comparison function */
+ size_t (*bt_pfx) __P((const DBT *, const DBT *));
+ /* R: recno input function */
+ int (*bt_irec) __P((struct _btree *, recno_t));
+
+ FILE *bt_rfp; /* R: record FILE pointer */
+ int bt_rfd; /* R: record file descriptor */
+
+ caddr_t bt_cmap; /* R: current point in mapped space */
+ caddr_t bt_smap; /* R: start of mapped space */
+ caddr_t bt_emap; /* R: end of mapped space */
+ size_t bt_msize; /* R: size of mapped region. */
+
+ recno_t bt_nrecs; /* R: number of records */
+ size_t bt_reclen; /* R: fixed record length */
+ u_char bt_bval; /* R: delimiting byte/pad character */
+
+/*
+ * NB:
+ * B_NODUPS and R_RECNO are stored on disk, and may not be changed.
+ */
+#define B_INMEM 0x00001 /* in-memory tree */
+#define B_METADIRTY 0x00002 /* need to write metadata */
+#define B_MODIFIED 0x00004 /* tree modified */
+#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */
+#define B_RDONLY 0x00010 /* read-only tree */
+
+#define B_NODUPS 0x00020 /* no duplicate keys permitted */
+#define R_RECNO 0x00080 /* record oriented tree */
+
+#define R_CLOSEFP 0x00040 /* opened a file pointer */
+#define R_EOF 0x00100 /* end of input file reached. */
+#define R_FIXLEN 0x00200 /* fixed length records */
+#define R_MEMMAPPED 0x00400 /* memory mapped file. */
+#define R_INMEM 0x00800 /* in-memory file */
+#define R_MODIFIED 0x01000 /* modified file */
+#define R_RDONLY 0x02000 /* read-only file */
+
+#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */
+#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */
+#define B_DB_TXN 0x10000 /* DB_TXN specified. */
+ u_int32_t flags;
+} BTREE;
+
+#include "extern.h"
diff --git a/lib/libc/db/btree/extern.h b/lib/libc/db/btree/extern.h
new file mode 100644
index 0000000..ebd9c54
--- /dev/null
+++ b/lib/libc/db/btree/extern.h
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)extern.h 8.10 (Berkeley) 7/20/94
+ */
+
+int __bt_close __P((DB *));
+int __bt_cmp __P((BTREE *, const DBT *, EPG *));
+int __bt_crsrdel __P((BTREE *, EPGNO *));
+int __bt_defcmp __P((const DBT *, const DBT *));
+size_t __bt_defpfx __P((const DBT *, const DBT *));
+int __bt_delete __P((const DB *, const DBT *, u_int));
+int __bt_dleaf __P((BTREE *, const DBT *, PAGE *, u_int));
+int __bt_fd __P((const DB *));
+int __bt_free __P((BTREE *, PAGE *));
+int __bt_get __P((const DB *, const DBT *, DBT *, u_int));
+PAGE *__bt_new __P((BTREE *, pgno_t *));
+void __bt_pgin __P((void *, pgno_t, void *));
+void __bt_pgout __P((void *, pgno_t, void *));
+int __bt_push __P((BTREE *, pgno_t, int));
+int __bt_put __P((const DB *dbp, DBT *, const DBT *, u_int));
+int __bt_ret __P((BTREE *, EPG *, DBT *, DBT *, DBT *, DBT *, int));
+EPG *__bt_search __P((BTREE *, const DBT *, int *));
+int __bt_seq __P((const DB *, DBT *, DBT *, u_int));
+void __bt_setcur __P((BTREE *, pgno_t, u_int));
+int __bt_split __P((BTREE *, PAGE *,
+ const DBT *, const DBT *, int, size_t, u_int32_t));
+int __bt_sync __P((const DB *, u_int));
+
+int __ovfl_delete __P((BTREE *, void *));
+int __ovfl_get __P((BTREE *, void *, size_t *, void **, size_t *));
+int __ovfl_put __P((BTREE *, const DBT *, pgno_t *));
+
+#ifdef DEBUG
+void __bt_dnpage __P((DB *, pgno_t));
+void __bt_dpage __P((PAGE *));
+void __bt_dump __P((DB *));
+#endif
+#ifdef STATISTICS
+void __bt_stat __P((DB *));
+#endif
diff --git a/lib/libc/db/changelog b/lib/libc/db/changelog
new file mode 100644
index 0000000..1540ca8
--- /dev/null
+++ b/lib/libc/db/changelog
@@ -0,0 +1,103 @@
+1.84 -> 1.85
+ recno: #ifdef out use of mmap, it's not portable enough.
+
+1.83 -> 1.84 Thu Aug 18 15:46:07 EDT 1994
+ recno: Rework fixed-length records so that closing and reopening
+ the file now works. Pad short records on input. Never do
+ signed comparison in recno input reading functions.
+
+1.82 -> 1.83 Tue Jul 26 15:33:44 EDT 1994
+ btree: Rework cursor deletion code yet again; bugs with
+ deleting empty pages that only contained the cursor
+ record.
+
+1.81 -> 1.82 Sat Jul 16 11:01:50 EDT 1994
+ btree: Fix bugs introduced by new cursor/deletion code.
+ Replace return kbuf/dbuf with real DBT's.
+
+1.80 -> 1.81
+ btree: Fix bugs introduced by new cursor/deletion code.
+ all: Add #defines for Purify.
+
+1.79 -> 1.80 Wed Jul 13 22:41:54 EDT 1994
+ btree Change deletion to coalesce empty pages. This is a major
+ change, cursors and duplicate pages all had to be reworked.
+ Return to a fixed stack.
+ recno: Affected by cursor changes. New cursor structures should
+ permit multiple cursors in the future.
+
+1.78 -> 1.79 Mon Jun 20 17:36:47 EDT 1994
+ all: Minor cleanups of 1.78 for porting reasons; only
+ major change was inlining check of NULL pointer
+ so that __fix_realloc goes away.
+
+1.77 -> 1.78 Thu Jun 16 19:06:43 EDT 1994
+ all: Move "standard" size typedef's into db.h.
+
+1.76 -> 1.77 Thu Jun 16 16:48:38 EDT 1994
+ hash: Delete __init_ routine, has special meaning to OSF 2.0.
+
+1.74 -> 1.76
+ all: Finish up the port to the Alpha.
+
+1.73 -> 1.74
+ recno: Don't put the record if rec_search fails, in rec_rdelete.
+ Create fixed-length intermediate records past "end" of DB
+ correctly.
+ Realloc bug when reading in fixed records.
+ all: First cut at port to Alpha (64-bit architecture) using
+ 4.4BSD basic integral types typedef's.
+ Cast allocation pointers to shut up old compilers.
+ Rework PORT directory into OS/machine directories.
+
+1.72 -> 1.73
+ btree: If enough duplicate records were inserted and then deleted
+ that internal pages had references to empty pages of the
+ duplicate keys, the search function ended up on the wrong
+ page.
+
+1.7 -> 1.72 12 Oct 1993
+ hash: Support NET/2 hash formats.
+
+1.7 -> 1.71 16 Sep 1993
+ btree/recno:
+ Fix bug in internal search routines that caused
+ return of invalid pointers.
+
+1.6 -> 1.7 07 Sep 1993
+ hash: Fixed big key overflow bugs.
+ test: Portability hacks, rewrite test script, Makefile.
+ btree/recno:
+ Stop copying non-overflow key/data pairs.
+ PORT: Break PORT directory up into per architecture/OS
+ subdirectories.
+
+1.5 -> 1.6 06 Jun 1993
+ hash: In PAIRFITS, the first comparison should look at (P)[2].
+ The hash_realloc function was walking off the end of memory.
+ The overflow page number was wrong when bumping splitpoint.
+
+1.4 -> 1.5 23 May 1993
+ hash: Set hash default fill factor dynamically.
+ recno: Fixed bug in sorted page splits.
+ Add page size parameter support.
+ Allow recno to specify the name of the underlying btree;
+ used for vi recovery.
+ btree/recno:
+ Support 64K pages.
+ btree/hash/recno:
+ Provide access to an underlying file descriptor.
+ Change sync routines to take a flag argument, recno
+ uses this to sync out the underlying btree.
+
+1.3 -> 1.4 10 May 1993
+ recno: Delete the R_CURSORLOG flag from the recno interface.
+ Zero-length record fix for non-mmap reads.
+ Try and make SIZE_T_MAX test in open portable.
+
+1.2 -> 1.3 01 May 1993
+ btree: Ignore user byte-order setting when reading already
+ existing database. Fixes to byte-order conversions.
+
+1.1 -> 1.2 15 Apr 1993
+ No bug fixes, only compatibility hacks.
diff --git a/lib/libc/db/db/Makefile.inc b/lib/libc/db/db/Makefile.inc
new file mode 100644
index 0000000..03cb1a8
--- /dev/null
+++ b/lib/libc/db/db/Makefile.inc
@@ -0,0 +1,6 @@
+# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libc/db/db
+
+SRCS+= db.c
diff --git a/lib/libc/db/db/db.c b/lib/libc/db/db/db.c
new file mode 100644
index 0000000..a18f056
--- /dev/null
+++ b/lib/libc/db/db/db.c
@@ -0,0 +1,99 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)db.c 8.4 (Berkeley) 2/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include <db.h>
+
+DB *
+dbopen(fname, flags, mode, type, openinfo)
+ const char *fname;
+ int flags, mode;
+ DBTYPE type;
+ const void *openinfo;
+{
+
+#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN)
+#define USE_OPEN_FLAGS \
+ (O_CREAT | O_EXCL | O_EXLOCK | O_NONBLOCK | O_RDONLY | \
+ O_RDWR | O_SHLOCK | O_TRUNC)
+
+ if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0)
+ switch (type) {
+ case DB_BTREE:
+ return (__bt_open(fname, flags & USE_OPEN_FLAGS,
+ mode, openinfo, flags & DB_FLAGS));
+ case DB_HASH:
+ return (__hash_open(fname, flags & USE_OPEN_FLAGS,
+ mode, openinfo, flags & DB_FLAGS));
+ case DB_RECNO:
+ return (__rec_open(fname, flags & USE_OPEN_FLAGS,
+ mode, openinfo, flags & DB_FLAGS));
+ }
+ errno = EINVAL;
+ return (NULL);
+}
+
+static int
+__dberr()
+{
+ return (RET_ERROR);
+}
+
+/*
+ * __DBPANIC -- Stop.
+ *
+ * Parameters:
+ * dbp: pointer to the DB structure.
+ */
+void
+__dbpanic(dbp)
+ DB *dbp;
+{
+ /* The only thing that can succeed is a close. */
+ dbp->del = (int (*)())__dberr;
+ dbp->fd = (int (*)())__dberr;
+ dbp->get = (int (*)())__dberr;
+ dbp->put = (int (*)())__dberr;
+ dbp->seq = (int (*)())__dberr;
+ dbp->sync = (int (*)())__dberr;
+}
diff --git a/lib/libc/db/docs/hash.usenix.ps b/lib/libc/db/docs/hash.usenix.ps
new file mode 100644
index 0000000..3a0cf44
--- /dev/null
+++ b/lib/libc/db/docs/hash.usenix.ps
@@ -0,0 +1,12209 @@
+%!PS-Adobe-1.0
+%%Creator: utopia:margo (& Seltzer,608-13E,8072,)
+%%Title: stdin (ditroff)
+%%CreationDate: Tue Dec 11 15:06:45 1990
+%%EndComments
+% @(#)psdit.pro 1.3 4/15/88
+% lib/psdit.pro -- prolog for psdit (ditroff) files
+% Copyright (c) 1984, 1985 Adobe Systems Incorporated. All Rights Reserved.
+% last edit: shore Sat Nov 23 20:28:03 1985
+% RCSID: $FreeBSD$
+
+% Changed by Edward Wang (edward@ucbarpa.berkeley.edu) to handle graphics,
+% 17 Feb, 87.
+
+/$DITroff 140 dict def $DITroff begin
+/fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def
+/xi{0 72 11 mul translate 72 resolution div dup neg scale 0 0 moveto
+ /fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def F
+ /pagesave save def}def
+/PB{save /psv exch def currentpoint translate
+ resolution 72 div dup neg scale 0 0 moveto}def
+/PE{psv restore}def
+/arctoobig 90 def /arctoosmall .05 def
+/m1 matrix def /m2 matrix def /m3 matrix def /oldmat matrix def
+/tan{dup sin exch cos div}def
+/point{resolution 72 div mul}def
+/dround {transform round exch round exch itransform}def
+/xT{/devname exch def}def
+/xr{/mh exch def /my exch def /resolution exch def}def
+/xp{}def
+/xs{docsave restore end}def
+/xt{}def
+/xf{/fontname exch def /slotno exch def fontnames slotno get fontname eq not
+ {fonts slotno fontname findfont put fontnames slotno fontname put}if}def
+/xH{/fontheight exch def F}def
+/xS{/fontslant exch def F}def
+/s{/fontsize exch def /fontheight fontsize def F}def
+/f{/fontnum exch def F}def
+/F{fontheight 0 le{/fontheight fontsize def}if
+ fonts fontnum get fontsize point 0 0 fontheight point neg 0 0 m1 astore
+ fontslant 0 ne{1 0 fontslant tan 1 0 0 m2 astore m3 concatmatrix}if
+ makefont setfont .04 fontsize point mul 0 dround pop setlinewidth}def
+/X{exch currentpoint exch pop moveto show}def
+/N{3 1 roll moveto show}def
+/Y{exch currentpoint pop exch moveto show}def
+/S{show}def
+/ditpush{}def/ditpop{}def
+/AX{3 -1 roll currentpoint exch pop moveto 0 exch ashow}def
+/AN{4 2 roll moveto 0 exch ashow}def
+/AY{3 -1 roll currentpoint pop exch moveto 0 exch ashow}def
+/AS{0 exch ashow}def
+/MX{currentpoint exch pop moveto}def
+/MY{currentpoint pop exch moveto}def
+/MXY{moveto}def
+/cb{pop}def % action on unknown char -- nothing for now
+/n{}def/w{}def
+/p{pop showpage pagesave restore /pagesave save def}def
+/Dt{/Dlinewidth exch def}def 1 Dt
+/Ds{/Ddash exch def}def -1 Ds
+/Di{/Dstipple exch def}def 1 Di
+/Dsetlinewidth{2 Dlinewidth mul setlinewidth}def
+/Dsetdash{Ddash 4 eq{[8 12]}{Ddash 16 eq{[32 36]}
+ {Ddash 20 eq{[32 12 8 12]}{[]}ifelse}ifelse}ifelse 0 setdash}def
+/Dstroke{gsave Dsetlinewidth Dsetdash 1 setlinecap stroke grestore
+ currentpoint newpath moveto}def
+/Dl{rlineto Dstroke}def
+/arcellipse{/diamv exch def /diamh exch def oldmat currentmatrix pop
+ currentpoint translate 1 diamv diamh div scale /rad diamh 2 div def
+ currentpoint exch rad add exch rad -180 180 arc oldmat setmatrix}def
+/Dc{dup arcellipse Dstroke}def
+/De{arcellipse Dstroke}def
+/Da{/endv exch def /endh exch def /centerv exch def /centerh exch def
+ /cradius centerv centerv mul centerh centerh mul add sqrt def
+ /eradius endv endv mul endh endh mul add sqrt def
+ /endang endv endh atan def
+ /startang centerv neg centerh neg atan def
+ /sweep startang endang sub dup 0 lt{360 add}if def
+ sweep arctoobig gt
+ {/midang startang sweep 2 div sub def /midrad cradius eradius add 2 div def
+ /midh midang cos midrad mul def /midv midang sin midrad mul def
+ midh neg midv neg endh endv centerh centerv midh midv Da
+ Da}
+ {sweep arctoosmall ge
+ {/controldelt 1 sweep 2 div cos sub 3 sweep 2 div sin mul div 4 mul def
+ centerv neg controldelt mul centerh controldelt mul
+ endv neg controldelt mul centerh add endh add
+ endh controldelt mul centerv add endv add
+ centerh endh add centerv endv add rcurveto Dstroke}
+ {centerh endh add centerv endv add rlineto Dstroke}
+ ifelse}
+ ifelse}def
+/Dpatterns[
+[%cf[widthbits]
+[8<0000000000000010>]
+[8<0411040040114000>]
+[8<0204081020408001>]
+[8<0000103810000000>]
+[8<6699996666999966>]
+[8<0000800100001008>]
+[8<81c36666c3810000>]
+[8<0f0e0c0800000000>]
+[8<0000000000000010>]
+[8<0411040040114000>]
+[8<0204081020408001>]
+[8<0000001038100000>]
+[8<6699996666999966>]
+[8<0000800100001008>]
+[8<81c36666c3810000>]
+[8<0f0e0c0800000000>]
+[8<0042660000246600>]
+[8<0000990000990000>]
+[8<0804020180402010>]
+[8<2418814242811824>]
+[8<6699996666999966>]
+[8<8000000008000000>]
+[8<00001c3e363e1c00>]
+[8<0000000000000000>]
+[32<00000040000000c00000004000000040000000e0000000000000000000000000>]
+[32<00000000000060000000900000002000000040000000f0000000000000000000>]
+[32<000000000000000000e0000000100000006000000010000000e0000000000000>]
+[32<00000000000000002000000060000000a0000000f00000002000000000000000>]
+[32<0000000e0000000000000000000000000000000f000000080000000e00000001>]
+[32<0000090000000600000000000000000000000000000007000000080000000e00>]
+[32<00010000000200000004000000040000000000000000000000000000000f0000>]
+[32<0900000006000000090000000600000000000000000000000000000006000000>]]
+[%ug
+[8<0000020000000000>]
+[8<0000020000002000>]
+[8<0004020000002000>]
+[8<0004020000402000>]
+[8<0004060000402000>]
+[8<0004060000406000>]
+[8<0006060000406000>]
+[8<0006060000606000>]
+[8<00060e0000606000>]
+[8<00060e000060e000>]
+[8<00070e000060e000>]
+[8<00070e000070e000>]
+[8<00070e020070e000>]
+[8<00070e020070e020>]
+[8<04070e020070e020>]
+[8<04070e024070e020>]
+[8<04070e064070e020>]
+[8<04070e064070e060>]
+[8<06070e064070e060>]
+[8<06070e066070e060>]
+[8<06070f066070e060>]
+[8<06070f066070f060>]
+[8<060f0f066070f060>]
+[8<060f0f0660f0f060>]
+[8<060f0f0760f0f060>]
+[8<060f0f0760f0f070>]
+[8<0e0f0f0760f0f070>]
+[8<0e0f0f07e0f0f070>]
+[8<0e0f0f0fe0f0f070>]
+[8<0e0f0f0fe0f0f0f0>]
+[8<0f0f0f0fe0f0f0f0>]
+[8<0f0f0f0ff0f0f0f0>]
+[8<1f0f0f0ff0f0f0f0>]
+[8<1f0f0f0ff1f0f0f0>]
+[8<1f0f0f8ff1f0f0f0>]
+[8<1f0f0f8ff1f0f0f8>]
+[8<9f0f0f8ff1f0f0f8>]
+[8<9f0f0f8ff9f0f0f8>]
+[8<9f0f0f9ff9f0f0f8>]
+[8<9f0f0f9ff9f0f0f9>]
+[8<9f8f0f9ff9f0f0f9>]
+[8<9f8f0f9ff9f8f0f9>]
+[8<9f8f1f9ff9f8f0f9>]
+[8<9f8f1f9ff9f8f1f9>]
+[8<bf8f1f9ff9f8f1f9>]
+[8<bf8f1f9ffbf8f1f9>]
+[8<bf8f1fdffbf8f1f9>]
+[8<bf8f1fdffbf8f1fd>]
+[8<ff8f1fdffbf8f1fd>]
+[8<ff8f1fdffff8f1fd>]
+[8<ff8f1ffffff8f1fd>]
+[8<ff8f1ffffff8f1ff>]
+[8<ff9f1ffffff8f1ff>]
+[8<ff9f1ffffff9f1ff>]
+[8<ff9f9ffffff9f1ff>]
+[8<ff9f9ffffff9f9ff>]
+[8<ffbf9ffffff9f9ff>]
+[8<ffbf9ffffffbf9ff>]
+[8<ffbfdffffffbf9ff>]
+[8<ffbfdffffffbfdff>]
+[8<ffffdffffffbfdff>]
+[8<ffffdffffffffdff>]
+[8<fffffffffffffdff>]
+[8<ffffffffffffffff>]]
+[%mg
+[8<8000000000000000>]
+[8<0822080080228000>]
+[8<0204081020408001>]
+[8<40e0400000000000>]
+[8<66999966>]
+[8<8001000010080000>]
+[8<81c36666c3810000>]
+[8<f0e0c08000000000>]
+[16<07c00f801f003e007c00f800f001e003c007800f001f003e007c00f801f003e0>]
+[16<1f000f8007c003e001f000f8007c003e001f800fc007e003f001f8007c003e00>]
+[8<c3c300000000c3c3>]
+[16<0040008001000200040008001000200040008000000100020004000800100020>]
+[16<0040002000100008000400020001800040002000100008000400020001000080>]
+[16<1fc03fe07df0f8f8f07de03fc01f800fc01fe03ff07df8f87df03fe01fc00f80>]
+[8<80>]
+[8<8040201000000000>]
+[8<84cc000048cc0000>]
+[8<9900009900000000>]
+[8<08040201804020100800020180002010>]
+[8<2418814242811824>]
+[8<66999966>]
+[8<8000000008000000>]
+[8<70f8d8f870000000>]
+[8<0814224180402010>]
+[8<aa00440a11a04400>]
+[8<018245aa45820100>]
+[8<221c224180808041>]
+[8<88000000>]
+[8<0855800080550800>]
+[8<2844004482440044>]
+[8<0810204080412214>]
+[8<00>]]]def
+/Dfill{
+ transform /maxy exch def /maxx exch def
+ transform /miny exch def /minx exch def
+ minx maxx gt{/minx maxx /maxx minx def def}if
+ miny maxy gt{/miny maxy /maxy miny def def}if
+ Dpatterns Dstipple 1 sub get exch 1 sub get
+ aload pop /stip exch def /stipw exch def /stiph 128 def
+ /imatrix[stipw 0 0 stiph 0 0]def
+ /tmatrix[stipw 0 0 stiph 0 0]def
+ /minx minx cvi stiph idiv stiph mul def
+ /miny miny cvi stipw idiv stipw mul def
+ gsave eoclip 0 setgray
+ miny stiph maxy{
+ tmatrix exch 5 exch put
+ minx stipw maxx{
+ tmatrix exch 4 exch put tmatrix setmatrix
+ stipw stiph true imatrix {stip} imagemask
+ }for
+ }for
+ grestore
+}def
+/Dp{Dfill Dstroke}def
+/DP{Dfill currentpoint newpath moveto}def
+end
+
+/ditstart{$DITroff begin
+ /nfonts 60 def % NFONTS makedev/ditroff dependent!
+ /fonts[nfonts{0}repeat]def
+ /fontnames[nfonts{()}repeat]def
+/docsave save def
+}def
+
+% character outcalls
+/oc{
+ /pswid exch def /cc exch def /name exch def
+ /ditwid pswid fontsize mul resolution mul 72000 div def
+ /ditsiz fontsize resolution mul 72 div def
+ ocprocs name known{ocprocs name get exec}{name cb}ifelse
+}def
+/fractm [.65 0 0 .6 0 0] def
+/fraction{
+ /fden exch def /fnum exch def gsave /cf currentfont def
+ cf fractm makefont setfont 0 .3 dm 2 copy neg rmoveto
+ fnum show rmoveto currentfont cf setfont(\244)show setfont fden show
+ grestore ditwid 0 rmoveto
+}def
+/oce{grestore ditwid 0 rmoveto}def
+/dm{ditsiz mul}def
+/ocprocs 50 dict def ocprocs begin
+(14){(1)(4)fraction}def
+(12){(1)(2)fraction}def
+(34){(3)(4)fraction}def
+(13){(1)(3)fraction}def
+(23){(2)(3)fraction}def
+(18){(1)(8)fraction}def
+(38){(3)(8)fraction}def
+(58){(5)(8)fraction}def
+(78){(7)(8)fraction}def
+(sr){gsave 0 .06 dm rmoveto(\326)show oce}def
+(is){gsave 0 .15 dm rmoveto(\362)show oce}def
+(->){gsave 0 .02 dm rmoveto(\256)show oce}def
+(<-){gsave 0 .02 dm rmoveto(\254)show oce}def
+(==){gsave 0 .05 dm rmoveto(\272)show oce}def
+(uc){gsave currentpoint 400 .009 dm mul add translate
+ 8 -8 scale ucseal oce}def
+end
+
+% an attempt at a PostScript FONT to implement ditroff special chars
+% this will enable us to
+% cache the little buggers
+% generate faster, more compact PS out of psdit
+% confuse everyone (including myself)!
+50 dict dup begin
+/FontType 3 def
+/FontName /DIThacks def
+/FontMatrix [.001 0 0 .001 0 0] def
+/FontBBox [-260 -260 900 900] def% a lie but ...
+/Encoding 256 array def
+0 1 255{Encoding exch /.notdef put}for
+Encoding
+ dup 8#040/space put %space
+ dup 8#110/rc put %right ceil
+ dup 8#111/lt put %left top curl
+ dup 8#112/bv put %bold vert
+ dup 8#113/lk put %left mid curl
+ dup 8#114/lb put %left bot curl
+ dup 8#115/rt put %right top curl
+ dup 8#116/rk put %right mid curl
+ dup 8#117/rb put %right bot curl
+ dup 8#120/rf put %right floor
+ dup 8#121/lf put %left floor
+ dup 8#122/lc put %left ceil
+ dup 8#140/sq put %square
+ dup 8#141/bx put %box
+ dup 8#142/ci put %circle
+ dup 8#143/br put %box rule
+ dup 8#144/rn put %root extender
+ dup 8#145/vr put %vertical rule
+ dup 8#146/ob put %outline bullet
+ dup 8#147/bu put %bullet
+ dup 8#150/ru put %rule
+ dup 8#151/ul put %underline
+ pop
+/DITfd 100 dict def
+/BuildChar{0 begin
+ /cc exch def /fd exch def
+ /charname fd /Encoding get cc get def
+ /charwid fd /Metrics get charname get def
+ /charproc fd /CharProcs get charname get def
+ charwid 0 fd /FontBBox get aload pop setcachedevice
+ 2 setlinejoin 40 setlinewidth
+ newpath 0 0 moveto gsave charproc grestore
+ end}def
+/BuildChar load 0 DITfd put
+/CharProcs 50 dict def
+CharProcs begin
+/space{}def
+/.notdef{}def
+/ru{500 0 rls}def
+/rn{0 840 moveto 500 0 rls}def
+/vr{0 800 moveto 0 -770 rls}def
+/bv{0 800 moveto 0 -1000 rls}def
+/br{0 840 moveto 0 -1000 rls}def
+/ul{0 -140 moveto 500 0 rls}def
+/ob{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath stroke}def
+/bu{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath fill}def
+/sq{80 0 rmoveto currentpoint dround newpath moveto
+ 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath stroke}def
+/bx{80 0 rmoveto currentpoint dround newpath moveto
+ 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath fill}def
+/ci{500 360 rmoveto currentpoint newpath 333 0 360 arc
+ 50 setlinewidth stroke}def
+
+/lt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 add exch s4 a4p stroke}def
+/lb{0 800 moveto 0 -550 rlineto currx -200 2cx s4 add exch s4 a4p stroke}def
+/rt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 sub exch s4 a4p stroke}def
+/rb{0 800 moveto 0 -500 rlineto currx -200 2cx s4 sub exch s4 a4p stroke}def
+/lk{0 800 moveto 0 300 -300 300 s4 arcto pop pop 1000 sub
+ 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def
+/rk{0 800 moveto 0 300 s2 300 s4 arcto pop pop 1000 sub
+ 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def
+/lf{0 800 moveto 0 -1000 rlineto s4 0 rls}def
+/rf{0 800 moveto 0 -1000 rlineto s4 neg 0 rls}def
+/lc{0 -200 moveto 0 1000 rlineto s4 0 rls}def
+/rc{0 -200 moveto 0 1000 rlineto s4 neg 0 rls}def
+end
+
+/Metrics 50 dict def Metrics begin
+/.notdef 0 def
+/space 500 def
+/ru 500 def
+/br 0 def
+/lt 416 def
+/lb 416 def
+/rt 416 def
+/rb 416 def
+/lk 416 def
+/rk 416 def
+/rc 416 def
+/lc 416 def
+/rf 416 def
+/lf 416 def
+/bv 416 def
+/ob 350 def
+/bu 350 def
+/ci 750 def
+/bx 750 def
+/sq 750 def
+/rn 500 def
+/ul 500 def
+/vr 0 def
+end
+
+DITfd begin
+/s2 500 def /s4 250 def /s3 333 def
+/a4p{arcto pop pop pop pop}def
+/2cx{2 copy exch}def
+/rls{rlineto stroke}def
+/currx{currentpoint pop}def
+/dround{transform round exch round exch itransform} def
+end
+end
+/DIThacks exch definefont pop
+ditstart
+(psc)xT
+576 1 1 xr
+1(Times-Roman)xf 1 f
+2(Times-Italic)xf 2 f
+3(Times-Bold)xf 3 f
+4(Times-BoldItalic)xf 4 f
+5(Helvetica)xf 5 f
+6(Helvetica-Bold)xf 6 f
+7(Courier)xf 7 f
+8(Courier-Bold)xf 8 f
+9(Symbol)xf 9 f
+10(DIThacks)xf 10 f
+10 s
+1 f
+xi
+%%EndProlog
+
+%%Page: 1 1
+10 s 10 xH 0 xS 1 f
+3 f
+22 s
+1249 626(A)N
+1420(N)X
+1547(ew)X
+1796(H)X
+1933(ashing)X
+2467(P)X
+2574(ackage)X
+3136(for)X
+3405(U)X
+3532(N)X
+3659(IX)X
+2 f
+20 s
+3855 562(1)N
+1 f
+12 s
+1607 779(Margo)N
+1887(Seltzer)X
+9 f
+2179(-)X
+1 f
+2256(University)X
+2686(of)X
+2790(California,)X
+3229(Berkeley)X
+2015 875(Ozan)N
+2242(Yigit)X
+9 f
+2464(-)X
+1 f
+2541(York)X
+2762(University)X
+3 f
+2331 1086(ABSTRACT)N
+1 f
+10 s
+1152 1222(UNIX)N
+1385(support)X
+1657(of)X
+1756(disk)X
+1921(oriented)X
+2216(hashing)X
+2497(was)X
+2654(originally)X
+2997(provided)X
+3314(by)X
+2 f
+3426(dbm)X
+1 f
+3595([ATT79])X
+3916(and)X
+1152 1310(subsequently)N
+1595(improved)X
+1927(upon)X
+2112(in)X
+2 f
+2199(ndbm)X
+1 f
+2402([BSD86].)X
+2735(In)X
+2826(AT&T)X
+3068(System)X
+3327(V,)X
+3429(in-memory)X
+3809(hashed)X
+1152 1398(storage)N
+1420(and)X
+1572(access)X
+1814(support)X
+2090(was)X
+2251(added)X
+2479(in)X
+2577(the)X
+2 f
+2711(hsearch)X
+1 f
+3000(library)X
+3249(routines)X
+3542([ATT85].)X
+3907(The)X
+1152 1486(result)N
+1367(is)X
+1457(a)X
+1530(system)X
+1789(with)X
+1968(two)X
+2125(incompatible)X
+2580(hashing)X
+2865(schemes,)X
+3193(each)X
+3377(with)X
+3555(its)X
+3666(own)X
+3840(set)X
+3965(of)X
+1152 1574(shortcomings.)N
+1152 1688(This)N
+1316(paper)X
+1517(presents)X
+1802(the)X
+1922(design)X
+2152(and)X
+2289(performance)X
+2717(characteristics)X
+3198(of)X
+3286(a)X
+3343(new)X
+3498(hashing)X
+3768(package)X
+1152 1776(providing)N
+1483(a)X
+1539(superset)X
+1822(of)X
+1909(the)X
+2027(functionality)X
+2456(provided)X
+2761(by)X
+2 f
+2861(dbm)X
+1 f
+3019(and)X
+2 f
+3155(hsearch)X
+1 f
+3409(.)X
+3469(The)X
+3614(new)X
+3768(package)X
+1152 1864(uses)N
+1322(linear)X
+1537(hashing)X
+1818(to)X
+1912(provide)X
+2189(ef\256cient)X
+2484(support)X
+2755(of)X
+2853(both)X
+3026(memory)X
+3324(based)X
+3538(and)X
+3685(disk)X
+3849(based)X
+1152 1952(hash)N
+1319(tables)X
+1526(with)X
+1688(performance)X
+2115(superior)X
+2398(to)X
+2480(both)X
+2 f
+2642(dbm)X
+1 f
+2800(and)X
+2 f
+2936(hsearch)X
+1 f
+3210(under)X
+3413(most)X
+3588(conditions.)X
+3 f
+1380 2128(Introduction)N
+1 f
+892 2260(Current)N
+1196(UNIX)X
+1456(systems)X
+1768(offer)X
+1984(two)X
+2163(forms)X
+2409(of)X
+720 2348(hashed)N
+973(data)X
+1137(access.)X
+2 f
+1413(Dbm)X
+1 f
+1599(and)X
+1745(its)X
+1850(derivatives)X
+2231(provide)X
+720 2436(keyed)N
+939(access)X
+1171(to)X
+1259(disk)X
+1418(resident)X
+1698(data)X
+1858(while)X
+2 f
+2062(hsearch)X
+1 f
+2342(pro-)X
+720 2524(vides)N
+929(access)X
+1175(for)X
+1309(memory)X
+1616(resident)X
+1910(data.)X
+2124(These)X
+2356(two)X
+720 2612(access)N
+979(methods)X
+1302(are)X
+1453(incompatible)X
+1923(in)X
+2037(that)X
+2209(memory)X
+720 2700(resident)N
+1011(hash)X
+1195(tables)X
+1419(may)X
+1593(not)X
+1731(be)X
+1843(stored)X
+2075(on)X
+2191(disk)X
+2360(and)X
+720 2788(disk)N
+884(resident)X
+1169(tables)X
+1387(cannot)X
+1632(be)X
+1739(read)X
+1909(into)X
+2063(memory)X
+2360(and)X
+720 2876(accessed)N
+1022(using)X
+1215(the)X
+1333(in-memory)X
+1709(routines.)X
+2 f
+892 2990(Dbm)N
+1 f
+1091(has)X
+1241(several)X
+1512(shortcomings.)X
+2026(Since)X
+2247(data)X
+2423(is)X
+720 3078(assumed)N
+1032(to)X
+1130(be)X
+1242(disk)X
+1411(resident,)X
+1721(each)X
+1905(access)X
+2146(requires)X
+2440(a)X
+720 3166(system)N
+963(call,)X
+1120(and)X
+1257(almost)X
+1491(certainly,)X
+1813(a)X
+1869(disk)X
+2022(operation.)X
+2365(For)X
+720 3254(extremely)N
+1072(large)X
+1264(databases,)X
+1623(where)X
+1851(caching)X
+2131(is)X
+2214(unlikely)X
+720 3342(to)N
+810(be)X
+914(effective,)X
+1244(this)X
+1386(is)X
+1466(acceptable,)X
+1853(however,)X
+2177(when)X
+2378(the)X
+720 3430(database)N
+1022(is)X
+1100(small)X
+1298(\(i.e.)X
+1447(the)X
+1569(password)X
+1896(\256le\),)X
+2069(performance)X
+720 3518(improvements)N
+1204(can)X
+1342(be)X
+1443(obtained)X
+1744(through)X
+2018(caching)X
+2293(pages)X
+720 3606(of)N
+818(the)X
+947(database)X
+1255(in)X
+1348(memory.)X
+1685(In)X
+1782(addition,)X
+2 f
+2094(dbm)X
+1 f
+2262(cannot)X
+720 3694(store)N
+902(data)X
+1062(items)X
+1261(whose)X
+1492(total)X
+1660(key)X
+1802(and)X
+1943(data)X
+2102(size)X
+2252(exceed)X
+720 3782(the)N
+850(page)X
+1034(size)X
+1191(of)X
+1290(the)X
+1420(hash)X
+1599(table.)X
+1827(Similarly,)X
+2176(if)X
+2257(two)X
+2409(or)X
+720 3870(more)N
+907(keys)X
+1076(produce)X
+1357(the)X
+1477(same)X
+1664(hash)X
+1833(value)X
+2029(and)X
+2166(their)X
+2334(total)X
+720 3958(size)N
+876(exceeds)X
+1162(the)X
+1291(page)X
+1474(size,)X
+1650(the)X
+1779(table)X
+1966(cannot)X
+2210(store)X
+2396(all)X
+720 4046(the)N
+838(colliding)X
+1142(keys.)X
+892 4160(The)N
+1050(in-memory)X
+2 f
+1439(hsearch)X
+1 f
+1725(routines)X
+2015(have)X
+2199(different)X
+720 4248(shortcomings.)N
+1219(First,)X
+1413(the)X
+1539(notion)X
+1771(of)X
+1865(a)X
+1928(single)X
+2146(hash)X
+2320(table)X
+720 4336(is)N
+807(embedded)X
+1171(in)X
+1266(the)X
+1397(interface,)X
+1732(preventing)X
+2108(an)X
+2217(applica-)X
+720 4424(tion)N
+902(from)X
+1116(accessing)X
+1482(multiple)X
+1806(tables)X
+2050(concurrently.)X
+720 4512(Secondly,)N
+1063(the)X
+1186(routine)X
+1438(to)X
+1525(create)X
+1743(a)X
+1804(hash)X
+1976(table)X
+2157(requires)X
+2440(a)X
+720 4600(parameter)N
+1066(which)X
+1286(declares)X
+1573(the)X
+1694(size)X
+1842(of)X
+1932(the)X
+2053(hash)X
+2223(table.)X
+2422(If)X
+720 4688(this)N
+856(size)X
+1001(is)X
+1074(set)X
+1183(too)X
+1305(low,)X
+1465(performance)X
+1892(degradation)X
+2291(or)X
+2378(the)X
+720 4776(inability)N
+1008(to)X
+1092(add)X
+1230(items)X
+1425(to)X
+1509(the)X
+1628(table)X
+1805(may)X
+1964(result.)X
+2223(In)X
+2311(addi-)X
+720 4864(tion,)N
+2 f
+910(hsearch)X
+1 f
+1210(requires)X
+1515(that)X
+1681(the)X
+1825(application)X
+2226(allocate)X
+720 4952(memory)N
+1037(for)X
+1181(the)X
+1329(key)X
+1495(and)X
+1661(data)X
+1845(items.)X
+2108(Lastly,)X
+2378(the)X
+2 f
+720 5040(hsearch)N
+1 f
+1013(routines)X
+1310(provide)X
+1594(no)X
+1713(interface)X
+2034(to)X
+2135(store)X
+2329(hash)X
+720 5128(tables)N
+927(on)X
+1027(disk.)X
+16 s
+720 5593 MXY
+864 0 Dl
+2 f
+8 s
+760 5648(1)N
+1 f
+9 s
+5673(UNIX)Y
+990(is)X
+1056(a)X
+1106(registered)X
+1408(trademark)X
+1718(of)X
+1796(AT&T.)X
+10 s
+2878 2128(The)N
+3032(goal)X
+3199(of)X
+3295(our)X
+3431(work)X
+3625(was)X
+3779(to)X
+3870(design)X
+4108(and)X
+4253(imple-)X
+2706 2216(ment)N
+2900(a)X
+2970(new)X
+3138(package)X
+3436(that)X
+3590(provides)X
+3899(a)X
+3968(superset)X
+4264(of)X
+4364(the)X
+2706 2304(functionality)N
+3144(of)X
+3240(both)X
+2 f
+3411(dbm)X
+1 f
+3578(and)X
+2 f
+3723(hsearch)X
+1 f
+3977(.)X
+4045(The)X
+4198(package)X
+2706 2392(had)N
+2871(to)X
+2982(overcome)X
+3348(the)X
+3495(interface)X
+3826(shortcomings)X
+4306(cited)X
+2706 2480(above)N
+2930(and)X
+3078(its)X
+3185(implementation)X
+3719(had)X
+3867(to)X
+3961(provide)X
+4238(perfor-)X
+2706 2568(mance)N
+2942(equal)X
+3142(or)X
+3235(superior)X
+3524(to)X
+3612(that)X
+3758(of)X
+3851(the)X
+3975(existing)X
+4253(imple-)X
+2706 2656(mentations.)N
+3152(In)X
+3274(order)X
+3498(to)X
+3614(provide)X
+3913(a)X
+4003(compact)X
+4329(disk)X
+2706 2744(representation,)N
+3224(graceful)X
+3531(table)X
+3729(growth,)X
+4018(and)X
+4176(expected)X
+2706 2832(constant)N
+3033(time)X
+3234(performance,)X
+3720(we)X
+3873(selected)X
+4191(Litwin's)X
+2706 2920(linear)N
+2923(hashing)X
+3206(algorithm)X
+3551([LAR88,)X
+3872(LIT80].)X
+4178(We)X
+4324(then)X
+2706 3008(enhanced)N
+3037(the)X
+3161(algorithm)X
+3498(to)X
+3586(handle)X
+3826(page)X
+4004(over\257ows)X
+4346(and)X
+2706 3096(large)N
+2900(key)X
+3049(handling)X
+3362(with)X
+3537(a)X
+3606(single)X
+3830(mechanism,)X
+4248(named)X
+2706 3184(buddy-in-waiting.)N
+3 f
+2975 3338(Existing)N
+3274(UNIX)X
+3499(Hashing)X
+3802(Techniques)X
+1 f
+2878 3470(Over)N
+3076(the)X
+3210(last)X
+3357(decade,)X
+3637(several)X
+3901(dynamic)X
+4213(hashing)X
+2706 3558(schemes)N
+3000(have)X
+3174(been)X
+3348(developed)X
+3700(for)X
+3816(the)X
+3936(UNIX)X
+4159(timeshar-)X
+2706 3646(ing)N
+2856(system,)X
+3146(starting)X
+3433(with)X
+3622(the)X
+3767(inclusion)X
+4107(of)X
+2 f
+4221(dbm)X
+1 f
+4359(,)X
+4426(a)X
+2706 3734(minimal)N
+3008(database)X
+3321(library)X
+3571(written)X
+3834(by)X
+3950(Ken)X
+4120(Thompson)X
+2706 3822([THOM90],)N
+3141(in)X
+3248(the)X
+3391(Seventh)X
+3694(Edition)X
+3974(UNIX)X
+4220(system.)X
+2706 3910(Since)N
+2916(then,)X
+3106(an)X
+3214(extended)X
+3536(version)X
+3804(of)X
+3903(the)X
+4032(same)X
+4228(library,)X
+2 f
+2706 3998(ndbm)N
+1 f
+2884(,)X
+2933(and)X
+3078(a)X
+3142(public-domain)X
+3637(clone)X
+3839(of)X
+3934(the)X
+4060(latter,)X
+2 f
+4273(sdbm)X
+1 f
+4442(,)X
+2706 4086(have)N
+2902(been)X
+3098(developed.)X
+3491(Another)X
+3797 0.1645(interface-compatible)AX
+2706 4174(library)N
+2 f
+2950(gdbm)X
+1 f
+3128(,)X
+3178(was)X
+3333(recently)X
+3622(made)X
+3826(available)X
+4145(as)X
+4241(part)X
+4395(of)X
+2706 4262(the)N
+2829(Free)X
+2997(Software)X
+3312(Foundation's)X
+3759(\(FSF\))X
+3970(software)X
+4271(distri-)X
+2706 4350(bution.)N
+2878 4464(All)N
+3017(of)X
+3121(these)X
+3323(implementations)X
+3893(are)X
+4029(based)X
+4248(on)X
+4364(the)X
+2706 4552(idea)N
+2871(of)X
+2969(revealing)X
+3299(just)X
+3445(enough)X
+3711(bits)X
+3856(of)X
+3953(a)X
+4019(hash)X
+4196(value)X
+4400(to)X
+2706 4640(locate)N
+2920(a)X
+2978(page)X
+3151(in)X
+3234(a)X
+3291(single)X
+3503(access.)X
+3770(While)X
+2 f
+3987(dbm/ndbm)X
+1 f
+4346(and)X
+2 f
+2706 4728(sdbm)N
+1 f
+2908(map)X
+3079(the)X
+3210(hash)X
+3390(value)X
+3597(directly)X
+3874(to)X
+3968(a)X
+4036(disk)X
+4201(address,)X
+2 f
+2706 4816(gdbm)N
+1 f
+2921(uses)X
+3096(the)X
+3231(hash)X
+3414(value)X
+3624(to)X
+3722(index)X
+3936(into)X
+4096(a)X
+2 f
+4168(directory)X
+1 f
+2706 4904([ENB88])N
+3020(containing)X
+3378(disk)X
+3531(addresses.)X
+2878 5018(The)N
+2 f
+3033(hsearch)X
+1 f
+3317(routines)X
+3605(in)X
+3697(System)X
+3962(V)X
+4049(are)X
+4177(designed)X
+2706 5106(to)N
+2804(provide)X
+3085(memory-resident)X
+3669(hash)X
+3852(tables.)X
+4115(Since)X
+4328(data)X
+2706 5194(access)N
+2948(does)X
+3131(not)X
+3269(require)X
+3533(disk)X
+3702(access,)X
+3964(simple)X
+4213(hashing)X
+2706 5282(schemes)N
+3010(which)X
+3238(may)X
+3408(require)X
+3667(multiple)X
+3964(probes)X
+4209(into)X
+4364(the)X
+2706 5370(table)N
+2889(are)X
+3015(used.)X
+3209(A)X
+3294(more)X
+3486(interesting)X
+3851(version)X
+4114(of)X
+2 f
+4208(hsearch)X
+1 f
+2706 5458(is)N
+2784(a)X
+2845(public)X
+3070(domain)X
+3335(library,)X
+2 f
+3594(dynahash)X
+1 f
+3901(,)X
+3945(that)X
+4089(implements)X
+2706 5546(Larson's)N
+3036(in-memory)X
+3440(adaptation)X
+3822([LAR88])X
+4164(of)X
+4279(linear)X
+2706 5634(hashing)N
+2975([LIT80].)X
+3 f
+720 5960(USENIX)N
+9 f
+1042(-)X
+3 f
+1106(Winter)X
+1371('91)X
+9 f
+1498(-)X
+3 f
+1562(Dallas,)X
+1815(TX)X
+1 f
+4424(1)X
+
+2 p
+%%Page: 2 2
+10 s 10 xH 0 xS 1 f
+3 f
+432 258(A)N
+510(New)X
+682(Hashing)X
+985(Package)X
+1290(for)X
+1413(UNIX)X
+3663(Seltzer)X
+3920(&)X
+4007(Yigit)X
+2 f
+1074 538(dbm)N
+1 f
+1232(and)X
+2 f
+1368(ndbm)X
+1 f
+604 670(The)N
+2 f
+760(dbm)X
+1 f
+928(and)X
+2 f
+1074(ndbm)X
+1 f
+1282(library)X
+1526(implementations)X
+2089(are)X
+432 758(based)N
+667(on)X
+799(the)X
+949(same)X
+1166(algorithm)X
+1529(by)X
+1661(Ken)X
+1846(Thompson)X
+432 846([THOM90,)N
+824(TOR88,)X
+1113(WAL84],)X
+1452(but)X
+1582(differ)X
+1789(in)X
+1879(their)X
+2054(pro-)X
+432 934(grammatic)N
+801(interfaces.)X
+1160(The)X
+1311(latter)X
+1502(is)X
+1581(a)X
+1643(modi\256ed)X
+1952(version)X
+432 1022(of)N
+533(the)X
+665(former)X
+918(which)X
+1148(adds)X
+1328(support)X
+1601(for)X
+1728(multiple)X
+2027(data-)X
+432 1110(bases)N
+634(to)X
+724(be)X
+828(open)X
+1011(concurrently.)X
+1484(The)X
+1636(discussion)X
+1996(of)X
+2090(the)X
+432 1198(algorithm)N
+774(that)X
+925(follows)X
+1196(is)X
+1280(applicable)X
+1640(to)X
+1732(both)X
+2 f
+1904(dbm)X
+1 f
+2072(and)X
+2 f
+432 1286(ndbm)N
+1 f
+610(.)X
+604 1400(The)N
+760(basic)X
+956(structure)X
+1268(of)X
+2 f
+1366(dbm)X
+1 f
+1535(calls)X
+1712(for)X
+1836(\256xed-sized)X
+432 1488(disk)N
+612(blocks)X
+868(\(buckets\))X
+1214(and)X
+1377(an)X
+2 f
+1499(access)X
+1 f
+1755(function)X
+2068(that)X
+432 1576(maps)N
+623(a)X
+681(key)X
+819(to)X
+902(a)X
+959(bucket.)X
+1234(The)X
+1380(interface)X
+1683(routines)X
+1962(use)X
+2090(the)X
+2 f
+432 1664(access)N
+1 f
+673(function)X
+970(to)X
+1062(obtain)X
+1292(the)X
+1420(appropriate)X
+1816(bucket)X
+2060(in)X
+2152(a)X
+432 1752(single)N
+643(disk)X
+796(access.)X
+604 1866(Within)N
+869(the)X
+2 f
+1010(access)X
+1 f
+1263(function,)X
+1593(a)X
+1672(bit-randomizing)X
+432 1954(hash)N
+610(function)X
+2 f
+8 s
+877 1929(2)N
+1 f
+10 s
+940 1954(is)N
+1024(used)X
+1202(to)X
+1294(convert)X
+1565(a)X
+1631(key)X
+1777(into)X
+1931(a)X
+1997(32-bit)X
+432 2042(hash)N
+605(value.)X
+825(Out)X
+971(of)X
+1064(these)X
+1254(32)X
+1359(bits,)X
+1519(only)X
+1686(as)X
+1778(many)X
+1981(bits)X
+2121(as)X
+432 2130(necessary)N
+773(are)X
+900(used)X
+1075(to)X
+1165(determine)X
+1514(the)X
+1639(particular)X
+1974(bucket)X
+432 2218(on)N
+533(which)X
+750(a)X
+807(key)X
+944(resides.)X
+1228(An)X
+1347(in-memory)X
+1724(bitmap)X
+1967(is)X
+2041(used)X
+432 2306(to)N
+533(determine)X
+893(how)X
+1070(many)X
+1287(bits)X
+1441(are)X
+1579(required.)X
+1905(Each)X
+2104(bit)X
+432 2394(indicates)N
+746(whether)X
+1033(its)X
+1136(associated)X
+1494(bucket)X
+1736(has)X
+1871(been)X
+2051(split)X
+432 2482(yet)N
+562(\(a)X
+657(0)X
+728(indicating)X
+1079(that)X
+1230(the)X
+1359(bucket)X
+1604(has)X
+1742(not)X
+1875(yet)X
+2004(split\).)X
+432 2570(The)N
+590(use)X
+730(of)X
+830(the)X
+961(hash)X
+1141(function)X
+1441(and)X
+1590(the)X
+1720(bitmap)X
+1974(is)X
+2059(best)X
+432 2658(described)N
+769(by)X
+878(stepping)X
+1177(through)X
+1454(database)X
+1759(creation)X
+2046(with)X
+432 2746(multiple)N
+718(invocations)X
+1107(of)X
+1194(a)X
+2 f
+1250(store)X
+1 f
+1430(operation.)X
+604 2860(Initially,)N
+906(the)X
+1033(hash)X
+1209(table)X
+1394(contains)X
+1690(a)X
+1755(single)X
+1974(bucket)X
+432 2948(\(bucket)N
+711(0\),)X
+836(the)X
+972(bit)X
+1094(map)X
+1270(contains)X
+1575(a)X
+1649(single)X
+1878(bit)X
+2000(\(bit)X
+2148(0)X
+432 3036(corresponding)N
+913(to)X
+997(bucket)X
+1233(0\),)X
+1342(and)X
+1480(0)X
+1542(bits)X
+1699(of)X
+1788(a)X
+1846(hash)X
+2014(value)X
+432 3124(are)N
+560(examined)X
+901(to)X
+992(determine)X
+1342(where)X
+1568(a)X
+1633(key)X
+1778(is)X
+1860(placed)X
+2099(\(in)X
+432 3212(bucket)N
+670(0\).)X
+801(When)X
+1017(bucket)X
+1255(0)X
+1319(is)X
+1396(full,)X
+1551(its)X
+1650(bit)X
+1758(in)X
+1844(the)X
+1966(bitmap)X
+432 3300(\(bit)N
+564(0\))X
+652(is)X
+726(set,)X
+856(and)X
+993(its)X
+1089(contents)X
+1377(are)X
+1497(split)X
+1655(between)X
+1943(buckets)X
+432 3388(0)N
+499(and)X
+641(1,)X
+727(by)X
+833(considering)X
+1233(the)X
+1357(0)X
+2 f
+7 s
+3356(th)Y
+10 s
+1 f
+1480 3388(bit)N
+1590(\(the)X
+1741(lowest)X
+1976(bit)X
+2086(not)X
+432 3476(previously)N
+800(examined\))X
+1169(of)X
+1266(the)X
+1393(hash)X
+1569(value)X
+1772(for)X
+1895(each)X
+2072(key)X
+432 3564(within)N
+668(the)X
+798(bucket.)X
+1064(Given)X
+1292(a)X
+1359(well-designed)X
+1840(hash)X
+2018(func-)X
+432 3652(tion,)N
+613(approximately)X
+1112(half)X
+1273(of)X
+1376(the)X
+1510(keys)X
+1693(will)X
+1853(have)X
+2041(hash)X
+432 3740(values)N
+666(with)X
+837(the)X
+964(0)X
+2 f
+7 s
+3708(th)Y
+10 s
+1 f
+1090 3740(bit)N
+1203(set.)X
+1341(All)X
+1471(such)X
+1646(keys)X
+1821(and)X
+1965(associ-)X
+432 3828(ated)N
+586(data)X
+740(are)X
+859(moved)X
+1097(to)X
+1179(bucket)X
+1413(1,)X
+1493(and)X
+1629(the)X
+1747(rest)X
+1883(remain)X
+2126(in)X
+432 3916(bucket)N
+666(0.)X
+604 4030(After)N
+804(this)X
+949(split,)X
+1135(the)X
+1262(\256le)X
+1393(now)X
+1560(contains)X
+1856(two)X
+2005(buck-)X
+432 4118(ets,)N
+562(and)X
+699(the)X
+818(bitmap)X
+1061(contains)X
+1349(three)X
+1530(bits:)X
+1687(the)X
+1805(0)X
+2 f
+7 s
+4086(th)Y
+10 s
+1 f
+1922 4118(bit)N
+2026(is)X
+2099(set)X
+432 4206(to)N
+525(indicate)X
+810(a)X
+876(bucket)X
+1120(0)X
+1190(split)X
+1357(when)X
+1561(no)X
+1671(bits)X
+1816(of)X
+1913(the)X
+2041(hash)X
+432 4294(value)N
+648(are)X
+789(considered,)X
+1199(and)X
+1357(two)X
+1519(more)X
+1726(unset)X
+1937(bits)X
+2094(for)X
+432 4382(buckets)N
+706(0)X
+775(and)X
+920(1.)X
+1029(The)X
+1183(placement)X
+1542(of)X
+1638(an)X
+1742(incoming)X
+2072(key)X
+432 4470(now)N
+604(requires)X
+897(examination)X
+1327(of)X
+1428(the)X
+1560(0)X
+2 f
+7 s
+4438(th)Y
+10 s
+1 f
+1691 4470(bit)N
+1809(of)X
+1910(the)X
+2041(hash)X
+432 4558(value,)N
+667(and)X
+824(the)X
+963(key)X
+1119(is)X
+1212(placed)X
+1462(either)X
+1685(in)X
+1787(bucket)X
+2041(0)X
+2121(or)X
+432 4646(bucket)N
+674(1.)X
+782(If)X
+864(either)X
+1075(bucket)X
+1317(0)X
+1385(or)X
+1480(bucket)X
+1722(1)X
+1790(\256lls)X
+1937(up,)X
+2064(it)X
+2135(is)X
+432 4734(split)N
+598(as)X
+693(before,)X
+947(its)X
+1050(bit)X
+1162(is)X
+1243(set)X
+1360(in)X
+1450(the)X
+1576(bitmap,)X
+1846(and)X
+1990(a)X
+2054(new)X
+432 4822(set)N
+541(of)X
+628(unset)X
+817(bits)X
+952(are)X
+1071(added)X
+1283(to)X
+1365(the)X
+1483(bitmap.)X
+604 4936(Each)N
+791(time)X
+959(we)X
+1079(consider)X
+1376(a)X
+1437(new)X
+1596(bit)X
+1705(\(bit)X
+1841(n\),)X
+1953(we)X
+2072(add)X
+432 5024(2)N
+2 f
+7 s
+4992(n)Y
+9 f
+509(+)X
+1 f
+540(1)X
+10 s
+595 5024(bits)N
+737(to)X
+826(the)X
+951(bitmap)X
+1199(and)X
+1341(obtain)X
+1567(2)X
+2 f
+7 s
+4992(n)Y
+9 f
+1644(+)X
+1 f
+1675(1)X
+10 s
+1729 5024(more)N
+1920(address-)X
+432 5112(able)N
+595(buckets)X
+869(in)X
+960(the)X
+1087(\256le.)X
+1258(As)X
+1376(a)X
+1441(result,)X
+1668(the)X
+1795(bitmap)X
+2045(con-)X
+432 5200(tains)N
+618(the)X
+751(previous)X
+1062(2)X
+2 f
+7 s
+5168(n)Y
+9 f
+1139(+)X
+1 f
+1170(1)X
+2 f
+10 s
+9 f
+5200(-)Y
+1 f
+1242(1)X
+1317(bits)X
+1467(\(1)X
+2 f
+9 f
+1534(+)X
+1 f
+1578(2)X
+2 f
+9 f
+(+)S
+1 f
+1662(4)X
+2 f
+9 f
+(+)S
+1 f
+1746(...)X
+2 f
+9 f
+(+)S
+1 f
+1850(2)X
+2 f
+7 s
+5168(n)Y
+10 s
+1 f
+1931 5200(\))N
+1992(which)X
+432 5288(trace)N
+649(the)X
+807(entire)X
+2 f
+1050(split)X
+1247(history)X
+1 f
+1529(of)X
+1656(the)X
+1813(addressable)X
+16 s
+432 5433 MXY
+864 0 Dl
+2 f
+8 s
+472 5488(2)N
+1 f
+9 s
+523 5513(This)N
+670(bit-randomizing)X
+1153(property)X
+1416(is)X
+1482(important)X
+1780(to)X
+1854(obtain)X
+2052(radi-)X
+432 5593(cally)N
+599(different)X
+874(hash)X
+1033(values)X
+1244(for)X
+1355(nearly)X
+1562(identical)X
+1836(keys,)X
+2012(which)X
+432 5673(in)N
+506(turn)X
+640(avoids)X
+846(clustering)X
+1148(of)X
+1226(such)X
+1376(keys)X
+1526(in)X
+1600(a)X
+1650(single)X
+1840(bucket.)X
+10 s
+2418 538(buckets.)N
+2590 652(Given)N
+2809(a)X
+2868(key)X
+3007(and)X
+3146(the)X
+3267(bitmap)X
+3512(created)X
+3768(by)X
+3871(this)X
+4009(algo-)X
+2418 740(rithm,)N
+2638(we)X
+2759(\256rst)X
+2910(examine)X
+3209(bit)X
+3320(0)X
+3386(of)X
+3479(the)X
+3603(bitmap)X
+3851(\(the)X
+4002(bit)X
+4112(to)X
+2418 828(consult)N
+2673(when)X
+2871(0)X
+2934(bits)X
+3072(of)X
+3162(the)X
+3283(hash)X
+3453(value)X
+3650(are)X
+3772(being)X
+3973(exam-)X
+2418 916(ined\).)N
+2631(If)X
+2713(it)X
+2785(is)X
+2866(set)X
+2982(\(indicating)X
+3356(that)X
+3503(the)X
+3628(bucket)X
+3869(split\),)X
+4080(we)X
+2418 1004(begin)N
+2617(considering)X
+3012(the)X
+3131(bits)X
+3267(of)X
+3355(the)X
+3473(32-bit)X
+3684(hash)X
+3851(value.)X
+4085(As)X
+2418 1092(bit)N
+2525(n)X
+2587(is)X
+2662(revealed,)X
+2977(a)X
+3035(mask)X
+3226(equal)X
+3422(to)X
+3506(2)X
+2 f
+7 s
+1060(n)Y
+9 f
+3583(+)X
+1 f
+3614(1)X
+2 f
+10 s
+9 f
+1092(-)Y
+1 f
+3686(1)X
+3748(will)X
+3894(yield)X
+4076(the)X
+2418 1180(current)N
+2675(bucket)X
+2918(address.)X
+3228(Adding)X
+3496(2)X
+2 f
+7 s
+1148(n)Y
+9 f
+3573(+)X
+1 f
+3604(1)X
+2 f
+10 s
+9 f
+1180(-)Y
+1 f
+3676(1)X
+3744(to)X
+3834(the)X
+3960(bucket)X
+2418 1268(address)N
+2701(identi\256es)X
+3035(which)X
+3272(bit)X
+3397(in)X
+3500(the)X
+3639(bitmap)X
+3902(must)X
+4098(be)X
+2418 1356(checked.)N
+2743(We)X
+2876(continue)X
+3173(revealing)X
+3493(bits)X
+3628(of)X
+3715(the)X
+3833(hash)X
+4000(value)X
+2418 1444(until)N
+2591(all)X
+2698(set)X
+2814(bits)X
+2955(in)X
+3043(the)X
+3167(bitmap)X
+3415(are)X
+3540(exhausted.)X
+3907(The)X
+4058(fol-)X
+2418 1532(lowing)N
+2682(algorithm,)X
+3055(a)X
+3133(simpli\256cation)X
+3614(of)X
+3723(the)X
+3863(algorithm)X
+2418 1620(due)N
+2565(to)X
+2658(Ken)X
+2823(Thompson)X
+3196([THOM90,)X
+3590(TOR88],)X
+3908(uses)X
+4076(the)X
+2418 1708(hash)N
+2625(value)X
+2839(and)X
+2995(the)X
+3133(bitmap)X
+3395(to)X
+3497(calculate)X
+3823(the)X
+3960(bucket)X
+2418 1796(address)N
+2679(as)X
+2766(discussed)X
+3093(above.)X
+0(Courier)xf 0 f
+1 f
+0 f
+8 s
+2418 2095(hash)N
+2608(=)X
+2684 -0.4038(calchash\(key\);)AX
+2418 2183(mask)N
+2608(=)X
+2684(0;)X
+2418 2271(while)N
+2646 -0.4018(\(isbitset\(\(hash)AX
+3254(&)X
+3330(mask\))X
+3558(+)X
+3634(mask\)\))X
+2706 2359(mask)N
+2896(=)X
+2972(\(mask)X
+3200(<<)X
+3314(1\))X
+3428(+)X
+3504(1;)X
+2418 2447(bucket)N
+2684(=)X
+2760(hash)X
+2950(&)X
+3026(mask;)X
+2 f
+10 s
+3211 2812(sdbm)N
+1 f
+2590 2944(The)N
+2 f
+2738(sdbm)X
+1 f
+2930(library)X
+3167(is)X
+3243(a)X
+3302(public-domain)X
+3791(clone)X
+3987(of)X
+4076(the)X
+2 f
+2418 3032(ndbm)N
+1 f
+2638(library,)X
+2914(developed)X
+3286(by)X
+3408(Ozan)X
+3620(Yigit)X
+3826(to)X
+3929(provide)X
+2 f
+2418 3120(ndbm)N
+1 f
+2596('s)X
+2692(functionality)X
+3139(under)X
+3359(some)X
+3565(versions)X
+3869(of)X
+3973(UNIX)X
+2418 3208(that)N
+2559(exclude)X
+2830(it)X
+2894(for)X
+3008(licensing)X
+3317(reasons)X
+3578([YIG89].)X
+3895(The)X
+4040(pro-)X
+2418 3296(grammer)N
+2735(interface,)X
+3064(and)X
+3207(the)X
+3332(basic)X
+3524(structure)X
+3832(of)X
+2 f
+3926(sdbm)X
+1 f
+4121(is)X
+2418 3384(identical)N
+2733(to)X
+2 f
+2834(ndbm)X
+1 f
+3051(but)X
+3192(internal)X
+3476(details)X
+3723(of)X
+3828(the)X
+2 f
+3964(access)X
+1 f
+2418 3472(function,)N
+2726(such)X
+2894(as)X
+2982(the)X
+3101(calculation)X
+3474(of)X
+3561(the)X
+3679(bucket)X
+3913(address,)X
+2418 3560(and)N
+2563(the)X
+2690(use)X
+2825(of)X
+2920(different)X
+3225(hash)X
+3400(functions)X
+3726(make)X
+3928(the)X
+4054(two)X
+2418 3648(incompatible)N
+2856(at)X
+2934(the)X
+3052(database)X
+3349(level.)X
+2590 3762(The)N
+2 f
+2740(sdbm)X
+1 f
+2934(library)X
+3173(is)X
+3251(based)X
+3458(on)X
+3562(a)X
+3622(simpli\256ed)X
+3965(imple-)X
+2418 3850(mentation)N
+2778(of)X
+2885(Larson's)X
+3206(1978)X
+2 f
+3406(dynamic)X
+3717(hashing)X
+1 f
+4009(algo-)X
+2418 3938(rithm)N
+2616(including)X
+2943(the)X
+2 f
+3066(re\256nements)X
+3461(and)X
+3605(variations)X
+1 f
+3953(of)X
+4044(sec-)X
+2418 4026(tion)N
+2562(5)X
+2622([LAR78].)X
+2956(Larson's)X
+3257(original)X
+3526(algorithm)X
+3857(calls)X
+4024(for)X
+4138(a)X
+2418 4114(forest)N
+2635(of)X
+2736(binary)X
+2975(hash)X
+3156(trees)X
+3341(that)X
+3494(are)X
+3626(accessed)X
+3941(by)X
+4054(two)X
+2418 4202(hash)N
+2586(functions.)X
+2925(The)X
+3071(\256rst)X
+3216(hash)X
+3384(function)X
+3672(selects)X
+3907(a)X
+3964(partic-)X
+2418 4290(ular)N
+2571(tree)X
+2720(within)X
+2952(the)X
+3078(forest.)X
+3309(The)X
+3462(second)X
+3713(hash)X
+3887(function,)X
+2418 4378(which)N
+2659(is)X
+2757(required)X
+3070(to)X
+3177(be)X
+3297(a)X
+3377(boolean)X
+3675(pseudo-random)X
+2418 4466(number)N
+2687(generator)X
+3015(that)X
+3159(is)X
+3236(seeded)X
+3479(by)X
+3583(the)X
+3705(key,)X
+3865(is)X
+3942(used)X
+4112(to)X
+2418 4554(traverse)N
+2733(the)X
+2890(tree)X
+3070(until)X
+3275(internal)X
+3579(\(split\))X
+3829(nodes)X
+4075(are)X
+2418 4642(exhausted)N
+2763(and)X
+2903(an)X
+3003(external)X
+3286(\(non-split\))X
+3648(node)X
+3827(is)X
+3903(reached.)X
+2418 4730(The)N
+2571(bucket)X
+2813(addresses)X
+3149(are)X
+3276(stored)X
+3500(directly)X
+3772(in)X
+3861(the)X
+3986(exter-)X
+2418 4818(nal)N
+2536(nodes.)X
+2590 4932(Larson's)N
+2903(re\256nements)X
+3309(are)X
+3440(based)X
+3655(on)X
+3767(the)X
+3897(observa-)X
+2418 5020(tion)N
+2570(that)X
+2718(the)X
+2844(nodes)X
+3059(can)X
+3199(be)X
+3303(represented)X
+3702(by)X
+3809(a)X
+3872(single)X
+4090(bit)X
+2418 5108(that)N
+2569(is)X
+2653(set)X
+2773(for)X
+2898(internal)X
+3174(nodes)X
+3392(and)X
+3539(not)X
+3672(set)X
+3791(for)X
+3915(external)X
+2418 5196(nodes,)N
+2652(resulting)X
+2959(in)X
+3048(a)X
+3111(radix)X
+3303(search)X
+3536(trie.)X
+3709(Figure)X
+3944(1)X
+4010(illus-)X
+2418 5284(trates)N
+2621(this.)X
+2804(Nodes)X
+3037(A)X
+3123(and)X
+3267(B)X
+3348(are)X
+3475(internal)X
+3748(\(split\))X
+3967(nodes,)X
+2418 5372(thus)N
+2573(having)X
+2813(no)X
+2915(bucket)X
+3151(addresses)X
+3480(associated)X
+3831(with)X
+3994(them.)X
+2418 5460(Instead,)N
+2693(the)X
+2814(external)X
+3096(nodes)X
+3306(\(C,)X
+3429(D,)X
+3530(and)X
+3669(E\))X
+3768(each)X
+3938(need)X
+4112(to)X
+2418 5548(refer)N
+2594(to)X
+2679(a)X
+2738(bucket)X
+2975(address.)X
+3279(These)X
+3494(bucket)X
+3731(addresses)X
+4062(can)X
+2418 5636(be)N
+2529(stored)X
+2760(in)X
+2857(the)X
+2990(trie)X
+3132(itself)X
+3327(where)X
+3559(the)X
+3691(subtries)X
+3974(would)X
+3 f
+432 5960(2)N
+2970(USENIX)X
+9 f
+3292(-)X
+3 f
+3356(Winter)X
+3621('91)X
+9 f
+3748(-)X
+3 f
+3812(Dallas,)X
+4065(TX)X
+
+3 p
+%%Page: 3 3
+0(Courier)xf 0 f
+10 s 10 xH 0 xS 0 f
+3 f
+720 258(Seltzer)N
+977(&)X
+1064(Yigit)X
+3278(A)X
+3356(New)X
+3528(Hashing)X
+3831(Package)X
+4136(for)X
+4259(UNIX)X
+1 f
+720 538(live)N
+862(if)X
+933(they)X
+1092(existed)X
+1340([KNU68].)X
+1709(For)X
+1841(example,)X
+2154(if)X
+2224(nodes)X
+2432(F)X
+720 626(and)N
+858(G)X
+938(were)X
+1117(the)X
+1237(children)X
+1522(of)X
+1610(node)X
+1787(C,)X
+1881(the)X
+2000(bucket)X
+2235(address)X
+720 714(L00)N
+886(could)X
+1101(reside)X
+1330(in)X
+1429(the)X
+1563(bits)X
+1714(that)X
+1870(will)X
+2030(eventually)X
+2400(be)X
+720 802(used)N
+887(to)X
+969(store)X
+1145(nodes)X
+1352(F)X
+1416(and)X
+1552(G)X
+1630(and)X
+1766(all)X
+1866(their)X
+2033(children.)X
+10 f
+720 890 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+3 f
+1894 2247(L1)N
+784 1925(A)N
+1431(E)X
+1106 2247(D)N
+1428 1281(C)N
+1109 1603(B)N
+1884 1930(L01)N
+1879 1286(L00)N
+1221 1814(1)N
+903 2131(1)N
+1221 1402(0)N
+903 1714(0)N
+1 Dt
+1397 1821 MXY
+-8 -32 Dl
+-5 19 Dl
+-20 6 Dl
+33 7 Dl
+-187 -182 Dl
+1397 1322 MXY
+-33 7 Dl
+20 6 Dl
+5 19 Dl
+8 -32 Dl
+-187 182 Dl
+1069 1639 MXY
+-32 7 Dl
+20 6 Dl
+5 19 Dl
+7 -32 Dl
+-186 182 Dl
+1374 1891 MXY
+185 Dc
+1779 2133 MXY
+0 161 Dl
+322 0 Dl
+0 -161 Dl
+-322 0 Dl
+1811 MY
+0 161 Dl
+322 0 Dl
+0 -161 Dl
+-322 0 Dl
+1166 MY
+0 161 Dl
+322 0 Dl
+0 -161 Dl
+-322 0 Dl
+1052 2213 MXY
+185 Dc
+1569 MY
+185 Dc
+720 1881 MXY
+185 Dc
+1779 2213 MXY
+-28 -17 Dl
+10 17 Dl
+-10 18 Dl
+28 -18 Dl
+-543 0 Dl
+1769 1891 MXY
+-28 -18 Dl
+10 18 Dl
+-10 18 Dl
+28 -18 Dl
+-201 0 Dl
+1364 1247 MXY
+185 Dc
+1769 MX
+-28 -18 Dl
+10 18 Dl
+-10 18 Dl
+28 -18 Dl
+-201 0 Dl
+1064 2143 MXY
+-7 -32 Dl
+-5 19 Dl
+-20 6 Dl
+32 7 Dl
+-181 -181 Dl
+3 Dt
+-1 Ds
+8 s
+720 2482(Figure)N
+925(1:)X
+1 f
+1002(Radix)X
+1179(search)X
+1365(trie)X
+1474(with)X
+1612(internal)X
+1831(nodes)X
+2004(A)X
+2074(and)X
+2189(B,)X
+2271(external)X
+720 2570(nodes)N
+891(C,)X
+972(D,)X
+1056(and)X
+1170(E,)X
+1247(and)X
+1361(bucket)X
+1553(addresses)X
+1819(stored)X
+1997(in)X
+2069(the)X
+2168(unused)X
+2370(por-)X
+720 2658(tion)N
+836(of)X
+905(the)X
+999(trie.)X
+10 s
+10 f
+720 2922 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+1 f
+892 3124(Further)N
+1153(simpli\256cations)X
+1647(of)X
+1738(the)X
+1860(above)X
+2076([YIG89])X
+2377(are)X
+720 3212(possible.)N
+1038(Using)X
+1265(a)X
+1337(single)X
+1564(radix)X
+1765(trie)X
+1908(to)X
+2006(avoid)X
+2219(the)X
+2352(\256rst)X
+720 3300(hash)N
+904(function,)X
+1227(replacing)X
+1562(the)X
+1696(pseudo-random)X
+2231(number)X
+720 3388(generator)N
+1052(with)X
+1222(a)X
+1286(well)X
+1452(designed,)X
+1785(bit-randomizing)X
+2329(hash)X
+720 3476(function,)N
+1053(and)X
+1215(using)X
+1434(the)X
+1578(portion)X
+1855(of)X
+1967(the)X
+2110(hash)X
+2302(value)X
+720 3564(exposed)N
+1021(during)X
+1268(the)X
+1404(trie)X
+1549(traversal)X
+1864(as)X
+1969(a)X
+2042(direct)X
+2262(bucket)X
+720 3652(address)N
+990(results)X
+1228(in)X
+1319(an)X
+2 f
+1424(access)X
+1 f
+1663(function)X
+1959(that)X
+2108(works)X
+2333(very)X
+720 3740(similar)N
+974(to)X
+1068(Thompson's)X
+1499(algorithm)X
+1841(above.)X
+2084(The)X
+2240(follow-)X
+720 3828(ing)N
+847(algorithm)X
+1183(uses)X
+1346(the)X
+1469(hash)X
+1641(value)X
+1840(to)X
+1927(traverse)X
+2206(a)X
+2266(linear-)X
+720 3916(ized)N
+874(radix)X
+1059(trie)X
+2 f
+8 s
+1166 3891(3)N
+1 f
+10 s
+1218 3916(starting)N
+1478(at)X
+1556(the)X
+1674(0)X
+2 f
+7 s
+3884(th)Y
+10 s
+1 f
+1791 3916(bit.)N
+0 f
+8 s
+720 4215(tbit)N
+910(=)X
+986(0;)X
+1296(/*)X
+1410(radix)X
+1638(trie)X
+1828(index)X
+2056(*/)X
+720 4303(hbit)N
+910(=)X
+986(0;)X
+1296(/*)X
+1410(hash)X
+1600(bit)X
+1752(index)X
+2056(*/)X
+720 4391(mask)N
+910(=)X
+986(0;)X
+720 4479(hash)N
+910(=)X
+986 -0.4038(calchash\(key\);)AX
+720 4655(for)N
+872(\(mask)X
+1100(=)X
+1176(0;)X
+910 4743 -0.4018(isbitset\(tbit\);)AN
+910 4831(mask)N
+1100(=)X
+1176(\(mask)X
+1404(<<)X
+1518(1\))X
+1632(+)X
+1708(1\))X
+1008 4919(if)N
+1122(\(hash)X
+1350(&)X
+1426(\(1)X
+1540(<<)X
+1654 -0.4219(hbit++\)\)\))AX
+1160 5007(/*)N
+1274(right)X
+1502(son)X
+1692(*/)X
+1160 5095(tbit)N
+1350(=)X
+1426(2)X
+1502(*)X
+1578(tbit)X
+1768(+)X
+1844(2;)X
+1008 5183(else)N
+1 f
+16 s
+720 5353 MXY
+864 0 Dl
+2 f
+8 s
+760 5408(3)N
+1 f
+9 s
+818 5433(A)N
+896(linearized)X
+1206(radix)X
+1380(trie)X
+1502(is)X
+1576(merely)X
+1802(an)X
+1895(array)X
+2068(representation)X
+720 5513(of)N
+800(the)X
+908(radix)X
+1076(search)X
+1280(trie)X
+1396(described)X
+1692(above.)X
+1920(The)X
+2052(children)X
+2308(of)X
+2388(the)X
+720 5593(node)N
+885(with)X
+1038(index)X
+1223(i)X
+1267(can)X
+1391(be)X
+1483(found)X
+1675(at)X
+1751(the)X
+1863(nodes)X
+2055(indexed)X
+2307(2*i+1)X
+720 5673(and)N
+842(2*i+2.)X
+0 f
+8 s
+3146 538(/*)N
+3260(left)X
+3450(son)X
+3678(*/)X
+3146 626(tbit)N
+3336(=)X
+3412(2)X
+3488(*)X
+3564(tbit)X
+3754(+)X
+3830(1;)X
+2706 802(bucket)N
+2972(=)X
+3048(hash)X
+3238(&)X
+3314(mask;)X
+2 f
+10 s
+3495 1167(gdbm)N
+1 f
+2878 1299(The)N
+3027(gdbm)X
+3233(\(GNU)X
+3458(data)X
+3616(base)X
+3783(manager\))X
+4111(library)X
+4349(is)X
+4426(a)X
+2706 1387(UNIX)N
+2933(database)X
+3236(manager)X
+3539(written)X
+3792(by)X
+3897(Philip)X
+4112(A.)X
+4215(Nelson,)X
+2706 1475(and)N
+2848(made)X
+3048(available)X
+3364(as)X
+3457(a)X
+3518(part)X
+3668(of)X
+3760(the)X
+3883(FSF)X
+4040(software)X
+4342(dis-)X
+2706 1563(tribution.)N
+3052(The)X
+3207(gdbm)X
+3419(library)X
+3663(provides)X
+3969(the)X
+4097(same)X
+4292(func-)X
+2706 1651(tionality)N
+3028(of)X
+3151(the)X
+2 f
+3304(dbm)X
+1 f
+3442(/)X
+2 f
+3464(ndbm)X
+1 f
+3697(libraries)X
+4015([NEL90])X
+4360(but)X
+2706 1739(attempts)N
+3018(to)X
+3121(avoid)X
+3340(some)X
+3550(of)X
+3658(their)X
+3846(shortcomings.)X
+4337(The)X
+2706 1827(gdbm)N
+2918(library)X
+3162(allows)X
+3401(for)X
+3525(arbitrary-length)X
+4059(data,)X
+4242(and)X
+4387(its)X
+2706 1915(database)N
+3027(is)X
+3124(a)X
+3203(singular,)X
+3524(non-sparse)X
+2 f
+8 s
+3872 1890(4)N
+1 f
+10 s
+3947 1915(\256le.)N
+4112(The)X
+4280(gdbm)X
+2706 2003(library)N
+2947(also)X
+3103(includes)X
+2 f
+3396(dbm)X
+1 f
+3560(and)X
+2 f
+3702(ndbm)X
+1 f
+3906(compatible)X
+4288(inter-)X
+2706 2091(faces.)N
+2878 2205(The)N
+3025(gdbm)X
+3229(library)X
+3465(is)X
+3540(based)X
+3745(on)X
+2 f
+3847(extensible)X
+4189(hashing)X
+1 f
+4442(,)X
+2706 2293(a)N
+2766(dynamic)X
+3066(hashing)X
+3339(algorithm)X
+3674(by)X
+3778(Fagin)X
+3984(et)X
+4066(al)X
+4148([FAG79].)X
+2706 2381(This)N
+2881(algorithm)X
+3225(differs)X
+3467(from)X
+3655(the)X
+3785(previously)X
+4155(discussed)X
+2706 2469(algorithms)N
+3069(in)X
+3152(that)X
+3293(it)X
+3358(uses)X
+3517(a)X
+2 f
+3574(directory)X
+1 f
+3889(that)X
+4030(is)X
+4103(a)X
+4159(collapsed)X
+2706 2557(representation)N
+3192([ENB88])X
+3517(of)X
+3615(the)X
+3744(radix)X
+3940(search)X
+4177(trie)X
+4315(used)X
+2706 2645(by)N
+2 f
+2806(sdbm)X
+1 f
+2975(.)X
+10 f
+2706 2733 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+3 f
+7 s
+3572 3761(L1)N
+1 Dt
+3485 3738 MXY
+-20 -13 Dl
+7 13 Dl
+-7 13 Dl
+20 -13 Dl
+-400 0 Dl
+3180 3027 MXY
+136 Dc
+2706 3494 MXY
+136 Dc
+2950 3264 MXY
+136 Dc
+3738 MY
+136 Dc
+3485 2968 MXY
+0 118 Dl
+238 0 Dl
+0 -118 Dl
+-238 0 Dl
+3442 MY
+0 119 Dl
+238 0 Dl
+0 -119 Dl
+-238 0 Dl
+3679 MY
+0 119 Dl
+238 0 Dl
+0 -119 Dl
+-238 0 Dl
+3187 3501 MXY
+136 Dc
+2963 3316 MXY
+-24 5 Dl
+15 4 Dl
+4 15 Dl
+5 -24 Dl
+-137 134 Dl
+3204 3083 MXY
+-24 5 Dl
+15 4 Dl
+3 14 Dl
+6 -23 Dl
+-137 133 Dl
+3204 3450 MXY
+-6 -24 Dl
+-3 14 Dl
+-15 5 Dl
+24 5 Dl
+-137 -134 Dl
+2842 3369(0)N
+3075 3139(0)N
+2842 3676(1)N
+3075 3443(1)N
+3562 3054(L00)N
+3565 3528(L01)N
+4197 2968 MXY
+0 118 Dl
+237 0 Dl
+0 -118 Dl
+-237 0 Dl
+3205 MY
+0 119 Dl
+237 0 Dl
+0 -119 Dl
+-237 0 Dl
+3561 MY
+0 118 Dl
+237 0 Dl
+0 -118 Dl
+-237 0 Dl
+3960 2909 MXY
+0 237 Dl
+118 0 Dl
+0 -237 Dl
+-118 0 Dl
+3146 MY
+0 237 Dl
+118 0 Dl
+0 -237 Dl
+-118 0 Dl
+3383 MY
+0 237 Dl
+118 0 Dl
+0 -237 Dl
+-118 0 Dl
+3620 MY
+0 237 Dl
+118 0 Dl
+0 -237 Dl
+-118 0 Dl
+4197 3027 MXY
+-21 -13 Dl
+8 13 Dl
+-8 13 Dl
+21 -13 Dl
+-119 0 Dl
+4197 3264 MXY
+-21 -13 Dl
+8 13 Dl
+-8 13 Dl
+21 -13 Dl
+-119 0 Dl
+3501 MY
+59 0 Dl
+0 89 Dl
+4078 3738 MXY
+59 0 Dl
+0 -88 Dl
+4197 3590 MXY
+-21 -13 Dl
+8 13 Dl
+-8 13 Dl
+21 -13 Dl
+-60 0 Dl
+4197 3650 MXY
+-21 -13 Dl
+8 13 Dl
+-8 13 Dl
+21 -13 Dl
+-60 0 Dl
+3991 3050(00)N
+3991 3287(01)N
+3991 3524(10)N
+3991 3761(11)N
+4269 3050(L00)N
+4269 3287(L01)N
+4283 3643(L1)N
+3485 3501 MXY
+-20 -13 Dl
+7 13 Dl
+-7 13 Dl
+20 -13 Dl
+-155 0 Dl
+3485 3027 MXY
+-20 -13 Dl
+7 13 Dl
+-7 13 Dl
+20 -13 Dl
+-163 0 Dl
+2967 3687 MXY
+-5 -24 Dl
+-4 14 Dl
+-15 4 Dl
+24 6 Dl
+-141 -141 Dl
+3 Dt
+-1 Ds
+8 s
+2706 4033(Figure)N
+2903(2:)X
+1 f
+2972(A)X
+3034(radix)X
+3181(search)X
+3359(trie)X
+3460(and)X
+3568(a)X
+3612(directory)X
+3858(representing)X
+4189(the)X
+4283(trie.)X
+10 s
+10 f
+2706 4209 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+1 f
+2878 4411(In)N
+2968(this)X
+3106(algorithm,)X
+3460(a)X
+3519(directory)X
+3832(consists)X
+4108(of)X
+4198(a)X
+4256(search)X
+2706 4499(trie)N
+2847(of)X
+2947(depth)X
+2 f
+3158(n)X
+1 f
+3211(,)X
+3264(containing)X
+3635(2)X
+2 f
+7 s
+4467(n)Y
+10 s
+1 f
+3749 4499(bucket)N
+3996(addresses)X
+4337(\(i.e.)X
+2706 4587(each)N
+2897(element)X
+3194(of)X
+3304(the)X
+3445(trie)X
+3594(is)X
+3689(a)X
+3767(bucket)X
+4023(address\).)X
+4373(To)X
+2706 4675(access)N
+2935(the)X
+3056(hash)X
+3226(table,)X
+3425(a)X
+3483(32-bit)X
+3696(hash)X
+3865(value)X
+4061(is)X
+4136(calculated)X
+2706 4763(and)N
+2 f
+2861(n)X
+1 f
+2953(bits)X
+3107(of)X
+3213(the)X
+3350(value)X
+3563(are)X
+3701(used)X
+3886(to)X
+3986(index)X
+4202(into)X
+4364(the)X
+2706 4851(directory)N
+3018(to)X
+3102(obtain)X
+3324(a)X
+3382(bucket)X
+3618(address.)X
+3921(It)X
+3992(is)X
+4067(important)X
+4400(to)X
+2706 4939(note)N
+2866(that)X
+3008(multiple)X
+3296(entries)X
+3532(of)X
+3620(this)X
+3756(directory)X
+4067(may)X
+4226(contain)X
+2706 5027(the)N
+2833(same)X
+3026(bucket)X
+3268(address)X
+3537(as)X
+3632(a)X
+3696(result)X
+3902(of)X
+3997(directory)X
+4315(dou-)X
+2706 5115(bling)N
+2903(during)X
+3145(bucket)X
+3392(splitting.)X
+3706(Figure)X
+3948(2)X
+4021(illustrates)X
+4364(the)X
+2706 5203(relationship)N
+3126(between)X
+3436(a)X
+3513(typical)X
+3772(\(skewed\))X
+4108(search)X
+4355(trie)X
+2706 5291(and)N
+2850(its)X
+2953(directory)X
+3271(representation.)X
+3774(The)X
+3927(formation)X
+4270(of)X
+4364(the)X
+2706 5379(directory)N
+3016(shown)X
+3245(in)X
+3327(the)X
+3445(\256gure)X
+3652(is)X
+3725(as)X
+3812(follows.)X
+16 s
+2706 5593 MXY
+864 0 Dl
+2 f
+8 s
+2746 5648(4)N
+1 f
+9 s
+2796 5673(It)N
+2858(does)X
+3008(not)X
+3118(contain)X
+3348(holes.)X
+3 f
+10 s
+720 5960(USENIX)N
+9 f
+1042(-)X
+3 f
+1106(Winter)X
+1371('91)X
+9 f
+1498(-)X
+3 f
+1562(Dallas,)X
+1815(TX)X
+4424(3)X
+
+4 p
+%%Page: 4 4
+0(Courier)xf 0 f
+10 s 10 xH 0 xS 0 f
+3 f
+432 258(A)N
+510(New)X
+682(Hashing)X
+985(Package)X
+1290(for)X
+1413(UNIX)X
+3663(Seltzer)X
+3920(&)X
+4007(Yigit)X
+1 f
+604 538(Initially,)N
+937(there)X
+1158(is)X
+1271(one)X
+1446(slot)X
+1620(in)X
+1741(the)X
+1898(directory)X
+432 626(addressing)N
+802(a)X
+865(single)X
+1083(bucket.)X
+1364(The)X
+1515(depth)X
+1719(of)X
+1812(the)X
+1936(trie)X
+2069(is)X
+2148(0)X
+432 714(and)N
+577(0)X
+646(bits)X
+790(of)X
+886(each)X
+1063(hash)X
+1239(value)X
+1442(are)X
+1570(examined)X
+1910(to)X
+2000(deter-)X
+432 802(mine)N
+624(in)X
+718(which)X
+946(bucket)X
+1192(to)X
+1286(place)X
+1488(a)X
+1556(key;)X
+1726(all)X
+1837(keys)X
+2015(go)X
+2126(in)X
+432 890(bucket)N
+682(0.)X
+797(When)X
+1024(this)X
+1174(bucket)X
+1423(is)X
+1511(full,)X
+1677(its)X
+1787(contents)X
+2089(are)X
+432 978(divided)N
+698(between)X
+992(L0)X
+1107(and)X
+1249(L1)X
+1363(as)X
+1455(was)X
+1605(done)X
+1786(in)X
+1873(the)X
+1996(previ-)X
+432 1066(ously)N
+664(discussed)X
+1030(algorithms.)X
+1471(After)X
+1700(this)X
+1874(split,)X
+2090(the)X
+432 1154(address)N
+710(of)X
+814(the)X
+948(second)X
+1207(bucket)X
+1457(must)X
+1648(be)X
+1760(stored)X
+1992(in)X
+2090(the)X
+432 1242(directory.)N
+796(To)X
+939(accommodate)X
+1438(the)X
+1589(new)X
+1776(address,)X
+2090(the)X
+432 1330(directory)N
+752(is)X
+835(split)X
+2 f
+8 s
+972 1305(5)N
+1 f
+10 s
+1330(,)Y
+1054(by)X
+1163(doubling)X
+1476(it,)X
+1569(thus)X
+1731(increasing)X
+2090(the)X
+432 1418(depth)N
+630(of)X
+717(the)X
+835(directory)X
+1145(by)X
+1245(one.)X
+604 1532(After)N
+813(this)X
+967(split,)X
+1163(a)X
+1237(single)X
+1466(bit)X
+1588(of)X
+1693(the)X
+1829(hash)X
+2014(value)X
+432 1620(needs)N
+663(to)X
+773(be)X
+896(examined)X
+1255(to)X
+1364(decide)X
+1621(whether)X
+1927(the)X
+2072(key)X
+432 1708(belongs)N
+711(to)X
+803(L0)X
+922(or)X
+1019(L1.)X
+1158(Once)X
+1358(one)X
+1504(of)X
+1601(these)X
+1795(buckets)X
+2069(\256lls)X
+432 1796(\(L0)N
+578(for)X
+702(example\),)X
+1051(it)X
+1125(is)X
+1208(split)X
+1375(as)X
+1472(before,)X
+1728(and)X
+1873(the)X
+2000(direc-)X
+432 1884(tory)N
+585(is)X
+662(split)X
+823(again)X
+1021(to)X
+1107(make)X
+1305(room)X
+1498(for)X
+1615(the)X
+1736(address)X
+2000(of)X
+2090(the)X
+432 1972(third)N
+618(bucket.)X
+927(This)X
+1104(splitting)X
+1400(causes)X
+1645(the)X
+1778(addresses)X
+2121(of)X
+432 2060(the)N
+567(non-splitting)X
+1012(bucket)X
+1263(\(L1\))X
+1443(to)X
+1541(be)X
+1653(duplicated.)X
+2063(The)X
+432 2148(directory)N
+766(now)X
+948(has)X
+1099(four)X
+1277(entries,)X
+1555(a)X
+1635(depth)X
+1857(of)X
+1968(2,)X
+2072(and)X
+432 2236(indexes)N
+700(the)X
+821(buckets)X
+1089(L00,)X
+1261(L01)X
+1413(and)X
+1552(L1,)X
+1684(as)X
+1774(shown)X
+2006(in)X
+2090(the)X
+432 2324(Figure)N
+661(2.)X
+604 2438(The)N
+756(crucial)X
+1002(part)X
+1154(of)X
+1247(the)X
+1371(algorithm)X
+1708(is)X
+1787(the)X
+1911(observa-)X
+432 2526(tion)N
+580(that)X
+724(L1)X
+837(is)X
+914(addressed)X
+1255(twice)X
+1453(in)X
+1539(the)X
+1661(directory.)X
+1995(If)X
+2073(this)X
+432 2614(bucket)N
+679(were)X
+869(to)X
+964(split)X
+1134(now,)X
+1324(the)X
+1454(directory)X
+1776(already)X
+2045(con-)X
+432 2702(tains)N
+611(room)X
+808(to)X
+898(hold)X
+1067(the)X
+1192(address)X
+1460(of)X
+1554(the)X
+1679(new)X
+1840(bucket.)X
+2121(In)X
+432 2790(general,)N
+711(the)X
+831(relationship)X
+1231(between)X
+1521(the)X
+1641(directory)X
+1953(and)X
+2090(the)X
+432 2878(number)N
+704(of)X
+798(bucket)X
+1039(addresses)X
+1374(contained)X
+1713(therein)X
+1962(is)X
+2041(used)X
+432 2966(to)N
+517(decide)X
+750(when)X
+947(to)X
+1031(split)X
+1190(the)X
+1310(directory.)X
+1662(Each)X
+1845(bucket)X
+2081(has)X
+432 3054(a)N
+505(depth,)X
+740(\()X
+2 f
+767(n)X
+7 s
+3070(b)Y
+10 s
+1 f
+848 3054(\),)N
+932(associated)X
+1299(with)X
+1478(it)X
+1558(and)X
+1710(appears)X
+1992(in)X
+2090(the)X
+432 3142(directory)N
+744(exactly)X
+998(2)X
+2 f
+7 s
+3106(n)Y
+9 f
+1075(-)X
+2 f
+1106(n)X
+4 s
+3110(b)Y
+7 s
+1 f
+10 s
+1181 3142(times.)N
+1396(When)X
+1610(a)X
+1668(bucket)X
+1904(splits,)X
+2113(its)X
+432 3230(depth)N
+638(increases)X
+961(by)X
+1069(one.)X
+1253(The)X
+1406(directory)X
+1724(must)X
+1907(split)X
+2072(any)X
+432 3318(time)N
+602(a)X
+665(bucket's)X
+964(depth)X
+1169(exceeds)X
+1451(the)X
+1576(depth)X
+1781(of)X
+1875(the)X
+2000(direc-)X
+432 3406(tory.)N
+630(The)X
+784(following)X
+1123(code)X
+1303(fragment)X
+1621(helps)X
+1818(to)X
+1908(illustrate)X
+432 3494(the)N
+554(extendible)X
+912(hashing)X
+1185(algorithm)X
+1520([FAG79])X
+1838(for)X
+1955(access-)X
+432 3582(ing)N
+554(individual)X
+898(buckets)X
+1163(and)X
+1299(maintaining)X
+1701(the)X
+1819(directory.)X
+0 f
+8 s
+432 3881(hash)N
+622(=)X
+698 -0.4038(calchash\(key\);)AX
+432 3969(mask)N
+622(=)X
+698 -0.4018(maskvec[depth];)AX
+432 4145(bucket)N
+698(=)X
+774 -0.4038(directory[hash)AX
+1344(&)X
+1420(mask];)X
+432 4321(/*)N
+546(Key)X
+698 -0.4219(Insertion)AX
+1078(*/)X
+432 4409(if)N
+546 -0.4038(\(store\(bucket,)AX
+1116(key,)X
+1306(data\))X
+1534(==)X
+1648(FAIL\))X
+1876({)X
+720 4497(newbl)N
+948(=)X
+1024 -0.4167(getpage\(\);)AX
+720 4585 -0.4000(bucket->depth++;)AN
+720 4673 -0.4091(newbl->depth)AN
+1214(=)X
+1290 -0.4038(bucket->depth;)AX
+720 4761(if)N
+834 -0.4038(\(bucket->depth)AX
+1404(>)X
+1480(depth\))X
+1746({)X
+1008 4849(/*)N
+1122(double)X
+1388 -0.4219(directory)AX
+1768(*/)X
+1008 4937(depth++;)N
+1 f
+16 s
+432 5033 MXY
+864 0 Dl
+2 f
+8 s
+472 5088(5)N
+1 f
+9 s
+534 5113(This)N
+692(decision)X
+962(to)X
+1048(split)X
+1202(the)X
+1319(directory)X
+1608(is)X
+1685(based)X
+1878(on)X
+1979(a)X
+2040(com-)X
+432 5193(parison)N
+666(of)X
+748(the)X
+858(depth)X
+1040(of)X
+1121(the)X
+1230(page)X
+1387(being)X
+1568(split)X
+1713(and)X
+1838(the)X
+1947(depth)X
+2128(of)X
+432 5273(the)N
+543(trie.)X
+698(In)X
+781(Figure)X
+992(2,)X
+1069(the)X
+1180(depths)X
+1390(of)X
+1472(both)X
+1622(L00)X
+1760(and)X
+1886(L01)X
+2024(are)X
+2134(2,)X
+432 5353(whereas)N
+689(the)X
+798(depth)X
+979(of)X
+1060(L1)X
+1161(is)X
+1230(1.)X
+1323(Therefore,)X
+1646(if)X
+1710(L1)X
+1810(were)X
+1970(to)X
+2046(split,)X
+432 5433(the)N
+543(directory)X
+826(would)X
+1029(not)X
+1144(need)X
+1303(to)X
+1382(split.)X
+1565(In)X
+1648(reality,)X
+1872(a)X
+1926(bucket)X
+2140(is)X
+432 5513(allocated)N
+727(for)X
+846(the)X
+969(directory)X
+1264(at)X
+1351(the)X
+1474(time)X
+1637(of)X
+1732(\256le)X
+1858(creation)X
+2124(so)X
+432 5593(although)N
+707(the)X
+818(directory)X
+1100(splits)X
+1274(logically,)X
+1566(physical)X
+1828(splits)X
+2002(do)X
+2096(not)X
+432 5673(occur)N
+610(until)X
+760(the)X
+866(\256le)X
+976(becomes)X
+1246(quite)X
+1408(large.)X
+0 f
+8 s
+2994 538 -0.4219(directory)AN
+3374(=)X
+3450 -0.3971(double\(directory\);)AX
+2706 626(})N
+2706 714 -0.3958(splitbucket\(bucket,)AN
+3466(newbl\))X
+2706 802(...)N
+2418 890(})N
+2 f
+10 s
+3169 1255(hsearch)N
+1 f
+2590 1387(Since)N
+2 f
+2807(hsearch)X
+1 f
+3100(does)X
+3286(not)X
+3427(have)X
+3617(to)X
+3717(translate)X
+4027(hash)X
+2418 1475(values)N
+2659(into)X
+2819(disk)X
+2988(addresses,)X
+3352(it)X
+3432(can)X
+3579(use)X
+3721(much)X
+3934(simpler)X
+2418 1563(algorithms)N
+2808(than)X
+2994(those)X
+3211(de\256ned)X
+3495(above.)X
+3775(System)X
+4058(V's)X
+2 f
+2418 1651(hsearch)N
+1 f
+2708(constructs)X
+3069(a)X
+3141(\256xed-size)X
+3489(hash)X
+3671(table)X
+3862(\(speci\256ed)X
+2418 1739(by)N
+2519(the)X
+2637(user)X
+2791(at)X
+2869(table)X
+3045(creation\).)X
+3391(By)X
+3504(default,)X
+3767(a)X
+3823(multiplica-)X
+2418 1827(tive)N
+2570(hash)X
+2748(function)X
+3046(based)X
+3260(on)X
+3371(that)X
+3522(described)X
+3861(in)X
+3954(Knuth,)X
+2418 1915(Volume)N
+2710(3,)X
+2804(section)X
+3065(6.4)X
+3199([KNU68])X
+3541(is)X
+3628(used)X
+3809(to)X
+3905(obtain)X
+4138(a)X
+2418 2003(primary)N
+2694(bucket)X
+2930(address.)X
+3233(If)X
+3309(this)X
+3446(bucket)X
+3681(is)X
+3755(full,)X
+3907(a)X
+3964(secon-)X
+2418 2091(dary)N
+2593(multiplicative)X
+3069(hash)X
+3248(value)X
+3454(is)X
+3538(computed)X
+3885(to)X
+3978(de\256ne)X
+2418 2179(the)N
+2542(probe)X
+2751(interval.)X
+3062(The)X
+3213(probe)X
+3422(interval)X
+3693(is)X
+3772(added)X
+3989(to)X
+4076(the)X
+2418 2267(original)N
+2712(bucket)X
+2971(address)X
+3257(\(modulo)X
+3573(the)X
+3716(table)X
+3916(size\))X
+4112(to)X
+2418 2355(obtain)N
+2658(a)X
+2734(new)X
+2908(bucket)X
+3162(address.)X
+3483(This)X
+3665(process)X
+3946(repeats)X
+2418 2443(until)N
+2588(an)X
+2688(empty)X
+2911(bucket)X
+3148(is)X
+3224(found.)X
+3474(If)X
+3551(no)X
+3654(bucket)X
+3891(is)X
+3967(found,)X
+2418 2531(an)N
+2514(insertion)X
+2814(fails)X
+2972(with)X
+3134(a)X
+3190(``table)X
+3420(full'')X
+3605(condition.)X
+2590 2645(The)N
+2768(basic)X
+2986(algorithm)X
+3350(may)X
+3541(be)X
+3670(modi\256ed)X
+4006(by)X
+4138(a)X
+2418 2733(number)N
+2705(of)X
+2813(compile)X
+3112(time)X
+3295(options)X
+3571(available)X
+3902(to)X
+4005(those)X
+2418 2821(users)N
+2604(with)X
+2767(AT&T)X
+3006(source)X
+3237(code.)X
+3450(First,)X
+3637(the)X
+3756(package)X
+4040(pro-)X
+2418 2909(vides)N
+2638(two)X
+2809(options)X
+3094(for)X
+3238(hash)X
+3435(functions.)X
+3803(Users)X
+4036(may)X
+2418 2997(specify)N
+2690(their)X
+2877(own)X
+3055(hash)X
+3242(function)X
+3549(by)X
+3669(compiling)X
+4032(with)X
+2418 3085(``USCR'')N
+2757(de\256ned)X
+3016(and)X
+3155(declaring)X
+3477(and)X
+3616(de\256ning)X
+3901(the)X
+4022(vari-)X
+2418 3173(able)N
+2 f
+2578(hcompar)X
+1 f
+2863(,)X
+2909(a)X
+2971(function)X
+3263(taking)X
+3488(two)X
+3633(string)X
+3840(arguments)X
+2418 3261(and)N
+2560(returning)X
+2880(an)X
+2982(integer.)X
+3271(Users)X
+3480(may)X
+3643(also)X
+3797(request)X
+4054(that)X
+2418 3349(hash)N
+2587(values)X
+2814(be)X
+2912(computed)X
+3250(simply)X
+3489(by)X
+3590(taking)X
+3811(the)X
+3930(modulo)X
+2418 3437(of)N
+2521(key)X
+2673(\(using)X
+2909(division)X
+3201(rather)X
+3424(than)X
+3597(multiplication)X
+4080(for)X
+2418 3525(hash)N
+2589(value)X
+2787(calculation\).)X
+3230(If)X
+3308(this)X
+3447(technique)X
+3783(is)X
+3859(used,)X
+4049(col-)X
+2418 3613(lisions)N
+2651(are)X
+2775(resolved)X
+3072(by)X
+3176(scanning)X
+3485(sequentially)X
+3896(from)X
+4076(the)X
+2418 3701(selected)N
+2702(bucket)X
+2941(\(linear)X
+3176(probing\).)X
+3517(This)X
+3684(option)X
+3913(is)X
+3991(avail-)X
+2418 3789(able)N
+2572(by)X
+2672(de\256ning)X
+2954(the)X
+3072(variable)X
+3351(``DIV'')X
+3622(at)X
+3700(compile)X
+3978(time.)X
+2590 3903(A)N
+2720(second)X
+3015(option,)X
+3311(based)X
+3565(on)X
+3716(an)X
+3863(algorithm)X
+2418 3991(discovered)N
+2787(by)X
+2888(Richard)X
+3163(P.)X
+3248(Brent,)X
+3466(rearranges)X
+3822(the)X
+3940(table)X
+4116(at)X
+2418 4079(the)N
+2549(time)X
+2724(of)X
+2824(insertion)X
+3137(in)X
+3232(order)X
+3434(to)X
+3528(speed)X
+3743(up)X
+3855(retrievals.)X
+2418 4167(The)N
+2571(basic)X
+2764(idea)X
+2926(is)X
+3007(to)X
+3097(shorten)X
+3361(long)X
+3531(probe)X
+3741(sequences)X
+4094(by)X
+2418 4255(lengthening)N
+2833(short)X
+3030(probe)X
+3249(sequences.)X
+3651(Once)X
+3857(the)X
+3991(probe)X
+2418 4343(chain)N
+2613(has)X
+2741(exceeded)X
+3062(some)X
+3252(threshold)X
+3571(\(Brent)X
+3796(suggests)X
+4087(2\),)X
+2418 4431(we)N
+2541(attempt)X
+2809(to)X
+2899(shuf\257e)X
+3145(any)X
+3289(colliding)X
+3601(keys)X
+3776(\(keys)X
+3978(which)X
+2418 4519(appeared)N
+2734(in)X
+2821(the)X
+2944(probe)X
+3152(sequence)X
+3471(of)X
+3562(the)X
+3684(new)X
+3842(key\).)X
+4049(The)X
+2418 4607(details)N
+2652(of)X
+2744(this)X
+2884(key)X
+3025(shuf\257ing)X
+3333(can)X
+3469(be)X
+3569(found)X
+3780(in)X
+3866([KNU68])X
+2418 4695(and)N
+2576([BRE73].)X
+2946(This)X
+3129(algorithm)X
+3481(may)X
+3660(be)X
+3777(obtained)X
+4094(by)X
+2418 4783(de\256ning)N
+2700(the)X
+2818(variable)X
+3097(``BRENT'')X
+3487(at)X
+3565(compile)X
+3843(time.)X
+2590 4897(A)N
+2698(third)X
+2899(set)X
+3038(of)X
+3154(options,)X
+3458(obtained)X
+3783(by)X
+3912(de\256ning)X
+2418 4985(``CHAINED'',)N
+2943(use)X
+3086(linked)X
+3321(lists)X
+3484(to)X
+3581(resolve)X
+3848(collisions.)X
+2418 5073(Either)N
+2647(of)X
+2747(the)X
+2878(primary)X
+3164(hash)X
+3343(function)X
+3642(described)X
+3982(above)X
+2418 5161(may)N
+2584(be)X
+2688(used,)X
+2882(but)X
+3011(all)X
+3118(collisions)X
+3451(are)X
+3577(resolved)X
+3876(by)X
+3983(build-)X
+2418 5249(ing)N
+2554(a)X
+2623(linked)X
+2856(list)X
+2986(of)X
+3086(entries)X
+3333(from)X
+3522(the)X
+3653(primary)X
+3940(bucket.)X
+2418 5337(By)N
+2542(default,)X
+2816(new)X
+2981(entries)X
+3226(will)X
+3381(be)X
+3488(added)X
+3711(to)X
+3804(a)X
+3871(bucket)X
+4116(at)X
+2418 5425(the)N
+2541(beginning)X
+2886(of)X
+2978(the)X
+3101(bucket)X
+3339(chain.)X
+3577(However,)X
+3916(compile)X
+2418 5513(options)N
+2706(``SORTUP'')X
+3173(or)X
+3293(``SORTDOWN'')X
+3908(may)X
+4098(be)X
+2418 5601(speci\256ed)N
+2723(to)X
+2805(order)X
+2995(the)X
+3113(hash)X
+3280(chains)X
+3505(within)X
+3729(each)X
+3897(bucket.)X
+3 f
+432 5960(4)N
+2970(USENIX)X
+9 f
+3292(-)X
+3 f
+3356(Winter)X
+3621('91)X
+9 f
+3748(-)X
+3 f
+3812(Dallas,)X
+4065(TX)X
+
+5 p
+%%Page: 5 5
+0(Courier)xf 0 f
+10 s 10 xH 0 xS 0 f
+3 f
+720 258(Seltzer)N
+977(&)X
+1064(Yigit)X
+3278(A)X
+3356(New)X
+3528(Hashing)X
+3831(Package)X
+4136(for)X
+4259(UNIX)X
+2 f
+1444 538(dynahash)N
+1 f
+892 670(The)N
+2 f
+1054(dynahash)X
+1 f
+1398(library,)X
+1669(written)X
+1932(by)X
+2048(Esmond)X
+2346(Pitt,)X
+720 758(implements)N
+1183(Larson's)X
+1554(linear)X
+1827(hashing)X
+2165(algorithm)X
+720 846([LAR88])N
+1097(with)X
+1302(an)X
+2 f
+1440(hsearch)X
+1 f
+1756(compatible)X
+2174(interface.)X
+720 934(Intuitively,)N
+1099(a)X
+1161(hash)X
+1334(table)X
+1516(begins)X
+1751(as)X
+1844(a)X
+1905(single)X
+2121(bucket)X
+2360(and)X
+720 1022(grows)N
+941(in)X
+1028(generations,)X
+1443(where)X
+1665(a)X
+1725(generation)X
+2088(corresponds)X
+720 1110(to)N
+815(a)X
+884(doubling)X
+1201(in)X
+1296(the)X
+1427(size)X
+1585(of)X
+1685(the)X
+1815(hash)X
+1994(table.)X
+2222(The)X
+2379(0)X
+2 f
+7 s
+1078(th)Y
+10 s
+1 f
+720 1198(generation)N
+1085(occurs)X
+1321(as)X
+1414(the)X
+1538(table)X
+1719(grows)X
+1940(from)X
+2121(one)X
+2262(bucket)X
+720 1286(to)N
+814(two.)X
+1006(In)X
+1105(the)X
+1235(next)X
+1405(generation)X
+1776(the)X
+1906(table)X
+2093(grows)X
+2320(from)X
+720 1374(two)N
+862(to)X
+946(four.)X
+1122(During)X
+1371(each)X
+1541(generation,)X
+1921(every)X
+2121(bucket)X
+2356(that)X
+720 1462(existed)N
+967(at)X
+1045(the)X
+1163(beginning)X
+1503(of)X
+1590(the)X
+1708(generation)X
+2067(is)X
+2140(split.)X
+892 1576(The)N
+1041(table)X
+1221(starts)X
+1414(as)X
+1505(a)X
+1565(single)X
+1780(bucket)X
+2018(\(numbered)X
+2389(0\),)X
+720 1664(the)N
+839(current)X
+1088(split)X
+1245(bucket)X
+1479(is)X
+1552(set)X
+1661(to)X
+1743(bucket)X
+1977(0,)X
+2057(and)X
+2193(the)X
+2311(max-)X
+720 1752(imum)N
+933(split)X
+1097(point)X
+1288(is)X
+1368(set)X
+1483(to)X
+1571(twice)X
+1771(the)X
+1895(current)X
+2149(split)X
+2312(point)X
+720 1840(\(0\).)N
+863(When)X
+1084(it)X
+1157(is)X
+1239(time)X
+1410(for)X
+1532(a)X
+1596(bucket)X
+1838(to)X
+1928(split,)X
+2113(the)X
+2239(keys)X
+2414(in)X
+720 1928(the)N
+872(current)X
+1154(split)X
+1345(bucket)X
+1612(are)X
+1764(divided)X
+2057(between)X
+2378(the)X
+720 2016(current)N
+981(split)X
+1151(bucket)X
+1397(and)X
+1545(a)X
+1613(new)X
+1779(bucket)X
+2025(whose)X
+2262(bucket)X
+720 2104(number)N
+1000(is)X
+1088(equal)X
+1297(to)X
+1394(1)X
+1469(+)X
+1549(current)X
+1812(split)X
+1984(bucket)X
+2232(+)X
+2311(max-)X
+720 2192(imum)N
+927(split)X
+1085(point.)X
+1310(We)X
+1442(can)X
+1574(determine)X
+1915(which)X
+2131(keys)X
+2298(move)X
+720 2280(to)N
+807(the)X
+929(new)X
+1087(bucket)X
+1325(by)X
+1429(examining)X
+1791(the)X
+2 f
+1913(n)X
+7 s
+1962 2248(th)N
+10 s
+1 f
+2043 2280(bit)N
+2151(of)X
+2242(a)X
+2302(key's)X
+720 2368(hash)N
+899(value)X
+1105(where)X
+1334(n)X
+1406(is)X
+1491(the)X
+1620(generation)X
+1990(number.)X
+2306(After)X
+720 2456(the)N
+846(bucket)X
+1088(at)X
+1174(the)X
+1300(maximum)X
+1651(split)X
+1815(point)X
+2006(has)X
+2140(been)X
+2319(split,)X
+720 2544(the)N
+839(generation)X
+1198(number)X
+1463(is)X
+1536(incremented,)X
+1973(the)X
+2091(current)X
+2339(split)X
+720 2632(point)N
+908(is)X
+985(set)X
+1098(back)X
+1274(to)X
+1360(zero,)X
+1543(and)X
+1683(the)X
+1805(maximum)X
+2152(split)X
+2312(point)X
+720 2720(is)N
+815(set)X
+946(to)X
+1050(the)X
+1190(number)X
+1477(of)X
+1586(the)X
+1725(last)X
+1877(bucket)X
+2132(in)X
+2235(the)X
+2374(\256le)X
+720 2808(\(which)N
+971(is)X
+1052(equal)X
+1253(to)X
+1342(twice)X
+1543(the)X
+1668(old)X
+1797(maximum)X
+2148(split)X
+2312(point)X
+720 2896(plus)N
+873(1\).)X
+892 3010(To)N
+1031(facilitate)X
+1361(locating)X
+1668(keys,)X
+1884(we)X
+2027(maintain)X
+2356(two)X
+720 3098(masks.)N
+989(The)X
+1143(low)X
+1291(mask)X
+1488(is)X
+1569(equal)X
+1771(to)X
+1861(the)X
+1987(maximum)X
+2339(split)X
+720 3186(bucket)N
+967(and)X
+1116(the)X
+1247(high)X
+1422(mask)X
+1624(is)X
+1710(equal)X
+1917(to)X
+2011(the)X
+2141(next)X
+2311(max-)X
+720 3274(imum)N
+931(split)X
+1093(bucket.)X
+1372(To)X
+1486(locate)X
+1703(a)X
+1764(speci\256c)X
+2033(key,)X
+2193(we)X
+2311(com-)X
+720 3362(pute)N
+881(a)X
+940(32-bit)X
+1154(hash)X
+1324(value)X
+1520(using)X
+1715(a)X
+1773(bit-randomizing)X
+2311(algo-)X
+720 3450(rithm)N
+932(such)X
+1118(as)X
+1224(the)X
+1361(one)X
+1516(described)X
+1862(in)X
+1962([LAR88].)X
+2334(This)X
+720 3538(hash)N
+893(value)X
+1093(is)X
+1172(then)X
+1336(masked)X
+1607(with)X
+1775(the)X
+1898(high)X
+2065(mask.)X
+2299(If)X
+2378(the)X
+720 3626(resulting)N
+1026(number)X
+1297(is)X
+1376(greater)X
+1626(than)X
+1790(the)X
+1913(maximum)X
+2262(bucket)X
+720 3714(in)N
+823(the)X
+962(table)X
+1159(\(current)X
+1455(split)X
+1633(bucket)X
+1888(+)X
+1974(maximum)X
+2339(split)X
+720 3802(point\),)N
+962(the)X
+1091(hash)X
+1269(value)X
+1474(is)X
+1558(masked)X
+1834(with)X
+2007(the)X
+2136(low)X
+2287(mask.)X
+720 3890(In)N
+825(either)X
+1046(case,)X
+1242(the)X
+1377(result)X
+1592(of)X
+1696(the)X
+1831(mask)X
+2037(is)X
+2127(the)X
+2262(bucket)X
+720 3978(number)N
+989(for)X
+1107(the)X
+1229(given)X
+1431(key.)X
+1611(The)X
+1759(algorithm)X
+2093(below)X
+2312(illus-)X
+720 4066(trates)N
+914(this)X
+1049(process.)X
+0 f
+8 s
+720 4365(h)N
+796(=)X
+872 -0.4038(calchash\(key\);)AX
+720 4453(bucket)N
+986(=)X
+1062(h)X
+1138(&)X
+1214 -0.4167(high_mask;)AX
+720 4541(if)N
+834(\()X
+910(bucket)X
+1176(>)X
+1252 -0.4167(max_bucket)AX
+1670(\))X
+1008 4629(bucket)N
+1274(=)X
+1350(h)X
+1426(&)X
+1502 -0.4219(low_mask;)AX
+720 4717 -0.4018(return\(bucket\);)AN
+1 f
+10 s
+892 5042(In)N
+1013(order)X
+1237(to)X
+1353(decide)X
+1617(when)X
+1845(to)X
+1961(split)X
+2152(a)X
+2242(bucket,)X
+2 f
+720 5130(dynahash)N
+1 f
+1050(uses)X
+2 f
+1210(controlled)X
+1561(splitting)X
+1 f
+1822(.)X
+1884(A)X
+1964(hash)X
+2133(table)X
+2311(has)X
+2440(a)X
+720 5218(\256ll)N
+837(factor)X
+1054(which)X
+1279(is)X
+1361(expressed)X
+1707(in)X
+1798(terms)X
+2004(of)X
+2099(the)X
+2225(average)X
+720 5306(number)N
+990(of)X
+1082(keys)X
+1253(in)X
+1339(each)X
+1511(bucket.)X
+1789(Each)X
+1974(time)X
+2140(the)X
+2262(table's)X
+720 5394(total)N
+885(number)X
+1153(of)X
+1243(keys)X
+1413(divided)X
+1676(by)X
+1778(its)X
+1875(number)X
+2142(of)X
+2231(buckets)X
+720 5482(exceeds)N
+995(this)X
+1130(\256ll)X
+1238(factor,)X
+1466(a)X
+1522(bucket)X
+1756(is)X
+1829(split.)X
+2878 538(Since)N
+3079(the)X
+2 f
+3200(hsearch)X
+1 f
+3477(create)X
+3693(interface)X
+3998(\()X
+2 f
+4025(hcreate)X
+1 f
+4266(\))X
+4315(calls)X
+2706 626(for)N
+2842(an)X
+2960(estimate)X
+3269(of)X
+3378(the)X
+3518(\256nal)X
+3702(size)X
+3869(of)X
+3978(the)X
+4118(hash)X
+4306(table)X
+2706 714(\()N
+2 f
+2733(nelem)X
+1 f
+2925(\),)X
+2 f
+3007(dynahash)X
+1 f
+3349(uses)X
+3522(this)X
+3672(information)X
+4085(to)X
+4182(initialize)X
+2706 802(the)N
+2848(table.)X
+3088(The)X
+3257(initial)X
+3486(number)X
+3774(of)X
+3884(buckets)X
+4172(is)X
+4268(set)X
+4400(to)X
+2 f
+2706 890(nelem)N
+1 f
+2926(rounded)X
+3217(to)X
+3306(the)X
+3431(next)X
+3596(higher)X
+3828(power)X
+4056(of)X
+4150(two.)X
+4337(The)X
+2706 978(current)N
+2958(split)X
+3118(point)X
+3305(is)X
+3381(set)X
+3493(to)X
+3578(0)X
+3641(and)X
+3780(the)X
+3901(maximum)X
+4248(bucket)X
+2706 1066(and)N
+2842(maximum)X
+3186(split)X
+3343(point)X
+3527(are)X
+3646(set)X
+3755(to)X
+3837(this)X
+3972(rounded)X
+4255(value.)X
+3 f
+3148 1220(The)N
+3301(New)X
+3473(Implementation)X
+1 f
+2878 1352(Our)N
+3042(implementation)X
+3583(is)X
+3675(also)X
+3842(based)X
+4063(on)X
+4181(Larson's)X
+2706 1440(linear)N
+2939(hashing)X
+3238([LAR88])X
+3582(algorithm)X
+3943(as)X
+4060(well)X
+4248(as)X
+4364(the)X
+2 f
+2706 1528(dynahash)N
+1 f
+3047(implementation.)X
+3623(The)X
+2 f
+3782(dbm)X
+1 f
+3954(family)X
+4197(of)X
+4297(algo-)X
+2706 1616(rithms)N
+2942(decide)X
+3184(dynamically)X
+3612(which)X
+3840(bucket)X
+4085(to)X
+4178(split)X
+4346(and)X
+2706 1704(when)N
+2914(to)X
+3010(split)X
+3180(it)X
+3257(\(when)X
+3491(it)X
+3568(over\257ows\))X
+3944(while)X
+2 f
+4155(dynahash)X
+1 f
+2706 1792(splits)N
+2933(in)X
+3054(a)X
+3149(prede\256ned)X
+3547(order)X
+3776(\(linearly\))X
+4134(and)X
+4309(at)X
+4426(a)X
+2706 1880(prede\256ned)N
+3116(time)X
+3328(\(when)X
+3599(the)X
+3767(table)X
+3993(\256ll)X
+4151(factor)X
+4409(is)X
+2706 1968(exceeded\).)N
+3121(We)X
+3280(use)X
+3434(a)X
+3517(hybrid)X
+3773(of)X
+3887(these)X
+4099(techniques.)X
+2706 2056(Splits)N
+2913(occur)X
+3118(in)X
+3206(the)X
+3330(prede\256ned)X
+3695(order)X
+3891(of)X
+3984(linear)X
+4193(hashing,)X
+2706 2144(but)N
+2845(the)X
+2980(time)X
+3159(at)X
+3253(which)X
+3485(pages)X
+3704(are)X
+3839(split)X
+4012(is)X
+4101(determined)X
+2706 2232(both)N
+2869(by)X
+2970(page)X
+3143(over\257ows)X
+3480(\()X
+2 f
+3507(uncontrolled)X
+3937(splitting)X
+1 f
+4198(\))X
+4246(and)X
+4382(by)X
+2706 2320(exceeding)N
+3052(the)X
+3170(\256ll)X
+3278(factor)X
+3486(\()X
+2 f
+3513(controlled)X
+3862(splitting)X
+1 f
+4123(\))X
+2878 2434(A)N
+2962(hash)X
+3135(table)X
+3317(is)X
+3395(parameterized)X
+3876(by)X
+3981(both)X
+4148(its)X
+4248(bucket)X
+2706 2522(size)N
+2904(\()X
+2 f
+2931(bsize)X
+1 f
+(\))S
+3191(and)X
+3380(\256ll)X
+3541(factor)X
+3801(\()X
+2 f
+3828(ffactor)X
+1 f
+4041(\).)X
+4180(Whereas)X
+2 f
+2706 2610(dynahash's)N
+1 f
+3095(buckets)X
+3364(can)X
+3500(be)X
+3599(represented)X
+3993(as)X
+4083(a)X
+4142(linked)X
+4365(list)X
+2706 2698(of)N
+2798(elements)X
+3108(in)X
+3195(memory,)X
+3507(our)X
+3639(package)X
+3928(needs)X
+4136(to)X
+4222(support)X
+2706 2786(disk)N
+2874(access,)X
+3135(and)X
+3286(must)X
+3476(represent)X
+3806(buckets)X
+4086(in)X
+4183(terms)X
+4395(of)X
+2706 2874(pages.)N
+2955(The)X
+2 f
+3106(bsize)X
+1 f
+3291(is)X
+3369(the)X
+3492(size)X
+3642(\(in)X
+3756(bytes\))X
+3977(of)X
+4069(these)X
+4259(pages.)X
+2706 2962(As)N
+2833(in)X
+2933(linear)X
+3154(hashing,)X
+3461(the)X
+3597(number)X
+3879(of)X
+3983(buckets)X
+4265(in)X
+4364(the)X
+2706 3050(table)N
+2906(is)X
+3003(equal)X
+3221(to)X
+3327(the)X
+3469(number)X
+3758(of)X
+3869(keys)X
+4060(in)X
+4165(the)X
+4306(table)X
+2706 3138(divided)N
+2988(by)X
+2 f
+3110(ffactor)X
+1 f
+3323(.)X
+2 f
+8 s
+3113(6)Y
+1 f
+10 s
+3417 3138(The)N
+3584(controlled)X
+3950(splitting)X
+4252(occurs)X
+2706 3226(each)N
+2878(time)X
+3044(the)X
+3166(number)X
+3435(of)X
+3526(keys)X
+3697(in)X
+3783(the)X
+3905(table)X
+4085(exceeds)X
+4364(the)X
+2706 3314(\256ll)N
+2814(factor)X
+3022(multiplied)X
+3370(by)X
+3470(the)X
+3588(number)X
+3853(of)X
+3940(buckets.)X
+2878 3428(Inserting)N
+3187(keys)X
+3358(and)X
+3498(splitting)X
+3783(buckets)X
+4051(is)X
+4127(performed)X
+2706 3516(precisely)N
+3018(as)X
+3107(described)X
+3437(previously)X
+3796(for)X
+2 f
+3911(dynahash)X
+1 f
+4218(.)X
+4279(How-)X
+2706 3604(ever,)N
+2897(since)X
+3094(buckets)X
+3371(are)X
+3502(now)X
+3671(comprised)X
+4036(of)X
+4134(pages,)X
+4368(we)X
+2706 3692(must)N
+2883(be)X
+2981(prepared)X
+3284(to)X
+3367(handle)X
+3602(cases)X
+3793(where)X
+4011(the)X
+4130(size)X
+4276(of)X
+4364(the)X
+2706 3780(keys)N
+2873(and)X
+3009(data)X
+3163(in)X
+3245(a)X
+3301(bucket)X
+3535(exceed)X
+3779(the)X
+3897(bucket)X
+4131(size.)X
+3 f
+3318 3934(Over\257ow)N
+3654(Pages)X
+1 f
+2878 4066(There)N
+3095(are)X
+3223(two)X
+3372(cases)X
+3571(where)X
+3797(a)X
+3862(key)X
+4007(may)X
+4174(not)X
+4305(\256t)X
+4400(in)X
+2706 4154(its)N
+2802(designated)X
+3166(bucket.)X
+3441(In)X
+3529(the)X
+3647(\256rst)X
+3791(case,)X
+3970(the)X
+4088(total)X
+4250(size)X
+4395(of)X
+2706 4242(the)N
+2833(key)X
+2978(and)X
+3123(data)X
+3286(may)X
+3453(exceed)X
+3706(the)X
+3833(bucket)X
+4076(size.)X
+4269(In)X
+4364(the)X
+2706 4330(second,)N
+3008(addition)X
+3328(of)X
+3453(a)X
+3547(new)X
+3739(key)X
+3913(could)X
+4149(cause)X
+4386(an)X
+2706 4418(over\257ow,)N
+3068(but)X
+3227(the)X
+3382(bucket)X
+3652(in)X
+3770(question)X
+4097(is)X
+4206(not)X
+4364(yet)X
+2706 4506(scheduled)N
+3049(to)X
+3133(be)X
+3230(split.)X
+3428(In)X
+3516(existing)X
+3790(implementations,)X
+4364(the)X
+2706 4594(second)N
+2953(case)X
+3115(never)X
+3317(arises)X
+3523(\(since)X
+3738(buckets)X
+4006(are)X
+4128(split)X
+4288(when)X
+2706 4682(they)N
+2871(over\257ow\))X
+3210(and)X
+3352(the)X
+3476(\256rst)X
+3626(case)X
+3791(is)X
+3870(not)X
+3998(handled)X
+4278(at)X
+4362(all.)X
+2706 4770(Although)N
+3036(large)X
+3225(key/data)X
+3525(pair)X
+3678(handling)X
+3986(is)X
+4066(dif\256cult)X
+4346(and)X
+2706 4858(expensive,)N
+3083(it)X
+3163(is)X
+3252(essential.)X
+3604(In)X
+3706(a)X
+3777(linear)X
+3995(hashed)X
+4253(imple-)X
+2706 4946(mentation,)N
+3087(over\257ow)X
+3413(pages)X
+3636(are)X
+3775(required)X
+4083(for)X
+4217(buckets)X
+2706 5034(which)N
+2935(over\257ow)X
+3253(before)X
+3492(they)X
+3662(are)X
+3793(split,)X
+3982(so)X
+4085(we)X
+4211(can)X
+4355(use)X
+2706 5122(the)N
+2833(same)X
+3027(mechanism)X
+3421(for)X
+3544(large)X
+3734(key/data)X
+4035(pairs)X
+4220(that)X
+4368(we)X
+2706 5210(use)N
+2837(for)X
+2955(over\257ow)X
+3264(pages.)X
+3511(Logically,)X
+3862(we)X
+3980(chain)X
+4177(over\257ow)X
+16 s
+2706 5353 MXY
+864 0 Dl
+2 f
+8 s
+2746 5408(6)N
+1 f
+9 s
+2801 5433(This)N
+2952(is)X
+3023(not)X
+3138(strictly)X
+3361(true.)X
+3532(The)X
+3667(\256le)X
+3782(does)X
+3937(not)X
+4052(contract)X
+4306(when)X
+2706 5513(keys)N
+2861(are)X
+2972(deleted,)X
+3221(so)X
+3308(the)X
+3419(number)X
+3662(of)X
+3744(buckets)X
+3986(is)X
+4056(actually)X
+4306(equal)X
+2706 5593(to)N
+2782(the)X
+2890(maximum)X
+3202(number)X
+3441(of)X
+3520(keys)X
+3671(ever)X
+3814(present)X
+4041(in)X
+4116(the)X
+4223(table)X
+4382(di-)X
+2706 5673(vided)N
+2884(by)X
+2974(the)X
+3080(\256ll)X
+3178(factor.)X
+3 f
+10 s
+720 5960(USENIX)N
+9 f
+1042(-)X
+3 f
+1106(Winter)X
+1371('91)X
+9 f
+1498(-)X
+3 f
+1562(Dallas,)X
+1815(TX)X
+4424(5)X
+
+6 p
+%%Page: 6 6
+0(Courier)xf 0 f
+10 s 10 xH 0 xS 0 f
+3 f
+432 258(A)N
+510(New)X
+682(Hashing)X
+985(Package)X
+1290(for)X
+1413(UNIX)X
+3663(Seltzer)X
+3920(&)X
+4007(Yigit)X
+1 f
+432 538(pages)N
+639(to)X
+725(the)X
+847(buckets)X
+1116(\(also)X
+1296(called)X
+1512(primary)X
+1789(pages\).)X
+2062(In)X
+2152(a)X
+432 626(memory)N
+730(based)X
+943(representation,)X
+1448(over\257ow)X
+1763(pages)X
+1976(do)X
+2086(not)X
+432 714(pose)N
+628(any)X
+792(special)X
+1063(problems)X
+1409(because)X
+1712(we)X
+1854(can)X
+2014(chain)X
+432 802(over\257ow)N
+776(pages)X
+1017(to)X
+1137(primary)X
+1449(pages)X
+1690(using)X
+1921(memory)X
+432 890(pointers.)N
+776(However,)X
+1137(mapping)X
+1463(these)X
+1674(over\257ow)X
+2005(pages)X
+432 978(into)N
+584(a)X
+648(disk)X
+809(\256le)X
+939(is)X
+1019(more)X
+1211(of)X
+1305(a)X
+1368(challenge,)X
+1723(since)X
+1915(we)X
+2036(need)X
+432 1066(to)N
+547(be)X
+675(able)X
+861(to)X
+975(address)X
+1268(both)X
+1462(bucket)X
+1728(pages,)X
+1983(whose)X
+432 1154(numbers)N
+729(are)X
+849(growing)X
+1137(linearly,)X
+1422(and)X
+1558(some)X
+1747(indeterminate)X
+432 1242(number)N
+715(of)X
+820(over\257ow)X
+1143(pages)X
+1364(without)X
+1646(reorganizing)X
+2090(the)X
+432 1330(\256le.)N
+604 1444(One)N
+789(simple)X
+1053(solution)X
+1361(would)X
+1612(be)X
+1739(to)X
+1852(allocate)X
+2152(a)X
+432 1532(separate)N
+737(\256le)X
+880(for)X
+1015(over\257ow)X
+1341(pages.)X
+1604(The)X
+1769(disadvantage)X
+432 1620(with)N
+605(such)X
+783(a)X
+850(technique)X
+1193(is)X
+1276(that)X
+1426(it)X
+1500(requires)X
+1789(an)X
+1895(extra)X
+2086(\256le)X
+432 1708(descriptor,)N
+794(an)X
+891(extra)X
+1073(system)X
+1316(call)X
+1453(on)X
+1554(open)X
+1731(and)X
+1867(close,)X
+2072(and)X
+432 1796(logically)N
+739(associating)X
+1122(two)X
+1269(independent)X
+1687(\256les.)X
+1886(For)X
+2023(these)X
+432 1884(reasons,)N
+728(we)X
+857(wanted)X
+1123(to)X
+1219(map)X
+1391(both)X
+1567(primary)X
+1855(pages)X
+2072(and)X
+432 1972(over\257ow)N
+737(pages)X
+940(into)X
+1084(the)X
+1202(same)X
+1387(\256le)X
+1509(space.)X
+604 2086(The)N
+799(buddy-in-waiting)X
+1425(algorithm)X
+1806(provides)X
+2152(a)X
+432 2174(mechanism)N
+851(to)X
+966(support)X
+1259(multiple)X
+1578(pages)X
+1814(per)X
+1970(logical)X
+432 2262(bucket)N
+685(while)X
+902(retaining)X
+1226(the)X
+1362(simple)X
+1613(split)X
+1788(sequence)X
+2121(of)X
+432 2350(linear)N
+681(hashing.)X
+1015(Over\257ow)X
+1383(pages)X
+1631(are)X
+1795(preallocated)X
+432 2438(between)N
+781(generations)X
+1232(of)X
+1379(primary)X
+1713(pages.)X
+1996(These)X
+432 2526(over\257ow)N
+759(pages)X
+984(are)X
+1125(used)X
+1314(by)X
+1436(any)X
+1594(bucket)X
+1850(containing)X
+432 2614(more)N
+646(keys)X
+842(than)X
+1029(\256t)X
+1144(on)X
+1273(the)X
+1420(primary)X
+1723(page)X
+1924(and)X
+2089(are)X
+432 2702(reclaimed,)N
+808(if)X
+896(possible,)X
+1217(when)X
+1430(the)X
+1567(bucket)X
+1819(later)X
+2000(splits.)X
+432 2790(Figure)N
+687(3)X
+773(depicts)X
+1045(the)X
+1188(layout)X
+1433(of)X
+1545(primary)X
+1844(pages)X
+2072(and)X
+432 2878(over\257ow)N
+752(pages)X
+970(within)X
+1209(the)X
+1342(same)X
+1542(\256le.)X
+1699(Over\257ow)X
+2036(page)X
+432 2966(use)N
+586(information)X
+1011(is)X
+1111(recorded)X
+1440(in)X
+1548(bitmaps)X
+1847(which)X
+2089(are)X
+432 3054(themselves)N
+819(stored)X
+1046(on)X
+1157(over\257ow)X
+1472(pages.)X
+1725(The)X
+1880(addresses)X
+432 3142(of)N
+520(the)X
+639(bitmap)X
+882(pages)X
+1086(and)X
+1223(the)X
+1342(number)X
+1608(of)X
+1695(pages)X
+1898(allocated)X
+432 3230(at)N
+515(each)X
+688(split)X
+850(point)X
+1039(are)X
+1163(stored)X
+1384(in)X
+1470(the)X
+1592(\256le)X
+1718(header.)X
+1997(Using)X
+432 3318(this)N
+577(information,)X
+1005(both)X
+1177(over\257ow)X
+1492(addresses)X
+1829(and)X
+1974(bucket)X
+432 3406(addresses)N
+764(can)X
+900(be)X
+999(mapped)X
+1276(to)X
+1361(disk)X
+1517(addresses)X
+1848(by)X
+1951(the)X
+2072(fol-)X
+432 3494(lowing)N
+674(calculation:)X
+0 f
+8 s
+432 3793(int)N
+736(bucket;)X
+1192(/*)X
+1306(bucket)X
+1572(address)X
+1876(*/)X
+432 3881(u_short)N
+736(oaddr;)X
+1192(/*)X
+1306(OVERFLOW)X
+1648(address)X
+1952(*/)X
+432 3969(int)N
+736 -0.4125(nhdr_pages;)AX
+1192(/*)X
+1306(npages)X
+1572(in)X
+1686 -112.4062(\256le)AX
+1838(header)X
+2104(*/)X
+432 4057(int)N
+736 -0.4125(spares[32];)AX
+1192(/*)X
+1306(npages)X
+1572(at)X
+1686(each)X
+1876(split)X
+2104(*/)X
+432 4145(int)N
+736(log2\(\);)X
+1198(/*)X
+1312(ceil\(log)X
+1654(base)X
+1844(2\))X
+1958(*/)X
+432 4321(#DEFINE)N
+736 -0.3929(BUCKET_TO_PAGE\(bucket\))AX
+1610(\\)X
+584 4409(bucket)N
+850(+)X
+926 -0.4167(nhdr_pages)AX
+1344(+)X
+1420(\\)X
+584 4497 -0.3894(\(bucket?spares[logs2\(bucket)AN
+1648(+)X
+1724(1\)-1]:0\))X
+432 4673(#DEFINE)N
+736 -0.3947(OADDR_TO_PAGE\(oaddr\))AX
+1534(\\)X
+584 4761 -0.3984(BUCKET_TO_PAGE\(\(1)AN
+1268(<<)X
+1382 -0.4091(\(oaddr>>11\)\))AX
+1876(-)X
+1952(1\))X
+2066(+)X
+2142(\\)X
+584 4849(oaddr)N
+812(&)X
+888(0x7ff;)X
+1 f
+10 s
+604 5262(An)N
+728(over\257ow)X
+1039(page)X
+1217(is)X
+1295(addressed)X
+1637(by)X
+1742(its)X
+1842(split)X
+2004(point,)X
+432 5350(identifying)N
+858(the)X
+1031(generations)X
+1476(between)X
+1819(which)X
+2090(the)X
+432 5438(over\257ow)N
+740(page)X
+915(is)X
+991(allocated,)X
+1324(and)X
+1463(its)X
+1561(page)X
+1736(number,)X
+2023(iden-)X
+432 5526(tifying)N
+665(the)X
+783(particular)X
+1111(page)X
+1283(within)X
+1507(the)X
+1625(split)X
+1782(point.)X
+1986(In)X
+2073(this)X
+432 5614(implementation,)N
+983(offsets)X
+1225(within)X
+1457(pages)X
+1668(are)X
+1795(16)X
+1903(bits)X
+2046(long)X
+432 5702(\(limiting)N
+732(the)X
+851(maximum)X
+1196(page)X
+1368(size)X
+1513(to)X
+1595(32K\),)X
+1800(so)X
+1891(we)X
+2005(select)X
+2418 538(an)N
+2535(over\257ow)X
+2860(page)X
+3052(addressing)X
+3435(algorithm)X
+3786(that)X
+3946(can)X
+4098(be)X
+2418 626(expressed)N
+2760(in)X
+2847(16)X
+2952(bits)X
+3091(and)X
+3231(which)X
+3451(allows)X
+3684(quick)X
+3886(retrieval.)X
+2418 714(The)N
+2568(top)X
+2695(\256ve)X
+2840(bits)X
+2980(indicate)X
+3258(the)X
+3380(split)X
+3541(point)X
+3729(and)X
+3869(the)X
+3991(lower)X
+2418 802(eleven)N
+2650(indicate)X
+2926(the)X
+3046(page)X
+3220(number)X
+3487(within)X
+3713(the)X
+3832(split)X
+3990(point.)X
+2418 890(Since)N
+2633(\256ve)X
+2789(bits)X
+2940(are)X
+3075(reserved)X
+3384(for)X
+3514(the)X
+3648(split)X
+3821(point,)X
+4041(\256les)X
+2418 978(may)N
+2578(split)X
+2737(32)X
+2839(times)X
+3034(yielding)X
+3318(a)X
+3376(maximum)X
+3721(\256le)X
+3844(size)X
+3990(of)X
+4078(2)X
+7 s
+946(32)Y
+10 s
+2418 1066(buckets)N
+2698(and)X
+2849(32)X
+2 f
+(*)S
+1 f
+2982(2)X
+7 s
+1034(11)Y
+10 s
+3113 1066(over\257ow)N
+3433(pages.)X
+3691(The)X
+3850(maximum)X
+2418 1154(page)N
+2597(size)X
+2749(is)X
+2829(2)X
+7 s
+1122(15)Y
+10 s
+1154(,)Y
+2971(yielding)X
+3259(a)X
+3321(maximum)X
+3671(\256le)X
+3799(size)X
+3950(greater)X
+2418 1242(than)N
+2601(131,000)X
+2906(GB)X
+3061(\(on)X
+3212(\256le)X
+3358(systems)X
+3655(supporting)X
+4041(\256les)X
+2418 1330(larger)N
+2626(than)X
+2784(4GB\).)X
+10 f
+2418 1418 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+1 Dt
+4014 2275 MXY
+0 133 Dl
+3881 2275 MXY
+0 133 Dl
+3748 2275 MXY
+0 133 Dl
+3083 2275 MXY
+0 133 Dl
+5 s
+1 f
+3523 2475(2/3)N
+3390(2/2)X
+3257(2/1)X
+2859(1/2)X
+2726(1/1)X
+5 Dt
+3814 1743 MXY
+0 133 Dl
+3282 1743 MXY
+0 133 Dl
+3017 1743 MXY
+0 133 Dl
+2884 1743 MXY
+0 133 Dl
+1 Dt
+3681 1743 MXY
+0 133 Dl
+133 0 Dl
+0 -133 Dl
+-133 0 Dl
+3548 MX
+0 133 Dl
+133 0 Dl
+0 -133 Dl
+-133 0 Dl
+3415 MX
+0 133 Dl
+133 0 Dl
+0 -133 Dl
+-133 0 Dl
+3282 MX
+0 133 Dl
+133 0 Dl
+0 -133 Dl
+-133 0 Dl
+3150 MX
+0 133 Dl
+132 0 Dl
+0 -133 Dl
+-132 0 Dl
+3017 MX
+0 133 Dl
+133 0 Dl
+0 -133 Dl
+-133 0 Dl
+2884 MX
+0 133 Dl
+133 0 Dl
+0 -133 Dl
+-133 0 Dl
+3 f
+8 s
+3017 2601(Over\257ow)N
+3285(Addresses)X
+3515 2833(Over\257ow)N
+3783(Pages)X
+2850(Buckets)X
+1 Di
+3349 2740 MXY
+ 3349 2740 lineto
+ 3482 2740 lineto
+ 3482 2873 lineto
+ 3349 2873 lineto
+ 3349 2740 lineto
+closepath 3 3349 2740 3482 2873 Dp
+2684 MX
+0 133 Dl
+133 0 Dl
+0 -133 Dl
+-133 0 Dl
+5 Dt
+4146 2275 MXY
+0 133 Dl
+3216 2275 MXY
+0 133 Dl
+2684 2275 MXY
+0 133 Dl
+2551 2275 MXY
+0 133 Dl
+1 f
+3798 1963(3)N
+3266 1980(2)N
+3001(1)X
+2868(0)X
+1 Dt
+2751 1743 MXY
+0 133 Dl
+133 0 Dl
+0 -133 Dl
+-133 0 Dl
+3548 2275 MXY
+-15 -22 Dl
+2 16 Dl
+-13 11 Dl
+26 -5 Dl
+-282 -117 Dl
+3432 2275 MXY
+-10 -25 Dl
+-2 16 Dl
+-15 8 Dl
+27 1 Dl
+-166 -117 Dl
+3282 2275 MXY
+12 -25 Dl
+-14 10 Dl
+-15 -6 Dl
+17 21 Dl
+-16 -117 Dl
+2884 2275 MXY
+26 7 Dl
+-12 -12 Dl
+3 -16 Dl
+-17 21 Dl
+382 -117 Dl
+2751 2275 MXY
+25 9 Dl
+-11 -12 Dl
+5 -17 Dl
+-19 20 Dl
+515 -117 Dl
+3 f
+3070 2152(Over\257ow)N
+3338(Pages)X
+3482 2275 MXY
+ 3482 2275 lineto
+ 3615 2275 lineto
+ 3615 2408 lineto
+ 3482 2408 lineto
+ 3482 2275 lineto
+closepath 3 3482 2275 3615 2408 Dp
+3349 MX
+ 3349 2275 lineto
+ 3482 2275 lineto
+ 3482 2408 lineto
+ 3349 2408 lineto
+ 3349 2275 lineto
+closepath 3 3349 2275 3482 2408 Dp
+3216 MX
+ 3216 2275 lineto
+ 3349 2275 lineto
+ 3349 2408 lineto
+ 3216 2408 lineto
+ 3216 2275 lineto
+closepath 3 3216 2275 3349 2408 Dp
+2817 MX
+ 2817 2275 lineto
+ 2950 2275 lineto
+ 2950 2408 lineto
+ 2817 2408 lineto
+ 2817 2275 lineto
+closepath 3 2817 2275 2950 2408 Dp
+2684 MX
+ 2684 2275 lineto
+ 2817 2275 lineto
+ 2817 2408 lineto
+ 2684 2408 lineto
+ 2684 2275 lineto
+closepath 3 2684 2275 2817 2408 Dp
+3615 MX
+0 133 Dl
+531 0 Dl
+0 -133 Dl
+-531 0 Dl
+2950 MX
+0 133 Dl
+266 0 Dl
+0 -133 Dl
+-266 0 Dl
+2551 MX
+0 133 Dl
+133 0 Dl
+0 -133 Dl
+-133 0 Dl
+3798 1726 MXY
+-21 -18 Dl
+6 16 Dl
+-10 13 Dl
+25 -11 Dl
+-599 -99 Dl
+3266 1726 MXY
+-1 -27 Dl
+-7 15 Dl
+-17 1 Dl
+25 11 Dl
+-67 -99 Dl
+3033 1726 MXY
+27 1 Dl
+-14 -8 Dl
+-1 -17 Dl
+-12 24 Dl
+166 -99 Dl
+2900 1726 MXY
+27 7 Dl
+-13 -11 Dl
+3 -17 Dl
+-17 21 Dl
+299 -99 Dl
+3058 1621(Split)N
+3203(Points)X
+2418 2275 MXY
+0 133 Dl
+133 0 Dl
+0 -133 Dl
+-133 0 Dl
+3 Dt
+-1 Ds
+3137(Figure)Y
+2619(3:)X
+1 f
+2691(Split)X
+2832(points)X
+3008(occur)X
+3168(between)X
+3399(generations)X
+3712(and)X
+3823(are)X
+3919(numbered)X
+2418 3225(from)N
+2560(0.)X
+2642(In)X
+2713(this)X
+2824(\256gure)X
+2991(there)X
+3136(are)X
+3231(two)X
+3345(over\257ow)X
+3590(pages)X
+3753(allocated)X
+4000(at)X
+4063(split)X
+2418 3313(point)N
+2566(1)X
+2614(and)X
+2722(three)X
+2865(allocated)X
+3111(at)X
+3173(split)X
+3300(point)X
+3448(2.)X
+10 s
+10 f
+2418 3489 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+3 f
+2949 3731(Buffer)N
+3192(Management)X
+1 f
+2590 3863(The)N
+2744(hash)X
+2920(table)X
+3105(is)X
+3187(stored)X
+3412(in)X
+3502(memory)X
+3797(as)X
+3892(a)X
+3956(logical)X
+2418 3951(array)N
+2633(of)X
+2749(bucket)X
+3012(pointers.)X
+3359(Physically,)X
+3761(the)X
+3907(array)X
+4121(is)X
+2418 4039(arranged)N
+2728(in)X
+2818(segments)X
+3144(of)X
+3239(256)X
+3387(pointers.)X
+3713(Initially,)X
+4013(there)X
+2418 4127(is)N
+2530(space)X
+2767(to)X
+2887(allocate)X
+3195(256)X
+3373(segments.)X
+3769(Reallocation)X
+2418 4215(occurs)N
+2651(when)X
+2847(the)X
+2967(number)X
+3234(of)X
+3323(buckets)X
+3590(exceeds)X
+3867(32K)X
+4027(\(256)X
+2418 4303(*)N
+2508(256\).)X
+2745(Primary)X
+3053(pages)X
+3286(may)X
+3473(be)X
+3598(accessed)X
+3929(directly)X
+2418 4391(through)N
+2711(the)X
+2853(array)X
+3062(by)X
+3185(bucket)X
+3442(number)X
+3730(and)X
+3889(over\257ow)X
+2418 4479(pages)N
+2628(are)X
+2754 0.4028(referenced)AX
+3122(logically)X
+3429(by)X
+3536(their)X
+3710(over\257ow)X
+4022(page)X
+2418 4567(address.)N
+2726(For)X
+2864(small)X
+3063(hash)X
+3236(tables,)X
+3469(it)X
+3539(is)X
+3618(desirable)X
+3934(to)X
+4022(keep)X
+2418 4655(all)N
+2525(pages)X
+2735(in)X
+2823(main)X
+3009(memory)X
+3302(while)X
+3506(on)X
+3612(larger)X
+3826(tables,)X
+4059(this)X
+2418 4743(is)N
+2523(probably)X
+2860(impossible.)X
+3298(To)X
+3438(satisfy)X
+3698(both)X
+3891(of)X
+4009(these)X
+2418 4831(requirements,)N
+2900(the)X
+3041(package)X
+3348(includes)X
+3658(buffer)X
+3897(manage-)X
+2418 4919(ment)N
+2598(with)X
+2760(LRU)X
+2940(\(least)X
+3134(recently)X
+3413(used\))X
+3607(replacement.)X
+2590 5033(By)N
+2730(default,)X
+3020(the)X
+3165(package)X
+3475(allocates)X
+3802(up)X
+3928(to)X
+4036(64K)X
+2418 5121(bytes)N
+2616(of)X
+2712(buffered)X
+3014(pages.)X
+3246(All)X
+3377(pages)X
+3589(in)X
+3680(the)X
+3807(buffer)X
+4032(pool)X
+2418 5209(are)N
+2542(linked)X
+2766(in)X
+2852(LRU)X
+3036(order)X
+3230(to)X
+3316(facilitate)X
+3621(fast)X
+3761(replacement.)X
+2418 5297(Whereas)N
+2724(ef\256cient)X
+3011(access)X
+3241(to)X
+3327(primary)X
+3605(pages)X
+3812(is)X
+3889(provided)X
+2418 5385(by)N
+2521(the)X
+2642(bucket)X
+2879(array,)X
+3087(ef\256cient)X
+3372(access)X
+3600(to)X
+3684(over\257ow)X
+3991(pages)X
+2418 5473(is)N
+2501(provided)X
+2816(by)X
+2926(linking)X
+3182(over\257ow)X
+3497(page)X
+3679(buffers)X
+3936(to)X
+4027(their)X
+2418 5561(predecessor)N
+2827(page)X
+3008(\(either)X
+3247(the)X
+3374(primary)X
+3657(page)X
+3838(or)X
+3933(another)X
+2418 5649(over\257ow)N
+2742(page\).)X
+3000(This)X
+3181(means)X
+3425(that)X
+3584(an)X
+3699(over\257ow)X
+4022(page)X
+3 f
+432 5960(6)N
+2970(USENIX)X
+9 f
+3292(-)X
+3 f
+3356(Winter)X
+3621('91)X
+9 f
+3748(-)X
+3 f
+3812(Dallas,)X
+4065(TX)X
+
+7 p
+%%Page: 7 7
+0(Courier)xf 0 f
+10 s 10 xH 0 xS 0 f
+3 f
+720 258(Seltzer)N
+977(&)X
+1064(Yigit)X
+3278(A)X
+3356(New)X
+3528(Hashing)X
+3831(Package)X
+4136(for)X
+4259(UNIX)X
+1 f
+720 538(cannot)N
+955(be)X
+1052(present)X
+1305(in)X
+1388(the)X
+1507(buffer)X
+1724(pool)X
+1886(if)X
+1955(its)X
+2050(primary)X
+2324(page)X
+720 626(is)N
+804(not)X
+937(present.)X
+1240(This)X
+1413(does)X
+1591(not)X
+1724(impact)X
+1972(performance)X
+2409(or)X
+720 714(functionality,)N
+1209(because)X
+1524(an)X
+1660(over\257ow)X
+2005(page)X
+2217(will)X
+2400(be)X
+720 802(accessed)N
+1048(only)X
+1236(after)X
+1430(its)X
+1550(predecessor)X
+1975(page)X
+2172(has)X
+2324(been)X
+720 890(accessed.)N
+1068(Figure)X
+1303(4)X
+1369(depicts)X
+1622(the)X
+1746(data)X
+1905(structures)X
+2242(used)X
+2414(to)X
+720 978(manage)N
+990(the)X
+1108(buffer)X
+1325(pool.)X
+892 1092(The)N
+1040(in-memory)X
+1419(bucket)X
+1656(array)X
+1845(contains)X
+2134(pointers)X
+2414(to)X
+720 1180(buffer)N
+975(header)X
+1248(structures)X
+1617(which)X
+1870(represent)X
+2222(primary)X
+720 1268(pages.)N
+968(Buffer)X
+1203(headers)X
+1474(contain)X
+1735(modi\256ed)X
+2043(bits,)X
+2202(the)X
+2324(page)X
+720 1356(address)N
+995(of)X
+1096(the)X
+1228(buffer,)X
+1479(a)X
+1548(pointer)X
+1808(to)X
+1903(the)X
+2034(actual)X
+2259(buffer,)X
+720 1444(and)N
+875(a)X
+950(pointer)X
+1216(to)X
+1317(the)X
+1454(buffer)X
+1690(header)X
+1944(for)X
+2077(an)X
+2191(over\257ow)X
+720 1532(page)N
+901(if)X
+979(it)X
+1052(exists,)X
+1283(in)X
+1374(addition)X
+1665(to)X
+1756(the)X
+1883(LRU)X
+2072(links.)X
+2296(If)X
+2378(the)X
+720 1620(buffer)N
+950(corresponding)X
+1442(to)X
+1537(a)X
+1606(particular)X
+1947(bucket)X
+2194(is)X
+2280(not)X
+2414(in)X
+720 1708(memory,)N
+1048(its)X
+1164(pointer)X
+1432(is)X
+1526(NULL.)X
+1801(In)X
+1909(effect,)X
+2154(pages)X
+2377(are)X
+720 1796(linked)N
+950(in)X
+1042(three)X
+1233(ways.)X
+1468(Using)X
+1689(the)X
+1817(buffer)X
+2043(headers,)X
+2338(they)X
+720 1884(are)N
+851(linked)X
+1083(physically)X
+1444(through)X
+1725(the)X
+1854(LRU)X
+2045(links)X
+2231(and)X
+2378(the)X
+720 1972(over\257ow)N
+1036(links.)X
+1241(Using)X
+1462(the)X
+1590(pages)X
+1803(themselves,)X
+2209(they)X
+2377(are)X
+720 2060(linked)N
+943(logically)X
+1246(through)X
+1518(the)X
+1639(over\257ow)X
+1946(addresses)X
+2276(on)X
+2378(the)X
+720 2148(page.)N
+948(Since)X
+1162(over\257ow)X
+1482(pages)X
+1700(are)X
+1834(accessed)X
+2151(only)X
+2328(after)X
+720 2236(their)N
+904(predecessor)X
+1321(pages,)X
+1560(they)X
+1734(are)X
+1869(removed)X
+2186(from)X
+2378(the)X
+720 2324(buffer)N
+937(pool)X
+1099(when)X
+1293(their)X
+1460(primary)X
+1734(is)X
+1807(removed.)X
+10 f
+720 2412 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+1 Dt
+2309 3177 MXY
+24 15 Dl
+-8 -15 Dl
+8 -15 Dl
+-24 15 Dl
+52 0 Dl
+789 3160 MXY
+-35 0 Dl
+0 -156 Dl
+1607 0 Dl
+0 173 Dl
+789 3091 MXY
+-24 -15 Dl
+9 15 Dl
+-9 15 Dl
+24 -15 Dl
+-69 0 Dl
+2309 3125 MXY
+104 0 Dl
+0 -155 Dl
+-1693 0 Dl
+0 121 Dl
+927 3160 MXY
+24 15 Dl
+-9 -15 Dl
+9 -15 Dl
+-24 15 Dl
+553 0 Dl
+1618 3177 MXY
+8 27 Dl
+4 -17 Dl
+16 -6 Dl
+-28 -4 Dl
+138 121 Dl
+1895 3315 MXY
+28 3 Dl
+-15 -9 Dl
+1 -18 Dl
+-14 24 Dl
+276 -138 Dl
+3108 MY
+-28 -3 Dl
+15 10 Dl
+-1 17 Dl
+14 -24 Dl
+-276 138 Dl
+1756 3229 MXY
+-8 -27 Dl
+-3 17 Dl
+-16 6 Dl
+27 4 Dl
+-138 -121 Dl
+1480 MX
+-24 -15 Dl
+9 15 Dl
+-9 15 Dl
+24 -15 Dl
+-553 0 Dl
+3 f
+5 s
+1083 3073(LRU)N
+1178(chain)X
+4 Ds
+1402 3851 MXY
+ 1402 3851 lineto
+ 1471 3851 lineto
+ 1471 3920 lineto
+ 1402 3920 lineto
+ 1402 3851 lineto
+closepath 19 1402 3851 1471 3920 Dp
+1445 3747(Over\257ow)N
+1613(Address)X
+1549 3609 MXY
+0 69 Dl
+1756 MX
+-23 -15 Dl
+8 15 Dl
+-8 15 Dl
+23 -15 Dl
+-207 0 Dl
+-1 Ds
+3 Dt
+1756 3419 MXY
+-6 -28 Dl
+-4 17 Dl
+-17 5 Dl
+27 6 Dl
+-138 -138 Dl
+2240 3471 MXY
+15 -24 Dl
+-15 9 Dl
+-15 -9 Dl
+15 24 Dl
+0 -138 Dl
+1826 3609 MXY
+15 -24 Dl
+-15 9 Dl
+-16 -9 Dl
+16 24 Dl
+0 -138 Dl
+1549 MX
+15 -24 Dl
+-15 9 Dl
+-15 -9 Dl
+15 24 Dl
+0 -138 Dl
+858 3471 MXY
+15 -24 Dl
+-15 9 Dl
+-15 -9 Dl
+15 24 Dl
+0 -138 Dl
+2240 3056 MXY
+15 -24 Dl
+-15 9 Dl
+-15 -9 Dl
+15 24 Dl
+0 -138 Dl
+1549 3056 MXY
+15 -24 Dl
+-15 9 Dl
+-15 -9 Dl
+15 24 Dl
+0 -138 Dl
+858 3056 MXY
+15 -24 Dl
+-15 9 Dl
+-15 -9 Dl
+15 24 Dl
+0 -138 Dl
+1 Dt
+2171 3471 MXY
+ 2171 3471 lineto
+ 2448 3471 lineto
+ 2448 3609 lineto
+ 2171 3609 lineto
+ 2171 3471 lineto
+closepath 19 2171 3471 2448 3609 Dp
+1756 3609 MXY
+ 1756 3609 lineto
+ 2033 3609 lineto
+ 2033 3747 lineto
+ 1756 3747 lineto
+ 1756 3609 lineto
+closepath 3 1756 3609 2033 3747 Dp
+1480 3471 MXY
+ 1480 3471 lineto
+ 1756 3471 lineto
+ 1756 3609 lineto
+ 1480 3609 lineto
+ 1480 3471 lineto
+closepath 19 1480 3471 1756 3609 Dp
+789 MX
+ 789 3471 lineto
+ 1065 3471 lineto
+ 1065 3609 lineto
+ 789 3609 lineto
+ 789 3471 lineto
+closepath 19 789 3471 1065 3609 Dp
+962 3903(Buffer)N
+1083(Header)X
+849 3851 MXY
+ 849 3851 lineto
+ 918 3851 lineto
+ 918 3920 lineto
+ 849 3920 lineto
+ 849 3851 lineto
+closepath 14 849 3851 918 3920 Dp
+1756 3194 MXY
+ 1756 3194 lineto
+ 1895 3194 lineto
+ 1895 3471 lineto
+ 1756 3471 lineto
+ 1756 3194 lineto
+closepath 14 1756 3194 1895 3471 Dp
+2171 3056 MXY
+ 2171 3056 lineto
+ 2309 3056 lineto
+ 2309 3333 lineto
+ 2171 3333 lineto
+ 2171 3056 lineto
+closepath 14 2171 3056 2309 3333 Dp
+1480 MX
+ 1480 3056 lineto
+ 1618 3056 lineto
+ 1618 3333 lineto
+ 1480 3333 lineto
+ 1480 3056 lineto
+closepath 14 1480 3056 1618 3333 Dp
+789 MX
+ 789 3056 lineto
+ 927 3056 lineto
+ 927 3333 lineto
+ 789 3333 lineto
+ 789 3056 lineto
+closepath 14 789 3056 927 3333 Dp
+2780 MY
+0 138 Dl
+138 0 Dl
+0 -138 Dl
+-138 0 Dl
+927 MX
+0 138 Dl
+138 0 Dl
+0 -138 Dl
+-138 0 Dl
+1065 MX
+0 138 Dl
+138 0 Dl
+0 -138 Dl
+-138 0 Dl
+1203 MX
+0 138 Dl
+139 0 Dl
+0 -138 Dl
+-139 0 Dl
+1342 MX
+0 138 Dl
+138 0 Dl
+0 -138 Dl
+-138 0 Dl
+1480 MX
+0 138 Dl
+138 0 Dl
+0 -138 Dl
+-138 0 Dl
+1618 MX
+0 138 Dl
+138 0 Dl
+0 -138 Dl
+-138 0 Dl
+1756 MX
+0 138 Dl
+139 0 Dl
+0 -138 Dl
+-139 0 Dl
+1895 MX
+0 138 Dl
+138 0 Dl
+0 -138 Dl
+-138 0 Dl
+2033 MX
+0 138 Dl
+138 0 Dl
+0 -138 Dl
+-138 0 Dl
+2171 MX
+0 138 Dl
+138 0 Dl
+0 -138 Dl
+-138 0 Dl
+2309 MX
+0 138 Dl
+139 0 Dl
+0 -138 Dl
+-139 0 Dl
+13 s
+1048 2720(In)N
+1173(Memory)X
+1580(Bucket)X
+1918(Array)X
+867 3584(B0)N
+1558(B5)X
+2223(B10)X
+1788 3722(O1/1)N
+5 s
+1515 3903(Primay)N
+1651(Buffer)X
+4 Ds
+1990 3851 MXY
+ 1990 3851 lineto
+ 2059 3851 lineto
+ 2059 3920 lineto
+ 1990 3920 lineto
+ 1990 3851 lineto
+closepath 3 1990 3851 2059 3920 Dp
+2102 3903(Over\257ow)N
+2270(Buffer)X
+3 Dt
+-1 Ds
+8 s
+720 4184(Figure)N
+922(4:)X
+1 f
+996(Three)X
+1164(primary)X
+1386(pages)X
+1551(\(B0,)X
+1683(B5,)X
+1794(B10\))X
+1942(are)X
+2039(accessed)X
+2281(directly)X
+720 4272(from)N
+862(the)X
+958(bucket)X
+1146(array.)X
+1326(The)X
+1443(one)X
+1553(over\257ow)X
+1798(page)X
+1935(\(O1/1\))X
+2122(is)X
+2182(linked)X
+2359(phy-)X
+720 4360(sically)N
+915(from)X
+1067(its)X
+1155(primary)X
+1384(page's)X
+1577(buffer)X
+1759(header)X
+1955(as)X
+2035(well)X
+2172(as)X
+2252(logically)X
+720 4448(from)N
+860(its)X
+937(predecessor)X
+1253(page)X
+1389(buffer)X
+1560(\(B5\).)X
+10 s
+10 f
+720 4624 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+3 f
+1191 4954(Table)N
+1406(Parameterization)X
+1 f
+892 5086(When)N
+1107(a)X
+1166(hash)X
+1336(table)X
+1515(is)X
+1590(created,)X
+1865(the)X
+1985(bucket)X
+2221(size,)X
+2388(\256ll)X
+720 5174(factor,)N
+953(initial)X
+1164(number)X
+1434(of)X
+1526(elements,)X
+1856(number)X
+2125(of)X
+2216(bytes)X
+2409(of)X
+720 5262(main)N
+919(memory)X
+1225(used)X
+1411(for)X
+1543(caching,)X
+1851(and)X
+2005(a)X
+2079(user-de\256ned)X
+720 5350(hash)N
+892(function)X
+1184(may)X
+1347(be)X
+1448(speci\256ed.)X
+1797(The)X
+1946(bucket)X
+2184(size)X
+2333(\(and)X
+720 5438(page)N
+906(size)X
+1064(for)X
+1191(over\257ow)X
+1509(pages\))X
+1752(defaults)X
+2039(to)X
+2134(256)X
+2287(bytes.)X
+720 5526(For)N
+858(tables)X
+1072(with)X
+1241(large)X
+1429(data)X
+1590(items,)X
+1810(it)X
+1881(may)X
+2046(be)X
+2149(preferable)X
+720 5614(to)N
+803(increase)X
+1088(the)X
+1207(page)X
+1380(size,)X
+1545(and,)X
+1701(conversely,)X
+2089(applications)X
+720 5702(storing)N
+1002(small)X
+1235(items)X
+1467(exclusively)X
+1891(in)X
+2012(memory)X
+2338(may)X
+2706 538(bene\256t)N
+2966(from)X
+3164(a)X
+3242(smaller)X
+3520(bucket)X
+3776(size.)X
+3983(A)X
+4082(bucket)X
+4337(size)X
+2706 626(smaller)N
+2962(than)X
+3120(64)X
+3220(bytes)X
+3409(is)X
+3482(not)X
+3604(recommended.)X
+2878 740(The)N
+3031(\256ll)X
+3147(factor)X
+3363(indicates)X
+3676(a)X
+3740(desired)X
+4000(density)X
+4258(within)X
+2706 828(the)N
+2833(hash)X
+3009(table.)X
+3234(It)X
+3312(is)X
+3394(an)X
+3499(approximation)X
+3995(of)X
+4091(the)X
+4217(number)X
+2706 916(of)N
+2815(keys)X
+3004(allowed)X
+3300(to)X
+3404(accumulate)X
+3811(in)X
+3914(any)X
+4071(one)X
+4228(bucket,)X
+2706 1004(determining)N
+3119(when)X
+3319(the)X
+3442(hash)X
+3614(table)X
+3795(grows.)X
+4056(Its)X
+4161(default)X
+4409(is)X
+2706 1092(eight.)N
+2953(If)X
+3054(the)X
+3199(user)X
+3380(knows)X
+3636(the)X
+3781(average)X
+4079(size)X
+4251(of)X
+4364(the)X
+2706 1180(key/data)N
+3008(pairs)X
+3194(being)X
+3402(stored)X
+3627(in)X
+3718(the)X
+3845(table,)X
+4050(near)X
+4218(optimal)X
+2706 1268(bucket)N
+2943(sizes)X
+3122(and)X
+3261(\256ll)X
+3372(factors)X
+3614(may)X
+3775(be)X
+3874(selected)X
+4155(by)X
+4257(apply-)X
+2706 1356(ing)N
+2828(the)X
+2946(equation:)X
+0 f
+8 s
+2706 1655(\(1\))N
+2994 -0.3938(\(\(average_pair_length)AX
+3830(+)X
+3906(4\))X
+4020(*)X
+3032 1743(ffactor\))N
+3374(>=)X
+3488(bsize)X
+1 f
+10 s
+2706 2042(For)N
+2859(highly)X
+3104(time)X
+3287(critical)X
+3551(applications,)X
+3999(experimenting)X
+2706 2130(with)N
+2919(different)X
+3266(bucket)X
+3550(sizes)X
+3776(and)X
+3962(\256ll)X
+4120(factors)X
+4409(is)X
+2706 2218(encouraged.)N
+2878 2332(Figures)N
+3144(5a,b,)X
+3326(and)X
+3468(c)X
+3530(illustrate)X
+3836(the)X
+3960(effects)X
+4200(of)X
+4292(vary-)X
+2706 2420(ing)N
+2841(page)X
+3026(sizes)X
+3215(and)X
+3363(\256ll)X
+3483(factors)X
+3734(for)X
+3860(the)X
+3990(same)X
+4187(data)X
+4353(set.)X
+2706 2508(The)N
+2864(data)X
+3031(set)X
+3152(consisted)X
+3482(of)X
+3581(24474)X
+3813(keys)X
+3992(taken)X
+4198(from)X
+4386(an)X
+2706 2596(online)N
+2931(dictionary.)X
+3301(The)X
+3451(data)X
+3609(value)X
+3807(for)X
+3925(each)X
+4097(key)X
+4237(was)X
+4386(an)X
+2706 2684(ASCII)N
+2938(string)X
+3143(for)X
+3260(an)X
+3359(integer)X
+3605(from)X
+3784(1)X
+3847(to)X
+3931(24474)X
+4153(inclusive.)X
+2706 2772(The)N
+2867(test)X
+3013(run)X
+3155(consisted)X
+3488(of)X
+3590(creating)X
+3884(a)X
+3955(new)X
+4124(hash)X
+4306(table)X
+2706 2860(\(where)N
+2966(the)X
+3100(ultimate)X
+3398(size)X
+3559(of)X
+3662(the)X
+3796(table)X
+3987(was)X
+4147(known)X
+4400(in)X
+2706 2948(advance\),)N
+3054(entering)X
+3354(each)X
+3539(key/data)X
+3848(pair)X
+4010(into)X
+4171(the)X
+4306(table)X
+2706 3036(and)N
+2849(then)X
+3014(retrieving)X
+3353(each)X
+3528(key/data)X
+3827(pair)X
+3979(from)X
+4162(the)X
+4286(table.)X
+2706 3124(Each)N
+2898(of)X
+2996(the)X
+3125(graphs)X
+3369(shows)X
+3599(the)X
+3727(timings)X
+3996(resulting)X
+4306(from)X
+2706 3212(varying)N
+2973(the)X
+3093(pagesize)X
+3392(from)X
+3570(128)X
+3712(bytes)X
+3903(to)X
+3986(1M)X
+4118(and)X
+4255(the)X
+4374(\256ll)X
+2706 3300(factor)N
+2929(from)X
+3120(1)X
+3195(to)X
+3292(128.)X
+3486(For)X
+3631(each)X
+3813(run,)X
+3974(the)X
+4106(buffer)X
+4337(size)X
+2706 3388(was)N
+2874(set)X
+3006(at)X
+3106(1M.)X
+3299(The)X
+3466(tests)X
+3650(were)X
+3849(all)X
+3971(run)X
+4120(on)X
+4242(an)X
+4360(HP)X
+2706 3476(9000/370)N
+3077(\(33.3)X
+3312(Mhz)X
+3527(MC68030\),)X
+3966(with)X
+4176(16M)X
+4395(of)X
+2706 3564(memory,)N
+3042(64K)X
+3228(physically)X
+3605(addressed)X
+3970(cache,)X
+4222(and)X
+4386(an)X
+2706 3652(HP7959S)N
+3055(disk)X
+3231(drive,)X
+3459(running)X
+3751(4.3BSD-Reno)X
+4244(single-)X
+2706 3740(user.)N
+2878 3854(Both)N
+3066(system)X
+3321(time)X
+3496(\(Figure)X
+3764(5a\))X
+3899(and)X
+4047(elapsed)X
+4320(time)X
+2706 3942(\(Figure)N
+2966(5b\))X
+3097(show)X
+3290(that)X
+3434(for)X
+3552(all)X
+3655(bucket)X
+3892(sizes,)X
+4091(the)X
+4212(greatest)X
+2706 4030(performance)N
+3137(gains)X
+3329(are)X
+3451(made)X
+3648(by)X
+3751(increasing)X
+4104(the)X
+4225(\256ll)X
+4336(fac-)X
+2706 4118(tor)N
+2822(until)X
+2995(equation)X
+3298(1)X
+3365(is)X
+3445(satis\256ed.)X
+3774(The)X
+3925(user)X
+4085(time)X
+4253(shown)X
+2706 4206(in)N
+2791(Figure)X
+3023(5c)X
+3122(gives)X
+3314(a)X
+3373(more)X
+3561(detailed)X
+3838(picture)X
+4083(of)X
+4172(how)X
+4332(per-)X
+2706 4294(formance)N
+3054(varies.)X
+3330(The)X
+3499(smaller)X
+3778(bucket)X
+4035(sizes)X
+4234(require)X
+2706 4382(fewer)N
+2921(keys)X
+3099(per)X
+3233(page)X
+3416(to)X
+3509(satisfy)X
+3749(equation)X
+4056(1)X
+4127(and)X
+4274(there-)X
+2706 4470(fore)N
+2860(incur)X
+3049(fewer)X
+3257(collisions.)X
+3607(However,)X
+3946(when)X
+4144(the)X
+4265(buffer)X
+2706 4558(pool)N
+2884(size)X
+3045(is)X
+3134(\256xed,)X
+3349(smaller)X
+3620(pages)X
+3838(imply)X
+4059(more)X
+4259(pages.)X
+2706 4646(An)N
+2830(increased)X
+3160(number)X
+3430(of)X
+3522(pages)X
+3730(means)X
+3960(more)X
+2 f
+4150(malloc\(3\))X
+1 f
+2706 4734(calls)N
+2879(and)X
+3021(more)X
+3212(overhead)X
+3533(in)X
+3621(the)X
+3745(hash)X
+3918(package's)X
+4265(buffer)X
+2706 4822(manager)N
+3003(to)X
+3085(manage)X
+3355(the)X
+3473(additional)X
+3813(pages.)X
+2878 4936(The)N
+3028(tradeoff)X
+3308(works)X
+3529(out)X
+3655(most)X
+3834(favorably)X
+4166(when)X
+4364(the)X
+2706 5024(page)N
+2886(size)X
+3039(is)X
+3120(256)X
+3268(and)X
+3412(the)X
+3538(\256ll)X
+3654(factor)X
+3870(is)X
+3950(8.)X
+4057(Similar)X
+4319(con-)X
+2706 5112(clusions)N
+3009(were)X
+3207(obtained)X
+3524(if)X
+3614(the)X
+3753(test)X
+3905(was)X
+4071(run)X
+4218(without)X
+2706 5200(knowing)N
+3007(the)X
+3126(\256nal)X
+3289(table)X
+3466(size)X
+3612(in)X
+3695(advance.)X
+4020(If)X
+4095(the)X
+4214(\256le)X
+4337(was)X
+2706 5288(closed)N
+2942(and)X
+3088(written)X
+3345(to)X
+3437(disk,)X
+3620(the)X
+3748(conclusions)X
+4156(were)X
+4343(still)X
+2706 5376(the)N
+2832(same.)X
+3065(However,)X
+3408(rereading)X
+3740(the)X
+3865(\256le)X
+3994(from)X
+4177(disk)X
+4337(was)X
+2706 5464(slightly)N
+2983(faster)X
+3199(if)X
+3285(a)X
+3358(larger)X
+3583(bucket)X
+3834(size)X
+3996(and)X
+4149(\256ll)X
+4274(factor)X
+2706 5552(were)N
+2898(used)X
+3079(\(1K)X
+3238(bucket)X
+3486(size)X
+3645(and)X
+3795(32)X
+3909(\256ll)X
+4031(factor\).)X
+4320(This)X
+2706 5640(follows)N
+2987(intuitively)X
+3356(from)X
+3553(the)X
+3691(improved)X
+4038(ef\256ciency)X
+4395(of)X
+3 f
+720 5960(USENIX)N
+9 f
+1042(-)X
+3 f
+1106(Winter)X
+1371('91)X
+9 f
+1498(-)X
+3 f
+1562(Dallas,)X
+1815(TX)X
+4424(7)X
+
+8 p
+%%Page: 8 8
+0(Courier)xf 0 f
+10 s 10 xH 0 xS 0 f
+3 f
+432 258(A)N
+510(New)X
+682(Hashing)X
+985(Package)X
+1290(for)X
+1413(UNIX)X
+3663(Seltzer)X
+3920(&)X
+4007(Yigit)X
+1 f
+432 538(performing)N
+830(1K)X
+965(reads)X
+1172(from)X
+1365(the)X
+1500(disk)X
+1670(rather)X
+1894(than)X
+2068(256)X
+432 626(byte)N
+609(reads.)X
+857(In)X
+962(general,)X
+1257(performance)X
+1702(for)X
+1834(disk)X
+2005(based)X
+432 714(tables)N
+639(is)X
+712(best)X
+861(when)X
+1055(the)X
+1173(page)X
+1345(size)X
+1490(is)X
+1563(approximately)X
+2046(1K.)X
+10 f
+432 802 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+619 2380 MXY
+-12 24 Dl
+24 0 Dl
+-12 -24 Dl
+629 2437 MXY
+-12 24 Dl
+24 0 Dl
+-12 -24 Dl
+648 2504 MXY
+-12 25 Dl
+24 0 Dl
+-12 -25 Dl
+686 2515 MXY
+-12 24 Dl
+24 0 Dl
+-12 -24 Dl
+762 2516 MXY
+-12 24 Dl
+25 0 Dl
+-13 -24 Dl
+916 2515 MXY
+-13 24 Dl
+25 0 Dl
+-12 -24 Dl
+1222 2516 MXY
+-12 24 Dl
+24 0 Dl
+-12 -24 Dl
+1834 2515 MXY
+-12 24 Dl
+24 0 Dl
+-12 -24 Dl
+1 Dt
+619 2392 MXY
+10 57 Dl
+19 67 Dl
+38 11 Dl
+76 1 Dl
+154 -1 Dl
+306 1 Dl
+612 -1 Dl
+8 s
+1 f
+1628 2522(128)N
+3 Dt
+607 2245 MXY
+24 Dc
+617 2375 MXY
+23 Dc
+635 2442 MXY
+24 Dc
+674 2525 MXY
+23 Dc
+750 2529 MXY
+24 Dc
+904 2527 MXY
+23 Dc
+1210 MX
+23 Dc
+1822 2528 MXY
+23 Dc
+20 Ds
+1 Dt
+619 2245 MXY
+10 130 Dl
+19 67 Dl
+38 83 Dl
+76 4 Dl
+154 -2 Dl
+306 0 Dl
+612 1 Dl
+678 2482(256)N
+-1 Ds
+3 Dt
+619 2127 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+629 2191 MXY
+0 25 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+648 2334 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+686 2409 MXY
+0 25 Dl
+0 -13 Dl
+12 0 Dl
+-24 0 Dl
+762 2516 MXY
+0 25 Dl
+0 -12 Dl
+13 0 Dl
+-25 0 Dl
+916 2516 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-25 0 Dl
+1222 2515 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+1834 2515 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+5 Dt
+619 2139 MXY
+10 65 Dl
+19 142 Dl
+38 75 Dl
+76 108 Dl
+154 -1 Dl
+306 -1 Dl
+612 0 Dl
+694 2401(512)N
+3 Dt
+631 2064 MXY
+-24 24 Dl
+12 -12 Dl
+-12 -12 Dl
+24 24 Dl
+641 2077 MXY
+-24 25 Dl
+12 -12 Dl
+-12 -13 Dl
+24 25 Dl
+660 2132 MXY
+-24 24 Dl
+12 -12 Dl
+-12 -12 Dl
+24 24 Dl
+698 2292 MXY
+-24 24 Dl
+12 -12 Dl
+-12 -12 Dl
+24 24 Dl
+775 2382 MXY
+-25 24 Dl
+12 -12 Dl
+-12 -12 Dl
+25 24 Dl
+928 2516 MXY
+-25 24 Dl
+13 -12 Dl
+-13 -12 Dl
+25 24 Dl
+1234 2516 MXY
+-24 25 Dl
+12 -12 Dl
+-12 -13 Dl
+24 25 Dl
+1846 2516 MXY
+-24 24 Dl
+12 -12 Dl
+-12 -12 Dl
+24 24 Dl
+16 Ds
+1 Dt
+619 2076 MXY
+10 14 Dl
+19 54 Dl
+38 160 Dl
+76 90 Dl
+154 134 Dl
+306 1 Dl
+612 -1 Dl
+694 2257(1024)N
+-1 Ds
+3 Dt
+619 1877 MXY
+12 -24 Dl
+-24 0 Dl
+12 24 Dl
+629 1855 MXY
+12 -24 Dl
+-24 0 Dl
+12 24 Dl
+648 1838 MXY
+12 -24 Dl
+-24 0 Dl
+12 24 Dl
+686 1860 MXY
+12 -25 Dl
+-24 0 Dl
+12 25 Dl
+762 1923 MXY
+13 -24 Dl
+-25 0 Dl
+12 24 Dl
+916 2087 MXY
+12 -24 Dl
+-25 0 Dl
+13 24 Dl
+1222 2256 MXY
+12 -24 Dl
+-24 0 Dl
+12 24 Dl
+1834 2541 MXY
+12 -25 Dl
+-24 0 Dl
+12 25 Dl
+619 1865 MXY
+10 -22 Dl
+19 -17 Dl
+38 21 Dl
+76 64 Dl
+154 164 Dl
+306 169 Dl
+612 285 Dl
+1645 2427(4096)N
+619 1243 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+629 1196 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+648 1146 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+686 1174 MXY
+0 25 Dl
+0 -13 Dl
+12 0 Dl
+-24 0 Dl
+762 1249 MXY
+0 24 Dl
+0 -12 Dl
+13 0 Dl
+-25 0 Dl
+916 1371 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-25 0 Dl
+1222 1680 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+1834 1999 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+619 1255 MXY
+10 -47 Dl
+19 -50 Dl
+38 28 Dl
+76 75 Dl
+154 122 Dl
+306 309 Dl
+612 319 Dl
+1741 1934(8192)N
+5 Dt
+609 2531 MXY
+1225 0 Dl
+609 MX
+0 -1553 Dl
+2531 MY
+0 16 Dl
+4 Ds
+1 Dt
+2531 MY
+0 -1553 Dl
+593 2625(0)N
+-1 Ds
+5 Dt
+916 2531 MXY
+0 16 Dl
+4 Ds
+1 Dt
+2531 MY
+0 -1553 Dl
+884 2625(32)N
+-1 Ds
+5 Dt
+1222 2531 MXY
+0 16 Dl
+4 Ds
+1 Dt
+2531 MY
+0 -1553 Dl
+1190 2625(64)N
+-1 Ds
+5 Dt
+1528 2531 MXY
+0 16 Dl
+4 Ds
+1 Dt
+2531 MY
+0 -1553 Dl
+1496 2625(96)N
+-1 Ds
+5 Dt
+1834 2531 MXY
+0 16 Dl
+4 Ds
+1 Dt
+2531 MY
+0 -1553 Dl
+1786 2625(128)N
+-1 Ds
+5 Dt
+609 2531 MXY
+-16 0 Dl
+4 Ds
+1 Dt
+609 MX
+1225 0 Dl
+545 2558(0)N
+-1 Ds
+5 Dt
+609 2013 MXY
+-16 0 Dl
+4 Ds
+1 Dt
+609 MX
+1225 0 Dl
+481 2040(100)N
+-1 Ds
+5 Dt
+609 1496 MXY
+-16 0 Dl
+4 Ds
+1 Dt
+609 MX
+1225 0 Dl
+481 1523(200)N
+-1 Ds
+5 Dt
+609 978 MXY
+-16 0 Dl
+4 Ds
+1 Dt
+609 MX
+1225 0 Dl
+481 1005(300)N
+1088 2724(Fill)N
+1194(Factor)X
+422 1611(S)N
+426 1667(e)N
+426 1724(c)N
+424 1780(o)N
+424 1837(n)N
+424 1893(d)N
+428 1949(s)N
+3 Dt
+-1 Ds
+3 f
+432 2882(Figure)N
+636(5a:)X
+1 f
+744(System)X
+956(Time)X
+1113(for)X
+1209(dictionary)X
+1490(data)X
+1618(set)X
+1711(with)X
+1847(1M)X
+1958(of)X
+2033(buffer)X
+432 2970(space)N
+594(and)X
+707(varying)X
+923(bucket)X
+1114(sizes)X
+1259(and)X
+1372(\256ll)X
+1465(factors.)X
+1675(Each)X
+1823(line)X
+1940(is)X
+2004(labeled)X
+432 3058(with)N
+562(its)X
+639(bucket)X
+825(size.)X
+10 s
+10 f
+432 3234 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+8 s
+1 f
+428 4381(s)N
+424 4325(d)N
+424 4269(n)N
+424 4212(o)N
+426 4156(c)N
+426 4099(e)N
+422 4043(S)N
+1116 5156(Fill)N
+1222(Factor)X
+506 3437(3200)N
+4 Ds
+1 Dt
+666 3410 MXY
+1168 0 Dl
+-1 Ds
+5 Dt
+666 MX
+-16 0 Dl
+506 3825(2400)N
+4 Ds
+1 Dt
+666 3799 MXY
+1168 0 Dl
+-1 Ds
+5 Dt
+666 MX
+-16 0 Dl
+506 4214(1600)N
+4 Ds
+1 Dt
+666 4186 MXY
+1168 0 Dl
+-1 Ds
+5 Dt
+666 MX
+-16 0 Dl
+538 4602(800)N
+4 Ds
+1 Dt
+666 4575 MXY
+1168 0 Dl
+-1 Ds
+5 Dt
+666 MX
+-16 0 Dl
+602 4990(0)N
+4 Ds
+1 Dt
+666 4963 MXY
+1168 0 Dl
+-1 Ds
+5 Dt
+666 MX
+-16 0 Dl
+1786 5057(128)N
+4 Ds
+1 Dt
+1834 4963 MXY
+0 -1553 Dl
+-1 Ds
+5 Dt
+4963 MY
+0 16 Dl
+1510 5057(96)N
+4 Ds
+1 Dt
+1542 4963 MXY
+0 -1553 Dl
+-1 Ds
+5 Dt
+4963 MY
+0 16 Dl
+1218 5057(64)N
+4 Ds
+1 Dt
+1250 4963 MXY
+0 -1553 Dl
+-1 Ds
+5 Dt
+4963 MY
+0 16 Dl
+926 5057(32)N
+4 Ds
+1 Dt
+958 4963 MXY
+0 -1553 Dl
+-1 Ds
+5 Dt
+4963 MY
+0 16 Dl
+650 5057(0)N
+4 Ds
+1 Dt
+666 4963 MXY
+0 -1553 Dl
+-1 Ds
+5 Dt
+4963 MY
+0 16 Dl
+4963 MY
+0 -1553 Dl
+4963 MY
+1168 0 Dl
+1741 4752(8192)N
+3 Dt
+675 3732 MXY
+9 -172 Dl
+18 -118 Dl
+37 128 Dl
+73 -121 Dl
+146 623 Dl
+292 497 Dl
+584 245 Dl
+4802 MY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+1250 4557 MXY
+0 25 Dl
+0 -13 Dl
+12 0 Dl
+-24 0 Dl
+958 4060 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+812 3437 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+739 3558 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+702 3430 MXY
+0 25 Dl
+0 -13 Dl
+13 0 Dl
+-25 0 Dl
+684 3548 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+675 3720 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+1637 4912(4096)N
+675 4307 MXY
+9 -58 Dl
+18 30 Dl
+37 89 Dl
+73 144 Dl
+146 235 Dl
+292 122 Dl
+584 89 Dl
+4970 MY
+12 -24 Dl
+-24 0 Dl
+12 24 Dl
+1250 4881 MXY
+12 -24 Dl
+-24 0 Dl
+12 24 Dl
+958 4759 MXY
+12 -24 Dl
+-24 0 Dl
+12 24 Dl
+812 4524 MXY
+12 -24 Dl
+-24 0 Dl
+12 24 Dl
+739 4380 MXY
+12 -24 Dl
+-24 0 Dl
+12 24 Dl
+702 4291 MXY
+13 -24 Dl
+-25 0 Dl
+12 24 Dl
+684 4261 MXY
+12 -24 Dl
+-24 0 Dl
+12 24 Dl
+675 4319 MXY
+12 -24 Dl
+-24 0 Dl
+12 24 Dl
+734 4662(1024)N
+16 Ds
+1 Dt
+675 4352 MXY
+9 60 Dl
+18 134 Dl
+37 266 Dl
+73 117 Dl
+146 30 Dl
+292 0 Dl
+584 -1 Dl
+-1 Ds
+3 Dt
+1846 4946 MXY
+-24 24 Dl
+12 -12 Dl
+-12 -12 Dl
+24 24 Dl
+1262 4946 MXY
+-24 25 Dl
+12 -12 Dl
+-12 -13 Dl
+24 25 Dl
+970 4947 MXY
+-24 24 Dl
+12 -12 Dl
+-12 -12 Dl
+24 24 Dl
+824 4917 MXY
+-24 24 Dl
+12 -12 Dl
+-12 -12 Dl
+24 24 Dl
+751 4800 MXY
+-24 24 Dl
+12 -12 Dl
+-12 -12 Dl
+24 24 Dl
+715 4534 MXY
+-25 25 Dl
+12 -13 Dl
+-12 -12 Dl
+25 25 Dl
+696 4400 MXY
+-24 24 Dl
+12 -12 Dl
+-12 -12 Dl
+24 24 Dl
+687 4339 MXY
+-24 25 Dl
+12 -12 Dl
+-12 -13 Dl
+24 25 Dl
+718 4792(512)N
+5 Dt
+675 4422 MXY
+9 137 Dl
+18 278 Dl
+37 105 Dl
+73 18 Dl
+146 -1 Dl
+292 0 Dl
+584 -1 Dl
+3 Dt
+4946 MY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+1250 4946 MXY
+0 25 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+958 4947 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+812 4948 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+739 4930 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+702 4824 MXY
+0 25 Dl
+0 -12 Dl
+13 0 Dl
+-25 0 Dl
+684 4547 MXY
+0 24 Dl
+0 -12 Dl
+12 0 Dl
+-24 0 Dl
+675 4410 MXY
+0 25 Dl
+0 -13 Dl
+12 0 Dl
+-24 0 Dl
+750 4921(256)N
+20 Ds
+1 Dt
+675 4597 MXY
+9 246 Dl
+18 106 Dl
+37 10 Dl
+73 0 Dl
+146 0 Dl
+292 0 Dl
+584 -1 Dl
+-1 Ds
+3 Dt
+1822 MX
+23 Dc
+1238 4959 MXY
+23 Dc
+946 MX
+23 Dc
+800 MX
+23 Dc
+727 MX
+23 Dc
+691 4949 MXY
+23 Dc
+672 4843 MXY
+24 Dc
+663 4597 MXY
+24 Dc
+1395 4961(128)N
+1 Dt
+675 4855 MXY
+9 93 Dl
+18 10 Dl
+37 1 Dl
+73 0 Dl
+146 -1 Dl
+292 0 Dl
+584 0 Dl
+3 Dt
+4946 MY
+-12 24 Dl
+24 0 Dl
+-12 -24 Dl
+1250 MX
+-12 24 Dl
+24 0 Dl
+-12 -24 Dl
+958 MX
+-12 24 Dl
+24 0 Dl
+-12 -24 Dl
+812 MX
+-12 25 Dl
+24 0 Dl
+-12 -25 Dl
+739 4947 MXY
+-12 24 Dl
+24 0 Dl
+-12 -24 Dl
+702 4946 MXY
+-12 24 Dl
+25 0 Dl
+-13 -24 Dl
+684 4936 MXY
+-12 24 Dl
+24 0 Dl
+-12 -24 Dl
+675 4843 MXY
+-12 24 Dl
+24 0 Dl
+-12 -24 Dl
+3 Dt
+-1 Ds
+3 f
+432 5314(Figure)N
+634(5b:)X
+1 f
+744(Elapsed)X
+967(Time)X
+1123(for)X
+1218(dictionary)X
+1498(data)X
+1625(set)X
+1717(with)X
+1851(1M)X
+1960(of)X
+2033(buffer)X
+432 5402(space)N
+593(and)X
+705(varying)X
+920(bucket)X
+1110(sizes)X
+1254(and)X
+1366(\256ll)X
+1457(factors.)X
+1681(Each)X
+1827(line)X
+1942(is)X
+2004(labeled)X
+432 5490(with)N
+562(its)X
+639(bucket)X
+825(size.)X
+10 s
+2590 538(If)N
+2677(an)X
+2785(approximation)X
+3284(of)X
+3383(the)X
+3513(number)X
+3790(of)X
+3889(elements)X
+2418 626(ultimately)N
+2773(to)X
+2866(be)X
+2973(stored)X
+3200(in)X
+3293(the)X
+3422(hash)X
+3599(table)X
+3785(is)X
+3868(known)X
+4116(at)X
+2418 714(the)N
+2564(time)X
+2754(of)X
+2869(creation,)X
+3196(the)X
+3342(hash)X
+3536(package)X
+3847(takes)X
+4059(this)X
+2418 802(number)N
+2688(as)X
+2779(a)X
+2839(parameter)X
+3185(and)X
+3325(uses)X
+3487(it)X
+3555(to)X
+3641(hash)X
+3812(entries)X
+4050(into)X
+2418 890(the)N
+2541(full)X
+2677(sized)X
+2867(table)X
+3048(rather)X
+3261(than)X
+3424(growing)X
+3716(the)X
+3838(table)X
+4018(from)X
+2418 978(a)N
+2477(single)X
+2691(bucket.)X
+2968(If)X
+3044(this)X
+3181(number)X
+3448(is)X
+3523(not)X
+3647(known,)X
+3907(the)X
+4027(hash)X
+2418 1066(table)N
+2632(starts)X
+2859(with)X
+3059(a)X
+3153(single)X
+3402(bucket)X
+3674(and)X
+3848(gracefully)X
+2418 1154(expands)N
+2707(as)X
+2800(elements)X
+3111(are)X
+3236(added,)X
+3474(although)X
+3780(a)X
+3842(slight)X
+4044(per-)X
+2418 1242(formance)N
+2747(degradation)X
+3151(may)X
+3313(be)X
+3413(noticed.)X
+3713(Figure)X
+3946(6)X
+4010(illus-)X
+2418 1330(trates)N
+2625(the)X
+2756(difference)X
+3116(in)X
+3211(performance)X
+3651(between)X
+3952(storing)X
+2418 1418(keys)N
+2588(in)X
+2673(a)X
+2732(\256le)X
+2857(when)X
+3054(the)X
+3174(ultimate)X
+3458(size)X
+3605(is)X
+3680(known)X
+3920(\(the)X
+4067(left)X
+2418 1506(bars)N
+2581(in)X
+2672(each)X
+2849(set\),)X
+3014(compared)X
+3360(to)X
+3450(building)X
+3744(the)X
+3870(\256le)X
+4000(when)X
+2418 1594(the)N
+2550(ultimate)X
+2846(size)X
+3005(is)X
+3091(unknown)X
+3422(\(the)X
+3580(right)X
+3764(bars)X
+3931(in)X
+4026(each)X
+2418 1682(set\).)N
+2609(Once)X
+2814(the)X
+2947(\256ll)X
+3069(factor)X
+3291(is)X
+3378(suf\256ciently)X
+3772(high)X
+3948(for)X
+4076(the)X
+2418 1770(page)N
+2596(size)X
+2747(\(8\),)X
+2887(growing)X
+3180(the)X
+3304(table)X
+3486(dynamically)X
+3908(does)X
+4081(lit-)X
+2418 1858(tle)N
+2518(to)X
+2600(degrade)X
+2875(performance.)X
+10 f
+2418 1946 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+9 s
+1 f
+2413 3238(s)N
+2409 3173(d)N
+2409 3108(n)N
+2409 3043(o)N
+2411 2979(c)N
+2411 2914(e)N
+2407 2849(S)N
+3143 4129(Fill)N
+3261(Factor)X
+2448 2152(15)N
+4 Ds
+1 Dt
+2557 2122 MXY
+1473 0 Dl
+-1 Ds
+5 Dt
+2557 MX
+-19 0 Dl
+2448 2747(10)N
+4 Ds
+1 Dt
+2557 2717 MXY
+1473 0 Dl
+-1 Ds
+5 Dt
+2557 MX
+-19 0 Dl
+2484 3343(5)N
+4 Ds
+1 Dt
+2557 3313 MXY
+1473 0 Dl
+-1 Ds
+5 Dt
+2557 MX
+-19 0 Dl
+2484 3938(0)N
+4 Ds
+1 Dt
+2557 3908 MXY
+1473 0 Dl
+-1 Ds
+5 Dt
+2557 MX
+-19 0 Dl
+3976 4015(128)N
+4 Ds
+1 Dt
+4030 3908 MXY
+0 -1786 Dl
+-1 Ds
+5 Dt
+3908 MY
+0 19 Dl
+3626 4015(96)N
+4 Ds
+1 Dt
+3662 3908 MXY
+0 -1786 Dl
+-1 Ds
+5 Dt
+3908 MY
+0 19 Dl
+3258 4015(64)N
+4 Ds
+1 Dt
+3294 3908 MXY
+0 -1786 Dl
+-1 Ds
+5 Dt
+3908 MY
+0 19 Dl
+2889 4015(32)N
+4 Ds
+1 Dt
+2925 3908 MXY
+0 -1786 Dl
+-1 Ds
+5 Dt
+3908 MY
+0 19 Dl
+2539 4015(0)N
+4 Ds
+1 Dt
+2557 3908 MXY
+0 -1786 Dl
+-1 Ds
+5 Dt
+3908 MY
+0 19 Dl
+3908 MY
+0 -1786 Dl
+3908 MY
+1473 0 Dl
+4053 2378(8192)N
+3 Dt
+2569 2277 MXY
+11 0 Dl
+23 48 Dl
+46 -167 Dl
+92 35 Dl
+184 12 Dl
+369 143 Dl
+736 0 Dl
+2334 MY
+0 28 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+3294 2334 MXY
+0 28 Dl
+0 -14 Dl
+13 0 Dl
+-27 0 Dl
+2925 2192 MXY
+0 27 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+2741 2180 MXY
+0 27 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+2649 2144 MXY
+0 28 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+2603 2311 MXY
+0 27 Dl
+0 -13 Dl
+14 0 Dl
+-28 0 Dl
+2580 2263 MXY
+0 28 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+2569 2263 MXY
+0 28 Dl
+0 -14 Dl
+13 0 Dl
+-27 0 Dl
+4053 2591(4096)N
+2569 2348 MXY
+11 -11 Dl
+23 -96 Dl
+46 71 Dl
+92 72 Dl
+184 226 Dl
+369 48 Dl
+736 -60 Dl
+2612 MY
+14 -28 Dl
+-28 0 Dl
+14 28 Dl
+3294 2672 MXY
+13 -28 Dl
+-27 0 Dl
+14 28 Dl
+2925 2624 MXY
+14 -28 Dl
+-28 0 Dl
+14 28 Dl
+2741 2398 MXY
+14 -28 Dl
+-28 0 Dl
+14 28 Dl
+2649 2326 MXY
+14 -27 Dl
+-28 0 Dl
+14 27 Dl
+2603 2255 MXY
+14 -28 Dl
+-28 0 Dl
+14 28 Dl
+2580 2350 MXY
+14 -27 Dl
+-28 0 Dl
+14 27 Dl
+2569 2362 MXY
+13 -28 Dl
+-27 0 Dl
+14 28 Dl
+4053 2681(1024)N
+16 Ds
+1 Dt
+2569 2300 MXY
+11 48 Dl
+23 96 Dl
+46 95 Dl
+92 274 Dl
+184 202 Dl
+369 -155 Dl
+736 -190 Dl
+-1 Ds
+3 Dt
+4044 2656 MXY
+-28 28 Dl
+14 -14 Dl
+-14 -14 Dl
+28 28 Dl
+3307 2846 MXY
+-27 28 Dl
+14 -14 Dl
+-14 -14 Dl
+27 28 Dl
+2939 3001 MXY
+-28 28 Dl
+14 -14 Dl
+-14 -14 Dl
+28 28 Dl
+2755 2799 MXY
+-28 28 Dl
+14 -14 Dl
+-14 -14 Dl
+28 28 Dl
+2663 2525 MXY
+-28 28 Dl
+14 -14 Dl
+-14 -14 Dl
+28 28 Dl
+2617 2430 MXY
+-28 28 Dl
+14 -14 Dl
+-14 -14 Dl
+28 28 Dl
+2594 2334 MXY
+-28 28 Dl
+14 -14 Dl
+-14 -14 Dl
+28 28 Dl
+2582 2287 MXY
+-27 27 Dl
+14 -14 Dl
+-14 -13 Dl
+27 27 Dl
+4053 2851(512)N
+5 Dt
+2569 2372 MXY
+11 -24 Dl
+23 405 Dl
+46 83 Dl
+92 227 Dl
+184 -72 Dl
+369 -119 Dl
+736 -107 Dl
+3 Dt
+2751 MY
+0 28 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+3294 2858 MXY
+0 28 Dl
+0 -14 Dl
+13 0 Dl
+-27 0 Dl
+2925 2977 MXY
+0 28 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+2741 3049 MXY
+0 27 Dl
+0 -13 Dl
+14 0 Dl
+-28 0 Dl
+2649 2823 MXY
+0 27 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+2603 2739 MXY
+0 28 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+2580 2334 MXY
+0 28 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+2569 2358 MXY
+0 28 Dl
+0 -14 Dl
+13 0 Dl
+-27 0 Dl
+4053 2795(256)N
+20 Ds
+1 Dt
+2569 2456 MXY
+11 285 Dl
+23 95 Dl
+46 251 Dl
+92 -60 Dl
+184 -84 Dl
+369 -107 Dl
+736 -71 Dl
+-1 Ds
+3 Dt
+4016 MX
+27 Dc
+3280 2836 MXY
+27 Dc
+2912 2943 MXY
+27 Dc
+2728 3027 MXY
+27 Dc
+2635 3087 MXY
+28 Dc
+2589 2836 MXY
+28 Dc
+2566 2741 MXY
+27 Dc
+2554 2456 MXY
+28 Dc
+4053 2741(128)N
+1 Dt
+2569 2729 MXY
+11 203 Dl
+23 131 Dl
+46 -60 Dl
+92 -119 Dl
+184 -60 Dl
+369 -83 Dl
+736 -12 Dl
+3 Dt
+2716 MY
+-14 27 Dl
+28 0 Dl
+-14 -27 Dl
+3294 2727 MXY
+-14 28 Dl
+27 0 Dl
+-13 -28 Dl
+2925 2811 MXY
+-14 27 Dl
+28 0 Dl
+-14 -27 Dl
+2741 2870 MXY
+-14 28 Dl
+28 0 Dl
+-14 -28 Dl
+2649 2989 MXY
+-14 28 Dl
+28 0 Dl
+-14 -28 Dl
+2603 3049 MXY
+-14 27 Dl
+28 0 Dl
+-14 -27 Dl
+2580 2918 MXY
+-14 28 Dl
+28 0 Dl
+-14 -28 Dl
+2569 2716 MXY
+-14 27 Dl
+27 0 Dl
+-13 -27 Dl
+3 Dt
+-1 Ds
+3 f
+8 s
+2418 4286(Figure)N
+2628(5c:)X
+1 f
+2738(User)X
+2887(Time)X
+3051(for)X
+3154(dictionary)X
+3442(data)X
+3577(set)X
+3677(with)X
+3820(1M)X
+3938(of)X
+4019(buffer)X
+2418 4374(space)N
+2579(and)X
+2691(varying)X
+2906(bucket)X
+3096(sizes)X
+3240(and)X
+3352(\256ll)X
+3443(factors.)X
+3667(Each)X
+3813(line)X
+3928(is)X
+3990(labeled)X
+2418 4462(with)N
+2548(its)X
+2625(bucket)X
+2811(size.)X
+10 s
+10 f
+2418 4638 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+1 f
+2590 4840(Since)N
+2796(no)X
+2904(known)X
+3150(hash)X
+3325(function)X
+3620(performs)X
+3938(equally)X
+2418 4928(well)N
+2589(on)X
+2702(all)X
+2815(possible)X
+3110(data,)X
+3297(the)X
+3428(user)X
+3595(may)X
+3766(\256nd)X
+3923(that)X
+4076(the)X
+2418 5016(built-in)N
+2678(hash)X
+2849(function)X
+3140(does)X
+3311(poorly)X
+3544(on)X
+3648(a)X
+3708(particular)X
+4040(data)X
+2418 5104(set.)N
+2548(In)X
+2636(this)X
+2771(case,)X
+2950(a)X
+3006(hash)X
+3173(function,)X
+3480(taking)X
+3700(two)X
+3840(arguments)X
+2418 5192(\(a)N
+2507(pointer)X
+2760(to)X
+2848(a)X
+2910(byte)X
+3074(string)X
+3282(and)X
+3424(a)X
+3486(length\))X
+3739(and)X
+3880(returning)X
+2418 5280(an)N
+2517(unsigned)X
+2829(long)X
+2993(to)X
+3077(be)X
+3175(used)X
+3344(as)X
+3433(the)X
+3553(hash)X
+3722(value,)X
+3938(may)X
+4098(be)X
+2418 5368(speci\256ed)N
+2731(at)X
+2817(hash)X
+2992(table)X
+3176(creation)X
+3463(time.)X
+3673(When)X
+3893(an)X
+3996(exist-)X
+2418 5456(ing)N
+2570(hash)X
+2767(table)X
+2973(is)X
+3076(opened)X
+3358(and)X
+3524(a)X
+3609(hash)X
+3805(function)X
+4121(is)X
+2418 5544(speci\256ed,)N
+2752(the)X
+2879(hash)X
+3054(package)X
+3346(will)X
+3498(try)X
+3615(to)X
+3705(determine)X
+4054(that)X
+2418 5632(the)N
+2546(hash)X
+2723(function)X
+3020(supplied)X
+3321(is)X
+3404(the)X
+3532(one)X
+3678(with)X
+3850(which)X
+4076(the)X
+2418 5720(table)N
+2630(was)X
+2811(created.)X
+3139(There)X
+3382(are)X
+3536(a)X
+3627(variety)X
+3905(of)X
+4027(hash)X
+3 f
+432 5960(8)N
+2970(USENIX)X
+9 f
+3292(-)X
+3 f
+3356(Winter)X
+3621('91)X
+9 f
+3748(-)X
+3 f
+3812(Dallas,)X
+4065(TX)X
+
+9 p
+%%Page: 9 9
+0(Courier)xf 0 f
+10 s 10 xH 0 xS 0 f
+3 f
+720 258(Seltzer)N
+977(&)X
+1064(Yigit)X
+3278(A)X
+3356(New)X
+3528(Hashing)X
+3831(Package)X
+4136(for)X
+4259(UNIX)X
+1 f
+720 538(functions)N
+1065(provided)X
+1397(with)X
+1586(the)X
+1731(package.)X
+2082(The)X
+2253(default)X
+720 626(function)N
+1014(for)X
+1135(the)X
+1260(package)X
+1551(is)X
+1631(the)X
+1755(one)X
+1897(which)X
+2119(offered)X
+2378(the)X
+720 714(best)N
+875(performance)X
+1308(in)X
+1396(terms)X
+1600(of)X
+1693(cycles)X
+1920(executed)X
+2232(per)X
+2360(call)X
+720 802(\(it)N
+827(did)X
+965(not)X
+1103(produce)X
+1398(the)X
+1531(fewest)X
+1776(collisions)X
+2117(although)X
+2432(it)X
+720 890(was)N
+866(within)X
+1091(a)X
+1148(small)X
+1341(percentage)X
+1710(of)X
+1797(the)X
+1915(function)X
+2202(that)X
+2342(pro-)X
+720 978(duced)N
+947(the)X
+1080(fewest)X
+1324(collisions\).)X
+1731(Again,)X
+1981(in)X
+2077(time)X
+2253(critical)X
+720 1066(applications,)N
+1152(users)X
+1342(are)X
+1466(encouraged)X
+1862(to)X
+1949(experiment)X
+2334(with)X
+720 1154(a)N
+783(variety)X
+1032(of)X
+1125(hash)X
+1298(functions)X
+1622(to)X
+1710(achieve)X
+1982(optimal)X
+2252(perfor-)X
+720 1242(mance.)N
+10 f
+720 1330 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+3 f
+7 s
+1038 2925(Full)N
+1149(size)X
+1251(table)X
+1384(\(left\))X
+1547 2718(Fill)N
+1643(Factor)X
+2268 2662(64)N
+1964(32)X
+1674(16)X
+1384(8)X
+1093(4)X
+4 Ds
+1 Dt
+900 2280 MXY
+1548 0 Dl
+900 1879 MXY
+1548 0 Dl
+900 1506 MXY
+1548 0 Dl
+1563 2902 MXY
+111 0 Dl
+-1 Ds
+900 MX
+110 0 Dl
+1425 2828(System)N
+983(User)X
+1895 2778 MXY
+ 1895 2778 lineto
+ 1950 2778 lineto
+ 1950 2833 lineto
+ 1895 2833 lineto
+ 1895 2778 lineto
+closepath 21 1895 2778 1950 2833 Dp
+1342 MX
+ 1342 2778 lineto
+ 1397 2778 lineto
+ 1397 2833 lineto
+ 1342 2833 lineto
+ 1342 2778 lineto
+closepath 14 1342 2778 1397 2833 Dp
+900 MX
+ 900 2778 lineto
+ 955 2778 lineto
+ 955 2833 lineto
+ 900 2833 lineto
+ 900 2778 lineto
+closepath 3 900 2778 955 2833 Dp
+5 Dt
+2283 2211 MXY
+96 0 Dl
+1992 MX
+97 0 Dl
+1702 MX
+97 0 Dl
+1411 2252 MXY
+97 0 Dl
+4 Ds
+1 Dt
+2283 2211 MXY
+ 2283 2211 lineto
+ 2379 2211 lineto
+ 2379 2252 lineto
+ 2283 2252 lineto
+ 2283 2211 lineto
+closepath 14 2283 2211 2379 2252 Dp
+1992 MX
+ 1992 2211 lineto
+ 2089 2211 lineto
+ 2089 2252 lineto
+ 1992 2252 lineto
+ 1992 2211 lineto
+closepath 14 1992 2211 2089 2252 Dp
+1702 MX
+ 1702 2211 lineto
+ 1799 2211 lineto
+ 1799 2252 lineto
+ 1702 2252 lineto
+ 1702 2211 lineto
+closepath 14 1702 2211 1799 2252 Dp
+1411 2252 MXY
+ 1411 2252 lineto
+ 1508 2252 lineto
+ 1508 2294 lineto
+ 1411 2294 lineto
+ 1411 2252 lineto
+closepath 14 1411 2252 1508 2294 Dp
+2283 MX
+ 2283 2252 lineto
+ 2379 2252 lineto
+ 2379 2612 lineto
+ 2283 2612 lineto
+ 2283 2252 lineto
+closepath 3 2283 2252 2379 2612 Dp
+1992 MX
+ 1992 2252 lineto
+ 2089 2252 lineto
+ 2089 2612 lineto
+ 1992 2612 lineto
+ 1992 2252 lineto
+closepath 3 1992 2252 2089 2612 Dp
+1702 MX
+ 1702 2252 lineto
+ 1799 2252 lineto
+ 1799 2612 lineto
+ 1702 2612 lineto
+ 1702 2252 lineto
+closepath 3 1702 2252 1799 2612 Dp
+1411 2294 MXY
+ 1411 2294 lineto
+ 1508 2294 lineto
+ 1508 2612 lineto
+ 1411 2612 lineto
+ 1411 2294 lineto
+closepath 3 1411 2294 1508 2612 Dp
+-1 Ds
+2158 2238 MXY
+ 2158 2238 lineto
+ 2255 2238 lineto
+ 2255 2252 lineto
+ 2158 2252 lineto
+ 2158 2238 lineto
+closepath 21 2158 2238 2255 2252 Dp
+1868 MX
+ 1868 2238 lineto
+ 1965 2238 lineto
+ 1965 2280 lineto
+ 1868 2280 lineto
+ 1868 2238 lineto
+closepath 21 1868 2238 1965 2280 Dp
+1577 MX
+ 1577 2238 lineto
+ 1674 2238 lineto
+ 1674 2308 lineto
+ 1577 2308 lineto
+ 1577 2238 lineto
+closepath 21 1577 2238 1674 2308 Dp
+1287 2308 MXY
+ 1287 2308 lineto
+ 1287 2280 lineto
+ 1384 2280 lineto
+ 1384 2308 lineto
+ 1287 2308 lineto
+closepath 21 1287 2280 1384 2308 Dp
+2158 2280 MXY
+ 2158 2280 lineto
+ 2158 2252 lineto
+ 2255 2252 lineto
+ 2255 2280 lineto
+ 2158 2280 lineto
+closepath 14 2158 2252 2255 2280 Dp
+1868 2308 MXY
+ 1868 2308 lineto
+ 1868 2280 lineto
+ 1965 2280 lineto
+ 1965 2308 lineto
+ 1868 2308 lineto
+closepath 14 1868 2280 1965 2308 Dp
+1577 2335 MXY
+ 1577 2335 lineto
+ 1577 2308 lineto
+ 1674 2308 lineto
+ 1674 2335 lineto
+ 1577 2335 lineto
+closepath 14 1577 2308 1674 2335 Dp
+1287 2363 MXY
+ 1287 2363 lineto
+ 1287 2308 lineto
+ 1384 2308 lineto
+ 1384 2363 lineto
+ 1287 2363 lineto
+closepath 14 1287 2308 1384 2363 Dp
+2158 2280 MXY
+ 2158 2280 lineto
+ 2255 2280 lineto
+ 2255 2612 lineto
+ 2158 2612 lineto
+ 2158 2280 lineto
+closepath 3 2158 2280 2255 2612 Dp
+1868 2308 MXY
+ 1868 2308 lineto
+ 1965 2308 lineto
+ 1965 2612 lineto
+ 1868 2612 lineto
+ 1868 2308 lineto
+closepath 3 1868 2308 1965 2612 Dp
+1577 2335 MXY
+ 1577 2335 lineto
+ 1674 2335 lineto
+ 1674 2612 lineto
+ 1577 2612 lineto
+ 1577 2335 lineto
+closepath 3 1577 2335 1674 2612 Dp
+1287 2363 MXY
+ 1287 2363 lineto
+ 1384 2363 lineto
+ 1384 2612 lineto
+ 1287 2612 lineto
+ 1287 2363 lineto
+closepath 3 1287 2363 1384 2612 Dp
+4 Ds
+1121 2066 MXY
+ 1121 2066 lineto
+ 1218 2066 lineto
+ 1224 2080 lineto
+ 1127 2080 lineto
+ 1121 2066 lineto
+closepath 21 1121 2066 1224 2080 Dp
+2080 MY
+ 1121 2080 lineto
+ 1218 2080 lineto
+ 1218 2273 lineto
+ 1121 2273 lineto
+ 1121 2080 lineto
+closepath 14 1121 2080 1218 2273 Dp
+2273 MY
+ 1121 2273 lineto
+ 1218 2273 lineto
+ 1218 2612 lineto
+ 1121 2612 lineto
+ 1121 2273 lineto
+closepath 3 1121 2273 1218 2612 Dp
+-1 Ds
+997 1589 MXY
+ 997 1589 lineto
+ 1093 1589 lineto
+ 1093 1644 lineto
+ 997 1644 lineto
+ 997 1589 lineto
+closepath 21 997 1589 1093 1644 Dp
+1644 MY
+ 997 1644 lineto
+ 1093 1644 lineto
+ 1093 2280 lineto
+ 997 2280 lineto
+ 997 1644 lineto
+closepath 14 997 1644 1093 2280 Dp
+2280 MY
+ 997 2280 lineto
+ 1093 2280 lineto
+ 1093 2612 lineto
+ 997 2612 lineto
+ 997 2280 lineto
+closepath 3 997 2280 1093 2612 Dp
+10 s
+719 2093(s)N
+712 2037(d)N
+712 1982(n)N
+714 1927(o)N
+716 1872(c)N
+716 1816(e)N
+712 1761(S)N
+804 2286(10)N
+804 1899(20)N
+804 1540(30)N
+3 Dt
+900 1506 MXY
+0 1106 Dl
+1548 0 Dl
+7 s
+1978 2828(Elapsed)N
+1701 2925(Dynamically)N
+2018(grown)X
+2184(table)X
+2317(\(right\))X
+3 Dt
+-1 Ds
+8 s
+720 3180(Figure)N
+934(6:)X
+1 f
+1020(The)X
+1152(total)X
+1299(regions)X
+1520(indicate)X
+1755(the)X
+1865(difference)X
+2154(between)X
+2398(the)X
+720 3268(elapsed)N
+931(time)X
+1065(and)X
+1177(the)X
+1275(sum)X
+1402(of)X
+1475(the)X
+1573(system)X
+1771(and)X
+1883(user)X
+2008(time.)X
+2173(The)X
+2291(left)X
+2395(bar)X
+720 3356(of)N
+798(each)X
+939(set)X
+1035(depicts)X
+1241(the)X
+1344(timing)X
+1537(of)X
+1615(the)X
+1718(test)X
+1831(run)X
+1940(when)X
+2102(the)X
+2204(number)X
+2423(of)X
+720 3444(entries)N
+910(is)X
+973(known)X
+1167(in)X
+1237(advance.)X
+1496(The)X
+1614(right)X
+1754(bars)X
+1879(depict)X
+2054(the)X
+2151(timing)X
+2338(when)X
+720 3532(the)N
+814(\256le)X
+912(is)X
+971(grown)X
+1150(from)X
+1290(a)X
+1334(single)X
+1503(bucket.)X
+10 s
+10 f
+720 3708 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+1 f
+892 3910(Since)N
+1131(this)X
+1307(hashing)X
+1617(package)X
+1942(provides)X
+2279(buffer)X
+720 3998(management,)N
+1188(the)X
+1323(amount)X
+1600(of)X
+1704(space)X
+1920(allocated)X
+2247(for)X
+2378(the)X
+720 4086(buffer)N
+948(pool)X
+1121(may)X
+1290(be)X
+1397(speci\256ed)X
+1713(by)X
+1824(the)X
+1953(user.)X
+2157(Using)X
+2378(the)X
+720 4174(same)N
+910(data)X
+1069(set)X
+1183(and)X
+1324(test)X
+1459(procedure)X
+1805(as)X
+1896(used)X
+2067(to)X
+2153(derive)X
+2378(the)X
+720 4262(graphs)N
+962(in)X
+1052(Figures)X
+1320(5a-c,)X
+1507(Figure)X
+1744(7)X
+1812(shows)X
+2039(the)X
+2164(impact)X
+2409(of)X
+720 4350(varying)N
+997(the)X
+1126(size)X
+1282(of)X
+1380(the)X
+1509(buffer)X
+1737(pool.)X
+1950(The)X
+2106(bucket)X
+2351(size)X
+720 4438(was)N
+873(set)X
+989(to)X
+1078(256)X
+1225(bytes)X
+1421(and)X
+1564(the)X
+1689(\256ll)X
+1804(factor)X
+2019(was)X
+2171(set)X
+2287(to)X
+2376(16.)X
+720 4526(The)N
+869(buffer)X
+1090(pool)X
+1256(size)X
+1404(was)X
+1552(varied)X
+1776(from)X
+1955(0)X
+2018(\(the)X
+2166(minimum)X
+720 4614(number)N
+986(of)X
+1074(pages)X
+1277(required)X
+1565(to)X
+1647(be)X
+1743(buffered\))X
+2063(to)X
+2145(1M.)X
+2316(With)X
+720 4702(1M)N
+854(of)X
+944(buffer)X
+1164(space,)X
+1386(the)X
+1507(package)X
+1794(performed)X
+2151(no)X
+2253(I/O)X
+2382(for)X
+720 4790(this)N
+871(data)X
+1040(set.)X
+1204(As)X
+1328(Figure)X
+1572(7)X
+1647(illustrates,)X
+2013(increasing)X
+2378(the)X
+720 4878(buffer)N
+944(pool)X
+1113(size)X
+1265(can)X
+1404(have)X
+1583(a)X
+1646(dramatic)X
+1954(affect)X
+2165(on)X
+2271(result-)X
+720 4966(ing)N
+842(performance.)X
+2 f
+8 s
+1269 4941(7)N
+1 f
+16 s
+720 5353 MXY
+864 0 Dl
+2 f
+8 s
+760 5408(7)N
+1 f
+9 s
+826 5433(Some)N
+1024(allocators)X
+1338(are)X
+1460(extremely)X
+1782(inef\256cient)X
+2107(at)X
+2192(allocating)X
+720 5513(memory.)N
+1029(If)X
+1110(you)X
+1251(\256nd)X
+1396(that)X
+1536(applications)X
+1916(are)X
+2036(running)X
+2292(out)X
+2416(of)X
+720 5593(memory)N
+1005(before)X
+1234(you)X
+1386(think)X
+1578(they)X
+1746(should,)X
+2000(try)X
+2124(varying)X
+2388(the)X
+720 5673(pagesize)N
+986(to)X
+1060(get)X
+1166(better)X
+1348(utilization)X
+1658(from)X
+1816(the)X
+1922(memory)X
+2180(allocator.)X
+10 s
+2830 1975 MXY
+0 -28 Dl
+28 0 Dl
+0 28 Dl
+-28 0 Dl
+2853 2004 MXY
+0 -27 Dl
+28 0 Dl
+0 27 Dl
+-28 0 Dl
+2876 2016 MXY
+0 -27 Dl
+27 0 Dl
+0 27 Dl
+-27 0 Dl
+2922 1998 MXY
+0 -27 Dl
+27 0 Dl
+0 27 Dl
+-27 0 Dl
+2967 2025 MXY
+0 -28 Dl
+28 0 Dl
+0 28 Dl
+-28 0 Dl
+3013 2031 MXY
+0 -28 Dl
+28 0 Dl
+0 28 Dl
+-28 0 Dl
+3059 MX
+0 -28 Dl
+27 0 Dl
+0 28 Dl
+-27 0 Dl
+3196 2052 MXY
+0 -28 Dl
+27 0 Dl
+0 28 Dl
+-27 0 Dl
+3561 2102 MXY
+0 -28 Dl
+28 0 Dl
+0 28 Dl
+-28 0 Dl
+4292 2105 MXY
+0 -28 Dl
+27 0 Dl
+0 28 Dl
+-27 0 Dl
+4 Ds
+1 Dt
+2844 1961 MXY
+23 30 Dl
+23 12 Dl
+45 -18 Dl
+46 26 Dl
+46 6 Dl
+45 0 Dl
+137 21 Dl
+366 50 Dl
+730 3 Dl
+9 s
+4227 2158(User)N
+-1 Ds
+3 Dt
+2830 1211 MXY
+27 Dc
+2853 1261 MXY
+27 Dc
+2876 1267 MXY
+27 Dc
+2921 1341 MXY
+27 Dc
+2967 1385 MXY
+27 Dc
+3013 1450 MXY
+27 Dc
+3059 1497 MXY
+27 Dc
+3196 1686 MXY
+27 Dc
+3561 2109 MXY
+27 Dc
+4292 2295 MXY
+27 Dc
+20 Ds
+1 Dt
+2844 1211 MXY
+23 50 Dl
+23 6 Dl
+45 74 Dl
+46 44 Dl
+46 65 Dl
+45 47 Dl
+137 189 Dl
+366 423 Dl
+730 186 Dl
+4181 2270(System)N
+-1 Ds
+3 Dt
+2844 583 MXY
+0 28 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+2867 672 MXY
+0 27 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+2890 701 MXY
+0 28 Dl
+0 -14 Dl
+13 0 Dl
+-27 0 Dl
+2935 819 MXY
+0 28 Dl
+0 -14 Dl
+14 0 Dl
+-27 0 Dl
+2981 849 MXY
+0 28 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+3027 908 MXY
+0 27 Dl
+0 -13 Dl
+14 0 Dl
+-28 0 Dl
+3072 1026 MXY
+0 27 Dl
+0 -13 Dl
+14 0 Dl
+-27 0 Dl
+3209 1292 MXY
+0 27 Dl
+0 -14 Dl
+14 0 Dl
+-27 0 Dl
+3575 1823 MXY
+0 28 Dl
+0 -14 Dl
+14 0 Dl
+-28 0 Dl
+4305 2059 MXY
+0 28 Dl
+0 -14 Dl
+14 0 Dl
+-27 0 Dl
+5 Dt
+2844 597 MXY
+23 88 Dl
+23 30 Dl
+45 118 Dl
+46 30 Dl
+46 59 Dl
+45 118 Dl
+137 265 Dl
+366 532 Dl
+730 236 Dl
+4328 2103(Total)N
+2844 2310 MXY
+1461 0 Dl
+2844 MX
+0 -1772 Dl
+2310 MY
+0 18 Dl
+4 Ds
+1 Dt
+2310 MY
+0 -1772 Dl
+2826 2416(0)N
+-1 Ds
+5 Dt
+3209 2310 MXY
+0 18 Dl
+4 Ds
+1 Dt
+2310 MY
+0 -1772 Dl
+3155 2416(256)N
+-1 Ds
+5 Dt
+3575 2310 MXY
+0 18 Dl
+4 Ds
+1 Dt
+2310 MY
+0 -1772 Dl
+3521 2416(512)N
+-1 Ds
+5 Dt
+3940 2310 MXY
+0 18 Dl
+4 Ds
+1 Dt
+2310 MY
+0 -1772 Dl
+3886 2416(768)N
+-1 Ds
+5 Dt
+4305 2310 MXY
+0 18 Dl
+4 Ds
+1 Dt
+2310 MY
+0 -1772 Dl
+4233 2416(1024)N
+-1 Ds
+5 Dt
+2844 2310 MXY
+-18 0 Dl
+4 Ds
+1 Dt
+2844 MX
+1461 0 Dl
+2771 2340(0)N
+-1 Ds
+5 Dt
+2844 2014 MXY
+-18 0 Dl
+2844 1719 MXY
+-18 0 Dl
+4 Ds
+1 Dt
+2844 MX
+1461 0 Dl
+2735 1749(20)N
+-1 Ds
+5 Dt
+2844 1423 MXY
+-18 0 Dl
+2844 1128 MXY
+-18 0 Dl
+4 Ds
+1 Dt
+2844 MX
+1461 0 Dl
+2735 1158(40)N
+-1 Ds
+5 Dt
+2844 833 MXY
+-18 0 Dl
+2844 538 MXY
+-18 0 Dl
+4 Ds
+1 Dt
+2844 MX
+1461 0 Dl
+2735 568(60)N
+3239 2529(Buffer)N
+3445(Pool)X
+3595(Size)X
+3737(\(in)X
+3835(K\))X
+2695 1259(S)N
+2699 1324(e)N
+2699 1388(c)N
+2697 1452(o)N
+2697 1517(n)N
+2697 1581(d)N
+2701 1645(s)N
+3 Dt
+-1 Ds
+3 f
+8 s
+2706 2773(Figure)N
+2908(7:)X
+1 f
+2982(User)X
+3123(time)X
+3258(is)X
+3322(virtually)X
+3560(insensitive)X
+3854(to)X
+3924(the)X
+4022(amount)X
+4234(of)X
+4307(buffer)X
+2706 2861(pool)N
+2852(available,)X
+3130(however,)X
+3396(both)X
+3541(system)X
+3750(time)X
+3895(and)X
+4018(elapsed)X
+4240(time)X
+4385(are)X
+2706 2949(inversely)N
+2960(proportional)X
+3296(to)X
+3366(the)X
+3464(size)X
+3583(of)X
+3656(the)X
+3753(buffer)X
+3927(pool.)X
+4092(Even)X
+4242(for)X
+4335(large)X
+2706 3037(data)N
+2831(sets)X
+2946(where)X
+3120(one)X
+3230(expects)X
+3439(few)X
+3552(collisions,)X
+3832(specifying)X
+4116(a)X
+4162(large)X
+4307(buffer)X
+2706 3125(pool)N
+2836(dramatically)X
+3171(improves)X
+3425(performance.)X
+10 s
+10 f
+2706 3301 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+3 f
+3175 3543(Enhanced)N
+3536(Functionality)X
+1 f
+2878 3675(This)N
+3046(hashing)X
+3320(package)X
+3609(provides)X
+3910(a)X
+3971(set)X
+4085(of)X
+4177(compati-)X
+2706 3763(bility)N
+2895(routines)X
+3174(to)X
+3257(implement)X
+3620(the)X
+2 f
+3739(ndbm)X
+1 f
+3937(interface.)X
+4279(How-)X
+2706 3851(ever,)N
+2893(when)X
+3095(the)X
+3220(native)X
+3443(interface)X
+3752(is)X
+3832(used,)X
+4026(the)X
+4151(following)X
+2706 3939(additional)N
+3046(functionality)X
+3475(is)X
+3548(provided:)X
+10 f
+2798 4071(g)N
+1 f
+2946(Inserts)X
+3197(never)X
+3413(fail)X
+3556(because)X
+3847(too)X
+3985(many)X
+4199(keys)X
+2946 4159(hash)N
+3113(to)X
+3195(the)X
+3313(same)X
+3498(value.)X
+10 f
+2798 4247(g)N
+1 f
+2946(Inserts)X
+3187(never)X
+3393(fail)X
+3527(because)X
+3808(key)X
+3950(and/or)X
+4181(asso-)X
+2946 4335(ciated)N
+3158(data)X
+3312(is)X
+3385(too)X
+3507(large)X
+10 f
+2798 4423(g)N
+1 f
+2946(Hash)X
+3131(functions)X
+3449(may)X
+3607(be)X
+3703(user-speci\256ed.)X
+10 f
+2798 4511(g)N
+1 f
+2946(Multiple)X
+3268(pages)X
+3498(may)X
+3683(be)X
+3806(cached)X
+4077(in)X
+4186(main)X
+2946 4599(memory.)N
+2706 4731(It)N
+2801(also)X
+2976(provides)X
+3298(a)X
+3380(set)X
+3514(of)X
+3626(compatibility)X
+4097(routines)X
+4400(to)X
+2706 4819(implement)N
+3087(the)X
+2 f
+3224(hsearch)X
+1 f
+3516(interface.)X
+3876(Again,)X
+4130(the)X
+4266(native)X
+2706 4907(interface)N
+3008(offers)X
+3216(enhanced)X
+3540(functionality:)X
+10 f
+2798 5039(g)N
+1 f
+2946(Files)X
+3121(may)X
+3279(grow)X
+3464(beyond)X
+2 f
+3720(nelem)X
+1 f
+3932(elements.)X
+10 f
+2798 5127(g)N
+1 f
+2946(Multiple)X
+3247(hash)X
+3420(tables)X
+3632(may)X
+3795(be)X
+3896(accessed)X
+4203(con-)X
+2946 5215(currently.)N
+10 f
+2798 5303(g)N
+1 f
+2946(Hash)X
+3134(tables)X
+3344(may)X
+3505(be)X
+3604(stored)X
+3823(and)X
+3962(accessed)X
+4266(on)X
+2946 5391(disk.)N
+10 f
+2798 5479(g)N
+1 f
+2946(Hash)X
+3155(functions)X
+3497(may)X
+3679(be)X
+3799(user-speci\256ed)X
+4288(at)X
+2946 5567(runtime.)N
+3 f
+720 5960(USENIX)N
+9 f
+1042(-)X
+3 f
+1106(Winter)X
+1371('91)X
+9 f
+1498(-)X
+3 f
+1562(Dallas,)X
+1815(TX)X
+4424(9)X
+
+10 p
+%%Page: 10 10
+0(Courier)xf 0 f
+10 s 10 xH 0 xS 0 f
+3 f
+432 258(A)N
+510(New)X
+682(Hashing)X
+985(Package)X
+1290(for)X
+1413(UNIX)X
+3663(Seltzer)X
+3920(&)X
+4007(Yigit)X
+459 538(Relative)N
+760(Performance)X
+1227(of)X
+1314(the)X
+1441(New)X
+1613(Implementation)X
+1 f
+604 670(The)N
+761(performance)X
+1200(testing)X
+1445(of)X
+1544(the)X
+1674(new)X
+1840(package)X
+2135(is)X
+432 758(divided)N
+711(into)X
+874(two)X
+1033(test)X
+1183(suites.)X
+1424(The)X
+1588(\256rst)X
+1751(suite)X
+1941(of)X
+2046(tests)X
+432 846(requires)N
+727(that)X
+882(the)X
+1015(tables)X
+1237(be)X
+1348(read)X
+1522(from)X
+1713(and)X
+1864(written)X
+2126(to)X
+432 934(disk.)N
+640(In)X
+742(these)X
+942(tests,)X
+1139(the)X
+1272(basis)X
+1467(for)X
+1595(comparison)X
+2003(is)X
+2090(the)X
+432 1022(4.3BSD-Reno)N
+908(version)X
+1169(of)X
+2 f
+1260(ndbm)X
+1 f
+1438(.)X
+1502(Based)X
+1722(on)X
+1826(the)X
+1948(designs)X
+432 1110(of)N
+2 f
+521(sdbm)X
+1 f
+712(and)X
+2 f
+850(gdbm)X
+1 f
+1028(,)X
+1070(they)X
+1230(are)X
+1351(expected)X
+1659(to)X
+1743(perform)X
+2024(simi-)X
+432 1198(larly)N
+605(to)X
+2 f
+693(ndbm)X
+1 f
+871(,)X
+917(and)X
+1059(we)X
+1179(do)X
+1285(not)X
+1413(show)X
+1608(their)X
+1781(performance)X
+432 1286(numbers.)N
+800(The)X
+977(second)X
+1252(suite)X
+1454(contains)X
+1772(the)X
+1921(memory)X
+432 1374(resident)N
+712(test)X
+849(which)X
+1071(does)X
+1243(not)X
+1370(require)X
+1623(that)X
+1768(the)X
+1891(\256les)X
+2049(ever)X
+432 1462(be)N
+533(written)X
+784(to)X
+870(disk,)X
+1047(only)X
+1213(that)X
+1357(hash)X
+1528(tables)X
+1739(may)X
+1901(be)X
+2001(mani-)X
+432 1550(pulated)N
+692(in)X
+778(main)X
+961(memory.)X
+1291(In)X
+1381(this)X
+1519(test,)X
+1673(we)X
+1790(compare)X
+2090(the)X
+432 1638(performance)N
+859(to)X
+941(that)X
+1081(of)X
+1168(the)X
+2 f
+1286(hsearch)X
+1 f
+1560(routines.)X
+604 1752(For)N
+760(both)X
+947(suites,)X
+1194(two)X
+1358(different)X
+1679(databases)X
+2031(were)X
+432 1840(used.)N
+656(The)X
+818(\256rst)X
+979(is)X
+1069(the)X
+1204(dictionary)X
+1566(database)X
+1880(described)X
+432 1928(previously.)N
+836(The)X
+987(second)X
+1236(was)X
+1386(constructed)X
+1781(from)X
+1962(a)X
+2023(pass-)X
+432 2016(word)N
+647(\256le)X
+799(with)X
+990(approximately)X
+1502(300)X
+1671(accounts.)X
+2041(Two)X
+432 2104(records)N
+700(were)X
+887(constructed)X
+1287(for)X
+1411(each)X
+1589(account.)X
+1909(The)X
+2064(\256rst)X
+432 2192(used)N
+604(the)X
+727(logname)X
+1028(as)X
+1120(the)X
+1243(key)X
+1384(and)X
+1525(the)X
+1648(remainder)X
+1999(of)X
+2090(the)X
+432 2280(password)N
+768(entry)X
+965(for)X
+1091(the)X
+1221(data.)X
+1427(The)X
+1584(second)X
+1839(was)X
+1996(keyed)X
+432 2368(by)N
+541(uid)X
+672(and)X
+817(contained)X
+1157(the)X
+1283(entire)X
+1494(password)X
+1825(entry)X
+2018(as)X
+2113(its)X
+432 2456(data)N
+589(\256eld.)X
+794(The)X
+942(tests)X
+1107(were)X
+1287(all)X
+1389(run)X
+1518(on)X
+1620(the)X
+1740(HP)X
+1864(9000)X
+2046(with)X
+432 2544(the)N
+574(same)X
+783(con\256guration)X
+1254(previously)X
+1636(described.)X
+2027(Each)X
+432 2632(test)N
+576(was)X
+734(run)X
+874(\256ve)X
+1027(times)X
+1232(and)X
+1380(the)X
+1510(timing)X
+1750(results)X
+1991(of)X
+2090(the)X
+432 2720(runs)N
+602(were)X
+791(averaged.)X
+1154(The)X
+1311(variance)X
+1616(across)X
+1849(the)X
+1979(5)X
+2050(runs)X
+432 2808(was)N
+591(approximately)X
+1088(1%)X
+1229(of)X
+1330(the)X
+1462(average)X
+1746(yielding)X
+2041(95%)X
+432 2896(con\256dence)N
+800(intervals)X
+1096(of)X
+1183(approximately)X
+1666(2%.)X
+3 f
+1021 3050(Disk)N
+1196(Based)X
+1420(Tests)X
+1 f
+604 3182(In)N
+693(these)X
+880(tests,)X
+1064(we)X
+1180(use)X
+1308(a)X
+1365(bucket)X
+1600(size)X
+1746(of)X
+1834(1024)X
+2015(and)X
+2152(a)X
+432 3270(\256ll)N
+540(factor)X
+748(of)X
+835(32.)X
+3 f
+432 3384(create)N
+663(test)X
+1 f
+547 3498(The)N
+703(keys)X
+881(are)X
+1011(entered)X
+1279(into)X
+1433(the)X
+1561(hash)X
+1738(table,)X
+1944(and)X
+2090(the)X
+547 3586(\256le)N
+669(is)X
+742(\257ushed)X
+993(to)X
+1075(disk.)X
+3 f
+432 3700(read)N
+608(test)X
+1 f
+547 3814(A)N
+640(lookup)X
+897(is)X
+984(performed)X
+1353(for)X
+1481(each)X
+1663(key)X
+1813(in)X
+1909(the)X
+2041(hash)X
+547 3902(table.)N
+3 f
+432 4016(verify)N
+653(test)X
+1 f
+547 4130(A)N
+640(lookup)X
+897(is)X
+984(performed)X
+1353(for)X
+1481(each)X
+1663(key)X
+1813(in)X
+1909(the)X
+2041(hash)X
+547 4218(table,)N
+759(and)X
+911(the)X
+1045(data)X
+1215(returned)X
+1519(is)X
+1608(compared)X
+1961(against)X
+547 4306(that)N
+687(originally)X
+1018(stored)X
+1234(in)X
+1316(the)X
+1434(hash)X
+1601(table.)X
+3 f
+432 4420(sequential)N
+798(retrieve)X
+1 f
+547 4534(All)N
+674(keys)X
+846(are)X
+970(retrieved)X
+1281(in)X
+1367(sequential)X
+1716(order)X
+1910(from)X
+2090(the)X
+547 4622(hash)N
+724(table.)X
+950(The)X
+2 f
+1105(ndbm)X
+1 f
+1313(interface)X
+1625(allows)X
+1863(sequential)X
+547 4710(retrieval)N
+848(of)X
+948(the)X
+1079(keys)X
+1259(from)X
+1448(the)X
+1578(database,)X
+1907(but)X
+2041(does)X
+547 4798(not)N
+701(return)X
+945(the)X
+1094(data)X
+1279(associated)X
+1660(with)X
+1853(each)X
+2052(key.)X
+547 4886(Therefore,)N
+929(we)X
+1067(compare)X
+1388(the)X
+1530(performance)X
+1980(of)X
+2090(the)X
+547 4974(new)N
+703(package)X
+989(to)X
+1073(two)X
+1215(different)X
+1514(runs)X
+1674(of)X
+2 f
+1763(ndbm)X
+1 f
+1941(.)X
+2002(In)X
+2090(the)X
+547 5062(\256rst)N
+697(case,)X
+2 f
+882(ndbm)X
+1 f
+1086(returns)X
+1335(only)X
+1503(the)X
+1627(keys)X
+1800(while)X
+2003(in)X
+2090(the)X
+547 5150(second,)N
+2 f
+823(ndbm)X
+1 f
+1034(returns)X
+1290(both)X
+1465(the)X
+1596(keys)X
+1776(and)X
+1924(the)X
+2054(data)X
+547 5238(\(requiring)N
+894(a)X
+956(second)X
+1204(call)X
+1345(to)X
+1432(the)X
+1555(library\).)X
+1861(There)X
+2074(is)X
+2152(a)X
+547 5326(single)N
+764(run)X
+897(for)X
+1017(the)X
+1141(new)X
+1300(library)X
+1539(since)X
+1729(it)X
+1798(returns)X
+2046(both)X
+547 5414(the)N
+665(key)X
+801(and)X
+937(the)X
+1055(data.)X
+3 f
+3014 538(In-Memory)N
+3431(Test)X
+1 f
+2590 670(This)N
+2757(test)X
+2892(uses)X
+3054(a)X
+3114(bucket)X
+3352(size)X
+3501(of)X
+3592(256)X
+3736(and)X
+3876(a)X
+3936(\256ll)X
+4048(fac-)X
+2418 758(tor)N
+2527(of)X
+2614(8.)X
+3 f
+2418 872(create/read)N
+2827(test)X
+1 f
+2533 986(In)N
+2627(this)X
+2769(test,)X
+2927(a)X
+2989(hash)X
+3162(table)X
+3344(is)X
+3423(created)X
+3682(by)X
+3788(inserting)X
+4094(all)X
+2533 1074(the)N
+2660(key/data)X
+2961(pairs.)X
+3186(Then)X
+3380(a)X
+3445(keyed)X
+3666(retrieval)X
+3963(is)X
+4044(per-)X
+2533 1162(formed)N
+2801(for)X
+2931(each)X
+3115(pair,)X
+3295(and)X
+3446(the)X
+3579(hash)X
+3761(table)X
+3952(is)X
+4040(des-)X
+2533 1250(troyed.)N
+3 f
+2938 1404(Performance)N
+3405(Results)X
+1 f
+2590 1536(Figures)N
+2866(8a)X
+2978(and)X
+3130(8b)X
+3246(show)X
+3451(the)X
+3585(user)X
+3755(time,)X
+3952(system)X
+2418 1624(time,)N
+2608(and)X
+2752(elapsed)X
+3021(time)X
+3191(for)X
+3312(each)X
+3487(test)X
+3625(for)X
+3746(both)X
+3915(the)X
+4040(new)X
+2418 1712(implementation)N
+2951(and)X
+3098(the)X
+3227(old)X
+3360(implementation)X
+3893(\()X
+2 f
+3920(hsearch)X
+1 f
+2418 1800(or)N
+2 f
+2528(ndbm)X
+1 f
+2706(,)X
+2769(whichever)X
+3147(is)X
+3243(appropriate\))X
+3678(as)X
+3787(well)X
+3967(as)X
+4076(the)X
+2418 1888(improvement.)N
+2929(The)X
+3098(improvement)X
+3569(is)X
+3666(expressed)X
+4027(as)X
+4138(a)X
+2418 1976(percentage)N
+2787(of)X
+2874(the)X
+2992(old)X
+3114(running)X
+3383(time:)X
+0 f
+8 s
+2418 2275(%)N
+2494(=)X
+2570(100)X
+2722(*)X
+2798 -0.4219(\(old_time)AX
+3178(-)X
+3254 -0.4219(new_time\))AX
+3634(/)X
+3710(old_time)X
+1 f
+10 s
+2590 2600(In)N
+2700(nearly)X
+2944(all)X
+3067(cases,)X
+3299(the)X
+3439(new)X
+3615(routines)X
+3915(perform)X
+2418 2688(better)N
+2628(than)X
+2793(the)X
+2918(old)X
+3047(routines)X
+3332(\(both)X
+2 f
+3527(hsearch)X
+1 f
+3807(and)X
+2 f
+3949(ndbm)X
+1 f
+4127(\).)X
+2418 2776(Although)N
+2755(the)X
+3 f
+2888(create)X
+1 f
+3134(tests)X
+3311(exhibit)X
+3567(superior)X
+3864(user)X
+4032(time)X
+2418 2864(performance,)N
+2869(the)X
+2991(test)X
+3126(time)X
+3292(is)X
+3369(dominated)X
+3731(by)X
+3834(the)X
+3955(cost)X
+4107(of)X
+2418 2952(writing)N
+2677(the)X
+2803(actual)X
+3023(\256le)X
+3153(to)X
+3243(disk.)X
+3444(For)X
+3583(the)X
+3709(large)X
+3897(database)X
+2418 3040(\(the)N
+2564(dictionary\),)X
+2957(this)X
+3093(completely)X
+3470(overwhelmed)X
+3927(the)X
+4045(sys-)X
+2418 3128(tem)N
+2570(time.)X
+2783(However,)X
+3129(for)X
+3254(the)X
+3383(small)X
+3587(data)X
+3752(base,)X
+3946(we)X
+4071(see)X
+2418 3216(that)N
+2569(differences)X
+2958(in)X
+3051(both)X
+3224(user)X
+3389(and)X
+3536(system)X
+3788(time)X
+3960(contri-)X
+2418 3304(bute)N
+2576(to)X
+2658(the)X
+2776(superior)X
+3059(performance)X
+3486(of)X
+3573(the)X
+3691(new)X
+3845(package.)X
+2590 3418(The)N
+3 f
+2764(read)X
+1 f
+2920(,)X
+3 f
+2989(verify)X
+1 f
+3190(,)X
+3259(and)X
+3 f
+3424(sequential)X
+1 f
+3818(results)X
+4075(are)X
+2418 3506(deceptive)N
+2758(for)X
+2883(the)X
+3012(small)X
+3216(database)X
+3524(since)X
+3720(the)X
+3849(entire)X
+4063(test)X
+2418 3594(ran)N
+2551(in)X
+2643(under)X
+2856(a)X
+2922(second.)X
+3215(However,)X
+3560(on)X
+3669(the)X
+3796(larger)X
+4013(data-)X
+2418 3682(base)N
+2590(the)X
+3 f
+2716(read)X
+1 f
+2900(and)X
+3 f
+3044(verify)X
+1 f
+3273(tests)X
+3443(bene\256t)X
+3689(from)X
+3873(the)X
+3999(cach-)X
+2418 3770(ing)N
+2546(of)X
+2639(buckets)X
+2910(in)X
+2998(the)X
+3122(new)X
+3282(package)X
+3571(to)X
+3658(improve)X
+3950(perfor-)X
+2418 3858(mance)N
+2666(by)X
+2784(over)X
+2965(80%.)X
+3169(Since)X
+3384(the)X
+3519(\256rst)X
+3 f
+3680(sequential)X
+1 f
+4063(test)X
+2418 3946(does)N
+2598(not)X
+2733(require)X
+2 f
+2994(ndbm)X
+1 f
+3205(to)X
+3299(return)X
+3523(the)X
+3653(data)X
+3819(values,)X
+4076(the)X
+2418 4034(user)N
+2573(time)X
+2735(is)X
+2808(lower)X
+3011(than)X
+3169(for)X
+3283(the)X
+3401(new)X
+3555(package.)X
+3879(However)X
+2418 4122(when)N
+2613(we)X
+2728(require)X
+2977(both)X
+3139(packages)X
+3454(to)X
+3536(return)X
+3748(data,)X
+3922(the)X
+4040(new)X
+2418 4210(package)N
+2702(excels)X
+2923(in)X
+3005(all)X
+3105(three)X
+3286(timings.)X
+2590 4324(The)N
+2773(small)X
+3003(database)X
+3337(runs)X
+3532(so)X
+3660(quickly)X
+3957(in)X
+4076(the)X
+2418 4412(memory-resident)N
+3000(case)X
+3173(that)X
+3326(the)X
+3457(results)X
+3699(are)X
+3831(uninterest-)X
+2418 4500(ing.)N
+2589(However,)X
+2933(for)X
+3056(the)X
+3183(larger)X
+3400(database)X
+3706(the)X
+3833(new)X
+3995(pack-)X
+2418 4588(age)N
+2567(pays)X
+2751(a)X
+2824(small)X
+3033(penalty)X
+3305(in)X
+3403(system)X
+3661(time)X
+3839(because)X
+4130(it)X
+2418 4676(limits)N
+2636(its)X
+2748(main)X
+2944(memory)X
+3247(utilization)X
+3607(and)X
+3759(swaps)X
+3991(pages)X
+2418 4764(out)N
+2550(to)X
+2642(temporary)X
+3002(storage)X
+3264(in)X
+3356(the)X
+3484(\256le)X
+3616(system)X
+3868(while)X
+4076(the)X
+2 f
+2418 4852(hsearch)N
+1 f
+2698(package)X
+2988(requires)X
+3273(that)X
+3419(the)X
+3543(application)X
+3924(allocate)X
+2418 4940(enough)N
+2692(space)X
+2909(for)X
+3041(all)X
+3159(key/data)X
+3468(pair.)X
+3670(However,)X
+4022(even)X
+2418 5028(with)N
+2600(the)X
+2738(system)X
+3000(time)X
+3182(penalty,)X
+3477(the)X
+3614(resulting)X
+3933(elapsed)X
+2418 5116(time)N
+2580(improves)X
+2898(by)X
+2998(over)X
+3161(50%.)X
+3 f
+432 5960(10)N
+2970(USENIX)X
+9 f
+3292(-)X
+3 f
+3356(Winter)X
+3621('91)X
+9 f
+3748(-)X
+3 f
+3812(Dallas,)X
+4065(TX)X
+
+11 p
+%%Page: 11 11
+0(Courier)xf 0 f
+10 s 10 xH 0 xS 0 f
+3 f
+720 258(Seltzer)N
+977(&)X
+1064(Yigit)X
+3278(A)X
+3356(New)X
+3528(Hashing)X
+3831(Package)X
+4136(for)X
+4259(UNIX)X
+1 f
+10 f
+908 454(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2 f
+1379 546(hash)N
+1652(ndbm)X
+1950(%change)X
+1 f
+10 f
+908 550(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+948 642(CREATE)N
+10 f
+908 646(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+1125 738(user)N
+1424(6.4)X
+1671(12.2)X
+2073(48)X
+1157 826(sys)N
+1384(32.5)X
+1671(34.7)X
+2113(6)X
+3 f
+1006 914(elapsed)N
+10 f
+1310 922(c)N
+890(c)Y
+810(c)Y
+730(c)Y
+3 f
+1384 914(90.4)N
+10 f
+1581 922(c)N
+890(c)Y
+810(c)Y
+730(c)Y
+3 f
+1671 914(99.6)N
+10 f
+1883 922(c)N
+890(c)Y
+810(c)Y
+730(c)Y
+3 f
+2113 914(9)N
+1 f
+10 f
+908 910(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+908 926(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+948 1010(READ)N
+10 f
+908 1014(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+1125 1106(user)N
+1424(3.4)X
+1711(6.1)X
+2073(44)X
+1157 1194(sys)N
+1424(1.2)X
+1671(15.3)X
+2073(92)X
+3 f
+1006 1282(elapsed)N
+10 f
+1310 1290(c)N
+1258(c)Y
+1178(c)Y
+1098(c)Y
+3 f
+1424 1282(4.0)N
+10 f
+1581 1290(c)N
+1258(c)Y
+1178(c)Y
+1098(c)Y
+3 f
+1671 1282(21.2)N
+10 f
+1883 1290(c)N
+1258(c)Y
+1178(c)Y
+1098(c)Y
+3 f
+2073 1282(81)N
+1 f
+10 f
+908 1278(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+908 1294(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+948 1378(VERIFY)N
+10 f
+908 1382(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+1125 1474(user)N
+1424(3.5)X
+1711(6.3)X
+2073(44)X
+1157 1562(sys)N
+1424(1.2)X
+1671(15.3)X
+2073(92)X
+3 f
+1006 1650(elapsed)N
+10 f
+1310 1658(c)N
+1626(c)Y
+1546(c)Y
+1466(c)Y
+3 f
+1424 1650(4.0)N
+10 f
+1581 1658(c)N
+1626(c)Y
+1546(c)Y
+1466(c)Y
+3 f
+1671 1650(21.2)N
+10 f
+1883 1658(c)N
+1626(c)Y
+1546(c)Y
+1466(c)Y
+3 f
+2073 1650(81)N
+1 f
+10 f
+908 1646(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+908 1662(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+948 1746(SEQUENTIAL)N
+10 f
+908 1750(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+1125 1842(user)N
+1424(2.7)X
+1711(1.9)X
+2046(-42)X
+1157 1930(sys)N
+1424(0.7)X
+1711(3.9)X
+2073(82)X
+3 f
+1006 2018(elapsed)N
+10 f
+1310 2026(c)N
+1994(c)Y
+1914(c)Y
+1834(c)Y
+3 f
+1424 2018(3.0)N
+10 f
+1581 2026(c)N
+1994(c)Y
+1914(c)Y
+1834(c)Y
+3 f
+1711 2018(5.0)N
+10 f
+1883 2026(c)N
+1994(c)Y
+1914(c)Y
+1834(c)Y
+3 f
+2073 2018(40)N
+1 f
+10 f
+908 2014(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+908 2030(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+948 2114(SEQUENTIAL)N
+1467(\(with)X
+1656(data)X
+1810(retrieval\))X
+10 f
+908 2118(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+1125 2210(user)N
+1424(2.7)X
+1711(8.2)X
+2073(67)X
+1157 2298(sys)N
+1424(0.7)X
+1711(4.3)X
+2073(84)X
+3 f
+1006 2386(elapsed)N
+1424(3.0)X
+1671(12.0)X
+2073(75)X
+1 f
+10 f
+908 2390(i)N
+927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+899 2394(c)N
+2378(c)Y
+2298(c)Y
+2218(c)Y
+2138(c)Y
+2058(c)Y
+1978(c)Y
+1898(c)Y
+1818(c)Y
+1738(c)Y
+1658(c)Y
+1578(c)Y
+1498(c)Y
+1418(c)Y
+1338(c)Y
+1258(c)Y
+1178(c)Y
+1098(c)Y
+1018(c)Y
+938(c)Y
+858(c)Y
+778(c)Y
+698(c)Y
+618(c)Y
+538(c)Y
+1310 2394(c)N
+2362(c)Y
+2282(c)Y
+2202(c)Y
+1581 2394(c)N
+2362(c)Y
+2282(c)Y
+2202(c)Y
+1883 2394(c)N
+2362(c)Y
+2282(c)Y
+2202(c)Y
+2278 2394(c)N
+2378(c)Y
+2298(c)Y
+2218(c)Y
+2138(c)Y
+2058(c)Y
+1978(c)Y
+1898(c)Y
+1818(c)Y
+1738(c)Y
+1658(c)Y
+1578(c)Y
+1498(c)Y
+1418(c)Y
+1338(c)Y
+1258(c)Y
+1178(c)Y
+1098(c)Y
+1018(c)Y
+938(c)Y
+858(c)Y
+778(c)Y
+698(c)Y
+618(c)Y
+538(c)Y
+905 2574(i)N
+930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2 f
+1318 2666(hash)N
+1585(hsearch)X
+1953(%change)X
+1 f
+10 f
+905 2670(i)N
+930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+945 2762(CREATE/READ)N
+10 f
+905 2766(i)N
+930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+1064 2858(user)N
+1343(6.6)X
+1642(17.2)X
+2096(62)X
+1096 2946(sys)N
+1343(1.1)X
+1682(0.3)X
+2029(-266)X
+3 f
+945 3034(elapsed)N
+1343(7.8)X
+1642(17.0)X
+2096(54)X
+1 f
+10 f
+905 3038(i)N
+930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+896 3050(c)N
+2978(c)Y
+2898(c)Y
+2818(c)Y
+2738(c)Y
+2658(c)Y
+1249 3034(c)N
+3010(c)Y
+2930(c)Y
+2850(c)Y
+1520 3034(c)N
+3010(c)Y
+2930(c)Y
+2850(c)Y
+1886 3034(c)N
+3010(c)Y
+2930(c)Y
+2850(c)Y
+2281 3050(c)N
+2978(c)Y
+2898(c)Y
+2818(c)Y
+2738(c)Y
+2658(c)Y
+3 f
+720 3174(Figure)N
+967(8a:)X
+1 f
+1094(Timing)X
+1349(results)X
+1578(for)X
+1692(the)X
+1810(dictionary)X
+2155(database.)X
+10 f
+720 3262 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+3 f
+1407 3504(Conclusion)N
+1 f
+892 3636(This)N
+1063(paper)X
+1271(has)X
+1407(presented)X
+1744(the)X
+1871(design,)X
+2129(implemen-)X
+720 3724(tation)N
+928(and)X
+1070(performance)X
+1503(of)X
+1596(a)X
+1658(new)X
+1818(hashing)X
+2093(package)X
+2382(for)X
+720 3812(UNIX.)N
+993(The)X
+1150(new)X
+1316(package)X
+1612(provides)X
+1919(a)X
+1986(superset)X
+2280(of)X
+2378(the)X
+720 3900(functionality)N
+1159(of)X
+1255(existing)X
+1537(hashing)X
+1815(packages)X
+2139(and)X
+2284(incor-)X
+720 3988(porates)N
+975(additional)X
+1318(features)X
+1596(such)X
+1766(as)X
+1855(large)X
+2038(key)X
+2176(handling,)X
+720 4076(user)N
+876(de\256ned)X
+1134(hash)X
+1302(functions,)X
+1641(multiple)X
+1928(hash)X
+2096(tables,)X
+2324(vari-)X
+720 4164(able)N
+894(sized)X
+1099(pages,)X
+1342(and)X
+1498(linear)X
+1721(hashing.)X
+2050(In)X
+2156(nearly)X
+2396(all)X
+720 4252(cases,)N
+954(the)X
+1096(new)X
+1274(package)X
+1582(provides)X
+1902(improved)X
+2252(perfor-)X
+720 4340(mance)N
+974(on)X
+1098(the)X
+1240(order)X
+1454(of)X
+1565(50-80%)X
+1863(for)X
+2001(the)X
+2142(workloads)X
+720 4428(shown.)N
+990(Applications)X
+1420(such)X
+1588(as)X
+1676(the)X
+1794(loader,)X
+2035(compiler,)X
+2360(and)X
+720 4516(mail,)N
+921(which)X
+1156(currently)X
+1485(implement)X
+1866(their)X
+2051(own)X
+2227(hashing)X
+720 4604(routines,)N
+1032(should)X
+1279(be)X
+1389(modi\256ed)X
+1706(to)X
+1801(use)X
+1941(the)X
+2072(generic)X
+2342(rou-)X
+720 4692(tines.)N
+892 4806(This)N
+1087(hashing)X
+1389(package)X
+1705(is)X
+1810(one)X
+1978(access)X
+2236(method)X
+720 4894(which)N
+953(is)X
+1043(part)X
+1205(of)X
+1309(a)X
+1382(generic)X
+1656(database)X
+1970(access)X
+2212(package)X
+720 4982(being)N
+955(developed)X
+1342(at)X
+1457(the)X
+1612(University)X
+2007(of)X
+2131(California,)X
+720 5070(Berkeley.)N
+1089(It)X
+1177(will)X
+1340(include)X
+1614(a)X
+1688(btree)X
+1887(access)X
+2131(method)X
+2409(as)X
+720 5158(well)N
+916(as)X
+1041(\256xed)X
+1259(and)X
+1433(variable)X
+1750(length)X
+2007(record)X
+2270(access)X
+720 5246(methods)N
+1024(in)X
+1119(addition)X
+1414(to)X
+1509(the)X
+1640(hashed)X
+1896(support)X
+2168(presented)X
+720 5334(here.)N
+948(All)X
+1099(of)X
+1215(the)X
+1361(access)X
+1615(methods)X
+1934(are)X
+2081(based)X
+2312(on)X
+2440(a)X
+720 5422(key/data)N
+1037(pair)X
+1207(interface)X
+1533(and)X
+1693(appear)X
+1952(identical)X
+2272(to)X
+2378(the)X
+720 5510(application)N
+1121(layer,)X
+1347(allowing)X
+1671(application)X
+2071(implementa-)X
+720 5598(tions)N
+906(to)X
+999(be)X
+1106(largely)X
+1360(independent)X
+1783(of)X
+1881(the)X
+2010(database)X
+2318(type.)X
+720 5686(The)N
+873(package)X
+1165(is)X
+1246(expected)X
+1560(to)X
+1650(be)X
+1754(an)X
+1858(integral)X
+2131(part)X
+2284(of)X
+2378(the)X
+2706 538(4.4BSD)N
+3006(system,)X
+3293(with)X
+3479(various)X
+3759(standard)X
+4075(applications)X
+2706 626(such)N
+2879(as)X
+2972(more\(1\),)X
+3277(sort\(1\))X
+3517(and)X
+3659(vi\(1\))X
+3841(based)X
+4050(on)X
+4156(it.)X
+4266(While)X
+2706 714(the)N
+2833(current)X
+3089(design)X
+3326(does)X
+3501(not)X
+3631(support)X
+3899(multi-user)X
+4256(access)X
+2706 802(or)N
+2804(transactions,)X
+3238(they)X
+3407(could)X
+3616(be)X
+3723(incorporated)X
+4159(relatively)X
+2706 890(easily.)N
+10 f
+2894 938(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2 f
+3365 1030(hash)N
+3638(ndbm)X
+3936(%change)X
+1 f
+10 f
+2894 1034(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+2934 1126(CREATE)N
+10 f
+2894 1130(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+3111 1222(user)N
+3390(0.2)X
+3677(0.4)X
+4079(50)X
+3143 1310(sys)N
+3390(0.1)X
+3677(1.0)X
+4079(90)X
+3 f
+2992 1398(elapsed)N
+10 f
+3296 1406(c)N
+1374(c)Y
+1294(c)Y
+1214(c)Y
+3 f
+3390 1398(0)N
+10 f
+3567 1406(c)N
+1374(c)Y
+1294(c)Y
+1214(c)Y
+3 f
+3677 1398(3.2)N
+10 f
+3869 1406(c)N
+1374(c)Y
+1294(c)Y
+1214(c)Y
+3 f
+4039 1398(100)N
+1 f
+10 f
+2894 1394(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2894 1410(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+2934 1494(READ)N
+10 f
+2894 1498(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+3111 1590(user)N
+3390(0.1)X
+3677(0.1)X
+4119(0)X
+3143 1678(sys)N
+3390(0.1)X
+3677(0.4)X
+4079(75)X
+3 f
+2992 1766(elapsed)N
+10 f
+3296 1774(c)N
+1742(c)Y
+1662(c)Y
+1582(c)Y
+3 f
+3390 1766(0.0)N
+10 f
+3567 1774(c)N
+1742(c)Y
+1662(c)Y
+1582(c)Y
+3 f
+3677 1766(0.0)N
+10 f
+3869 1774(c)N
+1742(c)Y
+1662(c)Y
+1582(c)Y
+3 f
+4119 1766(0)N
+1 f
+10 f
+2894 1762(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2894 1778(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+2934 1862(VERIFY)N
+10 f
+2894 1866(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+3111 1958(user)N
+3390(0.1)X
+3677(0.2)X
+4079(50)X
+3143 2046(sys)N
+3390(0.1)X
+3677(0.3)X
+4079(67)X
+3 f
+2992 2134(elapsed)N
+10 f
+3296 2142(c)N
+2110(c)Y
+2030(c)Y
+1950(c)Y
+3 f
+3390 2134(0.0)N
+10 f
+3567 2142(c)N
+2110(c)Y
+2030(c)Y
+1950(c)Y
+3 f
+3677 2134(0.0)N
+10 f
+3869 2142(c)N
+2110(c)Y
+2030(c)Y
+1950(c)Y
+3 f
+4119 2134(0)N
+1 f
+10 f
+2894 2130(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2894 2146(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+2934 2230(SEQUENTIAL)N
+10 f
+2894 2234(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+3111 2326(user)N
+3390(0.1)X
+3677(0.0)X
+4012(-100)X
+3143 2414(sys)N
+3390(0.1)X
+3677(0.1)X
+4119(0)X
+3 f
+2992 2502(elapsed)N
+10 f
+3296 2510(c)N
+2478(c)Y
+2398(c)Y
+2318(c)Y
+3 f
+3390 2502(0.0)N
+10 f
+3567 2510(c)N
+2478(c)Y
+2398(c)Y
+2318(c)Y
+3 f
+3677 2502(0.0)N
+10 f
+3869 2510(c)N
+2478(c)Y
+2398(c)Y
+2318(c)Y
+3 f
+4119 2502(0)N
+1 f
+10 f
+2894 2498(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2894 2514(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+2934 2598(SEQUENTIAL)N
+3453(\(with)X
+3642(data)X
+3796(retrieval\))X
+10 f
+2894 2602(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+3111 2694(user)N
+3390(0.1)X
+3677(0.1)X
+4119(0)X
+3143 2782(sys)N
+3390(0.1)X
+3677(0.1)X
+4119(0)X
+3 f
+2992 2870(elapsed)N
+3390(0.0)X
+3677(0.0)X
+4119(0)X
+1 f
+10 f
+2894 2874(i)N
+2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2885 2878(c)N
+2862(c)Y
+2782(c)Y
+2702(c)Y
+2622(c)Y
+2542(c)Y
+2462(c)Y
+2382(c)Y
+2302(c)Y
+2222(c)Y
+2142(c)Y
+2062(c)Y
+1982(c)Y
+1902(c)Y
+1822(c)Y
+1742(c)Y
+1662(c)Y
+1582(c)Y
+1502(c)Y
+1422(c)Y
+1342(c)Y
+1262(c)Y
+1182(c)Y
+1102(c)Y
+1022(c)Y
+3296 2878(c)N
+2846(c)Y
+2766(c)Y
+2686(c)Y
+3567 2878(c)N
+2846(c)Y
+2766(c)Y
+2686(c)Y
+3869 2878(c)N
+2846(c)Y
+2766(c)Y
+2686(c)Y
+4264 2878(c)N
+2862(c)Y
+2782(c)Y
+2702(c)Y
+2622(c)Y
+2542(c)Y
+2462(c)Y
+2382(c)Y
+2302(c)Y
+2222(c)Y
+2142(c)Y
+2062(c)Y
+1982(c)Y
+1902(c)Y
+1822(c)Y
+1742(c)Y
+1662(c)Y
+1582(c)Y
+1502(c)Y
+1422(c)Y
+1342(c)Y
+1262(c)Y
+1182(c)Y
+1102(c)Y
+1022(c)Y
+2891 3058(i)N
+2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2 f
+3304 3150(hash)N
+3571(hsearch)X
+3939(%change)X
+1 f
+10 f
+2891 3154(i)N
+2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+2931 3246(CREATE/READ)N
+10 f
+2891 3250(i)N
+2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+3050 3342(user)N
+3329(0.3)X
+3648(0.4)X
+4048(25)X
+3082 3430(sys)N
+3329(0.0)X
+3648(0.0)X
+4088(0)X
+3 f
+2931 3518(elapsed)N
+3329(0.0)X
+3648(0.0)X
+4088(0)X
+1 f
+10 f
+2891 3522(i)N
+2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2882 3534(c)N
+3462(c)Y
+3382(c)Y
+3302(c)Y
+3222(c)Y
+3142(c)Y
+3235 3518(c)N
+3494(c)Y
+3414(c)Y
+3334(c)Y
+3506 3518(c)N
+3494(c)Y
+3414(c)Y
+3334(c)Y
+3872 3518(c)N
+3494(c)Y
+3414(c)Y
+3334(c)Y
+4267 3534(c)N
+3462(c)Y
+3382(c)Y
+3302(c)Y
+3222(c)Y
+3142(c)Y
+3 f
+2706 3658(Figure)N
+2953(8b:)X
+1 f
+3084(Timing)X
+3339(results)X
+3568(for)X
+3682(the)X
+3800(password)X
+4123(database.)X
+10 f
+2706 3746 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN
+3 f
+3396 3988(References)N
+1 f
+2706 4120([ATT79])N
+3058(AT&T,)X
+3358(DBM\(3X\),)X
+2 f
+3773(Unix)X
+3990(Programmer's)X
+2878 4208(Manual,)N
+3194(Seventh)X
+3491(Edition,)X
+3793(Volume)X
+4085(1)X
+1 f
+(,)S
+4192(January,)X
+2878 4296(1979.)N
+2706 4472([ATT85])N
+3027(AT&T,)X
+3296(HSEARCH\(BA_LIB\),)X
+2 f
+4053(Unix)X
+4239(System)X
+2878 4560(User's)N
+3112(Manual,)X
+3401(System)X
+3644(V.3)X
+1 f
+3753(,)X
+3793(pp.)X
+3913(506-508,)X
+4220(1985.)X
+2706 4736([BRE73])N
+3025(Brent,)X
+3253(Richard)X
+3537(P.,)X
+3651(``Reducing)X
+4041(the)X
+4168(Retrieval)X
+2878 4824(Time)N
+3071(of)X
+3162(Scatter)X
+3409(Storage)X
+3678(Techniques'',)X
+2 f
+4146(Commun-)X
+2878 4912(ications)N
+3175(of)X
+3281(the)X
+3422(ACM)X
+1 f
+3591(,)X
+3654(Volume)X
+3955(16,)X
+4098(No.)X
+4259(2,)X
+4362(pp.)X
+2878 5000(105-109,)N
+3185(February,)X
+3515(1973.)X
+2706 5176([BSD86])N
+3055(NDBM\(3\),)X
+2 f
+3469(4.3BSD)X
+3775(Unix)X
+3990(Programmer's)X
+2878 5264(Manual)N
+3155(Reference)X
+3505(Guide)X
+1 f
+3701(,)X
+3749(University)X
+4114(of)X
+4208(Califor-)X
+2878 5352(nia,)N
+3016(Berkeley,)X
+3346(1986.)X
+2706 5528([ENB88])N
+3025(Enbody,)X
+3319(R.)X
+3417(J.,)X
+3533(Du,)X
+3676(H.)X
+3779(C.,)X
+3897(``Dynamic)X
+4270(Hash-)X
+2878 5616(ing)N
+3034(Schemes'',)X
+2 f
+3427(ACM)X
+3630(Computing)X
+4019(Surveys)X
+1 f
+4269(,)X
+4322(Vol.)X
+2878 5704(20,)N
+2998(No.)X
+3136(2,)X
+3216(pp.)X
+3336(85-113,)X
+3603(June)X
+3770(1988.)X
+3 f
+720 5960(USENIX)N
+9 f
+1042(-)X
+3 f
+1106(Winter)X
+1371('91)X
+9 f
+1498(-)X
+3 f
+1562(Dallas,)X
+1815(TX)X
+4384(11)X
+
+12 p
+%%Page: 12 12
+0(Courier)xf 0 f
+10 s 10 xH 0 xS 0 f
+3 f
+432 258(A)N
+510(New)X
+682(Hashing)X
+985(Package)X
+1290(for)X
+1413(UNIX)X
+3663(Seltzer)X
+3920(&)X
+4007(Yigit)X
+1 f
+432 538([FAG79])N
+776(Ronald)X
+1057(Fagin,)X
+1308(Jurg)X
+1495(Nievergelt,)X
+1903(Nicholas)X
+604 626(Pippenger,)N
+1003(H.)X
+1135(Raymond)X
+1500(Strong,)X
+1787(``Extendible)X
+604 714(Hashing)N
+901(--)X
+985(A)X
+1073(Fast)X
+1236(Access)X
+1493(Method)X
+1771(for)X
+1894(Dynamic)X
+604 802(Files'',)N
+2 f
+855(ACM)X
+1046(Transactions)X
+1485(on)X
+1586(Database)X
+1914(Systems)X
+1 f
+2168(,)X
+604 890(Volume)N
+882(4,)X
+962(No.)X
+1100(3.,)X
+1200(September)X
+1563(1979,)X
+1763(pp)X
+1863(315-34)X
+432 1066([KNU68],)N
+802(Knuth,)X
+1064(D.E.,)X
+2 f
+1273(The)X
+1434(Art)X
+1577(of)X
+1680(Computer)X
+2041(Pro-)X
+604 1154(gramming)N
+971(Vol.)X
+1140(3:)X
+1245(Sorting)X
+1518(and)X
+1676(Searching)X
+1 f
+2001(,)X
+2058(sec-)X
+604 1242(tions)N
+779(6.3-6.4,)X
+1046(pp)X
+1146(481-550.)X
+432 1418([LAR78])N
+747(Larson,)X
+1011(Per-Ake,)X
+1319(``Dynamic)X
+1687(Hashing'',)X
+2 f
+2048(BIT)X
+1 f
+(,)S
+604 1506(Vol.)N
+764(18,)X
+884(1978,)X
+1084(pp.)X
+1204(184-201.)X
+432 1682([LAR88])N
+752(Larson,)X
+1021(Per-Ake,)X
+1335(``Dynamic)X
+1709(Hash)X
+1900(Tables'',)X
+2 f
+604 1770(Communications)N
+1183(of)X
+1281(the)X
+1415(ACM)X
+1 f
+1584(,)X
+1640(Volume)X
+1934(31,)X
+2070(No.)X
+604 1858(4.,)N
+704(April)X
+893(1988,)X
+1093(pp)X
+1193(446-457.)X
+432 2034([LIT80])N
+731(Witold,)X
+1013(Litwin,)X
+1286(``Linear)X
+1590(Hashing:)X
+1939(A)X
+2036(New)X
+604 2122(Tool)N
+786(for)X
+911(File)X
+1065(and)X
+1211(Table)X
+1424(Addressing'',)X
+2 f
+1893(Proceed-)X
+604 2210(ings)N
+761(of)X
+847(the)X
+969(6th)X
+1095(International)X
+1540(Conference)X
+1933(on)X
+2036(Very)X
+604 2298(Large)N
+815(Databases)X
+1 f
+1153(,)X
+1193(1980.)X
+432 2474([NEL90])N
+743(Nelson,)X
+1011(Philip)X
+1222(A.,)X
+2 f
+1341(Gdbm)X
+1558(1.4)X
+1679(source)X
+1913(distribu-)X
+604 2562(tion)N
+748(and)X
+888(README)X
+1 f
+1209(,)X
+1249(August)X
+1500(1990.)X
+432 2738([THOM90])N
+840(Ken)X
+1011(Thompson,)X
+1410(private)X
+1670(communication,)X
+604 2826(Nov.)N
+782(1990.)X
+432 3002([TOR87])N
+790(Torek,)X
+1066(C.,)X
+1222(``Re:)X
+1470(dbm.a)X
+1751(and)X
+1950(ndbm.a)X
+604 3090(archives'',)N
+2 f
+966(USENET)X
+1279(newsgroup)X
+1650(comp.unix)X
+1 f
+2002(1987.)X
+432 3266([TOR88])N
+760(Torek,)X
+1006(C.,)X
+1133(``Re:)X
+1351(questions)X
+1686(regarding)X
+2027(data-)X
+604 3354(bases)N
+826(created)X
+1106(with)X
+1295(dbm)X
+1484(and)X
+1647(ndbm)X
+1876(routines'')X
+2 f
+604 3442(USENET)N
+937(newsgroup)X
+1328(comp.unix.questions)X
+1 f
+1982(,)X
+2041(June)X
+604 3530(1988.)N
+432 3706([WAL84])N
+773(Wales,)X
+1018(R.,)X
+1135(``Discussion)X
+1564(of)X
+1655("dbm")X
+1887(data)X
+2045(base)X
+604 3794(system'',)N
+2 f
+973(USENET)X
+1339(newsgroup)X
+1762(unix.wizards)X
+1 f
+2168(,)X
+604 3882(January,)N
+894(1984.)X
+432 4058([YIG89])N
+751(Ozan)X
+963(S.)X
+1069(Yigit,)X
+1294(``How)X
+1545(to)X
+1648(Roll)X
+1826(Your)X
+2032(Own)X
+604 4146(Dbm/Ndbm'',)N
+2 f
+1087(unpublished)X
+1504(manuscript)X
+1 f
+(,)S
+1910(Toronto,)X
+604 4234(July,)N
+777(1989)X
+3 f
+432 5960(12)N
+2970(USENIX)X
+9 f
+3292(-)X
+3 f
+3356(Winter)X
+3621('91)X
+9 f
+3748(-)X
+3 f
+3812(Dallas,)X
+4065(TX)X
+
+13 p
+%%Page: 13 13
+0(Courier)xf 0 f
+10 s 10 xH 0 xS 0 f
+3 f
+720 258(Seltzer)N
+977(&)X
+1064(Yigit)X
+3278(A)X
+3356(New)X
+3528(Hashing)X
+3831(Package)X
+4136(for)X
+4259(UNIX)X
+1 f
+720 538(Margo)N
+960(I.)X
+1033(Seltzer)X
+1282(is)X
+1361(a)X
+1423(Ph.D.)X
+1631(student)X
+1887(in)X
+1974(the)X
+2097(Department)X
+720 626(of)N
+823(Electrical)X
+1167(Engineering)X
+1595(and)X
+1747(Computer)X
+2102(Sciences)X
+2418(at)X
+720 714(the)N
+850(University)X
+1220(of)X
+1318(California,)X
+1694(Berkeley.)X
+2055(Her)X
+2207(research)X
+720 802(interests)N
+1017(include)X
+1283(\256le)X
+1415(systems,)X
+1718(databases,)X
+2076(and)X
+2221(transac-)X
+720 890(tion)N
+896(processing)X
+1291(systems.)X
+1636(She)X
+1807(spent)X
+2027(several)X
+2306(years)X
+720 978(working)N
+1026(at)X
+1123(startup)X
+1380(companies)X
+1762(designing)X
+2112(and)X
+2267(imple-)X
+720 1066(menting)N
+1048(\256le)X
+1216(systems)X
+1535(and)X
+1716(transaction)X
+2133(processing)X
+720 1154(software)N
+1026(and)X
+1170(designing)X
+1509(microprocessors.)X
+2103(Ms.)X
+2253(Seltzer)X
+720 1242(received)N
+1057(her)X
+1223(AB)X
+1397(in)X
+1522(Applied)X
+1843(Mathematics)X
+2320(from)X
+720 1330 0.1953(Harvard/Radcliffe)AN
+1325(College)X
+1594(in)X
+1676(1983.)X
+720 1444(In)N
+810(her)X
+936(spare)X
+1129(time,)X
+1313(Margo)X
+1549(can)X
+1683(usually)X
+1936(be)X
+2034(found)X
+2243(prepar-)X
+720 1532(ing)N
+868(massive)X
+1171(quantities)X
+1527(of)X
+1639(food)X
+1831(for)X
+1970(hungry)X
+2242(hoards,)X
+720 1620(studying)N
+1022(Japanese,)X
+1355(or)X
+1449(playing)X
+1716(soccer)X
+1948(with)X
+2116(an)X
+2218(exciting)X
+720 1708(Bay)N
+912(Area)X
+1132(Women's)X
+1507(Soccer)X
+1788(team,)X
+2026(the)X
+2186(Berkeley)X
+720 1796(Bruisers.)N
+720 1910(Ozan)N
+915(\()X
+3 f
+942(Oz)X
+1 f
+1040(\))X
+1092(Yigit)X
+1281(is)X
+1358(currently)X
+1672(a)X
+1732(software)X
+2033(engineer)X
+2334(with)X
+720 1998(the)N
+886(Communications)X
+1499(Research)X
+1861(and)X
+2044(Development)X
+720 2086(group,)N
+948(Computing)X
+1328(Services,)X
+1641(York)X
+1826(University.)X
+2224(His)X
+2355(for-)X
+720 2174(mative)N
+967(years)X
+1166(were)X
+1352(also)X
+1510(spent)X
+1708(at)X
+1795(York,)X
+2009(where)X
+2234(he)X
+2338(held)X
+720 2262(system)N
+985(programmer)X
+1425(and)X
+1583(administrator)X
+2052(positions)X
+2382(for)X
+720 2350(various)N
+995(mixtures)X
+1314(of)X
+1420(of)X
+1526(UNIX)X
+1765(systems)X
+2056(starting)X
+2334(with)X
+720 2438(Berkeley)N
+1031(4.1)X
+1151(in)X
+1233(1982,)X
+1433(while)X
+1631(at)X
+1709(the)X
+1827(same)X
+2012(time)X
+2174(obtaining)X
+720 2526(a)N
+776(degree)X
+1011(in)X
+1093(Computer)X
+1433(Science.)X
+720 2640(In)N
+813(his)X
+931(copious)X
+1205(free)X
+1356(time,)X
+1543(Oz)X
+1662(enjoys)X
+1896(working)X
+2188(on)X
+2293(what-)X
+720 2728(ever)N
+890(software)X
+1197(looks)X
+1400(interesting,)X
+1788(which)X
+2014(often)X
+2209(includes)X
+720 2816(language)N
+1044(interpreters,)X
+1464(preprocessors,)X
+1960(and)X
+2110(lately,)X
+2342(pro-)X
+720 2904(gram)N
+905(generators)X
+1260(and)X
+1396(expert)X
+1617(systems.)X
+720 3018(Oz)N
+836(has)X
+964(authored)X
+1266(several)X
+1515(public-domain)X
+2003(software)X
+2301(tools,)X
+720 3106(including)N
+1069(an)X
+1191(nroff-like)X
+1545(text)X
+1711(formatter)X
+2 f
+2056(proff)X
+1 f
+2257(that)X
+2423(is)X
+720 3194(apparently)N
+1083(still)X
+1226(used)X
+1397(in)X
+1483(some)X
+1676(basement)X
+2002(PCs.)X
+2173(His)X
+2307(latest)X
+720 3282(obsessions)N
+1143(include)X
+1460(the)X
+1639(incredible)X
+2040(programming)X
+720 3370(language)N
+1030(Scheme,)X
+1324(and)X
+1460(Chinese)X
+1738(Brush)X
+1949(painting.)X
+3 f
+720 5960(USENIX)N
+9 f
+1042(-)X
+3 f
+1106(Winter)X
+1371('91)X
+9 f
+1498(-)X
+3 f
+1562(Dallas,)X
+1815(TX)X
+4384(13)X
+
+14 p
+%%Page: 14 14
+0(Courier)xf 0 f
+10 s 10 xH 0 xS 0 f
+3 f
+432 5960(14)N
+2970(USENIX)X
+9 f
+3292(-)X
+3 f
+3356(Winter)X
+3621('91)X
+9 f
+3748(-)X
+3 f
+3812(Dallas,)X
+4065(TX)X
+
+14 p
+%%Trailer
+xt
+
+xs
diff --git a/lib/libc/db/docs/libtp.usenix.ps b/lib/libc/db/docs/libtp.usenix.ps
new file mode 100644
index 0000000..b7e441a
--- /dev/null
+++ b/lib/libc/db/docs/libtp.usenix.ps
@@ -0,0 +1,12340 @@
+%!PS-Adobe-1.0
+%%Creator: utopia:margo (& Seltzer,608-13E,8072,)
+%%Title: stdin (ditroff)
+%%CreationDate: Thu Dec 12 15:32:11 1991
+%%EndComments
+% @(#)psdit.pro 1.3 4/15/88
+% lib/psdit.pro -- prolog for psdit (ditroff) files
+% Copyright (c) 1984, 1985 Adobe Systems Incorporated. All Rights Reserved.
+% last edit: shore Sat Nov 23 20:28:03 1985
+% RCSID: $FreeBSD$
+
+% Changed by Edward Wang (edward@ucbarpa.berkeley.edu) to handle graphics,
+% 17 Feb, 87.
+
+/$DITroff 140 dict def $DITroff begin
+/fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def
+/xi{0 72 11 mul translate 72 resolution div dup neg scale 0 0 moveto
+ /fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def F
+ /pagesave save def}def
+/PB{save /psv exch def currentpoint translate
+ resolution 72 div dup neg scale 0 0 moveto}def
+/PE{psv restore}def
+/arctoobig 90 def /arctoosmall .05 def
+/m1 matrix def /m2 matrix def /m3 matrix def /oldmat matrix def
+/tan{dup sin exch cos div}def
+/point{resolution 72 div mul}def
+/dround {transform round exch round exch itransform}def
+/xT{/devname exch def}def
+/xr{/mh exch def /my exch def /resolution exch def}def
+/xp{}def
+/xs{docsave restore end}def
+/xt{}def
+/xf{/fontname exch def /slotno exch def fontnames slotno get fontname eq not
+ {fonts slotno fontname findfont put fontnames slotno fontname put}if}def
+/xH{/fontheight exch def F}def
+/xS{/fontslant exch def F}def
+/s{/fontsize exch def /fontheight fontsize def F}def
+/f{/fontnum exch def F}def
+/F{fontheight 0 le{/fontheight fontsize def}if
+ fonts fontnum get fontsize point 0 0 fontheight point neg 0 0 m1 astore
+ fontslant 0 ne{1 0 fontslant tan 1 0 0 m2 astore m3 concatmatrix}if
+ makefont setfont .04 fontsize point mul 0 dround pop setlinewidth}def
+/X{exch currentpoint exch pop moveto show}def
+/N{3 1 roll moveto show}def
+/Y{exch currentpoint pop exch moveto show}def
+/S{show}def
+/ditpush{}def/ditpop{}def
+/AX{3 -1 roll currentpoint exch pop moveto 0 exch ashow}def
+/AN{4 2 roll moveto 0 exch ashow}def
+/AY{3 -1 roll currentpoint pop exch moveto 0 exch ashow}def
+/AS{0 exch ashow}def
+/MX{currentpoint exch pop moveto}def
+/MY{currentpoint pop exch moveto}def
+/MXY{moveto}def
+/cb{pop}def % action on unknown char -- nothing for now
+/n{}def/w{}def
+/p{pop showpage pagesave restore /pagesave save def}def
+/Dt{/Dlinewidth exch def}def 1 Dt
+/Ds{/Ddash exch def}def -1 Ds
+/Di{/Dstipple exch def}def 1 Di
+/Dsetlinewidth{2 Dlinewidth mul setlinewidth}def
+/Dsetdash{Ddash 4 eq{[8 12]}{Ddash 16 eq{[32 36]}
+ {Ddash 20 eq{[32 12 8 12]}{[]}ifelse}ifelse}ifelse 0 setdash}def
+/Dstroke{gsave Dsetlinewidth Dsetdash 1 setlinecap stroke grestore
+ currentpoint newpath moveto}def
+/Dl{rlineto Dstroke}def
+/arcellipse{/diamv exch def /diamh exch def oldmat currentmatrix pop
+ currentpoint translate 1 diamv diamh div scale /rad diamh 2 div def
+ currentpoint exch rad add exch rad -180 180 arc oldmat setmatrix}def
+/Dc{dup arcellipse Dstroke}def
+/De{arcellipse Dstroke}def
+/Da{/endv exch def /endh exch def /centerv exch def /centerh exch def
+ /cradius centerv centerv mul centerh centerh mul add sqrt def
+ /eradius endv endv mul endh endh mul add sqrt def
+ /endang endv endh atan def
+ /startang centerv neg centerh neg atan def
+ /sweep startang endang sub dup 0 lt{360 add}if def
+ sweep arctoobig gt
+ {/midang startang sweep 2 div sub def /midrad cradius eradius add 2 div def
+ /midh midang cos midrad mul def /midv midang sin midrad mul def
+ midh neg midv neg endh endv centerh centerv midh midv Da
+ Da}
+ {sweep arctoosmall ge
+ {/controldelt 1 sweep 2 div cos sub 3 sweep 2 div sin mul div 4 mul def
+ centerv neg controldelt mul centerh controldelt mul
+ endv neg controldelt mul centerh add endh add
+ endh controldelt mul centerv add endv add
+ centerh endh add centerv endv add rcurveto Dstroke}
+ {centerh endh add centerv endv add rlineto Dstroke}
+ ifelse}
+ ifelse}def
+/Dpatterns[
+[%cf[widthbits]
+[8<0000000000000010>]
+[8<0411040040114000>]
+[8<0204081020408001>]
+[8<0000103810000000>]
+[8<6699996666999966>]
+[8<0000800100001008>]
+[8<81c36666c3810000>]
+[8<0f0e0c0800000000>]
+[8<0000000000000010>]
+[8<0411040040114000>]
+[8<0204081020408001>]
+[8<0000001038100000>]
+[8<6699996666999966>]
+[8<0000800100001008>]
+[8<81c36666c3810000>]
+[8<0f0e0c0800000000>]
+[8<0042660000246600>]
+[8<0000990000990000>]
+[8<0804020180402010>]
+[8<2418814242811824>]
+[8<6699996666999966>]
+[8<8000000008000000>]
+[8<00001c3e363e1c00>]
+[8<0000000000000000>]
+[32<00000040000000c00000004000000040000000e0000000000000000000000000>]
+[32<00000000000060000000900000002000000040000000f0000000000000000000>]
+[32<000000000000000000e0000000100000006000000010000000e0000000000000>]
+[32<00000000000000002000000060000000a0000000f00000002000000000000000>]
+[32<0000000e0000000000000000000000000000000f000000080000000e00000001>]
+[32<0000090000000600000000000000000000000000000007000000080000000e00>]
+[32<00010000000200000004000000040000000000000000000000000000000f0000>]
+[32<0900000006000000090000000600000000000000000000000000000006000000>]]
+[%ug
+[8<0000020000000000>]
+[8<0000020000002000>]
+[8<0004020000002000>]
+[8<0004020000402000>]
+[8<0004060000402000>]
+[8<0004060000406000>]
+[8<0006060000406000>]
+[8<0006060000606000>]
+[8<00060e0000606000>]
+[8<00060e000060e000>]
+[8<00070e000060e000>]
+[8<00070e000070e000>]
+[8<00070e020070e000>]
+[8<00070e020070e020>]
+[8<04070e020070e020>]
+[8<04070e024070e020>]
+[8<04070e064070e020>]
+[8<04070e064070e060>]
+[8<06070e064070e060>]
+[8<06070e066070e060>]
+[8<06070f066070e060>]
+[8<06070f066070f060>]
+[8<060f0f066070f060>]
+[8<060f0f0660f0f060>]
+[8<060f0f0760f0f060>]
+[8<060f0f0760f0f070>]
+[8<0e0f0f0760f0f070>]
+[8<0e0f0f07e0f0f070>]
+[8<0e0f0f0fe0f0f070>]
+[8<0e0f0f0fe0f0f0f0>]
+[8<0f0f0f0fe0f0f0f0>]
+[8<0f0f0f0ff0f0f0f0>]
+[8<1f0f0f0ff0f0f0f0>]
+[8<1f0f0f0ff1f0f0f0>]
+[8<1f0f0f8ff1f0f0f0>]
+[8<1f0f0f8ff1f0f0f8>]
+[8<9f0f0f8ff1f0f0f8>]
+[8<9f0f0f8ff9f0f0f8>]
+[8<9f0f0f9ff9f0f0f8>]
+[8<9f0f0f9ff9f0f0f9>]
+[8<9f8f0f9ff9f0f0f9>]
+[8<9f8f0f9ff9f8f0f9>]
+[8<9f8f1f9ff9f8f0f9>]
+[8<9f8f1f9ff9f8f1f9>]
+[8<bf8f1f9ff9f8f1f9>]
+[8<bf8f1f9ffbf8f1f9>]
+[8<bf8f1fdffbf8f1f9>]
+[8<bf8f1fdffbf8f1fd>]
+[8<ff8f1fdffbf8f1fd>]
+[8<ff8f1fdffff8f1fd>]
+[8<ff8f1ffffff8f1fd>]
+[8<ff8f1ffffff8f1ff>]
+[8<ff9f1ffffff8f1ff>]
+[8<ff9f1ffffff9f1ff>]
+[8<ff9f9ffffff9f1ff>]
+[8<ff9f9ffffff9f9ff>]
+[8<ffbf9ffffff9f9ff>]
+[8<ffbf9ffffffbf9ff>]
+[8<ffbfdffffffbf9ff>]
+[8<ffbfdffffffbfdff>]
+[8<ffffdffffffbfdff>]
+[8<ffffdffffffffdff>]
+[8<fffffffffffffdff>]
+[8<ffffffffffffffff>]]
+[%mg
+[8<8000000000000000>]
+[8<0822080080228000>]
+[8<0204081020408001>]
+[8<40e0400000000000>]
+[8<66999966>]
+[8<8001000010080000>]
+[8<81c36666c3810000>]
+[8<f0e0c08000000000>]
+[16<07c00f801f003e007c00f800f001e003c007800f001f003e007c00f801f003e0>]
+[16<1f000f8007c003e001f000f8007c003e001f800fc007e003f001f8007c003e00>]
+[8<c3c300000000c3c3>]
+[16<0040008001000200040008001000200040008000000100020004000800100020>]
+[16<0040002000100008000400020001800040002000100008000400020001000080>]
+[16<1fc03fe07df0f8f8f07de03fc01f800fc01fe03ff07df8f87df03fe01fc00f80>]
+[8<80>]
+[8<8040201000000000>]
+[8<84cc000048cc0000>]
+[8<9900009900000000>]
+[8<08040201804020100800020180002010>]
+[8<2418814242811824>]
+[8<66999966>]
+[8<8000000008000000>]
+[8<70f8d8f870000000>]
+[8<0814224180402010>]
+[8<aa00440a11a04400>]
+[8<018245aa45820100>]
+[8<221c224180808041>]
+[8<88000000>]
+[8<0855800080550800>]
+[8<2844004482440044>]
+[8<0810204080412214>]
+[8<00>]]]def
+/Dfill{
+ transform /maxy exch def /maxx exch def
+ transform /miny exch def /minx exch def
+ minx maxx gt{/minx maxx /maxx minx def def}if
+ miny maxy gt{/miny maxy /maxy miny def def}if
+ Dpatterns Dstipple 1 sub get exch 1 sub get
+ aload pop /stip exch def /stipw exch def /stiph 128 def
+ /imatrix[stipw 0 0 stiph 0 0]def
+ /tmatrix[stipw 0 0 stiph 0 0]def
+ /minx minx cvi stiph idiv stiph mul def
+ /miny miny cvi stipw idiv stipw mul def
+ gsave eoclip 0 setgray
+ miny stiph maxy{
+ tmatrix exch 5 exch put
+ minx stipw maxx{
+ tmatrix exch 4 exch put tmatrix setmatrix
+ stipw stiph true imatrix {stip} imagemask
+ }for
+ }for
+ grestore
+}def
+/Dp{Dfill Dstroke}def
+/DP{Dfill currentpoint newpath moveto}def
+end
+
+/ditstart{$DITroff begin
+ /nfonts 60 def % NFONTS makedev/ditroff dependent!
+ /fonts[nfonts{0}repeat]def
+ /fontnames[nfonts{()}repeat]def
+/docsave save def
+}def
+
+% character outcalls
+/oc{
+ /pswid exch def /cc exch def /name exch def
+ /ditwid pswid fontsize mul resolution mul 72000 div def
+ /ditsiz fontsize resolution mul 72 div def
+ ocprocs name known{ocprocs name get exec}{name cb}ifelse
+}def
+/fractm [.65 0 0 .6 0 0] def
+/fraction{
+ /fden exch def /fnum exch def gsave /cf currentfont def
+ cf fractm makefont setfont 0 .3 dm 2 copy neg rmoveto
+ fnum show rmoveto currentfont cf setfont(\244)show setfont fden show
+ grestore ditwid 0 rmoveto
+}def
+/oce{grestore ditwid 0 rmoveto}def
+/dm{ditsiz mul}def
+/ocprocs 50 dict def ocprocs begin
+(14){(1)(4)fraction}def
+(12){(1)(2)fraction}def
+(34){(3)(4)fraction}def
+(13){(1)(3)fraction}def
+(23){(2)(3)fraction}def
+(18){(1)(8)fraction}def
+(38){(3)(8)fraction}def
+(58){(5)(8)fraction}def
+(78){(7)(8)fraction}def
+(sr){gsave 0 .06 dm rmoveto(\326)show oce}def
+(is){gsave 0 .15 dm rmoveto(\362)show oce}def
+(->){gsave 0 .02 dm rmoveto(\256)show oce}def
+(<-){gsave 0 .02 dm rmoveto(\254)show oce}def
+(==){gsave 0 .05 dm rmoveto(\272)show oce}def
+(uc){gsave currentpoint 400 .009 dm mul add translate
+ 8 -8 scale ucseal oce}def
+end
+
+% an attempt at a PostScript FONT to implement ditroff special chars
+% this will enable us to
+% cache the little buggers
+% generate faster, more compact PS out of psdit
+% confuse everyone (including myself)!
+50 dict dup begin
+/FontType 3 def
+/FontName /DIThacks def
+/FontMatrix [.001 0 0 .001 0 0] def
+/FontBBox [-260 -260 900 900] def% a lie but ...
+/Encoding 256 array def
+0 1 255{Encoding exch /.notdef put}for
+Encoding
+ dup 8#040/space put %space
+ dup 8#110/rc put %right ceil
+ dup 8#111/lt put %left top curl
+ dup 8#112/bv put %bold vert
+ dup 8#113/lk put %left mid curl
+ dup 8#114/lb put %left bot curl
+ dup 8#115/rt put %right top curl
+ dup 8#116/rk put %right mid curl
+ dup 8#117/rb put %right bot curl
+ dup 8#120/rf put %right floor
+ dup 8#121/lf put %left floor
+ dup 8#122/lc put %left ceil
+ dup 8#140/sq put %square
+ dup 8#141/bx put %box
+ dup 8#142/ci put %circle
+ dup 8#143/br put %box rule
+ dup 8#144/rn put %root extender
+ dup 8#145/vr put %vertical rule
+ dup 8#146/ob put %outline bullet
+ dup 8#147/bu put %bullet
+ dup 8#150/ru put %rule
+ dup 8#151/ul put %underline
+ pop
+/DITfd 100 dict def
+/BuildChar{0 begin
+ /cc exch def /fd exch def
+ /charname fd /Encoding get cc get def
+ /charwid fd /Metrics get charname get def
+ /charproc fd /CharProcs get charname get def
+ charwid 0 fd /FontBBox get aload pop setcachedevice
+ 2 setlinejoin 40 setlinewidth
+ newpath 0 0 moveto gsave charproc grestore
+ end}def
+/BuildChar load 0 DITfd put
+/CharProcs 50 dict def
+CharProcs begin
+/space{}def
+/.notdef{}def
+/ru{500 0 rls}def
+/rn{0 840 moveto 500 0 rls}def
+/vr{0 800 moveto 0 -770 rls}def
+/bv{0 800 moveto 0 -1000 rls}def
+/br{0 840 moveto 0 -1000 rls}def
+/ul{0 -140 moveto 500 0 rls}def
+/ob{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath stroke}def
+/bu{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath fill}def
+/sq{80 0 rmoveto currentpoint dround newpath moveto
+ 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath stroke}def
+/bx{80 0 rmoveto currentpoint dround newpath moveto
+ 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath fill}def
+/ci{500 360 rmoveto currentpoint newpath 333 0 360 arc
+ 50 setlinewidth stroke}def
+
+/lt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 add exch s4 a4p stroke}def
+/lb{0 800 moveto 0 -550 rlineto currx -200 2cx s4 add exch s4 a4p stroke}def
+/rt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 sub exch s4 a4p stroke}def
+/rb{0 800 moveto 0 -500 rlineto currx -200 2cx s4 sub exch s4 a4p stroke}def
+/lk{0 800 moveto 0 300 -300 300 s4 arcto pop pop 1000 sub
+ 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def
+/rk{0 800 moveto 0 300 s2 300 s4 arcto pop pop 1000 sub
+ 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def
+/lf{0 800 moveto 0 -1000 rlineto s4 0 rls}def
+/rf{0 800 moveto 0 -1000 rlineto s4 neg 0 rls}def
+/lc{0 -200 moveto 0 1000 rlineto s4 0 rls}def
+/rc{0 -200 moveto 0 1000 rlineto s4 neg 0 rls}def
+end
+
+/Metrics 50 dict def Metrics begin
+/.notdef 0 def
+/space 500 def
+/ru 500 def
+/br 0 def
+/lt 416 def
+/lb 416 def
+/rt 416 def
+/rb 416 def
+/lk 416 def
+/rk 416 def
+/rc 416 def
+/lc 416 def
+/rf 416 def
+/lf 416 def
+/bv 416 def
+/ob 350 def
+/bu 350 def
+/ci 750 def
+/bx 750 def
+/sq 750 def
+/rn 500 def
+/ul 500 def
+/vr 0 def
+end
+
+DITfd begin
+/s2 500 def /s4 250 def /s3 333 def
+/a4p{arcto pop pop pop pop}def
+/2cx{2 copy exch}def
+/rls{rlineto stroke}def
+/currx{currentpoint pop}def
+/dround{transform round exch round exch itransform} def
+end
+end
+/DIThacks exch definefont pop
+ditstart
+(psc)xT
+576 1 1 xr
+1(Times-Roman)xf 1 f
+2(Times-Italic)xf 2 f
+3(Times-Bold)xf 3 f
+4(Times-BoldItalic)xf 4 f
+5(Helvetica)xf 5 f
+6(Helvetica-Bold)xf 6 f
+7(Courier)xf 7 f
+8(Courier-Bold)xf 8 f
+9(Symbol)xf 9 f
+10(DIThacks)xf 10 f
+10 s
+1 f
+xi
+%%EndProlog
+
+%%Page: 1 1
+10 s 10 xH 0 xS 1 f
+3 f
+14 s
+1205 1206(LIBTP:)N
+1633(Portable,)X
+2100(M)X
+2206(odular)X
+2551(Transactions)X
+3202(for)X
+3374(UNIX)X
+1 f
+11 s
+3661 1162(1)N
+2 f
+12 s
+2182 1398(Margo)N
+2467(Seltzer)X
+2171 1494(Michael)N
+2511(Olson)X
+1800 1590(University)N
+2225(of)X
+2324(California,)X
+2773(Berkeley)X
+3 f
+2277 1878(Abstract)N
+1 f
+10 s
+755 2001(Transactions)N
+1198(provide)X
+1475(a)X
+1543(useful)X
+1771(programming)X
+2239(paradigm)X
+2574(for)X
+2700(maintaining)X
+3114(logical)X
+3364(consistency,)X
+3790(arbitrating)X
+4156(con-)X
+555 2091(current)N
+808(access,)X
+1059(and)X
+1200(managing)X
+1540(recovery.)X
+1886(In)X
+1977(traditional)X
+2330(UNIX)X
+2555(systems,)X
+2852(the)X
+2974(only)X
+3140(easy)X
+3307(way)X
+3465(of)X
+3556(using)X
+3753(transactions)X
+4160(is)X
+4237(to)X
+555 2181(purchase)N
+876(a)X
+947(database)X
+1258(system.)X
+1554(Such)X
+1748(systems)X
+2035(are)X
+2168(often)X
+2367(slow,)X
+2572(costly,)X
+2817(and)X
+2967(may)X
+3139(not)X
+3275(provide)X
+3554(the)X
+3686(exact)X
+3890(functionality)X
+555 2271(desired.)N
+848(This)X
+1011(paper)X
+1210(presents)X
+1493(the)X
+1611(design,)X
+1860(implementation,)X
+2402(and)X
+2538(performance)X
+2965(of)X
+3052(LIBTP,)X
+3314(a)X
+3370(simple,)X
+3623(non-proprietary)X
+4147(tran-)X
+555 2361(saction)N
+809(library)X
+1050(using)X
+1249(the)X
+1373(4.4BSD)X
+1654(database)X
+1957(access)X
+2189(routines)X
+2473(\()X
+3 f
+2500(db)X
+1 f
+2588(\(3\)\).)X
+2775(On)X
+2899(a)X
+2961(conventional)X
+3401(transaction)X
+3779(processing)X
+4148(style)X
+555 2451(benchmark,)N
+959(its)X
+1061(performance)X
+1495(is)X
+1575(approximately)X
+2065(85%)X
+2239(that)X
+2386(of)X
+2480(the)X
+2604(database)X
+2907(access)X
+3139(routines)X
+3423(without)X
+3693(transaction)X
+4071(protec-)X
+555 2541(tion,)N
+725(200%)X
+938(that)X
+1084(of)X
+1177(using)X
+3 f
+1376(fsync)X
+1 f
+1554(\(2\))X
+1674(to)X
+1761(commit)X
+2030(modi\256cations)X
+2490(to)X
+2577(disk,)X
+2755(and)X
+2896(125%)X
+3108(that)X
+3253(of)X
+3345(a)X
+3406(commercial)X
+3810(relational)X
+4138(data-)X
+555 2631(base)N
+718(system.)X
+3 f
+555 2817(1.)N
+655(Introduction)X
+1 f
+755 2940(Transactions)N
+1186(are)X
+1306(used)X
+1474(in)X
+1557(database)X
+1855(systems)X
+2129(to)X
+2212(enable)X
+2443(concurrent)X
+2807(users)X
+2992(to)X
+3074(apply)X
+3272(multi-operation)X
+3790(updates)X
+4055(without)X
+555 3030(violating)N
+863(the)X
+985(integrity)X
+1280(of)X
+1371(the)X
+1493(database.)X
+1814(They)X
+2003(provide)X
+2271(the)X
+2392(properties)X
+2736(of)X
+2826(atomicity,)X
+3171(consistency,)X
+3588(isolation,)X
+3906(and)X
+4045(durabil-)X
+555 3120(ity.)N
+701(By)X
+816(atomicity,)X
+1160(we)X
+1276(mean)X
+1472(that)X
+1614(the)X
+1734(set)X
+1845(of)X
+1934(updates)X
+2200(comprising)X
+2581(a)X
+2638(transaction)X
+3011(must)X
+3187(be)X
+3284(applied)X
+3541(as)X
+3629(a)X
+3686(single)X
+3898(unit;)X
+4085(that)X
+4226(is,)X
+555 3210(they)N
+714(must)X
+890(either)X
+1094(all)X
+1195(be)X
+1292(applied)X
+1549(to)X
+1632(the)X
+1751(database)X
+2049(or)X
+2137(all)X
+2238(be)X
+2335(absent.)X
+2601(Consistency)X
+3013(requires)X
+3293(that)X
+3434(a)X
+3491(transaction)X
+3864(take)X
+4019(the)X
+4138(data-)X
+555 3300(base)N
+725(from)X
+908(one)X
+1051(logically)X
+1358(consistent)X
+1704(state)X
+1877(to)X
+1965(another.)X
+2272(The)X
+2423(property)X
+2721(of)X
+2814(isolation)X
+3115(requires)X
+3400(that)X
+3546(concurrent)X
+3916(transactions)X
+555 3390(yield)N
+750(results)X
+994(which)X
+1225(are)X
+1358(indistinguishable)X
+1938(from)X
+2128(the)X
+2260(results)X
+2503(which)X
+2733(would)X
+2967(be)X
+3077(obtained)X
+3387(by)X
+3501(running)X
+3784(the)X
+3916(transactions)X
+555 3480(sequentially.)N
+1002(Finally,)X
+1268(durability)X
+1599(requires)X
+1878(that)X
+2018(once)X
+2190(transactions)X
+2593(have)X
+2765(been)X
+2937(committed,)X
+3319(their)X
+3486(results)X
+3715(must)X
+3890(be)X
+3986(preserved)X
+555 3570(across)N
+776(system)X
+1018(failures)X
+1279([TPCB90].)X
+755 3693(Although)N
+1080(these)X
+1268(properties)X
+1612(are)X
+1734(most)X
+1912(frequently)X
+2265(discussed)X
+2595(in)X
+2680(the)X
+2801(context)X
+3060(of)X
+3150(databases,)X
+3501(they)X
+3661(are)X
+3782(useful)X
+4000(program-)X
+555 3783(ming)N
+750(paradigms)X
+1114(for)X
+1238(more)X
+1433(general)X
+1700(purpose)X
+1984(applications.)X
+2441(There)X
+2659(are)X
+2788(several)X
+3046(different)X
+3353(situations)X
+3689(where)X
+3916(transactions)X
+555 3873(can)N
+687(be)X
+783(used)X
+950(to)X
+1032(replace)X
+1285(current)X
+1533(ad-hoc)X
+1772(mechanisms.)X
+755 3996(One)N
+910(situation)X
+1206(is)X
+1280(when)X
+1475(multiple)X
+1762(\256les)X
+1916(or)X
+2004(parts)X
+2181(of)X
+2269(\256les)X
+2422(need)X
+2594(to)X
+2676(be)X
+2772(updated)X
+3046(in)X
+3128(an)X
+3224(atomic)X
+3462(fashion.)X
+3758(For)X
+3889(example,)X
+4201(the)X
+555 4086(traditional)N
+907(UNIX)X
+1131(\256le)X
+1256(system)X
+1501(uses)X
+1661(ordering)X
+1955(constraints)X
+2324(to)X
+2408(achieve)X
+2676(recoverability)X
+3144(in)X
+3228(the)X
+3348(face)X
+3505(of)X
+3594(crashes.)X
+3893(When)X
+4107(a)X
+4165(new)X
+555 4176(\256le)N
+678(is)X
+752(created,)X
+1026(its)X
+1122(inode)X
+1321(is)X
+1395(written)X
+1642(to)X
+1724(disk)X
+1877(before)X
+2103(the)X
+2221(new)X
+2375(\256le)X
+2497(is)X
+2570(added)X
+2782(to)X
+2864(the)X
+2982(directory)X
+3292(structure.)X
+3633(This)X
+3795(guarantees)X
+4159(that,)X
+555 4266(if)N
+627(the)X
+748(system)X
+993(crashes)X
+1253(between)X
+1544(the)X
+1665(two)X
+1808(I/O's,)X
+2016(the)X
+2137(directory)X
+2450(does)X
+2620(not)X
+2744(contain)X
+3002(a)X
+3060 0.4531(reference)AX
+3383(to)X
+3467(an)X
+3565(invalid)X
+3809(inode.)X
+4049(In)X
+4138(actu-)X
+555 4356(ality,)N
+741(the)X
+863(desired)X
+1119(effect)X
+1326(is)X
+1402(that)X
+1545(these)X
+1733(two)X
+1876(updates)X
+2144(have)X
+2319(the)X
+2440(transactional)X
+2873(property)X
+3168(of)X
+3258(atomicity)X
+3583(\(either)X
+3816(both)X
+3981(writes)X
+4200(are)X
+555 4446(visible)N
+790(or)X
+879(neither)X
+1124(is\).)X
+1266(Rather)X
+1501(than)X
+1660(building)X
+1947(special)X
+2191(purpose)X
+2466(recovery)X
+2769(mechanisms)X
+3186(into)X
+3331(the)X
+3450(\256le)X
+3573(system)X
+3816(or)X
+3904(related)X
+4144(tools)X
+555 4536(\()N
+2 f
+582(e.g.)X
+3 f
+726(fsck)X
+1 f
+864(\(8\)\),)X
+1033(one)X
+1177(could)X
+1383(use)X
+1518(general)X
+1783(purpose)X
+2064(transaction)X
+2443(recovery)X
+2752(protocols)X
+3077(after)X
+3252(system)X
+3501(failure.)X
+3778(Any)X
+3943(application)X
+555 4626(that)N
+705(needs)X
+918(to)X
+1010(keep)X
+1192(multiple,)X
+1508(related)X
+1757(\256les)X
+1920(\(or)X
+2044(directories\))X
+2440(consistent)X
+2790(should)X
+3032(do)X
+3141(so)X
+3241(using)X
+3443(transactions.)X
+3895(Source)X
+4147(code)X
+555 4716(control)N
+805(systems,)X
+1101(such)X
+1271(as)X
+1361(RCS)X
+1534(and)X
+1673(SCCS,)X
+1910(should)X
+2146(use)X
+2276(transaction)X
+2651(semantics)X
+2990(to)X
+3075(allow)X
+3276(the)X
+3397(``checking)X
+3764(in'')X
+3903(of)X
+3992(groups)X
+4232(of)X
+555 4806(related)N
+801(\256les.)X
+1001(In)X
+1095(this)X
+1237(way,)X
+1418(if)X
+1493(the)X
+1617 0.2841(``check-in'')AX
+2028(fails,)X
+2212(the)X
+2336(transaction)X
+2714(may)X
+2878(be)X
+2980(aborted,)X
+3267(backing)X
+3547(out)X
+3675(the)X
+3799(partial)X
+4030(``check-)X
+555 4896(in'')N
+691(leaving)X
+947(the)X
+1065(source)X
+1295(repository)X
+1640(in)X
+1722(a)X
+1778(consistent)X
+2118(state.)X
+755 5019(A)N
+842(second)X
+1094(situation)X
+1398(where)X
+1624(transactions)X
+2036(can)X
+2177(be)X
+2282(used)X
+2458(to)X
+2549(replace)X
+2811(current)X
+3068(ad-hoc)X
+3316(mechanisms)X
+3741(is)X
+3822(in)X
+3912(applications)X
+555 5109(where)N
+776(concurrent)X
+1144(updates)X
+1413(to)X
+1499(a)X
+1559(shared)X
+1793(\256le)X
+1919(are)X
+2042(desired,)X
+2318(but)X
+2444(there)X
+2629(is)X
+2706(logical)X
+2948(consistency)X
+3345(of)X
+3435(the)X
+3556(data)X
+3713(which)X
+3932(needs)X
+4138(to)X
+4223(be)X
+555 5199(preserved.)N
+928(For)X
+1059(example,)X
+1371(when)X
+1565(the)X
+1683(password)X
+2006(\256le)X
+2128(is)X
+2201(updated,)X
+2495(\256le)X
+2617(locking)X
+2877(is)X
+2950(used)X
+3117(to)X
+3199(disallow)X
+3490(concurrent)X
+3854(access.)X
+4120(Tran-)X
+555 5289(saction)N
+804(semantics)X
+1142(on)X
+1244(the)X
+1364(password)X
+1689(\256les)X
+1844(would)X
+2066(allow)X
+2266(concurrent)X
+2632(updates,)X
+2919(while)X
+3119(preserving)X
+3479(the)X
+3598(logical)X
+3837(consistency)X
+4232(of)X
+555 5379(the)N
+681(password)X
+1012(database.)X
+1357(Similarly,)X
+1702(UNIX)X
+1930(utilities)X
+2196(which)X
+2419(rewrite)X
+2674(\256les)X
+2834(face)X
+2996(a)X
+3059(potential)X
+3366(race)X
+3528(condition)X
+3857(between)X
+4152(their)X
+555 5469(rewriting)N
+871(a)X
+929(\256le)X
+1053(and)X
+1191(another)X
+1453(process)X
+1715(reading)X
+1977(the)X
+2096(\256le.)X
+2259(For)X
+2391(example,)X
+2704(the)X
+2823(compiler)X
+3129(\(more)X
+3342(precisely,)X
+3673(the)X
+3792(assembler\))X
+4161(may)X
+8 s
+10 f
+555 5541(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N
+5 s
+1 f
+727 5619(1)N
+8 s
+763 5644(To)N
+850(appear)X
+1035(in)X
+1101(the)X
+2 f
+1195(Proceedings)X
+1530(of)X
+1596(the)X
+1690(1992)X
+1834(Winter)X
+2024(Usenix)X
+1 f
+2201(,)X
+2233(San)X
+2345(Francisco,)X
+2625(CA,)X
+2746(January)X
+2960(1992.)X
+
+2 p
+%%Page: 2 2
+8 s 8 xH 0 xS 1 f
+10 s
+3 f
+1 f
+555 630(have)N
+737(to)X
+829(rewrite)X
+1087(a)X
+1152(\256le)X
+1283(to)X
+1374(which)X
+1599(it)X
+1672(has)X
+1808(write)X
+2002(permission)X
+2382(in)X
+2473(a)X
+2538(directory)X
+2857(to)X
+2948(which)X
+3173(it)X
+3246(does)X
+3422(not)X
+3553(have)X
+3734(write)X
+3928(permission.)X
+555 720(While)N
+779(the)X
+904(``.o'')X
+1099(\256le)X
+1228(is)X
+1308(being)X
+1513(written,)X
+1787(another)X
+2055(utility)X
+2272(such)X
+2446(as)X
+3 f
+2540(nm)X
+1 f
+2651(\(1\))X
+2772(or)X
+3 f
+2866(ar)X
+1 f
+2942(\(1\))X
+3063(may)X
+3228(read)X
+3394(the)X
+3519(\256le)X
+3648(and)X
+3791(produce)X
+4077(invalid)X
+555 810(results)N
+790(since)X
+981(the)X
+1105(\256le)X
+1233(has)X
+1366(not)X
+1494(been)X
+1672(completely)X
+2054(written.)X
+2347(Currently,)X
+2700(some)X
+2895(utilities)X
+3160(use)X
+3293(special)X
+3542(purpose)X
+3821(code)X
+3998(to)X
+4085(handle)X
+555 900(such)N
+722(cases)X
+912(while)X
+1110(others)X
+1326(ignore)X
+1551(the)X
+1669(problem)X
+1956(and)X
+2092(force)X
+2278(users)X
+2463(to)X
+2545(live)X
+2685(with)X
+2847(the)X
+2965(consequences.)X
+755 1023(In)N
+845(this)X
+983(paper,)X
+1205(we)X
+1322(present)X
+1577(a)X
+1635(simple)X
+1870(library)X
+2106(which)X
+2324(provides)X
+2622(transaction)X
+2996(semantics)X
+3334(\(atomicity,)X
+3705(consistency,)X
+4121(isola-)X
+555 1113(tion,)N
+720(and)X
+857(durability\).)X
+1236(The)X
+1382(4.4BSD)X
+1658(database)X
+1956(access)X
+2182(methods)X
+2473(have)X
+2645(been)X
+2817(modi\256ed)X
+3121(to)X
+3203(use)X
+3330(this)X
+3465(library,)X
+3719(optionally)X
+4063(provid-)X
+555 1203(ing)N
+682(shared)X
+917(buffer)X
+1139(management)X
+1574(between)X
+1867(applications,)X
+2298(locking,)X
+2582(and)X
+2722(transaction)X
+3098(semantics.)X
+3478(Any)X
+3640(UNIX)X
+3865(program)X
+4161(may)X
+555 1293(transaction)N
+930(protect)X
+1176(its)X
+1274(data)X
+1430(by)X
+1532(requesting)X
+1888(transaction)X
+2262(protection)X
+2609(with)X
+2773(the)X
+3 f
+2893(db)X
+1 f
+2981(\(3\))X
+3097(library)X
+3333(or)X
+3422(by)X
+3524(adding)X
+3764(appropriate)X
+4152(calls)X
+555 1383(to)N
+646(the)X
+773(transaction)X
+1154(manager,)X
+1480(buffer)X
+1706(manager,)X
+2032(lock)X
+2199(manager,)X
+2525(and)X
+2670(log)X
+2801(manager.)X
+3147(The)X
+3301(library)X
+3543(routines)X
+3829(may)X
+3995(be)X
+4099(linked)X
+555 1473(into)N
+708(the)X
+834(host)X
+995(application)X
+1379(and)X
+1523(called)X
+1743(by)X
+1851(subroutine)X
+2217(interface,)X
+2547(or)X
+2642(they)X
+2808(may)X
+2974(reside)X
+3194(in)X
+3284(a)X
+3348(separate)X
+3640(server)X
+3865(process.)X
+4174(The)X
+555 1563(server)N
+772(architecture)X
+1172(provides)X
+1468(for)X
+1582(network)X
+1865(access)X
+2091(and)X
+2227(better)X
+2430(protection)X
+2775(mechanisms.)X
+3 f
+555 1749(2.)N
+655(Related)X
+938(Work)X
+1 f
+755 1872(There)N
+1000(has)X
+1164(been)X
+1373(much)X
+1608(discussion)X
+1998(in)X
+2117(recent)X
+2371(years)X
+2597(about)X
+2831(new)X
+3021(transaction)X
+3429(models)X
+3716(and)X
+3888(architectures)X
+555 1962 0.1172([SPEC88][NODI90][CHEN91][MOHA91].)AN
+2009(Much)X
+2220(of)X
+2310(this)X
+2448(work)X
+2636(focuses)X
+2900(on)X
+3003(new)X
+3160(ways)X
+3348(to)X
+3433(model)X
+3656(transactions)X
+4062(and)X
+4201(the)X
+555 2052(interactions)N
+953(between)X
+1245(them,)X
+1449(while)X
+1651(the)X
+1772(work)X
+1960(presented)X
+2291(here)X
+2453(focuses)X
+2717(on)X
+2820(the)X
+2941(implementation)X
+3466(and)X
+3605(performance)X
+4035(of)X
+4125(tradi-)X
+555 2142(tional)N
+757(transaction)X
+1129(techniques)X
+1492(\(write-ahead)X
+1919(logging)X
+2183(and)X
+2319(two-phase)X
+2669(locking\))X
+2956(on)X
+3056(a)X
+3112(standard)X
+3404(operating)X
+3727(system)X
+3969(\(UNIX\).)X
+755 2265(Such)N
+947(traditional)X
+1308(operating)X
+1643(systems)X
+1928(are)X
+2059(often)X
+2256(criticized)X
+2587(for)X
+2713(their)X
+2892(inability)X
+3190(to)X
+3283(perform)X
+3573(transaction)X
+3956(processing)X
+555 2355(adequately.)N
+971([STON81])X
+1342(cites)X
+1517(three)X
+1706(main)X
+1894(areas)X
+2088(of)X
+2183(inadequate)X
+2559(support:)X
+2849(buffer)X
+3074(management,)X
+3532(the)X
+3658(\256le)X
+3788(system,)X
+4058(and)X
+4201(the)X
+555 2445(process)N
+823(structure.)X
+1191(These)X
+1410(arguments)X
+1771(are)X
+1897(summarized)X
+2316(in)X
+2405(table)X
+2587(one.)X
+2769(Fortunately,)X
+3184(much)X
+3388(has)X
+3521(changed)X
+3815(since)X
+4006(1981.)X
+4232(In)X
+555 2535(the)N
+683(area)X
+848(of)X
+945(buffer)X
+1172(management,)X
+1632(most)X
+1817(UNIX)X
+2048(systems)X
+2331(provide)X
+2606(the)X
+2734(ability)X
+2968(to)X
+3060(memory)X
+3357(map)X
+3525(\256les,)X
+3708(thus)X
+3870(obviating)X
+4201(the)X
+555 2625(need)N
+734(for)X
+855(a)X
+918(copy)X
+1101(between)X
+1396(kernel)X
+1624(and)X
+1766(user)X
+1926(space.)X
+2171(If)X
+2251(a)X
+2313(database)X
+2616(system)X
+2864(is)X
+2943(going)X
+3151(to)X
+3239(use)X
+3372(the)X
+3496(\256le)X
+3624(system)X
+3872(buffer)X
+4095(cache,)X
+555 2715(then)N
+719(a)X
+781(system)X
+1029(call)X
+1171(is)X
+1250(required.)X
+1584(However,)X
+1924(if)X
+1998(buffering)X
+2322(is)X
+2400(provided)X
+2710(at)X
+2793(user)X
+2952(level)X
+3133(using)X
+3331(shared)X
+3566(memory,)X
+3878(as)X
+3970(in)X
+4057(LIBTP,)X
+555 2805(buffer)N
+776(management)X
+1210(is)X
+1287(only)X
+1452(as)X
+1542(slow)X
+1716(as)X
+1806(access)X
+2035(to)X
+2120(shared)X
+2353(memory)X
+2643(and)X
+2782(any)X
+2921(replacement)X
+3337(algorithm)X
+3671(may)X
+3832(be)X
+3931(used.)X
+4121(Since)X
+555 2895(multiple)N
+849(processes)X
+1185(can)X
+1325(access)X
+1559(the)X
+1685(shared)X
+1923(data,)X
+2105(prefetching)X
+2499(may)X
+2665(be)X
+2769(accomplished)X
+3238(by)X
+3346(separate)X
+3638(processes)X
+3973(or)X
+4067(threads)X
+555 2985(whose)N
+782(sole)X
+932(purpose)X
+1207(is)X
+1281(to)X
+1364(prefetch)X
+1649(pages)X
+1853(and)X
+1990(wait)X
+2149(on)X
+2250(them.)X
+2471(There)X
+2680(is)X
+2754(still)X
+2894(no)X
+2995(way)X
+3150(to)X
+3233(enforce)X
+3496(write)X
+3682(ordering)X
+3975(other)X
+4161(than)X
+555 3075(keeping)N
+829(pages)X
+1032(in)X
+1114(user)X
+1268(memory)X
+1555(and)X
+1691(using)X
+1884(the)X
+3 f
+2002(fsync)X
+1 f
+2180(\(3\))X
+2294(system)X
+2536(call)X
+2672(to)X
+2754(perform)X
+3033(synchronous)X
+3458(writes.)X
+755 3198(In)N
+845(the)X
+966(area)X
+1124(of)X
+1214(\256le)X
+1339(systems,)X
+1635(the)X
+1756(fast)X
+1895(\256le)X
+2020(system)X
+2265(\(FFS\))X
+2474([MCKU84])X
+2871(allows)X
+3103(allocation)X
+3442(in)X
+3527(units)X
+3704(up)X
+3806(to)X
+3890(64KBytes)X
+4232(as)X
+555 3288(opposed)N
+846(to)X
+932(the)X
+1054(4KByte)X
+1327(and)X
+1466(8KByte)X
+1738(\256gures)X
+1979(quoted)X
+2220(in)X
+2305([STON81].)X
+2711(The)X
+2859(measurements)X
+3341(in)X
+3426(this)X
+3564(paper)X
+3766(were)X
+3946(taken)X
+4143(from)X
+555 3378(an)N
+655(8KByte)X
+928(FFS,)X
+1104(but)X
+1230(as)X
+1320(LIBTP)X
+1565(runs)X
+1726(exclusively)X
+2114(in)X
+2199(user)X
+2356(space,)X
+2578(there)X
+2762(is)X
+2838(nothing)X
+3105(to)X
+3190(prevent)X
+3454(it)X
+3521(from)X
+3700(being)X
+3901(run)X
+4031(on)X
+4134(other)X
+555 3468(UNIX)N
+776(compatible)X
+1152(\256le)X
+1274(systems)X
+1547(\(e.g.)X
+1710(log-structured)X
+2180([ROSE91],)X
+2558(extent-based,)X
+3004(or)X
+3091(multi-block)X
+3484([SELT91]\).)X
+755 3591(Finally,)N
+1029(with)X
+1199(regard)X
+1433(to)X
+1523(the)X
+1648(process)X
+1916(structure,)X
+2244(neither)X
+2494(context)X
+2757(switch)X
+2993(time)X
+3162(nor)X
+3296(scheduling)X
+3670(around)X
+3920(semaphores)X
+555 3681(seems)N
+785(to)X
+881(affect)X
+1099(the)X
+1231(system)X
+1487(performance.)X
+1968(However,)X
+2317(the)X
+2449(implementation)X
+2984(of)X
+3084(semaphores)X
+3496(can)X
+3641(impact)X
+3892(performance)X
+555 3771(tremendously.)N
+1051(This)X
+1213(is)X
+1286(discussed)X
+1613(in)X
+1695(more)X
+1880(detail)X
+2078(in)X
+2160(section)X
+2407(4.3.)X
+755 3894(The)N
+908(Tuxedo)X
+1181(system)X
+1431(from)X
+1615(AT&T)X
+1861(is)X
+1941(a)X
+2004(transaction)X
+2383(manager)X
+2687(which)X
+2910(coordinates)X
+3307(distributed)X
+3676(transaction)X
+4055(commit)X
+555 3984(from)N
+738(a)X
+801(variety)X
+1051(of)X
+1145(different)X
+1449(local)X
+1632(transaction)X
+2011(managers.)X
+2386(At)X
+2493(this)X
+2634(time,)X
+2822(LIBTP)X
+3070(does)X
+3243(not)X
+3371(have)X
+3549(its)X
+3650(own)X
+3814(mechanism)X
+4205(for)X
+555 4074(distributed)N
+942(commit)X
+1231(processing,)X
+1639(but)X
+1786(could)X
+2009(be)X
+2130(used)X
+2322(as)X
+2434(a)X
+2515(local)X
+2716(transaction)X
+3113(agent)X
+3331(by)X
+3455(systems)X
+3752(such)X
+3943(as)X
+4054(Tuxedo)X
+555 4164([ANDR89].)N
+10 f
+863 4393(i)N
+870(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+903 4483(Buffer)N
+1133(Management)X
+10 f
+1672(g)X
+1 f
+1720(Data)X
+1892(must)X
+2067(be)X
+2163(copied)X
+2397(between)X
+2685(kernel)X
+2906(space)X
+3105(and)X
+3241(user)X
+3395(space.)X
+10 f
+1672 4573(g)N
+1 f
+1720(Buffer)X
+1950(pool)X
+2112(access)X
+2338(is)X
+2411(too)X
+2533(slow.)X
+10 f
+1672 4663(g)N
+1 f
+1720(There)X
+1928(is)X
+2001(no)X
+2101(way)X
+2255(to)X
+2337(request)X
+2589(prefetch.)X
+10 f
+1672 4753(g)N
+1 f
+1720(Replacement)X
+2159(is)X
+2232(usually)X
+2483(LRU)X
+2663(which)X
+2879(may)X
+3037(be)X
+3133(suboptimal)X
+3508(for)X
+3622(databases.)X
+10 f
+1672 4843(g)N
+1 f
+1720(There)X
+1928(is)X
+2001(no)X
+2101(way)X
+2255(to)X
+2337(guarantee)X
+2670(write)X
+2855(ordering.)X
+10 f
+863 4853(i)N
+870(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+903 4943(File)N
+1047(System)X
+10 f
+1672(g)X
+1 f
+1720(Allocation)X
+2078(is)X
+2151(done)X
+2327(in)X
+2409(small)X
+2602(blocks)X
+2831(\(usually)X
+3109(4K)X
+3227(or)X
+3314(8K\).)X
+10 f
+1672 5033(g)N
+1 f
+1720(Logical)X
+1985(organization)X
+2406(of)X
+2493(\256les)X
+2646(is)X
+2719(redundantly)X
+3122(expressed.)X
+10 f
+863 5043(i)N
+870(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+903 5133(Process)N
+1168(Structure)X
+10 f
+1672(g)X
+1 f
+1720(Context)X
+1993(switching)X
+2324(and)X
+2460(message)X
+2752(passing)X
+3012(are)X
+3131(too)X
+3253(slow.)X
+10 f
+1672 5223(g)N
+1 f
+1720(A)X
+1798(process)X
+2059(may)X
+2217(be)X
+2313(descheduled)X
+2730(while)X
+2928(holding)X
+3192(a)X
+3248(semaphore.)X
+10 f
+863 5233(i)N
+870(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+863(c)X
+5193(c)Y
+5113(c)Y
+5033(c)Y
+4953(c)Y
+4873(c)Y
+4793(c)Y
+4713(c)Y
+4633(c)Y
+4553(c)Y
+4473(c)Y
+3990 5233(c)N
+5193(c)Y
+5113(c)Y
+5033(c)Y
+4953(c)Y
+4873(c)Y
+4793(c)Y
+4713(c)Y
+4633(c)Y
+4553(c)Y
+4473(c)Y
+3 f
+1156 5446(Table)N
+1371(One:)X
+1560(Shortcomings)X
+2051(of)X
+2138(UNIX)X
+2363(transaction)X
+2770(support)X
+3056(cited)X
+3241(in)X
+3327([STON81].)X
+
+3 p
+%%Page: 3 3
+10 s 10 xH 0 xS 3 f
+1 f
+755 630(The)N
+901(transaction)X
+1274(architecture)X
+1675(presented)X
+2004(in)X
+2087([YOUN91])X
+2474(is)X
+2548(very)X
+2712(similar)X
+2955(to)X
+3038(that)X
+3179(implemented)X
+3618(in)X
+3701(the)X
+3820(LIBTP.)X
+4103(While)X
+555 720([YOUN91])N
+947(presents)X
+1236(a)X
+1298(model)X
+1524(for)X
+1644(providing)X
+1981(transaction)X
+2359(services,)X
+2663(this)X
+2803(paper)X
+3007(focuses)X
+3273(on)X
+3378(the)X
+3501(implementation)X
+4028(and)X
+4169(per-)X
+555 810(formance)N
+881(of)X
+970(a)X
+1028(particular)X
+1358(system.)X
+1642(In)X
+1731(addition,)X
+2034(we)X
+2149(provide)X
+2415(detailed)X
+2690(comparisons)X
+3116(with)X
+3279(alternative)X
+3639(solutions:)X
+3970(traditional)X
+555 900(UNIX)N
+776(services)X
+1055(and)X
+1191(commercial)X
+1590(database)X
+1887(management)X
+2317(systems.)X
+3 f
+555 1086(3.)N
+655(Architecture)X
+1 f
+755 1209(The)N
+906(library)X
+1146(is)X
+1224(designed)X
+1534(to)X
+1621(provide)X
+1891(well)X
+2054(de\256ned)X
+2315(interfaces)X
+2653(to)X
+2740(the)X
+2863(services)X
+3147(required)X
+3440(for)X
+3559(transaction)X
+3936(processing.)X
+555 1299(These)N
+777(services)X
+1066(are)X
+1195(recovery,)X
+1527(concurrency)X
+1955(control,)X
+2232(and)X
+2378(the)X
+2506(management)X
+2946(of)X
+3043(shared)X
+3283(data.)X
+3487(First)X
+3663(we)X
+3787(will)X
+3941(discuss)X
+4201(the)X
+555 1389(design)N
+795(tradeoffs)X
+1112(in)X
+1205(the)X
+1334(selection)X
+1650(of)X
+1748(recovery,)X
+2081(concurrency)X
+2510(control,)X
+2787(and)X
+2933(buffer)X
+3160(management)X
+3600(implementations,)X
+4183(and)X
+555 1479(then)N
+713(we)X
+827(will)X
+971(present)X
+1223(the)X
+1341(overall)X
+1584(library)X
+1818(architecture)X
+2218(and)X
+2354(module)X
+2614(descriptions.)X
+3 f
+555 1665(3.1.)N
+715(Design)X
+966(Tradeoffs)X
+1 f
+3 f
+555 1851(3.1.1.)N
+775(Crash)X
+1004(Recovery)X
+1 f
+755 1974(The)N
+909(recovery)X
+1220(protocol)X
+1516(is)X
+1598(responsible)X
+1992(for)X
+2115(providing)X
+2455(the)X
+2582(transaction)X
+2963(semantics)X
+3308(discussed)X
+3644(earlier.)X
+3919(There)X
+4136(are)X
+4263(a)X
+555 2064(wide)N
+739(range)X
+946(of)X
+1041(recovery)X
+1351(protocols)X
+1677(available)X
+1995([HAER83],)X
+2395(but)X
+2525(we)X
+2647(can)X
+2786(crudely)X
+3054(divide)X
+3281(them)X
+3468(into)X
+3619(two)X
+3766(main)X
+3953(categories.)X
+555 2154(The)N
+706(\256rst)X
+856(category)X
+1159(records)X
+1422(all)X
+1528(modi\256cations)X
+1989(to)X
+2077(the)X
+2201(database)X
+2504(in)X
+2592(a)X
+2653(separate)X
+2942(\256le,)X
+3089(and)X
+3230(uses)X
+3393(this)X
+3533(\256le)X
+3660(\(log\))X
+3841(to)X
+3928(back)X
+4105(out)X
+4232(or)X
+555 2244(reapply)N
+825(these)X
+1019(modi\256cations)X
+1483(if)X
+1561(a)X
+1626(transaction)X
+2007(aborts)X
+2232(or)X
+2328(the)X
+2455(system)X
+2706(crashes.)X
+3012(We)X
+3153(call)X
+3298(this)X
+3442(set)X
+3560(the)X
+3 f
+3687(logging)X
+3963(protocols)X
+1 f
+4279(.)X
+555 2334(The)N
+703(second)X
+949(category)X
+1249(avoids)X
+1481(the)X
+1602(use)X
+1732(of)X
+1822(a)X
+1881(log)X
+2006(by)X
+2109(carefully)X
+2418(controlling)X
+2792(when)X
+2989(data)X
+3146(are)X
+3268(written)X
+3518(to)X
+3603(disk.)X
+3799(We)X
+3934(call)X
+4073(this)X
+4210(set)X
+555 2424(the)N
+3 f
+673(non-logging)X
+1096(protocols)X
+1 f
+1412(.)X
+755 2547(Non-logging)N
+1185(protocols)X
+1504(hold)X
+1666(dirty)X
+1837(buffers)X
+2085(in)X
+2167(main)X
+2347(memory)X
+2634(or)X
+2721(temporary)X
+3071(\256les)X
+3224(until)X
+3390(commit)X
+3654(and)X
+3790(then)X
+3948(force)X
+4134(these)X
+555 2637(pages)N
+769(to)X
+862(disk)X
+1026(at)X
+1115(transaction)X
+1498(commit.)X
+1813(While)X
+2040(we)X
+2165(can)X
+2308(use)X
+2446(temporary)X
+2807(\256les)X
+2971(to)X
+3064(hold)X
+3237(dirty)X
+3418(pages)X
+3631(that)X
+3781(may)X
+3949(need)X
+4131(to)X
+4223(be)X
+555 2727(evicted)N
+810(from)X
+988(memory)X
+1277(during)X
+1508(a)X
+1566(long-running)X
+2006(transaction,)X
+2400(the)X
+2520(only)X
+2684(user-level)X
+3023(mechanism)X
+3410(to)X
+3494(force)X
+3682(pages)X
+3887(to)X
+3971(disk)X
+4126(is)X
+4201(the)X
+3 f
+555 2817(fsync)N
+1 f
+733(\(2\))X
+850(system)X
+1095(call.)X
+1274(Unfortunately,)X
+3 f
+1767(fsync)X
+1 f
+1945(\(2\))X
+2062(is)X
+2138(an)X
+2237(expensive)X
+2581(system)X
+2826(call)X
+2965(in)X
+3050(that)X
+3193(it)X
+3260(forces)X
+3480(all)X
+3583(pages)X
+3789(of)X
+3879(a)X
+3938(\256le)X
+4062(to)X
+4146(disk,)X
+555 2907(and)N
+691(transactions)X
+1094(that)X
+1234(manage)X
+1504(more)X
+1689(than)X
+1847(one)X
+1983(\256le)X
+2105(must)X
+2280(issue)X
+2460(one)X
+2596(call)X
+2732(per)X
+2855(\256le.)X
+755 3030(In)N
+853(addition,)X
+3 f
+1166(fsync)X
+1 f
+1344(\(2\))X
+1469(provides)X
+1776(no)X
+1887(way)X
+2051(to)X
+2143(control)X
+2400(the)X
+2528(order)X
+2728(in)X
+2820(which)X
+3046(dirty)X
+3227(pages)X
+3440(are)X
+3569(written)X
+3826(to)X
+3918(disk.)X
+4121(Since)X
+555 3120(non-logging)N
+976(protocols)X
+1304(must)X
+1489(sometimes)X
+1861(order)X
+2061(writes)X
+2287(carefully)X
+2603([SULL92],)X
+2987(they)X
+3155(are)X
+3284(dif\256cult)X
+3567(to)X
+3659(implement)X
+4030(on)X
+4139(Unix)X
+555 3210(systems.)N
+868(As)X
+977(a)X
+1033(result,)X
+1251(we)X
+1365(have)X
+1537(chosen)X
+1780(to)X
+1862(implement)X
+2224(a)X
+2280(logging)X
+2544(protocol.)X
+755 3333(Logging)N
+1050(protocols)X
+1372(may)X
+1534(be)X
+1634(categorized)X
+2029(based)X
+2236(on)X
+2340(how)X
+2502(information)X
+2904(is)X
+2981(logged)X
+3223(\(physically)X
+3602(or)X
+3692(logically\))X
+4022(and)X
+4161(how)X
+555 3423(much)N
+767(is)X
+854(logged)X
+1106(\(before)X
+1373(images,)X
+1654(after)X
+1836(images)X
+2097(or)X
+2198(both\).)X
+2441(In)X
+3 f
+2542(physical)X
+2855(logging)X
+1 f
+3103(,)X
+3157(images)X
+3417(of)X
+3517(complete)X
+3844(physical)X
+4144(units)X
+555 3513(\(pages)N
+786(or)X
+874(buffers\))X
+1150(are)X
+1270(recorded,)X
+1593(while)X
+1792(in)X
+3 f
+1875(logical)X
+2118(logging)X
+1 f
+2387(a)X
+2444(description)X
+2820(of)X
+2907(the)X
+3025(operation)X
+3348(is)X
+3421(recorded.)X
+3763(Therefore,)X
+4121(while)X
+555 3603(we)N
+675(may)X
+839(record)X
+1071(entire)X
+1280(pages)X
+1489(in)X
+1577(a)X
+1639(physical)X
+1932(log,)X
+2080(we)X
+2200(need)X
+2378(only)X
+2546(record)X
+2777(the)X
+2900(records)X
+3162(being)X
+3365(modi\256ed)X
+3674(in)X
+3761(a)X
+3822(logical)X
+4065(log.)X
+4232(In)X
+555 3693(fact,)N
+718(physical)X
+1006(logging)X
+1271(can)X
+1404(be)X
+1501(thought)X
+1766(of)X
+1854(as)X
+1942(a)X
+1999(special)X
+2243(case)X
+2403(of)X
+2491(logical)X
+2730(logging,)X
+3015(since)X
+3201(the)X
+3320 0.3125(``records'')AX
+3686(that)X
+3827(we)X
+3942(log)X
+4065(in)X
+4148(logi-)X
+555 3783(cal)N
+673(logging)X
+941(might)X
+1151(be)X
+1251(physical)X
+1542(pages.)X
+1789(Since)X
+1991(logical)X
+2233(logging)X
+2501(is)X
+2578(both)X
+2743(more)X
+2931(space-ef\256cient)X
+3423(and)X
+3562(more)X
+3750(general,)X
+4030(we)X
+4147(have)X
+555 3873(chosen)N
+798(it)X
+862(for)X
+976(our)X
+1103(logging)X
+1367(protocol.)X
+755 3996(In)N
+3 f
+843(before-image)X
+1315(logging)X
+1 f
+1563(,)X
+1604(we)X
+1719(log)X
+1842(a)X
+1899(copy)X
+2076(of)X
+2164(the)X
+2283(data)X
+2438(before)X
+2665(the)X
+2784(update,)X
+3039(while)X
+3238(in)X
+3 f
+3321(after-image)X
+3739(logging)X
+1 f
+3987(,)X
+4027(we)X
+4141(log)X
+4263(a)X
+555 4086(copy)N
+740(of)X
+836(the)X
+963(data)X
+1126(after)X
+1303(the)X
+1429(update.)X
+1711(If)X
+1793(we)X
+1915(log)X
+2045(only)X
+2215(before-images,)X
+2723(then)X
+2889(there)X
+3078(is)X
+3159(suf\256cient)X
+3485(information)X
+3891(in)X
+3981(the)X
+4107(log)X
+4237(to)X
+555 4176(allow)N
+761(us)X
+860(to)X
+3 f
+950(undo)X
+1 f
+1150(the)X
+1276(transaction)X
+1656(\(go)X
+1791(back)X
+1971(to)X
+2061(the)X
+2187(state)X
+2361(represented)X
+2759(by)X
+2866(the)X
+2991(before-image\).)X
+3514(However,)X
+3876(if)X
+3952(the)X
+4077(system)X
+555 4266(crashes)N
+814(and)X
+952(a)X
+1010(committed)X
+1374(transaction's)X
+1806(changes)X
+2087(have)X
+2261(not)X
+2385(reached)X
+2658(the)X
+2778(disk,)X
+2953(we)X
+3068(have)X
+3241(no)X
+3342(means)X
+3568(to)X
+3 f
+3651(redo)X
+1 f
+3828(the)X
+3947(transaction)X
+555 4356(\(reapply)N
+849(the)X
+973(updates\).)X
+1311(Therefore,)X
+1675(logging)X
+1945(only)X
+2113(before-images)X
+2599(necessitates)X
+3004(forcing)X
+3262(dirty)X
+3439(pages)X
+3648(at)X
+3732(commit)X
+4002(time.)X
+4210(As)X
+555 4446(mentioned)N
+913(above,)X
+1145(forcing)X
+1397(pages)X
+1600(at)X
+1678(commit)X
+1942(is)X
+2015(considered)X
+2383(too)X
+2505(costly.)X
+755 4569(If)N
+834(we)X
+953(log)X
+1080(only)X
+1247(after-images,)X
+1694(then)X
+1857(there)X
+2043(is)X
+2121(suf\256cient)X
+2444(information)X
+2847(in)X
+2934(the)X
+3057(log)X
+3184(to)X
+3271(allow)X
+3474(us)X
+3570(to)X
+3657(redo)X
+3825(the)X
+3947(transaction)X
+555 4659(\(go)N
+687(forward)X
+967(to)X
+1054(the)X
+1177(state)X
+1348(represented)X
+1743(by)X
+1847(the)X
+1969(after-image\),)X
+2411(but)X
+2537(we)X
+2655(do)X
+2759(not)X
+2885(have)X
+3061(the)X
+3183(information)X
+3585(required)X
+3877(to)X
+3963(undo)X
+4147(tran-)X
+555 4749(sactions)N
+845(which)X
+1073(aborted)X
+1346(after)X
+1526(dirty)X
+1709(pages)X
+1924(were)X
+2113(written)X
+2372(to)X
+2466(disk.)X
+2670(Therefore,)X
+3039(logging)X
+3314(only)X
+3487(after-images)X
+3920(necessitates)X
+555 4839(holding)N
+819(all)X
+919(dirty)X
+1090(buffers)X
+1338(in)X
+1420(main)X
+1600(memory)X
+1887(until)X
+2053(commit)X
+2317(or)X
+2404(writing)X
+2655(them)X
+2835(to)X
+2917(a)X
+2973(temporary)X
+3323(\256le.)X
+755 4962(Since)N
+956(neither)X
+1202(constraint)X
+1541(\(forcing)X
+1823(pages)X
+2029(on)X
+2132(commit)X
+2399(or)X
+2489(buffering)X
+2811(pages)X
+3016(until)X
+3184(commit\))X
+3477(was)X
+3624(feasible,)X
+3916(we)X
+4032(chose)X
+4237(to)X
+555 5052(log)N
+683(both)X
+851(before)X
+1083(and)X
+1225(after)X
+1399(images.)X
+1672(The)X
+1823(only)X
+1991(remaining)X
+2342(consideration)X
+2800(is)X
+2879(when)X
+3079(changes)X
+3363(get)X
+3486(written)X
+3738(to)X
+3825(disk.)X
+4023(Changes)X
+555 5142(affect)N
+764(both)X
+931(data)X
+1090(pages)X
+1298(and)X
+1438(the)X
+1560(log.)X
+1726(If)X
+1804(the)X
+1926(changed)X
+2218(data)X
+2376(page)X
+2552(is)X
+2629(written)X
+2880(before)X
+3110(the)X
+3232(log)X
+3358(page,)X
+3554(and)X
+3694(the)X
+3816(system)X
+4062(crashes)X
+555 5232(before)N
+787(the)X
+911(log)X
+1039(page)X
+1217(is)X
+1296(written,)X
+1569(the)X
+1693(log)X
+1820(will)X
+1969(contain)X
+2230(insuf\256cient)X
+2615(information)X
+3018(to)X
+3105(undo)X
+3290(the)X
+3413(change.)X
+3706(This)X
+3873(violates)X
+4147(tran-)X
+555 5322(saction)N
+803(semantics,)X
+1160(since)X
+1346(some)X
+1536(changed)X
+1825(data)X
+1980(pages)X
+2184(may)X
+2343(not)X
+2466(have)X
+2638(been)X
+2810(written,)X
+3077(and)X
+3213(the)X
+3331(database)X
+3628(cannot)X
+3862(be)X
+3958(restored)X
+4237(to)X
+555 5412(its)N
+650(pre-transaction)X
+1152(state.)X
+755 5535(The)N
+914(log)X
+1050(record)X
+1290(describing)X
+1658(an)X
+1768(update)X
+2016(must)X
+2205(be)X
+2315(written)X
+2576(to)X
+2672(stable)X
+2893(storage)X
+3159(before)X
+3398(the)X
+3529(modi\256ed)X
+3846(page.)X
+4071(This)X
+4246(is)X
+3 f
+555 5625(write-ahead)N
+992(logging)X
+1 f
+1240(.)X
+1307(If)X
+1388(log)X
+1517(records)X
+1781(are)X
+1907(safely)X
+2126(written)X
+2380(to)X
+2469(disk,)X
+2649(data)X
+2810(pages)X
+3020(may)X
+3185(be)X
+3288(written)X
+3542(at)X
+3627(any)X
+3770(time)X
+3939(afterwards.)X
+555 5715(This)N
+721(means)X
+950(that)X
+1094(the)X
+1216(only)X
+1382(\256le)X
+1508(that)X
+1652(ever)X
+1815(needs)X
+2022(to)X
+2108(be)X
+2208(forced)X
+2438(to)X
+2524(disk)X
+2681(is)X
+2758(the)X
+2880(log.)X
+3046(Since)X
+3248(the)X
+3370(log)X
+3495(is)X
+3571(append-only,)X
+4015(modi\256ed)X
+
+4 p
+%%Page: 4 4
+10 s 10 xH 0 xS 1 f
+3 f
+1 f
+555 630(pages)N
+760(always)X
+1005(appear)X
+1242(at)X
+1322(the)X
+1442(end)X
+1580(and)X
+1718(may)X
+1878(be)X
+1976(written)X
+2224(to)X
+2307(disk)X
+2461(ef\256ciently)X
+2807(in)X
+2890(any)X
+3027(\256le)X
+3150(system)X
+3393(that)X
+3534(favors)X
+3756(sequential)X
+4102(order-)X
+555 720(ing)N
+677(\()X
+2 f
+704(e.g.)X
+1 f
+820(,)X
+860(FFS,)X
+1032(log-structured)X
+1502(\256le)X
+1624(system,)X
+1886(or)X
+1973(an)X
+2069(extent-based)X
+2495(system\).)X
+3 f
+555 906(3.1.2.)N
+775(Concurrency)X
+1245(Control)X
+1 f
+755 1029(The)N
+918(concurrency)X
+1354(control)X
+1619(protocol)X
+1923(is)X
+2013(responsible)X
+2415(for)X
+2546(maintaining)X
+2965(consistency)X
+3376(in)X
+3475(the)X
+3610(presence)X
+3929(of)X
+4033(multiple)X
+555 1119(accesses.)N
+897(There)X
+1114(are)X
+1242(several)X
+1499(alternative)X
+1867(solutions)X
+2183(such)X
+2358(as)X
+2453(locking,)X
+2741(optimistic)X
+3088(concurrency)X
+3514(control)X
+3769([KUNG81],)X
+4183(and)X
+555 1209(timestamp)N
+912(ordering)X
+1208([BERN80].)X
+1619(Since)X
+1821(optimistic)X
+2164(methods)X
+2459(and)X
+2599(timestamp)X
+2956(ordering)X
+3252(are)X
+3374(generally)X
+3696(more)X
+3884(complex)X
+4183(and)X
+555 1299(restrict)N
+804(concurrency)X
+1228(without)X
+1498(eliminating)X
+1888(starvation)X
+2230(or)X
+2323(deadlocks,)X
+2690(we)X
+2810(chose)X
+3018(two-phase)X
+3373(locking)X
+3638(\(2PL\).)X
+3890(Strict)X
+4088(2PL)X
+4246(is)X
+555 1389(suboptimal)N
+935(for)X
+1054(certain)X
+1297(data)X
+1455(structures)X
+1791(such)X
+1962(as)X
+2053(B-trees)X
+2309(because)X
+2588(it)X
+2656(can)X
+2792(limit)X
+2966(concurrency,)X
+3408(so)X
+3503(we)X
+3621(use)X
+3752(a)X
+3812(special)X
+4059(locking)X
+555 1479(protocol)N
+842(based)X
+1045(on)X
+1145(one)X
+1281(described)X
+1609(in)X
+1691([LEHM81].)X
+755 1602(The)N
+901(B-tree)X
+1123(locking)X
+1384(protocol)X
+1672(we)X
+1787(implemented)X
+2226(releases)X
+2502(locks)X
+2691(at)X
+2769(internal)X
+3034(nodes)X
+3241(in)X
+3323(the)X
+3441(tree)X
+3582(as)X
+3669(it)X
+3733(descends.)X
+4083(A)X
+4161(lock)X
+555 1692(on)N
+658(an)X
+757(internal)X
+1025(page)X
+1200(is)X
+1276(always)X
+1522(released)X
+1808(before)X
+2036(a)X
+2094(lock)X
+2254(on)X
+2356(its)X
+2453(child)X
+2635(is)X
+2710(obtained)X
+3008(\(that)X
+3177(is,)X
+3272(locks)X
+3463(are)X
+3584(not)X
+3 f
+3708(coupled)X
+1 f
+3996([BAY77])X
+555 1782(during)N
+786(descent\).)X
+1116(When)X
+1330(a)X
+1388(leaf)X
+1531(\(or)X
+1647(internal\))X
+1941(page)X
+2115(is)X
+2190(split,)X
+2369(a)X
+2427(write)X
+2614(lock)X
+2774(is)X
+2849(acquired)X
+3148(on)X
+3250(the)X
+3370(parent)X
+3593(before)X
+3821(the)X
+3941(lock)X
+4100(on)X
+4201(the)X
+555 1872(just-split)N
+855(page)X
+1028(is)X
+1102(released)X
+1387(\(locks)X
+1604(are)X
+3 f
+1724(coupled)X
+1 f
+2011(during)X
+2241(ascent\).)X
+2530(Write)X
+2734(locks)X
+2924(on)X
+3025(internal)X
+3291(pages)X
+3495(are)X
+3615(released)X
+3899(immediately)X
+555 1962(after)N
+723(the)X
+841(page)X
+1013(is)X
+1086(updated,)X
+1380(but)X
+1502(locks)X
+1691(on)X
+1791(leaf)X
+1932(pages)X
+2135(are)X
+2254(held)X
+2412(until)X
+2578(the)X
+2696(end)X
+2832(of)X
+2919(the)X
+3037(transaction.)X
+755 2085(Since)N
+964(locks)X
+1164(are)X
+1294(released)X
+1589(during)X
+1828(descent,)X
+2119(the)X
+2247(structure)X
+2558(of)X
+2655(the)X
+2783(tree)X
+2934(may)X
+3102(change)X
+3360(above)X
+3582(a)X
+3648(node)X
+3834(being)X
+4042(used)X
+4219(by)X
+555 2175(some)N
+752(process.)X
+1061(If)X
+1143(that)X
+1291(process)X
+1560(must)X
+1743(later)X
+1914(ascend)X
+2161(the)X
+2287(tree)X
+2435(because)X
+2717(of)X
+2811(a)X
+2874(page)X
+3053(split,)X
+3237(any)X
+3380(such)X
+3554(change)X
+3809(must)X
+3991(not)X
+4120(cause)X
+555 2265(confusion.)N
+938(We)X
+1077(use)X
+1211(the)X
+1336(technique)X
+1675(described)X
+2010(in)X
+2099([LEHM81])X
+2487(which)X
+2710(exploits)X
+2989(the)X
+3113(ordering)X
+3411(of)X
+3504(data)X
+3664(on)X
+3770(a)X
+3832(B-tree)X
+4059(page)X
+4237(to)X
+555 2355(guarantee)N
+888(that)X
+1028(no)X
+1128(process)X
+1389(ever)X
+1548(gets)X
+1697(lost)X
+1832(as)X
+1919(a)X
+1975(result)X
+2173(of)X
+2260(internal)X
+2525(page)X
+2697(updates)X
+2962(made)X
+3156(by)X
+3256(other)X
+3441(processes.)X
+755 2478(If)N
+836(a)X
+899(transaction)X
+1278(that)X
+1425(updates)X
+1697(a)X
+1760(B-tree)X
+1988(aborts,)X
+2231(the)X
+2356(user-visible)X
+2757(changes)X
+3043(to)X
+3131(the)X
+3255(tree)X
+3402(must)X
+3583(be)X
+3685(rolled)X
+3898(back.)X
+4116(How-)X
+555 2568(ever,)N
+735(changes)X
+1015(to)X
+1097(the)X
+1215(internal)X
+1480(nodes)X
+1687(of)X
+1774(the)X
+1892(tree)X
+2033(need)X
+2205(not)X
+2327(be)X
+2423(rolled)X
+2630(back,)X
+2822(since)X
+3007(these)X
+3192(pages)X
+3395(contain)X
+3651(no)X
+3751(user-visible)X
+4145(data.)X
+555 2658(When)N
+771(rolling)X
+1008(back)X
+1184(a)X
+1244(transaction,)X
+1640(we)X
+1758(roll)X
+1893(back)X
+2069(all)X
+2173(leaf)X
+2318(page)X
+2494(updates,)X
+2783(but)X
+2909(no)X
+3013(internal)X
+3281(insertions)X
+3615(or)X
+3705(page)X
+3880(splits.)X
+4111(In)X
+4201(the)X
+555 2748(worst)N
+759(case,)X
+944(this)X
+1085(will)X
+1235(leave)X
+1431(a)X
+1493(leaf)X
+1640(page)X
+1818(less)X
+1964(than)X
+2128(half)X
+2279(full.)X
+2456(This)X
+2624(may)X
+2788(cause)X
+2993(poor)X
+3166(space)X
+3371(utilization,)X
+3741(but)X
+3869(does)X
+4042(not)X
+4170(lose)X
+555 2838(user)N
+709(data.)X
+755 2961(Holding)N
+1038(locks)X
+1228(on)X
+1329(leaf)X
+1471(pages)X
+1675(until)X
+1842(transaction)X
+2215(commit)X
+2480(guarantees)X
+2845(that)X
+2986(no)X
+3087(other)X
+3273(process)X
+3535(can)X
+3668(insert)X
+3866(or)X
+3953(delete)X
+4165(data)X
+555 3051(that)N
+711(has)X
+854(been)X
+1042(touched)X
+1332(by)X
+1448(this)X
+1598(process.)X
+1914(Rolling)X
+2188(back)X
+2375(insertions)X
+2721(and)X
+2872(deletions)X
+3196(on)X
+3311(leaf)X
+3467(pages)X
+3685(guarantees)X
+4064(that)X
+4219(no)X
+555 3141(aborted)N
+819(updates)X
+1087(are)X
+1209(ever)X
+1371(visible)X
+1607(to)X
+1692(other)X
+1880(transactions.)X
+2326(Leaving)X
+2612(page)X
+2787(splits)X
+2978(intact)X
+3179(permits)X
+3442(us)X
+3536(to)X
+3621(release)X
+3867(internal)X
+4134(write)X
+555 3231(locks)N
+744(early.)X
+965(Thus)X
+1145(transaction)X
+1517(semantics)X
+1853(are)X
+1972(preserved,)X
+2325(and)X
+2461(locks)X
+2650(are)X
+2769(held)X
+2927(for)X
+3041(shorter)X
+3284(periods.)X
+755 3354(The)N
+901(extra)X
+1083(complexity)X
+1464(introduced)X
+1828(by)X
+1929(this)X
+2065(locking)X
+2326(protocol)X
+2614(appears)X
+2881(substantial,)X
+3264(but)X
+3387(it)X
+3452(is)X
+3525(important)X
+3856(for)X
+3970(multi-user)X
+555 3444(execution.)N
+950(The)X
+1118(bene\256ts)X
+1410(of)X
+1520(non-two-phase)X
+2040(locking)X
+2323(on)X
+2446(B-trees)X
+2721(are)X
+2863(well)X
+3044(established)X
+3443(in)X
+3548(the)X
+3689(database)X
+4009(literature)X
+555 3534([BAY77],)N
+899([LEHM81].)X
+1320(If)X
+1394(a)X
+1450(process)X
+1711(held)X
+1869(locks)X
+2058(until)X
+2224(it)X
+2288(committed,)X
+2670(then)X
+2828(a)X
+2884(long-running)X
+3322(update)X
+3556(could)X
+3754(lock)X
+3912(out)X
+4034(all)X
+4134(other)X
+555 3624(transactions)N
+967(by)X
+1076(preventing)X
+1448(any)X
+1593(other)X
+1787(process)X
+2057(from)X
+2241(locking)X
+2509(the)X
+2635(root)X
+2792(page)X
+2972(of)X
+3067(the)X
+3193(tree.)X
+3382(The)X
+3535(B-tree)X
+3764(locking)X
+4032(protocol)X
+555 3714(described)N
+884(above)X
+1096(guarantees)X
+1460(that)X
+1600(locks)X
+1789(on)X
+1889(internal)X
+2154(pages)X
+2357(are)X
+2476(held)X
+2634(for)X
+2748(extremely)X
+3089(short)X
+3269(periods,)X
+3545(thereby)X
+3806(increasing)X
+4156(con-)X
+555 3804(currency.)N
+3 f
+555 3990(3.1.3.)N
+775(Management)X
+1245(of)X
+1332(Shared)X
+1596(Data)X
+1 f
+755 4113(Database)N
+1075(systems)X
+1353(permit)X
+1587(many)X
+1790(users)X
+1980(to)X
+2067(examine)X
+2364(and)X
+2505(update)X
+2744(the)X
+2866(same)X
+3055(data)X
+3213(concurrently.)X
+3683(In)X
+3774(order)X
+3968(to)X
+4054(provide)X
+555 4203(this)N
+702(concurrent)X
+1078(access)X
+1316(and)X
+1464(enforce)X
+1738(the)X
+1868(write-ahead)X
+2280(logging)X
+2556(protocol)X
+2855(described)X
+3195(in)X
+3289(section)X
+3548(3.1.1,)X
+3759(we)X
+3884(use)X
+4022(a)X
+4089(shared)X
+555 4293(memory)N
+848(buffer)X
+1071(manager.)X
+1414(Not)X
+1559(only)X
+1726(does)X
+1898(this)X
+2038(provide)X
+2308(the)X
+2431(guarantees)X
+2800(we)X
+2919(require,)X
+3192(but)X
+3319(a)X
+3380(user-level)X
+3722(buffer)X
+3944(manager)X
+4246(is)X
+555 4383(frequently)N
+916(faster)X
+1126(than)X
+1295(using)X
+1498(the)X
+1626(\256le)X
+1758(system)X
+2010(buffer)X
+2237(cache.)X
+2491(Reads)X
+2717(or)X
+2814(writes)X
+3040(involving)X
+3376(the)X
+3504(\256le)X
+3636(system)X
+3888(buffer)X
+4115(cache)X
+555 4473(often)N
+746(require)X
+1000(copying)X
+1284(data)X
+1444(between)X
+1738(user)X
+1898(and)X
+2040(kernel)X
+2266(space)X
+2470(while)X
+2673(a)X
+2734(user-level)X
+3076(buffer)X
+3298(manager)X
+3600(can)X
+3737(return)X
+3954(pointers)X
+4237(to)X
+555 4563(data)N
+709(pages)X
+912(directly.)X
+1217(Additionally,)X
+1661(if)X
+1730(more)X
+1915(than)X
+2073(one)X
+2209(process)X
+2470(uses)X
+2628(the)X
+2746(same)X
+2931(page,)X
+3123(then)X
+3281(fewer)X
+3485(copies)X
+3710(may)X
+3868(be)X
+3964(required.)X
+3 f
+555 4749(3.2.)N
+715(Module)X
+997(Architecture)X
+1 f
+755 4872(The)N
+913(preceding)X
+1262(sections)X
+1552(described)X
+1892(modules)X
+2195(for)X
+2321(managing)X
+2669(the)X
+2799(transaction)X
+3183(log,)X
+3337(locks,)X
+3558(and)X
+3706(a)X
+3774(cache)X
+3990(of)X
+4089(shared)X
+555 4962(buffers.)N
+847(In)X
+938(addition,)X
+1244(we)X
+1362(need)X
+1538(to)X
+1624(provide)X
+1893(functionality)X
+2326(for)X
+2444(transaction)X
+2 f
+2819(begin)X
+1 f
+2997(,)X
+2 f
+3040(commit)X
+1 f
+3276(,)X
+3319(and)X
+2 f
+3458(abort)X
+1 f
+3654(processing,)X
+4040(necessi-)X
+555 5052(tating)N
+769(a)X
+837(transaction)X
+1221(manager.)X
+1570(In)X
+1669(order)X
+1871(to)X
+1965(arbitrate)X
+2265(concurrent)X
+2641(access)X
+2879(to)X
+2973(locks)X
+3173(and)X
+3320(buffers,)X
+3599(we)X
+3724(include)X
+3991(a)X
+4058(process)X
+555 5142(management)N
+995(module)X
+1264(which)X
+1489(manages)X
+1799(a)X
+1864(collection)X
+2209(of)X
+2305(semaphores)X
+2713(used)X
+2889(to)X
+2980(block)X
+3187(and)X
+3332(release)X
+3585(processes.)X
+3962(Finally,)X
+4237(in)X
+555 5232(order)N
+752(to)X
+841(provide)X
+1113(a)X
+1176(simple,)X
+1436(standard)X
+1735(interface)X
+2044(we)X
+2165(have)X
+2344(modi\256ed)X
+2655(the)X
+2780(database)X
+3084(access)X
+3317(routines)X
+3602(\()X
+3 f
+3629(db)X
+1 f
+3717(\(3\)\).)X
+3904(For)X
+4041(the)X
+4165(pur-)X
+555 5322(poses)N
+758(of)X
+850(this)X
+990(paper)X
+1194(we)X
+1313(call)X
+1453(the)X
+1575(modi\256ed)X
+1883(package)X
+2171(the)X
+3 f
+2293(Record)X
+2567(Manager)X
+1 f
+2879(.)X
+2943(Figure)X
+3176(one)X
+3316(shows)X
+3540(the)X
+3662(main)X
+3846(interfaces)X
+4183(and)X
+555 5412(architecture)N
+955(of)X
+1042(LIBTP.)X
+
+5 p
+%%Page: 5 5
+10 s 10 xH 0 xS 1 f
+3 f
+1 f
+11 s
+1851 1520(log_commit)N
+2764 2077(buf_unpin)N
+2764 1987(buf_get)N
+3633 1408(buf_unpin)N
+3633 1319(buf_pin)N
+3633 1230(buf_get)N
+3 f
+17 s
+1163 960(Txn)N
+1430(M)X
+1559(anager)X
+2582(Record)X
+3040(M)X
+3169(anager)X
+1 Dt
+2363 726 MXY
+0 355 Dl
+1426 0 Dl
+0 -355 Dl
+-1426 0 Dl
+3255 1616 MXY
+0 535 Dl
+534 0 Dl
+0 -535 Dl
+-534 0 Dl
+2185 MX
+0 535 Dl
+535 0 Dl
+0 -535 Dl
+-535 0 Dl
+1116 MX
+0 535 Dl
+534 0 Dl
+0 -535 Dl
+-534 0 Dl
+726 MY
+0 355 Dl
+891 0 Dl
+0 -355 Dl
+-891 0 Dl
+1 f
+11 s
+2207 1297(lock)N
+2564 1386(log)N
+865(unlock_all)X
+1851 1609(log_unroll)N
+1650 2508 MXY
+0 178 Dl
+1605 0 Dl
+0 -178 Dl
+-1605 0 Dl
+1294 1616 MXY
+19 -30 Dl
+-19 11 Dl
+-20 -11 Dl
+20 30 Dl
+0 -535 Dl
+2319 2508 MXY
+-22 -30 Dl
+4 23 Dl
+-18 14 Dl
+36 -7 Dl
+-936 -357 Dl
+3277 2455(sleep_on)N
+1405 1616 MXY
+36 4 Dl
+-18 -13 Dl
+1 -22 Dl
+-19 31 Dl
+1070 -535 Dl
+2631 2508 MXY
+36 6 Dl
+-18 -14 Dl
+3 -22 Dl
+-21 30 Dl
+891 -357 Dl
+1426 2455(sleep_on)N
+3255 1884 MXY
+-31 -20 Dl
+11 20 Dl
+-11 19 Dl
+31 -19 Dl
+-535 0 Dl
+1554 2366(wake)N
+3277(wake)X
+2185 1884 MXY
+-31 -20 Dl
+12 20 Dl
+-12 19 Dl
+31 -19 Dl
+-356 0 Dl
+0 -803 Dl
+3 f
+17 s
+1236 1851(Lock)N
+1118 2030(M)N
+1247(anager)X
+2339 1851(Log)N
+2187 2030(M)N
+2316(anager)X
+3333 1851(Buffer)N
+3257 2030(M)N
+3386(anager)X
+3522 1616 MXY
+20 -30 Dl
+-20 11 Dl
+-20 -11 Dl
+20 30 Dl
+0 -535 Dl
+1950 2654(Process)N
+2424(M)X
+2553(anager)X
+2542 1616 MXY
+19 -30 Dl
+-19 11 Dl
+-20 -11 Dl
+20 30 Dl
+0 -535 Dl
+1 f
+11 s
+2207 1364(unlock)N
+2452 2508 MXY
+20 -31 Dl
+-20 11 Dl
+-19 -11 Dl
+19 31 Dl
+0 -357 Dl
+2497 2322(sleep_on)N
+2497 2233(wake)N
+3 Dt
+-1 Ds
+3 f
+10 s
+1790 2830(Figure)N
+2037(1:)X
+2144(Library)X
+2435(module)X
+2708(interfaces.)X
+1 f
+10 f
+555 3010(h)N
+579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X
+3 f
+555 3286(3.2.1.)N
+775(The)X
+928(Log)X
+1081(Manager)X
+1 f
+755 3409(The)N
+3 f
+907(Log)X
+1067(Manager)X
+1 f
+1406(enforces)X
+1706(the)X
+1831(write-ahead)X
+2238(logging)X
+2509(protocol.)X
+2843(Its)X
+2949(primitive)X
+3268(operations)X
+3628(are)X
+2 f
+3753(log)X
+1 f
+3855(,)X
+2 f
+3901(log_commit)X
+1 f
+4279(,)X
+2 f
+555 3499(log_read)N
+1 f
+844(,)X
+2 f
+889(log_roll)X
+1 f
+1171(and)X
+2 f
+1312(log_unroll)X
+1 f
+1649(.)X
+1714(The)X
+2 f
+1864(log)X
+1 f
+1991(call)X
+2132(performs)X
+2447(a)X
+2508(buffered)X
+2806(write)X
+2996(of)X
+3088(the)X
+3211(speci\256ed)X
+3520(log)X
+3646(record)X
+3876(and)X
+4016(returns)X
+4263(a)X
+555 3589(unique)N
+809(log)X
+947(sequence)X
+1278(number)X
+1559(\(LSN\).)X
+1840(This)X
+2017(LSN)X
+2203(may)X
+2376(then)X
+2549(be)X
+2660(used)X
+2842(to)X
+2939(retrieve)X
+3220(a)X
+3291(record)X
+3532(from)X
+3723(the)X
+3856(log)X
+3993(using)X
+4201(the)X
+2 f
+555 3679(log_read)N
+1 f
+865(call.)X
+1042(The)X
+2 f
+1188(log)X
+1 f
+1311(interface)X
+1614(knows)X
+1844(very)X
+2008(little)X
+2175(about)X
+2374(the)X
+2493(internal)X
+2759(format)X
+2993(of)X
+3080(the)X
+3198(log)X
+3320(records)X
+3577(it)X
+3641(receives.)X
+3965(Rather,)X
+4219(all)X
+555 3769(log)N
+681(records)X
+942(are)X
+1065 0.4028(referenced)AX
+1430(by)X
+1534(a)X
+1594(header)X
+1833(structure,)X
+2158(a)X
+2218(log)X
+2344(record)X
+2574(type,)X
+2756(and)X
+2896(a)X
+2956(character)X
+3276(buffer)X
+3497(containing)X
+3859(the)X
+3981(data)X
+4138(to)X
+4223(be)X
+555 3859(logged.)N
+834(The)X
+980(log)X
+1103(record)X
+1330(type)X
+1489(is)X
+1563(used)X
+1731(to)X
+1814(call)X
+1951(the)X
+2070(appropriate)X
+2457(redo)X
+2621(and)X
+2758(undo)X
+2939(routines)X
+3217(during)X
+2 f
+3446(abort)X
+1 f
+3639(and)X
+2 f
+3775(commit)X
+1 f
+4031(process-)X
+555 3949(ing.)N
+721(While)X
+941(we)X
+1059(have)X
+1235(used)X
+1406(the)X
+3 f
+1528(Log)X
+1684(Manager)X
+1 f
+2019(to)X
+2104(provide)X
+2372(before)X
+2601(and)X
+2740(after)X
+2911(image)X
+3130(logging,)X
+3417(it)X
+3484(may)X
+3645(also)X
+3797(be)X
+3896(used)X
+4066(for)X
+4183(any)X
+555 4039(of)N
+642(the)X
+760(logging)X
+1024(algorithms)X
+1386(discussed.)X
+755 4162(The)N
+2 f
+905(log_commit)X
+1 f
+1308(operation)X
+1636(behaves)X
+1920(exactly)X
+2177(like)X
+2322(the)X
+2 f
+2445(log)X
+1 f
+2572(operation)X
+2900(but)X
+3026(guarantees)X
+3394(that)X
+3538(the)X
+3660(log)X
+3786(has)X
+3917(been)X
+4093(forced)X
+555 4252(to)N
+643(disk)X
+802(before)X
+1034(returning.)X
+1394(A)X
+1478(discussion)X
+1837(of)X
+1930(our)X
+2063(commit)X
+2333(strategy)X
+2613(appears)X
+2884(in)X
+2971(the)X
+3094(implementation)X
+3621(section)X
+3873(\(section)X
+4152(4.2\).)X
+2 f
+555 4342(Log_unroll)N
+1 f
+935(reads)X
+1126(log)X
+1249(records)X
+1507(from)X
+1684(the)X
+1803(log,)X
+1946(following)X
+2278(backward)X
+2611(transaction)X
+2983(pointers)X
+3261(and)X
+3397(calling)X
+3635(the)X
+3753(appropriate)X
+4139(undo)X
+555 4432(routines)N
+839(to)X
+927(implement)X
+1295(transaction)X
+1673(abort.)X
+1904(In)X
+1997(a)X
+2059(similar)X
+2307(manner,)X
+2 f
+2594(log_roll)X
+1 f
+2877(reads)X
+3073(log)X
+3201(records)X
+3464(sequentially)X
+3877(forward,)X
+4178(cal-)X
+555 4522(ling)N
+699(the)X
+817(appropriate)X
+1203(redo)X
+1366(routines)X
+1644(to)X
+1726(recover)X
+1988(committed)X
+2350(transactions)X
+2753(after)X
+2921(a)X
+2977(system)X
+3219(crash.)X
+3 f
+555 4708(3.2.2.)N
+775(The)X
+928(Buffer)X
+1171(Manager)X
+1 f
+755 4831(The)N
+3 f
+912(Buffer)X
+1167(Manager)X
+1 f
+1511(uses)X
+1681(a)X
+1749(pool)X
+1923(of)X
+2022(shared)X
+2264(memory)X
+2563(to)X
+2657(provide)X
+2934(a)X
+3002(least-recently-used)X
+3641(\(LRU\))X
+3886(block)X
+4095(cache.)X
+555 4921(Although)N
+886(the)X
+1013(current)X
+1270(library)X
+1513(provides)X
+1818(an)X
+1923(LRU)X
+2112(cache,)X
+2345(it)X
+2418(would)X
+2647(be)X
+2752(simple)X
+2994(to)X
+3085(add)X
+3229(alternate)X
+3534(replacement)X
+3955(policies)X
+4232(as)X
+555 5011(suggested)N
+903(by)X
+1015([CHOU85])X
+1408(or)X
+1507(to)X
+1601(provide)X
+1878(multiple)X
+2176(buffer)X
+2405(pools)X
+2610(with)X
+2784(different)X
+3092(policies.)X
+3412(Transactions)X
+3853(request)X
+4116(pages)X
+555 5101(from)N
+736(the)X
+859(buffer)X
+1081(manager)X
+1383(and)X
+1524(keep)X
+1701(them)X
+3 f
+1886(pinned)X
+1 f
+2145(to)X
+2232(ensure)X
+2466(that)X
+2610(they)X
+2772(are)X
+2895(not)X
+3021(written)X
+3272(to)X
+3358(disk)X
+3515(while)X
+3717(they)X
+3879(are)X
+4002(in)X
+4088(a)X
+4148(logi-)X
+555 5191(cally)N
+732(inconsistent)X
+1135(state.)X
+1343(When)X
+1556(page)X
+1729(replacement)X
+2143(is)X
+2217(necessary,)X
+2571(the)X
+3 f
+2689(Buffer)X
+2932(Manager)X
+1 f
+3264(\256nds)X
+3439(an)X
+3535(unpinned)X
+3853(page)X
+4025(and)X
+4161(then)X
+555 5281(checks)N
+794(with)X
+956(the)X
+3 f
+1074(Log)X
+1227(Manager)X
+1 f
+1559(to)X
+1641(ensure)X
+1871(that)X
+2011(the)X
+2129(write-ahead)X
+2529(protocol)X
+2816(is)X
+2889(enforced.)X
+3 f
+555 5467(3.2.3.)N
+775(The)X
+928(Lock)X
+1121(Manager)X
+1 f
+755 5590(The)N
+3 f
+901(Lock)X
+1095(Manager)X
+1 f
+1428(supports)X
+1720(general)X
+1978(purpose)X
+2253(locking)X
+2514(\(single)X
+2753(writer,)X
+2986(multiple)X
+3273(readers\))X
+3553(which)X
+3769(is)X
+3842(currently)X
+4152(used)X
+555 5680(to)N
+638(provide)X
+904(two-phase)X
+1254(locking)X
+1514(and)X
+1650(high)X
+1812(concurrency)X
+2230(B-tree)X
+2451(locking.)X
+2751(However,)X
+3086(the)X
+3204(general)X
+3461(purpose)X
+3735(nature)X
+3956(of)X
+4043(the)X
+4161(lock)X
+
+6 p
+%%Page: 6 6
+10 s 10 xH 0 xS 1 f
+3 f
+1 f
+555 630(manager)N
+857(provides)X
+1158(the)X
+1281(ability)X
+1510(to)X
+1597(support)X
+1862(a)X
+1923(variety)X
+2171(of)X
+2263(locking)X
+2528(protocols.)X
+2890(Currently,)X
+3241(all)X
+3345(locks)X
+3538(are)X
+3661(issued)X
+3885(at)X
+3967(the)X
+4089(granu-)X
+555 720(larity)N
+747(of)X
+837(a)X
+896(page)X
+1071(\(the)X
+1219(size)X
+1367(of)X
+1457(a)X
+1516(buffer)X
+1736(in)X
+1821(the)X
+1942(buffer)X
+2161(pool\))X
+2352(which)X
+2570(is)X
+2645(identi\256ed)X
+2969(by)X
+3071(two)X
+3213(4-byte)X
+3440(integers)X
+3716(\(a)X
+3801(\256le)X
+3925(id)X
+4009(and)X
+4147(page)X
+555 810(number\).)N
+898(This)X
+1071(provides)X
+1378(the)X
+1507(necessary)X
+1851(information)X
+2259(to)X
+2351(extend)X
+2595(the)X
+3 f
+2723(Lock)X
+2926(Manager)X
+1 f
+3268(to)X
+3360(perform)X
+3649(hierarchical)X
+4059(locking)X
+555 900([GRAY76].)N
+982(The)X
+1133(current)X
+1387(implementation)X
+1915(does)X
+2088(not)X
+2216(support)X
+2482(locks)X
+2677(at)X
+2760(other)X
+2950(granularities)X
+3376(and)X
+3517(does)X
+3689(not)X
+3816(promote)X
+4108(locks;)X
+555 990(these)N
+740(are)X
+859(obvious)X
+1132(future)X
+1344(additions)X
+1657(to)X
+1739(the)X
+1857(system.)X
+755 1113(If)N
+831(an)X
+929(incoming)X
+1253(lock)X
+1413(request)X
+1667(cannot)X
+1903(be)X
+2001(granted,)X
+2284(the)X
+2404(requesting)X
+2760(process)X
+3023(is)X
+3098(queued)X
+3352(for)X
+3467(the)X
+3586(lock)X
+3745(and)X
+3882(descheduled.)X
+555 1203(When)N
+769(a)X
+827(lock)X
+987(is)X
+1062(released,)X
+1368(the)X
+1488(wait)X
+1647(queue)X
+1860(is)X
+1934(traversed)X
+2250(and)X
+2387(any)X
+2524(newly)X
+2741(compatible)X
+3118(locks)X
+3308(are)X
+3428(granted.)X
+3730(Locks)X
+3947(are)X
+4067(located)X
+555 1293(via)N
+680(a)X
+743(\256le)X
+872(and)X
+1015(page)X
+1194(hash)X
+1368(table)X
+1551(and)X
+1694(are)X
+1820(chained)X
+2097(both)X
+2266(by)X
+2373(object)X
+2595(and)X
+2737(by)X
+2843(transaction,)X
+3241(facilitating)X
+3614(rapid)X
+3805(traversal)X
+4108(of)X
+4201(the)X
+555 1383(lock)N
+713(table)X
+889(during)X
+1118(transaction)X
+1490(commit)X
+1754(and)X
+1890(abort.)X
+755 1506(The)N
+907(primary)X
+1188(interfaces)X
+1528(to)X
+1617(the)X
+1742(lock)X
+1907(manager)X
+2211(are)X
+2 f
+2337(lock)X
+1 f
+2471(,)X
+2 f
+2518(unlock)X
+1 f
+2732(,)X
+2779(and)X
+2 f
+2922(lock_unlock_all)X
+1 f
+3434(.)X
+2 f
+3500(Lock)X
+1 f
+3682(obtains)X
+3939(a)X
+4001(new)X
+4161(lock)X
+555 1596(for)N
+680(a)X
+747(speci\256c)X
+1023(object.)X
+1290(There)X
+1509(are)X
+1638(also)X
+1797(two)X
+1947(variants)X
+2231(of)X
+2328(the)X
+2 f
+2456(lock)X
+1 f
+2620(request,)X
+2 f
+2902(lock_upgrade)X
+1 f
+3373(and)X
+2 f
+3519(lock_downgrade)X
+1 f
+4053(,)X
+4103(which)X
+555 1686(allow)N
+755(the)X
+875(caller)X
+1076(to)X
+1160(atomically)X
+1519(trade)X
+1701(a)X
+1758(lock)X
+1917(of)X
+2005(one)X
+2142(type)X
+2301(for)X
+2416(a)X
+2473(lock)X
+2632(of)X
+2720(another.)X
+2 f
+3022(Unlock)X
+1 f
+3275(releases)X
+3551(a)X
+3608(speci\256c)X
+3874(mode)X
+4073(of)X
+4161(lock)X
+555 1776(on)N
+655(a)X
+711(speci\256c)X
+976(object.)X
+2 f
+1232(Lock_unlock_all)X
+1 f
+1786(releases)X
+2061(all)X
+2161(the)X
+2279(locks)X
+2468(associated)X
+2818(with)X
+2980(a)X
+3036(speci\256c)X
+3301(transaction.)X
+3 f
+555 1962(3.2.4.)N
+775(The)X
+928(Process)X
+1207(Manager)X
+1 f
+755 2085(The)N
+3 f
+900(Process)X
+1179(Manager)X
+1 f
+1511(acts)X
+1656(as)X
+1743(a)X
+1799(user-level)X
+2136(scheduler)X
+2464(to)X
+2546(make)X
+2740(processes)X
+3068(wait)X
+3226(on)X
+3326(unavailable)X
+3716(locks)X
+3905(and)X
+4041(pending)X
+555 2175(buffer)N
+778(cache)X
+988(I/O.)X
+1161(For)X
+1297(each)X
+1470(process,)X
+1756(a)X
+1817(semaphore)X
+2190(is)X
+2268(maintained)X
+2649(upon)X
+2834(which)X
+3055(that)X
+3200(process)X
+3466(waits)X
+3660(when)X
+3859(it)X
+3928(needs)X
+4136(to)X
+4223(be)X
+555 2265(descheduled.)N
+1014(When)X
+1228(a)X
+1286(process)X
+1549(needs)X
+1754(to)X
+1838(be)X
+1936(run,)X
+2084(its)X
+2180(semaphore)X
+2549(is)X
+2623(cleared,)X
+2897(and)X
+3034(the)X
+3153(operating)X
+3477(system)X
+3720(reschedules)X
+4116(it.)X
+4201(No)X
+555 2355(sophisticated)N
+1002(scheduling)X
+1378(algorithm)X
+1718(is)X
+1799(applied;)X
+2085(if)X
+2162(the)X
+2288(lock)X
+2454(for)X
+2576(which)X
+2800(a)X
+2864(process)X
+3133(was)X
+3286(waiting)X
+3554(becomes)X
+3863(available,)X
+4201(the)X
+555 2445(process)N
+824(is)X
+905(made)X
+1107(runnable.)X
+1456(It)X
+1533(would)X
+1761(have)X
+1941(been)X
+2121(possible)X
+2411(to)X
+2501(change)X
+2757(the)X
+2883(kernel's)X
+3170(process)X
+3439(scheduler)X
+3775(to)X
+3865(interact)X
+4134(more)X
+555 2535(ef\256ciently)N
+900(with)X
+1062(the)X
+1180(lock)X
+1338(manager,)X
+1655(but)X
+1777(doing)X
+1979(so)X
+2070(would)X
+2290(have)X
+2462(compromised)X
+2918(our)X
+3045(commitment)X
+3469(to)X
+3551(a)X
+3607(user-level)X
+3944(package.)X
+3 f
+555 2721(3.2.5.)N
+775(The)X
+928(Transaction)X
+1361(Manager)X
+1 f
+755 2844(The)N
+3 f
+901(Transaction)X
+1335(Manager)X
+1 f
+1668(provides)X
+1965(the)X
+2084(standard)X
+2377(interface)X
+2680(of)X
+2 f
+2768(txn_begin)X
+1 f
+3084(,)X
+2 f
+3125(txn_commit)X
+1 f
+3499(,)X
+3540(and)X
+2 f
+3676(txn_abort)X
+1 f
+3987(.)X
+4047(It)X
+4116(keeps)X
+555 2934(track)N
+742(of)X
+835(all)X
+941(active)X
+1159(transactions,)X
+1588(assigns)X
+1845(unique)X
+2089(transaction)X
+2467(identi\256ers,)X
+2833(and)X
+2974(directs)X
+3213(the)X
+3336(abort)X
+3526(and)X
+3667(commit)X
+3936(processing.)X
+555 3024(When)N
+772(a)X
+2 f
+833(txn_begin)X
+1 f
+1174(is)X
+1252(issued,)X
+1497(the)X
+3 f
+1620(Transaction)X
+2058(Manager)X
+1 f
+2395(assigns)X
+2651(the)X
+2773(next)X
+2935(available)X
+3249(transaction)X
+3625(identi\256er,)X
+3958(allocates)X
+4263(a)X
+555 3114(per-process)N
+948(transaction)X
+1322(structure)X
+1625(in)X
+1709(shared)X
+1941(memory,)X
+2249(increments)X
+2622(the)X
+2741(count)X
+2940(of)X
+3028(active)X
+3241(transactions,)X
+3665(and)X
+3802(returns)X
+4046(the)X
+4165(new)X
+555 3204(transaction)N
+937(identi\256er)X
+1256(to)X
+1348(the)X
+1476(calling)X
+1724(process.)X
+2034(The)X
+2188(in-memory)X
+2573(transaction)X
+2954(structure)X
+3264(contains)X
+3560(a)X
+3625(pointer)X
+3881(into)X
+4034(the)X
+4161(lock)X
+555 3294(table)N
+734(for)X
+851(locks)X
+1043(held)X
+1204(by)X
+1307(this)X
+1445(transaction,)X
+1840(the)X
+1961(last)X
+2095(log)X
+2220(sequence)X
+2538(number,)X
+2826(a)X
+2885(transaction)X
+3260(state)X
+3430(\()X
+2 f
+3457(idle)X
+1 f
+(,)S
+2 f
+3620(running)X
+1 f
+3873(,)X
+2 f
+3915(aborting)X
+1 f
+4190(,)X
+4232(or)X
+2 f
+555 3384(committing\))N
+1 f
+942(,)X
+982(an)X
+1078(error)X
+1255(code,)X
+1447(and)X
+1583(a)X
+1639(semaphore)X
+2007(identi\256er.)X
+755 3507(At)N
+859(commit,)X
+1147(the)X
+3 f
+1269(Transaction)X
+1706(Manager)X
+1 f
+2042(calls)X
+2 f
+2213(log_commit)X
+1 f
+2615(to)X
+2700(record)X
+2929(the)X
+3050(end)X
+3189(of)X
+3279(transaction)X
+3654(and)X
+3793(to)X
+3878(\257ush)X
+4056(the)X
+4177(log.)X
+555 3597(Then)N
+743(it)X
+810(directs)X
+1047(the)X
+3 f
+1168(Lock)X
+1364(Manager)X
+1 f
+1699(to)X
+1784(release)X
+2031(all)X
+2134(locks)X
+2325(associated)X
+2677(with)X
+2841(the)X
+2961(given)X
+3161(transaction.)X
+3575(If)X
+3651(a)X
+3709(transaction)X
+4083(aborts,)X
+555 3687(the)N
+3 f
+680(Transaction)X
+1120(Manager)X
+1 f
+1459(calls)X
+1633(on)X
+2 f
+1739(log_unroll)X
+1 f
+2102(to)X
+2190(read)X
+2355(the)X
+2479(transaction's)X
+2915(log)X
+3043(records)X
+3306(and)X
+3448(undo)X
+3634(any)X
+3776(modi\256cations)X
+4237(to)X
+555 3777(the)N
+673(database.)X
+1010(As)X
+1119(in)X
+1201(the)X
+1319(commit)X
+1583(case,)X
+1762(it)X
+1826(then)X
+1984(calls)X
+2 f
+2151(lock_unlock_all)X
+1 f
+2683(to)X
+2765(release)X
+3009(the)X
+3127(transaction's)X
+3557(locks.)X
+3 f
+555 3963(3.2.6.)N
+775(The)X
+928(Record)X
+1198(Manager)X
+1 f
+755 4086(The)N
+3 f
+919(Record)X
+1208(Manager)X
+1 f
+1559(supports)X
+1869(the)X
+2006(abstraction)X
+2397(of)X
+2503(reading)X
+2783(and)X
+2938(writing)X
+3208(records)X
+3484(to)X
+3585(a)X
+3660(database.)X
+3996(We)X
+4147(have)X
+555 4176(modi\256ed)N
+861(the)X
+981(the)X
+1101(database)X
+1399(access)X
+1626(routines)X
+3 f
+1905(db)X
+1 f
+1993(\(3\))X
+2108([BSD91])X
+2418(to)X
+2501(call)X
+2638(the)X
+2757(log,)X
+2900(lock,)X
+3079(and)X
+3216(buffer)X
+3434(managers.)X
+3803(In)X
+3891(order)X
+4082(to)X
+4165(pro-)X
+555 4266(vide)N
+718(functionality)X
+1152(to)X
+1239(perform)X
+1523(undo)X
+1708(and)X
+1849(redo,)X
+2037(the)X
+3 f
+2160(Record)X
+2434(Manager)X
+1 f
+2770(de\256nes)X
+3021(a)X
+3081(collection)X
+3421(of)X
+3512(log)X
+3638(record)X
+3868(types)X
+4061(and)X
+4201(the)X
+555 4356(associated)N
+920(undo)X
+1115(and)X
+1266(redo)X
+1444(routines.)X
+1777(The)X
+3 f
+1937(Log)X
+2105(Manager)X
+1 f
+2452(performs)X
+2777(a)X
+2848(table)X
+3039(lookup)X
+3296(on)X
+3411(the)X
+3543(record)X
+3783(type)X
+3955(to)X
+4051(call)X
+4201(the)X
+555 4446(appropriate)N
+951(routines.)X
+1299(For)X
+1440(example,)X
+1762(the)X
+1890(B-tree)X
+2121(access)X
+2356(method)X
+2625(requires)X
+2913(two)X
+3062(log)X
+3193(record)X
+3428(types:)X
+3648(insert)X
+3855(and)X
+4000(delete.)X
+4241(A)X
+555 4536(replace)N
+808(operation)X
+1131(is)X
+1204(implemented)X
+1642(as)X
+1729(a)X
+1785(delete)X
+1997(followed)X
+2302(by)X
+2402(an)X
+2498(insert)X
+2696(and)X
+2832(is)X
+2905(logged)X
+3143(accordingly.)X
+3 f
+555 4722(3.3.)N
+715(Application)X
+1134(Architectures)X
+1 f
+755 4845(The)N
+907(structure)X
+1215(of)X
+1309(LIBTP)X
+1558(allows)X
+1794(application)X
+2177(designers)X
+2507(to)X
+2596(trade)X
+2784(off)X
+2905(performance)X
+3339(and)X
+3481(protection.)X
+3872(Since)X
+4076(a)X
+4138(large)X
+555 4935(portion)N
+810(of)X
+901(LIBTP's)X
+1205(functionality)X
+1638(is)X
+1715(provided)X
+2024(by)X
+2128(managing)X
+2468(structures)X
+2804(in)X
+2889(shared)X
+3122(memory,)X
+3432(its)X
+3530(structures)X
+3865(are)X
+3987(subject)X
+4237(to)X
+555 5025(corruption)N
+926(by)X
+1043(applications)X
+1467(when)X
+1678(the)X
+1813(library)X
+2064(is)X
+2154(linked)X
+2391(directly)X
+2673(with)X
+2852(the)X
+2987(application.)X
+3420(For)X
+3568(this)X
+3720(reason,)X
+3987(LIBTP)X
+4246(is)X
+555 5115(designed)N
+864(to)X
+950(allow)X
+1152(compilation)X
+1558(into)X
+1706(a)X
+1766(separate)X
+2053(server)X
+2273(process)X
+2537(which)X
+2756(may)X
+2917(be)X
+3016(accessed)X
+3321(via)X
+3442(a)X
+3501(socket)X
+3729(interface.)X
+4094(In)X
+4184(this)X
+555 5205(way)N
+712(LIBTP's)X
+1015(data)X
+1172(structures)X
+1507(are)X
+1629(protected)X
+1951(from)X
+2130(application)X
+2509(code,)X
+2704(but)X
+2829(communication)X
+3349(overhead)X
+3666(is)X
+3741(increased.)X
+4107(When)X
+555 5295(applications)N
+975(are)X
+1107(trusted,)X
+1377(LIBTP)X
+1631(may)X
+1801(be)X
+1909(compiled)X
+2239(directly)X
+2516(into)X
+2672(the)X
+2802(application)X
+3190(providing)X
+3533(improved)X
+3872(performance.)X
+555 5385(Figures)N
+815(two)X
+955(and)X
+1091(three)X
+1272(show)X
+1461(the)X
+1579(two)X
+1719(alternate)X
+2016(application)X
+2392(architectures.)X
+755 5508(There)N
+964(are)X
+1084(potentially)X
+1447(two)X
+1588(modes)X
+1818(in)X
+1901(which)X
+2118(one)X
+2255(might)X
+2462(use)X
+2590(LIBTP)X
+2833(in)X
+2916(a)X
+2972(server)X
+3189(based)X
+3392(architecture.)X
+3832(In)X
+3919(the)X
+4037(\256rst,)X
+4201(the)X
+555 5598(server)N
+778(would)X
+1004(provide)X
+1275(the)X
+1399(capability)X
+1741(to)X
+1829(respond)X
+2109(to)X
+2197(requests)X
+2486(to)X
+2574(each)X
+2747(of)X
+2839(the)X
+2962(low)X
+3107(level)X
+3288(modules)X
+3584(\(lock,)X
+3794(log,)X
+3941(buffer,)X
+4183(and)X
+555 5688(transaction)N
+944(managers\).)X
+1356(Unfortunately,)X
+1863(the)X
+1998(performance)X
+2442(of)X
+2546(such)X
+2730(a)X
+2803(system)X
+3062(is)X
+3152(likely)X
+3371(to)X
+3470(be)X
+3583(blindingly)X
+3947(slow)X
+4134(since)X
+
+7 p
+%%Page: 7 7
+10 s 10 xH 0 xS 1 f
+3 f
+1 f
+1 Dt
+1864 1125 MXY
+15 -26 Dl
+-15 10 Dl
+-14 -10 Dl
+14 26 Dl
+0 -266 Dl
+1315 1125 MXY
+15 -26 Dl
+-15 10 Dl
+-14 -10 Dl
+14 26 Dl
+0 -266 Dl
+3 Dt
+1133 1125 MXY
+0 798 Dl
+931 0 Dl
+0 -798 Dl
+-931 0 Dl
+1 Dt
+1266 1257 MXY
+0 133 Dl
+665 0 Dl
+0 -133 Dl
+-665 0 Dl
+3 f
+8 s
+1513 1351(driver)N
+1502 1617(LIBTP)N
+1266 1390 MXY
+0 400 Dl
+665 0 Dl
+0 -400 Dl
+-665 0 Dl
+3 Dt
+1133 726 MXY
+0 133 Dl
+931 0 Dl
+0 -133 Dl
+-931 0 Dl
+1 f
+1029 1098(txn_abort)N
+964 1015(txn_commit)N
+1018 932(txn_begin)N
+1910 1015(db_ops)N
+3 f
+1308 820(Application)N
+1645(Program)X
+1398 1218(Server)N
+1594(Process)X
+1 f
+1390 986(socket)N
+1569(interface)X
+1 Dt
+1848 967 MXY
+-23 -14 Dl
+8 14 Dl
+-8 15 Dl
+23 -15 Dl
+-50 0 Dl
+1324 MX
+23 15 Dl
+-9 -15 Dl
+9 -14 Dl
+-23 14 Dl
+50 0 Dl
+3 Dt
+2862 859 MXY
+0 1064 Dl
+932 0 Dl
+0 -1064 Dl
+-932 0 Dl
+1 Dt
+3178 1390 MXY
+24 -12 Dl
+-17 0 Dl
+-8 -15 Dl
+1 27 Dl
+150 -265 Dl
+3494 1390 MXY
+0 -27 Dl
+-8 15 Dl
+-16 1 Dl
+24 11 Dl
+-166 -265 Dl
+3 f
+3232 1617(LIBTP)N
+2995 1390 MXY
+0 400 Dl
+666 0 Dl
+0 -400 Dl
+-666 0 Dl
+992 MY
+0 133 Dl
+666 0 Dl
+0 -133 Dl
+-666 0 Dl
+3168 1086(Application)N
+1 f
+2939 1201(txn_begin)N
+2885 1284(txn_commit)N
+2950 1368(txn_abort)N
+3465 1284(db_ops)N
+3 f
+3155 766(Single)N
+3339(Process)X
+3 Dt
+-1 Ds
+811 2100(Figure)N
+1023(2:)X
+1107(Server)X
+1318(Architecture.)X
+1 f
+1727(In)X
+1811(this)X
+1934(con\256guration,)X
+811 2190(the)N
+916(library)X
+1113(is)X
+1183(loaded)X
+1380(into)X
+1507(a)X
+1562(server)X
+1744(process)X
+1962(which)X
+2145(is)X
+2214(ac-)X
+811 2280(cessed)N
+993(via)X
+1087(a)X
+1131(socket)X
+1310(interface.)X
+3 f
+2563 2100(Figure)N
+2803(3:)X
+2914(Single)X
+3140(Process)X
+3403(Architecture.)X
+1 f
+3839(In)X
+3950(this)X
+2563 2190(con\256guration,)N
+2948(the)X
+3053(library)X
+3250(routines)X
+3483(are)X
+3587(loaded)X
+3784(as)X
+3864(part)X
+3990(of)X
+2563 2280(the)N
+2657(application)X
+2957(and)X
+3065(accessed)X
+3303(via)X
+3397(a)X
+3441(subroutine)X
+3727(interface.)X
+10 s
+10 f
+555 2403(h)N
+579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X
+1 f
+555 2679(modifying)N
+909(a)X
+966(piece)X
+1157(of)X
+1245(data)X
+1400(would)X
+1621(require)X
+1870(three)X
+2051(or)X
+2138(possibly)X
+2424(four)X
+2578(separate)X
+2862(communications:)X
+3433(one)X
+3569(to)X
+3651(lock)X
+3809(the)X
+3927(data,)X
+4101(one)X
+4237(to)X
+555 2769(obtain)N
+781(the)X
+905(data,)X
+1085(one)X
+1227(to)X
+1315(log)X
+1443(the)X
+1567(modi\256cation,)X
+2017(and)X
+2159(possibly)X
+2451(one)X
+2593(to)X
+2681(transmit)X
+2969(the)X
+3093(modi\256ed)X
+3403(data.)X
+3583(Figure)X
+3817(four)X
+3976(shows)X
+4201(the)X
+555 2859(relative)N
+826(performance)X
+1263(for)X
+1387(retrieving)X
+1728(a)X
+1793(single)X
+2013(record)X
+2248(using)X
+2450(the)X
+2577(record)X
+2812(level)X
+2997(call)X
+3142(versus)X
+3376(using)X
+3578(the)X
+3705(lower)X
+3917(level)X
+4102(buffer)X
+555 2949(management)N
+987(and)X
+1125(locking)X
+1387(calls.)X
+1616(The)X
+1763(2:1)X
+1887(ratio)X
+2056(observed)X
+2367(in)X
+2450(the)X
+2569(single)X
+2781(process)X
+3043(case)X
+3203(re\257ects)X
+3456(the)X
+3575(additional)X
+3916(overhead)X
+4232(of)X
+555 3039(parsing)N
+819(eight)X
+1006(commands)X
+1380(rather)X
+1595(than)X
+1760(one)X
+1903(while)X
+2108(the)X
+2233(3:1)X
+2362(ratio)X
+2536(observed)X
+2853(in)X
+2942(the)X
+3067(client/server)X
+3491(architecture)X
+3898(re\257ects)X
+4157(both)X
+555 3129(the)N
+679(parsing)X
+941(and)X
+1083(the)X
+1207(communication)X
+1731(overheard.)X
+2118(Although)X
+2445(there)X
+2631(may)X
+2794(be)X
+2895(applications)X
+3307(which)X
+3528(could)X
+3731(tolerate)X
+3997(such)X
+4169(per-)X
+555 3219(formance,)N
+904(it)X
+973(seems)X
+1194(far)X
+1309(more)X
+1499(feasible)X
+1774(to)X
+1861(support)X
+2126(a)X
+2187(higher)X
+2417(level)X
+2597(interface,)X
+2923(such)X
+3094(as)X
+3185(that)X
+3329(provided)X
+3638(by)X
+3742(a)X
+3802(query)X
+4009(language)X
+555 3309(\()N
+2 f
+582(e.g.)X
+1 f
+718(SQL)X
+889([SQL86]\).)X
+755 3432(Although)N
+1081(LIBTP)X
+1327(does)X
+1498(not)X
+1624(have)X
+1800(an)X
+1900(SQL)X
+2075(parser,)X
+2316(we)X
+2433(have)X
+2608(built)X
+2777(a)X
+2836(server)X
+3056(application)X
+3435(using)X
+3631(the)X
+3752(toolkit)X
+3983(command)X
+555 3522(language)N
+882(\(TCL\))X
+1124([OUST90].)X
+1544(The)X
+1706(server)X
+1940(supports)X
+2248(a)X
+2321(command)X
+2674(line)X
+2831(interface)X
+3150(similar)X
+3409(to)X
+3508(the)X
+3643(subroutine)X
+4017(interface)X
+555 3612(de\256ned)N
+811(in)X
+3 f
+893(db)X
+1 f
+981(\(3\).)X
+1135(Since)X
+1333(it)X
+1397(is)X
+1470(based)X
+1673(on)X
+1773(TCL,)X
+1964(it)X
+2028(provides)X
+2324(control)X
+2571(structures)X
+2903(as)X
+2990(well.)X
+3 f
+555 3798(4.)N
+655(Implementation)X
+1 f
+3 f
+555 3984(4.1.)N
+715(Locking)X
+1014(and)X
+1162(Deadlock)X
+1502(Detection)X
+1 f
+755 4107(LIBTP)N
+1007(uses)X
+1175(two-phase)X
+1535(locking)X
+1805(for)X
+1929(user)X
+2093(data.)X
+2297(Strictly)X
+2562(speaking,)X
+2897(the)X
+3024(two)X
+3173(phases)X
+3416(in)X
+3507(two-phase)X
+3866(locking)X
+4135(are)X
+4263(a)X
+3 f
+555 4197(grow)N
+1 f
+756(phase,)X
+986(during)X
+1221(which)X
+1443(locks)X
+1638(are)X
+1763(acquired,)X
+2086(and)X
+2228(a)X
+3 f
+2290(shrink)X
+1 f
+2537(phase,)X
+2766(during)X
+3001(which)X
+3223(locks)X
+3418(are)X
+3543(released.)X
+3873(No)X
+3997(lock)X
+4161(may)X
+555 4287(ever)N
+720(be)X
+822(acquired)X
+1124(during)X
+1358(the)X
+1481(shrink)X
+1706(phase.)X
+1954(The)X
+2104(grow)X
+2294(phase)X
+2502(lasts)X
+2669(until)X
+2840(the)X
+2963(\256rst)X
+3112(release,)X
+3381(which)X
+3602(marks)X
+3823(the)X
+3946(start)X
+4109(of)X
+4201(the)X
+555 4377(shrink)N
+780(phase.)X
+1028(In)X
+1120(practice,)X
+1420(the)X
+1543(grow)X
+1733(phase)X
+1941(lasts)X
+2108(for)X
+2227(the)X
+2350(duration)X
+2642(of)X
+2734(a)X
+2795(transaction)X
+3172(in)X
+3259(LIBTP)X
+3506(and)X
+3647(in)X
+3734(commercial)X
+4138(data-)X
+555 4467(base)N
+721(systems.)X
+1037(The)X
+1184(shrink)X
+1406(phase)X
+1611(takes)X
+1798(place)X
+1990(during)X
+2221(transaction)X
+2595(commit)X
+2861(or)X
+2950(abort.)X
+3177(This)X
+3341(means)X
+3568(that)X
+3710(locks)X
+3901(are)X
+4022(acquired)X
+555 4557(on)N
+655(demand)X
+929(during)X
+1158(the)X
+1276(lifetime)X
+1545(of)X
+1632(a)X
+1688(transaction,)X
+2080(and)X
+2216(held)X
+2374(until)X
+2540(commit)X
+2804(time,)X
+2986(at)X
+3064(which)X
+3280(point)X
+3464(all)X
+3564(locks)X
+3753(are)X
+3872(released.)X
+755 4680(If)N
+832(multiple)X
+1121(transactions)X
+1527(are)X
+1649(active)X
+1864(concurrently,)X
+2313(deadlocks)X
+2657(can)X
+2792(occur)X
+2994(and)X
+3133(must)X
+3311(be)X
+3410(detected)X
+3701(and)X
+3840(resolved.)X
+4174(The)X
+555 4770(lock)N
+715(table)X
+893(can)X
+1027(be)X
+1125(thought)X
+1391(of)X
+1480(as)X
+1569(a)X
+1627(representation)X
+2104(of)X
+2193(a)X
+2251(directed)X
+2532(graph.)X
+2777(The)X
+2924(nodes)X
+3133(in)X
+3216(the)X
+3335(graph)X
+3539(are)X
+3659(transactions.)X
+4103(Edges)X
+555 4860(represent)N
+878(the)X
+3 f
+1004(waits-for)X
+1 f
+1340(relation)X
+1613(between)X
+1909(transactions;)X
+2342(if)X
+2419(transaction)X
+2 f
+2799(A)X
+1 f
+2876(is)X
+2957(waiting)X
+3225(for)X
+3347(a)X
+3411(lock)X
+3577(held)X
+3743(by)X
+3851(transaction)X
+2 f
+4230(B)X
+1 f
+4279(,)X
+555 4950(then)N
+716(a)X
+775(directed)X
+1057(edge)X
+1232(exists)X
+1437(from)X
+2 f
+1616(A)X
+1 f
+1687(to)X
+2 f
+1771(B)X
+1 f
+1842(in)X
+1926(the)X
+2046(graph.)X
+2291(A)X
+2371(deadlock)X
+2683(exists)X
+2887(if)X
+2958(a)X
+3016(cycle)X
+3208(appears)X
+3476(in)X
+3560(the)X
+3680(graph.)X
+3925(By)X
+4040(conven-)X
+555 5040(tion,)N
+719(no)X
+819(transaction)X
+1191(ever)X
+1350(waits)X
+1539(for)X
+1653(a)X
+1709(lock)X
+1867(it)X
+1931(already)X
+2188(holds,)X
+2401(so)X
+2492(re\257exive)X
+2793(edges)X
+2996(are)X
+3115(impossible.)X
+755 5163(A)N
+836(distinguished)X
+1285(process)X
+1549(monitors)X
+1856(the)X
+1977(lock)X
+2138(table,)X
+2337(searching)X
+2668(for)X
+2785(cycles.)X
+3048(The)X
+3195(frequency)X
+3539(with)X
+3703(which)X
+3921(this)X
+4058(process)X
+555 5253(runs)N
+716(is)X
+792(user-settable;)X
+1243(for)X
+1360(the)X
+1481(multi-user)X
+1833(tests)X
+1998(discussed)X
+2328(in)X
+2413(section)X
+2663(5.1.2,)X
+2866(it)X
+2933(has)X
+3063(been)X
+3238(set)X
+3350(to)X
+3435(wake)X
+3628(up)X
+3731(every)X
+3932(second,)X
+4197(but)X
+555 5343(more)N
+742(sophisticated)X
+1182(schedules)X
+1516(are)X
+1636(certainly)X
+1938(possible.)X
+2261(When)X
+2474(a)X
+2531(cycle)X
+2722(is)X
+2796(detected,)X
+3105(one)X
+3242(of)X
+3330(the)X
+3449(transactions)X
+3853(in)X
+3936(the)X
+4055(cycle)X
+4246(is)X
+555 5433(nominated)N
+917(and)X
+1057(aborted.)X
+1362(When)X
+1578(the)X
+1700(transaction)X
+2076(aborts,)X
+2315(it)X
+2382(rolls)X
+2547(back)X
+2722(its)X
+2820(changes)X
+3102(and)X
+3241(releases)X
+3519(its)X
+3617(locks,)X
+3829(thereby)X
+4093(break-)X
+555 5523(ing)N
+677(the)X
+795(cycle)X
+985(in)X
+1067(the)X
+1185(graph.)X
+
+8 p
+%%Page: 8 8
+10 s 10 xH 0 xS 1 f
+3 f
+1 f
+4 Ds
+1 Dt
+1866 865 MXY
+1338 0 Dl
+1866 1031 MXY
+1338 0 Dl
+1866 1199 MXY
+1338 0 Dl
+1866 1366 MXY
+1338 0 Dl
+1866 1533 MXY
+1338 0 Dl
+1866 1701 MXY
+1338 0 Dl
+-1 Ds
+5 Dt
+1866 1868 MXY
+1338 0 Dl
+1 Dt
+1 Di
+2981 MX
+ 2981 1868 lineto
+ 2981 1575 lineto
+ 3092 1575 lineto
+ 3092 1868 lineto
+ 2981 1868 lineto
+closepath 21 2981 1575 3092 1868 Dp
+2646 MX
+ 2646 1868 lineto
+ 2646 949 lineto
+ 2758 949 lineto
+ 2758 1868 lineto
+ 2646 1868 lineto
+closepath 14 2646 949 2758 1868 Dp
+2312 MX
+ 2312 1868 lineto
+ 2312 1701 lineto
+ 2423 1701 lineto
+ 2423 1868 lineto
+ 2312 1868 lineto
+closepath 3 2312 1701 2423 1868 Dp
+1977 MX
+ 1977 1868 lineto
+ 1977 1512 lineto
+ 2089 1512 lineto
+ 2089 1868 lineto
+ 1977 1868 lineto
+closepath 19 1977 1512 2089 1868 Dp
+3 f
+2640 2047(Client/Server)N
+1957(Single)X
+2185(Process)X
+7 s
+2957 1957(record)N
+2570(component)X
+2289(record)X
+1890(components)X
+1733 1724(.1)N
+1733 1556(.2)N
+1733 1389(.3)N
+1733 1222(.4)N
+1733 1055(.5)N
+1733 889(.6)N
+1590 726(Elapsed)N
+1794(Time)X
+1613 782(\(in)N
+1693(seconds\))X
+3 Dt
+-1 Ds
+8 s
+555 2255(Figure)N
+756(4:)X
+829(Comparison)X
+1187(of)X
+1260(High)X
+1416(and)X
+1540(Low)X
+1681(Level)X
+1850(Interfaces.)X
+1 f
+2174(Elapsed)X
+2395(time)X
+2528(in)X
+2597(seconds)X
+2818(to)X
+2887(perform)X
+3111(a)X
+3158(single)X
+3330(record)X
+3511(retrieval)X
+3742(from)X
+3885(a)X
+3932(command)X
+4203(line)X
+555 2345(\(rather)N
+751(than)X
+888(a)X
+943(procedural)X
+1241(interface\))X
+1510(is)X
+1579(shown)X
+1772(on)X
+1862(the)X
+1966(y)X
+2024(axis.)X
+2185(The)X
+2310(``component'')X
+2704(numbers)X
+2950(re\257ect)X
+3135(the)X
+3239(timings)X
+3458(when)X
+3622(the)X
+3726(record)X
+3914(is)X
+3983(retrieved)X
+4235(by)X
+555 2435(separate)N
+785(calls)X
+924(to)X
+996(the)X
+1096(lock)X
+1228(manager)X
+1469(and)X
+1583(buffer)X
+1760(manager)X
+2001(while)X
+2165(the)X
+2264(``record'')X
+2531(timings)X
+2745(were)X
+2889(obtained)X
+3130(by)X
+3215(using)X
+3375(a)X
+3424(single)X
+3598(call)X
+3711(to)X
+3782(the)X
+3881(record)X
+4064(manager.)X
+555 2525(The)N
+674(2:1)X
+776(ratio)X
+913(observed)X
+1163(for)X
+1257(the)X
+1355(single)X
+1528(process)X
+1739(case)X
+1868(is)X
+1930(a)X
+1977(re\257ection)X
+2237(of)X
+2309(the)X
+2406(parsing)X
+2613(overhead)X
+2865(for)X
+2958(executing)X
+3225(eight)X
+3372(separate)X
+3599(commands)X
+3895(rather)X
+4062(than)X
+4191(one.)X
+555 2615(The)N
+673(additional)X
+948(factor)X
+1115(of)X
+1187(one)X
+1298(re\257ected)X
+1536(in)X
+1605(the)X
+1702(3:1)X
+1803(ratio)X
+1939(for)X
+2031(the)X
+2127(client/server)X
+2460(architecture)X
+2794(is)X
+2855(due)X
+2965(to)X
+3033(the)X
+3129(communication)X
+3545(overhead.)X
+3828(The)X
+3945(true)X
+4062(ratios)X
+4222(are)X
+555 2705(actually)N
+775(worse)X
+945(since)X
+1094(the)X
+1190(component)X
+1492(timings)X
+1703(do)X
+1785(not)X
+1884(re\257ect)X
+2060(the)X
+2155(search)X
+2334(times)X
+2490(within)X
+2671(each)X
+2804(page)X
+2941(or)X
+3011(the)X
+3106(time)X
+3237(required)X
+3466(to)X
+3533(transmit)X
+3760(the)X
+3855(page)X
+3992(between)X
+4221(the)X
+555 2795(two)N
+667(processes.)X
+10 s
+10 f
+555 2885(h)N
+579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X
+3 f
+555 3161(4.2.)N
+715(Group)X
+961(Commit)X
+1 f
+755 3284(Since)N
+959(the)X
+1083(log)X
+1211(must)X
+1392(be)X
+1494(\257ushed)X
+1751(to)X
+1839(disk)X
+1997(at)X
+2080(commit)X
+2349(time,)X
+2536(disk)X
+2694(bandwidth)X
+3057(fundamentally)X
+3545(limits)X
+3751(the)X
+3874(rate)X
+4020(at)X
+4103(which)X
+555 3374(transactions)N
+959(complete.)X
+1314(Since)X
+1513(most)X
+1688(transactions)X
+2091(write)X
+2276(only)X
+2438(a)X
+2494(few)X
+2635(small)X
+2828(records)X
+3085(to)X
+3167(the)X
+3285(log,)X
+3427(the)X
+3545(last)X
+3676(page)X
+3848(of)X
+3935(the)X
+4053(log)X
+4175(will)X
+555 3464(be)N
+658(\257ushed)X
+916(once)X
+1095(by)X
+1202(every)X
+1408(transaction)X
+1787(which)X
+2010(writes)X
+2233(to)X
+2322(it.)X
+2433(In)X
+2527(the)X
+2652(naive)X
+2853(implementation,)X
+3402(these)X
+3593(\257ushes)X
+3841(would)X
+4067(happen)X
+555 3554(serially.)N
+755 3677(LIBTP)N
+1008(uses)X
+3 f
+1177(group)X
+1412(commit)X
+1 f
+1702([DEWI84])X
+2077(in)X
+2170(order)X
+2371(to)X
+2464(amortize)X
+2775(the)X
+2903(cost)X
+3062(of)X
+3159(one)X
+3305(synchronous)X
+3740(disk)X
+3903(write)X
+4098(across)X
+555 3767(multiple)N
+851(transactions.)X
+1304(Group)X
+1539(commit)X
+1812(provides)X
+2117(a)X
+2182(way)X
+2345(for)X
+2468(a)X
+2533(group)X
+2749(of)X
+2845(transactions)X
+3257(to)X
+3348(commit)X
+3621(simultaneously.)X
+4174(The)X
+555 3857(\256rst)N
+709(several)X
+967(transactions)X
+1380(to)X
+1472(commit)X
+1745(write)X
+1939(their)X
+2115(changes)X
+2403(to)X
+2494(the)X
+2621(in-memory)X
+3006(log)X
+3137(page,)X
+3338(then)X
+3505(sleep)X
+3699(on)X
+3808(a)X
+3873(distinguished)X
+555 3947(semaphore.)N
+966(Later,)X
+1179(a)X
+1238(committing)X
+1629(transaction)X
+2004(\257ushes)X
+2249(the)X
+2370(page)X
+2545(to)X
+2630(disk,)X
+2805(and)X
+2943(wakes)X
+3166(up)X
+3268(all)X
+3370(its)X
+3467(sleeping)X
+3756(peers.)X
+3988(The)X
+4135(point)X
+555 4037(at)N
+635(which)X
+853(changes)X
+1134(are)X
+1255(actually)X
+1531(written)X
+1780(is)X
+1855(determined)X
+2238(by)X
+2340(three)X
+2523(thresholds.)X
+2914(The)X
+3061(\256rst)X
+3207(is)X
+3281(the)X
+2 f
+3400(group)X
+3612(threshold)X
+1 f
+3935(and)X
+4072(de\256nes)X
+555 4127(the)N
+674(minimum)X
+1005(number)X
+1271(of)X
+1359(transactions)X
+1763(which)X
+1979(must)X
+2154(be)X
+2250(active)X
+2462(in)X
+2544(the)X
+2662(system)X
+2904(before)X
+3130(transactions)X
+3533(are)X
+3652(forced)X
+3878(to)X
+3960(participate)X
+555 4217(in)N
+646(a)X
+711(group)X
+927(commit.)X
+1240(The)X
+1394(second)X
+1646(is)X
+1728(the)X
+2 f
+1855(wait)X
+2021(threshold)X
+1 f
+2352(which)X
+2577(is)X
+2658(expressed)X
+3003(as)X
+3098(the)X
+3224(percentage)X
+3601(of)X
+3696(active)X
+3916(transactions)X
+555 4307(waiting)N
+826(to)X
+919(be)X
+1026(committed.)X
+1439(The)X
+1595(last)X
+1737(is)X
+1821(the)X
+2 f
+1950(logdelay)X
+2257(threshold)X
+1 f
+2590(which)X
+2816(indicates)X
+3131(how)X
+3299(much)X
+3507(un\257ushed)X
+3848(log)X
+3980(should)X
+4223(be)X
+555 4397(allowed)N
+829(to)X
+911(accumulate)X
+1297(before)X
+1523(a)X
+1579(waiting)X
+1839(transaction's)X
+2289(commit)X
+2553(record)X
+2779(is)X
+2852(\257ushed.)X
+755 4520(Group)N
+981(commit)X
+1246(can)X
+1379(substantially)X
+1803(improve)X
+2090(performance)X
+2517(for)X
+2631(high-concurrency)X
+3218(environments.)X
+3714(If)X
+3788(only)X
+3950(a)X
+4006(few)X
+4147(tran-)X
+555 4610(sactions)N
+836(are)X
+957(running,)X
+1248(it)X
+1314(is)X
+1389(unlikely)X
+1673(to)X
+1757(improve)X
+2046(things)X
+2263(at)X
+2343(all.)X
+2485(The)X
+2632(crossover)X
+2962(point)X
+3148(is)X
+3223(the)X
+3343(point)X
+3529(at)X
+3609(which)X
+3827(the)X
+3947(transaction)X
+555 4700(commit)N
+823(rate)X
+968(is)X
+1045(limited)X
+1295(by)X
+1399(the)X
+1521(bandwidth)X
+1883(of)X
+1974(the)X
+2096(device)X
+2330(on)X
+2434(which)X
+2654(the)X
+2776(log)X
+2902(resides.)X
+3189(If)X
+3267(processes)X
+3599(are)X
+3722(trying)X
+3937(to)X
+4023(\257ush)X
+4201(the)X
+555 4790(log)N
+677(faster)X
+876(than)X
+1034(the)X
+1152(log)X
+1274(disk)X
+1427(can)X
+1559(accept)X
+1785(data,)X
+1959(then)X
+2117(group)X
+2324(commit)X
+2588(will)X
+2732(increase)X
+3016(the)X
+3134(commit)X
+3398(rate.)X
+3 f
+555 4976(4.3.)N
+715(Kernel)X
+971(Intervention)X
+1418(for)X
+1541(Synchronization)X
+1 f
+755 5099(Since)N
+954(LIBTP)X
+1197(uses)X
+1356(data)X
+1511(in)X
+1594(shared)X
+1825(memory)X
+2113(\()X
+2 f
+2140(e.g.)X
+1 f
+2277(the)X
+2395(lock)X
+2553(table)X
+2729(and)X
+2865(buffer)X
+3082(pool\))X
+3271(it)X
+3335(must)X
+3510(be)X
+3606(possible)X
+3888(for)X
+4002(a)X
+4058(process)X
+555 5189(to)N
+640(acquire)X
+900(exclusive)X
+1226(access)X
+1454(to)X
+1538(shared)X
+1770(data)X
+1926(in)X
+2010(order)X
+2202(to)X
+2286(prevent)X
+2549(corruption.)X
+2945(In)X
+3034(addition,)X
+3338(the)X
+3458(process)X
+3721(manager)X
+4020(must)X
+4197(put)X
+555 5279(processes)N
+886(to)X
+971(sleep)X
+1159(when)X
+1356(the)X
+1477(lock)X
+1638(or)X
+1728(buffer)X
+1948(they)X
+2109(request)X
+2364(is)X
+2440(in)X
+2525(use)X
+2655(by)X
+2758(some)X
+2950(other)X
+3138(process.)X
+3441(In)X
+3530(the)X
+3650(LIBTP)X
+3894(implementa-)X
+555 5385(tion)N
+705(under)X
+914(Ultrix)X
+1131(4.0)X
+7 s
+5353(2)Y
+10 s
+5385(,)Y
+1305(we)X
+1424(use)X
+1556(System)X
+1816(V)X
+1899(semaphores)X
+2303(to)X
+2390(provide)X
+2660(this)X
+2800(synchronization.)X
+3377(Semaphores)X
+3794(implemented)X
+4237(in)X
+555 5475(this)N
+701(fashion)X
+968(turn)X
+1128(out)X
+1261(to)X
+1354(be)X
+1461(an)X
+1568(expensive)X
+1920(choice)X
+2161(for)X
+2285(synchronization,)X
+2847(because)X
+3132(each)X
+3310(access)X
+3546(traps)X
+3732(to)X
+3824(the)X
+3952(kernel)X
+4183(and)X
+8 s
+10 f
+555 5547(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N
+5 s
+1 f
+727 5625(2)N
+8 s
+763 5650(Ultrix)N
+932(and)X
+1040(DEC)X
+1184(are)X
+1277(trademarks)X
+1576(of)X
+1645(Digital)X
+1839(Equipment)X
+2136(Corporation.)X
+
+9 p
+%%Page: 9 9
+8 s 8 xH 0 xS 1 f
+10 s
+3 f
+1 f
+555 630(executes)N
+852(atomically)X
+1210(there.)X
+755 753(On)N
+878(architectures)X
+1314(that)X
+1459(support)X
+1724(atomic)X
+1967(test-and-set,)X
+2382(a)X
+2443(much)X
+2646(better)X
+2854(choice)X
+3089(would)X
+3314(be)X
+3415(to)X
+3502(attempt)X
+3767(to)X
+3854(obtain)X
+4079(a)X
+4139(spin-)X
+555 843(lock)N
+714(with)X
+877(a)X
+934(test-and-set,)X
+1345(and)X
+1482(issue)X
+1663(a)X
+1720(system)X
+1963(call)X
+2100(only)X
+2263(if)X
+2333(the)X
+2452(spinlock)X
+2744(is)X
+2818(unavailable.)X
+3249(Since)X
+3447(virtually)X
+3738(all)X
+3838(semaphores)X
+4237(in)X
+555 933(LIBTP)N
+801(are)X
+924(uncontested)X
+1330(and)X
+1469(are)X
+1591(held)X
+1752(for)X
+1869(very)X
+2035(short)X
+2218(periods)X
+2477(of)X
+2567(time,)X
+2752(this)X
+2890(would)X
+3113(improve)X
+3403(performance.)X
+3873(For)X
+4007(example,)X
+555 1023(processes)N
+885(must)X
+1062(acquire)X
+1321(exclusive)X
+1646(access)X
+1874(to)X
+1958(buffer)X
+2177(pool)X
+2341(metadata)X
+2653(in)X
+2737(order)X
+2929(to)X
+3013(\256nd)X
+3159(and)X
+3297(pin)X
+3421(a)X
+3479(buffer)X
+3698(in)X
+3781(shared)X
+4012(memory.)X
+555 1113(This)N
+721(semaphore)X
+1093(is)X
+1170(requested)X
+1502(most)X
+1681(frequently)X
+2034(in)X
+2119(LIBTP.)X
+2404(However,)X
+2742(once)X
+2917(it)X
+2984(is)X
+3060(acquired,)X
+3380(only)X
+3545(a)X
+3604(few)X
+3748(instructions)X
+4144(must)X
+555 1203(be)N
+656(executed)X
+966(before)X
+1196(it)X
+1264(is)X
+1341(released.)X
+1669(On)X
+1791(one)X
+1931(architecture)X
+2335(for)X
+2453(which)X
+2673(we)X
+2791(were)X
+2972(able)X
+3130(to)X
+3216(gather)X
+3441(detailed)X
+3719(pro\256ling)X
+4018(informa-)X
+555 1293(tion,)N
+729(the)X
+857(cost)X
+1015(of)X
+1111(the)X
+1238(semaphore)X
+1615(calls)X
+1791(accounted)X
+2146(for)X
+2269(25%)X
+2445(of)X
+2541(the)X
+2668(total)X
+2839(time)X
+3010(spent)X
+3208(updating)X
+3517(the)X
+3644(metadata.)X
+4003(This)X
+4174(was)X
+555 1383(fairly)N
+749(consistent)X
+1089(across)X
+1310(most)X
+1485(of)X
+1572(the)X
+1690(critical)X
+1933(sections.)X
+755 1506(In)N
+848(an)X
+950(attempt)X
+1216(to)X
+1304(quantify)X
+1597(the)X
+1720(overhead)X
+2040(of)X
+2132(kernel)X
+2358(synchronization,)X
+2915(we)X
+3034(ran)X
+3162(tests)X
+3329(on)X
+3434(a)X
+3495(version)X
+3756(of)X
+3848(4.3BSD-Reno)X
+555 1596(which)N
+786(had)X
+937(been)X
+1123(modi\256ed)X
+1441(to)X
+1537(support)X
+1811(binary)X
+2050(semaphore)X
+2432(facilities)X
+2742(similar)X
+2998(to)X
+3094(those)X
+3297(described)X
+3639(in)X
+3735([POSIX91].)X
+4174(The)X
+555 1686(hardware)N
+880(platform)X
+1181(consisted)X
+1504(of)X
+1595(an)X
+1695(HP300)X
+1941(\(33MHz)X
+2237(MC68030\))X
+2612(workstation)X
+3014(with)X
+3180(16MBytes)X
+3537(of)X
+3628(main)X
+3812(memory,)X
+4123(and)X
+4263(a)X
+555 1776(600MByte)N
+920(HP7959)X
+1205(SCSI)X
+1396(disk)X
+1552(\(17)X
+1682(ms)X
+1798(average)X
+2072(seek)X
+2237(time\).)X
+2468(We)X
+2602(ran)X
+2727(three)X
+2910(sets)X
+3052(of)X
+3141(comparisons)X
+3568(which)X
+3786(are)X
+3907(summarized)X
+555 1866(in)N
+645(\256gure)X
+860(\256ve.)X
+1028(In)X
+1123(each)X
+1299(comparison)X
+1701(we)X
+1823(ran)X
+1954(two)X
+2102(tests,)X
+2292(one)X
+2436(using)X
+2637(hardware)X
+2965(spinlocks)X
+3295(and)X
+3438(the)X
+3563(other)X
+3755(using)X
+3955(kernel)X
+4183(call)X
+555 1956(synchronization.)N
+1135(Since)X
+1341(the)X
+1467(test)X
+1606(was)X
+1758(run)X
+1892(single-user,)X
+2291(none)X
+2474(of)X
+2568(the)X
+2693(the)X
+2818(locks)X
+3014(were)X
+3198(contested.)X
+3568(In)X
+3662(the)X
+3787(\256rst)X
+3938(two)X
+4085(sets)X
+4232(of)X
+555 2046(tests,)N
+743(we)X
+863(ran)X
+992(the)X
+1116(full)X
+1253(transaction)X
+1631(processing)X
+2000(benchmark)X
+2383(described)X
+2717(in)X
+2805(section)X
+3058(5.1.)X
+3223(In)X
+3315(one)X
+3456(case)X
+3620(we)X
+3739(ran)X
+3867(with)X
+4034(both)X
+4201(the)X
+555 2136(database)N
+854(and)X
+992(log)X
+1116(on)X
+1218(the)X
+1338(same)X
+1525(disk)X
+1680(\(1)X
+1769(Disk\))X
+1969(and)X
+2107(in)X
+2191(the)X
+2311(second,)X
+2576(we)X
+2692(ran)X
+2817(with)X
+2981(the)X
+3101(database)X
+3400(and)X
+3538(log)X
+3661(on)X
+3762(separate)X
+4047(disks)X
+4232(\(2)X
+555 2226(Disk\).)N
+800(In)X
+894(the)X
+1019(last)X
+1157(test,)X
+1315(we)X
+1436(wanted)X
+1695(to)X
+1784(create)X
+2004(a)X
+2067(CPU)X
+2249(bound)X
+2476(environment,)X
+2928(so)X
+3026(we)X
+3146(used)X
+3319(a)X
+3381(database)X
+3684(small)X
+3883(enough)X
+4145(to)X
+4233(\256t)X
+555 2316(completely)N
+941(in)X
+1033(the)X
+1161(cache)X
+1375(and)X
+1521(issued)X
+1751(read-only)X
+2089(transactions.)X
+2541(The)X
+2695(results)X
+2933(in)X
+3024(\256gure)X
+3240(\256ve)X
+3389(express)X
+3659(the)X
+3786(kernel)X
+4016(call)X
+4161(syn-)X
+555 2406(chronization)N
+980(performance)X
+1411(as)X
+1502(a)X
+1562(percentage)X
+1935(of)X
+2026(the)X
+2148(spinlock)X
+2443(performance.)X
+2914(For)X
+3049(example,)X
+3365(in)X
+3451(the)X
+3573(1)X
+3637(disk)X
+3794(case,)X
+3977(the)X
+4098(kernel)X
+555 2496(call)N
+697(implementation)X
+1225(achieved)X
+1537(4.4)X
+1662(TPS)X
+1824(\(transactions)X
+2259(per)X
+2387(second\))X
+2662(while)X
+2865(the)X
+2988(semaphore)X
+3361(implementation)X
+3888(achieved)X
+4199(4.6)X
+555 2586(TPS,)N
+735(and)X
+874(the)X
+995(relative)X
+1259(performance)X
+1689(of)X
+1779(the)X
+1900(kernel)X
+2123(synchronization)X
+2657(is)X
+2732(96%)X
+2901(that)X
+3043(of)X
+3132(the)X
+3252(spinlock)X
+3545(\(100)X
+3714(*)X
+3776(4.4)X
+3898(/)X
+3942(4.6\).)X
+4111(There)X
+555 2676(are)N
+674(two)X
+814(striking)X
+1078(observations)X
+1503(from)X
+1679(these)X
+1864(results:)X
+10 f
+635 2799(g)N
+1 f
+755(even)X
+927(when)X
+1121(the)X
+1239(system)X
+1481(is)X
+1554(disk)X
+1707(bound,)X
+1947(the)X
+2065(CPU)X
+2240(cost)X
+2389(of)X
+2476(synchronization)X
+3008(is)X
+3081(noticeable,)X
+3451(and)X
+10 f
+635 2922(g)N
+1 f
+755(when)X
+949(we)X
+1063(are)X
+1182(CPU)X
+1357(bound,)X
+1597(the)X
+1715(difference)X
+2062(is)X
+2135(dramatic)X
+2436(\(67%\).)X
+3 f
+555 3108(4.4.)N
+715(Transaction)X
+1148(Protected)X
+1499(Access)X
+1747(Methods)X
+1 f
+755 3231(The)N
+903(B-tree)X
+1127(and)X
+1266(\256xed)X
+1449(length)X
+1671(recno)X
+1872(\(record)X
+2127(number\))X
+2421(access)X
+2649(methods)X
+2942(have)X
+3116(been)X
+3290(modi\256ed)X
+3596(to)X
+3680(provide)X
+3947(transaction)X
+555 3321(protection.)N
+941(Whereas)X
+1244(the)X
+1363(previously)X
+1722(published)X
+2054(interface)X
+2357(to)X
+2440(the)X
+2559(access)X
+2786(routines)X
+3065(had)X
+3202(separate)X
+3487(open)X
+3664(calls)X
+3832(for)X
+3946(each)X
+4114(of)X
+4201(the)X
+10 f
+555 3507(h)N
+579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X
+1 Dt
+2978 5036 MXY
+ 2978 5036 lineto
+ 2978 4662 lineto
+ 3093 4662 lineto
+ 3093 5036 lineto
+ 2978 5036 lineto
+closepath 21 2978 4662 3093 5036 Dp
+2518 MX
+ 2518 5036 lineto
+ 2518 3960 lineto
+ 2633 3960 lineto
+ 2633 5036 lineto
+ 2518 5036 lineto
+closepath 3 2518 3960 2633 5036 Dp
+2059 MX
+ 2059 5036 lineto
+ 2059 3946 lineto
+ 2174 3946 lineto
+ 2174 5036 lineto
+ 2059 5036 lineto
+closepath 1 2059 3946 2174 5036 Dp
+3 f
+7 s
+2912 5141(Read-only)N
+1426 3767(of)N
+1487(Spinlock)X
+1710(Throughput)X
+1480 3710(Throughput)N
+1786(as)X
+1850(a)X
+1892(%)X
+11 s
+1670 4843(20)N
+1670 4614(40)N
+1670 4384(60)N
+1670 4155(80)N
+1648 3925(100)N
+7 s
+2041 5141(1)N
+2083(Disk)X
+2490(2)X
+2532(Disks)X
+5 Dt
+1829 5036 MXY
+1494 0 Dl
+4 Ds
+1 Dt
+1829 4806 MXY
+1494 0 Dl
+1829 4577 MXY
+1494 0 Dl
+1829 4347 MXY
+1494 0 Dl
+1829 4118 MXY
+1494 0 Dl
+1829 3888 MXY
+1494 0 Dl
+3 Dt
+-1 Ds
+8 s
+555 5360(Figure)N
+753(5:)X
+823(Kernel)X
+1028(Overhead)X
+1315(for)X
+1413(System)X
+1625(Call)X
+1756(Synchronization.)X
+1 f
+2254(The)X
+2370(performance)X
+2708(of)X
+2778(the)X
+2873(kernel)X
+3049(call)X
+3158(synchronization)X
+3583(is)X
+3643(expressed)X
+3911(as)X
+3980(a)X
+4024(percentage)X
+555 5450(of)N
+625(the)X
+720(spinlock)X
+954(synchronization)X
+1379(performance.)X
+1749(In)X
+1819(disk)X
+1943(bound)X
+2120(cases)X
+2271(\(1)X
+2341(Disk)X
+2479(and)X
+2588(2)X
+2637(Disks\),)X
+2837(we)X
+2928(see)X
+3026(that)X
+3139(4-6%)X
+3294(of)X
+3364(the)X
+3459(performance)X
+3797(is)X
+3857(lost)X
+3966(due)X
+4074(to)X
+4140(kernel)X
+555 5540(calls)N
+688(while)X
+846(in)X
+912(the)X
+1006(CPU)X
+1147(bound)X
+1323(case,)X
+1464(we)X
+1554(have)X
+1690(lost)X
+1799(67%)X
+1932(of)X
+2001(the)X
+2095(performance)X
+2432(due)X
+2540(to)X
+2606(kernel)X
+2781(calls.)X
+
+10 p
+%%Page: 10 10
+8 s 8 xH 0 xS 1 f
+10 s
+3 f
+1 f
+555 630(access)N
+781(methods,)X
+1092(we)X
+1206(now)X
+1364(have)X
+1536(an)X
+1632(integrated)X
+1973(open)X
+2149(call)X
+2285(with)X
+2447(the)X
+2565(following)X
+2896(calling)X
+3134(conventions:)X
+7 f
+715 753(DB)N
+859(*dbopen)X
+1243(\(const)X
+1579(char)X
+1819(*file,)X
+2155(int)X
+2347(flags,)X
+2683(int)X
+2875(mode,)X
+3163(DBTYPE)X
+3499(type,)X
+1291 843(int)N
+1483(dbflags,)X
+1915(const)X
+2203(void)X
+2443(*openinfo\))X
+1 f
+555 966(where)N
+2 f
+774(\256le)X
+1 f
+894(is)X
+969(the)X
+1089(name)X
+1285(of)X
+1374(the)X
+1494(\256le)X
+1618(being)X
+1818(opened,)X
+2 f
+2092(\257ags)X
+1 f
+2265(and)X
+2 f
+2402(mode)X
+1 f
+2597(are)X
+2717(the)X
+2836(standard)X
+3129(arguments)X
+3484(to)X
+3 f
+3567(open)X
+1 f
+3731(\(2\),)X
+2 f
+3866(type)X
+1 f
+4021(is)X
+4095(one)X
+4232(of)X
+555 1056(the)N
+680(access)X
+913(method)X
+1180(types,)X
+2 f
+1396(db\257ags)X
+1 f
+1654(indicates)X
+1966(the)X
+2091(mode)X
+2296(of)X
+2390(the)X
+2515(buffer)X
+2739(pool)X
+2907(and)X
+3049(transaction)X
+3427(protection,)X
+3798(and)X
+2 f
+3940(openinfo)X
+1 f
+4246(is)X
+555 1146(the)N
+681(access)X
+915(method)X
+1183(speci\256c)X
+1456(information.)X
+1902(Currently,)X
+2257(the)X
+2383(possible)X
+2673(values)X
+2906(for)X
+2 f
+3028(db\257ags)X
+1 f
+3287(are)X
+3414(DB_SHARED)X
+3912(and)X
+4055(DB_TP)X
+555 1236(indicating)N
+895(that)X
+1035(buffers)X
+1283(should)X
+1516(be)X
+1612(kept)X
+1770(in)X
+1852(a)X
+1908(shared)X
+2138(buffer)X
+2355(pool)X
+2517(and)X
+2653(that)X
+2793(the)X
+2911(\256le)X
+3033(should)X
+3266(be)X
+3362(transaction)X
+3734(protected.)X
+755 1359(The)N
+900(modi\256cations)X
+1355(required)X
+1643(to)X
+1725(add)X
+1861(transaction)X
+2233(protection)X
+2578(to)X
+2660(an)X
+2756(access)X
+2982(method)X
+3242(are)X
+3361(quite)X
+3541(simple)X
+3774(and)X
+3910(localized.)X
+715 1482(1.)N
+795(Replace)X
+1074(\256le)X
+2 f
+1196(open)X
+1 f
+1372(with)X
+2 f
+1534(buf_open)X
+1 f
+1832(.)X
+715 1572(2.)N
+795(Replace)X
+1074(\256le)X
+2 f
+1196(read)X
+1 f
+1363(and)X
+2 f
+1499(write)X
+1 f
+1683(calls)X
+1850(with)X
+2012(buffer)X
+2229(manager)X
+2526(calls)X
+2693(\()X
+2 f
+2720(buf_get)X
+1 f
+(,)S
+2 f
+3000(buf_unpin)X
+1 f
+3324(\).)X
+715 1662(3.)N
+795(Precede)X
+1070(buffer)X
+1287(manager)X
+1584(calls)X
+1751(with)X
+1913(an)X
+2009(appropriate)X
+2395(\(read)X
+2581(or)X
+2668(write\))X
+2880(lock)X
+3038(call.)X
+715 1752(4.)N
+795(Before)X
+1034(updates,)X
+1319(issue)X
+1499(a)X
+1555(logging)X
+1819(operation.)X
+715 1842(5.)N
+795(After)X
+985(data)X
+1139(have)X
+1311(been)X
+1483(accessed,)X
+1805(release)X
+2049(the)X
+2167(buffer)X
+2384(manager)X
+2681(pin.)X
+715 1932(6.)N
+795(Provide)X
+1064(undo/redo)X
+1409(code)X
+1581(for)X
+1695(each)X
+1863(type)X
+2021(of)X
+2108(log)X
+2230(record)X
+2456(de\256ned.)X
+555 2071(The)N
+702(following)X
+1035(code)X
+1209(fragments)X
+1552(show)X
+1743(how)X
+1903(to)X
+1987(transaction)X
+2361(protect)X
+2606(several)X
+2856(updates)X
+3123(to)X
+3206(a)X
+3263(B-tree.)X
+7 s
+3484 2039(3)N
+10 s
+3533 2071(In)N
+3621(the)X
+3740(unprotected)X
+4140(case,)X
+555 2161(an)N
+652(open)X
+829(call)X
+966(is)X
+1040(followed)X
+1346(by)X
+1447(a)X
+1504(read)X
+1664(call)X
+1801(to)X
+1884(obtain)X
+2105(the)X
+2224(meta-data)X
+2562(for)X
+2677(the)X
+2796(B-tree.)X
+3058(Instead,)X
+3331(we)X
+3446(issue)X
+3627(an)X
+3724(open)X
+3901(to)X
+3984(the)X
+4102(buffer)X
+555 2251(manager)N
+852(to)X
+934(obtain)X
+1154(a)X
+1210(\256le)X
+1332(id)X
+1414(and)X
+1550(a)X
+1606(buffer)X
+1823(request)X
+2075(to)X
+2157(obtain)X
+2377(the)X
+2495(meta-data)X
+2832(as)X
+2919(shown)X
+3148(below.)X
+7 f
+715 2374(char)N
+955(*path;)X
+715 2464(int)N
+907(fid,)X
+1147(flags,)X
+1483(len,)X
+1723(mode;)X
+715 2644(/*)N
+859(Obtain)X
+1195(a)X
+1291(file)X
+1531(id)X
+1675(with)X
+1915(which)X
+2203(to)X
+2347(access)X
+2683(the)X
+2875(buffer)X
+3211(pool)X
+3451(*/)X
+715 2734(fid)N
+907(=)X
+1003(buf_open\(path,)X
+1723(flags,)X
+2059(mode\);)X
+715 2914(/*)N
+859(Read)X
+1099(the)X
+1291(meta)X
+1531(data)X
+1771(\(page)X
+2059(0\))X
+2203(for)X
+2395(the)X
+2587(B-tree)X
+2923(*/)X
+715 3004(if)N
+859(\(tp_lock\(fid,)X
+1531(0,)X
+1675(READ_LOCK\)\))X
+1003 3094(return)N
+1339(error;)X
+715 3184(meta_data_ptr)N
+1387(=)X
+1483(buf_get\(fid,)X
+2107(0,)X
+2251(BF_PIN,)X
+2635(&len\);)X
+1 f
+555 3307(The)N
+714(BF_PIN)X
+1014(argument)X
+1350(to)X
+2 f
+1445(buf_get)X
+1 f
+1718(indicates)X
+2036(that)X
+2189(we)X
+2316(wish)X
+2500(to)X
+2595(leave)X
+2798(this)X
+2946(page)X
+3131(pinned)X
+3382(in)X
+3477(memory)X
+3777(so)X
+3881(that)X
+4034(it)X
+4111(is)X
+4197(not)X
+555 3397(swapped)N
+862(out)X
+990(while)X
+1194(we)X
+1314(are)X
+1439(accessing)X
+1772(it.)X
+1881(The)X
+2031(last)X
+2167(argument)X
+2495(to)X
+2 f
+2582(buf_get)X
+1 f
+2847(returns)X
+3095(the)X
+3218(number)X
+3488(of)X
+3580(bytes)X
+3774(on)X
+3879(the)X
+4002(page)X
+4179(that)X
+555 3487(were)N
+732(valid)X
+912(so)X
+1003(that)X
+1143(the)X
+1261(access)X
+1487(method)X
+1747(may)X
+1905(initialize)X
+2205(the)X
+2323(page)X
+2495(if)X
+2564(necessary.)X
+755 3610(Next,)N
+955(consider)X
+1251(inserting)X
+1555(a)X
+1615(record)X
+1845(on)X
+1949(a)X
+2009(particular)X
+2341(page)X
+2517(of)X
+2608(a)X
+2668(B-tree.)X
+2932(In)X
+3022(the)X
+3143(unprotected)X
+3545(case,)X
+3727(we)X
+3844(read)X
+4006(the)X
+4127(page,)X
+555 3700(call)N
+2 f
+693(_bt_insertat)X
+1 f
+1079(,)X
+1121(and)X
+1258(write)X
+1444(the)X
+1563(page.)X
+1776(Instead,)X
+2049(we)X
+2164(lock)X
+2323(the)X
+2442(page,)X
+2635(request)X
+2888(the)X
+3007(buffer,)X
+3245(log)X
+3368(the)X
+3487(change,)X
+3756(modify)X
+4008(the)X
+4127(page,)X
+555 3790(and)N
+691(release)X
+935(the)X
+1053(buffer.)X
+7 f
+715 3913(int)N
+907(fid,)X
+1147(len,)X
+1387(pageno;)X
+1867(/*)X
+2011(Identifies)X
+2539(the)X
+2731(buffer)X
+3067(*/)X
+715 4003(int)N
+907(index;)X
+1867(/*)X
+2011(Location)X
+2443(at)X
+2587(which)X
+2875(to)X
+3019(insert)X
+3355(the)X
+3547(new)X
+3739(pair)X
+3979(*/)X
+715 4093(DBT)N
+907(*keyp,)X
+1243(*datap;)X
+1867(/*)X
+2011(Key/Data)X
+2443(pair)X
+2683(to)X
+2827(be)X
+2971(inserted)X
+3403(*/)X
+715 4183(DATUM)N
+1003(*d;)X
+1867(/*)X
+2011(Key/data)X
+2443(structure)X
+2923(to)X
+3067(insert)X
+3403(*/)X
+715 4363(/*)N
+859(Lock)X
+1099(and)X
+1291(request)X
+1675(the)X
+1867(buffer)X
+2203(*/)X
+715 4453(if)N
+859(\(tp_lock\(fid,)X
+1531(pageno,)X
+1915(WRITE_LOCK\)\))X
+1003 4543(return)N
+1339(error;)X
+715 4633(buffer_ptr)N
+1243(=)X
+1339(buf_get\(fid,)X
+1963(pageno,)X
+2347(BF_PIN,)X
+2731(&len\);)X
+715 4813(/*)N
+859(Log)X
+1051(and)X
+1243(perform)X
+1627(the)X
+1819(update)X
+2155(*/)X
+715 4903(log_insdel\(BTREE_INSERT,)N
+1915(fid,)X
+2155(pageno,)X
+2539(keyp,)X
+2827(datap\);)X
+715 4993(_bt_insertat\(buffer_ptr,)N
+1915(d,)X
+2059(index\);)X
+715 5083(buf_unpin\(buffer_ptr\);)N
+1 f
+555 5206(Succinctly,)N
+942(the)X
+1068(algorithm)X
+1407(for)X
+1529(turning)X
+1788(unprotected)X
+2195(code)X
+2375(into)X
+2527(protected)X
+2854(code)X
+3034(is)X
+3115(to)X
+3205(replace)X
+3466(read)X
+3633(operations)X
+3995(with)X
+2 f
+4165(lock)X
+1 f
+555 5296(and)N
+2 f
+691(buf_get)X
+1 f
+951(operations)X
+1305(and)X
+1441(write)X
+1626(operations)X
+1980(with)X
+2 f
+2142(log)X
+1 f
+2264(and)X
+2 f
+2400(buf_unpin)X
+1 f
+2744(operations.)X
+8 s
+10 f
+555 5458(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N
+5 s
+1 f
+727 5536(3)N
+8 s
+766 5561(The)N
+884(following)X
+1152(code)X
+1291(fragments)X
+1565(are)X
+1661(examples,)X
+1937(but)X
+2038(do)X
+2120(not)X
+2220(de\256ne)X
+2394(the)X
+2490(\256nal)X
+2622(interface.)X
+2894(The)X
+3011(\256nal)X
+3143(interface)X
+3383(will)X
+3501(be)X
+3579(determined)X
+3884(after)X
+4018(LIBTP)X
+4214(has)X
+555 5633(been)N
+691(fully)X
+828(integrated)X
+1099(with)X
+1229(the)X
+1323(most)X
+1464(recent)X
+3 f
+1635(db)X
+1 f
+1707(\(3\))X
+1797(release)X
+1989(from)X
+2129(the)X
+2223(Computer)X
+2495(Systems)X
+2725(Research)X
+2974(Group)X
+3153(at)X
+3215(University)X
+3501(of)X
+3570(California,)X
+3861(Berkeley.)X
+
+11 p
+%%Page: 11 11
+8 s 8 xH 0 xS 1 f
+10 s
+3 f
+555 630(5.)N
+655(Performance)X
+1 f
+755 753(In)N
+845(this)X
+983(section,)X
+1253(we)X
+1370(present)X
+1625(the)X
+1746(results)X
+1978(of)X
+2067(two)X
+2209(very)X
+2374(different)X
+2673(benchmarks.)X
+3103(The)X
+3250(\256rst)X
+3396(is)X
+3471(an)X
+3569(online)X
+3791(transaction)X
+4165(pro-)X
+555 843(cessing)N
+824(benchmark,)X
+1234(similar)X
+1489(to)X
+1584(the)X
+1715(standard)X
+2020(TPCB,)X
+2272(but)X
+2407(has)X
+2547(been)X
+2732(adapted)X
+3015(to)X
+3110(run)X
+3250(in)X
+3345(a)X
+3414(desktop)X
+3696(environment.)X
+4174(The)X
+555 933(second)N
+798(emulates)X
+1103(a)X
+1159(computer-aided)X
+1683(design)X
+1912(environment)X
+2337(and)X
+2473(provides)X
+2769(more)X
+2954(complex)X
+3250(query)X
+3453(processing.)X
+3 f
+555 1119(5.1.)N
+715(Transaction)X
+1148(Processing)X
+1533(Benchmark)X
+1 f
+755 1242(For)N
+887(this)X
+1023(section,)X
+1291(all)X
+1392(performance)X
+1820(numbers)X
+2117(shown)X
+2346(except)X
+2576(for)X
+2690(the)X
+2808(commercial)X
+3207(database)X
+3504(system)X
+3746(were)X
+3923(obtained)X
+4219(on)X
+555 1332(a)N
+614(DECstation)X
+1009(5000/200)X
+1333(with)X
+1497(32MBytes)X
+1852(of)X
+1941(memory)X
+2230(running)X
+2501(Ultrix)X
+2714(V4.0,)X
+2914(accessing)X
+3244(a)X
+3302(DEC)X
+3484(RZ57)X
+3688(1GByte)X
+3959(disk)X
+4114(drive.)X
+555 1422(The)N
+720(commercial)X
+1139(relational)X
+1482(database)X
+1799(system)X
+2061(tests)X
+2242(were)X
+2438(run)X
+2584(on)X
+2703(a)X
+2778(comparable)X
+3192(machine,)X
+3523(a)X
+3598(Sparcstation)X
+4033(1+)X
+4157(with)X
+555 1512(32MBytes)N
+915(memory)X
+1209(and)X
+1352(a)X
+1415(1GByte)X
+1691(external)X
+1976(disk)X
+2135(drive.)X
+2366(The)X
+2517(database,)X
+2840(binaries)X
+3120(and)X
+3262(log)X
+3390(resided)X
+3648(on)X
+3754(the)X
+3878(same)X
+4069(device.)X
+555 1602(Reported)N
+869(times)X
+1062(are)X
+1181(the)X
+1299(means)X
+1524(of)X
+1611(\256ve)X
+1751(tests)X
+1913(and)X
+2049(have)X
+2221(standard)X
+2513(deviations)X
+2862(within)X
+3086(two)X
+3226(percent)X
+3483(of)X
+3570(the)X
+3688(mean.)X
+755 1725(The)N
+905(test)X
+1041(database)X
+1343(was)X
+1493(con\256gured)X
+1861(according)X
+2203(to)X
+2290(the)X
+2413(TPCB)X
+2637(scaling)X
+2889(rules)X
+3070(for)X
+3189(a)X
+3250(10)X
+3355(transaction)X
+3732(per)X
+3860(second)X
+4108(\(TPS\))X
+555 1815(system)N
+817(with)X
+999(1,000,000)X
+1359(account)X
+1649(records,)X
+1946(100)X
+2106(teller)X
+2311(records,)X
+2607(and)X
+2762(10)X
+2881(branch)X
+3139(records.)X
+3455(Where)X
+3709(TPS)X
+3885(numbers)X
+4200(are)X
+555 1905(reported,)N
+865(we)X
+981(are)X
+1102(running)X
+1373(a)X
+1431(modi\256ed)X
+1737(version)X
+1995(of)X
+2084(the)X
+2203(industry)X
+2486(standard)X
+2779(transaction)X
+3152(processing)X
+3516(benchmark,)X
+3914(TPCB.)X
+4174(The)X
+555 1995(TPCB)N
+780(benchmark)X
+1163(simulates)X
+1491(a)X
+1553(withdrawal)X
+1940(performed)X
+2301(by)X
+2407(a)X
+2469(hypothetical)X
+2891(teller)X
+3082(at)X
+3166(a)X
+3228(hypothetical)X
+3650(bank.)X
+3872(The)X
+4022(database)X
+555 2085(consists)N
+831(of)X
+921(relations)X
+1220(\(\256les\))X
+1430(for)X
+1547(accounts,)X
+1871(branches,)X
+2200(tellers,)X
+2439(and)X
+2578(history.)X
+2863(For)X
+2997(each)X
+3168(transaction,)X
+3563(the)X
+3684(account,)X
+3976(teller,)X
+4183(and)X
+555 2175(branch)N
+795(balances)X
+1093(must)X
+1269(be)X
+1366(updated)X
+1641(to)X
+1724(re\257ect)X
+1946(the)X
+2065(withdrawal)X
+2447(and)X
+2584(a)X
+2640(history)X
+2882(record)X
+3108(is)X
+3181(written)X
+3428(which)X
+3644(contains)X
+3931(the)X
+4049(account)X
+555 2265(id,)N
+657(branch)X
+896(id,)X
+998(teller)X
+1183(id,)X
+1285(and)X
+1421(the)X
+1539(amount)X
+1799(of)X
+1886(the)X
+2004(withdrawal)X
+2385([TPCB90].)X
+755 2388(Our)N
+914(implementation)X
+1450(of)X
+1551(the)X
+1683(benchmark)X
+2074(differs)X
+2317(from)X
+2506(the)X
+2637(speci\256cation)X
+3075(in)X
+3170(several)X
+3431(aspects.)X
+3736(The)X
+3894(speci\256cation)X
+555 2478(requires)N
+840(that)X
+985(the)X
+1108(database)X
+1410(keep)X
+1587(redundant)X
+1933(logs)X
+2091(on)X
+2196(different)X
+2498(devices,)X
+2784(but)X
+2911(we)X
+3030(use)X
+3162(a)X
+3223(single)X
+3439(log.)X
+3606(Furthermore,)X
+4052(all)X
+4157(tests)X
+555 2568(were)N
+734(run)X
+863(on)X
+965(a)X
+1023(single,)X
+1256(centralized)X
+1631(system)X
+1875(so)X
+1968(there)X
+2151(is)X
+2226(no)X
+2328(notion)X
+2553(of)X
+2641(remote)X
+2885(accesses.)X
+3219(Finally,)X
+3486(we)X
+3601(calculated)X
+3948(throughput)X
+555 2658(by)N
+662(dividing)X
+955(the)X
+1080(total)X
+1249(elapsed)X
+1517(time)X
+1686(by)X
+1793(the)X
+1918(number)X
+2190(of)X
+2284(transactions)X
+2694(processed)X
+3038(rather)X
+3253(than)X
+3418(by)X
+3525(computing)X
+3894(the)X
+4018(response)X
+555 2748(time)N
+717(for)X
+831(each)X
+999(transaction.)X
+755 2871(The)N
+912(performance)X
+1351(comparisons)X
+1788(focus)X
+1993(on)X
+2104(traditional)X
+2464(Unix)X
+2655(techniques)X
+3029(\(unprotected,)X
+3486(using)X
+3 f
+3690(\257ock)X
+1 f
+3854(\(2\))X
+3979(and)X
+4126(using)X
+3 f
+555 2961(fsync)N
+1 f
+733(\(2\)\))X
+884(and)X
+1030(a)X
+1096(commercial)X
+1504(relational)X
+1836(database)X
+2142(system.)X
+2433(Well-behaved)X
+2913(applications)X
+3329(using)X
+3 f
+3531(\257ock)X
+1 f
+3695(\(2\))X
+3818(are)X
+3946(guaranteed)X
+555 3051(that)N
+704(concurrent)X
+1077(processes')X
+1441(updates)X
+1715(do)X
+1824(not)X
+1955(interact)X
+2225(with)X
+2396(one)X
+2541(another,)X
+2831(but)X
+2962(no)X
+3070(guarantees)X
+3442(about)X
+3648(atomicity)X
+3978(are)X
+4105(made.)X
+555 3141(That)N
+731(is,)X
+833(if)X
+911(the)X
+1038(system)X
+1289(crashes)X
+1555(in)X
+1646(mid-transaction,)X
+2198(only)X
+2369(parts)X
+2554(of)X
+2649(that)X
+2797(transaction)X
+3177(will)X
+3329(be)X
+3433(re\257ected)X
+3738(in)X
+3828(the)X
+3954 0.3125(after-crash)AX
+555 3231(state)N
+725(of)X
+815(the)X
+936(database.)X
+1276(The)X
+1424(use)X
+1554(of)X
+3 f
+1643(fsync)X
+1 f
+1821(\(2\))X
+1937(at)X
+2017(transaction)X
+2391(commit)X
+2657(time)X
+2821(provides)X
+3119(guarantees)X
+3485(of)X
+3574(durability)X
+3907(after)X
+4077(system)X
+555 3321(failure.)N
+825(However,)X
+1160(there)X
+1341(is)X
+1414(no)X
+1514(mechanism)X
+1899(to)X
+1981(perform)X
+2260(transaction)X
+2632(abort.)X
+3 f
+555 3507(5.1.1.)N
+775(Single-User)X
+1191(Tests)X
+1 f
+755 3630(These)N
+978(tests)X
+1151(compare)X
+1459(LIBTP)X
+1712(in)X
+1804(a)X
+1870(variety)X
+2123(of)X
+2220(con\256gurations)X
+2708(to)X
+2800(traditional)X
+3159(UNIX)X
+3390(solutions)X
+3708(and)X
+3854(a)X
+3920(commercial)X
+555 3720(relational)N
+884(database)X
+1187(system)X
+1435(\(RDBMS\).)X
+1814(To)X
+1929(demonstrate)X
+2347(the)X
+2471(server)X
+2694(architecture)X
+3100(we)X
+3220(built)X
+3392(a)X
+3454(front)X
+3636(end)X
+3777(test)X
+3913(process)X
+4179(that)X
+555 3810(uses)N
+732(TCL)X
+922([OUST90])X
+1304(to)X
+1405(parse)X
+1614(database)X
+1930(access)X
+2175(commands)X
+2561(and)X
+2716(call)X
+2870(the)X
+3006(database)X
+3321(access)X
+3565(routines.)X
+3901(In)X
+4006(one)X
+4160(case)X
+555 3900(\(SERVER\),)N
+956(frontend)X
+1249(and)X
+1386(backend)X
+1675(processes)X
+2004(were)X
+2181(created)X
+2434(which)X
+2650(communicated)X
+3142(via)X
+3260(an)X
+3356(IP)X
+3447(socket.)X
+3712(In)X
+3799(the)X
+3917(second)X
+4160(case)X
+555 3990(\(TCL\),)N
+802(a)X
+860(single)X
+1073(process)X
+1336(read)X
+1497(queries)X
+1751(from)X
+1929(standard)X
+2223(input,)X
+2429(parsed)X
+2660(them,)X
+2861(and)X
+2998(called)X
+3211(the)X
+3330(database)X
+3628(access)X
+3855(routines.)X
+4174(The)X
+555 4080(performance)N
+987(difference)X
+1338(between)X
+1630(the)X
+1752(TCL)X
+1927(and)X
+2067(SERVER)X
+2397(tests)X
+2563(quanti\256es)X
+2898(the)X
+3020(communication)X
+3542(overhead)X
+3861(of)X
+3952(the)X
+4074(socket.)X
+555 4170(The)N
+732(RDBMS)X
+1063(implementation)X
+1617(used)X
+1816(embedded)X
+2198(SQL)X
+2401(in)X
+2515(C)X
+2620(with)X
+2814(stored)X
+3062(database)X
+3391(procedures.)X
+3835(Therefore,)X
+4224(its)X
+555 4260(con\256guration)N
+1003(is)X
+1076(a)X
+1132(hybrid)X
+1361(of)X
+1448(the)X
+1566(single)X
+1777(process)X
+2038(architecture)X
+2438(and)X
+2574(the)X
+2692(server)X
+2909(architecture.)X
+3349(The)X
+3494(graph)X
+3697(in)X
+3779(\256gure)X
+3986(six)X
+4099(shows)X
+555 4350(a)N
+611(comparison)X
+1005(of)X
+1092(the)X
+1210(following)X
+1541(six)X
+1654(con\256gurations:)X
+1126 4506(LIBTP)N
+1552(Uses)X
+1728(the)X
+1846(LIBTP)X
+2088(library)X
+2322(in)X
+2404(a)X
+2460(single)X
+2671(application.)X
+1126 4596(TCL)N
+1552(Uses)X
+1728(the)X
+1846(LIBTP)X
+2088(library)X
+2322(in)X
+2404(a)X
+2460(single)X
+2671(application,)X
+3067(requires)X
+3346(query)X
+3549(parsing.)X
+1126 4686(SERVER)N
+1552(Uses)X
+1728(the)X
+1846(LIBTP)X
+2088(library)X
+2322(in)X
+2404(a)X
+2460(server)X
+2677(con\256guration,)X
+3144(requires)X
+3423(query)X
+3626(parsing.)X
+1126 4776(NOTP)N
+1552(Uses)X
+1728(no)X
+1828(locking,)X
+2108(logging,)X
+2392(or)X
+2479(concurrency)X
+2897(control.)X
+1126 4866(FLOCK)N
+1552(Uses)X
+3 f
+1728(\257ock)X
+1 f
+1892(\(2\))X
+2006(for)X
+2120(concurrency)X
+2538(control)X
+2785(and)X
+2921(nothing)X
+3185(for)X
+3299(durability.)X
+1126 4956(FSYNC)N
+1552(Uses)X
+3 f
+1728(fsync)X
+1 f
+1906(\(2\))X
+2020(for)X
+2134(durability)X
+2465(and)X
+2601(nothing)X
+2865(for)X
+2979(concurrency)X
+3397(control.)X
+1126 5046(RDBMS)N
+1552(Uses)X
+1728(a)X
+1784(commercial)X
+2183(relational)X
+2506(database)X
+2803(system.)X
+755 5235(The)N
+902(results)X
+1133(show)X
+1324(that)X
+1466(LIBTP,)X
+1730(both)X
+1894(in)X
+1978(the)X
+2098(procedural)X
+2464(and)X
+2602(parsed)X
+2834(environments,)X
+3312(is)X
+3387(competitive)X
+3787(with)X
+3951(a)X
+4009(commer-)X
+555 5325(cial)N
+692(system)X
+935(\(comparing)X
+1326(LIBTP,)X
+1589(TCL,)X
+1781(and)X
+1917(RDBMS\).)X
+2263(Compared)X
+2617(to)X
+2699(existing)X
+2972(UNIX)X
+3193(solutions,)X
+3521(LIBTP)X
+3763(is)X
+3836(approximately)X
+555 5415(15%)N
+738(slower)X
+988(than)X
+1162(using)X
+3 f
+1371(\257ock)X
+1 f
+1535(\(2\))X
+1665(or)X
+1768(no)X
+1884(protection)X
+2245(but)X
+2383(over)X
+2562(80%)X
+2745(better)X
+2964(than)X
+3137(using)X
+3 f
+3345(fsync)X
+1 f
+3523(\(2\))X
+3652(\(comparing)X
+4057(LIBTP,)X
+555 5505(FLOCK,)N
+857(NOTP,)X
+1106(and)X
+1242(FSYNC\).)X
+
+12 p
+%%Page: 12 12
+10 s 10 xH 0 xS 1 f
+3 f
+8 s
+3500 2184(RDBMS)N
+1 Dt
+3553 2085 MXY
+ 3553 2085 lineto
+ 3676 2085 lineto
+ 3676 1351 lineto
+ 3553 1351 lineto
+ 3553 2085 lineto
+closepath 16 3553 1351 3676 2085 Dp
+2018 2184(SERVER)N
+1720 1168 MXY
+0 917 Dl
+122 0 Dl
+0 -917 Dl
+-122 0 Dl
+1715 2184(TCL)N
+2087 1534 MXY
+ 2087 1534 lineto
+ 2209 1534 lineto
+ 2209 2085 lineto
+ 2087 2085 lineto
+ 2087 1534 lineto
+closepath 12 2087 1534 2209 2085 Dp
+3187 MX
+ 3187 1534 lineto
+ 3309 1534 lineto
+ 3309 2085 lineto
+ 3187 2085 lineto
+ 3187 1534 lineto
+closepath 19 3187 1534 3309 2085 Dp
+3142 2184(FSYNC)N
+2425(NOTP)X
+2453 955 MXY
+ 2453 955 lineto
+ 2576 955 lineto
+ 2576 2085 lineto
+ 2453 2085 lineto
+ 2453 955 lineto
+closepath 21 2453 955 2576 2085 Dp
+2820 1000 MXY
+ 2820 1000 lineto
+ 2942 1000 lineto
+ 2942 2085 lineto
+ 2820 2085 lineto
+ 2820 1000 lineto
+closepath 14 2820 1000 2942 2085 Dp
+5 Dt
+1231 2085 MXY
+2567 0 Dl
+4 Ds
+1 Dt
+1231 1840 MXY
+2567 0 Dl
+1231 1596 MXY
+2567 0 Dl
+1231 1351 MXY
+2567 0 Dl
+1231 1108 MXY
+2567 0 Dl
+1231 863 MXY
+2567 0 Dl
+11 s
+1087 1877(2)N
+1087 1633(4)N
+1087 1388(6)N
+1087 1145(8)N
+1065 900(10)N
+1028 763(TPS)N
+-1 Ds
+1353 2085 MXY
+ 1353 2085 lineto
+ 1353 1151 lineto
+ 1476 1151 lineto
+ 1476 2085 lineto
+ 1353 2085 lineto
+closepath 3 1353 1151 1476 2085 Dp
+8 s
+1318 2184(LIBTP)N
+2767(FLOCK)X
+3 Dt
+-1 Ds
+10 s
+1597 2399(Figure)N
+1844(6:)X
+1931(Single-User)X
+2347(Performance)X
+2814(Comparison.)X
+1 f
+10 f
+555 2579(h)N
+579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X
+3 f
+555 2855(5.1.2.)N
+775(Multi-User)X
+1174(Tests)X
+1 f
+755 2978(While)N
+975(the)X
+1097(single-user)X
+1473(tests)X
+1639(form)X
+1819(a)X
+1878(basis)X
+2061(for)X
+2178(comparing)X
+2544(LIBTP)X
+2789(to)X
+2874(other)X
+3062(systems,)X
+3358(our)X
+3488(goal)X
+3649(in)X
+3734(multi-user)X
+4086(testing)X
+555 3068(was)N
+714(to)X
+810(analyze)X
+1089(its)X
+1197(scalability.)X
+1579(To)X
+1701(this)X
+1849(end,)X
+2018(we)X
+2145(have)X
+2330(run)X
+2470(the)X
+2601(benchmark)X
+2991(in)X
+3086(three)X
+3280(modes,)X
+3542(the)X
+3673(normal)X
+3933(disk)X
+4099(bound)X
+555 3158(con\256guration)N
+1010(\(\256gure)X
+1252(seven\),)X
+1510(a)X
+1573(CPU)X
+1755(bound)X
+1982(con\256guration)X
+2436(\(\256gure)X
+2677(eight,)X
+2884(READ-ONLY\),)X
+3426(and)X
+3569(lock)X
+3734(contention)X
+4099(bound)X
+555 3248(\(\256gure)N
+796(eight,)X
+1003(NO_FSYNC\).)X
+1510(Since)X
+1715(the)X
+1840(normal)X
+2094(con\256guration)X
+2548(is)X
+2628(completely)X
+3011(disk)X
+3171(bound)X
+3398(\(each)X
+3600(transaction)X
+3978(requires)X
+4263(a)X
+555 3354(random)N
+823(read,)X
+1005(a)X
+1064(random)X
+1332(write,)X
+1540(and)X
+1679(a)X
+1738(sequential)X
+2086(write)X
+7 s
+2251 3322(4)N
+10 s
+3354(\))Y
+2329(we)X
+2446(expect)X
+2679(to)X
+2764(see)X
+2890(little)X
+3059(performance)X
+3489(improvement)X
+3939(as)X
+4028(the)X
+4148(mul-)X
+555 3444(tiprogramming)N
+1064(level)X
+1249(increases.)X
+1613(In)X
+1709(fact,)X
+1879(\256gure)X
+2095(seven)X
+2307(reveals)X
+2564(that)X
+2713(we)X
+2836(are)X
+2964(able)X
+3127(to)X
+3218(overlap)X
+3487(CPU)X
+3670(and)X
+3814(disk)X
+3975(utilization)X
+555 3534(slightly)N
+825(producing)X
+1181(approximately)X
+1674(a)X
+1740(10%)X
+1917(performance)X
+2354(improvement)X
+2811(with)X
+2983(two)X
+3133(processes.)X
+3511(After)X
+3711(that)X
+3861(point,)X
+4075(perfor-)X
+555 3624(mance)N
+785(drops)X
+983(off,)X
+1117(and)X
+1253(at)X
+1331(a)X
+1387(multi-programming)X
+2038(level)X
+2214(of)X
+2301(4,)X
+2381(we)X
+2495(are)X
+2614(performing)X
+2995(worse)X
+3207(than)X
+3365(in)X
+3447(the)X
+3565(single)X
+3776(process)X
+4037(case.)X
+755 3747(Similar)N
+1021(behavior)X
+1333(was)X
+1489(reported)X
+1787(on)X
+1897(the)X
+2025(commercial)X
+2434(relational)X
+2767(database)X
+3074(system)X
+3326(using)X
+3529(the)X
+3657(same)X
+3852(con\256guration.)X
+555 3837(The)N
+707(important)X
+1045(conclusion)X
+1419(to)X
+1508(draw)X
+1696(from)X
+1879(this)X
+2021(is)X
+2101(that)X
+2248(you)X
+2395(cannot)X
+2636(attain)X
+2841(good)X
+3028(multi-user)X
+3384(scaling)X
+3638(on)X
+3745(a)X
+3808(badly)X
+4013(balanced)X
+555 3927(system.)N
+839(If)X
+915(multi-user)X
+1266(performance)X
+1695(on)X
+1797(applications)X
+2205(of)X
+2293(this)X
+2429(sort)X
+2570(is)X
+2644(important,)X
+2996(one)X
+3133(must)X
+3309(have)X
+3482(a)X
+3539(separate)X
+3824(logging)X
+4089(device)X
+555 4017(and)N
+697(horizontally)X
+1110(partition)X
+1407(the)X
+1531(database)X
+1834(to)X
+1921(allow)X
+2124(a)X
+2185(suf\256ciently)X
+2570(high)X
+2737(degree)X
+2977(of)X
+3069(multiprogramming)X
+3698(that)X
+3843(group)X
+4055(commit)X
+555 4107(can)N
+687(amortize)X
+988(the)X
+1106(cost)X
+1255(of)X
+1342(log)X
+1464(\257ushing.)X
+755 4230(By)N
+871(using)X
+1067(a)X
+1126(very)X
+1292(small)X
+1488(database)X
+1788(\(one)X
+1954(that)X
+2097(can)X
+2232(be)X
+2331(entirely)X
+2599(cached)X
+2846(in)X
+2930(main)X
+3112(memory\))X
+3428(and)X
+3566(read-only)X
+3896(transactions,)X
+555 4320(we)N
+670(generated)X
+1004(a)X
+1061(CPU)X
+1236(bound)X
+1456(environment.)X
+1921(By)X
+2034(using)X
+2227(the)X
+2345(same)X
+2530(small)X
+2723(database,)X
+3040(the)X
+3158(complete)X
+3472(TPCB)X
+3691(transaction,)X
+4083(and)X
+4219(no)X
+3 f
+555 4410(fsync)N
+1 f
+733(\(2\))X
+862(on)X
+977(the)X
+1110(log)X
+1247(at)X
+1340(commit,)X
+1639(we)X
+1768(created)X
+2036(a)X
+2107(lock)X
+2280(contention)X
+2652(bound)X
+2886(environment.)X
+3365(The)X
+3524(small)X
+3731(database)X
+4042(used)X
+4223(an)X
+555 4500(account)N
+828(\256le)X
+953(containing)X
+1314(only)X
+1479(1000)X
+1662(records)X
+1922(rather)X
+2133(than)X
+2294(the)X
+2415(full)X
+2549(1,000,000)X
+2891(records)X
+3150(and)X
+3288(ran)X
+3413(enough)X
+3671(transactions)X
+4076(to)X
+4160(read)X
+555 4590(the)N
+677(entire)X
+883(database)X
+1183(into)X
+1330(the)X
+1451(buffer)X
+1671(pool)X
+1836(\(2000\))X
+2073(before)X
+2302(beginning)X
+2645(measurements.)X
+3147(The)X
+3295(read-only)X
+3626(transaction)X
+4001(consisted)X
+555 4680(of)N
+646(three)X
+831(database)X
+1132(reads)X
+1326(\(from)X
+1533(the)X
+1655(1000)X
+1839(record)X
+2069(account)X
+2343(\256le,)X
+2489(the)X
+2611(100)X
+2754(record)X
+2983(teller)X
+3171(\256le,)X
+3316(and)X
+3455(the)X
+3576(10)X
+3679(record)X
+3908(branch)X
+4150(\256le\).)X
+555 4770(Since)N
+759(no)X
+865(data)X
+1025(were)X
+1208(modi\256ed)X
+1518(and)X
+1660(no)X
+1766(history)X
+2014(records)X
+2277(were)X
+2460(written,)X
+2733(no)X
+2839(log)X
+2966(records)X
+3228(were)X
+3410(written.)X
+3702(For)X
+3838(the)X
+3961(contention)X
+555 4860(bound)N
+780(con\256guration,)X
+1252(we)X
+1371(used)X
+1543(the)X
+1666(normal)X
+1918(TPCB)X
+2142(transaction)X
+2519(\(against)X
+2798(the)X
+2920(small)X
+3117(database\))X
+3445(and)X
+3585(disabled)X
+3876(the)X
+3998(log)X
+4124(\257ush.)X
+555 4950(Figure)N
+784(eight)X
+964(shows)X
+1184(both)X
+1346(of)X
+1433(these)X
+1618(results.)X
+755 5073(The)N
+902(read-only)X
+1231(test)X
+1363(indicates)X
+1669(that)X
+1810(we)X
+1925(barely)X
+2147(scale)X
+2329(at)X
+2408(all)X
+2509(in)X
+2592(the)X
+2711(CPU)X
+2887(bound)X
+3108(case.)X
+3308(The)X
+3454(explanation)X
+3849(for)X
+3964(that)X
+4105(is)X
+4179(that)X
+555 5163(even)N
+735(with)X
+905(a)X
+969(single)X
+1188(process,)X
+1477(we)X
+1599(are)X
+1726(able)X
+1888(to)X
+1978(drive)X
+2171(the)X
+2297(CPU)X
+2480(utilization)X
+2832(to)X
+2922(96%.)X
+3137(As)X
+3254(a)X
+3317(result,)X
+3542(that)X
+3689(gives)X
+3885(us)X
+3983(very)X
+4153(little)X
+555 5253(room)N
+753(for)X
+876(improvement,)X
+1352(and)X
+1497(it)X
+1570(takes)X
+1764(a)X
+1829(multiprogramming)X
+2462(level)X
+2647(of)X
+2743(four)X
+2906(to)X
+2997(approach)X
+3321(100%)X
+3537(CPU)X
+3721(saturation.)X
+4106(In)X
+4201(the)X
+555 5343(case)N
+718(where)X
+939(we)X
+1057(do)X
+1161(perform)X
+1444(writes,)X
+1684(we)X
+1802(are)X
+1925(interested)X
+2261(in)X
+2347(detecting)X
+2665(when)X
+2863(lock)X
+3025(contention)X
+3387(becomes)X
+3691(a)X
+3750(dominant)X
+4075(perfor-)X
+555 5433(mance)N
+787(factor.)X
+1037(Contention)X
+1414(will)X
+1560(cause)X
+1761(two)X
+1903(phenomena;)X
+2317(we)X
+2433(will)X
+2579(see)X
+2704(transactions)X
+3109(queueing)X
+3425(behind)X
+3665(frequently)X
+4017(accessed)X
+555 5523(data,)N
+731(and)X
+869(we)X
+985(will)X
+1131(see)X
+1256(transaction)X
+1629(abort)X
+1815(rates)X
+1988(increasing)X
+2339(due)X
+2476(to)X
+2559(deadlock.)X
+2910(Given)X
+3127(that)X
+3268(the)X
+3387(branch)X
+3627(\256le)X
+3750(contains)X
+4038(only)X
+4201(ten)X
+8 s
+10 f
+555 5595(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N
+5 s
+1 f
+727 5673(4)N
+8 s
+763 5698(Although)N
+1021(the)X
+1115(log)X
+1213(is)X
+1272(written)X
+1469(sequentially,)X
+1810(we)X
+1900(do)X
+1980(not)X
+2078(get)X
+2172(the)X
+2266(bene\256t)X
+2456(of)X
+2525(sequentiality)X
+2868(since)X
+3015(the)X
+3109(log)X
+3207(and)X
+3315(database)X
+3550(reside)X
+3718(on)X
+3798(the)X
+3892(same)X
+4039(disk.)X
+
+13 p
+%%Page: 13 13
+8 s 8 xH 0 xS 1 f
+10 s
+3 f
+1 f
+3187 2051 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3286 2028 MXY
+0 17 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3384 1926 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3483 1910 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3581 1910 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3680 1832 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3778 1909 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3877 1883 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3975 1679 MXY
+0 17 Dl
+0 -8 Dl
+9 0 Dl
+-18 0 Dl
+4074 1487 MXY
+0 17 Dl
+0 -8 Dl
+9 0 Dl
+-18 0 Dl
+5 Dt
+3187 2060 MXY
+99 -24 Dl
+98 -101 Dl
+99 -16 Dl
+98 0 Dl
+99 -78 Dl
+98 77 Dl
+99 -26 Dl
+98 -204 Dl
+99 -192 Dl
+3 f
+6 s
+4088 1516(SMALL)N
+3 Dt
+3187 2051 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3286 2051 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3384 2041 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3483 1990 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3581 1843 MXY
+0 17 Dl
+0 -8 Dl
+9 0 Dl
+-18 0 Dl
+3680 1578 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3778 1496 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3877 1430 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+3975 1269 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+4074 1070 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+1 Dt
+3187 2060 MXY
+99 0 Dl
+98 -10 Dl
+99 -51 Dl
+98 -147 Dl
+99 -265 Dl
+98 -82 Dl
+99 -66 Dl
+98 -161 Dl
+99 -199 Dl
+4088 1099(LARGE)N
+5 Dt
+3089 2060 MXY
+985 0 Dl
+3089 MX
+0 -1174 Dl
+4 Ds
+1 Dt
+3581 2060 MXY
+0 -1174 Dl
+4074 2060 MXY
+0 -1174 Dl
+3089 1825 MXY
+985 0 Dl
+9 s
+2993 1855(25)N
+3089 1591 MXY
+985 0 Dl
+2993 1621(50)N
+3089 1356 MXY
+985 0 Dl
+2993 1386(75)N
+3089 1121 MXY
+985 0 Dl
+2957 1151(100)N
+3089 886 MXY
+985 0 Dl
+2957 916(125)N
+3281 2199(Multiprogramming)N
+3071 2152(0)N
+3569(5)X
+4038(10)X
+2859 787(Aborts)N
+3089(per)X
+3211(500)X
+2901 847(transactions)N
+-1 Ds
+3 Dt
+2037 1342 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2125 1358 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2213 1341 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2301 1191 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2388 1124 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-17 0 Dl
+2476 1157 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2564 1157 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2652 1161 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2740 1153 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2828 1150 MXY
+0 18 Dl
+0 -9 Dl
+8 0 Dl
+-17 0 Dl
+5 Dt
+2037 1351 MXY
+88 16 Dl
+88 -17 Dl
+88 -150 Dl
+87 -67 Dl
+88 33 Dl
+88 0 Dl
+88 4 Dl
+88 -8 Dl
+88 -3 Dl
+6 s
+2685 1234(READ-ONLY)N
+3 Dt
+2037 1464 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2125 1640 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2213 1854 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2301 1872 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2388 1871 MXY
+0 17 Dl
+0 -9 Dl
+9 0 Dl
+-17 0 Dl
+2476 1933 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2564 1914 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2652 1903 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2740 1980 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+2828 2004 MXY
+0 18 Dl
+0 -9 Dl
+8 0 Dl
+-17 0 Dl
+1 Dt
+2037 1473 MXY
+88 176 Dl
+88 214 Dl
+88 18 Dl
+87 -2 Dl
+88 63 Dl
+88 -19 Dl
+88 -11 Dl
+88 77 Dl
+88 24 Dl
+2759 1997(NO-FSYNC)N
+5 Dt
+1949 2060 MXY
+879 0 Dl
+1949 MX
+0 -1174 Dl
+4 Ds
+1 Dt
+2388 2060 MXY
+0 -1174 Dl
+2828 2060 MXY
+0 -1174 Dl
+1949 1825 MXY
+879 0 Dl
+9 s
+1842 1855(40)N
+1949 1591 MXY
+879 0 Dl
+1842 1621(80)N
+1949 1356 MXY
+879 0 Dl
+1806 1386(120)N
+1949 1121 MXY
+879 0 Dl
+1806 1151(160)N
+1949 886 MXY
+879 0 Dl
+1806 916(200)N
+2088 2199(Multiprogramming)N
+1844 863(in)N
+1922(TPS)X
+1761 792(Throughput)N
+1931 2121(0)N
+2370 2133(5)N
+2792(10)X
+6 s
+1679 1833(LIBTP)N
+-1 Ds
+3 Dt
+837 1019 MXY
+0 17 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+929 878 MXY
+0 17 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+1021 939 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+1113 1043 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+1205 1314 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+1297 1567 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+1389 1665 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+1481 1699 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+1573 1828 MXY
+0 18 Dl
+0 -9 Dl
+9 0 Dl
+-18 0 Dl
+1665 1804 MXY
+0 18 Dl
+0 -9 Dl
+8 0 Dl
+-17 0 Dl
+5 Dt
+837 1027 MXY
+92 -141 Dl
+92 62 Dl
+92 104 Dl
+92 271 Dl
+92 253 Dl
+92 98 Dl
+92 34 Dl
+92 129 Dl
+92 -24 Dl
+745 2060 MXY
+920 0 Dl
+745 MX
+0 -1174 Dl
+4 Ds
+1 Dt
+1205 2060 MXY
+0 -1174 Dl
+1665 2060 MXY
+0 -1174 Dl
+745 1766 MXY
+920 0 Dl
+9 s
+673 1796(3)N
+745 1473 MXY
+920 0 Dl
+673 1503(5)N
+745 1180 MXY
+920 0 Dl
+673 1210(8)N
+745 886 MXY
+920 0 Dl
+637 916(10)N
+905 2199(Multiprogramming)N
+622 851(in)N
+700(TPS)X
+575 792(Throughput)N
+733 2152(0)N
+1196(5)X
+1629(10)X
+3 Dt
+-1 Ds
+8 s
+655 2441(Figure)N
+872(7:)X
+960(Multi-user)X
+1286(Performance.)X
+1 f
+655 2531(Since)N
+825(the)X
+931(con\256guration)X
+1300(is)X
+1371(completely)X
+655 2621(disk)N
+790(bound,)X
+994(we)X
+1096(see)X
+1204(only)X
+1345(a)X
+1400(small)X
+1566(im-)X
+655 2711(provement)N
+964(by)X
+1064(adding)X
+1274(a)X
+1337(second)X
+1549(pro-)X
+655 2801(cess.)N
+849(Adding)X
+1081(any)X
+1213(more)X
+1383(concurrent)X
+655 2891(processes)N
+935(causes)X
+1137(performance)X
+1493(degra-)X
+655 2981(dation.)N
+3 f
+1927 2441(Figure)N
+2149(8:)X
+2243(Multi-user)X
+2574(Performance)X
+1927 2531(on)N
+2021(a)X
+2079(small)X
+2251(database.)X
+1 f
+2551(With)X
+2704(one)X
+2821(pro-)X
+1927 2621(cess,)N
+2075(we)X
+2174(are)X
+2276(driving)X
+2486(the)X
+2589(CPU)X
+2739(at)X
+2810(96%)X
+1927 2711(utilization)N
+2215(leaving)X
+2430(little)X
+2575(room)X
+2737(for)X
+2838(im-)X
+1927 2801(provement)N
+2238(as)X
+2328(the)X
+2443(multiprogramming)X
+1927 2891(level)N
+2091(increases.)X
+2396(In)X
+2489(the)X
+2607(NO-FSYNC)X
+1927 2981(case,)N
+2076(lock)X
+2209(contention)X
+2502(degrades)X
+2751(perfor-)X
+1927 3071(mance)N
+2117(as)X
+2194(soon)X
+2339(as)X
+2416(a)X
+2468(second)X
+2669(process)X
+2884(is)X
+1927 3161(added.)N
+3 f
+3199 2441(Figure)N
+3405(9:)X
+3482(Abort)X
+3669(rates)X
+3827(on)X
+3919(the)X
+4028(TPCB)X
+3199 2531(Benchmark.)N
+1 f
+3589(The)X
+3726(abort)X
+3895(rate)X
+4028(climbs)X
+3199 2621(more)N
+3366(quickly)X
+3594(for)X
+3704(the)X
+3818(large)X
+3980(database)X
+3199 2711(test)N
+3324(since)X
+3491(processes)X
+3771(are)X
+3884(descheduled)X
+3199 2801(more)N
+3409(frequently,)X
+3766(allowing)X
+4068(more)X
+3199 2891(processes)N
+3459(to)X
+3525(vie)X
+3619(for)X
+3709(the)X
+3803(same)X
+3950(locks.)X
+10 s
+10 f
+555 3284(h)N
+579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X
+1 f
+555 3560(records,)N
+835(we)X
+952(expect)X
+1185(contention)X
+1546(to)X
+1631(become)X
+1904(a)X
+1963(factor)X
+2174(quickly)X
+2437(and)X
+2576(the)X
+2697(NO-FSYNC)X
+3120(line)X
+3263(in)X
+3348(\256gure)X
+3557(eight)X
+3739(demonstrates)X
+4184(this)X
+555 3650(dramatically.)N
+1022(Each)X
+1209(additional)X
+1555(process)X
+1822(causes)X
+2058(both)X
+2226(more)X
+2417(waiting)X
+2682(and)X
+2823(more)X
+3013(deadlocking.)X
+3470(Figure)X
+3704(nine)X
+3867(shows)X
+4092(that)X
+4237(in)X
+555 3740(the)N
+681(small)X
+882(database)X
+1187(case)X
+1353(\(SMALL\),)X
+1725(waiting)X
+1992(is)X
+2072(the)X
+2197(dominant)X
+2526(cause)X
+2732(of)X
+2826(declining)X
+3151(performance)X
+3585(\(the)X
+3737(number)X
+4009(of)X
+4103(aborts)X
+555 3830(increases)N
+878(less)X
+1026(steeply)X
+1281(than)X
+1447(the)X
+1573(performance)X
+2008(drops)X
+2214(off)X
+2336(in)X
+2426(\256gure)X
+2641(eight\),)X
+2876(while)X
+3082(in)X
+3172(the)X
+3298(large)X
+3487(database)X
+3792(case)X
+3958(\(LARGE\),)X
+555 3920(deadlocking)N
+967(contributes)X
+1343(more)X
+1528(to)X
+1610(the)X
+1728(declining)X
+2046(performance.)X
+755 4043(Deadlocks)N
+1116(are)X
+1237(more)X
+1424(likely)X
+1628(to)X
+1712(occur)X
+1913(in)X
+1997(the)X
+2116(LARGE)X
+2404(test)X
+2536(than)X
+2695(in)X
+2778(the)X
+2897(SMALL)X
+3189(test)X
+3321(because)X
+3597(there)X
+3779(are)X
+3899(more)X
+4085(oppor-)X
+555 4133(tunities)N
+814(to)X
+900(wait.)X
+1082(In)X
+1173(the)X
+1295(SMALL)X
+1590(case,)X
+1773(processes)X
+2105(never)X
+2307(do)X
+2410(I/O)X
+2540(and)X
+2679(are)X
+2801(less)X
+2944(likely)X
+3149(to)X
+3234(be)X
+3333(descheduled)X
+3753(during)X
+3985(a)X
+4044(transac-)X
+555 4223(tion.)N
+740(In)X
+828(the)X
+947(LARGE)X
+1235(case,)X
+1415(processes)X
+1744(will)X
+1889(frequently)X
+2240(be)X
+2337(descheduled)X
+2755(since)X
+2941(they)X
+3100(have)X
+3273(to)X
+3356(perform)X
+3636(I/O.)X
+3804(This)X
+3967(provides)X
+4263(a)X
+555 4313(window)N
+837(where)X
+1058(a)X
+1118(second)X
+1365(process)X
+1630(can)X
+1766(request)X
+2022(locks)X
+2215(on)X
+2318(already)X
+2578(locked)X
+2815(pages,)X
+3041(thus)X
+3197(increasing)X
+3550(the)X
+3671(likelihood)X
+4018(of)X
+4108(build-)X
+555 4403(ing)N
+677(up)X
+777(long)X
+939(chains)X
+1164(of)X
+1251(waiting)X
+1511(processes.)X
+1879(Eventually,)X
+2266(this)X
+2401(leads)X
+2586(to)X
+2668(deadlock.)X
+3 f
+555 4589(5.2.)N
+715(The)X
+868(OO1)X
+1052(Benchmark)X
+1 f
+755 4712(The)N
+903(TPCB)X
+1125(benchmark)X
+1505(described)X
+1836(in)X
+1921(the)X
+2042(previous)X
+2341(section)X
+2591(measures)X
+2913(performance)X
+3343(under)X
+3549(a)X
+3608(conventional)X
+4044(transac-)X
+555 4802(tion)N
+706(processing)X
+1076(workload.)X
+1446(Other)X
+1656(application)X
+2039(domains,)X
+2357(such)X
+2531(as)X
+2625(computer-aided)X
+3156(design,)X
+3412(have)X
+3591(substantially)X
+4022(different)X
+555 4892(access)N
+786(patterns.)X
+1105(In)X
+1197(order)X
+1392(to)X
+1479(measure)X
+1772(the)X
+1895(performance)X
+2327(of)X
+2418(LIBTP)X
+2664(under)X
+2871(workloads)X
+3229(of)X
+3320(this)X
+3459(type,)X
+3641(we)X
+3759(implemented)X
+4201(the)X
+555 4982(OO1)N
+731(benchmark)X
+1108(described)X
+1436(in)X
+1518([CATT91].)X
+755 5105(The)N
+908(database)X
+1213(models)X
+1472(a)X
+1535(set)X
+1651(of)X
+1745(electronics)X
+2120(components)X
+2534(with)X
+2703(connections)X
+3113(among)X
+3358(them.)X
+3585(One)X
+3746(table)X
+3929(stores)X
+4143(parts)X
+555 5195(and)N
+696(another)X
+962(stores)X
+1174(connections.)X
+1622(There)X
+1835(are)X
+1959(three)X
+2145(connections)X
+2552(originating)X
+2927(at)X
+3009(any)X
+3149(given)X
+3351(part.)X
+3540(Ninety)X
+3782(percent)X
+4043(of)X
+4134(these)X
+555 5285(connections)N
+960(are)X
+1081(to)X
+1165(nearby)X
+1406(parts)X
+1584(\(those)X
+1802(with)X
+1966(nearby)X
+2 f
+2207(ids)X
+1 f
+2300(\))X
+2348(to)X
+2431(model)X
+2652(the)X
+2771(spatial)X
+3001(locality)X
+3262(often)X
+3448(exhibited)X
+3767(in)X
+3850(CAD)X
+4040(applica-)X
+555 5375(tions.)N
+779(Ten)X
+933(percent)X
+1198(of)X
+1293(the)X
+1419(connections)X
+1830(are)X
+1957(randomly)X
+2292(distributed)X
+2662(among)X
+2908(all)X
+3016(other)X
+3209(parts)X
+3393(in)X
+3483(the)X
+3609(database.)X
+3954(Every)X
+4174(part)X
+555 5465(appears)N
+829(exactly)X
+1089(three)X
+1278(times)X
+1479(in)X
+1569(the)X
+2 f
+1695(from)X
+1 f
+1874(\256eld)X
+2043(of)X
+2137(a)X
+2200(connection)X
+2579(record,)X
+2832(and)X
+2975(zero)X
+3141(or)X
+3235(more)X
+3427(times)X
+3627(in)X
+3716(the)X
+2 f
+3841(to)X
+1 f
+3930(\256eld.)X
+4139(Parts)X
+555 5555(have)N
+2 f
+727(x)X
+1 f
+783(and)X
+2 f
+919(y)X
+1 f
+975(locations)X
+1284(set)X
+1393(randomly)X
+1720(in)X
+1802(an)X
+1898(appropriate)X
+2284(range.)X
+
+14 p
+%%Page: 14 14
+10 s 10 xH 0 xS 1 f
+3 f
+1 f
+755 630(The)N
+900(intent)X
+1102(of)X
+1189(OO1)X
+1365(is)X
+1438(to)X
+1520(measure)X
+1808(the)X
+1926(overall)X
+2169(cost)X
+2318(of)X
+2405(a)X
+2461(query)X
+2664(mix)X
+2808(characteristic)X
+3257(of)X
+3344(engineering)X
+3743(database)X
+4040(applica-)X
+555 720(tions.)N
+770(There)X
+978(are)X
+1097(three)X
+1278(tests:)X
+10 f
+635 843(g)N
+2 f
+755(Lookup)X
+1 f
+1022(generates)X
+1353(1,000)X
+1560(random)X
+1832(part)X
+2 f
+1984(ids)X
+1 f
+2077(,)X
+2124(fetches)X
+2378(the)X
+2502(corresponding)X
+2987(parts)X
+3169(from)X
+3351(the)X
+3475(database,)X
+3798(and)X
+3940(calls)X
+4113(a)X
+4175(null)X
+755 933(procedure)N
+1097(in)X
+1179(the)X
+1297(host)X
+1450(programming)X
+1906(language)X
+2216(with)X
+2378(the)X
+2496(parts')X
+2 f
+2699(x)X
+1 f
+2755(and)X
+2 f
+2891(y)X
+1 f
+2947(positions.)X
+10 f
+635 1056(g)N
+2 f
+755(Traverse)X
+1 f
+1067(retrieves)X
+1371(a)X
+1434(random)X
+1706(part)X
+1858(from)X
+2041(the)X
+2166(database)X
+2470(and)X
+2613(follows)X
+2880(connections)X
+3290(from)X
+3473(it)X
+3544(to)X
+3632(other)X
+3823(parts.)X
+4045(Each)X
+4232(of)X
+755 1146(those)N
+947(parts)X
+1126(is)X
+1202(retrieved,)X
+1531(and)X
+1670(all)X
+1773(connections)X
+2179(from)X
+2358(it)X
+2424(followed.)X
+2771(This)X
+2935(procedure)X
+3279(is)X
+3354(repeated)X
+3649(depth-\256rst)X
+4000(for)X
+4116(seven)X
+755 1236(hops)N
+930(from)X
+1110(the)X
+1232(original)X
+1505(part,)X
+1674(for)X
+1792(a)X
+1852(total)X
+2018(of)X
+2109(3280)X
+2293(parts.)X
+2513(Backward)X
+2862(traversal)X
+3162(also)X
+3314(exists,)X
+3539(and)X
+3678(follows)X
+3941(all)X
+4044(connec-)X
+755 1326(tions)N
+930(into)X
+1074(a)X
+1130(given)X
+1328(part)X
+1473(to)X
+1555(their)X
+1722(origin.)X
+10 f
+635 1449(g)N
+2 f
+755(Insert)X
+1 f
+962(adds)X
+1129(100)X
+1269(new)X
+1423(parts)X
+1599(and)X
+1735(their)X
+1902(connections.)X
+755 1572(The)N
+913(benchmark)X
+1303(is)X
+1389(single-user,)X
+1794(but)X
+1929(multi-user)X
+2291(access)X
+2530(controls)X
+2821(\(locking)X
+3120(and)X
+3268(transaction)X
+3652(protection\))X
+4036(must)X
+4223(be)X
+555 1662(enforced.)N
+898(It)X
+968(is)X
+1042(designed)X
+1348(to)X
+1431(be)X
+1528(run)X
+1656(on)X
+1757(a)X
+1814(database)X
+2112(with)X
+2275(20,000)X
+2516(parts,)X
+2713(and)X
+2850(on)X
+2951(one)X
+3087(with)X
+3249(200,000)X
+3529(parts.)X
+3745(Because)X
+4033(we)X
+4147(have)X
+555 1752(insuf\256cient)N
+935(disk)X
+1088(space)X
+1287(for)X
+1401(the)X
+1519(larger)X
+1727(database,)X
+2044(we)X
+2158(report)X
+2370(results)X
+2599(only)X
+2761(for)X
+2875(the)X
+2993(20,000)X
+3233(part)X
+3378(database.)X
+3 f
+555 1938(5.2.1.)N
+775(Implementation)X
+1 f
+755 2061(The)N
+920(LIBTP)X
+1182(implementation)X
+1724(of)X
+1831(OO1)X
+2027(uses)X
+2205(the)X
+2342(TCL)X
+2532([OUST90])X
+2914(interface)X
+3235(described)X
+3582(earlier.)X
+3867(The)X
+4031(backend)X
+555 2151(accepts)N
+813(commands)X
+1181(over)X
+1345(an)X
+1442(IP)X
+1534(socket)X
+1760(and)X
+1897(performs)X
+2208(the)X
+2327(requested)X
+2656(database)X
+2954(actions.)X
+3242(The)X
+3387(frontend)X
+3679(opens)X
+3886(and)X
+4022(executes)X
+555 2241(a)N
+618(TCL)X
+796(script.)X
+1041(This)X
+1210(script)X
+1415(contains)X
+1709(database)X
+2013(accesses)X
+2313(interleaved)X
+2697(with)X
+2866(ordinary)X
+3165(program)X
+3463(control)X
+3716(statements.)X
+4120(Data-)X
+555 2331(base)N
+718(commands)X
+1085(are)X
+1204(submitted)X
+1539(to)X
+1621(the)X
+1739(backend)X
+2027(and)X
+2163(results)X
+2392(are)X
+2511(bound)X
+2731(to)X
+2813(program)X
+3105(variables.)X
+755 2454(The)N
+903(parts)X
+1082(table)X
+1261(was)X
+1409(stored)X
+1628(as)X
+1718(a)X
+1776(B-tree)X
+1999(indexed)X
+2275(by)X
+2 f
+2377(id)X
+1 f
+2439(.)X
+2501(The)X
+2648(connection)X
+3022(table)X
+3200(was)X
+3347(stored)X
+3565(as)X
+3654(a)X
+3712(set)X
+3823(of)X
+3912(\256xed-length)X
+555 2544(records)N
+824(using)X
+1029(the)X
+1159(4.4BSD)X
+1446(recno)X
+1657(access)X
+1895(method.)X
+2207(In)X
+2306(addition,)X
+2620(two)X
+2771(B-tree)X
+3003(indices)X
+3261(were)X
+3449(maintained)X
+3836(on)X
+3947(connection)X
+555 2634(table)N
+732(entries.)X
+1007(One)X
+1162(index)X
+1360(mapped)X
+1634(the)X
+2 f
+1752(from)X
+1 f
+1923(\256eld)X
+2085(to)X
+2167(a)X
+2223(connection)X
+2595(record)X
+2821(number,)X
+3106(and)X
+3242(the)X
+3360(other)X
+3545(mapped)X
+3819(the)X
+2 f
+3937(to)X
+1 f
+4019(\256eld)X
+4181(to)X
+4263(a)X
+555 2724(connection)N
+932(record)X
+1163(number.)X
+1473(These)X
+1690(indices)X
+1941(support)X
+2205(fast)X
+2345(lookups)X
+2622(on)X
+2726(connections)X
+3133(in)X
+3219(both)X
+3385(directions.)X
+3765(For)X
+3900(the)X
+4022(traversal)X
+555 2814(tests,)N
+743(the)X
+867(frontend)X
+1165(does)X
+1338(an)X
+1439(index)X
+1642(lookup)X
+1889(to)X
+1976(discover)X
+2273(the)X
+2396(connected)X
+2747(part's)X
+2 f
+2955(id)X
+1 f
+3017(,)X
+3062(and)X
+3203(then)X
+3366(does)X
+3538(another)X
+3804(lookup)X
+4051(to)X
+4138(fetch)X
+555 2904(the)N
+673(part)X
+818(itself.)X
+3 f
+555 3090(5.2.2.)N
+775(Performance)X
+1242(Measurements)X
+1766(for)X
+1889(OO1)X
+1 f
+755 3213(We)N
+888(compare)X
+1186(LIBTP's)X
+1487(OO1)X
+1664(performance)X
+2092(to)X
+2174(that)X
+2314(reported)X
+2602(in)X
+2684([CATT91].)X
+3087(Those)X
+3303(results)X
+3532(were)X
+3709(collected)X
+4019(on)X
+4119(a)X
+4175(Sun)X
+555 3303(3/280)N
+759(\(25)X
+888(MHz)X
+1075(MC68020\))X
+1448(with)X
+1612(16)X
+1714(MBytes)X
+1989(of)X
+2078(memory)X
+2367(and)X
+2505(two)X
+2647(Hitachi)X
+2904(892MByte)X
+3267(disks)X
+3452(\(15)X
+3580(ms)X
+3694(average)X
+3966(seek)X
+4130(time\))X
+555 3393(behind)N
+793(an)X
+889(SMD-4)X
+1149(controller.)X
+1521(Frontends)X
+1861(ran)X
+1984(on)X
+2084(an)X
+2180(8MByte)X
+2462(Sun)X
+2606(3/260.)X
+755 3516(In)N
+844(order)X
+1036(to)X
+1120(measure)X
+1410(performance)X
+1839(on)X
+1941(a)X
+1999(machine)X
+2293(of)X
+2382(roughly)X
+2653(equivalent)X
+3009(processor)X
+3339(power,)X
+3582(we)X
+3698(ran)X
+3822(one)X
+3959(set)X
+4069(of)X
+4157(tests)X
+555 3606(on)N
+666(a)X
+733(standalone)X
+1107(MC68030-based)X
+1671(HP300)X
+1923(\(33MHz)X
+2225(MC68030\).)X
+2646(The)X
+2801(database)X
+3108(was)X
+3263(stored)X
+3489(on)X
+3599(a)X
+3665(300MByte)X
+4037(HP7959)X
+555 3696(SCSI)N
+744(disk)X
+898(\(17)X
+1026(ms)X
+1139(average)X
+1410(seek)X
+1573(time\).)X
+1802(Since)X
+2000(this)X
+2135(machine)X
+2427(is)X
+2500(not)X
+2622(connected)X
+2968(to)X
+3050(a)X
+3106(network,)X
+3409(we)X
+3523(ran)X
+3646(local)X
+3822(tests)X
+3984(where)X
+4201(the)X
+555 3786(frontend)N
+855(and)X
+999(backend)X
+1295(run)X
+1430(on)X
+1538(the)X
+1664(same)X
+1856(machine.)X
+2195(We)X
+2334(compare)X
+2638(these)X
+2830(measurements)X
+3316(with)X
+3485(Cattell's)X
+3783(local)X
+3966(Sun)X
+4117(3/280)X
+555 3876(numbers.)N
+755 3999(Because)N
+1051(the)X
+1177(benchmark)X
+1562(requires)X
+1849(remote)X
+2100(access,)X
+2354(we)X
+2476(ran)X
+2607(another)X
+2876(set)X
+2993(of)X
+3088(tests)X
+3258(on)X
+3365(a)X
+3428(DECstation)X
+3828(5000/200)X
+4157(with)X
+555 4089(32M)N
+732(of)X
+825(memory)X
+1118(running)X
+1393(Ultrix)X
+1610(V4.0)X
+1794(and)X
+1936(a)X
+1998(DEC)X
+2184(1GByte)X
+2459(RZ57)X
+2666(SCSI)X
+2859(disk.)X
+3057(We)X
+3194(compare)X
+3496(the)X
+3619(local)X
+3800(performance)X
+4232(of)X
+555 4179(OO1)N
+734(on)X
+837(the)X
+958(DECstation)X
+1354(to)X
+1439(its)X
+1536(remote)X
+1781(performance.)X
+2250(For)X
+2383(the)X
+2503(remote)X
+2748(case,)X
+2929(we)X
+3045(ran)X
+3170(the)X
+3290(frontend)X
+3584(on)X
+3686(a)X
+3744(DECstation)X
+4139(3100)X
+555 4269(with)N
+717(16)X
+817(MBytes)X
+1090(of)X
+1177(main)X
+1357(memory.)X
+755 4392(The)N
+900(databases)X
+1228(tested)X
+1435(in)X
+1517([CATT91])X
+1880(are)X
+10 f
+635 4515(g)N
+1 f
+755(INDEX,)X
+1045(a)X
+1101(highly-optimized)X
+1672(access)X
+1898(method)X
+2158(package)X
+2442(developed)X
+2792(at)X
+2870(Sun)X
+3014(Microsystems.)X
+10 f
+635 4638(g)N
+1 f
+755(OODBMS,)X
+1137(a)X
+1193(beta)X
+1347(release)X
+1591(of)X
+1678(a)X
+1734(commercial)X
+2133(object-oriented)X
+2639(database)X
+2936(management)X
+3366(system.)X
+10 f
+635 4761(g)N
+1 f
+755(RDBMS,)X
+1076(a)X
+1133(UNIX-based)X
+1565(commercial)X
+1965(relational)X
+2289(data)X
+2444(manager)X
+2742(at)X
+2821(production)X
+3189(release.)X
+3474(The)X
+3620(OO1)X
+3797(implementation)X
+755 4851(used)N
+922(embedded)X
+1272(SQL)X
+1443(in)X
+1525(C.)X
+1638(Stored)X
+1867(procedures)X
+2240(were)X
+2417(de\256ned)X
+2673(to)X
+2755(reduce)X
+2990(client-server)X
+3412(traf\256c.)X
+755 4974(Table)N
+974(two)X
+1130(shows)X
+1366(the)X
+1500(measurements)X
+1995(from)X
+2187([CATT91])X
+2566(and)X
+2718(LIBTP)X
+2976(for)X
+3106(a)X
+3178(local)X
+3370(test)X
+3517(on)X
+3632(the)X
+3765(MC680x0-based)X
+555 5064(hardware.)N
+915(All)X
+1037(caches)X
+1272(are)X
+1391(cleared)X
+1644(before)X
+1870(each)X
+2038(test.)X
+2209(All)X
+2331(times)X
+2524(are)X
+2643(in)X
+2725(seconds.)X
+755 5187(Table)N
+960(two)X
+1102(shows)X
+1324(that)X
+1466(LIBTP)X
+1710(outperforms)X
+2123(the)X
+2242(commercial)X
+2642(relational)X
+2966(system,)X
+3229(but)X
+3352(is)X
+3426(slower)X
+3661(than)X
+3820(OODBMS)X
+4183(and)X
+555 5277(INDEX.)N
+872(Since)X
+1077(the)X
+1202(caches)X
+1444(were)X
+1628(cleared)X
+1888(at)X
+1973(the)X
+2098(start)X
+2263(of)X
+2356(each)X
+2530(test,)X
+2687(disk)X
+2846(throughput)X
+3223(is)X
+3302(critical)X
+3551(in)X
+3639(this)X
+3780(test.)X
+3957(The)X
+4108(single)X
+555 5367(SCSI)N
+749(HP)X
+877(drive)X
+1068(used)X
+1241(by)X
+1347(LIBTP)X
+1595(is)X
+1674(approximately)X
+2163(13%)X
+2336(slower)X
+2576(than)X
+2739(the)X
+2862(disks)X
+3051(used)X
+3223(in)X
+3310([CATT91])X
+3678(which)X
+3899(accounts)X
+4205(for)X
+555 5457(part)N
+700(of)X
+787(the)X
+905(difference.)X
+755 5580(OODBMS)N
+1118(and)X
+1255(INDEX)X
+1525(outperform)X
+1906(LIBTP)X
+2148(most)X
+2323(dramatically)X
+2744(on)X
+2844(traversal.)X
+3181(This)X
+3343(is)X
+3416(because)X
+3691(we)X
+3805(use)X
+3932(index)X
+4130(look-)X
+555 5670(ups)N
+689(to)X
+774(\256nd)X
+921(connections,)X
+1347(whereas)X
+1634(the)X
+1755(other)X
+1942(two)X
+2084(systems)X
+2359(use)X
+2488(a)X
+2546(link)X
+2692(access)X
+2920(method.)X
+3222(The)X
+3369(index)X
+3569(requires)X
+3850(us)X
+3943(to)X
+4027(examine)X
+
+15 p
+%%Page: 15 15
+10 s 10 xH 0 xS 1 f
+3 f
+1 f
+10 f
+555 679(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)N
+2 f
+606 769(Measure)N
+1 f
+1019(INDEX)X
+1389(OODBMS)X
+1851(RDBMS)X
+2250(LIBTP)X
+10 f
+555 771(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)N
+555 787(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)N
+1 f
+595 869(Lookup)N
+1114(5.4)X
+1490(12.9)X
+1950(27)X
+2291(27.2)X
+595 959(Traversal)N
+1074(13)X
+1530(9.8)X
+1950(90)X
+2291(47.3)X
+595 1049(Insert)N
+1114(7.4)X
+1530(1.5)X
+1950(22)X
+2331(9.7)X
+10 f
+555 1059(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)N
+555(c)X
+999(c)Y
+919(c)Y
+839(c)Y
+759(c)Y
+959 1059(c)N
+999(c)Y
+919(c)Y
+839(c)Y
+759(c)Y
+1329 1059(c)N
+999(c)Y
+919(c)Y
+839(c)Y
+759(c)Y
+1791 1059(c)N
+999(c)Y
+919(c)Y
+839(c)Y
+759(c)Y
+2190 1059(c)N
+999(c)Y
+919(c)Y
+839(c)Y
+759(c)Y
+2512 1059(c)N
+999(c)Y
+919(c)Y
+839(c)Y
+759(c)Y
+2618 679(i)N
+2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2 f
+2829 769(Measure)N
+3401(Cache)X
+3726(Local)X
+4028(Remote)X
+1 f
+10 f
+2618 771(i)N
+2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2618 787(i)N
+2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+2658 869(Lookup)N
+3401(cold)X
+3747(15.7)X
+4078(20.6)X
+3401 959(warm)N
+3787(7.8)X
+4078(12.4)X
+10 f
+2618 969(i)N
+2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+2658 1059(Forward)N
+2950(traversal)X
+3401(cold)X
+3747(28.4)X
+4078(52.6)X
+3401 1149(warm)N
+3747(23.5)X
+4078(47.4)X
+10 f
+2618 1159(i)N
+2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+2658 1249(Backward)N
+3004(traversal)X
+3401(cold)X
+3747(24.2)X
+4078(47.4)X
+3401 1339(warm)N
+3747(24.3)X
+4078(47.6)X
+10 f
+2618 1349(i)N
+2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+1 f
+2658 1439(Insert)N
+3401(cold)X
+3787(7.5)X
+4078(10.3)X
+3401 1529(warm)N
+3787(6.7)X
+4078(10.9)X
+10 f
+2618 1539(i)N
+2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X
+2618(c)X
+1479(c)Y
+1399(c)Y
+1319(c)Y
+1239(c)Y
+1159(c)Y
+1079(c)Y
+999(c)Y
+919(c)Y
+839(c)Y
+759(c)Y
+3341 1539(c)N
+1479(c)Y
+1399(c)Y
+1319(c)Y
+1239(c)Y
+1159(c)Y
+1079(c)Y
+999(c)Y
+919(c)Y
+839(c)Y
+759(c)Y
+3666 1539(c)N
+1479(c)Y
+1399(c)Y
+1319(c)Y
+1239(c)Y
+1159(c)Y
+1079(c)Y
+999(c)Y
+919(c)Y
+839(c)Y
+759(c)Y
+3968 1539(c)N
+1479(c)Y
+1399(c)Y
+1319(c)Y
+1239(c)Y
+1159(c)Y
+1079(c)Y
+999(c)Y
+919(c)Y
+839(c)Y
+759(c)Y
+4309 1539(c)N
+1479(c)Y
+1399(c)Y
+1319(c)Y
+1239(c)Y
+1159(c)Y
+1079(c)Y
+999(c)Y
+919(c)Y
+839(c)Y
+759(c)Y
+3 f
+587 1785(Table)N
+823(2:)X
+931(Local)X
+1163(MC680x0)X
+1538(Performance)X
+2026(of)X
+2133(Several)X
+587 1875(Systems)N
+883(on)X
+987(OO1.)X
+2667 1785(Table)N
+2909(3:)X
+3023(Local)X
+3260(vs.)X
+3397(Remote)X
+3707(Performance)X
+4200(of)X
+2667 1875(LIBTP)N
+2926(on)X
+3030(OO1.)X
+1 f
+10 f
+555 1998(h)N
+579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X
+1 f
+555 2274(two)N
+696(disk)X
+850(pages,)X
+1074(but)X
+1197(the)X
+1316(links)X
+1492(require)X
+1741(only)X
+1904(one,)X
+2061(regardless)X
+2408(of)X
+2496(database)X
+2794(size.)X
+2980(Cattell)X
+3214(reports)X
+3458(that)X
+3599(lookups)X
+3873(using)X
+4067(B-trees)X
+555 2364(instead)N
+808(of)X
+901(links)X
+1082(makes)X
+1313(traversal)X
+1616(take)X
+1776(twice)X
+1976(as)X
+2069(long)X
+2237(in)X
+2325(INDEX.)X
+2641(Adding)X
+2907(a)X
+2969(link)X
+3119(access)X
+3351(method)X
+3617(to)X
+3 f
+3704(db)X
+1 f
+3792(\(3\))X
+3911(or)X
+4003(using)X
+4201(the)X
+555 2454(existing)N
+828(hash)X
+995(method)X
+1255(would)X
+1475(apparently)X
+1834(be)X
+1930(a)X
+1986(good)X
+2166(idea.)X
+755 2577(Both)N
+936(OODBMS)X
+1304(and)X
+1446(INDEX)X
+1722(issue)X
+1908 0.1944(coarser-granularity)AX
+2545(locks)X
+2739(than)X
+2902(LIBTP.)X
+3189(This)X
+3356(limits)X
+3562(concurrency)X
+3985(for)X
+4104(multi-)X
+555 2667(user)N
+711(applications,)X
+1140(but)X
+1264(helps)X
+1455(single-user)X
+1829(applications.)X
+2278(In)X
+2367(addition,)X
+2671(the)X
+2791(fact)X
+2934(that)X
+3076(LIBTP)X
+3319(releases)X
+3595(B-tree)X
+3817(locks)X
+4007(early)X
+4189(is)X
+4263(a)X
+555 2757(drawback)N
+896(in)X
+986(OO1.)X
+1210(Since)X
+1416(there)X
+1605(is)X
+1686(no)X
+1793(concurrency)X
+2218(in)X
+2307(the)X
+2432(benchmark,)X
+2836(high-concurrency)X
+3430(strategies)X
+3760(only)X
+3929(show)X
+4125(up)X
+4232(as)X
+555 2847(increased)N
+882(locking)X
+1145(overhead.)X
+1503(Finally,)X
+1772(the)X
+1892(architecture)X
+2294(of)X
+2383(the)X
+2503(LIBTP)X
+2747(implementation)X
+3271(was)X
+3418(substantially)X
+3844(different)X
+4143(from)X
+555 2937(that)N
+702(of)X
+796(either)X
+1006(OODBMS)X
+1375(or)X
+1469(INDEX.)X
+1786(Both)X
+1968(of)X
+2062(those)X
+2258(systems)X
+2538(do)X
+2645(the)X
+2770(searches)X
+3070(in)X
+3159(the)X
+3284(user's)X
+3503(address)X
+3771(space,)X
+3997(and)X
+4139(issue)X
+555 3027(requests)N
+844(for)X
+964(pages)X
+1173(to)X
+1260(the)X
+1383(server)X
+1605(process.)X
+1911(Pages)X
+2123(are)X
+2247(cached)X
+2496(in)X
+2583(the)X
+2706(client,)X
+2929(and)X
+3070(many)X
+3273(queries)X
+3530(can)X
+3667(be)X
+3768(satis\256ed)X
+4055(without)X
+555 3117(contacting)N
+910(the)X
+1029(server)X
+1247(at)X
+1326(all.)X
+1467(LIBTP)X
+1710(submits)X
+1979(all)X
+2080(the)X
+2199(queries)X
+2452(to)X
+2535(the)X
+2653(server)X
+2870(process,)X
+3151(and)X
+3287(receives)X
+3571(database)X
+3868(records)X
+4125(back;)X
+555 3207(it)N
+619(does)X
+786(no)X
+886(client)X
+1084(caching.)X
+755 3330(The)N
+911(RDBMS)X
+1221(architecture)X
+1632(is)X
+1716(much)X
+1925(closer)X
+2148(to)X
+2241(that)X
+2392(of)X
+2490(LIBTP.)X
+2783(A)X
+2872(server)X
+3100(process)X
+3372(receives)X
+3667(queries)X
+3930(and)X
+4076(returns)X
+555 3420(results)N
+786(to)X
+870(a)X
+928(client.)X
+1168(The)X
+1315(timing)X
+1545(results)X
+1776(in)X
+1860(table)X
+2038(two)X
+2180(clearly)X
+2421(show)X
+2612(that)X
+2754(the)X
+2874(conventional)X
+3309(database)X
+3607(client/server)X
+4025(model)X
+4246(is)X
+555 3510(expensive.)N
+941(LIBTP)X
+1188(outperforms)X
+1605(the)X
+1728(RDBMS)X
+2032(on)X
+2136(traversal)X
+2437(and)X
+2577(insertion.)X
+2921(We)X
+3057(speculate)X
+3380(that)X
+3524(this)X
+3663(is)X
+3740(due)X
+3880(in)X
+3966(part)X
+4115(to)X
+4201(the)X
+555 3600(overhead)N
+870(of)X
+957(query)X
+1160(parsing,)X
+1436(optimization,)X
+1880(and)X
+2016(repeated)X
+2309(interpretation)X
+2761(of)X
+2848(the)X
+2966(plan)X
+3124(tree)X
+3265(in)X
+3347(the)X
+3465(RDBMS')X
+3791(query)X
+3994(executor.)X
+755 3723(Table)N
+962(three)X
+1147(shows)X
+1371(the)X
+1492(differences)X
+1873(between)X
+2164(local)X
+2343(and)X
+2482(remote)X
+2728(execution)X
+3063(of)X
+3153(LIBTP's)X
+3456(OO1)X
+3635(implementation)X
+4160(on)X
+4263(a)X
+555 3813(DECstation.)N
+989(We)X
+1122(measured)X
+1451(performance)X
+1879(with)X
+2042(a)X
+2099(populated)X
+2436(\(warm\))X
+2694(cache)X
+2899(and)X
+3036(an)X
+3133(empty)X
+3354(\(cold\))X
+3567(cache.)X
+3812(Reported)X
+4126(times)X
+555 3903(are)N
+681(the)X
+806(means)X
+1037(of)X
+1130(twenty)X
+1374(tests,)X
+1562(and)X
+1704(are)X
+1829(in)X
+1917(seconds.)X
+2237(Standard)X
+2548(deviations)X
+2903(were)X
+3086(within)X
+3316(seven)X
+3525(percent)X
+3788(of)X
+3881(the)X
+4005(mean)X
+4205(for)X
+555 3993(remote,)N
+818(and)X
+954(two)X
+1094(percent)X
+1351(of)X
+1438(the)X
+1556(mean)X
+1750(for)X
+1864(local.)X
+755 4116(The)N
+914(20ms)X
+1121(overhead)X
+1450(of)X
+1551(TCP/IP)X
+1824(on)X
+1938(an)X
+2048(Ethernet)X
+2354(entirely)X
+2633(accounts)X
+2948(for)X
+3076(the)X
+3207(difference)X
+3567(in)X
+3662(speed.)X
+3918(The)X
+4076(remote)X
+555 4206(traversal)N
+857(times)X
+1055(are)X
+1179(nearly)X
+1405(double)X
+1648(the)X
+1771(local)X
+1952(times)X
+2150(because)X
+2430(we)X
+2549(do)X
+2653(index)X
+2855(lookups)X
+3132(and)X
+3272(part)X
+3421(fetches)X
+3673(in)X
+3759(separate)X
+4047(queries.)X
+555 4296(It)N
+629(would)X
+854(make)X
+1053(sense)X
+1252(to)X
+1339(do)X
+1444(indexed)X
+1723(searches)X
+2021(on)X
+2126(the)X
+2248(server,)X
+2489(but)X
+2615(we)X
+2733(were)X
+2914(unwilling)X
+3244(to)X
+3330(hard-code)X
+3676(knowledge)X
+4052(of)X
+4143(OO1)X
+555 4386(indices)N
+803(into)X
+948(our)X
+1075(LIBTP)X
+1317(TCL)X
+1488(server.)X
+1745(Cold)X
+1920(and)X
+2056(warm)X
+2259(insertion)X
+2559(times)X
+2752(are)X
+2871(identical)X
+3167(since)X
+3352(insertions)X
+3683(do)X
+3783(not)X
+3905(bene\256t)X
+4143(from)X
+555 4476(caching.)N
+755 4599(One)N
+915(interesting)X
+1279(difference)X
+1632(shown)X
+1867(by)X
+1973(table)X
+2155(three)X
+2342(is)X
+2421(the)X
+2545(cost)X
+2700(of)X
+2793(forward)X
+3074(versus)X
+3305(backward)X
+3644(traversal.)X
+3987(When)X
+4205(we)X
+555 4689(built)N
+725(the)X
+847(database,)X
+1168(we)X
+1285(inserted)X
+1562(parts)X
+1741(in)X
+1826(part)X
+2 f
+1974(id)X
+1 f
+2059(order.)X
+2292(We)X
+2427(built)X
+2596(the)X
+2717(indices)X
+2967(at)X
+3048(the)X
+3169(same)X
+3357(time.)X
+3562(Therefore,)X
+3923(the)X
+4044(forward)X
+555 4779(index)N
+757(had)X
+897(keys)X
+1068(inserted)X
+1346(in)X
+1432(order,)X
+1646(while)X
+1848(the)X
+1970(backward)X
+2307(index)X
+2509(had)X
+2649(keys)X
+2820(inserted)X
+3098(more)X
+3286(randomly.)X
+3656(In-order)X
+3943(insertion)X
+4246(is)X
+555 4885(pessimal)N
+858(for)X
+975(B-tree)X
+1199(indices,)X
+1469(so)X
+1563(the)X
+1684(forward)X
+1962(index)X
+2163(is)X
+2239(much)X
+2440(larger)X
+2651(than)X
+2812(the)X
+2933(backward)X
+3269(one)X
+7 s
+3385 4853(5)N
+10 s
+4885(.)Y
+3476(This)X
+3640(larger)X
+3850(size)X
+3997(shows)X
+4219(up)X
+555 4975(as)N
+642(extra)X
+823(disk)X
+976(reads)X
+1166(in)X
+1248(the)X
+1366(cold)X
+1524(benchmark.)X
+3 f
+555 5161(6.)N
+655(Conclusions)X
+1 f
+755 5284(LIBTP)N
+1006(provides)X
+1311(the)X
+1438(basic)X
+1632(building)X
+1927(blocks)X
+2165(to)X
+2256(support)X
+2525(transaction)X
+2906(protection.)X
+3300(In)X
+3396(comparison)X
+3799(with)X
+3970(traditional)X
+555 5374(Unix)N
+746(libraries)X
+1040(and)X
+1187(commercial)X
+1597(systems,)X
+1900(it)X
+1974(offers)X
+2192(a)X
+2258(variety)X
+2511(of)X
+2608(tradeoffs.)X
+2964(Using)X
+3185(complete)X
+3509(transaction)X
+3891(protection)X
+4246(is)X
+555 5464(more)N
+747(complicated)X
+1166(than)X
+1331(simply)X
+1575(adding)X
+3 f
+1820(fsync)X
+1 f
+1998(\(2\))X
+2119(and)X
+3 f
+2262(\257ock)X
+1 f
+2426(\(2\))X
+2547(calls)X
+2721(to)X
+2810(code,)X
+3008(but)X
+3136(it)X
+3206(is)X
+3285(faster)X
+3490(in)X
+3578(some)X
+3773(cases)X
+3969(and)X
+4111(offers)X
+8 s
+10 f
+555 5536(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N
+5 s
+1 f
+727 5614(5)N
+8 s
+763 5639(The)N
+878(next)X
+1004(release)X
+1196(of)X
+1265(the)X
+1359(4.4BSD)X
+1580(access)X
+1758(method)X
+1966(will)X
+2082(automatically)X
+2446(detect)X
+2614(and)X
+2722(compensate)X
+3039(for)X
+3129(in-order)X
+3350(insertion,)X
+3606(eliminating)X
+3914(this)X
+4023(problem.)X
+
+16 p
+%%Page: 16 16
+8 s 8 xH 0 xS 1 f
+10 s
+3 f
+1 f
+555 630(stricter)N
+801(guarantees)X
+1168(\(atomicity,)X
+1540(consistency,)X
+1957(isolation,)X
+2275(and)X
+2414(durability\).)X
+2815(If)X
+2892(the)X
+3013(data)X
+3170(to)X
+3255(be)X
+3354(protected)X
+3676(are)X
+3798(already)X
+4058(format-)X
+555 720(ted)N
+675(\()X
+2 f
+702(i.e.)X
+1 f
+821(use)X
+949(one)X
+1086(of)X
+1174(the)X
+1293(database)X
+1591(access)X
+1818(methods\),)X
+2157(then)X
+2316(adding)X
+2555(transaction)X
+2928(protection)X
+3274(requires)X
+3554(no)X
+3655(additional)X
+3996(complex-)X
+555 810(ity,)N
+679(but)X
+801(incurs)X
+1017(a)X
+1073(performance)X
+1500(penalty)X
+1756(of)X
+1843(approximately)X
+2326(15%.)X
+755 933(In)N
+844(comparison)X
+1240(with)X
+1404(commercial)X
+1805(database)X
+2104(systems,)X
+2399(the)X
+2519(tradeoffs)X
+2827(are)X
+2948(more)X
+3135(complex.)X
+3473(LIBTP)X
+3717(does)X
+3886(not)X
+4009(currently)X
+555 1023(support)N
+825(a)X
+891(standard)X
+1193(query)X
+1406(language.)X
+1766(The)X
+1921(TCL-based)X
+2312(server)X
+2539(process)X
+2810(allows)X
+3049(a)X
+3115(certain)X
+3364(ease)X
+3533(of)X
+3630(use)X
+3767(which)X
+3993(would)X
+4223(be)X
+555 1113(enhanced)N
+882(with)X
+1047(a)X
+1106(more)X
+1294(user-friendly)X
+1732(interface)X
+2037(\()X
+2 f
+2064(e.g.)X
+1 f
+2203(a)X
+2261(windows)X
+2572(based)X
+2777(query-by-form)X
+3272(application\),)X
+3697(for)X
+3813(which)X
+4031(we)X
+4147(have)X
+555 1203(a)N
+620(working)X
+916(prototype.)X
+1292(When)X
+1513(accesses)X
+1815(do)X
+1924(not)X
+2055(require)X
+2312(sophisticated)X
+2758(query)X
+2969(processing,)X
+3360(the)X
+3486(TCL)X
+3665(interface)X
+3975(is)X
+4056(an)X
+4160(ade-)X
+555 1293(quate)N
+756(solution.)X
+1080(What)X
+1281(LIBTP)X
+1529(fails)X
+1693(to)X
+1781(provide)X
+2052(in)X
+2140(functionality,)X
+2595(it)X
+2665(makes)X
+2896(up)X
+3002(for)X
+3122(in)X
+3210(performance)X
+3643(and)X
+3785(\257exibility.)X
+4161(Any)X
+555 1383(application)N
+931(may)X
+1089(make)X
+1283(use)X
+1410(of)X
+1497(its)X
+1592(record)X
+1818(interface)X
+2120(or)X
+2207(the)X
+2325(more)X
+2510(primitive)X
+2823(log,)X
+2965(lock,)X
+3143(and)X
+3279(buffer)X
+3496(calls.)X
+755 1506(Future)N
+987(work)X
+1175(will)X
+1322(focus)X
+1519(on)X
+1621(overcoming)X
+2026(some)X
+2217(of)X
+2306(the)X
+2426(areas)X
+2614(in)X
+2698(which)X
+2916(LIBTP)X
+3160(is)X
+3235(currently)X
+3547(de\256cient)X
+3845(and)X
+3983(extending)X
+555 1596(its)N
+652(transaction)X
+1026(model.)X
+1288(The)X
+1435(addition)X
+1719(of)X
+1808(an)X
+1905(SQL)X
+2077(parser)X
+2295(and)X
+2432(forms)X
+2640(front)X
+2817(end)X
+2954(will)X
+3099(improve)X
+3387(the)X
+3506(system's)X
+3807(ease)X
+3967(of)X
+4055(use)X
+4183(and)X
+555 1686(make)N
+750(it)X
+815(more)X
+1001(competitive)X
+1400(with)X
+1563(commercial)X
+1963(systems.)X
+2277(In)X
+2365(the)X
+2484(long)X
+2647(term,)X
+2835(we)X
+2950(would)X
+3170(like)X
+3310(to)X
+3392(add)X
+3528(generalized)X
+3919(hierarchical)X
+555 1776(locking,)N
+836(nested)X
+1062(transactions,)X
+1486(parallel)X
+1748(transactions,)X
+2171(passing)X
+2431(of)X
+2518(transactions)X
+2921(between)X
+3209(processes,)X
+3557(and)X
+3693(distributed)X
+4055(commit)X
+555 1866(handling.)N
+900(In)X
+992(the)X
+1115(short)X
+1300(term,)X
+1492(the)X
+1614(next)X
+1776(step)X
+1929(is)X
+2006(to)X
+2092(integrate)X
+2397(LIBTP)X
+2643(with)X
+2809(the)X
+2931(most)X
+3110(recent)X
+3331(release)X
+3579(of)X
+3670(the)X
+3792(database)X
+4093(access)X
+555 1956(routines)N
+833(and)X
+969(make)X
+1163(it)X
+1227(freely)X
+1435(available)X
+1745(via)X
+1863(anonymous)X
+2252(ftp.)X
+3 f
+555 2142(7.)N
+655(Acknowledgements)X
+1 f
+755 2265(We)N
+888(would)X
+1109(like)X
+1250(to)X
+1332(thank)X
+1530(John)X
+1701(Wilkes)X
+1948(and)X
+2084(Carl)X
+2242(Staelin)X
+2484(of)X
+2571(Hewlett-Packard)X
+3131(Laboratories)X
+3557(and)X
+3693(Jon)X
+3824(Krueger.)X
+4148(John)X
+555 2355(and)N
+694(Carl)X
+855(provided)X
+1162(us)X
+1255(with)X
+1419(an)X
+1517(extra)X
+1700(disk)X
+1855(for)X
+1971(the)X
+2091(HP)X
+2215(testbed)X
+2464(less)X
+2606(than)X
+2766(24)X
+2868(hours)X
+3068(after)X
+3238(we)X
+3354(requested)X
+3684(it.)X
+3770(Jon)X
+3903(spent)X
+4094(count-)X
+555 2445(less)N
+699(hours)X
+901(helping)X
+1164(us)X
+1258(understand)X
+1633(the)X
+1754(intricacies)X
+2107(of)X
+2197(commercial)X
+2599(database)X
+2899(products)X
+3198(and)X
+3337(their)X
+3507(behavior)X
+3811(under)X
+4017(a)X
+4076(variety)X
+555 2535(of)N
+642(system)X
+884(con\256gurations.)X
+3 f
+555 2721(8.)N
+655(References)X
+1 f
+555 2901([ANDR89])N
+942(Andrade,)X
+1265(J.,)X
+1361(Carges,)X
+1629(M.,)X
+1765(Kovach,)X
+2060(K.,)X
+2183(``Building)X
+2541(an)X
+2642(On-Line)X
+2939(Transaction)X
+3343(Processing)X
+3715(System)X
+3975(On)X
+4098(UNIX)X
+727 2991(System)N
+982(V'',)X
+2 f
+1134(CommUNIXations)X
+1 f
+1725(,)X
+1765 0.2188(November/December)AX
+2477(1989.)X
+555 3171([BAY77])N
+878(Bayer,)X
+1110(R.,)X
+1223(Schkolnick,)X
+1623(M.,)X
+1754(``Concurrency)X
+2243(of)X
+2330(Operations)X
+2702(on)X
+2802(B-Trees'',)X
+2 f
+3155(Acta)X
+3322(Informatica)X
+1 f
+3700(,)X
+3740(1977.)X
+555 3351([BERN80])N
+936(Bernstein,)X
+1297(P.,)X
+1415(Goodman,)X
+1785(N.,)X
+1917(``Timestamp)X
+2365(Based)X
+2595(Algorithms)X
+2992(for)X
+3119(Concurrency)X
+3567(Control)X
+3844(in)X
+3939(Distributed)X
+727 3441(Database)N
+1042(Systems'',)X
+2 f
+1402(Proceedings)X
+1823(6th)X
+1945(International)X
+2387(Conference)X
+2777(on)X
+2877(Very)X
+3049(Large)X
+3260(Data)X
+3440(Bases)X
+1 f
+3627(,)X
+3667(October)X
+3946(1980.)X
+555 3621([BSD91])N
+864(DB\(3\),)X
+2 f
+1109(4.4BSD)X
+1376(Unix)X
+1552(Programmer's)X
+2044(Manual)X
+2313(Reference)X
+2655(Guide)X
+1 f
+2851(,)X
+2891(University)X
+3249(of)X
+3336(California,)X
+3701(Berkeley,)X
+4031(1991.)X
+555 3801([CATT91])N
+923(Cattell,)X
+1181(R.G.G.,)X
+1455(``An)X
+1632(Engineering)X
+2049(Database)X
+2369(Benchmark'',)X
+2 f
+2838(The)X
+2983(Benchmark)X
+3373(Handbook)X
+3731(for)X
+3848(Database)X
+4179(and)X
+727 3891(Transaction)N
+1133(Processing)X
+1509(Systems)X
+1 f
+1763(,)X
+1803(J.)X
+1874(Gray,)X
+2075(editor,)X
+2302(Morgan)X
+2576(Kaufman)X
+2895(1991.)X
+555 4071([CHEN91])N
+929(Cheng,)X
+1180(E.,)X
+1291(Chang,)X
+1542(E.,)X
+1653(Klein,)X
+1872(J.,)X
+1964(Lee,)X
+2126(D.,)X
+2245(Lu,)X
+2375(E.,)X
+2485(Lutgardo,)X
+2820(A.,)X
+2939(Obermarck,)X
+3342(R.,)X
+3456(``An)X
+3629(Open)X
+3824(and)X
+3961(Extensible)X
+727 4161(Event-Based)N
+1157(Transaction)X
+1556(Manager'',)X
+2 f
+1936(Proceedings)X
+2357(1991)X
+2537(Summer)X
+2820(Usenix)X
+1 f
+3043(,)X
+3083(Nashville,)X
+3430(TN,)X
+3577(June)X
+3744(1991.)X
+555 4341([CHOU85])N
+943(Chou,)X
+1163(H.,)X
+1288(DeWitt,)X
+1570(D.,)X
+1694(``An)X
+1872(Evaluation)X
+2245(of)X
+2338(Buffer)X
+2574(Management)X
+3019(Strategies)X
+3361(for)X
+3481(Relational)X
+3836(Database)X
+4157(Sys-)X
+727 4431(tems'',)N
+2 f
+972(Proceedings)X
+1393(of)X
+1475(the)X
+1593(11th)X
+1755(International)X
+2197(Conference)X
+2587(on)X
+2687(Very)X
+2859(Large)X
+3070(Databases)X
+1 f
+3408(,)X
+3448(1985.)X
+555 4611([DEWI84])N
+925(DeWitt,)X
+1207(D.,)X
+1331(Katz,)X
+1529(R.,)X
+1648(Olken,)X
+1890(F.,)X
+2000(Shapiro,)X
+2295(L.,)X
+2410(Stonebraker,)X
+2843(M.,)X
+2979(Wood,)X
+3220(D.,)X
+3343(``Implementation)X
+3929(Techniques)X
+727 4701(for)N
+841(Main)X
+1030(Memory)X
+1326(Database)X
+1641(Systems'',)X
+2 f
+2001(Proceedings)X
+2422(of)X
+2504(SIGMOD)X
+1 f
+2812(,)X
+2852(pp.)X
+2972(1-8,)X
+3119(June)X
+3286(1984.)X
+555 4881([GRAY76])N
+944(Gray,)X
+1153(J.,)X
+1252(Lorie,)X
+1474(R.,)X
+1595(Putzolu,)X
+1887(F.,)X
+1999(and)X
+2143(Traiger,)X
+2428(I.,)X
+2522(``Granularity)X
+2973(of)X
+3067(locks)X
+3263(and)X
+3406(degrees)X
+3679(of)X
+3773(consistency)X
+4174(in)X
+4263(a)X
+727 4971(large)N
+909(shared)X
+1140(data)X
+1295(base'',)X
+2 f
+1533(Modeling)X
+1861(in)X
+1944(Data)X
+2125(Base)X
+2301(Management)X
+2740(Systems)X
+1 f
+2994(,)X
+3034(Elsevier)X
+3317(North)X
+3524(Holland,)X
+3822(New)X
+3994(York,)X
+4199(pp.)X
+727 5061(365-394.)N
+555 5241([HAER83])N
+931(Haerder,)X
+1235(T.)X
+1348(Reuter,)X
+1606(A.)X
+1728(``Principles)X
+2126(of)X
+2217(Transaction-Oriented)X
+2928(Database)X
+3246(Recovery'',)X
+2 f
+3651(Computing)X
+4029(Surveys)X
+1 f
+4279(,)X
+727 5331(15\(4\);)N
+943(237-318,)X
+1250(1983.)X
+555 5511([KUNG81])N
+943(Kung,)X
+1162(H.)X
+1261(T.,)X
+1371(Richardson,)X
+1777(J.,)X
+1869(``On)X
+2042(Optimistic)X
+2400(Methods)X
+2701(for)X
+2816(Concurrency)X
+3252(Control'',)X
+2 f
+3591(ACM)X
+3781(Transactions)X
+4219(on)X
+727 5601(Database)N
+1054(Systems)X
+1 f
+1328(6\(2\);)X
+1504(213-226,)X
+1811(1981.)X
+
+17 p
+%%Page: 17 17
+10 s 10 xH 0 xS 1 f
+3 f
+1 f
+555 630([LEHM81])N
+939(Lehman,)X
+1245(P.,)X
+1352(Yao,)X
+1529(S.,)X
+1636(``Ef\256cient)X
+1989(Locking)X
+2279(for)X
+2396(Concurrent)X
+2780(Operations)X
+3155(on)X
+3258(B-trees'',)X
+2 f
+3587(ACM)X
+3779(Transactions)X
+4219(on)X
+727 720(Database)N
+1054(Systems)X
+1 f
+1308(,)X
+1348(6\(4\),)X
+1522(December)X
+1873(1981.)X
+555 900([MOHA91])N
+964(Mohan,)X
+1241(C.,)X
+1364(Pirahesh,)X
+1690(H.,)X
+1818(``ARIES-RRH:)X
+2366(Restricted)X
+2721(Repeating)X
+3076(of)X
+3173(History)X
+3442(in)X
+3533(the)X
+3660(ARIES)X
+3920(Transaction)X
+727 990(Recovery)N
+1055(Method'',)X
+2 f
+1398(Proceedings)X
+1819(7th)X
+1941(International)X
+2383(Conference)X
+2773(on)X
+2873(Data)X
+3053(Engineering)X
+1 f
+3449(,)X
+3489(Kobe,)X
+3703(Japan,)X
+3926(April)X
+4115(1991.)X
+555 1170([NODI90])N
+914(Nodine,)X
+1194(M.,)X
+1328(Zdonik,)X
+1602(S.,)X
+1709(``Cooperative)X
+2178(Transaction)X
+2580(Hierarchies:)X
+2996(A)X
+3077(Transaction)X
+3479(Model)X
+3711(to)X
+3796(Support)X
+4072(Design)X
+727 1260(Applications'',)N
+2 f
+1242(Proceedings)X
+1675(16th)X
+1849(International)X
+2303(Conference)X
+2704(on)X
+2815(Very)X
+2998(Large)X
+3220(Data)X
+3411(Bases)X
+1 f
+3598(,)X
+3649(Brisbane,)X
+3985(Australia,)X
+727 1350(August)N
+978(1990.)X
+555 1530([OUST90])N
+923(Ousterhout,)X
+1324(J.,)X
+1420(``Tcl:)X
+1648(An)X
+1771(Embeddable)X
+2197(Command)X
+2555(Language'',)X
+2 f
+2971(Proceedings)X
+3396(1990)X
+3580(Winter)X
+3822(Usenix)X
+1 f
+4045(,)X
+4089(Wash-)X
+727 1620(ington,)N
+971(D.C.,)X
+1162(January)X
+1432(1990.)X
+555 1800([POSIX91])N
+955(``Unapproved)X
+1441(Draft)X
+1645(for)X
+1773(Realtime)X
+2096(Extension)X
+2450(for)X
+2578(Portable)X
+2879(Operating)X
+3234(Systems'',)X
+3608(Draft)X
+3812(11,)X
+3946(October)X
+4239(7,)X
+727 1890(1991,)N
+927(IEEE)X
+1121(Computer)X
+1461(Society.)X
+555 2070([ROSE91])N
+925(Rosenblum,)X
+1341(M.,)X
+1484(Ousterhout,)X
+1892(J.,)X
+1995(``The)X
+2206(Design)X
+2464(and)X
+2611(Implementation)X
+3149(of)X
+3247(a)X
+3314(Log-Structured)X
+3835(File)X
+3990(System'',)X
+2 f
+727 2160(Proceedings)N
+1148(of)X
+1230(the)X
+1348(13th)X
+1510(Symposium)X
+1895(on)X
+1995(Operating)X
+2344(Systems)X
+2618(Principles)X
+1 f
+2947(,)X
+2987(1991.)X
+555 2340([SELT91])N
+904(Seltzer,)X
+1171(M.,)X
+1306(Stonebraker,)X
+1738(M.,)X
+1873(``Read)X
+2116(Optimized)X
+2478(File)X
+2626(Systems:)X
+2938(A)X
+3020(Performance)X
+3454(Evaluation'',)X
+2 f
+3898(Proceedings)X
+727 2430(7th)N
+849(Annual)X
+1100(International)X
+1542(Conference)X
+1932(on)X
+2032(Data)X
+2212(Engineering)X
+1 f
+2608(,)X
+2648(Kobe,)X
+2862(Japan,)X
+3085(April)X
+3274(1991.)X
+555 2610([SPEC88])N
+907(Spector,)X
+1200(Rausch,)X
+1484(Bruell,)X
+1732(``Camelot:)X
+2107(A)X
+2192(Flexible,)X
+2501(Distributed)X
+2888(Transaction)X
+3294(Processing)X
+3668(System'',)X
+2 f
+4004(Proceed-)X
+727 2700(ings)N
+880(of)X
+962(Spring)X
+1195(COMPCON)X
+1606(1988)X
+1 f
+(,)S
+1806(February)X
+2116(1988.)X
+555 2880([SQL86])N
+862(American)X
+1201(National)X
+1499(Standards)X
+1836(Institute,)X
+2139(``Database)X
+2509(Language)X
+2847(SQL'',)X
+3093(ANSI)X
+3301(X3.135-1986)X
+3747(\(ISO)X
+3924(9075\),)X
+4152(May)X
+727 2970(1986.)N
+555 3150([STON81])N
+919(Stonebraker,)X
+1348(M.,)X
+1480(``Operating)X
+1876(System)X
+2132(Support)X
+2406(for)X
+2520(Database)X
+2835(Management'',)X
+2 f
+3348(Communications)X
+3910(of)X
+3992(the)X
+4110(ACM)X
+1 f
+4279(,)X
+727 3240(1981.)N
+555 3420([SULL92])N
+925(Sullivan,)X
+1247(M.,)X
+1394(Olson,)X
+1641(M.,)X
+1788(``An)X
+1976(Index)X
+2195(Implementation)X
+2737(Supporting)X
+3127(Fast)X
+3295(Recovery)X
+3638(for)X
+3767(the)X
+3900(POSTGRES)X
+727 3510(Storage)N
+1014(System'',)X
+1365(to)X
+1469(appear)X
+1726(in)X
+2 f
+1830(Proceedings)X
+2272(8th)X
+2415(Annual)X
+2687(International)X
+3150(Conference)X
+3561(on)X
+3682(Data)X
+3883(Engineering)X
+1 f
+4279(,)X
+727 3600(Tempe,)N
+990(Arizona,)X
+1289(February)X
+1599(1992.)X
+555 3780([TPCB90])N
+914(Transaction)X
+1319(Processing)X
+1692(Performance)X
+2129(Council,)X
+2428(``TPC)X
+2653(Benchmark)X
+3048(B'',)X
+3200(Standard)X
+3510(Speci\256cation,)X
+3973(Waterside)X
+727 3870(Associates,)N
+1110(Fremont,)X
+1421(CA.,)X
+1592(1990.)X
+555 4050([YOUN91])N
+947(Young,)X
+1211(M.)X
+1328(W.,)X
+1470(Thompson,)X
+1858(D.)X
+1962(S.,)X
+2072(Jaffe,)X
+2274(E.,)X
+2388(``A)X
+2525(Modular)X
+2826(Architecture)X
+3253(for)X
+3372(Distributed)X
+3757(Transaction)X
+4161(Pro-)X
+727 4140(cessing'',)N
+2 f
+1057(Proceedings)X
+1478(1991)X
+1658(Winter)X
+1896(Usenix)X
+1 f
+2119(,)X
+2159(Dallas,)X
+2404(TX,)X
+2551(January)X
+2821(1991.)X
+3 f
+755 4263(Margo)N
+1008(I.)X
+1080(Seltzer)X
+1 f
+1338(is)X
+1411(a)X
+1467(Ph.D.)X
+1669(student)X
+1920(in)X
+2002(the)X
+2120(Department)X
+2519(of)X
+2606(Electrical)X
+2934(Engineering)X
+3346(and)X
+3482(Computer)X
+3822(Sciences)X
+4123(at)X
+4201(the)X
+555 4353(University)N
+919(of)X
+1012(California,)X
+1383(Berkeley.)X
+1739(Her)X
+1886(research)X
+2181(interests)X
+2474(include)X
+2735(\256le)X
+2862(systems,)X
+3160(databases,)X
+3513(and)X
+3654(transaction)X
+4031(process-)X
+555 4443(ing)N
+686(systems.)X
+1008(She)X
+1157(spent)X
+1355(several)X
+1612(years)X
+1811(working)X
+2107(at)X
+2194(startup)X
+2441(companies)X
+2813(designing)X
+3153(and)X
+3298(implementing)X
+3771(\256le)X
+3902(systems)X
+4183(and)X
+555 4533(transaction)N
+929(processing)X
+1294(software)X
+1592(and)X
+1729(designing)X
+2061(microprocessors.)X
+2648(Ms.)X
+2791(Seltzer)X
+3035(received)X
+3329(her)X
+3453(AB)X
+3585(in)X
+3668(Applied)X
+3947(Mathemat-)X
+555 4623(ics)N
+664(from)X
+840 0.1953(Harvard/Radcliffe)AX
+1445(College)X
+1714(in)X
+1796(1983.)X
+755 4746(In)N
+845(her)X
+971(spare)X
+1163(time,)X
+1347(Margo)X
+1583(can)X
+1717(usually)X
+1970(be)X
+2068(found)X
+2277(preparing)X
+2607(massive)X
+2887(quantities)X
+3220(of)X
+3309(food)X
+3478(for)X
+3594(hungry)X
+3843(hordes,)X
+4099(study-)X
+555 4836(ing)N
+677(Japanese,)X
+1003(or)X
+1090(playing)X
+1350(soccer)X
+1576(with)X
+1738(an)X
+1834(exciting)X
+2112(Bay)X
+2261(Area)X
+2438(Women's)X
+2770(Soccer)X
+3009(team,)X
+3205(the)X
+3323(Berkeley)X
+3633(Bruisers.)X
+3 f
+755 5049(Michael)N
+1056(A.)X
+1159(Olson)X
+1 f
+1383(is)X
+1461(a)X
+1522(Master's)X
+1828(student)X
+2084(in)X
+2170(the)X
+2292(Department)X
+2695(of)X
+2786(Electrical)X
+3118(Engineering)X
+3534(and)X
+3674(Computer)X
+4018(Sciences)X
+555 5139(at)N
+645(the)X
+774(University)X
+1143(of)X
+1241(California,)X
+1617(Berkeley.)X
+1978(His)X
+2120(primary)X
+2405(interests)X
+2703(are)X
+2833(database)X
+3141(systems)X
+3425(and)X
+3572(mass)X
+3763(storage)X
+4026(systems.)X
+555 5229(Mike)N
+759(spent)X
+963(two)X
+1118(years)X
+1323(working)X
+1625(for)X
+1754(a)X
+1825(commercial)X
+2239(database)X
+2551(system)X
+2808(vendor)X
+3066(before)X
+3307(joining)X
+3567(the)X
+3699(Postgres)X
+4004(Research)X
+555 5319(Group)N
+780(at)X
+858(Berkeley)X
+1168(in)X
+1250(1988.)X
+1470(He)X
+1584(received)X
+1877(his)X
+1990(B.A.)X
+2161(in)X
+2243(Computer)X
+2583(Science)X
+2853(from)X
+3029(Berkeley)X
+3339(in)X
+3421(May)X
+3588(1991.)X
+755 5442(Mike)N
+945(only)X
+1108(recently)X
+1388(transferred)X
+1758(into)X
+1903(Sin)X
+2030(City,)X
+2208(but)X
+2330(is)X
+2403(rapidly)X
+2650(adopting)X
+2950(local)X
+3126(customs)X
+3408(and)X
+3544(coloration.)X
+3929(In)X
+4016(his)X
+4129(spare)X
+555 5532(time,)N
+742(he)X
+843(organizes)X
+1176(informal)X
+1477(Friday)X
+1711(afternoon)X
+2043(study)X
+2240(groups)X
+2482(to)X
+2568(discuss)X
+2823(recent)X
+3044(technical)X
+3358(and)X
+3498(economic)X
+3834(developments.)X
+555 5622(Among)N
+815(his)X
+928(hobbies)X
+1197(are)X
+1316(Charles)X
+1581(Dickens,)X
+1884(Red)X
+2033(Rock,)X
+2242(and)X
+2378(speaking)X
+2683(Dutch)X
+2899(to)X
+2981(anyone)X
+3233(who)X
+3391(will)X
+3535(permit)X
+3764(it.)X
+
+17 p
+%%Trailer
+xt
+
+xs
+
diff --git a/lib/libc/db/hash/Makefile.inc b/lib/libc/db/hash/Makefile.inc
new file mode 100644
index 0000000..38b523d
--- /dev/null
+++ b/lib/libc/db/hash/Makefile.inc
@@ -0,0 +1,7 @@
+# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libc/db/hash
+
+SRCS+= hash.c hash_bigkey.c hash_buf.c hash_func.c hash_log2.c \
+ hash_page.c hsearch.c ndbm.c
diff --git a/lib/libc/db/hash/README b/lib/libc/db/hash/README
new file mode 100644
index 0000000..f29ccf7
--- /dev/null
+++ b/lib/libc/db/hash/README
@@ -0,0 +1,72 @@
+# @(#)README 8.1 (Berkeley) 6/4/93
+
+This package implements a superset of the hsearch and dbm/ndbm libraries.
+
+Test Programs:
+ All test programs which need key/data pairs expect them entered
+ with key and data on separate lines
+
+ tcreat3.c
+ Takes
+ bucketsize (bsize),
+ fill factor (ffactor), and
+ initial number of elements (nelem).
+ Creates a hash table named hashtest containing the
+ keys/data pairs entered from standard in.
+ thash4.c
+ Takes
+ bucketsize (bsize),
+ fill factor (ffactor),
+ initial number of elements (nelem)
+ bytes of cache (ncached), and
+ file from which to read data (fname)
+ Creates a table from the key/data pairs on standard in and
+ then does a read of each key/data in fname
+ tdel.c
+ Takes
+ bucketsize (bsize), and
+ fill factor (ffactor).
+ file from which to read data (fname)
+ Reads each key/data pair from fname and deletes the
+ key from the hash table hashtest
+ tseq.c
+ Reads the key/data pairs in the file hashtest and writes them
+ to standard out.
+ tread2.c
+ Takes
+ butes of cache (ncached).
+ Reads key/data pairs from standard in and looks them up
+ in the file hashtest.
+ tverify.c
+ Reads key/data pairs from standard in, looks them up
+ in the file hashtest, and verifies that the data is
+ correct.
+
+NOTES:
+
+The file search.h is provided for using the hsearch compatible interface
+on BSD systems. On System V derived systems, search.h should appear in
+/usr/include.
+
+The man page ../man/db.3 explains the interface to the hashing system.
+The file hash.ps is a postscript copy of a paper explaining
+the history, implementation, and performance of the hash package.
+
+"bugs" or idiosyncracies
+
+If you have a lot of overflows, it is possible to run out of overflow
+pages. Currently, this will cause a message to be printed on stderr.
+Eventually, this will be indicated by a return error code.
+
+If you are using the ndbm interface and exit without flushing or closing the
+file, you may lose updates since the package buffers all writes. Also,
+the db interface only creates a single database file. To avoid overwriting
+the user's original file, the suffix ".db" is appended to the file name
+passed to dbm_open. Additionally, if your code "knows" about the historic
+.dir and .pag files, it will break.
+
+There is a fundamental difference between this package and the old hsearch.
+Hsearch requires the user to maintain the keys and data in the application's
+allocated memory while hash takes care of all storage management. The down
+side is that the byte strings passed in the ENTRY structure must be null
+terminated (both the keys and the data).
diff --git a/lib/libc/db/hash/extern.h b/lib/libc/db/hash/extern.h
new file mode 100644
index 0000000..3167e6d
--- /dev/null
+++ b/lib/libc/db/hash/extern.h
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)extern.h 8.4 (Berkeley) 6/16/94
+ */
+
+BUFHEAD *__add_ovflpage __P((HTAB *, BUFHEAD *));
+int __addel __P((HTAB *, BUFHEAD *, const DBT *, const DBT *));
+int __big_delete __P((HTAB *, BUFHEAD *));
+int __big_insert __P((HTAB *, BUFHEAD *, const DBT *, const DBT *));
+int __big_keydata __P((HTAB *, BUFHEAD *, DBT *, DBT *, int));
+int __big_return __P((HTAB *, BUFHEAD *, int, DBT *, int));
+int __big_split __P((HTAB *, BUFHEAD *, BUFHEAD *, BUFHEAD *,
+ int, u_int32_t, SPLIT_RETURN *));
+int __buf_free __P((HTAB *, int, int));
+void __buf_init __P((HTAB *, int));
+u_int32_t __call_hash __P((HTAB *, char *, int));
+int __delpair __P((HTAB *, BUFHEAD *, int));
+int __expand_table __P((HTAB *));
+int __find_bigpair __P((HTAB *, BUFHEAD *, int, char *, int));
+u_int16_t __find_last_page __P((HTAB *, BUFHEAD **));
+void __free_ovflpage __P((HTAB *, BUFHEAD *));
+BUFHEAD *__get_buf __P((HTAB *, u_int32_t, BUFHEAD *, int));
+int __get_page __P((HTAB *, char *, u_int32_t, int, int, int));
+int __ibitmap __P((HTAB *, int, int, int));
+u_int32_t __log2 __P((u_int32_t));
+int __put_page __P((HTAB *, char *, u_int32_t, int, int));
+void __reclaim_buf __P((HTAB *, BUFHEAD *));
+int __split_page __P((HTAB *, u_int32_t, u_int32_t));
+
+/* Default hash routine. */
+extern u_int32_t (*__default_hash) __P((const void *, size_t));
+
+#ifdef HASH_STATISTICS
+extern int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
+#endif
diff --git a/lib/libc/db/hash/hash.c b/lib/libc/db/hash/hash.c
new file mode 100644
index 0000000..7d000dc
--- /dev/null
+++ b/lib/libc/db/hash/hash.c
@@ -0,0 +1,1001 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef DEBUG
+#include <assert.h>
+#endif
+
+#include <db.h>
+#include "hash.h"
+#include "page.h"
+#include "extern.h"
+
+static int alloc_segs __P((HTAB *, int));
+static int flush_meta __P((HTAB *));
+static int hash_access __P((HTAB *, ACTION, DBT *, DBT *));
+static int hash_close __P((DB *));
+static int hash_delete __P((const DB *, const DBT *, u_int32_t));
+static int hash_fd __P((const DB *));
+static int hash_get __P((const DB *, const DBT *, DBT *, u_int32_t));
+static int hash_put __P((const DB *, DBT *, const DBT *, u_int32_t));
+static void *hash_realloc __P((SEGMENT **, int, int));
+static int hash_seq __P((const DB *, DBT *, DBT *, u_int32_t));
+static int hash_sync __P((const DB *, u_int32_t));
+static int hdestroy __P((HTAB *));
+static HTAB *init_hash __P((HTAB *, const char *, HASHINFO *));
+static int init_htab __P((HTAB *, int));
+#if BYTE_ORDER == LITTLE_ENDIAN
+static void swap_header __P((HTAB *));
+static void swap_header_copy __P((HASHHDR *, HASHHDR *));
+#endif
+
+/* Fast arithmetic, relying on powers of 2, */
+#define MOD(x, y) ((x) & ((y) - 1))
+
+#define RETURN_ERROR(ERR, LOC) { save_errno = ERR; goto LOC; }
+
+/* Return values */
+#define SUCCESS (0)
+#define ERROR (-1)
+#define ABNORMAL (1)
+
+#ifdef HASH_STATISTICS
+int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
+#endif
+
+/************************** INTERFACE ROUTINES ***************************/
+/* OPEN/CLOSE */
+
+extern DB *
+__hash_open(file, flags, mode, info, dflags)
+ const char *file;
+ int flags, mode, dflags;
+ const HASHINFO *info; /* Special directives for create */
+{
+ HTAB *hashp;
+ struct stat statbuf;
+ DB *dbp;
+ int bpages, hdrsize, new_table, nsegs, save_errno;
+
+ if ((flags & O_ACCMODE) == O_WRONLY) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB))))
+ return (NULL);
+ hashp->fp = -1;
+
+ /*
+ * Even if user wants write only, we need to be able to read
+ * the actual file, so we need to open it read/write. But, the
+ * field in the hashp structure needs to be accurate so that
+ * we can check accesses.
+ */
+ hashp->flags = flags;
+
+ new_table = 0;
+ if (!file || (flags & O_TRUNC) ||
+ (stat(file, &statbuf) && (errno == ENOENT))) {
+ if (errno == ENOENT)
+ errno = 0; /* Just in case someone looks at errno */
+ new_table = 1;
+ }
+ if (file) {
+ if ((hashp->fp = open(file, flags, mode)) == -1)
+ RETURN_ERROR(errno, error0);
+
+ /* if the .db file is empty, and we had permission to create
+ a new .db file, then reinitialize the database */
+ if ((flags & O_CREAT) &&
+ fstat(hashp->fp, &statbuf) == 0 && statbuf.st_size == 0)
+ new_table = 1;
+
+ (void)fcntl(hashp->fp, F_SETFD, 1);
+ }
+ if (new_table) {
+ if (!(hashp = init_hash(hashp, file, (HASHINFO *)info)))
+ RETURN_ERROR(errno, error1);
+ } else {
+ /* Table already exists */
+ if (info && info->hash)
+ hashp->hash = info->hash;
+ else
+ hashp->hash = __default_hash;
+
+ hdrsize = read(hashp->fp, &hashp->hdr, sizeof(HASHHDR));
+#if BYTE_ORDER == LITTLE_ENDIAN
+ swap_header(hashp);
+#endif
+ if (hdrsize == -1)
+ RETURN_ERROR(errno, error1);
+ if (hdrsize != sizeof(HASHHDR))
+ RETURN_ERROR(EFTYPE, error1);
+ /* Verify file type, versions and hash function */
+ if (hashp->MAGIC != HASHMAGIC)
+ RETURN_ERROR(EFTYPE, error1);
+#define OLDHASHVERSION 1
+ if (hashp->VERSION != HASHVERSION &&
+ hashp->VERSION != OLDHASHVERSION)
+ RETURN_ERROR(EFTYPE, error1);
+ if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY)
+ RETURN_ERROR(EFTYPE, error1);
+ /*
+ * Figure out how many segments we need. Max_Bucket is the
+ * maximum bucket number, so the number of buckets is
+ * max_bucket + 1.
+ */
+ nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) /
+ hashp->SGSIZE;
+ hashp->nsegs = 0;
+ if (alloc_segs(hashp, nsegs))
+ /*
+ * If alloc_segs fails, table will have been destroyed
+ * and errno will have been set.
+ */
+ return (NULL);
+ /* Read in bitmaps */
+ bpages = (hashp->SPARES[hashp->OVFL_POINT] +
+ (hashp->BSIZE << BYTE_SHIFT) - 1) >>
+ (hashp->BSHIFT + BYTE_SHIFT);
+
+ hashp->nmaps = bpages;
+ (void)memset(&hashp->mapp[0], 0, bpages * sizeof(u_int32_t *));
+ }
+
+ /* Initialize Buffer Manager */
+ if (info && info->cachesize)
+ __buf_init(hashp, info->cachesize);
+ else
+ __buf_init(hashp, DEF_BUFSIZE);
+
+ hashp->new_file = new_table;
+ hashp->save_file = file && (hashp->flags & O_RDWR);
+ hashp->cbucket = -1;
+ if (!(dbp = (DB *)malloc(sizeof(DB)))) {
+ save_errno = errno;
+ hdestroy(hashp);
+ errno = save_errno;
+ return (NULL);
+ }
+ dbp->internal = hashp;
+ dbp->close = hash_close;
+ dbp->del = hash_delete;
+ dbp->fd = hash_fd;
+ dbp->get = hash_get;
+ dbp->put = hash_put;
+ dbp->seq = hash_seq;
+ dbp->sync = hash_sync;
+ dbp->type = DB_HASH;
+
+#ifdef DEBUG
+ (void)fprintf(stderr,
+"%s\n%s%x\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n",
+ "init_htab:",
+ "TABLE POINTER ", hashp,
+ "BUCKET SIZE ", hashp->BSIZE,
+ "BUCKET SHIFT ", hashp->BSHIFT,
+ "DIRECTORY SIZE ", hashp->DSIZE,
+ "SEGMENT SIZE ", hashp->SGSIZE,
+ "SEGMENT SHIFT ", hashp->SSHIFT,
+ "FILL FACTOR ", hashp->FFACTOR,
+ "MAX BUCKET ", hashp->MAX_BUCKET,
+ "OVFL POINT ", hashp->OVFL_POINT,
+ "LAST FREED ", hashp->LAST_FREED,
+ "HIGH MASK ", hashp->HIGH_MASK,
+ "LOW MASK ", hashp->LOW_MASK,
+ "NSEGS ", hashp->nsegs,
+ "NKEYS ", hashp->NKEYS);
+#endif
+#ifdef HASH_STATISTICS
+ hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0;
+#endif
+ return (dbp);
+
+error1:
+ if (hashp != NULL)
+ (void)close(hashp->fp);
+
+error0:
+ free(hashp);
+ errno = save_errno;
+ return (NULL);
+}
+
+static int
+hash_close(dbp)
+ DB *dbp;
+{
+ HTAB *hashp;
+ int retval;
+
+ if (!dbp)
+ return (ERROR);
+
+ hashp = (HTAB *)dbp->internal;
+ retval = hdestroy(hashp);
+ free(dbp);
+ return (retval);
+}
+
+static int
+hash_fd(dbp)
+ const DB *dbp;
+{
+ HTAB *hashp;
+
+ if (!dbp)
+ return (ERROR);
+
+ hashp = (HTAB *)dbp->internal;
+ if (hashp->fp == -1) {
+ errno = ENOENT;
+ return (-1);
+ }
+ return (hashp->fp);
+}
+
+/************************** LOCAL CREATION ROUTINES **********************/
+static HTAB *
+init_hash(hashp, file, info)
+ HTAB *hashp;
+ const char *file;
+ HASHINFO *info;
+{
+ struct stat statbuf;
+ int nelem;
+
+ nelem = 1;
+ hashp->NKEYS = 0;
+ hashp->LORDER = BYTE_ORDER;
+ hashp->BSIZE = DEF_BUCKET_SIZE;
+ hashp->BSHIFT = DEF_BUCKET_SHIFT;
+ hashp->SGSIZE = DEF_SEGSIZE;
+ hashp->SSHIFT = DEF_SEGSIZE_SHIFT;
+ hashp->DSIZE = DEF_DIRSIZE;
+ hashp->FFACTOR = DEF_FFACTOR;
+ hashp->hash = __default_hash;
+ memset(hashp->SPARES, 0, sizeof(hashp->SPARES));
+ memset(hashp->BITMAPS, 0, sizeof (hashp->BITMAPS));
+
+ /* Fix bucket size to be optimal for file system */
+ if (file != NULL) {
+ if (stat(file, &statbuf))
+ return (NULL);
+ hashp->BSIZE = statbuf.st_blksize;
+ hashp->BSHIFT = __log2(hashp->BSIZE);
+ }
+
+ if (info) {
+ if (info->bsize) {
+ /* Round pagesize up to power of 2 */
+ hashp->BSHIFT = __log2(info->bsize);
+ hashp->BSIZE = 1 << hashp->BSHIFT;
+ if (hashp->BSIZE > MAX_BSIZE) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ }
+ if (info->ffactor)
+ hashp->FFACTOR = info->ffactor;
+ if (info->hash)
+ hashp->hash = info->hash;
+ if (info->nelem)
+ nelem = info->nelem;
+ if (info->lorder) {
+ if (info->lorder != BIG_ENDIAN &&
+ info->lorder != LITTLE_ENDIAN) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ hashp->LORDER = info->lorder;
+ }
+ }
+ /* init_htab should destroy the table and set errno if it fails */
+ if (init_htab(hashp, nelem))
+ return (NULL);
+ else
+ return (hashp);
+}
+/*
+ * This calls alloc_segs which may run out of memory. Alloc_segs will destroy
+ * the table and set errno, so we just pass the error information along.
+ *
+ * Returns 0 on No Error
+ */
+static int
+init_htab(hashp, nelem)
+ HTAB *hashp;
+ int nelem;
+{
+ register int nbuckets, nsegs;
+ int l2;
+
+ /*
+ * Divide number of elements by the fill factor and determine a
+ * desired number of buckets. Allocate space for the next greater
+ * power of two number of buckets.
+ */
+ nelem = (nelem - 1) / hashp->FFACTOR + 1;
+
+ l2 = __log2(MAX(nelem, 2));
+ nbuckets = 1 << l2;
+
+ hashp->SPARES[l2] = l2 + 1;
+ hashp->SPARES[l2 + 1] = l2 + 1;
+ hashp->OVFL_POINT = l2;
+ hashp->LAST_FREED = 2;
+
+ /* First bitmap page is at: splitpoint l2 page offset 1 */
+ if (__ibitmap(hashp, OADDR_OF(l2, 1), l2 + 1, 0))
+ return (-1);
+
+ hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1;
+ hashp->HIGH_MASK = (nbuckets << 1) - 1;
+ hashp->HDRPAGES = ((MAX(sizeof(HASHHDR), MINHDRSIZE) - 1) >>
+ hashp->BSHIFT) + 1;
+
+ nsegs = (nbuckets - 1) / hashp->SGSIZE + 1;
+ nsegs = 1 << __log2(nsegs);
+
+ if (nsegs > hashp->DSIZE)
+ hashp->DSIZE = nsegs;
+ return (alloc_segs(hashp, nsegs));
+}
+
+/********************** DESTROY/CLOSE ROUTINES ************************/
+
+/*
+ * Flushes any changes to the file if necessary and destroys the hashp
+ * structure, freeing all allocated space.
+ */
+static int
+hdestroy(hashp)
+ HTAB *hashp;
+{
+ int i, save_errno;
+
+ save_errno = 0;
+
+#ifdef HASH_STATISTICS
+ (void)fprintf(stderr, "hdestroy: accesses %ld collisions %ld\n",
+ hash_accesses, hash_collisions);
+ (void)fprintf(stderr, "hdestroy: expansions %ld\n",
+ hash_expansions);
+ (void)fprintf(stderr, "hdestroy: overflows %ld\n",
+ hash_overflows);
+ (void)fprintf(stderr, "keys %ld maxp %d segmentcount %d\n",
+ hashp->NKEYS, hashp->MAX_BUCKET, hashp->nsegs);
+
+ for (i = 0; i < NCACHED; i++)
+ (void)fprintf(stderr,
+ "spares[%d] = %d\n", i, hashp->SPARES[i]);
+#endif
+ /*
+ * Call on buffer manager to free buffers, and if required,
+ * write them to disk.
+ */
+ if (__buf_free(hashp, 1, hashp->save_file))
+ save_errno = errno;
+ if (hashp->dir) {
+ free(*hashp->dir); /* Free initial segments */
+ /* Free extra segments */
+ while (hashp->exsegs--)
+ free(hashp->dir[--hashp->nsegs]);
+ free(hashp->dir);
+ }
+ if (flush_meta(hashp) && !save_errno)
+ save_errno = errno;
+ /* Free Bigmaps */
+ for (i = 0; i < hashp->nmaps; i++)
+ if (hashp->mapp[i])
+ free(hashp->mapp[i]);
+
+ if (hashp->fp != -1)
+ (void)close(hashp->fp);
+
+ free(hashp);
+
+ if (save_errno) {
+ errno = save_errno;
+ return (ERROR);
+ }
+ return (SUCCESS);
+}
+/*
+ * Write modified pages to disk
+ *
+ * Returns:
+ * 0 == OK
+ * -1 ERROR
+ */
+static int
+hash_sync(dbp, flags)
+ const DB *dbp;
+ u_int32_t flags;
+{
+ HTAB *hashp;
+
+ if (flags != 0) {
+ errno = EINVAL;
+ return (ERROR);
+ }
+
+ if (!dbp)
+ return (ERROR);
+
+ hashp = (HTAB *)dbp->internal;
+ if (!hashp->save_file)
+ return (0);
+ if (__buf_free(hashp, 0, 1) || flush_meta(hashp))
+ return (ERROR);
+ hashp->new_file = 0;
+ return (0);
+}
+
+/*
+ * Returns:
+ * 0 == OK
+ * -1 indicates that errno should be set
+ */
+static int
+flush_meta(hashp)
+ HTAB *hashp;
+{
+ HASHHDR *whdrp;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ HASHHDR whdr;
+#endif
+ int fp, i, wsize;
+
+ if (!hashp->save_file)
+ return (0);
+ hashp->MAGIC = HASHMAGIC;
+ hashp->VERSION = HASHVERSION;
+ hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY));
+
+ fp = hashp->fp;
+ whdrp = &hashp->hdr;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ whdrp = &whdr;
+ swap_header_copy(&hashp->hdr, whdrp);
+#endif
+ if ((lseek(fp, (off_t)0, SEEK_SET) == -1) ||
+ ((wsize = write(fp, whdrp, sizeof(HASHHDR))) == -1))
+ return (-1);
+ else
+ if (wsize != sizeof(HASHHDR)) {
+ errno = EFTYPE;
+ hashp->error = errno;
+ return (-1);
+ }
+ for (i = 0; i < NCACHED; i++)
+ if (hashp->mapp[i])
+ if (__put_page(hashp, (char *)hashp->mapp[i],
+ hashp->BITMAPS[i], 0, 1))
+ return (-1);
+ return (0);
+}
+
+/*******************************SEARCH ROUTINES *****************************/
+/*
+ * All the access routines return
+ *
+ * Returns:
+ * 0 on SUCCESS
+ * 1 to indicate an external ERROR (i.e. key not found, etc)
+ * -1 to indicate an internal ERROR (i.e. out of memory, etc)
+ */
+static int
+hash_get(dbp, key, data, flag)
+ const DB *dbp;
+ const DBT *key;
+ DBT *data;
+ u_int32_t flag;
+{
+ HTAB *hashp;
+
+ hashp = (HTAB *)dbp->internal;
+ if (flag) {
+ hashp->error = errno = EINVAL;
+ return (ERROR);
+ }
+ return (hash_access(hashp, HASH_GET, (DBT *)key, data));
+}
+
+static int
+hash_put(dbp, key, data, flag)
+ const DB *dbp;
+ DBT *key;
+ const DBT *data;
+ u_int32_t flag;
+{
+ HTAB *hashp;
+
+ hashp = (HTAB *)dbp->internal;
+ if (flag && flag != R_NOOVERWRITE) {
+ hashp->error = errno = EINVAL;
+ return (ERROR);
+ }
+ if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
+ hashp->error = errno = EPERM;
+ return (ERROR);
+ }
+ return (hash_access(hashp, flag == R_NOOVERWRITE ?
+ HASH_PUTNEW : HASH_PUT, (DBT *)key, (DBT *)data));
+}
+
+static int
+hash_delete(dbp, key, flag)
+ const DB *dbp;
+ const DBT *key;
+ u_int32_t flag; /* Ignored */
+{
+ HTAB *hashp;
+
+ hashp = (HTAB *)dbp->internal;
+ if (flag && flag != R_CURSOR) {
+ hashp->error = errno = EINVAL;
+ return (ERROR);
+ }
+ if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
+ hashp->error = errno = EPERM;
+ return (ERROR);
+ }
+ return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL));
+}
+
+/*
+ * Assume that hashp has been set in wrapper routine.
+ */
+static int
+hash_access(hashp, action, key, val)
+ HTAB *hashp;
+ ACTION action;
+ DBT *key, *val;
+{
+ register BUFHEAD *rbufp;
+ BUFHEAD *bufp, *save_bufp;
+ register u_int16_t *bp;
+ register int n, ndx, off, size;
+ register char *kp;
+ u_int16_t pageno;
+
+#ifdef HASH_STATISTICS
+ hash_accesses++;
+#endif
+
+ off = hashp->BSIZE;
+ size = key->size;
+ kp = (char *)key->data;
+ rbufp = __get_buf(hashp, __call_hash(hashp, kp, size), NULL, 0);
+ if (!rbufp)
+ return (ERROR);
+ save_bufp = rbufp;
+
+ /* Pin the bucket chain */
+ rbufp->flags |= BUF_PIN;
+ for (bp = (u_int16_t *)rbufp->page, n = *bp++, ndx = 1; ndx < n;)
+ if (bp[1] >= REAL_KEY) {
+ /* Real key/data pair */
+ if (size == off - *bp &&
+ memcmp(kp, rbufp->page + *bp, size) == 0)
+ goto found;
+ off = bp[1];
+#ifdef HASH_STATISTICS
+ hash_collisions++;
+#endif
+ bp += 2;
+ ndx += 2;
+ } else if (bp[1] == OVFLPAGE) {
+ rbufp = __get_buf(hashp, *bp, rbufp, 0);
+ if (!rbufp) {
+ save_bufp->flags &= ~BUF_PIN;
+ return (ERROR);
+ }
+ /* FOR LOOP INIT */
+ bp = (u_int16_t *)rbufp->page;
+ n = *bp++;
+ ndx = 1;
+ off = hashp->BSIZE;
+ } else if (bp[1] < REAL_KEY) {
+ if ((ndx =
+ __find_bigpair(hashp, rbufp, ndx, kp, size)) > 0)
+ goto found;
+ if (ndx == -2) {
+ bufp = rbufp;
+ if (!(pageno =
+ __find_last_page(hashp, &bufp))) {
+ ndx = 0;
+ rbufp = bufp;
+ break; /* FOR */
+ }
+ rbufp = __get_buf(hashp, pageno, bufp, 0);
+ if (!rbufp) {
+ save_bufp->flags &= ~BUF_PIN;
+ return (ERROR);
+ }
+ /* FOR LOOP INIT */
+ bp = (u_int16_t *)rbufp->page;
+ n = *bp++;
+ ndx = 1;
+ off = hashp->BSIZE;
+ } else {
+ save_bufp->flags &= ~BUF_PIN;
+ return (ERROR);
+ }
+ }
+
+ /* Not found */
+ switch (action) {
+ case HASH_PUT:
+ case HASH_PUTNEW:
+ if (__addel(hashp, rbufp, key, val)) {
+ save_bufp->flags &= ~BUF_PIN;
+ return (ERROR);
+ } else {
+ save_bufp->flags &= ~BUF_PIN;
+ return (SUCCESS);
+ }
+ case HASH_GET:
+ case HASH_DELETE:
+ default:
+ save_bufp->flags &= ~BUF_PIN;
+ return (ABNORMAL);
+ }
+
+found:
+ switch (action) {
+ case HASH_PUTNEW:
+ save_bufp->flags &= ~BUF_PIN;
+ return (ABNORMAL);
+ case HASH_GET:
+ bp = (u_int16_t *)rbufp->page;
+ if (bp[ndx + 1] < REAL_KEY) {
+ if (__big_return(hashp, rbufp, ndx, val, 0))
+ return (ERROR);
+ } else {
+ val->data = (u_char *)rbufp->page + (int)bp[ndx + 1];
+ val->size = bp[ndx] - bp[ndx + 1];
+ }
+ break;
+ case HASH_PUT:
+ if ((__delpair(hashp, rbufp, ndx)) ||
+ (__addel(hashp, rbufp, key, val))) {
+ save_bufp->flags &= ~BUF_PIN;
+ return (ERROR);
+ }
+ break;
+ case HASH_DELETE:
+ if (__delpair(hashp, rbufp, ndx))
+ return (ERROR);
+ break;
+ default:
+ abort();
+ }
+ save_bufp->flags &= ~BUF_PIN;
+ return (SUCCESS);
+}
+
+static int
+hash_seq(dbp, key, data, flag)
+ const DB *dbp;
+ DBT *key, *data;
+ u_int32_t flag;
+{
+ register u_int32_t bucket;
+ register BUFHEAD *bufp;
+ HTAB *hashp;
+ u_int16_t *bp, ndx;
+
+ hashp = (HTAB *)dbp->internal;
+ if (flag && flag != R_FIRST && flag != R_NEXT) {
+ hashp->error = errno = EINVAL;
+ return (ERROR);
+ }
+#ifdef HASH_STATISTICS
+ hash_accesses++;
+#endif
+ if ((hashp->cbucket < 0) || (flag == R_FIRST)) {
+ hashp->cbucket = 0;
+ hashp->cndx = 1;
+ hashp->cpage = NULL;
+ }
+
+ for (bp = NULL; !bp || !bp[0]; ) {
+ if (!(bufp = hashp->cpage)) {
+ for (bucket = hashp->cbucket;
+ bucket <= hashp->MAX_BUCKET;
+ bucket++, hashp->cndx = 1) {
+ bufp = __get_buf(hashp, bucket, NULL, 0);
+ if (!bufp)
+ return (ERROR);
+ hashp->cpage = bufp;
+ bp = (u_int16_t *)bufp->page;
+ if (bp[0])
+ break;
+ }
+ hashp->cbucket = bucket;
+ if (hashp->cbucket > hashp->MAX_BUCKET) {
+ hashp->cbucket = -1;
+ return (ABNORMAL);
+ }
+ } else
+ bp = (u_int16_t *)hashp->cpage->page;
+
+#ifdef DEBUG
+ assert(bp);
+ assert(bufp);
+#endif
+ while (bp[hashp->cndx + 1] == OVFLPAGE) {
+ bufp = hashp->cpage =
+ __get_buf(hashp, bp[hashp->cndx], bufp, 0);
+ if (!bufp)
+ return (ERROR);
+ bp = (u_int16_t *)(bufp->page);
+ hashp->cndx = 1;
+ }
+ if (!bp[0]) {
+ hashp->cpage = NULL;
+ ++hashp->cbucket;
+ }
+ }
+ ndx = hashp->cndx;
+ if (bp[ndx + 1] < REAL_KEY) {
+ if (__big_keydata(hashp, bufp, key, data, 1))
+ return (ERROR);
+ } else {
+ key->data = (u_char *)hashp->cpage->page + bp[ndx];
+ key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx];
+ data->data = (u_char *)hashp->cpage->page + bp[ndx + 1];
+ data->size = bp[ndx] - bp[ndx + 1];
+ ndx += 2;
+ if (ndx > bp[0]) {
+ hashp->cpage = NULL;
+ hashp->cbucket++;
+ hashp->cndx = 1;
+ } else
+ hashp->cndx = ndx;
+ }
+ return (SUCCESS);
+}
+
+/********************************* UTILITIES ************************/
+
+/*
+ * Returns:
+ * 0 ==> OK
+ * -1 ==> Error
+ */
+extern int
+__expand_table(hashp)
+ HTAB *hashp;
+{
+ u_int32_t old_bucket, new_bucket;
+ int dirsize, new_segnum, spare_ndx;
+
+#ifdef HASH_STATISTICS
+ hash_expansions++;
+#endif
+ new_bucket = ++hashp->MAX_BUCKET;
+ old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK);
+
+ new_segnum = new_bucket >> hashp->SSHIFT;
+
+ /* Check if we need a new segment */
+ if (new_segnum >= hashp->nsegs) {
+ /* Check if we need to expand directory */
+ if (new_segnum >= hashp->DSIZE) {
+ /* Reallocate directory */
+ dirsize = hashp->DSIZE * sizeof(SEGMENT *);
+ if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1))
+ return (-1);
+ hashp->DSIZE = dirsize << 1;
+ }
+ if ((hashp->dir[new_segnum] =
+ (SEGMENT)calloc(hashp->SGSIZE, sizeof(SEGMENT))) == NULL)
+ return (-1);
+ hashp->exsegs++;
+ hashp->nsegs++;
+ }
+ /*
+ * If the split point is increasing (MAX_BUCKET's log base 2
+ * * increases), we need to copy the current contents of the spare
+ * split bucket to the next bucket.
+ */
+ spare_ndx = __log2(hashp->MAX_BUCKET + 1);
+ if (spare_ndx > hashp->OVFL_POINT) {
+ hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT];
+ hashp->OVFL_POINT = spare_ndx;
+ }
+
+ if (new_bucket > hashp->HIGH_MASK) {
+ /* Starting a new doubling */
+ hashp->LOW_MASK = hashp->HIGH_MASK;
+ hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK;
+ }
+ /* Relocate records to the new bucket */
+ return (__split_page(hashp, old_bucket, new_bucket));
+}
+
+/*
+ * If realloc guarantees that the pointer is not destroyed if the realloc
+ * fails, then this routine can go away.
+ */
+static void *
+hash_realloc(p_ptr, oldsize, newsize)
+ SEGMENT **p_ptr;
+ int oldsize, newsize;
+{
+ register void *p;
+
+ if ( (p = malloc(newsize)) ) {
+ memmove(p, *p_ptr, oldsize);
+ memset((char *)p + oldsize, 0, newsize - oldsize);
+ free(*p_ptr);
+ *p_ptr = p;
+ }
+ return (p);
+}
+
+extern u_int32_t
+__call_hash(hashp, k, len)
+ HTAB *hashp;
+ char *k;
+ int len;
+{
+ int n, bucket;
+
+ n = hashp->hash(k, len);
+ bucket = n & hashp->HIGH_MASK;
+ if (bucket > hashp->MAX_BUCKET)
+ bucket = bucket & hashp->LOW_MASK;
+ return (bucket);
+}
+
+/*
+ * Allocate segment table. On error, destroy the table and set errno.
+ *
+ * Returns 0 on success
+ */
+static int
+alloc_segs(hashp, nsegs)
+ HTAB *hashp;
+ int nsegs;
+{
+ register int i;
+ register SEGMENT store;
+
+ int save_errno;
+
+ if ((hashp->dir =
+ (SEGMENT *)calloc(hashp->DSIZE, sizeof(SEGMENT *))) == NULL) {
+ save_errno = errno;
+ (void)hdestroy(hashp);
+ errno = save_errno;
+ return (-1);
+ }
+ /* Allocate segments */
+ if ((store =
+ (SEGMENT)calloc(nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) {
+ save_errno = errno;
+ (void)hdestroy(hashp);
+ errno = save_errno;
+ return (-1);
+ }
+ for (i = 0; i < nsegs; i++, hashp->nsegs++)
+ hashp->dir[i] = &store[i << hashp->SSHIFT];
+ return (0);
+}
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+/*
+ * Hashp->hdr needs to be byteswapped.
+ */
+static void
+swap_header_copy(srcp, destp)
+ HASHHDR *srcp, *destp;
+{
+ int i;
+
+ P_32_COPY(srcp->magic, destp->magic);
+ P_32_COPY(srcp->version, destp->version);
+ P_32_COPY(srcp->lorder, destp->lorder);
+ P_32_COPY(srcp->bsize, destp->bsize);
+ P_32_COPY(srcp->bshift, destp->bshift);
+ P_32_COPY(srcp->dsize, destp->dsize);
+ P_32_COPY(srcp->ssize, destp->ssize);
+ P_32_COPY(srcp->sshift, destp->sshift);
+ P_32_COPY(srcp->ovfl_point, destp->ovfl_point);
+ P_32_COPY(srcp->last_freed, destp->last_freed);
+ P_32_COPY(srcp->max_bucket, destp->max_bucket);
+ P_32_COPY(srcp->high_mask, destp->high_mask);
+ P_32_COPY(srcp->low_mask, destp->low_mask);
+ P_32_COPY(srcp->ffactor, destp->ffactor);
+ P_32_COPY(srcp->nkeys, destp->nkeys);
+ P_32_COPY(srcp->hdrpages, destp->hdrpages);
+ P_32_COPY(srcp->h_charkey, destp->h_charkey);
+ for (i = 0; i < NCACHED; i++) {
+ P_32_COPY(srcp->spares[i], destp->spares[i]);
+ P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]);
+ }
+}
+
+static void
+swap_header(hashp)
+ HTAB *hashp;
+{
+ HASHHDR *hdrp;
+ int i;
+
+ hdrp = &hashp->hdr;
+
+ M_32_SWAP(hdrp->magic);
+ M_32_SWAP(hdrp->version);
+ M_32_SWAP(hdrp->lorder);
+ M_32_SWAP(hdrp->bsize);
+ M_32_SWAP(hdrp->bshift);
+ M_32_SWAP(hdrp->dsize);
+ M_32_SWAP(hdrp->ssize);
+ M_32_SWAP(hdrp->sshift);
+ M_32_SWAP(hdrp->ovfl_point);
+ M_32_SWAP(hdrp->last_freed);
+ M_32_SWAP(hdrp->max_bucket);
+ M_32_SWAP(hdrp->high_mask);
+ M_32_SWAP(hdrp->low_mask);
+ M_32_SWAP(hdrp->ffactor);
+ M_32_SWAP(hdrp->nkeys);
+ M_32_SWAP(hdrp->hdrpages);
+ M_32_SWAP(hdrp->h_charkey);
+ for (i = 0; i < NCACHED; i++) {
+ M_32_SWAP(hdrp->spares[i]);
+ M_16_SWAP(hdrp->bitmaps[i]);
+ }
+}
+#endif
diff --git a/lib/libc/db/hash/hash.h b/lib/libc/db/hash/hash.h
new file mode 100644
index 0000000..504a9b6
--- /dev/null
+++ b/lib/libc/db/hash/hash.h
@@ -0,0 +1,293 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)hash.h 8.3 (Berkeley) 5/31/94
+ */
+
+/* Operations */
+typedef enum {
+ HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE, HASH_FIRST, HASH_NEXT
+} ACTION;
+
+/* Buffer Management structures */
+typedef struct _bufhead BUFHEAD;
+
+struct _bufhead {
+ BUFHEAD *prev; /* LRU links */
+ BUFHEAD *next; /* LRU links */
+ BUFHEAD *ovfl; /* Overflow page buffer header */
+ u_int32_t addr; /* Address of this page */
+ char *page; /* Actual page data */
+ char flags;
+#define BUF_MOD 0x0001
+#define BUF_DISK 0x0002
+#define BUF_BUCKET 0x0004
+#define BUF_PIN 0x0008
+};
+
+#define IS_BUCKET(X) ((X) & BUF_BUCKET)
+
+typedef BUFHEAD **SEGMENT;
+
+/* Hash Table Information */
+typedef struct hashhdr { /* Disk resident portion */
+ int magic; /* Magic NO for hash tables */
+ int version; /* Version ID */
+ u_int32_t lorder; /* Byte Order */
+ int bsize; /* Bucket/Page Size */
+ int bshift; /* Bucket shift */
+ int dsize; /* Directory Size */
+ int ssize; /* Segment Size */
+ int sshift; /* Segment shift */
+ int ovfl_point; /* Where overflow pages are being
+ * allocated */
+ int last_freed; /* Last overflow page freed */
+ int max_bucket; /* ID of Maximum bucket in use */
+ int high_mask; /* Mask to modulo into entire table */
+ int low_mask; /* Mask to modulo into lower half of
+ * table */
+ int ffactor; /* Fill factor */
+ int nkeys; /* Number of keys in hash table */
+ int hdrpages; /* Size of table header */
+ int h_charkey; /* value of hash(CHARKEY) */
+#define NCACHED 32 /* number of bit maps and spare
+ * points */
+ int spares[NCACHED];/* spare pages for overflow */
+ u_int16_t bitmaps[NCACHED]; /* address of overflow page
+ * bitmaps */
+} HASHHDR;
+
+typedef struct htab { /* Memory resident data structure */
+ HASHHDR hdr; /* Header */
+ int nsegs; /* Number of allocated segments */
+ int exsegs; /* Number of extra allocated
+ * segments */
+ u_int32_t /* Hash function */
+ (*hash)__P((const void *, size_t));
+ int flags; /* Flag values */
+ int fp; /* File pointer */
+ char *tmp_buf; /* Temporary Buffer for BIG data */
+ char *tmp_key; /* Temporary Buffer for BIG keys */
+ BUFHEAD *cpage; /* Current page */
+ int cbucket; /* Current bucket */
+ int cndx; /* Index of next item on cpage */
+ int error; /* Error Number -- for DBM
+ * compatability */
+ int new_file; /* Indicates if fd is backing store
+ * or no */
+ int save_file; /* Indicates whether we need to flush
+ * file at
+ * exit */
+ u_int32_t *mapp[NCACHED]; /* Pointers to page maps */
+ int nmaps; /* Initial number of bitmaps */
+ int nbufs; /* Number of buffers left to
+ * allocate */
+ BUFHEAD bufhead; /* Header of buffer lru list */
+ SEGMENT *dir; /* Hash Bucket directory */
+} HTAB;
+
+/*
+ * Constants
+ */
+#define MAX_BSIZE 65536 /* 2^16 */
+#define MIN_BUFFERS 6
+#define MINHDRSIZE 512
+#define DEF_BUFSIZE 65536 /* 64 K */
+#define DEF_BUCKET_SIZE 4096
+#define DEF_BUCKET_SHIFT 12 /* log2(BUCKET) */
+#define DEF_SEGSIZE 256
+#define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */
+#define DEF_DIRSIZE 256
+#define DEF_FFACTOR 65536
+#define MIN_FFACTOR 4
+#define SPLTMAX 8
+#define CHARKEY "%$sniglet^&"
+#define NUMKEY 1038583
+#define BYTE_SHIFT 3
+#define INT_TO_BYTE 2
+#define INT_BYTE_SHIFT 5
+#define ALL_SET ((u_int32_t)0xFFFFFFFF)
+#define ALL_CLEAR 0
+
+#define PTROF(X) ((BUFHEAD *)((ptrdiff_t)(X)&~0x3))
+#define ISMOD(X) ((u_int32_t)(ptrdiff_t)(X)&0x1)
+#define DOMOD(X) ((X) = (char *)((ptrdiff_t)(X)|0x1))
+#define ISDISK(X) ((u_int32_t)(ptrdiff_t)(X)&0x2)
+#define DODISK(X) ((X) = (char *)((ptrdiff_t)(X)|0x2))
+
+#define BITS_PER_MAP 32
+
+/* Given the address of the beginning of a big map, clear/set the nth bit */
+#define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP)))
+#define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP)))
+#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP)))
+
+/* Overflow management */
+/*
+ * Overflow page numbers are allocated per split point. At each doubling of
+ * the table, we can allocate extra pages. So, an overflow page number has
+ * the top 5 bits indicate which split point and the lower 11 bits indicate
+ * which page at that split point is indicated (pages within split points are
+ * numberered starting with 1).
+ */
+
+#define SPLITSHIFT 11
+#define SPLITMASK 0x7FF
+#define SPLITNUM(N) (((u_int32_t)(N)) >> SPLITSHIFT)
+#define OPAGENUM(N) ((N) & SPLITMASK)
+#define OADDR_OF(S,O) ((u_int32_t)((u_int32_t)(S) << SPLITSHIFT) + (O))
+
+#define BUCKET_TO_PAGE(B) \
+ (B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__log2((B)+1)-1] : 0)
+#define OADDR_TO_PAGE(B) \
+ BUCKET_TO_PAGE ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B));
+
+/*
+ * page.h contains a detailed description of the page format.
+ *
+ * Normally, keys and data are accessed from offset tables in the top of
+ * each page which point to the beginning of the key and data. There are
+ * four flag values which may be stored in these offset tables which indicate
+ * the following:
+ *
+ *
+ * OVFLPAGE Rather than a key data pair, this pair contains
+ * the address of an overflow page. The format of
+ * the pair is:
+ * OVERFLOW_PAGE_NUMBER OVFLPAGE
+ *
+ * PARTIAL_KEY This must be the first key/data pair on a page
+ * and implies that page contains only a partial key.
+ * That is, the key is too big to fit on a single page
+ * so it starts on this page and continues on the next.
+ * The format of the page is:
+ * KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE
+ *
+ * KEY_OFF -- offset of the beginning of the key
+ * PARTIAL_KEY -- 1
+ * OVFL_PAGENO - page number of the next overflow page
+ * OVFLPAGE -- 0
+ *
+ * FULL_KEY This must be the first key/data pair on the page. It
+ * is used in two cases.
+ *
+ * Case 1:
+ * There is a complete key on the page but no data
+ * (because it wouldn't fit). The next page contains
+ * the data.
+ *
+ * Page format it:
+ * KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
+ *
+ * KEY_OFF -- offset of the beginning of the key
+ * FULL_KEY -- 2
+ * OVFL_PAGENO - page number of the next overflow page
+ * OVFLPAGE -- 0
+ *
+ * Case 2:
+ * This page contains no key, but part of a large
+ * data field, which is continued on the next page.
+ *
+ * Page format it:
+ * DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
+ *
+ * KEY_OFF -- offset of the beginning of the data on
+ * this page
+ * FULL_KEY -- 2
+ * OVFL_PAGENO - page number of the next overflow page
+ * OVFLPAGE -- 0
+ *
+ * FULL_KEY_DATA
+ * This must be the first key/data pair on the page.
+ * There are two cases:
+ *
+ * Case 1:
+ * This page contains a key and the beginning of the
+ * data field, but the data field is continued on the
+ * next page.
+ *
+ * Page format is:
+ * KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF
+ *
+ * KEY_OFF -- offset of the beginning of the key
+ * FULL_KEY_DATA -- 3
+ * OVFL_PAGENO - page number of the next overflow page
+ * DATA_OFF -- offset of the beginning of the data
+ *
+ * Case 2:
+ * This page contains the last page of a big data pair.
+ * There is no key, only the tail end of the data
+ * on this page.
+ *
+ * Page format is:
+ * DATA_OFF FULL_KEY_DATA <OVFL_PAGENO> <OVFLPAGE>
+ *
+ * DATA_OFF -- offset of the beginning of the data on
+ * this page
+ * FULL_KEY_DATA -- 3
+ * OVFL_PAGENO - page number of the next overflow page
+ * OVFLPAGE -- 0
+ *
+ * OVFL_PAGENO and OVFLPAGE are optional (they are
+ * not present if there is no next page).
+ */
+
+#define OVFLPAGE 0
+#define PARTIAL_KEY 1
+#define FULL_KEY 2
+#define FULL_KEY_DATA 3
+#define REAL_KEY 4
+
+/* Short hands for accessing structure */
+#define BSIZE hdr.bsize
+#define BSHIFT hdr.bshift
+#define DSIZE hdr.dsize
+#define SGSIZE hdr.ssize
+#define SSHIFT hdr.sshift
+#define LORDER hdr.lorder
+#define OVFL_POINT hdr.ovfl_point
+#define LAST_FREED hdr.last_freed
+#define MAX_BUCKET hdr.max_bucket
+#define FFACTOR hdr.ffactor
+#define HIGH_MASK hdr.high_mask
+#define LOW_MASK hdr.low_mask
+#define NKEYS hdr.nkeys
+#define HDRPAGES hdr.hdrpages
+#define SPARES hdr.spares
+#define BITMAPS hdr.bitmaps
+#define VERSION hdr.version
+#define MAGIC hdr.magic
+#define NEXT_FREE hdr.next_free
+#define H_CHARKEY hdr.h_charkey
diff --git a/lib/libc/db/hash/hash_bigkey.c b/lib/libc/db/hash/hash_bigkey.c
new file mode 100644
index 0000000..0cee07e
--- /dev/null
+++ b/lib/libc/db/hash/hash_bigkey.c
@@ -0,0 +1,667 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * PACKAGE: hash
+ * DESCRIPTION:
+ * Big key/data handling for the hashing package.
+ *
+ * ROUTINES:
+ * External
+ * __big_keydata
+ * __big_split
+ * __big_insert
+ * __big_return
+ * __big_delete
+ * __find_last_page
+ * Internal
+ * collect_key
+ * collect_data
+ */
+
+#include <sys/param.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef DEBUG
+#include <assert.h>
+#endif
+
+#include <db.h>
+#include "hash.h"
+#include "page.h"
+#include "extern.h"
+
+static int collect_key __P((HTAB *, BUFHEAD *, int, DBT *, int));
+static int collect_data __P((HTAB *, BUFHEAD *, int, int));
+
+/*
+ * Big_insert
+ *
+ * You need to do an insert and the key/data pair is too big
+ *
+ * Returns:
+ * 0 ==> OK
+ *-1 ==> ERROR
+ */
+extern int
+__big_insert(hashp, bufp, key, val)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ const DBT *key, *val;
+{
+ register u_int16_t *p;
+ int key_size, n, val_size;
+ u_int16_t space, move_bytes, off;
+ char *cp, *key_data, *val_data;
+
+ cp = bufp->page; /* Character pointer of p. */
+ p = (u_int16_t *)cp;
+
+ key_data = (char *)key->data;
+ key_size = key->size;
+ val_data = (char *)val->data;
+ val_size = val->size;
+
+ /* First move the Key */
+ for (space = FREESPACE(p) - BIGOVERHEAD; key_size;
+ space = FREESPACE(p) - BIGOVERHEAD) {
+ move_bytes = MIN(space, key_size);
+ off = OFFSET(p) - move_bytes;
+ memmove(cp + off, key_data, move_bytes);
+ key_size -= move_bytes;
+ key_data += move_bytes;
+ n = p[0];
+ p[++n] = off;
+ p[0] = ++n;
+ FREESPACE(p) = off - PAGE_META(n);
+ OFFSET(p) = off;
+ p[n] = PARTIAL_KEY;
+ bufp = __add_ovflpage(hashp, bufp);
+ if (!bufp)
+ return (-1);
+ n = p[0];
+ if (!key_size)
+ if (FREESPACE(p)) {
+ move_bytes = MIN(FREESPACE(p), val_size);
+ off = OFFSET(p) - move_bytes;
+ p[n] = off;
+ memmove(cp + off, val_data, move_bytes);
+ val_data += move_bytes;
+ val_size -= move_bytes;
+ p[n - 2] = FULL_KEY_DATA;
+ FREESPACE(p) = FREESPACE(p) - move_bytes;
+ OFFSET(p) = off;
+ } else
+ p[n - 2] = FULL_KEY;
+ p = (u_int16_t *)bufp->page;
+ cp = bufp->page;
+ bufp->flags |= BUF_MOD;
+ }
+
+ /* Now move the data */
+ for (space = FREESPACE(p) - BIGOVERHEAD; val_size;
+ space = FREESPACE(p) - BIGOVERHEAD) {
+ move_bytes = MIN(space, val_size);
+ /*
+ * Here's the hack to make sure that if the data ends on the
+ * same page as the key ends, FREESPACE is at least one.
+ */
+ if (space == val_size && val_size == val->size)
+ move_bytes--;
+ off = OFFSET(p) - move_bytes;
+ memmove(cp + off, val_data, move_bytes);
+ val_size -= move_bytes;
+ val_data += move_bytes;
+ n = p[0];
+ p[++n] = off;
+ p[0] = ++n;
+ FREESPACE(p) = off - PAGE_META(n);
+ OFFSET(p) = off;
+ if (val_size) {
+ p[n] = FULL_KEY;
+ bufp = __add_ovflpage(hashp, bufp);
+ if (!bufp)
+ return (-1);
+ cp = bufp->page;
+ p = (u_int16_t *)cp;
+ } else
+ p[n] = FULL_KEY_DATA;
+ bufp->flags |= BUF_MOD;
+ }
+ return (0);
+}
+
+/*
+ * Called when bufp's page contains a partial key (index should be 1)
+ *
+ * All pages in the big key/data pair except bufp are freed. We cannot
+ * free bufp because the page pointing to it is lost and we can't get rid
+ * of its pointer.
+ *
+ * Returns:
+ * 0 => OK
+ *-1 => ERROR
+ */
+extern int
+__big_delete(hashp, bufp)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+{
+ register BUFHEAD *last_bfp, *rbufp;
+ u_int16_t *bp, pageno;
+ int key_done, n;
+
+ rbufp = bufp;
+ last_bfp = NULL;
+ bp = (u_int16_t *)bufp->page;
+ pageno = 0;
+ key_done = 0;
+
+ while (!key_done || (bp[2] != FULL_KEY_DATA)) {
+ if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA)
+ key_done = 1;
+
+ /*
+ * If there is freespace left on a FULL_KEY_DATA page, then
+ * the data is short and fits entirely on this page, and this
+ * is the last page.
+ */
+ if (bp[2] == FULL_KEY_DATA && FREESPACE(bp))
+ break;
+ pageno = bp[bp[0] - 1];
+ rbufp->flags |= BUF_MOD;
+ rbufp = __get_buf(hashp, pageno, rbufp, 0);
+ if (last_bfp)
+ __free_ovflpage(hashp, last_bfp);
+ last_bfp = rbufp;
+ if (!rbufp)
+ return (-1); /* Error. */
+ bp = (u_int16_t *)rbufp->page;
+ }
+
+ /*
+ * If we get here then rbufp points to the last page of the big
+ * key/data pair. Bufp points to the first one -- it should now be
+ * empty pointing to the next page after this pair. Can't free it
+ * because we don't have the page pointing to it.
+ */
+
+ /* This is information from the last page of the pair. */
+ n = bp[0];
+ pageno = bp[n - 1];
+
+ /* Now, bp is the first page of the pair. */
+ bp = (u_int16_t *)bufp->page;
+ if (n > 2) {
+ /* There is an overflow page. */
+ bp[1] = pageno;
+ bp[2] = OVFLPAGE;
+ bufp->ovfl = rbufp->ovfl;
+ } else
+ /* This is the last page. */
+ bufp->ovfl = NULL;
+ n -= 2;
+ bp[0] = n;
+ FREESPACE(bp) = hashp->BSIZE - PAGE_META(n);
+ OFFSET(bp) = hashp->BSIZE - 1;
+
+ bufp->flags |= BUF_MOD;
+ if (rbufp)
+ __free_ovflpage(hashp, rbufp);
+ if (last_bfp != rbufp)
+ __free_ovflpage(hashp, last_bfp);
+
+ hashp->NKEYS--;
+ return (0);
+}
+/*
+ * Returns:
+ * 0 = key not found
+ * -1 = get next overflow page
+ * -2 means key not found and this is big key/data
+ * -3 error
+ */
+extern int
+__find_bigpair(hashp, bufp, ndx, key, size)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ int ndx;
+ char *key;
+ int size;
+{
+ register u_int16_t *bp;
+ register char *p;
+ int ksize;
+ u_int16_t bytes;
+ char *kkey;
+
+ bp = (u_int16_t *)bufp->page;
+ p = bufp->page;
+ ksize = size;
+ kkey = key;
+
+ for (bytes = hashp->BSIZE - bp[ndx];
+ bytes <= size && bp[ndx + 1] == PARTIAL_KEY;
+ bytes = hashp->BSIZE - bp[ndx]) {
+ if (memcmp(p + bp[ndx], kkey, bytes))
+ return (-2);
+ kkey += bytes;
+ ksize -= bytes;
+ bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0);
+ if (!bufp)
+ return (-3);
+ p = bufp->page;
+ bp = (u_int16_t *)p;
+ ndx = 1;
+ }
+
+ if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) {
+#ifdef HASH_STATISTICS
+ ++hash_collisions;
+#endif
+ return (-2);
+ } else
+ return (ndx);
+}
+
+/*
+ * Given the buffer pointer of the first overflow page of a big pair,
+ * find the end of the big pair
+ *
+ * This will set bpp to the buffer header of the last page of the big pair.
+ * It will return the pageno of the overflow page following the last page
+ * of the pair; 0 if there isn't any (i.e. big pair is the last key in the
+ * bucket)
+ */
+extern u_int16_t
+__find_last_page(hashp, bpp)
+ HTAB *hashp;
+ BUFHEAD **bpp;
+{
+ BUFHEAD *bufp;
+ u_int16_t *bp, pageno;
+ int n;
+
+ bufp = *bpp;
+ bp = (u_int16_t *)bufp->page;
+ for (;;) {
+ n = bp[0];
+
+ /*
+ * This is the last page if: the tag is FULL_KEY_DATA and
+ * either only 2 entries OVFLPAGE marker is explicit there
+ * is freespace on the page.
+ */
+ if (bp[2] == FULL_KEY_DATA &&
+ ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp))))
+ break;
+
+ pageno = bp[n - 1];
+ bufp = __get_buf(hashp, pageno, bufp, 0);
+ if (!bufp)
+ return (0); /* Need to indicate an error! */
+ bp = (u_int16_t *)bufp->page;
+ }
+
+ *bpp = bufp;
+ if (bp[0] > 2)
+ return (bp[3]);
+ else
+ return (0);
+}
+
+/*
+ * Return the data for the key/data pair that begins on this page at this
+ * index (index should always be 1).
+ */
+extern int
+__big_return(hashp, bufp, ndx, val, set_current)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ int ndx;
+ DBT *val;
+ int set_current;
+{
+ BUFHEAD *save_p;
+ u_int16_t *bp, len, off, save_addr;
+ char *tp;
+
+ bp = (u_int16_t *)bufp->page;
+ while (bp[ndx + 1] == PARTIAL_KEY) {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (u_int16_t *)bufp->page;
+ ndx = 1;
+ }
+
+ if (bp[ndx + 1] == FULL_KEY) {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (u_int16_t *)bufp->page;
+ save_p = bufp;
+ save_addr = save_p->addr;
+ off = bp[1];
+ len = 0;
+ } else
+ if (!FREESPACE(bp)) {
+ /*
+ * This is a hack. We can't distinguish between
+ * FULL_KEY_DATA that contains complete data or
+ * incomplete data, so we require that if the data
+ * is complete, there is at least 1 byte of free
+ * space left.
+ */
+ off = bp[bp[0]];
+ len = bp[1] - off;
+ save_p = bufp;
+ save_addr = bufp->addr;
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (u_int16_t *)bufp->page;
+ } else {
+ /* The data is all on one page. */
+ tp = (char *)bp;
+ off = bp[bp[0]];
+ val->data = (u_char *)tp + off;
+ val->size = bp[1] - off;
+ if (set_current) {
+ if (bp[0] == 2) { /* No more buckets in
+ * chain */
+ hashp->cpage = NULL;
+ hashp->cbucket++;
+ hashp->cndx = 1;
+ } else {
+ hashp->cpage = __get_buf(hashp,
+ bp[bp[0] - 1], bufp, 0);
+ if (!hashp->cpage)
+ return (-1);
+ hashp->cndx = 1;
+ if (!((u_int16_t *)
+ hashp->cpage->page)[0]) {
+ hashp->cbucket++;
+ hashp->cpage = NULL;
+ }
+ }
+ }
+ return (0);
+ }
+
+ val->size = collect_data(hashp, bufp, (int)len, set_current);
+ if (val->size == -1)
+ return (-1);
+ if (save_p->addr != save_addr) {
+ /* We are pretty short on buffers. */
+ errno = EINVAL; /* OUT OF BUFFERS */
+ return (-1);
+ }
+ memmove(hashp->tmp_buf, (save_p->page) + off, len);
+ val->data = (u_char *)hashp->tmp_buf;
+ return (0);
+}
+/*
+ * Count how big the total datasize is by recursing through the pages. Then
+ * allocate a buffer and copy the data as you recurse up.
+ */
+static int
+collect_data(hashp, bufp, len, set)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ int len, set;
+{
+ register u_int16_t *bp;
+ register char *p;
+ BUFHEAD *xbp;
+ u_int16_t save_addr;
+ int mylen, totlen;
+
+ p = bufp->page;
+ bp = (u_int16_t *)p;
+ mylen = hashp->BSIZE - bp[1];
+ save_addr = bufp->addr;
+
+ if (bp[2] == FULL_KEY_DATA) { /* End of Data */
+ totlen = len + mylen;
+ if (hashp->tmp_buf)
+ free(hashp->tmp_buf);
+ if ((hashp->tmp_buf = (char *)malloc(totlen)) == NULL)
+ return (-1);
+ if (set) {
+ hashp->cndx = 1;
+ if (bp[0] == 2) { /* No more buckets in chain */
+ hashp->cpage = NULL;
+ hashp->cbucket++;
+ } else {
+ hashp->cpage =
+ __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!hashp->cpage)
+ return (-1);
+ else if (!((u_int16_t *)hashp->cpage->page)[0]) {
+ hashp->cbucket++;
+ hashp->cpage = NULL;
+ }
+ }
+ }
+ } else {
+ xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!xbp || ((totlen =
+ collect_data(hashp, xbp, len + mylen, set)) < 1))
+ return (-1);
+ }
+ if (bufp->addr != save_addr) {
+ errno = EINVAL; /* Out of buffers. */
+ return (-1);
+ }
+ memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], mylen);
+ return (totlen);
+}
+
+/*
+ * Fill in the key and data for this big pair.
+ */
+extern int
+__big_keydata(hashp, bufp, key, val, set)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ DBT *key, *val;
+ int set;
+{
+ key->size = collect_key(hashp, bufp, 0, val, set);
+ if (key->size == -1)
+ return (-1);
+ key->data = (u_char *)hashp->tmp_key;
+ return (0);
+}
+
+/*
+ * Count how big the total key size is by recursing through the pages. Then
+ * collect the data, allocate a buffer and copy the key as you recurse up.
+ */
+static int
+collect_key(hashp, bufp, len, val, set)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ int len;
+ DBT *val;
+ int set;
+{
+ BUFHEAD *xbp;
+ char *p;
+ int mylen, totlen;
+ u_int16_t *bp, save_addr;
+
+ p = bufp->page;
+ bp = (u_int16_t *)p;
+ mylen = hashp->BSIZE - bp[1];
+
+ save_addr = bufp->addr;
+ totlen = len + mylen;
+ if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */
+ if (hashp->tmp_key != NULL)
+ free(hashp->tmp_key);
+ if ((hashp->tmp_key = (char *)malloc(totlen)) == NULL)
+ return (-1);
+ if (__big_return(hashp, bufp, 1, val, set))
+ return (-1);
+ } else {
+ xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!xbp || ((totlen =
+ collect_key(hashp, xbp, totlen, val, set)) < 1))
+ return (-1);
+ }
+ if (bufp->addr != save_addr) {
+ errno = EINVAL; /* MIS -- OUT OF BUFFERS */
+ return (-1);
+ }
+ memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], mylen);
+ return (totlen);
+}
+
+/*
+ * Returns:
+ * 0 => OK
+ * -1 => error
+ */
+extern int
+__big_split(hashp, op, np, big_keyp, addr, obucket, ret)
+ HTAB *hashp;
+ BUFHEAD *op; /* Pointer to where to put keys that go in old bucket */
+ BUFHEAD *np; /* Pointer to new bucket page */
+ /* Pointer to first page containing the big key/data */
+ BUFHEAD *big_keyp;
+ int addr; /* Address of big_keyp */
+ u_int32_t obucket;/* Old Bucket */
+ SPLIT_RETURN *ret;
+{
+ register BUFHEAD *tmpp;
+ register u_int16_t *tp;
+ BUFHEAD *bp;
+ DBT key, val;
+ u_int32_t change;
+ u_int16_t free_space, n, off;
+
+ bp = big_keyp;
+
+ /* Now figure out where the big key/data goes */
+ if (__big_keydata(hashp, big_keyp, &key, &val, 0))
+ return (-1);
+ change = (__call_hash(hashp, key.data, key.size) != obucket);
+
+ if ( (ret->next_addr = __find_last_page(hashp, &big_keyp)) ) {
+ if (!(ret->nextp =
+ __get_buf(hashp, ret->next_addr, big_keyp, 0)))
+ return (-1);;
+ } else
+ ret->nextp = NULL;
+
+ /* Now make one of np/op point to the big key/data pair */
+#ifdef DEBUG
+ assert(np->ovfl == NULL);
+#endif
+ if (change)
+ tmpp = np;
+ else
+ tmpp = op;
+
+ tmpp->flags |= BUF_MOD;
+#ifdef DEBUG1
+ (void)fprintf(stderr,
+ "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr,
+ (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0));
+#endif
+ tmpp->ovfl = bp; /* one of op/np point to big_keyp */
+ tp = (u_int16_t *)tmpp->page;
+#ifdef DEBUG
+ assert(FREESPACE(tp) >= OVFLSIZE);
+#endif
+ n = tp[0];
+ off = OFFSET(tp);
+ free_space = FREESPACE(tp);
+ tp[++n] = (u_int16_t)addr;
+ tp[++n] = OVFLPAGE;
+ tp[0] = n;
+ OFFSET(tp) = off;
+ FREESPACE(tp) = free_space - OVFLSIZE;
+
+ /*
+ * Finally, set the new and old return values. BIG_KEYP contains a
+ * pointer to the last page of the big key_data pair. Make sure that
+ * big_keyp has no following page (2 elements) or create an empty
+ * following page.
+ */
+
+ ret->newp = np;
+ ret->oldp = op;
+
+ tp = (u_int16_t *)big_keyp->page;
+ big_keyp->flags |= BUF_MOD;
+ if (tp[0] > 2) {
+ /*
+ * There may be either one or two offsets on this page. If
+ * there is one, then the overflow page is linked on normally
+ * and tp[4] is OVFLPAGE. If there are two, tp[4] contains
+ * the second offset and needs to get stuffed in after the
+ * next overflow page is added.
+ */
+ n = tp[4];
+ free_space = FREESPACE(tp);
+ off = OFFSET(tp);
+ tp[0] -= 2;
+ FREESPACE(tp) = free_space + OVFLSIZE;
+ OFFSET(tp) = off;
+ tmpp = __add_ovflpage(hashp, big_keyp);
+ if (!tmpp)
+ return (-1);
+ tp[4] = n;
+ } else
+ tmpp = big_keyp;
+
+ if (change)
+ ret->newp = tmpp;
+ else
+ ret->oldp = tmpp;
+ return (0);
+}
diff --git a/lib/libc/db/hash/hash_buf.c b/lib/libc/db/hash/hash_buf.c
new file mode 100644
index 0000000..92e1f93
--- /dev/null
+++ b/lib/libc/db/hash/hash_buf.c
@@ -0,0 +1,355 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * PACKAGE: hash
+ *
+ * DESCRIPTION:
+ * Contains buffer management
+ *
+ * ROUTINES:
+ * External
+ * __buf_init
+ * __get_buf
+ * __buf_free
+ * __reclaim_buf
+ * Internal
+ * newbuf
+ */
+
+#include <sys/param.h>
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef DEBUG
+#include <assert.h>
+#endif
+
+#include <db.h>
+#include "hash.h"
+#include "page.h"
+#include "extern.h"
+
+static BUFHEAD *newbuf __P((HTAB *, u_int32_t, BUFHEAD *));
+
+/* Unlink B from its place in the lru */
+#define BUF_REMOVE(B) { \
+ (B)->prev->next = (B)->next; \
+ (B)->next->prev = (B)->prev; \
+}
+
+/* Insert B after P */
+#define BUF_INSERT(B, P) { \
+ (B)->next = (P)->next; \
+ (B)->prev = (P); \
+ (P)->next = (B); \
+ (B)->next->prev = (B); \
+}
+
+#define MRU hashp->bufhead.next
+#define LRU hashp->bufhead.prev
+
+#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufhead)
+#define LRU_INSERT(B) BUF_INSERT((B), LRU)
+
+/*
+ * We are looking for a buffer with address "addr". If prev_bp is NULL, then
+ * address is a bucket index. If prev_bp is not NULL, then it points to the
+ * page previous to an overflow page that we are trying to find.
+ *
+ * CAVEAT: The buffer header accessed via prev_bp's ovfl field may no longer
+ * be valid. Therefore, you must always verify that its address matches the
+ * address you are seeking.
+ */
+extern BUFHEAD *
+__get_buf(hashp, addr, prev_bp, newpage)
+ HTAB *hashp;
+ u_int32_t addr;
+ BUFHEAD *prev_bp;
+ int newpage; /* If prev_bp set, indicates a new overflow page. */
+{
+ register BUFHEAD *bp;
+ register u_int32_t is_disk_mask;
+ register int is_disk, segment_ndx;
+ SEGMENT segp;
+
+ is_disk = 0;
+ is_disk_mask = 0;
+ if (prev_bp) {
+ bp = prev_bp->ovfl;
+ if (!bp || (bp->addr != addr))
+ bp = NULL;
+ if (!newpage)
+ is_disk = BUF_DISK;
+ } else {
+ /* Grab buffer out of directory */
+ segment_ndx = addr & (hashp->SGSIZE - 1);
+
+ /* valid segment ensured by __call_hash() */
+ segp = hashp->dir[addr >> hashp->SSHIFT];
+#ifdef DEBUG
+ assert(segp != NULL);
+#endif
+ bp = PTROF(segp[segment_ndx]);
+ is_disk_mask = ISDISK(segp[segment_ndx]);
+ is_disk = is_disk_mask || !hashp->new_file;
+ }
+
+ if (!bp) {
+ bp = newbuf(hashp, addr, prev_bp);
+ if (!bp ||
+ __get_page(hashp, bp->page, addr, !prev_bp, is_disk, 0))
+ return (NULL);
+ if (!prev_bp)
+ segp[segment_ndx] =
+ (BUFHEAD *)((ptrdiff_t)bp | is_disk_mask);
+ } else {
+ BUF_REMOVE(bp);
+ MRU_INSERT(bp);
+ }
+ return (bp);
+}
+
+/*
+ * We need a buffer for this page. Either allocate one, or evict a resident
+ * one (if we have as many buffers as we're allowed) and put this one in.
+ *
+ * If newbuf finds an error (returning NULL), it also sets errno.
+ */
+static BUFHEAD *
+newbuf(hashp, addr, prev_bp)
+ HTAB *hashp;
+ u_int32_t addr;
+ BUFHEAD *prev_bp;
+{
+ register BUFHEAD *bp; /* The buffer we're going to use */
+ register BUFHEAD *xbp; /* Temp pointer */
+ register BUFHEAD *next_xbp;
+ SEGMENT segp;
+ int segment_ndx;
+ u_int16_t oaddr, *shortp;
+
+ oaddr = 0;
+ bp = LRU;
+ /*
+ * If LRU buffer is pinned, the buffer pool is too small. We need to
+ * allocate more buffers.
+ */
+ if (hashp->nbufs || (bp->flags & BUF_PIN)) {
+ /* Allocate a new one */
+ if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL)
+ return (NULL);
+#ifdef PURIFY
+ memset(bp, 0xff, sizeof(BUFHEAD));
+#endif
+ if ((bp->page = (char *)malloc(hashp->BSIZE)) == NULL) {
+ free(bp);
+ return (NULL);
+ }
+#ifdef PURIFY
+ memset(bp->page, 0xff, hashp->BSIZE);
+#endif
+ if (hashp->nbufs)
+ hashp->nbufs--;
+ } else {
+ /* Kick someone out */
+ BUF_REMOVE(bp);
+ /*
+ * If this is an overflow page with addr 0, it's already been
+ * flushed back in an overflow chain and initialized.
+ */
+ if ((bp->addr != 0) || (bp->flags & BUF_BUCKET)) {
+ /*
+ * Set oaddr before __put_page so that you get it
+ * before bytes are swapped.
+ */
+ shortp = (u_int16_t *)bp->page;
+ if (shortp[0])
+ oaddr = shortp[shortp[0] - 1];
+ if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page,
+ bp->addr, (int)IS_BUCKET(bp->flags), 0))
+ return (NULL);
+ /*
+ * Update the pointer to this page (i.e. invalidate it).
+ *
+ * If this is a new file (i.e. we created it at open
+ * time), make sure that we mark pages which have been
+ * written to disk so we retrieve them from disk later,
+ * rather than allocating new pages.
+ */
+ if (IS_BUCKET(bp->flags)) {
+ segment_ndx = bp->addr & (hashp->SGSIZE - 1);
+ segp = hashp->dir[bp->addr >> hashp->SSHIFT];
+#ifdef DEBUG
+ assert(segp != NULL);
+#endif
+
+ if (hashp->new_file &&
+ ((bp->flags & BUF_MOD) ||
+ ISDISK(segp[segment_ndx])))
+ segp[segment_ndx] = (BUFHEAD *)BUF_DISK;
+ else
+ segp[segment_ndx] = NULL;
+ }
+ /*
+ * Since overflow pages can only be access by means of
+ * their bucket, free overflow pages associated with
+ * this bucket.
+ */
+ for (xbp = bp; xbp->ovfl;) {
+ next_xbp = xbp->ovfl;
+ xbp->ovfl = 0;
+ xbp = next_xbp;
+
+ /* Check that ovfl pointer is up date. */
+ if (IS_BUCKET(xbp->flags) ||
+ (oaddr != xbp->addr))
+ break;
+
+ shortp = (u_int16_t *)xbp->page;
+ if (shortp[0])
+ /* set before __put_page */
+ oaddr = shortp[shortp[0] - 1];
+ if ((xbp->flags & BUF_MOD) && __put_page(hashp,
+ xbp->page, xbp->addr, 0, 0))
+ return (NULL);
+ xbp->addr = 0;
+ xbp->flags = 0;
+ BUF_REMOVE(xbp);
+ LRU_INSERT(xbp);
+ }
+ }
+ }
+
+ /* Now assign this buffer */
+ bp->addr = addr;
+#ifdef DEBUG1
+ (void)fprintf(stderr, "NEWBUF1: %d->ovfl was %d is now %d\n",
+ bp->addr, (bp->ovfl ? bp->ovfl->addr : 0), 0);
+#endif
+ bp->ovfl = NULL;
+ if (prev_bp) {
+ /*
+ * If prev_bp is set, this is an overflow page, hook it in to
+ * the buffer overflow links.
+ */
+#ifdef DEBUG1
+ (void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n",
+ prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0),
+ (bp ? bp->addr : 0));
+#endif
+ prev_bp->ovfl = bp;
+ bp->flags = 0;
+ } else
+ bp->flags = BUF_BUCKET;
+ MRU_INSERT(bp);
+ return (bp);
+}
+
+extern void
+__buf_init(hashp, nbytes)
+ HTAB *hashp;
+ int nbytes;
+{
+ BUFHEAD *bfp;
+ int npages;
+
+ bfp = &(hashp->bufhead);
+ npages = (nbytes + hashp->BSIZE - 1) >> hashp->BSHIFT;
+ npages = MAX(npages, MIN_BUFFERS);
+
+ hashp->nbufs = npages;
+ bfp->next = bfp;
+ bfp->prev = bfp;
+ /*
+ * This space is calloc'd so these are already null.
+ *
+ * bfp->ovfl = NULL;
+ * bfp->flags = 0;
+ * bfp->page = NULL;
+ * bfp->addr = 0;
+ */
+}
+
+extern int
+__buf_free(hashp, do_free, to_disk)
+ HTAB *hashp;
+ int do_free, to_disk;
+{
+ BUFHEAD *bp;
+
+ /* Need to make sure that buffer manager has been initialized */
+ if (!LRU)
+ return (0);
+ for (bp = LRU; bp != &hashp->bufhead;) {
+ /* Check that the buffer is valid */
+ if (bp->addr || IS_BUCKET(bp->flags)) {
+ if (to_disk && (bp->flags & BUF_MOD) &&
+ __put_page(hashp, bp->page,
+ bp->addr, IS_BUCKET(bp->flags), 0))
+ return (-1);
+ }
+ /* Check if we are freeing stuff */
+ if (do_free) {
+ if (bp->page)
+ free(bp->page);
+ BUF_REMOVE(bp);
+ free(bp);
+ bp = LRU;
+ } else
+ bp = bp->prev;
+ }
+ return (0);
+}
+
+extern void
+__reclaim_buf(hashp, bp)
+ HTAB *hashp;
+ BUFHEAD *bp;
+{
+ bp->ovfl = 0;
+ bp->addr = 0;
+ bp->flags = 0;
+ BUF_REMOVE(bp);
+ LRU_INSERT(bp);
+}
diff --git a/lib/libc/db/hash/hash_func.c b/lib/libc/db/hash/hash_func.c
new file mode 100644
index 0000000..a5ec434
--- /dev/null
+++ b/lib/libc/db/hash/hash_func.c
@@ -0,0 +1,212 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <db.h>
+#include "hash.h"
+#include "page.h"
+#include "extern.h"
+
+static u_int32_t hash1 __P((const void *, size_t));
+static u_int32_t hash2 __P((const void *, size_t));
+static u_int32_t hash3 __P((const void *, size_t));
+static u_int32_t hash4 __P((const void *, size_t));
+
+/* Global default hash function */
+u_int32_t (*__default_hash) __P((const void *, size_t)) = hash4;
+
+/*
+ * HASH FUNCTIONS
+ *
+ * Assume that we've already split the bucket to which this key hashes,
+ * calculate that bucket, and check that in fact we did already split it.
+ *
+ * This came from ejb's hsearch.
+ */
+
+#define PRIME1 37
+#define PRIME2 1048583
+
+static u_int32_t
+hash1(keyarg, len)
+ const void *keyarg;
+ register size_t len;
+{
+ register const u_char *key;
+ register u_int32_t h;
+
+ /* Convert string to integer */
+ for (key = keyarg, h = 0; len--;)
+ h = h * PRIME1 ^ (*key++ - ' ');
+ h %= PRIME2;
+ return (h);
+}
+
+/*
+ * Phong's linear congruential hash
+ */
+#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
+
+static u_int32_t
+hash2(keyarg, len)
+ const void *keyarg;
+ size_t len;
+{
+ register const u_char *e, *key;
+ register u_int32_t h;
+ register u_char c;
+
+ key = keyarg;
+ e = key + len;
+ for (h = 0; key != e;) {
+ c = *key++;
+ if (!c && key > e)
+ break;
+ dcharhash(h, c);
+ }
+ return (h);
+}
+
+/*
+ * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte
+ * units. On the first time through the loop we get the "leftover bytes"
+ * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle
+ * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If
+ * this routine is heavily used enough, it's worth the ugly coding.
+ *
+ * OZ's original sdbm hash
+ */
+static u_int32_t
+hash3(keyarg, len)
+ const void *keyarg;
+ register size_t len;
+{
+ register const u_char *key;
+ register size_t loop;
+ register u_int32_t h;
+
+#define HASHC h = *key++ + 65599 * h
+
+ h = 0;
+ key = keyarg;
+ if (len > 0) {
+ loop = (len + 8 - 1) >> 3;
+
+ switch (len & (8 - 1)) {
+ case 0:
+ do {
+ HASHC;
+ /* FALLTHROUGH */
+ case 7:
+ HASHC;
+ /* FALLTHROUGH */
+ case 6:
+ HASHC;
+ /* FALLTHROUGH */
+ case 5:
+ HASHC;
+ /* FALLTHROUGH */
+ case 4:
+ HASHC;
+ /* FALLTHROUGH */
+ case 3:
+ HASHC;
+ /* FALLTHROUGH */
+ case 2:
+ HASHC;
+ /* FALLTHROUGH */
+ case 1:
+ HASHC;
+ } while (--loop);
+ }
+ }
+ return (h);
+}
+
+/* Hash function from Chris Torek. */
+static u_int32_t
+hash4(keyarg, len)
+ const void *keyarg;
+ register size_t len;
+{
+ register const u_char *key;
+ register size_t loop;
+ register u_int32_t h;
+
+#define HASH4a h = (h << 5) - h + *key++;
+#define HASH4b h = (h << 5) + h + *key++;
+#define HASH4 HASH4b
+
+ h = 0;
+ key = keyarg;
+ if (len > 0) {
+ loop = (len + 8 - 1) >> 3;
+
+ switch (len & (8 - 1)) {
+ case 0:
+ do {
+ HASH4;
+ /* FALLTHROUGH */
+ case 7:
+ HASH4;
+ /* FALLTHROUGH */
+ case 6:
+ HASH4;
+ /* FALLTHROUGH */
+ case 5:
+ HASH4;
+ /* FALLTHROUGH */
+ case 4:
+ HASH4;
+ /* FALLTHROUGH */
+ case 3:
+ HASH4;
+ /* FALLTHROUGH */
+ case 2:
+ HASH4;
+ /* FALLTHROUGH */
+ case 1:
+ HASH4;
+ } while (--loop);
+ }
+ }
+ return (h);
+}
diff --git a/lib/libc/db/hash/hash_log2.c b/lib/libc/db/hash/hash_log2.c
new file mode 100644
index 0000000..c8c56bf
--- /dev/null
+++ b/lib/libc/db/hash/hash_log2.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <db.h>
+
+u_int32_t
+__log2(num)
+ u_int32_t num;
+{
+ register u_int32_t i, limit;
+
+ limit = 1;
+ for (i = 0; limit < num; limit = limit << 1, i++);
+ return (i);
+}
diff --git a/lib/libc/db/hash/hash_page.c b/lib/libc/db/hash/hash_page.c
new file mode 100644
index 0000000..2c05090
--- /dev/null
+++ b/lib/libc/db/hash/hash_page.c
@@ -0,0 +1,944 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * PACKAGE: hashing
+ *
+ * DESCRIPTION:
+ * Page manipulation for hashing package.
+ *
+ * ROUTINES:
+ *
+ * External
+ * __get_page
+ * __add_ovflpage
+ * Internal
+ * overflow_page
+ * open_temp
+ */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef DEBUG
+#include <assert.h>
+#endif
+
+#include <db.h>
+#include "hash.h"
+#include "page.h"
+#include "extern.h"
+
+static u_int32_t *fetch_bitmap __P((HTAB *, int));
+static u_int32_t first_free __P((u_int32_t));
+static int open_temp __P((HTAB *));
+static u_int16_t overflow_page __P((HTAB *));
+static void putpair __P((char *, const DBT *, const DBT *));
+static void squeeze_key __P((u_int16_t *, const DBT *, const DBT *));
+static int ugly_split
+ __P((HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int));
+
+#define PAGE_INIT(P) { \
+ ((u_int16_t *)(P))[0] = 0; \
+ ((u_int16_t *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_int16_t); \
+ ((u_int16_t *)(P))[2] = hashp->BSIZE; \
+}
+
+/*
+ * This is called AFTER we have verified that there is room on the page for
+ * the pair (PAIRFITS has returned true) so we go right ahead and start moving
+ * stuff on.
+ */
+static void
+putpair(p, key, val)
+ char *p;
+ const DBT *key, *val;
+{
+ register u_int16_t *bp, n, off;
+
+ bp = (u_int16_t *)p;
+
+ /* Enter the key first. */
+ n = bp[0];
+
+ off = OFFSET(bp) - key->size;
+ memmove(p + off, key->data, key->size);
+ bp[++n] = off;
+
+ /* Now the data. */
+ off -= val->size;
+ memmove(p + off, val->data, val->size);
+ bp[++n] = off;
+
+ /* Adjust page info. */
+ bp[0] = n;
+ bp[n + 1] = off - ((n + 3) * sizeof(u_int16_t));
+ bp[n + 2] = off;
+}
+
+/*
+ * Returns:
+ * 0 OK
+ * -1 error
+ */
+extern int
+__delpair(hashp, bufp, ndx)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ register int ndx;
+{
+ register u_int16_t *bp, newoff;
+ register int n;
+ u_int16_t pairlen;
+
+ bp = (u_int16_t *)bufp->page;
+ n = bp[0];
+
+ if (bp[ndx + 1] < REAL_KEY)
+ return (__big_delete(hashp, bufp));
+ if (ndx != 1)
+ newoff = bp[ndx - 1];
+ else
+ newoff = hashp->BSIZE;
+ pairlen = newoff - bp[ndx + 1];
+
+ if (ndx != (n - 1)) {
+ /* Hard Case -- need to shuffle keys */
+ register int i;
+ register char *src = bufp->page + (int)OFFSET(bp);
+ register char *dst = src + (int)pairlen;
+ memmove(dst, src, bp[ndx + 1] - OFFSET(bp));
+
+ /* Now adjust the pointers */
+ for (i = ndx + 2; i <= n; i += 2) {
+ if (bp[i + 1] == OVFLPAGE) {
+ bp[i - 2] = bp[i];
+ bp[i - 1] = bp[i + 1];
+ } else {
+ bp[i - 2] = bp[i] + pairlen;
+ bp[i - 1] = bp[i + 1] + pairlen;
+ }
+ }
+ }
+ /* Finally adjust the page data */
+ bp[n] = OFFSET(bp) + pairlen;
+ bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_int16_t);
+ bp[0] = n - 2;
+ hashp->NKEYS--;
+
+ bufp->flags |= BUF_MOD;
+ return (0);
+}
+/*
+ * Returns:
+ * 0 ==> OK
+ * -1 ==> Error
+ */
+extern int
+__split_page(hashp, obucket, nbucket)
+ HTAB *hashp;
+ u_int32_t obucket, nbucket;
+{
+ register BUFHEAD *new_bufp, *old_bufp;
+ register u_int16_t *ino;
+ register char *np;
+ DBT key, val;
+ int n, ndx, retval;
+ u_int16_t copyto, diff, off, moved;
+ char *op;
+
+ copyto = (u_int16_t)hashp->BSIZE;
+ off = (u_int16_t)hashp->BSIZE;
+ old_bufp = __get_buf(hashp, obucket, NULL, 0);
+ if (old_bufp == NULL)
+ return (-1);
+ new_bufp = __get_buf(hashp, nbucket, NULL, 0);
+ if (new_bufp == NULL)
+ return (-1);
+
+ old_bufp->flags |= (BUF_MOD | BUF_PIN);
+ new_bufp->flags |= (BUF_MOD | BUF_PIN);
+
+ ino = (u_int16_t *)(op = old_bufp->page);
+ np = new_bufp->page;
+
+ moved = 0;
+
+ for (n = 1, ndx = 1; n < ino[0]; n += 2) {
+ if (ino[n + 1] < REAL_KEY) {
+ retval = ugly_split(hashp, obucket, old_bufp, new_bufp,
+ (int)copyto, (int)moved);
+ old_bufp->flags &= ~BUF_PIN;
+ new_bufp->flags &= ~BUF_PIN;
+ return (retval);
+
+ }
+ key.data = (u_char *)op + ino[n];
+ key.size = off - ino[n];
+
+ if (__call_hash(hashp, key.data, key.size) == obucket) {
+ /* Don't switch page */
+ diff = copyto - off;
+ if (diff) {
+ copyto = ino[n + 1] + diff;
+ memmove(op + copyto, op + ino[n + 1],
+ off - ino[n + 1]);
+ ino[ndx] = copyto + ino[n] - ino[n + 1];
+ ino[ndx + 1] = copyto;
+ } else
+ copyto = ino[n + 1];
+ ndx += 2;
+ } else {
+ /* Switch page */
+ val.data = (u_char *)op + ino[n + 1];
+ val.size = ino[n] - ino[n + 1];
+ putpair(np, &key, &val);
+ moved += 2;
+ }
+
+ off = ino[n + 1];
+ }
+
+ /* Now clean up the page */
+ ino[0] -= moved;
+ FREESPACE(ino) = copyto - sizeof(u_int16_t) * (ino[0] + 3);
+ OFFSET(ino) = copyto;
+
+#ifdef DEBUG3
+ (void)fprintf(stderr, "split %d/%d\n",
+ ((u_int16_t *)np)[0] / 2,
+ ((u_int16_t *)op)[0] / 2);
+#endif
+ /* unpin both pages */
+ old_bufp->flags &= ~BUF_PIN;
+ new_bufp->flags &= ~BUF_PIN;
+ return (0);
+}
+
+/*
+ * Called when we encounter an overflow or big key/data page during split
+ * handling. This is special cased since we have to begin checking whether
+ * the key/data pairs fit on their respective pages and because we may need
+ * overflow pages for both the old and new pages.
+ *
+ * The first page might be a page with regular key/data pairs in which case
+ * we have a regular overflow condition and just need to go on to the next
+ * page or it might be a big key/data pair in which case we need to fix the
+ * big key/data pair.
+ *
+ * Returns:
+ * 0 ==> success
+ * -1 ==> failure
+ */
+static int
+ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
+ HTAB *hashp;
+ u_int32_t obucket; /* Same as __split_page. */
+ BUFHEAD *old_bufp, *new_bufp;
+ int copyto; /* First byte on page which contains key/data values. */
+ int moved; /* Number of pairs moved to new page. */
+{
+ register BUFHEAD *bufp; /* Buffer header for ino */
+ register u_int16_t *ino; /* Page keys come off of */
+ register u_int16_t *np; /* New page */
+ register u_int16_t *op; /* Page keys go on to if they aren't moving */
+
+ BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */
+ DBT key, val;
+ SPLIT_RETURN ret;
+ u_int16_t n, off, ov_addr, scopyto;
+ char *cino; /* Character value of ino */
+
+ bufp = old_bufp;
+ ino = (u_int16_t *)old_bufp->page;
+ np = (u_int16_t *)new_bufp->page;
+ op = (u_int16_t *)old_bufp->page;
+ last_bfp = NULL;
+ scopyto = (u_int16_t)copyto; /* ANSI */
+
+ n = ino[0] - 1;
+ while (n < ino[0]) {
+ if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
+ if (__big_split(hashp, old_bufp,
+ new_bufp, bufp, bufp->addr, obucket, &ret))
+ return (-1);
+ old_bufp = ret.oldp;
+ if (!old_bufp)
+ return (-1);
+ op = (u_int16_t *)old_bufp->page;
+ new_bufp = ret.newp;
+ if (!new_bufp)
+ return (-1);
+ np = (u_int16_t *)new_bufp->page;
+ bufp = ret.nextp;
+ if (!bufp)
+ return (0);
+ cino = (char *)bufp->page;
+ ino = (u_int16_t *)cino;
+ last_bfp = ret.nextp;
+ } else if (ino[n + 1] == OVFLPAGE) {
+ ov_addr = ino[n];
+ /*
+ * Fix up the old page -- the extra 2 are the fields
+ * which contained the overflow information.
+ */
+ ino[0] -= (moved + 2);
+ FREESPACE(ino) =
+ scopyto - sizeof(u_int16_t) * (ino[0] + 3);
+ OFFSET(ino) = scopyto;
+
+ bufp = __get_buf(hashp, ov_addr, bufp, 0);
+ if (!bufp)
+ return (-1);
+
+ ino = (u_int16_t *)bufp->page;
+ n = 1;
+ scopyto = hashp->BSIZE;
+ moved = 0;
+
+ if (last_bfp)
+ __free_ovflpage(hashp, last_bfp);
+ last_bfp = bufp;
+ }
+ /* Move regular sized pairs of there are any */
+ off = hashp->BSIZE;
+ for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
+ cino = (char *)ino;
+ key.data = (u_char *)cino + ino[n];
+ key.size = off - ino[n];
+ val.data = (u_char *)cino + ino[n + 1];
+ val.size = ino[n] - ino[n + 1];
+ off = ino[n + 1];
+
+ if (__call_hash(hashp, key.data, key.size) == obucket) {
+ /* Keep on old page */
+ if (PAIRFITS(op, (&key), (&val)))
+ putpair((char *)op, &key, &val);
+ else {
+ old_bufp =
+ __add_ovflpage(hashp, old_bufp);
+ if (!old_bufp)
+ return (-1);
+ op = (u_int16_t *)old_bufp->page;
+ putpair((char *)op, &key, &val);
+ }
+ old_bufp->flags |= BUF_MOD;
+ } else {
+ /* Move to new page */
+ if (PAIRFITS(np, (&key), (&val)))
+ putpair((char *)np, &key, &val);
+ else {
+ new_bufp =
+ __add_ovflpage(hashp, new_bufp);
+ if (!new_bufp)
+ return (-1);
+ np = (u_int16_t *)new_bufp->page;
+ putpair((char *)np, &key, &val);
+ }
+ new_bufp->flags |= BUF_MOD;
+ }
+ }
+ }
+ if (last_bfp)
+ __free_ovflpage(hashp, last_bfp);
+ return (0);
+}
+
+/*
+ * Add the given pair to the page
+ *
+ * Returns:
+ * 0 ==> OK
+ * 1 ==> failure
+ */
+extern int
+__addel(hashp, bufp, key, val)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ const DBT *key, *val;
+{
+ register u_int16_t *bp, *sop;
+ int do_expand;
+
+ bp = (u_int16_t *)bufp->page;
+ do_expand = 0;
+ while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
+ /* Exception case */
+ if (bp[2] == FULL_KEY_DATA && bp[0] == 2)
+ /* This is the last page of a big key/data pair
+ and we need to add another page */
+ break;
+ else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (u_int16_t *)bufp->page;
+ } else
+ /* Try to squeeze key on this page */
+ if (FREESPACE(bp) > PAIRSIZE(key, val)) {
+ squeeze_key(bp, key, val);
+ return (0);
+ } else {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (u_int16_t *)bufp->page;
+ }
+
+ if (PAIRFITS(bp, key, val))
+ putpair(bufp->page, key, val);
+ else {
+ do_expand = 1;
+ bufp = __add_ovflpage(hashp, bufp);
+ if (!bufp)
+ return (-1);
+ sop = (u_int16_t *)bufp->page;
+
+ if (PAIRFITS(sop, key, val))
+ putpair((char *)sop, key, val);
+ else
+ if (__big_insert(hashp, bufp, key, val))
+ return (-1);
+ }
+ bufp->flags |= BUF_MOD;
+ /*
+ * If the average number of keys per bucket exceeds the fill factor,
+ * expand the table.
+ */
+ hashp->NKEYS++;
+ if (do_expand ||
+ (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR))
+ return (__expand_table(hashp));
+ return (0);
+}
+
+/*
+ *
+ * Returns:
+ * pointer on success
+ * NULL on error
+ */
+extern BUFHEAD *
+__add_ovflpage(hashp, bufp)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+{
+ register u_int16_t *sp;
+ u_int16_t ndx, ovfl_num;
+#ifdef DEBUG1
+ int tmp1, tmp2;
+#endif
+ sp = (u_int16_t *)bufp->page;
+
+ /* Check if we are dynamically determining the fill factor */
+ if (hashp->FFACTOR == DEF_FFACTOR) {
+ hashp->FFACTOR = sp[0] >> 1;
+ if (hashp->FFACTOR < MIN_FFACTOR)
+ hashp->FFACTOR = MIN_FFACTOR;
+ }
+ bufp->flags |= BUF_MOD;
+ ovfl_num = overflow_page(hashp);
+#ifdef DEBUG1
+ tmp1 = bufp->addr;
+ tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0;
+#endif
+ if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1)))
+ return (NULL);
+ bufp->ovfl->flags |= BUF_MOD;
+#ifdef DEBUG1
+ (void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n",
+ tmp1, tmp2, bufp->ovfl->addr);
+#endif
+ ndx = sp[0];
+ /*
+ * Since a pair is allocated on a page only if there's room to add
+ * an overflow page, we know that the OVFL information will fit on
+ * the page.
+ */
+ sp[ndx + 4] = OFFSET(sp);
+ sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE;
+ sp[ndx + 1] = ovfl_num;
+ sp[ndx + 2] = OVFLPAGE;
+ sp[0] = ndx + 2;
+#ifdef HASH_STATISTICS
+ hash_overflows++;
+#endif
+ return (bufp->ovfl);
+}
+
+/*
+ * Returns:
+ * 0 indicates SUCCESS
+ * -1 indicates FAILURE
+ */
+extern int
+__get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap)
+ HTAB *hashp;
+ char *p;
+ u_int32_t bucket;
+ int is_bucket, is_disk, is_bitmap;
+{
+ register int fd, page, size;
+ int rsize;
+ u_int16_t *bp;
+
+ fd = hashp->fp;
+ size = hashp->BSIZE;
+
+ if ((fd == -1) || !is_disk) {
+ PAGE_INIT(p);
+ return (0);
+ }
+ if (is_bucket)
+ page = BUCKET_TO_PAGE(bucket);
+ else
+ page = OADDR_TO_PAGE(bucket);
+ if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
+ ((rsize = read(fd, p, size)) == -1))
+ return (-1);
+ bp = (u_int16_t *)p;
+ if (!rsize)
+ bp[0] = 0; /* We hit the EOF, so initialize a new page */
+ else
+ if (rsize != size) {
+ errno = EFTYPE;
+ return (-1);
+ }
+ if (!is_bitmap && !bp[0]) {
+ PAGE_INIT(p);
+ } else
+ if (hashp->LORDER != BYTE_ORDER) {
+ register int i, max;
+
+ if (is_bitmap) {
+ max = hashp->BSIZE >> 2; /* divide by 4 */
+ for (i = 0; i < max; i++)
+ M_32_SWAP(((int *)p)[i]);
+ } else {
+ M_16_SWAP(bp[0]);
+ max = bp[0] + 2;
+ for (i = 1; i <= max; i++)
+ M_16_SWAP(bp[i]);
+ }
+ }
+ return (0);
+}
+
+/*
+ * Write page p to disk
+ *
+ * Returns:
+ * 0 ==> OK
+ * -1 ==>failure
+ */
+extern int
+__put_page(hashp, p, bucket, is_bucket, is_bitmap)
+ HTAB *hashp;
+ char *p;
+ u_int32_t bucket;
+ int is_bucket, is_bitmap;
+{
+ register int fd, page, size;
+ int wsize;
+
+ size = hashp->BSIZE;
+ if ((hashp->fp == -1) && open_temp(hashp))
+ return (-1);
+ fd = hashp->fp;
+
+ if (hashp->LORDER != BYTE_ORDER) {
+ register int i;
+ register int max;
+
+ if (is_bitmap) {
+ max = hashp->BSIZE >> 2; /* divide by 4 */
+ for (i = 0; i < max; i++)
+ M_32_SWAP(((int *)p)[i]);
+ } else {
+ max = ((u_int16_t *)p)[0] + 2;
+ for (i = 0; i <= max; i++)
+ M_16_SWAP(((u_int16_t *)p)[i]);
+ }
+ }
+ if (is_bucket)
+ page = BUCKET_TO_PAGE(bucket);
+ else
+ page = OADDR_TO_PAGE(bucket);
+ if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
+ ((wsize = write(fd, p, size)) == -1))
+ /* Errno is set */
+ return (-1);
+ if (wsize != size) {
+ errno = EFTYPE;
+ return (-1);
+ }
+ return (0);
+}
+
+#define BYTE_MASK ((1 << INT_BYTE_SHIFT) -1)
+/*
+ * Initialize a new bitmap page. Bitmap pages are left in memory
+ * once they are read in.
+ */
+extern int
+__ibitmap(hashp, pnum, nbits, ndx)
+ HTAB *hashp;
+ int pnum, nbits, ndx;
+{
+ u_int32_t *ip;
+ int clearbytes, clearints;
+
+ if ((ip = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
+ return (1);
+ hashp->nmaps++;
+ clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1;
+ clearbytes = clearints << INT_TO_BYTE;
+ (void)memset((char *)ip, 0, clearbytes);
+ (void)memset(((char *)ip) + clearbytes, 0xFF,
+ hashp->BSIZE - clearbytes);
+ ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK);
+ SETBIT(ip, 0);
+ hashp->BITMAPS[ndx] = (u_int16_t)pnum;
+ hashp->mapp[ndx] = ip;
+ return (0);
+}
+
+static u_int32_t
+first_free(map)
+ u_int32_t map;
+{
+ register u_int32_t i, mask;
+
+ mask = 0x1;
+ for (i = 0; i < BITS_PER_MAP; i++) {
+ if (!(mask & map))
+ return (i);
+ mask = mask << 1;
+ }
+ return (i);
+}
+
+static u_int16_t
+overflow_page(hashp)
+ HTAB *hashp;
+{
+ register u_int32_t *freep;
+ register int max_free, offset, splitnum;
+ u_int16_t addr;
+ int bit, first_page, free_bit, free_page, i, in_use_bits, j;
+#ifdef DEBUG2
+ int tmp1, tmp2;
+#endif
+ splitnum = hashp->OVFL_POINT;
+ max_free = hashp->SPARES[splitnum];
+
+ free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
+ free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
+
+ /* Look through all the free maps to find the first free block */
+ first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT);
+ for ( i = first_page; i <= free_page; i++ ) {
+ if (!(freep = (u_int32_t *)hashp->mapp[i]) &&
+ !(freep = fetch_bitmap(hashp, i)))
+ return (0);
+ if (i == free_page)
+ in_use_bits = free_bit;
+ else
+ in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
+
+ if (i == first_page) {
+ bit = hashp->LAST_FREED &
+ ((hashp->BSIZE << BYTE_SHIFT) - 1);
+ j = bit / BITS_PER_MAP;
+ bit = bit & ~(BITS_PER_MAP - 1);
+ } else {
+ bit = 0;
+ j = 0;
+ }
+ for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
+ if (freep[j] != ALL_SET)
+ goto found;
+ }
+
+ /* No Free Page Found */
+ hashp->LAST_FREED = hashp->SPARES[splitnum];
+ hashp->SPARES[splitnum]++;
+ offset = hashp->SPARES[splitnum] -
+ (splitnum ? hashp->SPARES[splitnum - 1] : 0);
+
+#define OVMSG "HASH: Out of overflow pages. Increase page size\n"
+ if (offset > SPLITMASK) {
+ if (++splitnum >= NCACHED) {
+ (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
+ return (0);
+ }
+ hashp->OVFL_POINT = splitnum;
+ hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
+ hashp->SPARES[splitnum-1]--;
+ offset = 1;
+ }
+
+ /* Check if we need to allocate a new bitmap page */
+ if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
+ free_page++;
+ if (free_page >= NCACHED) {
+ (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
+ return (0);
+ }
+ /*
+ * This is tricky. The 1 indicates that you want the new page
+ * allocated with 1 clear bit. Actually, you are going to
+ * allocate 2 pages from this map. The first is going to be
+ * the map page, the second is the overflow page we were
+ * looking for. The init_bitmap routine automatically, sets
+ * the first bit of itself to indicate that the bitmap itself
+ * is in use. We would explicitly set the second bit, but
+ * don't have to if we tell init_bitmap not to leave it clear
+ * in the first place.
+ */
+ if (__ibitmap(hashp,
+ (int)OADDR_OF(splitnum, offset), 1, free_page))
+ return (0);
+ hashp->SPARES[splitnum]++;
+#ifdef DEBUG2
+ free_bit = 2;
+#endif
+ offset++;
+ if (offset > SPLITMASK) {
+ if (++splitnum >= NCACHED) {
+ (void)write(STDERR_FILENO, OVMSG,
+ sizeof(OVMSG) - 1);
+ return (0);
+ }
+ hashp->OVFL_POINT = splitnum;
+ hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
+ hashp->SPARES[splitnum-1]--;
+ offset = 0;
+ }
+ } else {
+ /*
+ * Free_bit addresses the last used bit. Bump it to address
+ * the first available bit.
+ */
+ free_bit++;
+ SETBIT(freep, free_bit);
+ }
+
+ /* Calculate address of the new overflow page */
+ addr = OADDR_OF(splitnum, offset);
+#ifdef DEBUG2
+ (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
+ addr, free_bit, free_page);
+#endif
+ return (addr);
+
+found:
+ bit = bit + first_free(freep[j]);
+ SETBIT(freep, bit);
+#ifdef DEBUG2
+ tmp1 = bit;
+ tmp2 = i;
+#endif
+ /*
+ * Bits are addressed starting with 0, but overflow pages are addressed
+ * beginning at 1. Bit is a bit addressnumber, so we need to increment
+ * it to convert it to a page number.
+ */
+ bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
+ if (bit >= hashp->LAST_FREED)
+ hashp->LAST_FREED = bit - 1;
+
+ /* Calculate the split number for this page */
+ for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++);
+ offset = (i ? bit - hashp->SPARES[i - 1] : bit);
+ if (offset >= SPLITMASK)
+ return (0); /* Out of overflow pages */
+ addr = OADDR_OF(i, offset);
+#ifdef DEBUG2
+ (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
+ addr, tmp1, tmp2);
+#endif
+
+ /* Allocate and return the overflow page */
+ return (addr);
+}
+
+/*
+ * Mark this overflow page as free.
+ */
+extern void
+__free_ovflpage(hashp, obufp)
+ HTAB *hashp;
+ BUFHEAD *obufp;
+{
+ register u_int16_t addr;
+ u_int32_t *freep;
+ int bit_address, free_page, free_bit;
+ u_int16_t ndx;
+
+ addr = obufp->addr;
+#ifdef DEBUG1
+ (void)fprintf(stderr, "Freeing %d\n", addr);
+#endif
+ ndx = (((u_int16_t)addr) >> SPLITSHIFT);
+ bit_address =
+ (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
+ if (bit_address < hashp->LAST_FREED)
+ hashp->LAST_FREED = bit_address;
+ free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
+ free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);
+
+ if (!(freep = hashp->mapp[free_page]))
+ freep = fetch_bitmap(hashp, free_page);
+#ifdef DEBUG
+ /*
+ * This had better never happen. It means we tried to read a bitmap
+ * that has already had overflow pages allocated off it, and we
+ * failed to read it from the file.
+ */
+ if (!freep)
+ assert(0);
+#endif
+ CLRBIT(freep, free_bit);
+#ifdef DEBUG2
+ (void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n",
+ obufp->addr, free_bit, free_page);
+#endif
+ __reclaim_buf(hashp, obufp);
+}
+
+/*
+ * Returns:
+ * 0 success
+ * -1 failure
+ */
+static int
+open_temp(hashp)
+ HTAB *hashp;
+{
+ sigset_t set, oset;
+ static char namestr[] = "_hashXXXXXX";
+
+ /* Block signals; make sure file goes away at process exit. */
+ (void)sigfillset(&set);
+ (void)sigprocmask(SIG_BLOCK, &set, &oset);
+ if ((hashp->fp = mkstemp(namestr)) != -1) {
+ (void)unlink(namestr);
+ (void)fcntl(hashp->fp, F_SETFD, 1);
+ }
+ (void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
+ return (hashp->fp != -1 ? 0 : -1);
+}
+
+/*
+ * We have to know that the key will fit, but the last entry on the page is
+ * an overflow pair, so we need to shift things.
+ */
+static void
+squeeze_key(sp, key, val)
+ u_int16_t *sp;
+ const DBT *key, *val;
+{
+ register char *p;
+ u_int16_t free_space, n, off, pageno;
+
+ p = (char *)sp;
+ n = sp[0];
+ free_space = FREESPACE(sp);
+ off = OFFSET(sp);
+
+ pageno = sp[n - 1];
+ off -= key->size;
+ sp[n - 1] = off;
+ memmove(p + off, key->data, key->size);
+ off -= val->size;
+ sp[n] = off;
+ memmove(p + off, val->data, val->size);
+ sp[0] = n + 2;
+ sp[n + 1] = pageno;
+ sp[n + 2] = OVFLPAGE;
+ FREESPACE(sp) = free_space - PAIRSIZE(key, val);
+ OFFSET(sp) = off;
+}
+
+static u_int32_t *
+fetch_bitmap(hashp, ndx)
+ HTAB *hashp;
+ int ndx;
+{
+ if (ndx >= hashp->nmaps)
+ return (NULL);
+ if ((hashp->mapp[ndx] = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
+ return (NULL);
+ if (__get_page(hashp,
+ (char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) {
+ free(hashp->mapp[ndx]);
+ return (NULL);
+ }
+ return (hashp->mapp[ndx]);
+}
+
+#ifdef DEBUG4
+int
+print_chain(addr)
+ int addr;
+{
+ BUFHEAD *bufp;
+ short *bp, oaddr;
+
+ (void)fprintf(stderr, "%d ", addr);
+ bufp = __get_buf(hashp, addr, NULL, 0);
+ bp = (short *)bufp->page;
+ while (bp[0] && ((bp[bp[0]] == OVFLPAGE) ||
+ ((bp[0] > 2) && bp[2] < REAL_KEY))) {
+ oaddr = bp[bp[0] - 1];
+ (void)fprintf(stderr, "%d ", (int)oaddr);
+ bufp = __get_buf(hashp, (int)oaddr, bufp, 0);
+ bp = (short *)bufp->page;
+ }
+ (void)fprintf(stderr, "\n");
+}
+#endif
diff --git a/lib/libc/db/hash/hsearch.c b/lib/libc/db/hash/hsearch.c
new file mode 100644
index 0000000..6185330
--- /dev/null
+++ b/lib/libc/db/hash/hsearch.c
@@ -0,0 +1,107 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hsearch.c 8.4 (Berkeley) 7/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <fcntl.h>
+#include <string.h>
+
+#include <db.h>
+#include "search.h"
+
+static DB *dbp = NULL;
+static ENTRY retval;
+
+extern int
+hcreate(nel)
+ u_int nel;
+{
+ HASHINFO info;
+
+ info.nelem = nel;
+ info.bsize = 256;
+ info.ffactor = 8;
+ info.cachesize = 0;
+ info.hash = NULL;
+ info.lorder = 0;
+ dbp = (DB *)__hash_open(NULL, O_CREAT | O_RDWR, 0600, &info, 0);
+ return (dbp != NULL);
+}
+
+extern ENTRY *
+hsearch(item, action)
+ ENTRY item;
+ ACTION action;
+{
+ DBT key, val;
+ int status;
+
+ if (!dbp)
+ return (NULL);
+ key.data = (u_char *)item.key;
+ key.size = strlen(item.key) + 1;
+
+ if (action == ENTER) {
+ val.data = (u_char *)item.data;
+ val.size = strlen(item.data) + 1;
+ status = (dbp->put)(dbp, &key, &val, R_NOOVERWRITE);
+ if (status)
+ return (NULL);
+ } else {
+ /* FIND */
+ status = (dbp->get)(dbp, &key, &val, 0);
+ if (status)
+ return (NULL);
+ else
+ item.data = (char *)val.data;
+ }
+ retval.key = item.key;
+ retval.data = item.data;
+ return (&retval);
+}
+
+extern void
+hdestroy()
+{
+ if (dbp) {
+ (void)(dbp->close)(dbp);
+ dbp = NULL;
+ }
+}
diff --git a/lib/libc/db/hash/ndbm.c b/lib/libc/db/hash/ndbm.c
new file mode 100644
index 0000000..2e8165d
--- /dev/null
+++ b/lib/libc/db/hash/ndbm.c
@@ -0,0 +1,229 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * This package provides a dbm compatible interface to the new hashing
+ * package described in db(3).
+ */
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <ndbm.h>
+#include "hash.h"
+
+/*
+ * Returns:
+ * *DBM on success
+ * NULL on failure
+ */
+extern DBM *
+dbm_open(file, flags, mode)
+ const char *file;
+ int flags, mode;
+{
+ HASHINFO info;
+ char path[MAXPATHLEN];
+
+ info.bsize = 4096;
+ info.ffactor = 40;
+ info.nelem = 1;
+ info.cachesize = 0;
+ info.hash = NULL;
+ info.lorder = 0;
+
+ if( strlen(file) >= sizeof(path) - strlen(DBM_SUFFIX)) {
+ errno = ENAMETOOLONG;
+ return(NULL);
+ }
+ (void)strcpy(path, file);
+ (void)strcat(path, DBM_SUFFIX);
+ return ((DBM *)__hash_open(path, flags, mode, &info, 0));
+}
+
+extern void
+dbm_close(db)
+ DBM *db;
+{
+ (void)(db->close)(db);
+}
+
+/*
+ * Returns:
+ * DATUM on success
+ * NULL on failure
+ */
+extern datum
+dbm_fetch(db, key)
+ DBM *db;
+ datum key;
+{
+ datum retdata;
+ int status;
+ DBT dbtkey, dbtretdata;
+
+ dbtkey.data = key.dptr;
+ dbtkey.size = key.dsize;
+ status = (db->get)(db, &dbtkey, &dbtretdata, 0);
+ if (status) {
+ dbtretdata.data = NULL;
+ dbtretdata.size = 0;
+ }
+ retdata.dptr = dbtretdata.data;
+ retdata.dsize = dbtretdata.size;
+ return (retdata);
+}
+
+/*
+ * Returns:
+ * DATUM on success
+ * NULL on failure
+ */
+extern datum
+dbm_firstkey(db)
+ DBM *db;
+{
+ int status;
+ datum retkey;
+ DBT dbtretkey, dbtretdata;
+
+ status = (db->seq)(db, &dbtretkey, &dbtretdata, R_FIRST);
+ if (status)
+ dbtretkey.data = NULL;
+ retkey.dptr = dbtretkey.data;
+ retkey.dsize = dbtretkey.size;
+ return (retkey);
+}
+
+/*
+ * Returns:
+ * DATUM on success
+ * NULL on failure
+ */
+extern datum
+dbm_nextkey(db)
+ DBM *db;
+{
+ int status;
+ datum retkey;
+ DBT dbtretkey, dbtretdata;
+
+ status = (db->seq)(db, &dbtretkey, &dbtretdata, R_NEXT);
+ if (status)
+ dbtretkey.data = NULL;
+ retkey.dptr = dbtretkey.data;
+ retkey.dsize = dbtretkey.size;
+ return (retkey);
+}
+
+/*
+ * Returns:
+ * 0 on success
+ * <0 failure
+ */
+extern int
+dbm_delete(db, key)
+ DBM *db;
+ datum key;
+{
+ int status;
+ DBT dbtkey;
+
+ dbtkey.data = key.dptr;
+ dbtkey.size = key.dsize;
+ status = (db->del)(db, &dbtkey, 0);
+ if (status)
+ return (-1);
+ else
+ return (0);
+}
+
+/*
+ * Returns:
+ * 0 on success
+ * <0 failure
+ * 1 if DBM_INSERT and entry exists
+ */
+extern int
+dbm_store(db, key, data, flags)
+ DBM *db;
+ datum key, data;
+ int flags;
+{
+ DBT dbtkey, dbtdata;
+
+ dbtkey.data = key.dptr;
+ dbtkey.size = key.dsize;
+ dbtdata.data = data.dptr;
+ dbtdata.size = data.dsize;
+ return ((db->put)(db, &dbtkey, &dbtdata,
+ (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
+}
+
+extern int
+dbm_error(db)
+ DBM *db;
+{
+ HTAB *hp;
+
+ hp = (HTAB *)db->internal;
+ return (hp->error);
+}
+
+extern int
+dbm_clearerr(db)
+ DBM *db;
+{
+ HTAB *hp;
+
+ hp = (HTAB *)db->internal;
+ hp->error = 0;
+ return (0);
+}
+
+extern int
+dbm_dirfno(db)
+ DBM *db;
+{
+ return(((HTAB *)db->internal)->fp);
+}
diff --git a/lib/libc/db/hash/page.h b/lib/libc/db/hash/page.h
new file mode 100644
index 0000000..0fc0d5a
--- /dev/null
+++ b/lib/libc/db/hash/page.h
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)page.h 8.2 (Berkeley) 5/31/94
+ */
+
+/*
+ * Definitions for hashing page file format.
+ */
+
+/*
+ * routines dealing with a data page
+ *
+ * page format:
+ * +------------------------------+
+ * p | n | keyoff | datoff | keyoff |
+ * +------------+--------+--------+
+ * | datoff | free | ptr | --> |
+ * +--------+---------------------+
+ * | F R E E A R E A |
+ * +--------------+---------------+
+ * | <---- - - - | data |
+ * +--------+-----+----+----------+
+ * | key | data | key |
+ * +--------+----------+----------+
+ *
+ * Pointer to the free space is always: p[p[0] + 2]
+ * Amount of free space on the page is: p[p[0] + 1]
+ */
+
+/*
+ * How many bytes required for this pair?
+ * 2 shorts in the table at the top of the page + room for the
+ * key and room for the data
+ *
+ * We prohibit entering a pair on a page unless there is also room to append
+ * an overflow page. The reason for this it that you can get in a situation
+ * where a single key/data pair fits on a page, but you can't append an
+ * overflow page and later you'd have to split the key/data and handle like
+ * a big pair.
+ * You might as well do this up front.
+ */
+
+#define PAIRSIZE(K,D) (2*sizeof(u_int16_t) + (K)->size + (D)->size)
+#define BIGOVERHEAD (4*sizeof(u_int16_t))
+#define KEYSIZE(K) (4*sizeof(u_int16_t) + (K)->size);
+#define OVFLSIZE (2*sizeof(u_int16_t))
+#define FREESPACE(P) ((P)[(P)[0]+1])
+#define OFFSET(P) ((P)[(P)[0]+2])
+#define PAIRFITS(P,K,D) \
+ (((P)[2] >= REAL_KEY) && \
+ (PAIRSIZE((K),(D)) + OVFLSIZE) <= FREESPACE((P)))
+#define PAGE_META(N) (((N)+3) * sizeof(u_int16_t))
+
+typedef struct {
+ BUFHEAD *newp;
+ BUFHEAD *oldp;
+ BUFHEAD *nextp;
+ u_int16_t next_addr;
+} SPLIT_RETURN;
diff --git a/lib/libc/db/hash/search.h b/lib/libc/db/hash/search.h
new file mode 100644
index 0000000..4d3b914
--- /dev/null
+++ b/lib/libc/db/hash/search.h
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)search.h 8.1 (Berkeley) 6/4/93
+ */
+
+/* Backward compatibility to hsearch interface. */
+typedef struct entry {
+ char *key;
+ char *data;
+} ENTRY;
+
+typedef enum {
+ FIND, ENTER
+} ACTION;
+
+int hcreate __P((unsigned int));
+void hdestroy __P((void));
+ENTRY *hsearch __P((ENTRY, ACTION));
diff --git a/lib/libc/db/man/Makefile.inc b/lib/libc/db/man/Makefile.inc
new file mode 100644
index 0000000..1498413
--- /dev/null
+++ b/lib/libc/db/man/Makefile.inc
@@ -0,0 +1,10 @@
+# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libc/db/man
+
+.if ${LIB} == "c"
+MAN3+= btree.3 dbopen.3 hash.3 mpool.3 recno.3
+
+MLINKS+= dbopen.3 db.3
+.endif
diff --git a/lib/libc/db/man/btree.3 b/lib/libc/db/man/btree.3
new file mode 100644
index 0000000..9ce6d66
--- /dev/null
+++ b/lib/libc/db/man/btree.3
@@ -0,0 +1,234 @@
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)btree.3 8.4 (Berkeley) 8/18/94
+.\" $FreeBSD$
+.\"
+.TH BTREE 3 "August 18, 1994"
+.\".UC 7
+.SH NAME
+btree \- btree database access method
+.SH SYNOPSIS
+.nf
+.ft B
+#include <sys/types.h>
+#include <db.h>
+.ft R
+.fi
+.SH DESCRIPTION
+The routine
+.IR dbopen
+is the library interface to database files.
+One of the supported file formats is btree files.
+The general description of the database access methods is in
+.IR dbopen (3),
+this manual page describes only the btree specific information.
+.PP
+The btree data structure is a sorted, balanced tree structure storing
+associated key/data pairs.
+.PP
+The btree access method specific data structure provided to
+.I dbopen
+is defined in the <db.h> include file as follows:
+.PP
+typedef struct {
+.RS
+u_long flags;
+.br
+u_int cachesize;
+.br
+int maxkeypage;
+.br
+int minkeypage;
+.br
+u_int psize;
+.br
+int (*compare)(const DBT *key1, const DBT *key2);
+.br
+size_t (*prefix)(const DBT *key1, const DBT *key2);
+.br
+int lorder;
+.RE
+} BTREEINFO;
+.PP
+The elements of this structure are as follows:
+.TP
+flags
+The flag value is specified by
+.IR or 'ing
+any of the following values:
+.RS
+.TP
+R_DUP
+Permit duplicate keys in the tree, i.e. permit insertion if the key to be
+inserted already exists in the tree.
+The default behavior, as described in
+.IR dbopen (3),
+is to overwrite a matching key when inserting a new key or to fail if
+the R_NOOVERWRITE flag is specified.
+The R_DUP flag is overridden by the R_NOOVERWRITE flag, and if the
+R_NOOVERWRITE flag is specified, attempts to insert duplicate keys into
+the tree will fail.
+.IP
+If the database contains duplicate keys, the order of retrieval of
+key/data pairs is undefined if the
+.I get
+routine is used, however,
+.I seq
+routine calls with the R_CURSOR flag set will always return the logical
+``first'' of any group of duplicate keys.
+.RE
+.TP
+cachesize
+A suggested maximum size (in bytes) of the memory cache.
+This value is
+.B only
+advisory, and the access method will allocate more memory rather than fail.
+Since every search examines the root page of the tree, caching the most
+recently used pages substantially improves access time.
+In addition, physical writes are delayed as long as possible, so a moderate
+cache can reduce the number of I/O operations significantly.
+Obviously, using a cache increases (but only increases) the likelihood of
+corruption or lost data if the system crashes while a tree is being modified.
+If
+.I cachesize
+is 0 (no size is specified) a default cache is used.
+.TP
+maxkeypage
+The maximum number of keys which will be stored on any single page.
+Not currently implemented.
+.\" The maximum number of keys which will be stored on any single page.
+.\" Because of the way the btree data structure works,
+.\" .I maxkeypage
+.\" must always be greater than or equal to 2.
+.\" If
+.\" .I maxkeypage
+.\" is 0 (no maximum number of keys is specified) the page fill factor is
+.\" made as large as possible (which is almost invariably what is wanted).
+.TP
+minkeypage
+The minimum number of keys which will be stored on any single page.
+This value is used to determine which keys will be stored on overflow
+pages, i.e. if a key or data item is longer than the pagesize divided
+by the minkeypage value, it will be stored on overflow pages instead
+of in the page itself.
+If
+.I minkeypage
+is 0 (no minimum number of keys is specified) a value of 2 is used.
+.TP
+psize
+Page size is the size (in bytes) of the pages used for nodes in the tree.
+The minimum page size is 512 bytes and the maximum page size is 64K.
+If
+.I psize
+is 0 (no page size is specified) a page size is chosen based on the
+underlying file system I/O block size.
+.TP
+compare
+Compare is the key comparison function.
+It must return an integer less than, equal to, or greater than zero if the
+first key argument is considered to be respectively less than, equal to,
+or greater than the second key argument.
+The same comparison function must be used on a given tree every time it
+is opened.
+If
+.I compare
+is NULL (no comparison function is specified), the keys are compared
+lexically, with shorter keys considered less than longer keys.
+.TP
+prefix
+Prefix is the prefix comparison function.
+If specified, this routine must return the number of bytes of the second key
+argument which are necessary to determine that it is greater than the first
+key argument.
+If the keys are equal, the key length should be returned.
+Note, the usefulness of this routine is very data dependent, but, in some
+data sets can produce significantly reduced tree sizes and search times.
+If
+.I prefix
+is NULL (no prefix function is specified),
+.B and
+no comparison function is specified, a default lexical comparison routine
+is used.
+If
+.I prefix
+is NULL and a comparison routine is specified, no prefix comparison is
+done.
+.TP
+lorder
+The byte order for integers in the stored database metadata.
+The number should represent the order as an integer; for example,
+big endian order would be the number 4,321.
+If
+.I lorder
+is 0 (no order is specified) the current host order is used.
+.PP
+If the file already exists (and the O_TRUNC flag is not specified), the
+values specified for the parameters flags, lorder and psize are ignored
+in favor of the values used when the tree was created.
+.PP
+Forward sequential scans of a tree are from the least key to the greatest.
+.PP
+Space freed up by deleting key/data pairs from the tree is never reclaimed,
+although it is normally made available for reuse.
+This means that the btree storage structure is grow-only.
+The only solutions are to avoid excessive deletions, or to create a fresh
+tree periodically from a scan of an existing one.
+.PP
+Searches, insertions, and deletions in a btree will all complete in
+O lg base N where base is the average fill factor.
+Often, inserting ordered data into btrees results in a low fill factor.
+This implementation has been modified to make ordered insertion the best
+case, resulting in a much better than normal page fill factor.
+.SH ERRORS
+The
+.I btree
+access method routines may fail and set
+.I errno
+for any of the errors specified for the library routine
+.IR dbopen (3).
+.SH "SEE ALSO"
+.IR dbopen (3),
+.IR hash (3),
+.IR mpool (3),
+.IR recno (3)
+.sp
+.IR "The Ubiquitous B-tree" ,
+Douglas Comer, ACM Comput. Surv. 11, 2 (June 1979), 121-138.
+.sp
+.IR "Prefix B-trees" ,
+Bayer and Unterauer, ACM Transactions on Database Systems, Vol. 2, 1
+(March 1977), 11-26.
+.sp
+.IR "The Art of Computer Programming Vol. 3: Sorting and Searching" ,
+D.E. Knuth, 1968, pp 471-480.
+.SH BUGS
+Only big and little endian byte order is supported.
diff --git a/lib/libc/db/man/dbopen.3 b/lib/libc/db/man/dbopen.3
new file mode 100644
index 0000000..defc687
--- /dev/null
+++ b/lib/libc/db/man/dbopen.3
@@ -0,0 +1,477 @@
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)dbopen.3 8.5 (Berkeley) 1/2/94
+.\" $FreeBSD$
+.\"
+.TH DBOPEN 3 "January 2, 1994"
+.UC 7
+.SH NAME
+dbopen \- database access methods
+.SH SYNOPSIS
+.nf
+.ft B
+#include <sys/types.h>
+#include <limits.h>
+#include <db.h>
+
+DB *
+dbopen(const char *file, int flags, int mode, DBTYPE type,
+.ti +5
+const void *openinfo);
+.ft R
+.fi
+.SH DESCRIPTION
+.IR Dbopen
+is the library interface to database files.
+The supported file formats are btree, hashed and UNIX file oriented.
+The btree format is a representation of a sorted, balanced tree structure.
+The hashed format is an extensible, dynamic hashing scheme.
+The flat-file format is a byte stream file with fixed or variable length
+records.
+The formats and file format specific information are described in detail
+in their respective manual pages
+.IR btree (3),
+.IR hash (3)
+and
+.IR recno (3).
+.PP
+Dbopen opens
+.I file
+for reading and/or writing.
+Files never intended to be preserved on disk may be created by setting
+the file parameter to NULL.
+.PP
+The
+.I flags
+and
+.I mode arguments
+are as specified to the
+.IR open (2)
+routine, however, only the O_CREAT, O_EXCL, O_EXLOCK, O_NONBLOCK,
+O_RDONLY, O_RDWR, O_SHLOCK and O_TRUNC flags are meaningful.
+(Note, opening a database file O_WRONLY is not possible.)
+.\"Three additional options may be specified by
+.\".IR or 'ing
+.\"them into the
+.\".I flags
+.\"argument.
+.\".TP
+.\"DB_LOCK
+.\"Do the necessary locking in the database to support concurrent access.
+.\"If concurrent access isn't needed or the database is read-only this
+.\"flag should not be set, as it tends to have an associated performance
+.\"penalty.
+.\".TP
+.\"DB_SHMEM
+.\"Place the underlying memory pool used by the database in shared
+.\"memory.
+.\"Necessary for concurrent access.
+.\".TP
+.\"DB_TXN
+.\"Support transactions in the database.
+.\"The DB_LOCK and DB_SHMEM flags must be set as well.
+.PP
+The
+.I type
+argument is of type DBTYPE (as defined in the <db.h> include file) and
+may be set to DB_BTREE, DB_HASH or DB_RECNO.
+.PP
+The
+.I openinfo
+argument is a pointer to an access method specific structure described
+in the access method's manual page.
+If
+.I openinfo
+is NULL, each access method will use defaults appropriate for the system
+and the access method.
+.PP
+.I Dbopen
+returns a pointer to a DB structure on success and NULL on error.
+The DB structure is defined in the <db.h> include file, and contains at
+least the following fields:
+.sp
+.nf
+typedef struct {
+.RS
+DBTYPE type;
+int (*close)(const DB *db);
+int (*del)(const DB *db, const DBT *key, u_int flags);
+int (*fd)(const DB *db);
+int (*get)(const DB *db, DBT *key, DBT *data, u_int flags);
+int (*put)(const DB *db, DBT *key, const DBT *data,
+.ti +5
+u_int flags);
+int (*sync)(const DB *db, u_int flags);
+int (*seq)(const DB *db, DBT *key, DBT *data, u_int flags);
+.RE
+} DB;
+.fi
+.PP
+These elements describe a database type and a set of functions performing
+various actions.
+These functions take a pointer to a structure as returned by
+.IR dbopen ,
+and sometimes one or more pointers to key/data structures and a flag value.
+.TP
+type
+The type of the underlying access method (and file format).
+.TP
+close
+A pointer to a routine to flush any cached information to disk, free any
+allocated resources, and close the underlying file(s).
+Since key/data pairs may be cached in memory, failing to sync the file
+with a
+.I close
+or
+.I sync
+function may result in inconsistent or lost information.
+.I Close
+routines return -1 on error (setting
+.IR errno )
+and 0 on success.
+.TP
+del
+A pointer to a routine to remove key/data pairs from the database.
+.IP
+The parameter
+.I flag
+may be set to the following value:
+.RS
+.TP
+R_CURSOR
+Delete the record referenced by the cursor.
+The cursor must have previously been initialized.
+.RE
+.IP
+.I Delete
+routines return -1 on error (setting
+.IR errno ),
+0 on success, and 1 if the specified
+.I key
+was not in the file.
+.TP
+fd
+A pointer to a routine which returns a file descriptor representative
+of the underlying database.
+A file descriptor referencing the same file will be returned to all
+processes which call
+.I dbopen
+with the same
+.I file
+name.
+This file descriptor may be safely used as an argument to the
+.IR fcntl (2)
+and
+.IR flock (2)
+locking functions.
+The file descriptor is not necessarily associated with any of the
+underlying files used by the access method.
+No file descriptor is available for in memory databases.
+.I Fd
+routines return -1 on error (setting
+.IR errno ),
+and the file descriptor on success.
+.TP
+get
+A pointer to a routine which is the interface for keyed retrieval from
+the database.
+The address and length of the data associated with the specified
+.I key
+are returned in the structure referenced by
+.IR data .
+.I Get
+routines return -1 on error (setting
+.IR errno ),
+0 on success, and 1 if the
+.I key
+was not in the file.
+.TP
+put
+A pointer to a routine to store key/data pairs in the database.
+.IP
+The parameter
+.I flag
+may be set to one of the following values:
+.RS
+.TP
+R_CURSOR
+Replace the key/data pair referenced by the cursor.
+The cursor must have previously been initialized.
+.TP
+R_IAFTER
+Append the data immediately after the data referenced by
+.IR key ,
+creating a new key/data pair.
+The record number of the appended key/data pair is returned in the
+.I key
+structure.
+(Applicable only to the DB_RECNO access method.)
+.TP
+R_IBEFORE
+Insert the data immediately before the data referenced by
+.IR key ,
+creating a new key/data pair.
+The record number of the inserted key/data pair is returned in the
+.I key
+structure.
+(Applicable only to the DB_RECNO access method.)
+.TP
+R_NOOVERWRITE
+Enter the new key/data pair only if the key does not previously exist.
+.TP
+R_SETCURSOR
+Store the key/data pair, setting or initializing the position of the
+cursor to reference it.
+(Applicable only to the DB_BTREE and DB_RECNO access methods.)
+.RE
+.IP
+R_SETCURSOR is available only for the DB_BTREE and DB_RECNO access
+methods because it implies that the keys have an inherent order
+which does not change.
+.IP
+R_IAFTER and R_IBEFORE are available only for the DB_RECNO
+access method because they each imply that the access method is able to
+create new keys.
+This is only true if the keys are ordered and independent, record numbers
+for example.
+.IP
+The default behavior of the
+.I put
+routines is to enter the new key/data pair, replacing any previously
+existing key.
+.IP
+.I Put
+routines return -1 on error (setting
+.IR errno ),
+0 on success, and 1 if the R_NOOVERWRITE
+.I flag
+was set and the key already exists in the file.
+.TP
+seq
+A pointer to a routine which is the interface for sequential
+retrieval from the database.
+The address and length of the key are returned in the structure
+referenced by
+.IR key ,
+and the address and length of the data are returned in the
+structure referenced
+by
+.IR data .
+.IP
+Sequential key/data pair retrieval may begin at any time, and the
+position of the ``cursor'' is not affected by calls to the
+.IR del ,
+.IR get ,
+.IR put ,
+or
+.I sync
+routines.
+Modifications to the database during a sequential scan will be reflected
+in the scan, i.e. records inserted behind the cursor will not be returned
+while records inserted in front of the cursor will be returned.
+.IP
+The flag value
+.B must
+be set to one of the following values:
+.RS
+.TP
+R_CURSOR
+The data associated with the specified key is returned.
+This differs from the
+.I get
+routines in that it sets or initializes the cursor to the location of
+the key as well.
+(Note, for the DB_BTREE access method, the returned key is not necessarily an
+exact match for the specified key.
+The returned key is the smallest key greater than or equal to the specified
+key, permitting partial key matches and range searches.)
+.TP
+R_FIRST
+The first key/data pair of the database is returned, and the cursor
+is set or initialized to reference it.
+.TP
+R_LAST
+The last key/data pair of the database is returned, and the cursor
+is set or initialized to reference it.
+(Applicable only to the DB_BTREE and DB_RECNO access methods.)
+.TP
+R_NEXT
+Retrieve the key/data pair immediately after the cursor.
+If the cursor is not yet set, this is the same as the R_FIRST flag.
+.TP
+R_PREV
+Retrieve the key/data pair immediately before the cursor.
+If the cursor is not yet set, this is the same as the R_LAST flag.
+(Applicable only to the DB_BTREE and DB_RECNO access methods.)
+.RE
+.IP
+R_LAST and R_PREV are available only for the DB_BTREE and DB_RECNO
+access methods because they each imply that the keys have an inherent
+order which does not change.
+.IP
+.I Seq
+routines return -1 on error (setting
+.IR errno ),
+0 on success and 1 if there are no key/data pairs less than or greater
+than the specified or current key.
+If the DB_RECNO access method is being used, and if the database file
+is a character special file and no complete key/data pairs are currently
+available, the
+.I seq
+routines return 2.
+.TP
+sync
+A pointer to a routine to flush any cached information to disk.
+If the database is in memory only, the
+.I sync
+routine has no effect and will always succeed.
+.IP
+The flag value may be set to the following value:
+.RS
+.TP
+R_RECNOSYNC
+If the DB_RECNO access method is being used, this flag causes
+the sync routine to apply to the btree file which underlies the
+recno file, not the recno file itself.
+(See the
+.I bfname
+field of the
+.IR recno (3)
+manual page for more information.)
+.RE
+.IP
+.I Sync
+routines return -1 on error (setting
+.IR errno )
+and 0 on success.
+.SH "KEY/DATA PAIRS"
+Access to all file types is based on key/data pairs.
+Both keys and data are represented by the following data structure:
+.PP
+typedef struct {
+.RS
+void *data;
+.br
+size_t size;
+.RE
+} DBT;
+.PP
+The elements of the DBT structure are defined as follows:
+.TP
+data
+A pointer to a byte string.
+.TP
+size
+The length of the byte string.
+.PP
+Key and data byte strings may reference strings of essentially unlimited
+length although any two of them must fit into available memory at the same
+time.
+It should be noted that the access methods provide no guarantees about
+byte string alignment.
+.SH ERRORS
+The
+.I dbopen
+routine may fail and set
+.I errno
+for any of the errors specified for the library routines
+.IR open (2)
+and
+.IR malloc (3)
+or the following:
+.TP
+[EFTYPE]
+A file is incorrectly formatted.
+.TP
+[EINVAL]
+A parameter has been specified (hash function, pad byte etc.) that is
+incompatible with the current file specification or which is not
+meaningful for the function (for example, use of the cursor without
+prior initialization) or there is a mismatch between the version
+number of file and the software.
+.PP
+The
+.I close
+routines may fail and set
+.I errno
+for any of the errors specified for the library routines
+.IR close (2),
+.IR read (2),
+.IR write (2),
+.IR free (3),
+or
+.IR fsync (2).
+.PP
+The
+.IR del ,
+.IR get ,
+.I put
+and
+.I seq
+routines may fail and set
+.I errno
+for any of the errors specified for the library routines
+.IR read (2),
+.IR write (2),
+.IR free (3)
+or
+.IR malloc (3).
+.PP
+The
+.I fd
+routines will fail and set
+.I errno
+to ENOENT for in memory databases.
+.PP
+The
+.I sync
+routines may fail and set
+.I errno
+for any of the errors specified for the library routine
+.IR fsync (2).
+.SH "SEE ALSO"
+.IR btree (3),
+.IR hash (3),
+.IR mpool (3),
+.IR recno (3)
+.sp
+.IR "LIBTP: Portable, Modular Transactions for UNIX" ,
+Margo Seltzer, Michael Olson, USENIX proceedings, Winter 1992.
+.SH BUGS
+The typedef DBT is a mnemonic for ``data base thang'', and was used
+because noone could think of a reasonable name that wasn't already used.
+.PP
+The file descriptor interface is a kluge and will be deleted in a
+future version of the interface.
+.PP
+None of the access methods provide any form of concurrent access,
+locking, or transactions.
diff --git a/lib/libc/db/man/hash.3 b/lib/libc/db/man/hash.3
new file mode 100644
index 0000000..54e02ca
--- /dev/null
+++ b/lib/libc/db/man/hash.3
@@ -0,0 +1,160 @@
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)hash.3 8.6 (Berkeley) 8/18/94
+.\" $FreeBSD$
+.\"
+.TH HASH 3 "August 18, 1994"
+.UC 7
+.SH NAME
+hash \- hash database access method
+.SH SYNOPSIS
+.nf
+.ft B
+#include <sys/types.h>
+#include <db.h>
+.ft R
+.fi
+.SH DESCRIPTION
+The routine
+.IR dbopen
+is the library interface to database files.
+One of the supported file formats is hash files.
+The general description of the database access methods is in
+.IR dbopen (3),
+this manual page describes only the hash specific information.
+.PP
+The hash data structure is an extensible, dynamic hashing scheme.
+.PP
+The access method specific data structure provided to
+.I dbopen
+is defined in the <db.h> include file as follows:
+.sp
+typedef struct {
+.RS
+u_int bsize;
+.br
+u_int ffactor;
+.br
+u_int nelem;
+.br
+u_int cachesize;
+.br
+u_int32_t (*hash)(const void *, size_t);
+.br
+int lorder;
+.RE
+} HASHINFO;
+.PP
+The elements of this structure are as follows:
+.TP
+bsize
+.I Bsize
+defines the hash table bucket size, and is, by default, 256 bytes.
+It may be preferable to increase the page size for disk-resident tables
+and tables with large data items.
+.TP
+ffactor
+.I Ffactor
+indicates a desired density within the hash table.
+It is an approximation of the number of keys allowed to accumulate in any
+one bucket, determining when the hash table grows or shrinks.
+The default value is 8.
+.TP
+nelem
+.I Nelem
+is an estimate of the final size of the hash table.
+If not set or set too low, hash tables will expand gracefully as keys
+are entered, although a slight performance degradation may be noticed.
+The default value is 1.
+.TP
+cachesize
+A suggested maximum size, in bytes, of the memory cache.
+This value is
+.B only
+advisory, and the access method will allocate more memory rather
+than fail.
+.TP
+hash
+.I Hash
+is a user defined hash function.
+Since no hash function performs equally well on all possible data, the
+user may find that the built-in hash function does poorly on a particular
+data set.
+User specified hash functions must take two arguments (a pointer to a byte
+string and a length) and return a 32-bit quantity to be used as the hash
+value.
+.TP
+lorder
+The byte order for integers in the stored database metadata.
+The number should represent the order as an integer; for example,
+big endian order would be the number 4,321.
+If
+.I lorder
+is 0 (no order is specified) the current host order is used.
+If the file already exists, the specified value is ignored and the
+value specified when the tree was created is used.
+.PP
+If the file already exists (and the O_TRUNC flag is not specified), the
+values specified for the parameters bsize, ffactor, lorder and nelem are
+ignored and the values specified when the tree was created are used.
+.PP
+If a hash function is specified,
+.I hash_open
+will attempt to determine if the hash function specified is the same as
+the one with which the database was created, and will fail if it is not.
+.PP
+Backward compatible interfaces to the older
+.I dbm
+and
+.I ndbm
+routines are provided, however these interfaces are not compatible with
+previous file formats.
+.SH ERRORS
+The
+.I hash
+access method routines may fail and set
+.I errno
+for any of the errors specified for the library routine
+.IR dbopen (3).
+.SH "SEE ALSO"
+.IR btree (3),
+.IR dbopen (3),
+.IR mpool (3),
+.IR recno (3)
+.sp
+.IR "Dynamic Hash Tables" ,
+Per-Ake Larson, Communications of the ACM, April 1988.
+.sp
+.IR "A New Hash Package for UNIX" ,
+Margo Seltzer, USENIX Proceedings, Winter 1991.
+.SH BUGS
+Only big and little endian byte order is supported.
diff --git a/lib/libc/db/man/mpool.3 b/lib/libc/db/man/mpool.3
new file mode 100644
index 0000000..5174df6
--- /dev/null
+++ b/lib/libc/db/man/mpool.3
@@ -0,0 +1,220 @@
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mpool.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.TH MPOOL 3 "June 4, 1993"
+.UC 7
+.SH NAME
+mpool \- shared memory buffer pool
+.SH SYNOPSIS
+.nf
+.ft B
+#include <db.h>
+#include <mpool.h>
+
+MPOOL *
+mpool_open (DBT *key, int fd, pgno_t pagesize, pgno_t maxcache);
+
+void
+mpool_filter (MPOOL *mp, void (*pgin)(void *, pgno_t, void *),
+.ti +5
+void (*pgout)(void *, pgno_t, void *), void *pgcookie);
+
+void *
+mpool_new (MPOOL *mp, pgno_t *pgnoaddr);
+
+void *
+mpool_get (MPOOL *mp, pgno_t pgno, u_int flags);
+
+int
+mpool_put (MPOOL *mp, void *pgaddr, u_int flags);
+
+int
+mpool_sync (MPOOL *mp);
+
+int
+mpool_close (MPOOL *mp);
+.ft R
+.fi
+.SH DESCRIPTION
+.IR Mpool
+is the library interface intended to provide page oriented buffer management
+of files.
+The buffers may be shared between processes.
+.PP
+The function
+.I mpool_open
+initializes a memory pool.
+The
+.I key
+argument is the byte string used to negotiate between multiple
+processes wishing to share buffers.
+If the file buffers are mapped in shared memory, all processes using
+the same key will share the buffers.
+If
+.I key
+is NULL, the buffers are mapped into private memory.
+The
+.I fd
+argument is a file descriptor for the underlying file, which must be seekable.
+If
+.I key
+is non-NULL and matches a file already being mapped, the
+.I fd
+argument is ignored.
+.PP
+The
+.I pagesize
+argument is the size, in bytes, of the pages into which the file is broken up.
+The
+.I maxcache
+argument is the maximum number of pages from the underlying file to cache
+at any one time.
+This value is not relative to the number of processes which share a file's
+buffers, but will be the largest value specified by any of the processes
+sharing the file.
+.PP
+The
+.I mpool_filter
+function is intended to make transparent input and output processing of the
+pages possible.
+If the
+.I pgin
+function is specified, it is called each time a buffer is read into the memory
+pool from the backing file.
+If the
+.I pgout
+function is specified, it is called each time a buffer is written into the
+backing file.
+Both functions are called with the
+.I pgcookie
+pointer, the page number and a pointer to the page to being read or written.
+.PP
+The function
+.I mpool_new
+takes an MPOOL pointer and an address as arguments.
+If a new page can be allocated, a pointer to the page is returned and
+the page number is stored into the
+.I pgnoaddr
+address.
+Otherwise, NULL is returned and errno is set.
+.PP
+The function
+.I mpool_get
+takes a MPOOL pointer and a page number as arguments.
+If the page exists, a pointer to the page is returned.
+Otherwise, NULL is returned and errno is set.
+The flags parameter is not currently used.
+.PP
+The function
+.I mpool_put
+unpins the page referenced by
+.IR pgaddr .
+.I Pgaddr
+must be an address previously returned by
+.I mpool_get
+or
+.IR mpool_new .
+The flag value is specified by
+.IR or 'ing
+any of the following values:
+.TP
+MPOOL_DIRTY
+The page has been modified and needs to be written to the backing file.
+.PP
+.I Mpool_put
+returns 0 on success and -1 if an error occurs.
+.PP
+The function
+.I mpool_sync
+writes all modified pages associated with the MPOOL pointer to the
+backing file.
+.I Mpool_sync
+returns 0 on success and -1 if an error occurs.
+.PP
+The
+.I mpool_close
+function free's up any allocated memory associated with the memory pool
+cookie.
+Modified pages are
+.B not
+written to the backing file.
+.I Mpool_close
+returns 0 on success and -1 if an error occurs.
+.SH ERRORS
+The
+.I mpool_open
+function may fail and set
+.I errno
+for any of the errors specified for the library routine
+.IR malloc (3).
+.PP
+The
+.I mpool_get
+function may fail and set
+.I errno
+for the following:
+.TP 15
+[EINVAL]
+The requested record doesn't exist.
+.PP
+The
+.I mpool_new
+and
+.I mpool_get
+functions may fail and set
+.I errno
+for any of the errors specified for the library routines
+.IR read (2) ,
+.IR write (2) ,
+and
+.IR malloc (3).
+.PP
+The
+.I mpool_sync
+function may fail and set
+.I errno
+for any of the errors specified for the library routine
+.IR write (2).
+.PP
+The
+.I mpool_close
+function may fail and set
+.I errno
+for any of the errors specified for the library routine
+.IR free (3).
+.SH "SEE ALSO"
+.IR dbopen (3),
+.IR btree (3),
+.IR hash (3),
+.IR recno (3)
diff --git a/lib/libc/db/man/recno.3 b/lib/libc/db/man/recno.3
new file mode 100644
index 0000000..84b7e25
--- /dev/null
+++ b/lib/libc/db/man/recno.3
@@ -0,0 +1,217 @@
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)recno.3 8.5 (Berkeley) 8/18/94
+.\" $FreeBSD$
+.\"
+.TH RECNO 3 "August 18, 1994"
+.UC 7
+.SH NAME
+recno \- record number database access method
+.SH SYNOPSIS
+.nf
+.ft B
+#include <sys/types.h>
+#include <db.h>
+.ft R
+.fi
+.SH DESCRIPTION
+The routine
+.IR dbopen
+is the library interface to database files.
+One of the supported file formats is record number files.
+The general description of the database access methods is in
+.IR dbopen (3),
+this manual page describes only the recno specific information.
+.PP
+The record number data structure is either variable or fixed-length
+records stored in a flat-file format, accessed by the logical record
+number.
+The existence of record number five implies the existence of records
+one through four, and the deletion of record number one causes
+record number five to be renumbered to record number four, as well
+as the cursor, if positioned after record number one, to shift down
+one record.
+.PP
+The recno access method specific data structure provided to
+.I dbopen
+is defined in the <db.h> include file as follows:
+.PP
+typedef struct {
+.RS
+u_long flags;
+.br
+u_int cachesize;
+.br
+u_int psize;
+.br
+int lorder;
+.br
+size_t reclen;
+.br
+u_char bval;
+.br
+char *bfname;
+.RE
+} RECNOINFO;
+.PP
+The elements of this structure are defined as follows:
+.TP
+flags
+The flag value is specified by
+.IR or 'ing
+any of the following values:
+.RS
+.TP
+R_FIXEDLEN
+The records are fixed-length, not byte delimited.
+The structure element
+.I reclen
+specifies the length of the record, and the structure element
+.I bval
+is used as the pad character.
+Any records, inserted into the database, that are less than
+.I reclen
+bytes long are automatically padded.
+.TP
+R_NOKEY
+In the interface specified by
+.IR dbopen ,
+the sequential record retrieval fills in both the caller's key and
+data structures.
+If the R_NOKEY flag is specified, the
+.I cursor
+routines are not required to fill in the key structure.
+This permits applications to retrieve records at the end of files without
+reading all of the intervening records.
+.TP
+R_SNAPSHOT
+This flag requires that a snapshot of the file be taken when
+.I dbopen
+is called, instead of permitting any unmodified records to be read from
+the original file.
+.RE
+.TP
+cachesize
+A suggested maximum size, in bytes, of the memory cache.
+This value is
+.B only
+advisory, and the access method will allocate more memory rather than fail.
+If
+.I cachesize
+is 0 (no size is specified) a default cache is used.
+.TP
+psize
+The recno access method stores the in-memory copies of its records
+in a btree.
+This value is the size (in bytes) of the pages used for nodes in that tree.
+If
+.I psize
+is 0 (no page size is specified) a page size is chosen based on the
+underlying file system I/O block size.
+See
+.IR btree (3)
+for more information.
+.TP
+lorder
+The byte order for integers in the stored database metadata.
+The number should represent the order as an integer; for example,
+big endian order would be the number 4,321.
+If
+.I lorder
+is 0 (no order is specified) the current host order is used.
+.TP
+reclen
+The length of a fixed-length record.
+.TP
+bval
+The delimiting byte to be used to mark the end of a record for
+variable-length records, and the pad character for fixed-length
+records.
+If no value is specified, newlines (``\en'') are used to mark the end
+of variable-length records and fixed-length records are padded with
+spaces.
+.TP
+bfname
+The recno access method stores the in-memory copies of its records
+in a btree.
+If bfname is non-NULL, it specifies the name of the btree file,
+as if specified as the file name for a dbopen of a btree file.
+.PP
+The data part of the key/data pair used by the recno access method
+is the same as other access methods.
+The key is different.
+The
+.I data
+field of the key should be a pointer to a memory location of type
+.IR recno_t ,
+as defined in the <db.h> include file.
+This type is normally the largest unsigned integral type available to
+the implementation.
+The
+.I size
+field of the key should be the size of that type.
+.PP
+Because there can be no meta-data associated with the underlying
+recno access method files, any changes made to the default values
+(e.g. fixed record length or byte separator value) must be explicitly
+specified each time the file is opened.
+.PP
+In the interface specified by
+.IR dbopen ,
+using the
+.I put
+interface to create a new record will cause the creation of multiple,
+empty records if the record number is more than one greater than the
+largest record currently in the database.
+.SH ERRORS
+The
+.I recno
+access method routines may fail and set
+.I errno
+for any of the errors specified for the library routine
+.IR dbopen (3)
+or the following:
+.TP
+[EINVAL]
+An attempt was made to add a record to a fixed-length database that
+was too large to fit.
+.SH "SEE ALSO"
+.IR btree (3),
+.IR dbopen (3),
+.IR hash (3),
+.IR mpool (3)
+.sp
+.IR "Document Processing in a Relational Database System" ,
+Michael Stonebraker, Heidi Stettner, Joseph Kalash, Antonin Guttman,
+Nadene Lynn, Memorandum No. UCB/ERL M82/32, May 1982.
+.SH BUGS
+Only big and little endian byte order is supported.
diff --git a/lib/libc/db/mpool/Makefile.inc b/lib/libc/db/mpool/Makefile.inc
new file mode 100644
index 0000000..461e62a
--- /dev/null
+++ b/lib/libc/db/mpool/Makefile.inc
@@ -0,0 +1,6 @@
+# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libc/db/mpool
+
+SRCS+= mpool.c
diff --git a/lib/libc/db/mpool/README b/lib/libc/db/mpool/README
new file mode 100644
index 0000000..0f01fbc
--- /dev/null
+++ b/lib/libc/db/mpool/README
@@ -0,0 +1,7 @@
+# @(#)README 8.1 (Berkeley) 6/4/93
+
+These are the current memory pool routines.
+They aren't ready for prime time, yet, and
+the interface is expected to change.
+
+--keith
diff --git a/lib/libc/db/mpool/mpool.c b/lib/libc/db/mpool/mpool.c
new file mode 100644
index 0000000..a61041e
--- /dev/null
+++ b/lib/libc/db/mpool/mpool.c
@@ -0,0 +1,463 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)mpool.c 8.5 (Berkeley) 7/26/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <db.h>
+
+#define __MPOOLINTERFACE_PRIVATE
+#include <mpool.h>
+
+static BKT *mpool_bkt __P((MPOOL *));
+static BKT *mpool_look __P((MPOOL *, pgno_t));
+static int mpool_write __P((MPOOL *, BKT *));
+
+/*
+ * mpool_open --
+ * Initialize a memory pool.
+ */
+MPOOL *
+mpool_open(key, fd, pagesize, maxcache)
+ void *key;
+ int fd;
+ pgno_t pagesize, maxcache;
+{
+ struct stat sb;
+ MPOOL *mp;
+ int entry;
+
+ /*
+ * Get information about the file.
+ *
+ * XXX
+ * We don't currently handle pipes, although we should.
+ */
+ if (fstat(fd, &sb))
+ return (NULL);
+ if (!S_ISREG(sb.st_mode)) {
+ errno = ESPIPE;
+ return (NULL);
+ }
+
+ /* Allocate and initialize the MPOOL cookie. */
+ if ((mp = (MPOOL *)calloc(1, sizeof(MPOOL))) == NULL)
+ return (NULL);
+ CIRCLEQ_INIT(&mp->lqh);
+ for (entry = 0; entry < HASHSIZE; ++entry)
+ CIRCLEQ_INIT(&mp->hqh[entry]);
+ mp->maxcache = maxcache;
+ mp->npages = sb.st_size / pagesize;
+ mp->pagesize = pagesize;
+ mp->fd = fd;
+ return (mp);
+}
+
+/*
+ * mpool_filter --
+ * Initialize input/output filters.
+ */
+void
+mpool_filter(mp, pgin, pgout, pgcookie)
+ MPOOL *mp;
+ void (*pgin) __P((void *, pgno_t, void *));
+ void (*pgout) __P((void *, pgno_t, void *));
+ void *pgcookie;
+{
+ mp->pgin = pgin;
+ mp->pgout = pgout;
+ mp->pgcookie = pgcookie;
+}
+
+/*
+ * mpool_new --
+ * Get a new page of memory.
+ */
+void *
+mpool_new(mp, pgnoaddr)
+ MPOOL *mp;
+ pgno_t *pgnoaddr;
+{
+ struct _hqh *head;
+ BKT *bp;
+
+ if (mp->npages == MAX_PAGE_NUMBER) {
+ (void)fprintf(stderr, "mpool_new: page allocation overflow.\n");
+ abort();
+ }
+#ifdef STATISTICS
+ ++mp->pagenew;
+#endif
+ /*
+ * Get a BKT from the cache. Assign a new page number, attach
+ * it to the head of the hash chain, the tail of the lru chain,
+ * and return.
+ */
+ if ((bp = mpool_bkt(mp)) == NULL)
+ return (NULL);
+ *pgnoaddr = bp->pgno = mp->npages++;
+ bp->flags = MPOOL_PINNED;
+
+ head = &mp->hqh[HASHKEY(bp->pgno)];
+ CIRCLEQ_INSERT_HEAD(head, bp, hq);
+ CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
+ return (bp->page);
+}
+
+/*
+ * mpool_get
+ * Get a page.
+ */
+void *
+mpool_get(mp, pgno, flags)
+ MPOOL *mp;
+ pgno_t pgno;
+ u_int flags; /* XXX not used? */
+{
+ struct _hqh *head;
+ BKT *bp;
+ off_t off;
+ int nr;
+
+ /* Check for attempt to retrieve a non-existent page. */
+ if (pgno >= mp->npages) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+#ifdef STATISTICS
+ ++mp->pageget;
+#endif
+
+ /* Check for a page that is cached. */
+ if ((bp = mpool_look(mp, pgno)) != NULL) {
+#ifdef DEBUG
+ if (bp->flags & MPOOL_PINNED) {
+ (void)fprintf(stderr,
+ "mpool_get: page %d already pinned\n", bp->pgno);
+ abort();
+ }
+#endif
+ /*
+ * Move the page to the head of the hash chain and the tail
+ * of the lru chain.
+ */
+ head = &mp->hqh[HASHKEY(bp->pgno)];
+ CIRCLEQ_REMOVE(head, bp, hq);
+ CIRCLEQ_INSERT_HEAD(head, bp, hq);
+ CIRCLEQ_REMOVE(&mp->lqh, bp, q);
+ CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
+
+ /* Return a pinned page. */
+ bp->flags |= MPOOL_PINNED;
+ return (bp->page);
+ }
+
+ /* Get a page from the cache. */
+ if ((bp = mpool_bkt(mp)) == NULL)
+ return (NULL);
+
+ /* Read in the contents. */
+#ifdef STATISTICS
+ ++mp->pageread;
+#endif
+ off = mp->pagesize * pgno;
+ if (lseek(mp->fd, off, SEEK_SET) != off)
+ return (NULL);
+ if ((nr = read(mp->fd, bp->page, mp->pagesize)) != mp->pagesize) {
+ if (nr >= 0)
+ errno = EFTYPE;
+ return (NULL);
+ }
+
+ /* Set the page number, pin the page. */
+ bp->pgno = pgno;
+ bp->flags = MPOOL_PINNED;
+
+ /*
+ * Add the page to the head of the hash chain and the tail
+ * of the lru chain.
+ */
+ head = &mp->hqh[HASHKEY(bp->pgno)];
+ CIRCLEQ_INSERT_HEAD(head, bp, hq);
+ CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
+
+ /* Run through the user's filter. */
+ if (mp->pgin != NULL)
+ (mp->pgin)(mp->pgcookie, bp->pgno, bp->page);
+
+ return (bp->page);
+}
+
+/*
+ * mpool_put
+ * Return a page.
+ */
+int
+mpool_put(mp, page, flags)
+ MPOOL *mp;
+ void *page;
+ u_int flags;
+{
+ BKT *bp;
+
+#ifdef STATISTICS
+ ++mp->pageput;
+#endif
+ bp = (BKT *)((char *)page - sizeof(BKT));
+#ifdef DEBUG
+ if (!(bp->flags & MPOOL_PINNED)) {
+ (void)fprintf(stderr,
+ "mpool_put: page %d not pinned\n", bp->pgno);
+ abort();
+ }
+#endif
+ bp->flags &= ~MPOOL_PINNED;
+ bp->flags |= flags & MPOOL_DIRTY;
+ return (RET_SUCCESS);
+}
+
+/*
+ * mpool_close
+ * Close the buffer pool.
+ */
+int
+mpool_close(mp)
+ MPOOL *mp;
+{
+ BKT *bp;
+
+ /* Free up any space allocated to the lru pages. */
+ while ((bp = mp->lqh.cqh_first) != (void *)&mp->lqh) {
+ CIRCLEQ_REMOVE(&mp->lqh, mp->lqh.cqh_first, q);
+ free(bp);
+ }
+
+ /* Free the MPOOL cookie. */
+ free(mp);
+ return (RET_SUCCESS);
+}
+
+/*
+ * mpool_sync
+ * Sync the pool to disk.
+ */
+int
+mpool_sync(mp)
+ MPOOL *mp;
+{
+ BKT *bp;
+
+ /* Walk the lru chain, flushing any dirty pages to disk. */
+ for (bp = mp->lqh.cqh_first;
+ bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
+ if (bp->flags & MPOOL_DIRTY &&
+ mpool_write(mp, bp) == RET_ERROR)
+ return (RET_ERROR);
+
+ /* Sync the file descriptor. */
+ return (fsync(mp->fd) ? RET_ERROR : RET_SUCCESS);
+}
+
+/*
+ * mpool_bkt
+ * Get a page from the cache (or create one).
+ */
+static BKT *
+mpool_bkt(mp)
+ MPOOL *mp;
+{
+ struct _hqh *head;
+ BKT *bp;
+
+ /* If under the max cached, always create a new page. */
+ if (mp->curcache < mp->maxcache)
+ goto new;
+
+ /*
+ * If the cache is max'd out, walk the lru list for a buffer we
+ * can flush. If we find one, write it (if necessary) and take it
+ * off any lists. If we don't find anything we grow the cache anyway.
+ * The cache never shrinks.
+ */
+ for (bp = mp->lqh.cqh_first;
+ bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
+ if (!(bp->flags & MPOOL_PINNED)) {
+ /* Flush if dirty. */
+ if (bp->flags & MPOOL_DIRTY &&
+ mpool_write(mp, bp) == RET_ERROR)
+ return (NULL);
+#ifdef STATISTICS
+ ++mp->pageflush;
+#endif
+ /* Remove from the hash and lru queues. */
+ head = &mp->hqh[HASHKEY(bp->pgno)];
+ CIRCLEQ_REMOVE(head, bp, hq);
+ CIRCLEQ_REMOVE(&mp->lqh, bp, q);
+#ifdef DEBUG
+ { void *spage;
+ spage = bp->page;
+ memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
+ bp->page = spage;
+ }
+#endif
+ return (bp);
+ }
+
+new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL)
+ return (NULL);
+#ifdef STATISTICS
+ ++mp->pagealloc;
+#endif
+#if defined(DEBUG) || defined(PURIFY)
+ memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
+#endif
+ bp->page = (char *)bp + sizeof(BKT);
+ ++mp->curcache;
+ return (bp);
+}
+
+/*
+ * mpool_write
+ * Write a page to disk.
+ */
+static int
+mpool_write(mp, bp)
+ MPOOL *mp;
+ BKT *bp;
+{
+ off_t off;
+
+#ifdef STATISTICS
+ ++mp->pagewrite;
+#endif
+
+ /* Run through the user's filter. */
+ if (mp->pgout)
+ (mp->pgout)(mp->pgcookie, bp->pgno, bp->page);
+
+ off = mp->pagesize * bp->pgno;
+ if (lseek(mp->fd, off, SEEK_SET) != off)
+ return (RET_ERROR);
+ if (write(mp->fd, bp->page, mp->pagesize) != mp->pagesize)
+ return (RET_ERROR);
+
+ bp->flags &= ~MPOOL_DIRTY;
+ return (RET_SUCCESS);
+}
+
+/*
+ * mpool_look
+ * Lookup a page in the cache.
+ */
+static BKT *
+mpool_look(mp, pgno)
+ MPOOL *mp;
+ pgno_t pgno;
+{
+ struct _hqh *head;
+ BKT *bp;
+
+ head = &mp->hqh[HASHKEY(pgno)];
+ for (bp = head->cqh_first; bp != (void *)head; bp = bp->hq.cqe_next)
+ if (bp->pgno == pgno) {
+#ifdef STATISTICS
+ ++mp->cachehit;
+#endif
+ return (bp);
+ }
+#ifdef STATISTICS
+ ++mp->cachemiss;
+#endif
+ return (NULL);
+}
+
+#ifdef STATISTICS
+/*
+ * mpool_stat
+ * Print out cache statistics.
+ */
+void
+mpool_stat(mp)
+ MPOOL *mp;
+{
+ BKT *bp;
+ int cnt;
+ char *sep;
+
+ (void)fprintf(stderr, "%lu pages in the file\n", mp->npages);
+ (void)fprintf(stderr,
+ "page size %lu, cacheing %lu pages of %lu page max cache\n",
+ mp->pagesize, mp->curcache, mp->maxcache);
+ (void)fprintf(stderr, "%lu page puts, %lu page gets, %lu page new\n",
+ mp->pageput, mp->pageget, mp->pagenew);
+ (void)fprintf(stderr, "%lu page allocs, %lu page flushes\n",
+ mp->pagealloc, mp->pageflush);
+ if (mp->cachehit + mp->cachemiss)
+ (void)fprintf(stderr,
+ "%.0f%% cache hit rate (%lu hits, %lu misses)\n",
+ ((double)mp->cachehit / (mp->cachehit + mp->cachemiss))
+ * 100, mp->cachehit, mp->cachemiss);
+ (void)fprintf(stderr, "%lu page reads, %lu page writes\n",
+ mp->pageread, mp->pagewrite);
+
+ sep = "";
+ cnt = 0;
+ for (bp = mp->lqh.cqh_first;
+ bp != (void *)&mp->lqh; bp = bp->q.cqe_next) {
+ (void)fprintf(stderr, "%s%d", sep, bp->pgno);
+ if (bp->flags & MPOOL_DIRTY)
+ (void)fprintf(stderr, "d");
+ if (bp->flags & MPOOL_PINNED)
+ (void)fprintf(stderr, "P");
+ if (++cnt == 10) {
+ sep = "\n";
+ cnt = 0;
+ } else
+ sep = ", ";
+
+ }
+ (void)fprintf(stderr, "\n");
+}
+#endif
diff --git a/lib/libc/db/mpool/mpool.libtp b/lib/libc/db/mpool/mpool.libtp
new file mode 100644
index 0000000..bcd827d
--- /dev/null
+++ b/lib/libc/db/mpool/mpool.libtp
@@ -0,0 +1,746 @@
+/******************************************************************************
+
+VERSION $FreeBSD$
+PACKAGE: User Level Shared Memory Manager
+
+DESCRIPTION:
+ This package provides a buffer pool interface implemented as
+ a collection of file pages mapped into shared memory.
+
+ Based on Mark's buffer manager
+
+ROUTINES:
+ External
+ buf_alloc
+ buf_flags
+ buf_get
+ buf_init
+ buf_last
+ buf_open
+ buf_pin
+ buf_sync
+ buf_unpin
+ Internal
+ bf_assign_buf
+ bf_fid_to_fd
+ bf_newbuf
+ bf_put_page
+
+
+******************************************************************************/
+#include <sys/types.h>
+#include <assert.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <errno.h>
+#include "list.h"
+#include "user.h"
+#include "txn_sys.h"
+#include "buf.h"
+#include "semkeys.h"
+#include "error.h"
+
+/*
+ we need to translate between some type of file id that the user
+ process passes and a file descriptor. For now, it's a nop.
+*/
+#define GET_MASTER get_sem ( buf_spinlock )
+#define RELEASE_MASTER release_sem ( buf_spinlock )
+
+#define LRUID *buf_lru
+#define LRUP (bufhdr_table+*buf_lru)
+#define MRU bufhdr_table[*buf_lru].lru.prev
+
+/* Global indicator that you have started reusing buffers */
+int do_statistics = 0;
+/*
+ Process Statics (pointers into shared memory)
+*/
+static BUF_T *buf_table = 0;
+static BUFHDR_T *bufhdr_table;
+static int *buf_hash_table;
+static int *buf_lru; /* LRU is the free list */
+static int buf_spinlock;
+static FINFO_T *buf_fids;
+static int *buf_sp; /* Pointer to string free space */
+static char *buf_strings;
+
+/* Process Local FID->FD table */
+static int fds[NUM_FILE_ENTRIES];
+
+/* Static routines */
+static BUFHDR_T *bf_assign_buf();
+static int bf_fid_to_fd();
+static BUFHDR_T *bf_newbuf();
+static int bf_put_page();
+
+/*
+ Return 0 on success
+ 1 on failure
+*/
+extern int
+buf_init ( )
+{
+ ADDR_T buf_region;
+ BUFHDR_T *bhp;
+ int i;
+ int ref_count;
+ int *spinlockp;
+
+ /*
+ Initialize Process local structures
+ */
+ for ( i = 0; i < NUM_FILE_ENTRIES; i++ ) {
+ fds[i] = -1;
+ }
+
+ buf_region = attach_region ( BUF_REGION_NAME, BUF_REGION_NUM,
+ BUF_REGION_SIZE, &ref_count );
+ if ( !buf_region ) {
+ return (1);
+ }
+ error_log3 ( "Buf Region: ADDR: %d ID: %d SIZE: %d\n", buf_region,
+ BUF_REGION_NUM, BUF_REGION_SIZE );
+
+ buf_table = (BUF_T *)buf_region;
+ bufhdr_table = (BUFHDR_T *)(buf_table + NUM_BUFS);
+ buf_hash_table = (int *)(bufhdr_table + NUM_BUFS);
+ buf_lru = buf_hash_table + NUMTABLE_ENTRIES;
+ spinlockp = buf_lru + 1;
+ buf_fids = (FINFO_T *)(spinlockp+1);
+ buf_sp = (int *)(buf_fids + NUM_FILE_ENTRIES);
+ buf_strings = (char *)(buf_sp + 1);
+
+ /* Create locking spinlock (gets creating holding the lock) */
+ buf_spinlock = create_sem ( BUF_SPIN_NAME, BUF_SPIN_NUM, ref_count <= 1 );
+ if ( buf_spinlock < 0 ) {
+ return(1);
+ }
+ if ( ref_count <= 1 ) {
+ *spinlockp = buf_spinlock;
+
+ /* Now initialize the buffer manager */
+
+ /* 1. Free list */
+ *buf_lru = 0;
+
+ /* 2. Buffer headers */
+ for ( i = 0, bhp = bufhdr_table; i < NUM_BUFS; bhp++, i++ ) {
+ bhp->lru.next = i+1;
+ bhp->lru.prev = i-1;
+ bhp->flags = 0; /* All Flags off */
+ bhp->refcount = 0;
+ bhp->wait_proc = -1; /* No sleepers */
+ LISTPE_INIT ( hash, bhp, i ); /* Hash chains */
+ }
+ bufhdr_table[0].lru.prev = NUM_BUFS-1;
+ bufhdr_table[NUM_BUFS-1].lru.next = 0;
+
+ /* 3. Hash Table */
+ for ( i = 0; i < NUMTABLE_ENTRIES; i++ ) {
+ buf_hash_table[i] = NUM_BUFS;
+ }
+
+ /* 4. File ID Table */
+ for ( i = 0; i < NUM_FILE_ENTRIES; i++ ) {
+ buf_fids[i].offset = -1;
+ buf_fids[i].npages = -1;
+ buf_fids[i].refcount = 0;
+ }
+
+ /* 5. Free String Pointer */
+ *buf_sp = (FILE_NAME_LEN*NUM_FILE_ENTRIES);
+ if (RELEASE_MASTER) {
+ return(1);
+ }
+ error_log0 ( "Initialized buffer region\n" );
+ }
+ return (0);
+}
+
+extern void
+buf_exit()
+{
+ int ref;
+ int i;
+
+ /* Flush Buffer Pool on Exit */
+ for ( i = 0; i < NUM_FILE_ENTRIES; i++ ) {
+ if ( fds[i] != -1 ) {
+ close ( fds[i] );
+ }
+ }
+ if ( buf_table ) {
+ detach_region ( buf_table, BUF_REGION_NUM, BUF_REGION_SIZE, &ref );
+ }
+ return;
+}
+
+/*
+ We need an empty buffer. Find the LRU unpinned NON-Dirty page.
+*/
+static BUFHDR_T *
+bf_newbuf()
+{
+ int fd;
+ int lruid;
+ int nbytes;
+ int ndx;
+ BUFHDR_T *bhp;
+
+ lruid = LRUID;
+ for ( bhp = LRUP;
+ bhp->flags & (BUF_PINNED|BUF_IO_IN_PROGRESS);
+ bhp = LISTP_NEXTP (bufhdr_table, lru, bhp ) ) {
+
+ if ( bhp->lru.next == lruid ) {
+ /* OUT OF BUFFERS */
+ error_log1 ( "All buffers are pinned. %s\n",
+ "Unable to grant buffer request" );
+ return(NULL);
+ }
+ }
+ /* BHP can be used */
+ if ( bhp->flags & BUF_DIRTY ) {
+ do_statistics = 1;
+ /*
+ MIS Check for log flushed appropriately
+ */
+ fd = bf_fid_to_fd(bhp->id.file_id);
+ if ( fd == -1 ) {
+ error_log1 ("Invalid fid %d\n", bhp->id.file_id);
+ return(NULL);
+ }
+ if ( bf_put_page(fd, bhp) < 0 ) {
+ return(NULL);
+ }
+ }
+ /* Update Hash Pointers */
+ ndx = BUF_HASH ( bhp->id.file_id, bhp->id.obj_id );
+ LISTP_REMOVE(bufhdr_table, hash, bhp);
+ if ( buf_hash_table[ndx] == (bhp-bufhdr_table) ) {
+ if ( bhp->hash.next != (bhp-bufhdr_table) ) {
+ buf_hash_table[ndx] = bhp->hash.next;
+ } else {
+ buf_hash_table[ndx] = NUM_BUFS;
+ }
+ }
+ INIT_BUF(bhp);
+
+ return(bhp);
+}
+/*
+ buf_alloc
+
+ Add a page to a file and return a buffer for it.
+
+*/
+ADDR_T
+buf_alloc ( fid, new_pageno )
+int fid;
+int *new_pageno;
+{
+ BUFHDR_T *bhp;
+ int fd;
+ int len;
+ int ndx;
+ OBJ_T fobj;
+
+ if (GET_MASTER) {
+ return(NULL);
+ }
+ if ( buf_fids[fid].npages == -1 ) {
+ /* initialize npages field */
+ fd = bf_fid_to_fd ( fid );
+ }
+ assert (fid < NUM_FILE_ENTRIES);
+
+ *new_pageno = buf_fids[fid].npages;
+ if ( *new_pageno == -1 ) {
+ RELEASE_MASTER;
+ return ( NULL );
+ }
+ buf_fids[fid].npages++;
+ ndx = BUF_HASH ( fid, *new_pageno );
+ fobj.file_id = fid;
+ fobj.obj_id = *new_pageno;
+ bhp = bf_assign_buf ( ndx, &fobj, BF_PIN|BF_DIRTY|BF_EMPTY, &len );
+ if ( RELEASE_MASTER ) {
+ /* Memory leak */
+ return(NULL);
+ }
+ if ( bhp ) {
+ return ((ADDR_T)(buf_table+(bhp-bufhdr_table)));
+ } else {
+ return ( NULL );
+ }
+}
+
+
+/*
+ Buffer Flags
+ BF_DIRTY Mark page as dirty
+ BF_EMPTY Don't initialize page, just get buffer
+ BF_PIN Retrieve with pin
+
+MIS
+Might want to add a flag that sets an LSN for this buffer is the
+DIRTY flag is set
+
+Eventually, you may want a flag that indicates the I/O and lock
+request should be shipped off together, but not for now.
+*/
+extern ADDR_T
+buf_get ( file_id, page_id, flags, len )
+int file_id;
+int page_id;
+u_long flags;
+int *len; /* Number of bytes read into buffer */
+{
+ BUFHDR_T *bhp;
+ int bufid;
+ int fd;
+ int ndx;
+ int next_bufid;
+ int stat;
+ OBJ_T fobj;
+
+ ndx = BUF_HASH ( file_id, page_id );
+ fobj.file_id = (long) file_id;
+ fobj.obj_id = (long) page_id;
+ if ( GET_MASTER ) {
+ return(NULL);
+ }
+ /*
+ This could be a for loop, but we lose speed
+ by making all the cases general purpose so we
+ optimize for the no-collision case.
+ */
+ bufid = buf_hash_table[ndx];
+ if ( bufid < NUM_BUFS ) {
+ for ( bhp = bufhdr_table+bufid;
+ !OBJ_EQ (bhp->id, fobj) || !(bhp->flags & BUF_VALID);
+ bhp = LISTP_NEXTP ( bufhdr_table, hash, bhp ) ) {
+
+ if ( bhp->hash.next == bufid ) {
+ goto not_found;
+ }
+ }
+/* found */
+ if ( flags & BF_PIN ) {
+ bhp->flags |= BUF_PINNED;
+ bhp->refcount++;
+#ifdef PIN_DEBUG
+ fprintf(stderr, "buf_get: %X PINNED (%d)\n",
+ buf_table + (bhp-bufhdr_table), bhp->refcount);
+#endif
+ }
+ if ( flags & BF_DIRTY ) {
+ bhp->flags |= BUF_DIRTY;
+ }
+
+ while ( bhp->flags & BUF_IO_IN_PROGRESS ) {
+ /* MIS -- eventually err check here */
+#ifdef DEBUG
+ printf("About to sleep on %d (me: %d\n)\n", bhp->wait_proc,
+ my_txnp - txn_table);
+#endif
+#ifdef WAIT_STATS
+ buf_waits++;
+#endif
+ stat = proc_sleep_on ( &(bhp->wait_proc), buf_spinlock );
+ if ( stat ) {
+ /* Memory leak */
+ return(NULL);
+ }
+ if (!( bhp->flags & BUF_IO_IN_PROGRESS) &&
+ (!OBJ_EQ (bhp->id, fobj) || !(bhp->flags & BUF_VALID))) {
+ if (RELEASE_MASTER)
+ return(NULL);
+ return(buf_get ( file_id, page_id, flags, len ));
+ }
+ }
+ MAKE_MRU( bhp );
+ *len = BUFSIZE;
+ } else {
+not_found:
+ /* If you get here, the page isn't in the hash table */
+ bhp = bf_assign_buf ( ndx, &fobj, flags, len );
+ }
+ /* Common code between found and not found */
+
+ if ( bhp && bhp->flags & BUF_NEWPAGE ) {
+ *len = 0;
+ }
+ if (RELEASE_MASTER){
+ /* Memory leak */
+ return(NULL);
+ }
+ if ( bhp ) {
+ return ((ADDR_T)(buf_table+(bhp-bufhdr_table)));
+ } else {
+ return ( NULL );
+ }
+}
+
+/*
+ MIS - do I want to add file links to buffer pool?
+*/
+extern int
+buf_sync ( fid, close )
+int fid;
+int close; /* should we dec refcount and possibly
+ invalidate all the buffers */
+{
+ int i;
+ int fd;
+ int invalidate;
+ BUFHDR_T *bhp;
+
+ if ( (fd = bf_fid_to_fd ( fid )) < 0 ) {
+ return(1);
+ }
+ if (GET_MASTER) {
+ return(1);
+ }
+ invalidate = (buf_fids[fid].refcount == 1 && close);
+ if ( invalidate )
+ for ( bhp = bufhdr_table, i = 0; i < NUM_BUFS; bhp++, i++ ) {
+ if (bhp->id.file_id == fid) {
+ if ((bhp->flags & BF_DIRTY) && (bf_put_page( fd, bhp ) < 0)) {
+ return(1);
+ }
+ bhp->id.file_id = -1;
+ }
+ }
+ if (invalidate || close)
+ buf_fids[fid].refcount--;
+
+ if (RELEASE_MASTER) {
+ return(1);
+ }
+ return(0);
+
+
+}
+
+extern int
+buf_flags ( addr, set_flags, unset_flags )
+ADDR_T addr;
+u_long set_flags;
+u_long unset_flags;
+{
+ int bufid;
+ BUFHDR_T *bhp;
+
+#ifdef PIN_DEBUG
+ fprintf(stderr, "buf_flags: %X setting %s%s%s%s%s releasing %s%s%s%s%s\n",
+ addr,
+ set_flags&BUF_DIRTY ? "DIRTY " : "",
+ set_flags&BUF_VALID ? "VALID " : "",
+ set_flags&BUF_PINNED ? "PINNED " : "",
+ set_flags&BUF_IO_ERROR ? "IO_ERROR " : "",
+ set_flags&BUF_IO_IN_PROGRESS ? "IO_IN_PROG " : "",
+ set_flags&BUF_NEWPAGE ? "NEWPAGE " : "",
+ unset_flags&BUF_DIRTY ? "DIRTY " : "",
+ unset_flags&BUF_VALID ? "VALID " : "",
+ unset_flags&BUF_PINNED ? "PINNED " : "",
+ unset_flags&BUF_IO_ERROR ? "IO_ERROR " : "",
+ unset_flags&BUF_IO_IN_PROGRESS ? "IO_IN_PROG " : "",
+ unset_flags&BUF_NEWPAGE ? "NEWPAGE " : "" );
+#endif
+ if (!ADDR_OK(addr)) {
+ error_log1 ( "buf_pin: Invalid Buffer Address %x\n", addr );
+ return(1);
+ }
+ bufid = ((BUF_T *)addr) - buf_table;
+ assert ( bufid < NUM_BUFS);
+ bhp = &bufhdr_table[bufid];
+ if (GET_MASTER) {
+ return(1);
+ }
+ bhp->flags |= set_flags;
+ if ( set_flags & BUF_PINNED ) {
+ bhp->refcount++;
+ }
+ if ( set_flags & BUF_DIRTY ) {
+ unset_flags |= BUF_NEWPAGE;
+ }
+
+ if ( unset_flags & BUF_PINNED ) {
+ bhp->refcount--;
+ if ( bhp->refcount ) {
+ /* Turn off pin bit so it doesn't get unset */
+ unset_flags &= ~BUF_PINNED;
+ }
+ }
+ bhp->flags &= ~unset_flags;
+ MAKE_MRU(bhp);
+ if (RELEASE_MASTER) {
+ return(1);
+ }
+ return(0);
+}
+
+/*
+ Take a string name and produce an fid.
+
+ returns -1 on error
+
+ MIS -- this is a potential problem -- you keep actual names
+ here -- what if people run from different directories?
+*/
+extern int
+buf_name_lookup ( fname )
+char *fname;
+{
+ int i;
+ int fid;
+ int ndx;
+
+ fid = -1;
+ if (GET_MASTER) {
+ return(-1);
+ }
+ for ( i = 0; i < NUM_FILE_ENTRIES; i++ ) {
+ if ( buf_fids[i].offset == -1 ) {
+ fid = i;
+ } else {
+ if (!strcmp (fname, buf_strings+buf_fids[i].offset)) {
+ if (RELEASE_MASTER) {
+ return(-1);
+ }
+ buf_fids[i].refcount++;
+ return(i);
+ }
+ }
+ }
+ if ( fid == -1 ) {
+ error_log0 ( "No more file ID's\n" );
+ } else {
+ ndx = *buf_sp - strlen(fname) - 1;
+ if ( ndx < 0 ) {
+ error_log0 ( "Out of string space\n" );
+ fid = -1;
+ } else {
+ *buf_sp = ndx;
+ strcpy ( buf_strings+ndx, fname );
+ buf_fids[fid].offset = ndx;
+ }
+ buf_fids[fid].refcount = 1;
+ }
+ if (RELEASE_MASTER) {
+ return(-1);
+ }
+ return(fid);
+}
+
+static int
+bf_fid_to_fd ( fid )
+int fid;
+{
+ struct stat sbuf;
+
+ assert ( (fid < NUM_FILE_ENTRIES) && (buf_fids[fid].offset != -1) );
+ if ( fds[fid] != -1 ) {
+ return(fds[fid]);
+
+ }
+ fds[fid] = open ( buf_strings+buf_fids[fid].offset, O_RDWR|O_CREAT,
+ 0666 );
+ if ( fds[fid] < 0 ) {
+ error_log3 ( "Error Opening File %s FID: %d FD: %d. Errno = %d\n",
+ buf_strings+buf_fids[fid].offset, fid, fds[fid],
+ errno );
+ return(-1);
+ }
+ error_log3 ( "Opening File %s FID: %d FD: %d\n",
+ buf_strings+buf_fids[fid].offset, fid, fds[fid] );
+ if ( buf_fids[fid].npages == -1 ) {
+ /* Initialize the npages field */
+ if ( fstat ( fds[fid], &sbuf ) ) {
+ error_log3 ( "Error Fstating %s FID: %d. Errno = %d\n",
+ buf_strings+buf_fids[fid].offset, fid, errno );
+ } else {
+ buf_fids[fid].npages = ( sbuf.st_size / BUFSIZE );
+ }
+ }
+
+ return ( fds[fid] );
+}
+
+static int
+bf_put_page ( fd, bhp )
+int fd;
+BUFHDR_T *bhp;
+{
+ int nbytes;
+
+ assert ( (bhp-bufhdr_table) < NUM_BUFS );
+ if ( lseek ( fd, bhp->id.obj_id << BUFSHIFT, L_SET ) < 0 ) {
+ return(-1);
+ }
+ bhp->flags |= BUF_IO_IN_PROGRESS;
+ if (RELEASE_MASTER) {
+ return(-1);
+ }
+ nbytes = write(fd, buf_table[bhp-bufhdr_table], BUFSIZE);
+ if (GET_MASTER) {
+ return(-2);
+ }
+ if ( nbytes < 0 ) {
+ error_log1 ("Write failed with error code %d\n", errno);
+ return(-1);
+ } else if ( nbytes != BUFSIZE ) {
+ error_log1 ("Short write: %d bytes of %d\n", nbytes, BUFSIZE );
+ }
+ bhp->flags &= ~(BUF_DIRTY|BUF_IO_IN_PROGRESS);
+ return (0);
+}
+
+static BUFHDR_T *
+bf_assign_buf ( ndx, obj, flags, len )
+int ndx;
+OBJ_T *obj;
+u_long flags;
+int *len; /* Number of bytes read */
+{
+ BUFHDR_T *bhp;
+ int fd;
+
+ assert ( obj->file_id < NUM_FILE_ENTRIES );
+ bhp = bf_newbuf();
+ if ( !bhp ) {
+ return(NULL);
+ }
+ OBJ_ASSIGN ( (*obj), bhp->id );
+ if ( buf_hash_table[ndx] >= NUM_BUFS ) {
+ buf_hash_table[ndx] = bhp-bufhdr_table;
+ } else {
+ LISTPE_INSERT ( bufhdr_table, hash, bhp, buf_hash_table[ndx] );
+ }
+
+ bhp->flags |= BUF_VALID;
+ if ( flags & BF_PIN ) {
+ bhp->flags |= BUF_PINNED;
+ bhp->refcount++;
+#ifdef PIN_DEBUG
+ fprintf(stderr, "bf_assign_buf: %X PINNED (%d)\n",
+ buf_table + (bhp-bufhdr_table), bhp->refcount);
+#endif
+ }
+ fd = bf_fid_to_fd(obj->file_id);
+ if ( fd == -1 ) {
+ error_log1 ("Invalid fid %d\n", obj->file_id);
+ bhp->flags |= ~BUF_IO_ERROR;
+ return(NULL);
+ }
+ if ( obj->obj_id >= buf_fids[obj->file_id].npages) {
+ buf_fids[obj->file_id].npages = obj->obj_id+1;
+ *len = 0;
+ } else if ( flags & BF_EMPTY ) {
+ *len = 0;
+ } else {
+ bhp->flags |= BUF_IO_IN_PROGRESS;
+ if (RELEASE_MASTER) {
+ return(NULL);
+ }
+ if ( lseek ( fd, obj->obj_id << BUFSHIFT, L_SET ) < -1 ) {
+ error_log2 ("Unable to perform seek on file: %d to page %d",
+ obj->file_id, obj->obj_id );
+ bhp->flags &= ~BUF_IO_IN_PROGRESS;
+ bhp->flags |= ~BUF_IO_ERROR;
+ return(NULL);
+ }
+ *len = read(fd, buf_table[bhp-bufhdr_table], BUFSIZE);
+ if ( *len < 0 ) {
+ error_log2 ("Unable to perform read on file: %d to page %d",
+ obj->file_id, obj->obj_id );
+ bhp->flags &= ~BUF_IO_IN_PROGRESS;
+ bhp->flags |= ~BUF_IO_ERROR;
+ return(NULL);
+ }
+ if (GET_MASTER) {
+ return(NULL);
+ }
+ bhp->flags &= ~BUF_IO_IN_PROGRESS;
+ if ( bhp->wait_proc != -1 ) {
+ /* wake up waiter and anyone waiting on it */
+#ifdef DEBUG
+ printf("Waking transaction %d due to completed I/O\n",
+ bhp->wait_proc);
+#endif
+ proc_wake_id ( bhp->wait_proc );
+ bhp->wait_proc = -1;
+ }
+ MAKE_MRU(bhp);
+ }
+
+ if ( flags & BF_DIRTY ) {
+ bhp->flags |= BUF_DIRTY;
+ } else if ( *len < BUFSIZE ) {
+ bhp->flags |= BUF_NEWPAGE;
+ }
+ return ( bhp );
+}
+
+int
+buf_last ( fid )
+int fid;
+{
+ int val;
+
+ if (GET_MASTER) {
+ return(-1);
+ }
+ assert ( fid < NUM_FILE_ENTRIES );
+ if ( buf_fids[fid].npages == -1 ) {
+ /* initialize npages field */
+ (void) bf_fid_to_fd ( fid );
+ }
+ val = buf_fids[fid].npages;
+ if ( val ) {
+ val--; /* Convert to page number */
+ }
+ if (RELEASE_MASTER) {
+ return(-1);
+ }
+ return(val);
+}
+
+#ifdef DEBUG
+extern void
+buf_dump ( id, all )
+int id;
+int all;
+{
+ int i;
+ BUFHDR_T *bhp;
+
+ printf ( "LRU + %d\n", *buf_lru );
+ if ( all ) {
+ printf("ID\tFID\tPID\tLNEXT\tLPREV\tHNEXT\tHPREV\tSLEEP\tFLAG\tREFS\n");
+ for ( bhp = bufhdr_table, i = 0; i < NUM_BUFS; bhp++, i++ ) {
+ printf ( "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%x\t%d\n", i,
+ bhp->id.file_id, bhp->id.obj_id,
+ bhp->lru.next, bhp->lru.prev,
+ bhp->hash.next, bhp->hash.prev,
+ bhp->wait_proc, bhp->flags, bhp->refcount );
+ }
+ } else {
+ if ( id >= NUM_BUFS ) {
+ printf ( "Buffer ID (%d) too high\n", id );
+ return;
+ }
+ bhp = bufhdr_table+id;
+ printf ( "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%x\t%d\n", i,
+ bhp->id.file_id, bhp->id.obj_id,
+ bhp->lru.next, bhp->lru.prev,
+ bhp->hash.next, bhp->hash.prev,
+ bhp->wait_proc, bhp->flags, bhp->refcount );
+ }
+ return;
+}
+#endif
+
diff --git a/lib/libc/db/recno/Makefile.inc b/lib/libc/db/recno/Makefile.inc
new file mode 100644
index 0000000..295332e
--- /dev/null
+++ b/lib/libc/db/recno/Makefile.inc
@@ -0,0 +1,7 @@
+# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libc/db/recno
+
+SRCS+= rec_close.c rec_delete.c rec_get.c rec_open.c rec_put.c rec_search.c \
+ rec_seq.c rec_utils.c
diff --git a/lib/libc/db/recno/extern.h b/lib/libc/db/recno/extern.h
new file mode 100644
index 0000000..feed434
--- /dev/null
+++ b/lib/libc/db/recno/extern.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)extern.h 8.3 (Berkeley) 6/4/94
+ */
+
+#include "../btree/extern.h"
+
+int __rec_close __P((DB *));
+int __rec_delete __P((const DB *, const DBT *, u_int));
+int __rec_dleaf __P((BTREE *, PAGE *, u_int32_t));
+int __rec_fd __P((const DB *));
+int __rec_fmap __P((BTREE *, recno_t));
+int __rec_fout __P((BTREE *));
+int __rec_fpipe __P((BTREE *, recno_t));
+int __rec_get __P((const DB *, const DBT *, DBT *, u_int));
+int __rec_iput __P((BTREE *, recno_t, const DBT *, u_int));
+int __rec_put __P((const DB *dbp, DBT *, const DBT *, u_int));
+int __rec_ret __P((BTREE *, EPG *, recno_t, DBT *, DBT *));
+EPG *__rec_search __P((BTREE *, recno_t, enum SRCHOP));
+int __rec_seq __P((const DB *, DBT *, DBT *, u_int));
+int __rec_sync __P((const DB *, u_int));
+int __rec_vmap __P((BTREE *, recno_t));
+int __rec_vout __P((BTREE *));
+int __rec_vpipe __P((BTREE *, recno_t));
diff --git a/lib/libc/db/recno/rec_close.c b/lib/libc/db/recno/rec_close.c
new file mode 100644
index 0000000..1c124de
--- /dev/null
+++ b/lib/libc/db/recno/rec_close.c
@@ -0,0 +1,182 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_close.c 8.6 (Berkeley) 8/18/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/mman.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <db.h>
+#include "recno.h"
+
+/*
+ * __REC_CLOSE -- Close a recno tree.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__rec_close(dbp)
+ DB *dbp;
+{
+ BTREE *t;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ if (__rec_sync(dbp, 0) == RET_ERROR)
+ return (RET_ERROR);
+
+ /* Committed to closing. */
+ status = RET_SUCCESS;
+ if (F_ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize))
+ status = RET_ERROR;
+
+ if (!F_ISSET(t, R_INMEM))
+ if (F_ISSET(t, R_CLOSEFP)) {
+ if (fclose(t->bt_rfp))
+ status = RET_ERROR;
+ } else
+ if (close(t->bt_rfd))
+ status = RET_ERROR;
+
+ if (__bt_close(dbp) == RET_ERROR)
+ status = RET_ERROR;
+
+ return (status);
+}
+
+/*
+ * __REC_SYNC -- sync the recno tree to disk.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__rec_sync(dbp, flags)
+ const DB *dbp;
+ u_int flags;
+{
+ struct iovec iov[2];
+ BTREE *t;
+ DBT data, key;
+ off_t off;
+ recno_t scursor, trec;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ if (flags == R_RECNOSYNC)
+ return (__bt_sync(dbp, 0));
+
+ if (F_ISSET(t, R_RDONLY | R_INMEM) || !F_ISSET(t, R_MODIFIED))
+ return (RET_SUCCESS);
+
+ /* Read any remaining records into the tree. */
+ if (!F_ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
+ return (RET_ERROR);
+
+ /* Rewind the file descriptor. */
+ if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0)
+ return (RET_ERROR);
+
+ /* Save the cursor. */
+ scursor = t->bt_cursor.rcursor;
+
+ key.size = sizeof(recno_t);
+ key.data = &trec;
+
+ if (F_ISSET(t, R_FIXLEN)) {
+ /*
+ * We assume that fixed length records are all fixed length.
+ * Any that aren't are either EINVAL'd or corrected by the
+ * record put code.
+ */
+ status = (dbp->seq)(dbp, &key, &data, R_FIRST);
+ while (status == RET_SUCCESS) {
+ if (write(t->bt_rfd, data.data, data.size) != data.size)
+ return (RET_ERROR);
+ status = (dbp->seq)(dbp, &key, &data, R_NEXT);
+ }
+ } else {
+ iov[1].iov_base = (char *)&t->bt_bval;
+ iov[1].iov_len = 1;
+
+ status = (dbp->seq)(dbp, &key, &data, R_FIRST);
+ while (status == RET_SUCCESS) {
+ iov[0].iov_base = data.data;
+ iov[0].iov_len = data.size;
+ if (writev(t->bt_rfd, iov, 2) != data.size + 1)
+ return (RET_ERROR);
+ status = (dbp->seq)(dbp, &key, &data, R_NEXT);
+ }
+ }
+
+ /* Restore the cursor. */
+ t->bt_cursor.rcursor = scursor;
+
+ if (status == RET_ERROR)
+ return (RET_ERROR);
+ if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1)
+ return (RET_ERROR);
+ if (ftruncate(t->bt_rfd, off))
+ return (RET_ERROR);
+ F_CLR(t, R_MODIFIED);
+ return (RET_SUCCESS);
+}
diff --git a/lib/libc/db/recno/rec_delete.c b/lib/libc/db/recno/rec_delete.c
new file mode 100644
index 0000000..a16593d
--- /dev/null
+++ b/lib/libc/db/recno/rec_delete.c
@@ -0,0 +1,197 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_delete.c 8.7 (Berkeley) 7/14/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <db.h>
+#include "recno.h"
+
+static int rec_rdelete __P((BTREE *, recno_t));
+
+/*
+ * __REC_DELETE -- Delete the item(s) referenced by a key.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key to delete
+ * flags: R_CURSOR if deleting what the cursor references
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
+ */
+int
+__rec_delete(dbp, key, flags)
+ const DB *dbp;
+ const DBT *key;
+ u_int flags;
+{
+ BTREE *t;
+ recno_t nrec;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ switch(flags) {
+ case 0:
+ if ((nrec = *(recno_t *)key->data) == 0)
+ goto einval;
+ if (nrec > t->bt_nrecs)
+ return (RET_SPECIAL);
+ --nrec;
+ status = rec_rdelete(t, nrec);
+ break;
+ case R_CURSOR:
+ if (!F_ISSET(&t->bt_cursor, CURS_INIT))
+ goto einval;
+ if (t->bt_nrecs == 0)
+ return (RET_SPECIAL);
+ status = rec_rdelete(t, t->bt_cursor.rcursor - 1);
+ if (status == RET_SUCCESS)
+ --t->bt_cursor.rcursor;
+ break;
+ default:
+einval: errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if (status == RET_SUCCESS)
+ F_SET(t, B_MODIFIED | R_MODIFIED);
+ return (status);
+}
+
+/*
+ * REC_RDELETE -- Delete the data matching the specified key.
+ *
+ * Parameters:
+ * tree: tree
+ * nrec: record to delete
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
+ */
+static int
+rec_rdelete(t, nrec)
+ BTREE *t;
+ recno_t nrec;
+{
+ EPG *e;
+ PAGE *h;
+ int status;
+
+ /* Find the record; __rec_search pins the page. */
+ if ((e = __rec_search(t, nrec, SDELETE)) == NULL)
+ return (RET_ERROR);
+
+ /* Delete the record. */
+ h = e->page;
+ status = __rec_dleaf(t, h, e->index);
+ if (status != RET_SUCCESS) {
+ mpool_put(t->bt_mp, h, 0);
+ return (status);
+ }
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ return (RET_SUCCESS);
+}
+
+/*
+ * __REC_DLEAF -- Delete a single record from a recno leaf page.
+ *
+ * Parameters:
+ * t: tree
+ * index: index on current page to delete
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__rec_dleaf(t, h, index)
+ BTREE *t;
+ PAGE *h;
+ u_int32_t index;
+{
+ RLEAF *rl;
+ indx_t *ip, cnt, offset;
+ u_int32_t nbytes;
+ char *from;
+ void *to;
+
+ /*
+ * Delete a record from a recno leaf page. Internal records are never
+ * deleted from internal pages, regardless of the records that caused
+ * them to be added being deleted. Pages made empty by deletion are
+ * not reclaimed. They are, however, made available for reuse.
+ *
+ * Pack the remaining entries at the end of the page, shift the indices
+ * down, overwriting the deleted record and its index. If the record
+ * uses overflow pages, make them available for reuse.
+ */
+ to = rl = GETRLEAF(h, index);
+ if (rl->flags & P_BIGDATA && __ovfl_delete(t, rl->bytes) == RET_ERROR)
+ return (RET_ERROR);
+ nbytes = NRLEAF(rl);
+
+ /*
+ * Compress the key/data pairs. Compress and adjust the [BR]LEAF
+ * offsets. Reset the headers.
+ */
+ from = (char *)h + h->upper;
+ memmove(from + nbytes, from, (char *)to - from);
+ h->upper += nbytes;
+
+ offset = h->linp[index];
+ for (cnt = &h->linp[index] - (ip = &h->linp[0]); cnt--; ++ip)
+ if (ip[0] < offset)
+ ip[0] += nbytes;
+ for (cnt = &h->linp[NEXTINDEX(h)] - ip; --cnt; ++ip)
+ ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
+ h->lower -= sizeof(indx_t);
+ --t->bt_nrecs;
+ return (RET_SUCCESS);
+}
diff --git a/lib/libc/db/recno/rec_get.c b/lib/libc/db/recno/rec_get.c
new file mode 100644
index 0000000..0a8b880
--- /dev/null
+++ b/lib/libc/db/recno/rec_get.c
@@ -0,0 +1,311 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_get.c 8.9 (Berkeley) 8/18/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <db.h>
+#include "recno.h"
+
+/*
+ * __REC_GET -- Get a record from the btree.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key to find
+ * data: data to return
+ * flag: currently unused
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
+ */
+int
+__rec_get(dbp, key, data, flags)
+ const DB *dbp;
+ const DBT *key;
+ DBT *data;
+ u_int flags;
+{
+ BTREE *t;
+ EPG *e;
+ recno_t nrec;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* Get currently doesn't take any flags, and keys of 0 are illegal. */
+ if (flags || (nrec = *(recno_t *)key->data) == 0) {
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ /*
+ * If we haven't seen this record yet, try to find it in the
+ * original file.
+ */
+ if (nrec > t->bt_nrecs) {
+ if (F_ISSET(t, R_EOF | R_INMEM))
+ return (RET_SPECIAL);
+ if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
+ return (status);
+ }
+
+ --nrec;
+ if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
+ return (RET_ERROR);
+
+ status = __rec_ret(t, e, 0, NULL, data);
+ if (F_ISSET(t, B_DB_LOCK))
+ mpool_put(t->bt_mp, e->page, 0);
+ else
+ t->bt_pinned = e->page;
+ return (status);
+}
+
+/*
+ * __REC_FPIPE -- Get fixed length records from a pipe.
+ *
+ * Parameters:
+ * t: tree
+ * cnt: records to read
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__rec_fpipe(t, top)
+ BTREE *t;
+ recno_t top;
+{
+ DBT data;
+ recno_t nrec;
+ size_t len;
+ int ch;
+ u_char *p;
+
+ if (t->bt_rdata.size < t->bt_reclen) {
+ t->bt_rdata.data = t->bt_rdata.data == NULL ?
+ malloc(t->bt_reclen) :
+ reallocf(t->bt_rdata.data, t->bt_reclen);
+ if (t->bt_rdata.data == NULL)
+ return (RET_ERROR);
+ t->bt_rdata.size = t->bt_reclen;
+ }
+ data.data = t->bt_rdata.data;
+ data.size = t->bt_reclen;
+
+ for (nrec = t->bt_nrecs; nrec < top;) {
+ len = t->bt_reclen;
+ for (p = t->bt_rdata.data;; *p++ = ch)
+ if ((ch = getc(t->bt_rfp)) == EOF || !--len) {
+ if (ch != EOF)
+ *p = ch;
+ if (len != 0)
+ memset(p, t->bt_bval, len);
+ if (__rec_iput(t,
+ nrec, &data, 0) != RET_SUCCESS)
+ return (RET_ERROR);
+ ++nrec;
+ break;
+ }
+ if (ch == EOF)
+ break;
+ }
+ if (nrec < top) {
+ F_SET(t, R_EOF);
+ return (RET_SPECIAL);
+ }
+ return (RET_SUCCESS);
+}
+
+/*
+ * __REC_VPIPE -- Get variable length records from a pipe.
+ *
+ * Parameters:
+ * t: tree
+ * cnt: records to read
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__rec_vpipe(t, top)
+ BTREE *t;
+ recno_t top;
+{
+ DBT data;
+ recno_t nrec;
+ indx_t len;
+ size_t sz;
+ int bval, ch;
+ u_char *p;
+
+ bval = t->bt_bval;
+ for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
+ for (p = t->bt_rdata.data,
+ sz = t->bt_rdata.size;; *p++ = ch, --sz) {
+ if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
+ data.data = t->bt_rdata.data;
+ data.size = p - (u_char *)t->bt_rdata.data;
+ if (ch == EOF && data.size == 0)
+ break;
+ if (__rec_iput(t, nrec, &data, 0)
+ != RET_SUCCESS)
+ return (RET_ERROR);
+ break;
+ }
+ if (sz == 0) {
+ len = p - (u_char *)t->bt_rdata.data;
+ t->bt_rdata.size += (sz = 256);
+ t->bt_rdata.data = t->bt_rdata.data == NULL ?
+ malloc(t->bt_rdata.size) :
+ reallocf(t->bt_rdata.data, t->bt_rdata.size);
+ if (t->bt_rdata.data == NULL)
+ return (RET_ERROR);
+ p = (u_char *)t->bt_rdata.data + len;
+ }
+ }
+ if (ch == EOF)
+ break;
+ }
+ if (nrec < top) {
+ F_SET(t, R_EOF);
+ return (RET_SPECIAL);
+ }
+ return (RET_SUCCESS);
+}
+
+/*
+ * __REC_FMAP -- Get fixed length records from a file.
+ *
+ * Parameters:
+ * t: tree
+ * cnt: records to read
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__rec_fmap(t, top)
+ BTREE *t;
+ recno_t top;
+{
+ DBT data;
+ recno_t nrec;
+ u_char *sp, *ep, *p;
+ size_t len;
+
+ if (t->bt_rdata.size < t->bt_reclen) {
+ t->bt_rdata.data = t->bt_rdata.data == NULL ?
+ malloc(t->bt_reclen) :
+ reallocf(t->bt_rdata.data, t->bt_reclen);
+ if (t->bt_rdata.data == NULL)
+ return (RET_ERROR);
+ t->bt_rdata.size = t->bt_reclen;
+ }
+ data.data = t->bt_rdata.data;
+ data.size = t->bt_reclen;
+
+ sp = (u_char *)t->bt_cmap;
+ ep = (u_char *)t->bt_emap;
+ for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
+ if (sp >= ep) {
+ F_SET(t, R_EOF);
+ return (RET_SPECIAL);
+ }
+ len = t->bt_reclen;
+ for (p = t->bt_rdata.data;
+ sp < ep && len > 0; *p++ = *sp++, --len);
+ if (len != 0)
+ memset(p, t->bt_bval, len);
+ if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
+ return (RET_ERROR);
+ }
+ t->bt_cmap = (caddr_t)sp;
+ return (RET_SUCCESS);
+}
+
+/*
+ * __REC_VMAP -- Get variable length records from a file.
+ *
+ * Parameters:
+ * t: tree
+ * cnt: records to read
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__rec_vmap(t, top)
+ BTREE *t;
+ recno_t top;
+{
+ DBT data;
+ u_char *sp, *ep;
+ recno_t nrec;
+ int bval;
+
+ sp = (u_char *)t->bt_cmap;
+ ep = (u_char *)t->bt_emap;
+ bval = t->bt_bval;
+
+ for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
+ if (sp >= ep) {
+ F_SET(t, R_EOF);
+ return (RET_SPECIAL);
+ }
+ for (data.data = sp; sp < ep && *sp != bval; ++sp);
+ data.size = sp - (u_char *)data.data;
+ if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
+ return (RET_ERROR);
+ ++sp;
+ }
+ t->bt_cmap = (caddr_t)sp;
+ return (RET_SUCCESS);
+}
diff --git a/lib/libc/db/recno/rec_open.c b/lib/libc/db/recno/rec_open.c
new file mode 100644
index 0000000..8f8eff2
--- /dev/null
+++ b/lib/libc/db/recno/rec_open.c
@@ -0,0 +1,241 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_open.c 8.10 (Berkeley) 9/1/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <db.h>
+#include "recno.h"
+
+DB *
+__rec_open(fname, flags, mode, openinfo, dflags)
+ const char *fname;
+ int flags, mode, dflags;
+ const RECNOINFO *openinfo;
+{
+ BTREE *t;
+ BTREEINFO btopeninfo;
+ DB *dbp;
+ PAGE *h;
+ struct stat sb;
+ int rfd, sverrno;
+
+ /* Open the user's file -- if this fails, we're done. */
+ if (fname != NULL && (rfd = open(fname, flags, mode)) < 0)
+ return (NULL);
+
+ /* Create a btree in memory (backed by disk). */
+ dbp = NULL;
+ if (openinfo) {
+ if (openinfo->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT))
+ goto einval;
+ btopeninfo.flags = 0;
+ btopeninfo.cachesize = openinfo->cachesize;
+ btopeninfo.maxkeypage = 0;
+ btopeninfo.minkeypage = 0;
+ btopeninfo.psize = openinfo->psize;
+ btopeninfo.compare = NULL;
+ btopeninfo.prefix = NULL;
+ btopeninfo.lorder = openinfo->lorder;
+ dbp = __bt_open(openinfo->bfname,
+ O_RDWR, S_IRUSR | S_IWUSR, &btopeninfo, dflags);
+ } else
+ dbp = __bt_open(NULL, O_RDWR, S_IRUSR | S_IWUSR, NULL, dflags);
+ if (dbp == NULL)
+ goto err;
+
+ /*
+ * Some fields in the tree structure are recno specific. Fill them
+ * in and make the btree structure look like a recno structure. We
+ * don't change the bt_ovflsize value, it's close enough and slightly
+ * bigger.
+ */
+ t = dbp->internal;
+ if (openinfo) {
+ if (openinfo->flags & R_FIXEDLEN) {
+ F_SET(t, R_FIXLEN);
+ t->bt_reclen = openinfo->reclen;
+ if (t->bt_reclen == 0)
+ goto einval;
+ }
+ t->bt_bval = openinfo->bval;
+ } else
+ t->bt_bval = '\n';
+
+ F_SET(t, R_RECNO);
+ if (fname == NULL)
+ F_SET(t, R_EOF | R_INMEM);
+ else
+ t->bt_rfd = rfd;
+
+ if (fname != NULL) {
+ /*
+ * In 4.4BSD, stat(2) returns true for ISSOCK on pipes.
+ * Unfortunately, that's not portable, so we use lseek
+ * and check the errno values.
+ */
+ errno = 0;
+ if (lseek(rfd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) {
+ switch (flags & O_ACCMODE) {
+ case O_RDONLY:
+ F_SET(t, R_RDONLY);
+ break;
+ default:
+ goto einval;
+ }
+slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL)
+ goto err;
+ F_SET(t, R_CLOSEFP);
+ t->bt_irec =
+ F_ISSET(t, R_FIXLEN) ? __rec_fpipe : __rec_vpipe;
+ } else {
+ switch (flags & O_ACCMODE) {
+ case O_RDONLY:
+ F_SET(t, R_RDONLY);
+ break;
+ case O_RDWR:
+ break;
+ default:
+ goto einval;
+ }
+
+ if (fstat(rfd, &sb))
+ goto err;
+ /*
+ * Kluge -- we'd like to test to see if the file is too
+ * big to mmap. Since, we don't know what size or type
+ * off_t's or size_t's are, what the largest unsigned
+ * integral type is, or what random insanity the local
+ * C compiler will perpetrate, doing the comparison in
+ * a portable way is flatly impossible. Hope that mmap
+ * fails if the file is too large.
+ */
+ if (sb.st_size == 0)
+ F_SET(t, R_EOF);
+ else {
+#ifdef MMAP_NOT_AVAILABLE
+ /*
+ * XXX
+ * Mmap doesn't work correctly on many current
+ * systems. In particular, it can fail subtly,
+ * with cache coherency problems. Don't use it
+ * for now.
+ */
+ t->bt_msize = sb.st_size;
+ if ((t->bt_smap = mmap(NULL, t->bt_msize,
+ PROT_READ, MAP_PRIVATE, rfd,
+ (off_t)0)) == MAP_FAILED)
+ goto slow;
+ t->bt_cmap = t->bt_smap;
+ t->bt_emap = t->bt_smap + sb.st_size;
+ t->bt_irec = F_ISSET(t, R_FIXLEN) ?
+ __rec_fmap : __rec_vmap;
+ F_SET(t, R_MEMMAPPED);
+#else
+ goto slow;
+#endif
+ }
+ }
+ }
+
+ /* Use the recno routines. */
+ dbp->close = __rec_close;
+ dbp->del = __rec_delete;
+ dbp->fd = __rec_fd;
+ dbp->get = __rec_get;
+ dbp->put = __rec_put;
+ dbp->seq = __rec_seq;
+ dbp->sync = __rec_sync;
+
+ /* If the root page was created, reset the flags. */
+ if ((h = mpool_get(t->bt_mp, P_ROOT, 0)) == NULL)
+ goto err;
+ if ((h->flags & P_TYPE) == P_BLEAF) {
+ F_CLR(h, P_TYPE);
+ F_SET(h, P_RLEAF);
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ } else
+ mpool_put(t->bt_mp, h, 0);
+
+ if (openinfo && openinfo->flags & R_SNAPSHOT &&
+ !F_ISSET(t, R_EOF | R_INMEM) &&
+ t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
+ goto err;
+ return (dbp);
+
+einval: errno = EINVAL;
+err: sverrno = errno;
+ if (dbp != NULL)
+ (void)__bt_close(dbp);
+ if (fname != NULL)
+ (void)close(rfd);
+ errno = sverrno;
+ return (NULL);
+}
+
+int
+__rec_fd(dbp)
+ const DB *dbp;
+{
+ BTREE *t;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* In-memory database can't have a file descriptor. */
+ if (F_ISSET(t, R_INMEM)) {
+ errno = ENOENT;
+ return (-1);
+ }
+ return (t->bt_rfd);
+}
diff --git a/lib/libc/db/recno/rec_put.c b/lib/libc/db/recno/rec_put.c
new file mode 100644
index 0000000..0a5bddf
--- /dev/null
+++ b/lib/libc/db/recno/rec_put.c
@@ -0,0 +1,279 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_put.c 8.7 (Berkeley) 8/18/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "recno.h"
+
+/*
+ * __REC_PUT -- Add a recno item to the tree.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key
+ * data: data
+ * flag: R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is
+ * already in the tree and R_NOOVERWRITE specified.
+ */
+int
+__rec_put(dbp, key, data, flags)
+ const DB *dbp;
+ DBT *key;
+ const DBT *data;
+ u_int flags;
+{
+ BTREE *t;
+ DBT fdata, tdata;
+ recno_t nrec;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /*
+ * If using fixed-length records, and the record is long, return
+ * EINVAL. If it's short, pad it out. Use the record data return
+ * memory, it's only short-term.
+ */
+ if (F_ISSET(t, R_FIXLEN) && data->size != t->bt_reclen) {
+ if (data->size > t->bt_reclen)
+ goto einval;
+
+ if (t->bt_rdata.size < t->bt_reclen) {
+ t->bt_rdata.data =
+ reallocf(t->bt_rdata.data, t->bt_reclen);
+ if (t->bt_rdata.data == NULL)
+ return (RET_ERROR);
+ t->bt_rdata.size = t->bt_reclen;
+ }
+ memmove(t->bt_rdata.data, data->data, data->size);
+ memset((char *)t->bt_rdata.data + data->size,
+ t->bt_bval, t->bt_reclen - data->size);
+ fdata.data = t->bt_rdata.data;
+ fdata.size = t->bt_reclen;
+ } else {
+ fdata.data = data->data;
+ fdata.size = data->size;
+ }
+
+ switch (flags) {
+ case R_CURSOR:
+ if (!F_ISSET(&t->bt_cursor, CURS_INIT))
+ goto einval;
+ nrec = t->bt_cursor.rcursor;
+ break;
+ case R_SETCURSOR:
+ if ((nrec = *(recno_t *)key->data) == 0)
+ goto einval;
+ break;
+ case R_IAFTER:
+ if ((nrec = *(recno_t *)key->data) == 0) {
+ nrec = 1;
+ flags = R_IBEFORE;
+ }
+ break;
+ case 0:
+ case R_IBEFORE:
+ if ((nrec = *(recno_t *)key->data) == 0)
+ goto einval;
+ break;
+ case R_NOOVERWRITE:
+ if ((nrec = *(recno_t *)key->data) == 0)
+ goto einval;
+ if (nrec <= t->bt_nrecs)
+ return (RET_SPECIAL);
+ break;
+ default:
+einval: errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ /*
+ * Make sure that records up to and including the put record are
+ * already in the database. If skipping records, create empty ones.
+ */
+ if (nrec > t->bt_nrecs) {
+ if (!F_ISSET(t, R_EOF | R_INMEM) &&
+ t->bt_irec(t, nrec) == RET_ERROR)
+ return (RET_ERROR);
+ if (nrec > t->bt_nrecs + 1) {
+ if (F_ISSET(t, R_FIXLEN)) {
+ if ((tdata.data =
+ (void *)malloc(t->bt_reclen)) == NULL)
+ return (RET_ERROR);
+ tdata.size = t->bt_reclen;
+ memset(tdata.data, t->bt_bval, tdata.size);
+ } else {
+ tdata.data = NULL;
+ tdata.size = 0;
+ }
+ while (nrec > t->bt_nrecs + 1)
+ if (__rec_iput(t,
+ t->bt_nrecs, &tdata, 0) != RET_SUCCESS)
+ return (RET_ERROR);
+ if (F_ISSET(t, R_FIXLEN))
+ free(tdata.data);
+ }
+ }
+
+ if ((status = __rec_iput(t, nrec - 1, &fdata, flags)) != RET_SUCCESS)
+ return (status);
+
+ if (flags == R_SETCURSOR)
+ t->bt_cursor.rcursor = nrec;
+
+ F_SET(t, R_MODIFIED);
+ return (__rec_ret(t, NULL, nrec, key, NULL));
+}
+
+/*
+ * __REC_IPUT -- Add a recno item to the tree.
+ *
+ * Parameters:
+ * t: tree
+ * nrec: record number
+ * data: data
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__rec_iput(t, nrec, data, flags)
+ BTREE *t;
+ recno_t nrec;
+ const DBT *data;
+ u_int flags;
+{
+ DBT tdata;
+ EPG *e;
+ PAGE *h;
+ indx_t index, nxtindex;
+ pgno_t pg;
+ u_int32_t nbytes;
+ int dflags, status;
+ char *dest, db[NOVFLSIZE];
+
+ /*
+ * If the data won't fit on a page, store it on indirect pages.
+ *
+ * XXX
+ * If the insert fails later on, these pages aren't recovered.
+ */
+ if (data->size > t->bt_ovflsize) {
+ if (__ovfl_put(t, data, &pg) == RET_ERROR)
+ return (RET_ERROR);
+ tdata.data = db;
+ tdata.size = NOVFLSIZE;
+ *(pgno_t *)db = pg;
+ *(u_int32_t *)(db + sizeof(pgno_t)) = data->size;
+ dflags = P_BIGDATA;
+ data = &tdata;
+ } else
+ dflags = 0;
+
+ /* __rec_search pins the returned page. */
+ if ((e = __rec_search(t, nrec,
+ nrec > t->bt_nrecs || flags == R_IAFTER || flags == R_IBEFORE ?
+ SINSERT : SEARCH)) == NULL)
+ return (RET_ERROR);
+
+ h = e->page;
+ index = e->index;
+
+ /*
+ * Add the specified key/data pair to the tree. The R_IAFTER and
+ * R_IBEFORE flags insert the key after/before the specified key.
+ *
+ * Pages are split as required.
+ */
+ switch (flags) {
+ case R_IAFTER:
+ ++index;
+ break;
+ case R_IBEFORE:
+ break;
+ default:
+ if (nrec < t->bt_nrecs &&
+ __rec_dleaf(t, h, index) == RET_ERROR) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_ERROR);
+ }
+ break;
+ }
+
+ /*
+ * If not enough room, split the page. The split code will insert
+ * the key and data and unpin the current page. If inserting into
+ * the offset array, shift the pointers up.
+ */
+ nbytes = NRLEAFDBT(data->size);
+ if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
+ status = __bt_split(t, h, NULL, data, dflags, nbytes, index);
+ if (status == RET_SUCCESS)
+ ++t->bt_nrecs;
+ return (status);
+ }
+
+ if (index < (nxtindex = NEXTINDEX(h)))
+ memmove(h->linp + index + 1, h->linp + index,
+ (nxtindex - index) * sizeof(indx_t));
+ h->lower += sizeof(indx_t);
+
+ h->linp[index] = h->upper -= nbytes;
+ dest = (char *)h + h->upper;
+ WR_RLEAF(dest, data, dflags);
+
+ ++t->bt_nrecs;
+ F_SET(t, B_MODIFIED);
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+
+ return (RET_SUCCESS);
+}
diff --git a/lib/libc/db/recno/rec_search.c b/lib/libc/db/recno/rec_search.c
new file mode 100644
index 0000000..acc109e
--- /dev/null
+++ b/lib/libc/db/recno/rec_search.c
@@ -0,0 +1,126 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_search.c 8.4 (Berkeley) 7/14/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+
+#include <db.h>
+#include "recno.h"
+
+/*
+ * __REC_SEARCH -- Search a btree for a key.
+ *
+ * Parameters:
+ * t: tree to search
+ * recno: key to find
+ * op: search operation
+ *
+ * Returns:
+ * EPG for matching record, if any, or the EPG for the location of the
+ * key, if it were inserted into the tree.
+ *
+ * Returns:
+ * The EPG for matching record, if any, or the EPG for the location
+ * of the key, if it were inserted into the tree, is entered into
+ * the bt_cur field of the tree. A pointer to the field is returned.
+ */
+EPG *
+__rec_search(t, recno, op)
+ BTREE *t;
+ recno_t recno;
+ enum SRCHOP op;
+{
+ register indx_t index;
+ register PAGE *h;
+ EPGNO *parent;
+ RINTERNAL *r;
+ pgno_t pg;
+ indx_t top;
+ recno_t total;
+ int sverrno;
+
+ BT_CLR(t);
+ for (pg = P_ROOT, total = 0;;) {
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ goto err;
+ if (h->flags & P_RLEAF) {
+ t->bt_cur.page = h;
+ t->bt_cur.index = recno - total;
+ return (&t->bt_cur);
+ }
+ for (index = 0, top = NEXTINDEX(h);;) {
+ r = GETRINTERNAL(h, index);
+ if (++index == top || total + r->nrecs > recno)
+ break;
+ total += r->nrecs;
+ }
+
+ BT_PUSH(t, pg, index - 1);
+
+ pg = r->pgno;
+ switch (op) {
+ case SDELETE:
+ --GETRINTERNAL(h, (index - 1))->nrecs;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ break;
+ case SINSERT:
+ ++GETRINTERNAL(h, (index - 1))->nrecs;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ break;
+ case SEARCH:
+ mpool_put(t->bt_mp, h, 0);
+ break;
+ }
+
+ }
+ /* Try and recover the tree. */
+err: sverrno = errno;
+ if (op != SEARCH)
+ while ((parent = BT_POP(t)) != NULL) {
+ if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
+ break;
+ if (op == SINSERT)
+ --GETRINTERNAL(h, parent->index)->nrecs;
+ else
+ ++GETRINTERNAL(h, parent->index)->nrecs;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ }
+ errno = sverrno;
+ return (NULL);
+}
diff --git a/lib/libc/db/recno/rec_seq.c b/lib/libc/db/recno/rec_seq.c
new file mode 100644
index 0000000..f80992c
--- /dev/null
+++ b/lib/libc/db/recno/rec_seq.c
@@ -0,0 +1,131 @@
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)rec_seq.c 8.3 (Berkeley) 7/14/94";
+#endif /* not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <db.h>
+#include "recno.h"
+
+/*
+ * __REC_SEQ -- Recno sequential scan interface.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key for positioning and return value
+ * data: data return value
+ * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
+ */
+int
+__rec_seq(dbp, key, data, flags)
+ const DB *dbp;
+ DBT *key, *data;
+ u_int flags;
+{
+ BTREE *t;
+ EPG *e;
+ recno_t nrec;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ switch(flags) {
+ case R_CURSOR:
+ if ((nrec = *(recno_t *)key->data) == 0)
+ goto einval;
+ break;
+ case R_NEXT:
+ if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
+ nrec = t->bt_cursor.rcursor + 1;
+ break;
+ }
+ /* FALLTHROUGH */
+ case R_FIRST:
+ nrec = 1;
+ break;
+ case R_PREV:
+ if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
+ if ((nrec = t->bt_cursor.rcursor - 1) == 0)
+ return (RET_SPECIAL);
+ break;
+ }
+ /* FALLTHROUGH */
+ case R_LAST:
+ if (!F_ISSET(t, R_EOF | R_INMEM) &&
+ t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
+ return (RET_ERROR);
+ nrec = t->bt_nrecs;
+ break;
+ default:
+einval: errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) {
+ if (!F_ISSET(t, R_EOF | R_INMEM) &&
+ (status = t->bt_irec(t, nrec)) != RET_SUCCESS)
+ return (status);
+ if (t->bt_nrecs == 0 || nrec > t->bt_nrecs)
+ return (RET_SPECIAL);
+ }
+
+ if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL)
+ return (RET_ERROR);
+
+ F_SET(&t->bt_cursor, CURS_INIT);
+ t->bt_cursor.rcursor = nrec;
+
+ status = __rec_ret(t, e, nrec, key, data);
+ if (F_ISSET(t, B_DB_LOCK))
+ mpool_put(t->bt_mp, e->page, 0);
+ else
+ t->bt_pinned = e->page;
+ return (status);
+}
diff --git a/lib/libc/db/recno/rec_utils.c b/lib/libc/db/recno/rec_utils.c
new file mode 100644
index 0000000..baea3fa
--- /dev/null
+++ b/lib/libc/db/recno/rec_utils.c
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_utils.c 8.6 (Berkeley) 7/16/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "recno.h"
+
+/*
+ * __rec_ret --
+ * Build return data.
+ *
+ * Parameters:
+ * t: tree
+ * e: key/data pair to be returned
+ * nrec: record number
+ * key: user's key structure
+ * data: user's data structure
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__rec_ret(t, e, nrec, key, data)
+ BTREE *t;
+ EPG *e;
+ recno_t nrec;
+ DBT *key, *data;
+{
+ RLEAF *rl;
+ void *p;
+
+ if (key == NULL)
+ goto dataonly;
+
+ /* We have to copy the key, it's not on the page. */
+ if (sizeof(recno_t) > t->bt_rkey.size) {
+ p = (void *)(t->bt_rkey.data == NULL ?
+ malloc(sizeof(recno_t)) :
+ realloc(t->bt_rkey.data, sizeof(recno_t)));
+ if (p == NULL)
+ return (RET_ERROR);
+ t->bt_rkey.data = p;
+ t->bt_rkey.size = sizeof(recno_t);
+ }
+ memmove(t->bt_rkey.data, &nrec, sizeof(recno_t));
+ key->size = sizeof(recno_t);
+ key->data = t->bt_rkey.data;
+
+dataonly:
+ if (data == NULL)
+ return (RET_SUCCESS);
+
+ /*
+ * We must copy big keys/data to make them contigous. Otherwise,
+ * leave the page pinned and don't copy unless the user specified
+ * concurrent access.
+ */
+ rl = GETRLEAF(e->page, e->index);
+ if (rl->flags & P_BIGDATA) {
+ if (__ovfl_get(t, rl->bytes,
+ &data->size, &t->bt_rdata.data, &t->bt_rdata.size))
+ return (RET_ERROR);
+ data->data = t->bt_rdata.data;
+ } else if (F_ISSET(t, B_DB_LOCK)) {
+ /* Use +1 in case the first record retrieved is 0 length. */
+ if (rl->dsize + 1 > t->bt_rdata.size) {
+ p = (void *)(t->bt_rdata.data == NULL ?
+ malloc(rl->dsize + 1) :
+ realloc(t->bt_rdata.data, rl->dsize + 1));
+ if (p == NULL)
+ return (RET_ERROR);
+ t->bt_rdata.data = p;
+ t->bt_rdata.size = rl->dsize + 1;
+ }
+ memmove(t->bt_rdata.data, rl->bytes, rl->dsize);
+ data->size = rl->dsize;
+ data->data = t->bt_rdata.data;
+ } else {
+ data->size = rl->dsize;
+ data->data = rl->bytes;
+ }
+ return (RET_SUCCESS);
+}
diff --git a/lib/libc/db/recno/recno.h b/lib/libc/db/recno/recno.h
new file mode 100644
index 0000000..bec772c
--- /dev/null
+++ b/lib/libc/db/recno/recno.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)recno.h 8.1 (Berkeley) 6/4/93
+ */
+
+enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */
+
+#include "../btree/btree.h"
+#include "extern.h"
diff --git a/lib/libc/db/test/Makefile b/lib/libc/db/test/Makefile
new file mode 100644
index 0000000..7ea5302
--- /dev/null
+++ b/lib/libc/db/test/Makefile
@@ -0,0 +1,23 @@
+# @(#)Makefile 8.15 (Berkeley) 7/28/94
+
+PROG= dbtest
+OBJS= dbtest.o strerror.o
+
+# Uncomment the STAT line get hash and btree statistical use info. This
+# also forces ld to load the btree debug functions for use by gdb, which
+# is useful. The db library has to be compiled with -DSTATISTICS as well.
+INC= -I${PORTDIR}/include -I${PORTDIR}
+OORG= -g
+#STAT= -DSTATISTICS
+CFLAGS= -D__DBINTERFACE_PRIVATE -DDEBUG ${STAT} ${OORG} ${INC}
+
+dbtest: ${OBJS} ${PORTDIR}/libdb.a
+ ${CC} -o ${.TARGET} ${OBJS} ${PORTDIR}/libdb.a
+
+strerror.o: ${PORTDIR}/clib/strerror.c
+ ${CC} -c ${PORTDIR}/clib/strerror.c
+
+clean:
+ rm -f dbtest.core gmon.out ${OBJS} ${PROG} t1 t2 t3
+
+${OBJS}: Makefile
diff --git a/lib/libc/db/test/README b/lib/libc/db/test/README
new file mode 100644
index 0000000..0c0cd13
--- /dev/null
+++ b/lib/libc/db/test/README
@@ -0,0 +1,74 @@
+# @(#)README 8.8 (Berkeley) 7/31/94
+
+To build this portably, try something like:
+
+ make PORTDIR="../PORT/MACH"
+
+where MACH is the machine, i.e. "sunos.4.1.1".
+
+To run the tests, enter "sh run.test". If your system dictionary isn't
+in /usr/share/dict/words, edit run.test to reflect the correct place.
+
+Fairly large files (the command files) are built in this directory during
+the test runs, and even larger files (the database files) are created in
+"/var/tmp". If the latter directory doesn't exist, set the environmental
+variable TMPDIR to a directory where the files can be built.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+The script file consists of lines with an initial character which is
+the command for that line, or an initial character indicating a key
+or data entry for a previous command.
+
+Legal command characters are as follows:
+
+c: compare a record
+ + must be followed by [kK][dD]; the data value in the database
+ associated with the specified key is compared to the specified
+ data value.
+e: echo a string
+ + writes out the rest of the line into the output file; if the
+ last character is not a carriage-return, a newline is appended.
+f: set the flags for the next command
+ + no value zero's the flags
+g: do a get command
+ + must be followed by [kK]
+ + writes out the retrieved data DBT.
+o [r]: dump [reverse]
+ + dump the database out, if 'r' is set, in reverse order.
+p: do a put command
+ + must be followed by [kK][dD]
+r: do a del command
+ + must be followed by [kK] unless R_CURSOR flag set.
+S: sync the database
+s: do a seq command
+ + must be followed by [kK] if R_CURSOR flag set.
+ + writes out the retrieved data DBT.
+
+Legal key/data characters are as follows:
+
+D [file]: data file
+ + set the current data value to the contents of the file
+d [data]:
+ + set the current key value to the contents of the line.
+K [file]: key file
+ + set the current key value to the contents of the file
+k [data]:
+ + set the current key value to the contents of the line.
+
+Blank lines, lines with leading white space, and lines with leading
+hash marks (#) are ignored.
+
+Options to dbtest are as follows:
+
+ -d: Set the DB_LOCK flag.
+ -f: Use the file argument as the database file.
+ -i: Use the rest of the argument to set elements in the info
+ structure. If the type is btree, then "-i cachesize=10240"
+ will set BTREEINFO.cachesize to 10240.
+ -o: The rest of the argument is the output file instead of
+ using stdout.
+ -s: Don't delete the database file before opening it, i.e.
+ use the database file from a previous run.
+
+Dbtest requires two arguments, the type of access "hash", "recno"
+or "btree", and the script name or "-" to indicate stdin.
diff --git a/lib/libc/db/test/btree.tests/main.c b/lib/libc/db/test/btree.tests/main.c
new file mode 100644
index 0000000..39c1da0
--- /dev/null
+++ b/lib/libc/db/test/btree.tests/main.c
@@ -0,0 +1,765 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <fcntl.h>
+#include <db.h>
+#include <errno.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "btree.h"
+
+typedef struct cmd_table {
+ char *cmd;
+ int nargs;
+ int rconv;
+ void (*func) __P((DB *, char **));
+ char *usage, *descrip;
+} cmd_table;
+
+int stopstop;
+DB *globaldb;
+
+void append __P((DB *, char **));
+void bstat __P((DB *, char **));
+void cursor __P((DB *, char **));
+void delcur __P((DB *, char **));
+void delete __P((DB *, char **));
+void dump __P((DB *, char **));
+void first __P((DB *, char **));
+void get __P((DB *, char **));
+void help __P((DB *, char **));
+void iafter __P((DB *, char **));
+void ibefore __P((DB *, char **));
+void icursor __P((DB *, char **));
+void insert __P((DB *, char **));
+void keydata __P((DBT *, DBT *));
+void last __P((DB *, char **));
+void list __P((DB *, char **));
+void load __P((DB *, char **));
+void mstat __P((DB *, char **));
+void next __P((DB *, char **));
+int parse __P((char *, char **, int));
+void previous __P((DB *, char **));
+void show __P((DB *, char **));
+void usage __P((void));
+void user __P((DB *));
+
+cmd_table commands[] = {
+ "?", 0, 0, help, "help", NULL,
+ "a", 2, 1, append, "append key def", "append key with data def",
+ "b", 0, 0, bstat, "bstat", "stat btree",
+ "c", 1, 1, cursor, "cursor word", "move cursor to word",
+ "delc", 0, 0, delcur, "delcur", "delete key the cursor references",
+ "dele", 1, 1, delete, "delete word", "delete word",
+ "d", 0, 0, dump, "dump", "dump database",
+ "f", 0, 0, first, "first", "move cursor to first record",
+ "g", 1, 1, get, "get key", "locate key",
+ "h", 0, 0, help, "help", "print command summary",
+ "ia", 2, 1, iafter, "iafter key data", "insert data after key",
+ "ib", 2, 1, ibefore, "ibefore key data", "insert data before key",
+ "ic", 2, 1, icursor, "icursor key data", "replace cursor",
+ "in", 2, 1, insert, "insert key def", "insert key with data def",
+ "la", 0, 0, last, "last", "move cursor to last record",
+ "li", 1, 1, list, "list file", "list to a file",
+ "loa", 1, 0, load, "load file", NULL,
+ "loc", 1, 1, get, "get key", NULL,
+ "m", 0, 0, mstat, "mstat", "stat memory pool",
+ "n", 0, 0, next, "next", "move cursor forward one record",
+ "p", 0, 0, previous, "previous", "move cursor back one record",
+ "q", 0, 0, NULL, "quit", "quit",
+ "sh", 1, 0, show, "show page", "dump a page",
+ { NULL },
+};
+
+int recno; /* use record numbers */
+char *dict = "words"; /* default dictionary */
+char *progname;
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ DB *db;
+ BTREEINFO b;
+
+ progname = *argv;
+
+ b.flags = 0;
+ b.cachesize = 0;
+ b.maxkeypage = 0;
+ b.minkeypage = 0;
+ b.psize = 0;
+ b.compare = NULL;
+ b.prefix = NULL;
+ b.lorder = 0;
+
+ while ((c = getopt(argc, argv, "bc:di:lp:ru")) != EOF) {
+ switch (c) {
+ case 'b':
+ b.lorder = BIG_ENDIAN;
+ break;
+ case 'c':
+ b.cachesize = atoi(optarg);
+ break;
+ case 'd':
+ b.flags |= R_DUP;
+ break;
+ case 'i':
+ dict = optarg;
+ break;
+ case 'l':
+ b.lorder = LITTLE_ENDIAN;
+ break;
+ case 'p':
+ b.psize = atoi(optarg);
+ break;
+ case 'r':
+ recno = 1;
+ break;
+ case 'u':
+ b.flags = 0;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (recno)
+ db = dbopen(*argv == NULL ? NULL : *argv, O_RDWR,
+ 0, DB_RECNO, NULL);
+ else
+ db = dbopen(*argv == NULL ? NULL : *argv, O_CREAT|O_RDWR,
+ 0600, DB_BTREE, &b);
+
+ if (db == NULL) {
+ (void)fprintf(stderr, "dbopen: %s\n", strerror(errno));
+ exit(1);
+ }
+ globaldb = db;
+ user(db);
+ exit(0);
+ /* NOTREACHED */
+}
+
+void
+user(db)
+ DB *db;
+{
+ FILE *ifp;
+ int argc, i, last;
+ char *lbuf, *argv[4], buf[512];
+
+ if ((ifp = fopen("/dev/tty", "r")) == NULL) {
+ (void)fprintf(stderr,
+ "/dev/tty: %s\n", strerror(errno));
+ exit(1);
+ }
+ for (last = 0;;) {
+ (void)printf("> ");
+ (void)fflush(stdout);
+ if ((lbuf = fgets(&buf[0], 512, ifp)) == NULL)
+ break;
+ if (lbuf[0] == '\n') {
+ i = last;
+ goto uselast;
+ }
+ lbuf[strlen(lbuf) - 1] = '\0';
+
+ if (lbuf[0] == 'q')
+ break;
+
+ argc = parse(lbuf, &argv[0], 3);
+ if (argc == 0)
+ continue;
+
+ for (i = 0; commands[i].cmd != NULL; i++)
+ if (strncmp(commands[i].cmd, argv[0],
+ strlen(commands[i].cmd)) == 0)
+ break;
+
+ if (commands[i].cmd == NULL) {
+ (void)fprintf(stderr,
+ "%s: command unknown ('help' for help)\n", lbuf);
+ continue;
+ }
+
+ if (commands[i].nargs != argc - 1) {
+ (void)fprintf(stderr, "usage: %s\n", commands[i].usage);
+ continue;
+ }
+
+ if (recno && commands[i].rconv) {
+ static recno_t nlong;
+ nlong = atoi(argv[1]);
+ argv[1] = (char *)&nlong;
+ }
+uselast: last = i;
+ (*commands[i].func)(db, argv);
+ }
+ if ((db->sync)(db) == RET_ERROR)
+ perror("dbsync");
+ else if ((db->close)(db) == RET_ERROR)
+ perror("dbclose");
+}
+
+int
+parse(lbuf, argv, maxargc)
+ char *lbuf, **argv;
+ int maxargc;
+{
+ int argc = 0;
+ char *c;
+
+ c = lbuf;
+ while (isspace(*c))
+ c++;
+ while (*c != '\0' && argc < maxargc) {
+ *argv++ = c;
+ argc++;
+ while (!isspace(*c) && *c != '\0') {
+ c++;
+ }
+ while (isspace(*c))
+ *c++ = '\0';
+ }
+ return (argc);
+}
+
+void
+append(db, argv)
+ DB *db;
+ char **argv;
+{
+ DBT key, data;
+ int status;
+
+ if (!recno) {
+ (void)fprintf(stderr,
+ "append only available for recno db's.\n");
+ return;
+ }
+ key.data = argv[1];
+ key.size = sizeof(recno_t);
+ data.data = argv[2];
+ data.size = strlen(data.data);
+ status = (db->put)(db, &key, &data, R_APPEND);
+ switch (status) {
+ case RET_ERROR:
+ perror("append/put");
+ break;
+ case RET_SPECIAL:
+ (void)printf("%s (duplicate key)\n", argv[1]);
+ break;
+ case RET_SUCCESS:
+ break;
+ }
+}
+
+void
+cursor(db, argv)
+ DB *db;
+ char **argv;
+{
+ DBT data, key;
+ int status;
+
+ key.data = argv[1];
+ if (recno)
+ key.size = sizeof(recno_t);
+ else
+ key.size = strlen(argv[1]) + 1;
+ status = (*db->seq)(db, &key, &data, R_CURSOR);
+ switch (status) {
+ case RET_ERROR:
+ perror("cursor/seq");
+ break;
+ case RET_SPECIAL:
+ (void)printf("key not found\n");
+ break;
+ case RET_SUCCESS:
+ keydata(&key, &data);
+ break;
+ }
+}
+
+void
+delcur(db, argv)
+ DB *db;
+ char **argv;
+{
+ int status;
+
+ status = (*db->del)(db, NULL, R_CURSOR);
+
+ if (status == RET_ERROR)
+ perror("delcur/del");
+}
+
+void
+delete(db, argv)
+ DB *db;
+ char **argv;
+{
+ DBT key;
+ int status;
+
+ key.data = argv[1];
+ if (recno)
+ key.size = sizeof(recno_t);
+ else
+ key.size = strlen(argv[1]) + 1;
+
+ status = (*db->del)(db, &key, 0);
+ switch (status) {
+ case RET_ERROR:
+ perror("delete/del");
+ break;
+ case RET_SPECIAL:
+ (void)printf("key not found\n");
+ break;
+ case RET_SUCCESS:
+ break;
+ }
+}
+
+void
+dump(db, argv)
+ DB *db;
+ char **argv;
+{
+ __bt_dump(db);
+}
+
+void
+first(db, argv)
+ DB *db;
+ char **argv;
+{
+ DBT data, key;
+ int status;
+
+ status = (*db->seq)(db, &key, &data, R_FIRST);
+
+ switch (status) {
+ case RET_ERROR:
+ perror("first/seq");
+ break;
+ case RET_SPECIAL:
+ (void)printf("no more keys\n");
+ break;
+ case RET_SUCCESS:
+ keydata(&key, &data);
+ break;
+ }
+}
+
+void
+get(db, argv)
+ DB *db;
+ char **argv;
+{
+ DBT data, key;
+ int status;
+
+ key.data = argv[1];
+ if (recno)
+ key.size = sizeof(recno_t);
+ else
+ key.size = strlen(argv[1]) + 1;
+
+ status = (*db->get)(db, &key, &data, 0);
+
+ switch (status) {
+ case RET_ERROR:
+ perror("get/get");
+ break;
+ case RET_SPECIAL:
+ (void)printf("key not found\n");
+ break;
+ case RET_SUCCESS:
+ keydata(&key, &data);
+ break;
+ }
+}
+
+void
+help(db, argv)
+ DB *db;
+ char **argv;
+{
+ int i;
+
+ for (i = 0; commands[i].cmd; i++)
+ if (commands[i].descrip)
+ (void)printf("%s: %s\n",
+ commands[i].usage, commands[i].descrip);
+}
+
+void
+iafter(db, argv)
+ DB *db;
+ char **argv;
+{
+ DBT key, data;
+ int status;
+
+ if (!recno) {
+ (void)fprintf(stderr,
+ "iafter only available for recno db's.\n");
+ return;
+ }
+ key.data = argv[1];
+ key.size = sizeof(recno_t);
+ data.data = argv[2];
+ data.size = strlen(data.data);
+ status = (db->put)(db, &key, &data, R_IAFTER);
+ switch (status) {
+ case RET_ERROR:
+ perror("iafter/put");
+ break;
+ case RET_SPECIAL:
+ (void)printf("%s (duplicate key)\n", argv[1]);
+ break;
+ case RET_SUCCESS:
+ break;
+ }
+}
+
+void
+ibefore(db, argv)
+ DB *db;
+ char **argv;
+{
+ DBT key, data;
+ int status;
+
+ if (!recno) {
+ (void)fprintf(stderr,
+ "ibefore only available for recno db's.\n");
+ return;
+ }
+ key.data = argv[1];
+ key.size = sizeof(recno_t);
+ data.data = argv[2];
+ data.size = strlen(data.data);
+ status = (db->put)(db, &key, &data, R_IBEFORE);
+ switch (status) {
+ case RET_ERROR:
+ perror("ibefore/put");
+ break;
+ case RET_SPECIAL:
+ (void)printf("%s (duplicate key)\n", argv[1]);
+ break;
+ case RET_SUCCESS:
+ break;
+ }
+}
+
+void
+icursor(db, argv)
+ DB *db;
+ char **argv;
+{
+ int status;
+ DBT data, key;
+
+ key.data = argv[1];
+ if (recno)
+ key.size = sizeof(recno_t);
+ else
+ key.size = strlen(argv[1]) + 1;
+ data.data = argv[2];
+ data.size = strlen(argv[2]) + 1;
+
+ status = (*db->put)(db, &key, &data, R_CURSOR);
+ switch (status) {
+ case RET_ERROR:
+ perror("icursor/put");
+ break;
+ case RET_SPECIAL:
+ (void)printf("%s (duplicate key)\n", argv[1]);
+ break;
+ case RET_SUCCESS:
+ break;
+ }
+}
+
+void
+insert(db, argv)
+ DB *db;
+ char **argv;
+{
+ int status;
+ DBT data, key;
+
+ key.data = argv[1];
+ if (recno)
+ key.size = sizeof(recno_t);
+ else
+ key.size = strlen(argv[1]) + 1;
+ data.data = argv[2];
+ data.size = strlen(argv[2]) + 1;
+
+ status = (*db->put)(db, &key, &data, R_NOOVERWRITE);
+ switch (status) {
+ case RET_ERROR:
+ perror("insert/put");
+ break;
+ case RET_SPECIAL:
+ (void)printf("%s (duplicate key)\n", argv[1]);
+ break;
+ case RET_SUCCESS:
+ break;
+ }
+}
+
+void
+last(db, argv)
+ DB *db;
+ char **argv;
+{
+ DBT data, key;
+ int status;
+
+ status = (*db->seq)(db, &key, &data, R_LAST);
+
+ switch (status) {
+ case RET_ERROR:
+ perror("last/seq");
+ break;
+ case RET_SPECIAL:
+ (void)printf("no more keys\n");
+ break;
+ case RET_SUCCESS:
+ keydata(&key, &data);
+ break;
+ }
+}
+
+void
+list(db, argv)
+ DB *db;
+ char **argv;
+{
+ DBT data, key;
+ FILE *fp;
+ int status;
+
+ if ((fp = fopen(argv[1], "w")) == NULL) {
+ (void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));
+ return;
+ }
+ status = (*db->seq)(db, &key, &data, R_FIRST);
+ while (status == RET_SUCCESS) {
+ (void)fprintf(fp, "%s\n", key.data);
+ status = (*db->seq)(db, &key, &data, R_NEXT);
+ }
+ if (status == RET_ERROR)
+ perror("list/seq");
+}
+
+DB *BUGdb;
+void
+load(db, argv)
+ DB *db;
+ char **argv;
+{
+ register char *p, *t;
+ FILE *fp;
+ DBT data, key;
+ recno_t cnt;
+ size_t len;
+ int status;
+ char *lp, buf[16 * 1024];
+
+ BUGdb = db;
+ if ((fp = fopen(argv[1], "r")) == NULL) {
+ (void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));
+ return;
+ }
+ (void)printf("loading %s...\n", argv[1]);
+
+ for (cnt = 1; (lp = fgetline(fp, &len)) != NULL; ++cnt) {
+ if (recno) {
+ key.data = &cnt;
+ key.size = sizeof(recno_t);
+ data.data = lp;
+ data.size = len + 1;
+ } else {
+ key.data = lp;
+ key.size = len + 1;
+ for (p = lp + len - 1, t = buf; p >= lp; *t++ = *p--);
+ *t = '\0';
+ data.data = buf;
+ data.size = len + 1;
+ }
+
+ status = (*db->put)(db, &key, &data, R_NOOVERWRITE);
+ switch (status) {
+ case RET_ERROR:
+ perror("load/put");
+ exit(1);
+ case RET_SPECIAL:
+ if (recno)
+ (void)fprintf(stderr,
+ "duplicate: %ld {%s}\n", cnt, data.data);
+ else
+ (void)fprintf(stderr,
+ "duplicate: %ld {%s}\n", cnt, key.data);
+ exit(1);
+ case RET_SUCCESS:
+ break;
+ }
+ }
+ (void)fclose(fp);
+}
+
+void
+next(db, argv)
+ DB *db;
+ char **argv;
+{
+ DBT data, key;
+ int status;
+
+ status = (*db->seq)(db, &key, &data, R_NEXT);
+
+ switch (status) {
+ case RET_ERROR:
+ perror("next/seq");
+ break;
+ case RET_SPECIAL:
+ (void)printf("no more keys\n");
+ break;
+ case RET_SUCCESS:
+ keydata(&key, &data);
+ break;
+ }
+}
+
+void
+previous(db, argv)
+ DB *db;
+ char **argv;
+{
+ DBT data, key;
+ int status;
+
+ status = (*db->seq)(db, &key, &data, R_PREV);
+
+ switch (status) {
+ case RET_ERROR:
+ perror("previous/seq");
+ break;
+ case RET_SPECIAL:
+ (void)printf("no more keys\n");
+ break;
+ case RET_SUCCESS:
+ keydata(&key, &data);
+ break;
+ }
+}
+
+void
+show(db, argv)
+ DB *db;
+ char **argv;
+{
+ BTREE *t;
+ PAGE *h;
+ pgno_t pg;
+
+ pg = atoi(argv[1]);
+ t = db->internal;
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) {
+ (void)printf("getpage of %ld failed\n", pg);
+ return;
+ }
+ if (pg == 0)
+ __bt_dmpage(h);
+ else
+ __bt_dpage(h);
+ mpool_put(t->bt_mp, h, 0);
+}
+
+void
+bstat(db, argv)
+ DB *db;
+ char **argv;
+{
+ (void)printf("BTREE\n");
+ __bt_stat(db);
+}
+
+void
+mstat(db, argv)
+ DB *db;
+ char **argv;
+{
+ (void)printf("MPOOL\n");
+ mpool_stat(((BTREE *)db->internal)->bt_mp);
+}
+
+void
+keydata(key, data)
+ DBT *key, *data;
+{
+ if (!recno && key->size > 0)
+ (void)printf("%s/", key->data);
+ if (data->size > 0)
+ (void)printf("%s", data->data);
+ (void)printf("\n");
+}
+
+void
+usage()
+{
+ (void)fprintf(stderr,
+ "usage: %s [-bdlu] [-c cache] [-i file] [-p page] [file]\n",
+ progname);
+ exit (1);
+}
diff --git a/lib/libc/db/test/dbtest.c b/lib/libc/db/test/dbtest.c
new file mode 100644
index 0000000..4341b4c
--- /dev/null
+++ b/lib/libc/db/test/dbtest.c
@@ -0,0 +1,753 @@
+/*-
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1992, 1993, 1994\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <db.h>
+
+enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA };
+
+void compare __P((DBT *, DBT *));
+DBTYPE dbtype __P((char *));
+void dump __P((DB *, int));
+void err __P((const char *, ...));
+void get __P((DB *, DBT *));
+void getdata __P((DB *, DBT *, DBT *));
+void put __P((DB *, DBT *, DBT *));
+void rem __P((DB *, DBT *));
+char *sflags __P((int));
+void synk __P((DB *));
+void *rfile __P((char *, size_t *));
+void seq __P((DB *, DBT *));
+u_int setflags __P((char *));
+void *setinfo __P((DBTYPE, char *));
+void usage __P((void));
+void *xmalloc __P((char *, size_t));
+
+DBTYPE type; /* Database type. */
+void *infop; /* Iflags. */
+u_long lineno; /* Current line in test script. */
+u_int flags; /* Current DB flags. */
+int ofd = STDOUT_FILENO; /* Standard output fd. */
+
+DB *XXdbp; /* Global for gdb. */
+int XXlineno; /* Fast breakpoint for gdb. */
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern int optind;
+ extern char *optarg;
+ enum S command, state;
+ DB *dbp;
+ DBT data, key, keydata;
+ size_t len;
+ int ch, oflags, sflag;
+ char *fname, *infoarg, *p, *t, buf[8 * 1024];
+
+ infoarg = NULL;
+ fname = NULL;
+ oflags = O_CREAT | O_RDWR;
+ sflag = 0;
+ while ((ch = getopt(argc, argv, "f:i:lo:s")) != EOF)
+ switch (ch) {
+ case 'f':
+ fname = optarg;
+ break;
+ case 'i':
+ infoarg = optarg;
+ break;
+ case 'l':
+ oflags |= DB_LOCK;
+ break;
+ case 'o':
+ if ((ofd = open(optarg,
+ O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
+ err("%s: %s", optarg, strerror(errno));
+ break;
+ case 's':
+ sflag = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 2)
+ usage();
+
+ /* Set the type. */
+ type = dbtype(*argv++);
+
+ /* Open the descriptor file. */
+ if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL)
+ err("%s: %s", *argv, strerror(errno));
+
+ /* Set up the db structure as necessary. */
+ if (infoarg == NULL)
+ infop = NULL;
+ else
+ for (p = strtok(infoarg, ",\t "); p != NULL;
+ p = strtok(0, ",\t "))
+ if (*p != '\0')
+ infop = setinfo(type, p);
+
+ /*
+ * Open the DB. Delete any preexisting copy, you almost never
+ * want it around, and it often screws up tests.
+ */
+ if (fname == NULL) {
+ p = getenv("TMPDIR");
+ if (p == NULL)
+ p = "/var/tmp";
+ (void)sprintf(buf, "%s/__dbtest", p);
+ fname = buf;
+ (void)unlink(buf);
+ } else if (!sflag)
+ (void)unlink(fname);
+
+ if ((dbp = dbopen(fname,
+ oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
+ err("dbopen: %s", strerror(errno));
+ XXdbp = dbp;
+
+ state = COMMAND;
+ for (lineno = 1;
+ (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) {
+ /* Delete the newline, displaying the key/data is easier. */
+ if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL)
+ *t = '\0';
+ if ((len = strlen(buf)) == 0 || isspace(*p) || *p == '#')
+ continue;
+
+ /* Convenient gdb break point. */
+ if (XXlineno == lineno)
+ XXlineno = 1;
+ switch (*p) {
+ case 'c': /* compare */
+ if (state != COMMAND)
+ err("line %lu: not expecting command", lineno);
+ state = KEY;
+ command = COMPARE;
+ break;
+ case 'e': /* echo */
+ if (state != COMMAND)
+ err("line %lu: not expecting command", lineno);
+ /* Don't display the newline, if CR at EOL. */
+ if (p[len - 2] == '\r')
+ --len;
+ if (write(ofd, p + 1, len - 1) != len - 1 ||
+ write(ofd, "\n", 1) != 1)
+ err("write: %s", strerror(errno));
+ break;
+ case 'g': /* get */
+ if (state != COMMAND)
+ err("line %lu: not expecting command", lineno);
+ state = KEY;
+ command = GET;
+ break;
+ case 'p': /* put */
+ if (state != COMMAND)
+ err("line %lu: not expecting command", lineno);
+ state = KEY;
+ command = PUT;
+ break;
+ case 'r': /* remove */
+ if (state != COMMAND)
+ err("line %lu: not expecting command", lineno);
+ if (flags == R_CURSOR) {
+ rem(dbp, &key);
+ state = COMMAND;
+ } else {
+ state = KEY;
+ command = REMOVE;
+ }
+ break;
+ case 'S': /* sync */
+ if (state != COMMAND)
+ err("line %lu: not expecting command", lineno);
+ synk(dbp);
+ state = COMMAND;
+ break;
+ case 's': /* seq */
+ if (state != COMMAND)
+ err("line %lu: not expecting command", lineno);
+ if (flags == R_CURSOR) {
+ state = KEY;
+ command = SEQ;
+ } else
+ seq(dbp, &key);
+ break;
+ case 'f':
+ flags = setflags(p + 1);
+ break;
+ case 'D': /* data file */
+ if (state != DATA)
+ err("line %lu: not expecting data", lineno);
+ data.data = rfile(p + 1, &data.size);
+ goto ldata;
+ case 'd': /* data */
+ if (state != DATA)
+ err("line %lu: not expecting data", lineno);
+ data.data = xmalloc(p + 1, len - 1);
+ data.size = len - 1;
+ldata: switch (command) {
+ case COMPARE:
+ compare(&keydata, &data);
+ break;
+ case PUT:
+ put(dbp, &key, &data);
+ break;
+ default:
+ err("line %lu: command doesn't take data",
+ lineno);
+ }
+ if (type != DB_RECNO)
+ free(key.data);
+ free(data.data);
+ state = COMMAND;
+ break;
+ case 'K': /* key file */
+ if (state != KEY)
+ err("line %lu: not expecting a key", lineno);
+ if (type == DB_RECNO)
+ err("line %lu: 'K' not available for recno",
+ lineno);
+ key.data = rfile(p + 1, &key.size);
+ goto lkey;
+ case 'k': /* key */
+ if (state != KEY)
+ err("line %lu: not expecting a key", lineno);
+ if (type == DB_RECNO) {
+ static recno_t recno;
+ recno = atoi(p + 1);
+ key.data = &recno;
+ key.size = sizeof(recno);
+ } else {
+ key.data = xmalloc(p + 1, len - 1);
+ key.size = len - 1;
+ }
+lkey: switch (command) {
+ case COMPARE:
+ getdata(dbp, &key, &keydata);
+ state = DATA;
+ break;
+ case GET:
+ get(dbp, &key);
+ if (type != DB_RECNO)
+ free(key.data);
+ state = COMMAND;
+ break;
+ case PUT:
+ state = DATA;
+ break;
+ case REMOVE:
+ rem(dbp, &key);
+ if ((type != DB_RECNO) && (flags != R_CURSOR))
+ free(key.data);
+ state = COMMAND;
+ break;
+ case SEQ:
+ seq(dbp, &key);
+ if ((type != DB_RECNO) && (flags != R_CURSOR))
+ free(key.data);
+ state = COMMAND;
+ break;
+ default:
+ err("line %lu: command doesn't take a key",
+ lineno);
+ }
+ break;
+ case 'o':
+ dump(dbp, p[1] == 'r');
+ break;
+ default:
+ err("line %lu: %s: unknown command character",
+ lineno, p);
+ }
+ }
+#ifdef STATISTICS
+ /*
+ * -l must be used (DB_LOCK must be set) for this to be
+ * used, otherwise a page will be locked and it will fail.
+ */
+ if (type == DB_BTREE && oflags & DB_LOCK)
+ __bt_stat(dbp);
+#endif
+ if (dbp->close(dbp))
+ err("db->close: %s", strerror(errno));
+ (void)close(ofd);
+ exit(0);
+}
+
+#define NOOVERWRITE "put failed, would overwrite key\n"
+
+void
+compare(db1, db2)
+ DBT *db1, *db2;
+{
+ register size_t len;
+ register u_char *p1, *p2;
+
+ if (db1->size != db2->size)
+ printf("compare failed: key->data len %lu != data len %lu\n",
+ db1->size, db2->size);
+
+ len = MIN(db1->size, db2->size);
+ for (p1 = db1->data, p2 = db2->data; len--;)
+ if (*p1++ != *p2++) {
+ printf("compare failed at offset %d\n",
+ p1 - (u_char *)db1->data);
+ break;
+ }
+}
+
+void
+get(dbp, kp)
+ DB *dbp;
+ DBT *kp;
+{
+ DBT data;
+
+ switch (dbp->get(dbp, kp, &data, flags)) {
+ case 0:
+ (void)write(ofd, data.data, data.size);
+ if (ofd == STDOUT_FILENO)
+ (void)write(ofd, "\n", 1);
+ break;
+ case -1:
+ err("line %lu: get: %s", lineno, strerror(errno));
+ /* NOTREACHED */
+ case 1:
+#define NOSUCHKEY "get failed, no such key\n"
+ if (ofd != STDOUT_FILENO)
+ (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
+ else
+ (void)fprintf(stderr, "%d: %.*s: %s",
+ lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY);
+#undef NOSUCHKEY
+ break;
+ }
+}
+
+void
+getdata(dbp, kp, dp)
+ DB *dbp;
+ DBT *kp, *dp;
+{
+ switch (dbp->get(dbp, kp, dp, flags)) {
+ case 0:
+ return;
+ case -1:
+ err("line %lu: getdata: %s", lineno, strerror(errno));
+ /* NOTREACHED */
+ case 1:
+ err("line %lu: getdata failed, no such key", lineno);
+ /* NOTREACHED */
+ }
+}
+
+void
+put(dbp, kp, dp)
+ DB *dbp;
+ DBT *kp, *dp;
+{
+ switch (dbp->put(dbp, kp, dp, flags)) {
+ case 0:
+ break;
+ case -1:
+ err("line %lu: put: %s", lineno, strerror(errno));
+ /* NOTREACHED */
+ case 1:
+ (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1);
+ break;
+ }
+}
+
+void
+rem(dbp, kp)
+ DB *dbp;
+ DBT *kp;
+{
+ switch (dbp->del(dbp, kp, flags)) {
+ case 0:
+ break;
+ case -1:
+ err("line %lu: rem: %s", lineno, strerror(errno));
+ /* NOTREACHED */
+ case 1:
+#define NOSUCHKEY "rem failed, no such key\n"
+ if (ofd != STDOUT_FILENO)
+ (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
+ else if (flags != R_CURSOR)
+ (void)fprintf(stderr, "%d: %.*s: %s",
+ lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY);
+ else
+ (void)fprintf(stderr,
+ "%d: rem of cursor failed\n", lineno);
+#undef NOSUCHKEY
+ break;
+ }
+}
+
+void
+synk(dbp)
+ DB *dbp;
+{
+ switch (dbp->sync(dbp, flags)) {
+ case 0:
+ break;
+ case -1:
+ err("line %lu: synk: %s", lineno, strerror(errno));
+ /* NOTREACHED */
+ }
+}
+
+void
+seq(dbp, kp)
+ DB *dbp;
+ DBT *kp;
+{
+ DBT data;
+
+ switch (dbp->seq(dbp, kp, &data, flags)) {
+ case 0:
+ (void)write(ofd, data.data, data.size);
+ if (ofd == STDOUT_FILENO)
+ (void)write(ofd, "\n", 1);
+ break;
+ case -1:
+ err("line %lu: seq: %s", lineno, strerror(errno));
+ /* NOTREACHED */
+ case 1:
+#define NOSUCHKEY "seq failed, no such key\n"
+ if (ofd != STDOUT_FILENO)
+ (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
+ else if (flags == R_CURSOR)
+ (void)fprintf(stderr, "%d: %.*s: %s",
+ lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY);
+ else
+ (void)fprintf(stderr,
+ "%d: seq (%s) failed\n", lineno, sflags(flags));
+#undef NOSUCHKEY
+ break;
+ }
+}
+
+void
+dump(dbp, rev)
+ DB *dbp;
+ int rev;
+{
+ DBT key, data;
+ int flags, nflags;
+
+ if (rev) {
+ flags = R_LAST;
+ nflags = R_PREV;
+ } else {
+ flags = R_FIRST;
+ nflags = R_NEXT;
+ }
+ for (;; flags = nflags)
+ switch (dbp->seq(dbp, &key, &data, flags)) {
+ case 0:
+ (void)write(ofd, data.data, data.size);
+ if (ofd == STDOUT_FILENO)
+ (void)write(ofd, "\n", 1);
+ break;
+ case 1:
+ goto done;
+ case -1:
+ err("line %lu: (dump) seq: %s",
+ lineno, strerror(errno));
+ /* NOTREACHED */
+ }
+done: return;
+}
+
+u_int
+setflags(s)
+ char *s;
+{
+ char *p, *index();
+
+ for (; isspace(*s); ++s);
+ if (*s == '\n' || *s == '\0')
+ return (0);
+ if ((p = index(s, '\n')) != NULL)
+ *p = '\0';
+ if (!strcmp(s, "R_CURSOR")) return (R_CURSOR);
+ if (!strcmp(s, "R_FIRST")) return (R_FIRST);
+ if (!strcmp(s, "R_IAFTER")) return (R_IAFTER);
+ if (!strcmp(s, "R_IBEFORE")) return (R_IBEFORE);
+ if (!strcmp(s, "R_LAST")) return (R_LAST);
+ if (!strcmp(s, "R_NEXT")) return (R_NEXT);
+ if (!strcmp(s, "R_NOOVERWRITE")) return (R_NOOVERWRITE);
+ if (!strcmp(s, "R_PREV")) return (R_PREV);
+ if (!strcmp(s, "R_SETCURSOR")) return (R_SETCURSOR);
+
+ err("line %lu: %s: unknown flag", lineno, s);
+ /* NOTREACHED */
+}
+
+char *
+sflags(flags)
+ int flags;
+{
+ switch (flags) {
+ case R_CURSOR: return ("R_CURSOR");
+ case R_FIRST: return ("R_FIRST");
+ case R_IAFTER: return ("R_IAFTER");
+ case R_IBEFORE: return ("R_IBEFORE");
+ case R_LAST: return ("R_LAST");
+ case R_NEXT: return ("R_NEXT");
+ case R_NOOVERWRITE: return ("R_NOOVERWRITE");
+ case R_PREV: return ("R_PREV");
+ case R_SETCURSOR: return ("R_SETCURSOR");
+ }
+
+ return ("UNKNOWN!");
+}
+
+DBTYPE
+dbtype(s)
+ char *s;
+{
+ if (!strcmp(s, "btree"))
+ return (DB_BTREE);
+ if (!strcmp(s, "hash"))
+ return (DB_HASH);
+ if (!strcmp(s, "recno"))
+ return (DB_RECNO);
+ err("%s: unknown type (use btree, hash or recno)", s);
+ /* NOTREACHED */
+}
+
+void *
+setinfo(type, s)
+ DBTYPE type;
+ char *s;
+{
+ static BTREEINFO ib;
+ static HASHINFO ih;
+ static RECNOINFO rh;
+ char *eq, *index();
+
+ if ((eq = index(s, '=')) == NULL)
+ err("%s: illegal structure set statement", s);
+ *eq++ = '\0';
+ if (!isdigit(*eq))
+ err("%s: structure set statement must be a number", s);
+
+ switch (type) {
+ case DB_BTREE:
+ if (!strcmp("flags", s)) {
+ ib.flags = atoi(eq);
+ return (&ib);
+ }
+ if (!strcmp("cachesize", s)) {
+ ib.cachesize = atoi(eq);
+ return (&ib);
+ }
+ if (!strcmp("maxkeypage", s)) {
+ ib.maxkeypage = atoi(eq);
+ return (&ib);
+ }
+ if (!strcmp("minkeypage", s)) {
+ ib.minkeypage = atoi(eq);
+ return (&ib);
+ }
+ if (!strcmp("lorder", s)) {
+ ib.lorder = atoi(eq);
+ return (&ib);
+ }
+ if (!strcmp("psize", s)) {
+ ib.psize = atoi(eq);
+ return (&ib);
+ }
+ break;
+ case DB_HASH:
+ if (!strcmp("bsize", s)) {
+ ih.bsize = atoi(eq);
+ return (&ih);
+ }
+ if (!strcmp("ffactor", s)) {
+ ih.ffactor = atoi(eq);
+ return (&ih);
+ }
+ if (!strcmp("nelem", s)) {
+ ih.nelem = atoi(eq);
+ return (&ih);
+ }
+ if (!strcmp("cachesize", s)) {
+ ih.cachesize = atoi(eq);
+ return (&ih);
+ }
+ if (!strcmp("lorder", s)) {
+ ih.lorder = atoi(eq);
+ return (&ih);
+ }
+ break;
+ case DB_RECNO:
+ if (!strcmp("flags", s)) {
+ rh.flags = atoi(eq);
+ return (&rh);
+ }
+ if (!strcmp("cachesize", s)) {
+ rh.cachesize = atoi(eq);
+ return (&rh);
+ }
+ if (!strcmp("lorder", s)) {
+ rh.lorder = atoi(eq);
+ return (&rh);
+ }
+ if (!strcmp("reclen", s)) {
+ rh.reclen = atoi(eq);
+ return (&rh);
+ }
+ if (!strcmp("bval", s)) {
+ rh.bval = atoi(eq);
+ return (&rh);
+ }
+ if (!strcmp("psize", s)) {
+ rh.psize = atoi(eq);
+ return (&rh);
+ }
+ break;
+ }
+ err("%s: unknown structure value", s);
+ /* NOTREACHED */
+}
+
+void *
+rfile(name, lenp)
+ char *name;
+ size_t *lenp;
+{
+ struct stat sb;
+ void *p;
+ int fd;
+ char *np, *index();
+
+ for (; isspace(*name); ++name);
+ if ((np = index(name, '\n')) != NULL)
+ *np = '\0';
+ if ((fd = open(name, O_RDONLY, 0)) < 0 ||
+ fstat(fd, &sb))
+ err("%s: %s\n", name, strerror(errno));
+#ifdef NOT_PORTABLE
+ if (sb.st_size > (off_t)SIZE_T_MAX)
+ err("%s: %s\n", name, strerror(E2BIG));
+#endif
+ if ((p = (void *)malloc((u_int)sb.st_size)) == NULL)
+ err("%s", strerror(errno));
+ (void)read(fd, p, (int)sb.st_size);
+ *lenp = sb.st_size;
+ (void)close(fd);
+ return (p);
+}
+
+void *
+xmalloc(text, len)
+ char *text;
+ size_t len;
+{
+ void *p;
+
+ if ((p = (void *)malloc(len)) == NULL)
+ err("%s", strerror(errno));
+ memmove(p, text, len);
+ return (p);
+}
+
+void
+usage()
+{
+ (void)fprintf(stderr,
+ "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n");
+ exit(1);
+}
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#if __STDC__
+err(const char *fmt, ...)
+#else
+err(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ (void)fprintf(stderr, "dbtest: ");
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void)fprintf(stderr, "\n");
+ exit(1);
+ /* NOTREACHED */
+}
diff --git a/lib/libc/db/test/hash.tests/driver2.c b/lib/libc/db/test/hash.tests/driver2.c
new file mode 100644
index 0000000..896820c
--- /dev/null
+++ b/lib/libc/db/test/hash.tests/driver2.c
@@ -0,0 +1,114 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1991, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)driver2.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * Test driver, to try to tackle the large ugly-split problem.
+ */
+
+#include <sys/file.h>
+#include <stdio.h>
+#include "ndbm.h"
+
+int my_hash(key, len)
+ char *key;
+ int len;
+{
+ return(17); /* So I'm cruel... */
+}
+
+main(argc, argv)
+ int argc;
+{
+ DB *db;
+ DBT key, content;
+ char keybuf[2049];
+ char contentbuf[2049];
+ char buf[256];
+ int i;
+ HASHINFO info;
+
+ info.bsize = 1024;
+ info.ffactor = 5;
+ info.nelem = 1;
+ info.cachesize = NULL;
+#ifdef HASH_ID_PROGRAM_SPECIFIED
+ info.hash_id = HASH_ID_PROGRAM_SPECIFIED;
+ info.hash_func = my_hash;
+#else
+ info.hash = my_hash;
+#endif
+ info.lorder = 0;
+ if (!(db = dbopen("bigtest", O_RDWR | O_CREAT, 0644, DB_HASH, &info))) {
+ sprintf(buf, "dbopen: failed on file bigtest");
+ perror(buf);
+ exit(1);
+ }
+ srandom(17);
+ key.data = keybuf;
+ content.data = contentbuf;
+ bzero(keybuf, sizeof(keybuf));
+ bzero(contentbuf, sizeof(contentbuf));
+ for (i=1; i <= 500; i++) {
+ key.size = 128 + (random()&1023);
+ content.size = 128 + (random()&1023);
+/* printf("%d: Key size %d, data size %d\n", i, key.size,
+ content.size); */
+ sprintf(keybuf, "Key #%d", i);
+ sprintf(contentbuf, "Contents #%d", i);
+ if ((db->put)(db, &key, &content, R_NOOVERWRITE)) {
+ sprintf(buf, "dbm_store #%d", i);
+ perror(buf);
+ }
+ }
+ if ((db->close)(db)) {
+ perror("closing hash file");
+ exit(1);
+ }
+ exit(0);
+}
+
+
+
diff --git a/lib/libc/db/test/hash.tests/makedb.sh b/lib/libc/db/test/hash.tests/makedb.sh
new file mode 100644
index 0000000..f28e281
--- /dev/null
+++ b/lib/libc/db/test/hash.tests/makedb.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# @(#)makedb.sh 8.1 (Berkeley) 6/4/93
+
+awk '{i++; print $0; print i;}' /usr/share/dict/words > WORDS
+ls /bin /usr/bin /usr/ucb /etc | egrep '^(...|....|.....|......)$' | \
+sort | uniq | \
+awk '{
+ printf "%s\n", $0
+ for (i = 0; i < 1000; i++)
+ printf "%s+", $0
+ printf "\n"
+}' > LONG.DATA
diff --git a/lib/libc/db/test/hash.tests/tcreat3.c b/lib/libc/db/test/hash.tests/tcreat3.c
new file mode 100644
index 0000000..31211c5
--- /dev/null
+++ b/lib/libc/db/test/hash.tests/tcreat3.c
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1991, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)tcreat3.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <db.h>
+
+#define INITIAL 25000
+#define MAXWORDS 25000 /* # of elements in search table */
+
+char wp1[8192];
+char wp2[8192];
+main(argc, argv)
+char **argv;
+{
+ DBT item, key;
+ DB *dbp;
+ HASHINFO ctl;
+ FILE *fp;
+ int trash;
+
+ int i = 0;
+
+ argv++;
+ ctl.hash = NULL;
+ ctl.bsize = atoi(*argv++);
+ ctl.ffactor = atoi(*argv++);
+ ctl.nelem = atoi(*argv++);
+ ctl.lorder = 0;
+ if (!(dbp = dbopen( "hashtest",
+ O_CREAT|O_TRUNC|O_RDWR, 0600, DB_HASH, &ctl))){
+ /* create table */
+ fprintf(stderr, "cannot create: hash table (size %d)\n",
+ INITIAL);
+ exit(1);
+ }
+
+ key.data = wp1;
+ item.data = wp2;
+ while ( fgets(wp1, 8192, stdin) &&
+ fgets(wp2, 8192, stdin) &&
+ i++ < MAXWORDS) {
+/*
+* put info in structure, and structure in the item
+*/
+ key.size = strlen(wp1);
+ item.size = strlen(wp2);
+
+/*
+ * enter key/data pair into the table
+ */
+ if ((dbp->put)(dbp, &key, &item, R_NOOVERWRITE) != NULL) {
+ fprintf(stderr, "cannot enter: key %s\n",
+ item.data);
+ exit(1);
+ }
+ }
+
+ (dbp->close)(dbp);
+ exit(0);
+}
diff --git a/lib/libc/db/test/hash.tests/tdel.c b/lib/libc/db/test/hash.tests/tdel.c
new file mode 100644
index 0000000..fb99431
--- /dev/null
+++ b/lib/libc/db/test/hash.tests/tdel.c
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1991, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)tdel.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <db.h>
+#include <stdio.h>
+
+#define INITIAL 25000
+#define MAXWORDS 25000 /* # of elements in search table */
+
+/* Usage: thash pagesize fillfactor file */
+char wp1[8192];
+char wp2[8192];
+main(argc, argv)
+char **argv;
+{
+ DBT item, key;
+ DB *dbp;
+ HASHINFO ctl;
+ FILE *fp;
+ int stat;
+
+ int i = 0;
+
+ argv++;
+ ctl.nelem = INITIAL;
+ ctl.hash = NULL;
+ ctl.bsize = atoi(*argv++);
+ ctl.ffactor = atoi(*argv++);
+ ctl.cachesize = 1024 * 1024; /* 1 MEG */
+ ctl.lorder = 0;
+ argc -= 2;
+ if (!(dbp = dbopen( NULL, O_CREAT|O_RDWR, 0400, DB_HASH, &ctl))) {
+ /* create table */
+ fprintf(stderr, "cannot create: hash table size %d)\n",
+ INITIAL);
+ exit(1);
+ }
+
+ key.data = wp1;
+ item.data = wp2;
+ while ( fgets(wp1, 8192, stdin) &&
+ fgets(wp2, 8192, stdin) &&
+ i++ < MAXWORDS) {
+/*
+* put info in structure, and structure in the item
+*/
+ key.size = strlen(wp1);
+ item.size = strlen(wp2);
+
+/*
+ * enter key/data pair into the table
+ */
+ if ((dbp->put)(dbp, &key, &item, R_NOOVERWRITE) != NULL) {
+ fprintf(stderr, "cannot enter: key %s\n",
+ item.data);
+ exit(1);
+ }
+ }
+
+ if ( --argc ) {
+ fp = fopen ( argv[0], "r");
+ i = 0;
+ while ( fgets(wp1, 8192, fp) &&
+ fgets(wp2, 8192, fp) &&
+ i++ < MAXWORDS) {
+ key.size = strlen(wp1);
+ stat = (dbp->del)(dbp, &key, 0);
+ if (stat) {
+ fprintf ( stderr, "Error retrieving %s\n", key.data );
+ exit(1);
+ }
+ }
+ fclose(fp);
+ }
+ (dbp->close)(dbp);
+ exit(0);
+}
diff --git a/lib/libc/db/test/hash.tests/testit b/lib/libc/db/test/hash.tests/testit
new file mode 100644
index 0000000..039457a
--- /dev/null
+++ b/lib/libc/db/test/hash.tests/testit
@@ -0,0 +1,147 @@
+#!/bin/csh -f
+#
+# @(#)testit 8.1 (Berkeley) 6/4/93
+#
+
+echo ""
+echo "PAGE FILL "
+set name=WORDS
+ set i = 256
+ foreach j ( 11 14 21 )
+ thash4 $i $j 25000 65536 $name < $name
+ end
+ set i = 512
+ foreach j ( 21 28 43 )
+ thash4 $i $j 25000 65536 $name < $name
+ end
+ set i = 1024
+ foreach j ( 43 57 85 )
+ thash4 $i $j 25000 65536 $name < $name
+ end
+ set i = 2048
+ foreach j ( 85 114 171 )
+ thash4 $i $j 25000 65536 $name < $name
+ end
+ set i = 4096
+ foreach j ( 171 228 341 )
+ thash4 $i $j 25000 65536 $name < $name
+ end
+ set i = 8192
+ foreach j ( 341 455 683 )
+ thash4 $i $j 25000 65536 $name < $name
+ end
+ echo "PAGE FILL "
+ set i = 256
+ foreach j ( 11 14 21 )
+ echo "$i"_"$j"
+ tcreat3 $i $j 25000 $name < $name
+ tread2 65536 < $name
+ tverify $name < $name
+ tseq > /dev/null
+ tdel $i $j $name < $name
+ end
+ set i = 512
+ foreach j ( 21 28 43 )
+ echo "$i"_"$j"
+ tcreat3 $i $j 25000 $name < $name
+ tread2 65536 < $name
+ tverify $name < $name
+ tseq > /dev/null
+ tdel $i $j $name < $name
+ end
+ set i = 1024
+ foreach j ( 43 57 85 )
+ echo "$i"_"$j"
+ tcreat3 $i $j 25000 $name < $name
+ tread2 65536 < $name
+ tverify $name < $name
+ tseq > /dev/null
+ tdel $i $j $name < $name
+ end
+ set i = 2048
+ foreach j ( 85 114 171 )
+ echo "$i"_"$j"
+ tcreat3 $i $j 25000 $name < $name
+ tread2 65536 < $name
+ tverify $name < $name
+ tseq > /dev/null
+ tdel $i $j $name < $name
+ end
+ set i = 4096
+ foreach j ( 171 228 341 )
+ echo "$i"_"$j"
+ tcreat3 $i $j 25000 $name < $name
+ tread2 65536 < $name
+ tverify $name < $name
+ tseq > /dev/null
+ tdel $i $j $name < $name
+ end
+ set i = 8192
+ foreach j ( 341 455 683 )
+ echo "$i"_"$j"
+ tcreat3 $i $j 25000 $name < $name
+ tread2 65536 < $name
+ tverify $name < $name
+ tseq > /dev/null
+ tdel $i $j $name < $name
+ end
+set name=LONG.DATA
+ set i = 1024
+ foreach j ( 1 2 4 )
+ echo thash4 $i $j 600 65536 $name
+ thash4 $i $j 600 65536 $name < $name
+ end
+
+ set i = 2048
+ foreach j ( 1 2 4 )
+ echo thash4 $i $j 600 65536 $name
+ thash4 $i $j 600 65536 $name < $name
+ end
+ set i = 4096
+ foreach j ( 1 2 4 )
+ echo thash4 $i $j 600 65536 $name
+ thash4 $i $j 600 65536 $name < $name
+ end
+ set i = 8192
+ foreach j ( 2 4 8 )
+ echo thash4 $i $j 600 65536 $name
+ thash4 $i $j 600 65536 $name < $name
+ end
+ echo "PAGE FILL "
+ set i = 1024
+ foreach j ( 1 2 4 )
+ echo "$i"_"$j"
+ tcreat3 $i $j 600 $name < $name
+ tread2 65536 < $name
+ tverify $name < $name
+ tseq > /dev/null
+ tdel $i $j $name < $name
+ end
+ set i = 2048
+ foreach j ( 1 2 4 )
+ echo "$i"_"$j"
+ tcreat3 $i $j 600 $name < $name
+ tread2 65536 < $name
+ tverify $name < $name
+ tseq > /dev/null
+ tdel $i $j $name < $name
+ end
+ set i = 4096
+ foreach j ( 1 2 4 )
+ echo "$i"_"$j"
+ tcreat3 $i $j 600 $name < $name
+ tread2 65536 < $name
+ tverify $name < $name
+ tseq > /dev/null
+ tdel $i $j $name < $name
+ end
+ set i = 8192
+ foreach j ( 2 4 8 )
+ echo "$i"_"$j"
+ tcreat3 $i $j 600 $name < $name
+ tread2 65536 < $name
+ tverify $name < $name
+ tseq > /dev/null
+ tdel $i $j $name < $name
+ end
+driver2
diff --git a/lib/libc/db/test/hash.tests/thash4.c b/lib/libc/db/test/hash.tests/thash4.c
new file mode 100644
index 0000000..952dccb
--- /dev/null
+++ b/lib/libc/db/test/hash.tests/thash4.c
@@ -0,0 +1,132 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1991, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)thash4.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/timeb.h>
+#include <stdio.h>
+#include <errno.h>
+#include <db.h>
+
+#define INITIAL 25000
+#define MAXWORDS 25000 /* # of elements in search table */
+
+/* Usage: thash pagesize fillfactor file */
+char wp1[8192];
+char wp2[8192];
+main(argc, argv)
+char **argv;
+{
+ DBT item, key, res;
+ DB *dbp;
+ HASHINFO ctl;
+ FILE *fp;
+ int stat;
+ time_t t;
+
+ int i = 0;
+
+ argv++;
+ ctl.hash = NULL;
+ ctl.bsize = atoi(*argv++);
+ ctl.ffactor = atoi(*argv++);
+ ctl.nelem = atoi(*argv++);
+ ctl.cachesize = atoi(*argv++);
+ ctl.lorder = 0;
+ if (!(dbp = dbopen( NULL, O_CREAT|O_RDWR, 0400, DB_HASH, &ctl))) {
+ /* create table */
+ fprintf(stderr, "cannot create: hash table size %d)\n",
+ INITIAL);
+ fprintf(stderr, "\terrno: %d\n", errno);
+ exit(1);
+ }
+
+ key.data = wp1;
+ item.data = wp2;
+ while ( fgets(wp1, 8192, stdin) &&
+ fgets(wp2, 8192, stdin) &&
+ i++ < MAXWORDS) {
+/*
+* put info in structure, and structure in the item
+*/
+ key.size = strlen(wp1);
+ item.size = strlen(wp2);
+
+/*
+ * enter key/data pair into the table
+ */
+ if ((dbp->put)(dbp, &key, &item, R_NOOVERWRITE) != NULL) {
+ fprintf(stderr, "cannot enter: key %s\n",
+ item.data);
+ fprintf(stderr, "\terrno: %d\n", errno);
+ exit(1);
+ }
+ }
+
+ if ( --argc ) {
+ fp = fopen ( argv[0], "r");
+ i = 0;
+ while ( fgets(wp1, 256, fp) &&
+ fgets(wp2, 8192, fp) &&
+ i++ < MAXWORDS) {
+
+ key.size = strlen(wp1);
+ stat = (dbp->get)(dbp, &key, &res, 0);
+ if (stat < 0 ) {
+ fprintf ( stderr, "Error retrieving %s\n", key.data );
+ fprintf(stderr, "\terrno: %d\n", errno);
+ exit(1);
+ } else if ( stat > 0 ) {
+ fprintf ( stderr, "%s not found\n", key.data );
+ fprintf(stderr, "\terrno: %d\n", errno);
+ exit(1);
+ }
+ }
+ fclose(fp);
+ }
+ dbp->close(dbp);
+ exit(0);
+}
diff --git a/lib/libc/db/test/hash.tests/tread2.c b/lib/libc/db/test/hash.tests/tread2.c
new file mode 100644
index 0000000..8f01556
--- /dev/null
+++ b/lib/libc/db/test/hash.tests/tread2.c
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1991, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)tread2.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <db.h>
+
+#define INITIAL 25000
+#define MAXWORDS 25000 /* # of elements in search table */
+
+typedef struct { /* info to be stored */
+ int num, siz;
+} info;
+
+char wp1[8192];
+char wp2[8192];
+main(argc, argv)
+char **argv;
+{
+ DBT item, key, res;
+ DB *dbp;
+ HASHINFO ctl;
+ int stat;
+
+ int i = 0;
+
+ ctl.nelem = INITIAL;
+ ctl.hash = NULL;
+ ctl.bsize = 64;
+ ctl.ffactor = 1;
+ ctl.cachesize = atoi(*argv++);
+ ctl.lorder = 0;
+ if (!(dbp = dbopen( "hashtest", O_RDONLY, 0400, DB_HASH, &ctl))) {
+ /* create table */
+ fprintf(stderr, "cannot open: hash table\n" );
+ exit(1);
+ }
+
+ key.data = wp1;
+ item.data = wp2;
+ while ( fgets(wp1, 8192, stdin) &&
+ fgets(wp2, 8192, stdin) &&
+ i++ < MAXWORDS) {
+/*
+* put info in structure, and structure in the item
+*/
+ key.size = strlen(wp1);
+ item.size = strlen(wp2);
+
+ stat = (dbp->get)(dbp, &key, &res,0);
+ if (stat < 0) {
+ fprintf ( stderr, "Error retrieving %s\n", key.data );
+ exit(1);
+ } else if ( stat > 0 ) {
+ fprintf ( stderr, "%s not found\n", key.data );
+ exit(1);
+ }
+ }
+ (dbp->close)(dbp);
+ exit(0);
+}
diff --git a/lib/libc/db/test/hash.tests/tseq.c b/lib/libc/db/test/hash.tests/tseq.c
new file mode 100644
index 0000000..f41c172
--- /dev/null
+++ b/lib/libc/db/test/hash.tests/tseq.c
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1991, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)tseq.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <db.h>
+
+#define INITIAL 25000
+#define MAXWORDS 25000 /* # of elements in search table */
+
+
+char wp[8192];
+char cp[8192];
+main(argc, argv)
+char **argv;
+{
+ DBT item, key, res;
+ DB *dbp;
+ FILE *fp;
+ int stat;
+
+ if (!(dbp = dbopen( "hashtest", O_RDONLY, 0400, DB_HASH, NULL))) {
+ /* create table */
+ fprintf(stderr, "cannot open: hash table\n" );
+ exit(1);
+ }
+
+/*
+* put info in structure, and structure in the item
+*/
+ for ( stat = (dbp->seq) (dbp, &res, &item, 1 );
+ stat == 0;
+ stat = (dbp->seq) (dbp, &res, &item, 0 ) ) {
+
+ bcopy ( res.data, wp, res.size );
+ wp[res.size] = 0;
+ bcopy ( item.data, cp, item.size );
+ cp[item.size] = 0;
+
+ printf ( "%s %s\n", wp, cp );
+ }
+ (dbp->close)(dbp);
+ exit(0);
+}
diff --git a/lib/libc/db/test/hash.tests/tverify.c b/lib/libc/db/test/hash.tests/tverify.c
new file mode 100644
index 0000000..ac5d2f9
--- /dev/null
+++ b/lib/libc/db/test/hash.tests/tverify.c
@@ -0,0 +1,107 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1991, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)tverify.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <db.h>
+
+#define INITIAL 25000
+#define MAXWORDS 25000 /* # of elements in search table */
+
+typedef struct { /* info to be stored */
+ int num, siz;
+} info;
+
+char wp1[8192];
+char wp2[8192];
+main(argc, argv)
+char **argv;
+{
+ DBT key, res;
+ DB *dbp;
+ HASHINFO ctl;
+ int trash;
+ int stat;
+
+ int i = 0;
+
+ ctl.nelem = INITIAL;
+ ctl.hash = NULL;
+ ctl.bsize = 64;
+ ctl.ffactor = 1;
+ ctl.cachesize = 1024 * 1024; /* 1 MEG */
+ ctl.lorder = 0;
+ if (!(dbp = dbopen( "hashtest", O_RDONLY, 0400, DB_HASH, &ctl))) {
+ /* create table */
+ fprintf(stderr, "cannot open: hash table\n" );
+ exit(1);
+ }
+
+ key.data = wp1;
+ while ( fgets(wp1, 8192, stdin) &&
+ fgets(wp2, 8192, stdin) &&
+ i++ < MAXWORDS) {
+/*
+* put info in structure, and structure in the item
+*/
+ key.size = strlen(wp1);
+
+ stat = (dbp->get)(dbp, &key, &res,0);
+ if (stat < 0) {
+ fprintf ( stderr, "Error retrieving %s\n", key.data );
+ exit(1);
+ } else if ( stat > 0 ) {
+ fprintf ( stderr, "%s not found\n", key.data );
+ exit(1);
+ }
+ if ( memcmp ( res.data, wp2, res.size ) ) {
+ fprintf ( stderr, "data for %s is incorrect. Data was %s. Should have been %s\n", key.data, res.data, wp2 );
+ }
+ }
+ (dbp->close)(dbp);
+ exit(0);
+}
diff --git a/lib/libc/db/test/run.test b/lib/libc/db/test/run.test
new file mode 100644
index 0000000..52b74c3
--- /dev/null
+++ b/lib/libc/db/test/run.test
@@ -0,0 +1,705 @@
+#!/bin/sh -
+#
+# @(#)run.test 8.10 (Berkeley) 7/26/94
+#
+
+# db regression tests
+main()
+{
+
+ PROG=./dbtest
+ TMP1=t1
+ TMP2=t2
+ TMP3=t3
+
+ if [ -f /usr/share/dict/words ]; then
+ DICT=/usr/share/dict/words
+ elif [ -f /usr/dict/words ]; then
+ DICT=/usr/dict/words
+ else
+ echo 'run.test: no dictionary'
+ exit 1
+ fi
+
+ if [ $# -eq 0 ]; then
+ for t in 1 2 3 4 5 6 7 8 9 10 11 12 13 20; do
+ test$t
+ done
+ else
+ while [ $# -gt 0 ]
+ do case "$1" in
+ test*)
+ $1;;
+ [0-9]*)
+ test$1;;
+ btree)
+ for t in 1 2 3 7 8 9 10 12 13; do
+ test$t
+ done;;
+ hash)
+ for t in 1 2 3 8 13 20; do
+ test$t
+ done;;
+ recno)
+ for t in 1 2 3 4 5 6 7 10 11; do
+ test$t
+ done;;
+ *)
+ echo "run.test: unknown test $1"
+ echo "usage: run.test test# | type"
+ exit 1
+ esac
+ shift
+ done
+ fi
+ rm -f $TMP1 $TMP2 $TMP3
+ exit 0
+}
+
+# Take the first hundred entries in the dictionary, and make them
+# be key/data pairs.
+test1()
+{
+ echo "Test 1: btree, hash: small key, small data pairs"
+ sed 200q $DICT > $TMP1
+ for type in btree hash; do
+ rm -f $TMP2 $TMP3
+ for i in `sed 200q $DICT`; do
+ echo p
+ echo k$i
+ echo d$i
+ echo g
+ echo k$i
+ done > $TMP2
+ $PROG -o $TMP3 $type $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test1: type $type: failed"
+ exit 1
+ fi
+ done
+ echo "Test 1: recno: small key, small data pairs"
+ rm -f $TMP2 $TMP3
+ sed 200q $DICT |
+ awk '{
+ ++i;
+ printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
+ }' > $TMP2
+ $PROG -o $TMP3 recno $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test1: type recno: failed"
+ exit 1
+ fi
+}
+
+# Take the first 200 entries in the dictionary, and give them
+# each a medium size data entry.
+test2()
+{
+ echo "Test 2: btree, hash: small key, medium data pairs"
+ mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i) print $0 }' > $TMP1
+ for type in hash btree; do
+ rm -f $TMP2 $TMP3
+ for i in `sed 200q $DICT`; do
+ echo p
+ echo k$i
+ echo d$mdata
+ echo g
+ echo k$i
+ done > $TMP2
+ $PROG -o $TMP3 $type $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test2: type $type: failed"
+ exit 1
+ fi
+ done
+ echo "Test 2: recno: small key, medium data pairs"
+ rm -f $TMP2 $TMP3
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i)
+ printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
+ }' > $TMP2
+ $PROG -o $TMP3 recno $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test2: type recno: failed"
+ exit 1
+ fi
+}
+
+# Insert the programs in /bin with their paths as their keys.
+test3()
+{
+ echo "Test 3: hash: small key, big data pairs"
+ rm -f $TMP1
+ (find /bin -type f -print | xargs cat) > $TMP1
+ for type in hash; do
+ rm -f $TMP2 $TMP3
+ for i in `find /bin -type f -print`; do
+ echo p
+ echo k$i
+ echo D$i
+ echo g
+ echo k$i
+ done > $TMP2
+ $PROG -o $TMP3 $type $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test3: $type: failed"
+ exit 1
+ fi
+ done
+ echo "Test 3: btree: small key, big data pairs"
+ for psize in 512 16384 65536; do
+ echo " page size $psize"
+ for type in btree; do
+ rm -f $TMP2 $TMP3
+ for i in `find /bin -type f -print`; do
+ echo p
+ echo k$i
+ echo D$i
+ echo g
+ echo k$i
+ done > $TMP2
+ $PROG -i psize=$psize -o $TMP3 $type $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test3: $type: page size $psize: failed"
+ exit 1
+ fi
+ done
+ done
+ echo "Test 3: recno: big data pairs"
+ rm -f $TMP2 $TMP3
+ find /bin -type f -print |
+ awk '{
+ ++i;
+ printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i);
+ }' > $TMP2
+ for psize in 512 16384 65536; do
+ echo " page size $psize"
+ $PROG -i psize=$psize -o $TMP3 recno $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test3: recno: page size $psize: failed"
+ exit 1
+ fi
+ done
+}
+
+# Do random recno entries.
+test4()
+{
+ echo "Test 4: recno: random entries"
+ echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
+ awk '{
+ for (i = 37; i <= 37 + 88 * 17; i += 17) {
+ if (i % 41)
+ s = substr($0, 1, i % 41);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ for (i = 1; i <= 15; ++i) {
+ if (i % 41)
+ s = substr($0, 1, i % 41);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ for (i = 19234; i <= 19234 + 61 * 27; i += 27) {
+ if (i % 41)
+ s = substr($0, 1, i % 41);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ exit
+ }' > $TMP1
+ rm -f $TMP2 $TMP3
+ cat $TMP1 |
+ awk 'BEGIN {
+ i = 37;
+ incr = 17;
+ }
+ {
+ printf("p\nk%d\nd%s\n", i, $0);
+ if (i == 19234 + 61 * 27)
+ exit;
+ if (i == 37 + 88 * 17) {
+ i = 1;
+ incr = 1;
+ } else if (i == 15) {
+ i = 19234;
+ incr = 27;
+ } else
+ i += incr;
+ }
+ END {
+ for (i = 37; i <= 37 + 88 * 17; i += 17)
+ printf("g\nk%d\n", i);
+ for (i = 1; i <= 15; ++i)
+ printf("g\nk%d\n", i);
+ for (i = 19234; i <= 19234 + 61 * 27; i += 27)
+ printf("g\nk%d\n", i);
+ }' > $TMP2
+ $PROG -o $TMP3 recno $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test4: type recno: failed"
+ exit 1
+ fi
+}
+
+# Do reverse order recno entries.
+test5()
+{
+ echo "Test 5: recno: reverse order entries"
+ echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
+ awk ' {
+ for (i = 1500; i; --i) {
+ if (i % 34)
+ s = substr($0, 1, i % 34);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ exit;
+ }' > $TMP1
+ rm -f $TMP2 $TMP3
+ cat $TMP1 |
+ awk 'BEGIN {
+ i = 1500;
+ }
+ {
+ printf("p\nk%d\nd%s\n", i, $0);
+ --i;
+ }
+ END {
+ for (i = 1500; i; --i)
+ printf("g\nk%d\n", i);
+ }' > $TMP2
+ $PROG -o $TMP3 recno $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test5: type recno: failed"
+ exit 1
+ fi
+}
+
+# Do alternating order recno entries.
+test6()
+{
+ echo "Test 6: recno: alternating order entries"
+ echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
+ awk ' {
+ for (i = 1; i < 1200; i += 2) {
+ if (i % 34)
+ s = substr($0, 1, i % 34);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ for (i = 2; i < 1200; i += 2) {
+ if (i % 34)
+ s = substr($0, 1, i % 34);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ exit;
+ }' > $TMP1
+ rm -f $TMP2 $TMP3
+ cat $TMP1 |
+ awk 'BEGIN {
+ i = 1;
+ even = 0;
+ }
+ {
+ printf("p\nk%d\nd%s\n", i, $0);
+ i += 2;
+ if (i >= 1200) {
+ if (even == 1)
+ exit;
+ even = 1;
+ i = 2;
+ }
+ }
+ END {
+ for (i = 1; i < 1200; ++i)
+ printf("g\nk%d\n", i);
+ }' > $TMP2
+ $PROG -o $TMP3 recno $TMP2
+ sort -o $TMP1 $TMP1
+ sort -o $TMP3 $TMP3
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test6: type recno: failed"
+ exit 1
+ fi
+}
+
+# Delete cursor record
+test7()
+{
+ echo "Test 7: btree, recno: delete cursor record"
+ echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
+ awk '{
+ for (i = 1; i <= 120; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ printf("%05d: input key %d: %s\n", 120, 120, $0);
+ printf("seq failed, no such key\n");
+ printf("%05d: input key %d: %s\n", 1, 1, $0);
+ printf("%05d: input key %d: %s\n", 2, 2, $0);
+ exit;
+ }' > $TMP1
+ rm -f $TMP2 $TMP3
+
+ for type in btree recno; do
+ cat $TMP1 |
+ awk '{
+ if (i == 120)
+ exit;
+ printf("p\nk%d\nd%s\n", ++i, $0);
+ }
+ END {
+ printf("fR_NEXT\n");
+ for (i = 1; i <= 120; ++i)
+ printf("s\n");
+ printf("fR_CURSOR\ns\nk120\n");
+ printf("r\n");
+ printf("fR_NEXT\ns\n");
+ printf("fR_CURSOR\ns\nk1\n");
+ printf("r\n");
+ printf("fR_FIRST\ns\n");
+ }' > $TMP2
+ $PROG -o $TMP3 recno $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test7: type $type: failed"
+ exit 1
+ fi
+ done
+}
+
+# Make sure that overflow pages are reused.
+test8()
+{
+ echo "Test 8: btree, hash: repeated small key, big data pairs"
+ rm -f $TMP1
+ echo "" |
+ awk 'BEGIN {
+ for (i = 1; i <= 10; ++i) {
+ printf("p\nkkey1\nD/bin/sh\n");
+ printf("p\nkkey2\nD/bin/csh\n");
+ if (i % 8 == 0) {
+ printf("c\nkkey2\nD/bin/csh\n");
+ printf("c\nkkey1\nD/bin/sh\n");
+ printf("e\t%d of 10 (comparison)\n", i);
+ } else
+ printf("e\t%d of 10 \n", i);
+ printf("r\nkkey1\nr\nkkey2\n");
+ }
+ }' > $TMP1
+ $PROG btree $TMP1
+# $PROG hash $TMP1
+ # No explicit test for success.
+}
+
+# Test btree duplicate keys
+test9()
+{
+ echo "Test 9: btree: duplicate keys"
+ echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
+ awk '{
+ for (i = 1; i <= 543; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ exit;
+ }' > $TMP1
+ rm -f $TMP2 $TMP3
+
+ for type in btree; do
+ cat $TMP1 |
+ awk '{
+ if (i++ % 2)
+ printf("p\nkduplicatekey\nd%s\n", $0);
+ else
+ printf("p\nkunique%dkey\nd%s\n", i, $0);
+ }
+ END {
+ printf("o\n");
+ }' > $TMP2
+ $PROG -iflags=1 -o $TMP3 $type $TMP2
+ sort -o $TMP3 $TMP3
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test9: type $type: failed"
+ exit 1
+ fi
+ done
+}
+
+# Test use of cursor flags without initialization
+test10()
+{
+ echo "Test 10: btree, recno: test cursor flag use"
+ echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
+ awk '{
+ for (i = 1; i <= 20; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ exit;
+ }' > $TMP1
+ rm -f $TMP2 $TMP3
+
+ # Test that R_CURSOR doesn't succeed before cursor initialized
+ for type in btree recno; do
+ cat $TMP1 |
+ awk '{
+ if (i == 10)
+ exit;
+ printf("p\nk%d\nd%s\n", ++i, $0);
+ }
+ END {
+ printf("fR_CURSOR\nr\n");
+ printf("eR_CURSOR SHOULD HAVE FAILED\n");
+ }' > $TMP2
+ $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
+ if [ -s $TMP3 ] ; then
+ echo "Test 10: delete: R_CURSOR SHOULD HAVE FAILED"
+ exit 1
+ fi
+ done
+ for type in btree recno; do
+ cat $TMP1 |
+ awk '{
+ if (i == 10)
+ exit;
+ printf("p\nk%d\nd%s\n", ++i, $0);
+ }
+ END {
+ printf("fR_CURSOR\np\nk1\ndsome data\n");
+ printf("eR_CURSOR SHOULD HAVE FAILED\n");
+ }' > $TMP2
+ $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
+ if [ -s $TMP3 ] ; then
+ echo "Test 10: put: R_CURSOR SHOULD HAVE FAILED"
+ exit 1
+ fi
+ done
+}
+
+# Test insert in reverse order.
+test11()
+{
+ echo "Test 11: recno: reverse order insert"
+ echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
+ awk '{
+ for (i = 1; i <= 779; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ exit;
+ }' > $TMP1
+ rm -f $TMP2 $TMP3
+
+ for type in recno; do
+ cat $TMP1 |
+ awk '{
+ if (i == 0) {
+ i = 1;
+ printf("p\nk1\nd%s\n", $0);
+ printf("%s\n", "fR_IBEFORE");
+ } else
+ printf("p\nk1\nd%s\n", $0);
+ }
+ END {
+ printf("or\n");
+ }' > $TMP2
+ $PROG -o $TMP3 $type $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test11: type $type: failed"
+ exit 1
+ fi
+ done
+}
+
+# Take the first 20000 entries in the dictionary, reverse them, and give
+# them each a small size data entry. Use a small page size to make sure
+# the btree split code gets hammered.
+test12()
+{
+ echo "Test 12: btree: lots of keys, small page size"
+ mdata=abcdefghijklmnopqrstuvwxy
+ echo $mdata |
+ awk '{ for (i = 1; i < 20001; ++i) print $0 }' > $TMP1
+ for type in btree; do
+ rm -f $TMP2 $TMP3
+ for i in `sed 20000q $DICT | rev`; do
+ echo p
+ echo k$i
+ echo d$mdata
+ echo g
+ echo k$i
+ done > $TMP2
+ $PROG -i psize=512 -o $TMP3 $type $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test12: type $type: failed"
+ exit 1
+ fi
+ done
+}
+
+# Test different byte orders.
+test13()
+{
+ echo "Test 13: btree, hash: differing byte orders"
+ sed 50q $DICT > $TMP1
+ for order in 1234 4321; do
+ for type in btree hash; do
+ rm -f byte.file $TMP2 $TMP3
+ for i in `sed 50q $DICT`; do
+ echo p
+ echo k$i
+ echo d$i
+ echo g
+ echo k$i
+ done > $TMP2
+ $PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test13: $type/$order put failed"
+ exit 1
+ fi
+ for i in `sed 50q $DICT`; do
+ echo g
+ echo k$i
+ done > $TMP2
+ $PROG -s \
+ -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test13: $type/$order get failed"
+ exit 1
+ fi
+ done
+ done
+ rm -f byte.file
+}
+
+# Try a variety of bucketsizes and fill factors for hashing
+test20()
+{
+ echo\
+ "Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536"
+ echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
+ awk '{
+ for (i = 1; i <= 10000; ++i) {
+ if (i % 34)
+ s = substr($0, 1, i % 34);
+ else
+ s = substr($0, 1);
+ printf("%s\n", s);
+ }
+ exit;
+ }' > $TMP1
+ sed 10000q $DICT |
+ awk 'BEGIN {
+ ds="abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg"
+ }
+ {
+ if (++i % 34)
+ s = substr(ds, 1, i % 34);
+ else
+ s = substr(ds, 1);
+ printf("p\nk%s\nd%s\n", $0, s);
+ }' > $TMP2
+ sed 10000q $DICT |
+ awk '{
+ ++i;
+ printf("g\nk%s\n", $0);
+ }' >> $TMP2
+ bsize=256
+ for ffactor in 11 14 21; do
+ echo " bucketsize $bsize, fill factor $ffactor"
+ $PROG -o$TMP3 \
+ -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
+ hash $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test20: type hash:\
+bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
+ exit 1
+ fi
+ done
+ bsize=512
+ for ffactor in 21 28 43; do
+ echo " bucketsize $bsize, fill factor $ffactor"
+ $PROG -o$TMP3 \
+ -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
+ hash $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test20: type hash:\
+bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
+ exit 1
+ fi
+ done
+ bsize=1024
+ for ffactor in 43 57 85; do
+ echo " bucketsize $bsize, fill factor $ffactor"
+ $PROG -o$TMP3 \
+ -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
+ hash $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test20: type hash:\
+bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
+ exit 1
+ fi
+ done
+ bsize=2048
+ for ffactor in 85 114 171; do
+ echo " bucketsize $bsize, fill factor $ffactor"
+ $PROG -o$TMP3 \
+ -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
+ hash $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test20: type hash:\
+bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
+ exit 1
+ fi
+ done
+ bsize=4096
+ for ffactor in 171 228 341; do
+ echo " bucketsize $bsize, fill factor $ffactor"
+ $PROG -o$TMP3 \
+ -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
+ hash $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test20: type hash:\
+bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
+ exit 1
+ fi
+ done
+ bsize=8192
+ for ffactor in 341 455 683; do
+ echo " bucketsize $bsize, fill factor $ffactor"
+ $PROG -o$TMP3 \
+ -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
+ hash $TMP2
+ if (cmp -s $TMP1 $TMP3) ; then :
+ else
+ echo "test20: type hash:\
+bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
+ exit 1
+ fi
+ done
+}
+
+main $*
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
new file mode 100644
index 0000000..58de374
--- /dev/null
+++ b/lib/libc/gen/Makefile.inc
@@ -0,0 +1,121 @@
+# @(#)Makefile.inc 8.6 (Berkeley) 5/4/95
+# $FreeBSD$
+
+# machine-independent gen sources
+.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/gen ${.CURDIR}/../libc/gen
+
+SRCS+= _rand48.c _spinlock_stub.c alarm.c arc4random.c assert.c \
+ clock.c closedir.c confstr.c \
+ crypt.c ctermid.c daemon.c devname.c disklabel.c \
+ dlfcn.c drand48.c erand48.c err.c errlst.c \
+ exec.c fnmatch.c fstab.c ftok.c fts.c getbootfile.c getbsize.c \
+ getcap.c getcwd.c getdomainname.c getgrent.c getgrouplist.c \
+ gethostname.c getloadavg.c getlogin.c getmntinfo.c getnetgrent.c \
+ getobjformat.c getosreldate.c getpagesize.c \
+ getpass.c getpwent.c getttyent.c \
+ getusershell.c getvfsbyname.c getvfsent.c glob.c \
+ initgroups.c isatty.c jrand48.c lcong48.c \
+ lockf.c lrand48.c mrand48.c msgctl.c \
+ msgget.c msgrcv.c msgsnd.c nice.c \
+ nlist.c nrand48.c ntp_gettime.c opendir.c \
+ pause.c popen.c psignal.c pwcache.c raise.c readdir.c rewinddir.c \
+ scandir.c seed48.c seekdir.c semconfig.c semctl.c semget.c semop.c \
+ setdomainname.c sethostname.c setjmperr.c setmode.c shmat.c \
+ shmctl.c shmdt.c shmget.c siginterrupt.c siglist.c signal.c \
+ sigsetops.c sleep.c srand48.c stringlist.c \
+ sysconf.c sysctl.c sysctlbyname.c \
+ syslog.c telldir.c termios.c time.c times.c timezone.c ttyname.c \
+ ttyslot.c ualarm.c uname.c unvis.c usleep.c utime.c valloc.c vis.c \
+ wait.c wait3.c waitpid.c
+
+# machine-dependent gen sources
+.include "${.CURDIR}/../libc/${MACHINE_ARCH}/gen/Makefile.inc"
+
+.if ${LIB} == "c"
+MAN3+= alarm.3 arc4random.3 clock.3 \
+ confstr.3 crypt.3 ctermid.3 daemon.3 \
+ devname.3 directory.3 dladdr.3 dlopen.3 \
+ err.3 exec.3 fnmatch.3 frexp.3 ftok.3 fts.3 \
+ getbootfile.3 getbsize.3 getcap.3 getcwd.3 \
+ getdiskbyname.3 getdomainname.3 getfsent.3 \
+ getgrent.3 getgrouplist.3 gethostname.3 getloadavg.3 \
+ getmntinfo.3 getnetgrent.3 getobjformat.3 \
+ getpagesize.3 getpass.3 getpwent.3 \
+ getttyent.3 getusershell.3 getvfsbyname.3 getvfsent.3 \
+ glob.3 initgroups.3 isinf.3 \
+ ldexp.3 lockf.3 modf.3 msgctl.3 msgget.3 msgrcv.3 msgsnd.3 \
+ nice.3 nlist.3 pause.3 popen.3 psignal.3 pwcache.3 \
+ raise.3 rand48.3 scandir.3 setjmp.3 setmode.3 siginterrupt.3 \
+ signal.3 sigsetops.3 sleep.3 stringlist.3 \
+ sysconf.3 sysctl.3 syslog.3 tcgetpgrp.3 \
+ tcsendbreak.3 tcsetattr.3 tcsetpgrp.3 time.3 times.3 timezone.3 \
+ ttyname.3 tzset.3 ualarm.3 uname.3 unvis.3 usleep.3 utime.3 \
+ valloc.3 vis.3
+
+MLINKS+=arc4random.3 arc4random_addrandom.3 arc4random.3 arc4random_stir.3
+MLINKS+=crypt.3 des_cipher.3 crypt.3 des_setkey.3 crypt.3 encrypt.3 \
+ crypt.3 setkey.3
+MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.3 \
+ directory.3 readdir.3 directory.3 rewinddir.3 directory.3 seekdir.3 \
+ directory.3 telldir.3
+MLINKS+=dlopen.3 dlclose.3 dlopen.3 dlerror.3 dlopen.3 dlsym.3
+MLINKS+=err.3 err_set_exit.3 err.3 err_set_file.3 err.3 errc.3 err.3 errx.3 \
+ err.3 verr.3 err.3 verrc.3 err.3 verrx.3 err.3 vwarn.3 err.3 vwarnc.3 \
+ err.3 vwarnx.3 err.3 warnc.3 err.3 warn.3 err.3 warnx.3
+MLINKS+=exec.3 execl.3 exec.3 execle.3 exec.3 execlp.3 exec.3 exect.3 \
+ exec.3 execv.3 exec.3 execvp.3
+MLINKS+=fts.3 fts_children.3 fts.3 fts_close.3 fts.3 fts_open.3 \
+ fts.3 fts_read.3 fts.3 fts_set.3
+MLINKS+=getcap.3 cgetcap.3 getcap.3 cgetclose.3 getcap.3 cgetent.3 \
+ getcap.3 cgetfirst.3 getcap.3 cgetmatch.3 getcap.3 cgetnext.3 \
+ getcap.3 cgetnum.3 getcap.3 cgetset.3 getcap.3 cgetstr.3 \
+ getcap.3 cgetustr.3
+MLINKS+=getcwd.3 getwd.3
+MLINKS+=getdomainname.3 setdomainname.3
+MLINKS+=getfsent.3 endfsent.3 getfsent.3 getfsfile.3 getfsent.3 getfsspec.3 \
+ getfsent.3 getfstype.3 getfsent.3 setfsent.3
+MLINKS+=getgrent.3 endgrent.3 getgrent.3 getgrgid.3 getgrent.3 getgrnam.3 \
+ getgrent.3 setgrent.3 getgrent.3 setgroupent.3
+MLINKS+=gethostname.3 sethostname.3
+MLINKS+=getnetgrent.3 endnetgrent.3 getnetgrent.3 innetgr.3 \
+ getnetgrent.3 setnetgrent.3
+MLINKS+=getpwent.3 endpwent.3 getpwent.3 getpwnam.3 getpwent.3 getpwuid.3 \
+ getpwent.3 setpassent.3 getpwent.3 setpwent.3 getpwent.3 setpwfile.3
+MLINKS+=getttyent.3 endttyent.3 getttyent.3 getttynam.3 \
+ getttyent.3 isdialuptty.3 getttyent.3 isnettty.3 \
+ getttyent.3 setttyent.3
+MLINKS+=getusershell.3 endusershell.3 getusershell.3 setusershell.3
+MLINKS+=getvfsent.3 endvfsent.3 getvfsent.3 getvfsbytype.3 \
+ getvfsent.3 setvfsent.3 getvfsent.3 vfsisloadable.3 \
+ getvfsent.3 vfsload.3
+MLINKS+=glob.3 globfree.3
+MLINKS+=isinf.3 isnan.3
+MLINKS+=popen.3 pclose.3
+MLINKS+=psignal.3 sys_siglist.3 psignal.3 sys_signame.3
+MLINKS+=psignal.3 strsignal.3 psignal.3 sys_siglist.3 psignal.3 sys_signame.3
+MLINKS+=pwcache.3 group_from_gid.3 pwcache.3 user_from_uid.3
+MLINKS+=rand48.3 _rand48.3 rand48.3 drand48.3 rand48.3 erand48.3 \
+ rand48.3 jrand48.3 rand48.3 lcong48.3 rand48.3 lrand48.3 \
+ rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 seed48.3 \
+ rand48.3 srand48.3
+MLINKS+=scandir.3 alphasort.3
+MLINKS+=setjmp.3 _longjmp.3 setjmp.3 _setjmp.3 setjmp.3 longjmp.3 \
+ setjmp.3 longjmperr.3 setjmp.3 longjmperror.3 \
+ setjmp.3 siglongjmp.3 setjmp.3 sigsetjmp.3
+MLINKS+=setmode.3 getmode.3
+MLINKS+=sigsetops.3 sigaddset.3 sigsetops.3 sigdelset.3 \
+ sigsetops.3 sigemptyset.3 sigsetops.3 sigfillset.3 \
+ sigsetops.3 sigismember.3
+MLINKS+=sysctl.3 sysctlbyname.3
+MLINKS+=syslog.3 closelog.3 syslog.3 openlog.3 syslog.3 setlogmask.3 \
+ syslog.3 vsyslog.3
+MLINKS+=tcsendbreak.3 tcdrain.3 tcsendbreak.3 tcflow.3 tcsendbreak.3 tcflush.3
+MLINKS+=tcsetattr.3 cfgetispeed.3 tcsetattr.3 cfgetospeed.3 \
+ tcsetattr.3 cfmakeraw.3 tcsetattr.3 cfsetispeed.3 \
+ tcsetattr.3 cfsetospeed.3 tcsetattr.3 cfsetspeed.3 \
+ tcsetattr.3 tcgetattr.3
+MLINKS+=ttyname.3 isatty.3 ttyname.3 ttyslot.3
+MLINKS+=tzset.3 tzsetwall.3
+MLINKS+=unvis.3 strunvis.3
+MLINKS+=vis.3 strvis.3 vis.3 strvisx.3
+.endif
diff --git a/lib/libc/gen/__xuname.c b/lib/libc/gen/__xuname.c
new file mode 100644
index 0000000..944c2dc
--- /dev/null
+++ b/lib/libc/gen/__xuname.c
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char sccsid[] = "From: @(#)uname.c 8.1 (Berkeley) 1/4/94";*/
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/utsname.h>
+#include <errno.h>
+
+int
+uname(name)
+ struct utsname *name;
+{
+ int mib[2], rval;
+ size_t len;
+ char *p;
+ int oerrno;
+
+ rval = 0;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_OSTYPE;
+ len = sizeof(name->sysname);
+ oerrno = errno;
+ if (sysctl(mib, 2, &name->sysname, &len, NULL, 0) == -1) {
+ if(errno == ENOMEM)
+ errno = oerrno;
+ else
+ rval = -1;
+ }
+ name->sysname[sizeof(name->sysname) - 1] = '\0';
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_HOSTNAME;
+ len = sizeof(name->nodename);
+ oerrno = errno;
+ if (sysctl(mib, 2, &name->nodename, &len, NULL, 0) == -1) {
+ if(errno == ENOMEM)
+ errno = oerrno;
+ else
+ rval = -1;
+ }
+ name->nodename[sizeof(name->nodename) - 1] = '\0';
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_OSRELEASE;
+ len = sizeof(name->release);
+ oerrno = errno;
+ if (sysctl(mib, 2, &name->release, &len, NULL, 0) == -1) {
+ if(errno == ENOMEM)
+ errno = oerrno;
+ else
+ rval = -1;
+ }
+ name->release[sizeof(name->release) - 1] = '\0';
+
+ /* The version may have newlines in it, turn them into spaces. */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_VERSION;
+ len = sizeof(name->version);
+ oerrno = errno;
+ if (sysctl(mib, 2, &name->version, &len, NULL, 0) == -1) {
+ if (errno == ENOMEM)
+ errno = oerrno;
+ else
+ rval = -1;
+ }
+ name->version[sizeof(name->version) - 1] = '\0';
+ for (p = name->version; len--; ++p) {
+ if (*p == '\n' || *p == '\t') {
+ if (len > 1)
+ *p = ' ';
+ else
+ *p = '\0';
+ }
+ }
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_MACHINE;
+ len = sizeof(name->machine);
+ oerrno = errno;
+ if (sysctl(mib, 2, &name->machine, &len, NULL, 0) == -1) {
+ if (errno == ENOMEM)
+ errno = oerrno;
+ else
+ rval = -1;
+ }
+ name->machine[sizeof(name->machine) - 1] = '\0';
+ return (rval);
+}
diff --git a/lib/libc/gen/_rand48.c b/lib/libc/gen/_rand48.c
new file mode 100644
index 0000000..990e2c8
--- /dev/null
+++ b/lib/libc/gen/_rand48.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#include "rand48.h"
+
+unsigned short _rand48_seed[3] = {
+ RAND48_SEED_0,
+ RAND48_SEED_1,
+ RAND48_SEED_2
+};
+unsigned short _rand48_mult[3] = {
+ RAND48_MULT_0,
+ RAND48_MULT_1,
+ RAND48_MULT_2
+};
+unsigned short _rand48_add = RAND48_ADD;
+
+void
+_dorand48(unsigned short xseed[3])
+{
+ unsigned long accu;
+ unsigned short temp[2];
+
+ accu = (unsigned long) _rand48_mult[0] * (unsigned long) xseed[0] +
+ (unsigned long) _rand48_add;
+ temp[0] = (unsigned short) accu; /* lower 16 bits */
+ accu >>= sizeof(unsigned short) * 8;
+ accu += (unsigned long) _rand48_mult[0] * (unsigned long) xseed[1] +
+ (unsigned long) _rand48_mult[1] * (unsigned long) xseed[0];
+ temp[1] = (unsigned short) accu; /* middle 16 bits */
+ accu >>= sizeof(unsigned short) * 8;
+ accu += _rand48_mult[0] * xseed[2] + _rand48_mult[1] * xseed[1] + _rand48_mult[2] * xseed[0];
+ xseed[0] = temp[0];
+ xseed[1] = temp[1];
+ xseed[2] = (unsigned short) accu;
+}
diff --git a/lib/libc/gen/_spinlock_stub.c b/lib/libc/gen/_spinlock_stub.c
new file mode 100644
index 0000000..e3a800d
--- /dev/null
+++ b/lib/libc/gen/_spinlock_stub.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+
+/* Don't build these stubs into libc_r: */
+#ifndef _THREAD_SAFE
+#include "spinlock.h"
+
+/*
+ * Declare weak references in case the application is not linked
+ * with libpthread.
+ */
+#pragma weak _spinlock=_spinlock_stub
+#pragma weak _spinlock_debug=_spinlock_debug_stub
+
+/*
+ * This function is a stub for the spinlock function in libpthread.
+ */
+void
+_spinlock_stub(spinlock_t *lck)
+{
+}
+
+/*
+ * This function is a stub for the debug spinlock function in libpthread.
+ */
+void
+_spinlock_debug_stub(spinlock_t *lck, char *fname, int lineno)
+{
+}
+#endif
diff --git a/lib/libc/gen/alarm.3 b/lib/libc/gen/alarm.3
new file mode 100644
index 0000000..0265180
--- /dev/null
+++ b/lib/libc/gen/alarm.3
@@ -0,0 +1,96 @@
+.\" Copyright (c) 1980, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)alarm.3 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt ALARM 3
+.Os BSD 4
+.Sh NAME
+.Nm alarm
+.Nd set signal timer alarm
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft unsigned int
+.Fn alarm "unsigned int seconds"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is made obsolete by setitimer(2).
+.Ef
+.Pp
+The
+.Fn alarm
+function sets a timer to deliver the signal
+.Dv SIGALRM
+to the calling process after the specified number of
+.Fa seconds .
+If an alarm has already been set with
+.Fn alarm
+but has not been delivered, another call to
+.Fn alarm
+will supersede the prior call.
+The request
+.Fn alarm "0"
+voids the current
+alarm and the signal SIGALRM will not be delivered.
+.Pp
+Due to
+.Xr setitimer 2
+restriction the maximum number of
+.Ar seconds
+allowed is 100000000.
+.Sh RETURN VALUES
+.Pp
+The return value of
+.Fn alarm
+is the amount of time left on the timer from a previous call to
+.Fn alarm .
+If no alarm is currently set, the return value is 0.
+.Sh SEE ALSO
+.Xr setitimer 2 ,
+.Xr sigaction 2 ,
+.Xr sigpause 2 ,
+.Xr sigvec 2 ,
+.Xr signal 3 ,
+.Xr sleep 3 ,
+.Xr ualarm 3 ,
+.Xr usleep 3
+.\" .Sh STANDARDS
+.\" The
+.\" .Fn alarm
+.\" function conforms to
+.\" .St -p1003.1-90 .
+.Sh HISTORY
+An
+.Fn alarm
+function appeared in
+.At v7 .
diff --git a/lib/libc/gen/alarm.c b/lib/libc/gen/alarm.c
new file mode 100644
index 0000000..7a7dc68
--- /dev/null
+++ b/lib/libc/gen/alarm.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)alarm.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Backwards compatible alarm.
+ */
+#include <sys/time.h>
+#include <unistd.h>
+
+unsigned int
+alarm(secs)
+ unsigned int secs;
+{
+ struct itimerval it, oitv;
+ register struct itimerval *itp = &it;
+
+ timerclear(&itp->it_interval);
+ itp->it_value.tv_sec = secs;
+ itp->it_value.tv_usec = 0;
+ if (setitimer(ITIMER_REAL, itp, &oitv) < 0)
+ return (-1);
+ if (oitv.it_value.tv_usec)
+ oitv.it_value.tv_sec++;
+ return (oitv.it_value.tv_sec);
+}
diff --git a/lib/libc/gen/arc4random.3 b/lib/libc/gen/arc4random.3
new file mode 100644
index 0000000..334bb7b
--- /dev/null
+++ b/lib/libc/gen/arc4random.3
@@ -0,0 +1,84 @@
+.\" $OpenBSD: arc4random.3,v 1.2 1997/04/27 22:40:25 angelos Exp $
+.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Niels Provos.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" Manual page, using -mandoc macros
+.\" $FreeBSD$
+.\"
+.Dd April 15, 1997
+.Dt ARC4RANDOM 3
+.Os
+.Sh NAME
+.Nm arc4random ,
+.Nm arc4random_stir ,
+.Nm arc4random_addrandom
+.Nd arc4 random number generator.
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft u_int32_t
+.Fn arc4random "void"
+.Ft void
+.Fn arc4random_stir "void"
+.Ft void
+.Fn arc4random_addrandom "unsigned char *dat" "int datlen"
+.Sh DESCRIPTION
+The
+.Fn arc4random
+function uses the key stream generator employed by the
+arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes
+can be in about
+.if t 2\u\s71700\s10\d
+.if n (2**1700)
+states.
+.Pp
+The
+.Fn arc4random_stir
+function reads data from
+.Pa /dev/urandom
+and uses it to permute the S-Boxes via
+.Fn arc4random_addrandom .
+.Pp
+There is no need to call
+.Fn arc4random_stir
+before using
+.Fn arc4random ,
+since
+.Fn arc4random
+automatically initializes itself.
+.Sh SEE ALSO
+.Xr rand 3 ,
+.Xr random 3 ,
+.Xr srandomdev 3
+.Sh HISTORY
+.Pa RC4
+has been designed by RSA Data Security, Inc. It was posted anonymously
+to the USENET and was confirmed to be equivalent by several sources who
+had access to the original cipher. Since
+.Pa RC4
+used to be a trade secret, the cipher is now referred to as
+.Pa ARC4 .
diff --git a/lib/libc/gen/arc4random.c b/lib/libc/gen/arc4random.c
new file mode 100644
index 0000000..f331687
--- /dev/null
+++ b/lib/libc/gen/arc4random.c
@@ -0,0 +1,172 @@
+/* $FreeBSD$ */
+
+/*
+ * Arc4 random number generator for OpenBSD.
+ * Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
+ *
+ * Modification and redistribution in source and binary forms is
+ * permitted provided that due credit is given to the author and the
+ * OpenBSD project (for instance by leaving this copyright notice
+ * intact).
+ */
+
+/*
+ * This code is derived from section 17.1 of Applied Cryptography,
+ * second edition, which describes a stream cipher allegedly
+ * compatible with RSA Labs "RC4" cipher (the actual description of
+ * which is a trade secret). The same algorithm is used as a stream
+ * cipher called "arcfour" in Tatu Ylonen's ssh package.
+ *
+ * Here the stream cipher has been modified always to include the time
+ * when initializing the state. That makes it impossible to
+ * regenerate the same random sequence twice, so this can't be used
+ * for encryption, but will generate good random numbers.
+ *
+ * RC4 is a registered trademark of RSA Laboratories.
+ */
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+struct arc4_stream {
+ u_int8_t i;
+ u_int8_t j;
+ u_int8_t s[256];
+};
+
+static int rs_initialized;
+static struct arc4_stream rs;
+
+static inline void
+arc4_init(as)
+ struct arc4_stream *as;
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ as->s[n] = n;
+ as->i = 0;
+ as->j = 0;
+}
+
+static inline void
+arc4_addrandom(as, dat, datlen)
+ struct arc4_stream *as;
+ u_char *dat;
+ int datlen;
+{
+ int n;
+ u_int8_t si;
+
+ as->i--;
+ for (n = 0; n < 256; n++) {
+ as->i = (as->i + 1);
+ si = as->s[as->i];
+ as->j = (as->j + si + dat[n % datlen]);
+ as->s[as->i] = as->s[as->j];
+ as->s[as->j] = si;
+ }
+}
+
+static void
+arc4_stir(as)
+ struct arc4_stream *as;
+{
+ int fd;
+ struct {
+ struct timeval tv;
+ pid_t pid;
+ u_int8_t rnd[128 - sizeof(struct timeval) - sizeof(pid_t)];
+ } rdat;
+
+ gettimeofday(&rdat.tv, NULL);
+ rdat.pid = getpid();
+ fd = open("/dev/urandom", O_RDONLY, 0);
+ if (fd >= 0) {
+ (void) read(fd, rdat.rnd, sizeof(rdat.rnd));
+ close(fd);
+ }
+ /* fd < 0? Ah, what the heck. We'll just take whatever was on the
+ * stack... */
+
+ arc4_addrandom(as, (void *) &rdat, sizeof(rdat));
+}
+
+static inline u_int8_t
+arc4_getbyte(as)
+ struct arc4_stream *as;
+{
+ u_int8_t si, sj;
+
+ as->i = (as->i + 1);
+ si = as->s[as->i];
+ as->j = (as->j + si);
+ sj = as->s[as->j];
+ as->s[as->i] = sj;
+ as->s[as->j] = si;
+ return (as->s[(si + sj) & 0xff]);
+}
+
+static inline u_int32_t
+arc4_getword(as)
+ struct arc4_stream *as;
+{
+ u_int32_t val;
+ val = arc4_getbyte(as) << 24;
+ val |= arc4_getbyte(as) << 16;
+ val |= arc4_getbyte(as) << 8;
+ val |= arc4_getbyte(as);
+ return val;
+}
+
+void
+arc4random_stir()
+{
+ if (!rs_initialized) {
+ arc4_init(&rs);
+ rs_initialized = 1;
+ }
+ arc4_stir(&rs);
+}
+
+void
+arc4random_addrandom(dat, datlen)
+ u_char *dat;
+ int datlen;
+{
+ if (!rs_initialized)
+ arc4random_stir();
+ arc4_addrandom(&rs, dat, datlen);
+}
+
+u_int32_t
+arc4random()
+{
+ if (!rs_initialized)
+ arc4random_stir();
+ return arc4_getword(&rs);
+}
+
+#if 0
+/*-------- Test code for i386 --------*/
+#include <stdio.h>
+#include <machine/pctr.h>
+int
+main(int argc, char **argv)
+{
+ const int iter = 1000000;
+ int i;
+ pctrval v;
+
+ v = rdtsc();
+ for (i = 0; i < iter; i++)
+ arc4random();
+ v = rdtsc() - v;
+ v /= iter;
+
+ printf("%qd cycles\n", v);
+}
+#endif
diff --git a/lib/libc/gen/assert.c b/lib/libc/gen/assert.c
new file mode 100644
index 0000000..eb2748c
--- /dev/null
+++ b/lib/libc/gen/assert.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)assert.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void
+__assert(file, line, failedexpr)
+ const char *file, *failedexpr;
+ int line;
+{
+ (void)fprintf(stderr,
+ "assertion \"%s\" failed: file \"%s\", line %d\n",
+ failedexpr, file, line);
+ abort();
+ /* NOTREACHED */
+}
diff --git a/lib/libc/gen/clock.3 b/lib/libc/gen/clock.3
new file mode 100644
index 0000000..1d0f8fa
--- /dev/null
+++ b/lib/libc/gen/clock.3
@@ -0,0 +1,69 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)clock.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt CLOCK 3
+.Os
+.Sh NAME
+.Nm clock
+.Nd determine processor time used
+.Sh SYNOPSIS
+.Fd #include <time.h>
+.Ft clock_t
+.Fn clock void
+.Sh DESCRIPTION
+The
+.Fn clock
+function
+determines the amount of processor time used since the invocation of the
+calling process, measured in
+.Dv CLOCKS_PER_SEC Ns 's
+of a second.
+.Sh RETURN VALUES
+The
+.Fn clock
+function returns the amount of time used unless an error occurs, in which
+case the return value is \-1.
+.Sh SEE ALSO
+.Xr getrusage 2 ,
+.Xr clocks 7
+.Sh STANDARDS
+The
+.Fn clock
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/gen/clock.c b/lib/libc/gen/clock.c
new file mode 100644
index 0000000..fe867c2
--- /dev/null
+++ b/lib/libc/gen/clock.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)clock.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+/*
+ * Convert usec to clock ticks; could do (usec * CLOCKS_PER_SEC) / 1000000,
+ * but this would overflow if we switch to nanosec.
+ */
+#define CONVTCK(r) ((r).tv_sec * CLOCKS_PER_SEC \
+ + (r).tv_usec / (1000000 / CLOCKS_PER_SEC))
+
+clock_t
+clock()
+{
+ struct rusage ru;
+
+ if (getrusage(RUSAGE_SELF, &ru))
+ return ((clock_t) -1);
+ return((clock_t)((CONVTCK(ru.ru_utime) + CONVTCK(ru.ru_stime))));
+}
diff --git a/lib/libc/gen/closedir.c b/lib/libc/gen/closedir.c
new file mode 100644
index 0000000..6c46e70
--- /dev/null
+++ b/lib/libc/gen/closedir.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1983, 1993
+ * Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)closedir.c 8.1 (Berkeley) 6/10/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+extern void _reclaim_telldir __P(( const DIR * ));
+
+/*
+ * close a directory.
+ */
+int
+closedir(dirp)
+ register DIR *dirp;
+{
+ int fd;
+
+ seekdir(dirp, dirp->dd_rewind); /* free seekdir storage */
+ fd = dirp->dd_fd;
+ dirp->dd_fd = -1;
+ dirp->dd_loc = 0;
+ free((void *)dirp->dd_buf);
+ free((void *)dirp);
+ _reclaim_telldir(dirp);
+ return(close(fd));
+}
diff --git a/lib/libc/gen/confstr.3 b/lib/libc/gen/confstr.3
new file mode 100644
index 0000000..6ba8e7c
--- /dev/null
+++ b/lib/libc/gen/confstr.3
@@ -0,0 +1,126 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)confstr.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt CONFSTR 3
+.Os BSD 4
+.Sh NAME
+.Nm confstr
+.Nd get string-valued configurable variables
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft size_t
+.Fn confstr "int name" "char *buf" "size_t len"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is obsoleted by
+.Xr sysctl 3 .
+.Ef
+.Pp
+The
+.Fn confstr
+function provides a method for applications to get configuration
+defined string values.
+.Pp
+The
+.Fa name
+argument specifies the system variable to be queried.
+Symbolic constants for each name value are found in the include file
+.Li <unistd.h> .
+The
+.Fa len
+argument specifies the size of the buffer referenced by the
+argument
+.Fa buf .
+If
+.Fa len
+is non-zero,
+.Fa buf
+is a non-null pointer, and
+.Fa name
+has a value, up to
+.Fa len
+\- 1 bytes of the value are copied into the buffer
+.Fa buf .
+The copied value is always null terminated.
+.Pp
+The available values are as follows:
+.Pp
+.Bl -tag -width "123456"
+.Pp
+.It Li _CS_PATH
+Return a value for the
+.Ev PATH
+environment variable that finds all the standard utilities.
+.El
+.Sh RETURN VALUES
+If the call to
+.Fn confstr
+is not successful, \-1 is returned and
+.Va errno
+is set appropriately.
+Otherwise, if the variable does not have a configuration defined value,
+0 is returned and
+.Va errno
+is not modified.
+Otherwise, the buffer size needed to hold the entire configuration-defined
+value is returned.
+If this size is greater than the argument
+.Fa len ,
+the string in
+.Fa buf
+was truncated.
+.Sh ERRORS
+The
+.Fn confstr
+function may fail and set
+.Va error
+for any of the errors specified for the library functions
+.Xr malloc 3
+and
+.Xr sysctl 3 .
+.Pp
+In addition, the following errors may be reported:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value of the
+.Fa name
+argument is invalid.
+.Sh SEE ALSO
+.Xr sysctl 3
+.Sh HISTORY
+The
+.Fn confstr
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/gen/confstr.c b/lib/libc/gen/confstr.c
new file mode 100644
index 0000000..0a7078e
--- /dev/null
+++ b/lib/libc/gen/confstr.c
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)confstr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#include <errno.h>
+#include <paths.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+size_t
+confstr(name, buf, len)
+ int name;
+ char *buf;
+ size_t len;
+{
+ size_t tlen;
+ int mib[2], sverrno;
+ char *p;
+
+ switch (name) {
+ case _CS_PATH:
+ mib[0] = CTL_USER;
+ mib[1] = USER_CS_PATH;
+ if (sysctl(mib, 2, NULL, &tlen, NULL, 0) == -1)
+ return (-1);
+ if (len != 0 && buf != NULL) {
+ if ((p = malloc(tlen)) == NULL)
+ return (-1);
+ if (sysctl(mib, 2, p, &tlen, NULL, 0) == -1) {
+ sverrno = errno;
+ free(p);
+ errno = sverrno;
+ return (-1);
+ }
+ /*
+ * POSIX 1003.2 requires partial return of
+ * the string -- that should be *real* useful.
+ */
+ (void)strncpy(buf, p, len - 1);
+ buf[len - 1] = '\0';
+ free(p);
+ }
+ return (tlen + 1);
+ default:
+ errno = EINVAL;
+ return (0);
+ }
+ /* NOTREACHED */
+}
diff --git a/lib/libc/gen/crypt.3 b/lib/libc/gen/crypt.3
new file mode 100644
index 0000000..4a111f8
--- /dev/null
+++ b/lib/libc/gen/crypt.3
@@ -0,0 +1,297 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)crypt.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt CRYPT 3
+.Os
+.Sh NAME
+.Nm crypt ,
+.Nm setkey ,
+.Nm encrypt ,
+.Nm des_setkey ,
+.Nm des_cipher
+.Nd DES encryption
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft char *
+.Fn crypt "const char *key" "const char *setting"
+.Ft int
+.Fn setkey "const char *key"
+.Ft int
+.Fn encrypt "char *block" "int flag"
+.Ft int
+.Fn des_setkey "const char *key"
+.Ft int
+.Fn des_cipher "const char *in" "char *out" "long salt" "int count"
+.Sh DESCRIPTION
+The
+.Fn crypt
+function
+performs password encryption.
+It is derived from the
+.Tn NBS
+Data Encryption Standard.
+Additional code has been added to deter
+key search attempts.
+The first argument to
+.Nm crypt
+is
+a
+.Dv NUL Ns -terminated
+string (normally a password typed by a user).
+The second is a character array, 9 bytes in length, consisting of an
+underscore (``_'') followed by 4 bytes of iteration count and 4 bytes
+of salt.
+Both the iteration
+.Fa count
+and the
+.Fa salt
+are encoded with 6 bits per character, least significant bits first.
+The values 0 to 63 are encoded by the characters ``./0-9A-Za-z'',
+respectively.
+.Pp
+The
+.Fa salt
+is used to induce disorder in to the
+.Tn DES
+algorithm
+in one of 16777216
+possible ways
+(specifically, if bit
+.Em i
+of the
+.Ar salt
+is set then bits
+.Em i
+and
+.Em i+24
+are swapped in the
+.Tn DES
+``E'' box output).
+The
+.Ar key
+is divided into groups of 8 characters (a short final group is null-padded)
+and the low-order 7 bits of each character (56 bits per group) are
+used to form the DES key as follows: the first group of 56 bits becomes the
+initial DES key.
+For each additional group, the XOR of the group bits and the encryption of
+the DES key with itself becomes the next DES key.
+Then the final DES key is used to perform
+.Ar count
+cumulative encryptions of a 64-bit constant.
+The value returned is a
+.Dv NUL Ns -terminated
+string, 20 bytes in length, consisting
+of the
+.Ar setting
+followed by the encoded 64-bit encryption.
+.Pp
+For compatibility with historical versions of
+.Xr crypt 3 ,
+the
+.Ar setting
+may consist of 2 bytes of salt, encoded as above, in which case an
+iteration
+.Ar count
+of 25 is used, fewer perturbations of
+.Tn DES
+are available, at most 8
+characters of
+.Ar key
+are used, and the returned value is a
+.Dv NUL Ns -terminated
+string 13 bytes in length.
+.Pp
+The
+functions,
+.Fn encrypt ,
+.Fn setkey ,
+.Fn des_setkey
+and
+.Fn des_cipher
+allow limited access to the
+.Tn DES
+algorithm itself.
+The
+.Ar key
+argument to
+.Fn setkey
+is a 64 character array of
+binary values (numeric 0 or 1).
+A 56-bit key is derived from this array by dividing the array
+into groups of 8 and ignoring the last bit in each group.
+.Pp
+The
+.Fn encrypt
+argument
+.Fa block
+is also a 64 character array of
+binary values.
+If the value of
+.Fa flag
+is 0,
+the argument
+.Fa block
+is encrypted, otherwise it
+is decrypted.
+The encryption or decryption is returned in the original
+array
+.Fa block
+after using the
+key specified
+by
+.Fn setkey
+to process it.
+.Pp
+The
+.Fn des_setkey
+and
+.Fn des_cipher
+functions are faster but less portable than
+.Fn setkey
+and
+.Fn encrypt .
+The argument to
+.Fn des_setkey
+is a character array of length 8.
+The
+.Em least
+significant bit in each character is ignored and the next 7 bits of each
+character are concatenated to yield a 56-bit key.
+The function
+.Fn des_cipher
+encrypts (or decrypts if
+.Fa count
+is negative) the 64-bits stored in the 8 characters at
+.Fa in
+using
+.Xr abs 3
+of
+.Fa count
+iterations of
+.Tn DES
+and stores the 64-bit result in the 8 characters at
+.Fa out .
+The
+.Fa salt
+specifies perturbations to
+.Tn DES
+as described above.
+.Pp
+The function
+.Fn crypt
+returns a pointer to the encrypted value on success and NULL on failure.
+The functions
+.Fn setkey ,
+.Fn encrypt ,
+.Fn des_setkey ,
+and
+.Fn des_cipher
+return 0 on success and 1 on failure.
+Historically, the functions
+.Fn setkey
+and
+.Fn encrypt
+did not return any value.
+They have been provided return values primarily to distinguish
+implementations where hardware support is provided but not
+available or where the DES encryption is not available due to the
+usual political silliness.
+.Pp
+Use of
+.Fn crypt
+requires linking with the
+.Nm libcrypt
+library. The
+.Fn setkey ,
+.Fn encrypt ,
+.Fn des_setkey
+and
+.Fn des_cipher
+can be found in the
+.Nm libcipher
+library (the standard C library,
+.Nm libc ,
+only contains stubs to these routines).
+.Sh SEE ALSO
+.Xr login 1 ,
+.Xr passwd 1 ,
+.Xr getpass 3 ,
+.Xr passwd 5
+.Rs
+.%T "Mathematical Cryptology for Computer Scientists and Mathematicians"
+.%A Wayne Patterson
+.%D 1987
+.%N ISBN 0-8476-7438-X
+.Re
+.Rs
+.%T "Password Security: A Case History"
+.%A R. Morris
+.%A Ken Thompson
+.%J "Communications of the ACM"
+.%V vol. 22
+.%P pp. 594-597
+.%D Nov. 1979
+.Re
+.Rs
+.%T "DES will be Totally Insecure within Ten Years"
+.%A M.E. Hellman
+.%J "IEEE Spectrum"
+.%V vol. 16
+.%P pp. 32-39
+.%D July 1979
+.Re
+.Sh HISTORY
+A rotor-based
+.Fn crypt
+function appeared in
+.At v6 .
+The current style
+.Fn crypt
+first appeared in
+.At v7 .
+.Sh BUGS
+Dropping the
+.Em least
+significant bit in each character of the argument to
+.Fn des_setkey
+is ridiculous.
+.Pp
+The
+.Fn crypt
+function leaves its result in an internal static object and returns
+a pointer to that object.
+Subsequent calls to
+.Fn crypt
+will modify the same object.
diff --git a/lib/libc/gen/crypt.c b/lib/libc/gen/crypt.c
new file mode 100644
index 0000000..8012b06
--- /dev/null
+++ b/lib/libc/gen/crypt.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Tom Truscott.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/* from static char sccsid[] = "@(#)crypt.c 5.11 (Berkeley) 6/25/91"; */
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+/*
+ * UNIX password, and DES, encryption.
+ *
+ * since this is non-exportable, this is just a dummy. if you want real
+ * encryption, make sure you've got libcrypt.a around.
+ */
+
+__warn_references(des_setkey,
+ "WARNING! des_setkey(3) not present in the system!");
+
+int
+des_setkey(key)
+ register const char *key;
+{
+ fprintf(stderr, "WARNING! des_setkey(3) not present in the system!\n");
+ return (0);
+}
+
+__warn_references(des_cipher,
+ "WARNING! des_cipher(3) not present in the system!");
+
+int
+des_cipher(in, out, salt, num_iter)
+ const char *in;
+ char *out;
+ long salt;
+ int num_iter;
+{
+ fprintf(stderr, "WARNING! des_cipher(3) not present in the system!\n");
+ bcopy(in, out, 8);
+ return (0);
+}
+
+__warn_references(setkey,
+ "WARNING! setkey(3) not present in the system!");
+
+int
+setkey(key)
+ register const char *key;
+{
+ fprintf(stderr, "WARNING! setkey(3) not present in the system!\n");
+ return (0);
+}
+
+__warn_references(encrypt,
+ "WARNING! encrypt(3) not present in the system!");
+
+int
+encrypt(block, flag)
+ register char *block;
+ int flag;
+{
+ fprintf(stderr, "WARNING! encrypt(3) not present in the system!\n");
+ return (0);
+}
diff --git a/lib/libc/gen/ctermid.3 b/lib/libc/gen/ctermid.3
new file mode 100644
index 0000000..3b1668f
--- /dev/null
+++ b/lib/libc/gen/ctermid.3
@@ -0,0 +1,107 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ctermid.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt CTERMID 3
+.Os
+.Sh NAME
+.Nm ctermid
+.Nd generate terminal pathname
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft char *
+.Fn ctermid "char *buf"
+.Ft char *
+.Fn ctermid_r "char *buf"
+.Sh DESCRIPTION
+The
+.Fn ctermid
+function generates a string, that, when used as a pathname, refers to
+the current controlling terminal of the calling process.
+.Pp
+If
+.Ar buf
+is the
+.Dv NULL
+pointer, a pointer to a static area is returned.
+Otherwise, the pathname is copied into the memory referenced by
+.Ar buf .
+The argument
+.Ar buf
+is assumed to be at least
+.Dv L_ctermid
+(as defined in the include
+file
+.Aq Pa stdio.h )
+bytes long.
+.Pp
+.Fn ctermid_r
+provides the same functionality as
+.Fn ctermid
+except that if
+.Ar buf
+is a
+.Dv NULL
+pointer,
+.Dv NULL
+is returned.
+.Pp
+The current implementation simply returns
+.Ql /dev/tty .
+.Sh RETURN VALUES
+Upon successful completion, a
+.Pf non- Dv NULL
+pointer is returned.
+Otherwise, a
+.Dv NULL
+pointer is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The current implementation detects no error conditions.
+.Sh SEE ALSO
+.Xr ttyname 3
+.Sh STANDARDS
+The
+.Fn ctermid
+function conforms to
+.St -p1003.1-88 .
+.Sh BUGS
+By default the
+.Fn ctermid
+function
+writes all information to an internal static object.
+Subsequent calls to
+.Fn ctermid
+will modify the same object.
diff --git a/lib/libc/gen/ctermid.c b/lib/libc/gen/ctermid.c
new file mode 100644
index 0000000..e43d6ab
--- /dev/null
+++ b/lib/libc/gen/ctermid.c
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ctermid.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <paths.h>
+#include <string.h>
+
+char *
+ctermid(char *s)
+{
+ static char def[] = _PATH_TTY;
+
+ if (s) {
+ bcopy(def, s, sizeof(_PATH_TTY));
+ return(s);
+ }
+ return(def);
+}
+
+
+char *
+ctermid_r(char *s)
+{
+ return (s) ? ctermid(s) : NULL;
+}
diff --git a/lib/libc/gen/daemon.3 b/lib/libc/gen/daemon.3
new file mode 100644
index 0000000..fa423d6
--- /dev/null
+++ b/lib/libc/gen/daemon.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)daemon.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt DAEMON 3
+.Os
+.Sh NAME
+.Nm daemon
+.Nd run in the background
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft int
+.Fn daemon "int nochdir" "int noclose"
+.Sh DESCRIPTION
+.Pp
+The
+.Fn daemon
+function is for programs wishing to detach themselves from the
+controlling terminal and run in the background as system daemons.
+.Pp
+Unless the argument
+.Fa nochdir
+is non-zero,
+.Fn daemon
+changes the current working directory to the root (``/'').
+.Pp
+Unless the argument
+.Fa noclose
+is non-zero,
+.Fn daemon
+will redirect standard input, standard output and standard error
+to ``/dev/null''.
+.Sh ERRORS
+If an error occurs,
+.Fn daemon
+returns -1 and sets the global variable
+.Va errno
+to any of the errors specified for the library functions
+.Xr fork 2
+and
+.Xr setsid 2 .
+.Sh SEE ALSO
+.Xr fork 2 ,
+.Xr setsid 2
+.Sh HISTORY
+The
+.Fn daemon
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/gen/daemon.c b/lib/libc/gen/daemon.c
new file mode 100644
index 0000000..6b3409c
--- /dev/null
+++ b/lib/libc/gen/daemon.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <fcntl.h>
+#include <paths.h>
+#include <unistd.h>
+
+int
+daemon(nochdir, noclose)
+ int nochdir, noclose;
+{
+ int fd;
+
+ switch (fork()) {
+ case -1:
+ return (-1);
+ case 0:
+ break;
+ default:
+ _exit(0);
+ }
+
+ if (setsid() == -1)
+ return (-1);
+
+ if (!nochdir)
+ (void)chdir("/");
+
+ if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+ (void)dup2(fd, STDIN_FILENO);
+ (void)dup2(fd, STDOUT_FILENO);
+ (void)dup2(fd, STDERR_FILENO);
+ if (fd > 2)
+ (void)close (fd);
+ }
+ return (0);
+}
diff --git a/lib/libc/gen/devname.3 b/lib/libc/gen/devname.3
new file mode 100644
index 0000000..2030125
--- /dev/null
+++ b/lib/libc/gen/devname.3
@@ -0,0 +1,69 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)devname.3 8.2 (Berkeley) 4/29/95
+.\" $FreeBSD$
+.\"
+.Dd April 29, 1995
+.Dt DEVNAME 3
+.Os BSD 4.4
+.Sh NAME
+.Nm devname
+.Nd get device name
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft char *
+.Fn devname "dev_t dev" "mode_t type"
+.Sh DESCRIPTION
+The
+.Fn devname
+function returns a pointer to the name of the block or character
+device in
+.Dq Pa /dev
+with a device number of
+.Fa dev ,
+and a file type matching the one encoded in
+.Fa type
+which must be one of S_IFBLK or S_IFCHR.
+If no device matches the specified values, or no information is
+available, NULL is returned.
+.Pp
+The traditional display for applications when no device is
+found is the string
+.Dq ?? .
+.Sh SEE ALSO
+.Xr stat 2 ,
+.Xr dev_mkdb 8
+.Sh HISTORY
+The
+.Fn devname
+function call appeared in
+.Bx 4.4 .
diff --git a/lib/libc/gen/devname.c b/lib/libc/gen/devname.c
new file mode 100644
index 0000000..898c8e8
--- /dev/null
+++ b/lib/libc/gen/devname.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)devname.c 8.2 (Berkeley) 4/29/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <db.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+static char *
+xdevname(dev, type)
+ dev_t dev;
+ mode_t type;
+{
+ struct {
+ mode_t type;
+ dev_t dev;
+ } bkey;
+ static DB *db;
+ static int failure;
+ DBT data, key;
+
+ if (!db && !failure &&
+ !(db = dbopen(_PATH_DEVDB, O_RDONLY, 0, DB_HASH, NULL))) {
+ warn("warning: %s", _PATH_DEVDB);
+ failure = 1;
+ }
+ if (failure)
+ return (NULL);
+
+ /*
+ * Keys are a mode_t followed by a dev_t. The former is the type of
+ * the file (mode & S_IFMT), the latter is the st_rdev field. Be
+ * sure to clear any padding that may be found in bkey.
+ */
+ memset(&bkey, 0, sizeof(bkey));
+ bkey.dev = dev;
+ bkey.type = type;
+ key.data = &bkey;
+ key.size = sizeof(bkey);
+ return ((db->get)(db, &key, &data, 0) ? NULL : (char *)data.data);
+}
+
+char *
+devname(dev, type)
+ dev_t dev;
+ mode_t type;
+{
+ static char buf[20];
+ char *r;
+
+ r = xdevname(dev, type);
+ if (!r) {
+ r = buf;
+ if (minor(dev) > 255) {
+ sprintf(buf, "#%c%d:0x%x",
+ (type & S_IFMT) == S_IFCHR ? 'C' : 'B',
+ major(dev), minor(dev));
+ } else {
+ sprintf(buf, "#%c%d:%d",
+ (type & S_IFMT) == S_IFCHR ? 'C' : 'B',
+ major(dev), minor(dev));
+ }
+ }
+ return (r);
+}
diff --git a/lib/libc/gen/directory.3 b/lib/libc/gen/directory.3
new file mode 100644
index 0000000..6334d38
--- /dev/null
+++ b/lib/libc/gen/directory.3
@@ -0,0 +1,198 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)directory.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt DIRECTORY 3
+.Os BSD 4.2
+.Sh NAME
+.Nm opendir ,
+.Nm readdir ,
+.Nm readdir_r ,
+.Nm telldir ,
+.Nm seekdir ,
+.Nm rewinddir ,
+.Nm closedir ,
+.Nm dirfd
+.Nd directory operations
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <dirent.h>
+.Ft DIR *
+.Fn opendir "const char *filename"
+.Ft struct dirent *
+.Fn readdir "DIR *dirp"
+.Ft int
+.Fn readdir_r "DIR *dirp" "struct dirent *entry" "struct dirent **result"
+.Ft long
+.Fn telldir "const DIR *dirp"
+.Ft void
+.Fn seekdir "DIR *dirp" "long loc"
+.Ft void
+.Fn rewinddir "DIR *dirp"
+.Ft int
+.Fn closedir "DIR *dirp"
+.Ft int
+.Fn dirfd "DIR *dirp"
+.Sh DESCRIPTION
+The
+.Fn opendir
+function
+opens the directory named by
+.Fa filename ,
+associates a
+.Em directory stream
+with it
+and
+returns a pointer to be used to identify the
+.Em directory stream
+in subsequent operations. The pointer
+.Dv NULL
+is returned if
+.Fa filename
+cannot be accessed, or if it cannot
+.Xr malloc 3
+enough memory to hold the whole thing.
+.Pp
+The
+.Fn readdir
+function
+returns a pointer to the next directory entry. It returns
+.Dv NULL
+upon reaching the end of the directory or detecting an invalid
+.Fn seekdir
+operation.
+.Pp
+.Fn readdir_r
+provides the same functionality as
+.Fn readdir ,
+but the caller must provide a directory
+.Fa entry
+buffer to store the results in. If the read succeeds,
+.Fa result
+is pointed at the
+.Fa entry ;
+upon reaching the end of the directory
+.Fa result
+is set to
+.Dv NULL .
+.Fn readdir_r
+returns 0 on success or an error number to indicate failure.
+.Pp
+The
+.Fn telldir
+function
+returns the current location associated with the named
+.Em directory stream .
+Values returned by
+.Fn telldir
+are good only for the lifetime of the
+.Dv DIR
+pointer,
+.Fa dirp ,
+from which they are derived. If the directory is closed and then
+reopened, prior values returned by
+.Fn telldir
+will no longer be valid.
+.Pp
+The
+.Fn seekdir
+function
+sets the position of the next
+.Fn readdir
+operation on the
+.Em directory stream .
+The new position reverts to the one associated with the
+.Em directory stream
+when the
+.Fn telldir
+operation was performed.
+.Pp
+The
+.Fn rewinddir
+function
+resets the position of the named
+.Em directory stream
+to the beginning of the directory.
+.Pp
+The
+.Fn closedir
+function
+closes the named
+.Em directory stream
+and frees the structure associated with the
+.Fa dirp
+pointer,
+returning 0 on success.
+On failure, \-1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Pp
+The
+.Fn dirfd
+function
+returns the integer file descriptor associated with the named
+.Em directory stream ,
+see
+.Xr open 2 .
+.Pp
+Sample code which searches a directory for entry ``name'' is:
+.Bd -literal -offset indent
+len = strlen(name);
+dirp = opendir(".");
+while ((dp = readdir(dirp)) != NULL)
+ if (dp->d_namlen == len && !strcmp(dp->d_name, name)) {
+ (void)closedir(dirp);
+ return FOUND;
+ }
+(void)closedir(dirp);
+return NOT_FOUND;
+.Ed
+.Sh SEE ALSO
+.Xr close 2 ,
+.Xr lseek 2 ,
+.Xr open 2 ,
+.Xr read 2 ,
+.Xr dir 5
+.Sh HISTORY
+The
+.Fn opendir ,
+.Fn readdir ,
+.Fn telldir ,
+.Fn seekdir ,
+.Fn rewinddir ,
+.Fn closedir ,
+and
+.Fn dirfd
+functions appeared in
+.Bx 4.2 .
diff --git a/lib/libc/gen/disklabel.c b/lib/libc/gen/disklabel.c
new file mode 100644
index 0000000..c7ac0b4
--- /dev/null
+++ b/lib/libc/gen/disklabel.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 1983, 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)disklabel.c 8.2 (Berkeley) 5/3/95";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* not lint */
+
+#include <sys/param.h>
+#define DKTYPENAMES
+#include <sys/disklabel.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+
+static int gettype __P((char *, char **));
+
+struct disklabel *
+getdiskbyname(name)
+ const char *name;
+{
+ static struct disklabel disk;
+ register struct disklabel *dp = &disk;
+ register struct partition *pp;
+ char *buf;
+ char *db_array[2] = { _PATH_DISKTAB, 0 };
+ char *cp, *cq; /* can't be register */
+ char p, max, psize[3], pbsize[3],
+ pfsize[3], poffset[3], ptype[3];
+ u_int32_t *dx;
+
+ if (cgetent(&buf, db_array, (char *) name) < 0)
+ return NULL;
+
+ bzero((char *)&disk, sizeof(disk));
+ /*
+ * typename
+ */
+ cq = dp->d_typename;
+ cp = buf;
+ while (cq < dp->d_typename + sizeof(dp->d_typename) - 1 &&
+ (*cq = *cp) && *cq != '|' && *cq != ':')
+ cq++, cp++;
+ *cq = '\0';
+ /*
+ * boot name (optional) xxboot, bootxx
+ */
+ cgetstr(buf, "b0", &dp->d_boot0);
+ cgetstr(buf, "b1", &dp->d_boot1);
+
+ if (cgetstr(buf, "ty", &cq) > 0 && strcmp(cq, "removable") == 0)
+ dp->d_flags |= D_REMOVABLE;
+ else if (cq && strcmp(cq, "simulated") == 0)
+ dp->d_flags |= D_RAMDISK;
+ if (cgetcap(buf, "sf", ':') != NULL)
+ dp->d_flags |= D_BADSECT;
+
+#define getnumdflt(field, dname, dflt) \
+ { long f; (field) = (cgetnum(buf, dname, &f) == -1) ? (dflt) : f; }
+
+ getnumdflt(dp->d_secsize, "se", DEV_BSIZE);
+ getnumdflt(dp->d_ntracks, "nt", 0);
+ getnumdflt(dp->d_nsectors, "ns", 0);
+ getnumdflt(dp->d_ncylinders, "nc", 0);
+
+ if (cgetstr(buf, "dt", &cq) > 0)
+ dp->d_type = gettype(cq, dktypenames);
+ else
+ getnumdflt(dp->d_type, "dt", 0);
+ getnumdflt(dp->d_secpercyl, "sc", dp->d_nsectors * dp->d_ntracks);
+ getnumdflt(dp->d_secperunit, "su", dp->d_secpercyl * dp->d_ncylinders);
+ getnumdflt(dp->d_rpm, "rm", 3600);
+ getnumdflt(dp->d_interleave, "il", 1);
+ getnumdflt(dp->d_trackskew, "sk", 0);
+ getnumdflt(dp->d_cylskew, "cs", 0);
+ getnumdflt(dp->d_headswitch, "hs", 0);
+ getnumdflt(dp->d_trkseek, "ts", 0);
+ getnumdflt(dp->d_bbsize, "bs", BBSIZE);
+ getnumdflt(dp->d_sbsize, "sb", SBSIZE);
+ strcpy(psize, "px");
+ strcpy(pbsize, "bx");
+ strcpy(pfsize, "fx");
+ strcpy(poffset, "ox");
+ strcpy(ptype, "tx");
+ max = 'a' - 1;
+ pp = &dp->d_partitions[0];
+ for (p = 'a'; p < 'a' + MAXPARTITIONS; p++, pp++) {
+ long l;
+ psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p;
+ if (cgetnum(buf, psize, &l) == -1)
+ pp->p_size = 0;
+ else {
+ pp->p_size = l;
+ cgetnum(buf, poffset, &l);
+ pp->p_offset = l;
+ getnumdflt(pp->p_fsize, pfsize, 0);
+ if (pp->p_fsize) {
+ long bsize;
+
+ if (cgetnum(buf, pbsize, &bsize) == 0)
+ pp->p_frag = bsize / pp->p_fsize;
+ else
+ pp->p_frag = 8;
+ }
+ getnumdflt(pp->p_fstype, ptype, 0);
+ if (pp->p_fstype == 0 && cgetstr(buf, ptype, &cq) > 0)
+ pp->p_fstype = gettype(cq, fstypenames);
+ max = p;
+ }
+ }
+ dp->d_npartitions = max + 1 - 'a';
+ (void)strcpy(psize, "dx");
+ dx = dp->d_drivedata;
+ for (p = '0'; p < '0' + NDDATA; p++, dx++) {
+ psize[1] = p;
+ getnumdflt(*dx, psize, 0);
+ }
+ dp->d_magic = DISKMAGIC;
+ dp->d_magic2 = DISKMAGIC;
+ free(buf);
+ return (dp);
+}
+
+static int
+gettype(t, names)
+ char *t;
+ char **names;
+{
+ register char **nm;
+
+ for (nm = names; *nm; nm++)
+ if (strcasecmp(t, *nm) == 0)
+ return (nm - names);
+ if (isdigit((unsigned char)*t))
+ return (atoi(t));
+ return (0);
+}
diff --git a/lib/libc/gen/dladdr.3 b/lib/libc/gen/dladdr.3
new file mode 100644
index 0000000..9938a7a
--- /dev/null
+++ b/lib/libc/gen/dladdr.3
@@ -0,0 +1,121 @@
+.\"
+.\" Copyright (c) 1998 John D. Polstra
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 5, 1998
+.Os FreeBSD
+.Dt DLADDR 3
+.Sh NAME
+.Nm dladdr
+.Nd find the shared object containing a given address
+.Sh SYNOPSIS
+.Fd #include <dlfcn.h>
+.Ft int
+.Fn dladdr "const void *addr" "Dl_info *info"
+.Sh DESCRIPTION
+.Nm
+queries the dynamic linker for information about the shared object
+containing the address
+.Fa addr .
+The information is returned in the structure specified by
+.Fa info .
+The structure contains at least the following members:
+.Bl -tag -width "XXXconst char *dli_fname"
+.It Li "const char *dli_fname"
+The pathname of the shared object containing the address.
+.It Li "void *dli_fbase"
+The base address at which the shared object is mapped into the
+address space of the calling process.
+.It Li "const char *dli_sname"
+The name of the nearest run-time symbol with a value less than or
+equal to
+.Fa addr .
+When possible, the symbol name is returned as it would appear in C
+source code.
+.Pp
+If no symbol with a suitable value is found, both this field and
+.Va dli_saddr
+are set to
+.Dv NULL .
+.It Li "void *dli_saddr"
+The value of the symbol returned in
+.Li dli_sname .
+.El
+.Pp
+.Nm
+is available only in dynamically linked programs.
+.Sh ERRORS
+If a mapped shared object containing
+.Fa addr
+cannot be found,
+.Nm
+returns 0.
+In that case, a message detailing the failure can be retrieved by
+calling
+.Fn dlerror .
+.Pp
+On success, a non-zero value is returned.
+.Sh SEE ALSO
+.Xr rtld 1 ,
+.Xr dlopen 3
+.Sh HISTORY
+The
+.Nm
+function first appeared in the Solaris operating system.
+.Sh BUGS
+This implementation is bug-compatible with the Solaris
+implementation. In particular, the following bugs are present:
+.Bl -bullet
+.It
+If
+.Fa addr
+lies in the main executable rather than in a shared library, the
+pathname returned in
+.Va dli_fname
+may not be correct. The pathname is taken directly from
+.Va argv[0]
+of the calling process. When executing a program specified by its
+full pathname, most shells set
+.Va argv[0]
+to the pathname. But this is not required of shells or guaranteed
+by the operating system.
+.It
+If
+.Fa addr
+is of the form
+.Va &func ,
+where
+.Va func
+is a global function, its value may be an unpleasant surprise. In
+dynamically linked programs, the address of a global function is
+considered to point to its program linkage table entry, rather than to
+the entry point of the function itself. This causes most global
+functions to appear to be defined within the main executable, rather
+than in the shared libraries where the actual code resides.
+.It
+Returning 0 as an indication of failure goes against long-standing
+Unix tradition.
+.El
diff --git a/lib/libc/gen/dlfcn.c b/lib/libc/gen/dlfcn.c
new file mode 100644
index 0000000..ff77b79
--- /dev/null
+++ b/lib/libc/gen/dlfcn.c
@@ -0,0 +1,168 @@
+/*-
+ * Copyright (c) 1998 John D. Polstra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Linkage to services provided by the dynamic linker. These are
+ * implemented differently in ELF and a.out, because the dynamic
+ * linkers have different interfaces.
+ */
+
+#ifdef __ELF__
+
+#include <dlfcn.h>
+#include <stddef.h>
+
+static const char sorry[] = "Service unavailable";
+
+/*
+ * For ELF, the dynamic linker directly resolves references to its
+ * services to functions inside the dynamic linker itself. These
+ * weak-symbol stubs are necessary so that "ld" won't complain about
+ * undefined symbols. The stubs are executed only when the program is
+ * linked statically, or when a given service isn't implemented in the
+ * dynamic linker. They must return an error if called, and they must
+ * be weak symbols so that the dynamic linker can override them.
+ */
+
+#pragma weak _rtld_error
+void
+_rtld_error(const char *fmt, ...)
+{
+}
+
+#pragma weak dladdr
+int
+dladdr(const void *addr, Dl_info *dlip)
+{
+ _rtld_error(sorry);
+ return 0;
+}
+
+#pragma weak dlclose
+int
+dlclose(void *handle)
+{
+ _rtld_error(sorry);
+ return -1;
+}
+
+#pragma weak dlerror
+const char *
+dlerror(void)
+{
+ return sorry;
+}
+
+#pragma weak dlopen
+void *
+dlopen(const char *name, int mode)
+{
+ _rtld_error(sorry);
+ return NULL;
+}
+
+#pragma weak dlsym
+void *
+dlsym(void *handle, const char *name)
+{
+ _rtld_error(sorry);
+ return NULL;
+}
+
+#else /* a.out format */
+
+#include <sys/types.h>
+#include <nlist.h> /* XXX - Required by link.h */
+#include <dlfcn.h>
+#include <link.h>
+#include <stddef.h>
+
+/*
+ * For a.out, entry to the dynamic linker is via these trampolines.
+ * They enter the dynamic linker through the ld_entry struct that was
+ * passed back from the dynamic linker at startup time.
+ */
+
+/* GCC is needed because we use its __builtin_return_address construct. */
+
+#ifndef __GNUC__
+#error "GCC is needed to compile this file"
+#endif
+
+/*
+ * These variables are set by code in crt0.o. For compatibility with
+ * old executables, they must be common, not extern.
+ */
+struct ld_entry *__ldso_entry; /* Entry points to dynamic linker */
+int __ldso_version; /* Dynamic linker version number */
+
+int
+dladdr(const void *addr, Dl_info *dlip)
+{
+ if (__ldso_entry == NULL || __ldso_version < LDSO_VERSION_HAS_DLADDR)
+ return 0;
+ return (__ldso_entry->dladdr)(addr, dlip);
+}
+
+int
+dlclose(void *handle)
+{
+ if (__ldso_entry == NULL)
+ return -1;
+ return (__ldso_entry->dlclose)(handle);
+}
+
+const char *
+dlerror(void)
+{
+ if (__ldso_entry == NULL)
+ return "Service unavailable";
+ return (__ldso_entry->dlerror)();
+}
+
+void *
+dlopen(const char *name, int mode)
+{
+ if (__ldso_entry == NULL)
+ return NULL;
+ return (__ldso_entry->dlopen)(name, mode);
+}
+
+void *
+dlsym(void *handle, const char *name)
+{
+ if (__ldso_entry == NULL)
+ return NULL;
+ if (__ldso_version >= LDSO_VERSION_HAS_DLSYM3) {
+ void *retaddr = __builtin_return_address(0); /* __GNUC__ only */
+ return (__ldso_entry->dlsym3)(handle, name, retaddr);
+ } else
+ return (__ldso_entry->dlsym)(handle, name);
+}
+
+#endif /* __ELF__ */
diff --git a/lib/libc/gen/dlopen.3 b/lib/libc/gen/dlopen.3
new file mode 100644
index 0000000..6485e75
--- /dev/null
+++ b/lib/libc/gen/dlopen.3
@@ -0,0 +1,230 @@
+.\" This source code is a product of Sun Microsystems, Inc. and is provided
+.\" for unrestricted use provided that this legend is included on all tape
+.\" media and as a part of the software program in whole or part. Users
+.\" may copy or modify this source code without charge, but are not authorized
+.\" to license or distribute it to anyone else except as part of a product or
+.\" program developed by the user.
+.\"
+.\" THIS PROGRAM CONTAINS SOURCE CODE COPYRIGHTED BY SUN MICROSYSTEMS, INC.
+.\" SUN MICROSYSTEMS, INC., MAKES NO REPRESENTATIONS ABOUT THE SUITABLITY
+.\" OF SUCH SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT
+.\" EXPRESS OR IMPLIED WARRANTY OF ANY KIND. SUN MICROSYSTEMS, INC. DISCLAIMS
+.\" ALL WARRANTIES WITH REGARD TO SUCH SOURCE CODE, INCLUDING ALL IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN
+.\" NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT,
+.\" INCIDENTAL, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM USE OF SUCH SOURCE CODE, REGARDLESS OF THE THEORY OF LIABILITY.
+.\"
+.\" This source code is provided with no support and without any obligation on
+.\" the part of Sun Microsystems, Inc. to assist in its use, correction,
+.\" modification or enhancement.
+.\"
+.\" SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+.\" INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS
+.\" SOURCE CODE OR ANY PART THEREOF.
+.\"
+.\" Sun Microsystems, Inc.
+.\" 2550 Garcia Avenue
+.\" Mountain View, California 94043
+.\"
+.\" Copyright (c) 1991 Sun Microsystems, Inc.
+.\"
+.\" @(#) dlopen.3 1.6 90/01/31 SMI
+.\" $FreeBSD$
+.\"
+.Dd September 24, 1989
+.Os FreeBSD
+.Dt DLOPEN 3
+.Sh NAME
+.Nm dlopen, dlsym, dlerror, dlclose
+.Nd programmatic interface to the dynamic linker
+.Sh SYNOPSIS
+.Fd #include <dlfcn.h>
+.Ft void *
+.Fn dlopen "const char *path" "int mode"
+.Ft void *
+.Fn dlsym "void *handle" "const char *symbol"
+.Ft const char *
+.Fn dlerror "void"
+.Ft int
+.Fn dlclose "void *handle"
+.Sh DESCRIPTION
+These functions provide a simple programmatic interface to the services of the
+dynamic linker.
+Operations are provided to add new shared objects to a
+program's address space, to obtain the address bindings of symbols
+defined by such
+objects, and to remove such objects when their use is no longer required.
+.Pp
+.Fn dlopen
+provides access to the shared object in
+.Fa path ,
+returning a descriptor that can be used for later
+references to the object in calls to
+.Fn dlsym
+and
+.Fn dlclose .
+If
+.Fa path
+was not in the address space prior to the call to
+.Fn dlopen ,
+it is placed in the address space.
+When an object is first loaded into the address space in this way, its
+function
+.Fn _init ,
+if any, is called by the dynamic linker.
+If
+.Fa path
+has already been placed in the address space in a previous call to
+.Fn dlopen ,
+it is not added a second time, although a reference count of
+.Fn dlopen
+operations on
+.Fa path
+is maintained.
+A null pointer supplied for
+.Fa path
+is interpreted as a reference to the main
+executable of the process.
+.Fa mode
+controls the way in which external function references from the
+loaded object are bound to their referents.
+It must contain one of the following values:
+.Bl -tag -width RTLD_LAZYX
+.It Dv RTLD_LAZY
+Each external function reference is resolved when the function is first
+called.
+.It Dv RTLD_NOW
+All external function references are bound immediately by
+.Fn dlopen .
+.El
+.Pp
+.Dv RTLD_LAZY
+is normally preferred, for reasons of efficiency.
+However,
+.Dv RTLD_NOW
+is useful to ensure that any undefined symbols are discovered during the
+call to
+.Fn dlopen .
+If
+.Fn dlopen
+fails, it returns a null pointer, and sets an error condition which may
+be interrogated with
+.Fn dlerror .
+.Pp
+.Fn dlsym
+returns the address binding of the symbol described in the null-terminated
+character string
+.Fa symbol ,
+as it occurs in the shared object identified by
+.Fa handle .
+The symbols exported by objects added to the address space by
+.Fn dlopen
+can be accessed only through calls to
+.Fn dlsym .
+Such symbols do not supersede any definition of those symbols already present
+in the address space when the object is loaded, nor are they available to
+satisfy normal dynamic linking references.
+A null pointer supplied as the value of
+.Fa handle
+is interpreted as a reference to the executable from which the call to
+.Fn dlsym
+is being made. Thus a shared object can reference its own symbols.
+.Fn dlsym
+returns a null pointer if the symbol cannot be found, and sets an error
+condition which may be queried with
+.Fn dlerror .
+.Pp
+If
+.Fn dlsym
+is called with the special
+.Fa handle
+.Dv RTLD_NEXT ,
+then the search for the symbol is limited to the shared objects
+which were loaded after the one issuing the call to
+.Fn dlsym .
+Thus, if the function is called from the main program, all
+the shared libraries are searched.
+If it is called from a shared library, all subsequent shared
+libraries are searched.
+.Dv RTLD_NEXT
+is useful for implementing wrappers around library functions.
+For example, a wrapper function
+.Fn getpid
+could access the
+.Dq real
+.Fn getpid
+with
+.Li dlsym(RTLD_NEXT, \&"getpid\&") .
+.Pp
+.Fn dlerror
+returns a null-terminated character string describing the last error that
+occurred during a call to
+.Fn dlopen ,
+.Fn dlsym ,
+or
+.Fn dlclose .
+If no such error has occurred,
+.Fn dlerror
+returns a null pointer.
+At each call to
+.Fn dlerror ,
+the error indication is reset. Thus in the case of two calls
+to
+.Fn dlerror ,
+where the second call follows the first immediately, the second call
+will always return a null pointer.
+.Pp
+.Fn dlclose
+deletes a reference to the shared object referenced by
+.Fa handle .
+If the reference count drops to 0, the object is removed from the
+address space, and
+.Fa handle
+is rendered invalid.
+Just before removing a shared object in this way, the dynamic linker
+calls the object's
+.Fn _fini
+function, if such a function is defined by the object.
+If
+.Fn dlclose
+is successful, it returns a value of 0.
+Otherwise it returns -1, and sets an error condition that can be
+interrogated with
+.Fn dlerror .
+.Pp
+The object-intrinsic functions
+.Fn _init
+and
+.Fn _fini
+are called with no arguments, and are not expected to return values.
+.Sh NOTES
+ELF executables need to be linked
+using the
+.Fl export-dynamic
+option to
+.Xr ld 1
+for symbols defined in the executable to become visible to
+.Fn dlsym .
+.Pp
+In previous implementations, it was necessary to prepend an underscore
+to all external symbols in order to gain symbol
+compatibility with object code compiled from the C language. This is
+still the case when using the (obsolete)
+.Fl aout
+option to the C language compiler.
+.Sh ERRORS
+.Fn dlopen
+and
+.Fn dlsym
+return the null pointer in the event of errors.
+.Fn dlclose
+returns 0 on success, or -1 if an error occurred.
+Whenever an error has been detected, a message detailing it can be
+retrieved via a call to
+.Fn dlerror .
+.Sh SEE ALSO
+.Xr ld 1 ,
+.Xr rtld 1 ,
+.Xr link 5
+
diff --git a/lib/libc/gen/drand48.c b/lib/libc/gen/drand48.c
new file mode 100644
index 0000000..cec04a6
--- /dev/null
+++ b/lib/libc/gen/drand48.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#include "rand48.h"
+
+extern unsigned short _rand48_seed[3];
+
+double
+drand48(void)
+{
+ return erand48(_rand48_seed);
+}
diff --git a/lib/libc/gen/erand48.c b/lib/libc/gen/erand48.c
new file mode 100644
index 0000000..286904c
--- /dev/null
+++ b/lib/libc/gen/erand48.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#include "rand48.h"
+
+double
+erand48(unsigned short xseed[3])
+{
+ _dorand48(xseed);
+ return ldexp((double) xseed[0], -48) +
+ ldexp((double) xseed[1], -32) +
+ ldexp((double) xseed[2], -16);
+}
diff --git a/lib/libc/gen/err.3 b/lib/libc/gen/err.3
new file mode 100644
index 0000000..468fd1f
--- /dev/null
+++ b/lib/libc/gen/err.3
@@ -0,0 +1,204 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)err.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd Mar 6, 1999
+.Dt ERR 3
+.Os BSD 4
+.Sh NAME
+.Nm err ,
+.Nm verr ,
+.Nm errc ,
+.Nm verrc ,
+.Nm errx ,
+.Nm verrx ,
+.Nm warn ,
+.Nm vwarn ,
+.Nm warnc ,
+.Nm vwarnc ,
+.Nm warnx ,
+.Nm vwarnx ,
+.Nm err_set_exit ,
+.Nm err_set_file
+.Nd formatted error messages
+.Sh SYNOPSIS
+.Fd #include <err.h>
+.Ft void
+.Fn err "int eval" "const char *fmt" "..."
+.Ft void
+.Fn err_set_exit "void (*exitf)(int)"
+.Ft void
+.Fn err_set_file "void *vfp"
+.Ft void
+.Fn errc "int eval" "int code" "const char *fmt" "..."
+.Ft void
+.Fn errx "int eval" "const char *fmt" "..."
+.Ft void
+.Fn warn "const char *fmt" "..."
+.Ft void
+.Fn warnc "int code" "const char *fmt" "..."
+.Ft void
+.Fn warnx "const char *fmt" "..."
+.Fd #include <stdarg.h>
+.Ft void
+.Fn verr "int eval" "const char *fmt" "va_list args"
+.Ft void
+.Fn verrc "int eval" "int code" "const char *fmt" "va_list args"
+.Ft void
+.Fn verrx "int eval" "const char *fmt" "va_list args"
+.Ft void
+.Fn vwarn "const char *fmt" "va_list args"
+.Ft void
+.Fn vwarnc "int code" "const char *fmt" "va_list args"
+.Ft void
+.Fn vwarnx "const char *fmt" "va_list args"
+.Sh DESCRIPTION
+The
+.Fn err
+and
+.Fn warn
+family of functions display a formatted error message on the standard
+error output, or on another file specified using the
+.Fn err_set_file
+function.
+In all cases, the last component of the program name, a colon character,
+and a space are output.
+If the
+.Va fmt
+argument is not NULL, the formatted error message is output.
+In the case of the
+.Fn errc ,
+.Fn verrc ,
+.Fn warnc ,
+and
+.Fn vwarnc
+functions,
+the error message string affiliated with the
+.Va code
+argument is also output,
+preceded by another colon and space if necessary.
+In all cases, the output is followed by a newline character.
+.Pp
+The
+.Fn err ,
+.Fn verr ,
+.Fn warn ,
+and
+.Fn vwarn
+functions use the global variable
+.Va errno
+rather than the
+.Va code
+argument of the
+.Fn errc
+family
+.Pp
+The
+.Fn err ,
+.Fn verr ,
+.Fn errc ,
+.Fn verrc ,
+.Fn errx ,
+and
+.Fn verrx
+functions do not return, but exit with the value of the argument
+.Fa eval .
+The
+.Fn err_set_exit
+function can be used to specify a function which is called before
+.Xr exit 3
+to perform any necessary cleanup; passing a null function pointer for
+.Va exitf
+resets the hook to do nothing.
+The
+.Fn err_set_file
+function sets the output stream used by the other functions.
+Its
+.Va vfp
+argument must be either a pointer to an open stream
+(possibly already converted to void *)
+or a null pointer
+(in which case the output stream is set to standard error).
+.Sh EXAMPLES
+Display the current errno information string and exit:
+.Bd -literal -offset indent
+if ((p = malloc(size)) == NULL)
+ err(1, NULL);
+if ((fd = open(file_name, O_RDONLY, 0)) == -1)
+ err(1, "%s", file_name);
+.Ed
+.Pp
+Display an error message and exit:
+.Bd -literal -offset indent
+if (tm.tm_hour < START_TIME)
+ errx(1, "too early, wait until %s", start_time_string);
+.Ed
+.Pp
+Warn of an error:
+.Bd -literal -offset indent
+if ((fd = open(raw_device, O_RDONLY, 0)) == -1)
+ warnx("%s: %s: trying the block device",
+ raw_device, strerror(errno));
+if ((fd = open(block_device, O_RDONLY, 0)) == -1)
+ err(1, "%s", block_device);
+.Ed
+.Pp
+Warn of an error without using the global variable
+.Va errno :
+.Bd -literal -offset indent
+error = my_function(); /* returns a value from <errno.h> */
+if (error != 0)
+ warnc(error, "my_function");
+.Ed
+.Sh SEE ALSO
+.Xr exit 3 ,
+.Xr strerror 3
+.Sh HISTORY
+The
+.Fn err
+and
+.Fn warn
+functions first appeared in
+.Bx 4.4 .
+The
+.Fn err_set_exit
+and
+.Fn err_set_file
+functions first appeared in
+.Fx 2.1 .
+The
+.Fn errc
+and
+.Fn warnc
+functions first appeared in
+.Fx 3.0 .
diff --git a/lib/libc/gen/err.c b/lib/libc/gen/err.c
new file mode 100644
index 0000000..6d1766c
--- /dev/null
+++ b/lib/libc/gen/err.c
@@ -0,0 +1,208 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * From: @(#)err.c 8.1 (Berkeley) 6/4/93
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <stdarg.h>
+
+extern char *__progname; /* Program name, from crt0. */
+
+static FILE *err_file; /* file to use for error output */
+static void (*err_exit)(int);
+
+/*
+ * This is declared to take a `void *' so that the caller is not required
+ * to include <stdio.h> first. However, it is really a `FILE *', and the
+ * manual page documents it as such.
+ */
+void
+err_set_file(void *fp)
+{
+ if (fp)
+ err_file = fp;
+ else
+ err_file = stderr;
+}
+
+void
+err_set_exit(void (*ef)(int))
+{
+ err_exit = ef;
+}
+
+void
+err(int eval, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verrc(eval, errno, fmt, ap);
+ va_end(ap);
+}
+
+void
+verr(eval, fmt, ap)
+ int eval;
+ const char *fmt;
+ va_list ap;
+{
+ verrc(eval, errno, fmt, ap);
+}
+
+void
+errc(int eval, int code, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verrc(eval, code, fmt, ap);
+ va_end(ap);
+}
+
+void
+verrc(eval, code, fmt, ap)
+ int eval;
+ int code;
+ const char *fmt;
+ va_list ap;
+{
+ if (err_file == 0)
+ err_set_file((FILE *)0);
+ fprintf(err_file, "%s: ", __progname);
+ if (fmt != NULL) {
+ vfprintf(err_file, fmt, ap);
+ fprintf(err_file, ": ");
+ }
+ fprintf(err_file, "%s\n", strerror(code));
+ if (err_exit)
+ err_exit(eval);
+ exit(eval);
+}
+
+void
+errx(int eval, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verrx(eval, fmt, ap);
+ va_end(ap);
+}
+
+void
+verrx(eval, fmt, ap)
+ int eval;
+ const char *fmt;
+ va_list ap;
+{
+ if (err_file == 0)
+ err_set_file((FILE *)0);
+ fprintf(err_file, "%s: ", __progname);
+ if (fmt != NULL)
+ vfprintf(err_file, fmt, ap);
+ fprintf(err_file, "\n");
+ if (err_exit)
+ err_exit(eval);
+ exit(eval);
+}
+
+void
+warn(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarnc(errno, fmt, ap);
+ va_end(ap);
+}
+
+void
+vwarn(fmt, ap)
+ const char *fmt;
+ va_list ap;
+{
+ vwarnc(errno, fmt, ap);
+}
+
+void
+warnc(int code, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarnc(code, fmt, ap);
+ va_end(ap);
+}
+
+void
+vwarnc(code, fmt, ap)
+ int code;
+ const char *fmt;
+ va_list ap;
+{
+ if (err_file == 0)
+ err_set_file((FILE *)0);
+ fprintf(err_file, "%s: ", __progname);
+ if (fmt != NULL) {
+ vfprintf(err_file, fmt, ap);
+ fprintf(err_file, ": ");
+ }
+ fprintf(err_file, "%s\n", strerror(code));
+}
+
+void
+warnx(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarnx(fmt, ap);
+ va_end(ap);
+}
+
+void
+vwarnx(fmt, ap)
+ const char *fmt;
+ va_list ap;
+{
+ if (err_file == 0)
+ err_set_file((FILE *)0);
+ fprintf(err_file, "%s: ", __progname);
+ if (fmt != NULL)
+ vfprintf(err_file, fmt, ap);
+ fprintf(err_file, "\n");
+}
diff --git a/lib/libc/gen/errlst.c b/lib/libc/gen/errlst.c
new file mode 100644
index 0000000..a643794
--- /dev/null
+++ b/lib/libc/gen/errlst.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 1982, 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)errlst.c 8.2 (Berkeley) 11/16/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+const char *const sys_errlist[] = {
+ "Undefined error: 0", /* 0 - ENOERROR */
+ "Operation not permitted", /* 1 - EPERM */
+ "No such file or directory", /* 2 - ENOENT */
+ "No such process", /* 3 - ESRCH */
+ "Interrupted system call", /* 4 - EINTR */
+ "Input/output error", /* 5 - EIO */
+ "Device not configured", /* 6 - ENXIO */
+ "Argument list too long", /* 7 - E2BIG */
+ "Exec format error", /* 8 - ENOEXEC */
+ "Bad file descriptor", /* 9 - EBADF */
+ "No child processes", /* 10 - ECHILD */
+ "Resource deadlock avoided", /* 11 - EDEADLK */
+ "Cannot allocate memory", /* 12 - ENOMEM */
+ "Permission denied", /* 13 - EACCES */
+ "Bad address", /* 14 - EFAULT */
+ "Block device required", /* 15 - ENOTBLK */
+ "Device busy", /* 16 - EBUSY */
+ "File exists", /* 17 - EEXIST */
+ "Cross-device link", /* 18 - EXDEV */
+ "Operation not supported by device", /* 19 - ENODEV */
+ "Not a directory", /* 20 - ENOTDIR */
+ "Is a directory", /* 21 - EISDIR */
+ "Invalid argument", /* 22 - EINVAL */
+ "Too many open files in system", /* 23 - ENFILE */
+ "Too many open files", /* 24 - EMFILE */
+ "Inappropriate ioctl for device", /* 25 - ENOTTY */
+ "Text file busy", /* 26 - ETXTBSY */
+ "File too large", /* 27 - EFBIG */
+ "No space left on device", /* 28 - ENOSPC */
+ "Illegal seek", /* 29 - ESPIPE */
+ "Read-only file system", /* 30 - EROFS */
+ "Too many links", /* 31 - EMLINK */
+ "Broken pipe", /* 32 - EPIPE */
+
+/* math software */
+ "Numerical argument out of domain", /* 33 - EDOM */
+ "Result too large", /* 34 - ERANGE */
+
+/* non-blocking and interrupt i/o */
+ "Resource temporarily unavailable", /* 35 - EAGAIN */
+ /* 35 - EWOULDBLOCK */
+ "Operation now in progress", /* 36 - EINPROGRESS */
+ "Operation already in progress", /* 37 - EALREADY */
+
+/* ipc/network software -- argument errors */
+ "Socket operation on non-socket", /* 38 - ENOTSOCK */
+ "Destination address required", /* 39 - EDESTADDRREQ */
+ "Message too long", /* 40 - EMSGSIZE */
+ "Protocol wrong type for socket", /* 41 - EPROTOTYPE */
+ "Protocol not available", /* 42 - ENOPROTOOPT */
+ "Protocol not supported", /* 43 - EPROTONOSUPPORT */
+ "Socket type not supported", /* 44 - ESOCKTNOSUPPORT */
+ "Operation not supported", /* 45 - EOPNOTSUPP */
+ "Protocol family not supported", /* 46 - EPFNOSUPPORT */
+ /* 47 - EAFNOSUPPORT */
+ "Address family not supported by protocol family",
+ "Address already in use", /* 48 - EADDRINUSE */
+ "Can't assign requested address", /* 49 - EADDRNOTAVAIL */
+
+/* ipc/network software -- operational errors */
+ "Network is down", /* 50 - ENETDOWN */
+ "Network is unreachable", /* 51 - ENETUNREACH */
+ "Network dropped connection on reset", /* 52 - ENETRESET */
+ "Software caused connection abort", /* 53 - ECONNABORTED */
+ "Connection reset by peer", /* 54 - ECONNRESET */
+ "No buffer space available", /* 55 - ENOBUFS */
+ "Socket is already connected", /* 56 - EISCONN */
+ "Socket is not connected", /* 57 - ENOTCONN */
+ "Can't send after socket shutdown", /* 58 - ESHUTDOWN */
+ "Too many references: can't splice", /* 59 - ETOOMANYREFS */
+ "Operation timed out", /* 60 - ETIMEDOUT */
+ "Connection refused", /* 61 - ECONNREFUSED */
+
+ "Too many levels of symbolic links", /* 62 - ELOOP */
+ "File name too long", /* 63 - ENAMETOOLONG */
+
+/* should be rearranged */
+ "Host is down", /* 64 - EHOSTDOWN */
+ "No route to host", /* 65 - EHOSTUNREACH */
+ "Directory not empty", /* 66 - ENOTEMPTY */
+
+/* quotas & mush */
+ "Too many processes", /* 67 - EPROCLIM */
+ "Too many users", /* 68 - EUSERS */
+ "Disc quota exceeded", /* 69 - EDQUOT */
+
+/* Network File System */
+ "Stale NFS file handle", /* 70 - ESTALE */
+ "Too many levels of remote in path", /* 71 - EREMOTE */
+ "RPC struct is bad", /* 72 - EBADRPC */
+ "RPC version wrong", /* 73 - ERPCMISMATCH */
+ "RPC prog. not avail", /* 74 - EPROGUNAVAIL */
+ "Program version wrong", /* 75 - EPROGMISMATCH */
+ "Bad procedure for program", /* 76 - EPROCUNAVAIL */
+
+ "No locks available", /* 77 - ENOLCK */
+ "Function not implemented", /* 78 - ENOSYS */
+ "Inappropriate file type or format", /* 79 - EFTYPE */
+ "Authentication error", /* 80 - EAUTH */
+ "Need authenticator", /* 81 - ENEEDAUTH */
+ "Identifier removed", /* 82 - EIDRM */
+ "No message of desired type", /* 83 - ENOMSG */
+ "Value too large to be stored in data type", /* 84 - EOVERFLOW */
+ "Operation canceled", /* 85 - ECANCELED */
+ "Illegal byte sequence", /* 86 - EILSEQ */
+};
+int errno;
+const int sys_nerr = sizeof(sys_errlist) / sizeof(sys_errlist[0]);
diff --git a/lib/libc/gen/exec.3 b/lib/libc/gen/exec.3
new file mode 100644
index 0000000..8da1247
--- /dev/null
+++ b/lib/libc/gen/exec.3
@@ -0,0 +1,291 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)exec.3 8.3 (Berkeley) 1/24/94
+.\" $FreeBSD$
+.\"
+.Dd January 24, 1994
+.Dt EXEC 3
+.Os
+.Sh NAME
+.Nm execl ,
+.Nm execlp ,
+.Nm execle ,
+.Nm exect ,
+.Nm execv ,
+.Nm execvp
+.Nd execute a file
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Vt extern char **environ;
+.Ft int
+.Fn execl "const char *path" "const char *arg" ...
+.Ft int
+.Fn execlp "const char *file" "const char *arg" ...
+.Ft int
+.Fn execle "const char *path" "const char *arg" ...
+.Ft int
+.Fn exect "const char *path" "char *const argv[]" "char *const envp[]"
+.Ft int
+.Fn execv "const char *path" "char *const argv[]"
+.Ft int
+.Fn execvp "const char *file" "char *const argv[]"
+.Sh DESCRIPTION
+The
+.Nm exec
+family of functions replaces the current process image with a
+new process image.
+The functions described in this manual page are front-ends for the function
+.Xr execve 2 .
+(See the manual page for
+.Xr execve 2
+for detailed information about the replacement of the current process.)
+.Pp
+The initial argument for these functions is the pathname of a file which
+is to be executed.
+.Pp
+The
+.Fa "const char *arg"
+and subsequent ellipses in the
+.Fn execl ,
+.Fn execlp ,
+and
+.Fn execle
+functions can be thought of as
+.Em arg0 ,
+.Em arg1 ,
+\&...,
+.Em argn .
+Together they describe a list of one or more pointers to null-terminated
+strings that represent the argument list available to the executed program.
+The first argument, by convention, should point to the file name associated
+with the file being executed.
+The list of arguments
+.Em must
+be terminated by a
+.Dv NULL
+pointer.
+.Pp
+The
+.Fn exect ,
+.Fn execv ,
+and
+.Fn execvp
+functions provide an array of pointers to null-terminated strings that
+represent the argument list available to the new program.
+The first argument, by convention, should point to the file name associated
+with the file begin executed.
+The array of pointers
+.Sy must
+be terminated by a
+.Dv NULL
+pointer.
+.Pp
+The
+.Fn execle
+and
+.Fn exect
+functions also specify the environment of the executed process by following
+the
+.Dv NULL
+pointer that terminates the list of arguments in the parameter list
+or the pointer to the argv array with an additional parameter.
+This additional parameter is an array of pointers to null-terminated strings
+and
+.Em must
+be terminated by a
+.Dv NULL
+pointer.
+The other functions take the environment for the new process image from the
+external variable
+.Va environ
+in the current process.
+.Pp
+Some of these functions have special semantics.
+.Pp
+The functions
+.Fn execlp
+and
+.Fn execvp
+will duplicate the actions of the shell in searching for an executable file
+if the specified file name does not contain a slash
+.Dq Li /
+character.
+The search path is the path specified in the environment by
+.Dq Ev PATH
+variable.
+If this variable isn't specified, the default path
+.Dq Ev /bin:/usr/bin:
+is
+used.
+In addition, certain errors are treated specially.
+.Pp
+If an error is ambiguous (for simplicity, we shall consider all
+errors except
+.Er ENOEXEC
+as being ambiguous here, although only the critical error
+.Er EACCES
+is really ambiguous),
+then these functions will act as if they stat the file to determine
+whether the file exists and has suitable execute permissions.
+If it does, they will return immediately with the global variable
+.Va errno
+restored to the value set by
+.Fn execve .
+Otherwise, the search will be continued.
+If the search completes without performing a successful
+.Fn execve
+or terminating due to an error,
+these functions will return with the global variable
+.Va errno
+set to
+.Er EACCES
+or
+.Er ENOENT
+according to whether at least one file with suitable execute permissions
+was found.
+.Pp
+If the header of a file isn't recognized (the attempted
+.Fn execve
+returned
+.Er ENOEXEC ) ,
+these functions will execute the shell with the path of
+the file as its first argument.
+(If this attempt fails, no further searching is done.)
+.Pp
+The function
+.Fn exect
+executes a file with the program tracing facilities enabled (see
+.Xr ptrace 2 ) .
+.Sh RETURN VALUES
+If any of the
+.Fn exec
+functions returns, an error will have occurred.
+The return value is \-1, and the global variable
+.Va errno
+will be set to indicate the error.
+.Sh FILES
+.Bl -tag -width /bin/sh -compact
+.It Pa /bin/sh
+The shell.
+.El
+.Sh ERRORS
+.Fn Execl ,
+.Fn execle ,
+.Fn execlp
+and
+.Fn execvp
+may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr execve 2
+and
+.Xr malloc 3 .
+.Pp
+.Fn Exect
+and
+.Fn execv
+may fail and set
+.Va errno
+for any of the errors specified for the library function
+.Xr execve 2 .
+.Sh SEE ALSO
+.Xr sh 1 ,
+.Xr execve 2 ,
+.Xr fork 2 ,
+.Xr ktrace 2 ,
+.Xr ptrace 2 ,
+.Xr environ 7 .
+.Sh COMPATIBILITY
+Historically, the default path for the
+.Fn execlp
+and
+.Fn execvp
+functions was
+.Dq Pa :/bin:/usr/bin .
+This was changed to place the current directory last to enhance system
+security.
+.Pp
+The behavior of
+.Fn execlp
+and
+.Fn execvp
+when errors occur while attempting to execute the file is not quite historic
+practice, and has not traditionally been documented and is not specified
+by the
+.Tn POSIX
+standard.
+.Pp
+Traditionally, the functions
+.Fn execlp
+and
+.Fn execvp
+ignored all errors except for the ones described above and
+.Er ETXTBSY ,
+upon which they retried after sleeping for several seconds, and
+.Er ENOMEM
+and
+.Er E2BIG ,
+upon which they returned.
+They now return for
+.Er ETXTBSY ,
+and determine existence and executability more carefully.
+In particular,
+.Er EACCES
+for inaccessible directories in the path prefix is no longer
+confused with
+.Er EACCES
+for files with unsuitable execute permissions.
+In
+.Bx 4.4 ,
+they returned upon all errors except
+.Er EACCES ,
+.Er ENOENT ,
+.Er ENOEXEC
+and
+.Er ETXTBSY .
+This was inferior to the traditional error handling,
+since it it breaks the ignoring of errors for path prefixes
+and only improves the handling of the unusual ambiguous error
+.Er EFAULT
+and the unusual error
+.Er EIO .
+The behaviour was changed to match the behaviour of
+.Xr sh 1 .
+.Sh STANDARDS
+.Fn Execl ,
+.Fn execv ,
+.Fn execle ,
+.Fn execlp
+and
+.Fn execvp
+conform to
+.St -p1003.1-88 .
diff --git a/lib/libc/gen/exec.c b/lib/libc/gen/exec.c
new file mode 100644
index 0000000..af313a4
--- /dev/null
+++ b/lib/libc/gen/exec.c
@@ -0,0 +1,315 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)exec.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <paths.h>
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+extern char **environ;
+
+int
+#if __STDC__
+execl(const char *name, const char *arg, ...)
+#else
+execl(name, arg, va_alist)
+ const char *name;
+ const char *arg;
+ va_dcl
+#endif
+{
+ va_list ap;
+ char **argv;
+ int n;
+
+#if __STDC__
+ va_start(ap, arg);
+#else
+ va_start(ap);
+#endif
+ n = 1;
+ while (va_arg(ap, char *) != NULL)
+ n++;
+ va_end(ap);
+ argv = alloca((n + 1) * sizeof(*argv));
+ if (argv == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+#if __STDC__
+ va_start(ap, arg);
+#else
+ va_start(ap);
+#endif
+ n = 1;
+ argv[0] = (char *)arg;
+ while ((argv[n] = va_arg(ap, char *)) != NULL)
+ n++;
+ va_end(ap);
+ return (execve(name, argv, environ));
+}
+
+int
+#if __STDC__
+execle(const char *name, const char *arg, ...)
+#else
+execle(name, arg, va_alist)
+ const char *name;
+ const char *arg;
+ va_dcl
+#endif
+{
+ va_list ap;
+ char **argv, **envp;
+ int n;
+
+#if __STDC__
+ va_start(ap, arg);
+#else
+ va_start(ap);
+#endif
+ n = 1;
+ while (va_arg(ap, char *) != NULL)
+ n++;
+ va_end(ap);
+ argv = alloca((n + 1) * sizeof(*argv));
+ if (argv == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+#if __STDC__
+ va_start(ap, arg);
+#else
+ va_start(ap);
+#endif
+ n = 1;
+ argv[0] = (char *)arg;
+ while ((argv[n] = va_arg(ap, char *)) != NULL)
+ n++;
+ envp = va_arg(ap, char **);
+ va_end(ap);
+ return (execve(name, argv, envp));
+}
+
+int
+#if __STDC__
+execlp(const char *name, const char *arg, ...)
+#else
+execlp(name, arg, va_alist)
+ const char *name;
+ const char *arg;
+ va_dcl
+#endif
+{
+ va_list ap;
+ int sverrno;
+ char **argv;
+ int n;
+
+#if __STDC__
+ va_start(ap, arg);
+#else
+ va_start(ap);
+#endif
+ n = 1;
+ while (va_arg(ap, char *) != NULL)
+ n++;
+ va_end(ap);
+ argv = alloca((n + 1) * sizeof(*argv));
+ if (argv == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+#if __STDC__
+ va_start(ap, arg);
+#else
+ va_start(ap);
+#endif
+ n = 1;
+ argv[0] = (char *)arg;
+ while ((argv[n] = va_arg(ap, char *)) != NULL)
+ n++;
+ va_end(ap);
+ return (execvp(name, argv));
+}
+
+int
+execv(name, argv)
+ const char *name;
+ char * const *argv;
+{
+ (void)execve(name, argv, environ);
+ return (-1);
+}
+
+int
+execvp(name, argv)
+ const char *name;
+ char * const *argv;
+{
+ char **memp;
+ register int cnt, lp, ln;
+ register char *p;
+ int eacces, save_errno;
+ char *bp, *cur, *path, buf[MAXPATHLEN];
+ struct stat sb;
+
+ eacces = 0;
+
+ /* If it's an absolute or relative path name, it's easy. */
+ if (index(name, '/')) {
+ bp = (char *)name;
+ cur = path = NULL;
+ goto retry;
+ }
+ bp = buf;
+
+ /* If it's an empty path name, fail in the usual POSIX way. */
+ if (*name == '\0') {
+ errno = ENOENT;
+ return (-1);
+ }
+
+ /* Get the path we're searching. */
+ if (!(path = getenv("PATH")))
+ path = _PATH_DEFPATH;
+ cur = alloca(strlen(path) + 1);
+ if (cur == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ strcpy(cur, path);
+ path = cur;
+ while ( (p = strsep(&cur, ":")) ) {
+ /*
+ * It's a SHELL path -- double, leading and trailing colons
+ * mean the current directory.
+ */
+ if (!*p) {
+ p = ".";
+ lp = 1;
+ } else
+ lp = strlen(p);
+ ln = strlen(name);
+
+ /*
+ * If the path is too long complain. This is a possible
+ * security issue; given a way to make the path too long
+ * the user may execute the wrong program.
+ */
+ if (lp + ln + 2 > sizeof(buf)) {
+ (void)write(STDERR_FILENO, "execvp: ", 8);
+ (void)write(STDERR_FILENO, p, lp);
+ (void)write(STDERR_FILENO, ": path too long\n", 16);
+ continue;
+ }
+ bcopy(p, buf, lp);
+ buf[lp] = '/';
+ bcopy(name, buf + lp + 1, ln);
+ buf[lp + ln + 1] = '\0';
+
+retry: (void)execve(bp, argv, environ);
+ switch(errno) {
+ case E2BIG:
+ goto done;
+ case ELOOP:
+ case ENAMETOOLONG:
+ case ENOENT:
+ break;
+ case ENOEXEC:
+ for (cnt = 0; argv[cnt]; ++cnt)
+ ;
+ memp = alloca((cnt + 2) * sizeof(char *));
+ if (memp == NULL) {
+ /* errno = ENOMEM; XXX override ENOEXEC? */
+ goto done;
+ }
+ memp[0] = "sh";
+ memp[1] = bp;
+ bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
+ (void)execve(_PATH_BSHELL, memp, environ);
+ goto done;
+ case ENOMEM:
+ goto done;
+ case ENOTDIR:
+ break;
+ case ETXTBSY:
+ /*
+ * We used to retry here, but sh(1) doesn't.
+ */
+ goto done;
+ default:
+ /*
+ * EACCES may be for an inaccessible directory or
+ * a non-executable file. Call stat() to decide
+ * which. This also handles ambiguities for EFAULT
+ * and EIO, and undocumented errors like ESTALE.
+ * We hope that the race for a stat() is unimportant.
+ */
+ save_errno = errno;
+ if (stat(bp, &sb) != 0)
+ break;
+ if (save_errno == EACCES) {
+ eacces = 1;
+ continue;
+ }
+ errno = save_errno;
+ goto done;
+ }
+ }
+ if (eacces)
+ errno = EACCES;
+ else
+ errno = ENOENT;
+done:
+ return (-1);
+}
diff --git a/lib/libc/gen/fnmatch.3 b/lib/libc/gen/fnmatch.3
new file mode 100644
index 0000000..8b556b5
--- /dev/null
+++ b/lib/libc/gen/fnmatch.3
@@ -0,0 +1,149 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Guido van Rossum.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fnmatch.3 8.3 (Berkeley) 4/28/95
+.\" $FreeBSD$
+.\"
+.Dd April 28, 1995
+.Dt FNMATCH 3
+.Os
+.Sh NAME
+.Nm fnmatch
+.Nd match filename or pathname
+.Sh SYNOPSIS
+.Fd #include <fnmatch.h>
+.Ft int
+.Fn fnmatch "const char *pattern" "const char *string" "int flags"
+.Sh DESCRIPTION
+The
+.Fn fnmatch
+function
+matches patterns according to the rules used by the shell.
+It checks the string specified by the
+.Fa string
+argument to see if it matches the pattern specified by the
+.Fa pattern
+argument.
+.Pp
+The
+.Fa flags
+argument modifies the interpretation of
+.Fa pattern
+and
+.Fa string .
+The value of
+.Fa flags
+is the bitwise inclusive
+.Tn OR
+of any of the following
+constants, which are defined in the include file
+.Pa fnmatch.h .
+.Bl -tag -width FNM_PATHNAME
+.It Dv FNM_NOESCAPE
+Normally, every occurrence of a backslash
+.Pq Ql \e
+followed by a character in
+.Fa pattern
+is replaced by that character.
+This is done to negate any special meaning for the character.
+If the
+.Dv FNM_NOESCAPE
+flag is set, a backslash character is treated as an ordinary character.
+.It Dv FNM_PATHNAME
+Slash characters in
+.Fa string
+must be explicitly matched by slashes in
+.Fa pattern .
+If this flag is not set, then slashes are treated as regular characters.
+.It Dv FNM_PERIOD
+Leading periods in
+.Fa string
+must be explicitly matched by periods in
+.Fa pattern .
+If this flag is not set, then leading periods are treated as regular
+characters.
+The definition of
+.Dq leading
+is related to the specification of
+.Dv FNM_PATHNAME .
+A period is always
+.Dq leading
+if it is the first character in
+.Ar string .
+Additionally, if
+.Dv FNM_PATHNAME
+is set,
+a period is
+leading
+if it immediately follows a slash.
+.It Dv FNM_LEADING_DIR
+Ignore
+.Nm /*
+rest after successful
+.Fa pattern
+matching.
+.It Dv FNM_CASEFOLD
+Ignore case distinctions in both the
+.Fa pattern
+and the
+.Fa string .
+.El
+.Sh RETURN VALUES
+The
+.Fn fnmatch
+function returns zero if
+.Fa string
+matches the pattern specified by
+.Fa pattern ,
+otherwise, it returns the value
+.Dv FNM_NOMATCH .
+.Sh SEE ALSO
+.Xr sh 1 ,
+.Xr glob 3 ,
+.Xr regex 3
+.Sh STANDARDS
+The
+.Fn fnmatch
+function conforms to
+.St -p1003.2 .
+.Sh HISTORY
+The
+.Fn fnmatch
+function first appeared in
+.Bx 4.4 .
+.Sh BUGS
+The pattern
+.Ql *
+matches the empty string, even if
+.Dv FNM_PATHNAME
+is specified.
diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c
new file mode 100644
index 0000000..c3312b4
--- /dev/null
+++ b/lib/libc/gen/fnmatch.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
+ * Compares a filename or pathname to a pattern.
+ */
+
+#include <ctype.h>
+#include <fnmatch.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "collate.h"
+
+#define EOS '\0'
+
+#define RANGE_MATCH 1
+#define RANGE_NOMATCH 0
+#define RANGE_ERROR (-1)
+
+static int rangematch __P((const char *, char, int, char **));
+
+int
+fnmatch(pattern, string, flags)
+ const char *pattern, *string;
+ int flags;
+{
+ const char *stringstart;
+ char *newp;
+ char c, test;
+
+ for (stringstart = string;;)
+ switch (c = *pattern++) {
+ case EOS:
+ if ((flags & FNM_LEADING_DIR) && *string == '/')
+ return (0);
+ return (*string == EOS ? 0 : FNM_NOMATCH);
+ case '?':
+ if (*string == EOS)
+ return (FNM_NOMATCH);
+ if (*string == '/' && (flags & FNM_PATHNAME))
+ return (FNM_NOMATCH);
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart ||
+ ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ return (FNM_NOMATCH);
+ ++string;
+ break;
+ case '*':
+ c = *pattern;
+ /* Collapse multiple stars. */
+ while (c == '*')
+ c = *++pattern;
+
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart ||
+ ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ return (FNM_NOMATCH);
+
+ /* Optimize for pattern with * at end or before /. */
+ if (c == EOS)
+ if (flags & FNM_PATHNAME)
+ return ((flags & FNM_LEADING_DIR) ||
+ strchr(string, '/') == NULL ?
+ 0 : FNM_NOMATCH);
+ else
+ return (0);
+ else if (c == '/' && flags & FNM_PATHNAME) {
+ if ((string = strchr(string, '/')) == NULL)
+ return (FNM_NOMATCH);
+ break;
+ }
+
+ /* General case, use recursion. */
+ while ((test = *string) != EOS) {
+ if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
+ return (0);
+ if (test == '/' && flags & FNM_PATHNAME)
+ break;
+ ++string;
+ }
+ return (FNM_NOMATCH);
+ case '[':
+ if (*string == EOS)
+ return (FNM_NOMATCH);
+ if (*string == '/' && (flags & FNM_PATHNAME))
+ return (FNM_NOMATCH);
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart ||
+ ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ return (FNM_NOMATCH);
+
+ switch (rangematch(pattern, *string, flags, &newp)) {
+ case RANGE_ERROR:
+ goto norm;
+ case RANGE_MATCH:
+ pattern = newp;
+ break;
+ case RANGE_NOMATCH:
+ return (FNM_NOMATCH);
+ }
+ ++string;
+ break;
+ case '\\':
+ if (!(flags & FNM_NOESCAPE)) {
+ if ((c = *pattern++) == EOS) {
+ c = '\\';
+ --pattern;
+ }
+ }
+ /* FALLTHROUGH */
+ default:
+ norm:
+ if (c == *string)
+ ;
+ else if ((flags & FNM_CASEFOLD) &&
+ (tolower((unsigned char)c) ==
+ tolower((unsigned char)*string)))
+ ;
+ else
+ return (FNM_NOMATCH);
+ string++;
+ break;
+ }
+ /* NOTREACHED */
+}
+
+static int
+rangematch(pattern, test, flags, newp)
+ const char *pattern;
+ char test;
+ int flags;
+ char **newp;
+{
+ int negate, ok;
+ char c, c2;
+
+ /*
+ * A bracket expression starting with an unquoted circumflex
+ * character produces unspecified results (IEEE 1003.2-1992,
+ * 3.13.2). This implementation treats it like '!', for
+ * consistency with the regular expression syntax.
+ * J.T. Conklin (conklin@ngai.kaleida.com)
+ */
+ if ( (negate = (*pattern == '!' || *pattern == '^')) )
+ ++pattern;
+
+ if (flags & FNM_CASEFOLD)
+ test = tolower((unsigned char)test);
+
+ /*
+ * A right bracket shall lose its special meaning and represent
+ * itself in a bracket expression if it occurs first in the list.
+ * -- POSIX.2 2.8.3.2
+ */
+ ok = 0;
+ c = *pattern++;
+ do {
+ if (c == '\\' && !(flags & FNM_NOESCAPE))
+ c = *pattern++;
+ if (c == EOS)
+ return (RANGE_ERROR);
+
+ if (c == '/' && (flags & FNM_PATHNAME))
+ return (RANGE_NOMATCH);
+
+ if (flags & FNM_CASEFOLD)
+ c = tolower((unsigned char)c);
+
+ if (*pattern == '-'
+ && (c2 = *(pattern+1)) != EOS && c2 != ']') {
+ pattern += 2;
+ if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+ c2 = *pattern++;
+ if (c2 == EOS)
+ return (RANGE_ERROR);
+
+ if (flags & FNM_CASEFOLD)
+ c2 = tolower((unsigned char)c2);
+
+ if (__collate_load_error ?
+ c <= test && test <= c2 :
+ __collate_range_cmp(c, test) <= 0
+ && __collate_range_cmp(test, c2) <= 0
+ )
+ ok = 1;
+ } else if (c == test)
+ ok = 1;
+ } while ((c = *pattern++) != ']');
+
+ *newp = (char *)pattern;
+ return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
+}
diff --git a/lib/libc/gen/frexp.3 b/lib/libc/gen/frexp.3
new file mode 100644
index 0000000..f2a6b5c
--- /dev/null
+++ b/lib/libc/gen/frexp.3
@@ -0,0 +1,86 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)frexp.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt FREXP 3
+.Os
+.Sh NAME
+.Nm frexp
+.Nd convert floating-point number to fractional and integral components
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn frexp "double value" "int *exp"
+.Sh DESCRIPTION
+The
+.Fn frexp
+function breaks a floating-point number into a normalized
+fraction and an integral power of 2.
+It stores the integer in the
+.Em int
+object pointed to by
+.Fa exp .
+.Sh RETURN VALUES
+The
+.Fn frexp
+function returns the value
+.Em x ,
+such that
+.Em x
+is a
+.Em double
+with magnitude in the interval
+.Bq 1/2 , 1
+or zero, and
+.Fa value
+equals
+.Em x
+times 2 raised to the power
+.Fa *exp .
+If
+.Fa value
+is zero, both parts of the result are zero.
+.Sh SEE ALSO
+.Xr ldexp 3 ,
+.Xr math 3 ,
+.Xr modf 3
+.Sh STANDARDS
+The
+.Fn frexp
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/gen/fstab.c b/lib/libc/gen/fstab.c
new file mode 100644
index 0000000..65b02c1
--- /dev/null
+++ b/lib/libc/gen/fstab.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 1980, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fstab.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fstab.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static FILE *_fs_fp;
+static struct fstab _fs_fstab;
+static int LineNo = 0;
+
+static void error __P((int));
+static void fixfsfile __P((void));
+static int fstabscan __P((void));
+
+static void
+fixfsfile()
+{
+ static char buf[sizeof(_PATH_DEV) + MNAMELEN];
+ struct stat sb;
+ struct statfs sf;
+
+ if (strcmp(_fs_fstab.fs_file, "/") != 0)
+ return;
+ if (statfs("/", &sf) != 0)
+ return;
+ if (sf.f_mntfromname[0] == '/')
+ buf[0] = '\0';
+ else
+ strcpy(buf, _PATH_DEV);
+ strcat(buf, sf.f_mntfromname);
+ if (stat(buf, &sb) != 0 || !S_ISBLK(sb.st_mode))
+ return;
+ _fs_fstab.fs_spec = buf;
+}
+
+static int
+fstabscan()
+{
+ char *cp, *p;
+#define MAXLINELENGTH 1024
+ static char line[MAXLINELENGTH];
+ char subline[MAXLINELENGTH];
+ int typexx;
+
+ for (;;) {
+
+ if (!(p = fgets(line, sizeof(line), _fs_fp)))
+ return(0);
+/* OLD_STYLE_FSTAB */
+ ++LineNo;
+ if (*line == '#' || *line == '\n')
+ continue;
+ if (!strpbrk(p, " \t")) {
+ _fs_fstab.fs_spec = strsep(&p, ":\n");
+ _fs_fstab.fs_file = strsep(&p, ":\n");
+ fixfsfile();
+ _fs_fstab.fs_type = strsep(&p, ":\n");
+ if (_fs_fstab.fs_type) {
+ if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
+ continue;
+ _fs_fstab.fs_mntops = _fs_fstab.fs_type;
+ _fs_fstab.fs_vfstype =
+ strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
+ "ufs" : "swap";
+ if ((cp = strsep(&p, ":\n")) != NULL) {
+ _fs_fstab.fs_freq = atoi(cp);
+ if ((cp = strsep(&p, ":\n")) != NULL) {
+ _fs_fstab.fs_passno = atoi(cp);
+ return(1);
+ }
+ }
+ }
+ goto bad;
+ }
+/* OLD_STYLE_FSTAB */
+ while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
+ ;
+ _fs_fstab.fs_spec = cp;
+ if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
+ continue;
+ while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
+ ;
+ _fs_fstab.fs_file = cp;
+ fixfsfile();
+ while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
+ ;
+ _fs_fstab.fs_vfstype = cp;
+ while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
+ ;
+ _fs_fstab.fs_mntops = cp;
+ if (_fs_fstab.fs_mntops == NULL)
+ goto bad;
+ _fs_fstab.fs_freq = 0;
+ _fs_fstab.fs_passno = 0;
+ while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
+ ;
+ if (cp != NULL) {
+ _fs_fstab.fs_freq = atoi(cp);
+ while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
+ ;
+ if (cp != NULL)
+ _fs_fstab.fs_passno = atoi(cp);
+ }
+ strcpy(subline, _fs_fstab.fs_mntops);
+ p = subline;
+ for (typexx = 0, cp = strsep(&p, ","); cp;
+ cp = strsep(&p, ",")) {
+ if (strlen(cp) != 2)
+ continue;
+ if (!strcmp(cp, FSTAB_RW)) {
+ _fs_fstab.fs_type = FSTAB_RW;
+ break;
+ }
+ if (!strcmp(cp, FSTAB_RQ)) {
+ _fs_fstab.fs_type = FSTAB_RQ;
+ break;
+ }
+ if (!strcmp(cp, FSTAB_RO)) {
+ _fs_fstab.fs_type = FSTAB_RO;
+ break;
+ }
+ if (!strcmp(cp, FSTAB_SW)) {
+ _fs_fstab.fs_type = FSTAB_SW;
+ break;
+ }
+ if (!strcmp(cp, FSTAB_XX)) {
+ _fs_fstab.fs_type = FSTAB_XX;
+ typexx++;
+ break;
+ }
+ }
+ if (typexx)
+ continue;
+ if (cp != NULL)
+ return(1);
+
+bad: /* no way to distinguish between EOF and syntax error */
+ error(EFTYPE);
+ }
+ /* NOTREACHED */
+}
+
+struct fstab *
+getfsent()
+{
+ if ((!_fs_fp && !setfsent()) || !fstabscan())
+ return((struct fstab *)NULL);
+ return(&_fs_fstab);
+}
+
+struct fstab *
+getfsspec(name)
+ register const char *name;
+{
+ if (setfsent())
+ while (fstabscan())
+ if (!strcmp(_fs_fstab.fs_spec, name))
+ return(&_fs_fstab);
+ return((struct fstab *)NULL);
+}
+
+struct fstab *
+getfsfile(name)
+ register const char *name;
+{
+ if (setfsent())
+ while (fstabscan())
+ if (!strcmp(_fs_fstab.fs_file, name))
+ return(&_fs_fstab);
+ return((struct fstab *)NULL);
+}
+
+int
+setfsent()
+{
+ if (_fs_fp) {
+ rewind(_fs_fp);
+ LineNo = 0;
+ return(1);
+ }
+ if ((_fs_fp = fopen(_PATH_FSTAB, "r")) != NULL) {
+ LineNo = 0;
+ return(1);
+ }
+ error(errno);
+ return(0);
+}
+
+void
+endfsent()
+{
+ if (_fs_fp) {
+ (void)fclose(_fs_fp);
+ _fs_fp = NULL;
+ }
+}
+
+static void
+error(err)
+ int err;
+{
+ char *p;
+ char num[30];
+
+ (void)write(STDERR_FILENO, "fstab: ", 7);
+ (void)write(STDERR_FILENO, _PATH_FSTAB, sizeof(_PATH_FSTAB) - 1);
+ (void)write(STDERR_FILENO, ":", 1);
+ sprintf(num, "%d: ", LineNo);
+ (void)write(STDERR_FILENO, num, strlen(num));
+ p = strerror(err);
+ (void)write(STDERR_FILENO, p, strlen(p));
+ (void)write(STDERR_FILENO, "\n", 1);
+}
diff --git a/lib/libc/gen/ftok.3 b/lib/libc/gen/ftok.3
new file mode 100644
index 0000000..611bf30
--- /dev/null
+++ b/lib/libc/gen/ftok.3
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.Dd June 24, 1994
+.Os
+.Dt FTOK 3
+.Sh NAME
+.Nm ftok
+.Nd create IPC identifier from path name
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/ipc.h>
+.Ft key_t
+.Fn ftok "const char *path" "int id"
+.Sh DESCRIPTION
+.Bf -symbolic
+This function is available from the compatibility library, libcompat.
+.Ef
+The
+.Fn ftok
+function attempts to create a unique key suitable for use with the
+.Xr msgget 3 ,
+.Xr semget 2
+and
+.Xr shmget 2
+functions given the
+.Fa path
+of an existing file and a user-selectable
+.Fa id .
+.Pp
+The specified
+.Fa path
+must specify an existing file that is accessible to the calling process
+or the call will fail. Also, note that links to files will return the
+same key, given the same
+.Fa id .
+.Sh RETURN VALUES
+The
+.Fn ftok
+function will return -1 if
+.Fa path
+does not exist or if it cannot be accessed by the calling process.
+.Sh SEE ALSO
+.Xr semget 2 ,
+.Xr shmget 2 ,
+.Xr msgget 3
+.Sh HISTORY
+The
+.Fn ftok
+function originates with System V and is typically used by programs
+that use the System V IPC routines.
+.Sh AUTHORS
+.An Thorsten Lockert Aq tholo@sigmasoft.com
+.Sh BUGS
+The returned key is computed based on the device minor number and inode of the
+specified
+.Fa path
+in combination with the lower 8 bits of the given
+.Fa id .
+Thus it is quite possible for the routine to return duplicate keys.
diff --git a/lib/libc/gen/ftok.c b/lib/libc/gen/ftok.c
new file mode 100644
index 0000000..24cfe7d
--- /dev/null
+++ b/lib/libc/gen/ftok.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ipc.h>
+
+key_t
+ftok(path, id)
+ const char *path;
+ char id;
+{
+ struct stat st;
+
+ if (stat(path, &st) < 0)
+ return (key_t)-1;
+
+ return (key_t) (id << 24 | (st.st_dev & 0xff) << 16 | (st.st_ino & 0xffff));
+}
diff --git a/lib/libc/gen/fts-compat.c b/lib/libc/gen/fts-compat.c
new file mode 100644
index 0000000..0ad03ca
--- /dev/null
+++ b/lib/libc/gen/fts-compat.c
@@ -0,0 +1,1112 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $OpenBSD: fts.c,v 1.22 1999/10/03 19:22:22 millert Exp $
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
+#else
+static char rcsid[] = "$FreeBSD$";
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fts.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static FTSENT *fts_alloc __P((FTS *, char *, int));
+static FTSENT *fts_build __P((FTS *, int));
+static void fts_lfree __P((FTSENT *));
+static void fts_load __P((FTS *, FTSENT *));
+static size_t fts_maxarglen __P((char * const *));
+static void fts_padjust __P((FTS *, FTSENT *));
+static int fts_palloc __P((FTS *, size_t));
+static FTSENT *fts_sort __P((FTS *, FTSENT *, int));
+static u_short fts_stat __P((FTS *, FTSENT *, int));
+static int fts_safe_changedir __P((FTS *, FTSENT *, int));
+
+#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
+
+#define CLR(opt) (sp->fts_options &= ~(opt))
+#define ISSET(opt) (sp->fts_options & (opt))
+#define SET(opt) (sp->fts_options |= (opt))
+
+#define CHDIR(sp, path) (!ISSET(FTS_NOCHDIR) && chdir(path))
+#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
+
+/* fts_build flags */
+#define BCHILD 1 /* fts_children */
+#define BNAMES 2 /* fts_children, names only */
+#define BREAD 3 /* fts_read */
+
+FTS *
+fts_open(argv, options, compar)
+ char * const *argv;
+ register int options;
+ int (*compar) __P((const FTSENT **, const FTSENT **));
+{
+ register FTS *sp;
+ register FTSENT *p, *root;
+ register int nitems;
+ FTSENT *parent, *tmp;
+ int len;
+
+ /* Options check. */
+ if (options & ~FTS_OPTIONMASK) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /* Allocate/initialize the stream */
+ if ((sp = malloc((u_int)sizeof(FTS))) == NULL)
+ return (NULL);
+ memset(sp, 0, sizeof(FTS));
+ sp->fts_compar = compar;
+ sp->fts_options = options;
+
+ /* Shush, GCC. */
+ tmp = NULL;
+
+ /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
+ if (ISSET(FTS_LOGICAL))
+ SET(FTS_NOCHDIR);
+
+ /*
+ * Start out with 1K of path space, and enough, in any case,
+ * to hold the user's paths.
+ */
+ if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
+ goto mem1;
+
+ /* Allocate/initialize root's parent. */
+ if ((parent = fts_alloc(sp, "", 0)) == NULL)
+ goto mem2;
+ parent->fts_level = FTS_ROOTPARENTLEVEL;
+
+ /* Allocate/initialize root(s). */
+ for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) {
+ /* Don't allow zero-length paths. */
+ if ((len = strlen(*argv)) == 0) {
+ errno = ENOENT;
+ goto mem3;
+ }
+
+ p = fts_alloc(sp, *argv, len);
+ p->fts_level = FTS_ROOTLEVEL;
+ p->fts_parent = parent;
+ p->fts_accpath = p->fts_name;
+ p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
+
+ /* Command-line "." and ".." are real directories. */
+ if (p->fts_info == FTS_DOT)
+ p->fts_info = FTS_D;
+
+ /*
+ * If comparison routine supplied, traverse in sorted
+ * order; otherwise traverse in the order specified.
+ */
+ if (compar) {
+ p->fts_link = root;
+ root = p;
+ } else {
+ p->fts_link = NULL;
+ if (root == NULL)
+ tmp = root = p;
+ else {
+ tmp->fts_link = p;
+ tmp = p;
+ }
+ }
+ }
+ if (compar && nitems > 1)
+ root = fts_sort(sp, root, nitems);
+
+ /*
+ * Allocate a dummy pointer and make fts_read think that we've just
+ * finished the node before the root(s); set p->fts_info to FTS_INIT
+ * so that everything about the "current" node is ignored.
+ */
+ if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
+ goto mem3;
+ sp->fts_cur->fts_link = root;
+ sp->fts_cur->fts_info = FTS_INIT;
+
+ /*
+ * If using chdir(2), grab a file descriptor pointing to dot to ensure
+ * that we can get back here; this could be avoided for some paths,
+ * but almost certainly not worth the effort. Slashes, symbolic links,
+ * and ".." are all fairly nasty problems. Note, if we can't get the
+ * descriptor we run anyway, just more slowly.
+ */
+ if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0)
+ SET(FTS_NOCHDIR);
+
+ return (sp);
+
+mem3: fts_lfree(root);
+ free(parent);
+mem2: free(sp->fts_path);
+mem1: free(sp);
+ return (NULL);
+}
+
+static void
+fts_load(sp, p)
+ FTS *sp;
+ register FTSENT *p;
+{
+ register int len;
+ register char *cp;
+
+ /*
+ * Load the stream structure for the next traversal. Since we don't
+ * actually enter the directory until after the preorder visit, set
+ * the fts_accpath field specially so the chdir gets done to the right
+ * place and the user can access the first node. From fts_open it's
+ * known that the path will fit.
+ */
+ len = p->fts_pathlen = p->fts_namelen;
+ memmove(sp->fts_path, p->fts_name, len + 1);
+ if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
+ len = strlen(++cp);
+ memmove(p->fts_name, cp, len + 1);
+ p->fts_namelen = len;
+ }
+ p->fts_accpath = p->fts_path = sp->fts_path;
+ sp->fts_dev = p->fts_dev;
+}
+
+int
+fts_close(sp)
+ FTS *sp;
+{
+ register FTSENT *freep, *p;
+ int saved_errno;
+
+ /*
+ * This still works if we haven't read anything -- the dummy structure
+ * points to the root list, so we step through to the end of the root
+ * list which has a valid parent pointer.
+ */
+ if (sp->fts_cur) {
+ for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
+ freep = p;
+ p = p->fts_link ? p->fts_link : p->fts_parent;
+ free(freep);
+ }
+ free(p);
+ }
+
+ /* Free up child linked list, sort array, path buffer. */
+ if (sp->fts_child)
+ fts_lfree(sp->fts_child);
+ if (sp->fts_array)
+ free(sp->fts_array);
+ free(sp->fts_path);
+
+ /* Return to original directory, save errno if necessary. */
+ if (!ISSET(FTS_NOCHDIR)) {
+ saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
+ (void)close(sp->fts_rfd);
+
+ /* Set errno and return. */
+ if (saved_errno != 0) {
+ /* Free up the stream pointer. */
+ free(sp);
+ errno = saved_errno;
+ return (-1);
+ }
+ }
+
+ /* Free up the stream pointer. */
+ free(sp);
+ return (0);
+}
+
+/*
+ * Special case of "/" at the end of the path so that slashes aren't
+ * appended which would cause paths to be written as "....//foo".
+ */
+#define NAPPEND(p) \
+ (p->fts_path[p->fts_pathlen - 1] == '/' \
+ ? p->fts_pathlen - 1 : p->fts_pathlen)
+
+FTSENT *
+fts_read(sp)
+ register FTS *sp;
+{
+ register FTSENT *p, *tmp;
+ register int instr;
+ register char *t;
+ int saved_errno;
+
+ /* If finished or unrecoverable error, return NULL. */
+ if (sp->fts_cur == NULL || ISSET(FTS_STOP))
+ return (NULL);
+
+ /* Set current node pointer. */
+ p = sp->fts_cur;
+
+ /* Save and zero out user instructions. */
+ instr = p->fts_instr;
+ p->fts_instr = FTS_NOINSTR;
+
+ /* Any type of file may be re-visited; re-stat and re-turn. */
+ if (instr == FTS_AGAIN) {
+ p->fts_info = fts_stat(sp, p, 0);
+ return (p);
+ }
+
+ /*
+ * Following a symlink -- SLNONE test allows application to see
+ * SLNONE and recover. If indirecting through a symlink, have
+ * keep a pointer to current location. If unable to get that
+ * pointer, follow fails.
+ */
+ if (instr == FTS_FOLLOW &&
+ (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
+ p->fts_info = fts_stat(sp, p, 1);
+ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
+ if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) {
+ p->fts_errno = errno;
+ p->fts_info = FTS_ERR;
+ } else
+ p->fts_flags |= FTS_SYMFOLLOW;
+ }
+ return (p);
+ }
+
+ /* Directory in pre-order. */
+ if (p->fts_info == FTS_D) {
+ /* If skipped or crossed mount point, do post-order visit. */
+ if (instr == FTS_SKIP ||
+ (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
+ if (p->fts_flags & FTS_SYMFOLLOW)
+ (void)close(p->fts_symfd);
+ if (sp->fts_child) {
+ fts_lfree(sp->fts_child);
+ sp->fts_child = NULL;
+ }
+ p->fts_info = FTS_DP;
+ return (p);
+ }
+
+ /* Rebuild if only read the names and now traversing. */
+ if (sp->fts_child && ISSET(FTS_NAMEONLY)) {
+ CLR(FTS_NAMEONLY);
+ fts_lfree(sp->fts_child);
+ sp->fts_child = NULL;
+ }
+
+ /*
+ * Cd to the subdirectory.
+ *
+ * If have already read and now fail to chdir, whack the list
+ * to make the names come out right, and set the parent errno
+ * so the application will eventually get an error condition.
+ * Set the FTS_DONTCHDIR flag so that when we logically change
+ * directories back to the parent we don't do a chdir.
+ *
+ * If haven't read do so. If the read fails, fts_build sets
+ * FTS_STOP or the fts_info field of the node.
+ */
+ if (sp->fts_child) {
+ if (fts_safe_changedir(sp, p, -1)) {
+ p->fts_errno = errno;
+ p->fts_flags |= FTS_DONTCHDIR;
+ for (p = sp->fts_child; p; p = p->fts_link)
+ p->fts_accpath =
+ p->fts_parent->fts_accpath;
+ }
+ } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
+ if (ISSET(FTS_STOP))
+ return (NULL);
+ return (p);
+ }
+ p = sp->fts_child;
+ sp->fts_child = NULL;
+ goto name;
+ }
+
+ /* Move to the next node on this level. */
+next: tmp = p;
+ if ((p = p->fts_link)) {
+ free(tmp);
+
+ /*
+ * If reached the top, return to the original directory (or
+ * the root of the tree), and load the paths for the next root.
+ */
+ if (p->fts_level == FTS_ROOTLEVEL) {
+ if (FCHDIR(sp, sp->fts_rfd)) {
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ fts_load(sp, p);
+ return (sp->fts_cur = p);
+ }
+
+ /*
+ * User may have called fts_set on the node. If skipped,
+ * ignore. If followed, get a file descriptor so we can
+ * get back if necessary.
+ */
+ if (p->fts_instr == FTS_SKIP)
+ goto next;
+ if (p->fts_instr == FTS_FOLLOW) {
+ p->fts_info = fts_stat(sp, p, 1);
+ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
+ if ((p->fts_symfd =
+ open(".", O_RDONLY, 0)) < 0) {
+ p->fts_errno = errno;
+ p->fts_info = FTS_ERR;
+ } else
+ p->fts_flags |= FTS_SYMFOLLOW;
+ }
+ p->fts_instr = FTS_NOINSTR;
+ }
+
+name: t = sp->fts_path + NAPPEND(p->fts_parent);
+ *t++ = '/';
+ memmove(t, p->fts_name, p->fts_namelen + 1);
+ return (sp->fts_cur = p);
+ }
+
+ /* Move up to the parent node. */
+ p = tmp->fts_parent;
+ free(tmp);
+
+ if (p->fts_level == FTS_ROOTPARENTLEVEL) {
+ /*
+ * Done; free everything up and set errno to 0 so the user
+ * can distinguish between error and EOF.
+ */
+ free(p);
+ errno = 0;
+ return (sp->fts_cur = NULL);
+ }
+
+ /* NUL terminate the pathname. */
+ sp->fts_path[p->fts_pathlen] = '\0';
+
+ /*
+ * Return to the parent directory. If at a root node or came through
+ * a symlink, go back through the file descriptor. Otherwise, cd up
+ * one directory.
+ */
+ if (p->fts_level == FTS_ROOTLEVEL) {
+ if (FCHDIR(sp, sp->fts_rfd)) {
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ } else if (p->fts_flags & FTS_SYMFOLLOW) {
+ if (FCHDIR(sp, p->fts_symfd)) {
+ saved_errno = errno;
+ (void)close(p->fts_symfd);
+ errno = saved_errno;
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ (void)close(p->fts_symfd);
+ } else if (!(p->fts_flags & FTS_DONTCHDIR)) {
+ if (CHDIR(sp, "..")) {
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ }
+ p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
+ return (sp->fts_cur = p);
+}
+
+/*
+ * Fts_set takes the stream as an argument although it's not used in this
+ * implementation; it would be necessary if anyone wanted to add global
+ * semantics to fts using fts_set. An error return is allowed for similar
+ * reasons.
+ */
+/* ARGSUSED */
+int
+fts_set(sp, p, instr)
+ FTS *sp;
+ FTSENT *p;
+ int instr;
+{
+ if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
+ instr != FTS_NOINSTR && instr != FTS_SKIP) {
+ errno = EINVAL;
+ return (1);
+ }
+ p->fts_instr = instr;
+ return (0);
+}
+
+FTSENT *
+fts_children(sp, instr)
+ register FTS *sp;
+ int instr;
+{
+ register FTSENT *p;
+ int fd;
+
+ if (instr && instr != FTS_NAMEONLY) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /* Set current node pointer. */
+ p = sp->fts_cur;
+
+ /*
+ * Errno set to 0 so user can distinguish empty directory from
+ * an error.
+ */
+ errno = 0;
+
+ /* Fatal errors stop here. */
+ if (ISSET(FTS_STOP))
+ return (NULL);
+
+ /* Return logical hierarchy of user's arguments. */
+ if (p->fts_info == FTS_INIT)
+ return (p->fts_link);
+
+ /*
+ * If not a directory being visited in pre-order, stop here. Could
+ * allow FTS_DNR, assuming the user has fixed the problem, but the
+ * same effect is available with FTS_AGAIN.
+ */
+ if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
+ return (NULL);
+
+ /* Free up any previous child list. */
+ if (sp->fts_child)
+ fts_lfree(sp->fts_child);
+
+ if (instr == FTS_NAMEONLY) {
+ SET(FTS_NAMEONLY);
+ instr = BNAMES;
+ } else
+ instr = BCHILD;
+
+ /*
+ * If using chdir on a relative path and called BEFORE fts_read does
+ * its chdir to the root of a traversal, we can lose -- we need to
+ * chdir into the subdirectory, and we don't know where the current
+ * directory is, so we can't get back so that the upcoming chdir by
+ * fts_read will work.
+ */
+ if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
+ ISSET(FTS_NOCHDIR))
+ return (sp->fts_child = fts_build(sp, instr));
+
+ if ((fd = open(".", O_RDONLY, 0)) < 0)
+ return (NULL);
+ sp->fts_child = fts_build(sp, instr);
+ if (fchdir(fd))
+ return (NULL);
+ (void)close(fd);
+ return (sp->fts_child);
+}
+
+/*
+ * This is the tricky part -- do not casually change *anything* in here. The
+ * idea is to build the linked list of entries that are used by fts_children
+ * and fts_read. There are lots of special cases.
+ *
+ * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
+ * set and it's a physical walk (so that symbolic links can't be directories),
+ * we can do things quickly. First, if it's a 4.4BSD file system, the type
+ * of the file is in the directory entry. Otherwise, we assume that the number
+ * of subdirectories in a node is equal to the number of links to the parent.
+ * The former skips all stat calls. The latter skips stat calls in any leaf
+ * directories and for any files after the subdirectories in the directory have
+ * been found, cutting the stat calls by about 2/3.
+ */
+static FTSENT *
+fts_build(sp, type)
+ register FTS *sp;
+ int type;
+{
+ register struct dirent *dp;
+ register FTSENT *p, *head;
+ register int nitems;
+ FTSENT *cur, *tail;
+ DIR *dirp;
+ void *oldaddr;
+ int cderrno, descend, len, level, maxlen, nlinks, oflag, saved_errno,
+ nostat, doadjust;
+ char *cp;
+
+ /* Set current node pointer. */
+ cur = sp->fts_cur;
+
+ /*
+ * Open the directory for reading. If this fails, we're done.
+ * If being called from fts_read, set the fts_info field.
+ */
+#ifdef FTS_WHITEOUT
+ if (ISSET(FTS_WHITEOUT))
+ oflag = DTF_NODUP|DTF_REWIND;
+ else
+ oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
+#else
+#define __opendir2(path, flag) opendir(path)
+#endif
+ if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
+ if (type == BREAD) {
+ cur->fts_info = FTS_DNR;
+ cur->fts_errno = errno;
+ }
+ return (NULL);
+ }
+
+ /*
+ * Nlinks is the number of possible entries of type directory in the
+ * directory if we're cheating on stat calls, 0 if we're not doing
+ * any stat calls at all, -1 if we're doing stats on everything.
+ */
+ if (type == BNAMES) {
+ nlinks = 0;
+ /* Be quiet about nostat, GCC. */
+ nostat = 0;
+ } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
+ nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
+ nostat = 1;
+ } else {
+ nlinks = -1;
+ nostat = 0;
+ }
+
+#ifdef notdef
+ (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink);
+ (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n",
+ ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT));
+#endif
+ /*
+ * If we're going to need to stat anything or we want to descend
+ * and stay in the directory, chdir. If this fails we keep going,
+ * but set a flag so we don't chdir after the post-order visit.
+ * We won't be able to stat anything, but we can still return the
+ * names themselves. Note, that since fts_read won't be able to
+ * chdir into the directory, it will have to return different path
+ * names than before, i.e. "a/b" instead of "b". Since the node
+ * has already been visited in pre-order, have to wait until the
+ * post-order visit to return the error. There is a special case
+ * here, if there was nothing to stat then it's not an error to
+ * not be able to stat. This is all fairly nasty. If a program
+ * needed sorted entries or stat information, they had better be
+ * checking FTS_NS on the returned nodes.
+ */
+ cderrno = 0;
+ if (nlinks || type == BREAD) {
+ if (fts_safe_changedir(sp, cur, dirfd(dirp))) {
+ if (nlinks && type == BREAD)
+ cur->fts_errno = errno;
+ cur->fts_flags |= FTS_DONTCHDIR;
+ descend = 0;
+ cderrno = errno;
+ (void)closedir(dirp);
+ dirp = NULL;
+ } else
+ descend = 1;
+ } else
+ descend = 0;
+
+ /*
+ * Figure out the max file name length that can be stored in the
+ * current path -- the inner loop allocates more path as necessary.
+ * We really wouldn't have to do the maxlen calculations here, we
+ * could do them in fts_read before returning the path, but it's a
+ * lot easier here since the length is part of the dirent structure.
+ *
+ * If not changing directories set a pointer so that can just append
+ * each new name into the path.
+ */
+ len = NAPPEND(cur);
+ if (ISSET(FTS_NOCHDIR)) {
+ cp = sp->fts_path + len;
+ *cp++ = '/';
+ } else {
+ /* GCC, you're too verbose. */
+ cp = NULL;
+ }
+ len++;
+ maxlen = sp->fts_pathlen - len;
+
+ level = cur->fts_level + 1;
+
+ /* Read the directory, attaching each entry to the `link' pointer. */
+ doadjust = 0;
+ for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
+ if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
+ continue;
+
+ if ((p = fts_alloc(sp, dp->d_name, (int)dp->d_namlen)) == NULL)
+ goto mem1;
+ if (dp->d_namlen >= maxlen) { /* include space for NUL */
+ oldaddr = sp->fts_path;
+ if (fts_palloc(sp, dp->d_namlen +len + 1)) {
+ /*
+ * No more memory for path or structures. Save
+ * errno, free up the current structure and the
+ * structures already allocated.
+ */
+mem1: saved_errno = errno;
+ if (p)
+ free(p);
+ fts_lfree(head);
+ (void)closedir(dirp);
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ errno = saved_errno;
+ return (NULL);
+ }
+ /* Did realloc() change the pointer? */
+ if (oldaddr != sp->fts_path) {
+ doadjust = 1;
+ if (ISSET(FTS_NOCHDIR))
+ cp = sp->fts_path + len;
+ }
+ maxlen = sp->fts_pathlen - len;
+ }
+
+ if (len + dp->d_namlen >= USHRT_MAX) {
+ /*
+ * In an FTSENT, fts_pathlen is a u_short so it is
+ * possible to wraparound here. If we do, free up
+ * the current structure and the structures already
+ * allocated, then error out with ENAMETOOLONG.
+ */
+ free(p);
+ fts_lfree(head);
+ (void)closedir(dirp);
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ p->fts_level = level;
+ p->fts_parent = sp->fts_cur;
+ p->fts_pathlen = len + dp->d_namlen;
+
+#ifdef FTS_WHITEOUT
+ if (dp->d_type == DT_WHT)
+ p->fts_flags |= FTS_ISW;
+#endif
+
+ if (cderrno) {
+ if (nlinks) {
+ p->fts_info = FTS_NS;
+ p->fts_errno = cderrno;
+ } else
+ p->fts_info = FTS_NSOK;
+ p->fts_accpath = cur->fts_accpath;
+ } else if (nlinks == 0
+#ifdef DT_DIR
+ || (nostat &&
+ dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
+#endif
+ ) {
+ p->fts_accpath =
+ ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
+ p->fts_info = FTS_NSOK;
+ } else {
+ /* Build a file name for fts_stat to stat. */
+ if (ISSET(FTS_NOCHDIR)) {
+ p->fts_accpath = p->fts_path;
+ memmove(cp, p->fts_name, p->fts_namelen + 1);
+ } else
+ p->fts_accpath = p->fts_name;
+ /* Stat it. */
+ p->fts_info = fts_stat(sp, p, 0);
+
+ /* Decrement link count if applicable. */
+ if (nlinks > 0 && (p->fts_info == FTS_D ||
+ p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
+ --nlinks;
+ }
+
+ /* We walk in directory order so "ls -f" doesn't get upset. */
+ p->fts_link = NULL;
+ if (head == NULL)
+ head = tail = p;
+ else {
+ tail->fts_link = p;
+ tail = p;
+ }
+ ++nitems;
+ }
+ if (dirp)
+ (void)closedir(dirp);
+
+ /*
+ * If realloc() changed the address of the path, adjust the
+ * addresses for the rest of the tree and the dir list.
+ */
+ if (doadjust)
+ fts_padjust(sp, head);
+
+ /*
+ * If not changing directories, reset the path back to original
+ * state.
+ */
+ if (ISSET(FTS_NOCHDIR)) {
+ if (len == sp->fts_pathlen || nitems == 0)
+ --cp;
+ *cp = '\0';
+ }
+
+ /*
+ * If descended after called from fts_children or after called from
+ * fts_read and nothing found, get back. At the root level we use
+ * the saved fd; if one of fts_open()'s arguments is a relative path
+ * to an empty directory, we wind up here with no other way back. If
+ * can't get back, we're done.
+ */
+ if (descend && (type == BCHILD || !nitems) &&
+ (cur->fts_level == FTS_ROOTLEVEL ?
+ FCHDIR(sp, sp->fts_rfd) : CHDIR(sp, ".."))) {
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ return (NULL);
+ }
+
+ /* If didn't find anything, return NULL. */
+ if (!nitems) {
+ if (type == BREAD)
+ cur->fts_info = FTS_DP;
+ return (NULL);
+ }
+
+ /* Sort the entries. */
+ if (sp->fts_compar && nitems > 1)
+ head = fts_sort(sp, head, nitems);
+ return (head);
+}
+
+static u_short
+fts_stat(sp, p, follow)
+ FTS *sp;
+ register FTSENT *p;
+ int follow;
+{
+ register FTSENT *t;
+ register dev_t dev;
+ register ino_t ino;
+ struct stat *sbp, sb;
+ int saved_errno;
+
+ /* If user needs stat info, stat buffer already allocated. */
+ sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
+
+#ifdef FTS_WHITEOUT
+ /* check for whiteout */
+ if (p->fts_flags & FTS_ISW) {
+ if (sbp != &sb) {
+ memset(sbp, '\0', sizeof (*sbp));
+ sbp->st_mode = S_IFWHT;
+ }
+ return (FTS_W);
+ }
+#endif
+
+ /*
+ * If doing a logical walk, or application requested FTS_FOLLOW, do
+ * a stat(2). If that fails, check for a non-existent symlink. If
+ * fail, set the errno from the stat call.
+ */
+ if (ISSET(FTS_LOGICAL) || follow) {
+ if (stat(p->fts_accpath, sbp)) {
+ saved_errno = errno;
+ if (!lstat(p->fts_accpath, sbp)) {
+ errno = 0;
+ return (FTS_SLNONE);
+ }
+ p->fts_errno = saved_errno;
+ goto err;
+ }
+ } else if (lstat(p->fts_accpath, sbp)) {
+ p->fts_errno = errno;
+err: memset(sbp, 0, sizeof(struct stat));
+ return (FTS_NS);
+ }
+
+ if (S_ISDIR(sbp->st_mode)) {
+ /*
+ * Set the device/inode. Used to find cycles and check for
+ * crossing mount points. Also remember the link count, used
+ * in fts_build to limit the number of stat calls. It is
+ * understood that these fields are only referenced if fts_info
+ * is set to FTS_D.
+ */
+ dev = p->fts_dev = sbp->st_dev;
+ ino = p->fts_ino = sbp->st_ino;
+ p->fts_nlink = sbp->st_nlink;
+
+ if (ISDOT(p->fts_name))
+ return (FTS_DOT);
+
+ /*
+ * Cycle detection is done by brute force when the directory
+ * is first encountered. If the tree gets deep enough or the
+ * number of symbolic links to directories is high enough,
+ * something faster might be worthwhile.
+ */
+ for (t = p->fts_parent;
+ t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
+ if (ino == t->fts_ino && dev == t->fts_dev) {
+ p->fts_cycle = t;
+ return (FTS_DC);
+ }
+ return (FTS_D);
+ }
+ if (S_ISLNK(sbp->st_mode))
+ return (FTS_SL);
+ if (S_ISREG(sbp->st_mode))
+ return (FTS_F);
+ return (FTS_DEFAULT);
+}
+
+static FTSENT *
+fts_sort(sp, head, nitems)
+ FTS *sp;
+ FTSENT *head;
+ register int nitems;
+{
+ register FTSENT **ap, *p;
+
+ /*
+ * Construct an array of pointers to the structures and call qsort(3).
+ * Reassemble the array in the order returned by qsort. If unable to
+ * sort for memory reasons, return the directory entries in their
+ * current order. Allocate enough space for the current needs plus
+ * 40 so don't realloc one entry at a time.
+ */
+ if (nitems > sp->fts_nitems) {
+ struct _ftsent **a;
+
+ sp->fts_nitems = nitems + 40;
+ if ((a = realloc(sp->fts_array,
+ sp->fts_nitems * sizeof(FTSENT *))) == NULL) {
+ if (sp->fts_array)
+ free(sp->fts_array);
+ sp->fts_array = NULL;
+ sp->fts_nitems = 0;
+ return (head);
+ }
+ sp->fts_array = a;
+ }
+ for (ap = sp->fts_array, p = head; p; p = p->fts_link)
+ *ap++ = p;
+ qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
+ for (head = *(ap = sp->fts_array); --nitems; ++ap)
+ ap[0]->fts_link = ap[1];
+ ap[0]->fts_link = NULL;
+ return (head);
+}
+
+static FTSENT *
+fts_alloc(sp, name, namelen)
+ FTS *sp;
+ char *name;
+ register int namelen;
+{
+ register FTSENT *p;
+ size_t len;
+
+ /*
+ * The file name is a variable length array and no stat structure is
+ * necessary if the user has set the nostat bit. Allocate the FTSENT
+ * structure, the file name and the stat structure in one chunk, but
+ * be careful that the stat structure is reasonably aligned. Since the
+ * fts_name field is declared to be of size 1, the fts_name pointer is
+ * namelen + 2 before the first possible address of the stat structure.
+ */
+ len = sizeof(FTSENT) + namelen;
+ if (!ISSET(FTS_NOSTAT))
+ len += sizeof(struct stat) + ALIGNBYTES;
+ if ((p = malloc(len)) == NULL)
+ return (NULL);
+
+ /* Copy the name and guarantee NUL termination. */
+ memmove(p->fts_name, name, namelen);
+ p->fts_name[namelen] = '\0';
+
+ if (!ISSET(FTS_NOSTAT))
+ p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2);
+ p->fts_namelen = namelen;
+ p->fts_path = sp->fts_path;
+ p->fts_errno = 0;
+ p->fts_flags = 0;
+ p->fts_instr = FTS_NOINSTR;
+ p->fts_number = 0;
+ p->fts_pointer = NULL;
+ return (p);
+}
+
+static void
+fts_lfree(head)
+ register FTSENT *head;
+{
+ register FTSENT *p;
+
+ /* Free a linked list of structures. */
+ while ((p = head)) {
+ head = head->fts_link;
+ free(p);
+ }
+}
+
+/*
+ * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
+ * Most systems will allow creation of paths much longer than MAXPATHLEN, even
+ * though the kernel won't resolve them. Add the size (not just what's needed)
+ * plus 256 bytes so don't realloc the path 2 bytes at a time.
+ */
+static int
+fts_palloc(sp, more)
+ FTS *sp;
+ size_t more;
+{
+ char *p;
+
+ sp->fts_pathlen += more + 256;
+ /*
+ * Check for possible wraparound. In an FTS, fts_pathlen is
+ * a signed int but in an FTSENT it is an unsigned short.
+ * We limit fts_pathlen to USHRT_MAX to be safe in both cases.
+ */
+ if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) {
+ if (sp->fts_path)
+ free(sp->fts_path);
+ sp->fts_path = NULL;
+ errno = ENAMETOOLONG;
+ return (1);
+ }
+ p = realloc(sp->fts_path, sp->fts_pathlen);
+ if (p == NULL) {
+ if (sp->fts_path)
+ free(sp->fts_path);
+ sp->fts_path = NULL;
+ return (1);
+ }
+ sp->fts_path = p;
+ return (0);
+}
+
+/*
+ * When the path is realloc'd, have to fix all of the pointers in structures
+ * already returned.
+ */
+static void
+fts_padjust(sp, head)
+ FTS *sp;
+ FTSENT *head;
+{
+ FTSENT *p;
+ char *addr = sp->fts_path;
+
+#define ADJUST(p) { \
+ if ((p)->fts_accpath != (p)->fts_name) { \
+ (p)->fts_accpath = \
+ (char *)addr + ((p)->fts_accpath - (p)->fts_path); \
+ } \
+ (p)->fts_path = addr; \
+}
+ /* Adjust the current set of children. */
+ for (p = sp->fts_child; p; p = p->fts_link)
+ ADJUST(p);
+
+ /* Adjust the rest of the tree, including the current level. */
+ for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
+ ADJUST(p);
+ p = p->fts_link ? p->fts_link : p->fts_parent;
+ }
+}
+
+static size_t
+fts_maxarglen(argv)
+ char * const *argv;
+{
+ size_t len, max;
+
+ for (max = 0; *argv; ++argv)
+ if ((len = strlen(*argv)) > max)
+ max = len;
+ return (max + 1);
+}
+
+/*
+ * Change to dir specified by fd or p->fts_accpath without getting
+ * tricked by someone changing the world out from underneath us.
+ * Assumes p->fts_dev and p->fts_ino are filled in.
+ */
+static int
+fts_safe_changedir(sp, p, fd)
+ FTS *sp;
+ FTSENT *p;
+ int fd;
+{
+ int ret, oerrno, newfd;
+ struct stat sb;
+
+ newfd = fd;
+ if (ISSET(FTS_NOCHDIR))
+ return (0);
+ if (fd < 0 && (newfd = open(p->fts_accpath, O_RDONLY, 0)) < 0)
+ return (-1);
+ if (fstat(newfd, &sb)) {
+ ret = -1;
+ goto bail;
+ }
+ if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {
+ errno = ENOENT; /* disinformation */
+ ret = -1;
+ goto bail;
+ }
+ ret = fchdir(newfd);
+bail:
+ oerrno = errno;
+ if (fd < 0)
+ (void)close(newfd);
+ errno = oerrno;
+ return (ret);
+}
diff --git a/lib/libc/gen/fts-compat.h b/lib/libc/gen/fts-compat.h
new file mode 100644
index 0000000..4fa4a3a
--- /dev/null
+++ b/lib/libc/gen/fts-compat.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)fts.h 8.3 (Berkeley) 8/14/94
+ */
+
+#ifndef _FTS_H_
+#define _FTS_H_
+
+typedef struct {
+ struct _ftsent *fts_cur; /* current node */
+ struct _ftsent *fts_child; /* linked list of children */
+ struct _ftsent **fts_array; /* sort array */
+ dev_t fts_dev; /* starting device # */
+ char *fts_path; /* path for this descent */
+ int fts_rfd; /* fd for root */
+ int fts_pathlen; /* sizeof(path) */
+ int fts_nitems; /* elements in the sort array */
+ int (*fts_compar)(); /* compare function */
+
+#define FTS_COMFOLLOW 0x001 /* follow command line symlinks */
+#define FTS_LOGICAL 0x002 /* logical walk */
+#define FTS_NOCHDIR 0x004 /* don't change directories */
+#define FTS_NOSTAT 0x008 /* don't get stat info */
+#define FTS_PHYSICAL 0x010 /* physical walk */
+#define FTS_SEEDOT 0x020 /* return dot and dot-dot */
+#define FTS_XDEV 0x040 /* don't cross devices */
+#define FTS_WHITEOUT 0x080 /* return whiteout information */
+#define FTS_OPTIONMASK 0x0ff /* valid user option mask */
+
+#define FTS_NAMEONLY 0x100 /* (private) child names only */
+#define FTS_STOP 0x200 /* (private) unrecoverable error */
+ int fts_options; /* fts_open options, global flags */
+} FTS;
+
+typedef struct _ftsent {
+ struct _ftsent *fts_cycle; /* cycle node */
+ struct _ftsent *fts_parent; /* parent directory */
+ struct _ftsent *fts_link; /* next file in directory */
+ long fts_number; /* local numeric value */
+ void *fts_pointer; /* local address value */
+ char *fts_accpath; /* access path */
+ char *fts_path; /* root path */
+ int fts_errno; /* errno for this node */
+ int fts_symfd; /* fd for symlink */
+ u_short fts_pathlen; /* strlen(fts_path) */
+ u_short fts_namelen; /* strlen(fts_name) */
+
+ ino_t fts_ino; /* inode */
+ dev_t fts_dev; /* device */
+ nlink_t fts_nlink; /* link count */
+
+#define FTS_ROOTPARENTLEVEL -1
+#define FTS_ROOTLEVEL 0
+ short fts_level; /* depth (-1 to N) */
+
+#define FTS_D 1 /* preorder directory */
+#define FTS_DC 2 /* directory that causes cycles */
+#define FTS_DEFAULT 3 /* none of the above */
+#define FTS_DNR 4 /* unreadable directory */
+#define FTS_DOT 5 /* dot or dot-dot */
+#define FTS_DP 6 /* postorder directory */
+#define FTS_ERR 7 /* error; errno is set */
+#define FTS_F 8 /* regular file */
+#define FTS_INIT 9 /* initialized only */
+#define FTS_NS 10 /* stat(2) failed */
+#define FTS_NSOK 11 /* no stat(2) requested */
+#define FTS_SL 12 /* symbolic link */
+#define FTS_SLNONE 13 /* symbolic link without target */
+#define FTS_W 14 /* whiteout object */
+ u_short fts_info; /* user flags for FTSENT structure */
+
+#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */
+#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */
+#define FTS_ISW 0x04 /* this is a whiteout object */
+ u_short fts_flags; /* private flags for FTSENT structure */
+
+#define FTS_AGAIN 1 /* read node again */
+#define FTS_FOLLOW 2 /* follow symbolic link */
+#define FTS_NOINSTR 3 /* no instructions */
+#define FTS_SKIP 4 /* discard node */
+ u_short fts_instr; /* fts_set() instructions */
+
+ struct stat *fts_statp; /* stat(2) information */
+ char fts_name[1]; /* file name */
+} FTSENT;
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+FTSENT *fts_children __P((FTS *, int));
+int fts_close __P((FTS *));
+FTS *fts_open __P((char * const *, int,
+ int (*)(const FTSENT **, const FTSENT **)));
+FTSENT *fts_read __P((FTS *));
+int fts_set __P((FTS *, FTSENT *, int));
+__END_DECLS
+
+#endif /* !_FTS_H_ */
diff --git a/lib/libc/gen/fts.3 b/lib/libc/gen/fts.3
new file mode 100644
index 0000000..ba21c89
--- /dev/null
+++ b/lib/libc/gen/fts.3
@@ -0,0 +1,755 @@
+.\" Copyright (c) 1989, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fts.3 8.5 (Berkeley) 4/16/94
+.\" $FreeBSD$
+.\"
+.Dd April 16, 1994
+.Dt FTS 3
+.Os
+.Sh NAME
+.Nm fts
+.Nd traverse a file hierarchy
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/stat.h>
+.Fd #include <fts.h>
+.Ft FTS *
+.Fn fts_open "char * const *path_argv" "int options" "int (*compar)(const FTSENT **, const FTSENT **)"
+.Ft FTSENT *
+.Fn fts_read "FTS *ftsp"
+.Ft FTSENT *
+.Fn fts_children "FTS *ftsp" "int options"
+.Ft int
+.Fn fts_set "FTS *ftsp" "FTSENT *f" "int options"
+.Ft int
+.Fn fts_close "FTS *ftsp"
+.Sh DESCRIPTION
+The
+.Nm fts
+functions are provided for traversing
+.Tn UNIX
+file hierarchies.
+A simple overview is that the
+.Fn fts_open
+function returns a
+.Dq handle
+on a file hierarchy, which is then supplied to
+the other
+.Nm fts
+functions.
+The function
+.Fn fts_read
+returns a pointer to a structure describing one of the files in the file
+hierarchy.
+The function
+.Fn fts_children
+returns a pointer to a linked list of structures, each of which describes
+one of the files contained in a directory in the hierarchy.
+In general, directories are visited two distinguishable times; in pre-order
+(before any of their descendants are visited) and in post-order (after all
+of their descendants have been visited).
+Files are visited once.
+It is possible to walk the hierarchy
+.Dq logically
+(ignoring symbolic links)
+or physically (visiting symbolic links), order the walk of the hierarchy or
+prune and/or re-visit portions of the hierarchy.
+.Pp
+Two structures are defined (and typedef'd) in the include file
+.Aq Pa fts.h .
+The first is
+.Fa FTS ,
+the structure that represents the file hierarchy itself.
+The second is
+.Fa FTSENT ,
+the structure that represents a file in the file
+hierarchy.
+Normally, an
+.Fa FTSENT
+structure is returned for every file in the file
+hierarchy.
+In this manual page,
+.Dq file
+and
+.Dq Fa FTSENT No structure
+are generally
+interchangeable.
+The
+.Fa FTSENT
+structure contains at least the following fields, which are
+described in greater detail below:
+.Bd -literal
+typedef struct _ftsent {
+ u_short fts_info; /* flags for FTSENT structure */
+ char *fts_accpath; /* access path */
+ char *fts_path; /* root path */
+ u_short fts_pathlen; /* strlen(fts_path) */
+ char *fts_name; /* file name */
+ u_short fts_namelen; /* strlen(fts_name) */
+ short fts_level; /* depth (\-1 to N) */
+ int fts_errno; /* file errno */
+ long fts_number; /* local numeric value */
+ void *fts_pointer; /* local address value */
+ struct ftsent *fts_parent; /* parent directory */
+ struct ftsent *fts_link; /* next file structure */
+ struct ftsent *fts_cycle; /* cycle structure */
+ struct stat *fts_statp; /* stat(2) information */
+} FTSENT;
+.Ed
+.Pp
+These fields are defined as follows:
+.Bl -tag -width "fts_namelen"
+.It Fa fts_info
+One of the following values describing the returned
+.Fa FTSENT
+structure and
+the file it represents.
+With the exception of directories without errors
+.Pq Dv FTS_D ,
+all of these
+entries are terminal, that is, they will not be revisited, nor will any
+of their descendants be visited.
+.Bl -tag -width FTS_DEFAULT
+.It Dv FTS_D
+A directory being visited in pre-order.
+.It Dv FTS_DC
+A directory that causes a cycle in the tree.
+(The
+.Fa fts_cycle
+field of the
+.Fa FTSENT
+structure will be filled in as well.)
+.It Dv FTS_DEFAULT
+Any
+.Fa FTSENT
+structure that represents a file type not explicitly described
+by one of the other
+.Fa fts_info
+values.
+.It Dv FTS_DNR
+A directory which cannot be read.
+This is an error return, and the
+.Fa fts_errno
+field will be set to indicate what caused the error.
+.It Dv FTS_DOT
+A file named
+.Ql \&.
+or
+.Ql ..
+which was not specified as a file name to
+.Fn fts_open
+(see
+.Dv FTS_SEEDOT ) .
+.It Dv FTS_DP
+A directory being visited in post-order.
+The contents of the
+.Fa FTSENT
+structure will be unchanged from when
+it was returned in pre-order, i.e. with the
+.Fa fts_info
+field set to
+.Dv FTS_D .
+.It Dv FTS_ERR
+This is an error return, and the
+.Fa fts_errno
+field will be set to indicate what caused the error.
+.It Dv FTS_F
+A regular file.
+.It Dv FTS_NS
+A file for which no
+.Xr stat 2
+information was available.
+The contents of the
+.Fa fts_statp
+field are undefined.
+This is an error return, and the
+.Fa fts_errno
+field will be set to indicate what caused the error.
+.It Dv FTS_NSOK
+A file for which no
+.Xr stat 2
+information was requested.
+The contents of the
+.Fa fts_statp
+field are undefined.
+.It Dv FTS_SL
+A symbolic link.
+.It Dv FTS_SLNONE
+A symbolic link with a non-existent target.
+The contents of the
+.Fa fts_statp
+field reference the file characteristic information for the symbolic link
+itself.
+.El
+.It Fa fts_accpath
+A path for accessing the file from the current directory.
+.It Fa fts_path
+The path for the file relative to the root of the traversal.
+This path contains the path specified to
+.Fn fts_open
+as a prefix.
+.It Fa fts_pathlen
+The length of the string referenced by
+.Fa fts_path .
+.It Fa fts_name
+The name of the file.
+.It Fa fts_namelen
+The length of the string referenced by
+.Fa fts_name .
+.It Fa fts_level
+The depth of the traversal, numbered from \-1 to N, where this file
+was found.
+The
+.Fa FTSENT
+structure representing the parent of the starting point (or root)
+of the traversal is numbered \-1, and the
+.Fa FTSENT
+structure for the root
+itself is numbered 0.
+.It Fa fts_errno
+Upon return of a
+.Fa FTSENT
+structure from the
+.Fn fts_children
+or
+.Fn fts_read
+functions, with its
+.Fa fts_info
+field set to
+.Dv FTS_DNR ,
+.Dv FTS_ERR
+or
+.Dv FTS_NS ,
+the
+.Fa fts_errno
+field contains the value of the external variable
+.Va errno
+specifying the cause of the error.
+Otherwise, the contents of the
+.Fa fts_errno
+field are undefined.
+.It Fa fts_number
+This field is provided for the use of the application program and is
+not modified by the
+.Nm fts
+functions.
+It is initialized to 0.
+.It Fa fts_pointer
+This field is provided for the use of the application program and is
+not modified by the
+.Nm fts
+functions.
+It is initialized to
+.Dv NULL .
+.It Fa fts_parent
+A pointer to the
+.Fa FTSENT
+structure referencing the file in the hierarchy
+immediately above the current file, i.e. the directory of which this
+file is a member.
+A parent structure for the initial entry point is provided as well,
+however, only the
+.Fa fts_level ,
+.Fa fts_number
+and
+.Fa fts_pointer
+fields are guaranteed to be initialized.
+.It Fa fts_link
+Upon return from the
+.Fn fts_children
+function, the
+.Fa fts_link
+field points to the next structure in the NULL-terminated linked list of
+directory members.
+Otherwise, the contents of the
+.Fa fts_link
+field are undefined.
+.It Fa fts_cycle
+If a directory causes a cycle in the hierarchy (see
+.Dv FTS_DC ) ,
+either because
+of a hard link between two directories, or a symbolic link pointing to a
+directory, the
+.Fa fts_cycle
+field of the structure will point to the
+.Fa FTSENT
+structure in the hierarchy that references the same file as the current
+.Fa FTSENT
+structure.
+Otherwise, the contents of the
+.Fa fts_cycle
+field are undefined.
+.It Fa fts_statp
+A pointer to
+.Xr stat 2
+information for the file.
+.El
+.Pp
+A single buffer is used for all of the paths of all of the files in the
+file hierarchy.
+Therefore, the
+.Fa fts_path
+and
+.Fa fts_accpath
+fields are guaranteed to be
+.Dv NUL Ns -terminated
+.Em only
+for the file most recently returned by
+.Fn fts_read .
+To use these fields to reference any files represented by other
+.Fa FTSENT
+structures will require that the path buffer be modified using the
+information contained in that
+.Fa FTSENT
+structure's
+.Fa fts_pathlen
+field.
+Any such modifications should be undone before further calls to
+.Fn fts_read
+are attempted.
+The
+.Fa fts_name
+field is always
+.Dv NUL Ns -terminated.
+.Sh FTS_OPEN
+The
+.Fn fts_open
+function takes a pointer to an array of character pointers naming one
+or more paths which make up a logical file hierarchy to be traversed.
+The array must be terminated by a
+.Dv NULL
+pointer.
+.Pp
+There are
+a number of options, at least one of which (either
+.Dv FTS_LOGICAL
+or
+.Dv FTS_PHYSICAL )
+must be specified.
+The options are selected by
+.Em or Ns 'ing
+the following values:
+.Bl -tag -width "FTS_PHYSICAL"
+.It Dv FTS_COMFOLLOW
+This option causes any symbolic link specified as a root path to be
+followed immediately whether or not
+.Dv FTS_LOGICAL
+is also specified.
+.It Dv FTS_LOGICAL
+This option causes the
+.Nm fts
+routines to return
+.Fa FTSENT
+structures for the targets of symbolic links
+instead of the symbolic links themselves.
+If this option is set, the only symbolic links for which
+.Fa FTSENT
+structures
+are returned to the application are those referencing non-existent files.
+Either
+.Dv FTS_LOGICAL
+or
+.Dv FTS_PHYSICAL
+.Em must
+be provided to the
+.Fn fts_open
+function.
+.It Dv FTS_NOCHDIR
+As a performance optimization, the
+.Nm fts
+functions change directories as they walk the file hierarchy.
+This has the side-effect that an application cannot rely on being
+in any particular directory during the traversal.
+The
+.Dv FTS_NOCHDIR
+option turns off this optimization, and the
+.Nm fts
+functions will not change the current directory.
+Note that applications should not themselves change their current directory
+and try to access files unless
+.Dv FTS_NOCHDIR
+is specified and absolute
+pathnames were provided as arguments to
+.Fn fts_open .
+.It Dv FTS_NOSTAT
+By default, returned
+.Fa FTSENT
+structures reference file characteristic information (the
+.Fa statp
+field) for each file visited.
+This option relaxes that requirement as a performance optimization,
+allowing the
+.Nm fts
+functions to set the
+.Fa fts_info
+field to
+.Dv FTS_NSOK
+and leave the contents of the
+.Fa statp
+field undefined.
+.It Dv FTS_PHYSICAL
+This option causes the
+.Nm fts
+routines to return
+.Fa FTSENT
+structures for symbolic links themselves instead
+of the target files they point to.
+If this option is set,
+.Fa FTSENT
+structures for all symbolic links in the
+hierarchy are returned to the application.
+Either
+.Dv FTS_LOGICAL
+or
+.Dv FTS_PHYSICAL
+.Em must
+be provided to the
+.Fn fts_open
+function.
+.It Dv FTS_SEEDOT
+By default, unless they are specified as path arguments to
+.Fn fts_open ,
+any files named
+.Ql \&.
+or
+.Ql ..
+encountered in the file hierarchy are ignored.
+This option causes the
+.Nm fts
+routines to return
+.Fa FTSENT
+structures for them.
+.It Dv FTS_XDEV
+This option prevents
+.Nm fts
+from descending into directories that have a different device number
+than the file from which the descent began.
+.El
+.Pp
+The argument
+.Fn compar
+specifies a user-defined function which may be used to order the traversal
+of the hierarchy.
+It
+takes two pointers to pointers to
+.Fa FTSENT
+structures as arguments and
+should return a negative value, zero, or a positive value to indicate
+if the file referenced by its first argument comes before, in any order
+with respect to, or after, the file referenced by its second argument.
+The
+.Fa fts_accpath ,
+.Fa fts_path
+and
+.Fa fts_pathlen
+fields of the
+.Fa FTSENT
+structures may
+.Em never
+be used in this comparison.
+If the
+.Fa fts_info
+field is set to
+.Dv FTS_NS
+or
+.Dv FTS_NSOK ,
+the
+.Fa fts_statp
+field may not either.
+If the
+.Fn compar
+argument is
+.Dv NULL ,
+the directory traversal order is in the order listed in
+.Fa path_argv
+for the root paths, and in the order listed in the directory for
+everything else.
+.Sh FTS_READ
+The
+.Fn fts_read
+function returns a pointer to an
+.Fa FTSENT
+structure describing a file in
+the hierarchy.
+Directories (that are readable and do not cause cycles) are visited at
+least twice, once in pre-order and once in post-order.
+All other files are visited at least once.
+(Hard links between directories that do not cause cycles or symbolic
+links to symbolic links may cause files to be visited more than once,
+or directories more than twice.)
+.Pp
+If all the members of the hierarchy have been returned,
+.Fn fts_read
+returns
+.Dv NULL
+and sets the external variable
+.Va errno
+to 0.
+If an error unrelated to a file in the hierarchy occurs,
+.Fn fts_read
+returns
+.Dv NULL
+and sets
+.Va errno
+appropriately.
+If an error related to a returned file occurs, a pointer to an
+.Fa FTSENT
+structure is returned, and
+.Va errno
+may or may not have been set (see
+.Fa fts_info ) .
+.Pp
+The
+.Fa FTSENT
+structures returned by
+.Fn fts_read
+may be overwritten after a call to
+.Fn fts_close
+on the same file hierarchy stream, or, after a call to
+.Fn fts_read
+on the same file hierarchy stream unless they represent a file of type
+directory, in which case they will not be overwritten until after a call to
+.Fn fts_read
+after the
+.Fa FTSENT
+structure has been returned by the function
+.Fn fts_read
+in post-order.
+.Sh FTS_CHILDREN
+The
+.Fn fts_children
+function returns a pointer to an
+.Fa FTSENT
+structure describing the first entry in a NULL-terminated linked list of
+the files in the directory represented by the
+.Fa FTSENT
+structure most recently returned by
+.Fn fts_read .
+The list is linked through the
+.Fa fts_link
+field of the
+.Fa FTSENT
+structure, and is ordered by the user-specified comparison function, if any.
+Repeated calls to
+.Fn fts_children
+will recreate this linked list.
+.Pp
+As a special case, if
+.Fn fts_read
+has not yet been called for a hierarchy,
+.Fn fts_children
+will return a pointer to the files in the logical directory specified to
+.Fn fts_open ,
+i.e. the arguments specified to
+.Fn fts_open .
+Otherwise, if the
+.Fa FTSENT
+structure most recently returned by
+.Fn fts_read
+is not a directory being visited in pre-order,
+or the directory does not contain any files,
+.Fn fts_children
+returns
+.Dv NULL
+and sets
+.Va errno
+to zero.
+If an error occurs,
+.Fn fts_children
+returns
+.Dv NULL
+and sets
+.Va errno
+appropriately.
+.Pp
+The
+.Fa FTSENT
+structures returned by
+.Fn fts_children
+may be overwritten after a call to
+.Fn fts_children ,
+.Fn fts_close
+or
+.Fn fts_read
+on the same file hierarchy stream.
+.Pp
+.Em Option
+may be set to the following value:
+.Bl -tag -width FTS_NAMEONLY
+.It Dv FTS_NAMEONLY
+Only the names of the files are needed.
+The contents of all the fields in the returned linked list of structures
+are undefined with the exception of the
+.Fa fts_name
+and
+.Fa fts_namelen
+fields.
+.El
+.Sh FTS_SET
+The function
+.Fn fts_set
+allows the user application to determine further processing for the
+file
+.Fa f
+of the stream
+.Fa ftsp .
+The
+.Fn fts_set
+function
+returns 0 on success, and \-1 if an error occurs.
+.Em Option
+must be set to one of the following values:
+.Bl -tag -width FTS_PHYSICAL
+.It Dv FTS_AGAIN
+Re-visit the file; any file type may be re-visited.
+The next call to
+.Fn fts_read
+will return the referenced file.
+The
+.Fa fts_stat
+and
+.Fa fts_info
+fields of the structure will be reinitialized at that time,
+but no other fields will have been changed.
+This option is meaningful only for the most recently returned
+file from
+.Fn fts_read .
+Normal use is for post-order directory visits, where it causes the
+directory to be re-visited (in both pre and post-order) as well as all
+of its descendants.
+.It Dv FTS_FOLLOW
+The referenced file must be a symbolic link.
+If the referenced file is the one most recently returned by
+.Fn fts_read ,
+the next call to
+.Fn fts_read
+returns the file with the
+.Fa fts_info
+and
+.Fa fts_statp
+fields reinitialized to reflect the target of the symbolic link instead
+of the symbolic link itself.
+If the file is one of those most recently returned by
+.Fn fts_children ,
+the
+.Fa fts_info
+and
+.Fa fts_statp
+fields of the structure, when returned by
+.Fn fts_read ,
+will reflect the target of the symbolic link instead of the symbolic link
+itself.
+In either case, if the target of the symbolic link does not exist the
+fields of the returned structure will be unchanged and the
+.Fa fts_info
+field will be set to
+.Dv FTS_SLNONE .
+.Pp
+If the target of the link is a directory, the pre-order return, followed
+by the return of all of its descendants, followed by a post-order return,
+is done.
+.It Dv FTS_SKIP
+No descendants of this file are visited.
+The file may be one of those most recently returned by either
+.Fn fts_children
+or
+.Fn fts_read .
+.El
+.Sh FTS_CLOSE
+The
+.Fn fts_close
+function closes a file hierarchy stream
+.Fa ftsp
+and restores the current directory to the directory from which
+.Fn fts_open
+was called to open
+.Fa ftsp .
+The
+.Fn fts_close
+function
+returns 0 on success, and \-1 if an error occurs.
+.Sh ERRORS
+The function
+.Fn fts_open
+may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr open 2
+and
+.Xr malloc 3 .
+.Pp
+The function
+.Fn fts_close
+may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr chdir 2
+and
+.Xr close 2 .
+.Pp
+The functions
+.Fn fts_read
+and
+.Fn fts_children
+may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr chdir 2 ,
+.Xr malloc 3 ,
+.Xr opendir 3 ,
+.Xr readdir 3
+and
+.Xr stat 2 .
+.Pp
+In addition,
+.Fn fts_children ,
+.Fn fts_open
+and
+.Fn fts_set
+may fail and set
+.Va errno
+as follows:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The options were invalid.
+.El
+.Sh SEE ALSO
+.Xr find 1 ,
+.Xr chdir 2 ,
+.Xr stat 2 ,
+.Xr qsort 3
+.Sh STANDARDS
+The
+.Nm fts
+utility is expected to be included in a future
+.St -p1003.1-88
+revision.
diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c
new file mode 100644
index 0000000..0ad03ca
--- /dev/null
+++ b/lib/libc/gen/fts.c
@@ -0,0 +1,1112 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $OpenBSD: fts.c,v 1.22 1999/10/03 19:22:22 millert Exp $
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
+#else
+static char rcsid[] = "$FreeBSD$";
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fts.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static FTSENT *fts_alloc __P((FTS *, char *, int));
+static FTSENT *fts_build __P((FTS *, int));
+static void fts_lfree __P((FTSENT *));
+static void fts_load __P((FTS *, FTSENT *));
+static size_t fts_maxarglen __P((char * const *));
+static void fts_padjust __P((FTS *, FTSENT *));
+static int fts_palloc __P((FTS *, size_t));
+static FTSENT *fts_sort __P((FTS *, FTSENT *, int));
+static u_short fts_stat __P((FTS *, FTSENT *, int));
+static int fts_safe_changedir __P((FTS *, FTSENT *, int));
+
+#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
+
+#define CLR(opt) (sp->fts_options &= ~(opt))
+#define ISSET(opt) (sp->fts_options & (opt))
+#define SET(opt) (sp->fts_options |= (opt))
+
+#define CHDIR(sp, path) (!ISSET(FTS_NOCHDIR) && chdir(path))
+#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
+
+/* fts_build flags */
+#define BCHILD 1 /* fts_children */
+#define BNAMES 2 /* fts_children, names only */
+#define BREAD 3 /* fts_read */
+
+FTS *
+fts_open(argv, options, compar)
+ char * const *argv;
+ register int options;
+ int (*compar) __P((const FTSENT **, const FTSENT **));
+{
+ register FTS *sp;
+ register FTSENT *p, *root;
+ register int nitems;
+ FTSENT *parent, *tmp;
+ int len;
+
+ /* Options check. */
+ if (options & ~FTS_OPTIONMASK) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /* Allocate/initialize the stream */
+ if ((sp = malloc((u_int)sizeof(FTS))) == NULL)
+ return (NULL);
+ memset(sp, 0, sizeof(FTS));
+ sp->fts_compar = compar;
+ sp->fts_options = options;
+
+ /* Shush, GCC. */
+ tmp = NULL;
+
+ /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
+ if (ISSET(FTS_LOGICAL))
+ SET(FTS_NOCHDIR);
+
+ /*
+ * Start out with 1K of path space, and enough, in any case,
+ * to hold the user's paths.
+ */
+ if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
+ goto mem1;
+
+ /* Allocate/initialize root's parent. */
+ if ((parent = fts_alloc(sp, "", 0)) == NULL)
+ goto mem2;
+ parent->fts_level = FTS_ROOTPARENTLEVEL;
+
+ /* Allocate/initialize root(s). */
+ for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) {
+ /* Don't allow zero-length paths. */
+ if ((len = strlen(*argv)) == 0) {
+ errno = ENOENT;
+ goto mem3;
+ }
+
+ p = fts_alloc(sp, *argv, len);
+ p->fts_level = FTS_ROOTLEVEL;
+ p->fts_parent = parent;
+ p->fts_accpath = p->fts_name;
+ p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
+
+ /* Command-line "." and ".." are real directories. */
+ if (p->fts_info == FTS_DOT)
+ p->fts_info = FTS_D;
+
+ /*
+ * If comparison routine supplied, traverse in sorted
+ * order; otherwise traverse in the order specified.
+ */
+ if (compar) {
+ p->fts_link = root;
+ root = p;
+ } else {
+ p->fts_link = NULL;
+ if (root == NULL)
+ tmp = root = p;
+ else {
+ tmp->fts_link = p;
+ tmp = p;
+ }
+ }
+ }
+ if (compar && nitems > 1)
+ root = fts_sort(sp, root, nitems);
+
+ /*
+ * Allocate a dummy pointer and make fts_read think that we've just
+ * finished the node before the root(s); set p->fts_info to FTS_INIT
+ * so that everything about the "current" node is ignored.
+ */
+ if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
+ goto mem3;
+ sp->fts_cur->fts_link = root;
+ sp->fts_cur->fts_info = FTS_INIT;
+
+ /*
+ * If using chdir(2), grab a file descriptor pointing to dot to ensure
+ * that we can get back here; this could be avoided for some paths,
+ * but almost certainly not worth the effort. Slashes, symbolic links,
+ * and ".." are all fairly nasty problems. Note, if we can't get the
+ * descriptor we run anyway, just more slowly.
+ */
+ if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0)
+ SET(FTS_NOCHDIR);
+
+ return (sp);
+
+mem3: fts_lfree(root);
+ free(parent);
+mem2: free(sp->fts_path);
+mem1: free(sp);
+ return (NULL);
+}
+
+static void
+fts_load(sp, p)
+ FTS *sp;
+ register FTSENT *p;
+{
+ register int len;
+ register char *cp;
+
+ /*
+ * Load the stream structure for the next traversal. Since we don't
+ * actually enter the directory until after the preorder visit, set
+ * the fts_accpath field specially so the chdir gets done to the right
+ * place and the user can access the first node. From fts_open it's
+ * known that the path will fit.
+ */
+ len = p->fts_pathlen = p->fts_namelen;
+ memmove(sp->fts_path, p->fts_name, len + 1);
+ if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
+ len = strlen(++cp);
+ memmove(p->fts_name, cp, len + 1);
+ p->fts_namelen = len;
+ }
+ p->fts_accpath = p->fts_path = sp->fts_path;
+ sp->fts_dev = p->fts_dev;
+}
+
+int
+fts_close(sp)
+ FTS *sp;
+{
+ register FTSENT *freep, *p;
+ int saved_errno;
+
+ /*
+ * This still works if we haven't read anything -- the dummy structure
+ * points to the root list, so we step through to the end of the root
+ * list which has a valid parent pointer.
+ */
+ if (sp->fts_cur) {
+ for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
+ freep = p;
+ p = p->fts_link ? p->fts_link : p->fts_parent;
+ free(freep);
+ }
+ free(p);
+ }
+
+ /* Free up child linked list, sort array, path buffer. */
+ if (sp->fts_child)
+ fts_lfree(sp->fts_child);
+ if (sp->fts_array)
+ free(sp->fts_array);
+ free(sp->fts_path);
+
+ /* Return to original directory, save errno if necessary. */
+ if (!ISSET(FTS_NOCHDIR)) {
+ saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
+ (void)close(sp->fts_rfd);
+
+ /* Set errno and return. */
+ if (saved_errno != 0) {
+ /* Free up the stream pointer. */
+ free(sp);
+ errno = saved_errno;
+ return (-1);
+ }
+ }
+
+ /* Free up the stream pointer. */
+ free(sp);
+ return (0);
+}
+
+/*
+ * Special case of "/" at the end of the path so that slashes aren't
+ * appended which would cause paths to be written as "....//foo".
+ */
+#define NAPPEND(p) \
+ (p->fts_path[p->fts_pathlen - 1] == '/' \
+ ? p->fts_pathlen - 1 : p->fts_pathlen)
+
+FTSENT *
+fts_read(sp)
+ register FTS *sp;
+{
+ register FTSENT *p, *tmp;
+ register int instr;
+ register char *t;
+ int saved_errno;
+
+ /* If finished or unrecoverable error, return NULL. */
+ if (sp->fts_cur == NULL || ISSET(FTS_STOP))
+ return (NULL);
+
+ /* Set current node pointer. */
+ p = sp->fts_cur;
+
+ /* Save and zero out user instructions. */
+ instr = p->fts_instr;
+ p->fts_instr = FTS_NOINSTR;
+
+ /* Any type of file may be re-visited; re-stat and re-turn. */
+ if (instr == FTS_AGAIN) {
+ p->fts_info = fts_stat(sp, p, 0);
+ return (p);
+ }
+
+ /*
+ * Following a symlink -- SLNONE test allows application to see
+ * SLNONE and recover. If indirecting through a symlink, have
+ * keep a pointer to current location. If unable to get that
+ * pointer, follow fails.
+ */
+ if (instr == FTS_FOLLOW &&
+ (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
+ p->fts_info = fts_stat(sp, p, 1);
+ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
+ if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) {
+ p->fts_errno = errno;
+ p->fts_info = FTS_ERR;
+ } else
+ p->fts_flags |= FTS_SYMFOLLOW;
+ }
+ return (p);
+ }
+
+ /* Directory in pre-order. */
+ if (p->fts_info == FTS_D) {
+ /* If skipped or crossed mount point, do post-order visit. */
+ if (instr == FTS_SKIP ||
+ (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
+ if (p->fts_flags & FTS_SYMFOLLOW)
+ (void)close(p->fts_symfd);
+ if (sp->fts_child) {
+ fts_lfree(sp->fts_child);
+ sp->fts_child = NULL;
+ }
+ p->fts_info = FTS_DP;
+ return (p);
+ }
+
+ /* Rebuild if only read the names and now traversing. */
+ if (sp->fts_child && ISSET(FTS_NAMEONLY)) {
+ CLR(FTS_NAMEONLY);
+ fts_lfree(sp->fts_child);
+ sp->fts_child = NULL;
+ }
+
+ /*
+ * Cd to the subdirectory.
+ *
+ * If have already read and now fail to chdir, whack the list
+ * to make the names come out right, and set the parent errno
+ * so the application will eventually get an error condition.
+ * Set the FTS_DONTCHDIR flag so that when we logically change
+ * directories back to the parent we don't do a chdir.
+ *
+ * If haven't read do so. If the read fails, fts_build sets
+ * FTS_STOP or the fts_info field of the node.
+ */
+ if (sp->fts_child) {
+ if (fts_safe_changedir(sp, p, -1)) {
+ p->fts_errno = errno;
+ p->fts_flags |= FTS_DONTCHDIR;
+ for (p = sp->fts_child; p; p = p->fts_link)
+ p->fts_accpath =
+ p->fts_parent->fts_accpath;
+ }
+ } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
+ if (ISSET(FTS_STOP))
+ return (NULL);
+ return (p);
+ }
+ p = sp->fts_child;
+ sp->fts_child = NULL;
+ goto name;
+ }
+
+ /* Move to the next node on this level. */
+next: tmp = p;
+ if ((p = p->fts_link)) {
+ free(tmp);
+
+ /*
+ * If reached the top, return to the original directory (or
+ * the root of the tree), and load the paths for the next root.
+ */
+ if (p->fts_level == FTS_ROOTLEVEL) {
+ if (FCHDIR(sp, sp->fts_rfd)) {
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ fts_load(sp, p);
+ return (sp->fts_cur = p);
+ }
+
+ /*
+ * User may have called fts_set on the node. If skipped,
+ * ignore. If followed, get a file descriptor so we can
+ * get back if necessary.
+ */
+ if (p->fts_instr == FTS_SKIP)
+ goto next;
+ if (p->fts_instr == FTS_FOLLOW) {
+ p->fts_info = fts_stat(sp, p, 1);
+ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
+ if ((p->fts_symfd =
+ open(".", O_RDONLY, 0)) < 0) {
+ p->fts_errno = errno;
+ p->fts_info = FTS_ERR;
+ } else
+ p->fts_flags |= FTS_SYMFOLLOW;
+ }
+ p->fts_instr = FTS_NOINSTR;
+ }
+
+name: t = sp->fts_path + NAPPEND(p->fts_parent);
+ *t++ = '/';
+ memmove(t, p->fts_name, p->fts_namelen + 1);
+ return (sp->fts_cur = p);
+ }
+
+ /* Move up to the parent node. */
+ p = tmp->fts_parent;
+ free(tmp);
+
+ if (p->fts_level == FTS_ROOTPARENTLEVEL) {
+ /*
+ * Done; free everything up and set errno to 0 so the user
+ * can distinguish between error and EOF.
+ */
+ free(p);
+ errno = 0;
+ return (sp->fts_cur = NULL);
+ }
+
+ /* NUL terminate the pathname. */
+ sp->fts_path[p->fts_pathlen] = '\0';
+
+ /*
+ * Return to the parent directory. If at a root node or came through
+ * a symlink, go back through the file descriptor. Otherwise, cd up
+ * one directory.
+ */
+ if (p->fts_level == FTS_ROOTLEVEL) {
+ if (FCHDIR(sp, sp->fts_rfd)) {
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ } else if (p->fts_flags & FTS_SYMFOLLOW) {
+ if (FCHDIR(sp, p->fts_symfd)) {
+ saved_errno = errno;
+ (void)close(p->fts_symfd);
+ errno = saved_errno;
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ (void)close(p->fts_symfd);
+ } else if (!(p->fts_flags & FTS_DONTCHDIR)) {
+ if (CHDIR(sp, "..")) {
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ }
+ p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
+ return (sp->fts_cur = p);
+}
+
+/*
+ * Fts_set takes the stream as an argument although it's not used in this
+ * implementation; it would be necessary if anyone wanted to add global
+ * semantics to fts using fts_set. An error return is allowed for similar
+ * reasons.
+ */
+/* ARGSUSED */
+int
+fts_set(sp, p, instr)
+ FTS *sp;
+ FTSENT *p;
+ int instr;
+{
+ if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
+ instr != FTS_NOINSTR && instr != FTS_SKIP) {
+ errno = EINVAL;
+ return (1);
+ }
+ p->fts_instr = instr;
+ return (0);
+}
+
+FTSENT *
+fts_children(sp, instr)
+ register FTS *sp;
+ int instr;
+{
+ register FTSENT *p;
+ int fd;
+
+ if (instr && instr != FTS_NAMEONLY) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /* Set current node pointer. */
+ p = sp->fts_cur;
+
+ /*
+ * Errno set to 0 so user can distinguish empty directory from
+ * an error.
+ */
+ errno = 0;
+
+ /* Fatal errors stop here. */
+ if (ISSET(FTS_STOP))
+ return (NULL);
+
+ /* Return logical hierarchy of user's arguments. */
+ if (p->fts_info == FTS_INIT)
+ return (p->fts_link);
+
+ /*
+ * If not a directory being visited in pre-order, stop here. Could
+ * allow FTS_DNR, assuming the user has fixed the problem, but the
+ * same effect is available with FTS_AGAIN.
+ */
+ if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
+ return (NULL);
+
+ /* Free up any previous child list. */
+ if (sp->fts_child)
+ fts_lfree(sp->fts_child);
+
+ if (instr == FTS_NAMEONLY) {
+ SET(FTS_NAMEONLY);
+ instr = BNAMES;
+ } else
+ instr = BCHILD;
+
+ /*
+ * If using chdir on a relative path and called BEFORE fts_read does
+ * its chdir to the root of a traversal, we can lose -- we need to
+ * chdir into the subdirectory, and we don't know where the current
+ * directory is, so we can't get back so that the upcoming chdir by
+ * fts_read will work.
+ */
+ if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
+ ISSET(FTS_NOCHDIR))
+ return (sp->fts_child = fts_build(sp, instr));
+
+ if ((fd = open(".", O_RDONLY, 0)) < 0)
+ return (NULL);
+ sp->fts_child = fts_build(sp, instr);
+ if (fchdir(fd))
+ return (NULL);
+ (void)close(fd);
+ return (sp->fts_child);
+}
+
+/*
+ * This is the tricky part -- do not casually change *anything* in here. The
+ * idea is to build the linked list of entries that are used by fts_children
+ * and fts_read. There are lots of special cases.
+ *
+ * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
+ * set and it's a physical walk (so that symbolic links can't be directories),
+ * we can do things quickly. First, if it's a 4.4BSD file system, the type
+ * of the file is in the directory entry. Otherwise, we assume that the number
+ * of subdirectories in a node is equal to the number of links to the parent.
+ * The former skips all stat calls. The latter skips stat calls in any leaf
+ * directories and for any files after the subdirectories in the directory have
+ * been found, cutting the stat calls by about 2/3.
+ */
+static FTSENT *
+fts_build(sp, type)
+ register FTS *sp;
+ int type;
+{
+ register struct dirent *dp;
+ register FTSENT *p, *head;
+ register int nitems;
+ FTSENT *cur, *tail;
+ DIR *dirp;
+ void *oldaddr;
+ int cderrno, descend, len, level, maxlen, nlinks, oflag, saved_errno,
+ nostat, doadjust;
+ char *cp;
+
+ /* Set current node pointer. */
+ cur = sp->fts_cur;
+
+ /*
+ * Open the directory for reading. If this fails, we're done.
+ * If being called from fts_read, set the fts_info field.
+ */
+#ifdef FTS_WHITEOUT
+ if (ISSET(FTS_WHITEOUT))
+ oflag = DTF_NODUP|DTF_REWIND;
+ else
+ oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
+#else
+#define __opendir2(path, flag) opendir(path)
+#endif
+ if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
+ if (type == BREAD) {
+ cur->fts_info = FTS_DNR;
+ cur->fts_errno = errno;
+ }
+ return (NULL);
+ }
+
+ /*
+ * Nlinks is the number of possible entries of type directory in the
+ * directory if we're cheating on stat calls, 0 if we're not doing
+ * any stat calls at all, -1 if we're doing stats on everything.
+ */
+ if (type == BNAMES) {
+ nlinks = 0;
+ /* Be quiet about nostat, GCC. */
+ nostat = 0;
+ } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
+ nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
+ nostat = 1;
+ } else {
+ nlinks = -1;
+ nostat = 0;
+ }
+
+#ifdef notdef
+ (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink);
+ (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n",
+ ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT));
+#endif
+ /*
+ * If we're going to need to stat anything or we want to descend
+ * and stay in the directory, chdir. If this fails we keep going,
+ * but set a flag so we don't chdir after the post-order visit.
+ * We won't be able to stat anything, but we can still return the
+ * names themselves. Note, that since fts_read won't be able to
+ * chdir into the directory, it will have to return different path
+ * names than before, i.e. "a/b" instead of "b". Since the node
+ * has already been visited in pre-order, have to wait until the
+ * post-order visit to return the error. There is a special case
+ * here, if there was nothing to stat then it's not an error to
+ * not be able to stat. This is all fairly nasty. If a program
+ * needed sorted entries or stat information, they had better be
+ * checking FTS_NS on the returned nodes.
+ */
+ cderrno = 0;
+ if (nlinks || type == BREAD) {
+ if (fts_safe_changedir(sp, cur, dirfd(dirp))) {
+ if (nlinks && type == BREAD)
+ cur->fts_errno = errno;
+ cur->fts_flags |= FTS_DONTCHDIR;
+ descend = 0;
+ cderrno = errno;
+ (void)closedir(dirp);
+ dirp = NULL;
+ } else
+ descend = 1;
+ } else
+ descend = 0;
+
+ /*
+ * Figure out the max file name length that can be stored in the
+ * current path -- the inner loop allocates more path as necessary.
+ * We really wouldn't have to do the maxlen calculations here, we
+ * could do them in fts_read before returning the path, but it's a
+ * lot easier here since the length is part of the dirent structure.
+ *
+ * If not changing directories set a pointer so that can just append
+ * each new name into the path.
+ */
+ len = NAPPEND(cur);
+ if (ISSET(FTS_NOCHDIR)) {
+ cp = sp->fts_path + len;
+ *cp++ = '/';
+ } else {
+ /* GCC, you're too verbose. */
+ cp = NULL;
+ }
+ len++;
+ maxlen = sp->fts_pathlen - len;
+
+ level = cur->fts_level + 1;
+
+ /* Read the directory, attaching each entry to the `link' pointer. */
+ doadjust = 0;
+ for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
+ if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
+ continue;
+
+ if ((p = fts_alloc(sp, dp->d_name, (int)dp->d_namlen)) == NULL)
+ goto mem1;
+ if (dp->d_namlen >= maxlen) { /* include space for NUL */
+ oldaddr = sp->fts_path;
+ if (fts_palloc(sp, dp->d_namlen +len + 1)) {
+ /*
+ * No more memory for path or structures. Save
+ * errno, free up the current structure and the
+ * structures already allocated.
+ */
+mem1: saved_errno = errno;
+ if (p)
+ free(p);
+ fts_lfree(head);
+ (void)closedir(dirp);
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ errno = saved_errno;
+ return (NULL);
+ }
+ /* Did realloc() change the pointer? */
+ if (oldaddr != sp->fts_path) {
+ doadjust = 1;
+ if (ISSET(FTS_NOCHDIR))
+ cp = sp->fts_path + len;
+ }
+ maxlen = sp->fts_pathlen - len;
+ }
+
+ if (len + dp->d_namlen >= USHRT_MAX) {
+ /*
+ * In an FTSENT, fts_pathlen is a u_short so it is
+ * possible to wraparound here. If we do, free up
+ * the current structure and the structures already
+ * allocated, then error out with ENAMETOOLONG.
+ */
+ free(p);
+ fts_lfree(head);
+ (void)closedir(dirp);
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ p->fts_level = level;
+ p->fts_parent = sp->fts_cur;
+ p->fts_pathlen = len + dp->d_namlen;
+
+#ifdef FTS_WHITEOUT
+ if (dp->d_type == DT_WHT)
+ p->fts_flags |= FTS_ISW;
+#endif
+
+ if (cderrno) {
+ if (nlinks) {
+ p->fts_info = FTS_NS;
+ p->fts_errno = cderrno;
+ } else
+ p->fts_info = FTS_NSOK;
+ p->fts_accpath = cur->fts_accpath;
+ } else if (nlinks == 0
+#ifdef DT_DIR
+ || (nostat &&
+ dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
+#endif
+ ) {
+ p->fts_accpath =
+ ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
+ p->fts_info = FTS_NSOK;
+ } else {
+ /* Build a file name for fts_stat to stat. */
+ if (ISSET(FTS_NOCHDIR)) {
+ p->fts_accpath = p->fts_path;
+ memmove(cp, p->fts_name, p->fts_namelen + 1);
+ } else
+ p->fts_accpath = p->fts_name;
+ /* Stat it. */
+ p->fts_info = fts_stat(sp, p, 0);
+
+ /* Decrement link count if applicable. */
+ if (nlinks > 0 && (p->fts_info == FTS_D ||
+ p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
+ --nlinks;
+ }
+
+ /* We walk in directory order so "ls -f" doesn't get upset. */
+ p->fts_link = NULL;
+ if (head == NULL)
+ head = tail = p;
+ else {
+ tail->fts_link = p;
+ tail = p;
+ }
+ ++nitems;
+ }
+ if (dirp)
+ (void)closedir(dirp);
+
+ /*
+ * If realloc() changed the address of the path, adjust the
+ * addresses for the rest of the tree and the dir list.
+ */
+ if (doadjust)
+ fts_padjust(sp, head);
+
+ /*
+ * If not changing directories, reset the path back to original
+ * state.
+ */
+ if (ISSET(FTS_NOCHDIR)) {
+ if (len == sp->fts_pathlen || nitems == 0)
+ --cp;
+ *cp = '\0';
+ }
+
+ /*
+ * If descended after called from fts_children or after called from
+ * fts_read and nothing found, get back. At the root level we use
+ * the saved fd; if one of fts_open()'s arguments is a relative path
+ * to an empty directory, we wind up here with no other way back. If
+ * can't get back, we're done.
+ */
+ if (descend && (type == BCHILD || !nitems) &&
+ (cur->fts_level == FTS_ROOTLEVEL ?
+ FCHDIR(sp, sp->fts_rfd) : CHDIR(sp, ".."))) {
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ return (NULL);
+ }
+
+ /* If didn't find anything, return NULL. */
+ if (!nitems) {
+ if (type == BREAD)
+ cur->fts_info = FTS_DP;
+ return (NULL);
+ }
+
+ /* Sort the entries. */
+ if (sp->fts_compar && nitems > 1)
+ head = fts_sort(sp, head, nitems);
+ return (head);
+}
+
+static u_short
+fts_stat(sp, p, follow)
+ FTS *sp;
+ register FTSENT *p;
+ int follow;
+{
+ register FTSENT *t;
+ register dev_t dev;
+ register ino_t ino;
+ struct stat *sbp, sb;
+ int saved_errno;
+
+ /* If user needs stat info, stat buffer already allocated. */
+ sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
+
+#ifdef FTS_WHITEOUT
+ /* check for whiteout */
+ if (p->fts_flags & FTS_ISW) {
+ if (sbp != &sb) {
+ memset(sbp, '\0', sizeof (*sbp));
+ sbp->st_mode = S_IFWHT;
+ }
+ return (FTS_W);
+ }
+#endif
+
+ /*
+ * If doing a logical walk, or application requested FTS_FOLLOW, do
+ * a stat(2). If that fails, check for a non-existent symlink. If
+ * fail, set the errno from the stat call.
+ */
+ if (ISSET(FTS_LOGICAL) || follow) {
+ if (stat(p->fts_accpath, sbp)) {
+ saved_errno = errno;
+ if (!lstat(p->fts_accpath, sbp)) {
+ errno = 0;
+ return (FTS_SLNONE);
+ }
+ p->fts_errno = saved_errno;
+ goto err;
+ }
+ } else if (lstat(p->fts_accpath, sbp)) {
+ p->fts_errno = errno;
+err: memset(sbp, 0, sizeof(struct stat));
+ return (FTS_NS);
+ }
+
+ if (S_ISDIR(sbp->st_mode)) {
+ /*
+ * Set the device/inode. Used to find cycles and check for
+ * crossing mount points. Also remember the link count, used
+ * in fts_build to limit the number of stat calls. It is
+ * understood that these fields are only referenced if fts_info
+ * is set to FTS_D.
+ */
+ dev = p->fts_dev = sbp->st_dev;
+ ino = p->fts_ino = sbp->st_ino;
+ p->fts_nlink = sbp->st_nlink;
+
+ if (ISDOT(p->fts_name))
+ return (FTS_DOT);
+
+ /*
+ * Cycle detection is done by brute force when the directory
+ * is first encountered. If the tree gets deep enough or the
+ * number of symbolic links to directories is high enough,
+ * something faster might be worthwhile.
+ */
+ for (t = p->fts_parent;
+ t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
+ if (ino == t->fts_ino && dev == t->fts_dev) {
+ p->fts_cycle = t;
+ return (FTS_DC);
+ }
+ return (FTS_D);
+ }
+ if (S_ISLNK(sbp->st_mode))
+ return (FTS_SL);
+ if (S_ISREG(sbp->st_mode))
+ return (FTS_F);
+ return (FTS_DEFAULT);
+}
+
+static FTSENT *
+fts_sort(sp, head, nitems)
+ FTS *sp;
+ FTSENT *head;
+ register int nitems;
+{
+ register FTSENT **ap, *p;
+
+ /*
+ * Construct an array of pointers to the structures and call qsort(3).
+ * Reassemble the array in the order returned by qsort. If unable to
+ * sort for memory reasons, return the directory entries in their
+ * current order. Allocate enough space for the current needs plus
+ * 40 so don't realloc one entry at a time.
+ */
+ if (nitems > sp->fts_nitems) {
+ struct _ftsent **a;
+
+ sp->fts_nitems = nitems + 40;
+ if ((a = realloc(sp->fts_array,
+ sp->fts_nitems * sizeof(FTSENT *))) == NULL) {
+ if (sp->fts_array)
+ free(sp->fts_array);
+ sp->fts_array = NULL;
+ sp->fts_nitems = 0;
+ return (head);
+ }
+ sp->fts_array = a;
+ }
+ for (ap = sp->fts_array, p = head; p; p = p->fts_link)
+ *ap++ = p;
+ qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
+ for (head = *(ap = sp->fts_array); --nitems; ++ap)
+ ap[0]->fts_link = ap[1];
+ ap[0]->fts_link = NULL;
+ return (head);
+}
+
+static FTSENT *
+fts_alloc(sp, name, namelen)
+ FTS *sp;
+ char *name;
+ register int namelen;
+{
+ register FTSENT *p;
+ size_t len;
+
+ /*
+ * The file name is a variable length array and no stat structure is
+ * necessary if the user has set the nostat bit. Allocate the FTSENT
+ * structure, the file name and the stat structure in one chunk, but
+ * be careful that the stat structure is reasonably aligned. Since the
+ * fts_name field is declared to be of size 1, the fts_name pointer is
+ * namelen + 2 before the first possible address of the stat structure.
+ */
+ len = sizeof(FTSENT) + namelen;
+ if (!ISSET(FTS_NOSTAT))
+ len += sizeof(struct stat) + ALIGNBYTES;
+ if ((p = malloc(len)) == NULL)
+ return (NULL);
+
+ /* Copy the name and guarantee NUL termination. */
+ memmove(p->fts_name, name, namelen);
+ p->fts_name[namelen] = '\0';
+
+ if (!ISSET(FTS_NOSTAT))
+ p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2);
+ p->fts_namelen = namelen;
+ p->fts_path = sp->fts_path;
+ p->fts_errno = 0;
+ p->fts_flags = 0;
+ p->fts_instr = FTS_NOINSTR;
+ p->fts_number = 0;
+ p->fts_pointer = NULL;
+ return (p);
+}
+
+static void
+fts_lfree(head)
+ register FTSENT *head;
+{
+ register FTSENT *p;
+
+ /* Free a linked list of structures. */
+ while ((p = head)) {
+ head = head->fts_link;
+ free(p);
+ }
+}
+
+/*
+ * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
+ * Most systems will allow creation of paths much longer than MAXPATHLEN, even
+ * though the kernel won't resolve them. Add the size (not just what's needed)
+ * plus 256 bytes so don't realloc the path 2 bytes at a time.
+ */
+static int
+fts_palloc(sp, more)
+ FTS *sp;
+ size_t more;
+{
+ char *p;
+
+ sp->fts_pathlen += more + 256;
+ /*
+ * Check for possible wraparound. In an FTS, fts_pathlen is
+ * a signed int but in an FTSENT it is an unsigned short.
+ * We limit fts_pathlen to USHRT_MAX to be safe in both cases.
+ */
+ if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) {
+ if (sp->fts_path)
+ free(sp->fts_path);
+ sp->fts_path = NULL;
+ errno = ENAMETOOLONG;
+ return (1);
+ }
+ p = realloc(sp->fts_path, sp->fts_pathlen);
+ if (p == NULL) {
+ if (sp->fts_path)
+ free(sp->fts_path);
+ sp->fts_path = NULL;
+ return (1);
+ }
+ sp->fts_path = p;
+ return (0);
+}
+
+/*
+ * When the path is realloc'd, have to fix all of the pointers in structures
+ * already returned.
+ */
+static void
+fts_padjust(sp, head)
+ FTS *sp;
+ FTSENT *head;
+{
+ FTSENT *p;
+ char *addr = sp->fts_path;
+
+#define ADJUST(p) { \
+ if ((p)->fts_accpath != (p)->fts_name) { \
+ (p)->fts_accpath = \
+ (char *)addr + ((p)->fts_accpath - (p)->fts_path); \
+ } \
+ (p)->fts_path = addr; \
+}
+ /* Adjust the current set of children. */
+ for (p = sp->fts_child; p; p = p->fts_link)
+ ADJUST(p);
+
+ /* Adjust the rest of the tree, including the current level. */
+ for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
+ ADJUST(p);
+ p = p->fts_link ? p->fts_link : p->fts_parent;
+ }
+}
+
+static size_t
+fts_maxarglen(argv)
+ char * const *argv;
+{
+ size_t len, max;
+
+ for (max = 0; *argv; ++argv)
+ if ((len = strlen(*argv)) > max)
+ max = len;
+ return (max + 1);
+}
+
+/*
+ * Change to dir specified by fd or p->fts_accpath without getting
+ * tricked by someone changing the world out from underneath us.
+ * Assumes p->fts_dev and p->fts_ino are filled in.
+ */
+static int
+fts_safe_changedir(sp, p, fd)
+ FTS *sp;
+ FTSENT *p;
+ int fd;
+{
+ int ret, oerrno, newfd;
+ struct stat sb;
+
+ newfd = fd;
+ if (ISSET(FTS_NOCHDIR))
+ return (0);
+ if (fd < 0 && (newfd = open(p->fts_accpath, O_RDONLY, 0)) < 0)
+ return (-1);
+ if (fstat(newfd, &sb)) {
+ ret = -1;
+ goto bail;
+ }
+ if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {
+ errno = ENOENT; /* disinformation */
+ ret = -1;
+ goto bail;
+ }
+ ret = fchdir(newfd);
+bail:
+ oerrno = errno;
+ if (fd < 0)
+ (void)close(newfd);
+ errno = oerrno;
+ return (ret);
+}
diff --git a/lib/libc/gen/getbootfile.3 b/lib/libc/gen/getbootfile.3
new file mode 100644
index 0000000..1ad2b8e
--- /dev/null
+++ b/lib/libc/gen/getbootfile.3
@@ -0,0 +1,70 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)gethostname.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd September 23, 1994
+.Dt GETBOOTFILE 3
+.Os
+.Sh NAME
+.Nm getbootfile
+.Nd get kernel boot file name
+.Sh SYNOPSIS
+.Fd #include <paths.h>
+.Ft const char *
+.Fn getbootfile void
+.Sh DESCRIPTION
+The
+.Fn getbootfile
+function retrieves the full pathname of the file from which the
+current kernel was loaded, and returns a static pointer to the name.
+A read/write interface to this information is available via the
+.Xr sysctl 3
+MIB variable
+.Dq Li kern.bootfile .
+.Sh RETURN VALUES
+If the call succeeds a string giving the pathname is returned. If it
+fails, a a null pointer is returned and an error code is
+placed in the global location
+.Va errno .
+.Sh SEE ALSO
+.Xr sysctl 3
+.Sh BUGS
+If the boot blocks have not been modified to pass this information into
+the kernel at boot time, the static string
+.Dq Pa /kernel
+is returned instead of the real boot file.
+.Sh HISTORY
+The
+.Fn getbootfile
+function call appeared in
+.Fx 2.0 .
diff --git a/lib/libc/gen/getbootfile.c b/lib/libc/gen/getbootfile.c
new file mode 100644
index 0000000..c2d1558
--- /dev/null
+++ b/lib/libc/gen/getbootfile.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char sccsid[] = "From: @(#)gethostname.c 8.1 (Berkeley) 6/4/93";*/
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+const char *
+getbootfile(void)
+{
+ static char name[MAXPATHLEN];
+ size_t size = sizeof name;
+ int mib[2];
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_BOOTFILE;
+ if (sysctl(mib, 2, name, &size, NULL, 0) == -1)
+ return ("/kernel");
+ return (name);
+}
diff --git a/lib/libc/gen/getbsize.3 b/lib/libc/gen/getbsize.3
new file mode 100644
index 0000000..00b09c6
--- /dev/null
+++ b/lib/libc/gen/getbsize.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getbsize.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETBSIZE 3
+.Os BSD 4.4
+.Sh NAME
+.Nm getbsize
+.Nd get user block size
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft char *
+.Fn getbsize "int *headerlenp" "long *blocksizep"
+.Sh DESCRIPTION
+The
+.Fn getbsize
+function determines the user's preferred block size based on the value of the
+.Dq BLOCKSIZE
+environment variable; see
+.Xr environ 7
+for details on its use and format.
+.Pp
+The
+.Fn getbsize
+function returns a pointer to a null-terminated string describing
+the block size, something like
+.Dq 1K-blocks .
+The memory referenced by
+.Fa headerlenp
+is filled in with the length of the string (not including the
+terminating null).
+The memory referenced by
+.Fa blocksizep
+is filled in with block size, in bytes.
+.Pp
+If the user's block size is unreasonable, a warning message is
+written to standard error and the returned information reflects
+a block size of 512 bytes.
+.Sh SEE ALSO
+.Xr df 1 ,
+.Xr du 1 ,
+.Xr ls 1 ,
+.Xr systat 1 ,
+.Xr environ 7
+.Sh HISTORY
+The
+.Fn getbsize
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/gen/getbsize.c b/lib/libc/gen/getbsize.c
new file mode 100644
index 0000000..6f951e7
--- /dev/null
+++ b/lib/libc/gen/getbsize.c
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)getbsize.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *
+getbsize(headerlenp, blocksizep)
+ int *headerlenp;
+ long *blocksizep;
+{
+ static char header[20];
+ long n, max, mul, blocksize;
+ char *ep, *p, *form;
+
+#define KB (1024L)
+#define MB (1024L * 1024L)
+#define GB (1024L * 1024L * 1024L)
+#define MAXB GB /* No tera, peta, nor exa. */
+ form = "";
+ if ((p = getenv("BLOCKSIZE")) != NULL && *p != '\0') {
+ if ((n = strtol(p, &ep, 10)) < 0)
+ goto underflow;
+ if (n == 0)
+ n = 1;
+ if (*ep && ep[1])
+ goto fmterr;
+ switch (*ep) {
+ case 'G': case 'g':
+ form = "G";
+ max = MAXB / GB;
+ mul = GB;
+ break;
+ case 'K': case 'k':
+ form = "K";
+ max = MAXB / KB;
+ mul = KB;
+ break;
+ case 'M': case 'm':
+ form = "M";
+ max = MAXB / MB;
+ mul = MB;
+ break;
+ case '\0':
+ max = MAXB;
+ mul = 1;
+ break;
+ default:
+fmterr: warnx("%s: unknown blocksize", p);
+ n = 512;
+ mul = 1;
+ break;
+ }
+ if (n > max) {
+ warnx("maximum blocksize is %ldG", MAXB / GB);
+ n = max;
+ }
+ if ((blocksize = n * mul) < 512) {
+underflow: warnx("minimum blocksize is 512");
+ form = "";
+ blocksize = n = 512;
+ }
+ } else
+ blocksize = n = 512;
+
+ (void)snprintf(header, sizeof(header), "%ld%s-blocks", n, form);
+ *headerlenp = strlen(header);
+ *blocksizep = blocksize;
+ return (header);
+}
diff --git a/lib/libc/gen/getcap.3 b/lib/libc/gen/getcap.3
new file mode 100644
index 0000000..0e6a3da
--- /dev/null
+++ b/lib/libc/gen/getcap.3
@@ -0,0 +1,529 @@
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Casey Leedom of Lawrence Livermore National Laboratory.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getcap.3 8.4 (Berkeley) 5/13/94
+.\" $FreeBSD$
+.\"
+.Dd May 13, 1994
+.Dt GETCAP 3
+.Os
+.Sh NAME
+.Nm cgetent ,
+.Nm cgetset ,
+.Nm cgetmatch ,
+.Nm cgetcap ,
+.Nm cgetnum ,
+.Nm cgetstr ,
+.Nm cgetustr ,
+.Nm cgetfirst ,
+.Nm cgetnext ,
+.Nm cgetclose
+.Nd capability database access routines
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft int
+.Fn cgetent "char **buf" "char **db_array" "char *name"
+.Ft int
+.Fn cgetset "char *ent"
+.Ft int
+.Fn cgetmatch "char *buf" "char *name"
+.Ft char *
+.Fn cgetcap "char *buf" "char *cap" "int type"
+.Ft int
+.Fn cgetnum "char *buf" "char *cap" "long *num"
+.Ft int
+.Fn cgetstr "char *buf" "char *cap" "char **str"
+.Ft int
+.Fn cgetustr "char *buf" "char *cap" "char **str"
+.Ft int
+.Fn cgetfirst "char **buf" "char **db_array"
+.Ft int
+.Fn cgetnext "char **buf" "char **db_array"
+.Ft int
+.Fn cgetclose "void"
+.Sh DESCRIPTION
+.Fn Cgetent
+extracts the capability
+.Fa name
+from the database specified by the
+.Dv NULL
+terminated file array
+.Fa db_array
+and returns a pointer to a
+.Xr malloc Ns \&'d
+copy of it in
+.Fa buf .
+The
+.Fn cgetent
+function will first look for files ending in
+.Nm .db
+(see
+.Xr cap_mkdb 1)
+before accessing the ASCII file.
+.Fa Buf
+must be retained through all subsequent calls to
+.Fn cgetmatch ,
+.Fn cgetcap ,
+.Fn cgetnum ,
+.Fn cgetstr ,
+and
+.Fn cgetustr ,
+but may then be
+.Xr free 3 Ns \&'d.
+On success 0 is returned, 1 if the returned
+record contains an unresolved
+.Nm tc
+expansion,
+\-1 if the requested record couldn't be found,
+\-2 if a system error was encountered (couldn't open/read a file, etc.) also
+setting
+.Va errno ,
+and \-3 if a potential reference loop is detected (see
+.Ic tc=
+comments below).
+.Pp
+The
+.Fn cgetset
+function enables the addition of a character buffer containing a single capability
+record entry
+to the capability database.
+Conceptually, the entry is added as the first ``file'' in the database, and
+is therefore searched first on the call to
+.Fn cgetent .
+The entry is passed in
+.Fa ent .
+If
+.Fa ent
+is
+.Dv NULL ,
+the current entry is removed from the database.
+A call to
+.Fn cgetset
+must precede the database traversal. It must be called before the
+.Fn cgetent
+call. If a sequential access is being performed (see below), it must be called
+before the first sequential access call (
+.Fn cgetfirst
+or
+.Fn cgetnext
+), or be directly preceded by a
+.Fn cgetclose
+call.
+On success 0 is returned and \-1 on failure.
+.Pp
+The
+.Fn cgetmatch
+function will return 0 if
+.Fa name
+is one of the names of the capability record
+.Fa buf ,
+\-1 if
+not.
+.Pp
+The
+.Fn cgetcap
+function searches the capability record
+.Fa buf
+for the capability
+.Fa cap
+with type
+.Fa type .
+A
+.Fa type
+is specified using any single character. If a colon (`:') is used, an
+untyped capability will be searched for (see below for explanation of
+types). A pointer to the value of
+.Fa cap
+in
+.Fa buf
+is returned on success,
+.Dv NULL
+if the requested capability couldn't be
+found. The end of the capability value is signaled by a `:' or
+.Tn ASCII
+.Dv NUL
+(see below for capability database syntax).
+.Pp
+The
+.Fn cgetnum
+function retrieves the value of the numeric capability
+.Fa cap
+from the capability record pointed to by
+.Fa buf .
+The numeric value is returned in the
+.Ft long
+pointed to by
+.Fa num .
+0 is returned on success, \-1 if the requested numeric capability couldn't
+be found.
+.Pp
+The
+.Fn cgetstr
+function retrieves the value of the string capability
+.Fa cap
+from the capability record pointed to by
+.Fa buf .
+A pointer to a decoded,
+.Dv NUL
+terminated,
+.Xr malloc Ns \&'d
+copy of the string is returned in the
+.Ft char *
+pointed to by
+.Fa str .
+The number of characters in the decoded string not including the trailing
+.Dv NUL
+is returned on success, \-1 if the requested string capability couldn't
+be found, \-2 if a system error was encountered (storage allocation
+failure).
+.Pp
+The
+.Fn cgetustr
+function is identical to
+.Fn cgetstr
+except that it does not expand special characters, but rather returns each
+character of the capability string literally.
+.Pp
+The
+.Fn cgetfirst
+and
+.Fn cgetnext
+functions comprise a function group that provides for sequential
+access of the
+.Dv NULL
+pointer terminated array of file names,
+.Fa db_array .
+The
+.Fn cgetfirst
+function returns the first record in the database and resets the access
+to the first record.
+The
+.Fn cgetnext
+function returns the next record in the database with respect to the
+record returned by the previous
+.Fn cgetfirst
+or
+.Fn cgetnext
+call. If there is no such previous call, the first record in the database is
+returned.
+Each record is returned in a
+.Xr malloc Ns \&'d
+copy pointed to by
+.Fa buf .
+.Ic Tc
+expansion is done (see
+.Ic tc=
+comments below).
+Upon completion of the database 0 is returned, 1 is returned upon successful
+return of record with possibly more remaining (we haven't reached the end of
+the database yet), 2 is returned if the record contains an unresolved
+.Nm tc
+expansion, \-1 is returned if an system error occurred, and \-2
+is returned if a potential reference loop is detected (see
+.Ic tc=
+comments below).
+Upon completion of database (0 return) the database is closed.
+.Pp
+The
+.Fn cgetclose
+function closes the sequential access and frees any memory and file descriptors
+being used. Note that it does not erase the buffer pushed by a call to
+.Fn cgetset .
+.Sh CAPABILITY DATABASE SYNTAX
+Capability databases are normally
+.Tn ASCII
+and may be edited with standard
+text editors. Blank lines and lines beginning with a `#' are comments
+and are ignored. Lines ending with a `\|\e' indicate that the next line
+is a continuation of the current line; the `\|\e' and following newline
+are ignored. Long lines are usually continued onto several physical
+lines by ending each line except the last with a `\|\e'.
+.Pp
+Capability databases consist of a series of records, one per logical
+line. Each record contains a variable number of `:'-separated fields
+(capabilities). Empty fields consisting entirely of white space
+characters (spaces and tabs) are ignored.
+.Pp
+The first capability of each record specifies its names, separated by `|'
+characters. These names are used to reference records in the database.
+By convention, the last name is usually a comment and is not intended as
+a lookup tag. For example, the
+.Em vt100
+record from the
+.Nm termcap
+database begins:
+.Pp
+.Dl "d0\||\|vt100\||\|vt100-am\||\|vt100am\||\|dec vt100:"
+.Pp
+giving four names that can be used to access the record.
+.Pp
+The remaining non-empty capabilities describe a set of (name, value)
+bindings, consisting of a names optionally followed by a typed values:
+.Bl -column "nameTvalue"
+.It name Ta "typeless [boolean] capability"
+.Em name No "is present [true]"
+.It name Ns Em \&T Ns value Ta capability
+.Pq Em name , \&T
+has value
+.Em value
+.It name@ Ta "no capability" Em name No exists
+.It name Ns Em T Ns \&@ Ta capability
+.Pq Em name , T
+does not exist
+.El
+.Pp
+Names consist of one or more characters. Names may contain any character
+except `:', but it's usually best to restrict them to the printable
+characters and avoid use of graphics like `#', `=', `%', `@', etc. Types
+are single characters used to separate capability names from their
+associated typed values. Types may be any character except a `:'.
+Typically, graphics like `#', `=', `%', etc. are used. Values may be any
+number of characters and may contain any character except `:'.
+.Sh CAPABILITY DATABASE SEMANTICS
+Capability records describe a set of (name, value) bindings. Names may
+have multiple values bound to them. Different values for a name are
+distinguished by their
+.Fa types .
+The
+.Fn cgetcap
+function will return a pointer to a value of a name given the capability
+name and the type of the value.
+.Pp
+The types `#' and `=' are conventionally used to denote numeric and
+string typed values, but no restriction on those types is enforced. The
+functions
+.Fn cgetnum
+and
+.Fn cgetstr
+can be used to implement the traditional syntax and semantics of `#'
+and `='.
+Typeless capabilities are typically used to denote boolean objects with
+presence or absence indicating truth and false values respectively.
+This interpretation is conveniently represented by:
+.Pp
+.Dl "(getcap(buf, name, ':') != NULL)"
+.Pp
+A special capability,
+.Ic tc= name ,
+is used to indicate that the record specified by
+.Fa name
+should be substituted for the
+.Ic tc
+capability.
+.Ic Tc
+capabilities may interpolate records which also contain
+.Ic tc
+capabilities and more than one
+.Ic tc
+capability may be used in a record. A
+.Ic tc
+expansion scope (i.e., where the argument is searched for) contains the
+file in which the
+.Ic tc
+is declared and all subsequent files in the file array.
+.Pp
+When a database is searched for a capability record, the first matching
+record in the search is returned. When a record is scanned for a
+capability, the first matching capability is returned; the capability
+.Ic :nameT@:
+will hide any following definition of a value of type
+.Em T
+for
+.Fa name ;
+and the capability
+.Ic :name@:
+will prevent any following values of
+.Fa name
+from being seen.
+.Pp
+These features combined with
+.Ic tc
+capabilities can be used to generate variations of other databases and
+records by either adding new capabilities, overriding definitions with new
+definitions, or hiding following definitions via `@' capabilities.
+.Sh EXAMPLES
+.Bd -unfilled -offset indent
+example\||\|an example of binding multiple values to names:\e
+ :foo%bar:foo^blah:foo@:\e
+ :abc%xyz:abc^frap:abc$@:\e
+ :tc=more:
+.Ed
+.Pp
+The capability foo has two values bound to it (bar of type `%' and blah of
+type `^') and any other value bindings are hidden. The capability abc
+also has two values bound but only a value of type `$' is prevented from
+being defined in the capability record more.
+.Pp
+.Bd -unfilled -offset indent
+file1:
+ new\||\|new_record\||\|a modification of "old":\e
+ :fript=bar:who-cares@:tc=old:blah:tc=extensions:
+file2:
+ old\||\|old_record\||\|an old database record:\e
+ :fript=foo:who-cares:glork#200:
+.Ed
+.Pp
+The records are extracted by calling
+.Fn cgetent
+with file1 preceding file2.
+In the capability record new in file1, fript=bar overrides the definition
+of fript=foo interpolated from the capability record old in file2,
+who-cares@ prevents the definition of any who-cares definitions in old
+from being seen, glork#200 is inherited from old, and blah and anything
+defined by the record extensions is added to those definitions in old.
+Note that the position of the fript=bar and who-cares@ definitions before
+tc=old is important here. If they were after, the definitions in old
+would take precedence.
+.Sh CGETNUM AND CGETSTR SYNTAX AND SEMANTICS
+Two types are predefined by
+.Fn cgetnum
+and
+.Fn cgetstr :
+.Bl -column "nameXnumber"
+.Sm off
+.It Em name No \&# Em number Ta numeric
+capability
+.Em name
+has value
+.Em number
+.It Em name No = Em string Ta "string capability"
+.Em name
+has value
+.Em string
+.It Em name No \&#@ Ta "the numeric capability"
+.Em name
+does not exist
+.It Em name No \&=@ Ta "the string capability"
+.Em name
+does not exist
+.El
+.Pp
+Numeric capability values may be given in one of three numeric bases.
+If the number starts with either
+.Ql 0x
+or
+.Ql 0X
+it is interpreted as a hexadecimal number (both upper and lower case a-f
+may be used to denote the extended hexadecimal digits).
+Otherwise, if the number starts with a
+.Ql 0
+it is interpreted as an octal number.
+Otherwise the number is interpreted as a decimal number.
+.Pp
+String capability values may contain any character. Non-printable
+.Dv ASCII
+codes, new lines, and colons may be conveniently represented by the use
+of escape sequences:
+.Bl -column "\e\|X,X\e\|X" "(ASCII octal nnn)"
+^X ('X' & 037) control-X
+\e\|b, \e\|B (ASCII 010) backspace
+\e\|t, \e\|T (ASCII 011) tab
+\e\|n, \e\|N (ASCII 012) line feed (newline)
+\e\|f, \e\|F (ASCII 014) form feed
+\e\|r, \e\|R (ASCII 015) carriage return
+\e\|e, \e\|E (ASCII 027) escape
+\e\|c, \e\|C (:) colon
+\e\|\e (\e\|) back slash
+\e\|^ (^) caret
+\e\|nnn (ASCII octal nnn)
+.El
+.Pp
+A `\|\e' may be followed by up to three octal digits directly specifies
+the numeric code for a character. The use of
+.Tn ASCII
+.Dv NUL Ns s ,
+while easily
+encoded, causes all sorts of problems and must be used with care since
+.Dv NUL Ns s
+are typically used to denote the end of strings; many applications
+use `\e\|200' to represent a
+.Dv NUL .
+.Sh DIAGNOSTICS
+.Fn Cgetent ,
+.Fn cgetset ,
+.Fn cgetmatch ,
+.Fn cgetnum ,
+.Fn cgetstr ,
+.Fn cgetustr ,
+.Fn cgetfirst ,
+and
+.Fn cgetnext
+return a value greater than or equal to 0 on success and a value less
+than 0 on failure.
+The
+.Fn cgetcap
+function returns a character pointer on success and a
+.Dv NULL
+on failure.
+.Pp
+The
+.Fn cgetent ,
+and
+.Fn cgetseq
+functions may fail and set
+.Va errno
+for any of the errors specified for the library functions:
+.Xr fopen 3 ,
+.Xr fclose 3 ,
+.Xr open 2 ,
+and
+.Xr close 2 .
+.Pp
+The
+.Fn cgetent ,
+.Fn cgetset ,
+.Fn cgetstr ,
+and
+.Fn cgetustr
+may fail and set
+.Va errno
+as follows:
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+No memory to allocate.
+.El
+.Sh SEE ALSO
+.Xr cap_mkdb 1 ,
+.Xr malloc 3
+.Sh BUGS
+Colons (`:') can't be used in names, types, or values.
+.Pp
+There are no checks for
+.Ic tc= name
+loops in
+.Fn cgetent .
+.Pp
+The buffer added to the database by a call to
+.Fn cgetset
+is not unique to the database but is rather prepended to any database used.
diff --git a/lib/libc/gen/getcap.c b/lib/libc/gen/getcap.c
new file mode 100644
index 0000000..d1e33b4
--- /dev/null
+++ b/lib/libc/gen/getcap.c
@@ -0,0 +1,1046 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Casey Leedom of Lawrence Livermore National Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getcap.c 8.3 (Berkeley) 3/25/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <db.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define BFRAG 1024
+#define BSIZE 1024
+#define ESC ('[' & 037) /* ASCII ESC */
+#define MAX_RECURSION 32 /* maximum getent recursion */
+#define SFRAG 100 /* cgetstr mallocs in SFRAG chunks */
+
+#define RECOK (char)0
+#define TCERR (char)1
+#define SHADOW (char)2
+
+static size_t topreclen; /* toprec length */
+static char *toprec; /* Additional record specified by cgetset() */
+static int gottoprec; /* Flag indicating retrieval of toprecord */
+
+static int cdbget __P((DB *, char **, char *));
+static int getent __P((char **, u_int *, char **, int, char *, int, char *));
+static int nfcmp __P((char *, char *));
+
+/*
+ * Cgetset() allows the addition of a user specified buffer to be added
+ * to the database array, in effect "pushing" the buffer on top of the
+ * virtual database. 0 is returned on success, -1 on failure.
+ */
+int
+cgetset(ent)
+ char *ent;
+{
+ if (ent == NULL) {
+ if (toprec)
+ free(toprec);
+ toprec = NULL;
+ topreclen = 0;
+ return (0);
+ }
+ topreclen = strlen(ent);
+ if ((toprec = malloc (topreclen + 1)) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ gottoprec = 0;
+ (void)strcpy(toprec, ent);
+ return (0);
+}
+
+/*
+ * Cgetcap searches the capability record buf for the capability cap with
+ * type `type'. A pointer to the value of cap is returned on success, NULL
+ * if the requested capability couldn't be found.
+ *
+ * Specifying a type of ':' means that nothing should follow cap (:cap:).
+ * In this case a pointer to the terminating ':' or NUL will be returned if
+ * cap is found.
+ *
+ * If (cap, '@') or (cap, terminator, '@') is found before (cap, terminator)
+ * return NULL.
+ */
+char *
+cgetcap(buf, cap, type)
+ char *buf, *cap;
+ int type;
+{
+ register char *bp, *cp;
+
+ bp = buf;
+ for (;;) {
+ /*
+ * Skip past the current capability field - it's either the
+ * name field if this is the first time through the loop, or
+ * the remainder of a field whose name failed to match cap.
+ */
+ for (;;)
+ if (*bp == '\0')
+ return (NULL);
+ else
+ if (*bp++ == ':')
+ break;
+
+ /*
+ * Try to match (cap, type) in buf.
+ */
+ for (cp = cap; *cp == *bp && *bp != '\0'; cp++, bp++)
+ continue;
+ if (*cp != '\0')
+ continue;
+ if (*bp == '@')
+ return (NULL);
+ if (type == ':') {
+ if (*bp != '\0' && *bp != ':')
+ continue;
+ return(bp);
+ }
+ if (*bp != type)
+ continue;
+ bp++;
+ return (*bp == '@' ? NULL : bp);
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * Cgetent extracts the capability record name from the NULL terminated file
+ * array db_array and returns a pointer to a malloc'd copy of it in buf.
+ * Buf must be retained through all subsequent calls to cgetcap, cgetnum,
+ * cgetflag, and cgetstr, but may then be free'd. 0 is returned on success,
+ * -1 if the requested record couldn't be found, -2 if a system error was
+ * encountered (couldn't open/read a file, etc.), and -3 if a potential
+ * reference loop is detected.
+ */
+int
+cgetent(buf, db_array, name)
+ char **buf, **db_array, *name;
+{
+ u_int dummy;
+
+ return (getent(buf, &dummy, db_array, -1, name, 0, NULL));
+}
+
+/*
+ * Getent implements the functions of cgetent. If fd is non-negative,
+ * *db_array has already been opened and fd is the open file descriptor. We
+ * do this to save time and avoid using up file descriptors for tc=
+ * recursions.
+ *
+ * Getent returns the same success/failure codes as cgetent. On success, a
+ * pointer to a malloc'ed capability record with all tc= capabilities fully
+ * expanded and its length (not including trailing ASCII NUL) are left in
+ * *cap and *len.
+ *
+ * Basic algorithm:
+ * + Allocate memory incrementally as needed in chunks of size BFRAG
+ * for capability buffer.
+ * + Recurse for each tc=name and interpolate result. Stop when all
+ * names interpolated, a name can't be found, or depth exceeds
+ * MAX_RECURSION.
+ */
+static int
+getent(cap, len, db_array, fd, name, depth, nfield)
+ char **cap, **db_array, *name, *nfield;
+ u_int *len;
+ int fd, depth;
+{
+ DB *capdbp;
+ register char *r_end, *rp, **db_p;
+ int myfd, eof, foundit, retval, clen;
+ char *record, *cbuf;
+ int tc_not_resolved;
+ char pbuf[_POSIX_PATH_MAX];
+
+ /*
+ * Return with ``loop detected'' error if we've recursed more than
+ * MAX_RECURSION times.
+ */
+ if (depth > MAX_RECURSION)
+ return (-3);
+
+ /*
+ * Check if we have a top record from cgetset().
+ */
+ if (depth == 0 && toprec != NULL && cgetmatch(toprec, name) == 0) {
+ if ((record = malloc (topreclen + BFRAG)) == NULL) {
+ errno = ENOMEM;
+ return (-2);
+ }
+ (void)strcpy(record, toprec);
+ myfd = 0;
+ db_p = db_array;
+ rp = record + topreclen + 1;
+ r_end = rp + BFRAG;
+ goto tc_exp;
+ }
+ /*
+ * Allocate first chunk of memory.
+ */
+ if ((record = malloc(BFRAG)) == NULL) {
+ errno = ENOMEM;
+ return (-2);
+ }
+ r_end = record + BFRAG;
+ foundit = 0;
+ /*
+ * Loop through database array until finding the record.
+ */
+
+ for (db_p = db_array; *db_p != NULL; db_p++) {
+ eof = 0;
+
+ /*
+ * Open database if not already open.
+ */
+
+ if (fd >= 0) {
+ (void)lseek(fd, (off_t)0, SEEK_SET);
+ myfd = 0;
+ } else {
+ (void)snprintf(pbuf, sizeof(pbuf), "%s.db", *db_p);
+ if ((capdbp = dbopen(pbuf, O_RDONLY, 0, DB_HASH, 0))
+ != NULL) {
+ free(record);
+ retval = cdbget(capdbp, &record, name);
+ if (retval < 0) {
+ /* no record available */
+ (void)capdbp->close(capdbp);
+ return (retval);
+ }
+ /* save the data; close frees it */
+ clen = strlen(record);
+ cbuf = malloc(clen + 1);
+ memcpy(cbuf, record, clen + 1);
+ if (capdbp->close(capdbp) < 0) {
+ free(cbuf);
+ return (-2);
+ }
+ *len = clen;
+ *cap = cbuf;
+ return (retval);
+ } else {
+ fd = open(*db_p, O_RDONLY, 0);
+ if (fd < 0)
+ continue;
+ myfd = 1;
+ }
+ }
+ /*
+ * Find the requested capability record ...
+ */
+ {
+ char buf[BUFSIZ];
+ register char *b_end, *bp;
+ register int c;
+
+ /*
+ * Loop invariants:
+ * There is always room for one more character in record.
+ * R_end always points just past end of record.
+ * Rp always points just past last character in record.
+ * B_end always points just past last character in buf.
+ * Bp always points at next character in buf.
+ */
+ b_end = buf;
+ bp = buf;
+ for (;;) {
+
+ /*
+ * Read in a line implementing (\, newline)
+ * line continuation.
+ */
+ rp = record;
+ for (;;) {
+ if (bp >= b_end) {
+ int n;
+
+ n = read(fd, buf, sizeof(buf));
+ if (n <= 0) {
+ if (myfd)
+ (void)close(fd);
+ if (n < 0) {
+ free(record);
+ return (-2);
+ } else {
+ fd = -1;
+ eof = 1;
+ break;
+ }
+ }
+ b_end = buf+n;
+ bp = buf;
+ }
+
+ c = *bp++;
+ if (c == '\n') {
+ if (rp > record && *(rp-1) == '\\') {
+ rp--;
+ continue;
+ } else
+ break;
+ }
+ *rp++ = c;
+
+ /*
+ * Enforce loop invariant: if no room
+ * left in record buffer, try to get
+ * some more.
+ */
+ if (rp >= r_end) {
+ u_int pos;
+ size_t newsize;
+
+ pos = rp - record;
+ newsize = r_end - record + BFRAG;
+ record = reallocf(record, newsize);
+ if (record == NULL) {
+ errno = ENOMEM;
+ if (myfd)
+ (void)close(fd);
+ return (-2);
+ }
+ r_end = record + newsize;
+ rp = record + pos;
+ }
+ }
+ /* loop invariant let's us do this */
+ *rp++ = '\0';
+
+ /*
+ * If encountered eof check next file.
+ */
+ if (eof)
+ break;
+
+ /*
+ * Toss blank lines and comments.
+ */
+ if (*record == '\0' || *record == '#')
+ continue;
+
+ /*
+ * See if this is the record we want ...
+ */
+ if (cgetmatch(record, name) == 0) {
+ if (nfield == NULL || !nfcmp(nfield, record)) {
+ foundit = 1;
+ break; /* found it! */
+ }
+ }
+ }
+ }
+ if (foundit)
+ break;
+ }
+
+ if (!foundit)
+ return (-1);
+
+ /*
+ * Got the capability record, but now we have to expand all tc=name
+ * references in it ...
+ */
+tc_exp: {
+ register char *newicap, *s;
+ register int newilen;
+ u_int ilen;
+ int diff, iret, tclen;
+ char *icap, *scan, *tc, *tcstart, *tcend;
+
+ /*
+ * Loop invariants:
+ * There is room for one more character in record.
+ * R_end points just past end of record.
+ * Rp points just past last character in record.
+ * Scan points at remainder of record that needs to be
+ * scanned for tc=name constructs.
+ */
+ scan = record;
+ tc_not_resolved = 0;
+ for (;;) {
+ if ((tc = cgetcap(scan, "tc", '=')) == NULL)
+ break;
+
+ /*
+ * Find end of tc=name and stomp on the trailing `:'
+ * (if present) so we can use it to call ourselves.
+ */
+ s = tc;
+ for (;;)
+ if (*s == '\0')
+ break;
+ else
+ if (*s++ == ':') {
+ *(s - 1) = '\0';
+ break;
+ }
+ tcstart = tc - 3;
+ tclen = s - tcstart;
+ tcend = s;
+
+ iret = getent(&icap, &ilen, db_p, fd, tc, depth+1,
+ NULL);
+ newicap = icap; /* Put into a register. */
+ newilen = ilen;
+ if (iret != 0) {
+ /* an error */
+ if (iret < -1) {
+ if (myfd)
+ (void)close(fd);
+ free(record);
+ return (iret);
+ }
+ if (iret == 1)
+ tc_not_resolved = 1;
+ /* couldn't resolve tc */
+ if (iret == -1) {
+ *(s - 1) = ':';
+ scan = s - 1;
+ tc_not_resolved = 1;
+ continue;
+
+ }
+ }
+ /* not interested in name field of tc'ed record */
+ s = newicap;
+ for (;;)
+ if (*s == '\0')
+ break;
+ else
+ if (*s++ == ':')
+ break;
+ newilen -= s - newicap;
+ newicap = s;
+
+ /* make sure interpolated record is `:'-terminated */
+ s += newilen;
+ if (*(s-1) != ':') {
+ *s = ':'; /* overwrite NUL with : */
+ newilen++;
+ }
+
+ /*
+ * Make sure there's enough room to insert the
+ * new record.
+ */
+ diff = newilen - tclen;
+ if (diff >= r_end - rp) {
+ u_int pos, tcpos, tcposend;
+ size_t newsize;
+
+ pos = rp - record;
+ newsize = r_end - record + diff + BFRAG;
+ tcpos = tcstart - record;
+ tcposend = tcend - record;
+ record = reallocf(record, newsize);
+ if (record == NULL) {
+ errno = ENOMEM;
+ if (myfd)
+ (void)close(fd);
+ free(icap);
+ return (-2);
+ }
+ r_end = record + newsize;
+ rp = record + pos;
+ tcstart = record + tcpos;
+ tcend = record + tcposend;
+ }
+
+ /*
+ * Insert tc'ed record into our record.
+ */
+ s = tcstart + newilen;
+ bcopy(tcend, s, rp - tcend);
+ bcopy(newicap, tcstart, newilen);
+ rp += diff;
+ free(icap);
+
+ /*
+ * Start scan on `:' so next cgetcap works properly
+ * (cgetcap always skips first field).
+ */
+ scan = s-1;
+ }
+
+ }
+ /*
+ * Close file (if we opened it), give back any extra memory, and
+ * return capability, length and success.
+ */
+ if (myfd)
+ (void)close(fd);
+ *len = rp - record - 1; /* don't count NUL */
+ if (r_end > rp)
+ if ((record =
+ reallocf(record, (size_t)(rp - record))) == NULL) {
+ errno = ENOMEM;
+ return (-2);
+ }
+
+ *cap = record;
+ if (tc_not_resolved)
+ return (1);
+ return (0);
+}
+
+static int
+cdbget(capdbp, bp, name)
+ DB *capdbp;
+ char **bp, *name;
+{
+ DBT key, data;
+
+ key.data = name;
+ key.size = strlen(name);
+
+ for (;;) {
+ /* Get the reference. */
+ switch(capdbp->get(capdbp, &key, &data, 0)) {
+ case -1:
+ return (-2);
+ case 1:
+ return (-1);
+ }
+
+ /* If not an index to another record, leave. */
+ if (((char *)data.data)[0] != SHADOW)
+ break;
+
+ key.data = (char *)data.data + 1;
+ key.size = data.size - 1;
+ }
+
+ *bp = (char *)data.data + 1;
+ return (((char *)(data.data))[0] == TCERR ? 1 : 0);
+}
+
+/*
+ * Cgetmatch will return 0 if name is one of the names of the capability
+ * record buf, -1 if not.
+ */
+int
+cgetmatch(buf, name)
+ char *buf, *name;
+{
+ register char *np, *bp;
+
+ /*
+ * Start search at beginning of record.
+ */
+ bp = buf;
+ for (;;) {
+ /*
+ * Try to match a record name.
+ */
+ np = name;
+ for (;;)
+ if (*np == '\0')
+ if (*bp == '|' || *bp == ':' || *bp == '\0')
+ return (0);
+ else
+ break;
+ else
+ if (*bp++ != *np++)
+ break;
+
+ /*
+ * Match failed, skip to next name in record.
+ */
+ bp--; /* a '|' or ':' may have stopped the match */
+ for (;;)
+ if (*bp == '\0' || *bp == ':')
+ return (-1); /* match failed totally */
+ else
+ if (*bp++ == '|')
+ break; /* found next name */
+ }
+}
+
+
+
+
+
+int
+cgetfirst(buf, db_array)
+ char **buf, **db_array;
+{
+ (void)cgetclose();
+ return (cgetnext(buf, db_array));
+}
+
+static FILE *pfp;
+static int slash;
+static char **dbp;
+
+int
+cgetclose()
+{
+ if (pfp != NULL) {
+ (void)fclose(pfp);
+ pfp = NULL;
+ }
+ dbp = NULL;
+ gottoprec = 0;
+ slash = 0;
+ return(0);
+}
+
+/*
+ * Cgetnext() gets either the first or next entry in the logical database
+ * specified by db_array. It returns 0 upon completion of the database, 1
+ * upon returning an entry with more remaining, and -1 if an error occurs.
+ */
+int
+cgetnext(bp, db_array)
+ register char **bp;
+ char **db_array;
+{
+ size_t len;
+ int status, i, done;
+ char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE];
+ u_int dummy;
+
+ if (dbp == NULL)
+ dbp = db_array;
+
+ if (pfp == NULL && (pfp = fopen(*dbp, "r")) == NULL) {
+ (void)cgetclose();
+ return (-1);
+ }
+ for(;;) {
+ if (toprec && !gottoprec) {
+ gottoprec = 1;
+ line = toprec;
+ } else {
+ line = fgetln(pfp, &len);
+ if (line == NULL && pfp) {
+ (void)fclose(pfp);
+ if (ferror(pfp)) {
+ (void)cgetclose();
+ return (-1);
+ } else {
+ if (*++dbp == NULL) {
+ (void)cgetclose();
+ return (0);
+ } else if ((pfp =
+ fopen(*dbp, "r")) == NULL) {
+ (void)cgetclose();
+ return (-1);
+ } else
+ continue;
+ }
+ } else
+ line[len - 1] = '\0';
+ if (len == 1) {
+ slash = 0;
+ continue;
+ }
+ if (isspace((unsigned char)*line) ||
+ *line == ':' || *line == '#' || slash) {
+ if (line[len - 2] == '\\')
+ slash = 1;
+ else
+ slash = 0;
+ continue;
+ }
+ if (line[len - 2] == '\\')
+ slash = 1;
+ else
+ slash = 0;
+ }
+
+
+ /*
+ * Line points to a name line.
+ */
+ i = 0;
+ done = 0;
+ np = nbuf;
+ for (;;) {
+ for (cp = line; *cp != '\0'; cp++) {
+ if (*cp == ':') {
+ *np++ = ':';
+ done = 1;
+ break;
+ }
+ if (*cp == '\\')
+ break;
+ *np++ = *cp;
+ }
+ if (done) {
+ *np = '\0';
+ break;
+ } else { /* name field extends beyond the line */
+ line = fgetln(pfp, &len);
+ if (line == NULL && pfp) {
+ (void)fclose(pfp);
+ if (ferror(pfp)) {
+ (void)cgetclose();
+ return (-1);
+ }
+ } else
+ line[len - 1] = '\0';
+ }
+ }
+ rp = buf;
+ for(cp = nbuf; *cp != '\0'; cp++)
+ if (*cp == '|' || *cp == ':')
+ break;
+ else
+ *rp++ = *cp;
+
+ *rp = '\0';
+ /*
+ * XXX
+ * Last argument of getent here should be nbuf if we want true
+ * sequential access in the case of duplicates.
+ * With NULL, getent will return the first entry found
+ * rather than the duplicate entry record. This is a
+ * matter of semantics that should be resolved.
+ */
+ status = getent(bp, &dummy, db_array, -1, buf, 0, NULL);
+ if (status == -2 || status == -3)
+ (void)cgetclose();
+
+ return (status + 1);
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * Cgetstr retrieves the value of the string capability cap from the
+ * capability record pointed to by buf. A pointer to a decoded, NUL
+ * terminated, malloc'd copy of the string is returned in the char *
+ * pointed to by str. The length of the string not including the trailing
+ * NUL is returned on success, -1 if the requested string capability
+ * couldn't be found, -2 if a system error was encountered (storage
+ * allocation failure).
+ */
+int
+cgetstr(buf, cap, str)
+ char *buf, *cap;
+ char **str;
+{
+ register u_int m_room;
+ register char *bp, *mp;
+ int len;
+ char *mem;
+
+ /*
+ * Find string capability cap
+ */
+ bp = cgetcap(buf, cap, '=');
+ if (bp == NULL)
+ return (-1);
+
+ /*
+ * Conversion / storage allocation loop ... Allocate memory in
+ * chunks SFRAG in size.
+ */
+ if ((mem = malloc(SFRAG)) == NULL) {
+ errno = ENOMEM;
+ return (-2); /* couldn't even allocate the first fragment */
+ }
+ m_room = SFRAG;
+ mp = mem;
+
+ while (*bp != ':' && *bp != '\0') {
+ /*
+ * Loop invariants:
+ * There is always room for one more character in mem.
+ * Mp always points just past last character in mem.
+ * Bp always points at next character in buf.
+ */
+ if (*bp == '^') {
+ bp++;
+ if (*bp == ':' || *bp == '\0')
+ break; /* drop unfinished escape */
+ if (*bp == '?') {
+ *mp++ = '\177';
+ bp++;
+ } else
+ *mp++ = *bp++ & 037;
+ } else if (*bp == '\\') {
+ bp++;
+ if (*bp == ':' || *bp == '\0')
+ break; /* drop unfinished escape */
+ if ('0' <= *bp && *bp <= '7') {
+ register int n, i;
+
+ n = 0;
+ i = 3; /* maximum of three octal digits */
+ do {
+ n = n * 8 + (*bp++ - '0');
+ } while (--i && '0' <= *bp && *bp <= '7');
+ *mp++ = n;
+ }
+ else switch (*bp++) {
+ case 'b': case 'B':
+ *mp++ = '\b';
+ break;
+ case 't': case 'T':
+ *mp++ = '\t';
+ break;
+ case 'n': case 'N':
+ *mp++ = '\n';
+ break;
+ case 'f': case 'F':
+ *mp++ = '\f';
+ break;
+ case 'r': case 'R':
+ *mp++ = '\r';
+ break;
+ case 'e': case 'E':
+ *mp++ = ESC;
+ break;
+ case 'c': case 'C':
+ *mp++ = ':';
+ break;
+ default:
+ /*
+ * Catches '\', '^', and
+ * everything else.
+ */
+ *mp++ = *(bp-1);
+ break;
+ }
+ } else
+ *mp++ = *bp++;
+ m_room--;
+
+ /*
+ * Enforce loop invariant: if no room left in current
+ * buffer, try to get some more.
+ */
+ if (m_room == 0) {
+ size_t size = mp - mem;
+
+ if ((mem = reallocf(mem, size + SFRAG)) == NULL)
+ return (-2);
+ m_room = SFRAG;
+ mp = mem + size;
+ }
+ }
+ *mp++ = '\0'; /* loop invariant let's us do this */
+ m_room--;
+ len = mp - mem - 1;
+
+ /*
+ * Give back any extra memory and return value and success.
+ */
+ if (m_room != 0)
+ if ((mem = reallocf(mem, (size_t)(mp - mem))) == NULL)
+ return (-2);
+ *str = mem;
+ return (len);
+}
+
+/*
+ * Cgetustr retrieves the value of the string capability cap from the
+ * capability record pointed to by buf. The difference between cgetustr()
+ * and cgetstr() is that cgetustr does not decode escapes but rather treats
+ * all characters literally. A pointer to a NUL terminated malloc'd
+ * copy of the string is returned in the char pointed to by str. The
+ * length of the string not including the trailing NUL is returned on success,
+ * -1 if the requested string capability couldn't be found, -2 if a system
+ * error was encountered (storage allocation failure).
+ */
+int
+cgetustr(buf, cap, str)
+ char *buf, *cap, **str;
+{
+ register u_int m_room;
+ register char *bp, *mp;
+ int len;
+ char *mem;
+
+ /*
+ * Find string capability cap
+ */
+ if ((bp = cgetcap(buf, cap, '=')) == NULL)
+ return (-1);
+
+ /*
+ * Conversion / storage allocation loop ... Allocate memory in
+ * chunks SFRAG in size.
+ */
+ if ((mem = malloc(SFRAG)) == NULL) {
+ errno = ENOMEM;
+ return (-2); /* couldn't even allocate the first fragment */
+ }
+ m_room = SFRAG;
+ mp = mem;
+
+ while (*bp != ':' && *bp != '\0') {
+ /*
+ * Loop invariants:
+ * There is always room for one more character in mem.
+ * Mp always points just past last character in mem.
+ * Bp always points at next character in buf.
+ */
+ *mp++ = *bp++;
+ m_room--;
+
+ /*
+ * Enforce loop invariant: if no room left in current
+ * buffer, try to get some more.
+ */
+ if (m_room == 0) {
+ size_t size = mp - mem;
+
+ if ((mem = reallocf(mem, size + SFRAG)) == NULL)
+ return (-2);
+ m_room = SFRAG;
+ mp = mem + size;
+ }
+ }
+ *mp++ = '\0'; /* loop invariant let's us do this */
+ m_room--;
+ len = mp - mem - 1;
+
+ /*
+ * Give back any extra memory and return value and success.
+ */
+ if (m_room != 0)
+ if ((mem = reallocf(mem, (size_t)(mp - mem))) == NULL)
+ return (-2);
+ *str = mem;
+ return (len);
+}
+
+/*
+ * Cgetnum retrieves the value of the numeric capability cap from the
+ * capability record pointed to by buf. The numeric value is returned in
+ * the long pointed to by num. 0 is returned on success, -1 if the requested
+ * numeric capability couldn't be found.
+ */
+int
+cgetnum(buf, cap, num)
+ char *buf, *cap;
+ long *num;
+{
+ register long n;
+ register int base, digit;
+ register char *bp;
+
+ /*
+ * Find numeric capability cap
+ */
+ bp = cgetcap(buf, cap, '#');
+ if (bp == NULL)
+ return (-1);
+
+ /*
+ * Look at value and determine numeric base:
+ * 0x... or 0X... hexadecimal,
+ * else 0... octal,
+ * else decimal.
+ */
+ if (*bp == '0') {
+ bp++;
+ if (*bp == 'x' || *bp == 'X') {
+ bp++;
+ base = 16;
+ } else
+ base = 8;
+ } else
+ base = 10;
+
+ /*
+ * Conversion loop ...
+ */
+ n = 0;
+ for (;;) {
+ if ('0' <= *bp && *bp <= '9')
+ digit = *bp - '0';
+ else if ('a' <= *bp && *bp <= 'f')
+ digit = 10 + *bp - 'a';
+ else if ('A' <= *bp && *bp <= 'F')
+ digit = 10 + *bp - 'A';
+ else
+ break;
+
+ if (digit >= base)
+ break;
+
+ n = n * base + digit;
+ bp++;
+ }
+
+ /*
+ * Return value and success.
+ */
+ *num = n;
+ return (0);
+}
+
+
+/*
+ * Compare name field of record.
+ */
+static int
+nfcmp(nf, rec)
+ char *nf, *rec;
+{
+ char *cp, tmp;
+ int ret;
+
+ for (cp = rec; *cp != ':'; cp++)
+ ;
+
+ tmp = *(cp + 1);
+ *(cp + 1) = '\0';
+ ret = strcmp(nf, rec);
+ *(cp + 1) = tmp;
+
+ return (ret);
+}
diff --git a/lib/libc/gen/getcwd.3 b/lib/libc/gen/getcwd.3
new file mode 100644
index 0000000..357fdf3
--- /dev/null
+++ b/lib/libc/gen/getcwd.3
@@ -0,0 +1,156 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getcwd.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd November 24, 1997
+.Dt GETCWD 3
+.Os BSD 4.2
+.Sh NAME
+.Nm getcwd ,
+.Nm getwd
+.Nd get working directory pathname
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft char *
+.Fn getcwd "char *buf" "size_t size"
+.Ft char *
+.Fn getwd "char *buf"
+.Sh DESCRIPTION
+The
+.Fn getcwd
+function copies the absolute pathname of the current working directory
+into the memory referenced by
+.Fa buf
+and returns a pointer to
+.Fa buf .
+The
+.Fa size
+argument is the size, in bytes, of the array referenced by
+.Fa buf .
+.Pp
+If
+.Fa buf
+is
+.Dv NULL ,
+space is allocated as necessary to store the pathname.
+This space may later be
+.Xr free 3 Ns 'd.
+.Pp
+The function
+.Fn getwd
+is a compatibility routine which calls
+.Fn getcwd
+with its
+.Fa buf
+argument and a size of
+.Dv MAXPATHLEN
+(as defined in the include
+file
+.Aq Pa sys/param.h ) .
+Obviously,
+.Fa buf
+should be at least
+.Dv MAXPATHLEN
+bytes in length.
+.Pp
+These routines have traditionally been used by programs to save the
+name of a working directory for the purpose of returning to it.
+A much faster and less error-prone method of accomplishing this is to
+open the current directory
+.Pq Ql \&.
+and use the
+.Xr fchdir 2
+function to return.
+.Sh RETURN VALUES
+Upon successful completion, a pointer to the pathname is returned.
+Otherwise a
+.Dv NULL
+pointer is returned and the global variable
+.Va errno
+is set to indicate the error.
+In addition,
+.Fn getwd
+copies the error message associated with
+.Va errno
+into the memory referenced by
+.Fa buf .
+.Sh ERRORS
+The
+.Fn getcwd
+function
+will fail if:
+.Bl -tag -width [EACCES]
+.It Bq Er EACCES
+Read or search permission was denied for a component of the pathname.
+.It Bq Er EINVAL
+The
+.Fa size
+argument is zero.
+.It Bq Er ENOENT
+A component of the pathname no longer exists.
+.It Bq Er ENOMEM
+Insufficient memory is available.
+.It Bq Er ERANGE
+The
+.Fa size
+argument is greater than zero but smaller than the length of the pathname
+plus 1.
+.El
+.Sh SEE ALSO
+.Xr chdir 2 ,
+.Xr fchdir 2 ,
+.Xr malloc 3 ,
+.Xr strerror 3
+.Sh STANDARDS
+The
+.Fn getcwd
+function
+conforms to
+.St -ansiC .
+The ability to specify a
+.Dv NULL
+pointer and have
+.Fn getcwd
+allocate memory as necessary is an extension.
+.Sh HISTORY
+The
+.Fn getwd
+function appeared in
+.Bx 4.0 .
+.Sh BUGS
+The
+.Fn getwd
+function
+does not do sufficient error checking and is not able to return very
+long, but valid, paths.
+It is provided for compatibility.
diff --git a/lib/libc/gen/getcwd.c b/lib/libc/gen/getcwd.c
new file mode 100644
index 0000000..9b1ccf3
--- /dev/null
+++ b/lib/libc/gen/getcwd.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 1989, 1991, 1993, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getcwd.c 8.5 (Berkeley) 2/7/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+
+#define ISDOT(dp) \
+ (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
+ (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
+
+static int have__getcwd = 1; /* 0 = no, 1 = perhaps, 2 = yes */
+
+char *
+getcwd(pt, size)
+ char *pt;
+ size_t size;
+{
+ register struct dirent *dp;
+ register DIR *dir = NULL;
+ register dev_t dev;
+ register ino_t ino;
+ register int first;
+ register char *bpt, *bup;
+ struct stat s;
+ dev_t root_dev;
+ ino_t root_ino;
+ size_t ptsize, upsize;
+ int save_errno;
+ char *ept, *eup, *up, c;
+
+ /*
+ * If no buffer specified by the user, allocate one as necessary.
+ * If a buffer is specified, the size has to be non-zero. The path
+ * is built from the end of the buffer backwards.
+ */
+ if (pt) {
+ ptsize = 0;
+ if (!size) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ if (size == 1) {
+ errno = ERANGE;
+ return (NULL);
+ }
+ ept = pt + size;
+ } else {
+ if ((pt = malloc(ptsize = 1024 - 4)) == NULL)
+ return (NULL);
+ ept = pt + ptsize;
+ }
+#if defined(__NETBSD_SYSCALLS)
+ have__getcwd = 0;
+#else
+ if (have__getcwd) {
+ struct sigaction sa, osa;
+ int sigsys_installed = 0;
+ int ret;
+
+ if (have__getcwd == 1) { /* unsure? */
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sa.sa_handler = SIG_IGN;
+ if (sigaction(SIGSYS, &sa, &osa) >= 0)
+ sigsys_installed = 1;
+ }
+ ret = __getcwd(pt, ept - pt);
+ if (sigsys_installed == 1) {
+ int oerrno = errno;
+ sigaction(SIGSYS, &osa, NULL);
+ errno = oerrno;
+ }
+ /* XXX a bogus syscall seems to return EINVAL(!) */
+ if (ret < 0 && (errno == ENOSYS || errno == EINVAL))
+ have__getcwd = 0;
+ else if (have__getcwd == 1)
+ have__getcwd = 2; /* yep, remember we have it */
+ if (ret == 0) {
+ if (*pt != '/') {
+ bpt = pt;
+ ept = pt + strlen(pt) - 1;
+ while (bpt < ept) {
+ c = *bpt;
+ *bpt++ = *ept;
+ *ept-- = c;
+ }
+ }
+ return (pt);
+ }
+ }
+#endif
+ bpt = ept - 1;
+ *bpt = '\0';
+
+ /*
+ * Allocate bytes (1024 - malloc space) for the string of "../"'s.
+ * Should always be enough (it's 340 levels). If it's not, allocate
+ * as necessary. Special case the first stat, it's ".", not "..".
+ */
+ if ((up = malloc(upsize = 1024 - 4)) == NULL)
+ goto err;
+ eup = up + MAXPATHLEN;
+ bup = up;
+ up[0] = '.';
+ up[1] = '\0';
+
+ /* Save root values, so know when to stop. */
+ if (stat("/", &s))
+ goto err;
+ root_dev = s.st_dev;
+ root_ino = s.st_ino;
+
+ errno = 0; /* XXX readdir has no error return. */
+
+ for (first = 1;; first = 0) {
+ /* Stat the current level. */
+ if (lstat(up, &s))
+ goto err;
+
+ /* Save current node values. */
+ ino = s.st_ino;
+ dev = s.st_dev;
+
+ /* Check for reaching root. */
+ if (root_dev == dev && root_ino == ino) {
+ *--bpt = '/';
+ /*
+ * It's unclear that it's a requirement to copy the
+ * path to the beginning of the buffer, but it's always
+ * been that way and stuff would probably break.
+ */
+ bcopy(bpt, pt, ept - bpt);
+ free(up);
+ return (pt);
+ }
+
+ /*
+ * Build pointer to the parent directory, allocating memory
+ * as necessary. Max length is 3 for "../", the largest
+ * possible component name, plus a trailing NULL.
+ */
+ if (bup + 3 + MAXNAMLEN + 1 >= eup) {
+ if ((up = reallocf(up, upsize *= 2)) == NULL)
+ goto err;
+ bup = up;
+ eup = up + upsize;
+ }
+ *bup++ = '.';
+ *bup++ = '.';
+ *bup = '\0';
+
+ /* Open and stat parent directory. */
+ if (!(dir = opendir(up)) || fstat(dirfd(dir), &s))
+ goto err;
+
+ /* Add trailing slash for next directory. */
+ *bup++ = '/';
+ *bup = '\0';
+
+ /*
+ * If it's a mount point, have to stat each element because
+ * the inode number in the directory is for the entry in the
+ * parent directory, not the inode number of the mounted file.
+ */
+ save_errno = 0;
+ if (s.st_dev == dev) {
+ for (;;) {
+ if (!(dp = readdir(dir)))
+ goto notfound;
+ if (dp->d_fileno == ino)
+ break;
+ }
+ } else
+ for (;;) {
+ if (!(dp = readdir(dir)))
+ goto notfound;
+ if (ISDOT(dp))
+ continue;
+ bcopy(dp->d_name, bup, dp->d_namlen + 1);
+
+ /* Save the first error for later. */
+ if (lstat(up, &s)) {
+ if (!save_errno)
+ save_errno = errno;
+ errno = 0;
+ continue;
+ }
+ if (s.st_dev == dev && s.st_ino == ino)
+ break;
+ }
+
+ /*
+ * Check for length of the current name, preceding slash,
+ * leading slash.
+ */
+ if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) {
+ size_t len, off;
+
+ if (!ptsize) {
+ errno = ERANGE;
+ goto err;
+ }
+ off = bpt - pt;
+ len = ept - bpt;
+ if ((pt = realloc(pt, ptsize *= 2)) == NULL)
+ goto err;
+ bpt = pt + off;
+ ept = pt + ptsize;
+ bcopy(bpt, ept - len, len);
+ bpt = ept - len;
+ }
+ if (!first)
+ *--bpt = '/';
+ bpt -= dp->d_namlen;
+ bcopy(dp->d_name, bpt, dp->d_namlen);
+ (void) closedir(dir);
+ dir = NULL;
+
+ /* Truncate any file name. */
+ *bup = '\0';
+ }
+
+notfound:
+ /*
+ * If readdir set errno, use it, not any saved error; otherwise,
+ * didn't find the current directory in its parent directory, set
+ * errno to ENOENT.
+ */
+ if (!errno)
+ errno = save_errno ? save_errno : ENOENT;
+ /* FALLTHROUGH */
+err:
+ save_errno = errno;
+
+ if (ptsize)
+ free(pt);
+ if (dir)
+ (void) closedir(dir);
+ free(up);
+
+ errno = save_errno;
+ return (NULL);
+}
diff --git a/lib/libc/gen/getdiskbyname.3 b/lib/libc/gen/getdiskbyname.3
new file mode 100644
index 0000000..14d8824
--- /dev/null
+++ b/lib/libc/gen/getdiskbyname.3
@@ -0,0 +1,65 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getdiskbyname.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETDISKBYNAME 3
+.Os BSD 4.2
+.Sh NAME
+.Nm getdiskbyname
+.Nd get generic disk description by its name
+.Sh SYNOPSIS
+.Fd #include <sys/disklabel.h>
+.Ft struct disklabel *
+.Fn getdiskbyname "const char *name"
+.Sh DESCRIPTION
+The
+.Fn getdiskbyname
+function
+takes a disk name (e.g.
+.Ql rm03 )
+and returns a prototype disk label
+describing its geometry information and the standard
+disk partition tables. All information is obtained from
+the
+.Xr disktab 5
+file.
+.Sh SEE ALSO
+.Xr disklabel 5 ,
+.Xr disktab 5 ,
+.Xr disklabel 8
+.Sh HISTORY
+The
+.Fn getdiskbyname
+function appeared in
+.Bx 4.3 .
diff --git a/lib/libc/gen/getdomainname.3 b/lib/libc/gen/getdomainname.3
new file mode 100644
index 0000000..60a8099
--- /dev/null
+++ b/lib/libc/gen/getdomainname.3
@@ -0,0 +1,99 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)gethostname.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd May 6, 1994
+.Dt GETDOMAINNAME 3
+.Os BSD 4.2
+.Sh NAME
+.Nm getdomainname ,
+.Nm setdomainname
+.Nd get/set domain name of current host
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn getdomainname "char *name" "int namelen"
+.Ft int
+.Fn setdomainname "const char *name" "int namelen"
+.Sh DESCRIPTION
+.Fn Getdomainname
+returns the standard domain name for the current processor, as
+previously set by
+.Fn setdomainname .
+The parameter
+.Fa namelen
+specifies the size of the
+.Fa name
+array. The returned name is null-terminated unless insufficient
+space is provided.
+.Pp
+.Fn Setdomainname
+sets the domain name of the host machine to be
+.Fa name ,
+which has length
+.Fa namelen .
+This call is restricted to the super-user and
+is normally used only when the system is bootstrapped.
+.Sh RETURN VALUES
+If the call succeeds a value of 0 is returned. If the call
+fails, a value of -1 is returned and an error code is
+placed in the global location
+.Va errno .
+.Sh ERRORS
+The following errors may be returned by these calls:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+The
+.Fa name
+or
+.Fa namelen
+parameter gave an
+invalid address.
+.It Bq Er EPERM
+The caller tried to set the hostname and was not the super-user.
+.El
+.Sh SEE ALSO
+.Xr gethostid 3 ,
+.Xr gethostname 3 ,
+.Xr sysctl 3
+.Sh BUGS
+Domain names are limited to
+.Dv MAXHOSTNAMELEN
+(from
+.Ao Pa sys/param.h Ac )
+characters, currently 256.
+.Sh HISTORY
+The
+.Fn getdomainname
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/gen/getdomainname.c b/lib/libc/gen/getdomainname.c
new file mode 100644
index 0000000..aafb010
--- /dev/null
+++ b/lib/libc/gen/getdomainname.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*
+static char sccsid[] = "From: @(#)gethostname.c 8.1 (Berkeley) 6/4/93";
+*/
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#include <unistd.h>
+
+int
+getdomainname(name, namelen)
+ char *name;
+ int namelen;
+{
+ int mib[2];
+ size_t size;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_NISDOMAINNAME;
+ size = namelen;
+ if (sysctl(mib, 2, name, &size, NULL, 0) == -1)
+ return (-1);
+ return (0);
+}
diff --git a/lib/libc/gen/getfsent.3 b/lib/libc/gen/getfsent.3
new file mode 100644
index 0000000..98064fc
--- /dev/null
+++ b/lib/libc/gen/getfsent.3
@@ -0,0 +1,151 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getfsent.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETFSENT 3
+.Os BSD 4
+.Sh NAME
+.Nm getfsent ,
+.Nm getfsspec ,
+.Nm getfsfile ,
+.Nm setfsent ,
+.Nm endfsent
+.Nd get file system descriptor file entry
+.Sh SYNOPSIS
+.Fd #include <fstab.h>
+.Ft struct fstab *
+.Fn getfsent void
+.Ft struct fstab *
+.Fn getfsspec "const char *spec"
+.Ft struct fstab *
+.Fn getfsfile "const char *file"
+.Ft int
+.Fn setfsent void
+.Ft void
+.Fn endfsent void
+.Sh DESCRIPTION
+The
+.Fn getfsent ,
+.Fn getfsspec ,
+and
+.Fn getfsfile
+functions
+each return a pointer to an object with the following structure
+containing the broken-out fields of a line in the file system
+description file,
+.Aq Pa fstab.h .
+.Bd -literal -offset indent
+struct fstab {
+ char *fs_spec; /* block special device name */
+ char *fs_file; /* file system path prefix */
+ char *fs_vfstype; /* File system type, ufs, nfs */
+ char *fs_mntops; /* Mount options ala -o */
+ char *fs_type; /* FSTAB_* from fs_mntops */
+ int fs_freq; /* dump frequency, in days */
+ int fs_passno; /* pass number on parallel fsck */
+};
+.Ed
+.Pp
+The fields have meanings described in
+.Xr fstab 5 .
+.Pp
+The
+.Fn setfsent
+function
+opens the file (closing any previously opened file) or rewinds it
+if it is already open.
+.Pp
+The
+.Fn endfsent
+function
+closes the file.
+.Pp
+The
+.Fn getfsspec
+and
+.Fn getfsfile
+functions
+search the entire file (opening it if necessary) for a matching special
+file name or file system file name.
+.Pp
+For programs wishing to read the entire database,
+.Fn getfsent
+reads the next entry (opening the file if necessary).
+.Pp
+All entries in the file with a type field equivalent to
+.Dv FSTAB_XX
+are ignored.
+.Sh RETURN VALUES
+The
+.Fn getfsent ,
+.Fn getfsspec ,
+and
+.Fn getfsfile
+functions
+return a
+.Dv NULL
+pointer on
+.Dv EOF
+or error.
+The
+.Fn setfsent
+function
+returns 0 on failure, 1 on success.
+The
+.Fn endfsent
+function
+returns nothing.
+.Sh FILES
+.Bl -tag -width /etc/fstab -compact
+.It Pa /etc/fstab
+.El
+.Sh SEE ALSO
+.Xr fstab 5
+.Sh HISTORY
+The
+.Fn getfsent
+function appeared in
+.Bx 4.0 ;
+the
+.Fn endfsent ,
+.Fn getfsfile ,
+.Fn getfsspec ,
+and
+.Fn setfsent
+functions appeared in
+.Bx 4.3 .
+.Sh BUGS
+These functions use static data storage;
+if the data is needed for future use, it should be
+copied before any subsequent calls overwrite it.
diff --git a/lib/libc/gen/getgrent.3 b/lib/libc/gen/getgrent.3
new file mode 100644
index 0000000..bb3cfb5
--- /dev/null
+++ b/lib/libc/gen/getgrent.3
@@ -0,0 +1,205 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)getgrent.3 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd September 29, 1994
+.Dt GETGRENT 3
+.Os
+.Sh NAME
+.Nm getgrent ,
+.Nm getgrnam ,
+.Nm getgrgid ,
+.Nm setgroupent ,
+.\" .Nm setgrfile ,
+.Nm setgrent ,
+.Nm endgrent
+.Nd group database operations
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <grp.h>
+.Ft struct group *
+.Fn getgrent void
+.Ft struct group *
+.Fn getgrnam "const char *name"
+.Ft struct group *
+.Fn getgrgid "gid_t gid"
+.Ft int
+.Fn setgroupent "int stayopen"
+.\" .Ft void
+.\" .Fn setgrfile "const char *name"
+.Ft int
+.Fn setgrent void
+.Ft void
+.Fn endgrent void
+.Sh DESCRIPTION
+These functions operate on the group database file
+.Pa /etc/group
+which is described
+in
+.Xr group 5 .
+Each line of the database is defined by the structure
+.Ar group
+found in the include
+file
+.Aq Pa grp.h :
+.Bd -literal -offset indent
+struct group {
+ char *gr_name; /* group name */
+ char *gr_passwd; /* group password */
+ int gr_gid; /* group id */
+ char **gr_mem; /* group members */
+};
+.Ed
+.Pp
+The functions
+.Fn getgrnam
+and
+.Fn getgrgid
+search the group database for the given group name pointed to by
+.Ar name
+or the group id pointed to by
+.Ar gid ,
+respectively, returning the first one encountered. Identical group
+names or group gids may result in undefined behavior.
+.Pp
+The
+.Fn getgrent
+function
+sequentially reads the group database and is intended for programs
+that wish to step through the complete list of groups.
+.Pp
+All three routines will open the group file for reading, if necessary.
+.Pp
+The
+.Fn setgroupent
+function
+opens the file, or rewinds it if it is already open. If
+.Fa stayopen
+is non-zero, file descriptors are left open, significantly speeding
+functions subsequent calls. This functionality is unnecessary for
+.Fn getgrent
+as it doesn't close its file descriptors by default. It should also
+be noted that it is dangerous for long-running programs to use this
+functionality as the group file may be updated.
+.Pp
+The
+.Fn setgrent
+function
+is identical to
+.Fn setgroupent
+with an argument of zero.
+.Pp
+The
+.Fn endgrent
+function
+closes any open files.
+.Sh YP/NIS INTERACTION
+When the
+.Xr yp 4
+group database is enabled, the
+.Fn getgrnam
+and
+.Fn getgrgid
+functions use the YP maps
+.Dq Li group.byname
+and
+.Dq Li group.bygid ,
+respectively, if the requested group is not found in the local
+.Pa /etc/group
+file. The
+.Fn getgrent
+function will step through the YP map
+.Dq Li group.byname
+if the entire map is enabled as described in
+.Xr group 5 .
+.Sh RETURN VALUES
+The functions
+.Fn getgrent ,
+.Fn getgrnam ,
+and
+.Fn getgrgid ,
+return a pointer to the group entry if successful; if end-of-file
+is reached or an error occurs a null pointer is returned.
+The functions
+.Fn setgroupent
+and
+.Fn setgrent
+return the value 1 if successful, otherwise the value
+0 is returned.
+The functions
+.Fn endgrent
+and
+.Fn setgrfile
+have no return value.
+.Sh FILES
+.Bl -tag -width /etc/group -compact
+.It Pa /etc/group
+group database file
+.El
+.Sh SEE ALSO
+.Xr getpwent 3 ,
+.Xr yp 4 ,
+.Xr group 5
+.Sh HISTORY
+The functions
+.Fn endgrent ,
+.Fn getgrent ,
+.Fn getgrnam ,
+.Fn getgrgid ,
+and
+.Fn setgrent
+appeared in
+.At v7 .
+The functions
+.Fn setgrfile
+and
+.Fn setgroupent
+appeared in
+.Bx 4.3 Reno .
+.Sh COMPATIBILITY
+The historic function
+.Fn setgrfile ,
+which allowed the specification of alternate password databases, has
+been deprecated and is no longer available.
+.Sh BUGS
+The functions
+.Fn getgrent ,
+.Fn getgrnam ,
+.Fn getgrgid ,
+.Fn setgroupent
+and
+.Fn setgrent
+leave their results in an internal static object and return
+a pointer to that object. Subsequent calls to
+the same function
+will modify the same object.
diff --git a/lib/libc/gen/getgrent.c b/lib/libc/gen/getgrent.c
new file mode 100644
index 0000000..5b5c9da
--- /dev/null
+++ b/lib/libc/gen/getgrent.c
@@ -0,0 +1,553 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getgrent.c 8.2 (Berkeley) 3/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <grp.h>
+
+static FILE *_gr_fp;
+static struct group _gr_group;
+static int _gr_stayopen;
+static int grscan(), start_gr();
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+static int _gr_stepping_yp;
+static int _gr_yp_enabled;
+static int _getypgroup(struct group *, const char *, char *);
+static int _nextypgroup(struct group *);
+#endif
+
+/* initial size for malloc and increase steps for realloc */
+#define MAXGRP 64
+#define MAXLINELENGTH 256
+
+static char **members; /* list of group members */
+static int maxgrp; /* current length of **mebers */
+static char *line; /* temp buffer for group line */
+static int maxlinelength; /* current length of *line */
+
+/*
+ * Lines longer than MAXLINELENGTHLIMIT will be count as an error.
+ * <= 0 disable check for maximum line length
+ * 256K is enough for 64,000 uids
+ */
+#define MAXLINELENGTHLIMIT (256 * 1024)
+#define GROUP_IGNORE_COMMENTS 1 /* allow comments in /etc/group */
+
+struct group *
+getgrent()
+{
+ if (!_gr_fp && !start_gr()) {
+ return NULL;
+ }
+
+#ifdef YP
+ if (_gr_stepping_yp) {
+ if (_nextypgroup(&_gr_group))
+ return(&_gr_group);
+ }
+tryagain:
+#endif
+
+ if (!grscan(0, 0, NULL))
+ return(NULL);
+#ifdef YP
+ if(_gr_group.gr_name[0] == '+' && _gr_group.gr_name[1]) {
+ _getypgroup(&_gr_group, &_gr_group.gr_name[1],
+ "group.byname");
+ } else if(_gr_group.gr_name[0] == '+') {
+ if (!_nextypgroup(&_gr_group))
+ goto tryagain;
+ else
+ return(&_gr_group);
+ }
+#endif
+ return(&_gr_group);
+}
+
+struct group *
+getgrnam(name)
+ const char *name;
+{
+ int rval;
+
+ if (!start_gr())
+ return(NULL);
+#ifdef YP
+ tryagain:
+#endif
+ rval = grscan(1, 0, name);
+#ifdef YP
+ if(rval == -1 && (_gr_yp_enabled < 0 || (_gr_yp_enabled &&
+ _gr_group.gr_name[0] == '+'))) {
+ if (!(rval = _getypgroup(&_gr_group, name, "group.byname")))
+ goto tryagain;
+ }
+#endif
+ if (!_gr_stayopen)
+ endgrent();
+ return(rval ? &_gr_group : NULL);
+}
+
+struct group *
+#ifdef __STDC__
+getgrgid(gid_t gid)
+#else
+getgrgid(gid)
+ gid_t gid;
+#endif
+{
+ int rval;
+
+ if (!start_gr())
+ return(NULL);
+#ifdef YP
+ tryagain:
+#endif
+ rval = grscan(1, gid, NULL);
+#ifdef YP
+ if(rval == -1 && _gr_yp_enabled) {
+ char buf[16];
+ snprintf(buf, sizeof buf, "%d", (unsigned)gid);
+ if (!(rval = _getypgroup(&_gr_group, buf, "group.bygid")))
+ goto tryagain;
+ }
+#endif
+ if (!_gr_stayopen)
+ endgrent();
+ return(rval ? &_gr_group : NULL);
+}
+
+static int
+start_gr()
+{
+ if (_gr_fp) {
+ rewind(_gr_fp);
+ return(1);
+ }
+ _gr_fp = fopen(_PATH_GROUP, "r");
+ if(!_gr_fp) return 0;
+#ifdef YP
+ /*
+ * This is a disgusting hack, used to determine when YP is enabled.
+ * This would be easier if we had a group database to go along with
+ * the password database.
+ */
+ {
+ char *line;
+ size_t linelen;
+ _gr_yp_enabled = 0;
+ while((line = fgetln(_gr_fp, &linelen)) != NULL) {
+ if(line[0] == '+') {
+ if(line[1] && line[1] != ':' && !_gr_yp_enabled) {
+ _gr_yp_enabled = 1;
+ } else {
+ _gr_yp_enabled = -1;
+ break;
+ }
+ }
+ }
+ rewind(_gr_fp);
+ }
+#endif
+
+ if (maxlinelength == 0) {
+ if ((line = (char *)malloc(sizeof(char) *
+ MAXLINELENGTH)) == NULL)
+ return(0);
+ maxlinelength += MAXLINELENGTH;
+ }
+
+ if (maxgrp == 0) {
+ if ((members = (char **)malloc(sizeof(char **) *
+ MAXGRP)) == NULL)
+ return(0);
+ maxgrp += MAXGRP;
+ }
+
+ return 1;
+}
+
+int
+setgrent()
+{
+ return(setgroupent(0));
+}
+
+int
+setgroupent(stayopen)
+ int stayopen;
+{
+ if (!start_gr())
+ return(0);
+ _gr_stayopen = stayopen;
+#ifdef YP
+ _gr_stepping_yp = 0;
+#endif
+ return(1);
+}
+
+void
+endgrent()
+{
+#ifdef YP
+ _gr_stepping_yp = 0;
+#endif
+ if (_gr_fp) {
+ (void)fclose(_gr_fp);
+ _gr_fp = NULL;
+ }
+}
+
+static int
+grscan(search, gid, name)
+ register int search, gid;
+ register char *name;
+{
+ register char *cp, **m;
+ char *bp;
+
+
+#ifdef YP
+ int _ypfound;
+#endif
+ for (;;) {
+#ifdef YP
+ _ypfound = 0;
+#endif
+ if (fgets(line, maxlinelength, _gr_fp) == NULL)
+ return(0);
+
+ if (!index(line, '\n')) {
+ do {
+ if (feof(_gr_fp))
+ return(0);
+
+ /* don't allocate infinite memory */
+ if (MAXLINELENGTHLIMIT > 0 &&
+ maxlinelength >= MAXLINELENGTHLIMIT)
+ return(0);
+
+ if ((line = (char *)reallocf(line,
+ sizeof(char) *
+ (maxlinelength + MAXLINELENGTH))) == NULL)
+ return(0);
+
+ if (fgets(line + maxlinelength - 1,
+ MAXLINELENGTH + 1, _gr_fp) == NULL)
+ return(0);
+
+ maxlinelength += MAXLINELENGTH;
+ } while (!index(line + maxlinelength -
+ MAXLINELENGTH - 1, '\n'));
+ }
+
+#ifdef GROUP_IGNORE_COMMENTS
+ /*
+ * Ignore comments: ^[ \t]*#
+ */
+ for (cp = line; *cp != '\0'; cp++)
+ if (*cp != ' ' && *cp != '\t')
+ break;
+ if (*cp == '#' || *cp == '\0')
+ continue;
+#endif
+
+ bp = line;
+
+ if ((_gr_group.gr_name = strsep(&bp, ":\n")) == NULL)
+ break;
+#ifdef YP
+ /*
+ * XXX We need to be careful to avoid proceeding
+ * past this point under certain circumstances or
+ * we risk dereferencing null pointers down below.
+ */
+ if (_gr_group.gr_name[0] == '+') {
+ if (strlen(_gr_group.gr_name) == 1) {
+ switch(search) {
+ case 0:
+ return(1);
+ case 1:
+ return(-1);
+ default:
+ return(0);
+ }
+ } else {
+ cp = &_gr_group.gr_name[1];
+ if (search && name != NULL)
+ if (strcmp(cp, name))
+ continue;
+ if (!_getypgroup(&_gr_group, cp,
+ "group.byname"))
+ continue;
+ if (search && name == NULL)
+ if (gid != _gr_group.gr_gid)
+ continue;
+ /* We're going to override -- tell the world. */
+ _ypfound++;
+ }
+ }
+#else
+ if (_gr_group.gr_name[0] == '+')
+ continue;
+#endif /* YP */
+ if (search && name) {
+ if(strcmp(_gr_group.gr_name, name)) {
+ continue;
+ }
+ }
+#ifdef YP
+ if ((cp = strsep(&bp, ":\n")) == NULL)
+ if (_ypfound)
+ return(1);
+ else
+ break;
+ if (strlen(cp) || !_ypfound)
+ _gr_group.gr_passwd = cp;
+#else
+ if ((_gr_group.gr_passwd = strsep(&bp, ":\n")) == NULL)
+ break;
+#endif
+ if (!(cp = strsep(&bp, ":\n")))
+#ifdef YP
+ if (_ypfound)
+ return(1);
+ else
+#endif
+ continue;
+#ifdef YP
+ /*
+ * Hurm. Should we be doing this? We allow UIDs to
+ * be overridden -- what about GIDs?
+ */
+ if (!_ypfound)
+#endif
+ _gr_group.gr_gid = atoi(cp);
+ if (search && name == NULL && _gr_group.gr_gid != gid)
+ continue;
+ cp = NULL;
+ if (bp == NULL) /* !!! Must check for this! */
+ break;
+#ifdef YP
+ if ((cp = strsep(&bp, ":\n")) == NULL)
+ break;
+
+ if (!strlen(cp) && _ypfound)
+ return(1);
+ else
+ members[0] = NULL;
+ bp = cp;
+ cp = NULL;
+#endif
+ for (m = members; ; bp++) {
+ if (m == (members + maxgrp - 1)) {
+ if ((members = (char **)
+ reallocf(members,
+ sizeof(char **) *
+ (maxgrp + MAXGRP))) == NULL)
+ return(0);
+ m = members + maxgrp - 1;
+ maxgrp += MAXGRP;
+ }
+ if (*bp == ',') {
+ if (cp) {
+ *bp = '\0';
+ *m++ = cp;
+ cp = NULL;
+ }
+ } else if (*bp == '\0' || *bp == '\n' || *bp == ' ') {
+ if (cp) {
+ *bp = '\0';
+ *m++ = cp;
+ }
+ break;
+ } else if (cp == NULL)
+ cp = bp;
+
+ }
+ _gr_group.gr_mem = members;
+ *m = NULL;
+ return(1);
+ }
+ /* NOTREACHED */
+ return (0);
+}
+
+#ifdef YP
+
+static int
+_gr_breakout_yp(struct group *gr, char *result)
+{
+ char *s, *cp;
+ char **m;
+
+ /*
+ * XXX If 's' ends up being a NULL pointer, punt on this group.
+ * It means the NIS group entry is badly formatted and should
+ * be skipped.
+ */
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* name */
+ gr->gr_name = s;
+
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* password */
+ gr->gr_passwd = s;
+
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* gid */
+ gr->gr_gid = atoi(s);
+
+ if ((s = result) == NULL) return 0;
+ cp = 0;
+
+ for (m = members; ; s++) {
+ if (m == members + maxgrp - 1) {
+ if ((members = (char **)reallocf(members,
+ sizeof(char **) * (maxgrp + MAXGRP))) == NULL)
+ return(0);
+ m = members + maxgrp - 1;
+ maxgrp += MAXGRP;
+ }
+ if (*s == ',') {
+ if (cp) {
+ *s = '\0';
+ *m++ = cp;
+ cp = NULL;
+ }
+ } else if (*s == '\0' || *s == '\n' || *s == ' ') {
+ if (cp) {
+ *s = '\0';
+ *m++ = cp;
+ }
+ break;
+ } else if (cp == NULL) {
+ cp = s;
+ }
+ }
+ _gr_group.gr_mem = members;
+ *m = NULL;
+
+ return 1;
+}
+
+static char *_gr_yp_domain;
+
+static int
+_getypgroup(struct group *gr, const char *name, char *map)
+{
+ char *result, *s;
+ static char resultbuf[YPMAXRECORD + 2];
+ int resultlen;
+
+ if(!_gr_yp_domain) {
+ if(yp_get_default_domain(&_gr_yp_domain))
+ return 0;
+ }
+
+ if(yp_match(_gr_yp_domain, map, name, strlen(name),
+ &result, &resultlen))
+ return 0;
+
+ s = strchr(result, '\n');
+ if(s) *s = '\0';
+
+ if(resultlen >= sizeof resultbuf) return 0;
+ strncpy(resultbuf, result, resultlen);
+ resultbuf[resultlen] = '\0';
+ free(result);
+ return(_gr_breakout_yp(gr, resultbuf));
+
+}
+
+
+static int
+_nextypgroup(struct group *gr)
+{
+ static char *key;
+ static int keylen;
+ char *lastkey, *result;
+ static char resultbuf[YPMAXRECORD + 2];
+ int resultlen;
+ int rv;
+
+ if(!_gr_yp_domain) {
+ if(yp_get_default_domain(&_gr_yp_domain))
+ return 0;
+ }
+
+ if(!_gr_stepping_yp) {
+ if(key) free(key);
+ rv = yp_first(_gr_yp_domain, "group.byname",
+ &key, &keylen, &result, &resultlen);
+ if(rv) {
+ return 0;
+ }
+ _gr_stepping_yp = 1;
+ goto unpack;
+ } else {
+tryagain:
+ lastkey = key;
+ rv = yp_next(_gr_yp_domain, "group.byname", key, keylen,
+ &key, &keylen, &result, &resultlen);
+ free(lastkey);
+unpack:
+ if(rv) {
+ _gr_stepping_yp = 0;
+ return 0;
+ }
+
+ if(resultlen > sizeof(resultbuf)) {
+ free(result);
+ goto tryagain;
+ }
+
+ strncpy(resultbuf, result, resultlen);
+ resultbuf[resultlen] = '\0';
+ free(result);
+ if((result = strchr(resultbuf, '\n')) != NULL)
+ *result = '\0';
+ if (_gr_breakout_yp(gr, resultbuf))
+ return(1);
+ else
+ goto tryagain;
+ }
+}
+
+#endif /* YP */
diff --git a/lib/libc/gen/getgrouplist.3 b/lib/libc/gen/getgrouplist.3
new file mode 100644
index 0000000..e85eaa5
--- /dev/null
+++ b/lib/libc/gen/getgrouplist.3
@@ -0,0 +1,94 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getgrouplist.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt GETGROUPLIST 3
+.Os
+.Sh NAME
+.Nm getgrouplist
+.Nd calculate group access list
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn getgrouplist "const char *name" "int basegid" "int *groups" "int *ngroups"
+.Sh DESCRIPTION
+The
+.Fn getgrouplist
+function reads through the group file and calculates
+the group access list for the user specified in
+.Fa name .
+The
+.Fa basegid
+is automatically included in the groups list.
+Typically this value is given as
+the group number from the password file.
+.Pp
+The resulting group list is returned in the integer array pointed to by
+.Fa groups .
+The caller specifies the size of the
+.Fa groups
+array in the integer pointed to by
+.Fa ngroups ;
+the actual number of groups found is returned in
+.Fa ngroups .
+.Sh RETURN VALUES
+The
+.Fn getgrouplist
+function
+returns \-1 if the size of the group list is too small to
+hold all the user's groups.
+Here, the group array will be filled with as many groups as will fit.
+.Sh FILES
+.Bl -tag -width /etc/group -compact
+.It Pa /etc/group
+group membership list
+.El
+.Sh SEE ALSO
+.Xr setgroups 2 ,
+.Xr initgroups 3
+.Sh HISTORY
+The
+.Fn getgrouplist
+function first appeared in
+.Bx 4.4 .
+.Sh BUGS
+The
+.Fn getgrouplist
+function
+uses the routines based on
+.Xr getgrent 3 .
+If the invoking program uses any of these routines,
+the group structure will
+be overwritten in the call to
+.Fn getgrouplist .
diff --git a/lib/libc/gen/getgrouplist.c b/lib/libc/gen/getgrouplist.c
new file mode 100644
index 0000000..31f90b4
--- /dev/null
+++ b/lib/libc/gen/getgrouplist.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getgrouplist.c 8.2 (Berkeley) 12/8/94";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * get credential
+ */
+#include <sys/types.h>
+#include <string.h>
+#include <grp.h>
+
+int
+getgrouplist(uname, agroup, groups, grpcnt)
+ const char *uname;
+ int agroup;
+ register int *groups;
+ int *grpcnt;
+{
+ register struct group *grp;
+ register int i, ngroups;
+ int ret, maxgroups;
+
+ ret = 0;
+ ngroups = 0;
+ maxgroups = *grpcnt;
+ /*
+ * When installing primary group, duplicate it;
+ * the first element of groups is the effective gid
+ * and will be overwritten when a setgid file is executed.
+ */
+ groups[ngroups++] = agroup;
+ if (maxgroups > 1)
+ groups[ngroups++] = agroup;
+ /*
+ * Scan the group file to find additional groups.
+ */
+ setgrent();
+ while (grp = getgrent()) {
+ for (i = 0; i < ngroups; i++) {
+ if (grp->gr_gid == groups[i])
+ goto skip;
+ }
+ for (i = 0; grp->gr_mem[i]; i++) {
+ if (!strcmp(grp->gr_mem[i], uname)) {
+ if (ngroups >= maxgroups) {
+ ret = -1;
+ break;
+ }
+ groups[ngroups++] = grp->gr_gid;
+ break;
+ }
+ }
+skip:
+ }
+ endgrent();
+ *grpcnt = ngroups;
+ return (ret);
+}
diff --git a/lib/libc/gen/gethostname.3 b/lib/libc/gen/gethostname.3
new file mode 100644
index 0000000..f4d2d04
--- /dev/null
+++ b/lib/libc/gen/gethostname.3
@@ -0,0 +1,98 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)gethostname.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETHOSTNAME 3
+.Os BSD 4.2
+.Sh NAME
+.Nm gethostname ,
+.Nm sethostname
+.Nd get/set name of current host
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn gethostname "char *name" "int namelen"
+.Ft int
+.Fn sethostname "const char *name" "int namelen"
+.Sh DESCRIPTION
+.Fn Gethostname
+returns the standard host name for the current processor, as
+previously set by
+.Fn sethostname .
+The parameter
+.Fa namelen
+specifies the size of the
+.Fa name
+array. The returned name is null-terminated unless insufficient
+space is provided.
+.Pp
+.Fn Sethostname
+sets the name of the host machine to be
+.Fa name ,
+which has length
+.Fa namelen .
+This call is restricted to the super-user and
+is normally used only when the system is bootstrapped.
+.Sh RETURN VALUES
+If the call succeeds a value of 0 is returned. If the call
+fails, a value of -1 is returned and an error code is
+placed in the global location
+.Va errno .
+.Sh ERRORS
+The following errors may be returned by these calls:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+The
+.Fa name
+or
+.Fa namelen
+parameter gave an
+invalid address.
+.It Bq Er EPERM
+The caller tried to set the hostname and was not the super-user.
+.El
+.Sh SEE ALSO
+.Xr gethostid 3 ,
+.Xr sysctl 3
+.Sh BUGS
+Host names are limited to
+.Dv MAXHOSTNAMELEN
+(from
+.Ao Pa sys/param.h Ac )
+characters, currently 256.
+.Sh HISTORY
+The
+.Fn gethostname
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/gen/gethostname.c b/lib/libc/gen/gethostname.c
new file mode 100644
index 0000000..64bd64d
--- /dev/null
+++ b/lib/libc/gen/gethostname.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostname.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+int
+gethostname(name, namelen)
+ char *name;
+ int namelen;
+{
+ int mib[2];
+ size_t size;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_HOSTNAME;
+ size = namelen;
+ if (sysctl(mib, 2, name, &size, NULL, 0) == -1)
+ return (-1);
+ return (0);
+}
diff --git a/lib/libc/gen/getloadavg.3 b/lib/libc/gen/getloadavg.3
new file mode 100644
index 0000000..737f699
--- /dev/null
+++ b/lib/libc/gen/getloadavg.3
@@ -0,0 +1,67 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getloadavg.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETLOADAVG 3
+.Os
+.Sh NAME
+.Nm getloadavg
+.Nd get system load averages
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft int
+.Fn getloadavg "double loadavg[]" "int nelem"
+.Sh DESCRIPTION
+The
+.Fn getloadavg
+function returns the number of processes in the system run queue
+averaged over various periods of time.
+Up to
+.Fa nelem
+samples are retrieved and assigned to successive elements of
+.Fa loadavg Ns Bq .
+The system imposes a maximum of 3 samples, representing averages
+over the last 1, 5, and 15 minutes, respectively.
+.Sh DIAGNOSTICS
+If the load average was unobtainable, \-1 is returned; otherwise,
+the number of samples actually retrieved is returned.
+.Sh SEE ALSO
+.Xr uptime 1 ,
+.Xr kvm_getloadavg 3 ,
+.Xr sysctl 3
+.Sh HISTORY
+The
+.Fn getloadavg
+function appeared in
+.Bx 4.3 Reno .
diff --git a/lib/libc/gen/getloadavg.c b/lib/libc/gen/getloadavg.c
new file mode 100644
index 0000000..811dbda
--- /dev/null
+++ b/lib/libc/gen/getloadavg.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getloadavg.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/sysctl.h>
+#include <vm/vm_param.h>
+
+#include <stdlib.h>
+
+/*
+ * getloadavg() -- Get system load averages.
+ *
+ * Put `nelem' samples into `loadavg' array.
+ * Return number of samples retrieved, or -1 on error.
+ */
+int
+getloadavg(loadavg, nelem)
+ double loadavg[];
+ int nelem;
+{
+ struct loadavg loadinfo;
+ int i, mib[2];
+ size_t size;
+
+ mib[0] = CTL_VM;
+ mib[1] = VM_LOADAVG;
+ size = sizeof(loadinfo);
+ if (sysctl(mib, 2, &loadinfo, &size, NULL, 0) < 0)
+ return (-1);
+
+ nelem = MIN(nelem, sizeof(loadinfo.ldavg) / sizeof(fixpt_t));
+ for (i = 0; i < nelem; i++)
+ loadavg[i] = (double) loadinfo.ldavg[i] / loadinfo.fscale;
+ return (nelem);
+}
diff --git a/lib/libc/gen/getlogin.c b/lib/libc/gen/getlogin.c
new file mode 100644
index 0000000..044689d
--- /dev/null
+++ b/lib/libc/gen/getlogin.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getlogin.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <pwd.h>
+#include <utmp.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+int _logname_valid; /* known to setlogin() */
+
+char *
+getlogin()
+{
+ static char logname[MAXLOGNAME];
+
+ if (_logname_valid == 0) {
+#ifdef __NETBSD_SYSCALLS
+ if (__getlogin(logname, sizeof(logname) - 1) < 0)
+#else
+ if (_getlogin(logname, sizeof(logname)) < 0)
+#endif
+ return ((char *)NULL);
+ _logname_valid = 1;
+ }
+ return (*logname ? logname : (char *)NULL);
+}
+
+
+char *
+getlogin_r(char *logname, int namelen)
+{
+ if (_logname_valid == 0) {
+#ifdef __NETBSD_SYSCALLS
+ if (__getlogin(logname, namelen - 1) < 0)
+#else
+ if (_getlogin(logname, namelen) < 0)
+#endif
+ return ((char *)NULL);
+ _logname_valid = 1;
+ }
+ return (*logname ? logname : (char *)NULL);
+}
diff --git a/lib/libc/gen/getmntinfo.3 b/lib/libc/gen/getmntinfo.3
new file mode 100644
index 0000000..d20fc5b
--- /dev/null
+++ b/lib/libc/gen/getmntinfo.3
@@ -0,0 +1,110 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getmntinfo.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt GETMNTINFO 3
+.Os
+.Sh NAME
+.Nm getmntinfo
+.Nd get information about mounted file systems
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/ucred.h>
+.Fd #include <sys/mount.h>
+.Ft int
+.Fn getmntinfo "struct statfs **mntbufp" "int flags"
+.Sh DESCRIPTION
+The
+.Fn getmntinfo
+function
+returns an array of
+.Fn statfs
+structures describing each currently mounted file system (see
+.Xr statfs 2 ) .
+.Pp
+The
+.Fn getmntinfo
+function
+passes its
+.Fa flags
+parameter transparently to
+.Xr getfsstat 2 .
+.Sh RETURN VALUES
+On successful completion,
+.Fn getmntinfo
+returns a count of the number of elements in the array.
+The pointer to the array is stored into
+.Fa mntbufp .
+.Pp
+If an error occurs, zero is returned and the external variable
+.Va errno
+is set to indicate the error.
+Although the pointer
+.Fa mntbufp
+will be unmodified, any information previously returned by
+.Fn getmntinfo
+will be lost.
+.Sh ERRORS
+The
+.Fn getmntinfo
+function
+may fail and set errno for any of the errors specified for the library
+routines
+.Xr getfsstat 2
+or
+.Xr malloc 3 .
+.Sh SEE ALSO
+.Xr getfsstat 2 ,
+.Xr mount 2 ,
+.Xr statfs 2 ,
+.Xr mount 8
+.Sh HISTORY
+The
+.Fn getmntinfo
+function first appeared in
+.Bx 4.4 .
+.Sh BUGS
+The
+.Fn getmntinfo
+function writes the array of structures to an internal static object
+and returns
+a pointer to that object. Subsequent calls to
+.Fn getmntinfo
+will modify the same object.
+.Pp
+The memory allocated by
+.Fn getmntinfo
+cannot be
+.Xr free 3 Ns 'd
+by the application.
diff --git a/lib/libc/gen/getmntinfo.c b/lib/libc/gen/getmntinfo.c
new file mode 100644
index 0000000..6e167a3
--- /dev/null
+++ b/lib/libc/gen/getmntinfo.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getmntinfo.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#include <stdlib.h>
+
+/*
+ * Return information about mounted filesystems.
+ */
+int
+getmntinfo(mntbufp, flags)
+ struct statfs **mntbufp;
+ int flags;
+{
+ static struct statfs *mntbuf;
+ static int mntsize;
+ static long bufsize;
+
+ if (mntsize <= 0 && (mntsize = getfsstat(0, 0, MNT_NOWAIT)) < 0)
+ return (0);
+ if (bufsize > 0 && (mntsize = getfsstat(mntbuf, bufsize, flags)) < 0)
+ return (0);
+ while (bufsize <= mntsize * sizeof(struct statfs)) {
+ if (mntbuf)
+ free(mntbuf);
+ bufsize = (mntsize + 1) * sizeof(struct statfs);
+ if ((mntbuf = (struct statfs *)malloc(bufsize)) == 0)
+ return (0);
+ if ((mntsize = getfsstat(mntbuf, bufsize, flags)) < 0)
+ return (0);
+ }
+ *mntbufp = mntbuf;
+ return (mntsize);
+}
diff --git a/lib/libc/gen/getnetgrent.3 b/lib/libc/gen/getnetgrent.3
new file mode 100644
index 0000000..db8f550
--- /dev/null
+++ b/lib/libc/gen/getnetgrent.3
@@ -0,0 +1,129 @@
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getnetgrent.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETNETGRENT 3
+.Os
+.Sh NAME
+.Nm getnetgrent ,
+.Nm innetgr ,
+.Nm setnetgrent ,
+.Nm endnetgrent
+.Nd netgroup database operations
+.Sh SYNOPSIS
+.Ft int
+.Fn getnetgrent "char **host" "char **user" "char **domain"
+.Ft int
+.Fn innetgr "const char *netgroup" "const char *host" "const char *user" "const char *domain"
+.Ft void
+.Fn setnetgrent "const char *netgroup"
+.Ft void
+.Fn endnetgrent void
+.Sh DESCRIPTION
+These functions operate on the netgroup database file
+.Pa /etc/netgroup
+which is described
+in
+.Xr netgroup 5 .
+The database defines a set of netgroups, each made up of one or more triples:
+.Bd -literal -offset indent
+(host, user, domain)
+.Ed
+that defines a combination of host, user and domain.
+Any of the three fields may be specified as ``wildcards'' that match any
+string.
+.Pp
+The function
+.Fn getnetgrent
+sets the three pointer arguments to the strings of the next member of the
+current netgroup.
+If any of the string pointers are
+.Sy (char *)0
+that field is considered a wildcard.
+.Pp
+The functions
+.Fn setnetgrent
+and
+.Fn endnetgrent
+set the current netgroup and terminate the current netgroup respectively.
+If
+.Fn setnetgrent
+is called with a different netgroup than the previous call, an implicit
+.Fn endnetgrent
+is implied.
+.Fn Setnetgrent
+also sets the offset to the first member of the netgroup.
+.Pp
+The function
+.Fn innetgr
+searches for a match of all fields within the specified group.
+If any of the
+.Sy host ,
+.Sy user ,
+or
+.Sy domain
+arguments are
+.Sy (char *)0
+those fields will match any string value in the netgroup member.
+.Sh RETURN VALUES
+The function
+.Fn getnetgrent
+returns 0 for ``no more netgroup members'' and 1 otherwise.
+The function
+.Fn innetgr
+returns 1 for a successful match and 0 otherwise.
+The functions
+.Fn setnetgrent
+and
+.Fn endnetgrent
+have no return value.
+.Sh FILES
+.Bl -tag -width /etc/netgroup -compact
+.It Pa /etc/netgroup
+netgroup database file
+.El
+.Sh SEE ALSO
+.Xr netgroup 5
+.Sh COMPATIBILITY
+The netgroup members have three string fields to maintain compatibility
+with other vendor implementations, however it is not obvious what use the
+.Sy domain
+string has within BSD.
+.Sh BUGS
+The function
+.Fn getnetgrent
+returns pointers to dynamically allocated data areas that are freed when
+the function
+.Fn endnetgrent
+is called.
diff --git a/lib/libc/gen/getnetgrent.c b/lib/libc/gen/getnetgrent.c
new file mode 100644
index 0000000..a26c86c
--- /dev/null
+++ b/lib/libc/gen/getnetgrent.c
@@ -0,0 +1,634 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetgrent.c 8.2 (Berkeley) 4/27/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef YP
+/*
+ * Notes:
+ * We want to be able to use NIS netgroups properly while retaining
+ * the ability to use a local /etc/netgroup file. Unfortunately, you
+ * can't really do both at the same time - at least, not efficiently.
+ * NetBSD deals with this problem by creating a netgroup database
+ * using Berkeley DB (just like the password database) that allows
+ * for lookups using netgroup, netgroup.byuser or netgroup.byhost
+ * searches. This is a neat idea, but I don't have time to implement
+ * something like that now. (I think ultimately it would be nice
+ * if we DB-fied the group and netgroup stuff all in one shot, but
+ * for now I'm satisfied just to have something that works well
+ * without requiring massive code changes.)
+ *
+ * Therefore, to still permit the use of the local file and maintain
+ * optimum NIS performance, we allow for the following conditions:
+ *
+ * - If /etc/netgroup does not exist and NIS is turned on, we use
+ * NIS netgroups only.
+ *
+ * - If /etc/netgroup exists but is empty, we use NIS netgroups
+ * only.
+ *
+ * - If /etc/netgroup exists and contains _only_ a '+', we use
+ * NIS netgroups only.
+ *
+ * - If /etc/netgroup exists, contains locally defined netgroups
+ * and a '+', we use a mixture of NIS and the local entries.
+ * This method should return the same NIS data as just using
+ * NIS alone, but it will be slower if the NIS netgroup database
+ * is large (innetgr() in particular will suffer since extra
+ * processing has to be done in order to determine memberships
+ * using just the raw netgroup data).
+ *
+ * - If /etc/netgroup exists and contains only locally defined
+ * netgroup entries, we use just those local entries and ignore
+ * NIS (this is the original, pre-NIS behavior).
+ */
+
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+static char *_netgr_yp_domain;
+int _use_only_yp;
+static int _netgr_yp_enabled;
+static int _yp_innetgr;
+#endif
+
+#ifndef _PATH_NETGROUP
+#define _PATH_NETGROUP "/etc/netgroup"
+#endif
+
+/*
+ * Static Variables and functions used by setnetgrent(), getnetgrent() and
+ * endnetgrent().
+ * There are two linked lists:
+ * - linelist is just used by setnetgrent() to parse the net group file via.
+ * parse_netgrp()
+ * - netgrp is the list of entries for the current netgroup
+ */
+struct linelist {
+ struct linelist *l_next; /* Chain ptr. */
+ int l_parsed; /* Flag for cycles */
+ char *l_groupname; /* Name of netgroup */
+ char *l_line; /* Netgroup entrie(s) to be parsed */
+};
+
+struct netgrp {
+ struct netgrp *ng_next; /* Chain ptr */
+ char *ng_str[3]; /* Field pointers, see below */
+};
+#define NG_HOST 0 /* Host name */
+#define NG_USER 1 /* User name */
+#define NG_DOM 2 /* and Domain name */
+
+static struct linelist *linehead = (struct linelist *)0;
+static struct netgrp *nextgrp = (struct netgrp *)0;
+static struct {
+ struct netgrp *gr;
+ char *grname;
+} grouphead = {
+ (struct netgrp *)0,
+ (char *)0,
+};
+static FILE *netf = (FILE *)0;
+static int parse_netgrp();
+static struct linelist *read_for_group();
+void setnetgrent(), endnetgrent();
+int getnetgrent(), innetgr();
+
+#define LINSIZ 1024 /* Length of netgroup file line */
+
+/*
+ * setnetgrent()
+ * Parse the netgroup file looking for the netgroup and build the list
+ * of netgrp structures. Let parse_netgrp() and read_for_group() do
+ * most of the work.
+ */
+void
+setnetgrent(group)
+ char *group;
+{
+#ifdef YP
+ struct stat _yp_statp;
+ char _yp_plus;
+#endif
+
+ /* Sanity check */
+
+ if (group == NULL || !strlen(group))
+ return;
+
+ if (grouphead.gr == (struct netgrp *)0 ||
+ strcmp(group, grouphead.grname)) {
+ endnetgrent();
+#ifdef YP
+ /* Presumed guilty until proven innocent. */
+ _use_only_yp = 0;
+ /*
+ * If /etc/netgroup doesn't exist or is empty,
+ * use NIS exclusively.
+ */
+ if (((stat(_PATH_NETGROUP, &_yp_statp) < 0) &&
+ errno == ENOENT) || _yp_statp.st_size == 0)
+ _use_only_yp = _netgr_yp_enabled = 1;
+ if ((netf = fopen(_PATH_NETGROUP,"r")) != NULL ||_use_only_yp){
+ /*
+ * Icky: grab the first character of the netgroup file
+ * and turn on NIS if it's a '+'. rewind the stream
+ * afterwards so we don't goof up read_for_group() later.
+ */
+ if (netf) {
+ fscanf(netf, "%c", &_yp_plus);
+ rewind(netf);
+ if (_yp_plus == '+')
+ _use_only_yp = _netgr_yp_enabled = 1;
+ }
+ /*
+ * If we were called specifically for an innetgr()
+ * lookup and we're in NIS-only mode, short-circuit
+ * parse_netgroup() and cut directly to the chase.
+ */
+ if (_use_only_yp && _yp_innetgr) {
+ /* dohw! */
+ if (netf != NULL)
+ fclose(netf);
+ return;
+ }
+#else
+ if (netf = fopen(_PATH_NETGROUP, "r")) {
+#endif
+ if (parse_netgrp(group))
+ endnetgrent();
+ else {
+ grouphead.grname = (char *)
+ malloc(strlen(group) + 1);
+ strcpy(grouphead.grname, group);
+ }
+ if (netf)
+ fclose(netf);
+ }
+ }
+ nextgrp = grouphead.gr;
+}
+
+/*
+ * Get the next netgroup off the list.
+ */
+int
+getnetgrent(hostp, userp, domp)
+ char **hostp, **userp, **domp;
+{
+#ifdef YP
+ _yp_innetgr = 0;
+#endif
+
+ if (nextgrp) {
+ *hostp = nextgrp->ng_str[NG_HOST];
+ *userp = nextgrp->ng_str[NG_USER];
+ *domp = nextgrp->ng_str[NG_DOM];
+ nextgrp = nextgrp->ng_next;
+ return (1);
+ }
+ return (0);
+}
+
+/*
+ * endnetgrent() - cleanup
+ */
+void
+endnetgrent()
+{
+ register struct linelist *lp, *olp;
+ register struct netgrp *gp, *ogp;
+
+ lp = linehead;
+ while (lp) {
+ olp = lp;
+ lp = lp->l_next;
+ free(olp->l_groupname);
+ free(olp->l_line);
+ free((char *)olp);
+ }
+ linehead = (struct linelist *)0;
+ if (grouphead.grname) {
+ free(grouphead.grname);
+ grouphead.grname = (char *)0;
+ }
+ gp = grouphead.gr;
+ while (gp) {
+ ogp = gp;
+ gp = gp->ng_next;
+ if (ogp->ng_str[NG_HOST])
+ free(ogp->ng_str[NG_HOST]);
+ if (ogp->ng_str[NG_USER])
+ free(ogp->ng_str[NG_USER]);
+ if (ogp->ng_str[NG_DOM])
+ free(ogp->ng_str[NG_DOM]);
+ free((char *)ogp);
+ }
+ grouphead.gr = (struct netgrp *)0;
+#ifdef YP
+ _netgr_yp_enabled = 0;
+#endif
+}
+
+#ifdef YP
+static int _listmatch(list, group, len)
+ char *list, *group;
+ int len;
+{
+ char *ptr = list, *cptr;
+ int glen = strlen(group);
+
+ /* skip possible leading whitespace */
+ while(isspace((unsigned char)*ptr))
+ ptr++;
+
+ while (ptr < list + len) {
+ cptr = ptr;
+ while(*ptr != ',' && *ptr != '\0' && !isspace((unsigned char)*ptr))
+ ptr++;
+ if (strncmp(cptr, group, glen) == 0 && glen == (ptr - cptr))
+ return(1);
+ while(*ptr == ',' || isspace((unsigned char)*ptr))
+ ptr++;
+ }
+
+ return(0);
+}
+
+static int _buildkey(key, str, dom, rotation)
+char *key, *str, *dom;
+int *rotation;
+{
+ (*rotation)++;
+ if (*rotation > 4)
+ return(0);
+ switch(*rotation) {
+ case(1): sprintf((char *)key, "%s.%s", str, dom ? dom : "*");
+ break;
+ case(2): sprintf((char *)key, "%s.*", str);
+ break;
+ case(3): sprintf((char *)key, "*.%s", dom ? dom : "*");
+ break;
+ case(4): sprintf((char *)key, "*.*");
+ break;
+ }
+ return(1);
+}
+#endif
+
+/*
+ * Search for a match in a netgroup.
+ */
+int
+innetgr(group, host, user, dom)
+ const char *group, *host, *user, *dom;
+{
+ char *hst, *usr, *dm;
+#ifdef YP
+ char *result;
+ int resultlen;
+ int rv;
+#endif
+ /* Sanity check */
+
+ if (group == NULL || !strlen(group))
+ return (0);
+
+#ifdef YP
+ _yp_innetgr = 1;
+#endif
+ setnetgrent(group);
+#ifdef YP
+ _yp_innetgr = 0;
+ /*
+ * If we're in NIS-only mode, do the search using
+ * NIS 'reverse netgroup' lookups.
+ */
+ if (_use_only_yp) {
+ char _key[MAXHOSTNAMELEN];
+ int rot = 0, y = 0;
+
+ if(yp_get_default_domain(&_netgr_yp_domain))
+ return(0);
+ while(_buildkey(_key, user ? user : host, dom, &rot)) {
+ y = yp_match(_netgr_yp_domain, user? "netgroup.byuser":
+ "netgroup.byhost", _key, strlen(_key), &result,
+ &resultlen);
+ if (y) {
+ /*
+ * If we get an error other than 'no
+ * such key in map' then something is
+ * wrong and we should stop the search.
+ */
+ if (y != YPERR_KEY)
+ break;
+ } else {
+ rv = _listmatch(result, group, resultlen);
+ free(result);
+ if (rv)
+ return(1);
+ else
+ return(0);
+ }
+ }
+ /*
+ * Couldn't match using NIS-exclusive mode. If the error
+ * was YPERR_MAP, then the failure happened because there
+ * was no netgroup.byhost or netgroup.byuser map. The odds
+ * are we are talking to an Sun NIS+ server in YP emulation
+ * mode; if this is the case, then we have to do the check
+ * the 'old-fashioned' way by grovelling through the netgroup
+ * map and resolving memberships on the fly.
+ */
+ if (y != YPERR_MAP)
+ return(0);
+ }
+
+ setnetgrent(group);
+#endif /* YP */
+
+ while (getnetgrent(&hst, &usr, &dm))
+ if ((host == NULL || hst == NULL || !strcmp(host, hst)) &&
+ (user == NULL || usr == NULL || !strcmp(user, usr)) &&
+ ( dom == NULL || dm == NULL || !strcmp(dom, dm))) {
+ endnetgrent();
+ return (1);
+ }
+ endnetgrent();
+ return (0);
+}
+
+/*
+ * Parse the netgroup file setting up the linked lists.
+ */
+static int
+parse_netgrp(group)
+ char *group;
+{
+ register char *spos, *epos;
+ register int len, strpos;
+#ifdef DEBUG
+ register int fields;
+#endif
+ char *pos, *gpos;
+ struct netgrp *grp;
+ struct linelist *lp = linehead;
+
+ /*
+ * First, see if the line has already been read in.
+ */
+ while (lp) {
+ if (!strcmp(group, lp->l_groupname))
+ break;
+ lp = lp->l_next;
+ }
+ if (lp == (struct linelist *)0 &&
+ (lp = read_for_group(group)) == (struct linelist *)0)
+ return (1);
+ if (lp->l_parsed) {
+#ifdef DEBUG
+ /*
+ * This error message is largely superflous since the
+ * code handles the error condition sucessfully, and
+ * spewing it out from inside libc can actually hose
+ * certain programs.
+ */
+ fprintf(stderr, "Cycle in netgroup %s\n", lp->l_groupname);
+#endif
+ return (1);
+ } else
+ lp->l_parsed = 1;
+ pos = lp->l_line;
+ /* Watch for null pointer dereferences, dammit! */
+ while (pos != NULL && *pos != '\0') {
+ if (*pos == '(') {
+ grp = (struct netgrp *)malloc(sizeof (struct netgrp));
+ bzero((char *)grp, sizeof (struct netgrp));
+ grp->ng_next = grouphead.gr;
+ grouphead.gr = grp;
+ pos++;
+ gpos = strsep(&pos, ")");
+#ifdef DEBUG
+ fields = 0;
+#endif
+ for (strpos = 0; strpos < 3; strpos++) {
+ if ((spos = strsep(&gpos, ","))) {
+#ifdef DEBUG
+ fields++;
+#endif
+ while (*spos == ' ' || *spos == '\t')
+ spos++;
+ if ((epos = strpbrk(spos, " \t"))) {
+ *epos = '\0';
+ len = epos - spos;
+ } else
+ len = strlen(spos);
+ if (len > 0) {
+ grp->ng_str[strpos] = (char *)
+ malloc(len + 1);
+ bcopy(spos, grp->ng_str[strpos],
+ len + 1);
+ }
+ } else {
+ /*
+ * All other systems I've tested
+ * return NULL for empty netgroup
+ * fields. It's up to user programs
+ * to handle the NULLs appropriately.
+ */
+ grp->ng_str[strpos] = NULL;
+ }
+ }
+#ifdef DEBUG
+ /*
+ * Note: on other platforms, malformed netgroup
+ * entries are not normally flagged. While we
+ * can catch bad entries and report them, we should
+ * stay silent by default for compatibility's sake.
+ */
+ if (fields < 3)
+ fprintf(stderr, "Bad entry (%s%s%s%s%s) in netgroup \"%s\"\n",
+ grp->ng_str[NG_HOST] == NULL ? "" : grp->ng_str[NG_HOST],
+ grp->ng_str[NG_USER] == NULL ? "" : ",",
+ grp->ng_str[NG_USER] == NULL ? "" : grp->ng_str[NG_USER],
+ grp->ng_str[NG_DOM] == NULL ? "" : ",",
+ grp->ng_str[NG_DOM] == NULL ? "" : grp->ng_str[NG_DOM],
+ lp->l_groupname);
+#endif
+ } else {
+ spos = strsep(&pos, ", \t");
+ if (parse_netgrp(spos))
+ continue;
+ }
+ if (pos == NULL)
+ break;
+ while (*pos == ' ' || *pos == ',' || *pos == '\t')
+ pos++;
+ }
+ return (0);
+}
+
+/*
+ * Read the netgroup file and save lines until the line for the netgroup
+ * is found. Return 1 if eof is encountered.
+ */
+static struct linelist *
+read_for_group(group)
+ char *group;
+{
+ register char *pos, *spos, *linep, *olinep;
+ register int len, olen;
+ int cont;
+ struct linelist *lp;
+ char line[LINSIZ + 2];
+#ifdef YP
+ char *result;
+ int resultlen;
+
+ while (_netgr_yp_enabled || fgets(line, LINSIZ, netf) != NULL) {
+ if (_netgr_yp_enabled) {
+ if(!_netgr_yp_domain)
+ if(yp_get_default_domain(&_netgr_yp_domain))
+ continue;
+ if (yp_match(_netgr_yp_domain, "netgroup", group,
+ strlen(group), &result, &resultlen)) {
+ free(result);
+ if (_use_only_yp)
+ return ((struct linelist *)0);
+ else {
+ _netgr_yp_enabled = 0;
+ continue;
+ }
+ }
+ snprintf(line, LINSIZ, "%s %s", group, result);
+ free(result);
+ }
+#else
+ while (fgets(line, LINSIZ, netf) != NULL) {
+#endif
+ pos = (char *)&line;
+#ifdef YP
+ if (*pos == '+') {
+ _netgr_yp_enabled = 1;
+ continue;
+ }
+#endif
+ if (*pos == '#')
+ continue;
+ while (*pos == ' ' || *pos == '\t')
+ pos++;
+ spos = pos;
+ while (*pos != ' ' && *pos != '\t' && *pos != '\n' &&
+ *pos != '\0')
+ pos++;
+ len = pos - spos;
+ while (*pos == ' ' || *pos == '\t')
+ pos++;
+ if (*pos != '\n' && *pos != '\0') {
+ lp = (struct linelist *)malloc(sizeof (*lp));
+ lp->l_parsed = 0;
+ lp->l_groupname = (char *)malloc(len + 1);
+ bcopy(spos, lp->l_groupname, len);
+ *(lp->l_groupname + len) = '\0';
+ len = strlen(pos);
+ olen = 0;
+
+ /*
+ * Loop around handling line continuations.
+ */
+ do {
+ if (*(pos + len - 1) == '\n')
+ len--;
+ if (*(pos + len - 1) == '\\') {
+ len--;
+ cont = 1;
+ } else
+ cont = 0;
+ if (len > 0) {
+ linep = (char *)malloc(olen + len + 1);
+ if (olen > 0) {
+ bcopy(olinep, linep, olen);
+ free(olinep);
+ }
+ bcopy(pos, linep + olen, len);
+ olen += len;
+ *(linep + olen) = '\0';
+ olinep = linep;
+ }
+ if (cont) {
+ if (fgets(line, LINSIZ, netf)) {
+ pos = line;
+ len = strlen(pos);
+ } else
+ cont = 0;
+ }
+ } while (cont);
+ lp->l_line = linep;
+ lp->l_next = linehead;
+ linehead = lp;
+
+ /*
+ * If this is the one we wanted, we are done.
+ */
+ if (!strcmp(lp->l_groupname, group))
+ return (lp);
+ }
+ }
+#ifdef YP
+ /*
+ * Yucky. The recursive nature of this whole mess might require
+ * us to make more than one pass through the netgroup file.
+ * This might be best left outside the #ifdef YP, but YP is
+ * defined by default anyway, so I'll leave it like this
+ * until I know better.
+ */
+ rewind(netf);
+#endif
+ return ((struct linelist *)0);
+}
diff --git a/lib/libc/gen/getobjformat.3 b/lib/libc/gen/getobjformat.3
new file mode 100644
index 0000000..3862d82
--- /dev/null
+++ b/lib/libc/gen/getobjformat.3
@@ -0,0 +1,124 @@
+.\" Copyright (c) 1998 John D. Polstra
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 7, 1998
+.Dt GETOBJFORMAT 3
+.Os FreeBSD
+.Sh NAME
+.Nm getobjformat
+.Nd get preferred object file format
+.Sh SYNOPSIS
+.Fd #include <objformat.h>
+.Ft int
+.Fn getobjformat "char *buf" "size_t bufsize" "int *argcp" "char **argv"
+.Sh DESCRIPTION
+.Fn getobjformat
+queries several sources to determine the preferred object file
+format, and copies its name into a buffer provided by the caller.
+.Pp
+The object file format is determined as follows. If
+.Va argv
+is
+.No non- Ns Ev NULL
+and an explicit command line argument such as
+.Fl aout
+or
+.Fl elf
+is present, then that determines the object file format.
+.Pp
+Otherwise, if the variable
+.Ev OBJFORMAT
+is set in the environment, the object file format is taken from its
+value.
+.Pp
+Otherwise, if the file
+.Pa /etc/objformat
+is readable and contains a line of the form
+.Ql OBJFORMAT=xxx ,
+the object file format is taken from there.
+.Pp
+Otherwise, a built-in system default object file format is returned.
+.Pp
+.Va buf
+points to a user-supplied buffer into which the name of the object
+file format is copied.
+.Va bufsize
+gives the size of the buffer in bytes. The string placed in
+.Va buf
+is always null-terminated. It is an error if the buffer is too
+small to hold the null-terminated name.
+.Pp
+.Va argv
+points to a
+.Dv NULL Ns -terminated
+argument vector to be scanned for object
+format options.
+.Va argv
+may be
+.Dv NULL ,
+in which case the argument vector is not scanned.
+.Pp
+If
+.Va argcp
+is non-NULL, any object format options are deleted from the
+argument vector, and the updated argument count is stored into
+the integer referenced by
+.Va argcp .
+If
+.Va argcp
+is
+.Dv NULL ,
+the argument vector is left unchanged.
+.Sh RETURN VALUES
+On success,
+.Fn getobjformat
+returns the length of the object file format name, not counting the
+null terminator.
+If the supplied buffer is too small to hold the object file format
+and its null terminator,
+.Fn getobjformat
+returns -1. In that case, the contents of the buffer and argument
+vector supplied by the caller are indeterminate.
+.Sh ENVIRONMENT
+.Bl -tag -width OBJFORMAT
+.It Ev OBJFORMAT
+If the environment variable
+.Ev OBJFORMAT
+is set, it overrides the default object file format.
+.Ev OBJFORMAT takes precedence over
+.Pa /etc/objformat .
+.Sh FILES
+.Bl -tag -width /etc/objformat -compact
+.It Pa /etc/objformat
+If present, specifies the object file format to use. Syntax is
+.Ql OBJFORMAT=xxx .
+.Sh SEE ALSO
+.Xr objformat 1
+.Sh HISTORY
+The
+.Fn getobjformat
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc/gen/getobjformat.c b/lib/libc/gen/getobjformat.c
new file mode 100644
index 0000000..98e6ab0
--- /dev/null
+++ b/lib/libc/gen/getobjformat.c
@@ -0,0 +1,119 @@
+/*-
+ * Copyright (c) 1998 John D. Polstra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <objformat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define PATH_OBJFORMAT "/etc/objformat"
+
+static int copyformat(char *, const char *, size_t);
+
+static const char *known_formats[] = { OBJFORMAT_NAMES, NULL };
+
+static int
+copyformat(char *buf, const char *fmt, size_t bufsize)
+{
+ size_t len;
+
+ len = strlen(fmt);
+ if (len > bufsize - 1)
+ return -1;
+ strcpy(buf, fmt);
+ return len;
+}
+
+int
+getobjformat(char *buf, size_t bufsize, int *argcp, char **argv)
+{
+ const char *fmt;
+ char **src, **dst;
+ const char *env;
+ FILE *fp;
+
+ fmt = NULL;
+
+ if (argv != NULL) {
+ /*
+ * Scan for arguments setting known formats, e.g., "-elf".
+ * If "argcp" is non-NULL, delete these arguments from the
+ * list and update the argument count in "*argcp".
+ */
+ for (dst = src = argv; *src != NULL; src++) {
+ if ((*src)[0] == '-') {
+ const char **p;
+
+ for (p = known_formats; *p != NULL; p++)
+ if (strcmp(*src + 1, *p) == 0)
+ break;
+ if (*p != NULL) {
+ fmt = *p;
+ if (argcp == NULL) /* Don't delete */
+ *dst++ = *src;
+ } else
+ *dst++ = *src;
+ } else
+ *dst++ = *src;
+ }
+ *dst = NULL;
+ if (argcp != NULL)
+ *argcp -= src - dst;
+ if (fmt != NULL)
+ return copyformat(buf, fmt, bufsize);
+ }
+
+ /* Check the OBJFORMAT environment variable. */
+ if ((env = getenv("OBJFORMAT")) != NULL)
+ return copyformat(buf, env, bufsize);
+
+ /* Take a look at "/etc/objformat". */
+ if ((fp = fopen(PATH_OBJFORMAT, "r")) != NULL) {
+ char line[1024];
+ int found;
+ int len;
+
+ found = len = 0;
+ while (fgets(line, sizeof line, fp) != NULL) {
+ if (strncmp(line, "OBJFORMAT=", 10) == 0) {
+ char *p = &line[10];
+
+ p[strcspn(p, " \t\n")] = '\0';
+ len = copyformat(buf, p, bufsize);
+ found = 1;
+ }
+ }
+ fclose(fp);
+ if (found)
+ return len;
+ }
+
+ /* As a last resort, use the compiled in default. */
+ return copyformat(buf, OBJFORMAT_DEFAULT, bufsize);
+}
diff --git a/lib/libc/gen/getosreldate.c b/lib/libc/gen/getosreldate.c
new file mode 100644
index 0000000..b6e91f4
--- /dev/null
+++ b/lib/libc/gen/getosreldate.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/* From:
+static char sccsid[] = "@(#)gethostid.c 8.1 (Berkeley) 6/2/93";
+*/
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#if __STDC__
+int
+getosreldate(void)
+#else
+int
+getosreldate()
+#endif
+{
+ int mib[2];
+ size_t size;
+ int value;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_OSRELDATE;
+ size = sizeof value;
+ if (sysctl(mib, 2, &value, &size, NULL, 0) == -1)
+ return (-1);
+ return (value);
+}
diff --git a/lib/libc/gen/getpagesize.3 b/lib/libc/gen/getpagesize.3
new file mode 100644
index 0000000..549cfe7
--- /dev/null
+++ b/lib/libc/gen/getpagesize.3
@@ -0,0 +1,61 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getpagesize.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETPAGESIZE 3
+.Os BSD 4.2
+.Sh NAME
+.Nm getpagesize
+.Nd get system page size
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn getpagesize void
+.Sh DESCRIPTION
+.Fn Getpagesize
+returns the number of bytes in a page.
+Page granularity is the granularity of many of the memory
+management calls.
+.Pp
+The page size is a system
+page size and may not be the same as the underlying
+hardware page size.
+.Sh SEE ALSO
+.Xr pagesize 1 ,
+.Xr sbrk 2
+.Sh HISTORY
+The
+.Fn getpagesze
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/gen/getpagesize.c b/lib/libc/gen/getpagesize.c
new file mode 100644
index 0000000..556ff9e
--- /dev/null
+++ b/lib/libc/gen/getpagesize.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getpagesize.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+/*
+ * This is unlikely to change over the running time of any
+ * program, so we cache the result to save some syscalls.
+ */
+
+int
+getpagesize()
+{
+ int mib[2];
+ static int value;
+ size_t size;
+
+ if (!value) {
+ mib[0] = CTL_HW;
+ mib[1] = HW_PAGESIZE;
+ size = sizeof value;
+ if (sysctl(mib, 2, &value, &size, NULL, 0) == -1)
+ return (-1);
+ }
+ return (value);
+}
diff --git a/lib/libc/gen/getpass.3 b/lib/libc/gen/getpass.3
new file mode 100644
index 0000000..4fe2636
--- /dev/null
+++ b/lib/libc/gen/getpass.3
@@ -0,0 +1,95 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getpass.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETPASS 3
+.Os
+.Sh NAME
+.Nm getpass
+.Nd get a password
+.Sh SYNOPSIS
+.Fd #include <pwd.h>
+.Fd #include <unistd.h>
+.Ft char *
+.Fn getpass "const char *prompt"
+.Sh DESCRIPTION
+The
+.Fn getpass
+function displays a prompt to, and reads in a password from,
+.Pa /dev/tty .
+If this file is not accessible,
+.Fn getpass
+displays the prompt on the standard error output and reads from the standard
+input.
+.Pp
+The password may be up to _PASSWORD_LEN (currently 128)
+characters in length.
+Any additional
+characters and the terminating newline character are discarded.
+.Pp
+The
+.Fn getpass
+function turns off character echoing while reading the password.
+.Pp
+.Sh RETURN VALUES
+The
+.Fn getpass
+function returns a pointer to the null terminated password.
+.Sh FILES
+.Bl -tag -width /dev/tty -compact
+.It Pa /dev/tty
+.El
+.Sh SEE ALSO
+.Xr crypt 3
+.Sh HISTORY
+A
+.Fn getpass
+function appeared in
+.At v7 .
+.Sh BUGS
+The
+.Fn getpass
+function leaves its result in an internal static object and returns
+a pointer to that object.
+Subsequent calls to
+.Fn getpass
+will modify the same object.
+.Pp
+The calling process should zero the password as soon as possible to
+avoid leaving the cleartext password visible in the process's address
+space.
+.Pp
+Upon receipt of a SIGTSTP, the input buffer will be flushed, so any
+partially typed password must be retyped when the process
+continues.
diff --git a/lib/libc/gen/getpass.c b/lib/libc/gen/getpass.c
new file mode 100644
index 0000000..e87a5df
--- /dev/null
+++ b/lib/libc/gen/getpass.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getpass.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/termios.h>
+#include <signal.h>
+
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static struct termios oterm, term;
+static FILE *fp;
+
+char *
+getpass(prompt)
+ const char *prompt;
+{
+ register int ch;
+ register char *p;
+ FILE *outfp;
+ static char buf[_PASSWORD_LEN + 1];
+ sigset_t oset, nset;
+
+ /*
+ * read and write to /dev/tty if possible; else read from
+ * stdin and write to stderr.
+ */
+ if ((outfp = fp = fopen(_PATH_TTY, "w+")) == NULL) {
+ outfp = stderr;
+ fp = stdin;
+ }
+
+ /*
+ * note - blocking signals isn't necessarily the
+ * right thing, but we leave it for now.
+ */
+ sigemptyset(&nset);
+ sigaddset(&nset, SIGINT);
+ sigaddset(&nset, SIGTSTP);
+ (void)sigprocmask(SIG_BLOCK, &nset, &oset);
+
+ (void)tcgetattr(fileno(fp), &oterm);
+ term = oterm;
+ term.c_lflag &= ~ECHO;
+ (void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &term);
+ (void)fputs(prompt, outfp);
+ rewind(outfp); /* implied flush */
+ for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';)
+ if (p < buf + _PASSWORD_LEN)
+ *p++ = ch;
+ *p = '\0';
+ (void)write(fileno(outfp), "\n", 1);
+ (void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &oterm);
+
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+
+ if (fp != stdin)
+ (void)fclose(fp);
+ return(buf);
+}
diff --git a/lib/libc/gen/getpwent.3 b/lib/libc/gen/getpwent.3
new file mode 100644
index 0000000..57803da
--- /dev/null
+++ b/lib/libc/gen/getpwent.3
@@ -0,0 +1,219 @@
+.\" Copyright (c) 1988, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)getpwent.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd September 20, 1994
+.Dt GETPWENT 3
+.Os
+.Sh NAME
+.Nm getpwent ,
+.Nm getpwnam ,
+.Nm getpwuid ,
+.Nm setpassent ,
+.Nm setpwent ,
+.Nm endpwent
+.Nd password database operations
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <pwd.h>
+.Ft struct passwd *
+.Fn getpwent void
+.Ft struct passwd *
+.Fn getpwnam "const char *login"
+.Ft struct passwd *
+.Fn getpwuid "uid_t uid"
+.Ft int
+.Fn setpassent "int stayopen"
+.Ft void
+.Fn setpwent void
+.Ft void
+.Fn endpwent void
+.Sh DESCRIPTION
+These functions
+operate on the password database file
+which is described
+in
+.Xr passwd 5 .
+Each entry in the database is defined by the structure
+.Ar passwd
+found in the include
+file
+.Aq Pa pwd.h :
+.Bd -literal -offset indent
+struct passwd {
+ char *pw_name; /* user name */
+ char *pw_passwd; /* encrypted password */
+ uid_t pw_uid; /* user uid */
+ gid_t pw_gid; /* user gid */
+ time_t pw_change; /* password change time */
+ char *pw_class; /* user access class */
+ char *pw_gecos; /* Honeywell login info */
+ char *pw_dir; /* home directory */
+ char *pw_shell; /* default shell */
+ time_t pw_expire; /* account expiration */
+ int pw_fields; /* internal: fields filled in */
+};
+.Ed
+.Pp
+The functions
+.Fn getpwnam
+and
+.Fn getpwuid
+search the password database for the given login name or user uid,
+respectively, always returning the first one encountered.
+.Pp
+The
+.Fn getpwent
+function
+sequentially reads the password database and is intended for programs
+that wish to process the complete list of users.
+.Pp
+The
+.Fn setpassent
+function
+accomplishes two purposes.
+First, it causes
+.Fn getpwent
+to ``rewind'' to the beginning of the database.
+Additionally, if
+.Fa stayopen
+is non-zero, file descriptors are left open, significantly speeding
+up subsequent accesses for all of the routines.
+(This latter functionality is unnecessary for
+.Fn getpwent
+as it doesn't close its file descriptors by default.)
+.Pp
+It is dangerous for long-running programs to keep the file descriptors
+open as the database will become out of date if it is updated while the
+program is running.
+.Pp
+The
+.Fn setpwent
+function
+is identical to
+.Fn setpassent
+with an argument of zero.
+.Pp
+The
+.Fn endpwent
+function
+closes any open files.
+.Pp
+These routines have been written to ``shadow'' the password file, e.g.
+allow only certain programs to have access to the encrypted password.
+If the process which calls them has an effective uid of 0, the encrypted
+password will be returned, otherwise, the password field of the returned
+structure will point to the string
+.Ql * .
+.Sh YP/NIS INTERACTION
+When the
+.Xr yp 4
+password database is enabled, the
+.Fn getpwnam
+and
+.Fn getpwuid
+functions use the YP maps
+.Dq Li passwd.byname
+and
+.Dq Li passwd.byuid ,
+respectively, if the requested password entry is not found in the
+local database. The
+.Fn getpwent
+function will step through the YP map
+.Dq Li passwd.byname
+if the entire map is enabled as described in
+.Xr passwd 5 .
+.Sh RETURN VALUES
+The functions
+.Fn getpwent ,
+.Fn getpwnam ,
+and
+.Fn getpwuid ,
+return a valid pointer to a passwd structure on success
+and a null pointer if end-of-file is reached or an error occurs.
+The
+.Fn setpassent
+function returns 0 on failure and 1 on success.
+The
+.Fn endpwent
+and
+.Fn setpwent
+functions
+have no return value.
+.Sh FILES
+.Bl -tag -width /etc/master.passwd -compact
+.It Pa /etc/pwd.db
+The insecure password database file
+.It Pa /etc/spwd.db
+The secure password database file
+.It Pa /etc/master.passwd
+The current password file
+.It Pa /etc/passwd
+A Version 7 format password file
+.El
+.Sh SEE ALSO
+.Xr getlogin 2 ,
+.Xr getgrent 3 ,
+.Xr yp 4 ,
+.Xr passwd 5 ,
+.Xr pwd_mkdb 8 ,
+.Xr vipw 8
+.Sh HISTORY
+The
+.Fn getpwent ,
+.Fn getpwnam ,
+.Fn getpwuid ,
+.Fn setpwent,
+and
+.Fn endpwent
+functions appeared in
+.At v7 .
+The
+.Fn setpassent
+function appeared in
+.Bx 4.3 Reno .
+.Sh COMPATIBILITY
+The historic function
+.Xr setpwfile 3 ,
+which allowed the specification of alternate password databases,
+has been deprecated and is no longer available.
+.Sh BUGS
+The functions
+.Fn getpwent ,
+.Fn getpwnam ,
+and
+.Fn getpwuid ,
+leave their results in an internal static object and return
+a pointer to that object. Subsequent calls to
+the same function
+will modify the same object.
diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c
new file mode 100644
index 0000000..90dbb4a
--- /dev/null
+++ b/lib/libc/gen/getpwent.c
@@ -0,0 +1,860 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getpwent.c 8.2 (Berkeley) 4/27/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <db.h>
+#include <syslog.h>
+#include <pwd.h>
+#include <utmp.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <grp.h>
+
+extern void setnetgrent __P(( char * ));
+extern int getnetgrent __P(( char **, char **, char ** ));
+extern int innetgr __P(( const char *, const char *, const char *, const char * ));
+
+/*
+ * The lookup techniques and data extraction code here must be kept
+ * in sync with that in `pwd_mkdb'.
+ */
+
+static struct passwd _pw_passwd; /* password structure */
+static DB *_pw_db; /* password database */
+static int _pw_keynum; /* key counter */
+static int _pw_stayopen; /* keep fd's open */
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+
+static struct passwd _pw_copy;
+static DBT empty = { NULL, 0 };
+static DB *_ypcache = (DB *)NULL;
+static int _yp_exclusions = 0;
+static int _yp_enabled = -1;
+static int _pw_stepping_yp; /* set true when stepping thru map */
+static char _ypnam[YPMAXRECORD];
+#define YP_HAVE_MASTER 2
+#define YP_HAVE_ADJUNCT 1
+#define YP_HAVE_NONE 0
+static int _gotmaster;
+static char *_pw_yp_domain;
+static inline int unwind __P(( char * ));
+static void _ypinitdb __P(( void ));
+static int _havemaster __P((char *));
+static int _getyppass __P((struct passwd *, const char *, const char * ));
+static int _nextyppass __P((struct passwd *));
+static inline int lookup __P((const char *));
+static inline void store __P((const char *));
+static inline int ingr __P((const char *, const char*));
+static inline int verf __P((const char *));
+static char * _get_adjunct_pw __P((const char *));
+#endif
+static int __hashpw(DBT *);
+static int __initdb(void);
+
+struct passwd *
+getpwent()
+{
+ DBT key;
+ char bf[sizeof(_pw_keynum) + 1];
+ int rv;
+
+ if (!_pw_db && !__initdb())
+ return((struct passwd *)NULL);
+
+#ifdef YP
+ if(_pw_stepping_yp) {
+ _pw_passwd = _pw_copy;
+ if (unwind((char *)&_ypnam))
+ return(&_pw_passwd);
+ }
+#endif
+tryagain:
+
+ ++_pw_keynum;
+ bf[0] = _PW_KEYBYNUM;
+ bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum));
+ key.data = (u_char *)bf;
+ key.size = sizeof(_pw_keynum) + 1;
+ rv = __hashpw(&key);
+ if(!rv) return (struct passwd *)NULL;
+#ifdef YP
+ if(_pw_passwd.pw_name[0] == '+' || _pw_passwd.pw_name[0] == '-') {
+ if (_yp_enabled == -1)
+ _ypinitdb();
+ bzero((char *)&_ypnam, sizeof(_ypnam));
+ bcopy(_pw_passwd.pw_name, _ypnam,
+ strlen(_pw_passwd.pw_name));
+ _pw_copy = _pw_passwd;
+ if (unwind((char *)&_ypnam) == 0)
+ goto tryagain;
+ else
+ return(&_pw_passwd);
+ }
+#else
+ /* Ignore YP password file entries when YP is disabled. */
+ if(_pw_passwd.pw_name[0] == '+' || _pw_passwd.pw_name[0] == '-') {
+ goto tryagain;
+ }
+#endif
+ return(&_pw_passwd);
+}
+
+struct passwd *
+getpwnam(name)
+ const char *name;
+{
+ DBT key;
+ int len, rval;
+ char bf[UT_NAMESIZE + 2];
+
+ if (!_pw_db && !__initdb())
+ return((struct passwd *)NULL);
+
+ bf[0] = _PW_KEYBYNAME;
+ len = strlen(name);
+ if (len > UT_NAMESIZE)
+ return(NULL);
+ bcopy(name, bf + 1, len);
+ key.data = (u_char *)bf;
+ key.size = len + 1;
+ rval = __hashpw(&key);
+
+#ifdef YP
+ if (!rval) {
+ if (_yp_enabled == -1)
+ _ypinitdb();
+ if (_yp_enabled)
+ rval = _getyppass(&_pw_passwd, name, "passwd.byname");
+ }
+#endif
+ /*
+ * Prevent login attempts when YP is not enabled but YP entries
+ * are in /etc/master.passwd.
+ */
+ if (rval && (_pw_passwd.pw_name[0] == '+'||
+ _pw_passwd.pw_name[0] == '-')) rval = 0;
+
+ if (!_pw_stayopen)
+ endpwent();
+ return(rval ? &_pw_passwd : (struct passwd *)NULL);
+}
+
+struct passwd *
+getpwuid(uid)
+ uid_t uid;
+{
+ DBT key;
+ int keyuid, rval;
+ char bf[sizeof(keyuid) + 1];
+
+ if (!_pw_db && !__initdb())
+ return((struct passwd *)NULL);
+
+ bf[0] = _PW_KEYBYUID;
+ keyuid = uid;
+ bcopy(&keyuid, bf + 1, sizeof(keyuid));
+ key.data = (u_char *)bf;
+ key.size = sizeof(keyuid) + 1;
+ rval = __hashpw(&key);
+
+#ifdef YP
+ if (!rval) {
+ if (_yp_enabled == -1)
+ _ypinitdb();
+ if (_yp_enabled) {
+ char ypbuf[16]; /* big enough for 32-bit uids */
+ snprintf(ypbuf, sizeof ypbuf, "%u", (unsigned)uid);
+ rval = _getyppass(&_pw_passwd, ypbuf, "passwd.byuid");
+ }
+ }
+#endif
+ /*
+ * Prevent login attempts when YP is not enabled but YP entries
+ * are in /etc/master.passwd.
+ */
+ if (rval && (_pw_passwd.pw_name[0] == '+'||
+ _pw_passwd.pw_name[0] == '-')) rval = 0;
+
+ if (!_pw_stayopen)
+ endpwent();
+ return(rval ? &_pw_passwd : (struct passwd *)NULL);
+}
+
+int
+setpassent(stayopen)
+ int stayopen;
+{
+ _pw_keynum = 0;
+#ifdef YP
+ _pw_stepping_yp = 0;
+ if (stayopen)
+ setgroupent(1);
+#endif
+ _pw_stayopen = stayopen;
+ return(1);
+}
+
+void
+setpwent()
+{
+ (void)setpassent(0);
+}
+
+void
+endpwent()
+{
+ _pw_keynum = 0;
+#ifdef YP
+ _pw_stepping_yp = 0;
+#endif
+ if (_pw_db) {
+ (void)(_pw_db->close)(_pw_db);
+ _pw_db = (DB *)NULL;
+ }
+#ifdef YP
+ if (_ypcache) {
+ (void)(_ypcache->close)(_ypcache);
+ _ypcache = (DB *)NULL;
+ _yp_exclusions = 0;
+ }
+ /* Fix for PR #12008 */
+ _yp_enabled = -1;
+#endif
+}
+
+static int
+__initdb()
+{
+ static int warned;
+ char *p;
+
+ p = (geteuid()) ? _PATH_MP_DB : _PATH_SMP_DB;
+ _pw_db = dbopen(p, O_RDONLY, 0, DB_HASH, NULL);
+ if (_pw_db)
+ return(1);
+ if (!warned++)
+ syslog(LOG_ERR, "%s: %m", p);
+ return(0);
+}
+
+static int
+__hashpw(key)
+ DBT *key;
+{
+ register char *p, *t;
+ static u_int max;
+ static char *line;
+ DBT data;
+
+ if ((_pw_db->get)(_pw_db, key, &data, 0))
+ return(0);
+ p = (char *)data.data;
+
+ /* Increase buffer size for long lines if necessary. */
+ if (data.size > max) {
+ max = data.size + 1024;
+ if (!(line = reallocf(line, max)))
+ return(0);
+ }
+
+ /* THIS CODE MUST MATCH THAT IN pwd_mkdb. */
+ t = line;
+#define EXPAND(e) e = t; while ( (*t++ = *p++) );
+#define SCALAR(v) memmove(&(v), p, sizeof v); p += sizeof v
+ EXPAND(_pw_passwd.pw_name);
+ EXPAND(_pw_passwd.pw_passwd);
+ SCALAR(_pw_passwd.pw_uid);
+ SCALAR(_pw_passwd.pw_gid);
+ SCALAR(_pw_passwd.pw_change);
+ EXPAND(_pw_passwd.pw_class);
+ EXPAND(_pw_passwd.pw_gecos);
+ EXPAND(_pw_passwd.pw_dir);
+ EXPAND(_pw_passwd.pw_shell);
+ SCALAR(_pw_passwd.pw_expire);
+ bcopy(p, (char *)&_pw_passwd.pw_fields, sizeof _pw_passwd.pw_fields);
+ p += sizeof _pw_passwd.pw_fields;
+ return(1);
+}
+
+#ifdef YP
+
+static void
+_ypinitdb()
+{
+ DBT key, data;
+ char buf[] = { _PW_KEYYPENABLED };
+ key.data = buf;
+ key.size = 1;
+ _yp_enabled = 0;
+ if ((_pw_db->get)(_pw_db, &key, &data, 0) == 0) {
+ _yp_enabled = (int)*((char *)data.data) - 2;
+ /* Don't even bother with this if we aren't root. */
+ if (!geteuid()) {
+ if (!_pw_yp_domain)
+ if (yp_get_default_domain(&_pw_yp_domain))
+ return;
+ _gotmaster = _havemaster(_pw_yp_domain);
+ } else _gotmaster = YP_HAVE_NONE;
+ /*
+ * Create a DB hash database in memory. Bet you didn't know you
+ * could do a dbopen() with a NULL filename, did you.
+ */
+ if (_ypcache == (DB *)NULL)
+ _ypcache = dbopen(NULL, O_RDWR, 600, DB_HASH, NULL);
+ }
+}
+
+/*
+ * See if a user is in the blackballed list.
+ */
+static inline int
+lookup(name)
+ const char *name;
+{
+ DBT key;
+
+ if (!_yp_exclusions)
+ return(0);
+
+ key.data = (char *)name;
+ key.size = strlen(name);
+
+ if ((_ypcache->get)(_ypcache, &key, &empty, 0)) {
+ return(0);
+ }
+
+ return(1);
+}
+
+/*
+ * Store a blackballed user in an in-core hash database.
+ */
+static inline void
+store(key)
+ const char *key;
+{
+ DBT lkey;
+/*
+ if (lookup(key))
+ return;
+*/
+
+ _yp_exclusions = 1;
+
+ lkey.data = (char *)key;
+ lkey.size = strlen(key);
+
+ (void)(_ypcache->put)(_ypcache, &lkey, &empty, R_NOOVERWRITE);
+}
+
+/*
+ * Parse the + entries in the password database and do appropriate
+ * NIS lookups. While ugly to look at, this is optimized to do only
+ * as many lookups as are absolutely necessary in any given case.
+ * Basically, the getpwent() function will feed us + and - lines
+ * as they appear in the database. For + lines, we do netgroup/group
+ * and user lookups to find all usernames that match the rule and
+ * extract them from the NIS passwd maps. For - lines, we save the
+ * matching names in a database and a) exlude them, and b) make sure
+ * we don't consider them when processing other + lines that appear
+ * later.
+ */
+static inline int
+unwind(grp)
+ char *grp;
+{
+ char *user, *host, *domain;
+ static int latch = 0;
+ static struct group *gr = NULL;
+ int rv = 0;
+
+ if (grp[0] == '+') {
+ if (strlen(grp) == 1) {
+ return(_nextyppass(&_pw_passwd));
+ }
+ if (grp[1] == '@') {
+ _pw_stepping_yp = 1;
+grpagain:
+ if (gr != NULL) {
+ if (*gr->gr_mem != NULL) {
+ if (lookup(*gr->gr_mem)) {
+ gr->gr_mem++;
+ goto grpagain;
+ }
+ rv = _getyppass(&_pw_passwd,
+ *gr->gr_mem,
+ "passwd.byname");
+ gr->gr_mem++;
+ return(rv);
+ } else {
+ latch = 0;
+ _pw_stepping_yp = 0;
+ gr = NULL;
+ return(0);
+ }
+ }
+ if (!latch) {
+ setnetgrent(grp+2);
+ latch++;
+ }
+again:
+ if (getnetgrent(&host, &user, &domain) == 0) {
+ if ((gr = getgrnam(grp+2)) != NULL)
+ goto grpagain;
+ latch = 0;
+ _pw_stepping_yp = 0;
+ return(0);
+ } else {
+ if (lookup(user))
+ goto again;
+ if (_getyppass(&_pw_passwd, user,
+ "passwd.byname"))
+ return(1);
+ else
+ goto again;
+ }
+ } else {
+ if (lookup(grp+1))
+ return(0);
+ return(_getyppass(&_pw_passwd, grp+1, "passwd.byname"));
+ }
+ } else {
+ if (grp[1] == '@') {
+ setnetgrent(grp+2);
+ rv = 0;
+ while(getnetgrent(&host, &user, &domain) != 0) {
+ store(user);
+ rv++;
+ }
+ if (!rv && (gr = getgrnam(grp+2)) != NULL) {
+ while(*gr->gr_mem) {
+ store(*gr->gr_mem);
+ gr->gr_mem++;
+ }
+ }
+ } else {
+ store(grp+1);
+ }
+ }
+ return(0);
+}
+
+/*
+ * See if a user is a member of a particular group.
+ */
+static inline int
+ingr(grp, name)
+ const char *grp;
+ const char *name;
+{
+ register struct group *gr;
+
+ if ((gr = getgrnam(grp)) == NULL)
+ return(0);
+
+ while(*gr->gr_mem) {
+ if (!strcmp(*gr->gr_mem, name))
+ return(1);
+ gr->gr_mem++;
+ }
+
+ return(0);
+}
+
+/*
+ * Check a user against the +@netgroup/-@netgroup lines listed in
+ * the local password database. Also checks +user/-user lines.
+ * If no netgroup exists that matches +@netgroup/-@netgroup,
+ * try searching regular groups with the same name.
+ */
+static inline int
+verf(name)
+ const char *name;
+{
+ DBT key;
+ char bf[sizeof(_pw_keynum) + 1];
+ int keynum = 0;
+
+again:
+ ++keynum;
+ bf[0] = _PW_KEYYPBYNUM;
+ bcopy((char *)&keynum, bf + 1, sizeof(keynum));
+ key.data = (u_char *)bf;
+ key.size = sizeof(keynum) + 1;
+ if (!__hashpw(&key)) {
+ /* Try again using old format */
+ bf[0] = _PW_KEYBYNUM;
+ bcopy((char *)&keynum, bf + 1, sizeof(keynum));
+ key.data = (u_char *)bf;
+ if (!__hashpw(&key))
+ return(0);
+ }
+ if (_pw_passwd.pw_name[0] != '+' && (_pw_passwd.pw_name[0] != '-'))
+ goto again;
+ if (_pw_passwd.pw_name[0] == '+') {
+ if (strlen(_pw_passwd.pw_name) == 1) /* Wildcard */
+ return(1);
+ if (_pw_passwd.pw_name[1] == '@') {
+ if ((innetgr(_pw_passwd.pw_name+2, NULL, name,
+ _pw_yp_domain) ||
+ ingr(_pw_passwd.pw_name+2, name)) && !lookup(name))
+ return(1);
+ else
+ goto again;
+ } else {
+ if (!strcmp(name, _pw_passwd.pw_name+1) &&
+ !lookup(name))
+ return(1);
+ else
+ goto again;
+ }
+ }
+ if (_pw_passwd.pw_name[0] == '-') {
+ /* Note that a minus wildcard is a no-op. */
+ if (_pw_passwd.pw_name[1] == '@') {
+ if (innetgr(_pw_passwd.pw_name+2, NULL, name,
+ _pw_yp_domain) ||
+ ingr(_pw_passwd.pw_name+2, name)) {
+ store(name);
+ return(0);
+ } else
+ goto again;
+ } else {
+ if (!strcmp(name, _pw_passwd.pw_name+1)) {
+ store(name);
+ return(0);
+ } else
+ goto again;
+ }
+
+ }
+ return(0);
+}
+
+static char *
+_get_adjunct_pw(name)
+ const char *name;
+{
+ static char adjunctbuf[YPMAXRECORD+2];
+ int rval;
+ char *result;
+ int resultlen;
+ char *map = "passwd.adjunct.byname";
+ char *s;
+
+ if ((rval = yp_match(_pw_yp_domain, map, name, strlen(name),
+ &result, &resultlen)))
+ return(NULL);
+
+ strncpy(adjunctbuf, result, resultlen);
+ adjunctbuf[resultlen] = '\0';
+ free(result);
+ result = (char *)&adjunctbuf;
+
+ /* Don't care about the name. */
+ if ((s = strsep(&result, ":")) == NULL)
+ return (NULL); /* name */
+ if ((s = strsep(&result, ":")) == NULL)
+ return (NULL); /* password */
+
+ return(s);
+}
+
+static int
+_pw_breakout_yp(struct passwd *pw, char *res, int resultlen, int master)
+{
+ char *s, *result;
+ static char resbuf[YPMAXRECORD+2];
+
+ /*
+ * Be triple, ultra super-duper paranoid: reject entries
+ * that start with a + or -. yp_mkdb and /var/yp/Makefile
+ * are _both_ supposed to strip these out, but you never
+ * know.
+ */
+ if (*res == '+' || *res == '-')
+ return 0;
+
+ /*
+ * The NIS protocol definition limits the size of an NIS
+ * record to YPMAXRECORD bytes. We need to do a copy to
+ * a static buffer here since the memory pointed to by
+ * res will be free()ed when this function returns.
+ */
+ strncpy((char *)&resbuf, res, resultlen);
+ resbuf[resultlen] = '\0';
+ result = (char *)&resbuf;
+
+ /*
+ * XXX Sanity check: make sure all fields are valid (no NULLs).
+ * If we find a badly formatted entry, we punt.
+ */
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* name */
+ /*
+ * We don't care what pw_fields says: we _always_ want the
+ * username returned to us by NIS.
+ */
+ pw->pw_name = s;
+ pw->pw_fields |= _PWF_NAME;
+
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* password */
+ if(!(pw->pw_fields & _PWF_PASSWD)) {
+ /* SunOS passwd.adjunct hack */
+ if (master == YP_HAVE_ADJUNCT && strstr(s, "##") != NULL) {
+ char *realpw;
+ realpw = _get_adjunct_pw(pw->pw_name);
+ if (realpw == NULL)
+ pw->pw_passwd = s;
+ else
+ pw->pw_passwd = realpw;
+ } else {
+ pw->pw_passwd = s;
+ }
+ pw->pw_fields |= _PWF_PASSWD;
+ }
+
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* uid */
+ if(!(pw->pw_fields & _PWF_UID)) {
+ pw->pw_uid = atoi(s);
+ pw->pw_fields |= _PWF_UID;
+ }
+
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* gid */
+ if(!(pw->pw_fields & _PWF_GID)) {
+ pw->pw_gid = atoi(s);
+ pw->pw_fields |= _PWF_GID;
+ }
+
+ if (master == YP_HAVE_MASTER) {
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* class */
+ if(!(pw->pw_fields & _PWF_CLASS)) {
+ pw->pw_class = s;
+ pw->pw_fields |= _PWF_CLASS;
+ }
+
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* change */
+ if(!(pw->pw_fields & _PWF_CHANGE)) {
+ pw->pw_change = atol(s);
+ pw->pw_fields |= _PWF_CHANGE;
+ }
+
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* expire */
+ if(!(pw->pw_fields & _PWF_EXPIRE)) {
+ pw->pw_expire = atol(s);
+ pw->pw_fields |= _PWF_EXPIRE;
+ }
+ }
+
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* gecos */
+ if(!(pw->pw_fields & _PWF_GECOS)) {
+ pw->pw_gecos = s;
+ pw->pw_fields |= _PWF_GECOS;
+ }
+
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* dir */
+ if(!(pw->pw_fields & _PWF_DIR)) {
+ pw->pw_dir = s;
+ pw->pw_fields |= _PWF_DIR;
+ }
+
+ if ((s = strsep(&result, ":")) == NULL) return 0; /* shell */
+ if(!(pw->pw_fields & _PWF_SHELL)) {
+ pw->pw_shell = s;
+ pw->pw_fields |= _PWF_SHELL;
+ }
+
+ /* Be consistent. */
+ if ((s = strchr(pw->pw_shell, '\n'))) *s = '\0';
+
+ return 1;
+}
+
+static int
+_havemaster(char *_yp_domain)
+{
+ int order;
+ int rval;
+
+ if (!(rval = yp_order(_yp_domain, "master.passwd.byname", &order)))
+ return(YP_HAVE_MASTER);
+
+ /*
+ * NIS+ in YP compat mode doesn't support
+ * YPPROC_ORDER -- no point in continuing.
+ */
+ if (rval == YPERR_YPERR)
+ return(YP_HAVE_NONE);
+
+ /* master.passwd doesn't exist -- try passwd.adjunct */
+ if (rval == YPERR_MAP) {
+ rval = yp_order(_yp_domain, "passwd.adjunct.byname", &order);
+ if (!rval)
+ return(YP_HAVE_ADJUNCT);
+ }
+
+ return (YP_HAVE_NONE);
+}
+
+static int
+_getyppass(struct passwd *pw, const char *name, const char *map)
+{
+ char *result, *s;
+ int resultlen;
+ int rv;
+ char mastermap[YPMAXRECORD];
+
+ if(!_pw_yp_domain) {
+ if(yp_get_default_domain(&_pw_yp_domain))
+ return 0;
+ }
+
+ if (_gotmaster == YP_HAVE_MASTER)
+ sprintf(mastermap,"master.%s", map);
+ else
+ sprintf(mastermap,"%s",map);
+
+ if(yp_match(_pw_yp_domain, (char *)&mastermap, name, strlen(name),
+ &result, &resultlen)) {
+ if (_gotmaster != YP_HAVE_MASTER)
+ return 0;
+ sprintf(mastermap,"%s",map);
+ if (yp_match(_pw_yp_domain, (char *)&mastermap,
+ name, strlen(name), &result, &resultlen))
+ return 0;
+ _gotmaster = YP_HAVE_NONE;
+ }
+
+ if (!_pw_stepping_yp) {
+ s = strchr(result, ':');
+ if (s) {
+ *s = '\0';
+ } else {
+ /* Must be a malformed entry if no colons. */
+ free(result);
+ return(0);
+ }
+
+ if (!verf(result)) {
+ *s = ':';
+ free(result);
+ return(0);
+ }
+
+ *s = ':'; /* Put back the colon we previously replaced with a NUL. */
+ }
+
+ rv = _pw_breakout_yp(pw, result, resultlen, _gotmaster);
+ free(result);
+ return(rv);
+}
+
+static int
+_nextyppass(struct passwd *pw)
+{
+ static char *key;
+ static int keylen;
+ char *lastkey, *result, *s;
+ int resultlen;
+ int rv;
+ char *map = "passwd.byname";
+
+ if(!_pw_yp_domain) {
+ if(yp_get_default_domain(&_pw_yp_domain))
+ return 0;
+ }
+
+ if (_gotmaster == YP_HAVE_MASTER)
+ map = "master.passwd.byname";
+
+ if(!_pw_stepping_yp) {
+ if(key) free(key);
+ rv = yp_first(_pw_yp_domain, map,
+ &key, &keylen, &result, &resultlen);
+ if(rv) {
+ return 0;
+ }
+ _pw_stepping_yp = 1;
+ goto unpack;
+ } else {
+tryagain:
+ lastkey = key;
+ rv = yp_next(_pw_yp_domain, map, key, keylen,
+ &key, &keylen, &result, &resultlen);
+ free(lastkey);
+unpack:
+ if(rv) {
+ _pw_stepping_yp = 0;
+ return 0;
+ }
+
+ s = strchr(result, ':');
+ if (s) {
+ *s = '\0';
+ } else {
+ /* Must be a malformed entry if no colons. */
+ free(result);
+ goto tryagain;
+ }
+
+ if (lookup(result)) {
+ *s = ':';
+ free(result);
+ goto tryagain;
+ }
+
+ *s = ':'; /* Put back the colon we previously replaced with a NUL. */
+ if (_pw_breakout_yp(pw, result, resultlen, _gotmaster)) {
+ free(result);
+ return(1);
+ } else {
+ free(result);
+ goto tryagain;
+ }
+ }
+}
+
+#endif /* YP */
diff --git a/lib/libc/gen/getttyent.3 b/lib/libc/gen/getttyent.3
new file mode 100644
index 0000000..ab3ff1d
--- /dev/null
+++ b/lib/libc/gen/getttyent.3
@@ -0,0 +1,210 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getttyent.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd November 17, 1996
+.Dt GETTTYENT 3
+.Os BSD 4.3
+.Sh NAME
+.Nm getttyent ,
+.Nm getttynam ,
+.Nm setttyent ,
+.Nm endttyent
+.Nd get ttys file entry
+.Nm isdialuptty ,
+.Nm isnettty
+.Nd determine tty type from ttys file entry
+.Sh SYNOPSIS
+.Fd #include <ttyent.h>
+.Ft struct ttyent *
+.Fn getttyent void
+.Ft struct ttyent *
+.Fn getttynam "const char *name"
+.Ft int
+.Fn setttyent void
+.Ft int
+.Fn endttyent void
+.Ft int
+.Fn isdialuptty "const char *name"
+.Ft int
+.Fn isnettty "const char *name"
+.Sh DESCRIPTION
+The
+.Fn getttyent ,
+and
+.Fn getttynam
+functions
+each return a pointer to an object, with the following structure,
+containing the broken-out fields of a line from the tty description
+file.
+.Bd -literal
+struct ttyent {
+ char *ty_name; /* terminal device name */
+ char *ty_getty; /* command to execute, usually getty */
+ char *ty_type; /* terminal type for termcap */
+#define TTY_ON 0x01 /* enable logins (start ty_getty program) */
+#define TTY_SECURE 0x02 /* allow uid of 0 to login */
+#define TTY_DIALUP 0x04 /* is a dialup tty */
+#define TTY_NETWORK 0x08 /* is a network tty */
+ int ty_status; /* status flags */
+ char *ty_window; /* command to start up window manager */
+ char *ty_comment; /* comment field */
+ char *ty_group; /* tty group name */
+};
+.Ed
+.Pp
+The fields are as follows:
+.Bl -tag -width ty_comment
+.It Fa ty_name
+The name of the character-special file.
+.It Fa ty_getty
+The name of the command invoked by
+.Xr init 8
+to initialize tty line characteristics.
+.It Fa ty_type
+The name of the default terminal type connected to this tty line.
+.It Fa ty_status
+A mask of bit fields which indicate various actions allowed on this
+tty line.
+The possible flags are as follows:
+.Bl -tag -width TTY_NETWORK
+.It Dv TTY_ON
+Enables logins (i.e.,
+.Xr init 8
+will start the command referenced by
+.Fa ty_getty
+on this entry).
+.It Dv TTY_SECURE
+Allow users with a uid of 0 to login on this terminal.
+.It Dv TTY_DIALUP
+Identifies a tty as a dialin line.
+If this flag is set, then
+.Fn isdialuptty
+will return a non-zero value.
+.It Dv TTY_NETWORK
+Identifies a tty used for network connections.
+If this flag is set, then
+.Fn isnettty
+will return a non-zero value.
+.El
+.It Fa ty_window
+The command to execute for a window system associated with the line.
+.It Fa ty_group
+A group name to which the tty belongs.
+If no group is specified in the ttys description file,
+then the tty is placed in an anonymous group called "none".
+.It Fa ty_comment
+Any trailing comment field, with any leading hash marks (``#'') or
+whitespace removed.
+.El
+.Pp
+If any of the fields pointing to character strings are unspecified,
+they are returned as null pointers.
+The field
+.Fa ty_status
+will be zero if no flag values are specified.
+.Pp
+See
+.Xr ttys 5
+for a more complete discussion of the meaning and usage of the
+fields.
+.Pp
+The
+.Fn getttyent
+function
+reads the next line from the ttys file, opening the file if necessary.
+The
+.Fn setttyent
+function
+rewinds the file if open, or opens the file if it is unopened.
+The
+.Fn endttyent
+function
+closes any open files.
+.Pp
+The
+.Fn getttynam
+function
+searches from the beginning of the file until a matching
+.Fa name
+is found
+(or until
+.Dv EOF
+is encountered).
+.Sh RETURN VALUES
+The routines
+.Fn getttyent
+and
+.Fn getttynam
+return a null pointer on
+.Dv EOF
+or error.
+The
+.Fn setttyent
+function
+and
+.Fn endttyent
+return 0 on failure and 1 on success.
+.Pp
+The routines
+.Fn isdialuptty
+and
+.Fn isnettty
+return non-zero if the dialup or network flag is set for the
+tty entry relating to the tty named by the parameter, and
+zero otherwise.
+.Sh FILES
+.Bl -tag -width /etc/ttys -compact
+.It Pa /etc/ttys
+.El
+.Sh SEE ALSO
+.Xr login 1 ,
+.Xr ttyslot 3 ,
+.Xr gettytab 5 ,
+.Xr termcap 5 ,
+.Xr ttys 5 ,
+.Xr getty 8 ,
+.Xr init 8
+.Sh HISTORY
+The
+.Fn getttyent ,
+.Fn getttynam ,
+.Fn setttyent ,
+and
+.Fn endttyent
+functions appeared in
+.Bx 4.3 .
+.Sh BUGS
+These functions use static data storage;
+if the data is needed for future use, it should be
+copied before any subsequent calls overwrite it.
diff --git a/lib/libc/gen/getttyent.c b/lib/libc/gen/getttyent.c
new file mode 100644
index 0000000..bfbe833
--- /dev/null
+++ b/lib/libc/gen/getttyent.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getttyent.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ttyent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+static char zapchar;
+static FILE *tf;
+static size_t lbsize;
+static char *line;
+
+#define MALLOCCHUNK 100
+
+static char *skip __P((char *));
+static char *value __P((char *));
+
+struct ttyent *
+getttynam(tty)
+ const char *tty;
+{
+ register struct ttyent *t;
+
+ if (strncmp(tty, "/dev/", 5) == 0)
+ tty += 5;
+ setttyent();
+ while ( (t = getttyent()) )
+ if (!strcmp(tty, t->ty_name))
+ break;
+ endttyent();
+ return (t);
+}
+
+struct ttyent *
+getttyent()
+{
+ static struct ttyent tty;
+ register char *p;
+ register int c;
+ size_t i;
+
+ if (!tf && !setttyent())
+ return (NULL);
+ for (;;) {
+ if (!fgets(p = line, lbsize, tf))
+ return (NULL);
+ /* extend buffer if line was too big, and retry */
+ while (!index(p, '\n')) {
+ i = strlen(p);
+ lbsize += MALLOCCHUNK;
+ if ((p = realloc(line, lbsize)) == NULL) {
+ (void)endttyent();
+ return (NULL);
+ }
+ line = p;
+ if (!fgets(&line[i], lbsize - i, tf))
+ return (NULL);
+ }
+ while (isspace((unsigned char)*p))
+ ++p;
+ if (*p && *p != '#')
+ break;
+ }
+
+#define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace((unsigned char)p[sizeof(e) - 1])
+#define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
+
+ zapchar = 0;
+ tty.ty_name = p;
+ p = skip(p);
+ if (!*(tty.ty_getty = p))
+ tty.ty_getty = tty.ty_type = NULL;
+ else {
+ p = skip(p);
+ if (!*(tty.ty_type = p))
+ tty.ty_type = NULL;
+ else {
+ /* compatibility kludge: handle network/dialup specially */
+ if (scmp(_TTYS_DIALUP))
+ tty.ty_status |= TTY_DIALUP;
+ else if (scmp(_TTYS_NETWORK))
+ tty.ty_status |= TTY_NETWORK;
+ p = skip(p);
+ }
+ }
+ tty.ty_status = 0;
+ tty.ty_window = NULL;
+ tty.ty_group = _TTYS_NOGROUP;
+
+ for (; *p; p = skip(p)) {
+ if (scmp(_TTYS_OFF))
+ tty.ty_status &= ~TTY_ON;
+ else if (scmp(_TTYS_ON))
+ tty.ty_status |= TTY_ON;
+ else if (scmp(_TTYS_SECURE))
+ tty.ty_status |= TTY_SECURE;
+ else if (scmp(_TTYS_INSECURE))
+ tty.ty_status &= ~TTY_SECURE;
+ else if (scmp(_TTYS_DIALUP))
+ tty.ty_status |= TTY_DIALUP;
+ else if (scmp(_TTYS_NETWORK))
+ tty.ty_status |= TTY_NETWORK;
+ else if (vcmp(_TTYS_WINDOW))
+ tty.ty_window = value(p);
+ else if (vcmp(_TTYS_GROUP))
+ tty.ty_group = value(p);
+ else
+ break;
+ }
+
+ if (zapchar == '#' || *p == '#')
+ while ((c = *++p) == ' ' || c == '\t')
+ ;
+ tty.ty_comment = p;
+ if (*p == 0)
+ tty.ty_comment = 0;
+ if ( (p = index(p, '\n')) )
+ *p = '\0';
+ return (&tty);
+}
+
+#define QUOTED 1
+
+/*
+ * Skip over the current field, removing quotes, and return a pointer to
+ * the next field.
+ */
+static char *
+skip(p)
+ register char *p;
+{
+ register char *t;
+ register int c, q;
+
+ for (q = 0, t = p; (c = *p) != '\0'; p++) {
+ if (c == '"') {
+ q ^= QUOTED; /* obscure, but nice */
+ continue;
+ }
+ if (q == QUOTED && *p == '\\' && *(p+1) == '"')
+ p++;
+ *t++ = *p;
+ if (q == QUOTED)
+ continue;
+ if (c == '#') {
+ zapchar = c;
+ *p = 0;
+ break;
+ }
+ if (c == '\t' || c == ' ' || c == '\n') {
+ zapchar = c;
+ *p++ = 0;
+ while ((c = *p) == '\t' || c == ' ' || c == '\n')
+ p++;
+ break;
+ }
+ }
+ *--t = '\0';
+ return (p);
+}
+
+static char *
+value(p)
+ register char *p;
+{
+
+ return ((p = index(p, '=')) ? ++p : NULL);
+}
+
+int
+setttyent()
+{
+
+ if (line == NULL) {
+ if ((line = malloc(MALLOCCHUNK)) == NULL)
+ return (0);
+ lbsize = MALLOCCHUNK;
+ }
+ if (tf) {
+ rewind(tf);
+ return (1);
+ } else if ( (tf = fopen(_PATH_TTYS, "r")) )
+ return (1);
+ return (0);
+}
+
+int
+endttyent()
+{
+ int rval;
+
+ /*
+ * NB: Don't free `line' because getttynam()
+ * may still be referencing it
+ */
+ if (tf) {
+ rval = (fclose(tf) != EOF);
+ tf = NULL;
+ return (rval);
+ }
+ return (1);
+}
+
+static int
+isttystat(tty, flag)
+ const char *tty;
+ int flag;
+{
+ register struct ttyent *t;
+
+ return ((t = getttynam(tty)) == NULL) ? 0 : !!(t->ty_status & flag);
+}
+
+
+int
+isdialuptty(tty)
+ const char *tty;
+{
+
+ return isttystat(tty, TTY_DIALUP);
+}
+
+int isnettty(tty)
+ const char *tty;
+{
+
+ return isttystat(tty, TTY_NETWORK);
+}
diff --git a/lib/libc/gen/getusershell.3 b/lib/libc/gen/getusershell.3
new file mode 100644
index 0000000..62eaafa
--- /dev/null
+++ b/lib/libc/gen/getusershell.3
@@ -0,0 +1,99 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getusershell.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETUSERSHELL 3
+.Os BSD 4.3
+.Sh NAME
+.Nm getusershell ,
+.Nm setusershell ,
+.Nm endusershell
+.Nd get legal user shells
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft char *
+.Fn getusershell void
+.Ft void
+.Fn setusershell void
+.Ft void
+.Fn endusershell void
+.Sh DESCRIPTION
+The
+.Fn getusershell
+function
+returns a pointer to a legal user shell as defined by the
+system manager in the file
+.Pa /etc/shells .
+If
+.Pa /etc/shells
+is unreadable or does not exist,
+.Fn getusershell
+behaves as if
+.Pa /bin/sh
+and
+.Pa /bin/csh
+were listed in the file.
+.Pp
+The
+.Fn getusershell
+function
+reads the next
+line (opening the file if necessary);
+.Fn setusershell
+rewinds the file;
+.Fn endusershell
+closes it.
+.Sh FILES
+.Bl -tag -width /etc/shells -compact
+.It Pa /etc/shells
+.El
+.Sh DIAGNOSTICS
+The routine
+.Fn getusershell
+returns a null pointer (0) on
+.Dv EOF .
+.Sh SEE ALSO
+.Xr shells 5
+.Sh HISTORY
+The
+.Fn getusershell
+function appeared in
+.Bx 4.3 .
+.Sh BUGS
+The
+.Fn getusershell
+function leaves its result in an internal static object and returns
+a pointer to that object. Subsequent calls to
+.Fn getusershell
+will modify the same object.
diff --git a/lib/libc/gen/getusershell.c b/lib/libc/gen/getusershell.c
new file mode 100644
index 0000000..be1a77a
--- /dev/null
+++ b/lib/libc/gen/getusershell.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getusershell.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <paths.h>
+
+/*
+ * Local shells should NOT be added here. They should be added in
+ * /etc/shells.
+ */
+
+static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
+static char **curshell, **shells, *strings;
+static char **initshells __P((void));
+
+/*
+ * Get a list of shells from _PATH_SHELLS, if it exists.
+ */
+char *
+getusershell()
+{
+ char *ret;
+
+ if (curshell == NULL)
+ curshell = initshells();
+ ret = *curshell;
+ if (ret != NULL)
+ curshell++;
+ return (ret);
+}
+
+void
+endusershell()
+{
+
+ if (shells != NULL)
+ free(shells);
+ shells = NULL;
+ if (strings != NULL)
+ free(strings);
+ strings = NULL;
+ curshell = NULL;
+}
+
+void
+setusershell()
+{
+
+ curshell = initshells();
+}
+
+static char **
+initshells()
+{
+ register char **sp, *cp;
+ register FILE *fp;
+ struct stat statb;
+
+ if (shells != NULL)
+ free(shells);
+ shells = NULL;
+ if (strings != NULL)
+ free(strings);
+ strings = NULL;
+ if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
+ return (okshells);
+ if (fstat(fileno(fp), &statb) == -1) {
+ (void)fclose(fp);
+ return (okshells);
+ }
+ if ((strings = malloc((u_int)statb.st_size)) == NULL) {
+ (void)fclose(fp);
+ return (okshells);
+ }
+ shells = calloc((unsigned)statb.st_size / 3, sizeof (char *));
+ if (shells == NULL) {
+ (void)fclose(fp);
+ free(strings);
+ strings = NULL;
+ return (okshells);
+ }
+ sp = shells;
+ cp = strings;
+ while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
+ while (*cp != '#' && *cp != '/' && *cp != '\0')
+ cp++;
+ if (*cp == '#' || *cp == '\0')
+ continue;
+ *sp++ = cp;
+ while (!isspace((unsigned char)*cp) && *cp != '#' && *cp != '\0')
+ cp++;
+ *cp++ = '\0';
+ }
+ *sp = NULL;
+ (void)fclose(fp);
+ return (shells);
+}
diff --git a/lib/libc/gen/getvfsbyname.3 b/lib/libc/gen/getvfsbyname.3
new file mode 100644
index 0000000..c33fbea
--- /dev/null
+++ b/lib/libc/gen/getvfsbyname.3
@@ -0,0 +1,98 @@
+.\" Copyright (c) 1995
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)kvm_getvfsbyname.3 8.3 (Berkeley) 5/4/95
+.\" $FreeBSD$
+.\"
+.Dd May 4, 1995
+.Dt GETVFSBYNAME 3
+.Os
+.Sh NAME
+.Nm getvfsbyname
+.Nd get information about a filesystem
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/mount.h>
+.Ft int
+.Fn getvfsbyname "const char *name" "struct vfsconf *vfc"
+.Sh DESCRIPTION
+The
+.Fn getvfsbyname
+function provides access to information about a
+filesystem module that is configured in the kernel.
+If successful,
+the requested filesystem
+.Fa vfsconf
+is returned in the location pointed to by
+.Fa vfc .
+The fields in a
+.Dq Li struct vfsconf
+are defined as follows:
+.Pp
+.Bl -tag -compact -width vfc_refcount
+.It vfc_name
+the name of the filesystem
+.It vfc_typenum
+the filesystem type number assigned by the kernel
+.It vfc_refcount
+the number of active mount points using the filesystem
+.It vfc_flags
+flag bits that are used to initialize a new mount point
+using the filesystem
+.El
+.Sh RETURN VALUES
+If the call to
+.Nm getvfsbyname
+is successful, 0 is returned.
+Otherwise \-1 is returned and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+The following errors may be reported:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+The
+.Fa vfc
+pointer contains an invalid address.
+.It Bq Er ENOENT
+The
+.Fa name
+specifies a filesystem that is unknown or not configured in the kernel.
+.Sh SEE ALSO
+.Xr mount 2 ,
+.Xr sysctl 3 ,
+.Xr mount 8 ,
+.Xr sysctl 8
+.Sh HISTORY
+A variant of the
+.Fn getvfsbyname
+function first appeared in
+.Fx 2.0 .
diff --git a/lib/libc/gen/getvfsbyname.c b/lib/libc/gen/getvfsbyname.c
new file mode 100644
index 0000000..a8f6913
--- /dev/null
+++ b/lib/libc/gen/getvfsbyname.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)kvm_getvfsbyname.c 8.1 (Berkeley) 4/3/95";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+#include <errno.h>
+
+/*
+ * Given a filesystem name, determine if it is resident in the kernel,
+ * and if it is resident, return its vfsconf structure.
+ */
+getvfsbyname(fsname, vfcp)
+ const char *fsname;
+ struct vfsconf *vfcp;
+{
+#ifdef __NETBSD_SYSCALLS
+ errno = ENOSYS;
+#else
+ int name[4], maxtypenum, cnt;
+ size_t buflen;
+
+ name[0] = CTL_VFS;
+ name[1] = VFS_GENERIC;
+ name[2] = VFS_MAXTYPENUM;
+ buflen = 4;
+ if (sysctl(name, 3, &maxtypenum, &buflen, (void *)0, (size_t)0) < 0)
+ return (-1);
+ name[2] = VFS_CONF;
+ buflen = sizeof *vfcp;
+ for (cnt = 0; cnt < maxtypenum; cnt++) {
+ name[3] = cnt;
+ if (sysctl(name, 4, vfcp, &buflen, (void *)0, (size_t)0) < 0) {
+ if (errno != EOPNOTSUPP)
+ return (-1);
+ continue;
+ }
+ if (!strcmp(fsname, vfcp->vfc_name))
+ return (0);
+ }
+ errno = ENOENT;
+#endif
+ return (-1);
+}
diff --git a/lib/libc/gen/getvfsent.3 b/lib/libc/gen/getvfsent.3
new file mode 100644
index 0000000..127e0f3
--- /dev/null
+++ b/lib/libc/gen/getvfsent.3
@@ -0,0 +1,163 @@
+.\" $FreeBSD$
+.\" Written by Garrett A. Wollman, September 1994.
+.\" This manual page is in the public domain.
+.\"
+.Dd September 24, 1994
+.Dt GETVFSENT 3
+.Os
+.Sh NAME
+.Nm getvfsent ,
+.Nm setvfsent ,
+.Nm endvfsent ,
+.Nm vfsisloadable ,
+.Nm vfsload
+.Nd manage virtual filesystem modules
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/mount.h>
+.Ft struct ovfsconf *
+.Fn getvfsent "void"
+.Ft void
+.Fn setvfsent "int cachelist"
+.Ft void
+.Fn endvfsent "void"
+.Ft int
+.Fn vfsisloadable "const char *name"
+.Ft int
+.Fn vfsload "const char *name"
+.Sh DESCRIPTION
+The
+.Fn getvfsent
+function provides convenient access to a list of installed virtual
+filesystem modules managed by the kernel. It steps through the
+list of filesystems one at a time. A null pointer is returned when
+no more data is available. The fields in a
+.Dq Li struct ovfsconf
+are as follows:
+.Pp
+.Bl -tag -compact -width vfc_refcount
+.It vfc_name
+the name of the filesystem
+.It vfc_index
+the filesystem type number assigned by the kernel and used in calls to
+.Xr mount 2
+.It vfc_refcount
+the number of references to this filesystem
+(usually the number of mounts, but one greater for filesystems which
+cannot be unloaded or which are statically linked into the kernel)
+.It vfc_flags
+flag bits, of which none are currently defined
+.El
+.Pp
+The
+.Fn setvfsent
+and
+.Fn endvfsent
+functions are used to control caching of the filesystem list, which is
+obtained in toto from the kernel via
+.Xr sysctl 3 .
+If the
+.Fa cachelist
+parameter to
+.Fn setvfsent
+is non-zero, the list will be retrieved only once, upon the first call
+to one of the retrieval functions, until
+.Fn endvfsent
+is called to clear the cache. In general,
+.Fn setvfsent 1
+should be called by programs using the
+.Fn getvfsent
+function, and
+.Fn setvfsent 0
+(which is also the default state)
+should be called by programs using the
+.Fn vfsload
+function.
+.Pp
+The
+.Fn vfsisloadable
+function returns a non-zero value if a later call to
+.Fn vfsload name
+is likely to succeed. We say
+.Dq likely
+because
+.Fn vfsisloadable
+does not check any of the conditions necessary for
+.Fn vfsload
+to succeed.
+.Pp
+The
+.Fn vfsload
+function attempts to load a kernel module implementing filesystem
+.Fa name .
+It returns zero if the filesystem module was successfully located and
+loaded, or non-zero otherwise. It should only be called in the
+following circumstances:
+.Bl -enum
+.It
+.Fn getvfsbyname
+has been called and returned a non-zero value.
+.It
+.Fn vfsisloadable
+has been called and returned a non-zero value.
+.El
+.Pp
+Here is an example, taken from the source to
+.Xr mount_cd9660 8 :
+.Bd -literal -offset indent
+
+struct vfsconf *vfc;
+int error;
+
+/* setup code here */
+
+error = getvfsbyname("cd9660", &vfc);
+if (error && vfsisloadable("cd9660")) {
+ if (vfsload("cd9660"))
+ err(EX_OSERR, "vfsload(cd9660)");
+ endvfsent(); /* flush cache */
+ error = getvfsbyname("cd9660", &vfc);
+}
+if (error)
+ errx(1, "cd9660 filesystem is not available");
+
+if (mount(vfc.vfc_name, dir, mntflags, &args) < 0)
+ err(1, NULL);
+
+.Ed
+.Sh RETURN VALUES
+The
+.Fn getvfsent
+routine returns a pointer to a static data structure when
+it succeeds, and returns a null pointer when it fails. On failure,
+.Va errno
+may be set to one of the values documented for
+.Xr sysctl 3
+or
+.Xr malloc 3 ,
+if a failure of that function was the cause; otherwise
+.Va errno
+will be unmodified.
+.Pp
+The
+.Fn vfsload
+function returns a non-zero value on failure, or zero on success. If
+.Fn vfsload
+fails,
+.Va errno
+may be set to one of the values documented for
+.Xr kldload 2 .
+.Sh SEE ALSO
+.Xr kldload 2 ,
+.Xr mount 2 ,
+.Xr mount 8
+.Sh AUTHORS
+The loadable filesystem support was written by
+.An Garrett A. Wollman ,
+based on generic loadable kernel module support by
+.An Terry Lambert .
+.Sh HISTORY
+The
+.Fn getvfsent
+family of functions first appeared in
+.Fx 2.0 .
diff --git a/lib/libc/gen/getvfsent.c b/lib/libc/gen/getvfsent.c
new file mode 100644
index 0000000..bf3ca20
--- /dev/null
+++ b/lib/libc/gen/getvfsent.c
@@ -0,0 +1,177 @@
+/*
+ * getvfsent.c - get a listing of installed filesystems
+ * Written September 1994 by Garrett A. Wollman
+ * This file is in the public domain.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+#include <unistd.h>
+#include <sys/file.h>
+#include <sys/wait.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <paths.h>
+
+/* XXX hide some compatibility problems. */
+#undef getvfsbyname
+#define vfsconf ovfsconf
+
+static struct vfsconf *_vfslist = 0;
+static struct vfsconf _vfsconf;
+static size_t _vfslistlen = 0;
+static int _vfs_keeplist = 0;
+static int _vfs_index = 0;
+
+static int
+initvfs(void)
+{
+ int mib[2] = { CTL_VFS, VFS_VFSCONF };
+ size_t size = 0;
+ int rv;
+
+ rv = sysctl(mib, 2, (void *)0, &size, (void *)0, (size_t)0);
+ if(rv < 0)
+ return 0;
+
+ if(_vfslist)
+ free(_vfslist);
+ _vfslist = malloc(size);
+ if(!_vfslist)
+ return 0;
+
+ rv = sysctl(mib, 2, _vfslist, &size, (void *)0, (size_t)0);
+ if(rv < 0) {
+ free(_vfslist);
+ _vfslist = 0;
+ return 0;
+ }
+
+ _vfslistlen = size / sizeof _vfslist[0];
+ return 1;
+}
+
+struct vfsconf *
+getvfsent(void)
+{
+ if(!_vfslist && !initvfs()) {
+ return 0;
+ }
+
+ do {
+ if(_vfs_index >= _vfslistlen) {
+ return 0;
+ }
+
+ _vfsconf = _vfslist[_vfs_index++];
+ } while(!_vfsconf.vfc_vfsops);
+
+ if(!_vfs_keeplist) {
+ free(_vfslist);
+ _vfslist = 0;
+ }
+ return &_vfsconf;
+}
+
+struct vfsconf *
+getvfsbyname(const char *name)
+{
+ int i;
+
+ if(!_vfslist && !initvfs()) {
+ return 0;
+ }
+
+ for(i = 0; i < _vfslistlen; i++) {
+ if( ! strcmp(_vfslist[i].vfc_name, name) )
+ break;
+ }
+
+ if(i < _vfslistlen) {
+ _vfsconf = _vfslist[i];
+ }
+
+ if(!_vfs_keeplist) {
+ free(_vfslist);
+ _vfslist = 0;
+ }
+
+ if(i < _vfslistlen) {
+ return &_vfsconf;
+ } else {
+ return 0;
+ }
+}
+
+struct vfsconf *
+getvfsbytype(int type)
+{
+ int i;
+
+ if(!_vfslist && !initvfs()) {
+ return 0;
+ }
+
+ for(i = 0; i < _vfslistlen; i++) {
+ if(_vfslist[i].vfc_index == type)
+ break;
+ }
+
+ if(i < _vfslistlen) {
+ _vfsconf = _vfslist[i];
+ }
+
+ if(!_vfs_keeplist) {
+ free(_vfslist);
+ _vfslist = 0;
+ }
+
+ if(i < _vfslistlen) {
+ return &_vfsconf;
+ } else {
+ return 0;
+ }
+}
+
+void
+setvfsent(int keep)
+{
+ if(_vfslist && !keep) {
+ free(_vfslist);
+ _vfslist = 0;
+ }
+
+ _vfs_keeplist = keep;
+ _vfs_index = 0;
+}
+
+void
+endvfsent(void)
+{
+ if(_vfslist) {
+ free(_vfslist);
+ _vfslist = 0;
+ }
+
+ _vfs_index = 0;
+}
+
+int
+vfsisloadable(const char *name)
+{
+ return 1;
+}
+
+int
+vfsload(const char *name)
+{
+ int status;
+
+ status = kldload(name);
+ return status == -1 ? status : 0;
+}
+
diff --git a/lib/libc/gen/glob.3 b/lib/libc/gen/glob.3
new file mode 100644
index 0000000..d99dc9f
--- /dev/null
+++ b/lib/libc/gen/glob.3
@@ -0,0 +1,447 @@
+.\" Copyright (c) 1989, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Guido van Rossum.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)glob.3 8.3 (Berkeley) 4/16/94
+.\" $FreeBSD$
+.\"
+.Dd April 16, 1994
+.Dt GLOB 3
+.Os
+.Sh NAME
+.Nm glob ,
+.Nm globfree
+.Nd generate pathnames matching a pattern
+.Sh SYNOPSIS
+.Fd #include <glob.h>
+.Ft int
+.Fn glob "const char *pattern" "int flags" "int (*errfunc)(const char *, int)" "glob_t *pglob"
+.Ft void
+.Fn globfree "glob_t *pglob"
+.Sh DESCRIPTION
+The
+.Fn glob
+function
+is a pathname generator that implements the rules for file name pattern
+matching used by the shell.
+.Pp
+The include file
+.Pa glob.h
+defines the structure type
+.Fa glob_t ,
+which contains at least the following fields:
+.Bd -literal
+typedef struct {
+ int gl_pathc; /* count of total paths so far */
+ int gl_matchc; /* count of paths matching pattern */
+ int gl_offs; /* reserved at beginning of gl_pathv */
+ int gl_flags; /* returned flags */
+ char **gl_pathv; /* list of paths matching pattern */
+} glob_t;
+.Ed
+.Pp
+The argument
+.Fa pattern
+is a pointer to a pathname pattern to be expanded.
+The
+.Fn glob
+argument
+matches all accessible pathnames against the pattern and creates
+a list of the pathnames that match.
+In order to have access to a pathname,
+.Fn glob
+requires search permission on every component of a path except the last
+and read permission on each directory of any filename component of
+.Fa pattern
+that contains any of the special characters
+.Ql * ,
+.Ql ?
+or
+.Ql [ .
+.Pp
+The
+.Fn glob
+argument
+stores the number of matched pathnames into the
+.Fa gl_pathc
+field, and a pointer to a list of pointers to pathnames into the
+.Fa gl_pathv
+field.
+The first pointer after the last pathname is
+.Dv NULL .
+If the pattern does not match any pathnames, the returned number of
+matched paths is set to zero.
+.Pp
+It is the caller's responsibility to create the structure pointed to by
+.Fa pglob .
+The
+.Fn glob
+function allocates other space as needed, including the memory pointed
+to by
+.Fa gl_pathv .
+.Pp
+The argument
+.Fa flags
+is used to modify the behavior of
+.Fn glob .
+The value of
+.Fa flags
+is the bitwise inclusive
+.Tn OR
+of any of the following
+values defined in
+.Pa glob.h :
+.Bl -tag -width GLOB_ALTDIRFUNC
+.It Dv GLOB_APPEND
+Append pathnames generated to the ones from a previous call (or calls)
+to
+.Fn glob .
+The value of
+.Fa gl_pathc
+will be the total matches found by this call and the previous call(s).
+The pathnames are appended to, not merged with the pathnames returned by
+the previous call(s).
+Between calls, the caller must not change the setting of the
+.Dv GLOB_DOOFFS
+flag, nor change the value of
+.Fa gl_offs
+when
+.Dv GLOB_DOOFFS
+is set, nor (obviously) call
+.Fn globfree
+for
+.Fa pglob .
+.It Dv GLOB_DOOFFS
+Make use of the
+.Fa gl_offs
+field.
+If this flag is set,
+.Fa gl_offs
+is used to specify how many
+.Dv NULL
+pointers to prepend to the beginning
+of the
+.Fa gl_pathv
+field.
+In other words,
+.Fa gl_pathv
+will point to
+.Fa gl_offs
+.Dv NULL
+pointers,
+followed by
+.Fa gl_pathc
+pathname pointers, followed by a
+.Dv NULL
+pointer.
+.It Dv GLOB_ERR
+Causes
+.Fn glob
+to return when it encounters a directory that it cannot open or read.
+Ordinarily,
+.Fn glob
+continues to find matches.
+.It Dv GLOB_MARK
+Each pathname that is a directory that matches
+.Fa pattern
+has a slash
+appended.
+.It Dv GLOB_NOCHECK
+If
+.Fa pattern
+does not match any pathname, then
+.Fn glob
+returns a list
+consisting of only
+.Fa pattern ,
+with the number of total pathnames is set to 1, and the number of matched
+pathnames set to 0.
+If
+.Dv GLOB_QUOTE
+is set, its effect is present in the pattern returned.
+.It Dv GLOB_NOSORT
+By default, the pathnames are sorted in ascending
+.Tn ASCII
+order;
+this flag prevents that sorting (speeding up
+.Fn glob ) .
+.El
+.Pp
+The following values may also be included in
+.Fa flags ,
+however, they are non-standard extensions to
+.St -p1003.2 .
+.Bl -tag -width GLOB_ALTDIRFUNC
+.It Dv GLOB_ALTDIRFUNC
+The following additional fields in the pglob structure have been
+initialized with alternate functions for glob to use to open, read,
+and close directories and to get stat information on names found
+in those directories.
+.Bd -literal
+void *(*gl_opendir)(const char * name);
+struct dirent *(*gl_readdir)(void *);
+void (*gl_closedir)(void *);
+int (*gl_lstat)(const char *name, struct stat *st);
+int (*gl_stat)(const char *name, struct stat *st);
+.Ed
+.Pp
+This extension is provided to allow programs such as
+.Xr restore 8
+to provide globbing from directories stored on tape.
+.It Dv GLOB_BRACE
+Pre-process the pattern string to expand
+.Ql {pat,pat,...}
+strings like
+.Xr csh 1 .
+The pattern
+.Ql {}
+is left unexpanded for historical reasons (and
+.Xr csh 1
+does the same thing to
+ease typing
+of
+.Xr find 1
+patterns).
+.It Dv GLOB_MAGCHAR
+Set by the
+.Fn glob
+function if the pattern included globbing characters.
+See the description of the usage of the
+.Fa gl_matchc
+structure member for more details.
+.It Dv GLOB_NOMAGIC
+Is the same as
+.Dv GLOB_NOCHECK
+but it only appends the
+.Fa pattern
+if it does not contain any of the special characters ``*'', ``?'' or ``[''.
+.Dv GLOB_NOMAGIC
+is provided to simplify implementing the historic
+.Xr csh 1
+globbing behavior and should probably not be used anywhere else.
+.It Dv GLOB_QUOTE
+Use the backslash
+.Pq Ql \e
+character for quoting: every occurrence of
+a backslash followed by a character in the pattern is replaced by that
+character, avoiding any special interpretation of the character.
+.It Dv GLOB_TILDE
+Expand patterns that start with
+.Ql ~
+to user name home directories.
+.El
+.Pp
+If, during the search, a directory is encountered that cannot be opened
+or read and
+.Fa errfunc
+is
+.Pf non- Dv NULL ,
+.Fn glob
+calls
+.Fa (*errfunc)(path, errno) .
+This may be unintuitive: a pattern like
+.Ql */Makefile
+will try to
+.Xr stat 2
+.Ql foo/Makefile
+even if
+.Ql foo
+is not a directory, resulting in a
+call to
+.Fa errfunc .
+The error routine can suppress this action by testing for
+.Dv ENOENT
+and
+.Dv ENOTDIR ;
+however, the
+.Dv GLOB_ERR
+flag will still cause an immediate
+return when this happens.
+.Pp
+If
+.Fa errfunc
+returns non-zero,
+.Fn glob
+stops the scan and returns
+.Dv GLOB_ABEND
+after setting
+.Fa gl_pathc
+and
+.Fa gl_pathv
+to reflect any paths already matched.
+This also happens if an error is encountered and
+.Dv GLOB_ERR
+is set in
+.Fa flags ,
+regardless of the return value of
+.Fa errfunc ,
+if called.
+If
+.Dv GLOB_ERR
+is not set and either
+.Fa errfunc
+is
+.Dv NULL
+or
+.Fa errfunc
+returns zero, the error is ignored.
+.Pp
+The
+.Fn globfree
+function frees any space associated with
+.Fa pglob
+from a previous call(s) to
+.Fn glob .
+.Sh RETURN VALUES
+On successful completion,
+.Fn glob
+returns zero.
+In addition the fields of
+.Fa pglob
+contain the values described below:
+.Bl -tag -width GLOB_NOCHECK
+.It Fa gl_pathc
+contains the total number of matched pathnames so far.
+This includes other matches from previous invocations of
+.Fn glob
+if
+.Dv GLOB_APPEND
+was specified.
+.It Fa gl_matchc
+contains the number of matched pathnames in the current invocation of
+.Fn glob .
+.It Fa gl_flags
+contains a copy of the
+.Fa flags
+parameter with the bit
+.Dv GLOB_MAGCHAR
+set if
+.Fa pattern
+contained any of the special characters ``*'', ``?'' or ``['', cleared
+if not.
+.It Fa gl_pathv
+contains a pointer to a
+.Dv NULL Ns -terminated
+list of matched pathnames.
+However, if
+.Fa gl_pathc
+is zero, the contents of
+.Fa gl_pathv
+are undefined.
+.El
+.Pp
+If
+.Fn glob
+terminates due to an error, it sets errno and returns one of the
+following non-zero constants, which are defined in the include
+file
+.Aq Pa glob.h :
+.Bl -tag -width GLOB_NOCHECK
+.It Dv GLOB_NOSPACE
+An attempt to allocate memory failed.
+.It Dv GLOB_ABEND
+The scan was stopped because an error was encountered and either
+.Dv GLOB_ERR
+was set or
+.Fa (*errfunc)()
+returned non-zero.
+.El
+.Pp
+The arguments
+.Fa pglob\->gl_pathc
+and
+.Fa pglob\->gl_pathv
+are still set as specified above.
+.Sh EXAMPLE
+A rough equivalent of
+.Ql "ls -l *.c *.h"
+can be obtained with the
+following code:
+.Bd -literal -offset indent
+glob_t g;
+
+g.gl_offs = 2;
+glob("*.c", GLOB_DOOFFS, NULL, &g);
+glob("*.h", GLOB_DOOFFS | GLOB_APPEND, NULL, &g);
+g.gl_pathv[0] = "ls";
+g.gl_pathv[1] = "-l";
+execvp("ls", g.gl_pathv);
+.Ed
+.Sh SEE ALSO
+.Xr sh 1 ,
+.Xr fnmatch 3 ,
+.Xr regexp 3
+.Sh STANDARDS
+The
+.Fn glob
+function is expected to be
+.St -p1003.2
+compatible with the exception
+that the flags
+.Dv GLOB_ALTDIRFUNC,
+.Dv GLOB_BRACE
+.Dv GLOB_MAGCHAR,
+.Dv GLOB_NOMAGIC,
+.Dv GLOB_QUOTE,
+and
+.Dv GLOB_TILDE,
+and the fields
+.Fa gl_matchc
+and
+.Fa gl_flags
+should not be used by applications striving for strict
+.Tn POSIX
+conformance.
+.Sh HISTORY
+The
+.Fn glob
+and
+.Fn globfree
+functions first appeared in
+.Bx 4.4 .
+.Sh BUGS
+Patterns longer than
+.Dv MAXPATHLEN
+may cause unchecked errors.
+.Pp
+The
+.Fn glob
+argument
+may fail and set errno for any of the errors specified for the
+library routines
+.Xr stat 2 ,
+.Xr closedir 3 ,
+.Xr opendir 3 ,
+.Xr readdir 3 ,
+.Xr malloc 3 ,
+and
+.Xr free 3 .
diff --git a/lib/libc/gen/glob.c b/lib/libc/gen/glob.c
new file mode 100644
index 0000000..09dfd7a
--- /dev/null
+++ b/lib/libc/gen/glob.c
@@ -0,0 +1,864 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * glob(3) -- a superset of the one defined in POSIX 1003.2.
+ *
+ * The [!...] convention to negate a range is supported (SysV, Posix, ksh).
+ *
+ * Optional extra services, controlled by flags not defined by POSIX:
+ *
+ * GLOB_QUOTE:
+ * Escaping convention: \ inhibits any special meaning the following
+ * character might have (except \ at end of string is retained).
+ * GLOB_MAGCHAR:
+ * Set in gl_flags if pattern contained a globbing character.
+ * GLOB_NOMAGIC:
+ * Same as GLOB_NOCHECK, but it will only append pattern if it did
+ * not contain any magic characters. [Used in csh style globbing]
+ * GLOB_ALTDIRFUNC:
+ * Use alternately specified directory access functions.
+ * GLOB_TILDE:
+ * expand ~user/foo to the /home/dir/of/user/foo
+ * GLOB_BRACE:
+ * expand {1,2}{a,b} to 1a 1b 2a 2b
+ * gl_matchc:
+ * Number of matches in the current invocation of glob.
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <glob.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "collate.h"
+
+#define DOLLAR '$'
+#define DOT '.'
+#define EOS '\0'
+#define LBRACKET '['
+#define NOT '!'
+#define QUESTION '?'
+#define QUOTE '\\'
+#define RANGE '-'
+#define RBRACKET ']'
+#define SEP '/'
+#define STAR '*'
+#define TILDE '~'
+#define UNDERSCORE '_'
+#define LBRACE '{'
+#define RBRACE '}'
+#define SLASH '/'
+#define COMMA ','
+
+#ifndef DEBUG
+
+#define M_QUOTE 0x8000
+#define M_PROTECT 0x4000
+#define M_MASK 0xffff
+#define M_ASCII 0x00ff
+
+typedef u_short Char;
+
+#else
+
+#define M_QUOTE 0x80
+#define M_PROTECT 0x40
+#define M_MASK 0xff
+#define M_ASCII 0x7f
+
+typedef char Char;
+
+#endif
+
+
+#define CHAR(c) ((Char)((c)&M_ASCII))
+#define META(c) ((Char)((c)|M_QUOTE))
+#define M_ALL META('*')
+#define M_END META(']')
+#define M_NOT META('!')
+#define M_ONE META('?')
+#define M_RNG META('-')
+#define M_SET META('[')
+#define ismeta(c) (((c)&M_QUOTE) != 0)
+
+
+static int compare __P((const void *, const void *));
+static void g_Ctoc __P((const Char *, char *));
+static int g_lstat __P((Char *, struct stat *, glob_t *));
+static DIR *g_opendir __P((Char *, glob_t *));
+static Char *g_strchr __P((Char *, int));
+#ifdef notdef
+static Char *g_strcat __P((Char *, const Char *));
+#endif
+static int g_stat __P((Char *, struct stat *, glob_t *));
+static int glob0 __P((const Char *, glob_t *));
+static int glob1 __P((Char *, glob_t *));
+static int glob2 __P((Char *, Char *, Char *, glob_t *));
+static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *));
+static int globextend __P((const Char *, glob_t *));
+static const Char * globtilde __P((const Char *, Char *, size_t, glob_t *));
+static int globexp1 __P((const Char *, glob_t *));
+static int globexp2 __P((const Char *, const Char *, glob_t *, int *));
+static int match __P((Char *, Char *, Char *));
+#ifdef DEBUG
+static void qprintf __P((const char *, Char *));
+#endif
+
+int
+glob(pattern, flags, errfunc, pglob)
+ const char *pattern;
+ int flags, (*errfunc) __P((const char *, int));
+ glob_t *pglob;
+{
+ const u_char *patnext;
+ int c;
+ Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
+
+ patnext = (u_char *) pattern;
+ if (!(flags & GLOB_APPEND)) {
+ pglob->gl_pathc = 0;
+ pglob->gl_pathv = NULL;
+ if (!(flags & GLOB_DOOFFS))
+ pglob->gl_offs = 0;
+ }
+ pglob->gl_flags = flags & ~GLOB_MAGCHAR;
+ pglob->gl_errfunc = errfunc;
+ pglob->gl_matchc = 0;
+
+ bufnext = patbuf;
+ bufend = bufnext + MAXPATHLEN;
+ if (flags & GLOB_QUOTE) {
+ /* Protect the quoted characters. */
+ while (bufnext < bufend && (c = *patnext++) != EOS)
+ if (c == QUOTE) {
+ if ((c = *patnext++) == EOS) {
+ c = QUOTE;
+ --patnext;
+ }
+ *bufnext++ = c | M_PROTECT;
+ }
+ else
+ *bufnext++ = c;
+ }
+ else
+ while (bufnext < bufend && (c = *patnext++) != EOS)
+ *bufnext++ = c;
+ *bufnext = EOS;
+
+ if (flags & GLOB_BRACE)
+ return globexp1(patbuf, pglob);
+ else
+ return glob0(patbuf, pglob);
+}
+
+/*
+ * Expand recursively a glob {} pattern. When there is no more expansion
+ * invoke the standard globbing routine to glob the rest of the magic
+ * characters
+ */
+static int globexp1(pattern, pglob)
+ const Char *pattern;
+ glob_t *pglob;
+{
+ const Char* ptr = pattern;
+ int rv;
+
+ /* Protect a single {}, for find(1), like csh */
+ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
+ return glob0(pattern, pglob);
+
+ while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL)
+ if (!globexp2(ptr, pattern, pglob, &rv))
+ return rv;
+
+ return glob0(pattern, pglob);
+}
+
+
+/*
+ * Recursive brace globbing helper. Tries to expand a single brace.
+ * If it succeeds then it invokes globexp1 with the new pattern.
+ * If it fails then it tries to glob the rest of the pattern and returns.
+ */
+static int globexp2(ptr, pattern, pglob, rv)
+ const Char *ptr, *pattern;
+ glob_t *pglob;
+ int *rv;
+{
+ int i;
+ Char *lm, *ls;
+ const Char *pe, *pm, *pl;
+ Char patbuf[MAXPATHLEN + 1];
+
+ /* copy part up to the brace */
+ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
+ continue;
+ ls = lm;
+
+ /* Find the balanced brace */
+ for (i = 0, pe = ++ptr; *pe; pe++)
+ if (*pe == LBRACKET) {
+ /* Ignore everything between [] */
+ for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
+ continue;
+ if (*pe == EOS) {
+ /*
+ * We could not find a matching RBRACKET.
+ * Ignore and just look for RBRACE
+ */
+ pe = pm;
+ }
+ }
+ else if (*pe == LBRACE)
+ i++;
+ else if (*pe == RBRACE) {
+ if (i == 0)
+ break;
+ i--;
+ }
+
+ /* Non matching braces; just glob the pattern */
+ if (i != 0 || *pe == EOS) {
+ *rv = glob0(patbuf, pglob);
+ return 0;
+ }
+
+ for (i = 0, pl = pm = ptr; pm <= pe; pm++)
+ switch (*pm) {
+ case LBRACKET:
+ /* Ignore everything between [] */
+ for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
+ continue;
+ if (*pm == EOS) {
+ /*
+ * We could not find a matching RBRACKET.
+ * Ignore and just look for RBRACE
+ */
+ pm = pl;
+ }
+ break;
+
+ case LBRACE:
+ i++;
+ break;
+
+ case RBRACE:
+ if (i) {
+ i--;
+ break;
+ }
+ /* FALLTHROUGH */
+ case COMMA:
+ if (i && *pm == COMMA)
+ break;
+ else {
+ /* Append the current string */
+ for (lm = ls; (pl < pm); *lm++ = *pl++)
+ continue;
+ /*
+ * Append the rest of the pattern after the
+ * closing brace
+ */
+ for (pl = pe + 1; (*lm++ = *pl++) != EOS;)
+ continue;
+
+ /* Expand the current pattern */
+#ifdef DEBUG
+ qprintf("globexp2:", patbuf);
+#endif
+ *rv = globexp1(patbuf, pglob);
+
+ /* move after the comma, to the next string */
+ pl = pm + 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ *rv = 0;
+ return 0;
+}
+
+
+
+/*
+ * expand tilde from the passwd file.
+ */
+static const Char *
+globtilde(pattern, patbuf, patbuf_len, pglob)
+ const Char *pattern;
+ Char *patbuf;
+ size_t patbuf_len;
+ glob_t *pglob;
+{
+ struct passwd *pwd;
+ char *h;
+ const Char *p;
+ Char *b, *eb;
+
+ if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
+ return pattern;
+
+ /*
+ * Copy up to the end of the string or /
+ */
+ eb = &patbuf[patbuf_len - 1];
+ for (p = pattern + 1, h = (char *) patbuf;
+ h < (char *)eb && *p && *p != SLASH; *h++ = *p++)
+ continue;
+
+ *h = EOS;
+
+ if (((char *) patbuf)[0] == EOS) {
+ /*
+ * handle a plain ~ or ~/ by expanding $HOME first (iff
+ * we're not running setuid or setgid) and then trying
+ * the password file
+ */
+ if (
+#ifndef __NETBSD_SYSCALLS
+ issetugid() != 0 ||
+#endif
+ (h = getenv("HOME")) == NULL) {
+ if (((h = getlogin()) != NULL &&
+ (pwd = getpwnam(h)) != NULL) ||
+ (pwd = getpwuid(getuid())) != NULL)
+ h = pwd->pw_dir;
+ else
+ return pattern;
+ }
+ }
+ else {
+ /*
+ * Expand a ~user
+ */
+ if ((pwd = getpwnam((char*) patbuf)) == NULL)
+ return pattern;
+ else
+ h = pwd->pw_dir;
+ }
+
+ /* Copy the home directory */
+ for (b = patbuf; b < eb && *h; *b++ = *h++)
+ continue;
+
+ /* Append the rest of the pattern */
+ while (b < eb && (*b++ = *p++) != EOS)
+ continue;
+ *b = EOS;
+
+ return patbuf;
+}
+
+
+/*
+ * The main glob() routine: compiles the pattern (optionally processing
+ * quotes), calls glob1() to do the real pattern matching, and finally
+ * sorts the list (unless unsorted operation is requested). Returns 0
+ * if things went well, nonzero if errors occurred. It is not an error
+ * to find no matches.
+ */
+static int
+glob0(pattern, pglob)
+ const Char *pattern;
+ glob_t *pglob;
+{
+ const Char *qpatnext;
+ int c, err, oldpathc;
+ Char *bufnext, patbuf[MAXPATHLEN+1];
+
+ qpatnext = globtilde(pattern, patbuf, sizeof(patbuf) / sizeof(Char),
+ pglob);
+ oldpathc = pglob->gl_pathc;
+ bufnext = patbuf;
+
+ /* We don't need to check for buffer overflow any more. */
+ while ((c = *qpatnext++) != EOS) {
+ switch (c) {
+ case LBRACKET:
+ c = *qpatnext;
+ if (c == NOT)
+ ++qpatnext;
+ if (*qpatnext == EOS ||
+ g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
+ *bufnext++ = LBRACKET;
+ if (c == NOT)
+ --qpatnext;
+ break;
+ }
+ *bufnext++ = M_SET;
+ if (c == NOT)
+ *bufnext++ = M_NOT;
+ c = *qpatnext++;
+ do {
+ *bufnext++ = CHAR(c);
+ if (*qpatnext == RANGE &&
+ (c = qpatnext[1]) != RBRACKET) {
+ *bufnext++ = M_RNG;
+ *bufnext++ = CHAR(c);
+ qpatnext += 2;
+ }
+ } while ((c = *qpatnext++) != RBRACKET);
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ *bufnext++ = M_END;
+ break;
+ case QUESTION:
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ *bufnext++ = M_ONE;
+ break;
+ case STAR:
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ /* collapse adjacent stars to one,
+ * to avoid exponential behavior
+ */
+ if (bufnext == patbuf || bufnext[-1] != M_ALL)
+ *bufnext++ = M_ALL;
+ break;
+ default:
+ *bufnext++ = CHAR(c);
+ break;
+ }
+ }
+ *bufnext = EOS;
+#ifdef DEBUG
+ qprintf("glob0:", patbuf);
+#endif
+
+ if ((err = glob1(patbuf, pglob)) != 0)
+ return(err);
+
+ /*
+ * If there was no match we are going to append the pattern
+ * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
+ * and the pattern did not contain any magic characters
+ * GLOB_NOMAGIC is there just for compatibility with csh.
+ */
+ if (pglob->gl_pathc == oldpathc &&
+ ((pglob->gl_flags & GLOB_NOCHECK) ||
+ ((pglob->gl_flags & GLOB_NOMAGIC) &&
+ !(pglob->gl_flags & GLOB_MAGCHAR))))
+ return(globextend(pattern, pglob));
+ else if (!(pglob->gl_flags & GLOB_NOSORT))
+ qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
+ pglob->gl_pathc - oldpathc, sizeof(char *), compare);
+ return(0);
+}
+
+static int
+compare(p, q)
+ const void *p, *q;
+{
+ return(strcmp(*(char **)p, *(char **)q));
+}
+
+static int
+glob1(pattern, pglob)
+ Char *pattern;
+ glob_t *pglob;
+{
+ Char pathbuf[MAXPATHLEN+1];
+
+ /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
+ if (*pattern == EOS)
+ return(0);
+ return(glob2(pathbuf, pathbuf, pattern, pglob));
+}
+
+/*
+ * The functions glob2 and glob3 are mutually recursive; there is one level
+ * of recursion for each segment in the pattern that contains one or more
+ * meta characters.
+ */
+static int
+glob2(pathbuf, pathend, pattern, pglob)
+ Char *pathbuf, *pathend, *pattern;
+ glob_t *pglob;
+{
+ struct stat sb;
+ Char *p, *q;
+ int anymeta;
+
+ /*
+ * Loop over pattern segments until end of pattern or until
+ * segment with meta character found.
+ */
+ for (anymeta = 0;;) {
+ if (*pattern == EOS) { /* End of pattern? */
+ *pathend = EOS;
+ if (g_lstat(pathbuf, &sb, pglob))
+ return(0);
+
+ if (((pglob->gl_flags & GLOB_MARK) &&
+ pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
+ || (S_ISLNK(sb.st_mode) &&
+ (g_stat(pathbuf, &sb, pglob) == 0) &&
+ S_ISDIR(sb.st_mode)))) {
+ *pathend++ = SEP;
+ *pathend = EOS;
+ }
+ ++pglob->gl_matchc;
+ return(globextend(pathbuf, pglob));
+ }
+
+ /* Find end of next segment, copy tentatively to pathend. */
+ q = pathend;
+ p = pattern;
+ while (*p != EOS && *p != SEP) {
+ if (ismeta(*p))
+ anymeta = 1;
+ *q++ = *p++;
+ }
+
+ if (!anymeta) { /* No expansion, do next segment. */
+ pathend = q;
+ pattern = p;
+ while (*pattern == SEP)
+ *pathend++ = *pattern++;
+ } else /* Need expansion, recurse. */
+ return(glob3(pathbuf, pathend, pattern, p, pglob));
+ }
+ /* NOTREACHED */
+}
+
+static int
+glob3(pathbuf, pathend, pattern, restpattern, pglob)
+ Char *pathbuf, *pathend, *pattern, *restpattern;
+ glob_t *pglob;
+{
+ register struct dirent *dp;
+ DIR *dirp;
+ int err;
+ char buf[MAXPATHLEN];
+
+ /*
+ * The readdirfunc declaration can't be prototyped, because it is
+ * assigned, below, to two functions which are prototyped in glob.h
+ * and dirent.h as taking pointers to differently typed opaque
+ * structures.
+ */
+ struct dirent *(*readdirfunc)();
+
+ *pathend = EOS;
+ errno = 0;
+
+ if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
+ /* TODO: don't call for ENOENT or ENOTDIR? */
+ if (pglob->gl_errfunc) {
+ g_Ctoc(pathbuf, buf);
+ if (pglob->gl_errfunc(buf, errno) ||
+ pglob->gl_flags & GLOB_ERR)
+ return (GLOB_ABEND);
+ }
+ return(0);
+ }
+
+ err = 0;
+
+ /* Search directory for matching names. */
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ readdirfunc = pglob->gl_readdir;
+ else
+ readdirfunc = readdir;
+ while ((dp = (*readdirfunc)(dirp))) {
+ register u_char *sc;
+ register Char *dc;
+
+ /* Initial DOT must be matched literally. */
+ if (dp->d_name[0] == DOT && *pattern != DOT)
+ continue;
+ for (sc = (u_char *) dp->d_name, dc = pathend;
+ (*dc++ = *sc++) != EOS;)
+ continue;
+ if (!match(pathend, pattern, restpattern)) {
+ *pathend = EOS;
+ continue;
+ }
+ err = glob2(pathbuf, --dc, restpattern, pglob);
+ if (err)
+ break;
+ }
+
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ (*pglob->gl_closedir)(dirp);
+ else
+ closedir(dirp);
+ return(err);
+}
+
+
+/*
+ * Extend the gl_pathv member of a glob_t structure to accomodate a new item,
+ * add the new item, and update gl_pathc.
+ *
+ * This assumes the BSD realloc, which only copies the block when its size
+ * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
+ * behavior.
+ *
+ * Return 0 if new item added, error code if memory couldn't be allocated.
+ *
+ * Invariant of the glob_t structure:
+ * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
+ * gl_pathv points to (gl_offs + gl_pathc + 1) items.
+ */
+static int
+globextend(path, pglob)
+ const Char *path;
+ glob_t *pglob;
+{
+ register char **pathv;
+ register int i;
+ u_int newsize;
+ char *copy;
+ const Char *p;
+
+ newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
+ pathv = pglob->gl_pathv ?
+ realloc((char *)pglob->gl_pathv, newsize) :
+ malloc(newsize);
+ if (pathv == NULL)
+ return(GLOB_NOSPACE);
+
+ if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
+ /* first time around -- clear initial gl_offs items */
+ pathv += pglob->gl_offs;
+ for (i = pglob->gl_offs; --i >= 0; )
+ *--pathv = NULL;
+ }
+ pglob->gl_pathv = pathv;
+
+ for (p = path; *p++;)
+ continue;
+ if ((copy = malloc(p - path)) != NULL) {
+ g_Ctoc(path, copy);
+ pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
+ }
+ pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
+ return(copy == NULL ? GLOB_NOSPACE : 0);
+}
+
+/*
+ * pattern matching function for filenames. Each occurrence of the *
+ * pattern causes a recursion level.
+ */
+static int
+match(name, pat, patend)
+ register Char *name, *pat, *patend;
+{
+ int ok, negate_range;
+ Char c, k;
+
+ while (pat < patend) {
+ c = *pat++;
+ switch (c & M_MASK) {
+ case M_ALL:
+ if (pat == patend)
+ return(1);
+ do
+ if (match(name, pat, patend))
+ return(1);
+ while (*name++ != EOS);
+ return(0);
+ case M_ONE:
+ if (*name++ == EOS)
+ return(0);
+ break;
+ case M_SET:
+ ok = 0;
+ if ((k = *name++) == EOS)
+ return(0);
+ if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
+ ++pat;
+ while (((c = *pat++) & M_MASK) != M_END)
+ if ((*pat & M_MASK) == M_RNG) {
+ if (__collate_load_error ?
+ CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1]) :
+ __collate_range_cmp(CHAR(c), CHAR(k)) <= 0
+ && __collate_range_cmp(CHAR(k), CHAR(pat[1])) <= 0
+ )
+ ok = 1;
+ pat += 2;
+ } else if (c == k)
+ ok = 1;
+ if (ok == negate_range)
+ return(0);
+ break;
+ default:
+ if (*name++ != c)
+ return(0);
+ break;
+ }
+ }
+ return(*name == EOS);
+}
+
+/* Free allocated data belonging to a glob_t structure. */
+void
+globfree(pglob)
+ glob_t *pglob;
+{
+ register int i;
+ register char **pp;
+
+ if (pglob->gl_pathv != NULL) {
+ pp = pglob->gl_pathv + pglob->gl_offs;
+ for (i = pglob->gl_pathc; i--; ++pp)
+ if (*pp)
+ free(*pp);
+ free(pglob->gl_pathv);
+ }
+}
+
+static DIR *
+g_opendir(str, pglob)
+ register Char *str;
+ glob_t *pglob;
+{
+ char buf[MAXPATHLEN];
+
+ if (!*str)
+ strcpy(buf, ".");
+ else
+ g_Ctoc(str, buf);
+
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ return((*pglob->gl_opendir)(buf));
+
+ return(opendir(buf));
+}
+
+static int
+g_lstat(fn, sb, pglob)
+ register Char *fn;
+ struct stat *sb;
+ glob_t *pglob;
+{
+ char buf[MAXPATHLEN];
+
+ g_Ctoc(fn, buf);
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ return((*pglob->gl_lstat)(buf, sb));
+ return(lstat(buf, sb));
+}
+
+static int
+g_stat(fn, sb, pglob)
+ register Char *fn;
+ struct stat *sb;
+ glob_t *pglob;
+{
+ char buf[MAXPATHLEN];
+
+ g_Ctoc(fn, buf);
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ return((*pglob->gl_stat)(buf, sb));
+ return(stat(buf, sb));
+}
+
+static Char *
+g_strchr(str, ch)
+ Char *str;
+ int ch;
+{
+ do {
+ if (*str == ch)
+ return (str);
+ } while (*str++);
+ return (NULL);
+}
+
+#ifdef notdef
+static Char *
+g_strcat(dst, src)
+ Char *dst;
+ const Char* src;
+{
+ Char *sdst = dst;
+
+ while (*dst++)
+ continue;
+ --dst;
+ while((*dst++ = *src++) != EOS)
+ continue;
+
+ return (sdst);
+}
+#endif
+
+static void
+g_Ctoc(str, buf)
+ register const Char *str;
+ char *buf;
+{
+ register char *dc;
+
+ for (dc = buf; (*dc++ = *str++) != EOS;)
+ continue;
+}
+
+#ifdef DEBUG
+static void
+qprintf(str, s)
+ const char *str;
+ register Char *s;
+{
+ register Char *p;
+
+ (void)printf("%s:\n", str);
+ for (p = s; *p; p++)
+ (void)printf("%c", CHAR(*p));
+ (void)printf("\n");
+ for (p = s; *p; p++)
+ (void)printf("%c", *p & M_PROTECT ? '"' : ' ');
+ (void)printf("\n");
+ for (p = s; *p; p++)
+ (void)printf("%c", ismeta(*p) ? '_' : ' ');
+ (void)printf("\n");
+}
+#endif
diff --git a/lib/libc/gen/initgroups.3 b/lib/libc/gen/initgroups.3
new file mode 100644
index 0000000..5ed1e06
--- /dev/null
+++ b/lib/libc/gen/initgroups.3
@@ -0,0 +1,84 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)initgroups.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt INITGROUPS 3
+.Os BSD 4.2
+.Sh NAME
+.Nm initgroups
+.Nd initialize group access list
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn initgroups "const char *name" "int basegid"
+.Sh DESCRIPTION
+The
+.Fn initgroups
+function
+uses the
+.Xr getgrouplist 3
+function to calculate the group access list for the user
+specified in
+.Fa name .
+This group list is then setup for the current process using
+.Xr setgroups 2 .
+The
+.Fa basegid
+is automatically included in the groups list.
+Typically this value is given as
+the group number from the password file.
+.Sh RETURN VALUES
+The
+.Fn initgroups
+function
+returns \-1 if it was not invoked by the super-user.
+.Sh SEE ALSO
+.Xr setgroups 2 ,
+.Xr getgrouplist 3
+.Sh HISTORY
+The
+.Fn initgroups
+function appeared in
+.Bx 4.2 .
+.Sh BUGS
+The
+.Fn getgrouplist
+function called by
+.Fn initgroups
+uses the routines based on
+.Xr getgrent 3 .
+If the invoking program uses any of these routines,
+the group structure will
+be overwritten in the call to
+.Fn initgroups .
diff --git a/lib/libc/gen/initgroups.c b/lib/libc/gen/initgroups.c
new file mode 100644
index 0000000..b1ddd86
--- /dev/null
+++ b/lib/libc/gen/initgroups.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)initgroups.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <err.h>
+#include <unistd.h>
+
+int
+initgroups(uname, agroup)
+ const char *uname;
+ int agroup;
+{
+ int groups[NGROUPS], ngroups;
+
+ ngroups = NGROUPS;
+ if (getgrouplist(uname, agroup, groups, &ngroups) < 0)
+ warnx("%s is in too many groups, using first %d",
+ uname, ngroups);
+ if (setgroups(ngroups, groups) < 0) {
+ warn("setgroups");
+ return (-1);
+ }
+ return (0);
+}
diff --git a/lib/libc/gen/isatty.c b/lib/libc/gen/isatty.c
new file mode 100644
index 0000000..f14f470
--- /dev/null
+++ b/lib/libc/gen/isatty.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)isatty.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <termios.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
+
+int
+isatty(fd)
+ int fd;
+{
+ int retval;
+ struct termios t;
+
+#ifdef _THREAD_SAFE
+ if (_FD_LOCK(fd, FD_READ, NULL) == 0) {
+#endif
+ retval = (tcgetattr(fd, &t) != -1);
+#ifdef _THREAD_SAFE
+ _FD_UNLOCK(fd, FD_READ);
+ } else {
+ retval = 0;
+ }
+#endif
+ return(retval);
+}
diff --git a/lib/libc/gen/isinf.3 b/lib/libc/gen/isinf.3
new file mode 100644
index 0000000..592bd04
--- /dev/null
+++ b/lib/libc/gen/isinf.3
@@ -0,0 +1,73 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)isinf.3 8.2 (Berkeley) 1/29/94
+.\" $FreeBSD$
+.\"
+.Dd January 29, 1994
+.Dt ISINF 3
+.Os
+.Sh NAME
+.Nm isinf ,
+.Nm isnan
+.Nd test for infinity or not-a-number
+.Sh SYNOPSIS
+.Ft int
+.Fn isinf double
+.Ft int
+.Fn isnan double
+.Sh DESCRIPTION
+The
+.Fn isinf
+function
+returns 1 if the number is
+.Dq \\*(If ,
+otherwise 0.
+.Pp
+The
+.Fn isnan
+function
+returns 1 if the number is
+.Dq not-a-number ,
+otherwise 0.
+.Sh SEE ALSO
+.Xr math 3
+.Rs
+.%T "IEEE Standard for Binary Floating-Point Arithmetic"
+.%Q ANSI
+.%R Std 754-1985
+.Re
+.Sh BUGS
+Neither the
+.Tn VAX
+nor the Tahoe floating point have distinguished values
+for either infinity or not-a-number.
+These routines always return 0 on those architectures.
diff --git a/lib/libc/gen/jrand48.c b/lib/libc/gen/jrand48.c
new file mode 100644
index 0000000..051d5a6
--- /dev/null
+++ b/lib/libc/gen/jrand48.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#include "rand48.h"
+
+long
+jrand48(unsigned short xseed[3])
+{
+ _dorand48(xseed);
+ return ((long) xseed[2] << 16) + (long) xseed[1];
+}
diff --git a/lib/libc/gen/lcong48.c b/lib/libc/gen/lcong48.c
new file mode 100644
index 0000000..f13826b
--- /dev/null
+++ b/lib/libc/gen/lcong48.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#include "rand48.h"
+
+extern unsigned short _rand48_seed[3];
+extern unsigned short _rand48_mult[3];
+extern unsigned short _rand48_add;
+
+void
+lcong48(unsigned short p[7])
+{
+ _rand48_seed[0] = p[0];
+ _rand48_seed[1] = p[1];
+ _rand48_seed[2] = p[2];
+ _rand48_mult[0] = p[3];
+ _rand48_mult[1] = p[4];
+ _rand48_mult[2] = p[5];
+ _rand48_add = p[6];
+}
diff --git a/lib/libc/gen/ldexp.3 b/lib/libc/gen/ldexp.3
new file mode 100644
index 0000000..8a0ffef
--- /dev/null
+++ b/lib/libc/gen/ldexp.3
@@ -0,0 +1,78 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ldexp.3 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt LDEXP 3
+.Os
+.Sh NAME
+.Nm ldexp
+.Nd multiply floating-point number by integral power of 2
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn ldexp "double x" "int exp"
+.Sh DESCRIPTION
+The
+.Fn ldexp
+function multiplies a floating-point number by an integral
+power of 2.
+.Sh RETURN VALUES
+The
+.Fn ldexp
+function returns the value of
+.Fa x
+times 2 raised to the power
+.Fa exp .
+.Pp
+If the resultant value would cause an overflow,
+the global variable
+.Va errno
+is set to
+.Er ERANGE
+and the value
+.Dv HUGE
+is returned.
+.Sh SEE ALSO
+.Xr frexp 3 ,
+.Xr math 3 ,
+.Xr modf 3
+.Sh STANDARDS
+The
+.Fn ldexp
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/gen/lockf.3 b/lib/libc/gen/lockf.3
index 6094ff1..1cfc40a 100644
--- a/lib/libc/gen/lockf.3
+++ b/lib/libc/gen/lockf.3
@@ -34,14 +34,14 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
+.\" $FreeBSD$
+.\"
.Dd December 19, 1997
.Dt LOCKF 3
.Os NetBSD 1.4
.Sh NAME
.Nm lockf
.Nd record locking on files
-.Sh LIBRARY
-.Lb libc
.Sh SYNOPSIS
.Fd #include <unistd.h>
.Ft int
diff --git a/lib/libc/gen/lockf.c b/lib/libc/gen/lockf.c
index 0419390..3363d58 100644
--- a/lib/libc/gen/lockf.c
+++ b/lib/libc/gen/lockf.c
@@ -36,21 +36,15 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: lockf.c,v 1.1 1997/12/20 20:23:18 kleink Exp $");
+static const char rcsid[]=
+ "$FreeBSD$";
#endif
-#include "namespace.h"
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
-#ifdef __weak_alias
-__weak_alias(lockf,_lockf);
-#endif
-
-
int
lockf(filedes, function, size)
int filedes;
diff --git a/lib/libc/gen/lrand48.c b/lib/libc/gen/lrand48.c
new file mode 100644
index 0000000..a3d0111
--- /dev/null
+++ b/lib/libc/gen/lrand48.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#include "rand48.h"
+
+extern unsigned short _rand48_seed[3];
+
+long
+lrand48(void)
+{
+ _dorand48(_rand48_seed);
+ return ((long) _rand48_seed[2] << 15) + ((long) _rand48_seed[1] >> 1);
+}
diff --git a/lib/libc/gen/modf.3 b/lib/libc/gen/modf.3
new file mode 100644
index 0000000..c2941a8
--- /dev/null
+++ b/lib/libc/gen/modf.3
@@ -0,0 +1,73 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)modf.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt MODF 3
+.Os
+.Sh NAME
+.Nm modf
+.Nd extract signed integral and fractional values from floating-point number
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn modf "double value" "double *iptr"
+.Sh DESCRIPTION
+The
+.Fn modf
+function breaks the argument
+.Fa value
+into integral and fractional parts, each of which has the
+same sign as the argument.
+It stores the integral part as a
+.Em double
+in the object pointed to by
+.Fa iptr .
+.Sh RETURN VALUES
+The
+.Fn modf
+function returns the signed fractional part of
+.Fa value .
+.Sh SEE ALSO
+.Xr frexp 3 ,
+.Xr ldexp 3 ,
+.Xr math 3
+.Sh STANDARDS
+The
+.Fn modf
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/gen/mrand48.c b/lib/libc/gen/mrand48.c
new file mode 100644
index 0000000..b23db51
--- /dev/null
+++ b/lib/libc/gen/mrand48.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#include "rand48.h"
+
+extern unsigned short _rand48_seed[3];
+
+long
+mrand48(void)
+{
+ _dorand48(_rand48_seed);
+ return ((long) _rand48_seed[2] << 16) + (long) _rand48_seed[1];
+}
diff --git a/lib/libc/gen/msgctl.3 b/lib/libc/gen/msgctl.3
new file mode 100644
index 0000000..326e8a5
--- /dev/null
+++ b/lib/libc/gen/msgctl.3
@@ -0,0 +1,210 @@
+.\" $NetBSD: msgctl.2,v 1.1 1995/10/16 23:49:15 jtc Exp $
+.\"
+.\" Copyright (c) 1995 Frank van der Linden
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed for the NetBSD Project
+.\" by Frank van der Linden
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"/
+.Dd November 24, 1997
+.Dt MSGCTL 3
+.Os FreeBSD
+.Sh NAME
+.Nm msgctl
+.Nd message control operations
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/ipc.h>
+.Fd #include <sys/msg.h>
+.Ft int
+.Fn msgctl "int msqid" "int cmd" "struct msqid_ds *buf"
+.Sh DESCRIPTION
+The
+.Fn msgctl
+system call performs some control operations on the message queue specified
+by
+.Fa msqid .
+
+Each message queue has a data structure associated with it, parts of which
+may be altered by
+.Fn msgctl
+and parts of which determine the actions of
+.Fn msgctl .
+The data structure is defined in
+.Aq Pa sys/msg.h
+and contains (amongst others) the following members:
+.Bd -literal
+struct msqid_ds {
+ struct ipc_perm msg_perm; /* msg queue permission bits */
+ struct msg *msg_first; /* first message in the queue */
+ struct msg *msg_last; /* last message in the queue */
+ u_long msg_cbytes; /* number of bytes in use on the queue */
+ u_long msg_qnum; /* number of msgs in the queue */
+ u_long msg_qbytes; /* max # of bytes on the queue */
+ pid_t msg_lspid; /* pid of last msgsnd() */
+ pid_t msg_lrpid; /* pid of last msgrcv() */
+ time_t msg_stime; /* time of last msgsnd() */
+ long msg_pad1;
+ time_t msg_rtime; /* time of last msgrcv() */
+ long msg_pad2;
+ time_t msg_ctime; /* time of last msgctl() */
+ long msg_pad3;
+ long msg_pad4[4];
+};
+.Ed
+.Pp
+The
+.Bf -literal
+ipc_perm
+.Ef
+structure used inside the
+.Bf -literal
+shmid_ds
+.Ef
+structure is defined in
+.Aq Pa sys/ipc.h
+and looks like this:
+.Bd -literal
+struct ipc_perm {
+ ushort cuid; /* creator user id */
+ ushort cgid; /* creator group id */
+ ushort uid; /* user id */
+ ushort gid; /* group id */
+ ushort mode; /* r/w permission */
+ ushort seq; /* sequence # (to generate unique msg/sem/shm id) */
+ key_t key; /* user specified msg/sem/shm key */
+};
+.Ed
+.Pp
+The operation to be performed by
+.Fn msgctl
+is specified in
+.Fa cmd
+and is one of:
+.Bl -tag -width IPC_RMIDX
+.It Dv IPC_STAT
+Gather information about the message queue and place it in the
+structure pointed to by
+.Fa buf .
+.It Dv IPC_SET
+Set the value of the
+.Va msg_perm.uid ,
+.Va msg_perm.gid ,
+.Va msg_perm.mode
+and
+.Va msg_qbytes
+fields in the structure associated with
+.Fa msqid .
+The values are taken from the corresponding fields in the structure
+pointed to by
+.Fa buf .
+This operation can only be executed by the super-user, or a process that
+has an effective user id equal to either
+.Va msg_perm.cuid
+or
+.Va msg_perm.uid
+in the data structure associated with the message queue.
+The value of
+.Va msg_qbytes
+can only be increased by the super-user. Values for
+.Va msg_qbytes
+that exceed the system limit (MSGMNB from
+.Aq Pa sys/msg.h )
+are silently truncated to that limit.
+
+.It Dv IPC_RMID
+Remove the message queue specified by
+.Fa msqid
+and destroy the data associated with it. Only the super-user or a process
+with an effective uid equal to the
+.Va msg_perm.cuid
+or
+.Va msg_perm.uid
+values in the data structure associated with the queue can do this.
+.El
+
+The permission to read from or write to a message queue (see
+.Xr msgsnd 3
+and
+.Xr msgrcv 3 )
+is determined by the
+.Va msg_perm.mode
+field in the same way as is
+done with files (see
+.Xr chmod 2 ),
+but the effective uid can match either the
+.Va msg_perm.cuid
+field or the
+.Va msg_perm.uid
+field, and the
+effective gid can match either
+.Va msg_perm.cgid
+or
+.Va msg_perm.gid .
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned. Otherwise, -1 is
+returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn msgctl
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+.Fa cmd
+is equal to IPC_SET or IPC_RMID and the caller is not the super-user, nor does
+the effective uid match either the
+.Va msg_perm.uid
+or
+.Va msg_perm.cuid
+fields of the data structure associated with the message queue.
+
+An attempt is made to increase the value of
+.Va msg_qbytes
+through IPC_SET
+but the caller is not the super-user.
+.It Bq Er EACCES
+The command is IPC_STAT
+and the caller has no read permission for this message queue.
+.It Bq Er EINVAL
+.Fa msqid
+is not a valid message queue identifier.
+
+.Va cmd
+is not a valid command.
+.It Bq Er EFAULT
+.Fa buf
+specifies an invalid address.
+.El
+.Sh SEE ALSO
+.Xr msgget 3 ,
+.Xr msgrcv 3 ,
+.Xr msgsnd 3
+.Sh HISTORY
+Message queues appeared in the first release of
+.At V .
diff --git a/lib/libc/gen/msgctl.c b/lib/libc/gen/msgctl.c
new file mode 100644
index 0000000..7b74c51e
--- /dev/null
+++ b/lib/libc/gen/msgctl.c
@@ -0,0 +1,15 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#if __STDC__
+int msgctl(int msqid, int cmd, struct msqid_ds *buf)
+#else
+int msgctl(msqid,cmd,buf)
+ int msqid;
+ int cmd;
+ caddr_t buf;
+#endif
+{
+ return (msgsys(0, msqid, cmd, buf));
+}
diff --git a/lib/libc/gen/msgget.3 b/lib/libc/gen/msgget.3
new file mode 100644
index 0000000..f68cd8a
--- /dev/null
+++ b/lib/libc/gen/msgget.3
@@ -0,0 +1,137 @@
+.\" $NetBSD: msgget.2,v 1.1 1995/10/16 23:49:19 jtc Exp $
+.\"
+.\" Copyright (c) 1995 Frank van der Linden
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed for the NetBSD Project
+.\" by Frank van der Linden
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\" $FreeBSD$
+.\"
+.\"/
+.Dd August 17, 1995
+.Dt MSGGET 3
+.Os FreeBSD
+.Sh NAME
+.Nm msgget
+.Nd get message queue
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/ipc.h>
+.Fd #include <sys/msg.h>
+.Ft int
+.Fn msgget "key_t key" "int msgflg"
+.Sh DESCRIPTION
+.Fn msgget
+returns the message queue identifier associated with
+.Fa key .
+A message queue identifier is a unique integer greater than zero.
+.Pp
+A message queue is created if either
+.Fa key
+is equal to
+.Dv IPC_PRIVATE ,
+or
+.Fa key
+does not have a message queue identifier associated with it, and the
+.Dv IPC_CREAT
+bit is set in
+.Fa msgflg.
+.Pp
+If a new message queue is created, the data structure associated with it (the
+.Va msqid_ds
+structure, see
+.Xr msgctl 3 )
+is initialized as follows:
+.Bl -bullet
+.It
+.Va msg_perm.cuid
+and
+.Va msg_perm.uid
+are set to the effective uid of the calling process.
+.It
+.Va msg_perm.gid
+and
+.Va msg_perm.cgid
+are set to the effective gid of the calling process.
+.It
+.Va msg_perm.mode
+is set to the lower 9 bits of
+.Fa msgflg .
+.It
+.Va msg_cbytes ,
+.Va msg_qnum ,
+.Va msg_lspid ,
+.Va msg_lrpid ,
+.Va msg_rtime ,
+and
+.Va msg_stime
+are set to 0.
+.It
+.Va msg_qbytes
+is set to the system wide maximum value for the number of bytes in a queue
+.Pf ( Dv MSGMNB ) .
+.It
+.Va msg_ctime
+is set to the current time.
+.El
+.Sh RETURN VALUES
+Upon successful completion a positive message queue identifier is returned.
+Otherwise, -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Bl -tag -width Er
+.It Bq Er EACCES
+A message queue is already associated with
+.Fa key
+and the caller has no permission to access it.
+.It Bq Er EEXIST
+Both
+.Dv IPC_CREAT
+and
+.Dv IPC_EXCL
+are set in
+.Fa msgflg ,
+and a message queue is already associated with
+.Fa key .
+.It Bq Er ENOSPC
+A new message queue could not be created because the system limit for
+the number of message queues has been reached.
+.It Bq Er ENOENT
+.Dv IPC_CREAT
+was not set in
+.Fa msgflg
+and no message queue associated with
+.Fa key
+was found.
+.El
+.Sh SEE ALSO
+.Xr msgctl 3 ,
+.Xr msgrcv 3 ,
+.Xr msgsnd 3
+.Sh HISTORY
+Message queues appeared in the first release of
+.At V .
diff --git a/lib/libc/gen/msgget.c b/lib/libc/gen/msgget.c
new file mode 100644
index 0000000..3e146b0
--- /dev/null
+++ b/lib/libc/gen/msgget.c
@@ -0,0 +1,14 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#if __STDC__
+int msgget(key_t key, int msgflg)
+#else
+int msgget(key,msgflg)
+ key_t key;
+ int msgflg;
+#endif
+{
+ return (msgsys(1, key, msgflg));
+}
diff --git a/lib/libc/gen/msgrcv.3 b/lib/libc/gen/msgrcv.3
new file mode 100644
index 0000000..e4aa45d
--- /dev/null
+++ b/lib/libc/gen/msgrcv.3
@@ -0,0 +1,209 @@
+.\" $NetBSD: msgrcv.2,v 1.1 1995/10/16 23:49:20 jtc Exp $
+.\"
+.\" Copyright (c) 1995 Frank van der Linden
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed for the NetBSD Project
+.\" by Frank van der Linden
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\" $FreeBSD$
+.\"
+.\"/
+.Dd November 24, 1997
+.Dt MSGRCV 3
+.Os FreeBSD
+.Sh NAME
+.Nm msgrcv
+.Nd receive a message from a message queue
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/ipc.h>
+.Fd #include <sys/msg.h>
+.Ft int
+.Fn msgrcv "int msqid" "void *msgp" "size_t msgsz" "long msgtyp" "int msgflg"
+.Sh DESCRIPTION
+The
+.Fn msgrcv
+function receives a message from the message queue specified in
+.Fa msqid ,
+and places it into the structure pointed to by
+.Fa msgp .
+This structure should consist of the following members:
+.Bd -literal
+ long mtype; /* message type */
+ char mtext[1]; /* body of message */
+.Ed
+.Pp
+.Va mtype
+is an integer greater than 0 that can be used for selecting messages,
+.Va mtext
+is an array of bytes, with a size up to that of the system limit
+.Pf ( Dv MSGMAX ) .
+.Pp
+The value of
+.Fa msgtyp
+has one of the following meanings:
+.Bl -bullet
+.It
+.Fa msgtyp
+is greater than 0. The first message of type
+.Fa msgtyp
+will be received.
+.It
+.Fa msgtyp
+is equal to 0. The first message on the queue will be received.
+.It
+.Fa msgtyp
+is less than 0. The first message of the lowest message type that is
+less than or equal to the absolute value of
+.Fa msgtyp
+will be received.
+.El
+.Pp
+.Fa msgsz
+specifies the maximum length of the requested message. If the received
+message has a length greater than
+.Fa msgsz
+it will be silently truncated if the
+.Dv MSG_NOERROR
+flag is set in
+.Fa msgflg ,
+otherwise an error will be returned.
+.Pp
+If no matching message is present on the message queue specified by
+.Fa msqid ,
+the behavior of
+.Fn msgrcv
+depends on whether the
+.Dv IPC_NOWAIT
+flag is set in
+.Fa msgflg
+or not. If
+.Dv IPC_NOWAIT
+is set,
+.Fn msgrcv
+will immediately return a value of -1, and set
+.Va errno
+to
+.Er EAGAIN .
+If
+.Dv IPC_NOWAIT
+is not set, the calling process will be blocked
+until:
+.Bl -bullet
+.It
+A message of the requested type becomes available on the message queue.
+.It
+The message queue is removed, in which case -1 will be returned, and
+.Va errno
+set to
+.Er EINVAL .
+.It
+A signal is received and caught. -1 is returned, and
+.Va errno
+set to
+.Er EINTR .
+.El
+.Pp
+If a message is successfully received, the data structure associated with
+.Fa msqid
+is updated as follows:
+.Bl -bullet
+.It
+.Va msg_cbytes
+is decremented by the size of the message.
+.It
+.Va msg_lrpid
+is set to the pid of the caller.
+.It
+.Va msg_lrtime
+is set to the current time.
+.It
+.Va msg_qnum
+is decremented by 1.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn msgrcv
+returns the number of bytes received into the
+.Va mtext
+field of the structure pointed to by
+.Fa msgp .
+Otherwise, -1 is returned, and
+.Va errno
+set to indicate the error.
+.Sh ERRORS
+.Fn msgrcv
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+.Fa msqid
+is not a valid message queue identifier.
+.Pp
+The message queue was removed while
+.Fn msgrcv
+was waiting for a message of the requested type to become available on it.
+.Pp
+.Fa msgsz
+is less than 0.
+.It Bq Er E2BIG
+A matching message was received, but its size was greater than
+.Fa msgsz
+and the
+.Dv MSG_NOERROR
+flag was not set in
+.Fa msgflg .
+.It Bq Er EACCES
+The calling process does not have read access to the message queue.
+.It Bq Er EFAULT
+.Fa msgp
+points to an invalid address.
+.It Bq Er EINTR
+The system call was interrupted by the delivery of a signal.
+.It Bq Er EAGAIN
+There is no message of the requested type available on the message queue,
+and
+.Dv IPC_NOWAIT
+is set in
+.Fa msgflg .
+.Sh SEE ALSO
+.Xr msgctl 3 ,
+.Xr msgget 3 ,
+.Xr msgsnd 3
+.Sh BUGS
+.Tn NetBSD
+and
+.Tn FreeBSD
+do not define the
+.Er EIDRM
+error value, which should be used in
+the case of a removed message queue, nor the
+.Er ENOMSG
+value, which
+should be used when no suitable message is available and
+.Dv IPC_NOWAIT
+is set.
+.Sh HISTORY
+Message queues appeared in the first release of
+.At V .
diff --git a/lib/libc/gen/msgrcv.c b/lib/libc/gen/msgrcv.c
new file mode 100644
index 0000000..5c1e387
--- /dev/null
+++ b/lib/libc/gen/msgrcv.c
@@ -0,0 +1,17 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#if __STDC__
+int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
+#else
+int msgrcv(msqid, msgp, msgsz, msgtyp, msgflg)
+ int msqid;
+ void *msgp;
+ size_t msgsz;
+ long msgtyp;
+ int msgflg;
+#endif
+{
+ return (msgsys(3, msqid, msgp, msgsz, msgtyp, msgflg));
+}
diff --git a/lib/libc/gen/msgsnd.3 b/lib/libc/gen/msgsnd.3
new file mode 100644
index 0000000..8946c1c
--- /dev/null
+++ b/lib/libc/gen/msgsnd.3
@@ -0,0 +1,164 @@
+.\" $NetBSD: msgsnd.2,v 1.1 1995/10/16 23:49:24 jtc Exp $
+.\"
+.\" Copyright (c) 1995 Frank van der Linden
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed for the NetBSD Project
+.\" by Frank van der Linden
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\" $FreeBSD$
+.\"
+.\"/
+.Dd November 24, 1997
+.Dt MSGSND 3
+.Os FreeBSD
+.Sh NAME
+.Nm msgsnd
+.Nd send a message to a message queue
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/ipc.h>
+.Fd #include <sys/msg.h>
+.Ft int
+.Fn msgsnd "int msqid" "void *msgp" "size_t msgsz" "int msgflg"
+.Sh DESCRIPTION
+The
+.Fn msgsnd
+function sends a message from the message queue specified in
+.Fa msqid .
+.Fa msgp
+points to a structure containing the message. This structure should
+consist of the following members:
+.Bd -literal
+ long mtype; /* message type */
+ char mtext[1]; /* body of message */
+.Ed
+.Pp
+.Va mtype
+is an integer greater than 0 that can be used for selecting messages (see
+.Xr msgrcv 3 ) ,
+.Va mtext
+is an array of bytes, with a size up to that of the system limit
+.Pf ( Dv MSGMAX ) .
+.Pp
+If the number of bytes already on the message queue plus
+.Fa msgsz
+is bigger than the maximum number of bytes on the message queue
+.Pf ( Va msg_qbytes ,
+see
+.Xr msgctl 3 ) ,
+or the number of messages on all queues system-wide is already equal to
+the system limit,
+.Fa msgflg
+determines the action of
+.Fn msgsnd .
+If
+.Fa msgflg
+has
+.Dv IPC_NOWAIT
+mask set in it, the call will return immediately. If
+.Fa msgflg
+does not have
+.Dv IPC_NOWAIT
+set in it, the call will block until:
+.Bl -bullet
+.It
+The condition which caused the call to block does no longer exist.
+The message will be sent.
+.It
+The message queue is removed, in which case -1 will be returned, and
+.Va errno
+is set to
+.Er EINVAL .
+.It
+The caller catches a signal. The call returns with
+.Va errno
+set to
+.Er EINTR .
+.El
+.Pp
+After a successful call, the data structure associated with the message
+queue is updated in the following way:
+.Bl -bullet
+.It
+.Va msg_cbytes
+is incremented by the size of the message.
+.It
+.Va msg_qnum
+is incremented by 1.
+.It
+.Va msg_lspid
+is set to the pid of the calling process.
+.It
+.Va msg_stime
+is set to the current time.
+.El
+.Sh RETURN VALUES
+Upon successful completion, 0 is returned. Otherwise, -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn msgsnd
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+.Fa msqid
+is not a valid message queue identifier
+.Pp
+The message queue was removed while
+.Fn msgsnd
+was waiting for a resource to become available in order to deliver the
+message.
+.Pp
+.Fa msgsz
+is less than 0, or greater than
+.Va msg_qbytes .
+.Pp
+.Fa mtype
+is not greater than 0.
+.It Bq Er EACCES
+The calling process does not have write access to the message queue.
+.It Bq Er EAGAIN
+There was no space for this message either on the queue, or in the whole
+system, and
+.Dv IPC_NOWAIT
+was set in
+.Fa msgflg .
+.It Bq Er EFAULT
+.Fa msgp
+points to an invalid address.
+.It Bq Er EINTR
+The system call was interrupted by the delivery of a signal.
+.El
+.Sh BUGS
+.Tn NetBSD
+and
+.Tn FreeBSD
+do not define the
+.Er EIDRM
+error value, which should be used
+in the case of a removed message queue.
+.Sh HISTORY
+Message queues appeared in the first release of AT&T Unix System V.
diff --git a/lib/libc/gen/msgsnd.c b/lib/libc/gen/msgsnd.c
new file mode 100644
index 0000000..a620915
--- /dev/null
+++ b/lib/libc/gen/msgsnd.c
@@ -0,0 +1,16 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#if __STDC__
+int msgsnd(int msqid, void *msgp, size_t msgsz, int msgflg)
+#else
+int msgsnd(msqid, msgp, msgsz, msgflg)
+ int msqid;
+ void *msgp;
+ size_t msgsz;
+ int msgflg;
+#endif
+{
+ return (msgsys(2, msqid, msgp, msgsz, msgflg));
+}
diff --git a/lib/libc/gen/nice.3 b/lib/libc/gen/nice.3
new file mode 100644
index 0000000..d61ec2e
--- /dev/null
+++ b/lib/libc/gen/nice.3
@@ -0,0 +1,70 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)nice.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt NICE 3
+.Os BSD 4
+.Sh NAME
+.Nm nice
+.Nd set program scheduling priority
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn nice "int incr"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is obsoleted by setpriority(2).
+.Ef
+.Pp
+The
+.Fn nice
+function obtains the scheduling priority of the process
+from the system and sets it to the priority value specified in
+.Fa incr .
+The priority is a value in the range -20 to 20.
+The default priority is 0; lower priorities cause more favorable scheduling.
+Only the super-user may lower priorities.
+.Pp
+Children inherit the priority of their parent processes via
+.Xr fork 2 .
+.Sh SEE ALSO
+.Xr nice 1 ,
+.Xr fork 2 ,
+.Xr setpriority 2 ,
+.Xr renice 8
+.Sh HISTORY
+A
+.Fn nice
+syscall appeared in
+.At v6 .
diff --git a/lib/libc/gen/nice.c b/lib/libc/gen/nice.c
new file mode 100644
index 0000000..104c1a2
--- /dev/null
+++ b/lib/libc/gen/nice.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)nice.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <errno.h>
+#include <unistd.h>
+
+/*
+ * Backwards compatible nice.
+ */
+int
+nice(incr)
+ int incr;
+{
+ int prio;
+
+ errno = 0;
+ prio = getpriority(PRIO_PROCESS, 0);
+ if (prio == -1 && errno)
+ return (-1);
+ return (setpriority(PRIO_PROCESS, 0, prio + incr));
+}
diff --git a/lib/libc/gen/nlist.3 b/lib/libc/gen/nlist.3
new file mode 100644
index 0000000..69add4a
--- /dev/null
+++ b/lib/libc/gen/nlist.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)nlist.3 8.3 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt NLIST 3
+.Os BSD 4
+.Sh NAME
+.Nm nlist
+.Nd retrieve symbol table name list from an executable file
+.Sh SYNOPSIS
+.Fd #include <nlist.h>
+.Ft int
+.Fn nlist "const char *filename" "struct nlist *nl"
+.Sh DESCRIPTION
+The
+.Fn nlist
+function
+retrieves name list entries from the symbol table of an
+executable file (see
+.Xr a.out 5 ) .
+The argument
+.Fa \&nl
+is set to reference the
+beginning of the list.
+The list is preened of binary and invalid data;
+if an entry in the
+name list is valid, the
+.Fa n_type
+and
+.Fa n_value
+for the entry are copied into the list
+referenced by
+.Fa \&nl .
+No other data is copied.
+The last entry in the list is always
+.Dv NULL .
+.Sh RETURN VALUES
+The number of invalid entries is returned if successful; otherwise,
+if the file
+.Fa filename
+does not exist or is not executable, the returned value is \-1.
+.Sh SEE ALSO
+.Xr a.out 5
+.Sh HISTORY
+A
+.Fn nlist
+function appeared in
+.At v6 .
diff --git a/lib/libc/gen/nlist.c b/lib/libc/gen/nlist.c
new file mode 100644
index 0000000..55f4f39
--- /dev/null
+++ b/lib/libc/gen/nlist.c
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)nlist.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+
+#include <errno.h>
+#include <a.out.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#define _NLIST_DO_AOUT
+#define _NLIST_DO_ELF
+
+#ifdef _NLIST_DO_ELF
+#include <elf.h>
+#endif
+
+int __fdnlist __P((int, struct nlist *));
+int __aout_fdnlist __P((int, struct nlist *));
+int __elf_fdnlist __P((int, struct nlist *));
+
+int
+nlist(name, list)
+ const char *name;
+ struct nlist *list;
+{
+ int fd, n;
+
+ fd = open(name, O_RDONLY, 0);
+ if (fd < 0)
+ return (-1);
+ n = __fdnlist(fd, list);
+ (void)close(fd);
+ return (n);
+}
+
+static struct nlist_handlers {
+ int (*fn) __P((int fd, struct nlist *list));
+} nlist_fn[] = {
+#ifdef _NLIST_DO_AOUT
+ { __aout_fdnlist },
+#endif
+#ifdef _NLIST_DO_ELF
+ { __elf_fdnlist },
+#endif
+};
+
+int
+__fdnlist(fd, list)
+ register int fd;
+ register struct nlist *list;
+{
+ int n = -1, i;
+
+ for (i = 0; i < sizeof(nlist_fn) / sizeof(nlist_fn[0]); i++) {
+ n = (nlist_fn[i].fn)(fd, list);
+ if (n != -1)
+ break;
+ }
+ return (n);
+}
+
+#define ISLAST(p) (p->n_un.n_name == 0 || p->n_un.n_name[0] == 0)
+
+#ifdef _NLIST_DO_AOUT
+int
+__aout_fdnlist(fd, list)
+ register int fd;
+ register struct nlist *list;
+{
+ register struct nlist *p, *symtab;
+ register caddr_t strtab, a_out_mmap;
+ register off_t stroff, symoff;
+ register u_long symsize;
+ register int nent;
+ struct exec * exec;
+ struct stat st;
+
+ /* check that file is at least as large as struct exec! */
+ if ((fstat(fd, &st) < 0) || (st.st_size < sizeof(struct exec)))
+ return (-1);
+
+ /* Check for files too large to mmap. */
+ if (st.st_size > SIZE_T_MAX) {
+ errno = EFBIG;
+ return (-1);
+ }
+
+ /*
+ * Map the whole a.out file into our address space.
+ * We then find the string table withing this area.
+ * We do not just mmap the string table, as it probably
+ * does not start at a page boundary - we save ourselves a
+ * lot of nastiness by mmapping the whole file.
+ *
+ * This gives us an easy way to randomly access all the strings,
+ * without making the memory allocation permanent as with
+ * malloc/free (i.e., munmap will return it to the system).
+ */
+ a_out_mmap = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t)0);
+ if (a_out_mmap == MAP_FAILED)
+ return (-1);
+
+ exec = (struct exec *)a_out_mmap;
+ if (N_BADMAG(*exec)) {
+ munmap(a_out_mmap, (size_t)st.st_size);
+ return (-1);
+ }
+
+ symoff = N_SYMOFF(*exec);
+ symsize = exec->a_syms;
+ stroff = symoff + symsize;
+
+ /* find the string table in our mmapped area */
+ strtab = a_out_mmap + stroff;
+ symtab = (struct nlist *)(a_out_mmap + symoff);
+
+ /*
+ * clean out any left-over information for all valid entries.
+ * Type and value defined to be 0 if not found; historical
+ * versions cleared other and desc as well. Also figure out
+ * the largest string length so don't read any more of the
+ * string table than we have to.
+ *
+ * XXX clearing anything other than n_type and n_value violates
+ * the semantics given in the man page.
+ */
+ nent = 0;
+ for (p = list; !ISLAST(p); ++p) {
+ p->n_type = 0;
+ p->n_other = 0;
+ p->n_desc = 0;
+ p->n_value = 0;
+ ++nent;
+ }
+
+ while (symsize > 0) {
+ register int soff;
+
+ symsize-= sizeof(struct nlist);
+ soff = symtab->n_un.n_strx;
+
+
+ if (soff != 0 && (symtab->n_type & N_STAB) == 0)
+ for (p = list; !ISLAST(p); p++)
+ if (!strcmp(&strtab[soff], p->n_un.n_name)) {
+ p->n_value = symtab->n_value;
+ p->n_type = symtab->n_type;
+ p->n_desc = symtab->n_desc;
+ p->n_other = symtab->n_other;
+ if (--nent <= 0)
+ break;
+ }
+ symtab++;
+ }
+ munmap(a_out_mmap, (size_t)st.st_size);
+ return (nent);
+}
+#endif
+
+#ifdef _NLIST_DO_ELF
+static void elf_sym_to_nlist __P((struct nlist *, Elf_Sym *, Elf_Shdr *, int));
+
+/*
+ * __elf_is_okay__ - Determine if ehdr really
+ * is ELF and valid for the target platform.
+ *
+ * WARNING: This is NOT a ELF ABI function and
+ * as such it's use should be restricted.
+ */
+int
+__elf_is_okay__(ehdr)
+ register Elf_Ehdr *ehdr;
+{
+ register int retval = 0;
+ /*
+ * We need to check magic, class size, endianess,
+ * and version before we look at the rest of the
+ * Elf_Ehdr structure. These few elements are
+ * represented in a machine independant fashion.
+ */
+ if (IS_ELF(*ehdr) &&
+ ehdr->e_ident[EI_CLASS] == ELF_TARG_CLASS &&
+ ehdr->e_ident[EI_DATA] == ELF_TARG_DATA &&
+ ehdr->e_ident[EI_VERSION] == ELF_TARG_VER) {
+
+ /* Now check the machine dependant header */
+ if (ehdr->e_machine == ELF_TARG_MACH &&
+ ehdr->e_version == ELF_TARG_VER)
+ retval = 1;
+ }
+ return retval;
+}
+
+int
+__elf_fdnlist(fd, list)
+ register int fd;
+ register struct nlist *list;
+{
+ register struct nlist *p;
+ register Elf_Off symoff = 0, symstroff = 0;
+ register Elf_Word symsize = 0, symstrsize = 0;
+ register Elf_Sword cc, i;
+ int nent = -1;
+ int errsave;
+ Elf_Sym sbuf[1024];
+ Elf_Sym *s;
+ Elf_Ehdr ehdr;
+ char *strtab = NULL;
+ Elf_Shdr *shdr = NULL;
+ Elf_Shdr *sh;
+ Elf_Word shdr_size;
+ void *base;
+ struct stat st;
+
+ /* Make sure obj is OK */
+ if (lseek(fd, (off_t)0, SEEK_SET) == -1 ||
+ read(fd, &ehdr, sizeof(Elf_Ehdr)) != sizeof(Elf_Ehdr) ||
+ !__elf_is_okay__(&ehdr) ||
+ fstat(fd, &st) < 0)
+ return (-1);
+
+ /* calculate section header table size */
+ shdr_size = ehdr.e_shentsize * ehdr.e_shnum;
+
+ /* Make sure it's not too big to mmap */
+ if (shdr_size > SIZE_T_MAX) {
+ errno = EFBIG;
+ return (-1);
+ }
+
+ /* mmap section header table */
+ base = mmap(NULL, (size_t)shdr_size, PROT_READ, 0, fd,
+ (off_t)ehdr.e_shoff);
+ if (base == MAP_FAILED)
+ return (-1);
+ shdr = (Elf_Shdr *)base;
+
+ /*
+ * Find the symbol table entry and it's corresponding
+ * string table entry. Version 1.1 of the ABI states
+ * that there is only one symbol table but that this
+ * could change in the future.
+ */
+ for (i = 0; i < ehdr.e_shnum; i++) {
+ if (shdr[i].sh_type == SHT_SYMTAB) {
+ symoff = shdr[i].sh_offset;
+ symsize = shdr[i].sh_size;
+ symstroff = shdr[shdr[i].sh_link].sh_offset;
+ symstrsize = shdr[shdr[i].sh_link].sh_size;
+ break;
+ }
+ }
+
+ /* Check for files too large to mmap. */
+ if (symstrsize > SIZE_T_MAX) {
+ errno = EFBIG;
+ goto done;
+ }
+ /*
+ * Map string table into our address space. This gives us
+ * an easy way to randomly access all the strings, without
+ * making the memory allocation permanent as with malloc/free
+ * (i.e., munmap will return it to the system).
+ */
+ base = mmap(NULL, (size_t)symstrsize, PROT_READ, 0, fd,
+ (off_t)symstroff);
+ if (base == MAP_FAILED)
+ goto done;
+ strtab = (char *)base;
+
+ /*
+ * clean out any left-over information for all valid entries.
+ * Type and value defined to be 0 if not found; historical
+ * versions cleared other and desc as well. Also figure out
+ * the largest string length so don't read any more of the
+ * string table than we have to.
+ *
+ * XXX clearing anything other than n_type and n_value violates
+ * the semantics given in the man page.
+ */
+ nent = 0;
+ for (p = list; !ISLAST(p); ++p) {
+ p->n_type = 0;
+ p->n_other = 0;
+ p->n_desc = 0;
+ p->n_value = 0;
+ ++nent;
+ }
+
+ /* Don't process any further if object is stripped. */
+ if (symoff == 0)
+ goto done;
+
+ if (lseek(fd, (off_t) symoff, SEEK_SET) == -1) {
+ nent = -1;
+ goto done;
+ }
+
+ while (symsize > 0 && nent > 0) {
+ cc = MIN(symsize, sizeof(sbuf));
+ if (read(fd, sbuf, cc) != cc)
+ break;
+ symsize -= cc;
+ for (s = sbuf; cc > 0 && nent > 0; ++s, cc -= sizeof(*s)) {
+ char *name;
+ struct nlist *p;
+
+ name = strtab + s->st_name;
+ if (name[0] == '\0')
+ continue;
+ for (p = list; !ISLAST(p); p++) {
+ if ((p->n_un.n_name[0] == '_' &&
+ strcmp(name, p->n_un.n_name+1) == 0)
+ || strcmp(name, p->n_un.n_name) == 0) {
+ elf_sym_to_nlist(p, s, shdr,
+ ehdr.e_shnum);
+ if (--nent <= 0)
+ break;
+ }
+ }
+ }
+ }
+ done:
+ errsave = errno;
+ if (strtab != NULL)
+ munmap(strtab, symstrsize);
+ if (shdr != NULL)
+ munmap(shdr, shdr_size);
+ errno = errsave;
+ return (nent);
+}
+
+/*
+ * Convert an Elf_Sym into an nlist structure. This fills in only the
+ * n_value and n_type members.
+ */
+static void
+elf_sym_to_nlist(nl, s, shdr, shnum)
+ struct nlist *nl;
+ Elf_Sym *s;
+ Elf_Shdr *shdr;
+ int shnum;
+{
+ nl->n_value = s->st_value;
+
+ switch (s->st_shndx) {
+ case SHN_UNDEF:
+ case SHN_COMMON:
+ nl->n_type = N_UNDF;
+ break;
+ case SHN_ABS:
+ nl->n_type = ELF_ST_TYPE(s->st_info) == STT_FILE ?
+ N_FN : N_ABS;
+ break;
+ default:
+ if (s->st_shndx >= shnum)
+ nl->n_type = N_UNDF;
+ else {
+ Elf_Shdr *sh = shdr + s->st_shndx;
+
+ nl->n_type = sh->sh_type == SHT_PROGBITS ?
+ (sh->sh_flags & SHF_WRITE ? N_DATA : N_TEXT) :
+ (sh->sh_type == SHT_NOBITS ? N_BSS : N_UNDF);
+ }
+ break;
+ }
+
+ if (ELF_ST_BIND(s->st_info) == STB_GLOBAL ||
+ ELF_ST_BIND(s->st_info) == STB_WEAK)
+ nl->n_type |= N_EXT;
+}
+#endif /* _NLIST_DO_ELF */
diff --git a/lib/libc/gen/nrand48.c b/lib/libc/gen/nrand48.c
new file mode 100644
index 0000000..6c54065
--- /dev/null
+++ b/lib/libc/gen/nrand48.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#include "rand48.h"
+
+long
+nrand48(unsigned short xseed[3])
+{
+ _dorand48(xseed);
+ return ((long) xseed[2] << 15) + ((long) xseed[1] >> 1);
+}
diff --git a/lib/libc/gen/ntp_gettime.c b/lib/libc/gen/ntp_gettime.c
new file mode 100644
index 0000000..3bb71c1
--- /dev/null
+++ b/lib/libc/gen/ntp_gettime.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/timex.h>
+
+int
+ntp_gettime(struct ntptimeval *ntv)
+{
+ struct ntptimeval tv;
+ size_t size = sizeof tv;
+
+ if (sysctlbyname("kern.ntp_pll.gettime", &tv, &size, NULL, 0) == -1)
+ return TIME_ERROR;
+ if(ntv) *ntv = tv;
+ return tv.time_state;
+}
+
diff --git a/lib/libc/gen/opendir.c b/lib/libc/gen/opendir.c
new file mode 100644
index 0000000..ff01646
--- /dev/null
+++ b/lib/libc/gen/opendir.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)opendir.c 8.8 (Berkeley) 5/1/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * Open a directory.
+ */
+DIR *
+opendir(name)
+ const char *name;
+{
+
+ return (__opendir2(name, DTF_HIDEW|DTF_NODUP));
+}
+
+DIR *
+__opendir2(name, flags)
+ const char *name;
+ int flags;
+{
+ DIR *dirp;
+ int fd;
+ int incr;
+ int saved_errno;
+ int unionstack;
+ struct stat statb;
+
+ /*
+ * stat() before open() because opening of special files may be
+ * harmful. fstat() after open because the file may have changed.
+ */
+ if (stat(name, &statb) != 0)
+ return (NULL);
+ if (!S_ISDIR(statb.st_mode)) {
+ errno = ENOTDIR;
+ return (NULL);
+ }
+ if ((fd = open(name, O_RDONLY | O_NONBLOCK)) == -1)
+ return (NULL);
+ dirp = NULL;
+ if (fstat(fd, &statb) != 0)
+ goto fail;
+ if (!S_ISDIR(statb.st_mode)) {
+ errno = ENOTDIR;
+ goto fail;
+ }
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1 ||
+ (dirp = malloc(sizeof(DIR))) == NULL)
+ goto fail;
+
+ /*
+ * Use the system page size if that is a multiple of DIRBLKSIZ.
+ * Hopefully this can be a big win someday by allowing page
+ * trades to user space to be done by getdirentries().
+ */
+ incr = getpagesize();
+ if ((incr % DIRBLKSIZ) != 0)
+ incr = DIRBLKSIZ;
+
+ /*
+ * Determine whether this directory is the top of a union stack.
+ */
+ if (flags & DTF_NODUP) {
+ struct statfs sfb;
+
+ if (fstatfs(fd, &sfb) < 0)
+ goto fail;
+ unionstack = !strcmp(sfb.f_fstypename, "union");
+ } else {
+ unionstack = 0;
+ }
+
+ if (unionstack) {
+ int len = 0;
+ int space = 0;
+ char *buf = 0;
+ char *ddptr = 0;
+ char *ddeptr;
+ int n;
+ struct dirent **dpv;
+
+ /*
+ * The strategy here is to read all the directory
+ * entries into a buffer, sort the buffer, and
+ * remove duplicate entries by setting the inode
+ * number to zero.
+ */
+
+ do {
+ /*
+ * Always make at least DIRBLKSIZ bytes
+ * available to getdirentries
+ */
+ if (space < DIRBLKSIZ) {
+ space += incr;
+ len += incr;
+ buf = reallocf(buf, len);
+ if (buf == NULL)
+ goto fail;
+ ddptr = buf + (len - space);
+ }
+
+ n = getdirentries(fd, ddptr, space, &dirp->dd_seek);
+ if (n > 0) {
+ ddptr += n;
+ space -= n;
+ }
+ } while (n > 0);
+
+ ddeptr = ddptr;
+ flags |= __DTF_READALL;
+
+ /*
+ * Re-open the directory.
+ * This has the effect of rewinding back to the
+ * top of the union stack and is needed by
+ * programs which plan to fchdir to a descriptor
+ * which has also been read -- see fts.c.
+ */
+ if (flags & DTF_REWIND) {
+ (void) close(fd);
+ if ((fd = open(name, O_RDONLY)) == -1) {
+ saved_errno = errno;
+ free(buf);
+ free(dirp);
+ errno = saved_errno;
+ return (NULL);
+ }
+ }
+
+ /*
+ * There is now a buffer full of (possibly) duplicate
+ * names.
+ */
+ dirp->dd_buf = buf;
+
+ /*
+ * Go round this loop twice...
+ *
+ * Scan through the buffer, counting entries.
+ * On the second pass, save pointers to each one.
+ * Then sort the pointers and remove duplicate names.
+ */
+ for (dpv = 0;;) {
+ n = 0;
+ ddptr = buf;
+ while (ddptr < ddeptr) {
+ struct dirent *dp;
+
+ dp = (struct dirent *) ddptr;
+ if ((long)dp & 03L)
+ break;
+ if ((dp->d_reclen <= 0) ||
+ (dp->d_reclen > (ddeptr + 1 - ddptr)))
+ break;
+ ddptr += dp->d_reclen;
+ if (dp->d_fileno) {
+ if (dpv)
+ dpv[n] = dp;
+ n++;
+ }
+ }
+
+ if (dpv) {
+ struct dirent *xp;
+
+ /*
+ * This sort must be stable.
+ */
+ mergesort(dpv, n, sizeof(*dpv), alphasort);
+
+ dpv[n] = NULL;
+ xp = NULL;
+
+ /*
+ * Scan through the buffer in sort order,
+ * zapping the inode number of any
+ * duplicate names.
+ */
+ for (n = 0; dpv[n]; n++) {
+ struct dirent *dp = dpv[n];
+
+ if ((xp == NULL) ||
+ strcmp(dp->d_name, xp->d_name)) {
+ xp = dp;
+ } else {
+ dp->d_fileno = 0;
+ }
+ if (dp->d_type == DT_WHT &&
+ (flags & DTF_HIDEW))
+ dp->d_fileno = 0;
+ }
+
+ free(dpv);
+ break;
+ } else {
+ dpv = malloc((n+1) * sizeof(struct dirent *));
+ if (dpv == NULL)
+ break;
+ }
+ }
+
+ dirp->dd_len = len;
+ dirp->dd_size = ddptr - dirp->dd_buf;
+ } else {
+ dirp->dd_len = incr;
+ dirp->dd_buf = malloc(dirp->dd_len);
+ if (dirp->dd_buf == NULL)
+ goto fail;
+ dirp->dd_seek = 0;
+ flags &= ~DTF_REWIND;
+ }
+
+ dirp->dd_loc = 0;
+ dirp->dd_fd = fd;
+ dirp->dd_flags = flags;
+
+ /*
+ * Set up seek point for rewinddir.
+ */
+ dirp->dd_rewind = telldir(dirp);
+
+ return (dirp);
+
+fail:
+ saved_errno = errno;
+ free(dirp);
+ (void) close(fd);
+ errno = saved_errno;
+ return (NULL);
+}
diff --git a/lib/libc/gen/pause.3 b/lib/libc/gen/pause.3
new file mode 100644
index 0000000..e48bc8e
--- /dev/null
+++ b/lib/libc/gen/pause.3
@@ -0,0 +1,84 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)pause.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt PAUSE 3
+.Os BSD 4
+.Sh NAME
+.Nm pause
+.Nd stop until signal
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn pause void
+.Sh DESCRIPTION
+.Sy Pause is made obsolete by
+.Xr sigsuspend 2 .
+.Pp
+The
+.Fn pause
+function
+forces a process to pause until
+a signal is received from either the
+.Xr kill 2
+function
+or an interval timer.
+(See
+.Xr setitimer 2 . )
+Upon termination of a signal handler started during a
+.Fn pause ,
+the
+.Fn pause
+call will return.
+.Sh RETURN VALUES
+Always returns \-1.
+.Sh ERRORS
+The
+.Fn pause
+function
+always returns:
+.Bl -tag -width [EINTR]
+.It Bq Er EINTR
+The call was interrupted.
+.El
+.Sh SEE ALSO
+.Xr kill 2 ,
+.Xr select 2 ,
+.Xr sigsuspend 2
+.Sh HISTORY
+A
+.Fn pause
+syscall
+appeared in
+.At v6 .
diff --git a/lib/libc/gen/pause.c b/lib/libc/gen/pause.c
new file mode 100644
index 0000000..9cbe467
--- /dev/null
+++ b/lib/libc/gen/pause.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)pause.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <signal.h>
+#include <unistd.h>
+
+/*
+ * Backwards compatible pause.
+ */
+int
+pause()
+{
+
+ return sigpause(sigblock(0L));
+}
diff --git a/lib/libc/gen/popen.3 b/lib/libc/gen/popen.3
new file mode 100644
index 0000000..53004c0
--- /dev/null
+++ b/lib/libc/gen/popen.3
@@ -0,0 +1,200 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)popen.3 8.2 (Berkeley) 5/3/95
+.\" $FreeBSD$
+.\"
+.Dd May 3, 1995
+.Dt POPEN 3
+.Os
+.Sh NAME
+.Nm popen ,
+.Nm pclose
+.Nd process
+.Tn I/O
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft FILE *
+.Fn popen "const char *command" "const char *type"
+.Ft int
+.Fn pclose "FILE *stream"
+.Sh DESCRIPTION
+The
+.Fn popen
+function
+.Dq opens
+a process by creating a bidirectional pipe
+forking,
+and invoking the shell.
+Any streams opened by previous
+.Fn popen
+calls in the parent process are closed in the new child process.
+Historically,
+.Fn popen
+was implemented with a unidirectional pipe;
+hence many implementations of
+.Fn popen
+only allow the
+.Fa type
+argument to specify reading or writing, not both.
+Since
+.Fn popen
+is now implemented using a bidirectional pipe, the
+.Fa type
+argument may request a bidirectional data flow.
+The
+.Fa type
+argument is a pointer to a null-terminated string
+which must be
+.Ql r
+for reading,
+.Ql w
+for writing, or
+.Ql r+
+for reading and writing.
+.Pp
+The
+.Fa command
+argument is a pointer to a null-terminated string
+containing a shell command line.
+This command is passed to
+.Pa /bin/sh
+using the
+.Fl c
+flag; interpretation, if any, is performed by the shell.
+.Pp
+The return value from
+.Fn popen
+is a normal standard
+.Tn I/O
+stream in all respects
+save that it must be closed with
+.Fn pclose
+rather than
+.Fn fclose .
+Writing to such a stream
+writes to the standard input of the command;
+the command's standard output is the same as that of the process that called
+.Fn popen ,
+unless this is altered by the command itself.
+Conversely, reading from a
+.Dq popened
+stream reads the command's standard output, and
+the command's standard input is the same as that of the process that called
+.Fn popen .
+.Pp
+Note that output
+.Fn popen
+streams are fully buffered by default.
+.Pp
+The
+.Fn pclose
+function waits for the associated process to terminate
+and returns the exit status of the command
+as returned by
+.Fn wait4 .
+.Sh RETURN VALUE
+The
+.Fn popen
+function returns
+.Dv NULL
+if the
+.Xr fork 2
+or
+.Xr pipe 2
+calls fail,
+or if it cannot allocate memory.
+.Pp
+The
+.Fn pclose
+function
+returns \-1 if
+.Fa stream
+is not associated with a
+.Dq popened
+command, if
+.Fa stream
+already
+.Dq pclosed ,
+or if
+.Xr wait4
+returns an error.
+.Sh ERRORS
+The
+.Fn popen
+function does not reliably set
+.Va errno .
+.Sh SEE ALSO
+.Xr sh 1 ,
+.Xr fork 2 ,
+.Xr pipe 2 ,
+.Xr wait4 2 ,
+.Xr fclose 3 ,
+.Xr fflush 3 ,
+.Xr fopen 3 ,
+.Xr stdio 3 ,
+.Xr system 3
+.Sh BUGS
+Since the standard input of a command opened for reading
+shares its seek offset with the process that called
+.Fn popen ,
+if the original process has done a buffered read,
+the command's input position may not be as expected.
+Similarly, the output from a command opened for writing
+may become intermingled with that of the original process.
+The latter can be avoided by calling
+.Xr fflush 3
+before
+.Fn popen .
+.Pp
+Failure to execute the shell
+is indistinguishable from the shell's failure to execute command,
+or an immediate exit of the command.
+The only hint is an exit status of 127.
+.Pp
+The
+.Fn popen
+argument
+always calls
+.Xr sh 1 ,
+never calls
+.Xr csh 1 .
+.Sh HISTORY
+A
+.Fn popen
+and a
+.Fn pclose
+function appeared in
+.At v7 .
+.br
+Bidirectional functionality was added in
+.Tn FreeBSD
+2.2.6.
diff --git a/lib/libc/gen/popen.c b/lib/libc/gen/popen.c
new file mode 100644
index 0000000..bcbd164
--- /dev/null
+++ b/lib/libc/gen/popen.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software written by Ken Arnold and
+ * published in UNIX Review, Vol. 6, No. 8.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 5/3/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/wait.h>
+
+#include <signal.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <paths.h>
+
+extern char **environ;
+
+static struct pid {
+ struct pid *next;
+ FILE *fp;
+ pid_t pid;
+} *pidlist;
+
+FILE *
+popen(command, type)
+ const char *command, *type;
+{
+ struct pid *cur;
+ FILE *iop;
+ int pdes[2], pid, twoway;
+ char *argv[4];
+ struct pid *p;
+
+ /*
+ * Lite2 introduced two-way popen() pipes using socketpair().
+ * FreeBSD's pipe() is bidirectional, so we use that.
+ */
+ if (strchr(type, '+')) {
+ twoway = 1;
+ type = "r+";
+ } else {
+ twoway = 0;
+ if ((*type != 'r' && *type != 'w') || type[1])
+ return (NULL);
+ }
+ if (pipe(pdes) < 0)
+ return (NULL);
+
+ if ((cur = malloc(sizeof(struct pid))) == NULL) {
+ (void)close(pdes[0]);
+ (void)close(pdes[1]);
+ return (NULL);
+ }
+
+ argv[0] = "sh";
+ argv[1] = "-c";
+ argv[2] = (char *)command;
+ argv[3] = NULL;
+
+ switch (pid = vfork()) {
+ case -1: /* Error. */
+ (void)close(pdes[0]);
+ (void)close(pdes[1]);
+ free(cur);
+ return (NULL);
+ /* NOTREACHED */
+ case 0: /* Child. */
+ if (*type == 'r') {
+ /*
+ * The dup2() to STDIN_FILENO is repeated to avoid
+ * writing to pdes[1], which might corrupt the
+ * parent's copy. This isn't good enough in
+ * general, since the _exit() is no return, so
+ * the compiler is free to corrupt all the local
+ * variables.
+ */
+ (void) close(pdes[0]);
+ if (pdes[1] != STDOUT_FILENO) {
+ (void)dup2(pdes[1], STDOUT_FILENO);
+ (void)close(pdes[1]);
+ if (twoway)
+ (void)dup2(STDOUT_FILENO, STDIN_FILENO);
+ } else if (twoway && (pdes[1] != STDIN_FILENO))
+ (void)dup2(pdes[1], STDIN_FILENO);
+ } else {
+ if (pdes[0] != STDIN_FILENO) {
+ (void)dup2(pdes[0], STDIN_FILENO);
+ (void)close(pdes[0]);
+ }
+ (void)close(pdes[1]);
+ }
+ for (p = pidlist; p; p = p->next) {
+ (void)close(fileno(p->fp));
+ }
+ execve(_PATH_BSHELL, argv, environ);
+ _exit(127);
+ /* NOTREACHED */
+ }
+
+ /* Parent; assume fdopen can't fail. */
+ if (*type == 'r') {
+ iop = fdopen(pdes[0], type);
+ (void)close(pdes[1]);
+ } else {
+ iop = fdopen(pdes[1], type);
+ (void)close(pdes[0]);
+ }
+
+ /* Link into list of file descriptors. */
+ cur->fp = iop;
+ cur->pid = pid;
+ cur->next = pidlist;
+ pidlist = cur;
+
+ return (iop);
+}
+
+/*
+ * pclose --
+ * Pclose returns -1 if stream is not associated with a `popened' command,
+ * if already `pclosed', or waitpid returns an error.
+ */
+int
+pclose(iop)
+ FILE *iop;
+{
+ register struct pid *cur, *last;
+ int omask;
+ int pstat;
+ pid_t pid;
+
+ /* Find the appropriate file pointer. */
+ for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
+ if (cur->fp == iop)
+ break;
+ if (cur == NULL)
+ return (-1);
+
+ (void)fclose(iop);
+
+ do {
+ pid = waitpid(cur->pid, &pstat, 0);
+ } while (pid == -1 && errno == EINTR);
+
+ /* Remove the entry from the linked list. */
+ if (last == NULL)
+ pidlist = cur->next;
+ else
+ last->next = cur->next;
+ free(cur);
+
+ return (pid == -1 ? -1 : pstat);
+}
diff --git a/lib/libc/gen/psignal.3 b/lib/libc/gen/psignal.3
new file mode 100644
index 0000000..325f8ec
--- /dev/null
+++ b/lib/libc/gen/psignal.3
@@ -0,0 +1,110 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)psignal.3 8.2 (Berkeley) 2/27/95
+.\" $FreeBSD$
+.\"
+.Dd February 27, 1995
+.Dt PSIGNAL 3
+.Os BSD 4.2
+.Sh NAME
+.Nm psignal ,
+.Nm strsignal ,
+.Nm sys_siglist ,
+.Nm sys_signame
+.Nd system signal messages
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Ft void
+.Fn psignal "unsigned sig" "const char *s"
+.Ft "char *"
+.Fn strsignal "unsigned sig"
+.Vt extern const char * const sys_siglist[];
+.Vt extern const char * const sys_signame[];
+.Sh DESCRIPTION
+The
+.Fn psignal
+and
+.Fn strsignal
+functions locate the descriptive message
+string for a signal number.
+.Pp
+The
+.Fn strsignal
+function accepts a signal number argument
+.Fa sig
+and returns a pointer to the corresponding message string.
+.Pp
+The
+.Fn psignal
+function accepts an signal number argument
+.Fa sig
+and writes it to the standard error.
+If the argument
+.Fa s
+is
+.Pf non- Dv NULL
+and does not point to the null character,
+.Fa s
+is written to the standard error file descriptor
+prior to the message string,
+immediately followed by a colon and a space.
+If the signal number is not recognized
+.Pq Xr sigaction 2 ,
+the string
+.Dq "Unknown signal
+is produced.
+.Pp
+The message strings can be accessed directly
+through the external array
+.Va sys_siglist ,
+indexed by recognized signal numbers.
+The external array
+.Va sys_signame
+is used similarly and
+contains short, lower-case abbreviations for signals
+which are useful for recognizing signal names
+in user input.
+The defined variable
+.Dv NSIG
+contains a count of the strings in
+.Va sys_siglist
+and
+.Va sys_signame .
+.Sh SEE ALSO
+.Xr sigaction 2 ,
+.Xr perror 3 ,
+.Xr strerror 3
+.Sh HISTORY
+The
+.Fn psignal
+function appeared in
+.Bx 4.2 .
diff --git a/lib/libc/gen/psignal.c b/lib/libc/gen/psignal.c
new file mode 100644
index 0000000..96eab9d
--- /dev/null
+++ b/lib/libc/gen/psignal.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)psignal.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Print the name of the signal indicated
+ * along with the supplied message.
+ */
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+void
+psignal(sig, s)
+ unsigned int sig;
+ const char *s;
+{
+ register const char *c;
+
+ if (sig < NSIG)
+ c = sys_siglist[sig];
+ else
+ c = "Unknown signal";
+ if (s != NULL && *s != '\0') {
+ (void)write(STDERR_FILENO, s, strlen(s));
+ (void)write(STDERR_FILENO, ": ", 2);
+ }
+ (void)write(STDERR_FILENO, c, strlen(c));
+ (void)write(STDERR_FILENO, "\n", 1);
+}
diff --git a/lib/libc/gen/pw_scan.c b/lib/libc/gen/pw_scan.c
new file mode 100644
index 0000000..849effa
--- /dev/null
+++ b/lib/libc/gen/pw_scan.c
@@ -0,0 +1,165 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)pw_scan.c 8.3 (Berkeley) 4/2/94";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* not lint */
+
+/*
+ * This module is used to "verify" password entries by chpass(1) and
+ * pwd_mkdb(8).
+ */
+
+#include <sys/param.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "pw_scan.h"
+
+/*
+ * Some software assumes that IDs are short. We should emit warnings
+ * for id's which can not be stored in a short, but we are more liberal
+ * by default, warning for IDs greater than USHRT_MAX.
+ *
+ * If pw_big_ids_warning is anything other than -1 on entry to pw_scan()
+ * it will be set based on the existance of PW_SCAN_BIG_IDS in the
+ * environment.
+ */
+int pw_big_ids_warning = -1;
+
+int
+pw_scan(bp, pw)
+ char *bp;
+ struct passwd *pw;
+{
+ long id;
+ int root;
+ char *p, *sh;
+
+ if (pw_big_ids_warning == -1)
+ pw_big_ids_warning = getenv("PW_SCAN_BIG_IDS") == NULL ? 1 : 0;
+
+ pw->pw_fields = 0;
+ if (!(pw->pw_name = strsep(&bp, ":"))) /* login */
+ goto fmt;
+ root = !strcmp(pw->pw_name, "root");
+ if(pw->pw_name[0] && (pw->pw_name[0] != '+' || pw->pw_name[1] == '\0'))
+ pw->pw_fields |= _PWF_NAME;
+
+ if (!(pw->pw_passwd = strsep(&bp, ":"))) /* passwd */
+ goto fmt;
+ if(pw->pw_passwd[0]) pw->pw_fields |= _PWF_PASSWD;
+
+ if (!(p = strsep(&bp, ":"))) /* uid */
+ goto fmt;
+ if (p[0])
+ pw->pw_fields |= _PWF_UID;
+ else {
+ if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') {
+ warnx("no uid for user %s", pw->pw_name);
+ return (0);
+ }
+ }
+ id = atol(p);
+ if (root && id) {
+ warnx("root uid should be 0");
+ return (0);
+ }
+ if (pw_big_ids_warning && id > USHRT_MAX) {
+ warnx("%s > max uid value (%u)", p, USHRT_MAX);
+ /*return (0);*/ /* THIS SHOULD NOT BE FATAL! */
+ }
+ pw->pw_uid = id;
+
+ if (!(p = strsep(&bp, ":"))) /* gid */
+ goto fmt;
+ if(p[0]) pw->pw_fields |= _PWF_GID;
+ id = atol(p);
+ if (pw_big_ids_warning && id > USHRT_MAX) {
+ warnx("%s > max gid value (%u)", p, USHRT_MAX);
+ /* return (0); This should not be fatal! */
+ }
+ pw->pw_gid = id;
+
+ pw->pw_class = strsep(&bp, ":"); /* class */
+ if(pw->pw_class[0]) pw->pw_fields |= _PWF_CLASS;
+
+ if (!(p = strsep(&bp, ":"))) /* change */
+ goto fmt;
+ if(p[0]) pw->pw_fields |= _PWF_CHANGE;
+ pw->pw_change = atol(p);
+
+ if (!(p = strsep(&bp, ":"))) /* expire */
+ goto fmt;
+ if(p[0]) pw->pw_fields |= _PWF_EXPIRE;
+ pw->pw_expire = atol(p);
+
+ if (!(pw->pw_gecos = strsep(&bp, ":"))) /* gecos */
+ goto fmt;
+ if(pw->pw_gecos[0]) pw->pw_fields |= _PWF_GECOS;
+
+ if (!(pw->pw_dir = strsep(&bp, ":"))) /* directory */
+ goto fmt;
+ if(pw->pw_dir[0]) pw->pw_fields |= _PWF_DIR;
+
+ if (!(pw->pw_shell = strsep(&bp, ":"))) /* shell */
+ goto fmt;
+
+ p = pw->pw_shell;
+ if (root && *p) /* empty == /bin/sh */
+ for (setusershell();;) {
+ if (!(sh = getusershell())) {
+ warnx("warning, unknown root shell");
+ break;
+ }
+ if (!strcmp(p, sh))
+ break;
+ }
+ if(p[0]) pw->pw_fields |= _PWF_SHELL;
+
+ if ((p = strsep(&bp, ":"))) { /* too many */
+fmt: warnx("corrupted entry");
+ return (0);
+ }
+ return (1);
+}
diff --git a/lib/libc/gen/pw_scan.h b/lib/libc/gen/pw_scan.h
new file mode 100644
index 0000000..2519bd4
--- /dev/null
+++ b/lib/libc/gen/pw_scan.h
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pw_scan.h 8.1 (Berkeley) 4/1/94
+ *
+ * $FreeBSD$
+ */
+
+extern int pw_big_ids_warning;
+
+extern int pw_scan __P((char *, struct passwd *));
diff --git a/lib/libc/gen/pwcache.3 b/lib/libc/gen/pwcache.3
new file mode 100644
index 0000000..d5f08a2
--- /dev/null
+++ b/lib/libc/gen/pwcache.3
@@ -0,0 +1,95 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)pwcache.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt PWCACHE 3
+.Os
+.Sh NAME
+.Nm pwcache
+.Nd cache password and group entries
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft char *
+.Fn user_from_uid "unsigned long uid" "int nouser"
+.Ft char *
+.Fn group_from_gid "unsigned long gid" "int nogroup"
+.Sh DESCRIPTION
+.Pp
+The
+.Fn user_from_uid
+function returns the user name associated with the argument
+.Fa uid .
+The user name is cached so that multiple calls with the same
+.Fa uid
+do not require additional calls to
+.Xr getpwuid 3 .
+If there is no user associated with the
+.Fa uid ,
+a pointer is returned
+to a string representation of the
+.Fa uid ,
+unless the argument
+.Fa nouser
+is non-zero, in which case a
+.Dv NULL
+pointer is returned.
+.Pp
+The
+.Fn group_from_gid
+function returns the group name associated with the argument
+.Fa gid .
+The group name is cached so that multiple calls with the same
+.Fa gid
+do not require additional calls to
+.Xr getgrgid 3 .
+If there is no group associated with the
+.Fa gid ,
+a pointer is returned
+to a string representation of the
+.Fa gid ,
+unless the argument
+.Fa nogroup
+is non-zero, in which case a
+.Dv NULL
+pointer is returned.
+.Sh SEE ALSO
+.Xr getgrgid 3 ,
+.Xr getpwuid 3
+.Sh HISTORY
+The
+.Fn user_from_uid
+and
+.Fn group_from_gid
+functions first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/gen/pwcache.c b/lib/libc/gen/pwcache.c
new file mode 100644
index 0000000..aea7f55
--- /dev/null
+++ b/lib/libc/gen/pwcache.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)pwcache.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <grp.h>
+#include <string.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <utmp.h>
+
+#define NCACHE 64 /* power of 2 */
+#define MASK (NCACHE - 1) /* bits to store with */
+
+char *
+user_from_uid(uid, nouser)
+ uid_t uid;
+ int nouser;
+{
+ static struct ncache {
+ uid_t uid;
+ int found;
+ char name[UT_NAMESIZE + 1];
+ } c_uid[NCACHE];
+ static int pwopen;
+ register struct passwd *pw;
+ register struct ncache *cp;
+
+ cp = c_uid + (uid & MASK);
+ if (cp->uid != uid || !*cp->name) {
+ if (pwopen == 0) {
+ setpassent(1);
+ pwopen = 1;
+ }
+ pw = getpwuid(uid);
+ cp->uid = uid;
+ if (pw != NULL) {
+ cp->found = 1;
+ (void)strncpy(cp->name, pw->pw_name, UT_NAMESIZE);
+ cp->name[UT_NAMESIZE] = '\0';
+ } else {
+ cp->found = 0;
+ (void)snprintf(cp->name, UT_NAMESIZE, "%u", uid);
+ if (nouser)
+ return (NULL);
+ }
+ }
+ return ((nouser && !cp->found) ? NULL : cp->name);
+}
+
+char *
+group_from_gid(gid, nogroup)
+ gid_t gid;
+ int nogroup;
+{
+ static struct ncache {
+ gid_t gid;
+ int found;
+ char name[UT_NAMESIZE + 1];
+ } c_gid[NCACHE];
+ static int gropen;
+ struct group *gr;
+ struct ncache *cp;
+
+ cp = c_gid + (gid & MASK);
+ if (cp->gid != gid || !*cp->name) {
+ if (gropen == 0) {
+ setgroupent(1);
+ gropen = 1;
+ }
+ gr = getgrgid(gid);
+ cp->gid = gid;
+ if (gr != NULL) {
+ cp->found = 1;
+ (void)strncpy(cp->name, gr->gr_name, UT_NAMESIZE);
+ cp->name[UT_NAMESIZE] = '\0';
+ } else {
+ cp->found = 0;
+ (void)snprintf(cp->name, UT_NAMESIZE, "%u", gid);
+ if (nogroup)
+ return (NULL);
+ }
+ }
+ return ((nogroup && !cp->found) ? NULL : cp->name);
+}
diff --git a/lib/libc/gen/raise.3 b/lib/libc/gen/raise.3
new file mode 100644
index 0000000..556ad2a
--- /dev/null
+++ b/lib/libc/gen/raise.3
@@ -0,0 +1,78 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)raise.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt RAISE 3
+.Os
+.Sh NAME
+.Nm raise
+.Nd send a signal to the current process
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Ft int
+.Fn raise "int sig"
+.Sh DESCRIPTION
+The
+.Fn raise
+function sends the signal
+.Fa sig
+to the current process.
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned.
+Otherwise, a value of \-1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn raise
+function
+may fail and set
+.Va errno
+for any of the errors specified for the
+library functions
+.Xr getpid 2
+and
+.Xr kill 2 .
+.Sh SEE ALSO
+.Xr kill 2
+.Sh STANDARDS
+The
+.Fn raise
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/gen/raise.c b/lib/libc/gen/raise.c
new file mode 100644
index 0000000..2562c81
--- /dev/null
+++ b/lib/libc/gen/raise.c
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)raise.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <signal.h>
+#include <unistd.h>
+
+int
+raise(s)
+ int s;
+{
+ return(kill(getpid(), s));
+}
diff --git a/lib/libc/gen/rand48.3 b/lib/libc/gen/rand48.3
new file mode 100644
index 0000000..86e7a2f
--- /dev/null
+++ b/lib/libc/gen/rand48.3
@@ -0,0 +1,161 @@
+\" Copyright (c) 1993 Martin Birgmeier
+.\" All rights reserved.
+.\"
+.\" You may redistribute unmodified or modified versions of this source
+.\" code provided that the above copyright notice and this and the
+.\" following conditions are retained.
+.\"
+.\" This software is provided ``as is'', and comes with no warranties
+.\" of any kind. I shall in no event be liable for anything that happens
+.\" to anyone/anything when using this software.
+.\"
+.\" @(#)rand48.3 V1.0 MB 8 Oct 1993
+.\" $FreeBSD$
+.\"
+.Dd October 8, 1993
+.Dt RAND48 3
+.Os FreeBSD
+.Sh NAME
+.Nm drand48 ,
+.Nm erand48 ,
+.Nm lrand48 ,
+.Nm nrand48 ,
+.Nm mrand48 ,
+.Nm jrand48 ,
+.Nm srand48 ,
+.Nm seed48 ,
+.Nm lcong48
+.Nd pseudo random number generators and initialization routines
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft double
+.Fn drand48 void
+.Ft double
+.Fn erand48 "unsigned short xseed[3]"
+.Ft long
+.Fn lrand48 void
+.Ft long
+.Fn nrand48 "unsigned short xseed[3]"
+.Ft long
+.Fn mrand48 void
+.Ft long
+.Fn jrand48 "unsigned short xseed[3]"
+.Ft void
+.Fn srand48 "long seed"
+.Ft "unsigned short *"
+.Fn seed48 "unsigned short xseed[3]"
+.Ft void
+.Fn lcong48 "unsigned short p[7]"
+.Sh DESCRIPTION
+The
+.Fn rand48
+family of functions generates pseudo-random numbers using a linear
+congruential algorithm working on integers 48 bits in size. The
+particular formula employed is
+r(n+1) = (a * r(n) + c) mod m
+where the default values are
+for the multiplicand a = 0xfdeece66d = 25214903917 and
+the addend c = 0xb = 11. The modulo is always fixed at m = 2 ** 48.
+r(n) is called the seed of the random number generator.
+.Pp
+For all the six generator routines described next, the first
+computational step is to perform a single iteration of the algorithm.
+.Pp
+.Fn drand48
+and
+.Fn erand48
+return values of type double. The full 48 bits of r(n+1) are
+loaded into the mantissa of the returned value, with the exponent set
+such that the values produced lie in the interval [0.0, 1.0).
+.Pp
+.Fn lrand48
+and
+.Fn nrand48
+return values of type long in the range
+[0, 2**31-1]. The high-order (31) bits of
+r(n+1) are loaded into the lower bits of the returned value, with
+the topmost (sign) bit set to zero.
+.Pp
+.Fn mrand48
+and
+.Fn jrand48
+return values of type long in the range
+[-2**31, 2**31-1]. The high-order (32) bits of
+r(n+1) are loaded into the returned value.
+.Pp
+.Fn drand48 ,
+.Fn lrand48 ,
+and
+.Fn mrand48
+use an internal buffer to store r(n). For these functions
+the initial value of r(0) = 0x1234abcd330e = 20017429951246.
+.Pp
+On the other hand,
+.Fn erand48 ,
+.Fn nrand48 ,
+and
+.Fn jrand48
+use a user-supplied buffer to store the seed r(n),
+which consists of an array of 3 shorts, where the zeroth member
+holds the least significant bits.
+.Pp
+All functions share the same multiplicand and addend.
+.Pp
+.Fn srand48
+is used to initialize the internal buffer r(n) of
+.Fn drand48 ,
+.Fn lrand48 ,
+and
+.Fn mrand48
+such that the 32 bits of the seed value are copied into the upper 32 bits
+of r(n), with the lower 16 bits of r(n) arbitrarily being set to 0x330e.
+Additionally, the constant multiplicand and addend of the algorithm are
+reset to the default values given above.
+.Pp
+.Fn seed48
+also initializes the internal buffer r(n) of
+.Fn drand48 ,
+.Fn lrand48 ,
+and
+.Fn mrand48 ,
+but here all 48 bits of the seed can be specified in an array of 3 shorts,
+where the zeroth member specifies the lowest bits. Again,
+the constant multiplicand and addend of the algorithm are
+reset to the default values given above.
+.Fn seed48
+returns a pointer to an array of 3 shorts which contains the old seed.
+This array is statically allocated, thus its contents are lost after
+each new call to
+.Fn seed48 .
+.Pp
+Finally,
+.Fn lcong48
+allows full control over the multiplicand and addend used in
+.Fn drand48 ,
+.Fn erand48 ,
+.Fn lrand48 ,
+.Fn nrand48 ,
+.Fn mrand48 ,
+and
+.Fn jrand48 ,
+and the seed used in
+.Fn drand48 ,
+.Fn lrand48 ,
+and
+.Fn mrand48 .
+An array of 7 shorts is passed as parameter; the first three shorts are
+used to initialize the seed; the second three are used to initialize the
+multiplicand; and the last short is used to initialize the addend.
+It is thus not possible to use values greater than 0xffff as the addend.
+.Pp
+Note that all three methods of seeding the random number generator
+always also set the multiplicand and addend for any of the six
+generator calls.
+.Pp
+For a more powerful random number generator, see
+.Xr random 3 .
+.Sh AUTHORS
+.An Martin Birgmeier
+.Sh SEE ALSO
+.Xr rand 3 ,
+.Xr random 3
diff --git a/lib/libc/gen/rand48.h b/lib/libc/gen/rand48.h
new file mode 100644
index 0000000..5b9f87d
--- /dev/null
+++ b/lib/libc/gen/rand48.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#ifndef _RAND48_H_
+#define _RAND48_H_
+
+#include <math.h>
+#include <stdlib.h>
+
+void _dorand48 __P((unsigned short[3]));
+
+#define RAND48_SEED_0 (0x330e)
+#define RAND48_SEED_1 (0xabcd)
+#define RAND48_SEED_2 (0x1234)
+#define RAND48_MULT_0 (0xe66d)
+#define RAND48_MULT_1 (0xdeec)
+#define RAND48_MULT_2 (0x0005)
+#define RAND48_ADD (0x000b)
+
+#endif /* _RAND48_H_ */
diff --git a/lib/libc/gen/readdir.c b/lib/libc/gen/readdir.c
new file mode 100644
index 0000000..2e91a9a
--- /dev/null
+++ b/lib/libc/gen/readdir.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)readdir.c 8.3 (Berkeley) 9/29/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <dirent.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif _THREAD_SAFE
+
+/*
+ * get next entry in a directory.
+ */
+struct dirent *
+readdir(dirp)
+ register DIR *dirp;
+{
+ register struct dirent *dp;
+
+ for (;;) {
+ if (dirp->dd_loc >= dirp->dd_size) {
+ if (dirp->dd_flags & __DTF_READALL)
+ return (NULL);
+ dirp->dd_loc = 0;
+ }
+ if (dirp->dd_loc == 0 && !(dirp->dd_flags & __DTF_READALL)) {
+ dirp->dd_size = getdirentries(dirp->dd_fd,
+ dirp->dd_buf, dirp->dd_len, &dirp->dd_seek);
+ if (dirp->dd_size <= 0)
+ return (NULL);
+ }
+ dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc);
+ if ((long)dp & 03L) /* bogus pointer check */
+ return (NULL);
+ if (dp->d_reclen <= 0 ||
+ dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc)
+ return (NULL);
+ dirp->dd_loc += dp->d_reclen;
+ if (dp->d_ino == 0)
+ continue;
+ if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW))
+ continue;
+ return (dp);
+ }
+}
+
+int
+readdir_r(dirp, entry, result)
+ DIR *dirp;
+ struct dirent *entry;
+ struct dirent **result;
+{
+ struct dirent *dp;
+ int ret, saved_errno;
+
+#ifdef _THREAD_SAFE
+ if ((ret = _FD_LOCK(dirp->dd_fd, FD_READ, NULL)) != 0)
+ return (ret);
+#endif
+
+ saved_errno = errno;
+ errno = 0;
+ dp = readdir(dirp);
+ if (errno != 0) {
+ if (dp == NULL) {
+#ifdef _THREAD_SAFE
+ _FD_UNLOCK(dirp->dd_fd, FD_READ);
+#endif
+ return (errno);
+ }
+ } else
+ errno = saved_errno;
+
+ if (dp != NULL)
+ memcpy(entry, dp, sizeof *entry);
+
+#ifdef _THREAD_SAFE
+ _FD_UNLOCK(dirp->dd_fd, FD_READ);
+#endif
+
+ if (dp != NULL)
+ *result = entry;
+ else
+ *result = NULL;
+
+ return (0);
+}
diff --git a/lib/libc/gen/rewinddir.c b/lib/libc/gen/rewinddir.c
new file mode 100644
index 0000000..2076ddd
--- /dev/null
+++ b/lib/libc/gen/rewinddir.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rewinddir.c 8.1 (Berkeley) 6/8/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <dirent.h>
+
+extern void _seekdir __P(( DIR *, long ));
+
+void
+rewinddir(dirp)
+ DIR *dirp;
+{
+
+ _seekdir(dirp, dirp->dd_rewind);
+ dirp->dd_rewind = telldir(dirp);
+}
diff --git a/lib/libc/gen/scandir.3 b/lib/libc/gen/scandir.3
new file mode 100644
index 0000000..afcde28
--- /dev/null
+++ b/lib/libc/gen/scandir.3
@@ -0,0 +1,107 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)scandir.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SCANDIR 3
+.Os BSD 4.2
+.Sh NAME
+.Nm scandir ,
+.Nm alphasort
+.Nd scan a directory
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <dirent.h>
+.Ft int
+.Fn scandir "const char *dirname" "struct dirent ***namelist" "int \\*(lp*select\\*(rp\\*(lpstruct dirent *\\*(rp" "int \\*(lp*compar\\*(rp\\*(lpconst void *, const void *\\*(rp"
+.Ft int
+.Fn alphasort "const void *d1" "const void *d2"
+.Sh DESCRIPTION
+The
+.Fn scandir
+function
+reads the directory
+.Fa dirname
+and builds an array of pointers to directory
+entries using
+.Xr malloc 3 .
+It returns the number of entries in the array.
+A pointer to the array of directory entries is stored in the location
+referenced by
+.Fa namelist .
+.Pp
+The
+.Fa select
+parameter is a pointer to a user supplied subroutine which is called by
+.Fn scandir
+to select which entries are to be included in the array.
+The select routine is passed a
+pointer to a directory entry and should return a non-zero
+value if the directory entry is to be included in the array.
+If
+.Fa select
+is null, then all the directory entries will be included.
+.Pp
+The
+.Fa compar
+parameter is a pointer to a user supplied subroutine which is passed to
+.Xr qsort 3
+to sort the completed array.
+If this pointer is null, the array is not sorted.
+.Pp
+The
+.Fn alphasort
+function
+is a routine which can be used for the
+.Fa compar
+parameter to sort the array alphabetically.
+.Pp
+The memory allocated for the array can be deallocated with
+.Xr free 3 ,
+by freeing each pointer in the array and then the array itself.
+.Sh DIAGNOSTICS
+Returns \-1 if the directory cannot be opened for reading or if
+.Xr malloc 3
+cannot allocate enough memory to hold all the data structures.
+.Sh SEE ALSO
+.Xr directory 3 ,
+.Xr malloc 3 ,
+.Xr qsort 3 ,
+.Xr dir 5
+.Sh HISTORY
+The
+.Fn scandir
+and
+.Fn alphasort
+functions appeared in
+.Bx 4.2 .
diff --git a/lib/libc/gen/scandir.c b/lib/libc/gen/scandir.c
new file mode 100644
index 0000000..5c64b29
--- /dev/null
+++ b/lib/libc/gen/scandir.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)scandir.c 8.3 (Berkeley) 1/2/94";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Scan the directory dirname calling select to make a list of selected
+ * directory entries then sort using qsort and compare routine dcomp.
+ * Returns the number of entries and a pointer to a list of pointers to
+ * struct dirent (through namelist). Returns -1 if there were any errors.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * The DIRSIZ macro is the minimum record length which will hold the directory
+ * entry. This requires the amount of space in struct dirent without the
+ * d_name field, plus enough space for the name and a terminating nul byte
+ * (dp->d_namlen + 1), rounded up to a 4 byte boundary.
+ */
+#undef DIRSIZ
+#define DIRSIZ(dp) \
+ ((sizeof(struct dirent) - sizeof(dp)->d_name) + \
+ (((dp)->d_namlen + 1 + 3) &~ 3))
+
+int
+scandir(dirname, namelist, select, dcomp)
+ const char *dirname;
+ struct dirent ***namelist;
+ int (*select) __P((struct dirent *));
+ int (*dcomp) __P((const void *, const void *));
+{
+ register struct dirent *d, *p, **names = NULL;
+ register size_t nitems = 0;
+ struct stat stb;
+ long arraysz;
+ DIR *dirp;
+
+ if ((dirp = opendir(dirname)) == NULL)
+ return(-1);
+ if (fstat(dirp->dd_fd, &stb) < 0)
+ goto fail;
+
+ /*
+ * estimate the array size by taking the size of the directory file
+ * and dividing it by a multiple of the minimum size entry.
+ */
+ arraysz = (stb.st_size / 24);
+ names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
+ if (names == NULL)
+ goto fail;
+
+ while ((d = readdir(dirp)) != NULL) {
+ if (select != NULL && !(*select)(d))
+ continue; /* just selected names */
+ /*
+ * Make a minimum size copy of the data
+ */
+ p = (struct dirent *)malloc(DIRSIZ(d));
+ if (p == NULL)
+ goto fail;
+ p->d_fileno = d->d_fileno;
+ p->d_type = d->d_type;
+ p->d_reclen = d->d_reclen;
+ p->d_namlen = d->d_namlen;
+ bcopy(d->d_name, p->d_name, p->d_namlen + 1);
+ /*
+ * Check to make sure the array has space left and
+ * realloc the maximum size.
+ */
+ if (nitems >= arraysz) {
+ const int inc = 10; /* increase by this much */
+ struct dirent **names2;
+
+ names2 = (struct dirent **)realloc((char *)names,
+ (arraysz + inc) * sizeof(struct dirent *));
+ if (names2 == NULL) {
+ free(p);
+ goto fail;
+ }
+ names = names2;
+ arraysz += inc;
+ }
+ names[nitems++] = p;
+ }
+ closedir(dirp);
+ if (nitems && dcomp != NULL)
+ qsort(names, nitems, sizeof(struct dirent *), dcomp);
+ *namelist = names;
+ return(nitems);
+
+fail:
+ while (nitems > 0)
+ free(names[--nitems]);
+ free(names);
+ closedir(dirp);
+ return -1;
+}
+
+/*
+ * Alphabetic order comparison routine for those who want it.
+ */
+int
+alphasort(d1, d2)
+ const void *d1;
+ const void *d2;
+{
+ return(strcmp((*(struct dirent **)d1)->d_name,
+ (*(struct dirent **)d2)->d_name));
+}
diff --git a/lib/libc/gen/seed48.c b/lib/libc/gen/seed48.c
new file mode 100644
index 0000000..258c4ba
--- /dev/null
+++ b/lib/libc/gen/seed48.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#include "rand48.h"
+
+extern unsigned short _rand48_seed[3];
+extern unsigned short _rand48_mult[3];
+extern unsigned short _rand48_add;
+
+unsigned short *
+seed48(unsigned short xseed[3])
+{
+ static unsigned short sseed[3];
+
+ sseed[0] = _rand48_seed[0];
+ sseed[1] = _rand48_seed[1];
+ sseed[2] = _rand48_seed[2];
+ _rand48_seed[0] = xseed[0];
+ _rand48_seed[1] = xseed[1];
+ _rand48_seed[2] = xseed[2];
+ _rand48_mult[0] = RAND48_MULT_0;
+ _rand48_mult[1] = RAND48_MULT_1;
+ _rand48_mult[2] = RAND48_MULT_2;
+ _rand48_add = RAND48_ADD;
+ return sseed;
+}
diff --git a/lib/libc/gen/seekdir.c b/lib/libc/gen/seekdir.c
new file mode 100644
index 0000000..1934bcc
--- /dev/null
+++ b/lib/libc/gen/seekdir.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)seekdir.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <dirent.h>
+
+extern void _seekdir __P(( DIR *, long ));
+
+/*
+ * Seek to an entry in a directory.
+ * _seekdir is in telldir.c so that it can share opaque data structures.
+ */
+void
+seekdir(dirp, loc)
+ DIR *dirp;
+ long loc;
+{
+
+ _seekdir(dirp, loc);
+}
diff --git a/lib/libc/gen/semconfig.c b/lib/libc/gen/semconfig.c
new file mode 100644
index 0000000..cf5399b
--- /dev/null
+++ b/lib/libc/gen/semconfig.c
@@ -0,0 +1,13 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+
+#if __STDC__
+int semconfig(int cmd, int p1, int p2, int p3)
+#else
+int semconfig(cmd, p1, p2, p3)
+ int cmd, p1, p2, p3;
+#endif
+{
+ return (semsys(3, cmd, p1, p2, p3));
+}
diff --git a/lib/libc/gen/semctl.c b/lib/libc/gen/semctl.c
new file mode 100644
index 0000000..03ecdbc
--- /dev/null
+++ b/lib/libc/gen/semctl.c
@@ -0,0 +1,42 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <stdlib.h>
+
+#if __STDC__
+int semctl(int semid, int semnum, int cmd, ...)
+#else
+int semctl(semid, semnum, cmd, va_alist)
+ int semid, semnum;
+ int cmd;
+ va_dcl
+#endif
+{
+ va_list ap;
+ union semun semun;
+ union semun *semun_ptr;
+#if __STDC__
+ va_start(ap, cmd);
+#else
+ va_start(ap);
+#endif
+ if (cmd == IPC_SET || cmd == IPC_STAT || cmd == GETALL
+ || cmd == SETVAL || cmd == SETALL) {
+ semun = va_arg(ap, union semun);
+ semun_ptr = &semun;
+ } else {
+ semun_ptr = NULL;
+ }
+ va_end(ap);
+
+#ifdef __NETBSD_SYSCALLS
+ return (__semctl(semid, semnum, cmd, semun_ptr));
+#else
+ return (semsys(0, semid, semnum, cmd, semun_ptr));
+#endif
+}
diff --git a/lib/libc/gen/semget.c b/lib/libc/gen/semget.c
new file mode 100644
index 0000000..81c6a86
--- /dev/null
+++ b/lib/libc/gen/semget.c
@@ -0,0 +1,15 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+
+#if __STDC__
+int semget(key_t key, int nsems, int semflg)
+#else
+int semget(key, nsems, semflg)
+ key_t key;
+ int nsems;
+ int semflg;
+#endif
+{
+ return (semsys(1, key, nsems, semflg));
+}
diff --git a/lib/libc/gen/semop.c b/lib/libc/gen/semop.c
new file mode 100644
index 0000000..0b97c6a
--- /dev/null
+++ b/lib/libc/gen/semop.c
@@ -0,0 +1,15 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+
+#if __STDC__
+int semop(int semid, struct sembuf *sops, unsigned nsops)
+#else
+int semop(semid, sops, nsops)
+ int semid;
+ struct sembuf *sops;
+ unsigned nsops;
+#endif
+{
+ return (semsys(2, semid, sops, nsops, 0));
+}
diff --git a/lib/libc/gen/setdomainname.c b/lib/libc/gen/setdomainname.c
new file mode 100644
index 0000000..8d46166
--- /dev/null
+++ b/lib/libc/gen/setdomainname.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*
+static char sccsid[] = "From: @(#)sethostname.c 8.1 (Berkeley) 6/4/93";
+*/
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#include <unistd.h>
+
+int
+setdomainname(const char *name, int namelen)
+{
+ int mib[2];
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_NISDOMAINNAME;
+ if (sysctl(mib, 2, NULL, NULL, (void *)name, namelen) == -1)
+ return (-1);
+ return (0);
+}
diff --git a/lib/libc/gen/setflags.c b/lib/libc/gen/setflags.c
new file mode 100644
index 0000000..5235eb3
--- /dev/null
+++ b/lib/libc/gen/setflags.c
@@ -0,0 +1,174 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)stat_flags.c 8.1 (Berkeley) 5/31/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stddef.h>
+#include <string.h>
+
+#define SAPPEND(s) { \
+ if (prefix != NULL) \
+ (void)strcat(string, prefix); \
+ (void)strcat(string, s); \
+ prefix = ","; \
+}
+
+/*
+ * flags_to_string --
+ * Convert stat flags to a comma-separated string. If no flags
+ * are set, return the default string.
+ */
+char *
+flags_to_string(flags, def)
+ u_long flags;
+ char *def;
+{
+ static char string[128];
+ char *prefix;
+
+ string[0] = '\0';
+ prefix = NULL;
+ if (flags & UF_APPEND)
+ SAPPEND("uappnd");
+ if (flags & UF_IMMUTABLE)
+ SAPPEND("uchg");
+#ifdef UF_NOUNLINK
+ if (flags & UF_NOUNLINK)
+ SAPPEND("uunlnk");
+#endif
+ if (flags & UF_NODUMP)
+ SAPPEND("nodump");
+ if (flags & UF_OPAQUE)
+ SAPPEND("opaque");
+ if (flags & SF_APPEND)
+ SAPPEND("sappnd");
+ if (flags & SF_ARCHIVED)
+ SAPPEND("arch");
+ if (flags & SF_IMMUTABLE)
+ SAPPEND("schg");
+#ifdef SF_NOUNLINK
+ if (flags & SF_NOUNLINK)
+ SAPPEND("sunlnk");
+#endif
+ return (prefix == NULL && def != NULL ? def : string);
+}
+
+#define TEST(a, b, f) { \
+ if (!memcmp(a, b, sizeof(b))) { \
+ if (clear) { \
+ if (clrp) \
+ *clrp |= (f); \
+ } else if (setp) \
+ *setp |= (f); \
+ break; \
+ } \
+}
+
+/*
+ * string_to_flags --
+ * Take string of arguments and return stat flags. Return 0 on
+ * success, 1 on failure. On failure, stringp is set to point
+ * to the offending token.
+ */
+int
+string_to_flags(stringp, setp, clrp)
+ char **stringp;
+ u_long *setp, *clrp;
+{
+ int clear;
+ char *string, *p;
+
+ if (setp)
+ *setp = 0;
+ if (clrp)
+ *clrp = 0;
+ string = *stringp;
+ while ((p = strsep(&string, "\t ,")) != NULL) {
+ clear = 0;
+ *stringp = p;
+ if (*p == '\0')
+ continue;
+ if (p[0] == 'n' && p[1] == 'o') {
+ clear = 1;
+ p += 2;
+ }
+ switch (p[0]) {
+ case 'a':
+ TEST(p, "arch", SF_ARCHIVED);
+ TEST(p, "archived", SF_ARCHIVED);
+ return (1);
+ case 'd':
+ clear = !clear;
+ TEST(p, "dump", UF_NODUMP);
+ return (1);
+ case 'o':
+ TEST(p, "opaque", UF_OPAQUE);
+ return (1);
+ case 's':
+ TEST(p, "sappnd", SF_APPEND);
+ TEST(p, "sappend", SF_APPEND);
+ TEST(p, "schg", SF_IMMUTABLE);
+ TEST(p, "schange", SF_IMMUTABLE);
+ TEST(p, "simmutable", SF_IMMUTABLE);
+#ifdef SF_NOUNLINK
+ TEST(p, "sunlnk", SF_NOUNLINK);
+ TEST(p, "sunlink", SF_NOUNLINK);
+#endif
+ return (1);
+ case 'u':
+ TEST(p, "uappnd", UF_APPEND);
+ TEST(p, "uappend", UF_APPEND);
+ TEST(p, "uchg", UF_IMMUTABLE);
+ TEST(p, "uchange", UF_IMMUTABLE);
+ TEST(p, "uimmutable", UF_IMMUTABLE);
+#ifdef UF_NOUNLINK
+ TEST(p, "uunlnk", UF_NOUNLINK);
+ TEST(p, "uunlink", UF_NOUNLINK);
+#endif
+ /* FALLTHROUGH */
+ default:
+ return (1);
+ }
+ }
+ return (0);
+}
diff --git a/lib/libc/gen/setflagsbyname.c b/lib/libc/gen/setflagsbyname.c
new file mode 100644
index 0000000..5235eb3
--- /dev/null
+++ b/lib/libc/gen/setflagsbyname.c
@@ -0,0 +1,174 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)stat_flags.c 8.1 (Berkeley) 5/31/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stddef.h>
+#include <string.h>
+
+#define SAPPEND(s) { \
+ if (prefix != NULL) \
+ (void)strcat(string, prefix); \
+ (void)strcat(string, s); \
+ prefix = ","; \
+}
+
+/*
+ * flags_to_string --
+ * Convert stat flags to a comma-separated string. If no flags
+ * are set, return the default string.
+ */
+char *
+flags_to_string(flags, def)
+ u_long flags;
+ char *def;
+{
+ static char string[128];
+ char *prefix;
+
+ string[0] = '\0';
+ prefix = NULL;
+ if (flags & UF_APPEND)
+ SAPPEND("uappnd");
+ if (flags & UF_IMMUTABLE)
+ SAPPEND("uchg");
+#ifdef UF_NOUNLINK
+ if (flags & UF_NOUNLINK)
+ SAPPEND("uunlnk");
+#endif
+ if (flags & UF_NODUMP)
+ SAPPEND("nodump");
+ if (flags & UF_OPAQUE)
+ SAPPEND("opaque");
+ if (flags & SF_APPEND)
+ SAPPEND("sappnd");
+ if (flags & SF_ARCHIVED)
+ SAPPEND("arch");
+ if (flags & SF_IMMUTABLE)
+ SAPPEND("schg");
+#ifdef SF_NOUNLINK
+ if (flags & SF_NOUNLINK)
+ SAPPEND("sunlnk");
+#endif
+ return (prefix == NULL && def != NULL ? def : string);
+}
+
+#define TEST(a, b, f) { \
+ if (!memcmp(a, b, sizeof(b))) { \
+ if (clear) { \
+ if (clrp) \
+ *clrp |= (f); \
+ } else if (setp) \
+ *setp |= (f); \
+ break; \
+ } \
+}
+
+/*
+ * string_to_flags --
+ * Take string of arguments and return stat flags. Return 0 on
+ * success, 1 on failure. On failure, stringp is set to point
+ * to the offending token.
+ */
+int
+string_to_flags(stringp, setp, clrp)
+ char **stringp;
+ u_long *setp, *clrp;
+{
+ int clear;
+ char *string, *p;
+
+ if (setp)
+ *setp = 0;
+ if (clrp)
+ *clrp = 0;
+ string = *stringp;
+ while ((p = strsep(&string, "\t ,")) != NULL) {
+ clear = 0;
+ *stringp = p;
+ if (*p == '\0')
+ continue;
+ if (p[0] == 'n' && p[1] == 'o') {
+ clear = 1;
+ p += 2;
+ }
+ switch (p[0]) {
+ case 'a':
+ TEST(p, "arch", SF_ARCHIVED);
+ TEST(p, "archived", SF_ARCHIVED);
+ return (1);
+ case 'd':
+ clear = !clear;
+ TEST(p, "dump", UF_NODUMP);
+ return (1);
+ case 'o':
+ TEST(p, "opaque", UF_OPAQUE);
+ return (1);
+ case 's':
+ TEST(p, "sappnd", SF_APPEND);
+ TEST(p, "sappend", SF_APPEND);
+ TEST(p, "schg", SF_IMMUTABLE);
+ TEST(p, "schange", SF_IMMUTABLE);
+ TEST(p, "simmutable", SF_IMMUTABLE);
+#ifdef SF_NOUNLINK
+ TEST(p, "sunlnk", SF_NOUNLINK);
+ TEST(p, "sunlink", SF_NOUNLINK);
+#endif
+ return (1);
+ case 'u':
+ TEST(p, "uappnd", UF_APPEND);
+ TEST(p, "uappend", UF_APPEND);
+ TEST(p, "uchg", UF_IMMUTABLE);
+ TEST(p, "uchange", UF_IMMUTABLE);
+ TEST(p, "uimmutable", UF_IMMUTABLE);
+#ifdef UF_NOUNLINK
+ TEST(p, "uunlnk", UF_NOUNLINK);
+ TEST(p, "uunlink", UF_NOUNLINK);
+#endif
+ /* FALLTHROUGH */
+ default:
+ return (1);
+ }
+ }
+ return (0);
+}
diff --git a/lib/libc/gen/sethostname.c b/lib/libc/gen/sethostname.c
new file mode 100644
index 0000000..6c3adc3
--- /dev/null
+++ b/lib/libc/gen/sethostname.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)sethostname.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#if __STDC__
+int
+sethostname(const char *name, int namelen)
+#else
+int
+sethostname(name, namelen)
+ char *name;
+ int namelen;
+#endif
+{
+ int mib[2];
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_HOSTNAME;
+ if (sysctl(mib, 2, NULL, NULL, (void *)name, namelen) == -1)
+ return (-1);
+ return (0);
+}
diff --git a/lib/libc/gen/setjmp.3 b/lib/libc/gen/setjmp.3
new file mode 100644
index 0000000..779239c
--- /dev/null
+++ b/lib/libc/gen/setjmp.3
@@ -0,0 +1,174 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)setjmp.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SETJMP 3
+.Os BSD 4
+.Sh NAME
+.Nm sigsetjmp ,
+.Nm siglongjmp ,
+.Nm setjmp ,
+.Nm longjmp ,
+.Nm _setjmp ,
+.Nm _longjmp ,
+.Nm longjmperror
+.Nd non-local jumps
+.Sh SYNOPSIS
+.Fd #include <setjmp.h>
+.Ft int
+.Fn sigsetjmp "sigjmp_buf env" "int savemask"
+.Ft void
+.Fn siglongjmp "sigjmp_buf env" "int val"
+.Ft int
+.Fn setjmp "jmp_buf env"
+.Ft void
+.Fn longjmp "jmp_buf env" "int val"
+.Ft int
+.Fn _setjmp "jmp_buf env"
+.Ft void
+.Fn _longjmp "jmp_buf env" "int val"
+.Ft void
+.Fn longjmperror void
+.Sh DESCRIPTION
+The
+.Fn sigsetjmp ,
+.Fn setjmp ,
+and
+.Fn _setjmp
+functions save their calling environment in
+.Fa env .
+Each of these functions returns 0.
+.Pp
+The corresponding
+.Fn longjmp
+functions restore the environment saved by their most recent respective
+invocations
+of the
+.Fn setjmp
+function.
+They then return so that program execution continues as if the corresponding
+invocation of the
+.Fn setjmp
+call had just returned the value specified by
+.Fa val ,
+instead of 0.
+.Pp
+Pairs of calls may be intermixed, i.e. both
+.Fn sigsetjmp
+and
+.Fn siglongjmp
+and
+.Fn setjmp
+and
+.Fn longjmp
+combinations may be used in the same program, however, individual
+calls may not, e.g. the
+.Fa env
+argument to
+.Fn setjmp
+may not be passed to
+.Fn siglongjmp .
+.Pp
+The
+.Fn longjmp
+routines may not be called after the routine which called the
+.Fn setjmp
+routines returns.
+.Pp
+All accessible objects have values as of the time
+.Fn longjmp
+routine was called, except that the values of objects of automatic storage
+invocation duration that do not have the
+.Em volatile
+type and have been changed between the
+.Fn setjmp
+invocation and
+.Fn longjmp
+call are indeterminate.
+.Pp
+The
+.Fn setjmp Ns / Ns Fn longjmp
+pairs save and restore the signal mask while
+.Fn _setjmp Ns / Ns Fn _longjmp
+pairs save and restore only the register set and the stack.
+(See
+.Fn sigprocmask 2 . )
+.Pp
+The
+.Fn sigsetjmp Ns / Ns Fn siglongjmp
+function
+pairs save and restore the signal mask if the argument
+.Fa savemask
+is non-zero, otherwise only the register set and the stack are saved.
+.Sh ERRORS
+If the contents of the
+.Fa env
+are corrupted, or correspond to an environment that has already returned,
+the
+.Fn longjmp
+routine calls the routine
+.Fn longjmperror 3 .
+If
+.Fn longjmperror
+returns the program is aborted (see
+.Xr abort 3 ) .
+The default version of
+.Fn longjmperror
+prints the message
+.Dq Li longjmp botch
+to standard error and returns.
+User programs wishing to exit more gracefully should write their own
+versions of
+.Fn longjmperror .
+.Sh SEE ALSO
+.Xr sigaction 2 ,
+.Xr sigaltstack 2 ,
+.Xr signal 3
+.Sh STANDARDS
+The
+.Fn setjmp
+and
+.Fn longjmp
+functions conform to
+.St -ansiC .
+The
+.Fn sigsetjmp
+and
+.Fn siglongjmp
+functions conform to
+.St -p1003.1-88 .
diff --git a/lib/libc/gen/setjmperr.c b/lib/libc/gen/setjmperr.c
new file mode 100644
index 0000000..26f83b5
--- /dev/null
+++ b/lib/libc/gen/setjmperr.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setjmperr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * This routine is called from longjmp() when an error occurs.
+ * Programs that wish to exit gracefully from this error may
+ * write their own versions.
+ * If this routine returns, the program is aborted.
+ */
+
+#include <setjmp.h>
+#include <unistd.h>
+
+void
+longjmperror()
+{
+#define ERRMSG "longjmp botch.\n"
+ (void)write(STDERR_FILENO, ERRMSG, sizeof(ERRMSG) - 1);
+}
diff --git a/lib/libc/gen/setmode.3 b/lib/libc/gen/setmode.3
new file mode 100644
index 0000000..20a26fe
--- /dev/null
+++ b/lib/libc/gen/setmode.3
@@ -0,0 +1,116 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)setmode.3 8.2 (Berkeley) 4/28/95
+.\" $FreeBSD$
+.\"
+.Dd April 28, 1995
+.Dt SETMODE 3
+.Os
+.Sh NAME
+.Nm getmode ,
+.Nm setmode
+.Nd modify mode bits
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft mode_t
+.Fn getmode "const void *set" "mode_t mode"
+.Ft void *
+.Fn setmode "const char *mode_str"
+.Sh DESCRIPTION
+The
+.Fn getmode
+function
+returns a copy of the file permission bits
+.Fa mode
+as altered by the values pointed to by
+.Fa set .
+While only the mode bits are altered, other parts of the file mode
+may be examined.
+.Pp
+The
+.Fn setmode
+function
+takes an absolute (octal) or symbolic value, as described in
+.Xr chmod 1 ,
+as an argument
+and returns a pointer to mode values to be supplied to
+.Fn getmode .
+Because some of the symbolic values are relative to the file
+creation mask,
+.Fn setmode
+may call
+.Xr umask 2 .
+If this occurs, the file creation mask will be restored before
+.Fn setmode
+returns.
+If the calling program changes the value of its file creation mask
+after calling
+.Fn setmode ,
+.Fn setmode
+must be called again if
+.Fn getmode
+is to modify future file modes correctly.
+.Pp
+If the mode passed to
+.Fn setmode
+is invalid or if memory cannot be allocated for the return value,
+.Fn setmode
+returns
+.Dv NULL .
+.Pp
+The value returned from
+.Fn setmode
+is obtained from
+.Fn malloc
+and should be returned to the system with
+.Fn free
+when the program is done with it, generally after a call to
+.Fn getmode .
+.Sh ERRORS
+The
+.Fn setmode
+function
+may fail and set errno for any of the errors specified for the library
+routine
+.Xr malloc 3 .
+.Sh SEE ALSO
+.Xr chmod 1 ,
+.Xr stat 2 ,
+.Xr umask 2 ,
+.Xr malloc 3
+.Sh HISTORY
+The
+.Fn getmode
+and
+.Fn setmode
+functions first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/gen/setmode.c b/lib/libc/gen/setmode.c
new file mode 100644
index 0000000..2c12b81
--- /dev/null
+++ b/lib/libc/gen/setmode.c
@@ -0,0 +1,457 @@
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Dave Borman at Cray Research, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#ifdef SETMODE_DEBUG
+#include <stdio.h>
+#endif
+
+#define SET_LEN 6 /* initial # of bitcmd struct to malloc */
+#define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
+
+typedef struct bitcmd {
+ char cmd;
+ char cmd2;
+ mode_t bits;
+} BITCMD;
+
+#define CMD2_CLR 0x01
+#define CMD2_SET 0x02
+#define CMD2_GBITS 0x04
+#define CMD2_OBITS 0x08
+#define CMD2_UBITS 0x10
+
+static BITCMD *addcmd __P((BITCMD *, int, int, int, u_int));
+static void compress_mode __P((BITCMD *));
+#ifdef SETMODE_DEBUG
+static void dumpmode __P((BITCMD *));
+#endif
+
+/*
+ * Given the old mode and an array of bitcmd structures, apply the operations
+ * described in the bitcmd structures to the old mode, and return the new mode.
+ * Note that there is no '=' command; a strict assignment is just a '-' (clear
+ * bits) followed by a '+' (set bits).
+ */
+mode_t
+getmode(bbox, omode)
+ void *bbox;
+ mode_t omode;
+{
+ register BITCMD *set;
+ register mode_t clrval, newmode, value;
+
+ set = (BITCMD *)bbox;
+ newmode = omode;
+ for (value = 0;; set++)
+ switch(set->cmd) {
+ /*
+ * When copying the user, group or other bits around, we "know"
+ * where the bits are in the mode so that we can do shifts to
+ * copy them around. If we don't use shifts, it gets real
+ * grundgy with lots of single bit checks and bit sets.
+ */
+ case 'u':
+ value = (newmode & S_IRWXU) >> 6;
+ goto common;
+
+ case 'g':
+ value = (newmode & S_IRWXG) >> 3;
+ goto common;
+
+ case 'o':
+ value = newmode & S_IRWXO;
+common: if (set->cmd2 & CMD2_CLR) {
+ clrval =
+ (set->cmd2 & CMD2_SET) ? S_IRWXO : value;
+ if (set->cmd2 & CMD2_UBITS)
+ newmode &= ~((clrval<<6) & set->bits);
+ if (set->cmd2 & CMD2_GBITS)
+ newmode &= ~((clrval<<3) & set->bits);
+ if (set->cmd2 & CMD2_OBITS)
+ newmode &= ~(clrval & set->bits);
+ }
+ if (set->cmd2 & CMD2_SET) {
+ if (set->cmd2 & CMD2_UBITS)
+ newmode |= (value<<6) & set->bits;
+ if (set->cmd2 & CMD2_GBITS)
+ newmode |= (value<<3) & set->bits;
+ if (set->cmd2 & CMD2_OBITS)
+ newmode |= value & set->bits;
+ }
+ break;
+
+ case '+':
+ newmode |= set->bits;
+ break;
+
+ case '-':
+ newmode &= ~set->bits;
+ break;
+
+ case 'X':
+ if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
+ newmode |= set->bits;
+ break;
+
+ case '\0':
+ default:
+#ifdef SETMODE_DEBUG
+ (void)printf("getmode:%04o -> %04o\n", omode, newmode);
+#endif
+ return (newmode);
+ }
+}
+
+#define ADDCMD(a, b, c, d) \
+ if (set >= endset) { \
+ register BITCMD *newset; \
+ setlen += SET_LEN_INCR; \
+ newset = realloc(saveset, sizeof(BITCMD) * setlen); \
+ if (!saveset) \
+ return (NULL); \
+ set = newset + (set - saveset); \
+ saveset = newset; \
+ endset = newset + (setlen - 2); \
+ } \
+ set = addcmd(set, (a), (b), (c), (d))
+
+#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
+
+void *
+setmode(p)
+ register char *p;
+{
+ register int perm, who;
+ register char op;
+ BITCMD *set, *saveset, *endset;
+ sigset_t sigset, sigoset;
+ mode_t mask;
+ int equalopdone=0, permXbits, setlen;
+
+ if (!*p)
+ return (NULL);
+
+ /*
+ * Get a copy of the mask for the permissions that are mask relative.
+ * Flip the bits, we want what's not set. Since it's possible that
+ * the caller is opening files inside a signal handler, protect them
+ * as best we can.
+ */
+ sigfillset(&sigset);
+ (void)sigprocmask(SIG_BLOCK, &sigset, &sigoset);
+ (void)umask(mask = umask(0));
+ mask = ~mask;
+ (void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
+
+ setlen = SET_LEN + 2;
+
+ if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL)
+ return (NULL);
+ saveset = set;
+ endset = set + (setlen - 2);
+
+ /*
+ * If an absolute number, get it and return; disallow non-octal digits
+ * or illegal bits.
+ */
+ if (isdigit((unsigned char)*p)) {
+ perm = (mode_t)strtol(p, NULL, 8);
+ if (perm & ~(STANDARD_BITS|S_ISTXT)) {
+ free(saveset);
+ return (NULL);
+ }
+ while (*++p)
+ if (*p < '0' || *p > '7') {
+ free(saveset);
+ return (NULL);
+ }
+ ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
+ return (saveset);
+ }
+
+ /*
+ * Build list of structures to set/clear/copy bits as described by
+ * each clause of the symbolic mode.
+ */
+ for (;;) {
+ /* First, find out which bits might be modified. */
+ for (who = 0;; ++p) {
+ switch (*p) {
+ case 'a':
+ who |= STANDARD_BITS;
+ break;
+ case 'u':
+ who |= S_ISUID|S_IRWXU;
+ break;
+ case 'g':
+ who |= S_ISGID|S_IRWXG;
+ break;
+ case 'o':
+ who |= S_IRWXO;
+ break;
+ default:
+ goto getop;
+ }
+ }
+
+getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
+ free(saveset);
+ return (NULL);
+ }
+ if (op == '=')
+ equalopdone = 0;
+
+ who &= ~S_ISTXT;
+ for (perm = 0, permXbits = 0;; ++p) {
+ switch (*p) {
+ case 'r':
+ perm |= S_IRUSR|S_IRGRP|S_IROTH;
+ break;
+ case 's':
+ /* If only "other" bits ignore set-id. */
+ if (!who || who & ~S_IRWXO)
+ perm |= S_ISUID|S_ISGID;
+ break;
+ case 't':
+ /* If only "other" bits ignore sticky. */
+ if (!who || who & ~S_IRWXO) {
+ who |= S_ISTXT;
+ perm |= S_ISTXT;
+ }
+ break;
+ case 'w':
+ perm |= S_IWUSR|S_IWGRP|S_IWOTH;
+ break;
+ case 'X':
+ permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
+ break;
+ case 'x':
+ perm |= S_IXUSR|S_IXGRP|S_IXOTH;
+ break;
+ case 'u':
+ case 'g':
+ case 'o':
+ /*
+ * When ever we hit 'u', 'g', or 'o', we have
+ * to flush out any partial mode that we have,
+ * and then do the copying of the mode bits.
+ */
+ if (perm) {
+ ADDCMD(op, who, perm, mask);
+ perm = 0;
+ }
+ if (op == '=')
+ equalopdone = 1;
+ if (op == '+' && permXbits) {
+ ADDCMD('X', who, permXbits, mask);
+ permXbits = 0;
+ }
+ ADDCMD(*p, who, op, mask);
+ break;
+
+ default:
+ /*
+ * Add any permissions that we haven't already
+ * done.
+ */
+ if (perm || (op == '=' && !equalopdone)) {
+ if (op == '=')
+ equalopdone = 1;
+ ADDCMD(op, who, perm, mask);
+ perm = 0;
+ }
+ if (permXbits) {
+ ADDCMD('X', who, permXbits, mask);
+ permXbits = 0;
+ }
+ goto apply;
+ }
+ }
+
+apply: if (!*p)
+ break;
+ if (*p != ',')
+ goto getop;
+ ++p;
+ }
+ set->cmd = 0;
+#ifdef SETMODE_DEBUG
+ (void)printf("Before compress_mode()\n");
+ dumpmode(saveset);
+#endif
+ compress_mode(saveset);
+#ifdef SETMODE_DEBUG
+ (void)printf("After compress_mode()\n");
+ dumpmode(saveset);
+#endif
+ return (saveset);
+}
+
+static BITCMD *
+addcmd(set, op, who, oparg, mask)
+ BITCMD *set;
+ register int oparg, who;
+ register int op;
+ u_int mask;
+{
+ switch (op) {
+ case '=':
+ set->cmd = '-';
+ set->bits = who ? who : STANDARD_BITS;
+ set++;
+
+ op = '+';
+ /* FALLTHROUGH */
+ case '+':
+ case '-':
+ case 'X':
+ set->cmd = op;
+ set->bits = (who ? who : mask) & oparg;
+ break;
+
+ case 'u':
+ case 'g':
+ case 'o':
+ set->cmd = op;
+ if (who) {
+ set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
+ ((who & S_IRGRP) ? CMD2_GBITS : 0) |
+ ((who & S_IROTH) ? CMD2_OBITS : 0);
+ set->bits = ~0;
+ } else {
+ set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
+ set->bits = mask;
+ }
+
+ if (oparg == '+')
+ set->cmd2 |= CMD2_SET;
+ else if (oparg == '-')
+ set->cmd2 |= CMD2_CLR;
+ else if (oparg == '=')
+ set->cmd2 |= CMD2_SET|CMD2_CLR;
+ break;
+ }
+ return (set + 1);
+}
+
+#ifdef SETMODE_DEBUG
+static void
+dumpmode(set)
+ register BITCMD *set;
+{
+ for (; set->cmd; ++set)
+ (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
+ set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
+ set->cmd2 & CMD2_CLR ? " CLR" : "",
+ set->cmd2 & CMD2_SET ? " SET" : "",
+ set->cmd2 & CMD2_UBITS ? " UBITS" : "",
+ set->cmd2 & CMD2_GBITS ? " GBITS" : "",
+ set->cmd2 & CMD2_OBITS ? " OBITS" : "");
+}
+#endif
+
+/*
+ * Given an array of bitcmd structures, compress by compacting consecutive
+ * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
+ * 'g' and 'o' commands continue to be separate. They could probably be
+ * compacted, but it's not worth the effort.
+ */
+static void
+compress_mode(set)
+ register BITCMD *set;
+{
+ register BITCMD *nset;
+ register int setbits, clrbits, Xbits, op;
+
+ for (nset = set;;) {
+ /* Copy over any 'u', 'g' and 'o' commands. */
+ while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
+ *set++ = *nset++;
+ if (!op)
+ return;
+ }
+
+ for (setbits = clrbits = Xbits = 0;; nset++) {
+ if ((op = nset->cmd) == '-') {
+ clrbits |= nset->bits;
+ setbits &= ~nset->bits;
+ Xbits &= ~nset->bits;
+ } else if (op == '+') {
+ setbits |= nset->bits;
+ clrbits &= ~nset->bits;
+ Xbits &= ~nset->bits;
+ } else if (op == 'X')
+ Xbits |= nset->bits & ~setbits;
+ else
+ break;
+ }
+ if (clrbits) {
+ set->cmd = '-';
+ set->cmd2 = 0;
+ set->bits = clrbits;
+ set++;
+ }
+ if (setbits) {
+ set->cmd = '+';
+ set->cmd2 = 0;
+ set->bits = setbits;
+ set++;
+ }
+ if (Xbits) {
+ set->cmd = 'X';
+ set->cmd2 = 0;
+ set->bits = Xbits;
+ set++;
+ }
+ }
+}
diff --git a/lib/libc/gen/setproctitle.3 b/lib/libc/gen/setproctitle.3
new file mode 100644
index 0000000..10eae65
--- /dev/null
+++ b/lib/libc/gen/setproctitle.3
@@ -0,0 +1,101 @@
+.\" Copyright (c) 1995 Peter Wemm <peter@freebsd.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, is permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice immediately at the beginning of the file, without modification,
+.\" this list of conditions, and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. This work was done expressly for inclusion into FreeBSD. Other use
+.\" is permitted provided this notation is included.
+.\" 4. Absolutely no warranty of function or purpose is made by the author
+.\" Peter Wemm.
+.\" 5. Modifications may be freely made to this file providing the above
+.\" conditions are met.
+.\"
+.\" $FreeBSD$
+.\"
+.\" The following requests are required for all man pages.
+.Dd December 16, 1995
+.Os FreeBSD
+.Dt SETPROCTITLE 3
+.Sh NAME
+.Nm setproctitle
+.Nd set the process title for
+.Xr ps 1
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <libutil.h>
+.Ft void
+.Fn setproctitle "const char *fmt" "..."
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+The
+.Fn setproctitle
+library routine sets the process title that appears on the
+.Xr ps 1
+command.
+.Pp
+The title is set from the executable's name, followed by the
+result of a
+.Xr printf 3
+style expansion of the arguments as specified by the
+.Va fmt
+argument.
+.Pp
+If
+.Va fmt
+is NULL, the process title is restored.
+.Sh EXAMPLES
+To set the title on a daemon to indicate its activity:
+.Bd -literal -offset indent
+setproctitle("talking to %s", inet_ntoa(addr));
+.Ed
+.Sh SEE ALSO
+.Xr ps 1 ,
+.Xr w 1 ,
+.Xr kvm 3 ,
+.Xr kvm_getargv 3 ,
+.Xr printf 3
+.Sh STANDARDS
+.Fn setproctitle
+is implicitly non-standard. Other methods of causing the
+.Xr ps 1
+command line to change, including copying over the argv[0] string are
+also implicitly non-portable. It is preferable to use an operating system
+supplied
+.Fn setproctitle
+if present.
+.Pp
+Unfortunately, it is possible that there are other calling conventions
+to other versions of
+.Fn setproctitle ,
+although none have been found by the author as yet. This is believed to be
+the predominant convention.
+.Pp
+It is thought that the implementation is compatible with other systems,
+including
+.Nx
+and
+.Tn BSD/OS .
+.Sh HISTORY
+.Fn setproctitle
+first appeared in
+.Fx 2.2 .
+Other operating systems have
+similar functions.
+.Sh AUTHORS
+.An Peter Wemm Aq peter@FreeBSD.org
+stole the idea from the
+.Sy "Sendmail 8.7.3"
+source code by
+.An Eric Allman Aq eric@sendmail.org .
diff --git a/lib/libc/gen/setproctitle.c b/lib/libc/gen/setproctitle.c
new file mode 100644
index 0000000..37b9fab
--- /dev/null
+++ b/lib/libc/gen/setproctitle.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1995 Peter Wemm <peter@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Absolutely no warranty of function or purpose is made by the author
+ * Peter Wemm.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/sysctl.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * Older FreeBSD 2.0, 2.1 and 2.2 had different ps_strings structures and
+ * in different locations.
+ * 1: old_ps_strings at the very top of the stack.
+ * 2: old_ps_strings at SPARE_USRSPACE below the top of the stack.
+ * 3: ps_strings at the very top of the stack.
+ * This attempts to support a kernel built in the #2 and #3 era.
+ */
+
+struct old_ps_strings {
+ char *old_ps_argvstr;
+ int old_ps_nargvstr;
+ char *old_ps_envstr;
+ int old_ps_nenvstr;
+};
+#define OLD_PS_STRINGS ((struct old_ps_strings *) \
+ (USRSTACK - SPARE_USRSPACE - sizeof(struct old_ps_strings)))
+
+#if defined(__STDC__) /* from other parts of sendmail */
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+
+#define SPT_BUFSIZE 2048 /* from other parts of sendmail */
+extern char * __progname; /* is this defined in a .h anywhere? */
+
+void
+#if defined(__STDC__)
+setproctitle(const char *fmt, ...)
+#else
+setproctitle(fmt, va_alist)
+ const char *fmt;
+ va_dcl
+#endif
+{
+ static struct ps_strings *ps_strings;
+ static char buf[SPT_BUFSIZE];
+ static char obuf[SPT_BUFSIZE];
+ static char **oargv, *kbuf;
+ static int oargc = -1;
+ static char *nargv[2] = { buf, NULL };
+ char **nargvp;
+ int nargc;
+ va_list ap;
+ size_t len;
+ unsigned long ul_ps_strings;
+ int oid[4];
+
+#if defined(__STDC__)
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+
+ if (fmt) {
+ buf[sizeof(buf) - 1] = '\0';
+
+ /* print program name heading for grep */
+ (void) snprintf(buf, sizeof(buf), "%s: ", __progname);
+
+ /*
+ * can't use return from sprintf, as that is the count of how
+ * much it wanted to write, not how much it actually did.
+ */
+
+ len = strlen(buf);
+
+ /* print the argument string */
+ (void) vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
+
+ nargvp = nargv;
+ nargc = 1;
+ kbuf = buf;
+ } else if (*obuf != '\0') {
+ /* Idea from NetBSD - reset the title on fmt == NULL */
+ nargvp = oargv;
+ nargc = oargc;
+ kbuf = obuf;
+ } else
+ /* Nothing to restore */
+ return;
+
+ va_end(ap);
+
+ /* Set the title into the kernel cached command line */
+ oid[0] = CTL_KERN;
+ oid[1] = KERN_PROC;
+ oid[2] = KERN_PROC_ARGS;
+ oid[3] = getpid();
+ sysctl(oid, 4, 0, 0, kbuf, strlen(kbuf) + 1);
+
+ if (ps_strings == NULL) {
+ len = sizeof(ul_ps_strings);
+ if (sysctlbyname("kern.ps_strings", &ul_ps_strings, &len, NULL,
+ 0) == -1)
+ ul_ps_strings = PS_STRINGS;
+ ps_strings = (struct ps_strings *)ul_ps_strings;
+ }
+
+ /* PS_STRINGS points to zeroed memory on a style #2 kernel */
+ if (ps_strings->ps_argvstr) {
+ /* style #3 */
+ if (oargc == -1) {
+ /* Record our original args */
+ oargc = ps_strings->ps_nargvstr;
+ oargv = ps_strings->ps_argvstr;
+ for (nargc = len = 0; nargc < oargc; nargc++) {
+ snprintf(obuf + len, sizeof(obuf) - len, "%s%s",
+ len ? " " : "", oargv[nargc]);
+ if (len)
+ len++;
+ len += strlen(oargv[nargc]);
+ if (len >= sizeof(obuf))
+ break;
+ }
+ }
+ ps_strings->ps_nargvstr = nargc;
+ ps_strings->ps_argvstr = nargvp;
+ } else {
+ /* style #2 - we can only restore our first arg :-( */
+ if (*obuf == '\0')
+ strncpy(obuf, OLD_PS_STRINGS->old_ps_argvstr,
+ sizeof(obuf) - 1);
+ OLD_PS_STRINGS->old_ps_nargvstr = 1;
+ OLD_PS_STRINGS->old_ps_argvstr = nargvp[0];
+ }
+}
diff --git a/lib/libc/gen/shmat.c b/lib/libc/gen/shmat.c
new file mode 100644
index 0000000..45b9143
--- /dev/null
+++ b/lib/libc/gen/shmat.c
@@ -0,0 +1,19 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#if __STDC__
+void *shmat(int shmid, void *shmaddr, int shmflg)
+#else
+void *shmat(shmid, shmaddr, shmflg)
+ int shmid;
+ void *shmaddr;
+ int shmflg;
+#endif
+{
+ return ((void *)shmsys(0, shmid, shmaddr, shmflg));
+}
diff --git a/lib/libc/gen/shmctl.c b/lib/libc/gen/shmctl.c
new file mode 100644
index 0000000..eae9fbb
--- /dev/null
+++ b/lib/libc/gen/shmctl.c
@@ -0,0 +1,19 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#if __STDC__
+int shmctl(int shmid, int cmd, struct shmid_ds *buf)
+#else
+int shmctl(shmid, cmd, buf)
+ int shmid;
+ int cmd;
+ struct shmid_ds *buf;
+#endif
+{
+ return (shmsys(4, shmid, cmd, buf));
+}
diff --git a/lib/libc/gen/shmdt.c b/lib/libc/gen/shmdt.c
new file mode 100644
index 0000000..f39ad18
--- /dev/null
+++ b/lib/libc/gen/shmdt.c
@@ -0,0 +1,17 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#if __STDC__
+int shmdt(void *shmaddr)
+#else
+int shmdt(shmaddr)
+ void *shmaddr;
+#endif
+{
+ return (shmsys(2, shmaddr));
+}
diff --git a/lib/libc/gen/shmget.c b/lib/libc/gen/shmget.c
new file mode 100644
index 0000000..8976d1c
--- /dev/null
+++ b/lib/libc/gen/shmget.c
@@ -0,0 +1,19 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#if __STDC__
+int shmget(key_t key, int size, int shmflg)
+#else
+int shmget(key, size, shmflg)
+ key_t key;
+ int size;
+ int shmflg;
+#endif
+{
+ return (shmsys(3, key, size, shmflg));
+}
diff --git a/lib/libc/gen/siginterrupt.3 b/lib/libc/gen/siginterrupt.3
new file mode 100644
index 0000000..ffce99c
--- /dev/null
+++ b/lib/libc/gen/siginterrupt.3
@@ -0,0 +1,112 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)siginterrupt.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SIGINTERRUPT 3
+.Os BSD 4.3
+.Sh NAME
+.Nm siginterrupt
+.Nd allow signals to interrupt system calls
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Ft int
+.Fn siginterrupt "int sig" "int flag"
+.Sh DESCRIPTION
+The
+.Fn siginterrupt
+function
+is used to change the system call restart
+behavior when a system call is interrupted by the specified signal.
+If the flag is false (0), then system calls will be restarted if
+they are interrupted by the specified signal
+and no data has been transferred yet.
+System call restart has been the default behavior since
+.Bx 4.2 ,
+and is the default behaviour for
+.Xr signal 3
+on
+.Tn FreeBSD .
+.Pp
+If the flag is true (1),
+then restarting of system calls is disabled.
+If a system call is interrupted by the specified signal
+and no data has been transferred,
+the system call will return \-1 with the global variable
+.Va errno
+set to
+.Dv EINTR .
+Interrupted system calls that have started transferring
+data will return the amount of data actually transferred.
+System call interrupt is the signal behavior found on
+.Bx 4.1
+and
+.At V
+systems.
+.Pp
+Note that the new
+.Bx 4.2
+signal handling semantics are not
+altered in any other way.
+Most notably, signal handlers always remain installed until
+explicitly changed by a subsequent
+.Xr sigaction 2
+call, and the signal mask operates as documented in
+.Xr sigaction 2 .
+Programs may switch between restartable and interruptible
+system call operation as often as desired in the execution of a program.
+.Pp
+Issuing a
+.Fn siginterrupt 3
+call during the execution of a signal handler will cause
+the new action to take place on the next signal to be caught.
+.Sh NOTES
+This library routine uses an extension of the
+.Xr sigaction 2
+system call that is not available in
+.Bx 4.2 ,
+hence it should not be used if backward compatibility is needed.
+.Sh RETURN VALUES
+A 0 value indicates that the call succeeded.
+A \-1 value indicates that an invalid signal number has been supplied.
+.Sh SEE ALSO
+.Xr sigaction 2 ,
+.Xr sigblock 2 ,
+.Xr sigpause 2 ,
+.Xr sigsetmask 2 ,
+.Xr signal 3
+.Sh HISTORY
+The
+.Fn siginterrupt
+function appeared in
+.Bx 4.3 .
diff --git a/lib/libc/gen/siginterrupt.c b/lib/libc/gen/siginterrupt.c
new file mode 100644
index 0000000..06960ab
--- /dev/null
+++ b/lib/libc/gen/siginterrupt.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)siginterrupt.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <signal.h>
+
+/*
+ * Set signal state to prevent restart of system calls
+ * after an instance of the indicated signal.
+ */
+int
+siginterrupt(sig, flag)
+ int sig, flag;
+{
+ extern sigset_t _sigintr;
+ struct sigaction sa;
+ int ret;
+
+ if ((ret = sigaction(sig, (struct sigaction *)0, &sa)) < 0)
+ return (ret);
+ if (flag) {
+ sigaddset(&_sigintr, sig);
+ sa.sa_flags &= ~SA_RESTART;
+ } else {
+ sigdelset(&_sigintr, sig);
+ sa.sa_flags |= SA_RESTART;
+ }
+ return (sigaction(sig, &sa, (struct sigaction *)0));
+}
diff --git a/lib/libc/gen/siglist.c b/lib/libc/gen/siglist.c
new file mode 100644
index 0000000..e6987d5
--- /dev/null
+++ b/lib/libc/gen/siglist.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)siglist.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <signal.h>
+
+const char *const sys_signame[NSIG] = {
+ "Signal 0",
+ "hup", /* SIGHUP */
+ "int", /* SIGINT */
+ "quit", /* SIGQUIT */
+ "ill", /* SIGILL */
+ "trap", /* SIGTRAP */
+ "abrt", /* SIGABRT */
+ "emt", /* SIGEMT */
+ "fpe", /* SIGFPE */
+ "kill", /* SIGKILL */
+ "bus", /* SIGBUS */
+ "segv", /* SIGSEGV */
+ "sys", /* SIGSYS */
+ "pipe", /* SIGPIPE */
+ "alrm", /* SIGALRM */
+ "term", /* SIGTERM */
+ "urg", /* SIGURG */
+ "stop", /* SIGSTOP */
+ "tstp", /* SIGTSTP */
+ "cont", /* SIGCONT */
+ "chld", /* SIGCHLD */
+ "ttin", /* SIGTTIN */
+ "ttou", /* SIGTTOU */
+ "io", /* SIGIO */
+ "xcpu", /* SIGXCPU */
+ "xfsz", /* SIGXFSZ */
+ "vtalrm", /* SIGVTALRM */
+ "prof", /* SIGPROF */
+ "winch", /* SIGWINCH */
+ "info", /* SIGINFO */
+ "usr1", /* SIGUSR1 */
+ "usr2", /* SIGUSR2 */
+};
+
+const char *const sys_siglist[NSIG] = {
+ "Signal 0",
+ "Hangup", /* SIGHUP */
+ "Interrupt", /* SIGINT */
+ "Quit", /* SIGQUIT */
+ "Illegal instruction", /* SIGILL */
+ "Trace/BPT trap", /* SIGTRAP */
+ "Abort trap", /* SIGABRT */
+ "EMT trap", /* SIGEMT */
+ "Floating point exception", /* SIGFPE */
+ "Killed", /* SIGKILL */
+ "Bus error", /* SIGBUS */
+ "Segmentation fault", /* SIGSEGV */
+ "Bad system call", /* SIGSYS */
+ "Broken pipe", /* SIGPIPE */
+ "Alarm clock", /* SIGALRM */
+ "Terminated", /* SIGTERM */
+ "Urgent I/O condition", /* SIGURG */
+ "Suspended (signal)", /* SIGSTOP */
+ "Suspended", /* SIGTSTP */
+ "Continued", /* SIGCONT */
+ "Child exited", /* SIGCHLD */
+ "Stopped (tty input)", /* SIGTTIN */
+ "Stopped (tty output)", /* SIGTTOU */
+ "I/O possible", /* SIGIO */
+ "Cputime limit exceeded", /* SIGXCPU */
+ "Filesize limit exceeded", /* SIGXFSZ */
+ "Virtual timer expired", /* SIGVTALRM */
+ "Profiling timer expired", /* SIGPROF */
+ "Window size changes", /* SIGWINCH */
+ "Information request", /* SIGINFO */
+ "User defined signal 1", /* SIGUSR1 */
+ "User defined signal 2" /* SIGUSR2 */
+};
+const int sys_nsig = sizeof(sys_siglist) / sizeof(sys_siglist[0]);
diff --git a/lib/libc/gen/signal.3 b/lib/libc/gen/signal.3
new file mode 100644
index 0000000..3da89d8
--- /dev/null
+++ b/lib/libc/gen/signal.3
@@ -0,0 +1,232 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)signal.3 8.3 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt SIGNAL 3
+.Os BSD 4
+.Sh NAME
+.Nm signal
+.Nd simplified software signal facilities
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.\" The following is Quite Ugly, but syntactically correct. Don't try to
+.\" fix it.
+.Ft void \*(lp*
+.Fn signal "int sig" "void \*(lp*func\*(rp\*(lpint\*(rp\*(rp\*(rp\*(lpint"
+
+or in FreeBSD's equivalent but easier to read typedef'd version:
+.Ft typedef "void \*(lp*sig_t\*(rp \*(lpint\*(rp"
+.Ft sig_t
+.Fn signal "int sig" "sig_t func"
+.Sh DESCRIPTION
+This
+.Fn signal
+facility
+is a simplified interface to the more general
+.Xr sigaction 2
+facility.
+.Pp
+Signals allow the manipulation of a process from outside its
+domain as well as allowing the process to manipulate itself or
+copies of itself (children). There are two general types of signals:
+those that cause termination of a process and those that do not.
+Signals which cause termination of a program might result from
+an irrecoverable error or might be the result of a user at a terminal
+typing the `interrupt' character.
+Signals are used when a process is stopped because it wishes to access
+its control terminal while in the background (see
+.Xr tty 4 ) .
+Signals are optionally generated
+when a process resumes after being stopped,
+when the status of child processes changes,
+or when input is ready at the control terminal.
+Most signals result in the termination of the process receiving them
+if no action
+is taken; some signals instead cause the process receiving them
+to be stopped, or are simply discarded if the process has not
+requested otherwise.
+Except for the
+.Dv SIGKILL
+and
+.Dv SIGSTOP
+signals, the
+.Fn signal
+function allows for a signal to be caught, to be ignored, or to generate
+an interrupt.
+These signals are defined in the file
+.Aq Pa signal.h :
+.Bl -column SIGVTALARMXX "create core imagexxx"
+.It Sy Name Default Action Description
+.It Dv SIGHUP Ta "terminate process" Ta "terminal line hangup"
+.It Dv SIGINT Ta "terminate process" Ta "interrupt program"
+.It Dv SIGQUIT Ta "create core image" Ta "quit program"
+.It Dv SIGILL Ta "create core image" Ta "illegal instruction"
+.It Dv SIGTRAP Ta "create core image" Ta "trace trap"
+.It Dv SIGABRT Ta "create core image" Ta Xr abort 2
+call (formerly
+.Dv SIGIOT )
+.It Dv SIGEMT Ta "create core image" Ta "emulate instruction executed"
+.It Dv SIGFPE Ta "create core image" Ta "floating-point exception"
+.It Dv SIGKILL Ta "terminate process" Ta "kill program"
+.It Dv SIGBUS Ta "create core image" Ta "bus error"
+.It Dv SIGSEGV Ta "create core image" Ta "segmentation violation"
+.It Dv SIGSYS Ta "create core image" Ta "non-existent system call invoked"
+.It Dv SIGPIPE Ta "terminate process" Ta "write on a pipe with no reader"
+.It Dv SIGALRM Ta "terminate process" Ta "real-time timer expired"
+.It Dv SIGTERM Ta "terminate process" Ta "software termination signal"
+.It Dv SIGURG Ta "discard signal" Ta "urgent condition present on socket"
+.It Dv SIGSTOP Ta "stop process" Ta "stop (cannot be caught or ignored)"
+.It Dv SIGTSTP Ta "stop process" Ta "stop signal generated from keyboard"
+.It Dv SIGCONT Ta "discard signal" Ta "continue after stop"
+.It Dv SIGCHLD Ta "discard signal" Ta "child status has changed"
+.It Dv SIGTTIN Ta "stop process" Ta "background read attempted from control terminal"
+.It Dv SIGTTOU Ta "stop process" Ta "background write attempted to control terminal"
+.It Dv SIGIO Ta "discard signal" Ta Tn "I/O"
+is possible on a descriptor (see
+.Xr fcntl 2 )
+.It Dv SIGXCPU Ta "terminate process" Ta "cpu time limit exceeded (see"
+.Xr setrlimit 2 )
+.It Dv SIGXFSZ Ta "terminate process" Ta "file size limit exceeded (see"
+.Xr setrlimit 2 )
+.It Dv SIGVTALRM Ta "terminate process" Ta "virtual time alarm (see"
+.Xr setitimer 2 )
+.It Dv SIGPROF Ta "terminate process" Ta "profiling timer alarm (see"
+.Xr setitimer 2 )
+.It Dv SIGWINCH Ta "discard signal" Ta "Window size change"
+.It Dv SIGINFO Ta "discard signal" Ta "status request from keyboard"
+.It Dv SIGUSR1 Ta "terminate process" Ta "User defined signal 1"
+.It Dv SIGUSR2 Ta "terminate process" Ta "User defined signal 2"
+.El
+.Pp
+The
+.Fa sig
+parameter specifies which signal was received.
+The
+.Fa func
+procedure allows a user to choose the action upon receipt of a signal.
+To set the default action of the signal to occur as listed above,
+.Fa func
+should be
+.Dv SIG_DFL .
+A
+.Dv SIG_DFL
+resets the default action.
+To ignore the signal
+.Fa func
+should be
+.Dv SIG_IGN .
+This will cause subsequent instances of the signal to be ignored
+and pending instances to be discarded. If
+.Dv SIG_IGN
+is not used,
+further occurrences of the signal are
+automatically blocked and
+.Fa func
+is called.
+.Pp
+The handled signal is unblocked when the
+function returns and
+the process continues from where it left off when the signal occurred.
+.Bf -symbolic
+Unlike previous signal facilities, the handler
+func() remains installed after a signal has been delivered.
+.Ef
+.Pp
+For some system calls, if a signal is caught while the call is
+executing and the call is prematurely terminated,
+the call is automatically restarted.
+(The handler is installed using the
+.Dv SA_RESTART
+flag with
+.Xr sigaction 2 . )
+The affected system calls include
+.Xr read 2 ,
+.Xr write 2 ,
+.Xr sendto 2 ,
+.Xr recvfrom 2 ,
+.Xr sendmsg 2
+and
+.Xr recvmsg 2
+on a communications channel or a low speed device
+and during a
+.Xr ioctl 2
+or
+.Xr wait 2 .
+However, calls that have already committed are not restarted,
+but instead return a partial success (for example, a short read count).
+This semantics could be changed with
+.Xr siginterrupt 3 .
+.Pp
+When a process which has installed signal handlers forks,
+the child process inherits the signals.
+All caught signals may be reset to their default action by a call
+to the
+.Xr execve 2
+function;
+ignored signals remain ignored.
+.Sh RETURN VALUES
+The previous action is returned on a successful call.
+Otherwise, SIG_ERR is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Signal
+will fail and no action will take place if one of the
+following occur:
+.Bl -tag -width [EINVAL]
+.It Bq Er EINVAL
+.Em Sig
+is not a valid signal number.
+.It Bq Er EINVAL
+An attempt is made to ignore or supply a handler for
+.Dv SIGKILL
+or
+.Ev SIGSTOP .
+.Sh SEE ALSO
+.Xr kill 1 ,
+.Xr kill 2 ,
+.Xr ptrace 2 ,
+.Xr sigaction 2 ,
+.Xr sigaltstack 2 ,
+.Xr sigprocmask 2 ,
+.Xr sigsuspend 2 ,
+.Xr fpsetmask 3 ,
+.Xr setjmp 3 ,
+.Xr siginterrupt 3 ,
+.Xr tty 4
+.Sh HISTORY
+This
+.Nm signal
+facility appeared in
+.Bx 4.0 .
diff --git a/lib/libc/gen/signal.c b/lib/libc/gen/signal.c
new file mode 100644
index 0000000..c4057f5
--- /dev/null
+++ b/lib/libc/gen/signal.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1985, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)signal.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Almost backwards compatible signal.
+ */
+#include <signal.h>
+
+sigset_t _sigintr; /* shared with siginterrupt */
+
+sig_t
+signal(s, a)
+ int s;
+ sig_t a;
+{
+ struct sigaction sa, osa;
+
+ sa.sa_handler = a;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (!sigismember(&_sigintr, s))
+ sa.sa_flags |= SA_RESTART;
+ if (sigaction(s, &sa, &osa) < 0)
+ return (SIG_ERR);
+ return (osa.sa_handler);
+}
diff --git a/lib/libc/gen/sigsetops.3 b/lib/libc/gen/sigsetops.3
new file mode 100644
index 0000000..a32daf6
--- /dev/null
+++ b/lib/libc/gen/sigsetops.3
@@ -0,0 +1,114 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sigsetops.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SIGSETOPS 3
+.Os
+.Sh NAME
+.Nm sigemptyset ,
+.Nm sigfillset ,
+.Nm sigaddset ,
+.Nm sigdelset ,
+.Nm sigismember
+.Nd manipulate signal sets
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Ft int
+.Fn sigemptyset "sigset_t *set"
+.Ft int
+.Fn sigfillset "sigset_t *set"
+.Ft int
+.Fn sigaddset "sigset_t *set" "int signo"
+.Ft int
+.Fn sigdelset "sigset_t *set" "int signo"
+.Ft int
+.Fn sigismember "const sigset_t *set" "int signo"
+.Sh DESCRIPTION
+These functions manipulate signal sets stored in a
+.Fa sigset_t .
+Either
+.Fn sigemptyset
+or
+.Fn sigfillset
+must be called for every object of type
+.Fa sigset_t
+before any other use of the object.
+.Pp
+The
+.Fn sigemptyset
+function initializes a signal set to be empty.
+.Pp
+The
+.Fn sigfillset
+function initializes a signal set to contain all signals.
+.Pp
+The
+.Fn sigaddset
+function adds the specified signal
+.Fa signo
+to the signal set.
+.Pp
+The
+.Fn sigdelset
+function deletes the specified signal
+.Fa signo
+from the signal set.
+.Pp
+The
+.Fn sigismember
+function returns whether a specified signal
+.Fa signo
+is contained in the signal set.
+.Pp
+These functions
+are provided as macros in the include file <signal.h>.
+Actual functions are available
+if their names are undefined (with #undef
+.Em name ) .
+.Sh RETURN VALUES
+The
+.Fn sigismember
+function returns 1
+if the signal is a member of the set,
+0 otherwise.
+The other functions return 0.
+.Sh ERRORS
+Currently no errors are detected.
+.Sh SEE ALSO
+.Xr kill 2 ,
+.Xr sigaction 2 ,
+.Xr sigsuspend 2
+.Sh STANDARDS
+These functions are defined by
+.St -p1003.1-88 .
diff --git a/lib/libc/gen/sigsetops.c b/lib/libc/gen/sigsetops.c
new file mode 100644
index 0000000..ffba20c
--- /dev/null
+++ b/lib/libc/gen/sigsetops.c
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)sigsetops.c 8.1 (Berkeley) 6/4/93
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)sigsetops.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <signal.h>
+
+int
+sigaddset(set, signo)
+ sigset_t *set;
+ int signo;
+{
+
+ if (signo <= 0 || signo > _SIG_MAXSIG) {
+ errno = EINVAL;
+ return (-1);
+ }
+ set->__bits[_SIG_WORD(signo)] |= _SIG_BIT(signo);
+ return (0);
+}
+
+int
+sigdelset(set, signo)
+ sigset_t *set;
+ int signo;
+{
+
+ if (signo <= 0 || signo > _SIG_MAXSIG) {
+ errno = EINVAL;
+ return (-1);
+ }
+ set->__bits[_SIG_WORD(signo)] &= ~_SIG_BIT(signo);
+ return (0);
+}
+
+int
+sigemptyset(set)
+ sigset_t *set;
+{
+ int i;
+
+ for (i = 0; i < _SIG_WORDS; i++)
+ set->__bits[i] = 0;
+ return (0);
+}
+
+int
+sigfillset(set)
+ sigset_t *set;
+{
+ int i;
+
+ for (i = 0; i < _SIG_WORDS; i++)
+ set->__bits[i] = ~0U;
+ return (0);
+}
+
+int
+sigismember(set, signo)
+ const sigset_t *set;
+ int signo;
+{
+
+ if (signo <= 0 || signo > _SIG_MAXSIG) {
+ errno = EINVAL;
+ return (-1);
+ }
+ return ((set->__bits[_SIG_WORD(signo)] & _SIG_BIT(signo)) ? 1 : 0);
+}
diff --git a/lib/libc/gen/sleep.3 b/lib/libc/gen/sleep.3
new file mode 100644
index 0000000..e59aad5
--- /dev/null
+++ b/lib/libc/gen/sleep.3
@@ -0,0 +1,84 @@
+.\" Copyright (c) 1986, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sleep.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd Feb 13, 1998
+.Dt SLEEP 3
+.Os
+.Sh NAME
+.Nm sleep
+.Nd suspend process execution for an interval measured in seconds
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft unsigned int
+.Fn sleep "unsigned int seconds"
+.Sh DESCRIPTION
+The
+.Fn sleep
+function suspends execution of the calling process until either
+.Fa seconds
+seconds have elapsed or a signal is delivered to the process and its
+action is to invoke a signal-catching function or to terminate the
+process.
+System activity may lengthen the sleep by an indeterminate amount.
+.Pp
+This function is implemented using
+.Xr nanosleep 2
+by pausing for
+.Fa seconds
+seconds or until a signal occurs.
+Consequently, in this implementation,
+sleeping has no effect on the state of process timers,
+and there is no special handling for SIGALRM.
+.Sh RETURN VALUES
+If the
+.Fn sleep
+function returns because the requested time has elapsed, the value
+returned will be zero. If the
+.Fn sleep
+function returns due to the delivery of a signal, the value returned
+will be the unslept amount (the requested time minus the time actually
+slept) in seconds.
+.Sh SEE ALSO
+.Xr nanosleep 2 ,
+.Xr usleep 3
+.Sh STANDARDS
+The
+.Fn sleep
+function conforms to
+.St -p1003.1-90 .
+.Sh HISTORY
+A
+.Fn sleep
+function appeared in
+.At v7 .
diff --git a/lib/libc/gen/sleep.c b/lib/libc/gen/sleep.c
new file mode 100644
index 0000000..f87ffba
--- /dev/null
+++ b/lib/libc/gen/sleep.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93";
+#endif
+static char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <limits.h>
+#include <time.h>
+#include <unistd.h>
+
+unsigned int
+sleep(seconds)
+ unsigned int seconds;
+{
+ struct timespec time_to_sleep;
+ struct timespec time_remaining;
+
+ /*
+ * Avoid overflow when `seconds' is huge. This assumes that
+ * the maximum value for a time_t is >= INT_MAX.
+ */
+ if (seconds > INT_MAX)
+ return (seconds - INT_MAX + sleep(INT_MAX));
+
+ time_to_sleep.tv_sec = seconds;
+ time_to_sleep.tv_nsec = 0;
+ if (nanosleep(&time_to_sleep, &time_remaining) != -1)
+ return (0);
+ if (errno != EINTR)
+ return (seconds); /* best guess */
+ return (time_remaining.tv_sec +
+ (time_remaining.tv_nsec != 0)); /* round up */
+}
diff --git a/lib/libc/gen/srand48.c b/lib/libc/gen/srand48.c
new file mode 100644
index 0000000..fd369a0
--- /dev/null
+++ b/lib/libc/gen/srand48.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#include "rand48.h"
+
+extern unsigned short _rand48_seed[3];
+extern unsigned short _rand48_mult[3];
+extern unsigned short _rand48_add;
+
+void
+srand48(long seed)
+{
+ _rand48_seed[0] = RAND48_SEED_0;
+ _rand48_seed[1] = (unsigned short) seed;
+ _rand48_seed[2] = (unsigned short) (seed >> 16);
+ _rand48_mult[0] = RAND48_MULT_0;
+ _rand48_mult[1] = RAND48_MULT_1;
+ _rand48_mult[2] = RAND48_MULT_2;
+ _rand48_add = RAND48_ADD;
+}
diff --git a/lib/libc/gen/stringlist.3 b/lib/libc/gen/stringlist.3
new file mode 100644
index 0000000..21fb2db
--- /dev/null
+++ b/lib/libc/gen/stringlist.3
@@ -0,0 +1,122 @@
+.\" $NetBSD: stringlist.3,v 1.2 1997/04/09 08:59:25 kleink Exp $
+.\"
+.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the NetBSD
+.\" Foundation, Inc. and its contributors.
+.\" 4. Neither the name of The NetBSD Foundation nor the names of its
+.\" contributors may be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 24, 1997
+.Os NetBSD 1.3
+.Dt STRINGLIST 3
+.Sh NAME
+.Nm stringlist ,
+.Nm sl_init ,
+.Nm sl_add ,
+.Nm sl_free ,
+.Nm sl_find
+.Nd stringlist manipulation functions
+.Sh SYNOPSIS
+.Fd #include <stringlist.h>
+.Ft StringList *
+.Fn sl_init
+.Ft void
+.Fn sl_add "StringList *sl" "char *item"
+.Ft void
+.Fn sl_free "StringList *sl" "int freeall"
+.Ft char *
+.Fn sl_find "StringList *sl" "char *item"
+.Sh DESCRIPTION
+The
+.Nm
+functions manipulate stringlists, which are lists of
+strings that extend automatically if necessary.
+.Pp
+The
+.Ar StringList
+structure has the following definition:
+.Bd -literal -offset indent
+typedef struct _stringlist {
+ char **sl_str;
+ size_t sl_max;
+ size_t sl_cur;
+} StringList;
+.Ed
+.Pp
+.Bl -tag -width "sl_str" -offset indent
+.It Ar sl_str
+a pointer to the base of the array containing the list.
+.It Ar sl_max
+the size of
+.Ar sl_str .
+.It Ar sl_cur
+the offset in
+.Ar sl_str
+of the current element.
+.El
+.Pp
+The following stringlist manipulation functions are available:
+.Bl -tag -width "sl_init()"
+.It Fn sl_init
+Create a stringlist.
+Returns a pointer to a
+.Ar StringList .
+.It Fn sl_free
+Releases memory occupied by
+.Ar sl
+and the
+.Ar sl->sl_str
+array.
+If
+.Ar freeall
+is non-zero, then each of the items within
+.Ar sl->sl_str
+is released as well.
+.It Fn sl_add
+Add
+.Ar item
+to
+.Ar sl->sl_str
+at
+.Ar sl->sl_cur ,
+extending the size of
+.Ar sl->sl_str
+.It Fn sl_find
+Find
+.Ar item
+in
+.Ar sl ,
+returning NULL if it's not found.
+.El
+.Sh SEE ALSO
+.Xr free 3 ,
+.Xr malloc 3
diff --git a/lib/libc/gen/stringlist.c b/lib/libc/gen/stringlist.c
new file mode 100644
index 0000000..bb74919
--- /dev/null
+++ b/lib/libc/gen/stringlist.c
@@ -0,0 +1,120 @@
+/* $NetBSD: stringlist.c,v 1.2 1997/01/17 07:26:20 lukem Exp $ */
+
+/*
+ * Copyright (c) 1994 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$NetBSD: stringlist.c,v 1.2 1997/01/17 07:26:20 lukem Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include <err.h>
+#include <stdlib.h>
+#include <stringlist.h>
+
+#define _SL_CHUNKSIZE 20
+
+/*
+ * sl_init(): Initialize a string list
+ */
+StringList *
+sl_init()
+{
+ StringList *sl = malloc(sizeof(StringList));
+ if (sl == NULL)
+ err(1, "stringlist: %m");
+
+ sl->sl_cur = 0;
+ sl->sl_max = _SL_CHUNKSIZE;
+ sl->sl_str = malloc(sl->sl_max * sizeof(char *));
+ if (sl->sl_str == NULL)
+ err(1, "stringlist: %m");
+ return sl;
+}
+
+
+/*
+ * sl_add(): Add an item to the string list
+ */
+void
+sl_add(sl, name)
+ StringList *sl;
+ char *name;
+{
+ if (sl->sl_cur == sl->sl_max - 1) {
+ sl->sl_max += _SL_CHUNKSIZE;
+ sl->sl_str = reallocf(sl->sl_str, sl->sl_max * sizeof(char *));
+ if (sl->sl_str == NULL)
+ err(1, "stringlist: %m");
+ }
+ sl->sl_str[sl->sl_cur++] = name;
+}
+
+
+/*
+ * sl_free(): Free a stringlist
+ */
+void
+sl_free(sl, all)
+ StringList *sl;
+ int all;
+{
+ size_t i;
+
+ if (sl == NULL)
+ return;
+ if (sl->sl_str) {
+ if (all)
+ for (i = 0; i < sl->sl_cur; i++)
+ free(sl->sl_str[i]);
+ free(sl->sl_str);
+ }
+ free(sl);
+}
+
+
+/*
+ * sl_find(): Find a name in the string list
+ */
+char *
+sl_find(sl, name)
+ StringList *sl;
+ char *name;
+{
+ size_t i;
+
+ for (i = 0; i < sl->sl_cur; i++)
+ if (strcmp(sl->sl_str[i], name) == 0)
+ return sl->sl_str[i];
+
+ return NULL;
+}
diff --git a/lib/libc/gen/strtofflags.c b/lib/libc/gen/strtofflags.c
new file mode 100644
index 0000000..5235eb3
--- /dev/null
+++ b/lib/libc/gen/strtofflags.c
@@ -0,0 +1,174 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)stat_flags.c 8.1 (Berkeley) 5/31/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stddef.h>
+#include <string.h>
+
+#define SAPPEND(s) { \
+ if (prefix != NULL) \
+ (void)strcat(string, prefix); \
+ (void)strcat(string, s); \
+ prefix = ","; \
+}
+
+/*
+ * flags_to_string --
+ * Convert stat flags to a comma-separated string. If no flags
+ * are set, return the default string.
+ */
+char *
+flags_to_string(flags, def)
+ u_long flags;
+ char *def;
+{
+ static char string[128];
+ char *prefix;
+
+ string[0] = '\0';
+ prefix = NULL;
+ if (flags & UF_APPEND)
+ SAPPEND("uappnd");
+ if (flags & UF_IMMUTABLE)
+ SAPPEND("uchg");
+#ifdef UF_NOUNLINK
+ if (flags & UF_NOUNLINK)
+ SAPPEND("uunlnk");
+#endif
+ if (flags & UF_NODUMP)
+ SAPPEND("nodump");
+ if (flags & UF_OPAQUE)
+ SAPPEND("opaque");
+ if (flags & SF_APPEND)
+ SAPPEND("sappnd");
+ if (flags & SF_ARCHIVED)
+ SAPPEND("arch");
+ if (flags & SF_IMMUTABLE)
+ SAPPEND("schg");
+#ifdef SF_NOUNLINK
+ if (flags & SF_NOUNLINK)
+ SAPPEND("sunlnk");
+#endif
+ return (prefix == NULL && def != NULL ? def : string);
+}
+
+#define TEST(a, b, f) { \
+ if (!memcmp(a, b, sizeof(b))) { \
+ if (clear) { \
+ if (clrp) \
+ *clrp |= (f); \
+ } else if (setp) \
+ *setp |= (f); \
+ break; \
+ } \
+}
+
+/*
+ * string_to_flags --
+ * Take string of arguments and return stat flags. Return 0 on
+ * success, 1 on failure. On failure, stringp is set to point
+ * to the offending token.
+ */
+int
+string_to_flags(stringp, setp, clrp)
+ char **stringp;
+ u_long *setp, *clrp;
+{
+ int clear;
+ char *string, *p;
+
+ if (setp)
+ *setp = 0;
+ if (clrp)
+ *clrp = 0;
+ string = *stringp;
+ while ((p = strsep(&string, "\t ,")) != NULL) {
+ clear = 0;
+ *stringp = p;
+ if (*p == '\0')
+ continue;
+ if (p[0] == 'n' && p[1] == 'o') {
+ clear = 1;
+ p += 2;
+ }
+ switch (p[0]) {
+ case 'a':
+ TEST(p, "arch", SF_ARCHIVED);
+ TEST(p, "archived", SF_ARCHIVED);
+ return (1);
+ case 'd':
+ clear = !clear;
+ TEST(p, "dump", UF_NODUMP);
+ return (1);
+ case 'o':
+ TEST(p, "opaque", UF_OPAQUE);
+ return (1);
+ case 's':
+ TEST(p, "sappnd", SF_APPEND);
+ TEST(p, "sappend", SF_APPEND);
+ TEST(p, "schg", SF_IMMUTABLE);
+ TEST(p, "schange", SF_IMMUTABLE);
+ TEST(p, "simmutable", SF_IMMUTABLE);
+#ifdef SF_NOUNLINK
+ TEST(p, "sunlnk", SF_NOUNLINK);
+ TEST(p, "sunlink", SF_NOUNLINK);
+#endif
+ return (1);
+ case 'u':
+ TEST(p, "uappnd", UF_APPEND);
+ TEST(p, "uappend", UF_APPEND);
+ TEST(p, "uchg", UF_IMMUTABLE);
+ TEST(p, "uchange", UF_IMMUTABLE);
+ TEST(p, "uimmutable", UF_IMMUTABLE);
+#ifdef UF_NOUNLINK
+ TEST(p, "uunlnk", UF_NOUNLINK);
+ TEST(p, "uunlink", UF_NOUNLINK);
+#endif
+ /* FALLTHROUGH */
+ default:
+ return (1);
+ }
+ }
+ return (0);
+}
diff --git a/lib/libc/gen/sysconf.3 b/lib/libc/gen/sysconf.3
new file mode 100644
index 0000000..e18c045
--- /dev/null
+++ b/lib/libc/gen/sysconf.3
@@ -0,0 +1,187 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sysconf.3 8.3 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt SYSCONF 3
+.Os BSD 4
+.Sh NAME
+.Nm sysconf
+.Nd get configurable system variables
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft long
+.Fn sysconf "int name"
+.Sh DESCRIPTION
+.Pp
+This interface is defined by
+.St -p1003.1-88 .
+A far more complete interface is available using
+.Xr sysctl 3 .
+.Pp
+The
+.Fn sysconf
+function provides a method for applications to determine the current
+value of a configurable system limit or option variable.
+The
+.Fa name
+argument specifies the system variable to be queried.
+Symbolic constants for each name value are found in the include file
+.Li <unistd.h> .
+.Pp
+The available values are as follows:
+.Pp
+.Bl -tag -width "123456"
+.Pp
+.It Li _SC_ARG_MAX
+The maximum bytes of argument to
+.Xr execve 2 .
+.It Li _SC_CHILD_MAX
+The maximum number of simultaneous processes per user id.
+.It Li _SC_CLK_TCK
+The frequency of the statistics clock in ticks per second.
+.It Li _SC_NGROUPS_MAX
+The maximum number of supplemental groups.
+.It Li _SC_OPEN_MAX
+The maximum number of open files per user id.
+.It Li _SC_STREAM_MAX
+The minimum maximum number of streams that a process may have open
+at any one time.
+.It Li _SC_TZNAME_MAX
+The minimum maximum number of types supported for the name of a
+timezone.
+.It Li _SC_JOB_CONTROL
+Return 1 if job control is available on this system, otherwise \-1.
+.It Li _SC_SAVED_IDS
+Returns 1 if saved set-group and saved set-user ID is available,
+otherwise \-1.
+.It Li _SC_VERSION
+The version of ISO/IEC 9945 (POSIX 1003.1) with which the system
+attempts to comply.
+.It Li _SC_BC_BASE_MAX
+The maximum ibase/obase values in the
+.Xr bc 1
+utility.
+.It Li _SC_BC_DIM_MAX
+The maximum array size in the
+.Xr bc 1
+utility.
+.It Li _SC_BC_SCALE_MAX
+The maximum scale value in the
+.Xr bc 1
+utility.
+.It Li _SC_BC_STRING_MAX
+The maximum string length in the
+.Xr bc 1
+utility.
+.It Li _SC_COLL_WEIGHTS_MAX
+The maximum number of weights that can be assigned to any entry of
+the LC_COLLATE order keyword in the locale definition file.
+.It Li _SC_EXPR_NEST_MAX
+The maximum number of expressions that can be nested within
+parenthesis by the
+.Xr expr 1
+utility.
+.It Li _SC_LINE_MAX
+The maximum length in bytes of a text-processing utility's input
+line.
+.It Li _SC_RE_DUP_MAX
+The maximum number of repeated occurrences of a regular expression
+permitted when using interval notation.
+.It Li _SC_2_VERSION
+The version of POSIX 1003.2 with which the system attempts to comply.
+.It Li _SC_2_C_BIND
+Return 1 if the system's C-language development facilities support the
+C-Language Bindings Option, otherwise \-1.
+.It Li _SC_2_C_DEV
+Return 1 if the system supports the C-Language Development Utilities Option,
+otherwise \-1.
+.It Li _SC_2_CHAR_TERM
+Return 1 if the system supports at least one terminal type capable of
+all operations described in POSIX 1003.2, otherwise \-1.
+.It Li _SC_2_FORT_DEV
+Return 1 if the system supports the FORTRAN Development Utilities Option,
+otherwise \-1.
+.It Li _SC_2_FORT_RUN
+Return 1 if the system supports the FORTRAN Runtime Utilities Option,
+otherwise \-1.
+.It Li _SC_2_LOCALEDEF
+Return 1 if the system supports the creation of locales, otherwise \-1.
+.It Li _SC_2_SW_DEV
+Return 1 if the system supports the Software Development Utilities Option,
+otherwise \-1.
+.It Li _SC_2_UPE
+Return 1 if the system supports the User Portability Utilities Option,
+otherwise \-1.
+.El
+.Sh RETURN VALUES
+If the call to
+.Fn sysconf
+is not successful, \-1 is returned and
+.Va errno
+is set appropriately.
+Otherwise, if the variable is associated with functionality that is not
+supported, \-1 is returned and
+.Va errno
+is not modified.
+Otherwise, the current variable value is returned.
+.Sh ERRORS
+The
+.Fn sysconf
+function may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr sysctl 3 .
+In addition, the following error may be reported:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value of the
+.Fa name
+argument is invalid.
+.Sh SEE ALSO
+.Xr sysctl 3
+.Sh BUGS
+The value for _SC_STREAM_MAX is a minimum maximum, and required to be
+the same as ANSI C's FOPEN_MAX, so the returned value is a ridiculously
+small and misleading number.
+.Sh STANDARDS
+Except for the fact that values returned by
+.Fn sysconf
+may change over the lifetime of the calling process,
+this function conforms to
+.St -p1003.1-88 .
+.Sh HISTORY
+The
+.Fn sysconf
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/gen/sysconf.c b/lib/libc/gen/sysconf.c
new file mode 100644
index 0000000..2298bb1
--- /dev/null
+++ b/lib/libc/gen/sysconf.c
@@ -0,0 +1,299 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Sean Eric Fagan of Cygnus Support.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)sysconf.c 8.2 (Berkeley) 3/20/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/_posix.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/sysctl.h>
+#include <sys/resource.h>
+
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+
+/*
+ * sysconf --
+ * get configurable system variables.
+ *
+ * XXX
+ * POSIX 1003.1 (ISO/IEC 9945-1, 4.8.1.3) states that the variable values
+ * not change during the lifetime of the calling process. This would seem
+ * to require that any change to system limits kill all running processes.
+ * A workaround might be to cache the values when they are first retrieved
+ * and then simply return the cached value on subsequent calls. This is
+ * less useful than returning up-to-date values, however.
+ */
+long
+sysconf(name)
+ int name;
+{
+ struct rlimit rl;
+ size_t len;
+ int mib[2], value;
+ long defaultresult;
+
+ len = sizeof(value);
+ defaultresult = -1;
+
+ switch (name) {
+/* 1003.1 */
+ case _SC_ARG_MAX:
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_ARGMAX;
+ break;
+ case _SC_CHILD_MAX:
+ return (getrlimit(RLIMIT_NPROC, &rl) ? -1 : rl.rlim_cur);
+ case _SC_CLK_TCK:
+ return (CLK_TCK);
+ case _SC_JOB_CONTROL:
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_JOB_CONTROL;
+ goto yesno;
+ case _SC_NGROUPS_MAX:
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_NGROUPS;
+ break;
+ case _SC_OPEN_MAX:
+ return (getrlimit(RLIMIT_NOFILE, &rl) ? -1 : rl.rlim_cur);
+ case _SC_STREAM_MAX:
+ mib[0] = CTL_USER;
+ mib[1] = USER_STREAM_MAX;
+ break;
+ case _SC_TZNAME_MAX:
+ mib[0] = CTL_USER;
+ mib[1] = USER_TZNAME_MAX;
+ break;
+ case _SC_SAVED_IDS:
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_SAVED_IDS;
+ goto yesno;
+ case _SC_VERSION:
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_POSIX1;
+ break;
+
+/* 1003.2 */
+ case _SC_BC_BASE_MAX:
+ mib[0] = CTL_USER;
+ mib[1] = USER_BC_BASE_MAX;
+ break;
+ case _SC_BC_DIM_MAX:
+ mib[0] = CTL_USER;
+ mib[1] = USER_BC_DIM_MAX;
+ break;
+ case _SC_BC_SCALE_MAX:
+ mib[0] = CTL_USER;
+ mib[1] = USER_BC_SCALE_MAX;
+ break;
+ case _SC_BC_STRING_MAX:
+ mib[0] = CTL_USER;
+ mib[1] = USER_BC_STRING_MAX;
+ break;
+ case _SC_COLL_WEIGHTS_MAX:
+ mib[0] = CTL_USER;
+ mib[1] = USER_COLL_WEIGHTS_MAX;
+ break;
+ case _SC_EXPR_NEST_MAX:
+ mib[0] = CTL_USER;
+ mib[1] = USER_EXPR_NEST_MAX;
+ break;
+ case _SC_LINE_MAX:
+ mib[0] = CTL_USER;
+ mib[1] = USER_LINE_MAX;
+ break;
+ case _SC_RE_DUP_MAX:
+ mib[0] = CTL_USER;
+ mib[1] = USER_RE_DUP_MAX;
+ break;
+ case _SC_2_VERSION:
+ mib[0] = CTL_USER;
+ mib[1] = USER_POSIX2_VERSION;
+ break;
+ case _SC_2_C_BIND:
+ mib[0] = CTL_USER;
+ mib[1] = USER_POSIX2_C_BIND;
+ goto yesno;
+ case _SC_2_C_DEV:
+ mib[0] = CTL_USER;
+ mib[1] = USER_POSIX2_C_DEV;
+ goto yesno;
+ case _SC_2_CHAR_TERM:
+ mib[0] = CTL_USER;
+ mib[1] = USER_POSIX2_CHAR_TERM;
+ goto yesno;
+ case _SC_2_FORT_DEV:
+ mib[0] = CTL_USER;
+ mib[1] = USER_POSIX2_FORT_DEV;
+ goto yesno;
+ case _SC_2_FORT_RUN:
+ mib[0] = CTL_USER;
+ mib[1] = USER_POSIX2_FORT_RUN;
+ goto yesno;
+ case _SC_2_LOCALEDEF:
+ mib[0] = CTL_USER;
+ mib[1] = USER_POSIX2_LOCALEDEF;
+ goto yesno;
+ case _SC_2_SW_DEV:
+ mib[0] = CTL_USER;
+ mib[1] = USER_POSIX2_SW_DEV;
+ goto yesno;
+ case _SC_2_UPE:
+ mib[0] = CTL_USER;
+ mib[1] = USER_POSIX2_UPE;
+ goto yesno;
+
+#ifdef _P1003_1B_VISIBLE
+ /* POSIX.1B */
+
+ case _SC_ASYNCHRONOUS_IO:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_ASYNCHRONOUS_IO;
+ goto yesno;
+ case _SC_MAPPED_FILES:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_MAPPED_FILES;
+ goto yesno;
+ case _SC_MEMLOCK:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_MEMLOCK;
+ goto yesno;
+ case _SC_MEMLOCK_RANGE:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_MEMLOCK_RANGE;
+ goto yesno;
+ case _SC_MEMORY_PROTECTION:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_MEMORY_PROTECTION;
+ goto yesno;
+ case _SC_MESSAGE_PASSING:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_MESSAGE_PASSING;
+ goto yesno;
+ case _SC_PRIORITIZED_IO:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_PRIORITIZED_IO;
+ goto yesno;
+ case _SC_PRIORITY_SCHEDULING:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_PRIORITY_SCHEDULING;
+ goto yesno;
+ case _SC_REALTIME_SIGNALS:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_REALTIME_SIGNALS;
+ goto yesno;
+ case _SC_SEMAPHORES:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SEMAPHORES;
+ goto yesno;
+ case _SC_FSYNC:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_FSYNC;
+ goto yesno;
+ case _SC_SHARED_MEMORY_OBJECTS:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SHARED_MEMORY_OBJECTS;
+ goto yesno;
+ case _SC_SYNCHRONIZED_IO:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SYNCHRONIZED_IO;
+ goto yesno;
+ case _SC_TIMERS:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_TIMERS;
+ goto yesno;
+ case _SC_AIO_LISTIO_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_AIO_LISTIO_MAX;
+ goto yesno;
+ case _SC_AIO_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_AIO_MAX;
+ goto yesno;
+ case _SC_AIO_PRIO_DELTA_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_AIO_PRIO_DELTA_MAX;
+ goto yesno;
+ case _SC_DELAYTIMER_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_DELAYTIMER_MAX;
+ goto yesno;
+ case _SC_MQ_OPEN_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_MQ_OPEN_MAX;
+ goto yesno;
+ case _SC_PAGESIZE:
+ defaultresult = getpagesize();
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_PAGESIZE;
+ goto yesno;
+ case _SC_RTSIG_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_RTSIG_MAX;
+ goto yesno;
+ case _SC_SEM_NSEMS_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SEM_NSEMS_MAX;
+ goto yesno;
+ case _SC_SEM_VALUE_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SEM_VALUE_MAX;
+ goto yesno;
+ case _SC_SIGQUEUE_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SIGQUEUE_MAX;
+ goto yesno;
+ case _SC_TIMER_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_TIMER_MAX;
+ goto yesno;
+#endif /* _P1003_1B_VISIBLE */
+
+yesno: if (sysctl(mib, 2, &value, &len, NULL, 0) == -1)
+ return (-1);
+ if (value == 0)
+ return (defaultresult);
+ return (value);
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+ return (sysctl(mib, 2, &value, &len, NULL, 0) == -1 ? -1 : value);
+}
diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3
new file mode 100644
index 0000000..098d4f2
--- /dev/null
+++ b/lib/libc/gen/sysctl.3
@@ -0,0 +1,746 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sysctl.3 8.4 (Berkeley) 5/9/95
+.\" $FreeBSD$
+.\"
+.Dd May 9, 1995
+.Dt SYSCTL 3
+.Os
+.Sh NAME
+.Nm sysctl ,
+.Nm sysctlbyname
+.Nd get or set system information
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/sysctl.h>
+.Ft int
+.Fn sysctl "int *name" "u_int namelen" "void *oldp" "size_t *oldlenp" "void *newp" "size_t newlen"
+.Ft int
+.Fn sysctlbyname "const char *name" "void *oldp" "size_t *oldlenp" "void *newp" "size_t newlen"
+.Sh DESCRIPTION
+The
+.Fn sysctl
+function retrieves system information and allows processes with
+appropriate privileges to set system information.
+The information available from
+.Fn sysctl
+consists of integers, strings, and tables.
+Information may be retrieved and set from the command interface
+using the
+.Xr sysctl 8
+utility.
+.Pp
+Unless explicitly noted below,
+.Fn sysctl
+returns a consistent snapshot of the data requested.
+Consistency is obtained by locking the destination
+buffer into memory so that the data may be copied out without blocking.
+Calls to
+.Fn sysctl
+are serialized to avoid deadlock.
+.Pp
+The state is described using a ``Management Information Base'' (MIB)
+style name, listed in
+.Fa name ,
+which is a
+.Fa namelen
+length array of integers.
+.Pp
+The
+.Fn sysctlbyname
+function accepts an ASCII representation of the name and internally
+looks up the integer name vector. Apart from that, it behaves the same
+as the standard
+.Fn sysctl
+function.
+.Pp
+The information is copied into the buffer specified by
+.Fa oldp .
+The size of the buffer is given by the location specified by
+.Fa oldlenp
+before the call,
+and that location gives the amount of data copied after a successful call
+and after a call that returns with the error code ENOMEM.
+If the amount of data available is greater
+than the size of the buffer supplied,
+the call supplies as much data as fits in the buffer provided
+and returns with the error code ENOMEM.
+If the old value is not desired,
+.Fa oldp
+and
+.Fa oldlenp
+should be set to NULL.
+.Pp
+The size of the available data can be determined by calling
+.Fn sysctl
+with a NULL parameter for
+.Fa oldp .
+The size of the available data will be returned in the location pointed to by
+.Fa oldlenp .
+For some operations, the amount of space may change often.
+For these operations,
+the system attempts to round up so that the returned size is
+large enough for a call to return the data shortly thereafter.
+.Pp
+To set a new value,
+.Fa newp
+is set to point to a buffer of length
+.Fa newlen
+from which the requested value is to be taken.
+If a new value is not to be set,
+.Fa newp
+should be set to NULL and
+.Fa newlen
+set to 0.
+.Pp
+The top level names are defined with a CTL_ prefix in
+.Pa <sys/sysctl.h> ,
+and are as follows.
+The next and subsequent levels down are found in the include files
+listed here, and described in separate sections below.
+.Pp
+.Bl -column CTLXMACHDEPXXX "Next level namesXXXXXX" -offset indent
+.It Sy Pa Name Next level names Description
+.It CTL\_DEBUG sys/sysctl.h Debugging
+.It CTL\_VFS sys/mount.h Filesystem
+.It CTL\_HW sys/sysctl.h Generic CPU, I/O
+.It CTL\_KERN sys/sysctl.h High kernel limits
+.It CTL\_MACHDEP sys/sysctl.h Machine dependent
+.It CTL\_NET sys/socket.h Networking
+.It CTL\_USER sys/sysctl.h User-level
+.It CTL\_VM vm/vm_param.h Virtual memory
+.El
+.Pp
+For example, the following retrieves the maximum number of processes allowed
+in the system:
+.Pp
+.Bd -literal -offset indent -compact
+int mib[2], maxproc;
+size_t len;
+
+mib[0] = CTL_KERN;
+mib[1] = KERN_MAXPROC;
+len = sizeof(maxproc);
+sysctl(mib, 2, &maxproc, &len, NULL, 0);
+.Ed
+.Pp
+To retrieve the standard search path for the system utilities:
+.Pp
+.Bd -literal -offset indent -compact
+int mib[2];
+size_t len;
+char *p;
+
+mib[0] = CTL_USER;
+mib[1] = USER_CS_PATH;
+sysctl(mib, 2, NULL, &len, NULL, 0);
+p = malloc(len);
+sysctl(mib, 2, p, &len, NULL, 0);
+.Ed
+.Sh CTL_DEBUG
+The debugging variables vary from system to system.
+A debugging variable may be added or deleted without need to recompile
+.Fn sysctl
+to know about it.
+Each time it runs,
+.Fn sysctl
+gets the list of debugging variables from the kernel and
+displays their current values.
+The system defines twenty
+.Ns ( Va struct ctldebug )
+variables named
+.Nm debug0
+through
+.Nm debug19 .
+They are declared as separate variables so that they can be
+individually initialized at the location of their associated variable.
+The loader prevents multiple use of the same variable by issuing errors
+if a variable is initialized in more than one place.
+For example, to export the variable
+.Nm dospecialcheck
+as a debugging variable, the following declaration would be used:
+.Bd -literal -offset indent -compact
+int dospecialcheck = 1;
+struct ctldebug debug5 = { "dospecialcheck", &dospecialcheck };
+.Ed
+.Sh CTL_VFS
+A distinguished second level name, VFS_GENERIC,
+is used to get general information about all filesystems.
+One of its third level identifiers is VFS_MAXTYPENUM
+that gives the highest valid filesystem type number.
+Its other third level identifier is VFS_CONF that
+returns configuration information about the filesystem
+type given as a fourth level identifier (see
+.Xr getvfsbyname 3
+as an example of its use).
+The remaining second level identifiers are the
+filesystem type number returned by a
+.Xr statfs 2
+call or from VFS_CONF.
+The third level identifiers available for each filesystem
+are given in the header file that defines the mount
+argument structure for that filesystem.
+.Sh CTL_HW
+The string and integer information available for the CTL_HW level
+is detailed below.
+The changeable column shows whether a process with appropriate
+privilege may change the value.
+.Bl -column "Second level nameXXXXXX" integerXXX -offset indent
+.It Sy Pa Second level name Type Changeable
+.It HW\_MACHINE string no
+.It HW\_MODEL string no
+.It HW\_NCPU integer no
+.It HW\_BYTEORDER integer no
+.It HW\_PHYSMEM integer no
+.It HW\_USERMEM integer no
+.It HW\_PAGESIZE integer no
+.It HW\_FLOATINGPOINT integer no
+.It HW\_MACHINE\_ARCH string no
+.\".It HW\_DISKNAMES integer no
+.\".It HW\_DISKSTATS integer no
+.El
+.Pp
+.Bl -tag -width "123456"
+.It Li HW_MACHINE
+The machine class.
+.It Li HW_MODEL
+The machine model
+.It Li HW_NCPU
+The number of cpus.
+.ne 1i
+.It Li HW_BYTEORDER
+The byteorder (4,321, or 1,234).
+.It Li HW_PHYSMEM
+The bytes of physical memory.
+.It Li HW_USERMEM
+The bytes of non-kernel memory.
+.It Li HW_PAGESIZE
+The software page size.
+.It Li HW_FLOATINGPOINT
+Nonzero if the floating point support is in hardware.
+.It Li HW_MACHINE_ARCH
+The machine dependent architecture type.
+.\".It Fa HW_DISKNAMES
+.\".It Fa HW_DISKSTATS
+.El
+.Sh CTL_KERN
+The string and integer information available for the CTL_KERN level
+is detailed below.
+The changeable column shows whether a process with appropriate
+privilege may change the value.
+The types of data currently available are process information,
+system vnodes, the open file entries, routing table entries,
+virtual memory statistics, load average history, and clock rate
+information.
+.Bl -column "KERNXMAXFILESPERPROCXXX" "struct clockrateXXX" -offset indent
+.It Sy Pa Second level name Type Changeable
+.It KERN\_ARGMAX integer no
+.It KERN\_BOOTFILE string yes
+.It KERN\_BOOTTIME struct timeval no
+.It KERN\_CLOCKRATE struct clockinfo no
+.It KERN\_FILE struct file no
+.It KERN\_HOSTID integer yes
+.It KERN\_HOSTNAME string yes
+.It KERN\_JOB\_CONTROL integer no
+.It KERN\_MAXFILES integer yes
+.It KERN\_MAXFILESPERPROC integer yes
+.It KERN\_MAXPROC integer no
+.It KERN\_MAXPROCPERUID integer yes
+.It KERN\_MAXVNODES integer yes
+.It KERN\_NGROUPS integer no
+.It KERN\_NISDOMAINNAME string yes
+.It KERN\_OSRELDATE integer no
+.It KERN\_OSRELEASE string no
+.It KERN\_OSREV integer no
+.It KERN\_OSTYPE string no
+.It KERN\_POSIX1 integer no
+.It KERN\_PROC struct proc no
+.It KERN\_PROF node not applicable
+.It KERN\_SAVED\_IDS integer no
+.It KERN\_SECURELVL integer raise only
+.It KERN\_UPDATEINTERVAL integer no
+.It KERN\_VERSION string no
+.It KERN\_VNODE struct vnode no
+.El
+.ne 1i
+.Pp
+.Bl -tag -width "123456"
+.It Li KERN_ARGMAX
+The maximum bytes of argument to
+.Xr execve 2 .
+.It Li KERN_BOOTFILE
+The full pathname of the file from which the kernel was loaded.
+.It Li KERN_BOOTTIME
+A
+.Va struct timeval
+structure is returned.
+This structure contains the time that the system was booted.
+.It Li KERN_CLOCKRATE
+A
+.Va struct clockinfo
+structure is returned.
+This structure contains the clock, statistics clock and profiling clock
+frequencies, the number of micro-seconds per hz tick and the skew rate.
+.It Li KERN_FILE
+Return the entire file table.
+The returned data consists of a single
+.Va struct filehead
+followed by an array of
+.Va struct file ,
+whose size depends on the current number of such objects in the system.
+.It Li KERN_HOSTID
+Get or set the host id.
+.It Li KERN_HOSTNAME
+Get or set the hostname.
+.It Li KERN_JOB_CONTROL
+Return 1 if job control is available on this system, otherwise 0.
+.It Li KERN_MAXFILES
+The maximum number of files that may be open in the system.
+.It Li KERN_MAXFILESPERPROC
+The maximum number of files that may be open for a single process.
+This limit only applies to processes with an effective uid of nonzero
+at the time of the open request.
+Files that have already been opened are not affected if the limit
+or the effective uid is changed.
+.It Li KERN_MAXPROC
+The maximum number of concurrent processes the system will allow.
+.It Li KERN_MAXPROCPERUID
+The maximum number of concurrent processes the system will allow
+for a single effective uid.
+This limit only applies to processes with an effective uid of nonzero
+at the time of a fork request.
+Processes that have already been started are not affected if the limit
+is changed.
+.It Li KERN_MAXVNODES
+The maximum number of vnodes available on the system.
+.It Li KERN_NGROUPS
+The maximum number of supplemental groups.
+.It Li KERN_NISDOMAINNAME
+The name of the current YP/NIS domain.
+.It Li KERN_OSRELDATE
+The system release date in YYYYMM format
+(January 1996 is encoded as 199601).
+.It Li KERN_OSRELEASE
+The system release string.
+.It Li KERN_OSREV
+The system revision string.
+.It Li KERN_OSTYPE
+The system type string.
+.It Li KERN_POSIX1
+The version of ISO/IEC 9945 (POSIX 1003.1) with which the system
+attempts to comply.
+.It Li KERN_PROC
+Return the entire process table, or a subset of it.
+An array of
+.Va struct kinfo_proc
+structures is returned,
+whose size depends on the current number of such objects in the system.
+The third and fourth level names are as follows:
+.Bl -column "Third level nameXXXXXX" "Fourth level is:XXXXXX" -offset indent
+.It Pa Third level name Fourth level is:
+.It KERN\_PROC\_ALL None
+.It KERN\_PROC\_PID A process ID
+.It KERN\_PROC\_PGRP A process group
+.It KERN\_PROC\_TTY A tty device
+.It KERN\_PROC\_UID A user ID
+.It KERN\_PROC\_RUID A real user ID
+.El
+.It Li KERN_PROF
+Return profiling information about the kernel.
+If the kernel is not compiled for profiling,
+attempts to retrieve any of the KERN_PROF values will
+fail with EOPNOTSUPP.
+The third level names for the string and integer profiling information
+is detailed below.
+The changeable column shows whether a process with appropriate
+privilege may change the value.
+.Bl -column "GPROFXGMONPARAMXXX" "struct gmonparamXXX" -offset indent
+.It Sy Pa Third level name Type Changeable
+.It GPROF\_STATE integer yes
+.It GPROF\_COUNT u_short[\|] yes
+.It GPROF\_FROMS u_short[\|] yes
+.It GPROF\_TOS struct tostruct yes
+.It GPROF\_GMONPARAM struct gmonparam no
+.El
+.Pp
+The variables are as follows:
+.Bl -tag -width "123456"
+.It Li GPROF_STATE
+Returns GMON_PROF_ON or GMON_PROF_OFF to show that profiling
+is running or stopped.
+.It Li GPROF_COUNT
+Array of statistical program counter counts.
+.It Li GPROF_FROMS
+Array indexed by program counter of call-from points.
+.It Li GPROF_TOS
+Array of
+.Va struct tostruct
+describing destination of calls and their counts.
+.It Li GPROF_GMONPARAM
+Structure giving the sizes of the above arrays.
+.El
+.ne 1i
+.It Li KERN_SAVED_IDS
+Returns 1 if saved set-group and saved set-user ID is available.
+.It Li KERN_SECURELVL
+The system security level.
+This level may be raised by processes with appropriate privilege.
+It may not be lowered.
+.It Li KERN_VERSION
+The system version string.
+.It Li KERN_VNODE
+Return the entire vnode table.
+Note, the vnode table is not necessarily a consistent snapshot of
+the system.
+The returned data consists of an array whose size depends on the
+current number of such objects in the system.
+Each element of the array contains the kernel address of a vnode
+.Va struct vnode *
+followed by the vnode itself
+.Va struct vnode .
+.It Li KERN_UPDATEINTERVAL
+The interval between
+.Xr sync 2
+calls in the
+.Xr update 4
+process.
+.El
+.Sh CTL_MACHDEP
+The set of variables defined is architecture dependent.
+The following variables are defined for the i386 architecture.
+.Bl -column "CONSOLE_DEVICEXXX" "struct bootinfoXXX" -offset indent
+.It Sy Pa Second level name Type Changeable
+.It Li CPU_CONSDEV dev_t no
+.It Li CPU_ADJKERNTZ int yes
+.It Li CPU_DISRTCSET int yes
+.It Li CPU_BOOTINFO struct bootinfo no
+.It Li CPU_WALLCLOCK int yes
+.El
+.Sh CTL_NET
+The string and integer information available for the CTL_NET level
+is detailed below.
+The changeable column shows whether a process with appropriate
+privilege may change the value.
+.Bl -column "Second level nameXXXXXX" "routing messagesXXX" -offset indent
+.It Sy Pa Second level name Type Changeable
+.It PF\_ROUTE routing messages no
+.It PF\_INET internet values yes
+.El
+.Pp
+.Bl -tag -width "123456"
+.It Li PF_ROUTE
+Return the entire routing table or a subset of it.
+The data is returned as a sequence of routing messages (see
+.Xr route 4
+for the header file, format and meaning).
+The length of each message is contained in the message header.
+.Pp
+The third level name is a protocol number, which is currently always 0.
+The fourth level name is an address family, which may be set to 0 to
+select all address families.
+The fifth and sixth level names are as follows:
+.Bl -column "Fifth level nameXXXXXX" "Sixth level is:XXX" -offset indent
+.It Pa Fifth level name Sixth level is:
+.It NET\_RT\_FLAGS rtflags
+.It NET\_RT\_DUMP None
+.It NET\_RT\_IFLIST None
+.El
+.It Li PF_INET
+Get or set various global information about the internet protocols.
+The third level name is the protocol.
+The fourth level name is the variable name.
+The currently defined protocols and names are:
+.ne 1i
+.Bl -column ProtocolXX VariableXX TypeXX ChangeableXX
+.It Pa Protocol Variable Type Changeable
+.It icmp bmcastecho integer yes
+.It icmp maskrepl integer yes
+.It ip forwarding integer yes
+.It ip redirect integer yes
+.It ip ttl integer yes
+.It udp checksum integer yes
+.El
+.Pp
+The variables are as follows:
+.Bl -tag -width "123456"
+.It Li icmp.bmcastecho
+Returns 1 if an ICMP echo request to a broadcast or multicast address is
+to be answered.
+.It Li icmp.maskrepl
+Returns 1 if ICMP network mask requests are to be answered.
+.It Li ip.forwarding
+Returns 1 when IP forwarding is enabled for the host,
+meaning that the host is acting as a router.
+.It Li ip.redirect
+Returns 1 when ICMP redirects may be sent by the host.
+This option is ignored unless the host is routing IP packets,
+and should normally be enabled on all systems.
+.It Li ip.ttl
+The maximum time-to-live (hop count) value for an IP packet sourced by
+the system.
+This value applies to normal transport protocols, not to ICMP.
+.It Li udp.checksum
+Returns 1 when UDP checksums are being computed and checked.
+Disabling UDP checksums is strongly discouraged.
+.El
+.Sh CTL_USER
+The string and integer information available for the CTL_USER level
+is detailed below.
+The changeable column shows whether a process with appropriate
+privilege may change the value.
+.Bl -column "USER_COLL_WEIGHTS_MAXXXX" "integerXXX" -offset indent
+.It Sy Pa Second level name Type Changeable
+.It USER\_BC\_BASE\_MAX integer no
+.It USER\_BC\_DIM\_MAX integer no
+.It USER\_BC\_SCALE\_MAX integer no
+.It USER\_BC\_STRING\_MAX integer no
+.It USER\_COLL\_WEIGHTS\_MAX integer no
+.It USER\_CS\_PATH string no
+.It USER\_EXPR\_NEST\_MAX integer no
+.It USER\_LINE\_MAX integer no
+.It USER\_POSIX2\_CHAR\_TERM integer no
+.It USER\_POSIX2\_C\_BIND integer no
+.It USER\_POSIX2\_C\_DEV integer no
+.It USER\_POSIX2\_FORT\_DEV integer no
+.It USER\_POSIX2\_FORT\_RUN integer no
+.It USER\_POSIX2\_LOCALEDEF integer no
+.It USER\_POSIX2\_SW\_DEV integer no
+.It USER\_POSIX2\_UPE integer no
+.It USER\_POSIX2\_VERSION integer no
+.It USER\_RE\_DUP\_MAX integer no
+.It USER\_STREAM\_MAX integer no
+.It USER\_TZNAME\_MAX integer no
+.El
+.Bl -tag -width "123456"
+.Pp
+.It Li USER_BC_BASE_MAX
+The maximum ibase/obase values in the
+.Xr bc 1
+utility.
+.It Li USER_BC_DIM_MAX
+The maximum array size in the
+.Xr bc 1
+utility.
+.It Li USER_BC_SCALE_MAX
+The maximum scale value in the
+.Xr bc 1
+utility.
+.It Li USER_BC_STRING_MAX
+The maximum string length in the
+.Xr bc 1
+utility.
+.It Li USER_COLL_WEIGHTS_MAX
+The maximum number of weights that can be assigned to any entry of
+the LC_COLLATE order keyword in the locale definition file.
+.It Li USER_CS_PATH
+Return a value for the
+.Ev PATH
+environment variable that finds all the standard utilities.
+.It Li USER_EXPR_NEST_MAX
+The maximum number of expressions that can be nested within
+parenthesis by the
+.Xr expr 1
+utility.
+.It Li USER_LINE_MAX
+The maximum length in bytes of a text-processing utility's input
+line.
+.It Li USER_POSIX2_CHAR_TERM
+Return 1 if the system supports at least one terminal type capable of
+all operations described in POSIX 1003.2, otherwise 0.
+.It Li USER_POSIX2_C_BIND
+Return 1 if the system's C-language development facilities support the
+C-Language Bindings Option, otherwise 0.
+.It Li USER_POSIX2_C_DEV
+Return 1 if the system supports the C-Language Development Utilities Option,
+otherwise 0.
+.It Li USER_POSIX2_FORT_DEV
+Return 1 if the system supports the FORTRAN Development Utilities Option,
+otherwise 0.
+.It Li USER_POSIX2_FORT_RUN
+Return 1 if the system supports the FORTRAN Runtime Utilities Option,
+otherwise 0.
+.It Li USER_POSIX2_LOCALEDEF
+Return 1 if the system supports the creation of locales, otherwise 0.
+.It Li USER_POSIX2_SW_DEV
+Return 1 if the system supports the Software Development Utilities Option,
+otherwise 0.
+.It Li USER_POSIX2_UPE
+Return 1 if the system supports the User Portability Utilities Option,
+otherwise 0.
+.It Li USER_POSIX2_VERSION
+The version of POSIX 1003.2 with which the system attempts to comply.
+.It Li USER_RE_DUP_MAX
+The maximum number of repeated occurrences of a regular expression
+permitted when using interval notation.
+.ne 1i
+.It Li USER_STREAM_MAX
+The minimum maximum number of streams that a process may have open
+at any one time.
+.It Li USER_TZNAME_MAX
+The minimum maximum number of types supported for the name of a
+timezone.
+.El
+.Sh CTL_VM
+The string and integer information available for the CTL_VM level
+is detailed below.
+The changeable column shows whether a process with appropriate
+privilege may change the value.
+.Bl -column "Second level nameXXXXXX" "struct loadavgXXX" -offset indent
+.It Sy Pa Second level name Type Changeable
+.It VM\_LOADAVG struct loadavg no
+.It VM\_METER struct vmtotal no
+.It VM\_PAGEOUT\_ALGORITHM integer yes
+.It VM\_SWAPPING\_ENABLED integer maybe
+.It VM\_V\_CACHE\_MAX integer yes
+.It VM\_V\_CACHE\_MIN integer yes
+.It VM\_V\_FREE\_MIN integer yes
+.It VM\_V\_FREE\_RESERVED integer yes
+.It VM\_V\_FREE\_TARGET integer yes
+.It VM\_V\_INACTIVE\_TARGET integer yes
+.It VM\_V\_PAGEOUT\_FREE\_MIN integer yes
+.El
+.Pp
+.Bl -tag -width "123456"
+.It Li VM_LOADAVG
+Return the load average history.
+The returned data consists of a
+.Va struct loadavg .
+.It Li VM_METER
+Return the system wide virtual memory statistics.
+The returned data consists of a
+.Va struct vmtotal .
+.It Li VM_PAGEOUT_ALGORITHM
+0 if the statistics-based page management algorithm is in use
+or 1 if the near-LRU algorithm is in use.
+.It Li VM_SWAPPING_ENABLED
+1 if process swapping is enabled or 0 if disabled. This variable is
+permanently set to 0 if the kernel was built with swapping disabled.
+.It Li VM_V_CACHE_MAX
+Maximum desired size of the cache queue.
+.It Li VM_V_CACHE_MIN
+Minimum desired size of the cache queue. If the cache queue size
+falls very far below this value, the pageout daemon is awakened.
+.It Li VM_V_FREE_MIN
+Minimum amount of memory (cache memory plus free memory)
+required to be available before a process waiting on memory will be
+awakened.
+.It Li VM_V_FREE_RESERVED
+Processes will awaken the pageout daemon and wait for memory if the
+number of free and cached pages drops below this value.
+.It Li VM_V_FREE_TARGET
+The total amount of free memory (including cache memory) that the
+pageout daemon tries to maintain.
+.It Li VM_V_INACTIVE_TARGET
+The desired number of inactive pages that the pageout daemon should
+achieve when it runs. Inactive pages can be quickly inserted into
+process address space when needed.
+.It Li VM_V_PAGEOUT_FREE_MIN
+If the amount of free and cache memory falls below this value, the
+pageout daemon will enter "memory conserving mode" to avoid deadlock.
+.El
+.Sh RETURN VALUES
+.Fn sysctl
+and
+.Fn sysctlbyname
+return 0 when successful.
+Otherwise \-1 is returned and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+The following errors may be reported:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+The buffer
+.Fa name ,
+.Fa oldp ,
+.Fa newp ,
+or length pointer
+.Fa oldlenp
+contains an invalid address.
+.It Bq Er EINVAL
+The
+.Fa name
+array is less than two or greater than CTL_MAXNAME.
+.It Bq Er EINVAL
+A non-null
+.Fa newp
+is given and its specified length in
+.Fa newlen
+is too large or too small.
+.It Bq Er ENOMEM
+The length pointed to by
+.Fa oldlenp
+is too short to hold the requested value.
+.It Bq Er ENOTDIR
+The
+.Fa name
+array specifies an intermediate rather than terminal name.
+.It Bq Er EISDIR
+The
+.Fa name
+array specifies a terminal name, but the actual name is not terminal.
+.It Bq Er EOPNOTSUPP
+The
+.Fa name
+array specifies a value that is unknown.
+.It Bq Er EPERM
+An attempt is made to set a read-only value.
+.It Bq Er EPERM
+A process without appropriate privilege attempts to set a value.
+.El
+.Sh FILES
+.Bl -tag -width <netinet/icmpXvar.h> -compact
+.It Pa <sys/sysctl.h>
+definitions for top level identifiers, second level kernel and hardware
+identifiers, and user level identifiers
+.It Pa <sys/socket.h>
+definitions for second level network identifiers
+.It Pa <sys/gmon.h>
+definitions for third level profiling identifiers
+.It Pa <vm/vm_param.h>
+definitions for second level virtual memory identifiers
+.It Pa <netinet/in.h>
+definitions for third level Internet identifiers and
+fourth level IP identifiers
+.It Pa <netinet/icmp_var.h>
+definitions for fourth level ICMP identifiers
+.It Pa <netinet/udp_var.h>
+definitions for fourth level UDP identifiers
+.El
+.Sh SEE ALSO
+.Xr sysconf 3 ,
+.Xr sysctl 8
+.Sh HISTORY
+The
+.Fn sysctl
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/gen/sysctl.c b/lib/libc/gen/sysctl.c
new file mode 100644
index 0000000..19709d5
--- /dev/null
+++ b/lib/libc/gen/sysctl.c
@@ -0,0 +1,182 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)sysctl.c 8.2 (Berkeley) 1/4/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+int
+sysctl(name, namelen, oldp, oldlenp, newp, newlen)
+ int *name;
+ u_int namelen;
+ void *oldp, *newp;
+ size_t *oldlenp, newlen;
+{
+ if (name[0] != CTL_USER)
+ return (__sysctl(name, namelen, oldp, oldlenp, newp, newlen));
+
+ if (newp != NULL) {
+ errno = EPERM;
+ return (-1);
+ }
+ if (namelen != 2) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ switch (name[1]) {
+ case USER_CS_PATH:
+ if (oldp && *oldlenp < sizeof(_PATH_STDPATH)) {
+ errno = ENOMEM;
+ return -1;
+ }
+ *oldlenp = sizeof(_PATH_STDPATH);
+ if (oldp != NULL)
+ memmove(oldp, _PATH_STDPATH, sizeof(_PATH_STDPATH));
+ return (0);
+ }
+
+ if (oldp && *oldlenp < sizeof(int)) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ *oldlenp = sizeof(int);
+ if (oldp == NULL)
+ return (0);
+
+ switch (name[1]) {
+ case USER_BC_BASE_MAX:
+ *(int *)oldp = BC_BASE_MAX;
+ return (0);
+ case USER_BC_DIM_MAX:
+ *(int *)oldp = BC_DIM_MAX;
+ return (0);
+ case USER_BC_SCALE_MAX:
+ *(int *)oldp = BC_SCALE_MAX;
+ return (0);
+ case USER_BC_STRING_MAX:
+ *(int *)oldp = BC_STRING_MAX;
+ return (0);
+ case USER_COLL_WEIGHTS_MAX:
+ *(int *)oldp = COLL_WEIGHTS_MAX;
+ return (0);
+ case USER_EXPR_NEST_MAX:
+ *(int *)oldp = EXPR_NEST_MAX;
+ return (0);
+ case USER_LINE_MAX:
+ *(int *)oldp = LINE_MAX;
+ return (0);
+ case USER_RE_DUP_MAX:
+ *(int *)oldp = RE_DUP_MAX;
+ return (0);
+ case USER_POSIX2_VERSION:
+ *(int *)oldp = _POSIX2_VERSION;
+ return (0);
+ case USER_POSIX2_C_BIND:
+#ifdef POSIX2_C_BIND
+ *(int *)oldp = 1;
+#else
+ *(int *)oldp = 0;
+#endif
+ return (0);
+ case USER_POSIX2_C_DEV:
+#ifdef POSIX2_C_DEV
+ *(int *)oldp = 1;
+#else
+ *(int *)oldp = 0;
+#endif
+ return (0);
+ case USER_POSIX2_CHAR_TERM:
+#ifdef POSIX2_CHAR_TERM
+ *(int *)oldp = 1;
+#else
+ *(int *)oldp = 0;
+#endif
+ return (0);
+ case USER_POSIX2_FORT_DEV:
+#ifdef POSIX2_FORT_DEV
+ *(int *)oldp = 1;
+#else
+ *(int *)oldp = 0;
+#endif
+ return (0);
+ case USER_POSIX2_FORT_RUN:
+#ifdef POSIX2_FORT_RUN
+ *(int *)oldp = 1;
+#else
+ *(int *)oldp = 0;
+#endif
+ return (0);
+ case USER_POSIX2_LOCALEDEF:
+#ifdef POSIX2_LOCALEDEF
+ *(int *)oldp = 1;
+#else
+ *(int *)oldp = 0;
+#endif
+ return (0);
+ case USER_POSIX2_SW_DEV:
+#ifdef POSIX2_SW_DEV
+ *(int *)oldp = 1;
+#else
+ *(int *)oldp = 0;
+#endif
+ return (0);
+ case USER_POSIX2_UPE:
+#ifdef POSIX2_UPE
+ *(int *)oldp = 1;
+#else
+ *(int *)oldp = 0;
+#endif
+ return (0);
+ case USER_STREAM_MAX:
+ *(int *)oldp = FOPEN_MAX;
+ return (0);
+ case USER_TZNAME_MAX:
+ *(int *)oldp = NAME_MAX;
+ return (0);
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+ /* NOTREACHED */
+}
diff --git a/lib/libc/gen/sysctlbyname.c b/lib/libc/gen/sysctlbyname.c
new file mode 100644
index 0000000..3d19ca2
--- /dev/null
+++ b/lib/libc/gen/sysctlbyname.c
@@ -0,0 +1,37 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <string.h>
+
+int
+sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp,
+ size_t newlen)
+{
+ int name2oid_oid[2];
+ int real_oid[CTL_MAXNAME+2];
+ int error;
+ size_t oidlen;
+
+ name2oid_oid[0] = 0; /* This is magic & undocumented! */
+ name2oid_oid[1] = 3;
+
+ oidlen = sizeof(real_oid);
+ error = sysctl(name2oid_oid, 2, real_oid, &oidlen, (void *)name,
+ strlen(name));
+ if (error < 0)
+ return error;
+ oidlen /= sizeof (int);
+ error = sysctl(real_oid, oidlen, oldp, oldlenp, newp, newlen);
+ return (error);
+}
+
diff --git a/lib/libc/gen/syslog.3 b/lib/libc/gen/syslog.3
new file mode 100644
index 0000000..437b622
--- /dev/null
+++ b/lib/libc/gen/syslog.3
@@ -0,0 +1,274 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)syslog.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SYSLOG 3
+.Os BSD 4.2
+.Sh NAME
+.Nm syslog ,
+.Nm vsyslog ,
+.Nm openlog ,
+.Nm closelog ,
+.Nm setlogmask
+.Nd control system log
+.Sh SYNOPSIS
+.Fd #include <syslog.h>
+.Fd #include <varargs.h>
+.Ft void
+.Fn syslog "int priority" "const char *message" "..."
+.Ft void
+.Fn vsyslog "int priority" "const char *message" "va_list args"
+.Ft void
+.Fn openlog "const char *ident" "int logopt" "int facility"
+.Ft void
+.Fn closelog void
+.Ft int
+.Fn setlogmask "int maskpri"
+.Sh DESCRIPTION
+The
+.Fn syslog
+function
+writes
+.Fa message
+to the system message logger.
+The message is then written to the system console, log files,
+logged-in users, or forwarded to other machines as appropriate. (See
+.Xr syslogd 8 . )
+.Pp
+The message is identical to a
+.Xr printf 3
+format string, except that
+.Ql %m
+is replaced by the current error
+message. (As denoted by the global variable
+.Va errno ;
+see
+.Xr strerror 3 . )
+A trailing newline is added if none is present.
+.Pp
+The
+.Fn vsyslog
+function
+is an alternate form in which the arguments have already been captured
+using the variable-length argument facilities of
+.Xr varargs 3 .
+.Pp
+The message is tagged with
+.Fa priority .
+Priorities are encoded as a
+.Fa facility
+and a
+.Em level .
+The facility describes the part of the system
+generating the message.
+The level is selected from the following
+.Em ordered
+(high to low) list:
+.Bl -tag -width LOG_AUTHPRIV
+.It Dv LOG_EMERG
+A panic condition.
+This is normally broadcast to all users.
+.It Dv LOG_ALERT
+A condition that should be corrected immediately, such as a corrupted
+system database.
+.It Dv LOG_CRIT
+Critical conditions, e.g., hard device errors.
+.It Dv LOG_ERR
+Errors.
+.It Dv LOG_WARNING
+Warning messages.
+.It Dv LOG_NOTICE
+Conditions that are not error conditions,
+but should possibly be handled specially.
+.It Dv LOG_INFO
+Informational messages.
+.It Dv LOG_DEBUG
+Messages that contain information
+normally of use only when debugging a program.
+.El
+.Pp
+The
+.Fn openlog
+function
+provides for more specialized processing of the messages sent
+by
+.Fn syslog
+and
+.Fn vsyslog .
+The parameter
+.Fa ident
+is a string that will be prepended to every message.
+The
+.Fa logopt
+argument
+is a bit field specifying logging options, which is formed by
+.Tn OR Ns 'ing
+one or more of the following values:
+.Bl -tag -width LOG_AUTHPRIV
+.It Dv LOG_CONS
+If
+.Fn syslog
+cannot pass the message to
+.Xr syslogd 8
+it will attempt to write the message to the console
+.Pq Dq Pa /dev/console.
+.It Dv LOG_NDELAY
+Open the connection to
+.Xr syslogd 8
+immediately.
+Normally the open is delayed until the first message is logged.
+Useful for programs that need to manage the order in which file
+descriptors are allocated.
+.It Dv LOG_PERROR
+Write the message to standard error output as well to the system log.
+.It Dv LOG_PID
+Log the process id with each message: useful for identifying
+instantiations of daemons.
+.El
+.Pp
+The
+.Fa facility
+parameter encodes a default facility to be assigned to all messages
+that do not have an explicit facility encoded:
+.Bl -tag -width LOG_AUTHPRIV
+.It Dv LOG_AUTH
+The authorization system:
+.Xr login 1 ,
+.Xr su 1 ,
+.Xr getty 8 ,
+etc.
+.It Dv LOG_AUTHPRIV
+The same as
+.Dv LOG_AUTH ,
+but logged to a file readable only by
+selected individuals.
+.It Dv LOG_CRON
+The cron daemon:
+.Xr cron 8 .
+.It Dv LOG_DAEMON
+System daemons, such as
+.Xr routed 8 ,
+that are not provided for explicitly by other facilities.
+.It Dv LOG_FTP
+The file transfer protocol daemons:
+.Xr ftpd 8 ,
+.Xr tftpd 8 .
+.It Dv LOG_KERN
+Messages generated by the kernel.
+These cannot be generated by any user processes.
+.It Dv LOG_LPR
+The line printer spooling system:
+.Xr lpr 1 ,
+.Xr lpc 8 ,
+.Xr lpd 8 ,
+etc.
+.It Dv LOG_MAIL
+The mail system.
+.It Dv LOG_NEWS
+The network news system.
+.It Dv LOG_SECURITY
+Security subsystems, such as
+.It Dv LOG_SYSLOG
+Messages generated internally by
+.Xr syslogd 8 .
+.It Dv LOG_USER
+Messages generated by random user processes.
+This is the default facility identifier if none is specified.
+.It Dv LOG_UUCP
+The uucp system.
+.Xr ipfw 4 .
+.It Dv LOG_LOCAL0
+Reserved for local use.
+Similarly for
+.Dv LOG_LOCAL1
+through
+.Dv LOG_LOCAL7 .
+.El
+.Pp
+The
+.Fn closelog
+function
+can be used to close the log file.
+.Pp
+The
+.Fn setlogmask
+function
+sets the log priority mask to
+.Fa maskpri
+and returns the previous mask.
+Calls to
+.Fn syslog
+with a priority not set in
+.Fa maskpri
+are rejected.
+The mask for an individual priority
+.Fa pri
+is calculated by the macro
+.Fn LOG_MASK pri ;
+the mask for all priorities up to and including
+.Fa toppri
+is given by the macro
+.Fn LOG_UPTO toppri ; .
+The default allows all priorities to be logged.
+.Sh RETURN VALUES
+The routines
+.Fn closelog ,
+.Fn openlog ,
+.Fn syslog
+and
+.Fn vsyslog
+return no value.
+.Pp
+The routine
+.Fn setlogmask
+always returns the previous log mask level.
+.Sh EXAMPLES
+.Bd -literal -offset indent -compact
+syslog(LOG_ALERT, "who: internal error 23");
+
+openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
+
+setlogmask(LOG_UPTO(LOG_ERR));
+
+syslog(LOG_INFO, "Connection from host %d", CallingHost);
+
+syslog(LOG_INFO|LOG_LOCAL2, "foobar error: %m");
+.Ed
+.Sh SEE ALSO
+.Xr logger 1 ,
+.Xr syslogd 8
+.Sh HISTORY
+These
+functions appeared in
+.Bx 4.2 .
diff --git a/lib/libc/gen/syslog.c b/lib/libc/gen/syslog.c
new file mode 100644
index 0000000..3a9eca4
--- /dev/null
+++ b/lib/libc/gen/syslog.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 1983, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*
+static char sccsid[] = "@(#)syslog.c 8.5 (Berkeley) 4/29/95";
+*/
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/syslog.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <netdb.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+static int LogFile = -1; /* fd for log */
+static int connected; /* have done connect */
+static int opened; /* have done openlog() */
+static int LogStat = 0; /* status bits, set by openlog() */
+static const char *LogTag = NULL; /* string to tag the entry with */
+static int LogFacility = LOG_USER; /* default facility code */
+static int LogMask = 0xff; /* mask of priorities to be logged */
+extern char *__progname; /* Program name, from crt0. */
+
+static void disconnectlog __P((void)); /* disconnect from syslogd */
+static void connectlog __P((void)); /* (re)connect to syslogd */
+
+/*
+ * Format of the magic cookie passed through the stdio hook
+ */
+struct bufcookie {
+ char *base; /* start of buffer */
+ int left;
+};
+
+/*
+ * stdio write hook for writing to a static string buffer
+ * XXX: Maybe one day, dynamically allocate it so that the line length
+ * is `unlimited'.
+ */
+static
+int writehook(cookie, buf, len)
+ void *cookie; /* really [struct bufcookie *] */
+ char *buf; /* characters to copy */
+ int len; /* length to copy */
+{
+ struct bufcookie *h; /* private `handle' */
+
+ h = (struct bufcookie *)cookie;
+ if (len > h->left) {
+ /* clip in case of wraparound */
+ len = h->left;
+ }
+ if (len > 0) {
+ (void)memcpy(h->base, buf, len); /* `write' it. */
+ h->base += len;
+ h->left -= len;
+ }
+ return 0;
+}
+
+/*
+ * syslog, vsyslog --
+ * print message on log file; output is intended for syslogd(8).
+ */
+void
+#if __STDC__
+syslog(int pri, const char *fmt, ...)
+#else
+syslog(pri, fmt, va_alist)
+ int pri;
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ vsyslog(pri, fmt, ap);
+ va_end(ap);
+}
+
+void
+vsyslog(pri, fmt, ap)
+ int pri;
+ register const char *fmt;
+ va_list ap;
+{
+ register int cnt;
+ register char ch, *p;
+ time_t now;
+ int fd, saved_errno;
+ char *stdp, tbuf[2048], fmt_cpy[1024];
+ FILE *fp, *fmt_fp;
+ struct bufcookie tbuf_cookie;
+ struct bufcookie fmt_cookie;
+
+#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
+ /* Check for invalid bits. */
+ if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
+ syslog(INTERNALLOG,
+ "syslog: unknown facility/priority: %x", pri);
+ pri &= LOG_PRIMASK|LOG_FACMASK;
+ }
+
+ /* Check priority against setlogmask values. */
+ if (!(LOG_MASK(LOG_PRI(pri)) & LogMask))
+ return;
+
+ saved_errno = errno;
+
+ /* Set default facility if none specified. */
+ if ((pri & LOG_FACMASK) == 0)
+ pri |= LogFacility;
+
+ /* Create the primary stdio hook */
+ tbuf_cookie.base = tbuf;
+ tbuf_cookie.left = sizeof(tbuf);
+ fp = fwopen(&tbuf_cookie, writehook);
+ if (fp == NULL)
+ return;
+
+ /* Build the message. */
+ (void)time(&now);
+ (void)fprintf(fp, "<%d>", pri);
+ (void)fprintf(fp, "%.15s ", ctime(&now) + 4);
+ if (LogStat & LOG_PERROR) {
+ /* Transfer to string buffer */
+ (void)fflush(fp);
+ stdp = tbuf + (sizeof(tbuf) - tbuf_cookie.left);
+ }
+ if (LogTag == NULL)
+ LogTag = __progname;
+ if (LogTag != NULL)
+ (void)fprintf(fp, "%s", LogTag);
+ if (LogStat & LOG_PID)
+ (void)fprintf(fp, "[%d]", getpid());
+ if (LogTag != NULL) {
+ (void)fprintf(fp, ": ");
+ }
+
+ /* Check to see if we can skip expanding the %m */
+ if (strstr(fmt, "%m")) {
+
+ /* Create the second stdio hook */
+ fmt_cookie.base = fmt_cpy;
+ fmt_cookie.left = sizeof(fmt_cpy) - 1;
+ fmt_fp = fwopen(&fmt_cookie, writehook);
+ if (fmt_fp == NULL) {
+ fclose(fp);
+ return;
+ }
+
+ /* Substitute error message for %m. */
+ for ( ; (ch = *fmt); ++fmt)
+ if (ch == '%' && fmt[1] == 'm') {
+ ++fmt;
+ fputs(strerror(saved_errno), fmt_fp);
+ } else
+ fputc(ch, fmt_fp);
+
+ /* Null terminate if room */
+ fputc(0, fmt_fp);
+ fclose(fmt_fp);
+
+ /* Guarantee null termination */
+ fmt_cpy[sizeof(fmt_cpy) - 1] = '\0';
+
+ fmt = fmt_cpy;
+ }
+
+ (void)vfprintf(fp, fmt, ap);
+ (void)fclose(fp);
+
+ cnt = sizeof(tbuf) - tbuf_cookie.left;
+
+ /* Output to stderr if requested. */
+ if (LogStat & LOG_PERROR) {
+ struct iovec iov[2];
+ register struct iovec *v = iov;
+
+ v->iov_base = stdp;
+ v->iov_len = cnt - (stdp - tbuf);
+ ++v;
+ v->iov_base = "\n";
+ v->iov_len = 1;
+ (void)writev(STDERR_FILENO, iov, 2);
+ }
+
+ /* Get connected, output the message to the local logger. */
+ if (!opened)
+ openlog(LogTag, LogStat | LOG_NDELAY, 0);
+ connectlog();
+ if (send(LogFile, tbuf, cnt, 0) >= 0)
+ return;
+
+ /*
+ * If the send() failed, the odds are syslogd was restarted.
+ * Make one (only) attempt to reconnect to /dev/log.
+ */
+ disconnectlog();
+ connectlog();
+ if (send(LogFile, tbuf, cnt, 0) >= 0)
+ return;
+
+ /*
+ * Output the message to the console; don't worry about blocking,
+ * if console blocks everything will. Make sure the error reported
+ * is the one from the syslogd failure.
+ */
+ if (LogStat & LOG_CONS &&
+ (fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) {
+ struct iovec iov[2];
+ register struct iovec *v = iov;
+
+ p = strchr(tbuf, '>') + 1;
+ v->iov_base = p;
+ v->iov_len = cnt - (p - tbuf);
+ ++v;
+ v->iov_base = "\r\n";
+ v->iov_len = 2;
+ (void)writev(fd, iov, 2);
+ (void)close(fd);
+ }
+}
+static void
+disconnectlog()
+{
+ /*
+ * If the user closed the FD and opened another in the same slot,
+ * that's their problem. They should close it before calling on
+ * system services.
+ */
+ if (LogFile != -1) {
+ close(LogFile);
+ LogFile = -1;
+ }
+ connected = 0; /* retry connect */
+}
+
+static void
+connectlog()
+{
+ struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */
+
+ if (LogFile == -1) {
+ if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
+ return;
+ (void)fcntl(LogFile, F_SETFD, 1);
+ }
+ if (LogFile != -1 && !connected) {
+ SyslogAddr.sun_len = sizeof(SyslogAddr);
+ SyslogAddr.sun_family = AF_UNIX;
+ (void)strncpy(SyslogAddr.sun_path, _PATH_LOG,
+ sizeof SyslogAddr.sun_path);
+ connected = connect(LogFile, (struct sockaddr *)&SyslogAddr,
+ sizeof(SyslogAddr)) != -1;
+
+ if (!connected) {
+ /*
+ * Try the old "/dev/log" path, for backward
+ * compatibility.
+ */
+ (void)strncpy(SyslogAddr.sun_path, _PATH_OLDLOG,
+ sizeof SyslogAddr.sun_path);
+ connected = connect(LogFile,
+ (struct sockaddr *)&SyslogAddr,
+ sizeof(SyslogAddr)) != -1;
+ }
+
+ if (!connected) {
+ (void)close(LogFile);
+ LogFile = -1;
+ }
+ }
+}
+
+void
+openlog(ident, logstat, logfac)
+ const char *ident;
+ int logstat, logfac;
+{
+ if (ident != NULL)
+ LogTag = ident;
+ LogStat = logstat;
+ if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
+ LogFacility = logfac;
+
+ if (LogStat & LOG_NDELAY) /* open immediately */
+ connectlog();
+
+ opened = 1; /* ident and facility has been set */
+}
+
+void
+closelog()
+{
+ (void)close(LogFile);
+ LogFile = -1;
+ connected = 0;
+}
+
+/* setlogmask -- set the log mask level */
+int
+setlogmask(pmask)
+ int pmask;
+{
+ int omask;
+
+ omask = LogMask;
+ if (pmask != 0)
+ LogMask = pmask;
+ return (omask);
+}
diff --git a/lib/libc/gen/tcgetpgrp.3 b/lib/libc/gen/tcgetpgrp.3
new file mode 100644
index 0000000..7a026b7
--- /dev/null
+++ b/lib/libc/gen/tcgetpgrp.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tcgetpgrp.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt TCGETPGRP 3
+.Os
+.Sh NAME
+.Nm tcgetpgrp
+.Nd get foreground process group ID
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <unistd.h>
+.Ft pid_t
+.Fn tcgetpgrp "int fd"
+.Sh DESCRIPTION
+The
+.Fn tcgetpgrp
+function returns the value of the process group ID of the foreground
+process group associated with the terminal device.
+If there is no foreground process group,
+.Fn tcgetpgrp
+returns an invalid process ID.
+.Sh ERRORS
+If an error occurs,
+.Fn tcgetpgrp
+returns -1 and the global variable
+.Va errno
+is set to indicate the error, as follows:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument is not a valid file descriptor.
+.It Bq Er ENOTTY
+The calling process does not have a controlling terminal or the
+underlying terminal device represented by
+.Fa fd
+is not the controlling terminal.
+.El
+.Sh SEE ALSO
+.Xr setpgid 2 ,
+.Xr setsid 2 ,
+.Xr tcsetpgrp 3
+.Sh STANDARDS
+The
+.Fn tcgetpgrp
+function is expected to be compliant with the
+.St -p1003.1-88
+specification.
diff --git a/lib/libc/gen/tcsendbreak.3 b/lib/libc/gen/tcsendbreak.3
new file mode 100644
index 0000000..6b5f754
--- /dev/null
+++ b/lib/libc/gen/tcsendbreak.3
@@ -0,0 +1,155 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tcsendbreak.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt TCSENDBREAK 3
+.Os
+.Sh NAME
+.Nm tcsendbreak ,
+.Nm tcdrain ,
+.Nm tcflush ,
+.Nm tcflow
+.Nd line control functions
+.Sh SYNOPSIS
+.Fd #include <termios.h>
+.Ft int
+.Fn tcdrain "int fd"
+.Ft int
+.Fn tcflow "int fd" "int action"
+.Ft int
+.Fn tcflush "int fd" "int action"
+.Ft int
+.Fn tcsendbreak "int fd" "int len"
+.Sh DESCRIPTION
+The
+.Fn tcdrain
+function waits until all output written to the terminal referenced by
+.Fa fd
+has been transmitted to the terminal.
+.Pp
+The
+.Fn tcflow
+function suspends transmission of data to or the reception of data from
+the terminal referenced by
+.Fa fd
+depending on the value of
+.Fa action .
+The value of
+.Fa action
+must be one of the following:
+.Bl -tag -width "TCIOFF"
+.It Fa TCOOFF
+Suspend output.
+.It Fa TCOON
+Restart suspended output.
+.It Fa TCIOFF
+Transmit a STOP character, which is intended to cause the terminal to stop
+transmitting data to the system.
+(See the description of IXOFF in the
+.Ql Input Modes
+section of
+.Xr termios 4 ).
+.It Fa TCION
+Transmit a START character, which is intended to cause the terminal to start
+transmitting data to the system.
+(See the description of IXOFF in the
+.Ql Input Modes
+section of
+.Xr termios 4 ).
+.El
+.Pp
+The
+.Fn tcflush
+function discards any data written to the terminal referenced by
+.Fa fd
+which has not been transmitted to the terminal, or any data received
+from the terminal but not yet read, depending on the value of
+.Fa action .
+The value of
+.Fa action
+must be one of the following:
+.Bl -tag -width "TCIOFLUSH"
+.It Fa TCIFLUSH
+Flush data received but not read.
+.It Fa TCOFLUSH
+Flush data written but not transmitted.
+.It Fa TCIOFLUSH
+Flush both data received but not read and data written but not transmitted.
+.El
+.Pp
+The
+.Fn tcsendbreak
+function transmits a continuous stream of zero-valued bits for four-tenths
+of a second to the terminal referenced by
+.Fa fd .
+The
+.Fa len
+parameter is ignored in this implementation.
+.Sh RETURN VALUES
+Upon successful completion, all of these functions return a value of zero.
+.Sh ERRORS
+If any error occurs, a value of -1 is returned and the global variable
+.Va errno
+is set to indicate the error, as follows:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument is not a valid file descriptor.
+.It Bq Er EINVAL
+The
+.Fa action
+argument is not a proper value.
+.It Bq Er ENOTTY
+The file associated with
+.Fa fd
+is not a terminal.
+.It Bq Er EINTR
+A signal interrupted the
+.Fn tcdrain
+function.
+.El
+.Sh SEE ALSO
+.Xr tcsetattr 3 ,
+.Xr termios 4
+.Sh STANDARDS
+The
+.Fn tcsendbreak ,
+.Fn tcdrain ,
+.Fn tcflush
+and
+.Fn tcflow
+functions are expected to be compliant with the
+.St -p1003.1-88
+specification.
diff --git a/lib/libc/gen/tcsetattr.3 b/lib/libc/gen/tcsetattr.3
new file mode 100644
index 0000000..b5c6fd9
--- /dev/null
+++ b/lib/libc/gen/tcsetattr.3
@@ -0,0 +1,331 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tcsetattr.3 8.3 (Berkeley) 1/2/94
+.\" $FreeBSD$
+.\"
+.Dd January 2, 1994
+.Dt TCSETATTR 3
+.Os
+.Sh NAME
+.Nm cfgetispeed ,
+.Nm cfsetispeed ,
+.Nm cfgetospeed ,
+.Nm cfsetospeed ,
+.Nm cfsetspeed ,
+.Nm cfmakeraw ,
+.Nm tcgetattr ,
+.Nm tcsetattr
+.Nd manipulating the termios structure
+.Sh SYNOPSIS
+.Fd #include <termios.h>
+.Ft speed_t
+.Fn cfgetispeed "const struct termios *t"
+.Ft int
+.Fn cfsetispeed "struct termios *t" "speed_t speed"
+.Ft speed_t
+.Fn cfgetospeed "const struct termios *t"
+.Ft int
+.Fn cfsetospeed "struct termios *t" "speed_t speed"
+.Ft int
+.Fn cfsetspeed "struct termios *t" "speed_t speed"
+.Ft void
+.Fn cfmakeraw "struct termios *t"
+.Ft int
+.Fn tcgetattr "int fd" "struct termios *t"
+.Ft int
+.Fn tcsetattr "int fd" "int action" "const struct termios *t"
+.Sh DESCRIPTION
+The
+.Fn cfmakeraw ,
+.Fn tcgetattr
+and
+.Fn tcsetattr
+functions are provided for getting and setting the termios structure.
+.Pp
+The
+.Fn cfgetispeed ,
+.Fn cfsetispeed ,
+.Fn cfgetospeed ,
+.Fn cfsetospeed
+and
+.Fn cfsetspeed
+functions are provided for getting and setting the baud rate values in
+the termios structure.
+The effects of the functions on the terminal as described below
+do not become effective, nor are all errors detected, until the
+.Fn tcsetattr
+function is called.
+Certain values for baud rates set in the termios structure and passed to
+.Fn tcsetattr
+have special meanings.
+These are discussed in the portion of the manual page that describes the
+.Fn tcsetattr
+function.
+.Sh GETTING AND SETTING THE BAUD RATE
+The input and output baud rates are found in the termios structure.
+The unsigned integer
+.Li speed_t
+is typdef'd in the include file
+.Aq Pa termios.h .
+The value of the integer corresponds directly to the baud rate being
+represented, however, the following symbolic values are defined.
+.Bd -literal
+#define B0 0
+#define B50 50
+#define B75 75
+#define B110 110
+#define B134 134
+#define B150 150
+#define B200 200
+#define B300 300
+#define B600 600
+#define B1200 1200
+#define B1800 1800
+#define B2400 2400
+#define B4800 4800
+#define B9600 9600
+#define B19200 19200
+#define B38400 38400
+#ifndef _POSIX_SOURCE
+#define EXTA 19200
+#define EXTB 38400
+#endif /*_POSIX_SOURCE */
+.Ed
+.Pp
+The
+.Fn cfgetispeed
+function returns the input baud rate in the termios structure referenced by
+.Fa tp .
+.Pp
+The
+.Fn cfsetispeed
+function sets the input baud rate in the termios structure referenced by
+.Fa tp
+to
+.Fa speed .
+.Pp
+The
+.Fn cfgetospeed
+function returns the output baud rate in the termios structure referenced by
+.Fa tp .
+.Pp
+The
+.Fn cfsetospeed
+function sets the output baud rate in the termios structure referenced by
+.Fa tp
+to
+.Fa speed .
+.Pp
+The
+.Fn cfsetspeed
+function sets both the input and output baud rate in the termios structure
+referenced by
+.Fa tp
+to
+.Fa speed .
+.Pp
+Upon successful completion, the functions
+.Fn cfsetispeed ,
+.Fn cfsetospeed ,
+and
+.Fn cfsetspeed
+return a value of 0.
+Otherwise, a value of -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh GETTING AND SETTING THE TERMIOS STATE
+This section describes the functions that are used to control the general
+terminal interface.
+Unless otherwise noted for a specific command, these functions are restricted
+from use by background processes.
+Attempts to perform these operations shall cause the process group to be sent
+a SIGTTOU signal.
+If the calling process is blocking or ignoring SIGTTOU signals, the process
+is allowed to perform the operation and the SIGTTOU signal is not sent.
+.Pp
+In all the functions, although
+.Fa fd
+is an open file descriptor, the functions affect the underlying terminal
+file, not just the open file description associated with the particular
+file descriptor.
+.Pp
+The
+.Fn cfmakeraw
+function sets the flags stored in the termios structure to a state disabling
+all input and output processing, giving a
+.Dq raw I/O path.
+It should be noted that there is no function to reverse this effect.
+This is because there are a variety of processing options that could be
+re-enabled and the correct method is for an application to snapshot the
+current terminal state using the function
+.Fn tcgetattr ,
+setting raw mode with
+.Fn cfmakeraw
+and the subsequent
+.Fn tcsetattr ,
+and then using another
+.Fn tcsetattr
+with the saved state to revert to the previous terminal state.
+.Pp
+The
+.Fn tcgetattr
+function copies the parameters associated with the terminal referenced
+by
+.Fa fd
+in the termios structure referenced by
+.Fa tp .
+This function is allowed from a background process, however, the terminal
+attributes may be subsequently changed by a foreground process.
+.Pp
+The
+.Fn tcsetattr
+function sets the parameters associated with the terminal from the
+termios structure referenced by
+.Fa tp .
+The
+.Fa action
+field is created by
+.Em or Ns 'ing
+the following values, as specified in the include file
+.Aq Pa termios.h .
+.Bl -tag -width "TCSADRAIN"
+.It Fa TCSANOW
+The change occurs immediately.
+.It Fa TCSADRAIN
+The change occurs after all output written to
+.Fa fd
+has been transmitted to the terminal.
+This value of
+.Fa action
+should be used when changing parameters that affect output.
+.It Fa TCSAFLUSH
+The change occurs after all output written to
+.Fa fd
+has been transmitted to the terminal.
+Additionally, any input that has been received but not read is discarded.
+.It Fa TCSASOFT
+If this value is
+.Em or Ns 'ed
+into the
+.Fa action
+value, the values of the
+.Em c_cflag ,
+.Em c_ispeed ,
+and
+.Em c_ospeed
+fields are ignored.
+.El
+.Pp
+The 0 baud rate is used to terminate the connection.
+If 0 is specified as the output speed to the function
+.Fn tcsetattr ,
+modem control will no longer be asserted on the terminal, disconnecting
+the terminal.
+.Pp
+If zero is specified as the input speed to the function
+.Fn tcsetattr ,
+the input baud rate will be set to the same value as that specified by
+the output baud rate.
+.Pp
+If
+.Fn tcsetattr
+is unable to make any of the requested changes, it returns -1 and
+sets errno.
+Otherwise, it makes all of the requested changes it can.
+If the specified input and output baud rates differ and are a combination
+that is not supported, neither baud rate is changed.
+.Pp
+Upon successful completion, the functions
+.Fn tcgetattr
+and
+.Fn tcsetattr
+return a value of 0.
+Otherwise, they
+return -1 and the global variable
+.Va errno
+is set to indicate the error, as follows:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument to
+.Fn tcgetattr
+or
+.Fn tcsetattr
+was not a valid file descriptor.
+.It Bq Er EINTR
+The
+.Fn tcsetattr
+function was interrupted by a signal.
+.It Bq Er EINVAL
+The
+.Fa action
+argument to the
+.Fn tcsetattr
+function was not valid, or an attempt was made to change an attribute
+represented in the termios structure to an unsupported value.
+.It Bq Er ENOTTY
+The file associated with the
+.Fa fd
+argument to
+.Fn tcgetattr
+or
+.Fn tcsetattr
+is not a terminal.
+.El
+.Sh SEE ALSO
+.Xr tcsendbreak 3 ,
+.Xr termios 4
+.Sh STANDARDS
+The
+.Fn cfgetispeed ,
+.Fn cfsetispeed ,
+.Fn cfgetospeed ,
+.Fn cfsetospeed ,
+.Fn tcgetattr
+and
+.Fn tcsetattr
+functions are expected to be compliant with the
+.St -p1003.1-88
+specification.
+The
+.Fn cfmakeraw
+and
+.Fn cfsetspeed
+functions,
+as well as the
+.Li TCSASOFT
+option to the
+.Fn tcsetattr
+function are extensions to the
+.St -p1003.1-88
+specification.
diff --git a/lib/libc/gen/tcsetpgrp.3 b/lib/libc/gen/tcsetpgrp.3
new file mode 100644
index 0000000..3da2cd1
--- /dev/null
+++ b/lib/libc/gen/tcsetpgrp.3
@@ -0,0 +1,101 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tcsetpgrp.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt TCSETPGRP 3
+.Os
+.Sh NAME
+.Nm tcsetpgrp
+.Nd set foreground process group ID
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <unistd.h>
+.Ft int
+.Fn tcsetpgrp "int fd" "pid_t pgrp_id"
+.Sh DESCRIPTION
+If the process has a controlling terminal, the
+.Nm tcsetpgrp
+function sets the foreground process group ID associated with the
+terminal device to
+.Fa pgrp_id .
+The terminal device associated with
+.Fa fd
+must be the controlling terminal of the calling process and the
+controlling terminal must be currently associated with the session
+of the calling process.
+The value of
+.Fa pgrp_id
+must be the same as the process group ID of a process in the same
+session as the calling process.
+.Pp
+Upon successful completion,
+.Nm tcsetpgrp
+returns a value of zero.
+.Sh ERRORS
+If an error occurs,
+.Nm tcsetpgrp
+returns -1 and the global variable
+.Va errno
+is set to indicate the error, as follows:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument is not a valid file descriptor.
+.It Bq Er EINVAL
+An invalid value of
+.Fa pgrp_id
+was specified.
+.It Bq Er ENOTTY
+The calling process does not have a controlling terminal, or the file
+represented by
+.Fa fd
+is not the controlling terminal, or the controlling terminal is no
+longer associated with the session of the calling process.
+.It Bq Er EPERM
+The
+.Fa pgrp_id
+argument does not match the process group ID of a process in the same
+session as the calling process.
+.El
+.Sh SEE ALSO
+.Xr setpgid 2 ,
+.Xr setsid 2 ,
+.Xr tcgetpgrp 3
+.Sh STANDARDS
+The
+.Nm tcsetpgprp
+function is expected to be compliant with the
+.St -p1003.1-88
+specification.
diff --git a/lib/libc/gen/telldir.c b/lib/libc/gen/telldir.c
new file mode 100644
index 0000000..ab23d9d
--- /dev/null
+++ b/lib/libc/gen/telldir.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)telldir.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * The option SINGLEUSE may be defined to say that a telldir
+ * cookie may be used only once before it is freed. This option
+ * is used to avoid having memory usage grow without bound.
+ */
+#define SINGLEUSE
+
+/*
+ * One of these structures is malloced to describe the current directory
+ * position each time telldir is called. It records the current magic
+ * cookie returned by getdirentries and the offset within the buffer
+ * associated with that return value.
+ */
+struct ddloc {
+ struct ddloc *loc_next;/* next structure in list */
+ long loc_index; /* key associated with structure */
+ long loc_seek; /* magic cookie returned by getdirentries */
+ long loc_loc; /* offset of entry in buffer */
+ const DIR* loc_dirp; /* directory which used this entry */
+};
+
+#define NDIRHASH 32 /* Num of hash lists, must be a power of 2 */
+#define LOCHASH(i) ((i)&(NDIRHASH-1))
+
+static long dd_loccnt; /* Index of entry for sequential readdir's */
+static struct ddloc *dd_hash[NDIRHASH]; /* Hash list heads for ddlocs */
+
+/*
+ * return a pointer into a directory
+ */
+long
+telldir(dirp)
+ const DIR *dirp;
+{
+ register int index;
+ register struct ddloc *lp;
+
+ if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL)
+ return (-1);
+ index = dd_loccnt++;
+ lp->loc_index = index;
+ lp->loc_seek = dirp->dd_seek;
+ lp->loc_loc = dirp->dd_loc;
+ lp->loc_dirp = dirp;
+ lp->loc_next = dd_hash[LOCHASH(index)];
+ dd_hash[LOCHASH(index)] = lp;
+ return (index);
+}
+
+/*
+ * seek to an entry in a directory.
+ * Only values returned by "telldir" should be passed to seekdir.
+ */
+void
+_seekdir(dirp, loc)
+ register DIR *dirp;
+ long loc;
+{
+ register struct ddloc *lp;
+ register struct ddloc **prevlp;
+ struct dirent *dp;
+
+ prevlp = &dd_hash[LOCHASH(loc)];
+ lp = *prevlp;
+ while (lp != NULL) {
+ if (lp->loc_index == loc)
+ break;
+ prevlp = &lp->loc_next;
+ lp = lp->loc_next;
+ }
+ if (lp == NULL)
+ return;
+ if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek)
+ goto found;
+ (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET);
+ dirp->dd_seek = lp->loc_seek;
+ dirp->dd_loc = 0;
+ while (dirp->dd_loc < lp->loc_loc) {
+ dp = readdir(dirp);
+ if (dp == NULL)
+ break;
+ }
+found:
+#ifdef SINGLEUSE
+ *prevlp = lp->loc_next;
+ free((caddr_t)lp);
+#endif
+}
+
+/*
+ * Reclaim memory for telldir cookies which weren't used.
+ */
+void
+_reclaim_telldir(dirp)
+ register const DIR *dirp;
+{
+ register struct ddloc *lp;
+ register struct ddloc **prevlp;
+ int i;
+
+ for (i = 0; i < NDIRHASH; i++) {
+ prevlp = &dd_hash[i];
+ lp = *prevlp;
+ while (lp != NULL) {
+ if (lp->loc_dirp == dirp) {
+ *prevlp = lp->loc_next;
+ free((caddr_t)lp);
+ lp = *prevlp;
+ continue;
+ }
+ prevlp = &lp->loc_next;
+ lp = lp->loc_next;
+ }
+ }
+}
diff --git a/lib/libc/gen/termios.c b/lib/libc/gen/termios.c
new file mode 100644
index 0000000..5264a2d
--- /dev/null
+++ b/lib/libc/gen/termios.c
@@ -0,0 +1,245 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)termios.c 8.2 (Berkeley) 2/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+
+#include <errno.h>
+#include <termios.h>
+#include <unistd.h>
+
+int
+tcgetattr(fd, t)
+ int fd;
+ struct termios *t;
+{
+
+ return (ioctl(fd, TIOCGETA, t));
+}
+
+int
+tcsetattr(fd, opt, t)
+ int fd, opt;
+ const struct termios *t;
+{
+ struct termios localterm;
+
+ if (opt & TCSASOFT) {
+ localterm = *t;
+ localterm.c_cflag |= CIGNORE;
+ t = &localterm;
+ }
+ switch (opt & ~TCSASOFT) {
+ case TCSANOW:
+ return (ioctl(fd, TIOCSETA, t));
+ case TCSADRAIN:
+ return (ioctl(fd, TIOCSETAW, t));
+ case TCSAFLUSH:
+ return (ioctl(fd, TIOCSETAF, t));
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+}
+
+int
+#if __STDC__
+tcsetpgrp(int fd, pid_t pgrp)
+#else
+tcsetpgrp(fd, pgrp)
+ int fd;
+ pid_t pgrp;
+#endif
+{
+ int s;
+
+ s = pgrp;
+ return (ioctl(fd, TIOCSPGRP, &s));
+}
+
+pid_t
+tcgetpgrp(fd)
+ int fd;
+{
+ int s;
+
+ if (ioctl(fd, TIOCGPGRP, &s) < 0)
+ return ((pid_t)-1);
+
+ return ((pid_t)s);
+}
+
+speed_t
+cfgetospeed(t)
+ const struct termios *t;
+{
+
+ return (t->c_ospeed);
+}
+
+speed_t
+cfgetispeed(t)
+ const struct termios *t;
+{
+
+ return (t->c_ispeed);
+}
+
+int
+cfsetospeed(t, speed)
+ struct termios *t;
+ speed_t speed;
+{
+
+ t->c_ospeed = speed;
+ return (0);
+}
+
+int
+cfsetispeed(t, speed)
+ struct termios *t;
+ speed_t speed;
+{
+
+ t->c_ispeed = speed;
+ return (0);
+}
+
+int
+cfsetspeed(t, speed)
+ struct termios *t;
+ speed_t speed;
+{
+
+ t->c_ispeed = t->c_ospeed = speed;
+ return (0);
+}
+
+/*
+ * Make a pre-existing termios structure into "raw" mode: character-at-a-time
+ * mode with no characters interpreted, 8-bit data path.
+ */
+void
+cfmakeraw(t)
+ struct termios *t;
+{
+
+ t->c_iflag &= ~(IMAXBEL|IXOFF|INPCK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IGNPAR);
+ t->c_iflag |= IGNBRK;
+ t->c_oflag &= ~OPOST;
+ t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|NOFLSH|TOSTOP|PENDIN);
+ t->c_cflag &= ~(CSIZE|PARENB);
+ t->c_cflag |= CS8|CREAD;
+ t->c_cc[VMIN] = 1;
+ t->c_cc[VTIME] = 0;
+}
+
+int
+tcsendbreak(fd, len)
+ int fd, len;
+{
+ struct timeval sleepytime;
+
+ sleepytime.tv_sec = 0;
+ sleepytime.tv_usec = 400000;
+ if (ioctl(fd, TIOCSBRK, 0) == -1)
+ return (-1);
+ (void)select(0, 0, 0, 0, &sleepytime);
+ if (ioctl(fd, TIOCCBRK, 0) == -1)
+ return (-1);
+ return (0);
+}
+
+int
+tcdrain(fd)
+ int fd;
+{
+
+ return (ioctl(fd, TIOCDRAIN, 0));
+}
+
+int
+tcflush(fd, which)
+ int fd, which;
+{
+ int com;
+
+ switch (which) {
+ case TCIFLUSH:
+ com = FREAD;
+ break;
+ case TCOFLUSH:
+ com = FWRITE;
+ break;
+ case TCIOFLUSH:
+ com = FREAD | FWRITE;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+ return (ioctl(fd, TIOCFLUSH, &com));
+}
+
+int
+tcflow(fd, action)
+ int fd, action;
+{
+ struct termios term;
+ u_char c;
+
+ switch (action) {
+ case TCOOFF:
+ return (ioctl(fd, TIOCSTOP, 0));
+ case TCOON:
+ return (ioctl(fd, TIOCSTART, 0));
+ case TCION:
+ case TCIOFF:
+ if (tcgetattr(fd, &term) == -1)
+ return (-1);
+ c = term.c_cc[action == TCIOFF ? VSTOP : VSTART];
+ if (c != _POSIX_VDISABLE && write(fd, &c, sizeof(c)) == -1)
+ return (-1);
+ return (0);
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+ /* NOTREACHED */
+}
diff --git a/lib/libc/gen/time.3 b/lib/libc/gen/time.3
new file mode 100644
index 0000000..71c1982
--- /dev/null
+++ b/lib/libc/gen/time.3
@@ -0,0 +1,86 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)time.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt TIME 3
+.Os BSD 4
+.Sh NAME
+.Nm time
+.Nd get time of day
+.Sh SYNOPSIS
+.Fd #include <time.h>
+.Ft time_t
+.Fn time "time_t *tloc"
+.Sh DESCRIPTION
+The
+.Fn time
+function
+returns the value of time in seconds since 0 hours, 0 minutes,
+0 seconds, January 1, 1970, Coordinated Universal Time.
+.Pp
+A copy of the time value may be saved to the area indicated by the
+pointer
+.Fa tloc .
+If
+.Fa tloc
+is a NULL pointer, no value is stored.
+.Pp
+Upon successful completion,
+.Fn time
+returns the value of time.
+Otherwise a value of
+.Po
+.Po Fa time_t Pc \-1
+.Pc
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The following error codes may be set in
+.Va errno :
+.Bl -tag -width [EFAULT]
+.It Bq Er EFAULT
+An argument address referenced invalid memory.
+.Sh SEE ALSO
+.Xr gettimeofday 2 ,
+.Xr ctime 3
+.Sh HISTORY
+A
+.Fn time
+function appeared in
+.At v6 .
diff --git a/lib/libc/gen/time.c b/lib/libc/gen/time.c
new file mode 100644
index 0000000..044d3a2
--- /dev/null
+++ b/lib/libc/gen/time.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)time.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+time_t
+time(t)
+ time_t *t;
+{
+ struct timeval tt;
+
+ if (gettimeofday(&tt, (struct timezone *)0) < 0)
+ return(-1);
+ if (t)
+ *t = tt.tv_sec;
+ return(tt.tv_sec);
+}
diff --git a/lib/libc/gen/times.3 b/lib/libc/gen/times.3
new file mode 100644
index 0000000..b971e2d
--- /dev/null
+++ b/lib/libc/gen/times.3
@@ -0,0 +1,138 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)times.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt TIMES 3
+.Os BSD 4
+.Sh NAME
+.Nm times
+.Nd process times
+.Sh SYNOPSIS
+.Fd #include <sys/times.h>
+.Ft clock_t
+.Fn times "struct tms *tp"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is obsoleted by getrusage(2)
+and gettimeofday(3).
+.Ef
+.Pp
+The
+.Fn times
+function returns the value of time in
+.Dv CLK_TCK Ns 's
+of a second since
+0 hours, 0 minutes, 0 seconds, January 1, 1970, Coordinated Universal
+Time.
+.Pp
+It also fills in the structure pointed to by
+.Fa tp
+with time-accounting information.
+.Pp
+The
+.Fa tms
+structure is defined as follows:
+.Bd -literal -offset indent
+typedef struct {
+ clock_t tms_utime;
+ clock_t tms_stime;
+ clock_t tms_cutime;
+ clock_t tms_cstime;
+}
+.Ed
+.Pp
+The elements of this structure are defined as follows:
+.Bl -tag -width tms_cutime
+.It Fa tms_utime
+The
+.Tn CPU
+time charged for the execution of user instructions.
+.It Fa tms_stime
+The
+.Tn CPU
+time charged for execution by the system on behalf of
+the process.
+.It Fa tms_cutime
+The sum of the
+.Fa tms_utime s
+and
+.Fa tms_cutime s
+of the child processes.
+.It Fa tms_cstime
+The sum of the
+.Fa tms_stime Ns s
+and
+.Fa tms_cstime Ns s
+of the child processes.
+.El
+.Pp
+All times are in
+.Dv CLK_TCK Ns 's
+of a second.
+.Pp
+The times of a terminated child process are included in the
+.Fa tms_cutime
+and
+.Fa tms_cstime
+elements of the parent when one of the
+.Xr wait 2
+functions returns the process ID of the terminated child to the parent.
+If an error occurs,
+.Fn times
+returns the value
+.Pq (clock_t)\-1 ,
+and sets errno to indicate the error.
+.Sh ERRORS
+The
+.Fn times
+function
+may fail and set the global variable
+.Va errno
+for any of the errors specified for the library
+routines
+.Xr getrusage 2
+and
+.Xr gettimeofday 2 .
+.Sh SEE ALSO
+.Xr time 1 ,
+.Xr getrusage 2 ,
+.Xr gettimeofday 2 ,
+.Xr wait 2 ,
+.Xr clocks 7
+.Sh STANDARDS
+The
+.Fn times
+function
+conforms to
+.St -p1003.1-88 .
diff --git a/lib/libc/gen/times.c b/lib/libc/gen/times.c
new file mode 100644
index 0000000..c145d0a
--- /dev/null
+++ b/lib/libc/gen/times.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)times.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/resource.h>
+
+/*
+ * Convert usec to clock ticks; could do (usec * CLK_TCK) / 1000000,
+ * but this would overflow if we switch to nanosec.
+ */
+#define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK))
+
+clock_t
+times(tp)
+ register struct tms *tp;
+{
+ struct rusage ru;
+ struct timeval t;
+
+ if (getrusage(RUSAGE_SELF, &ru) < 0)
+ return ((clock_t)-1);
+ tp->tms_utime = CONVTCK(ru.ru_utime);
+ tp->tms_stime = CONVTCK(ru.ru_stime);
+ if (getrusage(RUSAGE_CHILDREN, &ru) < 0)
+ return ((clock_t)-1);
+ tp->tms_cutime = CONVTCK(ru.ru_utime);
+ tp->tms_cstime = CONVTCK(ru.ru_stime);
+ if (gettimeofday(&t, (struct timezone *)0))
+ return ((clock_t)-1);
+ return ((clock_t)(CONVTCK(t)));
+}
diff --git a/lib/libc/gen/timezone.3 b/lib/libc/gen/timezone.3
new file mode 100644
index 0000000..7468aa4
--- /dev/null
+++ b/lib/libc/gen/timezone.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)timezone.3 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt TIMEZONE 3
+.Os
+.Sh NAME
+.Nm timezone
+.Nd return the timezone abbreviation
+.Sh SYNOPSIS
+.Ft char *
+.Fn timezone "int zone" "int dst"
+.Sh DESCRIPTION
+.ft B
+This interface is for compatibility only; it is impossible to reliably
+map timezone's arguments to a time zone abbreviation.
+See ctime(3).
+.ft P
+.Pp
+The
+.Fn timezone
+function returns a pointer to a time zone abbreviation for the specified
+.Ar zone
+and
+.Ar dst
+values.
+.Ar Zone
+is the number of minutes west of GMT and
+.Ar dst
+is non-zero if daylight savings time is in effect.
+.Sh SEE ALSO
+.Xr ctime 3
+.Sh HISTORY
+A
+.Fn timezone
+function appeared in
+.At v7 .
diff --git a/lib/libc/gen/timezone.c b/lib/libc/gen/timezone.c
new file mode 100644
index 0000000..74086ef
--- /dev/null
+++ b/lib/libc/gen/timezone.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)timezone.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define TZ_MAX_CHARS 255
+
+char *_tztab();
+
+/*
+ * timezone --
+ * The arguments are the number of minutes of time you are westward
+ * from Greenwich and whether DST is in effect. It returns a string
+ * giving the name of the local timezone. Should be replaced, in the
+ * application code, by a call to localtime.
+ */
+
+static char czone[TZ_MAX_CHARS]; /* space for zone name */
+
+char *
+timezone(zone, dst)
+ int zone,
+ dst;
+{
+ register char *beg,
+ *end;
+
+ if ( (beg = getenv("TZNAME")) ) { /* set in environment */
+ if ( (end = index(beg, ',')) ) {/* "PST,PDT" */
+ if (dst)
+ return(++end);
+ *end = '\0';
+ (void)strncpy(czone,beg,sizeof(czone) - 1);
+ czone[sizeof(czone) - 1] = '\0';
+ *end = ',';
+ return(czone);
+ }
+ return(beg);
+ }
+ return(_tztab(zone,dst)); /* default: table or created zone */
+}
+
+static struct zone {
+ int offset;
+ char *stdzone;
+ char *dlzone;
+} zonetab[] = {
+ {-1*60, "MET", "MET DST"}, /* Middle European */
+ {-2*60, "EET", "EET DST"}, /* Eastern European */
+ {4*60, "AST", "ADT"}, /* Atlantic */
+ {5*60, "EST", "EDT"}, /* Eastern */
+ {6*60, "CST", "CDT"}, /* Central */
+ {7*60, "MST", "MDT"}, /* Mountain */
+ {8*60, "PST", "PDT"}, /* Pacific */
+#ifdef notdef
+ /* there's no way to distinguish this from WET */
+ {0, "GMT", 0}, /* Greenwich */
+#endif
+ {0*60, "WET", "WET DST"}, /* Western European */
+ {-10*60,"EST", "EST"}, /* Aust: Eastern */
+ {-10*60+30,"CST", "CST"}, /* Aust: Central */
+ {-8*60, "WST", 0}, /* Aust: Western */
+ {-1}
+};
+
+/*
+ * _tztab --
+ * check static tables or create a new zone name; broken out so that
+ * we can make a guess as to what the zone is if the standard tables
+ * aren't in place in /etc. DO NOT USE THIS ROUTINE OUTSIDE OF THE
+ * STANDARD LIBRARY.
+ */
+char *
+_tztab(zone,dst)
+ register int zone;
+ int dst;
+{
+ register struct zone *zp;
+ register char sign;
+
+ for (zp = zonetab; zp->offset != -1;++zp) /* static tables */
+ if (zp->offset == zone) {
+ if (dst && zp->dlzone)
+ return(zp->dlzone);
+ if (!dst && zp->stdzone)
+ return(zp->stdzone);
+ }
+
+ if (zone < 0) { /* create one */
+ zone = -zone;
+ sign = '+';
+ }
+ else
+ sign = '-';
+ (void)snprintf(czone, sizeof(czone),
+ "GMT%c%d:%02d",sign,zone / 60,zone % 60);
+ return(czone);
+}
diff --git a/lib/libc/gen/ttyname.3 b/lib/libc/gen/ttyname.3
new file mode 100644
index 0000000..719b9fb
--- /dev/null
+++ b/lib/libc/gen/ttyname.3
@@ -0,0 +1,127 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ttyname.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt TTYNAME 3
+.Os
+.Sh NAME
+.Nm ttyname ,
+.Nm isatty ,
+.Nm ttyslot
+.Nd get name of associated terminal (tty) from file descriptor
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft char *
+.Fn ttyname "int fd"
+.Ft int
+.Fn isatty "int fd"
+.Ft int
+.Fn ttyslot void
+.Sh DESCRIPTION
+These functions operate on the system file descriptors for terminal
+type devices. These descriptors are not related to the standard
+.Tn I/O
+.Dv FILE
+typedef, but refer to the special device files found in
+.Pa /dev
+and named
+.Pa /dev/tty Ns Em xx
+and for which an entry exists
+in the initialization file
+.Pa /etc/ttys.
+(See
+.Xr ttys 5 . )
+.Pp
+The
+.Fn isatty
+function
+determines if the file descriptor
+.Fa fd
+refers to a valid
+terminal type device.
+.Pp
+The
+.Fn ttyname
+function
+gets the related device name of
+a file descriptor for which
+.Fn isatty
+is true
+.Pp
+The
+.Fn ttyslot
+function
+fetches the current process' control terminal number from the
+.Xr ttys 5
+file entry.
+.Sh RETURN VALUES
+The
+.Fn ttyname
+function
+returns the null terminated name if the device is found and
+.Fn isatty
+is true; otherwise
+a
+.Dv NULL
+pointer is returned.
+.Pp
+The
+.Fn ttyslot
+function
+returns the unit number of the device file if found; otherwise
+the value zero is returned.
+.Sh FILES
+.Bl -tag -width /etc/ttys -compact
+.It Pa /dev/\(**
+.It Pa /etc/ttys
+.El
+.Sh SEE ALSO
+.Xr ioctl 2 ,
+.Xr ttys 5
+.Sh HISTORY
+A
+.Fn isatty ,
+.Fn ttyname ,
+and
+.Fn ttyslot
+function
+appeared in
+.At v7 .
+.Sh BUGS
+The
+.Fn ttyname
+function leaves its result in an internal static object and returns
+a pointer to that object. Subsequent calls to
+.Fn ttyname
+will modify the same object.
diff --git a/lib/libc/gen/ttyname.c b/lib/libc/gen/ttyname.c
new file mode 100644
index 0000000..cb01870
--- /dev/null
+++ b/lib/libc/gen/ttyname.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ttyname.c 8.2 (Berkeley) 1/27/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+#include <db.h>
+#include <string.h>
+#include <paths.h>
+
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+static struct pthread_mutex _ttyname_lockd = PTHREAD_MUTEX_STATIC_INITIALIZER;
+static pthread_mutex_t ttyname_lock = &_ttyname_lockd;
+static pthread_key_t ttyname_key;
+static int ttyname_init = 0;
+
+char *
+ttyname(int fd)
+{
+ char *ret;
+
+ if (_FD_LOCK(fd, FD_READ, NULL) == 0) {
+ ret = __ttyname_basic(fd);
+ _FD_UNLOCK(fd, FD_READ);
+ } else {
+ ret = NULL;
+ }
+
+ return (ret);
+}
+
+char *
+__ttyname_r_basic(int fd, char *buf, size_t len)
+{
+ register struct dirent *dirp;
+ register DIR *dp;
+ struct stat dsb;
+ struct stat sb;
+ char *rval;
+ int minlen;
+
+ rval = NULL;
+
+ /* Must be a terminal. */
+ if (!isatty(fd))
+ return (rval);
+ /* Must be a character device. */
+ if (_thread_sys_fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
+ return (rval);
+ /* Must have enough room */
+ if (len <= sizeof(_PATH_DEV))
+ return (rval);
+
+ if ((dp = opendir(_PATH_DEV)) != NULL) {
+ memcpy(buf, _PATH_DEV, sizeof(_PATH_DEV));
+ for (rval = NULL; (dirp = readdir(dp)) != NULL;) {
+ if (dirp->d_fileno != sb.st_ino)
+ continue;
+ minlen = (len - (sizeof(_PATH_DEV) - 1)) < (dirp->d_namlen + 1) ?
+ (len - (sizeof(_PATH_DEV) - 1)) : (dirp->d_namlen + 1);
+ memcpy(buf + sizeof(_PATH_DEV) - 1, dirp->d_name, minlen);
+ if (stat(buf, &dsb) || sb.st_dev != dsb.st_dev ||
+ sb.st_ino != dsb.st_ino)
+ continue;
+ rval = buf;
+ break;
+ }
+ (void) closedir(dp);
+ }
+ return (rval);
+}
+
+char *
+__ttyname_basic(int fd)
+{
+ char *buf;
+
+ pthread_mutex_lock(&ttyname_lock);
+ if (ttyname_init == 0) {
+ if (pthread_key_create(&ttyname_key, free)) {
+ pthread_mutex_unlock(&ttyname_lock);
+ return (NULL);
+ }
+ ttyname_init = 1;
+ }
+ pthread_mutex_unlock(&ttyname_lock);
+
+ /* Must have thread specific data field to put data */
+ if ((buf = pthread_getspecific(ttyname_key)) == NULL) {
+ if ((buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN)) != NULL) {
+ if (pthread_setspecific(ttyname_key, buf) != 0) {
+ free(buf);
+ return (NULL);
+ }
+ } else {
+ return (NULL);
+ }
+ }
+ return (__ttyname_r_basic(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN));
+}
+
+char *
+ttyname_r(int fd, char *buf, size_t len)
+{
+ char *ret;
+
+ if (_FD_LOCK(fd, FD_READ, NULL) == 0) {
+ ret = __ttyname_r_basic(fd, buf, len);
+ _FD_UNLOCK(fd, FD_READ);
+ } else {
+ ret = NULL;
+ }
+ return (ret);
+}
+#else
+static char buf[sizeof(_PATH_DEV) + MAXNAMLEN] = _PATH_DEV;
+static char *oldttyname __P((int, struct stat *));
+
+char *
+ttyname(fd)
+ int fd;
+{
+ struct stat sb;
+ struct termios ttyb;
+ DB *db;
+ DBT data, key;
+ struct {
+ mode_t type;
+ dev_t dev;
+ } bkey;
+
+ /* Must be a terminal. */
+ if (tcgetattr(fd, &ttyb) < 0)
+ return (NULL);
+ /* Must be a character device. */
+ if (fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
+ return (NULL);
+
+ if ( (db = dbopen(_PATH_DEVDB, O_RDONLY, 0, DB_HASH, NULL)) ) {
+ memset(&bkey, 0, sizeof(bkey));
+ bkey.type = S_IFCHR;
+ bkey.dev = sb.st_rdev;
+ key.data = &bkey;
+ key.size = sizeof(bkey);
+ if (!(db->get)(db, &key, &data, 0)) {
+ bcopy(data.data,
+ buf + sizeof(_PATH_DEV) - 1, data.size);
+ (void)(db->close)(db);
+ return (buf);
+ }
+ (void)(db->close)(db);
+ }
+ return (oldttyname(fd, &sb));
+}
+
+static char *
+oldttyname(fd, sb)
+ int fd;
+ struct stat *sb;
+{
+ register struct dirent *dirp;
+ register DIR *dp;
+ struct stat dsb;
+
+ if ((dp = opendir(_PATH_DEV)) == NULL)
+ return (NULL);
+
+ while ( (dirp = readdir(dp)) ) {
+ if (dirp->d_fileno != sb->st_ino)
+ continue;
+ bcopy(dirp->d_name, buf + sizeof(_PATH_DEV) - 1,
+ dirp->d_namlen + 1);
+ if (stat(buf, &dsb) || sb->st_dev != dsb.st_dev ||
+ sb->st_ino != dsb.st_ino)
+ continue;
+ (void)closedir(dp);
+ return (buf);
+ }
+ (void)closedir(dp);
+ return (NULL);
+}
+#endif
diff --git a/lib/libc/gen/ttyslot.c b/lib/libc/gen/ttyslot.c
new file mode 100644
index 0000000..2f72ebb
--- /dev/null
+++ b/lib/libc/gen/ttyslot.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ttyslot.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ttyent.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+int
+ttyslot()
+{
+ register struct ttyent *ttyp;
+ register int slot;
+ register char *p;
+ int cnt;
+ char *name;
+
+ setttyent();
+ for (cnt = 0; cnt < 3; ++cnt)
+ if ( (name = ttyname(cnt)) ) {
+ if ( (p = rindex(name, '/')) )
+ ++p;
+ else
+ p = name;
+ for (slot = 1; (ttyp = getttyent()); ++slot)
+ if (!strcmp(ttyp->ty_name, p)) {
+ endttyent();
+ return(slot);
+ }
+ break;
+ }
+ endttyent();
+ return(0);
+}
diff --git a/lib/libc/gen/tzset.3 b/lib/libc/gen/tzset.3
new file mode 100644
index 0000000..853a1da
--- /dev/null
+++ b/lib/libc/gen/tzset.3
@@ -0,0 +1,326 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Arthur Olson.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tzset.3 8.2 (Berkeley) 11/17/93
+.\" $FreeBSD$
+.\"
+.Dd November 17, 1993
+.Dt TZSET 3
+.Os
+.Sh NAME
+.Nm tzset ,
+.Nm tzsetwall
+.Nd initialize time conversion information
+.Sh SYNOPSIS
+.Fd #include <time.h>
+.Ft void
+.Fn tzset void
+.Ft void
+.Fn tzsetwall void
+.Sh DESCRIPTION
+The
+.Fn tzset
+function
+initializes time conversion information used by the library routine
+.Xr localtime 3 .
+The environment variable
+.Ev TZ
+specifies how this is done.
+.Pp
+If
+.Ev TZ
+does not appear in the environment, the best available approximation to
+local wall clock time, as specified by the
+.Xr tzfile 5 Ns -format
+file
+.Pa /etc/localtime
+is used.
+.Pp
+If
+.Ev TZ
+appears in the environment but its value is a null string, Coordinated
+Universal Time
+.Pq Tn UTC
+is used (without leap second correction).
+.Pp
+If
+.Ev TZ
+appears in the environment and its value begins with a colon
+.Pq Ql \: ,
+the rest of its value is used as a pathname of a
+.Xr tzfile 5 Ns -format
+file from which to read the time conversion information.
+If the first character of the pathname is a slash
+.Pq Ql /
+it is used as
+an absolute pathname; otherwise, it is used as a pathname relative to
+the system time conversion information directory.
+.Pp
+If its value does not begin with a colon, it is first used as the pathname
+of a file (as described above) from which to read the time conversion
+information.
+If that file cannot be read, the value is then interpreted as a direct
+specification (the format is described below) of the time conversion
+information.
+.Pp
+If the
+.Ev TZ
+environment variable does not specify a
+.Xr tzfile 5 Ns -format
+file and cannot be interpreted as a direct specification,
+.Tn UTC
+is used.
+.Pp
+The
+.Fn tzsetwall
+function
+sets things up so that
+.Xr localtime
+returns the best available approximation of local wall clock time.
+.Sh SPECIFICATION FORMAT
+When
+.Ev TZ
+is used directly as a specification of the time conversion information,
+it must have the following syntax (spaces inserted for clarity):
+.Bd -filled -offset indent
+.Em std offset Bo
+.Em dst Bo
+.Em offset
+.Bc
+.Bo
+.No , Em rule
+.Bc
+.Bc
+.Ed
+.Pp
+Where:
+.Bl -tag -width std_and_dst -offset indent
+.It Em std No and Em dst
+Three or more bytes that are the designation for the standard
+.Pq Em std
+or summer
+.Pq Em dst
+time zone. Only
+.Em std
+is required; if
+.Em dst
+is missing, then summer time does not apply in this locale.
+Upper and lowercase letters are explicitly allowed. Any characters
+except a leading colon
+.Pq Ql \: ,
+digits, comma
+.Pq Ql \&, ,
+minus
+.Pq Ql \- ,
+plus
+.Pq Ql + ,
+and
+.Tn ASCII
+.Dv NUL
+are allowed.
+.It Em offset
+Indicates the value one must add to the local time to arrive at
+Coordinated Universal Time. The
+.Em offset
+has the form:
+.Bd -unfilled -offset indent
+.Em hh Bo
+.Pf \&: Em mm
+.Bo
+.Pf \&: Em ss
+.Bc
+.Bc
+.Ed
+.Pp
+The minutes
+.Pq Em mm
+and seconds
+.Pq Em ss
+are optional. The hour
+.Pq Em hh
+is required and may be a single digit. The
+.Em offset
+following
+.Em std
+is required. If no
+.Em offset
+follows
+.Em dst ,
+summer time is assumed to be one hour ahead of standard time. One or
+more digits may be used; the value is always interpreted as a decimal
+number. The hour must be between zero and 24, and the minutes (and
+seconds) \(em if present \(em between zero and 59. If preceded by a
+.Pq Ql \-
+the time zone shall be east of the Prime Meridian; otherwise it shall be
+west (which may be indicated by an optional preceding
+.Pq Ql + ) .
+.It Em rule
+Indicates when to change to and back from summer time. The
+.Em rule
+has the form:
+.Bd -filled -offset indent
+.Em date/time,date/time
+.Ed
+.Pp
+where the first
+.Em date
+describes when the change from standard to summer time occurs and the
+second
+.Em date
+describes when the change back happens. Each
+.Em time
+field describes when, in current local time, the change to the other
+time is made.
+.Pp
+The format of
+.Em date
+is one of the following:
+.Bl -tag -width "M.m.n.d"
+.It Sy J Em n
+The Julian day
+.Em n
+(1 \*(Le
+.Em n
+\*(Le 365).
+Leap days are not counted; that is, in all years \(em including leap
+years \(em February 28 is day 59 and March 1 is day 60. It is
+impossible to explicitly refer to the occasional February 29.
+.It Em n
+The zero-based Julian day
+(0 \*(Le
+.Em n
+\*(Le 365 ) .
+Leap days are counted, and it is possible to refer to February 29.
+.It Sy M Em m.n.d
+The
+.Em d Ns 'th
+day (0 \*(Le
+.Em d
+\*(Le 6 )
+of week
+.Em n
+of month
+.Em m
+of the year
+(1 \*(Le
+.Em n
+\*(Le 5),
+(1 \*(Le
+.Em m
+\*(Le 12),
+where week 5 means
+.Do
+the last
+.Em d
+day in month
+.Em m
+.Dc
+which may occur in either the fourth or the fifth week). Week 1 is the
+first week in which the
+.Em d Ns 'th
+day occurs. Day zero is Sunday.
+.Pp
+The
+.Em time
+has the same format as
+.Em offset
+except that no leading sign
+.Pq Ql \-
+or
+.Pq Ql +
+is allowed. The default, if
+.Em time
+is not given, is
+.Sy 02:00:00 .
+.El
+.Pp
+If no
+.Em rule
+is present in the
+.Ev TZ
+specification, the rules specified
+by the
+.Xr tzfile 5 Ns -format
+file
+.Em posixrules
+in the system time conversion information directory are used, with the
+standard and summer time offsets from
+.Tn UTC
+replaced by those specified by
+the
+.Em offset
+values in
+.Ev TZ .
+.El
+.Pp
+For compatibility with System V Release 3.1, a semicolon
+.Pq Ql \;
+may be used to separate the
+.Em rule
+from the rest of the specification.
+.Sh FILES
+.Bl -tag -width /usr/share/zoneinfo/posixrules -compact
+.It Pa /etc/localtime
+local time zone file
+.It Pa /usr/share/zoneinfo
+time zone directory
+.It Pa /usr/share/zoneinfo/posixrules
+rules for
+.Tn POSIX Ns -style
+.Tn TZ Ns 's
+.It Pa /usr/share/zoneinfo/GMT for
+.Tn UTC
+leap seconds
+.El
+.Pp
+If the file
+.Pa /usr/share/zoneinfo/GMT
+does not exist,
+.Tn UTC
+leap seconds are loaded from
+.Pa /usr/share/zoneinfo/posixrules .
+.Sh SEE ALSO
+.Xr date 1 ,
+.Xr gettimeofday 2 ,
+.Xr ctime 3 ,
+.Xr getenv 3 ,
+.Xr time 3 ,
+.Xr tzfile 5
+.Sh HISTORY
+The
+.Fn tzset
+and
+.Fn tzsetwall
+functions first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/gen/ualarm.3 b/lib/libc/gen/ualarm.3
new file mode 100644
index 0000000..bbf9457
--- /dev/null
+++ b/lib/libc/gen/ualarm.3
@@ -0,0 +1,99 @@
+.\" Copyright (c) 1986, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)ualarm.3 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt UALARM 3
+.Os BSD 4.3
+.Sh NAME
+.Nm ualarm
+.Nd schedule signal after specified time
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft u_int
+.Fn ualarm "u_int microseconds" "u_int interval"
+.Sh DESCRIPTION
+.Bf -symbolic
+This is a simplified interface to setitimer(2).
+.Ef
+.Pp
+The
+.Fn ualarm
+function
+waits a count of
+.Ar microseconds
+before asserting the terminating signal
+.Dv SIGALRM .
+System activity or time used in processing the call may cause a slight
+delay.
+.Pp
+If the
+.Fa interval
+argument is non-zero, the
+.Dv SIGALRM
+signal will be sent
+to the process every
+.Fa interval
+microseconds after the timer expires (e.g. after
+.Fa value
+microseconds have passed).
+.Pp
+Due to
+.Xr setitimer 2
+restriction the maximum number of
+.Ar microseconds
+and
+.Ar interval
+is limited to 100000000000000
+(in case this value fit in the unsigned integer).
+.Sh RETURN VALUES
+When the signal has successfully been caught,
+.Fn ualarm
+returns the amount of time left on the clock.
+.Sh NOTES
+.Pp
+A microsecond is 0.000001 seconds.
+.Sh SEE ALSO
+.Xr getitimer 2 ,
+.Xr setitimer 2 ,
+.Xr sigpause 2 ,
+.Xr sigvec 2 ,
+.Xr alarm 3 ,
+.Xr signal 3 ,
+.Xr sleep 3 ,
+.Xr usleep 3
+.Sh HISTORY
+The
+.Fn ualarm
+function appeared in
+.Bx 4.3 .
diff --git a/lib/libc/gen/ualarm.c b/lib/libc/gen/ualarm.c
new file mode 100644
index 0000000..ec49a2d
--- /dev/null
+++ b/lib/libc/gen/ualarm.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ualarm.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/time.h>
+#include <unistd.h>
+
+#define USPS 1000000 /* # of microseconds in a second */
+
+/*
+ * Generate a SIGALRM signal in ``usecs'' microseconds.
+ * If ``reload'' is non-zero, keep generating SIGALRM
+ * every ``reload'' microseconds after the first signal.
+ */
+unsigned
+ualarm(usecs, reload)
+ register unsigned usecs;
+ register unsigned reload;
+{
+ struct itimerval new, old;
+
+ new.it_interval.tv_usec = reload % USPS;
+ new.it_interval.tv_sec = reload / USPS;
+
+ new.it_value.tv_usec = usecs % USPS;
+ new.it_value.tv_sec = usecs / USPS;
+
+ if (setitimer(ITIMER_REAL, &new, &old) == 0)
+ return (old.it_value.tv_sec * USPS + old.it_value.tv_usec);
+ /* else */
+ return (-1);
+}
diff --git a/lib/libc/gen/uname.3 b/lib/libc/gen/uname.3
new file mode 100644
index 0000000..6a3aef6
--- /dev/null
+++ b/lib/libc/gen/uname.3
@@ -0,0 +1,94 @@
+.\" Copyright (c) 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)uname.3 8.1 (Berkeley) 1/4/94
+.\" $FreeBSD$
+.\"
+.Dd January 4, 1994
+.Dt UNAME 3
+.Os
+.Sh NAME
+.Nm uname
+.Nd get system identification
+.Sh SYNOPSIS
+.Fd #include <sys/utsname.h>
+.Ft int
+.Fn uname "struct utsname *name"
+.Sh DESCRIPTION
+The
+.Fn uname
+function stores nul-terminated strings of information identifying
+the current system into the structure referenced by
+.Fa name .
+.Pp
+The
+.Li utsname
+structure is defined in the
+.Li <sys/utsname.h>
+header file, and contains the following members:
+.Bl -tag -width nodenameXXXX -offset indent
+.It sysname
+Name of the operating system implementation.
+.It nodename
+Network name of this machine.
+.It release
+Release level of the operating system.
+.It version
+Version level of the operating system.
+.It machine
+Machine hardware platform.
+.El
+.Sh RETURN VALUES
+If
+.Fn uname
+is successful, 0 is returned, otherwise, -1 is returned and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+The
+.Fn uname
+function may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr sysctl 3 .
+.Sh SEE ALSO
+.Xr uname 1 ,
+.Xr sysctl 3
+.Sh STANDARDS
+The
+.Fn uname
+function conforms to
+.St -p1003.1-88 .
+.Sh HISTORY
+The
+.Fn uname
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/gen/uname.c b/lib/libc/gen/uname.c
new file mode 100644
index 0000000..944c2dc
--- /dev/null
+++ b/lib/libc/gen/uname.c
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char sccsid[] = "From: @(#)uname.c 8.1 (Berkeley) 1/4/94";*/
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/utsname.h>
+#include <errno.h>
+
+int
+uname(name)
+ struct utsname *name;
+{
+ int mib[2], rval;
+ size_t len;
+ char *p;
+ int oerrno;
+
+ rval = 0;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_OSTYPE;
+ len = sizeof(name->sysname);
+ oerrno = errno;
+ if (sysctl(mib, 2, &name->sysname, &len, NULL, 0) == -1) {
+ if(errno == ENOMEM)
+ errno = oerrno;
+ else
+ rval = -1;
+ }
+ name->sysname[sizeof(name->sysname) - 1] = '\0';
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_HOSTNAME;
+ len = sizeof(name->nodename);
+ oerrno = errno;
+ if (sysctl(mib, 2, &name->nodename, &len, NULL, 0) == -1) {
+ if(errno == ENOMEM)
+ errno = oerrno;
+ else
+ rval = -1;
+ }
+ name->nodename[sizeof(name->nodename) - 1] = '\0';
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_OSRELEASE;
+ len = sizeof(name->release);
+ oerrno = errno;
+ if (sysctl(mib, 2, &name->release, &len, NULL, 0) == -1) {
+ if(errno == ENOMEM)
+ errno = oerrno;
+ else
+ rval = -1;
+ }
+ name->release[sizeof(name->release) - 1] = '\0';
+
+ /* The version may have newlines in it, turn them into spaces. */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_VERSION;
+ len = sizeof(name->version);
+ oerrno = errno;
+ if (sysctl(mib, 2, &name->version, &len, NULL, 0) == -1) {
+ if (errno == ENOMEM)
+ errno = oerrno;
+ else
+ rval = -1;
+ }
+ name->version[sizeof(name->version) - 1] = '\0';
+ for (p = name->version; len--; ++p) {
+ if (*p == '\n' || *p == '\t') {
+ if (len > 1)
+ *p = ' ';
+ else
+ *p = '\0';
+ }
+ }
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_MACHINE;
+ len = sizeof(name->machine);
+ oerrno = errno;
+ if (sysctl(mib, 2, &name->machine, &len, NULL, 0) == -1) {
+ if (errno == ENOMEM)
+ errno = oerrno;
+ else
+ rval = -1;
+ }
+ name->machine[sizeof(name->machine) - 1] = '\0';
+ return (rval);
+}
diff --git a/lib/libc/gen/unvis.3 b/lib/libc/gen/unvis.3
new file mode 100644
index 0000000..16734d1
--- /dev/null
+++ b/lib/libc/gen/unvis.3
@@ -0,0 +1,164 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)unvis.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt UNVIS 3
+.Os
+.Sh NAME
+.Nm unvis ,
+.Nm strunvis
+.Nd decode a visual representation of characters
+.Sh SYNOPSIS
+.Fd #include <vis.h>
+.Ft int
+.Fn unvis "char *cp" "int c" "int *astate" "int flag"
+.Ft int
+.Fn strunvis "char *dst" "const char *src"
+.Sh DESCRIPTION
+The
+.Fn unvis
+and
+.Fn strunvis
+functions
+are used to decode a visual representation of characters, as produced
+by the
+.Xr vis 3
+function, back into
+the original form. Unvis is called with successive characters in
+.Ar c
+until a valid
+sequence is recognized, at which time the decoded character is
+available at the character pointed to by
+.Ar cp .
+Strunvis decodes the
+characters pointed to by
+.Ar src
+into the buffer pointed to by
+.Ar dst .
+.Pp
+The
+.Fn strunvis
+function
+simply copies
+.Ar src
+to
+.Ar dst ,
+decoding any escape sequences along the way,
+and returns the number of characters placed into
+.Ar dst ,
+or \-1 if an
+invalid escape sequence was detected. The size of
+.Ar dst
+should be
+equal to the size of
+.Ar src
+(that is, no expansion takes place during
+decoding).
+.Pp
+The
+.Fn unvis
+function
+implements a state machine that can be used to decode an arbitrary
+stream of bytes. All state associated with the bytes being decoded
+is stored outside the
+.Fn unvis
+function (that is, a pointer to the state is passed in), so
+calls decoding different streams can be freely intermixed. To
+start decoding a stream of bytes, first initialize an integer
+to zero. Call
+.Fn unvis
+with each successive byte, along with a pointer
+to this integer, and a pointer to a destination character.
+The
+.Fn unvis
+function
+has several return codes that must be handled properly. They are:
+.Bl -tag -width UNVIS_VALIDPUSH
+.It Li \&0 (zero)
+Another character is necessary; nothing has been recognized yet.
+.It Dv UNVIS_VALID
+A valid character has been recognized and is available at the location
+pointed to by cp.
+.It Dv UNVIS_VALIDPUSH
+A valid character has been recognized and is available at the location
+pointed to by cp; however, the character currently passed in should
+be passed in again.
+.It Dv UNVIS_NOCHAR
+A valid sequence was detected, but no character was produced. This
+return code is necessary to indicate a logical break between characters.
+.It Dv UNVIS_SYNBAD
+An invalid escape sequence was detected, or the decoder is in an
+unknown state. The decoder is placed into the starting state.
+.El
+.Pp
+When all bytes in the stream have been processed, call
+.Fn unvis
+one more time with flag set to
+.Dv UNVIS_END
+to extract any remaining character (the character passed in is ignored).
+.Pp
+The following code fragment illustrates a proper use of
+.Fn unvis .
+.Bd -literal -offset indent
+int state = 0;
+char out;
+
+while ((ch = getchar()) != EOF) {
+again:
+ switch(unvis(&out, ch, &state, 0)) {
+ case 0:
+ case UNVIS_NOCHAR:
+ break;
+ case UNVIS_VALID:
+ (void) putchar(out);
+ break;
+ case UNVIS_VALIDPUSH:
+ (void) putchar(out);
+ goto again;
+ case UNVIS_SYNBAD:
+ (void)fprintf(stderr, "bad sequence!\n");
+ exit(1);
+ }
+}
+if (unvis(&out, (char)0, &state, UNVIS_END) == UNVIS_VALID)
+ (void) putchar(out);
+.Ed
+.Sh SEE ALSO
+.Xr vis 1
+.Sh HISTORY
+The
+.Nm unvis
+function
+first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/gen/unvis.c b/lib/libc/gen/unvis.c
new file mode 100644
index 0000000..32405df
--- /dev/null
+++ b/lib/libc/gen/unvis.c
@@ -0,0 +1,247 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <vis.h>
+
+/*
+ * decode driven by state machine
+ */
+#define S_GROUND 0 /* haven't seen escape char */
+#define S_START 1 /* start decoding special sequence */
+#define S_META 2 /* metachar started (M) */
+#define S_META1 3 /* metachar more, regular char (-) */
+#define S_CTRL 4 /* control char started (^) */
+#define S_OCTAL2 5 /* octal digit 2 */
+#define S_OCTAL3 6 /* octal digit 3 */
+
+#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
+
+/*
+ * unvis - decode characters previously encoded by vis
+ */
+int
+unvis(cp, c, astate, flag)
+ char *cp;
+ int c, *astate, flag;
+{
+
+ if (flag & UNVIS_END) {
+ if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ }
+ return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
+ }
+
+ switch (*astate) {
+
+ case S_GROUND:
+ *cp = 0;
+ if (c == '\\') {
+ *astate = S_START;
+ return (0);
+ }
+ *cp = c;
+ return (UNVIS_VALID);
+
+ case S_START:
+ switch(c) {
+ case '\\':
+ *cp = c;
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ *cp = (c - '0');
+ *astate = S_OCTAL2;
+ return (0);
+ case 'M':
+ *cp = 0200;
+ *astate = S_META;
+ return (0);
+ case '^':
+ *astate = S_CTRL;
+ return (0);
+ case 'n':
+ *cp = '\n';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 'r':
+ *cp = '\r';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 'b':
+ *cp = '\b';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 'a':
+ *cp = '\007';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 'v':
+ *cp = '\v';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 't':
+ *cp = '\t';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 'f':
+ *cp = '\f';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 's':
+ *cp = ' ';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 'E':
+ *cp = '\033';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case '\n':
+ /*
+ * hidden newline
+ */
+ *astate = S_GROUND;
+ return (UNVIS_NOCHAR);
+ case '$':
+ /*
+ * hidden marker
+ */
+ *astate = S_GROUND;
+ return (UNVIS_NOCHAR);
+ }
+ *astate = S_GROUND;
+ return (UNVIS_SYNBAD);
+
+ case S_META:
+ if (c == '-')
+ *astate = S_META1;
+ else if (c == '^')
+ *astate = S_CTRL;
+ else {
+ *astate = S_GROUND;
+ return (UNVIS_SYNBAD);
+ }
+ return (0);
+
+ case S_META1:
+ *astate = S_GROUND;
+ *cp |= c;
+ return (UNVIS_VALID);
+
+ case S_CTRL:
+ if (c == '?')
+ *cp |= 0177;
+ else
+ *cp |= c & 037;
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+
+ case S_OCTAL2: /* second possible octal digit */
+ if (isoctal(c)) {
+ /*
+ * yes - and maybe a third
+ */
+ *cp = (*cp << 3) + (c - '0');
+ *astate = S_OCTAL3;
+ return (0);
+ }
+ /*
+ * no - done with current sequence, push back passed char
+ */
+ *astate = S_GROUND;
+ return (UNVIS_VALIDPUSH);
+
+ case S_OCTAL3: /* third possible octal digit */
+ *astate = S_GROUND;
+ if (isoctal(c)) {
+ *cp = (*cp << 3) + (c - '0');
+ return (UNVIS_VALID);
+ }
+ /*
+ * we were done, push back passed char
+ */
+ return (UNVIS_VALIDPUSH);
+
+ default:
+ /*
+ * decoder in unknown state - (probably uninitialized)
+ */
+ *astate = S_GROUND;
+ return (UNVIS_SYNBAD);
+ }
+}
+
+/*
+ * strunvis - decode src into dst
+ *
+ * Number of chars decoded into dst is returned, -1 on error.
+ * Dst is null terminated.
+ */
+
+int
+strunvis(dst, src)
+ register char *dst;
+ register const char *src;
+{
+ register char c;
+ char *start = dst;
+ int state = 0;
+
+ while ( (c = *src++) ) {
+ again:
+ switch (unvis(dst, c, &state, 0)) {
+ case UNVIS_VALID:
+ dst++;
+ break;
+ case UNVIS_VALIDPUSH:
+ dst++;
+ goto again;
+ case 0:
+ case UNVIS_NOCHAR:
+ break;
+ default:
+ return (-1);
+ }
+ }
+ if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
+ dst++;
+ *dst = '\0';
+ return (dst - start);
+}
diff --git a/lib/libc/gen/usleep.3 b/lib/libc/gen/usleep.3
new file mode 100644
index 0000000..77d6259
--- /dev/null
+++ b/lib/libc/gen/usleep.3
@@ -0,0 +1,81 @@
+.\" Copyright (c) 1986, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)usleep.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd Feb 13, 1998
+.Dt USLEEP 3
+.Os BSD 4.3
+.Sh NAME
+.Nm usleep
+.Nd suspend process execution for an interval measured in microseconds
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn usleep "unsigned int microseconds"
+.Sh DESCRIPTION
+The
+.Fn usleep
+function suspends execution of the calling process until either
+.Fa microseconds
+microseconds have elapsed or a signal is delivered to the process and its
+action is to invoke a signal-catching function or to terminate the
+process.
+System activity may lengthen the sleep by an indeterminate amount.
+.Pp
+This function is implemented using
+.Xr nanosleep 2
+by pausing for
+.Fa microseconds
+microseconds or until a signal occurs.
+Consequently, in this implementation,
+sleeping has no effect on the state of process timers,
+and there is no special handling for SIGALRM.
+.Sh RETURN VALUES
+.Rv -std usleep
+.Sh ERRORS
+The
+.Fn usleep
+function
+will fail if:
+.Bl -tag -width [EINTR]
+.It Bq Er EINTR
+A signal was delivered to the process and its
+action was to invoke a signal-catching function.
+.Sh SEE ALSO
+.Xr nanosleep 2 ,
+.Xr sleep 3
+.Sh HISTORY
+The
+.Fn usleep
+function appeared in
+.Bx 4.3 .
diff --git a/lib/libc/gen/usleep.c b/lib/libc/gen/usleep.c
new file mode 100644
index 0000000..4b6c67d
--- /dev/null
+++ b/lib/libc/gen/usleep.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93";
+#endif
+static char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <time.h>
+#include <unistd.h>
+
+int
+usleep(useconds)
+ unsigned int useconds;
+{
+ struct timespec time_to_sleep;
+
+ time_to_sleep.tv_nsec = (useconds % 1000000) * 1000;
+ time_to_sleep.tv_sec = useconds / 1000000;
+ return (nanosleep(&time_to_sleep, NULL));
+}
diff --git a/lib/libc/gen/utime.3 b/lib/libc/gen/utime.3
new file mode 100644
index 0000000..b8d66fd
--- /dev/null
+++ b/lib/libc/gen/utime.3
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)utime.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt UTIME 3
+.Os BSD 4
+.Sh NAME
+.Nm utime
+.Nd set file times
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <utime.h>
+.Ft int
+.Fn utime "const char *file" "const struct utimbuf *timep"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is obsoleted by utimes(2) .
+.Ef
+.Pp
+The
+.Fn utime
+function sets the access and modification times of the named file from
+the structures in the argument array
+.Fa timep .
+.Pp
+If the times are specified (the
+.Fa timep
+argument is
+.Pf non- Dv NULL )
+the caller must be the owner of the file or be the super-user.
+.Pp
+If the times are not specified (the
+.Fa timep
+argument is
+.Dv NULL )
+the caller must be the owner of the file, have permission to write
+the file, or be the super-user.
+.Sh ERRORS
+The
+.Fn utime
+function may fail and set
+.Va errno
+for any of the errors specified for the library function
+.Xr utimes 2 .
+.Sh SEE ALSO
+.Xr stat 2 ,
+.Xr utimes 2
+.Sh HISTORY
+A
+.Fn utime
+function appeared in
+.At v7 .
+.Sh STANDARDS
+The
+.Fn utime
+function conforms to
+.St -p1003.1-88 .
diff --git a/lib/libc/gen/utime.c b/lib/libc/gen/utime.c
new file mode 100644
index 0000000..a561fd6
--- /dev/null
+++ b/lib/libc/gen/utime.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)utime.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/time.h>
+
+#include <utime.h>
+
+int
+utime(path, times)
+ const char *path;
+ const struct utimbuf *times;
+{
+ struct timeval tv[2], *tvp;
+
+ if (times) {
+ tv[0].tv_sec = times->actime;
+ tv[1].tv_sec = times->modtime;
+ tv[0].tv_usec = tv[1].tv_usec = 0;
+ tvp = tv;
+ } else
+ tvp = NULL;
+ return (utimes(path, tvp));
+}
diff --git a/lib/libc/gen/valloc.3 b/lib/libc/gen/valloc.3
new file mode 100644
index 0000000..e97d1f3
--- /dev/null
+++ b/lib/libc/gen/valloc.3
@@ -0,0 +1,76 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)valloc.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt VALLOC 3
+.Os BSD 3
+.Sh NAME
+.Nm valloc
+.Nd aligned memory allocation function
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft void *
+.Fn valloc "size_t size"
+.Sh DESCRIPTION
+.Bf -symbolic
+Valloc is obsoleted by the current version of malloc(3),
+which aligns page-sized and larger allocations.
+.Ef
+.Pp
+The
+.Fn valloc
+function
+allocates
+.Fa size
+bytes aligned on a page boundary.
+It is implemented by calling
+.Xr malloc 3
+with a slightly larger request, saving the true beginning of the block
+allocated, and returning a properly aligned pointer.
+.Sh RETURN VALUES
+The
+.Fn valloc
+function returns
+a pointer to the allocated space if successful; otherwise
+a null pointer is returned
+.Sh HISTORY
+The
+.Fn valloc
+function appeared in
+.Bx 3.0 .
+.Sh BUGS
+A
+.Em vfree
+function
+has not been implemented.
diff --git a/lib/libc/gen/valloc.c b/lib/libc/gen/valloc.c
new file mode 100644
index 0000000..6035329
--- /dev/null
+++ b/lib/libc/gen/valloc.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)valloc.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+void *
+valloc(i)
+ size_t i;
+{
+ long valsiz = getpagesize(), j;
+ void *cp = malloc(i + (valsiz-1));
+
+ j = ((long)cp + (valsiz-1)) &~ (valsiz-1);
+ return ((void *)j);
+}
diff --git a/lib/libc/gen/vis.3 b/lib/libc/gen/vis.3
new file mode 100644
index 0000000..e8860b0
--- /dev/null
+++ b/lib/libc/gen/vis.3
@@ -0,0 +1,265 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)vis.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd July 25, 1996
+.Dt VIS 3
+.Os
+.Sh NAME
+.Nm vis
+.Nd visually encode characters
+.Sh SYNOPSIS
+.Fd #include <vis.h>
+.Ft char *
+.Fn vis "char *dst" "int c" "int flag" "int nextc"
+.Ft int
+.Fn strvis "char *dst" "const char *src" "int flag"
+.Ft int
+.Fn strvisx "char *dst" "const char *src" "size_t len" "int flag"
+.Sh DESCRIPTION
+The
+.Fn vis
+function
+copies into
+.Fa dst
+a string which represents the character
+.Fa c .
+If
+.Fa c
+needs no encoding, it is copied in unaltered. The string is
+null terminated, and a pointer to the end of the string is
+returned. The maximum length of any encoding is four
+characters (not including the trailing
+.Dv NUL ) ;
+thus, when
+encoding a set of characters into a buffer, the size of the buffer should
+be four times the number of characters encoded, plus one for the trailing
+.Dv NUL .
+The flag parameter is used for altering the default range of
+characters considered for encoding and for altering the visual
+representation.
+The additional character,
+.Fa nextc ,
+is only used when selecting the
+.Dv VIS_CSTYLE
+encoding format (explained below).
+.Pp
+The
+.Fn strvis
+and
+.Fn strvisx
+functions copy into
+.Fa dst
+a visual representation of
+the string
+.Fa src .
+The
+.Fn strvis
+function encodes characters from
+.Fa src
+up to the
+first
+.Dv NUL .
+The
+.Fn strvisx
+function encodes exactly
+.Fa len
+characters from
+.Fa src
+(this
+is useful for encoding a block of data that may contain
+.Dv NUL Ns 's).
+Both forms
+.Dv NUL
+terminate
+.Fa dst .
+The size of
+.Fa dst
+must be four times the number
+of characters encoded from
+.Fa src
+(plus one for the
+.Dv NUL ) .
+Both
+forms return the number of characters in dst (not including
+the trailing
+.Dv NUL ) .
+.Pp
+The encoding is a unique, invertible representation composed entirely of
+graphic characters; it can be decoded back into the original form using
+the
+.Xr unvis 3
+or
+.Xr strunvis 3
+functions.
+.Pp
+There are two parameters that can be controlled: the range of
+characters that are encoded, and the type
+of representation used.
+By default, all non-graphic characters.
+except space, tab, and newline are encoded.
+(See
+.Xr isgraph 3 . )
+The following flags
+alter this:
+.Bl -tag -width VIS_WHITEX
+.It Dv VIS_SP
+Also encode space.
+.It Dv VIS_TAB
+Also encode tab.
+.It Dv VIS_NL
+Also encode newline.
+.It Dv VIS_WHITE
+Synonym for
+.Dv VIS_SP
+\&|
+.Dv VIS_TAB
+\&|
+.Dv VIS_NL .
+.It Dv VIS_SAFE
+Only encode "unsafe" characters. Unsafe means control
+characters which may cause common terminals to perform
+unexpected functions. Currently this form allows space,
+tab, newline, backspace, bell, and return - in addition
+to all graphic characters - unencoded.
+.El
+.Pp
+There are three forms of encoding.
+All forms use the backslash character
+.Ql \e
+to introduce a special
+sequence; two backslashes are used to represent a real backslash.
+These are the visual formats:
+.Bl -tag -width VIS_CSTYLE
+.It (default)
+Use an
+.Ql M
+to represent meta characters (characters with the 8th
+bit set), and use carat
+.Ql ^
+to represent control characters see
+.Pf ( Xr iscntrl 3 ) .
+The following formats are used:
+.Bl -tag -width xxxxx
+.It Dv \e^C
+Represents the control character
+.Ql C .
+Spans characters
+.Ql \e000
+through
+.Ql \e037 ,
+and
+.Ql \e177
+(as
+.Ql \e^? ) .
+.It Dv \eM-C
+Represents character
+.Ql C
+with the 8th bit set.
+Spans characters
+.Ql \e241
+through
+.Ql \e376 .
+.It Dv \eM^C
+Represents control character
+.Ql C
+with the 8th bit set.
+Spans characters
+.Ql \e200
+through
+.Ql \e237 ,
+and
+.Ql \e377
+(as
+.Ql \eM^? ) .
+.It Dv \e040
+Represents
+.Tn ASCII
+space.
+.It Dv \e240
+Represents Meta-space.
+.El
+.Pp
+.It Dv VIS_CSTYLE
+Use C-style backslash sequences to represent standard non-printable
+characters.
+The following sequences are used to represent the indicated characters:
+.Bd -unfilled -offset indent
+.Li \ea Tn - BEL No (007)
+.Li \eb Tn - BS No (010)
+.Li \ef Tn - NP No (014)
+.Li \en Tn - NL No (012)
+.Li \er Tn - CR No (015)
+.Li \et Tn - HT No (011)
+.Li \ev Tn - VT No (013)
+.Li \e0 Tn - NUL No (000)
+.Ed
+.Pp
+When using this format, the nextc parameter is looked at to determine
+if a
+.Dv NUL
+character can be encoded as
+.Ql \e0
+instead of
+.Ql \e000 .
+If
+.Fa nextc
+is an octal digit, the latter representation is used to
+avoid ambiguity.
+.It Dv VIS_OCTAL
+Use a three digit octal sequence. The form is
+.Ql \eddd
+where
+.Em d
+represents an octal digit.
+.El
+.Pp
+There is one additional flag,
+.Dv VIS_NOSLASH ,
+which inhibits the
+doubling of backslashes and the backslash before the default
+format (that is, control characters are represented by
+.Ql ^C
+and
+meta characters as
+.Ql M-C ) .
+With this flag set, the encoding is
+ambiguous and non-invertible.
+.Sh SEE ALSO
+.Xr unvis 1 ,
+.Xr strunvis 3 ,
+.Xr unvis 3
+.Sh HISTORY
+These functions first appeared in
+.Bx 4.4 .
+
diff --git a/lib/libc/gen/vis.c b/lib/libc/gen/vis.c
new file mode 100644
index 0000000..61aa836
--- /dev/null
+++ b/lib/libc/gen/vis.c
@@ -0,0 +1,187 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)vis.c 8.1 (Berkeley) 7/19/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <limits.h>
+#include <ctype.h>
+#include <vis.h>
+
+#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
+
+/*
+ * vis - visually encode characters
+ */
+char *
+vis(dst, c, flag, nextc)
+ register char *dst;
+ int c, nextc;
+ register int flag;
+{
+ c = (unsigned char)c;
+ if (isgraph(c) ||
+ ((flag & VIS_SP) == 0 && c == ' ') ||
+ ((flag & VIS_TAB) == 0 && c == '\t') ||
+ ((flag & VIS_NL) == 0 && c == '\n') ||
+ ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
+ *dst++ = c;
+ if (c == '\\' && (flag & VIS_NOSLASH) == 0)
+ *dst++ = '\\';
+ *dst = '\0';
+ return (dst);
+ }
+
+ if (flag & VIS_CSTYLE) {
+ switch(c) {
+ case '\n':
+ *dst++ = '\\';
+ *dst++ = 'n';
+ goto done;
+ case '\r':
+ *dst++ = '\\';
+ *dst++ = 'r';
+ goto done;
+ case '\b':
+ *dst++ = '\\';
+ *dst++ = 'b';
+ goto done;
+#if __STDC__
+ case '\a':
+#else
+ case '\007':
+#endif
+ *dst++ = '\\';
+ *dst++ = 'a';
+ goto done;
+ case '\v':
+ *dst++ = '\\';
+ *dst++ = 'v';
+ goto done;
+ case '\t':
+ *dst++ = '\\';
+ *dst++ = 't';
+ goto done;
+ case '\f':
+ *dst++ = '\\';
+ *dst++ = 'f';
+ goto done;
+ case ' ':
+ *dst++ = '\\';
+ *dst++ = 's';
+ goto done;
+ case '\0':
+ *dst++ = '\\';
+ *dst++ = '0';
+ if (isoctal(nextc)) {
+ *dst++ = '0';
+ *dst++ = '0';
+ }
+ goto done;
+ }
+ }
+ if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
+ *dst++ = '\\';
+ *dst++ = ((u_char)c >> 6 & 07) + '0';
+ *dst++ = ((u_char)c >> 3 & 07) + '0';
+ *dst++ = ((u_char)c & 07) + '0';
+ goto done;
+ }
+ if ((flag & VIS_NOSLASH) == 0)
+ *dst++ = '\\';
+ if (c & 0200) {
+ c &= 0177;
+ *dst++ = 'M';
+ }
+ if (iscntrl(c)) {
+ *dst++ = '^';
+ if (c == 0177)
+ *dst++ = '?';
+ else
+ *dst++ = c + '@';
+ } else {
+ *dst++ = '-';
+ *dst++ = c;
+ }
+done:
+ *dst = '\0';
+ return (dst);
+}
+
+/*
+ * strvis, strvisx - visually encode characters from src into dst
+ *
+ * Dst must be 4 times the size of src to account for possible
+ * expansion. The length of dst, not including the trailing NULL,
+ * is returned.
+ *
+ * Strvisx encodes exactly len bytes from src into dst.
+ * This is useful for encoding a block of data.
+ */
+int
+strvis(dst, src, flag)
+ register char *dst;
+ register const char *src;
+ int flag;
+{
+ register char c;
+ char *start;
+
+ for (start = dst; (c = *src); )
+ dst = vis(dst, c, flag, *++src);
+ *dst = '\0';
+ return (dst - start);
+}
+
+int
+strvisx(dst, src, len, flag)
+ register char *dst;
+ register const char *src;
+ register size_t len;
+ int flag;
+{
+ int c;
+ char *start;
+
+ for (start = dst; len > 1; len--) {
+ c = *src;
+ dst = vis(dst, c, flag, *++src);
+ }
+ if (len)
+ dst = vis(dst, *src, flag, '\0');
+ *dst = '\0';
+
+ return (dst - start);
+}
diff --git a/lib/libc/gen/wait.c b/lib/libc/gen/wait.c
new file mode 100644
index 0000000..0bf5e8b
--- /dev/null
+++ b/lib/libc/gen/wait.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)wait.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/resource.h>
+
+pid_t
+wait(istat)
+ int *istat;
+{
+ return (wait4(WAIT_ANY, istat, 0, (struct rusage *)0));
+}
diff --git a/lib/libc/gen/wait3.c b/lib/libc/gen/wait3.c
new file mode 100644
index 0000000..c8d8f9e
--- /dev/null
+++ b/lib/libc/gen/wait3.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)wait3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/resource.h>
+
+pid_t
+wait3(istat, options, rup)
+ int *istat;
+ int options;
+ struct rusage *rup;
+{
+ return (wait4(WAIT_ANY, istat, options, rup));
+}
diff --git a/lib/libc/gen/waitpid.c b/lib/libc/gen/waitpid.c
new file mode 100644
index 0000000..7af6a63
--- /dev/null
+++ b/lib/libc/gen/waitpid.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)waitpid.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/resource.h>
+
+pid_t
+#if __STDC__
+waitpid(pid_t pid, int *istat, int options)
+#else
+waitpid(pid, istat, options)
+ pid_t pid;
+ int *istat;
+ int options;
+#endif
+{
+ return (wait4(pid, istat, options, (struct rusage *)0));
+}
diff --git a/lib/libc/gmon/Makefile.inc b/lib/libc/gmon/Makefile.inc
new file mode 100644
index 0000000..1b8a906
--- /dev/null
+++ b/lib/libc/gmon/Makefile.inc
@@ -0,0 +1,17 @@
+# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+# gmon sources
+.PATH: ${.CURDIR}/../libc/gmon
+
+SRCS+= gmon.c mcount.c
+
+.if ${LIB} == "c"
+MAN3+= moncontrol.3
+
+MLINKS+=moncontrol.3 monstartup.3
+.endif
+
+# mcount cannot be compiled with profiling
+mcount.po: mcount.o
+ cp mcount.o mcount.po
diff --git a/lib/libc/gmon/gmon.c b/lib/libc/gmon/gmon.c
new file mode 100644
index 0000000..267a469
--- /dev/null
+++ b/lib/libc/gmon/gmon.c
@@ -0,0 +1,261 @@
+/*-
+ * Copyright (c) 1983, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "@(#)gmon.c 8.1 (Berkeley) 6/4/93";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/gmon.h>
+#include <sys/sysctl.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#if defined(__ELF__) && defined(i386)
+extern char *minbrk asm (".minbrk");
+#else
+extern char *minbrk asm ("minbrk");
+#endif
+
+extern char *__progname;
+
+struct gmonparam _gmonparam = { GMON_PROF_OFF };
+
+static int s_scale;
+/* see profil(2) where this is describe (incorrectly) */
+#define SCALE_1_TO_1 0x10000L
+
+#define ERR(s) write(2, s, sizeof(s))
+
+void moncontrol __P((int));
+static int hertz __P((void));
+
+void
+monstartup(lowpc, highpc)
+ u_long lowpc;
+ u_long highpc;
+{
+ register int o;
+ char *cp;
+ struct gmonparam *p = &_gmonparam;
+
+ /*
+ * round lowpc and highpc to multiples of the density we're using
+ * so the rest of the scaling (here and in gprof) stays in ints.
+ */
+ p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
+ p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
+ p->textsize = p->highpc - p->lowpc;
+ p->kcountsize = p->textsize / HISTFRACTION;
+ p->hashfraction = HASHFRACTION;
+ p->fromssize = p->textsize / HASHFRACTION;
+ p->tolimit = p->textsize * ARCDENSITY / 100;
+ if (p->tolimit < MINARCS)
+ p->tolimit = MINARCS;
+ else if (p->tolimit > MAXARCS)
+ p->tolimit = MAXARCS;
+ p->tossize = p->tolimit * sizeof(struct tostruct);
+
+ cp = sbrk(p->kcountsize + p->fromssize + p->tossize);
+ if (cp == (char *)-1) {
+ ERR("monstartup: out of memory\n");
+ return;
+ }
+#ifdef notdef
+ bzero(cp, p->kcountsize + p->fromssize + p->tossize);
+#endif
+ p->tos = (struct tostruct *)cp;
+ cp += p->tossize;
+ p->kcount = (u_short *)cp;
+ cp += p->kcountsize;
+ p->froms = (u_short *)cp;
+
+ minbrk = sbrk(0);
+ p->tos[0].link = 0;
+
+ o = p->highpc - p->lowpc;
+ if (p->kcountsize < o) {
+#ifndef hp300
+ s_scale = ((float)p->kcountsize / o ) * SCALE_1_TO_1;
+#else /* avoid floating point */
+ int quot = o / p->kcountsize;
+
+ if (quot >= 0x10000)
+ s_scale = 1;
+ else if (quot >= 0x100)
+ s_scale = 0x10000 / quot;
+ else if (o >= 0x800000)
+ s_scale = 0x1000000 / (o / (p->kcountsize >> 8));
+ else
+ s_scale = 0x1000000 / ((o << 8) / p->kcountsize);
+#endif
+ } else
+ s_scale = SCALE_1_TO_1;
+
+ moncontrol(1);
+}
+
+void
+_mcleanup()
+{
+ int fd;
+ int fromindex;
+ int endfrom;
+ u_long frompc;
+ int toindex;
+ struct rawarc rawarc;
+ struct gmonparam *p = &_gmonparam;
+ struct gmonhdr gmonhdr, *hdr;
+ struct clockinfo clockinfo;
+ char outname[128];
+ int mib[2];
+ size_t size;
+#ifdef DEBUG
+ int log, len;
+ char buf[200];
+#endif
+
+ if (p->state == GMON_PROF_ERROR)
+ ERR("_mcleanup: tos overflow\n");
+
+ size = sizeof(clockinfo);
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_CLOCKRATE;
+ if (sysctl(mib, 2, &clockinfo, &size, NULL, 0) < 0) {
+ /*
+ * Best guess
+ */
+ clockinfo.profhz = hertz();
+ } else if (clockinfo.profhz == 0) {
+ if (clockinfo.hz != 0)
+ clockinfo.profhz = clockinfo.hz;
+ else
+ clockinfo.profhz = hertz();
+ }
+
+ moncontrol(0);
+ snprintf(outname,sizeof(outname),"%s.gmon",__progname);
+ fd = open(outname, O_CREAT|O_TRUNC|O_WRONLY, 0666);
+ if (fd < 0) {
+ warnx("_mcleanup: %s - %s",outname,strerror(errno));
+ return;
+ }
+#ifdef DEBUG
+ log = open("gmon.log", O_CREAT|O_TRUNC|O_WRONLY, 0664);
+ if (log < 0) {
+ perror("_mcleanup: gmon.log");
+ return;
+ }
+ len = sprintf(buf, "[mcleanup1] kcount 0x%x ssiz %d\n",
+ p->kcount, p->kcountsize);
+ write(log, buf, len);
+#endif
+ hdr = (struct gmonhdr *)&gmonhdr;
+ hdr->lpc = p->lowpc;
+ hdr->hpc = p->highpc;
+ hdr->ncnt = p->kcountsize + sizeof(gmonhdr);
+ hdr->version = GMONVERSION;
+ hdr->profrate = clockinfo.profhz;
+ write(fd, (char *)hdr, sizeof *hdr);
+ write(fd, p->kcount, p->kcountsize);
+ endfrom = p->fromssize / sizeof(*p->froms);
+ for (fromindex = 0; fromindex < endfrom; fromindex++) {
+ if (p->froms[fromindex] == 0)
+ continue;
+
+ frompc = p->lowpc;
+ frompc += fromindex * p->hashfraction * sizeof(*p->froms);
+ for (toindex = p->froms[fromindex]; toindex != 0;
+ toindex = p->tos[toindex].link) {
+#ifdef DEBUG
+ len = sprintf(buf,
+ "[mcleanup2] frompc 0x%x selfpc 0x%x count %d\n" ,
+ frompc, p->tos[toindex].selfpc,
+ p->tos[toindex].count);
+ write(log, buf, len);
+#endif
+ rawarc.raw_frompc = frompc;
+ rawarc.raw_selfpc = p->tos[toindex].selfpc;
+ rawarc.raw_count = p->tos[toindex].count;
+ write(fd, &rawarc, sizeof rawarc);
+ }
+ }
+ close(fd);
+}
+
+/*
+ * Control profiling
+ * profiling is what mcount checks to see if
+ * all the data structures are ready.
+ */
+void
+moncontrol(mode)
+ int mode;
+{
+ struct gmonparam *p = &_gmonparam;
+
+ if (mode) {
+ /* start */
+ profil((char *)p->kcount, p->kcountsize, p->lowpc, s_scale);
+ p->state = GMON_PROF_ON;
+ } else {
+ /* stop */
+ profil((char *)0, 0, 0, 0);
+ p->state = GMON_PROF_OFF;
+ }
+}
+
+/*
+ * discover the tick frequency of the machine
+ * if something goes wrong, we return 0, an impossible hertz.
+ */
+static int
+hertz()
+{
+ struct itimerval tim;
+
+ tim.it_interval.tv_sec = 0;
+ tim.it_interval.tv_usec = 1;
+ tim.it_value.tv_sec = 0;
+ tim.it_value.tv_usec = 0;
+ setitimer(ITIMER_REAL, &tim, 0);
+ setitimer(ITIMER_REAL, 0, &tim);
+ if (tim.it_interval.tv_usec < 2)
+ return(0);
+ return (1000000 / tim.it_interval.tv_usec);
+}
diff --git a/lib/libc/gmon/mcount.c b/lib/libc/gmon/mcount.c
new file mode 100644
index 0000000..b27b386
--- /dev/null
+++ b/lib/libc/gmon/mcount.c
@@ -0,0 +1,325 @@
+/*-
+ * Copyright (c) 1983, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(KERNEL) && defined(LIBC_SCCS)
+#if 0
+static char sccsid[] = "@(#)mcount.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+
+#include <sys/param.h>
+#include <sys/gmon.h>
+#ifdef KERNEL
+#include <sys/systm.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+void bintr __P((void));
+void btrap __P((void));
+void eintr __P((void));
+void user __P((void));
+#endif
+
+/*
+ * mcount is called on entry to each function compiled with the profiling
+ * switch set. _mcount(), which is declared in a machine-dependent way
+ * with _MCOUNT_DECL, does the actual work and is either inlined into a
+ * C routine or called by an assembly stub. In any case, this magic is
+ * taken care of by the MCOUNT definition in <machine/profile.h>.
+ *
+ * _mcount updates data structures that represent traversals of the
+ * program's call graph edges. frompc and selfpc are the return
+ * address and function address that represents the given call graph edge.
+ *
+ * Note: the original BSD code used the same variable (frompcindex) for
+ * both frompcindex and frompc. Any reasonable, modern compiler will
+ * perform this optimization.
+ */
+_MCOUNT_DECL(frompc, selfpc) /* _mcount; may be static, inline, etc */
+ register uintfptr_t frompc, selfpc;
+{
+#ifdef GUPROF
+ u_int delta;
+#endif
+ register fptrdiff_t frompci;
+ register u_short *frompcindex;
+ register struct tostruct *top, *prevtop;
+ register struct gmonparam *p;
+ register long toindex;
+#ifdef KERNEL
+ MCOUNT_DECL(s)
+#endif
+
+ p = &_gmonparam;
+#ifndef GUPROF /* XXX */
+ /*
+ * check that we are profiling
+ * and that we aren't recursively invoked.
+ */
+ if (p->state != GMON_PROF_ON)
+ return;
+#endif
+#ifdef KERNEL
+ MCOUNT_ENTER(s);
+#else
+ p->state = GMON_PROF_BUSY;
+#endif
+ frompci = frompc - p->lowpc;
+
+#ifdef KERNEL
+ /*
+ * When we are called from an exception handler, frompci may be
+ * for a user address. Convert such frompci's to the index of
+ * user() to merge all user counts.
+ */
+ if (frompci >= p->textsize) {
+ if (frompci + p->lowpc
+ >= (uintfptr_t)(VM_MAXUSER_ADDRESS + UPAGES * PAGE_SIZE))
+ goto done;
+ frompci = (uintfptr_t)user - p->lowpc;
+ if (frompci >= p->textsize)
+ goto done;
+ }
+#endif /* KERNEL */
+
+#ifdef GUPROF
+ if (p->state != GMON_PROF_HIRES)
+ goto skip_guprof_stuff;
+ /*
+ * Look at the clock and add the count of clock cycles since the
+ * clock was last looked at to a counter for frompc. This
+ * solidifies the count for the function containing frompc and
+ * effectively starts another clock for the current function.
+ * The count for the new clock will be solidified when another
+ * function call is made or the function returns.
+ *
+ * We use the usual sampling counters since they can be located
+ * efficiently. 4-byte counters are usually necessary.
+ *
+ * There are many complications for subtracting the profiling
+ * overheads from the counts for normal functions and adding
+ * them to the counts for mcount(), mexitcount() and cputime().
+ * We attempt to handle fractional cycles, but the overheads
+ * are usually underestimated because they are calibrated for
+ * a simpler than usual setup.
+ */
+ delta = cputime() - p->mcount_overhead;
+ p->cputime_overhead_resid += p->cputime_overhead_frac;
+ p->mcount_overhead_resid += p->mcount_overhead_frac;
+ if ((int)delta < 0)
+ *p->mcount_count += delta + p->mcount_overhead
+ - p->cputime_overhead;
+ else if (delta != 0) {
+ if (p->cputime_overhead_resid >= CALIB_SCALE) {
+ p->cputime_overhead_resid -= CALIB_SCALE;
+ ++*p->cputime_count;
+ --delta;
+ }
+ if (delta != 0) {
+ if (p->mcount_overhead_resid >= CALIB_SCALE) {
+ p->mcount_overhead_resid -= CALIB_SCALE;
+ ++*p->mcount_count;
+ --delta;
+ }
+ KCOUNT(p, frompci) += delta;
+ }
+ *p->mcount_count += p->mcount_overhead_sub;
+ }
+ *p->cputime_count += p->cputime_overhead;
+skip_guprof_stuff:
+#endif /* GUPROF */
+
+#ifdef KERNEL
+ /*
+ * When we are called from an exception handler, frompc is faked
+ * to be for where the exception occurred. We've just solidified
+ * the count for there. Now convert frompci to the index of btrap()
+ * for trap handlers and bintr() for interrupt handlers to make
+ * exceptions appear in the call graph as calls from btrap() and
+ * bintr() instead of calls from all over.
+ */
+ if ((uintfptr_t)selfpc >= (uintfptr_t)btrap
+ && (uintfptr_t)selfpc < (uintfptr_t)eintr) {
+ if ((uintfptr_t)selfpc >= (uintfptr_t)bintr)
+ frompci = (uintfptr_t)bintr - p->lowpc;
+ else
+ frompci = (uintfptr_t)btrap - p->lowpc;
+ }
+#endif /* KERNEL */
+
+ /*
+ * check that frompc is a reasonable pc value.
+ * for example: signal catchers get called from the stack,
+ * not from text space. too bad.
+ */
+ if (frompci >= p->textsize)
+ goto done;
+
+ frompcindex = &p->froms[frompci / (p->hashfraction * sizeof(*p->froms))];
+ toindex = *frompcindex;
+ if (toindex == 0) {
+ /*
+ * first time traversing this arc
+ */
+ toindex = ++p->tos[0].link;
+ if (toindex >= p->tolimit)
+ /* halt further profiling */
+ goto overflow;
+
+ *frompcindex = toindex;
+ top = &p->tos[toindex];
+ top->selfpc = selfpc;
+ top->count = 1;
+ top->link = 0;
+ goto done;
+ }
+ top = &p->tos[toindex];
+ if (top->selfpc == selfpc) {
+ /*
+ * arc at front of chain; usual case.
+ */
+ top->count++;
+ goto done;
+ }
+ /*
+ * have to go looking down chain for it.
+ * top points to what we are looking at,
+ * prevtop points to previous top.
+ * we know it is not at the head of the chain.
+ */
+ for (; /* goto done */; ) {
+ if (top->link == 0) {
+ /*
+ * top is end of the chain and none of the chain
+ * had top->selfpc == selfpc.
+ * so we allocate a new tostruct
+ * and link it to the head of the chain.
+ */
+ toindex = ++p->tos[0].link;
+ if (toindex >= p->tolimit)
+ goto overflow;
+
+ top = &p->tos[toindex];
+ top->selfpc = selfpc;
+ top->count = 1;
+ top->link = *frompcindex;
+ *frompcindex = toindex;
+ goto done;
+ }
+ /*
+ * otherwise, check the next arc on the chain.
+ */
+ prevtop = top;
+ top = &p->tos[top->link];
+ if (top->selfpc == selfpc) {
+ /*
+ * there it is.
+ * increment its count
+ * move it to the head of the chain.
+ */
+ top->count++;
+ toindex = prevtop->link;
+ prevtop->link = top->link;
+ top->link = *frompcindex;
+ *frompcindex = toindex;
+ goto done;
+ }
+
+ }
+done:
+#ifdef KERNEL
+ MCOUNT_EXIT(s);
+#else
+ p->state = GMON_PROF_ON;
+#endif
+ return;
+overflow:
+ p->state = GMON_PROF_ERROR;
+#ifdef KERNEL
+ MCOUNT_EXIT(s);
+#endif
+ return;
+}
+
+/*
+ * Actual definition of mcount function. Defined in <machine/profile.h>,
+ * which is included by <sys/gmon.h>.
+ */
+MCOUNT
+
+#ifdef GUPROF
+void
+mexitcount(selfpc)
+ uintfptr_t selfpc;
+{
+ struct gmonparam *p;
+ uintfptr_t selfpcdiff;
+
+ p = &_gmonparam;
+ selfpcdiff = selfpc - (uintfptr_t)p->lowpc;
+ if (selfpcdiff < p->textsize) {
+ u_int delta;
+
+ /*
+ * Solidify the count for the current function.
+ */
+ delta = cputime() - p->mexitcount_overhead;
+ p->cputime_overhead_resid += p->cputime_overhead_frac;
+ p->mexitcount_overhead_resid += p->mexitcount_overhead_frac;
+ if ((int)delta < 0)
+ *p->mexitcount_count += delta + p->mexitcount_overhead
+ - p->cputime_overhead;
+ else if (delta != 0) {
+ if (p->cputime_overhead_resid >= CALIB_SCALE) {
+ p->cputime_overhead_resid -= CALIB_SCALE;
+ ++*p->cputime_count;
+ --delta;
+ }
+ if (delta != 0) {
+ if (p->mexitcount_overhead_resid
+ >= CALIB_SCALE) {
+ p->mexitcount_overhead_resid
+ -= CALIB_SCALE;
+ ++*p->mexitcount_count;
+ --delta;
+ }
+ KCOUNT(p, selfpcdiff) += delta;
+ }
+ *p->mexitcount_count += p->mexitcount_overhead_sub;
+ }
+ *p->cputime_count += p->cputime_overhead;
+ }
+}
+#endif /* GUPROF */
diff --git a/lib/libc/gmon/moncontrol.3 b/lib/libc/gmon/moncontrol.3
new file mode 100644
index 0000000..f608f8f
--- /dev/null
+++ b/lib/libc/gmon/moncontrol.3
@@ -0,0 +1,106 @@
+.\" Copyright (c) 1980, 1991, 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)moncontrol.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt MONCONTROL 3
+.Os BSD 4
+.Sh NAME
+.Nm moncontrol ,
+.Nm monstartup
+.Nd control execution profile
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Ft int
+.Fn moncontrol "int mode"
+.Ft int
+.Fn monstartup "u_long *lowpc" "u_long *highpc"
+.Sh DESCRIPTION
+An executable program compiled using the
+.Fl pg
+option to
+.Xr cc 1
+automatically includes calls to collect statistics for the
+.Xr gprof 1
+call-graph execution profiler.
+In typical operation, profiling begins at program startup
+and ends when the program calls exit.
+When the program exits, the profiling data are written to the file
+.Em progname.gmon ,
+where progname is the name of the program, then
+.Xr gprof 1
+can be used to examine the results.
+.Pp
+.Fn moncontrol
+selectively controls profiling within a program.
+When the program starts, profiling begins.
+To stop the collection of histogram ticks and call counts use
+.Fn moncontrol 0 ;
+to resume the collection of histogram ticks and call counts use
+.Fn moncontrol 1 .
+This feature allows the cost of particular operations to be measured.
+Note that an output file will be produced on program exit
+regardless of the state of
+.Fn moncontrol .
+.Pp
+Programs that are not loaded with
+.Fl pg
+may selectively collect profiling statistics by calling
+.Fn monstartup
+with the range of addresses to be profiled.
+.Fa lowpc
+and
+.Fa highpc
+specify the address range that is to be sampled;
+the lowest address sampled is that of
+.Fa lowpc
+and the highest is just below
+.Fa highpc .
+Only functions in that range that have been compiled with the
+.Fl pg
+option to
+.Xr cc 1
+will appear in the call graph part of the output;
+however, all functions in that address range will
+have their execution time measured.
+Profiling begins on return from
+.Fn monstartup .
+.Sh FILES
+.Bl -tag -width Pa -compact
+.It Pa progname.gmon execution data file
+.El
+.Sh SEE ALSO
+.Xr cc 1 ,
+.Xr gprof 1 ,
+.Xr profil 2 ,
+.Xr clocks 7
diff --git a/lib/libc/i386/DEFS.h b/lib/libc/i386/DEFS.h
new file mode 100644
index 0000000..edf08ea
--- /dev/null
+++ b/lib/libc/i386/DEFS.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)DEFS.h 5.1 (Berkeley) 4/23/90
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/asm.h>
diff --git a/lib/libc/i386/SYS.h b/lib/libc/i386/SYS.h
new file mode 100644
index 0000000..a5daa1c
--- /dev/null
+++ b/lib/libc/i386/SYS.h
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)SYS.h 5.5 (Berkeley) 5/7/91
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/syscall.h>
+#include "DEFS.h"
+
+#define SYSCALL(x) 2: PIC_PROLOGUE; jmp PIC_PLT(HIDENAME(cerror)); \
+ ENTRY(__CONCAT(_,x)); \
+ .weak CNAME(x); \
+ .set CNAME(x),CNAME(__CONCAT(_,x)); \
+ lea __CONCAT(SYS_,x),%eax; KERNCALL; jb 2b
+#define RSYSCALL(x) SYSCALL(x); ret
+
+#define PSEUDO(x,y) ENTRY(__CONCAT(_,x)); \
+ .weak CNAME(x); \
+ .set CNAME(x),CNAME(__CONCAT(_,x)); \
+ lea __CONCAT(SYS_,y), %eax; KERNCALL; ret
+/* gas messes up offset -- although we don't currently need it, do for BCS */
+#define LCALL(x,y) .byte 0x9a ; .long y; .word x
+
+/*
+ * Design note:
+ *
+ * The macros PSYSCALL() and PRSYSCALL() are intended for use where a
+ * syscall needs to be renamed in the threaded library. When building
+ * a normal library, they default to the traditional SYSCALL() and
+ * RSYSCALL(). This avoids the need to #ifdef _THREAD_SAFE everywhere
+ * that the renamed function needs to be called.
+ */
+#ifdef _THREAD_SAFE
+/*
+ * For the thread_safe versions, we prepend _thread_sys_ to the function
+ * name so that the 'C' wrapper can go around the real name.
+ */
+#define PSYSCALL(x) 2: PIC_PROLOGUE; jmp PIC_PLT(HIDENAME(cerror)); \
+ ENTRY(__CONCAT(_thread_sys_,x)); \
+ lea __CONCAT(SYS_,x),%eax; KERNCALL; jb 2b
+#define PRSYSCALL(x) PSYSCALL(x); ret
+#define PPSEUDO(x,y) ENTRY(__CONCAT(_thread_sys_,x)); \
+ lea __CONCAT(SYS_,y), %eax; KERNCALL; ret
+#else
+/*
+ * The non-threaded library defaults to traditional syscalls where
+ * the function name matches the syscall name.
+ */
+#define PSYSCALL(x) SYSCALL(x)
+#define PRSYSCALL(x) RSYSCALL(x)
+#define PPSEUDO(x,y) PSEUDO(x,y)
+#endif
+
+#ifdef __ELF__
+#define KERNCALL int $0x80 /* Faster */
+#else
+#define KERNCALL LCALL(7,0) /* The old way */
+#endif
diff --git a/lib/libc/i386/gen/Makefile.inc b/lib/libc/i386/gen/Makefile.inc
new file mode 100644
index 0000000..f2506fd
--- /dev/null
+++ b/lib/libc/i386/gen/Makefile.inc
@@ -0,0 +1,5 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+SRCS+= _setjmp.S alloca.S fabs.S frexp.c infinity.c isinf.c ldexp.c modf.S \
+ setjmp.S sigsetjmp.S
diff --git a/lib/libc/i386/gen/_setjmp.S b/lib/libc/i386/gen/_setjmp.S
new file mode 100644
index 0000000..c8a1d21
--- /dev/null
+++ b/lib/libc/i386/gen/_setjmp.S
@@ -0,0 +1,84 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ * _longjmp(a,v)
+ * will generate a "return(v)" from the last call to
+ * _setjmp(a)
+ * by restoring registers from the environment 'a'.
+ * The previous signal state is NOT restored.
+ */
+
+#include "DEFS.h"
+
+ENTRY(_setjmp)
+ movl 4(%esp),%eax
+ movl 0(%esp),%edx
+ movl %edx, 0(%eax) /* rta */
+ movl %ebx, 4(%eax)
+ movl %esp, 8(%eax)
+ movl %ebp,12(%eax)
+ movl %esi,16(%eax)
+ movl %edi,20(%eax)
+ fnstcw 24(%eax)
+ xorl %eax,%eax
+ ret
+
+ENTRY(_longjmp)
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ movl 0(%edx),%ecx
+ movl 4(%edx),%ebx
+ movl 8(%edx),%esp
+ movl 12(%edx),%ebp
+ movl 16(%edx),%esi
+ movl 20(%edx),%edi
+ fninit
+ fldcw 24(%edx)
+ testl %eax,%eax
+ jnz 1f
+ incl %eax
+1: movl %ecx,0(%esp)
+ ret
diff --git a/lib/libc/i386/gen/alloca.S b/lib/libc/i386/gen/alloca.S
new file mode 100644
index 0000000..4aa0e32
--- /dev/null
+++ b/lib/libc/i386/gen/alloca.S
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/* like alloc, but automatic automatic free in return */
+
+#include "DEFS.h"
+
+ENTRY(alloca)
+ popl %edx /* pop return addr */
+ popl %eax /* pop amount to allocate */
+ movl %esp,%ecx
+ addl $3,%eax /* round up to next word */
+ andl $0xfffffffc,%eax
+ subl %eax,%esp
+ movl %esp,%eax /* base of newly allocated space */
+ pushl 8(%ecx) /* copy possible saved registers */
+ pushl 4(%ecx)
+ pushl 0(%ecx)
+ pushl %eax /* dummy to pop at callsite */
+ jmp %edx /* "return" */
diff --git a/lib/libc/i386/gen/fabs.S b/lib/libc/i386/gen/fabs.S
new file mode 100644
index 0000000..578cf7c
--- /dev/null
+++ b/lib/libc/i386/gen/fabs.S
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+ENTRY(fabs)
+ fldl 4(%esp)
+ fabs
+ ret
diff --git a/lib/libc/i386/gen/frexp.c b/lib/libc/i386/gen/frexp.c
new file mode 100644
index 0000000..4834f17
--- /dev/null
+++ b/lib/libc/i386/gen/frexp.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <sys/types.h>
+#include <math.h>
+
+double
+frexp(value, eptr)
+ double value;
+ int *eptr;
+{
+ union {
+ double v;
+ struct {
+ u_int u_mant2 : 32;
+ u_int u_mant1 : 20;
+ u_int u_exp : 11;
+ u_int u_sign : 1;
+ } s;
+ } u;
+
+ if (value) {
+ u.v = value;
+ *eptr = u.s.u_exp - 1022;
+ u.s.u_exp = 1022;
+ return(u.v);
+ } else {
+ *eptr = 0;
+ return((double)0);
+ }
+}
diff --git a/lib/libc/i386/gen/infinity.c b/lib/libc/i386/gen/infinity.c
new file mode 100644
index 0000000..ac92d46
--- /dev/null
+++ b/lib/libc/i386/gen/infinity.c
@@ -0,0 +1,9 @@
+/*
+ * infinity.c
+ * $FreeBSD$
+ */
+
+#include <math.h>
+
+/* bytes for +Infinity on a 387 */
+char __infinity[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
diff --git a/lib/libc/i386/gen/isinf.c b/lib/libc/i386/gen/isinf.c
new file mode 100644
index 0000000..b2b63a8
--- /dev/null
+++ b/lib/libc/i386/gen/isinf.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <sys/types.h>
+
+int
+isnan(d)
+ double d;
+{
+ register struct IEEEdp {
+ u_int manl : 32;
+ u_int manh : 20;
+ u_int exp : 11;
+ u_int sign : 1;
+ } *p = (struct IEEEdp *)&d;
+
+ return(p->exp == 2047 && (p->manh || p->manl));
+}
+
+int
+isinf(d)
+ double d;
+{
+ register struct IEEEdp {
+ u_int manl : 32;
+ u_int manh : 20;
+ u_int exp : 11;
+ u_int sign : 1;
+ } *p = (struct IEEEdp *)&d;
+
+ return(p->exp == 2047 && !p->manh && !p->manl);
+}
diff --git a/lib/libc/i386/gen/ldexp.c b/lib/libc/i386/gen/ldexp.c
new file mode 100644
index 0000000..e7e58f0
--- /dev/null
+++ b/lib/libc/i386/gen/ldexp.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Sean Eric Fagan.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+/*
+ * ldexp(value, exp): return value * (2 ** exp).
+ *
+ * Written by Sean Eric Fagan (sef@kithrup.COM)
+ * Sun Mar 11 20:27:09 PST 1990
+ */
+
+/*
+ * We do the conversion in C to let gcc optimize it away, if possible.
+ * The "fxch ; fstp" stuff is because value is still on the stack
+ * (stupid 8087!).
+ */
+double
+ldexp (double value, int exp)
+{
+ double temp, texp, temp2;
+ texp = exp;
+#ifdef __GNUC__
+#if __GNUC__ >= 2
+ asm ("fscale "
+ : "=u" (temp2), "=t" (temp)
+ : "0" (texp), "1" (value));
+#else
+ asm ("fscale ; fxch %%st(1) ; fstp%L1 %1 "
+ : "=f" (temp), "=0" (temp2)
+ : "0" (texp), "f" (value));
+#endif
+#else
+error unknown asm
+#endif
+ return (temp);
+}
diff --git a/lib/libc/i386/gen/modf.S b/lib/libc/i386/gen/modf.S
new file mode 100644
index 0000000..751ec1c
--- /dev/null
+++ b/lib/libc/i386/gen/modf.S
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Sean Eric Fagan.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/*
+ * modf(value, iptr): return fractional part of value, and stores the
+ * integral part into iptr (a pointer to double).
+ *
+ * Written by Sean Eric Fagan (sef@kithrup.COM)
+ * Sun Mar 11 20:27:30 PST 1990
+ */
+
+/* With CHOP mode on, frndint behaves as TRUNC does. Useful. */
+
+#include "DEFS.h"
+
+ENTRY(modf)
+ pushl %ebp
+ movl %esp,%ebp
+ subl $16,%esp
+ fnstcw -12(%ebp)
+ movw -12(%ebp),%dx
+ orw $3072,%dx
+ movw %dx,-16(%ebp)
+ fldcw -16(%ebp)
+ fldl 8(%ebp)
+ frndint
+ fstpl -8(%ebp)
+ fldcw -12(%ebp)
+ movl 16(%ebp),%eax
+ movl -8(%ebp),%edx
+ movl -4(%ebp),%ecx
+ movl %edx,(%eax)
+ movl %ecx,4(%eax)
+ fldl 8(%ebp)
+ fsubl -8(%ebp)
+ jmp L1
+L1:
+ leave
+ ret
diff --git a/lib/libc/i386/gen/setjmp.S b/lib/libc/i386/gen/setjmp.S
new file mode 100644
index 0000000..c82b7f0
--- /dev/null
+++ b/lib/libc/i386/gen/setjmp.S
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ * longjmp(a,v)
+ * will generate a "return(v)" from the last call to
+ * setjmp(a)
+ * by restoring registers from the environment 'a'.
+ * The previous signal state is restored.
+ */
+
+#include "DEFS.h"
+#include "SYS.h"
+
+ENTRY(__setjmp)
+.weak setjmp;
+.set setjmp, __setjmp;
+ movl 4(%esp),%ecx
+ PIC_PROLOGUE
+ leal 28(%ecx), %eax
+ pushl %eax /* (sigset_t*)oset */
+ pushl $0 /* (sigset_t*)set */
+ pushl $1 /* SIG_BLOCK */
+#ifdef _THREAD_SAFE
+ call PIC_PLT(CNAME(_thread_sys_sigprocmask))
+#else
+ call PIC_PLT(CNAME(sigprocmask))
+#endif
+ addl $12,%esp
+ PIC_EPILOGUE
+ movl 4(%esp),%ecx
+ movl 0(%esp),%edx
+ movl %edx, 0(%ecx)
+ movl %ebx, 4(%ecx)
+ movl %esp, 8(%ecx)
+ movl %ebp,12(%ecx)
+ movl %esi,16(%ecx)
+ movl %edi,20(%ecx)
+ fnstcw 24(%ecx)
+ xorl %eax,%eax
+ ret
+
+ENTRY(__longjmp)
+.weak longjmp;
+.set longjmp, __longjmp;
+ movl 4(%esp),%edx
+ PIC_PROLOGUE
+ pushl $0 /* (sigset_t*)oset */
+ leal 28(%edx), %eax
+ pushl %eax /* (sigset_t*)set */
+ pushl $3 /* SIG_SETMASK */
+#ifdef _THREAD_SAFE
+ call PIC_PLT(CNAME(_thread_sys_sigprocmask))
+#else
+ call PIC_PLT(CNAME(sigprocmask))
+#endif
+ addl $12,%esp
+ PIC_EPILOGUE
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ movl 0(%edx),%ecx
+ movl 4(%edx),%ebx
+ movl 8(%edx),%esp
+ movl 12(%edx),%ebp
+ movl 16(%edx),%esi
+ movl 20(%edx),%edi
+ fninit
+ fldcw 24(%edx)
+ testl %eax,%eax
+ jnz 1f
+ incl %eax
+1: movl %ecx,0(%esp)
+ ret
diff --git a/lib/libc/i386/gen/sigsetjmp.S b/lib/libc/i386/gen/sigsetjmp.S
new file mode 100644
index 0000000..22cf790
--- /dev/null
+++ b/lib/libc/i386/gen/sigsetjmp.S
@@ -0,0 +1,126 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+#include "SYS.h"
+
+/*-
+ * TODO:
+ * Rename sigsetjmp to __sigsetjmp and siglongjmp to __siglongjmp,
+ * remove the other *jmp functions and define everything in terms
+ * of the renamed functions. This requires compiler support for
+ * the renamed functions (introduced in gcc-2.5.3; previous versions
+ * only supported *jmp with 0 or 1 leading underscores).
+ *
+ * Use sigprocmask() instead of sigblock() and sigsetmask(), and
+ * check for and handle errors.
+ *
+ * Restore _all_ the registers and the signal mask atomically. Can
+ * use sigreturn() if sigreturn() works.
+ */
+
+ENTRY(__sigsetjmp)
+.weak sigsetjmp;
+.set sigsetjmp, __sigsetjmp;
+ movl 8(%esp),%eax
+ movl 4(%esp),%ecx
+ movl %eax,44(%ecx)
+ testl %eax,%eax
+ jz 2f
+ PIC_PROLOGUE
+ leal 28(%ecx), %eax
+ pushl %eax /* (sigset_t*)oset */
+ pushl $0 /* (sigset_t*)set */
+ pushl $1 /* SIG_BLOCK */
+#ifdef _THREAD_SAFE
+ call PIC_PLT(CNAME(_thread_sys_sigprocmask))
+#else
+ call PIC_PLT(CNAME(sigprocmask))
+#endif
+ addl $12,%esp
+ PIC_EPILOGUE
+ movl 4(%esp),%ecx
+2: movl 0(%esp),%edx
+ movl %edx, 0(%ecx)
+ movl %ebx, 4(%ecx)
+ movl %esp, 8(%ecx)
+ movl %ebp,12(%ecx)
+ movl %esi,16(%ecx)
+ movl %edi,20(%ecx)
+ fnstcw 24(%ecx)
+ xorl %eax,%eax
+ ret
+
+ENTRY(__siglongjmp)
+.weak siglongjmp;
+.set siglongjmp, __siglongjmp;
+ movl 4(%esp),%edx
+ cmpl $0,44(%edx)
+ jz 2f
+ PIC_PROLOGUE
+ pushl $0 /* (sigset_t*)oset */
+ leal 28(%edx), %eax
+ pushl %eax /* (sigset_t*)set */
+ pushl $3 /* SIG_SETMASK */
+#ifdef _THREAD_SAFE
+ call PIC_PLT(CNAME(_thread_sys_sigprocmask))
+#else
+ call PIC_PLT(CNAME(sigprocmask))
+#endif
+ addl $12,%esp
+ PIC_EPILOGUE
+ movl 4(%esp),%edx
+2: movl 8(%esp),%eax
+ movl 0(%edx),%ecx
+ movl 4(%edx),%ebx
+ movl 8(%edx),%esp
+ movl 12(%edx),%ebp
+ movl 16(%edx),%esi
+ movl 20(%edx),%edi
+ fninit
+ fldcw 24(%edx)
+ testl %eax,%eax
+ jnz 1f
+ incl %eax
+1: movl %ecx,0(%esp)
+ ret
diff --git a/lib/libc/i386/net/Makefile.inc b/lib/libc/i386/net/Makefile.inc
new file mode 100644
index 0000000..96e559b
--- /dev/null
+++ b/lib/libc/i386/net/Makefile.inc
@@ -0,0 +1,4 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+SRCS+= htonl.S htons.S ntohl.S ntohs.S
diff --git a/lib/libc/i386/net/htonl.S b/lib/libc/i386/net/htonl.S
new file mode 100644
index 0000000..48f1ca8
--- /dev/null
+++ b/lib/libc/i386/net/htonl.S
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/* netorder = htonl(hostorder) */
+
+#include "DEFS.h"
+
+ENTRY(htonl)
+ movl 4(%esp),%eax
+ xchgb %al,%ah
+ roll $16,%eax
+ xchgb %al,%ah
+ ret
diff --git a/lib/libc/i386/net/htons.S b/lib/libc/i386/net/htons.S
new file mode 100644
index 0000000..68f2b5a
--- /dev/null
+++ b/lib/libc/i386/net/htons.S
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/* netorder = htons(hostorder) */
+
+#include "DEFS.h"
+
+ENTRY(htons)
+ movzwl 4(%esp),%eax
+ xchgb %al,%ah
+ ret
diff --git a/lib/libc/i386/net/ntohl.S b/lib/libc/i386/net/ntohl.S
new file mode 100644
index 0000000..7be9dee
--- /dev/null
+++ b/lib/libc/i386/net/ntohl.S
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/* hostorder = ntohl(netorder) */
+
+#include "DEFS.h"
+
+ENTRY(ntohl)
+ movl 4(%esp),%eax
+ xchgb %al,%ah
+ roll $16,%eax
+ xchgb %al,%ah
+ ret
diff --git a/lib/libc/i386/net/ntohs.S b/lib/libc/i386/net/ntohs.S
new file mode 100644
index 0000000..0f1d228
--- /dev/null
+++ b/lib/libc/i386/net/ntohs.S
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/* hostorder = ntohs(netorder) */
+
+#include "DEFS.h"
+
+ENTRY(ntohs)
+ movzwl 4(%esp),%eax
+ xchgb %al,%ah
+ ret
diff --git a/lib/libc/i386/stdlib/Makefile.inc b/lib/libc/i386/stdlib/Makefile.inc
new file mode 100644
index 0000000..0a6a6a8
--- /dev/null
+++ b/lib/libc/i386/stdlib/Makefile.inc
@@ -0,0 +1,4 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+MDSRCS+=abs.S div.S labs.S ldiv.S
diff --git a/lib/libc/i386/stdlib/abs.S b/lib/libc/i386/stdlib/abs.S
new file mode 100644
index 0000000..e4812d8
--- /dev/null
+++ b/lib/libc/i386/stdlib/abs.S
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+ENTRY(abs)
+ movl 4(%esp),%eax
+ testl %eax,%eax
+ jns 1f
+ negl %eax
+1: ret
diff --git a/lib/libc/i386/stdlib/div.S b/lib/libc/i386/stdlib/div.S
new file mode 100644
index 0000000..a9ff515
--- /dev/null
+++ b/lib/libc/i386/stdlib/div.S
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+ENTRY(div)
+ movl 4(%esp),%eax
+ movl 8(%esp),%ecx
+ cdq
+ idiv %ecx
+ movl %eax,4(%esp)
+ movl %edx,8(%esp)
+ ret
diff --git a/lib/libc/i386/stdlib/labs.S b/lib/libc/i386/stdlib/labs.S
new file mode 100644
index 0000000..6fa8149
--- /dev/null
+++ b/lib/libc/i386/stdlib/labs.S
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+ENTRY(labs)
+ movl 4(%esp),%eax
+ testl %eax,%eax
+ jns 1f
+ negl %eax
+1: ret
diff --git a/lib/libc/i386/stdlib/ldiv.S b/lib/libc/i386/stdlib/ldiv.S
new file mode 100644
index 0000000..c9546c3
--- /dev/null
+++ b/lib/libc/i386/stdlib/ldiv.S
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+ENTRY(ldiv)
+ movl 4(%esp),%eax
+ movl 8(%esp),%ecx
+ cdq
+ idiv %ecx
+ movl %eax,4(%esp)
+ movl %edx,8(%esp)
+ ret
diff --git a/lib/libc/i386/string/Makefile.inc b/lib/libc/i386/string/Makefile.inc
new file mode 100644
index 0000000..1b2de19
--- /dev/null
+++ b/lib/libc/i386/string/Makefile.inc
@@ -0,0 +1,6 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+MDSRCS+=bcmp.S bcopy.S bzero.S ffs.S index.S memchr.S memcmp.S memcpy.S \
+ memmove.S memset.S rindex.S strcat.S strchr.S strcmp.S strcpy.S \
+ strlen.S strncmp.S strrchr.S swab.S
diff --git a/lib/libc/i386/string/bcmp.S b/lib/libc/i386/string/bcmp.S
new file mode 100644
index 0000000..3c0bd02
--- /dev/null
+++ b/lib/libc/i386/string/bcmp.S
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * bcmp (void *b1, void *b2, size_t len)
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+ENTRY(bcmp)
+ pushl %edi
+ pushl %esi
+ movl 12(%esp),%edi
+ movl 16(%esp),%esi
+ xorl %eax,%eax /* clear return value */
+ cld /* set compare direction forward */
+
+ movl 20(%esp),%ecx /* compare by words */
+ shrl $2,%ecx
+ repe
+ cmpsl
+ jne L1
+
+ movl 20(%esp),%ecx /* compare remainder by bytes */
+ andl $3,%ecx
+ repe
+ cmpsb
+ je L2
+
+L1: incl %eax
+L2: popl %esi
+ popl %edi
+ ret
diff --git a/lib/libc/i386/string/bcopy.S b/lib/libc/i386/string/bcopy.S
new file mode 100644
index 0000000..d2a571e
--- /dev/null
+++ b/lib/libc/i386/string/bcopy.S
@@ -0,0 +1,103 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from locore.s.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+ RCSID("$NetBSD: bcopy.S,v 1.6 1996/11/12 00:50:06 jtc Exp $")
+
+ /*
+ * (ov)bcopy (src,dst,cnt)
+ * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
+ */
+
+#ifdef MEMCOPY
+ENTRY(memcpy)
+#else
+#ifdef MEMMOVE
+ENTRY(memmove)
+#else
+ENTRY(bcopy)
+#endif
+#endif
+ pushl %esi
+ pushl %edi
+#if defined(MEMCOPY) || defined(MEMMOVE)
+ movl 12(%esp),%edi
+ movl 16(%esp),%esi
+#else
+ movl 12(%esp),%esi
+ movl 16(%esp),%edi
+#endif
+ movl 20(%esp),%ecx
+ movl %edi,%eax
+ subl %esi,%eax
+ cmpl %ecx,%eax /* overlapping? */
+ jb 1f
+ cld /* nope, copy forwards. */
+ shrl $2,%ecx /* copy by words */
+ rep
+ movsl
+ movl 20(%esp),%ecx
+ andl $3,%ecx /* any bytes left? */
+ rep
+ movsb
+#if defined(MEMCOPY) || defined(MEMMOVE)
+ movl 12(%esp),%eax
+#endif
+ popl %edi
+ popl %esi
+ ret
+1:
+ addl %ecx,%edi /* copy backwards. */
+ addl %ecx,%esi
+ std
+ andl $3,%ecx /* any fractional bytes? */
+ decl %edi
+ decl %esi
+ rep
+ movsb
+ movl 20(%esp),%ecx /* copy remainder by words */
+ shrl $2,%ecx
+ subl $3,%esi
+ subl $3,%edi
+ rep
+ movsl
+#if defined(MEMCOPY) || defined(MEMMOVE)
+ movl 12(%esp),%eax
+#endif
+ popl %edi
+ popl %esi
+ cld
+ ret
diff --git a/lib/libc/i386/string/bzero.S b/lib/libc/i386/string/bzero.S
new file mode 100644
index 0000000..7f95f71
--- /dev/null
+++ b/lib/libc/i386/string/bzero.S
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * bzero (void *b, size_t len)
+ * write len zero bytes to the string b.
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+ENTRY(bzero)
+ pushl %edi
+ pushl %ebx
+ movl 12(%esp),%edi
+ movl 16(%esp),%ecx
+
+ cld /* set fill direction forward */
+ xorl %eax,%eax /* set fill data to 0 */
+
+ /*
+ * if the string is too short, it's really not worth the overhead
+ * of aligning to word boundries, etc. So we jump to a plain
+ * unaligned set.
+ */
+ cmpl $0x0f,%ecx
+ jle L1
+
+ movl %edi,%edx /* compute misalignment */
+ negl %edx
+ andl $3,%edx
+ movl %ecx,%ebx
+ subl %edx,%ebx
+
+ movl %edx,%ecx /* zero until word aligned */
+ rep
+ stosb
+
+ movl %ebx,%ecx /* zero by words */
+ shrl $2,%ecx
+ rep
+ stosl
+
+ movl %ebx,%ecx
+ andl $3,%ecx /* zero remainder by bytes */
+L1: rep
+ stosb
+
+ popl %ebx
+ popl %edi
+ ret
diff --git a/lib/libc/i386/string/ffs.S b/lib/libc/i386/string/ffs.S
new file mode 100644
index 0000000..ae4be79
--- /dev/null
+++ b/lib/libc/i386/string/ffs.S
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * ffs(value)
+ * finds the first bit set in value and returns the index of
+ * that bit. Bits are numbered starting from 1, starting at the
+ * rightmost bit. A return value of 0 means that the argument
+ * was zero.
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+ENTRY(ffs)
+ bsfl 4(%esp),%eax
+ jz L1 /* ZF is set if all bits are 0 */
+ incl %eax /* bits numbered from 1, not 0 */
+ ret
+
+ .align 2
+L1: xorl %eax,%eax /* clear result */
+ ret
diff --git a/lib/libc/i386/string/index.S b/lib/libc/i386/string/index.S
new file mode 100644
index 0000000..d63a646
--- /dev/null
+++ b/lib/libc/i386/string/index.S
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * index(s, c)
+ * return a pointer to the first occurance of the character c in
+ * string s, or NULL if c does not occur in the string.
+ *
+ * %edx - pointer iterating through string
+ * %eax - pointer to first occurance of 'c'
+ * %cl - character we're comparing against
+ * %bl - character at %edx
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+ENTRY(index)
+ pushl %ebx
+ movl 8(%esp),%eax
+ movb 12(%esp),%cl
+ .align 2,0x90
+L1:
+ movb (%eax),%bl
+ cmpb %bl,%cl /* found char??? */
+ je L2
+ incl %eax
+ testb %bl,%bl /* null terminator??? */
+ jne L1
+ xorl %eax,%eax
+L2:
+ popl %ebx
+ ret
diff --git a/lib/libc/i386/string/memchr.S b/lib/libc/i386/string/memchr.S
new file mode 100644
index 0000000..9604f59
--- /dev/null
+++ b/lib/libc/i386/string/memchr.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * memchr (b, c, len)
+ * locates the first occurance of c in string b.
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+ENTRY(memchr)
+ pushl %edi
+ movl 8(%esp),%edi /* string address */
+ movl 12(%esp),%eax /* set character to search for */
+ movl 16(%esp),%ecx /* set length of search */
+ testl %esp,%esp /* clear Z flag, for len == 0 */
+ cld /* set search forward */
+ repne /* search! */
+ scasb
+ jnz L1 /* scan failed, return null */
+ leal -1(%edi),%eax /* adjust result of scan */
+ popl %edi
+ ret
+ .align 2,0x90
+L1: xorl %eax,%eax
+ popl %edi
+ ret
diff --git a/lib/libc/i386/string/memcmp.S b/lib/libc/i386/string/memcmp.S
new file mode 100644
index 0000000..e4fd4a7
--- /dev/null
+++ b/lib/libc/i386/string/memcmp.S
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * memcmp (void *b1, void *b2, size_t len)
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+ENTRY(memcmp)
+ pushl %edi
+ pushl %esi
+ movl 12(%esp),%edi
+ movl 16(%esp),%esi
+ cld /* set compare direction forward */
+
+ movl 20(%esp),%ecx /* compare by words */
+ shrl $2,%ecx
+ repe
+ cmpsl
+ jne L5 /* do we match so far? */
+
+ movl 20(%esp),%ecx /* compare remainder by bytes */
+ andl $3,%ecx
+ repe
+ cmpsb
+ jne L6 /* do we match? */
+
+ xorl %eax,%eax /* we match, return zero */
+ popl %esi
+ popl %edi
+ ret
+
+L5: movl $4,%ecx /* We know that one of the next */
+ subl %ecx,%edi /* four pairs of bytes do not */
+ subl %ecx,%esi /* match. */
+ repe
+ cmpsb
+L6: movzbl -1(%edi),%eax /* Perform unsigned comparison */
+ movzbl -1(%esi),%edx
+ subl %edx,%eax
+ popl %esi
+ popl %edi
+ ret
diff --git a/lib/libc/i386/string/memcpy.S b/lib/libc/i386/string/memcpy.S
new file mode 100644
index 0000000..1617c71
--- /dev/null
+++ b/lib/libc/i386/string/memcpy.S
@@ -0,0 +1,2 @@
+#define MEMCOPY
+#include "bcopy.S"
diff --git a/lib/libc/i386/string/memmove.S b/lib/libc/i386/string/memmove.S
new file mode 100644
index 0000000..f5a94ed
--- /dev/null
+++ b/lib/libc/i386/string/memmove.S
@@ -0,0 +1,2 @@
+#define MEMMOVE
+#include "bcopy.S"
diff --git a/lib/libc/i386/string/memset.S b/lib/libc/i386/string/memset.S
new file mode 100644
index 0000000..bb9e268
--- /dev/null
+++ b/lib/libc/i386/string/memset.S
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * memset(void *b, int c, size_t len)
+ * write len bytes of value c (converted to an unsigned char) to
+ * the string b.
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+ENTRY(memset)
+ pushl %edi
+ pushl %ebx
+ movl 12(%esp),%edi
+ movzbl 16(%esp),%eax /* unsigned char, zero extend */
+ movl 20(%esp),%ecx
+ pushl %edi /* push address of buffer */
+
+ cld /* set fill direction forward */
+
+ /*
+ * if the string is too short, it's really not worth the overhead
+ * of aligning to word boundries, etc. So we jump to a plain
+ * unaligned set.
+ */
+ cmpl $0x0f,%ecx
+ jle L1
+
+ movb %al,%ah /* copy char to all bytes in word */
+ movl %eax,%edx
+ sall $16,%eax
+ orl %edx,%eax
+
+ movl %edi,%edx /* compute misalignment */
+ negl %edx
+ andl $3,%edx
+ movl %ecx,%ebx
+ subl %edx,%ebx
+
+ movl %edx,%ecx /* set until word aligned */
+ rep
+ stosb
+
+ movl %ebx,%ecx
+ shrl $2,%ecx /* set by words */
+ rep
+ stosl
+
+ movl %ebx,%ecx /* set remainder by bytes */
+ andl $3,%ecx
+L1: rep
+ stosb
+
+ popl %eax /* pop address of buffer */
+ popl %ebx
+ popl %edi
+ ret
diff --git a/lib/libc/i386/string/rindex.S b/lib/libc/i386/string/rindex.S
new file mode 100644
index 0000000..dd15865
--- /dev/null
+++ b/lib/libc/i386/string/rindex.S
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * rindex(s, c)
+ * return a pointer to the last occurance of the character c in
+ * string s, or NULL if c does not occur in the string.
+ *
+ * %edx - pointer iterating through string
+ * %eax - pointer to last occurance of 'c'
+ * %cl - character we're comparing against
+ * %bl - character at %edx
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+ENTRY(rindex)
+ pushl %ebx
+ movl 8(%esp),%edx
+ movb 12(%esp),%cl
+ xorl %eax,%eax /* init pointer to null */
+ .align 2,0x90
+L1:
+ movb (%edx),%bl
+ cmpb %bl,%cl
+ jne L2
+ movl %edx,%eax
+L2:
+ incl %edx
+ testb %bl,%bl /* null terminator??? */
+ jne L1
+ popl %ebx
+ ret
diff --git a/lib/libc/i386/string/strcat.S b/lib/libc/i386/string/strcat.S
new file mode 100644
index 0000000..ceda010
--- /dev/null
+++ b/lib/libc/i386/string/strcat.S
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * strcat(s, append)
+ * append a copy of the null-terminated string "append" to the end
+ * of the null-terminated string s, then add a terminating `\0'.
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+/*
+ * I've unrolled the loop eight times: large enough to make a
+ * significant difference, and small enough not to totally trash the
+ * cashe.
+ */
+
+ENTRY(strcat)
+ pushl %edi /* save edi */
+ movl 8(%esp),%edi /* dst address */
+ movl 12(%esp),%edx /* src address */
+ pushl %edi /* push destination address */
+
+ cld /* set search forward */
+ xorl %eax,%eax /* set search for null terminator */
+ movl $-1,%ecx /* set search for lots of characters */
+ repne /* search! */
+ scasb
+
+ leal -1(%edi),%ecx /* correct dst address */
+
+ .align 2,0x90
+L1: movb (%edx),%al /* unroll loop, but not too much */
+ movb %al,(%ecx)
+ testb %al,%al
+ je L2
+ movb 1(%edx),%al
+ movb %al,1(%ecx)
+ testb %al,%al
+ je L2
+ movb 2(%edx),%al
+ movb %al,2(%ecx)
+ testb %al,%al
+ je L2
+ movb 3(%edx),%al
+ movb %al,3(%ecx)
+ testb %al,%al
+ je L2
+ movb 4(%edx),%al
+ movb %al,4(%ecx)
+ testb %al,%al
+ je L2
+ movb 5(%edx),%al
+ movb %al,5(%ecx)
+ testb %al,%al
+ je L2
+ movb 6(%edx),%al
+ movb %al,6(%ecx)
+ testb %al,%al
+ je L2
+ movb 7(%edx),%al
+ movb %al,7(%ecx)
+ addl $8,%edx
+ addl $8,%ecx
+ testb %al,%al
+ jne L1
+L2: popl %eax /* pop destination address */
+ popl %edi /* restore edi */
+ ret
diff --git a/lib/libc/i386/string/strchr.S b/lib/libc/i386/string/strchr.S
new file mode 100644
index 0000000..16fa724
--- /dev/null
+++ b/lib/libc/i386/string/strchr.S
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * strchr(s, c)
+ * return a pointer to the first occurance of the character c in
+ * string s, or NULL if c does not occur in the string.
+ *
+ * %edx - pointer iterating through string
+ * %eax - pointer to first occurance of 'c'
+ * %cl - character we're comparing against
+ * %bl - character at %edx
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+ENTRY(strchr)
+ pushl %ebx
+ movl 8(%esp),%eax
+ movb 12(%esp),%cl
+ .align 2,0x90
+L1:
+ movb (%eax),%bl
+ cmpb %bl,%cl /* found char??? */
+ je L2
+ incl %eax
+ testb %bl,%bl /* null terminator??? */
+ jne L1
+ xorl %eax,%eax
+L2:
+ popl %ebx
+ ret
diff --git a/lib/libc/i386/string/strcmp.S b/lib/libc/i386/string/strcmp.S
new file mode 100644
index 0000000..28a3f2f
--- /dev/null
+++ b/lib/libc/i386/string/strcmp.S
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * strcmp(s1, s2)
+ * return an integer greater than, equal to, or less than 0,
+ * according as string s1 is greater than, equal to, or less
+ * than the string s2.
+ *
+ * %eax - pointer to s1
+ * %edx - pointer to s2
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+/*
+ * I've unrolled the loop eight times: large enough to make a
+ * significant difference, and small enough not to totally trash the
+ * cashe.
+ */
+
+ENTRY(strcmp)
+ movl 0x04(%esp),%eax
+ movl 0x08(%esp),%edx
+ jmp L2 /* Jump into the loop! */
+
+ .align 2,0x90
+L1: incl %eax
+ incl %edx
+L2: movb (%eax),%cl
+ testb %cl,%cl
+ je L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ je L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ je L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ je L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ je L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ je L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ je L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ je L3
+ cmpb %cl,(%edx)
+ je L1
+ .align 2, 0x90
+L3: movzbl (%eax),%eax /* unsigned comparison */
+ movzbl (%edx),%edx
+ subl %edx,%eax
+ ret
diff --git a/lib/libc/i386/string/strcpy.S b/lib/libc/i386/string/strcpy.S
new file mode 100644
index 0000000..5a30414
--- /dev/null
+++ b/lib/libc/i386/string/strcpy.S
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * strcpy (dst, src)
+ * copy the string src to dst.
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+/*
+ * I've unrolled the loop eight times: large enough to make a
+ * significant difference, and small enough not to totally trash the
+ * cashe.
+ */
+
+ENTRY(strcpy)
+ movl 4(%esp),%ecx /* dst address */
+ movl 8(%esp),%edx /* src address */
+ pushl %ecx /* push dst address */
+
+ .align 2,0x90
+L1: movb (%edx),%al /* unroll loop, but not too much */
+ movb %al,(%ecx)
+ testb %al,%al
+ je L2
+ movb 1(%edx),%al
+ movb %al,1(%ecx)
+ testb %al,%al
+ je L2
+ movb 2(%edx),%al
+ movb %al,2(%ecx)
+ testb %al,%al
+ je L2
+ movb 3(%edx),%al
+ movb %al,3(%ecx)
+ testb %al,%al
+ je L2
+ movb 4(%edx),%al
+ movb %al,4(%ecx)
+ testb %al,%al
+ je L2
+ movb 5(%edx),%al
+ movb %al,5(%ecx)
+ testb %al,%al
+ je L2
+ movb 6(%edx),%al
+ movb %al,6(%ecx)
+ testb %al,%al
+ je L2
+ movb 7(%edx),%al
+ movb %al,7(%ecx)
+ addl $8,%edx
+ addl $8,%ecx
+ testb %al,%al
+ jne L1
+L2: popl %eax /* pop dst address */
+ ret
diff --git a/lib/libc/i386/string/strlen.S b/lib/libc/i386/string/strlen.S
new file mode 100644
index 0000000..eedc969
--- /dev/null
+++ b/lib/libc/i386/string/strlen.S
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * strlen (s)
+ * compute the length of the string s.
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+ENTRY(strlen)
+ pushl %edi
+ movl 8(%esp),%edi /* string address */
+ cld /* set search forward */
+ xorl %eax,%eax /* set search for null terminator */
+ movl $-1,%ecx /* set search for lots of characters */
+ repne /* search! */
+ scasb
+ notl %ecx /* get length by taking complement */
+ leal -1(%ecx),%eax /* and subtracting one */
+ popl %edi
+ ret
diff --git a/lib/libc/i386/string/strncmp.S b/lib/libc/i386/string/strncmp.S
new file mode 100644
index 0000000..0efc6ac
--- /dev/null
+++ b/lib/libc/i386/string/strncmp.S
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * strncmp(s1, s2, n)
+ * return an integer greater than, equal to, or less than 0,
+ * according as the first n characters of string s1 is greater
+ * than, equal to, or less than the string s2.
+ *
+ * %eax - pointer to s1
+ * %ecx - pointer to s2
+ * %edx - length
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+/*
+ * I've unrolled the loop eight times: large enough to make a
+ * significant difference, and small enough not to totally trash the
+ * cache.
+ *
+ * TODO: change all the jz's back to je for consistency.
+ */
+
+ENTRY(strncmp)
+ pushl %ebx
+ movl 8(%esp),%eax
+ movl 12(%esp),%ecx
+ movl 16(%esp),%edx
+ testl %edx,%edx
+ jmp L2 /* Jump into the loop! */
+
+ .align 2,0x90
+L1: incl %eax
+ incl %ecx
+ decl %edx
+L2: jz L4 /* strings are equal */
+ movb (%eax),%bl
+ testb %bl,%bl
+ jz L3
+ cmpb %bl,(%ecx)
+ jne L3
+
+/*
+ * XXX it might be best to move the next 4 instructions to the end of the
+ * unrolled part of the loop. The unrolled part would then be
+ * movb n(%eax),%bl; testb %bl, %bl; je L3; cmpb n(%ecx); jne L3
+ * or maybe better
+ * movb n(%eax),%bl; cmpb n(%ecx); jne L3; testb %bl,%bl; je return_0
+ * for n = 0, 1, ..., 8. The end of the loop would be
+ * L1: addl $8,%eax; addl $8,%ecx; subl $8,%edx; cmpl $8,%edx; jae Lx
+ * where residual counts of 0 to 7 are handled at Lx. However, this would
+ * be slower for short strings. Cache effects are probably not so
+ * important because we are only handling a byte at a time.
+ */
+ incl %eax
+ incl %ecx
+ decl %edx
+ jz L4
+ movb (%eax),%bl
+ testb %bl,%bl
+ jz L3
+ cmpb %bl,(%ecx)
+ jne L3
+
+ incl %eax
+ incl %ecx
+ decl %edx
+ jz L4
+ movb (%eax),%bl
+ testb %bl,%bl
+ jz L3
+ cmpb %bl,(%ecx)
+ jne L3
+
+ incl %eax
+ incl %ecx
+ decl %edx
+ jz L4
+ movb (%eax),%bl
+ testb %bl,%bl
+ jz L3
+ cmpb %bl,(%ecx)
+ jne L3
+
+ incl %eax
+ incl %ecx
+ decl %edx
+ jz L4
+ movb (%eax),%bl
+ testb %bl,%bl
+ jz L3
+ cmpb %bl,(%ecx)
+ jne L3
+
+ incl %eax
+ incl %ecx
+ decl %edx
+ jz L4
+ movb (%eax),%bl
+ testb %bl,%bl
+ jz L3
+ cmpb %bl,(%ecx)
+ jne L3
+
+ incl %eax
+ incl %ecx
+ decl %edx
+ jz L4
+ movb (%eax),%bl
+ testb %bl,%bl
+ jz L3
+ cmpb %bl,(%ecx)
+ jne L3
+
+ incl %eax
+ incl %ecx
+ decl %edx
+ jz L4
+ movb (%eax),%bl
+ testb %bl,%bl
+ jz L3
+ cmpb %bl,(%ecx)
+ je L1
+
+ .align 2,0x90
+L3: movzbl (%eax),%eax /* unsigned comparison */
+ movzbl (%ecx),%ecx
+ subl %ecx,%eax
+ popl %ebx
+ ret
+ .align 2,0x90
+L4: xorl %eax,%eax
+ popl %ebx
+ ret
diff --git a/lib/libc/i386/string/strrchr.S b/lib/libc/i386/string/strrchr.S
new file mode 100644
index 0000000..d62039f
--- /dev/null
+++ b/lib/libc/i386/string/strrchr.S
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1993 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * strrchr(s, c)
+ * return a pointer to the last occurance of the character c in
+ * string s, or NULL if c does not occur in the string.
+ *
+ * %edx - pointer iterating through string
+ * %eax - pointer to last occurance of 'c'
+ * %cl - character we're comparing against
+ * %bl - character at %edx
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+ENTRY(strrchr)
+ pushl %ebx
+ movl 8(%esp),%edx
+ movb 12(%esp),%cl
+ xorl %eax,%eax /* init pointer to null */
+ .align 2,0x90
+L1:
+ movb (%edx),%bl
+ cmpb %bl,%cl
+ jne L2
+ movl %edx,%eax
+L2:
+ incl %edx
+ testb %bl,%bl /* null terminator??? */
+ jne L1
+ popl %ebx
+ ret
diff --git a/lib/libc/i386/string/swab.S b/lib/libc/i386/string/swab.S
new file mode 100644
index 0000000..80578af
--- /dev/null
+++ b/lib/libc/i386/string/swab.S
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif
+
+#include "DEFS.h"
+
+/*
+ * void
+ * swab (const void *src, void *dst, size_t len)
+ * copy len bytes from src to dst, swapping adjacent bytes
+ *
+ * On the i486, this code is negligibly faster than the code generated
+ * by gcc at about half the size. If my i386 databook is correct, it
+ * should be considerably faster than the gcc code on a i386.
+ *
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+ENTRY(swab)
+ pushl %esi
+ pushl %edi
+ movl 12(%esp),%esi
+ movl 16(%esp),%edi
+ movl 20(%esp),%ecx
+
+ cld # set direction forward
+
+ shrl $1,%ecx
+ testl $7,%ecx # copy first group of 1 to 7 words
+ jz L2 # while swaping alternate bytes.
+ .align 2,0x90
+L1: lodsw
+ rorw $8,%ax
+ stosw
+ decl %ecx
+ testl $7,%ecx
+ jnz L1
+
+L2: shrl $3,%ecx # copy remainder 8 words at a time
+ jz L4 # while swapping alternate bytes.
+ .align 2,0x90
+L3: lodsw
+ rorw $8,%ax
+ stosw
+ lodsw
+ rorw $8,%ax
+ stosw
+ lodsw
+ rorw $8,%ax
+ stosw
+ lodsw
+ rorw $8,%ax
+ stosw
+ lodsw
+ rorw $8,%ax
+ stosw
+ lodsw
+ rorw $8,%ax
+ stosw
+ lodsw
+ rorw $8,%ax
+ stosw
+ lodsw
+ rorw $8,%ax
+ stosw
+ decl %ecx
+ jnz L3
+
+L4: popl %edi
+ popl %esi
+ ret
diff --git a/lib/libc/i386/sys/Makefile.inc b/lib/libc/i386/sys/Makefile.inc
new file mode 100644
index 0000000..c1c3d2d
--- /dev/null
+++ b/lib/libc/i386/sys/Makefile.inc
@@ -0,0 +1,28 @@
+# from: Makefile.inc,v 1.1 1993/09/03 19:04:23 jtc Exp
+# $FreeBSD$
+
+SRCS+= i386_get_ioperm.c i386_get_ldt.c i386_set_ioperm.c i386_set_ldt.c \
+ i386_vm86.c
+
+MDASM= Ovfork.S brk.S cerror.S exect.S fork.S pipe.S ptrace.S reboot.S \
+ rfork.S sbrk.S setlogin.S sigreturn.S syscall.S
+
+# Don't generate default code for these syscalls:
+NOASM= __semctl.o break.o exit.o ftruncate.o getdomainname.o getlogin.o \
+ lseek.o mlockall.o mmap.o msgctl.o msgget.o msgrcv.o msgsnd.o \
+ munlockall.o openbsd_poll.o pread.o pwrite.o semconfig.o semget.o \
+ semop.o setdomainname.o shmat.o shmctl.o shmdt.o shmget.o sstk.o \
+ thr_sleep.o thr_wakeup.o truncate.o uname.o vfork.o yield.o
+
+PSEUDO= _getlogin.o
+
+# Pseudo syscalls that are renamed as _thread_sys_{pseudo} when
+# building libc_r.
+PSEUDOR= _exit.o
+
+.if ${LIB} == "c"
+MAN2+= i386_get_ioperm.2 i386_get_ldt.2 i386_vm86.2
+
+MLINKS+=i386_get_ioperm.2 i386_set_ioperm.2
+MLINKS+=i386_get_ldt.2 i386_set_ldt.2
+.endif
diff --git a/lib/libc/i386/sys/Ovfork.S b/lib/libc/i386/sys/Ovfork.S
new file mode 100644
index 0000000..30d7fd1
--- /dev/null
+++ b/lib/libc/i386/sys/Ovfork.S
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "DEFS.h"
+#include "SYS.h"
+
+/*
+ * pid = vfork();
+ *
+ * %edx == 0 in parent process, %edx == 1 in child process.
+ * %eax == pid of child in parent, %eax == pid of parent in child.
+ *
+ */
+
+#ifdef _THREAD_SAFE
+ENTRY(_thread_sys_vfork)
+#else
+ENTRY(vfork)
+#endif
+ popl %ecx /* my rta into ecx */
+ lea SYS_vfork,%eax
+ KERNCALL
+ jb 2f
+ cmpl $0,%edx /* parent process? */
+ je 1f /* yes */
+ movl $0,%eax
+1:
+ jmp %ecx
+2:
+ pushl %ecx
+ PIC_PROLOGUE
+ jmp PIC_PLT(HIDENAME(cerror))
diff --git a/lib/libc/i386/sys/brk.S b/lib/libc/i386/sys/brk.S
new file mode 100644
index 0000000..5726675
--- /dev/null
+++ b/lib/libc/i386/sys/brk.S
@@ -0,0 +1,91 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ .globl HIDENAME(curbrk)
+ .globl HIDENAME(minbrk)
+ENTRY(_brk)
+ jmp ok
+
+ENTRY(brk)
+#ifdef PIC
+ movl 4(%esp),%eax
+ PIC_PROLOGUE
+ movl PIC_GOT(HIDENAME(curbrk)),%edx # set up GOT addressing
+ movl PIC_GOT(HIDENAME(minbrk)),%ecx #
+ PIC_EPILOGUE
+ cmpl %eax,(%ecx)
+ jbe ok
+ movl (%ecx),%eax
+ movl %eax,4(%esp)
+ok:
+ lea SYS_break,%eax
+ KERNCALL
+ jb err
+ movl 4(%esp),%eax
+ movl %eax,(%edx)
+ movl $0,%eax
+ ret
+err:
+ PIC_PROLOGUE
+ jmp PIC_PLT(HIDENAME(cerror))
+
+#else
+
+ movl 4(%esp),%eax
+ cmpl %eax,HIDENAME(minbrk)
+ jbe ok
+ movl HIDENAME(minbrk),%eax
+ movl %eax,4(%esp)
+ok:
+ lea SYS_break,%eax
+ KERNCALL
+ jb err
+ movl 4(%esp),%eax
+ movl %eax,HIDENAME(curbrk)
+ movl $0,%eax
+ ret
+err:
+ jmp HIDENAME(cerror)
+#endif
diff --git a/lib/libc/i386/sys/cerror.S b/lib/libc/i386/sys/cerror.S
new file mode 100644
index 0000000..31c3622
--- /dev/null
+++ b/lib/libc/i386/sys/cerror.S
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ .globl HIDENAME(cerror)
+
+ /*
+ * The __error() function is thread aware. For non-threaded
+ * programs and the initial threaded in threaded programs,
+ * it returns a pointer to the global errno variable.
+ */
+ .globl CNAME(__error)
+ .type CNAME(__error),@function
+HIDENAME(cerror):
+ pushl %eax
+#ifdef PIC
+ /* The caller must execute the PIC prologue before jumping to cerror. */
+ call PIC_PLT(CNAME(__error))
+ popl %ecx
+ PIC_EPILOGUE
+#else
+ call CNAME(__error)
+ popl %ecx
+#endif
+ movl %ecx,(%eax)
+ movl $-1,%eax
+ movl $-1,%edx
+ ret
+
diff --git a/lib/libc/i386/sys/exect.S b/lib/libc/i386/sys/exect.S
new file mode 100644
index 0000000..9f90060
--- /dev/null
+++ b/lib/libc/i386/sys/exect.S
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+#include <machine/psl.h>
+
+ENTRY(exect)
+ lea SYS_execve,%eax
+ pushf
+ popl %edx
+ orl $ PSL_T,%edx
+ pushl %edx
+ popf
+ KERNCALL
+ PIC_PROLOGUE
+ jmp PIC_PLT(HIDENAME(cerror)) /* exect(file, argv, env); */
diff --git a/lib/libc/i386/sys/fork.S b/lib/libc/i386/sys/fork.S
new file mode 100644
index 0000000..6c3cde8
--- /dev/null
+++ b/lib/libc/i386/sys/fork.S
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+PSYSCALL(fork)
+ cmpl $0,%edx /* parent, since %edx == 0 in parent, 1 in child */
+ je 1f
+ movl $0,%eax
+1:
+ ret /* pid = fork(); */
diff --git a/lib/libc/i386/sys/i386_get_ioperm.2 b/lib/libc/i386/sys/i386_get_ioperm.2
new file mode 100644
index 0000000..2d326b8
--- /dev/null
+++ b/lib/libc/i386/sys/i386_get_ioperm.2
@@ -0,0 +1,84 @@
+.\" Copyright (c) 1998 Jonathan Lemon
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 27, 1998
+.Os
+.Dt I386_GET_IOPERM 2
+.Sh NAME
+.Nm i386_get_ioperm ,
+.Nm i386_set_ioperm
+.Nd manage per-process access to the i386 I/O port space
+.Sh SYNOPSIS
+.Fd #include <machine/sysarch.h>
+.Ft int
+.Fn i386_get_ioperm "unsigned int start" "unsigned int *length" "int *enable"
+.Ft int
+.Fn i386_set_ioperm "unsigned int start" "unsigned int length" "int enable"
+.Sh DESCRIPTION
+.Fn i386_get_ioperm
+will return the permission for the process' I/O port space in the
+.Fa *enable
+argument. The port range starts at
+.Fa start
+and the number of contiguous entries will be returned in
+.Fa *length .
+.Pp
+.Fn i386_set_ioperm
+will set access to a range of I/O ports described by the
+.Fa start
+and
+.Fa length
+arguments to the state specified by the
+.Fa enable
+argument.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn i386_get_ioperm
+and
+.Fn i386_set_ioperm
+return the value of 0.
+Otherwise, a value of -1 is returned and the global
+variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn i386_get_ioperm
+and
+.Fn i386_set_ioperm
+will fail if:
+.Bl -tag -width [EINVAL]
+.It Bq Er EINVAL
+An invalid range was specified by the
+.Fa start
+or
+.Fa length
+arguments.
+.It Bq Er EPERM
+The caller of i386_set_ioperm was not the superuser.
+.El
+.Sh AUTHORS
+This man page was written by
+.An Jonathan Lemon .
diff --git a/lib/libc/i386/sys/i386_get_ioperm.c b/lib/libc/i386/sys/i386_get_ioperm.c
new file mode 100644
index 0000000..319ce57
--- /dev/null
+++ b/lib/libc/i386/sys/i386_get_ioperm.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1998 Jonathan Lemon
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <machine/sysarch.h>
+
+int
+i386_get_ioperm(unsigned int start, unsigned int *length, int *enable)
+{
+ struct i386_ioperm_args p;
+ int error;
+
+ p.start = start;
+ p.length = *length;
+ p.enable = *enable;
+
+ error = sysarch(I386_GET_IOPERM, (char *)&p);
+
+ *length = p.length;
+ *enable = p.enable;
+
+ return (error);
+}
diff --git a/lib/libc/i386/sys/i386_get_ldt.2 b/lib/libc/i386/sys/i386_get_ldt.2
new file mode 100644
index 0000000..fce57b6
--- /dev/null
+++ b/lib/libc/i386/sys/i386_get_ldt.2
@@ -0,0 +1,98 @@
+.\" Copyright (c) 1980, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)fork.2 6.5 (Berkeley) 3/10/91
+.\" $FreeBSD$
+.\"
+.Dd September 20, 1993
+.Dt I386_GET_LDT 2
+.Os FreeBSD
+.Sh NAME
+.Nm i386_get_ldt ,
+.Nm i386_set_ldt
+.Nd manage i386 per-process Local Descriptor Table entries
+.Sh SYNOPSIS
+.Fd #include <machine/segments.h>
+.Fd #include <machine/sysarch.h>
+.Ft int
+.Fn i386_get_ldt "int start_sel" "union descriptor *descs" "int num_sels"
+.Ft int
+.Fn i386_set_ldt "int start_sel" "union descriptor *descs" "int num_sels"
+.Sh DESCRIPTION
+.Fn i386_get_ldt
+will return the list of i386 descriptors that the process has in its
+LDT.
+.Fn i386_set_ldt
+will set a list of i386 descriptors for the current process in its
+LDT.
+Both routines accept a starting selector number
+.Fa start_sel
+, an array of memory that
+will contain the descriptors to be set or returned
+.Fa descs
+, and the number of entries to set or return
+.Fa num_sels .
+.Pp
+The argument
+.Fa descs
+can be either segment_descriptor or gate_descriptor and are defined in
+.Fd <i386/segments.h> .
+These structures are defined by the architecture
+as disjoint bit-fields, so care must be taken in constructing them.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn i386_get_ldt
+returns the number of descriptors currently in the LDT.
+.Fn i386_set_ldt
+returns the first selector set.
+Otherwise, a value of -1 is returned and the global
+variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn i386_get_ldt
+and
+.Fn i386_set_ldt
+will fail if:
+.Bl -tag -width [EINVAL]
+.It Bq Er EINVAL
+An inappropriate parameter was used for
+.Fa start_sel
+or
+.Fa num_sels .
+.It Bq Er EACCES
+The caller attempted to use a descriptor that would
+circumvent protection or cause a failure.
+.El
+.Sh REFERENCES
+i386 Microprocessor Programmer's Reference Manual, Intel
+.Sh WARNING
+You can really hose your process using this.
diff --git a/lib/libc/i386/sys/i386_get_ldt.c b/lib/libc/i386/sys/i386_get_ldt.c
new file mode 100644
index 0000000..e2e6bd4
--- /dev/null
+++ b/lib/libc/i386/sys/i386_get_ldt.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1993 John Brezak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <sys/cdefs.h>
+#include <machine/segments.h>
+#include <machine/sysarch.h>
+
+int
+i386_get_ldt(int start, union descriptor *descs, int num)
+{
+ struct i386_ldt_args p;
+
+ p.start = start;
+ p.descs = descs;
+ p.num = num;
+
+ return sysarch(I386_GET_LDT, (char *)&p);
+}
diff --git a/lib/libc/i386/sys/i386_set_ioperm.c b/lib/libc/i386/sys/i386_set_ioperm.c
new file mode 100644
index 0000000..1eca62b
--- /dev/null
+++ b/lib/libc/i386/sys/i386_set_ioperm.c
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 1998 Jonathan Lemon
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <machine/sysarch.h>
+
+int
+i386_set_ioperm(unsigned int start, unsigned int length, int enable)
+{
+ struct i386_ioperm_args p;
+
+ p.start = start;
+ p.length = length;
+ p.enable = enable;
+
+ return (sysarch(I386_SET_IOPERM, (char *)&p));
+}
diff --git a/lib/libc/i386/sys/i386_set_ldt.c b/lib/libc/i386/sys/i386_set_ldt.c
new file mode 100644
index 0000000..97fc318
--- /dev/null
+++ b/lib/libc/i386/sys/i386_set_ldt.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1993 John Brezak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <sys/cdefs.h>
+#include <machine/segments.h>
+#include <machine/sysarch.h>
+
+int
+i386_set_ldt(int start, union descriptor *descs, int num)
+{
+ struct i386_ldt_args p;
+
+ p.start = start;
+ p.descs = descs;
+ p.num = num;
+
+ return sysarch(I386_SET_LDT, (char *)&p);
+}
diff --git a/lib/libc/i386/sys/i386_vm86.2 b/lib/libc/i386/sys/i386_vm86.2
new file mode 100644
index 0000000..4dc0d52
--- /dev/null
+++ b/lib/libc/i386/sys/i386_vm86.2
@@ -0,0 +1,96 @@
+.\" Copyright (c) 1998 Jonathan Lemon
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 27, 1998
+.Os
+.Dt I386_VM86 2
+.Sh NAME
+.Nm i386_vm86
+.Nd control vm86-related functions
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <machine/sysarch.h>
+.Fd #include <machine/vm86.h>
+.Ft int
+.Fn i386_vm86 "int function" "void *data"
+.Sh DESCRIPTION
+.Fn i386_vm86
+is used to call various vm86 related functions.
+.Fa function
+can be one of the following values:
+.Bl -tag -offset indent -width VM86_SET_VME
+.It Dv VM86_INIT
+This will initialize the kernel's vm86 parameter area for the
+process, and permit the process to make vm86 calls.
+.Fa data
+points to the following structure:
+.Bd -literal
+struct vm86_init_args {
+ int debug;
+ int cpu_type;
+ u_char int_map[32];
+};
+.Ed
+.Pp
+.Fa debug
+is used to turn on debugging code.
+.Fa cpu_type
+controls the type of CPU being emulated, and is currently unimplemented.
+.Fa int_map
+is a bitmap which determines whether vm86 interrupts should be handled
+in vm86 mode, or reflected back to the process. If the
+.Em Nth
+bit is set, the interrupt will be reflected to the process, otherwise
+it will be dispatched by the vm86 interrupt table.
+.\" .It Dv VM86_SET_VME
+.\" .It Dv VM86_GET_VME
+.\" .It Dv VM86_INTCALL
+.El
+.Pp
+vm86 mode is entered by calling
+.Xr sigreturn 2
+with the correct machine context for vm86, and with the
+.Em PSL_VM
+bit set. Control returns to the process upon delivery of a signal.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn i386_vm86
+will return the value of 0.
+Otherwise, a value of -1 is returned and the global
+variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn i386_vm86
+will fail if:
+.Bl -tag -width [ENOMEM]
+.It Bq Er EINVAL
+The kernel does not have vm86 support, or an invalid function was specified.
+.It Bq Er ENOMEM
+There is not enough memory to initialize the kernel data structures.
+.Sh AUTHORS
+This man page was written by
+.An Jonathan Lemon .
diff --git a/lib/libc/i386/sys/i386_vm86.c b/lib/libc/i386/sys/i386_vm86.c
new file mode 100644
index 0000000..3e2c842
--- /dev/null
+++ b/lib/libc/i386/sys/i386_vm86.c
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 1998 Jonathan Lemon
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <machine/sysarch.h>
+
+int
+i386_vm86(int fcn, void *data)
+{
+ struct i386_vm86_args p;
+
+ p.sub_op = fcn;
+ p.sub_args = (char *)data;
+
+ return (sysarch(I386_VM86, (void *)&p));
+}
diff --git a/lib/libc/i386/sys/pipe.S b/lib/libc/i386/sys/pipe.S
new file mode 100644
index 0000000..1684611
--- /dev/null
+++ b/lib/libc/i386/sys/pipe.S
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+PSYSCALL(pipe)
+ movl 4(%esp),%ecx
+ movl %eax,(%ecx)
+ movl %edx,4(%ecx)
+ movl $0,%eax
+ ret
diff --git a/lib/libc/i386/sys/ptrace.S b/lib/libc/i386/sys/ptrace.S
new file mode 100644
index 0000000..7f5e149
--- /dev/null
+++ b/lib/libc/i386/sys/ptrace.S
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ENTRY(ptrace)
+ xorl %eax,%eax
+#ifdef PIC
+ PIC_PROLOGUE
+ movl PIC_GOT(CNAME(errno)),%edx
+ movl %eax,(%edx)
+ PIC_EPILOGUE
+#else
+ movl %eax,CNAME(errno)
+#endif
+ lea SYS_ptrace,%eax
+ KERNCALL
+ jb err
+ ret
+err:
+ PIC_PROLOGUE
+ jmp PIC_PLT(HIDENAME(cerror))
diff --git a/lib/libc/i386/sys/reboot.S b/lib/libc/i386/sys/reboot.S
new file mode 100644
index 0000000..4e39068
--- /dev/null
+++ b/lib/libc/i386/sys/reboot.S
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+SYSCALL(reboot)
+ iret
diff --git a/lib/libc/i386/sys/rfork.S b/lib/libc/i386/sys/rfork.S
new file mode 100644
index 0000000..b3e20e4
--- /dev/null
+++ b/lib/libc/i386/sys/rfork.S
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+PSYSCALL(rfork)
+ cmpl $0,%edx /* parent, since %edx == 0 in parent, 1 in child */
+ je 1f
+ movl $0,%eax
+1:
+ ret /* pid = rfork(); */
diff --git a/lib/libc/i386/sys/sbrk.S b/lib/libc/i386/sys/sbrk.S
new file mode 100644
index 0000000..f7aae35
--- /dev/null
+++ b/lib/libc/i386/sys/sbrk.S
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ .globl CNAME(end)
+ .globl HIDENAME(minbrk)
+ .globl HIDENAME(curbrk)
+
+ .data
+HIDENAME(minbrk): .long CNAME(end)
+HIDENAME(curbrk): .long CNAME(end)
+ .text
+
+ENTRY(sbrk)
+#ifdef PIC
+ movl 4(%esp),%ecx
+ PIC_PROLOGUE
+ movl PIC_GOT(HIDENAME(curbrk)),%edx
+ movl (%edx),%eax
+ PIC_EPILOGUE
+ testl %ecx,%ecx
+ jz back
+ addl %eax,4(%esp)
+ lea SYS_break,%eax
+ KERNCALL
+ jb err
+ PIC_PROLOGUE
+ movl PIC_GOT(HIDENAME(curbrk)),%edx
+ movl (%edx),%eax
+ addl %ecx,(%edx)
+ PIC_EPILOGUE
+back:
+ ret
+err:
+ PIC_PROLOGUE
+ jmp PIC_PLT(HIDENAME(cerror))
+
+#else /* !PIC */
+
+ movl 4(%esp),%ecx
+ movl HIDENAME(curbrk),%eax
+ testl %ecx,%ecx
+ jz back
+ addl %eax,4(%esp)
+ lea SYS_break,%eax
+ KERNCALL
+ jb err
+ movl HIDENAME(curbrk),%eax
+ addl %ecx,HIDENAME(curbrk)
+back:
+ ret
+err:
+ jmp HIDENAME(cerror)
+#endif /* PIC */
diff --git a/lib/libc/i386/sys/setlogin.S b/lib/libc/i386/sys/setlogin.S
new file mode 100644
index 0000000..a4d74b0
--- /dev/null
+++ b/lib/libc/i386/sys/setlogin.S
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "SYS.h"
+
+.globl CNAME(_logname_valid) /* in getlogin() */
+
+SYSCALL(setlogin)
+#ifdef PIC
+ PIC_PROLOGUE
+ pushl %eax
+ movl PIC_GOT(CNAME(_logname_valid)),%eax
+ movl $0,(%eax)
+ popl %eax
+ PIC_EPILOGUE
+#else
+ movl $0,CNAME(_logname_valid)
+#endif
+ ret /* setlogin(name) */
diff --git a/lib/libc/i386/sys/sigreturn.S b/lib/libc/i386/sys/sigreturn.S
new file mode 100644
index 0000000..7405c34
--- /dev/null
+++ b/lib/libc/i386/sys/sigreturn.S
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+/*
+ * NOTE: If the profiling ENTRY() code ever changes any registers, they
+ * must be saved. On FreeBSD, this is not the case.
+ */
+
+PSYSCALL(sigreturn)
+ ret
diff --git a/lib/libc/i386/sys/syscall.S b/lib/libc/i386/sys/syscall.S
new file mode 100644
index 0000000..b5516f0
--- /dev/null
+++ b/lib/libc/i386/sys/syscall.S
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ENTRY(syscall)
+ pop %ecx /* rta */
+ pop %eax /* syscall number */
+ push %ecx
+ KERNCALL
+ push %ecx /* need to push a word to keep stack frame intact
+ upon return; the word must be the return address. */
+ jb 1f
+ ret
+1:
+ PIC_PROLOGUE
+ jmp PIC_PLT(HIDENAME(cerror))
diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h
new file mode 100644
index 0000000..1e20bc7
--- /dev/null
+++ b/lib/libc/include/libc_private.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ * Private definitions for libc, libc_r and libpthread.
+ *
+ */
+
+#ifndef _LIBC_PRIVATE_H_
+#define _LIBC_PRIVATE_H_
+
+/*
+ * This global flag is non-zero when a process has created one
+ * or more threads. It is used to avoid calling locking functions
+ * when they are not required.
+ */
+extern int __isthreaded;
+
+/*
+ * File lock contention is difficult to diagnose without knowing
+ * where locks were set. Allow a debug library to be built which
+ * records the source file and line number of each lock call.
+ */
+#ifdef _FLOCK_DEBUG
+#define _FLOCKFILE(x) _flockfile_debug(x, __FILE__, __LINE__)
+#else
+#define _FLOCKFILE(x) flockfile(x)
+#endif
+
+/*
+ * Macros for locking and unlocking FILEs. These test if the
+ * process is threaded to avoid locking when not required.
+ */
+#define FLOCKFILE(fp) if (__isthreaded) _FLOCKFILE(fp)
+#define FUNLOCKFILE(fp) if (__isthreaded) funlockfile(fp)
+
+#endif /* _LIBC_PRIVATE_H_ */
diff --git a/lib/libc/include/spinlock.h b/lib/libc/include/spinlock.h
new file mode 100644
index 0000000..d81615d
--- /dev/null
+++ b/lib/libc/include/spinlock.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ * Lock definitions used in both libc and libpthread.
+ *
+ */
+
+#ifndef _SPINLOCK_H_
+#define _SPINLOCK_H_
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+/*
+ * Lock structure with room for debugging information.
+ */
+typedef struct {
+ volatile long access_lock;
+ volatile long lock_owner;
+ volatile char *fname;
+ volatile int lineno;
+} spinlock_t;
+
+#define _SPINLOCK_INITIALIZER { 0, 0, 0, 0 }
+
+#define _SPINUNLOCK(_lck) (_lck)->access_lock = 0
+#ifdef _LOCK_DEBUG
+#define _SPINLOCK(_lck) _spinlock_debug(_lck, __FILE__, __LINE__)
+#else
+#define _SPINLOCK(_lck) _spinlock(_lck)
+#endif
+
+/*
+ * Thread function prototype definitions:
+ */
+__BEGIN_DECLS
+long _atomic_lock __P((volatile long *));
+void _spinlock __P((spinlock_t *));
+void _spinlock_debug __P((spinlock_t *, char *, int));
+__END_DECLS
+
+#endif /* _SPINLOCK_H_ */
diff --git a/lib/libc/locale/Makefile.inc b/lib/libc/locale/Makefile.inc
new file mode 100644
index 0000000..fb3cb39
--- /dev/null
+++ b/lib/libc/locale/Makefile.inc
@@ -0,0 +1,26 @@
+# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+# locale sources
+.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/locale ${.CURDIR}/../libc/locale
+
+SRCS+= ansi.c big5.c collate.c collcmp.c euc.c frune.c isctype.c \
+ lconv.c localeconv.c mbrune.c mskanji.c nomacros.c none.c rune.c \
+ runetype.c setinvalidrune.c setlocale.c setrunelocale.c table.c \
+ tolower.c toupper.c utf2.c
+
+.if ${LIB} == "c"
+MAN3+= ctype.3 isalnum.3 isalpha.3 isascii.3 isblank.3 iscntrl.3 \
+ isdigit.3 isgraph.3 islower.3 isprint.3 ispunct.3 isspace.3 \
+ isupper.3 isxdigit.3 mbrune.3 multibyte.3 rune.3 setlocale.3 \
+ toascii.3 tolower.3 toupper.3
+MAN4+= euc.4 utf2.4
+
+MLINKS+=mbrune.3 mbmb.3 mbrune.3 mbrrune.3
+MLINKS+=multibyte.3 mblen.3 multibyte.3 mbstowcs.3 multibyte.3 mbtowc.3 \
+ multibyte.3 wcstombs.3 multibyte.3 wctomb.3
+MLINKS+=rune.3 fgetrune.3 rune.3 fputrune.3 rune.3 fungetrune.3 \
+ rune.3 setinvalidrune.3 rune.3 setrunelocale.3 rune.3 sgetrune.3 \
+ rune.3 sputrune.3
+MLINKS+=setlocale.3 localeconv.3
+.endif
diff --git a/lib/libc/locale/ansi.c b/lib/libc/locale/ansi.c
new file mode 100644
index 0000000..c0871fe
--- /dev/null
+++ b/lib/libc/locale/ansi.c
@@ -0,0 +1,151 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ansi.c 8.1 (Berkeley) 6/27/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <limits.h>
+#include <stddef.h>
+#include <rune.h>
+
+int
+mblen(s, n)
+ const char *s;
+ size_t n;
+{
+ char const *e;
+
+ if (s == 0 || *s == 0)
+ return (0); /* No support for state dependent encodings. */
+
+ if (sgetrune(s, n, &e) == _INVALID_RUNE)
+ return (s - e);
+ return (e - s);
+}
+
+int
+mbtowc(pwc, s, n)
+ wchar_t *pwc;
+ const char *s;
+ size_t n;
+{
+ char const *e;
+ rune_t r;
+
+ if (s == 0 || *s == 0)
+ return (0); /* No support for state dependent encodings. */
+
+ if ((r = sgetrune(s, n, &e)) == _INVALID_RUNE)
+ return (s - e);
+ if (pwc)
+ *pwc = r;
+ return (e - s);
+}
+
+int
+wctomb(s, wchar)
+ char *s;
+ wchar_t wchar;
+{
+ char *e;
+
+ if (s == 0)
+ return (0); /* No support for state dependent encodings. */
+
+ if (wchar == 0) {
+ *s = 0;
+ return (1);
+ }
+
+ sputrune(wchar, s, MB_CUR_MAX, &e);
+ return (e ? e - s : -1);
+}
+
+size_t
+mbstowcs(pwcs, s, n)
+ wchar_t *pwcs;
+ const char *s;
+ size_t n;
+{
+ char const *e;
+ int cnt = 0;
+
+ if (!pwcs || !s)
+ return (-1);
+
+ while (n-- > 0) {
+ *pwcs = sgetrune(s, MB_LEN_MAX, &e);
+ if (*pwcs == _INVALID_RUNE)
+ return (-1);
+ if (*pwcs++ == 0)
+ break;
+ s = e;
+ ++cnt;
+ }
+ return (cnt);
+}
+
+size_t
+wcstombs(s, pwcs, n)
+ char *s;
+ const wchar_t *pwcs;
+ size_t n;
+{
+ char *e;
+ int cnt, nb;
+
+ if (!pwcs || !s || n > INT_MAX)
+ return (-1);
+
+ nb = n;
+ cnt = 0;
+ while (nb > 0) {
+ if (*pwcs == 0) {
+ *s = 0;
+ break;
+ }
+ if (!sputrune(*pwcs++, s, nb, &e))
+ return (-1); /* encoding error */
+ if (!e) /* too long */
+ return (cnt);
+ cnt += e - s;
+ nb -= e - s;
+ s = e;
+ }
+ return (cnt);
+}
diff --git a/lib/libc/locale/big5.c b/lib/libc/locale/big5.c
new file mode 100644
index 0000000..9294f0c
--- /dev/null
+++ b/lib/libc/locale/big5.c
@@ -0,0 +1,120 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef XPG4
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)big5.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <rune.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+rune_t _BIG5_sgetrune __P((const char *, size_t, char const **));
+int _BIG5_sputrune __P((rune_t, char *, size_t, char **));
+
+int
+_BIG5_init(rl)
+ _RuneLocale *rl;
+{
+ rl->sgetrune = _BIG5_sgetrune;
+ rl->sputrune = _BIG5_sputrune;
+ _CurrentRuneLocale = rl;
+ __mb_cur_max = 2;
+ return (0);
+}
+
+static inline int
+_big5_check(c)
+ u_int c;
+{
+ c &= 0xff;
+ return ((c >= 0xa1 && c <= 0xfe) ? 2 : 1);
+}
+
+rune_t
+_BIG5_sgetrune(string, n, result)
+ const char *string;
+ size_t n;
+ char const **result;
+{
+ rune_t rune = 0;
+ int len;
+
+ if (n < 1 || (len = _big5_check(*string)) > n) {
+ if (result)
+ *result = string;
+ return (_INVALID_RUNE);
+ }
+ while (--len >= 0)
+ rune = (rune << 8) | ((u_int)(*string++) & 0xff);
+ if (result)
+ *result = string;
+ return rune;
+}
+
+int
+_BIG5_sputrune(c, string, n, result)
+ rune_t c;
+ char *string, **result;
+ size_t n;
+{
+ if (c & 0x8000) {
+ if (n >= 2) {
+ string[0] = (c >> 8) & 0xff;
+ string[1] = c & 0xff;
+ if (result)
+ *result = string + 2;
+ return (2);
+ }
+ }
+ else {
+ if (n >= 1) {
+ *string = c & 0xff;
+ if (result)
+ *result = string + 1;
+ return (1);
+ }
+ }
+ if (result)
+ *result = string;
+ return (0);
+
+}
+#endif /* XPG4 */
diff --git a/lib/libc/locale/collate.c b/lib/libc/locale/collate.c
new file mode 100644
index 0000000..cfa7cfe
--- /dev/null
+++ b/lib/libc/locale/collate.c
@@ -0,0 +1,211 @@
+/*-
+ * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
+ * at Electronni Visti IA, Kiev, Ukraine.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <rune.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sysexits.h>
+#include "collate.h"
+#include "setlocale.h"
+
+int __collate_load_error = 1;
+int __collate_substitute_nontrivial;
+char __collate_version[STR_LEN];
+u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN];
+struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1];
+struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE];
+
+#define FREAD(a, b, c, d) \
+ do { \
+ if(fread(a, b, c, d) != c) { \
+ fclose(d); \
+ return -1; \
+ } \
+ } while(0)
+
+void __collate_err(int ex, const char *f) __dead2;
+
+int
+__collate_load_tables(encoding)
+ char *encoding;
+{
+ char buf[PATH_MAX];
+ FILE *fp;
+ int i, save_load_error;
+
+ save_load_error = __collate_load_error;
+ __collate_load_error = 1;
+ if (!encoding) {
+ __collate_load_error = save_load_error;
+ return -1;
+ }
+ if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX"))
+ return 0;
+ if (!_PathLocale) {
+ __collate_load_error = save_load_error;
+ return -1;
+ }
+ /* Range checking not needed, encoding has fixed size */
+ (void) strcpy(buf, _PathLocale);
+ (void) strcat(buf, "/");
+ (void) strcat(buf, encoding);
+ (void) strcat(buf, "/LC_COLLATE");
+ if ((fp = fopen(buf, "r")) == NULL) {
+ __collate_load_error = save_load_error;
+ return -1;
+ }
+ FREAD(__collate_version, sizeof(__collate_version), 1, fp);
+ if (strcmp(__collate_version, COLLATE_VERSION) != 0) {
+ fclose(fp);
+ return -1;
+ }
+ FREAD(__collate_substitute_table, sizeof(__collate_substitute_table),
+ 1, fp);
+ FREAD(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1,
+ fp);
+ FREAD(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1,
+ fp);
+ fclose(fp);
+ __collate_load_error = 0;
+
+ __collate_substitute_nontrivial = 0;
+ for (i = 0; i < UCHAR_MAX + 1; i++) {
+ if (__collate_substitute_table[i][0] != i ||
+ __collate_substitute_table[i][1] != 0) {
+ __collate_substitute_nontrivial = 1;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+u_char *
+__collate_substitute(s)
+ const u_char *s;
+{
+ int dest_len, len, nlen;
+ int delta = strlen(s);
+ u_char *dest_str = NULL;
+
+ if(s == NULL || *s == '\0')
+ return __collate_strdup("");
+ delta += delta / 8;
+ dest_str = malloc(dest_len = delta);
+ if(dest_str == NULL)
+ __collate_err(EX_OSERR, __FUNCTION__);
+ len = 0;
+ while(*s) {
+ nlen = len + strlen(__collate_substitute_table[*s]);
+ if (dest_len <= nlen) {
+ dest_str = reallocf(dest_str, dest_len = nlen + delta);
+ if(dest_str == NULL)
+ __collate_err(EX_OSERR, __FUNCTION__);
+ }
+ strcpy(dest_str + len, __collate_substitute_table[*s++]);
+ len = nlen;
+ }
+ return dest_str;
+}
+
+void
+__collate_lookup(t, len, prim, sec)
+ const u_char *t;
+ int *len, *prim, *sec;
+{
+ struct __collate_st_chain_pri *p2;
+
+ *len = 1;
+ *prim = *sec = 0;
+ for(p2 = __collate_chain_pri_table; p2->str[0]; p2++) {
+ if(strncmp(t, p2->str, strlen(p2->str)) == 0) {
+ *len = strlen(p2->str);
+ *prim = p2->prim;
+ *sec = p2->sec;
+ return;
+ }
+ }
+ *prim = __collate_char_pri_table[*t].prim;
+ *sec = __collate_char_pri_table[*t].sec;
+}
+
+u_char *
+__collate_strdup(s)
+ u_char *s;
+{
+ u_char *t = strdup(s);
+
+ if (t == NULL)
+ __collate_err(EX_OSERR, __FUNCTION__);
+ return t;
+}
+
+void
+__collate_err(int ex, const char *f)
+{
+ extern char *__progname; /* Program name, from crt0. */
+ const char *s;
+ int serrno = errno;
+
+ s = __progname;
+ write(STDERR_FILENO, s, strlen(s));
+ write(STDERR_FILENO, ": ", 2);
+ s = f;
+ write(STDERR_FILENO, s, strlen(s));
+ write(STDERR_FILENO, ": ", 2);
+ s = strerror(serrno);
+ write(STDERR_FILENO, s, strlen(s));
+ write(STDERR_FILENO, "\n", 1);
+ exit(ex);
+}
+
+#ifdef COLLATE_DEBUG
+void
+__collate_print_tables()
+{
+ int i;
+ struct __collate_st_chain_pri *p2;
+
+ printf("Substitute table:\n");
+ for (i = 0; i < UCHAR_MAX + 1; i++)
+ if (i != *__collate_substitute_table[i])
+ printf("\t'%c' --> \"%s\"\n", i,
+ __collate_substitute_table[i]);
+ printf("Chain priority table:\n");
+ for (p2 = __collate_chain_pri_table; p2->str[0]; p2++)
+ printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec);
+ printf("Char priority table:\n");
+ for (i = 0; i < UCHAR_MAX + 1; i++)
+ printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim,
+ __collate_char_pri_table[i].sec);
+}
+#endif
diff --git a/lib/libc/locale/collate.h b/lib/libc/locale/collate.h
new file mode 100644
index 0000000..ae6317c
--- /dev/null
+++ b/lib/libc/locale/collate.h
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
+ * at Electronni Visti IA, Kiev, Ukraine.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef COLLATE_H_INCLUDED
+#define COLLATE_H_INCLUDED
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <limits.h>
+
+#define STR_LEN 10
+#define TABLE_SIZE 100
+#define COLLATE_VERSION "1.0\n"
+
+struct __collate_st_char_pri {
+ int prim, sec;
+};
+struct __collate_st_chain_pri {
+ u_char str[STR_LEN];
+ int prim, sec;
+};
+
+extern int __collate_load_error;
+extern int __collate_substitute_nontrivial;
+extern char __collate_version[STR_LEN];
+extern u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN];
+extern struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1];
+extern struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE];
+
+__BEGIN_DECLS
+u_char *__collate_strdup __P((u_char *));
+u_char *__collate_substitute __P((const u_char *));
+int __collate_load_tables __P((char *));
+void __collate_lookup __P((const u_char *, int *, int *, int *));
+int __collate_range_cmp __P((int, int));
+#ifdef COLLATE_DEBUG
+void __collate_print_tables __P((void));
+#endif
+__END_DECLS
+
+#endif /* not COLLATE_H_INCLUDED */
diff --git a/lib/libc/locale/collcmp.c b/lib/libc/locale/collcmp.c
new file mode 100644
index 0000000..ae783d0
--- /dev/null
+++ b/lib/libc/locale/collcmp.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 1996 by Andrey A. Chernov, Moscow, Russia.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#define ASCII_COMPATIBLE_COLLATE /* see usr.bin/colldef/data */
+
+#include <string.h>
+#include "collate.h"
+#ifndef ASCII_COMPATIBLE_COLLATE
+#include <ctype.h>
+#endif
+
+/*
+ * Compare two characters converting collate information
+ * into ASCII-compatible range, it allows to handle
+ * "[a-z]"-type ranges with national characters.
+ */
+
+int __collate_range_cmp (c1, c2)
+ int c1, c2;
+{
+ static char s1[2], s2[2];
+ int ret;
+#ifndef ASCII_COMPATIBLE_COLLATE
+ int as1, as2, al1, al2;
+#endif
+
+ c1 &= UCHAR_MAX;
+ c2 &= UCHAR_MAX;
+ if (c1 == c2)
+ return (0);
+
+#ifndef ASCII_COMPATIBLE_COLLATE
+ as1 = isascii(c1);
+ as2 = isascii(c2);
+ al1 = isalpha(c1);
+ al2 = isalpha(c2);
+
+ if (as1 || as2 || al1 || al2) {
+ if ((as1 && as2) || (!al1 && !al2))
+ return (c1 - c2);
+ if (al1 && !al2) {
+ if (isupper(c1))
+ return ('A' - c2);
+ else
+ return ('a' - c2);
+ } else if (al2 && !al1) {
+ if (isupper(c2))
+ return (c1 - 'A');
+ else
+ return (c1 - 'a');
+ }
+ }
+#endif
+ s1[0] = c1;
+ s2[0] = c2;
+ if ((ret = strcoll(s1, s2)) != 0)
+ return (ret);
+ return (c1 - c2);
+}
diff --git a/lib/libc/locale/ctype.3 b/lib/libc/locale/ctype.3
new file mode 100644
index 0000000..ba7143b
--- /dev/null
+++ b/lib/libc/locale/ctype.3
@@ -0,0 +1,145 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ctype.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt CTYPE 3
+.Os
+.Sh NAME
+.Nm isalnum ,
+.Nm isalpha ,
+.Nm isascii ,
+.Nm isblank ,
+.Nm iscntrl ,
+.Nm isdigit ,
+.Nm isgraph ,
+.Nm ishexnumber ,
+.Nm isideogram ,
+.Nm islower ,
+.Nm isnumber ,
+.Nm isphonogram ,
+.Nm isprint ,
+.Nm ispunct ,
+.Nm isrune ,
+.Nm isspace ,
+.Nm isspecial ,
+.Nm isupper ,
+.Nm isxdigit ,
+.Nm toascii ,
+.Nm tolower ,
+.Nm toupper
+.Nd character classification macros
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn isalnum "int c"
+.Ft int
+.Fn isalpha "int c"
+.Ft int
+.Fn isascii "int c"
+.Ft int
+.Fn iscntrl "int c"
+.Ft int
+.Fn isdigit "int c"
+.Ft int
+.Fn isgraph "int c"
+.Ft int
+.Fn ishexnumber "int c"
+.Ft int
+.Fn isideogram "int c"
+.Ft int
+.Fn islower "int c"
+.Ft int
+.Fn isnumber "int c"
+.Ft int
+.Fn isphonogram "int c"
+.Ft int
+.Fn isspecial "int c"
+.Ft int
+.Fn isprint "int c"
+.Ft int
+.Fn ispunct "int c"
+.Ft int
+.Fn isrune "int c"
+.Ft int
+.Fn isspace "int c"
+.Ft int
+.Fn isupper "int c"
+.Ft int
+.Fn isxdigit "int c"
+.Ft int
+.Fn toascii "int c"
+.Ft int
+.Fn tolower "int c"
+.Ft int
+.Fn toupper "int c"
+.Sh DESCRIPTION
+The above functions perform character tests and conversions on the integer
+.Ar c .
+They are available as macros, defined in the include file
+.Aq Pa ctype.h ,
+or as true functions in the C library.
+See the specific manual pages for more information.
+.Sh SEE ALSO
+.Xr isalnum 3 ,
+.Xr isalpha 3 ,
+.Xr isascii 3 ,
+.Xr isblank 3 ,
+.Xr iscntrl 3 ,
+.Xr isdigit 3 ,
+.Xr isgraph 3 ,
+.Xr islower 3 ,
+.Xr isprint 3 ,
+.Xr ispunct 3 ,
+.Xr isspace 3 ,
+.Xr isupper 3 ,
+.Xr isxdigit 3 ,
+.Xr toascii 3 ,
+.Xr tolower 3 ,
+.Xr toupper 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+These functions, except for
+.Fn digittoint ,
+.Fn isascii ,
+.Fn isblank ,
+.Fn ishexnumber ,
+.Fn isideogram ,
+.Fn isnumber ,
+.Fn isphonogram ,
+.Fn isrune ,
+.Fn isspecial
+and
+.Fn toascii ,
+conform to
+.St -ansiC .
diff --git a/lib/libc/locale/euc.4 b/lib/libc/locale/euc.4
new file mode 100644
index 0000000..ce319ba
--- /dev/null
+++ b/lib/libc/locale/euc.4
@@ -0,0 +1,242 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Borman at Krystal Technologies.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)euc.4 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt EUC 4
+.Os
+.Sh NAME
+.Nm euc
+.Nd EUC encoding of runes
+.Sh SYNOPSIS
+.Nm ENCODING
+.Qq EUC
+.Pp
+.Nm VARIABLE
+.Ar len1
+.Ar mask1
+.Ar len2
+.Ar mask2
+.Ar len3
+.Ar mask3
+.Ar len4
+.Ar mask4
+.Ar mask
+.Sh DESCRIPTION
+The
+.Nm EUC
+encoding is provided for compatibility with
+.Ux
+based systems.
+See
+.Xr mklocale 1
+for a complete description of the
+.Ev LC_CTYPE
+source file format.
+.Pp
+.Nm EUC
+implements a system of 4 multibyte codesets.
+A multibyte character in the first codeset consists of
+.Ar len1
+bytes starting with a byte in the range of 0x00 to 0x7f.
+To allow use of ASCII,
+.Ar len1
+is always 1.
+A multibyte character in the second codeset consists of
+.Ar len2
+bytes starting with a byte in the range of 0x80-0xff excluding 0x8e and 0x8f.
+A multibyte character in the third codeset consists of
+.Ar len3
+bytes starting with the byte 0x8e.
+A multibyte character in the fourth codeset consists of
+.Ar len4
+bytes starting with the byte 0x8f.
+.Pp
+The
+.Ev rune_t
+encoding of
+.Nm EUC
+multibyte characters is dependent on the
+.Ar len
+and
+.Ar mask
+arguments.
+First, the bytes are moved into a
+.Ev rune_t
+as follows:
+.Bd -literal
+byte0 << ((\fIlen\fPN-1) * 8) | byte1 << ((\fIlen\fPN-2) * 8) | ... | byte\fIlen\fPN-1
+.Ed
+.Pp
+The result is then ANDed with
+.Ar ~mask
+and ORed with
+.Ar maskN .
+Codesets 2 and 3 are special in that the leading byte (0x8e or 0x8f) is
+first removed and the
+.Ar lenN
+argument is reduced by 1.
+.Pp
+For example, the Japanese locale has the following
+.Ev VARIABLE
+line:
+.Bd -literal
+VARIABLE 1 0x0000 2 0x8080 2 0x0080 3 0x8000 0x8080
+.Ed
+.Pp
+Codeset 1 consists of the values 0x0000 - 0x007f.
+.Pp
+Codeset 2 consists of the values who have the bits 0x8080 set.
+.Pp
+Codeset 3 consists of the values 0x0080 - 0x00ff.
+.Pp
+Codeset 4 consists of the values 0x8000 - 0xff7f excluding the values
+which have the 0x0080 bit set.
+.Pp
+Notice that the global
+.Ar mask
+is set to 0x8080, this implies that from those 2 bits the codeset can
+be determined.
+.Sh "EXAMPLE - Japanese Locale"
+This is a complete example of an
+.Ev LC_CTYPE
+source file for the Japanese locale
+.Bd -literal
+/*
+ * Japanese LOCALE_CTYPE definitions using EUC of JIS character sets
+ */
+
+ENCODING "EUC"
+
+/* JIS JIS JIS */
+/* X201 X208 X201 */
+/* 00-7f 84-fe */
+
+VARIABLE 1 0x0000 2 0x8080 2 0x0080 3 0x8000 0x8080
+
+/*
+ * Code Set 1
+ */
+ALPHA 'A' - 'Z' 'a' - 'z'
+CONTROL 0x00 - 0x1f 0x7f
+DIGIT '0' - '9'
+GRAPH 0x21 - 0x7e
+LOWER 'a' - 'z'
+PUNCT 0x21 - 0x2f 0x3a - 0x40 0x5b - 0x60 0x7b - 0x7e
+SPACE 0x09 - 0x0d 0x20
+UPPER 'A' - 'Z'
+XDIGIT 'a' - 'f' 'A' - 'F'
+BLANK ' ' '\t'
+PRINT 0x20 - 0x7e
+
+MAPLOWER < 'A' - 'Z' : 'a' > < 'a' - 'z' : 'a' >
+MAPUPPER < 'A' - 'Z' : 'A' > < 'a' - 'z' : 'A' >
+TODIGIT < '0' - '9' : 0 >
+TODIGIT < 'A' - 'F' : 10 > < 'a' - 'f' : 10 >
+
+/*
+ * Code Set 2
+ */
+
+SPACE 0xa1a1
+PHONOGRAM 0xa1bc
+SPECIAL 0xa1a2 - 0xa1fe
+PUNCT 0xa1a2 - 0xa1f8 /* A few too many in here... */
+
+SPECIAL 0xa2a1 - 0xa2ae 0xa2ba - 0xa2c1 0xa2ca - 0xa2d0 0xa2dc - 0xa2ea
+SPECIAL 0xa2f2 - 0xa2f9 0xa2fe
+
+DIGIT 0xa3b0 - 0xa3b9
+UPPER 0xa3c1 - 0xa3da /* Romaji */
+LOWER 0xa3e1 - 0xa3fa /* Romaji */
+MAPLOWER < 0xa3c1 - 0xa3da : 0xa3e1 > /* English */
+MAPLOWER < 0xa3e1 - 0xa3fa : 0xa3e1 > /* English */
+MAPUPPER < 0xa3c1 - 0xa3da : 0xa3c1 >
+MAPUPPER < 0xa3e1 - 0xa3fa : 0xa3c1 >
+
+XDIGIT 0xa3c1 - 0xa3c6 0xa3e1 - 0xa3e6
+
+TODIGIT < 0xa3b0 - 0xa3b9 : 0 >
+TODIGIT < 0xa3c1 - 0xa3c6 : 10 > < 0xa3e1 - 0xa3e6 : 10 >
+
+PHONOGRAM 0xa4a1 - 0xa4f3
+PHONOGRAM 0xa5a1 - 0xa5f6
+
+UPPER 0xa6a1 - 0xa6b8 /* Greek */
+LOWER 0xa6c1 - 0xa6d8 /* Greek */
+MAPLOWER < 0xa6a1 - 0xa6b8 : 0xa6c1 > < 0xa6c1 - 0xa6d8 : 0xa6c1 >
+MAPUPPER < 0xa6a1 - 0xa6b8 : 0xa6a1 > < 0xa6c1 - 0xa6d8 : 0xa6a1 >
+
+UPPER 0xa7a1 - 0xa7c1 /* Cyrillic */
+LOWER 0xa7d1 - 0xa7f1 /* Cyrillic */
+MAPLOWER < 0xa7a1 - 0xa7c1 : 0xa7d1 > < 0xa7d1 - 0xa7f1 : 0xa7d1 >
+MAPUPPER < 0xa7a1 - 0xa7c1 : 0xa7a1 > < 0xa7d1 - 0xa7f1 : 0xa7a1 >
+
+SPECIAL 0xa8a1 - 0xa8c0
+
+IDEOGRAM 0xb0a1 - 0xb0fe 0xb1a1 - 0xb1fe 0xb2a1 - 0xb2fe
+IDEOGRAM 0xb3a1 - 0xb3fe 0xb4a1 - 0xb4fe 0xb5a1 - 0xb5fe
+IDEOGRAM 0xb6a1 - 0xb6fe 0xb7a1 - 0xb7fe 0xb8a1 - 0xb8fe
+IDEOGRAM 0xb9a1 - 0xb9fe 0xbaa1 - 0xbafe 0xbba1 - 0xbbfe
+IDEOGRAM 0xbca1 - 0xbcfe 0xbda1 - 0xbdfe 0xbea1 - 0xbefe
+IDEOGRAM 0xbfa1 - 0xbffe 0xc0a1 - 0xc0fe 0xc1a1 - 0xc1fe
+IDEOGRAM 0xc2a1 - 0xc2fe 0xc3a1 - 0xc3fe 0xc4a1 - 0xc4fe
+IDEOGRAM 0xc5a1 - 0xc5fe 0xc6a1 - 0xc6fe 0xc7a1 - 0xc7fe
+IDEOGRAM 0xc8a1 - 0xc8fe 0xc9a1 - 0xc9fe 0xcaa1 - 0xcafe
+IDEOGRAM 0xcba1 - 0xcbfe 0xcca1 - 0xccfe 0xcda1 - 0xcdfe
+IDEOGRAM 0xcea1 - 0xcefe 0xcfa1 - 0xcfd3 0xd0a1 - 0xd0fe
+IDEOGRAM 0xd1a1 - 0xd1fe 0xd2a1 - 0xd2fe 0xd3a1 - 0xd3fe
+IDEOGRAM 0xd4a1 - 0xd4fe 0xd5a1 - 0xd5fe 0xd6a1 - 0xd6fe
+IDEOGRAM 0xd7a1 - 0xd7fe 0xd8a1 - 0xd8fe 0xd9a1 - 0xd9fe
+IDEOGRAM 0xdaa1 - 0xdafe 0xdba1 - 0xdbfe 0xdca1 - 0xdcfe
+IDEOGRAM 0xdda1 - 0xddfe 0xdea1 - 0xdefe 0xdfa1 - 0xdffe
+IDEOGRAM 0xe0a1 - 0xe0fe 0xe1a1 - 0xe1fe 0xe2a1 - 0xe2fe
+IDEOGRAM 0xe3a1 - 0xe3fe 0xe4a1 - 0xe4fe 0xe5a1 - 0xe5fe
+IDEOGRAM 0xe6a1 - 0xe6fe 0xe7a1 - 0xe7fe 0xe8a1 - 0xe8fe
+IDEOGRAM 0xe9a1 - 0xe9fe 0xeaa1 - 0xeafe 0xeba1 - 0xebfe
+IDEOGRAM 0xeca1 - 0xecfe 0xeda1 - 0xedfe 0xeea1 - 0xeefe
+IDEOGRAM 0xefa1 - 0xeffe 0xf0a1 - 0xf0fe 0xf1a1 - 0xf1fe
+IDEOGRAM 0xf2a1 - 0xf2fe 0xf3a1 - 0xf3fe 0xf4a1 - 0xf4a4
+/*
+ * This is for Code Set 3, half-width kana
+ */
+SPECIAL 0xa1 - 0xdf
+PHONOGRAM 0xa1 - 0xdf
+CONTROL 0x84 - 0x97 0x9b - 0x9f 0xe0 - 0xfe
+.Ed
+.Sh "SEE ALSO"
+.Xr mklocale 1 ,
+.Xr setlocale 3
diff --git a/lib/libc/locale/euc.5 b/lib/libc/locale/euc.5
new file mode 100644
index 0000000..ce319ba
--- /dev/null
+++ b/lib/libc/locale/euc.5
@@ -0,0 +1,242 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Borman at Krystal Technologies.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)euc.4 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt EUC 4
+.Os
+.Sh NAME
+.Nm euc
+.Nd EUC encoding of runes
+.Sh SYNOPSIS
+.Nm ENCODING
+.Qq EUC
+.Pp
+.Nm VARIABLE
+.Ar len1
+.Ar mask1
+.Ar len2
+.Ar mask2
+.Ar len3
+.Ar mask3
+.Ar len4
+.Ar mask4
+.Ar mask
+.Sh DESCRIPTION
+The
+.Nm EUC
+encoding is provided for compatibility with
+.Ux
+based systems.
+See
+.Xr mklocale 1
+for a complete description of the
+.Ev LC_CTYPE
+source file format.
+.Pp
+.Nm EUC
+implements a system of 4 multibyte codesets.
+A multibyte character in the first codeset consists of
+.Ar len1
+bytes starting with a byte in the range of 0x00 to 0x7f.
+To allow use of ASCII,
+.Ar len1
+is always 1.
+A multibyte character in the second codeset consists of
+.Ar len2
+bytes starting with a byte in the range of 0x80-0xff excluding 0x8e and 0x8f.
+A multibyte character in the third codeset consists of
+.Ar len3
+bytes starting with the byte 0x8e.
+A multibyte character in the fourth codeset consists of
+.Ar len4
+bytes starting with the byte 0x8f.
+.Pp
+The
+.Ev rune_t
+encoding of
+.Nm EUC
+multibyte characters is dependent on the
+.Ar len
+and
+.Ar mask
+arguments.
+First, the bytes are moved into a
+.Ev rune_t
+as follows:
+.Bd -literal
+byte0 << ((\fIlen\fPN-1) * 8) | byte1 << ((\fIlen\fPN-2) * 8) | ... | byte\fIlen\fPN-1
+.Ed
+.Pp
+The result is then ANDed with
+.Ar ~mask
+and ORed with
+.Ar maskN .
+Codesets 2 and 3 are special in that the leading byte (0x8e or 0x8f) is
+first removed and the
+.Ar lenN
+argument is reduced by 1.
+.Pp
+For example, the Japanese locale has the following
+.Ev VARIABLE
+line:
+.Bd -literal
+VARIABLE 1 0x0000 2 0x8080 2 0x0080 3 0x8000 0x8080
+.Ed
+.Pp
+Codeset 1 consists of the values 0x0000 - 0x007f.
+.Pp
+Codeset 2 consists of the values who have the bits 0x8080 set.
+.Pp
+Codeset 3 consists of the values 0x0080 - 0x00ff.
+.Pp
+Codeset 4 consists of the values 0x8000 - 0xff7f excluding the values
+which have the 0x0080 bit set.
+.Pp
+Notice that the global
+.Ar mask
+is set to 0x8080, this implies that from those 2 bits the codeset can
+be determined.
+.Sh "EXAMPLE - Japanese Locale"
+This is a complete example of an
+.Ev LC_CTYPE
+source file for the Japanese locale
+.Bd -literal
+/*
+ * Japanese LOCALE_CTYPE definitions using EUC of JIS character sets
+ */
+
+ENCODING "EUC"
+
+/* JIS JIS JIS */
+/* X201 X208 X201 */
+/* 00-7f 84-fe */
+
+VARIABLE 1 0x0000 2 0x8080 2 0x0080 3 0x8000 0x8080
+
+/*
+ * Code Set 1
+ */
+ALPHA 'A' - 'Z' 'a' - 'z'
+CONTROL 0x00 - 0x1f 0x7f
+DIGIT '0' - '9'
+GRAPH 0x21 - 0x7e
+LOWER 'a' - 'z'
+PUNCT 0x21 - 0x2f 0x3a - 0x40 0x5b - 0x60 0x7b - 0x7e
+SPACE 0x09 - 0x0d 0x20
+UPPER 'A' - 'Z'
+XDIGIT 'a' - 'f' 'A' - 'F'
+BLANK ' ' '\t'
+PRINT 0x20 - 0x7e
+
+MAPLOWER < 'A' - 'Z' : 'a' > < 'a' - 'z' : 'a' >
+MAPUPPER < 'A' - 'Z' : 'A' > < 'a' - 'z' : 'A' >
+TODIGIT < '0' - '9' : 0 >
+TODIGIT < 'A' - 'F' : 10 > < 'a' - 'f' : 10 >
+
+/*
+ * Code Set 2
+ */
+
+SPACE 0xa1a1
+PHONOGRAM 0xa1bc
+SPECIAL 0xa1a2 - 0xa1fe
+PUNCT 0xa1a2 - 0xa1f8 /* A few too many in here... */
+
+SPECIAL 0xa2a1 - 0xa2ae 0xa2ba - 0xa2c1 0xa2ca - 0xa2d0 0xa2dc - 0xa2ea
+SPECIAL 0xa2f2 - 0xa2f9 0xa2fe
+
+DIGIT 0xa3b0 - 0xa3b9
+UPPER 0xa3c1 - 0xa3da /* Romaji */
+LOWER 0xa3e1 - 0xa3fa /* Romaji */
+MAPLOWER < 0xa3c1 - 0xa3da : 0xa3e1 > /* English */
+MAPLOWER < 0xa3e1 - 0xa3fa : 0xa3e1 > /* English */
+MAPUPPER < 0xa3c1 - 0xa3da : 0xa3c1 >
+MAPUPPER < 0xa3e1 - 0xa3fa : 0xa3c1 >
+
+XDIGIT 0xa3c1 - 0xa3c6 0xa3e1 - 0xa3e6
+
+TODIGIT < 0xa3b0 - 0xa3b9 : 0 >
+TODIGIT < 0xa3c1 - 0xa3c6 : 10 > < 0xa3e1 - 0xa3e6 : 10 >
+
+PHONOGRAM 0xa4a1 - 0xa4f3
+PHONOGRAM 0xa5a1 - 0xa5f6
+
+UPPER 0xa6a1 - 0xa6b8 /* Greek */
+LOWER 0xa6c1 - 0xa6d8 /* Greek */
+MAPLOWER < 0xa6a1 - 0xa6b8 : 0xa6c1 > < 0xa6c1 - 0xa6d8 : 0xa6c1 >
+MAPUPPER < 0xa6a1 - 0xa6b8 : 0xa6a1 > < 0xa6c1 - 0xa6d8 : 0xa6a1 >
+
+UPPER 0xa7a1 - 0xa7c1 /* Cyrillic */
+LOWER 0xa7d1 - 0xa7f1 /* Cyrillic */
+MAPLOWER < 0xa7a1 - 0xa7c1 : 0xa7d1 > < 0xa7d1 - 0xa7f1 : 0xa7d1 >
+MAPUPPER < 0xa7a1 - 0xa7c1 : 0xa7a1 > < 0xa7d1 - 0xa7f1 : 0xa7a1 >
+
+SPECIAL 0xa8a1 - 0xa8c0
+
+IDEOGRAM 0xb0a1 - 0xb0fe 0xb1a1 - 0xb1fe 0xb2a1 - 0xb2fe
+IDEOGRAM 0xb3a1 - 0xb3fe 0xb4a1 - 0xb4fe 0xb5a1 - 0xb5fe
+IDEOGRAM 0xb6a1 - 0xb6fe 0xb7a1 - 0xb7fe 0xb8a1 - 0xb8fe
+IDEOGRAM 0xb9a1 - 0xb9fe 0xbaa1 - 0xbafe 0xbba1 - 0xbbfe
+IDEOGRAM 0xbca1 - 0xbcfe 0xbda1 - 0xbdfe 0xbea1 - 0xbefe
+IDEOGRAM 0xbfa1 - 0xbffe 0xc0a1 - 0xc0fe 0xc1a1 - 0xc1fe
+IDEOGRAM 0xc2a1 - 0xc2fe 0xc3a1 - 0xc3fe 0xc4a1 - 0xc4fe
+IDEOGRAM 0xc5a1 - 0xc5fe 0xc6a1 - 0xc6fe 0xc7a1 - 0xc7fe
+IDEOGRAM 0xc8a1 - 0xc8fe 0xc9a1 - 0xc9fe 0xcaa1 - 0xcafe
+IDEOGRAM 0xcba1 - 0xcbfe 0xcca1 - 0xccfe 0xcda1 - 0xcdfe
+IDEOGRAM 0xcea1 - 0xcefe 0xcfa1 - 0xcfd3 0xd0a1 - 0xd0fe
+IDEOGRAM 0xd1a1 - 0xd1fe 0xd2a1 - 0xd2fe 0xd3a1 - 0xd3fe
+IDEOGRAM 0xd4a1 - 0xd4fe 0xd5a1 - 0xd5fe 0xd6a1 - 0xd6fe
+IDEOGRAM 0xd7a1 - 0xd7fe 0xd8a1 - 0xd8fe 0xd9a1 - 0xd9fe
+IDEOGRAM 0xdaa1 - 0xdafe 0xdba1 - 0xdbfe 0xdca1 - 0xdcfe
+IDEOGRAM 0xdda1 - 0xddfe 0xdea1 - 0xdefe 0xdfa1 - 0xdffe
+IDEOGRAM 0xe0a1 - 0xe0fe 0xe1a1 - 0xe1fe 0xe2a1 - 0xe2fe
+IDEOGRAM 0xe3a1 - 0xe3fe 0xe4a1 - 0xe4fe 0xe5a1 - 0xe5fe
+IDEOGRAM 0xe6a1 - 0xe6fe 0xe7a1 - 0xe7fe 0xe8a1 - 0xe8fe
+IDEOGRAM 0xe9a1 - 0xe9fe 0xeaa1 - 0xeafe 0xeba1 - 0xebfe
+IDEOGRAM 0xeca1 - 0xecfe 0xeda1 - 0xedfe 0xeea1 - 0xeefe
+IDEOGRAM 0xefa1 - 0xeffe 0xf0a1 - 0xf0fe 0xf1a1 - 0xf1fe
+IDEOGRAM 0xf2a1 - 0xf2fe 0xf3a1 - 0xf3fe 0xf4a1 - 0xf4a4
+/*
+ * This is for Code Set 3, half-width kana
+ */
+SPECIAL 0xa1 - 0xdf
+PHONOGRAM 0xa1 - 0xdf
+CONTROL 0x84 - 0x97 0x9b - 0x9f 0xe0 - 0xfe
+.Ed
+.Sh "SEE ALSO"
+.Xr mklocale 1 ,
+.Xr setlocale 3
diff --git a/lib/libc/locale/euc.c b/lib/libc/locale/euc.c
new file mode 100644
index 0000000..ea5cdb4
--- /dev/null
+++ b/lib/libc/locale/euc.c
@@ -0,0 +1,223 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef XPG4
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)euc.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <rune.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+rune_t _EUC_sgetrune __P((const char *, size_t, char const **));
+int _EUC_sputrune __P((rune_t, char *, size_t, char **));
+
+typedef struct {
+ int count[4];
+ rune_t bits[4];
+ rune_t mask;
+} _EucInfo;
+
+int
+_EUC_init(rl)
+ _RuneLocale *rl;
+{
+ _EucInfo *ei;
+ int x;
+ char *v, *e;
+
+ rl->sgetrune = _EUC_sgetrune;
+ rl->sputrune = _EUC_sputrune;
+
+ if (!rl->variable) {
+ free(rl);
+ return (EFTYPE);
+ }
+ v = (char *) rl->variable;
+
+ while (*v == ' ' || *v == '\t')
+ ++v;
+
+ if ((ei = malloc(sizeof(_EucInfo))) == NULL) {
+ free(rl);
+ return (ENOMEM);
+ }
+ for (x = 0; x < 4; ++x) {
+ ei->count[x] = (int) strtol(v, &e, 0);
+ if (v == e || !(v = e)) {
+ free(rl);
+ free(ei);
+ return (EFTYPE);
+ }
+ while (*v == ' ' || *v == '\t')
+ ++v;
+ ei->bits[x] = (int) strtol(v, &e, 0);
+ if (v == e || !(v = e)) {
+ free(rl);
+ free(ei);
+ return (EFTYPE);
+ }
+ while (*v == ' ' || *v == '\t')
+ ++v;
+ }
+ ei->mask = (int)strtol(v, &e, 0);
+ if (v == e || !(v = e)) {
+ free(rl);
+ free(ei);
+ return (EFTYPE);
+ }
+ if (sizeof(_EucInfo) <= rl->variable_len) {
+ memcpy(rl->variable, ei, sizeof(_EucInfo));
+ free(ei);
+ } else {
+ rl->variable = &ei;
+ }
+ rl->variable_len = sizeof(_EucInfo);
+ _CurrentRuneLocale = rl;
+ __mb_cur_max = 3;
+ return (0);
+}
+
+#define CEI ((_EucInfo *)(_CurrentRuneLocale->variable))
+
+#define _SS2 0x008e
+#define _SS3 0x008f
+
+static inline int
+_euc_set(c)
+ u_int c;
+{
+ c &= 0xff;
+
+ return ((c & 0x80) ? c == _SS3 ? 3 : c == _SS2 ? 2 : 1 : 0);
+}
+rune_t
+_EUC_sgetrune(string, n, result)
+ const char *string;
+ size_t n;
+ char const **result;
+{
+ rune_t rune = 0;
+ int len, set;
+
+ if (n < 1 || (len = CEI->count[set = _euc_set(*string)]) > n) {
+ if (result)
+ *result = string;
+ return (_INVALID_RUNE);
+ }
+ switch (set) {
+ case 3:
+ case 2:
+ --len;
+ ++string;
+ /* FALLTHROUGH */
+ case 1:
+ case 0:
+ while (len-- > 0)
+ rune = (rune << 8) | ((u_int)(*string++) & 0xff);
+ break;
+ }
+ if (result)
+ *result = string;
+ return ((rune & ~CEI->mask) | CEI->bits[set]);
+}
+
+int
+_EUC_sputrune(c, string, n, result)
+ rune_t c;
+ char *string, **result;
+ size_t n;
+{
+ rune_t m = c & CEI->mask;
+ rune_t nm = c & ~m;
+ int i, len;
+
+ if (m == CEI->bits[1]) {
+CodeSet1:
+ /* Codeset 1: The first byte must have 0x80 in it. */
+ i = len = CEI->count[1];
+ if (n >= len) {
+ if (result)
+ *result = string + len;
+ while (i-- > 0)
+ *string++ = (nm >> (i << 3)) | 0x80;
+ } else
+ if (result)
+ *result = (char *) 0;
+ } else {
+ if (m == CEI->bits[0]) {
+ i = len = CEI->count[0];
+ if (n < len) {
+ if (result)
+ *result = NULL;
+ return (len);
+ }
+ } else
+ if (m == CEI->bits[2]) {
+ i = len = CEI->count[2];
+ if (n < len) {
+ if (result)
+ *result = NULL;
+ return (len);
+ }
+ *string++ = _SS2;
+ --i;
+ } else
+ if (m == CEI->bits[3]) {
+ i = len = CEI->count[3];
+ if (n < len) {
+ if (result)
+ *result = NULL;
+ return (len);
+ }
+ *string++ = _SS3;
+ --i;
+ } else
+ goto CodeSet1; /* Bletch */
+ while (i-- > 0)
+ *string++ = (nm >> (i << 3)) & 0xff;
+ if (result)
+ *result = string;
+ }
+ return (len);
+}
+#endif /* XPG4 */
diff --git a/lib/libc/locale/frune.c b/lib/libc/locale/frune.c
new file mode 100644
index 0000000..443d3ba
--- /dev/null
+++ b/lib/libc/locale/frune.c
@@ -0,0 +1,103 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)frune.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <rune.h>
+#include <stddef.h>
+#include <stdio.h>
+
+long
+fgetrune(fp)
+ FILE *fp;
+{
+ rune_t r;
+ int c, len;
+ char buf[MB_LEN_MAX];
+ char const *result;
+
+ len = 0;
+ do {
+ if ((c = getc(fp)) == EOF) {
+ if (len)
+ break;
+ return (EOF);
+ }
+ buf[len++] = c;
+
+ if ((r = sgetrune(buf, len, &result)) != _INVALID_RUNE)
+ return (r);
+ } while (result == buf && len < MB_LEN_MAX);
+
+ while (--len > 0)
+ ungetc(buf[len], fp);
+ return (_INVALID_RUNE);
+}
+
+int
+fungetrune(r, fp)
+ rune_t r;
+ FILE* fp;
+{
+ int len;
+ char buf[MB_LEN_MAX];
+
+ len = sputrune(r, buf, MB_LEN_MAX, 0);
+ while (len-- > 0)
+ if (ungetc(buf[len], fp) == EOF)
+ return (EOF);
+ return (0);
+}
+
+int
+fputrune(r, fp)
+ rune_t r;
+ FILE *fp;
+{
+ int i, len;
+ char buf[MB_LEN_MAX];
+
+ len = sputrune(r, buf, MB_LEN_MAX, 0);
+
+ for (i = 0; i < len; ++i)
+ if (putc(buf[i], fp) == EOF)
+ return (EOF);
+
+ return (0);
+}
diff --git a/lib/libc/locale/isalnum.3 b/lib/libc/locale/isalnum.3
new file mode 100644
index 0000000..be99644
--- /dev/null
+++ b/lib/libc/locale/isalnum.3
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)isalnum.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ISALNUM 3
+.Os
+.Sh NAME
+.Nm isalnum
+.Nd alphanumeric character test
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn isalnum "int c"
+.Sh DESCRIPTION
+The
+.Fn isalnum
+function tests for any character for which
+.Xr isalpha 3
+or
+.Xr isdigit 3
+is true.
+In the ASCII character set, this includes the following characters:
+.Pp
+.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
+.It \&060\ ``0'' \t061\ ``1'' \t062\ ``2'' \t063\ ``3'' \t064\ ``4''
+.It \&065\ ``5'' \t066\ ``6'' \t067\ ``7'' \t070\ ``8'' \t071\ ``9''
+.It \&101\ ``A'' \t102\ ``B'' \t103\ ``C'' \t104\ ``D'' \t105\ ``E''
+.It \&106\ ``F'' \t107\ ``G'' \t110\ ``H'' \t111\ ``I'' \t112\ ``J''
+.It \&113\ ``K'' \t114\ ``L'' \t115\ ``M'' \t116\ ``N'' \t117\ ``O''
+.It \&120\ ``P'' \t121\ ``Q'' \t122\ ``R'' \t123\ ``S'' \t124\ ``T''
+.It \&125\ ``U'' \t126\ ``V'' \t127\ ``W'' \t130\ ``X'' \t131\ ``Y''
+.It \&132\ ``Z'' \t141\ ``a'' \t142\ ``b'' \t143\ ``c'' \t144\ ``d''
+.It \&145\ ``e'' \t146\ ``f'' \t147\ ``g'' \t150\ ``h'' \t151\ ``i''
+.It \&152\ ``j'' \t153\ ``k'' \t154\ ``l'' \t155\ ``m'' \t156\ ``n''
+.It \&157\ ``o'' \t160\ ``p'' \t161\ ``q'' \t162\ ``r'' \t163\ ``s''
+.It \&164\ ``t'' \t165\ ``u'' \t166\ ``v'' \t167\ ``w'' \t170\ ``x''
+.It \&171\ ``y'' \t172\ ``z''
+.El
+.Sh RETURN VALUES
+The
+.Fn isalnum
+function returns zero if the character tests false and
+returns non-zero if the character tests true.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr isalpha 3 ,
+.Xr isdigit 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn isalnum
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/isalpha.3 b/lib/libc/locale/isalpha.3
new file mode 100644
index 0000000..7d9ba66
--- /dev/null
+++ b/lib/libc/locale/isalpha.3
@@ -0,0 +1,86 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)isalpha.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ISALPHA 3
+.Os
+.Sh NAME
+.Nm isalpha
+.Nd alphabetic character test
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn isalpha "int c"
+.Sh DESCRIPTION
+The
+.Fn isalpha
+function tests for any character for which
+.Xr isupper 3
+or
+.Xr islower 3
+is true.
+In the ASCII character set, this includes the following characters:
+.Pp
+.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
+.It \&101\ ``A'' \t102\ ``B'' \t103\ ``C'' \t104\ ``D'' \t105\ ``E''
+.It \&106\ ``F'' \t107\ ``G'' \t110\ ``H'' \t111\ ``I'' \t112\ ``J''
+.It \&113\ ``K'' \t114\ ``L'' \t115\ ``M'' \t116\ ``N'' \t117\ ``O''
+.It \&120\ ``P'' \t121\ ``Q'' \t122\ ``R'' \t123\ ``S'' \t124\ ``T''
+.It \&125\ ``U'' \t126\ ``V'' \t127\ ``W'' \t130\ ``X'' \t131\ ``Y''
+.It \&132\ ``Z'' \t141\ ``a'' \t142\ ``b'' \t143\ ``c'' \t144\ ``d''
+.It \&145\ ``e'' \t146\ ``f'' \t147\ ``g'' \t150\ ``h'' \t151\ ``i''
+.It \&152\ ``j'' \t153\ ``k'' \t154\ ``l'' \t155\ ``m'' \t156\ ``n''
+.It \&157\ ``o'' \t160\ ``p'' \t161\ ``q'' \t162\ ``r'' \t163\ ``s''
+.It \&164\ ``t'' \t165\ ``u'' \t166\ ``v'' \t167\ ``w'' \t170\ ``x''
+.It \&171\ ``y'' \t172\ ``z''
+.El
+.Sh RETURN VALUES
+The
+.Fn isalpha
+function returns zero if the character tests false and
+returns non-zero if the character tests true.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr islower 3 ,
+.Xr isupper 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn isalpha
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/isascii.3 b/lib/libc/locale/isascii.3
new file mode 100644
index 0000000..2315d7e
--- /dev/null
+++ b/lib/libc/locale/isascii.3
@@ -0,0 +1,59 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)isascii.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt ISASCII 3
+.Os
+.Sh NAME
+.Nm isascii
+.Nd test for ASCII character
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn isascii "int c"
+.Sh DESCRIPTION
+The
+.Fn isascii
+function tests for an
+.Tn ASCII
+character, which is any character with a value less than or
+equal to 0177.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn isascii
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/isblank.3 b/lib/libc/locale/isblank.3
new file mode 100644
index 0000000..c0ec34d
--- /dev/null
+++ b/lib/libc/locale/isblank.3
@@ -0,0 +1,56 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)isblank.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ISBLANK 3
+.Os
+.Sh NAME
+.Nm isblank
+.Nd space or tab character test
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn isblank "int c"
+.Sh DESCRIPTION
+The
+.Fn isblank
+function tests for a space or tab character.
+.Sh RETURN VALUES
+The
+.Fn isblank
+function returns zero if the character tests false and
+returns non-zero if the character tests true.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr ascii 7
diff --git a/lib/libc/locale/iscntrl.3 b/lib/libc/locale/iscntrl.3
new file mode 100644
index 0000000..2b5c737
--- /dev/null
+++ b/lib/libc/locale/iscntrl.3
@@ -0,0 +1,76 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)iscntrl.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ISCNTRL 3
+.Os
+.Sh NAME
+.Nm iscntrl
+.Nd control character test
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn iscntrl "int c"
+.Sh DESCRIPTION
+The
+.Fn iscntrl
+function tests for any control character.
+In the ASCII character set, this includes the following characters:
+.Pp
+.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
+.It \&000\ nul \t001\ soh \t002\ stx \t003\ etx \t004\ eot
+.It \&005\ enq \t006\ ack \t007\ bel \t010\ bs \t011\ ht
+.It \&012\ nl \t013\ vt \t014\ np \t015\ cr \t016\ so
+.It \&017\ si \t020\ dle \t021\ dc1 \t022\ dc2 \t023\ dc3
+.It \&024\ dc4 \t025\ nak \t026\ syn \t027\ etb \t030\ can
+.It \&031\ em \t032\ sub \t033\ esc \t034\ fs \t035\ gs
+.It \&036\ rs \t037\ us \t177\ del
+.El
+.Sh RETURN VALUES
+The
+.Fn iscntrl
+function returns zero if the character tests false and
+returns non-zero if the character tests true.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn iscntrl
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/isctype.c b/lib/libc/locale/isctype.c
new file mode 100644
index 0000000..70bcfd4
--- /dev/null
+++ b/lib/libc/locale/isctype.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)isctype.c 8.3 (Berkeley) 2/24/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ctype.h>
+
+#undef digittoint
+int
+digittoint(c)
+ int c;
+{
+ return (__maskrune((c), 0xFF));
+}
+
+#undef isalnum
+int
+isalnum(c)
+ int c;
+{
+ return (__istype((c), _A|_D));
+}
+
+#undef isalpha
+int
+isalpha(c)
+ int c;
+{
+ return (__istype((c), _A));
+}
+
+#undef isascii
+int
+isascii(c)
+ int c;
+{
+ return (((c) & ~0x7F) == 0);
+}
+
+#undef isblank
+int
+isblank(c)
+ int c;
+{
+ return (__istype((c), _B));
+}
+
+#undef iscntrl
+int
+iscntrl(c)
+ int c;
+{
+ return (__istype((c), _C));
+}
+
+#undef isdigit
+int
+isdigit(c)
+ int c;
+{
+ return (__isctype((c), _D));
+}
+
+#undef isgraph
+int
+isgraph(c)
+ int c;
+{
+ return (__istype((c), _G));
+}
+
+#undef ishexnumber
+int
+ishexnumber(c)
+ int c;
+{
+ return (__istype((c), _X));
+}
+
+#undef isideogram
+int
+isideogram(c)
+ int c;
+{
+ return (__istype((c), _I));
+}
+
+#undef islower
+int
+islower(c)
+ int c;
+{
+ return (__istype((c), _L));
+}
+
+#undef isnumber
+int
+isnumber(c)
+ int c;
+{
+ return (__istype((c), _D));
+}
+
+#undef isphonogram
+int
+isphonogram(c)
+ int c;
+{
+ return (__istype((c), _Q));
+}
+
+#undef isprint
+int
+isprint(c)
+ int c;
+{
+ return (__istype((c), _R));
+}
+
+#undef ispunct
+int
+ispunct(c)
+ int c;
+{
+ return (__istype((c), _P));
+}
+
+#undef isrune
+int
+isrune(c)
+ int c;
+{
+ return (__istype((c), 0xFFFFFF00L));
+}
+
+#undef isspace
+int
+isspace(c)
+ int c;
+{
+ return (__istype((c), _S));
+}
+
+#undef isspecial
+int
+isspecial(c)
+ int c;
+{
+ return (__istype((c), _T));
+}
+
+#undef isupper
+int
+isupper(c)
+ int c;
+{
+ return (__istype((c), _U));
+}
+
+#undef isxdigit
+int
+isxdigit(c)
+ int c;
+{
+ return (__isctype((c), _X));
+}
+
+#undef toascii
+int
+toascii(c)
+ int c;
+{
+ return ((c) & 0x7F);
+}
+
+#undef tolower
+int
+tolower(c)
+ int c;
+{
+ return (__tolower(c));
+}
+
+#undef toupper
+int
+toupper(c)
+ int c;
+{
+ return (__toupper(c));
+}
+
diff --git a/lib/libc/locale/isdigit.3 b/lib/libc/locale/isdigit.3
new file mode 100644
index 0000000..dbae177
--- /dev/null
+++ b/lib/libc/locale/isdigit.3
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)isdigit.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ISDIGIT 3
+.Os
+.Sh NAME
+.Nm isdigit
+.Nd decimal-digit character test
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn isdigit "int c"
+.Sh DESCRIPTION
+The
+.Fn isdigit
+function tests for any decimal-digit character.
+In the ASCII character set, this includes the following characters:
+.Pp
+.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
+.It \&060\ ``0'' \t061\ ``1'' \t062\ ``2'' \t063\ ``3'' \t064\ ``4''
+.It \&065\ ``5'' \t066\ ``6'' \t067\ ``7'' \t070\ ``8'' \t071\ ``9''
+.El
+.Sh RETURN VALUES
+The
+.Fn isdigit
+function returns zero if the character tests false and
+returns non-zero if the character tests true.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn isdigit
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/isgraph.3 b/lib/libc/locale/isgraph.3
new file mode 100644
index 0000000..62fe710
--- /dev/null
+++ b/lib/libc/locale/isgraph.3
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)isgraph.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt ISGRAPH 3
+.Os
+.Sh NAME
+.Nm isgraph
+.Nd printing character test (space character exclusive)
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn isgraph "int c"
+.Sh DESCRIPTION
+The
+.Fn isgraph
+function tests for any printing character except space.
+In the ASCII character set, this includes the following characters:
+.Pp
+.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
+.It \&041\ ``!'' \t042\ ``"'' \t043\ ``#'' \t044\ ``$'' \t045\ ``%''
+.It \&046\ ``&'' \t047\ ``''' \t050\ ``('' \t051\ ``)'' \t052\ ``*''
+.It \&053\ ``+'' \t054\ ``,'' \t055\ ``-'' \t056\ ``.'' \t057\ ``/''
+.It \&060\ ``0'' \t061\ ``1'' \t062\ ``2'' \t063\ ``3'' \t064\ ``4''
+.It \&065\ ``5'' \t066\ ``6'' \t067\ ``7'' \t070\ ``8'' \t071\ ``9''
+.It \&072\ ``:'' \t073\ ``;'' \t074\ ``<'' \t075\ ``='' \t076\ ``>''
+.It \&077\ ``?'' \t100\ ``@'' \t101\ ``A'' \t102\ ``B'' \t103\ ``C''
+.It \&104\ ``D'' \t105\ ``E'' \t106\ ``F'' \t107\ ``G'' \t110\ ``H''
+.It \&111\ ``I'' \t112\ ``J'' \t113\ ``K'' \t114\ ``L'' \t115\ ``M''
+.It \&116\ ``N'' \t117\ ``O'' \t120\ ``P'' \t121\ ``Q'' \t122\ ``R''
+.It \&123\ ``S'' \t124\ ``T'' \t125\ ``U'' \t126\ ``V'' \t127\ ``W''
+.It \&130\ ``X'' \t131\ ``Y'' \t132\ ``Z'' \t133\ ``['' \t134\ ``\e\|''
+.It \&135\ ``]'' \t136\ ``^'' \t137\ ``_'' \t140\ ```'' \t141\ ``a''
+.It \&142\ ``b'' \t143\ ``c'' \t144\ ``d'' \t145\ ``e'' \t146\ ``f''
+.It \&147\ ``g'' \t150\ ``h'' \t151\ ``i'' \t152\ ``j'' \t153\ ``k''
+.It \&154\ ``l'' \t155\ ``m'' \t156\ ``n'' \t157\ ``o'' \t160\ ``p''
+.It \&161\ ``q'' \t162\ ``r'' \t163\ ``s'' \t164\ ``t'' \t165\ ``u''
+.It \&166\ ``v'' \t167\ ``w'' \t170\ ``x'' \t171\ ``y'' \t172\ ``z''
+.It \&173\ ``{'' \t174\ ``|'' \t175\ ``}'' \t176\ ``~''
+.El
+.Sh RETURN VALUES
+The
+.Fn isgraph
+function returns zero if the character tests false and
+returns non-zero if the character tests true.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn isgraph
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/islower.3 b/lib/libc/locale/islower.3
new file mode 100644
index 0000000..019e612
--- /dev/null
+++ b/lib/libc/locale/islower.3
@@ -0,0 +1,75 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)islower.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ISLOWER 3
+.Os
+.Sh NAME
+.Nm islower
+.Nd lower-case character test
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn islower "int c"
+.Sh DESCRIPTION
+The
+.Fn islower
+function tests for any lower-case letters.
+In the ASCII character set, this includes the following characters:
+.Pp
+.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
+.It \&141\ ``a'' \t142\ ``b'' \t143\ ``c'' \t144\ ``d'' \t145\ ``e''
+.It \&146\ ``f'' \t147\ ``g'' \t150\ ``h'' \t151\ ``i'' \t152\ ``j''
+.It \&153\ ``k'' \t154\ ``l'' \t155\ ``m'' \t156\ ``n'' \t157\ ``o''
+.It \&160\ ``p'' \t161\ ``q'' \t162\ ``r'' \t163\ ``s'' \t164\ ``t''
+.It \&165\ ``u'' \t166\ ``v'' \t167\ ``w'' \t170\ ``x'' \t171\ ``y''
+.It \&172\ ``z''
+.El
+.Sh RETURN VALUES
+The
+.Fn islower
+function returns zero if the character tests false and
+returns non-zero if the character tests true.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn islower
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/isprint.3 b/lib/libc/locale/isprint.3
new file mode 100644
index 0000000..790015f
--- /dev/null
+++ b/lib/libc/locale/isprint.3
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)isprint.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ISPRINT 3
+.Os
+.Sh NAME
+.Nm isprint
+.Nd printing character test (space character inclusive)
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn isprint "int c"
+.Sh DESCRIPTION
+The
+.Fn isprint
+function tests for any printing character including space (' ').
+In the ASCII character set, this includes the following characters:
+.Pp
+.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
+.It \&040\ sp \t041\ ``!'' \t042\ ``"'' \t043\ ``#'' \t044\ ``$''
+.It \&045\ ``%'' \t046\ ``&'' \t047\ ``''' \t050\ ``('' \t051\ ``)''
+.It \&052\ ``*'' \t053\ ``+'' \t054\ ``,'' \t055\ ``-'' \t056\ ``.''
+.It \&057\ ``/'' \t060\ ``0'' \t061\ ``1'' \t062\ ``2'' \t063\ ``3''
+.It \&064\ ``4'' \t065\ ``5'' \t066\ ``6'' \t067\ ``7'' \t070\ ``8''
+.It \&071\ ``9'' \t072\ ``:'' \t073\ ``;'' \t074\ ``<'' \t075\ ``=''
+.It \&076\ ``>'' \t077\ ``?'' \t100\ ``@'' \t101\ ``A'' \t102\ ``B''
+.It \&103\ ``C'' \t104\ ``D'' \t105\ ``E'' \t106\ ``F'' \t107\ ``G''
+.It \&110\ ``H'' \t111\ ``I'' \t112\ ``J'' \t113\ ``K'' \t114\ ``L''
+.It \&115\ ``M'' \t116\ ``N'' \t117\ ``O'' \t120\ ``P'' \t121\ ``Q''
+.It \&122\ ``R'' \t123\ ``S'' \t124\ ``T'' \t125\ ``U'' \t126\ ``V''
+.It \&127\ ``W'' \t130\ ``X'' \t131\ ``Y'' \t132\ ``Z'' \t133\ ``[''
+.It \&134\ ``\e\|'' \t135\ ``]'' \t136\ ``^'' \t137\ ``_'' \t140\ ```''
+.It \&141\ ``a'' \t142\ ``b'' \t143\ ``c'' \t144\ ``d'' \t145\ ``e''
+.It \&146\ ``f'' \t147\ ``g'' \t150\ ``h'' \t151\ ``i'' \t152\ ``j''
+.It \&153\ ``k'' \t154\ ``l'' \t155\ ``m'' \t156\ ``n'' \t157\ ``o''
+.It \&160\ ``p'' \t161\ ``q'' \t162\ ``r'' \t163\ ``s'' \t164\ ``t''
+.It \&165\ ``u'' \t166\ ``v'' \t167\ ``w'' \t170\ ``x'' \t171\ ``y''
+.It \&172\ ``z'' \t173\ ``{'' \t174\ ``|'' \t175\ ``}'' \t176\ ``~''
+.El
+.Sh RETURN VALUES
+The
+.Fn isprint
+function returns zero if the character tests false and
+returns non-zero if the character tests true.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn isprint
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/ispunct.3 b/lib/libc/locale/ispunct.3
new file mode 100644
index 0000000..01a75dd
--- /dev/null
+++ b/lib/libc/locale/ispunct.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ispunct.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ISPUNCT 3
+.Os
+.Sh NAME
+.Nm ispunct
+.Nd punctuation character test
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn ispunct "int c"
+.Sh DESCRIPTION
+The
+.Fn ispunct
+function tests for any printing character except for space (' ') or a
+character for which
+.Xr isalnum 3
+is true.
+In the ASCII character set, this includes the following characters:
+.Pp
+.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
+.It \&041\ ``!'' \t042\ ``"'' \t043\ ``#'' \t044\ ``$'' \t045\ ``%''
+.It \&046\ ``&'' \t047\ ``''' \t050\ ``('' \t051\ ``)'' \t052\ ``*''
+.It \&053\ ``+'' \t054\ ``,'' \t055\ ``-'' \t056\ ``.'' \t057\ ``/''
+.It \&072\ ``:'' \t073\ ``;'' \t074\ ``<'' \t075\ ``='' \t076\ ``>''
+.It \&077\ ``?'' \t100\ ``@'' \t133\ ``['' \t134\ ``\e\|'' \t135\ ``]''
+.It \&136\ ``^'' \t137\ ``_'' \t140\ ```'' \t173\ ``{'' \t174\ ``|''
+.It \&175\ ``}'' \t176\ ``~''
+.El
+.Sh RETURN VALUES
+The
+.Fn ispunct
+function returns zero if the character tests false and
+returns non-zero if the character tests true.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn ispunct
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/isspace.3 b/lib/libc/locale/isspace.3
new file mode 100644
index 0000000..c3850a2
--- /dev/null
+++ b/lib/libc/locale/isspace.3
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)isspace.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ISSPACE 3
+.Os
+.Sh NAME
+.Nm isspace
+.Nd white-space character test
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn isspace "int c"
+.Sh DESCRIPTION
+The
+.Fn isspace
+function tests for the standard white-space characters.
+In the ASCII character set, this includes the following characters:
+.Pp
+.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
+.It \&011\ ht \t012\ nl \t013\ vt \t014\ np \t015\ cr
+.It \&040\ sp
+.El
+.Sh RETURN VALUES
+The
+.Fn isspace
+function returns zero if the character tests false and
+returns non-zero if the character tests true.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn isspace
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/isupper.3 b/lib/libc/locale/isupper.3
new file mode 100644
index 0000000..7d09f44
--- /dev/null
+++ b/lib/libc/locale/isupper.3
@@ -0,0 +1,75 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)isupper.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ISUPPER 3
+.Os
+.Sh NAME
+.Nm isupper
+.Nd upper-case character test
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn isupper "int c"
+.Sh DESCRIPTION
+The
+.Fn isupper
+function tests for any upper-case letter.
+In the ASCII character set, this includes the following characters:
+.Pp
+.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
+.It \&101\ ``A'' \t102\ ``B'' \t103\ ``C'' \t104\ ``D'' \t105\ ``E''
+.It \&106\ ``F'' \t107\ ``G'' \t110\ ``H'' \t111\ ``I'' \t112\ ``J''
+.It \&113\ ``K'' \t114\ ``L'' \t115\ ``M'' \t116\ ``N'' \t117\ ``O''
+.It \&120\ ``P'' \t121\ ``Q'' \t122\ ``R'' \t123\ ``S'' \t124\ ``T''
+.It \&125\ ``U'' \t126\ ``V'' \t127\ ``W'' \t130\ ``X'' \t131\ ``Y''
+.It \&132\ ``Z''
+.El
+.Sh RETURN VALUES
+The
+.Fn isupper
+function returns zero if the character tests false and
+returns non-zero if the character tests true.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn isupper
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/isxdigit.3 b/lib/libc/locale/isxdigit.3
new file mode 100644
index 0000000..31f3158
--- /dev/null
+++ b/lib/libc/locale/isxdigit.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)isxdigit.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ISXDIGIT 3
+.Os
+.Sh NAME
+.Nm isxdigit
+.Nd hexadecimal-digit character test
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn isxdigit "int c"
+.Sh DESCRIPTION
+The
+.Fn isxdigit
+function tests for any hexadecimal-digit character.
+In the ASCII character set, this includes the following characters:
+.Pp
+.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__
+.It \&060\ ``0'' \t061\ ``1'' \t062\ ``2'' \t063\ ``3'' \t064\ ``4''
+.It \&065\ ``5'' \t066\ ``6'' \t067\ ``7'' \t070\ ``8'' \t071\ ``9''
+.It \&101\ ``A'' \t102\ ``B'' \t103\ ``C'' \t104\ ``D'' \t105\ ``E''
+.It \&106\ ``F'' \t141\ ``a'' \t142\ ``b'' \t143\ ``c'' \t144\ ``d''
+.It \&145\ ``e'' \t146\ ``f''
+.El
+.Sh RETURN VALUES
+The
+.Fn isxdigit
+function returns zero if the character tests false and
+returns non-zero if the character tests true.
+.Sh SEE ALSO
+.Xr ctype 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn isxdigit
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/lconv.c b/lib/libc/locale/lconv.c
new file mode 100644
index 0000000..f1212b0a
--- /dev/null
+++ b/lib/libc/locale/lconv.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)lconv.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <locale.h>
+
+static char empty[] = "";
+
+/*
+ * Default (C) locale conversion.
+ */
+static struct lconv C_lconv = {
+ ".", /* decimal_point */
+ empty, /* thousands_sep */
+ empty, /* grouping */
+ empty, /* int_curr_symbol */
+ empty, /* currency_symbol */
+ empty, /* mon_decimal_point */
+ empty, /* mon_thousands_sep */
+ empty, /* mon_grouping */
+ empty, /* positive_sign */
+ empty, /* negative_sign */
+ CHAR_MAX, /* int_frac_digits */
+ CHAR_MAX, /* frac_digits */
+ CHAR_MAX, /* p_cs_precedes */
+ CHAR_MAX, /* p_sep_by_space */
+ CHAR_MAX, /* n_cs_precedes */
+ CHAR_MAX, /* n_sep_by_space */
+ CHAR_MAX, /* p_sign_posn */
+ CHAR_MAX, /* n_sign_posn */
+};
+
+/*
+ * Current locale conversion.
+ */
+struct lconv *__lconv = &C_lconv;
diff --git a/lib/libc/locale/localeconv.c b/lib/libc/locale/localeconv.c
new file mode 100644
index 0000000..f3172af
--- /dev/null
+++ b/lib/libc/locale/localeconv.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)localeconv.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <locale.h>
+
+/*
+ * Return the current locale conversion.
+ */
+struct lconv *
+localeconv()
+{
+ extern struct lconv *__lconv;
+
+ return (__lconv);
+}
diff --git a/lib/libc/locale/mbrune.3 b/lib/libc/locale/mbrune.3
new file mode 100644
index 0000000..5c9d53b
--- /dev/null
+++ b/lib/libc/locale/mbrune.3
@@ -0,0 +1,158 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Borman at Krystal Technologies.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mbrune.3 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt MBRUNE 3
+.Os
+.Sh NAME
+.Nm mbrune ,
+.Nm mbrrune ,
+.Nm mbmb
+.Nd multibyte rune support for C
+.Sh SYNOPSIS
+.Fd #include <rune.h>
+.Ft char *
+.Fn mbrune "const char *string" "rune_t rune"
+.Ft char *
+.Fn mbrrune "const char *string" "rune_t rune"
+.Ft char *
+.Fn mbmb "const char *string" "char *pattern"
+.Sh DESCRIPTION
+These routines provide the corresponding functionality of
+.Fn strchr ,
+.Fn strrchr
+and
+.Fn strstr
+for multibyte strings.
+.Pp
+The
+.Fn mbrune
+function locates the first occurrence of
+.Fn rune
+in the string pointed to by
+.Ar string .
+The terminating
+.Dv NUL
+character is considered part of the string.
+If
+.Fa rune
+is
+.Ql \e0 ,
+.Fn mbrune
+locates the terminating
+.Ql \e0 .
+.Pp
+The
+.Fn mbrrune
+function
+locates the last occurrence of
+.Fa rune
+in the string
+.Fa string .
+If
+.Fa rune
+is
+.Ql \e0 ,
+.Fn mbrune
+locates the terminating
+.Ql \e0 .
+.Pp
+The
+.Fn mbmb
+function locates the first occurrence of the null-terminated string
+.Fa pattern
+in the null-terminated string
+.Fa string.
+If
+.Fa pattern
+is the empty string,
+.Fn mbmb
+returns
+.Fa string ;
+if
+.Fa pattern
+occurs nowhere in
+.Fa string ,
+.Fn mbmb
+returns
+.Dv NULL ;
+otherwise
+.Fn mbmb
+returns a pointer to the first character of the first occurrence of
+.Fa pattern .
+.Sh RETURN VALUES
+The function
+.Fn mbrune
+returns a pointer to the located character, or
+.Dv NULL
+if the character does not appear in the string.
+.Pp
+The
+.Fn mbrrune
+function
+returns a pointer to the character, or
+.Dv NULL
+if the character does not appear in the string.
+.Pp
+The
+.Fn mbmb
+function
+returns a pointer to the
+.Fa pattern ,
+or
+.Dv NULL
+if the
+.Fa pattern
+does not appear in the string.
+.Sh "SEE ALSO
+.Xr mbrune 3 ,
+.Xr rune 3 ,
+.Xr setlocale 3 ,
+.Xr euc 4 ,
+.Xr utf2 4
+.Sh HISTORY
+The
+.Fn mbrune ,
+.Fn mbrrune ,
+and
+.Fn mbmb
+functions
+first appeared in Plan 9 from Bell Labs as
+.Fn utfrune ,
+.Fn utfrrune ,
+and
+.Fn utfutf .
diff --git a/lib/libc/locale/mbrune.c b/lib/libc/locale/mbrune.c
new file mode 100644
index 0000000..92efe83
--- /dev/null
+++ b/lib/libc/locale/mbrune.c
@@ -0,0 +1,112 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)mbrune.c 8.1 (Berkeley) 6/27/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <rune.h>
+#include <stddef.h>
+#include <string.h>
+
+char *
+mbrune(string, c)
+ const char *string;
+ rune_t c;
+{
+ char const *result;
+ rune_t r;
+
+ while ((r = sgetrune(string, MB_LEN_MAX, &result))) {
+ if (r == c)
+ return ((char *)string);
+ string = result == string ? string + 1 : result;
+ }
+
+ return (c == *string ? (char *)string : NULL);
+}
+
+char *
+mbrrune(string, c)
+ const char *string;
+ rune_t c;
+{
+ const char *last = 0;
+ char const *result;
+ rune_t r;
+
+ while ((r = sgetrune(string, MB_LEN_MAX, &result))) {
+ if (r == c)
+ last = string;
+ string = result == string ? string + 1 : result;
+ }
+ return (c == *string ? (char *)string : (char *)last);
+}
+
+char *
+mbmb(string, pattern)
+ const char *string;
+ char *pattern;
+{
+ rune_t first, r;
+ size_t plen, slen;
+ char const *result;
+
+ plen = strlen(pattern);
+ slen = strlen(string);
+ if (plen > slen)
+ return (0);
+
+ first = sgetrune(pattern, plen, &result);
+ if (result == string)
+ return (0);
+
+ while (slen >= plen && (r = sgetrune(string, slen, &result))) {
+ if (r == first) {
+ if (strncmp(string, pattern, slen) == 0)
+ return ((char *) string);
+ }
+ if (result == string) {
+ --slen;
+ ++string;
+ } else {
+ slen -= result - string;
+ string = result;
+ }
+ }
+ return (0);
+}
diff --git a/lib/libc/locale/mskanji.c b/lib/libc/locale/mskanji.c
new file mode 100644
index 0000000..bce27fe
--- /dev/null
+++ b/lib/libc/locale/mskanji.c
@@ -0,0 +1,107 @@
+/*
+ * ja_JP.SJIS locale table for BSD4.4/rune
+ * version 1.0
+ * (C) Sin'ichiro MIYATANI / Phase One, Inc
+ * May 12, 1995
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Phase One, Inc.
+ * 4. The name of Phase One, Inc. may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef XPG4
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)mskanji.c 1.0 (Phase One) 5/5/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <rune.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+rune_t _MSKanji_sgetrune __P((const char *, size_t, char const **));
+int _MSKanji_sputrune __P((rune_t, char *, size_t, char **));
+
+int
+_MSKanji_init(rl)
+ _RuneLocale *rl;
+{
+ rl->sgetrune = _MSKanji_sgetrune;
+ rl->sputrune = _MSKanji_sputrune;
+
+ _CurrentRuneLocale = rl;
+ __mb_cur_max = 2;
+ return (0);
+}
+
+rune_t
+_MSKanji_sgetrune(string, n, result)
+ const char *string;
+ size_t n;
+ char const **result;
+{
+ rune_t rune = 0;
+
+ if (n < 1 ) {
+ rune = _INVALID_RUNE;
+ } else {
+ rune = *( string++ ) & 0xff;
+ if ( ( rune > 0x80 && rune < 0xa0 )
+ || ( rune >= 0xe0 && rune < 0xfa ) ) {
+ if ( n < 2 ) {
+ rune = (rune_t)_INVALID_RUNE;
+ --string;
+ } else {
+ rune = ( rune << 8 ) | ( *( string++ ) & 0xff );
+ }
+ }
+ }
+ if (result) *result = string;
+ return rune;
+}
+
+int
+_MSKanji_sputrune(c, string, n, result)
+ rune_t c;
+ char *string, **result;
+ size_t n;
+{
+ int len, i;
+
+ len = ( c > 0x100 ) ? 2 : 1;
+ if ( n < len ) {
+ if ( result ) *result = (char *) 0;
+ } else {
+ if ( result ) *result = string + len;
+ for ( i = len; i-- > 0; ) {
+ *( string++ ) = c >> ( i << 3 );
+ }
+ }
+ return len;
+}
+#endif /* XPG4 */
diff --git a/lib/libc/locale/multibyte.3 b/lib/libc/locale/multibyte.3
new file mode 100644
index 0000000..fd0c19f
--- /dev/null
+++ b/lib/libc/locale/multibyte.3
@@ -0,0 +1,242 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Donn Seeley of BSDI.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)multibyte.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt MULTIBYTE 3
+.Os
+.Sh NAME
+.Nm mblen ,
+.Nm mbstowcs ,
+.Nm mbtowc ,
+.Nm wcstombs ,
+.Nm wctomb
+.Nd multibyte character support for C
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft int
+.Fn mblen "const char *mbchar" "size_t nbytes"
+.Ft size_t
+.Fn mbstowcs "wchar_t *wcstring" "const char *mbstring" "size_t nwchars"
+.Ft int
+.Fn mbtowc "wchar_t *wcharp" "const char *mbchar" "size_t nbytes"
+.Ft size_t
+.Fn wcstombs "char *mbstring" "const wchar_t *wcstring" "size_t nbytes"
+.Ft int
+.Fn wctomb "char *mbchar" "wchar_t wchar"
+.Sh DESCRIPTION
+The basic elements of some written natural languages such as Chinese
+cannot be represented uniquely with single C
+.Va char Ns s .
+The C standard supports two different ways of dealing with
+extended natural language encodings,
+.Em wide
+characters and
+.Em multibyte
+characters.
+Wide characters are an internal representation
+which allows each basic element to map
+to a single object of type
+.Va wchar_t .
+Multibyte characters are used for input and output
+and code each basic element as a sequence of C
+.Va char Ns s .
+Individual basic elements may map into one or more
+.Pq up to Dv MB_CHAR_MAX
+bytes in a multibyte character.
+.Pp
+The current locale
+.Pq Xr setlocale 3
+governs the interpretation of wide and multibyte characters.
+The locale category
+.Dv LC_CTYPE
+specifically controls this interpretation.
+The
+.Va wchar_t
+type is wide enough to hold the largest value
+in the wide character representations for all locales.
+.Pp
+Multibyte strings may contain
+.Sq shift
+indicators to switch to and from
+particular modes within the given representation.
+If explicit bytes are used to signal shifting,
+these are not recognized as separate characters
+but are lumped with a neighboring character.
+There is always a distinguished
+.Sq initial
+shift state.
+The
+.Fn mbstowcs
+and
+.Fn wcstombs
+functions assume that multibyte strings are interpreted
+starting from the initial shift state.
+The
+.Fn mblen ,
+.Fn mbtowc
+and
+.Fn wctomb
+functions maintain static shift state internally.
+A call with a null
+.Fa mbchar
+pointer returns nonzero if the current locale requires shift states,
+zero otherwise;
+if shift states are required, the shift state is reset to the initial state.
+The internal shift states are undefined after a call to
+.Fn setlocale
+with the
+.Dv LC_CTYPE
+or
+.Dv LC_ALL
+categories.
+.Pp
+For convenience in processing,
+the wide character with value 0
+.Pq the null wide character
+is recognized as the wide character string terminator,
+and the character with value 0
+.Pq the null byte
+is recognized as the multibyte character string terminator.
+Null bytes are not permitted within multibyte characters.
+.Pp
+The
+.Fn mblen
+function computes the length in bytes
+of a multibyte character
+.Fa mbchar .
+Up to
+.Fa nbytes
+bytes are examined.
+.Pp
+The
+.Fn mbtowc
+function converts a multibyte character
+.Fa mbchar
+into a wide character and stores the result
+in the object pointed to by
+.Fa wcharp.
+Up to
+.Fa nbytes
+bytes are examined.
+.Pp
+The
+.Fn wctomb
+function converts a wide character
+.Fa wchar
+into a multibyte character and stores
+the result in
+.Fa mbchar .
+The object pointed to by
+.Fa mbchar
+must be large enough to accommodate the multibyte character.
+.Pp
+The
+.Fn mbstowcs
+function converts a multibyte character string
+.Fa mbstring
+into a wide character string
+.Fa wcstring .
+No more than
+.Fa nwchars
+wide characters are stored.
+A terminating null wide character is appended if there is room.
+.Pp
+The
+.Fn wcstombs
+function converts a wide character string
+.Fa wcstring
+into a multibyte character string
+.Fa mbstring .
+Up to
+.Fa nbytes
+bytes are stored in
+.Fa mbstring .
+Partial multibyte characters at the end of the string are not stored.
+The multibyte character string is null terminated if there is room.
+.Sh "RETURN VALUES
+If multibyte characters are not supported in the current locale,
+all of these functions will return \-1 if characters can be processed,
+otherwise 0.
+.Pp
+If
+.Fa mbchar
+is
+.Dv NULL ,
+the
+.Fn mblen ,
+.Fn mbtowc
+and
+.Fn wctomb
+functions return nonzero if shift states are supported,
+zero otherwise.
+If
+.Fa mbchar
+is valid,
+then these functions return
+the number of bytes processed in
+.Fa mbchar ,
+or \-1 if no multibyte character
+could be recognized or converted.
+.Pp
+The
+.Fn mbstowcs
+function returns the number of wide characters converted,
+not counting any terminating null wide character.
+The
+.Fn wcstombs
+function returns the number of bytes converted,
+not counting any terminating null byte.
+If any invalid multibyte characters are encountered,
+both functions return \-1.
+.Sh "SEE ALSO
+.Xr mbrune 3 ,
+.Xr rune 3 ,
+.Xr setlocale 3 ,
+.Xr euc 4 ,
+.Xr utf2 4
+.Sh STANDARDS
+The
+.Fn mblen ,
+.Fn mbstowcs ,
+.Fn mbtowc ,
+.Fn wcstombs
+and
+.Fn wctomb
+functions conform to
+.St -ansiC .
+.Sh BUGS
+The current implementation does not support shift states.
diff --git a/lib/libc/locale/nomacros.c b/lib/libc/locale/nomacros.c
new file mode 100644
index 0000000..45c0db7
--- /dev/null
+++ b/lib/libc/locale/nomacros.c
@@ -0,0 +1,9 @@
+/*
+ * Tell <ctype.h> to generate extern versions of all its inline
+ * functions. The extern versions get called if the system doesn't
+ * support inlines or the user defines _DONT_USE_CTYPE_INLINE_
+ * before including <ctype.h>.
+ */
+#define _EXTERNALIZE_CTYPE_INLINES_
+
+#include <ctype.h>
diff --git a/lib/libc/locale/none.c b/lib/libc/locale/none.c
new file mode 100644
index 0000000..41f70ae
--- /dev/null
+++ b/lib/libc/locale/none.c
@@ -0,0 +1,91 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)none.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <rune.h>
+#include <errno.h>
+#include <stdlib.h>
+
+rune_t _none_sgetrune __P((const char *, size_t, char const **));
+int _none_sputrune __P((rune_t, char *, size_t, char **));
+
+int
+_none_init(rl)
+ _RuneLocale *rl;
+{
+ rl->sgetrune = _none_sgetrune;
+ rl->sputrune = _none_sputrune;
+ _CurrentRuneLocale = rl;
+ __mb_cur_max = 1;
+ return(0);
+}
+
+rune_t
+_none_sgetrune(string, n, result)
+ const char *string;
+ size_t n;
+ char const **result;
+{
+ if (n < 1) {
+ if (result)
+ *result = string;
+ return(_INVALID_RUNE);
+ }
+ if (result)
+ *result = string + 1;
+ return(*string & 0xff);
+}
+
+int
+_none_sputrune(c, string, n, result)
+ rune_t c;
+ char *string, **result;
+ size_t n;
+{
+ if (n >= 1) {
+ if (string)
+ *string = c;
+ if (result)
+ *result = string + 1;
+ } else if (result)
+ *result = (char *)0;
+ return(1);
+}
diff --git a/lib/libc/locale/rune.3 b/lib/libc/locale/rune.3
new file mode 100644
index 0000000..a479e33
--- /dev/null
+++ b/lib/libc/locale/rune.3
@@ -0,0 +1,272 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Borman at Krystal Technologies.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)rune.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt RUNE 3
+.Os
+.Sh NAME
+.Nm setrunelocale ,
+.Nm setinvalidrune ,
+.Nm sgetrune ,
+.Nm sputrune
+.Nd rune support for C
+.Sh SYNOPSIS
+.Fd #include <rune.h>
+.Fd #include <errno.h>
+.Ft int
+.Fn setrunelocale "char *locale"
+.Ft void
+.Fn setinvalidrune "rune_t rune"
+.Ft rune_t
+.Fn sgetrune "const char *string" "size_t n" "char const **result"
+.Ft int
+.Fn sputrune "rune_t rune" "char *string" "size_t n" "char **result"
+.Pp
+.Fd #include <stdio.h>
+.Ft long
+.Fn fgetrune "FILE *stream"
+.Ft int
+.Fn fungetrune "rune_t rune" "FILE *stream"
+.Ft int
+.Fn fputrune "rune_t rune" "FILE *stream"
+.Sh DESCRIPTION
+The
+.Fn setrunelocale
+controls the type of encoding used to represent runes as multibyte strings
+as well as the properties of the runes as defined in
+.Aq Pa ctype.h .
+The
+.Fa locale
+argument indicates which locale to load.
+If the locale is successfully loaded,
+.Dv 0
+is returned, otherwise an errno value is returned to indicate the
+type of error.
+.Pp
+The
+.Fn setinvalidrune
+function sets the value of the global value
+.Ev _INVALID_RUNE
+to be
+.Fa rune .
+.Pp
+The
+.Fn sgetrune
+function tries to read a single multibyte character from
+.Fa string ,
+which is at most
+.Fa n
+bytes long.
+If
+.Fn sgetrune
+is successful, the rune is returned.
+If
+.Fa result
+is not
+.Dv NULL ,
+.Fa *result
+will point to the first byte which was not converted in
+.Fa string .
+If the first
+.Fa n
+bytes of
+.Fa string
+do not describe a full multibyte character,
+.Ev _INVALID_RUNE
+is returned and
+.Fa *result
+will point to
+.Fa string .
+If there is an encoding error at the start of
+.Fa string ,
+.Ev _INVALID_RUNE
+is returned and
+.Fa *result
+will point to the second character of
+.Fa string .
+.Pp
+the
+.Fn sputrune
+function tries to encode
+.Fa rune
+as a multibyte string and store it at
+.Fa string ,
+but no more than
+.Fa n
+bytes will be stored.
+If
+.Fa result
+is not
+.Dv NULL ,
+.Fa *result
+will be set to point to the first byte in string following the new
+multibyte character.
+If
+.Fa string
+is
+.Dv NULL ,
+.Fa *result
+will point to
+.Dv "(char *)0 +"
+.Fa x ,
+where
+.Fa x
+is the number of bytes that would be needed to store the multibyte value.
+If the multibyte character would consist of more than
+.Fa n
+bytes and
+.Fa result
+is not
+.Dv NULL ,
+.Fa *result
+will be set to
+.Dv NULL.
+In all cases,
+.Fn sputrune
+will return the number of bytes which would be needed to store
+.Fa rune
+as a multibyte character.
+.Pp
+The
+.Fn fgetrune
+function operates the same as
+.Fn sgetrune
+with the exception that it attempts to read enough bytes from
+.Fa stream
+to decode a single rune. It returns either
+.Ev EOF
+on end of file,
+.Ev _INVALID_RUNE
+on an encoding error, or the rune decoded if all went well.
+.Pp
+The
+.Fn fungetrune
+function pushes the multibyte encoding, as provided by
+.Fn sputrune ,
+of
+.Fa rune
+onto
+.Fa stream
+such that the next
+.Fn fgetrune
+call will return
+.Fa rune .
+It returns
+.Ev EOF
+if it fails and
+.Dv 0
+on success.
+.Pp
+The
+.Fn fputrune
+function writes the multibyte encoding of
+.Fa rune ,
+as provided by
+.Fn sputrune ,
+onto
+.Fa stream .
+It returns
+.Ev EOF
+on failure and
+.Dv 0
+on success.
+.Sh RETURN VALUES
+The
+.Fn setrunelocale
+function returns one of the following values:
+.Bl -tag -width WWWWWWWW
+.It Dv 0
+.Fn setrunelocale
+was successful.
+.It Ev EFAULT
+.Fa locale
+was
+.Dv NULL .
+.It Ev ENOENT
+The locale could not be found.
+.It Ev EFTYPE
+The file found was not a valid file.
+.It Ev EINVAL
+The encoding indicated by the locale was unknown.
+.El
+.Pp
+The
+.Fn sgetrune
+function either returns the rune read or
+.Ev _INVALID_RUNE .
+The
+.Fn sputrune
+function returns the number of bytes needed to store
+.Fa rune
+as a multibyte string.
+.Sh FILES
+.Bl -tag -width /usr/share/locale/locale/LC_CTYPE -compact
+.It Pa $PATH_LOCALE/ Ns Em locale Ns /LC_CTYPE
+.It Pa /usr/share/locale/ Ns Em locale Ns /LC_CTYPE
+binary LC_CTYPE file for the locale
+.Em locale .
+.El
+.Sh "SEE ALSO
+.Xr mbrune 3 ,
+.Xr setlocale 3 ,
+.Xr euc 4 ,
+.Xr utf2 4
+.Sh NOTE
+The ANSI C type
+.Ev wchar_t
+is the same as
+.Ev rune_t .
+.Ev Rune_t
+was chosen to accent the purposeful choice of not basing the
+system with the ANSI C
+primitives, which were, shall we say, less aesthetic.
+.Sh HISTORY
+These functions first appeared in
+.Bx 4.4 .
+.Pp
+The
+.Fn setrunelocale
+function and the other non-ANSI rune functions were inspired by
+.Nm Plan 9 from Bell Labs
+as a much more sane alternative to the ANSI multibyte and
+wide character support.
+.\"They were conceived at the San Diego 1993 Summer USENIX conference by
+.\"Paul Borman of Krystal Technologies, Keith Bostic of CSRG and Andrew Hume
+.\"of Bell Labs.
+.Pp
+All of the ANSI multibyte and wide character
+support functions are built using the rune functions.
diff --git a/lib/libc/locale/rune.c b/lib/libc/locale/rune.c
new file mode 100644
index 0000000..bc4d07c
--- /dev/null
+++ b/lib/libc/locale/rune.c
@@ -0,0 +1,173 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <rune.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+_RuneLocale *
+_Read_RuneMagi(fp)
+ FILE *fp;
+{
+ char *data;
+ void *lastp;
+ _RuneLocale *rl;
+ _RuneEntry *rr;
+ struct stat sb;
+ int x;
+
+ if (fstat(fileno(fp), &sb) < 0)
+ return(0);
+
+ if (sb.st_size < sizeof(_RuneLocale))
+ return(0);
+
+ if ((data = malloc(sb.st_size)) == NULL)
+ return(0);
+
+ rewind(fp); /* Someone might have read the magic number once already */
+
+ if (fread(data, sb.st_size, 1, fp) != 1) {
+ free(data);
+ return(0);
+ }
+
+ rl = (_RuneLocale *)data;
+ lastp = data + sb.st_size;
+
+ rl->variable = rl + 1;
+
+ if (memcmp(rl->magic, _RUNE_MAGIC_1, sizeof(rl->magic))) {
+ free(data);
+ return(0);
+ }
+
+ rl->invalid_rune = ntohl(rl->invalid_rune);
+ rl->variable_len = ntohl(rl->variable_len);
+ rl->runetype_ext.nranges = ntohl(rl->runetype_ext.nranges);
+ rl->maplower_ext.nranges = ntohl(rl->maplower_ext.nranges);
+ rl->mapupper_ext.nranges = ntohl(rl->mapupper_ext.nranges);
+
+ for (x = 0; x < _CACHED_RUNES; ++x) {
+ rl->runetype[x] = ntohl(rl->runetype[x]);
+ rl->maplower[x] = ntohl(rl->maplower[x]);
+ rl->mapupper[x] = ntohl(rl->mapupper[x]);
+ }
+
+ rl->runetype_ext.ranges = (_RuneEntry *)rl->variable;
+ rl->variable = rl->runetype_ext.ranges + rl->runetype_ext.nranges;
+ if (rl->variable > lastp) {
+ free(data);
+ return(0);
+ }
+
+ rl->maplower_ext.ranges = (_RuneEntry *)rl->variable;
+ rl->variable = rl->maplower_ext.ranges + rl->maplower_ext.nranges;
+ if (rl->variable > lastp) {
+ free(data);
+ return(0);
+ }
+
+ rl->mapupper_ext.ranges = (_RuneEntry *)rl->variable;
+ rl->variable = rl->mapupper_ext.ranges + rl->mapupper_ext.nranges;
+ if (rl->variable > lastp) {
+ free(data);
+ return(0);
+ }
+
+ for (x = 0; x < rl->runetype_ext.nranges; ++x) {
+ rr = rl->runetype_ext.ranges;
+
+ rr[x].min = ntohl(rr[x].min);
+ rr[x].max = ntohl(rr[x].max);
+ if ((rr[x].map = ntohl(rr[x].map)) == 0) {
+ int len = rr[x].max - rr[x].min + 1;
+ rr[x].types = rl->variable;
+ rl->variable = rr[x].types + len;
+ if (rl->variable > lastp) {
+ free(data);
+ return(0);
+ }
+ while (len-- > 0)
+ rr[x].types[len] = ntohl(rr[x].types[len]);
+ } else
+ rr[x].types = 0;
+ }
+
+ for (x = 0; x < rl->maplower_ext.nranges; ++x) {
+ rr = rl->maplower_ext.ranges;
+
+ rr[x].min = ntohl(rr[x].min);
+ rr[x].max = ntohl(rr[x].max);
+ rr[x].map = ntohl(rr[x].map);
+ }
+
+ for (x = 0; x < rl->mapupper_ext.nranges; ++x) {
+ rr = rl->mapupper_ext.ranges;
+
+ rr[x].min = ntohl(rr[x].min);
+ rr[x].max = ntohl(rr[x].max);
+ rr[x].map = ntohl(rr[x].map);
+ }
+ if (((char *)rl->variable) + rl->variable_len > (char *)lastp) {
+ free(data);
+ return(0);
+ }
+
+ /*
+ * Go out and zero pointers that should be zero.
+ */
+ if (!rl->variable_len)
+ rl->variable = 0;
+
+ if (!rl->runetype_ext.nranges)
+ rl->runetype_ext.ranges = 0;
+
+ if (!rl->maplower_ext.nranges)
+ rl->maplower_ext.ranges = 0;
+
+ if (!rl->mapupper_ext.nranges)
+ rl->mapupper_ext.ranges = 0;
+
+ return(rl);
+}
diff --git a/lib/libc/locale/runetype.c b/lib/libc/locale/runetype.c
new file mode 100644
index 0000000..282f806
--- /dev/null
+++ b/lib/libc/locale/runetype.c
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <rune.h>
+
+unsigned long
+___runetype(c)
+ _BSD_CT_RUNE_T_ c;
+{
+#ifdef XPG4
+ int x;
+ _RuneRange *rr = &_CurrentRuneLocale->runetype_ext;
+ _RuneEntry *re = rr->ranges;
+
+ if (c < 0 || c == EOF)
+ return(0L);
+
+ for (x = 0; x < rr->nranges; ++x, ++re) {
+ if (c < re->min)
+ return(0L);
+ if (c <= re->max) {
+ if (re->types)
+ return(re->types[c - re->min]);
+ else
+ return(re->map);
+ }
+ }
+#endif
+ return(0L);
+}
diff --git a/lib/libc/locale/setinvalidrune.c b/lib/libc/locale/setinvalidrune.c
new file mode 100644
index 0000000..45a2a47
--- /dev/null
+++ b/lib/libc/locale/setinvalidrune.c
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <rune.h>
+
+void
+setinvalidrune(ir)
+ rune_t ir;
+{
+ _INVALID_RUNE = ir;
+}
diff --git a/lib/libc/locale/setlocale.3 b/lib/libc/locale/setlocale.3
new file mode 100644
index 0000000..4750034
--- /dev/null
+++ b/lib/libc/locale/setlocale.3
@@ -0,0 +1,336 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Donn Seeley at BSDI.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)setlocale.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt SETLOCALE 3
+.Os
+.Sh NAME
+.Nm setlocale ,
+.Nm localeconv
+.Nd natural language formatting for C
+.Sh SYNOPSIS
+.Fd #include <locale.h>
+.Ft char *
+.Fn setlocale "int category" "const char *locale"
+.Ft struct lconv *
+.Fn localeconv "void"
+.Sh DESCRIPTION
+The
+.Fn setlocale
+function sets the C library's notion
+of natural language formatting style
+for particular sets of routines.
+Each such style is called a
+.Sq locale
+and is invoked using an appropriate name passed as a C string.
+The
+.Fn localeconv
+routine returns the current locale's parameters
+for formatting numbers.
+.Pp
+The
+.Fn setlocale
+function recognizes several categories of routines.
+These are the categories and the sets of routines they select:
+.Pp
+.Bl -tag -width LC_MONETARY
+.It Dv LC_ALL
+Set the entire locale generically.
+.It Dv LC_COLLATE
+Set a locale for string collation routines.
+This controls alphabetic ordering in
+.Fn strcoll
+and
+.Fn strxfrm .
+.It Dv LC_CTYPE
+Set a locale for the
+.Xr ctype 3 ,
+.Xr mbrune 3 ,
+.Xr multibyte 3
+and
+.Xr rune 3
+functions.
+This controls recognition of upper and lower case,
+alphabetic or non-alphabetic characters,
+and so on. The real work is done by the
+.Fn setrunelocale
+function.
+.It Dv LC_MESSAGES
+Set a locale for message catalogs, see
+.Xr catopen 3
+function.
+.It Dv LC_MONETARY
+Set a locale for formatting monetary values;
+this affects the
+.Fn localeconv
+function.
+.It Dv LC_NUMERIC
+Set a locale for formatting numbers.
+This controls the formatting of decimal points
+in input and output of floating point numbers
+in functions such as
+.Fn printf
+and
+.Fn scanf ,
+as well as values returned by
+.Fn localeconv .
+.It Dv LC_TIME
+Set a locale for formatting dates and times using the
+.Fn strftime
+function.
+.El
+.Pp
+Only three locales are defined by default,
+the empty string
+.Li "\&""\|""
+which denotes the native environment, and the
+.Li "\&""C""
+and
+.Li "\&""POSIX""
+locales, which denote the C language environment.
+A
+.Fa locale
+argument of
+.Dv NULL
+causes
+.Fn setlocale
+to return the current locale.
+By default, C programs start in the
+.Li "\&""C""
+locale.
+The only function in the library that sets the locale is
+.Fn setlocale ;
+the locale is never changed as a side effect of some other routine.
+.Pp
+The
+.Fn localeconv
+function returns a pointer to a structure
+which provides parameters for formatting numbers,
+especially currency values:
+.Bd -literal -offset indent
+struct lconv {
+ char *decimal_point;
+ char *thousands_sep;
+ char *grouping;
+ char *int_curr_symbol;
+ char *currency_symbol;
+ char *mon_decimal_point;
+ char *mon_thousands_sep;
+ char *mon_grouping;
+ char *positive_sign;
+ char *negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+};
+.Ed
+.Pp
+The individual fields have the following meanings:
+.Pp
+.Bl -tag -width mon_decimal_point
+.It Fa decimal_point
+The decimal point character, except for currency values.
+.It Fa thousands_sep
+The separator between groups of digits
+before the decimal point, except for currency values.
+.It Fa grouping
+The sizes of the groups of digits, except for currency values.
+This is a pointer to a vector of integers, each of size
+.Va char ,
+representing group size from low order digit groups
+to high order (right to left).
+The list may be terminated with 0 or
+.Dv CHAR_MAX .
+If the list is terminated with 0,
+the last group size before the 0 is repeated to account for all the digits.
+If the list is terminated with
+.Dv CHAR_MAX ,
+no more grouping is performed.
+.It Fa int_curr_symbol
+The standardized international currency symbol.
+.It Fa currency_symbol
+The local currency symbol.
+.It Fa mon_decimal_point
+The decimal point character for currency values.
+.It Fa mon_thousands_sep
+The separator for digit groups in currency values.
+.It Fa mon_grouping
+Like
+.Fa grouping
+but for currency values.
+.It Fa positive_sign
+The character used to denote nonnegative currency values,
+usually the empty string.
+.It Fa negative_sign
+The character used to denote negative currency values,
+usually a minus sign.
+.It Fa int_frac_digits
+The number of digits after the decimal point
+in an international-style currency value.
+.It Fa frac_digits
+The number of digits after the decimal point
+in the local style for currency values.
+.It Fa p_cs_precedes
+1 if the currency symbol precedes the currency value
+for nonnegative values, 0 if it follows.
+.It Fa p_sep_by_space
+1 if a space is inserted between the currency symbol
+and the currency value for nonnegative values, 0 otherwise.
+.It Fa n_cs_precedes
+Like
+.Fa p_cs_precedes
+but for negative values.
+.It Fa n_sep_by_space
+Like
+.Fa p_sep_by_space
+but for negative values.
+.It Fa p_sign_posn
+The location of the
+.Fa positive_sign
+with respect to a nonnegative quantity and the
+.Fa currency_symbol ,
+coded as follows:
+.Bl -tag -width 3n -compact
+.It Li 0
+Parentheses around the entire string.
+.It Li 1
+Before the string.
+.It Li 2
+After the string.
+.It Li 3
+Just before
+.Fa currency_symbol .
+.It Li 4
+Just after
+.Fa currency_symbol .
+.El
+.It Fa n_sign_posn
+Like
+.Fa p_sign_posn
+but for negative currency values.
+.El
+.Pp
+Unless mentioned above,
+an empty string as a value for a field
+indicates a zero length result or
+a value that is not in the current locale.
+A
+.Dv CHAR_MAX
+result similarly denotes an unavailable value.
+.Sh "RETURN VALUES
+The
+.Fn setlocale
+function returns
+.Dv NULL
+and fails to change the locale
+if the given combination of
+.Fa category
+and
+.Fa locale
+makes no sense.
+The
+.Fn localeconv
+function returns a pointer to a static object
+which may be altered by later calls to
+.Fn setlocale
+or
+.Fn localeconv .
+.Sh FILES
+.Bl -tag -width /usr/share/locale/locale/category -compact
+.It Pa $PATH_LOCALE/ Ns Em locale/category
+.It Pa /usr/share/locale/ Ns Em locale/category
+locale file for the locale
+.Em locale
+and the category
+.Em category .
+.El
+.Sh "SEE ALSO
+.Xr colldef 1 ,
+.Xr mklocale 1 ,
+.Xr catopen 3 ,
+.Xr ctype 3 ,
+.Xr mbrune 3 ,
+.Xr multibyte 3 ,
+.Xr rune 3 ,
+.Xr strcoll 3 ,
+.Xr strxfrm 3 ,
+.Xr euc 4 ,
+.Xr utf2 4
+.Sh STANDARDS
+The
+.Fn setlocale
+and
+.Fn localeconv
+functions conform to
+.St -ansiC .
+.Sh HISTORY
+The
+.Fn setlocale
+and
+.Fn localeconv
+functions first appeared in
+.Bx 4.4 .
+.Sh BUGS
+The current implementation supports only the
+.Li "\&""C""
+and
+.Li "\&""POSIX""
+locales for all but the
+.Dv LC_COLLATE ,
+.Dv LC_CTYPE ,
+and
+.Dv LC_TIME
+categories.
+.Pp
+In spite of the gnarly currency support in
+.Fn localeconv ,
+the standards don't include any functions
+for generalized currency formatting.
+.Pp
+Use of
+.Dv LC_MONETARY
+could lead to misleading results until we have a real time currency
+conversion function.
+.Dv LC_NUMERIC
+and
+.Dv LC_TIME
+are personal choices and should not be wrapped up with the other categories.
diff --git a/lib/libc/locale/setlocale.c b/lib/libc/locale/setlocale.c
new file mode 100644
index 0000000..179be54
--- /dev/null
+++ b/lib/libc/locale/setlocale.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifdef LIBC_RCS
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <locale.h>
+#include <rune.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "collate.h"
+#include "setlocale.h"
+
+/*
+ * Category names for getenv()
+ */
+static char *categories[_LC_LAST] = {
+ "LC_ALL",
+ "LC_COLLATE",
+ "LC_CTYPE",
+ "LC_MONETARY",
+ "LC_NUMERIC",
+ "LC_TIME",
+ "LC_MESSAGES",
+};
+
+/*
+ * Current locales for each category
+ */
+static char current_categories[_LC_LAST][ENCODING_LEN + 1] = {
+ "C",
+ "C",
+ "C",
+ "C",
+ "C",
+ "C",
+ "C",
+};
+
+/*
+ * The locales we are going to try and load
+ */
+static char new_categories[_LC_LAST][ENCODING_LEN + 1];
+static char saved_categories[_LC_LAST][ENCODING_LEN + 1];
+
+static char current_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)];
+
+static char *currentlocale __P((void));
+static char *loadlocale __P((int));
+static int stub_load_locale __P((const char *));
+
+extern int __time_load_locale __P((const char *)); /* strftime.c */
+
+#ifdef XPG4
+extern int _xpg4_setrunelocale __P((char *));
+#endif
+
+char *
+setlocale(category, locale)
+ int category;
+ const char *locale;
+{
+ int i, j, len;
+ char *env, *r;
+
+ if (category < LC_ALL || category >= _LC_LAST)
+ return (NULL);
+
+ if (!locale)
+ return (category != LC_ALL ?
+ current_categories[category] : currentlocale());
+
+ /*
+ * Default to the current locale for everything.
+ */
+ for (i = 1; i < _LC_LAST; ++i)
+ (void)strcpy(new_categories[i], current_categories[i]);
+
+ /*
+ * Now go fill up new_categories from the locale argument
+ */
+ if (!*locale) {
+ env = getenv(categories[category]);
+
+ if (category != LC_ALL && (!env || !*env))
+ env = getenv(categories[LC_ALL]);
+
+ if (!env || !*env)
+ env = getenv("LANG");
+
+ if (!env || !*env)
+ env = "C";
+
+ (void) strncpy(new_categories[category], env, ENCODING_LEN);
+ new_categories[category][ENCODING_LEN] = '\0';
+ if (category == LC_ALL) {
+ for (i = 1; i < _LC_LAST; ++i) {
+ if (!(env = getenv(categories[i])) || !*env)
+ env = new_categories[LC_ALL];
+ (void)strncpy(new_categories[i], env, ENCODING_LEN);
+ new_categories[i][ENCODING_LEN] = '\0';
+ }
+ }
+ } else if (category != LC_ALL) {
+ (void)strncpy(new_categories[category], locale, ENCODING_LEN);
+ new_categories[category][ENCODING_LEN] = '\0';
+ } else {
+ if ((r = strchr(locale, '/')) == NULL) {
+ for (i = 1; i < _LC_LAST; ++i) {
+ (void)strncpy(new_categories[i], locale, ENCODING_LEN);
+ new_categories[i][ENCODING_LEN] = '\0';
+ }
+ } else {
+ for (i = 1; r[1] == '/'; ++r);
+ if (!r[1])
+ return (NULL); /* Hmm, just slashes... */
+ do {
+ len = r - locale > ENCODING_LEN ? ENCODING_LEN : r - locale;
+ (void)strncpy(new_categories[i], locale, len);
+ new_categories[i][len] = '\0';
+ i++;
+ locale = r;
+ while (*locale == '/')
+ ++locale;
+ while (*++r && *r != '/');
+ } while (*locale);
+ while (i < _LC_LAST) {
+ (void)strcpy(new_categories[i],
+ new_categories[i-1]);
+ i++;
+ }
+ }
+ }
+
+ if (category)
+ return (loadlocale(category));
+
+ for (i = 1; i < _LC_LAST; ++i) {
+ (void)strcpy(saved_categories[i], current_categories[i]);
+ if (loadlocale(i) == NULL) {
+ for (j = 1; j < i; j++) {
+ (void)strcpy(new_categories[j],
+ saved_categories[j]);
+ /* XXX can fail too */
+ (void)loadlocale(j);
+ }
+ return (NULL);
+ }
+ }
+ return (currentlocale());
+}
+
+static char *
+currentlocale()
+{
+ int i;
+
+ (void)strcpy(current_locale_string, current_categories[1]);
+
+ for (i = 2; i < _LC_LAST; ++i)
+ if (strcmp(current_categories[1], current_categories[i])) {
+ for (i = 2; i < _LC_LAST; ++i) {
+ (void) strcat(current_locale_string, "/");
+ (void) strcat(current_locale_string, current_categories[i]);
+ }
+ break;
+ }
+ return (current_locale_string);
+}
+
+static char *
+loadlocale(category)
+ int category;
+{
+ char *ret;
+ char *new = new_categories[category];
+ char *old = current_categories[category];
+
+ if (_PathLocale == NULL) {
+ char *p = getenv("PATH_LOCALE");
+
+ if (p != NULL
+#ifndef __NETBSD_SYSCALLS
+ && !issetugid()
+#endif
+ ) {
+ if (strlen(p) + 1/*"/"*/ + ENCODING_LEN +
+ 1/*"/"*/ + CATEGORY_LEN >= PATH_MAX)
+ return (NULL);
+ _PathLocale = strdup(p);
+ if (_PathLocale == NULL)
+ return (NULL);
+ } else
+ _PathLocale = _PATH_LOCALE;
+ }
+
+ if (strcmp(new, old) == 0)
+ return (old);
+
+ if (category == LC_CTYPE) {
+#ifdef XPG4
+ ret = _xpg4_setrunelocale(new) ? NULL : new;
+#else
+ ret = setrunelocale(new) ? NULL : new;
+#endif
+ if (!ret) {
+#ifdef XPG4
+ (void)_xpg4_setrunelocale(old);
+#else
+ (void)setrunelocale(old);
+#endif
+ } else
+ (void)strcpy(old, new);
+ return (ret);
+ }
+
+ if (category == LC_COLLATE) {
+ ret = (__collate_load_tables(new) < 0) ? NULL : new;
+ if (!ret)
+ (void)__collate_load_tables(old);
+ else
+ (void)strcpy(old, new);
+ return (ret);
+ }
+
+ if (category == LC_TIME) {
+ ret = (__time_load_locale(new) < 0) ? NULL : new;
+ if (!ret)
+ (void)__time_load_locale(old);
+ else
+ (void)strcpy(old, new);
+ return (ret);
+ }
+
+ if (category == LC_MONETARY ||
+ category == LC_MESSAGES ||
+ category == LC_NUMERIC) {
+ ret = stub_load_locale(new) ? NULL : new;
+ if (!ret)
+ (void)stub_load_locale(old);
+ else
+ (void)strcpy(old, new);
+ return (ret);
+ }
+
+ /* Just in case...*/
+ return (NULL);
+}
+
+static int
+stub_load_locale(encoding)
+const char *encoding;
+{
+ char name[PATH_MAX];
+ struct stat st;
+
+ if (!encoding)
+ return(1);
+ /*
+ * The "C" and "POSIX" locale are always here.
+ */
+ if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX"))
+ return(0);
+ if (!_PathLocale)
+ return(1);
+ /* Range checking not needed, encoding has fixed size */
+ strcpy(name, _PathLocale);
+ strcat(name, "/");
+ strcat(name, encoding);
+#if 0
+ /*
+ * Some day we will actually look at this file.
+ */
+#endif
+ return (stat(name, &st) != 0 || !S_ISDIR(st.st_mode));
+}
diff --git a/lib/libc/locale/setlocale.h b/lib/libc/locale/setlocale.h
new file mode 100644
index 0000000..f3b2a22
--- /dev/null
+++ b/lib/libc/locale/setlocale.h
@@ -0,0 +1,34 @@
+#ifndef _SETLOCALE_H
+#define _SETLOCALE_H
+/*
+ * Copyright (C) 1997 by Andrey A. Chernov, Moscow, Russia.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define ENCODING_LEN 31
+#define CATEGORY_LEN 11
+
+extern char *_PathLocale;
+
+#endif /* SETLOCALE_H */
diff --git a/lib/libc/locale/setrunelocale.c b/lib/libc/locale/setrunelocale.c
new file mode 100644
index 0000000..8cfddab
--- /dev/null
+++ b/lib/libc/locale/setrunelocale.c
@@ -0,0 +1,140 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <rune.h>
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "setlocale.h"
+
+extern int _none_init __P((_RuneLocale *));
+#ifdef XPG4
+extern int _UTF2_init __P((_RuneLocale *));
+extern int _EUC_init __P((_RuneLocale *));
+extern int _BIG5_init __P((_RuneLocale *));
+extern int _MSKanji_init __P((_RuneLocale *));
+extern int _xpg4_setrunelocale __P((char *));
+#endif
+extern _RuneLocale *_Read_RuneMagi __P((FILE *));
+
+#ifdef XPG4
+int
+setrunelocale(encoding)
+ char *encoding;
+{
+ return _xpg4_setrunelocale(encoding);
+}
+#endif
+
+int
+#ifndef XPG4
+setrunelocale(encoding)
+#else
+_xpg4_setrunelocale(encoding)
+#endif
+ char *encoding;
+{
+ FILE *fp;
+ char name[PATH_MAX];
+ _RuneLocale *rl;
+
+ if (!encoding || strlen(encoding) > ENCODING_LEN)
+ return(EFAULT);
+
+ /*
+ * The "C" and "POSIX" locale are always here.
+ */
+ if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX")) {
+ _CurrentRuneLocale = &_DefaultRuneLocale;
+ return(0);
+ }
+
+ if (_PathLocale == NULL) {
+ char *p = getenv("PATH_LOCALE");
+
+ if (p != NULL
+#ifndef __NETBSD_SYSCALLS
+ && !issetugid()
+#endif
+ ) {
+ if (strlen(p) + 1/*"/"*/ + ENCODING_LEN +
+ 1/*"/"*/ + CATEGORY_LEN >= PATH_MAX)
+ return(EFAULT);
+ _PathLocale = strdup(p);
+ if (_PathLocale == NULL)
+ return (errno);
+ } else
+ _PathLocale = _PATH_LOCALE;
+ }
+ /* Range checking not needed, encoding length already checked above */
+ (void) strcpy(name, _PathLocale);
+ (void) strcat(name, "/");
+ (void) strcat(name, encoding);
+ (void) strcat(name, "/LC_CTYPE");
+
+ if ((fp = fopen(name, "r")) == NULL)
+ return(ENOENT);
+
+ if ((rl = _Read_RuneMagi(fp)) == 0) {
+ fclose(fp);
+ return(EFTYPE);
+ }
+ fclose(fp);
+
+#ifdef XPG4
+ if (!rl->encoding[0] || !strcmp(rl->encoding, "UTF2"))
+ return(_UTF2_init(rl));
+#else
+ if (!rl->encoding[0])
+ return(EINVAL);
+#endif
+ else if (!strcmp(rl->encoding, "NONE"))
+ return(_none_init(rl));
+#ifdef XPG4
+ else if (!strcmp(rl->encoding, "EUC"))
+ return(_EUC_init(rl));
+ else if (!strcmp(rl->encoding, "BIG5"))
+ return(_BIG5_init(rl));
+ else if (!strcmp(rl->encoding, "MSKanji"))
+ return(_MSKanji_init(rl));
+#endif
+ else
+ return(EINVAL);
+}
+
diff --git a/lib/libc/locale/table.c b/lib/libc/locale/table.c
new file mode 100644
index 0000000..556a8de
--- /dev/null
+++ b/lib/libc/locale/table.c
@@ -0,0 +1,162 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)table.c 8.1 (Berkeley) 6/27/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ctype.h>
+#include <rune.h>
+
+extern rune_t _none_sgetrune __P((const char *, size_t, char const **));
+extern int _none_sputrune __P((rune_t, char *, size_t, char **));
+extern int _none_init __P((char *, char **));
+
+_RuneLocale _DefaultRuneLocale = {
+ _RUNE_MAGIC_1,
+ "none",
+ _none_sgetrune,
+ _none_sputrune,
+ 0xFFFD,
+
+ { /*00*/ _C, _C, _C, _C,
+ _C, _C, _C, _C,
+ /*08*/ _C, _C|_S|_B, _C|_S, _C|_S,
+ _C|_S, _C|_S, _C, _C,
+ /*10*/ _C, _C, _C, _C,
+ _C, _C, _C, _C,
+ /*18*/ _C, _C, _C, _C,
+ _C, _C, _C, _C,
+ /*20*/ _S|_B|_R, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ /*28*/ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ /*30*/ _D|_R|_G|_X|0, _D|_R|_G|_X|1, _D|_R|_G|_X|2, _D|_R|_G|_X|3,
+ _D|_R|_G|_X|4, _D|_R|_G|_X|5, _D|_R|_G|_X|6, _D|_R|_G|_X|7,
+ /*38*/ _D|_R|_G|_X|8, _D|_R|_G|_X|9, _P|_R|_G, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ /*40*/ _P|_R|_G, _U|_X|_R|_G|_A|10, _U|_X|_R|_G|_A|11, _U|_X|_R|_G|_A|12,
+ _U|_X|_R|_G|_A|13, _U|_X|_R|_G|_A|14, _U|_X|_R|_G|_A|15, _U|_R|_G|_A,
+ /*48*/ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A,
+ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A,
+ /*50*/ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A,
+ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A,
+ /*58*/ _U|_R|_G|_A, _U|_R|_G|_A, _U|_R|_G|_A, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ /*60*/ _P|_R|_G, _L|_X|_R|_G|_A|10, _L|_X|_R|_G|_A|11, _L|_X|_R|_G|_A|12,
+ _L|_X|_R|_G|_A|13, _L|_X|_R|_G|_A|14, _L|_X|_R|_G|_A|15, _L|_R|_G|_A,
+ /*68*/ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A,
+ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A,
+ /*70*/ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A,
+ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A,
+ /*78*/ _L|_R|_G|_A, _L|_R|_G|_A, _L|_R|_G|_A, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _C,
+ },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+ },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+ },
+};
+
+_RuneLocale *_CurrentRuneLocale = &_DefaultRuneLocale;
+
+int __mb_cur_max = 1;
+
+char *_PathLocale;
diff --git a/lib/libc/locale/toascii.3 b/lib/libc/locale/toascii.3
new file mode 100644
index 0000000..6fc26f97
--- /dev/null
+++ b/lib/libc/locale/toascii.3
@@ -0,0 +1,70 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)toascii.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt TOASCII 3
+.Os
+.Sh NAME
+.Nm toascii
+.Nd convert a byte to 7-bit ASCII
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn toascii "int c"
+.Sh DESCRIPTION
+The
+.Fn toascii
+function strips all but the low 7 bits from a letter,
+including parity or other marker bits.
+.Sh RETURN VALUES
+The
+.Fn toascii
+function always returns a valid ASCII character.
+.Sh SEE ALSO
+.Xr isalnum 3 ,
+.Xr isalpha 3 ,
+.Xr isascii 3 ,
+.Xr iscntrl 3 ,
+.Xr isdigit 3 ,
+.Xr isgraph 3 ,
+.Xr islower 3 ,
+.Xr isprint 3 ,
+.Xr ispunct 3 ,
+.Xr isspace 3 ,
+.Xr isupper 3 ,
+.Xr isxdigit 3 ,
+.Xr stdio 3 ,
+.Xr tolower 3 ,
+.Xr toupper 3 ,
+.Xr ascii 7
diff --git a/lib/libc/locale/tolower.3 b/lib/libc/locale/tolower.3
new file mode 100644
index 0000000..1bd82c2
--- /dev/null
+++ b/lib/libc/locale/tolower.3
@@ -0,0 +1,89 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tolower.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt TOLOWER 3
+.Os
+.Sh NAME
+.Nm tolower
+.Nd upper case to lower case letter conversion
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn tolower "int c"
+.Sh DESCRIPTION
+The
+.Fn tolower
+function converts an upper-case letter to the corresponding lower-case
+letter.
+.Sh RETURN VALUES
+If the argument is an upper-case letter, the
+.Fn tolower
+function returns the corresponding lower-case letter if there is
+one; otherwise the argument is returned unchanged.
+.\" In the
+.\" .Em ``C''
+.\" locale,
+.\" .Fn tolower
+.\" maps only the characters for which
+.\" .Xr isupper
+.\" is true to the corresponding characters for which
+.\" .Xr islower
+.\" is true.
+.Sh SEE ALSO
+.Xr isalnum 3 ,
+.Xr isalpha 3 ,
+.Xr isascii 3 ,
+.Xr iscntrl 3 ,
+.Xr isdigit 3 ,
+.Xr isgraph 3 ,
+.Xr islower 3 ,
+.Xr isprint 3 ,
+.Xr ispunct 3 ,
+.Xr isspace 3 ,
+.Xr isupper 3 ,
+.Xr isxdigit 3 ,
+.Xr stdio 3 ,
+.Xr toascii 3 ,
+.Xr toupper 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn tolower
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/tolower.c b/lib/libc/locale/tolower.c
new file mode 100644
index 0000000..65d5175
--- /dev/null
+++ b/lib/libc/locale/tolower.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <rune.h>
+
+_BSD_CT_RUNE_T_
+___tolower(c)
+ _BSD_CT_RUNE_T_ c;
+{
+#ifdef XPG4
+ int x;
+ _RuneRange *rr = &_CurrentRuneLocale->maplower_ext;
+ _RuneEntry *re = rr->ranges;
+
+ if (c < 0 || c == EOF)
+ return(c);
+
+ for (x = 0; x < rr->nranges; ++x, ++re) {
+ if (c < re->min)
+ return(c);
+ if (c <= re->max)
+ return(re->map + c - re->min);
+ }
+#endif
+ return(c);
+}
diff --git a/lib/libc/locale/toupper.3 b/lib/libc/locale/toupper.3
new file mode 100644
index 0000000..33742da
--- /dev/null
+++ b/lib/libc/locale/toupper.3
@@ -0,0 +1,89 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)toupper.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt TOUPPER 3
+.Os
+.Sh NAME
+.Nm toupper
+.Nd lower case to upper case letter conversion
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Ft int
+.Fn toupper "int c"
+.Sh DESCRIPTION
+The
+.Fn toupper
+function converts a lower-case letter to the corresponding
+upper-case letter.
+.SH RETURN VALUES
+If the argument is a lower-case letter, the
+.Fn toupper
+function returns the corresponding upper-case letter if there is
+one; otherwise the argument is returned unchanged.
+.\" In the
+.\" .Em ``C''
+.\" locale,
+.\" .Fn toupper
+.\" maps only the characters for which
+.\" .Xr islower
+.\" is true to the corresponding characters for which
+.\" .Xr isupper
+.\" is true.
+.Sh SEE ALSO
+.Xr isalnum 3 ,
+.Xr isalpha 3 ,
+.Xr isascii 3 ,
+.Xr iscntrl 3 ,
+.Xr isdigit 3 ,
+.Xr isgraph 3 ,
+.Xr islower 3 ,
+.Xr isprint 3 ,
+.Xr ispunct 3 ,
+.Xr isspace 3 ,
+.Xr isupper 3 ,
+.Xr isxdigit 3 ,
+.Xr stdio 3 ,
+.Xr toascii 3 ,
+.Xr tolower 3 ,
+.Xr ascii 7
+.Sh STANDARDS
+The
+.Fn toupper
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/locale/toupper.c b/lib/libc/locale/toupper.c
new file mode 100644
index 0000000..d2e4480
--- /dev/null
+++ b/lib/libc/locale/toupper.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <rune.h>
+
+_BSD_CT_RUNE_T_
+___toupper(c)
+ _BSD_CT_RUNE_T_ c;
+{
+#ifdef XPG4
+ int x;
+ _RuneRange *rr = &_CurrentRuneLocale->mapupper_ext;
+ _RuneEntry *re = rr->ranges;
+
+ if (c < 0 || c == EOF)
+ return(c);
+
+ for (x = 0; x < rr->nranges; ++x, ++re) {
+ if (c < re->min)
+ return(c);
+ if (c <= re->max)
+ return(re->map + c - re->min);
+ }
+#endif
+ return(c);
+}
diff --git a/lib/libc/locale/utf2.4 b/lib/libc/locale/utf2.4
new file mode 100644
index 0000000..3734dba
--- /dev/null
+++ b/lib/libc/locale/utf2.4
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Borman at Krystal Technologies.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)utf2.4 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt UTF2 4
+.Os
+.Sh NAME
+.Nm utf2
+.Nd "Universal character set Transformation Format encoding of runes
+.Sh SYNOPSIS
+.Nm ENCODING
+.Qq UTF2
+.Sh DESCRIPTION
+The
+.Nm UTF2
+encoding is based on a proposed X-Open multibyte
+\s-1FSS-UCS-TF\s+1 (File System Safe Universal Character Set Transformation Format) encoding as used in
+.Nm Plan 9 from Bell Labs.
+Although it is capable of representing more than 16 bits,
+the current implementation is limited to 16 bits as defined by the
+Unicode Standard.
+.Pp
+.Nm UTF2
+representation is backwards compatible with ASCII, so 0x00-0x7f refer to the
+ASCII character set. The multibyte encoding of runes between 0x0080 and 0xffff
+consist entirely of bytes whose high order bit is set. The actual
+encoding is represented by the following table:
+.Bd -literal
+[0x0000 - 0x007f] [00000000.0bbbbbbb] -> 0bbbbbbb
+[0x0080 - 0x07ff] [00000bbb.bbbbbbbb] -> 110bbbbb, 10bbbbbb
+[0x0800 - 0xffff] [bbbbbbbb.bbbbbbbb] -> 1110bbbb, 10bbbbbb, 10bbbbbb
+.Ed
+.Pp
+If more than a single representation of a value exists (for example,
+0x00; 0xC0 0x80; 0xE0 0x80 0x80) the shortest representation is always
+used (but the longer ones will be correctly decoded).
+.Pp
+The final three encodings provided by X-Open:
+.Bd -literal
+[00000000.000bbbbb.bbbbbbbb.bbbbbbbb] ->
+ 11110bbb, 10bbbbbb, 10bbbbbb, 10bbbbbb
+
+[000000bb.bbbbbbbb.bbbbbbbb.bbbbbbbb] ->
+ 111110bb, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb
+
+[0bbbbbbb.bbbbbbbb.bbbbbbbb.bbbbbbbb] ->
+ 1111110b, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb
+.Ed
+.Pp
+which provides for the entire proposed ISO-10646 31 bit standard are currently
+not implemented.
+.Sh "SEE ALSO"
+.Xr mklocale 1 ,
+.Xr setlocale 3
diff --git a/lib/libc/locale/utf2.5 b/lib/libc/locale/utf2.5
new file mode 100644
index 0000000..3734dba
--- /dev/null
+++ b/lib/libc/locale/utf2.5
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Borman at Krystal Technologies.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)utf2.4 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt UTF2 4
+.Os
+.Sh NAME
+.Nm utf2
+.Nd "Universal character set Transformation Format encoding of runes
+.Sh SYNOPSIS
+.Nm ENCODING
+.Qq UTF2
+.Sh DESCRIPTION
+The
+.Nm UTF2
+encoding is based on a proposed X-Open multibyte
+\s-1FSS-UCS-TF\s+1 (File System Safe Universal Character Set Transformation Format) encoding as used in
+.Nm Plan 9 from Bell Labs.
+Although it is capable of representing more than 16 bits,
+the current implementation is limited to 16 bits as defined by the
+Unicode Standard.
+.Pp
+.Nm UTF2
+representation is backwards compatible with ASCII, so 0x00-0x7f refer to the
+ASCII character set. The multibyte encoding of runes between 0x0080 and 0xffff
+consist entirely of bytes whose high order bit is set. The actual
+encoding is represented by the following table:
+.Bd -literal
+[0x0000 - 0x007f] [00000000.0bbbbbbb] -> 0bbbbbbb
+[0x0080 - 0x07ff] [00000bbb.bbbbbbbb] -> 110bbbbb, 10bbbbbb
+[0x0800 - 0xffff] [bbbbbbbb.bbbbbbbb] -> 1110bbbb, 10bbbbbb, 10bbbbbb
+.Ed
+.Pp
+If more than a single representation of a value exists (for example,
+0x00; 0xC0 0x80; 0xE0 0x80 0x80) the shortest representation is always
+used (but the longer ones will be correctly decoded).
+.Pp
+The final three encodings provided by X-Open:
+.Bd -literal
+[00000000.000bbbbb.bbbbbbbb.bbbbbbbb] ->
+ 11110bbb, 10bbbbbb, 10bbbbbb, 10bbbbbb
+
+[000000bb.bbbbbbbb.bbbbbbbb.bbbbbbbb] ->
+ 111110bb, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb
+
+[0bbbbbbb.bbbbbbbb.bbbbbbbb.bbbbbbbb] ->
+ 1111110b, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb
+.Ed
+.Pp
+which provides for the entire proposed ISO-10646 31 bit standard are currently
+not implemented.
+.Sh "SEE ALSO"
+.Xr mklocale 1 ,
+.Xr setlocale 3
diff --git a/lib/libc/locale/utf2.c b/lib/libc/locale/utf2.c
new file mode 100644
index 0000000..52b4cad
--- /dev/null
+++ b/lib/libc/locale/utf2.c
@@ -0,0 +1,150 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef XPG4
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)utf2.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <rune.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+rune_t _UTF2_sgetrune __P((const char *, size_t, char const **));
+int _UTF2_sputrune __P((rune_t, char *, size_t, char **));
+
+static int _utf_count[16] = {
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 2, 2, 3, 0,
+};
+
+int
+_UTF2_init(rl)
+ _RuneLocale *rl;
+{
+ rl->sgetrune = _UTF2_sgetrune;
+ rl->sputrune = _UTF2_sputrune;
+ _CurrentRuneLocale = rl;
+ __mb_cur_max = 3;
+ return (0);
+}
+
+rune_t
+_UTF2_sgetrune(string, n, result)
+ const char *string;
+ size_t n;
+ char const **result;
+{
+ int c;
+
+ if (n < 1 || (c = _utf_count[(*string >> 4) & 0xf]) > n) {
+ if (result)
+ *result = string;
+ return (_INVALID_RUNE);
+ }
+ switch (c) {
+ case 1:
+ if (result)
+ *result = string + 1;
+ return (*string & 0xff);
+ case 2:
+ if ((string[1] & 0xC0) != 0x80)
+ goto encoding_error;
+ if (result)
+ *result = string + 2;
+ return (((string[0] & 0x1F) << 6) | (string[1] & 0x3F));
+ case 3:
+ if ((string[1] & 0xC0) != 0x80 || (string[2] & 0xC0) != 0x80)
+ goto encoding_error;
+ if (result)
+ *result = string + 3;
+ return (((string[0] & 0x1F) << 12) | ((string[1] & 0x3F) << 6)
+ | (string[2] & 0x3F));
+ default:
+encoding_error: if (result)
+ *result = string + 1;
+ return (_INVALID_RUNE);
+ }
+}
+
+int
+_UTF2_sputrune(c, string, n, result)
+ rune_t c;
+ char *string, **result;
+ size_t n;
+{
+ if (c & 0xF800) {
+ if (n >= 3) {
+ if (string) {
+ string[0] = 0xE0 | ((c >> 12) & 0x0F);
+ string[1] = 0x80 | ((c >> 6) & 0x3F);
+ string[2] = 0x80 | ((c) & 0x3F);
+ }
+ if (result)
+ *result = string + 3;
+ } else
+ if (result)
+ *result = NULL;
+
+ return (3);
+ } else
+ if (c & 0x0780) {
+ if (n >= 2) {
+ if (string) {
+ string[0] = 0xC0 | ((c >> 6) & 0x1F);
+ string[1] = 0x80 | ((c) & 0x3F);
+ }
+ if (result)
+ *result = string + 2;
+ } else
+ if (result)
+ *result = NULL;
+ return (2);
+ } else {
+ if (n >= 1) {
+ if (string)
+ string[0] = c;
+ if (result)
+ *result = string + 1;
+ } else
+ if (result)
+ *result = NULL;
+ return (1);
+ }
+}
+#endif /* XPG4 */
diff --git a/lib/libc/mips/:errfix b/lib/libc/mips/:errfix
new file mode 100644
index 0000000..528c927
--- /dev/null
+++ b/lib/libc/mips/:errfix
@@ -0,0 +1,5 @@
+?sys_nerr?
+.-4,.+1m1
+.+1,$g/\.data/s//\.text/
+w
+q
diff --git a/lib/libc/mips/Makefile.inc b/lib/libc/mips/Makefile.inc
new file mode 100644
index 0000000..c64d01b
--- /dev/null
+++ b/lib/libc/mips/Makefile.inc
@@ -0,0 +1,4 @@
+# $OpenBSD: Makefile.inc,v 1.1.1.1 1995/10/18 08:41:33 deraadt Exp $
+
+KMINCLUDES=
+KMSRCS=
diff --git a/lib/libc/mips/SYS.h b/lib/libc/mips/SYS.h
new file mode 100644
index 0000000..ccce710
--- /dev/null
+++ b/lib/libc/mips/SYS.h
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $OpenBSD: SYS.h,v 1.3 1996/07/30 20:27:48 pefo Exp $
+ */
+
+#include <sys/syscall.h>
+#include <machine/asm.h>
+
+#ifdef __STDC__
+#define RSYSCALL(x) \
+ LEAF(x); \
+ li v0,SYS_ ## x; \
+ syscall; \
+ bne a3,zero,err; \
+ j ra; \
+ err: la t9, cerror; \
+ jr t9; \
+ END(x);
+#define PSEUDO(x,y) \
+ LEAF(x); \
+ li v0,SYS_ ## y; \
+ syscall; \
+ bne a3,zero,err; \
+ j ra; \
+ err: la t9, cerror; \
+ jr t9; \
+ END(x);
+#else
+#define RSYSCALL(x) \
+ LEAF(x); \
+ li v0,SYS_/**/x; \
+ syscall; \
+ bne a3,zero,err; \
+ j ra; \
+ err: la t9, cerror; \
+ jr t9; \
+ END(x);
+#define PSEUDO(x,y) \
+ LEAF(x); \
+ li v0,SYS_/**/y; \
+ syscall; \
+ bne a3,zero,err; \
+ j ra; \
+ err: la t9, cerror; \
+ jr t9; \
+ END(x);
+#endif
diff --git a/lib/libc/mips/gen/Makefile.inc b/lib/libc/mips/gen/Makefile.inc
new file mode 100644
index 0000000..6c358a9
--- /dev/null
+++ b/lib/libc/mips/gen/Makefile.inc
@@ -0,0 +1,6 @@
+# $OpenBSD: Makefile.inc,v 1.4 1995/12/15 01:12:36 jonathan Exp $
+
+SRCS+= _setjmp.S fabs.S frexp.c infinity.c isinf.S ldexp.S modf.S
+SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
+ fpsetround.c fpsetsticky.c
+SRCS+= setjmp.S sigsetjmp.S
diff --git a/lib/libc/mips/gen/_setjmp.S b/lib/libc/mips/gen/_setjmp.S
new file mode 100644
index 0000000..0e7b886
--- /dev/null
+++ b/lib/libc/mips/gen/_setjmp.S
@@ -0,0 +1,132 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/regnum.h>
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD: _setjmp.S,v 1.5 1996/08/19 08:15:51 tholo Exp $"
+#endif /* LIBC_SCCS */
+
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ * _longjmp(a,v)
+ * will generate a "return(v)" from
+ * the last call to
+ * _setjmp(a)
+ * by restoring registers from the stack,
+ * The previous signal state is NOT restored.
+ */
+
+LEAF(_setjmp)
+ .set noreorder
+ li v0, 0xACEDBADE # sigcontext magic number
+ sw ra, (2 * 4)(a0) # sc_pc = return address
+ sw v0, (3 * 4)(a0) # saved in sc_regs[0]
+ sw s0, ((S0 + 3) * 4)(a0)
+ sw s1, ((S1 + 3) * 4)(a0)
+ sw s2, ((S2 + 3) * 4)(a0)
+ sw s3, ((S3 + 3) * 4)(a0)
+ sw s4, ((S4 + 3) * 4)(a0)
+ sw s5, ((S5 + 3) * 4)(a0)
+ sw s6, ((S6 + 3) * 4)(a0)
+ sw s7, ((S7 + 3) * 4)(a0)
+ sw sp, ((SP + 3) * 4)(a0)
+ sw s8, ((S8 + 3) * 4)(a0)
+ cfc1 v0, $31 # too bad cant check if FP used
+ swc1 $f20, ((20 + 38) * 4)(a0)
+ swc1 $f21, ((21 + 38) * 4)(a0)
+ swc1 $f22, ((22 + 38) * 4)(a0)
+ swc1 $f23, ((23 + 38) * 4)(a0)
+ swc1 $f24, ((24 + 38) * 4)(a0)
+ swc1 $f25, ((25 + 38) * 4)(a0)
+ swc1 $f26, ((26 + 38) * 4)(a0)
+ swc1 $f27, ((27 + 38) * 4)(a0)
+ swc1 $f28, ((28 + 38) * 4)(a0)
+ swc1 $f29, ((29 + 38) * 4)(a0)
+ swc1 $f30, ((30 + 38) * 4)(a0)
+ swc1 $f31, ((31 + 38) * 4)(a0)
+ sw v0, ((32 + 38) * 4)(a0)
+ j ra
+ move v0, zero
+END(_setjmp)
+
+LEAF(_longjmp)
+#ifdef ABICALLS
+ subu sp, sp, 32
+ .cprestore 16
+#endif
+ .set noreorder
+ lw v0, (3 * 4)(a0) # get magic number
+ lw ra, (2 * 4)(a0)
+ bne v0, 0xACEDBADE, botch # jump if error
+
+ addu sp, sp, 32 # does not matter, sanity
+ lw s0, ((S0 + 3) * 4)(a0)
+ lw s1, ((S1 + 3) * 4)(a0)
+ lw s2, ((S2 + 3) * 4)(a0)
+ lw s3, ((S3 + 3) * 4)(a0)
+ lw s4, ((S4 + 3) * 4)(a0)
+ lw s5, ((S5 + 3) * 4)(a0)
+ lw s6, ((S6 + 3) * 4)(a0)
+ lw s7, ((S7 + 3) * 4)(a0)
+ lw v0, ((32 + 38) * 4)(a0) # get fpu status
+ lw sp, ((SP + 3) * 4)(a0)
+ lw s8, ((S8 + 3) * 4)(a0)
+ ctc1 v0, $31
+ lwc1 $f20, ((20 + 38) * 4)(a0)
+ lwc1 $f21, ((21 + 38) * 4)(a0)
+ lwc1 $f22, ((22 + 38) * 4)(a0)
+ lwc1 $f23, ((23 + 38) * 4)(a0)
+ lwc1 $f24, ((24 + 38) * 4)(a0)
+ lwc1 $f25, ((25 + 38) * 4)(a0)
+ lwc1 $f26, ((26 + 38) * 4)(a0)
+ lwc1 $f27, ((27 + 38) * 4)(a0)
+ lwc1 $f28, ((28 + 38) * 4)(a0)
+ lwc1 $f29, ((29 + 38) * 4)(a0)
+ lwc1 $f30, ((30 + 38) * 4)(a0)
+ lwc1 $f31, ((31 + 38) * 4)(a0)
+
+ j ra
+ move v0, a1
+botch:
+ jal _C_LABEL(longjmperror)
+ nop
+ jal _C_LABEL(abort)
+ nop
+END(_longjmp)
diff --git a/lib/libc/mips/gen/fabs.S b/lib/libc/mips/gen/fabs.S
new file mode 100644
index 0000000..5306870
--- /dev/null
+++ b/lib/libc/mips/gen/fabs.S
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+/*
+ * fabs(x)
+ * double x;
+ *
+ * Return absolute value of x.
+ */
+LEAF(fabs)
+ .set noreorder
+ j ra
+ abs.d $f0, $f12 # compute absolute value of x
+END(fabs)
diff --git a/lib/libc/mips/gen/flt_rounds.c b/lib/libc/mips/gen/flt_rounds.c
new file mode 100644
index 0000000..289ed7c
--- /dev/null
+++ b/lib/libc/mips/gen/flt_rounds.c
@@ -0,0 +1,27 @@
+/*
+ * Written by J.T. Conklin, Apr 11, 1995
+ * Public domain.
+ */
+
+#include <sys/types.h>
+#include <machine/float.h>
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: flt_rounds.c,v 1.3 1997/08/01 21:36:28 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+static const int map[] = {
+ 1, /* round to nearest */
+ 0, /* round to zero */
+ 2, /* round to positive infinity */
+ 3 /* round to negative infinity */
+};
+
+int
+__flt_rounds()
+{
+ int x;
+
+ __asm__("cfc1 %0,$31" : "=r" (x));
+ return map[x & 0x03];
+}
diff --git a/lib/libc/mips/gen/fpgetmask.c b/lib/libc/mips/gen/fpgetmask.c
new file mode 100644
index 0000000..8c1a53e
--- /dev/null
+++ b/lib/libc/mips/gen/fpgetmask.c
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin, Apr 11, 1995
+ * Public domain.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ieeefp.h>
+
+fp_except
+fpgetmask()
+{
+ int x;
+
+ __asm__("cfc1 %0,$31" : "=r" (x));
+ return (x >> 7) & 0x1f;
+}
diff --git a/lib/libc/mips/gen/fpgetround.c b/lib/libc/mips/gen/fpgetround.c
new file mode 100644
index 0000000..565f7c8
--- /dev/null
+++ b/lib/libc/mips/gen/fpgetround.c
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin, Apr 11, 1995
+ * Public domain.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ieeefp.h>
+
+fp_rnd
+fpgetround()
+{
+ int x;
+
+ __asm__("cfc1 %0,$31" : "=r" (x));
+ return x & 0x03;
+}
diff --git a/lib/libc/mips/gen/fpgetsticky.c b/lib/libc/mips/gen/fpgetsticky.c
new file mode 100644
index 0000000..f7057ff
--- /dev/null
+++ b/lib/libc/mips/gen/fpgetsticky.c
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin, Apr 11, 1995
+ * Public domain.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ieeefp.h>
+
+fp_except
+fpgetsticky()
+{
+ int x;
+
+ __asm__("cfc1 %0,$31" : "=r" (x));
+ return (x >> 2) & 0x1f;
+}
diff --git a/lib/libc/mips/gen/fpsetmask.c b/lib/libc/mips/gen/fpsetmask.c
new file mode 100644
index 0000000..c57f52f
--- /dev/null
+++ b/lib/libc/mips/gen/fpsetmask.c
@@ -0,0 +1,28 @@
+/*
+ * Written by J.T. Conklin, Apr 11, 1995
+ * Public domain.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ieeefp.h>
+
+fp_except
+fpsetmask(mask)
+ fp_except mask;
+{
+ fp_except old;
+ fp_except new;
+
+ __asm__("cfc1 %0,$31" : "=r" (old));
+
+ new = old;
+ new &= ~(0x1f << 7);
+ new |= ((mask & 0x1f) << 7);
+
+ __asm__("ctc1 %0,$31" : : "r" (new));
+
+ return (old >> 7) & 0x1f;
+}
diff --git a/lib/libc/mips/gen/fpsetround.c b/lib/libc/mips/gen/fpsetround.c
new file mode 100644
index 0000000..9516d34
--- /dev/null
+++ b/lib/libc/mips/gen/fpsetround.c
@@ -0,0 +1,28 @@
+/*
+ * Written by J.T. Conklin, Apr 11, 1995
+ * Public domain.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ieeefp.h>
+
+fp_rnd
+fpsetround(rnd_dir)
+ fp_rnd rnd_dir;
+{
+ fp_rnd old;
+ fp_rnd new;
+
+ __asm__("cfc1 %0,$31" : "=r" (old));
+
+ new = old;
+ new &= ~0x03;
+ new |= (rnd_dir & 0x03);
+
+ __asm__("ctc1 %0,$31" : : "r" (new));
+
+ return old & 0x03;
+}
diff --git a/lib/libc/mips/gen/fpsetsticky.c b/lib/libc/mips/gen/fpsetsticky.c
new file mode 100644
index 0000000..493c3a0
--- /dev/null
+++ b/lib/libc/mips/gen/fpsetsticky.c
@@ -0,0 +1,28 @@
+/*
+ * Written by J.T. Conklin, Apr 11, 1995
+ * Public domain.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ieeefp.h>
+
+fp_except
+fpsetsticky(sticky)
+ fp_except sticky;
+{
+ fp_except old;
+ fp_except new;
+
+ __asm__("cfc1 %0,$31" : "=r" (old));
+
+ new = old;
+ new &= ~(0x1f << 2);
+ new |= ((sticky & 0x1f) << 2);
+
+ __asm__("ctc1 %0,$31" : : "r" (new));
+
+ return (old >> 2) & 0x1f;
+}
diff --git a/lib/libc/mips/gen/frexp.c b/lib/libc/mips/gen/frexp.c
new file mode 100644
index 0000000..181e1dc
--- /dev/null
+++ b/lib/libc/mips/gen/frexp.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: frexp.c,v 1.3 1997/07/23 20:55:24 kstailey Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <machine/endian.h>
+#include <math.h>
+
+double
+frexp(value, eptr)
+ double value;
+ int *eptr;
+{
+ union {
+ double v;
+ struct {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int u_mant2 : 32;
+ u_int u_mant1 : 20;
+ u_int u_exp : 11;
+ u_int u_sign : 1;
+#else
+ u_int u_sign : 1;
+ u_int u_exp : 11;
+ u_int u_mant1 : 20;
+ u_int u_mant2 : 32;
+#endif
+ } s;
+ } u;
+
+ if (value) {
+ u.v = value;
+ *eptr = u.s.u_exp - 1022;
+ u.s.u_exp = 1022;
+ return(u.v);
+ } else {
+ *eptr = 0;
+ return((double)0);
+ }
+}
diff --git a/lib/libc/mips/gen/infinity.c b/lib/libc/mips/gen/infinity.c
new file mode 100644
index 0000000..7a0b131
--- /dev/null
+++ b/lib/libc/mips/gen/infinity.c
@@ -0,0 +1,15 @@
+/* infinity.c */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: infinity.c,v 1.2 1996/08/19 08:16:01 tholo Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <math.h>
+#include <sys/types.h>
+
+/* bytes for +Infinity on a MIPS */
+#if BYTE_ORDER == BIG_ENDIAN
+char __infinity[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
+#else
+char __infinity[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
+#endif
diff --git a/lib/libc/mips/gen/isinf.S b/lib/libc/mips/gen/isinf.S
new file mode 100644
index 0000000..e872cd7
--- /dev/null
+++ b/lib/libc/mips/gen/isinf.S
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+#define DEXP_INF 0x7ff
+
+/*
+ * isnan(x)
+ * double x;
+ *
+ * Return true if x is a NAN.
+ */
+LEAF(isnan)
+ .set noreorder
+ mfc1 v1, $f13 # get MSW of x
+ mfc1 t3, $f12 # get LSW of x
+ sll t1, v1, 1 # get x exponent
+ srl t1, t1, 32 - 11
+ bne t1, DEXP_INF, 2f # is it a finite number?
+ sll t2, v1, 32 - 20 # get x fraction
+ bne t3, zero, 1f # is it a NAN?
+ nop
+ beq t2, zero, 2f # its infinity
+ nop
+1:
+ j ra
+ li v0, 1 # x is a NAN
+2:
+ j ra
+ move v0, zero # x is NOT a NAN
+END(isnan)
+
+/*
+ * isinf(x)
+ * double x;
+ *
+ * Return true if x is infinity.
+ */
+LEAF(isinf)
+ .set noreorder
+ mfc1 v1, $f13 # get MSW of x
+ mfc1 t3, $f12 # get LSW of x
+ sll t1, v1, 1 # get x exponent
+ srl t1, t1, 32 - 11
+ bne t1, DEXP_INF, 1f # is it a finite number?
+ sll t2, v1, 32 - 20 # get x fraction
+ bne t3, zero, 1f # is it a NAN?
+ nop
+ bne t2, zero, 1f # is it a NAN?
+ nop
+ j ra
+ li v0, 1 # x is infinity
+1:
+ j ra
+ move v0, zero # x is NOT infinity
+END(isinf)
diff --git a/lib/libc/mips/gen/ldexp.S b/lib/libc/mips/gen/ldexp.S
new file mode 100644
index 0000000..5aa6131
--- /dev/null
+++ b/lib/libc/mips/gen/ldexp.S
@@ -0,0 +1,217 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+#define DEXP_INF 0x7ff
+#define DEXP_BIAS 1023
+#define DEXP_MIN -1022
+#define DEXP_MAX 1023
+#define DFRAC_BITS 52
+#define DIMPL_ONE 0x00100000
+#define DLEAD_ZEROS 31 - 20
+#define STICKYBIT 1
+#define GUARDBIT 0x80000000
+#define DSIGNAL_NAN 0x00040000
+#define DQUIET_NAN0 0x0007ffff
+#define DQUIET_NAN1 0xffffffff
+
+/*
+ * double ldexp(x, N)
+ * double x; int N;
+ *
+ * Return x * (2**N), for integer values N.
+ */
+LEAF(ldexp)
+ .set reorder
+ mfc1 v1, $f13 # get MSW of x
+ mfc1 t3, $f12 # get LSW of x
+ sll t1, v1, 1 # get x exponent
+ srl t1, t1, 32 - 11
+ beq t1, DEXP_INF, 9f # is it a NAN or infinity?
+ beq t1, zero, 1f # zero or denormalized number?
+ addu t1, t1, a2 # scale exponent
+ sll v0, a2, 20 # position N for addition
+ bge t1, DEXP_INF, 8f # overflow?
+ addu v0, v0, v1 # multiply by (2**N)
+ ble t1, zero, 4f # underflow?
+ mtc1 v0, $f1 # save MSW of result
+ mtc1 t3, $f0 # save LSW of result
+ j ra
+1:
+ sll t2, v1, 32 - 20 # get x fraction
+ srl t2, t2, 32 - 20
+ srl t0, v1, 31 # get x sign
+ bne t2, zero, 1f
+ beq t3, zero, 9f # result is zero
+1:
+/*
+ * Find out how many leading zero bits are in t2,t3 and put in t9.
+ */
+ move v0, t2
+ move t9, zero
+ bne t2, zero, 1f
+ move v0, t3
+ addu t9, 32
+1:
+ srl t4, v0, 16
+ bne t4, zero, 1f
+ addu t9, 16
+ sll v0, 16
+1:
+ srl t4, v0, 24
+ bne t4, zero, 1f
+ addu t9, 8
+ sll v0, 8
+1:
+ srl t4, v0, 28
+ bne t4, zero, 1f
+ addu t9, 4
+ sll v0, 4
+1:
+ srl t4, v0, 30
+ bne t4, zero, 1f
+ addu t9, 2
+ sll v0, 2
+1:
+ srl t4, v0, 31
+ bne t4, zero, 1f
+ addu t9, 1
+/*
+ * Now shift t2,t3 the correct number of bits.
+ */
+1:
+ subu t9, t9, DLEAD_ZEROS # dont count normal leading zeros
+ li t1, DEXP_MIN + DEXP_BIAS
+ subu t1, t1, t9 # adjust exponent
+ addu t1, t1, a2 # scale exponent
+ li v0, 32
+ blt t9, v0, 1f
+ subu t9, t9, v0 # shift fraction left >= 32 bits
+ sll t2, t3, t9
+ move t3, zero
+ b 2f
+1:
+ subu v0, v0, t9 # shift fraction left < 32 bits
+ sll t2, t2, t9
+ srl t4, t3, v0
+ or t2, t2, t4
+ sll t3, t3, t9
+2:
+ bge t1, DEXP_INF, 8f # overflow?
+ ble t1, zero, 4f # underflow?
+ sll t2, t2, 32 - 20 # clear implied one bit
+ srl t2, t2, 32 - 20
+3:
+ sll t1, t1, 31 - 11 # reposition exponent
+ sll t0, t0, 31 # reposition sign
+ or t0, t0, t1 # put result back together
+ or t0, t0, t2
+ mtc1 t0, $f1 # save MSW of result
+ mtc1 t3, $f0 # save LSW of result
+ j ra
+4:
+ li v0, 0x80000000
+ ble t1, -52, 7f # is result too small for denorm?
+ sll t2, v1, 31 - 20 # clear exponent, extract fraction
+ or t2, t2, v0 # set implied one bit
+ blt t1, -30, 2f # will all bits in t3 be shifted out?
+ srl t2, t2, 31 - 20 # shift fraction back to normal position
+ subu t1, t1, 1
+ sll t4, t2, t1 # shift right t2,t3 based on exponent
+ srl t8, t3, t1 # save bits shifted out
+ negu t1
+ srl t3, t3, t1
+ or t3, t3, t4
+ srl t2, t2, t1
+ bge t8, zero, 1f # does result need to be rounded?
+ addu t3, t3, 1 # round result
+ sltu t4, t3, 1
+ sll t8, t8, 1
+ addu t2, t2, t4
+ bne t8, zero, 1f # round result to nearest
+ and t3, t3, ~1
+1:
+ mtc1 t3, $f0 # save denormalized result (LSW)
+ mtc1 t2, $f1 # save denormalized result (MSW)
+ bge v1, zero, 1f # should result be negative?
+ neg.d $f0, $f0 # negate result
+1:
+ j ra
+2:
+ mtc1 zero, $f1 # exponent and upper fraction
+ addu t1, t1, 20 # compute amount to shift right by
+ sll t8, t2, t1 # save bits shifted out
+ negu t1
+ srl t3, t2, t1
+ bge t8, zero, 1f # does result need to be rounded?
+ addu t3, t3, 1 # round result
+ sltu t4, t3, 1
+ sll t8, t8, 1
+ mtc1 t4, $f1 # exponent and upper fraction
+ bne t8, zero, 1f # round result to nearest
+ and t3, t3, ~1
+1:
+ mtc1 t3, $f0
+ bge v1, zero, 1f # is result negative?
+ neg.d $f0, $f0 # negate result
+1:
+ j ra
+7:
+ mtc1 zero, $f0 # result is zero
+ mtc1 zero, $f1
+ beq t0, zero, 1f # is result positive?
+ neg.d $f0, $f0 # negate result
+1:
+ j ra
+8:
+ li t1, 0x7ff00000 # result is infinity (MSW)
+ mtc1 t1, $f1
+ mtc1 zero, $f0 # result is infinity (LSW)
+ bge v1, zero, 1f # should result be negative infinity?
+ neg.d $f0, $f0 # result is negative infinity
+1:
+ add.d $f0, $f0 # cause overflow faults if enabled
+ j ra
+9:
+ mov.d $f0, $f12 # yes, result is just x
+ j ra
+END(ldexp)
diff --git a/lib/libc/mips/gen/modf.S b/lib/libc/mips/gen/modf.S
new file mode 100644
index 0000000..057feaa
--- /dev/null
+++ b/lib/libc/mips/gen/modf.S
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 1991, 1993, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+/*
+ * double modf(val, iptr)
+ * double val, *iptr;
+ * returns: xxx and n (in *iptr) where val == n.xxx
+ */
+LEAF(modf)
+ .set reorder
+ cfc1 t0, $31 # get the control register
+ li.d $f2, 4503599627370496e0 # f2 <- 2^52
+
+ or t1, t0, 0x3 # set rounding mode to round to zero
+ xor t1, t1, 0x2 # (i.e., 01)
+ ctc1 t1, $31
+
+ mov.d $f0, $f12 # f0 <- f12
+ abs.d $f4, $f12 # f4 <- |f12|
+ c.olt.d $f4, $f2 # f4 ? < f2
+ bc1f 1f # leave f0 alone if Nan, infinity
+ # or >=2^52
+ c.eq.d $f12,$f4 # was f12 positive ?
+ add.d $f4,$f2,$f4 # round off to integer
+ bc1f 2f # No -> will have to negate result
+ sub.d $f0,$f4,$f2 # Remove fudge factor
+ j 1f # integer fraction got
+2:
+ sub.d $f0,$f2,$f4 # Remove fudge factor and negate
+1:
+ ctc1 t0, $31 # restore old rounding mode
+ s.d $f0, 0(a2) # save the integer part
+ sub.d $f0, $f12, $f0 # subtract val - integer part
+ j ra
+END(modf)
diff --git a/lib/libc/mips/gen/setjmp.S b/lib/libc/mips/gen/setjmp.S
new file mode 100644
index 0000000..0abfed8
--- /dev/null
+++ b/lib/libc/mips/gen/setjmp.S
@@ -0,0 +1,128 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/syscall.h>
+#include <machine/asm.h>
+#include <machine/regnum.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD: setjmp.S,v 1.6 1997/07/23 20:55:25 kstailey Exp $"
+#endif /* LIBC_SCCS */
+
+/*
+ * C library -- setjmp, longjmp
+ *
+ * longjmp(a,v)
+ * will generate a "return(v)" from
+ * the last call to
+ * setjmp(a)
+ * by restoring registers from the stack,
+ * and a struct sigcontext, see <signal.h>
+ */
+
+#define SETJMP_FRAME_SIZE (STAND_FRAME_SIZE + 12)
+
+NON_LEAF(setjmp, SETJMP_FRAME_SIZE, ra)
+ .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
+ subu sp, sp, SETJMP_FRAME_SIZE # allocate stack frame
+#ifdef ABICALLS
+ .cprestore 16
+#endif
+ .set reorder
+ sw ra, STAND_RA_OFFSET(sp) # save state
+ sw a0, SETJMP_FRAME_SIZE(sp)
+ move a0, zero # get current signal mask
+ jal _C_LABEL(sigblock)
+ lw v1, SETJMP_FRAME_SIZE(sp) # v1 = jmpbuf
+ sw v0, (1 * 4)(v1) # save sc_mask = sigblock(0)
+ move a0, zero
+ addu a1, sp, STAND_FRAME_SIZE # pointer to struct sigaltstack
+ jal _C_LABEL(sigaltstack)
+ lw a0, SETJMP_FRAME_SIZE(sp) # restore jmpbuf
+ lw v1, STAND_FRAME_SIZE+8(sp) # get old ss_onstack
+ and v1, v1, 1 # extract onstack flag
+ sw v1, 0(a0) # save it in sc_onstack
+ lw ra, STAND_RA_OFFSET(sp)
+ addu sp, sp, SETJMP_FRAME_SIZE
+ blt v0, zero, botch # check for sigstack() error
+ sw ra, (2 * 4)(a0) # sc_pc = return address
+ li v0, 0xACEDBADE # sigcontext magic number
+ sw v0, ((ZERO + 3) * 4)(a0) # saved in sc_regs[0]
+ sw s0, ((S0 + 3) * 4)(a0)
+ sw s1, ((S1 + 3) * 4)(a0)
+ sw s2, ((S2 + 3) * 4)(a0)
+ sw s3, ((S3 + 3) * 4)(a0)
+ sw s4, ((S4 + 3) * 4)(a0)
+ sw s5, ((S5 + 3) * 4)(a0)
+ sw s6, ((S6 + 3) * 4)(a0)
+ sw s7, ((S7 + 3) * 4)(a0)
+ sw gp, ((GP + 3) * 4)(a0)
+ sw sp, ((SP + 3) * 4)(a0)
+ sw s8, ((S8 + 3) * 4)(a0)
+ li v0, 1 # be nice if we could tell
+ sw v0, (37 * 4)(a0) # sc_fpused = 1
+ cfc1 v0, $31
+ swc1 $f20, ((20 + 38) * 4)(a0)
+ swc1 $f21, ((21 + 38) * 4)(a0)
+ swc1 $f22, ((22 + 38) * 4)(a0)
+ swc1 $f23, ((23 + 38) * 4)(a0)
+ swc1 $f24, ((24 + 38) * 4)(a0)
+ swc1 $f25, ((25 + 38) * 4)(a0)
+ swc1 $f26, ((26 + 38) * 4)(a0)
+ swc1 $f27, ((27 + 38) * 4)(a0)
+ swc1 $f28, ((28 + 38) * 4)(a0)
+ swc1 $f29, ((29 + 38) * 4)(a0)
+ swc1 $f30, ((30 + 38) * 4)(a0)
+ swc1 $f31, ((31 + 38) * 4)(a0)
+ sw v0, ((32 + 38) * 4)(a0)
+ move v0, zero
+ j ra
+END(setjmp)
+
+LEAF(longjmp)
+#ifdef ABICALLS
+ subu sp, sp, 32
+ .cprestore 16
+#endif
+ .set reorder
+ sw a1, ((V0 + 3) * 4)(a0) # save return value in sc_regs[V0]
+ li v0, SYS_sigreturn
+ syscall
+botch:
+ jal _C_LABEL(longjmperror)
+ jal _C_LABEL(abort)
+END(longjmp)
diff --git a/lib/libc/mips/gen/sigsetjmp.S b/lib/libc/mips/gen/sigsetjmp.S
new file mode 100644
index 0000000..4a7d414
--- /dev/null
+++ b/lib/libc/mips/gen/sigsetjmp.S
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 1991, 1993, 1995,
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Havard Eidnes.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/syscall.h>
+#include <machine/regnum.h>
+#include <machine/asm.h>
+#include <machine/setjmp.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+/*
+ * C library -- sigsetjmp, siglongjmp
+ *
+ * siglongjmp(a,v)
+ * will generate a "return(v)" from
+ * the last call to
+ * sigsetjmp(a, savemask)
+ * by restoring registers from the stack,
+ * and dependent on savemask restores the
+ * signal mask.
+ */
+
+LEAF(sigsetjmp)
+ .set reorder
+ sw a1, (_JBLEN*4)(a0) # save "savemask"
+ bne a1, 0x0, 1f # do saving of signal mask?
+ la t9, _setjmp
+ jr t9
+
+1: la t9, setjmp
+ jr t9
+END(sigsetjmp)
+
+LEAF(siglongjmp)
+ .set reorder
+ lw t0, (_JBLEN * 4)(a0) # get "savemask"
+ bne t0, 0x0, 1f # restore signal mask?
+ la t9, _longjmp
+ jr t9
+1: la t9, longjmp
+ jr t9
+END(siglongjmp)
diff --git a/lib/libc/mips/net/Makefile.inc b/lib/libc/mips/net/Makefile.inc
new file mode 100644
index 0000000..1518429
--- /dev/null
+++ b/lib/libc/mips/net/Makefile.inc
@@ -0,0 +1,4 @@
+# $OpenBSD: Makefile.inc,v 1.1 1995/02/25 14:59:01 cgd Exp $
+
+SRCS+= htonl.S htons.S
+LSRCS+= htonl.c htons.c
diff --git a/lib/libc/mips/net/htonl.S b/lib/libc/mips/net/htonl.S
new file mode 100644
index 0000000..3ec9a96
--- /dev/null
+++ b/lib/libc/mips/net/htonl.S
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+/*
+ * netorder = htonl(hostorder)
+ * hostorder = ntohl(netorder)
+ */
+ALEAF(ntohl)
+NLEAF(htonl) # a0 = 0x11223344, return 0x44332211
+ .set reorder
+#ifdef MIPSEL
+ srl v1, a0, 24 # v1 = 0x00000011
+ sll v0, a0, 24 # v0 = 0x44000000
+ or v0, v0, v1
+ and v1, a0, 0xff00
+ sll v1, v1, 8 # v1 = 0x00330000
+ or v0, v0, v1
+ srl v1, a0, 8
+ and v1, v1, 0xff00 # v1 = 0x00002200
+ or v0, v0, v1
+#else
+#ifdef MIPSEB
+ move v0, a0
+#else
+ ERROR
+#endif
+#endif
+ j ra
+END(htonl)
diff --git a/lib/libc/mips/net/htons.S b/lib/libc/mips/net/htons.S
new file mode 100644
index 0000000..be056d2
--- /dev/null
+++ b/lib/libc/mips/net/htons.S
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+/*
+ * netorder = htons(hostorder)
+ * hostorder = ntohs(netorder)
+ */
+ALEAF(ntohs)
+NLEAF(htons)
+ .set reorder
+#ifdef MIPSEL
+ srl v0, a0, 8
+ and v0, v0, 0xff
+ sll v1, a0, 8
+ and v1, v1, 0xff00
+ or v0, v0, v1
+#else
+#ifdef MIPSEB
+ move v0, a0
+#else
+ ERROR
+#endif
+#endif
+ j ra
+END(htons)
diff --git a/lib/libc/mips/stdlib/Makefile.inc b/lib/libc/mips/stdlib/Makefile.inc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/libc/mips/stdlib/Makefile.inc
diff --git a/lib/libc/mips/string/Makefile.inc b/lib/libc/mips/string/Makefile.inc
new file mode 100644
index 0000000..a60e550
--- /dev/null
+++ b/lib/libc/mips/string/Makefile.inc
@@ -0,0 +1,7 @@
+# $OpenBSD: Makefile.inc,v 1.1 1995/03/20 14:45:47 mycroft Exp $
+
+SRCS+= bcmp.S bcopy.S bzero.S ffs.S index.S memchr.c memcmp.c memset.c \
+ rindex.S strcat.c strcmp.S strcpy.c strcspn.c strlen.S \
+ strncat.c strncmp.c strncpy.c strpbrk.c strsep.c \
+ strspn.c strstr.c swab.c
+LSRCS+= bcmp.c bcopy.c bzero.c ffs.c index.c rindex.c strcmp.c strlen.c
diff --git a/lib/libc/mips/string/bcmp.S b/lib/libc/mips/string/bcmp.S
new file mode 100644
index 0000000..7d3a96e
--- /dev/null
+++ b/lib/libc/mips/string/bcmp.S
@@ -0,0 +1,120 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+/* bcmp(s1, s2, n) */
+
+LEAF(bcmp)
+ .set noreorder
+ blt a2, 16, small # is it worth any trouble?
+ xor v0, a0, a1 # compare low two bits of addresses
+ and v0, v0, 3
+ subu a3, zero, a1 # compute # bytes to word align address
+ bne v0, zero, unaligned # not possible to align addresses
+ and a3, a3, 3
+
+ beq a3, zero, 1f
+ subu a2, a2, a3 # subtract from remaining count
+ move v0, v1 # init v0,v1 so unmodified bytes match
+ LWHI v0, 0(a0) # read 1, 2, or 3 bytes
+ LWHI v1, 0(a1)
+ addu a1, a1, a3
+ bne v0, v1, nomatch
+ addu a0, a0, a3
+1:
+ and a3, a2, ~3 # compute number of whole words left
+ subu a2, a2, a3 # which has to be >= (16-3) & ~3
+ addu a3, a3, a0 # compute ending address
+2:
+ lw v0, 0(a0) # compare words
+ lw v1, 0(a1)
+ addu a0, a0, 4
+ bne v0, v1, nomatch
+ addu a1, a1, 4
+ bne a0, a3, 2b
+ nop
+ b small # finish remainder
+ nop
+unaligned:
+ beq a3, zero, 2f
+ subu a2, a2, a3 # subtract from remaining count
+ addu a3, a3, a0 # compute ending address
+1:
+ lbu v0, 0(a0) # compare bytes until a1 word aligned
+ lbu v1, 0(a1)
+ addu a0, a0, 1
+ bne v0, v1, nomatch
+ addu a1, a1, 1
+ bne a0, a3, 1b
+ nop
+2:
+ and a3, a2, ~3 # compute number of whole words left
+ subu a2, a2, a3 # which has to be >= (16-3) & ~3
+ addu a3, a3, a0 # compute ending address
+3:
+ LWHI v0, 0(a0) # compare words a0 unaligned, a1 aligned
+ LWLO v0, 3(a0)
+ lw v1, 0(a1)
+ addu a0, a0, 4
+ bne v0, v1, nomatch
+ addu a1, a1, 4
+ bne a0, a3, 3b
+ nop
+small:
+ ble a2, zero, match
+ addu a3, a2, a0 # compute ending address
+1:
+ lbu v0, 0(a0)
+ lbu v1, 0(a1)
+ addu a0, a0, 1
+ bne v0, v1, nomatch
+ addu a1, a1, 1
+ bne a0, a3, 1b
+ nop
+match:
+ j ra
+ move v0, zero
+nomatch:
+ j ra
+ li v0, 1
+ .set reorder
+END(bcmp)
diff --git a/lib/libc/mips/string/bcopy.S b/lib/libc/mips/string/bcopy.S
new file mode 100644
index 0000000..3f64af5
--- /dev/null
+++ b/lib/libc/mips/string/bcopy.S
@@ -0,0 +1,127 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+/* bcopy(s1, s2, n) */
+
+
+LEAF(bcopy)
+ .set noreorder
+ addu t0, a0, a2 # t0 = end of s1 region
+ sltu t1, a1, t0
+ sltu t2, a0, a1
+ and t1, t1, t2 # t1 = true if from < to < (from+len)
+ beq t1, zero, forward # non overlapping, do forward copy
+ slt t2, a2, 12 # check for small copy
+
+ ble a2, zero, 2f
+ addu t1, a1, a2 # t1 = end of to region
+1:
+ lb v0, -1(t0) # copy bytes backwards,
+ subu t0, t0, 1 # doesnt happen often so do slow way
+ subu t1, t1, 1
+ bne t0, a0, 1b
+ sb v0, 0(t1)
+2:
+ j ra
+ nop
+forward:
+ bne t2, zero, smallcpy # do a small bcopy
+ xor v0, a0, a1 # compare low two bits of addresses
+ and v0, v0, 3
+ subu a3, zero, a1 # compute # bytes to word align address
+ beq v0, zero, aligned # addresses can be word aligned
+ and a3, a3, 3
+
+ beq a3, zero, 1f
+ subu a2, a2, a3 # subtract from remaining count
+ LWHI v0, 0(a0) # get next 4 bytes (unaligned)
+ LWLO v0, 3(a0)
+ addu a0, a0, a3
+ SWHI v0, 0(a1) # store 1, 2, or 3 bytes to align a1
+ addu a1, a1, a3
+1:
+ and v0, a2, 3 # compute number of words left
+ subu a3, a2, v0
+ move a2, v0
+ addu a3, a3, a0 # compute ending address
+2:
+ LWHI v0, 0(a0) # copy words a0 unaligned, a1 aligned
+ LWLO v0, 3(a0)
+ addu a0, a0, 4
+ addu a1, a1, 4
+ bne a0, a3, 2b
+ sw v0, -4(a1)
+ b smallcpy
+ nop
+aligned:
+ beq a3, zero, 1f
+ subu a2, a2, a3 # subtract from remaining count
+ LWHI v0, 0(a0) # copy 1, 2, or 3 bytes to align
+ addu a0, a0, a3
+ SWHI v0, 0(a1)
+ addu a1, a1, a3
+1:
+ and v0, a2, 3 # compute number of whole words left
+ subu a3, a2, v0
+ move a2, v0
+ addu a3, a3, a0 # compute ending address
+2:
+ lw v0, 0(a0) # copy words
+ addu a0, a0, 4
+ addu a1, a1, 4
+ bne a0, a3, 2b
+ sw v0, -4(a1)
+smallcpy:
+ ble a2, zero, 2f
+ addu a3, a2, a0 # compute ending address
+1:
+ lbu v0, 0(a0) # copy bytes
+ addu a0, a0, 1
+ addu a1, a1, 1
+ bne a0, a3, 1b
+ sb v0, -1(a1)
+2:
+ j ra
+ nop
+ .set reorder
+END(bcopy)
diff --git a/lib/libc/mips/string/bzero.S b/lib/libc/mips/string/bzero.S
new file mode 100644
index 0000000..cb5d258
--- /dev/null
+++ b/lib/libc/mips/string/bzero.S
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+/* bzero(s1, n) */
+
+LEAF(bzero)
+ .set noreorder
+ blt a1, 12, smallclr # small amount to clear?
+ subu a3, zero, a0 # compute # bytes to word align address
+ and a3, a3, 3
+ beq a3, zero, 1f # skip if word aligned
+ subu a1, a1, a3 # subtract from remaining count
+ SWHI zero, 0(a0) # clear 1, 2, or 3 bytes to align
+ addu a0, a0, a3
+1:
+ and v0, a1, 3 # compute number of words left
+ subu a3, a1, v0
+ move a1, v0
+ addu a3, a3, a0 # compute ending address
+2:
+ addu a0, a0, 4 # clear words
+ bne a0, a3, 2b # unrolling loop doesnt help
+ sw zero, -4(a0) # since we are limited by memory speed
+smallclr:
+ ble a1, zero, 2f
+ addu a3, a1, a0 # compute ending address
+1:
+ addu a0, a0, 1 # clear bytes
+ bne a0, a3, 1b
+ sb zero, -1(a0)
+2:
+ j ra
+ nop
+END(bzero)
diff --git a/lib/libc/mips/string/ffs.S b/lib/libc/mips/string/ffs.S
new file mode 100644
index 0000000..7392ad8
--- /dev/null
+++ b/lib/libc/mips/string/ffs.S
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+/* bit = ffs(value) */
+
+LEAF(ffs)
+ .set reorder
+ move v0, zero
+ beq a0, zero, done
+1:
+ and v1, a0, 1 # bit set?
+ addu v0, v0, 1
+ srl a0, a0, 1
+ beq v1, zero, 1b # no, continue
+done:
+ j ra
+END(ffs)
diff --git a/lib/libc/mips/string/index.S b/lib/libc/mips/string/index.S
new file mode 100644
index 0000000..c3bbe57
--- /dev/null
+++ b/lib/libc/mips/string/index.S
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+LEAF(index)
+ .set reorder
+ lbu a2, 0(a0) # get a byte
+ addu a0, a0, 1
+ beq a2, a1, fnd
+ bne a2, zero, _C_LABEL(index)
+notfnd:
+ move v0, zero
+ j ra
+fnd:
+ subu v0, a0, 1
+ j ra
+END(index)
diff --git a/lib/libc/mips/string/rindex.S b/lib/libc/mips/string/rindex.S
new file mode 100644
index 0000000..4e7dee4
--- /dev/null
+++ b/lib/libc/mips/string/rindex.S
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+LEAF(rindex)
+ .set reorder
+ move v0, zero # default if not found
+1:
+ lbu a3, 0(a0) # get a byte
+ addu a0, a0, 1
+ bne a3, a1, 2f
+ subu v0, a0, 1 # save address of last match
+2:
+ bne a3, zero, 1b # continue if not end
+ j ra
+END(rindex)
diff --git a/lib/libc/mips/string/strcmp.S b/lib/libc/mips/string/strcmp.S
new file mode 100644
index 0000000..bd6922e2
--- /dev/null
+++ b/lib/libc/mips/string/strcmp.S
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+/*
+ * NOTE: this version assumes unsigned chars in order to be "8 bit clean".
+ */
+LEAF(strcmp)
+ .set reorder
+1:
+ lbu t0, 0(a0) # get two bytes and compare them
+ lbu t1, 0(a1)
+ beq t0, zero, LessOrEq # end of first string?
+ bne t0, t1, NotEq
+ lbu t0, 1(a0) # unroll loop
+ lbu t1, 1(a1)
+ add a0, a0, 2
+ beq t0, zero, LessOrEq # end of first string?
+ add a1, a1, 2
+ beq t0, t1, 1b
+NotEq:
+ subu v0, t0, t1
+ j ra
+LessOrEq:
+ subu v0, zero, t1
+ j ra
+END(strcmp)
diff --git a/lib/libc/mips/string/strlen.S b/lib/libc/mips/string/strlen.S
new file mode 100644
index 0000000..4f0569a
--- /dev/null
+++ b/lib/libc/mips/string/strlen.S
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* LIBC_SCCS */
+
+LEAF(strlen)
+ .set reorder
+ addu v1, a0, 1
+1:
+ lb v0, 0(a0) # get byte from string
+ addu a0, a0, 1 # increment pointer
+ bne v0, zero, 1b # continue if not end
+ subu v0, a0, v1 # compute length - 1 for '\0' char
+ j ra
+END(strlen)
diff --git a/lib/libc/mips/sys/Makefile.inc b/lib/libc/mips/sys/Makefile.inc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/libc/mips/sys/Makefile.inc
diff --git a/lib/libc/mips/sys/Ovfork.S b/lib/libc/mips/sys/Ovfork.S
new file mode 100644
index 0000000..fa95c3a
--- /dev/null
+++ b/lib/libc/mips/sys/Ovfork.S
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+/*
+ * pid = vfork();
+ *
+ * v1 == 0 in parent process, v1 == 1 in child process.
+ * v0 == pid of child in parent, v0 == pid of parent in child.
+ */
+
+LEAF(vfork)
+ .set reorder
+ li v0, SYS_vfork # system call number for vfork
+ syscall
+ beq a3, zero, 1f # jump if no errors
+ la t9, cerror
+ jr t9
+1:
+ beq v1, zero, 2f # parent process ?
+ move v0, zero # return zero in child
+2:
+ j ra
+END(vfork)
diff --git a/lib/libc/mips/sys/brk.S b/lib/libc/mips/sys/brk.S
new file mode 100644
index 0000000..483be25
--- /dev/null
+++ b/lib/libc/mips/sys/brk.S
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+ .globl minbrk
+ .globl curbrk
+
+ .data
+minbrk: .word _C_LABEL(end)
+ .text
+
+LEAF(brk)
+ .set reorder
+ lw v0, minbrk
+ bltu a0, v0, 1f
+ la t9, _brk
+ jr t9
+1:
+ move a0, v0 # dont allow break < minbrk
+ li v0, SYS_break
+ syscall
+ bne a3, zero, 2f
+ sw a0, curbrk
+ move v0, zero
+ j ra
+2:
+ la t9, _C_LABEL(cerror)
+ jr t9
+END(brk)
+
+LEAF(_brk)
+ .set reorder
+ li v0, SYS_break
+ syscall
+ bne a3, zero, 1f
+ sw a0, curbrk
+ move v0, zero
+ j ra
+1:
+ la t9, _C_LABEL(cerror)
+ jr t9
+END(brk)
diff --git a/lib/libc/mips/sys/cerror.S b/lib/libc/mips/sys/cerror.S
new file mode 100644
index 0000000..8dd3aff
--- /dev/null
+++ b/lib/libc/mips/sys/cerror.S
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+ .globl _C_LABEL(errno)
+LEAF(cerror)
+ .set noreorder
+ sw v0, _C_LABEL(errno)
+ li v0, -1
+ j ra
+ li v1, -1
+END(cerror)
diff --git a/lib/libc/mips/sys/exect.S b/lib/libc/mips/sys/exect.S
new file mode 100644
index 0000000..581f21f
--- /dev/null
+++ b/lib/libc/mips/sys/exect.S
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+LEAF(exect)
+ .set reorder
+ li v0, SYS_execve
+ syscall
+ bne a3, zero, 1f
+ j ra
+1:
+ la t9, _C_LABEL(cerror)
+ jr t9
+END(exect)
diff --git a/lib/libc/mips/sys/fork.S b/lib/libc/mips/sys/fork.S
new file mode 100644
index 0000000..c454056
--- /dev/null
+++ b/lib/libc/mips/sys/fork.S
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+LEAF(fork)
+ .set reorder
+ li v0, SYS_fork # pid = fork()
+ syscall
+ bne a3, zero, 2f
+ beq v1, zero, 1f # v1 == 0 in parent, 1 in child
+ move v0, zero
+1:
+ j ra
+2:
+ la t9, _C_LABEL(cerror)
+ jr t9
+END(fork)
diff --git a/lib/libc/mips/sys/pipe.S b/lib/libc/mips/sys/pipe.S
new file mode 100644
index 0000000..2bed812
--- /dev/null
+++ b/lib/libc/mips/sys/pipe.S
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+LEAF(pipe)
+ .set reorder
+ li v0, SYS_pipe # pipe(fildes) int fildes[2];
+ syscall
+ bne a3, zero, 1f
+ sw v0, 0(a0) # store the two file descriptors
+ sw v1, 4(a0)
+ move v0, zero
+ j ra
+1:
+ la t9, _C_LABEL(cerror)
+ jr t9
+END(pipe)
diff --git a/lib/libc/mips/sys/ptrace.S b/lib/libc/mips/sys/ptrace.S
new file mode 100644
index 0000000..fe73ee0
--- /dev/null
+++ b/lib/libc/mips/sys/ptrace.S
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+LEAF(ptrace)
+ .set reorder
+ sw zero, _C_LABEL(errno)
+ li v0, SYS_ptrace
+ syscall
+ bne a3, zero, 1f
+ j ra
+1:
+ la t9, _C_LABEL(cerror)
+ jr t9
+END(ptrace)
diff --git a/lib/libc/mips/sys/sbrk.S b/lib/libc/mips/sys/sbrk.S
new file mode 100644
index 0000000..8946be1
--- /dev/null
+++ b/lib/libc/mips/sys/sbrk.S
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+ .globl curbrk
+
+ .data
+curbrk: .word _C_LABEL(end)
+ .text
+
+LEAF(sbrk)
+ .set reorder
+ lw v1, curbrk
+ li v0, SYS_break
+ addu a0, a0, v1 # compute current break
+ syscall
+
+ bne a3, zero, 1f
+ move v0, v1 # return old val of curbrk from above
+ sw a0, curbrk # save current val of curbrk from above
+ j ra
+1:
+ la t9, _C_LABEL(cerror)
+ jr t9
+END(sbrk)
diff --git a/lib/libc/mips/sys/setlogin.S b/lib/libc/mips/sys/setlogin.S
new file mode 100644
index 0000000..c148c3e
--- /dev/null
+++ b/lib/libc/mips/sys/setlogin.S
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+LEAF(setlogin)
+ .set reorder
+ li v0, SYS_setlogin # setlogin(name)
+ syscall
+
+ bne a3, zero, 1f
+ sw zero, _C_LABEL(__logname_valid) # in getlogin()
+ j ra
+1:
+ la t9, _C_LABEL(cerror)
+ jr t9
+END(setlogin)
diff --git a/lib/libc/mips/sys/sigpending.S b/lib/libc/mips/sys/sigpending.S
new file mode 100644
index 0000000..9982086
--- /dev/null
+++ b/lib/libc/mips/sys/sigpending.S
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+LEAF(sigpending)
+ .set reorder
+ li v0, SYS_sigpending # setlogin(name)
+ syscall
+ bne a3, zero, 1f
+ sw v0, 0(a0)
+ move v0, zero
+ j ra
+1:
+ la t9, _C_LABEL(cerror)
+ jr t9
+END(sigpending)
diff --git a/lib/libc/mips/sys/sigprocmask.S b/lib/libc/mips/sys/sigprocmask.S
new file mode 100644
index 0000000..ee30fd4
--- /dev/null
+++ b/lib/libc/mips/sys/sigprocmask.S
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+LEAF(sigprocmask) # sigprocmask(how, new, old) sigset_t *new, *old;
+ .set reorder
+ bne a1, zero, gotptr # if new sigset pointer not null
+ li a0, 1 # how = SIG_BLOCK
+ b doit # mask = zero
+gotptr:
+ lw a1, 0(a1) # indirect to new mask arg
+doit:
+ li v0, SYS_sigprocmask
+ syscall
+ bne a3, zero, err
+ beq a2, zero, out # test if old mask requested
+ sw v0, 0(a2) # store old mask
+out:
+ move v0, zero
+ j ra
+err:
+ la t9, _C_LABEL(cerror)
+ jr t9
+END(sigprocmask)
diff --git a/lib/libc/mips/sys/sigreturn.S b/lib/libc/mips/sys/sigreturn.S
new file mode 100644
index 0000000..4c20042
--- /dev/null
+++ b/lib/libc/mips/sys/sigreturn.S
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+/*
+ * We must preserve the state of the registers as the user has set them up.
+ */
+
+RSYSCALL(sigreturn)
diff --git a/lib/libc/mips/sys/sigsuspend.S b/lib/libc/mips/sys/sigsuspend.S
new file mode 100644
index 0000000..2394e2b
--- /dev/null
+++ b/lib/libc/mips/sys/sigsuspend.S
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+LEAF(sigsuspend)
+ .set reorder
+ lw a0, 0(a0) # indirect to mask arg
+ li v0, SYS_sigsuspend
+ syscall
+ bne a3, zero, 1f
+ move v0, zero # should not happen
+ j ra
+1:
+ la t9, _C_LABEL(cerror)
+ jr t9
+END(sigsuspend)
diff --git a/lib/libc/mips/sys/syscall.S b/lib/libc/mips/sys/syscall.S
new file mode 100644
index 0000000..d471155
--- /dev/null
+++ b/lib/libc/mips/sys/syscall.S
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "SYS.h"
+
+#if defined(SYSLIBC_SCCS)
+ .text
+ .asciz "$OpenBSD$"
+#endif /* SYSLIBC_SCCS */
+
+#define SYS_syscall 0
+
+
+RSYSCALL(syscall)
diff --git a/lib/libc/mipseb/Makefile.inc b/lib/libc/mipseb/Makefile.inc
new file mode 100644
index 0000000..656b6dd
--- /dev/null
+++ b/lib/libc/mipseb/Makefile.inc
@@ -0,0 +1 @@
+.include "${.CURDIR}/../libc/mips/Makefile.inc"
diff --git a/lib/libc/mipseb/SYS.h b/lib/libc/mipseb/SYS.h
new file mode 100644
index 0000000..ccce710
--- /dev/null
+++ b/lib/libc/mipseb/SYS.h
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $OpenBSD: SYS.h,v 1.3 1996/07/30 20:27:48 pefo Exp $
+ */
+
+#include <sys/syscall.h>
+#include <machine/asm.h>
+
+#ifdef __STDC__
+#define RSYSCALL(x) \
+ LEAF(x); \
+ li v0,SYS_ ## x; \
+ syscall; \
+ bne a3,zero,err; \
+ j ra; \
+ err: la t9, cerror; \
+ jr t9; \
+ END(x);
+#define PSEUDO(x,y) \
+ LEAF(x); \
+ li v0,SYS_ ## y; \
+ syscall; \
+ bne a3,zero,err; \
+ j ra; \
+ err: la t9, cerror; \
+ jr t9; \
+ END(x);
+#else
+#define RSYSCALL(x) \
+ LEAF(x); \
+ li v0,SYS_/**/x; \
+ syscall; \
+ bne a3,zero,err; \
+ j ra; \
+ err: la t9, cerror; \
+ jr t9; \
+ END(x);
+#define PSEUDO(x,y) \
+ LEAF(x); \
+ li v0,SYS_/**/y; \
+ syscall; \
+ bne a3,zero,err; \
+ j ra; \
+ err: la t9, cerror; \
+ jr t9; \
+ END(x);
+#endif
diff --git a/lib/libc/mipseb/gen/Makefile.inc b/lib/libc/mipseb/gen/Makefile.inc
new file mode 100644
index 0000000..157d1a4
--- /dev/null
+++ b/lib/libc/mipseb/gen/Makefile.inc
@@ -0,0 +1 @@
+.include "${.CURDIR}/../libc/mips/gen/Makefile.inc"
diff --git a/lib/libc/mipseb/net/Makefile.inc b/lib/libc/mipseb/net/Makefile.inc
new file mode 100644
index 0000000..6d330b0
--- /dev/null
+++ b/lib/libc/mipseb/net/Makefile.inc
@@ -0,0 +1 @@
+.include "${.CURDIR}/../libc/mips/net/Makefile.inc"
diff --git a/lib/libc/mipseb/stdlib/Makefile.inc b/lib/libc/mipseb/stdlib/Makefile.inc
new file mode 100644
index 0000000..9a9462b
--- /dev/null
+++ b/lib/libc/mipseb/stdlib/Makefile.inc
@@ -0,0 +1 @@
+.include "${.CURDIR}/../libc/mips/stdlib/Makefile.inc"
diff --git a/lib/libc/mipseb/string/Makefile.inc b/lib/libc/mipseb/string/Makefile.inc
new file mode 100644
index 0000000..302acfd
--- /dev/null
+++ b/lib/libc/mipseb/string/Makefile.inc
@@ -0,0 +1 @@
+.include "${.CURDIR}/../libc/mips/string/Makefile.inc"
diff --git a/lib/libc/mipseb/sys/Makefile.inc b/lib/libc/mipseb/sys/Makefile.inc
new file mode 100644
index 0000000..1fe51f5
--- /dev/null
+++ b/lib/libc/mipseb/sys/Makefile.inc
@@ -0,0 +1 @@
+.include "${.CURDIR}/../libc/mips/sys/Makefile.inc"
diff --git a/lib/libc/mipsel/Makefile.inc b/lib/libc/mipsel/Makefile.inc
new file mode 100644
index 0000000..656b6dd
--- /dev/null
+++ b/lib/libc/mipsel/Makefile.inc
@@ -0,0 +1 @@
+.include "${.CURDIR}/../libc/mips/Makefile.inc"
diff --git a/lib/libc/mipsel/SYS.h b/lib/libc/mipsel/SYS.h
new file mode 100644
index 0000000..ccce710
--- /dev/null
+++ b/lib/libc/mipsel/SYS.h
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $OpenBSD: SYS.h,v 1.3 1996/07/30 20:27:48 pefo Exp $
+ */
+
+#include <sys/syscall.h>
+#include <machine/asm.h>
+
+#ifdef __STDC__
+#define RSYSCALL(x) \
+ LEAF(x); \
+ li v0,SYS_ ## x; \
+ syscall; \
+ bne a3,zero,err; \
+ j ra; \
+ err: la t9, cerror; \
+ jr t9; \
+ END(x);
+#define PSEUDO(x,y) \
+ LEAF(x); \
+ li v0,SYS_ ## y; \
+ syscall; \
+ bne a3,zero,err; \
+ j ra; \
+ err: la t9, cerror; \
+ jr t9; \
+ END(x);
+#else
+#define RSYSCALL(x) \
+ LEAF(x); \
+ li v0,SYS_/**/x; \
+ syscall; \
+ bne a3,zero,err; \
+ j ra; \
+ err: la t9, cerror; \
+ jr t9; \
+ END(x);
+#define PSEUDO(x,y) \
+ LEAF(x); \
+ li v0,SYS_/**/y; \
+ syscall; \
+ bne a3,zero,err; \
+ j ra; \
+ err: la t9, cerror; \
+ jr t9; \
+ END(x);
+#endif
diff --git a/lib/libc/mipsel/gen/Makefile.inc b/lib/libc/mipsel/gen/Makefile.inc
new file mode 100644
index 0000000..157d1a4
--- /dev/null
+++ b/lib/libc/mipsel/gen/Makefile.inc
@@ -0,0 +1 @@
+.include "${.CURDIR}/../libc/mips/gen/Makefile.inc"
diff --git a/lib/libc/mipsel/net/Makefile.inc b/lib/libc/mipsel/net/Makefile.inc
new file mode 100644
index 0000000..6d330b0
--- /dev/null
+++ b/lib/libc/mipsel/net/Makefile.inc
@@ -0,0 +1 @@
+.include "${.CURDIR}/../libc/mips/net/Makefile.inc"
diff --git a/lib/libc/mipsel/stdlib/Makefile.inc b/lib/libc/mipsel/stdlib/Makefile.inc
new file mode 100644
index 0000000..9a9462b
--- /dev/null
+++ b/lib/libc/mipsel/stdlib/Makefile.inc
@@ -0,0 +1 @@
+.include "${.CURDIR}/../libc/mips/stdlib/Makefile.inc"
diff --git a/lib/libc/mipsel/string/Makefile.inc b/lib/libc/mipsel/string/Makefile.inc
new file mode 100644
index 0000000..302acfd
--- /dev/null
+++ b/lib/libc/mipsel/string/Makefile.inc
@@ -0,0 +1 @@
+.include "${.CURDIR}/../libc/mips/string/Makefile.inc"
diff --git a/lib/libc/mipsel/sys/Makefile.inc b/lib/libc/mipsel/sys/Makefile.inc
new file mode 100644
index 0000000..1fe51f5
--- /dev/null
+++ b/lib/libc/mipsel/sys/Makefile.inc
@@ -0,0 +1 @@
+.include "${.CURDIR}/../libc/mips/sys/Makefile.inc"
diff --git a/lib/libc/net/Makefile.inc b/lib/libc/net/Makefile.inc
new file mode 100644
index 0000000..5b7dc85
--- /dev/null
+++ b/lib/libc/net/Makefile.inc
@@ -0,0 +1,59 @@
+# from @(#)Makefile.inc 8.2 (Berkeley) 9/5/93
+# $FreeBSD$
+
+# machine-independent net sources
+.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/net ${.CURDIR}/../libc/net
+
+SRCS+= addr2ascii.c ascii2addr.c base64.c ether_addr.c \
+ gethostbydns.c gethostbyht.c gethostbynis.c gethostnamadr.c \
+ getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \
+ getproto.c getprotoent.c getprotoname.c getservbyname.c \
+ getservbyport.c getservent.c herror.c inet_addr.c ifname.c \
+ inet_lnaof.c \
+ inet_makeaddr.c inet_net_ntop.c inet_net_pton.c inet_neta.c \
+ inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \
+ inet_pton.c ip6opt.c linkaddr.c map_v4v6.c ns_addr.c \
+ ns_name.c ns_netint.c \
+ ns_ntoa.c ns_parse.c ns_print.c ns_ttl.c nsap_addr.c \
+ rcmd.c recv.c res_comp.c res_data.c res_debug.c \
+ res_init.c res_mkquery.c res_mkupdate.c res_query.c res_send.c \
+ res_update.c rthdr.c send.c vars.c
+# not supported: iso_addr.c
+
+# machine-dependent net sources
+.include "${.CURDIR}/../libc/${MACHINE_ARCH}/net/Makefile.inc"
+
+.if ${LIB} == "c"
+MAN3+= addr2ascii.3 byteorder.3 ethers.3 gethostbyname.3 \
+ getnetent.3 getprotoent.3 getservent.3 if_indextoname.3 \
+ inet.3 linkaddr.3 rcmd.3 resolver.3
+# not installed: iso_addr.3 ns.3
+
+MLINKS+=addr2ascii.3 ascii2addr.3
+MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \
+ byteorder.3 ntohs.3
+MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \
+ ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3
+MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \
+ gethostbyname.3 gethostbyname2.3 gethostbyname.3 gethostent.3 \
+ gethostbyname.3 herror.3 gethostbyname.3 hstrerror.3 \
+ gethostbyname.3 sethostent.3
+MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \
+ getnetent.3 getnetbyname.3 getnetent.3 setnetent.3
+MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \
+ getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3
+MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \
+ getservent.3 getservbyport.3 getservent.3 setservent.3
+MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_aton.3 \
+ inet.3 inet_lnaof.3 inet.3 inet_makeaddr.3 inet.3 inet_netof.3 \
+ inet.3 inet_network.3 inet.3 inet_ntoa.3 inet.3 network.3 \
+ inet.3 ntoa.3
+MLINKS+=if_indextoname.3 if_nametoindex.3 if_indextoname.3 if_nameindex.3 \
+ if_indextoname.3 if_freenameindex.3
+MLINKS+=linkaddr.3 link_addr.3 linkaddr.3 link_ntoa.3
+#MLINKS+=ns.3 ns_addr.3 ns.3 ns_ntoa.3
+MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3
+MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \
+ resolver.3 res_mkquery.3 resolver.3 res_query.3 \
+ resolver.3 res_search.3 resolver.3 res_send.3
+.endif
diff --git a/lib/libc/net/addr2ascii.3 b/lib/libc/net/addr2ascii.3
new file mode 100644
index 0000000..b5ec167
--- /dev/null
+++ b/lib/libc/net/addr2ascii.3
@@ -0,0 +1,217 @@
+.\"
+.\" Copyright 1996 Massachusetts Institute of Technology
+.\"
+.\" Permission to use, copy, modify, and distribute this software and
+.\" its documentation for any purpose and without fee is hereby
+.\" granted, provided that both the above copyright notice and this
+.\" permission notice appear in all copies, that both the above
+.\" copyright notice and this permission notice appear in all
+.\" supporting documentation, and that the name of M.I.T. not be used
+.\" in advertising or publicity pertaining to distribution of the
+.\" software without specific, written prior permission. M.I.T. makes
+.\" no representations about the suitability of this software for any
+.\" purpose. It is provided "as is" without express or implied
+.\" warranty.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+.\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+.\" SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $ANA: addr2ascii.3,v 1.1 1996/06/13 18:41:46 wollman Exp $
+.\" $FreeBSD$
+.\"
+.Dd June 13, 1996
+.Dt ADDR2ASCII 3
+.Os
+.Sh NAME
+.Nm addr2ascii ,
+.Nm ascii2addr
+.Nd Generic address formatting routines
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <netinet/in.h>
+.Fd #include <arpa/inet.h>
+.Ft "char *"
+.Fn addr2ascii "int af" "const void *addrp" "int len" "char *buf"
+.Ft int
+.Fn ascii2addr "int af" "const char *ascii" "void *result"
+.Sh DESCRIPTION
+The routines
+.Fn addr2ascii
+and
+.Fn ascii2addr
+are used to convert network addresses between binary form and a
+printable form appropriate to the address family. Both functions take
+an
+.Fa af
+argument, specifying the address family to be used in the conversion
+process.
+(Currently, only the
+.Dv AF_INET
+and
+.Dv AF_LINK
+address families are supported.)
+.Pp
+The
+.Fn addr2ascii
+function
+is used to convert binary, network-format addresses into printable
+form. In addition to
+.Fa af ,
+there are three other arguments. The
+.Fa addrp
+argument is a pointer to the network address to be converted.
+The
+.Fa len
+argument is the length of the address. The
+.Fa buf
+argument is an optional pointer to a caller-allocated buffer to hold
+the result; if a null pointer is passed,
+.Fn addr2ascii
+uses a statically-allocated buffer.
+.Pp
+The
+.Fn ascii2addr
+function performs the inverse operation to
+.Fn addr2ascii .
+In addition to
+.Fa af ,
+it takes two parameters,
+.Fa ascii
+and
+.Fa result .
+The
+.Fa ascii
+parameter is a pointer to the string which is to be converted into
+binary. The
+.Fa result
+parameter is a pointer to an appropriate network address structure for
+the specified family.
+.Pp
+The following gives the appropriate structure to use for binary
+addresses in the specified family:
+.Pp
+.Bl -tag -width AF_INETxxxx -compact
+.It Dv AF_INET
+.Li struct in_addr
+.Pq in Aq Pa netinet/in.h
+.It Dv AF_LINK
+.Li struct sockaddr_dl
+.Pq in Aq Pa net/if_dl.h
+.\" .It Dv AF_INET6
+.\" .Li struct in6_addr
+.\" .Pq in Aq Pa netinet6/in6.h
+.El
+.Sh RETURN VALUES
+The
+.Fn addr2ascii
+function returns the address of the buffer it was passed, or a static
+buffer if the a null pointer was passed; on failure, it returns a null
+pointer.
+The
+.Fn ascii2addr
+function returns the length of the binary address in bytes, or -1 on
+failure.
+.Sh EXAMPLES
+The
+.Xr inet 3
+functions
+.Fn inet_ntoa
+and
+.Fn inet_aton
+could be implemented thusly:
+.Bd -literal -offset indent
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+char *
+inet_ntoa(struct in_addr addr)
+{
+ return addr2ascii(AF_INET, &addr, sizeof addr, 0);
+}
+
+int
+inet_aton(const char *ascii, struct in_addr *addr)
+{
+ return (ascii2addr(AF_INET, ascii, addr)
+ == sizeof(*addr));
+}
+.Ed
+.Pp
+In actuality, this cannot be done because
+.Fn addr2ascii
+and
+.Fn ascii2addr
+are implemented in terms of the
+.Xr inet 3
+functions, rather than the other way around.
+.Sh ERRORS
+When a failure is returned,
+.Li errno
+is set to one of the following values:
+.Bl -tag -width [EPROTONOSUPPORT]
+.It Bq Er ENAMETOOLONG
+The
+.Fn addr2ascii
+routine was passed a
+.Fa len
+parameter which was inappropriate for the address family given by
+.Fa af .
+.It Bq Er EPROTONOSUPPORT
+Either routine was passed an
+.Fa af
+parameter other than
+.Dv AF_INET
+or
+.Dv AF_LINK .
+.It Bq Er EINVAL
+The string passed to
+.Fn ascii2addr
+was improperly formatted for address family
+.Fa af .
+.El
+.Sh SEE ALSO
+.Xr inet 3 ,
+.Xr linkaddr 3 ,
+.Xr inet 4
+.Sh HISTORY
+An interface close to this one was originally suggested by Craig
+Partridge. This particular interface originally appeared in the
+.Tn INRIA
+.Tn IPv6
+implementation.
+.Sh AUTHORS
+Code and documentation by
+.An Garrett A. Wollman ,
+MIT Laboratory for Computer Science.
+.Sh BUGS
+The original implementations supported IPv6. This support should
+eventually be resurrected. The
+.Tn NRL
+implementation also included support for the
+.Dv AF_ISO
+and
+.Dv AF_NS
+address families.
+.Pp
+The genericity of this interface is somewhat questionable. A truly
+generic interface would provide a means for determining the length of
+the buffer to be used so that it could be dynamically allocated, and
+would always require a
+.Dq Li "struct sockaddr"
+to hold the binary address. Unfortunately, this is incompatible with existing
+practice. This limitation means that a routine for printing network
+addresses from arbitrary address families must still have internal
+knowledge of the maximum buffer length needed and the appropriate part
+of the address to use as the binary address.
diff --git a/lib/libc/net/addr2ascii.c b/lib/libc/net/addr2ascii.c
new file mode 100644
index 0000000..5bee3ea
--- /dev/null
+++ b/lib/libc/net/addr2ascii.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright 1996 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $ANA: addr2ascii.c,v 1.1 1996/06/13 18:41:46 wollman Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include <net/if_dl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*-
+ * Convert a network address from binary to printable numeric format.
+ * This API is copied from INRIA's IPv6 implementation, but it is a
+ * bit bogus in two ways:
+ *
+ * 1) There is no value in passing both an address family and
+ * an address length; either one should imply the other,
+ * or we should be passing sockaddrs instead.
+ * 2) There should by contrast be /added/ a length for the buffer
+ * that we pass in, so that programmers are spared the need to
+ * manually calculate (read: ``guess'') the maximum length.
+ *
+ * Flash: the API is also the same in the NRL implementation, and seems to
+ * be some sort of standard, so we appear to be stuck with both the bad
+ * naming and the poor choice of arguments.
+ */
+char *
+addr2ascii(af, addrp, len, buf)
+ int af;
+ const void *addrp;
+ int len; /* should be size_t XXX */
+ char *buf; /* XXX should pass length of buffer */
+{
+ static char staticbuf[64]; /* 64 for AF_LINK > 16 for AF_INET */
+
+ if (!buf)
+ buf = staticbuf;
+
+ switch(af) {
+ case AF_INET:
+ if (len != sizeof(struct in_addr)) {
+ errno = ENAMETOOLONG;
+ return 0;
+ }
+ strcpy(buf, inet_ntoa(*(const struct in_addr *)addrp));
+ break;
+
+ case AF_LINK:
+ if (len != sizeof(struct sockaddr_dl)) {
+ errno = ENAMETOOLONG;
+ return 0;
+ }
+ strcpy(buf, link_ntoa((const struct sockaddr_dl *)addrp));
+ break;
+
+ default:
+ errno = EPROTONOSUPPORT;
+ return 0;
+ }
+ return buf;
+}
diff --git a/lib/libc/net/ascii2addr.c b/lib/libc/net/ascii2addr.c
new file mode 100644
index 0000000..0b5bab4
--- /dev/null
+++ b/lib/libc/net/ascii2addr.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1996 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $ANA: ascii2addr.c,v 1.2 1996/06/13 18:46:02 wollman Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include <net/if_dl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int
+ascii2addr(af, ascii, result)
+ int af;
+ const char *ascii;
+ void *result;
+{
+ struct in_addr *ina;
+ char strbuf[4*sizeof("123")]; /* long enough for V4 only */
+
+ switch(af) {
+ case AF_INET:
+ ina = result;
+ strbuf[0] = '\0';
+ strncat(strbuf, ascii, (sizeof strbuf)-1);
+ if (inet_aton(strbuf, ina))
+ return sizeof(struct in_addr);
+ errno = EINVAL;
+ break;
+
+ case AF_LINK:
+ link_addr(ascii, result);
+ /* oops... no way to detect failure */
+ return sizeof(struct sockaddr_dl);
+
+ default:
+ errno = EPROTONOSUPPORT;
+ break;
+ }
+
+ return -1;
+}
diff --git a/lib/libc/net/base64.c b/lib/libc/net/base64.c
new file mode 100644
index 0000000..1301b6a
--- /dev/null
+++ b/lib/libc/net/base64.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software. No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#if !defined(LINT) && !defined(CODECENTER)
+static char rcsid[] = "$FreeBSD$";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define Assert(Cond) if (!(Cond)) abort()
+
+static const char Base64[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char Pad64 = '=';
+
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
+ The following encoding technique is taken from RFC 1521 by Borenstein
+ and Freed. It is reproduced here in a slightly edited form for
+ convenience.
+
+ A 65-character subset of US-ASCII is used, enabling 6 bits to be
+ represented per printable character. (The extra 65th character, "=",
+ is used to signify a special processing function.)
+
+ The encoding process represents 24-bit groups of input bits as output
+ strings of 4 encoded characters. Proceeding from left to right, a
+ 24-bit input group is formed by concatenating 3 8-bit input groups.
+ These 24 bits are then treated as 4 concatenated 6-bit groups, each
+ of which is translated into a single digit in the base64 alphabet.
+
+ Each 6-bit group is used as an index into an array of 64 printable
+ characters. The character referenced by the index is placed in the
+ output string.
+
+ Table 1: The Base64 Alphabet
+
+ Value Encoding Value Encoding Value Encoding Value Encoding
+ 0 A 17 R 34 i 51 z
+ 1 B 18 S 35 j 52 0
+ 2 C 19 T 36 k 53 1
+ 3 D 20 U 37 l 54 2
+ 4 E 21 V 38 m 55 3
+ 5 F 22 W 39 n 56 4
+ 6 G 23 X 40 o 57 5
+ 7 H 24 Y 41 p 58 6
+ 8 I 25 Z 42 q 59 7
+ 9 J 26 a 43 r 60 8
+ 10 K 27 b 44 s 61 9
+ 11 L 28 c 45 t 62 +
+ 12 M 29 d 46 u 63 /
+ 13 N 30 e 47 v
+ 14 O 31 f 48 w (pad) =
+ 15 P 32 g 49 x
+ 16 Q 33 h 50 y
+
+ Special processing is performed if fewer than 24 bits are available
+ at the end of the data being encoded. A full encoding quantum is
+ always completed at the end of a quantity. When fewer than 24 input
+ bits are available in an input group, zero bits are added (on the
+ right) to form an integral number of 6-bit groups. Padding at the
+ end of the data is performed using the '=' character.
+
+ Since all base64 input is an integral number of octets, only the
+ -------------------------------------------------
+ following cases can arise:
+
+ (1) the final quantum of encoding input is an integral
+ multiple of 24 bits; here, the final unit of encoded
+ output will be an integral multiple of 4 characters
+ with no "=" padding,
+ (2) the final quantum of encoding input is exactly 8 bits;
+ here, the final unit of encoded output will be two
+ characters followed by two "=" padding characters, or
+ (3) the final quantum of encoding input is exactly 16 bits;
+ here, the final unit of encoded output will be three
+ characters followed by one "=" padding character.
+ */
+
+int
+b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
+ size_t datalength = 0;
+ u_char input[3];
+ u_char output[4];
+ size_t i;
+
+ while (2 < srclength) {
+ input[0] = *src++;
+ input[1] = *src++;
+ input[2] = *src++;
+ srclength -= 3;
+
+ output[0] = input[0] >> 2;
+ output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+ output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+ output[3] = input[2] & 0x3f;
+ Assert(output[0] < 64);
+ Assert(output[1] < 64);
+ Assert(output[2] < 64);
+ Assert(output[3] < 64);
+
+ if (datalength + 4 > targsize)
+ return (-1);
+ target[datalength++] = Base64[output[0]];
+ target[datalength++] = Base64[output[1]];
+ target[datalength++] = Base64[output[2]];
+ target[datalength++] = Base64[output[3]];
+ }
+
+ /* Now we worry about padding. */
+ if (0 != srclength) {
+ /* Get what's left. */
+ input[0] = input[1] = input[2] = '\0';
+ for (i = 0; i < srclength; i++)
+ input[i] = *src++;
+
+ output[0] = input[0] >> 2;
+ output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+ output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+ Assert(output[0] < 64);
+ Assert(output[1] < 64);
+ Assert(output[2] < 64);
+
+ if (datalength + 4 > targsize)
+ return (-1);
+ target[datalength++] = Base64[output[0]];
+ target[datalength++] = Base64[output[1]];
+ if (srclength == 1)
+ target[datalength++] = Pad64;
+ else
+ target[datalength++] = Base64[output[2]];
+ target[datalength++] = Pad64;
+ }
+ if (datalength >= targsize)
+ return (-1);
+ target[datalength] = '\0'; /* Returned value doesn't count \0. */
+ return (datalength);
+}
+
+/* skips all whitespace anywhere.
+ converts characters, four at a time, starting at (or after)
+ src from base - 64 numbers into three 8 bit bytes in the target area.
+ it returns the number of data bytes stored at the target, or -1 on error.
+ */
+
+int
+b64_pton(src, target, targsize)
+ char const *src;
+ u_char *target;
+ size_t targsize;
+{
+ int tarindex, state, ch;
+ char *pos;
+
+ state = 0;
+ tarindex = 0;
+
+ while ((ch = *src++) != '\0') {
+ if (isspace((unsigned char)ch)) /* Skip whitespace anywhere. */
+ continue;
+
+ if (ch == Pad64)
+ break;
+
+ pos = strchr(Base64, ch);
+ if (pos == 0) /* A non-base64 character. */
+ return (-1);
+
+ switch (state) {
+ case 0:
+ if (target) {
+ if ((size_t)tarindex >= targsize)
+ return (-1);
+ target[tarindex] = (pos - Base64) << 2;
+ }
+ state = 1;
+ break;
+ case 1:
+ if (target) {
+ if ((size_t)tarindex + 1 >= targsize)
+ return (-1);
+ target[tarindex] |= (pos - Base64) >> 4;
+ target[tarindex+1] = ((pos - Base64) & 0x0f)
+ << 4 ;
+ }
+ tarindex++;
+ state = 2;
+ break;
+ case 2:
+ if (target) {
+ if ((size_t)tarindex + 1 >= targsize)
+ return (-1);
+ target[tarindex] |= (pos - Base64) >> 2;
+ target[tarindex+1] = ((pos - Base64) & 0x03)
+ << 6;
+ }
+ tarindex++;
+ state = 3;
+ break;
+ case 3:
+ if (target) {
+ if ((size_t)tarindex >= targsize)
+ return (-1);
+ target[tarindex] |= (pos - Base64);
+ }
+ tarindex++;
+ state = 0;
+ break;
+ default:
+ abort();
+ }
+ }
+
+ /*
+ * We are done decoding Base-64 chars. Let's see if we ended
+ * on a byte boundary, and/or with erroneous trailing characters.
+ */
+
+ if (ch == Pad64) { /* We got a pad char. */
+ ch = *src++; /* Skip it, get next. */
+ switch (state) {
+ case 0: /* Invalid = in first position */
+ case 1: /* Invalid = in second position */
+ return (-1);
+
+ case 2: /* Valid, means one byte of info */
+ /* Skip any number of spaces. */
+ for ((void)NULL; ch != '\0'; ch = *src++)
+ if (!isspace((unsigned char)ch))
+ break;
+ /* Make sure there is another trailing = sign. */
+ if (ch != Pad64)
+ return (-1);
+ ch = *src++; /* Skip the = */
+ /* Fall through to "single trailing =" case. */
+ /* FALLTHROUGH */
+
+ case 3: /* Valid, means two bytes of info */
+ /*
+ * We know this char is an =. Is there anything but
+ * whitespace after it?
+ */
+ for ((void)NULL; ch != '\0'; ch = *src++)
+ if (!isspace((unsigned char)ch))
+ return (-1);
+
+ /*
+ * Now make sure for cases 2 and 3 that the "extra"
+ * bits that slopped past the last full byte were
+ * zeros. If we don't check them, they become a
+ * subliminal channel.
+ */
+ if (target && target[tarindex] != 0)
+ return (-1);
+ }
+ } else {
+ /*
+ * We ended by seeing the end of the string. Make sure we
+ * have no partial bytes lying around.
+ */
+ if (state != 0)
+ return (-1);
+ }
+
+ return (tarindex);
+}
diff --git a/lib/libc/net/byteorder.3 b/lib/libc/net/byteorder.3
new file mode 100644
index 0000000..3c55d21c
--- /dev/null
+++ b/lib/libc/net/byteorder.3
@@ -0,0 +1,77 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)byteorder.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt BYTEORDER 3
+.Os BSD 4.2
+.Sh NAME
+.Nm htonl ,
+.Nm htons ,
+.Nm ntohl ,
+.Nm ntohs
+.Nd convert values between host and network byte order
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Ft u_long
+.Fn htonl "u_long hostlong"
+.Ft u_short
+.Fn htons "u_short hostshort"
+.Ft u_long
+.Fn ntohl "u_long netlong"
+.Ft u_short
+.Fn ntohs "u_short netshort"
+.Sh DESCRIPTION
+These routines convert 16 and 32 bit quantities between network
+byte order and host byte order.
+On machines which have a byte order which is the same as the network
+order, routines are defined as null macros.
+.Pp
+These routines are most often used in conjunction with Internet
+addresses and ports as returned by
+.Xr gethostbyname 3
+and
+.Xr getservent 3 .
+.Sh SEE ALSO
+.Xr gethostbyname 3 ,
+.Xr getservent 3
+.Sh HISTORY
+The
+.Nm byteorder
+functions appeared in
+.Bx 4.2 .
+.Sh BUGS
+On the
+.Tn VAX
+bytes are handled backwards from most everyone else in
+the world. This is not expected to be fixed in the near future.
diff --git a/lib/libc/net/ether_addr.c b/lib/libc/net/ether_addr.c
new file mode 100644
index 0000000..89aa7b5
--- /dev/null
+++ b/lib/libc/net/ether_addr.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 1995
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * ethernet address conversion and lookup routines
+ *
+ * Written by Bill Paul <wpaul@ctr.columbia.edu>
+ * Center for Telecommunications Research
+ * Columbia University, New York City
+ *
+ * $FreeBSD$
+ */
+
+
+#include <stdio.h>
+#include <paths.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/ethernet.h>
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+
+#ifndef _PATH_ETHERS
+#define _PATH_ETHERS "/etc/ethers"
+#endif
+
+/*
+ * Parse a string of text containing an ethernet address and hostname
+ * and separate it into its component parts.
+ */
+int ether_line(l, e, hostname)
+ char *l;
+ struct ether_addr *e;
+ char *hostname;
+{
+ int i, o[6];
+
+ i = sscanf(l, "%x:%x:%x:%x:%x:%x %s", &o[0], &o[1], &o[2],
+ &o[3], &o[4], &o[5],
+ hostname);
+ if (i != 7)
+ return (i);
+
+ for (i=0; i<6; i++)
+ e->octet[i] = o[i];
+ return (0);
+}
+
+/*
+ * Convert an ASCII representation of an ethernet address to
+ * binary form.
+ */
+struct ether_addr *ether_aton(a)
+ char *a;
+{
+ int i;
+ static struct ether_addr o;
+ unsigned int o0, o1, o2, o3, o4, o5;
+
+ i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o0, &o1, &o2, &o3, &o4, &o5);
+
+ if (i != 6)
+ return (NULL);
+
+ o.octet[0]=o0;
+ o.octet[1]=o1;
+ o.octet[2]=o2;
+ o.octet[3]=o3;
+ o.octet[4]=o4;
+ o.octet[5]=o5;
+
+ return ((struct ether_addr *)&o);
+}
+
+/*
+ * Convert a binary representation of an ethernet address to
+ * an ASCII string.
+ */
+char *ether_ntoa(n)
+ struct ether_addr *n;
+{
+ int i;
+ static char a[18];
+
+ i = sprintf(a,"%x:%x:%x:%x:%x:%x",n->octet[0],n->octet[1],n->octet[2],
+ n->octet[3],n->octet[4],n->octet[5]);
+ if (i < 11)
+ return (NULL);
+ return ((char *)&a);
+}
+
+/*
+ * Map an ethernet address to a hostname. Use either /etc/ethers or
+ * NIS/YP.
+ */
+
+int ether_ntohost(hostname, e)
+ char *hostname;
+ struct ether_addr *e;
+{
+ FILE *fp;
+ char buf[BUFSIZ + 2];
+ struct ether_addr local_ether;
+ char local_host[MAXHOSTNAMELEN];
+#ifdef YP
+ char *result;
+ int resultlen;
+ char *ether_a;
+ char *yp_domain;
+#endif
+ if ((fp = fopen(_PATH_ETHERS, "r")) == NULL)
+ return (1);
+
+ while (fgets(buf,BUFSIZ,fp)) {
+ if (buf[0] == '#')
+ continue;
+#ifdef YP
+ if (buf[0] == '+') {
+ if (yp_get_default_domain(&yp_domain))
+ continue;
+ ether_a = ether_ntoa(e);
+ if (yp_match(yp_domain, "ethers.byaddr", ether_a,
+ strlen(ether_a), &result, &resultlen)) {
+ continue;
+ }
+ strncpy(buf, result, resultlen);
+ buf[resultlen] = '\0';
+ free(result);
+ }
+#endif
+ if (!ether_line(buf, &local_ether, local_host)) {
+ if (!bcmp((char *)&local_ether.octet[0],
+ (char *)&e->octet[0], 6)) {
+ /* We have a match */
+ strcpy(hostname, local_host);
+ fclose(fp);
+ return(0);
+ }
+ }
+ }
+ fclose(fp);
+ return (1);
+}
+
+/*
+ * Map a hostname to an ethernet address using /etc/ethers or
+ * NIS/YP.
+ */
+int ether_hostton(hostname, e)
+ char *hostname;
+ struct ether_addr *e;
+{
+ FILE *fp;
+ char buf[BUFSIZ + 2];
+ struct ether_addr local_ether;
+ char local_host[MAXHOSTNAMELEN];
+#ifdef YP
+ char *result;
+ int resultlen;
+ char *yp_domain;
+#endif
+ if ((fp = fopen(_PATH_ETHERS, "r")) == NULL)
+ return (1);
+
+ while (fgets(buf,BUFSIZ,fp)) {
+ if (buf[0] == '#')
+ continue;
+#ifdef YP
+ if (buf[0] == '+') {
+ if (yp_get_default_domain(&yp_domain))
+ continue;
+ if (yp_match(yp_domain, "ethers.byname", hostname,
+ strlen(hostname), &result, &resultlen)) {
+ continue;
+ }
+ strncpy(buf, result, resultlen);
+ buf[resultlen] = '\0';
+ free(result);
+ }
+#endif
+ if (!ether_line(buf, &local_ether, local_host)) {
+ if (!strcmp(hostname, local_host)) {
+ /* We have a match */
+ bcopy((char *)&local_ether.octet[0],
+ (char *)&e->octet[0], 6);
+ fclose(fp);
+ return(0);
+ }
+ }
+ }
+ fclose(fp);
+ return (1);
+}
diff --git a/lib/libc/net/ethers.3 b/lib/libc/net/ethers.3
new file mode 100644
index 0000000..41376c9
--- /dev/null
+++ b/lib/libc/net/ethers.3
@@ -0,0 +1,192 @@
+.\" Copyright (c) 1995
+.\" Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Bill Paul.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 12, 1995
+.Dt ETHERS 3
+.Os FreeBSD 2.1
+.Sh NAME
+.Nm ethers ,
+.Nm ether_line ,
+.Nm ether_aton ,
+.Nm ether_ntoa ,
+.Nm ether_ntohost ,
+.Nm ether_hostton
+.Nd Ethernet address conversion and lookup routines
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Fd #include <net/ethernet.h>
+.Ft int
+.Fn ether_line "char *l" "struct ether_addr *e" "char *hostname"
+.Ft struct ether_addr *
+.Fn ether_aton "char *a"
+.Ft char *
+.Fn ether_ntoa "struct ether_addr *n"
+.Ft int
+.Fn ether_ntohost "char *hostname" "struct ether_addr *e"
+.Ft int
+.Fn ether_hostton "char *hostname" "struct ether_addr *e"
+.Sh DESCRIPTION
+These functions operate on ethernet addresses using an
+.Ar ether_addr
+structure, which is defined in the header file
+.Aq Pa netinet/if_ether.h :
+.Bd -literal -offset indent
+/*
+ * The number of bytes in an ethernet (MAC) address.
+ */
+#define ETHER_ADDR_LEN 6
+
+/*
+ * Structure of a 48-bit Ethernet address.
+ */
+struct ether_addr {
+ u_char octet[ETHER_ADDR_LEN];
+};
+.Ed
+.Pp
+The function
+.Fn ether_line
+scans
+.Ar l ,
+an
+.Tn ASCII
+string in
+.Xr ethers 5
+format and sets
+.Ar e
+to the ethernet address specified in the string and
+.Ar h
+to the hostname. This function is used to parse lines from
+.Pa /etc/ethers
+into their component parts.
+.Pp
+The
+.Fn ether_aton
+function converts an
+.Tn ASCII
+representation of an ethernet address into an
+.Ar ether_addr
+structure. Likewise,
+.Fn ether_ntoa
+converts an ethernet address specified as an
+.Ar ether_addr
+structure into an
+.Tn ASCII
+string.
+.Pp
+The
+.Fn ether_ntohost
+and
+.Fn ether_hostton
+functions map ethernet addresses to their corresponding hostnames
+as specified in the
+.Pa /etc/ethers
+database.
+.Fn ether_ntohost
+converts from ethernet address to hostname, and
+.Fn ether_hostton
+converts from hostname to ethernet address.
+.Sh RETURN VALUES
+.Fn ether_line
+returns zero on success and non-zero if it was unable to parse
+any part of the supplied line
+.Ar l .
+It returns the extracted ethernet address in the supplied
+.Ar ether_addr
+structure
+.Ar e
+and the hostname in the supplied string
+.Ar h .
+.Pp
+On success,
+.Fn ether_ntoa
+returns a pointer to a string containing an
+.Tn ASCII
+representation of an ethernet address. If it is unable to convert
+the supplied
+.Ar ether_addr
+structure, it returns a
+.Dv NULL
+pointer. Likewise,
+.Fn ether_aton
+returns a pointer to an
+.Ar ether_addr
+structure on success and a
+.Dv NULL
+pointer on failure.
+.Pp
+The
+.Fn ether_ntohost
+and
+.Fn ether_hostton
+functions both return zero on success or non-zero if they were
+unable to find a match in the
+.Pa /etc/ethers
+database.
+.Sh NOTES
+The user must insure that the hostname strings passed to the
+.Fn ether_line ,
+.Fn ether_ntohost
+and
+.Fn ether_hostton
+functions are large enough to contain the returned hostnames.
+.Sh NIS INTERACTION
+If the
+.Pa /etc/ethers
+contains a line with a single + in it, the
+.Fn ether_ntohost
+and
+.Fn ether_hostton
+functions will attempt to consult the NIS
+.Pa ethers.byname
+and
+.Pa ethers.byaddr
+maps in addition to the data in the
+.Pa /etc/ethers
+file.
+.Sh SEE ALSO
+.Xr yp 4 ,
+.Xr ethers 5
+.Sh BUGS
+.Pp
+The
+.Fn ether_aton
+and
+.Fn ether_ntoa
+functions returns values that are stored in static memory areas
+which may be overwritten the next time they are called.
+.Sh HISTORY
+This particular implementation of the
+.Nm ethers
+library functions were written for and first appeared in
+.Fx 2.1 .
diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c
new file mode 100644
index 0000000..bd1f181
--- /dev/null
+++ b/lib/libc/net/gethostbydns.c
@@ -0,0 +1,773 @@
+/*
+ * ++Copyright++ 1985, 1988, 1993
+ * -
+ * Copyright (c) 1985, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
+static char fromrcsid[] = "From: Id: gethnamaddr.c,v 8.23 1998/04/07 04:59:46 vixie Exp $";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#include <syslog.h>
+
+#include "res_config.h"
+
+#define SPRINTF(x) ((size_t)sprintf x)
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+static const char AskedForGot[] =
+ "gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
+
+static char *h_addr_ptrs[MAXADDRS + 1];
+
+static struct hostent host;
+static char *host_aliases[MAXALIASES];
+static char hostbuf[8*1024];
+static u_char host_addr[16]; /* IPv4 or IPv6 */
+
+#ifdef RESOLVSORT
+static void addrsort __P((char **, int));
+#endif
+
+#if PACKETSZ > 1024
+#define MAXPACKET PACKETSZ
+#else
+#define MAXPACKET 1024
+#endif
+
+typedef union {
+ HEADER hdr;
+ u_char buf[MAXPACKET];
+} querybuf;
+
+typedef union {
+ int32_t al;
+ char ac;
+} align;
+
+extern int h_errno;
+int _dns_ttl_;
+
+#ifdef DEBUG
+static void
+dprintf(msg, num)
+ char *msg;
+ int num;
+{
+ if (_res.options & RES_DEBUG) {
+ int save = errno;
+
+ printf(msg, num);
+ errno = save;
+ }
+}
+#else
+# define dprintf(msg, num) /*nada*/
+#endif
+
+#define BOUNDED_INCR(x) \
+ do { \
+ cp += x; \
+ if (cp > eom) { \
+ h_errno = NO_RECOVERY; \
+ return (NULL); \
+ } \
+ } while (0)
+
+#define BOUNDS_CHECK(ptr, count) \
+ do { \
+ if ((ptr) + (count) > eom) { \
+ h_errno = NO_RECOVERY; \
+ return (NULL); \
+ } \
+ } while (0)
+
+static struct hostent *
+gethostanswer(answer, anslen, qname, qtype)
+ const querybuf *answer;
+ int anslen;
+ const char *qname;
+ int qtype;
+{
+ register const HEADER *hp;
+ register const u_char *cp;
+ register int n;
+ const u_char *eom, *erdata;
+ char *bp, **ap, **hap;
+ int type, class, buflen, ancount, qdcount;
+ int haveanswer, had_error;
+ int toobig = 0;
+ char tbuf[MAXDNAME];
+ const char *tname;
+ int (*name_ok) __P((const char *));
+
+ tname = qname;
+ host.h_name = NULL;
+ eom = answer->buf + anslen;
+ switch (qtype) {
+ case T_A:
+ case T_AAAA:
+ name_ok = res_hnok;
+ break;
+ case T_PTR:
+ name_ok = res_dnok;
+ break;
+ default:
+ h_errno = NO_RECOVERY;
+ return (NULL); /* XXX should be abort(); */
+ }
+ /*
+ * find first satisfactory answer
+ */
+ hp = &answer->hdr;
+ ancount = ntohs(hp->ancount);
+ qdcount = ntohs(hp->qdcount);
+ bp = hostbuf;
+ buflen = sizeof hostbuf;
+ cp = answer->buf;
+ BOUNDED_INCR(HFIXEDSZ);
+ if (qdcount != 1) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !(*name_ok)(bp)) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ BOUNDED_INCR(n + QFIXEDSZ);
+ if (qtype == T_A || qtype == T_AAAA) {
+ /* res_send() has already verified that the query name is the
+ * same as the one we sent; this just gets the expanded name
+ * (i.e., with the succeeding search-domain tacked on).
+ */
+ n = strlen(bp) + 1; /* for the \0 */
+ if (n >= MAXHOSTNAMELEN) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ host.h_name = bp;
+ bp += n;
+ buflen -= n;
+ /* The qname can be abbreviated, but h_name is now absolute. */
+ qname = host.h_name;
+ }
+ ap = host_aliases;
+ *ap = NULL;
+ host.h_aliases = host_aliases;
+ hap = h_addr_ptrs;
+ *hap = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ haveanswer = 0;
+ had_error = 0;
+ _dns_ttl_ = -1;
+ while (ancount-- > 0 && cp < eom && !had_error) {
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !(*name_ok)(bp)) {
+ had_error++;
+ continue;
+ }
+ cp += n; /* name */
+ BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
+ type = _getshort(cp);
+ cp += INT16SZ; /* type */
+ class = _getshort(cp);
+ cp += INT16SZ; /* class */
+ if (qtype == T_A && type == T_A)
+ _dns_ttl_ = _getlong(cp);
+ cp += INT32SZ; /* TTL */
+ n = _getshort(cp);
+ cp += INT16SZ; /* len */
+ BOUNDS_CHECK(cp, n);
+ erdata = cp + n;
+ if (class != C_IN) {
+ /* XXX - debug? syslog? */
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
+ if (ap >= &host_aliases[MAXALIASES-1])
+ continue;
+ n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
+ if ((n < 0) || !(*name_ok)(tbuf)) {
+ had_error++;
+ continue;
+ }
+ cp += n;
+ if (cp != erdata) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ /* Store alias. */
+ *ap++ = bp;
+ n = strlen(bp) + 1; /* for the \0 */
+ if (n >= MAXHOSTNAMELEN) {
+ had_error++;
+ continue;
+ }
+ bp += n;
+ buflen -= n;
+ /* Get canonical name. */
+ n = strlen(tbuf) + 1; /* for the \0 */
+ if (n > buflen || n >= MAXHOSTNAMELEN) {
+ had_error++;
+ continue;
+ }
+ strcpy(bp, tbuf);
+ host.h_name = bp;
+ bp += n;
+ buflen -= n;
+ continue;
+ }
+ if (qtype == T_PTR && type == T_CNAME) {
+ n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
+ if (n < 0 || !res_dnok(tbuf)) {
+ had_error++;
+ continue;
+ }
+ cp += n;
+ if (cp != erdata) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ /* Get canonical name. */
+ n = strlen(tbuf) + 1; /* for the \0 */
+ if (n > buflen || n >= MAXHOSTNAMELEN) {
+ had_error++;
+ continue;
+ }
+ strcpy(bp, tbuf);
+ tname = bp;
+ bp += n;
+ buflen -= n;
+ continue;
+ }
+ if (type != qtype) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",
+ qname, p_class(C_IN), p_type(qtype),
+ p_type(type));
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ switch (type) {
+ case T_PTR:
+ if (strcasecmp(tname, bp) != 0) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ AskedForGot, qname, bp);
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !res_hnok(bp)) {
+ had_error++;
+ break;
+ }
+#if MULTI_PTRS_ARE_ALIASES
+ cp += n;
+ if (cp != erdata) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ if (!haveanswer)
+ host.h_name = bp;
+ else if (ap < &host_aliases[MAXALIASES-1])
+ *ap++ = bp;
+ else
+ n = -1;
+ if (n != -1) {
+ n = strlen(bp) + 1; /* for the \0 */
+ if (n >= MAXHOSTNAMELEN) {
+ had_error++;
+ break;
+ }
+ bp += n;
+ buflen -= n;
+ }
+ break;
+#else
+ host.h_name = bp;
+ if (_res.options & RES_USE_INET6) {
+ n = strlen(bp) + 1; /* for the \0 */
+ if (n >= MAXHOSTNAMELEN) {
+ had_error++;
+ break;
+ }
+ bp += n;
+ buflen -= n;
+ _map_v4v6_hostent(&host, &bp, &buflen);
+ }
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+#endif
+ case T_A:
+ case T_AAAA:
+ if (strcasecmp(host.h_name, bp) != 0) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ AskedForGot, host.h_name, bp);
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ if (n != host.h_length) {
+ cp += n;
+ continue;
+ }
+ if (!haveanswer) {
+ register int nn;
+
+ host.h_name = bp;
+ nn = strlen(bp) + 1; /* for the \0 */
+ bp += nn;
+ buflen -= nn;
+ }
+
+ bp += sizeof(align) - ((u_long)bp % sizeof(align));
+
+ if (bp + n >= &hostbuf[sizeof hostbuf]) {
+ dprintf("size (%d) too big\n", n);
+ had_error++;
+ continue;
+ }
+ if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
+ if (!toobig++)
+ dprintf("Too many addresses (%d)\n",
+ MAXADDRS);
+ cp += n;
+ continue;
+ }
+ bcopy(cp, *hap++ = bp, n);
+ bp += n;
+ buflen -= n;
+ cp += n;
+ if (cp != erdata) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ break;
+ default:
+ dprintf("Impossible condition (type=%d)\n", type);
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ /* BIND has abort() here, too risky on bad data */
+ }
+ if (!had_error)
+ haveanswer++;
+ }
+ if (haveanswer) {
+ *ap = NULL;
+ *hap = NULL;
+# if defined(RESOLVSORT)
+ /*
+ * Note: we sort even if host can take only one address
+ * in its return structures - should give it the "best"
+ * address in that case, not some random one
+ */
+ if (_res.nsort && haveanswer > 1 && qtype == T_A)
+ addrsort(h_addr_ptrs, haveanswer);
+# endif /*RESOLVSORT*/
+ if (!host.h_name) {
+ n = strlen(qname) + 1; /* for the \0 */
+ if (n > buflen || n >= MAXHOSTNAMELEN)
+ goto no_recovery;
+ strcpy(bp, qname);
+ host.h_name = bp;
+ bp += n;
+ buflen -= n;
+ }
+ if (_res.options & RES_USE_INET6)
+ _map_v4v6_hostent(&host, &bp, &buflen);
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+ }
+ no_recovery:
+ h_errno = NO_RECOVERY;
+ return (NULL);
+}
+
+struct hostent *
+__dns_getanswer(answer, anslen, qname, qtype)
+ const char *answer;
+ int anslen;
+ const char *qname;
+ int qtype;
+{
+ switch(qtype) {
+ case T_AAAA:
+ host.h_addrtype = AF_INET6;
+ host.h_length = IN6ADDRSZ;
+ break;
+ case T_A:
+ default:
+ host.h_addrtype = AF_INET;
+ host.h_length = INADDRSZ;
+ break;
+ }
+
+ return(gethostanswer((const querybuf *)answer, anslen, qname, qtype));
+}
+
+struct hostent *
+_gethostbydnsname(name, af)
+ const char *name;
+ int af;
+{
+ querybuf buf;
+ register const char *cp;
+ char *bp;
+ int n, size, type, len;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+
+ switch (af) {
+ case AF_INET:
+ size = INADDRSZ;
+ type = T_A;
+ break;
+ case AF_INET6:
+ size = IN6ADDRSZ;
+ type = T_AAAA;
+ break;
+ default:
+ h_errno = NETDB_INTERNAL;
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+
+ host.h_addrtype = af;
+ host.h_length = size;
+
+ /*
+ * if there aren't any dots, it could be a user-level alias.
+ * this is also done in res_query() since we are not the only
+ * function that looks up host names.
+ */
+ if (!strchr(name, '.') && (cp = __hostalias(name)))
+ name = cp;
+
+ /*
+ * disallow names consisting only of digits/dots, unless
+ * they end in a dot.
+ */
+ if (isdigit((unsigned char)name[0]))
+ for (cp = name;; ++cp) {
+ if (!*cp) {
+ if (*--cp == '.')
+ break;
+ /*
+ * All-numeric, no dot at the end.
+ * Fake up a hostent as if we'd actually
+ * done a lookup.
+ */
+ if (inet_pton(af, name, host_addr) <= 0) {
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ strncpy(hostbuf, name, MAXDNAME);
+ hostbuf[MAXDNAME] = '\0';
+ bp = hostbuf + MAXDNAME;
+ len = sizeof hostbuf - MAXDNAME;
+ host.h_name = hostbuf;
+ host.h_aliases = host_aliases;
+ host_aliases[0] = NULL;
+ h_addr_ptrs[0] = (char *)host_addr;
+ h_addr_ptrs[1] = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ if (_res.options & RES_USE_INET6)
+ _map_v4v6_hostent(&host, &bp, &len);
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+ }
+ if (!isdigit((unsigned char)*cp) && *cp != '.')
+ break;
+ }
+ if ((isxdigit((unsigned char)name[0]) && strchr(name, ':') != NULL) ||
+ name[0] == ':')
+ for (cp = name;; ++cp) {
+ if (!*cp) {
+ if (*--cp == '.')
+ break;
+ /*
+ * All-IPv6-legal, no dot at the end.
+ * Fake up a hostent as if we'd actually
+ * done a lookup.
+ */
+ if (inet_pton(af, name, host_addr) <= 0) {
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ strncpy(hostbuf, name, MAXDNAME);
+ hostbuf[MAXDNAME] = '\0';
+ bp = hostbuf + MAXDNAME;
+ len = sizeof hostbuf - MAXDNAME;
+ host.h_name = hostbuf;
+ host.h_aliases = host_aliases;
+ host_aliases[0] = NULL;
+ h_addr_ptrs[0] = (char *)host_addr;
+ h_addr_ptrs[1] = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+ }
+ if (!isxdigit((unsigned char)*cp) && *cp != ':' && *cp != '.')
+ break;
+ }
+
+ if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) {
+ dprintf("res_search failed (%d)\n", n);
+ return (NULL);
+ }
+ return (gethostanswer(&buf, n, name, type));
+}
+
+struct hostent *
+_gethostbydnsaddr(addr, len, af)
+ const char *addr; /* XXX should have been def'd as u_char! */
+ int len, af;
+{
+ const u_char *uaddr = (const u_char *)addr;
+ static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
+ static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
+ int n, size;
+ querybuf buf;
+ register struct hostent *hp;
+ char qbuf[MAXDNAME+1], *qp;
+#ifdef SUNSECURITY
+ register struct hostent *rhp;
+ char **haddr;
+ u_long old_options;
+ char hname2[MAXDNAME+1];
+#endif /*SUNSECURITY*/
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ if (af == AF_INET6 && len == IN6ADDRSZ &&
+ (!bcmp(uaddr, mapped, sizeof mapped) ||
+ !bcmp(uaddr, tunnelled, sizeof tunnelled))) {
+ /* Unmap. */
+ addr += sizeof mapped;
+ uaddr += sizeof mapped;
+ af = AF_INET;
+ len = INADDRSZ;
+ }
+ switch (af) {
+ case AF_INET:
+ size = INADDRSZ;
+ break;
+ case AF_INET6:
+ size = IN6ADDRSZ;
+ break;
+ default:
+ errno = EAFNOSUPPORT;
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ if (size != len) {
+ errno = EINVAL;
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ switch (af) {
+ case AF_INET:
+ (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
+ (uaddr[3] & 0xff),
+ (uaddr[2] & 0xff),
+ (uaddr[1] & 0xff),
+ (uaddr[0] & 0xff));
+ break;
+ case AF_INET6:
+ qp = qbuf;
+ for (n = IN6ADDRSZ - 1; n >= 0; n--) {
+ qp += SPRINTF((qp, "%x.%x.",
+ uaddr[n] & 0xf,
+ (uaddr[n] >> 4) & 0xf));
+ }
+ strcpy(qp, "ip6.int");
+ break;
+ default:
+ abort();
+ }
+ n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
+ if (n < 0) {
+ dprintf("res_query failed (%d)\n", n);
+ return (NULL);
+ }
+ if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR)))
+ return (NULL); /* h_errno was set by gethostanswer() */
+#ifdef SUNSECURITY
+ if (af == AF_INET) {
+ /*
+ * turn off search as the name should be absolute,
+ * 'localhost' should be matched by defnames
+ */
+ strncpy(hname2, hp->h_name, MAXDNAME);
+ hname2[MAXDNAME] = '\0';
+ old_options = _res.options;
+ _res.options &= ~RES_DNSRCH;
+ _res.options |= RES_DEFNAMES;
+ if (!(rhp = gethostbyname(hname2))) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostbyaddr: No A record for %s (verifying [%s])",
+ hname2, inet_ntoa(*((struct in_addr *)addr)));
+ _res.options = old_options;
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ _res.options = old_options;
+ for (haddr = rhp->h_addr_list; *haddr; haddr++)
+ if (!memcmp(*haddr, addr, INADDRSZ))
+ break;
+ if (!*haddr) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostbyaddr: A record of %s != PTR record [%s]",
+ hname2, inet_ntoa(*((struct in_addr *)addr)));
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ }
+#endif /*SUNSECURITY*/
+ hp->h_addrtype = af;
+ hp->h_length = len;
+ bcopy(addr, host_addr, len);
+ h_addr_ptrs[0] = (char *)host_addr;
+ h_addr_ptrs[1] = NULL;
+ if (af == AF_INET && (_res.options & RES_USE_INET6)) {
+ _map_v4v6_address((char*)host_addr, (char*)host_addr);
+ hp->h_addrtype = AF_INET6;
+ hp->h_length = IN6ADDRSZ;
+ }
+ h_errno = NETDB_SUCCESS;
+ return (hp);
+}
+
+#ifdef RESOLVSORT
+static void
+addrsort(ap, num)
+ char **ap;
+ int num;
+{
+ int i, j;
+ char **p;
+ short aval[MAXADDRS];
+ int needsort = 0;
+
+ p = ap;
+ for (i = 0; i < num; i++, p++) {
+ for (j = 0 ; (unsigned)j < _res.nsort; j++)
+ if (_res.sort_list[j].addr.s_addr ==
+ (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
+ break;
+ aval[i] = j;
+ if (needsort == 0 && i > 0 && j < aval[i-1])
+ needsort = i;
+ }
+ if (!needsort)
+ return;
+
+ while (needsort < num) {
+ for (j = needsort - 1; j >= 0; j--) {
+ if (aval[j] > aval[j+1]) {
+ char *hp;
+
+ i = aval[j];
+ aval[j] = aval[j+1];
+ aval[j+1] = i;
+
+ hp = ap[j];
+ ap[j] = ap[j+1];
+ ap[j+1] = hp;
+
+ } else
+ break;
+ }
+ needsort++;
+ }
+}
+#endif
+void
+_sethostdnsent(stayopen)
+ int stayopen;
+{
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return;
+ if (stayopen)
+ _res.options |= RES_STAYOPEN | RES_USEVC;
+}
+
+void
+_endhostdnsent()
+{
+ _res.options &= ~(RES_STAYOPEN | RES_USEVC);
+ res_close();
+}
diff --git a/lib/libc/net/gethostbyht.c b/lib/libc/net/gethostbyht.c
new file mode 100644
index 0000000..cd5f0f4
--- /dev/null
+++ b/lib/libc/net/gethostbyht.c
@@ -0,0 +1,202 @@
+/*-
+ * Copyright (c) 1985, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <arpa/nameser.h> /* XXX */
+#include <resolv.h> /* XXX */
+
+#define MAXALIASES 35
+
+static struct hostent host;
+static char *host_aliases[MAXALIASES];
+static char hostbuf[BUFSIZ+1];
+static FILE *hostf = NULL;
+static u_int32_t host_addr[4]; /* IPv4 or IPv6 */
+static char *h_addr_ptrs[2];
+static int stayopen = 0;
+
+void
+_sethosthtent(f)
+ int f;
+{
+ if (!hostf)
+ hostf = fopen(_PATH_HOSTS, "r" );
+ else
+ rewind(hostf);
+ stayopen = f;
+}
+
+void
+_endhosthtent()
+{
+ if (hostf && !stayopen) {
+ (void) fclose(hostf);
+ hostf = NULL;
+ }
+}
+
+struct hostent *
+gethostent()
+{
+ char *p;
+ register char *cp, **q;
+ int af, len;
+
+ if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ again:
+ if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) {
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ if (*p == '#')
+ goto again;
+ if (!(cp = strpbrk(p, "#\n")))
+ goto again;
+ *cp = '\0';
+ if (!(cp = strpbrk(p, " \t")))
+ goto again;
+ *cp++ = '\0';
+ if (inet_pton(AF_INET6, p, host_addr) > 0) {
+ af = AF_INET6;
+ len = IN6ADDRSZ;
+ } else if (inet_pton(AF_INET, p, host_addr) > 0) {
+ if (_res.options & RES_USE_INET6) {
+ _map_v4v6_address((char*)host_addr, (char*)host_addr);
+ af = AF_INET6;
+ len = IN6ADDRSZ;
+ } else {
+ af = AF_INET;
+ len = INADDRSZ;
+ }
+ } else {
+ goto again;
+ }
+ h_addr_ptrs[0] = (char *)host_addr;
+ h_addr_ptrs[1] = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ host.h_length = len;
+ host.h_addrtype = af;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ host.h_name = cp;
+ q = host.h_aliases = host_aliases;
+ if ((cp = strpbrk(cp, " \t")) != NULL)
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &host_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ if ((cp = strpbrk(cp, " \t")) != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+}
+
+struct hostent *
+_gethostbyhtname(name, af)
+ const char *name;
+ int af;
+{
+ register struct hostent *p;
+ register char **cp;
+
+ sethostent(0);
+ while ((p = gethostent()) != NULL) {
+ if (p->h_addrtype != af)
+ continue;
+ if (strcasecmp(p->h_name, name) == 0)
+ break;
+ for (cp = p->h_aliases; *cp != 0; cp++)
+ if (strcasecmp(*cp, name) == 0)
+ goto found;
+ }
+found:
+ endhostent();
+ return (p);
+}
+
+struct hostent *
+_gethostbyhtaddr(addr, len, af)
+ const char *addr;
+ int len, af;
+{
+ register struct hostent *p;
+
+ sethostent(0);
+ while ((p = gethostent()) != NULL)
+ if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
+ break;
+ endhostent();
+ return (p);
+}
diff --git a/lib/libc/net/gethostbyname.3 b/lib/libc/net/gethostbyname.3
new file mode 100644
index 0000000..1b48c4a
--- /dev/null
+++ b/lib/libc/net/gethostbyname.3
@@ -0,0 +1,305 @@
+.\" Copyright (c) 1983, 1987, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
+.\" $FreeBSD$
+.\"
+.Dd May 25, 1995
+.Dt GETHOSTBYNAME 3
+.Os BSD 4.2
+.Sh NAME
+.Nm gethostbyname ,
+.Nm gethostbyname2 ,
+.Nm gethostbyaddr ,
+.Nm gethostent ,
+.Nm sethostent ,
+.Nm endhostent ,
+.Nm herror ,
+.Nm hstrerror
+.Nd get network host entry
+.Sh SYNOPSIS
+.Fd #include <netdb.h>
+.Vt extern int h_errno;
+.Ft struct hostent *
+.Fn gethostbyname "const char *name"
+.Ft struct hostent *
+.Fn gethostbyname2 "const char *name" "int af"
+.Ft struct hostent *
+.Fn gethostbyaddr "const char *addr" "int len" "int type"
+.Ft struct hostent *
+.Fn gethostent void
+.Ft void
+.Fn sethostent "int stayopen"
+.Ft void
+.Fn endhostent void
+.Ft void
+.Fn herror "const char *string"
+.Ft const char *
+.Fn hstrerror "int err"
+.Sh DESCRIPTION
+The
+.Fn gethostbyname ,
+.Fn gethostbyname2
+and
+.Fn gethostbyaddr
+functions
+each return a pointer to an object with the
+following structure describing an internet host
+referenced by name or by address, respectively.
+This structure contains either the information obtained from the name server,
+.Xr named 8 ,
+or broken-out fields from a line in
+.Pa /etc/hosts .
+If the local name server is not running these routines do a lookup in
+.Pa /etc/hosts .
+.Bd -literal
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+.Ed
+.Pp
+The members of this structure are:
+.Bl -tag -width h_addr_list
+.It Fa h_name
+Official name of the host.
+.It Fa h_aliases
+A NULL-terminated array of alternate names for the host.
+.It Fa h_addrtype
+The type of address being returned; usually
+.Dv AF_INET .
+.It Fa h_length
+The length, in bytes, of the address.
+.It Fa h_addr_list
+A NULL-terminated array of network addresses for the host.
+Host addresses are returned in network byte order.
+.It Fa h_addr
+The first address in
+.Fa h_addr_list ;
+this is for backward compatibility.
+.El
+.Pp
+When using the nameserver,
+.Fn gethostbyname
+and
+.Fn gethostbyname2
+will search for the named host in the current domain and its parents
+unless the name ends in a dot.
+If the name contains no dot, and if the environment variable
+.Dq Ev HOSTALIASES
+contains the name of an alias file, the alias file will first be searched
+for an alias matching the input name.
+See
+.Xr hostname 7
+for the domain search procedure and the alias file format.
+.Pp
+The
+.Fn gethostbyname2
+function is an evolution of
+.Fn gethostbyname
+which is intended to allow lookups in address families other than
+.Dv AF_INET ,
+for example
+.Dv AF_INET6 .
+Currently the
+.Fa af
+argument must be specified as
+.Dv AF_INET
+else the function will return
+.Dv NULL
+after having set
+.Va h_errno
+to
+.Dv NETDB_INTERNAL
+.Pp
+The
+.Fn sethostent
+function
+may be used to request the use of a connected
+.Tn TCP
+socket for queries.
+If the
+.Fa stayopen
+flag is non-zero,
+this sets the option to send all queries to the name server using
+.Tn TCP
+and to retain the connection after each call to
+.Fn gethostbyname ,
+.Fn gethostbyname2
+or
+.Fn gethostbyaddr .
+Otherwise, queries are performed using
+.Tn UDP
+datagrams.
+.Pp
+The
+.Fn endhostent
+function
+closes the
+.Tn TCP
+connection.
+.Pp
+The
+.Fn herror
+function writes a message to the diagnostic output consisting of the
+string parameter
+.Fa s ,
+the constant string ": ", and a message corresponding to the value of
+.Va h_errno .
+.Pp
+The
+.Fn hstrerror
+function returns a string which is the message text corresponding to the
+value of the
+.Fa err
+parameter.
+.Sh FILES
+.Bl -tag -width /etc/resolv.conf -compact
+.It Pa /etc/hosts
+.It Pa /etc/host.conf
+.It Pa /etc/resolv.conf
+.El
+.Sh DIAGNOSTICS
+Error return status from
+.Fn gethostbyname ,
+.Fn gethostbyname2
+and
+.Fn gethostbyaddr
+is indicated by return of a null pointer.
+The external integer
+.Va h_errno
+may then be checked to see whether this is a temporary failure
+or an invalid or unknown host.
+The routine
+.Fn herror
+can be used to print an error message describing the failure.
+If its argument
+.Fa string
+is
+.Pf non Dv -NULL ,
+it is printed, followed by a colon and a space.
+The error message is printed with a trailing newline.
+.Pp
+The variable
+.Va h_errno
+can have the following values:
+.Bl -tag -width HOST_NOT_FOUND
+.It Dv HOST_NOT_FOUND
+No such host is known.
+.It Dv TRY_AGAIN
+This is usually a temporary error
+and means that the local server did not receive
+a response from an authoritative server.
+A retry at some later time may succeed.
+.It Dv NO_RECOVERY
+Some unexpected server failure was encountered.
+This is a non-recoverable error.
+.It Dv NO_DATA
+The requested name is valid but does not have an IP address;
+this is not a temporary error.
+This means that the name is known to the name server but there is no address
+associated with this name.
+Another type of request to the name server using this domain name
+will result in an answer;
+for example, a mail-forwarder may be registered for this domain.
+.El
+.Sh SEE ALSO
+.Xr resolver 3 ,
+.Xr hosts 5 ,
+.Xr hostname 7 ,
+.Xr named 8
+.Sh CAVEAT
+The
+.Fn gethostent
+function
+is defined, and
+.Fn sethostent
+and
+.Fn endhostent
+are redefined,
+when
+.Xr libc 3
+is built to use only the routines to lookup in
+.Pa /etc/hosts
+and not the name server.
+.Pp
+The
+.Fn gethostent
+function
+reads the next line of
+.Pa /etc/hosts ,
+opening the file if necessary.
+.Pp
+The
+.Fn sethostent
+function
+opens and/or rewinds the file
+.Pa /etc/hosts .
+If the
+.Fa stayopen
+argument is non-zero,
+the file will not be closed after each call to
+.Fn gethostbyname ,
+.Fn gethostbyname2
+or
+.Fn gethostbyaddr .
+.Pp
+The
+.Fn endhostent
+function
+closes the file.
+.Sh HISTORY
+The
+.Fn herror
+function appeared in
+.Bx 4.3 .
+The
+.Fn endhostent ,
+.Fn gethostbyaddr ,
+.Fn gethostbyname ,
+.Fn gethostent ,
+and
+.Fn sethostent
+functions appeared in
+.Bx 4.2 .
+The
+.Fn gethostbyname2
+function first appeared in bind-4.9.4.
+.Sh BUGS
+These functions use static data storage;
+if the data is needed for future use, it should be
+copied before any subsequent calls overwrite it.
+Only the Internet
+address format is currently understood.
diff --git a/lib/libc/net/gethostbynis.c b/lib/libc/net/gethostbynis.c
new file mode 100644
index 0000000..82e0b3d
--- /dev/null
+++ b/lib/libc/net/gethostbynis.c
@@ -0,0 +1,145 @@
+/*-
+ * Copyright (c) 1994, Garrett Wollman
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)$FreeBSD$";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+#ifdef YP
+static char *host_aliases[MAXALIASES];
+static char hostaddr[MAXADDRS];
+static char *host_addrs[2];
+#endif /* YP */
+
+static struct hostent *
+_gethostbynis(name, map, af)
+ const char *name;
+ char *map;
+ int af;
+{
+#ifdef YP
+ register char *cp, **q;
+ char *result;
+ int resultlen,size;
+ static struct hostent h;
+ static char *domain = (char *)NULL;
+ static char ypbuf[YPMAXRECORD + 2];
+
+ switch(af) {
+ case AF_INET:
+ size = NS_INADDRSZ;
+ break;
+ default:
+ case AF_INET6:
+ size = NS_IN6ADDRSZ;
+ errno = EAFNOSUPPORT;
+ return NULL;
+ }
+
+ if (domain == (char *)NULL)
+ if (yp_get_default_domain (&domain))
+ return ((struct hostent *)NULL);
+
+ if (yp_match(domain, map, name, strlen(name), &result, &resultlen))
+ return ((struct hostent *)NULL);
+
+ /* avoid potential memory leak */
+ bcopy((char *)result, (char *)&ypbuf, resultlen);
+ ypbuf[resultlen] = '\0';
+ free(result);
+ result = (char *)&ypbuf;
+
+ if ((cp = index(result, '\n')))
+ *cp = '\0';
+
+ cp = strpbrk(result, " \t");
+ *cp++ = '\0';
+ h.h_addr_list = host_addrs;
+ h.h_addr = hostaddr;
+ *((u_long *)h.h_addr) = inet_addr(result);
+ h.h_length = size;
+ h.h_addrtype = AF_INET;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ h.h_name = cp;
+ q = h.h_aliases = host_aliases;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &host_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ return (&h);
+#else
+ return (NULL);
+#endif /* YP */
+}
+
+struct hostent *
+_gethostbynisname(name, af)
+ const char *name;
+ int af;
+{
+ return _gethostbynis(name, "hosts.byname", af);
+}
+
+struct hostent *
+_gethostbynisaddr(addr, len, af)
+ const char *addr;
+ int len;
+ int af;
+{
+ return _gethostbynis(inet_ntoa(*(struct in_addr *)addr),"hosts.byaddr", af);
+}
diff --git a/lib/libc/net/gethostnamadr.c b/lib/libc/net/gethostnamadr.c
new file mode 100644
index 0000000..010e4db
--- /dev/null
+++ b/lib/libc/net/gethostnamadr.c
@@ -0,0 +1,224 @@
+/*-
+ * Copyright (c) 1994, Garrett Wollman
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)$FreeBSD$";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <arpa/nameser.h> /* XXX hack for _res */
+#include <resolv.h> /* XXX hack for _res */
+
+#define _PATH_HOSTCONF "/etc/host.conf"
+
+enum service_type {
+ SERVICE_NONE = 0,
+ SERVICE_BIND,
+ SERVICE_HOSTS,
+ SERVICE_NIS };
+#define SERVICE_MAX SERVICE_NIS
+
+static struct {
+ const char *name;
+ enum service_type type;
+} service_names[] = {
+ { "hosts", SERVICE_HOSTS },
+ { "/etc/hosts", SERVICE_HOSTS },
+ { "hosttable", SERVICE_HOSTS },
+ { "htable", SERVICE_HOSTS },
+ { "bind", SERVICE_BIND },
+ { "dns", SERVICE_BIND },
+ { "domain", SERVICE_BIND },
+ { "yp", SERVICE_NIS },
+ { "yellowpages", SERVICE_NIS },
+ { "nis", SERVICE_NIS },
+ { 0, SERVICE_NONE }
+};
+
+static enum service_type service_order[SERVICE_MAX + 1];
+static int service_done = 0;
+
+static enum service_type
+get_service_name(const char *name) {
+ int i;
+ for(i = 0; service_names[i].type != SERVICE_NONE; i++) {
+ if(!strcasecmp(name, service_names[i].name)) {
+ return service_names[i].type;
+ }
+ }
+ return SERVICE_NONE;
+}
+
+static void
+init_services()
+{
+ char *cp, *p, buf[BUFSIZ];
+ register int cc = 0;
+ FILE *fd;
+
+ if ((fd = (FILE *)fopen(_PATH_HOSTCONF, "r")) == NULL) {
+ /* make some assumptions */
+ service_order[0] = SERVICE_BIND;
+ service_order[1] = SERVICE_HOSTS;
+ service_order[2] = SERVICE_NONE;
+ } else {
+ while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {
+ if(buf[0] == '#')
+ continue;
+
+ p = buf;
+ while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
+ ;
+ if (cp == NULL)
+ continue;
+ do {
+ if (isalpha((unsigned char)cp[0])) {
+ service_order[cc] = get_service_name(cp);
+ if(service_order[cc] != SERVICE_NONE)
+ cc++;
+ }
+ while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
+ ;
+ } while(cp != NULL && cc < SERVICE_MAX);
+ }
+ service_order[cc] = SERVICE_NONE;
+ fclose(fd);
+ }
+ service_done = 1;
+}
+
+struct hostent *
+gethostbyname(const char *name)
+{
+ struct hostent *hp;
+
+ if (_res.options & RES_USE_INET6) { /* XXX */
+ hp = gethostbyname2(name, AF_INET6); /* XXX */
+ if (hp) /* XXX */
+ return (hp); /* XXX */
+ } /* XXX */
+ return (gethostbyname2(name, AF_INET));
+}
+
+struct hostent *
+gethostbyname2(const char *name, int type)
+{
+ struct hostent *hp = 0;
+ int nserv = 0;
+
+ if (!service_done)
+ init_services();
+
+ while (!hp) {
+ switch (service_order[nserv]) {
+ case SERVICE_NONE:
+ return NULL;
+ case SERVICE_HOSTS:
+ hp = _gethostbyhtname(name, type);
+ break;
+ case SERVICE_BIND:
+ hp = _gethostbydnsname(name, type);
+ break;
+ case SERVICE_NIS:
+ hp = _gethostbynisname(name, type);
+ break;
+ }
+ nserv++;
+ }
+ return hp;
+}
+
+struct hostent *
+gethostbyaddr(const char *addr, int len, int type)
+{
+ struct hostent *hp = 0;
+ int nserv = 0;
+
+ if (!service_done)
+ init_services();
+
+ while (!hp) {
+ switch (service_order[nserv]) {
+ case SERVICE_NONE:
+ return 0;
+ case SERVICE_HOSTS:
+ hp = _gethostbyhtaddr(addr, len, type);
+ break;
+ case SERVICE_BIND:
+ hp = _gethostbydnsaddr(addr, len, type);
+ break;
+ case SERVICE_NIS:
+ hp = _gethostbynisaddr(addr, len, type);
+ break;
+ }
+ nserv++;
+ }
+ return hp;
+}
+
+#ifdef _THREAD_SAFE
+struct hostent_data;
+
+/*
+ * Temporary function (not thread safe)
+ */
+int gethostbyaddr_r(const char *addr, int len, int type,
+ struct hostent *result, struct hostent_data *buffer)
+{
+ struct hostent *hp;
+ int ret;
+ if ((hp = gethostbyaddr(addr, len, type)) == NULL) {
+ ret = -1;
+ } else {
+ memcpy(result, hp, sizeof(struct hostent));
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
+
+void
+sethostent(stayopen)
+ int stayopen;
+{
+ _sethosthtent(stayopen);
+ _sethostdnsent(stayopen);
+}
+
+void
+endhostent()
+{
+ _endhosthtent();
+ _endhostdnsent();
+}
diff --git a/lib/libc/net/getnetbydns.c b/lib/libc/net/getnetbydns.c
new file mode 100644
index 0000000..65d9d2d
--- /dev/null
+++ b/lib/libc/net/getnetbydns.c
@@ -0,0 +1,313 @@
+/*-
+ * Copyright (c) 1985, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
+ * Dep. Matematica Universidade de Coimbra, Portugal, Europe
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <syslog.h>
+
+#include "res_config.h"
+
+extern int h_errno;
+
+#define BYADDR 0
+#define BYNAME 1
+#define MAXALIASES 35
+
+#if PACKETSZ > 1024
+#define MAXPACKET PACKETSZ
+#else
+#define MAXPACKET 1024
+#endif
+
+typedef union {
+ HEADER hdr;
+ u_char buf[MAXPACKET];
+} querybuf;
+
+typedef union {
+ long al;
+ char ac;
+} align;
+
+static struct netent *
+getnetanswer(answer, anslen, net_i)
+ querybuf *answer;
+ int anslen;
+ int net_i;
+{
+
+ register HEADER *hp;
+ register u_char *cp;
+ register int n;
+ u_char *eom;
+ int type, class, buflen, ancount, qdcount, haveanswer, i, nchar;
+ char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN];
+ char *in, *st, *pauxt, *bp, **ap;
+ char *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
+static struct netent net_entry;
+static char *net_aliases[MAXALIASES], netbuf[PACKETSZ];
+
+ /*
+ * find first satisfactory answer
+ *
+ * answer --> +------------+ ( MESSAGE )
+ * | Header |
+ * +------------+
+ * | Question | the question for the name server
+ * +------------+
+ * | Answer | RRs answering the question
+ * +------------+
+ * | Authority | RRs pointing toward an authority
+ * | Additional | RRs holding additional information
+ * +------------+
+ */
+ eom = answer->buf + anslen;
+ hp = &answer->hdr;
+ ancount = ntohs(hp->ancount); /* #/records in the answer section */
+ qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
+ bp = netbuf;
+ buflen = sizeof(netbuf);
+ cp = answer->buf + HFIXEDSZ;
+ if (!qdcount) {
+ if (hp->aa)
+ h_errno = HOST_NOT_FOUND;
+ else
+ h_errno = TRY_AGAIN;
+ return (NULL);
+ }
+ while (qdcount-- > 0)
+ cp += __dn_skipname(cp, eom) + QFIXEDSZ;
+ ap = net_aliases;
+ *ap = NULL;
+ net_entry.n_aliases = net_aliases;
+ haveanswer = 0;
+ while (--ancount >= 0 && cp < eom) {
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !res_dnok(bp))
+ break;
+ cp += n;
+ ans[0] = '\0';
+ (void)strncpy(&ans[0], bp, sizeof(ans) - 1);
+ ans[sizeof(ans) - 1] = '\0';
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ cp += INT32SZ; /* TTL */
+ GETSHORT(n, cp);
+ if (class == C_IN && type == T_PTR) {
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !res_hnok(bp)) {
+ cp += n;
+ return (NULL);
+ }
+ cp += n;
+ *ap++ = bp;
+ bp += strlen(bp) + 1;
+ net_entry.n_addrtype =
+ (class == C_IN) ? AF_INET : AF_UNSPEC;
+ haveanswer++;
+ }
+ }
+ if (haveanswer) {
+ *ap = NULL;
+ switch (net_i) {
+ case BYADDR:
+ net_entry.n_name = *net_entry.n_aliases;
+ net_entry.n_net = 0L;
+ break;
+ case BYNAME:
+ in = *net_entry.n_aliases;
+ net_entry.n_name = &ans[0];
+ aux2[0] = '\0';
+ for (i = 0; i < 4; i++) {
+ for (st = in, nchar = 0;
+ *st != '.';
+ st++, nchar++)
+ ;
+ if (nchar != 1 || *in != '0' || flag) {
+ flag = 1;
+ (void)strncpy(paux1,
+ (i==0) ? in : in-1,
+ (i==0) ?nchar : nchar+1);
+ paux1[(i==0) ? nchar : nchar+1] = '\0';
+ pauxt = paux2;
+ paux2 = strcat(paux1, paux2);
+ paux1 = pauxt;
+ }
+ in = ++st;
+ }
+ net_entry.n_net = inet_network(paux2);
+ break;
+ }
+ net_entry.n_aliases++;
+ return (&net_entry);
+ }
+ h_errno = TRY_AGAIN;
+ return (NULL);
+}
+
+struct netent *
+_getnetbydnsaddr(net, net_type)
+ register unsigned long net;
+ register int net_type;
+{
+ unsigned int netbr[4];
+ int nn, anslen;
+ querybuf buf;
+ char qbuf[MAXDNAME];
+ unsigned long net2;
+ struct netent *net_entry;
+
+ if (net_type != AF_INET)
+ return (NULL);
+
+ for (nn = 4, net2 = net; net2; net2 >>= 8)
+ netbr[--nn] = net2 & 0xff;
+ switch (nn) {
+ case 3: /* Class A */
+ sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]);
+ break;
+ case 2: /* Class B */
+ sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]);
+ break;
+ case 1: /* Class C */
+ sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
+ netbr[1]);
+ break;
+ case 0: /* Class D - E */
+ sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
+ netbr[1], netbr[0]);
+ break;
+ }
+ anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
+ if (anslen < 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf("res_query failed\n");
+#endif
+ return (NULL);
+ }
+ net_entry = getnetanswer(&buf, anslen, BYADDR);
+ if (net_entry) {
+ unsigned u_net = net; /* maybe net should be unsigned ? */
+
+ /* Strip trailing zeros */
+ while ((u_net & 0xff) == 0 && u_net != 0)
+ u_net >>= 8;
+ net_entry->n_net = u_net;
+ return (net_entry);
+ }
+ return (NULL);
+}
+
+struct netent *
+_getnetbydnsname(net)
+ register const char *net;
+{
+ int anslen;
+ querybuf buf;
+ char qbuf[MAXDNAME];
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ strncpy(qbuf, net, sizeof(qbuf) - 1);
+ qbuf[sizeof(qbuf) - 1] = '\0';
+ anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
+ if (anslen < 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf("res_query failed\n");
+#endif
+ return (NULL);
+ }
+ return getnetanswer(&buf, anslen, BYNAME);
+}
+
+void
+_setnetdnsent(stayopen)
+ int stayopen;
+{
+ if (stayopen)
+ _res.options |= RES_STAYOPEN | RES_USEVC;
+}
+
+void
+_endnetdnsent()
+{
+ _res.options &= ~(RES_STAYOPEN | RES_USEVC);
+ res_close();
+}
diff --git a/lib/libc/net/getnetbyht.c b/lib/libc/net/getnetbyht.c
new file mode 100644
index 0000000..ab164b1
--- /dev/null
+++ b/lib/libc/net/getnetbyht.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
+ * Dep. Matematica Universidade de Coimbra, Portugal, Europe
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * from getnetent.c 1.1 (Coimbra) 93/06/02
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93";
+static char orig_rcsid[] = "From: Id: getnetent.c,v 8.4 1997/06/01 20:34:37 vixie Exp";
+static chat rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+
+#define MAXALIASES 35
+
+static FILE *netf;
+static char line[BUFSIZ+1];
+static struct netent net;
+static char *net_aliases[MAXALIASES];
+static int _net_stayopen;
+
+void
+_setnethtent(f)
+ int f;
+{
+
+ if (netf == NULL)
+ netf = fopen(_PATH_NETWORKS, "r" );
+ else
+ rewind(netf);
+ _net_stayopen |= f;
+}
+
+void
+_endnethtent()
+{
+
+ if (netf) {
+ fclose(netf);
+ netf = NULL;
+ }
+ _net_stayopen = 0;
+}
+
+struct netent *
+getnetent()
+{
+ char *p;
+ register char *cp, **q;
+
+ if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL)
+ return (NULL);
+again:
+ p = fgets(line, sizeof line, netf);
+ if (p == NULL)
+ return (NULL);
+ if (*p == '#')
+ goto again;
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ goto again;
+ *cp = '\0';
+ net.n_name = p;
+ cp = strpbrk(p, " \t");
+ if (cp == NULL)
+ goto again;
+ *cp++ = '\0';
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ p = strpbrk(cp, " \t");
+ if (p != NULL)
+ *p++ = '\0';
+ net.n_net = inet_network(cp);
+ net.n_addrtype = AF_INET;
+ q = net.n_aliases = net_aliases;
+ if (p != NULL)
+ cp = p;
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &net_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ return (&net);
+}
+
+struct netent *
+_getnetbyhtname(name)
+ register const char *name;
+{
+ register struct netent *p;
+ register char **cp;
+
+ setnetent(_net_stayopen);
+ while ( (p = getnetent()) ) {
+ if (strcasecmp(p->n_name, name) == 0)
+ break;
+ for (cp = p->n_aliases; *cp != 0; cp++)
+ if (strcasecmp(*cp, name) == 0)
+ goto found;
+ }
+found:
+ if (!_net_stayopen)
+ endnetent();
+ return (p);
+}
+
+struct netent *
+_getnetbyhtaddr(net, type)
+ register unsigned long net;
+ register int type;
+{
+ register struct netent *p;
+
+ setnetent(_net_stayopen);
+ while ( (p = getnetent()) )
+ if (p->n_addrtype == type && p->n_net == net)
+ break;
+ if (!_net_stayopen)
+ endnetent();
+ return (p);
+}
diff --git a/lib/libc/net/getnetbynis.c b/lib/libc/net/getnetbynis.c
new file mode 100644
index 0000000..0ab7073
--- /dev/null
+++ b/lib/libc/net/getnetbynis.c
@@ -0,0 +1,177 @@
+/*-
+ * Copyright (c) 1994, Garrett Wollman
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)$FreeBSD$";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <arpa/nameser.h>
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+#ifdef YP
+static char *host_aliases[MAXALIASES];
+#endif /* YP */
+
+static struct netent *
+_getnetbynis(name, map, af)
+ const char *name;
+ char *map;
+ int af;
+{
+#ifdef YP
+ register char *cp, **q;
+ static char *result;
+ int resultlen;
+ static struct netent h;
+ static char *domain = (char *)NULL;
+ static char ypbuf[YPMAXRECORD + 2];
+
+ switch(af) {
+ case AF_INET:
+ break;
+ default:
+ case AF_INET6:
+ errno = EAFNOSUPPORT;
+ return NULL;
+ }
+
+ if (domain == (char *)NULL)
+ if (yp_get_default_domain (&domain))
+ return (NULL);
+
+ if (yp_match(domain, map, name, strlen(name), &result, &resultlen))
+ return (NULL);
+
+ bcopy((char *)result, (char *)&ypbuf, resultlen);
+ ypbuf[resultlen] = '\0';
+ free(result);
+ result = (char *)&ypbuf;
+
+ if ((cp = index(result, '\n')))
+ *cp = '\0';
+
+ cp = strpbrk(result, " \t");
+ *cp++ = '\0';
+ h.n_name = result;
+
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+
+ h.n_net = inet_network(cp);
+ h.n_addrtype = AF_INET;
+
+ q = h.n_aliases = host_aliases;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &host_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ return (&h);
+#else
+ return (NULL);
+#endif
+}
+
+struct netent *
+_getnetbynisname(name)
+ const char *name;
+{
+ return _getnetbynis(name, "networks.byname", AF_INET);
+}
+
+struct netent *
+_getnetbynisaddr(addr, af)
+ unsigned long addr;
+ int af;
+{
+ char *str, *cp;
+ unsigned long net2;
+ int nn;
+ unsigned int netbr[4];
+ char buf[MAXDNAME];
+
+ if (af != AF_INET) {
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+
+ for (nn = 4, net2 = addr; net2; net2 >>= 8) {
+ netbr[--nn] = net2 & 0xff;
+ }
+
+ switch (nn) {
+ case 3: /* Class A */
+ sprintf(buf, "%u", netbr[3]);
+ break;
+ case 2: /* Class B */
+ sprintf(buf, "%u.%u", netbr[2], netbr[3]);
+ break;
+ case 1: /* Class C */
+ sprintf(buf, "%u.%u.%u", netbr[1], netbr[2], netbr[3]);
+ break;
+ case 0: /* Class D - E */
+ sprintf(buf, "%u.%u.%u.%u", netbr[0], netbr[1],
+ netbr[2], netbr[3]);
+ break;
+ }
+
+ str = (char *)&buf;
+ cp = str + (strlen(str) - 2);
+
+ while(!strcmp(cp, ".0")) {
+ *cp = '\0';
+ cp = str + (strlen(str) - 2);
+ }
+
+ return _getnetbynis(str, "networks.byaddr", af);
+}
diff --git a/lib/libc/net/getnetent.3 b/lib/libc/net/getnetent.3
new file mode 100644
index 0000000..58bb7a2
--- /dev/null
+++ b/lib/libc/net/getnetent.3
@@ -0,0 +1,159 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getnetent.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETNETENT 3
+.Os BSD 4.2
+.Sh NAME
+.Nm getnetent ,
+.Nm getnetbyaddr ,
+.Nm getnetbyname ,
+.Nm setnetent ,
+.Nm endnetent
+.Nd get network entry
+.Sh SYNOPSIS
+.Fd #include <netdb.h>
+.Ft struct netent *
+.Fn getnetent void
+.Ft struct netent *
+.Fn getnetbyname "const char *name"
+.Ft struct netent *
+.Fn getnetbyaddr "unsigned long net" "int type"
+.Ft void
+.Fn setnetent "int stayopen"
+.Ft void
+.Fn endnetent void
+.Sh DESCRIPTION
+The
+.Fn getnetent ,
+.Fn getnetbyname ,
+and
+.Fn getnetbyaddr
+functions
+each return a pointer to an object with the
+following structure
+containing the broken-out
+fields of a line in the network data base,
+.Pa /etc/networks .
+.Bd -literal -offset indent
+struct netent {
+ char *n_name; /* official name of net */
+ char **n_aliases; /* alias list */
+ int n_addrtype; /* net number type */
+ unsigned long n_net; /* net number */
+};
+.Ed
+.Pp
+The members of this structure are:
+.Bl -tag -width n_addrtype
+.It Fa n_name
+The official name of the network.
+.It Fa n_aliases
+A zero terminated list of alternate names for the network.
+.It Fa n_addrtype
+The type of the network number returned; currently only AF_INET.
+.It Fa n_net
+The network number. Network numbers are returned in machine byte
+order.
+.El
+.Pp
+The
+.Fn getnetent
+function
+reads the next line of the file, opening the file if necessary.
+.Pp
+The
+.Fn setnetent
+function
+opens and rewinds the file. If the
+.Fa stayopen
+flag is non-zero,
+the net data base will not be closed after each call to
+.Fn getnetbyname
+or
+.Fn getnetbyaddr .
+.Pp
+The
+.Fn endnetent
+function
+closes the file.
+.Pp
+The
+.Fn getnetbyname
+function
+and
+.Fn getnetbyaddr
+sequentially search from the beginning
+of the file until a matching
+net name or
+net address and type is found,
+or until
+.Dv EOF
+is encountered. The
+.Fa type
+must be
+.Dv AF_INET .
+Network numbers are supplied in host order.
+.Sh FILES
+.Bl -tag -width /etc/networks -compact
+.It Pa /etc/networks
+.El
+.Sh DIAGNOSTICS
+Null pointer
+(0) returned on
+.Dv EOF
+or error.
+.Sh SEE ALSO
+.Xr networks 5
+.Pp
+.%T RFC 1101
+.Sh HISTORY
+The
+.Fn getnetent ,
+.Fn getnetbyaddr ,
+.Fn getnetbyname ,
+.Fn setnetent ,
+and
+.Fn endnetent
+functions appeared in
+.Bx 4.2 .
+.Sh BUGS
+The data space used by
+these functions is static; if future use requires the data, it should be
+copied before any subsequent calls to these functions overwrite it.
+Only Internet network
+numbers are currently understood.
+Expecting network numbers to fit
+in no more than 32 bits is probably
+naive.
diff --git a/lib/libc/net/getnetnamadr.c b/lib/libc/net/getnetnamadr.c
new file mode 100644
index 0000000..cb5871b
--- /dev/null
+++ b/lib/libc/net/getnetnamadr.c
@@ -0,0 +1,190 @@
+/*-
+ * Copyright (c) 1994, Garrett Wollman
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+
+#ifndef _PATH_NETCONF
+#define _PATH_NETCONF "/etc/host.conf"
+#endif
+
+enum service_type {
+ SERVICE_NONE = 0,
+ SERVICE_BIND,
+ SERVICE_TABLE,
+ SERVICE_NIS };
+#define SERVICE_MAX SERVICE_NIS
+
+static struct {
+ const char *name;
+ enum service_type type;
+} service_names[] = {
+ { "hosts", SERVICE_TABLE },
+ { "/etc/hosts", SERVICE_TABLE },
+ { "hosttable", SERVICE_TABLE },
+ { "htable", SERVICE_TABLE },
+ { "bind", SERVICE_BIND },
+ { "dns", SERVICE_BIND },
+ { "domain", SERVICE_BIND },
+ { "yp", SERVICE_NIS },
+ { "yellowpages", SERVICE_NIS },
+ { "nis", SERVICE_NIS },
+ { 0, SERVICE_NONE }
+};
+
+static enum service_type service_order[SERVICE_MAX + 1];
+static int service_done = 0;
+
+static enum service_type
+get_service_name(const char *name) {
+ int i;
+ for(i = 0; service_names[i].type != SERVICE_NONE; i++) {
+ if(!strcasecmp(name, service_names[i].name)) {
+ return service_names[i].type;
+ }
+ }
+ return SERVICE_NONE;
+}
+
+static void
+init_services()
+{
+ char *cp, *p, buf[BUFSIZ];
+ register int cc = 0;
+ FILE *fd;
+
+ if ((fd = (FILE *)fopen(_PATH_NETCONF, "r")) == NULL) {
+ /* make some assumptions */
+ service_order[0] = SERVICE_TABLE;
+ service_order[1] = SERVICE_NONE;
+ } else {
+ while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {
+ if(buf[0] == '#')
+ continue;
+
+ p = buf;
+ while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
+ ;
+ if (cp == NULL)
+ continue;
+ do {
+ if (isalpha((unsigned char)cp[0])) {
+ service_order[cc] = get_service_name(cp);
+ if(service_order[cc] != SERVICE_NONE)
+ cc++;
+ }
+ while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
+ ;
+ } while(cp != NULL && cc < SERVICE_MAX);
+ }
+ service_order[cc] = SERVICE_NONE;
+ fclose(fd);
+ }
+ service_done = 1;
+}
+
+struct netent *
+getnetbyname(const char *name)
+{
+ struct netent *hp = 0;
+ int nserv = 0;
+
+ if (!service_done)
+ init_services();
+
+ while (!hp) {
+ switch (service_order[nserv]) {
+ case SERVICE_NONE:
+ return NULL;
+ case SERVICE_TABLE:
+ hp = _getnetbyhtname(name);
+ break;
+ case SERVICE_BIND:
+ hp = _getnetbydnsname(name);
+ break;
+ case SERVICE_NIS:
+ hp = _getnetbynisname(name);
+ break;
+ }
+ nserv++;
+ }
+ return hp;
+}
+
+struct netent *
+getnetbyaddr(addr, af)
+ u_long addr;
+ int af;
+{
+ struct netent *hp = 0;
+ int nserv = 0;
+
+ if (!service_done)
+ init_services();
+
+ while (!hp) {
+ switch (service_order[nserv]) {
+ case SERVICE_NONE:
+ return 0;
+ case SERVICE_TABLE:
+ hp = _getnetbyhtaddr(addr, af);
+ break;
+ case SERVICE_BIND:
+ hp = _getnetbydnsaddr(addr, af);
+ break;
+ case SERVICE_NIS:
+ hp = _getnetbynisaddr(addr, af);
+ break;
+ }
+ nserv++;
+ }
+ return hp;
+}
+
+void
+setnetent(stayopen)
+ int stayopen;
+{
+ _setnethtent(stayopen);
+ _setnetdnsent(stayopen);
+}
+
+void
+endnetent()
+{
+ _endnethtent();
+ _endnetdnsent();
+}
diff --git a/lib/libc/net/getproto.c b/lib/libc/net/getproto.c
new file mode 100644
index 0000000..46f46d3
--- /dev/null
+++ b/lib/libc/net/getproto.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getproto.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <netdb.h>
+
+extern int _proto_stayopen;
+
+struct protoent *
+getprotobynumber(proto)
+ register int proto;
+{
+ register struct protoent *p;
+
+ setprotoent(_proto_stayopen);
+ while ( (p = getprotoent()) )
+ if (p->p_proto == proto)
+ break;
+ if (!_proto_stayopen)
+ endprotoent();
+ return (p);
+}
diff --git a/lib/libc/net/getprotoent.3 b/lib/libc/net/getprotoent.3
new file mode 100644
index 0000000..fad937e
--- /dev/null
+++ b/lib/libc/net/getprotoent.3
@@ -0,0 +1,147 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getprotoent.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETPROTOENT 3
+.Os BSD 4.2
+.Sh NAME
+.Nm getprotoent ,
+.Nm getprotobynumber ,
+.Nm getprotobyname ,
+.Nm setprotoent ,
+.Nm endprotoent
+.Nd get protocol entry
+.Sh SYNOPSIS
+.Fd #include <netdb.h>
+.Ft struct protoent *
+.Fn getprotoent void
+.Ft struct protoent *
+.Fn getprotobyname "const char *name"
+.Ft struct protoent *
+.Fn getprotobynumber "int proto"
+.Ft void
+.Fn setprotoent "int stayopen"
+.Ft void
+.Fn endprotoent void
+.Sh DESCRIPTION
+The
+.Fn getprotoent ,
+.Fn getprotobyname ,
+and
+.Fn getprotobynumber
+functions
+each return a pointer to an object with the
+following structure
+containing the broken-out
+fields of a line in the network protocol data base,
+.Pa /etc/protocols .
+.Bd -literal -offset indent
+.Pp
+struct protoent {
+ char *p_name; /* official name of protocol */
+ char **p_aliases; /* alias list */
+ int p_proto; /* protocol number */
+};
+.Ed
+.Pp
+The members of this structure are:
+.Bl -tag -width p_aliases
+.It Fa p_name
+The official name of the protocol.
+.It Fa p_aliases
+A zero terminated list of alternate names for the protocol.
+.It Fa p_proto
+The protocol number.
+.El
+.Pp
+The
+.Fn getprotoent
+function
+reads the next line of the file, opening the file if necessary.
+.Pp
+The
+.Fn setprotoent
+function
+opens and rewinds the file. If the
+.Fa stayopen
+flag is non-zero,
+the net data base will not be closed after each call to
+.Fn getprotobyname
+or
+.Fn getprotobynumber .
+.Pp
+The
+.Fn endprotoent
+function
+closes the file.
+.Pp
+The
+.Fn getprotobyname
+function
+and
+.Fn getprotobynumber
+sequentially search from the beginning
+of the file until a matching
+protocol name or
+protocol number is found,
+or until
+.Dv EOF
+is encountered.
+.Sh RETURN VALUES
+Null pointer
+(0) returned on
+.Dv EOF
+or error.
+.Sh FILES
+.Bl -tag -width /etc/protocols -compact
+.It Pa /etc/protocols
+.El
+.Sh SEE ALSO
+.Xr protocols 5
+.Sh HISTORY
+The
+.Fn getprotoent ,
+.Fn getprotobynumber ,
+.Fn getprotobyname ,
+.Fn setprotoent ,
+and
+.Fn endprotoent
+functions appeared in
+.Bx 4.2 .
+.Sh BUGS
+These functions use a static data space;
+if the data is needed for future use, it should be
+copied before any subsequent calls overwrite it.
+Only the Internet
+protocols are currently understood.
diff --git a/lib/libc/net/getprotoent.c b/lib/libc/net/getprotoent.c
new file mode 100644
index 0000000..c10ae33
--- /dev/null
+++ b/lib/libc/net/getprotoent.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getprotoent.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MAXALIASES 35
+
+static FILE *protof = NULL;
+static char line[BUFSIZ+1];
+static struct protoent proto;
+static char *proto_aliases[MAXALIASES];
+int _proto_stayopen;
+
+void
+setprotoent(f)
+ int f;
+{
+ if (protof == NULL)
+ protof = fopen(_PATH_PROTOCOLS, "r" );
+ else
+ rewind(protof);
+ _proto_stayopen |= f;
+}
+
+void
+endprotoent()
+{
+ if (protof) {
+ fclose(protof);
+ protof = NULL;
+ }
+ _proto_stayopen = 0;
+}
+
+struct protoent *
+getprotoent()
+{
+ char *p;
+ register char *cp, **q;
+
+ if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL)
+ return (NULL);
+again:
+ if ((p = fgets(line, BUFSIZ, protof)) == NULL)
+ return (NULL);
+ if (*p == '#')
+ goto again;
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ goto again;
+ *cp = '\0';
+ proto.p_name = p;
+ cp = strpbrk(p, " \t");
+ if (cp == NULL)
+ goto again;
+ *cp++ = '\0';
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ p = strpbrk(cp, " \t");
+ if (p != NULL)
+ *p++ = '\0';
+ proto.p_proto = atoi(cp);
+ q = proto.p_aliases = proto_aliases;
+ if (p != NULL) {
+ cp = p;
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &proto_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ }
+ *q = NULL;
+ return (&proto);
+}
diff --git a/lib/libc/net/getprotoname.c b/lib/libc/net/getprotoname.c
new file mode 100644
index 0000000..0832acf
--- /dev/null
+++ b/lib/libc/net/getprotoname.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getprotoname.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <netdb.h>
+#include <string.h>
+
+extern int _proto_stayopen;
+
+struct protoent *
+getprotobyname(name)
+ register const char *name;
+{
+ register struct protoent *p;
+ register char **cp;
+
+ setprotoent(_proto_stayopen);
+ while ( (p = getprotoent()) ) {
+ if (strcmp(p->p_name, name) == 0)
+ break;
+ for (cp = p->p_aliases; *cp != 0; cp++)
+ if (strcmp(*cp, name) == 0)
+ goto found;
+ }
+found:
+ if (!_proto_stayopen)
+ endprotoent();
+ return (p);
+}
diff --git a/lib/libc/net/getservbyname.c b/lib/libc/net/getservbyname.c
new file mode 100644
index 0000000..124f5ac
--- /dev/null
+++ b/lib/libc/net/getservbyname.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getservbyname.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <netdb.h>
+#include <string.h>
+
+extern int _serv_stayopen;
+
+struct servent *
+getservbyname(name, proto)
+ const char *name, *proto;
+{
+ register struct servent *p;
+ register char **cp;
+
+#ifdef YP
+ extern char *___getservbyname_yp;
+ extern char *___getservbyproto_yp;
+
+ ___getservbyname_yp = (char *)name;
+ ___getservbyproto_yp = (char *)proto;
+#endif
+
+ setservent(_serv_stayopen);
+ while ( (p = getservent()) ) {
+ if (strcmp(name, p->s_name) == 0)
+ goto gotname;
+ for (cp = p->s_aliases; *cp; cp++)
+ if (strcmp(name, *cp) == 0)
+ goto gotname;
+ continue;
+gotname:
+ if (proto == 0 || strcmp(p->s_proto, proto) == 0)
+ break;
+ }
+ if (!_serv_stayopen)
+ endservent();
+
+#ifdef YP
+ ___getservbyname_yp = NULL;
+ ___getservbyproto_yp = NULL;
+#endif
+
+ return (p);
+}
diff --git a/lib/libc/net/getservbyport.c b/lib/libc/net/getservbyport.c
new file mode 100644
index 0000000..ef9a2e8
--- /dev/null
+++ b/lib/libc/net/getservbyport.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getservbyport.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <netdb.h>
+#include <string.h>
+
+extern int _serv_stayopen;
+
+struct servent *
+getservbyport(port, proto)
+ int port;
+ const char *proto;
+{
+ register struct servent *p;
+
+#ifdef YP
+ extern int ___getservbyport_yp;
+ extern char *___getservbyproto_yp;
+
+ ___getservbyport_yp = port;
+ ___getservbyproto_yp = (char *)proto;
+#endif
+
+ setservent(_serv_stayopen);
+ while ( (p = getservent()) ) {
+ if (p->s_port != port)
+ continue;
+ if (proto == 0 || strcmp(p->s_proto, proto) == 0)
+ break;
+ }
+ if (!_serv_stayopen)
+ endservent();
+
+#ifdef YP
+ ___getservbyport_yp = 0;
+ ___getservbyproto_yp = NULL;
+#endif
+
+ return (p);
+}
diff --git a/lib/libc/net/getservent.3 b/lib/libc/net/getservent.3
new file mode 100644
index 0000000..eac2361
--- /dev/null
+++ b/lib/libc/net/getservent.3
@@ -0,0 +1,157 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)getservent.3 8.3 (Berkeley) 1/12/94
+.\" $FreeBSD$
+.\"
+.Dd July 9, 1995
+.Dt GETSERVENT 3
+.Os BSD 4.2
+.Sh NAME
+.Nm getservent ,
+.Nm getservbyport ,
+.Nm getservbyname ,
+.Nm setservent ,
+.Nm endservent
+.Nd get service entry
+.Sh SYNOPSIS
+.Fd #include <netdb.h>
+.Ft struct servent *
+.Fn getservent
+.Ft struct servent *
+.Fn getservbyname "const char *name" "const char *proto"
+.Ft struct servent *
+.Fn getservbyport "int port" "const char *proto"
+.Ft void
+.Fn setservent "int stayopen"
+.Ft void
+.Fn endservent void
+.Sh DESCRIPTION
+The
+.Fn getservent ,
+.Fn getservbyname ,
+and
+.Fn getservbyport
+functions
+each return a pointer to an object with the
+following structure
+containing the broken-out
+fields of a line in the network services data base,
+.Pa /etc/services .
+.Bd -literal -offset indent
+struct servent {
+ char *s_name; /* official name of service */
+ char **s_aliases; /* alias list */
+ int s_port; /* port service resides at */
+ char *s_proto; /* protocol to use */
+};
+.Ed
+.Pp
+The members of this structure are:
+.Bl -tag -width s_aliases
+.It Fa s_name
+The official name of the service.
+.It Fa s_aliases
+A zero terminated list of alternate names for the service.
+.It Fa s_port
+The port number at which the service resides.
+Port numbers are returned in network byte order.
+.It Fa s_proto
+The name of the protocol to use when contacting the
+service.
+.El
+.Pp
+The
+.Fn getservent
+function
+reads the next line of the file, opening the file if necessary.
+.Pp
+The
+.Fn setservent
+function
+opens and rewinds the file. If the
+.Fa stayopen
+flag is non-zero,
+the net data base will not be closed after each call to
+.Fn getservbyname
+or
+.Fn getservbyport .
+.Pp
+The
+.Fn endservent
+function
+closes the file.
+.Pp
+The
+.Fn getservbyname
+and
+.Fn getservbyport
+functions
+sequentially search from the beginning
+of the file until a matching
+protocol name or
+port number (which must be specified in
+network byte order) is found,
+or until
+.Dv EOF
+is encountered.
+If a protocol name is also supplied (non-
+.Dv NULL ) ,
+searches must also match the protocol.
+.ne 1i
+.Sh FILES
+.Bl -tag -width /etc/services -compact
+.It Pa /etc/services
+.El
+.Sh DIAGNOSTICS
+Null pointer
+(0) returned on
+.Dv EOF
+or error.
+.Sh SEE ALSO
+.Xr getprotoent 3 ,
+.Xr services 5
+.Sh HISTORY
+The
+.Fn getservent ,
+.Fn getservbyport ,
+.Fn getservbyname ,
+.Fn setservent ,
+and
+.Fn endservent
+functions appeared in
+.Bx 4.2 .
+.Sh BUGS
+These functions use static data storage;
+if the data is needed for future use, it should be
+copied before any subsequent calls overwrite it.
+Expecting port numbers to fit in a 32 bit
+quantity is probably naive.
diff --git a/lib/libc/net/getservent.c b/lib/libc/net/getservent.c
new file mode 100644
index 0000000..cd4449f
--- /dev/null
+++ b/lib/libc/net/getservent.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+static int serv_stepping_yp = 0;
+extern int _yp_check __P(( char ** ));
+#endif
+
+
+#define MAXALIASES 35
+
+static FILE *servf = NULL;
+static char line[BUFSIZ+1];
+static struct servent serv;
+static char *serv_aliases[MAXALIASES];
+int _serv_stayopen;
+
+#ifdef YP
+char *___getservbyname_yp = NULL;
+char *___getservbyproto_yp = NULL;
+int ___getservbyport_yp = 0;
+static char *yp_domain = NULL;
+
+static int
+_getservbyport_yp(line)
+ char *line;
+{
+ char *result;
+ int resultlen;
+ char buf[YPMAXRECORD + 2];
+ int rv;
+
+ snprintf(buf, sizeof(buf), "%d/%s", ntohs(___getservbyport_yp),
+ ___getservbyproto_yp);
+
+ ___getservbyport_yp = 0;
+ ___getservbyproto_yp = NULL;
+
+ if(!yp_domain) {
+ if(yp_get_default_domain(&yp_domain))
+ return (0);
+ }
+
+ /*
+ * We have to be a little flexible here. Ideally you're supposed
+ * to have both a services.byname and a services.byport map, but
+ * some systems have only services.byname. FreeBSD cheats a little
+ * by putting the services.byport information in the same map as
+ * services.byname so that either case will work. We allow for both
+ * possibilities here: if there is no services.byport map, we try
+ * services.byname instead.
+ */
+ if ((rv = yp_match(yp_domain, "services.byport", buf, strlen(buf),
+ &result, &resultlen))) {
+ if (rv == YPERR_MAP) {
+ if (yp_match(yp_domain, "services.byname", buf,
+ strlen(buf), &result, &resultlen))
+ return(0);
+ } else
+ return(0);
+ }
+
+ /* getservent() expects lines terminated with \n -- make it happy */
+ snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
+
+ free(result);
+ return(1);
+}
+
+static int
+_getservbyname_yp(line)
+ char *line;
+{
+ char *result;
+ int resultlen;
+ char buf[YPMAXRECORD + 2];
+
+ if(!yp_domain) {
+ if(yp_get_default_domain(&yp_domain))
+ return (0);
+ }
+
+ snprintf(buf, sizeof(buf), "%s/%s", ___getservbyname_yp,
+ ___getservbyproto_yp);
+
+ ___getservbyname_yp = 0;
+ ___getservbyproto_yp = NULL;
+
+ if (yp_match(yp_domain, "services.byname", buf, strlen(buf),
+ &result, &resultlen)) {
+ return(0);
+ }
+
+ /* getservent() expects lines terminated with \n -- make it happy */
+ snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
+
+ free(result);
+ return(1);
+}
+
+static int
+_getservent_yp(line)
+ char *line;
+{
+ static char *key = NULL;
+ static int keylen;
+ char *lastkey, *result;
+ int resultlen;
+ int rv;
+
+ if(!yp_domain) {
+ if(yp_get_default_domain(&yp_domain))
+ return (0);
+ }
+
+ if (!serv_stepping_yp) {
+ if (key)
+ free(key);
+ if ((rv = yp_first(yp_domain, "services.byname", &key, &keylen,
+ &result, &resultlen))) {
+ serv_stepping_yp = 0;
+ return(0);
+ }
+ serv_stepping_yp = 1;
+ } else {
+ lastkey = key;
+ rv = yp_next(yp_domain, "services.byname", key, keylen, &key,
+ &keylen, &result, &resultlen);
+ free(lastkey);
+ if (rv) {
+ serv_stepping_yp = 0;
+ return (0);
+ }
+ }
+
+ /* getservent() expects lines terminated with \n -- make it happy */
+ snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
+
+ free(result);
+
+ return(1);
+}
+#endif
+
+void
+setservent(f)
+ int f;
+{
+ if (servf == NULL)
+ servf = fopen(_PATH_SERVICES, "r" );
+ else
+ rewind(servf);
+ _serv_stayopen |= f;
+}
+
+void
+endservent()
+{
+ if (servf) {
+ fclose(servf);
+ servf = NULL;
+ }
+ _serv_stayopen = 0;
+}
+
+struct servent *
+getservent()
+{
+ char *p;
+ register char *cp, **q;
+
+#ifdef YP
+ if (serv_stepping_yp && _getservent_yp(line)) {
+ p = (char *)&line;
+ goto unpack;
+ }
+tryagain:
+#endif
+ if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
+ return (NULL);
+again:
+ if ((p = fgets(line, BUFSIZ, servf)) == NULL)
+ return (NULL);
+#ifdef YP
+ if (*p == '+' && _yp_check(NULL)) {
+ if (___getservbyname_yp != NULL) {
+ if (!_getservbyname_yp(line))
+ goto tryagain;
+ }
+ else if (___getservbyport_yp != 0) {
+ if (!_getservbyport_yp(line))
+ goto tryagain;
+ }
+ else if (!_getservent_yp(line))
+ goto tryagain;
+ }
+unpack:
+#endif
+ if (*p == '#')
+ goto again;
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ goto again;
+ *cp = '\0';
+ serv.s_name = p;
+ p = strpbrk(p, " \t");
+ if (p == NULL)
+ goto again;
+ *p++ = '\0';
+ while (*p == ' ' || *p == '\t')
+ p++;
+ cp = strpbrk(p, ",/");
+ if (cp == NULL)
+ goto again;
+ *cp++ = '\0';
+ serv.s_port = htons((u_short)atoi(p));
+ serv.s_proto = cp;
+ q = serv.s_aliases = serv_aliases;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &serv_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ return (&serv);
+}
diff --git a/lib/libc/net/herror.c b/lib/libc/net/herror.c
new file mode 100644
index 0000000..0ab7448
--- /dev/null
+++ b/lib/libc/net/herror.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <netdb.h>
+#include <string.h>
+#include <unistd.h>
+
+const char *h_errlist[] = {
+ "Resolver Error 0 (no error)",
+ "Unknown host", /* 1 HOST_NOT_FOUND */
+ "Host name lookup failure", /* 2 TRY_AGAIN */
+ "Unknown server error", /* 3 NO_RECOVERY */
+ "No address associated with name", /* 4 NO_ADDRESS */
+};
+int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
+
+int h_errno;
+
+/*
+ * herror --
+ * print the error indicated by the h_errno value.
+ */
+void
+herror(s)
+ const char *s;
+{
+ struct iovec iov[4];
+ register struct iovec *v = iov;
+
+ if (s && *s) {
+ v->iov_base = (char *)s;
+ v->iov_len = strlen(s);
+ v++;
+ v->iov_base = ": ";
+ v->iov_len = 2;
+ v++;
+ }
+ v->iov_base = (char *)hstrerror(h_errno);
+ v->iov_len = strlen(v->iov_base);
+ v++;
+ v->iov_base = "\n";
+ v->iov_len = 1;
+ writev(STDERR_FILENO, iov, (v - iov) + 1);
+}
+
+const char *
+hstrerror(err)
+ int err;
+{
+ if (err < 0)
+ return ("Resolver internal error");
+ else if (err < h_nerr)
+ return (h_errlist[err]);
+ return ("Unknown resolver error");
+}
diff --git a/lib/libc/net/if_indextoname.3 b/lib/libc/net/if_indextoname.3
new file mode 100644
index 0000000..186ddba
--- /dev/null
+++ b/lib/libc/net/if_indextoname.3
@@ -0,0 +1,142 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)rcmd.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd May 21, 1998
+.Dt IF_NAMETOINDEX 3
+.Os KAME
+.Sh NAME
+.Nm if_nametoindex ,
+.Nm if_indextoname ,
+.Nm if_nameindex ,
+.Nm if_freenameindex
+.Nd convert interface index to name, and vice versa
+.Sh SYNOPSIS
+.Fd #include <net/if.h>
+.Ft "unsigned int"
+.Fn if_nametoindex "const char *ifname"
+.Ft "char *"
+.Fn if_indextoname "unsigned int ifindex" "char *ifname"
+.Ft "struct if_nameindex *"
+.Fn if_nameindex "void"
+.Ft "void"
+.Fn if_freenameindex "struct if_nameindex *ptr"
+.Sh DESCRIPTION
+The functions map interface index to readable interface name
+.Po
+such as
+.Li ``lo0''
+.Pc
+, and vice versa.
+.Pp
+.Fn if_nametoindex
+converts readable interface name to interface index
+.Pp positive integer value .
+If the specified interface does not exist, 0 will be returned.
+.Pp
+.Fn if_indextoname
+converts interface index to readable interface name.
+The
+.Fa ifname
+argument must point to a buffer of at least
+.Dv IF_NAMESIZE
+bytes into which the interface name corresponding to the specified index is
+returned.
+.Po
+.Dv IF_NAMESIZE
+is also defined in
+.Li <net/if.h>
+and its value includes a terminating null byte at the end of the
+interface name.
+.Pc
+This pointer is also the return value of the function.
+If there is no interface corresponding to the specified index,
+.Dv NULL
+is returned.
+.Pp
+.Fn if_nameindex
+returns an array of
+.Fa if_nameindex
+structures.
+.Fa if_nametoindex
+is also defined in
+.Li <net/if.h> ,
+and is as follows:
+.Bd -literal -offset
+struct if_nameindex {
+ unsigned int if_index; /* 1, 2, ... */
+ char *if_name; /* null terminated name: "le0", ... */
+};
+.Ed
+.Pp
+The end of the array of structures is indicated by a structure with
+an
+.Fa if_index
+of 0 and an
+.Fa if_name
+of
+.Dv NULL .
+The function returns a
+.Dv NULL
+pointer upon an error.
+The memory used for this array of structures along with the interface
+names pointed to by the
+.Fa if_name
+members is obtained dynamically.
+This memory is freed by the
+.Fn if_freenameindex
+function.
+.Pp
+.Fn if_freenameindex
+takes a pointer that was returned by
+.Fn if_nameindex
+as argument
+.Pq Fa ptr ,
+and it reclaims the region allocated.
+.Sh DIAGNOSTICS
+.Fn if_nametoindex
+returns 0 on error, positive integer on success.
+.Fn if_indextoname
+and
+.Fn if_nameindex
+return
+.Dv NULL
+on errors.
+.Sh SEE ALSO
+R. Gilligan, S. Thomson, J. Bound, and W. Stevens,
+``Basic Socket Interface Extensions for IPv6,'' RFC2553, March 1999.
+.Sh HISTORY
+The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit.
+.Sh STANDARDS
+These functions are defined in ``Basic Socket Interface Extensions for IPv6''
+.Pq RFC2533 .
diff --git a/lib/libc/net/ifname.c b/lib/libc/net/ifname.c
new file mode 100644
index 0000000..3d3916a
--- /dev/null
+++ b/lib/libc/net/ifname.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/*
+ * TODO:
+ * - prototype defs into arpa/inet.h, not net/if.h (bsd-api-new-02)
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <net/if_dl.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ROUNDUP(a) \
+ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+
+unsigned int
+if_nametoindex(ifname)
+ const char *ifname;
+{
+ struct if_nameindex *iff = if_nameindex(), *ifx;
+ int ret;
+
+ if (iff == NULL) return 0;
+ ifx = iff;
+ while (ifx->if_name != NULL) {
+ if (strcmp(ifx->if_name, ifname) == 0) {
+ ret = ifx->if_index;
+ if_freenameindex(iff);
+ return ret;
+ }
+ ifx++;
+ }
+ if_freenameindex(iff);
+ errno = ENXIO;
+ return 0;
+}
+
+char *
+if_indextoname(ifindex, ifname)
+ unsigned int ifindex;
+ char *ifname; /* at least IF_NAMESIZE */
+{
+ struct if_nameindex *iff = if_nameindex(), *ifx;
+ char *cp, *dp;
+
+ if (iff == NULL) return NULL;
+ ifx = iff;
+ while (ifx->if_index != 0) {
+ if (ifx->if_index == ifindex) {
+ cp = ifname;
+ dp = ifx->if_name;
+ while ((*cp++ = *dp++)) ;
+ if_freenameindex(iff);
+ return (ifname);
+ }
+ ifx++;
+ }
+ if_freenameindex(iff);
+ errno = ENXIO;
+ return NULL;
+}
+
+struct if_nameindex *
+if_nameindex()
+{
+ size_t needed;
+ int mib[6], i, ifn = 0, off = 0, hlen;
+ char *buf = NULL, *lim, *next, *cp, *ifbuf = NULL;
+ struct rt_msghdr *rtm;
+ struct if_msghdr *ifm;
+ struct sockaddr *sa;
+ struct sockaddr_dl *sdl;
+ struct if_nameindex *ret = NULL;
+ static int ifxs = 64; /* initial upper limit */
+ struct _ifx {
+ int if_index;
+ int if_off;
+ } *ifx = NULL;
+
+ mib[0] = CTL_NET;
+ mib[1] = PF_ROUTE;
+ mib[2] = 0; /* protocol */
+ mib[3] = 0; /* wildcard address family */
+ mib[4] = NET_RT_IFLIST;
+ mib[5] = 0; /* no flags */
+ if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+ return NULL;
+ if ((buf = malloc(needed)) == NULL) {
+ errno = ENOMEM;
+ goto end;
+ }
+ /* XXX: we may have allocated too much than necessary */
+ if ((ifbuf = malloc(needed)) == NULL) {
+ errno = ENOMEM;
+ goto end;
+ }
+ if ((ifx = (struct _ifx *)malloc(sizeof(*ifx) * ifxs)) == NULL) {
+ errno = ENOMEM;
+ goto end;
+ }
+ if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
+ /* sysctl has set errno */
+ goto end;
+ }
+ lim = buf + needed;
+ for (next = buf; next < lim; next += rtm->rtm_msglen) {
+ rtm = (struct rt_msghdr *)next;
+ if (rtm->rtm_version != RTM_VERSION) {
+ errno = EPROTONOSUPPORT;
+ goto end;
+ }
+ switch (rtm->rtm_type) {
+ case RTM_IFINFO:
+ ifm = (struct if_msghdr *)rtm;
+ ifx[ifn].if_index = ifm->ifm_index;
+ ifx[ifn].if_off = off;
+ cp = (char *)(ifm + 1);
+ for (i = 1; i; i <<= 1) {
+ if (i & ifm->ifm_addrs) {
+ sa = (struct sockaddr *)cp;
+ if (i == RTA_IFP &&
+ sa->sa_family == AF_LINK) {
+ sdl = (struct sockaddr_dl *)sa;
+ memcpy(ifbuf + off,
+ sdl->sdl_data,
+ sdl->sdl_nlen);
+ off += sdl->sdl_nlen;
+ *(ifbuf + off) = '\0';
+ off++;
+ }
+ ADVANCE(cp, sa);
+ }
+ }
+ if (++ifn == ifxs) {
+ /* we need more memory */
+ struct _ifx *newifx;
+
+ ifxs *= 2;
+ if ((newifx = (struct _ifx *)malloc(sizeof(*newifx) * ifxs)) == NULL) {
+ errno = ENOMEM;
+ goto end;
+ }
+
+ /* copy and free old data */
+ memcpy(newifx, ifx, (sizeof(*ifx) * ifxs) / 2);
+ free(ifx);
+ ifx = newifx;
+ }
+ }
+ }
+ hlen = sizeof(struct if_nameindex) * (ifn + 1);
+ if ((cp = (char *)malloc(hlen + off)) == NULL) {
+ errno = ENOMEM;
+ goto end;
+ }
+ bcopy(ifbuf, cp + hlen, off);
+ ret = (struct if_nameindex *)cp;
+ for (i = 0; i < ifn; i++) {
+ ret[i].if_index = ifx[i].if_index;
+ ret[i].if_name = cp + hlen + ifx[i].if_off;
+ }
+ ret[ifn].if_index = 0;
+ ret[ifn].if_name = NULL;
+
+ end:
+ if (buf) free(buf);
+ if (ifbuf) free(ifbuf);
+ if (ifx) free(ifx);
+
+ return ret;
+}
+
+void if_freenameindex(ptr)
+ struct if_nameindex *ptr;
+{
+ free(ptr);
+}
diff --git a/lib/libc/net/inet.3 b/lib/libc/net/inet.3
new file mode 100644
index 0000000..629ab0f
--- /dev/null
+++ b/lib/libc/net/inet.3
@@ -0,0 +1,210 @@
+.\" Copyright (c) 1983, 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)inet.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 17, 1996
+.Dt INET 3
+.Os BSD 4.2
+.Sh NAME
+.Nm inet_aton ,
+.Nm inet_addr ,
+.Nm inet_network ,
+.Nm inet_ntoa ,
+.Nm inet_makeaddr ,
+.Nm inet_lnaof ,
+.Nm inet_netof
+.Nd Internet address manipulation routines
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Fd #include <netinet/in.h>
+.Fd #include <arpa/inet.h>
+.Ft int
+.Fn inet_aton "const char *cp" "struct in_addr *pin"
+.Ft unsigned long
+.Fn inet_addr "const char *cp"
+.Ft unsigned long
+.Fn inet_network "const char *cp"
+.Ft char *
+.Fn inet_ntoa "struct in_addr in"
+.Ft struct in_addr
+.Fn inet_makeaddr "unsigned long net" "unsigned long lna"
+.Ft unsigned long
+.Fn inet_lnaof "struct in_addr in"
+.Ft unsigned long
+.Fn inet_netof "struct in_addr in"
+.Sh DESCRIPTION
+The routines
+.Fn inet_aton ,
+.Fn inet_addr
+and
+.Fn inet_network
+interpret character strings representing
+numbers expressed in the Internet standard
+.Ql \&.
+notation.
+The
+.Fn inet_aton
+routine interprets the specified character string as an Internet address,
+placing the address into the structure provided.
+It returns 1 if the string was successfully interpreted,
+or 0 if the string is invalid.
+The
+.Fn inet_addr
+and
+.Fn inet_network
+functions return numbers suitable for use
+as Internet addresses and Internet network
+numbers, respectively.
+The routine
+.Fn inet_ntoa
+takes an Internet address and returns an
+.Tn ASCII
+string representing the address in
+.Ql \&.
+notation. The routine
+.Fn inet_makeaddr
+takes an Internet network number and a local
+network address and constructs an Internet address
+from it. The routines
+.Fn inet_netof
+and
+.Fn inet_lnaof
+break apart Internet host addresses, returning
+the network number and local network address part,
+respectively.
+.Pp
+All Internet addresses are returned in network
+order (bytes ordered from left to right).
+All network numbers and local address parts are
+returned as machine format integer values.
+.Sh INTERNET ADDRESSES
+Values specified using the
+.Ql \&.
+notation take one
+of the following forms:
+.Bd -literal -offset indent
+a.b.c.d
+a.b.c
+a.b
+a
+.Ed
+.Pp
+When four parts are specified, each is interpreted
+as a byte of data and assigned, from left to right,
+to the four bytes of an Internet address. Note
+that when an Internet address is viewed as a 32-bit
+integer quantity on the
+.Tn VAX
+the bytes referred to
+above appear as
+.Dq Li d.c.b.a .
+That is,
+.Tn VAX
+bytes are
+ordered from right to left.
+.Pp
+When a three part address is specified, the last
+part is interpreted as a 16-bit quantity and placed
+in the right-most two bytes of the network address.
+This makes the three part address format convenient
+for specifying Class B network addresses as
+.Dq Li 128.net.host .
+.Pp
+When a two part address is supplied, the last part
+is interpreted as a 24-bit quantity and placed in
+the right most three bytes of the network address.
+This makes the two part address format convenient
+for specifying Class A network addresses as
+.Dq Li net.host .
+.Pp
+When only one part is given, the value is stored
+directly in the network address without any byte
+rearrangement.
+.Pp
+All numbers supplied as
+.Dq parts
+in a
+.Ql \&.
+notation
+may be decimal, octal, or hexadecimal, as specified
+in the C language (i.e., a leading 0x or 0X implies
+hexadecimal; otherwise, a leading 0 implies octal;
+otherwise, the number is interpreted as decimal).
+.Pp
+The
+.Fn inet_aton
+and
+.Fn inet_ntoa
+functions are semi-deprecated in favor of the
+.Xr addr2ascii 3
+family. However, since those functions are not yet widely implemented,
+portable programs cannot rely on their presence and will continue
+to use the
+.Xr inet 3
+functions for some time.
+.Sh DIAGNOSTICS
+The constant
+.Dv INADDR_NONE
+is returned by
+.Fn inet_addr
+and
+.Fn inet_network
+for malformed requests.
+.Sh SEE ALSO
+.Xr addr2ascii 3 ,
+.Xr gethostbyname 3 ,
+.Xr getnetent 3 ,
+.Xr hosts 5 ,
+.Xr networks 5
+.Sh HISTORY
+These
+functions appeared in
+.Bx 4.2 .
+.Sh BUGS
+The value
+.Dv INADDR_NONE
+(0xffffffff) is a valid broadcast address, but
+.Fn inet_addr
+cannot return that value without indicating failure.
+The newer
+.Fn inet_aton
+function does not share this problem.
+The problem of host byte ordering versus network byte ordering is
+confusing.
+The string returned by
+.Fn inet_ntoa
+resides in a static memory area.
+.Pp
+Inet_addr should return a
+.Fa struct in_addr .
diff --git a/lib/libc/net/inet_addr.c b/lib/libc/net/inet_addr.c
new file mode 100644
index 0000000..abfdaa5
--- /dev/null
+++ b/lib/libc/net/inet_addr.c
@@ -0,0 +1,196 @@
+/*
+ * ++Copyright++ 1983, 1990, 1993
+ * -
+ * Copyright (c) 1983, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+
+/*
+ * ASCII internet address interpretation routine.
+ * The value returned is in network order.
+ */
+u_long /* XXX should be struct in_addr :( */
+inet_addr(cp)
+ register const char *cp;
+{
+ struct in_addr val;
+
+ if (inet_aton(cp, &val))
+ return (val.s_addr);
+ return (INADDR_NONE);
+}
+
+/*
+ * Check whether "cp" is a valid ASCII representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ */
+int
+inet_aton(cp, addr)
+ register const char *cp;
+ struct in_addr *addr;
+{
+ u_long parts[4];
+ u_long val;
+ char *c;
+ char *endptr;
+ int base, gotend, n;
+
+ c = (char *)cp;
+ n = 0;
+ /*
+ * Run through the string, grabbing numbers until
+ * the end of the string, or some error
+ */
+ gotend = 0;
+ while (!gotend) {
+ errno = 0;
+ val = strtoul(c, &endptr, 0);
+
+ if (errno == ERANGE) /* Fail completely if it overflowed. */
+ return (0);
+
+ /*
+ * If the whole string is invalid, endptr will equal
+ * c.. this way we can make sure someone hasn't
+ * gone '.12' or something which would get past
+ * the next check.
+ */
+ if (endptr == c)
+ return (0);
+ parts[n] = val;
+ c = endptr;
+
+ /* Check the next character past the previous number's end */
+ switch (*c) {
+ case '.' :
+ /* Make sure we only do 3 dots .. */
+ if (n == 3) /* Whoops. Quit. */
+ return (0);
+ n++;
+ c++;
+ break;
+
+ case '\0':
+ gotend = 1;
+ break;
+
+ default:
+ if (isspace((unsigned char)*c)) {
+ gotend = 1;
+ break;
+ } else
+ return (0); /* Invalid character, so fail */
+ }
+
+ }
+
+ /*
+ * Concoct the address according to
+ * the number of parts specified.
+ */
+
+ switch (n) {
+ case 0: /* a -- 32 bits */
+ /*
+ * Nothing is necessary here. Overflow checking was
+ * already done in strtoul().
+ */
+ break;
+ case 1: /* a.b -- 8.24 bits */
+ if (val > 0xffffff || parts[0] > 0xff)
+ return (0);
+ val |= parts[0] << 24;
+ break;
+
+ case 2: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff || parts[0] > 0xff || parts[1] > 0xff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 3: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff || parts[0] > 0xff || parts[1] > 0xff ||
+ parts[2] > 0xff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+
+ if (addr != NULL)
+ addr->s_addr = htonl(val);
+ return (1);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_addr
+__weak_reference(__inet_addr, inet_addr);
+#undef inet_aton
+__weak_reference(__inet_aton, inet_aton);
diff --git a/lib/libc/net/inet_lnaof.c b/lib/libc/net/inet_lnaof.c
new file mode 100644
index 0000000..99024d9
--- /dev/null
+++ b/lib/libc/net/inet_lnaof.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*
+ * Return the local network address portion of an
+ * internet address; handles class a/b/c network
+ * number formats.
+ */
+u_long
+inet_lnaof(in)
+ struct in_addr in;
+{
+ register u_long i = ntohl(in.s_addr);
+
+ if (IN_CLASSA(i))
+ return ((i)&IN_CLASSA_HOST);
+ else if (IN_CLASSB(i))
+ return ((i)&IN_CLASSB_HOST);
+ else
+ return ((i)&IN_CLASSC_HOST);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_lnaof
+__weak_reference(__inet_lnaof, inet_lnaof);
diff --git a/lib/libc/net/inet_makeaddr.c b/lib/libc/net/inet_makeaddr.c
new file mode 100644
index 0000000..8af7770
--- /dev/null
+++ b/lib/libc/net/inet_makeaddr.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*
+ * Formulate an Internet address from network + host. Used in
+ * building addresses stored in the ifnet structure.
+ */
+struct in_addr
+inet_makeaddr(net, host)
+ u_long net, host;
+{
+ u_long addr;
+
+ if (net < 128)
+ addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
+ else if (net < 65536)
+ addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
+ else if (net < 16777216L)
+ addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
+ else
+ addr = net | host;
+ addr = htonl(addr);
+ return (*(struct in_addr *)&addr);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_makeaddr
+__weak_reference(__inet_makeaddr, inet_makeaddr);
diff --git a/lib/libc/net/inet_net_ntop.c b/lib/libc/net/inet_net_ntop.c
new file mode 100644
index 0000000..4b30cb6
--- /dev/null
+++ b/lib/libc/net/inet_net_ntop.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char orig_rcsid[] = "From Id: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp";
+static const char rcsid[] = "$FreeBSD$";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits,
+ char *dst, size_t size));
+
+/*
+ * char *
+ * inet_net_ntop(af, src, bits, dst, size)
+ * convert network number from network to presentation format.
+ * generates CIDR style result always.
+ * return:
+ * pointer to dst, or NULL if an error occurred (check errno).
+ * author:
+ * Paul Vixie (ISC), July 1996
+ */
+char *
+inet_net_ntop(af, src, bits, dst, size)
+ int af;
+ const void *src;
+ int bits;
+ char *dst;
+ size_t size;
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_net_ntop_ipv4(src, bits, dst, size));
+ default:
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+}
+
+/*
+ * static char *
+ * inet_net_ntop_ipv4(src, bits, dst, size)
+ * convert IPv4 network number from network to presentation format.
+ * generates CIDR style result always.
+ * return:
+ * pointer to dst, or NULL if an error occurred (check errno).
+ * note:
+ * network byte order assumed. this means 192.5.5.240/28 has
+ * 0x11110000 in its fourth octet.
+ * author:
+ * Paul Vixie (ISC), July 1996
+ */
+static char *
+inet_net_ntop_ipv4(src, bits, dst, size)
+ const u_char *src;
+ int bits;
+ char *dst;
+ size_t size;
+{
+ char *odst = dst;
+ char *t;
+ u_int m;
+ int b;
+
+ if (bits < 0 || bits > 32) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ if (bits == 0) {
+ if (size < sizeof "0")
+ goto emsgsize;
+ *dst++ = '0';
+ *dst = '\0';
+ }
+
+ /* Format whole octets. */
+ for (b = bits / 8; b > 0; b--) {
+ if (size < sizeof "255.")
+ goto emsgsize;
+ t = dst;
+ dst += SPRINTF((dst, "%u", *src++));
+ if (b > 1) {
+ *dst++ = '.';
+ *dst = '\0';
+ }
+ size -= (size_t)(dst - t);
+ }
+
+ /* Format partial octet. */
+ b = bits % 8;
+ if (b > 0) {
+ if (size < sizeof ".255")
+ goto emsgsize;
+ t = dst;
+ if (dst != odst)
+ *dst++ = '.';
+ m = ((1 << b) - 1) << (8 - b);
+ dst += SPRINTF((dst, "%u", *src & m));
+ size -= (size_t)(dst - t);
+ }
+
+ /* Format CIDR /width. */
+ if (size < sizeof "/32")
+ goto emsgsize;
+ dst += SPRINTF((dst, "/%u", bits));
+ return (odst);
+
+ emsgsize:
+ errno = EMSGSIZE;
+ return (NULL);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_net_ntop
+__weak_reference(__inet_net_ntop, inet_net_ntop);
diff --git a/lib/libc/net/inet_net_pton.c b/lib/libc/net/inet_net_pton.c
new file mode 100644
index 0000000..04a45d4
--- /dev/null
+++ b/lib/libc/net/inet_net_pton.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char orig_rcsid[] = "From Id: inet_net_pton.c,v 1.8 1996/11/21 10:28:12 vixie Exp $";
+static const char rcsid[] = "$FreeBSD$";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+static int inet_net_pton_ipv4 __P((const char *src, u_char *dst,
+ size_t size));
+
+/*
+ * static int
+ * inet_net_pton(af, src, dst, size)
+ * convert network number from presentation to network format.
+ * accepts hex octets, hex strings, decimal octets, and /CIDR.
+ * "size" is in bytes and describes "dst".
+ * return:
+ * number of bits, either imputed classfully or specified with /CIDR,
+ * or -1 if some failure occurred (check errno). ENOENT means it was
+ * not a valid network specification.
+ * author:
+ * Paul Vixie (ISC), June 1996
+ */
+int
+inet_net_pton(af, src, dst, size)
+ int af;
+ const char *src;
+ void *dst;
+ size_t size;
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_net_pton_ipv4(src, dst, size));
+ default:
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+}
+
+/*
+ * static int
+ * inet_net_pton_ipv4(src, dst, size)
+ * convert IPv4 network number from presentation to network format.
+ * accepts hex octets, hex strings, decimal octets, and /CIDR.
+ * "size" is in bytes and describes "dst".
+ * return:
+ * number of bits, either imputed classfully or specified with /CIDR,
+ * or -1 if some failure occurred (check errno). ENOENT means it was
+ * not an IPv4 network specification.
+ * note:
+ * network byte order assumed. this means 192.5.5.240/28 has
+ * 0x11110000 in its fourth octet.
+ * author:
+ * Paul Vixie (ISC), June 1996
+ */
+static int
+inet_net_pton_ipv4(src, dst, size)
+ const char *src;
+ u_char *dst;
+ size_t size;
+{
+ static const char
+ xdigits[] = "0123456789abcdef",
+ digits[] = "0123456789";
+ int n, ch, tmp, dirty, bits;
+ const u_char *odst = dst;
+
+ ch = *src++;
+ if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
+ && isascii(src[1]) && isxdigit(src[1])) {
+ /* Hexadecimal: Eat nybble string. */
+ if (size <= 0)
+ goto emsgsize;
+ *dst = 0, dirty = 0;
+ src++; /* skip x or X. */
+ while ((ch = *src++) != '\0' &&
+ isascii(ch) && isxdigit(ch)) {
+ if (isupper(ch))
+ ch = tolower(ch);
+ n = strchr(xdigits, ch) - xdigits;
+ assert(n >= 0 && n <= 15);
+ *dst |= n;
+ if (!dirty++)
+ *dst <<= 4;
+ else if (size-- > 0)
+ *++dst = 0, dirty = 0;
+ else
+ goto emsgsize;
+ }
+ if (dirty)
+ size--;
+ } else if (isascii(ch) && isdigit(ch)) {
+ /* Decimal: eat dotted digit string. */
+ for (;;) {
+ tmp = 0;
+ do {
+ n = strchr(digits, ch) - digits;
+ assert(n >= 0 && n <= 9);
+ tmp *= 10;
+ tmp += n;
+ if (tmp > 255)
+ goto enoent;
+ } while ((ch = *src++) != '\0' &&
+ isascii(ch) && isdigit(ch));
+ if (size-- <= 0)
+ goto emsgsize;
+ *dst++ = (u_char) tmp;
+ if (ch == '\0' || ch == '/')
+ break;
+ if (ch != '.')
+ goto enoent;
+ ch = *src++;
+ if (!isascii(ch) || !isdigit(ch))
+ goto enoent;
+ }
+ } else
+ goto enoent;
+
+ bits = -1;
+ if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
+ /* CIDR width specifier. Nothing can follow it. */
+ ch = *src++; /* Skip over the /. */
+ bits = 0;
+ do {
+ n = strchr(digits, ch) - digits;
+ assert(n >= 0 && n <= 9);
+ bits *= 10;
+ bits += n;
+ } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
+ if (ch != '\0')
+ goto enoent;
+ if (bits > 32)
+ goto emsgsize;
+ }
+
+ /* Firey death and destruction unless we prefetched EOS. */
+ if (ch != '\0')
+ goto enoent;
+
+ /* If nothing was written to the destination, we found no address. */
+ if (dst == odst)
+ goto enoent;
+ /* If no CIDR spec was given, infer width from net class. */
+ if (bits == -1) {
+ if (*odst >= 240) /* Class E */
+ bits = 32;
+ else if (*odst >= 224) /* Class D */
+ bits = 4;
+ else if (*odst >= 192) /* Class C */
+ bits = 24;
+ else if (*odst >= 128) /* Class B */
+ bits = 16;
+ else /* Class A */
+ bits = 8;
+ /* If imputed mask is narrower than specified octets, widen. */
+ if (bits >= 8 && bits < ((dst - odst) * 8))
+ bits = (dst - odst) * 8;
+ }
+ /* Extend network to cover the actual mask. */
+ while (bits > ((dst - odst) * 8)) {
+ if (size-- <= 0)
+ goto emsgsize;
+ *dst++ = '\0';
+ }
+ return (bits);
+
+ enoent:
+ errno = ENOENT;
+ return (-1);
+
+ emsgsize:
+ errno = EMSGSIZE;
+ return (-1);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_net_pton
+__weak_reference(__inet_net_pton, inet_net_pton);
diff --git a/lib/libc/net/inet_neta.c b/lib/libc/net/inet_neta.c
new file mode 100644
index 0000000..2b8a84c
--- /dev/null
+++ b/lib/libc/net/inet_neta.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char orig_rcsid[] = "From Id: inet_neta.c,v 8.2 1996/08/08 06:54:44 vixie Exp";
+static const char rcsid[] = "$FreeBSD$";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/*
+ * char *
+ * inet_neta(src, dst, size)
+ * format a u_long network number into presentation format.
+ * return:
+ * pointer to dst, or NULL if an error occurred (check errno).
+ * note:
+ * format of ``src'' is as for inet_network().
+ * author:
+ * Paul Vixie (ISC), July 1996
+ */
+char *
+inet_neta(src, dst, size)
+ u_long src;
+ char *dst;
+ size_t size;
+{
+ char *odst = dst;
+ char *tp;
+
+ while (src & 0xffffffff) {
+ u_char b = (src & 0xff000000) >> 24;
+
+ src <<= 8;
+ if (b) {
+ if (size < sizeof "255.")
+ goto emsgsize;
+ tp = dst;
+ dst += SPRINTF((dst, "%u", b));
+ if (src != 0L) {
+ *dst++ = '.';
+ *dst = '\0';
+ }
+ size -= (size_t)(dst - tp);
+ }
+ }
+ if (dst == odst) {
+ if (size < sizeof "0.0.0.0")
+ goto emsgsize;
+ strcpy(dst, "0.0.0.0");
+ }
+ return (odst);
+
+ emsgsize:
+ errno = EMSGSIZE;
+ return (NULL);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_neta
+__weak_reference(__inet_neta, inet_neta);
diff --git a/lib/libc/net/inet_netof.c b/lib/libc/net/inet_netof.c
new file mode 100644
index 0000000..37063f7
--- /dev/null
+++ b/lib/libc/net/inet_netof.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*
+ * Return the network number from an internet
+ * address; handles class a/b/c network #'s.
+ */
+u_long
+inet_netof(in)
+ struct in_addr in;
+{
+ register u_long i = ntohl(in.s_addr);
+
+ if (IN_CLASSA(i))
+ return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
+ else if (IN_CLASSB(i))
+ return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
+ else
+ return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_netof
+__weak_reference(__inet_netof, inet_netof);
diff --git a/lib/libc/net/inet_network.c b/lib/libc/net/inet_network.c
new file mode 100644
index 0000000..e44257a
--- /dev/null
+++ b/lib/libc/net/inet_network.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+
+/*
+ * Internet network address interpretation routine.
+ * The library routines call this routine to interpret
+ * network numbers.
+ */
+u_long
+inet_network(cp)
+ register const char *cp;
+{
+ register u_long val, base, n, i;
+ register char c;
+ u_long parts[4], *pp = parts;
+
+again:
+ val = 0; base = 10;
+ if (*cp == '0')
+ base = 8, cp++;
+ if (*cp == 'x' || *cp == 'X')
+ base = 16, cp++;
+ while ((c = *cp) != 0) {
+ if (isdigit((unsigned char)c)) {
+ val = (val * base) + (c - '0');
+ cp++;
+ continue;
+ }
+ if (base == 16 && isxdigit((unsigned char)c)) {
+ val = (val << 4) + (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
+ cp++;
+ continue;
+ }
+ break;
+ }
+ if (*cp == '.') {
+ if (pp >= parts + 3)
+ return (INADDR_NONE);
+ *pp++ = val, cp++;
+ goto again;
+ }
+ if (*cp && !isspace((unsigned char)*cp))
+ return (INADDR_NONE);
+ *pp++ = val;
+ n = pp - parts;
+ for (val = 0, i = 0; i < n; i++) {
+ val <<= 8;
+ val |= parts[i] & 0xff;
+ }
+ return (val);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_network
+__weak_reference(__inet_network, inet_network);
diff --git a/lib/libc/net/inet_ntoa.c b/lib/libc/net/inet_ntoa.c
new file mode 100644
index 0000000..c210545
--- /dev/null
+++ b/lib/libc/net/inet_ntoa.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+
+/*
+ * Convert network-format internet address
+ * to base 256 d.d.d.d representation.
+ */
+char *
+inet_ntoa(in)
+ struct in_addr in;
+{
+ static char ret[18];
+
+ strcpy(ret, "[inet_ntoa error]");
+ (void) inet_ntop(AF_INET, &in, ret, sizeof ret);
+ return (ret);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_ntoa
+__weak_reference(__inet_ntoa, inet_ntoa);
diff --git a/lib/libc/net/inet_ntop.c b/lib/libc/net/inet_ntop.c
new file mode 100644
index 0000000..0b9449b
--- /dev/null
+++ b/lib/libc/net/inet_ntop.c
@@ -0,0 +1,198 @@
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#define SPRINTF(x) ((size_t)sprintf x)
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size));
+static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size));
+
+/* char *
+ * inet_ntop(af, src, dst, size)
+ * convert a network format address to presentation format.
+ * return:
+ * pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ * Paul Vixie, 1996.
+ */
+const char *
+inet_ntop(af, src, dst, size)
+ int af;
+ const void *src;
+ char *dst;
+ size_t size;
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_ntop4(src, dst, size));
+ case AF_INET6:
+ return (inet_ntop6(src, dst, size));
+ default:
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ * format an IPv4 address, more or less like inet_ntoa()
+ * return:
+ * `dst' (as a const)
+ * notes:
+ * (1) uses no statics
+ * (2) takes a u_char* not an in_addr as input
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(src, dst, size)
+ const u_char *src;
+ char *dst;
+ size_t size;
+{
+ static const char fmt[] = "%u.%u.%u.%u";
+ char tmp[sizeof "255.255.255.255"];
+
+ if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return (dst);
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ * convert IPv6 binary address into presentation (printable) format
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(src, dst, size)
+ const u_char *src;
+ char *dst;
+ size_t size;
+{
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+ struct { int base, len; } best, cur;
+ u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
+ int i;
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, '\0', sizeof words);
+ for (i = 0; i < NS_IN6ADDRSZ; i++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ cur.base = -1;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ } else {
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ /* Are we inside the best run of 0x00's? */
+ if (best.base != -1 && i >= best.base &&
+ i < (best.base + best.len)) {
+ if (i == best.base)
+ *tp++ = ':';
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0)
+ *tp++ = ':';
+ /* Is this address an encapsulated IPv4? */
+ if (i == 6 && best.base == 0 &&
+ (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+ if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
+ return (NULL);
+ tp += strlen(tp);
+ break;
+ }
+ tp += SPRINTF((tp, "%x", words[i]));
+ }
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 && (best.base + best.len) ==
+ (NS_IN6ADDRSZ / NS_INT16SZ))
+ *tp++ = ':';
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ((size_t)(tp - tmp) > size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return (dst);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_ntop
+__weak_reference(__inet_ntop, inet_ntop);
diff --git a/lib/libc/net/inet_pton.c b/lib/libc/net/inet_pton.c
new file mode 100644
index 0000000..488ac7f
--- /dev/null
+++ b/lib/libc/net/inet_pton.c
@@ -0,0 +1,221 @@
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <string.h>
+#include <errno.h>
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4 __P((const char *src, u_char *dst));
+static int inet_pton6 __P((const char *src, u_char *dst));
+
+/* int
+ * inet_pton(af, src, dst)
+ * convert from presentation format (which usually means ASCII printable)
+ * to network format (which is usually some kind of binary format).
+ * return:
+ * 1 if the address was valid for the specified address family
+ * 0 if the address wasn't valid (`dst' is untouched in this case)
+ * -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ * Paul Vixie, 1996.
+ */
+int
+inet_pton(af, src, dst)
+ int af;
+ const char *src;
+ void *dst;
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_pton4(src, dst));
+ case AF_INET6:
+ return (inet_pton6(src, dst));
+ default:
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+ /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ * like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ * 1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ * does not touch `dst' unless it's returning 1.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton4(src, dst)
+ const char *src;
+ u_char *dst;
+{
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ u_char tmp[NS_INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ u_int new = *tp * 10 + (pch - digits);
+
+ if (new > 255)
+ return (0);
+ *tp = new;
+ if (! saw_digit) {
+ if (++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return (0);
+ }
+ if (octets < 4)
+ return (0);
+
+ memcpy(dst, tmp, NS_INADDRSZ);
+ return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ * convert presentation level address to network order binary form.
+ * return:
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ * (1) does not touch `dst' unless it's returning 1.
+ * (2) :: in a full address is silently ignored.
+ * credit:
+ * inspired by Mark Andrews.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton6(src, dst)
+ const char *src;
+ u_char *dst;
+{
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, saw_xdigit;
+ u_int val;
+
+ memset((tp = tmp), '\0', NS_IN6ADDRSZ);
+ endp = tp + NS_IN6ADDRSZ;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if (*src == ':')
+ if (*++src != ':')
+ return (0);
+ curtok = src;
+ saw_xdigit = 0;
+ val = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (val > 0xffff)
+ return (0);
+ saw_xdigit = 1;
+ continue;
+ }
+ if (ch == ':') {
+ curtok = src;
+ if (!saw_xdigit) {
+ if (colonp)
+ return (0);
+ colonp = tp;
+ continue;
+ }
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ saw_xdigit = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+ inet_pton4(curtok, tp) > 0) {
+ tp += NS_INADDRSZ;
+ saw_xdigit = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ return (0);
+ }
+ if (saw_xdigit) {
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const int n = tp - colonp;
+ int i;
+
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp)
+ return (0);
+ memcpy(dst, tmp, NS_IN6ADDRSZ);
+ return (1);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_pton
+__weak_reference(__inet_pton, inet_pton);
diff --git a/lib/libc/net/ip6opt.c b/lib/libc/net/ip6opt.c
new file mode 100644
index 0000000..f9291b9
--- /dev/null
+++ b/lib/libc/net/ip6opt.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+
+#include <string.h>
+#include <stdio.h>
+
+static int ip6optlen(u_int8_t *opt, u_int8_t *lim);
+static void inet6_insert_padopt(u_char *p, int len);
+
+/*
+ * This function returns the number of bytes required to hold an option
+ * when it is stored as ancillary data, including the cmsghdr structure
+ * at the beginning, and any padding at the end (to make its size a
+ * multiple of 8 bytes). The argument is the size of the structure
+ * defining the option, which must include any pad bytes at the
+ * beginning (the value y in the alignment term "xn + y"), the type
+ * byte, the length byte, and the option data.
+ */
+int
+inet6_option_space(nbytes)
+ int nbytes;
+{
+ nbytes += 2; /* we need space for nxt-hdr and length fields */
+ return(CMSG_SPACE((nbytes + 7) & ~7));
+}
+
+/*
+ * This function is called once per ancillary data object that will
+ * contain either Hop-by-Hop or Destination options. It returns 0 on
+ * success or -1 on an error.
+ */
+int
+inet6_option_init(bp, cmsgp, type)
+ void *bp;
+ struct cmsghdr **cmsgp;
+ int type;
+{
+ register struct cmsghdr *ch = (struct cmsghdr *)bp;
+
+ /* argument validation */
+ if (type != IPV6_HOPOPTS && type != IPV6_DSTOPTS)
+ return(-1);
+
+ ch->cmsg_level = IPPROTO_IPV6;
+ ch->cmsg_type = type;
+ ch->cmsg_len = CMSG_LEN(0);
+
+ *cmsgp = ch;
+ return(0);
+}
+
+/*
+ * This function appends a Hop-by-Hop option or a Destination option
+ * into an ancillary data object that has been initialized by
+ * inet6_option_init(). This function returns 0 if it succeeds or -1 on
+ * an error.
+ * multx is the value x in the alignment term "xn + y" described
+ * earlier. It must have a value of 1, 2, 4, or 8.
+ * plusy is the value y in the alignment term "xn + y" described
+ * earlier. It must have a value between 0 and 7, inclusive.
+ */
+int
+inet6_option_append(cmsg, typep, multx, plusy)
+ struct cmsghdr *cmsg;
+ const u_int8_t *typep;
+ int multx;
+ int plusy;
+{
+ int padlen, optlen, off;
+ register u_char *bp = (u_char *)cmsg + cmsg->cmsg_len;
+ struct ip6_ext *eh = (struct ip6_ext *)CMSG_DATA(cmsg);
+
+ /* argument validation */
+ if (multx != 1 && multx != 2 && multx != 4 && multx != 8)
+ return(-1);
+ if (plusy < 0 || plusy > 7)
+ return(-1);
+ if (typep[0] > 255)
+ return(-1);
+
+ /*
+ * If this is the first option, allocate space for the
+ * first 2 bytes(for next header and length fields) of
+ * the option header.
+ */
+ if (bp == (u_char *)eh) {
+ bp += 2;
+ cmsg->cmsg_len += 2;
+ }
+
+ /* calculate pad length before the option. */
+ off = bp - (u_char *)eh;
+ padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) -
+ (off % multx);
+ padlen += plusy;
+ /* insert padding */
+ inet6_insert_padopt(bp, padlen);
+ cmsg->cmsg_len += padlen;
+ bp += padlen;
+
+ /* copy the option */
+ if (typep[0] == IP6OPT_PAD1)
+ optlen = 1;
+ else
+ optlen = typep[1] + 2;
+ memcpy(bp, typep, optlen);
+ bp += optlen;
+ cmsg->cmsg_len += optlen;
+
+ /* calculate pad length after the option and insert the padding */
+ off = bp - (u_char *)eh;
+ padlen = ((off + 7) & ~7) - off;
+ inet6_insert_padopt(bp, padlen);
+ bp += padlen;
+ cmsg->cmsg_len += padlen;
+
+ /* update the length field of the ip6 option header */
+ eh->ip6e_len = ((bp - (u_char *)eh) >> 3) - 1;
+
+ return(0);
+}
+
+/*
+ * This function appends a Hop-by-Hop option or a Destination option
+ * into an ancillary data object that has been initialized by
+ * inet6_option_init(). This function returns a pointer to the 8-bit
+ * option type field that starts the option on success, or NULL on an
+ * error.
+ * The difference between this function and inet6_option_append() is
+ * that the latter copies the contents of a previously built option into
+ * the ancillary data object while the current function returns a
+ * pointer to the space in the data object where the option's TLV must
+ * then be built by the caller.
+ *
+ */
+u_int8_t *
+inet6_option_alloc(cmsg, datalen, multx, plusy)
+ struct cmsghdr *cmsg;
+ int datalen;
+ int multx;
+ int plusy;
+{
+ int padlen, off;
+ register u_int8_t *bp = (u_char *)cmsg + cmsg->cmsg_len;
+ u_int8_t *retval;
+ struct ip6_ext *eh = (struct ip6_ext *)CMSG_DATA(cmsg);
+
+ /* argument validation */
+ if (multx != 1 && multx != 2 && multx != 4 && multx != 8)
+ return(NULL);
+ if (plusy < 0 || plusy > 7)
+ return(NULL);
+
+ /*
+ * If this is the first option, allocate space for the
+ * first 2 bytes(for next header and length fields) of
+ * the option header.
+ */
+ if (bp == (u_char *)eh) {
+ bp += 2;
+ cmsg->cmsg_len += 2;
+ }
+
+ /* calculate pad length before the option. */
+ off = bp - (u_char *)eh;
+ padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) -
+ (off % multx);
+ padlen += plusy;
+ /* insert padding */
+ inet6_insert_padopt(bp, padlen);
+ cmsg->cmsg_len += padlen;
+ bp += padlen;
+
+ /* keep space to store specified length of data */
+ retval = bp;
+ bp += datalen;
+ cmsg->cmsg_len += datalen;
+
+ /* calculate pad length after the option and insert the padding */
+ off = bp - (u_char *)eh;
+ padlen = ((off + 7) & ~7) - off;
+ inet6_insert_padopt(bp, padlen);
+ bp += padlen;
+ cmsg->cmsg_len += padlen;
+
+ /* update the length field of the ip6 option header */
+ eh->ip6e_len = ((bp - (u_char *)eh) >> 3) - 1;
+
+ return(retval);
+}
+
+/*
+ * This function processes the next Hop-by-Hop option or Destination
+ * option in an ancillary data object. If another option remains to be
+ * processed, the return value of the function is 0 and *tptrp points to
+ * the 8-bit option type field (which is followed by the 8-bit option
+ * data length, followed by the option data). If no more options remain
+ * to be processed, the return value is -1 and *tptrp is NULL. If an
+ * error occurs, the return value is -1 and *tptrp is not NULL.
+ * (RFC 2292, 6.3.5)
+ */
+int
+inet6_option_next(cmsg, tptrp)
+ const struct cmsghdr *cmsg;
+ u_int8_t **tptrp;
+{
+ struct ip6_ext *ip6e;
+ int hdrlen, optlen;
+ u_int8_t *lim;
+
+ if (cmsg->cmsg_level != IPPROTO_IPV6 ||
+ (cmsg->cmsg_type != IPV6_HOPOPTS &&
+ cmsg->cmsg_type != IPV6_DSTOPTS))
+ return(-1);
+
+ /* message length validation */
+ if (cmsg->cmsg_len < CMSG_SPACE(sizeof(struct ip6_ext)))
+ return(-1);
+ ip6e = (struct ip6_ext *)CMSG_DATA(cmsg);
+ hdrlen = (ip6e->ip6e_len + 1) << 3;
+ if (cmsg->cmsg_len < CMSG_SPACE(hdrlen))
+ return(-1);
+
+ /*
+ * If the caller does not specify the starting point,
+ * simply return the 1st option.
+ * Otherwise, search the option list for the next option.
+ */
+ lim = (u_int8_t *)ip6e + hdrlen;
+ if (*tptrp == NULL)
+ *tptrp = (u_int8_t *)(ip6e + 1);
+ else {
+ if ((optlen = ip6optlen(*tptrp, lim)) == 0)
+ return(-1);
+
+ *tptrp = *tptrp + optlen;
+ }
+ if (*tptrp >= lim) { /* there is no option */
+ *tptrp = NULL;
+ return(-1);
+ }
+ /*
+ * Finally, checks if the next option is safely stored in the
+ * cmsg data.
+ */
+ if (ip6optlen(*tptrp, lim) == 0)
+ return(-1);
+ else
+ return(0);
+}
+
+/*
+ * This function is similar to the inet6_option_next() function,
+ * except this function lets the caller specify the option type to be
+ * searched for, instead of always returning the next option in the
+ * ancillary data object.
+ * Note: RFC 2292 says the type of tptrp is u_int8_t *, but we think
+ * it's a typo. The variable should be type of u_int8_t **.
+ */
+int
+inet6_option_find(cmsg, tptrp, type)
+ const struct cmsghdr *cmsg;
+ u_int8_t **tptrp;
+ int type;
+{
+ struct ip6_ext *ip6e;
+ int hdrlen, optlen;
+ u_int8_t *optp, *lim;
+
+ if (cmsg->cmsg_level != IPPROTO_IPV6 ||
+ (cmsg->cmsg_type != IPV6_HOPOPTS &&
+ cmsg->cmsg_type != IPV6_DSTOPTS))
+ return(-1);
+
+ /* message length validation */
+ if (cmsg->cmsg_len < CMSG_SPACE(sizeof(struct ip6_ext)))
+ return(-1);
+ ip6e = (struct ip6_ext *)CMSG_DATA(cmsg);
+ hdrlen = (ip6e->ip6e_len + 1) << 3;
+ if (cmsg->cmsg_len < CMSG_SPACE(hdrlen))
+ return(-1);
+
+ /*
+ * If the caller does not specify the starting point,
+ * search from the beginning of the option list.
+ * Otherwise, search from *the next option* of the specified point.
+ */
+ lim = (u_int8_t *)ip6e + hdrlen;
+ if (*tptrp == NULL)
+ *tptrp = (u_int8_t *)(ip6e + 1);
+ else {
+ if ((optlen = ip6optlen(*tptrp, lim)) == 0)
+ return(-1);
+
+ *tptrp = *tptrp + optlen;
+ }
+ for (optp = *tptrp; optp < lim; optp += optlen) {
+ if (*optp == type) {
+ *tptrp = optp;
+ return(0);
+ }
+ if ((optlen = ip6optlen(optp, lim)) == 0)
+ return(-1);
+ }
+
+ /* search failed */
+ *tptrp = NULL;
+ return(-1);
+}
+
+/*
+ * Calculate the length of a given IPv6 option. Also checks
+ * if the option is safely stored in user's buffer according to the
+ * calculated length and the limitation of the buffer.
+ */
+static int
+ip6optlen(opt, lim)
+ u_int8_t *opt, *lim;
+{
+ int optlen;
+
+ if (*opt == IP6OPT_PAD1)
+ optlen = 1;
+ else {
+ /* is there enough space to store type and len? */
+ if (opt + 2 > lim)
+ return(0);
+ optlen = *(opt + 1) + 2;
+ }
+ if (opt + optlen <= lim)
+ return(optlen);
+
+ return(0);
+}
+
+static void
+inet6_insert_padopt(u_char *p, int len)
+{
+ switch(len) {
+ case 0:
+ return;
+ case 1:
+ p[0] = IP6OPT_PAD1;
+ return;
+ default:
+ p[0] = IP6OPT_PADN;
+ p[1] = len - 2;
+ memset(&p[2], 0, len - 2);
+ return;
+ }
+}
diff --git a/lib/libc/net/iso_addr.3 b/lib/libc/net/iso_addr.3
new file mode 100644
index 0000000..ad49778
--- /dev/null
+++ b/lib/libc/net/iso_addr.3
@@ -0,0 +1,111 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)iso_addr.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ISO_ADDR 3
+.Os
+.Sh NAME
+.Nm iso_addr ,
+.Nm iso_ntoa
+.Nd "elementary network address conversion routines for Open System Interconnection
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <netiso/iso.h>
+.Ft struct iso_addr *
+.Fn iso_addr "char *cp"
+.Ft char *
+.Fn iso_ntoa "struct iso_addr *isoa"
+.Sh DESCRIPTION
+The routine
+.Fn iso_addr
+interprets character strings representing
+.Tn OSI
+addresses, returning binary information suitable
+for use in system calls.
+The routine
+.Fn iso_ntoa
+takes
+.Tn OSI
+addresses and returns
+.Tn ASCII
+strings representing NSAPs (network service
+access points) in a
+notation inverse to that accepted by
+.Fn iso_addr .
+.Pp
+Unfortunately, no universal standard exists for representing
+.Tn OSI
+network addresses.
+.Pp
+The format employed by
+.Fn iso_addr
+is a sequence of hexadecimal
+.Dq digits
+(optionally separated by periods),
+of the form:
+.Bd -filled -offset indent
+<hex digits>.<hex digits>.<hex digits>
+.Ed
+.Pp
+Each pair of hexadecimal digits represents a byte
+with the leading digit indicating the higher-ordered bits.
+A period following an even number of bytes has no
+effect (but may be used to increase legibility).
+A period following an odd number of bytes has the
+effect of causing the byte of address being translated
+to have its higher order bits filled with zeros.
+.Sh RETURN VALUES
+.Fn iso_ntoa
+always returns a null terminated string.
+.Fn iso_addr
+always returns a pointer to a struct iso_addr.
+(See
+.Sx BUGS . )
+.Sh SEE ALSO
+.Xr iso 4
+.Sh HISTORY
+The
+.Fn iso_addr
+and
+.Fn iso_ntoa
+functions appeared in
+.Bx 4.3 Reno .
+.Sh BUGS
+The returned values
+reside in a static memory area.
+.Pp
+The function
+.Fn iso_addr
+should diagnose improperly formed input, and there should be an unambiguous
+way to recognize this.
diff --git a/lib/libc/net/iso_addr.c b/lib/libc/net/iso_addr.c
new file mode 100644
index 0000000..8829497
--- /dev/null
+++ b/lib/libc/net/iso_addr.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)iso_addr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <netiso/iso.h>
+#include <string.h>
+
+/* States*/
+#define VIRGIN 0
+#define GOTONE 1
+#define GOTTWO 2
+/* Inputs */
+#define DIGIT (4*0)
+#define END (4*1)
+#define DELIM (4*2)
+
+struct iso_addr *
+iso_addr(addr)
+ register const char *addr;
+{
+ static struct iso_addr out_addr;
+ register char *cp = out_addr.isoa_genaddr;
+ char *cplim = cp + sizeof(out_addr.isoa_genaddr);
+ register int byte = 0, state = VIRGIN, new;
+
+ bzero((char *)&out_addr, sizeof(out_addr));
+ do {
+ if ((*addr >= '0') && (*addr <= '9')) {
+ new = *addr - '0';
+ } else if ((*addr >= 'a') && (*addr <= 'f')) {
+ new = *addr - 'a' + 10;
+ } else if ((*addr >= 'A') && (*addr <= 'F')) {
+ new = *addr - 'A' + 10;
+ } else if (*addr == 0)
+ state |= END;
+ else
+ state |= DELIM;
+ addr++;
+ switch (state /* | INPUT */) {
+ case GOTTWO | DIGIT:
+ *cp++ = byte; /*FALLTHROUGH*/
+ case VIRGIN | DIGIT:
+ state = GOTONE; byte = new; continue;
+ case GOTONE | DIGIT:
+ state = GOTTWO; byte = new + (byte << 4); continue;
+ default: /* | DELIM */
+ state = VIRGIN; *cp++ = byte; byte = 0; continue;
+ case GOTONE | END:
+ case GOTTWO | END:
+ *cp++ = byte; /* FALLTHROUGH */
+ case VIRGIN | END:
+ break;
+ }
+ break;
+ } while (cp < cplim);
+ out_addr.isoa_len = cp - out_addr.isoa_genaddr;
+ return (&out_addr);
+}
+
+static char hexlist[] = "0123456789abcdef";
+
+char *
+iso_ntoa(isoa)
+ const struct iso_addr *isoa;
+{
+ static char tmpbuf[sizeof(isoa->isoa_genaddr)*3];
+ const u_char *binary;
+ char *cp;
+ int i;
+
+ binary = isoa->isoa_genaddr;
+ cp = tmpbuf;
+
+ for (i = 0; i < isoa->isoa_len; i++) {
+ *cp++ = hexlist[*binary >> 4];
+ *cp++ = hexlist[*binary++ & 0xf];
+
+ if ((((i % 2) == 0) && ((i + 1) < isoa->isoa_len)))
+ *cp++ = '.';
+ }
+ *cp = '\0';
+ return tmpbuf;
+}
diff --git a/lib/libc/net/linkaddr.3 b/lib/libc/net/linkaddr.3
new file mode 100644
index 0000000..543e040
--- /dev/null
+++ b/lib/libc/net/linkaddr.3
@@ -0,0 +1,138 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Donn Seeley at BSDI.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)linkaddr.3 8.1 (Berkeley) 7/28/93
+.\" $FreeBSD$
+.\"
+.Dd June 17, 1996
+.Dt LINK_ADDR 3
+.Os BSD 4.4
+.Sh NAME
+.Nm link_addr ,
+.Nm link_ntoa
+.Nd elementary address specification routines for link level access
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Fd #include <net/if_dl.h>
+.Ft void
+.Fn link_addr "const char *addr" "struct sockaddr_dl *sdl"
+.Ft char *
+.Fn link_ntoa "const struct sockaddr_dl *sdl"
+.Sh DESCRIPTION
+The routine
+.Fn link_addr
+interprets character strings representing
+link-level addresses, returning binary information suitable
+for use in system calls.
+The routine
+.Fn link_ntoa
+takes
+a link-level
+address and returns an
+.Tn ASCII
+string representing some of the information present,
+including the link level address itself, and the interface name
+or number, if present.
+This facility is experimental and is
+still subject to change.
+.Pp
+For
+.Fn link_addr ,
+the string
+.Fa addr
+may contain
+an optional network interface identifier of the form
+.Dq "name unit-number" ,
+suitable for the first argument to
+.Xr ifconfig 8 ,
+followed in all cases by a colon and
+an interface address in the form of
+groups of hexadecimal digits
+separated by periods.
+Each group represents a byte of address;
+address bytes are filled left to right from
+low order bytes through high order bytes.
+.Pp
+.\" A regular expression may make this format clearer:
+.\" .Bd -literal -offset indent
+.\" ([a-z]+[0-9]+:)?[0-9a-f]+(\e.[0-9a-f]+)*
+.\" .Ed
+.\" .Pp
+Thus
+.Li le0:8.0.9.13.d.30
+represents an ethernet address
+to be transmitted on the first Lance ethernet interface.
+.Pp
+The direct use of these functions is deprecated in favor of the
+.Xr addr2ascii 3
+interface; however, portable programs cannot rely on the latter as it is
+not yet widely implemented.
+.Sh RETURN VALUES
+.Fn link_ntoa
+always returns a null terminated string.
+.Fn link_addr
+has no return value.
+(See
+.Sx BUGS . )
+.Sh SEE ALSO
+.Xr addr2ascii 3
+.\" .Xr iso 4
+.Sh HISTORY
+The
+.Fn link_addr
+and
+.Fn link_ntoa
+functions appeared in
+.Bx 4.3 Reno .
+.Sh BUGS
+The returned values for link_ntoa
+reside in a static memory area.
+.Pp
+The function
+.Fn link_addr
+should diagnose improperly formed input, and there should be an unambiguous
+way to recognize this.
+.Pp
+If the
+.Va sdl_len
+field of the link socket address
+.Fa sdl
+is 0,
+.Fn link_ntoa
+will not insert a colon before the interface address bytes.
+If this translated address is given to
+.Fn link_addr
+without inserting an initial colon,
+the latter will not interpret it correctly.
diff --git a/lib/libc/net/linkaddr.c b/lib/libc/net/linkaddr.c
new file mode 100644
index 0000000..68eed3d
--- /dev/null
+++ b/lib/libc/net/linkaddr.c
@@ -0,0 +1,158 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if_dl.h>
+#include <string.h>
+
+/* States*/
+#define NAMING 0
+#define GOTONE 1
+#define GOTTWO 2
+#define RESET 3
+/* Inputs */
+#define DIGIT (4*0)
+#define END (4*1)
+#define DELIM (4*2)
+#define LETTER (4*3)
+
+void
+link_addr(addr, sdl)
+ register const char *addr;
+ register struct sockaddr_dl *sdl;
+{
+ register char *cp = sdl->sdl_data;
+ char *cplim = sdl->sdl_len + (char *)sdl;
+ register int byte = 0, state = NAMING, new;
+
+ bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1);
+ sdl->sdl_family = AF_LINK;
+ do {
+ state &= ~LETTER;
+ if ((*addr >= '0') && (*addr <= '9')) {
+ new = *addr - '0';
+ } else if ((*addr >= 'a') && (*addr <= 'f')) {
+ new = *addr - 'a' + 10;
+ } else if ((*addr >= 'A') && (*addr <= 'F')) {
+ new = *addr - 'A' + 10;
+ } else if (*addr == 0) {
+ state |= END;
+ } else if (state == NAMING &&
+ (((*addr >= 'A') && (*addr <= 'Z')) ||
+ ((*addr >= 'a') && (*addr <= 'z'))))
+ state |= LETTER;
+ else
+ state |= DELIM;
+ addr++;
+ switch (state /* | INPUT */) {
+ case NAMING | DIGIT:
+ case NAMING | LETTER:
+ *cp++ = addr[-1];
+ continue;
+ case NAMING | DELIM:
+ state = RESET;
+ sdl->sdl_nlen = cp - sdl->sdl_data;
+ continue;
+ case GOTTWO | DIGIT:
+ *cp++ = byte;
+ /* FALLTHROUGH */
+ case RESET | DIGIT:
+ state = GOTONE;
+ byte = new;
+ continue;
+ case GOTONE | DIGIT:
+ state = GOTTWO;
+ byte = new + (byte << 4);
+ continue;
+ default: /* | DELIM */
+ state = RESET;
+ *cp++ = byte;
+ byte = 0;
+ continue;
+ case GOTONE | END:
+ case GOTTWO | END:
+ *cp++ = byte;
+ /* FALLTHROUGH */
+ case RESET | END:
+ break;
+ }
+ break;
+ } while (cp < cplim);
+ sdl->sdl_alen = cp - LLADDR(sdl);
+ new = cp - (char *)sdl;
+ if (new > sizeof(*sdl))
+ sdl->sdl_len = new;
+ return;
+}
+
+static char hexlist[] = "0123456789abcdef";
+
+char *
+link_ntoa(sdl)
+ register const struct sockaddr_dl *sdl;
+{
+ static char obuf[64];
+ register char *out = obuf;
+ register int i;
+ register u_char *in = (u_char *)LLADDR(sdl);
+ u_char *inlim = in + sdl->sdl_alen;
+ int firsttime = 1;
+
+ if (sdl->sdl_nlen) {
+ bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen);
+ out += sdl->sdl_nlen;
+ if (sdl->sdl_alen)
+ *out++ = ':';
+ }
+ while (in < inlim) {
+ if (firsttime)
+ firsttime = 0;
+ else
+ *out++ = '.';
+ i = *in++;
+ if (i > 0xf) {
+ out[1] = hexlist[i & 0xf];
+ i >>= 4;
+ out[0] = hexlist[i];
+ out += 2;
+ } else
+ *out++ = hexlist[i];
+ }
+ *out = 0;
+ return (obuf);
+}
diff --git a/lib/libc/net/map_v4v6.c b/lib/libc/net/map_v4v6.c
new file mode 100644
index 0000000..ca5e553
--- /dev/null
+++ b/lib/libc/net/map_v4v6.c
@@ -0,0 +1,128 @@
+/*
+ * ++Copyright++ 1985, 1988, 1993
+ * -
+ * Copyright (c) 1985, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#include <syslog.h>
+
+typedef union {
+ int32_t al;
+ char ac;
+} align;
+
+void
+_map_v4v6_address(src, dst)
+ const char *src;
+ char *dst;
+{
+ u_char *p = (u_char *)dst;
+ char tmp[INADDRSZ];
+ int i;
+
+ /* Stash a temporary copy so our caller can update in place. */
+ bcopy(src, tmp, INADDRSZ);
+ /* Mark this ipv6 addr as a mapped ipv4. */
+ for (i = 0; i < 10; i++)
+ *p++ = 0x00;
+ *p++ = 0xff;
+ *p++ = 0xff;
+ /* Retrieve the saved copy and we're done. */
+ bcopy(tmp, (void*)p, INADDRSZ);
+}
+
+void
+_map_v4v6_hostent(hp, bpp, lenp)
+ struct hostent *hp;
+ char **bpp;
+ int *lenp;
+{
+ char **ap;
+
+ if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
+ return;
+ hp->h_addrtype = AF_INET6;
+ hp->h_length = IN6ADDRSZ;
+ for (ap = hp->h_addr_list; *ap; ap++) {
+ int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
+
+ if (*lenp < (i + IN6ADDRSZ)) {
+ /* Out of memory. Truncate address list here. XXX */
+ *ap = NULL;
+ return;
+ }
+ *bpp += i;
+ *lenp -= i;
+ _map_v4v6_address(*ap, *bpp);
+ *ap = *bpp;
+ *bpp += IN6ADDRSZ;
+ *lenp -= IN6ADDRSZ;
+ }
+}
diff --git a/lib/libc/net/ns.3 b/lib/libc/net/ns.3
new file mode 100644
index 0000000..6e697f9
--- /dev/null
+++ b/lib/libc/net/ns.3
@@ -0,0 +1,131 @@
+.\" Copyright (c) 1986, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ns.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt NS 3
+.Os BSD 4.3
+.Sh NAME
+.Nm ns_addr ,
+.Nm ns_ntoa
+.Nd Xerox
+.Tn NS Ns (tm)
+address conversion routines
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <netns/ns.h>
+.Ft struct ns_addr
+.Fn ns_addr "char *cp"
+.Ft char *
+.Fn ns_ntoa "struct ns_addr ns"
+.Sh DESCRIPTION
+The routine
+.Fn ns_addr
+interprets character strings representing
+.Tn XNS
+addresses, returning binary information suitable
+for use in system calls.
+The routine
+.Fn ns_ntoa
+takes
+.Tn XNS
+addresses and returns
+.Tn ASCII
+strings representing the address in a
+notation in common use in the Xerox Development Environment:
+.Bd -filled -offset indent
+<network number>.<host number>.<port number>
+.Ed
+.Pp
+Trailing zero fields are suppressed, and each number is printed in hexadecimal,
+in a format suitable for input to
+.Fn ns_addr .
+Any fields lacking super-decimal digits will have a
+trailing
+.Ql H
+appended.
+.Pp
+Unfortunately, no universal standard exists for representing
+.Tn XNS
+addresses.
+An effort has been made to insure that
+.Fn ns_addr
+be compatible with most formats in common use.
+It will first separate an address into 1 to 3 fields using a single delimiter
+chosen from
+period
+.Ql \&. ,
+colon
+.Ql \&:
+or pound-sign
+.Ql \&# .
+Each field is then examined for byte separators (colon or period).
+If there are byte separators, each subfield separated is taken to be
+a small hexadecimal number, and the entirety is taken as a network-byte-ordered
+quantity to be zero extended in the high-network-order bytes.
+Next, the field is inspected for hyphens, in which case
+the field is assumed to be a number in decimal notation
+with hyphens separating the millenia.
+Next, the field is assumed to be a number:
+It is interpreted
+as hexadecimal if there is a leading
+.Ql 0x
+(as in C),
+a trailing
+.Ql H
+(as in Mesa), or there are any super-decimal digits present.
+It is interpreted as octal is there is a leading
+.Ql 0
+and there are no super-octal digits.
+Otherwise, it is converted as a decimal number.
+.Sh RETURN VALUES
+None. (See
+.Sx BUGS . )
+.Sh SEE ALSO
+.Xr hosts 5 ,
+.Xr networks 5
+.Sh HISTORY
+The
+.Fn ns_addr
+and
+.Fn ns_toa
+functions appeared in
+.Bx 4.3 .
+.Sh BUGS
+The string returned by
+.Fn ns_ntoa
+resides in a static memory area.
+The function
+.Fn ns_addr
+should diagnose improperly formed input, and there should be an unambiguous
+way to recognize this.
diff --git a/lib/libc/net/ns_addr.c b/lib/libc/net/ns_addr.c
new file mode 100644
index 0000000..3446e08
--- /dev/null
+++ b/lib/libc/net/ns_addr.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * J.Q. Johnson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ns_addr.c 8.1 (Berkeley) 6/7/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netns/ns.h>
+#include <stdio.h>
+#include <string.h>
+
+static struct ns_addr addr, zero_addr;
+
+static void Field(), cvtbase();
+
+struct ns_addr
+ns_addr(name)
+ const char *name;
+{
+ char separator;
+ char *hostname, *socketname, *cp;
+ char buf[50];
+
+ (void)strncpy(buf, name, sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+
+ /*
+ * First, figure out what he intends as a field separtor.
+ * Despite the way this routine is written, the prefered
+ * form 2-272.AA001234H.01777, i.e. XDE standard.
+ * Great efforts are made to insure backward compatability.
+ */
+ if ((hostname = strchr(buf, '#')) != NULL)
+ separator = '#';
+ else {
+ hostname = strchr(buf, '.');
+ if ((cp = strchr(buf, ':')) &&
+ ((hostname && cp < hostname) || (hostname == 0))) {
+ hostname = cp;
+ separator = ':';
+ } else
+ separator = '.';
+ }
+ if (hostname)
+ *hostname++ = 0;
+
+ addr = zero_addr;
+ Field(buf, addr.x_net.c_net, 4);
+ if (hostname == 0)
+ return (addr); /* No separator means net only */
+
+ socketname = strchr(hostname, separator);
+ if (socketname) {
+ *socketname++ = 0;
+ Field(socketname, (u_char *)&addr.x_port, 2);
+ }
+
+ Field(hostname, addr.x_host.c_host, 6);
+
+ return (addr);
+}
+
+static void
+Field(buf, out, len)
+ char *buf;
+ u_char *out;
+ int len;
+{
+ register char *bp = buf;
+ int i, ibase, base16 = 0, base10 = 0, clen = 0;
+ int hb[6], *hp;
+ char *fmt;
+
+ /*
+ * first try 2-273#2-852-151-014#socket
+ */
+ if ((*buf != '-') &&
+ (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
+ &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
+ cvtbase(1000L, 256, hb, i, out, len);
+ return;
+ }
+ /*
+ * try form 8E1#0.0.AA.0.5E.E6#socket
+ */
+ if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
+ &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
+ cvtbase(256L, 256, hb, i, out, len);
+ return;
+ }
+ /*
+ * try form 8E1#0:0:AA:0:5E:E6#socket
+ */
+ if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
+ &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
+ cvtbase(256L, 256, hb, i, out, len);
+ return;
+ }
+ /*
+ * This is REALLY stretching it but there was a
+ * comma notation separting shorts -- definitely non standard
+ */
+ if (1 < (i = sscanf(buf,"%x,%x,%x",
+ &hb[0], &hb[1], &hb[2]))) {
+ hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
+ hb[2] = htons(hb[2]);
+ cvtbase(65536L, 256, hb, i, out, len);
+ return;
+ }
+
+ /* Need to decide if base 10, 16 or 8 */
+ while (*bp) switch (*bp++) {
+
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '-':
+ break;
+
+ case '8': case '9':
+ base10 = 1;
+ break;
+
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ base16 = 1;
+ break;
+
+ case 'x': case 'X':
+ *--bp = '0';
+ base16 = 1;
+ break;
+
+ case 'h': case 'H':
+ base16 = 1;
+ /* fall into */
+
+ default:
+ *--bp = 0; /* Ends Loop */
+ }
+ if (base16) {
+ fmt = "%3x";
+ ibase = 4096;
+ } else if (base10 == 0 && *buf == '0') {
+ fmt = "%3o";
+ ibase = 512;
+ } else {
+ fmt = "%3d";
+ ibase = 1000;
+ }
+
+ for (bp = buf; *bp++; ) clen++;
+ if (clen == 0) clen++;
+ if (clen > 18) clen = 18;
+ i = ((clen - 1) / 3) + 1;
+ bp = clen + buf - 3;
+ hp = hb + i - 1;
+
+ while (hp > hb) {
+ (void)sscanf(bp, fmt, hp);
+ bp[0] = 0;
+ hp--;
+ bp -= 3;
+ }
+ (void)sscanf(buf, fmt, hp);
+ cvtbase((long)ibase, 256, hb, i, out, len);
+}
+
+static void
+cvtbase(oldbase,newbase,input,inlen,result,reslen)
+ long oldbase;
+ int newbase;
+ int input[];
+ int inlen;
+ unsigned char result[];
+ int reslen;
+{
+ int d, e;
+ long sum;
+
+ e = 1;
+ while (e > 0 && reslen > 0) {
+ d = 0; e = 0; sum = 0;
+ /* long division: input=input/newbase */
+ while (d < inlen) {
+ sum = sum*oldbase + (long) input[d];
+ e += (sum > 0);
+ input[d++] = sum / newbase;
+ sum %= newbase;
+ }
+ result[--reslen] = sum; /* accumulate remainder */
+ }
+ for (d=0; d < reslen; d++)
+ result[d] = 0;
+}
diff --git a/lib/libc/net/ns_name.c b/lib/libc/net/ns_name.c
new file mode 100644
index 0000000..cbaf7bd
--- /dev/null
+++ b/lib/libc/net/ns_name.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <errno.h>
+#include <resolv.h>
+#include <string.h>
+
+/* Data. */
+
+static char digits[] = "0123456789";
+
+/* Forward. */
+
+static int special(int);
+static int printable(int);
+static int dn_find(const u_char *, const u_char *,
+ const u_char * const *,
+ const u_char * const *);
+
+/* Public. */
+
+/*
+ * ns_name_ntop(src, dst, dstsiz)
+ * Convert an encoded domain name to printable ascii as per RFC1035.
+ * return:
+ * Number of bytes written to buffer, or -1 (with errno set)
+ * notes:
+ * The root is returned as "."
+ * All other domains are returned in non absolute form
+ */
+int
+ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
+ const u_char *cp;
+ char *dn, *eom;
+ u_char c;
+ u_int n;
+
+ cp = src;
+ dn = dst;
+ eom = dst + dstsiz;
+
+ while ((n = *cp++) != 0) {
+ if ((n & NS_CMPRSFLGS) != 0) {
+ /* Some kind of compression pointer. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (dn != dst) {
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '.';
+ }
+ if (dn + n >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ for ((void)NULL; n > 0; n--) {
+ c = *cp++;
+ if (special(c)) {
+ if (dn + 1 >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '\\';
+ *dn++ = (char)c;
+ } else if (!printable(c)) {
+ if (dn + 3 >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '\\';
+ *dn++ = digits[c / 100];
+ *dn++ = digits[(c % 100) / 10];
+ *dn++ = digits[c % 10];
+ } else {
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = (char)c;
+ }
+ }
+ }
+ if (dn == dst) {
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '.';
+ }
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '\0';
+ return (dn - dst);
+}
+
+/*
+ * ns_name_pton(src, dst, dstsiz)
+ * Convert a ascii string into an encoded domain name as per RFC1035.
+ * return:
+ * -1 if it fails
+ * 1 if string was fully qualified
+ * 0 is string was not fully qualified
+ * notes:
+ * Enforces label and domain length limits.
+ */
+
+int
+ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
+ u_char *label, *bp, *eom;
+ int c, n, escaped;
+ char *cp;
+
+ escaped = 0;
+ bp = dst;
+ eom = dst + dstsiz;
+ label = bp++;
+
+ while ((c = *src++) != 0) {
+ if (escaped) {
+ if ((cp = strchr(digits, c)) != NULL) {
+ n = (cp - digits) * 100;
+ if ((c = *src++) == 0 ||
+ (cp = strchr(digits, c)) == NULL) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ n += (cp - digits) * 10;
+ if ((c = *src++) == 0 ||
+ (cp = strchr(digits, c)) == NULL) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ n += (cp - digits);
+ if (n > 255) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ c = n;
+ }
+ escaped = 0;
+ } else if (c == '\\') {
+ escaped = 1;
+ continue;
+ } else if (c == '.') {
+ c = (bp - label - 1);
+ if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (label >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *label = c;
+ /* Fully qualified ? */
+ if (*src == '\0') {
+ if (c != 0) {
+ if (bp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *bp++ = '\0';
+ }
+ if ((bp - dst) > MAXCDNAME) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ return (1);
+ }
+ if (c == 0) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ label = bp++;
+ continue;
+ }
+ if (bp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *bp++ = (u_char)c;
+ }
+ c = (bp - label - 1);
+ if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (label >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *label = c;
+ if (c != 0) {
+ if (bp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *bp++ = 0;
+ }
+ if ((bp - dst) > MAXCDNAME) { /* src too big */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * ns_name_unpack(msg, eom, src, dst, dstsiz)
+ * Unpack a domain name from a message, source may be compressed.
+ * return:
+ * -1 if it fails, or consumed octets if it succeeds.
+ */
+int
+ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
+ u_char *dst, size_t dstsiz)
+{
+ const u_char *srcp, *dstlim;
+ u_char *dstp;
+ int n, c, len, checked;
+
+ len = -1;
+ checked = 0;
+ dstp = dst;
+ srcp = src;
+ dstlim = dst + dstsiz;
+ if (srcp < msg || srcp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ /* Fetch next label in domain name. */
+ while ((n = *srcp++) != 0) {
+ /* Check for indirection. */
+ switch (n & NS_CMPRSFLGS) {
+ case 0:
+ /* Limit checks. */
+ if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ checked += n + 1;
+ *dstp++ = n;
+ memcpy(dstp, srcp, n);
+ dstp += n;
+ srcp += n;
+ break;
+
+ case NS_CMPRSFLGS:
+ if (srcp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (len < 0)
+ len = srcp - src + 1;
+ srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
+ if (srcp < msg || srcp >= eom) { /* Out of range. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ checked += 2;
+ /*
+ * Check for loops in the compressed name;
+ * if we've looked at the whole message,
+ * there must be a loop.
+ */
+ if (checked >= eom - msg) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ break;
+
+ default:
+ errno = EMSGSIZE;
+ return (-1); /* flag error */
+ }
+ }
+ *dstp = '\0';
+ if (len < 0)
+ len = srcp - src;
+ return (len);
+}
+
+/*
+ * ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
+ * Pack domain name 'domain' into 'comp_dn'.
+ * return:
+ * Size of the compressed name, or -1.
+ * notes:
+ * 'dnptrs' is an array of pointers to previous compressed names.
+ * dnptrs[0] is a pointer to the beginning of the message. The array
+ * ends with NULL.
+ * 'lastdnptr' is a pointer to the end of the array pointed to
+ * by 'dnptrs'.
+ * Side effects:
+ * The list of pointers in dnptrs is updated for labels inserted into
+ * the message as we compress the name. If 'dnptr' is NULL, we don't
+ * try to compress names. If 'lastdnptr' is NULL, we don't update the
+ * list.
+ */
+int
+ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
+ const u_char **dnptrs, const u_char **lastdnptr)
+{
+ u_char *dstp;
+ const u_char **cpp, **lpp, *eob, *msg;
+ const u_char *srcp;
+ int n, l;
+
+ srcp = src;
+ dstp = dst;
+ eob = dstp + dstsiz;
+ lpp = cpp = NULL;
+ if (dnptrs != NULL) {
+ if ((msg = *dnptrs++) != NULL) {
+ for (cpp = dnptrs; *cpp != NULL; cpp++)
+ (void)NULL;
+ lpp = cpp; /* end of list to search */
+ }
+ } else
+ msg = NULL;
+
+ /* make sure the domain we are about to add is legal */
+ l = 0;
+ do {
+ n = *srcp;
+ if ((n & NS_CMPRSFLGS) != 0) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ l += n + 1;
+ if (l > MAXCDNAME) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ srcp += n + 1;
+ } while (n != 0);
+
+ srcp = src;
+ do {
+ /* Look to see if we can use pointers. */
+ n = *srcp;
+ if (n != 0 && msg != NULL) {
+ l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
+ (const u_char * const *)lpp);
+ if (l >= 0) {
+ if (dstp + 1 >= eob) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dstp++ = (l >> 8) | NS_CMPRSFLGS;
+ *dstp++ = l % 256;
+ return (dstp - dst);
+ }
+ /* Not found, save it. */
+ if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
+ (dstp - msg) < 0x4000) {
+ *cpp++ = dstp;
+ *cpp = NULL;
+ }
+ }
+ /* copy label to buffer */
+ if (n & NS_CMPRSFLGS) { /* Should not happen. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (dstp + 1 + n >= eob) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ memcpy(dstp, srcp, n + 1);
+ srcp += n + 1;
+ dstp += n + 1;
+ } while (n != 0);
+
+ if (dstp > eob) {
+ if (msg != NULL)
+ *lpp = NULL;
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ return (dstp - dst);
+}
+
+/*
+ * ns_name_uncompress(msg, eom, src, dst, dstsiz)
+ * Expand compressed domain name to presentation format.
+ * return:
+ * Number of bytes read out of `src', or -1 (with errno set).
+ * note:
+ * Root domain returns as "." not "".
+ */
+int
+ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
+ char *dst, size_t dstsiz)
+{
+ u_char tmp[NS_MAXCDNAME];
+ int n;
+
+ if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
+ return (-1);
+ if (ns_name_ntop(tmp, dst, dstsiz) == -1)
+ return (-1);
+ return (n);
+}
+
+/*
+ * ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
+ * Compress a domain name into wire format, using compression pointers.
+ * return:
+ * Number of bytes consumed in `dst' or -1 (with errno set).
+ * notes:
+ * 'dnptrs' is an array of pointers to previous compressed names.
+ * dnptrs[0] is a pointer to the beginning of the message.
+ * The list ends with NULL. 'lastdnptr' is a pointer to the end of the
+ * array pointed to by 'dnptrs'. Side effect is to update the list of
+ * pointers for labels inserted into the message as we compress the name.
+ * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
+ * is NULL, we don't update the list.
+ */
+int
+ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
+ const u_char **dnptrs, const u_char **lastdnptr)
+{
+ u_char tmp[NS_MAXCDNAME];
+
+ if (ns_name_pton(src, tmp, sizeof tmp) == -1)
+ return (-1);
+ return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
+}
+
+/*
+ * ns_name_skip(ptrptr, eom)
+ * Advance *ptrptr to skip over the compressed name it points at.
+ * return:
+ * 0 on success, -1 (with errno set) on failure.
+ */
+int
+ns_name_skip(const u_char **ptrptr, const u_char *eom) {
+ const u_char *cp;
+ u_int n;
+
+ cp = *ptrptr;
+ while (cp < eom && (n = *cp++) != 0) {
+ /* Check for indirection. */
+ switch (n & NS_CMPRSFLGS) {
+ case 0: /* normal case, n == len */
+ cp += n;
+ continue;
+ case NS_CMPRSFLGS: /* indirection */
+ cp++;
+ break;
+ default: /* illegal type */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ break;
+ }
+ if (cp > eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *ptrptr = cp;
+ return (0);
+}
+
+/* Private. */
+
+/*
+ * special(ch)
+ * Thinking in noninternationalized USASCII (per the DNS spec),
+ * is this characted special ("in need of quoting") ?
+ * return:
+ * boolean.
+ */
+static int
+special(int ch) {
+ switch (ch) {
+ case 0x22: /* '"' */
+ case 0x2E: /* '.' */
+ case 0x3B: /* ';' */
+ case 0x5C: /* '\\' */
+ /* Special modifiers in zone files. */
+ case 0x40: /* '@' */
+ case 0x24: /* '$' */
+ return (1);
+ default:
+ return (0);
+ }
+}
+
+/*
+ * printable(ch)
+ * Thinking in noninternationalized USASCII (per the DNS spec),
+ * is this character visible and not a space when printed ?
+ * return:
+ * boolean.
+ */
+static int
+printable(int ch) {
+ return (ch > 0x20 && ch < 0x7f);
+}
+
+/*
+ * Thinking in noninternationalized USASCII (per the DNS spec),
+ * convert this character to lower case if it's upper case.
+ */
+static int
+mklower(int ch) {
+ if (ch >= 0x41 && ch <= 0x5A)
+ return (ch + 0x20);
+ return (ch);
+}
+
+/*
+ * dn_find(domain, msg, dnptrs, lastdnptr)
+ * Search for the counted-label name in an array of compressed names.
+ * return:
+ * offset from msg if found, or -1.
+ * notes:
+ * dnptrs is the pointer to the first name on the list,
+ * not the pointer to the start of the message.
+ */
+static int
+dn_find(const u_char *domain, const u_char *msg,
+ const u_char * const *dnptrs,
+ const u_char * const *lastdnptr)
+{
+ const u_char *dn, *cp, *sp;
+ const u_char * const *cpp;
+ u_int n;
+
+ for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
+ dn = domain;
+ sp = cp = *cpp;
+ while ((n = *cp++) != 0) {
+ /*
+ * check for indirection
+ */
+ switch (n & NS_CMPRSFLGS) {
+ case 0: /* normal case, n == len */
+ if (n != *dn++)
+ goto next;
+ for ((void)NULL; n > 0; n--)
+ if (mklower(*dn++) != mklower(*cp++))
+ goto next;
+ /* Is next root for both ? */
+ if (*dn == '\0' && *cp == '\0')
+ return (sp - msg);
+ if (*dn)
+ continue;
+ goto next;
+
+ case NS_CMPRSFLGS: /* indirection */
+ cp = msg + (((n & 0x3f) << 8) | *cp);
+ break;
+
+ default: /* illegal type */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ }
+ next: ;
+ }
+ errno = ENOENT;
+ return (-1);
+}
diff --git a/lib/libc/net/ns_netint.c b/lib/libc/net/ns_netint.c
new file mode 100644
index 0000000..5e25b49
--- /dev/null
+++ b/lib/libc/net/ns_netint.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* Import. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+u_int
+ns_get16(const u_char *src) {
+ u_int dst;
+
+ NS_GET16(dst, src);
+ return (dst);
+}
+
+u_long
+ns_get32(const u_char *src) {
+ u_long dst;
+
+ NS_GET32(dst, src);
+ return (dst);
+}
+
+void
+ns_put16(u_int src, u_char *dst) {
+ NS_PUT16(src, dst);
+}
+
+void
+ns_put32(u_long src, u_char *dst) {
+ NS_PUT32(src, dst);
+}
diff --git a/lib/libc/net/ns_ntoa.c b/lib/libc/net/ns_ntoa.c
new file mode 100644
index 0000000..de5f305
--- /dev/null
+++ b/lib/libc/net/ns_ntoa.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ns_ntoa.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netns/ns.h>
+#include <stdio.h>
+
+char *
+ns_ntoa(addr)
+ struct ns_addr addr;
+{
+ static char obuf[40];
+ union { union ns_net net_e; u_long long_e; } net;
+ u_short port = htons(addr.x_port);
+ register char *cp;
+ char *cp2;
+ register u_char *up = addr.x_host.c_host;
+ u_char *uplim = up + 6;
+ static char *spectHex();
+
+ net.net_e = addr.x_net;
+ sprintf(obuf, "%lx", (u_long)ntohl(net.long_e));
+ cp = spectHex(obuf);
+ cp2 = cp + 1;
+ while (*up==0 && up < uplim) up++;
+ if (up == uplim) {
+ if (port) {
+ sprintf(cp, ".0");
+ cp += 2;
+ }
+ } else {
+ sprintf(cp, ".%x", *up++);
+ while (up < uplim) {
+ while (*cp) cp++;
+ sprintf(cp, "%02x", *up++);
+ }
+ cp = spectHex(cp2);
+ }
+ if (port) {
+ sprintf(cp, ".%x", port);
+ spectHex(cp + 1);
+ }
+ return (obuf);
+}
+
+static char *
+spectHex(p0)
+ char *p0;
+{
+ int ok = 0;
+ int nonzero = 0;
+ register char *p = p0;
+ for (; *p; p++) switch (*p) {
+
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ *p += ('A' - 'a');
+ /* fall into . . . */
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ ok = 1;
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ nonzero = 1;
+ }
+ if (nonzero && !ok) { *p++ = 'H'; *p = 0; }
+ return (p);
+}
diff --git a/lib/libc/net/ns_parse.c b/lib/libc/net/ns_parse.c
new file mode 100644
index 0000000..d3653b1
--- /dev/null
+++ b/lib/libc/net/ns_parse.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <errno.h>
+#include <resolv.h>
+#include <string.h>
+
+/* These need to be in the same order as the nres.h:ns_flag enum. */
+struct _ns_flagdata _ns_flagdata[16] = {
+ { 0x8000, 15 }, /* qr. */
+ { 0x7800, 11 }, /* opcode. */
+ { 0x0400, 10 }, /* aa. */
+ { 0x0200, 9 }, /* tc. */
+ { 0x0100, 8 }, /* rd. */
+ { 0x0080, 7 }, /* ra. */
+ { 0x0040, 6 }, /* z. */
+ { 0x0020, 5 }, /* ad. */
+ { 0x0010, 4 }, /* cd. */
+ { 0x000f, 0 }, /* rcode. */
+ { 0x0000, 0 }, /* expansion (1/6). */
+ { 0x0000, 0 }, /* expansion (2/6). */
+ { 0x0000, 0 }, /* expansion (3/6). */
+ { 0x0000, 0 }, /* expansion (4/6). */
+ { 0x0000, 0 }, /* expansion (5/6). */
+ { 0x0000, 0 }, /* expansion (6/6). */
+};
+
+static int
+skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
+ const u_char *optr = ptr;
+
+ for ((void)NULL; count > 0; count--) {
+ int b, rdlength;
+
+ b = dn_skipname(ptr, eom);
+ if (b < 0)
+ goto emsgsize;
+ ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
+ if (section != ns_s_qd) {
+ if (ptr + NS_INT32SZ > eom)
+ goto emsgsize;
+ ptr += NS_INT32SZ/*TTL*/;
+ if (ptr + NS_INT16SZ > eom)
+ goto emsgsize;
+ NS_GET16(rdlength, ptr);
+ ptr += rdlength/*RData*/;
+ }
+ }
+ if (ptr > eom)
+ goto emsgsize;
+ return (ptr - optr);
+ emsgsize:
+ errno = EMSGSIZE;
+ return (-1);
+}
+
+int
+ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {
+ const u_char *eom = msg + msglen;
+ int i;
+
+ memset(handle, 0x5e, sizeof *handle);
+ handle->_msg = msg;
+ handle->_eom = eom;
+ if (msg + NS_INT16SZ > eom)
+ goto emsgsize;
+ NS_GET16(handle->_id, msg);
+ if (msg + NS_INT16SZ > eom)
+ goto emsgsize;
+ NS_GET16(handle->_flags, msg);
+ for (i = 0; i < ns_s_max; i++) {
+ if (msg + NS_INT16SZ > eom)
+ goto emsgsize;
+ NS_GET16(handle->_counts[i], msg);
+ }
+ for (i = 0; i < ns_s_max; i++)
+ if (handle->_counts[i] == 0)
+ handle->_sections[i] = NULL;
+ else {
+ int b = skiprr(msg, eom, (ns_sect)i,
+ handle->_counts[i]);
+
+ if (b < 0)
+ return (-1);
+ handle->_sections[i] = msg;
+ msg += b;
+ }
+ if (msg != eom)
+ goto emsgsize;
+ handle->_sect = ns_s_max;
+ handle->_rrnum = -1;
+ handle->_ptr = NULL;
+ return (0);
+ emsgsize:
+ errno = EMSGSIZE;
+ return (-1);
+}
+
+int
+ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
+ int b;
+
+ /* Make section right. */
+ if (section < 0 || section >= ns_s_max)
+ goto enodev;
+ if ((int)section != (int)handle->_sect) {
+ handle->_sect = section;
+ handle->_rrnum = 0;
+ handle->_ptr = handle->_sections[(int)section];
+ }
+
+ /* Make rrnum right. */
+ if (rrnum == -1)
+ rrnum = handle->_rrnum;
+ if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
+ goto enodev;
+ if (rrnum < handle->_rrnum) {
+ handle->_rrnum = 0;
+ handle->_ptr = handle->_sections[(int)section];
+ }
+
+ b = skiprr(handle->_msg, handle->_eom, section,
+ rrnum - handle->_rrnum);
+ if (b < 0)
+ return (-1);
+ handle->_ptr += b;
+ handle->_rrnum = rrnum;
+
+ /* Do the parse. */
+ b = dn_expand(handle->_msg, handle->_eom,
+ handle->_ptr, rr->name, NS_MAXDNAME);
+ if (b < 0)
+ return (-1);
+ handle->_ptr += b;
+ if (handle->_ptr + NS_INT16SZ > handle->_eom)
+ goto emsgsize;
+ NS_GET16(rr->type, handle->_ptr);
+ if (handle->_ptr + NS_INT16SZ > handle->_eom)
+ goto emsgsize;
+ NS_GET16(rr->rr_class, handle->_ptr);
+ if (section == ns_s_qd) {
+ rr->ttl = 0;
+ rr->rdlength = 0;
+ rr->rdata = NULL;
+ } else {
+ if (handle->_ptr + NS_INT32SZ > handle->_eom)
+ goto emsgsize;
+ NS_GET32(rr->ttl, handle->_ptr);
+ if (handle->_ptr + NS_INT16SZ > handle->_eom)
+ goto emsgsize;
+ NS_GET16(rr->rdlength, handle->_ptr);
+ if (handle->_ptr + rr->rdlength > handle->_eom)
+ goto emsgsize;
+ rr->rdata = handle->_ptr;
+ handle->_ptr += rr->rdlength;
+ }
+ handle->_rrnum++;
+
+ /* All done. */
+ return (0);
+ enodev:
+ errno = ENODEV;
+ return (-1);
+ emsgsize:
+ errno = EMSGSIZE;
+ return (-1);
+}
diff --git a/lib/libc/net/ns_print.c b/lib/libc/net/ns_print.c
new file mode 100644
index 0000000..6be8c80
--- /dev/null
+++ b/lib/libc/net/ns_print.c
@@ -0,0 +1,743 @@
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* Import. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <resolv.h>
+#include <string.h>
+#include <ctype.h>
+
+#define SPRINTF(x) ((size_t)sprintf x)
+
+/* Forward. */
+
+static size_t prune_origin(const char *name, const char *origin);
+static int charstr(const u_char *rdata, const u_char *edata,
+ char **buf, size_t *buflen);
+static int addname(const u_char *msg, size_t msglen,
+ const u_char **p, const char *origin,
+ char **buf, size_t *buflen);
+static void addlen(size_t len, char **buf, size_t *buflen);
+static int addstr(const char *src, size_t len,
+ char **buf, size_t *buflen);
+static int addtab(size_t len, size_t target, int spaced,
+ char **buf, size_t *buflen);
+
+/* Macros. */
+
+#define T(x) \
+ do { \
+ if ((x) < 0) \
+ return (-1); \
+ } while (0)
+
+/* Public. */
+
+/*
+ * int
+ * ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen)
+ * Convert an RR to presentation format.
+ * return:
+ * Number of characters written to buf, or -1 (check errno).
+ */
+int
+ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
+ const char *name_ctx, const char *origin,
+ char *buf, size_t buflen)
+{
+ int n;
+
+ n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
+ ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
+ ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
+ name_ctx, origin, buf, buflen);
+ return (n);
+}
+
+/*
+ * int
+ * ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen,
+ * name_ctx, origin, buf, buflen)
+ * Convert the fields of an RR into presentation format.
+ * return:
+ * Number of characters written to buf, or -1 (check errno).
+ */
+int
+ns_sprintrrf(const u_char *msg, size_t msglen,
+ const char *name, ns_class class, ns_type type,
+ u_long ttl, const u_char *rdata, size_t rdlen,
+ const char *name_ctx, const char *origin,
+ char *buf, size_t buflen)
+{
+ const char *obuf = buf;
+ const u_char *edata = rdata + rdlen;
+ int spaced = 0;
+
+ const char *comment;
+ char tmp[100];
+ int len, x;
+
+ /*
+ * Owner.
+ */
+ if (name_ctx != NULL && strcasecmp(name_ctx, name) == 0) {
+ T(addstr("\t\t\t", 3, &buf, &buflen));
+ } else {
+ len = prune_origin(name, origin);
+ if (len == 0) {
+ T(addstr("@\t\t\t", 4, &buf, &buflen));
+ } else {
+ T(addstr(name, len, &buf, &buflen));
+ /* Origin not used and no trailing dot? */
+ if ((!origin || !origin[0] || name[len] == '\0') &&
+ name[len - 1] != '.') {
+ T(addstr(".", 1, &buf, &buflen));
+ len++;
+ }
+ T(spaced = addtab(len, 24, spaced, &buf, &buflen));
+ }
+ }
+
+ /*
+ * TTL, Class, Type.
+ */
+ T(x = ns_format_ttl(ttl, buf, buflen));
+ addlen(x, &buf, &buflen);
+ len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
+ T(addstr(tmp, len, &buf, &buflen));
+ T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
+
+ /*
+ * RData.
+ */
+ switch (type) {
+ case ns_t_a:
+ if (rdlen != NS_INADDRSZ)
+ goto formerr;
+ (void) inet_ntop(AF_INET, rdata, buf, buflen);
+ addlen(strlen(buf), &buf, &buflen);
+ break;
+
+ case ns_t_cname:
+ case ns_t_mb:
+ case ns_t_mg:
+ case ns_t_mr:
+ case ns_t_ns:
+ case ns_t_ptr:
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ break;
+
+ case ns_t_hinfo:
+ case ns_t_isdn:
+ /* First word. */
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Second word. */
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ break;
+
+ case ns_t_soa: {
+ u_long t;
+
+ /* Server name. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Administrator name. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ T(addstr(" (\n", 3, &buf, &buflen));
+ spaced = 0;
+
+ if ((edata - rdata) != 5*NS_INT32SZ)
+ goto formerr;
+
+ /* Serial number. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+ len = SPRINTF((tmp, "%lu", t));
+ T(addstr(tmp, len, &buf, &buflen));
+ T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+ T(addstr("; serial\n", 9, &buf, &buflen));
+ spaced = 0;
+
+ /* Refresh interval. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+ T(len = ns_format_ttl(t, buf, buflen));
+ addlen(len, &buf, &buflen);
+ T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+ T(addstr("; refresh\n", 10, &buf, &buflen));
+ spaced = 0;
+
+ /* Retry interval. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+ T(len = ns_format_ttl(t, buf, buflen));
+ addlen(len, &buf, &buflen);
+ T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+ T(addstr("; retry\n", 8, &buf, &buflen));
+ spaced = 0;
+
+ /* Expiry. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+ T(len = ns_format_ttl(t, buf, buflen));
+ addlen(len, &buf, &buflen);
+ T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+ T(addstr("; expiry\n", 9, &buf, &buflen));
+ spaced = 0;
+
+ /* Minimum TTL. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+ T(len = ns_format_ttl(t, buf, buflen));
+ addlen(len, &buf, &buflen);
+ T(addstr(" )", 2, &buf, &buflen));
+ T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+ T(addstr("; minimum\n", 10, &buf, &buflen));
+
+ break;
+ }
+
+ case ns_t_mx:
+ case ns_t_afsdb:
+ case ns_t_rt: {
+ u_int t;
+
+ if (rdlen < NS_INT16SZ)
+ goto formerr;
+
+ /* Priority. */
+ t = ns_get16(rdata);
+ rdata += NS_INT16SZ;
+ len = SPRINTF((tmp, "%u ", t));
+ T(addstr(tmp, len, &buf, &buflen));
+
+ /* Target. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+ break;
+ }
+
+ case ns_t_px: {
+ u_int t;
+
+ if (rdlen < NS_INT16SZ)
+ goto formerr;
+
+ /* Priority. */
+ t = ns_get16(rdata);
+ rdata += NS_INT16SZ;
+ len = SPRINTF((tmp, "%u ", t));
+ T(addstr(tmp, len, &buf, &buflen));
+
+ /* Name1. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Name2. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+ break;
+ }
+
+ case ns_t_x25:
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ break;
+
+ case ns_t_txt:
+ while (rdata < edata) {
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ if (rdata < edata)
+ T(addstr(" ", 1, &buf, &buflen));
+ }
+ break;
+
+ case ns_t_nsap: {
+ char t[255*3];
+
+ (void) inet_nsap_ntoa(rdlen, rdata, t);
+ T(addstr(t, strlen(t), &buf, &buflen));
+ break;
+ }
+
+ case ns_t_aaaa:
+ if (rdlen != NS_IN6ADDRSZ)
+ goto formerr;
+ (void) inet_ntop(AF_INET6, rdata, buf, buflen);
+ addlen(strlen(buf), &buf, &buflen);
+ break;
+
+ case ns_t_loc: {
+ char t[255];
+
+ /* XXX protocol format checking? */
+ (void) loc_ntoa(rdata, t);
+ T(addstr(t, strlen(t), &buf, &buflen));
+ break;
+ }
+
+ case ns_t_naptr: {
+ u_int order, preference;
+ char t[50];
+
+ if (rdlen < 2*NS_INT16SZ)
+ goto formerr;
+
+ /* Order, Precedence. */
+ order = ns_get16(rdata); rdata += NS_INT16SZ;
+ preference = ns_get16(rdata); rdata += NS_INT16SZ;
+ len = SPRINTF((t, "%u %u ", order, preference));
+ T(addstr(t, len, &buf, &buflen));
+
+ /* Flags. */
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Service. */
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Regexp. */
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len < 0)
+ return (-1);
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Server. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ break;
+ }
+
+ case ns_t_srv: {
+ u_int priority, weight, port;
+ char t[50];
+
+ if (rdlen < NS_INT16SZ*3)
+ goto formerr;
+
+ /* Priority, Weight, Port. */
+ priority = ns_get16(rdata); rdata += NS_INT16SZ;
+ weight = ns_get16(rdata); rdata += NS_INT16SZ;
+ port = ns_get16(rdata); rdata += NS_INT16SZ;
+ len = SPRINTF((t, "%u %u %u ", priority, weight, port));
+ T(addstr(t, len, &buf, &buflen));
+
+ /* Server. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ break;
+ }
+
+ case ns_t_minfo:
+ case ns_t_rp:
+ /* Name1. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Name2. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+ break;
+
+ case ns_t_wks: {
+ int n, lcnt;
+
+ if (rdlen < NS_INT32SZ + 1)
+ goto formerr;
+
+ /* Address. */
+ (void) inet_ntop(AF_INET, rdata, buf, buflen);
+ addlen(strlen(buf), &buf, &buflen);
+ rdata += NS_INADDRSZ;
+
+ /* Protocol. */
+ len = SPRINTF((tmp, " %u ( ", *rdata));
+ T(addstr(tmp, len, &buf, &buflen));
+ rdata += NS_INT8SZ;
+
+ /* Bit map. */
+ n = 0;
+ lcnt = 0;
+ while (rdata < edata) {
+ u_int c = *rdata++;
+ do {
+ if (c & 0200) {
+ if (lcnt == 0) {
+ T(addstr("\n\t\t\t\t", 5,
+ &buf, &buflen));
+ lcnt = 10;
+ spaced = 0;
+ }
+ len = SPRINTF((tmp, "%d ", n));
+ T(addstr(tmp, len, &buf, &buflen));
+ lcnt--;
+ }
+ c <<= 1;
+ } while (++n & 07);
+ }
+ T(addstr(")", 1, &buf, &buflen));
+
+ break;
+ }
+
+ case ns_t_key: {
+ char base64_key[NS_MD5RSA_MAX_BASE64];
+ u_int keyflags, protocol, algorithm;
+ const char *leader;
+ int n;
+
+ if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
+ goto formerr;
+
+ /* Key flags, Protocol, Algorithm. */
+ keyflags = ns_get16(rdata); rdata += NS_INT16SZ;
+ protocol = *rdata++;
+ algorithm = *rdata++;
+ len = SPRINTF((tmp, "0x%04x %u %u",
+ keyflags, protocol, algorithm));
+ T(addstr(tmp, len, &buf, &buflen));
+
+ /* Public key data. */
+ len = b64_ntop(rdata, edata - rdata,
+ base64_key, sizeof base64_key);
+ if (len < 0)
+ goto formerr;
+ if (len > 15) {
+ T(addstr(" (", 2, &buf, &buflen));
+ leader = "\n\t\t";
+ spaced = 0;
+ } else
+ leader = " ";
+ for (n = 0; n < len; n += 48) {
+ T(addstr(leader, strlen(leader), &buf, &buflen));
+ T(addstr(base64_key + n, MIN(len - n, 48),
+ &buf, &buflen));
+ }
+ if (len > 15)
+ T(addstr(" )", 2, &buf, &buflen));
+
+ break;
+ }
+
+ case ns_t_sig: {
+ char base64_key[NS_MD5RSA_MAX_BASE64];
+ u_int type, algorithm, labels, footprint;
+ const char *leader;
+ u_long t;
+ int n;
+
+ if (rdlen < 22)
+ goto formerr;
+
+ /* Type covered, Algorithm, Label count, Original TTL. */
+ type = ns_get16(rdata); rdata += NS_INT16SZ;
+ algorithm = *rdata++;
+ labels = *rdata++;
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ len = SPRINTF((tmp, " %s %d %lu ",
+ p_type(type), algorithm, t));
+ T(addstr(tmp, len, &buf, &buflen));
+ if (labels != (u_int)dn_count_labels(name))
+ goto formerr;
+
+ /* Signature expiry. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+ T(addstr(tmp, len, &buf, &buflen));
+
+ /* Time signed. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+ T(addstr(tmp, len, &buf, &buflen));
+
+ /* Signature Footprint. */
+ footprint = ns_get16(rdata); rdata += NS_INT16SZ;
+ len = SPRINTF((tmp, "%u ", footprint));
+ T(addstr(tmp, len, &buf, &buflen));
+
+ /* Signer's name. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+ /* Signature. */
+ len = b64_ntop(rdata, edata - rdata,
+ base64_key, sizeof base64_key);
+ if (len > 15) {
+ T(addstr(" (", 2, &buf, &buflen));
+ leader = "\n\t\t";
+ spaced = 0;
+ } else
+ leader = " ";
+ if (len < 0)
+ goto formerr;
+ for (n = 0; n < len; n += 48) {
+ T(addstr(leader, strlen(leader), &buf, &buflen));
+ T(addstr(base64_key + n, MIN(len - n, 48),
+ &buf, &buflen));
+ }
+ if (len > 15)
+ T(addstr(" )", 2, &buf, &buflen));
+
+ break;
+ }
+
+ case ns_t_nxt: {
+ int n, c;
+
+ /* Next domain name. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+ /* Type bit map. */
+ n = edata - rdata;
+ for (c = 0; c < n*8; c++)
+ if (NS_NXT_BIT_ISSET(c, rdata)) {
+ len = SPRINTF((tmp, " %s", p_type(c)));
+ T(addstr(tmp, len, &buf, &buflen));
+ }
+ break;
+ }
+
+ default:
+ comment = "unknown RR type";
+ goto hexify;
+ }
+ return (buf - obuf);
+ formerr:
+ comment = "RR format error";
+ hexify: {
+ int n, m;
+ char *p;
+
+ len = SPRINTF((tmp, "\\#(\t\t; %s", comment));
+ T(addstr(tmp, len, &buf, &buflen));
+ while (rdata < edata) {
+ p = tmp;
+ p += SPRINTF((p, "\n\t"));
+ spaced = 0;
+ n = MIN(16, edata - rdata);
+ for (m = 0; m < n; m++)
+ p += SPRINTF((p, "%02x ", rdata[m]));
+ T(addstr(tmp, p - tmp, &buf, &buflen));
+ if (n < 16) {
+ T(addstr(")", 1, &buf, &buflen));
+ T(addtab(p - tmp + 1, 48, spaced, &buf, &buflen));
+ }
+ p = tmp;
+ p += SPRINTF((p, "; "));
+ for (m = 0; m < n; m++)
+ *p++ = (isascii(rdata[m]) && isprint(rdata[m]))
+ ? rdata[m]
+ : '.';
+ T(addstr(tmp, p - tmp, &buf, &buflen));
+ rdata += n;
+ }
+ return (buf - obuf);
+ }
+}
+
+/* Private. */
+
+/*
+ * size_t
+ * prune_origin(name, origin)
+ * Find out if the name is at or under the current origin.
+ * return:
+ * Number of characters in name before start of origin,
+ * or length of name if origin does not match.
+ * notes:
+ * This function should share code with samedomain().
+ */
+static size_t
+prune_origin(const char *name, const char *origin) {
+ const char *oname = name;
+
+ while (*name != '\0') {
+ if (origin != NULL && strcasecmp(name, origin) == 0)
+ return (name - oname - (name > oname));
+ while (*name != '\0') {
+ if (*name == '\\') {
+ name++;
+ /* XXX need to handle \nnn form. */
+ if (*name == '\0')
+ break;
+ } else if (*name == '.') {
+ name++;
+ break;
+ }
+ name++;
+ }
+ }
+ return (name - oname);
+}
+
+/*
+ * int
+ * charstr(rdata, edata, buf, buflen)
+ * Format a <character-string> into the presentation buffer.
+ * return:
+ * Number of rdata octets consumed
+ * 0 for protocol format error
+ * -1 for output buffer error
+ * side effects:
+ * buffer is advanced on success.
+ */
+static int
+charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
+ const u_char *odata = rdata;
+ size_t save_buflen = *buflen;
+ char *save_buf = *buf;
+
+ if (addstr("\"", 1, buf, buflen) < 0)
+ goto enospc;
+ if (rdata < edata) {
+ int n = *rdata;
+
+ if (rdata + 1 + n <= edata) {
+ rdata++;
+ while (n-- > 0) {
+ if (strchr("\n\"\\", *rdata) != NULL)
+ if (addstr("\\", 1, buf, buflen) < 0)
+ goto enospc;
+ if (addstr((const char *)rdata, 1,
+ buf, buflen) < 0)
+ goto enospc;
+ rdata++;
+ }
+ }
+ }
+ if (addstr("\"", 1, buf, buflen) < 0)
+ goto enospc;
+ return (rdata - odata);
+ enospc:
+ errno = ENOSPC;
+ *buf = save_buf;
+ *buflen = save_buflen;
+ return (-1);
+}
+
+static int
+addname(const u_char *msg, size_t msglen,
+ const u_char **pp, const char *origin,
+ char **buf, size_t *buflen)
+{
+ size_t newlen, save_buflen = *buflen;
+ char *save_buf = *buf;
+ int n;
+
+ n = dn_expand(msg, msg + msglen, *pp, *buf, *buflen);
+ if (n < 0)
+ goto enospc; /* Guess. */
+ newlen = prune_origin(*buf, origin);
+ if ((origin == NULL || origin[0] == '\0' || (*buf)[newlen] == '\0') &&
+ (newlen == 0 || (*buf)[newlen - 1] != '.')) {
+ /* No trailing dot. */
+ if (newlen + 2 > *buflen)
+ goto enospc; /* No room for ".\0". */
+ (*buf)[newlen++] = '.';
+ (*buf)[newlen] = '\0';
+ }
+ if (newlen == 0) {
+ /* Use "@" instead of name. */
+ if (newlen + 2 > *buflen)
+ goto enospc; /* No room for "@\0". */
+ (*buf)[newlen++] = '@';
+ (*buf)[newlen] = '\0';
+ }
+ *pp += n;
+ addlen(newlen, buf, buflen);
+ **buf = '\0';
+ return (newlen);
+ enospc:
+ errno = ENOSPC;
+ *buf = save_buf;
+ *buflen = save_buflen;
+ return (-1);
+}
+
+static void
+addlen(size_t len, char **buf, size_t *buflen) {
+ assert(len <= *buflen);
+ *buf += len;
+ *buflen -= len;
+}
+
+static int
+addstr(const char *src, size_t len, char **buf, size_t *buflen) {
+ if (len > *buflen) {
+ errno = ENOSPC;
+ return (-1);
+ }
+ memcpy(*buf, src, len);
+ addlen(len, buf, buflen);
+ **buf = '\0';
+ return (0);
+}
+
+static int
+addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
+ size_t save_buflen = *buflen;
+ char *save_buf = *buf;
+ int t;
+
+ if (spaced || len >= target - 1) {
+ T(addstr(" ", 2, buf, buflen));
+ spaced = 1;
+ } else {
+ for (t = (target - len - 1) / 8; t >= 0; t--)
+ if (addstr("\t", 1, buf, buflen) < 0) {
+ *buflen = save_buflen;
+ *buf = save_buf;
+ return (-1);
+ }
+ spaced = 0;
+ }
+ return (spaced);
+}
diff --git a/lib/libc/net/ns_ttl.c b/lib/libc/net/ns_ttl.c
new file mode 100644
index 0000000..3327d86
--- /dev/null
+++ b/lib/libc/net/ns_ttl.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* Import. */
+
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#define SPRINTF(x) ((size_t)sprintf x)
+
+/* Forward. */
+
+static int fmt1(int t, char s, char **buf, size_t *buflen);
+
+/* Macros. */
+
+#define T(x) if ((x) < 0) return (-1); else (void)NULL
+
+/* Public. */
+
+int
+ns_format_ttl(u_long src, char *dst, size_t dstlen) {
+ char *odst = dst;
+ int secs, mins, hours, days, weeks, x;
+ char tmp[50], *p;
+
+ secs = src % 60; src /= 60;
+ mins = src % 60; src /= 60;
+ hours = src % 24; src /= 24;
+ days = src % 7; src /= 7;
+ weeks = src; src = 0;
+
+ x = 0;
+ if (weeks) {
+ T(fmt1(weeks, 'W', &dst, &dstlen));
+ x++;
+ }
+ if (days) {
+ T(fmt1(days, 'D', &dst, &dstlen));
+ x++;
+ }
+ if (hours) {
+ T(fmt1(hours, 'H', &dst, &dstlen));
+ x++;
+ }
+ if (mins) {
+ T(fmt1(mins, 'M', &dst, &dstlen));
+ x++;
+ }
+ if (secs || !(weeks || days || hours || mins)) {
+ T(fmt1(secs, 'S', &dst, &dstlen));
+ x++;
+ }
+
+ if (x > 1) {
+ int ch;
+
+ for (p = odst; (ch = *p) != '\0'; p++)
+ if (isascii(ch) && isupper(ch))
+ *p = tolower(ch);
+ }
+
+ return (dst - odst);
+}
+
+int
+ns_parse_ttl(const char *src, u_long *dst) {
+ u_long ttl, tmp;
+ int ch, digits, dirty;
+
+ ttl = 0;
+ tmp = 0;
+ digits = 0;
+ dirty = 0;
+ while ((ch = *src++) != '\0') {
+ if (!isascii(ch) || !isprint(ch))
+ goto einval;
+ if (isdigit(ch)) {
+ tmp *= 10;
+ tmp += (ch - '0');
+ digits++;
+ continue;
+ }
+ if (digits == 0)
+ goto einval;
+ if (islower(ch))
+ ch = toupper(ch);
+ switch (ch) {
+ case 'W': tmp *= 7;
+ case 'D': tmp *= 24;
+ case 'H': tmp *= 60;
+ case 'M': tmp *= 60;
+ case 'S': break;
+ default: goto einval;
+ }
+ ttl += tmp;
+ tmp = 0;
+ digits = 0;
+ dirty = 1;
+ }
+ if (digits > 0) {
+ if (dirty)
+ goto einval;
+ else
+ ttl += tmp;
+ }
+ *dst = ttl;
+ return (0);
+
+ einval:
+ errno = EINVAL;
+ return (-1);
+}
+
+/* Private. */
+
+static int
+fmt1(int t, char s, char **buf, size_t *buflen) {
+ char tmp[50];
+ size_t len;
+
+ len = SPRINTF((tmp, "%d%c", t, s));
+ if (len + 1 > *buflen)
+ return (-1);
+ strcpy(*buf, tmp);
+ *buf += len;
+ *buflen -= len;
+ return (0);
+}
diff --git a/lib/libc/net/nsap_addr.c b/lib/libc/net/nsap_addr.c
new file mode 100644
index 0000000..1f16fd2
--- /dev/null
+++ b/lib/libc/net/nsap_addr.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <resolv.h>
+
+static char
+xtob(c)
+ register int c;
+{
+ return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
+}
+
+u_int
+inet_nsap_addr(ascii, binary, maxlen)
+ const char *ascii;
+ u_char *binary;
+ int maxlen;
+{
+ u_char c, nib;
+ u_int len = 0;
+
+ while ((c = *ascii++) != '\0' && len < (u_int)maxlen) {
+ if (c == '.' || c == '+' || c == '/')
+ continue;
+ if (!isascii(c))
+ return (0);
+ if (islower(c))
+ c = toupper(c);
+ if (isxdigit(c)) {
+ nib = xtob(c);
+ c = *ascii++;
+ if (c != '\0') {
+ c = toupper(c);
+ if (isxdigit(c)) {
+ *binary++ = (nib << 4) | xtob(c);
+ len++;
+ } else
+ return (0);
+ }
+ else
+ return (0);
+ }
+ else
+ return (0);
+ }
+ return (len);
+}
+
+char *
+inet_nsap_ntoa(binlen, binary, ascii)
+ int binlen;
+ register const u_char *binary;
+ register char *ascii;
+{
+ register int nib;
+ int i;
+ static char tmpbuf[255*3];
+ char *start;
+
+ if (ascii)
+ start = ascii;
+ else {
+ ascii = tmpbuf;
+ start = tmpbuf;
+ }
+
+ if (binlen > 255)
+ binlen = 255;
+
+ for (i = 0; i < binlen; i++) {
+ nib = *binary >> 4;
+ *ascii++ = nib + (nib < 10 ? '0' : '7');
+ nib = *binary++ & 0x0f;
+ *ascii++ = nib + (nib < 10 ? '0' : '7');
+ if (((i % 2) == 0 && (i + 1) < binlen))
+ *ascii++ = '.';
+ }
+ *ascii = '\0';
+ return (start);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_nsap_addr
+__weak_reference(__inet_nsap_addr, inet_nsap_addr);
+#undef inet_nsap_ntoa
+__weak_reference(__inet_nsap_ntoa, inet_nsap_ntoa);
diff --git a/lib/libc/net/rcmd.3 b/lib/libc/net/rcmd.3
new file mode 100644
index 0000000..0154e82
--- /dev/null
+++ b/lib/libc/net/rcmd.3
@@ -0,0 +1,204 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)rcmd.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd February 15, 1996
+.Dt RCMD 3
+.Os BSD 4.2
+.Sh NAME
+.Nm rcmd ,
+.Nm rresvport ,
+.Nm iruserok ,
+.Nm ruserok
+.Nd routines for returning a stream to a remote command
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p"
+.Ft int
+.Fn rresvport "int *port"
+.Ft int
+.Fn iruserok "u_long raddr" "int superuser" "const char *ruser" "const char *luser"
+.Ft int
+.Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser"
+.Sh DESCRIPTION
+The
+.Fn rcmd
+function
+is used by the super-user to execute a command on
+a remote machine using an authentication scheme based
+on reserved port numbers.
+The
+.Fn rresvport
+function
+returns a descriptor to a socket
+with an address in the privileged port space.
+The
+.Fn ruserok
+function
+is used by servers
+to authenticate clients requesting service with
+.Fn rcmd .
+All three functions are present in the same file and are used
+by the
+.Xr rshd 8
+server (among others).
+.Pp
+The
+.Fn rcmd
+function
+looks up the host
+.Fa *ahost
+using
+.Xr gethostbyname 3 ,
+returning \-1 if the host does not exist.
+Otherwise
+.Fa *ahost
+is set to the standard name of the host
+and a connection is established to a server
+residing at the well-known Internet port
+.Fa inport .
+.Pp
+If the connection succeeds,
+a socket in the Internet domain of type
+.Dv SOCK_STREAM
+is returned to the caller, and given to the remote
+command as
+.Em stdin
+and
+.Em stdout .
+If
+.Fa fd2p
+is non-zero, then an auxiliary channel to a control
+process will be set up, and a descriptor for it will be placed
+in
+.Fa *fd2p .
+The control process will return diagnostic
+output from the command (unit 2) on this channel, and will also
+accept bytes on this channel as being
+.Tn UNIX
+signal numbers, to be
+forwarded to the process group of the command.
+If
+.Fa fd2p
+is 0, then the
+.Em stderr
+(unit 2 of the remote
+command) will be made the same as the
+.Em stdout
+and no
+provision is made for sending arbitrary signals to the remote process,
+although you may be able to get its attention by using out-of-band data.
+.Pp
+The protocol is described in detail in
+.Xr rshd 8 .
+.Pp
+The
+.Fn rresvport
+function is used to obtain a socket with a privileged
+address bound to it. This socket is suitable for use
+by
+.Fn rcmd
+and several other functions. Privileged Internet ports are those
+in the range 0 to 1023. Only the super-user
+is allowed to bind an address of this sort to a socket.
+.Pp
+The
+.Fn iruserok
+and
+.Fn ruserok
+functions take a remote host's IP address or name, as returned by the
+.Xr gethostbyname 3
+routines, two user names and a flag indicating whether the local user's
+name is that of the super-user.
+Then, if the user is
+.Em NOT
+the super-user, it checks the
+.Pa /etc/hosts.equiv
+file.
+If that lookup is not done, or is unsuccessful, the
+.Pa .rhosts
+in the local user's home directory is checked to see if the request for
+service is allowed.
+.Pp
+If this file does not exist, is not a regular file, is owned by anyone
+other than the user or the super-user, or is writable by anyone other
+than the owner, the check automatically fails.
+Zero is returned if the machine name is listed in the
+.Dq Pa hosts.equiv
+file, or the host and remote user name are found in the
+.Dq Pa .rhosts
+file; otherwise
+.Fn iruserok
+and
+.Fn ruserok
+return \-1.
+If the local domain (as obtained from
+.Xr gethostname 3 )
+is the same as the remote domain, only the machine name need be specified.
+.Pp
+The
+.Fn iruserok
+function is strongly preferred for security reasons.
+It requires trusting the local DNS at most, while the
+.Fn ruserok
+function requires trusting the entire DNS, which can be spoofed.
+.Sh DIAGNOSTICS
+The
+.Fn rcmd
+function
+returns a valid socket descriptor on success.
+It returns \-1 on error and prints a diagnostic message on the standard error.
+.Pp
+The
+.Fn rresvport
+function
+returns a valid, bound socket descriptor on success.
+It returns \-1 on error with the global value
+.Va errno
+set according to the reason for failure.
+The error code
+.Dv EAGAIN
+is overloaded to mean ``All network ports in use.''
+.Sh SEE ALSO
+.Xr rlogin 1 ,
+.Xr rsh 1 ,
+.Xr intro 2 ,
+.Xr rexec 3 ,
+.Xr rexecd 8 ,
+.Xr rlogind 8 ,
+.Xr rshd 8
+.Sh HISTORY
+These
+functions appeared in
+.Bx 4.2 .
diff --git a/lib/libc/net/rcmd.c b/lib/libc/net/rcmd.c
new file mode 100644
index 0000000..0424a2a
--- /dev/null
+++ b/lib/libc/net/rcmd.c
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 1983, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <signal.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+
+extern int innetgr __P(( const char *, const char *, const char *, const char * ));
+
+#define max(a, b) ((a > b) ? a : b)
+
+int __ivaliduser __P((FILE *, u_int32_t, const char *, const char *));
+static int __icheckhost __P((u_int32_t, char *));
+
+int
+rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
+ char **ahost;
+ u_short rport;
+ const char *locuser, *remuser, *cmd;
+ int *fd2p;
+{
+ struct hostent *hp;
+ struct sockaddr_in sin, from;
+ fd_set reads;
+ long oldmask;
+ pid_t pid;
+ int s, lport, timo;
+ char c;
+
+ pid = getpid();
+ hp = gethostbyname(*ahost);
+ if (hp == NULL) {
+ herror(*ahost);
+ return (-1);
+ }
+ *ahost = hp->h_name;
+ oldmask = sigblock(sigmask(SIGURG));
+ for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
+ s = rresvport(&lport);
+ if (s < 0) {
+ if (errno == EAGAIN)
+ (void)fprintf(stderr,
+ "rcmd: socket: All ports in use\n");
+ else
+ (void)fprintf(stderr, "rcmd: socket: %s\n",
+ strerror(errno));
+ sigsetmask(oldmask);
+ return (-1);
+ }
+ fcntl(s, F_SETOWN, pid);
+ bzero(&sin, sizeof sin);
+ sin.sin_len = sizeof(struct sockaddr_in);
+ sin.sin_family = hp->h_addrtype;
+ sin.sin_port = rport;
+ bcopy(hp->h_addr_list[0], &sin.sin_addr, MIN(hp->h_length, sizeof sin.sin_addr));
+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+ break;
+ (void)close(s);
+ if (errno == EADDRINUSE) {
+ lport--;
+ continue;
+ }
+ if (errno == ECONNREFUSED && timo <= 16) {
+ (void)sleep(timo);
+ timo *= 2;
+ continue;
+ }
+ if (hp->h_addr_list[1] != NULL) {
+ int oerrno = errno;
+
+ (void)fprintf(stderr, "connect to address %s: ",
+ inet_ntoa(sin.sin_addr));
+ errno = oerrno;
+ perror(0);
+ hp->h_addr_list++;
+ bcopy(hp->h_addr_list[0], &sin.sin_addr, MIN(hp->h_length, sizeof sin.sin_addr));
+ (void)fprintf(stderr, "Trying %s...\n",
+ inet_ntoa(sin.sin_addr));
+ continue;
+ }
+ (void)fprintf(stderr, "%s: %s\n", hp->h_name, strerror(errno));
+ sigsetmask(oldmask);
+ return (-1);
+ }
+ lport--;
+ if (fd2p == 0) {
+ write(s, "", 1);
+ lport = 0;
+ } else {
+ char num[8];
+ int s2 = rresvport(&lport), s3;
+ int len = sizeof(from);
+ int nfds;
+
+ if (s2 < 0)
+ goto bad;
+ listen(s2, 1);
+ (void)snprintf(num, sizeof(num), "%d", lport);
+ if (write(s, num, strlen(num)+1) != strlen(num)+1) {
+ (void)fprintf(stderr,
+ "rcmd: write (setting up stderr): %s\n",
+ strerror(errno));
+ (void)close(s2);
+ goto bad;
+ }
+ nfds = max(s, s2)+1;
+ if(nfds > FD_SETSIZE) {
+ fprintf(stderr, "rcmd: too many files\n");
+ (void)close(s2);
+ goto bad;
+ }
+again:
+ FD_ZERO(&reads);
+ FD_SET(s, &reads);
+ FD_SET(s2, &reads);
+ errno = 0;
+ if (select(nfds, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)){
+ if (errno != 0)
+ (void)fprintf(stderr,
+ "rcmd: select (setting up stderr): %s\n",
+ strerror(errno));
+ else
+ (void)fprintf(stderr,
+ "select: protocol failure in circuit setup\n");
+ (void)close(s2);
+ goto bad;
+ }
+ s3 = accept(s2, (struct sockaddr *)&from, &len);
+ /*
+ * XXX careful for ftp bounce attacks. If discovered, shut them
+ * down and check for the real auxiliary channel to connect.
+ */
+ if (from.sin_family == AF_INET && from.sin_port == htons(20)) {
+ close(s3);
+ goto again;
+ }
+ (void)close(s2);
+ if (s3 < 0) {
+ (void)fprintf(stderr,
+ "rcmd: accept: %s\n", strerror(errno));
+ lport = 0;
+ goto bad;
+ }
+ *fd2p = s3;
+ from.sin_port = ntohs((u_short)from.sin_port);
+ if (from.sin_family != AF_INET ||
+ from.sin_port >= IPPORT_RESERVED ||
+ from.sin_port < IPPORT_RESERVED / 2) {
+ (void)fprintf(stderr,
+ "socket: protocol failure in circuit setup.\n");
+ goto bad2;
+ }
+ }
+ (void)write(s, locuser, strlen(locuser)+1);
+ (void)write(s, remuser, strlen(remuser)+1);
+ (void)write(s, cmd, strlen(cmd)+1);
+ if (read(s, &c, 1) != 1) {
+ (void)fprintf(stderr,
+ "rcmd: %s: %s\n", *ahost, strerror(errno));
+ goto bad2;
+ }
+ if (c != 0) {
+ while (read(s, &c, 1) == 1) {
+ (void)write(STDERR_FILENO, &c, 1);
+ if (c == '\n')
+ break;
+ }
+ goto bad2;
+ }
+ sigsetmask(oldmask);
+ return (s);
+bad2:
+ if (lport)
+ (void)close(*fd2p);
+bad:
+ (void)close(s);
+ sigsetmask(oldmask);
+ return (-1);
+}
+
+int
+rresvport(alport)
+ int *alport;
+{
+ struct sockaddr_in sin;
+ int s;
+
+ bzero(&sin, sizeof sin);
+ sin.sin_len = sizeof(struct sockaddr_in);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0)
+ return (-1);
+#if 0 /* compat_exact_traditional_rresvport_semantics */
+ sin.sin_port = htons((u_short)*alport);
+ if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+ return (s);
+ if (errno != EADDRINUSE) {
+ (void)close(s);
+ return (-1);
+ }
+#endif
+ sin.sin_port = 0;
+ if (bindresvport(s, &sin) == -1) {
+ (void)close(s);
+ return (-1);
+ }
+ *alport = (int)ntohs(sin.sin_port);
+ return (s);
+}
+
+int __check_rhosts_file = 1;
+char *__rcmd_errstr;
+
+int
+ruserok(rhost, superuser, ruser, luser)
+ const char *rhost, *ruser, *luser;
+ int superuser;
+{
+ struct hostent *hp;
+ u_int32_t addr;
+ char **ap;
+
+ if ((hp = gethostbyname(rhost)) == NULL)
+ return (-1);
+ for (ap = hp->h_addr_list; *ap; ++ap) {
+ bcopy(*ap, &addr, sizeof(addr));
+ if (iruserok(addr, superuser, ruser, luser) == 0)
+ return (0);
+ }
+ return (-1);
+}
+
+/*
+ * New .rhosts strategy: We are passed an ip address. We spin through
+ * hosts.equiv and .rhosts looking for a match. When the .rhosts only
+ * has ip addresses, we don't have to trust a nameserver. When it
+ * contains hostnames, we spin through the list of addresses the nameserver
+ * gives us and look for a match.
+ *
+ * Returns 0 if ok, -1 if not ok.
+ */
+int
+iruserok(raddr, superuser, ruser, luser)
+ unsigned long raddr;
+ int superuser;
+ const char *ruser, *luser;
+{
+ register char *cp;
+ struct stat sbuf;
+ struct passwd *pwd;
+ FILE *hostf;
+ uid_t uid;
+ int first;
+ char pbuf[MAXPATHLEN];
+
+ first = 1;
+ hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r");
+again:
+ if (hostf) {
+ if (__ivaliduser(hostf, (u_int32_t)raddr, luser, ruser) == 0) {
+ (void)fclose(hostf);
+ return (0);
+ }
+ (void)fclose(hostf);
+ }
+ if (first == 1 && (__check_rhosts_file || superuser)) {
+ first = 0;
+ if ((pwd = getpwnam(luser)) == NULL)
+ return (-1);
+ (void)strcpy(pbuf, pwd->pw_dir);
+ (void)strcat(pbuf, "/.rhosts");
+
+ /*
+ * Change effective uid while opening .rhosts. If root and
+ * reading an NFS mounted file system, can't read files that
+ * are protected read/write owner only.
+ */
+ uid = geteuid();
+ (void)seteuid(pwd->pw_uid);
+ hostf = fopen(pbuf, "r");
+ (void)seteuid(uid);
+
+ if (hostf == NULL)
+ return (-1);
+ /*
+ * If not a regular file, or is owned by someone other than
+ * user or root or if writeable by anyone but the owner, quit.
+ */
+ cp = NULL;
+ if (lstat(pbuf, &sbuf) < 0)
+ cp = ".rhosts lstat failed";
+ else if (!S_ISREG(sbuf.st_mode))
+ cp = ".rhosts not regular file";
+ else if (fstat(fileno(hostf), &sbuf) < 0)
+ cp = ".rhosts fstat failed";
+ else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
+ cp = "bad .rhosts owner";
+ else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
+ cp = ".rhosts writeable by other than owner";
+ /* If there were any problems, quit. */
+ if (cp) {
+ __rcmd_errstr = cp;
+ (void)fclose(hostf);
+ return (-1);
+ }
+ goto again;
+ }
+ return (-1);
+}
+
+/*
+ * XXX
+ * Don't make static, used by lpd(8).
+ *
+ * Returns 0 if ok, -1 if not ok.
+ */
+int
+__ivaliduser(hostf, raddr, luser, ruser)
+ FILE *hostf;
+ u_int32_t raddr;
+ const char *luser, *ruser;
+{
+ register char *user, *p;
+ int ch;
+ char buf[MAXHOSTNAMELEN + 128]; /* host + login */
+ char hname[MAXHOSTNAMELEN];
+ struct hostent *hp;
+ /* Presumed guilty until proven innocent. */
+ int userok = 0, hostok = 0;
+#ifdef YP
+ char *ypdomain;
+
+ if (yp_get_default_domain(&ypdomain))
+ ypdomain = NULL;
+#else
+#define ypdomain NULL
+#endif
+ /* We need to get the damn hostname back for netgroup matching. */
+ if ((hp = gethostbyaddr((char *)&raddr, sizeof(u_int32_t),
+ AF_INET)) == NULL)
+ return (-1);
+ strncpy(hname, hp->h_name, sizeof(hname));
+ hname[sizeof(hname) - 1] = '\0';
+
+ while (fgets(buf, sizeof(buf), hostf)) {
+ p = buf;
+ /* Skip lines that are too long. */
+ if (strchr(p, '\n') == NULL) {
+ while ((ch = getc(hostf)) != '\n' && ch != EOF);
+ continue;
+ }
+ if (*p == '\n' || *p == '#') {
+ /* comment... */
+ continue;
+ }
+ while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
+ *p = isupper((unsigned char)*p) ? tolower((unsigned char)*p) : *p;
+ p++;
+ }
+ if (*p == ' ' || *p == '\t') {
+ *p++ = '\0';
+ while (*p == ' ' || *p == '\t')
+ p++;
+ user = p;
+ while (*p != '\n' && *p != ' ' &&
+ *p != '\t' && *p != '\0')
+ p++;
+ } else
+ user = p;
+ *p = '\0';
+ /*
+ * Do +/- and +@/-@ checking. This looks really nasty,
+ * but it matches SunOS's behavior so far as I can tell.
+ */
+ switch(buf[0]) {
+ case '+':
+ if (!buf[1]) { /* '+' matches all hosts */
+ hostok = 1;
+ break;
+ }
+ if (buf[1] == '@') /* match a host by netgroup */
+ hostok = innetgr((char *)&buf[2],
+ (char *)&hname, NULL, ypdomain);
+ else /* match a host by addr */
+ hostok = __icheckhost(raddr,(char *)&buf[1]);
+ break;
+ case '-': /* reject '-' hosts and all their users */
+ if (buf[1] == '@') {
+ if (innetgr((char *)&buf[2],
+ (char *)&hname, NULL, ypdomain))
+ return(-1);
+ } else {
+ if (__icheckhost(raddr,(char *)&buf[1]))
+ return(-1);
+ }
+ break;
+ default: /* if no '+' or '-', do a simple match */
+ hostok = __icheckhost(raddr, buf);
+ break;
+ }
+ switch(*user) {
+ case '+':
+ if (!*(user+1)) { /* '+' matches all users */
+ userok = 1;
+ break;
+ }
+ if (*(user+1) == '@') /* match a user by netgroup */
+ userok = innetgr(user+2, NULL, ruser, ypdomain);
+ else /* match a user by direct specification */
+ userok = !(strcmp(ruser, user+1));
+ break;
+ case '-': /* if we matched a hostname, */
+ if (hostok) { /* check for user field rejections */
+ if (!*(user+1))
+ return(-1);
+ if (*(user+1) == '@') {
+ if (innetgr(user+2, NULL,
+ ruser, ypdomain))
+ return(-1);
+ } else {
+ if (!strcmp(ruser, user+1))
+ return(-1);
+ }
+ }
+ break;
+ default: /* no rejections: try to match the user */
+ if (hostok)
+ userok = !(strcmp(ruser,*user ? user : luser));
+ break;
+ }
+ if (hostok && userok)
+ return(0);
+ }
+ return (-1);
+}
+
+/*
+ * Returns "true" if match, 0 if no match.
+ */
+static int
+__icheckhost(raddr, lhost)
+ u_int32_t raddr;
+ register char *lhost;
+{
+ register struct hostent *hp;
+ register u_int32_t laddr;
+ register char **pp;
+
+ /* Try for raw ip address first. */
+ if (isdigit((unsigned char)*lhost) && (u_int32_t)(laddr = inet_addr(lhost)) != -1)
+ return (raddr == laddr);
+
+ /* Better be a hostname. */
+ if ((hp = gethostbyname(lhost)) == NULL)
+ return (0);
+
+ /* Spin through ip addresses. */
+ for (pp = hp->h_addr_list; *pp; ++pp)
+ if (!bcmp(&raddr, *pp, sizeof(u_int32_t)))
+ return (1);
+
+ /* No match. */
+ return (0);
+}
diff --git a/lib/libc/net/recv.c b/lib/libc/net/recv.c
new file mode 100644
index 0000000..65ec9d4
--- /dev/null
+++ b/lib/libc/net/recv.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)recv.c 8.2 (Berkeley) 2/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <stddef.h>
+
+ssize_t
+recv(s, buf, len, flags)
+ int s, flags;
+ size_t len;
+ void *buf;
+{
+ return (recvfrom(s, buf, len, flags, NULL, 0));
+}
diff --git a/lib/libc/net/res_comp.c b/lib/libc/net/res_comp.c
new file mode 100644
index 0000000..0d237ac
--- /dev/null
+++ b/lib/libc/net/res_comp.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
+static char orig_rcsid[] = "From: Id: res_comp.c,v 8.11 1997/05/21 19:31:04 halley Exp $";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#define BIND_4_COMPAT
+
+/*
+ * Expand compressed domain name 'comp_dn' to full domain name.
+ * 'msg' is a pointer to the begining of the message,
+ * 'eomorig' points to the first location after the message,
+ * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
+ * Return size of compressed name or -1 if there was an error.
+ */
+int
+dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
+ char *dst, int dstsiz)
+{
+ int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
+
+ if (n > 0 && dst[0] == '.')
+ dst[0] = '\0';
+ return (n);
+}
+
+/*
+ * Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
+ * Return the size of the compressed name or -1.
+ * 'length' is the size of the array pointed to by 'comp_dn'.
+ */
+int
+dn_comp(const char *src, u_char *dst, int dstsiz,
+ u_char **dnptrs, u_char **lastdnptr)
+{
+ return (ns_name_compress(src, dst, (size_t)dstsiz,
+ (const u_char **)dnptrs,
+ (const u_char **)lastdnptr));
+}
+
+/*
+ * Skip over a compressed domain name. Return the size or -1.
+ */
+int
+dn_skipname(const u_char *ptr, const u_char *eom) {
+ const u_char *saveptr = ptr;
+
+ if (ns_name_skip(&ptr, eom) == -1)
+ return (-1);
+ return (ptr - saveptr);
+}
+
+/*
+ * Verify that a domain name uses an acceptable character set.
+ */
+
+/*
+ * Note the conspicuous absence of ctype macros in these definitions. On
+ * non-ASCII hosts, we can't depend on string literals or ctype macros to
+ * tell us anything about network-format data. The rest of the BIND system
+ * is not careful about this, but for some reason, we're doing it right here.
+ */
+#define PERIOD 0x2e
+#define hyphenchar(c) ((c) == 0x2d)
+#define bslashchar(c) ((c) == 0x5c)
+#define periodchar(c) ((c) == PERIOD)
+#define asterchar(c) ((c) == 0x2a)
+#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
+ || ((c) >= 0x61 && (c) <= 0x7a))
+#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
+
+#define borderchar(c) (alphachar(c) || digitchar(c))
+#define middlechar(c) (borderchar(c) || hyphenchar(c))
+#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
+
+int
+res_hnok(dn)
+ const char *dn;
+{
+ int ppch = '\0', pch = PERIOD, ch = *dn++;
+
+ while (ch != '\0') {
+ int nch = *dn++;
+
+ if (periodchar(ch)) {
+ (void)NULL;
+ } else if (periodchar(pch)) {
+ if (!borderchar(ch))
+ return (0);
+ } else if (periodchar(nch) || nch == '\0') {
+ if (!borderchar(ch))
+ return (0);
+ } else {
+ if (!middlechar(ch))
+ return (0);
+ }
+ ppch = pch, pch = ch, ch = nch;
+ }
+ return (1);
+}
+
+/*
+ * hostname-like (A, MX, WKS) owners can have "*" as their first label
+ * but must otherwise be as a host name.
+ */
+int
+res_ownok(dn)
+ const char *dn;
+{
+ if (asterchar(dn[0])) {
+ if (periodchar(dn[1]))
+ return (res_hnok(dn+2));
+ if (dn[1] == '\0')
+ return (1);
+ }
+ return (res_hnok(dn));
+}
+
+/*
+ * SOA RNAMEs and RP RNAMEs can have any printable character in their first
+ * label, but the rest of the name has to look like a host name.
+ */
+int
+res_mailok(dn)
+ const char *dn;
+{
+ int ch, escaped = 0;
+
+ /* "." is a valid missing representation */
+ if (*dn == '\0')
+ return (1);
+
+ /* otherwise <label>.<hostname> */
+ while ((ch = *dn++) != '\0') {
+ if (!domainchar(ch))
+ return (0);
+ if (!escaped && periodchar(ch))
+ break;
+ if (escaped)
+ escaped = 0;
+ else if (bslashchar(ch))
+ escaped = 1;
+ }
+ if (periodchar(ch))
+ return (res_hnok(dn));
+ return (0);
+}
+
+/*
+ * This function is quite liberal, since RFC 1034's character sets are only
+ * recommendations.
+ */
+int
+res_dnok(dn)
+ const char *dn;
+{
+ int ch;
+
+ while ((ch = *dn++) != '\0')
+ if (!domainchar(ch))
+ return (0);
+ return (1);
+}
+
+#ifdef BIND_4_COMPAT
+/*
+ * This module must export the following externally-visible symbols:
+ * ___putlong
+ * ___putshort
+ * __getlong
+ * __getshort
+ * Note that one _ comes from C and the others come from us.
+ */
+void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
+void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
+u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); }
+u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); }
+#endif /*BIND_4_COMPAT*/
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <resolv.h>.
+ */
+#undef dn_comp
+__weak_reference(__dn_comp, dn_comp);
+#undef dn_expand
+__weak_reference(__dn_expand, dn_expand);
diff --git a/lib/libc/net/res_config.h b/lib/libc/net/res_config.h
new file mode 100644
index 0000000..644e7d7
--- /dev/null
+++ b/lib/libc/net/res_config.h
@@ -0,0 +1,8 @@
+#define DEBUG 1 /* enable debugging code (needed for dig) */
+#define RESOLVSORT /* allow sorting of addresses in gethostbyname */
+#define RFC1535 /* comply with RFC1535 (STRONGLY reccomended by vixie)*/
+#undef USELOOPBACK /* res_init() bind to localhost */
+#undef SUNSECURITY /* verify gethostbyaddr() calls - WE DONT NEED IT */
+#define MULTI_PTRS_ARE_ALIASES 1 /* fold multiple PTR records into aliases */
+#define CHECK_SRVR_ADDR 1 /* confirm that the server requested sent the reply */
+#define BIND_UPDATE 1 /* update support */
diff --git a/lib/libc/net/res_data.c b/lib/libc/net/res_data.c
new file mode 100644
index 0000000..501ca32
--- /dev/null
+++ b/lib/libc/net/res_data.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1995,1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "res_config.h"
+
+const char *_res_opcodes[] = {
+ "QUERY",
+ "IQUERY",
+ "CQUERYM",
+ "CQUERYU", /* experimental */
+ "NOTIFY", /* experimental */
+ "UPDATE",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ "11",
+ "12",
+ "13",
+ "ZONEINIT",
+ "ZONEREF",
+};
+
+const char *_res_resultcodes[] = {
+ "NOERROR",
+ "FORMERR",
+ "SERVFAIL",
+ "NXDOMAIN",
+ "NOTIMP",
+ "REFUSED",
+ "YXDOMAIN",
+ "YXRRSET",
+ "NXRRSET",
+ "NOTAUTH",
+ "ZONEERR",
+ "11",
+ "12",
+ "13",
+ "14",
+ "NOCHANGE",
+};
+
+#ifdef BIND_UPDATE
+const char *_res_sectioncodes[] = {
+ "ZONE",
+ "PREREQUISITES",
+ "UPDATE",
+ "ADDITIONAL",
+};
+#endif
diff --git a/lib/libc/net/res_debug.c b/lib/libc/net/res_debug.c
new file mode 100644
index 0000000..16033f2
--- /dev/null
+++ b/lib/libc/net/res_debug.c
@@ -0,0 +1,987 @@
+/*
+ * Copyright (c) 1985
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software. No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <math.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#define SPRINTF(x) sprintf x
+
+extern const char *_res_opcodes[];
+extern const char *_res_resultcodes[];
+extern const char *_res_sectioncodes[];
+
+/*
+ * Print the current options.
+ */
+void
+fp_resstat(struct __res_state *statp, FILE *file) {
+ u_long mask;
+
+ fprintf(file, ";; res options:");
+ if (!statp)
+ statp = &_res;
+ for (mask = 1; mask != 0; mask <<= 1)
+ if (statp->options & mask)
+ fprintf(file, " %s", p_option(mask));
+ putc('\n', file);
+}
+
+static void
+do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file) {
+ int n, sflag, rrnum;
+ char buf[2048]; /* XXX need to malloc */
+ ns_opcode opcode;
+ ns_rr rr;
+
+ /*
+ * Print answer records.
+ */
+ sflag = (_res.pfcode & pflag);
+ if (_res.pfcode && !sflag)
+ return;
+
+ opcode = ns_msg_getflag(*handle, ns_f_opcode);
+ rrnum = 0;
+ for (;;) {
+ if (ns_parserr(handle, section, rrnum, &rr)) {
+ if (errno != ENODEV)
+ fprintf(file, ";; ns_parserr: %s\n",
+ strerror(errno));
+ else if (rrnum > 0 && sflag != 0 &&
+ (_res.pfcode & RES_PRF_HEAD1))
+ putc('\n', file);
+ return;
+ }
+ if (rrnum == 0 && sflag != 0 && (_res.pfcode & RES_PRF_HEAD1))
+ fprintf(file, ";; %s SECTION:\n",
+ p_section(section, opcode));
+ if (section == ns_s_qd)
+ fprintf(file, ";;\t%s, type = %s, class = %s\n",
+ ns_rr_name(rr),
+ p_type(ns_rr_type(rr)),
+ p_class(ns_rr_class(rr)));
+ else {
+ n = ns_sprintrr(handle, &rr, NULL, NULL,
+ buf, sizeof buf);
+ if (n < 0) {
+ fprintf(file, ";; ns_sprintrr: %s\n",
+ strerror(errno));
+ return;
+ }
+ fputs(buf, file);
+ fputc('\n', file);
+ }
+ rrnum++;
+ }
+}
+
+void
+p_query(const u_char *msg) {
+ fp_query(msg, stdout);
+}
+
+void
+fp_query(const u_char *msg, FILE *file) {
+ fp_nquery(msg, PACKETSZ, file);
+}
+
+/*
+ * Print the contents of a query.
+ * This is intended to be primarily a debugging routine.
+ */
+void
+fp_nquery(const u_char *msg, int len, FILE *file) {
+ ns_msg handle;
+ int n, qdcount, ancount, nscount, arcount;
+ u_int opcode, rcode, id;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return;
+
+ if (ns_initparse(msg, len, &handle) < 0) {
+ fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
+ return;
+ }
+ opcode = ns_msg_getflag(handle, ns_f_opcode);
+ rcode = ns_msg_getflag(handle, ns_f_rcode);
+ id = ns_msg_id(handle);
+ qdcount = ns_msg_count(handle, ns_s_qd);
+ ancount = ns_msg_count(handle, ns_s_an);
+ nscount = ns_msg_count(handle, ns_s_ns);
+ arcount = ns_msg_count(handle, ns_s_ar);
+
+ /*
+ * Print header fields.
+ */
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || rcode)
+ fprintf(file,
+ ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
+ _res_opcodes[opcode], _res_resultcodes[rcode], id);
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
+ putc(';', file);
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
+ fprintf(file, "; flags:");
+ if (ns_msg_getflag(handle, ns_f_qr))
+ fprintf(file, " qr");
+ if (ns_msg_getflag(handle, ns_f_aa))
+ fprintf(file, " aa");
+ if (ns_msg_getflag(handle, ns_f_tc))
+ fprintf(file, " tc");
+ if (ns_msg_getflag(handle, ns_f_rd))
+ fprintf(file, " rd");
+ if (ns_msg_getflag(handle, ns_f_ra))
+ fprintf(file, " ra");
+ if (ns_msg_getflag(handle, ns_f_z))
+ fprintf(file, " ??");
+ if (ns_msg_getflag(handle, ns_f_ad))
+ fprintf(file, " ad");
+ if (ns_msg_getflag(handle, ns_f_cd))
+ fprintf(file, " cd");
+ }
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
+ fprintf(file, "; %s: %d",
+ p_section(ns_s_qd, opcode), qdcount);
+ fprintf(file, ", %s: %d",
+ p_section(ns_s_an, opcode), ancount);
+ fprintf(file, ", %s: %d",
+ p_section(ns_s_ns, opcode), nscount);
+ fprintf(file, ", %s: %d",
+ p_section(ns_s_ar, opcode), arcount);
+ }
+ if ((!_res.pfcode) || (_res.pfcode &
+ (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
+ putc('\n',file);
+ }
+ /*
+ * Print the various sections.
+ */
+ do_section(&handle, ns_s_qd, RES_PRF_QUES, file);
+ do_section(&handle, ns_s_an, RES_PRF_ANS, file);
+ do_section(&handle, ns_s_ns, RES_PRF_AUTH, file);
+ do_section(&handle, ns_s_ar, RES_PRF_ADD, file);
+ if (qdcount == 0 && ancount == 0 &&
+ nscount == 0 && arcount == 0)
+ putc('\n', file);
+}
+
+const u_char *
+p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) {
+ char name[MAXDNAME];
+ int n;
+
+ if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
+ return (NULL);
+ if (name[0] == '\0')
+ putc('.', file);
+ else
+ fputs(name, file);
+ return (cp + n);
+}
+
+const u_char *
+p_cdname(const u_char *cp, const u_char *msg, FILE *file) {
+ return (p_cdnname(cp, msg, PACKETSZ, file));
+}
+
+/* Return a fully-qualified domain name from a compressed name (with
+ length supplied). */
+
+const u_char *
+p_fqnname(cp, msg, msglen, name, namelen)
+ const u_char *cp, *msg;
+ int msglen;
+ char *name;
+ int namelen;
+{
+ int n, newlen;
+
+ if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
+ return (NULL);
+ newlen = strlen(name);
+ if (newlen == 0 || name[newlen - 1] != '.') {
+ if (newlen + 1 >= namelen) /* Lack space for final dot */
+ return (NULL);
+ else
+ strcpy(name + newlen, ".");
+ }
+ return (cp + n);
+}
+
+/* XXX: the rest of these functions need to become length-limited, too. */
+
+const u_char *
+p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
+ char name[MAXDNAME];
+ const u_char *n;
+
+ n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
+ if (n == NULL)
+ return (NULL);
+ fputs(name, file);
+ return (n);
+}
+
+/*
+ * Names of RR classes and qclasses. Classes and qclasses are the same, except
+ * that C_ANY is a qclass but not a class. (You can ask for records of class
+ * C_ANY, but you can't have any records of that class in the database.)
+ */
+const struct res_sym __p_class_syms[] = {
+ {C_IN, "IN"},
+ {C_CHAOS, "CHAOS"},
+ {C_HS, "HS"},
+ {C_HS, "HESIOD"},
+ {C_ANY, "ANY"},
+ {C_NONE, "NONE"},
+ {C_IN, (char *)0}
+};
+
+/*
+ * Names of message sections.
+ */
+const struct res_sym __p_default_section_syms[] = {
+ {ns_s_qd, "QUERY"},
+ {ns_s_an, "ANSWER"},
+ {ns_s_ns, "AUTHORITY"},
+ {ns_s_ar, "ADDITIONAL"},
+ {0, (char *)0}
+};
+
+const struct res_sym __p_update_section_syms[] = {
+ {S_ZONE, "ZONE"},
+ {S_PREREQ, "PREREQUISITE"},
+ {S_UPDATE, "UPDATE"},
+ {S_ADDT, "ADDITIONAL"},
+ {0, (char *)0}
+};
+
+/*
+ * Names of RR types and qtypes. Types and qtypes are the same, except
+ * that T_ANY is a qtype but not a type. (You can ask for records of type
+ * T_ANY, but you can't have any records of that type in the database.)
+ */
+const struct res_sym __p_type_syms[] = {
+ {T_A, "A", "address"},
+ {T_NS, "NS", "name server"},
+ {T_MD, "MD", "mail destination (deprecated)"},
+ {T_MF, "MF", "mail forwarder (deprecated)"},
+ {T_CNAME, "CNAME", "canonical name"},
+ {T_SOA, "SOA", "start of authority"},
+ {T_MB, "MB", "mailbox"},
+ {T_MG, "MG", "mail group member"},
+ {T_MR, "MR", "mail rename"},
+ {T_NULL, "NULL", "null"},
+ {T_WKS, "WKS", "well-known service (deprecated)"},
+ {T_PTR, "PTR", "domain name pointer"},
+ {T_HINFO, "HINFO", "host information"},
+ {T_MINFO, "MINFO", "mailbox information"},
+ {T_MX, "MX", "mail exchanger"},
+ {T_TXT, "TXT", "text"},
+ {T_RP, "RP", "responsible person"},
+ {T_AFSDB, "AFSDB", "DCE or AFS server"},
+ {T_X25, "X25", "X25 address"},
+ {T_ISDN, "ISDN", "ISDN address"},
+ {T_RT, "RT", "router"},
+ {T_NSAP, "NSAP", "nsap address"},
+ {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"},
+ {T_SIG, "SIG", "signature"},
+ {T_KEY, "KEY", "key"},
+ {T_PX, "PX", "mapping information"},
+ {T_GPOS, "GPOS", "geographical position (withdrawn)"},
+ {T_AAAA, "AAAA", "IPv6 address"},
+ {T_LOC, "LOC", "location"},
+ {T_NXT, "NXT", "next valid name (unimplemented)"},
+ {T_EID, "EID", "endpoint identifier (unimplemented)"},
+ {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"},
+ {T_SRV, "SRV", "server selection"},
+ {T_ATMA, "ATMA", "ATM address (unimplemented)"},
+ {T_IXFR, "IXFR", "incremental zone transfer"},
+ {T_AXFR, "AXFR", "zone transfer"},
+ {T_MAILB, "MAILB", "mailbox-related data (deprecated)"},
+ {T_MAILA, "MAILA", "mail agent (deprecated)"},
+ {T_NAPTR, "NAPTR", "URN Naming Authority"},
+ {T_ANY, "ANY", "\"any\""},
+ {0, NULL, NULL}
+};
+
+int
+sym_ston(const struct res_sym *syms, const char *name, int *success) {
+ for ((void)NULL; syms->name != 0; syms++) {
+ if (strcasecmp (name, syms->name) == 0) {
+ if (success)
+ *success = 1;
+ return (syms->number);
+ }
+ }
+ if (success)
+ *success = 0;
+ return (syms->number); /* The default value. */
+}
+
+const char *
+sym_ntos(const struct res_sym *syms, int number, int *success) {
+ static char unname[20];
+
+ for ((void)NULL; syms->name != 0; syms++) {
+ if (number == syms->number) {
+ if (success)
+ *success = 1;
+ return (syms->name);
+ }
+ }
+
+ sprintf(unname, "%d", number);
+ if (success)
+ *success = 0;
+ return (unname);
+}
+
+const char *
+sym_ntop(const struct res_sym *syms, int number, int *success) {
+ static char unname[20];
+
+ for ((void)NULL; syms->name != 0; syms++) {
+ if (number == syms->number) {
+ if (success)
+ *success = 1;
+ return (syms->humanname);
+ }
+ }
+ sprintf(unname, "%d", number);
+ if (success)
+ *success = 0;
+ return (unname);
+}
+
+/*
+ * Return a string for the type.
+ */
+const char *
+p_type(int type) {
+ return (sym_ntos(__p_type_syms, type, (int *)0));
+}
+
+/*
+ * Return a string for the type.
+ */
+const char *
+p_section(int section, int opcode) {
+ const struct res_sym *symbols;
+
+ switch (opcode) {
+ case ns_o_update:
+ symbols = __p_update_section_syms;
+ break;
+ default:
+ symbols = __p_default_section_syms;
+ break;
+ }
+ return (sym_ntos(symbols, section, (int *)0));
+}
+
+/*
+ * Return a mnemonic for class.
+ */
+const char *
+p_class(int class) {
+ return (sym_ntos(__p_class_syms, class, (int *)0));
+}
+
+/*
+ * Return a mnemonic for an option
+ */
+const char *
+p_option(u_long option) {
+ static char nbuf[40];
+
+ switch (option) {
+ case RES_INIT: return "init";
+ case RES_DEBUG: return "debug";
+ case RES_AAONLY: return "aaonly(unimpl)";
+ case RES_USEVC: return "usevc";
+ case RES_PRIMARY: return "primry(unimpl)";
+ case RES_IGNTC: return "igntc";
+ case RES_RECURSE: return "recurs";
+ case RES_DEFNAMES: return "defnam";
+ case RES_STAYOPEN: return "styopn";
+ case RES_DNSRCH: return "dnsrch";
+ case RES_INSECURE1: return "insecure1";
+ case RES_INSECURE2: return "insecure2";
+ default: sprintf(nbuf, "?0x%lx?", (u_long)option);
+ return (nbuf);
+ }
+}
+
+/*
+ * Return a mnemonic for a time to live.
+ */
+const char *
+p_time(u_int32_t value) {
+ static char nbuf[40];
+
+ if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0)
+ sprintf(nbuf, "%u", value);
+ return (nbuf);
+}
+
+
+/*
+ * routines to convert between on-the-wire RR format and zone file format.
+ * Does not contain conversion to/from decimal degrees; divide or multiply
+ * by 60*60*1000 for that.
+ */
+
+static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
+ 1000000,10000000,100000000,1000000000};
+
+/* takes an XeY precision/size value, returns a string representation. */
+static const char *
+precsize_ntoa(prec)
+ u_int8_t prec;
+{
+ static char retbuf[sizeof "90000000.00"];
+ unsigned long val;
+ int mantissa, exponent;
+
+ mantissa = (int)((prec >> 4) & 0x0f) % 10;
+ exponent = (int)((prec >> 0) & 0x0f) % 10;
+
+ val = mantissa * poweroften[exponent];
+
+ (void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100);
+ return (retbuf);
+}
+
+/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
+static u_int8_t
+precsize_aton(strptr)
+ char **strptr;
+{
+ unsigned int mval = 0, cmval = 0;
+ u_int8_t retval = 0;
+ char *cp;
+ int exponent;
+ int mantissa;
+
+ cp = *strptr;
+
+ while (isdigit((unsigned char)*cp))
+ mval = mval * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* centimeters */
+ cp++;
+ if (isdigit((unsigned char)*cp)) {
+ cmval = (*cp++ - '0') * 10;
+ if (isdigit((unsigned char)*cp)) {
+ cmval += (*cp++ - '0');
+ }
+ }
+ }
+ cmval = (mval * 100) + cmval;
+
+ for (exponent = 0; exponent < 9; exponent++)
+ if (cmval < poweroften[exponent+1])
+ break;
+
+ mantissa = cmval / poweroften[exponent];
+ if (mantissa > 9)
+ mantissa = 9;
+
+ retval = (mantissa << 4) | exponent;
+
+ *strptr = cp;
+
+ return (retval);
+}
+
+/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
+static u_int32_t
+latlon2ul(latlonstrptr,which)
+ char **latlonstrptr;
+ int *which;
+{
+ char *cp;
+ u_int32_t retval;
+ int deg = 0, min = 0, secs = 0, secsfrac = 0;
+
+ cp = *latlonstrptr;
+
+ while (isdigit((unsigned char)*cp))
+ deg = deg * 10 + (*cp++ - '0');
+
+ while (isspace((unsigned char)*cp))
+ cp++;
+
+ if (!(isdigit((unsigned char)*cp)))
+ goto fndhemi;
+
+ while (isdigit((unsigned char)*cp))
+ min = min * 10 + (*cp++ - '0');
+
+ while (isspace((unsigned char)*cp))
+ cp++;
+
+ if (!(isdigit((unsigned char)*cp)))
+ goto fndhemi;
+
+ while (isdigit((unsigned char)*cp))
+ secs = secs * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* decimal seconds */
+ cp++;
+ if (isdigit((unsigned char)*cp)) {
+ secsfrac = (*cp++ - '0') * 100;
+ if (isdigit((unsigned char)*cp)) {
+ secsfrac += (*cp++ - '0') * 10;
+ if (isdigit((unsigned char)*cp)) {
+ secsfrac += (*cp++ - '0');
+ }
+ }
+ }
+ }
+
+ while (!isspace((unsigned char)*cp)) /* if any trailing garbage */
+ cp++;
+
+ while (isspace((unsigned char)*cp))
+ cp++;
+
+ fndhemi:
+ switch (*cp) {
+ case 'N': case 'n':
+ case 'E': case 'e':
+ retval = ((unsigned)1<<31)
+ + (((((deg * 60) + min) * 60) + secs) * 1000)
+ + secsfrac;
+ break;
+ case 'S': case 's':
+ case 'W': case 'w':
+ retval = ((unsigned)1<<31)
+ - (((((deg * 60) + min) * 60) + secs) * 1000)
+ - secsfrac;
+ break;
+ default:
+ retval = 0; /* invalid value -- indicates error */
+ break;
+ }
+
+ switch (*cp) {
+ case 'N': case 'n':
+ case 'S': case 's':
+ *which = 1; /* latitude */
+ break;
+ case 'E': case 'e':
+ case 'W': case 'w':
+ *which = 2; /* longitude */
+ break;
+ default:
+ *which = 0; /* error */
+ break;
+ }
+
+ cp++; /* skip the hemisphere */
+
+ while (!isspace((unsigned char)*cp)) /* if any trailing garbage */
+ cp++;
+
+ while (isspace((unsigned char)*cp)) /* move to next field */
+ cp++;
+
+ *latlonstrptr = cp;
+
+ return (retval);
+}
+
+/* converts a zone file representation in a string to an RDATA on-the-wire
+ * representation. */
+int
+loc_aton(ascii, binary)
+ const char *ascii;
+ u_char *binary;
+{
+ const char *cp, *maxcp;
+ u_char *bcp;
+
+ u_int32_t latit = 0, longit = 0, alt = 0;
+ u_int32_t lltemp1 = 0, lltemp2 = 0;
+ int altmeters = 0, altfrac = 0, altsign = 1;
+ u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
+ u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
+ u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
+ int which1 = 0, which2 = 0;
+
+ cp = ascii;
+ maxcp = cp + strlen(ascii);
+
+ lltemp1 = latlon2ul(&cp, &which1);
+
+ lltemp2 = latlon2ul(&cp, &which2);
+
+ switch (which1 + which2) {
+ case 3: /* 1 + 2, the only valid combination */
+ if ((which1 == 1) && (which2 == 2)) { /* normal case */
+ latit = lltemp1;
+ longit = lltemp2;
+ } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
+ longit = lltemp1;
+ latit = lltemp2;
+ } else { /* some kind of brokenness */
+ return (0);
+ }
+ break;
+ default: /* we didn't get one of each */
+ return (0);
+ }
+
+ /* altitude */
+ if (*cp == '-') {
+ altsign = -1;
+ cp++;
+ }
+
+ if (*cp == '+')
+ cp++;
+
+ while (isdigit((unsigned char)*cp))
+ altmeters = altmeters * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* decimal meters */
+ cp++;
+ if (isdigit((unsigned char)*cp)) {
+ altfrac = (*cp++ - '0') * 10;
+ if (isdigit((unsigned char)*cp)) {
+ altfrac += (*cp++ - '0');
+ }
+ }
+ }
+
+ alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
+
+ while (!isspace((unsigned char)*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ cp++;
+
+ while (isspace((unsigned char)*cp) && (cp < maxcp))
+ cp++;
+
+ if (cp >= maxcp)
+ goto defaults;
+
+ siz = precsize_aton(&cp);
+
+ while (!isspace((unsigned char)*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ cp++;
+
+ while (isspace((unsigned char)*cp) && (cp < maxcp))
+ cp++;
+
+ if (cp >= maxcp)
+ goto defaults;
+
+ hp = precsize_aton(&cp);
+
+ while (!isspace((unsigned char)*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ cp++;
+
+ while (isspace((unsigned char)*cp) && (cp < maxcp))
+ cp++;
+
+ if (cp >= maxcp)
+ goto defaults;
+
+ vp = precsize_aton(&cp);
+
+ defaults:
+
+ bcp = binary;
+ *bcp++ = (u_int8_t) 0; /* version byte */
+ *bcp++ = siz;
+ *bcp++ = hp;
+ *bcp++ = vp;
+ PUTLONG(latit,bcp);
+ PUTLONG(longit,bcp);
+ PUTLONG(alt,bcp);
+
+ return (16); /* size of RR in octets */
+}
+
+/* takes an on-the-wire LOC RR and formats it in a human readable format. */
+const char *
+loc_ntoa(binary, ascii)
+ const u_char *binary;
+ char *ascii;
+{
+ static char *error = "?";
+ const u_char *cp = binary;
+
+ int latdeg, latmin, latsec, latsecfrac;
+ int longdeg, longmin, longsec, longsecfrac;
+ char northsouth, eastwest;
+ int altmeters, altfrac, altsign;
+
+ const u_int32_t referencealt = 100000 * 100;
+
+ int32_t latval, longval, altval;
+ u_int32_t templ;
+ u_int8_t sizeval, hpval, vpval, versionval;
+
+ char *sizestr, *hpstr, *vpstr;
+
+ versionval = *cp++;
+
+ if (versionval) {
+ (void) sprintf(ascii, "; error: unknown LOC RR version");
+ return (ascii);
+ }
+
+ sizeval = *cp++;
+
+ hpval = *cp++;
+ vpval = *cp++;
+
+ GETLONG(templ, cp);
+ latval = (templ - ((unsigned)1<<31));
+
+ GETLONG(templ, cp);
+ longval = (templ - ((unsigned)1<<31));
+
+ GETLONG(templ, cp);
+ if (templ < referencealt) { /* below WGS 84 spheroid */
+ altval = referencealt - templ;
+ altsign = -1;
+ } else {
+ altval = templ - referencealt;
+ altsign = 1;
+ }
+
+ if (latval < 0) {
+ northsouth = 'S';
+ latval = -latval;
+ } else
+ northsouth = 'N';
+
+ latsecfrac = latval % 1000;
+ latval = latval / 1000;
+ latsec = latval % 60;
+ latval = latval / 60;
+ latmin = latval % 60;
+ latval = latval / 60;
+ latdeg = latval;
+
+ if (longval < 0) {
+ eastwest = 'W';
+ longval = -longval;
+ } else
+ eastwest = 'E';
+
+ longsecfrac = longval % 1000;
+ longval = longval / 1000;
+ longsec = longval % 60;
+ longval = longval / 60;
+ longmin = longval % 60;
+ longval = longval / 60;
+ longdeg = longval;
+
+ altfrac = altval % 100;
+ altmeters = (altval / 100) * altsign;
+
+ if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
+ sizestr = error;
+ if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
+ hpstr = error;
+ if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
+ vpstr = error;
+
+ sprintf(ascii,
+ "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
+ latdeg, latmin, latsec, latsecfrac, northsouth,
+ longdeg, longmin, longsec, longsecfrac, eastwest,
+ altmeters, altfrac, sizestr, hpstr, vpstr);
+
+ if (sizestr != error)
+ free(sizestr);
+ if (hpstr != error)
+ free(hpstr);
+ if (vpstr != error)
+ free(vpstr);
+
+ return (ascii);
+}
+
+
+/* Return the number of DNS hierarchy levels in the name. */
+int
+dn_count_labels(const char *name) {
+ int i, len, count;
+
+ len = strlen(name);
+ for (i = 0, count = 0; i < len; i++) {
+ /* XXX need to check for \. or use named's nlabels(). */
+ if (name[i] == '.')
+ count++;
+ }
+
+ /* don't count initial wildcard */
+ if (name[0] == '*')
+ if (count)
+ count--;
+
+ /* don't count the null label for root. */
+ /* if terminating '.' not found, must adjust */
+ /* count to include last label */
+ if (len > 0 && name[len-1] != '.')
+ count++;
+ return (count);
+}
+
+
+/*
+ * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
+ * SIG records are required to be printed like this, by the Secure DNS RFC.
+ */
+char *
+p_secstodate (u_long secs) {
+ static char output[15]; /* YYYYMMDDHHMMSS and null */
+ time_t clock = secs;
+ struct tm *time;
+
+ time = gmtime(&clock);
+ time->tm_year += 1900;
+ time->tm_mon += 1;
+ sprintf(output, "%04d%02d%02d%02d%02d%02d",
+ time->tm_year, time->tm_mon, time->tm_mday,
+ time->tm_hour, time->tm_min, time->tm_sec);
+ return (output);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <resolv.h>.
+ */
+#undef fp_resstat
+__weak_reference(__fp_resstat, fp_resstat);
+#undef p_query
+__weak_reference(__p_query, p_query);
+#undef p_fqnname
+__weak_reference(__p_fqnname, p_fqnname);
+#undef sym_ston
+__weak_reference(__sym_ston, sym_ston);
+#undef sym_ntos
+__weak_reference(__sym_ntos, sym_ntos);
+#undef sym_ntop
+__weak_reference(__sym_ntop, sym_ntop);
+#undef dn_count_labels
+__weak_reference(__dn_count_labels, dn_count_labels);
+#undef p_secstodate
+__weak_reference(__p_secstodate, p_secstodate);
diff --git a/lib/libc/net/res_init.c b/lib/libc/net/res_init.c
new file mode 100644
index 0000000..8f6e649
--- /dev/null
+++ b/lib/libc/net/res_init.c
@@ -0,0 +1,492 @@
+/*
+ * Copyright (c) 1985, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
+static char orig_rcsid[] = "From: Id: res_init.c,v 8.7 1996/11/18 09:10:04 vixie Exp $";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "res_config.h"
+
+static void res_setoptions __P((char *, char *));
+
+#ifdef RESOLVSORT
+static const char sort_mask[] = "/&";
+#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
+static u_int32_t net_mask __P((struct in_addr));
+#endif
+
+#if !defined(isascii) /* XXX - could be a function */
+# define isascii(c) (!(c & 0200))
+#endif
+
+/*
+ * Resolver state default settings.
+ */
+
+struct __res_state _res
+# if defined(__BIND_RES_TEXT)
+ = { RES_TIMEOUT, } /* Motorola, et al. */
+# endif
+ ;
+
+
+/*
+ * Set up default settings. If the configuration file exist, the values
+ * there will have precedence. Otherwise, the server address is set to
+ * INADDR_ANY and the default domain name comes from the gethostname().
+ *
+ * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
+ * rather than INADDR_ANY ("0.0.0.0") as the default name server address
+ * since it was noted that INADDR_ANY actually meant ``the first interface
+ * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
+ * it had to be "up" in order for you to reach your own name server. It
+ * was later decided that since the recommended practice is to always
+ * install local static routes through 127.0.0.1 for all your network
+ * interfaces, that we could solve this problem without a code change.
+ *
+ * The configuration file should always be used, since it is the only way
+ * to specify a default domain. If you are running a server on your local
+ * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
+ * in the configuration file.
+ *
+ * Return 0 if completes successfully, -1 on error
+ */
+int
+res_init()
+{
+ register FILE *fp;
+ register char *cp, **pp;
+ register int n;
+ char buf[MAXDNAME];
+ int nserv = 0; /* number of nameserver records read from file */
+ int haveenv = 0;
+ int havesearch = 0;
+#ifdef RESOLVSORT
+ int nsort = 0;
+ char *net;
+#endif
+#ifndef RFC1535
+ int dots;
+#endif
+
+ /*
+ * These three fields used to be statically initialized. This made
+ * it hard to use this code in a shared library. It is necessary,
+ * now that we're doing dynamic initialization here, that we preserve
+ * the old semantics: if an application modifies one of these three
+ * fields of _res before res_init() is called, res_init() will not
+ * alter them. Of course, if an application is setting them to
+ * _zero_ before calling res_init(), hoping to override what used
+ * to be the static default, we can't detect it and unexpected results
+ * will follow. Zero for any of these fields would make no sense,
+ * so one can safely assume that the applications were already getting
+ * unexpected results.
+ *
+ * _res.options is tricky since some apps were known to diddle the bits
+ * before res_init() was first called. We can't replicate that semantic
+ * with dynamic initialization (they may have turned bits off that are
+ * set in RES_DEFAULT). Our solution is to declare such applications
+ * "broken". They could fool us by setting RES_INIT but none do (yet).
+ */
+ if (!_res.retrans)
+ _res.retrans = RES_TIMEOUT;
+ if (!_res.retry)
+ _res.retry = 4;
+ if (!(_res.options & RES_INIT))
+ _res.options = RES_DEFAULT;
+
+ /*
+ * This one used to initialize implicitly to zero, so unless the app
+ * has set it to something in particular, we can randomize it now.
+ */
+ if (!_res.id)
+ _res.id = res_randomid();
+
+#ifdef USELOOPBACK
+ _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
+#else
+ _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
+#endif
+ _res.nsaddr.sin_family = AF_INET;
+ _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
+ _res.nscount = 1;
+ _res.ndots = 1;
+ _res.pfcode = 0;
+
+ /* Allow user to override the local domain definition */
+ if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) {
+ (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+ _res.defdname[sizeof(_res.defdname) - 1] = '\0';
+ haveenv++;
+
+ /*
+ * Set search list to be blank-separated strings
+ * from rest of env value. Permits users of LOCALDOMAIN
+ * to still have a search list, and anyone to set the
+ * one that they want to use as an individual (even more
+ * important now that the rfc1535 stuff restricts searches)
+ */
+ cp = _res.defdname;
+ pp = _res.dnsrch;
+ *pp++ = cp;
+ for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
+ if (*cp == '\n') /* silly backwards compat */
+ break;
+ else if (*cp == ' ' || *cp == '\t') {
+ *cp = 0;
+ n = 1;
+ } else if (n) {
+ *pp++ = cp;
+ n = 0;
+ havesearch = 1;
+ }
+ }
+ /* null terminate last domain if there are excess */
+ while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
+ cp++;
+ *cp = '\0';
+ *pp++ = 0;
+ }
+
+#define MATCH(line, name) \
+ (!strncmp(line, name, sizeof(name) - 1) && \
+ (line[sizeof(name) - 1] == ' ' || \
+ line[sizeof(name) - 1] == '\t'))
+
+ if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
+ /* read the config file */
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ /* skip comments */
+ if (*buf == ';' || *buf == '#')
+ continue;
+ /* read default domain name */
+ if (MATCH(buf, "domain")) {
+ if (haveenv) /* skip if have from environ */
+ continue;
+ cp = buf + sizeof("domain") - 1;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ if ((*cp == '\0') || (*cp == '\n'))
+ continue;
+ strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+ _res.defdname[sizeof(_res.defdname) - 1] = '\0';
+ if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
+ *cp = '\0';
+ havesearch = 0;
+ continue;
+ }
+ /* set search list */
+ if (MATCH(buf, "search")) {
+ if (haveenv) /* skip if have from environ */
+ continue;
+ cp = buf + sizeof("search") - 1;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ if ((*cp == '\0') || (*cp == '\n'))
+ continue;
+ strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+ _res.defdname[sizeof(_res.defdname) - 1] = '\0';
+ if ((cp = strchr(_res.defdname, '\n')) != NULL)
+ *cp = '\0';
+ /*
+ * Set search list to be blank-separated strings
+ * on rest of line.
+ */
+ cp = _res.defdname;
+ pp = _res.dnsrch;
+ *pp++ = cp;
+ for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
+ if (*cp == ' ' || *cp == '\t') {
+ *cp = 0;
+ n = 1;
+ } else if (n) {
+ *pp++ = cp;
+ n = 0;
+ }
+ }
+ /* null terminate last domain if there are excess */
+ while (*cp != '\0' && *cp != ' ' && *cp != '\t')
+ cp++;
+ *cp = '\0';
+ *pp++ = 0;
+ havesearch = 1;
+ continue;
+ }
+ /* read nameservers to query */
+ if (MATCH(buf, "nameserver") && nserv < MAXNS) {
+ struct in_addr a;
+
+ cp = buf + sizeof("nameserver") - 1;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
+ _res.nsaddr_list[nserv].sin_addr = a;
+ _res.nsaddr_list[nserv].sin_family = AF_INET;
+ _res.nsaddr_list[nserv].sin_port =
+ htons(NAMESERVER_PORT);
+ nserv++;
+ }
+ continue;
+ }
+#ifdef RESOLVSORT
+ if (MATCH(buf, "sortlist")) {
+ struct in_addr a;
+
+ cp = buf + sizeof("sortlist") - 1;
+ while (nsort < MAXRESOLVSORT) {
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ if (*cp == '\0' || *cp == '\n' || *cp == ';')
+ break;
+ net = cp;
+ while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
+ isascii(*cp) && !isspace(*cp))
+ cp++;
+ n = *cp;
+ *cp = 0;
+ if (inet_aton(net, &a)) {
+ _res.sort_list[nsort].addr = a;
+ if (ISSORTMASK(n)) {
+ *cp++ = n;
+ net = cp;
+ while (*cp && *cp != ';' &&
+ isascii(*cp) && !isspace(*cp))
+ cp++;
+ n = *cp;
+ *cp = 0;
+ if (inet_aton(net, &a)) {
+ _res.sort_list[nsort].mask = a.s_addr;
+ } else {
+ _res.sort_list[nsort].mask =
+ net_mask(_res.sort_list[nsort].addr);
+ }
+ } else {
+ _res.sort_list[nsort].mask =
+ net_mask(_res.sort_list[nsort].addr);
+ }
+ nsort++;
+ }
+ *cp = n;
+ }
+ continue;
+ }
+#endif
+ if (MATCH(buf, "options")) {
+ res_setoptions(buf + sizeof("options") - 1, "conf");
+ continue;
+ }
+ }
+ if (nserv > 1)
+ _res.nscount = nserv;
+#ifdef RESOLVSORT
+ _res.nsort = nsort;
+#endif
+ (void) fclose(fp);
+ }
+ if (_res.defdname[0] == 0 &&
+ gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
+ (cp = strchr(buf, '.')) != NULL)
+ strcpy(_res.defdname, cp + 1);
+
+ /* find components of local domain that might be searched */
+ if (havesearch == 0) {
+ pp = _res.dnsrch;
+ *pp++ = _res.defdname;
+ *pp = NULL;
+
+#ifndef RFC1535
+ dots = 0;
+ for (cp = _res.defdname; *cp; cp++)
+ dots += (*cp == '.');
+
+ cp = _res.defdname;
+ while (pp < _res.dnsrch + MAXDFLSRCH) {
+ if (dots < LOCALDOMAINPARTS)
+ break;
+ cp = strchr(cp, '.') + 1; /* we know there is one */
+ *pp++ = cp;
+ dots--;
+ }
+ *pp = NULL;
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG) {
+ printf(";; res_init()... default dnsrch list:\n");
+ for (pp = _res.dnsrch; *pp; pp++)
+ printf(";;\t%s\n", *pp);
+ printf(";;\t..END..\n");
+ }
+#endif
+#endif /* !RFC1535 */
+ }
+
+ if (issetugid())
+ _res.options |= RES_NOALIASES;
+ else if ((cp = getenv("RES_OPTIONS")) != NULL)
+ res_setoptions(cp, "env");
+ _res.options |= RES_INIT;
+ return (0);
+}
+
+static void
+res_setoptions(options, source)
+ char *options, *source;
+{
+ char *cp = options;
+ int i;
+
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_setoptions(\"%s\", \"%s\")...\n",
+ options, source);
+#endif
+ while (*cp) {
+ /* skip leading and inner runs of spaces */
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ /* search for and process individual options */
+ if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
+ i = atoi(cp + sizeof("ndots:") - 1);
+ if (i <= RES_MAXNDOTS)
+ _res.ndots = i;
+ else
+ _res.ndots = RES_MAXNDOTS;
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";;\tndots=%d\n", _res.ndots);
+#endif
+ } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
+#ifdef DEBUG
+ if (!(_res.options & RES_DEBUG)) {
+ printf(";; res_setoptions(\"%s\", \"%s\")..\n",
+ options, source);
+ _res.options |= RES_DEBUG;
+ }
+ printf(";;\tdebug\n");
+#endif
+ } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
+ _res.options |= RES_USE_INET6;
+ } else if (!strncmp(cp, "no_tld_query", sizeof("no_tld_query") - 1)) {
+ _res.options |= RES_NOTLDQUERY;
+ } else {
+ /* XXX - print a warning here? */
+ }
+ /* skip to next run of spaces */
+ while (*cp && *cp != ' ' && *cp != '\t')
+ cp++;
+ }
+}
+
+#ifdef RESOLVSORT
+/* XXX - should really support CIDR which means explicit masks always. */
+static u_int32_t
+net_mask(in) /* XXX - should really use system's version of this */
+ struct in_addr in;
+{
+ register u_int32_t i = ntohl(in.s_addr);
+
+ if (IN_CLASSA(i))
+ return (htonl(IN_CLASSA_NET));
+ else if (IN_CLASSB(i))
+ return (htonl(IN_CLASSB_NET));
+ return (htonl(IN_CLASSC_NET));
+}
+#endif
+
+u_int
+res_randomid()
+{
+ struct timeval now;
+
+ gettimeofday(&now, NULL);
+ return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <resolv.h>.
+ */
+#undef res_init
+__weak_reference(__res_init, res_init);
diff --git a/lib/libc/net/res_mkquery.c b/lib/libc/net/res_mkquery.c
new file mode 100644
index 0000000..5ac662b
--- /dev/null
+++ b/lib/libc/net/res_mkquery.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
+static char orig_rcsid[] = "From: Id: res_mkquery.c,v 8.9 1997/04/24 22:22:36 vixie Exp $";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "res_config.h"
+
+/*
+ * Form all types of queries.
+ * Returns the size of the result or -1.
+ */
+int
+res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
+ int op; /* opcode of query */
+ const char *dname; /* domain name */
+ int class, type; /* class and type of query */
+ const u_char *data; /* resource record data */
+ int datalen; /* length of data */
+ const u_char *newrr_in; /* new rr for modify or append */
+ u_char *buf; /* buffer to put query */
+ int buflen; /* size of buffer */
+{
+ register HEADER *hp;
+ register u_char *cp;
+ register int n;
+ u_char *dnptrs[20], **dpp, **lastdnptr;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_mkquery(%d, %s, %d, %d)\n",
+ op, dname, class, type);
+#endif
+ /*
+ * Initialize header fields.
+ */
+ if ((buf == NULL) || (buflen < HFIXEDSZ))
+ return (-1);
+ memset(buf, 0, HFIXEDSZ);
+ hp = (HEADER *) buf;
+ hp->id = htons(++_res.id);
+ hp->opcode = op;
+ hp->rd = (_res.options & RES_RECURSE) != 0;
+ hp->rcode = NOERROR;
+ cp = buf + HFIXEDSZ;
+ buflen -= HFIXEDSZ;
+ dpp = dnptrs;
+ *dpp++ = buf;
+ *dpp++ = NULL;
+ lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
+ /*
+ * perform opcode specific processing
+ */
+ switch (op) {
+ case QUERY: /*FALLTHROUGH*/
+ case NS_NOTIFY_OP:
+ if ((buflen -= QFIXEDSZ) < 0)
+ return (-1);
+ if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
+ return (-1);
+ cp += n;
+ buflen -= n;
+ __putshort(type, cp);
+ cp += INT16SZ;
+ __putshort(class, cp);
+ cp += INT16SZ;
+ hp->qdcount = htons(1);
+ if (op == QUERY || data == NULL)
+ break;
+ /*
+ * Make an additional record for completion domain.
+ */
+ buflen -= RRFIXEDSZ;
+ n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ buflen -= n;
+ __putshort(T_NULL, cp);
+ cp += INT16SZ;
+ __putshort(class, cp);
+ cp += INT16SZ;
+ __putlong(0, cp);
+ cp += INT32SZ;
+ __putshort(0, cp);
+ cp += INT16SZ;
+ hp->arcount = htons(1);
+ break;
+
+ case IQUERY:
+ /*
+ * Initialize answer section
+ */
+ if (buflen < 1 + RRFIXEDSZ + datalen)
+ return (-1);
+ *cp++ = '\0'; /* no domain name */
+ __putshort(type, cp);
+ cp += INT16SZ;
+ __putshort(class, cp);
+ cp += INT16SZ;
+ __putlong(0, cp);
+ cp += INT32SZ;
+ __putshort(datalen, cp);
+ cp += INT16SZ;
+ if (datalen) {
+ memcpy(cp, data, datalen);
+ cp += datalen;
+ }
+ hp->ancount = htons(1);
+ break;
+
+ default:
+ return (-1);
+ }
+ return (cp - buf);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <resolv.h>.
+ */
+#undef res_mkquery
+__weak_reference(__res_mkquery, res_mkquery);
diff --git a/lib/libc/net/res_mkupdate.c b/lib/libc/net/res_mkupdate.c
new file mode 100644
index 0000000..eb31bac
--- /dev/null
+++ b/lib/libc/net/res_mkupdate.c
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Based on the Dynamic DNS reference implementation by Viraj Bais
+ * <viraj_bais@ccm.fm.intel.com>
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid[] = "$FreeBSD$";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include "res_config.h"
+
+static int getnum_str(u_char **, u_char *);
+static int getword_str(char *, int, u_char **, u_char *);
+
+#define ShrinkBuffer(x) if ((buflen -= x) < 0) return (-2);
+
+/*
+ * Form update packets.
+ * Returns the size of the resulting packet if no error
+ * On error,
+ * returns -1 if error in reading a word/number in rdata
+ * portion for update packets
+ * -2 if length of buffer passed is insufficient
+ * -3 if zone section is not the first section in
+ * the linked list, or section order has a problem
+ * -4 on a number overflow
+ * -5 unknown operation or no records
+ */
+int
+res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
+ ns_updrec *rrecp_start = rrecp_in;
+ HEADER *hp;
+ u_char c, *cp, *cp1, *sp1, *sp2, *startp, *endp;
+ int n, i, j, found, soanum, multiline;
+ ns_updrec *rrecp, *tmprrecp, *recptr = NULL;
+ struct in_addr ina;
+ char buf2[MAXDNAME];
+ int section, numrrs = 0, counts[ns_s_max];
+ u_int16_t rtype, rclass;
+ u_int32_t n1, rttl;
+ u_char *dnptrs[20], **dpp, **lastdnptr;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+
+ /*
+ * Initialize header fields.
+ */
+ if ((buf == NULL) || (buflen < HFIXEDSZ))
+ return (-1);
+ memset(buf, 0, HFIXEDSZ);
+ hp = (HEADER *) buf;
+ hp->id = htons(++_res.id);
+ hp->opcode = ns_o_update;
+ hp->rcode = NOERROR;
+ sp1 = buf + 2*INT16SZ; /* save pointer to zocount */
+ cp = buf + HFIXEDSZ;
+ buflen -= HFIXEDSZ;
+ dpp = dnptrs;
+ *dpp++ = buf;
+ *dpp++ = NULL;
+ lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
+
+ if (rrecp_start == NULL)
+ return (-5);
+ else if (rrecp_start->r_section != S_ZONE)
+ return (-3);
+
+ memset(counts, 0, sizeof counts);
+ for (rrecp = rrecp_start; rrecp; rrecp = rrecp->r_grpnext) {
+ numrrs++;
+ section = rrecp->r_section;
+ if (section < 0 || section >= ns_s_max)
+ return (-1);
+ counts[section]++;
+ for (i = section + 1; i < ns_s_max; i++)
+ if (counts[i])
+ return (-3);
+ rtype = rrecp->r_type;
+ rclass = rrecp->r_class;
+ rttl = rrecp->r_ttl;
+ /* overload class and type */
+ if (section == S_PREREQ) {
+ rttl = 0;
+ switch (rrecp->r_opcode) {
+ case YXDOMAIN:
+ rclass = C_ANY;
+ rtype = T_ANY;
+ rrecp->r_size = 0;
+ break;
+ case NXDOMAIN:
+ rclass = C_NONE;
+ rtype = T_ANY;
+ rrecp->r_size = 0;
+ break;
+ case NXRRSET:
+ rclass = C_NONE;
+ rrecp->r_size = 0;
+ break;
+ case YXRRSET:
+ if (rrecp->r_size == 0)
+ rclass = C_ANY;
+ break;
+ default:
+ fprintf(stderr,
+ "res_mkupdate: incorrect opcode: %d\n",
+ rrecp->r_opcode);
+ fflush(stderr);
+ return (-1);
+ }
+ } else if (section == S_UPDATE) {
+ switch (rrecp->r_opcode) {
+ case DELETE:
+ rclass = rrecp->r_size == 0 ? C_ANY : C_NONE;
+ break;
+ case ADD:
+ break;
+ default:
+ fprintf(stderr,
+ "res_mkupdate: incorrect opcode: %d\n",
+ rrecp->r_opcode);
+ fflush(stderr);
+ return (-1);
+ }
+ }
+
+ /*
+ * XXX appending default domain to owner name is omitted,
+ * fqdn must be provided
+ */
+ if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs,
+ lastdnptr)) < 0)
+ return (-1);
+ cp += n;
+ ShrinkBuffer(n + 2*INT16SZ);
+ PUTSHORT(rtype, cp);
+ PUTSHORT(rclass, cp);
+ if (section == S_ZONE) {
+ if (numrrs != 1 || rrecp->r_type != T_SOA)
+ return (-3);
+ continue;
+ }
+ ShrinkBuffer(INT32SZ + INT16SZ);
+ PUTLONG(rttl, cp);
+ sp2 = cp; /* save pointer to length byte */
+ cp += INT16SZ;
+ if (rrecp->r_size == 0) {
+ if (section == S_UPDATE && rclass != C_ANY)
+ return (-1);
+ else {
+ PUTSHORT(0, sp2);
+ continue;
+ }
+ }
+ startp = rrecp->r_data;
+ endp = startp + rrecp->r_size - 1;
+ /* XXX this should be done centrally. */
+ switch (rrecp->r_type) {
+ case T_A:
+ if (!getword_str(buf2, sizeof buf2, &startp, endp))
+ return (-1);
+ if (!inet_aton(buf2, &ina))
+ return (-1);
+ n1 = ntohl(ina.s_addr);
+ ShrinkBuffer(INT32SZ);
+ PUTLONG(n1, cp);
+ break;
+ case T_CNAME:
+ case T_MB:
+ case T_MG:
+ case T_MR:
+ case T_NS:
+ case T_PTR:
+ if (!getword_str(buf2, sizeof buf2, &startp, endp))
+ return (-1);
+ n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ ShrinkBuffer(n);
+ break;
+ case T_MINFO:
+ case T_SOA:
+ case T_RP:
+ for (i = 0; i < 2; i++) {
+ if (!getword_str(buf2, sizeof buf2, &startp,
+ endp))
+ return (-1);
+ n = dn_comp(buf2, cp, buflen,
+ dnptrs, lastdnptr);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ ShrinkBuffer(n);
+ }
+ if (rrecp->r_type == T_SOA) {
+ ShrinkBuffer(5 * INT32SZ);
+ while (isspace(*startp) || !*startp)
+ startp++;
+ if (*startp == '(') {
+ multiline = 1;
+ startp++;
+ } else
+ multiline = 0;
+ /* serial, refresh, retry, expire, minimum */
+ for (i = 0; i < 5; i++) {
+ soanum = getnum_str(&startp, endp);
+ if (soanum < 0)
+ return (-1);
+ PUTLONG(soanum, cp);
+ }
+ if (multiline) {
+ while (isspace(*startp) || !*startp)
+ startp++;
+ if (*startp != ')')
+ return (-1);
+ }
+ }
+ break;
+ case T_MX:
+ case T_AFSDB:
+ case T_RT:
+ n = getnum_str(&startp, endp);
+ if (n < 0)
+ return (-1);
+ PUTSHORT(n, cp);
+ ShrinkBuffer(INT16SZ);
+ if (!getword_str(buf2, sizeof buf2, &startp, endp))
+ return (-1);
+ n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ ShrinkBuffer(n);
+ break;
+ case T_PX:
+ n = getnum_str(&startp, endp);
+ if (n < 0)
+ return (-1);
+ PUTSHORT(n, cp);
+ ShrinkBuffer(INT16SZ);
+ for (i = 0; i < 2; i++) {
+ if (!getword_str(buf2, sizeof buf2, &startp,
+ endp))
+ return (-1);
+ n = dn_comp(buf2, cp, buflen, dnptrs,
+ lastdnptr);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ ShrinkBuffer(n);
+ }
+ break;
+ case T_WKS:
+ case T_HINFO:
+ case T_TXT:
+ case T_X25:
+ case T_ISDN:
+ case T_NSAP:
+ case T_LOC:
+ /* XXX - more fine tuning needed here */
+ ShrinkBuffer(rrecp->r_size);
+ memcpy(cp, rrecp->r_data, rrecp->r_size);
+ cp += rrecp->r_size;
+ break;
+ default:
+ return (-1);
+ } /*switch*/
+ n = (u_int16_t)((cp - sp2) - INT16SZ);
+ PUTSHORT(n, sp2);
+ } /*for*/
+
+ hp->qdcount = htons(counts[0]);
+ hp->ancount = htons(counts[1]);
+ hp->nscount = htons(counts[2]);
+ hp->arcount = htons(counts[3]);
+ return (cp - buf);
+}
+
+/*
+ * Get a whitespace delimited word from a string (not file)
+ * into buf. modify the start pointer to point after the
+ * word in the string.
+ */
+static int
+getword_str(char *buf, int size, u_char **startpp, u_char *endp) {
+ char *cp;
+ int c;
+
+ for (cp = buf; *startpp <= endp; ) {
+ c = **startpp;
+ if (isspace(c) || c == '\0') {
+ if (cp != buf) /* trailing whitespace */
+ break;
+ else { /* leading whitespace */
+ (*startpp)++;
+ continue;
+ }
+ }
+ (*startpp)++;
+ if (cp >= buf+size-1)
+ break;
+ *cp++ = (u_char)c;
+ }
+ *cp = '\0';
+ return (cp != buf);
+}
+
+/*
+ * Get a whitespace delimited number from a string (not file) into buf
+ * update the start pointer to point after the number in the string.
+ */
+static int
+getnum_str(u_char **startpp, u_char *endp) {
+ int c, n;
+ int seendigit = 0;
+ int seendecimal = 0;
+ int m = 0;
+
+ for (n = 0; *startpp <= endp; ) {
+ c = **startpp;
+ if (isspace(c) || c == '\0') {
+ if (seendigit) /* trailing whitespace */
+ break;
+ else { /* leading whitespace */
+ (*startpp)++;
+ continue;
+ }
+ }
+ if (c == ';') {
+ while ((*startpp <= endp) &&
+ ((c = **startpp) != '\n'))
+ (*startpp)++;
+ if (seendigit)
+ break;
+ continue;
+ }
+ if (!isdigit(c)) {
+ if (c == ')' && seendigit) {
+ (*startpp)--;
+ break;
+ }
+ return (-1);
+ }
+ (*startpp)++;
+ n = n * 10 + (c - '0');
+ seendigit = 1;
+ }
+ return (n + m);
+}
+
+/*
+ * Allocate a resource record buffer & save rr info.
+ */
+ns_updrec *
+res_mkupdrec(int section, const char *dname,
+ u_int class, u_int type, u_long ttl) {
+ ns_updrec *rrecp = (ns_updrec *)calloc(1, sizeof(ns_updrec));
+
+ if (!rrecp || !(rrecp->r_dname = strdup(dname)))
+ return (NULL);
+ rrecp->r_class = class;
+ rrecp->r_type = type;
+ rrecp->r_ttl = ttl;
+ rrecp->r_section = section;
+ return (rrecp);
+}
+
+/*
+ * Free a resource record buffer created by res_mkupdrec.
+ */
+void
+res_freeupdrec(ns_updrec *rrecp) {
+ /* Note: freeing r_dp is the caller's responsibility. */
+ if (rrecp->r_dname != NULL)
+ free(rrecp->r_dname);
+ free(rrecp);
+}
diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c
new file mode 100644
index 0000000..0ee2ad2
--- /dev/null
+++ b/lib/libc/net/res_query.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
+static char orig_rcsid = "From: Id: res_query.c,v 8.14 1997/06/09 17:47:05 halley Exp $";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "res_config.h"
+
+#if PACKETSZ > 1024
+#define MAXPACKET PACKETSZ
+#else
+#define MAXPACKET 1024
+#endif
+
+/*
+ * Formulate a normal query, send, and await answer.
+ * Returned answer is placed in supplied buffer "answer".
+ * Perform preliminary check of answer, returning success only
+ * if no error is indicated and the answer count is nonzero.
+ * Return the size of the response on success, -1 on error.
+ * Error number is left in h_errno.
+ *
+ * Caller must parse answer and determine whether it answers the question.
+ */
+int
+res_query(name, class, type, answer, anslen)
+ const char *name; /* domain name */
+ int class, type; /* class and type of query */
+ u_char *answer; /* buffer to put answer */
+ int anslen; /* size of answer buffer */
+{
+ u_char buf[MAXPACKET];
+ HEADER *hp = (HEADER *) answer;
+ int n;
+
+ hp->rcode = NOERROR; /* default */
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_query(%s, %d, %d)\n", name, class, type);
+#endif
+
+ n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
+ buf, sizeof(buf));
+ if (n <= 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_query: mkquery failed\n");
+#endif
+ h_errno = NO_RECOVERY;
+ return (n);
+ }
+ n = res_send(buf, n, answer, anslen);
+ if (n < 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_query: send error\n");
+#endif
+ h_errno = TRY_AGAIN;
+ return (n);
+ }
+
+ if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; rcode = %d, ancount=%d\n", hp->rcode,
+ ntohs(hp->ancount));
+#endif
+ switch (hp->rcode) {
+ case NXDOMAIN:
+ h_errno = HOST_NOT_FOUND;
+ break;
+ case SERVFAIL:
+ h_errno = TRY_AGAIN;
+ break;
+ case NOERROR:
+ h_errno = NO_DATA;
+ break;
+ case FORMERR:
+ case NOTIMP:
+ case REFUSED:
+ default:
+ h_errno = NO_RECOVERY;
+ break;
+ }
+ return (-1);
+ }
+ return (n);
+}
+
+/*
+ * Formulate a normal query, send, and retrieve answer in supplied buffer.
+ * Return the size of the response on success, -1 on error.
+ * If enabled, implement search rules until answer or unrecoverable failure
+ * is detected. Error code, if any, is left in h_errno.
+ */
+int
+res_search(name, class, type, answer, anslen)
+ const char *name; /* domain name */
+ int class, type; /* class and type of query */
+ u_char *answer; /* buffer to put answer */
+ int anslen; /* size of answer */
+{
+ const char *cp, * const *domain;
+ HEADER *hp = (HEADER *) answer;
+ u_int dots;
+ int trailing_dot, ret, saved_herrno;
+ int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+ errno = 0;
+ h_errno = HOST_NOT_FOUND; /* default, if we never query */
+ dots = 0;
+ for (cp = name; *cp; cp++)
+ dots += (*cp == '.');
+ trailing_dot = 0;
+ if (cp > name && *--cp == '.')
+ trailing_dot++;
+
+ /* If there aren't any dots, it could be a user-level alias */
+ if (!dots && (cp = hostalias(name)) != NULL)
+ return (res_query(cp, class, type, answer, anslen));
+
+ /*
+ * If there are dots in the name already, let's just give it a try
+ * 'as is'. The threshold can be set with the "ndots" option.
+ */
+ saved_herrno = -1;
+ if (dots >= _res.ndots) {
+ ret = res_querydomain(name, NULL, class, type, answer, anslen);
+ if (ret > 0)
+ return (ret);
+ saved_herrno = h_errno;
+ tried_as_is++;
+ }
+
+ /*
+ * We do at least one level of search if
+ * - there is no dot and RES_DEFNAME is set, or
+ * - there is at least one dot, there is no trailing dot,
+ * and RES_DNSRCH is set.
+ */
+ if ((!dots && (_res.options & RES_DEFNAMES)) ||
+ (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
+ int done = 0;
+
+ for (domain = (const char * const *)_res.dnsrch;
+ *domain && !done;
+ domain++) {
+
+ ret = res_querydomain(name, *domain, class, type,
+ answer, anslen);
+ if (ret > 0)
+ return (ret);
+
+ /*
+ * If no server present, give up.
+ * If name isn't found in this domain,
+ * keep trying higher domains in the search list
+ * (if that's enabled).
+ * On a NO_DATA error, keep trying, otherwise
+ * a wildcard entry of another type could keep us
+ * from finding this entry higher in the domain.
+ * If we get some other error (negative answer or
+ * server failure), then stop searching up,
+ * but try the input name below in case it's
+ * fully-qualified.
+ */
+ if (errno == ECONNREFUSED) {
+ h_errno = TRY_AGAIN;
+ return (-1);
+ }
+
+ switch (h_errno) {
+ case NO_DATA:
+ got_nodata++;
+ /* FALLTHROUGH */
+ case HOST_NOT_FOUND:
+ /* keep trying */
+ break;
+ case TRY_AGAIN:
+ if (hp->rcode == SERVFAIL) {
+ /* try next search element, if any */
+ got_servfail++;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ /* anything else implies that we're done */
+ done++;
+ }
+
+ /* if we got here for some reason other than DNSRCH,
+ * we only wanted one iteration of the loop, so stop.
+ */
+ if (!(_res.options & RES_DNSRCH))
+ done++;
+ }
+ }
+
+ /*
+ * If we have not already tried the name "as is", do that now.
+ * note that we do this regardless of how many dots were in the
+ * name or whether it ends with a dot unless NOTLDQUERY is set.
+ */
+ if (!tried_as_is && (dots || !(_res.options & RES_NOTLDQUERY))) {
+ ret = res_querydomain(name, NULL, class, type, answer, anslen);
+ if (ret > 0)
+ return (ret);
+ }
+
+ /* if we got here, we didn't satisfy the search.
+ * if we did an initial full query, return that query's h_errno
+ * (note that we wouldn't be here if that query had succeeded).
+ * else if we ever got a nodata, send that back as the reason.
+ * else send back meaningless h_errno, that being the one from
+ * the last DNSRCH we did.
+ */
+ if (saved_herrno != -1)
+ h_errno = saved_herrno;
+ else if (got_nodata)
+ h_errno = NO_DATA;
+ else if (got_servfail)
+ h_errno = TRY_AGAIN;
+ return (-1);
+}
+
+/*
+ * Perform a call on res_query on the concatenation of name and domain,
+ * removing a trailing dot from name if domain is NULL.
+ */
+int
+res_querydomain(name, domain, class, type, answer, anslen)
+ const char *name, *domain;
+ int class, type; /* class and type of query */
+ u_char *answer; /* buffer to put answer */
+ int anslen; /* size of answer */
+{
+ char nbuf[MAXDNAME];
+ const char *longname = nbuf;
+ int n, d;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_querydomain(%s, %s, %d, %d)\n",
+ name, domain?domain:"<Nil>", class, type);
+#endif
+ if (domain == NULL) {
+ /*
+ * Check for trailing '.';
+ * copy without '.' if present.
+ */
+ n = strlen(name);
+ if (n >= MAXDNAME) {
+ h_errno = NO_RECOVERY;
+ return (-1);
+ }
+ n--;
+ if (n >= 0 && name[n] == '.') {
+ strncpy(nbuf, name, n);
+ nbuf[n] = '\0';
+ } else
+ longname = name;
+ } else {
+ n = strlen(name);
+ d = strlen(domain);
+ if (n + d + 1 >= MAXDNAME) {
+ h_errno = NO_RECOVERY;
+ return (-1);
+ }
+ sprintf(nbuf, "%s.%s", name, domain);
+ }
+ return (res_query(longname, class, type, answer, anslen));
+}
+
+const char *
+hostalias(name)
+ const char *name;
+{
+ register char *cp1, *cp2;
+ FILE *fp;
+ char *file;
+ char buf[BUFSIZ];
+ static char abuf[MAXDNAME];
+
+ if (_res.options & RES_NOALIASES)
+ return (NULL);
+ if (issetugid())
+ return (NULL);
+ file = getenv("HOSTALIASES");
+ if (file == NULL || (fp = fopen(file, "r")) == NULL)
+ return (NULL);
+ setbuf(fp, NULL);
+ buf[sizeof(buf) - 1] = '\0';
+ while (fgets(buf, sizeof(buf), fp)) {
+ for (cp1 = buf; *cp1 && !isspace((unsigned char)*cp1); ++cp1)
+ ;
+ if (!*cp1)
+ break;
+ *cp1 = '\0';
+ if (!strcasecmp(buf, name)) {
+ while (isspace((unsigned char)*++cp1))
+ ;
+ if (!*cp1)
+ break;
+ for (cp2 = cp1 + 1; *cp2 && !isspace((unsigned char)*cp2); ++cp2)
+ ;
+ abuf[sizeof(abuf) - 1] = *cp2 = '\0';
+ strncpy(abuf, cp1, sizeof(abuf) - 1);
+ fclose(fp);
+ return (abuf);
+ }
+ }
+ fclose(fp);
+ return (NULL);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <resolv.h>.
+ */
+#undef res_query
+__weak_reference(__res_query, res_query);
+#undef res_search
+__weak_reference(__res_search, res_search);
+#undef res_querydomain
+__weak_reference(__res_querydomain, res_querydomain);
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c
new file mode 100644
index 0000000..15f2a13
--- /dev/null
+++ b/lib/libc/net/res_send.c
@@ -0,0 +1,910 @@
+/*
+ * Copyright (c) 1985, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
+static char orig_rcsid[] = "From: Id: res_send.c,v 8.20 1998/04/06 23:27:51 halley Exp $";
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Send query to name server and wait for reply.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <poll.h>
+
+#include "res_config.h"
+
+#ifdef NOPOLL /* libc_r doesn't wrap poll yet() */
+static int use_poll = 0;
+#else
+static int use_poll = 1; /* adapt to poll() syscall availability */
+ /* 0 = not present, 1 = try it, 2 = exists */
+#endif
+
+static int s = -1; /* socket used for communications */
+static int connected = 0; /* is the socket connected */
+static int vc = 0; /* is the socket a virtual circuit? */
+static res_send_qhook Qhook = NULL;
+static res_send_rhook Rhook = NULL;
+
+
+#define CAN_RECONNECT 1
+
+#ifndef DEBUG
+# define Dprint(cond, args) /*empty*/
+# define DprintQ(cond, args, query, size) /*empty*/
+# define Aerror(file, string, error, address) /*empty*/
+# define Perror(file, string, error) /*empty*/
+#else
+# define Dprint(cond, args) if (cond) {fprintf args;} else {}
+# define DprintQ(cond, args, query, size) if (cond) {\
+ fprintf args;\
+ __fp_nquery(query, size, stdout);\
+ } else {}
+ static void
+ Aerror(file, string, error, address)
+ FILE *file;
+ char *string;
+ int error;
+ struct sockaddr_in address;
+ {
+ int save = errno;
+
+ if (_res.options & RES_DEBUG) {
+ fprintf(file, "res_send: %s ([%s].%u): %s\n",
+ string,
+ inet_ntoa(address.sin_addr),
+ ntohs(address.sin_port),
+ strerror(error));
+ }
+ errno = save;
+ }
+ static void
+ Perror(file, string, error)
+ FILE *file;
+ char *string;
+ int error;
+ {
+ int save = errno;
+
+ if (_res.options & RES_DEBUG) {
+ fprintf(file, "res_send: %s: %s\n",
+ string, strerror(error));
+ }
+ errno = save;
+ }
+#endif
+
+void
+res_send_setqhook(hook)
+ res_send_qhook hook;
+{
+
+ Qhook = hook;
+}
+
+void
+res_send_setrhook(hook)
+ res_send_rhook hook;
+{
+
+ Rhook = hook;
+}
+
+/* int
+ * res_isourserver(ina)
+ * looks up "ina" in _res.ns_addr_list[]
+ * returns:
+ * 0 : not found
+ * >0 : found
+ * author:
+ * paul vixie, 29may94
+ */
+int
+res_isourserver(inp)
+ const struct sockaddr_in *inp;
+{
+ struct sockaddr_in ina;
+ int ns, ret;
+
+ ina = *inp;
+ ret = 0;
+ for (ns = 0; ns < _res.nscount; ns++) {
+ const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
+
+ if (srv->sin_family == ina.sin_family &&
+ srv->sin_port == ina.sin_port &&
+ (srv->sin_addr.s_addr == INADDR_ANY ||
+ srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {
+ ret++;
+ break;
+ }
+ }
+ return (ret);
+}
+
+/* int
+ * res_nameinquery(name, type, class, buf, eom)
+ * look for (name,type,class) in the query section of packet (buf,eom)
+ * requires:
+ * buf + HFIXEDSZ <= eom
+ * returns:
+ * -1 : format error
+ * 0 : not found
+ * >0 : found
+ * author:
+ * paul vixie, 29may94
+ */
+int
+res_nameinquery(name, type, class, buf, eom)
+ const char *name;
+ int type, class;
+ const u_char *buf, *eom;
+{
+ const u_char *cp = buf + HFIXEDSZ;
+ int qdcount = ntohs(((HEADER*)buf)->qdcount);
+
+ while (qdcount-- > 0) {
+ char tname[MAXDNAME+1];
+ int n, ttype, tclass;
+
+ n = dn_expand(buf, eom, cp, tname, sizeof tname);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ if (cp + 2 * INT16SZ > eom)
+ return (-1);
+ ttype = ns_get16(cp); cp += INT16SZ;
+ tclass = ns_get16(cp); cp += INT16SZ;
+ if (ttype == type &&
+ tclass == class &&
+ strcasecmp(tname, name) == 0)
+ return (1);
+ }
+ return (0);
+}
+
+/* int
+ * res_queriesmatch(buf1, eom1, buf2, eom2)
+ * is there a 1:1 mapping of (name,type,class)
+ * in (buf1,eom1) and (buf2,eom2)?
+ * returns:
+ * -1 : format error
+ * 0 : not a 1:1 mapping
+ * >0 : is a 1:1 mapping
+ * author:
+ * paul vixie, 29may94
+ */
+int
+res_queriesmatch(buf1, eom1, buf2, eom2)
+ const u_char *buf1, *eom1;
+ const u_char *buf2, *eom2;
+{
+ const u_char *cp = buf1 + HFIXEDSZ;
+ int qdcount = ntohs(((HEADER*)buf1)->qdcount);
+
+ if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
+ return (-1);
+
+ /*
+ * Only header section present in replies to
+ * dynamic update packets.
+ */
+ if ( (((HEADER *)buf1)->opcode == ns_o_update) &&
+ (((HEADER *)buf2)->opcode == ns_o_update) )
+ return (1);
+
+ if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
+ return (0);
+ while (qdcount-- > 0) {
+ char tname[MAXDNAME+1];
+ int n, ttype, tclass;
+
+ n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ if (cp + 2 * INT16SZ > eom1)
+ return (-1);
+ ttype = ns_get16(cp); cp += INT16SZ;
+ tclass = ns_get16(cp); cp += INT16SZ;
+ if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
+ return (0);
+ }
+ return (1);
+}
+
+int
+res_send(buf, buflen, ans, anssiz)
+ const u_char *buf;
+ int buflen;
+ u_char *ans;
+ int anssiz;
+{
+ HEADER *hp = (HEADER *) buf;
+ HEADER *anhp = (HEADER *) ans;
+ int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns, n;
+ u_int badns; /* XXX NSMAX can't exceed #/bits in this variable */
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ /* errno should have been set by res_init() in this case. */
+ return (-1);
+ }
+ if (anssiz < HFIXEDSZ) {
+ errno = EINVAL;
+ return (-1);
+ }
+ DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
+ (stdout, ";; res_send()\n"), buf, buflen);
+ v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
+ gotsomewhere = 0;
+ connreset = 0;
+ terrno = ETIMEDOUT;
+ badns = 0;
+
+ /*
+ * Send request, RETRY times, or until successful
+ */
+ for (try = 0; try < _res.retry; try++) {
+ for (ns = 0; ns < _res.nscount; ns++) {
+ struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
+ same_ns:
+ if (badns & (1 << ns)) {
+ res_close();
+ goto next_ns;
+ }
+
+ if (Qhook) {
+ int done = 0, loops = 0;
+
+ do {
+ res_sendhookact act;
+
+ act = (*Qhook)(&nsap, &buf, &buflen,
+ ans, anssiz, &resplen);
+ switch (act) {
+ case res_goahead:
+ done = 1;
+ break;
+ case res_nextns:
+ res_close();
+ goto next_ns;
+ case res_done:
+ return (resplen);
+ case res_modified:
+ /* give the hook another try */
+ if (++loops < 42) /*doug adams*/
+ break;
+ /*FALLTHROUGH*/
+ case res_error:
+ /*FALLTHROUGH*/
+ default:
+ return (-1);
+ }
+ } while (!done);
+ }
+
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; Querying server (# %d) address = %s\n",
+ ns + 1, inet_ntoa(nsap->sin_addr)));
+
+ if (v_circuit) {
+ int truncated;
+ struct iovec iov[2];
+ u_short len;
+ u_char *cp;
+
+ /*
+ * Use virtual circuit;
+ * at most one attempt per server.
+ */
+ try = _res.retry;
+ truncated = 0;
+ if (s < 0 || !vc || hp->opcode == ns_o_update) {
+ if (s >= 0)
+ res_close();
+
+ s = socket(PF_INET, SOCK_STREAM, 0);
+ if (s < 0) {
+ terrno = errno;
+ Perror(stderr, "socket(vc)", errno);
+ return (-1);
+ }
+ errno = 0;
+ if (connect(s, (struct sockaddr *)nsap,
+ sizeof *nsap) < 0) {
+ terrno = errno;
+ Aerror(stderr, "connect/vc",
+ errno, *nsap);
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+ vc = 1;
+ }
+ /*
+ * Send length & message
+ */
+ putshort((u_short)buflen, (u_char*)&len);
+ iov[0].iov_base = (caddr_t)&len;
+ iov[0].iov_len = INT16SZ;
+ iov[1].iov_base = (caddr_t)buf;
+ iov[1].iov_len = buflen;
+ if (writev(s, iov, 2) != (INT16SZ + buflen)) {
+ terrno = errno;
+ Perror(stderr, "write failed", errno);
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+ /*
+ * Receive length & response
+ */
+read_len:
+ cp = ans;
+ len = INT16SZ;
+ while ((n = read(s, (char *)cp, (int)len)) > 0) {
+ cp += n;
+ if ((len -= n) <= 0)
+ break;
+ }
+ if (n <= 0) {
+ terrno = errno;
+ Perror(stderr, "read failed", errno);
+ res_close();
+ /*
+ * A long running process might get its TCP
+ * connection reset if the remote server was
+ * restarted. Requery the server instead of
+ * trying a new one. When there is only one
+ * server, this means that a query might work
+ * instead of failing. We only allow one reset
+ * per query to prevent looping.
+ */
+ if (terrno == ECONNRESET && !connreset) {
+ connreset = 1;
+ res_close();
+ goto same_ns;
+ }
+ res_close();
+ goto next_ns;
+ }
+ resplen = ns_get16(ans);
+ if (resplen > anssiz) {
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; response truncated\n")
+ );
+ truncated = 1;
+ len = anssiz;
+ } else
+ len = resplen;
+ if (len < HFIXEDSZ) {
+ /*
+ * Undersized message.
+ */
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; undersized: %d\n", len));
+ terrno = EMSGSIZE;
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+ cp = ans;
+ while (len != 0 &&
+ (n = read(s, (char *)cp, (int)len)) > 0) {
+ cp += n;
+ len -= n;
+ }
+ if (n <= 0) {
+ terrno = errno;
+ Perror(stderr, "read(vc)", errno);
+ res_close();
+ goto next_ns;
+ }
+ if (truncated) {
+ /*
+ * Flush rest of answer
+ * so connection stays in synch.
+ */
+ anhp->tc = 1;
+ len = resplen - anssiz;
+ while (len != 0) {
+ char junk[PACKETSZ];
+
+ n = (len > sizeof(junk)
+ ? sizeof(junk)
+ : len);
+ if ((n = read(s, junk, n)) > 0)
+ len -= n;
+ else
+ break;
+ }
+ }
+ /*
+ * The calling applicating has bailed out of
+ * a previous call and failed to arrange to have
+ * the circuit closed or the server has got
+ * itself confused. Anyway drop the packet and
+ * wait for the correct one.
+ */
+ if (hp->id != anhp->id) {
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; old answer (unexpected):\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto read_len;
+ }
+ } else {
+ /*
+ * Use datagrams.
+ */
+#ifndef NOPOLL
+ struct pollfd pfd;
+ int msec;
+#endif
+ struct timeval timeout;
+ fd_set dsmask, *dsmaskp;
+ int dsmasklen;
+ struct sockaddr_in from;
+ int fromlen;
+
+ if ((s < 0) || vc) {
+ if (vc)
+ res_close();
+ s = socket(PF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+#ifndef CAN_RECONNECT
+ bad_dg_sock:
+#endif
+ terrno = errno;
+ Perror(stderr, "socket(dg)", errno);
+ return (-1);
+ }
+ connected = 0;
+ }
+#ifndef CANNOT_CONNECT_DGRAM
+ /*
+ * On a 4.3BSD+ machine (client and server,
+ * actually), sending to a nameserver datagram
+ * port with no nameserver will cause an
+ * ICMP port unreachable message to be returned.
+ * If our datagram socket is "connected" to the
+ * server, we get an ECONNREFUSED error on the next
+ * socket operation, and select returns if the
+ * error message is received. We can thus detect
+ * the absence of a nameserver without timing out.
+ * If we have sent queries to at least two servers,
+ * however, we don't want to remain connected,
+ * as we wish to receive answers from the first
+ * server to respond.
+ */
+ if (_res.nscount == 1 || (try == 0 && ns == 0)) {
+ /*
+ * Connect only if we are sure we won't
+ * receive a response from another server.
+ */
+ if (!connected) {
+ if (connect(s, (struct sockaddr *)nsap,
+ sizeof *nsap
+ ) < 0) {
+ Aerror(stderr,
+ "connect(dg)",
+ errno, *nsap);
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+ connected = 1;
+ }
+ if (send(s, (char*)buf, buflen, 0) != buflen) {
+ Perror(stderr, "send", errno);
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+ } else {
+ /*
+ * Disconnect if we want to listen
+ * for responses from more than one server.
+ */
+ if (connected) {
+#ifdef CAN_RECONNECT
+ struct sockaddr_in no_addr;
+
+ no_addr.sin_family = AF_INET;
+ no_addr.sin_addr.s_addr = INADDR_ANY;
+ no_addr.sin_port = 0;
+ (void) connect(s,
+ (struct sockaddr *)
+ &no_addr,
+ sizeof no_addr);
+#else
+ int s1 = socket(PF_INET, SOCK_DGRAM,0);
+ if (s1 < 0)
+ goto bad_dg_sock;
+ (void) dup2(s1, s);
+ (void) close(s1);
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; new DG socket\n"))
+#endif /* CAN_RECONNECT */
+ connected = 0;
+ errno = 0;
+ }
+#endif /* !CANNOT_CONNECT_DGRAM */
+ if (sendto(s, (char*)buf, buflen, 0,
+ (struct sockaddr *)nsap,
+ sizeof *nsap)
+ != buflen) {
+ Aerror(stderr, "sendto", errno, *nsap);
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+#ifndef CANNOT_CONNECT_DGRAM
+ }
+#endif /* !CANNOT_CONNECT_DGRAM */
+
+ /*
+ * Wait for reply
+ */
+#ifndef NOPOLL
+ othersyscall:
+ if (use_poll) {
+ msec = (_res.retrans << try) * 1000;
+ if (try > 0)
+ msec /= _res.nscount;
+ if (msec <= 0)
+ msec = 1000;
+ } else {
+#endif
+ timeout.tv_sec = (_res.retrans << try);
+ if (try > 0)
+ timeout.tv_sec /= _res.nscount;
+ if ((long) timeout.tv_sec <= 0)
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+#ifndef NOPOLL
+ }
+#endif
+ wait:
+ if (s < 0) {
+ Perror(stderr, "s out-of-bounds", EMFILE);
+ res_close();
+ goto next_ns;
+ }
+#ifndef NOPOLL
+ if (use_poll) {
+ struct sigaction sa, osa;
+ int sigsys_installed = 0;
+
+ pfd.fd = s;
+ pfd.events = POLLIN;
+ if (use_poll == 1) {
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sa.sa_handler = SIG_IGN;
+ if (sigaction(SIGSYS, &sa, &osa) >= 0)
+ sigsys_installed = 1;
+ }
+ n = poll(&pfd, 1, msec);
+ if (sigsys_installed == 1) {
+ int oerrno = errno;
+ sigaction(SIGSYS, &osa, NULL);
+ errno = oerrno;
+ }
+ /* XXX why does nosys() return EINVAL? */
+ if (n < 0 && (errno == ENOSYS ||
+ errno == EINVAL)) {
+ use_poll = 0;
+ goto othersyscall;
+ } else if (use_poll == 1)
+ use_poll = 2;
+ if (n < 0) {
+ if (errno == EINTR)
+ goto wait;
+ Perror(stderr, "poll", errno);
+ res_close();
+ goto next_ns;
+ }
+ } else {
+#endif
+ dsmasklen = howmany(s + 1, NFDBITS) *
+ sizeof(fd_mask);
+ if (dsmasklen > sizeof(fd_set)) {
+ dsmaskp = (fd_set *)malloc(dsmasklen);
+ if (dsmaskp == NULL) {
+ res_close();
+ goto next_ns;
+ }
+ } else
+ dsmaskp = &dsmask;
+ /* only zero what we need */
+ bzero((char *)dsmaskp, dsmasklen);
+ FD_SET(s, dsmaskp);
+ n = select(s + 1, dsmaskp, (fd_set *)NULL,
+ (fd_set *)NULL, &timeout);
+ if (dsmaskp != &dsmask)
+ free(dsmaskp);
+ if (n < 0) {
+ if (errno == EINTR)
+ goto wait;
+ Perror(stderr, "select", errno);
+ res_close();
+ goto next_ns;
+ }
+#ifndef NOPOLL
+ }
+#endif
+
+ if (n == 0) {
+ /*
+ * timeout
+ */
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; timeout\n"));
+ gotsomewhere = 1;
+ res_close();
+ goto next_ns;
+ }
+ errno = 0;
+ fromlen = sizeof(struct sockaddr_in);
+ resplen = recvfrom(s, (char*)ans, anssiz, 0,
+ (struct sockaddr *)&from, &fromlen);
+ if (resplen <= 0) {
+ Perror(stderr, "recvfrom", errno);
+ res_close();
+ goto next_ns;
+ }
+ gotsomewhere = 1;
+ if (resplen < HFIXEDSZ) {
+ /*
+ * Undersized message.
+ */
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; undersized: %d\n",
+ resplen));
+ terrno = EMSGSIZE;
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+ if (hp->id != anhp->id) {
+ /*
+ * response from old query, ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; old answer:\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto wait;
+ }
+#ifdef CHECK_SRVR_ADDR
+ if (!(_res.options & RES_INSECURE1) &&
+ !res_isourserver(&from)) {
+ /*
+ * response from wrong server? ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; not our server:\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto wait;
+ }
+#endif
+ if (!(_res.options & RES_INSECURE2) &&
+ !res_queriesmatch(buf, buf + buflen,
+ ans, ans + anssiz)) {
+ /*
+ * response contains wrong query? ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; wrong query name:\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto wait;
+ }
+ if (anhp->rcode == SERVFAIL ||
+ anhp->rcode == NOTIMP ||
+ anhp->rcode == REFUSED) {
+ DprintQ(_res.options & RES_DEBUG,
+ (stdout, "server rejected query:\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ badns |= (1 << ns);
+ res_close();
+ /* don't retry if called from dig */
+ if (!_res.pfcode)
+ goto next_ns;
+ }
+ if (!(_res.options & RES_IGNTC) && anhp->tc) {
+ /*
+ * get rest of answer;
+ * use TCP with same server.
+ */
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; truncated answer\n"));
+ v_circuit = 1;
+ res_close();
+ goto same_ns;
+ }
+ } /*if vc/dg*/
+ Dprint((_res.options & RES_DEBUG) ||
+ ((_res.pfcode & RES_PRF_REPLY) &&
+ (_res.pfcode & RES_PRF_HEAD1)),
+ (stdout, ";; got answer:\n"));
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ""),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ /*
+ * If using virtual circuits, we assume that the first server
+ * is preferred over the rest (i.e. it is on the local
+ * machine) and only keep that one open.
+ * If we have temporarily opened a virtual circuit,
+ * or if we haven't been asked to keep a socket open,
+ * close the socket.
+ */
+ if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
+ !(_res.options & RES_STAYOPEN)) {
+ res_close();
+ }
+ if (Rhook) {
+ int done = 0, loops = 0;
+
+ do {
+ res_sendhookact act;
+
+ act = (*Rhook)(nsap, buf, buflen,
+ ans, anssiz, &resplen);
+ switch (act) {
+ case res_goahead:
+ case res_done:
+ done = 1;
+ break;
+ case res_nextns:
+ res_close();
+ goto next_ns;
+ case res_modified:
+ /* give the hook another try */
+ if (++loops < 42) /*doug adams*/
+ break;
+ /*FALLTHROUGH*/
+ case res_error:
+ /*FALLTHROUGH*/
+ default:
+ return (-1);
+ }
+ } while (!done);
+
+ }
+ return (resplen);
+ next_ns: ;
+ } /*foreach ns*/
+ } /*foreach retry*/
+ res_close();
+ if (!v_circuit) {
+ if (!gotsomewhere)
+ errno = ECONNREFUSED; /* no nameservers found */
+ else
+ errno = ETIMEDOUT; /* no answer obtained */
+ } else
+ errno = terrno;
+ return (-1);
+}
+
+/*
+ * This routine is for closing the socket if a virtual circuit is used and
+ * the program wants to close it. This provides support for endhostent()
+ * which expects to close the socket.
+ *
+ * This routine is not expected to be user visible.
+ */
+void
+res_close()
+{
+ if (s >= 0) {
+ (void) close(s);
+ s = -1;
+ connected = 0;
+ vc = 0;
+ }
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <resolv.h>.
+ */
+#undef res_close
+__weak_reference(__res_close, _res_close);
+#undef res_send
+__weak_reference(__res_send, res_send);
diff --git a/lib/libc/net/res_update.c b/lib/libc/net/res_update.c
new file mode 100644
index 0000000..a877d4a
--- /dev/null
+++ b/lib/libc/net/res_update.c
@@ -0,0 +1,516 @@
+#if !defined(lint) && !defined(SABER)
+static char rcsid[] = "$FreeBSD$";
+#endif /* not lint */
+
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Based on the Dynamic DNS reference implementation by Viraj Bais
+ * <viraj_bais@ccm.fm.intel.com>
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <limits.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * Separate a linked list of records into groups so that all records
+ * in a group will belong to a single zone on the nameserver.
+ * Create a dynamic update packet for each zone and send it to the
+ * nameservers for that zone, and await answer.
+ * Abort if error occurs in updating any zone.
+ * Return the number of zones updated on success, < 0 on error.
+ *
+ * On error, caller must deal with the unsynchronized zones
+ * eg. an A record might have been successfully added to the forward
+ * zone but the corresponding PTR record would be missing if error
+ * was encountered while updating the reverse zone.
+ */
+
+#define NSMAX 16
+
+struct ns1 {
+ char nsname[MAXDNAME];
+ struct in_addr nsaddr1;
+};
+
+struct zonegrp {
+ char z_origin[MAXDNAME];
+ int16_t z_class;
+ char z_soardata[MAXDNAME + 5 * INT32SZ];
+ struct ns1 z_ns[NSMAX];
+ int z_nscount;
+ ns_updrec * z_rr;
+ struct zonegrp *z_next;
+};
+
+
+int
+res_update(ns_updrec *rrecp_in) {
+ ns_updrec *rrecp, *tmprrecp;
+ u_char buf[PACKETSZ], answer[PACKETSZ], packet[2*PACKETSZ];
+ char name[MAXDNAME], zname[MAXDNAME], primary[MAXDNAME],
+ mailaddr[MAXDNAME];
+ u_char soardata[2*MAXCDNAME+5*INT32SZ];
+ char *dname, *svdname, *cp1, *target;
+ u_char *cp, *eom;
+ HEADER *hp = (HEADER *) answer;
+ struct zonegrp *zptr = NULL, *tmpzptr, *prevzptr, *zgrp_start = NULL;
+ int i, j, k = 0, n, ancount, nscount, arcount, rcode, rdatasize,
+ newgroup, done, myzone, seen_before, numzones = 0;
+ u_int16_t dlen, class, qclass, type, qtype;
+ u_int32_t ttl;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+
+ for (rrecp = rrecp_in; rrecp; rrecp = rrecp->r_next) {
+ dname = rrecp->r_dname;
+ n = strlen(dname);
+ if (dname[n-1] == '.')
+ dname[n-1] = '\0';
+ qtype = T_SOA;
+ qclass = rrecp->r_class;
+ done = 0;
+ seen_before = 0;
+
+ while (!done && dname) {
+ if (qtype == T_SOA) {
+ for (tmpzptr = zgrp_start;
+ tmpzptr && !seen_before;
+ tmpzptr = tmpzptr->z_next) {
+ if (strcasecmp(dname,
+ tmpzptr->z_origin) == 0 &&
+ tmpzptr->z_class == qclass)
+ seen_before++;
+ for (tmprrecp = tmpzptr->z_rr;
+ tmprrecp && !seen_before;
+ tmprrecp = tmprrecp->r_grpnext)
+ if (strcasecmp(dname, tmprrecp->r_dname) == 0
+ && tmprrecp->r_class == qclass) {
+ seen_before++;
+ break;
+ }
+ if (seen_before) {
+ /*
+ * Append to the end of
+ * current group.
+ */
+ for (tmprrecp = tmpzptr->z_rr;
+ tmprrecp->r_grpnext;
+ tmprrecp = tmprrecp->r_grpnext)
+ (void)NULL;
+ tmprrecp->r_grpnext = rrecp;
+ rrecp->r_grpnext = NULL;
+ done = 1;
+ break;
+ }
+ }
+ } else if (qtype == T_A) {
+ for (tmpzptr = zgrp_start;
+ tmpzptr && !done;
+ tmpzptr = tmpzptr->z_next)
+ for (i = 0; i < tmpzptr->z_nscount; i++)
+ if (tmpzptr->z_class == qclass &&
+ strcasecmp(tmpzptr->z_ns[i].nsname,
+ dname) == 0 &&
+ tmpzptr->z_ns[i].nsaddr1.s_addr != 0) {
+ zptr->z_ns[k].nsaddr1.s_addr =
+ tmpzptr->z_ns[i].nsaddr1.s_addr;
+ done = 1;
+ break;
+ }
+ }
+ if (done)
+ break;
+ n = res_mkquery(QUERY, dname, qclass, qtype, NULL,
+ 0, NULL, buf, sizeof buf);
+ if (n <= 0) {
+ fprintf(stderr, "res_update: mkquery failed\n");
+ return (n);
+ }
+ n = res_send(buf, n, answer, sizeof answer);
+ if (n < 0) {
+ fprintf(stderr, "res_update: send error for %s\n",
+ rrecp->r_dname);
+ return (n);
+ }
+ if (n < HFIXEDSZ)
+ return (-1);
+ ancount = ntohs(hp->ancount);
+ nscount = ntohs(hp->nscount);
+ arcount = ntohs(hp->arcount);
+ rcode = hp->rcode;
+ cp = answer + HFIXEDSZ;
+ eom = answer + n;
+ /* skip the question section */
+ n = dn_skipname(cp, eom);
+ if (n < 0 || cp + n + 2 * INT16SZ > eom)
+ return (-1);
+ cp += n + 2 * INT16SZ;
+
+ if (qtype == T_SOA) {
+ if (ancount == 0 && nscount == 0 && arcount == 0) {
+ /*
+ * if (rcode == NOERROR) then the dname exists but
+ * has no soa record associated with it.
+ * if (rcode == NXDOMAIN) then the dname does not
+ * exist and the server is replying out of NCACHE.
+ * in either case, proceed with the next try
+ */
+ dname = strchr(dname, '.');
+ if (dname != NULL)
+ dname++;
+ continue;
+ } else if ((rcode == NOERROR || rcode == NXDOMAIN) &&
+ ancount == 0 &&
+ nscount == 1 && arcount == 0) {
+ /*
+ * name/data does not exist, soa record supplied in the
+ * authority section
+ */
+ /* authority section must contain the soa record */
+ if ((n = dn_expand(answer, eom, cp, zname,
+ sizeof zname)) < 0)
+ return (n);
+ cp += n;
+ if (cp + 2 * INT16SZ > eom)
+ return (-1);
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ if (type != T_SOA || class != qclass) {
+ fprintf(stderr, "unknown answer\n");
+ return (-1);
+ }
+ myzone = 0;
+ svdname = dname;
+ while (dname)
+ if (strcasecmp(dname, zname) == 0) {
+ myzone = 1;
+ break;
+ } else if ((dname = strchr(dname, '.')) != NULL)
+ dname++;
+ if (!myzone) {
+ dname = strchr(svdname, '.');
+ if (dname != NULL)
+ dname++;
+ continue;
+ }
+ nscount = 0;
+ /* fallthrough */
+ } else if (rcode == NOERROR && ancount == 1) {
+ /*
+ * found the zone name
+ * new servers will supply NS records for the zone
+ * in authority section and A records for those
+ * nameservers in the additional section
+ * older servers have to be explicitly queried for
+ * NS records for the zone
+ */
+ /* answer section must contain the soa record */
+ if ((n = dn_expand(answer, eom, cp, zname,
+ sizeof zname)) < 0)
+ return (n);
+ else
+ cp += n;
+ if (cp + 2 * INT16SZ > eom)
+ return (-1);
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ if (type == T_CNAME) {
+ dname = strchr(dname, '.');
+ if (dname != NULL)
+ dname++;
+ continue;
+ }
+ if (strcasecmp(dname, zname) != 0 ||
+ type != T_SOA ||
+ class != rrecp->r_class) {
+ fprintf(stderr, "unknown answer\n");
+ return (-1);
+ }
+ /* FALLTHROUGH */
+ } else {
+ fprintf(stderr,
+ "unknown response: ans=%d, auth=%d, add=%d, rcode=%d\n",
+ ancount, nscount, arcount, hp->rcode);
+ return (-1);
+ }
+ if (cp + INT32SZ + INT16SZ > eom)
+ return (-1);
+ /* continue processing the soa record */
+ GETLONG(ttl, cp);
+ GETSHORT(dlen, cp);
+ if (cp + dlen > eom)
+ return (-1);
+ newgroup = 1;
+ zptr = zgrp_start;
+ prevzptr = NULL;
+ while (zptr) {
+ if (strcasecmp(zname, zptr->z_origin) == 0 &&
+ type == T_SOA && class == qclass) {
+ newgroup = 0;
+ break;
+ }
+ prevzptr = zptr;
+ zptr = zptr->z_next;
+ }
+ if (!newgroup) {
+ for (tmprrecp = zptr->z_rr;
+ tmprrecp->r_grpnext;
+ tmprrecp = tmprrecp->r_grpnext)
+ ;
+ tmprrecp->r_grpnext = rrecp;
+ rrecp->r_grpnext = NULL;
+ done = 1;
+ cp += dlen;
+ break;
+ } else {
+ if ((n = dn_expand(answer, eom, cp, primary,
+ sizeof primary)) < 0)
+ return (n);
+ cp += n;
+ /*
+ * We don't have to bounds check here because the
+ * next use of 'cp' is in dn_expand().
+ */
+ cp1 = (char *)soardata;
+ strcpy(cp1, primary);
+ cp1 += strlen(cp1) + 1;
+ if ((n = dn_expand(answer, eom, cp, mailaddr,
+ sizeof mailaddr)) < 0)
+ return (n);
+ cp += n;
+ strcpy(cp1, mailaddr);
+ cp1 += strlen(cp1) + 1;
+ if (cp + 5*INT32SZ > eom)
+ return (-1);
+ memcpy(cp1, cp, 5*INT32SZ);
+ cp += 5*INT32SZ;
+ cp1 += 5*INT32SZ;
+ rdatasize = (u_char *)cp1 - soardata;
+ zptr = calloc(1, sizeof(struct zonegrp));
+ if (zptr == NULL)
+ return (-1);
+ if (zgrp_start == NULL)
+ zgrp_start = zptr;
+ else
+ prevzptr->z_next = zptr;
+ zptr->z_rr = rrecp;
+ rrecp->r_grpnext = NULL;
+ strcpy(zptr->z_origin, zname);
+ zptr->z_class = class;
+ memcpy(zptr->z_soardata, soardata, rdatasize);
+ /* fallthrough to process NS and A records */
+ }
+ } else if (qtype == T_NS) {
+ if (rcode == NOERROR && ancount > 0) {
+ strcpy(zname, dname);
+ for (zptr = zgrp_start; zptr; zptr = zptr->z_next) {
+ if (strcasecmp(zname, zptr->z_origin) == 0)
+ break;
+ }
+ if (zptr == NULL)
+ /* should not happen */
+ return (-1);
+ if (nscount > 0) {
+ /*
+ * answer and authority sections contain
+ * the same information, skip answer section
+ */
+ for (j = 0; j < ancount; j++) {
+ n = dn_skipname(cp, eom);
+ if (n < 0)
+ return (-1);
+ n += 2*INT16SZ + INT32SZ;
+ if (cp + n + INT16SZ > eom)
+ return (-1);
+ cp += n;
+ GETSHORT(dlen, cp);
+ cp += dlen;
+ }
+ } else
+ nscount = ancount;
+ /* fallthrough to process NS and A records */
+ } else {
+ fprintf(stderr, "cannot determine nameservers for %s:\
+ans=%d, auth=%d, add=%d, rcode=%d\n",
+ dname, ancount, nscount, arcount, hp->rcode);
+ return (-1);
+ }
+ } else if (qtype == T_A) {
+ if (rcode == NOERROR && ancount > 0) {
+ arcount = ancount;
+ ancount = nscount = 0;
+ /* fallthrough to process A records */
+ } else {
+ fprintf(stderr, "cannot determine address for %s:\
+ans=%d, auth=%d, add=%d, rcode=%d\n",
+ dname, ancount, nscount, arcount, hp->rcode);
+ return (-1);
+ }
+ }
+ /* process NS records for the zone */
+ j = 0;
+ for (i = 0; i < nscount; i++) {
+ if ((n = dn_expand(answer, eom, cp, name,
+ sizeof name)) < 0)
+ return (n);
+ cp += n;
+ if (cp + 3 * INT16SZ + INT32SZ > eom)
+ return (-1);
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ GETLONG(ttl, cp);
+ GETSHORT(dlen, cp);
+ if (cp + dlen > eom)
+ return (-1);
+ if (strcasecmp(name, zname) == 0 &&
+ type == T_NS && class == qclass) {
+ if ((n = dn_expand(answer, eom, cp,
+ name, sizeof name)) < 0)
+ return (n);
+ target = zptr->z_ns[j++].nsname;
+ strcpy(target, name);
+ }
+ cp += dlen;
+ }
+ if (zptr->z_nscount == 0)
+ zptr->z_nscount = j;
+ /* get addresses for the nameservers */
+ for (i = 0; i < arcount; i++) {
+ if ((n = dn_expand(answer, eom, cp, name,
+ sizeof name)) < 0)
+ return (n);
+ cp += n;
+ if (cp + 3 * INT16SZ + INT32SZ > eom)
+ return (-1);
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ GETLONG(ttl, cp);
+ GETSHORT(dlen, cp);
+ if (cp + dlen > eom)
+ return (-1);
+ if (type == T_A && dlen == INT32SZ && class == qclass) {
+ for (j = 0; j < zptr->z_nscount; j++)
+ if (strcasecmp(name, zptr->z_ns[j].nsname) == 0) {
+ memcpy(&zptr->z_ns[j].nsaddr1.s_addr, cp,
+ INT32SZ);
+ break;
+ }
+ }
+ cp += dlen;
+ }
+ if (zptr->z_nscount == 0) {
+ dname = zname;
+ qtype = T_NS;
+ continue;
+ }
+ done = 1;
+ for (k = 0; k < zptr->z_nscount; k++)
+ if (zptr->z_ns[k].nsaddr1.s_addr == 0) {
+ done = 0;
+ dname = zptr->z_ns[k].nsname;
+ qtype = T_A;
+ }
+
+ } /* while */
+ }
+
+ _res.options |= RES_DEBUG;
+ for (zptr = zgrp_start; zptr; zptr = zptr->z_next) {
+
+ /* append zone section */
+ rrecp = res_mkupdrec(ns_s_zn, zptr->z_origin,
+ zptr->z_class, ns_t_soa, 0);
+ if (rrecp == NULL) {
+ fprintf(stderr, "saverrec error\n");
+ fflush(stderr);
+ return (-1);
+ }
+ rrecp->r_grpnext = zptr->z_rr;
+ zptr->z_rr = rrecp;
+
+ n = res_mkupdate(zptr->z_rr, packet, sizeof packet);
+ if (n < 0) {
+ fprintf(stderr, "res_mkupdate error\n");
+ fflush(stderr);
+ return (-1);
+ } else
+ fprintf(stdout, "res_mkupdate: packet size = %d\n", n);
+
+ /*
+ * Override the list of NS records from res_init() with
+ * the authoritative nameservers for the zone being updated.
+ * Sort primary to be the first in the list of nameservers.
+ */
+ for (i = 0; i < zptr->z_nscount; i++) {
+ if (strcasecmp(zptr->z_ns[i].nsname,
+ zptr->z_soardata) == 0) {
+ struct in_addr tmpaddr;
+
+ if (i != 0) {
+ strcpy(zptr->z_ns[i].nsname,
+ zptr->z_ns[0].nsname);
+ strcpy(zptr->z_ns[0].nsname,
+ zptr->z_soardata);
+ tmpaddr = zptr->z_ns[i].nsaddr1;
+ zptr->z_ns[i].nsaddr1 =
+ zptr->z_ns[0].nsaddr1;
+ zptr->z_ns[0].nsaddr1 = tmpaddr;
+ }
+ break;
+ }
+ }
+ for (i = 0; i < MAXNS; i++) {
+ _res.nsaddr_list[i].sin_addr = zptr->z_ns[i].nsaddr1;
+ _res.nsaddr_list[i].sin_family = AF_INET;
+ _res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);
+ }
+ _res.nscount = (zptr->z_nscount < MAXNS) ?
+ zptr->z_nscount : MAXNS;
+ n = res_send(packet, n, answer, sizeof(answer));
+ if (n < 0) {
+ fprintf(stderr, "res_send: send error, n=%d\n", n);
+ break;
+ } else
+ numzones++;
+ }
+
+ /* free malloc'ed memory */
+ while(zgrp_start) {
+ zptr = zgrp_start;
+ zgrp_start = zgrp_start->z_next;
+ res_freeupdrec(zptr->z_rr); /* Zone section we allocated. */
+ free((char *)zptr);
+ }
+
+ return (numzones);
+}
diff --git a/lib/libc/net/resolver.3 b/lib/libc/net/resolver.3
new file mode 100644
index 0000000..4e71585
--- /dev/null
+++ b/lib/libc/net/resolver.3
@@ -0,0 +1,352 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)resolver.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt RESOLVER 3
+.Os BSD 4.3
+.Sh NAME
+.Nm res_query ,
+.Nm res_search ,
+.Nm res_mkquery ,
+.Nm res_send ,
+.Nm res_init ,
+.Nm dn_comp ,
+.Nm dn_expand
+.Nd resolver routines
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <netinet/in.h>
+.Fd #include <arpa/nameser.h>
+.Fd #include <resolv.h>
+.Ft int
+.Fo res_query
+.Fa "const char *dname"
+.Fa "int class"
+.Fa "int type"
+.Fa "u_char *answer"
+.Fa "int anslen"
+.Fc
+.Ft int
+.Fo res_search
+.Fa "const char *dname"
+.Fa "int class"
+.Fa "int type"
+.Fa "u_char *answer"
+.Fa "int anslen"
+.Fc
+.Ft int
+.Fo res_mkquery
+.Fa "int op"
+.Fa "const char *dname"
+.Fa "int class"
+.Fa "int type"
+.Fa "const u_char *data"
+.Fa "int datalen"
+.Fa "const u_char *newrr_in"
+.Fa "u_char *buf"
+.Fa "int buflen"
+.Fc
+.Ft int
+.Fo res_send
+.Fa "const u_char *msg"
+.Fa "int msglen"
+.Fa "u_char *answer"
+.Fa "int anslen"
+.Fc
+.Ft int
+.Fn res_init
+.Fo dn_comp
+.Fa "const char *exp_dn"
+.Fa "u_char *comp_dn"
+.Fa "int length"
+.Fa "u_char **dnptrs"
+.Fa "u_char **lastdnptr"
+.Fc
+.Ft int
+.Fo dn_expand
+.Fa "const u_char *msg"
+.Fa "const u_char *eomorig"
+.Fa "const u_char *comp_dn"
+.Fa "char *exp_dn"
+.Fa "int length"
+.Fc
+.Sh DESCRIPTION
+These routines are used for making, sending and interpreting
+query and reply messages with Internet domain name servers.
+.Pp
+Global configuration and state information that is used by the
+resolver routines is kept in the structure
+.Em _res .
+Most of the values have reasonable defaults and can be ignored.
+Options
+stored in
+.Em _res.options
+are defined in
+.Pa resolv.h
+and are as follows.
+Options are stored as a simple bit mask containing the bitwise ``or''
+of the options enabled.
+.Bl -tag -width RES_DEFNAMES
+.It Dv RES_INIT
+True if the initial name server address and default domain name are
+initialized (i.e.,
+.Fn res_init
+has been called).
+.It Dv RES_DEBUG
+Print debugging messages.
+.It Dv RES_AAONLY
+Accept authoritative answers only.
+With this option,
+.Fn res_send
+should continue until it finds an authoritative answer or finds an error.
+Currently this is not implemented.
+.It Dv RES_USEVC
+Use
+.Tn TCP
+connections for queries instead of
+.Tn UDP
+datagrams.
+.It Dv RES_STAYOPEN
+Used with
+.Dv RES_USEVC
+to keep the
+.Tn TCP
+connection open between
+queries.
+This is useful only in programs that regularly do many queries.
+.Tn UDP
+should be the normal mode used.
+.It Dv RES_IGNTC
+Unused currently (ignore truncation errors, i.e., don't retry with
+.Tn TCP ) .
+.It Dv RES_RECURSE
+Set the recursion-desired bit in queries.
+This is the default.
+.Pf ( Fn res_send
+does not do iterative queries and expects the name server
+to handle recursion.)
+.It Dv RES_DEFNAMES
+If set,
+.Fn res_search
+will append the default domain name to single-component names
+(those that do not contain a dot).
+This option is enabled by default.
+.It Dv RES_DNSRCH
+If this option is set,
+.Fn res_search
+will search for host names in the current domain and in parent domains; see
+.Xr hostname 7 .
+This is used by the standard host lookup routine
+.Xr gethostbyname 3 .
+This option is enabled by default.
+.It Dv RES_NOALIASES
+This option turns off the user level aliasing feature controlled by the
+.Dq Ev HOSTALIASES
+environment variable. Network daemons should set this option.
+.El
+.Pp
+The
+.Fn res_init
+routine
+reads the configuration file (if any; see
+.Xr resolver 5 )
+to get the default domain name,
+search list and
+the Internet address of the local name server(s).
+If no server is configured, the host running
+the resolver is tried.
+The current domain name is defined by the hostname
+if not specified in the configuration file;
+it can be overridden by the environment variable
+.Ev LOCALDOMAIN .
+This environment variable may contain several blank-separated
+tokens if you wish to override the
+.Em "search list"
+on a per-process basis. This is similar to the
+.Em search
+command in the configuration file.
+Another environment variable (
+.Dq Ev RES_OPTIONS
+can be set to
+override certain internal resolver options which are otherwise
+set by changing fields in the
+.Em _res
+structure or are inherited from the configuration file's
+.Em options
+command. The syntax of the
+.Dq Ev RES_OPTIONS
+environment variable is explained in
+.Xr resolver 5 .
+Initialization normally occurs on the first call
+to one of the following routines.
+.Pp
+The
+.Fn res_query
+function provides an interface to the server query mechanism.
+It constructs a query, sends it to the local server,
+awaits a response, and makes preliminary checks on the reply.
+The query requests information of the specified
+.Fa type
+and
+.Fa class
+for the specified fully-qualified domain name
+.Fa dname .
+The reply message is left in the
+.Fa answer
+buffer with length
+.Fa anslen
+supplied by the caller.
+.Pp
+The
+.Fn res_search
+routine makes a query and awaits a response like
+.Fn res_query ,
+but in addition, it implements the default and search rules
+controlled by the
+.Dv RES_DEFNAMES
+and
+.Dv RES_DNSRCH
+options.
+It returns the first successful reply.
+.Pp
+The remaining routines are lower-level routines used by
+.Fn res_query .
+The
+.Fn res_mkquery
+function
+constructs a standard query message and places it in
+.Fa buf .
+It returns the size of the query, or \-1 if the query is
+larger than
+.Fa buflen .
+The query type
+.Fa op
+is usually
+.Dv QUERY ,
+but can be any of the query types defined in
+.Aq Pa arpa/nameser.h .
+The domain name for the query is given by
+.Fa dname .
+.Fa Newrr
+is currently unused but is intended for making update messages.
+.Pp
+The
+.Fn res_send
+routine
+sends a pre-formatted query and returns an answer.
+It will call
+.Fn res_init
+if
+.Dv RES_INIT
+is not set, send the query to the local name server, and
+handle timeouts and retries.
+The length of the reply message is returned, or
+\-1 if there were errors.
+.Pp
+The
+.Fn dn_comp
+function
+compresses the domain name
+.Fa exp_dn
+and stores it in
+.Fa comp_dn .
+The size of the compressed name is returned or \-1 if there were errors.
+The size of the array pointed to by
+.Fa comp_dn
+is given by
+.Fa length .
+The compression uses
+an array of pointers
+.Fa dnptrs
+to previously-compressed names in the current message.
+The first pointer points to
+the beginning of the message and the list ends with
+.Dv NULL .
+The limit to the array is specified by
+.Fa lastdnptr .
+A side effect of
+.Fn dn_comp
+is to update the list of pointers for
+labels inserted into the message
+as the name is compressed.
+If
+.Em dnptr
+is
+.Dv NULL, names are not compressed.
+If
+.Fa lastdnptr
+is
+.Dv NULL ,
+the list of labels is not updated.
+.Pp
+The
+.Fn dn_expand
+entry
+expands the compressed domain name
+.Fa comp_dn
+to a full domain name
+The compressed name is contained in a query or reply message;
+.Fa msg
+is a pointer to the beginning of the message.
+The uncompressed name is placed in the buffer indicated by
+.Fa exp_dn
+which is of size
+.Fa length .
+The size of compressed name is returned or \-1 if there was an error.
+.Sh FILES
+.Bl -tag -width Pa
+/etc/resolv.conf
+The configuration file
+see
+.Xr resolver 5 .
+.El
+.Sh SEE ALSO
+.Xr gethostbyname 3 ,
+.Xr resolver 5 ,
+.Xr hostname 7 ,
+.Xr named 8
+.Pp
+.%T RFC1032 ,
+.%T RFC1033 ,
+.%T RFC1034 ,
+.%T RFC1035 ,
+.%T RFC974
+.Rs
+.%T "Name Server Operations Guide for BIND"
+.Re
+.Sh HISTORY
+The
+.Nm
+function appeared in
+.Bx 4.3 .
diff --git a/lib/libc/net/rthdr.c b/lib/libc/net/rthdr.c
new file mode 100644
index 0000000..ce2a33c
--- /dev/null
+++ b/lib/libc/net/rthdr.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+
+#include <string.h>
+#include <stdio.h>
+
+size_t
+inet6_rthdr_space(type, seg)
+ int type, seg;
+{
+ switch(type) {
+ case IPV6_RTHDR_TYPE_0:
+ if (seg < 1 || seg > 23)
+ return(0);
+ return(CMSG_SPACE(sizeof(struct in6_addr) * (seg - 1)
+ + sizeof(struct ip6_rthdr0)));
+ default:
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_space: unknown type(%d)\n", type);
+#endif
+ return(0);
+ }
+}
+
+struct cmsghdr *
+inet6_rthdr_init(bp, type)
+ void *bp;
+ int type;
+{
+ register struct cmsghdr *ch = (struct cmsghdr *)bp;
+ register struct ip6_rthdr *rthdr = (struct ip6_rthdr *)(ch + 1);
+
+ ch->cmsg_level = IPPROTO_IPV6;
+ ch->cmsg_type = IPV6_RTHDR;
+
+ switch(type) {
+ case IPV6_RTHDR_TYPE_0:
+ ch->cmsg_len = CMSG_LEN(sizeof(struct ip6_rthdr0) - sizeof(struct in6_addr));
+ bzero(rthdr, sizeof(struct ip6_rthdr0));
+ rthdr->ip6r_type = IPV6_RTHDR_TYPE_0;
+ return(ch);
+ default:
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_init: unknown type(%d)\n", type);
+#endif
+ return(NULL);
+ }
+}
+
+int
+inet6_rthdr_add(cmsg, addr, flags)
+ struct cmsghdr *cmsg;
+ const struct in6_addr *addr;
+ u_int flags;
+{
+ register struct ip6_rthdr *rthdr = (struct ip6_rthdr *)(cmsg + 1);
+
+ switch(rthdr->ip6r_type) {
+ case IPV6_RTHDR_TYPE_0:
+ {
+ struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
+ if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT) {
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_add: unsupported flag(%d)\n", flags);
+#endif
+ return(-1);
+ }
+ if (rt0->ip6r0_segleft == 23) {
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_add: segment overflow\n");
+#endif
+ return(-1);
+ }
+ if (flags == IPV6_RTHDR_STRICT) {
+ int c, b;
+ c = rt0->ip6r0_segleft / 8;
+ b = rt0->ip6r0_segleft % 8;
+ rt0->ip6r0_slmap[c] |= (1 << (7 - b));
+ }
+ rt0->ip6r0_segleft++;
+ bcopy(addr, (caddr_t)rt0 + ((rt0->ip6r0_len + 1) << 3),
+ sizeof(struct in6_addr));
+ rt0->ip6r0_len += sizeof(struct in6_addr) >> 3;
+ cmsg->cmsg_len = CMSG_LEN((rt0->ip6r0_len + 1) << 3);
+ break;
+ }
+ default:
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_add: unknown type(%d)\n",
+ rthdr->ip6r_type);
+#endif
+ return(-1);
+ }
+
+ return(0);
+}
+
+int
+inet6_rthdr_lasthop(cmsg, flags)
+ struct cmsghdr *cmsg;
+ unsigned int flags;
+{
+ register struct ip6_rthdr *rthdr = (struct ip6_rthdr *)(cmsg + 1);
+
+ switch(rthdr->ip6r_type) {
+ case IPV6_RTHDR_TYPE_0:
+ {
+ struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
+ if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT) {
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_lasthop: unsupported flag(%d)\n", flags);
+#endif
+ return(-1);
+ }
+ if (rt0->ip6r0_segleft > 23) {
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_add: segment overflow\n");
+#endif
+ return(-1);
+ }
+ if (flags == IPV6_RTHDR_STRICT) {
+ int c, b;
+ c = rt0->ip6r0_segleft / 8;
+ b = rt0->ip6r0_segleft % 8;
+ rt0->ip6r0_slmap[c] |= (1 << (7 - b));
+ }
+ break;
+ }
+ default:
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_lasthop: unknown type(%d)\n",
+ rthdr->ip6r_type);
+#endif
+ return(-1);
+ }
+
+ return(0);
+}
+
+#if 0
+int
+inet6_rthdr_reverse(in, out)
+ const struct cmsghdr *in;
+ struct cmsghdr *out;
+{
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_reverse: not implemented yet\n");
+#endif
+ return -1;
+}
+#endif
+
+int
+inet6_rthdr_segments(cmsg)
+ const struct cmsghdr *cmsg;
+{
+ register struct ip6_rthdr *rthdr = (struct ip6_rthdr *)(cmsg + 1);
+
+ switch(rthdr->ip6r_type) {
+ case IPV6_RTHDR_TYPE_0:
+ {
+ struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
+
+ if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_segments: invalid size(%d)\n",
+ rt0->ip6r0_len);
+#endif
+ return -1;
+ }
+
+ return (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
+ }
+
+ default:
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_segments: unknown type(%d)\n",
+ rthdr->ip6r_type);
+#endif
+ return -1;
+ }
+}
+
+struct in6_addr *
+inet6_rthdr_getaddr(cmsg, index)
+ struct cmsghdr *cmsg;
+ int index;
+{
+ register struct ip6_rthdr *rthdr = (struct ip6_rthdr *)(cmsg + 1);
+
+ switch(rthdr->ip6r_type) {
+ case IPV6_RTHDR_TYPE_0:
+ {
+ struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
+ int naddr;
+
+ if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_getaddr: invalid size(%d)\n",
+ rt0->ip6r0_len);
+#endif
+ return NULL;
+ }
+ naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
+ if (index <= 0 || naddr < index) {
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_getaddr: invalid index(%d)\n", index);
+#endif
+ return NULL;
+ }
+ return &rt0->ip6r0_addr[index - 1];
+ }
+
+ default:
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_getaddr: unknown type(%d)\n",
+ rthdr->ip6r_type);
+#endif
+ return NULL;
+ }
+}
+
+int
+inet6_rthdr_getflags(cmsg, index)
+ const struct cmsghdr *cmsg;
+ int index;
+{
+ register struct ip6_rthdr *rthdr = (struct ip6_rthdr *)(cmsg + 1);
+
+ switch(rthdr->ip6r_type) {
+ case IPV6_RTHDR_TYPE_0:
+ {
+ struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
+ int naddr;
+
+ if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_getflags: invalid size(%d)\n",
+ rt0->ip6r0_len);
+#endif
+ return -1;
+ }
+ naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
+ if (index < 0 || naddr < index) {
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_getflags: invalid index(%d)\n", index);
+#endif
+ return -1;
+ }
+ if (rt0->ip6r0_slmap[index / 8] & (0x80 >> (index % 8)))
+ return IPV6_RTHDR_STRICT;
+ else
+ return IPV6_RTHDR_LOOSE;
+ }
+
+ default:
+#ifdef DEBUG
+ fprintf(stderr, "inet6_rthdr_getflags: unknown type(%d)\n",
+ rthdr->ip6r_type);
+#endif
+ return -1;
+ }
+}
diff --git a/lib/libc/net/send.c b/lib/libc/net/send.c
new file mode 100644
index 0000000..81151c4
--- /dev/null
+++ b/lib/libc/net/send.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)send.c 8.2 (Berkeley) 2/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <stddef.h>
+
+ssize_t
+send(s, msg, len, flags)
+ int s, flags;
+ size_t len;
+ const void *msg;
+{
+ return (sendto(s, msg, len, flags, NULL, 0));
+}
diff --git a/lib/libc/net/vars.c b/lib/libc/net/vars.c
new file mode 100644
index 0000000..bf6b57a
--- /dev/null
+++ b/lib/libc/net/vars.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+/*
+ * Definitions of some costant IPv6 addresses.
+ */
+const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
+const struct in6_addr in6addr_nodelocal_allnodes = IN6ADDR_NODELOCAL_ALLNODES_INIT;
+const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
+
diff --git a/lib/libc/nls/Makefile.inc b/lib/libc/nls/Makefile.inc
new file mode 100644
index 0000000..56a664d
--- /dev/null
+++ b/lib/libc/nls/Makefile.inc
@@ -0,0 +1,10 @@
+# from $NetBSD: Makefile.inc,v 1.7 1995/02/27 13:06:20 cgd Exp $
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libc/nls
+
+SRCS+= catclose.c catgets.c catopen.c msgcat.c
+
+.if ${LIB} == "c"
+MAN3+= catclose.3 catgets.3 catopen.3
+.endif
diff --git a/lib/libc/nls/catclose.3 b/lib/libc/nls/catclose.3
new file mode 100644
index 0000000..fcdecc5
--- /dev/null
+++ b/lib/libc/nls/catclose.3
@@ -0,0 +1,55 @@
+.\" $FreeBSD$
+.\"
+.\" Copyright (c) 1994 Winning Strategies, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Winning Strategies, Inc.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd May 29, 1994
+.Dt CATCLOSE 3
+.Os
+.Sh NAME
+.Nm catclose
+.Nd close message catalog
+.Sh SYNOPSIS
+.Fd #include <nl_types.h>
+.Ft int
+.Fn catclose "nl_catd catd"
+.Sh DESCRIPTION
+The
+.Fn catclose
+function closes the message catalog specified by the argument
+.Fa catd .
+.Sh SEE ALSO
+.Xr gencat 1 ,
+.Xr catgets 3 ,
+.Xr catopen 3
+.Sh STANDARDS
+The
+.Fn catclose
+function conforms to
+.St -xpg4 .
+
diff --git a/lib/libc/nls/catclose.c b/lib/libc/nls/catclose.c
new file mode 100644
index 0000000..a732666
--- /dev/null
+++ b/lib/libc/nls/catclose.c
@@ -0,0 +1,25 @@
+/* $FreeBSD$ */
+
+/*
+ * Written by J.T. Conklin, 10/05/94
+ * Public domain.
+ */
+
+#include <sys/cdefs.h>
+
+#ifdef __indr_reference
+__indr_reference(_catclose,catclose);
+#else
+
+#include <nl_types.h>
+
+extern int _catclose __P((nl_catd));
+
+int
+catclose(catd)
+ nl_catd catd;
+{
+ return _catclose(catd);
+}
+
+#endif
diff --git a/lib/libc/nls/catgets.3 b/lib/libc/nls/catgets.3
new file mode 100644
index 0000000..9359e5f
--- /dev/null
+++ b/lib/libc/nls/catgets.3
@@ -0,0 +1,68 @@
+.\" $FreeBSD$
+.\"
+.\" Copyright (c) 1994 Winning Strategies, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Winning Strategies, Inc.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd May 29, 1994
+.Dt CATGETS 3
+.Os
+.Sh NAME
+.Nm catgets
+.Nd retrieve string from message catalog
+.Sh SYNOPSIS
+.Fd #include <nl_types.h>
+.Ft char *
+.Fn catgets "nl_catd catd" "int set_id" "int msg_id" "const char *s"
+.Sh DESCRIPTION
+The
+.Fn catgets
+function attempts to retrieve message
+.Fa msg_id
+of set
+.Fa set_id
+from the message catalog referenced by the descriptor
+.Fa catd .
+The argument
+.Fa s
+points to a default message which is returned if the function
+is unable to retrieve the specified message.
+.Sh RETURN VALUE
+If the specified message was retrieved successfully,
+.Fn catgets
+returns a pointer to an internal buffer containing the message string;
+otherwise it returns
+.Fa s .
+.Sh SEE ALSO
+.Xr gencat 1 ,
+.Xr catclose 3 ,
+.Xr catopen 3
+.Sh STANDARDS
+The
+.Fn catgets
+function conforms to
+.St -xpg4 .
diff --git a/lib/libc/nls/catgets.c b/lib/libc/nls/catgets.c
new file mode 100644
index 0000000..037b6ff
--- /dev/null
+++ b/lib/libc/nls/catgets.c
@@ -0,0 +1,28 @@
+/* $FreeBSD$ */
+
+/*
+ * Written by J.T. Conklin, 10/05/94
+ * Public domain.
+ */
+
+#include <sys/cdefs.h>
+
+#ifdef __indr_reference
+__indr_reference(_catgets,catgets);
+#else
+
+#include <nl_types.h>
+
+extern char * _catgets __P((nl_catd, int, int, __const char *));
+
+char *
+catgets(catd, set_id, msg_id, s)
+ nl_catd catd;
+ int set_id;
+ int msg_id;
+ __const char *s;
+{
+ return _catgets(catd, set_id, msg_id, s);
+}
+
+#endif
diff --git a/lib/libc/nls/catopen.3 b/lib/libc/nls/catopen.3
new file mode 100644
index 0000000..3130616
--- /dev/null
+++ b/lib/libc/nls/catopen.3
@@ -0,0 +1,99 @@
+.\" $FreeBSD$
+.\"
+.\" Copyright (c) 1994 Winning Strategies, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Winning Strategies, Inc.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd May 29, 1994
+.Dt CATOPEN 3
+.Os
+.Sh NAME
+.Nm catopen
+.Nd open message catalog
+.Sh SYNOPSIS
+.Fd #include <nl_types.h>
+.Ft nl_catd
+.Fn catopen "const char *name" "int oflag"
+.Sh DESCRIPTION
+The
+.Fn catopen
+function opens the message catalog specified by
+.Fa name
+and returns a message catalog descriptor.
+If
+.Fa name
+contains a
+.Sq /
+then
+.Fa name
+specifies the full pathname for the message catalog, otherwise the value
+of the environment variable
+.Ev NLSPATH
+is used with
+.Fa name
+substituted for %N.
+.Pp
+If the
+.Fa oflag
+argument is set to the
+.Dv NL_CAT_LOCALE
+constant,
+.Dv LC_MESSAGES
+locale category used to open the message catalog; using
+.Dv NL_CAT_LOCALE
+conforms to the
+.St -xpg4
+standard. You can specify 0 for compatibility with
+.St -xpg3 ;
+when
+.Fa oflag
+is set to 0, the
+.Ev LANG
+environment variable
+determines the message catalog locale.
+.Sh RETURN VALUE
+Upon successful completion,
+.Fn catopen
+returns a message catalog descriptor.
+Otherwise, (nl_catd) -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+Insufficient memory is available.
+.El
+.Sh SEE ALSO
+.Xr gencat 1 ,
+.Xr catclose 3 ,
+.Xr catgets 3 ,
+.Xr setlocale 3
+.Sh STANDARDS
+The
+.Fn catopen
+function conforms to
+.St -xpg4 .
diff --git a/lib/libc/nls/catopen.c b/lib/libc/nls/catopen.c
new file mode 100644
index 0000000..c5ab394
--- /dev/null
+++ b/lib/libc/nls/catopen.c
@@ -0,0 +1,26 @@
+/* $FreeBSD$ */
+
+/*
+ * Written by J.T. Conklin, 10/05/94
+ * Public domain.
+ */
+
+#include <sys/cdefs.h>
+
+#ifdef __indr_reference
+__indr_reference(_catopen,catopen);
+#else
+
+#include <nl_types.h>
+
+extern nl_catd _catopen __P((__const char *, int));
+
+nl_catd
+catopen(name, oflag)
+ __const char *name;
+ int oflag;
+{
+ return _catopen(name, oflag);
+}
+
+#endif
diff --git a/lib/libc/nls/msgcat.c b/lib/libc/nls/msgcat.c
new file mode 100644
index 0000000..0e11ee2
--- /dev/null
+++ b/lib/libc/nls/msgcat.c
@@ -0,0 +1,451 @@
+/* $FreeBSD$ */
+
+/***********************************************************
+Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that Alfalfa's name not be used in
+advertising or publicity pertaining to distribution of the software
+without specific, written prior permission.
+
+ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+If you make any modifications, bugfixes or other changes to this software
+we'd appreciate it if you could send a copy to us so we can keep things
+up-to-date. Many thanks.
+ Kee Hinckley
+ Alfalfa Software, Inc.
+ 267 Allston St., #3
+ Cambridge, MA 02139 USA
+ nazgul@alfalfa.com
+
+******************************************************************/
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$NetBSD: msgcat.c,v 1.11 1995/02/27 13:06:51 cgd Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/* Edit History
+
+03/06/91 4 schulert remove working directory from nlspath
+01/18/91 2 hamilton #if not rescanned
+01/12/91 3 schulert conditionally use prototypes
+11/03/90 1 hamilton Alphalpha->Alfalfa & OmegaMail->Poste
+10/15/90 2 schulert > #include <unistd.h> if MIPS
+08/13/90 1 schulert move from ua to omu
+*/
+
+/*
+ * We need a better way of handling errors than printing text. I need
+ * to add an error handling routine.
+ */
+
+#include "nl_types.h"
+#include "msgcat.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifndef True
+# define True ~0
+# define False 0
+#endif
+
+/* take care of sysv diffs */
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+#ifndef FD_CLOEXEC
+#define FD_CLOEXEC 1
+#endif
+
+#define NLERR ((nl_catd) -1)
+
+static nl_catd loadCat();
+static int loadSet();
+
+nl_catd _catopen( name, type)
+__const char *name;
+int type;
+{
+ char path[MAXPATHLEN];
+ __const char *catpath = NULL;
+ char *nlspath;
+ char *lang;
+ long len;
+ char *base, *cptr, *pathP;
+ struct stat sbuf;
+
+ if (!name || !*name) {
+ errno = EINVAL;
+ return(NLERR);
+ }
+
+ if (strchr(name, '/')) {
+ catpath = name;
+ if (stat(catpath, &sbuf)) return(NLERR);
+ } else {
+ if (type == NL_CAT_LOCALE)
+ lang = setlocale(LC_MESSAGES, NULL);
+ else {
+ if ((lang = (char *) getenv("LANG")) == NULL)
+ lang = "C";
+ }
+ if ((nlspath = (char *) getenv("NLSPATH")) == NULL
+#ifndef __NETBSD_SYSCALLS
+ || issetugid()
+#endif
+ )
+ nlspath = "/usr/share/nls/%L/%N.cat:/usr/share/nls/%N/%L:/usr/local/share/nls/%L/%N.cat:/usr/local/share/nls/%N/%L";
+
+ len = strlen(nlspath);
+ base = cptr = malloc(len + 2);
+ if (!base) return(NLERR);
+ strcpy(cptr, nlspath);
+ cptr[len] = ':';
+ cptr[len+1] = '\0';
+
+ for (nlspath = cptr; *cptr; ++cptr) {
+ if (*cptr == ':') {
+ *cptr = '\0';
+ for (pathP = path; *nlspath; ++nlspath) {
+ if (*nlspath == '%') {
+ if (*(nlspath + 1) == 'L') {
+ ++nlspath;
+ strcpy(pathP, lang);
+ pathP += strlen(lang);
+ } else if (*(nlspath + 1) == 'N') {
+ ++nlspath;
+ strcpy(pathP, name);
+ pathP += strlen(name);
+ } else *(pathP++) = *nlspath;
+ } else *(pathP++) = *nlspath;
+ }
+ *pathP = '\0';
+ if (stat(path, &sbuf) == 0) {
+ catpath = path;
+ break;
+ }
+ nlspath = cptr+1;
+ }
+ }
+ free(base);
+
+ if (!catpath) {
+ errno = ENOENT;
+ return(NLERR);
+ }
+ }
+
+ return(loadCat(catpath));
+}
+
+/*
+ * We've got an odd situation here. The odds are real good that the
+ * number we are looking for is almost the same as the index. We could
+ * use the index, check the difference and do something intelligent, but
+ * I haven't quite figured out what's intelligent.
+ *
+ * Here's a start.
+ * Take an id N. If there are > N items in the list, then N cannot
+ * be more than N items from the start, since otherwise there would
+ * have to be duplicate items. So we can safely set the top to N+1
+ * (after taking into account that ids start at 1, and arrays at 0)
+ *
+ * Let's say we are at position P, and we are looking for N, but have
+ * V. If N > V, then the furthest away that N could be is
+ * P + (N-V). So we can safely set hi to P+(N-V)+1. For example:
+ * We are looking for 10, but have 8
+ * 8 ? ? ? ?
+ * >=9 >=10 >=11
+ *
+ */
+static MCSetT *MCGetSet( cat, setId)
+MCCatT *cat;
+int setId;
+{
+ MCSetT *set;
+ long lo, hi, cur, dir;
+
+ if (!cat || setId <= 0) return(NULL);
+
+ lo = 0;
+ if (setId - 1 < cat->numSets) {
+ cur = setId - 1;
+ hi = setId;
+ } else {
+ hi = cat->numSets;
+ cur = (hi - lo) / 2;
+ }
+
+ while (True) {
+ set = cat->sets + cur;
+ if (set->setId == setId) break;
+ if (set->setId < setId) {
+ lo = cur+1;
+ if (hi > cur + (setId - set->setId) + 1) hi = cur+(setId-set->setId)+1;
+ dir = 1;
+ } else {
+ hi = cur;
+ dir = -1;
+ }
+ if (lo >= hi) return(NULL);
+ if (hi - lo == 1) cur += dir;
+ else cur += ((hi - lo) / 2) * dir;
+ }
+ if (set->invalid)
+ (void) loadSet(cat, set);
+ return(set);
+}
+
+
+static MCMsgT *MCGetMsg( set, msgId)
+MCSetT *set;
+int msgId;
+{
+ MCMsgT *msg;
+ long lo, hi, cur, dir;
+
+ if (!set || set->invalid || msgId <= 0) return(NULL);
+
+ lo = 0;
+ if (msgId - 1 < set->numMsgs) {
+ cur = msgId - 1;
+ hi = msgId;
+ } else {
+ hi = set->numMsgs;
+ cur = (hi - lo) / 2;
+ }
+
+ while (True) {
+ msg = set->u.msgs + cur;
+ if (msg->msgId == msgId) break;
+ if (msg->msgId < msgId) {
+ lo = cur+1;
+ if (hi > cur + (msgId - msg->msgId) + 1) hi = cur+(msgId-msg->msgId)+1;
+ dir = 1;
+ } else {
+ hi = cur;
+ dir = -1;
+ }
+ if (lo >= hi) return(NULL);
+ if (hi - lo == 1) cur += dir;
+ else cur += ((hi - lo) / 2) * dir;
+ }
+ return(msg);
+}
+
+char *_catgets( catd, setId, msgId, dflt)
+nl_catd catd;
+int setId;
+int msgId;
+__const char *dflt;
+{
+ MCMsgT *msg;
+ MCCatT *cat = (MCCatT *) catd;
+ __const char *cptr;
+
+ if (catd == NULL || catd == NLERR)
+ return((char *)dflt);
+ msg = MCGetMsg(MCGetSet(cat, setId), msgId);
+ if (msg) cptr = msg->msg.str;
+ else cptr = dflt;
+ return((char *)cptr);
+}
+
+
+int _catclose( catd)
+nl_catd catd;
+{
+ MCCatT *cat = (MCCatT *) catd;
+ MCSetT *set;
+ int i;
+
+ if (catd == NULL || catd == NLERR) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (cat->loadType != MCLoadAll) close(cat->fd);
+ for (i = 0; i < cat->numSets; ++i) {
+ set = cat->sets + i;
+ if (!set->invalid) {
+ free(set->data.str);
+ free(set->u.msgs);
+ }
+ }
+ free(cat->sets);
+ free(cat);
+
+ return 0;
+}
+
+/*
+ * Internal routines
+ */
+
+/* Note that only malloc failures are allowed to return an error */
+#define ERRNAME "Message Catalog System"
+#define CORRUPT() {fprintf(stderr, "%s: corrupt file.\n", ERRNAME); free(cat); errno = EINVAL; return(NLERR);}
+#define NOSPACE() {fprintf(stderr, "%s: no more memory.\n", ERRNAME); free(cat); return(NLERR);}
+
+static nl_catd loadCat(catpath)
+__const char *catpath;
+{
+ MCHeaderT header;
+ MCCatT *cat;
+ MCSetT *set;
+ long i, j;
+ off_t nextSet;
+
+ cat = (MCCatT *) malloc(sizeof(MCCatT));
+ if (!cat) return(NLERR);
+ cat->loadType = MCLoadBySet;
+
+ if ((cat->fd = open(catpath, O_RDONLY)) < 0) {
+ free(cat);
+ return(NLERR);
+ }
+
+ (void)fcntl(cat->fd, F_SETFD, FD_CLOEXEC);
+
+ if (read(cat->fd, &header, sizeof(header)) != sizeof(header)) CORRUPT();
+
+ if (strncmp(header.magic, MCMagic, MCMagicLen) != 0) CORRUPT();
+
+ if (header.majorVer != MCMajorVer) {
+ free(cat);
+ fprintf(stderr, "%s: %s is version %ld, we need %ld.\n", ERRNAME,
+ catpath, header.majorVer, MCMajorVer);
+ errno = EINVAL;
+ return(NLERR);
+ }
+
+ if (header.numSets <= 0) {
+ free(cat);
+ fprintf(stderr, "%s: %s has %ld sets!\n", ERRNAME, catpath,
+ header.numSets);
+ errno = EINVAL;
+ return(NLERR);
+ }
+
+ cat->numSets = header.numSets;
+ cat->sets = (MCSetT *) malloc(sizeof(MCSetT) * header.numSets);
+ if (!cat->sets) NOSPACE();
+
+ nextSet = header.firstSet;
+ for (i = 0; i < cat->numSets; ++i) {
+ if (lseek(cat->fd, nextSet, 0) == -1) {
+ for (j = 0; j < i; j++) {
+ set = cat->sets + j;
+ if (!set->invalid) {
+ free(set->data.str);
+ free(set->u.msgs);
+ }
+ }
+ free(cat->sets);
+ CORRUPT();
+ }
+
+ /* read in the set header */
+ set = cat->sets + i;
+ if (read(cat->fd, set, sizeof(*set)) != sizeof(*set)) {
+ for (j = 0; j < i; j++) {
+ set = cat->sets + j;
+ if (!set->invalid) {
+ free(set->data.str);
+ free(set->u.msgs);
+ }
+ }
+ free(cat->sets);
+ CORRUPT();
+ }
+
+ /* if it's invalid, skip over it (and backup 'i') */
+
+ if (set->invalid) {
+ --i;
+ nextSet = set->nextSet;
+ continue;
+ }
+
+ if (cat->loadType == MCLoadAll) {
+ int res;
+
+ if ((res = loadSet(cat, set)) <= 0) {
+ for (j = 0; j < i; j++) {
+ set = cat->sets + j;
+ if (!set->invalid) {
+ free(set->data.str);
+ free(set->u.msgs);
+ }
+ }
+ free(cat->sets);
+ if (res < 0) NOSPACE();
+ CORRUPT();
+ }
+ } else set->invalid = True;
+ nextSet = set->nextSet;
+ }
+ if (cat->loadType == MCLoadAll) {
+ close(cat->fd);
+ cat->fd = -1;
+ }
+ return((nl_catd) cat);
+}
+
+static int loadSet(cat, set)
+MCCatT *cat;
+MCSetT *set;
+{
+ MCMsgT *msg;
+ int i;
+
+ /* Get the data */
+ if (lseek(cat->fd, set->data.off, 0) == -1) return(0);
+ if ((set->data.str = malloc(set->dataLen)) == NULL) return(-1);
+ if (read(cat->fd, set->data.str, set->dataLen) != set->dataLen) {
+ free(set->data.str); return(0);
+ }
+
+ /* Get the messages */
+ if (lseek(cat->fd, set->u.firstMsg, 0) == -1) {
+ free(set->data.str); return(0);
+ }
+ if ((set->u.msgs = (MCMsgT *) malloc(sizeof(MCMsgT) * set->numMsgs)) == NULL) {
+ free(set->data.str); return(-1);
+ }
+
+ for (i = 0; i < set->numMsgs; ++i) {
+ msg = set->u.msgs + i;
+ if (read(cat->fd, msg, sizeof(*msg)) != sizeof(*msg)) {
+ free(set->u.msgs); free(set->data.str); return(0);
+ }
+ if (msg->invalid) {
+ --i;
+ continue;
+ }
+ msg->msg.str = (char *) (set->data.str + msg->msg.off);
+ }
+ set->invalid = False;
+ return(1);
+}
diff --git a/lib/libc/nls/msgcat.h b/lib/libc/nls/msgcat.h
new file mode 100644
index 0000000..0a4c164
--- /dev/null
+++ b/lib/libc/nls/msgcat.h
@@ -0,0 +1,170 @@
+/* $FreeBSD$ */
+
+/* -*-c++-*- */
+
+#ifndef __msgcath
+
+
+/***********************************************************
+Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that Alfalfa's name not be used in
+advertising or publicity pertaining to distribution of the software
+without specific, written prior permission.
+
+ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+If you make any modifications, bugfixes or other changes to this software
+we'd appreciate it if you could send a copy to us so we can keep things
+up-to-date. Many thanks.
+ Kee Hinckley
+ Alfalfa Software, Inc.
+ 267 Allston St., #3
+ Cambridge, MA 02139 USA
+ nazgul@alfalfa.com
+
+******************************************************************/
+
+
+#include <sys/types.h>
+
+/*
+ * On disk data structures
+ */
+
+/* Edit History
+
+02/25/91 2 nazgul Byte order flags, upped the version number
+11/03/90 1 hamilton Alphalpha->Alfalfa & OmegaMail->Poste
+08/13/90 1 schulert move from ua to omu
+*/
+
+/* For or'd constants */
+#define MCMakeId(s,m) (unsigned long) ( ((unsigned short)s << (sizeof(short)*8)) \
+ | (unsigned short)m )
+#define MCSetId(id) (unsigned int) ( id >> (sizeof(short) * 8) )
+#define MCMsgId(id) (unsigned int) ( (id << (sizeof(short) * 8)) \
+ >> (sizeof(short) * 8) )
+#undef S
+#undef UI
+#undef UL
+
+#define MCMagicLen 8
+#define MCMagic "*nazgul*"
+#define MCLastMsg 0
+#define MCLastSet 0
+
+#define MCMajorVer 1L
+#define MCMinorVer 0
+
+/*
+ * Critical note here. Sets and Messages *MUST* be stored in ascending
+ * order. There are stored that way (by specification) in the original
+ * data file, however in the process of merging in new stuff you might
+ * mix that up. Don't! The catget stuff does a binary search and will
+ * totally lose it if these aren't in order (not contiguous mind you, just
+ * in order. If this turns out to be a major problem this could be enhanced
+ * by adding a 'sorted' flag to the db, and sorting msgs and sets at load
+ * time if things aren't sorted, but I'd like not to have to do that.
+ */
+
+/*
+ * I have tried here to define data structures which can be used
+ * while the catalog is on disk, and at runtime.
+ * This is rather dangerous of course, but I think it can be done without
+ * overly increasing the memory usage, and it makes loading and storing
+ * somewhat simpler and less prone to accidents. I have also tried to
+ * define on disk data structures which can be updated in place, so that
+ * with a very large catalog (e.g. all system errors) you don't have to
+ * load everything in memory in order to add or update one set. With
+ * this in mind there are "invalid" flags which allow items to be
+ * invalidated and thus not loaded at runtime. Note however that although
+ * I pay attention to these when I load the DB, I do not currently use
+ * them in gencat (it just reads everything into memory), so there is
+ * no guarantee that this will all work.
+ */
+
+/* These should be publicly available */
+
+#define MCLoadBySet 0 /* Load entire sets as they are used */
+#define MCLoadAll 1 /* Load entire DB on catopen */
+
+/*
+ * MCOffsetT - Union to handle both disk and runtime pointers
+ */
+typedef union {
+ off_t off;
+ char *str;
+ void *ptr;
+ struct _MCMsgT *msg;
+ struct _MCSetT *set;
+} MCOffsetT;
+
+/*
+ * MCMsgT - Message structure (disk and runtime)
+ */
+typedef struct _MCMsgT {
+ long msgId; /* Id of this message */
+ MCOffsetT msg; /* Relative offset on disk or pointer in memory */
+ long invalid; /* Valid on disk, loaded in memory */
+} MCMsgT;
+
+/*
+ * MCSetT - Set structure (disk and runtime)
+ */
+typedef struct _MCSetT {
+ long setId; /* Id of this set */
+ off_t nextSet; /* Offset of next set on disk */
+ union {
+ off_t firstMsg; /* Offset to first Msg (while on disk) */
+ MCMsgT *msgs; /* Pointer to array of msgs (in mem, loaded) */
+ } u;
+ MCOffsetT data; /* Offset to data, or pointer to data */
+ long dataLen; /* Length of data area on disk */
+ long numMsgs; /* Number of messages */
+ long invalid; /* Valid on disk, loaded in memory */
+} MCSetT;
+
+/*
+ * MCCatT - Runtime catalog pointer
+ */
+typedef struct {
+ long loadType; /* How to load the messages (see MSLoadType) */
+ int fd; /* File descriptor of catalog (if load-on-demand) */
+ long numSets; /* Number of sets */
+ MCSetT *sets; /* Pointer to the sets */
+ off_t firstSet; /* Offset of first set on disk */
+} MCCatT;
+
+/*
+ * MCHeaderT - Disk file header
+ */
+typedef struct {
+ char magic[MCMagicLen]; /* Magic cookie "*nazgul*" */
+ long majorVer; /* ++ on incompatible changes */
+ long minorVer; /* ++ on compatible changes */
+ long flags; /* Informational flags */
+ long numSets; /* Number of valid Sets */
+ off_t firstSet; /* Offset of first set on disk */
+} MCHeaderT;
+
+/* Some flags */
+#define MC68KByteOrder 0x01
+#define MCn86ByteOrder 0x02
+
+
+
+
+#endif
diff --git a/lib/libc/quad/Makefile.inc b/lib/libc/quad/Makefile.inc
new file mode 100644
index 0000000..9934328
--- /dev/null
+++ b/lib/libc/quad/Makefile.inc
@@ -0,0 +1,19 @@
+# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+# Quad support, if needed
+.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/quad ${.CURDIR}/../libc/quad
+
+.if ${MACHINE_ARCH} == "i386"
+
+SRCS+= cmpdi2.c divdi3.c moddi3.c qdivrem.c ucmpdi2.c udivdi3.c umoddi3.c
+
+.else
+
+SRCS+= adddi3.c anddi3.c ashldi3.c ashrdi3.c cmpdi2.c divdi3.c fixdfdi.c \
+ fixsfdi.c fixunsdfdi.c fixunssfdi.c floatdidf.c floatdisf.c \
+ floatunsdidf.c iordi3.c lshldi3.c lshrdi3.c moddi3.c muldi3.c \
+ negdi2.c notdi2.c qdivrem.c subdi3.c ucmpdi2.c udivdi3.c umoddi3.c \
+ xordi3.c
+
+.endif
diff --git a/lib/libc/quad/TESTS/Makefile b/lib/libc/quad/TESTS/Makefile
new file mode 100644
index 0000000..5834f21e
--- /dev/null
+++ b/lib/libc/quad/TESTS/Makefile
@@ -0,0 +1,11 @@
+# @(#)Makefile 8.1 (Berkeley) 6/4/93
+
+all: mul divrem
+
+MUL= mul.c ../muldi3.c
+mul: ${MUL}
+ gcc -g -DSPARC_XXX ${MUL} -o ${.TARGET}
+
+DIVREM= divrem.c ../qdivrem.c
+divrem: ${DIVREM}
+ gcc -g -DSPARC_XXX ${DIVREM} -o ${.TARGET}
diff --git a/lib/libc/quad/TESTS/divrem.c b/lib/libc/quad/TESTS/divrem.c
new file mode 100644
index 0000000..73be605
--- /dev/null
+++ b/lib/libc/quad/TESTS/divrem.c
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1992, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)divrem.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <stdio.h>
+
+main()
+{
+ union { long long q; unsigned long v[2]; } a, b, q, r;
+ char buf[300];
+ extern long long __qdivrem(unsigned long long, unsigned long long,
+ unsigned long long *);
+
+ for (;;) {
+ printf("> ");
+ if (fgets(buf, sizeof buf, stdin) == NULL)
+ break;
+ if (sscanf(buf, "%lu:%lu %lu:%lu",
+ &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4 &&
+ sscanf(buf, "0x%lx:%lx 0x%lx:%lx",
+ &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4) {
+ printf("eh?\n");
+ continue;
+ }
+ q.q = __qdivrem(a.q, b.q, &r.q);
+ printf("%lx:%lx /%% %lx:%lx => q=%lx:%lx r=%lx:%lx\n",
+ a.v[0], a.v[1], b.v[0], b.v[1],
+ q.v[0], q.v[1], r.v[0], r.v[1]);
+ printf(" = %lX%08lX / %lX%08lX => %lX%08lX\n\
+ = %lX%08lX %% %lX%08lX => %lX%08lX\n",
+ a.v[0], a.v[1], b.v[0], b.v[1], q.v[0], q.v[1],
+ a.v[0], a.v[1], b.v[0], b.v[1], r.v[0], r.v[1]);
+ }
+ exit(0);
+}
diff --git a/lib/libc/quad/TESTS/mul.c b/lib/libc/quad/TESTS/mul.c
new file mode 100644
index 0000000..1ab00f1
--- /dev/null
+++ b/lib/libc/quad/TESTS/mul.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1992, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)mul.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <stdio.h>
+
+main()
+{
+ union { long long q; unsigned long v[2]; } a, b, m;
+ char buf[300];
+ extern long long __muldi3(long long, long long);
+
+ for (;;) {
+ printf("> ");
+ if (fgets(buf, sizeof buf, stdin) == NULL)
+ break;
+ if (sscanf(buf, "%lu:%lu %lu:%lu",
+ &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4 &&
+ sscanf(buf, "0x%lx:%lx 0x%lx:%lx",
+ &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4) {
+ printf("eh?\n");
+ continue;
+ }
+ m.q = __muldi3(a.q, b.q);
+ printf("%lx:%lx * %lx:%lx => %lx:%lx\n",
+ a.v[0], a.v[1], b.v[0], b.v[1], m.v[0], m.v[1]);
+ printf(" = %lX%08lX * %lX%08lX => %lX%08lX\n",
+ a.v[0], a.v[1], b.v[0], b.v[1], m.v[0], m.v[1]);
+ }
+ exit(0);
+}
diff --git a/lib/libc/quad/adddi3.c b/lib/libc/quad/adddi3.c
new file mode 100644
index 0000000..d10da47
--- /dev/null
+++ b/lib/libc/quad/adddi3.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)adddi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Add two quads. This is trivial since a one-bit carry from a single
+ * u_long addition x+y occurs if and only if the sum x+y is less than
+ * either x or y (the choice to compare with x or y is arbitrary).
+ */
+quad_t
+__adddi3(a, b)
+ quad_t a, b;
+{
+ union uu aa, bb, sum;
+
+ aa.q = a;
+ bb.q = b;
+ sum.ul[L] = aa.ul[L] + bb.ul[L];
+ sum.ul[H] = aa.ul[H] + bb.ul[H] + (sum.ul[L] < bb.ul[L]);
+ return (sum.q);
+}
diff --git a/lib/libc/quad/anddi3.c b/lib/libc/quad/anddi3.c
new file mode 100644
index 0000000..5ae45ac
--- /dev/null
+++ b/lib/libc/quad/anddi3.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)anddi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return a & b, in quad.
+ */
+quad_t
+__anddi3(a, b)
+ quad_t a, b;
+{
+ union uu aa, bb;
+
+ aa.q = a;
+ bb.q = b;
+ aa.ul[0] &= bb.ul[0];
+ aa.ul[1] &= bb.ul[1];
+ return (aa.q);
+}
diff --git a/lib/libc/quad/ashldi3.c b/lib/libc/quad/ashldi3.c
new file mode 100644
index 0000000..72501ad
--- /dev/null
+++ b/lib/libc/quad/ashldi3.c
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ashldi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Shift a (signed) quad value left (arithmetic shift left).
+ * This is the same as logical shift left!
+ */
+quad_t
+__ashldi3(a, shift)
+ quad_t a;
+ qshift_t shift;
+{
+ union uu aa;
+
+ aa.q = a;
+ if (shift >= LONG_BITS) {
+ aa.ul[H] = shift >= QUAD_BITS ? 0 :
+ aa.ul[L] << (shift - LONG_BITS);
+ aa.ul[L] = 0;
+ } else if (shift > 0) {
+ aa.ul[H] = (aa.ul[H] << shift) |
+ (aa.ul[L] >> (LONG_BITS - shift));
+ aa.ul[L] <<= shift;
+ }
+ return (aa.q);
+}
diff --git a/lib/libc/quad/ashrdi3.c b/lib/libc/quad/ashrdi3.c
new file mode 100644
index 0000000..9ffa5ed
--- /dev/null
+++ b/lib/libc/quad/ashrdi3.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ashrdi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Shift a (signed) quad value right (arithmetic shift right).
+ */
+quad_t
+__ashrdi3(a, shift)
+ quad_t a;
+ qshift_t shift;
+{
+ union uu aa;
+
+ aa.q = a;
+ if (shift >= LONG_BITS) {
+ long s;
+
+ /*
+ * Smear bits rightward using the machine's right-shift
+ * method, whether that is sign extension or zero fill,
+ * to get the `sign word' s. Note that shifting by
+ * LONG_BITS is undefined, so we shift (LONG_BITS-1),
+ * then 1 more, to get our answer.
+ */
+ s = (aa.sl[H] >> (LONG_BITS - 1)) >> 1;
+ aa.ul[L] = shift >= QUAD_BITS ? s :
+ aa.sl[H] >> (shift - LONG_BITS);
+ aa.ul[H] = s;
+ } else if (shift > 0) {
+ aa.ul[L] = (aa.ul[L] >> shift) |
+ (aa.ul[H] << (LONG_BITS - shift));
+ aa.sl[H] >>= shift;
+ }
+ return (aa.q);
+}
diff --git a/lib/libc/quad/cmpdi2.c b/lib/libc/quad/cmpdi2.c
new file mode 100644
index 0000000..f6e4bdd
--- /dev/null
+++ b/lib/libc/quad/cmpdi2.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)cmpdi2.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return 0, 1, or 2 as a <, =, > b respectively.
+ * Both a and b are considered signed---which means only the high word is
+ * signed.
+ */
+int
+__cmpdi2(a, b)
+ quad_t a, b;
+{
+ union uu aa, bb;
+
+ aa.q = a;
+ bb.q = b;
+ return (aa.sl[H] < bb.sl[H] ? 0 : aa.sl[H] > bb.sl[H] ? 2 :
+ aa.ul[L] < bb.ul[L] ? 0 : aa.ul[L] > bb.ul[L] ? 2 : 1);
+}
diff --git a/lib/libc/quad/divdi3.c b/lib/libc/quad/divdi3.c
new file mode 100644
index 0000000..da7b2fc
--- /dev/null
+++ b/lib/libc/quad/divdi3.c
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)divdi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Divide two signed quads.
+ * ??? if -1/2 should produce -1 on this machine, this code is wrong
+ */
+quad_t
+__divdi3(a, b)
+ quad_t a, b;
+{
+ u_quad_t ua, ub, uq;
+ int neg;
+
+ if (a < 0)
+ ua = -(u_quad_t)a, neg = 1;
+ else
+ ua = a, neg = 0;
+ if (b < 0)
+ ub = -(u_quad_t)b, neg ^= 1;
+ else
+ ub = b;
+ uq = __qdivrem(ua, ub, (u_quad_t *)0);
+ return (neg ? -uq : uq);
+}
diff --git a/lib/libc/quad/fixdfdi.c b/lib/libc/quad/fixdfdi.c
new file mode 100644
index 0000000..6d57550
--- /dev/null
+++ b/lib/libc/quad/fixdfdi.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fixdfdi.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Convert double to (signed) quad.
+ * We clamp anything that is out of range.
+ */
+quad_t
+__fixdfdi(x)
+ double x;
+{
+ if (x < 0)
+ if (x <= QUAD_MIN)
+ return (QUAD_MIN);
+ else
+ return ((quad_t)-(u_quad_t)-x);
+ else
+ if (x >= QUAD_MAX)
+ return (QUAD_MAX);
+ else
+ return ((quad_t)(u_quad_t)x);
+}
diff --git a/lib/libc/quad/fixsfdi.c b/lib/libc/quad/fixsfdi.c
new file mode 100644
index 0000000..448109f
--- /dev/null
+++ b/lib/libc/quad/fixsfdi.c
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 1992 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fixsfdi.c 5.1 (Berkeley) 7/7/92";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Convert float to (signed) quad.
+ * We clamp anything that is out of range.
+ *
+ * N.B.: must use new ANSI syntax (sorry).
+ */
+long long
+__fixsfdi(float x)
+{
+ if (x < 0)
+ if (x <= QUAD_MIN)
+ return (QUAD_MIN);
+ else
+ return ((quad_t)-(u_quad_t)-x);
+ else
+ if (x >= QUAD_MAX)
+ return (QUAD_MAX);
+ else
+ return ((quad_t)(u_quad_t)x);
+}
diff --git a/lib/libc/quad/fixunsdfdi.c b/lib/libc/quad/fixunsdfdi.c
new file mode 100644
index 0000000..601790f
--- /dev/null
+++ b/lib/libc/quad/fixunsdfdi.c
@@ -0,0 +1,96 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fixunsdfdi.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+#define ONE_FOURTH (1 << (LONG_BITS - 2))
+#define ONE_HALF (ONE_FOURTH * 2.0)
+#define ONE (ONE_FOURTH * 4.0)
+
+/*
+ * Convert double to (unsigned) quad.
+ * Not sure what to do with negative numbers---for now, anything out
+ * of range becomes UQUAD_MAX.
+ */
+u_quad_t
+__fixunsdfdi(x)
+ double x;
+{
+ double toppart;
+ union uu t;
+
+ if (x < 0)
+ return (UQUAD_MAX); /* ??? should be 0? ERANGE??? */
+#ifdef notdef /* this falls afoul of a GCC bug */
+ if (x >= UQUAD_MAX)
+ return (UQUAD_MAX);
+#else /* so we wire in 2^64-1 instead */
+ if (x >= 18446744073709551615.0)
+ return (UQUAD_MAX);
+#endif
+ /*
+ * Get the upper part of the result. Note that the divide
+ * may round up; we want to avoid this if possible, so we
+ * subtract `1/2' first.
+ */
+ toppart = (x - ONE_HALF) / ONE;
+ /*
+ * Now build a u_quad_t out of the top part. The difference
+ * between x and this is the bottom part (this may introduce
+ * a few fuzzy bits, but what the heck). With any luck this
+ * difference will be nonnegative: x should wind up in the
+ * range [0..ULONG_MAX]. For paranoia, we assume [LONG_MIN..
+ * 2*ULONG_MAX] instead.
+ */
+ t.ul[H] = (unsigned long)toppart;
+ t.ul[L] = 0;
+ x -= (double)t.uq;
+ if (x < 0) {
+ t.ul[H]--;
+ x += ULONG_MAX;
+ }
+ if (x > ULONG_MAX) {
+ t.ul[H]++;
+ x -= ULONG_MAX;
+ }
+ t.ul[L] = (u_long)x;
+ return (t.uq);
+}
diff --git a/lib/libc/quad/fixunssfdi.c b/lib/libc/quad/fixunssfdi.c
new file mode 100644
index 0000000..9405ce7
--- /dev/null
+++ b/lib/libc/quad/fixunssfdi.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fixunssfdi.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+#define ONE_FOURTH (1 << (LONG_BITS - 2))
+#define ONE_HALF (ONE_FOURTH * 2.0)
+#define ONE (ONE_FOURTH * 4.0)
+
+/*
+ * Convert float to (unsigned) quad. We do most of our work in double,
+ * out of sheer paranoia.
+ *
+ * Not sure what to do with negative numbers---for now, anything out
+ * of range becomes UQUAD_MAX.
+ *
+ * N.B.: must use new ANSI syntax (sorry).
+ */
+u_quad_t
+__fixunssfdi(float f)
+{
+ double x, toppart;
+ union uu t;
+
+ if (f < 0)
+ return (UQUAD_MAX); /* ??? should be 0? ERANGE??? */
+#ifdef notdef /* this falls afoul of a GCC bug */
+ if (f >= UQUAD_MAX)
+ return (UQUAD_MAX);
+#else /* so we wire in 2^64-1 instead */
+ if (f >= 18446744073709551615.0)
+ return (UQUAD_MAX);
+#endif
+ x = f;
+ /*
+ * Get the upper part of the result. Note that the divide
+ * may round up; we want to avoid this if possible, so we
+ * subtract `1/2' first.
+ */
+ toppart = (x - ONE_HALF) / ONE;
+ /*
+ * Now build a u_quad_t out of the top part. The difference
+ * between x and this is the bottom part (this may introduce
+ * a few fuzzy bits, but what the heck). With any luck this
+ * difference will be nonnegative: x should wind up in the
+ * range [0..ULONG_MAX]. For paranoia, we assume [LONG_MIN..
+ * 2*ULONG_MAX] instead.
+ */
+ t.ul[H] = (unsigned long)toppart;
+ t.ul[L] = 0;
+ x -= (double)t.uq;
+ if (x < 0) {
+ t.ul[H]--;
+ x += ULONG_MAX;
+ }
+ if (x > ULONG_MAX) {
+ t.ul[H]++;
+ x -= ULONG_MAX;
+ }
+ t.ul[L] = (u_long)x;
+ return (t.uq);
+}
diff --git a/lib/libc/quad/floatdidf.c b/lib/libc/quad/floatdidf.c
new file mode 100644
index 0000000..7b90f6e
--- /dev/null
+++ b/lib/libc/quad/floatdidf.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)floatdidf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Convert (signed) quad to double.
+ */
+double
+__floatdidf(x)
+ quad_t x;
+{
+ double d;
+ union uu u;
+ int neg;
+
+ /*
+ * Get an unsigned number first, by negating if necessary.
+ */
+ if (x < 0)
+ u.q = -x, neg = 1;
+ else
+ u.q = x, neg = 0;
+
+ /*
+ * Now u.ul[H] has the factor of 2^32 (or whatever) and u.ul[L]
+ * has the units. Ideally we could just set d, add LONG_BITS to
+ * its exponent, and then add the units, but this is portable
+ * code and does not know how to get at an exponent. Machine-
+ * specific code may be able to do this more efficiently.
+ */
+ d = (double)u.ul[H] * ((1 << (LONG_BITS - 2)) * 4.0);
+ d += u.ul[L];
+
+ return (neg ? -d : d);
+}
diff --git a/lib/libc/quad/floatdisf.c b/lib/libc/quad/floatdisf.c
new file mode 100644
index 0000000..7772218
--- /dev/null
+++ b/lib/libc/quad/floatdisf.c
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)floatdisf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Convert (signed) quad to float.
+ */
+float
+__floatdisf(x)
+ quad_t x;
+{
+ float f;
+ union uu u;
+ int neg;
+
+ /*
+ * Get an unsigned number first, by negating if necessary.
+ */
+ if (x < 0)
+ u.q = -x, neg = 1;
+ else
+ u.q = x, neg = 0;
+
+ /*
+ * Now u.ul[H] has the factor of 2^32 (or whatever) and u.ul[L]
+ * has the units. Ideally we could just set f, add LONG_BITS to
+ * its exponent, and then add the units, but this is portable
+ * code and does not know how to get at an exponent. Machine-
+ * specific code may be able to do this more efficiently.
+ *
+ * Using double here may be excessive paranoia.
+ */
+ f = (double)u.ul[H] * ((1 << (LONG_BITS - 2)) * 4.0);
+ f += u.ul[L];
+
+ return (neg ? -f : f);
+}
diff --git a/lib/libc/quad/floatunsdidf.c b/lib/libc/quad/floatunsdidf.c
new file mode 100644
index 0000000..2fb6401
--- /dev/null
+++ b/lib/libc/quad/floatunsdidf.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)floatunsdidf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Convert (unsigned) quad to double.
+ * This is exactly like floatdidf.c except that negatives never occur.
+ */
+double
+__floatunsdidf(x)
+ u_quad_t x;
+{
+ double d;
+ union uu u;
+
+ u.uq = x;
+ d = (double)u.ul[H] * ((1 << (LONG_BITS - 2)) * 4.0);
+ d += u.ul[L];
+ return (d);
+}
diff --git a/lib/libc/quad/iordi3.c b/lib/libc/quad/iordi3.c
new file mode 100644
index 0000000..e225005
--- /dev/null
+++ b/lib/libc/quad/iordi3.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)iordi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return a | b, in quad.
+ */
+quad_t
+__iordi3(a, b)
+ quad_t a, b;
+{
+ union uu aa, bb;
+
+ aa.q = a;
+ bb.q = b;
+ aa.ul[0] |= bb.ul[0];
+ aa.ul[1] |= bb.ul[1];
+ return (aa.q);
+}
diff --git a/lib/libc/quad/lshldi3.c b/lib/libc/quad/lshldi3.c
new file mode 100644
index 0000000..0af6051
--- /dev/null
+++ b/lib/libc/quad/lshldi3.c
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)lshldi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Shift an (unsigned) quad value left (logical shift left).
+ * This is the same as arithmetic shift left!
+ */
+quad_t
+__lshldi3(a, shift)
+ quad_t a;
+ qshift_t shift;
+{
+ union uu aa;
+
+ aa.q = a;
+ if (shift >= LONG_BITS) {
+ aa.ul[H] = shift >= QUAD_BITS ? 0 :
+ aa.ul[L] << (shift - LONG_BITS);
+ aa.ul[L] = 0;
+ } else if (shift > 0) {
+ aa.ul[H] = (aa.ul[H] << shift) |
+ (aa.ul[L] >> (LONG_BITS - shift));
+ aa.ul[L] <<= shift;
+ }
+ return (aa.q);
+}
diff --git a/lib/libc/quad/lshrdi3.c b/lib/libc/quad/lshrdi3.c
new file mode 100644
index 0000000..add2eda
--- /dev/null
+++ b/lib/libc/quad/lshrdi3.c
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)lshrdi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Shift an (unsigned) quad value right (logical shift right).
+ */
+quad_t
+__lshrdi3(a, shift)
+ quad_t a;
+ qshift_t shift;
+{
+ union uu aa;
+
+ aa.q = a;
+ if (shift >= LONG_BITS) {
+ aa.ul[L] = shift >= QUAD_BITS ? 0 :
+ aa.ul[H] >> (shift - LONG_BITS);
+ aa.ul[H] = 0;
+ } else if (shift > 0) {
+ aa.ul[L] = (aa.ul[L] >> shift) |
+ (aa.ul[H] << (LONG_BITS - shift));
+ aa.ul[H] >>= shift;
+ }
+ return (aa.q);
+}
diff --git a/lib/libc/quad/moddi3.c b/lib/libc/quad/moddi3.c
new file mode 100644
index 0000000..fa76ea3
--- /dev/null
+++ b/lib/libc/quad/moddi3.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)moddi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return remainder after dividing two signed quads.
+ *
+ * XXX
+ * If -1/2 should produce -1 on this machine, this code is wrong.
+ */
+quad_t
+__moddi3(a, b)
+ quad_t a, b;
+{
+ u_quad_t ua, ub, ur;
+ int neg;
+
+ if (a < 0)
+ ua = -(u_quad_t)a, neg = 1;
+ else
+ ua = a, neg = 0;
+ if (b < 0)
+ ub = -(u_quad_t)b;
+ else
+ ub = b;
+ (void)__qdivrem(ua, ub, &ur);
+ return (neg ? -ur : ur);
+}
diff --git a/lib/libc/quad/muldi3.c b/lib/libc/quad/muldi3.c
new file mode 100644
index 0000000..5e2331f
--- /dev/null
+++ b/lib/libc/quad/muldi3.c
@@ -0,0 +1,246 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)muldi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Multiply two quads.
+ *
+ * Our algorithm is based on the following. Split incoming quad values
+ * u and v (where u,v >= 0) into
+ *
+ * u = 2^n u1 * u0 (n = number of bits in `u_long', usu. 32)
+ *
+ * and
+ *
+ * v = 2^n v1 * v0
+ *
+ * Then
+ *
+ * uv = 2^2n u1 v1 + 2^n u1 v0 + 2^n v1 u0 + u0 v0
+ * = 2^2n u1 v1 + 2^n (u1 v0 + v1 u0) + u0 v0
+ *
+ * Now add 2^n u1 v1 to the first term and subtract it from the middle,
+ * and add 2^n u0 v0 to the last term and subtract it from the middle.
+ * This gives:
+ *
+ * uv = (2^2n + 2^n) (u1 v1) +
+ * (2^n) (u1 v0 - u1 v1 + u0 v1 - u0 v0) +
+ * (2^n + 1) (u0 v0)
+ *
+ * Factoring the middle a bit gives us:
+ *
+ * uv = (2^2n + 2^n) (u1 v1) + [u1v1 = high]
+ * (2^n) (u1 - u0) (v0 - v1) + [(u1-u0)... = mid]
+ * (2^n + 1) (u0 v0) [u0v0 = low]
+ *
+ * The terms (u1 v1), (u1 - u0) (v0 - v1), and (u0 v0) can all be done
+ * in just half the precision of the original. (Note that either or both
+ * of (u1 - u0) or (v0 - v1) may be negative.)
+ *
+ * This algorithm is from Knuth vol. 2 (2nd ed), section 4.3.3, p. 278.
+ *
+ * Since C does not give us a `long * long = quad' operator, we split
+ * our input quads into two longs, then split the two longs into two
+ * shorts. We can then calculate `short * short = long' in native
+ * arithmetic.
+ *
+ * Our product should, strictly speaking, be a `long quad', with 128
+ * bits, but we are going to discard the upper 64. In other words,
+ * we are not interested in uv, but rather in (uv mod 2^2n). This
+ * makes some of the terms above vanish, and we get:
+ *
+ * (2^n)(high) + (2^n)(mid) + (2^n + 1)(low)
+ *
+ * or
+ *
+ * (2^n)(high + mid + low) + low
+ *
+ * Furthermore, `high' and `mid' can be computed mod 2^n, as any factor
+ * of 2^n in either one will also vanish. Only `low' need be computed
+ * mod 2^2n, and only because of the final term above.
+ */
+static quad_t __lmulq(u_long, u_long);
+
+quad_t
+__muldi3(a, b)
+ quad_t a, b;
+{
+ union uu u, v, low, prod;
+ register u_long high, mid, udiff, vdiff;
+ register int negall, negmid;
+#define u1 u.ul[H]
+#define u0 u.ul[L]
+#define v1 v.ul[H]
+#define v0 v.ul[L]
+
+ /*
+ * Get u and v such that u, v >= 0. When this is finished,
+ * u1, u0, v1, and v0 will be directly accessible through the
+ * longword fields.
+ */
+ if (a >= 0)
+ u.q = a, negall = 0;
+ else
+ u.q = -a, negall = 1;
+ if (b >= 0)
+ v.q = b;
+ else
+ v.q = -b, negall ^= 1;
+
+ if (u1 == 0 && v1 == 0) {
+ /*
+ * An (I hope) important optimization occurs when u1 and v1
+ * are both 0. This should be common since most numbers
+ * are small. Here the product is just u0*v0.
+ */
+ prod.q = __lmulq(u0, v0);
+ } else {
+ /*
+ * Compute the three intermediate products, remembering
+ * whether the middle term is negative. We can discard
+ * any upper bits in high and mid, so we can use native
+ * u_long * u_long => u_long arithmetic.
+ */
+ low.q = __lmulq(u0, v0);
+
+ if (u1 >= u0)
+ negmid = 0, udiff = u1 - u0;
+ else
+ negmid = 1, udiff = u0 - u1;
+ if (v0 >= v1)
+ vdiff = v0 - v1;
+ else
+ vdiff = v1 - v0, negmid ^= 1;
+ mid = udiff * vdiff;
+
+ high = u1 * v1;
+
+ /*
+ * Assemble the final product.
+ */
+ prod.ul[H] = high + (negmid ? -mid : mid) + low.ul[L] +
+ low.ul[H];
+ prod.ul[L] = low.ul[L];
+ }
+ return (negall ? -prod.q : prod.q);
+#undef u1
+#undef u0
+#undef v1
+#undef v0
+}
+
+/*
+ * Multiply two 2N-bit longs to produce a 4N-bit quad, where N is half
+ * the number of bits in a long (whatever that is---the code below
+ * does not care as long as quad.h does its part of the bargain---but
+ * typically N==16).
+ *
+ * We use the same algorithm from Knuth, but this time the modulo refinement
+ * does not apply. On the other hand, since N is half the size of a long,
+ * we can get away with native multiplication---none of our input terms
+ * exceeds (ULONG_MAX >> 1).
+ *
+ * Note that, for u_long l, the quad-precision result
+ *
+ * l << N
+ *
+ * splits into high and low longs as HHALF(l) and LHUP(l) respectively.
+ */
+static quad_t
+__lmulq(u_long u, u_long v)
+{
+ u_long u1, u0, v1, v0, udiff, vdiff, high, mid, low;
+ u_long prodh, prodl, was;
+ union uu prod;
+ int neg;
+
+ u1 = HHALF(u);
+ u0 = LHALF(u);
+ v1 = HHALF(v);
+ v0 = LHALF(v);
+
+ low = u0 * v0;
+
+ /* This is the same small-number optimization as before. */
+ if (u1 == 0 && v1 == 0)
+ return (low);
+
+ if (u1 >= u0)
+ udiff = u1 - u0, neg = 0;
+ else
+ udiff = u0 - u1, neg = 1;
+ if (v0 >= v1)
+ vdiff = v0 - v1;
+ else
+ vdiff = v1 - v0, neg ^= 1;
+ mid = udiff * vdiff;
+
+ high = u1 * v1;
+
+ /* prod = (high << 2N) + (high << N); */
+ prodh = high + HHALF(high);
+ prodl = LHUP(high);
+
+ /* if (neg) prod -= mid << N; else prod += mid << N; */
+ if (neg) {
+ was = prodl;
+ prodl -= LHUP(mid);
+ prodh -= HHALF(mid) + (prodl > was);
+ } else {
+ was = prodl;
+ prodl += LHUP(mid);
+ prodh += HHALF(mid) + (prodl < was);
+ }
+
+ /* prod += low << N */
+ was = prodl;
+ prodl += LHUP(low);
+ prodh += HHALF(low) + (prodl < was);
+ /* ... + low; */
+ if ((prodl += low) < low)
+ prodh++;
+
+ /* return 4N-bit product */
+ prod.ul[H] = prodh;
+ prod.ul[L] = prodl;
+ return (prod.q);
+}
diff --git a/lib/libc/quad/negdi2.c b/lib/libc/quad/negdi2.c
new file mode 100644
index 0000000..bb8670d
--- /dev/null
+++ b/lib/libc/quad/negdi2.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)negdi2.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return -a (or, equivalently, 0 - a), in quad. See subdi3.c.
+ */
+quad_t
+__negdi2(a)
+ quad_t a;
+{
+ union uu aa, res;
+
+ aa.q = a;
+ res.ul[L] = -aa.ul[L];
+ res.ul[H] = -aa.ul[H] - (res.ul[L] > 0);
+ return (res.q);
+}
diff --git a/lib/libc/quad/notdi2.c b/lib/libc/quad/notdi2.c
new file mode 100644
index 0000000..d624733
--- /dev/null
+++ b/lib/libc/quad/notdi2.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)notdi2.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return ~a. For some reason gcc calls this `one's complement' rather
+ * than `not'.
+ */
+quad_t
+__one_cmpldi2(a)
+ quad_t a;
+{
+ union uu aa;
+
+ aa.q = a;
+ aa.ul[0] = ~aa.ul[0];
+ aa.ul[1] = ~aa.ul[1];
+ return (aa.q);
+}
diff --git a/lib/libc/quad/qdivrem.c b/lib/libc/quad/qdivrem.c
new file mode 100644
index 0000000..56f91ec
--- /dev/null
+++ b/lib/libc/quad/qdivrem.c
@@ -0,0 +1,279 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)qdivrem.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed),
+ * section 4.3.1, pp. 257--259.
+ */
+
+#include "quad.h"
+
+#define B (1 << HALF_BITS) /* digit base */
+
+/* Combine two `digits' to make a single two-digit number. */
+#define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b))
+
+/* select a type for digits in base B: use unsigned short if they fit */
+#if ULONG_MAX == 0xffffffff && USHRT_MAX >= 0xffff
+typedef unsigned short digit;
+#else
+typedef u_long digit;
+#endif
+
+/*
+ * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
+ * `fall out' the left (there never will be any such anyway).
+ * We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS.
+ */
+static void
+shl(register digit *p, register int len, register int sh)
+{
+ register int i;
+
+ for (i = 0; i < len; i++)
+ p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh));
+ p[i] = LHALF(p[i] << sh);
+}
+
+/*
+ * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
+ *
+ * We do this in base 2-sup-HALF_BITS, so that all intermediate products
+ * fit within u_long. As a consequence, the maximum length dividend and
+ * divisor are 4 `digits' in this base (they are shorter if they have
+ * leading zeros).
+ */
+u_quad_t
+__qdivrem(uq, vq, arq)
+ u_quad_t uq, vq, *arq;
+{
+ union uu tmp;
+ digit *u, *v, *q;
+ register digit v1, v2;
+ u_long qhat, rhat, t;
+ int m, n, d, j, i;
+ digit uspace[5], vspace[5], qspace[5];
+
+ /*
+ * Take care of special cases: divide by zero, and u < v.
+ */
+ if (vq == 0) {
+ /* divide by zero. */
+ static volatile const unsigned int zero = 0;
+
+ tmp.ul[H] = tmp.ul[L] = 1 / zero;
+ if (arq)
+ *arq = uq;
+ return (tmp.q);
+ }
+ if (uq < vq) {
+ if (arq)
+ *arq = uq;
+ return (0);
+ }
+ u = &uspace[0];
+ v = &vspace[0];
+ q = &qspace[0];
+
+ /*
+ * Break dividend and divisor into digits in base B, then
+ * count leading zeros to determine m and n. When done, we
+ * will have:
+ * u = (u[1]u[2]...u[m+n]) sub B
+ * v = (v[1]v[2]...v[n]) sub B
+ * v[1] != 0
+ * 1 < n <= 4 (if n = 1, we use a different division algorithm)
+ * m >= 0 (otherwise u < v, which we already checked)
+ * m + n = 4
+ * and thus
+ * m = 4 - n <= 2
+ */
+ tmp.uq = uq;
+ u[0] = 0;
+ u[1] = HHALF(tmp.ul[H]);
+ u[2] = LHALF(tmp.ul[H]);
+ u[3] = HHALF(tmp.ul[L]);
+ u[4] = LHALF(tmp.ul[L]);
+ tmp.uq = vq;
+ v[1] = HHALF(tmp.ul[H]);
+ v[2] = LHALF(tmp.ul[H]);
+ v[3] = HHALF(tmp.ul[L]);
+ v[4] = LHALF(tmp.ul[L]);
+ for (n = 4; v[1] == 0; v++) {
+ if (--n == 1) {
+ u_long rbj; /* r*B+u[j] (not root boy jim) */
+ digit q1, q2, q3, q4;
+
+ /*
+ * Change of plan, per exercise 16.
+ * r = 0;
+ * for j = 1..4:
+ * q[j] = floor((r*B + u[j]) / v),
+ * r = (r*B + u[j]) % v;
+ * We unroll this completely here.
+ */
+ t = v[2]; /* nonzero, by definition */
+ q1 = u[1] / t;
+ rbj = COMBINE(u[1] % t, u[2]);
+ q2 = rbj / t;
+ rbj = COMBINE(rbj % t, u[3]);
+ q3 = rbj / t;
+ rbj = COMBINE(rbj % t, u[4]);
+ q4 = rbj / t;
+ if (arq)
+ *arq = rbj % t;
+ tmp.ul[H] = COMBINE(q1, q2);
+ tmp.ul[L] = COMBINE(q3, q4);
+ return (tmp.q);
+ }
+ }
+
+ /*
+ * By adjusting q once we determine m, we can guarantee that
+ * there is a complete four-digit quotient at &qspace[1] when
+ * we finally stop.
+ */
+ for (m = 4 - n; u[1] == 0; u++)
+ m--;
+ for (i = 4 - m; --i >= 0;)
+ q[i] = 0;
+ q += 4 - m;
+
+ /*
+ * Here we run Program D, translated from MIX to C and acquiring
+ * a few minor changes.
+ *
+ * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
+ */
+ d = 0;
+ for (t = v[1]; t < B / 2; t <<= 1)
+ d++;
+ if (d > 0) {
+ shl(&u[0], m + n, d); /* u <<= d */
+ shl(&v[1], n - 1, d); /* v <<= d */
+ }
+ /*
+ * D2: j = 0.
+ */
+ j = 0;
+ v1 = v[1]; /* for D3 -- note that v[1..n] are constant */
+ v2 = v[2]; /* for D3 */
+ do {
+ register digit uj0, uj1, uj2;
+
+ /*
+ * D3: Calculate qhat (\^q, in TeX notation).
+ * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
+ * let rhat = (u[j]*B + u[j+1]) mod v[1].
+ * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
+ * decrement qhat and increase rhat correspondingly.
+ * Note that if rhat >= B, v[2]*qhat < rhat*B.
+ */
+ uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */
+ uj1 = u[j + 1]; /* for D3 only */
+ uj2 = u[j + 2]; /* for D3 only */
+ if (uj0 == v1) {
+ qhat = B;
+ rhat = uj1;
+ goto qhat_too_big;
+ } else {
+ u_long n = COMBINE(uj0, uj1);
+ qhat = n / v1;
+ rhat = n % v1;
+ }
+ while (v2 * qhat > COMBINE(rhat, uj2)) {
+ qhat_too_big:
+ qhat--;
+ if ((rhat += v1) >= B)
+ break;
+ }
+ /*
+ * D4: Multiply and subtract.
+ * The variable `t' holds any borrows across the loop.
+ * We split this up so that we do not require v[0] = 0,
+ * and to eliminate a final special case.
+ */
+ for (t = 0, i = n; i > 0; i--) {
+ t = u[i + j] - v[i] * qhat - t;
+ u[i + j] = LHALF(t);
+ t = (B - HHALF(t)) & (B - 1);
+ }
+ t = u[j] - t;
+ u[j] = LHALF(t);
+ /*
+ * D5: test remainder.
+ * There is a borrow if and only if HHALF(t) is nonzero;
+ * in that (rare) case, qhat was too large (by exactly 1).
+ * Fix it by adding v[1..n] to u[j..j+n].
+ */
+ if (HHALF(t)) {
+ qhat--;
+ for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
+ t += u[i + j] + v[i];
+ u[i + j] = LHALF(t);
+ t = HHALF(t);
+ }
+ u[j] = LHALF(u[j] + t);
+ }
+ q[j] = qhat;
+ } while (++j <= m); /* D7: loop on j. */
+
+ /*
+ * If caller wants the remainder, we have to calculate it as
+ * u[m..m+n] >> d (this is at most n digits and thus fits in
+ * u[m+1..m+n], but we may need more source digits).
+ */
+ if (arq) {
+ if (d) {
+ for (i = m + n; i > m; --i)
+ u[i] = (u[i] >> d) |
+ LHALF(u[i - 1] << (HALF_BITS - d));
+ u[i] = 0;
+ }
+ tmp.ul[H] = COMBINE(uspace[1], uspace[2]);
+ tmp.ul[L] = COMBINE(uspace[3], uspace[4]);
+ *arq = tmp.q;
+ }
+
+ tmp.ul[H] = COMBINE(qspace[1], qspace[2]);
+ tmp.ul[L] = COMBINE(qspace[3], qspace[4]);
+ return (tmp.q);
+}
diff --git a/lib/libc/quad/quad.h b/lib/libc/quad/quad.h
new file mode 100644
index 0000000..65f0f12
--- /dev/null
+++ b/lib/libc/quad/quad.h
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)quad.h 8.1 (Berkeley) 6/4/93
+ * $FreeBSD$
+ */
+
+/*
+ * Quad arithmetic.
+ *
+ * This library makes the following assumptions:
+ *
+ * - The type long long (aka quad_t) exists.
+ *
+ * - A quad variable is exactly twice as long as `long'.
+ *
+ * - The machine's arithmetic is two's complement.
+ *
+ * This library can provide 128-bit arithmetic on a machine with 128-bit
+ * quads and 64-bit longs, for instance, or 96-bit arithmetic on machines
+ * with 48-bit longs.
+ */
+
+#include <sys/types.h>
+#include <limits.h>
+
+/*
+ * Depending on the desired operation, we view a `long long' (aka quad_t) in
+ * one or more of the following formats.
+ */
+union uu {
+ quad_t q; /* as a (signed) quad */
+ quad_t uq; /* as an unsigned quad */
+ long sl[2]; /* as two signed longs */
+ u_long ul[2]; /* as two unsigned longs */
+};
+
+/*
+ * Define high and low longwords.
+ */
+#define H _QUAD_HIGHWORD
+#define L _QUAD_LOWWORD
+
+/*
+ * Total number of bits in a quad_t and in the pieces that make it up.
+ * These are used for shifting, and also below for halfword extraction
+ * and assembly.
+ */
+#define QUAD_BITS (sizeof(quad_t) * CHAR_BIT)
+#define LONG_BITS (sizeof(long) * CHAR_BIT)
+#define HALF_BITS (sizeof(long) * CHAR_BIT / 2)
+
+/*
+ * Extract high and low shortwords from longword, and move low shortword of
+ * longword to upper half of long, i.e., produce the upper longword of
+ * ((quad_t)(x) << (number_of_bits_in_long/2)). (`x' must actually be u_long.)
+ *
+ * These are used in the multiply code, to split a longword into upper
+ * and lower halves, and to reassemble a product as a quad_t, shifted left
+ * (sizeof(long)*CHAR_BIT/2).
+ */
+#define HHALF(x) ((x) >> HALF_BITS)
+#define LHALF(x) ((x) & ((1 << HALF_BITS) - 1))
+#define LHUP(x) ((x) << HALF_BITS)
+
+quad_t __divdi3 __P((quad_t a, quad_t b));
+quad_t __moddi3 __P((quad_t a, quad_t b));
+u_quad_t __qdivrem __P((u_quad_t u, u_quad_t v, u_quad_t *rem));
+u_quad_t __udivdi3 __P((u_quad_t a, u_quad_t b));
+u_quad_t __umoddi3 __P((u_quad_t a, u_quad_t b));
+
+/*
+ * XXX
+ * Compensate for gcc 1 vs gcc 2. Gcc 1 defines ?sh?di3's second argument
+ * as u_quad_t, while gcc 2 correctly uses int. Unfortunately, we still use
+ * both compilers.
+ */
+#if __GNUC__ >= 2
+typedef unsigned int qshift_t;
+#else
+typedef u_quad_t qshift_t;
+#endif
diff --git a/lib/libc/quad/subdi3.c b/lib/libc/quad/subdi3.c
new file mode 100644
index 0000000..e976345
--- /dev/null
+++ b/lib/libc/quad/subdi3.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)subdi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Subtract two quad values. This is trivial since a one-bit carry
+ * from a single u_long difference x-y occurs if and only if (x-y) > x.
+ */
+quad_t
+__subdi3(a, b)
+ quad_t a, b;
+{
+ union uu aa, bb, diff;
+
+ aa.q = a;
+ bb.q = b;
+ diff.ul[L] = aa.ul[L] - bb.ul[L];
+ diff.ul[H] = aa.ul[H] - bb.ul[H] - (diff.ul[L] > aa.ul[L]);
+ return (diff.q);
+}
diff --git a/lib/libc/quad/ucmpdi2.c b/lib/libc/quad/ucmpdi2.c
new file mode 100644
index 0000000..e5dfc43
--- /dev/null
+++ b/lib/libc/quad/ucmpdi2.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ucmpdi2.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return 0, 1, or 2 as a <, =, > b respectively.
+ * Neither a nor b are considered signed.
+ */
+int
+__ucmpdi2(a, b)
+ u_quad_t a, b;
+{
+ union uu aa, bb;
+
+ aa.uq = a;
+ bb.uq = b;
+ return (aa.ul[H] < bb.ul[H] ? 0 : aa.ul[H] > bb.ul[H] ? 2 :
+ aa.ul[L] < bb.ul[L] ? 0 : aa.ul[L] > bb.ul[L] ? 2 : 1);
+}
diff --git a/lib/libc/quad/udivdi3.c b/lib/libc/quad/udivdi3.c
new file mode 100644
index 0000000..8ddd559
--- /dev/null
+++ b/lib/libc/quad/udivdi3.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)udivdi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Divide two unsigned quads.
+ */
+u_quad_t
+__udivdi3(a, b)
+ u_quad_t a, b;
+{
+
+ return (__qdivrem(a, b, (u_quad_t *)0));
+}
diff --git a/lib/libc/quad/umoddi3.c b/lib/libc/quad/umoddi3.c
new file mode 100644
index 0000000..2a85f76
--- /dev/null
+++ b/lib/libc/quad/umoddi3.c
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)umoddi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return remainder after dividing two unsigned quads.
+ */
+u_quad_t
+__umoddi3(a, b)
+ u_quad_t a, b;
+{
+ u_quad_t r;
+
+ (void)__qdivrem(a, b, &r);
+ return (r);
+}
diff --git a/lib/libc/quad/xordi3.c b/lib/libc/quad/xordi3.c
new file mode 100644
index 0000000..e3a8588
--- /dev/null
+++ b/lib/libc/quad/xordi3.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)xordi3.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return a ^ b, in quad.
+ */
+quad_t
+__xordi3(a, b)
+ quad_t a, b;
+{
+ union uu aa, bb;
+
+ aa.q = a;
+ bb.q = b;
+ aa.ul[0] ^= bb.ul[0];
+ aa.ul[1] ^= bb.ul[1];
+ return (aa.q);
+}
diff --git a/lib/libc/regex/COPYRIGHT b/lib/libc/regex/COPYRIGHT
new file mode 100644
index 0000000..574f6bc
--- /dev/null
+++ b/lib/libc/regex/COPYRIGHT
@@ -0,0 +1,56 @@
+Copyright 1992, 1993, 1994 Henry Spencer. All rights reserved.
+This software is not subject to any license of the American Telephone
+and Telegraph Company or of the Regents of the University of California.
+
+Permission is granted to anyone to use this software for any purpose on
+any computer system, and to alter it and redistribute it, subject
+to the following restrictions:
+
+1. The author is not responsible for the consequences of use of this
+ software, no matter how awful, even if they arise from flaws in it.
+
+2. The origin of this software must not be misrepresented, either by
+ explicit claim or by omission. Since few users ever read sources,
+ credits must appear in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+ misrepresented as being the original software. Since few users
+ ever read sources, credits must appear in the documentation.
+
+4. This notice may not be removed or altered.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/*-
+ * Copyright (c) 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)COPYRIGHT 8.1 (Berkeley) 3/16/94
+ */
diff --git a/lib/libc/regex/Makefile.inc b/lib/libc/regex/Makefile.inc
new file mode 100644
index 0000000..107de2e
--- /dev/null
+++ b/lib/libc/regex/Makefile.inc
@@ -0,0 +1,17 @@
+# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+# regex sources
+.PATH: ${.CURDIR}/../libc/regex
+
+CFLAGS+=-DPOSIX_MISTAKE
+
+SRCS+= regcomp.c regerror.c regexec.c regfree.c
+
+.if ${LIB} == "c"
+MAN3+= regex.3
+MAN7+= re_format.7
+
+MLINKS+=regex.3 regcomp.3 regex.3 regexec.3 regex.3 regerror.3
+MLINKS+=regexec.3 regfree.3
+.endif
diff --git a/lib/libc/regex/WHATSNEW b/lib/libc/regex/WHATSNEW
new file mode 100644
index 0000000..f4301d3
--- /dev/null
+++ b/lib/libc/regex/WHATSNEW
@@ -0,0 +1,94 @@
+# @(#)WHATSNEW 8.3 (Berkeley) 3/18/94
+
+New in alpha3.4: The complex bug alluded to below has been fixed (in a
+slightly kludgey temporary way that may hurt efficiency a bit; this is
+another "get it out the door for 4.4" release). The tests at the end of
+the tests file have accordingly been uncommented. The primary sign of
+the bug was that something like a?b matching ab matched b rather than ab.
+(The bug was essentially specific to this exact situation, else it would
+have shown up earlier.)
+
+New in alpha3.3: The definition of word boundaries has been altered
+slightly, to more closely match the usual programming notion that "_"
+is an alphabetic. Stuff used for pre-ANSI systems is now in a subdir,
+and the makefile no longer alludes to it in mysterious ways. The
+makefile has generally been cleaned up some. Fixes have been made
+(again!) so that the regression test will run without -DREDEBUG, at
+the cost of weaker checking. A workaround for a bug in some folks'
+<assert.h> has been added. And some more things have been added to
+tests, including a couple right at the end which are commented out
+because the code currently flunks them (complex bug; fix coming).
+Plus the usual minor cleanup.
+
+New in alpha3.2: Assorted bits of cleanup and portability improvement
+(the development base is now a BSDI system using GCC instead of an ancient
+Sun system, and the newer compiler exposed some glitches). Fix for a
+serious bug that affected REs using many [] (including REG_ICASE REs
+because of the way they are implemented), *sometimes*, depending on
+memory-allocation patterns. The header-file prototypes no longer name
+the parameters, avoiding possible name conflicts. The possibility that
+some clot has defined CHAR_MIN as (say) `-128' instead of `(-128)' is
+now handled gracefully. "uchar" is no longer used as an internal type
+name (too many people have the same idea). Still the same old lousy
+performance, alas.
+
+New in alpha3.1: Basically nothing, this release is just a bookkeeping
+convenience. Stay tuned.
+
+New in alpha3.0: Performance is no better, alas, but some fixes have been
+made and some functionality has been added. (This is basically the "get
+it out the door in time for 4.4" release.) One bug fix: regfree() didn't
+free the main internal structure (how embarrassing). It is now possible
+to put NULs in either the RE or the target string, using (resp.) a new
+REG_PEND flag and the old REG_STARTEND flag. The REG_NOSPEC flag to
+regcomp() makes all characters ordinary, so you can match a literal
+string easily (this will become more useful when performance improves!).
+There are now primitives to match beginnings and ends of words, although
+the syntax is disgusting and so is the implementation. The REG_ATOI
+debugging interface has changed a bit. And there has been considerable
+internal cleanup of various kinds.
+
+New in alpha2.3: Split change list out of README, and moved flags notes
+into Makefile. Macro-ized the name of regex(7) in regex(3), since it has
+to change for 4.4BSD. Cleanup work in engine.c, and some new regression
+tests to catch tricky cases thereof.
+
+New in alpha2.2: Out-of-date manpages updated. Regerror() acquires two
+small extensions -- REG_ITOA and REG_ATOI -- which avoid debugging kludges
+in my own test program and might be useful to others for similar purposes.
+The regression test will now compile (and run) without REDEBUG. The
+BRE \$ bug is fixed. Most uses of "uchar" are gone; it's all chars now.
+Char/uchar parameters are now written int/unsigned, to avoid possible
+portability problems with unpromoted parameters. Some unsigned casts have
+been introduced to minimize portability problems with shifting into sign
+bits.
+
+New in alpha2.1: Lots of little stuff, cleanup and fixes. The one big
+thing is that regex.h is now generated, using mkh, rather than being
+supplied in the distribution; due to circularities in dependencies,
+you have to build regex.h explicitly by "make h". The two known bugs
+have been fixed (and the regression test now checks for them), as has a
+problem with assertions not being suppressed in the absence of REDEBUG.
+No performance work yet.
+
+New in alpha2: Backslash-anything is an ordinary character, not an
+error (except, of course, for the handful of backslashed metacharacters
+in BREs), which should reduce script breakage. The regression test
+checks *where* null strings are supposed to match, and has generally
+been tightened up somewhat. Small bug fixes in parameter passing (not
+harmful, but technically errors) and some other areas. Debugging
+invoked by defining REDEBUG rather than not defining NDEBUG.
+
+New in alpha+3: full prototyping for internal routines, using a little
+helper program, mkh, which extracts prototypes given in stylized comments.
+More minor cleanup. Buglet fix: it's CHAR_BIT, not CHAR_BITS. Simple
+pre-screening of input when a literal string is known to be part of the
+RE; this does wonders for performance.
+
+New in alpha+2: minor bits of cleanup. Notably, the number "32" for the
+word width isn't hardwired into regexec.c any more, the public header
+file prototypes the functions if __STDC__ is defined, and some small typos
+in the manpages have been fixed.
+
+New in alpha+1: improvements to the manual pages, and an important
+extension, the REG_STARTEND option to regexec().
diff --git a/lib/libc/regex/cclass.h b/lib/libc/regex/cclass.h
new file mode 100644
index 0000000..581909c
--- /dev/null
+++ b/lib/libc/regex/cclass.h
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)cclass.h 8.3 (Berkeley) 3/20/94
+ */
+
+
+typedef enum {CALNUM, CALPHA, CBLANK, CCNTRL, CDIGIT, CGRAPH,
+ CLOWER, CPRINT, CPUNCT, CSPACE, CUPPER, CXDIGIT} citype;
+
+/* character-class table */
+static struct cclass {
+ char *name;
+ citype fidx;
+} cclasses[] = {
+ {"alnum", CALNUM},
+ {"alpha", CALPHA},
+ {"blank", CBLANK},
+ {"cntrl", CCNTRL},
+ {"digit", CDIGIT},
+ {"graph", CGRAPH},
+ {"lower", CLOWER},
+ {"print", CPRINT},
+ {"punct", CPUNCT},
+ {"space", CSPACE},
+ {"upper", CUPPER},
+ {"xdigit", CXDIGIT},
+ {NULL, }
+};
diff --git a/lib/libc/regex/cname.h b/lib/libc/regex/cname.h
new file mode 100644
index 0000000..72bbe5e
--- /dev/null
+++ b/lib/libc/regex/cname.h
@@ -0,0 +1,141 @@
+/*-
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)cname.h 8.3 (Berkeley) 3/20/94
+ */
+
+/* character-name table */
+static struct cname {
+ char *name;
+ char code;
+} cnames[] = {
+ {"NUL", '\0'},
+ {"SOH", '\001'},
+ {"STX", '\002'},
+ {"ETX", '\003'},
+ {"EOT", '\004'},
+ {"ENQ", '\005'},
+ {"ACK", '\006'},
+ {"BEL", '\007'},
+ {"alert", '\007'},
+ {"BS", '\010'},
+ {"backspace", '\b'},
+ {"HT", '\011'},
+ {"tab", '\t'},
+ {"LF", '\012'},
+ {"newline", '\n'},
+ {"VT", '\013'},
+ {"vertical-tab", '\v'},
+ {"FF", '\014'},
+ {"form-feed", '\f'},
+ {"CR", '\015'},
+ {"carriage-return", '\r'},
+ {"SO", '\016'},
+ {"SI", '\017'},
+ {"DLE", '\020'},
+ {"DC1", '\021'},
+ {"DC2", '\022'},
+ {"DC3", '\023'},
+ {"DC4", '\024'},
+ {"NAK", '\025'},
+ {"SYN", '\026'},
+ {"ETB", '\027'},
+ {"CAN", '\030'},
+ {"EM", '\031'},
+ {"SUB", '\032'},
+ {"ESC", '\033'},
+ {"IS4", '\034'},
+ {"FS", '\034'},
+ {"IS3", '\035'},
+ {"GS", '\035'},
+ {"IS2", '\036'},
+ {"RS", '\036'},
+ {"IS1", '\037'},
+ {"US", '\037'},
+ {"space", ' '},
+ {"exclamation-mark", '!'},
+ {"quotation-mark", '"'},
+ {"number-sign", '#'},
+ {"dollar-sign", '$'},
+ {"percent-sign", '%'},
+ {"ampersand", '&'},
+ {"apostrophe", '\''},
+ {"left-parenthesis", '('},
+ {"right-parenthesis", ')'},
+ {"asterisk", '*'},
+ {"plus-sign", '+'},
+ {"comma", ','},
+ {"hyphen", '-'},
+ {"hyphen-minus", '-'},
+ {"period", '.'},
+ {"full-stop", '.'},
+ {"slash", '/'},
+ {"solidus", '/'},
+ {"zero", '0'},
+ {"one", '1'},
+ {"two", '2'},
+ {"three", '3'},
+ {"four", '4'},
+ {"five", '5'},
+ {"six", '6'},
+ {"seven", '7'},
+ {"eight", '8'},
+ {"nine", '9'},
+ {"colon", ':'},
+ {"semicolon", ';'},
+ {"less-than-sign", '<'},
+ {"equals-sign", '='},
+ {"greater-than-sign", '>'},
+ {"question-mark", '?'},
+ {"commercial-at", '@'},
+ {"left-square-bracket", '['},
+ {"backslash", '\\'},
+ {"reverse-solidus", '\\'},
+ {"right-square-bracket",']'},
+ {"circumflex", '^'},
+ {"circumflex-accent", '^'},
+ {"underscore", '_'},
+ {"low-line", '_'},
+ {"grave-accent", '`'},
+ {"left-brace", '{'},
+ {"left-curly-bracket", '{'},
+ {"vertical-line", '|'},
+ {"right-brace", '}'},
+ {"right-curly-bracket", '}'},
+ {"tilde", '~'},
+ {"DEL", '\177'},
+ {NULL, 0}
+};
diff --git a/lib/libc/regex/engine.c b/lib/libc/regex/engine.c
new file mode 100644
index 0000000..be569b1
--- /dev/null
+++ b/lib/libc/regex/engine.c
@@ -0,0 +1,1092 @@
+/*-
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)engine.c 8.5 (Berkeley) 3/20/94
+ */
+
+/*
+ * The matching engine and friends. This file is #included by regexec.c
+ * after suitable #defines of a variety of macros used herein, so that
+ * different state representations can be used without duplicating masses
+ * of code.
+ */
+
+#ifdef SNAMES
+#define matcher smatcher
+#define fast sfast
+#define slow sslow
+#define dissect sdissect
+#define backref sbackref
+#define step sstep
+#define print sprint
+#define at sat
+#define match smat
+#endif
+#ifdef LNAMES
+#define matcher lmatcher
+#define fast lfast
+#define slow lslow
+#define dissect ldissect
+#define backref lbackref
+#define step lstep
+#define print lprint
+#define at lat
+#define match lmat
+#endif
+
+/* another structure passed up and down to avoid zillions of parameters */
+struct match {
+ struct re_guts *g;
+ int eflags;
+ regmatch_t *pmatch; /* [nsub+1] (0 element unused) */
+ char *offp; /* offsets work from here */
+ char *beginp; /* start of string -- virtual NUL precedes */
+ char *endp; /* end of string -- virtual NUL here */
+ char *coldp; /* can be no match starting before here */
+ char **lastpos; /* [nplus+1] */
+ STATEVARS;
+ states st; /* current states */
+ states fresh; /* states for a fresh start */
+ states tmp; /* temporary */
+ states empty; /* empty set of states */
+};
+
+/* ========= begin header generated by ./mkh ========= */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* === engine.c === */
+static int matcher __P((struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags));
+static char *dissect __P((struct match *m, char *start, char *stop, sopno startst, sopno stopst));
+static char *backref __P((struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev));
+static char *fast __P((struct match *m, char *start, char *stop, sopno startst, sopno stopst));
+static char *slow __P((struct match *m, char *start, char *stop, sopno startst, sopno stopst));
+static states step __P((struct re_guts *g, sopno start, sopno stop, states bef, int ch, states aft));
+#define BOL (OUT+1)
+#define EOL (BOL+1)
+#define BOLEOL (BOL+2)
+#define NOTHING (BOL+3)
+#define BOW (BOL+4)
+#define EOW (BOL+5)
+#define CODEMAX (BOL+5) /* highest code used */
+#define NONCHAR(c) ((c) > CHAR_MAX)
+#define NNONCHAR (CODEMAX-CHAR_MAX)
+#ifdef REDEBUG
+static void print __P((struct match *m, char *caption, states st, int ch, FILE *d));
+#endif
+#ifdef REDEBUG
+static void at __P((struct match *m, char *title, char *start, char *stop, sopno startst, sopno stopst));
+#endif
+#ifdef REDEBUG
+static char *pchar __P((int ch));
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+/* ========= end header generated by ./mkh ========= */
+
+#ifdef REDEBUG
+#define SP(t, s, c) print(m, t, s, c, stdout)
+#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2)
+#define NOTE(str) { if (m->eflags&REG_TRACE) printf("=%s\n", (str)); }
+#else
+#define SP(t, s, c) /* nothing */
+#define AT(t, p1, p2, s1, s2) /* nothing */
+#define NOTE(s) /* nothing */
+#endif
+
+/*
+ - matcher - the actual matching engine
+ == static int matcher(register struct re_guts *g, char *string, \
+ == size_t nmatch, regmatch_t pmatch[], int eflags);
+ */
+static int /* 0 success, REG_NOMATCH failure */
+matcher(g, string, nmatch, pmatch, eflags)
+register struct re_guts *g;
+char *string;
+size_t nmatch;
+regmatch_t pmatch[];
+int eflags;
+{
+ register char *endp;
+ register int i;
+ struct match mv;
+ register struct match *m = &mv;
+ register char *dp;
+ register const sopno gf = g->firststate+1; /* +1 for OEND */
+ register const sopno gl = g->laststate;
+ char *start;
+ char *stop;
+
+ /* simplify the situation where possible */
+ if (g->cflags&REG_NOSUB)
+ nmatch = 0;
+ if (eflags&REG_STARTEND) {
+ start = string + pmatch[0].rm_so;
+ stop = string + pmatch[0].rm_eo;
+ } else {
+ start = string;
+ stop = start + strlen(start);
+ }
+ if (stop < start)
+ return(REG_INVARG);
+
+ /* prescreening; this does wonders for this rather slow code */
+ if (g->must != NULL) {
+ for (dp = start; dp < stop; dp++)
+ if (*dp == g->must[0] && stop - dp >= g->mlen &&
+ memcmp(dp, g->must, (size_t)g->mlen) == 0)
+ break;
+ if (dp == stop) /* we didn't find g->must */
+ return(REG_NOMATCH);
+ }
+
+ /* match struct setup */
+ m->g = g;
+ m->eflags = eflags;
+ m->pmatch = NULL;
+ m->lastpos = NULL;
+ m->offp = string;
+ m->beginp = start;
+ m->endp = stop;
+ STATESETUP(m, 4);
+ SETUP(m->st);
+ SETUP(m->fresh);
+ SETUP(m->tmp);
+ SETUP(m->empty);
+ CLEAR(m->empty);
+
+ /* this loop does only one repetition except for backrefs */
+ for (;;) {
+ endp = fast(m, start, stop, gf, gl);
+ if (endp == NULL) { /* a miss */
+ STATETEARDOWN(m);
+ return(REG_NOMATCH);
+ }
+ if (nmatch == 0 && !g->backrefs)
+ break; /* no further info needed */
+
+ /* where? */
+ assert(m->coldp != NULL);
+ for (;;) {
+ NOTE("finding start");
+ endp = slow(m, m->coldp, stop, gf, gl);
+ if (endp != NULL)
+ break;
+ assert(m->coldp < m->endp);
+ m->coldp++;
+ }
+ if (nmatch == 1 && !g->backrefs)
+ break; /* no further info needed */
+
+ /* oh my, he wants the subexpressions... */
+ if (m->pmatch == NULL)
+ m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) *
+ sizeof(regmatch_t));
+ if (m->pmatch == NULL) {
+ STATETEARDOWN(m);
+ return(REG_ESPACE);
+ }
+ for (i = 1; i <= m->g->nsub; i++)
+ m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1;
+ if (!g->backrefs && !(m->eflags&REG_BACKR)) {
+ NOTE("dissecting");
+ dp = dissect(m, m->coldp, endp, gf, gl);
+ } else {
+ if (g->nplus > 0 && m->lastpos == NULL)
+ m->lastpos = (char **)malloc((g->nplus+1) *
+ sizeof(char *));
+ if (g->nplus > 0 && m->lastpos == NULL) {
+ free(m->pmatch);
+ STATETEARDOWN(m);
+ return(REG_ESPACE);
+ }
+ NOTE("backref dissect");
+ dp = backref(m, m->coldp, endp, gf, gl, (sopno)0);
+ }
+ if (dp != NULL)
+ break;
+
+ /* uh-oh... we couldn't find a subexpression-level match */
+ assert(g->backrefs); /* must be back references doing it */
+ assert(g->nplus == 0 || m->lastpos != NULL);
+ for (;;) {
+ if (dp != NULL || endp <= m->coldp)
+ break; /* defeat */
+ NOTE("backoff");
+ endp = slow(m, m->coldp, endp-1, gf, gl);
+ if (endp == NULL)
+ break; /* defeat */
+ /* try it on a shorter possibility */
+#ifndef NDEBUG
+ for (i = 1; i <= m->g->nsub; i++) {
+ assert(m->pmatch[i].rm_so == -1);
+ assert(m->pmatch[i].rm_eo == -1);
+ }
+#endif
+ NOTE("backoff dissect");
+ dp = backref(m, m->coldp, endp, gf, gl, (sopno)0);
+ }
+ assert(dp == NULL || dp == endp);
+ if (dp != NULL) /* found a shorter one */
+ break;
+
+ /* despite initial appearances, there is no match here */
+ NOTE("false alarm");
+ start = m->coldp + 1; /* recycle starting later */
+ assert(start <= stop);
+ }
+
+ /* fill in the details if requested */
+ if (nmatch > 0) {
+ pmatch[0].rm_so = m->coldp - m->offp;
+ pmatch[0].rm_eo = endp - m->offp;
+ }
+ if (nmatch > 1) {
+ assert(m->pmatch != NULL);
+ for (i = 1; i < nmatch; i++)
+ if (i <= m->g->nsub)
+ pmatch[i] = m->pmatch[i];
+ else {
+ pmatch[i].rm_so = -1;
+ pmatch[i].rm_eo = -1;
+ }
+ }
+
+ if (m->pmatch != NULL)
+ free((char *)m->pmatch);
+ if (m->lastpos != NULL)
+ free((char *)m->lastpos);
+ STATETEARDOWN(m);
+ return(0);
+}
+
+/*
+ - dissect - figure out what matched what, no back references
+ == static char *dissect(register struct match *m, char *start, \
+ == char *stop, sopno startst, sopno stopst);
+ */
+static char * /* == stop (success) always */
+dissect(m, start, stop, startst, stopst)
+register struct match *m;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+{
+ register int i;
+ register sopno ss; /* start sop of current subRE */
+ register sopno es; /* end sop of current subRE */
+ register char *sp; /* start of string matched by it */
+ register char *stp; /* string matched by it cannot pass here */
+ register char *rest; /* start of rest of string */
+ register char *tail; /* string unmatched by rest of RE */
+ register sopno ssub; /* start sop of subsubRE */
+ register sopno esub; /* end sop of subsubRE */
+ register char *ssp; /* start of string matched by subsubRE */
+ register char *sep; /* end of string matched by subsubRE */
+ register char *oldssp; /* previous ssp */
+ register char *dp;
+
+ AT("diss", start, stop, startst, stopst);
+ sp = start;
+ for (ss = startst; ss < stopst; ss = es) {
+ /* identify end of subRE */
+ es = ss;
+ switch (OP(m->g->strip[es])) {
+ case OPLUS_:
+ case OQUEST_:
+ es += OPND(m->g->strip[es]);
+ break;
+ case OCH_:
+ while (OP(m->g->strip[es]) != O_CH)
+ es += OPND(m->g->strip[es]);
+ break;
+ }
+ es++;
+
+ /* figure out what it matched */
+ switch (OP(m->g->strip[ss])) {
+ case OEND:
+ assert(nope);
+ break;
+ case OCHAR:
+ sp++;
+ break;
+ case OBOL:
+ case OEOL:
+ case OBOW:
+ case OEOW:
+ break;
+ case OANY:
+ case OANYOF:
+ sp++;
+ break;
+ case OBACK_:
+ case O_BACK:
+ assert(nope);
+ break;
+ /* cases where length of match is hard to find */
+ case OQUEST_:
+ stp = stop;
+ for (;;) {
+ /* how long could this one be? */
+ rest = slow(m, sp, stp, ss, es);
+ assert(rest != NULL); /* it did match */
+ /* could the rest match the rest? */
+ tail = slow(m, rest, stop, es, stopst);
+ if (tail == stop)
+ break; /* yes! */
+ /* no -- try a shorter match for this one */
+ stp = rest - 1;
+ assert(stp >= sp); /* it did work */
+ }
+ ssub = ss + 1;
+ esub = es - 1;
+ /* did innards match? */
+ if (slow(m, sp, rest, ssub, esub) != NULL) {
+ dp = dissect(m, sp, rest, ssub, esub);
+ assert(dp == rest);
+ } else /* no */
+ assert(sp == rest);
+ sp = rest;
+ break;
+ case OPLUS_:
+ stp = stop;
+ for (;;) {
+ /* how long could this one be? */
+ rest = slow(m, sp, stp, ss, es);
+ assert(rest != NULL); /* it did match */
+ /* could the rest match the rest? */
+ tail = slow(m, rest, stop, es, stopst);
+ if (tail == stop)
+ break; /* yes! */
+ /* no -- try a shorter match for this one */
+ stp = rest - 1;
+ assert(stp >= sp); /* it did work */
+ }
+ ssub = ss + 1;
+ esub = es - 1;
+ ssp = sp;
+ oldssp = ssp;
+ for (;;) { /* find last match of innards */
+ sep = slow(m, ssp, rest, ssub, esub);
+ if (sep == NULL || sep == ssp)
+ break; /* failed or matched null */
+ oldssp = ssp; /* on to next try */
+ ssp = sep;
+ }
+ if (sep == NULL) {
+ /* last successful match */
+ sep = ssp;
+ ssp = oldssp;
+ }
+ assert(sep == rest); /* must exhaust substring */
+ assert(slow(m, ssp, sep, ssub, esub) == rest);
+ dp = dissect(m, ssp, sep, ssub, esub);
+ assert(dp == sep);
+ sp = rest;
+ break;
+ case OCH_:
+ stp = stop;
+ for (;;) {
+ /* how long could this one be? */
+ rest = slow(m, sp, stp, ss, es);
+ assert(rest != NULL); /* it did match */
+ /* could the rest match the rest? */
+ tail = slow(m, rest, stop, es, stopst);
+ if (tail == stop)
+ break; /* yes! */
+ /* no -- try a shorter match for this one */
+ stp = rest - 1;
+ assert(stp >= sp); /* it did work */
+ }
+ ssub = ss + 1;
+ esub = ss + OPND(m->g->strip[ss]) - 1;
+ assert(OP(m->g->strip[esub]) == OOR1);
+ for (;;) { /* find first matching branch */
+ if (slow(m, sp, rest, ssub, esub) == rest)
+ break; /* it matched all of it */
+ /* that one missed, try next one */
+ assert(OP(m->g->strip[esub]) == OOR1);
+ esub++;
+ assert(OP(m->g->strip[esub]) == OOR2);
+ ssub = esub + 1;
+ esub += OPND(m->g->strip[esub]);
+ if (OP(m->g->strip[esub]) == OOR2)
+ esub--;
+ else
+ assert(OP(m->g->strip[esub]) == O_CH);
+ }
+ dp = dissect(m, sp, rest, ssub, esub);
+ assert(dp == rest);
+ sp = rest;
+ break;
+ case O_PLUS:
+ case O_QUEST:
+ case OOR1:
+ case OOR2:
+ case O_CH:
+ assert(nope);
+ break;
+ case OLPAREN:
+ i = OPND(m->g->strip[ss]);
+ assert(0 < i && i <= m->g->nsub);
+ m->pmatch[i].rm_so = sp - m->offp;
+ break;
+ case ORPAREN:
+ i = OPND(m->g->strip[ss]);
+ assert(0 < i && i <= m->g->nsub);
+ m->pmatch[i].rm_eo = sp - m->offp;
+ break;
+ default: /* uh oh */
+ assert(nope);
+ break;
+ }
+ }
+
+ assert(sp == stop);
+ return(sp);
+}
+
+/*
+ - backref - figure out what matched what, figuring in back references
+ == static char *backref(register struct match *m, char *start, \
+ == char *stop, sopno startst, sopno stopst, sopno lev);
+ */
+static char * /* == stop (success) or NULL (failure) */
+backref(m, start, stop, startst, stopst, lev)
+register struct match *m;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+sopno lev; /* PLUS nesting level */
+{
+ register int i;
+ register sopno ss; /* start sop of current subRE */
+ register char *sp; /* start of string matched by it */
+ register sopno ssub; /* start sop of subsubRE */
+ register sopno esub; /* end sop of subsubRE */
+ register char *ssp; /* start of string matched by subsubRE */
+ register char *dp;
+ register size_t len;
+ register int hard;
+ register sop s;
+ register regoff_t offsave;
+ register cset *cs;
+
+ AT("back", start, stop, startst, stopst);
+ sp = start;
+
+ /* get as far as we can with easy stuff */
+ hard = 0;
+ for (ss = startst; !hard && ss < stopst; ss++)
+ switch (OP(s = m->g->strip[ss])) {
+ case OCHAR:
+ if (sp == stop || *sp++ != (char)OPND(s))
+ return(NULL);
+ break;
+ case OANY:
+ if (sp == stop)
+ return(NULL);
+ sp++;
+ break;
+ case OANYOF:
+ cs = &m->g->sets[OPND(s)];
+ if (sp == stop || !CHIN(cs, *sp++))
+ return(NULL);
+ break;
+ case OBOL:
+ if ( (sp == m->beginp && !(m->eflags&REG_NOTBOL)) ||
+ (sp < m->endp && *(sp-1) == '\n' &&
+ (m->g->cflags&REG_NEWLINE)) )
+ { /* yes */ }
+ else
+ return(NULL);
+ break;
+ case OEOL:
+ if ( (sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
+ (sp < m->endp && *sp == '\n' &&
+ (m->g->cflags&REG_NEWLINE)) )
+ { /* yes */ }
+ else
+ return(NULL);
+ break;
+ case OBOW:
+ if (( (sp == m->beginp && !(m->eflags&REG_NOTBOL)) ||
+ (sp < m->endp && *(sp-1) == '\n' &&
+ (m->g->cflags&REG_NEWLINE)) ||
+ (sp > m->beginp &&
+ !ISWORD(*(sp-1))) ) &&
+ (sp < m->endp && ISWORD(*sp)) )
+ { /* yes */ }
+ else
+ return(NULL);
+ break;
+ case OEOW:
+ if (( (sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
+ (sp < m->endp && *sp == '\n' &&
+ (m->g->cflags&REG_NEWLINE)) ||
+ (sp < m->endp && !ISWORD(*sp)) ) &&
+ (sp > m->beginp && ISWORD(*(sp-1))) )
+ { /* yes */ }
+ else
+ return(NULL);
+ break;
+ case O_QUEST:
+ break;
+ case OOR1: /* matches null but needs to skip */
+ ss++;
+ s = m->g->strip[ss];
+ do {
+ assert(OP(s) == OOR2);
+ ss += OPND(s);
+ } while (OP(s = m->g->strip[ss]) != O_CH);
+ /* note that the ss++ gets us past the O_CH */
+ break;
+ default: /* have to make a choice */
+ hard = 1;
+ break;
+ }
+ if (!hard) { /* that was it! */
+ if (sp != stop)
+ return(NULL);
+ return(sp);
+ }
+ ss--; /* adjust for the for's final increment */
+
+ /* the hard stuff */
+ AT("hard", sp, stop, ss, stopst);
+ s = m->g->strip[ss];
+ switch (OP(s)) {
+ case OBACK_: /* the vilest depths */
+ i = OPND(s);
+ assert(0 < i && i <= m->g->nsub);
+ if (m->pmatch[i].rm_eo == -1)
+ return(NULL);
+ assert(m->pmatch[i].rm_so != -1);
+ len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so;
+ assert(stop - m->beginp >= len);
+ if (sp > stop - len)
+ return(NULL); /* not enough left to match */
+ ssp = m->offp + m->pmatch[i].rm_so;
+ if (memcmp(sp, ssp, len) != 0)
+ return(NULL);
+ while (m->g->strip[ss] != SOP(O_BACK, i))
+ ss++;
+ return(backref(m, sp+len, stop, ss+1, stopst, lev));
+ break;
+ case OQUEST_: /* to null or not */
+ dp = backref(m, sp, stop, ss+1, stopst, lev);
+ if (dp != NULL)
+ return(dp); /* not */
+ return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev));
+ break;
+ case OPLUS_:
+ assert(m->lastpos != NULL);
+ assert(lev+1 <= m->g->nplus);
+ m->lastpos[lev+1] = sp;
+ return(backref(m, sp, stop, ss+1, stopst, lev+1));
+ break;
+ case O_PLUS:
+ if (sp == m->lastpos[lev]) /* last pass matched null */
+ return(backref(m, sp, stop, ss+1, stopst, lev-1));
+ /* try another pass */
+ m->lastpos[lev] = sp;
+ dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev);
+ if (dp == NULL)
+ return(backref(m, sp, stop, ss+1, stopst, lev-1));
+ else
+ return(dp);
+ break;
+ case OCH_: /* find the right one, if any */
+ ssub = ss + 1;
+ esub = ss + OPND(s) - 1;
+ assert(OP(m->g->strip[esub]) == OOR1);
+ for (;;) { /* find first matching branch */
+ dp = backref(m, sp, stop, ssub, esub, lev);
+ if (dp != NULL)
+ return(dp);
+ /* that one missed, try next one */
+ if (OP(m->g->strip[esub]) == O_CH)
+ return(NULL); /* there is none */
+ esub++;
+ assert(OP(m->g->strip[esub]) == OOR2);
+ ssub = esub + 1;
+ esub += OPND(m->g->strip[esub]);
+ if (OP(m->g->strip[esub]) == OOR2)
+ esub--;
+ else
+ assert(OP(m->g->strip[esub]) == O_CH);
+ }
+ break;
+ case OLPAREN: /* must undo assignment if rest fails */
+ i = OPND(s);
+ assert(0 < i && i <= m->g->nsub);
+ offsave = m->pmatch[i].rm_so;
+ m->pmatch[i].rm_so = sp - m->offp;
+ dp = backref(m, sp, stop, ss+1, stopst, lev);
+ if (dp != NULL)
+ return(dp);
+ m->pmatch[i].rm_so = offsave;
+ return(NULL);
+ break;
+ case ORPAREN: /* must undo assignment if rest fails */
+ i = OPND(s);
+ assert(0 < i && i <= m->g->nsub);
+ offsave = m->pmatch[i].rm_eo;
+ m->pmatch[i].rm_eo = sp - m->offp;
+ dp = backref(m, sp, stop, ss+1, stopst, lev);
+ if (dp != NULL)
+ return(dp);
+ m->pmatch[i].rm_eo = offsave;
+ return(NULL);
+ break;
+ default: /* uh oh */
+ assert(nope);
+ break;
+ }
+
+ /* "can't happen" */
+ assert(nope);
+ /* NOTREACHED */
+ return "shut up gcc";
+}
+
+/*
+ - fast - step through the string at top speed
+ == static char *fast(register struct match *m, char *start, \
+ == char *stop, sopno startst, sopno stopst);
+ */
+static char * /* where tentative match ended, or NULL */
+fast(m, start, stop, startst, stopst)
+register struct match *m;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+{
+ register states st = m->st;
+ register states fresh = m->fresh;
+ register states tmp = m->tmp;
+ register char *p = start;
+ register int c = (start == m->beginp) ? OUT : *(start-1);
+ register int lastc; /* previous c */
+ register int flagch;
+ register int i;
+ register char *coldp; /* last p after which no match was underway */
+
+ CLEAR(st);
+ SET1(st, startst);
+ st = step(m->g, startst, stopst, st, NOTHING, st);
+ ASSIGN(fresh, st);
+ SP("start", st, *p);
+ coldp = NULL;
+ for (;;) {
+ /* next character */
+ lastc = c;
+ c = (p == m->endp) ? OUT : *p;
+ if (EQ(st, fresh))
+ coldp = p;
+
+ /* is there an EOL and/or BOL between lastc and c? */
+ flagch = '\0';
+ i = 0;
+ if ( (lastc == '\n' && m->g->cflags&REG_NEWLINE) ||
+ (lastc == OUT && !(m->eflags&REG_NOTBOL)) ) {
+ flagch = BOL;
+ i = m->g->nbol;
+ }
+ if ( (c == '\n' && m->g->cflags&REG_NEWLINE) ||
+ (c == OUT && !(m->eflags&REG_NOTEOL)) ) {
+ flagch = (flagch == BOL) ? BOLEOL : EOL;
+ i += m->g->neol;
+ }
+ if (i != 0) {
+ for (; i > 0; i--)
+ st = step(m->g, startst, stopst, st, flagch, st);
+ SP("boleol", st, c);
+ }
+
+ /* how about a word boundary? */
+ if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
+ (c != OUT && ISWORD(c)) ) {
+ flagch = BOW;
+ }
+ if ( (lastc != OUT && ISWORD(lastc)) &&
+ (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
+ flagch = EOW;
+ }
+ if (flagch == BOW || flagch == EOW) {
+ st = step(m->g, startst, stopst, st, flagch, st);
+ SP("boweow", st, c);
+ }
+
+ /* are we done? */
+ if (ISSET(st, stopst) || p == stop)
+ break; /* NOTE BREAK OUT */
+
+ /* no, we must deal with this character */
+ ASSIGN(tmp, st);
+ ASSIGN(st, fresh);
+ assert(c != OUT);
+ st = step(m->g, startst, stopst, tmp, c, st);
+ SP("aft", st, c);
+ assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
+ p++;
+ }
+
+ assert(coldp != NULL);
+ m->coldp = coldp;
+ if (ISSET(st, stopst))
+ return(p+1);
+ else
+ return(NULL);
+}
+
+/*
+ - slow - step through the string more deliberately
+ == static char *slow(register struct match *m, char *start, \
+ == char *stop, sopno startst, sopno stopst);
+ */
+static char * /* where it ended */
+slow(m, start, stop, startst, stopst)
+register struct match *m;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+{
+ register states st = m->st;
+ register states empty = m->empty;
+ register states tmp = m->tmp;
+ register char *p = start;
+ register int c = (start == m->beginp) ? OUT : *(start-1);
+ register int lastc; /* previous c */
+ register int flagch;
+ register int i;
+ register char *matchp; /* last p at which a match ended */
+
+ AT("slow", start, stop, startst, stopst);
+ CLEAR(st);
+ SET1(st, startst);
+ SP("sstart", st, *p);
+ st = step(m->g, startst, stopst, st, NOTHING, st);
+ matchp = NULL;
+ for (;;) {
+ /* next character */
+ lastc = c;
+ c = (p == m->endp) ? OUT : *p;
+
+ /* is there an EOL and/or BOL between lastc and c? */
+ flagch = '\0';
+ i = 0;
+ if ( (lastc == '\n' && m->g->cflags&REG_NEWLINE) ||
+ (lastc == OUT && !(m->eflags&REG_NOTBOL)) ) {
+ flagch = BOL;
+ i = m->g->nbol;
+ }
+ if ( (c == '\n' && m->g->cflags&REG_NEWLINE) ||
+ (c == OUT && !(m->eflags&REG_NOTEOL)) ) {
+ flagch = (flagch == BOL) ? BOLEOL : EOL;
+ i += m->g->neol;
+ }
+ if (i != 0) {
+ for (; i > 0; i--)
+ st = step(m->g, startst, stopst, st, flagch, st);
+ SP("sboleol", st, c);
+ }
+
+ /* how about a word boundary? */
+ if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
+ (c != OUT && ISWORD(c)) ) {
+ flagch = BOW;
+ }
+ if ( (lastc != OUT && ISWORD(lastc)) &&
+ (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
+ flagch = EOW;
+ }
+ if (flagch == BOW || flagch == EOW) {
+ st = step(m->g, startst, stopst, st, flagch, st);
+ SP("sboweow", st, c);
+ }
+
+ /* are we done? */
+ if (ISSET(st, stopst))
+ matchp = p;
+ if (EQ(st, empty) || p == stop)
+ break; /* NOTE BREAK OUT */
+
+ /* no, we must deal with this character */
+ ASSIGN(tmp, st);
+ ASSIGN(st, empty);
+ assert(c != OUT);
+ st = step(m->g, startst, stopst, tmp, c, st);
+ SP("saft", st, c);
+ assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
+ p++;
+ }
+
+ return(matchp);
+}
+
+
+/*
+ - step - map set of states reachable before char to set reachable after
+ == static states step(register struct re_guts *g, sopno start, sopno stop, \
+ == register states bef, int ch, register states aft);
+ == #define BOL (OUT+1)
+ == #define EOL (BOL+1)
+ == #define BOLEOL (BOL+2)
+ == #define NOTHING (BOL+3)
+ == #define BOW (BOL+4)
+ == #define EOW (BOL+5)
+ == #define CODEMAX (BOL+5) // highest code used
+ == #define NONCHAR(c) ((c) > CHAR_MAX)
+ == #define NNONCHAR (CODEMAX-CHAR_MAX)
+ */
+static states
+step(g, start, stop, bef, ch, aft)
+register struct re_guts *g;
+sopno start; /* start state within strip */
+sopno stop; /* state after stop state within strip */
+register states bef; /* states reachable before */
+int ch; /* character or NONCHAR code */
+register states aft; /* states already known reachable after */
+{
+ register cset *cs;
+ register sop s;
+ register sopno pc;
+ register onestate here; /* note, macros know this name */
+ register sopno look;
+ register int i;
+
+ for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) {
+ s = g->strip[pc];
+ switch (OP(s)) {
+ case OEND:
+ assert(pc == stop-1);
+ break;
+ case OCHAR:
+ /* only characters can match */
+ assert(!NONCHAR(ch) || ch != (char)OPND(s));
+ if (ch == (char)OPND(s))
+ FWD(aft, bef, 1);
+ break;
+ case OBOL:
+ if (ch == BOL || ch == BOLEOL)
+ FWD(aft, bef, 1);
+ break;
+ case OEOL:
+ if (ch == EOL || ch == BOLEOL)
+ FWD(aft, bef, 1);
+ break;
+ case OBOW:
+ if (ch == BOW)
+ FWD(aft, bef, 1);
+ break;
+ case OEOW:
+ if (ch == EOW)
+ FWD(aft, bef, 1);
+ break;
+ case OANY:
+ if (!NONCHAR(ch))
+ FWD(aft, bef, 1);
+ break;
+ case OANYOF:
+ cs = &g->sets[OPND(s)];
+ if (!NONCHAR(ch) && CHIN(cs, ch))
+ FWD(aft, bef, 1);
+ break;
+ case OBACK_: /* ignored here */
+ case O_BACK:
+ FWD(aft, aft, 1);
+ break;
+ case OPLUS_: /* forward, this is just an empty */
+ FWD(aft, aft, 1);
+ break;
+ case O_PLUS: /* both forward and back */
+ FWD(aft, aft, 1);
+ i = ISSETBACK(aft, OPND(s));
+ BACK(aft, aft, OPND(s));
+ if (!i && ISSETBACK(aft, OPND(s))) {
+ /* oho, must reconsider loop body */
+ pc -= OPND(s) + 1;
+ INIT(here, pc);
+ }
+ break;
+ case OQUEST_: /* two branches, both forward */
+ FWD(aft, aft, 1);
+ FWD(aft, aft, OPND(s));
+ break;
+ case O_QUEST: /* just an empty */
+ FWD(aft, aft, 1);
+ break;
+ case OLPAREN: /* not significant here */
+ case ORPAREN:
+ FWD(aft, aft, 1);
+ break;
+ case OCH_: /* mark the first two branches */
+ FWD(aft, aft, 1);
+ assert(OP(g->strip[pc+OPND(s)]) == OOR2);
+ FWD(aft, aft, OPND(s));
+ break;
+ case OOR1: /* done a branch, find the O_CH */
+ if (ISSTATEIN(aft, here)) {
+ for (look = 1;
+ OP(s = g->strip[pc+look]) != O_CH;
+ look += OPND(s))
+ assert(OP(s) == OOR2);
+ FWD(aft, aft, look);
+ }
+ break;
+ case OOR2: /* propagate OCH_'s marking */
+ FWD(aft, aft, 1);
+ if (OP(g->strip[pc+OPND(s)]) != O_CH) {
+ assert(OP(g->strip[pc+OPND(s)]) == OOR2);
+ FWD(aft, aft, OPND(s));
+ }
+ break;
+ case O_CH: /* just empty */
+ FWD(aft, aft, 1);
+ break;
+ default: /* ooooops... */
+ assert(nope);
+ break;
+ }
+ }
+
+ return(aft);
+}
+
+#ifdef REDEBUG
+/*
+ - print - print a set of states
+ == #ifdef REDEBUG
+ == static void print(struct match *m, char *caption, states st, \
+ == int ch, FILE *d);
+ == #endif
+ */
+static void
+print(m, caption, st, ch, d)
+struct match *m;
+char *caption;
+states st;
+int ch;
+FILE *d;
+{
+ register struct re_guts *g = m->g;
+ register int i;
+ register int first = 1;
+
+ if (!(m->eflags&REG_TRACE))
+ return;
+
+ fprintf(d, "%s", caption);
+ if (ch != '\0')
+ fprintf(d, " %s", pchar(ch));
+ for (i = 0; i < g->nstates; i++)
+ if (ISSET(st, i)) {
+ fprintf(d, "%s%d", (first) ? "\t" : ", ", i);
+ first = 0;
+ }
+ fprintf(d, "\n");
+}
+
+/*
+ - at - print current situation
+ == #ifdef REDEBUG
+ == static void at(struct match *m, char *title, char *start, char *stop, \
+ == sopno startst, sopno stopst);
+ == #endif
+ */
+static void
+at(m, title, start, stop, startst, stopst)
+struct match *m;
+char *title;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+{
+ if (!(m->eflags&REG_TRACE))
+ return;
+
+ printf("%s %s-", title, pchar(*start));
+ printf("%s ", pchar(*stop));
+ printf("%ld-%ld\n", (long)startst, (long)stopst);
+}
+
+#ifndef PCHARDONE
+#define PCHARDONE /* never again */
+/*
+ - pchar - make a character printable
+ == #ifdef REDEBUG
+ == static char *pchar(int ch);
+ == #endif
+ *
+ * Is this identical to regchar() over in debug.c? Well, yes. But a
+ * duplicate here avoids having a debugging-capable regexec.o tied to
+ * a matching debug.o, and this is convenient. It all disappears in
+ * the non-debug compilation anyway, so it doesn't matter much.
+ */
+static char * /* -> representation */
+pchar(ch)
+int ch;
+{
+ static char pbuf[10];
+
+ if (isprint((uch)ch) || ch == ' ')
+ sprintf(pbuf, "%c", ch);
+ else
+ sprintf(pbuf, "\\%o", ch);
+ return(pbuf);
+}
+#endif
+#endif
+
+#undef matcher
+#undef fast
+#undef slow
+#undef dissect
+#undef backref
+#undef step
+#undef print
+#undef at
+#undef match
diff --git a/lib/libc/regex/re_format.7 b/lib/libc/regex/re_format.7
new file mode 100644
index 0000000..1fcce4a
--- /dev/null
+++ b/lib/libc/regex/re_format.7
@@ -0,0 +1,273 @@
+.\" Copyright (c) 1992, 1993, 1994 Henry Spencer.
+.\" Copyright (c) 1992, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Henry Spencer.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)re_format.7 8.3 (Berkeley) 3/20/94
+.\" $FreeBSD$
+.\"
+.TH RE_FORMAT 7 "March 20, 1994"
+.SH NAME
+re_format \- POSIX 1003.2 regular expressions
+.SH DESCRIPTION
+Regular expressions (``RE''s),
+as defined in POSIX 1003.2, come in two forms:
+modern REs (roughly those of
+.IR egrep ;
+1003.2 calls these ``extended'' REs)
+and obsolete REs (roughly those of
+.IR ed ;
+1003.2 ``basic'' REs).
+Obsolete REs mostly exist for backward compatibility in some old programs;
+they will be discussed at the end.
+1003.2 leaves some aspects of RE syntax and semantics open;
+`\(dg' marks decisions on these aspects that
+may not be fully portable to other 1003.2 implementations.
+.PP
+A (modern) RE is one\(dg or more non-empty\(dg \fIbranches\fR,
+separated by `|'.
+It matches anything that matches one of the branches.
+.PP
+A branch is one\(dg or more \fIpieces\fR, concatenated.
+It matches a match for the first, followed by a match for the second, etc.
+.PP
+A piece is an \fIatom\fR possibly followed
+by a single\(dg `*', `+', `?', or \fIbound\fR.
+An atom followed by `*' matches a sequence of 0 or more matches of the atom.
+An atom followed by `+' matches a sequence of 1 or more matches of the atom.
+An atom followed by `?' matches a sequence of 0 or 1 matches of the atom.
+.PP
+A \fIbound\fR is `{' followed by an unsigned decimal integer,
+possibly followed by `,'
+possibly followed by another unsigned decimal integer,
+always followed by `}'.
+The integers must lie between 0 and RE_DUP_MAX (255\(dg) inclusive,
+and if there are two of them, the first may not exceed the second.
+An atom followed by a bound containing one integer \fIi\fR
+and no comma matches
+a sequence of exactly \fIi\fR matches of the atom.
+An atom followed by a bound
+containing one integer \fIi\fR and a comma matches
+a sequence of \fIi\fR or more matches of the atom.
+An atom followed by a bound
+containing two integers \fIi\fR and \fIj\fR matches
+a sequence of \fIi\fR through \fIj\fR (inclusive) matches of the atom.
+.PP
+An atom is a regular expression enclosed in `()' (matching a match for the
+regular expression),
+an empty set of `()' (matching the null string)\(dg,
+a \fIbracket expression\fR (see below), `.'
+(matching any single character), `^' (matching the null string at the
+beginning of a line), `$' (matching the null string at the
+end of a line), a `\e' followed by one of the characters
+`^.[$()|*+?{\e'
+(matching that character taken as an ordinary character),
+a `\e' followed by any other character\(dg
+(matching that character taken as an ordinary character,
+as if the `\e' had not been present\(dg),
+or a single character with no other significance (matching that character).
+A `{' followed by a character other than a digit is an ordinary
+character, not the beginning of a bound\(dg.
+It is illegal to end an RE with `\e'.
+.PP
+A \fIbracket expression\fR is a list of characters enclosed in `[]'.
+It normally matches any single character from the list (but see below).
+If the list begins with `^',
+it matches any single character
+(but see below) \fInot\fR from the rest of the list.
+If two characters in the list are separated by `\-', this is shorthand
+for the full \fIrange\fR of characters between those two (inclusive) in the
+collating sequence,
+e.g. `[0-9]' in ASCII matches any decimal digit.
+It is illegal\(dg for two ranges to share an
+endpoint, e.g. `a-c-e'.
+Ranges are very collating-sequence-dependent,
+and portable programs should avoid relying on them.
+.PP
+To include a literal `]' in the list, make it the first character
+(following a possible `^').
+To include a literal `\-', make it the first or last character,
+or the second endpoint of a range.
+To use a literal `\-' as the first endpoint of a range,
+enclose it in `[.' and `.]' to make it a collating element (see below).
+With the exception of these and some combinations using `[' (see next
+paragraphs), all other special characters, including `\e', lose their
+special significance within a bracket expression.
+.PP
+Within a bracket expression, a collating element (a character,
+a multi-character sequence that collates as if it were a single character,
+or a collating-sequence name for either)
+enclosed in `[.' and `.]' stands for the
+sequence of characters of that collating element.
+The sequence is a single element of the bracket expression's list.
+A bracket expression containing a multi-character collating element
+can thus match more than one character,
+e.g. if the collating sequence includes a `ch' collating element,
+then the RE `[[.ch.]]*c' matches the first five characters
+of `chchcc'.
+.PP
+Within a bracket expression, a collating element enclosed in `[=' and
+`=]' is an equivalence class, standing for the sequences of characters
+of all collating elements equivalent to that one, including itself.
+(If there are no other equivalent collating elements,
+the treatment is as if the enclosing delimiters were `[.' and `.]'.)
+For example, if o and \o'o^' are the members of an equivalence class,
+then `[[=o=]]', `[[=\o'o^'=]]', and `[o\o'o^']' are all synonymous.
+An equivalence class may not\(dg be an endpoint
+of a range.
+.PP
+Within a bracket expression, the name of a \fIcharacter class\fR enclosed
+in `[:' and `:]' stands for the list of all characters belonging to that
+class.
+Standard character class names are:
+.PP
+.RS
+.nf
+.ta 3c 6c 9c
+alnum digit punct
+alpha graph space
+blank lower upper
+cntrl print xdigit
+.fi
+.RE
+.PP
+These stand for the character classes defined in
+.IR ctype (3).
+A locale may provide others.
+A character class may not be used as an endpoint of a range.
+.PP
+There are two special cases\(dg of bracket expressions:
+the bracket expressions `[[:<:]]' and `[[:>:]]' match the null string at
+the beginning and end of a word respectively.
+A word is defined as a sequence of
+word characters
+which is neither preceded nor followed by
+word characters.
+A word character is an
+.I alnum
+character (as defined by
+.IR ctype (3))
+or an underscore.
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+.PP
+In the event that an RE could match more than one substring of a given
+string,
+the RE matches the one starting earliest in the string.
+If the RE could match more than one substring starting at that point,
+it matches the longest.
+Subexpressions also match the longest possible substrings, subject to
+the constraint that the whole match be as long as possible,
+with subexpressions starting earlier in the RE taking priority over
+ones starting later.
+Note that higher-level subexpressions thus take priority over
+their lower-level component subexpressions.
+.PP
+Match lengths are measured in characters, not collating elements.
+A null string is considered longer than no match at all.
+For example,
+`bb*' matches the three middle characters of `abbbc',
+`(wee|week)(knights|nights)' matches all ten characters of `weeknights',
+when `(.*).*' is matched against `abc' the parenthesized subexpression
+matches all three characters, and
+when `(a*)*' is matched against `bc' both the whole RE and the parenthesized
+subexpression match the null string.
+.PP
+If case-independent matching is specified,
+the effect is much as if all case distinctions had vanished from the
+alphabet.
+When an alphabetic that exists in multiple cases appears as an
+ordinary character outside a bracket expression, it is effectively
+transformed into a bracket expression containing both cases,
+e.g. `x' becomes `[xX]'.
+When it appears inside a bracket expression, all case counterparts
+of it are added to the bracket expression, so that (e.g.) `[x]'
+becomes `[xX]' and `[^x]' becomes `[^xX]'.
+.PP
+No particular limit is imposed on the length of REs\(dg.
+Programs intended to be portable should not employ REs longer
+than 256 bytes,
+as an implementation can refuse to accept such REs and remain
+POSIX-compliant.
+.PP
+Obsolete (``basic'') regular expressions differ in several respects.
+`|' is an ordinary character and there is no equivalent
+for its functionality.
+`+' and `?' are ordinary characters, and their functionality
+can be expressed using bounds (\&{1,\&} or \&{0,1\&} respectively).
+Also note that `x+' in modern REs is equivalent to `xx*'.
+The delimiters for bounds are `\e{' and `\e}',
+with `{' and `}' by themselves ordinary characters.
+The parentheses for nested subexpressions are `\e(' and `\e)',
+with `(' and `)' by themselves ordinary characters.
+`^' is an ordinary character except at the beginning of the
+RE or\(dg the beginning of a parenthesized subexpression,
+`$' is an ordinary character except at the end of the
+RE or\(dg the end of a parenthesized subexpression,
+and `*' is an ordinary character if it appears at the beginning of the
+RE or the beginning of a parenthesized subexpression
+(after a possible leading `^').
+Finally, there is one new type of atom, a \fIback reference\fR:
+`\e' followed by a non-zero decimal digit \fId\fR
+matches the same sequence of characters
+matched by the \fId\fRth parenthesized subexpression
+(numbering subexpressions by the positions of their opening parentheses,
+left to right),
+so that (e.g.) `\e([bc]\e)\e1' matches `bb' or `cc' but not `bc'.
+.SH SEE ALSO
+regex(3)
+.PP
+POSIX 1003.2, section 2.8 (Regular Expression Notation).
+.SH BUGS
+Having two kinds of REs is a botch.
+.PP
+The current 1003.2 spec says that `)' is an ordinary character in
+the absence of an unmatched `(';
+this was an unintentional result of a wording error,
+and change is likely.
+Avoid relying on it.
+.PP
+Back references are a dreadful botch,
+posing major problems for efficient implementations.
+They are also somewhat vaguely defined
+(does
+`a\e(\e(b\e)*\e2\e)*d' match `abbbd'?).
+Avoid using them.
+.PP
+1003.2's specification of case-independent matching is vague.
+The ``one case implies all cases'' definition given above
+is current consensus among implementors as to the right interpretation.
+.PP
+The syntax for word boundaries is incredibly ugly.
diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c
new file mode 100644
index 0000000..a4e9e1d
--- /dev/null
+++ b/lib/libc/regex/regcomp.c
@@ -0,0 +1,1777 @@
+/*-
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regcomp.c 8.5 (Berkeley) 3/20/94
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)regcomp.c 8.5 (Berkeley) 3/20/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <regex.h>
+
+#include "collate.h"
+
+#include "utils.h"
+#include "regex2.h"
+
+#include "cclass.h"
+#include "cname.h"
+
+/*
+ * parse structure, passed up and down to avoid global variables and
+ * other clumsinesses
+ */
+struct parse {
+ char *next; /* next character in RE */
+ char *end; /* end of string (-> NUL normally) */
+ int error; /* has an error been seen? */
+ sop *strip; /* malloced strip */
+ sopno ssize; /* malloced strip size (allocated) */
+ sopno slen; /* malloced strip length (used) */
+ int ncsalloc; /* number of csets allocated */
+ struct re_guts *g;
+# define NPAREN 10 /* we need to remember () 1-9 for back refs */
+ sopno pbegin[NPAREN]; /* -> ( ([0] unused) */
+ sopno pend[NPAREN]; /* -> ) ([0] unused) */
+};
+
+/* ========= begin header generated by ./mkh ========= */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* === regcomp.c === */
+static void p_ere __P((struct parse *p, int stop));
+static void p_ere_exp __P((struct parse *p));
+static void p_str __P((struct parse *p));
+static void p_bre __P((struct parse *p, int end1, int end2));
+static int p_simp_re __P((struct parse *p, int starordinary));
+static int p_count __P((struct parse *p));
+static void p_bracket __P((struct parse *p));
+static void p_b_term __P((struct parse *p, cset *cs));
+static void p_b_cclass __P((struct parse *p, cset *cs));
+static void p_b_eclass __P((struct parse *p, cset *cs));
+static char p_b_symbol __P((struct parse *p));
+static char p_b_coll_elem __P((struct parse *p, int endc));
+static char othercase __P((int ch));
+static void bothcases __P((struct parse *p, int ch));
+static void ordinary __P((struct parse *p, int ch));
+static void nonnewline __P((struct parse *p));
+static void repeat __P((struct parse *p, sopno start, int from, int to));
+static int seterr __P((struct parse *p, int e));
+static cset *allocset __P((struct parse *p));
+static void freeset __P((struct parse *p, cset *cs));
+static int freezeset __P((struct parse *p, cset *cs));
+static int firstch __P((struct parse *p, cset *cs));
+static int nch __P((struct parse *p, cset *cs));
+static void mcadd __P((struct parse *p, cset *cs, char *cp));
+#if used
+static void mcsub __P((cset *cs, char *cp));
+static int mcin __P((cset *cs, char *cp));
+static char *mcfind __P((cset *cs, char *cp));
+#endif
+static void mcinvert __P((struct parse *p, cset *cs));
+static void mccase __P((struct parse *p, cset *cs));
+static int isinsets __P((struct re_guts *g, int c));
+static int samesets __P((struct re_guts *g, int c1, int c2));
+static void categorize __P((struct parse *p, struct re_guts *g));
+static sopno dupl __P((struct parse *p, sopno start, sopno finish));
+static void doemit __P((struct parse *p, sop op, size_t opnd));
+static void doinsert __P((struct parse *p, sop op, size_t opnd, sopno pos));
+static void dofwd __P((struct parse *p, sopno pos, sop value));
+static void enlarge __P((struct parse *p, sopno size));
+static void stripsnug __P((struct parse *p, struct re_guts *g));
+static void findmust __P((struct parse *p, struct re_guts *g));
+static sopno pluscount __P((struct parse *p, struct re_guts *g));
+
+#ifdef __cplusplus
+}
+#endif
+/* ========= end header generated by ./mkh ========= */
+
+static char nuls[10]; /* place to point scanner in event of error */
+
+/*
+ * macros for use with parse structure
+ * BEWARE: these know that the parse structure is named `p' !!!
+ */
+#define PEEK() (*p->next)
+#define PEEK2() (*(p->next+1))
+#define MORE() (p->next < p->end)
+#define MORE2() (p->next+1 < p->end)
+#define SEE(c) (MORE() && PEEK() == (c))
+#define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b))
+#define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0)
+#define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0)
+#define NEXT() (p->next++)
+#define NEXT2() (p->next += 2)
+#define NEXTn(n) (p->next += (n))
+#define GETNEXT() (*p->next++)
+#define SETERROR(e) seterr(p, (e))
+#define REQUIRE(co, e) ((co) || SETERROR(e))
+#define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e))
+#define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e))
+#define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e))
+#define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd))
+#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos)
+#define AHEAD(pos) dofwd(p, pos, HERE()-(pos))
+#define ASTERN(sop, pos) EMIT(sop, HERE()-pos)
+#define HERE() (p->slen)
+#define THERE() (p->slen - 1)
+#define THERETHERE() (p->slen - 2)
+#define DROP(n) (p->slen -= (n))
+
+#ifndef NDEBUG
+static int never = 0; /* for use in asserts; shuts lint up */
+#else
+#define never 0 /* some <assert.h>s have bugs too */
+#endif
+
+/*
+ - regcomp - interface for parser and compilation
+ = extern int regcomp(regex_t *, const char *, int);
+ = #define REG_BASIC 0000
+ = #define REG_EXTENDED 0001
+ = #define REG_ICASE 0002
+ = #define REG_NOSUB 0004
+ = #define REG_NEWLINE 0010
+ = #define REG_NOSPEC 0020
+ = #define REG_PEND 0040
+ = #define REG_DUMP 0200
+ */
+int /* 0 success, otherwise REG_something */
+regcomp(preg, pattern, cflags)
+regex_t *preg;
+const char *pattern;
+int cflags;
+{
+ struct parse pa;
+ register struct re_guts *g;
+ register struct parse *p = &pa;
+ register int i;
+ register size_t len;
+#ifdef REDEBUG
+# define GOODFLAGS(f) (f)
+#else
+# define GOODFLAGS(f) ((f)&~REG_DUMP)
+#endif
+
+ cflags = GOODFLAGS(cflags);
+ if ((cflags&REG_EXTENDED) && (cflags&REG_NOSPEC))
+ return(REG_INVARG);
+
+ if (cflags&REG_PEND) {
+ if (preg->re_endp < pattern)
+ return(REG_INVARG);
+ len = preg->re_endp - pattern;
+ } else
+ len = strlen((char *)pattern);
+
+ /* do the mallocs early so failure handling is easy */
+ g = (struct re_guts *)malloc(sizeof(struct re_guts) +
+ (NC-1)*sizeof(cat_t));
+ if (g == NULL)
+ return(REG_ESPACE);
+ p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
+ p->strip = (sop *)malloc(p->ssize * sizeof(sop));
+ p->slen = 0;
+ if (p->strip == NULL) {
+ free((char *)g);
+ return(REG_ESPACE);
+ }
+
+ /* set things up */
+ p->g = g;
+ p->next = (char *)pattern; /* convenience; we do not modify it */
+ p->end = p->next + len;
+ p->error = 0;
+ p->ncsalloc = 0;
+ for (i = 0; i < NPAREN; i++) {
+ p->pbegin[i] = 0;
+ p->pend[i] = 0;
+ }
+ g->csetsize = NC;
+ g->sets = NULL;
+ g->setbits = NULL;
+ g->ncsets = 0;
+ g->cflags = cflags;
+ g->iflags = 0;
+ g->nbol = 0;
+ g->neol = 0;
+ g->must = NULL;
+ g->mlen = 0;
+ g->nsub = 0;
+ g->ncategories = 1; /* category 0 is "everything else" */
+ g->categories = &g->catspace[-(CHAR_MIN)];
+ (void) memset((char *)g->catspace, 0, NC*sizeof(cat_t));
+ g->backrefs = 0;
+
+ /* do it */
+ EMIT(OEND, 0);
+ g->firststate = THERE();
+ if (cflags&REG_EXTENDED)
+ p_ere(p, OUT);
+ else if (cflags&REG_NOSPEC)
+ p_str(p);
+ else
+ p_bre(p, OUT, OUT);
+ EMIT(OEND, 0);
+ g->laststate = THERE();
+
+ /* tidy up loose ends and fill things in */
+ categorize(p, g);
+ stripsnug(p, g);
+ findmust(p, g);
+ g->nplus = pluscount(p, g);
+ g->magic = MAGIC2;
+ preg->re_nsub = g->nsub;
+ preg->re_g = g;
+ preg->re_magic = MAGIC1;
+#ifndef REDEBUG
+ /* not debugging, so can't rely on the assert() in regexec() */
+ if (g->iflags&BAD)
+ SETERROR(REG_ASSERT);
+#endif
+
+ /* win or lose, we're done */
+ if (p->error != 0) /* lose */
+ regfree(preg);
+ return(p->error);
+}
+
+/*
+ - p_ere - ERE parser top level, concatenation and alternation
+ == static void p_ere(register struct parse *p, int stop);
+ */
+static void
+p_ere(p, stop)
+register struct parse *p;
+int stop; /* character this ERE should end at */
+{
+ register char c;
+ register sopno prevback;
+ register sopno prevfwd;
+ register sopno conc;
+ register int first = 1; /* is this the first alternative? */
+
+ for (;;) {
+ /* do a bunch of concatenated expressions */
+ conc = HERE();
+ while (MORE() && (c = PEEK()) != '|' && c != stop)
+ p_ere_exp(p);
+ (void)REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */
+
+ if (!EAT('|'))
+ break; /* NOTE BREAK OUT */
+
+ if (first) {
+ INSERT(OCH_, conc); /* offset is wrong */
+ prevfwd = conc;
+ prevback = conc;
+ first = 0;
+ }
+ ASTERN(OOR1, prevback);
+ prevback = THERE();
+ AHEAD(prevfwd); /* fix previous offset */
+ prevfwd = HERE();
+ EMIT(OOR2, 0); /* offset is very wrong */
+ }
+
+ if (!first) { /* tail-end fixups */
+ AHEAD(prevfwd);
+ ASTERN(O_CH, prevback);
+ }
+
+ assert(!MORE() || SEE(stop));
+}
+
+/*
+ - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
+ == static void p_ere_exp(register struct parse *p);
+ */
+static void
+p_ere_exp(p)
+register struct parse *p;
+{
+ register char c;
+ register sopno pos;
+ register int count;
+ register int count2;
+ register sopno subno;
+ int wascaret = 0;
+
+ assert(MORE()); /* caller should have ensured this */
+ c = GETNEXT();
+
+ pos = HERE();
+ switch (c) {
+ case '(':
+ (void)REQUIRE(MORE(), REG_EPAREN);
+ p->g->nsub++;
+ subno = p->g->nsub;
+ if (subno < NPAREN)
+ p->pbegin[subno] = HERE();
+ EMIT(OLPAREN, subno);
+ if (!SEE(')'))
+ p_ere(p, ')');
+ if (subno < NPAREN) {
+ p->pend[subno] = HERE();
+ assert(p->pend[subno] != 0);
+ }
+ EMIT(ORPAREN, subno);
+ (void)MUSTEAT(')', REG_EPAREN);
+ break;
+#ifndef POSIX_MISTAKE
+ case ')': /* happens only if no current unmatched ( */
+ /*
+ * You may ask, why the ifndef? Because I didn't notice
+ * this until slightly too late for 1003.2, and none of the
+ * other 1003.2 regular-expression reviewers noticed it at
+ * all. So an unmatched ) is legal POSIX, at least until
+ * we can get it fixed.
+ */
+ SETERROR(REG_EPAREN);
+ break;
+#endif
+ case '^':
+ EMIT(OBOL, 0);
+ p->g->iflags |= USEBOL;
+ p->g->nbol++;
+ wascaret = 1;
+ break;
+ case '$':
+ EMIT(OEOL, 0);
+ p->g->iflags |= USEEOL;
+ p->g->neol++;
+ break;
+ case '|':
+ SETERROR(REG_EMPTY);
+ break;
+ case '*':
+ case '+':
+ case '?':
+ SETERROR(REG_BADRPT);
+ break;
+ case '.':
+ if (p->g->cflags&REG_NEWLINE)
+ nonnewline(p);
+ else
+ EMIT(OANY, 0);
+ break;
+ case '[':
+ p_bracket(p);
+ break;
+ case '\\':
+ (void)REQUIRE(MORE(), REG_EESCAPE);
+ c = GETNEXT();
+ ordinary(p, c);
+ break;
+ case '{': /* okay as ordinary except if digit follows */
+ (void)REQUIRE(!MORE() || !isdigit((uch)PEEK()), REG_BADRPT);
+ /* FALLTHROUGH */
+ default:
+ ordinary(p, c);
+ break;
+ }
+
+ if (!MORE())
+ return;
+ c = PEEK();
+ /* we call { a repetition if followed by a digit */
+ if (!( c == '*' || c == '+' || c == '?' ||
+ (c == '{' && MORE2() && isdigit((uch)PEEK2())) ))
+ return; /* no repetition, we're done */
+ NEXT();
+
+ (void)REQUIRE(!wascaret, REG_BADRPT);
+ switch (c) {
+ case '*': /* implemented as +? */
+ /* this case does not require the (y|) trick, noKLUDGE */
+ INSERT(OPLUS_, pos);
+ ASTERN(O_PLUS, pos);
+ INSERT(OQUEST_, pos);
+ ASTERN(O_QUEST, pos);
+ break;
+ case '+':
+ INSERT(OPLUS_, pos);
+ ASTERN(O_PLUS, pos);
+ break;
+ case '?':
+ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
+ INSERT(OCH_, pos); /* offset slightly wrong */
+ ASTERN(OOR1, pos); /* this one's right */
+ AHEAD(pos); /* fix the OCH_ */
+ EMIT(OOR2, 0); /* offset very wrong... */
+ AHEAD(THERE()); /* ...so fix it */
+ ASTERN(O_CH, THERETHERE());
+ break;
+ case '{':
+ count = p_count(p);
+ if (EAT(',')) {
+ if (isdigit((uch)PEEK())) {
+ count2 = p_count(p);
+ (void)REQUIRE(count <= count2, REG_BADBR);
+ } else /* single number with comma */
+ count2 = INFINITY;
+ } else /* just a single number */
+ count2 = count;
+ repeat(p, pos, count, count2);
+ if (!EAT('}')) { /* error heuristics */
+ while (MORE() && PEEK() != '}')
+ NEXT();
+ (void)REQUIRE(MORE(), REG_EBRACE);
+ SETERROR(REG_BADBR);
+ }
+ break;
+ }
+
+ if (!MORE())
+ return;
+ c = PEEK();
+ if (!( c == '*' || c == '+' || c == '?' ||
+ (c == '{' && MORE2() && isdigit((uch)PEEK2())) ) )
+ return;
+ SETERROR(REG_BADRPT);
+}
+
+/*
+ - p_str - string (no metacharacters) "parser"
+ == static void p_str(register struct parse *p);
+ */
+static void
+p_str(p)
+register struct parse *p;
+{
+ (void)REQUIRE(MORE(), REG_EMPTY);
+ while (MORE())
+ ordinary(p, GETNEXT());
+}
+
+/*
+ - p_bre - BRE parser top level, anchoring and concatenation
+ == static void p_bre(register struct parse *p, register int end1, \
+ == register int end2);
+ * Giving end1 as OUT essentially eliminates the end1/end2 check.
+ *
+ * This implementation is a bit of a kludge, in that a trailing $ is first
+ * taken as an ordinary character and then revised to be an anchor. The
+ * only undesirable side effect is that '$' gets included as a character
+ * category in such cases. This is fairly harmless; not worth fixing.
+ * The amount of lookahead needed to avoid this kludge is excessive.
+ */
+static void
+p_bre(p, end1, end2)
+register struct parse *p;
+register int end1; /* first terminating character */
+register int end2; /* second terminating character */
+{
+ register sopno start = HERE();
+ register int first = 1; /* first subexpression? */
+ register int wasdollar = 0;
+
+ if (EAT('^')) {
+ EMIT(OBOL, 0);
+ p->g->iflags |= USEBOL;
+ p->g->nbol++;
+ }
+ while (MORE() && !SEETWO(end1, end2)) {
+ wasdollar = p_simp_re(p, first);
+ first = 0;
+ }
+ if (wasdollar) { /* oops, that was a trailing anchor */
+ DROP(1);
+ EMIT(OEOL, 0);
+ p->g->iflags |= USEEOL;
+ p->g->neol++;
+ }
+
+ (void)REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */
+}
+
+/*
+ - p_simp_re - parse a simple RE, an atom possibly followed by a repetition
+ == static int p_simp_re(register struct parse *p, int starordinary);
+ */
+static int /* was the simple RE an unbackslashed $? */
+p_simp_re(p, starordinary)
+register struct parse *p;
+int starordinary; /* is a leading * an ordinary character? */
+{
+ register int c;
+ register int count;
+ register int count2;
+ register sopno pos;
+ register int i;
+ register sopno subno;
+# define BACKSL (1<<CHAR_BIT)
+
+ pos = HERE(); /* repetion op, if any, covers from here */
+
+ assert(MORE()); /* caller should have ensured this */
+ c = GETNEXT();
+ if (c == '\\') {
+ (void)REQUIRE(MORE(), REG_EESCAPE);
+ c = BACKSL | GETNEXT();
+ }
+ switch (c) {
+ case '.':
+ if (p->g->cflags&REG_NEWLINE)
+ nonnewline(p);
+ else
+ EMIT(OANY, 0);
+ break;
+ case '[':
+ p_bracket(p);
+ break;
+ case BACKSL|'{':
+ SETERROR(REG_BADRPT);
+ break;
+ case BACKSL|'(':
+ p->g->nsub++;
+ subno = p->g->nsub;
+ if (subno < NPAREN)
+ p->pbegin[subno] = HERE();
+ EMIT(OLPAREN, subno);
+ /* the MORE here is an error heuristic */
+ if (MORE() && !SEETWO('\\', ')'))
+ p_bre(p, '\\', ')');
+ if (subno < NPAREN) {
+ p->pend[subno] = HERE();
+ assert(p->pend[subno] != 0);
+ }
+ EMIT(ORPAREN, subno);
+ (void)REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
+ break;
+ case BACKSL|')': /* should not get here -- must be user */
+ case BACKSL|'}':
+ SETERROR(REG_EPAREN);
+ break;
+ case BACKSL|'1':
+ case BACKSL|'2':
+ case BACKSL|'3':
+ case BACKSL|'4':
+ case BACKSL|'5':
+ case BACKSL|'6':
+ case BACKSL|'7':
+ case BACKSL|'8':
+ case BACKSL|'9':
+ i = (c&~BACKSL) - '0';
+ assert(i < NPAREN);
+ if (p->pend[i] != 0) {
+ assert(i <= p->g->nsub);
+ EMIT(OBACK_, i);
+ assert(p->pbegin[i] != 0);
+ assert(OP(p->strip[p->pbegin[i]]) == OLPAREN);
+ assert(OP(p->strip[p->pend[i]]) == ORPAREN);
+ (void) dupl(p, p->pbegin[i]+1, p->pend[i]);
+ EMIT(O_BACK, i);
+ } else
+ SETERROR(REG_ESUBREG);
+ p->g->backrefs = 1;
+ break;
+ case '*':
+ (void)REQUIRE(starordinary, REG_BADRPT);
+ /* FALLTHROUGH */
+ default:
+ ordinary(p, (char)c);
+ break;
+ }
+
+ if (EAT('*')) { /* implemented as +? */
+ /* this case does not require the (y|) trick, noKLUDGE */
+ INSERT(OPLUS_, pos);
+ ASTERN(O_PLUS, pos);
+ INSERT(OQUEST_, pos);
+ ASTERN(O_QUEST, pos);
+ } else if (EATTWO('\\', '{')) {
+ count = p_count(p);
+ if (EAT(',')) {
+ if (MORE() && isdigit((uch)PEEK())) {
+ count2 = p_count(p);
+ (void)REQUIRE(count <= count2, REG_BADBR);
+ } else /* single number with comma */
+ count2 = INFINITY;
+ } else /* just a single number */
+ count2 = count;
+ repeat(p, pos, count, count2);
+ if (!EATTWO('\\', '}')) { /* error heuristics */
+ while (MORE() && !SEETWO('\\', '}'))
+ NEXT();
+ (void)REQUIRE(MORE(), REG_EBRACE);
+ SETERROR(REG_BADBR);
+ }
+ } else if (c == '$') /* $ (but not \$) ends it */
+ return(1);
+
+ return(0);
+}
+
+/*
+ - p_count - parse a repetition count
+ == static int p_count(register struct parse *p);
+ */
+static int /* the value */
+p_count(p)
+register struct parse *p;
+{
+ register int count = 0;
+ register int ndigits = 0;
+
+ while (MORE() && isdigit((uch)PEEK()) && count <= DUPMAX) {
+ count = count*10 + (GETNEXT() - '0');
+ ndigits++;
+ }
+
+ (void)REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
+ return(count);
+}
+
+/*
+ - p_bracket - parse a bracketed character list
+ == static void p_bracket(register struct parse *p);
+ *
+ * Note a significant property of this code: if the allocset() did SETERROR,
+ * no set operations are done.
+ */
+static void
+p_bracket(p)
+register struct parse *p;
+{
+ register cset *cs = allocset(p);
+ register int invert = 0;
+
+ /* Dept of Truly Sickening Special-Case Kludges */
+ if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) {
+ EMIT(OBOW, 0);
+ NEXTn(6);
+ return;
+ }
+ if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) {
+ EMIT(OEOW, 0);
+ NEXTn(6);
+ return;
+ }
+
+ if (EAT('^'))
+ invert++; /* make note to invert set at end */
+ if (EAT(']'))
+ CHadd(cs, ']');
+ else if (EAT('-'))
+ CHadd(cs, '-');
+ while (MORE() && PEEK() != ']' && !SEETWO('-', ']'))
+ p_b_term(p, cs);
+ if (EAT('-'))
+ CHadd(cs, '-');
+ (void)MUSTEAT(']', REG_EBRACK);
+
+ if (p->error != 0) /* don't mess things up further */
+ return;
+
+ if (p->g->cflags&REG_ICASE) {
+ register int i;
+ register int ci;
+
+ for (i = p->g->csetsize - 1; i >= 0; i--)
+ if (CHIN(cs, i) && isalpha(i)) {
+ ci = othercase(i);
+ if (ci != i)
+ CHadd(cs, ci);
+ }
+ if (cs->multis != NULL)
+ mccase(p, cs);
+ }
+ if (invert) {
+ register int i;
+
+ for (i = p->g->csetsize - 1; i >= 0; i--)
+ if (CHIN(cs, i))
+ CHsub(cs, i);
+ else
+ CHadd(cs, i);
+ if (p->g->cflags&REG_NEWLINE)
+ CHsub(cs, '\n');
+ if (cs->multis != NULL)
+ mcinvert(p, cs);
+ }
+
+ assert(cs->multis == NULL); /* xxx */
+
+ if (nch(p, cs) == 1) { /* optimize singleton sets */
+ ordinary(p, firstch(p, cs));
+ freeset(p, cs);
+ } else
+ EMIT(OANYOF, freezeset(p, cs));
+}
+
+/*
+ - p_b_term - parse one term of a bracketed character list
+ == static void p_b_term(register struct parse *p, register cset *cs);
+ */
+static void
+p_b_term(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register char c;
+ register char start, finish;
+ register int i;
+
+ /* classify what we've got */
+ switch ((MORE()) ? PEEK() : '\0') {
+ case '[':
+ c = (MORE2()) ? PEEK2() : '\0';
+ break;
+ case '-':
+ SETERROR(REG_ERANGE);
+ return; /* NOTE RETURN */
+ break;
+ default:
+ c = '\0';
+ break;
+ }
+
+ switch (c) {
+ case ':': /* character class */
+ NEXT2();
+ (void)REQUIRE(MORE(), REG_EBRACK);
+ c = PEEK();
+ (void)REQUIRE(c != '-' && c != ']', REG_ECTYPE);
+ p_b_cclass(p, cs);
+ (void)REQUIRE(MORE(), REG_EBRACK);
+ (void)REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
+ break;
+ case '=': /* equivalence class */
+ NEXT2();
+ (void)REQUIRE(MORE(), REG_EBRACK);
+ c = PEEK();
+ (void)REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
+ p_b_eclass(p, cs);
+ (void)REQUIRE(MORE(), REG_EBRACK);
+ (void)REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
+ break;
+ default: /* symbol, ordinary character, or range */
+/* xxx revision needed for multichar stuff */
+ start = p_b_symbol(p);
+ if (SEE('-') && MORE2() && PEEK2() != ']') {
+ /* range */
+ NEXT();
+ if (EAT('-'))
+ finish = '-';
+ else
+ finish = p_b_symbol(p);
+ } else
+ finish = start;
+ if (start == finish)
+ CHadd(cs, start);
+ else {
+ if (__collate_load_error) {
+ (void)REQUIRE((uch)start <= (uch)finish, REG_ERANGE);
+ for (i = (uch)start; i <= (uch)finish; i++)
+ CHadd(cs, i);
+ } else {
+ (void)REQUIRE(__collate_range_cmp(start, finish) <= 0, REG_ERANGE);
+ for (i = CHAR_MIN; i <= CHAR_MAX; i++) {
+ if ( __collate_range_cmp(start, i) <= 0
+ && __collate_range_cmp(i, finish) <= 0
+ )
+ CHadd(cs, i);
+ }
+ }
+ }
+ break;
+ }
+}
+
+/*
+ - p_b_cclass - parse a character-class name and deal with it
+ == static void p_b_cclass(register struct parse *p, register cset *cs);
+ */
+static void
+p_b_cclass(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register int c;
+ register char *sp = p->next;
+ register struct cclass *cp;
+ register size_t len;
+
+ while (MORE() && isalpha((uch)PEEK()))
+ NEXT();
+ len = p->next - sp;
+ for (cp = cclasses; cp->name != NULL; cp++)
+ if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
+ break;
+ if (cp->name == NULL) {
+ /* oops, didn't find it */
+ SETERROR(REG_ECTYPE);
+ return;
+ }
+
+ switch (cp->fidx) {
+ case CALNUM:
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (isalnum((uch)c))
+ CHadd(cs, c);
+ break;
+ case CALPHA:
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (isalpha((uch)c))
+ CHadd(cs, c);
+ break;
+ case CBLANK:
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (isblank((uch)c))
+ CHadd(cs, c);
+ break;
+ case CCNTRL:
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (iscntrl((uch)c))
+ CHadd(cs, c);
+ break;
+ case CDIGIT:
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (isdigit((uch)c))
+ CHadd(cs, c);
+ break;
+ case CGRAPH:
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (isgraph((uch)c))
+ CHadd(cs, c);
+ break;
+ case CLOWER:
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (islower((uch)c))
+ CHadd(cs, c);
+ break;
+ case CPRINT:
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (isprint((uch)c))
+ CHadd(cs, c);
+ break;
+ case CPUNCT:
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (ispunct((uch)c))
+ CHadd(cs, c);
+ break;
+ case CSPACE:
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (isspace((uch)c))
+ CHadd(cs, c);
+ break;
+ case CUPPER:
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (isupper((uch)c))
+ CHadd(cs, c);
+ break;
+ case CXDIGIT:
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (isxdigit((uch)c))
+ CHadd(cs, c);
+ break;
+ }
+#if 0
+ for (u = cp->multis; *u != '\0'; u += strlen(u) + 1)
+ MCadd(p, cs, u);
+#endif
+}
+
+/*
+ - p_b_eclass - parse an equivalence-class name and deal with it
+ == static void p_b_eclass(register struct parse *p, register cset *cs);
+ *
+ * This implementation is incomplete. xxx
+ */
+static void
+p_b_eclass(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register char c;
+
+ c = p_b_coll_elem(p, '=');
+ CHadd(cs, c);
+}
+
+/*
+ - p_b_symbol - parse a character or [..]ed multicharacter collating symbol
+ == static char p_b_symbol(register struct parse *p);
+ */
+static char /* value of symbol */
+p_b_symbol(p)
+register struct parse *p;
+{
+ register char value;
+
+ (void)REQUIRE(MORE(), REG_EBRACK);
+ if (!EATTWO('[', '.'))
+ return(GETNEXT());
+
+ /* collating symbol */
+ value = p_b_coll_elem(p, '.');
+ (void)REQUIRE(EATTWO('.', ']'), REG_ECOLLATE);
+ return(value);
+}
+
+/*
+ - p_b_coll_elem - parse a collating-element name and look it up
+ == static char p_b_coll_elem(register struct parse *p, int endc);
+ */
+static char /* value of collating element */
+p_b_coll_elem(p, endc)
+register struct parse *p;
+int endc; /* name ended by endc,']' */
+{
+ register char *sp = p->next;
+ register struct cname *cp;
+ register int len;
+
+ while (MORE() && !SEETWO(endc, ']'))
+ NEXT();
+ if (!MORE()) {
+ SETERROR(REG_EBRACK);
+ return(0);
+ }
+ len = p->next - sp;
+ for (cp = cnames; cp->name != NULL; cp++)
+ if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
+ return(cp->code); /* known name */
+ if (len == 1)
+ return(*sp); /* single character */
+ SETERROR(REG_ECOLLATE); /* neither */
+ return(0);
+}
+
+/*
+ - othercase - return the case counterpart of an alphabetic
+ == static char othercase(int ch);
+ */
+static char /* if no counterpart, return ch */
+othercase(ch)
+int ch;
+{
+ ch = (uch)ch;
+ assert(isalpha(ch));
+ if (isupper(ch))
+ return(tolower(ch));
+ else if (islower(ch))
+ return(toupper(ch));
+ else /* peculiar, but could happen */
+ return(ch);
+}
+
+/*
+ - bothcases - emit a dualcase version of a two-case character
+ == static void bothcases(register struct parse *p, int ch);
+ *
+ * Boy, is this implementation ever a kludge...
+ */
+static void
+bothcases(p, ch)
+register struct parse *p;
+int ch;
+{
+ register char *oldnext = p->next;
+ register char *oldend = p->end;
+ char bracket[3];
+
+ ch = (uch)ch;
+ assert(othercase(ch) != ch); /* p_bracket() would recurse */
+ p->next = bracket;
+ p->end = bracket+2;
+ bracket[0] = ch;
+ bracket[1] = ']';
+ bracket[2] = '\0';
+ p_bracket(p);
+ assert(p->next == bracket+2);
+ p->next = oldnext;
+ p->end = oldend;
+}
+
+/*
+ - ordinary - emit an ordinary character
+ == static void ordinary(register struct parse *p, register int ch);
+ */
+static void
+ordinary(p, ch)
+register struct parse *p;
+register int ch;
+{
+ register cat_t *cap = p->g->categories;
+
+ if ((p->g->cflags&REG_ICASE) && isalpha((uch)ch) && othercase(ch) != ch)
+ bothcases(p, ch);
+ else {
+ EMIT(OCHAR, (uch)ch);
+ if (cap[ch] == 0)
+ cap[ch] = p->g->ncategories++;
+ }
+}
+
+/*
+ - nonnewline - emit REG_NEWLINE version of OANY
+ == static void nonnewline(register struct parse *p);
+ *
+ * Boy, is this implementation ever a kludge...
+ */
+static void
+nonnewline(p)
+register struct parse *p;
+{
+ register char *oldnext = p->next;
+ register char *oldend = p->end;
+ char bracket[4];
+
+ p->next = bracket;
+ p->end = bracket+3;
+ bracket[0] = '^';
+ bracket[1] = '\n';
+ bracket[2] = ']';
+ bracket[3] = '\0';
+ p_bracket(p);
+ assert(p->next == bracket+3);
+ p->next = oldnext;
+ p->end = oldend;
+}
+
+/*
+ - repeat - generate code for a bounded repetition, recursively if needed
+ == static void repeat(register struct parse *p, sopno start, int from, int to);
+ */
+static void
+repeat(p, start, from, to)
+register struct parse *p;
+sopno start; /* operand from here to end of strip */
+int from; /* repeated from this number */
+int to; /* to this number of times (maybe INFINITY) */
+{
+ register sopno finish = HERE();
+# define N 2
+# define INF 3
+# define REP(f, t) ((f)*8 + (t))
+# define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
+ register sopno copy;
+
+ if (p->error != 0) /* head off possible runaway recursion */
+ return;
+
+ assert(from <= to);
+
+ switch (REP(MAP(from), MAP(to))) {
+ case REP(0, 0): /* must be user doing this */
+ DROP(finish-start); /* drop the operand */
+ break;
+ case REP(0, 1): /* as x{1,1}? */
+ case REP(0, N): /* as x{1,n}? */
+ case REP(0, INF): /* as x{1,}? */
+ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
+ INSERT(OCH_, start); /* offset is wrong... */
+ repeat(p, start+1, 1, to);
+ ASTERN(OOR1, start);
+ AHEAD(start); /* ... fix it */
+ EMIT(OOR2, 0);
+ AHEAD(THERE());
+ ASTERN(O_CH, THERETHERE());
+ break;
+ case REP(1, 1): /* trivial case */
+ /* done */
+ break;
+ case REP(1, N): /* as x?x{1,n-1} */
+ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
+ INSERT(OCH_, start);
+ ASTERN(OOR1, start);
+ AHEAD(start);
+ EMIT(OOR2, 0); /* offset very wrong... */
+ AHEAD(THERE()); /* ...so fix it */
+ ASTERN(O_CH, THERETHERE());
+ copy = dupl(p, start+1, finish+1);
+ assert(copy == finish+4);
+ repeat(p, copy, 1, to-1);
+ break;
+ case REP(1, INF): /* as x+ */
+ INSERT(OPLUS_, start);
+ ASTERN(O_PLUS, start);
+ break;
+ case REP(N, N): /* as xx{m-1,n-1} */
+ copy = dupl(p, start, finish);
+ repeat(p, copy, from-1, to-1);
+ break;
+ case REP(N, INF): /* as xx{n-1,INF} */
+ copy = dupl(p, start, finish);
+ repeat(p, copy, from-1, to);
+ break;
+ default: /* "can't happen" */
+ SETERROR(REG_ASSERT); /* just in case */
+ break;
+ }
+}
+
+/*
+ - seterr - set an error condition
+ == static int seterr(register struct parse *p, int e);
+ */
+static int /* useless but makes type checking happy */
+seterr(p, e)
+register struct parse *p;
+int e;
+{
+ if (p->error == 0) /* keep earliest error condition */
+ p->error = e;
+ p->next = nuls; /* try to bring things to a halt */
+ p->end = nuls;
+ return(0); /* make the return value well-defined */
+}
+
+/*
+ - allocset - allocate a set of characters for []
+ == static cset *allocset(register struct parse *p);
+ */
+static cset *
+allocset(p)
+register struct parse *p;
+{
+ register int no = p->g->ncsets++;
+ register size_t nc;
+ register size_t nbytes;
+ register cset *cs;
+ register size_t css = (size_t)p->g->csetsize;
+ register int i;
+
+ if (no >= p->ncsalloc) { /* need another column of space */
+ p->ncsalloc += CHAR_BIT;
+ nc = p->ncsalloc;
+ assert(nc % CHAR_BIT == 0);
+ nbytes = nc / CHAR_BIT * css;
+ if (p->g->sets == NULL)
+ p->g->sets = (cset *)malloc(nc * sizeof(cset));
+ else
+ p->g->sets = (cset *)reallocf((char *)p->g->sets,
+ nc * sizeof(cset));
+ if (p->g->setbits == NULL)
+ p->g->setbits = (uch *)malloc(nbytes);
+ else {
+ p->g->setbits = (uch *)reallocf((char *)p->g->setbits,
+ nbytes);
+ /* xxx this isn't right if setbits is now NULL */
+ for (i = 0; i < no; i++)
+ p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT);
+ }
+ if (p->g->sets != NULL && p->g->setbits != NULL)
+ (void) memset((char *)p->g->setbits + (nbytes - css),
+ 0, css);
+ else {
+ no = 0;
+ SETERROR(REG_ESPACE);
+ /* caller's responsibility not to do set ops */
+ }
+ }
+
+ assert(p->g->sets != NULL); /* xxx */
+ cs = &p->g->sets[no];
+ cs->ptr = p->g->setbits + css*((no)/CHAR_BIT);
+ cs->mask = 1 << ((no) % CHAR_BIT);
+ cs->hash = 0;
+ cs->smultis = 0;
+ cs->multis = NULL;
+
+ return(cs);
+}
+
+/*
+ - freeset - free a now-unused set
+ == static void freeset(register struct parse *p, register cset *cs);
+ */
+static void
+freeset(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register int i;
+ register cset *top = &p->g->sets[p->g->ncsets];
+ register size_t css = (size_t)p->g->csetsize;
+
+ for (i = 0; i < css; i++)
+ CHsub(cs, i);
+ if (cs == top-1) /* recover only the easy case */
+ p->g->ncsets--;
+}
+
+/*
+ - freezeset - final processing on a set of characters
+ == static int freezeset(register struct parse *p, register cset *cs);
+ *
+ * The main task here is merging identical sets. This is usually a waste
+ * of time (although the hash code minimizes the overhead), but can win
+ * big if REG_ICASE is being used. REG_ICASE, by the way, is why the hash
+ * is done using addition rather than xor -- all ASCII [aA] sets xor to
+ * the same value!
+ */
+static int /* set number */
+freezeset(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register short h = cs->hash;
+ register int i;
+ register cset *top = &p->g->sets[p->g->ncsets];
+ register cset *cs2;
+ register size_t css = (size_t)p->g->csetsize;
+
+ /* look for an earlier one which is the same */
+ for (cs2 = &p->g->sets[0]; cs2 < top; cs2++)
+ if (cs2->hash == h && cs2 != cs) {
+ /* maybe */
+ for (i = 0; i < css; i++)
+ if (!!CHIN(cs2, i) != !!CHIN(cs, i))
+ break; /* no */
+ if (i == css)
+ break; /* yes */
+ }
+
+ if (cs2 < top) { /* found one */
+ freeset(p, cs);
+ cs = cs2;
+ }
+
+ return((int)(cs - p->g->sets));
+}
+
+/*
+ - firstch - return first character in a set (which must have at least one)
+ == static int firstch(register struct parse *p, register cset *cs);
+ */
+static int /* character; there is no "none" value */
+firstch(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register int i;
+ register size_t css = (size_t)p->g->csetsize;
+
+ for (i = 0; i < css; i++)
+ if (CHIN(cs, i))
+ return((char)i);
+ assert(never);
+ return(0); /* arbitrary */
+}
+
+/*
+ - nch - number of characters in a set
+ == static int nch(register struct parse *p, register cset *cs);
+ */
+static int
+nch(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register int i;
+ register size_t css = (size_t)p->g->csetsize;
+ register int n = 0;
+
+ for (i = 0; i < css; i++)
+ if (CHIN(cs, i))
+ n++;
+ return(n);
+}
+
+/*
+ - mcadd - add a collating element to a cset
+ == static void mcadd(register struct parse *p, register cset *cs, \
+ == register char *cp);
+ */
+static void
+mcadd(p, cs, cp)
+register struct parse *p;
+register cset *cs;
+register char *cp;
+{
+ register size_t oldend = cs->smultis;
+
+ cs->smultis += strlen(cp) + 1;
+ if (cs->multis == NULL)
+ cs->multis = malloc(cs->smultis);
+ else
+ cs->multis = reallocf(cs->multis, cs->smultis);
+ if (cs->multis == NULL) {
+ SETERROR(REG_ESPACE);
+ return;
+ }
+
+ (void) strcpy(cs->multis + oldend - 1, cp);
+ cs->multis[cs->smultis - 1] = '\0';
+}
+
+#if used
+/*
+ - mcsub - subtract a collating element from a cset
+ == static void mcsub(register cset *cs, register char *cp);
+ */
+static void
+mcsub(cs, cp)
+register cset *cs;
+register char *cp;
+{
+ register char *fp = mcfind(cs, cp);
+ register size_t len = strlen(fp);
+
+ assert(fp != NULL);
+ (void) memmove(fp, fp + len + 1,
+ cs->smultis - (fp + len + 1 - cs->multis));
+ cs->smultis -= len;
+
+ if (cs->smultis == 0) {
+ free(cs->multis);
+ cs->multis = NULL;
+ return;
+ }
+
+ cs->multis = reallocf(cs->multis, cs->smultis);
+ assert(cs->multis != NULL);
+}
+
+/*
+ - mcin - is a collating element in a cset?
+ == static int mcin(register cset *cs, register char *cp);
+ */
+static int
+mcin(cs, cp)
+register cset *cs;
+register char *cp;
+{
+ return(mcfind(cs, cp) != NULL);
+}
+
+/*
+ - mcfind - find a collating element in a cset
+ == static char *mcfind(register cset *cs, register char *cp);
+ */
+static char *
+mcfind(cs, cp)
+register cset *cs;
+register char *cp;
+{
+ register char *p;
+
+ if (cs->multis == NULL)
+ return(NULL);
+ for (p = cs->multis; *p != '\0'; p += strlen(p) + 1)
+ if (strcmp(cp, p) == 0)
+ return(p);
+ return(NULL);
+}
+#endif
+
+/*
+ - mcinvert - invert the list of collating elements in a cset
+ == static void mcinvert(register struct parse *p, register cset *cs);
+ *
+ * This would have to know the set of possibilities. Implementation
+ * is deferred.
+ */
+static void
+mcinvert(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ assert(cs->multis == NULL); /* xxx */
+}
+
+/*
+ - mccase - add case counterparts of the list of collating elements in a cset
+ == static void mccase(register struct parse *p, register cset *cs);
+ *
+ * This would have to know the set of possibilities. Implementation
+ * is deferred.
+ */
+static void
+mccase(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ assert(cs->multis == NULL); /* xxx */
+}
+
+/*
+ - isinsets - is this character in any sets?
+ == static int isinsets(register struct re_guts *g, int c);
+ */
+static int /* predicate */
+isinsets(g, c)
+register struct re_guts *g;
+int c;
+{
+ register uch *col;
+ register int i;
+ register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
+ register unsigned uc = (uch)c;
+
+ for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
+ if (col[uc] != 0)
+ return(1);
+ return(0);
+}
+
+/*
+ - samesets - are these two characters in exactly the same sets?
+ == static int samesets(register struct re_guts *g, int c1, int c2);
+ */
+static int /* predicate */
+samesets(g, c1, c2)
+register struct re_guts *g;
+int c1;
+int c2;
+{
+ register uch *col;
+ register int i;
+ register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
+ register unsigned uc1 = (uch)c1;
+ register unsigned uc2 = (uch)c2;
+
+ for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
+ if (col[uc1] != col[uc2])
+ return(0);
+ return(1);
+}
+
+/*
+ - categorize - sort out character categories
+ == static void categorize(struct parse *p, register struct re_guts *g);
+ */
+static void
+categorize(p, g)
+struct parse *p;
+register struct re_guts *g;
+{
+ register cat_t *cats = g->categories;
+ register int c;
+ register int c2;
+ register cat_t cat;
+
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (cats[c] == 0 && isinsets(g, c)) {
+ cat = g->ncategories++;
+ cats[c] = cat;
+ for (c2 = c+1; c2 <= CHAR_MAX; c2++)
+ if (cats[c2] == 0 && samesets(g, c, c2))
+ cats[c2] = cat;
+ }
+}
+
+/*
+ - dupl - emit a duplicate of a bunch of sops
+ == static sopno dupl(register struct parse *p, sopno start, sopno finish);
+ */
+static sopno /* start of duplicate */
+dupl(p, start, finish)
+register struct parse *p;
+sopno start; /* from here */
+sopno finish; /* to this less one */
+{
+ register sopno ret = HERE();
+ register sopno len = finish - start;
+
+ assert(finish >= start);
+ if (len == 0)
+ return(ret);
+ enlarge(p, p->ssize + len); /* this many unexpected additions */
+ assert(p->ssize >= p->slen + len);
+ (void) memcpy((char *)(p->strip + p->slen),
+ (char *)(p->strip + start), (size_t)len*sizeof(sop));
+ p->slen += len;
+ return(ret);
+}
+
+/*
+ - doemit - emit a strip operator
+ == static void doemit(register struct parse *p, sop op, size_t opnd);
+ *
+ * It might seem better to implement this as a macro with a function as
+ * hard-case backup, but it's just too big and messy unless there are
+ * some changes to the data structures. Maybe later.
+ */
+static void
+doemit(p, op, opnd)
+register struct parse *p;
+sop op;
+size_t opnd;
+{
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ /* deal with oversize operands ("can't happen", more or less) */
+ assert(opnd < 1<<OPSHIFT);
+
+ /* deal with undersized strip */
+ if (p->slen >= p->ssize)
+ enlarge(p, (p->ssize+1) / 2 * 3); /* +50% */
+ assert(p->slen < p->ssize);
+
+ /* finally, it's all reduced to the easy case */
+ p->strip[p->slen++] = SOP(op, opnd);
+}
+
+/*
+ - doinsert - insert a sop into the strip
+ == static void doinsert(register struct parse *p, sop op, size_t opnd, sopno pos);
+ */
+static void
+doinsert(p, op, opnd, pos)
+register struct parse *p;
+sop op;
+size_t opnd;
+sopno pos;
+{
+ register sopno sn;
+ register sop s;
+ register int i;
+
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ sn = HERE();
+ EMIT(op, opnd); /* do checks, ensure space */
+ assert(HERE() == sn+1);
+ s = p->strip[sn];
+
+ /* adjust paren pointers */
+ assert(pos > 0);
+ for (i = 1; i < NPAREN; i++) {
+ if (p->pbegin[i] >= pos) {
+ p->pbegin[i]++;
+ }
+ if (p->pend[i] >= pos) {
+ p->pend[i]++;
+ }
+ }
+
+ memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos],
+ (HERE()-pos-1)*sizeof(sop));
+ p->strip[pos] = s;
+}
+
+/*
+ - dofwd - complete a forward reference
+ == static void dofwd(register struct parse *p, sopno pos, sop value);
+ */
+static void
+dofwd(p, pos, value)
+register struct parse *p;
+register sopno pos;
+sop value;
+{
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ assert(value < 1<<OPSHIFT);
+ p->strip[pos] = OP(p->strip[pos]) | value;
+}
+
+/*
+ - enlarge - enlarge the strip
+ == static void enlarge(register struct parse *p, sopno size);
+ */
+static void
+enlarge(p, size)
+register struct parse *p;
+register sopno size;
+{
+ register sop *sp;
+
+ if (p->ssize >= size)
+ return;
+
+ sp = (sop *)realloc(p->strip, size*sizeof(sop));
+ if (sp == NULL) {
+ SETERROR(REG_ESPACE);
+ return;
+ }
+ p->strip = sp;
+ p->ssize = size;
+}
+
+/*
+ - stripsnug - compact the strip
+ == static void stripsnug(register struct parse *p, register struct re_guts *g);
+ */
+static void
+stripsnug(p, g)
+register struct parse *p;
+register struct re_guts *g;
+{
+ g->nstates = p->slen;
+ g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop));
+ if (g->strip == NULL) {
+ SETERROR(REG_ESPACE);
+ g->strip = p->strip;
+ }
+}
+
+/*
+ - findmust - fill in must and mlen with longest mandatory literal string
+ == static void findmust(register struct parse *p, register struct re_guts *g);
+ *
+ * This algorithm could do fancy things like analyzing the operands of |
+ * for common subsequences. Someday. This code is simple and finds most
+ * of the interesting cases.
+ *
+ * Note that must and mlen got initialized during setup.
+ */
+static void
+findmust(p, g)
+struct parse *p;
+register struct re_guts *g;
+{
+ register sop *scan;
+ sop *start;
+ register sop *newstart;
+ register sopno newlen;
+ register sop s;
+ register char *cp;
+ register sopno i;
+
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ /* find the longest OCHAR sequence in strip */
+ newlen = 0;
+ scan = g->strip + 1;
+ do {
+ s = *scan++;
+ switch (OP(s)) {
+ case OCHAR: /* sequence member */
+ if (newlen == 0) /* new sequence */
+ newstart = scan - 1;
+ newlen++;
+ break;
+ case OPLUS_: /* things that don't break one */
+ case OLPAREN:
+ case ORPAREN:
+ break;
+ case OQUEST_: /* things that must be skipped */
+ case OCH_:
+ scan--;
+ do {
+ scan += OPND(s);
+ s = *scan;
+ /* assert() interferes w debug printouts */
+ if (OP(s) != O_QUEST && OP(s) != O_CH &&
+ OP(s) != OOR2) {
+ g->iflags |= BAD;
+ return;
+ }
+ } while (OP(s) != O_QUEST && OP(s) != O_CH);
+ /* fallthrough */
+ default: /* things that break a sequence */
+ if (newlen > g->mlen) { /* ends one */
+ start = newstart;
+ g->mlen = newlen;
+ }
+ newlen = 0;
+ break;
+ }
+ } while (OP(s) != OEND);
+
+ if (g->mlen == 0) /* there isn't one */
+ return;
+
+ /* turn it into a character string */
+ g->must = malloc((size_t)g->mlen + 1);
+ if (g->must == NULL) { /* argh; just forget it */
+ g->mlen = 0;
+ return;
+ }
+ cp = g->must;
+ scan = start;
+ for (i = g->mlen; i > 0; i--) {
+ while (OP(s = *scan++) != OCHAR)
+ continue;
+ assert(cp < g->must + g->mlen);
+ *cp++ = (char)OPND(s);
+ }
+ assert(cp == g->must + g->mlen);
+ *cp++ = '\0'; /* just on general principles */
+}
+
+/*
+ - pluscount - count + nesting
+ == static sopno pluscount(register struct parse *p, register struct re_guts *g);
+ */
+static sopno /* nesting depth */
+pluscount(p, g)
+struct parse *p;
+register struct re_guts *g;
+{
+ register sop *scan;
+ register sop s;
+ register sopno plusnest = 0;
+ register sopno maxnest = 0;
+
+ if (p->error != 0)
+ return(0); /* there may not be an OEND */
+
+ scan = g->strip + 1;
+ do {
+ s = *scan++;
+ switch (OP(s)) {
+ case OPLUS_:
+ plusnest++;
+ break;
+ case O_PLUS:
+ if (plusnest > maxnest)
+ maxnest = plusnest;
+ plusnest--;
+ break;
+ }
+ } while (OP(s) != OEND);
+ if (plusnest != 0)
+ g->iflags |= BAD;
+ return(maxnest);
+}
diff --git a/lib/libc/regex/regerror.c b/lib/libc/regex/regerror.c
new file mode 100644
index 0000000..b1d151d
--- /dev/null
+++ b/lib/libc/regex/regerror.c
@@ -0,0 +1,177 @@
+/*-
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regerror.c 8.4 (Berkeley) 3/20/94
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)regerror.c 8.4 (Berkeley) 3/20/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <regex.h>
+
+#include "utils.h"
+
+/* ========= begin header generated by ./mkh ========= */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* === regerror.c === */
+static char *regatoi __P((const regex_t *preg, char *localbuf));
+
+#ifdef __cplusplus
+}
+#endif
+/* ========= end header generated by ./mkh ========= */
+/*
+ = #define REG_NOMATCH 1
+ = #define REG_BADPAT 2
+ = #define REG_ECOLLATE 3
+ = #define REG_ECTYPE 4
+ = #define REG_EESCAPE 5
+ = #define REG_ESUBREG 6
+ = #define REG_EBRACK 7
+ = #define REG_EPAREN 8
+ = #define REG_EBRACE 9
+ = #define REG_BADBR 10
+ = #define REG_ERANGE 11
+ = #define REG_ESPACE 12
+ = #define REG_BADRPT 13
+ = #define REG_EMPTY 14
+ = #define REG_ASSERT 15
+ = #define REG_INVARG 16
+ = #define REG_ATOI 255 // convert name to number (!)
+ = #define REG_ITOA 0400 // convert number to name (!)
+ */
+static struct rerr {
+ int code;
+ char *name;
+ char *explain;
+} rerrs[] = {
+ {REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"},
+ {REG_BADPAT, "REG_BADPAT", "invalid regular expression"},
+ {REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"},
+ {REG_ECTYPE, "REG_ECTYPE", "invalid character class"},
+ {REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)"},
+ {REG_ESUBREG, "REG_ESUBREG", "invalid backreference number"},
+ {REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced"},
+ {REG_EPAREN, "REG_EPAREN", "parentheses not balanced"},
+ {REG_EBRACE, "REG_EBRACE", "braces not balanced"},
+ {REG_BADBR, "REG_BADBR", "invalid repetition count(s)"},
+ {REG_ERANGE, "REG_ERANGE", "invalid character range"},
+ {REG_ESPACE, "REG_ESPACE", "out of memory"},
+ {REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid"},
+ {REG_EMPTY, "REG_EMPTY", "empty (sub)expression"},
+ {REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug"},
+ {REG_INVARG, "REG_INVARG", "invalid argument to regex routine"},
+ {0, "", "*** unknown regexp error code ***"}
+};
+
+/*
+ - regerror - the interface to error numbers
+ = extern size_t regerror(int, const regex_t *, char *, size_t);
+ */
+/* ARGSUSED */
+size_t
+regerror(errcode, preg, errbuf, errbuf_size)
+int errcode;
+const regex_t *preg;
+char *errbuf;
+size_t errbuf_size;
+{
+ register struct rerr *r;
+ register size_t len;
+ register int target = errcode &~ REG_ITOA;
+ register char *s;
+ char convbuf[50];
+
+ if (errcode == REG_ATOI)
+ s = regatoi(preg, convbuf);
+ else {
+ for (r = rerrs; r->code != 0; r++)
+ if (r->code == target)
+ break;
+
+ if (errcode&REG_ITOA) {
+ if (r->code != 0)
+ (void) strcpy(convbuf, r->name);
+ else
+ sprintf(convbuf, "REG_0x%x", target);
+ assert(strlen(convbuf) < sizeof(convbuf));
+ s = convbuf;
+ } else
+ s = r->explain;
+ }
+
+ len = strlen(s) + 1;
+ if (errbuf_size > 0) {
+ if (errbuf_size > len)
+ (void) strcpy(errbuf, s);
+ else {
+ (void) strncpy(errbuf, s, errbuf_size-1);
+ errbuf[errbuf_size-1] = '\0';
+ }
+ }
+
+ return(len);
+}
+
+/*
+ - regatoi - internal routine to implement REG_ATOI
+ == static char *regatoi(const regex_t *preg, char *localbuf);
+ */
+static char *
+regatoi(preg, localbuf)
+const regex_t *preg;
+char *localbuf;
+{
+ register struct rerr *r;
+
+ for (r = rerrs; r->code != 0; r++)
+ if (strcmp(r->name, preg->re_endp) == 0)
+ break;
+ if (r->code == 0)
+ return("0");
+
+ sprintf(localbuf, "%d", r->code);
+ return(localbuf);
+}
diff --git a/lib/libc/regex/regex.3 b/lib/libc/regex/regex.3
new file mode 100644
index 0000000..3d90055
--- /dev/null
+++ b/lib/libc/regex/regex.3
@@ -0,0 +1,541 @@
+.\" Copyright (c) 1992, 1993, 1994 Henry Spencer.
+.\" Copyright (c) 1992, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Henry Spencer.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)regex.3 8.4 (Berkeley) 3/20/94
+.\" $FreeBSD$
+.\"
+.TH REGEX 3 "March 20, 1994"
+.de ZR
+.\" one other place knows this name: the SEE ALSO section
+.IR re_format (7) \\$1
+..
+.SH NAME
+regcomp, regexec, regerror, regfree \- regular-expression library
+.SH SYNOPSIS
+.ft B
+.\".na
+#include <sys/types.h>
+.br
+#include <regex.h>
+.HP 10
+int regcomp(regex_t\ *preg, const\ char\ *pattern, int\ cflags);
+.HP
+int\ regexec(const\ regex_t\ *preg, const\ char\ *string,
+size_t\ nmatch, regmatch_t\ pmatch[], int\ eflags);
+.HP
+size_t\ regerror(int\ errcode, const\ regex_t\ *preg,
+char\ *errbuf, size_t\ errbuf_size);
+.HP
+void\ regfree(regex_t\ *preg);
+.\".ad
+.ft
+.SH DESCRIPTION
+These routines implement POSIX 1003.2 regular expressions (``RE''s);
+see
+.ZR .
+.I Regcomp
+compiles an RE written as a string into an internal form,
+.I regexec
+matches that internal form against a string and reports results,
+.I regerror
+transforms error codes from either into human-readable messages,
+and
+.I regfree
+frees any dynamically-allocated storage used by the internal form
+of an RE.
+.PP
+The header
+.I <regex.h>
+declares two structure types,
+.I regex_t
+and
+.IR regmatch_t ,
+the former for compiled internal forms and the latter for match reporting.
+It also declares the four functions,
+a type
+.IR regoff_t ,
+and a number of constants with names starting with ``REG_''.
+.PP
+.I Regcomp
+compiles the regular expression contained in the
+.I pattern
+string,
+subject to the flags in
+.IR cflags ,
+and places the results in the
+.I regex_t
+structure pointed to by
+.IR preg .
+.I Cflags
+is the bitwise OR of zero or more of the following flags:
+.IP REG_EXTENDED \w'REG_EXTENDED'u+2n
+Compile modern (``extended'') REs,
+rather than the obsolete (``basic'') REs that
+are the default.
+.IP REG_BASIC
+This is a synonym for 0,
+provided as a counterpart to REG_EXTENDED to improve readability.
+.IP REG_NOSPEC
+Compile with recognition of all special characters turned off.
+All characters are thus considered ordinary,
+so the ``RE'' is a literal string.
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+REG_EXTENDED and REG_NOSPEC may not be used
+in the same call to
+.IR regcomp .
+.IP REG_ICASE
+Compile for matching that ignores upper/lower case distinctions.
+See
+.ZR .
+.IP REG_NOSUB
+Compile for matching that need only report success or failure,
+not what was matched.
+.IP REG_NEWLINE
+Compile for newline-sensitive matching.
+By default, newline is a completely ordinary character with no special
+meaning in either REs or strings.
+With this flag,
+`[^' bracket expressions and `.' never match newline,
+a `^' anchor matches the null string after any newline in the string
+in addition to its normal function,
+and the `$' anchor matches the null string before any newline in the
+string in addition to its normal function.
+.IP REG_PEND
+The regular expression ends,
+not at the first NUL,
+but just before the character pointed to by the
+.I re_endp
+member of the structure pointed to by
+.IR preg .
+The
+.I re_endp
+member is of type
+.IR const\ char\ * .
+This flag permits inclusion of NULs in the RE;
+they are considered ordinary characters.
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+.PP
+When successful,
+.I regcomp
+returns 0 and fills in the structure pointed to by
+.IR preg .
+One member of that structure
+(other than
+.IR re_endp )
+is publicized:
+.IR re_nsub ,
+of type
+.IR size_t ,
+contains the number of parenthesized subexpressions within the RE
+(except that the value of this member is undefined if the
+REG_NOSUB flag was used).
+If
+.I regcomp
+fails, it returns a non-zero error code;
+see DIAGNOSTICS.
+.PP
+.I Regexec
+matches the compiled RE pointed to by
+.I preg
+against the
+.IR string ,
+subject to the flags in
+.IR eflags ,
+and reports results using
+.IR nmatch ,
+.IR pmatch ,
+and the returned value.
+The RE must have been compiled by a previous invocation of
+.IR regcomp .
+The compiled form is not altered during execution of
+.IR regexec ,
+so a single compiled RE can be used simultaneously by multiple threads.
+.PP
+By default,
+the NUL-terminated string pointed to by
+.I string
+is considered to be the text of an entire line, minus any terminating
+newline.
+The
+.I eflags
+argument is the bitwise OR of zero or more of the following flags:
+.IP REG_NOTBOL \w'REG_STARTEND'u+2n
+The first character of
+the string
+is not the beginning of a line, so the `^' anchor should not match before it.
+This does not affect the behavior of newlines under REG_NEWLINE.
+.IP REG_NOTEOL
+The NUL terminating
+the string
+does not end a line, so the `$' anchor should not match before it.
+This does not affect the behavior of newlines under REG_NEWLINE.
+.IP REG_STARTEND
+The string is considered to start at
+\fIstring\fR\ + \fIpmatch\fR[0].\fIrm_so\fR
+and to have a terminating NUL located at
+\fIstring\fR\ + \fIpmatch\fR[0].\fIrm_eo\fR
+(there need not actually be a NUL at that location),
+regardless of the value of
+.IR nmatch .
+See below for the definition of
+.IR pmatch
+and
+.IR nmatch .
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+Note that a non-zero \fIrm_so\fR does not imply REG_NOTBOL;
+REG_STARTEND affects only the location of the string,
+not how it is matched.
+.PP
+See
+.ZR
+for a discussion of what is matched in situations where an RE or a
+portion thereof could match any of several substrings of
+.IR string .
+.PP
+Normally,
+.I regexec
+returns 0 for success and the non-zero code REG_NOMATCH for failure.
+Other non-zero error codes may be returned in exceptional situations;
+see DIAGNOSTICS.
+.PP
+If REG_NOSUB was specified in the compilation of the RE,
+or if
+.I nmatch
+is 0,
+.I regexec
+ignores the
+.I pmatch
+argument (but see below for the case where REG_STARTEND is specified).
+Otherwise,
+.I pmatch
+points to an array of
+.I nmatch
+structures of type
+.IR regmatch_t .
+Such a structure has at least the members
+.I rm_so
+and
+.IR rm_eo ,
+both of type
+.I regoff_t
+(a signed arithmetic type at least as large as an
+.I off_t
+and a
+.IR ssize_t ),
+containing respectively the offset of the first character of a substring
+and the offset of the first character after the end of the substring.
+Offsets are measured from the beginning of the
+.I string
+argument given to
+.IR regexec .
+An empty substring is denoted by equal offsets,
+both indicating the character following the empty substring.
+.PP
+The 0th member of the
+.I pmatch
+array is filled in to indicate what substring of
+.I string
+was matched by the entire RE.
+Remaining members report what substring was matched by parenthesized
+subexpressions within the RE;
+member
+.I i
+reports subexpression
+.IR i ,
+with subexpressions counted (starting at 1) by the order of their opening
+parentheses in the RE, left to right.
+Unused entries in the array\(emcorresponding either to subexpressions that
+did not participate in the match at all, or to subexpressions that do not
+exist in the RE (that is, \fIi\fR\ > \fIpreg\fR\->\fIre_nsub\fR)\(emhave both
+.I rm_so
+and
+.I rm_eo
+set to \-1.
+If a subexpression participated in the match several times,
+the reported substring is the last one it matched.
+(Note, as an example in particular, that when the RE `(b*)+' matches `bbb',
+the parenthesized subexpression matches each of the three `b's and then
+an infinite number of empty strings following the last `b',
+so the reported substring is one of the empties.)
+.PP
+If REG_STARTEND is specified,
+.I pmatch
+must point to at least one
+.I regmatch_t
+(even if
+.I nmatch
+is 0 or REG_NOSUB was specified),
+to hold the input offsets for REG_STARTEND.
+Use for output is still entirely controlled by
+.IR nmatch ;
+if
+.I nmatch
+is 0 or REG_NOSUB was specified,
+the value of
+.IR pmatch [0]
+will not be changed by a successful
+.IR regexec .
+.PP
+.I Regerror
+maps a non-zero
+.I errcode
+from either
+.I regcomp
+or
+.I regexec
+to a human-readable, printable message.
+If
+.I preg
+is non-NULL,
+the error code should have arisen from use of
+the
+.I regex_t
+pointed to by
+.IR preg ,
+and if the error code came from
+.IR regcomp ,
+it should have been the result from the most recent
+.I regcomp
+using that
+.IR regex_t .
+.RI ( Regerror
+may be able to supply a more detailed message using information
+from the
+.IR regex_t .)
+.I Regerror
+places the NUL-terminated message into the buffer pointed to by
+.IR errbuf ,
+limiting the length (including the NUL) to at most
+.I errbuf_size
+bytes.
+If the whole message won't fit,
+as much of it as will fit before the terminating NUL is supplied.
+In any case,
+the returned value is the size of buffer needed to hold the whole
+message (including terminating NUL).
+If
+.I errbuf_size
+is 0,
+.I errbuf
+is ignored but the return value is still correct.
+.PP
+If the
+.I errcode
+given to
+.I regerror
+is first ORed with REG_ITOA,
+the ``message'' that results is the printable name of the error code,
+e.g. ``REG_NOMATCH'',
+rather than an explanation thereof.
+If
+.I errcode
+is REG_ATOI,
+then
+.I preg
+shall be non-NULL and the
+.I re_endp
+member of the structure it points to
+must point to the printable name of an error code;
+in this case, the result in
+.I errbuf
+is the decimal digits of
+the numeric value of the error code
+(0 if the name is not recognized).
+REG_ITOA and REG_ATOI are intended primarily as debugging facilities;
+they are extensions,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+Be warned also that they are considered experimental and changes are possible.
+.PP
+.I Regfree
+frees any dynamically-allocated storage associated with the compiled RE
+pointed to by
+.IR preg .
+The remaining
+.I regex_t
+is no longer a valid compiled RE
+and the effect of supplying it to
+.I regexec
+or
+.I regerror
+is undefined.
+.PP
+None of these functions references global variables except for tables
+of constants;
+all are safe for use from multiple threads if the arguments are safe.
+.SH IMPLEMENTATION CHOICES
+There are a number of decisions that 1003.2 leaves up to the implementor,
+either by explicitly saying ``undefined'' or by virtue of them being
+forbidden by the RE grammar.
+This implementation treats them as follows.
+.PP
+See
+.ZR
+for a discussion of the definition of case-independent matching.
+.PP
+There is no particular limit on the length of REs,
+except insofar as memory is limited.
+Memory usage is approximately linear in RE size, and largely insensitive
+to RE complexity, except for bounded repetitions.
+See BUGS for one short RE using them
+that will run almost any system out of memory.
+.PP
+A backslashed character other than one specifically given a magic meaning
+by 1003.2 (such magic meanings occur only in obsolete [``basic''] REs)
+is taken as an ordinary character.
+.PP
+Any unmatched [ is a REG_EBRACK error.
+.PP
+Equivalence classes cannot begin or end bracket-expression ranges.
+The endpoint of one range cannot begin another.
+.PP
+RE_DUP_MAX, the limit on repetition counts in bounded repetitions, is 255.
+.PP
+A repetition operator (?, *, +, or bounds) cannot follow another
+repetition operator.
+A repetition operator cannot begin an expression or subexpression
+or follow `^' or `|'.
+.PP
+`|' cannot appear first or last in a (sub)expression or after another `|',
+i.e. an operand of `|' cannot be an empty subexpression.
+An empty parenthesized subexpression, `()', is legal and matches an
+empty (sub)string.
+An empty string is not a legal RE.
+.PP
+A `{' followed by a digit is considered the beginning of bounds for a
+bounded repetition, which must then follow the syntax for bounds.
+A `{' \fInot\fR followed by a digit is considered an ordinary character.
+.PP
+`^' and `$' beginning and ending subexpressions in obsolete (``basic'')
+REs are anchors, not ordinary characters.
+.SH SEE ALSO
+grep(1), re_format(7)
+.PP
+POSIX 1003.2, sections 2.8 (Regular Expression Notation)
+and
+B.5 (C Binding for Regular Expression Matching).
+.SH DIAGNOSTICS
+Non-zero error codes from
+.I regcomp
+and
+.I regexec
+include the following:
+.PP
+.nf
+.ta \w'REG_ECOLLATE'u+3n
+REG_NOMATCH regexec() failed to match
+REG_BADPAT invalid regular expression
+REG_ECOLLATE invalid collating element
+REG_ECTYPE invalid character class
+REG_EESCAPE \e applied to unescapable character
+REG_ESUBREG invalid backreference number
+REG_EBRACK brackets [ ] not balanced
+REG_EPAREN parentheses ( ) not balanced
+REG_EBRACE braces { } not balanced
+REG_BADBR invalid repetition count(s) in { }
+REG_ERANGE invalid character range in [ ]
+REG_ESPACE ran out of memory
+REG_BADRPT ?, *, or + operand invalid
+REG_EMPTY empty (sub)expression
+REG_ASSERT ``can't happen''\(emyou found a bug
+REG_INVARG invalid argument, e.g. negative-length string
+.fi
+.SH HISTORY
+Originally written by Henry Spencer.
+Altered for inclusion in the
+.Bx 4.4
+distribution.
+.SH BUGS
+This is an alpha release with known defects.
+Please report problems.
+.PP
+There is one known functionality bug.
+The implementation of internationalization is incomplete:
+the locale is always assumed to be the default one of 1003.2,
+and only the collating elements etc. of that locale are available.
+.PP
+The back-reference code is subtle and doubts linger about its correctness
+in complex cases.
+.PP
+.I Regexec
+performance is poor.
+This will improve with later releases.
+.I Nmatch
+exceeding 0 is expensive;
+.I nmatch
+exceeding 1 is worse.
+.I Regexec
+is largely insensitive to RE complexity \fIexcept\fR that back
+references are massively expensive.
+RE length does matter; in particular, there is a strong speed bonus
+for keeping RE length under about 30 characters,
+with most special characters counting roughly double.
+.PP
+.I Regcomp
+implements bounded repetitions by macro expansion,
+which is costly in time and space if counts are large
+or bounded repetitions are nested.
+An RE like, say,
+`((((a{1,100}){1,100}){1,100}){1,100}){1,100}'
+will (eventually) run almost any existing machine out of swap space.
+.PP
+There are suspected problems with response to obscure error conditions.
+Notably,
+certain kinds of internal overflow,
+produced only by truly enormous REs or by multiply nested bounded repetitions,
+are probably not handled well.
+.PP
+Due to a mistake in 1003.2, things like `a)b' are legal REs because `)' is
+a special character only in the presence of a previous unmatched `('.
+This can't be fixed until the spec is fixed.
+.PP
+The standard's definition of back references is vague.
+For example, does
+`a\e(\e(b\e)*\e2\e)*d' match `abbbd'?
+Until the standard is clarified,
+behavior in such cases should not be relied on.
+.PP
+The implementation of word-boundary matching is a bit of a kludge,
+and bugs may lurk in combinations of word-boundary matching and anchoring.
diff --git a/lib/libc/regex/regex2.h b/lib/libc/regex/regex2.h
new file mode 100644
index 0000000..cd7b962
--- /dev/null
+++ b/lib/libc/regex/regex2.h
@@ -0,0 +1,173 @@
+/*-
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regex2.h 8.4 (Berkeley) 3/20/94
+ */
+
+/*
+ * First, the stuff that ends up in the outside-world include file
+ = typedef off_t regoff_t;
+ = typedef struct {
+ = int re_magic;
+ = size_t re_nsub; // number of parenthesized subexpressions
+ = const char *re_endp; // end pointer for REG_PEND
+ = struct re_guts *re_g; // none of your business :-)
+ = } regex_t;
+ = typedef struct {
+ = regoff_t rm_so; // start of match
+ = regoff_t rm_eo; // end of match
+ = } regmatch_t;
+ */
+/*
+ * internals of regex_t
+ */
+#define MAGIC1 ((('r'^0200)<<8) | 'e')
+
+/*
+ * The internal representation is a *strip*, a sequence of
+ * operators ending with an endmarker. (Some terminology etc. is a
+ * historical relic of earlier versions which used multiple strips.)
+ * Certain oddities in the representation are there to permit running
+ * the machinery backwards; in particular, any deviation from sequential
+ * flow must be marked at both its source and its destination. Some
+ * fine points:
+ *
+ * - OPLUS_ and O_PLUS are *inside* the loop they create.
+ * - OQUEST_ and O_QUEST are *outside* the bypass they create.
+ * - OCH_ and O_CH are *outside* the multi-way branch they create, while
+ * OOR1 and OOR2 are respectively the end and the beginning of one of
+ * the branches. Note that there is an implicit OOR2 following OCH_
+ * and an implicit OOR1 preceding O_CH.
+ *
+ * In state representations, an operator's bit is on to signify a state
+ * immediately *preceding* "execution" of that operator.
+ */
+typedef unsigned long sop; /* strip operator */
+typedef long sopno;
+#define OPRMASK 0xf8000000L
+#define OPDMASK 0x07ffffffL
+#define OPSHIFT ((unsigned)27)
+#define OP(n) ((n)&OPRMASK)
+#define OPND(n) ((n)&OPDMASK)
+#define SOP(op, opnd) ((op)|(opnd))
+/* operators meaning operand */
+/* (back, fwd are offsets) */
+#define OEND (1L<<OPSHIFT) /* endmarker - */
+#define OCHAR (2L<<OPSHIFT) /* character unsigned char */
+#define OBOL (3L<<OPSHIFT) /* left anchor - */
+#define OEOL (4L<<OPSHIFT) /* right anchor - */
+#define OANY (5L<<OPSHIFT) /* . - */
+#define OANYOF (6L<<OPSHIFT) /* [...] set number */
+#define OBACK_ (7L<<OPSHIFT) /* begin \d paren number */
+#define O_BACK (8L<<OPSHIFT) /* end \d paren number */
+#define OPLUS_ (9L<<OPSHIFT) /* + prefix fwd to suffix */
+#define O_PLUS (10L<<OPSHIFT) /* + suffix back to prefix */
+#define OQUEST_ (11L<<OPSHIFT) /* ? prefix fwd to suffix */
+#define O_QUEST (12L<<OPSHIFT) /* ? suffix back to prefix */
+#define OLPAREN (13L<<OPSHIFT) /* ( fwd to ) */
+#define ORPAREN (14L<<OPSHIFT) /* ) back to ( */
+#define OCH_ (15L<<OPSHIFT) /* begin choice fwd to OOR2 */
+#define OOR1 (16L<<OPSHIFT) /* | pt. 1 back to OOR1 or OCH_ */
+#define OOR2 (17L<<OPSHIFT) /* | pt. 2 fwd to OOR2 or O_CH */
+#define O_CH (18L<<OPSHIFT) /* end choice back to OOR1 */
+#define OBOW (19L<<OPSHIFT) /* begin word - */
+#define OEOW (20L<<OPSHIFT) /* end word - */
+
+/*
+ * Structure for [] character-set representation. Character sets are
+ * done as bit vectors, grouped 8 to a byte vector for compactness.
+ * The individual set therefore has both a pointer to the byte vector
+ * and a mask to pick out the relevant bit of each byte. A hash code
+ * simplifies testing whether two sets could be identical.
+ *
+ * This will get trickier for multicharacter collating elements. As
+ * preliminary hooks for dealing with such things, we also carry along
+ * a string of multi-character elements, and decide the size of the
+ * vectors at run time.
+ */
+typedef struct {
+ uch *ptr; /* -> uch [csetsize] */
+ uch mask; /* bit within array */
+ short hash; /* hash code */
+ size_t smultis;
+ char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */
+} cset;
+/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */
+#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (uch)(c))
+#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (uch)(c))
+#define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask)
+#define MCadd(p, cs, cp) mcadd(p, cs, cp) /* regcomp() internal fns */
+#define MCsub(p, cs, cp) mcsub(p, cs, cp)
+#define MCin(p, cs, cp) mcin(p, cs, cp)
+
+/* stuff for character categories */
+typedef unsigned char cat_t;
+
+/*
+ * main compiled-expression structure
+ */
+struct re_guts {
+ int magic;
+# define MAGIC2 ((('R'^0200)<<8)|'E')
+ sop *strip; /* malloced area for strip */
+ int csetsize; /* number of bits in a cset vector */
+ int ncsets; /* number of csets in use */
+ cset *sets; /* -> cset [ncsets] */
+ uch *setbits; /* -> uch[csetsize][ncsets/CHAR_BIT] */
+ int cflags; /* copy of regcomp() cflags argument */
+ sopno nstates; /* = number of sops */
+ sopno firststate; /* the initial OEND (normally 0) */
+ sopno laststate; /* the final OEND */
+ int iflags; /* internal flags */
+# define USEBOL 01 /* used ^ */
+# define USEEOL 02 /* used $ */
+# define BAD 04 /* something wrong */
+ int nbol; /* number of ^ used */
+ int neol; /* number of $ used */
+ int ncategories; /* how many character categories */
+ cat_t *categories; /* ->catspace[-CHAR_MIN] */
+ char *must; /* match must contain this string */
+ int mlen; /* length of must */
+ size_t nsub; /* copy of re_nsub */
+ int backrefs; /* does it use back references? */
+ sopno nplus; /* how deep does it nest +s? */
+ /* catspace must be last */
+ cat_t catspace[1]; /* actually [NC] */
+};
+
+/* misc utilities */
+#define OUT (CHAR_MAX+1) /* a non-character value */
+#define ISWORD(c) (isalnum((uch)(c)) || (c) == '_')
diff --git a/lib/libc/regex/regexec.c b/lib/libc/regex/regexec.c
new file mode 100644
index 0000000..80a7ad0
--- /dev/null
+++ b/lib/libc/regex/regexec.c
@@ -0,0 +1,181 @@
+/*-
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regexec.c 8.3 (Berkeley) 3/20/94
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)regexec.c 8.3 (Berkeley) 3/20/94";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * the outer shell of regexec()
+ *
+ * This file includes engine.c *twice*, after muchos fiddling with the
+ * macros that code uses. This lets the same code operate on two different
+ * representations for state sets.
+ */
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <ctype.h>
+#include <regex.h>
+
+#include "utils.h"
+#include "regex2.h"
+
+static int nope = 0; /* for use in asserts; shuts lint up */
+
+/* macros for manipulating states, small version */
+#define states long
+#define states1 states /* for later use in regexec() decision */
+#define CLEAR(v) ((v) = 0)
+#define SET0(v, n) ((v) &= ~((unsigned long)1 << (n)))
+#define SET1(v, n) ((v) |= (unsigned long)1 << (n))
+#define ISSET(v, n) (((v) & ((unsigned long)1 << (n))) != 0)
+#define ASSIGN(d, s) ((d) = (s))
+#define EQ(a, b) ((a) == (b))
+#define STATEVARS long dummy /* dummy version */
+#define STATESETUP(m, n) /* nothing */
+#define STATETEARDOWN(m) /* nothing */
+#define SETUP(v) ((v) = 0)
+#define onestate long
+#define INIT(o, n) ((o) = (unsigned long)1 << (n))
+#define INC(o) ((o) <<= 1)
+#define ISSTATEIN(v, o) (((v) & (o)) != 0)
+/* some abbreviations; note that some of these know variable names! */
+/* do "if I'm here, I can also be there" etc without branches */
+#define FWD(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) << (n))
+#define BACK(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) >> (n))
+#define ISSETBACK(v, n) (((v) & ((unsigned long)here >> (n))) != 0)
+/* function names */
+#define SNAMES /* engine.c looks after details */
+
+#include "engine.c"
+
+/* now undo things */
+#undef states
+#undef CLEAR
+#undef SET0
+#undef SET1
+#undef ISSET
+#undef ASSIGN
+#undef EQ
+#undef STATEVARS
+#undef STATESETUP
+#undef STATETEARDOWN
+#undef SETUP
+#undef onestate
+#undef INIT
+#undef INC
+#undef ISSTATEIN
+#undef FWD
+#undef BACK
+#undef ISSETBACK
+#undef SNAMES
+
+/* macros for manipulating states, large version */
+#define states char *
+#define CLEAR(v) memset(v, 0, m->g->nstates)
+#define SET0(v, n) ((v)[n] = 0)
+#define SET1(v, n) ((v)[n] = 1)
+#define ISSET(v, n) ((v)[n])
+#define ASSIGN(d, s) memcpy(d, s, m->g->nstates)
+#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0)
+#define STATEVARS long vn; char *space
+#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \
+ if ((m)->space == NULL) return(REG_ESPACE); \
+ (m)->vn = 0; }
+#define STATETEARDOWN(m) { free((m)->space); }
+#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates])
+#define onestate long
+#define INIT(o, n) ((o) = (n))
+#define INC(o) ((o)++)
+#define ISSTATEIN(v, o) ((v)[o])
+/* some abbreviations; note that some of these know variable names! */
+/* do "if I'm here, I can also be there" etc without branches */
+#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here])
+#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here])
+#define ISSETBACK(v, n) ((v)[here - (n)])
+/* function names */
+#define LNAMES /* flag */
+
+#include "engine.c"
+
+/*
+ - regexec - interface for matching
+ = extern int regexec(const regex_t *, const char *, size_t, \
+ = regmatch_t [], int);
+ = #define REG_NOTBOL 00001
+ = #define REG_NOTEOL 00002
+ = #define REG_STARTEND 00004
+ = #define REG_TRACE 00400 // tracing of execution
+ = #define REG_LARGE 01000 // force large representation
+ = #define REG_BACKR 02000 // force use of backref code
+ *
+ * We put this here so we can exploit knowledge of the state representation
+ * when choosing which matcher to call. Also, by this point the matchers
+ * have been prototyped.
+ */
+int /* 0 success, REG_NOMATCH failure */
+regexec(preg, string, nmatch, pmatch, eflags)
+const regex_t *preg;
+const char *string;
+size_t nmatch;
+regmatch_t pmatch[];
+int eflags;
+{
+ register struct re_guts *g = preg->re_g;
+#ifdef REDEBUG
+# define GOODFLAGS(f) (f)
+#else
+# define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND))
+#endif
+
+ if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
+ return(REG_BADPAT);
+ assert(!(g->iflags&BAD));
+ if (g->iflags&BAD) /* backstop for no-debug case */
+ return(REG_BADPAT);
+ eflags = GOODFLAGS(eflags);
+
+ if (g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags&REG_LARGE))
+ return(smatcher(g, (char *)string, nmatch, pmatch, eflags));
+ else
+ return(lmatcher(g, (char *)string, nmatch, pmatch, eflags));
+}
diff --git a/lib/libc/regex/regfree.c b/lib/libc/regex/regfree.c
new file mode 100644
index 0000000..580fb75
--- /dev/null
+++ b/lib/libc/regex/regfree.c
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regfree.c 8.3 (Berkeley) 3/20/94
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)regfree.c 8.3 (Berkeley) 3/20/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <regex.h>
+
+#include "utils.h"
+#include "regex2.h"
+
+/*
+ - regfree - free everything
+ = extern void regfree(regex_t *);
+ */
+void
+regfree(preg)
+regex_t *preg;
+{
+ register struct re_guts *g;
+
+ if (preg->re_magic != MAGIC1) /* oops */
+ return; /* nice to complain, but hard */
+
+ g = preg->re_g;
+ if (g == NULL || g->magic != MAGIC2) /* oops again */
+ return;
+ preg->re_magic = 0; /* mark it invalid */
+ g->magic = 0; /* mark it invalid */
+
+ if (g->strip != NULL)
+ free((char *)g->strip);
+ if (g->sets != NULL)
+ free((char *)g->sets);
+ if (g->setbits != NULL)
+ free((char *)g->setbits);
+ if (g->must != NULL)
+ free(g->must);
+ free((char *)g);
+}
diff --git a/lib/libc/regex/utils.h b/lib/libc/regex/utils.h
new file mode 100644
index 0000000..d804d8d
--- /dev/null
+++ b/lib/libc/regex/utils.h
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)utils.h 8.3 (Berkeley) 3/20/94
+ */
+
+/* utility definitions */
+#define DUPMAX _POSIX2_RE_DUP_MAX /* xxx is this right? */
+#define INFINITY (DUPMAX + 1)
+#define NC (CHAR_MAX - CHAR_MIN + 1)
+typedef unsigned char uch;
+
+/* switch off assertions (if not already off) if no REDEBUG */
+#ifndef REDEBUG
+#ifndef NDEBUG
+#define NDEBUG /* no assertions please */
+#endif
+#endif
+#include <assert.h>
+
+/* for old systems with bcopy() but no memmove() */
+#ifdef USEBCOPY
+#define memmove(d, s, c) bcopy(s, d, c)
+#endif
diff --git a/lib/libc/rpc/DISCLAIMER b/lib/libc/rpc/DISCLAIMER
new file mode 100644
index 0000000..1a66d5f
--- /dev/null
+++ b/lib/libc/rpc/DISCLAIMER
@@ -0,0 +1,28 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
diff --git a/lib/libc/rpc/Makefile.inc b/lib/libc/rpc/Makefile.inc
new file mode 100644
index 0000000..79103b3
--- /dev/null
+++ b/lib/libc/rpc/Makefile.inc
@@ -0,0 +1,119 @@
+# @(#)Makefile 5.11 (Berkeley) 9/6/90
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libc/rpc ${.CURDIR}/.
+
+SRCS+= auth_des.c auth_none.c auth_time.c auth_unix.c \
+ authdes_prot.c authunix_prot.c bindresvport.c \
+ clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c clnt_tcp.c \
+ clnt_udp.c clnt_unix.c crypt_client.c des_crypt.c des_soft.c \
+ get_myaddress.c getpublickey.c getrpcent.c getrpcport.c \
+ key_call.c key_prot_xdr.c netname.c netnamer.c \
+ pmap_clnt.c pmap_getmaps.c pmap_getport.c pmap_prot.c \
+ pmap_prot2.c pmap_rmt.c rpc_callmsg.c rpc_commondata.c \
+ rpc_dtablesize.c rpc_prot.c rpcdname.c rtime.c \
+ svc.c svc_auth.c svc_auth_des.c svc_auth_unix.c \
+ svc_raw.c svc_run.c svc_simple.c \
+ svc_tcp.c svc_udp.c svc_unix.c
+
+# generated sources
+SRCS+= crypt_clnt.c crypt_xdr.c crypt.h
+
+CFLAGS+= -DBROKEN_DES
+
+CLEANFILES+= crypt_clnt.c crypt_xdr.c crypt.h
+
+RPCDIR= ${DESTDIR}/usr/include/rpcsvc
+RPCGEN= rpcgen -C
+
+crypt_clnt.c: ${RPCDIR}/crypt.x crypt.h
+ ${RPCGEN} -l -o ${.TARGET} ${RPCDIR}/crypt.x
+
+crypt_xdr.c: ${RPCDIR}/crypt.x crypt.h
+ ${RPCGEN} -c -o ${.TARGET} ${RPCDIR}/crypt.x
+
+crypt.h: ${RPCDIR}/crypt.x
+ ${RPCGEN} -h -o ${.TARGET} ${RPCDIR}/crypt.x
+
+.if ${LIB} == "c"
+#
+# XXX -- rstat.1 and rstat_svc.8 shouldn't really be here
+# but there's no rstat command, don't know why, so I'm
+# leaving them here in case they're needed sometime later.
+# Paul.
+#
+
+# MAN1+= rstat.1
+MAN3+= bindresvport.3 des_crypt.3 getrpcent.3 getrpcport.3 publickey.3 rpc.3 \
+ rpc_secure.3 rtime.3
+MAN5+= publickey.5 rpc.5
+# MAN8+= rstat_svc.8
+
+MLINKS+= getrpcent.3 endrpcent.3 \
+ getrpcent.3 getrpcbyname.3 \
+ getrpcent.3 getrpcbynumber.3 \
+ getrpcent.3 setrpcent.3 \
+ rpc.3 auth_destroy.3 \
+ rpc.3 authnone_create.3 \
+ rpc.3 authunix_create.3 \
+ rpc.3 authunix_create_default.3 \
+ rpc.3 callrpc.3 \
+ rpc.3 clnt_broadcast.3 \
+ rpc.3 clnt_call.3 \
+ rpc.3 clnt_control.3 \
+ rpc.3 clnt_create.3 \
+ rpc.3 clnt_destroy.3 \
+ rpc.3 clnt_freeres.3 \
+ rpc.3 clnt_geterr.3 \
+ rpc.3 clnt_pcreateerror.3 \
+ rpc.3 clnt_perrno.3 \
+ rpc.3 clnt_perror.3 \
+ rpc.3 clnt_spcreateerror.3 \
+ rpc.3 clnt_sperrno.3 \
+ rpc.3 clnt_sperror.3 \
+ rpc.3 clntraw_create.3 \
+ rpc.3 clnttcp_create.3 \
+ rpc.3 clntudp_bufcreate.3 \
+ rpc.3 clntudp_create.3 \
+ rpc.3 get_myaddress.3 \
+ rpc.3 pmap_getmaps.3 \
+ rpc.3 pmap_getport.3 \
+ rpc.3 pmap_rmtcall.3 \
+ rpc.3 pmap_set.3 \
+ rpc.3 pmap_unset.3 \
+ rpc.3 regsterrpc.3 \
+ rpc.3 rpc_createerr.3 \
+ rpc.3 svc_destroy.3 \
+ rpc.3 svc_fds.3 \
+ rpc.3 svc_fdset.3 \
+ rpc.3 svc_getargs.3 \
+ rpc.3 svc_getcaller.3 \
+ rpc.3 svc_getreg.3 \
+ rpc.3 svc_getregset.3 \
+ rpc.3 svc_register.3 \
+ rpc.3 svc_run.3 \
+ rpc.3 svc_sendreply.3 \
+ rpc.3 svc_unregister.3 \
+ rpc.3 svcerr_auth.3 \
+ rpc.3 svcerr_decode.3 \
+ rpc.3 svcerr_noproc.3 \
+ rpc.3 svcerr_noprog.3 \
+ rpc.3 svcerr_progvers.3 \
+ rpc.3 svcerr_systemerr.3 \
+ rpc.3 svcerr_weakauth.3 \
+ rpc.3 svcfd_create.3 \
+ rpc.3 svcraw_create.3 \
+ rpc.3 svctcp_create.3 \
+ rpc.3 svcudp_bufcreate.3 \
+ rpc.3 xdr_accepted_reply.3 \
+ rpc.3 xdr_authunix_parms.3 \
+ rpc.3 xdr_callhdr.3 \
+ rpc.3 xdr_callmsg.3 \
+ rpc.3 xdr_opaque_auth.3 \
+ rpc.3 xdr_pmap.3 \
+ rpc.3 xdr_pmaplist.3 \
+ rpc.3 xdr_rejected_reply.3 \
+ rpc.3 xdr_replymsg.3 \
+ rpc.3 xprt_register.3 \
+ rpc.3 xprt_unregister.3
+.endif
diff --git a/lib/libc/rpc/PSD.doc/nfs.rfc.ms b/lib/libc/rpc/PSD.doc/nfs.rfc.ms
new file mode 100644
index 0000000..0c9a899
--- /dev/null
+++ b/lib/libc/rpc/PSD.doc/nfs.rfc.ms
@@ -0,0 +1,1372 @@
+.\"
+.\" Must use -- tbl -- with this one
+.\"
+.\" @(#)nfs.rfc.ms 2.2 88/08/05 4.0 RPCSRC
+.de BT
+.if \\n%=1 .tl ''- % -''
+..
+.ND
+.\" prevent excess underlining in nroff
+.if n .fp 2 R
+.OH 'Network File System: Version 2 Protocol Specification''Page %'
+.EH 'Page %''Network File System: Version 2 Protocol Specification'
+.if \\n%=1 .bp
+.SH
+\&Network File System: Version 2 Protocol Specification
+.IX NFS "" "" "" PAGE MAJOR
+.IX "Network File System" "" "" "" PAGE MAJOR
+.IX NFS "version-2 protocol specification"
+.IX "Network File System" "version-2 protocol specification"
+.LP
+.NH 0
+\&Status of this Standard
+.LP
+Note: This document specifies a protocol that Sun Microsystems, Inc.,
+and others are using. It specifies it in standard ARPA RFC form.
+.NH 1
+\&Introduction
+.IX NFS introduction
+.LP
+The Sun Network Filesystem (NFS) protocol provides transparent remote
+access to shared filesystems over local area networks. The NFS
+protocol is designed to be machine, operating system, network architecture,
+and transport protocol independent. This independence is
+achieved through the use of Remote Procedure Call (RPC) primitives
+built on top of an External Data Representation (XDR). Implementations
+exist for a variety of machines, from personal computers to
+supercomputers.
+.LP
+The supporting mount protocol allows the server to hand out remote
+access privileges to a restricted set of clients. It performs the
+operating system-specific functions that allow, for example, to
+attach remote directory trees to some local file system.
+.NH 2
+\&Remote Procedure Call
+.IX "Remote Procedure Call"
+.LP
+Sun's remote procedure call specification provides a procedure-
+oriented interface to remote services. Each server supplies a
+program that is a set of procedures. NFS is one such "program".
+The combination of host address, program number, and procedure
+number specifies one remote service procedure. RPC does not depend
+on services provided by specific protocols, so it can be used with
+any underlying transport protocol. See the
+.I "Remote Procedure Calls: Protocol Specification"
+chapter of this manual.
+.NH 2
+\&External Data Representation
+.IX "External Data Representation"
+.LP
+The External Data Representation (XDR) standard provides a common
+way of representing a set of data types over a network.
+The NFS
+Protocol Specification is written using the RPC data description
+language.
+For more information, see the
+.I " External Data Representation Standard: Protocol Specification."
+Sun provides implementations of XDR and
+RPC, but NFS does not require their use. Any software that
+provides equivalent functionality can be used, and if the encoding
+is exactly the same it can interoperate with other implementations
+of NFS.
+.NH 2
+\&Stateless Servers
+.IX "stateless servers"
+.IX servers stateless
+.LP
+The NFS protocol is stateless. That is, a server does not need to
+maintain any extra state information about any of its clients in
+order to function correctly. Stateless servers have a distinct
+advantage over stateful servers in the event of a failure. With
+stateless servers, a client need only retry a request until the
+server responds; it does not even need to know that the server has
+crashed, or the network temporarily went down. The client of a
+stateful server, on the other hand, needs to either detect a server
+crash and rebuild the server's state when it comes back up, or
+cause client operations to fail.
+.LP
+This may not sound like an important issue, but it affects the
+protocol in some unexpected ways. We feel that it is worth a bit
+of extra complexity in the protocol to be able to write very simple
+servers that do not require fancy crash recovery.
+.LP
+On the other hand, NFS deals with objects such as files and
+directories that inherently have state -- what good would a file be
+if it did not keep its contents intact? The goal is to not
+introduce any extra state in the protocol itself. Another way to
+simplify recovery is by making operations "idempotent" whenever
+possible (so that they can potentially be repeated).
+.NH 1
+\&NFS Protocol Definition
+.IX NFS "protocol definition"
+.IX NFS protocol
+.LP
+Servers have been known to change over time, and so can the
+protocol that they use. So RPC provides a version number with each
+RPC request. This RFC describes version two of the NFS protocol.
+Even in the second version, there are various obsolete procedures
+and parameters, which will be removed in later versions. An RFC
+for version three of the NFS protocol is currently under
+preparation.
+.NH 2
+\&File System Model
+.IX filesystem model
+.LP
+NFS assumes a file system that is hierarchical, with directories as
+all but the bottom-level files. Each entry in a directory (file,
+directory, device, etc.) has a string name. Different operating
+systems may have restrictions on the depth of the tree or the names
+used, as well as using different syntax to represent the "pathname",
+which is the concatenation of all the "components" (directory and
+file names) in the name. A "file system" is a tree on a single
+server (usually a single disk or physical partition) with a specified
+"root". Some operating systems provide a "mount" operation to make
+all file systems appear as a single tree, while others maintain a
+"forest" of file systems. Files are unstructured streams of
+uninterpreted bytes. Version 3 of NFS uses a slightly more general
+file system model.
+.LP
+NFS looks up one component of a pathname at a time. It may not be
+obvious why it does not just take the whole pathname, traipse down
+the directories, and return a file handle when it is done. There are
+several good reasons not to do this. First, pathnames need
+separators between the directory components, and different operating
+systems use different separators. We could define a Network Standard
+Pathname Representation, but then every pathname would have to be
+parsed and converted at each end. Other issues are discussed in
+\fINFS Implementation Issues\fP below.
+.LP
+Although files and directories are similar objects in many ways,
+different procedures are used to read directories and files. This
+provides a network standard format for representing directories. The
+same argument as above could have been used to justify a procedure
+that returns only one directory entry per call. The problem is
+efficiency. Directories can contain many entries, and a remote call
+to return each would be just too slow.
+.NH 2
+\&RPC Information
+.IX NFS "RPC information"
+.IP \fIAuthentication\fP
+The NFS service uses
+.I AUTH_UNIX ,
+.I AUTH_DES ,
+or
+.I AUTH_SHORT
+style
+authentication, except in the NULL procedure where
+.I AUTH_NONE
+is also allowed.
+.IP "\fITransport Protocols\fP"
+NFS currently is supported on UDP/IP only.
+.IP "\fIPort Number\fP"
+The NFS protocol currently uses the UDP port number 2049. This is
+not an officially assigned port, so later versions of the protocol
+use the \*QPortmapping\*U facility of RPC.
+.NH 2
+\&Sizes of XDR Structures
+.IX "XDR structure sizes"
+.LP
+These are the sizes, given in decimal bytes, of various XDR
+structures used in the protocol:
+.DS
+/* \fIThe maximum number of bytes of data in a READ or WRITE request\fP */
+const MAXDATA = 8192;
+
+/* \fIThe maximum number of bytes in a pathname argument\fP */
+const MAXPATHLEN = 1024;
+
+/* \fIThe maximum number of bytes in a file name argument\fP */
+const MAXNAMLEN = 255;
+
+/* \fIThe size in bytes of the opaque "cookie" passed by READDIR\fP */
+const COOKIESIZE = 4;
+
+/* \fIThe size in bytes of the opaque file handle\fP */
+const FHSIZE = 32;
+.DE
+.NH 2
+\&Basic Data Types
+.IX "NFS data types"
+.IX NFS "basic data types"
+.LP
+The following XDR definitions are basic structures and types used
+in other structures described further on.
+.KS
+.NH 3
+\&stat
+.IX "NFS data types" stat "" \fIstat\fP
+.DS
+enum stat {
+ NFS_OK = 0,
+ NFSERR_PERM=1,
+ NFSERR_NOENT=2,
+ NFSERR_IO=5,
+ NFSERR_NXIO=6,
+ NFSERR_ACCES=13,
+ NFSERR_EXIST=17,
+ NFSERR_NODEV=19,
+ NFSERR_NOTDIR=20,
+ NFSERR_ISDIR=21,
+ NFSERR_FBIG=27,
+ NFSERR_NOSPC=28,
+ NFSERR_ROFS=30,
+ NFSERR_NAMETOOLONG=63,
+ NFSERR_NOTEMPTY=66,
+ NFSERR_DQUOT=69,
+ NFSERR_STALE=70,
+ NFSERR_WFLUSH=99
+};
+.DE
+.KE
+.LP
+The
+.I stat
+type is returned with every procedure's results. A
+value of
+.I NFS_OK
+indicates that the call completed successfully and
+the results are valid. The other values indicate some kind of
+error occurred on the server side during the servicing of the
+procedure. The error values are derived from UNIX error numbers.
+.IP \fBNFSERR_PERM\fP:
+Not owner. The caller does not have correct ownership
+to perform the requested operation.
+.IP \fBNFSERR_NOENT\fP:
+No such file or directory. The file or directory
+specified does not exist.
+.IP \fBNFSERR_IO\fP:
+Some sort of hard error occurred when the operation was
+in progress. This could be a disk error, for example.
+.IP \fBNFSERR_NXIO\fP:
+No such device or address.
+.IP \fBNFSERR_ACCES\fP:
+Permission denied. The caller does not have the
+correct permission to perform the requested operation.
+.IP \fBNFSERR_EXIST\fP:
+File exists. The file specified already exists.
+.IP \fBNFSERR_NODEV\fP:
+No such device.
+.IP \fBNFSERR_NOTDIR\fP:
+Not a directory. The caller specified a
+non-directory in a directory operation.
+.IP \fBNFSERR_ISDIR\fP:
+Is a directory. The caller specified a directory in
+a non- directory operation.
+.IP \fBNFSERR_FBIG\fP:
+File too large. The operation caused a file to grow
+beyond the server's limit.
+.IP \fBNFSERR_NOSPC\fP:
+No space left on device. The operation caused the
+server's filesystem to reach its limit.
+.IP \fBNFSERR_ROFS\fP:
+Read-only filesystem. Write attempted on a read-only filesystem.
+.IP \fBNFSERR_NAMETOOLONG\fP:
+File name too long. The file name in an operation was too long.
+.IP \fBNFSERR_NOTEMPTY\fP:
+Directory not empty. Attempted to remove a
+directory that was not empty.
+.IP \fBNFSERR_DQUOT\fP:
+Disk quota exceeded. The client's disk quota on the
+server has been exceeded.
+.IP \fBNFSERR_STALE\fP:
+The "fhandle" given in the arguments was invalid.
+That is, the file referred to by that file handle no longer exists,
+or access to it has been revoked.
+.IP \fBNFSERR_WFLUSH\fP:
+The server's write cache used in the
+.I WRITECACHE
+call got flushed to disk.
+.LP
+.KS
+.NH 3
+\&ftype
+.IX "NFS data types" ftype "" \fIftype\fP
+.DS
+enum ftype {
+ NFNON = 0,
+ NFREG = 1,
+ NFDIR = 2,
+ NFBLK = 3,
+ NFCHR = 4,
+ NFLNK = 5
+};
+.DE
+.KE
+The enumeration
+.I ftype
+gives the type of a file. The type
+.I NFNON
+indicates a non-file,
+.I NFREG
+is a regular file,
+.I NFDIR
+is a directory,
+.I NFBLK
+is a block-special device,
+.I NFCHR
+is a character-special device, and
+.I NFLNK
+is a symbolic link.
+.KS
+.NH 3
+\&fhandle
+.IX "NFS data types" fhandle "" \fIfhandle\fP
+.DS
+typedef opaque fhandle[FHSIZE];
+.DE
+.KE
+The
+.I fhandle
+is the file handle passed between the server and the client.
+All file operations are done using file handles to refer to a file or
+directory. The file handle can contain whatever information the server
+needs to distinguish an individual file.
+.KS
+.NH 3
+\&timeval
+.IX "NFS data types" timeval "" \fItimeval\fP
+.DS
+struct timeval {
+ unsigned int seconds;
+ unsigned int useconds;
+};
+.DE
+.KE
+The
+.I timeval
+structure is the number of seconds and microseconds
+since midnight January 1, 1970, Greenwich Mean Time. It is used to
+pass time and date information.
+.KS
+.NH 3
+\&fattr
+.IX "NFS data types" fattr "" \fIfattr\fP
+.DS
+struct fattr {
+ ftype type;
+ unsigned int mode;
+ unsigned int nlink;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int size;
+ unsigned int blocksize;
+ unsigned int rdev;
+ unsigned int blocks;
+ unsigned int fsid;
+ unsigned int fileid;
+ timeval atime;
+ timeval mtime;
+ timeval ctime;
+};
+.DE
+.KE
+The
+.I fattr
+structure contains the attributes of a file; "type" is the type of
+the file; "nlink" is the number of hard links to the file (the number
+of different names for the same file); "uid" is the user
+identification number of the owner of the file; "gid" is the group
+identification number of the group of the file; "size" is the size in
+bytes of the file; "blocksize" is the size in bytes of a block of the
+file; "rdev" is the device number of the file if it is type
+.I NFCHR
+or
+.I NFBLK ;
+"blocks" is the number of blocks the file takes up on disk; "fsid" is
+the file system identifier for the filesystem containing the file;
+"fileid" is a number that uniquely identifies the file within its
+filesystem; "atime" is the time when the file was last accessed for
+either read or write; "mtime" is the time when the file data was last
+modified (written); and "ctime" is the time when the status of the
+file was last changed. Writing to the file also changes "ctime" if
+the size of the file changes.
+.LP
+"mode" is the access mode encoded as a set of bits. Notice that the
+file type is specified both in the mode bits and in the file type.
+This is really a bug in the protocol and will be fixed in future
+versions. The descriptions given below specify the bit positions
+using octal numbers.
+.TS
+box tab (&) ;
+cfI cfI
+lfL l .
+Bit&Description
+_
+0040000&This is a directory; "type" field should be NFDIR.
+0020000&This is a character special file; "type" field should be NFCHR.
+0060000&This is a block special file; "type" field should be NFBLK.
+0100000&This is a regular file; "type" field should be NFREG.
+0120000&This is a symbolic link file; "type" field should be NFLNK.
+0140000&This is a named socket; "type" field should be NFNON.
+0004000&Set user id on execution.
+0002000&Set group id on execution.
+0001000&Save swapped text even after use.
+0000400&Read permission for owner.
+0000200&Write permission for owner.
+0000100&Execute and search permission for owner.
+0000040&Read permission for group.
+0000020&Write permission for group.
+0000010&Execute and search permission for group.
+0000004&Read permission for others.
+0000002&Write permission for others.
+0000001&Execute and search permission for others.
+.TE
+.KS
+Notes:
+.IP
+The bits are the same as the mode bits returned by the
+.I stat(2)
+system call in the UNIX system. The file type is specified both in
+the mode bits and in the file type. This is fixed in future
+versions.
+.IP
+The "rdev" field in the attributes structure is an operating system
+specific device specifier. It will be removed and generalized in
+the next revision of the protocol.
+.KE
+.LP
+.KS
+.NH 3
+\&sattr
+.IX "NFS data types" sattr "" \fIsattr\fP
+.DS
+struct sattr {
+ unsigned int mode;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int size;
+ timeval atime;
+ timeval mtime;
+};
+.DE
+.KE
+The
+.I sattr
+structure contains the file attributes which can be set
+from the client. The fields are the same as for
+.I fattr
+above. A "size" of zero means the file should be truncated.
+A value of -1 indicates a field that should be ignored.
+.LP
+.KS
+.NH 3
+\&filename
+.IX "NFS data types" filename "" \fIfilename\fP
+.DS
+typedef string filename<MAXNAMLEN>;
+.DE
+.KE
+The type
+.I filename
+is used for passing file names or pathname components.
+.LP
+.KS
+.NH 3
+\&path
+.IX "NFS data types" path "" \fIpath\fP
+.DS
+typedef string path<MAXPATHLEN>;
+.DE
+.KE
+The type
+.I path
+is a pathname. The server considers it as a string
+with no internal structure, but to the client it is the name of a
+node in a filesystem tree.
+.LP
+.KS
+.NH 3
+\&attrstat
+.IX "NFS data types" attrstat "" \fIattrstat\fP
+.DS
+union attrstat switch (stat status) {
+ case NFS_OK:
+ fattr attributes;
+ default:
+ void;
+};
+.DE
+.KE
+The
+.I attrstat
+structure is a common procedure result. It contains
+a "status" and, if the call succeeded, it also contains the
+attributes of the file on which the operation was done.
+.LP
+.KS
+.NH 3
+\&diropargs
+.IX "NFS data types" diropargs "" \fIdiropargs\fP
+.DS
+struct diropargs {
+ fhandle dir;
+ filename name;
+};
+.DE
+.KE
+The
+.I diropargs
+structure is used in directory operations. The
+"fhandle" "dir" is the directory in which to find the file "name".
+A directory operation is one in which the directory is affected.
+.LP
+.KS
+.NH 3
+\&diropres
+.IX "NFS data types" diropres "" \fIdiropres\fP
+.DS
+union diropres switch (stat status) {
+ case NFS_OK:
+ struct {
+ fhandle file;
+ fattr attributes;
+ } diropok;
+ default:
+ void;
+};
+.DE
+.KE
+The results of a directory operation are returned in a
+.I diropres
+structure. If the call succeeded, a new file handle "file" and the
+"attributes" associated with that file are returned along with the
+"status".
+.NH 2
+\&Server Procedures
+.IX "NFS server procedures" "" "" "" PAGE MAJOR
+.LP
+The protocol definition is given as a set of procedures with
+arguments and results defined using the RPC language. A brief
+description of the function of each procedure should provide enough
+information to allow implementation.
+.LP
+All of the procedures in the NFS protocol are assumed to be
+synchronous. When a procedure returns to the client, the client
+can assume that the operation has completed and any data associated
+with the request is now on stable storage. For example, a client
+.I WRITE
+request may cause the server to update data blocks,
+filesystem information blocks (such as indirect blocks), and file
+attribute information (size and modify times). When the
+.I WRITE
+returns to the client, it can assume that the write is safe, even
+in case of a server crash, and it can discard the data written.
+This is a very important part of the statelessness of the server.
+If the server waited to flush data from remote requests, the client
+would have to save those requests so that it could resend them in
+case of a server crash.
+.ie t .DS
+.el .DS L
+
+.ft I
+/*
+* Remote file service routines
+*/
+.ft CW
+program NFS_PROGRAM {
+ version NFS_VERSION {
+ void NFSPROC_NULL(void) = 0;
+ attrstat NFSPROC_GETATTR(fhandle) = 1;
+ attrstat NFSPROC_SETATTR(sattrargs) = 2;
+ void NFSPROC_ROOT(void) = 3;
+ diropres NFSPROC_LOOKUP(diropargs) = 4;
+ readlinkres NFSPROC_READLINK(fhandle) = 5;
+ readres NFSPROC_READ(readargs) = 6;
+ void NFSPROC_WRITECACHE(void) = 7;
+ attrstat NFSPROC_WRITE(writeargs) = 8;
+ diropres NFSPROC_CREATE(createargs) = 9;
+ stat NFSPROC_REMOVE(diropargs) = 10;
+ stat NFSPROC_RENAME(renameargs) = 11;
+ stat NFSPROC_LINK(linkargs) = 12;
+ stat NFSPROC_SYMLINK(symlinkargs) = 13;
+ diropres NFSPROC_MKDIR(createargs) = 14;
+ stat NFSPROC_RMDIR(diropargs) = 15;
+ readdirres NFSPROC_READDIR(readdirargs) = 16;
+ statfsres NFSPROC_STATFS(fhandle) = 17;
+ } = 2;
+} = 100003;
+.DE
+.KS
+.NH 3
+\&Do Nothing
+.IX "NFS server procedures" NFSPROC_NULL() "" \fINFSPROC_NULL()\fP
+.DS
+void
+NFSPROC_NULL(void) = 0;
+.DE
+.KE
+This procedure does no work. It is made available in all RPC
+services to allow server response testing and timing.
+.KS
+.NH 3
+\&Get File Attributes
+.IX "NFS server procedures" NFSPROC_GETATTR() "" \fINFSPROC_GETATTR()\fP
+.DS
+attrstat
+NFSPROC_GETATTR (fhandle) = 1;
+.DE
+.KE
+If the reply status is
+.I NFS_OK ,
+then the reply attributes contains
+the attributes for the file given by the input fhandle.
+.KS
+.NH 3
+\&Set File Attributes
+.IX "NFS server procedures" NFSPROC_SETATTR() "" \fINFSPROC_SETATTR()\fP
+.DS
+struct sattrargs {
+ fhandle file;
+ sattr attributes;
+ };
+
+attrstat
+NFSPROC_SETATTR (sattrargs) = 2;
+.DE
+.KE
+The "attributes" argument contains fields which are either -1 or
+are the new value for the attributes of "file". If the reply
+status is
+.I NFS_OK ,
+then the reply attributes have the attributes of
+the file after the "SETATTR" operation has completed.
+.LP
+Note: The use of -1 to indicate an unused field in "attributes" is
+changed in the next version of the protocol.
+.KS
+.NH 3
+\&Get Filesystem Root
+.IX "NFS server procedures" NFSPROC_ROOT "" \fINFSPROC_ROOT\fP
+.DS
+void
+NFSPROC_ROOT(void) = 3;
+.DE
+.KE
+Obsolete. This procedure is no longer used because finding the
+root file handle of a filesystem requires moving pathnames between
+client and server. To do this right we would have to define a
+network standard representation of pathnames. Instead, the
+function of looking up the root file handle is done by the
+.I MNTPROC_MNT()
+procedure. (See the
+.I "Mount Protocol Definition"
+later in this chapter for details).
+.KS
+.NH 3
+\&Look Up File Name
+.IX "NFS server procedures" NFSPROC_LOOKUP() "" \fINFSPROC_LOOKUP()\fP
+.DS
+diropres
+NFSPROC_LOOKUP(diropargs) = 4;
+.DE
+.KE
+If the reply "status" is
+.I NFS_OK ,
+then the reply "file" and reply
+"attributes" are the file handle and attributes for the file "name"
+in the directory given by "dir" in the argument.
+.KS
+.NH 3
+\&Read From Symbolic Link
+.IX "NFS server procedures" NFSPROC_READLINK() "" \fINFSPROC_READLINK()\fP
+.DS
+union readlinkres switch (stat status) {
+ case NFS_OK:
+ path data;
+ default:
+ void;
+};
+
+readlinkres
+NFSPROC_READLINK(fhandle) = 5;
+.DE
+.KE
+If "status" has the value
+.I NFS_OK ,
+then the reply "data" is the data in
+the symbolic link given by the file referred to by the fhandle argument.
+.LP
+Note: since NFS always parses pathnames on the client, the
+pathname in a symbolic link may mean something different (or be
+meaningless) on a different client or on the server if a different
+pathname syntax is used.
+.KS
+.NH 3
+\&Read From File
+.IX "NFS server procedures" NFSPROC_READ "" \fINFSPROC_READ\fP
+.DS
+struct readargs {
+ fhandle file;
+ unsigned offset;
+ unsigned count;
+ unsigned totalcount;
+};
+
+union readres switch (stat status) {
+ case NFS_OK:
+ fattr attributes;
+ opaque data<NFS_MAXDATA>;
+ default:
+ void;
+};
+
+readres
+NFSPROC_READ(readargs) = 6;
+.DE
+.KE
+Returns up to "count" bytes of "data" from the file given by
+"file", starting at "offset" bytes from the beginning of the file.
+The first byte of the file is at offset zero. The file attributes
+after the read takes place are returned in "attributes".
+.LP
+Note: The argument "totalcount" is unused, and is removed in the
+next protocol revision.
+.KS
+.NH 3
+\&Write to Cache
+.IX "NFS server procedures" NFSPROC_WRITECACHE() "" \fINFSPROC_WRITECACHE()\fP
+.DS
+void
+NFSPROC_WRITECACHE(void) = 7;
+.DE
+.KE
+To be used in the next protocol revision.
+.KS
+.NH 3
+\&Write to File
+.IX "NFS server procedures" NFSPROC_WRITE() "" \fINFSPROC_WRITE()\fP
+.DS
+struct writeargs {
+ fhandle file;
+ unsigned beginoffset;
+ unsigned offset;
+ unsigned totalcount;
+ opaque data<NFS_MAXDATA>;
+};
+
+attrstat
+NFSPROC_WRITE(writeargs) = 8;
+.DE
+.KE
+Writes "data" beginning "offset" bytes from the beginning of
+"file". The first byte of the file is at offset zero. If the
+reply "status" is NFS_OK, then the reply "attributes" contains the
+attributes of the file after the write has completed. The write
+operation is atomic. Data from this call to
+.I WRITE
+will not be mixed with data from another client's calls.
+.LP
+Note: The arguments "beginoffset" and "totalcount" are ignored and
+are removed in the next protocol revision.
+.KS
+.NH 3
+\&Create File
+.IX "NFS server procedures" NFSPROC_CREATE() "" \fINFSPROC_CREATE()\fP
+.DS
+struct createargs {
+ diropargs where;
+ sattr attributes;
+};
+
+diropres
+NFSPROC_CREATE(createargs) = 9;
+.DE
+.KE
+The file "name" is created in the directory given by "dir". The
+initial attributes of the new file are given by "attributes". A
+reply "status" of NFS_OK indicates that the file was created, and
+reply "file" and reply "attributes" are its file handle and
+attributes. Any other reply "status" means that the operation
+failed and no file was created.
+.LP
+Note: This routine should pass an exclusive create flag, meaning
+"create the file only if it is not already there".
+.KS
+.NH 3
+\&Remove File
+.IX "NFS server procedures" NFSPROC_REMOVE() "" \fINFSPROC_REMOVE()\fP
+.DS
+stat
+NFSPROC_REMOVE(diropargs) = 10;
+.DE
+.KE
+The file "name" is removed from the directory given by "dir". A
+reply of NFS_OK means the directory entry was removed.
+.LP
+Note: possibly non-idempotent operation.
+.KS
+.NH 3
+\&Rename File
+.IX "NFS server procedures" NFSPROC_RENAME() "" \fINFSPROC_RENAME()\fP
+.DS
+struct renameargs {
+ diropargs from;
+ diropargs to;
+};
+
+stat
+NFSPROC_RENAME(renameargs) = 11;
+.DE
+.KE
+The existing file "from.name" in the directory given by "from.dir"
+is renamed to "to.name" in the directory given by "to.dir". If the
+reply is
+.I NFS_OK ,
+the file was renamed. The
+RENAME
+operation is
+atomic on the server; it cannot be interrupted in the middle.
+.LP
+Note: possibly non-idempotent operation.
+.KS
+.NH 3
+\&Create Link to File
+.IX "NFS server procedures" NFSPROC_LINK() "" \fINFSPROC_LINK()\fP
+.DS
+struct linkargs {
+ fhandle from;
+ diropargs to;
+};
+
+stat
+NFSPROC_LINK(linkargs) = 12;
+.DE
+.KE
+Creates the file "to.name" in the directory given by "to.dir",
+which is a hard link to the existing file given by "from". If the
+return value is
+.I NFS_OK ,
+a link was created. Any other return value
+indicates an error, and the link was not created.
+.LP
+A hard link should have the property that changes to either of the
+linked files are reflected in both files. When a hard link is made
+to a file, the attributes for the file should have a value for
+"nlink" that is one greater than the value before the link.
+.LP
+Note: possibly non-idempotent operation.
+.KS
+.NH 3
+\&Create Symbolic Link
+.IX "NFS server procedures" NFSPROC_SYMLINK() "" \fINFSPROC_SYMLINK()\fP
+.DS
+struct symlinkargs {
+ diropargs from;
+ path to;
+ sattr attributes;
+};
+
+stat
+NFSPROC_SYMLINK(symlinkargs) = 13;
+.DE
+.KE
+Creates the file "from.name" with ftype
+.I NFLNK
+in the directory
+given by "from.dir". The new file contains the pathname "to" and
+has initial attributes given by "attributes". If the return value
+is
+.I NFS_OK ,
+a link was created. Any other return value indicates an
+error, and the link was not created.
+.LP
+A symbolic link is a pointer to another file. The name given in
+"to" is not interpreted by the server, only stored in the newly
+created file. When the client references a file that is a symbolic
+link, the contents of the symbolic link are normally transparently
+reinterpreted as a pathname to substitute. A
+.I READLINK
+operation returns the data to the client for interpretation.
+.LP
+Note: On UNIX servers the attributes are never used, since
+symbolic links always have mode 0777.
+.KS
+.NH 3
+\&Create Directory
+.IX "NFS server procedures" NFSPROC_MKDIR() "" \fINFSPROC_MKDIR()\fP
+.DS
+diropres
+NFSPROC_MKDIR (createargs) = 14;
+.DE
+.KE
+The new directory "where.name" is created in the directory given by
+"where.dir". The initial attributes of the new directory are given
+by "attributes". A reply "status" of NFS_OK indicates that the new
+directory was created, and reply "file" and reply "attributes" are
+its file handle and attributes. Any other reply "status" means
+that the operation failed and no directory was created.
+.LP
+Note: possibly non-idempotent operation.
+.KS
+.NH 3
+\&Remove Directory
+.IX "NFS server procedures" NFSPROC_RMDIR() "" \fINFSPROC_RMDIR()\fP
+.DS
+stat
+NFSPROC_RMDIR(diropargs) = 15;
+.DE
+.KE
+The existing empty directory "name" in the directory given by "dir"
+is removed. If the reply is
+.I NFS_OK ,
+the directory was removed.
+.LP
+Note: possibly non-idempotent operation.
+.KS
+.NH 3
+\&Read From Directory
+.IX "NFS server procedures" NFSPROC_READDIR() "" \fINFSPROC_READDIR()\fP
+.DS
+struct readdirargs {
+ fhandle dir;
+ nfscookie cookie;
+ unsigned count;
+};
+
+struct entry {
+ unsigned fileid;
+ filename name;
+ nfscookie cookie;
+ entry *nextentry;
+};
+
+union readdirres switch (stat status) {
+ case NFS_OK:
+ struct {
+ entry *entries;
+ bool eof;
+ } readdirok;
+ default:
+ void;
+};
+
+readdirres
+NFSPROC_READDIR (readdirargs) = 16;
+.DE
+.KE
+Returns a variable number of directory entries, with a total size
+of up to "count" bytes, from the directory given by "dir". If the
+returned value of "status" is
+.I NFS_OK ,
+then it is followed by a
+variable number of "entry"s. Each "entry" contains a "fileid"
+which consists of a unique number to identify the file within a
+filesystem, the "name" of the file, and a "cookie" which is an
+opaque pointer to the next entry in the directory. The cookie is
+used in the next
+.I READDIR
+call to get more entries starting at a
+given point in the directory. The special cookie zero (all bits
+zero) can be used to get the entries starting at the beginning of
+the directory. The "fileid" field should be the same number as the
+"fileid" in the the attributes of the file. (See the
+.I "Basic Data Types"
+section.)
+The "eof" flag has a value of
+.I TRUE
+if there are no more entries in the directory.
+.KS
+.NH 3
+\&Get Filesystem Attributes
+.IX "NFS server procedures" NFSPROC_STATFS() "" \fINFSPROC_STATFS()\fP
+.DS
+union statfsres (stat status) {
+ case NFS_OK:
+ struct {
+ unsigned tsize;
+ unsigned bsize;
+ unsigned blocks;
+ unsigned bfree;
+ unsigned bavail;
+ } info;
+ default:
+ void;
+};
+
+statfsres
+NFSPROC_STATFS(fhandle) = 17;
+.DE
+.KE
+If the reply "status" is
+.I NFS_OK ,
+then the reply "info" gives the
+attributes for the filesystem that contains file referred to by the
+input fhandle. The attribute fields contain the following values:
+.IP tsize:
+The optimum transfer size of the server in bytes. This is
+the number of bytes the server would like to have in the
+data part of READ and WRITE requests.
+.IP bsize:
+The block size in bytes of the filesystem.
+.IP blocks:
+The total number of "bsize" blocks on the filesystem.
+.IP bfree:
+The number of free "bsize" blocks on the filesystem.
+.IP bavail:
+The number of "bsize" blocks available to non-privileged users.
+.LP
+Note: This call does not work well if a filesystem has variable
+size blocks.
+.NH 1
+\&NFS Implementation Issues
+.IX NFS implementation
+.LP
+The NFS protocol is designed to be operating system independent, but
+since this version was designed in a UNIX environment, many
+operations have semantics similar to the operations of the UNIX file
+system. This section discusses some of the implementation-specific
+semantic issues.
+.NH 2
+\&Server/Client Relationship
+.IX NFS "server/client relationship"
+.LP
+The NFS protocol is designed to allow servers to be as simple and
+general as possible. Sometimes the simplicity of the server can be a
+problem, if the client wants to implement complicated filesystem
+semantics.
+.LP
+For example, some operating systems allow removal of open files. A
+process can open a file and, while it is open, remove it from the
+directory. The file can be read and written as long as the process
+keeps it open, even though the file has no name in the filesystem.
+It is impossible for a stateless server to implement these semantics.
+The client can do some tricks such as renaming the file on remove,
+and only removing it on close. We believe that the server provides
+enough functionality to implement most file system semantics on the
+client.
+.LP
+Every NFS client can also potentially be a server, and remote and
+local mounted filesystems can be freely intermixed. This leads to
+some interesting problems when a client travels down the directory
+tree of a remote filesystem and reaches the mount point on the server
+for another remote filesystem. Allowing the server to follow the
+second remote mount would require loop detection, server lookup, and
+user revalidation. Instead, we decided not to let clients cross a
+server's mount point. When a client does a LOOKUP on a directory on
+which the server has mounted a filesystem, the client sees the
+underlying directory instead of the mounted directory. A client can
+do remote mounts that match the server's mount points to maintain the
+server's view.
+.LP
+.NH 2
+\&Pathname Interpretation
+.IX NFS "pathname interpretation"
+.LP
+There are a few complications to the rule that pathnames are always
+parsed on the client. For example, symbolic links could have
+different interpretations on different clients. Another common
+problem for non-UNIX implementations is the special interpretation of
+the pathname ".." to mean the parent of a given directory. The next
+revision of the protocol uses an explicit flag to indicate the parent
+instead.
+.NH 2
+\&Permission Issues
+.IX NFS "permission issues"
+.LP
+The NFS protocol, strictly speaking, does not define the permission
+checking used by servers. However, it is expected that a server
+will do normal operating system permission checking using
+.I AUTH_UNIX
+style authentication as the basis of its protection mechanism. The
+server gets the client's effective "uid", effective "gid", and groups
+on each call and uses them to check permission. There are various
+problems with this method that can been resolved in interesting ways.
+.LP
+Using "uid" and "gid" implies that the client and server share the
+same "uid" list. Every server and client pair must have the same
+mapping from user to "uid" and from group to "gid". Since every
+client can also be a server, this tends to imply that the whole
+network shares the same "uid/gid" space.
+.I AUTH_DES
+(and the next
+revision of the NFS protocol) uses string names instead of numbers,
+but there are still complex problems to be solved.
+.LP
+Another problem arises due to the usually stateful open operation.
+Most operating systems check permission at open time, and then check
+that the file is open on each read and write request. With stateless
+servers, the server has no idea that the file is open and must do
+permission checking on each read and write call. On a local
+filesystem, a user can open a file and then change the permissions so
+that no one is allowed to touch it, but will still be able to write
+to the file because it is open. On a remote filesystem, by contrast,
+the write would fail. To get around this problem, the server's
+permission checking algorithm should allow the owner of a file to
+access it regardless of the permission setting.
+.LP
+A similar problem has to do with paging in from a file over the
+network. The operating system usually checks for execute permission
+before opening a file for demand paging, and then reads blocks from
+the open file. The file may not have read permission, but after it
+is opened it doesn't matter. An NFS server can not tell the
+difference between a normal file read and a demand page-in read. To
+make this work, the server allows reading of files if the "uid" given
+in the call has execute or read permission on the file.
+.LP
+In most operating systems, a particular user (on the user ID zero)
+has access to all files no matter what permission and ownership they
+have. This "super-user" permission may not be allowed on the server,
+since anyone who can become super-user on their workstation could
+gain access to all remote files. The UNIX server by default maps
+user id 0 to -2 before doing its access checking. This works except
+for NFS root filesystems, where super-user access cannot be avoided.
+.NH 2
+\&Setting RPC Parameters
+.IX NFS "setting RPC parameters"
+.LP
+Various file system parameters and options should be set at mount
+time. The mount protocol is described in the appendix below. For
+example, "Soft" mounts as well as "Hard" mounts are usually both
+provided. Soft mounted file systems return errors when RPC
+operations fail (after a given number of optional retransmissions),
+while hard mounted file systems continue to retransmit forever.
+Clients and servers may need to keep caches of recent operations to
+help avoid problems with non-idempotent operations.
+.NH 1
+\&Mount Protocol Definition
+.IX "mount protocol" "" "" "" PAGE MAJOR
+.sp 1
+.NH 2
+\&Introduction
+.IX "mount protocol" introduction
+.LP
+The mount protocol is separate from, but related to, the NFS
+protocol. It provides operating system specific services to get the
+NFS off the ground -- looking up server path names, validating user
+identity, and checking access permissions. Clients use the mount
+protocol to get the first file handle, which allows them entry into a
+remote filesystem.
+.LP
+The mount protocol is kept separate from the NFS protocol to make it
+easy to plug in new access checking and validation methods without
+changing the NFS server protocol.
+.LP
+Notice that the protocol definition implies stateful servers because
+the server maintains a list of client's mount requests. The mount
+list information is not critical for the correct functioning of
+either the client or the server. It is intended for advisory use
+only, for example, to warn possible clients when a server is going
+down.
+.LP
+Version one of the mount protocol is used with version two of the NFS
+protocol. The only connecting point is the
+.I fhandle
+structure, which is the same for both protocols.
+.NH 2
+\&RPC Information
+.IX "mount protocol" "RPC information"
+.IP \fIAuthentication\fP
+The mount service uses
+.I AUTH_UNIX
+and
+.I AUTH_DES
+style authentication only.
+.IP "\fITransport Protocols\fP"
+The mount service is currently supported on UDP/IP only.
+.IP "\fIPort Number\fP"
+Consult the server's portmapper, described in the chapter
+.I "Remote Procedure Calls: Protocol Specification",
+to find the port number on which the mount service is registered.
+.NH 2
+\&Sizes of XDR Structures
+.IX "mount protocol" "XDR structure sizes"
+.LP
+These are the sizes, given in decimal bytes, of various XDR
+structures used in the protocol:
+.DS
+/* \fIThe maximum number of bytes in a pathname argument\fP */
+const MNTPATHLEN = 1024;
+
+/* \fIThe maximum number of bytes in a name argument\fP */
+const MNTNAMLEN = 255;
+
+/* \fIThe size in bytes of the opaque file handle\fP */
+const FHSIZE = 32;
+.DE
+.NH 2
+\&Basic Data Types
+.IX "mount protocol" "basic data types"
+.IX "mount data types"
+.LP
+This section presents the data types used by the mount protocol.
+In many cases they are similar to the types used in NFS.
+.KS
+.NH 3
+\&fhandle
+.IX "mount data types" fhandle "" \fIfhandle\fP
+.DS
+typedef opaque fhandle[FHSIZE];
+.DE
+.KE
+The type
+.I fhandle
+is the file handle that the server passes to the
+client. All file operations are done using file handles to refer
+to a file or directory. The file handle can contain whatever
+information the server needs to distinguish an individual file.
+.LP
+This is the same as the "fhandle" XDR definition in version 2 of
+the NFS protocol; see
+.I "Basic Data Types"
+in the definition of the NFS protocol, above.
+.KS
+.NH 3
+\&fhstatus
+.IX "mount data types" fhstatus "" \fIfhstatus\fP
+.DS
+union fhstatus switch (unsigned status) {
+ case 0:
+ fhandle directory;
+ default:
+ void;
+};
+.DE
+.KE
+The type
+.I fhstatus
+is a union. If a "status" of zero is returned,
+the call completed successfully, and a file handle for the
+"directory" follows. A non-zero status indicates some sort of
+error. In this case the status is a UNIX error number.
+.KS
+.NH 3
+\&dirpath
+.IX "mount data types" dirpath "" \fIdirpath\fP
+.DS
+typedef string dirpath<MNTPATHLEN>;
+.DE
+.KE
+The type
+.I dirpath
+is a server pathname of a directory.
+.KS
+.NH 3
+\&name
+.IX "mount data types" name "" \fIname\fP
+.DS
+typedef string name<MNTNAMLEN>;
+.DE
+.KE
+The type
+.I name
+is an arbitrary string used for various names.
+.NH 2
+\&Server Procedures
+.IX "mount server procedures"
+.LP
+The following sections define the RPC procedures supplied by a
+mount server.
+.ie t .DS
+.el .DS L
+.ft I
+/*
+* Protocol description for the mount program
+*/
+.ft CW
+
+program MOUNTPROG {
+.ft I
+/*
+* Version 1 of the mount protocol used with
+* version 2 of the NFS protocol.
+*/
+.ft CW
+ version MOUNTVERS {
+ void MOUNTPROC_NULL(void) = 0;
+ fhstatus MOUNTPROC_MNT(dirpath) = 1;
+ mountlist MOUNTPROC_DUMP(void) = 2;
+ void MOUNTPROC_UMNT(dirpath) = 3;
+ void MOUNTPROC_UMNTALL(void) = 4;
+ exportlist MOUNTPROC_EXPORT(void) = 5;
+ } = 1;
+} = 100005;
+.DE
+.KS
+.NH 3
+\&Do Nothing
+.IX "mount server procedures" MNTPROC_NULL() "" \fIMNTPROC_NULL()\fP
+.DS
+void
+MNTPROC_NULL(void) = 0;
+.DE
+.KE
+This procedure does no work. It is made available in all RPC
+services to allow server response testing and timing.
+.KS
+.NH 3
+\&Add Mount Entry
+.IX "mount server procedures" MNTPROC_MNT() "" \fIMNTPROC_MNT()\fP
+.DS
+fhstatus
+MNTPROC_MNT(dirpath) = 1;
+.DE
+.KE
+If the reply "status" is 0, then the reply "directory" contains the
+file handle for the directory "dirname". This file handle may be
+used in the NFS protocol. This procedure also adds a new entry to
+the mount list for this client mounting "dirname".
+.KS
+.NH 3
+\&Return Mount Entries
+.IX "mount server procedures" MNTPROC_DUMP() "" \fIMNTPROC_DUMP()\fP
+.DS
+struct *mountlist {
+ name hostname;
+ dirpath directory;
+ mountlist nextentry;
+};
+
+mountlist
+MNTPROC_DUMP(void) = 2;
+.DE
+.KE
+Returns the list of remote mounted filesystems. The "mountlist"
+contains one entry for each "hostname" and "directory" pair.
+.KS
+.NH 3
+\&Remove Mount Entry
+.IX "mount server procedures" MNTPROC_UMNT() "" \fIMNTPROC_UMNT()\fP
+.DS
+void
+MNTPROC_UMNT(dirpath) = 3;
+.DE
+.KE
+Removes the mount list entry for the input "dirpath".
+.KS
+.NH 3
+\&Remove All Mount Entries
+.IX "mount server procedures" MNTPROC_UMNTALL() "" \fIMNTPROC_UMNTALL()\fP
+.DS
+void
+MNTPROC_UMNTALL(void) = 4;
+.DE
+.KE
+Removes all of the mount list entries for this client.
+.KS
+.NH 3
+\&Return Export List
+.IX "mount server procedures" MNTPROC_EXPORT() "" \fIMNTPROC_EXPORT()\fP
+.DS
+struct *groups {
+ name grname;
+ groups grnext;
+};
+
+struct *exportlist {
+ dirpath filesys;
+ groups groups;
+ exportlist next;
+};
+
+exportlist
+MNTPROC_EXPORT(void) = 5;
+.DE
+.KE
+Returns a variable number of export list entries. Each entry
+contains a filesystem name and a list of groups that are allowed to
+import it. The filesystem name is in "filesys", and the group name
+is in the list "groups".
+.LP
+Note: The exportlist should contain
+more information about the status of the filesystem, such as a
+read-only flag.
diff --git a/lib/libc/rpc/PSD.doc/rpc.prog.ms b/lib/libc/rpc/PSD.doc/rpc.prog.ms
new file mode 100644
index 0000000..3b02447
--- /dev/null
+++ b/lib/libc/rpc/PSD.doc/rpc.prog.ms
@@ -0,0 +1,2684 @@
+.\"
+.\" Must use -- tbl and pic -- with this one
+.\"
+.\" @(#)rpc.prog.ms 2.3 88/08/11 4.0 RPCSRC
+.de BT
+.if \\n%=1 .tl ''- % -''
+..
+.IX "Network Programming" "" "" "" PAGE MAJOR
+.nr OF 0
+.ND
+.\" prevent excess underlining in nroff
+.if n .fp 2 R
+.OH 'Remote Procedure Call Programming Guide''Page %'
+.EH 'Page %''Remote Procedure Call Programming Guide'
+.SH
+\&Remote Procedure Call Programming Guide
+.nr OF 1
+.IX "RPC Programming Guide"
+.LP
+This document assumes a working knowledge of network theory. It is
+intended for programmers who wish to write network applications using
+remote procedure calls (explained below), and who want to understand
+the RPC mechanisms usually hidden by the
+.I rpcgen(1)
+protocol compiler.
+.I rpcgen
+is described in detail in the previous chapter, the
+.I "\fBrpcgen\fP \fIProgramming Guide\fP".
+.SH
+Note:
+.I
+.IX rpcgen "" \fIrpcgen\fP
+Before attempting to write a network application, or to convert an
+existing non-network application to run over the network, you may want to
+understand the material in this chapter. However, for most applications,
+you can circumvent the need to cope with the details presented here by using
+.I rpcgen .
+The
+.I "Generating XDR Routines"
+section of that chapter contains the complete source for a working RPC
+service\(ema remote directory listing service which uses
+.I rpcgen
+to generate XDR routines as well as client and server stubs.
+.LP
+.LP
+What are remote procedure calls? Simply put, they are the high-level
+communications paradigm used in the operating system.
+RPC presumes the existence of
+low-level networking mechanisms (such as TCP/IP and UDP/IP), and upon them
+it implements a logical client to server communications system designed
+specifically for the support of network applications. With RPC, the client
+makes a procedure call to send a data packet to the server. When the
+packet arrives, the server calls a dispatch routine, performs whatever
+service is requested, sends back the reply, and the procedure call returns
+to the client.
+.NH 0
+\&Layers of RPC
+.IX "layers of RPC"
+.IX "RPC" "layers"
+.LP
+The RPC interface can be seen as being divided into three layers.\**
+.FS
+For a complete specification of the routines in the remote procedure
+call Library, see the
+.I rpc(3N)
+manual page.
+.FE
+.LP
+.I "The Highest Layer:"
+.IX RPC "The Highest Layer"
+The highest layer is totally transparent to the operating system,
+machine and network upon which is is run. It's probably best to
+think of this level as a way of
+.I using
+RPC, rather than as
+a \fIpart of\fP RPC proper. Programmers who write RPC routines
+should (almost) always make this layer available to others by way
+of a simple C front end that entirely hides the networking.
+.LP
+To illustrate, at this level a program can simply make a call to
+.I rnusers (),
+a C routine which returns the number of users on a remote machine.
+The user is not explicitly aware of using RPC \(em they simply
+call a procedure, just as they would call
+.I malloc() .
+.LP
+.I "The Middle Layer:"
+.IX RPC "The Middle Layer"
+The middle layer is really \*QRPC proper.\*U Here, the user doesn't
+need to consider details about sockets, the UNIX system, or other low-level
+implementation mechanisms. They simply make remote procedure calls
+to routines on other machines. The selling point here is simplicity.
+It's this layer that allows RPC to pass the \*Qhello world\*U test \(em
+simple things should be simple. The middle-layer routines are used
+for most applications.
+.LP
+RPC calls are made with the system routines
+.I registerrpc()
+.I callrpc()
+and
+.I svc_run ().
+The first two of these are the most fundamental:
+.I registerrpc()
+obtains a unique system-wide procedure-identification number, and
+.I callrpc()
+actually executes a remote procedure call. At the middle level, a
+call to
+.I rnusers()
+is implemented by way of these two routines.
+.LP
+The middle layer is unfortunately rarely used in serious programming
+due to its inflexibility (simplicity). It does not allow timeout
+specifications or the choice of transport. It allows no UNIX
+process control or flexibility in case of errors. It doesn't support
+multiple kinds of call authentication. The programmer rarely needs
+all these kinds of control, but one or two of them is often necessary.
+.LP
+.I "The Lowest Layer:"
+.IX RPC "The Lowest Layer"
+The lowest layer does allow these details to be controlled by the
+programmer, and for that reason it is often necessary. Programs
+written at this level are also most efficient, but this is rarely a
+real issue \(em since RPC clients and servers rarely generate
+heavy network loads.
+.LP
+Although this document only discusses the interface to C,
+remote procedure calls can be made from any language.
+Even though this document discusses RPC
+when it is used to communicate
+between processes on different machines,
+it works just as well for communication
+between different processes on the same machine.
+.br
+.KS
+.NH 2
+\&The RPC Paradigm
+.IX RPC paradigm
+.LP
+Here is a diagram of the RPC paradigm:
+.LP
+\fBFigure 1-1\fI Network Communication with the Remote Reocedure Call\fR
+.LP
+.PS
+L1: arrow down 1i "client " rjust "program " rjust
+L2: line right 1.5i "\fIcallrpc\fP" "function"
+move up 1.5i; line dotted down 6i; move up 4.5i
+arrow right 1i
+L3: arrow down 1i "invoke " rjust "service " rjust
+L4: arrow right 1.5i "call" "service"
+L5: arrow down 1i " service" ljust " executes" ljust
+L6: arrow left 1.5i "\fIreturn\fP" "answer"
+L7: arrow down 1i "request " rjust "completed " rjust
+L8: line left 1i
+arrow left 1.5i "\fIreturn\fP" "reply"
+L9: arrow down 1i "program " rjust "continues " rjust
+line dashed down from L2 to L9
+line dashed down from L4 to L7
+line dashed up 1i from L3 "service " rjust "daemon " rjust
+arrow dashed down 1i from L8
+move right 1i from L3
+box invis "Machine B"
+move left 1.2i from L2; move down
+box invis "Machine A"
+.PE
+.KE
+.KS
+.NH 1
+\&Higher Layers of RPC
+.NH 2
+\&Highest Layer
+.IX "highest layer of RPC"
+.IX RPC "highest layer"
+.LP
+Imagine you're writing a program that needs to know
+how many users are logged into a remote machine.
+You can do this by calling the RPC library routine
+.I rnusers()
+as illustrated below:
+.ie t .DS
+.el .DS L
+.ft CW
+#include <stdio.h>
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int num;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: rnusers hostname\en");
+ exit(1);
+ }
+ if ((num = rnusers(argv[1])) < 0) {
+ fprintf(stderr, "error: rnusers\en");
+ exit(-1);
+ }
+ printf("%d users on %s\en", num, argv[1]);
+ exit(0);
+}
+.DE
+.KE
+RPC library routines such as
+.I rnusers()
+are in the RPC services library
+.I librpcsvc.a
+Thus, the program above should be compiled with
+.DS
+.ft CW
+% cc \fIprogram.c -lrpcsvc\fP
+.DE
+.I rnusers (),
+like the other RPC library routines, is documented in section 3R
+of the
+.I "System Interface Manual for the Sun Workstation" ,
+the same section which documents the standard Sun RPC services.
+.IX "RPC Services"
+See the
+.I intro(3R)
+manual page for an explanation of the documentation strategy
+for these services and their RPC protocols.
+.LP
+Here are some of the RPC service library routines available to the
+C programmer:
+.LP
+\fBTable 3-3\fI RPC Service Library Routines\RP
+.TS
+box tab (&) ;
+cfI cfI
+lfL l .
+Routine&Description
+_
+.sp.5
+rnusers&Return number of users on remote machine
+rusers&Return information about users on remote machine
+havedisk&Determine if remote machine has disk
+rstats&Get performance data from remote kernel
+rwall&Write to specified remote machines
+yppasswd&Update user password in Yellow Pages
+.TE
+.LP
+Other RPC services \(em for example
+.I ether()
+.I mount
+.I rquota()
+and
+.I spray
+\(em are not available to the C programmer as library routines.
+They do, however,
+have RPC program numbers so they can be invoked with
+.I callrpc()
+which will be discussed in the next section. Most of them also
+have compilable
+.I rpcgen(1)
+protocol description files. (The
+.I rpcgen
+protocol compiler radically simplifies the process of developing
+network applications.
+See the \fBrpcgen\fI Programming Guide\fR
+for detailed information about
+.I rpcgen
+and
+.I rpcgen
+protocol description files).
+.KS
+.NH 2
+\&Intermediate Layer
+.IX "intermediate layer of RPC"
+.IX "RPC" "intermediate layer"
+.LP
+The simplest interface, which explicitly makes RPC calls, uses the
+functions
+.I callrpc()
+and
+.I registerrpc()
+Using this method, the number of remote users can be gotten as follows:
+.ie t .DS
+.el .DS L
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <utmp.h>
+#include <rpcsvc/rusers.h>
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ unsigned long nusers;
+ int stat;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: nusers hostname\en");
+ exit(-1);
+ }
+ if (stat = callrpc(argv[1],
+ RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM,
+ xdr_void, 0, xdr_u_long, &nusers) != 0) {
+ clnt_perrno(stat);
+ exit(1);
+ }
+ printf("%d users on %s\en", nusers, argv[1]);
+ exit(0);
+}
+.DE
+.KE
+Each RPC procedure is uniquely defined by a program number,
+version number, and procedure number. The program number
+specifies a group of related remote procedures, each of
+which has a different procedure number. Each program also
+has a version number, so when a minor change is made to a
+remote service (adding a new procedure, for example), a new
+program number doesn't have to be assigned. When you want
+to call a procedure to find the number of remote users, you
+look up the appropriate program, version and procedure numbers
+in a manual, just as you look up the name of a memory allocator
+when you want to allocate memory.
+.LP
+The simplest way of making remote procedure calls is with the the RPC
+library routine
+.I callrpc()
+It has eight parameters. The first is the name of the remote server
+machine. The next three parameters are the program, version, and procedure
+numbers\(emtogether they identify the procedure to be called.
+The fifth and sixth parameters are an XDR filter and an argument to
+be encoded and passed to the remote procedure.
+The final two parameters are a filter for decoding the results
+returned by the remote procedure and a pointer to the place where
+the procedure's results are to be stored. Multiple arguments and
+results are handled by embedding them in structures. If
+.I callrpc()
+completes successfully, it returns zero; else it returns a nonzero
+value. The return codes (of type
+.IX "enum clnt_stat (in RPC programming)" "" "\fIenum clnt_stat\fP (in RPC programming)"
+cast into an integer) are found in
+.I <rpc/clnt.h> .
+.LP
+Since data types may be represented differently on different machines,
+.I callrpc()
+needs both the type of the RPC argument, as well as
+a pointer to the argument itself (and similarly for the result). For
+.I RUSERSPROC_NUM ,
+the return value is an
+.I "unsigned long"
+so
+.I callrpc()
+has
+.I xdr_u_long()
+as its first return parameter, which says
+that the result is of type
+.I "unsigned long"
+and
+.I &nusers
+as its second return parameter,
+which is a pointer to where the long result will be placed. Since
+.I RUSERSPROC_NUM
+takes no argument, the argument parameter of
+.I callrpc()
+is
+.I xdr_void ().
+.LP
+After trying several times to deliver a message, if
+.I callrpc()
+gets no answer, it returns with an error code.
+The delivery mechanism is UDP,
+which stands for User Datagram Protocol.
+Methods for adjusting the number of retries
+or for using a different protocol require you to use the lower
+layer of the RPC library, discussed later in this document.
+The remote server procedure
+corresponding to the above might look like this:
+.ie t .DS
+.el .DS L
+.ft CW
+.ft CW
+char *
+nuser(indata)
+ char *indata;
+{
+ unsigned long nusers;
+
+.ft I
+ /*
+ * Code here to compute the number of users
+ * and place result in variable \fInusers\fP.
+ */
+.ft CW
+ return((char *)&nusers);
+}
+.DE
+.LP
+It takes one argument, which is a pointer to the input
+of the remote procedure call (ignored in our example),
+and it returns a pointer to the result.
+In the current version of C,
+character pointers are the generic pointers,
+so both the input argument and the return value are cast to
+.I "char *" .
+.LP
+Normally, a server registers all of the RPC calls it plans
+to handle, and then goes into an infinite loop waiting to service requests.
+In this example, there is only a single procedure
+to register, so the main body of the server would look like this:
+.ie t .DS
+.el .DS L
+.ft CW
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <utmp.h>
+#include <rpcsvc/rusers.h>
+
+char *nuser();
+
+main()
+{
+ registerrpc(RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM,
+ nuser, xdr_void, xdr_u_long);
+ svc_run(); /* \fINever returns\fP */
+ fprintf(stderr, "Error: svc_run returned!\en");
+ exit(1);
+}
+.DE
+.LP
+The
+.I registerrpc()
+routine registers a C procedure as corresponding to a
+given RPC procedure number. The first three parameters,
+.I RUSERPROG ,
+.I RUSERSVERS ,
+and
+.I RUSERSPROC_NUM
+are the program, version, and procedure numbers
+of the remote procedure to be registered;
+.I nuser()
+is the name of the local procedure that implements the remote
+procedure; and
+.I xdr_void()
+and
+.I xdr_u_long()
+are the XDR filters for the remote procedure's arguments and
+results, respectively. (Multiple arguments or multiple results
+are passed as structures).
+.LP
+Only the UDP transport mechanism can use
+.I registerrpc()
+thus, it is always safe in conjunction with calls generated by
+.I callrpc() .
+.SH
+.IX "UDP 8K warning"
+Warning: the UDP transport mechanism can only deal with
+arguments and results less than 8K bytes in length.
+.LP
+.LP
+After registering the local procedure, the server program's
+main procedure calls
+.I svc_run (),
+the RPC library's remote procedure dispatcher. It is this
+function that calls the remote procedures in response to RPC
+call messages. Note that the dispatcher takes care of decoding
+remote procedure arguments and encoding results, using the XDR
+filters specified when the remote procedure was registered.
+.NH 2
+\&Assigning Program Numbers
+.IX "program number assignment"
+.IX "assigning program numbers"
+.LP
+Program numbers are assigned in groups of
+.I 0x20000000
+according to the following chart:
+.DS
+.ft CW
+ 0x0 - 0x1fffffff \fRDefined by Sun\fP
+0x20000000 - 0x3fffffff \fRDefined by user\fP
+0x40000000 - 0x5fffffff \fRTransient\fP
+0x60000000 - 0x7fffffff \fRReserved\fP
+0x80000000 - 0x9fffffff \fRReserved\fP
+0xa0000000 - 0xbfffffff \fRReserved\fP
+0xc0000000 - 0xdfffffff \fRReserved\fP
+0xe0000000 - 0xffffffff \fRReserved\fP
+.ft R
+.DE
+Sun Microsystems administers the first group of numbers, which
+should be identical for all Sun customers. If a customer
+develops an application that might be of general interest, that
+application should be given an assigned number in the first
+range. The second group of numbers is reserved for specific
+customer applications. This range is intended primarily for
+debugging new programs. The third group is reserved for
+applications that generate program numbers dynamically. The
+final groups are reserved for future use, and should not be
+used.
+.LP
+To register a protocol specification, send a request by network
+mail to
+.I rpc@sun
+or write to:
+.DS
+RPC Administrator
+Sun Microsystems
+2550 Garcia Ave.
+Mountain View, CA 94043
+.DE
+Please include a compilable
+.I rpcgen
+\*Q.x\*U file describing your protocol.
+You will be given a unique program number in return.
+.IX RPC administration
+.IX administration "of RPC"
+.LP
+The RPC program numbers and protocol specifications
+of standard Sun RPC services can be
+found in the include files in
+.I "/usr/include/rpcsvc" .
+These services, however, constitute only a small subset
+of those which have been registered. The complete list of
+registered programs, as of the time when this manual was
+printed, is:
+.LP
+\fBTable 3-2\fI RPC Registered Programs\fR
+.TS H
+box tab (&) ;
+lfBI lfBI lfBI
+lfL lfL lfI .
+RPC Number&Program&Description
+_
+.TH
+.sp.5
+100000&PMAPPROG&portmapper
+100001&RSTATPROG&remote stats
+100002&RUSERSPROG&remote users
+100003&NFSPROG&nfs
+100004&YPPROG&Yellow Pages
+100005&MOUNTPROG&mount demon
+100006&DBXPROG&remote dbx
+100007&YPBINDPROG&yp binder
+100008&WALLPROG&shutdown msg
+100009&YPPASSWDPROG&yppasswd server
+100010&ETHERSTATPROG&ether stats
+100011&RQUOTAPROG&disk quotas
+100012&SPRAYPROG&spray packets
+100013&IBM3270PROG&3270 mapper
+100014&IBMRJEPROG&RJE mapper
+100015&SELNSVCPROG&selection service
+100016&RDATABASEPROG&remote database access
+100017&REXECPROG&remote execution
+100018&ALICEPROG&Alice Office Automation
+100019&SCHEDPROG&scheduling service
+100020&LOCKPROG&local lock manager
+100021&NETLOCKPROG&network lock manager
+100022&X25PROG&x.25 inr protocol
+100023&STATMON1PROG&status monitor 1
+100024&STATMON2PROG&status monitor 2
+100025&SELNLIBPROG&selection library
+100026&BOOTPARAMPROG&boot parameters service
+100027&MAZEPROG&mazewars game
+100028&YPUPDATEPROG&yp update
+100029&KEYSERVEPROG&key server
+100030&SECURECMDPROG&secure login
+100031&NETFWDIPROG&nfs net forwarder init
+100032&NETFWDTPROG&nfs net forwarder trans
+100033&SUNLINKMAP_PROG&sunlink MAP
+100034&NETMONPROG&network monitor
+100035&DBASEPROG&lightweight database
+100036&PWDAUTHPROG&password authorization
+100037&TFSPROG&translucent file svc
+100038&NSEPROG&nse server
+100039&NSE_ACTIVATE_PROG&nse activate daemon
+.sp .2i
+150001&PCNFSDPROG&pc passwd authorization
+.sp .2i
+200000&PYRAMIDLOCKINGPROG&Pyramid-locking
+200001&PYRAMIDSYS5&Pyramid-sys5
+200002&CADDS_IMAGE&CV cadds_image
+.sp .2i
+300001&ADT_RFLOCKPROG&ADT file locking
+.TE
+.NH 2
+\&Passing Arbitrary Data Types
+.IX "arbitrary data types"
+.LP
+In the previous example, the RPC call passes a single
+.I "unsigned long"
+RPC can handle arbitrary data structures, regardless of
+different machines' byte orders or structure layout conventions,
+by always converting them to a network standard called
+.I "External Data Representation"
+(XDR) before
+sending them over the wire.
+The process of converting from a particular machine representation
+to XDR format is called
+.I serializing ,
+and the reverse process is called
+.I deserializing .
+The type field parameters of
+.I callrpc()
+and
+.I registerrpc()
+can be a built-in procedure like
+.I xdr_u_long()
+in the previous example, or a user supplied one.
+XDR has these built-in type routines:
+.IX RPC "built-in routines"
+.DS
+.ft CW
+xdr_int() xdr_u_int() xdr_enum()
+xdr_long() xdr_u_long() xdr_bool()
+xdr_short() xdr_u_short() xdr_wrapstring()
+xdr_char() xdr_u_char()
+.DE
+Note that the routine
+.I xdr_string()
+exists, but cannot be used with
+.I callrpc()
+and
+.I registerrpc (),
+which only pass two parameters to their XDR routines.
+.I xdr_wrapstring()
+has only two parameters, and is thus OK. It calls
+.I xdr_string ().
+.LP
+As an example of a user-defined type routine,
+if you wanted to send the structure
+.DS
+.ft CW
+struct simple {
+ int a;
+ short b;
+} simple;
+.DE
+then you would call
+.I callrpc()
+as
+.DS
+.ft CW
+callrpc(hostname, PROGNUM, VERSNUM, PROCNUM,
+ xdr_simple, &simple ...);
+.DE
+where
+.I xdr_simple()
+is written as:
+.ie t .DS
+.el .DS L
+.ft CW
+#include <rpc/rpc.h>
+
+xdr_simple(xdrsp, simplep)
+ XDR *xdrsp;
+ struct simple *simplep;
+{
+ if (!xdr_int(xdrsp, &simplep->a))
+ return (0);
+ if (!xdr_short(xdrsp, &simplep->b))
+ return (0);
+ return (1);
+}
+.DE
+.LP
+An XDR routine returns nonzero (true in the sense of C) if it
+completes successfully, and zero otherwise.
+A complete description of XDR is in the
+.I "XDR Protocol Specification"
+section of this manual, only few implementation examples are
+given here.
+.LP
+In addition to the built-in primitives,
+there are also the prefabricated building blocks:
+.DS
+.ft CW
+xdr_array() xdr_bytes() xdr_reference()
+xdr_vector() xdr_union() xdr_pointer()
+xdr_string() xdr_opaque()
+.DE
+To send a variable array of integers,
+you might package them up as a structure like this
+.DS
+.ft CW
+struct varintarr {
+ int *data;
+ int arrlnth;
+} arr;
+.DE
+and make an RPC call such as
+.DS
+.ft CW
+callrpc(hostname, PROGNUM, VERSNUM, PROCNUM,
+ xdr_varintarr, &arr...);
+.DE
+with
+.I xdr_varintarr()
+defined as:
+.ie t .DS
+.el .DS L
+.ft CW
+xdr_varintarr(xdrsp, arrp)
+ XDR *xdrsp;
+ struct varintarr *arrp;
+{
+ return (xdr_array(xdrsp, &arrp->data, &arrp->arrlnth,
+ MAXLEN, sizeof(int), xdr_int));
+}
+.DE
+This routine takes as parameters the XDR handle,
+a pointer to the array, a pointer to the size of the array,
+the maximum allowable array size,
+the size of each array element,
+and an XDR routine for handling each array element.
+.KS
+.LP
+If the size of the array is known in advance, one can use
+.I xdr_vector (),
+which serializes fixed-length arrays.
+.ie t .DS
+.el .DS L
+.ft CW
+int intarr[SIZE];
+
+xdr_intarr(xdrsp, intarr)
+ XDR *xdrsp;
+ int intarr[];
+{
+ int i;
+
+ return (xdr_vector(xdrsp, intarr, SIZE, sizeof(int),
+ xdr_int));
+}
+.DE
+.KE
+.LP
+XDR always converts quantities to 4-byte multiples when serializing.
+Thus, if either of the examples above involved characters
+instead of integers, each character would occupy 32 bits.
+That is the reason for the XDR routine
+.I xdr_bytes()
+which is like
+.I xdr_array()
+except that it packs characters;
+.I xdr_bytes()
+has four parameters, similar to the first four parameters of
+.I xdr_array ().
+For null-terminated strings, there is also the
+.I xdr_string()
+routine, which is the same as
+.I xdr_bytes()
+without the length parameter.
+On serializing it gets the string length from
+.I strlen (),
+and on deserializing it creates a null-terminated string.
+.LP
+Here is a final example that calls the previously written
+.I xdr_simple()
+as well as the built-in functions
+.I xdr_string()
+and
+.I xdr_reference (),
+which chases pointers:
+.ie t .DS
+.el .DS L
+.ft CW
+struct finalexample {
+ char *string;
+ struct simple *simplep;
+} finalexample;
+
+xdr_finalexample(xdrsp, finalp)
+ XDR *xdrsp;
+ struct finalexample *finalp;
+{
+
+ if (!xdr_string(xdrsp, &finalp->string, MAXSTRLEN))
+ return (0);
+ if (!xdr_reference(xdrsp, &finalp->simplep,
+ sizeof(struct simple), xdr_simple);
+ return (0);
+ return (1);
+}
+.DE
+Note that we could as easily call
+.I xdr_simple()
+here instead of
+.I xdr_reference ().
+.NH 1
+\&Lowest Layer of RPC
+.IX "lowest layer of RPC"
+.IX "RPC" "lowest layer"
+.LP
+In the examples given so far,
+RPC takes care of many details automatically for you.
+In this section, we'll show you how you can change the defaults
+by using lower layers of the RPC library.
+It is assumed that you are familiar with sockets
+and the system calls for dealing with them.
+.LP
+There are several occasions when you may need to use lower layers of
+RPC. First, you may need to use TCP, since the higher layer uses UDP,
+which restricts RPC calls to 8K bytes of data. Using TCP permits calls
+to send long streams of data.
+For an example, see the
+.I TCP
+section below. Second, you may want to allocate and free memory
+while serializing or deserializing with XDR routines.
+There is no call at the higher level to let
+you free memory explicitly.
+For more explanation, see the
+.I "Memory Allocation with XDR"
+section below.
+Third, you may need to perform authentication
+on either the client or server side, by supplying
+credentials or verifying them.
+See the explanation in the
+.I Authentication
+section below.
+.NH 2
+\&More on the Server Side
+.IX RPC "server side"
+.LP
+The server for the
+.I nusers()
+program shown below does the same thing as the one using
+.I registerrpc()
+above, but is written using a lower layer of the RPC package:
+.ie t .DS
+.el .DS L
+.ft CW
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <utmp.h>
+#include <rpcsvc/rusers.h>
+
+main()
+{
+ SVCXPRT *transp;
+ int nuser();
+
+ transp = svcudp_create(RPC_ANYSOCK);
+ if (transp == NULL){
+ fprintf(stderr, "can't create an RPC server\en");
+ exit(1);
+ }
+ pmap_unset(RUSERSPROG, RUSERSVERS);
+ if (!svc_register(transp, RUSERSPROG, RUSERSVERS,
+ nuser, IPPROTO_UDP)) {
+ fprintf(stderr, "can't register RUSER service\en");
+ exit(1);
+ }
+ svc_run(); /* \fINever returns\fP */
+ fprintf(stderr, "should never reach this point\en");
+}
+
+nuser(rqstp, transp)
+ struct svc_req *rqstp;
+ SVCXPRT *transp;
+{
+ unsigned long nusers;
+
+ switch (rqstp->rq_proc) {
+ case NULLPROC:
+ if (!svc_sendreply(transp, xdr_void, 0))
+ fprintf(stderr, "can't reply to RPC call\en");
+ return;
+ case RUSERSPROC_NUM:
+.ft I
+ /*
+ * Code here to compute the number of users
+ * and assign it to the variable \fInusers\fP
+ */
+.ft CW
+ if (!svc_sendreply(transp, xdr_u_long, &nusers))
+ fprintf(stderr, "can't reply to RPC call\en");
+ return;
+ default:
+ svcerr_noproc(transp);
+ return;
+ }
+}
+.DE
+.LP
+First, the server gets a transport handle, which is used
+for receiving and replying to RPC messages.
+.I registerrpc()
+uses
+.I svcudp_create()
+to get a UDP handle.
+If you require a more reliable protocol, call
+.I svctcp_create()
+instead.
+If the argument to
+.I svcudp_create()
+is
+.I RPC_ANYSOCK
+the RPC library creates a socket
+on which to receive and reply to RPC calls. Otherwise,
+.I svcudp_create()
+expects its argument to be a valid socket number.
+If you specify your own socket, it can be bound or unbound.
+If it is bound to a port by the user, the port numbers of
+.I svcudp_create()
+and
+.I clnttcp_create()
+(the low-level client routine) must match.
+.LP
+If the user specifies the
+.I RPC_ANYSOCK
+argument, the RPC library routines will open sockets.
+Otherwise they will expect the user to do so. The routines
+.I svcudp_create()
+and
+.I clntudp_create()
+will cause the RPC library routines to
+.I bind()
+their socket if it is not bound already.
+.LP
+A service may choose to register its port number with the
+local portmapper service. This is done is done by specifying
+a non-zero protocol number in
+.I svc_register ().
+Incidently, a client can discover the server's port number by
+consulting the portmapper on their server's machine. This can
+be done automatically by specifying a zero port number in
+.I clntudp_create()
+or
+.I clnttcp_create ().
+.LP
+After creating an
+.I SVCXPRT ,
+the next step is to call
+.I pmap_unset()
+so that if the
+.I nusers()
+server crashed earlier,
+any previous trace of it is erased before restarting.
+More precisely,
+.I pmap_unset()
+erases the entry for
+.I RUSERSPROG
+from the port mapper's tables.
+.LP
+Finally, we associate the program number for
+.I nusers()
+with the procedure
+.I nuser ().
+The final argument to
+.I svc_register()
+is normally the protocol being used,
+which, in this case, is
+.I IPPROTO_UDP
+Notice that unlike
+.I registerrpc (),
+there are no XDR routines involved
+in the registration process.
+Also, registration is done on the program,
+rather than procedure, level.
+.LP
+The user routine
+.I nuser()
+must call and dispatch the appropriate XDR routines
+based on the procedure number.
+Note that
+two things are handled by
+.I nuser()
+that
+.I registerrpc()
+handles automatically.
+The first is that procedure
+.I NULLPROC
+(currently zero) returns with no results.
+This can be used as a simple test
+for detecting if a remote program is running.
+Second, there is a check for invalid procedure numbers.
+If one is detected,
+.I svcerr_noproc()
+is called to handle the error.
+.KS
+.LP
+The user service routine serializes the results and returns
+them to the RPC caller via
+.I svc_sendreply()
+Its first parameter is the
+.I SVCXPRT
+handle, the second is the XDR routine,
+and the third is a pointer to the data to be returned.
+Not illustrated above is how a server
+handles an RPC program that receives data.
+As an example, we can add a procedure
+.I RUSERSPROC_BOOL
+which has an argument
+.I nusers (),
+and returns
+.I TRUE
+or
+.I FALSE
+depending on whether there are nusers logged on.
+It would look like this:
+.ie t .DS
+.el .DS L
+.ft CW
+case RUSERSPROC_BOOL: {
+ int bool;
+ unsigned nuserquery;
+
+ if (!svc_getargs(transp, xdr_u_int, &nuserquery) {
+ svcerr_decode(transp);
+ return;
+ }
+.ft I
+ /*
+ * Code to set \fInusers\fP = number of users
+ */
+.ft CW
+ if (nuserquery == nusers)
+ bool = TRUE;
+ else
+ bool = FALSE;
+ if (!svc_sendreply(transp, xdr_bool, &bool)) {
+ fprintf(stderr, "can't reply to RPC call\en");
+ return (1);
+ }
+ return;
+}
+.DE
+.KE
+.LP
+The relevant routine is
+.I svc_getargs()
+which takes an
+.I SVCXPRT
+handle, the XDR routine,
+and a pointer to where the input is to be placed as arguments.
+.NH 2
+\&Memory Allocation with XDR
+.IX "memory allocation with XDR"
+.IX XDR "memory allocation"
+.LP
+XDR routines not only do input and output,
+they also do memory allocation.
+This is why the second parameter of
+.I xdr_array()
+is a pointer to an array, rather than the array itself.
+If it is
+.I NULL ,
+then
+.I xdr_array()
+allocates space for the array and returns a pointer to it,
+putting the size of the array in the third argument.
+As an example, consider the following XDR routine
+.I xdr_chararr1()
+which deals with a fixed array of bytes with length
+.I SIZE .
+.ie t .DS
+.el .DS L
+.ft CW
+xdr_chararr1(xdrsp, chararr)
+ XDR *xdrsp;
+ char chararr[];
+{
+ char *p;
+ int len;
+
+ p = chararr;
+ len = SIZE;
+ return (xdr_bytes(xdrsp, &p, &len, SIZE));
+}
+.DE
+If space has already been allocated in
+.I chararr ,
+it can be called from a server like this:
+.ie t .DS
+.el .DS L
+.ft CW
+char chararr[SIZE];
+
+svc_getargs(transp, xdr_chararr1, chararr);
+.DE
+If you want XDR to do the allocation,
+you would have to rewrite this routine in the following way:
+.ie t .DS
+.el .DS L
+.ft CW
+xdr_chararr2(xdrsp, chararrp)
+ XDR *xdrsp;
+ char **chararrp;
+{
+ int len;
+
+ len = SIZE;
+ return (xdr_bytes(xdrsp, charrarrp, &len, SIZE));
+}
+.DE
+Then the RPC call might look like this:
+.ie t .DS
+.el .DS L
+.ft CW
+char *arrptr;
+
+arrptr = NULL;
+svc_getargs(transp, xdr_chararr2, &arrptr);
+.ft I
+/*
+ * Use the result here
+ */
+.ft CW
+svc_freeargs(transp, xdr_chararr2, &arrptr);
+.DE
+Note that, after being used, the character array can be freed with
+.I svc_freeargs()
+.I svc_freeargs()
+will not attempt to free any memory if the variable indicating it
+is NULL. For example, in the the routine
+.I xdr_finalexample (),
+given earlier, if
+.I finalp->string
+was NULL, then it would not be freed. The same is true for
+.I finalp->simplep .
+.LP
+To summarize, each XDR routine is responsible
+for serializing, deserializing, and freeing memory.
+When an XDR routine is called from
+.I callrpc()
+the serializing part is used.
+When called from
+.I svc_getargs()
+the deserializer is used.
+And when called from
+.I svc_freeargs()
+the memory deallocator is used. When building simple examples like those
+in this section, a user doesn't have to worry
+about the three modes.
+See the
+.I "External Data Representation: Sun Technical Notes"
+for examples of more sophisticated XDR routines that determine
+which of the three modes they are in and adjust their behavior accordingly.
+.KS
+.NH 2
+\&The Calling Side
+.IX RPC "calling side"
+.LP
+When you use
+.I callrpc()
+you have no control over the RPC delivery
+mechanism or the socket used to transport the data.
+To illustrate the layer of RPC that lets you adjust these
+parameters, consider the following code to call the
+.I nusers
+service:
+.ie t .DS
+.el .DS L
+.ft CW
+.vs 11
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <utmp.h>
+#include <rpcsvc/rusers.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netdb.h>
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct hostent *hp;
+ struct timeval pertry_timeout, total_timeout;
+ struct sockaddr_in server_addr;
+ int sock = RPC_ANYSOCK;
+ register CLIENT *client;
+ enum clnt_stat clnt_stat;
+ unsigned long nusers;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: nusers hostname\en");
+ exit(-1);
+ }
+ if ((hp = gethostbyname(argv[1])) == NULL) {
+ fprintf(stderr, "can't get addr for %s\en",argv[1]);
+ exit(-1);
+ }
+ pertry_timeout.tv_sec = 3;
+ pertry_timeout.tv_usec = 0;
+ bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr,
+ hp->h_length);
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_port = 0;
+ if ((client = clntudp_create(&server_addr, RUSERSPROG,
+ RUSERSVERS, pertry_timeout, &sock)) == NULL) {
+ clnt_pcreateerror("clntudp_create");
+ exit(-1);
+ }
+ total_timeout.tv_sec = 20;
+ total_timeout.tv_usec = 0;
+ clnt_stat = clnt_call(client, RUSERSPROC_NUM, xdr_void,
+ 0, xdr_u_long, &nusers, total_timeout);
+ if (clnt_stat != RPC_SUCCESS) {
+ clnt_perror(client, "rpc");
+ exit(-1);
+ }
+ clnt_destroy(client);
+ close(sock);
+ exit(0);
+}
+.vs
+.DE
+.KE
+The low-level version of
+.I callrpc()
+is
+.I clnt_call()
+which takes a
+.I CLIENT
+pointer rather than a host name. The parameters to
+.I clnt_call()
+are a
+.I CLIENT
+pointer, the procedure number,
+the XDR routine for serializing the argument,
+a pointer to the argument,
+the XDR routine for deserializing the return value,
+a pointer to where the return value will be placed,
+and the time in seconds to wait for a reply.
+.LP
+The
+.I CLIENT
+pointer is encoded with the transport mechanism.
+.I callrpc()
+uses UDP, thus it calls
+.I clntudp_create()
+to get a
+.I CLIENT
+pointer. To get TCP (Transmission Control Protocol), you would use
+.I clnttcp_create() .
+.LP
+The parameters to
+.I clntudp_create()
+are the server address, the program number, the version number,
+a timeout value (between tries), and a pointer to a socket.
+The final argument to
+.I clnt_call()
+is the total time to wait for a response.
+Thus, the number of tries is the
+.I clnt_call()
+timeout divided by the
+.I clntudp_create()
+timeout.
+.LP
+Note that the
+.I clnt_destroy()
+call
+always deallocates the space associated with the
+.I CLIENT
+handle. It closes the socket associated with the
+.I CLIENT
+handle, however, only if the RPC library opened it. It the
+socket was opened by the user, it stays open. This makes it
+possible, in cases where there are multiple client handles
+using the same socket, to destroy one handle without closing
+the socket that other handles are using.
+.LP
+To make a stream connection, the call to
+.I clntudp_create()
+is replaced with a call to
+.I clnttcp_create() .
+.DS
+.ft CW
+clnttcp_create(&server_addr, prognum, versnum, &sock,
+ inputsize, outputsize);
+.DE
+There is no timeout argument; instead, the receive and send buffer
+sizes must be specified. When the
+.I clnttcp_create()
+call is made, a TCP connection is established.
+All RPC calls using that
+.I CLIENT
+handle would use this connection.
+The server side of an RPC call using TCP has
+.I svcudp_create()
+replaced by
+.I svctcp_create() .
+.DS
+.ft CW
+transp = svctcp_create(RPC_ANYSOCK, 0, 0);
+.DE
+The last two arguments to
+.I svctcp_create()
+are send and receive sizes respectively. If `0' is specified for
+either of these, the system chooses a reasonable default.
+.KS
+.NH 1
+\&Other RPC Features
+.IX "RPC" "miscellaneous features"
+.IX "miscellaneous RPC features"
+.LP
+This section discusses some other aspects of RPC
+that are occasionally useful.
+.NH 2
+\&Select on the Server Side
+.IX RPC select() RPC \fIselect()\fP
+.IX select() "" \fIselect()\fP "on the server side"
+.LP
+Suppose a process is processing RPC requests
+while performing some other activity.
+If the other activity involves periodically updating a data structure,
+the process can set an alarm signal before calling
+.I svc_run()
+But if the other activity
+involves waiting on a a file descriptor, the
+.I svc_run()
+call won't work.
+The code for
+.I svc_run()
+is as follows:
+.ie t .DS
+.el .DS L
+.ft CW
+.vs 11
+void
+svc_run()
+{
+ fd_set readfds;
+ int dtbsz = getdtablesize();
+
+ for (;;) {
+ readfds = svc_fds;
+ switch (select(dtbsz, &readfds, NULL,NULL,NULL)) {
+
+ case -1:
+ if (errno == EINTR)
+ continue;
+ perror("select");
+ return;
+ case 0:
+ break;
+ default:
+ svc_getreqset(&readfds);
+ }
+ }
+}
+.vs
+.DE
+.KE
+.LP
+You can bypass
+.I svc_run()
+and call
+.I svc_getreqset()
+yourself.
+All you need to know are the file descriptors
+of the socket(s) associated with the programs you are waiting on.
+Thus you can have your own
+.I select()
+.IX select() "" \fIselect()\fP
+that waits on both the RPC socket,
+and your own descriptors. Note that
+.I svc_fds()
+is a bit mask of all the file descriptors that RPC is using for
+services. It can change everytime that
+.I any
+RPC library routine is called, because descriptors are constantly
+being opened and closed, for example for TCP connections.
+.NH 2
+\&Broadcast RPC
+.IX "broadcast RPC"
+.IX RPC "broadcast"
+.LP
+The
+.I portmapper
+is a daemon that converts RPC program numbers
+into DARPA protocol port numbers; see the
+.I portmap
+man page. You can't do broadcast RPC without the portmapper.
+Here are the main differences between
+broadcast RPC and normal RPC calls:
+.IP 1.
+Normal RPC expects one answer, whereas
+broadcast RPC expects many answers
+(one or more answer from each responding machine).
+.IP 2.
+Broadcast RPC can only be supported by packet-oriented (connectionless)
+transport protocols like UPD/IP.
+.IP 3.
+The implementation of broadcast RPC
+treats all unsuccessful responses as garbage by filtering them out.
+Thus, if there is a version mismatch between the
+broadcaster and a remote service,
+the user of broadcast RPC never knows.
+.IP 4.
+All broadcast messages are sent to the portmap port.
+Thus, only services that register themselves with their portmapper
+are accessible via the broadcast RPC mechanism.
+.IP 5.
+Broadcast requests are limited in size to the MTU (Maximum Transfer
+Unit) of the local network. For Ethernet, the MTU is 1500 bytes.
+.KS
+.NH 3
+\&Broadcast RPC Synopsis
+.IX "broadcast RPC" synopsis
+.IX "RPC" "broadcast synopsis"
+.ie t .DS
+.el .DS L
+.ft CW
+#include <rpc/pmap_clnt.h>
+ . . .
+enum clnt_stat clnt_stat;
+ . . .
+clnt_stat = clnt_broadcast(prognum, versnum, procnum,
+ inproc, in, outproc, out, eachresult)
+ u_long prognum; /* \fIprogram number\fP */
+ u_long versnum; /* \fIversion number\fP */
+ u_long procnum; /* \fIprocedure number\fP */
+ xdrproc_t inproc; /* \fIxdr routine for args\fP */
+ caddr_t in; /* \fIpointer to args\fP */
+ xdrproc_t outproc; /* \fIxdr routine for results\fP */
+ caddr_t out; /* \fIpointer to results\fP */
+ bool_t (*eachresult)();/* \fIcall with each result gotten\fP */
+.DE
+.KE
+The procedure
+.I eachresult()
+is called each time a valid result is obtained.
+It returns a boolean that indicates
+whether or not the user wants more responses.
+.ie t .DS
+.el .DS L
+.ft CW
+bool_t done;
+ . . .
+done = eachresult(resultsp, raddr)
+ caddr_t resultsp;
+ struct sockaddr_in *raddr; /* \fIAddr of responding machine\fP */
+.DE
+If
+.I done
+is
+.I TRUE ,
+then broadcasting stops and
+.I clnt_broadcast()
+returns successfully.
+Otherwise, the routine waits for another response.
+The request is rebroadcast
+after a few seconds of waiting.
+If no responses come back,
+the routine returns with
+.I RPC_TIMEDOUT .
+.NH 2
+\&Batching
+.IX "batching"
+.IX RPC "batching"
+.LP
+The RPC architecture is designed so that clients send a call message,
+and wait for servers to reply that the call succeeded.
+This implies that clients do not compute
+while servers are processing a call.
+This is inefficient if the client does not want or need
+an acknowledgement for every message sent.
+It is possible for clients to continue computing
+while waiting for a response,
+using RPC batch facilities.
+.LP
+RPC messages can be placed in a \*Qpipeline\*U of calls
+to a desired server; this is called batching.
+Batching assumes that:
+1) each RPC call in the pipeline requires no response from the server,
+and the server does not send a response message; and
+2) the pipeline of calls is transported on a reliable
+byte stream transport such as TCP/IP.
+Since the server does not respond to every call,
+the client can generate new calls in parallel
+with the server executing previous calls.
+Furthermore, the TCP/IP implementation can buffer up
+many call messages, and send them to the server in one
+.I write()
+system call. This overlapped execution
+greatly decreases the interprocess communication overhead of
+the client and server processes,
+and the total elapsed time of a series of calls.
+.LP
+Since the batched calls are buffered,
+the client should eventually do a nonbatched call
+in order to flush the pipeline.
+.LP
+A contrived example of batching follows.
+Assume a string rendering service (like a window system)
+has two similar calls: one renders a string and returns void results,
+while the other renders a string and remains silent.
+The service (using the TCP/IP transport) may look like:
+.ie t .DS
+.el .DS L
+.ft CW
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <suntool/windows.h>
+
+void windowdispatch();
+
+main()
+{
+ SVCXPRT *transp;
+
+ transp = svctcp_create(RPC_ANYSOCK, 0, 0);
+ if (transp == NULL){
+ fprintf(stderr, "can't create an RPC server\en");
+ exit(1);
+ }
+ pmap_unset(WINDOWPROG, WINDOWVERS);
+ if (!svc_register(transp, WINDOWPROG, WINDOWVERS,
+ windowdispatch, IPPROTO_TCP)) {
+ fprintf(stderr, "can't register WINDOW service\en");
+ exit(1);
+ }
+ svc_run(); /* \fINever returns\fP */
+ fprintf(stderr, "should never reach this point\en");
+}
+
+void
+windowdispatch(rqstp, transp)
+ struct svc_req *rqstp;
+ SVCXPRT *transp;
+{
+ char *s = NULL;
+
+ switch (rqstp->rq_proc) {
+ case NULLPROC:
+ if (!svc_sendreply(transp, xdr_void, 0))
+ fprintf(stderr, "can't reply to RPC call\en");
+ return;
+ case RENDERSTRING:
+ if (!svc_getargs(transp, xdr_wrapstring, &s)) {
+ fprintf(stderr, "can't decode arguments\en");
+.ft I
+ /*
+ * Tell caller he screwed up
+ */
+.ft CW
+ svcerr_decode(transp);
+ break;
+ }
+.ft I
+ /*
+ * Code here to render the string \fIs\fP
+ */
+.ft CW
+ if (!svc_sendreply(transp, xdr_void, NULL))
+ fprintf(stderr, "can't reply to RPC call\en");
+ break;
+ case RENDERSTRING_BATCHED:
+ if (!svc_getargs(transp, xdr_wrapstring, &s)) {
+ fprintf(stderr, "can't decode arguments\en");
+.ft I
+ /*
+ * We are silent in the face of protocol errors
+ */
+.ft CW
+ break;
+ }
+.ft I
+ /*
+ * Code here to render string s, but send no reply!
+ */
+.ft CW
+ break;
+ default:
+ svcerr_noproc(transp);
+ return;
+ }
+.ft I
+ /*
+ * Now free string allocated while decoding arguments
+ */
+.ft CW
+ svc_freeargs(transp, xdr_wrapstring, &s);
+}
+.DE
+Of course the service could have one procedure
+that takes the string and a boolean
+to indicate whether or not the procedure should respond.
+.LP
+In order for a client to take advantage of batching,
+the client must perform RPC calls on a TCP-based transport
+and the actual calls must have the following attributes:
+1) the result's XDR routine must be zero
+.I NULL ),
+and 2) the RPC call's timeout must be zero.
+.KS
+.LP
+Here is an example of a client that uses batching to render a
+bunch of strings; the batching is flushed when the client gets
+a null string (EOF):
+.ie t .DS
+.el .DS L
+.ft CW
+.vs 11
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netdb.h>
+#include <suntool/windows.h>
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct hostent *hp;
+ struct timeval pertry_timeout, total_timeout;
+ struct sockaddr_in server_addr;
+ int sock = RPC_ANYSOCK;
+ register CLIENT *client;
+ enum clnt_stat clnt_stat;
+ char buf[1000], *s = buf;
+
+ if ((client = clnttcp_create(&server_addr,
+ WINDOWPROG, WINDOWVERS, &sock, 0, 0)) == NULL) {
+ perror("clnttcp_create");
+ exit(-1);
+ }
+ total_timeout.tv_sec = 0;
+ total_timeout.tv_usec = 0;
+ while (scanf("%s", s) != EOF) {
+ clnt_stat = clnt_call(client, RENDERSTRING_BATCHED,
+ xdr_wrapstring, &s, NULL, NULL, total_timeout);
+ if (clnt_stat != RPC_SUCCESS) {
+ clnt_perror(client, "batched rpc");
+ exit(-1);
+ }
+ }
+
+ /* \fINow flush the pipeline\fP */
+
+ total_timeout.tv_sec = 20;
+ clnt_stat = clnt_call(client, NULLPROC, xdr_void, NULL,
+ xdr_void, NULL, total_timeout);
+ if (clnt_stat != RPC_SUCCESS) {
+ clnt_perror(client, "rpc");
+ exit(-1);
+ }
+ clnt_destroy(client);
+ exit(0);
+}
+.vs
+.DE
+.KE
+Since the server sends no message,
+the clients cannot be notified of any of the failures that may occur.
+Therefore, clients are on their own when it comes to handling errors.
+.LP
+The above example was completed to render
+all of the (2000) lines in the file
+.I /etc/termcap .
+The rendering service did nothing but throw the lines away.
+The example was run in the following four configurations:
+1) machine to itself, regular RPC;
+2) machine to itself, batched RPC;
+3) machine to another, regular RPC; and
+4) machine to another, batched RPC.
+The results are as follows:
+1) 50 seconds;
+2) 16 seconds;
+3) 52 seconds;
+4) 10 seconds.
+Running
+.I fscanf()
+on
+.I /etc/termcap
+only requires six seconds.
+These timings show the advantage of protocols
+that allow for overlapped execution,
+though these protocols are often hard to design.
+.NH 2
+\&Authentication
+.IX "authentication"
+.IX "RPC" "authentication"
+.LP
+In the examples presented so far,
+the caller never identified itself to the server,
+and the server never required an ID from the caller.
+Clearly, some network services, such as a network filesystem,
+require stronger security than what has been presented so far.
+.LP
+In reality, every RPC call is authenticated by
+the RPC package on the server, and similarly,
+the RPC client package generates and sends authentication parameters.
+Just as different transports (TCP/IP or UDP/IP)
+can be used when creating RPC clients and servers,
+different forms of authentication can be associated with RPC clients;
+the default authentication type used as a default is type
+.I none .
+.LP
+The authentication subsystem of the RPC package is open ended.
+That is, numerous types of authentication are easy to support.
+.NH 3
+\&UNIX Authentication
+.IX "UNIX Authentication"
+.IP "\fIThe Client Side\fP"
+.LP
+When a caller creates a new RPC client handle as in:
+.DS
+.ft CW
+clnt = clntudp_create(address, prognum, versnum,
+ wait, sockp)
+.DE
+the appropriate transport instance defaults
+the associate authentication handle to be
+.DS
+.ft CW
+clnt->cl_auth = authnone_create();
+.DE
+The RPC client can choose to use
+.I UNIX
+style authentication by setting
+.I clnt\->cl_auth
+after creating the RPC client handle:
+.DS
+.ft CW
+clnt->cl_auth = authunix_create_default();
+.DE
+This causes each RPC call associated with
+.I clnt
+to carry with it the following authentication credentials structure:
+.ie t .DS
+.el .DS L
+.ft I
+/*
+ * UNIX style credentials.
+ */
+.ft CW
+struct authunix_parms {
+ u_long aup_time; /* \fIcredentials creation time\fP */
+ char *aup_machname; /* \fIhost name where client is\fP */
+ int aup_uid; /* \fIclient's UNIX effective uid\fP */
+ int aup_gid; /* \fIclient's current group id\fP */
+ u_int aup_len; /* \fIelement length of aup_gids\fP */
+ int *aup_gids; /* \fIarray of groups user is in\fP */
+};
+.DE
+These fields are set by
+.I authunix_create_default()
+by invoking the appropriate system calls.
+Since the RPC user created this new style of authentication,
+the user is responsible for destroying it with:
+.DS
+.ft CW
+auth_destroy(clnt->cl_auth);
+.DE
+This should be done in all cases, to conserve memory.
+.sp
+.IP "\fIThe Server Side\fP"
+.LP
+Service implementors have a harder time dealing with authentication issues
+since the RPC package passes the service dispatch routine a request
+that has an arbitrary authentication style associated with it.
+Consider the fields of a request handle passed to a service dispatch routine:
+.ie t .DS
+.el .DS L
+.ft I
+/*
+ * An RPC Service request
+ */
+.ft CW
+struct svc_req {
+ u_long rq_prog; /* \fIservice program number\fP */
+ u_long rq_vers; /* \fIservice protocol vers num\fP */
+ u_long rq_proc; /* \fIdesired procedure number\fP */
+ struct opaque_auth rq_cred; /* \fIraw credentials from wire\fP */
+ caddr_t rq_clntcred; /* \fIcredentials (read only)\fP */
+};
+.DE
+The
+.I rq_cred
+is mostly opaque, except for one field of interest:
+the style or flavor of authentication credentials:
+.ie t .DS
+.el .DS L
+.ft I
+/*
+ * Authentication info. Mostly opaque to the programmer.
+ */
+.ft CW
+struct opaque_auth {
+ enum_t oa_flavor; /* \fIstyle of credentials\fP */
+ caddr_t oa_base; /* \fIaddress of more auth stuff\fP */
+ u_int oa_length; /* \fInot to exceed \fIMAX_AUTH_BYTES */
+};
+.DE
+.IX RPC guarantees
+The RPC package guarantees the following
+to the service dispatch routine:
+.IP 1.
+That the request's
+.I rq_cred
+is well formed. Thus the service implementor may inspect the request's
+.I rq_cred.oa_flavor
+to determine which style of authentication the caller used.
+The service implementor may also wish to inspect the other fields of
+.I rq_cred
+if the style is not one of the styles supported by the RPC package.
+.IP 2.
+That the request's
+.I rq_clntcred
+field is either
+.I NULL
+or points to a well formed structure
+that corresponds to a supported style of authentication credentials.
+Remember that only
+.I unix
+style is currently supported, so (currently)
+.I rq_clntcred
+could be cast to a pointer to an
+.I authunix_parms
+structure. If
+.I rq_clntcred
+is
+.I NULL ,
+the service implementor may wish to inspect the other (opaque) fields of
+.I rq_cred
+in case the service knows about a new type of authentication
+that the RPC package does not know about.
+.LP
+Our remote users service example can be extended so that
+it computes results for all users except UID 16:
+.ie t .DS
+.el .DS L
+.ft CW
+.vs 11
+nuser(rqstp, transp)
+ struct svc_req *rqstp;
+ SVCXPRT *transp;
+{
+ struct authunix_parms *unix_cred;
+ int uid;
+ unsigned long nusers;
+
+.ft I
+ /*
+ * we don't care about authentication for null proc
+ */
+.ft CW
+ if (rqstp->rq_proc == NULLPROC) {
+ if (!svc_sendreply(transp, xdr_void, 0)) {
+ fprintf(stderr, "can't reply to RPC call\en");
+ return (1);
+ }
+ return;
+ }
+.ft I
+ /*
+ * now get the uid
+ */
+.ft CW
+ switch (rqstp->rq_cred.oa_flavor) {
+ case AUTH_UNIX:
+ unix_cred =
+ (struct authunix_parms *)rqstp->rq_clntcred;
+ uid = unix_cred->aup_uid;
+ break;
+ case AUTH_NULL:
+ default:
+ svcerr_weakauth(transp);
+ return;
+ }
+ switch (rqstp->rq_proc) {
+ case RUSERSPROC_NUM:
+.ft I
+ /*
+ * make sure caller is allowed to call this proc
+ */
+.ft CW
+ if (uid == 16) {
+ svcerr_systemerr(transp);
+ return;
+ }
+.ft I
+ /*
+ * Code here to compute the number of users
+ * and assign it to the variable \fInusers\fP
+ */
+.ft CW
+ if (!svc_sendreply(transp, xdr_u_long, &nusers)) {
+ fprintf(stderr, "can't reply to RPC call\en");
+ return (1);
+ }
+ return;
+ default:
+ svcerr_noproc(transp);
+ return;
+ }
+}
+.vs
+.DE
+A few things should be noted here.
+First, it is customary not to check
+the authentication parameters associated with the
+.I NULLPROC
+(procedure number zero).
+Second, if the authentication parameter's type is not suitable
+for your service, you should call
+.I svcerr_weakauth() .
+And finally, the service protocol itself should return status
+for access denied; in the case of our example, the protocol
+does not have such a status, so we call the service primitive
+.I svcerr_systemerr()
+instead.
+.LP
+The last point underscores the relation between
+the RPC authentication package and the services;
+RPC deals only with
+.I authentication
+and not with individual services'
+.I "access control" .
+The services themselves must implement their own access control policies
+and reflect these policies as return statuses in their protocols.
+.NH 2
+\&DES Authentication
+.IX RPC DES
+.IX RPC authentication
+.LP
+UNIX authentication is quite easy to defeat. Instead of using
+.I authunix_create_default (),
+one can call
+.I authunix_create()
+and then modify the RPC authentication handle it returns by filling in
+whatever user ID and hostname they wish the server to think they have.
+DES authentication is thus recommended for people who want more security
+than UNIX authentication offers.
+.LP
+The details of the DES authentication protocol are complicated and
+are not explained here.
+See
+.I "Remote Procedure Calls: Protocol Specification"
+for the details.
+.LP
+In order for DES authentication to work, the
+.I keyserv(8c)
+daemon must be running on both the server and client machines. The
+users on these machines need public keys assigned by the network
+administrator in the
+.I publickey(5)
+database. And, they need to have decrypted their secret keys
+using their login password. This automatically happens when one
+logs in using
+.I login(1) ,
+or can be done manually using
+.I keylogin(1) .
+The
+.I "Network Services"
+chapter
+./" XXX
+explains more how to setup secure networking.
+.sp
+.IP "\fIClient Side\fP"
+.LP
+If a client wishes to use DES authentication, it must set its
+authentication handle appropriately. Here is an example:
+.DS
+cl->cl_auth =
+ authdes_create(servername, 60, &server_addr, NULL);
+.DE
+The first argument is the network name or \*Qnetname\*U of the owner of
+the server process. Typically, server processes are root processes
+and their netname can be derived using the following call:
+.DS
+char servername[MAXNETNAMELEN];
+
+host2netname(servername, rhostname, NULL);
+.DE
+Here,
+.I rhostname
+is the hostname of the machine the server process is running on.
+.I host2netname()
+fills in
+.I servername
+to contain this root process's netname. If the
+server process was run by a regular user, one could use the call
+.I user2netname()
+instead. Here is an example for a server process with the same user
+ID as the client:
+.DS
+char servername[MAXNETNAMELEN];
+
+user2netname(servername, getuid(), NULL);
+.DE
+The last argument to both of these calls,
+.I user2netname()
+and
+.I host2netname (),
+is the name of the naming domain where the server is located. The
+.I NULL
+used here means \*Quse the local domain name.\*U
+.LP
+The second argument to
+.I authdes_create()
+is a lifetime for the credential. Here it is set to sixty
+seconds. What that means is that the credential will expire 60
+seconds from now. If some mischievous user tries to reuse the
+credential, the server RPC subsystem will recognize that it has
+expired and not grant any requests. If the same mischievous user
+tries to reuse the credential within the sixty second lifetime,
+he will still be rejected because the server RPC subsystem
+remembers which credentials it has already seen in the near past,
+and will not grant requests to duplicates.
+.LP
+The third argument to
+.I authdes_create()
+is the address of the host to synchronize with. In order for DES
+authentication to work, the server and client must agree upon the
+time. Here we pass the address of the server itself, so the
+client and server will both be using the same time: the server's
+time. The argument can be
+.I NULL ,
+which means \*Qdon't bother synchronizing.\*U You should only do this
+if you are sure the client and server are already synchronized.
+.LP
+The final argument to
+.I authdes_create()
+is the address of a DES encryption key to use for encrypting
+timestamps and data. If this argument is
+.I NULL ,
+as it is in this example, a random key will be chosen. The client
+may find out the encryption key being used by consulting the
+.I ah_key
+field of the authentication handle.
+.sp
+.IP "\fIServer Side\fP"
+.LP
+The server side is a lot simpler than the client side. Here is the
+previous example rewritten to use
+.I AUTH_DES
+instead of
+.I AUTH_UNIX :
+.ie t .DS
+.el .DS L
+.ft CW
+.vs 11
+#include <sys/time.h>
+#include <rpc/auth_des.h>
+ . . .
+ . . .
+nuser(rqstp, transp)
+ struct svc_req *rqstp;
+ SVCXPRT *transp;
+{
+ struct authdes_cred *des_cred;
+ int uid;
+ int gid;
+ int gidlen;
+ int gidlist[10];
+.ft I
+ /*
+ * we don't care about authentication for null proc
+ */
+.ft CW
+
+ if (rqstp->rq_proc == NULLPROC) {
+ /* \fIsame as before\fP */
+ }
+
+.ft I
+ /*
+ * now get the uid
+ */
+.ft CW
+ switch (rqstp->rq_cred.oa_flavor) {
+ case AUTH_DES:
+ des_cred =
+ (struct authdes_cred *) rqstp->rq_clntcred;
+ if (! netname2user(des_cred->adc_fullname.name,
+ &uid, &gid, &gidlen, gidlist))
+ {
+ fprintf(stderr, "unknown user: %s\n",
+ des_cred->adc_fullname.name);
+ svcerr_systemerr(transp);
+ return;
+ }
+ break;
+ case AUTH_NULL:
+ default:
+ svcerr_weakauth(transp);
+ return;
+ }
+
+.ft I
+ /*
+ * The rest is the same as before
+ */
+.ft CW
+.vs
+.DE
+Note the use of the routine
+.I netname2user (),
+the inverse of
+.I user2netname ():
+it takes a network ID and converts to a unix ID.
+.I netname2user ()
+also supplies the group IDs which we don't use in this example,
+but which may be useful to other UNIX programs.
+.NH 2
+\&Using Inetd
+.IX inetd "" "using \fIinetd\fP"
+.LP
+An RPC server can be started from
+.I inetd
+The only difference from the usual code is that the service
+creation routine should be called in the following form:
+.ie t .DS
+.el .DS L
+.ft CW
+transp = svcudp_create(0); /* \fIFor UDP\fP */
+transp = svctcp_create(0,0,0); /* \fIFor listener TCP sockets\fP */
+transp = svcfd_create(0,0,0); /* \fIFor connected TCP sockets\fP */
+.DE
+since
+.I inet
+passes a socket as file descriptor 0.
+Also,
+.I svc_register()
+should be called as
+.ie t .DS
+.el .DS L
+.ft CW
+svc_register(transp, PROGNUM, VERSNUM, service, 0);
+.DE
+with the final flag as 0,
+since the program would already be registered by
+.I inetd
+Remember that if you want to exit
+from the server process and return control to
+.I inet
+you need to explicitly exit, since
+.I svc_run()
+never returns.
+.LP
+The format of entries in
+.I /etc/inetd.conf
+for RPC services is in one of the following two forms:
+.ie t .DS
+.el .DS L
+.ft CW
+p_name/version dgram rpc/udp wait/nowait user server args
+p_name/version stream rpc/tcp wait/nowait user server args
+.DE
+where
+.I p_name
+is the symbolic name of the program as it appears in
+.I rpc(5) ,
+.I server
+is the program implementing the server,
+and
+.I program
+and
+.I version
+are the program and version numbers of the service.
+For more information, see
+.I inetd.conf(5) .
+.LP
+If the same program handles multiple versions,
+then the version number can be a range,
+as in this example:
+.ie t .DS
+.el .DS L
+.ft CW
+rstatd/1-2 dgram rpc/udp wait root /usr/etc/rpc.rstatd
+.DE
+.NH 1
+\&More Examples
+.sp 1
+.NH 2
+\&Versions
+.IX "versions"
+.IX "RPC" "versions"
+.LP
+By convention, the first version number of program
+.I PROG
+is
+.I PROGVERS_ORIG
+and the most recent version is
+.I PROGVERS
+Suppose there is a new version of the
+.I user
+program that returns an
+.I "unsigned short"
+rather than a
+.I long .
+If we name this version
+.I RUSERSVERS_SHORT
+then a server that wants to support both versions
+would do a double register.
+.ie t .DS
+.el .DS L
+.ft CW
+if (!svc_register(transp, RUSERSPROG, RUSERSVERS_ORIG,
+ nuser, IPPROTO_TCP)) {
+ fprintf(stderr, "can't register RUSER service\en");
+ exit(1);
+}
+if (!svc_register(transp, RUSERSPROG, RUSERSVERS_SHORT,
+ nuser, IPPROTO_TCP)) {
+ fprintf(stderr, "can't register RUSER service\en");
+ exit(1);
+}
+.DE
+Both versions can be handled by the same C procedure:
+.ie t .DS
+.el .DS L
+.ft CW
+.vs 11
+nuser(rqstp, transp)
+ struct svc_req *rqstp;
+ SVCXPRT *transp;
+{
+ unsigned long nusers;
+ unsigned short nusers2;
+
+ switch (rqstp->rq_proc) {
+ case NULLPROC:
+ if (!svc_sendreply(transp, xdr_void, 0)) {
+ fprintf(stderr, "can't reply to RPC call\en");
+ return (1);
+ }
+ return;
+ case RUSERSPROC_NUM:
+.ft I
+ /*
+ * Code here to compute the number of users
+ * and assign it to the variable \fInusers\fP
+ */
+.ft CW
+ nusers2 = nusers;
+ switch (rqstp->rq_vers) {
+ case RUSERSVERS_ORIG:
+ if (!svc_sendreply(transp, xdr_u_long,
+ &nusers)) {
+ fprintf(stderr,"can't reply to RPC call\en");
+ }
+ break;
+ case RUSERSVERS_SHORT:
+ if (!svc_sendreply(transp, xdr_u_short,
+ &nusers2)) {
+ fprintf(stderr,"can't reply to RPC call\en");
+ }
+ break;
+ }
+ default:
+ svcerr_noproc(transp);
+ return;
+ }
+}
+.vs
+.DE
+.KS
+.NH 2
+\&TCP
+.IX "TCP"
+.LP
+Here is an example that is essentially
+.I rcp.
+The initiator of the RPC
+.I snd
+call takes its standard input and sends it to the server
+.I rcv
+which prints it on standard output.
+The RPC call uses TCP.
+This also illustrates an XDR procedure that behaves differently
+on serialization than on deserialization.
+.ie t .DS
+.el .DS L
+.vs 11
+.ft I
+/*
+ * The xdr routine:
+ * on decode, read from wire, write onto fp
+ * on encode, read from fp, write onto wire
+ */
+.ft CW
+#include <stdio.h>
+#include <rpc/rpc.h>
+
+xdr_rcp(xdrs, fp)
+ XDR *xdrs;
+ FILE *fp;
+{
+ unsigned long size;
+ char buf[BUFSIZ], *p;
+
+ if (xdrs->x_op == XDR_FREE)/* nothing to free */
+ return 1;
+ while (1) {
+ if (xdrs->x_op == XDR_ENCODE) {
+ if ((size = fread(buf, sizeof(char), BUFSIZ,
+ fp)) == 0 && ferror(fp)) {
+ fprintf(stderr, "can't fread\en");
+ return (1);
+ }
+ }
+ p = buf;
+ if (!xdr_bytes(xdrs, &p, &size, BUFSIZ))
+ return 0;
+ if (size == 0)
+ return 1;
+ if (xdrs->x_op == XDR_DECODE) {
+ if (fwrite(buf, sizeof(char), size,
+ fp) != size) {
+ fprintf(stderr, "can't fwrite\en");
+ return (1);
+ }
+ }
+ }
+}
+.vs
+.DE
+.KE
+.ie t .DS
+.el .DS L
+.vs 11
+.ft I
+/*
+ * The sender routines
+ */
+.ft CW
+#include <stdio.h>
+#include <netdb.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int xdr_rcp();
+ int err;
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s servername\en", argv[0]);
+ exit(-1);
+ }
+ if ((err = callrpctcp(argv[1], RCPPROG, RCPPROC,
+ RCPVERS, xdr_rcp, stdin, xdr_void, 0) != 0)) {
+ clnt_perrno(err);
+ fprintf(stderr, "can't make RPC call\en");
+ exit(1);
+ }
+ exit(0);
+}
+
+callrpctcp(host, prognum, procnum, versnum,
+ inproc, in, outproc, out)
+ char *host, *in, *out;
+ xdrproc_t inproc, outproc;
+{
+ struct sockaddr_in server_addr;
+ int socket = RPC_ANYSOCK;
+ enum clnt_stat clnt_stat;
+ struct hostent *hp;
+ register CLIENT *client;
+ struct timeval total_timeout;
+
+ if ((hp = gethostbyname(host)) == NULL) {
+ fprintf(stderr, "can't get addr for '%s'\en", host);
+ return (-1);
+ }
+ bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr,
+ hp->h_length);
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_port = 0;
+ if ((client = clnttcp_create(&server_addr, prognum,
+ versnum, &socket, BUFSIZ, BUFSIZ)) == NULL) {
+ perror("rpctcp_create");
+ return (-1);
+ }
+ total_timeout.tv_sec = 20;
+ total_timeout.tv_usec = 0;
+ clnt_stat = clnt_call(client, procnum,
+ inproc, in, outproc, out, total_timeout);
+ clnt_destroy(client);
+ return (int)clnt_stat;
+}
+.vs
+.DE
+.ie t .DS
+.el .DS L
+.vs 11
+.ft I
+/*
+ * The receiving routines
+ */
+.ft CW
+#include <stdio.h>
+#include <rpc/rpc.h>
+
+main()
+{
+ register SVCXPRT *transp;
+ int rcp_service(), xdr_rcp();
+
+ if ((transp = svctcp_create(RPC_ANYSOCK,
+ BUFSIZ, BUFSIZ)) == NULL) {
+ fprintf("svctcp_create: error\en");
+ exit(1);
+ }
+ pmap_unset(RCPPROG, RCPVERS);
+ if (!svc_register(transp,
+ RCPPROG, RCPVERS, rcp_service, IPPROTO_TCP)) {
+ fprintf(stderr, "svc_register: error\en");
+ exit(1);
+ }
+ svc_run(); /* \fInever returns\fP */
+ fprintf(stderr, "svc_run should never return\en");
+}
+
+rcp_service(rqstp, transp)
+ register struct svc_req *rqstp;
+ register SVCXPRT *transp;
+{
+ switch (rqstp->rq_proc) {
+ case NULLPROC:
+ if (svc_sendreply(transp, xdr_void, 0) == 0) {
+ fprintf(stderr, "err: rcp_service");
+ return (1);
+ }
+ return;
+ case RCPPROC_FP:
+ if (!svc_getargs(transp, xdr_rcp, stdout)) {
+ svcerr_decode(transp);
+ return;
+ }
+ if (!svc_sendreply(transp, xdr_void, 0)) {
+ fprintf(stderr, "can't reply\en");
+ return;
+ }
+ return (0);
+ default:
+ svcerr_noproc(transp);
+ return;
+ }
+}
+.vs
+.DE
+.NH 2
+\&Callback Procedures
+.IX RPC "callback procedures"
+.LP
+Occasionally, it is useful to have a server become a client,
+and make an RPC call back to the process which is its client.
+An example is remote debugging,
+where the client is a window system program,
+and the server is a debugger running on the remote machine.
+Most of the time,
+the user clicks a mouse button at the debugging window,
+which converts this to a debugger command,
+and then makes an RPC call to the server
+(where the debugger is actually running),
+telling it to execute that command.
+However, when the debugger hits a breakpoint, the roles are reversed,
+and the debugger wants to make an rpc call to the window program,
+so that it can inform the user that a breakpoint has been reached.
+.LP
+In order to do an RPC callback,
+you need a program number to make the RPC call on.
+Since this will be a dynamically generated program number,
+it should be in the transient range,
+.I "0x40000000 - 0x5fffffff" .
+The routine
+.I gettransient()
+returns a valid program number in the transient range,
+and registers it with the portmapper.
+It only talks to the portmapper running on the same machine as the
+.I gettransient()
+routine itself. The call to
+.I pmap_set()
+is a test and set operation,
+in that it indivisibly tests whether a program number
+has already been registered,
+and if it has not, then reserves it. On return, the
+.I sockp
+argument will contain a socket that can be used
+as the argument to an
+.I svcudp_create()
+or
+.I svctcp_create()
+call.
+.ie t .DS
+.el .DS L
+.ft CW
+.vs 11
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+
+gettransient(proto, vers, sockp)
+ int proto, vers, *sockp;
+{
+ static int prognum = 0x40000000;
+ int s, len, socktype;
+ struct sockaddr_in addr;
+
+ switch(proto) {
+ case IPPROTO_UDP:
+ socktype = SOCK_DGRAM;
+ break;
+ case IPPROTO_TCP:
+ socktype = SOCK_STREAM;
+ break;
+ default:
+ fprintf(stderr, "unknown protocol type\en");
+ return 0;
+ }
+ if (*sockp == RPC_ANYSOCK) {
+ if ((s = socket(AF_INET, socktype, 0)) < 0) {
+ perror("socket");
+ return (0);
+ }
+ *sockp = s;
+ }
+ else
+ s = *sockp;
+ addr.sin_addr.s_addr = 0;
+ addr.sin_family = AF_INET;
+ addr.sin_port = 0;
+ len = sizeof(addr);
+.ft I
+ /*
+ * may be already bound, so don't check for error
+ */
+.ft CW
+ bind(s, &addr, len);
+ if (getsockname(s, &addr, &len)< 0) {
+ perror("getsockname");
+ return (0);
+ }
+ while (!pmap_set(prognum++, vers, proto,
+ ntohs(addr.sin_port))) continue;
+ return (prognum-1);
+}
+.vs
+.DE
+.SH
+Note:
+.I
+The call to
+.I ntohs()
+is necessary to ensure that the port number in
+.I "addr.sin_port" ,
+which is in
+.I network
+byte order, is passed in
+.I host
+byte order (as
+.I pmap_set()
+expects). See the
+.I byteorder(3N)
+man page for more details on the conversion of network
+addresses from network to host byte order.
+.KS
+.LP
+The following pair of programs illustrate how to use the
+.I gettransient()
+routine.
+The client makes an RPC call to the server,
+passing it a transient program number.
+Then the client waits around to receive a callback
+from the server at that program number.
+The server registers the program
+.I EXAMPLEPROG
+so that it can receive the RPC call
+informing it of the callback program number.
+Then at some random time (on receiving an
+.I ALRM
+signal in this example), it sends a callback RPC call,
+using the program number it received earlier.
+.ie t .DS
+.el .DS L
+.vs 11
+.ft I
+/*
+ * client
+ */
+.ft CW
+#include <stdio.h>
+#include <rpc/rpc.h>
+
+int callback();
+char hostname[256];
+
+main()
+{
+ int x, ans, s;
+ SVCXPRT *xprt;
+
+ gethostname(hostname, sizeof(hostname));
+ s = RPC_ANYSOCK;
+ x = gettransient(IPPROTO_UDP, 1, &s);
+ fprintf(stderr, "client gets prognum %d\en", x);
+ if ((xprt = svcudp_create(s)) == NULL) {
+ fprintf(stderr, "rpc_server: svcudp_create\en");
+ exit(1);
+ }
+.ft I
+ /* protocol is 0 - gettransient does registering
+ */
+.ft CW
+ (void)svc_register(xprt, x, 1, callback, 0);
+ ans = callrpc(hostname, EXAMPLEPROG, EXAMPLEVERS,
+ EXAMPLEPROC_CALLBACK, xdr_int, &x, xdr_void, 0);
+ if ((enum clnt_stat) ans != RPC_SUCCESS) {
+ fprintf(stderr, "call: ");
+ clnt_perrno(ans);
+ fprintf(stderr, "\en");
+ }
+ svc_run();
+ fprintf(stderr, "Error: svc_run shouldn't return\en");
+}
+
+callback(rqstp, transp)
+ register struct svc_req *rqstp;
+ register SVCXPRT *transp;
+{
+ switch (rqstp->rq_proc) {
+ case 0:
+ if (!svc_sendreply(transp, xdr_void, 0)) {
+ fprintf(stderr, "err: exampleprog\en");
+ return (1);
+ }
+ return (0);
+ case 1:
+ if (!svc_getargs(transp, xdr_void, 0)) {
+ svcerr_decode(transp);
+ return (1);
+ }
+ fprintf(stderr, "client got callback\en");
+ if (!svc_sendreply(transp, xdr_void, 0)) {
+ fprintf(stderr, "err: exampleprog");
+ return (1);
+ }
+ }
+}
+.vs
+.DE
+.KE
+.ie t .DS
+.el .DS L
+.vs 11
+.ft I
+/*
+ * server
+ */
+.ft CW
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/signal.h>
+
+char *getnewprog();
+char hostname[256];
+int docallback();
+int pnum; /* \fIprogram number for callback routine\fP */
+
+main()
+{
+ gethostname(hostname, sizeof(hostname));
+ registerrpc(EXAMPLEPROG, EXAMPLEVERS,
+ EXAMPLEPROC_CALLBACK, getnewprog, xdr_int, xdr_void);
+ fprintf(stderr, "server going into svc_run\en");
+ signal(SIGALRM, docallback);
+ alarm(10);
+ svc_run();
+ fprintf(stderr, "Error: svc_run shouldn't return\en");
+}
+
+char *
+getnewprog(pnump)
+ char *pnump;
+{
+ pnum = *(int *)pnump;
+ return NULL;
+}
+
+docallback()
+{
+ int ans;
+
+ ans = callrpc(hostname, pnum, 1, 1, xdr_void, 0,
+ xdr_void, 0);
+ if (ans != 0) {
+ fprintf(stderr, "server: ");
+ clnt_perrno(ans);
+ fprintf(stderr, "\en");
+ }
+}
+.vs
+.DE
diff --git a/lib/libc/rpc/PSD.doc/rpc.rfc.ms b/lib/libc/rpc/PSD.doc/rpc.rfc.ms
new file mode 100644
index 0000000..af9c2df
--- /dev/null
+++ b/lib/libc/rpc/PSD.doc/rpc.rfc.ms
@@ -0,0 +1,1302 @@
+.\"
+.\" Must use -- tbl -- with this one
+.\"
+.\" @(#)rpc.rfc.ms 2.2 88/08/05 4.0 RPCSRC
+.de BT
+.if \\n%=1 .tl ''- % -''
+..
+.ND
+.\" prevent excess underlining in nroff
+.if n .fp 2 R
+.OH 'Remote Procedure Calls: Protocol Specification''Page %'
+.EH 'Page %''Remote Procedure Calls: Protocol Specification'
+.if \\n%=1 .bp
+.SH
+\&Remote Procedure Calls: Protocol Specification
+.LP
+.NH 0
+\&Status of this Memo
+.LP
+Note: This chapter specifies a protocol that Sun Microsystems, Inc.,
+and others are using.
+It has been designated RFC1050 by the ARPA Network
+Information Center.
+.LP
+.NH 1
+\&Introduction
+.LP
+This chapter specifies a message protocol used in implementing
+Sun's Remote Procedure Call (RPC) package. (The message protocol is
+specified with the External Data Representation (XDR) language.
+See the
+.I "External Data Representation Standard: Protocol Specification"
+for the details. Here, we assume that the reader is familiar
+with XDR and do not attempt to justify it or its uses). The paper
+by Birrell and Nelson [1] is recommended as an excellent background
+to and justification of RPC.
+.NH 2
+\&Terminology
+.LP
+This chapter discusses servers, services, programs, procedures,
+clients, and versions. A server is a piece of software where network
+services are implemented. A network service is a collection of one
+or more remote programs. A remote program implements one or more
+remote procedures; the procedures, their parameters, and results are
+documented in the specific program's protocol specification (see the
+\fIPort Mapper Program Protocol\fP\, below, for an example). Network
+clients are pieces of software that initiate remote procedure calls
+to services. A server may support more than one version of a remote
+program in order to be forward compatible with changing protocols.
+.LP
+For example, a network file service may be composed of two programs.
+One program may deal with high-level applications such as file system
+access control and locking. The other may deal with low-level file
+IO and have procedures like "read" and "write". A client machine of
+the network file service would call the procedures associated with
+the two programs of the service on behalf of some user on the client
+machine.
+.NH 2
+\&The RPC Model
+.LP
+The remote procedure call model is similar to the local procedure
+call model. In the local case, the caller places arguments to a
+procedure in some well-specified location (such as a result
+register). It then transfers control to the procedure, and
+eventually gains back control. At that point, the results of the
+procedure are extracted from the well-specified location, and the
+caller continues execution.
+.LP
+The remote procedure call is similar, in that one thread of control
+logically winds through two processes\(emone is the caller's process,
+the other is a server's process. That is, the caller process sends a
+call message to the server process and waits (blocks) for a reply
+message. The call message contains the procedure's parameters, among
+other things. The reply message contains the procedure's results,
+among other things. Once the reply message is received, the results
+of the procedure are extracted, and caller's execution is resumed.
+.LP
+On the server side, a process is dormant awaiting the arrival of a
+call message. When one arrives, the server process extracts the
+procedure's parameters, computes the results, sends a reply message,
+and then awaits the next call message.
+.LP
+Note that in this model, only one of the two processes is active at
+any given time. However, this model is only given as an example.
+The RPC protocol makes no restrictions on the concurrency model
+implemented, and others are possible. For example, an implementation
+may choose to have RPC calls be asynchronous, so that the client may
+do useful work while waiting for the reply from the server. Another
+possibility is to have the server create a task to process an
+incoming request, so that the server can be free to receive other
+requests.
+.NH 2
+\&Transports and Semantics
+.LP
+The RPC protocol is independent of transport protocols. That is, RPC
+does not care how a message is passed from one process to another.
+The protocol deals only with specification and interpretation of
+messages.
+.LP
+It is important to point out that RPC does not try to implement any
+kind of reliability and that the application must be aware of the
+type of transport protocol underneath RPC. If it knows it is running
+on top of a reliable transport such as TCP/IP[6], then most of the
+work is already done for it. On the other hand, if it is running on
+top of an unreliable transport such as UDP/IP[7], it must implement
+is own retransmission and time-out policy as the RPC layer does not
+provide this service.
+.LP
+Because of transport independence, the RPC protocol does not attach
+specific semantics to the remote procedures or their execution.
+Semantics can be inferred from (but should be explicitly specified
+by) the underlying transport protocol. For example, consider RPC
+running on top of an unreliable transport such as UDP/IP. If an
+application retransmits RPC messages after short time-outs, the only
+thing it can infer if it receives no reply is that the procedure was
+executed zero or more times. If it does receive a reply, then it can
+infer that the procedure was executed at least once.
+.LP
+A server may wish to remember previously granted requests from a
+client and not regrant them in order to insure some degree of
+execute-at-most-once semantics. A server can do this by taking
+advantage of the transaction ID that is packaged with every RPC
+request. The main use of this transaction is by the client RPC layer
+in matching replies to requests. However, a client application may
+choose to reuse its previous transaction ID when retransmitting a
+request. The server application, knowing this fact, may choose to
+remember this ID after granting a request and not regrant requests
+with the same ID in order to achieve some degree of
+execute-at-most-once semantics. The server is not allowed to examine
+this ID in any other way except as a test for equality.
+.LP
+On the other hand, if using a reliable transport such as TCP/IP, the
+application can infer from a reply message that the procedure was
+executed exactly once, but if it receives no reply message, it cannot
+assume the remote procedure was not executed. Note that even if a
+connection-oriented protocol like TCP is used, an application still
+needs time-outs and reconnection to handle server crashes.
+.LP
+There are other possibilities for transports besides datagram- or
+connection-oriented protocols. For example, a request-reply protocol
+such as VMTP[2] is perhaps the most natural transport for RPC.
+.SH
+.I
+NOTE: At Sun, RPC is currently implemented on top of both TCP/IP
+and UDP/IP transports.
+.LP
+.NH 2
+\&Binding and Rendezvous Independence
+.LP
+The act of binding a client to a service is NOT part of the remote
+procedure call specification. This important and necessary function
+is left up to some higher-level software. (The software may use RPC
+itself\(emsee the \fIPort Mapper Program Protocol\fP\, below).
+.LP
+Implementors should think of the RPC protocol as the jump-subroutine
+instruction ("JSR") of a network; the loader (binder) makes JSR
+useful, and the loader itself uses JSR to accomplish its task.
+Likewise, the network makes RPC useful, using RPC to accomplish this
+task.
+.NH 2
+\&Authentication
+.LP
+The RPC protocol provides the fields necessary for a client to
+identify itself to a service and vice-versa. Security and access
+control mechanisms can be built on top of the message authentication.
+Several different authentication protocols can be supported. A field
+in the RPC header indicates which protocol is being used. More
+information on specific authentication protocols can be found in the
+\fIAuthentication Protocols\fP\,
+below.
+.KS
+.NH 1
+\&RPC Protocol Requirements
+.LP
+The RPC protocol must provide for the following:
+.IP 1.
+Unique specification of a procedure to be called.
+.IP 2.
+Provisions for matching response messages to request messages.
+.KE
+.IP 3.
+Provisions for authenticating the caller to service and vice-versa.
+.LP
+Besides these requirements, features that detect the following are
+worth supporting because of protocol roll-over errors, implementation
+bugs, user error, and network administration:
+.IP 1.
+RPC protocol mismatches.
+.IP 2.
+Remote program protocol version mismatches.
+.IP 3.
+Protocol errors (such as misspecification of a procedure's parameters).
+.IP 4.
+Reasons why remote authentication failed.
+.IP 5.
+Any other reasons why the desired procedure was not called.
+.NH 2
+\&Programs and Procedures
+.LP
+The RPC call message has three unsigned fields: remote program
+number, remote program version number, and remote procedure number.
+The three fields uniquely identify the procedure to be called.
+Program numbers are administered by some central authority (like
+Sun). Once an implementor has a program number, he can implement his
+remote program; the first implementation would most likely have the
+version number of 1. Because most new protocols evolve into better,
+stable, and mature protocols, a version field of the call message
+identifies which version of the protocol the caller is using.
+Version numbers make speaking old and new protocols through the same
+server process possible.
+.LP
+The procedure number identifies the procedure to be called. These
+numbers are documented in the specific program's protocol
+specification. For example, a file service's protocol specification
+may state that its procedure number 5 is "read" and procedure number
+12 is "write".
+.LP
+Just as remote program protocols may change over several versions,
+the actual RPC message protocol could also change. Therefore, the
+call message also has in it the RPC version number, which is always
+equal to two for the version of RPC described here.
+.LP
+The reply message to a request message has enough information to
+distinguish the following error conditions:
+.IP 1.
+The remote implementation of RPC does speak protocol version 2.
+The lowest and highest supported RPC version numbers are returned.
+.IP 2.
+The remote program is not available on the remote system.
+.IP 3.
+The remote program does not support the requested version number.
+The lowest and highest supported remote program version numbers are
+returned.
+.IP 4.
+The requested procedure number does not exist. (This is usually a
+caller side protocol or programming error.)
+.IP 5.
+The parameters to the remote procedure appear to be garbage from the
+server's point of view. (Again, this is usually caused by a
+disagreement about the protocol between client and service.)
+.NH 2
+\&Authentication
+.LP
+Provisions for authentication of caller to service and vice-versa are
+provided as a part of the RPC protocol. The call message has two
+authentication fields, the credentials and verifier. The reply
+message has one authentication field, the response verifier. The RPC
+protocol specification defines all three fields to be the following
+opaque type:
+.DS
+.ft CW
+.vs 11
+enum auth_flavor {
+ AUTH_NULL = 0,
+ AUTH_UNIX = 1,
+ AUTH_SHORT = 2,
+ AUTH_DES = 3
+ /* \fIand more to be defined\fP */
+};
+
+struct opaque_auth {
+ auth_flavor flavor;
+ opaque body<400>;
+};
+.DE
+.LP
+In simple English, any
+.I opaque_auth
+structure is an
+.I auth_flavor
+enumeration followed by bytes which are opaque to the RPC protocol
+implementation.
+.LP
+The interpretation and semantics of the data contained within the
+authentication fields is specified by individual, independent
+authentication protocol specifications. (See
+\fIAuthentication Protocols\fP\,
+below, for definitions of the various authentication protocols.)
+.LP
+If authentication parameters were rejected, the response message
+contains information stating why they were rejected.
+.NH 2
+\&Program Number Assignment
+.LP
+Program numbers are given out in groups of
+.I 0x20000000
+(decimal 536870912) according to the following chart:
+.TS
+box tab (&) ;
+lfI lfI
+rfL cfI .
+Program Numbers&Description
+_
+.sp .5
+0 - 1fffffff&Defined by Sun
+20000000 - 3fffffff&Defined by user
+40000000 - 5fffffff&Transient
+60000000 - 7fffffff&Reserved
+80000000 - 9fffffff&Reserved
+a0000000 - bfffffff&Reserved
+c0000000 - dfffffff&Reserved
+e0000000 - ffffffff&Reserved
+.TE
+.LP
+The first group is a range of numbers administered by Sun
+Microsystems and should be identical for all sites. The second range
+is for applications peculiar to a particular site. This range is
+intended primarily for debugging new programs. When a site develops
+an application that might be of general interest, that application
+should be given an assigned number in the first range. The third
+group is for applications that generate program numbers dynamically.
+The final groups are reserved for future use, and should not be used.
+.NH 2
+\&Other Uses of the RPC Protocol
+.LP
+The intended use of this protocol is for calling remote procedures.
+That is, each call message is matched with a response message.
+However, the protocol itself is a message-passing protocol with which
+other (non-RPC) protocols can be implemented. Sun currently uses, or
+perhaps abuses, the RPC message protocol for the following two
+(non-RPC) protocols: batching (or pipelining) and broadcast RPC.
+These two protocols are discussed but not defined below.
+.NH 3
+\&Batching
+.LP
+Batching allows a client to send an arbitrarily large sequence of
+call messages to a server; batching typically uses reliable byte
+stream protocols (like TCP/IP) for its transport. In the case of
+batching, the client never waits for a reply from the server, and the
+server does not send replies to batch requests. A sequence of batch
+calls is usually terminated by a legitimate RPC in order to flush the
+pipeline (with positive acknowledgement).
+.NH 3
+\&Broadcast RPC
+.LP
+In broadcast RPC-based protocols, the client sends a broadcast packet
+to the network and waits for numerous replies. Broadcast RPC uses
+unreliable, packet-based protocols (like UDP/IP) as its transports.
+Servers that support broadcast protocols only respond when the
+request is successfully processed, and are silent in the face of
+errors. Broadcast RPC uses the Port Mapper RPC service to achieve
+its semantics. See the \fIPort Mapper Program Protocol\fP\, below,
+for more information.
+.KS
+.NH 1
+\&The RPC Message Protocol
+.LP
+This section defines the RPC message protocol in the XDR data
+description language. The message is defined in a top-down style.
+.ie t .DS
+.el .DS L
+.ft CW
+enum msg_type {
+ CALL = 0,
+ REPLY = 1
+};
+
+.ft I
+/*
+* A reply to a call message can take on two forms:
+* The message was either accepted or rejected.
+*/
+.ft CW
+enum reply_stat {
+ MSG_ACCEPTED = 0,
+ MSG_DENIED = 1
+};
+
+.ft I
+/*
+* Given that a call message was accepted, the following is the
+* status of an attempt to call a remote procedure.
+*/
+.ft CW
+enum accept_stat {
+ SUCCESS = 0, /* \fIRPC executed successfully \fP*/
+ PROG_UNAVAIL = 1, /* \fIremote hasn't exported program \fP*/
+ PROG_MISMATCH = 2, /* \fIremote can't support version # \fP*/
+ PROC_UNAVAIL = 3, /* \fIprogram can't support procedure \fP*/
+ GARBAGE_ARGS = 4 /* \fIprocedure can't decode params \fP*/
+};
+.DE
+.ie t .DS
+.el .DS L
+.ft I
+/*
+* Reasons why a call message was rejected:
+*/
+.ft CW
+enum reject_stat {
+ RPC_MISMATCH = 0, /* \fIRPC version number != 2 \fP*/
+ AUTH_ERROR = 1 /* \fIremote can't authenticate caller \fP*/
+};
+
+.ft I
+/*
+* Why authentication failed:
+*/
+.ft CW
+enum auth_stat {
+ AUTH_BADCRED = 1, /* \fIbad credentials \fP*/
+ AUTH_REJECTEDCRED = 2, /* \fIclient must begin new session \fP*/
+ AUTH_BADVERF = 3, /* \fIbad verifier \fP*/
+ AUTH_REJECTEDVERF = 4, /* \fIverifier expired or replayed \fP*/
+ AUTH_TOOWEAK = 5 /* \fIrejected for security reasons \fP*/
+};
+.DE
+.KE
+.ie t .DS
+.el .DS L
+.ft I
+/*
+* The RPC message:
+* All messages start with a transaction identifier, xid,
+* followed by a two-armed discriminated union. The union's
+* discriminant is a msg_type which switches to one of the two
+* types of the message. The xid of a \fIREPLY\fP message always
+* matches that of the initiating \fICALL\fP message. NB: The xid
+* field is only used for clients matching reply messages with
+* call messages or for servers detecting retransmissions; the
+* service side cannot treat this id as any type of sequence
+* number.
+*/
+.ft CW
+struct rpc_msg {
+ unsigned int xid;
+ union switch (msg_type mtype) {
+ case CALL:
+ call_body cbody;
+ case REPLY:
+ reply_body rbody;
+ } body;
+};
+.DE
+.ie t .DS
+.el .DS L
+.ft I
+/*
+* Body of an RPC request call:
+* In version 2 of the RPC protocol specification, rpcvers must
+* be equal to 2. The fields prog, vers, and proc specify the
+* remote program, its version number, and the procedure within
+* the remote program to be called. After these fields are two
+* authentication parameters: cred (authentication credentials)
+* and verf (authentication verifier). The two authentication
+* parameters are followed by the parameters to the remote
+* procedure, which are specified by the specific program
+* protocol.
+*/
+.ft CW
+struct call_body {
+ unsigned int rpcvers; /* \fImust be equal to two (2) \fP*/
+ unsigned int prog;
+ unsigned int vers;
+ unsigned int proc;
+ opaque_auth cred;
+ opaque_auth verf;
+ /* \fIprocedure specific parameters start here \fP*/
+};
+.DE
+.ie t .DS
+.el .DS L
+.ft I
+/*
+* Body of a reply to an RPC request:
+* The call message was either accepted or rejected.
+*/
+.ft CW
+union reply_body switch (reply_stat stat) {
+ case MSG_ACCEPTED:
+ accepted_reply areply;
+ case MSG_DENIED:
+ rejected_reply rreply;
+} reply;
+.DE
+.ie t .DS
+.el .DS L
+.ft I
+/*
+* Reply to an RPC request that was accepted by the server:
+* there could be an error even though the request was accepted.
+* The first field is an authentication verifier that the server
+* generates in order to validate itself to the caller. It is
+* followed by a union whose discriminant is an enum
+* accept_stat. The \fISUCCESS\fP arm of the union is protocol
+* specific. The \fIPROG_UNAVAIL\fP, \fIPROC_UNAVAIL\fP, and \fIGARBAGE_ARGP\fP
+* arms of the union are void. The \fIPROG_MISMATCH\fP arm specifies
+* the lowest and highest version numbers of the remote program
+* supported by the server.
+*/
+.ft CW
+struct accepted_reply {
+ opaque_auth verf;
+ union switch (accept_stat stat) {
+ case SUCCESS:
+ opaque results[0];
+ /* \fIprocedure-specific results start here\fP */
+ case PROG_MISMATCH:
+ struct {
+ unsigned int low;
+ unsigned int high;
+ } mismatch_info;
+ default:
+.ft I
+ /*
+ * Void. Cases include \fIPROG_UNAVAIL, PROC_UNAVAIL\fP,
+ * and \fIGARBAGE_ARGS\fP.
+ */
+.ft CW
+ void;
+ } reply_data;
+};
+.DE
+.ie t .DS
+.el .DS L
+.ft I
+/*
+* Reply to an RPC request that was rejected by the server:
+* The request can be rejected for two reasons: either the
+* server is not running a compatible version of the RPC
+* protocol (\fIRPC_MISMATCH\fP), or the server refuses to
+* authenticate the caller (\fIAUTH_ERROR\fP). In case of an RPC
+* version mismatch, the server returns the lowest and highest
+* supported RPC version numbers. In case of refused
+* authentication, failure status is returned.
+*/
+.ft CW
+union rejected_reply switch (reject_stat stat) {
+ case RPC_MISMATCH:
+ struct {
+ unsigned int low;
+ unsigned int high;
+ } mismatch_info;
+ case AUTH_ERROR:
+ auth_stat stat;
+};
+.DE
+.NH 1
+\&Authentication Protocols
+.LP
+As previously stated, authentication parameters are opaque, but
+open-ended to the rest of the RPC protocol. This section defines
+some "flavors" of authentication implemented at (and supported by)
+Sun. Other sites are free to invent new authentication types, with
+the same rules of flavor number assignment as there is for program
+number assignment.
+.NH 2
+\&Null Authentication
+.LP
+Often calls must be made where the caller does not know who he is or
+the server does not care who the caller is. In this case, the flavor
+value (the discriminant of the \fIopaque_auth\fP's union) of the RPC
+message's credentials, verifier, and response verifier is
+.I AUTH_NULL .
+The bytes of the opaque_auth's body are undefined.
+It is recommended that the opaque length be zero.
+.NH 2
+\&UNIX Authentication
+.LP
+The caller of a remote procedure may wish to identify himself as he
+is identified on a UNIX system. The value of the credential's
+discriminant of an RPC call message is
+.I AUTH_UNIX .
+The bytes of
+the credential's opaque body encode the following structure:
+.DS
+.ft CW
+struct auth_unix {
+ unsigned int stamp;
+ string machinename<255>;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int gids<10>;
+};
+.DE
+The
+.I stamp
+is an arbitrary ID which the caller machine may
+generate. The
+.I machinename
+is the name of the caller's machine (like "krypton"). The
+.I uid
+is the caller's effective user ID. The
+.I gid
+is the caller's effective group ID. The
+.I gids
+is a
+counted array of groups which contain the caller as a member. The
+verifier accompanying the credentials should be of
+.I AUTH_NULL
+(defined above).
+.LP
+The value of the discriminant of the response verifier received in
+the reply message from the server may be
+.I AUTH_NULL
+or
+.I AUTH_SHORT .
+In the case of
+.I AUTH_SHORT ,
+the bytes of the response verifier's string encode an opaque
+structure. This new opaque structure may now be passed to the server
+instead of the original
+.I AUTH_UNIX
+flavor credentials. The server keeps a cache which maps shorthand
+opaque structures (passed back by way of an
+.I AUTH_SHORT
+style response verifier) to the original credentials of the caller.
+The caller can save network bandwidth and server cpu cycles by using
+the new credentials.
+.LP
+The server may flush the shorthand opaque structure at any time. If
+this happens, the remote procedure call message will be rejected due
+to an authentication error. The reason for the failure will be
+.I AUTH_REJECTEDCRED .
+At this point, the caller may wish to try the original
+.I AUTH_UNIX
+style of credentials.
+.KS
+.NH 2
+\&DES Authentication
+.LP
+UNIX authentication suffers from two major problems:
+.IP 1.
+The naming is too UNIX-system oriented.
+.IP 2.
+There is no verifier, so credentials can easily be faked.
+.LP
+DES authentication attempts to fix these two problems.
+.KE
+.NH 3
+\&Naming
+.LP
+The first problem is handled by addressing the caller by a simple
+string of characters instead of by an operating system specific
+integer. This string of characters is known as the "netname" or
+network name of the caller. The server is not allowed to interpret
+the contents of the caller's name in any other way except to
+identify the caller. Thus, netnames should be unique for every
+caller in the internet.
+.LP
+It is up to each operating system's implementation of DES
+authentication to generate netnames for its users that insure this
+uniqueness when they call upon remote servers. Operating systems
+already know how to distinguish users local to their systems. It is
+usually a simple matter to extend this mechanism to the network.
+For example, a UNIX user at Sun with a user ID of 515 might be
+assigned the following netname: "unix.515@sun.com". This netname
+contains three items that serve to insure it is unique. Going
+backwards, there is only one naming domain called "sun.com" in the
+internet. Within this domain, there is only one UNIX user with
+user ID 515. However, there may be another user on another
+operating system, for example VMS, within the same naming domain
+that, by coincidence, happens to have the same user ID. To insure
+that these two users can be distinguished we add the operating
+system name. So one user is "unix.515@sun.com" and the other is
+"vms.515@sun.com".
+.LP
+The first field is actually a naming method rather than an
+operating system name. It just happens that today there is almost
+a one-to-one correspondence between naming methods and operating
+systems. If the world could agree on a naming standard, the first
+field could be the name of that standard, instead of an operating
+system name.
+.LP
+.NH 3
+\&DES Authentication Verifiers
+.LP
+Unlike UNIX authentication, DES authentication does have a verifier
+so the server can validate the client's credential (and
+vice-versa). The contents of this verifier is primarily an
+encrypted timestamp. The server can decrypt this timestamp, and if
+it is close to what the real time is, then the client must have
+encrypted it correctly. The only way the client could encrypt it
+correctly is to know the "conversation key" of the RPC session. And
+if the client knows the conversation key, then it must be the real
+client.
+.LP
+The conversation key is a DES [5] key which the client generates
+and notifies the server of in its first RPC call. The conversation
+key is encrypted using a public key scheme in this first
+transaction. The particular public key scheme used in DES
+authentication is Diffie-Hellman [3] with 192-bit keys. The
+details of this encryption method are described later.
+.LP
+The client and the server need the same notion of the current time
+in order for all of this to work. If network time synchronization
+cannot be guaranteed, then client can synchronize with the server
+before beginning the conversation, perhaps by consulting the
+Internet Time Server (TIME[4]).
+.LP
+The way a server determines if a client timestamp is valid is
+somewhat complicated. For any other transaction but the first, the
+server just checks for two things:
+.IP 1.
+the timestamp is greater than the one previously seen from the
+same client.
+.IP 2.
+the timestamp has not expired.
+.LP
+A timestamp is expired if the server's time is later than the sum
+of the client's timestamp plus what is known as the client's
+"window". The "window" is a number the client passes (encrypted)
+to the server in its first transaction. You can think of it as a
+lifetime for the credential.
+.LP
+This explains everything but the first transaction. In the first
+transaction, the server checks only that the timestamp has not
+expired. If this was all that was done though, then it would be
+quite easy for the client to send random data in place of the
+timestamp with a fairly good chance of succeeding. As an added
+check, the client sends an encrypted item in the first transaction
+known as the "window verifier" which must be equal to the window
+minus 1, or the server will reject the credential.
+.LP
+The client too must check the verifier returned from the server to
+be sure it is legitimate. The server sends back to the client the
+encrypted timestamp it received from the client, minus one second.
+If the client gets anything different than this, it will reject it.
+.LP
+.NH 3
+\&Nicknames and Clock Synchronization
+.LP
+After the first transaction, the server's DES authentication
+subsystem returns in its verifier to the client an integer
+"nickname" which the client may use in its further transactions
+instead of passing its netname, encrypted DES key and window every
+time. The nickname is most likely an index into a table on the
+server which stores for each client its netname, decrypted DES key
+and window.
+.LP
+Though they originally were synchronized, the client's and server's
+clocks can get out of sync again. When this happens the client RPC
+subsystem most likely will get back
+.I RPC_AUTHERROR
+at which point it should resynchronize.
+.LP
+A client may still get the
+.I RPC_AUTHERROR
+error even though it is
+synchronized with the server. The reason is that the server's
+nickname table is a limited size, and it may flush entries whenever
+it wants. A client should resend its original credential in this
+case and the server will give it a new nickname. If a server
+crashes, the entire nickname table gets flushed, and all clients
+will have to resend their original credentials.
+.KS
+.NH 3
+\&DES Authentication Protocol (in XDR language)
+.ie t .DS
+.el .DS L
+.ft I
+/*
+* There are two kinds of credentials: one in which the client uses
+* its full network name, and one in which it uses its "nickname"
+* (just an unsigned integer) given to it by the server. The
+* client must use its fullname in its first transaction with the
+* server, in which the server will return to the client its
+* nickname. The client may use its nickname in all further
+* transactions with the server. There is no requirement to use the
+* nickname, but it is wise to use it for performance reasons.
+*/
+.ft CW
+enum authdes_namekind {
+ ADN_FULLNAME = 0,
+ ADN_NICKNAME = 1
+};
+
+.ft I
+/*
+* A 64-bit block of encrypted DES data
+*/
+.ft CW
+typedef opaque des_block[8];
+
+.ft I
+/*
+* Maximum length of a network user's name
+*/
+.ft CW
+const MAXNETNAMELEN = 255;
+
+.ft I
+/*
+* A fullname contains the network name of the client, an encrypted
+* conversation key and the window. The window is actually a
+* lifetime for the credential. If the time indicated in the
+* verifier timestamp plus the window has past, then the server
+* should expire the request and not grant it. To insure that
+* requests are not replayed, the server should insist that
+* timestamps are greater than the previous one seen, unless it is
+* the first transaction. In the first transaction, the server
+* checks instead that the window verifier is one less than the
+* window.
+*/
+.ft CW
+struct authdes_fullname {
+string name<MAXNETNAMELEN>; /* \fIname of client \f(CW*/
+des_block key; /* \fIPK encrypted conversation key \f(CW*/
+unsigned int window; /* \fIencrypted window \f(CW*/
+};
+
+.ft I
+/*
+* A credential is either a fullname or a nickname
+*/
+.ft CW
+union authdes_cred switch (authdes_namekind adc_namekind) {
+ case ADN_FULLNAME:
+ authdes_fullname adc_fullname;
+ case ADN_NICKNAME:
+ unsigned int adc_nickname;
+};
+
+.ft I
+/*
+* A timestamp encodes the time since midnight, January 1, 1970.
+*/
+.ft CW
+struct timestamp {
+ unsigned int seconds; /* \fIseconds \fP*/
+ unsigned int useconds; /* \fIand microseconds \fP*/
+};
+
+.ft I
+/*
+* Verifier: client variety
+* The window verifier is only used in the first transaction. In
+* conjunction with a fullname credential, these items are packed
+* into the following structure before being encrypted:
+*
+* \f(CWstruct {\fP
+* \f(CWadv_timestamp; \fP-- one DES block
+* \f(CWadc_fullname.window; \fP-- one half DES block
+* \f(CWadv_winverf; \fP-- one half DES block
+* \f(CW}\fP
+* This structure is encrypted using CBC mode encryption with an
+* input vector of zero. All other encryptions of timestamps use
+* ECB mode encryption.
+*/
+.ft CW
+struct authdes_verf_clnt {
+ timestamp adv_timestamp; /* \fIencrypted timestamp \fP*/
+ unsigned int adv_winverf; /* \fIencrypted window verifier \fP*/
+};
+
+.ft I
+/*
+* Verifier: server variety
+* The server returns (encrypted) the same timestamp the client
+* gave it minus one second. It also tells the client its nickname
+* to be used in future transactions (unencrypted).
+*/
+.ft CW
+struct authdes_verf_svr {
+timestamp adv_timeverf; /* \fIencrypted verifier \fP*/
+unsigned int adv_nickname; /* \fInew nickname for client \fP*/
+};
+.DE
+.KE
+.NH 3
+\&Diffie-Hellman Encryption
+.LP
+In this scheme, there are two constants,
+.I BASE
+and
+.I MODULUS .
+The
+particular values Sun has chosen for these for the DES
+authentication protocol are:
+.ie t .DS
+.el .DS L
+.ft CW
+const BASE = 3;
+const MODULUS =
+ "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"; /* \fIhex \fP*/
+.DE
+.ft R
+The way this scheme works is best explained by an example. Suppose
+there are two people "A" and "B" who want to send encrypted
+messages to each other. So, A and B both generate "secret" keys at
+random which they do not reveal to anyone. Let these keys be
+represented as SK(A) and SK(B). They also publish in a public
+directory their "public" keys. These keys are computed as follows:
+.ie t .DS
+.el .DS L
+.ft CW
+PK(A) = ( BASE ** SK(A) ) mod MODULUS
+PK(B) = ( BASE ** SK(B) ) mod MODULUS
+.DE
+.ft R
+The "**" notation is used here to represent exponentiation. Now,
+both A and B can arrive at the "common" key between them,
+represented here as CK(A, B), without revealing their secret keys.
+.LP
+A computes:
+.ie t .DS
+.el .DS L
+.ft CW
+CK(A, B) = ( PK(B) ** SK(A)) mod MODULUS
+.DE
+.ft R
+while B computes:
+.ie t .DS
+.el .DS L
+.ft CW
+CK(A, B) = ( PK(A) ** SK(B)) mod MODULUS
+.DE
+.ft R
+These two can be shown to be equivalent:
+.ie t .DS
+.el .DS L
+.ft CW
+(PK(B) ** SK(A)) mod MODULUS = (PK(A) ** SK(B)) mod MODULUS
+.DE
+.ft R
+We drop the "mod MODULUS" parts and assume modulo arithmetic to
+simplify things:
+.ie t .DS
+.el .DS L
+.ft CW
+PK(B) ** SK(A) = PK(A) ** SK(B)
+.DE
+.ft R
+Then, replace PK(B) by what B computed earlier and likewise for
+PK(A).
+.ie t .DS
+.el .DS L
+.ft CW
+((BASE ** SK(B)) ** SK(A) = (BASE ** SK(A)) ** SK(B)
+.DE
+.ft R
+which leads to:
+.ie t .DS
+.el .DS L
+.ft CW
+BASE ** (SK(A) * SK(B)) = BASE ** (SK(A) * SK(B))
+.DE
+.ft R
+This common key CK(A, B) is not used to encrypt the timestamps used
+in the protocol. Rather, it is used only to encrypt a conversation
+key which is then used to encrypt the timestamps. The reason for
+doing this is to use the common key as little as possible, for fear
+that it could be broken. Breaking the conversation key is a far
+less serious offense, since conversations are relatively
+short-lived.
+.LP
+The conversation key is encrypted using 56-bit DES keys, yet the
+common key is 192 bits. To reduce the number of bits, 56 bits are
+selected from the common key as follows. The middle-most 8-bytes
+are selected from the common key, and then parity is added to the
+lower order bit of each byte, producing a 56-bit key with 8 bits of
+parity.
+.KS
+.NH 1
+\&Record Marking Standard
+.LP
+When RPC messages are passed on top of a byte stream protocol (like
+TCP/IP), it is necessary, or at least desirable, to delimit one
+message from another in order to detect and possibly recover from
+user protocol errors. This is called record marking (RM). Sun uses
+this RM/TCP/IP transport for passing RPC messages on TCP streams.
+One RPC message fits into one RM record.
+.LP
+A record is composed of one or more record fragments. A record
+fragment is a four-byte header followed by 0 to (2**31) - 1 bytes of
+fragment data. The bytes encode an unsigned binary number; as with
+XDR integers, the byte order is from highest to lowest. The number
+encodes two values\(ema boolean which indicates whether the fragment
+is the last fragment of the record (bit value 1 implies the fragment
+is the last fragment) and a 31-bit unsigned binary value which is the
+length in bytes of the fragment's data. The boolean value is the
+highest-order bit of the header; the length is the 31 low-order bits.
+(Note that this record specification is NOT in XDR standard form!)
+.KE
+.KS
+.NH 1
+\&The RPC Language
+.LP
+Just as there was a need to describe the XDR data-types in a formal
+language, there is also need to describe the procedures that operate
+on these XDR data-types in a formal language as well. We use the RPC
+Language for this purpose. It is an extension to the XDR language.
+The following example is used to describe the essence of the
+language.
+.NH 2
+\&An Example Service Described in the RPC Language
+.LP
+Here is an example of the specification of a simple ping program.
+.ie t .DS
+.el .DS L
+.vs 11
+.ft I
+/*
+* Simple ping program
+*/
+.ft CW
+program PING_PROG {
+ /* \fILatest and greatest version\fP */
+ version PING_VERS_PINGBACK {
+ void
+ PINGPROC_NULL(void) = 0;
+
+.ft I
+ /*
+ * Ping the caller, return the round-trip time
+ * (in microseconds). Returns -1 if the operation
+ * timed out.
+ */
+.ft CW
+ int
+ PINGPROC_PINGBACK(void) = 1;
+} = 2;
+
+.ft I
+/*
+* Original version
+*/
+.ft CW
+version PING_VERS_ORIG {
+ void
+ PINGPROC_NULL(void) = 0;
+ } = 1;
+} = 1;
+
+const PING_VERS = 2; /* \fIlatest version \fP*/
+.vs
+.DE
+.KE
+.LP
+The first version described is
+.I PING_VERS_PINGBACK
+with two procedures,
+.I PINGPROC_NULL
+and
+.I PINGPROC_PINGBACK .
+.I PINGPROC_NULL
+takes no arguments and returns no results, but it is useful for
+computing round-trip times from the client to the server and back
+again. By convention, procedure 0 of any RPC protocol should have
+the same semantics, and never require any kind of authentication.
+The second procedure is used for the client to have the server do a
+reverse ping operation back to the client, and it returns the amount
+of time (in microseconds) that the operation used. The next version,
+.I PING_VERS_ORIG ,
+is the original version of the protocol
+and it does not contain
+.I PINGPROC_PINGBACK
+procedure. It is useful
+for compatibility with old client programs, and as this program
+matures it may be dropped from the protocol entirely.
+.KS
+.NH 2
+\&The RPC Language Specification
+.LP
+The RPC language is identical to the XDR language, except for the
+added definition of a
+.I program-def
+described below.
+.DS
+.ft CW
+program-def:
+ "program" identifier "{"
+ version-def
+ version-def *
+ "}" "=" constant ";"
+
+version-def:
+ "version" identifier "{"
+ procedure-def
+ procedure-def *
+ "}" "=" constant ";"
+
+procedure-def:
+ type-specifier identifier "(" type-specifier ")"
+ "=" constant ";"
+.DE
+.KE
+.NH 2
+\&Syntax Notes
+.IP 1.
+The following keywords are added and cannot be used as
+identifiers: "program" and "version";
+.IP 2.
+A version name cannot occur more than once within the scope of
+a program definition. Nor can a version number occur more than once
+within the scope of a program definition.
+.IP 3.
+A procedure name cannot occur more than once within the scope
+of a version definition. Nor can a procedure number occur more than
+once within the scope of version definition.
+.IP 4.
+Program identifiers are in the same name space as constant and
+type identifiers.
+.IP 5.
+Only unsigned constants can be assigned to programs, versions
+and procedures.
+.NH 1
+\&Port Mapper Program Protocol
+.LP
+The port mapper program maps RPC program and version numbers to
+transport-specific port numbers. This program makes dynamic binding
+of remote programs possible.
+.LP
+This is desirable because the range of reserved port numbers is very
+small and the number of potential remote programs is very large. By
+running only the port mapper on a reserved port, the port numbers of
+other remote programs can be ascertained by querying the port mapper.
+.LP
+The port mapper also aids in broadcast RPC. A given RPC program will
+usually have different port number bindings on different machines, so
+there is no way to directly broadcast to all of these programs. The
+port mapper, however, does have a fixed port number. So, to
+broadcast to a given program, the client actually sends its message
+to the port mapper located at the broadcast address. Each port
+mapper that picks up the broadcast then calls the local service
+specified by the client. When the port mapper gets the reply from
+the local service, it sends the reply on back to the client.
+.KS
+.NH 2
+\&Port Mapper Protocol Specification (in RPC Language)
+.ie t .DS
+.el .DS L
+.ft CW
+.vs 11
+const PMAP_PORT = 111; /* \fIportmapper port number \fP*/
+
+.ft I
+/*
+* A mapping of (program, version, protocol) to port number
+*/
+.ft CW
+struct mapping {
+ unsigned int prog;
+ unsigned int vers;
+ unsigned int prot;
+ unsigned int port;
+};
+
+.ft I
+/*
+* Supported values for the "prot" field
+*/
+.ft CW
+const IPPROTO_TCP = 6; /* \fIprotocol number for TCP/IP \fP*/
+const IPPROTO_UDP = 17; /* \fIprotocol number for UDP/IP \fP*/
+
+.ft I
+/*
+* A list of mappings
+*/
+.ft CW
+struct *pmaplist {
+ mapping map;
+ pmaplist next;
+};
+.vs
+.DE
+.ie t .DS
+.el .DS L
+.vs 11
+.ft I
+/*
+* Arguments to callit
+*/
+.ft CW
+struct call_args {
+ unsigned int prog;
+ unsigned int vers;
+ unsigned int proc;
+ opaque args<>;
+};
+
+.ft I
+/*
+* Results of callit
+*/
+.ft CW
+struct call_result {
+ unsigned int port;
+ opaque res<>;
+};
+.vs
+.DE
+.KE
+.ie t .DS
+.el .DS L
+.vs 11
+.ft I
+/*
+* Port mapper procedures
+*/
+.ft CW
+program PMAP_PROG {
+ version PMAP_VERS {
+ void
+ PMAPPROC_NULL(void) = 0;
+
+ bool
+ PMAPPROC_SET(mapping) = 1;
+
+ bool
+ PMAPPROC_UNSET(mapping) = 2;
+
+ unsigned int
+ PMAPPROC_GETPORT(mapping) = 3;
+
+ pmaplist
+ PMAPPROC_DUMP(void) = 4;
+
+ call_result
+ PMAPPROC_CALLIT(call_args) = 5;
+ } = 2;
+} = 100000;
+.vs
+.DE
+.NH 2
+\&Port Mapper Operation
+.LP
+The portmapper program currently supports two protocols (UDP/IP and
+TCP/IP). The portmapper is contacted by talking to it on assigned
+port number 111 (SUNRPC [8]) on either of these protocols. The
+following is a description of each of the portmapper procedures:
+.IP \fBPMAPPROC_NULL:\fP
+This procedure does no work. By convention, procedure zero of any
+protocol takes no parameters and returns no results.
+.IP \fBPMAPPROC_SET:\fP
+When a program first becomes available on a machine, it registers
+itself with the port mapper program on the same machine. The program
+passes its program number "prog", version number "vers", transport
+protocol number "prot", and the port "port" on which it awaits
+service request. The procedure returns a boolean response whose
+value is
+.I TRUE
+if the procedure successfully established the mapping and
+.I FALSE
+otherwise. The procedure refuses to establish
+a mapping if one already exists for the tuple "(prog, vers, prot)".
+.IP \fBPMAPPROC_UNSET:\fP
+When a program becomes unavailable, it should unregister itself with
+the port mapper program on the same machine. The parameters and
+results have meanings identical to those of
+.I PMAPPROC_SET .
+The protocol and port number fields of the argument are ignored.
+.IP \fBPMAPPROC_GETPORT:\fP
+Given a program number "prog", version number "vers", and transport
+protocol number "prot", this procedure returns the port number on
+which the program is awaiting call requests. A port value of zeros
+means the program has not been registered. The "port" field of the
+argument is ignored.
+.IP \fBPMAPPROC_DUMP:\fP
+This procedure enumerates all entries in the port mapper's database.
+The procedure takes no parameters and returns a list of program,
+version, protocol, and port values.
+.IP \fBPMAPPROC_CALLIT:\fP
+This procedure allows a caller to call another remote procedure on
+the same machine without knowing the remote procedure's port number.
+It is intended for supporting broadcasts to arbitrary remote programs
+via the well-known port mapper's port. The parameters "prog",
+"vers", "proc", and the bytes of "args" are the program number,
+version number, procedure number, and parameters of the remote
+procedure.
+.LP
+.B Note:
+.RS
+.IP 1.
+This procedure only sends a response if the procedure was
+successfully executed and is silent (no response) otherwise.
+.IP 2.
+The port mapper communicates with the remote program using UDP/IP
+only.
+.RE
+.LP
+The procedure returns the remote program's port number, and the bytes
+of results are the results of the remote procedure.
+.bp
+.NH 1
+\&References
+.LP
+[1] Birrell, Andrew D. & Nelson, Bruce Jay; "Implementing Remote
+Procedure Calls"; XEROX CSL-83-7, October 1983.
+.LP
+[2] Cheriton, D.; "VMTP: Versatile Message Transaction Protocol",
+Preliminary Version 0.3; Stanford University, January 1987.
+.LP
+[3] Diffie & Hellman; "New Directions in Cryptography"; IEEE
+Transactions on Information Theory IT-22, November 1976.
+.LP
+[4] Harrenstien, K.; "Time Server", RFC 738; Information Sciences
+Institute, October 1977.
+.LP
+[5] National Bureau of Standards; "Data Encryption Standard"; Federal
+Information Processing Standards Publication 46, January 1977.
+.LP
+[6] Postel, J.; "Transmission Control Protocol - DARPA Internet
+Program Protocol Specification", RFC 793; Information Sciences
+Institute, September 1981.
+.LP
+[7] Postel, J.; "User Datagram Protocol", RFC 768; Information Sciences
+Institute, August 1980.
+.LP
+[8] Reynolds, J. & Postel, J.; "Assigned Numbers", RFC 923; Information
+Sciences Institute, October 1984.
diff --git a/lib/libc/rpc/PSD.doc/rpcgen.ms b/lib/libc/rpc/PSD.doc/rpcgen.ms
new file mode 100644
index 0000000..b4e50e5
--- /dev/null
+++ b/lib/libc/rpc/PSD.doc/rpcgen.ms
@@ -0,0 +1,1299 @@
+.\"
+.\" Must use -- tbl -- for this one
+.\"
+.\" @(#)rpcgen.ms 2.2 88/08/04 4.0 RPCSRC
+.de BT
+.if \\n%=1 .tl ''- % -''
+..
+.ND
+.\" prevent excess underlining in nroff
+.if n .fp 2 R
+.OH '\fBrpcgen\fP Programming Guide''Page %'
+.EH 'Page %''\fBrpcgen\fP Programming Guide'
+.if \\n%=1 .bp
+.SH
+\&\fBrpcgen\fP Programming Guide
+.NH 0
+\&The \fBrpcgen\fP Protocol Compiler
+.IX rpcgen "" \fIrpcgen\fP "" PAGE MAJOR
+.LP
+.IX RPC "" "" \fIrpcgen\fP
+The details of programming applications to use Remote Procedure Calls
+can be overwhelming. Perhaps most daunting is the writing of the XDR
+routines necessary to convert procedure arguments and results into
+their network format and vice-versa.
+.LP
+Fortunately,
+.I rpcgen(1)
+exists to help programmers write RPC applications simply and directly.
+.I rpcgen
+does most of the dirty work, allowing programmers to debug
+the main features of their application, instead of requiring them to
+spend most of their time debugging their network interface code.
+.LP
+.I rpcgen
+is a compiler. It accepts a remote program interface definition written
+in a language, called RPC Language, which is similar to C. It produces a C
+language output which includes stub versions of the client routines, a
+server skeleton, XDR filter routines for both parameters and results, and a
+header file that contains common definitions. The client stubs interface
+with the RPC library and effectively hide the network from their callers.
+The server stub similarly hides the network from the server procedures that
+are to be invoked by remote clients.
+.I rpcgen 's
+output files can be compiled and linked in the usual way. The developer
+writes server procedures\(emin any language that observes Sun calling
+conventions\(emand links them with the server skeleton produced by
+.I rpcgen
+to get an executable server program. To use a remote program, a programmer
+writes an ordinary main program that makes local procedure calls to the
+client stubs produced by
+.I rpcgen .
+Linking this program with
+.I rpcgen 's
+stubs creates an executable program. (At present the main program must be
+written in C).
+.I rpcgen
+options can be used to suppress stub generation and to specify the transport
+to be used by the server stub.
+.LP
+Like all compilers,
+.I rpcgen
+reduces development time
+that would otherwise be spent coding and debugging low-level routines.
+All compilers, including
+.I rpcgen ,
+do this at a small cost in efficiency
+and flexibility. However, many compilers allow escape hatches for
+programmers to mix low-level code with high-level code.
+.I rpcgen
+is no exception. In speed-critical applications, hand-written routines
+can be linked with the
+.I rpcgen
+output without any difficulty. Also, one may proceed by using
+.I rpcgen
+output as a starting point, and then rewriting it as necessary.
+(If you need a discussion of RPC programming without
+.I rpcgen ,
+see the
+.I "Remote Procedure Call Programming Guide)\.
+.NH 1
+\&Converting Local Procedures into Remote Procedures
+.IX rpcgen "local procedures" \fIrpcgen\fP
+.IX rpcgen "remote procedures" \fIrpcgen\fP
+.LP
+Assume an application that runs on a single machine, one which we want
+to convert to run over the network. Here we will demonstrate such a
+conversion by way of a simple example\(ema program that prints a
+message to the console:
+.ie t .DS
+.el .DS L
+.ft I
+/*
+ * printmsg.c: print a message on the console
+ */
+.ft CW
+#include <stdio.h>
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char *message;
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s <message>\en", argv[0]);
+ exit(1);
+ }
+ message = argv[1];
+
+ if (!printmessage(message)) {
+ fprintf(stderr, "%s: couldn't print your message\en",
+ argv[0]);
+ exit(1);
+ }
+ printf("Message Delivered!\en");
+ exit(0);
+}
+.ft I
+/*
+ * Print a message to the console.
+ * Return a boolean indicating whether the message was actually printed.
+ */
+.ft CW
+printmessage(msg)
+ char *msg;
+{
+ FILE *f;
+
+ f = fopen("/dev/console", "w");
+ if (f == NULL) {
+ return (0);
+ }
+ fprintf(f, "%s\en", msg);
+ fclose(f);
+ return(1);
+}
+.DE
+.LP
+And then, of course:
+.ie t .DS
+.el .DS L
+.ft CW
+example% \fBcc printmsg.c -o printmsg\fP
+example% \fBprintmsg "Hello, there."\fP
+Message delivered!
+example%
+.DE
+.LP
+If
+.I printmessage()
+was turned into a remote procedure,
+then it could be called from anywhere in the network.
+Ideally, one would just like to stick a keyword like
+.I remote
+in front of a
+procedure to turn it into a remote procedure. Unfortunately,
+we have to live within the constraints of the C language, since
+it existed long before RPC did. But even without language
+support, it's not very difficult to make a procedure remote.
+.LP
+In general, it's necessary to figure out what the types are for
+all procedure inputs and outputs. In this case, we have a
+procedure
+.I printmessage()
+which takes a string as input, and returns an integer
+as output. Knowing this, we can write a protocol specification in RPC
+language that describes the remote version of
+.I printmessage ().
+Here it is:
+.ie t .DS
+.el .DS L
+.ft I
+/*
+ * msg.x: Remote message printing protocol
+ */
+.ft CW
+
+program MESSAGEPROG {
+ version MESSAGEVERS {
+ int PRINTMESSAGE(string) = 1;
+ } = 1;
+} = 99;
+.DE
+.LP
+Remote procedures are part of remote programs, so we actually declared
+an entire remote program here which contains the single procedure
+.I PRINTMESSAGE .
+This procedure was declared to be in version 1 of the
+remote program. No null procedure (procedure 0) is necessary because
+.I rpcgen
+generates it automatically.
+.LP
+Notice that everything is declared with all capital letters. This is
+not required, but is a good convention to follow.
+.LP
+Notice also that the argument type is \*Qstring\*U and not \*Qchar *\*U. This
+is because a \*Qchar *\*U in C is ambiguous. Programmers usually intend it
+to mean a null-terminated string of characters, but it could also
+represent a pointer to a single character or a pointer to an array of
+characters. In RPC language, a null-terminated string is
+unambiguously called a \*Qstring\*U.
+.LP
+There are just two more things to write. First, there is the remote
+procedure itself. Here's the definition of a remote procedure
+to implement the
+.I PRINTMESSAGE
+procedure we declared above:
+.ie t .DS
+.el .DS L
+.vs 11
+.ft I
+/*
+ * msg_proc.c: implementation of the remote procedure "printmessage"
+ */
+.ft CW
+
+#include <stdio.h>
+#include <rpc/rpc.h> /* \fIalways needed\fP */
+#include "msg.h" /* \fIneed this too: msg.h will be generated by rpcgen\fP */
+
+.ft I
+/*
+ * Remote verson of "printmessage"
+ */
+.ft CW
+int *
+printmessage_1(msg)
+ char **msg;
+{
+ static int result; /* \fImust be static!\fP */
+ FILE *f;
+
+ f = fopen("/dev/console", "w");
+ if (f == NULL) {
+ result = 0;
+ return (&result);
+ }
+ fprintf(f, "%s\en", *msg);
+ fclose(f);
+ result = 1;
+ return (&result);
+}
+.vs
+.DE
+.LP
+Notice here that the declaration of the remote procedure
+.I printmessage_1()
+differs from that of the local procedure
+.I printmessage()
+in three ways:
+.IP 1.
+It takes a pointer to a string instead of a string itself. This
+is true of all remote procedures: they always take pointers to their
+arguments rather than the arguments themselves.
+.IP 2.
+It returns a pointer to an integer instead of an integer itself. This is
+also generally true of remote procedures: they always return a pointer
+to their results.
+.IP 3.
+It has an \*Q_1\*U appended to its name. In general, all remote
+procedures called by
+.I rpcgen
+are named by the following rule: the name in the program definition
+(here
+.I PRINTMESSAGE )
+is converted to all
+lower-case letters, an underbar (\*Q_\*U) is appended to it, and
+finally the version number (here 1) is appended.
+.LP
+The last thing to do is declare the main client program that will call
+the remote procedure. Here it is:
+.ie t .DS
+.el .DS L
+.ft I
+/*
+ * rprintmsg.c: remote version of "printmsg.c"
+ */
+.ft CW
+#include <stdio.h>
+#include <rpc/rpc.h> /* \fIalways needed\fP */
+#include "msg.h" /* \fIneed this too: msg.h will be generated by rpcgen\fP */
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ CLIENT *cl;
+ int *result;
+ char *server;
+ char *message;
+
+ if (argc < 3) {
+ fprintf(stderr, "usage: %s host message\en", argv[0]);
+ exit(1);
+ }
+
+.ft I
+ /*
+ * Save values of command line arguments
+ */
+.ft CW
+ server = argv[1];
+ message = argv[2];
+
+.ft I
+ /*
+ * Create client "handle" used for calling \fIMESSAGEPROG\fP on the
+ * server designated on the command line. We tell the RPC package
+ * to use the "tcp" protocol when contacting the server.
+ */
+.ft CW
+ cl = clnt_create(server, MESSAGEPROG, MESSAGEVERS, "tcp");
+ if (cl == NULL) {
+.ft I
+ /*
+ * Couldn't establish connection with server.
+ * Print error message and die.
+ */
+.ft CW
+ clnt_pcreateerror(server);
+ exit(1);
+ }
+
+.ft I
+ /*
+ * Call the remote procedure "printmessage" on the server
+ */
+.ft CW
+ result = printmessage_1(&message, cl);
+ if (result == NULL) {
+.ft I
+ /*
+ * An error occurred while calling the server.
+ * Print error message and die.
+ */
+.ft CW
+ clnt_perror(cl, server);
+ exit(1);
+ }
+
+.ft I
+ /*
+ * Okay, we successfully called the remote procedure.
+ */
+.ft CW
+ if (*result == 0) {
+.ft I
+ /*
+ * Server was unable to print our message.
+ * Print error message and die.
+ */
+.ft CW
+ fprintf(stderr, "%s: %s couldn't print your message\en",
+ argv[0], server);
+ exit(1);
+ }
+
+.ft I
+ /*
+ * The message got printed on the server's console
+ */
+.ft CW
+ printf("Message delivered to %s!\en", server);
+}
+.DE
+There are two things to note here:
+.IP 1.
+.IX "client handle, used by rpcgen" "" "client handle, used by \fIrpcgen\fP"
+First a client \*Qhandle\*U is created using the RPC library routine
+.I clnt_create ().
+This client handle will be passed to the stub routines
+which call the remote procedure.
+.IP 2.
+The remote procedure
+.I printmessage_1()
+is called exactly the same way as it is declared in
+.I msg_proc.c
+except for the inserted client handle as the first argument.
+.LP
+Here's how to put all of the pieces together:
+.ie t .DS
+.el .DS L
+.ft CW
+example% \fBrpcgen msg.x\fP
+example% \fBcc rprintmsg.c msg_clnt.c -o rprintmsg\fP
+example% \fBcc msg_proc.c msg_svc.c -o msg_server\fP
+.DE
+Two programs were compiled here: the client program
+.I rprintmsg
+and the server program
+.I msg_server .
+Before doing this though,
+.I rpcgen
+was used to fill in the missing pieces.
+.LP
+Here is what
+.I rpcgen
+did with the input file
+.I msg.x :
+.IP 1.
+It created a header file called
+.I msg.h
+that contained
+.I #define 's
+for
+.I MESSAGEPROG ,
+.I MESSAGEVERS
+and
+.I PRINTMESSAGE
+for use in the other modules.
+.IP 2.
+It created client \*Qstub\*U routines in the
+.I msg_clnt.c
+file. In this case there is only one, the
+.I printmessage_1()
+that was referred to from the
+.I printmsg
+client program. The name of the output file for
+client stub routines is always formed in this way: if the name of the
+input file is
+.I FOO.x ,
+the client stubs output file is called
+.I FOO_clnt.c .
+.IP 3.
+It created the server program which calls
+.I printmessage_1()
+in
+.I msg_proc.c .
+This server program is named
+.I msg_svc.c .
+The rule for naming the server output file is similar to the
+previous one: for an input file called
+.I FOO.x ,
+the output server file is named
+.I FOO_svc.c .
+.LP
+Now we're ready to have some fun. First, copy the server to a
+remote machine and run it. For this example, the
+machine is called \*Qmoon\*U. Server processes are run in the
+background, because they never exit.
+.ie t .DS
+.el .DS L
+.ft CW
+moon% \fBmsg_server &\fP
+.DE
+Then on our local machine (\*Qsun\*U) we can print a message on \*Qmoon\*Us
+console.
+.ie t .DS
+.el .DS L
+.ft CW
+sun% \fBprintmsg moon "Hello, moon."\fP
+.DE
+The message will get printed to \*Qmoon\*Us console. You can print a
+message on anybody's console (including your own) with this program if
+you are able to copy the server to their machine and run it.
+.NH 1
+\&Generating XDR Routines
+.IX RPC "generating XDR routines"
+.LP
+The previous example only demonstrated the automatic generation of
+client and server RPC code.
+.I rpcgen
+may also be used to generate XDR routines, that is, the routines
+necessary to convert local data
+structures into network format and vice-versa. This example presents
+a complete RPC service\(ema remote directory listing service, which uses
+.I rpcgen
+not only to generate stub routines, but also to generate the XDR
+routines. Here is the protocol description file:
+.ie t .DS
+.el .DS L
+.ft I
+/*
+ * dir.x: Remote directory listing protocol
+ */
+.ft CW
+const MAXNAMELEN = 255; /* \fImaximum length of a directory entry\fP */
+
+typedef string nametype<MAXNAMELEN>; /* \fIa directory entry\fP */
+
+typedef struct namenode *namelist; /* \fIa link in the listing\fP */
+
+.ft I
+/*
+ * A node in the directory listing
+ */
+.ft CW
+struct namenode {
+ nametype name; /* \fIname of directory entry\fP */
+ namelist next; /* \fInext entry\fP */
+};
+
+.ft I
+/*
+ * The result of a READDIR operation.
+ */
+.ft CW
+union readdir_res switch (int errno) {
+case 0:
+ namelist list; /* \fIno error: return directory listing\fP */
+default:
+ void; /* \fIerror occurred: nothing else to return\fP */
+};
+
+.ft I
+/*
+ * The directory program definition
+ */
+.ft CW
+program DIRPROG {
+ version DIRVERS {
+ readdir_res
+ READDIR(nametype) = 1;
+ } = 1;
+} = 76;
+.DE
+.SH
+Note:
+.I
+Types (like
+.I readdir_res
+in the example above) can be defined using
+the \*Qstruct\*U, \*Qunion\*U and \*Qenum\*U keywords, but those keywords
+should not be used in subsequent declarations of variables of those types.
+For example, if you define a union \*Qfoo\*U, you should declare using
+only \*Qfoo\*U and not \*Qunion foo\*U. In fact,
+.I rpcgen
+compiles
+RPC unions into C structures and it is an error to declare them using the
+\*Qunion\*U keyword.
+.LP
+Running
+.I rpcgen
+on
+.I dir.x
+creates four output files. Three are the same as before: header file,
+client stub routines and server skeleton. The fourth are the XDR routines
+necessary for converting the data types we declared into XDR format and
+vice-versa. These are output in the file
+.I dir_xdr.c .
+.LP
+Here is the implementation of the
+.I READDIR
+procedure.
+.ie t .DS
+.el .DS L
+.vs 11
+.ft I
+/*
+ * dir_proc.c: remote readdir implementation
+ */
+.ft CW
+#include <rpc/rpc.h>
+#include <sys/dir.h>
+#include "dir.h"
+
+extern int errno;
+extern char *malloc();
+extern char *strdup();
+
+readdir_res *
+readdir_1(dirname)
+ nametype *dirname;
+{
+ DIR *dirp;
+ struct direct *d;
+ namelist nl;
+ namelist *nlp;
+ static readdir_res res; /* \fImust be static\fP! */
+
+.ft I
+ /*
+ * Open directory
+ */
+.ft CW
+ dirp = opendir(*dirname);
+ if (dirp == NULL) {
+ res.errno = errno;
+ return (&res);
+ }
+
+.ft I
+ /*
+ * Free previous result
+ */
+.ft CW
+ xdr_free(xdr_readdir_res, &res);
+
+.ft I
+ /*
+ * Collect directory entries.
+ * Memory allocated here will be freed by \fIxdr_free\fP
+ * next time \fIreaddir_1\fP is called
+ */
+.ft CW
+ nlp = &res.readdir_res_u.list;
+ while (d = readdir(dirp)) {
+ nl = *nlp = (namenode *) malloc(sizeof(namenode));
+ nl->name = strdup(d->d_name);
+ nlp = &nl->next;
+ }
+ *nlp = NULL;
+
+.ft I
+ /*
+ * Return the result
+ */
+.ft CW
+ res.errno = 0;
+ closedir(dirp);
+ return (&res);
+}
+.vs
+.DE
+Finally, there is the client side program to call the server:
+.ie t .DS
+.el .DS L
+.ft I
+/*
+ * rls.c: Remote directory listing client
+ */
+.ft CW
+#include <stdio.h>
+#include <rpc/rpc.h> /* \fIalways need this\fP */
+#include "dir.h" /* \fIwill be generated by rpcgen\fI */
+
+extern int errno;
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ CLIENT *cl;
+ char *server;
+ char *dir;
+ readdir_res *result;
+ namelist nl;
+
+
+ if (argc != 3) {
+ fprintf(stderr, "usage: %s host directory\en",
+ argv[0]);
+ exit(1);
+ }
+
+.ft I
+ /*
+ * Remember what our command line arguments refer to
+ */
+.ft CW
+ server = argv[1];
+ dir = argv[2];
+
+.ft I
+ /*
+ * Create client "handle" used for calling \fIMESSAGEPROG\fP on the
+ * server designated on the command line. We tell the RPC package
+ * to use the "tcp" protocol when contacting the server.
+ */
+.ft CW
+ cl = clnt_create(server, DIRPROG, DIRVERS, "tcp");
+ if (cl == NULL) {
+.ft I
+ /*
+ * Couldn't establish connection with server.
+ * Print error message and die.
+ */
+.ft CW
+ clnt_pcreateerror(server);
+ exit(1);
+ }
+
+.ft I
+ /*
+ * Call the remote procedure \fIreaddir\fP on the server
+ */
+.ft CW
+ result = readdir_1(&dir, cl);
+ if (result == NULL) {
+.ft I
+ /*
+ * An error occurred while calling the server.
+ * Print error message and die.
+ */
+.ft CW
+ clnt_perror(cl, server);
+ exit(1);
+ }
+
+.ft I
+ /*
+ * Okay, we successfully called the remote procedure.
+ */
+.ft CW
+ if (result->errno != 0) {
+.ft I
+ /*
+ * A remote system error occurred.
+ * Print error message and die.
+ */
+.ft CW
+ errno = result->errno;
+ perror(dir);
+ exit(1);
+ }
+
+.ft I
+ /*
+ * Successfully got a directory listing.
+ * Print it out.
+ */
+.ft CW
+ for (nl = result->readdir_res_u.list; nl != NULL;
+ nl = nl->next) {
+ printf("%s\en", nl->name);
+ }
+ exit(0);
+}
+.DE
+Compile everything, and run.
+.DS
+.ft CW
+sun% \fBrpcgen dir.x\fP
+sun% \fBcc rls.c dir_clnt.c dir_xdr.c -o rls\fP
+sun% \fBcc dir_svc.c dir_proc.c dir_xdr.c -o dir_svc\fP
+
+sun% \fBdir_svc &\fP
+
+moon% \fBrls sun /usr/pub\fP
+\&.
+\&..
+ascii
+eqnchar
+greek
+kbd
+marg8
+tabclr
+tabs
+tabs4
+moon%
+.DE
+.LP
+.IX "debugging with rpcgen" "" "debugging with \fIrpcgen\fP"
+A final note about
+.I rpcgen :
+The client program and the server procedure can be tested together
+as a single program by simply linking them with each other rather
+than with the client and server stubs. The procedure calls will be
+executed as ordinary local procedure calls and the program can be
+debugged with a local debugger such as
+.I dbx .
+When the program is working, the client program can be linked to
+the client stub produced by
+.I rpcgen
+and the server procedures can be linked to the server stub produced
+by
+.I rpcgen .
+.SH
+.I NOTE :
+\fIIf you do this, you may want to comment out calls to RPC library
+routines, and have client-side routines call server routines
+directly.\fP
+.LP
+.NH 1
+\&The C-Preprocessor
+.IX rpcgen "C-preprocessor" \fIrpcgen\fP
+.LP
+The C-preprocessor is run on all input files before they are
+compiled, so all the preprocessor directives are legal within a \*Q.x\*U
+file. Four symbols may be defined, depending upon which output file is
+getting generated. The symbols are:
+.TS
+box tab (&);
+lfI lfI
+lfL l .
+Symbol&Usage
+_
+RPC_HDR&for header-file output
+RPC_XDR&for XDR routine output
+RPC_SVC&for server-skeleton output
+RPC_CLNT&for client stub output
+.TE
+.LP
+Also,
+.I rpcgen
+does a little preprocessing of its own. Any line that
+begins with a percent sign is passed directly into the output file,
+without any interpretation of the line. Here is a simple example that
+demonstrates the preprocessing features.
+.ie t .DS
+.el .DS L
+.ft I
+/*
+ * time.x: Remote time protocol
+ */
+.ft CW
+program TIMEPROG {
+ version TIMEVERS {
+ unsigned int TIMEGET(void) = 1;
+ } = 1;
+} = 44;
+
+#ifdef RPC_SVC
+%int *
+%timeget_1()
+%{
+% static int thetime;
+%
+% thetime = time(0);
+% return (&thetime);
+%}
+#endif
+.DE
+The '%' feature is not generally recommended, as there is no guarantee
+that the compiler will stick the output where you intended.
+.NH 1
+\&\fBrpcgen\fP Programming Notes
+.IX rpcgen "other operations" \fIrpcgen\fP
+.sp
+.NH 2
+\&Timeout Changes
+.IX rpcgen "timeout changes" \fIrpcgen\fP
+.LP
+RPC sets a default timeout of 25 seconds for RPC calls when
+.I clnt_create()
+is used. This timeout may be changed using
+.I clnt_control()
+Here is a small code fragment to demonstrate use of
+.I clnt_control ():
+.ID
+struct timeval tv;
+CLIENT *cl;
+.sp .5
+cl = clnt_create("somehost", SOMEPROG, SOMEVERS, "tcp");
+if (cl == NULL) {
+ exit(1);
+}
+tv.tv_sec = 60; /* \fIchange timeout to 1 minute\fP */
+tv.tv_usec = 0;
+clnt_control(cl, CLSET_TIMEOUT, &tv);
+.DE
+.NH 2
+\&Handling Broadcast on the Server Side
+.IX "broadcast RPC"
+.IX rpcgen "broadcast RPC" \fIrpcgen\fP
+.LP
+When a procedure is known to be called via broadcast RPC,
+it is usually wise for the server to not reply unless it can provide
+some useful information to the client. This prevents the network
+from getting flooded by useless replies.
+.LP
+To prevent the server from replying, a remote procedure can
+return NULL as its result, and the server code generated by
+.I rpcgen
+will detect this and not send out a reply.
+.LP
+Here is an example of a procedure that replies only if it
+thinks it is an NFS server:
+.ID
+void *
+reply_if_nfsserver()
+{
+ char notnull; /* \fIjust here so we can use its address\fP */
+.sp .5
+ if (access("/etc/exports", F_OK) < 0) {
+ return (NULL); /* \fIprevent RPC from replying\fP */
+ }
+.ft I
+ /*
+ * return non-null pointer so RPC will send out a reply
+ */
+.ft L
+ return ((void *)&notnull);
+}
+.DE
+Note that if procedure returns type \*Qvoid *\*U, they must return a non-NULL
+pointer if they want RPC to reply for them.
+.NH 2
+\&Other Information Passed to Server Procedures
+.LP
+Server procedures will often want to know more about an RPC call
+than just its arguments. For example, getting authentication information
+is important to procedures that want to implement some level of security.
+This extra information is actually supplied to the server procedure as a
+second argument. Here is an example to demonstrate its use. What we've
+done here is rewrite the previous
+.I printmessage_1()
+procedure to only allow root users to print a message to the console.
+.ID
+int *
+printmessage_1(msg, rq)
+ char **msg;
+ struct svc_req *rq;
+{
+ static in result; /* \fIMust be static\fP */
+ FILE *f;
+ struct suthunix_parms *aup;
+.sp .5
+ aup = (struct authunix_parms *)rq->rq_clntcred;
+ if (aup->aup_uid != 0) {
+ result = 0;
+ return (&result);
+ }
+.sp
+.ft I
+ /*
+ * Same code as before.
+ */
+.ft L
+}
+.DE
+.NH 1
+\&RPC Language
+.IX RPCL
+.IX rpcgen "RPC Language" \fIrpcgen\fP
+.LP
+RPC language is an extension of XDR language. The sole extension is
+the addition of the
+.I program
+type. For a complete description of the XDR language syntax, see the
+.I "External Data Representation Standard: Protocol Specification"
+chapter. For a description of the RPC extensions to the XDR language,
+see the
+.I "Remote Procedure Calls: Protocol Specification"
+chapter.
+.LP
+However, XDR language is so close to C that if you know C, you know most
+of it already. We describe here the syntax of the RPC language,
+showing a few examples along the way. We also show how the various
+RPC and XDR type definitions get compiled into C type definitions in
+the output header file.
+.KS
+.NH 2
+Definitions
+\&
+.IX rpcgen definitions \fIrpcgen\fP
+.LP
+An RPC language file consists of a series of definitions.
+.DS L
+.ft CW
+ definition-list:
+ definition ";"
+ definition ";" definition-list
+.DE
+.KE
+It recognizes five types of definitions.
+.DS L
+.ft CW
+ definition:
+ enum-definition
+ struct-definition
+ union-definition
+ typedef-definition
+ const-definition
+ program-definition
+.DE
+.NH 2
+Structures
+\&
+.IX rpcgen structures \fIrpcgen\fP
+.LP
+An XDR struct is declared almost exactly like its C counterpart. It
+looks like the following:
+.DS L
+.ft CW
+ struct-definition:
+ "struct" struct-ident "{"
+ declaration-list
+ "}"
+
+ declaration-list:
+ declaration ";"
+ declaration ";" declaration-list
+.DE
+As an example, here is an XDR structure to a two-dimensional
+coordinate, and the C structure that it gets compiled into in the
+output header file.
+.DS
+.ft CW
+ struct coord { struct coord {
+ int x; --> int x;
+ int y; int y;
+ }; };
+ typedef struct coord coord;
+.DE
+The output is identical to the input, except for the added
+.I typedef
+at the end of the output. This allows one to use \*Qcoord\*U instead of
+\*Qstruct coord\*U when declaring items.
+.NH 2
+Unions
+\&
+.IX rpcgen unions \fIrpcgen\fP
+.LP
+XDR unions are discriminated unions, and look quite different from C
+unions. They are more analogous to Pascal variant records than they
+are to C unions.
+.DS L
+.ft CW
+ union-definition:
+ "union" union-ident "switch" "(" declaration ")" "{"
+ case-list
+ "}"
+
+ case-list:
+ "case" value ":" declaration ";"
+ "default" ":" declaration ";"
+ "case" value ":" declaration ";" case-list
+.DE
+Here is an example of a type that might be returned as the result of a
+\*Qread data\*U operation. If there is no error, return a block of data.
+Otherwise, don't return anything.
+.DS L
+.ft CW
+ union read_result switch (int errno) {
+ case 0:
+ opaque data[1024];
+ default:
+ void;
+ };
+.DE
+It gets compiled into the following:
+.DS L
+.ft CW
+ struct read_result {
+ int errno;
+ union {
+ char data[1024];
+ } read_result_u;
+ };
+ typedef struct read_result read_result;
+.DE
+Notice that the union component of the output struct has the name as
+the type name, except for the trailing \*Q_u\*U.
+.NH 2
+Enumerations
+\&
+.IX rpcgen enumerations \fIrpcgen\fP
+.LP
+XDR enumerations have the same syntax as C enumerations.
+.DS L
+.ft CW
+ enum-definition:
+ "enum" enum-ident "{"
+ enum-value-list
+ "}"
+
+ enum-value-list:
+ enum-value
+ enum-value "," enum-value-list
+
+ enum-value:
+ enum-value-ident
+ enum-value-ident "=" value
+.DE
+Here is a short example of an XDR enum, and the C enum that it gets
+compiled into.
+.DS L
+.ft CW
+ enum colortype { enum colortype {
+ RED = 0, RED = 0,
+ GREEN = 1, --> GREEN = 1,
+ BLUE = 2 BLUE = 2,
+ }; };
+ typedef enum colortype colortype;
+.DE
+.NH 2
+Typedef
+\&
+.IX rpcgen typedef \fIrpcgen\fP
+.LP
+XDR typedefs have the same syntax as C typedefs.
+.DS L
+.ft CW
+ typedef-definition:
+ "typedef" declaration
+.DE
+Here is an example that defines a
+.I fname_type
+used for declaring
+file name strings that have a maximum length of 255 characters.
+.DS L
+.ft CW
+typedef string fname_type<255>; --> typedef char *fname_type;
+.DE
+.NH 2
+Constants
+\&
+.IX rpcgen constants \fIrpcgen\fP
+.LP
+XDR constants symbolic constants that may be used wherever a
+integer constant is used, for example, in array size specifications.
+.DS L
+.ft CW
+ const-definition:
+ "const" const-ident "=" integer
+.DE
+For example, the following defines a constant
+.I DOZEN
+equal to 12.
+.DS L
+.ft CW
+ const DOZEN = 12; --> #define DOZEN 12
+.DE
+.NH 2
+Programs
+\&
+.IX rpcgen programs \fIrpcgen\fP
+.LP
+RPC programs are declared using the following syntax:
+.DS L
+.ft CW
+ program-definition:
+ "program" program-ident "{"
+ version-list
+ "}" "=" value
+
+ version-list:
+ version ";"
+ version ";" version-list
+
+ version:
+ "version" version-ident "{"
+ procedure-list
+ "}" "=" value
+
+ procedure-list:
+ procedure ";"
+ procedure ";" procedure-list
+
+ procedure:
+ type-ident procedure-ident "(" type-ident ")" "=" value
+.DE
+For example, here is the time protocol, revisited:
+.ie t .DS
+.el .DS L
+.ft I
+/*
+ * time.x: Get or set the time. Time is represented as number of seconds
+ * since 0:00, January 1, 1970.
+ */
+.ft CW
+program TIMEPROG {
+ version TIMEVERS {
+ unsigned int TIMEGET(void) = 1;
+ void TIMESET(unsigned) = 2;
+ } = 1;
+} = 44;
+.DE
+This file compiles into #defines in the output header file:
+.ie t .DS
+.el .DS L
+.ft CW
+#define TIMEPROG 44
+#define TIMEVERS 1
+#define TIMEGET 1
+#define TIMESET 2
+.DE
+.NH 2
+Declarations
+\&
+.IX rpcgen declarations \fIrpcgen\fP
+.LP
+In XDR, there are only four kinds of declarations.
+.DS L
+.ft CW
+ declaration:
+ simple-declaration
+ fixed-array-declaration
+ variable-array-declaration
+ pointer-declaration
+.DE
+\fB1) Simple declarations\fP are just like simple C declarations.
+.DS L
+.ft CW
+ simple-declaration:
+ type-ident variable-ident
+.DE
+Example:
+.DS L
+.ft CW
+ colortype color; --> colortype color;
+.DE
+\fB2) Fixed-length Array Declarations\fP are just like C array declarations:
+.DS L
+.ft CW
+ fixed-array-declaration:
+ type-ident variable-ident "[" value "]"
+.DE
+Example:
+.DS L
+.ft CW
+ colortype palette[8]; --> colortype palette[8];
+.DE
+\fB3) Variable-Length Array Declarations\fP have no explicit syntax
+in C, so XDR invents its own using angle-brackets.
+.DS L
+.ft CW
+variable-array-declaration:
+ type-ident variable-ident "<" value ">"
+ type-ident variable-ident "<" ">"
+.DE
+The maximum size is specified between the angle brackets. The size may
+be omitted, indicating that the array may be of any size.
+.DS L
+.ft CW
+ int heights<12>; /* \fIat most 12 items\fP */
+ int widths<>; /* \fIany number of items\fP */
+.DE
+Since variable-length arrays have no explicit syntax in C, these
+declarations are actually compiled into \*Qstruct\*Us. For example, the
+\*Qheights\*U declaration gets compiled into the following struct:
+.DS L
+.ft CW
+ struct {
+ u_int heights_len; /* \fI# of items in array\fP */
+ int *heights_val; /* \fIpointer to array\fP */
+ } heights;
+.DE
+Note that the number of items in the array is stored in the \*Q_len\*U
+component and the pointer to the array is stored in the \*Q_val\*U
+component. The first part of each of these component's names is the
+same as the name of the declared XDR variable.
+.LP
+\fB4) Pointer Declarations\fP are made in
+XDR exactly as they are in C. You can't
+really send pointers over the network, but you can use XDR pointers
+for sending recursive data types such as lists and trees. The type is
+actually called \*Qoptional-data\*U, not \*Qpointer\*U, in XDR language.
+.DS L
+.ft CW
+ pointer-declaration:
+ type-ident "*" variable-ident
+.DE
+Example:
+.DS L
+.ft CW
+ listitem *next; --> listitem *next;
+.DE
+.NH 2
+\&Special Cases
+.IX rpcgen "special cases" \fIrpcgen\fP
+.LP
+There are a few exceptions to the rules described above.
+.LP
+.B Booleans:
+C has no built-in boolean type. However, the RPC library does a
+boolean type called
+.I bool_t
+that is either
+.I TRUE
+or
+.I FALSE .
+Things declared as type
+.I bool
+in XDR language are compiled into
+.I bool_t
+in the output header file.
+.LP
+Example:
+.DS L
+.ft CW
+ bool married; --> bool_t married;
+.DE
+.B Strings:
+C has no built-in string type, but instead uses the null-terminated
+\*Qchar *\*U convention. In XDR language, strings are declared using the
+\*Qstring\*U keyword, and compiled into \*Qchar *\*Us in the output header
+file. The maximum size contained in the angle brackets specifies the
+maximum number of characters allowed in the strings (not counting the
+.I NULL
+character). The maximum size may be left off, indicating a string
+of arbitrary length.
+.LP
+Examples:
+.DS L
+.ft CW
+ string name<32>; --> char *name;
+ string longname<>; --> char *longname;
+.DE
+.B "Opaque Data:"
+Opaque data is used in RPC and XDR to describe untyped data, that is,
+just sequences of arbitrary bytes. It may be declared either as a
+fixed or variable length array.
+.DS L
+Examples:
+.ft CW
+ opaque diskblock[512]; --> char diskblock[512];
+
+ opaque filedata<1024>; --> struct {
+ u_int filedata_len;
+ char *filedata_val;
+ } filedata;
+.DE
+.B Voids:
+In a void declaration, the variable is not named. The declaration is
+just \*Qvoid\*U and nothing else. Void declarations can only occur in two
+places: union definitions and program definitions (as the argument or
+result of a remote procedure).
diff --git a/lib/libc/rpc/PSD.doc/xdr.nts.ms b/lib/libc/rpc/PSD.doc/xdr.nts.ms
new file mode 100644
index 0000000..6c2d482
--- /dev/null
+++ b/lib/libc/rpc/PSD.doc/xdr.nts.ms
@@ -0,0 +1,1966 @@
+.\"
+.\" Must use -- eqn -- with this one
+.\"
+.\" @(#)xdr.nts.ms 2.2 88/08/05 4.0 RPCSRC
+.EQ
+delim $$
+.EN
+.de BT
+.if \\n%=1 .tl ''- % -''
+..
+.ND
+.\" prevent excess underlining in nroff
+.if n .fp 2 R
+.OH 'External Data Representation: Sun Technical Notes''Page %'
+.EH 'Page %''External Data Representation: Sun Technical Notes'
+.if \\n%=1 .bp
+.SH
+\&External Data Representation: Sun Technical Notes
+.IX XDR "Sun technical notes"
+.LP
+This chapter contains technical notes on Sun's implementation of the
+External Data Representation (XDR) standard, a set of library routines
+that allow a C programmer to describe arbitrary data structures in a
+machinex-independent fashion.
+For a formal specification of the XDR
+standard, see the
+.I "External Data Representation Standard: Protocol Specification".
+XDR is the backbone of Sun's Remote Procedure Call package, in the
+sense that data for remote procedure calls is transmitted using the
+standard. XDR library routines should be used to transmit data
+that is accessed (read or written) by more than one type of machine.\**
+.FS
+.IX XDR "system routines"
+For a compete specification of the system External Data Representation
+routines, see the
+.I xdr(3N)
+manual page.
+.FE
+.LP
+This chapter contains a short tutorial overview of the XDR library
+routines, a guide to accessing currently available XDR streams, and
+information on defining new streams and data types. XDR was designed
+to work across different languages, operating systems, and machine
+architectures. Most users (particularly RPC users) will only need
+the information in the
+.I "Number Filters",
+.I "Floating Point Filters",
+and
+.I "Enumeration Filters"
+sections.
+Programmers wishing to implement RPC and XDR on new machines
+will be interested in the rest of the chapter, as well as the
+.I "External Data Representaiton Standard: Protocol Specification",
+which will be their primary reference.
+.SH
+Note:
+.I
+.I rpcgen
+can be used to write XDR routines even in cases where no RPC calls are
+being made.
+.LP
+On Sun systems,
+C programs that want to use XDR routines
+must include the file
+.I <rpc/rpc.h> ,
+which contains all the necessary interfaces to the XDR system.
+Since the C library
+.I libc.a
+contains all the XDR routines,
+compile as normal.
+.DS
+example% \fBcc\0\fIprogram\fP.c\fI
+.DE
+.ne 3i
+.NH 0
+\&Justification
+.IX XDR justification
+.LP
+Consider the following two programs,
+.I writer :
+.ie t .DS
+.el .DS L
+.ft CW
+#include <stdio.h>
+.sp.5
+main() /* \fIwriter.c\fP */
+{
+ long i;
+.sp.5
+ for (i = 0; i < 8; i++) {
+ if (fwrite((char *)&i, sizeof(i), 1, stdout) != 1) {
+ fprintf(stderr, "failed!\en");
+ exit(1);
+ }
+ }
+ exit(0);
+}
+.DE
+and
+.I reader :
+.ie t .DS
+.el .DS L
+.ft CW
+#include <stdio.h>
+.sp.5
+main() /* \fIreader.c\fP */
+{
+ long i, j;
+.sp.5
+ for (j = 0; j < 8; j++) {
+ if (fread((char *)&i, sizeof (i), 1, stdin) != 1) {
+ fprintf(stderr, "failed!\en");
+ exit(1);
+ }
+ printf("%ld ", i);
+ }
+ printf("\en");
+ exit(0);
+}
+.DE
+The two programs appear to be portable, because (a) they pass
+.I lint
+checking, and (b) they exhibit the same behavior when executed
+on two different hardware architectures, a Sun and a VAX.
+.LP
+Piping the output of the
+.I writer
+program to the
+.I reader
+program gives identical results on a Sun or a VAX.
+.DS
+.ft CW
+sun% \fBwriter | reader\fP
+0 1 2 3 4 5 6 7
+sun%
+
+
+vax% \fBwriter | reader\fP
+0 1 2 3 4 5 6 7
+vax%
+.DE
+With the advent of local area networks and 4.2BSD came the concept
+of \*Qnetwork pipes\*U \(em a process produces data on one machine,
+and a second process consumes data on another machine.
+A network pipe can be constructed with
+.I writer
+and
+.I reader .
+Here are the results if the first produces data on a Sun,
+and the second consumes data on a VAX.
+.DS
+.ft CW
+sun% \fBwriter | rsh vax reader\fP
+0 16777216 33554432 50331648 67108864 83886080 100663296
+117440512
+sun%
+.DE
+Identical results can be obtained by executing
+.I writer
+on the VAX and
+.I reader
+on the Sun. These results occur because the byte ordering
+of long integers differs between the VAX and the Sun,
+even though word size is the same.
+Note that $16777216$ is $2 sup 24$ \(em
+when four bytes are reversed, the 1 winds up in the 24th bit.
+.LP
+Whenever data is shared by two or more machine types, there is
+a need for portable data. Programs can be made data-portable by
+replacing the
+.I read()
+and
+.I write()
+calls with calls to an XDR library routine
+.I xdr_long() ,
+a filter that knows the standard representation
+of a long integer in its external form.
+Here are the revised versions of
+.I writer :
+.ie t .DS
+.el .DS L
+.ft CW
+#include <stdio.h>
+#include <rpc/rpc.h> /* \fIxdr is a sub-library of rpc\fP */
+.sp.5
+main() /* \fIwriter.c\fP */
+{
+ XDR xdrs;
+ long i;
+.sp.5
+ xdrstdio_create(&xdrs, stdout, XDR_ENCODE);
+ for (i = 0; i < 8; i++) {
+ if (!xdr_long(&xdrs, &i)) {
+ fprintf(stderr, "failed!\en");
+ exit(1);
+ }
+ }
+ exit(0);
+}
+.DE
+and
+.I reader :
+.ie t .DS
+.el .DS L
+.ft CW
+#include <stdio.h>
+#include <rpc/rpc.h> /* \fIxdr is a sub-library of rpc\fP */
+.sp.5
+main() /* \fIreader.c\fP */
+{
+ XDR xdrs;
+ long i, j;
+.sp.5
+ xdrstdio_create(&xdrs, stdin, XDR_DECODE);
+ for (j = 0; j < 8; j++) {
+ if (!xdr_long(&xdrs, &i)) {
+ fprintf(stderr, "failed!\en");
+ exit(1);
+ }
+ printf("%ld ", i);
+ }
+ printf("\en");
+ exit(0);
+}
+.DE
+The new programs were executed on a Sun,
+on a VAX, and from a Sun to a VAX;
+the results are shown below.
+.DS
+.ft CW
+sun% \fBwriter | reader\fP
+0 1 2 3 4 5 6 7
+sun%
+
+vax% \fBwriter | reader\fP
+0 1 2 3 4 5 6 7
+vax%
+
+sun% \fBwriter | rsh vax reader\fP
+0 1 2 3 4 5 6 7
+sun%
+.DE
+.SH
+Note:
+.I
+.IX XDR "portable data"
+Integers are just the tip of the portable-data iceberg. Arbitrary
+data structures present portability problems, particularly with
+respect to alignment and pointers. Alignment on word boundaries
+may cause the size of a structure to vary from machine to machine.
+And pointers, which are very convenient to use, have no meaning
+outside the machine where they are defined.
+.LP
+.NH 1
+\&A Canonical Standard
+.IX XDR "canonical standard"
+.LP
+XDR's approach to standardizing data representations is
+.I canonical .
+That is, XDR defines a single byte order (Big Endian), a single
+floating-point representation (IEEE), and so on. Any program running on
+any machine can use XDR to create portable data by translating its
+local representation to the XDR standard representations; similarly, any
+program running on any machine can read portable data by translating the
+XDR standard representaions to its local equivalents. The single standard
+completely decouples programs that create or send portable data from those
+that use or receive portable data. The advent of a new machine or a new
+language has no effect upon the community of existing portable data creators
+and users. A new machine joins this community by being \*Qtaught\*U how to
+convert the standard representations and its local representations; the
+local representations of other machines are irrelevant. Conversely, to
+existing programs running on other machines, the local representations of
+the new machine are also irrelevant; such programs can immediately read
+portable data produced by the new machine because such data conforms to the
+canonical standards that they already understand.
+.LP
+There are strong precedents for XDR's canonical approach. For example,
+TCP/IP, UDP/IP, XNS, Ethernet, and, indeed, all protocols below layer five
+of the ISO model, are canonical protocols. The advantage of any canonical
+approach is simplicity; in the case of XDR, a single set of conversion
+routines is written once and is never touched again. The canonical approach
+has a disadvantage, but it is unimportant in real-world data transfer
+applications. Suppose two Little-Endian machines are transferring integers
+according to the XDR standard. The sending machine converts the integers
+from Little-Endian byte order to XDR (Big-Endian) byte order; the receiving
+machine performs the reverse conversion. Because both machines observe the
+same byte order, their conversions are unnecessary. The point, however, is
+not necessity, but cost as compared to the alternative.
+.LP
+The time spent converting to and from a canonical representation is
+insignificant, especially in networking applications. Most of the time
+required to prepare a data structure for transfer is not spent in conversion
+but in traversing the elements of the data structure. To transmit a tree,
+for example, each leaf must be visited and each element in a leaf record must
+be copied to a buffer and aligned there; storage for the leaf may have to be
+deallocated as well. Similarly, to receive a tree, storage must be
+allocated for each leaf, data must be moved from the buffer to the leaf and
+properly aligned, and pointers must be constructed to link the leaves
+together. Every machine pays the cost of traversing and copying data
+structures whether or not conversion is required. In networking
+applications, communications overhead\(emthe time required to move the data
+down through the sender's protocol layers, across the network and up through
+the receiver's protocol layers\(emdwarfs conversion overhead.
+.NH 1
+\&The XDR Library
+.IX "XDR" "library"
+.LP
+The XDR library not only solves data portability problems, it also
+allows you to write and read arbitrary C constructs in a consistent,
+specified, well-documented manner. Thus, it can make sense to use the
+library even when the data is not shared among machines on a network.
+.LP
+The XDR library has filter routines for
+strings (null-terminated arrays of bytes),
+structures, unions, and arrays, to name a few.
+Using more primitive routines,
+you can write your own specific XDR routines
+to describe arbitrary data structures,
+including elements of arrays, arms of unions,
+or objects pointed at from other structures.
+The structures themselves may contain arrays of arbitrary elements,
+or pointers to other structures.
+.LP
+Let's examine the two programs more closely.
+There is a family of XDR stream creation routines
+in which each member treats the stream of bits differently.
+In our example, data is manipulated using standard I/O routines,
+so we use
+.I xdrstdio_create ().
+.IX xdrstdio_create() "" "\fIxdrstdio_create()\fP"
+The parameters to XDR stream creation routines
+vary according to their function.
+In our example,
+.I xdrstdio_create()
+takes a pointer to an XDR structure that it initializes,
+a pointer to a
+.I FILE
+that the input or output is performed on, and the operation.
+The operation may be
+.I XDR_ENCODE
+for serializing in the
+.I writer
+program, or
+.I XDR_DECODE
+for deserializing in the
+.I reader
+program.
+.LP
+Note: RPC users never need to create XDR streams;
+the RPC system itself creates these streams,
+which are then passed to the users.
+.LP
+The
+.I xdr_long()
+.IX xdr_long() "" "\fIxdr_long()\fP"
+primitive is characteristic of most XDR library
+primitives and all client XDR routines.
+First, the routine returns
+.I FALSE
+(0) if it fails, and
+.I TRUE
+(1) if it succeeds.
+Second, for each data type,
+.I xxx ,
+there is an associated XDR routine of the form:
+.DS
+.ft CW
+xdr_xxx(xdrs, xp)
+ XDR *xdrs;
+ xxx *xp;
+{
+}
+.DE
+In our case,
+.I xxx
+is long, and the corresponding XDR routine is
+a primitive,
+.I xdr_long() .
+The client could also define an arbitrary structure
+.I xxx
+in which case the client would also supply the routine
+.I xdr_xxx (),
+describing each field by calling XDR routines
+of the appropriate type.
+In all cases the first parameter,
+.I xdrs
+can be treated as an opaque handle,
+and passed to the primitive routines.
+.LP
+XDR routines are direction independent;
+that is, the same routines are called to serialize or deserialize data.
+This feature is critical to software engineering of portable data.
+The idea is to call the same routine for either operation \(em
+this almost guarantees that serialized data can also be deserialized.
+One routine is used by both producer and consumer of networked data.
+This is implemented by always passing the address
+of an object rather than the object itself \(em
+only in the case of deserialization is the object modified.
+This feature is not shown in our trivial example,
+but its value becomes obvious when nontrivial data structures
+are passed among machines.
+If needed, the user can obtain the
+direction of the XDR operation.
+See the
+.I "XDR Operation Directions"
+section below for details.
+.LP
+Let's look at a slightly more complicated example.
+Assume that a person's gross assets and liabilities
+are to be exchanged among processes.
+Also assume that these values are important enough
+to warrant their own data type:
+.ie t .DS
+.el .DS L
+.ft CW
+struct gnumbers {
+ long g_assets;
+ long g_liabilities;
+};
+.DE
+The corresponding XDR routine describing this structure would be:
+.ie t .DS
+.el .DS L
+.ft CW
+bool_t /* \fITRUE is success, FALSE is failure\fP */
+xdr_gnumbers(xdrs, gp)
+ XDR *xdrs;
+ struct gnumbers *gp;
+{
+ if (xdr_long(xdrs, &gp->g_assets) &&
+ xdr_long(xdrs, &gp->g_liabilities))
+ return(TRUE);
+ return(FALSE);
+}
+.DE
+Note that the parameter
+.I xdrs
+is never inspected or modified;
+it is only passed on to the subcomponent routines.
+It is imperative to inspect the return value of each XDR routine call,
+and to give up immediately and return
+.I FALSE
+if the subroutine fails.
+.LP
+This example also shows that the type
+.I bool_t
+is declared as an integer whose only values are
+.I TRUE
+(1) and
+.I FALSE
+(0). This document uses the following definitions:
+.ie t .DS
+.el .DS L
+.ft CW
+#define bool_t int
+#define TRUE 1
+#define FALSE 0
+.DE
+.LP
+Keeping these conventions in mind,
+.I xdr_gnumbers()
+can be rewritten as follows:
+.ie t .DS
+.el .DS L
+.ft CW
+xdr_gnumbers(xdrs, gp)
+ XDR *xdrs;
+ struct gnumbers *gp;
+{
+ return(xdr_long(xdrs, &gp->g_assets) &&
+ xdr_long(xdrs, &gp->g_liabilities));
+}
+.DE
+This document uses both coding styles.
+.NH 1
+\&XDR Library Primitives
+.IX "library primitives for XDR"
+.IX XDR "library primitives"
+.LP
+This section gives a synopsis of each XDR primitive.
+It starts with basic data types and moves on to constructed data types.
+Finally, XDR utilities are discussed.
+The interface to these primitives
+and utilities is defined in the include file
+.I <rpc/xdr.h> ,
+automatically included by
+.I <rpc/rpc.h> .
+.NH 2
+\&Number Filters
+.IX "XDR library" "number filters"
+.LP
+The XDR library provides primitives to translate between numbers
+and their corresponding external representations.
+Primitives cover the set of numbers in:
+.DS
+.ft CW
+[signed, unsigned] * [short, int, long]
+.DE
+.ne 2i
+Specifically, the eight primitives are:
+.DS
+.ft CW
+bool_t xdr_char(xdrs, cp)
+ XDR *xdrs;
+ char *cp;
+.sp.5
+bool_t xdr_u_char(xdrs, ucp)
+ XDR *xdrs;
+ unsigned char *ucp;
+.sp.5
+bool_t xdr_int(xdrs, ip)
+ XDR *xdrs;
+ int *ip;
+.sp.5
+bool_t xdr_u_int(xdrs, up)
+ XDR *xdrs;
+ unsigned *up;
+.sp.5
+bool_t xdr_long(xdrs, lip)
+ XDR *xdrs;
+ long *lip;
+.sp.5
+bool_t xdr_u_long(xdrs, lup)
+ XDR *xdrs;
+ u_long *lup;
+.sp.5
+bool_t xdr_short(xdrs, sip)
+ XDR *xdrs;
+ short *sip;
+.sp.5
+bool_t xdr_u_short(xdrs, sup)
+ XDR *xdrs;
+ u_short *sup;
+.DE
+The first parameter,
+.I xdrs ,
+is an XDR stream handle.
+The second parameter is the address of the number
+that provides data to the stream or receives data from it.
+All routines return
+.I TRUE
+if they complete successfully, and
+.I FALSE
+otherwise.
+.NH 2
+\&Floating Point Filters
+.IX "XDR library" "floating point filters"
+.LP
+The XDR library also provides primitive routines
+for C's floating point types:
+.DS
+.ft CW
+bool_t xdr_float(xdrs, fp)
+ XDR *xdrs;
+ float *fp;
+.sp.5
+bool_t xdr_double(xdrs, dp)
+ XDR *xdrs;
+ double *dp;
+.DE
+The first parameter,
+.I xdrs
+is an XDR stream handle.
+The second parameter is the address
+of the floating point number that provides data to the stream
+or receives data from it.
+Both routines return
+.I TRUE
+if they complete successfully, and
+.I FALSE
+otherwise.
+.LP
+Note: Since the numbers are represented in IEEE floating point,
+routines may fail when decoding a valid IEEE representation
+into a machine-specific representation, or vice-versa.
+.NH 2
+\&Enumeration Filters
+.IX "XDR library" "enumeration filters"
+.LP
+The XDR library provides a primitive for generic enumerations.
+The primitive assumes that a C
+.I enum
+has the same representation inside the machine as a C integer.
+The boolean type is an important instance of the
+.I enum .
+The external representation of a boolean is always
+.I TRUE
+(1) or
+.I FALSE
+(0).
+.DS
+.ft CW
+#define bool_t int
+#define FALSE 0
+#define TRUE 1
+.sp.5
+#define enum_t int
+.sp.5
+bool_t xdr_enum(xdrs, ep)
+ XDR *xdrs;
+ enum_t *ep;
+.sp.5
+bool_t xdr_bool(xdrs, bp)
+ XDR *xdrs;
+ bool_t *bp;
+.DE
+The second parameters
+.I ep
+and
+.I bp
+are addresses of the associated type that provides data to, or
+receives data from, the stream
+.I xdrs .
+.NH 2
+\&No Data
+.IX "XDR library" "no data"
+.LP
+Occasionally, an XDR routine must be supplied to the RPC system,
+even when no data is passed or required.
+The library provides such a routine:
+.DS
+.ft CW
+bool_t xdr_void(); /* \fIalways returns TRUE\fP */
+.DE
+.NH 2
+\&Constructed Data Type Filters
+.IX "XDR library" "constructed data type filters"
+.LP
+Constructed or compound data type primitives
+require more parameters and perform more complicated functions
+then the primitives discussed above.
+This section includes primitives for
+strings, arrays, unions, and pointers to structures.
+.LP
+Constructed data type primitives may use memory management.
+In many cases, memory is allocated when deserializing data with
+.I XDR_DECODE
+Therefore, the XDR package must provide means to deallocate memory.
+This is done by an XDR operation,
+.I XDR_FREE
+To review, the three XDR directional operations are
+.I XDR_ENCODE ,
+.I XDR_DECODE
+and
+.I XDR_FREE .
+.NH 3
+\&Strings
+.IX "XDR library" "strings"
+.LP
+In C, a string is defined as a sequence of bytes
+terminated by a null byte,
+which is not considered when calculating string length.
+However, when a string is passed or manipulated,
+a pointer to it is employed.
+Therefore, the XDR library defines a string to be a
+.I "char *"
+and not a sequence of characters.
+The external representation of a string is drastically different
+from its internal representation.
+Externally, strings are represented as
+sequences of ASCII characters,
+while internally, they are represented with character pointers.
+Conversion between the two representations
+is accomplished with the routine
+.I xdr_string ():
+.IX xdr_string() "" \fIxdr_string()\fP
+.DS
+.ft CW
+bool_t xdr_string(xdrs, sp, maxlength)
+ XDR *xdrs;
+ char **sp;
+ u_int maxlength;
+.DE
+The first parameter
+.I xdrs
+is the XDR stream handle.
+The second parameter
+.I sp
+is a pointer to a string (type
+.I "char **" .
+The third parameter
+.I maxlength
+specifies the maximum number of bytes allowed during encoding or decoding.
+its value is usually specified by a protocol. For example, a protocol
+specification may say that a file name may be no longer than 255 characters.
+.LP
+The routine returns
+.I FALSE
+if the number of characters exceeds
+.I maxlength ,
+and
+.I TRUE
+if it doesn't.
+.SH
+Keep
+.I maxlength
+small. If it is too big you can blow the heap, since
+.I xdr_string()
+will call
+.I malloc()
+for space.
+.LP
+The behavior of
+.I xdr_string()
+.IX xdr_string() "" \fIxdr_string()\fP
+is similar to the behavior of other routines
+discussed in this section. The direction
+.I XDR_ENCODE
+is easiest to understand. The parameter
+.I sp
+points to a string of a certain length;
+if the string does not exceed
+.I maxlength ,
+the bytes are serialized.
+.LP
+The effect of deserializing a string is subtle.
+First the length of the incoming string is determined;
+it must not exceed
+.I maxlength .
+Next
+.I sp
+is dereferenced; if the the value is
+.I NULL ,
+then a string of the appropriate length is allocated and
+.I *sp
+is set to this string.
+If the original value of
+.I *sp
+is non-null, then the XDR package assumes
+that a target area has been allocated,
+which can hold strings no longer than
+.I maxlength .
+In either case, the string is decoded into the target area.
+The routine then appends a null character to the string.
+.LP
+In the
+.I XDR_FREE
+operation, the string is obtained by dereferencing
+.I sp .
+If the string is not
+.I NULL ,
+it is freed and
+.I *sp
+is set to
+.I NULL .
+In this operation,
+.I xdr_string()
+ignores the
+.I maxlength
+parameter.
+.NH 3
+\&Byte Arrays
+.IX "XDR library" "byte arrays"
+.LP
+Often variable-length arrays of bytes are preferable to strings.
+Byte arrays differ from strings in the following three ways:
+1) the length of the array (the byte count) is explicitly
+located in an unsigned integer,
+2) the byte sequence is not terminated by a null character, and
+3) the external representation of the bytes is the same as their
+internal representation.
+The primitive
+.I xdr_bytes()
+.IX xdr_bytes() "" \fIxdr_bytes()\fP
+converts between the internal and external
+representations of byte arrays:
+.DS
+.ft CW
+bool_t xdr_bytes(xdrs, bpp, lp, maxlength)
+ XDR *xdrs;
+ char **bpp;
+ u_int *lp;
+ u_int maxlength;
+.DE
+The usage of the first, second and fourth parameters
+are identical to the first, second and third parameters of
+.I xdr_string (),
+respectively.
+The length of the byte area is obtained by dereferencing
+.I lp
+when serializing;
+.I *lp
+is set to the byte length when deserializing.
+.NH 3
+\&Arrays
+.IX "XDR library" "arrays"
+.LP
+The XDR library package provides a primitive
+for handling arrays of arbitrary elements.
+The
+.I xdr_bytes()
+routine treats a subset of generic arrays,
+in which the size of array elements is known to be 1,
+and the external description of each element is built-in.
+The generic array primitive,
+.I xdr_array() ,
+.IX xdr_array() "" \fIxdr_array()\fP
+requires parameters identical to those of
+.I xdr_bytes()
+plus two more:
+the size of array elements,
+and an XDR routine to handle each of the elements.
+This routine is called to encode or decode
+each element of the array.
+.DS
+.ft CW
+bool_t
+xdr_array(xdrs, ap, lp, maxlength, elementsiz, xdr_element)
+ XDR *xdrs;
+ char **ap;
+ u_int *lp;
+ u_int maxlength;
+ u_int elementsiz;
+ bool_t (*xdr_element)();
+.DE
+The parameter
+.I ap
+is the address of the pointer to the array.
+If
+.I *ap
+is
+.I NULL
+when the array is being deserialized,
+XDR allocates an array of the appropriate size and sets
+.I *ap
+to that array.
+The element count of the array is obtained from
+.I *lp
+when the array is serialized;
+.I *lp
+is set to the array length when the array is deserialized.
+The parameter
+.I maxlength
+is the maximum number of elements that the array is allowed to have;
+.I elementsiz
+is the byte size of each element of the array
+(the C function
+.I sizeof()
+can be used to obtain this value).
+The
+.I xdr_element()
+.IX xdr_element() "" \fIxdr_element()\fP
+routine is called to serialize, deserialize, or free
+each element of the array.
+.br
+.LP
+Before defining more constructed data types, it is appropriate to
+present three examples.
+.LP
+.I "Example A:"
+.br
+A user on a networked machine can be identified by
+(a) the machine name, such as
+.I krypton :
+see the
+.I gethostname
+man page; (b) the user's UID: see the
+.I geteuid
+man page; and (c) the group numbers to which the user belongs:
+see the
+.I getgroups
+man page. A structure with this information and its associated
+XDR routine could be coded like this:
+.ie t .DS
+.el .DS L
+.ft CW
+struct netuser {
+ char *nu_machinename;
+ int nu_uid;
+ u_int nu_glen;
+ int *nu_gids;
+};
+#define NLEN 255 /* \fImachine names < 256 chars\fP */
+#define NGRPS 20 /* \fIuser can't be in > 20 groups\fP */
+.sp.5
+bool_t
+xdr_netuser(xdrs, nup)
+ XDR *xdrs;
+ struct netuser *nup;
+{
+ return(xdr_string(xdrs, &nup->nu_machinename, NLEN) &&
+ xdr_int(xdrs, &nup->nu_uid) &&
+ xdr_array(xdrs, &nup->nu_gids, &nup->nu_glen,
+ NGRPS, sizeof (int), xdr_int));
+}
+.DE
+.LP
+.I "Example B:"
+.br
+A party of network users could be implemented
+as an array of
+.I netuser
+structure.
+The declaration and its associated XDR routines
+are as follows:
+.ie t .DS
+.el .DS L
+.ft CW
+struct party {
+ u_int p_len;
+ struct netuser *p_nusers;
+};
+#define PLEN 500 /* \fImax number of users in a party\fP */
+.sp.5
+bool_t
+xdr_party(xdrs, pp)
+ XDR *xdrs;
+ struct party *pp;
+{
+ return(xdr_array(xdrs, &pp->p_nusers, &pp->p_len, PLEN,
+ sizeof (struct netuser), xdr_netuser));
+}
+.DE
+.LP
+.I "Example C:"
+.br
+The well-known parameters to
+.I main ,
+.I argc
+and
+.I argv
+can be combined into a structure.
+An array of these structures can make up a history of commands.
+The declarations and XDR routines might look like:
+.ie t .DS
+.el .DS L
+.ft CW
+struct cmd {
+ u_int c_argc;
+ char **c_argv;
+};
+#define ALEN 1000 /* \fIargs cannot be > 1000 chars\fP */
+#define NARGC 100 /* \fIcommands cannot have > 100 args\fP */
+
+struct history {
+ u_int h_len;
+ struct cmd *h_cmds;
+};
+#define NCMDS 75 /* \fIhistory is no more than 75 commands\fP */
+
+bool_t
+xdr_wrap_string(xdrs, sp)
+ XDR *xdrs;
+ char **sp;
+{
+ return(xdr_string(xdrs, sp, ALEN));
+}
+.DE
+.ie t .DS
+.el .DS L
+.ft CW
+bool_t
+xdr_cmd(xdrs, cp)
+ XDR *xdrs;
+ struct cmd *cp;
+{
+ return(xdr_array(xdrs, &cp->c_argv, &cp->c_argc, NARGC,
+ sizeof (char *), xdr_wrap_string));
+}
+.DE
+.ie t .DS
+.el .DS L
+.ft CW
+bool_t
+xdr_history(xdrs, hp)
+ XDR *xdrs;
+ struct history *hp;
+{
+ return(xdr_array(xdrs, &hp->h_cmds, &hp->h_len, NCMDS,
+ sizeof (struct cmd), xdr_cmd));
+}
+.DE
+The most confusing part of this example is that the routine
+.I xdr_wrap_string()
+is needed to package the
+.I xdr_string()
+routine, because the implementation of
+.I xdr_array()
+only passes two parameters to the array element description routine;
+.I xdr_wrap_string()
+supplies the third parameter to
+.I xdr_string ().
+.LP
+By now the recursive nature of the XDR library should be obvious.
+Let's continue with more constructed data types.
+.NH 3
+\&Opaque Data
+.IX "XDR library" "opaque data"
+.LP
+In some protocols, handles are passed from a server to client.
+The client passes the handle back to the server at some later time.
+Handles are never inspected by clients;
+they are obtained and submitted.
+That is to say, handles are opaque.
+The
+.I xdr_opaque()
+.IX xdr_opaque() "" \fIxdr_opaque()\fP
+primitive is used for describing fixed sized, opaque bytes.
+.DS
+.ft CW
+bool_t xdr_opaque(xdrs, p, len)
+ XDR *xdrs;
+ char *p;
+ u_int len;
+.DE
+The parameter
+.I p
+is the location of the bytes;
+.I len
+is the number of bytes in the opaque object.
+By definition, the actual data
+contained in the opaque object are not machine portable.
+.NH 3
+\&Fixed Sized Arrays
+.IX "XDR library" "fixed sized arrays"
+.LP
+The XDR library provides a primitive,
+.I xdr_vector (),
+for fixed-length arrays.
+.ie t .DS
+.el .DS L
+.ft CW
+#define NLEN 255 /* \fImachine names must be < 256 chars\fP */
+#define NGRPS 20 /* \fIuser belongs to exactly 20 groups\fP */
+.sp.5
+struct netuser {
+ char *nu_machinename;
+ int nu_uid;
+ int nu_gids[NGRPS];
+};
+.sp.5
+bool_t
+xdr_netuser(xdrs, nup)
+ XDR *xdrs;
+ struct netuser *nup;
+{
+ int i;
+.sp.5
+ if (!xdr_string(xdrs, &nup->nu_machinename, NLEN))
+ return(FALSE);
+ if (!xdr_int(xdrs, &nup->nu_uid))
+ return(FALSE);
+ if (!xdr_vector(xdrs, nup->nu_gids, NGRPS, sizeof(int),
+ xdr_int)) {
+ return(FALSE);
+ }
+ return(TRUE);
+}
+.DE
+.NH 3
+\&Discriminated Unions
+.IX "XDR library" "discriminated unions"
+.LP
+The XDR library supports discriminated unions.
+A discriminated union is a C union and an
+.I enum_t
+value that selects an \*Qarm\*U of the union.
+.DS
+.ft CW
+struct xdr_discrim {
+ enum_t value;
+ bool_t (*proc)();
+};
+.sp.5
+bool_t xdr_union(xdrs, dscmp, unp, arms, defaultarm)
+ XDR *xdrs;
+ enum_t *dscmp;
+ char *unp;
+ struct xdr_discrim *arms;
+ bool_t (*defaultarm)(); /* \fImay equal NULL\fP */
+.DE
+First the routine translates the discriminant of the union located at
+.I *dscmp .
+The discriminant is always an
+.I enum_t .
+Next the union located at
+.I *unp
+is translated.
+The parameter
+.I arms
+is a pointer to an array of
+.I xdr_discrim
+structures.
+Each structure contains an ordered pair of
+.I [value,proc] .
+If the union's discriminant is equal to the associated
+.I value ,
+then the
+.I proc
+is called to translate the union.
+The end of the
+.I xdr_discrim
+structure array is denoted by a routine of value
+.I NULL
+(0). If the discriminant is not found in the
+.I arms
+array, then the
+.I defaultarm
+procedure is called if it is non-null;
+otherwise the routine returns
+.I FALSE .
+.LP
+.I "Example D:"
+Suppose the type of a union may be integer,
+character pointer (a string), or a
+.I gnumbers
+structure.
+Also, assume the union and its current type
+are declared in a structure.
+The declaration is:
+.ie t .DS
+.el .DS L
+.ft CW
+enum utype { INTEGER=1, STRING=2, GNUMBERS=3 };
+.sp.5
+struct u_tag {
+ enum utype utype; /* \fIthe union's discriminant\fP */
+ union {
+ int ival;
+ char *pval;
+ struct gnumbers gn;
+ } uval;
+};
+.DE
+The following constructs and XDR procedure (de)serialize
+the discriminated union:
+.ie t .DS
+.el .DS L
+.ft CW
+struct xdr_discrim u_tag_arms[4] = {
+ { INTEGER, xdr_int },
+ { GNUMBERS, xdr_gnumbers }
+ { STRING, xdr_wrap_string },
+ { __dontcare__, NULL }
+ /* \fIalways terminate arms with a NULL xdr_proc\fP */
+}
+.sp.5
+bool_t
+xdr_u_tag(xdrs, utp)
+ XDR *xdrs;
+ struct u_tag *utp;
+{
+ return(xdr_union(xdrs, &utp->utype, &utp->uval,
+ u_tag_arms, NULL));
+}
+.DE
+The routine
+.I xdr_gnumbers()
+was presented above in
+.I "The XDR Library"
+section.
+.I xdr_wrap_string()
+was presented in example C.
+The default
+.I arm
+parameter to
+.I xdr_union()
+(the last parameter) is
+.I NULL
+in this example. Therefore the value of the union's discriminant
+may legally take on only values listed in the
+.I u_tag_arms
+array. This example also demonstrates that
+the elements of the arm's array do not need to be sorted.
+.LP
+It is worth pointing out that the values of the discriminant
+may be sparse, though in this example they are not.
+It is always good
+practice to assign explicitly integer values to each element of the
+discriminant's type.
+This practice both documents the external
+representation of the discriminant and guarantees that different
+C compilers emit identical discriminant values.
+.LP
+Exercise: Implement
+.I xdr_union()
+using the other primitives in this section.
+.NH 3
+\&Pointers
+.IX "XDR library" "pointers"
+.LP
+In C it is often convenient to put pointers
+to another structure within a structure.
+The
+.I xdr_reference()
+.IX xdr_reference() "" \fIxdr_reference()\fP
+primitive makes it easy to serialize, deserialize, and free
+these referenced structures.
+.DS
+.ft CW
+bool_t xdr_reference(xdrs, pp, size, proc)
+ XDR *xdrs;
+ char **pp;
+ u_int ssize;
+ bool_t (*proc)();
+.DE
+.LP
+Parameter
+.I pp
+is the address of
+the pointer to the structure;
+parameter
+.I ssize
+is the size in bytes of the structure (use the C function
+.I sizeof()
+to obtain this value); and
+.I proc
+is the XDR routine that describes the structure.
+When decoding data, storage is allocated if
+.I *pp
+is
+.I NULL .
+.LP
+There is no need for a primitive
+.I xdr_struct()
+to describe structures within structures,
+because pointers are always sufficient.
+.LP
+Exercise: Implement
+.I xdr_reference()
+using
+.I xdr_array ().
+Warning:
+.I xdr_reference()
+and
+.I xdr_array()
+are NOT interchangeable external representations of data.
+.LP
+.I "Example E:"
+Suppose there is a structure containing a person's name
+and a pointer to a
+.I gnumbers
+structure containing the person's gross assets and liabilities.
+The construct is:
+.DS
+.ft CW
+struct pgn {
+ char *name;
+ struct gnumbers *gnp;
+};
+.DE
+The corresponding XDR routine for this structure is:
+.DS
+.ft CW
+bool_t
+xdr_pgn(xdrs, pp)
+ XDR *xdrs;
+ struct pgn *pp;
+{
+ if (xdr_string(xdrs, &pp->name, NLEN) &&
+ xdr_reference(xdrs, &pp->gnp,
+ sizeof(struct gnumbers), xdr_gnumbers))
+ return(TRUE);
+ return(FALSE);
+}
+.DE
+.IX "pointer semantics and XDR"
+.I "Pointer Semantics and XDR"
+.LP
+In many applications, C programmers attach double meaning to
+the values of a pointer. Typically the value
+.I NULL
+(or zero) means data is not needed,
+yet some application-specific interpretation applies.
+In essence, the C programmer is encoding
+a discriminated union efficiently
+by overloading the interpretation of the value of a pointer.
+For instance, in example E a
+.I NULL
+pointer value for
+.I gnp
+could indicate that
+the person's assets and liabilities are unknown.
+That is, the pointer value encodes two things:
+whether or not the data is known;
+and if it is known, where it is located in memory.
+Linked lists are an extreme example of the use
+of application-specific pointer interpretation.
+.LP
+The primitive
+.I xdr_reference()
+.IX xdr_reference() "" \fIxdr_reference()\fP
+cannot and does not attach any special
+meaning to a null-value pointer during serialization.
+That is, passing an address of a pointer whose value is
+.I NULL
+to
+.I xdr_reference()
+when serialing data will most likely cause a memory fault and, on the UNIX
+system, a core dump.
+.LP
+.I xdr_pointer()
+correctly handles
+.I NULL
+pointers. For more information about its use, see
+the
+.I "Linked Lists"
+topics below.
+.LP
+.I Exercise:
+After reading the section on
+.I "Linked Lists" ,
+return here and extend example E so that
+it can correctly deal with
+.I NULL
+pointer values.
+.LP
+.I Exercise:
+Using the
+.I xdr_union (),
+.I xdr_reference()
+and
+.I xdr_void()
+primitives, implement a generic pointer handling primitive
+that implicitly deals with
+.I NULL
+pointers. That is, implement
+.I xdr_pointer ().
+.NH 2
+\&Non-filter Primitives
+.IX "XDR" "non-filter primitives"
+.LP
+XDR streams can be manipulated with
+the primitives discussed in this section.
+.DS
+.ft CW
+u_int xdr_getpos(xdrs)
+ XDR *xdrs;
+.sp.5
+bool_t xdr_setpos(xdrs, pos)
+ XDR *xdrs;
+ u_int pos;
+.sp.5
+xdr_destroy(xdrs)
+ XDR *xdrs;
+.DE
+The routine
+.I xdr_getpos()
+.IX xdr_getpos() "" \fIxdr_getpos()\fP
+returns an unsigned integer
+that describes the current position in the data stream.
+Warning: In some XDR streams, the returned value of
+.I xdr_getpos()
+is meaningless;
+the routine returns a \-1 in this case
+(though \-1 should be a legitimate value).
+.LP
+The routine
+.I xdr_setpos()
+.IX xdr_setpos() "" \fIxdr_setpos()\fP
+sets a stream position to
+.I pos .
+Warning: In some XDR streams, setting a position is impossible;
+in such cases,
+.I xdr_setpos()
+will return
+.I FALSE .
+This routine will also fail if the requested position is out-of-bounds.
+The definition of bounds varies from stream to stream.
+.LP
+The
+.I xdr_destroy()
+.IX xdr_destroy() "" \fIxdr_destroy()\fP
+primitive destroys the XDR stream.
+Usage of the stream
+after calling this routine is undefined.
+.NH 2
+\&XDR Operation Directions
+.IX XDR "operation directions"
+.IX "direction of XDR operations"
+.LP
+At times you may wish to optimize XDR routines by taking
+advantage of the direction of the operation \(em
+.I XDR_ENCODE
+.I XDR_DECODE
+or
+.I XDR_FREE
+The value
+.I xdrs->x_op
+always contains the direction of the XDR operation.
+Programmers are not encouraged to take advantage of this information.
+Therefore, no example is presented here. However, an example in the
+.I "Linked Lists"
+topic below, demonstrates the usefulness of the
+.I xdrs->x_op
+field.
+.NH 2
+\&XDR Stream Access
+.IX "XDR" "stream access"
+.LP
+An XDR stream is obtained by calling the appropriate creation routine.
+These creation routines take arguments that are tailored to the
+specific properties of the stream.
+.LP
+Streams currently exist for (de)serialization of data to or from
+standard I/O
+.I FILE
+streams, TCP/IP connections and UNIX files, and memory.
+.NH 3
+\&Standard I/O Streams
+.IX "XDR" "standard I/O streams"
+.LP
+XDR streams can be interfaced to standard I/O using the
+.I xdrstdio_create()
+.IX xdrstdio_create() "" \fIxdrstdio_create()\fP
+routine as follows:
+.DS
+.ft CW
+#include <stdio.h>
+#include <rpc/rpc.h> /* \fIxdr streams part of rpc\fP */
+.sp.5
+void
+xdrstdio_create(xdrs, fp, x_op)
+ XDR *xdrs;
+ FILE *fp;
+ enum xdr_op x_op;
+.DE
+The routine
+.I xdrstdio_create()
+initializes an XDR stream pointed to by
+.I xdrs .
+The XDR stream interfaces to the standard I/O library.
+Parameter
+.I fp
+is an open file, and
+.I x_op
+is an XDR direction.
+.NH 3
+\&Memory Streams
+.IX "XDR" "memory streams"
+.LP
+Memory streams allow the streaming of data into or out of
+a specified area of memory:
+.DS
+.ft CW
+#include <rpc/rpc.h>
+.sp.5
+void
+xdrmem_create(xdrs, addr, len, x_op)
+ XDR *xdrs;
+ char *addr;
+ u_int len;
+ enum xdr_op x_op;
+.DE
+The routine
+.I xdrmem_create()
+.IX xdrmem_create() "" \fIxdrmem_create()\fP
+initializes an XDR stream in local memory.
+The memory is pointed to by parameter
+.I addr ;
+parameter
+.I len
+is the length in bytes of the memory.
+The parameters
+.I xdrs
+and
+.I x_op
+are identical to the corresponding parameters of
+.I xdrstdio_create ().
+Currently, the UDP/IP implementation of RPC uses
+.I xdrmem_create ().
+Complete call or result messages are built in memory before calling the
+.I sendto()
+system routine.
+.NH 3
+\&Record (TCP/IP) Streams
+.IX "XDR" "record (TCP/IP) streams"
+.LP
+A record stream is an XDR stream built on top of
+a record marking standard that is built on top of the
+UNIX file or 4.2 BSD connection interface.
+.DS
+.ft CW
+#include <rpc/rpc.h> /* \fIxdr streams part of rpc\fP */
+.sp.5
+xdrrec_create(xdrs,
+ sendsize, recvsize, iohandle, readproc, writeproc)
+ XDR *xdrs;
+ u_int sendsize, recvsize;
+ char *iohandle;
+ int (*readproc)(), (*writeproc)();
+.DE
+The routine
+.I xdrrec_create()
+provides an XDR stream interface that allows for a bidirectional,
+arbitrarily long sequence of records.
+The contents of the records are meant to be data in XDR form.
+The stream's primary use is for interfacing RPC to TCP connections.
+However, it can be used to stream data into or out of normal
+UNIX files.
+.LP
+The parameter
+.I xdrs
+is similar to the corresponding parameter described above.
+The stream does its own data buffering similar to that of standard I/O.
+The parameters
+.I sendsize
+and
+.I recvsize
+determine the size in bytes of the output and input buffers, respectively;
+if their values are zero (0), then predetermined defaults are used.
+When a buffer needs to be filled or flushed, the routine
+.I readproc()
+or
+.I writeproc()
+is called, respectively.
+The usage and behavior of these
+routines are similar to the UNIX system calls
+.I read()
+and
+.I write ().
+However,
+the first parameter to each of these routines is the opaque parameter
+.I iohandle .
+The other two parameters
+.I buf ""
+and
+.I nbytes )
+and the results
+(byte count) are identical to the system routines.
+If
+.I xxx
+is
+.I readproc()
+or
+.I writeproc (),
+then it has the following form:
+.DS
+.ft CW
+.ft I
+/*
+ * returns the actual number of bytes transferred.
+ * -1 is an error
+ */
+.ft CW
+int
+xxx(iohandle, buf, len)
+ char *iohandle;
+ char *buf;
+ int nbytes;
+.DE
+The XDR stream provides means for delimiting records in the byte stream.
+The implementation details of delimiting records in a stream are
+discussed in the
+.I "Advanced Topics"
+topic below.
+The primitives that are specific to record streams are as follows:
+.DS
+.ft CW
+bool_t
+xdrrec_endofrecord(xdrs, flushnow)
+ XDR *xdrs;
+ bool_t flushnow;
+.sp.5
+bool_t
+xdrrec_skiprecord(xdrs)
+ XDR *xdrs;
+.sp.5
+bool_t
+xdrrec_eof(xdrs)
+ XDR *xdrs;
+.DE
+The routine
+.I xdrrec_endofrecord()
+.IX xdrrec_endofrecord() "" \fIxdrrec_endofrecord()\fP
+causes the current outgoing data to be marked as a record.
+If the parameter
+.I flushnow
+is
+.I TRUE ,
+then the stream's
+.I writeproc
+will be called; otherwise,
+.I writeproc
+will be called when the output buffer has been filled.
+.LP
+The routine
+.I xdrrec_skiprecord()
+.IX xdrrec_skiprecord() "" \fIxdrrec_skiprecord()\fP
+causes an input stream's position to be moved past
+the current record boundary and onto the
+beginning of the next record in the stream.
+.LP
+If there is no more data in the stream's input buffer,
+then the routine
+.I xdrrec_eof()
+.IX xdrrec_eof() "" \fIxdrrec_eof()\fP
+returns
+.I TRUE .
+That is not to say that there is no more data
+in the underlying file descriptor.
+.NH 2
+\&XDR Stream Implementation
+.IX "XDR" "stream implementation"
+.IX "stream implementation in XDR"
+.LP
+This section provides the abstract data types needed
+to implement new instances of XDR streams.
+.NH 3
+\&The XDR Object
+.IX "XDR" "object"
+.LP
+The following structure defines the interface to an XDR stream:
+.ie t .DS
+.el .DS L
+.ft CW
+enum xdr_op { XDR_ENCODE=0, XDR_DECODE=1, XDR_FREE=2 };
+.sp.5
+typedef struct {
+ enum xdr_op x_op; /* \fIoperation; fast added param\fP */
+ struct xdr_ops {
+ bool_t (*x_getlong)(); /* \fIget long from stream\fP */
+ bool_t (*x_putlong)(); /* \fIput long to stream\fP */
+ bool_t (*x_getbytes)(); /* \fIget bytes from stream\fP */
+ bool_t (*x_putbytes)(); /* \fIput bytes to stream\fP */
+ u_int (*x_getpostn)(); /* \fIreturn stream offset\fP */
+ bool_t (*x_setpostn)(); /* \fIreposition offset\fP */
+ caddr_t (*x_inline)(); /* \fIptr to buffered data\fP */
+ VOID (*x_destroy)(); /* \fIfree private area\fP */
+ } *x_ops;
+ caddr_t x_public; /* \fIusers' data\fP */
+ caddr_t x_private; /* \fIpointer to private data\fP */
+ caddr_t x_base; /* \fIprivate for position info\fP */
+ int x_handy; /* \fIextra private word\fP */
+} XDR;
+.DE
+The
+.I x_op
+field is the current operation being performed on the stream.
+This field is important to the XDR primitives,
+but should not affect a stream's implementation.
+That is, a stream's implementation should not depend
+on this value.
+The fields
+.I x_private ,
+.I x_base ,
+and
+.I x_handy
+are private to the particular
+stream's implementation.
+The field
+.I x_public
+is for the XDR client and should never be used by
+the XDR stream implementations or the XDR primitives.
+.I x_getpostn() ,
+.I x_setpostn()
+and
+.I x_destroy()
+are macros for accessing operations. The operation
+.I x_inline()
+takes two parameters:
+an XDR *, and an unsigned integer, which is a byte count.
+The routine returns a pointer to a piece of
+the stream's internal buffer.
+The caller can then use the buffer segment for any purpose.
+From the stream's point of view, the bytes in the
+buffer segment have been consumed or put.
+The routine may return
+.I NULL
+if it cannot return a buffer segment of the requested size.
+(The
+.I x_inline()
+routine is for cycle squeezers.
+Use of the resulting buffer is not data-portable.
+Users are encouraged not to use this feature.)
+.LP
+The operations
+.I x_getbytes()
+and
+.I x_putbytes()
+blindly get and put sequences of bytes
+from or to the underlying stream;
+they return
+.I TRUE
+if they are successful, and
+.I FALSE
+otherwise. The routines have identical parameters (replace
+.I xxx ):
+.DS
+.ft CW
+bool_t
+xxxbytes(xdrs, buf, bytecount)
+ XDR *xdrs;
+ char *buf;
+ u_int bytecount;
+.DE
+The operations
+.I x_getlong()
+and
+.I x_putlong()
+receive and put
+long numbers from and to the data stream.
+It is the responsibility of these routines
+to translate the numbers between the machine representation
+and the (standard) external representation.
+The UNIX primitives
+.I htonl()
+and
+.I ntohl()
+can be helpful in accomplishing this.
+The higher-level XDR implementation assumes that
+signed and unsigned long integers contain the same number of bits,
+and that nonnegative integers
+have the same bit representations as unsigned integers.
+The routines return
+.I TRUE
+if they succeed, and
+.I FALSE
+otherwise. They have identical parameters:
+.DS
+.ft CW
+bool_t
+xxxlong(xdrs, lp)
+ XDR *xdrs;
+ long *lp;
+.DE
+Implementors of new XDR streams must make an XDR structure
+(with new operation routines) available to clients,
+using some kind of create routine.
+.NH 1
+\&Advanced Topics
+.IX XDR "advanced topics"
+.LP
+This section describes techniques for passing data structures that
+are not covered in the preceding sections. Such structures include
+linked lists (of arbitrary lengths). Unlike the simpler examples
+covered in the earlier sections, the following examples are written
+using both the XDR C library routines and the XDR data description
+language.
+The
+.I "External Data Representation Standard: Protocol Specification"
+describes this
+language in complete detail.
+.NH 2
+\&Linked Lists
+.IX XDR "linked lists"
+.LP
+The last example in the
+.I Pointers
+topic earlier in this chapter
+presented a C data structure and its associated XDR
+routines for a individual's gross assets and liabilities.
+The example is duplicated below:
+.ie t .DS
+.el .DS L
+.ft CW
+struct gnumbers {
+ long g_assets;
+ long g_liabilities;
+};
+.sp.5
+bool_t
+xdr_gnumbers(xdrs, gp)
+ XDR *xdrs;
+ struct gnumbers *gp;
+{
+ if (xdr_long(xdrs, &(gp->g_assets)))
+ return(xdr_long(xdrs, &(gp->g_liabilities)));
+ return(FALSE);
+}
+.DE
+.LP
+Now assume that we wish to implement a linked list of such information.
+A data structure could be constructed as follows:
+.ie t .DS
+.el .DS L
+.ft CW
+struct gnumbers_node {
+ struct gnumbers gn_numbers;
+ struct gnumbers_node *gn_next;
+};
+.sp .5
+typedef struct gnumbers_node *gnumbers_list;
+.DE
+.LP
+The head of the linked list can be thought of as the data object;
+that is, the head is not merely a convenient shorthand for a
+structure. Similarly the
+.I gn_next
+field is used to indicate whether or not the object has terminated.
+Unfortunately, if the object continues, the
+.I gn_next
+field is also the address of where it continues. The link addresses
+carry no useful information when the object is serialized.
+.LP
+The XDR data description of this linked list is described by the
+recursive declaration of
+.I gnumbers_list :
+.ie t .DS
+.el .DS L
+.ft CW
+struct gnumbers {
+ int g_assets;
+ int g_liabilities;
+};
+.sp .5
+struct gnumbers_node {
+ gnumbers gn_numbers;
+ gnumbers_node *gn_next;
+};
+.DE
+.LP
+In this description, the boolean indicates whether there is more data
+following it. If the boolean is
+.I FALSE ,
+then it is the last data field of the structure. If it is
+.I TRUE ,
+then it is followed by a gnumbers structure and (recursively) by a
+.I gnumbers_list .
+Note that the C declaration has no boolean explicitly declared in it
+(though the
+.I gn_next
+field implicitly carries the information), while the XDR data
+description has no pointer explicitly declared in it.
+.LP
+Hints for writing the XDR routines for a
+.I gnumbers_list
+follow easily from the XDR description above. Note how the primitive
+.I xdr_pointer()
+is used to implement the XDR union above.
+.ie t .DS
+.el .DS L
+.ft CW
+bool_t
+xdr_gnumbers_node(xdrs, gn)
+ XDR *xdrs;
+ gnumbers_node *gn;
+{
+ return(xdr_gnumbers(xdrs, &gn->gn_numbers) &&
+ xdr_gnumbers_list(xdrs, &gp->gn_next));
+}
+.sp .5
+bool_t
+xdr_gnumbers_list(xdrs, gnp)
+ XDR *xdrs;
+ gnumbers_list *gnp;
+{
+ return(xdr_pointer(xdrs, gnp,
+ sizeof(struct gnumbers_node),
+ xdr_gnumbers_node));
+}
+.DE
+.LP
+The unfortunate side effect of XDR'ing a list with these routines
+is that the C stack grows linearly with respect to the number of
+node in the list. This is due to the recursion. The following
+routine collapses the above two mutually recursive into a single,
+non-recursive one.
+.ie t .DS
+.el .DS L
+.ft CW
+bool_t
+xdr_gnumbers_list(xdrs, gnp)
+ XDR *xdrs;
+ gnumbers_list *gnp;
+{
+ bool_t more_data;
+ gnumbers_list *nextp;
+.sp .5
+ for (;;) {
+ more_data = (*gnp != NULL);
+ if (!xdr_bool(xdrs, &more_data)) {
+ return(FALSE);
+ }
+ if (! more_data) {
+ break;
+ }
+ if (xdrs->x_op == XDR_FREE) {
+ nextp = &(*gnp)->gn_next;
+ }
+ if (!xdr_reference(xdrs, gnp,
+ sizeof(struct gnumbers_node), xdr_gnumbers)) {
+
+ return(FALSE);
+ }
+ gnp = (xdrs->x_op == XDR_FREE) ?
+ nextp : &(*gnp)->gn_next;
+ }
+ *gnp = NULL;
+ return(TRUE);
+}
+.DE
+.LP
+The first task is to find out whether there is more data or not,
+so that this boolean information can be serialized. Notice that
+this statement is unnecessary in the
+.I XDR_DECODE
+case, since the value of more_data is not known until we
+deserialize it in the next statement.
+.LP
+The next statement XDR's the more_data field of the XDR union.
+Then if there is truly no more data, we set this last pointer to
+.I NULL
+to indicate the end of the list, and return
+.I TRUE
+because we are done. Note that setting the pointer to
+.I NULL
+is only important in the
+.I XDR_DECODE
+case, since it is already
+.I NULL
+in the
+.I XDR_ENCODE
+and
+XDR_FREE
+cases.
+.LP
+Next, if the direction is
+.I XDR_FREE ,
+the value of
+.I nextp
+is set to indicate the location of the next pointer in the list.
+We do this now because we need to dereference gnp to find the
+location of the next item in the list, and after the next
+statement the storage pointed to by
+.I gnp
+will be freed up and no be longer valid. We can't do this for all
+directions though, because in the
+.I XDR_DECODE
+direction the value of
+.I gnp
+won't be set until the next statement.
+.LP
+Next, we XDR the data in the node using the primitive
+.I xdr_reference ().
+.I xdr_reference()
+is like
+.I xdr_pointer()
+which we used before, but it does not
+send over the boolean indicating whether there is more data.
+We use it instead of
+.I xdr_pointer()
+because we have already XDR'd this information ourselves. Notice
+that the xdr routine passed is not the same type as an element
+in the list. The routine passed is
+.I xdr_gnumbers (),
+for XDR'ing gnumbers, but each element in the list is actually of
+type
+.I gnumbers_node .
+We don't pass
+.I xdr_gnumbers_node()
+because it is recursive, and instead use
+.I xdr_gnumbers()
+which XDR's all of the non-recursive part. Note that this trick
+will work only if the
+.I gn_numbers
+field is the first item in each element, so that their addresses
+are identical when passed to
+.I xdr_reference ().
+.LP
+Finally, we update
+.I gnp
+to point to the next item in the list. If the direction is
+.I XDR_FREE ,
+we set it to the previously saved value, otherwise we can
+dereference
+.I gnp
+to get the proper value. Though harder to understand than the
+recursive version, this non-recursive routine is far less likely
+to blow the C stack. It will also run more efficiently since
+a lot of procedure call overhead has been removed. Most lists
+are small though (in the hundreds of items or less) and the
+recursive version should be sufficient for them.
+.EQ
+delim off
+.EN
diff --git a/lib/libc/rpc/PSD.doc/xdr.rfc.ms b/lib/libc/rpc/PSD.doc/xdr.rfc.ms
new file mode 100644
index 0000000..d4baff5
--- /dev/null
+++ b/lib/libc/rpc/PSD.doc/xdr.rfc.ms
@@ -0,0 +1,1058 @@
+.\"
+.\" Must use -- tbl -- with this one
+.\"
+.\" @(#)xdr.rfc.ms 2.2 88/08/05 4.0 RPCSRC
+.de BT
+.if \\n%=1 .tl ''- % -''
+..
+.ND
+.\" prevent excess underlining in nroff
+.if n .fp 2 R
+.OH 'External Data Representation Standard''Page %'
+.EH 'Page %''External Data Representation Standard'
+.IX "External Data Representation"
+.if \\n%=1 .bp
+.SH
+\&External Data Representation Standard: Protocol Specification
+.IX XDR RFC
+.IX XDR "protocol specification"
+.LP
+.NH 0
+\&Status of this Standard
+.nr OF 1
+.IX XDR "RFC status"
+.LP
+Note: This chapter specifies a protocol that Sun Microsystems, Inc., and
+others are using. It has been designated RFC1014 by the ARPA Network
+Information Center.
+.NH 1
+Introduction
+\&
+.LP
+XDR is a standard for the description and encoding of data. It is
+useful for transferring data between different computer
+architectures, and has been used to communicate data between such
+diverse machines as the Sun Workstation, VAX, IBM-PC, and Cray.
+XDR fits into the ISO presentation layer, and is roughly analogous in
+purpose to X.409, ISO Abstract Syntax Notation. The major difference
+between these two is that XDR uses implicit typing, while X.409 uses
+explicit typing.
+.LP
+XDR uses a language to describe data formats. The language can only
+be used only to describe data; it is not a programming language.
+This language allows one to describe intricate data formats in a
+concise manner. The alternative of using graphical representations
+(itself an informal language) quickly becomes incomprehensible when
+faced with complexity. The XDR language itself is similar to the C
+language [1], just as Courier [4] is similar to Mesa. Protocols such
+as Sun RPC (Remote Procedure Call) and the NFS (Network File System)
+use XDR to describe the format of their data.
+.LP
+The XDR standard makes the following assumption: that bytes (or
+octets) are portable, where a byte is defined to be 8 bits of data.
+A given hardware device should encode the bytes onto the various
+media in such a way that other hardware devices may decode the bytes
+without loss of meaning. For example, the Ethernet standard
+suggests that bytes be encoded in "little-endian" style [2], or least
+significant bit first.
+.NH 2
+\&Basic Block Size
+.IX XDR "basic block size"
+.IX XDR "block size"
+.LP
+The representation of all items requires a multiple of four bytes (or
+32 bits) of data. The bytes are numbered 0 through n-1. The bytes
+are read or written to some byte stream such that byte m always
+precedes byte m+1. If the n bytes needed to contain the data are not
+a multiple of four, then the n bytes are followed by enough (0 to 3)
+residual zero bytes, r, to make the total byte count a multiple of 4.
+.LP
+We include the familiar graphic box notation for illustration and
+comparison. In most illustrations, each box (delimited by a plus
+sign at the 4 corners and vertical bars and dashes) depicts a byte.
+Ellipses (...) between boxes show zero or more additional bytes where
+required.
+.ie t .DS
+.el .DS L
+\fIA Block\fP
+
+\f(CW+--------+--------+...+--------+--------+...+--------+
+| byte 0 | byte 1 |...|byte n-1| 0 |...| 0 |
++--------+--------+...+--------+--------+...+--------+
+|<-----------n bytes---------->|<------r bytes------>|
+|<-----------n+r (where (n+r) mod 4 = 0)>----------->|\fP
+
+.DE
+.NH 1
+\&XDR Data Types
+.IX XDR "data types"
+.IX "XDR data types"
+.LP
+Each of the sections that follow describes a data type defined in the
+XDR standard, shows how it is declared in the language, and includes
+a graphic illustration of its encoding.
+.LP
+For each data type in the language we show a general paradigm
+declaration. Note that angle brackets (< and >) denote
+variable length sequences of data and square brackets ([ and ]) denote
+fixed-length sequences of data. "n", "m" and "r" denote integers.
+For the full language specification and more formal definitions of
+terms such as "identifier" and "declaration", refer to
+.I "The XDR Language Specification" ,
+below.
+.LP
+For some data types, more specific examples are included.
+A more extensive example of a data description is in
+.I "An Example of an XDR Data Description"
+below.
+.NH 2
+\&Integer
+.IX XDR integer
+.LP
+An XDR signed integer is a 32-bit datum that encodes an integer in
+the range [-2147483648,2147483647]. The integer is represented in
+two's complement notation. The most and least significant bytes are
+0 and 3, respectively. Integers are declared as follows:
+.ie t .DS
+.el .DS L
+\fIInteger\fP
+
+\f(CW(MSB) (LSB)
++-------+-------+-------+-------+
+|byte 0 |byte 1 |byte 2 |byte 3 |
++-------+-------+-------+-------+
+<------------32 bits------------>\fP
+.DE
+.NH 2
+\&Unsigned Integer
+.IX XDR "unsigned integer"
+.IX XDR "integer, unsigned"
+.LP
+An XDR unsigned integer is a 32-bit datum that encodes a nonnegative
+integer in the range [0,4294967295]. It is represented by an
+unsigned binary number whose most and least significant bytes are 0
+and 3, respectively. An unsigned integer is declared as follows:
+.ie t .DS
+.el .DS L
+\fIUnsigned Integer\fP
+
+\f(CW(MSB) (LSB)
++-------+-------+-------+-------+
+|byte 0 |byte 1 |byte 2 |byte 3 |
++-------+-------+-------+-------+
+<------------32 bits------------>\fP
+.DE
+.NH 2
+\&Enumeration
+.IX XDR enumeration
+.LP
+Enumerations have the same representation as signed integers.
+Enumerations are handy for describing subsets of the integers.
+Enumerated data is declared as follows:
+.ft CW
+.DS
+enum { name-identifier = constant, ... } identifier;
+.DE
+For example, the three colors red, yellow, and blue could be
+described by an enumerated type:
+.DS
+.ft CW
+enum { RED = 2, YELLOW = 3, BLUE = 5 } colors;
+.DE
+It is an error to encode as an enum any other integer than those that
+have been given assignments in the enum declaration.
+.NH 2
+\&Boolean
+.IX XDR boolean
+.LP
+Booleans are important enough and occur frequently enough to warrant
+their own explicit type in the standard. Booleans are declared as
+follows:
+.DS
+.ft CW
+bool identifier;
+.DE
+This is equivalent to:
+.DS
+.ft CW
+enum { FALSE = 0, TRUE = 1 } identifier;
+.DE
+.NH 2
+\&Hyper Integer and Unsigned Hyper Integer
+.IX XDR "hyper integer"
+.IX XDR "integer, hyper"
+.LP
+The standard also defines 64-bit (8-byte) numbers called hyper
+integer and unsigned hyper integer. Their representations are the
+obvious extensions of integer and unsigned integer defined above.
+They are represented in two's complement notation. The most and
+least significant bytes are 0 and 7, respectively. Their
+declarations:
+.ie t .DS
+.el .DS L
+\fIHyper Integer\fP
+\fIUnsigned Hyper Integer\fP
+
+\f(CW(MSB) (LSB)
++-------+-------+-------+-------+-------+-------+-------+-------+
+|byte 0 |byte 1 |byte 2 |byte 3 |byte 4 |byte 5 |byte 6 |byte 7 |
++-------+-------+-------+-------+-------+-------+-------+-------+
+<----------------------------64 bits---------------------------->\fP
+.DE
+.NH 2
+\&Floating-point
+.IX XDR "integer, floating point"
+.IX XDR "floating-point integer"
+.LP
+The standard defines the floating-point data type "float" (32 bits or
+4 bytes). The encoding used is the IEEE standard for normalized
+single-precision floating-point numbers [3]. The following three
+fields describe the single-precision floating-point number:
+.RS
+.IP \fBS\fP:
+The sign of the number. Values 0 and 1 represent positive and
+negative, respectively. One bit.
+.IP \fBE\fP:
+The exponent of the number, base 2. 8 bits are devoted to this
+field. The exponent is biased by 127.
+.IP \fBF\fP:
+The fractional part of the number's mantissa, base 2. 23 bits
+are devoted to this field.
+.RE
+.LP
+Therefore, the floating-point number is described by:
+.DS
+(-1)**S * 2**(E-Bias) * 1.F
+.DE
+It is declared as follows:
+.ie t .DS
+.el .DS L
+\fISingle-Precision Floating-Point\fP
+
+\f(CW+-------+-------+-------+-------+
+|byte 0 |byte 1 |byte 2 |byte 3 |
+S| E | F |
++-------+-------+-------+-------+
+1|<- 8 ->|<-------23 bits------>|
+<------------32 bits------------>\fP
+.DE
+Just as the most and least significant bytes of a number are 0 and 3,
+the most and least significant bits of a single-precision floating-
+point number are 0 and 31. The beginning bit (and most significant
+bit) offsets of S, E, and F are 0, 1, and 9, respectively. Note that
+these numbers refer to the mathematical positions of the bits, and
+NOT to their actual physical locations (which vary from medium to
+medium).
+.LP
+The IEEE specifications should be consulted concerning the encoding
+for signed zero, signed infinity (overflow), and denormalized numbers
+(underflow) [3]. According to IEEE specifications, the "NaN" (not a
+number) is system dependent and should not be used externally.
+.NH 2
+\&Double-precision Floating-point
+.IX XDR "integer, double-precision floating point"
+.IX XDR "double-precision floating-point integer"
+.LP
+The standard defines the encoding for the double-precision floating-
+point data type "double" (64 bits or 8 bytes). The encoding used is
+the IEEE standard for normalized double-precision floating-point
+numbers [3]. The standard encodes the following three fields, which
+describe the double-precision floating-point number:
+.RS
+.IP \fBS\fP:
+The sign of the number. Values 0 and 1 represent positive and
+negative, respectively. One bit.
+.IP \fBE\fP:
+The exponent of the number, base 2. 11 bits are devoted to this
+field. The exponent is biased by 1023.
+.IP \fBF\fP:
+The fractional part of the number's mantissa, base 2. 52 bits
+are devoted to this field.
+.RE
+.LP
+Therefore, the floating-point number is described by:
+.DS
+(-1)**S * 2**(E-Bias) * 1.F
+.DE
+It is declared as follows:
+.ie t .DS
+.el .DS L
+\fIDouble-Precision Floating-Point\fP
+
+\f(CW+------+------+------+------+------+------+------+------+
+|byte 0|byte 1|byte 2|byte 3|byte 4|byte 5|byte 6|byte 7|
+S| E | F |
++------+------+------+------+------+------+------+------+
+1|<--11-->|<-----------------52 bits------------------->|
+<-----------------------64 bits------------------------->\fP
+.DE
+Just as the most and least significant bytes of a number are 0 and 3,
+the most and least significant bits of a double-precision floating-
+point number are 0 and 63. The beginning bit (and most significant
+bit) offsets of S, E , and F are 0, 1, and 12, respectively. Note
+that these numbers refer to the mathematical positions of the bits,
+and NOT to their actual physical locations (which vary from medium to
+medium).
+.LP
+The IEEE specifications should be consulted concerning the encoding
+for signed zero, signed infinity (overflow), and denormalized numbers
+(underflow) [3]. According to IEEE specifications, the "NaN" (not a
+number) is system dependent and should not be used externally.
+.NH 2
+\&Fixed-length Opaque Data
+.IX XDR "fixed-length opaque data"
+.IX XDR "opaque data, fixed length"
+.LP
+At times, fixed-length uninterpreted data needs to be passed among
+machines. This data is called "opaque" and is declared as follows:
+.DS
+.ft CW
+opaque identifier[n];
+.DE
+where the constant n is the (static) number of bytes necessary to
+contain the opaque data. If n is not a multiple of four, then the n
+bytes are followed by enough (0 to 3) residual zero bytes, r, to make
+the total byte count of the opaque object a multiple of four.
+.ie t .DS
+.el .DS L
+\fIFixed-Length Opaque\fP
+
+\f(CW0 1 ...
++--------+--------+...+--------+--------+...+--------+
+| byte 0 | byte 1 |...|byte n-1| 0 |...| 0 |
++--------+--------+...+--------+--------+...+--------+
+|<-----------n bytes---------->|<------r bytes------>|
+|<-----------n+r (where (n+r) mod 4 = 0)------------>|\fP
+.DE
+.NH 2
+\&Variable-length Opaque Data
+.IX XDR "variable-length opaque data"
+.IX XDR "opaque data, variable length"
+.LP
+The standard also provides for variable-length (counted) opaque data,
+defined as a sequence of n (numbered 0 through n-1) arbitrary bytes
+to be the number n encoded as an unsigned integer (as described
+below), and followed by the n bytes of the sequence.
+.LP
+Byte m of the sequence always precedes byte m+1 of the sequence, and
+byte 0 of the sequence always follows the sequence's length (count).
+enough (0 to 3) residual zero bytes, r, to make the total byte count
+a multiple of four. Variable-length opaque data is declared in the
+following way:
+.DS
+.ft CW
+opaque identifier<m>;
+.DE
+or
+.DS
+.ft CW
+opaque identifier<>;
+.DE
+The constant m denotes an upper bound of the number of bytes that the
+sequence may contain. If m is not specified, as in the second
+declaration, it is assumed to be (2**32) - 1, the maximum length.
+The constant m would normally be found in a protocol specification.
+For example, a filing protocol may state that the maximum data
+transfer size is 8192 bytes, as follows:
+.DS
+.ft CW
+opaque filedata<8192>;
+.DE
+This can be illustrated as follows:
+.ie t .DS
+.el .DS L
+\fIVariable-Length Opaque\fP
+
+\f(CW0 1 2 3 4 5 ...
++-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+
+| length n |byte0|byte1|...| n-1 | 0 |...| 0 |
++-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+
+|<-------4 bytes------->|<------n bytes------>|<---r bytes--->|
+|<----n+r (where (n+r) mod 4 = 0)---->|\fP
+.DE
+.LP
+It is an error to encode a length greater than the maximum
+described in the specification.
+.NH 2
+\&String
+.IX XDR string
+.LP
+The standard defines a string of n (numbered 0 through n-1) ASCII
+bytes to be the number n encoded as an unsigned integer (as described
+above), and followed by the n bytes of the string. Byte m of the
+string always precedes byte m+1 of the string, and byte 0 of the
+string always follows the string's length. If n is not a multiple of
+four, then the n bytes are followed by enough (0 to 3) residual zero
+bytes, r, to make the total byte count a multiple of four. Counted
+byte strings are declared as follows:
+.DS
+.ft CW
+string object<m>;
+.DE
+or
+.DS
+.ft CW
+string object<>;
+.DE
+The constant m denotes an upper bound of the number of bytes that a
+string may contain. If m is not specified, as in the second
+declaration, it is assumed to be (2**32) - 1, the maximum length.
+The constant m would normally be found in a protocol specification.
+For example, a filing protocol may state that a file name can be no
+longer than 255 bytes, as follows:
+.DS
+.ft CW
+string filename<255>;
+.DE
+Which can be illustrated as:
+.ie t .DS
+.el .DS L
+\fIA String\fP
+
+\f(CW0 1 2 3 4 5 ...
++-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+
+| length n |byte0|byte1|...| n-1 | 0 |...| 0 |
++-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+
+|<-------4 bytes------->|<------n bytes------>|<---r bytes--->|
+|<----n+r (where (n+r) mod 4 = 0)---->|\fP
+.DE
+.LP
+It is an error to encode a length greater than the maximum
+described in the specification.
+.NH 2
+\&Fixed-length Array
+.IX XDR "fixed-length array"
+.IX XDR "array, fixed length"
+.LP
+Declarations for fixed-length arrays of homogeneous elements are in
+the following form:
+.DS
+.ft CW
+type-name identifier[n];
+.DE
+Fixed-length arrays of elements numbered 0 through n-1 are encoded by
+individually encoding the elements of the array in their natural
+order, 0 through n-1. Each element's size is a multiple of four
+bytes. Though all elements are of the same type, the elements may
+have different sizes. For example, in a fixed-length array of
+strings, all elements are of type "string", yet each element will
+vary in its length.
+.ie t .DS
+.el .DS L
+\fIFixed-Length Array\fP
+
+\f(CW+---+---+---+---+---+---+---+---+...+---+---+---+---+
+| element 0 | element 1 |...| element n-1 |
++---+---+---+---+---+---+---+---+...+---+---+---+---+
+|<--------------------n elements------------------->|\fP
+.DE
+.NH 2
+\&Variable-length Array
+.IX XDR "variable-length array"
+.IX XDR "array, variable length"
+.LP
+Counted arrays provide the ability to encode variable-length arrays
+of homogeneous elements. The array is encoded as the element count n
+(an unsigned integer) followed by the encoding of each of the array's
+elements, starting with element 0 and progressing through element n-
+1. The declaration for variable-length arrays follows this form:
+.DS
+.ft CW
+type-name identifier<m>;
+.DE
+or
+.DS
+.ft CW
+type-name identifier<>;
+.DE
+The constant m specifies the maximum acceptable element count of an
+array; if m is not specified, as in the second declaration, it is
+assumed to be (2**32) - 1.
+.ie t .DS
+.el .DS L
+\fICounted Array\fP
+
+\f(CW0 1 2 3
++--+--+--+--+--+--+--+--+--+--+--+--+...+--+--+--+--+
+| n | element 0 | element 1 |...|element n-1|
++--+--+--+--+--+--+--+--+--+--+--+--+...+--+--+--+--+
+|<-4 bytes->|<--------------n elements------------->|\fP
+.DE
+It is an error to encode a value of n that is greater than the
+maximum described in the specification.
+.NH 2
+\&Structure
+.IX XDR structure
+.LP
+Structures are declared as follows:
+.DS
+.ft CW
+struct {
+ component-declaration-A;
+ component-declaration-B;
+ \&...
+} identifier;
+.DE
+The components of the structure are encoded in the order of their
+declaration in the structure. Each component's size is a multiple of
+four bytes, though the components may be different sizes.
+.ie t .DS
+.el .DS L
+\fIStructure\fP
+
+\f(CW+-------------+-------------+...
+| component A | component B |...
++-------------+-------------+...\fP
+.DE
+.NH 2
+\&Discriminated Union
+.IX XDR "discriminated union"
+.IX XDR union discriminated
+.LP
+A discriminated union is a type composed of a discriminant followed
+by a type selected from a set of prearranged types according to the
+value of the discriminant. The type of discriminant is either "int",
+"unsigned int", or an enumerated type, such as "bool". The component
+types are called "arms" of the union, and are preceded by the value
+of the discriminant which implies their encoding. Discriminated
+unions are declared as follows:
+.DS
+.ft CW
+union switch (discriminant-declaration) {
+ case discriminant-value-A:
+ arm-declaration-A;
+ case discriminant-value-B:
+ arm-declaration-B;
+ \&...
+ default: default-declaration;
+} identifier;
+.DE
+Each "case" keyword is followed by a legal value of the discriminant.
+The default arm is optional. If it is not specified, then a valid
+encoding of the union cannot take on unspecified discriminant values.
+The size of the implied arm is always a multiple of four bytes.
+.LP
+The discriminated union is encoded as its discriminant followed by
+the encoding of the implied arm.
+.ie t .DS
+.el .DS L
+\fIDiscriminated Union\fP
+
+\f(CW0 1 2 3
++---+---+---+---+---+---+---+---+
+| discriminant | implied arm |
++---+---+---+---+---+---+---+---+
+|<---4 bytes--->|\fP
+.DE
+.NH 2
+\&Void
+.IX XDR void
+.LP
+An XDR void is a 0-byte quantity. Voids are useful for describing
+operations that take no data as input or no data as output. They are
+also useful in unions, where some arms may contain data and others do
+not. The declaration is simply as follows:
+.DS
+.ft CW
+void;
+.DE
+Voids are illustrated as follows:
+.ie t .DS
+.el .DS L
+\fIVoid\fP
+
+\f(CW ++
+ ||
+ ++
+--><-- 0 bytes\fP
+.DE
+.NH 2
+\&Constant
+.IX XDR constant
+.LP
+The data declaration for a constant follows this form:
+.DS
+.ft CW
+const name-identifier = n;
+.DE
+"const" is used to define a symbolic name for a constant; it does not
+declare any data. The symbolic constant may be used anywhere a
+regular constant may be used. For example, the following defines a
+symbolic constant DOZEN, equal to 12.
+.DS
+.ft CW
+const DOZEN = 12;
+.DE
+.NH 2
+\&Typedef
+.IX XDR typedef
+.LP
+"typedef" does not declare any data either, but serves to define new
+identifiers for declaring data. The syntax is:
+.DS
+.ft CW
+typedef declaration;
+.DE
+The new type name is actually the variable name in the declaration
+part of the typedef. For example, the following defines a new type
+called "eggbox" using an existing type called "egg":
+.DS
+.ft CW
+typedef egg eggbox[DOZEN];
+.DE
+Variables declared using the new type name have the same type as the
+new type name would have in the typedef, if it was considered a
+variable. For example, the following two declarations are equivalent
+in declaring the variable "fresheggs":
+.DS
+.ft CW
+eggbox fresheggs;
+egg fresheggs[DOZEN];
+.DE
+When a typedef involves a struct, enum, or union definition, there is
+another (preferred) syntax that may be used to define the same type.
+In general, a typedef of the following form:
+.DS
+.ft CW
+typedef <<struct, union, or enum definition>> identifier;
+.DE
+may be converted to the alternative form by removing the "typedef"
+part and placing the identifier after the "struct", "union", or
+"enum" keyword, instead of at the end. For example, here are the two
+ways to define the type "bool":
+.DS
+.ft CW
+typedef enum { /* \fIusing typedef\fP */
+ FALSE = 0,
+ TRUE = 1
+ } bool;
+
+enum bool { /* \fIpreferred alternative\fP */
+ FALSE = 0,
+ TRUE = 1
+ };
+.DE
+The reason this syntax is preferred is one does not have to wait
+until the end of a declaration to figure out the name of the new
+type.
+.NH 2
+\&Optional-data
+.IX XDR "optional data"
+.IX XDR "data, optional"
+.LP
+Optional-data is one kind of union that occurs so frequently that we
+give it a special syntax of its own for declaring it. It is declared
+as follows:
+.DS
+.ft CW
+type-name *identifier;
+.DE
+This is equivalent to the following union:
+.DS
+.ft CW
+union switch (bool opted) {
+ case TRUE:
+ type-name element;
+ case FALSE:
+ void;
+} identifier;
+.DE
+It is also equivalent to the following variable-length array
+declaration, since the boolean "opted" can be interpreted as the
+length of the array:
+.DS
+.ft CW
+type-name identifier<1>;
+.DE
+Optional-data is not so interesting in itself, but it is very useful
+for describing recursive data-structures such as linked-lists and
+trees. For example, the following defines a type "stringlist" that
+encodes lists of arbitrary length strings:
+.DS
+.ft CW
+struct *stringlist {
+ string item<>;
+ stringlist next;
+};
+.DE
+It could have been equivalently declared as the following union:
+.DS
+.ft CW
+union stringlist switch (bool opted) {
+ case TRUE:
+ struct {
+ string item<>;
+ stringlist next;
+ } element;
+ case FALSE:
+ void;
+};
+.DE
+or as a variable-length array:
+.DS
+.ft CW
+struct stringlist<1> {
+ string item<>;
+ stringlist next;
+};
+.DE
+Both of these declarations obscure the intention of the stringlist
+type, so the optional-data declaration is preferred over both of
+them. The optional-data type also has a close correlation to how
+recursive data structures are represented in high-level languages
+such as Pascal or C by use of pointers. In fact, the syntax is the
+same as that of the C language for pointers.
+.NH 2
+\&Areas for Future Enhancement
+.IX XDR futures
+.LP
+The XDR standard lacks representations for bit fields and bitmaps,
+since the standard is based on bytes. Also missing are packed (or
+binary-coded) decimals.
+.LP
+The intent of the XDR standard was not to describe every kind of data
+that people have ever sent or will ever want to send from machine to
+machine. Rather, it only describes the most commonly used data-types
+of high-level languages such as Pascal or C so that applications
+written in these languages will be able to communicate easily over
+some medium.
+.LP
+One could imagine extensions to XDR that would let it describe almost
+any existing protocol, such as TCP. The minimum necessary for this
+are support for different block sizes and byte-orders. The XDR
+discussed here could then be considered the 4-byte big-endian member
+of a larger XDR family.
+.NH 1
+\&Discussion
+.sp 2
+.NH 2
+\&Why a Language for Describing Data?
+.IX XDR language
+.LP
+There are many advantages in using a data-description language such
+as XDR versus using diagrams. Languages are more formal than
+diagrams and lead to less ambiguous descriptions of data.
+Languages are also easier to understand and allow one to think of
+other issues instead of the low-level details of bit-encoding.
+Also, there is a close analogy between the types of XDR and a
+high-level language such as C or Pascal. This makes the
+implementation of XDR encoding and decoding modules an easier task.
+Finally, the language specification itself is an ASCII string that
+can be passed from machine to machine to perform on-the-fly data
+interpretation.
+.NH 2
+\&Why Only one Byte-Order for an XDR Unit?
+.IX XDR "byte order"
+.LP
+Supporting two byte-orderings requires a higher level protocol for
+determining in which byte-order the data is encoded. Since XDR is
+not a protocol, this can't be done. The advantage of this, though,
+is that data in XDR format can be written to a magnetic tape, for
+example, and any machine will be able to interpret it, since no
+higher level protocol is necessary for determining the byte-order.
+.NH 2
+\&Why does XDR use Big-Endian Byte-Order?
+.LP
+Yes, it is unfair, but having only one byte-order means you have to
+be unfair to somebody. Many architectures, such as the Motorola
+68000 and IBM 370, support the big-endian byte-order.
+.NH 2
+\&Why is the XDR Unit Four Bytes Wide?
+.LP
+There is a tradeoff in choosing the XDR unit size. Choosing a small
+size such as two makes the encoded data small, but causes alignment
+problems for machines that aren't aligned on these boundaries. A
+large size such as eight means the data will be aligned on virtually
+every machine, but causes the encoded data to grow too big. We chose
+four as a compromise. Four is big enough to support most
+architectures efficiently, except for rare machines such as the
+eight-byte aligned Cray. Four is also small enough to keep the
+encoded data restricted to a reasonable size.
+.NH 2
+\&Why must Variable-Length Data be Padded with Zeros?
+.IX XDR "variable-length data"
+.LP
+It is desirable that the same data encode into the same thing on all
+machines, so that encoded data can be meaningfully compared or
+checksummed. Forcing the padded bytes to be zero ensures this.
+.NH 2
+\&Why is there No Explicit Data-Typing?
+.LP
+Data-typing has a relatively high cost for what small advantages it
+may have. One cost is the expansion of data due to the inserted type
+fields. Another is the added cost of interpreting these type fields
+and acting accordingly. And most protocols already know what type
+they expect, so data-typing supplies only redundant information.
+However, one can still get the benefits of data-typing using XDR. One
+way is to encode two things: first a string which is the XDR data
+description of the encoded data, and then the encoded data itself.
+Another way is to assign a value to all the types in XDR, and then
+define a universal type which takes this value as its discriminant
+and for each value, describes the corresponding data type.
+.NH 1
+\&The XDR Language Specification
+.IX XDR language
+.sp 1
+.NH 2
+\&Notational Conventions
+.IX "XDR language" notation
+.LP
+This specification uses an extended Backus-Naur Form notation for
+describing the XDR language. Here is a brief description of the
+notation:
+.IP 1.
+The characters
+.I | ,
+.I ( ,
+.I ) ,
+.I [ ,
+.I ] ,
+.I " ,
+and
+.I *
+are special.
+.IP 2.
+Terminal symbols are strings of any characters surrounded by
+double quotes.
+.IP 3.
+Non-terminal symbols are strings of non-special characters.
+.IP 4.
+Alternative items are separated by a vertical bar ("\fI|\fP").
+.IP 5.
+Optional items are enclosed in brackets.
+.IP 6.
+Items are grouped together by enclosing them in parentheses.
+.IP 7.
+A
+.I *
+following an item means 0 or more occurrences of that item.
+.LP
+For example, consider the following pattern:
+.DS L
+"a " "very" (", " " very")* [" cold " "and"] " rainy " ("day" | "night")
+.DE
+.LP
+An infinite number of strings match this pattern. A few of them
+are:
+.DS
+"a very rainy day"
+"a very, very rainy day"
+"a very cold and rainy day"
+"a very, very, very cold and rainy night"
+.DE
+.NH 2
+\&Lexical Notes
+.IP 1.
+Comments begin with '/*' and terminate with '*/'.
+.IP 2.
+White space serves to separate items and is otherwise ignored.
+.IP 3.
+An identifier is a letter followed by an optional sequence of
+letters, digits or underbar ('_'). The case of identifiers is
+not ignored.
+.IP 4.
+A constant is a sequence of one or more decimal digits,
+optionally preceded by a minus-sign ('-').
+.NH 2
+\&Syntax Information
+.IX "XDR language" syntax
+.DS
+.ft CW
+declaration:
+ type-specifier identifier
+ | type-specifier identifier "[" value "]"
+ | type-specifier identifier "<" [ value ] ">"
+ | "opaque" identifier "[" value "]"
+ | "opaque" identifier "<" [ value ] ">"
+ | "string" identifier "<" [ value ] ">"
+ | type-specifier "*" identifier
+ | "void"
+.DE
+.DS
+.ft CW
+value:
+ constant
+ | identifier
+
+type-specifier:
+ [ "unsigned" ] "int"
+ | [ "unsigned" ] "hyper"
+ | "float"
+ | "double"
+ | "bool"
+ | enum-type-spec
+ | struct-type-spec
+ | union-type-spec
+ | identifier
+.DE
+.DS
+.ft CW
+enum-type-spec:
+ "enum" enum-body
+
+enum-body:
+ "{"
+ ( identifier "=" value )
+ ( "," identifier "=" value )*
+ "}"
+.DE
+.DS
+.ft CW
+struct-type-spec:
+ "struct" struct-body
+
+struct-body:
+ "{"
+ ( declaration ";" )
+ ( declaration ";" )*
+ "}"
+.DE
+.DS
+.ft CW
+union-type-spec:
+ "union" union-body
+
+union-body:
+ "switch" "(" declaration ")" "{"
+ ( "case" value ":" declaration ";" )
+ ( "case" value ":" declaration ";" )*
+ [ "default" ":" declaration ";" ]
+ "}"
+
+constant-def:
+ "const" identifier "=" constant ";"
+.DE
+.DS
+.ft CW
+type-def:
+ "typedef" declaration ";"
+ | "enum" identifier enum-body ";"
+ | "struct" identifier struct-body ";"
+ | "union" identifier union-body ";"
+
+definition:
+ type-def
+ | constant-def
+
+specification:
+ definition *
+.DE
+.NH 3
+\&Syntax Notes
+.IX "XDR language" syntax
+.LP
+.IP 1.
+The following are keywords and cannot be used as identifiers:
+"bool", "case", "const", "default", "double", "enum", "float",
+"hyper", "opaque", "string", "struct", "switch", "typedef", "union",
+"unsigned" and "void".
+.IP 2.
+Only unsigned constants may be used as size specifications for
+arrays. If an identifier is used, it must have been declared
+previously as an unsigned constant in a "const" definition.
+.IP 3.
+Constant and type identifiers within the scope of a specification
+are in the same name space and must be declared uniquely within this
+scope.
+.IP 4.
+Similarly, variable names must be unique within the scope of
+struct and union declarations. Nested struct and union declarations
+create new scopes.
+.IP 5.
+The discriminant of a union must be of a type that evaluates to
+an integer. That is, "int", "unsigned int", "bool", an enumerated
+type or any typedefed type that evaluates to one of these is legal.
+Also, the case values must be one of the legal values of the
+discriminant. Finally, a case value may not be specified more than
+once within the scope of a union declaration.
+.NH 1
+\&An Example of an XDR Data Description
+.LP
+Here is a short XDR data description of a thing called a "file",
+which might be used to transfer files from one machine to another.
+.ie t .DS
+.el .DS L
+.ft CW
+
+const MAXUSERNAME = 32; /*\fI max length of a user name \fP*/
+const MAXFILELEN = 65535; /*\fI max length of a file \fP*/
+const MAXNAMELEN = 255; /*\fI max length of a file name \fP*/
+
+.ft I
+/*
+ * Types of files:
+ */
+.ft CW
+
+enum filekind {
+ TEXT = 0, /*\fI ascii data \fP*/
+ DATA = 1, /*\fI raw data \fP*/
+ EXEC = 2 /*\fI executable \fP*/
+};
+
+.ft I
+/*
+ * File information, per kind of file:
+ */
+.ft CW
+
+union filetype switch (filekind kind) {
+ case TEXT:
+ void; /*\fI no extra information \fP*/
+ case DATA:
+ string creator<MAXNAMELEN>; /*\fI data creator \fP*/
+ case EXEC:
+ string interpretor<MAXNAMELEN>; /*\fI program interpretor \fP*/
+};
+
+.ft I
+/*
+ * A complete file:
+ */
+.ft CW
+
+struct file {
+ string filename<MAXNAMELEN>; /*\fI name of file \fP*/
+ filetype type; /*\fI info about file \fP*/
+ string owner<MAXUSERNAME>; /*\fI owner of file \fP*/
+ opaque data<MAXFILELEN>; /*\fI file data \fP*/
+};
+.DE
+.LP
+Suppose now that there is a user named "john" who wants to store
+his lisp program "sillyprog" that contains just the data "(quit)".
+His file would be encoded as follows:
+.TS
+box tab (&) ;
+lfI lfI lfI lfI
+rfL rfL rfL l .
+Offset&Hex Bytes&ASCII&Description
+_
+0&00 00 00 09&....&Length of filename = 9
+4&73 69 6c 6c&sill&Filename characters
+8&79 70 72 6f&ypro& ... and more characters ...
+12&67 00 00 00&g...& ... and 3 zero-bytes of fill
+16&00 00 00 02&....&Filekind is EXEC = 2
+20&00 00 00 04&....&Length of interpretor = 4
+24&6c 69 73 70&lisp&Interpretor characters
+28&00 00 00 04&....&Length of owner = 4
+32&6a 6f 68 6e&john&Owner characters
+36&00 00 00 06&....&Length of file data = 6
+40&28 71 75 69&(qui&File data bytes ...
+44&74 29 00 00&t)..& ... and 2 zero-bytes of fill
+.TE
+.NH 1
+\&References
+.LP
+[1] Brian W. Kernighan & Dennis M. Ritchie, "The C Programming
+Language", Bell Laboratories, Murray Hill, New Jersey, 1978.
+.LP
+[2] Danny Cohen, "On Holy Wars and a Plea for Peace", IEEE Computer,
+October 1981.
+.LP
+[3] "IEEE Standard for Binary Floating-Point Arithmetic", ANSI/IEEE
+Standard 754-1985, Institute of Electrical and Electronics
+Engineers, August 1985.
+.LP
+[4] "Courier: The Remote Procedure Call Protocol", XEROX
+Corporation, XSIS 038112, December 1981.
diff --git a/lib/libc/rpc/README b/lib/libc/rpc/README
new file mode 100644
index 0000000..ad9d70f
--- /dev/null
+++ b/lib/libc/rpc/README
@@ -0,0 +1,233 @@
+RPCSRC 4.0 7/11/89
+
+This distribution contains Sun Microsystem's implementation of the
+RPC and XDR protocols and is compatible with 4.2BSD and 4.3BSD. Also
+included is complete documentation, utilities, RPC service
+specification files, and demonstration services in the format used by
+the RPC protocol compiler (rpcgen). See WHAT'S NEW below for
+details.
+
+NOTE ABOUT SECURE RPC:
+
+This release of RPCSRC contains most of the code needed to implement
+Secure RPC (see "DES Authentication" in the RPC Protocol Specification,
+doc/rpc.rfc.ms). Due to legal considerations, we are unable to
+distribute an implementation of DES, the Data Encryption Standard, which
+Secure RPC requires. For this reason, all of the files, documentation, and
+programs associated with Secure RPC have been placed into a separate
+directory, secure_rpc. The RPC library contained in the main body of this
+release *DOES NOT* support Secure RPC. See secure_rpc/README for more
+details. (A DES library was posted in Volume 18 of comp.sources.unix.)
+
+If you wish to report bugs found in this release, send mail to:
+
+Portable ONC/NFS
+Sun Microsystems, Inc
+MS 12-33
+2550 Garcia Avenue
+Mountain View, CA 94043
+
+or send Email to nfsnet@sun.com (the Internet) or sun!nfsnet (Usenet).
+
+ROADMAP
+
+The directory hierarchy is as follows:
+
+ demo/ Various demonstration services
+ demo/dir Remote directory lister
+ demo/msg Remote console message delivery service
+ demo/sort Remote sort service
+
+ doc/ Documentation for RPC, XDR and NFS in "-ms" format.
+
+ etc/ Utilities (rpcinfo and portmap). portmap must be
+ started by root before any other RPC network services are
+ used. SEE BELOW FOR BUGFIX TO 4.3BSD COMPILER.
+
+ man/ Manual pages for RPC library, rpcgen, and utilities.
+
+ rpc/ The RPC and XDR library. SEE BELOW
+ FOR BUGFIX TO 4.2BSD COMPILER.
+
+ rpcgen/ The RPC Language compiler (for .x files)
+
+ rpcsvc/ Service definition files for various services and the
+ server and client code for the Remote Status service.
+
+ secure_rpc/ The files in this directory are used to build a version of
+ the RPC library with DES Authentication. See the README
+ file in that directory for more details.
+
+BUILD INSTRUCTIONS
+
+Makefiles can be found in all directories except for man. The
+Makefile in the top directory will cause these others to be invoked
+(except for in the doc, man and demo directories), in turn building the
+entire release.
+
+WARNING! THE DEFAULT INSTALLATION PROCEDURES WILL INSTALL FILES
+IN /usr/include, /usr/lib, /usr/bin and /etc.
+
+The master RPC include file, rpc/rpc.h, is used by all programs and
+routines that use RPC. It includes other RPC and system include files
+needed by the RPC system. PLEASE NOTE: If your system has NFS, it
+may have been based on Sun's NFS Source. The include files installed
+by this package may duplicate include files you will find on your NFS
+system. The RPCSRC 4.0 include files are upwardly compatible to all
+NFS Source include files as of the date of this distribution (not
+including any new definitions or declarations added by your system
+vendor). HOWEVER: Please read the comments towards the end of
+rpc/rpc.h regarding rpc/netdb.h. You may need to uncomment the
+inclusion of that file if the structures it defines are already
+defined by your system's include files.
+
+After making any compiler fixes that are needed (see below), at
+the top directory, type:
+
+ make install
+
+For all installations, the Makefile macro DESTDIR is prepended to the
+installation path. It is defined to be null in the Makefiles, so
+installations are relative to root. (You will probably need root
+privileges for installing the files under the default path.) To
+install the files under some other tree (e.g., /usr/local), use the
+command:
+
+ make install DESTDIR=/usr/local
+
+This will place the include files in /usr/local/usr/include, the RPC
+library in /usr/local/usr/lib, rpcgen in /usr/local/usr/bin, and the
+utilities in /usr/local/etc. You'll have to edit the Makefiles or
+install the files by hand if you want to do anything other than this
+kind of relocation of the installation tree.
+
+The RPC library will be built and installed first. By default it is
+installed in /usr/lib as "librpclib.a". The directory
+/usr/include/rpc will also be created, and several header files will
+be installed there. ALL RPC SERVICES INCLUDE THESE HEADER FILES.
+
+The programs in etc/ link in routines from librpclib.a. If you change
+where it is installed, be sure to edit etc/'s Makefile to reflect this.
+These programs are installed in /etc. PORTMAP MUST BE RUNNING ON
+YOUR SYSTEM BEFORE YOU START ANY OTHER RPC SERVICE.
+
+rpcgen is installed in /usr/bin. This program is required to build
+the demonstration services in demo and the rstat client and server in
+rpcsvc/.
+
+The rpcsvc/ directory will install its files in the directory
+/usr/include/rpcsvc. The Remote Status service (rstat_svc) will be
+compiled and installed in /etc. If you wish to make this service
+available, you should either start this service when needed or have
+it started at boot time by invoking it in your /etc/rc.local script.
+(Be sure that portmap is started first!) Sun has modified its
+version of inetd to automatically start RPC services. (Use "make
+LIB=" when building rstat on a Sun Workstation.) The Remote Status
+client (rstat) will be installed in /usr/bin. This program queries
+the rstat_svc on a remote host and prints a system status summary
+similar to the one printed by "uptime".
+
+The documentation is not built during the "make install" command.
+Typing "make" in the doc directory will cause all of the manuals to
+be formatted using nroff into a single file. We have had a report
+that certain "troff" equivalents have trouble processing the full
+manual. If you have trouble, try building the manuals individually
+(see the Makefile).
+
+The demonstration services in the demo directory are not built by the
+top-level "make install" command. To build these, cd to the demo
+directory and enter "make". The three services will be built.
+RPCGEN MUST BE INSTALLED in a path that make can find. To run the
+services, start the portmap program as root and invoke the service
+(you probably will want to put it in the background). rpcinfo can be
+used to check that the service succeeded in getting registered with
+portmap, and to ping the service (see rpcinfo's man page). You can
+then use the corresponding client program to exercise the service.
+To build these services on a Sun workstation, you must prevent the
+Makefile from trying to link the RPC library (as these routines are
+already a part of Sun's libc). Use: "make LIB=".
+
+BUGFIX FOR 4.3BSD COMPILER
+
+The use of a 'void *' declaration for one of the arguments in
+the reply_proc() procedure in etc/rpcinfo.c will trigger a bug
+in the 4.3BSD compiler. The bug is fixed by the following change to
+the compiler file mip/manifest.h:
+
+*** manifest.h.r1.1 Thu Apr 30 13:52:25 1987
+--- manifest.h.r1.2 Mon Nov 23 18:58:17 1987
+***************
+*** 21,27 ****
+ /*
+ * Bogus type values
+ */
+! #define TNULL PTR /* pointer to UNDEF */
+ #define TVOID FTN /* function returning UNDEF (for void) */
+
+ /*
+--- 21,27 ----
+ /*
+ * Bogus type values
+ */
+! #define TNULL INCREF(MOETY) /* pointer to MOETY -- impossible type */
+ #define TVOID FTN /* function returning UNDEF (for void) */
+
+ /*
+
+If you cannot fix your compiler, change the declaration in reply_proc()
+from 'void *' to 'char *'.
+
+BUGFIX FOR 4.2BSD COMPILER
+
+Unpatched 4.2BSD compilers complain about valid C. You can make old
+compilers happy by changing some voids to ints. However, the fix to
+the 4.2 VAX compiler is as follows (to mip/trees.c):
+
+*** trees.c.r1.1 Mon May 11 13:47:58 1987
+--- trees.c.r1.2 Wed Jul 2 18:28:52 1986
+***************
+*** 1247,1253 ****
+ if(o==CAST && mt1==0)return(TYPL+TYMATCH);
+ if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
+ else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );
+! else if( mt12 == 0 ) break;
+ else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN );
+ else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
+ break;
+--- 1261,1269 ----
+ if(o==CAST && mt1==0)return(TYPL+TYMATCH);
+ if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
+ else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );
+! /* if right is TVOID and looks like a CALL, is not ok */
+! else if (mt2 == 0 && (p->in.right->in.op == CALL || p->in.right->in.op == UNARY CALL))
+! break;
+ else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN );
+ else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
+ break;
+
+WHAT'S NEW IN THIS RELEASE: RPCSRC 4.0
+
+The previous release was RPCSRC 3.9. As with all previous releases,
+this release is based directly on files from Sun Microsystem's
+implementation.
+
+Upgrade from RPCSRC 3.9
+
+1) RPCSRC 4.0 upgrades RPCSRC 3.9. Improvements from SunOS 4.0 have
+ been integrated into this release.
+
+Secure RPC (in the secure_rpc/ directory)
+
+2) DES Authentication routines and programs are provided.
+3) A new manual, "Secure NFS" is provided, which describes Secure RPC
+ and Secure NFS.
+4) Skeleton routines and manual pages are provided which describe the
+ DES encryption procedures required by Secure RPC. HOWEVER, NO DES
+ ROUTINE IS PROVIDED.
+
+New Functionality
+
+5) rpcinfo can now be used to de-register services from the portmapper
+ which may have terminated abnormally.
+6) A new client, rstat, is provided which queries the rstat_svc and
+ prints a status line similar to the one displayed by "uptime".
diff --git a/lib/libc/rpc/auth_des.c b/lib/libc/rpc/auth_des.c
new file mode 100644
index 0000000..51cfb1f
--- /dev/null
+++ b/lib/libc/rpc/auth_des.c
@@ -0,0 +1,554 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+/*
+ * auth_des.c, client-side implementation of DES authentication
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/cdefs.h>
+#include <rpc/des_crypt.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_des.h>
+#include <netinet/in.h> /* XXX: just to get htonl() and ntohl() */
+#include <sys/socket.h>
+#undef NIS
+#include <rpcsvc/nis.h>
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/* from: static char sccsid[] = "@(#)auth_des.c 2.2 88/07/29 4.0 RPCSRC; from 1.9 88/02/08 SMI"; */
+static const char rcsid[] = "$FreeBSD$";
+#endif
+
+extern bool_t __rpc_get_time_offset __P(( struct timeval *, nis_server *,
+ char *, char **, struct sockaddr_in * ));
+extern int rtime __P(( struct sockaddr_in *, struct timeval *, struct timeval *));
+extern bool_t xdr_authdes_cred __P(( XDR *, struct authdes_cred * ));
+extern bool_t xdr_authdes_verf __P(( XDR *, struct authdes_verf * ));
+
+#define MILLION 1000000L
+#define RTIME_TIMEOUT 5 /* seconds to wait for sync */
+
+#define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private
+#define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type))
+#define FREE(ptr, size) mem_free((char *)(ptr), (int) size)
+#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
+
+#define debug(msg) /*printf("%s\n", msg) */
+
+/*
+ * DES authenticator operations vector
+ */
+static void authdes_nextverf();
+static bool_t authdes_marshal();
+static bool_t authdes_validate();
+static bool_t authdes_refresh();
+static void authdes_destroy();
+static struct auth_ops authdes_ops = {
+ authdes_nextverf,
+ authdes_marshal,
+ authdes_validate,
+ authdes_refresh,
+ authdes_destroy
+};
+#ifdef foo
+static bool_t synchronize __P(( struct sockaddr *, struct timeval *));
+#endif
+/*
+ * This struct is pointed to by the ah_private field of an "AUTH *"
+ */
+struct ad_private {
+ char *ad_fullname; /* client's full name */
+ u_int ad_fullnamelen; /* length of name, rounded up */
+ char *ad_servername; /* server's full name */
+ u_int ad_servernamelen; /* length of name, rounded up */
+ u_int ad_window; /* client specified window */
+ bool_t ad_dosync; /* synchronize? */
+ struct sockaddr ad_syncaddr; /* remote host to synch with */
+ char *ad_timehost; /* remote host to synch with */
+ struct timeval ad_timediff; /* server's time - client's time */
+ u_long ad_nickname; /* server's nickname for client */
+ struct authdes_cred ad_cred; /* storage for credential */
+ struct authdes_verf ad_verf; /* storage for verifier */
+ struct timeval ad_timestamp; /* timestamp sent */
+ des_block ad_xkey; /* encrypted conversation key */
+ u_char ad_pkey[1024]; /* Server's actual public key */
+ char *ad_netid; /* Timehost netid */
+ char *ad_uaddr; /* Timehost uaddr */
+ nis_server *ad_nis_srvr; /* NIS+ server struct */
+};
+
+
+/*
+ * Create the client des authentication object
+ */
+AUTH *
+authdes_create(servername, window, syncaddr, ckey)
+ char *servername; /* network name of server */
+ u_int window; /* time to live */
+ struct sockaddr *syncaddr; /* optional addr of host to sync with */
+ des_block *ckey; /* optional conversation key to use*/
+{
+
+ AUTH *auth;
+ struct ad_private *ad;
+ char namebuf[MAXNETNAMELEN+1];
+ u_char pkey_data[1024];
+
+ if (!getpublickey(servername, pkey_data))
+ return(NULL);
+
+ /*
+ * Allocate everything now
+ */
+ auth = ALLOC(AUTH);
+ ad = ALLOC(struct ad_private);
+ (void) getnetname(namebuf);
+
+ ad->ad_fullnamelen = RNDUP(strlen(namebuf));
+ ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1);
+
+ ad->ad_servernamelen = strlen(servername);
+ ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1);
+
+ if (auth == NULL || ad == NULL || ad->ad_fullname == NULL ||
+ ad->ad_servername == NULL) {
+ debug("authdes_create: out of memory");
+ goto failed;
+ }
+
+ /*
+ * Set up private data
+ */
+ bcopy(namebuf, ad->ad_fullname, ad->ad_fullnamelen + 1);
+ bcopy(servername, ad->ad_servername, ad->ad_servernamelen + 1);
+ bcopy(pkey_data, ad->ad_pkey, strlen(pkey_data) + 1);
+ if (syncaddr != NULL) {
+ ad->ad_syncaddr = *syncaddr;
+ ad->ad_dosync = TRUE;
+ } else {
+ ad->ad_dosync = FALSE;
+ }
+ ad->ad_window = window;
+ if (ckey == NULL) {
+ if (key_gendes(&auth->ah_key) < 0) {
+ debug("authdes_create: unable to gen conversation key");
+ return (NULL);
+ }
+ } else {
+ auth->ah_key = *ckey;
+ }
+
+ /*
+ * Set up auth handle
+ */
+ auth->ah_cred.oa_flavor = AUTH_DES;
+ auth->ah_verf.oa_flavor = AUTH_DES;
+ auth->ah_ops = &authdes_ops;
+ auth->ah_private = (caddr_t)ad;
+
+ if (!authdes_refresh(auth)) {
+ goto failed;
+ }
+ return (auth);
+
+failed:
+ if (auth != NULL)
+ FREE(auth, sizeof(AUTH));
+ if (ad != NULL)
+ FREE(ad, sizeof(struct ad_private));
+ if (ad->ad_fullname != NULL)
+ FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
+ if (ad->ad_servername != NULL)
+ FREE(ad->ad_servername, ad->ad_servernamelen + 1);
+ return (NULL);
+}
+
+/*
+ * Slightly modified version of authdes_create which takes the public key
+ * of the server principal as an argument. This spares us a call to
+ * getpublickey() which in the nameserver context can cause a deadlock.
+ */
+AUTH *
+authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
+ char *servername; /* network name of server */
+ netobj *pkey; /* public key of server */
+ u_int window; /* time to live */
+ char *timehost; /* optional hostname to sync with */
+ des_block *ckey; /* optional conversation key to use */
+ nis_server *srvr; /* optional NIS+ server struct */
+{
+ AUTH *auth;
+ struct ad_private *ad;
+ char namebuf[MAXNETNAMELEN+1];
+
+ /*
+ * Allocate everything now
+ */
+ auth = ALLOC(AUTH);
+ if (auth == NULL) {
+ debug("authdes_pk_create: out of memory");
+ return (NULL);
+ }
+ ad = ALLOC(struct ad_private);
+ if (ad == NULL) {
+ debug("authdes_pk_create: out of memory");
+ goto failed;
+ }
+ ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */
+ ad->ad_timehost = NULL;
+ ad->ad_netid = NULL;
+ ad->ad_uaddr = NULL;
+ ad->ad_nis_srvr = NULL;
+ ad->ad_timediff.tv_sec = 0;
+ ad->ad_timediff.tv_usec = 0;
+ memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len);
+ if (!getnetname(namebuf))
+ goto failed;
+ ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf));
+ ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1);
+ ad->ad_servernamelen = strlen(servername);
+ ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1);
+
+ if (ad->ad_fullname == NULL || ad->ad_servername == NULL) {
+ debug("authdes_pk_create: out of memory");
+ goto failed;
+ }
+ if (timehost != NULL) {
+ ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1);
+ if (ad->ad_timehost == NULL) {
+ debug("authdes_pk_create: out of memory");
+ goto failed;
+ }
+ memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1);
+ ad->ad_dosync = TRUE;
+ } else if (srvr != NULL) {
+ ad->ad_nis_srvr = srvr; /* transient */
+ ad->ad_dosync = TRUE;
+ } else {
+ ad->ad_dosync = FALSE;
+ }
+ memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1);
+ memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1);
+ ad->ad_window = window;
+ if (ckey == NULL) {
+ if (key_gendes(&auth->ah_key) < 0) {
+ debug("authdes_pk_create: unable to gen conversation key");
+ goto failed;
+ }
+ } else {
+ auth->ah_key = *ckey;
+ }
+
+ /*
+ * Set up auth handle
+ */
+ auth->ah_cred.oa_flavor = AUTH_DES;
+ auth->ah_verf.oa_flavor = AUTH_DES;
+ auth->ah_ops = &authdes_ops;
+ auth->ah_private = (caddr_t)ad;
+
+ if (!authdes_refresh(auth)) {
+ goto failed;
+ }
+ ad->ad_nis_srvr = NULL; /* not needed any longer */
+ return (auth);
+
+failed:
+ if (auth)
+ FREE(auth, sizeof (AUTH));
+ if (ad) {
+ if (ad->ad_fullname)
+ FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
+ if (ad->ad_servername)
+ FREE(ad->ad_servername, ad->ad_servernamelen + 1);
+ if (ad->ad_timehost)
+ FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1);
+ if (ad->ad_netid)
+ free(ad->ad_netid);
+ if (ad->ad_uaddr)
+ free(ad->ad_uaddr);
+ FREE(ad, sizeof (struct ad_private));
+ }
+ return (NULL);
+}
+/*
+ * Implement the five authentication operations
+ */
+
+
+/*
+ * 1. Next Verifier
+ */
+/*ARGSUSED*/
+static void
+authdes_nextverf(auth)
+ AUTH *auth;
+{
+ /* what the heck am I supposed to do??? */
+}
+
+
+
+/*
+ * 2. Marshal
+ */
+static bool_t
+authdes_marshal(auth, xdrs)
+ AUTH *auth;
+ XDR *xdrs;
+{
+ struct ad_private *ad = AUTH_PRIVATE(auth);
+ struct authdes_cred *cred = &ad->ad_cred;
+ struct authdes_verf *verf = &ad->ad_verf;
+ des_block cryptbuf[2];
+ des_block ivec;
+ int status;
+ long len;
+ int32_t *ixdr;
+
+ /*
+ * Figure out the "time", accounting for any time difference
+ * with the server if necessary.
+ */
+ (void) gettimeofday(&ad->ad_timestamp, (struct timezone *)NULL);
+ ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec;
+ ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec;
+ if (ad->ad_timestamp.tv_usec >= MILLION) {
+ ad->ad_timestamp.tv_usec -= MILLION;
+ ad->ad_timestamp.tv_sec += 1;
+ }
+
+ /*
+ * XDR the timestamp and possibly some other things, then
+ * encrypt them.
+ */
+ ixdr = (int32_t *)cryptbuf;
+ IXDR_PUT_LONG(ixdr, ad->ad_timestamp.tv_sec);
+ IXDR_PUT_LONG(ixdr, ad->ad_timestamp.tv_usec);
+ if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
+ IXDR_PUT_U_LONG(ixdr, ad->ad_window);
+ IXDR_PUT_U_LONG(ixdr, ad->ad_window - 1);
+ ivec.key.high = ivec.key.low = 0;
+ status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf,
+ 2*sizeof(des_block), DES_ENCRYPT | DES_HW, (char *)&ivec);
+ } else {
+ status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf,
+ sizeof(des_block), DES_ENCRYPT | DES_HW);
+ }
+ if (DES_FAILED(status)) {
+ debug("authdes_marshal: DES encryption failure");
+ return (FALSE);
+ }
+ ad->ad_verf.adv_xtimestamp = cryptbuf[0];
+ if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
+ ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high;
+ ad->ad_verf.adv_winverf = cryptbuf[1].key.low;
+ } else {
+ ad->ad_cred.adc_nickname = ad->ad_nickname;
+ ad->ad_verf.adv_winverf = 0;
+ }
+
+ /*
+ * Serialize the credential and verifier into opaque
+ * authentication data.
+ */
+ if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
+ len = ((1 + 1 + 2 + 1)*BYTES_PER_XDR_UNIT + ad->ad_fullnamelen);
+ } else {
+ len = (1 + 1)*BYTES_PER_XDR_UNIT;
+ }
+
+ if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) {
+ IXDR_PUT_LONG(ixdr, AUTH_DES);
+ IXDR_PUT_LONG(ixdr, len);
+ } else {
+ ATTEMPT(xdr_putlong(xdrs, (long *)&auth->ah_cred.oa_flavor));
+ ATTEMPT(xdr_putlong(xdrs, &len));
+ }
+ ATTEMPT(xdr_authdes_cred(xdrs, cred));
+
+ len = (2 + 1)*BYTES_PER_XDR_UNIT;
+ if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) {
+ IXDR_PUT_LONG(ixdr, AUTH_DES);
+ IXDR_PUT_LONG(ixdr, len);
+ } else {
+ ATTEMPT(xdr_putlong(xdrs, (long *)&auth->ah_verf.oa_flavor));
+ ATTEMPT(xdr_putlong(xdrs, &len));
+ }
+ ATTEMPT(xdr_authdes_verf(xdrs, verf));
+ return (TRUE);
+}
+
+
+/*
+ * 3. Validate
+ */
+static bool_t
+authdes_validate(auth, rverf)
+ AUTH *auth;
+ struct opaque_auth *rverf;
+{
+ struct ad_private *ad = AUTH_PRIVATE(auth);
+ struct authdes_verf verf;
+ int status;
+ register u_long *ixdr;
+
+ if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) {
+ return (FALSE);
+ }
+ ixdr = (u_long *)rverf->oa_base;
+ verf.adv_xtimestamp.key.high = (u_long)*ixdr++;
+ verf.adv_xtimestamp.key.low = (u_long)*ixdr++;
+ verf.adv_int_u = (u_long)*ixdr++; /* nickname not XDR'd ! */
+
+ /*
+ * Decrypt the timestamp
+ */
+ status = ecb_crypt((char *)&auth->ah_key, (char *)&verf.adv_xtimestamp,
+ sizeof(des_block), DES_DECRYPT | DES_HW);
+
+ if (DES_FAILED(status)) {
+ debug("authdes_validate: DES decryption failure");
+ return (FALSE);
+ }
+
+ /*
+ * xdr the decrypted timestamp
+ */
+ ixdr = (u_long *)verf.adv_xtimestamp.c;
+ verf.adv_timestamp.tv_sec = IXDR_GET_LONG(ixdr) + 1;
+ verf.adv_timestamp.tv_usec = IXDR_GET_LONG(ixdr);
+
+ /*
+ * validate
+ */
+ if (bcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp,
+ sizeof(struct timeval)) != 0) {
+ debug("authdes_validate: verifier mismatch\n");
+ return (FALSE);
+ }
+
+ /*
+ * We have a nickname now, let's use it
+ */
+ ad->ad_nickname = verf.adv_nickname;
+ ad->ad_cred.adc_namekind = ADN_NICKNAME;
+ return (TRUE);
+}
+
+/*
+ * 4. Refresh
+ */
+static bool_t
+authdes_refresh(auth)
+ AUTH *auth;
+{
+ struct ad_private *ad = AUTH_PRIVATE(auth);
+ struct authdes_cred *cred = &ad->ad_cred;
+ netobj pkey;
+
+ if (ad->ad_dosync &&
+#ifdef old
+ !synchronize(&ad->ad_syncaddr, &ad->ad_timediff)) {
+#else
+ !__rpc_get_time_offset(&ad->ad_timediff,ad->ad_nis_srvr,
+ ad->ad_timehost, &(ad->ad_uaddr),
+ (struct sockaddr_in *)&(ad->ad_syncaddr))) {
+#endif
+ /*
+ * Hope the clocks are synced!
+ */
+ ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0;
+ ad->ad_dosync = 0;
+ debug("authdes_refresh: unable to synchronize with server");
+ }
+ ad->ad_xkey = auth->ah_key;
+ pkey.n_bytes = (char *)(ad->ad_pkey);
+ pkey.n_len = strlen((char *)ad->ad_pkey) + 1;
+ if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) {
+ debug("authdes_create: unable to encrypt conversation key");
+ return (FALSE);
+ }
+ cred->adc_fullname.key = ad->ad_xkey;
+ cred->adc_namekind = ADN_FULLNAME;
+ cred->adc_fullname.name = ad->ad_fullname;
+ return (TRUE);
+}
+
+
+/*
+ * 5. Destroy
+ */
+static void
+authdes_destroy(auth)
+ AUTH *auth;
+{
+ struct ad_private *ad = AUTH_PRIVATE(auth);
+
+ FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
+ FREE(ad->ad_servername, ad->ad_servernamelen + 1);
+ FREE(ad, sizeof(struct ad_private));
+ FREE(auth, sizeof(AUTH));
+}
+
+
+#ifdef old
+/*
+ * Synchronize with the server at the given address, that is,
+ * adjust timep to reflect the delta between our clocks
+ */
+static bool_t
+synchronize(syncaddr, timep)
+ struct sockaddr *syncaddr;
+ struct timeval *timep;
+{
+ struct timeval mytime;
+ struct timeval timeout;
+
+ timeout.tv_sec = RTIME_TIMEOUT;
+ timeout.tv_usec = 0;
+ if (rtime((struct sockaddr_in *)syncaddr, timep, NULL /*&timeout*/) < 0) {
+ return (FALSE);
+ }
+ (void) gettimeofday(&mytime, (struct timezone *)NULL);
+ timep->tv_sec -= mytime.tv_sec;
+ if (mytime.tv_usec > timep->tv_usec) {
+ timep->tv_sec -= 1;
+ timep->tv_usec += MILLION;
+ }
+ timep->tv_usec -= mytime.tv_usec;
+ return (TRUE);
+}
+#endif
diff --git a/lib/libc/rpc/auth_none.c b/lib/libc/rpc/auth_none.c
new file mode 100644
index 0000000..9649df3
--- /dev/null
+++ b/lib/libc/rpc/auth_none.c
@@ -0,0 +1,136 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * auth_none.c
+ * Creates a client authentication handle for passing "null"
+ * credentials and verifiers to remote systems.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdlib.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#define MAX_MARSHEL_SIZE 20
+
+/*
+ * Authenticator operations routines
+ */
+static void authnone_verf();
+static void authnone_destroy();
+static bool_t authnone_marshal();
+static bool_t authnone_validate();
+static bool_t authnone_refresh();
+
+static struct auth_ops ops = {
+ authnone_verf,
+ authnone_marshal,
+ authnone_validate,
+ authnone_refresh,
+ authnone_destroy
+};
+
+static struct authnone_private {
+ AUTH no_client;
+ char marshalled_client[MAX_MARSHEL_SIZE];
+ u_int mcnt;
+} *authnone_private;
+
+AUTH *
+authnone_create()
+{
+ register struct authnone_private *ap = authnone_private;
+ XDR xdr_stream;
+ register XDR *xdrs;
+
+ if (ap == 0) {
+ ap = (struct authnone_private *)calloc(1, sizeof (*ap));
+ if (ap == 0)
+ return (0);
+ authnone_private = ap;
+ }
+ if (!ap->mcnt) {
+ ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
+ ap->no_client.ah_ops = &ops;
+ xdrs = &xdr_stream;
+ xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHEL_SIZE,
+ XDR_ENCODE);
+ (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
+ (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
+ ap->mcnt = XDR_GETPOS(xdrs);
+ XDR_DESTROY(xdrs);
+ }
+ return (&ap->no_client);
+}
+
+/*ARGSUSED*/
+static bool_t
+authnone_marshal(client, xdrs)
+ AUTH *client;
+ XDR *xdrs;
+{
+ register struct authnone_private *ap = authnone_private;
+
+ if (ap == 0)
+ return (0);
+ return ((*xdrs->x_ops->x_putbytes)(xdrs,
+ ap->marshalled_client, ap->mcnt));
+}
+
+static void
+authnone_verf()
+{
+}
+
+static bool_t
+authnone_validate()
+{
+
+ return (TRUE);
+}
+
+static bool_t
+authnone_refresh()
+{
+
+ return (FALSE);
+}
+
+static void
+authnone_destroy()
+{
+}
diff --git a/lib/libc/rpc/auth_time.c b/lib/libc/rpc/auth_time.c
new file mode 100644
index 0000000..3128e6d
--- /dev/null
+++ b/lib/libc/rpc/auth_time.c
@@ -0,0 +1,501 @@
+#pragma ident "@(#)auth_time.c 1.4 92/11/10 SMI"
+
+/*
+ * auth_time.c
+ *
+ * This module contains the private function __rpc_get_time_offset()
+ * which will return the difference in seconds between the local system's
+ * notion of time and a remote server's notion of time. This must be
+ * possible without calling any functions that may invoke the name
+ * service. (netdir_getbyxxx, getXbyY, etc). The function is used in the
+ * synchronize call of the authdes code to synchronize clocks between
+ * NIS+ clients and their servers.
+ *
+ * Note to minimize the amount of duplicate code, portions of the
+ * synchronize() function were folded into this code, and the synchronize
+ * call becomes simply a wrapper around this function. Further, if this
+ * function is called with a timehost it *DOES* recurse to the name
+ * server so don't use it in that mode if you are doing name service code.
+ *
+ * Copyright (c) 1992 Sun Microsystems Inc.
+ * All rights reserved.
+ *
+ * Side effects :
+ * When called a client handle to a RPCBIND process is created
+ * and destroyed. Two strings "netid" and "uaddr" are malloc'd
+ * and returned. The SIGALRM processing is modified only if
+ * needed to deal with TCP connections.
+ *
+ * NOTE: This code has had the crap beaten out it in order to convert
+ * it from TI-RPC back to TD-RPC for use on FreeBSD.
+ */
+#include <stdio.h>
+#include <syslog.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <sys/signal.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <rpc/rpc.h>
+#include <rpc/rpc_com.h>
+#undef NIS
+#include <rpcsvc/nis.h>
+
+/*
+ * FreeBSD currently uses RPC 4.0, which uses portmap rather than
+ * rpcbind. Consequently, we need to fake up these values here.
+ * Luckily, the RPCB_GETTIME procedure uses only base XDR data types
+ * so we don't need anything besides these magic numbers.
+ */
+#define RPCBPROG (u_long)100000
+#define RPCBVERS (u_long)3
+#define RPCBPROC_GETTIME (u_long)6
+
+#ifdef TESTING
+#define msg(x) printf("ERROR: %s\n", x)
+/* #define msg(x) syslog(LOG_ERR, "%s", x) */
+#else
+#define msg(x)
+#endif
+
+static int saw_alarm = 0;
+
+static void
+alarm_hndler(s)
+ int s;
+{
+ saw_alarm = 1;
+ return;
+}
+
+/*
+ * The internet time server defines the epoch to be Jan 1, 1900
+ * whereas UNIX defines it to be Jan 1, 1970. To adjust the result
+ * from internet time-service time, into UNIX time we subtract the
+ * following offset :
+ */
+#define NYEARS (1970 - 1900)
+#define TOFFSET ((u_long)60*60*24*(365*NYEARS + (NYEARS/4)))
+
+
+/*
+ * Stolen from rpc.nisd:
+ * Turn a 'universal address' into a struct sockaddr_in.
+ * Bletch.
+ */
+static int uaddr_to_sockaddr(uaddr, sin)
+#ifdef foo
+ endpoint *endpt;
+#endif
+ char *uaddr;
+ struct sockaddr_in *sin;
+{
+ unsigned char p_bytes[2];
+ int i;
+ unsigned long a[6];
+
+ i = sscanf(uaddr, "%lu.%lu.%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2],
+ &a[3], &a[4], &a[5]);
+
+ if (i < 6)
+ return(1);
+
+ for (i = 0; i < 4; i++)
+ sin->sin_addr.s_addr |= (a[i] & 0x000000FF) << (8 * i);
+
+ p_bytes[0] = (unsigned char)a[4] & 0x000000FF;
+ p_bytes[1] = (unsigned char)a[5] & 0x000000FF;
+
+ sin->sin_family = AF_INET; /* always */
+ bcopy((char *)&p_bytes, (char *)&sin->sin_port, 2);
+
+ return (0);
+}
+
+/*
+ * free_eps()
+ *
+ * Free the strings that were strduped into the eps structure.
+ */
+static void
+free_eps(eps, num)
+ endpoint eps[];
+ int num;
+{
+ int i;
+
+ for (i = 0; i < num; i++) {
+ free(eps[i].uaddr);
+ free(eps[i].proto);
+ free(eps[i].family);
+ }
+ return;
+}
+
+/*
+ * get_server()
+ *
+ * This function constructs a nis_server structure description for the
+ * indicated hostname.
+ *
+ * NOTE: There is a chance we may end up recursing here due to the
+ * fact that gethostbyname() could do an NIS search. Ideally, the
+ * NIS+ server will call __rpc_get_time_offset() with the nis_server
+ * structure already populated.
+ */
+static nis_server *
+get_server(sin, host, srv, eps, maxep)
+ struct sockaddr_in *sin;
+ char *host; /* name of the time host */
+ nis_server *srv; /* nis_server struct to use. */
+ endpoint eps[]; /* array of endpoints */
+ int maxep; /* max array size */
+{
+ char hname[256];
+ int num_ep = 0, i;
+ struct hostent *he;
+ struct hostent dummy;
+ char *ptr[2];
+
+ if (host == NULL && sin == NULL)
+ return (NULL);
+
+ if (sin == NULL) {
+ he = gethostbyname(host);
+ if (he == NULL)
+ return(NULL);
+ } else {
+ he = &dummy;
+ ptr[0] = (char *)&sin->sin_addr.s_addr;
+ ptr[1] = NULL;
+ dummy.h_addr_list = ptr;
+ }
+
+ /*
+ * This is lame. We go around once for TCP, then again
+ * for UDP.
+ */
+ for (i = 0; (he->h_addr_list[i] != NULL) && (num_ep < maxep);
+ i++, num_ep++) {
+ struct in_addr *a;
+
+ a = (struct in_addr *)he->h_addr_list[i];
+ snprintf(hname, sizeof(hname), "%s.0.111", inet_ntoa(*a));
+ eps[num_ep].uaddr = strdup(hname);
+ eps[num_ep].family = strdup("inet");
+ eps[num_ep].proto = strdup("tcp");
+ }
+
+ for (i = 0; (he->h_addr_list[i] != NULL) && (num_ep < maxep);
+ i++, num_ep++) {
+ struct in_addr *a;
+
+ a = (struct in_addr *)he->h_addr_list[i];
+ snprintf(hname, sizeof(hname), "%s.0.111", inet_ntoa(*a));
+ eps[num_ep].uaddr = strdup(hname);
+ eps[num_ep].family = strdup("inet");
+ eps[num_ep].proto = strdup("udp");
+ }
+
+ srv->name = (nis_name) host;
+ srv->ep.ep_len = num_ep;
+ srv->ep.ep_val = eps;
+ srv->key_type = NIS_PK_NONE;
+ srv->pkey.n_bytes = NULL;
+ srv->pkey.n_len = 0;
+ return (srv);
+}
+
+/*
+ * __rpc_get_time_offset()
+ *
+ * This function uses a nis_server structure to contact the a remote
+ * machine (as named in that structure) and returns the offset in time
+ * between that machine and this one. This offset is returned in seconds
+ * and may be positive or negative.
+ *
+ * The first time through, a lot of fiddling is done with the netconfig
+ * stuff to find a suitable transport. The function is very aggressive
+ * about choosing UDP or at worst TCP if it can. This is because
+ * those transports support both the RCPBIND call and the internet
+ * time service.
+ *
+ * Once through, *uaddr is set to the universal address of
+ * the machine and *netid is set to the local netid for the transport
+ * that uaddr goes with. On the second call, the netconfig stuff
+ * is skipped and the uaddr/netid pair are used to fetch the netconfig
+ * structure and to then contact the machine for the time.
+ *
+ * td = "server" - "client"
+ */
+int
+__rpc_get_time_offset(td, srv, thost, uaddr, netid)
+ struct timeval *td; /* Time difference */
+ nis_server *srv; /* NIS Server description */
+ char *thost; /* if no server, this is the timehost */
+ char **uaddr; /* known universal address */
+ struct sockaddr_in *netid; /* known network identifier */
+{
+ CLIENT *clnt; /* Client handle */
+ endpoint *ep, /* useful endpoints */
+ *useep = NULL; /* endpoint of xp */
+ char *useua = NULL; /* uaddr of selected xp */
+ int epl, i; /* counters */
+ enum clnt_stat status; /* result of clnt_call */
+ u_long thetime, delta;
+ int needfree = 0;
+ struct timeval tv;
+ int time_valid;
+ int udp_ep = -1, tcp_ep = -1;
+ int a1, a2, a3, a4;
+ char ut[64], ipuaddr[64];
+ endpoint teps[32];
+ nis_server tsrv;
+ void (*oldsig)() = NULL; /* old alarm handler */
+ struct sockaddr_in sin;
+ int s = RPC_ANYSOCK, len;
+ int type = 0;
+
+ td->tv_sec = 0;
+ td->tv_usec = 0;
+
+ /*
+ * First check to see if we need to find and address for this
+ * server.
+ */
+ if (*uaddr == NULL) {
+ if ((srv != NULL) && (thost != NULL)) {
+ msg("both timehost and srv pointer used!");
+ return (0);
+ }
+ if (! srv) {
+ srv = get_server(netid, thost, &tsrv, teps, 32);
+ if (srv == NULL) {
+ msg("unable to contruct server data.");
+ return (0);
+ }
+ needfree = 1; /* need to free data in endpoints */
+ }
+
+ ep = srv->ep.ep_val;
+ epl = srv->ep.ep_len;
+
+ /* Identify the TCP and UDP endpoints */
+ for (i = 0;
+ (i < epl) && ((udp_ep == -1) || (tcp_ep == -1)); i++) {
+ if (strcasecmp(ep[i].proto, "udp") == 0)
+ udp_ep = i;
+ if (strcasecmp(ep[i].proto, "tcp") == 0)
+ tcp_ep = i;
+ }
+
+ /* Check to see if it is UDP or TCP */
+ if (tcp_ep > -1) {
+ useep = &ep[tcp_ep];
+ useua = ep[tcp_ep].uaddr;
+ type = SOCK_STREAM;
+ } else if (udp_ep > -1) {
+ useep = &ep[udp_ep];
+ useua = ep[udp_ep].uaddr;
+ type = SOCK_DGRAM;
+ }
+
+ if (useep == NULL) {
+ msg("no acceptable transport endpoints.");
+ if (needfree)
+ free_eps(teps, tsrv.ep.ep_len);
+ return (0);
+ }
+ }
+
+ /*
+ * Create a sockaddr from the uaddr.
+ */
+ if (*uaddr != NULL)
+ useua = *uaddr;
+
+ /* Fixup test for NIS+ */
+ sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
+ sprintf(ipuaddr, "%d.%d.%d.%d.0.111", a1, a2, a3, a4);
+ useua = &ipuaddr[0];
+
+ bzero((char *)&sin, sizeof(sin));
+ if (uaddr_to_sockaddr(useua, &sin)) {
+ msg("unable to translate uaddr to sockaddr.");
+ if (needfree)
+ free_eps(teps, tsrv.ep.ep_len);
+ return (0);
+ }
+
+ /*
+ * Create the client handle to rpcbind. Note we always try
+ * version 3 since that is the earliest version that supports
+ * the RPCB_GETTIME call. Also it is the version that comes
+ * standard with SVR4. Since most everyone supports TCP/IP
+ * we could consider trying the rtime call first.
+ */
+ clnt = clnttcp_create(&sin, RPCBPROG, RPCBVERS, &s, 0, 0);
+ if (clnt == NULL) {
+ msg("unable to create client handle to rpcbind.");
+ if (needfree)
+ free_eps(teps, tsrv.ep.ep_len);
+ return (0);
+ }
+
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+ time_valid = 0;
+ status = clnt_call(clnt, RPCBPROC_GETTIME, xdr_void, NULL,
+ xdr_u_long, (char *)&thetime, tv);
+ /*
+ * The only error we check for is anything but success. In
+ * fact we could have seen PROGMISMATCH if talking to a 4.1
+ * machine (pmap v2) or TIMEDOUT if the net was busy.
+ */
+ if (status == RPC_SUCCESS)
+ time_valid = 1;
+ else {
+ int save;
+
+ /* Blow away possible stale CLNT handle. */
+ if (clnt != NULL) {
+ clnt_destroy(clnt);
+ clnt = NULL;
+ }
+
+ /*
+ * Convert PMAP address into timeservice address
+ * We take advantage of the fact that we "know" what
+ * the universal address looks like for inet transports.
+ *
+ * We also know that the internet timeservice is always
+ * listening on port 37.
+ */
+ sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
+ sprintf(ut, "%d.%d.%d.%d.0.37", a1, a2, a3, a4);
+
+ if (uaddr_to_sockaddr(ut, &sin)) {
+ msg("cannot convert timeservice uaddr to sockaddr.");
+ goto error;
+ }
+
+ s = socket(AF_INET, type, 0);
+ if (s == -1) {
+ msg("unable to open fd to network.");
+ goto error;
+ }
+
+ /*
+ * Now depending on whether or not we're talking to
+ * UDP we set a timeout or not.
+ */
+ if (type == SOCK_DGRAM) {
+ struct timeval timeout = { 20, 0 };
+ struct sockaddr_in from;
+ fd_set readfds;
+ int res;
+
+ if (sendto(s, &thetime, sizeof(thetime), 0,
+ (struct sockaddr *)&sin, sizeof(sin)) == -1) {
+ msg("udp : sendto failed.");
+ goto error;
+ }
+ do {
+ FD_ZERO(&readfds);
+ FD_SET(s, &readfds);
+ res = select(_rpc_dtablesize(), &readfds,
+ (fd_set *)NULL, (fd_set *)NULL, &timeout);
+ } while (res < 0 && errno == EINTR);
+ if (res <= 0)
+ goto error;
+ len = sizeof(from);
+ res = recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
+ (struct sockaddr *)&from, &len);
+ if (res == -1) {
+ msg("recvfrom failed on udp transport.");
+ goto error;
+ }
+ time_valid = 1;
+ } else {
+ int res;
+
+ oldsig = (void (*)())signal(SIGALRM, alarm_hndler);
+ saw_alarm = 0; /* global tracking the alarm */
+ alarm(20); /* only wait 20 seconds */
+ res = connect(s, (struct sockaddr *)&sin, sizeof(sin));
+ if (res == -1) {
+ msg("failed to connect to tcp endpoint.");
+ goto error;
+ }
+ if (saw_alarm) {
+ msg("alarm caught it, must be unreachable.");
+ goto error;
+ }
+ res = read(s, (char *)&thetime, sizeof(thetime));
+ if (res != sizeof(thetime)) {
+ if (saw_alarm)
+ msg("timed out TCP call.");
+ else
+ msg("wrong size of results returned");
+
+ goto error;
+ }
+ time_valid = 1;
+ }
+ save = errno;
+ (void) close(s);
+ errno = save;
+ s = RPC_ANYSOCK;
+
+ if (time_valid) {
+ thetime = ntohl(thetime);
+ thetime = thetime - TOFFSET; /* adjust to UNIX time */
+ } else
+ thetime = 0;
+ }
+
+ gettimeofday(&tv, 0);
+
+error:
+ /*
+ * clean up our allocated data structures.
+ */
+
+ if (s != RPC_ANYSOCK)
+ (void) close(s);
+
+ if (clnt != NULL)
+ clnt_destroy(clnt);
+
+ alarm(0); /* reset that alarm if its outstanding */
+ if (oldsig) {
+ signal(SIGALRM, oldsig);
+ }
+
+ /*
+ * note, don't free uaddr strings until after we've made a
+ * copy of them.
+ */
+ if (time_valid) {
+ if (*uaddr == NULL)
+ *uaddr = strdup(useua);
+
+ /* Round to the nearest second */
+ tv.tv_sec += (tv.tv_sec > 500000) ? 1 : 0;
+ delta = (thetime > tv.tv_sec) ? thetime - tv.tv_sec :
+ tv.tv_sec - thetime;
+ td->tv_sec = (thetime < tv.tv_sec) ? - delta : delta;
+ td->tv_usec = 0;
+ } else {
+ msg("unable to get the server's time.");
+ }
+
+ if (needfree)
+ free_eps(teps, tsrv.ep.ep_len);
+
+ return (time_valid);
+}
diff --git a/lib/libc/rpc/auth_unix.c b/lib/libc/rpc/auth_unix.c
new file mode 100644
index 0000000..f2a0918
--- /dev/null
+++ b/lib/libc/rpc/auth_unix.c
@@ -0,0 +1,349 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * auth_unix.c, Implements UNIX style authentication parameters.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The system is very weak. The client uses no encryption for it's
+ * credentials and only sends null verifiers. The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+/*
+ * Unix authenticator operations vector
+ */
+static void authunix_nextverf();
+static bool_t authunix_marshal();
+static bool_t authunix_validate();
+static bool_t authunix_refresh();
+static void authunix_destroy();
+
+static struct auth_ops auth_unix_ops = {
+ authunix_nextverf,
+ authunix_marshal,
+ authunix_validate,
+ authunix_refresh,
+ authunix_destroy
+};
+
+/*
+ * This struct is pointed to by the ah_private field of an auth_handle.
+ */
+struct audata {
+ struct opaque_auth au_origcred; /* original credentials */
+ struct opaque_auth au_shcred; /* short hand cred */
+ u_long au_shfaults; /* short hand cache faults */
+ char au_marshed[MAX_AUTH_BYTES];
+ u_int au_mpos; /* xdr pos at end of marshed */
+};
+#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
+
+static void marshal_new_auth();
+
+/*
+ * This goop is here because some servers refuse to accept a
+ * credential with more than some number (usually 8) supplementary
+ * groups. Blargh!
+ */
+static int authunix_maxgrouplist = 0;
+
+void
+set_rpc_maxgrouplist(int num)
+{
+ authunix_maxgrouplist = num;
+}
+
+/*
+ * Create a unix style authenticator.
+ * Returns an auth handle with the given stuff in it.
+ */
+AUTH *
+authunix_create(machname, uid, gid, len, aup_gids)
+ char *machname;
+ int uid;
+ int gid;
+ register int len;
+ int *aup_gids;
+{
+ struct authunix_parms aup;
+ char mymem[MAX_AUTH_BYTES];
+ struct timeval now;
+ XDR xdrs;
+ register AUTH *auth;
+ register struct audata *au;
+
+ /*
+ * Allocate and set up auth handle
+ */
+ auth = (AUTH *)mem_alloc(sizeof(*auth));
+#ifndef KERNEL
+ if (auth == NULL) {
+ (void)fprintf(stderr, "authunix_create: out of memory\n");
+ return (NULL);
+ }
+#endif
+ au = (struct audata *)mem_alloc(sizeof(*au));
+#ifndef KERNEL
+ if (au == NULL) {
+ (void)fprintf(stderr, "authunix_create: out of memory\n");
+ return (NULL);
+ }
+#endif
+ auth->ah_ops = &auth_unix_ops;
+ auth->ah_private = (caddr_t)au;
+ auth->ah_verf = au->au_shcred = _null_auth;
+ au->au_shfaults = 0;
+
+ /*
+ * fill in param struct from the given params
+ */
+ (void)gettimeofday(&now, (struct timezone *)0);
+ aup.aup_time = now.tv_sec;
+ aup.aup_machname = machname;
+ aup.aup_uid = uid;
+ aup.aup_gid = gid;
+ /* GW: continuation of max group list hack */
+ if(authunix_maxgrouplist != 0) {
+ aup.aup_len = ((len < authunix_maxgrouplist) ? len
+ : authunix_maxgrouplist);
+ } else {
+ aup.aup_len = (u_int)len;
+ }
+ aup.aup_gids = aup_gids;
+
+ /*
+ * Serialize the parameters into origcred
+ */
+ xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
+ if (! xdr_authunix_parms(&xdrs, &aup))
+ abort();
+ au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
+ au->au_origcred.oa_flavor = AUTH_UNIX;
+#ifdef KERNEL
+ au->au_origcred.oa_base = mem_alloc((u_int) len);
+#else
+ if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
+ (void)fprintf(stderr, "authunix_create: out of memory\n");
+ return (NULL);
+ }
+#endif
+ memcpy(au->au_origcred.oa_base, mymem, (u_int)len);
+
+ /*
+ * set auth handle to reflect new cred.
+ */
+ auth->ah_cred = au->au_origcred;
+ marshal_new_auth(auth);
+ return (auth);
+}
+
+/*
+ * Returns an auth handle with parameters determined by doing lots of
+ * syscalls.
+ */
+AUTH *
+authunix_create_default()
+{
+ register int len;
+ char machname[MAX_MACHINE_NAME + 1];
+ register int uid;
+ register int gid;
+ int gids[NGRPS];
+ int i;
+ gid_t real_gids[NGROUPS];
+
+ if (gethostname(machname, MAX_MACHINE_NAME) == -1)
+ abort();
+ machname[MAX_MACHINE_NAME] = 0;
+ uid = (int)geteuid();
+ gid = (int)getegid();
+ if ((len = getgroups(NGROUPS, real_gids)) < 0)
+ abort();
+ if(len > NGRPS) len = NGRPS; /* GW: turn `gid_t's into `int's */
+ for(i = 0; i < len; i++) {
+ gids[i] = (int)real_gids[i];
+ }
+ return (authunix_create(machname, uid, gid, len, gids));
+}
+
+/*
+ * authunix operations
+ */
+
+static void
+authunix_nextverf(auth)
+ AUTH *auth;
+{
+ /* no action necessary */
+}
+
+static bool_t
+authunix_marshal(auth, xdrs)
+ AUTH *auth;
+ XDR *xdrs;
+{
+ register struct audata *au = AUTH_PRIVATE(auth);
+
+ return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
+}
+
+static bool_t
+authunix_validate(auth, verf)
+ register AUTH *auth;
+ struct opaque_auth verf;
+{
+ register struct audata *au;
+ XDR xdrs;
+
+ if (verf.oa_flavor == AUTH_SHORT) {
+ au = AUTH_PRIVATE(auth);
+ xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE);
+
+ if (au->au_shcred.oa_base != NULL) {
+ mem_free(au->au_shcred.oa_base,
+ au->au_shcred.oa_length);
+ au->au_shcred.oa_base = NULL;
+ }
+ if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
+ auth->ah_cred = au->au_shcred;
+ } else {
+ xdrs.x_op = XDR_FREE;
+ (void)xdr_opaque_auth(&xdrs, &au->au_shcred);
+ au->au_shcred.oa_base = NULL;
+ auth->ah_cred = au->au_origcred;
+ }
+ marshal_new_auth(auth);
+ }
+ return (TRUE);
+}
+
+static bool_t
+authunix_refresh(auth)
+ register AUTH *auth;
+{
+ register struct audata *au = AUTH_PRIVATE(auth);
+ struct authunix_parms aup;
+ struct timeval now;
+ XDR xdrs;
+ register int stat;
+
+ if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
+ /* there is no hope. Punt */
+ return (FALSE);
+ }
+ au->au_shfaults ++;
+
+ /* first deserialize the creds back into a struct authunix_parms */
+ aup.aup_machname = NULL;
+ aup.aup_gids = (int *)NULL;
+ xdrmem_create(&xdrs, au->au_origcred.oa_base,
+ au->au_origcred.oa_length, XDR_DECODE);
+ stat = xdr_authunix_parms(&xdrs, &aup);
+ if (! stat)
+ goto done;
+
+ /* update the time and serialize in place */
+ (void)gettimeofday(&now, (struct timezone *)0);
+ aup.aup_time = now.tv_sec;
+ xdrs.x_op = XDR_ENCODE;
+ XDR_SETPOS(&xdrs, 0);
+ stat = xdr_authunix_parms(&xdrs, &aup);
+ if (! stat)
+ goto done;
+ auth->ah_cred = au->au_origcred;
+ marshal_new_auth(auth);
+done:
+ /* free the struct authunix_parms created by deserializing */
+ xdrs.x_op = XDR_FREE;
+ (void)xdr_authunix_parms(&xdrs, &aup);
+ XDR_DESTROY(&xdrs);
+ return (stat);
+}
+
+static void
+authunix_destroy(auth)
+ register AUTH *auth;
+{
+ register struct audata *au = AUTH_PRIVATE(auth);
+
+ mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
+
+ if (au->au_shcred.oa_base != NULL)
+ mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);
+
+ mem_free(auth->ah_private, sizeof(struct audata));
+
+ if (auth->ah_verf.oa_base != NULL)
+ mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
+
+ mem_free((caddr_t)auth, sizeof(*auth));
+}
+
+/*
+ * Marshals (pre-serializes) an auth struct.
+ * sets private data, au_marshed and au_mpos
+ */
+static void
+marshal_new_auth(auth)
+ register AUTH *auth;
+{
+ XDR xdr_stream;
+ register XDR *xdrs = &xdr_stream;
+ register struct audata *au = AUTH_PRIVATE(auth);
+
+ xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
+ if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
+ (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {
+ perror("auth_none.c - Fatal marshalling problem");
+ } else {
+ au->au_mpos = XDR_GETPOS(xdrs);
+ }
+ XDR_DESTROY(xdrs);
+}
diff --git a/lib/libc/rpc/authdes_prot.c b/lib/libc/rpc/authdes_prot.c
new file mode 100644
index 0000000..14679c0
--- /dev/null
+++ b/lib/libc/rpc/authdes_prot.c
@@ -0,0 +1,82 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)authdes_prot.c 2.1 88/07/29 4.0 RPCSRC; from 1.6 88/02/08 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+
+/*
+ * authdes_prot.c, XDR routines for DES authentication
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_des.h>
+
+#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
+
+bool_t
+xdr_authdes_cred(xdrs, cred)
+ XDR *xdrs;
+ struct authdes_cred *cred;
+{
+ /*
+ * Unrolled xdr
+ */
+ ATTEMPT(xdr_enum(xdrs, (enum_t *)&cred->adc_namekind));
+ switch (cred->adc_namekind) {
+ case ADN_FULLNAME:
+ ATTEMPT(xdr_string(xdrs, &cred->adc_fullname.name, MAXNETNAMELEN));
+ ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.key, sizeof(des_block)));
+ ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.window, sizeof(cred->adc_fullname.window)));
+ return (TRUE);
+ case ADN_NICKNAME:
+ ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_nickname, sizeof(cred->adc_nickname)));
+ return (TRUE);
+ default:
+ return (FALSE);
+ }
+}
+
+
+bool_t
+xdr_authdes_verf(xdrs, verf)
+ register XDR *xdrs;
+ register struct authdes_verf *verf;
+{
+ /*
+ * Unrolled xdr
+ */
+ ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_xtimestamp, sizeof(des_block)));
+ ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_int_u, sizeof(verf->adv_int_u)));
+ return (TRUE);
+}
diff --git a/lib/libc/rpc/authunix_prot.c b/lib/libc/rpc/authunix_prot.c
new file mode 100644
index 0000000..54f23fc
--- /dev/null
+++ b/lib/libc/rpc/authunix_prot.c
@@ -0,0 +1,68 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * authunix_prot.c
+ * XDR for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+/*
+ * XDR for unix authentication parameters.
+ */
+bool_t
+xdr_authunix_parms(xdrs, p)
+ register XDR *xdrs;
+ register struct authunix_parms *p;
+{
+
+ if (xdr_u_long(xdrs, &(p->aup_time))
+ && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME)
+ && xdr_int(xdrs, &(p->aup_uid))
+ && xdr_int(xdrs, &(p->aup_gid))
+ && xdr_array(xdrs, (caddr_t *)&(p->aup_gids),
+ &(p->aup_len), NGRPS, sizeof(int), xdr_int) ) {
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
diff --git a/lib/libc/rpc/bindresvport.3 b/lib/libc/rpc/bindresvport.3
new file mode 100644
index 0000000..9abdcb9
--- /dev/null
+++ b/lib/libc/rpc/bindresvport.3
@@ -0,0 +1,32 @@
+.\" @(#)bindresvport.3n 2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI
+.\" $FreeBSD$
+.\"
+.Dd November 22, 1987
+.Dt BINDRESVPORT 3
+.Os
+.Sh NAME
+.Nm bindresvport
+.Ndbind a socket to a privileged IP port
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <netinet/in.h>
+.Ft int
+.Fn bindresvport "int sd" "struct sockaddr_in **sin"
+.Sh DESCRIPTION
+.Nm Bindresvport
+is used to bind a socket descriptor to a privileged
+.Tn IP
+port, that is, a
+port number in the range 0-1023.
+The routine returns 0 if it is successful,
+otherwise -1 is returned and
+.Va errno
+set to reflect the cause of the error.
+.Pp
+Only root can bind to a privileged port; this call will fail for any
+other users.
+.Pp
+If the value of sin->sin_port is non-zero
+.Fn bindresvport
+will attempt to use that specific port. If it fails, it chooses another
+privileged port automatically.
diff --git a/lib/libc/rpc/bindresvport.c b/lib/libc/rpc/bindresvport.c
new file mode 100644
index 0000000..1a62efa
--- /dev/null
+++ b/lib/libc/rpc/bindresvport.c
@@ -0,0 +1,107 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)bindresvport.c 1.8 88/02/08 SMI";*/
+/*static char *sccsid = "from: @(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";*/
+/*from: OpenBSD: bindresvport.c,v 1.7 1996/07/30 16:25:47 downsj Exp */
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * Copyright (c) 1987 by Sun Microsystems, Inc.
+ *
+ * Portions Copyright(C) 1996, Jason Downs. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <string.h>
+
+/*
+ * Bind a socket to a privileged IP port
+ */
+int
+bindresvport(sd, sin)
+ int sd;
+ struct sockaddr_in *sin;
+{
+ int on, old, error;
+ struct sockaddr_in myaddr;
+ int sinlen = sizeof(struct sockaddr_in);
+
+ if (sin == (struct sockaddr_in *)0) {
+ sin = &myaddr;
+ memset(sin, 0, sinlen);
+ sin->sin_len = sinlen;
+ sin->sin_family = AF_INET;
+ } else if (sin->sin_family != AF_INET) {
+ errno = EPFNOSUPPORT;
+ return (-1);
+ }
+
+ if (sin->sin_port == 0) {
+ int oldlen = sizeof(old);
+ error = getsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
+ &old, &oldlen);
+ if (error < 0)
+ return(error);
+
+ on = IP_PORTRANGE_LOW;
+ error = setsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
+ &on, sizeof(on));
+ if (error < 0)
+ return(error);
+ }
+
+ error = bind(sd, (struct sockaddr *)sin, sinlen);
+
+ if (sin->sin_port == 0) {
+ int saved_errno = errno;
+
+ if (error) {
+ if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
+ &old, sizeof(old)) < 0)
+ errno = saved_errno;
+ return (error);
+ }
+
+ if (sin != &myaddr) {
+ /* Hmm, what did the kernel assign... */
+ if (getsockname(sd, (struct sockaddr *)sin,
+ &sinlen) < 0)
+ errno = saved_errno;
+ return (error);
+ }
+ }
+ return (error);
+}
diff --git a/lib/libc/rpc/clnt_generic.c b/lib/libc/rpc/clnt_generic.c
new file mode 100644
index 0000000..5e3cb7b
--- /dev/null
+++ b/lib/libc/rpc/clnt_generic.c
@@ -0,0 +1,137 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";*/
+/*static char *sccsid = "from: @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <netdb.h>
+#include <string.h>
+
+/*
+ * Generic client creation: takes (hostname, program-number, protocol) and
+ * returns client handle. Default options are set, which the user can
+ * change using the rpc equivalent of ioctl()'s.
+ */
+CLIENT *
+clnt_create(hostname, prog, vers, proto)
+ char *hostname;
+ u_long prog;
+ u_long vers;
+ char *proto;
+{
+ struct hostent *h;
+ struct protoent *p;
+ struct sockaddr_in sin;
+ struct sockaddr_un sun;
+ int sock;
+ static struct timeval tv;
+ CLIENT *client;
+
+ if (!strcmp(proto, "unix")) {
+ bzero((char *)&sun, sizeof(sun));
+ sun.sun_family = AF_UNIX;
+ strcpy(sun.sun_path, hostname);
+ sun.sun_len = sizeof(sun.sun_len) + sizeof(sun.sun_family) +
+ strlen(sun.sun_path) + 1;
+ sock = RPC_ANYSOCK;
+ client = clntunix_create(&sun, prog, vers, &sock, 0, 0);
+ if (client == NULL)
+ return(NULL);
+ tv.tv_sec = 25;
+ tv.tv_usec = 0;
+ clnt_control(client, CLSET_TIMEOUT, &tv);
+ return(client);
+ }
+
+ h = gethostbyname(hostname);
+ if (h == NULL) {
+ rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
+ return (NULL);
+ }
+ if (h->h_addrtype != AF_INET) {
+ /*
+ * Only support INET for now
+ */
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(struct sockaddr_in);
+ sin.sin_family = h->h_addrtype;
+ sin.sin_port = 0;
+ memcpy((char*)&sin.sin_addr, h->h_addr, h->h_length);
+ p = getprotobyname(proto);
+ if (p == NULL) {
+ rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
+ rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
+ return (NULL);
+ }
+ sock = RPC_ANYSOCK;
+ switch (p->p_proto) {
+ case IPPROTO_UDP:
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+ client = clntudp_create(&sin, prog, vers, tv, &sock);
+ if (client == NULL) {
+ return (NULL);
+ }
+#if 0 /* XXX do we need this? */
+ tv.tv_sec = 25;
+ tv.tv_usec = 0;
+ clnt_control(client, CLSET_TIMEOUT, &tv);
+#endif
+ break;
+ case IPPROTO_TCP:
+ client = clnttcp_create(&sin, prog, vers, &sock, 0, 0);
+ if (client == NULL) {
+ return (NULL);
+ }
+#if 0 /* XXX do we need this? */
+ tv.tv_sec = 25;
+ tv.tv_usec = 0;
+ clnt_control(client, CLSET_TIMEOUT, &tv);
+#endif
+ break;
+ default:
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
+ return (NULL);
+ }
+ return (client);
+}
diff --git a/lib/libc/rpc/clnt_perror.c b/lib/libc/rpc/clnt_perror.c
new file mode 100644
index 0000000..53c2c88
--- /dev/null
+++ b/lib/libc/rpc/clnt_perror.c
@@ -0,0 +1,254 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * clnt_perror.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <rpc/clnt.h>
+
+static char *auth_errmsg();
+#define CLNT_PERROR_BUFLEN 256
+
+static char *buf;
+
+static char *
+_buf()
+{
+
+ if (buf == 0)
+ buf = (char *)malloc(CLNT_PERROR_BUFLEN);
+ return (buf);
+}
+
+/*
+ * Print reply error info
+ */
+char *
+clnt_sperror(rpch, s)
+ CLIENT *rpch;
+ char *s;
+{
+ struct rpc_err e;
+ char *err;
+ char *str = _buf();
+ char *strstart = str;
+
+ if (str == 0)
+ return (0);
+ CLNT_GETERR(rpch, &e);
+
+ (void) sprintf(str, "%s: %s", s, clnt_sperrno(e.re_status));
+ str += strlen(str);
+
+ switch (e.re_status) {
+ case RPC_SUCCESS:
+ case RPC_CANTENCODEARGS:
+ case RPC_CANTDECODERES:
+ case RPC_TIMEDOUT:
+ case RPC_PROGUNAVAIL:
+ case RPC_PROCUNAVAIL:
+ case RPC_CANTDECODEARGS:
+ case RPC_SYSTEMERROR:
+ case RPC_UNKNOWNHOST:
+ case RPC_UNKNOWNPROTO:
+ case RPC_PMAPFAILURE:
+ case RPC_PROGNOTREGISTERED:
+ case RPC_FAILED:
+ break;
+
+ case RPC_CANTSEND:
+ case RPC_CANTRECV:
+ (void) snprintf(str, CLNT_PERROR_BUFLEN - (str - strstart),
+ "; errno = %s\n", strerror(e.re_errno));
+ break;
+
+ case RPC_VERSMISMATCH:
+ (void) sprintf(str,
+ "; low version = %lu, high version = %lu\n",
+ (u_long)e.re_vers.low, (u_long)e.re_vers.high);
+ break;
+
+ case RPC_AUTHERROR:
+ err = auth_errmsg(e.re_why);
+ (void) sprintf(str,"; why = ");
+ str += strlen(str);
+ if (err != NULL) {
+ (void) sprintf(str, "%s\n",err);
+ } else {
+ (void) sprintf(str,
+ "(unknown authentication error - %d)\n",
+ (int) e.re_why);
+ }
+ break;
+
+ case RPC_PROGVERSMISMATCH:
+ (void) sprintf(str,
+ "; low version = %lu, high version = %lu\n",
+ (u_long)e.re_vers.low, (u_long)e.re_vers.high);
+ break;
+
+ default: /* unknown */
+ (void) sprintf(str,
+ "; s1 = %lu, s2 = %lu\n",
+ (long)e.re_lb.s1, (long)e.re_lb.s2);
+ break;
+ }
+ strstart[CLNT_PERROR_BUFLEN-2] = '\n';
+ strstart[CLNT_PERROR_BUFLEN-1] = '\0';
+ return(strstart) ;
+}
+
+void
+clnt_perror(rpch, s)
+ CLIENT *rpch;
+ char *s;
+{
+ (void) fprintf(stderr,"%s\n",clnt_sperror(rpch,s));
+}
+
+
+static const char *const rpc_errlist[] = {
+ "RPC: Success", /* 0 - RPC_SUCCESS */
+ "RPC: Can't encode arguments", /* 1 - RPC_CANTENCODEARGS */
+ "RPC: Can't decode result", /* 2 - RPC_CANTDECODERES */
+ "RPC: Unable to send", /* 3 - RPC_CANTSEND */
+ "RPC: Unable to receive", /* 4 - RPC_CANTRECV */
+ "RPC: Timed out", /* 5 - RPC_TIMEDOUT */
+ "RPC: Incompatible versions of RPC", /* 6 - RPC_VERSMISMATCH */
+ "RPC: Authentication error", /* 7 - RPC_AUTHERROR */
+ "RPC: Program unavailable", /* 8 - RPC_PROGUNAVAIL */
+ "RPC: Program/version mismatch", /* 9 - RPC_PROGVERSMISMATCH */
+ "RPC: Procedure unavailable", /* 10 - RPC_PROCUNAVAIL */
+ "RPC: Server can't decode arguments", /* 11 - RPC_CANTDECODEARGS */
+ "RPC: Remote system error", /* 12 - RPC_SYSTEMERROR */
+ "RPC: Unknown host", /* 13 - RPC_UNKNOWNHOST */
+ "RPC: Port mapper failure", /* 14 - RPC_PMAPFAILURE */
+ "RPC: Program not registered", /* 15 - RPC_PROGNOTREGISTERED */
+ "RPC: Failed (unspecified error)", /* 16 - RPC_FAILED */
+ "RPC: Unknown protocol" /* 17 - RPC_UNKNOWNPROTO */
+};
+
+
+/*
+ * This interface for use by clntrpc
+ */
+char *
+clnt_sperrno(stat)
+ enum clnt_stat stat;
+{
+ unsigned int errnum = stat;
+
+ if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0])))
+ return (char *)rpc_errlist[errnum];
+
+ return ("RPC: (unknown error code)");
+}
+
+void
+clnt_perrno(num)
+ enum clnt_stat num;
+{
+ (void) fprintf(stderr,"%s\n",clnt_sperrno(num));
+}
+
+
+char *
+clnt_spcreateerror(s)
+ char *s;
+{
+ char *str = _buf();
+
+ if (str == 0)
+ return(0);
+ switch (rpc_createerr.cf_stat) {
+ case RPC_PMAPFAILURE:
+ (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
+ clnt_sperrno(rpc_createerr.cf_stat),
+ clnt_sperrno(rpc_createerr.cf_error.re_status));
+ break;
+
+ case RPC_SYSTEMERROR:
+ (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
+ clnt_sperrno(rpc_createerr.cf_stat),
+ strerror(rpc_createerr.cf_error.re_errno));
+ break;
+ default:
+ (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s\n", s,
+ clnt_sperrno(rpc_createerr.cf_stat));
+ break;
+ }
+ str[CLNT_PERROR_BUFLEN-2] = '\n';
+ str[CLNT_PERROR_BUFLEN-1] = '\0';
+ return (str);
+}
+
+void
+clnt_pcreateerror(s)
+ char *s;
+{
+ (void) fprintf(stderr,"%s\n",clnt_spcreateerror(s));
+}
+
+static const char *const auth_errlist[] = {
+ "Authentication OK", /* 0 - AUTH_OK */
+ "Invalid client credential", /* 1 - AUTH_BADCRED */
+ "Server rejected credential", /* 2 - AUTH_REJECTEDCRED */
+ "Invalid client verifier", /* 3 - AUTH_BADVERF */
+ "Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
+ "Client credential too weak", /* 5 - AUTH_TOOWEAK */
+ "Invalid server verifier", /* 6 - AUTH_INVALIDRESP */
+ "Failed (unspecified error)" /* 7 - AUTH_FAILED */
+};
+
+static char *
+auth_errmsg(stat)
+ enum auth_stat stat;
+{
+ unsigned int errnum = stat;
+
+ if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0])))
+ return (char *)auth_errlist[errnum];
+
+ return(NULL);
+}
diff --git a/lib/libc/rpc/clnt_raw.c b/lib/libc/rpc/clnt_raw.c
new file mode 100644
index 0000000..6f228fe
--- /dev/null
+++ b/lib/libc/rpc/clnt_raw.c
@@ -0,0 +1,242 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * clnt_raw.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Memory based rpc for simple testing and timing.
+ * Interface to create an rpc client and server in the same process.
+ * This lets us similate rpc and get round trip overhead, without
+ * any interference from the kernal.
+ */
+
+#include <rpc/rpc.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define MCALL_MSG_SIZE 24
+
+/*
+ * This is the "network" we will be moving stuff over.
+ */
+static struct clntraw_private {
+ CLIENT client_object;
+ XDR xdr_stream;
+ char _raw_buf[UDPMSGSIZE];
+ char mashl_callmsg[MCALL_MSG_SIZE];
+ u_int mcnt;
+} *clntraw_private;
+
+static enum clnt_stat clntraw_call();
+static void clntraw_abort();
+static void clntraw_geterr();
+static bool_t clntraw_freeres();
+static bool_t clntraw_control();
+static void clntraw_destroy();
+
+static struct clnt_ops client_ops = {
+ clntraw_call,
+ clntraw_abort,
+ clntraw_geterr,
+ clntraw_freeres,
+ clntraw_destroy,
+ clntraw_control
+};
+
+void svc_getreq();
+
+/*
+ * Create a client handle for memory based rpc.
+ */
+CLIENT *
+clntraw_create(prog, vers)
+ u_long prog;
+ u_long vers;
+{
+ register struct clntraw_private *clp = clntraw_private;
+ struct rpc_msg call_msg;
+ XDR *xdrs = &clp->xdr_stream;
+ CLIENT *client = &clp->client_object;
+
+ if (clp == 0) {
+ clp = (struct clntraw_private *)calloc(1, sizeof (*clp));
+ if (clp == 0)
+ return (0);
+ clntraw_private = clp;
+ }
+ /*
+ * pre-serialize the static part of the call msg and stash it away
+ */
+ call_msg.rm_direction = CALL;
+ call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ call_msg.rm_call.cb_prog = prog;
+ call_msg.rm_call.cb_vers = vers;
+ xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
+ if (! xdr_callhdr(xdrs, &call_msg)) {
+ perror("clnt_raw.c - Fatal header serialization error.");
+ }
+ clp->mcnt = XDR_GETPOS(xdrs);
+ XDR_DESTROY(xdrs);
+
+ /*
+ * Set xdrmem for client/server shared buffer
+ */
+ xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
+
+ /*
+ * create client handle
+ */
+ client->cl_ops = &client_ops;
+ client->cl_auth = authnone_create();
+ return (client);
+}
+
+static enum clnt_stat
+clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
+ CLIENT *h;
+ u_long proc;
+ xdrproc_t xargs;
+ caddr_t argsp;
+ xdrproc_t xresults;
+ caddr_t resultsp;
+ struct timeval timeout;
+{
+ register struct clntraw_private *clp = clntraw_private;
+ register XDR *xdrs = &clp->xdr_stream;
+ struct rpc_msg msg;
+ enum clnt_stat status;
+ struct rpc_err error;
+
+ if (clp == 0)
+ return (RPC_FAILED);
+call_again:
+ /*
+ * send request
+ */
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, 0);
+ ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ;
+ if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) ||
+ (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+ (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+ (! (*xargs)(xdrs, argsp))) {
+ return (RPC_CANTENCODEARGS);
+ }
+ (void)XDR_GETPOS(xdrs); /* called just to cause overhead */
+
+ /*
+ * We have to call server input routine here because this is
+ * all going on in one process. Yuk.
+ */
+ svc_getreq(1);
+
+ /*
+ * get results
+ */
+ xdrs->x_op = XDR_DECODE;
+ XDR_SETPOS(xdrs, 0);
+ msg.acpted_rply.ar_verf = _null_auth;
+ msg.acpted_rply.ar_results.where = resultsp;
+ msg.acpted_rply.ar_results.proc = xresults;
+ if (! xdr_replymsg(xdrs, &msg))
+ return (RPC_CANTDECODERES);
+ _seterr_reply(&msg, &error);
+ status = error.re_status;
+
+ if (status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
+ status = RPC_AUTHERROR;
+ }
+ } /* end successful completion */
+ else {
+ if (AUTH_REFRESH(h->cl_auth))
+ goto call_again;
+ } /* end of unsuccessful completion */
+
+ if (status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
+ status = RPC_AUTHERROR;
+ }
+ if (msg.acpted_rply.ar_verf.oa_base != NULL) {
+ xdrs->x_op = XDR_FREE;
+ (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
+ }
+ }
+
+ return (status);
+}
+
+static void
+clntraw_geterr()
+{
+}
+
+
+static bool_t
+clntraw_freeres(cl, xdr_res, res_ptr)
+ CLIENT *cl;
+ xdrproc_t xdr_res;
+ caddr_t res_ptr;
+{
+ register struct clntraw_private *clp = clntraw_private;
+ register XDR *xdrs = &clp->xdr_stream;
+ bool_t rval;
+
+ if (clp == 0)
+ {
+ rval = (bool_t) RPC_FAILED;
+ return (rval);
+ }
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clntraw_abort()
+{
+}
+
+static bool_t
+clntraw_control()
+{
+ return (FALSE);
+}
+
+static void
+clntraw_destroy()
+{
+}
diff --git a/lib/libc/rpc/clnt_simple.c b/lib/libc/rpc/clnt_simple.c
new file mode 100644
index 0000000..dd935d3
--- /dev/null
+++ b/lib/libc/rpc/clnt_simple.c
@@ -0,0 +1,122 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * clnt_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+static struct callrpc_private {
+ CLIENT *client;
+ int socket;
+ int oldprognum, oldversnum, valid;
+ char *oldhost;
+} *callrpc_private;
+
+int
+callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
+ char *host;
+ int prognum, versnum, procnum;
+ xdrproc_t inproc, outproc;
+ char *in, *out;
+{
+ register struct callrpc_private *crp = callrpc_private;
+ struct sockaddr_in server_addr;
+ enum clnt_stat clnt_stat;
+ struct hostent *hp;
+ struct timeval timeout, tottimeout;
+
+ if (crp == 0) {
+ crp = (struct callrpc_private *)calloc(1, sizeof (*crp));
+ if (crp == 0)
+ return (0);
+ callrpc_private = crp;
+ }
+ if (crp->oldhost == NULL) {
+ crp->oldhost = malloc(MAXHOSTNAMELEN);
+ crp->oldhost[0] = 0;
+ crp->socket = RPC_ANYSOCK;
+ }
+ if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
+ && strcmp(crp->oldhost, host) == 0) {
+ /* reuse old client */
+ } else {
+ crp->valid = 0;
+ if (crp->socket != -1)
+ (void)close(crp->socket);
+ crp->socket = RPC_ANYSOCK;
+ if (crp->client) {
+ clnt_destroy(crp->client);
+ crp->client = NULL;
+ }
+ if ((hp = gethostbyname(host)) == NULL)
+ return ((int) RPC_UNKNOWNHOST);
+ timeout.tv_usec = 0;
+ timeout.tv_sec = 5;
+ memset(&server_addr, 0, sizeof(server_addr));
+ memcpy((char *)&server_addr.sin_addr, hp->h_addr, hp->h_length);
+ server_addr.sin_len = sizeof(struct sockaddr_in);
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_port = 0;
+ if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
+ (u_long)versnum, timeout, &crp->socket)) == NULL)
+ return ((int) rpc_createerr.cf_stat);
+ crp->valid = 1;
+ crp->oldprognum = prognum;
+ crp->oldversnum = versnum;
+ (void) strcpy(crp->oldhost, host);
+ }
+ tottimeout.tv_sec = 25;
+ tottimeout.tv_usec = 0;
+ clnt_stat = clnt_call(crp->client, procnum, inproc, in,
+ outproc, out, tottimeout);
+ /*
+ * if call failed, empty cache
+ */
+ if (clnt_stat != RPC_SUCCESS)
+ crp->valid = 0;
+ return ((int) clnt_stat);
+}
diff --git a/lib/libc/rpc/clnt_tcp.c b/lib/libc/rpc/clnt_tcp.c
new file mode 100644
index 0000000..ebbaddc
--- /dev/null
+++ b/lib/libc/rpc/clnt_tcp.c
@@ -0,0 +1,580 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * TCP based RPC supports 'batched calls'.
+ * A sequence of calls may be batched-up in a send buffer. The rpc call
+ * return immediately to the client even though the call was not necessarily
+ * sent. The batching occurs if the results' xdr routine is NULL (0) AND
+ * the rpc timeout value is zero (see clnt.h, rpc).
+ *
+ * Clients should NOT casually batch calls that in fact return results; that is,
+ * the server side should be aware that a call is batched and not produce any
+ * return message. Batched calls that produce many result messages can
+ * deadlock (netlock) the client and the server....
+ *
+ * Now go hang yourself.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+
+#define MCALL_MSG_SIZE 24
+
+static int readtcp();
+static int writetcp();
+
+static enum clnt_stat clnttcp_call();
+static void clnttcp_abort();
+static void clnttcp_geterr();
+static bool_t clnttcp_freeres();
+static bool_t clnttcp_control();
+static void clnttcp_destroy();
+
+static struct clnt_ops tcp_ops = {
+ clnttcp_call,
+ clnttcp_abort,
+ clnttcp_geterr,
+ clnttcp_freeres,
+ clnttcp_destroy,
+ clnttcp_control
+};
+
+struct ct_data {
+ int ct_sock;
+ bool_t ct_closeit;
+ struct timeval ct_wait;
+ bool_t ct_waitset; /* wait set by clnt_control? */
+ struct sockaddr_in ct_addr;
+ struct rpc_err ct_error;
+ char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */
+ u_int ct_mpos; /* pos after marshal */
+ XDR ct_xdrs;
+};
+
+/*
+ * Create a client handle for a tcp/ip connection.
+ * If *sockp<0, *sockp is set to a newly created TCP socket and it is
+ * connected to raddr. If *sockp non-negative then
+ * raddr is ignored. The rpc/tcp package does buffering
+ * similar to stdio, so the client must pick send and receive buffer sizes,];
+ * 0 => use the default.
+ * If raddr->sin_port is 0, then a binder on the remote machine is
+ * consulted for the right port number.
+ * NB: *sockp is copied into a private area.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is set null authentication. Caller may wish to set this
+ * something more useful.
+ */
+CLIENT *
+clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ struct sockaddr_in *raddr;
+ u_long prog;
+ u_long vers;
+ register int *sockp;
+ u_int sendsz;
+ u_int recvsz;
+{
+ CLIENT *h;
+ register struct ct_data *ct = NULL;
+ struct timeval now;
+ struct rpc_msg call_msg;
+ static u_int32_t disrupt;
+
+ if (disrupt == 0)
+ disrupt = (u_int32_t)(long)raddr;
+
+ h = (CLIENT *)mem_alloc(sizeof(*h));
+ if (h == NULL) {
+ (void)fprintf(stderr, "clnttcp_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ ct = (struct ct_data *)mem_alloc(sizeof(*ct));
+ if (ct == NULL) {
+ (void)fprintf(stderr, "clnttcp_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+
+ /*
+ * If no port number given ask the pmap for one
+ */
+ if (raddr->sin_port == 0) {
+ u_short port;
+ if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) {
+ mem_free((caddr_t)ct, sizeof(struct ct_data));
+ mem_free((caddr_t)h, sizeof(CLIENT));
+ return ((CLIENT *)NULL);
+ }
+ raddr->sin_port = htons(port);
+ }
+
+ /*
+ * If no socket given, open one
+ */
+ if (*sockp < 0) {
+ *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ (void)bindresvport(*sockp, (struct sockaddr_in *)0);
+ if ((*sockp < 0)
+ || (connect(*sockp, (struct sockaddr *)raddr,
+ sizeof(*raddr)) < 0)) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ if (*sockp != -1)
+ (void)close(*sockp);
+ goto fooy;
+ }
+ ct->ct_closeit = TRUE;
+ } else {
+ ct->ct_closeit = FALSE;
+ }
+
+ /*
+ * Set up private data struct
+ */
+ ct->ct_sock = *sockp;
+ ct->ct_wait.tv_usec = 0;
+ ct->ct_waitset = FALSE;
+ ct->ct_addr = *raddr;
+
+ /*
+ * Initialize call message
+ */
+ (void)gettimeofday(&now, (struct timezone *)0);
+ call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
+ call_msg.rm_direction = CALL;
+ call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ call_msg.rm_call.cb_prog = prog;
+ call_msg.rm_call.cb_vers = vers;
+
+ /*
+ * pre-serialize the static part of the call msg and stash it away
+ */
+ xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
+ XDR_ENCODE);
+ if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
+ if (ct->ct_closeit) {
+ (void)close(*sockp);
+ }
+ goto fooy;
+ }
+ ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
+ XDR_DESTROY(&(ct->ct_xdrs));
+
+ /*
+ * Create a client handle which uses xdrrec for serialization
+ * and authnone for authentication.
+ */
+ xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
+ (caddr_t)ct, readtcp, writetcp);
+ h->cl_ops = &tcp_ops;
+ h->cl_private = (caddr_t) ct;
+ h->cl_auth = authnone_create();
+ return (h);
+
+fooy:
+ /*
+ * Something goofed, free stuff and barf
+ */
+ if (ct)
+ mem_free((caddr_t)ct, sizeof(struct ct_data));
+ if (h)
+ mem_free((caddr_t)h, sizeof(CLIENT));
+ return ((CLIENT *)NULL);
+}
+
+static enum clnt_stat
+clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
+ register CLIENT *h;
+ u_long proc;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+ xdrproc_t xdr_results;
+ caddr_t results_ptr;
+ struct timeval timeout;
+{
+ register struct ct_data *ct = (struct ct_data *) h->cl_private;
+ register XDR *xdrs = &(ct->ct_xdrs);
+ struct rpc_msg reply_msg;
+ u_long x_id;
+ u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall); /* yuk */
+ register bool_t shipnow;
+ int refreshes = 2;
+
+ if (!ct->ct_waitset) {
+ ct->ct_wait = timeout;
+ }
+
+ shipnow =
+ (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
+ && timeout.tv_usec == 0) ? FALSE : TRUE;
+
+call_again:
+ xdrs->x_op = XDR_ENCODE;
+ ct->ct_error.re_status = RPC_SUCCESS;
+ x_id = ntohl(--(*msg_x_id));
+ if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
+ (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+ (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+ (! (*xdr_args)(xdrs, args_ptr))) {
+ if (ct->ct_error.re_status == RPC_SUCCESS)
+ ct->ct_error.re_status = RPC_CANTENCODEARGS;
+ (void)xdrrec_endofrecord(xdrs, TRUE);
+ return (ct->ct_error.re_status);
+ }
+ if (! xdrrec_endofrecord(xdrs, shipnow))
+ return (ct->ct_error.re_status = RPC_CANTSEND);
+ if (! shipnow)
+ return (RPC_SUCCESS);
+ /*
+ * Hack to provide rpc-based message passing
+ */
+ if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+ return(ct->ct_error.re_status = RPC_TIMEDOUT);
+ }
+
+
+ /*
+ * Keep receiving until we get a valid transaction id
+ */
+ xdrs->x_op = XDR_DECODE;
+ while (TRUE) {
+ reply_msg.acpted_rply.ar_verf = _null_auth;
+ reply_msg.acpted_rply.ar_results.where = NULL;
+ reply_msg.acpted_rply.ar_results.proc = xdr_void;
+ if (! xdrrec_skiprecord(xdrs))
+ return (ct->ct_error.re_status);
+ /* now decode and validate the response header */
+ if (! xdr_replymsg(xdrs, &reply_msg)) {
+ if (ct->ct_error.re_status == RPC_SUCCESS)
+ continue;
+ return (ct->ct_error.re_status);
+ }
+ if (reply_msg.rm_xid == x_id)
+ break;
+ }
+
+ /*
+ * process header
+ */
+ _seterr_reply(&reply_msg, &(ct->ct_error));
+ if (ct->ct_error.re_status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
+ ct->ct_error.re_status = RPC_AUTHERROR;
+ ct->ct_error.re_why = AUTH_INVALIDRESP;
+ } else if (! (*xdr_results)(xdrs, results_ptr)) {
+ if (ct->ct_error.re_status == RPC_SUCCESS)
+ ct->ct_error.re_status = RPC_CANTDECODERES;
+ }
+ /* free verifier ... */
+ if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+ xdrs->x_op = XDR_FREE;
+ (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
+ }
+ } /* end successful completion */
+ else {
+ /* maybe our credentials need to be refreshed ... */
+ if (refreshes-- && AUTH_REFRESH(h->cl_auth))
+ goto call_again;
+ } /* end of unsuccessful completion */
+ return (ct->ct_error.re_status);
+}
+
+static void
+clnttcp_geterr(h, errp)
+ CLIENT *h;
+ struct rpc_err *errp;
+{
+ register struct ct_data *ct =
+ (struct ct_data *) h->cl_private;
+
+ *errp = ct->ct_error;
+}
+
+static bool_t
+clnttcp_freeres(cl, xdr_res, res_ptr)
+ CLIENT *cl;
+ xdrproc_t xdr_res;
+ caddr_t res_ptr;
+{
+ register struct ct_data *ct = (struct ct_data *)cl->cl_private;
+ register XDR *xdrs = &(ct->ct_xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clnttcp_abort()
+{
+}
+
+
+static bool_t
+clnttcp_control(cl, request, info)
+ CLIENT *cl;
+ int request;
+ char *info;
+{
+ register struct ct_data *ct = (struct ct_data *)cl->cl_private;
+ register struct timeval *tv;
+ int len;
+
+ switch (request) {
+ case CLSET_FD_CLOSE:
+ ct->ct_closeit = TRUE;
+ break;
+ case CLSET_FD_NCLOSE:
+ ct->ct_closeit = FALSE;
+ break;
+ case CLSET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ tv = (struct timeval *)info;
+ ct->ct_wait.tv_sec = tv->tv_sec;
+ ct->ct_wait.tv_usec = tv->tv_usec;
+ ct->ct_waitset = TRUE;
+ break;
+ case CLGET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ *(struct timeval *)info = ct->ct_wait;
+ break;
+ case CLGET_SERVER_ADDR:
+ if (info == NULL)
+ return(FALSE);
+ *(struct sockaddr_in *)info = ct->ct_addr;
+ break;
+ case CLGET_FD:
+ if (info == NULL)
+ return(FALSE);
+ *(int *)info = ct->ct_sock;
+ break;
+ case CLGET_XID:
+ /*
+ * use the knowledge that xid is the
+ * first element in the call structure *.
+ * This will get the xid of the PREVIOUS call
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)ct->ct_mcall);
+ break;
+ case CLSET_XID:
+ /* This will set the xid of the NEXT call */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)ct->ct_mcall = htonl(*(u_long *)info - 1);
+ /* decrement by 1 as clnttcp_call() increments once */
+ case CLGET_VERS:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the version number field is the fifth field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
+ 4 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_VERS:
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_long *)info);
+ break;
+ case CLGET_PROG:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the program number field is the field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
+ 3 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_PROG:
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_long *)info);
+ break;
+ case CLGET_LOCAL_ADDR:
+ len = sizeof(struct sockaddr);
+ if (getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0)
+ return(FALSE);
+ break;
+ case CLGET_RETRY_TIMEOUT:
+ case CLSET_RETRY_TIMEOUT:
+ case CLGET_SVC_ADDR:
+ case CLSET_SVC_ADDR:
+ case CLSET_PUSH_TIMOD:
+ case CLSET_POP_TIMOD:
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+static void
+clnttcp_destroy(h)
+ CLIENT *h;
+{
+ register struct ct_data *ct =
+ (struct ct_data *) h->cl_private;
+
+ if (ct->ct_closeit) {
+ (void)close(ct->ct_sock);
+ }
+ XDR_DESTROY(&(ct->ct_xdrs));
+ mem_free((caddr_t)ct, sizeof(struct ct_data));
+ mem_free((caddr_t)h, sizeof(CLIENT));
+}
+
+/*
+ * Interface between xdr serializer and tcp connection.
+ * Behaves like the system calls, read & write, but keeps some error state
+ * around for the rpc level.
+ */
+static int
+readtcp(ct, buf, len)
+ register struct ct_data *ct;
+ caddr_t buf;
+ register int len;
+{
+ fd_set *fds, readfds;
+ struct timeval start, after, duration, delta, tmp, tv;
+ int r, save_errno;
+
+ if (len == 0)
+ return (0);
+
+ if (ct->ct_sock + 1 > FD_SETSIZE) {
+ int bytes = howmany(ct->ct_sock + 1, NFDBITS) * sizeof(fd_mask);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL)
+ return (-1);
+ memset(fds, 0, bytes);
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ gettimeofday(&start, NULL);
+ delta = ct->ct_wait;
+ while (TRUE) {
+ /* XXX we know the other bits are still clear */
+ FD_SET(ct->ct_sock, fds);
+ tv = delta; /* in case select writes back */
+ r = select(ct->ct_sock+1, fds, NULL, NULL, &tv);
+ save_errno = errno;
+
+ gettimeofday(&after, NULL);
+ timersub(&start, &after, &duration);
+ timersub(&ct->ct_wait, &duration, &tmp);
+ delta = tmp;
+ if (delta.tv_sec < 0 || !timerisset(&delta))
+ r = 0;
+
+ switch (r) {
+ case 0:
+ if (fds != &readfds)
+ free(fds);
+ ct->ct_error.re_status = RPC_TIMEDOUT;
+ return (-1);
+
+ case -1:
+ if (errno == EINTR)
+ continue;
+ if (fds != &readfds)
+ free(fds);
+ ct->ct_error.re_status = RPC_CANTRECV;
+ ct->ct_error.re_errno = save_errno;
+ return (-1);
+ }
+ break;
+ }
+ switch (len = read(ct->ct_sock, buf, len)) {
+
+ case 0:
+ /* premature eof */
+ ct->ct_error.re_errno = ECONNRESET;
+ ct->ct_error.re_status = RPC_CANTRECV;
+ len = -1; /* it's really an error */
+ break;
+
+ case -1:
+ ct->ct_error.re_errno = errno;
+ ct->ct_error.re_status = RPC_CANTRECV;
+ break;
+ }
+ return (len);
+}
+
+static int
+writetcp(ct, buf, len)
+ struct ct_data *ct;
+ caddr_t buf;
+ int len;
+{
+ register int i, cnt;
+
+ for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+ if ((i = write(ct->ct_sock, buf, cnt)) == -1) {
+ ct->ct_error.re_errno = errno;
+ ct->ct_error.re_status = RPC_CANTSEND;
+ return (-1);
+ }
+ }
+ return (len);
+}
diff --git a/lib/libc/rpc/clnt_udp.c b/lib/libc/rpc/clnt_udp.c
new file mode 100644
index 0000000..5756fc5
--- /dev/null
+++ b/lib/libc/rpc/clnt_udp.c
@@ -0,0 +1,567 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * clnt_udp.c, Implements a UDP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+
+/*
+ * UDP bases client side rpc operations
+ */
+static enum clnt_stat clntudp_call();
+static void clntudp_abort();
+static void clntudp_geterr();
+static bool_t clntudp_freeres();
+static bool_t clntudp_control();
+static void clntudp_destroy();
+
+static struct clnt_ops udp_ops = {
+ clntudp_call,
+ clntudp_abort,
+ clntudp_geterr,
+ clntudp_freeres,
+ clntudp_destroy,
+ clntudp_control
+};
+
+/*
+ * Private data kept per client handle
+ */
+struct cu_data {
+ int cu_sock;
+ bool_t cu_closeit;
+ struct sockaddr_in cu_raddr;
+ int cu_rlen;
+ struct timeval cu_wait;
+ struct timeval cu_total;
+ struct rpc_err cu_error;
+ XDR cu_outxdrs;
+ u_int cu_xdrpos;
+ u_int cu_sendsz;
+ char *cu_outbuf;
+ u_int cu_recvsz;
+ char cu_inbuf[1];
+};
+
+/*
+ * Create a UDP based client handle.
+ * If *sockp<0, *sockp is set to a newly created UPD socket.
+ * If raddr->sin_port is 0 a binder on the remote machine
+ * is consulted for the correct port number.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is initialized to null authentication.
+ * Caller may wish to set this something more useful.
+ *
+ * wait is the amount of time used between retransmitting a call if
+ * no response has been heard; retransmition occurs until the actual
+ * rpc call times out.
+ *
+ * sendsz and recvsz are the maximum allowable packet sizes that can be
+ * sent and received.
+ */
+CLIENT *
+clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+ struct sockaddr_in *raddr;
+ u_long program;
+ u_long version;
+ struct timeval wait;
+ register int *sockp;
+ u_int sendsz;
+ u_int recvsz;
+{
+ CLIENT *cl;
+ register struct cu_data *cu = NULL;
+ struct timeval now;
+ struct rpc_msg call_msg;
+ static u_int32_t disrupt;
+
+ if (disrupt == 0)
+ disrupt = (u_int32_t)(long)raddr;
+
+ cl = (CLIENT *)mem_alloc(sizeof(CLIENT));
+ if (cl == NULL) {
+ (void) fprintf(stderr, "clntudp_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ sendsz = ((sendsz + 3) / 4) * 4;
+ recvsz = ((recvsz + 3) / 4) * 4;
+ cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz);
+ if (cu == NULL) {
+ (void) fprintf(stderr, "clntudp_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ cu->cu_outbuf = &cu->cu_inbuf[recvsz];
+
+ (void)gettimeofday(&now, (struct timezone *)0);
+ if (raddr->sin_port == 0) {
+ u_short port;
+ if ((port =
+ pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
+ goto fooy;
+ }
+ raddr->sin_port = htons(port);
+ }
+ cl->cl_ops = &udp_ops;
+ cl->cl_private = (caddr_t)cu;
+ cu->cu_raddr = *raddr;
+ cu->cu_rlen = sizeof (cu->cu_raddr);
+ cu->cu_wait = wait;
+ cu->cu_total.tv_sec = -1;
+ cu->cu_total.tv_usec = -1;
+ cu->cu_sendsz = sendsz;
+ cu->cu_recvsz = recvsz;
+ call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
+ call_msg.rm_direction = CALL;
+ call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ call_msg.rm_call.cb_prog = program;
+ call_msg.rm_call.cb_vers = version;
+ xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf,
+ sendsz, XDR_ENCODE);
+ if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
+ goto fooy;
+ }
+ cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
+ if (*sockp < 0) {
+ int dontblock = 1;
+
+ *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (*sockp < 0) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ /* attempt to bind to priv port */
+ (void)bindresvport(*sockp, (struct sockaddr_in *)0);
+ /* the sockets rpc controls are non-blocking */
+ (void)ioctl(*sockp, FIONBIO, (char *) &dontblock);
+ cu->cu_closeit = TRUE;
+ } else {
+ cu->cu_closeit = FALSE;
+ }
+ cu->cu_sock = *sockp;
+ cl->cl_auth = authnone_create();
+ return (cl);
+fooy:
+ if (cu)
+ mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz);
+ if (cl)
+ mem_free((caddr_t)cl, sizeof(CLIENT));
+ return ((CLIENT *)NULL);
+}
+
+CLIENT *
+clntudp_create(raddr, program, version, wait, sockp)
+ struct sockaddr_in *raddr;
+ u_long program;
+ u_long version;
+ struct timeval wait;
+ register int *sockp;
+{
+
+ return(clntudp_bufcreate(raddr, program, version, wait, sockp,
+ UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum clnt_stat
+clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
+ register CLIENT *cl; /* client handle */
+ u_long proc; /* procedure number */
+ xdrproc_t xargs; /* xdr routine for args */
+ caddr_t argsp; /* pointer to args */
+ xdrproc_t xresults; /* xdr routine for results */
+ caddr_t resultsp; /* pointer to results */
+ struct timeval utimeout; /* seconds to wait before giving up */
+{
+ register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+ register XDR *xdrs;
+ register int outlen;
+ register int inlen;
+ int fromlen;
+ fd_set *fds, readfds;
+ struct sockaddr_in from;
+ struct rpc_msg reply_msg;
+ XDR reply_xdrs;
+ struct timeval time_waited, start, after, tmp1, tmp2, tv;
+ bool_t ok;
+ int nrefreshes = 2; /* number of times to refresh cred */
+ struct timeval timeout;
+
+ if (cu->cu_total.tv_usec == -1)
+ timeout = utimeout; /* use supplied timeout */
+ else
+ timeout = cu->cu_total; /* use default timeout */
+
+ if (cu->cu_sock + 1 > FD_SETSIZE) {
+ int bytes = howmany(cu->cu_sock + 1, NFDBITS) * sizeof(fd_mask);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL)
+ return (cu->cu_error.re_status = RPC_CANTSEND);
+ memset(fds, 0, bytes);
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ timerclear(&time_waited);
+
+call_again:
+ xdrs = &(cu->cu_outxdrs);
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, cu->cu_xdrpos);
+ /*
+ * the transaction is the first thing in the out buffer
+ */
+ (*(u_short *)(cu->cu_outbuf))++;
+ if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+ (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
+ (! (*xargs)(xdrs, argsp))) {
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
+ }
+ outlen = (int)XDR_GETPOS(xdrs);
+
+send_again:
+ if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
+ (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) != outlen) {
+ cu->cu_error.re_errno = errno;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_CANTSEND);
+ }
+
+ /*
+ * Hack to provide rpc-based message passing
+ */
+ if (!timerisset(&timeout)) {
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+ }
+ /*
+ * sub-optimal code appears here because we have
+ * some clock time to spare while the packets are in flight.
+ * (We assume that this is actually only executed once.)
+ */
+ reply_msg.acpted_rply.ar_verf = _null_auth;
+ reply_msg.acpted_rply.ar_results.where = resultsp;
+ reply_msg.acpted_rply.ar_results.proc = xresults;
+
+ gettimeofday(&start, NULL);
+ for (;;) {
+ /* XXX we know the other bits are still clear */
+ FD_SET(cu->cu_sock, fds);
+ tv = cu->cu_wait;
+ switch (select(cu->cu_sock+1, fds, NULL, NULL, &tv)) {
+
+ case 0:
+ timeradd(&time_waited, &cu->cu_wait, &tmp1);
+ time_waited = tmp1;
+ if (timercmp(&time_waited, &timeout, <))
+ goto send_again;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+
+ case -1:
+ if (errno == EINTR) {
+ gettimeofday(&after, NULL);
+ timersub(&after, &start, &tmp1);
+ timeradd(&time_waited, &tmp1, &tmp2);
+ time_waited = tmp2;
+ if (timercmp(&time_waited, &timeout, <))
+ continue;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+ }
+ cu->cu_error.re_errno = errno;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+
+ do {
+ fromlen = sizeof(struct sockaddr);
+ inlen = recvfrom(cu->cu_sock, cu->cu_inbuf,
+ (int) cu->cu_recvsz, 0,
+ (struct sockaddr *)&from, &fromlen);
+ } while (inlen < 0 && errno == EINTR);
+ if (inlen < 0) {
+ if (errno == EWOULDBLOCK)
+ continue;
+ cu->cu_error.re_errno = errno;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+ if (inlen < sizeof(u_int32_t))
+ continue;
+ /* see if reply transaction id matches sent id */
+ if (*((u_int32_t *)(cu->cu_inbuf)) != *((u_int32_t *)(cu->cu_outbuf)))
+ continue;
+ /* we now assume we have the proper reply */
+ break;
+ }
+
+ /*
+ * now decode and validate the response
+ */
+ xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE);
+ ok = xdr_replymsg(&reply_xdrs, &reply_msg);
+ /* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */
+ if (ok) {
+ _seterr_reply(&reply_msg, &(cu->cu_error));
+ if (cu->cu_error.re_status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(cl->cl_auth,
+ &reply_msg.acpted_rply.ar_verf)) {
+ cu->cu_error.re_status = RPC_AUTHERROR;
+ cu->cu_error.re_why = AUTH_INVALIDRESP;
+ }
+ if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+ xdrs->x_op = XDR_FREE;
+ (void)xdr_opaque_auth(xdrs,
+ &(reply_msg.acpted_rply.ar_verf));
+ }
+ } /* end successful completion */
+ else {
+ /* maybe our credentials need to be refreshed ... */
+ if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) {
+ nrefreshes--;
+ goto call_again;
+ }
+ } /* end of unsuccessful completion */
+ } /* end of valid reply message */
+ else {
+ /*
+ * It's possible for xdr_replymsg() to fail partway
+ * through its attempt to decode the result from the
+ * server. If this happens, it will leave the reply
+ * structure partially populated with dynamically
+ * allocated memory. (This can happen if someone uses
+ * clntudp_bufcreate() to create a CLIENT handle and
+ * specifies a receive buffer size that is too small.)
+ * This memory must be free()ed to avoid a leak.
+ */
+ int op = reply_xdrs.x_op;
+ reply_xdrs.x_op = XDR_FREE;
+ xdr_replymsg(&reply_xdrs, &reply_msg);
+ reply_xdrs.x_op = op;
+ cu->cu_error.re_status = RPC_CANTDECODERES;
+ }
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status);
+}
+
+static void
+clntudp_geterr(cl, errp)
+ CLIENT *cl;
+ struct rpc_err *errp;
+{
+ register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+ *errp = cu->cu_error;
+}
+
+
+static bool_t
+clntudp_freeres(cl, xdr_res, res_ptr)
+ CLIENT *cl;
+ xdrproc_t xdr_res;
+ caddr_t res_ptr;
+{
+ register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+ register XDR *xdrs = &(cu->cu_outxdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clntudp_abort(/*h*/)
+ /*CLIENT *h;*/
+{
+}
+
+
+static bool_t
+clntudp_control(cl, request, info)
+ CLIENT *cl;
+ int request;
+ char *info;
+{
+ register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+ register struct timeval *tv;
+ int len;
+
+ switch (request) {
+ case CLSET_FD_CLOSE:
+ cu->cu_closeit = TRUE;
+ break;
+ case CLSET_FD_NCLOSE:
+ cu->cu_closeit = FALSE;
+ break;
+ case CLSET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ tv = (struct timeval *)info;
+ cu->cu_total.tv_sec = tv->tv_sec;
+ cu->cu_total.tv_usec = tv->tv_usec;
+ break;
+ case CLGET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ *(struct timeval *)info = cu->cu_total;
+ break;
+ case CLSET_RETRY_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ tv = (struct timeval *)info;
+ cu->cu_wait.tv_sec = tv->tv_sec;
+ cu->cu_wait.tv_usec = tv->tv_usec;
+ break;
+ case CLGET_RETRY_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ *(struct timeval *)info = cu->cu_wait;
+ break;
+ case CLGET_SERVER_ADDR:
+ if (info == NULL)
+ return(FALSE);
+ *(struct sockaddr_in *)info = cu->cu_raddr;
+ break;
+ case CLGET_FD:
+ if (info == NULL)
+ return(FALSE);
+ *(int *)info = cu->cu_sock;
+ break;
+ case CLGET_XID:
+ /*
+ * use the knowledge that xid is the
+ * first element in the call structure *.
+ * This will get the xid of the PREVIOUS call
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)cu->cu_outbuf);
+ break;
+ case CLSET_XID:
+ /* This will set the xid of the NEXT call */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)cu->cu_outbuf = htonl(*(u_long *)info - 1);
+ /* decrement by 1 as clntudp_call() increments once */
+ case CLGET_VERS:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the version number field is the fifth field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
+ 4 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_VERS:
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_long *)info);
+ break;
+ case CLGET_PROG:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the program number field is the field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
+ 3 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_PROG:
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_long *)info);
+ break;
+ case CLGET_LOCAL_ADDR:
+ len = sizeof(struct sockaddr);
+ if (getsockname(cu->cu_sock, (struct sockaddr *)info, &len) <0)
+ return(FALSE);
+ break;
+ case CLGET_SVC_ADDR:
+ case CLSET_SVC_ADDR:
+ case CLSET_PUSH_TIMOD:
+ case CLSET_POP_TIMOD:
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+static void
+clntudp_destroy(cl)
+ CLIENT *cl;
+{
+ register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+ if (cu->cu_closeit) {
+ (void)close(cu->cu_sock);
+ }
+ XDR_DESTROY(&(cu->cu_outxdrs));
+ mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz));
+ mem_free((caddr_t)cl, sizeof(CLIENT));
+}
diff --git a/lib/libc/rpc/clnt_unix.c b/lib/libc/rpc/clnt_unix.c
new file mode 100644
index 0000000..d7a490b
--- /dev/null
+++ b/lib/libc/rpc/clnt_unix.c
@@ -0,0 +1,635 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_unix.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * clnt_unix.c, Implements a AF_UNIX based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * AF_UNIX based RPC supports 'batched calls'.
+ * A sequence of calls may be batched-up in a send buffer. The rpc call
+ * return immediately to the client even though the call was not necessarily
+ * sent. The batching occurs if the results' xdr routine is NULL (0) AND
+ * the rpc timeout value is zero (see clnt.h, rpc).
+ *
+ * Clients should NOT casually batch calls that in fact return results; that is,
+ * the server side should be aware that a call is batched and not produce any
+ * return message. Batched calls that produce many result messages can
+ * deadlock (netlock) the client and the server....
+ *
+ * Now go hang yourself.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+
+#define MCALL_MSG_SIZE 24
+
+static int readunix();
+static int writeunix();
+
+static enum clnt_stat clntunix_call();
+static void clntunix_abort();
+static void clntunix_geterr();
+static bool_t clntunix_freeres();
+static bool_t clntunix_control();
+static void clntunix_destroy();
+
+static struct clnt_ops unix_ops = {
+ clntunix_call,
+ clntunix_abort,
+ clntunix_geterr,
+ clntunix_freeres,
+ clntunix_destroy,
+ clntunix_control
+};
+
+struct ct_data {
+ int ct_sock;
+ bool_t ct_closeit;
+ struct timeval ct_wait;
+ bool_t ct_waitset; /* wait set by clnt_control? */
+ struct sockaddr_un ct_addr;
+ struct rpc_err ct_error;
+ char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */
+ u_int ct_mpos; /* pos after marshal */
+ XDR ct_xdrs;
+};
+
+/*
+ * Create a client handle for a unix/ip connection.
+ * If *sockp<0, *sockp is set to a newly created TCP socket and it is
+ * connected to raddr. If *sockp non-negative then
+ * raddr is ignored. The rpc/unix package does buffering
+ * similar to stdio, so the client must pick send and receive buffer sizes,];
+ * 0 => use the default.
+ * If raddr->sin_port is 0, then a binder on the remote machine is
+ * consulted for the right port number.
+ * NB: *sockp is copied into a private area.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is set null authentication. Caller may wish to set this
+ * something more useful.
+ */
+CLIENT *
+clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ struct sockaddr_un *raddr;
+ u_long prog;
+ u_long vers;
+ register int *sockp;
+ u_int sendsz;
+ u_int recvsz;
+{
+ CLIENT *h;
+ register struct ct_data *ct = NULL;
+ struct timeval now;
+ struct rpc_msg call_msg;
+ static u_int32_t disrupt;
+ int len;
+
+ if (disrupt == 0)
+ disrupt = (u_int32_t)(long)raddr;
+
+ h = (CLIENT *)mem_alloc(sizeof(*h));
+ if (h == NULL) {
+ (void)fprintf(stderr, "clntunix_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ ct = (struct ct_data *)mem_alloc(sizeof(*ct));
+ if (ct == NULL) {
+ (void)fprintf(stderr, "clntunix_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+
+ /*
+ * If no socket given, open one
+ */
+ if (*sockp < 0) {
+ *sockp = socket(AF_UNIX, SOCK_STREAM, 0);
+ len = strlen(raddr->sun_path) + sizeof(raddr->sun_family) +
+ sizeof(raddr->sun_len) + 1;
+ raddr->sun_len = len;
+ if ((*sockp < 0)
+ || (connect(*sockp, (struct sockaddr *)raddr, len) < 0)) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ if (*sockp != -1)
+ (void)close(*sockp);
+ goto fooy;
+ }
+ ct->ct_closeit = TRUE;
+ } else {
+ ct->ct_closeit = FALSE;
+ }
+
+ /*
+ * Set up private data struct
+ */
+ ct->ct_sock = *sockp;
+ ct->ct_wait.tv_usec = 0;
+ ct->ct_waitset = FALSE;
+ ct->ct_addr = *raddr;
+
+ /*
+ * Initialize call message
+ */
+ (void)gettimeofday(&now, (struct timezone *)0);
+ call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
+ call_msg.rm_direction = CALL;
+ call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ call_msg.rm_call.cb_prog = prog;
+ call_msg.rm_call.cb_vers = vers;
+
+ /*
+ * pre-serialize the static part of the call msg and stash it away
+ */
+ xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
+ XDR_ENCODE);
+ if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
+ if (ct->ct_closeit) {
+ (void)close(*sockp);
+ }
+ goto fooy;
+ }
+ ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
+ XDR_DESTROY(&(ct->ct_xdrs));
+
+ /*
+ * Create a client handle which uses xdrrec for serialization
+ * and authnone for authentication.
+ */
+ xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
+ (caddr_t)ct, readunix, writeunix);
+ h->cl_ops = &unix_ops;
+ h->cl_private = (caddr_t) ct;
+ h->cl_auth = authnone_create();
+ return (h);
+
+fooy:
+ /*
+ * Something goofed, free stuff and barf
+ */
+ if (ct)
+ mem_free((caddr_t)ct, sizeof(struct ct_data));
+ if (h)
+ mem_free((caddr_t)h, sizeof(CLIENT));
+ return ((CLIENT *)NULL);
+}
+
+static enum clnt_stat
+clntunix_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
+ register CLIENT *h;
+ u_long proc;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+ xdrproc_t xdr_results;
+ caddr_t results_ptr;
+ struct timeval timeout;
+{
+ register struct ct_data *ct = (struct ct_data *) h->cl_private;
+ register XDR *xdrs = &(ct->ct_xdrs);
+ struct rpc_msg reply_msg;
+ u_long x_id;
+ u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall); /* yuk */
+ register bool_t shipnow;
+ int refreshes = 2;
+
+ if (!ct->ct_waitset) {
+ ct->ct_wait = timeout;
+ }
+
+ shipnow =
+ (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
+ && timeout.tv_usec == 0) ? FALSE : TRUE;
+
+call_again:
+ xdrs->x_op = XDR_ENCODE;
+ ct->ct_error.re_status = RPC_SUCCESS;
+ x_id = ntohl(--(*msg_x_id));
+ if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
+ (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+ (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+ (! (*xdr_args)(xdrs, args_ptr))) {
+ if (ct->ct_error.re_status == RPC_SUCCESS)
+ ct->ct_error.re_status = RPC_CANTENCODEARGS;
+ (void)xdrrec_endofrecord(xdrs, TRUE);
+ return (ct->ct_error.re_status);
+ }
+ if (! xdrrec_endofrecord(xdrs, shipnow))
+ return (ct->ct_error.re_status = RPC_CANTSEND);
+ if (! shipnow)
+ return (RPC_SUCCESS);
+ /*
+ * Hack to provide rpc-based message passing
+ */
+ if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+ return(ct->ct_error.re_status = RPC_TIMEDOUT);
+ }
+
+
+ /*
+ * Keep receiving until we get a valid transaction id
+ */
+ xdrs->x_op = XDR_DECODE;
+ while (TRUE) {
+ reply_msg.acpted_rply.ar_verf = _null_auth;
+ reply_msg.acpted_rply.ar_results.where = NULL;
+ reply_msg.acpted_rply.ar_results.proc = xdr_void;
+ if (! xdrrec_skiprecord(xdrs))
+ return (ct->ct_error.re_status);
+ /* now decode and validate the response header */
+ if (! xdr_replymsg(xdrs, &reply_msg)) {
+ if (ct->ct_error.re_status == RPC_SUCCESS)
+ continue;
+ return (ct->ct_error.re_status);
+ }
+ if (reply_msg.rm_xid == x_id)
+ break;
+ }
+
+ /*
+ * process header
+ */
+ _seterr_reply(&reply_msg, &(ct->ct_error));
+ if (ct->ct_error.re_status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
+ ct->ct_error.re_status = RPC_AUTHERROR;
+ ct->ct_error.re_why = AUTH_INVALIDRESP;
+ } else if (! (*xdr_results)(xdrs, results_ptr)) {
+ if (ct->ct_error.re_status == RPC_SUCCESS)
+ ct->ct_error.re_status = RPC_CANTDECODERES;
+ }
+ /* free verifier ... */
+ if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+ xdrs->x_op = XDR_FREE;
+ (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
+ }
+ } /* end successful completion */
+ else {
+ /* maybe our credentials need to be refreshed ... */
+ if (refreshes-- && AUTH_REFRESH(h->cl_auth))
+ goto call_again;
+ } /* end of unsuccessful completion */
+ return (ct->ct_error.re_status);
+}
+
+static void
+clntunix_geterr(h, errp)
+ CLIENT *h;
+ struct rpc_err *errp;
+{
+ register struct ct_data *ct =
+ (struct ct_data *) h->cl_private;
+
+ *errp = ct->ct_error;
+}
+
+static bool_t
+clntunix_freeres(cl, xdr_res, res_ptr)
+ CLIENT *cl;
+ xdrproc_t xdr_res;
+ caddr_t res_ptr;
+{
+ register struct ct_data *ct = (struct ct_data *)cl->cl_private;
+ register XDR *xdrs = &(ct->ct_xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clntunix_abort()
+{
+}
+
+
+static bool_t
+clntunix_control(cl, request, info)
+ CLIENT *cl;
+ int request;
+ char *info;
+{
+ register struct ct_data *ct = (struct ct_data *)cl->cl_private;
+ register struct timeval *tv;
+ int len;
+
+ switch (request) {
+ case CLSET_FD_CLOSE:
+ ct->ct_closeit = TRUE;
+ break;
+ case CLSET_FD_NCLOSE:
+ ct->ct_closeit = FALSE;
+ break;
+ case CLSET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ tv = (struct timeval *)info;
+ ct->ct_wait.tv_sec = tv->tv_sec;
+ ct->ct_wait.tv_usec = tv->tv_usec;
+ ct->ct_waitset = TRUE;
+ break;
+ case CLGET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ *(struct timeval *)info = ct->ct_wait;
+ break;
+ case CLGET_SERVER_ADDR:
+ if (info == NULL)
+ return(FALSE);
+ *(struct sockaddr_un *)info = ct->ct_addr;
+ break;
+ case CLGET_FD:
+ if (info == NULL)
+ return(FALSE);
+ *(int *)info = ct->ct_sock;
+ break;
+ case CLGET_XID:
+ /*
+ * use the knowledge that xid is the
+ * first element in the call structure *.
+ * This will get the xid of the PREVIOUS call
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)ct->ct_mcall);
+ break;
+ case CLSET_XID:
+ /* This will set the xid of the NEXT call */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)ct->ct_mcall = htonl(*(u_long *)info - 1);
+ /* decrement by 1 as clntunix_call() increments once */
+ case CLGET_VERS:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the version number field is the fifth field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
+ 4 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_VERS:
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_long *)info);
+ break;
+ case CLGET_PROG:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the program number field is the field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
+ 3 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_PROG:
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_long *)info);
+ break;
+ case CLGET_LOCAL_ADDR:
+ len = sizeof(struct sockaddr);
+ if (getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0)
+ return(FALSE);
+ break;
+ case CLGET_RETRY_TIMEOUT:
+ case CLSET_RETRY_TIMEOUT:
+ case CLGET_SVC_ADDR:
+ case CLSET_SVC_ADDR:
+ case CLSET_PUSH_TIMOD:
+ case CLSET_POP_TIMOD:
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+static void
+clntunix_destroy(h)
+ CLIENT *h;
+{
+ register struct ct_data *ct =
+ (struct ct_data *) h->cl_private;
+
+ if (ct->ct_closeit) {
+ (void)close(ct->ct_sock);
+ }
+ XDR_DESTROY(&(ct->ct_xdrs));
+ mem_free((caddr_t)ct, sizeof(struct ct_data));
+ mem_free((caddr_t)h, sizeof(CLIENT));
+}
+
+/*
+ * read() and write() are replaced with recvmsg()/sendmsg() so that
+ * we can pass ancillary control data. In this case, the data constists
+ * of credential information which the kernel will fill in for us.
+ * XXX: This code is specific to FreeBSD and will not work on other
+ * platforms without the requisite kernel modifications.
+ */
+struct cmessage {
+ struct cmsghdr cmsg;
+ struct cmsgcred cmcred;
+};
+
+static int __msgread(sock, buf, cnt)
+ int sock;
+ void *buf;
+ size_t cnt;
+{
+ struct iovec iov[1];
+ struct msghdr msg;
+ struct cmessage cm;
+
+ bzero((char *)&cm, sizeof(cm));
+ iov[0].iov_base = buf;
+ iov[0].iov_len = cnt;
+
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = (caddr_t)&cm;
+ msg.msg_controllen = sizeof(struct cmessage);
+ msg.msg_flags = 0;
+
+ return(recvmsg(sock, &msg, 0));
+}
+
+static int __msgwrite(sock, buf, cnt)
+ int sock;
+ void *buf;
+ size_t cnt;
+{
+ struct iovec iov[1];
+ struct msghdr msg;
+ struct cmessage cm;
+
+ bzero((char *)&cm, sizeof(cm));
+ iov[0].iov_base = buf;
+ iov[0].iov_len = cnt;
+
+ cm.cmsg.cmsg_type = SCM_CREDS;
+ cm.cmsg.cmsg_level = SOL_SOCKET;
+ cm.cmsg.cmsg_len = sizeof(struct cmessage);
+
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = (caddr_t)&cm;
+ msg.msg_controllen = sizeof(struct cmessage);
+ msg.msg_flags = 0;
+
+ return(sendmsg(sock, &msg, 0));
+}
+
+/*
+ * Interface between xdr serializer and unix connection.
+ * Behaves like the system calls, read & write, but keeps some error state
+ * around for the rpc level.
+ */
+static int
+readunix(ct, buf, len)
+ register struct ct_data *ct;
+ caddr_t buf;
+ register int len;
+{
+ fd_set *fds, readfds;
+ struct timeval start, after, duration, delta, tmp, tv;
+ int r, save_errno;
+
+ if (len == 0)
+ return (0);
+
+ if (ct->ct_sock + 1 > FD_SETSIZE) {
+ int bytes = howmany(ct->ct_sock + 1, NFDBITS) * sizeof(fd_mask);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL)
+ return (-1);
+ memset(fds, 0, bytes);
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ gettimeofday(&start, NULL);
+ delta = ct->ct_wait;
+ while (TRUE) {
+ /* XXX we know the other bits are still clear */
+ FD_SET(ct->ct_sock, fds);
+ tv = delta; /* in case select writes back */
+ r = select(ct->ct_sock+1, fds, NULL, NULL, &tv);
+ save_errno = errno;
+
+ gettimeofday(&after, NULL);
+ timersub(&start, &after, &duration);
+ timersub(&delta, &duration, &tmp);
+ delta = tmp;
+ if (delta.tv_sec < 0 || !timerisset(&delta))
+ r = 0;
+
+ switch (r) {
+ case 0:
+ if (fds != &readfds)
+ free(fds);
+ ct->ct_error.re_status = RPC_TIMEDOUT;
+ return (-1);
+
+ case -1:
+ if (errno == EINTR)
+ continue;
+ if (fds != &readfds)
+ free(fds);
+ ct->ct_error.re_status = RPC_CANTRECV;
+ ct->ct_error.re_errno = save_errno;
+ return (-1);
+ }
+ break;
+ }
+ switch (len = __msgread(ct->ct_sock, buf, len)) {
+
+ case 0:
+ /* premature eof */
+ ct->ct_error.re_errno = ECONNRESET;
+ ct->ct_error.re_status = RPC_CANTRECV;
+ len = -1; /* it's really an error */
+ break;
+
+ case -1:
+ ct->ct_error.re_errno = errno;
+ ct->ct_error.re_status = RPC_CANTRECV;
+ break;
+ }
+ return (len);
+}
+
+static int
+writeunix(ct, buf, len)
+ struct ct_data *ct;
+ caddr_t buf;
+ int len;
+{
+ register int i, cnt;
+
+ for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+ if ((i = __msgwrite(ct->ct_sock, buf, cnt)) == -1) {
+ ct->ct_error.re_errno = errno;
+ ct->ct_error.re_status = RPC_CANTSEND;
+ return (-1);
+ }
+ }
+ return (len);
+}
diff --git a/lib/libc/rpc/crypt_client.c b/lib/libc/rpc/crypt_client.c
new file mode 100644
index 0000000..ab01971
--- /dev/null
+++ b/lib/libc/rpc/crypt_client.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1996
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <rpc/des_crypt.h>
+#include <rpc/des.h>
+#include <string.h>
+#include <rpcsvc/crypt.h>
+
+#ifndef lint
+static const char rcsid[] = "$FreeBSD$";
+#endif
+
+#ifndef KEYSERVSOCK
+#define KEYSERVSOCK "/var/run/keyservsock"
+#endif
+
+int
+_des_crypt_call(buf, len, dparms)
+ char *buf;
+ int len;
+ struct desparams *dparms;
+{
+ CLIENT *clnt;
+ desresp *result_1;
+ desargs des_crypt_1_arg;
+ int stat;
+
+ clnt = clnt_create(KEYSERVSOCK, CRYPT_PROG, CRYPT_VERS, "unix");
+ if (clnt == (CLIENT *) NULL) {
+ return(DESERR_HWERROR);
+ }
+
+ des_crypt_1_arg.desbuf.desbuf_len = len;
+ des_crypt_1_arg.desbuf.desbuf_val = buf;
+ des_crypt_1_arg.des_dir = dparms->des_dir;
+ des_crypt_1_arg.des_mode = dparms->des_mode;
+ bcopy(dparms->des_ivec, des_crypt_1_arg.des_ivec, 8);
+ bcopy(dparms->des_key, des_crypt_1_arg.des_key, 8);
+
+ result_1 = des_crypt_1(&des_crypt_1_arg, clnt);
+ if (result_1 == (desresp *) NULL) {
+ clnt_destroy(clnt);
+ return(DESERR_HWERROR);
+ }
+
+ stat = result_1->stat;
+
+ if (result_1->stat == DESERR_NONE ||
+ result_1->stat == DESERR_NOHWDEVICE) {
+ bcopy(result_1->desbuf.desbuf_val, buf, len);
+ bcopy(result_1->des_ivec, dparms->des_ivec, 8);
+ }
+
+ clnt_freeres(clnt, xdr_desresp, (char *)result_1);
+ clnt_destroy(clnt);
+
+ return(stat);
+}
diff --git a/lib/libc/rpc/des_crypt.3 b/lib/libc/rpc/des_crypt.3
new file mode 100644
index 0000000..00ddda9
--- /dev/null
+++ b/lib/libc/rpc/des_crypt.3
@@ -0,0 +1,128 @@
+.\" @(#)des_crypt.3 2.1 88/08/11 4.0 RPCSRC; from 1.16 88/03/02 SMI;
+.\" $FreeBSD$
+.\"
+.TH DES_CRYPT 3 "6 October 1987"
+.SH NAME
+des_crypt, ecb_crypt, cbc_crypt, des_setparity \- fast DES encryption
+.SH SYNOPSIS
+.nf
+.B #include <des_crypt.h>
+.LP
+.B int ecb_crypt(key, data, datalen, mode)
+.B char *key;
+.B char *data;
+.B unsigned datalen;
+.B unsigned mode;
+.LP
+.B int cbc_crypt(key, data, datalen, mode, ivec)
+.B char *key;
+.B char *data;
+.B unsigned datalen;
+.B unsigned mode;
+.B char *ivec;
+.LP
+.B void des_setparity(key)
+.B char *key;
+.fi
+.SH DESCRIPTION
+.IX encryption cbc_crypt "" \fLcbc_crypt\fP
+.IX "des encryption" cbc_crypt "DES encryption" \fLcbc_crypt\fP
+.IX encryption des_setparity "" \fLdes_setparity\fP
+.IX "des encryption" des_setparity "DES encryption" \fLdes_setparity\fP
+.B ecb_crypt(\|)
+and
+.B cbc_crypt(\|)
+implement the
+.SM NBS
+.SM DES
+(Data Encryption Standard).
+These routines are faster and more general purpose than
+.BR crypt (3).
+They also are able to utilize
+.SM DES
+hardware if it is available.
+.B ecb_crypt(\|)
+encrypts in
+.SM ECB
+(Electronic Code Book)
+mode, which encrypts blocks of data independently.
+.B cbc_crypt(\|)
+encrypts in
+.SM CBC
+(Cipher Block Chaining)
+mode, which chains together
+successive blocks.
+.SM CBC
+mode protects against insertions, deletions and
+substitutions of blocks. Also, regularities in the clear text will
+not appear in the cipher text.
+.LP
+Here is how to use these routines. The first parameter,
+.IR key ,
+is the 8-byte encryption key with parity.
+To set the key's parity, which for
+.SM DES
+is in the low bit of each byte, use
+.IR des_setparity .
+The second parameter,
+.IR data ,
+contains the data to be encrypted or decrypted. The
+third parameter,
+.IR datalen ,
+is the length in bytes of
+.IR data ,
+which must be a multiple of 8. The fourth parameter,
+.IR mode ,
+is formed by
+.SM OR\s0'ing
+together some things. For the encryption direction 'or' in either
+.SM DES_ENCRYPT
+or
+.SM DES_DECRYPT\s0.
+For software versus hardware
+encryption, 'or' in either
+.SM DES_HW
+or
+.SM DES_SW\s0.
+If
+.SM DES_HW
+is specified, and there is no hardware, then the encryption is performed
+in software and the routine returns
+.SM DESERR_NOHWDEVICE\s0.
+For
+.IR cbc_crypt ,
+the parameter
+.I ivec
+is the the 8-byte initialization
+vector for the chaining. It is updated to the next initialization
+vector upon return.
+.LP
+.SH "SEE ALSO"
+.BR des (1),
+.BR crypt (3)
+.SH DIAGNOSTICS
+.PD 0
+.TP 20
+.SM DESERR_NONE
+No error.
+.TP
+.SM DESERR_NOHWDEVICE
+Encryption succeeded, but done in software instead of the requested hardware.
+.TP
+.SM DESERR_HWERR
+An error occurred in the hardware or driver.
+.TP
+.SM DESERR_BADPARAM
+Bad parameter to routine.
+.PD
+.LP
+Given a result status
+.IR stat ,
+the macro
+.SM DES_FAILED\c
+.BR ( stat )
+is false only for the first two statuses.
+.SH RESTRICTIONS
+These routines are not available in RPCSRC 4.0.
+This information is provided to describe the DES interface expected by
+Secure RPC.
diff --git a/lib/libc/rpc/des_crypt.c b/lib/libc/rpc/des_crypt.c
new file mode 100644
index 0000000..fa71d5c
--- /dev/null
+++ b/lib/libc/rpc/des_crypt.c
@@ -0,0 +1,153 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * des_crypt.c, DES encryption library routines
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+#include <sys/types.h>
+#include <rpc/des_crypt.h>
+#include <rpc/des.h>
+
+#ifndef lint
+/* from: static char sccsid[] = "@(#)des_crypt.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI"; */
+static const char rcsid[] = "$FreeBSD$";
+#endif
+
+static int common_crypt __P(( char *, char *, register unsigned, unsigned, struct desparams * ));
+int (*__des_crypt_LOCAL)() = 0;
+extern _des_crypt_call __P(( char *, int, struct desparams * ));
+/*
+ * Copy 8 bytes
+ */
+#define COPY8(src, dst) { \
+ register char *a = (char *) dst; \
+ register char *b = (char *) src; \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+}
+
+/*
+ * Copy multiple of 8 bytes
+ */
+#define DESCOPY(src, dst, len) { \
+ register char *a = (char *) dst; \
+ register char *b = (char *) src; \
+ register int i; \
+ for (i = (int) len; i > 0; i -= 8) { \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+ } \
+}
+
+/*
+ * CBC mode encryption
+ */
+int
+cbc_crypt(key, buf, len, mode, ivec)
+ char *key;
+ char *buf;
+ unsigned len;
+ unsigned mode;
+ char *ivec;
+{
+ int err;
+ struct desparams dp;
+
+#ifdef BROKEN_DES
+ dp.UDES.UDES_buf = buf;
+ dp.des_mode = ECB;
+#else
+ dp.des_mode = CBC;
+#endif
+ COPY8(ivec, dp.des_ivec);
+ err = common_crypt(key, buf, len, mode, &dp);
+ COPY8(dp.des_ivec, ivec);
+ return(err);
+}
+
+
+/*
+ * ECB mode encryption
+ */
+int
+ecb_crypt(key, buf, len, mode)
+ char *key;
+ char *buf;
+ unsigned len;
+ unsigned mode;
+{
+ struct desparams dp;
+
+#ifdef BROKEN_DES
+ dp.UDES.UDES_buf = buf;
+ dp.des_mode = CBC;
+#else
+ dp.des_mode = ECB;
+#endif
+ return(common_crypt(key, buf, len, mode, &dp));
+}
+
+
+
+/*
+ * Common code to cbc_crypt() & ecb_crypt()
+ */
+static int
+common_crypt(key, buf, len, mode, desp)
+ char *key;
+ char *buf;
+ register unsigned len;
+ unsigned mode;
+ register struct desparams *desp;
+{
+ register int desdev;
+
+ if ((len % 8) != 0 || len > DES_MAXDATA) {
+ return(DESERR_BADPARAM);
+ }
+ desp->des_dir =
+ ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
+
+ desdev = mode & DES_DEVMASK;
+ COPY8(key, desp->des_key);
+ /*
+ * software
+ */
+ if (__des_crypt_LOCAL != NULL) {
+ if (!__des_crypt_LOCAL(buf, len, desp)) {
+ return (DESERR_HWERROR);
+ }
+ } else {
+ if (!_des_crypt_call(buf, len, desp)) {
+ return (DESERR_HWERROR);
+ }
+ }
+ return(desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
+}
diff --git a/lib/libc/rpc/des_soft.c b/lib/libc/rpc/des_soft.c
new file mode 100644
index 0000000..01dd7f2
--- /dev/null
+++ b/lib/libc/rpc/des_soft.c
@@ -0,0 +1,67 @@
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)des_soft.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Table giving odd parity in the low bit for ASCII characters
+ */
+static char partab[128] = {
+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07,
+ 0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e,
+ 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
+ 0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f,
+ 0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26,
+ 0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f,
+ 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37,
+ 0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e,
+ 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
+ 0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f,
+ 0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57,
+ 0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e,
+ 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67,
+ 0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e,
+ 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
+ 0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f,
+};
+
+/*
+ * Add odd parity to low bit of 8 byte key
+ */
+void
+des_setparity(p)
+ char *p;
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ *p = partab[*p & 0x7f];
+ p++;
+ }
+}
diff --git a/lib/libc/rpc/get_myaddress.c b/lib/libc/rpc/get_myaddress.c
new file mode 100644
index 0000000..a18a032
--- /dev/null
+++ b/lib/libc/rpc/get_myaddress.c
@@ -0,0 +1,112 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * get_myaddress.c
+ *
+ * Get client's IP address via ioctl. This avoids using the yellowpages.
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*
+ * don't use gethostbyname, which would invoke yellow pages
+ *
+ * Avoid loopback interfaces. We return information from a loopback
+ * interface only if there are no other possible interfaces.
+ */
+int
+get_myaddress(addr)
+ struct sockaddr_in *addr;
+{
+ int s;
+ char buf[BUFSIZ];
+ struct ifconf ifc;
+ struct ifreq ifreq, *ifr, *end;
+ int loopback = 0, gotit = 0;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ return(-1);
+ }
+ ifc.ifc_len = sizeof (buf);
+ ifc.ifc_buf = buf;
+ if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+ close(s);
+ return(-1);
+ }
+again:
+ ifr = ifc.ifc_req;
+ end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
+
+ while (ifr < end) {
+ ifreq = *ifr;
+ if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+ close(s);
+ return(-1);
+ }
+ if (((ifreq.ifr_flags & IFF_UP) &&
+ ifr->ifr_addr.sa_family == AF_INET &&
+ !(ifreq.ifr_flags & IFF_LOOPBACK)) ||
+ (loopback == 1 && (ifreq.ifr_flags & IFF_LOOPBACK)
+ && (ifr->ifr_addr.sa_family == AF_INET)
+ && (ifreq.ifr_flags & IFF_UP))) {
+ *addr = *((struct sockaddr_in *)&ifr->ifr_addr);
+ addr->sin_port = htons(PMAPPORT);
+ gotit = 1;
+ break;
+ }
+ if (ifr->ifr_addr.sa_len)
+ ifr = (struct ifreq *) ((caddr_t) ifr +
+ ifr->ifr_addr.sa_len -
+ sizeof(struct sockaddr));
+ ifr++;
+ }
+ if (gotit == 0 && loopback == 0) {
+ loopback = 1;
+ goto again;
+ }
+ (void) close(s);
+ return (gotit ? 0 : -1);
+}
diff --git a/lib/libc/rpc/getpublickey.c b/lib/libc/rpc/getpublickey.c
new file mode 100644
index 0000000..e1c34d9
--- /dev/null
+++ b/lib/libc/rpc/getpublickey.c
@@ -0,0 +1,172 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)publickey.c 1.10 91/03/11 Copyr 1986 Sun Micro";
+#endif
+
+/*
+ * publickey.c
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+/*
+ * Public key lookup routines
+ */
+#include <stdio.h>
+#include <pwd.h>
+#include <rpc/rpc.h>
+#include <rpc/key_prot.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define PKFILE "/etc/publickey"
+
+/*
+ * Hack to let ypserv/rpc.nisd use AUTH_DES.
+ */
+int (*__getpublickey_LOCAL)() = 0;
+
+/*
+ * Get somebody's public key
+ */
+int
+__getpublickey_real(netname, publickey)
+ char *netname;
+ char *publickey;
+{
+ char lookup[3 * HEXKEYBYTES];
+ char *p;
+
+ if (publickey == NULL)
+ return (0);
+ if (!getpublicandprivatekey(netname, lookup))
+ return (0);
+ p = strchr(lookup, ':');
+ if (p == NULL) {
+ return (0);
+ }
+ *p = '\0';
+ (void) strncpy(publickey, lookup, HEXKEYBYTES);
+ publickey[HEXKEYBYTES] = '\0';
+ return (1);
+}
+
+/*
+ * reads the file /etc/publickey looking for a + to optionally go to the
+ * yellow pages
+ */
+
+int
+getpublicandprivatekey(key, ret)
+ char *key;
+ char *ret;
+{
+ char buf[1024]; /* big enough */
+ char *res;
+ FILE *fd;
+ char *mkey;
+ char *mval;
+
+ fd = fopen(PKFILE, "r");
+ if (fd == (FILE *) 0)
+ return (0);
+ for (;;) {
+ res = fgets(buf, 1024, fd);
+ if (res == 0) {
+ fclose(fd);
+ return (0);
+ }
+ if (res[0] == '#')
+ continue;
+ else if (res[0] == '+') {
+#ifdef YP
+ char *PKMAP = "publickey.byname";
+ char *lookup;
+ char *domain;
+ int err;
+ int len;
+
+ err = yp_get_default_domain(&domain);
+ if (err) {
+ continue;
+ }
+ lookup = NULL;
+ err = yp_match(domain, PKMAP, key, strlen(key), &lookup, &len);
+ if (err) {
+#ifdef DEBUG
+ fprintf(stderr, "match failed error %d\n", err);
+#endif
+ continue;
+ }
+ lookup[len] = 0;
+ strcpy(ret, lookup);
+ fclose(fd);
+ free(lookup);
+ return (2);
+#else /* YP */
+#ifdef DEBUG
+ fprintf(stderr,
+"Bad record in %s '+' -- NIS not supported in this library copy\n", PKFILE);
+#endif /* DEBUG */
+ continue;
+#endif /* YP */
+ } else {
+ mkey = strtok(buf, "\t ");
+ if (mkey == NULL) {
+ fprintf(stderr,
+ "Bad record in %s -- %s", PKFILE, buf);
+ continue;
+ }
+ mval = strtok((char *)NULL, " \t#\n");
+ if (mval == NULL) {
+ fprintf(stderr,
+ "Bad record in %s val problem - %s", PKFILE, buf);
+ continue;
+ }
+ if (strcmp(mkey, key) == 0) {
+ strcpy(ret, mval);
+ fclose(fd);
+ return (1);
+ }
+ }
+ }
+}
+
+int getpublickey(netname, publickey)
+ char *netname;
+ char *publickey;
+{
+ if (__getpublickey_LOCAL != NULL)
+ return(__getpublickey_LOCAL(netname, publickey));
+ else
+ return(__getpublickey_real(netname, publickey));
+}
diff --git a/lib/libc/rpc/getrpcent.3 b/lib/libc/rpc/getrpcent.3
new file mode 100644
index 0000000..eef8067
--- /dev/null
+++ b/lib/libc/rpc/getrpcent.3
@@ -0,0 +1,98 @@
+.\" @(#)getrpcent.3n 2.2 88/08/02 4.0 RPCSRC; from 1.11 88/03/14 SMI
+.\" $FreeBSD$
+.\"
+.Dd December 14, 1987
+.Dt GETRPCENT 3
+.Os
+.Sh NAME
+.Nm getrpcent ,
+.Nm getrpcbyname ,
+.Nm getrpcbynumber ,
+.Nm endrpcent ,
+.Nm setrpcent
+.Nd get RPC entry
+.Sh SYNOPSIS
+.Fd #include <rpc/rpc.h>
+.Ft struct rpcent *
+.Fn getrpcent void
+.Ft struct rpcent *
+.Fn getrpcbyname "char *name"
+.Ft struct rpcent *
+.Fn getrpcbynumber "int number"
+.Ft void
+.Fn setrpcent "int stayopen"
+.Ft void
+.Fn endrpcent void
+.Sh DESCRIPTION
+The
+.Fn getrpcent ,
+.Fn getrpcbyname ,
+and
+.Fn getrpcbynumber
+functions each return a pointer to an object with the
+following structure
+containing the broken-out
+fields of a line in the rpc program number data base,
+.Pa /etc/rpc .
+.Bd -literal
+
+struct rpcent {
+ char *r_name; /* name of server for this rpc program */
+ char **r_aliases; /* alias list */
+ long r_number; /* rpc program number */
+};
+.Ed
+.Pp
+The members of this structure are:
+.Bl -tag -width r_aliasesxxx
+.It Fa r_name
+The name of the server for this rpc program.
+.It Fa r_aliases
+A zero terminated list of alternate names for the rpc program.
+.It Fa r_number
+The rpc program number for this service.
+.El
+.Pp
+The
+.Fn getrpcent
+function reads the next line of the file, opening the file if necessary.
+The
+.Nm getrpcent
+function opens and rewinds the file. If the
+.Fa stayopen
+flag is non-zero,
+the net data base will not be closed after each call to
+.Fn getrpcent
+(either directly, or indirectly through one of
+the other
+.Fn getrpcent
+function family.
+.Pp
+.Fn endrpcent
+closes the file.
+.Pp
+.Fn getrpcbyname
+and
+.Fn getrpcbynumber
+sequentially search from the beginning
+of the file until a matching rpc program name or
+program number is found, or until end-of-file is encountered.
+.Sh FILES
+.Bl -tag -width /etc/rpc -compact
+.It Pa /etc/rpc
+.El
+.Sh "SEE ALSO"
+.Xr rpc 5 ,
+.Xr rpcinfo 8 ,
+.Xr ypserv 8
+.Sh DIAGNOSTICS
+A
+.Dv NULL
+pointer is returned on
+.Dv EOF
+or error.
+.Sh BUGS
+All information
+is contained in a static area
+so it must be copied if it is
+to be saved.
diff --git a/lib/libc/rpc/getrpcent.c b/lib/libc/rpc/getrpcent.c
new file mode 100644
index 0000000..4290235
--- /dev/null
+++ b/lib/libc/rpc/getrpcent.c
@@ -0,0 +1,303 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * Copyright (c) 1984 by Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#ifdef YP
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+
+/*
+ * Internet version.
+ */
+struct rpcdata {
+ FILE *rpcf;
+ int stayopen;
+#define MAXALIASES 35
+ char *rpc_aliases[MAXALIASES];
+ struct rpcent rpc;
+ char line[BUFSIZ+1];
+#ifdef YP
+ char *domain;
+ char *current;
+ int currentlen;
+#endif
+} *rpcdata;
+
+#ifdef YP
+static int __yp_nomap = 0;
+extern int _yp_check(char **);
+#endif /* YP */
+
+static struct rpcent *interpret();
+struct hostent *gethostent();
+char *inet_ntoa();
+
+static char RPCDB[] = "/etc/rpc";
+
+static struct rpcdata *
+_rpcdata()
+{
+ register struct rpcdata *d = rpcdata;
+
+ if (d == 0) {
+ d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
+ rpcdata = d;
+ }
+ return (d);
+}
+
+struct rpcent *
+getrpcbynumber(number)
+ register int number;
+{
+ register struct rpcdata *d = _rpcdata();
+ register struct rpcent *p;
+#ifdef YP
+ int reason;
+ char adrstr[16];
+#endif
+
+ if (d == 0)
+ return (0);
+#ifdef YP
+ if (!__yp_nomap && _yp_check(&d->domain)) {
+ sprintf(adrstr, "%d", number);
+ reason = yp_match(d->domain, "rpc.bynumber", adrstr, strlen(adrstr),
+ &d->current, &d->currentlen);
+ switch(reason) {
+ case 0:
+ break;
+ case YPERR_MAP:
+ __yp_nomap = 1;
+ goto no_yp;
+ break;
+ default:
+ return(0);
+ break;
+ }
+ d->current[d->currentlen] = '\0';
+ p = interpret(d->current, d->currentlen);
+ (void) free(d->current);
+ return p;
+ }
+no_yp:
+#endif /* YP */
+ setrpcent(0);
+ while ((p = getrpcent())) {
+ if (p->r_number == number)
+ break;
+ }
+ endrpcent();
+ return (p);
+}
+
+struct rpcent *
+getrpcbyname(name)
+ char *name;
+{
+ struct rpcent *rpc = NULL;
+ char **rp;
+
+ setrpcent(0);
+ while ((rpc = getrpcent())) {
+ if (strcmp(rpc->r_name, name) == 0)
+ goto done;
+ for (rp = rpc->r_aliases; *rp != NULL; rp++) {
+ if (strcmp(*rp, name) == 0)
+ goto done;
+ }
+ }
+done:
+ endrpcent();
+ return (rpc);
+}
+
+void
+setrpcent(f)
+ int f;
+{
+ register struct rpcdata *d = _rpcdata();
+
+ if (d == 0)
+ return;
+#ifdef YP
+ if (!__yp_nomap && _yp_check(NULL)) {
+ if (d->current)
+ free(d->current);
+ d->current = NULL;
+ d->currentlen = 0;
+ return;
+ }
+ __yp_nomap = 0;
+#endif /* YP */
+ if (d->rpcf == NULL)
+ d->rpcf = fopen(RPCDB, "r");
+ else
+ rewind(d->rpcf);
+ d->stayopen |= f;
+}
+
+void
+endrpcent()
+{
+ register struct rpcdata *d = _rpcdata();
+
+ if (d == 0)
+ return;
+#ifdef YP
+ if (!__yp_nomap && _yp_check(NULL)) {
+ if (d->current && !d->stayopen)
+ free(d->current);
+ d->current = NULL;
+ d->currentlen = 0;
+ return;
+ }
+ __yp_nomap = 0;
+#endif /* YP */
+ if (d->rpcf && !d->stayopen) {
+ fclose(d->rpcf);
+ d->rpcf = NULL;
+ }
+}
+
+struct rpcent *
+getrpcent()
+{
+ register struct rpcdata *d = _rpcdata();
+#ifdef YP
+ struct rpcent *hp;
+ int reason;
+ char *val = NULL;
+ int vallen;
+#endif
+
+ if (d == 0)
+ return(NULL);
+#ifdef YP
+ if (!__yp_nomap && _yp_check(&d->domain)) {
+ if (d->current == NULL && d->currentlen == 0) {
+ reason = yp_first(d->domain, "rpc.bynumber",
+ &d->current, &d->currentlen,
+ &val, &vallen);
+ } else {
+ reason = yp_next(d->domain, "rpc.bynumber",
+ d->current, d->currentlen,
+ &d->current, &d->currentlen,
+ &val, &vallen);
+ }
+ switch(reason) {
+ case 0:
+ break;
+ case YPERR_MAP:
+ __yp_nomap = 1;
+ goto no_yp;
+ break;
+ default:
+ return(0);
+ break;
+ }
+ val[vallen] = '\0';
+ hp = interpret(val, vallen);
+ (void) free(val);
+ return hp;
+ }
+no_yp:
+#endif /* YP */
+ if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
+ return (NULL);
+ /* -1 so there is room to append a \n below */
+ if (fgets(d->line, BUFSIZ - 1, d->rpcf) == NULL)
+ return (NULL);
+ return (interpret(d->line, strlen(d->line)));
+}
+
+static struct rpcent *
+interpret(val, len)
+ char *val;
+ int len;
+{
+ register struct rpcdata *d = _rpcdata();
+ char *p;
+ register char *cp, **q;
+
+ if (d == 0)
+ return (0);
+ (void) strncpy(d->line, val, BUFSIZ);
+ d->line[BUFSIZ] = '\0';
+ p = d->line;
+ p[len] = '\n';
+ if (*p == '#')
+ return (getrpcent());
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ return (getrpcent());
+ *cp = '\0';
+ cp = strpbrk(p, " \t");
+ if (cp == NULL)
+ return (getrpcent());
+ *cp++ = '\0';
+ /* THIS STUFF IS INTERNET SPECIFIC */
+ d->rpc.r_name = d->line;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ d->rpc.r_number = atoi(cp);
+ q = d->rpc.r_aliases = d->rpc_aliases;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &(d->rpc_aliases[MAXALIASES - 1]))
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ return (&d->rpc);
+}
+
diff --git a/lib/libc/rpc/getrpcport.3 b/lib/libc/rpc/getrpcport.3
new file mode 100644
index 0000000..b4fa812
--- /dev/null
+++ b/lib/libc/rpc/getrpcport.3
@@ -0,0 +1,31 @@
+.\" @(#)getrpcport.3r 2.2 88/08/02 4.0 RPCSRC; from 1.12 88/02/26 SMI
+.\" $FreeBSD$
+.\"
+.Dd October 6, 1987
+.Dt GETRPCPORT 3
+.Os
+.Sh NAME
+.Nm getrpcport
+.Nd get RPC port number
+.Sh SYNOPSIS
+.Ft int
+.Fn getrpcport "char *host" "int prognum" "int versnum" "int proto"
+.Sh DESCRIPTION
+.Fn getrpcport
+returns the port number for version
+.Fa versnum
+of the RPC program
+.Fa prognum
+running on
+.Fa host
+and using protocol
+.Fa proto .
+It returns 0 if it cannot contact the portmapper, or if
+.Fa prognum
+is not registered. If
+.Fa prognum
+is registered but not with version
+.Fa versnum ,
+it will still return a port number (for some version of the program)
+indicating that the program is indeed registered.
+The version mismatch will be detected upon the first call to the service.
diff --git a/lib/libc/rpc/getrpcport.c b/lib/libc/rpc/getrpcport.c
new file mode 100644
index 0000000..24c6257f
--- /dev/null
+++ b/lib/libc/rpc/getrpcport.c
@@ -0,0 +1,63 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getrpcport.c 1.3 87/08/11 SMI";*/
+/*static char *sccsid = "from: @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+int
+getrpcport(host, prognum, versnum, proto)
+ char *host;
+ int prognum, versnum, proto;
+{
+ struct sockaddr_in addr;
+ struct hostent *hp;
+
+ if ((hp = gethostbyname(host)) == NULL)
+ return (0);
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_len = sizeof(struct sockaddr_in);
+ addr.sin_family = AF_INET;
+ addr.sin_port = 0;
+ memcpy((char *)&addr.sin_addr, hp->h_addr, hp->h_length);
+ return (pmap_getport(&addr, prognum, versnum, proto));
+}
diff --git a/lib/libc/rpc/key_call.c b/lib/libc/rpc/key_call.c
new file mode 100644
index 0000000..bcef22e
--- /dev/null
+++ b/lib/libc/rpc/key_call.c
@@ -0,0 +1,425 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1986-1991 by Sun Microsystems Inc.
+ */
+
+#ident "@(#)key_call.c 1.25 94/04/24 SMI"
+
+/*
+ * key_call.c, Interface to keyserver
+ *
+ * setsecretkey(key) - set your secret key
+ * encryptsessionkey(agent, deskey) - encrypt a session key to talk to agent
+ * decryptsessionkey(agent, deskey) - decrypt ditto
+ * gendeskey(deskey) - generate a secure des key
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <rpc/rpc.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+#include <rpc/key_prot.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/fcntl.h>
+
+
+#define KEY_TIMEOUT 5 /* per-try timeout in seconds */
+#define KEY_NRETRY 12 /* number of retries */
+
+#ifdef DEBUG
+#define debug(msg) (void) fprintf(stderr, "%s\n", msg);
+#else
+#define debug(msg)
+#endif /* DEBUG */
+
+/*
+ * Hack to allow the keyserver to use AUTH_DES (for authenticated
+ * NIS+ calls, for example). The only functions that get called
+ * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
+ *
+ * The approach is to have the keyserver fill in pointers to local
+ * implementations of these functions, and to call those in key_call().
+ */
+
+cryptkeyres *(*__key_encryptsession_pk_LOCAL)() = 0;
+cryptkeyres *(*__key_decryptsession_pk_LOCAL)() = 0;
+des_block *(*__key_gendes_LOCAL)() = 0;
+
+static int key_call __P(( u_long, xdrproc_t, char *, xdrproc_t, char * ));
+
+int
+key_setsecret(secretkey)
+ const char *secretkey;
+{
+ keystatus status;
+
+ if (!key_call((u_long) KEY_SET, xdr_keybuf, (char *) secretkey,
+ xdr_keystatus, (char *)&status)) {
+ return (-1);
+ }
+ if (status != KEY_SUCCESS) {
+ debug("set status is nonzero");
+ return (-1);
+ }
+ return (0);
+}
+
+
+/* key_secretkey_is_set() returns 1 if the keyserver has a secret key
+ * stored for the caller's effective uid; it returns 0 otherwise
+ *
+ * N.B.: The KEY_NET_GET key call is undocumented. Applications shouldn't
+ * be using it, because it allows them to get the user's secret key.
+ */
+
+int
+key_secretkey_is_set(void)
+{
+ struct key_netstres kres;
+
+ memset((void*)&kres, 0, sizeof (kres));
+ if (key_call((u_long) KEY_NET_GET, xdr_void, (char *)NULL,
+ xdr_key_netstres, (char *) &kres) &&
+ (kres.status == KEY_SUCCESS) &&
+ (kres.key_netstres_u.knet.st_priv_key[0] != 0)) {
+ /* avoid leaving secret key in memory */
+ memset(kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES);
+ return (1);
+ }
+ return (0);
+}
+
+int
+key_encryptsession_pk(remotename, remotekey, deskey)
+ char *remotename;
+ netobj *remotekey;
+ des_block *deskey;
+{
+ cryptkeyarg2 arg;
+ cryptkeyres res;
+
+ arg.remotename = remotename;
+ arg.remotekey = *remotekey;
+ arg.deskey = *deskey;
+ if (!key_call((u_long)KEY_ENCRYPT_PK, xdr_cryptkeyarg2, (char *)&arg,
+ xdr_cryptkeyres, (char *)&res)) {
+ return (-1);
+ }
+ if (res.status != KEY_SUCCESS) {
+ debug("encrypt status is nonzero");
+ return (-1);
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return (0);
+}
+
+int
+key_decryptsession_pk(remotename, remotekey, deskey)
+ char *remotename;
+ netobj *remotekey;
+ des_block *deskey;
+{
+ cryptkeyarg2 arg;
+ cryptkeyres res;
+
+ arg.remotename = remotename;
+ arg.remotekey = *remotekey;
+ arg.deskey = *deskey;
+ if (!key_call((u_long)KEY_DECRYPT_PK, xdr_cryptkeyarg2, (char *)&arg,
+ xdr_cryptkeyres, (char *)&res)) {
+ return (-1);
+ }
+ if (res.status != KEY_SUCCESS) {
+ debug("decrypt status is nonzero");
+ return (-1);
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return (0);
+}
+
+int
+key_encryptsession(remotename, deskey)
+ const char *remotename;
+ des_block *deskey;
+{
+ cryptkeyarg arg;
+ cryptkeyres res;
+
+ arg.remotename = (char *) remotename;
+ arg.deskey = *deskey;
+ if (!key_call((u_long)KEY_ENCRYPT, xdr_cryptkeyarg, (char *)&arg,
+ xdr_cryptkeyres, (char *)&res)) {
+ return (-1);
+ }
+ if (res.status != KEY_SUCCESS) {
+ debug("encrypt status is nonzero");
+ return (-1);
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return (0);
+}
+
+int
+key_decryptsession(remotename, deskey)
+ const char *remotename;
+ des_block *deskey;
+{
+ cryptkeyarg arg;
+ cryptkeyres res;
+
+ arg.remotename = (char *) remotename;
+ arg.deskey = *deskey;
+ if (!key_call((u_long)KEY_DECRYPT, xdr_cryptkeyarg, (char *)&arg,
+ xdr_cryptkeyres, (char *)&res)) {
+ return (-1);
+ }
+ if (res.status != KEY_SUCCESS) {
+ debug("decrypt status is nonzero");
+ return (-1);
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return (0);
+}
+
+int
+key_gendes(key)
+ des_block *key;
+{
+ if (!key_call((u_long)KEY_GEN, xdr_void, (char *)NULL,
+ xdr_des_block, (char *)key)) {
+ return (-1);
+ }
+ return (0);
+}
+
+int
+key_setnet(arg)
+struct netstarg *arg;
+{
+ keystatus status;
+
+
+ if (!key_call((u_long) KEY_NET_PUT, xdr_key_netstarg, (char *) arg,
+ xdr_keystatus, (char *) &status)){
+ return (-1);
+ }
+
+ if (status != KEY_SUCCESS) {
+ debug("key_setnet status is nonzero");
+ return (-1);
+ }
+ return (1);
+}
+
+
+int
+key_get_conv(pkey, deskey)
+ char *pkey;
+ des_block *deskey;
+{
+ cryptkeyres res;
+
+ if (!key_call((u_long) KEY_GET_CONV, xdr_keybuf, pkey,
+ xdr_cryptkeyres, (char *)&res)) {
+ return (-1);
+ }
+ if (res.status != KEY_SUCCESS) {
+ debug("get_conv status is nonzero");
+ return (-1);
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return (0);
+}
+
+struct key_call_private {
+ CLIENT *client; /* Client handle */
+ pid_t pid; /* process-id at moment of creation */
+ uid_t uid; /* user-id at last authorization */
+};
+static struct key_call_private *key_call_private_main = NULL;
+
+#ifdef foo
+static void
+key_call_destroy(void *vp)
+{
+ register struct key_call_private *kcp = (struct key_call_private *)vp;
+
+ if (kcp) {
+ if (kcp->client)
+ clnt_destroy(kcp->client);
+ free(kcp);
+ }
+}
+#endif
+
+/*
+ * Keep the handle cached. This call may be made quite often.
+ */
+static CLIENT *
+getkeyserv_handle(vers)
+int vers;
+{
+ struct key_call_private *kcp = key_call_private_main;
+ struct timeval wait_time;
+ int fd;
+ struct sockaddr_un name;
+ int namelen = sizeof(struct sockaddr_un);
+
+#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */
+#define TOTAL_TRIES 5 /* Number of tries */
+
+ if (kcp == (struct key_call_private *)NULL) {
+ kcp = (struct key_call_private *)malloc(sizeof (*kcp));
+ if (kcp == (struct key_call_private *)NULL) {
+ return ((CLIENT *) NULL);
+ }
+ key_call_private_main = kcp;
+ kcp->client = NULL;
+ }
+
+ /* if pid has changed, destroy client and rebuild */
+ if (kcp->client != NULL && kcp->pid != getpid()) {
+ clnt_destroy(kcp->client);
+ kcp->client = NULL;
+ }
+
+ if (kcp->client != NULL) {
+ /* if other side closed socket, build handle again */
+ clnt_control(kcp->client, CLGET_FD, (char *)&fd);
+ if (getpeername(fd,(struct sockaddr *)&name,&namelen) == -1) {
+ auth_destroy(kcp->client->cl_auth);
+ clnt_destroy(kcp->client);
+ kcp->client = NULL;
+ }
+ }
+
+ if (kcp->client != NULL) {
+ /* if uid has changed, build client handle again */
+ if (kcp->uid != geteuid()) {
+ kcp->uid = geteuid();
+ auth_destroy(kcp->client->cl_auth);
+ kcp->client->cl_auth =
+ authsys_create("", kcp->uid, 0, 0, NULL);
+ if (kcp->client->cl_auth == NULL) {
+ clnt_destroy(kcp->client);
+ kcp->client = NULL;
+ return ((CLIENT *) NULL);
+ }
+ }
+ /* Change the version number to the new one */
+ clnt_control(kcp->client, CLSET_VERS, (void *)&vers);
+ return (kcp->client);
+ }
+
+ if ((kcp->client == (CLIENT *) NULL))
+ /* Use the AF_UNIX transport */
+ kcp->client = clnt_create("/var/run/keyservsock", KEY_PROG,
+ vers, "unix");
+
+ if (kcp->client == (CLIENT *) NULL) {
+ return ((CLIENT *) NULL);
+ }
+ kcp->uid = geteuid();
+ kcp->pid = getpid();
+ kcp->client->cl_auth = authsys_create("", kcp->uid, 0, 0, NULL);
+ if (kcp->client->cl_auth == NULL) {
+ clnt_destroy(kcp->client);
+ kcp->client = NULL;
+ return ((CLIENT *) NULL);
+ }
+
+ wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES;
+ wait_time.tv_usec = 0;
+ (void) clnt_control(kcp->client, CLSET_RETRY_TIMEOUT,
+ (char *)&wait_time);
+ if (clnt_control(kcp->client, CLGET_FD, (char *)&fd))
+ fcntl(fd, F_SETFD, 1); /* make it "close on exec" */
+
+ return (kcp->client);
+}
+
+/* returns 0 on failure, 1 on success */
+
+static int
+key_call(proc, xdr_arg, arg, xdr_rslt, rslt)
+ u_long proc;
+ xdrproc_t xdr_arg;
+ char *arg;
+ xdrproc_t xdr_rslt;
+ char *rslt;
+{
+ CLIENT *clnt;
+ struct timeval wait_time;
+
+ if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL) {
+ cryptkeyres *res;
+ res = (*__key_encryptsession_pk_LOCAL)(geteuid(), arg);
+ *(cryptkeyres*)rslt = *res;
+ return (1);
+ } else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL) {
+ cryptkeyres *res;
+ res = (*__key_decryptsession_pk_LOCAL)(geteuid(), arg);
+ *(cryptkeyres*)rslt = *res;
+ return (1);
+ } else if (proc == KEY_GEN && __key_gendes_LOCAL) {
+ des_block *res;
+ res = (*__key_gendes_LOCAL)(geteuid(), 0);
+ *(des_block*)rslt = *res;
+ return (1);
+ }
+
+ if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) ||
+ (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) ||
+ (proc == KEY_GET_CONV))
+ clnt = getkeyserv_handle(2); /* talk to version 2 */
+ else
+ clnt = getkeyserv_handle(1); /* talk to version 1 */
+
+ if (clnt == NULL) {
+ return (0);
+ }
+
+ wait_time.tv_sec = TOTAL_TIMEOUT;
+ wait_time.tv_usec = 0;
+
+ if (clnt_call(clnt, proc, xdr_arg, arg, xdr_rslt, rslt,
+ wait_time) == RPC_SUCCESS) {
+ return (1);
+ } else {
+ return (0);
+ }
+}
diff --git a/lib/libc/rpc/key_prot_xdr.c b/lib/libc/rpc/key_prot_xdr.c
new file mode 100644
index 0000000..8cd6b6b
--- /dev/null
+++ b/lib/libc/rpc/key_prot_xdr.c
@@ -0,0 +1,166 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include <rpc/key_prot.h>
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI"
+
+/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */
+
+/*
+ * Compiled from key_prot.x using rpcgen.
+ * DO NOT EDIT THIS FILE!
+ * This is NOT source code!
+ */
+
+bool_t
+xdr_keystatus(register XDR *xdrs, keystatus *objp)
+{
+
+ if (!xdr_enum(xdrs, (enum_t *)objp))
+ return (FALSE);
+ return (TRUE);
+}
+
+bool_t
+xdr_keybuf(register XDR *xdrs, keybuf objp)
+{
+
+ if (!xdr_opaque(xdrs, objp, HEXKEYBYTES))
+ return (FALSE);
+ return (TRUE);
+}
+
+bool_t
+xdr_netnamestr(register XDR *xdrs, netnamestr *objp)
+{
+
+ if (!xdr_string(xdrs, objp, MAXNETNAMELEN))
+ return (FALSE);
+ return (TRUE);
+}
+
+bool_t
+xdr_cryptkeyarg(register XDR *xdrs, cryptkeyarg *objp)
+{
+
+ if (!xdr_netnamestr(xdrs, &objp->remotename))
+ return (FALSE);
+ if (!xdr_des_block(xdrs, &objp->deskey))
+ return (FALSE);
+ return (TRUE);
+}
+
+bool_t
+xdr_cryptkeyarg2(register XDR *xdrs, cryptkeyarg2 *objp)
+{
+
+ if (!xdr_netnamestr(xdrs, &objp->remotename))
+ return (FALSE);
+ if (!xdr_netobj(xdrs, &objp->remotekey))
+ return (FALSE);
+ if (!xdr_des_block(xdrs, &objp->deskey))
+ return (FALSE);
+ return (TRUE);
+}
+
+bool_t
+xdr_cryptkeyres(register XDR *xdrs, cryptkeyres *objp)
+{
+
+ if (!xdr_keystatus(xdrs, &objp->status))
+ return (FALSE);
+ switch (objp->status) {
+ case KEY_SUCCESS:
+ if (!xdr_des_block(xdrs, &objp->cryptkeyres_u.deskey))
+ return (FALSE);
+ break;
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_unixcred(register XDR *xdrs, unixcred *objp)
+{
+
+ if (!xdr_u_int(xdrs, &objp->uid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->gid))
+ return (FALSE);
+ if (!xdr_array(xdrs, (char **)&objp->gids.gids_val, (u_int *) &objp->gids.gids_len, MAXGIDS,
+ sizeof (u_int), (xdrproc_t) xdr_u_int))
+ return (FALSE);
+ return (TRUE);
+}
+
+bool_t
+xdr_getcredres(register XDR *xdrs, getcredres *objp)
+{
+
+ if (!xdr_keystatus(xdrs, &objp->status))
+ return (FALSE);
+ switch (objp->status) {
+ case KEY_SUCCESS:
+ if (!xdr_unixcred(xdrs, &objp->getcredres_u.cred))
+ return (FALSE);
+ break;
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_key_netstarg(register XDR *xdrs, key_netstarg *objp)
+{
+
+ if (!xdr_keybuf(xdrs, objp->st_priv_key))
+ return (FALSE);
+ if (!xdr_keybuf(xdrs, objp->st_pub_key))
+ return (FALSE);
+ if (!xdr_netnamestr(xdrs, &objp->st_netname))
+ return (FALSE);
+ return (TRUE);
+}
+
+bool_t
+xdr_key_netstres(register XDR *xdrs, key_netstres *objp)
+{
+
+ if (!xdr_keystatus(xdrs, &objp->status))
+ return (FALSE);
+ switch (objp->status) {
+ case KEY_SUCCESS:
+ if (!xdr_key_netstarg(xdrs, &objp->key_netstres_u.knet))
+ return (FALSE);
+ break;
+ }
+ return (TRUE);
+}
diff --git a/lib/libc/rpc/netname.c b/lib/libc/rpc/netname.c
new file mode 100644
index 0000000..22167be
--- /dev/null
+++ b/lib/libc/rpc/netname.c
@@ -0,0 +1,136 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)netname.c 1.8 91/03/11 Copyr 1986 Sun Micro";
+#endif
+
+/*
+ * netname utility routines
+ * convert from unix names to network names and vice-versa
+ * This module is operating system dependent!
+ * What we define here will work with any unix system that has adopted
+ * the sun NIS domain architecture.
+ */
+
+#include <sys/param.h>
+#include <rpc/rpc.h>
+#include <rpc/rpc_com.h>
+#ifdef YP
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
+#ifndef NGROUPS
+#define NGROUPS 16
+#endif
+
+static char *OPSYS = "unix";
+
+/*
+ * Figure out my fully qualified network name
+ */
+int
+getnetname(name)
+ char name[MAXNETNAMELEN+1];
+{
+ uid_t uid;
+
+ uid = geteuid();
+ if (uid == 0) {
+ return (host2netname(name, (char *) NULL, (char *) NULL));
+ } else {
+ return (user2netname(name, uid, (char *) NULL));
+ }
+}
+
+
+/*
+ * Convert unix cred to network-name
+ */
+int
+user2netname(netname, uid, domain)
+ char netname[MAXNETNAMELEN + 1];
+ uid_t uid;
+ char *domain;
+{
+ char *dfltdom;
+
+#define MAXIPRINT (11) /* max length of printed integer */
+
+ if (domain == NULL) {
+ if (_rpc_get_default_domain(&dfltdom) != 0) {
+ return (0);
+ }
+ domain = dfltdom;
+ }
+ if (strlen(domain) + 1 + MAXIPRINT > MAXNETNAMELEN) {
+ return (0);
+ }
+ (void) sprintf(netname, "%s.%ld@%s", OPSYS, (u_long)uid, domain);
+ return (1);
+}
+
+
+/*
+ * Convert host to network-name
+ */
+int
+host2netname(netname, host, domain)
+ char netname[MAXNETNAMELEN + 1];
+ char *host;
+ char *domain;
+{
+ char *dfltdom;
+ char hostname[MAXHOSTNAMELEN+1];
+
+ if (domain == NULL) {
+ if (_rpc_get_default_domain(&dfltdom) != 0) {
+ return (0);
+ }
+ domain = dfltdom;
+ }
+ if (host == NULL) {
+ (void) gethostname(hostname, sizeof(hostname));
+ host = hostname;
+ }
+ if (strlen(domain) + 1 + strlen(host) > MAXNETNAMELEN) {
+ return (0);
+ }
+ (void) sprintf(netname, "%s.%s@%s", OPSYS, host, domain);
+ return (1);
+}
diff --git a/lib/libc/rpc/netnamer.c b/lib/libc/rpc/netnamer.c
new file mode 100644
index 0000000..26e58b0
--- /dev/null
+++ b/lib/libc/rpc/netnamer.c
@@ -0,0 +1,324 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
+#endif
+/*
+ * netname utility routines convert from unix names to network names and
+ * vice-versa This module is operating system dependent! What we define here
+ * will work with any unix system that has adopted the sun NIS domain
+ * architecture.
+ */
+#include <sys/param.h>
+#include <rpc/rpc.h>
+#include <rpc/rpc_com.h>
+#ifdef YP
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+#include <ctype.h>
+#include <stdio.h>
+#include <grp.h>
+#include <pwd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static char *OPSYS = "unix";
+static char *NETID = "netid.byname";
+static char *NETIDFILE = "/etc/netid";
+
+static int getnetid __P(( char *, char * ));
+static int _getgroups __P(( char *, gid_t * ));
+
+#ifndef NGROUPS
+#define NGROUPS 16
+#endif
+
+/*
+ * Convert network-name into unix credential
+ */
+int
+netname2user(netname, uidp, gidp, gidlenp, gidlist)
+ char netname[MAXNETNAMELEN + 1];
+ uid_t *uidp;
+ gid_t *gidp;
+ int *gidlenp;
+ gid_t *gidlist;
+{
+ char *p;
+ int gidlen;
+ uid_t uid;
+ long luid;
+ struct passwd *pwd;
+ char val[1024];
+ char *val1, *val2;
+ char *domain;
+ int vallen;
+ int err;
+
+ if (getnetid(netname, val)) {
+ p = strtok(val, ":");
+ if (p == NULL)
+ return (0);
+ *uidp = (uid_t) atol(val);
+ p = strtok(NULL, "\n,");
+ *gidp = (gid_t) atol(p);
+ if (p == NULL) {
+ return (0);
+ }
+ gidlen = 0;
+ for (gidlen = 0; gidlen < NGROUPS; gidlen++) {
+ p = strtok(NULL, "\n,");
+ if (p == NULL)
+ break;
+ gidlist[gidlen] = (gid_t) atol(p);
+ }
+ *gidlenp = gidlen;
+
+ return (1);
+ }
+ val1 = strchr(netname, '.');
+ if (val1 == NULL)
+ return (0);
+ if (strncmp(netname, OPSYS, (val1-netname)))
+ return (0);
+ val1++;
+ val2 = strchr(val1, '@');
+ if (val2 == NULL)
+ return (0);
+ vallen = val2 - val1;
+ if (vallen > (1024 - 1))
+ vallen = 1024 - 1;
+ (void) strncpy(val, val1, 1024);
+ val[vallen] = 0;
+
+ err = _rpc_get_default_domain(&domain); /* change to rpc */
+ if (err)
+ return (0);
+
+ if (strcmp(val2 + 1, domain))
+ return (0); /* wrong domain */
+
+ if (sscanf(val, "%ld", &luid) != 1)
+ return (0);
+ uid = luid;
+
+ /* use initgroups method */
+ pwd = getpwuid(uid);
+ if (pwd == NULL)
+ return (0);
+ *uidp = pwd->pw_uid;
+ *gidp = pwd->pw_gid;
+ *gidlenp = _getgroups(pwd->pw_name, gidlist);
+ return (1);
+}
+
+/*
+ * initgroups
+ */
+
+static int
+_getgroups(uname, groups)
+ char *uname;
+ gid_t groups[NGROUPS];
+{
+ gid_t ngroups = 0;
+ register struct group *grp;
+ register int i;
+ register int j;
+ int filter;
+
+ setgrent();
+ while ((grp = getgrent())) {
+ for (i = 0; grp->gr_mem[i]; i++)
+ if (!strcmp(grp->gr_mem[i], uname)) {
+ if (ngroups == NGROUPS) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "initgroups: %s is in too many groups\n", uname);
+#endif
+ goto toomany;
+ }
+ /* filter out duplicate group entries */
+ filter = 0;
+ for (j = 0; j < ngroups; j++)
+ if (groups[j] == grp->gr_gid) {
+ filter++;
+ break;
+ }
+ if (!filter)
+ groups[ngroups++] = grp->gr_gid;
+ }
+ }
+toomany:
+ endgrent();
+ return (ngroups);
+}
+
+/*
+ * Convert network-name to hostname
+ */
+int
+netname2host(netname, hostname, hostlen)
+ char netname[MAXNETNAMELEN + 1];
+ char *hostname;
+ int hostlen;
+{
+ int err;
+ char valbuf[1024];
+ char *val;
+ char *val2;
+ int vallen;
+ char *domain;
+
+ if (getnetid(netname, valbuf)) {
+ val = valbuf;
+ if ((*val == '0') && (val[1] == ':')) {
+ (void) strncpy(hostname, val + 2, hostlen);
+ return (1);
+ }
+ }
+ val = strchr(netname, '.');
+ if (val == NULL)
+ return (0);
+ if (strncmp(netname, OPSYS, (val - netname)))
+ return (0);
+ val++;
+ val2 = strchr(val, '@');
+ if (val2 == NULL)
+ return (0);
+ vallen = val2 - val;
+ if (vallen > (hostlen - 1))
+ vallen = hostlen - 1;
+ (void) strncpy(hostname, val, vallen);
+ hostname[vallen] = 0;
+
+ err = _rpc_get_default_domain(&domain); /* change to rpc */
+ if (err)
+ return (0);
+
+ if (strcmp(val2 + 1, domain))
+ return (0); /* wrong domain */
+ else
+ return (1);
+}
+
+/*
+ * reads the file /etc/netid looking for a + to optionally go to the
+ * network information service.
+ */
+int
+getnetid(key, ret)
+ char *key, *ret;
+{
+ char buf[1024]; /* big enough */
+ char *res;
+ char *mkey;
+ char *mval;
+ FILE *fd;
+#ifdef YP
+ char *domain;
+ int err;
+ char *lookup;
+ int len;
+#endif
+
+ fd = fopen(NETIDFILE, "r");
+ if (fd == (FILE *) 0) {
+#ifdef YP
+ res = "+";
+ goto getnetidyp;
+#else
+ return (0);
+#endif
+ }
+ for (;;) {
+ if (fd == (FILE *) 0)
+ return (0); /* getnetidyp brings us here */
+ res = fgets(buf, 1024, fd);
+ if (res == 0) {
+ fclose(fd);
+ return (0);
+ }
+ if (res[0] == '#')
+ continue;
+ else if (res[0] == '+') {
+#ifdef YP
+ getnetidyp:
+ err = yp_get_default_domain(&domain);
+ if (err) {
+ continue;
+ }
+ lookup = NULL;
+ err = yp_match(domain, NETID, key,
+ strlen(key), &lookup, &len);
+ if (err) {
+#ifdef DEBUG
+ fprintf(stderr, "match failed error %d\n", err);
+#endif
+ continue;
+ }
+ lookup[len] = 0;
+ strcpy(ret, lookup);
+ free(lookup);
+ if (fd != NULL)
+ fclose(fd);
+ return (2);
+#else /* YP */
+#ifdef DEBUG
+ fprintf(stderr,
+"Bad record in %s '+' -- NIS not supported in this library copy\n",
+ NETIDFILE);
+#endif
+ continue;
+#endif /* YP */
+ } else {
+ mkey = strtok(buf, "\t ");
+ if (mkey == NULL) {
+ fprintf(stderr,
+ "Bad record in %s -- %s", NETIDFILE, buf);
+ continue;
+ }
+ mval = strtok(NULL, " \t#\n");
+ if (mval == NULL) {
+ fprintf(stderr,
+ "Bad record in %s val problem - %s", NETIDFILE, buf);
+ continue;
+ }
+ if (strcmp(mkey, key) == 0) {
+ strcpy(ret, mval);
+ fclose(fd);
+ return (1);
+
+ }
+ }
+ }
+}
diff --git a/lib/libc/rpc/pmap_clnt.c b/lib/libc/rpc/pmap_clnt.c
new file mode 100644
index 0000000..67d1d89
--- /dev/null
+++ b/lib/libc/rpc/pmap_clnt.c
@@ -0,0 +1,149 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * pmap_clnt.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <netinet/in.h>
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+void clnt_perror();
+
+#ifndef PORTMAPSOCK
+#define PORTMAPSOCK "/var/run/portmapsock"
+#endif
+
+/*
+ * Set a mapping between program,version and port.
+ * Calls the pmap service remotely to do the mapping.
+ */
+bool_t
+pmap_set(program, version, protocol, port)
+ u_long program;
+ u_long version;
+ int protocol;
+ u_short port;
+{
+ struct sockaddr_in myaddress;
+ int socket = -1;
+ register CLIENT *client;
+ struct pmap parms;
+ bool_t rslt;
+ struct stat st;
+
+ /*
+ * Temporary hack for backwards compatibility. Eventually
+ * this test will go away and we'll use only the "unix" transport.
+ */
+ if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK)
+ client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix");
+ else {
+ if (get_myaddress(&myaddress) != 0)
+ return (FALSE);
+ myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
+ timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ }
+
+ if (client == (CLIENT *)NULL)
+ return (FALSE);
+ parms.pm_prog = program;
+ parms.pm_vers = version;
+ parms.pm_prot = protocol;
+ parms.pm_port = port;
+ if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt,
+ tottimeout) != RPC_SUCCESS) {
+ clnt_perror(client, "Cannot register service");
+ return (FALSE);
+ }
+ CLNT_DESTROY(client);
+ if (socket != -1)
+ (void)close(socket);
+ return (rslt);
+}
+
+/*
+ * Remove the mapping between program,version and port.
+ * Calls the pmap service remotely to do the un-mapping.
+ */
+bool_t
+pmap_unset(program, version)
+ u_long program;
+ u_long version;
+{
+ struct sockaddr_in myaddress;
+ int socket = -1;
+ register CLIENT *client;
+ struct pmap parms;
+ bool_t rslt;
+ struct stat st;
+
+ /*
+ * Temporary hack for backwards compatibility. Eventually
+ * this test will go away and we'll use only the "unix" transport.
+ */
+ if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK)
+ client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix");
+ else {
+ if (get_myaddress(&myaddress) != 0)
+ return (FALSE);
+ myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
+ timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ }
+ if (client == (CLIENT *)NULL)
+ return (FALSE);
+ parms.pm_prog = program;
+ parms.pm_vers = version;
+ parms.pm_port = parms.pm_prot = 0;
+ CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt,
+ tottimeout);
+ CLNT_DESTROY(client);
+ if (socket != -1)
+ (void)close(socket);
+ return (rslt);
+}
diff --git a/lib/libc/rpc/pmap_getmaps.c b/lib/libc/rpc/pmap_getmaps.c
new file mode 100644
index 0000000..098ba17
--- /dev/null
+++ b/lib/libc/rpc/pmap_getmaps.c
@@ -0,0 +1,86 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * pmap_getmap.c
+ * Client interface to pmap rpc service.
+ * contains pmap_getmaps, which is only tcp service involved
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#define NAMELEN 255
+#define MAX_BROADCAST_SIZE 1400
+
+/*
+ * Get a copy of the current port maps.
+ * Calls the pmap service remotely to do get the maps.
+ */
+struct pmaplist *
+pmap_getmaps(address)
+ struct sockaddr_in *address;
+{
+ struct pmaplist *head = (struct pmaplist *)NULL;
+ int socket = -1;
+ struct timeval minutetimeout;
+ register CLIENT *client;
+
+ minutetimeout.tv_sec = 60;
+ minutetimeout.tv_usec = 0;
+ address->sin_port = htons(PMAPPORT);
+ client = clnttcp_create(address, PMAPPROG,
+ PMAPVERS, &socket, 50, 500);
+ if (client != (CLIENT *)NULL) {
+ if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist,
+ &head, minutetimeout) != RPC_SUCCESS) {
+ clnt_perror(client, "pmap_getmaps rpc problem");
+ }
+ CLNT_DESTROY(client);
+ }
+ if (socket != -1)
+ (void)close(socket);
+ address->sin_port = 0;
+ return (head);
+}
diff --git a/lib/libc/rpc/pmap_getport.c b/lib/libc/rpc/pmap_getport.c
new file mode 100644
index 0000000..29a26ca
--- /dev/null
+++ b/lib/libc/rpc/pmap_getport.c
@@ -0,0 +1,91 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * pmap_getport.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <unistd.h>
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+/*
+ * Find the mapped port for program,version.
+ * Calls the pmap service remotely to do the lookup.
+ * Returns 0 if no map exists.
+ */
+u_short
+pmap_getport(address, program, version, protocol)
+ struct sockaddr_in *address;
+ u_long program;
+ u_long version;
+ u_int protocol;
+{
+ u_short port = 0;
+ int socket = -1;
+ register CLIENT *client;
+ struct pmap parms;
+
+ address->sin_port = htons(PMAPPORT);
+ client = clntudp_bufcreate(address, PMAPPROG,
+ PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ if (client != (CLIENT *)NULL) {
+ parms.pm_prog = program;
+ parms.pm_vers = version;
+ parms.pm_prot = protocol;
+ parms.pm_port = 0; /* not needed or used */
+ if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms,
+ xdr_u_short, &port, tottimeout) != RPC_SUCCESS){
+ rpc_createerr.cf_stat = RPC_PMAPFAILURE;
+ clnt_geterr(client, &rpc_createerr.cf_error);
+ } else if (port == 0) {
+ rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
+ }
+ CLNT_DESTROY(client);
+ }
+ if (socket != -1)
+ (void)close(socket);
+ address->sin_port = 0;
+ return (port);
+}
diff --git a/lib/libc/rpc/pmap_prot.c b/lib/libc/rpc/pmap_prot.c
new file mode 100644
index 0000000..f424842
--- /dev/null
+++ b/lib/libc/rpc/pmap_prot.c
@@ -0,0 +1,59 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * pmap_prot.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+bool_t
+xdr_pmap(xdrs, regs)
+ XDR *xdrs;
+ struct pmap *regs;
+{
+
+ if (xdr_u_long(xdrs, &regs->pm_prog) &&
+ xdr_u_long(xdrs, &regs->pm_vers) &&
+ xdr_u_long(xdrs, &regs->pm_prot))
+ return (xdr_u_long(xdrs, &regs->pm_port));
+ return (FALSE);
+}
diff --git a/lib/libc/rpc/pmap_prot2.c b/lib/libc/rpc/pmap_prot2.c
new file mode 100644
index 0000000..9c5230d
--- /dev/null
+++ b/lib/libc/rpc/pmap_prot2.c
@@ -0,0 +1,118 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * pmap_prot2.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+/*
+ * What is going on with linked lists? (!)
+ * First recall the link list declaration from pmap_prot.h:
+ *
+ * struct pmaplist {
+ * struct pmap pml_map;
+ * struct pmaplist *pml_map;
+ * };
+ *
+ * Compare that declaration with a corresponding xdr declaration that
+ * is (a) pointer-less, and (b) recursive:
+ *
+ * typedef union switch (bool_t) {
+ *
+ * case TRUE: struct {
+ * struct pmap;
+ * pmaplist_t foo;
+ * };
+ *
+ * case FALSE: struct {};
+ * } pmaplist_t;
+ *
+ * Notice that the xdr declaration has no nxt pointer while
+ * the C declaration has no bool_t variable. The bool_t can be
+ * interpreted as ``more data follows me''; if FALSE then nothing
+ * follows this bool_t; if TRUE then the bool_t is followed by
+ * an actual struct pmap, and then (recursively) by the
+ * xdr union, pamplist_t.
+ *
+ * This could be implemented via the xdr_union primitive, though this
+ * would cause a one recursive call per element in the list. Rather than do
+ * that we can ``unwind'' the recursion
+ * into a while loop and do the union arms in-place.
+ *
+ * The head of the list is what the C programmer wishes to past around
+ * the net, yet is the data that the pointer points to which is interesting;
+ * this sounds like a job for xdr_reference!
+ */
+bool_t
+xdr_pmaplist(xdrs, rp)
+ register XDR *xdrs;
+ register struct pmaplist **rp;
+{
+ /*
+ * more_elements is pre-computed in case the direction is
+ * XDR_ENCODE or XDR_FREE. more_elements is overwritten by
+ * xdr_bool when the direction is XDR_DECODE.
+ */
+ bool_t more_elements;
+ register int freeing = (xdrs->x_op == XDR_FREE);
+ register struct pmaplist **next = NULL;
+
+ while (TRUE) {
+ more_elements = (bool_t)(*rp != NULL);
+ if (! xdr_bool(xdrs, &more_elements))
+ return (FALSE);
+ if (! more_elements)
+ return (TRUE); /* we are done */
+ /*
+ * the unfortunate side effect of non-recursion is that in
+ * the case of freeing we must remember the next object
+ * before we free the current object ...
+ */
+ if (freeing)
+ next = &((*rp)->pml_next);
+ if (! xdr_reference(xdrs, (caddr_t *)rp,
+ (u_int)sizeof(struct pmaplist), xdr_pmap))
+ return (FALSE);
+ rp = (freeing) ? next : &((*rp)->pml_next);
+ }
+}
diff --git a/lib/libc/rpc/pmap_rmt.c b/lib/libc/rpc/pmap_rmt.c
new file mode 100644
index 0000000..355f34b
--- /dev/null
+++ b/lib/libc/rpc/pmap_rmt.c
@@ -0,0 +1,415 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * pmap_rmt.c
+ * Client interface to pmap rpc service.
+ * remote call and broadcast service
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <rpc/pmap_rmt.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#define MAX_BROADCAST_SIZE 1400
+
+static struct timeval timeout = { 3, 0 };
+
+/*
+ * pmapper remote-call-service interface.
+ * This routine is used to call the pmapper remote call service
+ * which will look up a service program in the port maps, and then
+ * remotely call that routine with the given parameters. This allows
+ * programs to do a lookup and call in one step.
+*/
+enum clnt_stat
+pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr)
+ struct sockaddr_in *addr;
+ u_long prog, vers, proc;
+ xdrproc_t xdrargs, xdrres;
+ caddr_t argsp, resp;
+ struct timeval tout;
+ u_long *port_ptr;
+{
+ int socket = -1;
+ register CLIENT *client;
+ struct rmtcallargs a;
+ struct rmtcallres r;
+ enum clnt_stat stat;
+
+ addr->sin_port = htons(PMAPPORT);
+ client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket);
+ if (client != (CLIENT *)NULL) {
+ a.prog = prog;
+ a.vers = vers;
+ a.proc = proc;
+ a.args_ptr = argsp;
+ a.xdr_args = xdrargs;
+ r.port_ptr = port_ptr;
+ r.results_ptr = resp;
+ r.xdr_results = xdrres;
+ stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a,
+ xdr_rmtcallres, &r, tout);
+ CLNT_DESTROY(client);
+ } else {
+ stat = RPC_FAILED;
+ }
+ if (socket != -1)
+ (void)close(socket);
+ addr->sin_port = 0;
+ return (stat);
+}
+
+
+/*
+ * XDR remote call arguments
+ * written for XDR_ENCODE direction only
+ */
+bool_t
+xdr_rmtcall_args(xdrs, cap)
+ register XDR *xdrs;
+ register struct rmtcallargs *cap;
+{
+ u_int lenposition, argposition, position;
+
+ if (xdr_u_long(xdrs, &(cap->prog)) &&
+ xdr_u_long(xdrs, &(cap->vers)) &&
+ xdr_u_long(xdrs, &(cap->proc))) {
+ lenposition = XDR_GETPOS(xdrs);
+ if (! xdr_u_long(xdrs, &(cap->arglen)))
+ return (FALSE);
+ argposition = XDR_GETPOS(xdrs);
+ if (! (*(cap->xdr_args))(xdrs, cap->args_ptr))
+ return (FALSE);
+ position = XDR_GETPOS(xdrs);
+ cap->arglen = (u_long)position - (u_long)argposition;
+ XDR_SETPOS(xdrs, lenposition);
+ if (! xdr_u_long(xdrs, &(cap->arglen)))
+ return (FALSE);
+ XDR_SETPOS(xdrs, position);
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * XDR remote call results
+ * written for XDR_DECODE direction only
+ */
+bool_t
+xdr_rmtcallres(xdrs, crp)
+ register XDR *xdrs;
+ register struct rmtcallres *crp;
+{
+ caddr_t port_ptr;
+
+ port_ptr = (caddr_t)crp->port_ptr;
+ if (xdr_reference(xdrs, &port_ptr, sizeof (u_long),
+ xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) {
+ crp->port_ptr = (u_long *)port_ptr;
+ return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
+ }
+ return (FALSE);
+}
+
+
+/*
+ * The following is kludged-up support for simple rpc broadcasts.
+ * Someday a large, complicated system will replace these trivial
+ * routines which only support udp/ip .
+ */
+
+static int
+getbroadcastnets(addrs, sock, buf)
+ struct in_addr *addrs;
+ int sock; /* any valid socket will do */
+ char *buf; /* why allocxate more when we can use existing... */
+{
+ struct ifconf ifc;
+ struct ifreq ifreq, *ifr;
+ struct sockaddr_in *sin;
+ struct in_addr addr;
+ char *cp, *cplim;
+ int n, i = 0;
+
+ ifc.ifc_len = UDPMSGSIZE;
+ ifc.ifc_buf = buf;
+ if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
+ perror("broadcast: ioctl (get interface configuration)");
+ return (0);
+ }
+#define max(a, b) (a > b ? a : b)
+#define size(p) max((p).sa_len, sizeof(p))
+ cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
+ for (cp = buf; cp < cplim;
+ cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
+ ifr = (struct ifreq *)cp;
+ if (ifr->ifr_addr.sa_family != AF_INET)
+ continue;
+ ifreq = *ifr;
+ if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+ perror("broadcast: ioctl (get interface flags)");
+ continue;
+ }
+ if ((ifreq.ifr_flags & IFF_BROADCAST) &&
+ (ifreq.ifr_flags & IFF_UP)) {
+ sin = (struct sockaddr_in *)&ifr->ifr_addr;
+#ifdef SIOCGIFBRDADDR /* 4.3BSD */
+ if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
+ addr =
+ inet_makeaddr(inet_netof(sin->sin_addr),
+ INADDR_ANY);
+ } else {
+ addr = ((struct sockaddr_in*)
+ &ifreq.ifr_addr)->sin_addr;
+ }
+#else /* 4.2 BSD */
+ addr = inet_makeaddr(inet_netof(sin->sin_addr),
+ INADDR_ANY);
+#endif
+ for (n=i-1; n>=0; n--) {
+ if (addr.s_addr == addrs[n].s_addr)
+ break;
+ }
+ if (n<0) {
+ addrs[i++] = addr;
+ }
+ }
+ }
+ return (i);
+}
+
+typedef bool_t (*resultproc_t)();
+
+enum clnt_stat
+clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
+ u_long prog; /* program number */
+ u_long vers; /* version number */
+ u_long proc; /* procedure number */
+ xdrproc_t xargs; /* xdr routine for args */
+ caddr_t argsp; /* pointer to args */
+ xdrproc_t xresults; /* xdr routine for results */
+ caddr_t resultsp; /* pointer to results */
+ resultproc_t eachresult; /* call with each result obtained */
+{
+ enum clnt_stat stat;
+ AUTH *unix_auth = authunix_create_default();
+ XDR xdr_stream;
+ register XDR *xdrs = &xdr_stream;
+ int outlen, inlen, fromlen, nets;
+ register int sock;
+ int on = 1;
+ fd_set *fds, readfds;
+ register int i;
+ bool_t done = FALSE;
+ register u_long xid;
+ u_long port;
+ struct in_addr addrs[20];
+ struct sockaddr_in baddr, raddr; /* broadcast and response addresses */
+ struct rmtcallargs a;
+ struct rmtcallres r;
+ struct rpc_msg msg;
+ struct timeval t, tv;
+ char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
+ static u_int32_t disrupt;
+
+ if (disrupt == 0)
+ disrupt = (u_int32_t)(long)resultsp;
+
+ /*
+ * initialization: create a socket, a broadcast address, and
+ * preserialize the arguments into a send buffer.
+ */
+ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ perror("Cannot create socket for broadcast rpc");
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+#ifdef SO_BROADCAST
+ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
+ perror("Cannot set socket option SO_BROADCAST");
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+#endif /* def SO_BROADCAST */
+ if (sock + 1 > FD_SETSIZE) {
+ int bytes = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL) {
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+ memset(fds, 0, bytes);
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ nets = getbroadcastnets(addrs, sock, inbuf);
+ memset(&baddr, 0, sizeof (baddr));
+ baddr.sin_len = sizeof(struct sockaddr_in);
+ baddr.sin_family = AF_INET;
+ baddr.sin_port = htons(PMAPPORT);
+ baddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ (void)gettimeofday(&t, (struct timezone *)0);
+ msg.rm_xid = xid = (++disrupt) ^ getpid() ^ t.tv_sec ^ t.tv_usec;
+ t.tv_usec = 0;
+ msg.rm_direction = CALL;
+ msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ msg.rm_call.cb_prog = PMAPPROG;
+ msg.rm_call.cb_vers = PMAPVERS;
+ msg.rm_call.cb_proc = PMAPPROC_CALLIT;
+ msg.rm_call.cb_cred = unix_auth->ah_cred;
+ msg.rm_call.cb_verf = unix_auth->ah_verf;
+ a.prog = prog;
+ a.vers = vers;
+ a.proc = proc;
+ a.xdr_args = xargs;
+ a.args_ptr = argsp;
+ r.port_ptr = &port;
+ r.xdr_results = xresults;
+ r.results_ptr = resultsp;
+ xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE);
+ if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) {
+ stat = RPC_CANTENCODEARGS;
+ goto done_broad;
+ }
+ outlen = (int)xdr_getpos(xdrs);
+ xdr_destroy(xdrs);
+ /*
+ * Basic loop: broadcast a packet and wait a while for response(s).
+ * The response timeout grows larger per iteration.
+ *
+ * XXX This will loop about 5 times the stop. If there are
+ * lots of signals being received by the process it will quit
+ * send them all in one quick burst, not paying attention to
+ * the intended function of sending them slowly over half a
+ * minute or so
+ */
+ for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) {
+ for (i = 0; i < nets; i++) {
+ baddr.sin_addr = addrs[i];
+ if (sendto(sock, outbuf, outlen, 0,
+ (struct sockaddr *)&baddr,
+ sizeof (struct sockaddr)) != outlen) {
+ perror("Cannot send broadcast packet");
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+ }
+ if (eachresult == NULL) {
+ stat = RPC_SUCCESS;
+ goto done_broad;
+ }
+ recv_again:
+ msg.acpted_rply.ar_verf = _null_auth;
+ msg.acpted_rply.ar_results.where = (caddr_t)&r;
+ msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
+ /* XXX we know the other bits are still clear */
+ FD_SET(sock, fds);
+ tv = t; /* for select() that copies back */
+ switch (select(sock + 1, fds, NULL, NULL, &tv)) {
+
+ case 0: /* timed out */
+ stat = RPC_TIMEDOUT;
+ continue;
+
+ case -1: /* some kind of error */
+ if (errno == EINTR)
+ goto recv_again;
+ perror("Broadcast select problem");
+ stat = RPC_CANTRECV;
+ goto done_broad;
+
+ } /* end of select results switch */
+ try_again:
+ fromlen = sizeof(struct sockaddr);
+ inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0,
+ (struct sockaddr *)&raddr, &fromlen);
+ if (inlen < 0) {
+ if (errno == EINTR)
+ goto try_again;
+ perror("Cannot receive reply to broadcast");
+ stat = RPC_CANTRECV;
+ goto done_broad;
+ }
+ if (inlen < sizeof(u_int32_t))
+ goto recv_again;
+ /*
+ * see if reply transaction id matches sent id.
+ * If so, decode the results.
+ */
+ xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
+ if (xdr_replymsg(xdrs, &msg)) {
+ if ((msg.rm_xid == xid) &&
+ (msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
+ (msg.acpted_rply.ar_stat == SUCCESS)) {
+ raddr.sin_port = htons((u_short)port);
+ done = (*eachresult)(resultsp, &raddr);
+ }
+ /* otherwise, we just ignore the errors ... */
+ }
+ xdrs->x_op = XDR_FREE;
+ msg.acpted_rply.ar_results.proc = xdr_void;
+ (void)xdr_replymsg(xdrs, &msg);
+ (void)(*xresults)(xdrs, resultsp);
+ xdr_destroy(xdrs);
+ if (done) {
+ stat = RPC_SUCCESS;
+ goto done_broad;
+ } else {
+ goto recv_again;
+ }
+ }
+done_broad:
+ if (fds != &readfds)
+ free(fds);
+ if (sock >= 0)
+ (void)close(sock);
+ AUTH_DESTROY(unix_auth);
+ return (stat);
+}
+
diff --git a/lib/libc/rpc/publickey.3 b/lib/libc/rpc/publickey.3
new file mode 100644
index 0000000..7f32e49
--- /dev/null
+++ b/lib/libc/rpc/publickey.3
@@ -0,0 +1,46 @@
+.\" @(#)publickey.3r 2.1 88/08/07 4.0 RPCSRC
+.\" $FreeBSD$
+.\"
+.TH PUBLICKEY 3R "6 October 1987"
+.SH NAME
+publickey, getpublickey, getsecretkey \- get public or secret key
+.SH SYNOPSIS
+.nf
+.B #include <rpc/rpc.h>
+.B #include <rpc/key_prot.h>
+.LP
+.B getpublickey(netname, publickey)
+.B char netname[\s-1MAXNETNAMELEN\s0+1];
+.B char publickey[\s-1HEXKEYBYTES\s0+1];
+.LP
+.B getsecretkey(netname, secretkey, passwd)
+.B char netname[\s-1MAXNETNAMELEN\s0+1];
+.B char secretkey[\s-1HEXKEYBYTES\s0+1];
+.B char *passwd;
+.fi
+.SH DESCRIPTION
+.IX "getpublickey function" "" "\fLgetpublickey()\fP function"
+.IX "getsecretkey function" "" "\fLgetsecretkey()\fP function"
+These routines are used to get public and secret keys from the
+.SM YP
+database.
+.B getsecretkey(\|)
+has an extra argument,
+.IR passwd ,
+which is used to decrypt the encrypted secret key stored in the database.
+Both routines return 1 if they are successful in finding the key, 0 otherwise.
+The keys are returned as
+.SM NULL\s0-terminated,
+hexadecimal strings. If the password supplied to
+.B getsecretkey(\|)
+fails to decrypt the secret key, the routine will return 1 but the
+.I secretkey
+argument will be a
+.SM NULL
+string (``'').
+.SH "SEE ALSO"
+.BR publickey (5)
+.LP
+.I \s-1RPC\s0 Programmer's Manual
+in
+.TX NETP
diff --git a/lib/libc/rpc/publickey.5 b/lib/libc/rpc/publickey.5
new file mode 100644
index 0000000..806028f
--- /dev/null
+++ b/lib/libc/rpc/publickey.5
@@ -0,0 +1,37 @@
+.\" $FreeBSD$
+.\" @(#)publickey.5 2.1 88/08/07 4.0 RPCSRC; from 1.6 88/02/29 SMI;
+.TH PUBLICKEY 5 "19 October 1987"
+.SH NAME
+publickey \- public key database
+.SH SYNOPSIS
+.B /etc/publickey
+.SH DESCRIPTION
+.LP
+.B /etc/publickey
+is the public key database used for secure
+networking. Each entry in
+the database consists of a network user
+name (which may either refer to
+a user or a hostname), followed by the user's
+public key (in hex
+notation), a colon, and then the user's
+secret key encrypted with
+its login password (also in hex notation).
+.LP
+This file is altered either by the user through the
+.BR chkey (1)
+command or by the system administrator through the
+.BR newkey (8)
+command.
+The file
+.B /etc/publickey
+should only contain data on the NIS master machine, where it
+is converted into the
+.SM NIS
+database
+.BR publickey.byname .
+.SH SEE ALSO
+.BR chkey (1),
+.BR publickey (3R),
+.BR newkey (8),
+.BR ypupdated (8C)
diff --git a/lib/libc/rpc/rpc.3 b/lib/libc/rpc/rpc.3
new file mode 100644
index 0000000..256b59b
--- /dev/null
+++ b/lib/libc/rpc/rpc.3
@@ -0,0 +1,1740 @@
+.\" @(#)rpc.3n 2.4 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI
+.\" $FreeBSD$
+.\"
+.TH RPC 3 "16 February 1988"
+.SH NAME
+rpc \- library routines for remote procedure calls
+.SH SYNOPSIS AND DESCRIPTION
+These routines allow C programs to make procedure
+calls on other machines across the network.
+First, the client calls a procedure to send a
+data packet to the server.
+Upon receipt of the packet, the server calls a dispatch routine
+to perform the requested service, and then sends back a
+reply.
+Finally, the procedure call returns to the client.
+.LP
+Routines that are used for Secure RPC (DES authentication) are described in
+.BR rpc_secure (3).
+Secure RPC can be used only if DES encryption is available.
+.LP
+.ft B
+.nf
+.sp .5
+#include <rpc/rpc.h>
+.fi
+.ft R
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+auth_destroy(auth)
+\s-1AUTH\s0 *auth;
+.fi
+.ft R
+.IP
+A macro that destroys the authentication information associated with
+.IR auth .
+Destruction usually involves deallocation of private data
+structures. The use of
+.I auth
+is undefined after calling
+.BR auth_destroy(\|) .
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+\s-1AUTH\s0 *
+authnone_create(\|)
+.fi
+.ft R
+.IP
+Create and returns an
+.SM RPC
+authentication handle that passes nonusable authentication
+information with each remote procedure call. This is the
+default authentication used by
+.SM RPC.
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1AUTH\s0 *
+authunix_create(host, uid, gid, len, aup_gids)
+char *host;
+int uid, gid, len, *aup.gids;
+.fi
+.ft R
+.IP
+Create and return an
+.SM RPC
+authentication handle that contains
+.UX
+authentication information.
+The parameter
+.I host
+is the name of the machine on which the information was
+created;
+.I uid
+is the user's user
+.SM ID ;
+.I gid
+is the user's current group
+.SM ID ;
+.I len
+and
+.I aup_gids
+refer to a counted array of groups to which the user belongs.
+It is easy to impersonate a user.
+.br
+.if t .ne 5
+.LP
+.ft B
+.nf
+.sp .5
+\s-1AUTH\s0 *
+authunix_create_default(\|)
+.fi
+.ft R
+.IP
+Calls
+.B authunix_create(\|)
+with the appropriate parameters.
+.br
+.if t .ne 13
+.LP
+.ft B
+.nf
+.sp .5
+callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
+char *host;
+u_long prognum, versnum, procnum;
+char *in, *out;
+xdrproc_t inproc, outproc;
+.fi
+.ft R
+.IP
+Call the remote procedure associated with
+.IR prognum ,
+.IR versnum ,
+and
+.I procnum
+on the machine,
+.IR host .
+The parameter
+.I in
+is the address of the procedure's argument(s), and
+.I out
+is the address of where to place the result(s);
+.I inproc
+is used to encode the procedure's parameters, and
+.I outproc
+is used to decode the procedure's results.
+This routine returns zero if it succeeds, or the value of
+.B "enum clnt_stat"
+cast to an integer if it fails.
+The routine
+.B clnt_perrno(\|)
+is handy for translating failure statuses into messages.
+.IP
+Warning: calling remote procedures with this routine
+uses
+.SM UDP/IP
+as a transport; see
+.B clntudp_create(\|)
+for restrictions.
+You do not have control of timeouts or authentication using
+this routine.
+.br
+.if t .ne 16
+.LP
+.ft B
+.nf
+.sp .5
+enum clnt_stat
+clnt_broadcast(prognum, versnum, procnum, inproc, in, outproc, out, eachresult)
+u_long prognum, versnum, procnum;
+char *in, *out;
+xdrproc_t inproc, outproc;
+resultproc_t eachresult;
+.fi
+.ft R
+.IP
+Like
+.BR callrpc(\|) ,
+except the call message is broadcast to all locally
+connected broadcast nets. Each time it receives a
+response, this routine calls
+.BR eachresult(\|) ,
+whose form is:
+.IP
+.RS 1i
+.ft B
+.nf
+eachresult(out, addr)
+char *out;
+struct sockaddr_in *addr;
+.ft R
+.fi
+.RE
+.IP
+where
+.I out
+is the same as
+.I out
+passed to
+.BR clnt_broadcast(\|) ,
+except that the remote procedure's output is decoded there;
+.I addr
+points to the address of the machine that sent the results.
+If
+.B eachresult(\|)
+returns zero,
+.B clnt_broadcast(\|)
+waits for more replies; otherwise it returns with appropriate
+status.
+.IP
+Warning: broadcast sockets are limited in size to the
+maximum transfer unit of the data link. For ethernet,
+this value is 1500 bytes.
+.br
+.if t .ne 13
+.LP
+.ft B
+.nf
+.sp .5
+enum clnt_stat
+clnt_call(clnt, procnum, inproc, in, outproc, out, tout)
+\s-1CLIENT\s0 *clnt;
+u_long
+procnum;
+xdrproc_t inproc, outproc;
+char *in, *out;
+struct timeval tout;
+.fi
+.ft R
+.IP
+A macro that calls the remote procedure
+.I procnum
+associated with the client handle,
+.IR clnt ,
+which is obtained with an
+.SM RPC
+client creation routine such as
+.BR clnt_create(\|) .
+The parameter
+.I in
+is the address of the procedure's argument(s), and
+.I out
+is the address of where to place the result(s);
+.I inproc
+is used to encode the procedure's parameters, and
+.I outproc
+is used to decode the procedure's results;
+.I tout
+is the time allowed for results to come back.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+clnt_destroy(clnt)
+\s-1CLIENT\s0 *clnt;
+.fi
+.ft R
+.IP
+A macro that destroys the client's
+.SM RPC
+handle. Destruction usually involves deallocation
+of private data structures, including
+.I clnt
+itself. Use of
+.I clnt
+is undefined after calling
+.BR clnt_destroy(\|) .
+If the
+.SM RPC
+library opened the associated socket, it will close it also.
+Otherwise, the socket remains open.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clnt_create(host, prog, vers, proto)
+char *host;
+u_long prog, vers;
+char *proto;
+.fi
+.ft R
+.IP
+Generic client creation routine.
+.I host
+identifies the name of the remote host where the server
+is located.
+.I proto
+indicates which kind of transport protocol to use. The
+currently supported values for this field are \(lqudp\(rq
+and \(lqtcp\(rq.
+Default timeouts are set, but can be modified using
+.BR clnt_control(\|) .
+.IP
+Warning: Using
+.SM UDP
+has its shortcomings. Since
+.SM UDP\s0-based
+.SM RPC
+messages can only hold up to 8 Kbytes of encoded data,
+this transport cannot be used for procedures that take
+large arguments or return huge results.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+bool_t
+clnt_control(cl, req, info)
+\s-1CLIENT\s0 *cl;
+u_int req;
+char *info;
+.fi
+.ft R
+.IP
+A macro used to change or retrieve various information
+about a client object.
+.I req
+indicates the type of operation, and
+.I info
+is a pointer to the information. For both
+.SM UDP
+and
+.SM TCP\s0,
+the supported values of
+.I req
+and their argument types and what they do are:
+.IP
+.nf
+.ta +2.0i +2.0i +2.0i
+.SM CLSET_TIMEOUT\s0 struct timeval set total timeout
+.SM CLGET_TIMEOUT\s0 struct timeval get total timeout
+.fi
+.IP
+Note: if you set the timeout using
+.BR clnt_control(\|) ,
+the timeout parameter passed to
+.B clnt_call(\|)
+will be ignored in all future calls.
+.IP
+.nf
+.SM CLGET_SERVER_ADDR\s0 struct sockaddr_in get server's address
+.fi
+.br
+.IP
+The following operations are valid for
+.SM UDP
+only:
+.IP
+.nf
+.ta +2.0i ; +2.0i ; +2.0i
+.SM CLSET_RETRY_TIMEOUT\s0 struct timeval set the retry timeout
+.SM CLGET_RETRY_TIMEOUT\s0 struct timeval get the retry timeout
+.fi
+.br
+.IP
+The retry timeout is the time that
+.SM "UDP RPC"
+waits for the server to reply before
+retransmitting the request.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+clnt_freeres(clnt, outproc, out)
+\s-1CLIENT\s0 *clnt;
+xdrproc_t outproc;
+char *out;
+.fi
+.ft R
+.IP
+A macro that frees any data allocated by the
+.SM RPC/XDR
+system when it decoded the results of an
+.SM RPC
+call. The
+parameter
+.I out
+is the address of the results, and
+.I outproc
+is the
+.SM XDR
+routine describing the results.
+This routine returns one if the results were successfully
+freed,
+and zero otherwise.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+void
+clnt_geterr(clnt, errp)
+\s-1CLIENT\s0 *clnt;
+struct rpc_err *errp;
+.fi
+.ft R
+.IP
+A macro that copies the error structure out of the client
+handle
+to the structure at address
+.IR errp .
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+clnt_pcreateerror(s)
+char *s;
+.fi
+.ft R
+.IP
+Print a message to standard error indicating
+why a client
+.SM RPC
+handle could not be created.
+The message is prepended with string
+.I s
+and a colon.
+Used when a
+.BR clnt_create(\|) ,
+.BR clntraw_create(\|) ,
+.BR clnttcp_create(\|) ,
+or
+.B clntudp_create(\|)
+call fails.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+clnt_perrno(stat)
+enum clnt_stat stat;
+.fi
+.ft R
+.IP
+Print a message to standard error corresponding
+to the condition indicated by
+.IR stat .
+Used after
+.BR callrpc(\|) .
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+clnt_perror(clnt, s)
+\s-1CLIENT\s0 *clnt;
+char *s;
+.fi
+.ft R
+.IP
+Print a message to standard error indicating why an
+.SM RPC
+call failed;
+.I clnt
+is the handle used to do the call.
+The message is prepended with string
+.I s
+and a colon.
+Used after
+.BR clnt_call(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+char *
+clnt_spcreateerror
+char *s;
+.fi
+.ft R
+.IP
+Like
+.BR clnt_pcreateerror(\|) ,
+except that it returns a string
+instead of printing to the standard error.
+.IP
+Bugs: returns pointer to static data that is overwritten
+on each call.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+char *
+clnt_sperrno(stat)
+enum clnt_stat stat;
+.fi
+.ft R
+.IP
+Take the same arguments as
+.BR clnt_perrno(\|) ,
+but instead of sending a message to the standard error
+indicating why an
+.SM RPC
+call failed, return a pointer to a string which contains
+the message. The string ends with a
+.SM NEWLINE\s0.
+.IP
+.B clnt_sperrno(\|)
+is used instead of
+.B clnt_perrno(\|)
+if the program does not have a standard error (as a program
+running as a server quite likely does not), or if the
+programmer
+does not want the message to be output with
+.BR printf ,
+or if a message format different than that supported by
+.B clnt_perrno(\|)
+is to be used.
+Note: unlike
+.B clnt_sperror(\|)
+and
+.BR clnt_spcreaterror(\|) ,
+.B clnt_sperrno(\|)
+returns pointer to static data, but the
+result will not get overwritten on each call.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+char *
+clnt_sperror(rpch, s)
+\s-1CLIENT\s0 *rpch;
+char *s;
+.fi
+.ft R
+.IP
+Like
+.BR clnt_perror(\|) ,
+except that (like
+.BR clnt_sperrno(\|) )
+it returns a string instead of printing to standard error.
+.IP
+Bugs: returns pointer to static data that is overwritten
+on each call.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clntraw_create(prognum, versnum)
+u_long prognum, versnum;
+.fi
+.ft R
+.IP
+This routine creates a toy
+.SM RPC
+client for the remote program
+.IR prognum ,
+version
+.IR versnum .
+The transport used to pass messages to the service is
+actually a buffer within the process's address space, so the
+corresponding
+.SM RPC
+server should live in the same address space; see
+.BR svcraw_create(\|) .
+This allows simulation of
+.SM RPC
+and acquisition of
+.SM RPC
+overheads, such as round trip times, without any
+kernel interference. This routine returns
+.SM NULL
+if it fails.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clnttcp_create(addr, prognum, versnum, sockp, sendsz, recvsz)
+struct sockaddr_in *addr;
+u_long prognum, versnum;
+int *sockp;
+u_int sendsz, recvsz;
+.fi
+.ft R
+.IP
+This routine creates an
+.SM RPC
+client for the remote program
+.IR prognum ,
+version
+.IR versnum ;
+the client uses
+.SM TCP/IP
+as a transport. The remote program is located at Internet
+address
+.IR *addr .
+If
+.\"The following in-line font conversion is necessary for the hyphen indicator
+\fB\%addr\->sin_port\fR
+is zero, then it is set to the actual port that the remote
+program is listening on (the remote
+.B portmap
+service is consulted for this information). The parameter
+.I sockp
+is a socket; if it is
+.BR \s-1RPC_ANYSOCK\s0 ,
+then this routine opens a new one and sets
+.IR sockp .
+Since
+.SM TCP\s0-based
+.SM RPC
+uses buffered
+.SM I/O ,
+the user may specify the size of the send and receive buffers
+with the parameters
+.I sendsz
+and
+.IR recvsz ;
+values of zero choose suitable defaults.
+This routine returns
+.SM NULL
+if it fails.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clntudp_create(addr, prognum, versnum, wait, sockp)
+struct sockaddr_in *addr;
+u_long prognum, versnum;
+struct timeval wait;
+int *sockp;
+.fi
+.ft R
+.IP
+This routine creates an
+.SM RPC
+client for the remote program
+.IR prognum ,
+version
+.IR versnum ;
+the client uses
+.SM UDP/IP
+as a transport. The remote program is located at Internet
+address
+.IR addr .
+If
+\fB\%addr\->sin_port\fR
+is zero, then it is set to actual port that the remote
+program is listening on (the remote
+.B portmap
+service is consulted for this information). The parameter
+.I sockp
+is a socket; if it is
+.BR \s-1RPC_ANYSOCK\s0 ,
+then this routine opens a new one and sets
+.IR sockp .
+The
+.SM UDP
+transport resends the call message in intervals of
+.B wait
+time until a response is received or until the call times
+out.
+The total time for the call to time out is specified by
+.BR clnt_call(\|) .
+.IP
+Warning: since
+.SM UDP\s0-based
+.SM RPC
+messages can only hold up to 8 Kbytes
+of encoded data, this transport cannot be used for procedures
+that take large arguments or return huge results.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clntudp_bufcreate(addr, prognum, versnum, wait, sockp, sendsize, recosize)
+struct sockaddr_in *addr;
+u_long prognum, versnum;
+struct timeval wait;
+int *sockp;
+unsigned int sendsize;
+unsigned int recosize;
+.fi
+.ft R
+.IP
+This routine creates an
+.SM RPC
+client for the remote program
+.IR prognum ,
+on
+.IR versnum ;
+the client uses
+.SM UDP/IP
+as a transport. The remote program is located at Internet
+address
+.IR addr .
+If
+\fB\%addr\->sin_port\fR
+is zero, then it is set to actual port that the remote
+program is listening on (the remote
+.B portmap
+service is consulted for this information). The parameter
+.I sockp
+is a socket; if it is
+.BR \s-1RPC_ANYSOCK\s0 ,
+then this routine opens a new one and sets
+.BR sockp .
+The
+.SM UDP
+transport resends the call message in intervals of
+.B wait
+time until a response is received or until the call times
+out.
+The total time for the call to time out is specified by
+.BR clnt_call(\|) .
+.IP
+This allows the user to specify the maximum packet size for sending and receiving
+.SM UDP\s0-based
+.SM RPC
+messages.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+int
+get_myaddress(addr)
+struct sockaddr_in *addr;
+.fi
+.ft R
+.IP
+Stuff the machine's
+.SM IP
+address into
+.IR *addr ,
+without consulting the library routines that deal with
+.BR /etc/hosts .
+The port number is always set to
+.BR htons(\s-1PMAPPORT\s0) .
+Returns zero on success, non-zero on failure.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+struct pmaplist *
+pmap_getmaps(addr)
+struct sockaddr_in *addr;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which returns a list of the current
+.SM RPC
+program-to-port mappings
+on the host located at
+.SM IP
+address
+.IR *addr .
+This routine can return
+.SM NULL .
+The command
+.RB ` "rpcinfo \-p" '
+uses this routine.
+.br
+.if t .ne 12
+.LP
+.ft B
+.nf
+.sp .5
+u_short
+pmap_getport(addr, prognum, versnum, protocol)
+struct sockaddr_in *addr;
+u_long prognum, versnum, protocol;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which returns the port number
+on which waits a service that supports program number
+.IR prognum ,
+version
+.IR versnum ,
+and speaks the transport protocol associated with
+.IR protocol .
+The value of
+.I protocol
+is most likely
+.B
+.SM IPPROTO_UDP
+or
+.BR \s-1IPPROTO_TCP\s0 .
+A return value of zero means that the mapping does not exist
+or that
+the
+.SM RPC
+system failed to contact the remote
+.B portmap
+service. In the latter case, the global variable
+.B rpc_createerr(\|)
+contains the
+.SM RPC
+status.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+enum clnt_stat
+pmap_rmtcall(addr, prognum, versnum, procnum, inproc, in, outproc, out, tout, portp)
+struct sockaddr_in *addr;
+u_long prognum, versnum, procnum;
+char *in, *out;
+xdrproc_t inproc, outproc;
+struct timeval tout;
+u_long *portp;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which instructs
+.B portmap
+on the host at
+.SM IP
+address
+.I *addr
+to make an
+.SM RPC
+call on your behalf to a procedure on that host.
+The parameter
+.I *portp
+will be modified to the program's port number if the
+procedure
+succeeds. The definitions of other parameters are discussed
+in
+.B callrpc(\|)
+and
+.BR clnt_call(\|) .
+This procedure should be used for a \(lqping\(rq and nothing
+else.
+See also
+.BR clnt_broadcast(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+pmap_set(prognum, versnum, protocol, port)
+u_long prognum, versnum, protocol;
+u_short port;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which establishes a mapping between the triple
+.RI [ prognum , versnum , protocol\fR]
+and
+.I port
+on the machine's
+.B portmap
+service. The value of
+.I protocol
+is most likely
+.B
+.SM IPPROTO_UDP
+or
+.BR \s-1IPPROTO_TCP\s0 .
+This routine returns one if it succeeds, zero otherwise.
+Automatically done by
+.BR svc_register(\|) .
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+pmap_unset(prognum, versnum)
+u_long prognum, versnum;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which destroys all mapping between the triple
+.RI [ prognum , versnum , *\fR]
+and
+.B ports
+on the machine's
+.B portmap
+service. This routine returns one if it succeeds, zero
+otherwise.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+registerrpc(prognum, versnum, procnum, procname, inproc, outproc)
+u_long prognum, versnum, procnum;
+char *(*procname) (\|) ;
+xdrproc_t inproc, outproc;
+.fi
+.ft R
+.IP
+Register procedure
+.I procname
+with the
+.SM RPC
+service package. If a request arrives for program
+.IR prognum ,
+version
+.IR versnum ,
+and procedure
+.IR procnum ,
+.I procname
+is called with a pointer to its parameter(s);
+.I progname
+should return a pointer to its static result(s);
+.I inproc
+is used to decode the parameters while
+.I outproc
+is used to encode the results.
+This routine returns zero if the registration succeeded, \-1
+otherwise.
+.IP
+Warning: remote procedures registered in this form
+are accessed using the
+.SM UDP/IP
+transport; see
+.B svcudp_create(\|)
+for restrictions.
+.br
+.if t .ne 5
+.LP
+.ft B
+.nf
+.sp .5
+struct rpc_createerr rpc_createerr;
+.fi
+.ft R
+.IP
+A global variable whose value is set by any
+.SM RPC
+client creation routine
+that does not succeed. Use the routine
+.B clnt_pcreateerror(\|)
+to print the reason why.
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+svc_destroy(xprt)
+\s-1SVCXPRT\s0 *
+xprt;
+.fi
+.ft R
+.IP
+A macro that destroys the
+.SM RPC
+service transport handle,
+.IR xprt .
+Destruction usually involves deallocation
+of private data structures, including
+.I xprt
+itself. Use of
+.I xprt
+is undefined after calling this routine.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+fd_set svc_fdset;
+.fi
+.ft R
+.IP
+A global variable reflecting the
+.SM RPC
+service side's
+read file descriptor bit mask; it is suitable as a template parameter
+to the
+.B select
+system call. This is only of interest
+if a service implementor does not call
+.BR svc_run(\|) ,
+but rather does his own asynchronous event processing.
+This variable is read-only (do not pass its address to
+.BR select !),
+yet it may change after calls to
+.B svc_getreqset(\|)
+or any creation routines.
+.br
+As well, note that if the process has descriptor limits
+which are extended beyond
+.BR FD_SETSIZE ,
+this variable will only be usable for the first
+.BR FD_SETSIZE
+descriptors.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+int svc_fds;
+.fi
+.ft R
+.IP
+Similar to
+.BR svc_fedset(\|) ,
+but limited to 32 descriptors. This
+interface is obsoleted by
+.BR svc_fdset(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+svc_freeargs(xprt, inproc, in)
+\s-1SVCXPRT\s0 *xprt;
+xdrproc_t inproc;
+char *in;
+.fi
+.ft R
+.IP
+A macro that frees any data allocated by the
+.SM RPC/XDR
+system when it decoded the arguments to a service procedure
+using
+.BR svc_getargs(\|) .
+This routine returns 1 if the results were successfully
+freed,
+and zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+svc_getargs(xprt, inproc, in)
+\s-1SVCXPRT\s0 *xprt;
+xdrproc_t inproc;
+char *in;
+.fi
+.ft R
+.IP
+A macro that decodes the arguments of an
+.SM RPC
+request
+associated with the
+.SM RPC
+service transport handle,
+.IR xprt .
+The parameter
+.I in
+is the address where the arguments will be placed;
+.I inproc
+is the
+.SM XDR
+routine used to decode the arguments.
+This routine returns one if decoding succeeds, and zero
+otherwise.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+struct sockaddr_in *
+svc_getcaller(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+The approved way of getting the network address of the caller
+of a procedure associated with the
+.SM RPC
+service transport handle,
+.IR xprt .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+svc_getreqset(rdfds)
+fd_set *rdfds;
+.fi
+.ft R
+.IP
+This routine is only of interest if a service implementor
+does not call
+.BR svc_run(\|) ,
+but instead implements custom asynchronous event processing.
+It is called when the
+.B select
+system call has determined that an
+.SM RPC
+request has arrived on some
+.SM RPC
+.B socket(s) ;
+.I rdfds
+is the resultant read file descriptor bit mask.
+The routine returns when all sockets associated with the
+value of
+.I rdfds
+have been serviced.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+svc_getreq(rdfds)
+int rdfds;
+.fi
+.ft R
+.IP
+Similar to
+.BR svc_getreqset(\|) ,
+but limited to 32 descriptors. This interface is obsoleted by
+.BR svc_getreqset(\|) .
+.br
+.if t .ne 17
+.LP
+.ft B
+.nf
+.sp .5
+svc_register(xprt, prognum, versnum, dispatch, protocol)
+\s-1SVCXPRT\s0 *xprt;
+u_long prognum, versnum;
+void (*dispatch) (\|);
+u_long protocol;
+.fi
+.ft R
+.IP
+Associates
+.I prognum
+and
+.I versnum
+with the service dispatch procedure,
+.IR dispatch .
+If
+.I protocol
+is zero, the service is not registered with the
+.B portmap
+service. If
+.I protocol
+is non-zero, then a mapping of the triple
+.RI [ prognum , versnum , protocol\fR]
+to
+\fB\%xprt\->xp_port\fR
+is established with the local
+.B portmap
+service (generally
+.I protocol
+is zero,
+.B
+.SM IPPROTO_UDP
+or
+.B
+.SM IPPROTO_TCP
+).
+The procedure
+.I dispatch
+has the following form:
+.RS 1i
+.ft B
+.nf
+dispatch(request, xprt)
+struct svc_req *request;
+\s-1SVCXPRT\s0 *xprt;
+.ft R
+.fi
+.RE
+.IP
+The
+.B svc_register(\|)
+routine returns one if it succeeds, and zero otherwise.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+svc_run(\|)
+.fi
+.ft R
+.IP
+This routine never returns. It waits for
+.SM RPC
+requests to arrive, and calls the appropriate service
+procedure using
+.B svc_getreq(\|)
+when one arrives. This procedure is usually waiting for a
+.B select(\|)
+system call to return.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+svc_sendreply(xprt, outproc, out)
+\s-1SVCXPRT\s0 *xprt;
+xdrproc_t outproc;
+char *out;
+.fi
+.ft R
+.IP
+Called by an
+.SM RPC
+service's dispatch routine to send the results of a
+remote procedure call. The parameter
+.I xprt
+is the request's associated transport handle;
+.I outproc
+is the
+.SM XDR
+routine which is used to encode the results; and
+.I out
+is the address of the results.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svc_unregister(prognum, versnum)
+u_long prognum, versnum;
+.fi
+.ft R
+.IP
+Remove all mapping of the double
+.RI [ prognum , versnum ]
+to dispatch routines, and of the triple
+.RI [ prognum , versnum , *\fR]
+to port number.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_auth(xprt, why)
+\s-1SVCXPRT\s0 *xprt;
+enum auth_stat why;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that refuses to perform
+a remote procedure call due to an authentication error.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_decode(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that cannot successfully
+decode its parameters. See also
+.BR svc_getargs(\|) .
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_noproc(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that does not implement
+the procedure number that the caller requests.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_noprog(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called when the desired program is not registered with the
+.SM RPC
+package. Service implementors usually do not need this routine.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_progvers(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called when the desired version of a program is not registered
+with the
+.SM RPC
+package. Service implementors usually do not need this routine.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_systemerr(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine when it detects a system
+error
+not covered by any particular protocol.
+For example, if a service can no longer allocate storage,
+it may call this routine.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_weakauth(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that refuses to perform
+a remote procedure call due to insufficient
+authentication parameters. The routine calls
+.BR "svcerr_auth(xprt, \s-1AUTH_TOOWEAK\s0)" .
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svcraw_create(\|)
+.fi
+.ft R
+.IP
+This routine creates a toy
+.SM RPC
+service transport, to which it returns a pointer. The
+transport
+is really a buffer within the process's address space,
+so the corresponding
+.SM RPC
+client should live in the same
+address space;
+see
+.BR clntraw_create(\|) .
+This routine allows simulation of
+.SM RPC
+and acquisition of
+.SM RPC
+overheads (such as round trip times), without any kernel
+interference.
+This routine returns
+.SM NULL
+if it fails.
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svctcp_create(sock, send_buf_size, recv_buf_size)
+int sock;
+u_int send_buf_size, recv_buf_size;
+.fi
+.ft R
+.IP
+This routine creates a
+.SM TCP/IP\s0-based
+.SM RPC
+service transport, to which it returns a pointer.
+The transport is associated with the socket
+.IR sock ,
+which may be
+.BR \s-1RPC_ANYSOCK\s0 ,
+in which case a new socket is created.
+If the socket is not bound to a local
+.SM TCP
+port, then this routine binds it to an arbitrary port. Upon
+completion,
+\fB\%xprt\->xp_sock\fR
+is the transport's socket descriptor, and
+\fB\%xprt\->xp_port\fR
+is the transport's port number.
+This routine returns
+.SM NULL
+if it fails. Since
+.SM TCP\s0-based
+.SM RPC
+uses buffered
+.SM I/O ,
+users may specify the size of buffers; values of zero
+choose suitable defaults.
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svcfd_create(fd, sendsize, recvsize)
+int fd;
+u_int sendsize;
+u_int recvsize;
+.fi
+.ft R
+.IP
+Create a service on top of any open descriptor. Typically,
+this
+descriptor is a connected socket for a stream protocol such
+as
+.SM TCP\s0.
+.I sendsize
+and
+.I recvsize
+indicate sizes for the send and receive buffers. If they are
+zero, a reasonable default is chosen.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svcudp_bufcreate(sock, sendsize, recosize)
+int sock;
+.fi
+.ft R
+.IP
+This routine creates a
+.SM UDP/IP\s0-based
+.SM RPC
+service transport, to which it returns a pointer.
+The transport is associated with the socket
+.IR sock ,
+which may be
+.B \s-1RPC_ANYSOCK\s0 ,
+in which case a new socket is created.
+If the socket is not bound to a local
+.SM UDP
+port, then this routine binds it to an arbitrary port. Upon
+completion,
+\fB\%xprt\->xp_sock\fR
+is the transport's socket descriptor, and
+\fB\%xprt\->xp_port\fR
+is the transport's port number.
+This routine returns
+.SM NULL
+if it fails.
+.IP
+This allows the user to specify the maximum packet size for sending and
+receiving
+.SM UDP\s0-based
+.SM RPC messages.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_accepted_reply(xdrs, ar)
+\s-1XDR\s0 *xdrs;
+struct accepted_reply *ar;
+.fi
+.ft R
+.IP
+Used for encoding
+.SM RPC
+reply messages. This routine is useful for users who
+wish to generate
+\s-1RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_authunix_parms(xdrs, aupp)
+\s-1XDR\s0 *xdrs;
+struct authunix_parms *aupp;
+.fi
+.ft R
+.IP
+Used for describing
+.SM UNIX
+credentials. This routine is useful for users
+who wish to generate these credentials without using the
+.SM RPC
+authentication package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdr_callhdr(xdrs, chdr)
+\s-1XDR\s0 *xdrs;
+struct rpc_msg *chdr;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+call header messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_callmsg(xdrs, cmsg)
+\s-1XDR\s0 *xdrs;
+struct rpc_msg *cmsg;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+call messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_opaque_auth(xdrs, ap)
+\s-1XDR\s0 *xdrs;
+struct opaque_auth *ap;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+authentication information messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_pmap(xdrs, regs)
+\s-1XDR\s0 *xdrs;
+struct pmap *regs;
+.fi
+.ft R
+.IP
+Used for describing parameters to various
+.B portmap
+procedures, externally.
+This routine is useful for users who wish to generate
+these parameters without using the
+.B pmap
+interface.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_pmaplist(xdrs, rp)
+\s-1XDR\s0 *xdrs;
+struct pmaplist **rp;
+.fi
+.ft R
+.IP
+Used for describing a list of port mappings, externally.
+This routine is useful for users who wish to generate
+these parameters without using the
+.B pmap
+interface.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_rejected_reply(xdrs, rr)
+\s-1XDR\s0 *xdrs;
+struct rejected_reply *rr;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+reply messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_replymsg(xdrs, rmsg)
+\s-1XDR\s0 *xdrs;
+struct rpc_msg *rmsg;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+reply messages.
+This routine is useful for users who wish to generate
+.SM RPC
+style messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+xprt_register(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+After
+.SM RPC
+service transport handles are created,
+they should register themselves with the
+.SM RPC
+service package.
+This routine modifies the global variable
+.BR svc_fds(\|) .
+Service implementors usually do not need this routine.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+xprt_unregister(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Before an
+.SM RPC
+service transport handle is destroyed,
+it should unregister itself with the
+.SM RPC
+service package.
+This routine modifies the global variable
+.BR svc_fds(\|) .
+Service implementors usually do not need this routine.
+.SH SEE ALSO
+.BR rpc_secure (3),
+.BR xdr (3)
+.br
+The following manuals:
+.RS
+.ft I
+Remote Procedure Calls: Protocol Specification
+.br
+Remote Procedure Call Programming Guide
+.br
+rpcgen Programming Guide
+.br
+.ft R
+.RE
+.IR "\s-1RPC\s0: Remote Procedure Call Protocol Specification" ,
+.SM RFC1050, Sun Microsystems, Inc.,
+.SM USC-ISI\s0.
+
diff --git a/lib/libc/rpc/rpc.5 b/lib/libc/rpc/rpc.5
new file mode 100644
index 0000000..b559020
--- /dev/null
+++ b/lib/libc/rpc/rpc.5
@@ -0,0 +1,35 @@
+.\" $FreeBSD$
+.\" @(#)rpc.5 2.2 88/08/03 4.0 RPCSRC; from 1.4 87/11/27 SMI;
+.Dd September 26, 1985
+.Dt RPC 5
+.Sh NAME
+.Nm rpc
+.Nd rpc program number data base
+.Sh SYNOPSIS
+/etc/rpc
+.Sh DESCRIPTION
+The
+.Pa /etc/rpc
+file contains user readable names that
+can be used in place of rpc program numbers.
+Each line has the following information:
+.Pp
+.Bl -bullet -compact
+.It
+name of server for the rpc program
+.It
+rpc program number
+.It
+aliases
+.El
+.Pp
+Items are separated by any number of blanks and/or
+tab characters.
+A ``#'' indicates the beginning of a comment; characters up to the end of
+the line are not interpreted by routines which search the file.
+.Sh FILES
+.Bl -tag -compact -width /etc/rpc
+.Pa /etc/rpc
+.El
+.Sh "SEE ALSO"
+.Xr getrpcent 3
diff --git a/lib/libc/rpc/rpc_callmsg.c b/lib/libc/rpc/rpc_callmsg.c
new file mode 100644
index 0000000..dca3a18
--- /dev/null
+++ b/lib/libc/rpc/rpc_callmsg.c
@@ -0,0 +1,193 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * rpc_callmsg.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+
+#include <sys/param.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/rpc.h>
+
+/*
+ * XDR a call message
+ */
+bool_t
+xdr_callmsg(xdrs, cmsg)
+ register XDR *xdrs;
+ register struct rpc_msg *cmsg;
+{
+ register int32_t *buf;
+ register struct opaque_auth *oa;
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
+ return (FALSE);
+ }
+ if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) {
+ return (FALSE);
+ }
+ buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT
+ + RNDUP(cmsg->rm_call.cb_cred.oa_length)
+ + 2 * BYTES_PER_XDR_UNIT
+ + RNDUP(cmsg->rm_call.cb_verf.oa_length));
+ if (buf != NULL) {
+ IXDR_PUT_LONG(buf, cmsg->rm_xid);
+ IXDR_PUT_ENUM(buf, cmsg->rm_direction);
+ if (cmsg->rm_direction != CALL) {
+ return (FALSE);
+ }
+ IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers);
+ if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
+ return (FALSE);
+ }
+ IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog);
+ IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers);
+ IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc);
+ oa = &cmsg->rm_call.cb_cred;
+ IXDR_PUT_ENUM(buf, oa->oa_flavor);
+ IXDR_PUT_LONG(buf, oa->oa_length);
+ if (oa->oa_length) {
+ memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
+ buf += RNDUP(oa->oa_length) / sizeof (int32_t);
+ }
+ oa = &cmsg->rm_call.cb_verf;
+ IXDR_PUT_ENUM(buf, oa->oa_flavor);
+ IXDR_PUT_LONG(buf, oa->oa_length);
+ if (oa->oa_length) {
+ memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
+ /* no real need....
+ buf += RNDUP(oa->oa_length) / sizeof (int32_t);
+ */
+ }
+ return (TRUE);
+ }
+ }
+ if (xdrs->x_op == XDR_DECODE) {
+ buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
+ if (buf != NULL) {
+ cmsg->rm_xid = IXDR_GET_LONG(buf);
+ cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
+ if (cmsg->rm_direction != CALL) {
+ return (FALSE);
+ }
+ cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf);
+ if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
+ return (FALSE);
+ }
+ cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf);
+ cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf);
+ cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf);
+ oa = &cmsg->rm_call.cb_cred;
+ oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
+ oa->oa_length = IXDR_GET_LONG(buf);
+ if (oa->oa_length) {
+ if (oa->oa_length > MAX_AUTH_BYTES) {
+ return (FALSE);
+ }
+ if (oa->oa_base == NULL) {
+ oa->oa_base = (caddr_t)
+ mem_alloc(oa->oa_length);
+ }
+ buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+ if (buf == NULL) {
+ if (xdr_opaque(xdrs, oa->oa_base,
+ oa->oa_length) == FALSE) {
+ return (FALSE);
+ }
+ } else {
+ memcpy(oa->oa_base, (caddr_t)buf,
+ oa->oa_length);
+ /* no real need....
+ buf += RNDUP(oa->oa_length) /
+ sizeof (int32_t);
+ */
+ }
+ }
+ oa = &cmsg->rm_call.cb_verf;
+ buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
+ xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
+ return (FALSE);
+ }
+ } else {
+ oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
+ oa->oa_length = IXDR_GET_LONG(buf);
+ }
+ if (oa->oa_length) {
+ if (oa->oa_length > MAX_AUTH_BYTES) {
+ return (FALSE);
+ }
+ if (oa->oa_base == NULL) {
+ oa->oa_base = (caddr_t)
+ mem_alloc(oa->oa_length);
+ }
+ buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+ if (buf == NULL) {
+ if (xdr_opaque(xdrs, oa->oa_base,
+ oa->oa_length) == FALSE) {
+ return (FALSE);
+ }
+ } else {
+ memcpy(oa->oa_base, (caddr_t)buf,
+ oa->oa_length);
+ /* no real need...
+ buf += RNDUP(oa->oa_length) /
+ sizeof (int32_t);
+ */
+ }
+ }
+ return (TRUE);
+ }
+ }
+ if (
+ xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) &&
+ xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
+ (cmsg->rm_direction == CALL) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+ (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_proc)) &&
+ xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
+ return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
+ return (FALSE);
+}
+
diff --git a/lib/libc/rpc/rpc_commondata.c b/lib/libc/rpc/rpc_commondata.c
new file mode 100644
index 0000000..043c082
--- /dev/null
+++ b/lib/libc/rpc/rpc_commondata.c
@@ -0,0 +1,43 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+#include <rpc/rpc.h>
+/*
+ * This file should only contain common data (global data) that is exported
+ * by public interfaces
+ */
+struct opaque_auth _null_auth;
+fd_set svc_fdset;
+int svc_maxfd = -1;
+struct rpc_createerr rpc_createerr;
diff --git a/lib/libc/rpc/rpc_dtablesize.c b/lib/libc/rpc/rpc_dtablesize.c
new file mode 100644
index 0000000..1ce5617
--- /dev/null
+++ b/lib/libc/rpc/rpc_dtablesize.c
@@ -0,0 +1,61 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro";*/
+/*static char *sccsid = "from: @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+#include <sys/types.h>
+#include <unistd.h>
+
+/*
+ * Cache the result of getdtablesize(), so we don't have to do an
+ * expensive system call every time.
+ */
+/*
+ * XXX In FreeBSD 2.x, you can have the maximum number of open file
+ * descriptors be greater than FD_SETSIZE (which us 256 by default).
+ *
+ * Since old programs tend to use this call to determine the first arg
+ * for select(), having this return > FD_SETSIZE is a Bad Idea(TM)!
+ */
+int
+_rpc_dtablesize(void)
+{
+ static int size;
+
+ if (size == 0) {
+ size = getdtablesize();
+ if (size > FD_SETSIZE)
+ size = FD_SETSIZE;
+ }
+ return (size);
+}
diff --git a/lib/libc/rpc/rpc_prot.c b/lib/libc/rpc/rpc_prot.c
new file mode 100644
index 0000000..940a29d
--- /dev/null
+++ b/lib/libc/rpc/rpc_prot.c
@@ -0,0 +1,297 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * rpc_prot.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements the rpc message definition,
+ * its serializer and some common rpc utility routines.
+ * The routines are meant for various implementations of rpc -
+ * they are NOT for the rpc client or rpc service implementations!
+ * Because authentication stuff is easy and is part of rpc, the opaque
+ * routines are also in this program.
+ */
+
+#include <sys/param.h>
+
+#include <rpc/rpc.h>
+
+/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
+
+struct opaque_auth _null_auth;
+
+/*
+ * XDR an opaque authentication struct
+ * (see auth.h)
+ */
+bool_t
+xdr_opaque_auth(xdrs, ap)
+ register XDR *xdrs;
+ register struct opaque_auth *ap;
+{
+
+ if (xdr_enum(xdrs, &(ap->oa_flavor)))
+ return (xdr_bytes(xdrs, &ap->oa_base,
+ &ap->oa_length, MAX_AUTH_BYTES));
+ return (FALSE);
+}
+
+/*
+ * XDR a DES block
+ */
+bool_t
+xdr_des_block(xdrs, blkp)
+ register XDR *xdrs;
+ register des_block *blkp;
+{
+ return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
+}
+
+/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
+
+/*
+ * XDR the MSG_ACCEPTED part of a reply message union
+ */
+bool_t
+xdr_accepted_reply(xdrs, ar)
+ register XDR *xdrs;
+ register struct accepted_reply *ar;
+{
+
+ /* personalized union, rather than calling xdr_union */
+ if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
+ return (FALSE);
+ if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
+ return (FALSE);
+ switch (ar->ar_stat) {
+
+ case SUCCESS:
+ return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
+
+ case PROG_MISMATCH:
+ if (! xdr_u_int32_t(xdrs, &(ar->ar_vers.low)))
+ return (FALSE);
+ return (xdr_u_int32_t(xdrs, &(ar->ar_vers.high)));
+ default:
+ break;
+ }
+ return (TRUE); /* TRUE => open ended set of problems */
+}
+
+/*
+ * XDR the MSG_DENIED part of a reply message union
+ */
+bool_t
+xdr_rejected_reply(xdrs, rr)
+ register XDR *xdrs;
+ register struct rejected_reply *rr;
+{
+
+ /* personalized union, rather than calling xdr_union */
+ if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
+ return (FALSE);
+ switch (rr->rj_stat) {
+
+ case RPC_MISMATCH:
+ if (! xdr_u_int32_t(xdrs, &(rr->rj_vers.low)))
+ return (FALSE);
+ return (xdr_u_int32_t(xdrs, &(rr->rj_vers.high)));
+
+ case AUTH_ERROR:
+ return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
+ }
+ return (FALSE);
+}
+
+static struct xdr_discrim reply_dscrm[3] = {
+ { (int)MSG_ACCEPTED, xdr_accepted_reply },
+ { (int)MSG_DENIED, xdr_rejected_reply },
+ { __dontcare__, NULL_xdrproc_t } };
+
+/*
+ * XDR a reply message
+ */
+bool_t
+xdr_replymsg(xdrs, rmsg)
+ register XDR *xdrs;
+ register struct rpc_msg *rmsg;
+{
+ if (
+ xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
+ xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
+ (rmsg->rm_direction == REPLY) )
+ return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
+ (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
+ return (FALSE);
+}
+
+
+/*
+ * Serializes the "static part" of a call message header.
+ * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
+ * The rm_xid is not really static, but the user can easily munge on the fly.
+ */
+bool_t
+xdr_callhdr(xdrs, cmsg)
+ register XDR *xdrs;
+ register struct rpc_msg *cmsg;
+{
+
+ cmsg->rm_direction = CALL;
+ cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ if (
+ (xdrs->x_op == XDR_ENCODE) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) &&
+ xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) )
+ return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)));
+ return (FALSE);
+}
+
+/* ************************** Client utility routine ************* */
+
+static void
+accepted(acpt_stat, error)
+ register enum accept_stat acpt_stat;
+ register struct rpc_err *error;
+{
+
+ switch (acpt_stat) {
+
+ case PROG_UNAVAIL:
+ error->re_status = RPC_PROGUNAVAIL;
+ return;
+
+ case PROG_MISMATCH:
+ error->re_status = RPC_PROGVERSMISMATCH;
+ return;
+
+ case PROC_UNAVAIL:
+ error->re_status = RPC_PROCUNAVAIL;
+ return;
+
+ case GARBAGE_ARGS:
+ error->re_status = RPC_CANTDECODEARGS;
+ return;
+
+ case SYSTEM_ERR:
+ error->re_status = RPC_SYSTEMERROR;
+ return;
+
+ case SUCCESS:
+ error->re_status = RPC_SUCCESS;
+ return;
+ }
+ /* something's wrong, but we don't know what ... */
+ error->re_status = RPC_FAILED;
+ error->re_lb.s1 = (long)MSG_ACCEPTED;
+ error->re_lb.s2 = (long)acpt_stat;
+}
+
+static void
+rejected(rjct_stat, error)
+ register enum reject_stat rjct_stat;
+ register struct rpc_err *error;
+{
+
+ switch (rjct_stat) {
+
+ case RPC_VERSMISMATCH:
+ error->re_status = RPC_VERSMISMATCH;
+ return;
+
+ case AUTH_ERROR:
+ error->re_status = RPC_AUTHERROR;
+ return;
+ default:
+ break;
+ }
+ /* something's wrong, but we don't know what ... */
+ error->re_status = RPC_FAILED;
+ error->re_lb.s1 = (long)MSG_DENIED;
+ error->re_lb.s2 = (long)rjct_stat;
+}
+
+/*
+ * given a reply message, fills in the error
+ */
+void
+_seterr_reply(msg, error)
+ register struct rpc_msg *msg;
+ register struct rpc_err *error;
+{
+
+ /* optimized for normal, SUCCESSful case */
+ switch (msg->rm_reply.rp_stat) {
+
+ case MSG_ACCEPTED:
+ if (msg->acpted_rply.ar_stat == SUCCESS) {
+ error->re_status = RPC_SUCCESS;
+ return;
+ };
+ accepted(msg->acpted_rply.ar_stat, error);
+ break;
+
+ case MSG_DENIED:
+ rejected(msg->rjcted_rply.rj_stat, error);
+ break;
+
+ default:
+ error->re_status = RPC_FAILED;
+ error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
+ break;
+ }
+ switch (error->re_status) {
+
+ case RPC_VERSMISMATCH:
+ error->re_vers.low = msg->rjcted_rply.rj_vers.low;
+ error->re_vers.high = msg->rjcted_rply.rj_vers.high;
+ break;
+
+ case RPC_AUTHERROR:
+ error->re_why = msg->rjcted_rply.rj_why;
+ break;
+
+ case RPC_PROGVERSMISMATCH:
+ error->re_vers.low = msg->acpted_rply.ar_vers.low;
+ error->re_vers.high = msg->acpted_rply.ar_vers.high;
+ break;
+ default:
+ break;
+ }
+}
diff --git a/lib/libc/rpc/rpc_secure.3 b/lib/libc/rpc/rpc_secure.3
new file mode 100644
index 0000000..23f1a7e
--- /dev/null
+++ b/lib/libc/rpc/rpc_secure.3
@@ -0,0 +1,239 @@
+.\" @(#)rpc_secure.3n 2.1 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI
+.\" $FreeBSD$
+.\"
+.Dd February 16, 1988
+.Dt RPC 3
+.Sh NAME
+.Nm rpc_secure
+.Nd library routines for secure remote procedure calls
+.Sh SYNOPSIS
+.Fd #include <rpc/rpc.h>
+.Ft AUTH *
+.Fo authdes_create
+.Fa "char *name"
+.Fa "unsigned window"
+.Fa "struct sockaddr *addr"
+.Fa "des_block *ckey"
+.Fc
+.Ft int
+.Fn authdes_getucred "struct authdes_cred *adc" "uid_t *uid" "gid_t *gid" "int *grouplen" "gid_t *groups"
+.Ft int
+.Fn getnetname "char *name"
+.Ft int
+.Fn host2netname "char *name" "char *host" "char *domain"
+.Ft int
+.Fn key_decryptsession "const char *remotename" "des_block *deskey"
+.Ft int
+.Fn key_encryptsession "const char *remotename" "des_block *deskey"
+.Ft int
+.Fn key_gendes "des_block *deskey"
+.Ft int
+.Fn key_setsecret "const char *key"
+.Ft int
+.Fn netname2host "char *name" "char *host" "int hostlen"
+.Ft int
+.Fn netname2user "char *name" "uid_t *uidp" "gid_t *gidp" "int *gidlenp" "gid_t *gidlist"
+.Ft int
+.Fn user2netname "char *name" "uid_t uid" "char *domain"
+.Sh DESCRIPTION
+These routines are part of the
+.Tn RPC
+library. They implement
+.Tn DES
+Authentication. See
+.Xr rpc 3
+for further details about
+.Tn RPC .
+.Pp
+The
+.Fn authdes_create
+is the first of two routines which interface to the
+.Tn RPC
+secure authentication system, known as
+.Tn DES
+authentication.
+The second is
+.Fn authdes_getucred ,
+below.
+.Pp
+Note: the keyserver daemon
+.Xr keyserv 8
+must be running for the
+.Tn DES
+authentication system to work.
+.Pp
+.Fn Authdes_create ,
+used on the client side, returns an authentication handle that
+will enable the use of the secure authentication system.
+The first parameter
+.Fa name
+is the network name, or
+.Fa netname ,
+of the owner of the server process. This field usually
+represents a
+.Fa hostname
+derived from the utility routine
+.Fn host2netname ,
+but could also represent a user name using
+.Fn user2netname .
+The second field is window on the validity of
+the client credential, given in seconds. A small
+window is more secure than a large one, but choosing
+too small of a window will increase the frequency of
+resynchronizations because of clock drift. The third
+parameter
+.Fa addr
+is optional. If it is
+.Dv NULL ,
+then the authentication system will assume
+that the local clock is always in sync with the server's
+clock, and will not attempt resynchronizations. If an address
+is supplied, however, then the system will use the address
+for consulting the remote time service whenever
+resynchronization
+is required. This parameter is usually the
+address of the
+.Tn RPC
+server itself. The final parameter
+.Fa ckey
+is also optional. If it is
+.Dv NULL ,
+then the authentication system will
+generate a random
+.Tn DES
+key to be used for the encryption of credentials.
+If it is supplied, however, then it will be used instead.
+.Pp
+.Fn Authdes_getucred ,
+the second of the two
+.Tn DES
+authentication routines,
+is used on the server side for converting a
+.Tn DES
+credential, which is
+operating system independent, into a
+.Ux
+credential. This routine differs from utility routine
+.Fn netname2user
+in that
+.Fn authdes_getucred
+pulls its information from a cache, and does not have to do a
+Yellow Pages lookup every time it is called to get its information.
+.Pp
+.Fn Getnetname
+installs the unique, operating-system independent netname of
+the
+caller in the fixed-length array
+.Fa name .
+Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails.
+.Pp
+.Fn Host2netname
+converts from a domain-specific hostname to an
+operating-system independent netname. Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails. Inverse of
+.Fn netname2host .
+.Pp
+.Fn Key_decryptsession
+is an interface to the keyserver daemon, which is associated
+with
+.Tn RPC Ns 's
+secure authentication system (
+.Tn DES
+authentication).
+User programs rarely need to call it, or its associated routines
+.Fn key_encryptsession ,
+.Fn key_gendes
+and
+.Fn key_setsecret .
+System commands such as
+.Xr login 1
+and the
+.Tn RPC
+library are the main clients of these four routines.
+.Pp
+.Fn Key_decryptsession
+takes a server netname and a
+.Tn DES
+key, and decrypts the key by
+using the the public key of the the server and the secret key
+associated with the effective uid of the calling process. It
+is the inverse of
+.Fn key_encryptsession .
+.Pp
+.Fn Key_encryptsession
+is a keyserver interface routine. It
+takes a server netname and a des key, and encrypts
+it using the public key of the the server and the secret key
+associated with the effective uid of the calling process. It
+is the inverse of
+.Fn key_decryptsession .
+.Pp
+.Fn Key_gendes
+is a keyserver interface routine. It
+is used to ask the keyserver for a secure conversation key.
+Choosing one
+.Qq random
+is usually not good enough,
+because
+the common ways of choosing random numbers, such as using the
+current time, are very easy to guess.
+.Pp
+.Fn Key_setsecret
+is a keyserver interface routine. It is used to set the key for
+the effective
+.Fa uid
+of the calling process.
+.Pp
+.Fn Netname2host
+converts from an operating-system independent netname to a
+domain-specific hostname. Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails. Inverse of
+.Fn host2netname .
+.Pp
+.Fn Netname2user
+converts from an operating-system independent netname to a
+domain-specific user ID.
+Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails. Inverse of
+.Fn user2netname .
+.Pp
+.Fn User2netname
+converts from a domain-specific username to an operating-system
+independent netname. Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails. Inverse of
+.Fn netname2user .
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr xdr 3 ,
+.Xr keyserv 8
+.Pp
+The following manuals:
+.Rs
+.%B Remote Procedure Calls: Protocol Specification
+.Re
+.Rs
+.%B Remote Procedure Call Programming Guide
+.Re
+.Rs
+.%B Rpcgen Programming Guide
+.Re
+.Rs
+.%B RPC: Remote Procedure Call Protocol Specification
+.%O RFC1050, Sun Microsystems Inc., USC-ISI
+.Re
diff --git a/lib/libc/rpc/rpcdname.c b/lib/libc/rpc/rpcdname.c
new file mode 100644
index 0000000..f28b4fd
--- /dev/null
+++ b/lib/libc/rpc/rpcdname.c
@@ -0,0 +1,77 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rpcdname.c 1.7 91/03/11 Copyr 1989 Sun Micro";
+#endif
+
+/*
+ * rpcdname.c
+ * Gets the default domain name
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+static char *default_domain = 0;
+
+static char *
+get_default_domain()
+{
+ char temp[256];
+
+ if (default_domain)
+ return (default_domain);
+ if (getdomainname(temp, sizeof(temp)) < 0)
+ return (0);
+ if ((int) strlen(temp) > 0) {
+ default_domain = (char *)malloc((strlen(temp)+(unsigned)1));
+ if (default_domain == 0)
+ return (0);
+ (void) strcpy(default_domain, temp);
+ return (default_domain);
+ }
+ return (0);
+}
+
+/*
+ * This is a wrapper for the system call getdomainname which returns a
+ * ypclnt.h error code in the failure case. It also checks to see that
+ * the domain name is non-null, knowing that the null string is going to
+ * get rejected elsewhere in the NIS client package.
+ */
+int
+_rpc_get_default_domain(domain)
+ char **domain;
+{
+ if ((*domain = get_default_domain()) != 0)
+ return (0);
+ return (-1);
+}
diff --git a/lib/libc/rpc/rstat.1 b/lib/libc/rpc/rstat.1
new file mode 100644
index 0000000..b302282
--- /dev/null
+++ b/lib/libc/rpc/rstat.1
@@ -0,0 +1,58 @@
+.\" $FreeBSD$
+.\" @(#)rstat.1 2.1 88/08/03 4.0 RPCSRC
+.TH RSTAT 1 "3 August 1988"
+.SH NAME
+rstat \- remote status display
+.SH SYNOPSIS
+.B rstat
+.B host
+.SH DESCRIPTION
+.LP
+.B rstat
+displays a summary of the current system status of a particular
+.BR host .
+The output shows the current time of day, how long the system has
+been up,
+and the load averages.
+The load average numbers give the number of jobs in the run queue
+averaged over 1, 5 and 15 minutes.
+.PP
+The
+.B rstat_svc(8)
+daemon must be running on the remote host for this command to
+work.
+.B rstat
+uses an RPC protocol defined in /usr/include/rpcsvc/rstat.x.
+.SH EXAMPLE
+.RS
+.ft B
+.nf
+example% rstat otherhost
+7:36am up 6 days, 16:45, load average: 0.20, 0.23, 0.18
+example%
+.ft R
+.fi
+.RE
+.SH DIAGNOSTICS
+.LP
+rstat: RPC: Program not registered
+.IP
+The
+.B rstat_svc
+daemon has not been started on the remote host.
+.LP
+rstat: RPC: Timed out
+.IP
+A communication error occurred. Either the network is
+excessively congested, or the
+.B rstat_svc
+daemon has terminated on the remote host.
+.LP
+rstat: RPC: Port mapper failure - RPC: Timed out
+.IP
+The remote host is not running the portmapper (see
+.BR portmap(8) ),
+and cannot accommodate any RPC-based services. The host may be down.
+.SH "SEE ALSO"
+.BR portmap (8),
+.BR rstat_svc (8)
diff --git a/lib/libc/rpc/rstat_svc.8 b/lib/libc/rpc/rstat_svc.8
new file mode 100644
index 0000000..103cbf5
--- /dev/null
+++ b/lib/libc/rpc/rstat_svc.8
@@ -0,0 +1,22 @@
+.\" $FreeBSD$
+.\" @(#)rstat_svc.8c 2.2 88/08/03 4.0 RPCSRC; from 1.10 87/09/09 SMI
+.TH RSTAT_SVC 8 "24 November 1987"
+.SH NAME
+rstat_svc \- kernel statistics server
+.SH SYNOPSIS
+.B /etc/rstat_svc
+.SH DESCRIPTION
+.LP
+.B rstat_svc
+is a server which returns performance statistics
+obtained from the kernel.
+These statistics are graphically displayed by the Sun Microsystems program,
+.BR perfmeter (1).
+The
+.B rstat_svc
+daemon is normally invoked at boot time through /etc/rc.local.
+.PP
+.B rstat_svc
+uses an RPC protocol defined in /usr/include/rpcsvc/rstat.x.
+.\" .SH "SEE ALSO"
+.\" .BR rstat (1),
diff --git a/lib/libc/rpc/rtime.3 b/lib/libc/rpc/rtime.3
new file mode 100644
index 0000000..de19866
--- /dev/null
+++ b/lib/libc/rpc/rtime.3
@@ -0,0 +1,45 @@
+.\" @(#)rtime.3n 2.1 88/08/08 4.0 RPCSRC; from 1.5 88/02/08 SMI
+.\" $FreeBSD$
+.\"
+.TH RTIME 3 "22 November 1987"
+.SH NAME
+rtime \- get remote time
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/time.h>
+.B #include <netinet/in.h>
+.LP
+.B int rtime(addrp, timep, timeout)
+.B struct sockaddr_in \(**addrp;
+.B struct timeval \(**timep;
+.B struct timeval \(**timeout;
+.fi
+.SH DESCRIPTION
+.B rtime(\|)
+consults the Internet Time Server at the address pointed to by
+.I addrp
+and returns the remote time in the
+.B timeval
+struct pointed to by
+.IR timep .
+Normally, the
+.SM UDP
+protocol is used when consulting the Time Server. The
+.I timeout
+parameter specifies how long the
+routine should wait before giving
+up when waiting for a reply. If
+.I timeout
+is specified as
+.SM NULL\s0,
+however, the routine will instead use
+.SM TCP
+and block until a reply is received from the time server.
+.LP
+The routine returns 0 if it is successful. Otherwise,
+it returns \-1 and
+.B errno
+is set to reflect the cause of the error.
+.SH "SEE ALSO"
+.BR timed (8c)
diff --git a/lib/libc/rpc/rtime.c b/lib/libc/rpc/rtime.c
new file mode 100644
index 0000000..4e65c03
--- /dev/null
+++ b/lib/libc/rpc/rtime.c
@@ -0,0 +1,157 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+
+ */
+
+/*
+ * rtime - get time from remote machine
+ *
+ * gets time, obtaining value from host
+ * on the udp/time socket. Since timeserver returns
+ * with time of day in seconds since Jan 1, 1900, must
+ * subtract seconds before Jan 1, 1970 to get
+ * what unix uses.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <netdb.h>
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/* from: static char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI"; */
+static const char rcsid[] = "$FreeBSD$";
+#endif
+
+extern int _rpc_dtablesize __P(( void ));
+
+#define NYEARS (unsigned long)(1970 - 1900)
+#define TOFFSET (unsigned long)(60*60*24*(365*NYEARS + (NYEARS/4)))
+
+static void do_close __P(( int ));
+
+int
+rtime(addrp, timep, timeout)
+ struct sockaddr_in *addrp;
+ struct timeval *timep;
+ struct timeval *timeout;
+{
+ int s;
+ fd_set readfds;
+ int res;
+ unsigned long thetime;
+ struct sockaddr_in from;
+ int fromlen;
+ int type;
+ struct servent *serv;
+
+ if (timeout == NULL) {
+ type = SOCK_STREAM;
+ } else {
+ type = SOCK_DGRAM;
+ }
+ s = socket(AF_INET, type, 0);
+ if (s < 0) {
+ return(-1);
+ }
+ addrp->sin_family = AF_INET;
+
+ /* TCP and UDP port are the same in this case */
+ if ((serv = getservbyname("time", "tcp")) == NULL) {
+ return(-1);
+ }
+
+ addrp->sin_port = serv->s_port;
+
+ if (type == SOCK_DGRAM) {
+ res = sendto(s, (char *)&thetime, sizeof(thetime), 0,
+ (struct sockaddr *)addrp, sizeof(*addrp));
+ if (res < 0) {
+ do_close(s);
+ return(-1);
+ }
+ do {
+ FD_ZERO(&readfds);
+ FD_SET(s, &readfds);
+ res = select(_rpc_dtablesize(), &readfds,
+ (fd_set *)NULL, (fd_set *)NULL, timeout);
+ } while (res < 0 && errno == EINTR);
+ if (res <= 0) {
+ if (res == 0) {
+ errno = ETIMEDOUT;
+ }
+ do_close(s);
+ return(-1);
+ }
+ fromlen = sizeof(from);
+ res = recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
+ (struct sockaddr *)&from, &fromlen);
+ do_close(s);
+ if (res < 0) {
+ return(-1);
+ }
+ } else {
+ if (connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) {
+ do_close(s);
+ return(-1);
+ }
+ res = read(s, (char *)&thetime, sizeof(thetime));
+ do_close(s);
+ if (res < 0) {
+ return(-1);
+ }
+ }
+ if (res != sizeof(thetime)) {
+ errno = EIO;
+ return(-1);
+ }
+ thetime = ntohl(thetime);
+ timep->tv_sec = thetime - TOFFSET;
+ timep->tv_usec = 0;
+ return(0);
+}
+
+static void
+do_close(s)
+ int s;
+{
+ int save;
+
+ save = errno;
+ (void) close(s);
+ errno = save;
+}
diff --git a/lib/libc/rpc/svc.c b/lib/libc/rpc/svc.c
new file mode 100644
index 0000000..1f9803b
--- /dev/null
+++ b/lib/libc/rpc/svc.c
@@ -0,0 +1,494 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc.c 2.4 88/08/11 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * svc.c, Server-side remote procedure call interface.
+ *
+ * There are two sets of procedures here. The xprt routines are
+ * for handling transport handles. The svc routines handle the
+ * list of service routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/errno.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+
+static SVCXPRT **xports;
+static int xportssize;
+
+#define NULL_SVC ((struct svc_callout *)0)
+#define RQCRED_SIZE 400 /* this size is excessive */
+
+#define max(a, b) (a > b ? a : b)
+
+/*
+ * The services list
+ * Each entry represents a set of procedures (an rpc program).
+ * The dispatch routine takes request structs and runs the
+ * apropriate procedure.
+ */
+static struct svc_callout {
+ struct svc_callout *sc_next;
+ u_long sc_prog;
+ u_long sc_vers;
+ void (*sc_dispatch)();
+} *svc_head;
+
+static struct svc_callout *svc_find();
+
+int __svc_fdsetsize = 0;
+fd_set *__svc_fdset = NULL;
+
+/* *************** SVCXPRT related stuff **************** */
+
+/*
+ * Activate a transport handle.
+ */
+void
+xprt_register(xprt)
+ SVCXPRT *xprt;
+{
+ register int sock = xprt->xp_sock;
+
+ if (sock + 1 > __svc_fdsetsize) {
+ int bytes = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
+ fd_set *fds;
+
+ fds = (fd_set *)malloc(bytes);
+ memset(fds, 0, bytes);
+ if (__svc_fdset) {
+ memcpy(fds, __svc_fdset, howmany(__svc_fdsetsize,
+ NFDBITS) * sizeof(fd_mask));
+ free(__svc_fdset);
+ }
+ __svc_fdset = fds;
+ __svc_fdsetsize = howmany(sock+1, NFDBITS) * NFDBITS;
+ }
+
+ if (sock < FD_SETSIZE)
+ FD_SET(sock, &svc_fdset);
+ FD_SET(sock, __svc_fdset);
+
+ if (xports == NULL || sock + 1 > xportssize) {
+ SVCXPRT **xp;
+ int size = FD_SETSIZE;
+
+ if (sock + 1 > size)
+ size = sock + 1;
+ xp = (SVCXPRT **)mem_alloc(size * sizeof(SVCXPRT *));
+ memset(xp, 0, size * sizeof(SVCXPRT *));
+ if (xports) {
+ memcpy(xp, xports, xportssize * sizeof(SVCXPRT *));
+ free(xports);
+ }
+ xportssize = size;
+ xports = xp;
+ }
+ xports[sock] = xprt;
+ svc_maxfd = max(svc_maxfd, sock);
+}
+
+/*
+ * De-activate a transport handle.
+ */
+void
+xprt_unregister(xprt)
+ SVCXPRT *xprt;
+{
+ register int sock = xprt->xp_sock;
+
+ if (xports[sock] == xprt) {
+ xports[sock] = (SVCXPRT *)0;
+ if (sock < FD_SETSIZE)
+ FD_CLR(sock, &svc_fdset);
+ FD_CLR(sock, __svc_fdset);
+ if (sock == svc_maxfd) {
+ for (svc_maxfd--; svc_maxfd >= 0; svc_maxfd--)
+ if (xports[svc_maxfd])
+ break;
+ }
+ /*
+ * XXX could use svc_maxfd as a hint to
+ * decrease the size of __svc_fdset
+ */
+ }
+}
+
+
+/* ********************** CALLOUT list related stuff ************* */
+
+/*
+ * Add a service program to the callout list.
+ * The dispatch routine will be called when a rpc request for this
+ * program number comes in.
+ */
+bool_t
+svc_register(xprt, prog, vers, dispatch, protocol)
+ SVCXPRT *xprt;
+ u_long prog;
+ u_long vers;
+ void (*dispatch)();
+ int protocol;
+{
+ struct svc_callout *prev;
+ register struct svc_callout *s;
+
+ if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) {
+ if (s->sc_dispatch == dispatch)
+ goto pmap_it; /* he is registering another xptr */
+ return (FALSE);
+ }
+ s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout));
+ if (s == (struct svc_callout *)0) {
+ return (FALSE);
+ }
+ s->sc_prog = prog;
+ s->sc_vers = vers;
+ s->sc_dispatch = dispatch;
+ s->sc_next = svc_head;
+ svc_head = s;
+pmap_it:
+ /* now register the information with the local binder service */
+ if (protocol) {
+ return (pmap_set(prog, vers, protocol, xprt->xp_port));
+ }
+ return (TRUE);
+}
+
+/*
+ * Remove a service program from the callout list.
+ */
+void
+svc_unregister(prog, vers)
+ u_long prog;
+ u_long vers;
+{
+ struct svc_callout *prev;
+ register struct svc_callout *s;
+
+ if ((s = svc_find(prog, vers, &prev)) == NULL_SVC)
+ return;
+ if (prev == NULL_SVC) {
+ svc_head = s->sc_next;
+ } else {
+ prev->sc_next = s->sc_next;
+ }
+ s->sc_next = NULL_SVC;
+ mem_free((char *) s, (u_int) sizeof(struct svc_callout));
+ /* now unregister the information with the local binder service */
+ (void)pmap_unset(prog, vers);
+}
+
+/*
+ * Search the callout list for a program number, return the callout
+ * struct.
+ */
+static struct svc_callout *
+svc_find(prog, vers, prev)
+ u_long prog;
+ u_long vers;
+ struct svc_callout **prev;
+{
+ register struct svc_callout *s, *p;
+
+ p = NULL_SVC;
+ for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
+ if ((s->sc_prog == prog) && (s->sc_vers == vers))
+ goto done;
+ p = s;
+ }
+done:
+ *prev = p;
+ return (s);
+}
+
+/* ******************* REPLY GENERATION ROUTINES ************ */
+
+/*
+ * Send a reply to an rpc request
+ */
+bool_t
+svc_sendreply(xprt, xdr_results, xdr_location)
+ register SVCXPRT *xprt;
+ xdrproc_t xdr_results;
+ caddr_t xdr_location;
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = SUCCESS;
+ rply.acpted_rply.ar_results.where = xdr_location;
+ rply.acpted_rply.ar_results.proc = xdr_results;
+ return (SVC_REPLY(xprt, &rply));
+}
+
+/*
+ * No procedure error reply
+ */
+void
+svcerr_noproc(xprt)
+ register SVCXPRT *xprt;
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = PROC_UNAVAIL;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Can't decode args error reply
+ */
+void
+svcerr_decode(xprt)
+ register SVCXPRT *xprt;
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = GARBAGE_ARGS;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Some system error
+ */
+void
+svcerr_systemerr(xprt)
+ register SVCXPRT *xprt;
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = SYSTEM_ERR;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Authentication error reply
+ */
+void
+svcerr_auth(xprt, why)
+ SVCXPRT *xprt;
+ enum auth_stat why;
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_DENIED;
+ rply.rjcted_rply.rj_stat = AUTH_ERROR;
+ rply.rjcted_rply.rj_why = why;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Auth too weak error reply
+ */
+void
+svcerr_weakauth(xprt)
+ SVCXPRT *xprt;
+{
+
+ svcerr_auth(xprt, AUTH_TOOWEAK);
+}
+
+/*
+ * Program unavailable error reply
+ */
+void
+svcerr_noprog(xprt)
+ register SVCXPRT *xprt;
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = PROG_UNAVAIL;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Program version mismatch error reply
+ */
+void
+svcerr_progvers(xprt, low_vers, high_vers)
+ register SVCXPRT *xprt;
+ u_long low_vers;
+ u_long high_vers;
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = PROG_MISMATCH;
+ rply.acpted_rply.ar_vers.low = low_vers;
+ rply.acpted_rply.ar_vers.high = high_vers;
+ SVC_REPLY(xprt, &rply);
+}
+
+/* ******************* SERVER INPUT STUFF ******************* */
+
+/*
+ * Get server side input from some transport.
+ *
+ * Statement of authentication parameters management:
+ * This function owns and manages all authentication parameters, specifically
+ * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and
+ * the "cooked" credentials (rqst->rq_clntcred).
+ * However, this function does not know the structure of the cooked
+ * credentials, so it make the following assumptions:
+ * a) the structure is contiguous (no pointers), and
+ * b) the cred structure size does not exceed RQCRED_SIZE bytes.
+ * In all events, all three parameters are freed upon exit from this routine.
+ * The storage is trivially management on the call stack in user land, but
+ * is mallocated in kernel land.
+ */
+
+void
+svc_getreq(rdfds)
+ int rdfds;
+{
+ fd_set readfds;
+
+ FD_ZERO(&readfds);
+ readfds.fds_bits[0] = rdfds;
+ svc_getreqset(&readfds);
+}
+
+void
+svc_getreqset(readfds)
+ fd_set *readfds;
+{
+ svc_getreqset2(readfds, FD_SETSIZE);
+}
+
+void
+svc_getreqset2(readfds, width)
+ fd_set *readfds;
+ int width;
+{
+ enum xprt_stat stat;
+ struct rpc_msg msg;
+ int prog_found;
+ u_long low_vers;
+ u_long high_vers;
+ struct svc_req r;
+ register SVCXPRT *xprt;
+ register int bit;
+ register int sock;
+ register fd_mask mask, *maskp;
+ char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE];
+ msg.rm_call.cb_cred.oa_base = cred_area;
+ msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
+ r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);
+
+
+ maskp = readfds->fds_bits;
+ for (sock = 0; sock < width; sock += NFDBITS) {
+ for (mask = *maskp++; (bit = ffs(mask)); mask ^= (1 << (bit - 1))) {
+ /* sock has input waiting */
+ xprt = xports[sock + bit - 1];
+ if (xprt == NULL)
+ /* But do we control sock? */
+ continue;
+ /* now receive msgs from xprtprt (support batch calls) */
+ do {
+ if (SVC_RECV(xprt, &msg)) {
+
+ /* now find the exported program and call it */
+ register struct svc_callout *s;
+ enum auth_stat why;
+
+ r.rq_xprt = xprt;
+ r.rq_prog = msg.rm_call.cb_prog;
+ r.rq_vers = msg.rm_call.cb_vers;
+ r.rq_proc = msg.rm_call.cb_proc;
+ r.rq_cred = msg.rm_call.cb_cred;
+ /* first authenticate the message */
+ if ((why= _authenticate(&r, &msg)) != AUTH_OK) {
+ svcerr_auth(xprt, why);
+ goto call_done;
+ }
+ /* now match message with a registered service*/
+ prog_found = FALSE;
+ low_vers = (u_long) - 1;
+ high_vers = 0;
+ for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
+ if (s->sc_prog == r.rq_prog) {
+ if (s->sc_vers == r.rq_vers) {
+ (*s->sc_dispatch)(&r, xprt);
+ goto call_done;
+ } /* found correct version */
+ prog_found = TRUE;
+ if (s->sc_vers < low_vers)
+ low_vers = s->sc_vers;
+ if (s->sc_vers > high_vers)
+ high_vers = s->sc_vers;
+ } /* found correct program */
+ }
+ /*
+ * if we got here, the program or version
+ * is not served ...
+ */
+ if (prog_found)
+ svcerr_progvers(xprt,
+ low_vers, high_vers);
+ else
+ svcerr_noprog(xprt);
+ /* Fall through to ... */
+ }
+ call_done:
+ if ((stat = SVC_STAT(xprt)) == XPRT_DIED){
+ SVC_DESTROY(xprt);
+ break;
+ }
+ } while (stat == XPRT_MOREREQS);
+ }
+ }
+}
diff --git a/lib/libc/rpc/svc_auth.c b/lib/libc/rpc/svc_auth.c
new file mode 100644
index 0000000..0063e75
--- /dev/null
+++ b/lib/libc/rpc/svc_auth.c
@@ -0,0 +1,211 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1986-1991 by Sun Microsystems Inc.
+ */
+
+#ident "@(#)svc_auth.c 1.16 94/04/24 SMI"
+
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_auth.c, Server-side rpc authenticator interface.
+ *
+ */
+
+#ifdef KERNEL
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/clnt.h>
+#include <rpc/rpc_msg.h>
+#include <rpc/svc.h>
+#include <rpc/svc_auth.h>
+#else
+#include <stdlib.h>
+#include <rpc/rpc.h>
+#endif
+#include <sys/types.h>
+
+/*
+ * svcauthsw is the bdevsw of server side authentication.
+ *
+ * Server side authenticators are called from authenticate by
+ * using the client auth struct flavor field to index into svcauthsw.
+ * The server auth flavors must implement a routine that looks
+ * like:
+ *
+ * enum auth_stat
+ * flavorx_auth(rqst, msg)
+ * register struct svc_req *rqst;
+ * register struct rpc_msg *msg;
+ *
+ */
+
+enum auth_stat _svcauth_null(); /* no authentication */
+enum auth_stat _svcauth_unix(); /* (system) unix style (uid, gids) */
+enum auth_stat _svcauth_short(); /* short hand unix style */
+enum auth_stat _svcauth_des(); /* des style */
+
+/* declarations to allow servers to specify new authentication flavors */
+struct authsvc {
+ int flavor;
+ enum auth_stat (*handler)();
+ struct authsvc *next;
+};
+static struct authsvc *Auths = NULL;
+
+/*
+ * The call rpc message, msg has been obtained from the wire. The msg contains
+ * the raw form of credentials and verifiers. authenticate returns AUTH_OK
+ * if the msg is successfully authenticated. If AUTH_OK then the routine also
+ * does the following things:
+ * set rqst->rq_xprt->verf to the appropriate response verifier;
+ * sets rqst->rq_client_cred to the "cooked" form of the credentials.
+ *
+ * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
+ * its length is set appropriately.
+ *
+ * The caller still owns and is responsible for msg->u.cmb.cred and
+ * msg->u.cmb.verf. The authentication system retains ownership of
+ * rqst->rq_client_cred, the cooked credentials.
+ *
+ * There is an assumption that any flavour less than AUTH_NULL is
+ * invalid.
+ */
+enum auth_stat
+_authenticate(rqst, msg)
+ register struct svc_req *rqst;
+ struct rpc_msg *msg;
+{
+ register int cred_flavor;
+ register struct authsvc *asp;
+
+ rqst->rq_cred = msg->rm_call.cb_cred;
+ rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
+ rqst->rq_xprt->xp_verf.oa_length = 0;
+ cred_flavor = rqst->rq_cred.oa_flavor;
+ switch (cred_flavor) {
+ case AUTH_NULL:
+ return(_svcauth_null(rqst, msg));
+ case AUTH_UNIX:
+ return(_svcauth_unix(rqst, msg));
+ case AUTH_SHORT:
+ return(_svcauth_short(rqst, msg));
+ /*
+ * We leave AUTH_DES turned off by default because svcauth_des()
+ * needs getpublickey(), which is in librpcsvc, not libc. If we
+ * included AUTH_DES as a built-in flavor, programs that don't
+ * have -lrpcsvc in their Makefiles wouldn't link correctly, even
+ * though they don't use AUTH_DES. And I'm too lazy to go through
+ * the tree looking for all of them.
+ */
+#ifdef DES_BUILTIN
+ case AUTH_DES:
+ return(_svcauth_des(rqst, msg));
+#endif
+ }
+
+ /* flavor doesn't match any of the builtin types, so try new ones */
+ for (asp = Auths; asp; asp = asp->next) {
+ if (asp->flavor == cred_flavor) {
+ enum auth_stat as;
+
+ as = (*asp->handler)(rqst, msg);
+ return (as);
+ }
+ }
+
+ return (AUTH_REJECTEDCRED);
+}
+
+/*ARGSUSED*/
+enum auth_stat
+_svcauth_null(rqst, msg)
+ struct svc_req *rqst;
+ struct rpc_msg *msg;
+{
+ return (AUTH_OK);
+}
+
+/*
+ * Allow the rpc service to register new authentication types that it is
+ * prepared to handle. When an authentication flavor is registered,
+ * the flavor is checked against already registered values. If not
+ * registered, then a new Auths entry is added on the list.
+ *
+ * There is no provision to delete a registration once registered.
+ *
+ * This routine returns:
+ * 0 if registration successful
+ * 1 if flavor already registered
+ * -1 if can't register (errno set)
+ */
+
+int
+svc_auth_reg(cred_flavor, handler)
+ register int cred_flavor;
+ enum auth_stat (*handler)();
+{
+ register struct authsvc *asp;
+
+ switch (cred_flavor) {
+ case AUTH_NULL:
+ case AUTH_UNIX:
+ case AUTH_SHORT:
+#ifdef DES_BUILTIN
+ case AUTH_DES:
+#endif
+ /* already registered */
+ return (1);
+
+ default:
+ for (asp = Auths; asp; asp = asp->next) {
+ if (asp->flavor == cred_flavor) {
+ /* already registered */
+ return (1);
+ }
+ }
+
+ /* this is a new one, so go ahead and register it */
+ asp = (struct authsvc *)mem_alloc(sizeof (*asp));
+ if (asp == NULL) {
+ return (-1);
+ }
+ asp->flavor = cred_flavor;
+ asp->handler = handler;
+ asp->next = Auths;
+ Auths = asp;
+ break;
+ }
+ return (0);
+}
diff --git a/lib/libc/rpc/svc_auth_des.c b/lib/libc/rpc/svc_auth_des.c
new file mode 100644
index 0000000..6a937f5
--- /dev/null
+++ b/lib/libc/rpc/svc_auth_des.c
@@ -0,0 +1,531 @@
+
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * svcauth_des.c, server-side des authentication
+ *
+ * We insure for the service the following:
+ * (1) The timestamp microseconds do not exceed 1 million.
+ * (2) The timestamp plus the window is less than the current time.
+ * (3) The timestamp is not less than the one previously
+ * seen in the current session.
+ *
+ * It is up to the server to determine if the window size is
+ * too small .
+ *
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <rpc/des_crypt.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_des.h>
+#include <rpc/svc.h>
+#include <rpc/rpc_msg.h>
+#include <rpc/svc_auth.h>
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/* from: static char sccsid[] = "@(#)svcauth_des.c 2.3 89/07/11 4.0 RPCSRC; from 1.15 88/02/08 SMI"; */
+static const char rcsid[] = "$FreeBSD$";
+#endif
+
+#define debug(msg) printf("svcauth_des: %s\n", msg)
+
+#define USEC_PER_SEC ((u_long) 1000000L)
+#define BEFORE(t1, t2) timercmp(t1, t2, <)
+
+/*
+ * LRU cache of conversation keys and some other useful items.
+ */
+#define AUTHDES_CACHESZ 64
+struct cache_entry {
+ des_block key; /* conversation key */
+ char *rname; /* client's name */
+ u_int window; /* credential lifetime window */
+ struct timeval laststamp; /* detect replays of creds */
+ char *localcred; /* generic local credential */
+};
+static struct cache_entry *authdes_cache/* [AUTHDES_CACHESZ] */;
+static short *authdes_lru/* [AUTHDES_CACHESZ] */;
+
+static void cache_init(); /* initialize the cache */
+static short cache_spot(); /* find an entry in the cache */
+static void cache_ref(/*short sid*/); /* note that sid was ref'd */
+
+static void invalidate(); /* invalidate entry in cache */
+
+/*
+ * cache statistics
+ */
+static struct {
+ u_long ncachehits; /* times cache hit, and is not replay */
+ u_long ncachereplays; /* times cache hit, and is replay */
+ u_long ncachemisses; /* times cache missed */
+} svcauthdes_stats;
+
+/*
+ * Service side authenticator for AUTH_DES
+ */
+enum auth_stat
+_svcauth_des(rqst, msg)
+ register struct svc_req *rqst;
+ register struct rpc_msg *msg;
+{
+
+ register long *ixdr;
+ des_block cryptbuf[2];
+ register struct authdes_cred *cred;
+ struct authdes_verf verf;
+ int status;
+ register struct cache_entry *entry;
+ short sid = 0;
+ des_block *sessionkey;
+ des_block ivec;
+ u_int window;
+ struct timeval timestamp;
+ u_long namelen;
+ struct area {
+ struct authdes_cred area_cred;
+ char area_netname[MAXNETNAMELEN+1];
+ } *area;
+
+ if (authdes_cache == NULL) {
+ cache_init();
+ }
+
+ area = (struct area *)rqst->rq_clntcred;
+ cred = (struct authdes_cred *)&area->area_cred;
+
+ /*
+ * Get the credential
+ */
+ ixdr = (long *)msg->rm_call.cb_cred.oa_base;
+ cred->adc_namekind = IXDR_GET_ENUM(ixdr, enum authdes_namekind);
+ switch (cred->adc_namekind) {
+ case ADN_FULLNAME:
+ namelen = IXDR_GET_U_LONG(ixdr);
+ if (namelen > MAXNETNAMELEN) {
+ return (AUTH_BADCRED);
+ }
+ cred->adc_fullname.name = area->area_netname;
+ bcopy((char *)ixdr, cred->adc_fullname.name,
+ (u_int)namelen);
+ cred->adc_fullname.name[namelen] = 0;
+ ixdr += (RNDUP(namelen) / BYTES_PER_XDR_UNIT);
+ cred->adc_fullname.key.key.high = (u_long)*ixdr++;
+ cred->adc_fullname.key.key.low = (u_long)*ixdr++;
+ cred->adc_fullname.window = (u_long)*ixdr++;
+ break;
+ case ADN_NICKNAME:
+ cred->adc_nickname = (u_long)*ixdr++;
+ break;
+ default:
+ return (AUTH_BADCRED);
+ }
+
+ /*
+ * Get the verifier
+ */
+ ixdr = (long *)msg->rm_call.cb_verf.oa_base;
+ verf.adv_xtimestamp.key.high = (u_long)*ixdr++;
+ verf.adv_xtimestamp.key.low = (u_long)*ixdr++;
+ verf.adv_int_u = (u_long)*ixdr++;
+
+
+ /*
+ * Get the conversation key
+ */
+ if (cred->adc_namekind == ADN_FULLNAME) {
+ netobj pkey;
+ char pkey_data[1024];
+
+ sessionkey = &cred->adc_fullname.key;
+ if (! getpublickey(cred->adc_fullname.name, pkey_data)) {
+ debug("getpublickey");
+ return(AUTH_BADCRED);
+ }
+ pkey.n_bytes = pkey_data;
+ pkey.n_len = strlen(pkey_data) + 1;
+ if (key_decryptsession_pk(cred->adc_fullname.name, &pkey,
+ sessionkey) < 0) {
+ debug("decryptsessionkey");
+ return (AUTH_BADCRED); /* key not found */
+ }
+ } else { /* ADN_NICKNAME */
+ sid = (short)cred->adc_nickname;
+ if (sid >= AUTHDES_CACHESZ) {
+ debug("bad nickname");
+ return (AUTH_BADCRED); /* garbled credential */
+ }
+ sessionkey = &authdes_cache[sid].key;
+ }
+
+
+ /*
+ * Decrypt the timestamp
+ */
+ cryptbuf[0] = verf.adv_xtimestamp;
+ if (cred->adc_namekind == ADN_FULLNAME) {
+ cryptbuf[1].key.high = cred->adc_fullname.window;
+ cryptbuf[1].key.low = verf.adv_winverf;
+ ivec.key.high = ivec.key.low = 0;
+ status = cbc_crypt((char *)sessionkey, (char *)cryptbuf,
+ 2*sizeof(des_block), DES_DECRYPT | DES_HW,
+ (char *)&ivec);
+ } else {
+ status = ecb_crypt((char *)sessionkey, (char *)cryptbuf,
+ sizeof(des_block), DES_DECRYPT | DES_HW);
+ }
+ if (DES_FAILED(status)) {
+ debug("decryption failure");
+ return (AUTH_FAILED); /* system error */
+ }
+
+ /*
+ * XDR the decrypted timestamp
+ */
+ ixdr = (long *)cryptbuf;
+ timestamp.tv_sec = IXDR_GET_LONG(ixdr);
+ timestamp.tv_usec = IXDR_GET_LONG(ixdr);
+
+ /*
+ * Check for valid credentials and verifiers.
+ * They could be invalid because the key was flushed
+ * out of the cache, and so a new session should begin.
+ * Be sure and send AUTH_REJECTED{CRED, VERF} if this is the case.
+ */
+ {
+ struct timeval current;
+ int nick;
+ int winverf;
+
+ if (cred->adc_namekind == ADN_FULLNAME) {
+ window = IXDR_GET_U_LONG(ixdr);
+ winverf = IXDR_GET_U_LONG(ixdr);
+ if (winverf != window - 1) {
+ debug("window verifier mismatch");
+ return (AUTH_BADCRED); /* garbled credential */
+ }
+ sid = cache_spot(sessionkey, cred->adc_fullname.name,
+ &timestamp);
+ if (sid < 0) {
+ debug("replayed credential");
+ return (AUTH_REJECTEDCRED); /* replay */
+ }
+ nick = 0;
+ } else { /* ADN_NICKNAME */
+ window = authdes_cache[sid].window;
+ nick = 1;
+ }
+
+ if ((u_long)timestamp.tv_usec >= USEC_PER_SEC) {
+ debug("invalid usecs");
+ /* cached out (bad key), or garbled verifier */
+ return (nick ? AUTH_REJECTEDVERF : AUTH_BADVERF);
+ }
+ if (nick && BEFORE(&timestamp,
+ &authdes_cache[sid].laststamp)) {
+ debug("timestamp before last seen");
+ return (AUTH_REJECTEDVERF); /* replay */
+ }
+ (void) gettimeofday(&current, (struct timezone *)NULL);
+ current.tv_sec -= window; /* allow for expiration */
+ if (!BEFORE(&current, &timestamp)) {
+ debug("timestamp expired");
+ /* replay, or garbled credential */
+ return (nick ? AUTH_REJECTEDVERF : AUTH_BADCRED);
+ }
+ }
+
+ /*
+ * Set up the reply verifier
+ */
+ verf.adv_nickname = (u_long)sid;
+
+ /*
+ * xdr the timestamp before encrypting
+ */
+ ixdr = (long *)cryptbuf;
+ IXDR_PUT_LONG(ixdr, timestamp.tv_sec - 1);
+ IXDR_PUT_LONG(ixdr, timestamp.tv_usec);
+
+ /*
+ * encrypt the timestamp
+ */
+ status = ecb_crypt((char *)sessionkey, (char *)cryptbuf,
+ sizeof(des_block), DES_ENCRYPT | DES_HW);
+ if (DES_FAILED(status)) {
+ debug("encryption failure");
+ return (AUTH_FAILED); /* system error */
+ }
+ verf.adv_xtimestamp = cryptbuf[0];
+
+ /*
+ * Serialize the reply verifier, and update rqst
+ */
+ ixdr = (long *)msg->rm_call.cb_verf.oa_base;
+ *ixdr++ = (long)verf.adv_xtimestamp.key.high;
+ *ixdr++ = (long)verf.adv_xtimestamp.key.low;
+ *ixdr++ = (long)verf.adv_int_u;
+
+ rqst->rq_xprt->xp_verf.oa_flavor = AUTH_DES;
+ rqst->rq_xprt->xp_verf.oa_base = msg->rm_call.cb_verf.oa_base;
+ rqst->rq_xprt->xp_verf.oa_length =
+ (char *)ixdr - msg->rm_call.cb_verf.oa_base;
+
+ /*
+ * We succeeded, commit the data to the cache now and
+ * finish cooking the credential.
+ */
+ entry = &authdes_cache[sid];
+ entry->laststamp = timestamp;
+ cache_ref(sid);
+ if (cred->adc_namekind == ADN_FULLNAME) {
+ cred->adc_fullname.window = window;
+ cred->adc_nickname = (u_long)sid; /* save nickname */
+ if (entry->rname != NULL) {
+ mem_free(entry->rname, strlen(entry->rname) + 1);
+ }
+ entry->rname = (char *)mem_alloc((u_int)strlen(cred->adc_fullname.name)
+ + 1);
+ if (entry->rname != NULL) {
+ (void) strcpy(entry->rname, cred->adc_fullname.name);
+ } else {
+ debug("out of memory");
+ }
+ entry->key = *sessionkey;
+ entry->window = window;
+ invalidate(entry->localcred); /* mark any cached cred invalid */
+ } else { /* ADN_NICKNAME */
+ /*
+ * nicknames are cooked into fullnames
+ */
+ cred->adc_namekind = ADN_FULLNAME;
+ cred->adc_fullname.name = entry->rname;
+ cred->adc_fullname.key = entry->key;
+ cred->adc_fullname.window = entry->window;
+ }
+ return (AUTH_OK); /* we made it!*/
+}
+
+
+/*
+ * Initialize the cache
+ */
+static void
+cache_init()
+{
+ register int i;
+
+ authdes_cache = (struct cache_entry *)
+ mem_alloc(sizeof(struct cache_entry) * AUTHDES_CACHESZ);
+ bzero((char *)authdes_cache,
+ sizeof(struct cache_entry) * AUTHDES_CACHESZ);
+
+ authdes_lru = (short *)mem_alloc(sizeof(short) * AUTHDES_CACHESZ);
+ /*
+ * Initialize the lru list
+ */
+ for (i = 0; i < AUTHDES_CACHESZ; i++) {
+ authdes_lru[i] = i;
+ }
+}
+
+
+/*
+ * Find the lru victim
+ */
+static short
+cache_victim()
+{
+ return (authdes_lru[AUTHDES_CACHESZ-1]);
+}
+
+/*
+ * Note that sid was referenced
+ */
+static void
+cache_ref(sid)
+ register short sid;
+{
+ register int i;
+ register short curr;
+ register short prev;
+
+ prev = authdes_lru[0];
+ authdes_lru[0] = sid;
+ for (i = 1; prev != sid; i++) {
+ curr = authdes_lru[i];
+ authdes_lru[i] = prev;
+ prev = curr;
+ }
+}
+
+
+/*
+ * Find a spot in the cache for a credential containing
+ * the items given. Return -1 if a replay is detected, otherwise
+ * return the spot in the cache.
+ */
+static short
+cache_spot(key, name, timestamp)
+ register des_block *key;
+ char *name;
+ struct timeval *timestamp;
+{
+ register struct cache_entry *cp;
+ register int i;
+ register u_long hi;
+
+ hi = key->key.high;
+ for (cp = authdes_cache, i = 0; i < AUTHDES_CACHESZ; i++, cp++) {
+ if (cp->key.key.high == hi &&
+ cp->key.key.low == key->key.low &&
+ cp->rname != NULL &&
+ bcmp(cp->rname, name, strlen(name) + 1) == 0) {
+ if (BEFORE(timestamp, &cp->laststamp)) {
+ svcauthdes_stats.ncachereplays++;
+ return (-1); /* replay */
+ }
+ svcauthdes_stats.ncachehits++;
+ return (i); /* refresh */
+ }
+ }
+ svcauthdes_stats.ncachemisses++;
+ return (cache_victim()); /* new credential */
+}
+
+
+#if (defined(sun) || defined(vax) || defined(__FreeBSD__))
+/*
+ * Local credential handling stuff.
+ * NOTE: bsd unix dependent.
+ * Other operating systems should put something else here.
+ */
+#define UNKNOWN -2 /* grouplen, if cached cred is unknown user */
+#define INVALID -1 /* grouplen, if cache entry is invalid */
+
+struct bsdcred {
+ short uid; /* cached uid */
+ short gid; /* cached gid */
+ short grouplen; /* length of cached groups */
+ short groups[NGROUPS]; /* cached groups */
+};
+
+/*
+ * Map a des credential into a unix cred.
+ * We cache the credential here so the application does
+ * not have to make an rpc call every time to interpret
+ * the credential.
+ */
+int
+authdes_getucred(adc, uid, gid, grouplen, groups)
+ struct authdes_cred *adc;
+ uid_t *uid;
+ gid_t *gid;
+ int *grouplen;
+ register gid_t *groups;
+{
+ unsigned sid;
+ register int i;
+ uid_t i_uid;
+ gid_t i_gid;
+ int i_grouplen;
+ struct bsdcred *cred;
+
+ sid = adc->adc_nickname;
+ if (sid >= AUTHDES_CACHESZ) {
+ debug("invalid nickname");
+ return (0);
+ }
+ cred = (struct bsdcred *)authdes_cache[sid].localcred;
+ if (cred == NULL) {
+ cred = (struct bsdcred *)mem_alloc(sizeof(struct bsdcred));
+ authdes_cache[sid].localcred = (char *)cred;
+ cred->grouplen = INVALID;
+ }
+ if (cred->grouplen == INVALID) {
+ /*
+ * not in cache: lookup
+ */
+ if (!netname2user(adc->adc_fullname.name, &i_uid, &i_gid,
+ &i_grouplen, groups))
+ {
+ debug("unknown netname");
+ cred->grouplen = UNKNOWN; /* mark as lookup up, but not found */
+ return (0);
+ }
+ debug("missed ucred cache");
+ *uid = cred->uid = i_uid;
+ *gid = cred->gid = i_gid;
+ *grouplen = cred->grouplen = i_grouplen;
+ for (i = i_grouplen - 1; i >= 0; i--) {
+ cred->groups[i] = groups[i]; /* int to short */
+ }
+ return (1);
+ } else if (cred->grouplen == UNKNOWN) {
+ /*
+ * Already lookup up, but no match found
+ */
+ return (0);
+ }
+
+ /*
+ * cached credentials
+ */
+ *uid = cred->uid;
+ *gid = cred->gid;
+ *grouplen = cred->grouplen;
+ for (i = cred->grouplen - 1; i >= 0; i--) {
+ groups[i] = cred->groups[i]; /* short to int */
+ }
+ return (1);
+}
+
+static void
+invalidate(cred)
+ char *cred;
+{
+ if (cred == NULL) {
+ return;
+ }
+ ((struct bsdcred *)cred)->grouplen = INVALID;
+}
+#endif
+
diff --git a/lib/libc/rpc/svc_auth_unix.c b/lib/libc/rpc/svc_auth_unix.c
new file mode 100644
index 0000000..4e800e5
--- /dev/null
+++ b/lib/libc/rpc/svc_auth_unix.c
@@ -0,0 +1,148 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * svc_auth_unix.c
+ * Handles UNIX flavor authentication parameters on the service side of rpc.
+ * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT.
+ * _svcauth_unix does full blown unix style uid,gid+gids auth,
+ * _svcauth_short uses a shorthand auth to index into a cache of longhand auths.
+ * Note: the shorthand has been gutted for efficiency.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <rpc/rpc.h>
+
+/*
+ * Unix longhand authenticator
+ */
+enum auth_stat
+_svcauth_unix(rqst, msg)
+ register struct svc_req *rqst;
+ register struct rpc_msg *msg;
+{
+ register enum auth_stat stat;
+ XDR xdrs;
+ register struct authunix_parms *aup;
+ register int32_t *buf;
+ struct area {
+ struct authunix_parms area_aup;
+ char area_machname[MAX_MACHINE_NAME+1];
+ int area_gids[NGRPS];
+ } *area;
+ u_int auth_len;
+ int str_len, gid_len;
+ register int i;
+
+ area = (struct area *) rqst->rq_clntcred;
+ aup = &area->area_aup;
+ aup->aup_machname = area->area_machname;
+ aup->aup_gids = area->area_gids;
+ auth_len = (u_int)msg->rm_call.cb_cred.oa_length;
+ xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE);
+ buf = XDR_INLINE(&xdrs, auth_len);
+ if (buf != NULL) {
+ aup->aup_time = IXDR_GET_LONG(buf);
+ str_len = IXDR_GET_U_LONG(buf);
+ if (str_len > MAX_MACHINE_NAME) {
+ stat = AUTH_BADCRED;
+ goto done;
+ }
+ memcpy(aup->aup_machname, (caddr_t)buf, (u_int)str_len);
+ aup->aup_machname[str_len] = 0;
+ str_len = RNDUP(str_len);
+ buf += str_len / sizeof (int32_t);
+ aup->aup_uid = IXDR_GET_LONG(buf);
+ aup->aup_gid = IXDR_GET_LONG(buf);
+ gid_len = IXDR_GET_U_LONG(buf);
+ if (gid_len > NGRPS) {
+ stat = AUTH_BADCRED;
+ goto done;
+ }
+ aup->aup_len = gid_len;
+ for (i = 0; i < gid_len; i++) {
+ aup->aup_gids[i] = IXDR_GET_LONG(buf);
+ }
+ /*
+ * five is the smallest unix credentials structure -
+ * timestamp, hostname len (0), uid, gid, and gids len (0).
+ */
+ if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
+ (void) printf("bad auth_len gid %d str %d auth %d\n",
+ gid_len, str_len, auth_len);
+ stat = AUTH_BADCRED;
+ goto done;
+ }
+ } else if (! xdr_authunix_parms(&xdrs, aup)) {
+ xdrs.x_op = XDR_FREE;
+ (void)xdr_authunix_parms(&xdrs, aup);
+ stat = AUTH_BADCRED;
+ goto done;
+ }
+
+ /* get the verifier */
+ if ((u_int)msg->rm_call.cb_verf.oa_length) {
+ rqst->rq_xprt->xp_verf.oa_flavor =
+ msg->rm_call.cb_verf.oa_flavor;
+ rqst->rq_xprt->xp_verf.oa_base =
+ msg->rm_call.cb_verf.oa_base;
+ rqst->rq_xprt->xp_verf.oa_length =
+ msg->rm_call.cb_verf.oa_length;
+ } else {
+ rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
+ rqst->rq_xprt->xp_verf.oa_length = 0;
+ }
+ stat = AUTH_OK;
+done:
+ XDR_DESTROY(&xdrs);
+ return (stat);
+}
+
+
+/*
+ * Shorthand unix authenticator
+ * Looks up longhand in a cache.
+ */
+/*ARGSUSED*/
+enum auth_stat
+_svcauth_short(rqst, msg)
+ struct svc_req *rqst;
+ struct rpc_msg *msg;
+{
+ return (AUTH_REJECTEDCRED);
+}
diff --git a/lib/libc/rpc/svc_raw.c b/lib/libc/rpc/svc_raw.c
new file mode 100644
index 0000000..4726152
--- /dev/null
+++ b/lib/libc/rpc/svc_raw.c
@@ -0,0 +1,168 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_raw.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * svc_raw.c, This a toy for simple testing and timing.
+ * Interface to create an rpc client and server in the same UNIX process.
+ * This lets us similate rpc and get rpc (round trip) overhead, without
+ * any interference from the kernal.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <stdlib.h>
+
+/*
+ * This is the "network" that we will be moving data over
+ */
+static struct svcraw_private {
+ char _raw_buf[UDPMSGSIZE];
+ SVCXPRT server;
+ XDR xdr_stream;
+ char verf_body[MAX_AUTH_BYTES];
+} *svcraw_private;
+
+static bool_t svcraw_recv();
+static enum xprt_stat svcraw_stat();
+static bool_t svcraw_getargs();
+static bool_t svcraw_reply();
+static bool_t svcraw_freeargs();
+static void svcraw_destroy();
+
+static struct xp_ops server_ops = {
+ svcraw_recv,
+ svcraw_stat,
+ svcraw_getargs,
+ svcraw_reply,
+ svcraw_freeargs,
+ svcraw_destroy
+};
+
+SVCXPRT *
+svcraw_create()
+{
+ register struct svcraw_private *srp = svcraw_private;
+
+ if (srp == 0) {
+ srp = (struct svcraw_private *)calloc(1, sizeof (*srp));
+ if (srp == 0)
+ return (0);
+ }
+ srp->server.xp_sock = 0;
+ srp->server.xp_port = 0;
+ srp->server.xp_ops = &server_ops;
+ srp->server.xp_verf.oa_base = srp->verf_body;
+ xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE);
+ return (&srp->server);
+}
+
+static enum xprt_stat
+svcraw_stat()
+{
+
+ return (XPRT_IDLE);
+}
+
+static bool_t
+svcraw_recv(xprt, msg)
+ SVCXPRT *xprt;
+ struct rpc_msg *msg;
+{
+ register struct svcraw_private *srp = svcraw_private;
+ register XDR *xdrs;
+
+ if (srp == 0)
+ return (0);
+ xdrs = &srp->xdr_stream;
+ xdrs->x_op = XDR_DECODE;
+ XDR_SETPOS(xdrs, 0);
+ if (! xdr_callmsg(xdrs, msg))
+ return (FALSE);
+ return (TRUE);
+}
+
+static bool_t
+svcraw_reply(xprt, msg)
+ SVCXPRT *xprt;
+ struct rpc_msg *msg;
+{
+ register struct svcraw_private *srp = svcraw_private;
+ register XDR *xdrs;
+
+ if (srp == 0)
+ return (FALSE);
+ xdrs = &srp->xdr_stream;
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, 0);
+ if (! xdr_replymsg(xdrs, msg))
+ return (FALSE);
+ (void)XDR_GETPOS(xdrs); /* called just for overhead */
+ return (TRUE);
+}
+
+static bool_t
+svcraw_getargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+ register struct svcraw_private *srp = svcraw_private;
+
+ if (srp == 0)
+ return (FALSE);
+ return ((*xdr_args)(&srp->xdr_stream, args_ptr));
+}
+
+static bool_t
+svcraw_freeargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+ register struct svcraw_private *srp = svcraw_private;
+ register XDR *xdrs;
+
+ if (srp == 0)
+ return (FALSE);
+ xdrs = &srp->xdr_stream;
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static void
+svcraw_destroy()
+{
+}
diff --git a/lib/libc/rpc/svc_run.c b/lib/libc/rpc/svc_run.c
new file mode 100644
index 0000000..f39886a
--- /dev/null
+++ b/lib/libc/rpc/svc_run.c
@@ -0,0 +1,87 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * This is the rpc server side idle loop
+ * Wait for input, call server program.
+ */
+#include <rpc/rpc.h>
+#include <stdio.h>
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern int __svc_fdsetsize;
+extern fd_set *__svc_fdset;
+
+void
+svc_run()
+{
+ fd_set *fds;
+
+ for (;;) {
+ if (__svc_fdset) {
+ int bytes = howmany(__svc_fdsetsize, NFDBITS) *
+ sizeof(fd_mask);
+ fds = (fd_set *)malloc(bytes);
+ memcpy(fds, __svc_fdset, bytes);
+ } else
+ fds = NULL;
+ switch (select(svc_maxfd + 1, fds, NULL, NULL,
+ (struct timeval *)0)) {
+ case -1:
+ if (errno == EINTR) {
+ if (fds)
+ free(fds);
+ continue;
+ }
+ perror("svc_run: - select failed");
+ if (fds)
+ free(fds);
+ return;
+ case 0:
+ if (fds)
+ free(fds);
+ continue;
+ default:
+ /* if fds == NULL, select() can't return a result */
+ svc_getreqset2(fds, svc_maxfd + 1);
+ free(fds);
+ }
+ }
+}
diff --git a/lib/libc/rpc/svc_simple.c b/lib/libc/rpc/svc_simple.c
new file mode 100644
index 0000000..1bfaf1c
--- /dev/null
+++ b/lib/libc/rpc/svc_simple.c
@@ -0,0 +1,150 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_simple.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * svc_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+static struct proglst {
+ char *(*p_progname)();
+ int p_prognum;
+ int p_procnum;
+ xdrproc_t p_inproc, p_outproc;
+ struct proglst *p_nxt;
+} *proglst;
+static void universal();
+static SVCXPRT *transp;
+struct proglst *pl;
+
+int
+registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
+ int prognum, versnum, procnum;
+ char *(*progname)();
+ xdrproc_t inproc, outproc;
+{
+
+ if (procnum == NULLPROC) {
+ (void) fprintf(stderr,
+ "can't reassign procedure number %ld\n", NULLPROC);
+ return (-1);
+ }
+ if (transp == 0) {
+ transp = svcudp_create(RPC_ANYSOCK);
+ if (transp == NULL) {
+ (void) fprintf(stderr, "couldn't create an rpc server\n");
+ return (-1);
+ }
+ }
+ (void) pmap_unset((u_long)prognum, (u_long)versnum);
+ if (!svc_register(transp, (u_long)prognum, (u_long)versnum,
+ universal, IPPROTO_UDP)) {
+ (void) fprintf(stderr, "couldn't register prog %d vers %d\n",
+ prognum, versnum);
+ return (-1);
+ }
+ pl = (struct proglst *)malloc(sizeof(struct proglst));
+ if (pl == NULL) {
+ (void) fprintf(stderr, "registerrpc: out of memory\n");
+ return (-1);
+ }
+ pl->p_progname = progname;
+ pl->p_prognum = prognum;
+ pl->p_procnum = procnum;
+ pl->p_inproc = inproc;
+ pl->p_outproc = outproc;
+ pl->p_nxt = proglst;
+ proglst = pl;
+ return (0);
+}
+
+static void
+universal(rqstp, transp)
+ struct svc_req *rqstp;
+ SVCXPRT *transp;
+{
+ int prog, proc;
+ char *outdata;
+ char xdrbuf[UDPMSGSIZE];
+ struct proglst *pl;
+
+ /*
+ * enforce "procnum 0 is echo" convention
+ */
+ if (rqstp->rq_proc == NULLPROC) {
+ if (svc_sendreply(transp, xdr_void, NULL) == FALSE) {
+ (void) fprintf(stderr, "xxx\n");
+ exit(1);
+ }
+ return;
+ }
+ prog = rqstp->rq_prog;
+ proc = rqstp->rq_proc;
+ for (pl = proglst; pl != NULL; pl = pl->p_nxt)
+ if (pl->p_prognum == prog && pl->p_procnum == proc) {
+ /* decode arguments into a CLEAN buffer */
+ memset(xdrbuf, 0, sizeof(xdrbuf)); /* required ! */
+ if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) {
+ svcerr_decode(transp);
+ return;
+ }
+ outdata = (*(pl->p_progname))(xdrbuf);
+ if (outdata == NULL && pl->p_outproc != xdr_void)
+ /* there was an error */
+ return;
+ if (!svc_sendreply(transp, pl->p_outproc, outdata)) {
+ (void) fprintf(stderr,
+ "trouble replying to prog %d\n",
+ pl->p_prognum);
+ exit(1);
+ }
+ /* free the decoded arguments */
+ (void)svc_freeargs(transp, pl->p_inproc, xdrbuf);
+ return;
+ }
+ (void) fprintf(stderr, "never registered prog %d\n", prog);
+ exit(1);
+}
+
diff --git a/lib/libc/rpc/svc_tcp.c b/lib/libc/rpc/svc_tcp.c
new file mode 100644
index 0000000..90e37a0
--- /dev/null
+++ b/lib/libc/rpc/svc_tcp.c
@@ -0,0 +1,484 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * svc_tcp.c, Server side for TCP/IP based RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Actually implements two flavors of transporter -
+ * a tcp rendezvouser (a listner and connection establisher)
+ * and a record/tcp stream.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+/*
+ * Ops vector for TCP/IP based rpc service handle
+ */
+static bool_t svctcp_recv();
+static enum xprt_stat svctcp_stat();
+static bool_t svctcp_getargs();
+static bool_t svctcp_reply();
+static bool_t svctcp_freeargs();
+static void svctcp_destroy();
+
+static struct xp_ops svctcp_op = {
+ svctcp_recv,
+ svctcp_stat,
+ svctcp_getargs,
+ svctcp_reply,
+ svctcp_freeargs,
+ svctcp_destroy
+};
+
+/*
+ * Ops vector for TCP/IP rendezvous handler
+ */
+static bool_t rendezvous_request();
+static enum xprt_stat rendezvous_stat();
+
+static struct xp_ops svctcp_rendezvous_op = {
+ rendezvous_request,
+ rendezvous_stat,
+ (bool_t (*)())abort,
+ (bool_t (*)())abort,
+ (bool_t (*)())abort,
+ svctcp_destroy
+};
+
+static int readtcp(), writetcp();
+static SVCXPRT *makefd_xprt();
+
+struct tcp_rendezvous { /* kept in xprt->xp_p1 */
+ u_int sendsize;
+ u_int recvsize;
+};
+
+struct tcp_conn { /* kept in xprt->xp_p1 */
+ enum xprt_stat strm_stat;
+ u_long x_id;
+ XDR xdrs;
+ char verf_body[MAX_AUTH_BYTES];
+};
+
+/*
+ * Usage:
+ * xprt = svctcp_create(sock, send_buf_size, recv_buf_size);
+ *
+ * Creates, registers, and returns a (rpc) tcp based transporter.
+ * Once *xprt is initialized, it is registered as a transporter
+ * see (svc.h, xprt_register). This routine returns
+ * a NULL if a problem occurred.
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svctcp_create
+ * binds it to an arbitrary port. The routine then starts a tcp
+ * listener on the socket's associated port. In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ *
+ * Since tcp streams do buffered io similar to stdio, the caller can specify
+ * how big the send and receive buffers are via the second and third parms;
+ * 0 => use the system default.
+ */
+SVCXPRT *
+svctcp_create(sock, sendsize, recvsize)
+ register int sock;
+ u_int sendsize;
+ u_int recvsize;
+{
+ bool_t madesock = FALSE;
+ register SVCXPRT *xprt;
+ register struct tcp_rendezvous *r;
+ struct sockaddr_in addr;
+ int len = sizeof(struct sockaddr_in);
+ int on;
+
+ if (sock == RPC_ANYSOCK) {
+ if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ perror("svctcp_.c - udp socket creation problem");
+ return ((SVCXPRT *)NULL);
+ }
+ madesock = TRUE;
+ }
+ on = 1;
+ if (ioctl(sock, FIONBIO, &on) < 0) {
+ perror("svc_tcp.c - cannot turn on non-blocking mode");
+ if (madesock)
+ (void)close(sock);
+ return ((SVCXPRT *)NULL);
+ }
+ memset(&addr, 0, sizeof (addr));
+ addr.sin_len = sizeof(struct sockaddr_in);
+ addr.sin_family = AF_INET;
+ if (bindresvport(sock, &addr)) {
+ addr.sin_port = 0;
+ (void)bind(sock, (struct sockaddr *)&addr, len);
+ }
+ if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0) ||
+ (listen(sock, 2) != 0)) {
+ perror("svctcp_.c - cannot getsockname or listen");
+ if (madesock)
+ (void)close(sock);
+ return ((SVCXPRT *)NULL);
+ }
+ r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r));
+ if (r == NULL) {
+ (void) fprintf(stderr, "svctcp_create: out of memory\n");
+ return (NULL);
+ }
+ r->sendsize = sendsize;
+ r->recvsize = recvsize;
+ xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+ if (xprt == NULL) {
+ (void) fprintf(stderr, "svctcp_create: out of memory\n");
+ return (NULL);
+ }
+ xprt->xp_p2 = NULL;
+ xprt->xp_p1 = (caddr_t)r;
+ xprt->xp_verf = _null_auth;
+ xprt->xp_ops = &svctcp_rendezvous_op;
+ xprt->xp_port = ntohs(addr.sin_port);
+ xprt->xp_sock = sock;
+ xprt_register(xprt);
+ return (xprt);
+}
+
+/*
+ * Like svtcp_create(), except the routine takes any *open* UNIX file
+ * descriptor as its first input.
+ */
+SVCXPRT *
+svcfd_create(fd, sendsize, recvsize)
+ int fd;
+ u_int sendsize;
+ u_int recvsize;
+{
+
+ return (makefd_xprt(fd, sendsize, recvsize));
+}
+
+static SVCXPRT *
+makefd_xprt(fd, sendsize, recvsize)
+ int fd;
+ u_int sendsize;
+ u_int recvsize;
+{
+ register SVCXPRT *xprt;
+ register struct tcp_conn *cd;
+
+ xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+ if (xprt == (SVCXPRT *)NULL) {
+ (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+ goto done;
+ }
+ cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn));
+ if (cd == (struct tcp_conn *)NULL) {
+ (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+ mem_free((char *) xprt, sizeof(SVCXPRT));
+ xprt = (SVCXPRT *)NULL;
+ goto done;
+ }
+ cd->strm_stat = XPRT_IDLE;
+ xdrrec_create(&(cd->xdrs), sendsize, recvsize,
+ (caddr_t)xprt, readtcp, writetcp);
+ xprt->xp_p2 = NULL;
+ xprt->xp_p1 = (caddr_t)cd;
+ xprt->xp_verf.oa_base = cd->verf_body;
+ xprt->xp_addrlen = 0;
+ xprt->xp_ops = &svctcp_op; /* truely deals with calls */
+ xprt->xp_port = 0; /* this is a connection, not a rendezvouser */
+ xprt->xp_sock = fd;
+ xprt_register(xprt);
+ done:
+ return (xprt);
+}
+
+static bool_t
+rendezvous_request(xprt)
+ register SVCXPRT *xprt;
+{
+ int sock;
+ struct tcp_rendezvous *r;
+ struct sockaddr_in addr;
+ int len;
+ int off;
+
+ r = (struct tcp_rendezvous *)xprt->xp_p1;
+ again:
+ len = sizeof(struct sockaddr_in);
+ if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr,
+ &len)) < 0) {
+ if (errno == EINTR)
+ goto again;
+ return (FALSE);
+ }
+ /*
+ * Guard against FTP bounce attacks.
+ */
+ if (addr.sin_port == htons(20)) {
+ close(sock);
+ return (FALSE);
+ }
+ /*
+ * The listening socket is in FIONBIO mode and we inherit it.
+ */
+ off = 0;
+ if (ioctl(sock, FIONBIO, &off) < 0) {
+ close(sock);
+ return (FALSE);
+ }
+ /*
+ * make a new transporter (re-uses xprt)
+ */
+ xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
+ xprt->xp_raddr = addr;
+ xprt->xp_addrlen = len;
+ return (FALSE); /* there is never an rpc msg to be processed */
+}
+
+static enum xprt_stat
+rendezvous_stat()
+{
+
+ return (XPRT_IDLE);
+}
+
+static void
+svctcp_destroy(xprt)
+ register SVCXPRT *xprt;
+{
+ register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1;
+
+ xprt_unregister(xprt);
+ (void)close(xprt->xp_sock);
+ if (xprt->xp_port != 0) {
+ /* a rendezvouser socket */
+ xprt->xp_port = 0;
+ } else {
+ /* an actual connection socket */
+ XDR_DESTROY(&(cd->xdrs));
+ }
+ mem_free((caddr_t)cd, sizeof(struct tcp_conn));
+ mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+/*
+ * All read operations timeout after 35 seconds.
+ * A timeout is fatal for the connection.
+ */
+static struct timeval wait_per_try = { 35, 0 };
+
+/*
+ * reads data from the tcp conection.
+ * any error is fatal and the connection is closed.
+ * (And a read of zero bytes is a half closed stream => error.)
+ *
+ * Note: we have to be careful here not to allow ourselves to become
+ * blocked too long in this routine. While we're waiting for data from one
+ * client, another client may be trying to connect. To avoid this situation,
+ * some code from svc_run() is transplanted here: the select() loop checks
+ * all RPC descriptors including the one we want and calls svc_getreqset2()
+ * to handle new requests if any are detected.
+ */
+static int
+readtcp(xprt, buf, len)
+ register SVCXPRT *xprt;
+ caddr_t buf;
+ register int len;
+{
+ register int sock = xprt->xp_sock;
+ struct timeval start, delta, tv;
+ struct timeval tmp1, tmp2;
+ fd_set *fds;
+ extern fd_set *__svc_fdset;
+ extern int __svc_fdsetsize;
+
+ delta = wait_per_try;
+ fds = NULL;
+ gettimeofday(&start, NULL);
+ do {
+ int bytes = howmany(__svc_fdsetsize, NFDBITS) *
+ sizeof(fd_mask);
+ if (fds != NULL)
+ free(fds);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL)
+ goto fatal_err;
+ memcpy(fds, __svc_fdset, bytes);
+
+ /* XXX we know the other bits are still clear */
+ FD_SET(sock, fds);
+ tv = delta; /* in case select() implements writeback */
+ switch (select(svc_maxfd + 1, fds, NULL, NULL, &tv)) {
+ case -1:
+ if (errno != EINTR)
+ goto fatal_err;
+ gettimeofday(&tmp1, NULL);
+ timersub(&tmp1, &start, &tmp2);
+ timersub(&wait_per_try, &tmp2, &tmp1);
+ if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
+ goto fatal_err;
+ delta = tmp1;
+ continue;
+ case 0:
+ goto fatal_err;
+ default:
+ if (!FD_ISSET(sock, fds)) {
+ svc_getreqset2(fds, svc_maxfd + 1);
+ gettimeofday(&tmp1, NULL);
+ timersub(&tmp1, &start, &tmp2);
+ timersub(&wait_per_try, &tmp2, &tmp1);
+ if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
+ goto fatal_err;
+ delta = tmp1;
+ continue;
+ }
+ }
+ } while (!FD_ISSET(sock, fds));
+ if ((len = read(sock, buf, len)) > 0) {
+ if (fds != NULL)
+ free(fds);
+ return (len);
+ }
+fatal_err:
+ ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
+ if (fds != NULL)
+ free(fds);
+ return (-1);
+}
+
+/*
+ * writes data to the tcp connection.
+ * Any error is fatal and the connection is closed.
+ */
+static int
+writetcp(xprt, buf, len)
+ register SVCXPRT *xprt;
+ caddr_t buf;
+ int len;
+{
+ register int i, cnt;
+
+ for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+ if ((i = write(xprt->xp_sock, buf, cnt)) < 0) {
+ ((struct tcp_conn *)(xprt->xp_p1))->strm_stat =
+ XPRT_DIED;
+ return (-1);
+ }
+ }
+ return (len);
+}
+
+static enum xprt_stat
+svctcp_stat(xprt)
+ SVCXPRT *xprt;
+{
+ register struct tcp_conn *cd =
+ (struct tcp_conn *)(xprt->xp_p1);
+
+ if (cd->strm_stat == XPRT_DIED)
+ return (XPRT_DIED);
+ if (! xdrrec_eof(&(cd->xdrs)))
+ return (XPRT_MOREREQS);
+ return (XPRT_IDLE);
+}
+
+static bool_t
+svctcp_recv(xprt, msg)
+ SVCXPRT *xprt;
+ register struct rpc_msg *msg;
+{
+ register struct tcp_conn *cd =
+ (struct tcp_conn *)(xprt->xp_p1);
+ register XDR *xdrs = &(cd->xdrs);
+
+ xdrs->x_op = XDR_DECODE;
+ (void)xdrrec_skiprecord(xdrs);
+ if (xdr_callmsg(xdrs, msg)) {
+ cd->x_id = msg->rm_xid;
+ return (TRUE);
+ }
+ cd->strm_stat = XPRT_DIED; /* XXXX */
+ return (FALSE);
+}
+
+static bool_t
+svctcp_getargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+
+ return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr));
+}
+
+static bool_t
+svctcp_freeargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+ register XDR *xdrs =
+ &(((struct tcp_conn *)(xprt->xp_p1))->xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static bool_t
+svctcp_reply(xprt, msg)
+ SVCXPRT *xprt;
+ register struct rpc_msg *msg;
+{
+ register struct tcp_conn *cd =
+ (struct tcp_conn *)(xprt->xp_p1);
+ register XDR *xdrs = &(cd->xdrs);
+ register bool_t stat;
+
+ xdrs->x_op = XDR_ENCODE;
+ msg->rm_xid = cd->x_id;
+ stat = xdr_replymsg(xdrs, msg);
+ (void)xdrrec_endofrecord(xdrs, TRUE);
+ return (stat);
+}
diff --git a/lib/libc/rpc/svc_udp.c b/lib/libc/rpc/svc_udp.c
new file mode 100644
index 0000000..4b76f2d
--- /dev/null
+++ b/lib/libc/rpc/svc_udp.c
@@ -0,0 +1,480 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * svc_udp.c,
+ * Server side for UDP/IP based RPC. (Does some caching in the hopes of
+ * achieving execute-at-most-once semantics.)
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+#define rpc_buffer(xprt) ((xprt)->xp_p1)
+#define MAX(a, b) ((a > b) ? a : b)
+
+static bool_t svcudp_recv();
+static bool_t svcudp_reply();
+static enum xprt_stat svcudp_stat();
+static bool_t svcudp_getargs();
+static bool_t svcudp_freeargs();
+static void svcudp_destroy();
+static void cache_set __P((SVCXPRT *, u_long));
+static int cache_get __P((SVCXPRT *, struct rpc_msg *, char **, u_long *));
+
+static struct xp_ops svcudp_op = {
+ svcudp_recv,
+ svcudp_stat,
+ svcudp_getargs,
+ svcudp_reply,
+ svcudp_freeargs,
+ svcudp_destroy
+};
+
+/*
+ * kept in xprt->xp_p2
+ */
+struct svcudp_data {
+ u_int su_iosz; /* byte size of send.recv buffer */
+ u_long su_xid; /* transaction id */
+ XDR su_xdrs; /* XDR handle */
+ char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */
+ char * su_cache; /* cached data, NULL if no cache */
+};
+#define su_data(xprt) ((struct svcudp_data *)(xprt->xp_p2))
+
+/*
+ * Usage:
+ * xprt = svcudp_create(sock);
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svcudp_create
+ * binds it to an arbitrary port. In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ * Once *xprt is initialized, it is registered as a transporter;
+ * see (svc.h, xprt_register).
+ * The routines returns NULL if a problem occurred.
+ */
+SVCXPRT *
+svcudp_bufcreate(sock, sendsz, recvsz)
+ register int sock;
+ u_int sendsz, recvsz;
+{
+ bool_t madesock = FALSE;
+ register SVCXPRT *xprt;
+ register struct svcudp_data *su;
+ struct sockaddr_in addr;
+ int len = sizeof(struct sockaddr_in);
+
+ if (sock == RPC_ANYSOCK) {
+ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ perror("svcudp_create: socket creation problem");
+ return ((SVCXPRT *)NULL);
+ }
+ madesock = TRUE;
+ }
+ memset((char *)&addr, 0, sizeof (addr));
+ addr.sin_len = sizeof(struct sockaddr_in);
+ addr.sin_family = AF_INET;
+ if (bindresvport(sock, &addr)) {
+ addr.sin_port = 0;
+ (void)bind(sock, (struct sockaddr *)&addr, len);
+ }
+ if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) {
+ perror("svcudp_create - cannot getsockname");
+ if (madesock)
+ (void)close(sock);
+ return ((SVCXPRT *)NULL);
+ }
+ xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+ if (xprt == NULL) {
+ (void)fprintf(stderr, "svcudp_create: out of memory\n");
+ return (NULL);
+ }
+ su = (struct svcudp_data *)mem_alloc(sizeof(*su));
+ if (su == NULL) {
+ (void)fprintf(stderr, "svcudp_create: out of memory\n");
+ return (NULL);
+ }
+ su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
+ if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) {
+ (void)fprintf(stderr, "svcudp_create: out of memory\n");
+ return (NULL);
+ }
+ xdrmem_create(
+ &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE);
+ su->su_cache = NULL;
+ xprt->xp_p2 = (caddr_t)su;
+ xprt->xp_verf.oa_base = su->su_verfbody;
+ xprt->xp_ops = &svcudp_op;
+ xprt->xp_port = ntohs(addr.sin_port);
+ xprt->xp_sock = sock;
+ xprt_register(xprt);
+ return (xprt);
+}
+
+SVCXPRT *
+svcudp_create(sock)
+ int sock;
+{
+
+ return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum xprt_stat
+svcudp_stat(xprt)
+ SVCXPRT *xprt;
+{
+
+ return (XPRT_IDLE);
+}
+
+static bool_t
+svcudp_recv(xprt, msg)
+ register SVCXPRT *xprt;
+ struct rpc_msg *msg;
+{
+ register struct svcudp_data *su = su_data(xprt);
+ register XDR *xdrs = &(su->su_xdrs);
+ register int rlen;
+ char *reply;
+ u_long replylen;
+
+ again:
+ xprt->xp_addrlen = sizeof(struct sockaddr_in);
+ rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz,
+ 0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen));
+ if (rlen == -1 && errno == EINTR)
+ goto again;
+ if (rlen == -1 || rlen < 4*sizeof(u_int32_t))
+ return (FALSE);
+ xdrs->x_op = XDR_DECODE;
+ XDR_SETPOS(xdrs, 0);
+ if (! xdr_callmsg(xdrs, msg))
+ return (FALSE);
+ su->su_xid = msg->rm_xid;
+ if (su->su_cache != NULL) {
+ if (cache_get(xprt, msg, &reply, &replylen)) {
+ (void) sendto(xprt->xp_sock, reply, (int) replylen, 0,
+ (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen);
+ return (TRUE);
+ }
+ }
+ return (TRUE);
+}
+
+static bool_t
+svcudp_reply(xprt, msg)
+ register SVCXPRT *xprt;
+ struct rpc_msg *msg;
+{
+ register struct svcudp_data *su = su_data(xprt);
+ register XDR *xdrs = &(su->su_xdrs);
+ register int slen;
+ register bool_t stat = FALSE;
+
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, 0);
+ msg->rm_xid = su->su_xid;
+ if (xdr_replymsg(xdrs, msg)) {
+ slen = (int)XDR_GETPOS(xdrs);
+ if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
+ (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
+ == slen) {
+ stat = TRUE;
+ if (su->su_cache && slen >= 0) {
+ cache_set(xprt, (u_long) slen);
+ }
+ }
+ }
+ return (stat);
+}
+
+static bool_t
+svcudp_getargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+
+ return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr));
+}
+
+static bool_t
+svcudp_freeargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+ register XDR *xdrs = &(su_data(xprt)->su_xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static void
+svcudp_destroy(xprt)
+ register SVCXPRT *xprt;
+{
+ register struct svcudp_data *su = su_data(xprt);
+
+ xprt_unregister(xprt);
+ (void)close(xprt->xp_sock);
+ XDR_DESTROY(&(su->su_xdrs));
+ mem_free(rpc_buffer(xprt), su->su_iosz);
+ mem_free((caddr_t)su, sizeof(struct svcudp_data));
+ mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+
+/***********this could be a separate file*********************/
+
+/*
+ * Fifo cache for udp server
+ * Copies pointers to reply buffers into fifo cache
+ * Buffers are sent again if retransmissions are detected.
+ */
+
+#define SPARSENESS 4 /* 75% sparse */
+
+#define CACHE_PERROR(msg) \
+ (void) fprintf(stderr,"%s\n", msg)
+
+#define ALLOC(type, size) \
+ (type *) mem_alloc((unsigned) (sizeof(type) * (size)))
+
+#define BZERO(addr, type, size) \
+ memset((char *) addr, 0, sizeof(type) * (int) (size))
+
+/*
+ * An entry in the cache
+ */
+typedef struct cache_node *cache_ptr;
+struct cache_node {
+ /*
+ * Index into cache is xid, proc, vers, prog and address
+ */
+ u_long cache_xid;
+ u_long cache_proc;
+ u_long cache_vers;
+ u_long cache_prog;
+ struct sockaddr_in cache_addr;
+ /*
+ * The cached reply and length
+ */
+ char * cache_reply;
+ u_long cache_replylen;
+ /*
+ * Next node on the list, if there is a collision
+ */
+ cache_ptr cache_next;
+};
+
+
+
+/*
+ * The entire cache
+ */
+struct udp_cache {
+ u_long uc_size; /* size of cache */
+ cache_ptr *uc_entries; /* hash table of entries in cache */
+ cache_ptr *uc_fifo; /* fifo list of entries in cache */
+ u_long uc_nextvictim; /* points to next victim in fifo list */
+ u_long uc_prog; /* saved program number */
+ u_long uc_vers; /* saved version number */
+ u_long uc_proc; /* saved procedure number */
+ struct sockaddr_in uc_addr; /* saved caller's address */
+};
+
+
+/*
+ * the hashing function
+ */
+#define CACHE_LOC(transp, xid) \
+ (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size))
+
+
+/*
+ * Enable use of the cache.
+ * Note: there is no disable.
+ */
+int svcudp_enablecache(transp, size)
+ SVCXPRT *transp;
+ u_long size;
+{
+ struct svcudp_data *su = su_data(transp);
+ struct udp_cache *uc;
+
+ if (su->su_cache != NULL) {
+ CACHE_PERROR("enablecache: cache already enabled");
+ return(0);
+ }
+ uc = ALLOC(struct udp_cache, 1);
+ if (uc == NULL) {
+ CACHE_PERROR("enablecache: could not allocate cache");
+ return(0);
+ }
+ uc->uc_size = size;
+ uc->uc_nextvictim = 0;
+ uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS);
+ if (uc->uc_entries == NULL) {
+ CACHE_PERROR("enablecache: could not allocate cache data");
+ return(0);
+ }
+ BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS);
+ uc->uc_fifo = ALLOC(cache_ptr, size);
+ if (uc->uc_fifo == NULL) {
+ CACHE_PERROR("enablecache: could not allocate cache fifo");
+ return(0);
+ }
+ BZERO(uc->uc_fifo, cache_ptr, size);
+ su->su_cache = (char *) uc;
+ return(1);
+}
+
+
+/*
+ * Set an entry in the cache
+ */
+static void
+cache_set(xprt, replylen)
+ SVCXPRT *xprt;
+ u_long replylen;
+{
+ register cache_ptr victim;
+ register cache_ptr *vicp;
+ register struct svcudp_data *su = su_data(xprt);
+ struct udp_cache *uc = (struct udp_cache *) su->su_cache;
+ u_int loc;
+ char *newbuf;
+
+ /*
+ * Find space for the new entry, either by
+ * reusing an old entry, or by mallocing a new one
+ */
+ victim = uc->uc_fifo[uc->uc_nextvictim];
+ if (victim != NULL) {
+ loc = CACHE_LOC(xprt, victim->cache_xid);
+ for (vicp = &uc->uc_entries[loc];
+ *vicp != NULL && *vicp != victim;
+ vicp = &(*vicp)->cache_next)
+ ;
+ if (*vicp == NULL) {
+ CACHE_PERROR("cache_set: victim not found");
+ return;
+ }
+ *vicp = victim->cache_next; /* remote from cache */
+ newbuf = victim->cache_reply;
+ } else {
+ victim = ALLOC(struct cache_node, 1);
+ if (victim == NULL) {
+ CACHE_PERROR("cache_set: victim alloc failed");
+ return;
+ }
+ newbuf = mem_alloc(su->su_iosz);
+ if (newbuf == NULL) {
+ CACHE_PERROR("cache_set: could not allocate new rpc_buffer");
+ return;
+ }
+ }
+
+ /*
+ * Store it away
+ */
+ victim->cache_replylen = replylen;
+ victim->cache_reply = rpc_buffer(xprt);
+ rpc_buffer(xprt) = newbuf;
+ xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE);
+ victim->cache_xid = su->su_xid;
+ victim->cache_proc = uc->uc_proc;
+ victim->cache_vers = uc->uc_vers;
+ victim->cache_prog = uc->uc_prog;
+ victim->cache_addr = uc->uc_addr;
+ loc = CACHE_LOC(xprt, victim->cache_xid);
+ victim->cache_next = uc->uc_entries[loc];
+ uc->uc_entries[loc] = victim;
+ uc->uc_fifo[uc->uc_nextvictim++] = victim;
+ uc->uc_nextvictim %= uc->uc_size;
+}
+
+/*
+ * Try to get an entry from the cache
+ * return 1 if found, 0 if not found
+ */
+static int
+cache_get(xprt, msg, replyp, replylenp)
+ SVCXPRT *xprt;
+ struct rpc_msg *msg;
+ char **replyp;
+ u_long *replylenp;
+{
+ u_int loc;
+ register cache_ptr ent;
+ register struct svcudp_data *su = su_data(xprt);
+ register struct udp_cache *uc = (struct udp_cache *) su->su_cache;
+
+# define EQADDR(a1, a2) (memcmp(&a1, &a2, sizeof(a1)) == 0)
+
+ loc = CACHE_LOC(xprt, su->su_xid);
+ for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) {
+ if (ent->cache_xid == su->su_xid &&
+ ent->cache_proc == uc->uc_proc &&
+ ent->cache_vers == uc->uc_vers &&
+ ent->cache_prog == uc->uc_prog &&
+ EQADDR(ent->cache_addr, uc->uc_addr)) {
+ *replyp = ent->cache_reply;
+ *replylenp = ent->cache_replylen;
+ return(1);
+ }
+ }
+ /*
+ * Failed to find entry
+ * Remember a few things so we can do a set later
+ */
+ uc->uc_proc = msg->rm_call.cb_proc;
+ uc->uc_vers = msg->rm_call.cb_vers;
+ uc->uc_prog = msg->rm_call.cb_prog;
+ uc->uc_addr = xprt->xp_raddr;
+ return(0);
+}
+
diff --git a/lib/libc/rpc/svc_unix.c b/lib/libc/rpc/svc_unix.c
new file mode 100644
index 0000000..365f1a5
--- /dev/null
+++ b/lib/libc/rpc/svc_unix.c
@@ -0,0 +1,530 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_unix.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * svc_unix.c, Server side for TCP/IP based RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Actually implements two flavors of transporter -
+ * a unix rendezvouser (a listner and connection establisher)
+ * and a record/unix stream.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/uio.h>
+#include <errno.h>
+
+/*
+ * Ops vector for AF_UNIX based rpc service handle
+ */
+static bool_t svcunix_recv();
+static enum xprt_stat svcunix_stat();
+static bool_t svcunix_getargs();
+static bool_t svcunix_reply();
+static bool_t svcunix_freeargs();
+static void svcunix_destroy();
+
+static struct xp_ops svcunix_op = {
+ svcunix_recv,
+ svcunix_stat,
+ svcunix_getargs,
+ svcunix_reply,
+ svcunix_freeargs,
+ svcunix_destroy
+};
+
+/*
+ * Ops vector for TCP/IP rendezvous handler
+ */
+static bool_t rendezvous_request();
+static enum xprt_stat rendezvous_stat();
+
+static struct xp_ops svcunix_rendezvous_op = {
+ rendezvous_request,
+ rendezvous_stat,
+ (bool_t (*)())abort,
+ (bool_t (*)())abort,
+ (bool_t (*)())abort,
+ svcunix_destroy
+};
+
+static int readunix(), writeunix();
+static SVCXPRT *makefd_xprt();
+
+struct unix_rendezvous { /* kept in xprt->xp_p1 */
+ u_int sendsize;
+ u_int recvsize;
+};
+
+struct unix_conn { /* kept in xprt->xp_p1 */
+ enum xprt_stat strm_stat;
+ u_long x_id;
+ XDR xdrs;
+ char verf_body[MAX_AUTH_BYTES];
+};
+
+
+struct cmessage {
+ struct cmsghdr cmsg;
+ struct cmsgcred cmcred;
+};
+
+static struct cmessage cm;
+
+static int __msgread(sock, buf, cnt)
+ int sock;
+ void *buf;
+ size_t cnt;
+{
+ struct iovec iov[1];
+ struct msghdr msg;
+
+ bzero((char *)&cm, sizeof(cm));
+ iov[0].iov_base = buf;
+ iov[0].iov_len = cnt;
+
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = (caddr_t)&cm;
+ msg.msg_controllen = sizeof(struct cmessage);
+ msg.msg_flags = 0;
+
+ return(recvmsg(sock, &msg, 0));
+}
+
+static int __msgwrite(sock, buf, cnt)
+ int sock;
+ void *buf;
+ size_t cnt;
+{
+ struct iovec iov[1];
+ struct msghdr msg;
+
+ bzero((char *)&cm, sizeof(cm));
+ iov[0].iov_base = buf;
+ iov[0].iov_len = cnt;
+
+ cm.cmsg.cmsg_type = SCM_CREDS;
+ cm.cmsg.cmsg_level = SOL_SOCKET;
+ cm.cmsg.cmsg_len = sizeof(struct cmessage);
+
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = (caddr_t)&cm;
+ msg.msg_controllen = sizeof(struct cmessage);
+ msg.msg_flags = 0;
+
+ return(sendmsg(sock, &msg, 0));
+}
+
+/*
+ * Usage:
+ * xprt = svcunix_create(sock, send_buf_size, recv_buf_size);
+ *
+ * Creates, registers, and returns a (rpc) unix based transporter.
+ * Once *xprt is initialized, it is registered as a transporter
+ * see (svc.h, xprt_register). This routine returns
+ * a NULL if a problem occurred.
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svcunix_create
+ * binds it to an arbitrary port. The routine then starts a unix
+ * listener on the socket's associated port. In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ *
+ * Since unix streams do buffered io similar to stdio, the caller can specify
+ * how big the send and receive buffers are via the second and third parms;
+ * 0 => use the system default.
+ */
+SVCXPRT *
+svcunix_create(sock, sendsize, recvsize, path)
+ register int sock;
+ u_int sendsize;
+ u_int recvsize;
+ char *path;
+{
+ bool_t madesock = FALSE;
+ register SVCXPRT *xprt;
+ register struct unix_rendezvous *r;
+ struct sockaddr_un addr;
+ int len = sizeof(struct sockaddr_un);
+
+ if (sock == RPC_ANYSOCK) {
+ if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ perror("svc_unix.c - AF_UNIX socket creation problem");
+ return ((SVCXPRT *)NULL);
+ }
+ madesock = TRUE;
+ }
+ memset(&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, path);
+ len = strlen(addr.sun_path) + sizeof(addr.sun_family) +
+ sizeof(addr.sun_len) + 1;
+ addr.sun_len = len;
+
+ bind(sock, (struct sockaddr *)&addr, len);
+
+ if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0) ||
+ (listen(sock, 2) != 0)) {
+ perror("svc_unix.c - cannot getsockname or listen");
+ if (madesock)
+ (void)close(sock);
+ return ((SVCXPRT *)NULL);
+ }
+ r = (struct unix_rendezvous *)mem_alloc(sizeof(*r));
+ if (r == NULL) {
+ (void) fprintf(stderr, "svcunix_create: out of memory\n");
+ return (NULL);
+ }
+ r->sendsize = sendsize;
+ r->recvsize = recvsize;
+ xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+ if (xprt == NULL) {
+ (void) fprintf(stderr, "svcunix_create: out of memory\n");
+ return (NULL);
+ }
+ xprt->xp_p2 = NULL;
+ xprt->xp_p1 = (caddr_t)r;
+ xprt->xp_verf = _null_auth;
+ xprt->xp_ops = &svcunix_rendezvous_op;
+ xprt->xp_port = -1 /*ntohs(addr.sin_port)*/;
+ xprt->xp_sock = sock;
+ xprt_register(xprt);
+ return (xprt);
+}
+
+/*
+ * Like svunix_create(), except the routine takes any *open* UNIX file
+ * descriptor as its first input.
+ */
+SVCXPRT *
+svcunixfd_create(fd, sendsize, recvsize)
+ int fd;
+ u_int sendsize;
+ u_int recvsize;
+{
+
+ return (makefd_xprt(fd, sendsize, recvsize));
+}
+
+static SVCXPRT *
+makefd_xprt(fd, sendsize, recvsize)
+ int fd;
+ u_int sendsize;
+ u_int recvsize;
+{
+ register SVCXPRT *xprt;
+ register struct unix_conn *cd;
+
+ xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+ if (xprt == (SVCXPRT *)NULL) {
+ (void) fprintf(stderr, "svc_unix: makefd_xprt: out of memory\n");
+ goto done;
+ }
+ cd = (struct unix_conn *)mem_alloc(sizeof(struct unix_conn));
+ if (cd == (struct unix_conn *)NULL) {
+ (void) fprintf(stderr, "svc_unix: makefd_xprt: out of memory\n");
+ mem_free((char *) xprt, sizeof(SVCXPRT));
+ xprt = (SVCXPRT *)NULL;
+ goto done;
+ }
+ cd->strm_stat = XPRT_IDLE;
+ xdrrec_create(&(cd->xdrs), sendsize, recvsize,
+ (caddr_t)xprt, readunix, writeunix);
+ xprt->xp_p2 = NULL;
+ xprt->xp_p1 = (caddr_t)cd;
+ xprt->xp_verf.oa_base = cd->verf_body;
+ xprt->xp_addrlen = 0;
+ xprt->xp_ops = &svcunix_op; /* truely deals with calls */
+ xprt->xp_port = 0; /* this is a connection, not a rendezvouser */
+ xprt->xp_sock = fd;
+ xprt_register(xprt);
+ done:
+ return (xprt);
+}
+
+static bool_t
+rendezvous_request(xprt)
+ register SVCXPRT *xprt;
+{
+ int sock;
+ struct unix_rendezvous *r;
+ struct sockaddr_un addr;
+ struct sockaddr_in in_addr;
+ int len;
+
+ r = (struct unix_rendezvous *)xprt->xp_p1;
+ again:
+ len = sizeof(struct sockaddr_in);
+ if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr,
+ &len)) < 0) {
+ if (errno == EINTR)
+ goto again;
+ return (FALSE);
+ }
+
+ /*
+ * make a new transporter (re-uses xprt)
+ */
+ bzero((char *)&in_addr, sizeof(in_addr));
+ in_addr.sin_family = AF_UNIX;
+ xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
+ xprt->xp_raddr = in_addr;
+ xprt->xp_addrlen = len;
+ return (FALSE); /* there is never an rpc msg to be processed */
+}
+
+static enum xprt_stat
+rendezvous_stat()
+{
+
+ return (XPRT_IDLE);
+}
+
+static void
+svcunix_destroy(xprt)
+ register SVCXPRT *xprt;
+{
+ register struct unix_conn *cd = (struct unix_conn *)xprt->xp_p1;
+
+ xprt_unregister(xprt);
+ (void)close(xprt->xp_sock);
+ if (xprt->xp_port != 0) {
+ /* a rendezvouser socket */
+ xprt->xp_port = 0;
+ } else {
+ /* an actual connection socket */
+ XDR_DESTROY(&(cd->xdrs));
+ }
+ mem_free((caddr_t)cd, sizeof(struct unix_conn));
+ mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+/*
+ * All read operations timeout after 35 seconds.
+ * A timeout is fatal for the connection.
+ */
+static struct timeval wait_per_try = { 35, 0 };
+
+/*
+ * reads data from the unix conection.
+ * any error is fatal and the connection is closed.
+ * (And a read of zero bytes is a half closed stream => error.)
+ *
+ * Note: we have to be careful here not to allow ourselves to become
+ * blocked too long in this routine. While we're waiting for data from one
+ * client, another client may be trying to connect. To avoid this situation,
+ * some code from svc_run() is transplanted here: the select() loop checks
+ * all RPC descriptors including the one we want and calls svc_getreqset2()
+ * to handle new requests if any are detected.
+ */
+static int
+readunix(xprt, buf, len)
+ register SVCXPRT *xprt;
+ caddr_t buf;
+ register int len;
+{
+ register int sock = xprt->xp_sock;
+ struct timeval start, delta, tv;
+ struct timeval tmp1, tmp2;
+ fd_set *fds;
+ extern fd_set *__svc_fdset;
+ extern int __svc_fdsetsize;
+
+ delta = wait_per_try;
+ fds = NULL;
+ gettimeofday(&start, NULL);
+ do {
+ int bytes = howmany(__svc_fdsetsize, NFDBITS) *
+ sizeof(fd_mask);
+ if (fds != NULL)
+ free(fds);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL)
+ goto fatal_err;
+ memcpy(fds, __svc_fdset, bytes);
+
+ /* XXX we know the other bits are still clear */
+ FD_SET(sock, fds);
+ tv = delta; /* in case select() implements writeback */
+ switch (select(svc_maxfd + 1, fds, NULL, NULL, &tv)) {
+ case -1:
+ if (errno != EINTR)
+ goto fatal_err;
+ gettimeofday(&tmp1, NULL);
+ timersub(&tmp1, &start, &tmp2);
+ timersub(&wait_per_try, &tmp2, &tmp1);
+ if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
+ goto fatal_err;
+ delta = tmp1;
+ continue;
+ case 0:
+ goto fatal_err;
+ default:
+ if (!FD_ISSET(sock, fds)) {
+ svc_getreqset2(fds, svc_maxfd + 1);
+ gettimeofday(&tmp1, NULL);
+ timersub(&tmp1, &start, &tmp2);
+ timersub(&wait_per_try, &tmp2, &tmp1);
+ if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
+ goto fatal_err;
+ delta = tmp1;
+ continue;
+ }
+ }
+ } while (!FD_ISSET(sock, fds));
+ if ((len = __msgread(sock, buf, len)) > 0) {
+ if (fds != NULL)
+ free(fds);
+ return (len);
+ }
+fatal_err:
+ ((struct unix_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
+ if (fds != NULL)
+ free(fds);
+ return (-1);
+}
+
+/*
+ * writes data to the unix connection.
+ * Any error is fatal and the connection is closed.
+ */
+static int
+writeunix(xprt, buf, len)
+ register SVCXPRT *xprt;
+ caddr_t buf;
+ int len;
+{
+ register int i, cnt;
+
+ for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+ if ((i = __msgwrite(xprt->xp_sock, buf, cnt)) < 0) {
+ ((struct unix_conn *)(xprt->xp_p1))->strm_stat =
+ XPRT_DIED;
+ return (-1);
+ }
+ }
+ return (len);
+}
+
+static enum xprt_stat
+svcunix_stat(xprt)
+ SVCXPRT *xprt;
+{
+ register struct unix_conn *cd =
+ (struct unix_conn *)(xprt->xp_p1);
+
+ if (cd->strm_stat == XPRT_DIED)
+ return (XPRT_DIED);
+ if (! xdrrec_eof(&(cd->xdrs)))
+ return (XPRT_MOREREQS);
+ return (XPRT_IDLE);
+}
+
+static bool_t
+svcunix_recv(xprt, msg)
+ SVCXPRT *xprt;
+ register struct rpc_msg *msg;
+{
+ register struct unix_conn *cd =
+ (struct unix_conn *)(xprt->xp_p1);
+ register XDR *xdrs = &(cd->xdrs);
+
+ xdrs->x_op = XDR_DECODE;
+ (void)xdrrec_skiprecord(xdrs);
+ if (xdr_callmsg(xdrs, msg)) {
+ cd->x_id = msg->rm_xid;
+ /* set up verifiers */
+ msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX;
+ msg->rm_call.cb_verf.oa_base = (caddr_t)&cm;
+ msg->rm_call.cb_verf.oa_length = sizeof(cm);
+ return (TRUE);
+ }
+ cd->strm_stat = XPRT_DIED; /* XXXX */
+ return (FALSE);
+}
+
+static bool_t
+svcunix_getargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+
+ return ((*xdr_args)(&(((struct unix_conn *)(xprt->xp_p1))->xdrs), args_ptr));
+}
+
+static bool_t
+svcunix_freeargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+ register XDR *xdrs =
+ &(((struct unix_conn *)(xprt->xp_p1))->xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static bool_t
+svcunix_reply(xprt, msg)
+ SVCXPRT *xprt;
+ register struct rpc_msg *msg;
+{
+ register struct unix_conn *cd =
+ (struct unix_conn *)(xprt->xp_p1);
+ register XDR *xdrs = &(cd->xdrs);
+ register bool_t stat;
+
+ xdrs->x_op = XDR_ENCODE;
+ msg->rm_xid = cd->x_id;
+ stat = xdr_replymsg(xdrs, msg);
+ (void)xdrrec_endofrecord(xdrs, TRUE);
+ return (stat);
+}
diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc
new file mode 100644
index 0000000..514ab31
--- /dev/null
+++ b/lib/libc/stdio/Makefile.inc
@@ -0,0 +1,45 @@
+# @(#)Makefile.inc 8.3 (Berkeley) 4/17/94
+# $FreeBSD$
+
+# stdio sources
+.PATH: ${.CURDIR}/../libc/stdio
+
+SRCS+= _flock_stub.c \
+ asprintf.c clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c \
+ fgetc.c fgetln.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \
+ fprintf.c fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \
+ fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \
+ getc.c getchar.c gets.c getw.c makebuf.c mktemp.c perror.c \
+ printf.c putc.c putchar.c puts.c putw.c refill.c remove.c rewind.c \
+ rget.c scanf.c setbuf.c setbuffer.c setvbuf.c snprintf.c sprintf.c \
+ sscanf.c stdio.c tempnam.c tmpfile.c tmpnam.c ungetc.c vasprintf.c \
+ vfprintf.c vfscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c \
+ vsscanf.c wbuf.c wsetup.c
+
+.if ${LIB} == "c"
+MAN3+= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fopen.3 fputs.3 \
+ fread.3 fseek.3 funopen.3 getc.3 mktemp.3 printf.3 putc.3 remove.3 \
+ scanf.3 setbuf.3 stdio.3 tmpnam.3 ungetc.3
+
+MLINKS+=ferror.3 clearerr.3 ferror.3 feof.3 ferror.3 fileno.3
+MLINKS+=fflush.3 fpurge.3
+MLINKS+=fgets.3 gets.3
+MLINKS+=fopen.3 fdopen.3 fopen.3 freopen.3
+MLINKS+=fputs.3 puts.3
+MLINKS+=fread.3 fwrite.3
+MLINKS+=fseek.3 fgetpos.3 fseek.3 fseeko.3 fseek.3 fsetpos.3 fseek.3 ftell.3 \
+ fseek.3 ftello.3 fseek.3 rewind.3
+MLINKS+=funopen.3 fropen.3 funopen.3 fwopen.3
+MLINKS+=getc.3 fgetc.3 getc.3 getchar.3 getc.3 getw.3
+MLINKS+=mktemp.3 mkdtemp.3 mktemp.3 mkstemp.3 mktemp.3 mkstemps.3
+MLINKS+=printf.3 asprintf.3 printf.3 fprintf.3 \
+ printf.3 snprintf.3 printf.3 sprintf.3 \
+ printf.3 vasprintf.3 \
+ printf.3 vfprintf.3 printf.3 vprintf.3 printf.3 vsnprintf.3 \
+ printf.3 vsprintf.3
+MLINKS+=putc.3 fputc.3 putc.3 putchar.3 putc.3 putw.3
+MLINKS+=scanf.3 fscanf.3 scanf.3 sscanf.3 scanf.3 vfscanf.3 scanf.3 vscanf.3 \
+ scanf.3 vsscanf.3
+MLINKS+=setbuf.3 setbuffer.3 setbuf.3 setlinebuf.3 setbuf.3 setvbuf.3
+MLINKS+=tmpnam.3 tempnam.3 tmpnam.3 tmpfile.3
+.endif
diff --git a/lib/libc/stdio/_flock_stub.c b/lib/libc/stdio/_flock_stub.c
new file mode 100644
index 0000000..ada714c
--- /dev/null
+++ b/lib/libc/stdio/_flock_stub.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+
+/* Don't build this in libc_r, just libc: */
+#ifndef _THREAD_SAFE
+/*
+ * Declare weak references in case the application is not linked
+ * with libpthread.
+ */
+#pragma weak flockfile=_flockfile_stub
+#pragma weak _flockfile_debug=_flockfile_debug_stub
+#pragma weak ftrylockfile=_ftrylockfile_stub
+#pragma weak funlockfile=_funlockfile_stub
+
+/*
+ * This function is a stub for the _flockfile function in libpthread.
+ */
+void
+_flockfile_stub(FILE *fp)
+{
+}
+
+/*
+ * This function is a stub for the _flockfile_debug function in libpthread.
+ */
+void
+_flockfile_debug_stub(FILE *fp, char *fname, int lineno)
+{
+}
+
+/*
+ * This function is a stub for the _ftrylockfile function in libpthread.
+ */
+int
+_ftrylockfile_stub(FILE *fp)
+{
+ return(0);
+}
+
+/*
+ * This function is a stub for the _funlockfile function in libpthread.
+ */
+void
+_funlockfile_stub(FILE *fp)
+{
+}
+#endif
diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c
new file mode 100644
index 0000000..e125bfc
--- /dev/null
+++ b/lib/libc/stdio/asprintf.c
@@ -0,0 +1,81 @@
+/* $OpenBSD: asprintf.c,v 1.4 1998/06/21 22:13:46 millert Exp $ */
+
+/*
+ * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+#if __STDC__
+asprintf(char **str, char const *fmt, ...)
+#else
+asprintf(str, fmt, va_alist)
+ char **str;
+ const char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+ FILE f;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ f._file = -1;
+ f._flags = __SWR | __SSTR | __SALC;
+ f._bf._base = f._p = (unsigned char *)malloc(128);
+ if (f._bf._base == NULL) {
+ *str = NULL;
+ errno = ENOMEM;
+ return (-1);
+ }
+ f._bf._size = f._w = 127; /* Leave room for the NULL */
+ ret = vfprintf(&f, fmt, ap);
+ *f._p = '\0';
+ va_end(ap);
+ f._bf._base = reallocf(f._bf._base, f._bf._size + 1);
+ if (f._bf._base == NULL) {
+ errno = ENOMEM;
+ ret = -1;
+ }
+ *str = (char *)f._bf._base;
+ return (ret);
+}
diff --git a/lib/libc/stdio/clrerr.c b/lib/libc/stdio/clrerr.c
new file mode 100644
index 0000000..4e6b720
--- /dev/null
+++ b/lib/libc/stdio/clrerr.c
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)clrerr.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#undef clearerr
+#include "libc_private.h"
+
+void
+clearerr(fp)
+ FILE *fp;
+{
+ FLOCKFILE(fp);
+ __sclearerr(fp);
+ FUNLOCKFILE(fp);
+}
diff --git a/lib/libc/stdio/fclose.3 b/lib/libc/stdio/fclose.3
new file mode 100644
index 0000000..9850c8b
--- /dev/null
+++ b/lib/libc/stdio/fclose.3
@@ -0,0 +1,95 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fclose.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt FCLOSE 3
+.Os
+.Sh NAME
+.Nm fclose
+.Nd close a stream
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft int
+.Fn fclose "FILE *stream"
+.Sh DESCRIPTION
+The
+.Fn fclose
+function
+dissociates the named
+.Fa stream
+from its underlying file or set of functions.
+If the stream was being used for output, any buffered data is written
+first, using
+.Xr fflush 3 .
+.Sh RETURN VALUES
+Upon successful completion 0 is returned.
+Otherwise,
+.Dv EOF
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+In either case no further access to the stream is possible.
+.Sh ERRORS
+The
+.Fn fclose
+function
+may also fail and set
+.Va errno
+for any of the errors specified for the routines
+.Xr close 2
+or
+.Xr fflush 3 .
+.Sh NOTES
+.Fn fclose
+does not handle NULL arguments; they will result in a segmentation
+violation.
+This is intentional - it makes it easier to make sure programs written
+under FreeBSD are bug free.
+This behaviour is an implementation detail, and programs should not
+rely upon it.
+.Sh SEE ALSO
+.Xr close 2 ,
+.Xr fflush 3 ,
+.Xr fopen 3 ,
+.Xr setbuf 3
+.Sh STANDARDS
+The
+.Fn fclose
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/stdio/fclose.c b/lib/libc/stdio/fclose.c
new file mode 100644
index 0000000..8ddb98b
--- /dev/null
+++ b/lib/libc/stdio/fclose.c
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fclose.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+#include "libc_private.h"
+
+int
+fclose(fp)
+ register FILE *fp;
+{
+ register int r;
+
+ if (fp->_flags == 0) { /* not open! */
+ errno = EBADF;
+ return (EOF);
+ }
+ FLOCKFILE(fp);
+ r = fp->_flags & __SWR ? __sflush(fp) : 0;
+ if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
+ r = EOF;
+ if (fp->_flags & __SMBF)
+ free((char *)fp->_bf._base);
+ if (HASUB(fp))
+ FREEUB(fp);
+ if (HASLB(fp))
+ FREELB(fp);
+ FUNLOCKFILE(fp);
+ fp->_file = -1;
+ fp->_r = fp->_w = 0; /* Mess up if reaccessed. */
+ fp->_flags = 0; /* Release this FILE for reuse. */
+ return (r);
+}
diff --git a/lib/libc/stdio/fdopen.c b/lib/libc/stdio/fdopen.c
new file mode 100644
index 0000000..48ea401
--- /dev/null
+++ b/lib/libc/stdio/fdopen.c
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fdopen.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include "local.h"
+
+FILE *
+fdopen(fd, mode)
+ int fd;
+ const char *mode;
+{
+ register FILE *fp;
+ static int nofile;
+ int flags, oflags, fdflags, tmp;
+
+ if (nofile == 0)
+ nofile = getdtablesize();
+
+ if ((flags = __sflags(mode, &oflags)) == 0)
+ return (NULL);
+
+ /* Make sure the mode the user wants is a subset of the actual mode. */
+ if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0)
+ return (NULL);
+ tmp = fdflags & O_ACCMODE;
+ if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if ((fp = __sfp()) == NULL)
+ return (NULL);
+ fp->_flags = flags;
+ /*
+ * If opened for appending, but underlying descriptor does not have
+ * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to
+ * end before each write.
+ */
+ if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
+ fp->_flags |= __SAPP;
+ fp->_file = fd;
+ fp->_cookie = fp;
+ fp->_read = __sread;
+ fp->_write = __swrite;
+ fp->_seek = __sseek;
+ fp->_close = __sclose;
+ return (fp);
+}
diff --git a/lib/libc/stdio/feof.c b/lib/libc/stdio/feof.c
new file mode 100644
index 0000000..3581100
--- /dev/null
+++ b/lib/libc/stdio/feof.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)feof.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro feof.
+ */
+#undef feof
+
+int
+feof(fp)
+ FILE *fp;
+{
+ return (__sfeof(fp));
+}
diff --git a/lib/libc/stdio/ferror.3 b/lib/libc/stdio/ferror.3
new file mode 100644
index 0000000..c6850c9
--- /dev/null
+++ b/lib/libc/stdio/ferror.3
@@ -0,0 +1,101 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ferror.3 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt FERROR 3
+.Os
+.Sh NAME
+.Nm clearerr ,
+.Nm feof ,
+.Nm ferror ,
+.Nm fileno
+.Nd check and reset stream status
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft void
+.Fn clearerr "FILE *stream"
+.Ft int
+.Fn feof "FILE *stream"
+.Ft int
+.Fn ferror "FILE *stream"
+.Ft int
+.Fn fileno "FILE *stream"
+.Sh DESCRIPTION
+The function
+.Fn clearerr
+clears the end-of-file and error indicators for the stream pointed
+to by
+.Fa stream .
+.Pp
+The function
+.Fn feof
+tests the end-of-file indicator for the stream pointed to by
+.Fa stream ,
+returning non-zero if it is set.
+The end-of-file indicator can only be cleared by the function
+.Fn clearerr .
+.Pp
+The function
+.Fn ferror
+tests the error indicator for the stream pointed to by
+.Fa stream ,
+returning non-zero if it is set.
+The error indicator can only be reset by the
+.Fn clearerr
+function.
+.Pp
+The function
+.Fn fileno
+examines the argument
+.Fa stream
+and returns its integer descriptor.
+.Sh ERRORS
+These functions should not fail and do not set the external
+variable
+.Va errno .
+.Sh SEE ALSO
+.Xr open 2 ,
+.Xr stdio 3
+.Sh STANDARDS
+The functions
+.Fn clearerr ,
+.Fn feof ,
+and
+.Fn ferror
+conform to
+.St -ansiC .
diff --git a/lib/libc/stdio/ferror.c b/lib/libc/stdio/ferror.c
new file mode 100644
index 0000000..2311926
--- /dev/null
+++ b/lib/libc/stdio/ferror.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)ferror.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro ferror.
+ */
+#undef ferror
+
+int
+ferror(fp)
+ FILE *fp;
+{
+ return (__sferror(fp));
+}
diff --git a/lib/libc/stdio/fflush.3 b/lib/libc/stdio/fflush.3
new file mode 100644
index 0000000..0b0ed43
--- /dev/null
+++ b/lib/libc/stdio/fflush.3
@@ -0,0 +1,111 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fflush.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt FFLUSH 3
+.Os
+.Sh NAME
+.Nm fflush ,
+.Nm fpurge
+.Nd flush a stream
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft int
+.Fn fflush "FILE *stream"
+.Ft int
+.Fn fpurge "FILE *stream"
+.Sh DESCRIPTION
+The function
+.Fn fflush
+forces a write of all buffered data for the given output or update
+.Fa stream
+via the stream's underlying write function.
+The open status of the stream is unaffected.
+.Pp
+If the
+.Fa stream
+argument is
+.Dv NULL ,
+.Fn fflush
+flushes
+.Em all
+open output streams.
+.Pp
+The function
+.Fn fpurge
+erases any input or output buffered in the given
+.Fa stream .
+For output streams this discards any unwritten output.
+For input streams this discards any input read from the underlying object
+but not yet obtained via
+.Xr getc 3 ;
+this includes any text pushed back via
+.Xr ungetc .
+.Sh RETURN VALUES
+Upon successful completion 0 is returned.
+Otherwise,
+.Dv EOF
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Bl -tag -width [EBADF]
+.It Bq Er EBADF
+.Fa Stream
+is not an open stream, or, in the case of
+.Fn fflush ,
+not a stream open for writing.
+.El
+.Pp
+The function
+.Fn fflush
+may also fail and set
+.Va errno
+for any of the errors specified for the routine
+.Xr write 2 .
+.Sh SEE ALSO
+.Xr write 2 ,
+.Xr fclose 3 ,
+.Xr fopen 3 ,
+.Xr setbuf 3
+.Sh STANDARDS
+The
+.Fn fflush
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c
new file mode 100644
index 0000000..cd7fbe8
--- /dev/null
+++ b/lib/libc/stdio/fflush.c
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fflush.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+#include "local.h"
+#include "libc_private.h"
+
+/* Flush a single file, or (if fp is NULL) all files. */
+int
+fflush(fp)
+ register FILE *fp;
+{
+ int retval;
+
+ if (fp == NULL)
+ return (_fwalk(__sflush));
+ FLOCKFILE(fp);
+ if ((fp->_flags & (__SWR | __SRW)) == 0) {
+ errno = EBADF;
+ retval = EOF;
+ } else {
+ retval = __sflush(fp);
+ }
+ FUNLOCKFILE(fp);
+ return (retval);
+}
+
+int
+__sflush(fp)
+ register FILE *fp;
+{
+ register unsigned char *p;
+ register int n, t;
+
+ t = fp->_flags;
+ if ((t & __SWR) == 0)
+ return (0);
+
+ if ((p = fp->_bf._base) == NULL)
+ return (0);
+
+ n = fp->_p - p; /* write this much */
+
+ /*
+ * Set these immediately to avoid problems with longjmp and to allow
+ * exchange buffering (via setvbuf) in user write function.
+ */
+ fp->_p = p;
+ fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
+
+ for (; n > 0; n -= t, p += t) {
+ t = (*fp->_write)(fp->_cookie, (char *)p, n);
+ if (t <= 0) {
+ fp->_flags |= __SERR;
+ return (EOF);
+ }
+ }
+ return (0);
+}
diff --git a/lib/libc/stdio/fgetc.c b/lib/libc/stdio/fgetc.c
new file mode 100644
index 0000000..4e52705
--- /dev/null
+++ b/lib/libc/stdio/fgetc.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fgetc.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "libc_private.h"
+
+int
+fgetc(fp)
+ FILE *fp;
+{
+ int retval;
+ FLOCKFILE(fp);
+ retval = __sgetc(fp);
+ FUNLOCKFILE(fp);
+ return (retval);
+}
diff --git a/lib/libc/stdio/fgetln.3 b/lib/libc/stdio/fgetln.3
new file mode 100644
index 0000000..17c09e7
--- /dev/null
+++ b/lib/libc/stdio/fgetln.3
@@ -0,0 +1,125 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fgetln.3 8.3 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt FGETLN 3
+.Os
+.Sh NAME
+.Nm fgetln
+.Nd get a line from a stream
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft char *
+.Fn fgetln "FILE *stream" "size_t *len"
+.Sh DESCRIPTION
+The
+.Fn fgetln
+function
+returns a pointer to the next line from the stream referenced by
+.Fa stream .
+This line is
+.Em not
+a C string as it does not end with a terminating
+.Dv NUL
+character.
+The length of the line, including the final newline,
+is stored in the memory location to which
+.Fa len
+points.
+(Note, however, that if the line is the last
+in a file that does not end in a newline,
+the returned text will not contain a newline.)
+.Sh RETURN VALUES
+Upon successful completion a pointer is returned;
+this pointer becomes invalid after the next
+.Tn I/O
+operation on
+.Fa stream
+(whether successful or not)
+or as soon as the stream is closed.
+Otherwise,
+.Dv NULL
+is returned.
+The
+.Fn fgetln
+function
+does not distinguish between end-of-file and error; the routines
+.Xr feof 3
+and
+.Xr ferror 3
+must be used
+to determine which occurred.
+If an error occurs, the global variable
+.Va errno
+is set to indicate the error.
+The end-of-file condition is remembered, even on a terminal, and all
+subsequent attempts to read will return
+.Dv NULL
+until the condition is
+cleared with
+.Xr clearerr 3 .
+.Pp
+The text to which the returned pointer points may be modified,
+provided that no changes are made beyond the returned size.
+These changes are lost as soon as the pointer becomes invalid.
+.Sh ERRORS
+.Bl -tag -width [EBADF]
+.It Bq Er EBADF
+The argument
+.Fa stream
+is not a stream open for reading.
+.El
+.Pp
+The
+.Fn fgetln
+function
+may also fail and set
+.Va errno
+for any of the errors specified for the routines
+.Xr fflush 3 ,
+.Xr malloc 3 ,
+.Xr read 2 ,
+.Xr stat 2 ,
+or
+.Xr realloc 3 .
+.Sh SEE ALSO
+.Xr ferror 3 ,
+.Xr fgets 3 ,
+.Xr fopen 3 ,
+.Xr putc 3
+.Sh HISTORY
+The
+.Fn fgetln
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/stdio/fgetln.c b/lib/libc/stdio/fgetln.c
new file mode 100644
index 0000000..3987b0d
--- /dev/null
+++ b/lib/libc/stdio/fgetln.c
@@ -0,0 +1,165 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fgetln.c 8.2 (Berkeley) 1/2/94";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "local.h"
+
+/*
+ * Expand the line buffer. Return -1 on error.
+#ifdef notdef
+ * The `new size' does not account for a terminating '\0',
+ * so we add 1 here.
+#endif
+ */
+int
+__slbexpand(fp, newsize)
+ FILE *fp;
+ size_t newsize;
+{
+ void *p;
+
+#ifdef notdef
+ ++newsize;
+#endif
+ if (fp->_lb._size >= newsize)
+ return (0);
+ if ((p = realloc(fp->_lb._base, newsize)) == NULL)
+ return (-1);
+ fp->_lb._base = p;
+ fp->_lb._size = newsize;
+ return (0);
+}
+
+/*
+ * Get an input line. The returned pointer often (but not always)
+ * points into a stdio buffer. Fgetln does not alter the text of
+ * the returned line (which is thus not a C string because it will
+ * not necessarily end with '\0'), but does allow callers to modify
+ * it if they wish. Thus, we set __SMOD in case the caller does.
+ */
+char *
+fgetln(fp, lenp)
+ register FILE *fp;
+ size_t *lenp;
+{
+ register unsigned char *p;
+ register size_t len;
+ size_t off;
+
+ /* make sure there is input */
+ if (fp->_r <= 0 && __srefill(fp)) {
+ *lenp = 0;
+ return (NULL);
+ }
+
+ /* look for a newline in the input */
+ if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) != NULL) {
+ register char *ret;
+
+ /*
+ * Found one. Flag buffer as modified to keep fseek from
+ * `optimising' a backward seek, in case the user stomps on
+ * the text.
+ */
+ p++; /* advance over it */
+ ret = (char *)fp->_p;
+ *lenp = len = p - fp->_p;
+ fp->_flags |= __SMOD;
+ fp->_r -= len;
+ fp->_p = p;
+ return (ret);
+ }
+
+ /*
+ * We have to copy the current buffered data to the line buffer.
+ * As a bonus, though, we can leave off the __SMOD.
+ *
+ * OPTIMISTIC is length that we (optimistically) expect will
+ * accomodate the `rest' of the string, on each trip through the
+ * loop below.
+ */
+#define OPTIMISTIC 80
+
+ for (len = fp->_r, off = 0;; len += fp->_r) {
+ register size_t diff;
+
+ /*
+ * Make sure there is room for more bytes. Copy data from
+ * file buffer to line buffer, refill file and look for
+ * newline. The loop stops only when we find a newline.
+ */
+ if (__slbexpand(fp, len + OPTIMISTIC))
+ goto error;
+ (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
+ len - off);
+ off = len;
+ if (__srefill(fp))
+ break; /* EOF or error: return partial line */
+ if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL)
+ continue;
+
+ /* got it: finish up the line (like code above) */
+ p++;
+ diff = p - fp->_p;
+ len += diff;
+ if (__slbexpand(fp, len))
+ goto error;
+ (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
+ diff);
+ fp->_r -= diff;
+ fp->_p = p;
+ break;
+ }
+ *lenp = len;
+#ifdef notdef
+ fp->_lb._base[len] = 0;
+#endif
+ return ((char *)fp->_lb._base);
+
+error:
+ *lenp = 0; /* ??? */
+ return (NULL); /* ??? */
+}
diff --git a/lib/libc/stdio/fgetpos.c b/lib/libc/stdio/fgetpos.c
new file mode 100644
index 0000000..6d6cfa1
--- /dev/null
+++ b/lib/libc/stdio/fgetpos.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fgetpos.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "libc_private.h"
+
+int
+fgetpos(fp, pos)
+ FILE *fp;
+ fpos_t *pos;
+{
+ int retval;
+ FLOCKFILE(fp);
+ retval = (*pos = ftello(fp)) == (fpos_t)-1;
+ FUNLOCKFILE(fp);
+ return(retval);
+}
diff --git a/lib/libc/stdio/fgets.3 b/lib/libc/stdio/fgets.3
new file mode 100644
index 0000000..9b4d4ef
--- /dev/null
+++ b/lib/libc/stdio/fgets.3
@@ -0,0 +1,157 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fgets.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt FGETS 3
+.Os
+.Sh NAME
+.Nm fgets ,
+.Nm gets
+.Nd get a line from a stream
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft char *
+.Fn fgets "char *str" "int size" "FILE *stream"
+.Ft char *
+.Fn gets "char *str"
+.Sh DESCRIPTION
+The
+.Fn fgets
+function
+reads at most one less than the number of characters specified by
+.Fa size
+from the given
+.Fa stream
+and stores them in the string
+.Fa str .
+Reading stops when a newline character is found,
+at end-of-file or error.
+The newline, if any, is retained.
+If any characters are read and there is no error, a
+.Ql \e0
+character is appended to end the string.
+.Pp
+The
+.Fn gets
+function
+is equivalent to
+.Fn fgets
+with an infinite
+.Fa size
+and a
+.Fa stream
+of
+.Em stdin ,
+except that the newline character (if any) is not stored in the string.
+It is the caller's responsibility to ensure that the input line,
+if any, is sufficiently short to fit in the string.
+.Sh RETURN VALUES
+.Pp
+Upon successful completion,
+.Fn fgets
+and
+.Fn gets
+return
+a pointer to the string.
+If end-of-file occurs before any characters are read,
+they return
+.Dv NULL
+and the buffer contents is unchanged.
+If an error occurs,
+they return
+.Dv NULL
+and the buffer contents is indeterminate.
+The
+.Fn fgets
+and
+.Fn gets
+functions
+do not distinguish between end-of-file and error, and callers must use
+.Xr feof 3
+and
+.Xr ferror 3
+to determine which occurred.
+.Sh ERRORS
+.Bl -tag -width [EBADF]
+.It Bq Er EBADF
+The given
+.Fa stream
+is not a readable stream.
+.El
+.Pp
+The function
+.Fn fgets
+may also fail and set
+.Va errno
+for any of the errors specified for the routines
+.Xr fflush 3 ,
+.Xr fstat 2 ,
+.Xr read 2 ,
+or
+.Xr malloc 3 .
+.Pp
+The function
+.Fn gets
+may also fail and set
+.Va errno
+for any of the errors specified for the routine
+.Xr getchar 3 .
+.Sh SEE ALSO
+.Xr feof 3 ,
+.Xr ferror 3 ,
+.Xr fgetln 3
+.Sh STANDARDS
+The functions
+.Fn fgets
+and
+.Fn gets
+conform to
+.St -ansiC .
+.Sh BUGS
+Since it is usually impossible to ensure that the next input line
+is less than some arbitrary length, and because overflowing the
+input buffer is almost invariably a security violation, programs
+should
+.Em NEVER
+use
+.Fn gets .
+The
+.Fn gets
+function
+exists purely to conform to
+.St -ansiC .
diff --git a/lib/libc/stdio/fgets.c b/lib/libc/stdio/fgets.c
new file mode 100644
index 0000000..33b7144
--- /dev/null
+++ b/lib/libc/stdio/fgets.c
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fgets.c 8.2 (Berkeley) 12/22/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include "local.h"
+#include "libc_private.h"
+
+/*
+ * Read at most n-1 characters from the given file.
+ * Stop when a newline has been read, or the count runs out.
+ * Return first argument, or NULL if no characters were read.
+ */
+char *
+fgets(buf, n, fp)
+ char *buf;
+ register int n;
+ register FILE *fp;
+{
+ register size_t len;
+ register char *s;
+ register unsigned char *p, *t;
+
+ if (n <= 0) /* sanity check */
+ return (NULL);
+
+ FLOCKFILE(fp);
+ s = buf;
+ n--; /* leave space for NUL */
+ while (n != 0) {
+ /*
+ * If the buffer is empty, refill it.
+ */
+ if ((len = fp->_r) <= 0) {
+ if (__srefill(fp)) {
+ /* EOF/error: stop with partial or no line */
+ if (s == buf) {
+ FUNLOCKFILE(fp);
+ return (NULL);
+ }
+ break;
+ }
+ len = fp->_r;
+ }
+ p = fp->_p;
+
+ /*
+ * Scan through at most n bytes of the current buffer,
+ * looking for '\n'. If found, copy up to and including
+ * newline, and stop. Otherwise, copy entire chunk
+ * and loop.
+ */
+ if (len > n)
+ len = n;
+ t = memchr((void *)p, '\n', len);
+ if (t != NULL) {
+ len = ++t - p;
+ fp->_r -= len;
+ fp->_p = t;
+ (void)memcpy((void *)s, (void *)p, len);
+ s[len] = 0;
+ FUNLOCKFILE(fp);
+ return (buf);
+ }
+ fp->_r -= len;
+ fp->_p += len;
+ (void)memcpy((void *)s, (void *)p, len);
+ s += len;
+ n -= len;
+ }
+ *s = 0;
+ FUNLOCKFILE(fp);
+ return (buf);
+}
diff --git a/lib/libc/stdio/fileno.c b/lib/libc/stdio/fileno.c
new file mode 100644
index 0000000..0c3a8dc
--- /dev/null
+++ b/lib/libc/stdio/fileno.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fileno.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro fileno.
+ */
+#undef fileno
+
+int
+fileno(fp)
+ FILE *fp;
+{
+ return (__sfileno(fp));
+}
diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c
new file mode 100644
index 0000000..3cc08a9
--- /dev/null
+++ b/lib/libc/stdio/findfp.c
@@ -0,0 +1,186 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)findfp.c 8.2 (Berkeley) 1/4/94";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libc_private.h>
+#include <spinlock.h>
+
+#include "local.h"
+#include "glue.h"
+
+int __sdidinit;
+
+#define NDYNAMIC 10 /* add ten more whenever necessary */
+
+#define std(flags, file) \
+ {0,0,0,flags,file,{0},0,__sF+file,__sclose,__sread,__sseek,__swrite}
+/* p r w flags file _bf z cookie close read seek write */
+
+ /* the usual - (stdin + stdout + stderr) */
+static FILE usual[FOPEN_MAX - 3];
+static struct glue uglue = { 0, FOPEN_MAX - 3, usual };
+
+FILE __sF[3] = {
+ std(__SRD, STDIN_FILENO), /* stdin */
+ std(__SWR, STDOUT_FILENO), /* stdout */
+ std(__SWR|__SNBF, STDERR_FILENO) /* stderr */
+};
+struct glue __sglue = { &uglue, 3, __sF };
+
+static struct glue * moreglue __P((int));
+
+static spinlock_t thread_lock = _SPINLOCK_INITIALIZER;
+#define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&thread_lock)
+#define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&thread_lock)
+
+static struct glue *
+moreglue(n)
+ register int n;
+{
+ register struct glue *g;
+ register FILE *p;
+ static FILE empty;
+
+ g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE));
+ if (g == NULL)
+ return (NULL);
+ p = (FILE *)ALIGN(g + 1);
+ g->next = NULL;
+ g->niobs = n;
+ g->iobs = p;
+ while (--n >= 0)
+ *p++ = empty;
+ return (g);
+}
+
+/*
+ * Find a free FILE for fopen et al.
+ */
+FILE *
+__sfp()
+{
+ register FILE *fp;
+ register int n;
+ register struct glue *g;
+
+ if (!__sdidinit)
+ __sinit();
+ THREAD_LOCK();
+ for (g = &__sglue;; g = g->next) {
+ for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
+ if (fp->_flags == 0)
+ goto found;
+ if (g->next == NULL && (g->next = moreglue(NDYNAMIC)) == NULL)
+ break;
+ }
+ THREAD_UNLOCK();
+ return (NULL);
+found:
+ fp->_flags = 1; /* reserve this slot; caller sets real flags */
+ THREAD_UNLOCK();
+ fp->_p = NULL; /* no current pointer */
+ fp->_w = 0; /* nothing to read or write */
+ fp->_r = 0;
+ fp->_bf._base = NULL; /* no buffer */
+ fp->_bf._size = 0;
+ fp->_lbfsize = 0; /* not line buffered */
+ fp->_file = -1; /* no file */
+/* fp->_cookie = <any>; */ /* caller sets cookie, _read/_write etc */
+ fp->_ub._base = NULL; /* no ungetc buffer */
+ fp->_ub._size = 0;
+ fp->_lb._base = NULL; /* no line buffer */
+ fp->_lb._size = 0;
+ return (fp);
+}
+
+/*
+ * XXX. Force immediate allocation of internal memory. Not used by stdio,
+ * but documented historically for certain applications. Bad applications.
+ */
+__warn_references(f_prealloc,
+ "warning: this program uses f_prealloc(), which is stupid.");
+
+void
+f_prealloc()
+{
+ register struct glue *g;
+ int n;
+
+ n = getdtablesize() - FOPEN_MAX + 20; /* 20 for slop. */
+ for (g = &__sglue; (n -= g->niobs) > 0 && g->next; g = g->next)
+ /* void */;
+ if (n > 0)
+ g->next = moreglue(n);
+}
+
+/*
+ * exit() calls _cleanup() through *__cleanup, set whenever we
+ * open or buffer a file. This chicanery is done so that programs
+ * that do not use stdio need not link it all in.
+ *
+ * The name `_cleanup' is, alas, fairly well known outside stdio.
+ */
+void
+_cleanup()
+{
+ /* (void) _fwalk(fclose); */
+ (void) _fwalk(__sflush); /* `cheating' */
+}
+
+/*
+ * __sinit() is called whenever stdio's internal variables must be set up.
+ */
+void
+__sinit()
+{
+ /* make sure we clean up on exit */
+ __cleanup = _cleanup; /* conservative */
+ __sdidinit = 1;
+}
diff --git a/lib/libc/stdio/flags.c b/lib/libc/stdio/flags.c
new file mode 100644
index 0000000..afcc4d8
--- /dev/null
+++ b/lib/libc/stdio/flags.c
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)flags.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <errno.h>
+#include "local.h"
+
+/*
+ * Return the (stdio) flags for a given mode. Store the flags
+ * to be passed to an open() syscall through *optr.
+ * Return 0 on error.
+ */
+int
+__sflags(mode, optr)
+ register const char *mode;
+ int *optr;
+{
+ register int ret, m, o;
+
+ switch (*mode++) {
+
+ case 'r': /* open for reading */
+ ret = __SRD;
+ m = O_RDONLY;
+ o = 0;
+ break;
+
+ case 'w': /* open for writing */
+ ret = __SWR;
+ m = O_WRONLY;
+ o = O_CREAT | O_TRUNC;
+ break;
+
+ case 'a': /* open for appending */
+ ret = __SWR;
+ m = O_WRONLY;
+ o = O_CREAT | O_APPEND;
+ break;
+
+ default: /* illegal mode */
+ errno = EINVAL;
+ return (0);
+ }
+
+ /* [rwa]\+ or [rwa]b\+ means read and write */
+ if (*mode == '+' || (*mode == 'b' && mode[1] == '+')) {
+ ret = __SRW;
+ m = O_RDWR;
+ }
+ *optr = m | o;
+ return (ret);
+}
diff --git a/lib/libc/stdio/floatio.h b/lib/libc/stdio/floatio.h
new file mode 100644
index 0000000..c2089fe
--- /dev/null
+++ b/lib/libc/stdio/floatio.h
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)floatio.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * Floating point scanf/printf (input/output) definitions.
+ */
+
+/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
+#define MAXEXP 308
+/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
+#define MAXFRACT 39
diff --git a/lib/libc/stdio/fopen.3 b/lib/libc/stdio/fopen.3
new file mode 100644
index 0000000..0b76729
--- /dev/null
+++ b/lib/libc/stdio/fopen.3
@@ -0,0 +1,242 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fopen.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt FOPEN 3
+.Os
+.Sh NAME
+.Nm fopen ,
+.Nm fdopen ,
+.Nm freopen
+.Nd stream open functions
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft FILE *
+.Fn fopen "const char *path" "const char *mode"
+.Ft FILE *
+.Fn fdopen "int fildes" "const char *mode"
+.Ft FILE *
+.Fn freopen "const char *path" "const char *mode" "FILE *stream"
+.Sh DESCRIPTION
+The
+.Fn fopen
+function
+opens the file whose name is the string pointed to by
+.Fa path
+and associates a stream with it.
+.Pp
+The argument
+.Fa mode
+points to a string beginning with one of the following
+sequences (Additional characters may follow these sequences.):
+.Bl -tag -width indent
+.It Dq Li r
+Open text file for reading.
+The stream is positioned at the beginning of the file.
+.It Dq Li r+
+Open for reading and writing.
+The stream is positioned at the beginning of the file.
+.It Dq Li w
+Truncate file to zero length or create text file for writing.
+The stream is positioned at the beginning of the file.
+.It Dq Li w+
+Open for reading and writing.
+The file is created if it does not exist, otherwise it is truncated.
+The stream is positioned at the beginning of the file.
+.It Dq Li a
+Open for writing.
+The file is created if it does not exist.
+The stream is positioned at the end of the file.
+.It Dq Li a+
+Open for reading and writing.
+The file is created if it does not exist.
+The stream is positioned at the end of the file.
+.El
+.Pp
+The
+.Fa mode
+string can also include the letter ``b'' either as a third character or
+as a character between the characters in any of the two-character strings
+described above.
+This is strictly for compatibility with
+.St -ansiC
+and has no effect; the ``b'' is ignored.
+.Pp
+Any created files will have mode
+.Pf \\*q Dv S_IRUSR
+\&|
+.Dv S_IWUSR
+\&|
+.Dv S_IRGRP
+\&|
+.Dv S_IWGRP
+\&|
+.Dv S_IROTH
+\&|
+.Dv S_IWOTH Ns \\*q
+.Pq Li 0666 ,
+as modified by the process'
+umask value (see
+.Xr umask 2 ) .
+.Pp
+Reads and writes may be intermixed on read/write streams in any order,
+and do not require an intermediate seek as in previous versions of
+.Em stdio .
+This is not portable to other systems, however;
+.Tn ANSI C
+requires that
+a file positioning function intervene between output and input, unless
+an input operation encounters end-of-file.
+.Pp
+The
+.Fn fdopen
+function associates a stream with the existing file descriptor,
+.Fa fildes .
+The
+.Fa mode
+of the stream must be compatible with the mode of the file descriptor.
+When the stream is closed via
+.Xr fclose 3 ,
+.Fa fildes
+is closed also.
+.Pp
+The
+.Fn freopen
+function
+opens the file whose name is the string pointed to by
+.Fa path
+and associates the stream pointed to by
+.Fa stream
+with it.
+The original stream (if it exists) is closed.
+The
+.Fa mode
+argument is used just as in the
+.Fn fopen
+function.
+The primary use of the
+.Fn freopen
+function
+is to change the file associated with a
+standard text stream
+.Pf ( Em stderr ,
+.Em stdin ,
+or
+.Em stdout ) .
+.Sh RETURN VALUES
+Upon successful completion
+.Fn fopen ,
+.Fn fdopen
+and
+.Fn freopen
+return a
+.Tn FILE
+pointer.
+Otherwise,
+.Dv NULL
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Bl -tag -width [EINVAL]
+.It Bq Er EINVAL
+The
+.Fa mode
+provided to
+.Fn fopen ,
+.Fn fdopen ,
+or
+.Fn freopen
+was invalid.
+.El
+.Pp
+The
+.Fn fopen ,
+.Fn fdopen
+and
+.Fn freopen
+functions
+may also fail and set
+.Va errno
+for any of the errors specified for the routine
+.Xr malloc 3 .
+.Pp
+The
+.Fn fopen
+function
+may also fail and set
+.Va errno
+for any of the errors specified for the routine
+.Xr open 2 .
+.Pp
+The
+.Fn fdopen
+function
+may also fail and set
+.Va errno
+for any of the errors specified for the routine
+.Xr fcntl 2 .
+.Pp
+The
+.Fn freopen
+function
+may also fail and set
+.Va errno
+for any of the errors specified for the routines
+.Xr open 2 ,
+.Xr fclose 3
+and
+.Xr fflush 3 .
+.Sh SEE ALSO
+.Xr open 2 ,
+.Xr fclose 3 ,
+.Xr fseek 3 ,
+.Xr funopen 3
+.Sh STANDARDS
+The
+.Fn fopen
+and
+.Fn freopen
+functions
+conform to
+.St -ansiC .
+The
+.Fn fdopen
+function
+conforms to
+.St -p1003.1-88 .
diff --git a/lib/libc/stdio/fopen.c b/lib/libc/stdio/fopen.c
new file mode 100644
index 0000000..9199755
--- /dev/null
+++ b/lib/libc/stdio/fopen.c
@@ -0,0 +1,84 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fopen.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include "local.h"
+
+FILE *
+fopen(file, mode)
+ const char *file;
+ const char *mode;
+{
+ register FILE *fp;
+ register int f;
+ int flags, oflags;
+
+ if ((flags = __sflags(mode, &oflags)) == 0)
+ return (NULL);
+ if ((fp = __sfp()) == NULL)
+ return (NULL);
+ if ((f = open(file, oflags, DEFFILEMODE)) < 0) {
+ fp->_flags = 0; /* release */
+ return (NULL);
+ }
+ fp->_file = f;
+ fp->_flags = flags;
+ fp->_cookie = fp;
+ fp->_read = __sread;
+ fp->_write = __swrite;
+ fp->_seek = __sseek;
+ fp->_close = __sclose;
+
+ /*
+ * When opening in append mode, even though we use O_APPEND,
+ * we need to seek to the end so that ftell() gets the right
+ * answer. If the user then alters the seek pointer, or
+ * the file extends, this will fail, but there is not much
+ * we can do about this. (We could set __SAPP and check in
+ * fseek and ftell.)
+ */
+ if (oflags & O_APPEND)
+ (void) __sseek((void *)fp, (fpos_t)0, SEEK_END);
+ return (fp);
+}
diff --git a/lib/libc/stdio/fprintf.c b/lib/libc/stdio/fprintf.c
new file mode 100644
index 0000000..27094b3
--- /dev/null
+++ b/lib/libc/stdio/fprintf.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fprintf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+#if __STDC__
+fprintf(FILE *fp, const char *fmt, ...)
+#else
+fprintf(fp, fmt, va_alist)
+ FILE *fp;
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ ret = vfprintf(fp, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libc/stdio/fpurge.c b/lib/libc/stdio/fpurge.c
new file mode 100644
index 0000000..acf0b8b
--- /dev/null
+++ b/lib/libc/stdio/fpurge.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fpurge.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+#include "libc_private.h"
+
+/*
+ * fpurge: like fflush, but without writing anything: leave the
+ * given FILE's buffer empty.
+ */
+int
+fpurge(fp)
+ register FILE *fp;
+{
+ int retval;
+ FLOCKFILE(fp);
+ if (!fp->_flags) {
+ errno = EBADF;
+ retval = EOF;
+ } else {
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_p = fp->_bf._base;
+ fp->_r = 0;
+ fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
+ retval = 0;
+ }
+ FUNLOCKFILE(fp);
+ return (retval);
+}
diff --git a/lib/libc/stdio/fputc.c b/lib/libc/stdio/fputc.c
new file mode 100644
index 0000000..60079f1
--- /dev/null
+++ b/lib/libc/stdio/fputc.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fputc.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "libc_private.h"
+
+int
+fputc(c, fp)
+ int c;
+ register FILE *fp;
+{
+ int retval;
+ FLOCKFILE(fp);
+ retval = putc(c, fp);
+ FUNLOCKFILE(fp);
+ return (retval);
+}
diff --git a/lib/libc/stdio/fputs.3 b/lib/libc/stdio/fputs.3
new file mode 100644
index 0000000..75ba73d
--- /dev/null
+++ b/lib/libc/stdio/fputs.3
@@ -0,0 +1,108 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fputs.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt FPUTS 3
+.Os
+.Sh NAME
+.Nm fputs ,
+.Nm puts
+.Nd output a line to a stream
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft int
+.Fn fputs "const char *str" "FILE *stream"
+.Ft int
+.Fn puts "const char *str"
+.Sh DESCRIPTION
+The function
+.Fn fputs
+writes the string pointed to by
+.Fa str
+to the stream pointed to by
+.Fa stream .
+.\" The terminating
+.\" .Dv NUL
+.\" character is not written.
+.Pp
+The function
+.Fn puts
+writes the string
+.Fa str ,
+and a terminating newline character,
+to the stream
+.Em stdout .
+.Sh RETURN VALUES
+The
+.Fn fputs
+function
+returns 0 on success and
+.Dv EOF
+on error;
+.Fn puts
+returns a nonnegative integer on success and
+.Dv EOF
+on error.
+.Sh ERRORS
+.Bl -tag -width [EBADF]
+.It Bq Er EBADF
+The
+.Fa stream
+supplied
+is not a writable stream.
+.El
+.Pp
+The functions
+.Fn fputs
+and
+.Fn puts
+may also fail and set
+.Va errno
+for any of the errors specified for the routines
+.Xr write 2 .
+.Sh SEE ALSO
+.Xr ferror 3 ,
+.Xr putc 3 ,
+.Xr stdio 3
+.Sh STANDARDS
+The functions
+.Fn fputs
+and
+.Fn puts
+conform to
+.St -ansiC .
diff --git a/lib/libc/stdio/fputs.c b/lib/libc/stdio/fputs.c
new file mode 100644
index 0000000..63a5321
--- /dev/null
+++ b/lib/libc/stdio/fputs.c
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fputs.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include "fvwrite.h"
+#include "libc_private.h"
+
+/*
+ * Write the given string to the given file.
+ */
+int
+fputs(s, fp)
+ const char *s;
+ FILE *fp;
+{
+ int retval;
+ struct __suio uio;
+ struct __siov iov;
+
+ iov.iov_base = (void *)s;
+ iov.iov_len = uio.uio_resid = strlen(s);
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ FLOCKFILE(fp);
+ retval = __sfvwrite(fp, &uio);
+ FUNLOCKFILE(fp);
+ return (retval);
+}
diff --git a/lib/libc/stdio/fread.3 b/lib/libc/stdio/fread.3
new file mode 100644
index 0000000..5fc67a2
--- /dev/null
+++ b/lib/libc/stdio/fread.3
@@ -0,0 +1,107 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fread.3 8.2 (Berkeley) 3/8/94
+.\" $FreeBSD$
+.\"
+.Dd March 8, 1994
+.Dt FREAD 3
+.Os
+.Sh NAME
+.Nm fread ,
+.Nm fwrite
+.Nd binary stream input/output
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft size_t
+.Fn fread "void *ptr" "size_t size" "size_t nmemb" "FILE *stream"
+.Ft size_t
+.Fn fwrite "const void *ptr" "size_t size" "size_t nmemb" "FILE *stream"
+.Sh DESCRIPTION
+The function
+.Fn fread
+reads
+.Fa nmemb
+objects, each
+.Fa size
+bytes long, from the stream pointed to by
+.Fa stream ,
+storing them at the location given by
+.Fa ptr .
+.Pp
+The function
+.Fn fwrite
+writes
+.Fa nmemb
+objects, each
+.Fa size
+bytes long, to the stream pointed to by
+.Fa stream ,
+obtaining them from the location given by
+.Fa ptr .
+.Sh RETURN VALUES
+The functions
+.Fn fread
+and
+.Fn fwrite
+advance the file position indicator for the stream
+by the number of bytes read or written.
+They return the number of objects read or written.
+If an error occurs, or the end-of-file is reached,
+the return value is a short object count (or zero).
+.Pp
+The function
+.Fn fread
+does not distinguish between end-of-file and error, and callers
+must use
+.Xr feof 3
+and
+.Xr ferror 3
+to determine which occurred.
+The function
+.Fn fwrite
+returns a value less than
+.Fa nmemb
+only if a write error has occurred.
+.Sh SEE ALSO
+.Xr read 2 ,
+.Xr write 2
+.Sh STANDARDS
+The functions
+.Fn fread
+and
+.Fn fwrite
+conform to
+.St -ansiC .
diff --git a/lib/libc/stdio/fread.c b/lib/libc/stdio/fread.c
new file mode 100644
index 0000000..886a9fc
--- /dev/null
+++ b/lib/libc/stdio/fread.c
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fread.c 8.2 (Berkeley) 12/11/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include "local.h"
+#include "libc_private.h"
+
+size_t
+fread(buf, size, count, fp)
+ void *buf;
+ size_t size, count;
+ register FILE *fp;
+{
+ register size_t resid;
+ register char *p;
+ register int r;
+ size_t total;
+
+ /*
+ * The ANSI standard requires a return value of 0 for a count
+ * or a size of 0. Peculiarily, it imposes no such requirements
+ * on fwrite; it only requires fread to be broken.
+ */
+ if ((resid = count * size) == 0)
+ return (0);
+ FLOCKFILE(fp);
+ if (fp->_r < 0)
+ fp->_r = 0;
+ total = resid;
+ p = buf;
+ while (resid > (r = fp->_r)) {
+ (void)memcpy((void *)p, (void *)fp->_p, (size_t)r);
+ fp->_p += r;
+ /* fp->_r = 0 ... done in __srefill */
+ p += r;
+ resid -= r;
+ if (__srefill(fp)) {
+ /* no more input: return partial result */
+ FUNLOCKFILE(fp);
+ return ((total - resid) / size);
+ }
+ }
+ (void)memcpy((void *)p, (void *)fp->_p, resid);
+ fp->_r -= resid;
+ fp->_p += resid;
+ FUNLOCKFILE(fp);
+ return (count);
+}
diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c
new file mode 100644
index 0000000..9de6724
--- /dev/null
+++ b/lib/libc/stdio/freopen.c
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)freopen.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <libc_private.h>
+#include "local.h"
+
+/*
+ * Re-direct an existing, open (probably) file to some other file.
+ * ANSI is written such that the original file gets closed if at
+ * all possible, no matter what.
+ */
+FILE *
+freopen(file, mode, fp)
+ const char *file, *mode;
+ register FILE *fp;
+{
+ register int f;
+ int flags, isopen, oflags, sverrno, wantfd;
+
+ if ((flags = __sflags(mode, &oflags)) == 0) {
+ (void) fclose(fp);
+ return (NULL);
+ }
+
+ FLOCKFILE(fp);
+
+ if (!__sdidinit)
+ __sinit();
+
+ /*
+ * There are actually programs that depend on being able to "freopen"
+ * descriptors that weren't originally open. Keep this from breaking.
+ * Remember whether the stream was open to begin with, and which file
+ * descriptor (if any) was associated with it. If it was attached to
+ * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin)
+ * should work. This is unnecessary if it was not a Unix file.
+ */
+ if (fp->_flags == 0) {
+ fp->_flags = __SEOF; /* hold on to it */
+ isopen = 0;
+ wantfd = -1;
+ } else {
+ /* flush the stream; ANSI doesn't require this. */
+ if (fp->_flags & __SWR)
+ (void) __sflush(fp);
+ /* if close is NULL, closing is a no-op, hence pointless */
+ isopen = fp->_close != NULL;
+ if ((wantfd = fp->_file) < 0 && isopen) {
+ (void) (*fp->_close)(fp->_cookie);
+ isopen = 0;
+ }
+ }
+
+ /* Get a new descriptor to refer to the new file. */
+ f = open(file, oflags, DEFFILEMODE);
+ if (f < 0 && isopen) {
+ /* If out of fd's close the old one and try again. */
+ if (errno == ENFILE || errno == EMFILE) {
+ (void) (*fp->_close)(fp->_cookie);
+ isopen = 0;
+ f = open(file, oflags, DEFFILEMODE);
+ }
+ }
+ sverrno = errno;
+
+ /*
+ * Finish closing fp. Even if the open succeeded above, we cannot
+ * keep fp->_base: it may be the wrong size. This loses the effect
+ * of any setbuffer calls, but stdio has always done this before.
+ */
+ if (isopen)
+ (void) (*fp->_close)(fp->_cookie);
+ if (fp->_flags & __SMBF)
+ free((char *)fp->_bf._base);
+ fp->_w = 0;
+ fp->_r = 0;
+ fp->_p = NULL;
+ fp->_bf._base = NULL;
+ fp->_bf._size = 0;
+ fp->_lbfsize = 0;
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_ub._size = 0;
+ if (HASLB(fp))
+ FREELB(fp);
+ fp->_lb._size = 0;
+
+ if (f < 0) { /* did not get it after all */
+ fp->_flags = 0; /* set it free */
+ errno = sverrno; /* restore in case _close clobbered */
+ FUNLOCKFILE(fp);
+ return (NULL);
+ }
+
+ /*
+ * If reopening something that was open before on a real file, try
+ * to maintain the descriptor. Various C library routines (perror)
+ * assume stderr is always fd STDERR_FILENO, even if being freopen'd.
+ */
+ if (wantfd >= 0 && f != wantfd) {
+ if (dup2(f, wantfd) >= 0) {
+ (void) close(f);
+ f = wantfd;
+ }
+ }
+
+ fp->_flags = flags;
+ fp->_file = f;
+ fp->_cookie = fp;
+ fp->_read = __sread;
+ fp->_write = __swrite;
+ fp->_seek = __sseek;
+ fp->_close = __sclose;
+ FUNLOCKFILE(fp);
+ return (fp);
+}
diff --git a/lib/libc/stdio/fscanf.c b/lib/libc/stdio/fscanf.c
new file mode 100644
index 0000000..8b7b941
--- /dev/null
+++ b/lib/libc/stdio/fscanf.c
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fscanf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include "libc_private.h"
+
+#if __STDC__
+int
+fscanf(FILE *fp, char const *fmt, ...) {
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+#else
+int
+fscanf(fp, fmt, va_alist)
+ FILE *fp;
+ char *fmt;
+ va_dcl
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap);
+#endif
+ FLOCKFILE(fp);
+ ret = __svfscanf(fp, fmt, ap);
+ va_end(ap);
+ FUNLOCKFILE(fp);
+ return (ret);
+}
diff --git a/lib/libc/stdio/fseek.3 b/lib/libc/stdio/fseek.3
new file mode 100644
index 0000000..fd6ff9f
--- /dev/null
+++ b/lib/libc/stdio/fseek.3
@@ -0,0 +1,230 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fseek.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd Mar 5, 1999
+.Dt FSEEK 3
+.Os
+.Sh NAME
+.Nm fgetpos ,
+.Nm fseek ,
+.Nm fseeko ,
+.Nm fsetpos ,
+.Nm ftell ,
+.Nm ftello ,
+.Nm rewind
+.Nd reposition a stream
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft int
+.Fn fseek "FILE *stream" "long offset" "int whence"
+.Ft long
+.Fn ftell "FILE *stream"
+.Ft void
+.Fn rewind "FILE *stream"
+.Ft int
+.Fn fgetpos "FILE *stream" "fpos_t *pos"
+.Ft int
+.Fn fsetpos "FILE *stream" "const fpos_t *pos"
+.Fd #include <sys/types.h>
+.Ft int
+.Fn fseeko "FILE *stream" "off_t offset" "int whence"
+.Ft off_t
+.Fn ftello "FILE *stream"
+.Sh DESCRIPTION
+The
+.Fn fseek
+function sets the file position indicator for the stream pointed
+to by
+.Fa stream .
+The new position, measured in bytes, is obtained by adding
+.Fa offset
+bytes to the position specified by
+.Fa whence .
+If
+.Fa whence
+is set to
+.Dv SEEK_SET ,
+.Dv SEEK_CUR ,
+or
+.Dv SEEK_END ,
+the offset is relative to the
+start of the file, the current position indicator, or end-of-file,
+respectively.
+A successful call to the
+.Fn fseek
+function clears the end-of-file indicator for the stream and undoes
+any effects of the
+.Xr ungetc 3
+function on the same stream.
+.Pp
+The
+.Fn ftell
+function
+obtains the current value of the file position indicator for the
+stream pointed to by
+.Fa stream .
+.Pp
+The
+.Fn rewind
+function sets the file position indicator for the stream pointed
+to by
+.Fa stream
+to the beginning of the file.
+It is equivalent to:
+.Pp
+.Dl (void)fseek(stream, 0L, SEEK_SET)
+.Pp
+except that the error indicator for the stream is also cleared
+(see
+.Xr clearerr 3 ) .
+.Pp
+The
+.Fn fseeko
+function is identical to
+.Fn fseek ,
+except it takes an
+.Fa off_t
+argument
+instead of a
+.Fa long .
+Likewise, the
+.Fn ftello
+function is identical to
+.Fn ftell ,
+except it returns an
+.Fa off_t .
+.Pp
+The
+.Fn fgetpos
+and
+.Fn fsetpos
+functions
+are alternate interfaces equivalent to
+.Fn ftell
+and
+.Fn fseek
+(with whence set to
+.Dv SEEK_SET ) ,
+setting and storing the current value of
+the file offset into or from the object referenced by
+.Fa pos .
+On some
+.Pq non- Ns Tn UNIX
+systems an
+.Dq Fa fpos_t
+object may be a complex object
+and these routines may be the only way to portably reposition a text stream.
+.Sh RETURN VALUES
+The
+.Fn rewind
+function
+returns no value.
+Upon successful completion,
+.Fn fgetpos ,
+.Fn fseek ,
+.Fn fseeko ,
+and
+.Fn fsetpos
+return 0,
+and
+.Fn ftell
+and
+.Fn ftello
+return the current offset.
+Otherwise, \-1 is returned and the global variable errno is set to
+indicate the error.
+.Sh ERRORS
+.Bl -tag -width [EINVAL]
+.It Bq Er EBADF
+The
+.Fa stream
+specified
+is not a seekable stream.
+.It Bq Er EINVAL
+The
+.Fa whence
+argument to
+.Fn fseek
+was not
+.Dv SEEK_SET ,
+.Dv SEEK_END ,
+or
+.Dv SEEK_CUR .
+.It Bq Er EOVERFLOW
+For
+.Fn ftell ,
+the resulting file offset would be a value which
+cannot be represented correctly in an object of type long.
+.El
+.Pp
+The functions
+.Fn fgetpos ,
+.Fn fseek ,
+.Fn fseeko ,
+.Fn fsetpos ,
+.Fn ftell ,
+and
+.Fn ftello
+may also fail and set
+.Va errno
+for any of the errors specified for the routines
+.Xr fflush 3 ,
+.Xr fstat 2 ,
+.Xr lseek 2 ,
+and
+.Xr malloc 3 .
+.Sh SEE ALSO
+.Xr lseek 2
+.Sh STANDARDS
+The
+.Fn fgetpos ,
+.Fn fsetpos ,
+.Fn fseek ,
+.Fn ftell ,
+and
+.Fn rewind
+functions
+conform to
+.St -ansiC .
+.Pp
+The
+.Fn fseeko
+and
+.Fn ftello
+functions conform to
+.St -susv2 .
diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c
new file mode 100644
index 0000000..8c2732e
--- /dev/null
+++ b/lib/libc/stdio/fseek.c
@@ -0,0 +1,269 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fseek.c 8.3 (Berkeley) 1/2/94";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "local.h"
+#include "libc_private.h"
+
+#define POS_ERR (-(fpos_t)1)
+
+int
+fseek(fp, offset, whence)
+ register FILE *fp;
+ long offset;
+ int whence;
+{
+ return (fseeko(fp, offset, whence));
+}
+
+/*
+ * Seek the given file to the given offset.
+ * `Whence' must be one of the three SEEK_* macros.
+ */
+int
+fseeko(fp, offset, whence)
+ register FILE *fp;
+ off_t offset;
+ int whence;
+{
+ register fpos_t (*seekfn) __P((void *, fpos_t, int));
+ fpos_t target, curoff;
+ size_t n;
+ struct stat st;
+ int havepos;
+
+ /* make sure stdio is set up */
+ if (!__sdidinit)
+ __sinit();
+
+ FLOCKFILE(fp);
+ /*
+ * Have to be able to seek.
+ */
+ if ((seekfn = fp->_seek) == NULL) {
+ errno = ESPIPE; /* historic practice */
+ FUNLOCKFILE(fp);
+ return (EOF);
+ }
+
+ /*
+ * Change any SEEK_CUR to SEEK_SET, and check `whence' argument.
+ * After this, whence is either SEEK_SET or SEEK_END.
+ */
+ switch (whence) {
+
+ case SEEK_CUR:
+ /*
+ * In order to seek relative to the current stream offset,
+ * we have to first find the current stream offset a la
+ * ftell (see ftell for details).
+ */
+ if (fp->_flags & __SOFF)
+ curoff = fp->_offset;
+ else {
+ curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR);
+ if (curoff == -1) {
+ FUNLOCKFILE(fp);
+ return (EOF);
+ }
+ }
+ if (fp->_flags & __SRD) {
+ curoff -= fp->_r;
+ if (HASUB(fp))
+ curoff -= fp->_ur;
+ } else if (fp->_flags & __SWR && fp->_p != NULL)
+ curoff += fp->_p - fp->_bf._base;
+
+ offset += curoff;
+ whence = SEEK_SET;
+ havepos = 1;
+ break;
+
+ case SEEK_SET:
+ case SEEK_END:
+ curoff = 0; /* XXX just to keep gcc quiet */
+ havepos = 0;
+ break;
+
+ default:
+ errno = EINVAL;
+ FUNLOCKFILE(fp);
+ return (EOF);
+ }
+
+ /*
+ * Can only optimise if:
+ * reading (and not reading-and-writing);
+ * not unbuffered; and
+ * this is a `regular' Unix file (and hence seekfn==__sseek).
+ * We must check __NBF first, because it is possible to have __NBF
+ * and __SOPT both set.
+ */
+ if (fp->_bf._base == NULL)
+ __smakebuf(fp);
+ if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT))
+ goto dumb;
+ if ((fp->_flags & __SOPT) == 0) {
+ if (seekfn != __sseek ||
+ fp->_file < 0 || fstat(fp->_file, &st) ||
+ (st.st_mode & S_IFMT) != S_IFREG) {
+ fp->_flags |= __SNPT;
+ goto dumb;
+ }
+ fp->_blksize = st.st_blksize;
+ fp->_flags |= __SOPT;
+ }
+
+ /*
+ * We are reading; we can try to optimise.
+ * Figure out where we are going and where we are now.
+ */
+ if (whence == SEEK_SET)
+ target = offset;
+ else {
+ if (fstat(fp->_file, &st))
+ goto dumb;
+ target = st.st_size + offset;
+ }
+
+ if (!havepos) {
+ if (fp->_flags & __SOFF)
+ curoff = fp->_offset;
+ else {
+ curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR);
+ if (curoff == POS_ERR)
+ goto dumb;
+ }
+ curoff -= fp->_r;
+ if (HASUB(fp))
+ curoff -= fp->_ur;
+ }
+
+ /*
+ * Compute the number of bytes in the input buffer (pretending
+ * that any ungetc() input has been discarded). Adjust current
+ * offset backwards by this count so that it represents the
+ * file offset for the first byte in the current input buffer.
+ */
+ if (HASUB(fp)) {
+ curoff += fp->_r; /* kill off ungetc */
+ n = fp->_up - fp->_bf._base;
+ curoff -= n;
+ n += fp->_ur;
+ } else {
+ n = fp->_p - fp->_bf._base;
+ curoff -= n;
+ n += fp->_r;
+ }
+
+ /*
+ * If the target offset is within the current buffer,
+ * simply adjust the pointers, clear EOF, undo ungetc(),
+ * and return. (If the buffer was modified, we have to
+ * skip this; see fgetln.c.)
+ */
+ if ((fp->_flags & __SMOD) == 0 &&
+ target >= curoff && target < curoff + n) {
+ register int o = target - curoff;
+
+ fp->_p = fp->_bf._base + o;
+ fp->_r = n - o;
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_flags &= ~__SEOF;
+ FUNLOCKFILE(fp);
+ return (0);
+ }
+
+ /*
+ * The place we want to get to is not within the current buffer,
+ * but we can still be kind to the kernel copyout mechanism.
+ * By aligning the file offset to a block boundary, we can let
+ * the kernel use the VM hardware to map pages instead of
+ * copying bytes laboriously. Using a block boundary also
+ * ensures that we only read one block, rather than two.
+ */
+ curoff = target & ~(fp->_blksize - 1);
+ if ((*seekfn)(fp->_cookie, curoff, SEEK_SET) == POS_ERR)
+ goto dumb;
+ fp->_r = 0;
+ fp->_p = fp->_bf._base;
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_flags &= ~__SEOF;
+ n = target - curoff;
+ if (n) {
+ if (__srefill(fp) || fp->_r < n)
+ goto dumb;
+ fp->_p += n;
+ fp->_r -= n;
+ }
+ FUNLOCKFILE(fp);
+ return (0);
+
+ /*
+ * We get here if we cannot optimise the seek ... just
+ * do it. Allow the seek function to change fp->_bf._base.
+ */
+dumb:
+ if (__sflush(fp) ||
+ (*seekfn)(fp->_cookie, (fpos_t)offset, whence) == POS_ERR) {
+ FUNLOCKFILE(fp);
+ return (EOF);
+ }
+ /* success: clear EOF indicator and discard ungetc() data */
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_p = fp->_bf._base;
+ fp->_r = 0;
+ /* fp->_w = 0; */ /* unnecessary (I think...) */
+ fp->_flags &= ~__SEOF;
+ FUNLOCKFILE(fp);
+ return (0);
+}
diff --git a/lib/libc/stdio/fsetpos.c b/lib/libc/stdio/fsetpos.c
new file mode 100644
index 0000000..60ab719
--- /dev/null
+++ b/lib/libc/stdio/fsetpos.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fsetpos.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <stdio.h>
+
+/*
+ * fsetpos: like fseek.
+ */
+int
+fsetpos(iop, pos)
+ FILE *iop;
+ const fpos_t *pos;
+{
+ return (fseeko(iop, (off_t)*pos, SEEK_SET));
+}
diff --git a/lib/libc/stdio/ftell.c b/lib/libc/stdio/ftell.c
new file mode 100644
index 0000000..9057f89
--- /dev/null
+++ b/lib/libc/stdio/ftell.c
@@ -0,0 +1,114 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)ftell.c 8.2 (Berkeley) 5/4/95";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <errno.h>
+#include "local.h"
+#include "libc_private.h"
+
+/*
+ * standard ftell function.
+ */
+long
+ftell(fp)
+ register FILE *fp;
+{
+ register off_t rv;
+ rv = ftello(fp);
+ if ((long)rv != rv) {
+ errno = EOVERFLOW;
+ return (-1);
+ }
+ return (rv);
+}
+
+/*
+ * ftello: return current offset.
+ */
+off_t
+ftello(fp)
+ register FILE *fp;
+{
+ register fpos_t pos;
+
+ if (fp->_seek == NULL) {
+ errno = ESPIPE; /* historic practice */
+ return (-1L);
+ }
+
+ FLOCKFILE(fp);
+ /*
+ * Find offset of underlying I/O object, then
+ * adjust for buffered bytes.
+ */
+ if (fp->_flags & __SOFF)
+ pos = fp->_offset;
+ else {
+ pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR);
+ if (pos == -1) {
+ FUNLOCKFILE(fp);
+ return (pos);
+ }
+ }
+ if (fp->_flags & __SRD) {
+ /*
+ * Reading. Any unread characters (including
+ * those from ungetc) cause the position to be
+ * smaller than that in the underlying object.
+ */
+ pos -= fp->_r;
+ if (HASUB(fp))
+ pos -= fp->_ur;
+ } else if (fp->_flags & __SWR && fp->_p != NULL) {
+ /*
+ * Writing. Any buffered characters cause the
+ * position to be greater than that in the
+ * underlying object.
+ */
+ pos += fp->_p - fp->_bf._base;
+ }
+ FUNLOCKFILE(fp);
+ return (pos);
+}
diff --git a/lib/libc/stdio/funopen.3 b/lib/libc/stdio/funopen.3
new file mode 100644
index 0000000..b3cf808
--- /dev/null
+++ b/lib/libc/stdio/funopen.3
@@ -0,0 +1,170 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)funopen.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt FUNOPEN 3
+.Os
+.Sh NAME
+.Nm funopen ,
+.Nm fropen ,
+.Nm fwopen
+.Nd open a stream
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft FILE *
+.Fn funopen "const void *cookie" "int (*readfn)(void *, char *, int)" "int (*writefn)(void *, const char *, int)" "fpos_t (*seekfn)(void *, fpos_t, int)" "int (*closefn)(void *)"
+.Ft FILE *
+.Fn fropen "void *cookie" "int (*readfn)(void *, char *, int)"
+.Ft FILE *
+.Fn fwopen "void *cookie" "int (*writefn)(void *, const char *, int)"
+.Sh DESCRIPTION
+The
+.Fn funopen
+function
+associates a stream with up to four
+.Dq Tn I/O No functions .
+Either
+.Fa readfn
+or
+.Fa writefn
+must be specified;
+the others can be given as an appropriately-typed
+.Dv NULL
+pointer.
+These
+.Tn I/O
+functions will be used to read, write, seek and
+close the new stream.
+.Pp
+In general, omitting a function means that any attempt to perform the
+associated operation on the resulting stream will fail.
+If the close function is omitted, closing the stream will flush
+any buffered output and then succeed.
+.Pp
+The calling conventions of
+.Fa readfn ,
+.Fa writefn ,
+.Fa seekfn
+and
+.Fa closefn
+must match those, respectively, of
+.Xr read 2 ,
+.Xr write 2 ,
+.Xr seek 2 ,
+and
+.Xr close 2
+with the single exception that they are passed the
+.Fa cookie
+argument specified to
+.Fn funopen
+in place of the traditional file descriptor argument.
+.Pp
+Read and write
+.Tn I/O
+functions are allowed to change the underlying buffer
+on fully buffered or line buffered streams by calling
+.Xr setvbuf 3 .
+They are also not required to completely fill or empty the buffer.
+They are not, however, allowed to change streams from unbuffered to buffered
+or to change the state of the line buffering flag.
+They must also be prepared to have read or write calls occur on buffers other
+than the one most recently specified.
+.Pp
+All user
+.Tn I/O
+functions can report an error by returning \-1.
+Additionally, all of the functions should set the external variable
+.Va errno
+appropriately if an error occurs.
+.Pp
+An error on
+.Fn closefn
+does not keep the stream open.
+.Pp
+As a convenience, the include file
+.Aq Pa stdio.h
+defines the macros
+.Fn fropen
+and
+.Fn fwopen
+as calls to
+.Fn funopen
+with only a read or write function specified.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn funopen
+returns a
+.Dv FILE
+pointer.
+Otherwise,
+.Dv NULL
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Bl -tag -width [EINVAL]
+.It Bq Er EINVAL
+The
+.Fn funopen
+function
+was called without either a read or write function.
+The
+.Fn funopen
+function
+may also fail and set
+.Va errno
+for any of the errors
+specified for the routine
+.Xr malloc 3 .
+.El
+.Sh SEE ALSO
+.Xr fcntl 2 ,
+.Xr open 2 ,
+.Xr fclose 3 ,
+.Xr fopen 3 ,
+.Xr fseek 3 ,
+.Xr setbuf 3
+.Sh HISTORY
+The
+.Fn funopen
+functions first appeared in
+.Bx 4.4 .
+.Sh BUGS
+The
+.Fn funopen
+function
+may not be portable to systems other than
+.Bx .
diff --git a/lib/libc/stdio/funopen.c b/lib/libc/stdio/funopen.c
new file mode 100644
index 0000000..4d65b68
--- /dev/null
+++ b/lib/libc/stdio/funopen.c
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)funopen.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <errno.h>
+#include "local.h"
+
+FILE *
+funopen(cookie, readfn, writefn, seekfn, closefn)
+ const void *cookie;
+ int (*readfn)(), (*writefn)();
+#if __STDC__
+ fpos_t (*seekfn)(void *cookie, fpos_t off, int whence);
+#else
+ fpos_t (*seekfn)();
+#endif
+ int (*closefn)();
+{
+ register FILE *fp;
+ int flags;
+
+ if (readfn == NULL) {
+ if (writefn == NULL) { /* illegal */
+ errno = EINVAL;
+ return (NULL);
+ } else
+ flags = __SWR; /* write only */
+ } else {
+ if (writefn == NULL)
+ flags = __SRD; /* read only */
+ else
+ flags = __SRW; /* read-write */
+ }
+ if ((fp = __sfp()) == NULL)
+ return (NULL);
+ fp->_flags = flags;
+ fp->_file = -1;
+ fp->_cookie = (void *)cookie;
+ fp->_read = readfn;
+ fp->_write = writefn;
+ fp->_seek = seekfn;
+ fp->_close = closefn;
+ return (fp);
+}
diff --git a/lib/libc/stdio/fvwrite.c b/lib/libc/stdio/fvwrite.c
new file mode 100644
index 0000000..75d7191
--- /dev/null
+++ b/lib/libc/stdio/fvwrite.c
@@ -0,0 +1,213 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fvwrite.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "local.h"
+#include "fvwrite.h"
+
+/*
+ * Write some memory regions. Return zero on success, EOF on error.
+ *
+ * This routine is large and unsightly, but most of the ugliness due
+ * to the three different kinds of output buffering is handled here.
+ */
+int
+__sfvwrite(fp, uio)
+ register FILE *fp;
+ register struct __suio *uio;
+{
+ register size_t len;
+ register char *p;
+ register struct __siov *iov;
+ register int w, s;
+ char *nl;
+ int nlknown, nldist;
+
+ if ((len = uio->uio_resid) == 0)
+ return (0);
+ /* make sure we can write */
+ if (cantwrite(fp))
+ return (EOF);
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n))
+
+ iov = uio->uio_iov;
+ p = iov->iov_base;
+ len = iov->iov_len;
+ iov++;
+#define GETIOV(extra_work) \
+ while (len == 0) { \
+ extra_work; \
+ p = iov->iov_base; \
+ len = iov->iov_len; \
+ iov++; \
+ }
+ if (fp->_flags & __SNBF) {
+ /*
+ * Unbuffered: write up to BUFSIZ bytes at a time.
+ */
+ do {
+ GETIOV(;);
+ w = (*fp->_write)(fp->_cookie, p, MIN(len, BUFSIZ));
+ if (w <= 0)
+ goto err;
+ p += w;
+ len -= w;
+ } while ((uio->uio_resid -= w) != 0);
+ } else if ((fp->_flags & __SLBF) == 0) {
+ /*
+ * Fully buffered: fill partially full buffer, if any,
+ * and then flush. If there is no partial buffer, write
+ * one _bf._size byte chunk directly (without copying).
+ *
+ * String output is a special case: write as many bytes
+ * as fit, but pretend we wrote everything. This makes
+ * snprintf() return the number of bytes needed, rather
+ * than the number used, and avoids its write function
+ * (so that the write function can be invalid).
+ */
+ do {
+ GETIOV(;);
+ if ((fp->_flags & (__SALC | __SSTR)) ==
+ (__SALC | __SSTR) && fp->_w < len) {
+ size_t blen = fp->_p - fp->_bf._base;
+
+ /*
+ * Alloc an extra 128 bytes (+ 1 for NULL)
+ * so we don't call realloc(3) so often.
+ */
+ fp->_w = len + 128;
+ fp->_bf._size = blen + len + 128;
+ fp->_bf._base =
+ reallocf(fp->_bf._base, fp->_bf._size + 1);
+ if (fp->_bf._base == NULL)
+ goto err;
+ fp->_p = fp->_bf._base + blen;
+ }
+ w = fp->_w;
+ if (fp->_flags & __SSTR) {
+ if (len < w)
+ w = len;
+ if (w > 0) {
+ COPY(w); /* copy MIN(fp->_w,len), */
+ fp->_w -= w;
+ fp->_p += w;
+ }
+ w = len; /* but pretend copied all */
+ } else if (fp->_p > fp->_bf._base && len > w) {
+ /* fill and flush */
+ COPY(w);
+ /* fp->_w -= w; */ /* unneeded */
+ fp->_p += w;
+ if (fflush(fp))
+ goto err;
+ } else if (len >= (w = fp->_bf._size)) {
+ /* write directly */
+ w = (*fp->_write)(fp->_cookie, p, w);
+ if (w <= 0)
+ goto err;
+ } else {
+ /* fill and done */
+ w = len;
+ COPY(w);
+ fp->_w -= w;
+ fp->_p += w;
+ }
+ p += w;
+ len -= w;
+ } while ((uio->uio_resid -= w) != 0);
+ } else {
+ /*
+ * Line buffered: like fully buffered, but we
+ * must check for newlines. Compute the distance
+ * to the first newline (including the newline),
+ * or `infinity' if there is none, then pretend
+ * that the amount to write is MIN(len,nldist).
+ */
+ nlknown = 0;
+ nldist = 0; /* XXX just to keep gcc happy */
+ do {
+ GETIOV(nlknown = 0);
+ if (!nlknown) {
+ nl = memchr((void *)p, '\n', len);
+ nldist = nl ? nl + 1 - p : len + 1;
+ nlknown = 1;
+ }
+ s = MIN(len, nldist);
+ w = fp->_w + fp->_bf._size;
+ if (fp->_p > fp->_bf._base && s > w) {
+ COPY(w);
+ /* fp->_w -= w; */
+ fp->_p += w;
+ if (fflush(fp))
+ goto err;
+ } else if (s >= (w = fp->_bf._size)) {
+ w = (*fp->_write)(fp->_cookie, p, w);
+ if (w <= 0)
+ goto err;
+ } else {
+ w = s;
+ COPY(w);
+ fp->_w -= w;
+ fp->_p += w;
+ }
+ if ((nldist -= w) == 0) {
+ /* copied the newline: flush and forget */
+ if (fflush(fp))
+ goto err;
+ nlknown = 0;
+ }
+ p += w;
+ len -= w;
+ } while ((uio->uio_resid -= w) != 0);
+ }
+ return (0);
+
+err:
+ fp->_flags |= __SERR;
+ return (EOF);
+}
diff --git a/lib/libc/stdio/fvwrite.h b/lib/libc/stdio/fvwrite.h
new file mode 100644
index 0000000..ec6bc0b
--- /dev/null
+++ b/lib/libc/stdio/fvwrite.h
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)fvwrite.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * I/O descriptors for __sfvwrite().
+ */
+struct __siov {
+ void *iov_base;
+ size_t iov_len;
+};
+struct __suio {
+ struct __siov *uio_iov;
+ int uio_iovcnt;
+ int uio_resid;
+};
+
+#if __STDC__ || c_plusplus
+extern int __sfvwrite(FILE *, struct __suio *);
+#else
+extern int __sfvwrite();
+#endif
diff --git a/lib/libc/stdio/fwalk.c b/lib/libc/stdio/fwalk.c
new file mode 100644
index 0000000..b1a25d1
--- /dev/null
+++ b/lib/libc/stdio/fwalk.c
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fwalk.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+#include "local.h"
+#include "glue.h"
+
+int
+_fwalk(function)
+ register int (*function)(FILE *);
+{
+ register FILE *fp;
+ register int n, ret;
+ register struct glue *g;
+
+ ret = 0;
+ for (g = &__sglue; g != NULL; g = g->next)
+ for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
+ if (fp->_flags != 0)
+ ret |= (*function)(fp);
+ return (ret);
+}
diff --git a/lib/libc/stdio/fwrite.c b/lib/libc/stdio/fwrite.c
new file mode 100644
index 0000000..681b9d3
--- /dev/null
+++ b/lib/libc/stdio/fwrite.c
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)fwrite.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "local.h"
+#include "fvwrite.h"
+#include "libc_private.h"
+
+/*
+ * Write `count' objects (each size `size') from memory to the given file.
+ * Return the number of whole objects written.
+ */
+size_t
+fwrite(buf, size, count, fp)
+ const void *buf;
+ size_t size, count;
+ FILE *fp;
+{
+ size_t n;
+ struct __suio uio;
+ struct __siov iov;
+
+ iov.iov_base = (void *)buf;
+ uio.uio_resid = iov.iov_len = n = count * size;
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+
+ FLOCKFILE(fp);
+ /*
+ * The usual case is success (__sfvwrite returns 0);
+ * skip the divide if this happens, since divides are
+ * generally slow and since this occurs whenever size==0.
+ */
+ if (__sfvwrite(fp, &uio) != 0)
+ count = (n - uio.uio_resid) / size;
+ FUNLOCKFILE(fp);
+ return (count);
+}
diff --git a/lib/libc/stdio/getc.3 b/lib/libc/stdio/getc.3
new file mode 100644
index 0000000..b0fde0d
--- /dev/null
+++ b/lib/libc/stdio/getc.3
@@ -0,0 +1,137 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getc.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETC 3
+.Os
+.Sh NAME
+.Nm fgetc ,
+.Nm getc ,
+.Nm getchar ,
+.Nm getw
+.Nd get next character or word from input stream
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft int
+.Fn fgetc "FILE *stream"
+.Ft int
+.Fn getc "FILE *stream"
+.Ft int
+.Fn getchar
+.Ft int
+.Fn getw "FILE *stream"
+.Sh DESCRIPTION
+The
+.Fn fgetc
+function
+obtains the next input character (if present) from the stream pointed at by
+.Fa stream ,
+or the next character pushed back on the stream via
+.Xr ungetc 3 .
+.Pp
+The
+.Fn getc
+function
+acts essentially identically to
+.Fn fgetc ,
+but is a macro that expands in-line.
+.Pp
+The
+.Fn getchar
+function
+is equivalent to:
+getc with the argument stdin.
+.Pp
+The
+.Fn getw
+function
+obtains the next
+.Em int
+(if present)
+from the stream pointed at by
+.Fa stream .
+.Sh RETURN VALUES
+If successful, these routines return the next requested object
+from the
+.Fa stream .
+If the stream is at end-of-file or a read error occurs,
+the routines return
+.Dv EOF .
+The routines
+.Xr feof 3
+and
+.Xr ferror 3
+must be used to distinguish between end-of-file and error.
+If an error occurs, the global variable
+.Va errno
+is set to indicate the error.
+The end-of-file condition is remembered, even on a terminal, and all
+subsequent attempts to read will return
+.Dv EOF
+until the condition is cleared with
+.Xr clearerr 3 .
+.Sh SEE ALSO
+.Xr ferror 3 ,
+.Xr fopen 3 ,
+.Xr fread 3 ,
+.Xr putc 3 ,
+.Xr ungetc 3
+.Sh STANDARDS
+The
+.Fn fgetc ,
+.Fn getc
+and
+.Fn getchar
+functions
+conform to
+.St -ansiC .
+.Sh BUGS
+Since
+.Dv EOF
+is a valid integer value,
+.Xr feof 3
+and
+.Xr ferror 3
+must be used to check for failure after calling
+.Fn getw .
+The size and byte order of an
+.Em int
+varies from one machine to another, and
+.Fn getw
+is not recommended for portable applications.
+.Pp
diff --git a/lib/libc/stdio/getc.c b/lib/libc/stdio/getc.c
new file mode 100644
index 0000000..eff320a
--- /dev/null
+++ b/lib/libc/stdio/getc.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)getc.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "libc_private.h"
+
+/*
+ * A subroutine version of the macro getc.
+ */
+#undef getc
+
+int
+getc(fp)
+ register FILE *fp;
+{
+ int retval;
+ FLOCKFILE(fp);
+ retval = __sgetc(fp);
+ FUNLOCKFILE(fp);
+ return (retval);
+}
diff --git a/lib/libc/stdio/getchar.c b/lib/libc/stdio/getchar.c
new file mode 100644
index 0000000..ec8810d
--- /dev/null
+++ b/lib/libc/stdio/getchar.c
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)getchar.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * A subroutine version of the macro getchar.
+ */
+#include <stdio.h>
+#include "libc_private.h"
+
+#undef getchar
+
+int
+getchar()
+{
+ int retval;
+ FLOCKFILE(stdin);
+ retval = getc(stdin);
+ FUNLOCKFILE(stdin);
+ return (retval);
+}
diff --git a/lib/libc/stdio/gets.c b/lib/libc/stdio/gets.c
new file mode 100644
index 0000000..da90fe2
--- /dev/null
+++ b/lib/libc/stdio/gets.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)gets.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/cdefs.h>
+
+__warn_references(gets, "warning: this program uses gets(), which is unsafe.");
+
+char *
+gets(buf)
+ char *buf;
+{
+ register int c;
+ register char *s;
+ static int warned;
+ static char w[] =
+ "warning: this program uses gets(), which is unsafe.\n";
+
+ if (!warned) {
+ (void) write(STDERR_FILENO, w, sizeof(w) - 1);
+ warned = 1;
+ }
+ for (s = buf; (c = getchar()) != '\n';)
+ if (c == EOF)
+ if (s == buf)
+ return (NULL);
+ else
+ break;
+ else
+ *s++ = c;
+ *s = 0;
+ return (buf);
+}
diff --git a/lib/libc/stdio/getw.c b/lib/libc/stdio/getw.c
new file mode 100644
index 0000000..5ebb46b
--- /dev/null
+++ b/lib/libc/stdio/getw.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)getw.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+int
+getw(fp)
+ FILE *fp;
+{
+ int x;
+
+ return (fread((void *)&x, sizeof(x), 1, fp) == 1 ? x : EOF);
+}
diff --git a/lib/libc/stdio/glue.h b/lib/libc/stdio/glue.h
new file mode 100644
index 0000000..5dcdaff
--- /dev/null
+++ b/lib/libc/stdio/glue.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)glue.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * The first few FILEs are statically allocated; others are dynamically
+ * allocated and linked in via this glue structure.
+ */
+struct glue {
+ struct glue *next;
+ int niobs;
+ FILE *iobs;
+} __sglue;
diff --git a/lib/libc/stdio/local.h b/lib/libc/stdio/local.h
new file mode 100644
index 0000000..cbc07a9
--- /dev/null
+++ b/lib/libc/stdio/local.h
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)local.h 8.3 (Berkeley) 7/3/94
+ */
+
+/*
+ * Information local to this implementation of stdio,
+ * in particular, macros and private variables.
+ */
+
+extern int __sflush __P((FILE *));
+extern FILE *__sfp __P((void));
+extern int __srefill __P((FILE *));
+extern int __sread __P((void *, char *, int));
+extern int __swrite __P((void *, char const *, int));
+extern fpos_t __sseek __P((void *, fpos_t, int));
+extern int __sclose __P((void *));
+extern void __sinit __P((void));
+extern void _cleanup __P((void));
+extern void (*__cleanup) __P((void));
+extern void __smakebuf __P((FILE *));
+extern int __swhatbuf __P((FILE *, size_t *, int *));
+extern int _fwalk __P((int (*)(FILE *)));
+extern int __swsetup __P((FILE *));
+extern int __sflags __P((const char *, int *));
+
+extern int __sdidinit;
+
+/*
+ * Return true iff the given FILE cannot be written now.
+ */
+#define cantwrite(fp) \
+ ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \
+ __swsetup(fp))
+
+/*
+ * Test whether the given stdio file has an active ungetc buffer;
+ * release such a buffer, without restoring ordinary unread data.
+ */
+#define HASUB(fp) ((fp)->_ub._base != NULL)
+#define FREEUB(fp) { \
+ if ((fp)->_ub._base != (fp)->_ubuf) \
+ free((char *)(fp)->_ub._base); \
+ (fp)->_ub._base = NULL; \
+}
+
+/*
+ * test for an fgetln() buffer.
+ */
+#define HASLB(fp) ((fp)->_lb._base != NULL)
+#define FREELB(fp) { \
+ free((char *)(fp)->_lb._base); \
+ (fp)->_lb._base = NULL; \
+}
diff --git a/lib/libc/stdio/makebuf.c b/lib/libc/stdio/makebuf.c
new file mode 100644
index 0000000..7dcbd70
--- /dev/null
+++ b/lib/libc/stdio/makebuf.c
@@ -0,0 +1,118 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)makebuf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+/*
+ * Allocate a file buffer, or switch to unbuffered I/O.
+ * Per the ANSI C standard, ALL tty devices default to line buffered.
+ *
+ * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek
+ * optimisation) right after the fstat() that finds the buffer size.
+ */
+void
+__smakebuf(fp)
+ register FILE *fp;
+{
+ register void *p;
+ register int flags;
+ size_t size;
+ int couldbetty;
+
+ if (fp->_flags & __SNBF) {
+ fp->_bf._base = fp->_p = fp->_nbuf;
+ fp->_bf._size = 1;
+ return;
+ }
+ flags = __swhatbuf(fp, &size, &couldbetty);
+ if ((p = malloc(size)) == NULL) {
+ fp->_flags |= __SNBF;
+ fp->_bf._base = fp->_p = fp->_nbuf;
+ fp->_bf._size = 1;
+ return;
+ }
+ __cleanup = _cleanup;
+ flags |= __SMBF;
+ fp->_bf._base = fp->_p = p;
+ fp->_bf._size = size;
+ if (couldbetty && isatty(fp->_file))
+ flags |= __SLBF;
+ fp->_flags |= flags;
+}
+
+/*
+ * Internal routine to determine `proper' buffering for a file.
+ */
+int
+__swhatbuf(fp, bufsize, couldbetty)
+ register FILE *fp;
+ size_t *bufsize;
+ int *couldbetty;
+{
+ struct stat st;
+
+ if (fp->_file < 0 || fstat(fp->_file, &st) < 0) {
+ *couldbetty = 0;
+ *bufsize = BUFSIZ;
+ return (__SNPT);
+ }
+
+ /* could be a tty iff it is a character device */
+ *couldbetty = (st.st_mode & S_IFMT) == S_IFCHR;
+ if (st.st_blksize <= 0) {
+ *bufsize = BUFSIZ;
+ return (__SNPT);
+ }
+
+ /*
+ * Optimise fseek() only if it is a regular file. (The test for
+ * __sseek is mainly paranoia.) It is safe to set _blksize
+ * unconditionally; it will only be used if __SOPT is also set.
+ */
+ *bufsize = st.st_blksize;
+ fp->_blksize = st.st_blksize;
+ return ((st.st_mode & S_IFMT) == S_IFREG && fp->_seek == __sseek ?
+ __SOPT : __SNPT);
+}
diff --git a/lib/libc/stdio/mktemp.3 b/lib/libc/stdio/mktemp.3
new file mode 100644
index 0000000..d78d67c
--- /dev/null
+++ b/lib/libc/stdio/mktemp.3
@@ -0,0 +1,216 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mktemp.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd February 11, 1998
+.Dt MKTEMP 3
+.Os
+.Sh NAME
+.Nm mktemp
+.Nd make temporary file name (unique)
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft char *
+.Fn mktemp "char *template"
+.Ft int
+.Fn mkstemp "char *template"
+.Ft int
+.Fn mkstemps "char *template" "int suffixlen"
+.Ft char *
+.Fn mkdtemp "char *template"
+.Sh DESCRIPTION
+The
+.Fn mktemp
+function
+takes the given file name template and overwrites a portion of it
+to create a file name.
+This file name is unique and suitable for use
+by the application.
+The template may be any file name with some number of
+.Ql X Ns s
+appended
+to it, for example
+.Pa /tmp/temp.XXXX .
+The trailing
+.Ql X Ns s
+are replaced with the current process number and/or a
+unique letter combination.
+The number of unique file names
+.Fn mktemp
+can return depends on the number of
+.Ql X Ns s
+provided; six
+.Ql X Ns s
+will
+result in
+.Fn mktemp
+testing roughly 26 ** 6 combinations.
+.Pp
+The
+.Fn mkstemp
+function
+makes the same replacement to the template and creates the template file,
+mode 0600, returning a file descriptor opened for reading and writing.
+This avoids the race between testing for a file's existence and opening it
+for use.
+.Pp
+The
+.Fn mkstemps
+function acts the same as
+.Fn mkstemp ,
+except it permits a suffix to exist in the template.
+The template should be of the form
+.Pa /tmp/tmpXXXXXXsuffix .
+.Fn mkstemps
+is told the length of the suffix string.
+.Pp
+The
+.Fn mkdtemp
+function makes the same replacement to the template as in
+.Xr mktemp 3
+and creates the template directory, mode 0700.
+.Sh RETURN VALUES
+The
+.Fn mktemp
+and
+.Fn mkdtemp
+functions return a pointer to the template on success and
+.Dv NULL
+on failure.
+The
+.Fn mkstemp
+and
+.Fn mkstemps
+functions
+return \-1 if no suitable file could be created.
+If either call fails an error code is placed in the global variable
+.Va errno .
+.Sh ERRORS
+The
+.Fn mkstemp ,
+.Fn mkstemps
+and
+.Fn mkdtemp
+functions
+may set
+.Va errno
+to one of the following values:
+.Bl -tag -width [ENOTDIR]
+.It Bq Er ENOTDIR
+The pathname portion of the template is not an existing directory.
+.El
+.Pp
+The
+.Fn mkstemp ,
+.Fn mkstemps
+and
+.Fn mkdtemp
+functions
+may also set
+.Va errno
+to any value specified by the
+.Xr stat 2
+function.
+.Pp
+The
+.Fn mkstemp
+and
+.Fn mkstemps
+functions
+may also set
+.Va errno
+to any value specified by the
+.Xr open 2
+function.
+.Pp
+The
+.Fn mkdtemp
+function
+may also set
+.Va errno
+to any value specified by the
+.Xr mkdir 2
+function.
+.Sh NOTES
+A common problem that results in a core dump is that the programmer
+passes in a read-only string to
+.Fn mktemp ,
+.Fn mkstemp ,
+.Fn mkstemps
+or
+.Fn mkdtemp .
+This is common with programs that were developed before
+.St -ansiC
+compilers were common.
+For example, calling
+.Fn mkstemp
+with an argument of
+.Qq /tmp/tempfile.XXXXXX
+will result in a core dump due to
+.Fn mkstemp
+attempting to modify the string constant that was given.
+If the program in question makes heavy use of that type
+of function call, you do have the option of compiling the program
+so that it will store string constants in a writable segment of memory.
+See
+.Xr gcc 1
+for more information.
+.Sh BUGS
+An attacker can guess the filenames produced by
+.Fn mktemp .
+Whenever it is possible
+.Fn mkstemp
+should be used instead.
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr getpid 2 ,
+.Xr mkdir 2 ,
+.Xr open 2 ,
+.Xr stat 2
+.Sh HISTORY
+A
+.Fn mktemp
+function appeared in
+.At v7 .
+The
+.Fn mkdtemp
+function first appeared in
+.Ox 2.2 ,
+and later in
+.Fx 3.2 .
+The
+.Fn mkstemps
+function first appeared in
+.Ox 2.4 ,
+and later in
+.Fx 3.4 .
diff --git a/lib/libc/stdio/mktemp.c b/lib/libc/stdio/mktemp.c
new file mode 100644
index 0000000..cd24449
--- /dev/null
+++ b/lib/libc/stdio/mktemp.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+
+char *_mktemp __P((char *));
+
+static int _gettemp __P((char *, int *, int, int));
+
+int
+mkstemps(path, slen)
+ char *path;
+ int slen;
+{
+ int fd;
+
+ return (_gettemp(path, &fd, 0, slen) ? fd : -1);
+}
+
+int
+mkstemp(path)
+ char *path;
+{
+ int fd;
+
+ return (_gettemp(path, &fd, 0, 0) ? fd : -1);
+}
+
+char *
+mkdtemp(path)
+ char *path;
+{
+ return(_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL);
+}
+
+char *
+_mktemp(path)
+ char *path;
+{
+ return(_gettemp(path, (int *)NULL, 0, 0) ? path : (char *)NULL);
+}
+
+__warn_references(mktemp,
+ "warning: mktemp() possibly used unsafely; consider using mkstemp()");
+
+char *
+mktemp(path)
+ char *path;
+{
+ return(_mktemp(path));
+}
+
+static int
+_gettemp(path, doopen, domkdir, slen)
+ char *path;
+ register int *doopen;
+ int domkdir;
+ int slen;
+{
+ register char *start, *trv, *suffp;
+ struct stat sbuf;
+ int pid, rval;
+
+ if (doopen && domkdir) {
+ errno = EINVAL;
+ return(0);
+ }
+
+ for (trv = path; *trv; ++trv)
+ ;
+ trv -= slen;
+ suffp = trv;
+ --trv;
+ if (trv < path) {
+ errno = EINVAL;
+ return (0);
+ }
+ pid = getpid();
+ while (*trv == 'X' && pid != 0) {
+ *trv-- = (pid % 10) + '0';
+ pid /= 10;
+ }
+ while (*trv == 'X') {
+ char c;
+
+ pid = (arc4random() & 0xffff) % (26+26);
+ if (pid < 26)
+ c = pid + 'A';
+ else
+ c = (pid - 26) + 'a';
+ *trv-- = c;
+ }
+ start = trv + 1;
+
+ /*
+ * check the target directory; if you have six X's and it
+ * doesn't exist this runs for a *very* long time.
+ */
+ if (doopen || domkdir) {
+ for (;; --trv) {
+ if (trv <= path)
+ break;
+ if (*trv == '/') {
+ *trv = '\0';
+ rval = stat(path, &sbuf);
+ *trv = '/';
+ if (rval != 0)
+ return(0);
+ if (!S_ISDIR(sbuf.st_mode)) {
+ errno = ENOTDIR;
+ return(0);
+ }
+ break;
+ }
+ }
+ }
+
+ for (;;) {
+ if (doopen) {
+ if ((*doopen =
+ open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
+ return(1);
+ if (errno != EEXIST)
+ return(0);
+ } else if (domkdir) {
+ if (mkdir(path, 0700) == 0)
+ return(1);
+ if (errno != EEXIST)
+ return(0);
+ } else if (lstat(path, &sbuf))
+ return(errno == ENOENT ? 1 : 0);
+
+ /* tricky little algorithm for backward compatibility */
+ for (trv = start;;) {
+ if (*trv == '\0' || trv == suffp)
+ return(0);
+ if (*trv == 'Z')
+ *trv++ = 'a';
+ else {
+ if (isdigit((unsigned char)*trv))
+ *trv = 'a';
+ else if (*trv == 'z') /* inc from z to A */
+ *trv = 'A';
+ else
+ ++*trv;
+ break;
+ }
+ }
+ }
+ /*NOTREACHED*/
+}
diff --git a/lib/libc/stdio/perror.c b/lib/libc/stdio/perror.c
new file mode 100644
index 0000000..bb61824
--- /dev/null
+++ b/lib/libc/stdio/perror.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)perror.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+void
+perror(s)
+ const char *s;
+{
+ register struct iovec *v;
+ struct iovec iov[4];
+
+ v = iov;
+ if (s != NULL && *s != '\0') {
+ v->iov_base = (char *)s;
+ v->iov_len = strlen(s);
+ v++;
+ v->iov_base = ": ";
+ v->iov_len = 2;
+ v++;
+ }
+ v->iov_base = strerror(errno);
+ v->iov_len = strlen(v->iov_base);
+ v++;
+ v->iov_base = "\n";
+ v->iov_len = 1;
+ (void)writev(STDERR_FILENO, iov, (v - iov) + 1);
+}
diff --git a/lib/libc/stdio/printf.3 b/lib/libc/stdio/printf.3
new file mode 100644
index 0000000..18e1493
--- /dev/null
+++ b/lib/libc/stdio/printf.3
@@ -0,0 +1,661 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)printf.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt PRINTF 3
+.Os
+.Sh NAME
+.Nm printf ,
+.Nm fprintf ,
+.Nm sprintf ,
+.Nm snprintf ,
+.Nm asprintf ,
+.Nm vprintf ,
+.Nm vfprintf,
+.Nm vsprintf ,
+.Nm vsnprintf ,
+.Nm vasprintf
+.Nd formatted output conversion
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft int
+.Fn printf "const char *format" ...
+.Ft int
+.Fn fprintf "FILE *stream" "const char *format" ...
+.Ft int
+.Fn sprintf "char *str" "const char *format" ...
+.Ft int
+.Fn snprintf "char *str" "size_t size" "const char *format" ...
+.Ft int
+.Fn asprintf "char **ret" "const char *format" ...
+.Fd #include <stdarg.h>
+.Ft int
+.Fn vprintf "const char *format" "va_list ap"
+.Ft int
+.Fn vfprintf "FILE *stream" "const char *format" "va_list ap"
+.Ft int
+.Fn vsprintf "char *str" "const char *format" "va_list ap"
+.Ft int
+.Fn vsnprintf "char *str" "size_t size" "const char *format" "va_list ap"
+.Ft int
+.Fn vasprintf "char **ret" "const char *format" "va_list ap"
+.Sh DESCRIPTION
+The
+.Fn printf
+family of functions produces output according to a
+.Fa format
+as described below.
+.Fn Printf
+and
+.Fn vprintf
+write output to
+.Em stdout,
+the standard output stream;
+.Fn fprintf
+and
+.Fn vfprintf
+write output to the given output
+.Fa stream ;
+.Fn sprintf ,
+.Fn snprintf ,
+.Fn vsprintf ,
+and
+.Fn vsnprintf
+write to the character string
+.Fa str ;
+and
+.Fn asprintf
+and
+.Fn vasprintf
+dynamically allocate a new string with
+.Xr malloc 3 .
+.Pp
+These functions write the output under the control of a
+.Fa format
+string that specifies how subsequent arguments
+(or arguments accessed via the variable-length argument facilities of
+.Xr stdarg 3 )
+are converted for output.
+.Pp
+These functions return
+the number of characters printed
+(not including the trailing
+.Ql \e0
+used to end output to strings).
+.Pp
+.Fn Asprintf
+and
+.Fn vasprintf
+return a pointer to a buffer sufficiently large to hold the
+string in the
+.Fa ret
+argument;
+This pointer should be passed to
+.Xr free 3
+to release the allocated storage when it is no longer needed.
+If sufficient space cannot be allocated,
+.Fn asprintf
+and
+.Fn vasprintf
+will return -1 and set
+.Fa ret
+to be a NULL pointer.
+.Pp
+.Fn Snprintf
+and
+.Fn vsnprintf
+will write at most
+.Fa size Ns \-1
+of the characters printed into the output string
+(the
+.Fa size Ns 'th
+character then gets the terminating
+.Ql \e0 ) ;
+if the return value is greater than or equal to the
+.Fa size
+argument, the string was too short
+and some of the printed characters were discarded.
+.Pp
+.Fn Sprintf
+and
+.Fn vsprintf
+effectively assume an infinite
+.Fa size .
+.Pp
+The format string is composed of zero or more directives:
+ordinary
+.\" multibyte
+characters (not
+.Cm % ) ,
+which are copied unchanged to the output stream;
+and conversion specifications, each of which results
+in fetching zero or more subsequent arguments.
+Each conversion specification is introduced by
+the character
+.Cm % .
+The arguments must correspond properly (after type promotion)
+with the conversion specifier.
+After the
+.Cm % ,
+the following appear in sequence:
+.Bl -bullet
+.It
+An optional field, consisting of a decimal digit string followed by a
+.Cm $ ,
+specifying the next argument to access .
+If this field is not provided, the argument following the last
+argument accessed will be used.
+Arguments are numbered starting at
+.Cm 1 .
+If unaccessed arguments in the format string are interspersed with ones that
+are accessed the results will be indeterminate.
+.It
+Zero or more of the following flags:
+.Bl -hyphen
+.It
+A
+.Cm #
+character
+specifying that the value should be converted to an ``alternate form''.
+For
+.Cm c ,
+.Cm d ,
+.Cm i ,
+.Cm n ,
+.Cm p ,
+.Cm s ,
+and
+.Cm u ,
+conversions, this option has no effect.
+For
+.Cm o
+conversions, the precision of the number is increased to force the first
+character of the output string to a zero (except if a zero value is printed
+with an explicit precision of zero).
+For
+.Cm x
+and
+.Cm X
+conversions, a non-zero result has the string
+.Ql 0x
+(or
+.Ql 0X
+for
+.Cm X
+conversions) prepended to it.
+For
+.Cm e ,
+.Cm E ,
+.Cm f ,
+.Cm g ,
+and
+.Cm G ,
+conversions, the result will always contain a decimal point, even if no
+digits follow it (normally, a decimal point appears in the results of
+those conversions only if a digit follows).
+For
+.Cm g
+and
+.Cm G
+conversions, trailing zeros are not removed from the result as they
+would otherwise be.
+.It
+A zero
+.Sq Cm \&0
+character specifying zero padding.
+For all conversions except
+.Cm n ,
+the converted value is padded on the left with zeros rather than blanks.
+If a precision is given with a numeric conversion
+.Pf ( Cm d ,
+.Cm i ,
+.Cm o ,
+.Cm u ,
+.Cm i ,
+.Cm x ,
+and
+.Cm X ) ,
+the
+.Sq Cm \&0
+flag is ignored.
+.It
+A negative field width flag
+.Sq Cm \-
+indicates the converted value is to be left adjusted on the field boundary.
+Except for
+.Cm n
+conversions, the converted value is padded on the right with blanks,
+rather than on the left with blanks or zeros.
+A
+.Sq Cm \-
+overrides a
+.Sq Cm \&0
+if both are given.
+.It
+A space, specifying that a blank should be left before a positive number
+produced by a signed conversion
+.Pf ( Cm d ,
+.Cm e ,
+.Cm E ,
+.Cm f ,
+.Cm g ,
+.Cm G ,
+or
+.Cm i ) .
+.It
+A
+.Sq Cm +
+character specifying that a sign always be placed before a
+number produced by a signed conversion.
+A
+.Sq Cm +
+overrides a space if both are used.
+.El
+.It
+An optional decimal digit string specifying a minimum field width.
+If the converted value has fewer characters than the field width, it will
+be padded with spaces on the left (or right, if the left-adjustment
+flag has been given) to fill out
+the field width.
+.It
+An optional precision, in the form of a period
+.Sq Cm \&.
+followed by an
+optional digit string. If the digit string is omitted, the precision
+is taken as zero. This gives the minimum number of digits to appear for
+.Cm d ,
+.Cm i ,
+.Cm o ,
+.Cm u ,
+.Cm x ,
+and
+.Cm X
+conversions, the number of digits to appear after the decimal-point for
+.Cm e ,
+.Cm E ,
+and
+.Cm f
+conversions, the maximum number of significant digits for
+.Cm g
+and
+.Cm G
+conversions, or the maximum number of characters to be printed from a
+string for
+.Cm s
+conversions.
+.It
+The optional character
+.Cm h ,
+specifying that a following
+.Cm d ,
+.Cm i ,
+.Cm o ,
+.Cm u ,
+.Cm x ,
+or
+.Cm X
+conversion corresponds to a
+.Em short int
+or
+.Em unsigned short int
+argument, or that a following
+.Cm n
+conversion corresponds to a pointer to a
+.Em short int
+argument.
+.It
+The optional character
+.Cm l
+(ell) specifying that a following
+.Cm d ,
+.Cm i ,
+.Cm o ,
+.Cm u ,
+.Cm x ,
+or
+.Cm X
+conversion applies to a pointer to a
+.Em long int
+or
+.Em unsigned long int
+argument, or that a following
+.Cm n
+conversion corresponds to a pointer to a
+.Em long int
+argument.
+.It
+The optional character
+.Cm q ,
+specifying that a following
+.Cm d ,
+.Cm i ,
+.Cm o ,
+.Cm u ,
+.Cm x ,
+or
+.Cm X
+conversion corresponds to a
+.Em quad int
+or
+.Em unsigned quad int
+argument, or that a following
+.Cm n
+conversion corresponds to a pointer to a
+.Em quad int
+argument.
+.It
+The character
+.Cm L
+specifying that a following
+.Cm e ,
+.Cm E ,
+.Cm f ,
+.Cm g ,
+or
+.Cm G
+conversion corresponds to a
+.Em long double
+argument (but note that long double values are not currently supported
+by the
+.Tn VAX
+and
+.Tn Tahoe
+compilers).
+.It
+A character that specifies the type of conversion to be applied.
+.El
+.Pp
+A field width or precision, or both, may be indicated by
+an asterisk
+.Ql *
+or an asterisk followed by one or more decimal digits and a
+.Ql $
+instead of a
+digit string.
+In this case, an
+.Em int
+argument supplies the field width or precision.
+A negative field width is treated as a left adjustment flag followed by a
+positive field width; a negative precision is treated as though it were
+missing.
+If a single format directive mixes positional (nn$)
+and non-positional arguments, the results are undefined.
+.Pp
+The conversion specifiers and their meanings are:
+.Bl -tag -width "diouxX"
+.It Cm diouxX
+The
+.Em int
+(or appropriate variant) argument is converted to signed decimal
+.Pf ( Cm d
+and
+.Cm i ) ,
+unsigned octal
+.Pq Cm o ,
+unsigned decimal
+.Pq Cm u ,
+or unsigned hexadecimal
+.Pf ( Cm x
+and
+.Cm X )
+notation. The letters
+.Cm abcdef
+are used for
+.Cm x
+conversions; the letters
+.Cm ABCDEF
+are used for
+.Cm X
+conversions.
+The precision, if any, gives the minimum number of digits that must
+appear; if the converted value requires fewer digits, it is padded on
+the left with zeros.
+.It Cm DOU
+The
+.Em long int
+argument is converted to signed decimal, unsigned octal, or unsigned
+decimal, as if the format had been
+.Cm ld ,
+.Cm lo ,
+or
+.Cm lu
+respectively.
+These conversion characters are deprecated, and will eventually disappear.
+.It Cm eE
+The
+.Em double
+argument is rounded and converted in the style
+.Sm off
+.Pf [\-]d Cm \&. No ddd Cm e No \\*(Pmdd
+.Sm on
+where there is one digit before the
+decimal-point character
+and the number of digits after it is equal to the precision;
+if the precision is missing,
+it is taken as 6; if the precision is
+zero, no decimal-point character appears.
+An
+.Cm E
+conversion uses the letter
+.Cm E
+(rather than
+.Cm e )
+to introduce the exponent.
+The exponent always contains at least two digits; if the value is zero,
+the exponent is 00.
+.It Cm f
+The
+.Em double
+argument is rounded and converted to decimal notation in the style
+.Sm off
+.Pf [-]ddd Cm \&. No ddd ,
+.Sm on
+where the number of digits after the decimal-point character
+is equal to the precision specification.
+If the precision is missing, it is taken as 6; if the precision is
+explicitly zero, no decimal-point character appears.
+If a decimal point appears, at least one digit appears before it.
+.It Cm gG
+The
+.Em double
+argument is converted in style
+.Cm f
+or
+.Cm e
+(or
+.Cm E
+for
+.Cm G
+conversions).
+The precision specifies the number of significant digits.
+If the precision is missing, 6 digits are given; if the precision is zero,
+it is treated as 1.
+Style
+.Cm e
+is used if the exponent from its conversion is less than -4 or greater than
+or equal to the precision.
+Trailing zeros are removed from the fractional part of the result; a
+decimal point appears only if it is followed by at least one digit.
+.It Cm c
+The
+.Em int
+argument is converted to an
+.Em unsigned char ,
+and the resulting character is written.
+.It Cm s
+The
+.Dq Em char *
+argument is expected to be a pointer to an array of character type (pointer
+to a string).
+Characters from the array are written up to (but not including)
+a terminating
+.Dv NUL
+character;
+if a precision is specified, no more than the number specified are
+written.
+If a precision is given, no null character
+need be present; if the precision is not specified, or is greater than
+the size of the array, the array must contain a terminating
+.Dv NUL
+character.
+.It Cm p
+The
+.Dq Em void *
+pointer argument is printed in hexadecimal (as if by
+.Ql %#x
+or
+.Ql %#lx ) .
+.It Cm n
+The number of characters written so far is stored into the
+integer indicated by the
+.Dq Em int *
+(or variant) pointer argument.
+No argument is converted.
+.It Cm %
+A
+.Ql %
+is written. No argument is converted. The complete conversion specification
+is
+.Ql %% .
+.El
+.Pp
+In no case does a non-existent or small field width cause truncation of
+a field; if the result of a conversion is wider than the field width, the
+field is expanded to contain the conversion result.
+.Pp
+.Sh EXAMPLES
+.br
+To print a date and time in the form `Sunday, July 3, 10:02',
+where
+.Em weekday
+and
+.Em month
+are pointers to strings:
+.Bd -literal -offset indent
+#include <stdio.h>
+fprintf(stdout, "%s, %s %d, %.2d:%.2d\en",
+ weekday, month, day, hour, min);
+.Ed
+.Pp
+To print \*(Pi
+to five decimal places:
+.Bd -literal -offset indent
+#include <math.h>
+#include <stdio.h>
+fprintf(stdout, "pi = %.5f\en", 4 * atan(1.0));
+.Ed
+.Pp
+To allocate a 128 byte string and print into it:
+.Bd -literal -offset indent
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+char *newfmt(const char *fmt, ...)
+{
+ char *p;
+ va_list ap;
+ if ((p = malloc(128)) == NULL)
+ return (NULL);
+ va_start(ap, fmt);
+ (void) vsnprintf(p, 128, fmt, ap);
+ va_end(ap);
+ return (p);
+}
+.Ed
+.Sh SEE ALSO
+.Xr printf 1 ,
+.Xr scanf 3
+.Sh STANDARDS
+The
+.Fn fprintf ,
+.Fn printf ,
+.Fn sprintf ,
+.Fn vprintf ,
+.Fn vfprintf ,
+and
+.Fn vsprintf
+functions
+conform to
+.St -ansiC .
+.Sh HISTORY
+The functions
+.Fn asprintf
+and
+.Fn vasprintf
+first appeared in the GNU C library.
+These were implemented by Peter Wemm <peter@FreeBSD.org> in
+.Fx 2.2 ,
+but were later replaced with a different implementation
+from Todd C. Miller <Todd.Miller@courtesan.com> for
+.Ox 2.3 .
+.Sh BUGS
+The conversion formats
+.Cm \&%D ,
+.Cm \&%O ,
+and
+.Cm %U
+are not standard and
+are provided only for backward compatibility.
+The effect of padding the
+.Cm %p
+format with zeros (either by the
+.Sq Cm 0
+flag or by specifying a precision), and the benign effect (i.e., none)
+of the
+.Sq Cm #
+flag on
+.Cm %n
+and
+.Cm %p
+conversions, as well as other
+nonsensical combinations such as
+.Cm %Ld ,
+are not standard; such combinations
+should be avoided.
+.Pp
+Because
+.Fn sprintf
+and
+.Fn vsprintf
+assume an infinitely long string,
+callers must be careful not to overflow the actual space;
+this is often hard to assure.
+For safety, programmers should use the
+.Fn snprintf
+interface instead.
+Unfortunately, this interface is not portable.
diff --git a/lib/libc/stdio/printf.c b/lib/libc/stdio/printf.c
new file mode 100644
index 0000000..053ec8e
--- /dev/null
+++ b/lib/libc/stdio/printf.c
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)printf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+#if __STDC__
+printf(char const *fmt, ...)
+#else
+printf(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ ret = vfprintf(stdout, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libc/stdio/putc.3 b/lib/libc/stdio/putc.3
new file mode 100644
index 0000000..d251174
--- /dev/null
+++ b/lib/libc/stdio/putc.3
@@ -0,0 +1,133 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)putc.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt PUTC 3
+.Os
+.Sh NAME
+.Nm fputc ,
+.Nm putc ,
+.Nm putchar ,
+.Nm putw
+.Nd output a character or word to a stream
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft int
+.Fn fputc "int c" "FILE *stream"
+.Ft int
+.Fn putc "int c" "FILE *stream"
+.Ft int
+.Fn putchar "int c"
+.Ft int
+.Fn putw "int w" "FILE *stream"
+.Sh DESCRIPTION
+The
+.Fn fputc
+function
+writes the character
+.Fa c
+(converted to an ``unsigned char'')
+to the output stream pointed to by
+.Fa stream .
+.Pp
+The
+.Fn putc
+macro acts essentially identically to
+.Fn fputc ,
+but is a macro that expands in-line. It may evaluate
+.Fa stream
+more than once, so arguments given to
+.Fn putc
+should not be expressions with potential side effects.
+.Pp
+The
+.Fn putchar
+macro
+is identical to
+.Fn putc
+with an output stream of
+.Em stdout .
+.Pp
+The
+.Fn putw
+function
+writes the specified
+.Em int
+to the named output
+.Fa stream .
+.Sh RETURN VALUES
+The functions,
+.Fn fputc ,
+.Fn putc
+and
+.Fn putchar
+return the character written.
+If an error occurs, the value
+.Dv EOF
+is returned.
+The
+.Fn putw
+function
+returns 0 on success;
+.Dv EOF
+is returned if
+a write error occurs,
+or if an attempt is made to write a read-only stream.
+.Sh SEE ALSO
+.Xr ferror 3 ,
+.Xr fopen 3 ,
+.Xr getc 3 ,
+.Xr stdio 3
+.Sh STANDARDS
+The functions
+.Fn fputc ,
+.Fn putc ,
+and
+.Fn putchar ,
+conform to
+.St -ansiC .
+A function
+.Fn putw
+function appeared in
+.At v6 .
+.Sh BUGS
+The size and byte order of an
+.Em int
+varies from one machine to another, and
+.Fn putw
+is not recommended for portable applications.
diff --git a/lib/libc/stdio/putc.c b/lib/libc/stdio/putc.c
new file mode 100644
index 0000000..fe1591c
--- /dev/null
+++ b/lib/libc/stdio/putc.c
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)putc.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "libc_private.h"
+
+/*
+ * A subroutine version of the macro putc.
+ */
+#undef putc
+
+int
+putc(c, fp)
+ int c;
+ register FILE *fp;
+{
+ int retval;
+ FLOCKFILE(fp);
+ retval = __sputc(c, fp);
+ FUNLOCKFILE(fp);
+ return (retval);
+}
diff --git a/lib/libc/stdio/putchar.c b/lib/libc/stdio/putchar.c
new file mode 100644
index 0000000..cebd872
--- /dev/null
+++ b/lib/libc/stdio/putchar.c
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)putchar.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "libc_private.h"
+
+#undef putchar
+
+/*
+ * A subroutine version of the macro putchar
+ */
+int
+putchar(c)
+ int c;
+{
+ int retval;
+ register FILE *so = stdout;
+
+ FLOCKFILE(so);
+ retval = __sputc(c, so);
+ FUNLOCKFILE(so);
+ return (retval);
+}
diff --git a/lib/libc/stdio/puts.c b/lib/libc/stdio/puts.c
new file mode 100644
index 0000000..59f153d
--- /dev/null
+++ b/lib/libc/stdio/puts.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)puts.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include "fvwrite.h"
+#include "libc_private.h"
+
+/*
+ * Write the given string to stdout, appending a newline.
+ */
+int
+puts(s)
+ char const *s;
+{
+ int retval;
+ size_t c = strlen(s);
+ struct __suio uio;
+ struct __siov iov[2];
+
+ iov[0].iov_base = (void *)s;
+ iov[0].iov_len = c;
+ iov[1].iov_base = "\n";
+ iov[1].iov_len = 1;
+ uio.uio_resid = c + 1;
+ uio.uio_iov = &iov[0];
+ uio.uio_iovcnt = 2;
+ FLOCKFILE(stdout);
+ retval = __sfvwrite(stdout, &uio) ? EOF : '\n';
+ FUNLOCKFILE(stdout);
+ return (retval);
+}
diff --git a/lib/libc/stdio/putw.c b/lib/libc/stdio/putw.c
new file mode 100644
index 0000000..8eac4cf
--- /dev/null
+++ b/lib/libc/stdio/putw.c
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)putw.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "fvwrite.h"
+#include "libc_private.h"
+
+int
+putw(w, fp)
+ int w;
+ FILE *fp;
+{
+ int retval;
+ struct __suio uio;
+ struct __siov iov;
+
+ iov.iov_base = &w;
+ iov.iov_len = uio.uio_resid = sizeof(w);
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ FLOCKFILE(fp);
+ retval = __sfvwrite(fp, &uio);
+ FUNLOCKFILE(fp);
+ return (retval);
+}
diff --git a/lib/libc/stdio/refill.c b/lib/libc/stdio/refill.c
new file mode 100644
index 0000000..8793830
--- /dev/null
+++ b/lib/libc/stdio/refill.c
@@ -0,0 +1,136 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)refill.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+static int lflush __P((FILE *));
+
+static int
+lflush(fp)
+ FILE *fp;
+{
+
+ if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR))
+ return (__sflush(fp));
+ return (0);
+}
+
+/*
+ * Refill a stdio buffer.
+ * Return EOF on eof or error, 0 otherwise.
+ */
+int
+__srefill(fp)
+ register FILE *fp;
+{
+
+ /* make sure stdio is set up */
+ if (!__sdidinit)
+ __sinit();
+
+ fp->_r = 0; /* largely a convenience for callers */
+
+ /* SysV does not make this test; take it out for compatibility */
+ if (fp->_flags & __SEOF)
+ return (EOF);
+
+ /* if not already reading, have to be reading and writing */
+ if ((fp->_flags & __SRD) == 0) {
+ if ((fp->_flags & __SRW) == 0) {
+ errno = EBADF;
+ fp->_flags |= __SERR;
+ return (EOF);
+ }
+ /* switch to reading */
+ if (fp->_flags & __SWR) {
+ if (__sflush(fp))
+ return (EOF);
+ fp->_flags &= ~__SWR;
+ fp->_w = 0;
+ fp->_lbfsize = 0;
+ }
+ fp->_flags |= __SRD;
+ } else {
+ /*
+ * We were reading. If there is an ungetc buffer,
+ * we must have been reading from that. Drop it,
+ * restoring the previous buffer (if any). If there
+ * is anything in that buffer, return.
+ */
+ if (HASUB(fp)) {
+ FREEUB(fp);
+ if ((fp->_r = fp->_ur) != 0) {
+ fp->_p = fp->_up;
+ return (0);
+ }
+ }
+ }
+
+ if (fp->_bf._base == NULL)
+ __smakebuf(fp);
+
+ /*
+ * Before reading from a line buffered or unbuffered file,
+ * flush all line buffered output files, per the ANSI C
+ * standard.
+ */
+ if (fp->_flags & (__SLBF|__SNBF))
+ (void) _fwalk(lflush);
+ fp->_p = fp->_bf._base;
+ fp->_r = (*fp->_read)(fp->_cookie, (char *)fp->_p, fp->_bf._size);
+ fp->_flags &= ~__SMOD; /* buffer contents are again pristine */
+ if (fp->_r <= 0) {
+ if (fp->_r == 0)
+ fp->_flags |= __SEOF;
+ else {
+ fp->_r = 0;
+ fp->_flags |= __SERR;
+ }
+ return (EOF);
+ }
+ return (0);
+}
diff --git a/lib/libc/stdio/remove.3 b/lib/libc/stdio/remove.3
new file mode 100644
index 0000000..e9b380b
--- /dev/null
+++ b/lib/libc/stdio/remove.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)remove.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt REMOVE 3
+.Os
+.Sh NAME
+.Nm remove
+.Nd remove directory entry
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft int
+.Fn remove "const char *path"
+.Sh DESCRIPTION
+The
+.Fn remove
+function
+is an alias for the
+.Xr unlink 2
+system call.
+It deletes the file referenced by
+.Fa path .
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn remove
+returns 0.
+Otherwise, \-1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn remove
+function
+may fail and set
+.Va errno
+for any of the errors specified for the routine
+.Xr unlink 2 .
+.Sh SEE ALSO
+.Xr unlink 2
+.Sh STANDARDS
+The
+.Fn remove
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/stdio/remove.c b/lib/libc/stdio/remove.c
new file mode 100644
index 0000000..cca7cb6
--- /dev/null
+++ b/lib/libc/stdio/remove.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)remove.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <unistd.h>
+#include <stdio.h>
+
+int
+remove(file)
+ const char *file;
+{
+ return (unlink(file));
+}
diff --git a/lib/libc/stdio/rewind.c b/lib/libc/stdio/rewind.c
new file mode 100644
index 0000000..98c5846
--- /dev/null
+++ b/lib/libc/stdio/rewind.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)rewind.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+#include "libc_private.h"
+
+void
+rewind(fp)
+ register FILE *fp;
+{
+ FLOCKFILE(fp);
+ (void) fseek(fp, 0L, SEEK_SET);
+ clearerr(fp);
+ FUNLOCKFILE(fp);
+ errno = 0; /* not required, but seems reasonable */
+}
diff --git a/lib/libc/stdio/rget.c b/lib/libc/stdio/rget.c
new file mode 100644
index 0000000..45d817d
--- /dev/null
+++ b/lib/libc/stdio/rget.c
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)rget.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$Id";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "local.h"
+
+int
+__srefill(FILE *);
+
+/*
+ * Handle getc() when the buffer ran out:
+ * Refill, then return the first character
+ * in the newly-filled buffer.
+ */
+int __srget(fp)
+ register FILE *fp;
+{
+ if (__srefill(fp) == 0) {
+ fp->_r--;
+ return (*fp->_p++);
+ }
+ return (EOF);
+}
diff --git a/lib/libc/stdio/scanf.3 b/lib/libc/stdio/scanf.3
new file mode 100644
index 0000000..1144f5a
--- /dev/null
+++ b/lib/libc/stdio/scanf.3
@@ -0,0 +1,440 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)scanf.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt SCANF 3
+.Os
+.Sh NAME
+.Nm scanf ,
+.Nm fscanf ,
+.Nm sscanf ,
+.Nm vscanf ,
+.Nm vsscanf ,
+.Nm vfscanf
+.Nd input format conversion
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft int
+.Fn scanf "const char *format" ...
+.Ft int
+.Fn fscanf "FILE *stream" "const char *format" ...
+.Ft int
+.Fn sscanf "const char *str" "const char *format" ...
+.Fd #include <stdarg.h>
+.Ft int
+.Fn vscanf "const char *format" "va_list ap"
+.Ft int
+.Fn vsscanf "const char *str" "const char *format" "va_list ap"
+.Ft int
+.Fn vfscanf "FILE *stream" "const char *format" "va_list ap"
+.Sh DESCRIPTION
+The
+.Fn scanf
+family of functions scans input according to a
+.Fa format
+as described below.
+This format may contain
+.Em conversion specifiers ;
+the results from such conversions, if any,
+are stored through the
+.Em pointer
+arguments.
+The
+.Fn scanf
+function
+reads input from the standard input stream
+.Em stdin ,
+.Fn fscanf
+reads input from the stream pointer
+.Fa stream ,
+and
+.Fn sscanf
+reads its input from the character string pointed to by
+.Fa str .
+The
+.Fn vfscanf
+function
+is analogous to
+.Xr vfprintf 3
+and reads input from the stream pointer
+.Fa stream
+using a variable argument list of pointers (see
+.Xr stdarg 3 ) .
+The
+.Fn vscanf
+function scans a variable argument list from the standard input and
+the
+.Fn vsscanf
+function scans it from a string;
+these are analogous to
+the
+.Fn vprintf
+and
+.Fn vsprintf
+functions respectively.
+Each successive
+.Em pointer
+argument must correspond properly with
+each successive conversion specifier
+(but see `suppression' below).
+All conversions are introduced by the
+.Cm %
+(percent sign) character.
+The
+.Fa format
+string
+may also contain other characters.
+White space (such as blanks, tabs, or newlines) in the
+.Fa format
+string match any amount of white space, including none, in the input.
+Everything else
+matches only itself.
+Scanning stops
+when an input character does not match such a format character.
+Scanning also stops
+when an input conversion cannot be made (see below).
+.Sh CONVERSIONS
+Following the
+.Cm %
+character introducing a conversion
+there may be a number of
+.Em flag
+characters, as follows:
+.Bl -tag -width indent
+.It Cm *
+Suppresses assignment.
+The conversion that follows occurs as usual, but no pointer is used;
+the result of the conversion is simply discarded.
+.It Cm h
+Indicates that the conversion will be one of
+.Cm dioux
+or
+.Cm n
+and the next pointer is a pointer to a
+.Em short int
+(rather than
+.Em int ) .
+.It Cm l
+Indicates either that the conversion will be one of
+.Cm dioux
+or
+.Cm n
+and the next pointer is a pointer to a
+.Em long int
+(rather than
+.Em int ) ,
+or that the conversion will be one of
+.Cm efg
+and the next pointer is a pointer to
+.Em double
+(rather than
+.Em float ) .
+.It Cm L
+Indicates that the conversion will be
+.Cm efg
+and the next pointer is a pointer to
+.Em long double .
+(This type is not implemented; the
+.Cm L
+flag is currently ignored.)
+.It Cm q
+Indicates either that the conversion will be one of
+.Cm dioux
+or
+.Cm n
+and the next pointer is a pointer to a
+.Em long long int
+(rather than
+.Em int ) ,
+.El
+.Pp
+In addition to these flags,
+there may be an optional maximum field width,
+expressed as a decimal integer,
+between the
+.Cm %
+and the conversion.
+If no width is given,
+a default of `infinity' is used (with one exception, below);
+otherwise at most this many characters are scanned
+in processing the conversion.
+Before conversion begins,
+most conversions skip white space;
+this white space is not counted against the field width.
+.Pp
+The following conversions are available:
+.Bl -tag -width XXXX
+.It Cm %
+Matches a literal `%'.
+That is, `%\&%' in the format string
+matches a single input `%' character.
+No conversion is done, and assignment does not occur.
+.It Cm d
+Matches an optionally signed decimal integer;
+the next pointer must be a pointer to
+.Em int .
+.It Cm D
+Equivalent to
+.Cm ld ;
+this exists only for backwards compatibility.
+.It Cm i
+Matches an optionally signed integer;
+the next pointer must be a pointer to
+.Em int .
+The integer is read in base 16 if it begins
+with
+.Ql 0x
+or
+.Ql 0X ,
+in base 8 if it begins with
+.Ql 0 ,
+and in base 10 otherwise.
+Only characters that correspond to the base are used.
+.It Cm o
+Matches an octal integer;
+the next pointer must be a pointer to
+.Em unsigned int .
+.It Cm O
+Equivalent to
+.Cm lo ;
+this exists for backwards compatibility.
+.It Cm u
+Matches an optionally signed decimal integer;
+the next pointer must be a pointer to
+.Em unsigned int .
+.It Cm x
+Matches an optionally signed hexadecimal integer;
+the next pointer must be a pointer to
+.Em unsigned int .
+.It Cm X
+Equivalent to
+.Cm lx ;
+this violates the
+.St -ansiC ,
+but is backwards compatible with previous
+.Ux
+systems.
+.It Cm f
+Matches an optionally signed floating-point number;
+the next pointer must be a pointer to
+.Em float .
+.It Cm e
+Equivalent to
+.Cm f .
+.It Cm g
+Equivalent to
+.Cm f .
+.It Cm E
+Equivalent to
+.Cm lf ;
+this violates the
+.St -ansiC ,
+but is backwards compatible with previous
+.Ux
+systems.
+.It Cm F
+Equivalent to
+.Cm lf ;
+this exists only for backwards compatibility.
+.It Cm s
+Matches a sequence of non-white-space characters;
+the next pointer must be a pointer to
+.Em char ,
+and the array must be large enough to accept all the sequence and the
+terminating
+.Dv NUL
+character.
+The input string stops at white space
+or at the maximum field width, whichever occurs first.
+.It Cm c
+Matches a sequence of
+.Em width
+count
+characters (default 1);
+the next pointer must be a pointer to
+.Em char ,
+and there must be enough room for all the characters
+(no terminating
+.Dv NUL
+is added).
+The usual skip of leading white space is suppressed.
+To skip white space first, use an explicit space in the format.
+.It Cm \&[
+Matches a nonempty sequence of characters from the specified set
+of accepted characters;
+the next pointer must be a pointer to
+.Em char ,
+and there must be enough room for all the characters in the string,
+plus a terminating
+.Dv NUL
+character.
+The usual skip of leading white space is suppressed.
+The string is to be made up of characters in
+(or not in)
+a particular set;
+the set is defined by the characters between the open bracket
+.Cm [
+character
+and a close bracket
+.Cm ]
+character.
+The set
+.Em excludes
+those characters
+if the first character after the open bracket is a circumflex
+.Cm ^ .
+To include a close bracket in the set,
+make it the first character after the open bracket
+or the circumflex;
+any other position will end the set.
+The hyphen character
+.Cm -
+is also special;
+when placed between two other characters,
+it adds all intervening characters to the set.
+To include a hyphen,
+make it the last character before the final close bracket.
+For instance,
+.Ql [^]0-9-]
+means the set `everything except close bracket, zero through nine,
+and hyphen'.
+The string ends with the appearance of a character not in the
+(or, with a circumflex, in) set
+or when the field width runs out.
+.It Cm p
+Matches a pointer value (as printed by
+.Ql %p
+in
+.Xr printf 3 ) ;
+the next pointer must be a pointer to
+.Em void .
+.It Cm n
+Nothing is expected;
+instead, the number of characters consumed thus far from the input
+is stored through the next pointer,
+which must be a pointer to
+.Em int .
+This is
+.Em not
+a conversion, although it can be suppressed with the
+.Cm *
+flag.
+.El
+.Pp
+For backwards compatibility,
+other conversion characters (except
+.Ql \e0 )
+are taken as if they were
+.Ql %d
+or, if uppercase,
+.Ql %ld ,
+and a `conversion' of
+.Ql %\e0
+causes an immediate return of
+.Dv EOF .
+The
+.Cm F
+and
+.Cm X
+conversions will be changed in the future
+to conform to the
+.Tn ANSI
+C standard,
+after which they will act like
+.Cm f
+and
+.Cm x
+respectively.
+.Pp
+.Sh RETURN VALUES
+These
+functions
+return
+the number of input items assigned, which can be fewer than provided
+for, or even zero, in the event of a matching failure.
+Zero
+indicates that, while there was input available,
+no conversions were assigned;
+typically this is due to an invalid input character,
+such as an alphabetic character for a
+.Ql %d
+conversion.
+The value
+.Dv EOF
+is returned if an input failure occurs before any conversion such as an
+end-of-file occurs. If an error or end-of-file occurs after conversion
+has begun,
+the number of conversions which were successfully completed is returned.
+.Sh SEE ALSO
+.Xr getc 3 ,
+.Xr printf 3 ,
+.Xr strtod 3 ,
+.Xr strtol 3 ,
+.Xr strtoul 3
+.Sh STANDARDS
+The functions
+.Fn fscanf ,
+.Fn scanf ,
+and
+.Fn sscanf
+conform to
+.St -ansiC .
+.Sh HISTORY
+The functions
+.Fn vscanf ,
+.Fn vsscanf
+and
+.Fn vfscanf
+are new to this release.
+.Sh BUGS
+The current situation with
+.Cm %F
+and
+.Cm %X
+conversions is unfortunate.
+.Pp
+All of the backwards compatibility formats will be removed in the future.
+.Pp
+Numerical strings are truncated to 512 characters; for example,
+.Cm %f
+and
+.Cm %d
+are implicitly
+.Cm %512f
+and
+.Cm %512d .
diff --git a/lib/libc/stdio/scanf.c b/lib/libc/stdio/scanf.c
new file mode 100644
index 0000000..b183c17
--- /dev/null
+++ b/lib/libc/stdio/scanf.c
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)scanf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include "libc_private.h"
+
+#if __STDC__
+int
+scanf(char const *fmt, ...)
+#else
+int
+scanf(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ FLOCKFILE(stdin);
+ ret = __svfscanf(stdin, fmt, ap);
+ FUNLOCKFILE(stdin);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libc/stdio/setbuf.3 b/lib/libc/stdio/setbuf.3
new file mode 100644
index 0000000..1626bc1
--- /dev/null
+++ b/lib/libc/stdio/setbuf.3
@@ -0,0 +1,203 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)setbuf.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SETBUF 3
+.Os BSD 4
+.Sh NAME
+.Nm setbuf ,
+.Nm setbuffer ,
+.Nm setlinebuf ,
+.Nm setvbuf
+.Nd stream buffering operations
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft void
+.Fn setbuf "FILE *stream" "char *buf"
+.Ft void
+.Fn setbuffer "FILE *stream" "char *buf" "int size"
+.Ft int
+.Fn setlinebuf "FILE *stream"
+.Ft int
+.Fn setvbuf "FILE *stream" "char *buf" "int mode" "size_t size"
+.Sh DESCRIPTION
+The three types of buffering available are unbuffered, block buffered,
+and line buffered.
+When an output stream is unbuffered, information appears on the
+destination file or terminal as soon as written;
+when it is block buffered many characters are saved up and written as a block;
+when it is line buffered characters are saved up until a newline is
+output or input is read from any stream attached to a terminal device
+(typically stdin).
+The function
+.Xr fflush 3
+may be used to force the block out early.
+(See
+.Xr fclose 3 . )
+.Pp
+Normally all files are block buffered.
+When the first
+.Tn I/O
+operation occurs on a file,
+.Xr malloc 3
+is called,
+and an optimally-sized buffer is obtained.
+If a stream refers to a terminal
+(as
+.Em stdout
+normally does) it is line buffered.
+The standard error stream
+.Em stderr
+is always unbuffered.
+.Pp
+The
+.Fn setvbuf
+function
+may be used to alter the buffering behavior of a stream.
+The
+.Fa mode
+parameter must be one of the following three macros:
+.Bl -tag -width _IOFBF -offset indent
+.It Dv _IONBF
+unbuffered
+.It Dv _IOLBF
+line buffered
+.It Dv _IOFBF
+fully buffered
+.El
+.Pp
+The
+.Fa size
+parameter may be given as zero
+to obtain deferred optimal-size buffer allocation as usual.
+If it is not zero,
+then except for unbuffered files, the
+.Fa buf
+argument should point to a buffer at least
+.Fa size
+bytes long;
+this buffer will be used instead of the current buffer.
+(If the
+.Fa size
+argument
+is not zero but
+.Fa buf
+is
+.Dv NULL ,
+a buffer of the given size will be allocated immediately,
+and released on close.
+This is an extension to ANSI C;
+portable code should use a size of 0 with any
+.Dv NULL
+buffer.)
+.Pp
+The
+.Fn setvbuf
+function may be used at any time,
+but may have peculiar side effects
+(such as discarding input or flushing output)
+if the stream is ``active''.
+Portable applications should call it only once on any given stream,
+and before any
+.Tn I/O
+is performed.
+.Pp
+The other three calls are, in effect, simply aliases for calls to
+.Fn setvbuf .
+Except for the lack of a return value, the
+.Fn setbuf
+function is exactly equivalent to the call
+.Pp
+.Dl "setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);"
+.Pp
+The
+.Fn setbuffer
+function
+is the same, except that the size of the buffer is up to the caller,
+rather than being determined by the default
+.Dv BUFSIZ .
+The
+.Fn setlinebuf
+function
+is exactly equivalent to the call:
+.Pp
+.Dl "setvbuf(stream, (char *)NULL, _IOLBF, 0);"
+.Sh RETURN VALUES
+The
+.Fn setvbuf
+function returns 0 on success, or
+.Dv EOF
+if the request cannot be honored
+(note that the stream is still functional in this case).
+.Pp
+The
+.Fn setlinebuf
+function returns what the equivalent
+.Fn setvbuf
+would have returned.
+.Sh SEE ALSO
+.Xr fclose 3 ,
+.Xr fopen 3 ,
+.Xr fread 3 ,
+.Xr malloc 3 ,
+.Xr printf 3 ,
+.Xr puts 3
+.Sh STANDARDS
+The
+.Fn setbuf
+and
+.Fn setvbuf
+functions
+conform to
+.St -ansiC .
+.Sh BUGS
+The
+.Fn setbuffer
+and
+.Fn setlinebuf
+functions are not portable to versions of
+.Bx
+before
+.Bx 4.2 .
+On
+.Bx 4.2
+and
+.Bx 4.3
+systems,
+.Fn setbuf
+always uses a suboptimal buffer size and should be avoided.
diff --git a/lib/libc/stdio/setbuf.c b/lib/libc/stdio/setbuf.c
new file mode 100644
index 0000000..b07bce9
--- /dev/null
+++ b/lib/libc/stdio/setbuf.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setbuf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "local.h"
+
+void
+setbuf(fp, buf)
+ FILE *fp;
+ char *buf;
+{
+ (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
+}
diff --git a/lib/libc/stdio/setbuffer.c b/lib/libc/stdio/setbuffer.c
new file mode 100644
index 0000000..7db2d4d
--- /dev/null
+++ b/lib/libc/stdio/setbuffer.c
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)setbuffer.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+void
+setbuffer(fp, buf, size)
+ register FILE *fp;
+ char *buf;
+ int size;
+{
+
+ (void)setvbuf(fp, buf, buf ? _IOFBF : _IONBF, (size_t)size);
+}
+
+/*
+ * set line buffering
+ */
+int
+setlinebuf(fp)
+ FILE *fp;
+{
+
+ return (setvbuf(fp, (char *)NULL, _IOLBF, (size_t)0));
+}
diff --git a/lib/libc/stdio/setvbuf.c b/lib/libc/stdio/setvbuf.c
new file mode 100644
index 0000000..4693b9f
--- /dev/null
+++ b/lib/libc/stdio/setvbuf.c
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)setvbuf.c 8.2 (Berkeley) 11/16/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+#include "libc_private.h"
+
+/*
+ * Set one of the three kinds of buffering, optionally including
+ * a buffer.
+ */
+int
+setvbuf(fp, buf, mode, size)
+ register FILE *fp;
+ char *buf;
+ register int mode;
+ register size_t size;
+{
+ register int ret, flags;
+ size_t iosize;
+ int ttyflag;
+
+ /*
+ * Verify arguments. The `int' limit on `size' is due to this
+ * particular implementation. Note, buf and size are ignored
+ * when setting _IONBF.
+ */
+ if (mode != _IONBF)
+ if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0)
+ return (EOF);
+
+ FLOCKFILE(fp);
+ /*
+ * Write current buffer, if any. Discard unread input (including
+ * ungetc data), cancel line buffering, and free old buffer if
+ * malloc()ed. We also clear any eof condition, as if this were
+ * a seek.
+ */
+ ret = 0;
+ (void)__sflush(fp);
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_r = fp->_lbfsize = 0;
+ flags = fp->_flags;
+ if (flags & __SMBF)
+ free((void *)fp->_bf._base);
+ flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT | __SEOF);
+
+ /* If setting unbuffered mode, skip all the hard work. */
+ if (mode == _IONBF)
+ goto nbf;
+
+ /*
+ * Find optimal I/O size for seek optimization. This also returns
+ * a `tty flag' to suggest that we check isatty(fd), but we do not
+ * care since our caller told us how to buffer.
+ */
+ flags |= __swhatbuf(fp, &iosize, &ttyflag);
+ if (size == 0) {
+ buf = NULL; /* force local allocation */
+ size = iosize;
+ }
+
+ /* Allocate buffer if needed. */
+ if (buf == NULL) {
+ if ((buf = malloc(size)) == NULL) {
+ /*
+ * Unable to honor user's request. We will return
+ * failure, but try again with file system size.
+ */
+ ret = EOF;
+ if (size != iosize) {
+ size = iosize;
+ buf = malloc(size);
+ }
+ }
+ if (buf == NULL) {
+ /* No luck; switch to unbuffered I/O. */
+nbf:
+ fp->_flags = flags | __SNBF;
+ fp->_w = 0;
+ fp->_bf._base = fp->_p = fp->_nbuf;
+ fp->_bf._size = 1;
+ FUNLOCKFILE(fp);
+ return (ret);
+ }
+ flags |= __SMBF;
+ }
+
+ /*
+ * Kill any seek optimization if the buffer is not the
+ * right size.
+ *
+ * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)?
+ */
+ if (size != iosize)
+ flags |= __SNPT;
+
+ /*
+ * Fix up the FILE fields, and set __cleanup for output flush on
+ * exit (since we are buffered in some way).
+ */
+ if (mode == _IOLBF)
+ flags |= __SLBF;
+ fp->_flags = flags;
+ fp->_bf._base = fp->_p = (unsigned char *)buf;
+ fp->_bf._size = size;
+ /* fp->_lbfsize is still 0 */
+ if (flags & __SWR) {
+ /*
+ * Begin or continue writing: see __swsetup(). Note
+ * that __SNBF is impossible (it was handled earlier).
+ */
+ if (flags & __SLBF) {
+ fp->_w = 0;
+ fp->_lbfsize = -fp->_bf._size;
+ } else
+ fp->_w = size;
+ } else {
+ /* begin/continue reading, or stay in intermediate state */
+ fp->_w = 0;
+ }
+ __cleanup = _cleanup;
+
+ FUNLOCKFILE(fp);
+ return (ret);
+}
diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c
new file mode 100644
index 0000000..bedf98d
--- /dev/null
+++ b/lib/libc/stdio/snprintf.c
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#if __STDC__
+int
+snprintf(char *str, size_t n, char const *fmt, ...)
+#else
+int
+snprintf(str, n, fmt, va_alist)
+ char *str;
+ size_t n;
+ char *fmt;
+ va_dcl
+#endif
+{
+ size_t on;
+ int ret;
+ va_list ap;
+ FILE f;
+
+ on = n;
+ if (n != 0)
+ n--;
+ if (n > INT_MAX)
+ n = INT_MAX;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ f._file = -1;
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = n;
+ ret = vfprintf(&f, fmt, ap);
+ if (on > 0)
+ *f._p = '\0';
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c
new file mode 100644
index 0000000..10e73f0
--- /dev/null
+++ b/lib/libc/stdio/sprintf.c
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)sprintf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <limits.h>
+#include "local.h"
+
+int
+#if __STDC__
+sprintf(char *str, char const *fmt, ...)
+#else
+sprintf(str, fmt, va_alist)
+ char *str;
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+ FILE f;
+
+ f._file = -1;
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = INT_MAX;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ ret = vfprintf(&f, fmt, ap);
+ va_end(ap);
+ *f._p = 0;
+ return (ret);
+}
diff --git a/lib/libc/stdio/sscanf.c b/lib/libc/stdio/sscanf.c
new file mode 100644
index 0000000..2ed797e
--- /dev/null
+++ b/lib/libc/stdio/sscanf.c
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)sscanf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include "local.h"
+
+static int eofread __P((void *, char *, int));
+
+/* ARGSUSED */
+static int
+eofread(cookie, buf, len)
+ void *cookie;
+ char *buf;
+ int len;
+{
+
+ return (0);
+}
+
+#if __STDC__
+int
+sscanf(const char *str, char const *fmt, ...)
+#else
+int
+sscanf(str, fmt, va_alist)
+ char *str;
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+ FILE f;
+
+ f._file = -1;
+ f._flags = __SRD;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._r = strlen(str);
+ f._read = eofread;
+ f._ub._base = NULL;
+ f._lb._base = NULL;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ ret = __svfscanf(&f, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libc/stdio/stdio.3 b/lib/libc/stdio/stdio.3
new file mode 100644
index 0000000..9648414
--- /dev/null
+++ b/lib/libc/stdio/stdio.3
@@ -0,0 +1,291 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)stdio.3 8.7 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt STDIO 3
+.Os BSD 4
+.Sh NAME
+.Nm stdio
+.Nd standard input/output library functions
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Fd FILE *stdin;
+.Fd FILE *stdout;
+.Fd FILE *stderr;
+.Sh DESCRIPTION
+The standard
+.Tn I/O
+library provides a simple and efficient buffered stream
+.Tn I/O
+interface.
+Input and output is mapped into logical data streams
+and the physical
+.Tn I/O
+characteristics are concealed. The functions and macros are listed
+below; more information is available from the individual man pages.
+.Pp
+A stream is associated with an external file (which may be a physical
+device) by
+.Em opening
+a file, which may involve creating a new file. Creating an
+existing file causes its former contents to be discarded.
+If a file can support positioning requests (such as a disk file, as opposed
+to a terminal) then a
+.Em file position indicator
+associated with the stream is positioned at the start of the file (byte
+zero), unless the file is opened with append mode. If append mode
+is used, the position indicator will be placed at the end-of-file.
+The position indicator is maintained by subsequent reads, writes
+and positioning requests. All input occurs as if the characters
+were read by successive calls to the
+.Xr fgetc 3
+function; all output takes place as if all characters were
+written by successive calls to the
+.Xr fputc 3
+function.
+.Pp
+A file is disassociated from a stream by
+.Em closing
+the file.
+Output streams are flushed (any unwritten buffer contents are transferred
+to the host environment) before the stream is disassociated from the file.
+The value of a pointer to a
+.Dv FILE
+object is indeterminate (garbage) after a file is closed.
+.Pp
+A file may be subsequently reopened, by the same or another program
+execution, and its contents reclaimed or modified (if it can be repositioned
+at the start). If the main function returns to its original caller, or
+the
+.Xr exit 3
+function is called, all open files are closed (hence all output
+streams are flushed) before program termination. Other methods
+of program termination may not close files properly and hence
+buffered output may be lost. In particular,
+.Xr _exit 2
+does not flush stdio files. Neither does an exit due to a signal.
+Buffers are flushed by
+.Xr abort 3
+as required by POSIX, although previous implementations did not.
+.Pp
+This implementation makes no distinction between
+.Dq text
+and
+.Dq binary
+streams.
+In effect, all streams are binary.
+No translation is performed and no extra padding appears on any stream.
+.Pp
+At program startup, three streams are predefined and need not be
+opened explicitly:
+.Bl -bullet -compact -offset indent
+.It
+.Em standard input
+(for reading conventional input),
+.It
+.Em standard output
+(for writing conventional output), and
+.It
+.Em standard error
+(for writing diagnostic output).
+.El
+These streams are abbreviated
+.Em stdin , stdout
+and
+.Em stderr .
+Initially, the standard error stream
+is unbuffered; the standard input and output streams are
+fully buffered if and only if the streams do not refer to
+an interactive or
+.Dq terminal
+device, as determined by the
+.Xr isatty 3
+function.
+In fact,
+.Em all
+freshly-opened streams that refer to terminal devices
+default to line buffering, and
+pending output to such streams is written automatically
+whenever such an input stream is read.
+Note that this applies only to
+.Dq "true reads" ;
+if the read request can be satisfied by existing buffered data,
+no automatic flush will occur.
+In these cases,
+or when a large amount of computation is done after printing
+part of a line on an output terminal, it is necessary to
+.Xr fflush 3
+the standard output before going off and computing so that the output
+will appear.
+Alternatively, these defaults may be modified via the
+.Xr setvbuf 3
+function.
+.Pp
+The
+.Nm stdio
+library is a part of the library
+.Nm libc
+and routines are automatically loaded as needed by the C compiler.
+The
+.Tn SYNOPSIS
+sections of the following manual pages indicate which include files
+are to be used, what the compiler declaration for the function
+looks like and which external variables are of interest.
+.Pp
+The following are defined as macros;
+these names may not be re-used
+without first removing their current definitions with
+.Dv #undef :
+.Dv BUFSIZ ,
+.Dv EOF ,
+.Dv FILENAME_MAX ,
+.Dv FOPEN_MAX ,
+.Dv L_cuserid ,
+.Dv L_ctermid ,
+.Dv L_tmpnam,
+.Dv NULL ,
+.Dv P_tmpdir,
+.Dv SEEK_CUR ,
+.Dv SEEK_END ,
+.Dv SEEK_SET ,
+.Dv TMP_MAX ,
+.Dv clearerr ,
+.Dv feof ,
+.Dv ferror ,
+.Dv fileno ,
+.Dv fropen ,
+.Dv fwopen ,
+.Dv getc ,
+.Dv getchar ,
+.Dv putc ,
+.Dv putchar ,
+.Dv stderr ,
+.Dv stdin ,
+.Dv stdout ,
+.Dv vfscanf .
+Function versions of the macro functions
+.Fn clearerr ,
+.Fn feof ,
+.Fn ferror ,
+.Fn fileno ,
+.Fn getc ,
+.Fn getchar ,
+.Fn putc ,
+and
+.Fn putchar
+exist and will be used if the macro
+definitions are explicitly removed.
+.Sh SEE ALSO
+.Xr close 2 ,
+.Xr open 2 ,
+.Xr read 2 ,
+.Xr write 2
+.Sh BUGS
+The standard buffered functions do not interact well with certain other
+library and system functions, especially
+.Xr vfork 2 .
+.Sh STANDARDS
+The
+.Nm stdio
+library conforms to
+.St -ansiC .
+.Sh LIST OF FUNCTIONS
+.Bl -column "Description"
+.Sy Function Description
+asprintf formatted output conversion
+clearerr check and reset stream status
+fclose close a stream
+fdopen stream open functions
+feof check and reset stream status
+ferror check and reset stream status
+fflush flush a stream
+fgetc get next character or word from input stream
+fgetln get a line from a stream
+fgetpos reposition a stream
+fgets get a line from a stream
+fileno check and reset stream status
+fopen stream open functions
+fprintf formatted output conversion
+fpurge flush a stream
+fputc output a character or word to a stream
+fputs output a line to a stream
+fread binary stream input/output
+freopen stream open functions
+fropen open a stream
+fscanf input format conversion
+fseek reposition a stream
+fsetpos reposition a stream
+ftell reposition a stream
+funopen open a stream
+fwopen open a stream
+fwrite binary stream input/output
+getc get next character or word from input stream
+getchar get next character or word from input stream
+gets get a line from a stream
+getw get next character or word from input stream
+mkdtemp create unique temporary file
+mkstemp create unique temporary file
+mktemp create unique temporary file
+perror system error messages
+printf formatted output conversion
+putc output a character or word to a stream
+putchar output a character or word to a stream
+puts output a line to a stream
+putw output a character or word to a stream
+remove remove directory entry
+rewind reposition a stream
+scanf input format conversion
+setbuf stream buffering operations
+setbuffer stream buffering operations
+setlinebuf stream buffering operations
+setvbuf stream buffering operations
+snprintf formatted output conversion
+sprintf formatted output conversion
+sscanf input format conversion
+strerror system error messages
+sys_errlist system error messages
+sys_nerr system error messages
+tempnam temporary file routines
+tmpfile temporary file routines
+tmpnam temporary file routines
+ungetc un-get character from input stream
+vasprintf formatted output conversion
+vfprintf formatted output conversion
+vfscanf input format conversion
+vprintf formatted output conversion
+vscanf input format conversion
+vsnprintf formatted output conversion
+vsprintf formatted output conversion
+vsscanf input format conversion
+.El
diff --git a/lib/libc/stdio/stdio.c b/lib/libc/stdio/stdio.c
new file mode 100644
index 0000000..e12dc28
--- /dev/null
+++ b/lib/libc/stdio/stdio.c
@@ -0,0 +1,111 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)stdio.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "local.h"
+
+/*
+ * Small standard I/O/seek/close functions.
+ * These maintain the `known seek offset' for seek optimisation.
+ */
+int
+__sread(cookie, buf, n)
+ void *cookie;
+ char *buf;
+ int n;
+{
+ register FILE *fp = cookie;
+ register int ret;
+
+ ret = read(fp->_file, buf, (size_t)n);
+ /* if the read succeeded, update the current offset */
+ if (ret >= 0)
+ fp->_offset += ret;
+ else
+ fp->_flags &= ~__SOFF; /* paranoia */
+ return (ret);
+}
+
+int
+__swrite(cookie, buf, n)
+ void *cookie;
+ char const *buf;
+ int n;
+{
+ register FILE *fp = cookie;
+
+ if (fp->_flags & __SAPP)
+ (void) lseek(fp->_file, (off_t)0, SEEK_END);
+ fp->_flags &= ~__SOFF; /* in case FAPPEND mode is set */
+ return (write(fp->_file, buf, (size_t)n));
+}
+
+fpos_t
+__sseek(cookie, offset, whence)
+ void *cookie;
+ fpos_t offset;
+ int whence;
+{
+ register FILE *fp = cookie;
+ register off_t ret;
+
+ ret = lseek(fp->_file, (off_t)offset, whence);
+ if (ret == -1)
+ fp->_flags &= ~__SOFF;
+ else {
+ fp->_flags |= __SOFF;
+ fp->_offset = ret;
+ }
+ return (ret);
+}
+
+int
+__sclose(cookie)
+ void *cookie;
+{
+
+ return (close(((FILE *)cookie)->_file));
+}
diff --git a/lib/libc/stdio/tempnam.c b/lib/libc/stdio/tempnam.c
new file mode 100644
index 0000000..dc34c7d
--- /dev/null
+++ b/lib/libc/stdio/tempnam.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)tempnam.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <paths.h>
+
+__warn_references(tempnam,
+ "warning: tempnam() possibly used unsafely; consider using mkstemp()");
+
+extern char *_mktemp __P((char *));
+
+char *
+tempnam(dir, pfx)
+ const char *dir, *pfx;
+{
+ int sverrno;
+ char *f, *name;
+
+ if (!(name = malloc(MAXPATHLEN)))
+ return(NULL);
+
+ if (!pfx)
+ pfx = "tmp.";
+
+ if (issetugid() == 0 && (f = getenv("TMPDIR"))) {
+ (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
+ *(f + strlen(f) - 1) == '/'? "": "/", pfx);
+ if ((f = _mktemp(name)))
+ return(f);
+ }
+
+ if ((f = (char *)dir)) {
+ (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
+ *(f + strlen(f) - 1) == '/'? "": "/", pfx);
+ if ((f = _mktemp(name)))
+ return(f);
+ }
+
+ f = P_tmpdir;
+ (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
+ if ((f = _mktemp(name)))
+ return(f);
+
+ f = _PATH_TMP;
+ (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
+ if ((f = _mktemp(name)))
+ return(f);
+
+ sverrno = errno;
+ free(name);
+ errno = sverrno;
+ return(NULL);
+}
diff --git a/lib/libc/stdio/tmpfile.c b/lib/libc/stdio/tmpfile.c
new file mode 100644
index 0000000..3c5e97e
--- /dev/null
+++ b/lib/libc/stdio/tmpfile.c
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)tmpfile.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <paths.h>
+
+FILE *
+tmpfile()
+{
+ sigset_t set, oset;
+ FILE *fp;
+ int fd, sverrno;
+#define TRAILER "tmp.XXXXXX"
+ char buf[sizeof(_PATH_TMP) + sizeof(TRAILER)];
+
+ (void)memcpy(buf, _PATH_TMP, sizeof(_PATH_TMP) - 1);
+ (void)memcpy(buf + sizeof(_PATH_TMP) - 1, TRAILER, sizeof(TRAILER));
+
+ sigfillset(&set);
+ (void)sigprocmask(SIG_BLOCK, &set, &oset);
+
+ fd = mkstemp(buf);
+ if (fd != -1)
+ (void)unlink(buf);
+
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+
+ if (fd == -1)
+ return (NULL);
+
+ if ((fp = fdopen(fd, "w+")) == NULL) {
+ sverrno = errno;
+ (void)close(fd);
+ errno = sverrno;
+ return (NULL);
+ }
+ return (fp);
+}
diff --git a/lib/libc/stdio/tmpnam.3 b/lib/libc/stdio/tmpnam.3
new file mode 100644
index 0000000..f42dc25
--- /dev/null
+++ b/lib/libc/stdio/tmpnam.3
@@ -0,0 +1,220 @@
+.\" Copyright (c) 1988, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tmpnam.3 8.2 (Berkeley) 11/17/93
+.\" $FreeBSD$
+.\"
+.Dd November 17, 1993
+.Dt TMPFILE 3
+.Os
+.Sh NAME
+.Nm tempnam ,
+.Nm tmpfile ,
+.Nm tmpnam
+.Nd temporary file routines
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft FILE *
+.Fn tmpfile void
+.Ft char *
+.Fn tmpnam "char *str"
+.Ft char *
+.Fn tempnam "const char *tmpdir" "const char *prefix"
+.Sh DESCRIPTION
+The
+.Fn tmpfile
+function
+returns a pointer to a stream associated with a file descriptor returned
+by the routine
+.Xr mkstemp 3 .
+The created file is unlinked before
+.Fn tmpfile
+returns, causing the file to be automatically deleted when the last
+reference to it is closed.
+The file is opened with the access value
+.Ql w+ .
+.Pp
+The
+.Fn tmpnam
+function
+returns a pointer to a file name, in the
+.Dv P_tmpdir
+directory, which
+did not reference an existing file at some indeterminate point in the
+past.
+.Dv P_tmpdir
+is defined in the include file
+.Aq Pa stdio.h .
+If the argument
+.Fa s
+is
+.Pf non- Dv NULL ,
+the file name is copied to the buffer it references.
+Otherwise, the file name is copied to a static buffer.
+In either case,
+.Fn tmpnam
+returns a pointer to the file name.
+.Pp
+The buffer referenced by
+.Fa s
+is expected to be at least
+.Dv L_tmpnam
+bytes in length.
+.Dv L_tmpnam
+is defined in the include file
+.Aq Pa stdio.h .
+.Pp
+The
+.Fn tempnam
+function
+is similar to
+.Fn tmpnam ,
+but provides the ability to specify the directory which will
+contain the temporary file and the file name prefix.
+.Pp
+The environment variable
+.Ev TMPDIR
+(if set), the argument
+.Fa tmpdir
+(if
+.Pf non- Dv NULL ) ,
+the directory
+.Dv P_tmpdir ,
+and the directory
+.Pa /tmp
+are tried, in the listed order, as directories in which to store the
+temporary file.
+.Pp
+The argument
+.Fa prefix ,
+if
+.Pf non- Dv NULL ,
+is used to specify a file name prefix, which will be the
+first part of the created file name.
+.Fn Tempnam
+allocates memory in which to store the file name; the returned pointer
+may be used as a subsequent argument to
+.Xr free 3 .
+.Sh RETURN VALUES
+The
+.Fn tmpfile
+function
+returns a pointer to an open file stream on success, and a
+.Dv NULL
+pointer
+on error.
+.Pp
+The
+.Fn tmpnam
+and
+.Fn tempfile
+functions
+return a pointer to a file name on success, and a
+.Dv NULL
+pointer
+on error.
+.Sh ERRORS
+The
+.Fn tmpfile
+function
+may fail and set the global variable
+.Va errno
+for any of the errors specified for the library functions
+.Xr fdopen 3
+or
+.Xr mkstemp 3 .
+.Pp
+The
+.Fn tmpnam
+function
+may fail and set
+.Va errno
+for any of the errors specified for the library function
+.Xr mktemp 3 .
+.Pp
+The
+.Fn tempnam
+function
+may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr malloc 3
+or
+.Xr mktemp 3 .
+.Sh SEE ALSO
+.Xr mkstemp 3 ,
+.Xr mktemp 3
+.Sh STANDARDS
+The
+.Fn tmpfile
+and
+.Fn tmpnam
+functions
+conform to
+.St -ansiC .
+.Sh BUGS
+These interfaces are provided for System V and
+.Tn ANSI
+compatibility only.
+The
+.Xr mkstemp 3
+interface is strongly preferred.
+.Pp
+There are four important problems with these interfaces (as well as
+with the historic
+.Xr mktemp 3
+interface).
+First, there is an obvious race between file name selection and file
+creation and deletion.
+Second, most historic implementations provide only a limited number
+of possible temporary file names (usually 26) before file names will
+start being recycled.
+Third, the System V implementations of these functions (and of
+.Xr mktemp 3 )
+use the
+.Xr access 2
+function to determine whether or not the temporary file may be created.
+This has obvious ramifications for setuid or setgid programs, complicating
+the portable use of these interfaces in such programs.
+Finally, there is no specification of the permissions with which the
+temporary files are created.
+.Pp
+This implementation does not have these flaws, but portable software
+cannot depend on that.
+In particular, the
+.Fn tmpfile
+interface should not be used in software expected to be used on other systems
+if there is any possibility that the user does not wish the temporary file to
+be publicly readable and writable.
diff --git a/lib/libc/stdio/tmpnam.c b/lib/libc/stdio/tmpnam.c
new file mode 100644
index 0000000..ff1c038
--- /dev/null
+++ b/lib/libc/stdio/tmpnam.c
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)tmpnam.c 8.3 (Berkeley) 3/28/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+__warn_references(tmpnam,
+ "warning: tmpnam() possibly used unsafely; consider using mkstemp()");
+
+extern char *_mktemp __P((char *));
+
+char *
+tmpnam(s)
+ char *s;
+{
+ static u_long tmpcount;
+ static char buf[L_tmpnam];
+
+ if (s == NULL)
+ s = buf;
+ (void)snprintf(s, L_tmpnam, "%stmp.%lu.XXXXXX", P_tmpdir, tmpcount);
+ ++tmpcount;
+ return (_mktemp(s));
+}
diff --git a/lib/libc/stdio/ungetc.3 b/lib/libc/stdio/ungetc.3
new file mode 100644
index 0000000..173513a
--- /dev/null
+++ b/lib/libc/stdio/ungetc.3
@@ -0,0 +1,96 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ungetc.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt UNGETC 3
+.Os
+.Sh NAME
+.Nm ungetc
+.Nd un-get character from input stream
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft int
+.Fn ungetc "int c" "FILE *stream"
+.Sh DESCRIPTION
+The
+.Fn ungetc
+function pushes the character
+.Fa c
+(converted to an unsigned char)
+back onto the input stream pointed to by
+.Fa stream .
+The pushed-backed characters will be returned by subsequent reads on the
+stream (in reverse order).
+A successful intervening call, using the same stream, to one of the file
+positioning functions
+.Po
+.Xr fseek 3 ,
+.Xr fsetpos 3 ,
+or
+.Xr rewind 3
+.Pc
+will discard the pushed back characters.
+.Pp
+One character of push-back is guaranteed,
+but as long as there is
+sufficient memory, an effectively infinite amount of pushback is allowed.
+.Pp
+If a character is successfully pushed-back,
+the end-of-file indicator for the stream is cleared.
+.Sh RETURN VALUES
+The
+.Fn ungetc
+function
+returns
+the character pushed-back after the conversion, or
+.Dv EOF
+if the operation fails.
+If the value of the argument
+.Fa c
+character equals
+.Dv EOF ,
+the operation will fail and the stream will remain unchanged.
+.Sh SEE ALSO
+.Xr fseek 3 ,
+.Xr getc 3 ,
+.Xr setvbuf 3
+.Sh STANDARDS
+The
+.Fn ungetc
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/stdio/ungetc.c b/lib/libc/stdio/ungetc.c
new file mode 100644
index 0000000..3f4b32c
--- /dev/null
+++ b/lib/libc/stdio/ungetc.c
@@ -0,0 +1,166 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)ungetc.c 8.2 (Berkeley) 11/3/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "local.h"
+#include "libc_private.h"
+
+static int __submore __P((FILE *));
+
+/*
+ * Expand the ungetc buffer `in place'. That is, adjust fp->_p when
+ * the buffer moves, so that it points the same distance from the end,
+ * and move the bytes in the buffer around as necessary so that they
+ * are all at the end (stack-style).
+ */
+static int
+__submore(fp)
+ register FILE *fp;
+{
+ register int i;
+ register unsigned char *p;
+
+ if (fp->_ub._base == fp->_ubuf) {
+ /*
+ * Get a new buffer (rather than expanding the old one).
+ */
+ if ((p = malloc((size_t)BUFSIZ)) == NULL)
+ return (EOF);
+ fp->_ub._base = p;
+ fp->_ub._size = BUFSIZ;
+ p += BUFSIZ - sizeof(fp->_ubuf);
+ for (i = sizeof(fp->_ubuf); --i >= 0;)
+ p[i] = fp->_ubuf[i];
+ fp->_p = p;
+ return (0);
+ }
+ i = fp->_ub._size;
+ p = realloc(fp->_ub._base, (size_t)(i << 1));
+ if (p == NULL)
+ return (EOF);
+ /* no overlap (hence can use memcpy) because we doubled the size */
+ (void)memcpy((void *)(p + i), (void *)p, (size_t)i);
+ fp->_p = p + i;
+ fp->_ub._base = p;
+ fp->_ub._size = i << 1;
+ return (0);
+}
+
+int
+ungetc(c, fp)
+ int c;
+ register FILE *fp;
+{
+ if (c == EOF)
+ return (EOF);
+ if (!__sdidinit)
+ __sinit();
+ FLOCKFILE(fp);
+ if ((fp->_flags & __SRD) == 0) {
+ /*
+ * Not already reading: no good unless reading-and-writing.
+ * Otherwise, flush any current write stuff.
+ */
+ if ((fp->_flags & __SRW) == 0) {
+ FUNLOCKFILE(fp);
+ return (EOF);
+ }
+ if (fp->_flags & __SWR) {
+ if (__sflush(fp)) {
+ FUNLOCKFILE(fp);
+ return (EOF);
+ }
+ fp->_flags &= ~__SWR;
+ fp->_w = 0;
+ fp->_lbfsize = 0;
+ }
+ fp->_flags |= __SRD;
+ }
+ c = (unsigned char)c;
+
+ /*
+ * If we are in the middle of ungetc'ing, just continue.
+ * This may require expanding the current ungetc buffer.
+ */
+ if (HASUB(fp)) {
+ if (fp->_r >= fp->_ub._size && __submore(fp)) {
+ FUNLOCKFILE(fp);
+ return (EOF);
+ }
+ *--fp->_p = c;
+ fp->_r++;
+ FUNLOCKFILE(fp);
+ return (c);
+ }
+ fp->_flags &= ~__SEOF;
+
+ /*
+ * If we can handle this by simply backing up, do so,
+ * but never replace the original character.
+ * (This makes sscanf() work when scanning `const' data.)
+ */
+ if (fp->_bf._base != NULL && fp->_p > fp->_bf._base &&
+ fp->_p[-1] == c) {
+ fp->_p--;
+ fp->_r++;
+ FUNLOCKFILE(fp);
+ return (c);
+ }
+
+ /*
+ * Create an ungetc buffer.
+ * Initially, we will use the `reserve' buffer.
+ */
+ fp->_ur = fp->_r;
+ fp->_up = fp->_p;
+ fp->_ub._base = fp->_ubuf;
+ fp->_ub._size = sizeof(fp->_ubuf);
+ fp->_ubuf[sizeof(fp->_ubuf) - 1] = c;
+ fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1];
+ fp->_r = 1;
+ FUNLOCKFILE(fp);
+ return (c);
+}
diff --git a/lib/libc/stdio/vasprintf.c b/lib/libc/stdio/vasprintf.c
new file mode 100644
index 0000000..37fb0fd
--- /dev/null
+++ b/lib/libc/stdio/vasprintf.c
@@ -0,0 +1,65 @@
+/* $OpenBSD: vasprintf.c,v 1.4 1998/06/21 22:13:47 millert Exp $ */
+
+/*
+ * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+int
+vasprintf(str, fmt, ap)
+ char **str;
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ int ret;
+ FILE f;
+
+ f._file = -1;
+ f._flags = __SWR | __SSTR | __SALC;
+ f._bf._base = f._p = (unsigned char *)malloc(128);
+ if (f._bf._base == NULL) {
+ *str = NULL;
+ errno = ENOMEM;
+ return (-1);
+ }
+ f._bf._size = f._w = 127; /* Leave room for the NULL */
+ ret = vfprintf(&f, fmt, ap);
+ *f._p = '\0';
+ f._bf._base = reallocf(f._bf._base, f._bf._size + 1);
+ if (f._bf._base == NULL) {
+ errno = ENOMEM;
+ ret = -1;
+ }
+ *str = (char *)f._bf._base;
+ return (ret);
+}
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
new file mode 100644
index 0000000..44fd34b
--- /dev/null
+++ b/lib/libc/stdio/vfprintf.c
@@ -0,0 +1,1278 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Actual printf innards.
+ *
+ * This code is large and complicated...
+ */
+
+#include <sys/types.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#include "local.h"
+#include "fvwrite.h"
+#include "libc_private.h"
+
+/* Define FLOATING_POINT to get floating point. */
+#define FLOATING_POINT
+
+static int __sprint __P((FILE *, struct __suio *));
+static int __sbprintf __P((FILE *, const char *, va_list));
+static char * __ultoa __P((u_long, char *, int, int, char *));
+static char * __uqtoa __P((u_quad_t, char *, int, int, char *));
+static void __find_arguments __P((const char *, va_list, void ***));
+static void __grow_type_table __P((int, unsigned char **, int *));
+
+/*
+ * Flush out all the vectors defined by the given uio,
+ * then reset it so that it can be reused.
+ */
+static int
+__sprint(fp, uio)
+ FILE *fp;
+ register struct __suio *uio;
+{
+ register int err;
+
+ if (uio->uio_resid == 0) {
+ uio->uio_iovcnt = 0;
+ return (0);
+ }
+ err = __sfvwrite(fp, uio);
+ uio->uio_resid = 0;
+ uio->uio_iovcnt = 0;
+ return (err);
+}
+
+/*
+ * Helper function for `fprintf to unbuffered unix file': creates a
+ * temporary buffer. We only work on write-only files; this avoids
+ * worries about ungetc buffers and so forth.
+ */
+static int
+__sbprintf(fp, fmt, ap)
+ register FILE *fp;
+ const char *fmt;
+ va_list ap;
+{
+ int ret;
+ FILE fake;
+ unsigned char buf[BUFSIZ];
+
+ /* copy the important variables */
+ fake._flags = fp->_flags & ~__SNBF;
+ fake._file = fp->_file;
+ fake._cookie = fp->_cookie;
+ fake._write = fp->_write;
+
+ /* set up the buffer */
+ fake._bf._base = fake._p = buf;
+ fake._bf._size = fake._w = sizeof(buf);
+ fake._lbfsize = 0; /* not actually used, but Just In Case */
+
+ /* do the work, then copy any error status */
+ ret = vfprintf(&fake, fmt, ap);
+ if (ret >= 0 && fflush(&fake))
+ ret = EOF;
+ if (fake._flags & __SERR)
+ fp->_flags |= __SERR;
+ return (ret);
+}
+
+/*
+ * Macros for converting digits to letters and vice versa
+ */
+#define to_digit(c) ((c) - '0')
+#define is_digit(c) ((unsigned)to_digit(c) <= 9)
+#define to_char(n) ((n) + '0')
+
+/*
+ * Convert an unsigned long to ASCII for printf purposes, returning
+ * a pointer to the first character of the string representation.
+ * Octal numbers can be forced to have a leading zero; hex numbers
+ * use the given digits.
+ */
+static char *
+__ultoa(val, endp, base, octzero, xdigs)
+ register u_long val;
+ char *endp;
+ int base, octzero;
+ char *xdigs;
+{
+ register char *cp = endp;
+ register long sval;
+
+ /*
+ * Handle the three cases separately, in the hope of getting
+ * better/faster code.
+ */
+ switch (base) {
+ case 10:
+ if (val < 10) { /* many numbers are 1 digit */
+ *--cp = to_char(val);
+ return (cp);
+ }
+ /*
+ * On many machines, unsigned arithmetic is harder than
+ * signed arithmetic, so we do at most one unsigned mod and
+ * divide; this is sufficient to reduce the range of
+ * the incoming value to where signed arithmetic works.
+ */
+ if (val > LONG_MAX) {
+ *--cp = to_char(val % 10);
+ sval = val / 10;
+ } else
+ sval = val;
+ do {
+ *--cp = to_char(sval % 10);
+ sval /= 10;
+ } while (sval != 0);
+ break;
+
+ case 8:
+ do {
+ *--cp = to_char(val & 7);
+ val >>= 3;
+ } while (val);
+ if (octzero && *cp != '0')
+ *--cp = '0';
+ break;
+
+ case 16:
+ do {
+ *--cp = xdigs[val & 15];
+ val >>= 4;
+ } while (val);
+ break;
+
+ default: /* oops */
+ abort();
+ }
+ return (cp);
+}
+
+/* Identical to __ultoa, but for quads. */
+static char *
+__uqtoa(val, endp, base, octzero, xdigs)
+ register u_quad_t val;
+ char *endp;
+ int base, octzero;
+ char *xdigs;
+{
+ register char *cp = endp;
+ register quad_t sval;
+
+ /* quick test for small values; __ultoa is typically much faster */
+ /* (perhaps instead we should run until small, then call __ultoa?) */
+ if (val <= ULONG_MAX)
+ return (__ultoa((u_long)val, endp, base, octzero, xdigs));
+ switch (base) {
+ case 10:
+ if (val < 10) {
+ *--cp = to_char(val % 10);
+ return (cp);
+ }
+ if (val > QUAD_MAX) {
+ *--cp = to_char(val % 10);
+ sval = val / 10;
+ } else
+ sval = val;
+ do {
+ *--cp = to_char(sval % 10);
+ sval /= 10;
+ } while (sval != 0);
+ break;
+
+ case 8:
+ do {
+ *--cp = to_char(val & 7);
+ val >>= 3;
+ } while (val);
+ if (octzero && *cp != '0')
+ *--cp = '0';
+ break;
+
+ case 16:
+ do {
+ *--cp = xdigs[val & 15];
+ val >>= 4;
+ } while (val);
+ break;
+
+ default:
+ abort();
+ }
+ return (cp);
+}
+
+#ifdef FLOATING_POINT
+#include <math.h>
+#include "floatio.h"
+
+#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
+#define DEFPREC 6
+
+static char *cvt __P((double, int, int, char *, int *, int, int *));
+static int exponent __P((char *, int, int));
+
+#else /* no FLOATING_POINT */
+
+#define BUF 68
+
+#endif /* FLOATING_POINT */
+
+#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
+
+/*
+ * Flags used during conversion.
+ */
+#define ALT 0x001 /* alternate form */
+#define HEXPREFIX 0x002 /* add 0x or 0X prefix */
+#define LADJUST 0x004 /* left adjustment */
+#define LONGDBL 0x008 /* long double */
+#define LONGINT 0x010 /* long integer */
+#define QUADINT 0x020 /* quad integer */
+#define SHORTINT 0x040 /* short integer */
+#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
+#define FPT 0x100 /* Floating point number */
+int
+vfprintf(fp, fmt0, ap)
+ FILE *fp;
+ const char *fmt0;
+ va_list ap;
+{
+ register char *fmt; /* format string */
+ register int ch; /* character from fmt */
+ register int n, n2; /* handy integer (short term usage) */
+ register char *cp; /* handy char pointer (short term usage) */
+ register struct __siov *iovp;/* for PRINT macro */
+ register int flags; /* flags as above */
+ int ret; /* return value accumulator */
+ int width; /* width from format (%8d), or 0 */
+ int prec; /* precision from format (%.3d), or -1 */
+ char sign; /* sign prefix (' ', '+', '-', or \0) */
+#ifdef FLOATING_POINT
+ char softsign; /* temporary negative sign for floats */
+ double _double; /* double precision arguments %[eEfgG] */
+ int expt; /* integer value of exponent */
+ int expsize; /* character count for expstr */
+ int ndig; /* actual number of digits returned by cvt */
+ char expstr[7]; /* buffer for exponent string */
+#endif
+ u_long ulval; /* integer arguments %[diouxX] */
+ u_quad_t uqval; /* %q integers */
+ int base; /* base for [diouxX] conversion */
+ int dprec; /* a copy of prec if [diouxX], 0 otherwise */
+ int realsz; /* field size expanded by dprec, sign, etc */
+ int size; /* size of converted field or string */
+ int prsize; /* max size of printed field */
+ char *xdigs; /* digits for [xX] conversion */
+#define NIOV 8
+ struct __suio uio; /* output information: summary */
+ struct __siov iov[NIOV];/* ... and individual io vectors */
+ char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
+ char ox[2]; /* space for 0x hex-prefix */
+ void **argtable; /* args, built due to positional arg */
+ void *statargtable [STATIC_ARG_TBL_SIZE];
+ int nextarg; /* 1-based argument index */
+ va_list orgap; /* original argument pointer */
+
+ /*
+ * Choose PADSIZE to trade efficiency vs. size. If larger printf
+ * fields occur frequently, increase PADSIZE and make the initialisers
+ * below longer.
+ */
+#define PADSIZE 16 /* pad chunk size */
+ static char blanks[PADSIZE] =
+ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
+ static char zeroes[PADSIZE] =
+ {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+
+ /*
+ * BEWARE, these `goto error' on error, and PAD uses `n'.
+ */
+#define PRINT(ptr, len) { \
+ iovp->iov_base = (ptr); \
+ iovp->iov_len = (len); \
+ uio.uio_resid += (len); \
+ iovp++; \
+ if (++uio.uio_iovcnt >= NIOV) { \
+ if (__sprint(fp, &uio)) \
+ goto error; \
+ iovp = iov; \
+ } \
+}
+#define PAD(howmany, with) { \
+ if ((n = (howmany)) > 0) { \
+ while (n > PADSIZE) { \
+ PRINT(with, PADSIZE); \
+ n -= PADSIZE; \
+ } \
+ PRINT(with, n); \
+ } \
+}
+#define FLUSH() { \
+ if (uio.uio_resid && __sprint(fp, &uio)) \
+ goto error; \
+ uio.uio_iovcnt = 0; \
+ iovp = iov; \
+}
+
+ /*
+ * Get the argument indexed by nextarg. If the argument table is
+ * built, use it to get the argument. If its not, get the next
+ * argument (and arguments must be gotten sequentially).
+ */
+#define GETARG(type) \
+ ((argtable != NULL) ? *((type*)(argtable[nextarg++])) : \
+ (nextarg++, va_arg(ap, type)))
+
+ /*
+ * To extend shorts properly, we need both signed and unsigned
+ * argument extraction methods.
+ */
+#define SARG() \
+ (flags&LONGINT ? GETARG(long) : \
+ flags&SHORTINT ? (long)(short)GETARG(int) : \
+ (long)GETARG(int))
+#define UARG() \
+ (flags&LONGINT ? GETARG(u_long) : \
+ flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \
+ (u_long)GETARG(u_int))
+
+ /*
+ * Get * arguments, including the form *nn$. Preserve the nextarg
+ * that the argument can be gotten once the type is determined.
+ */
+#define GETASTER(val) \
+ n2 = 0; \
+ cp = fmt; \
+ while (is_digit(*cp)) { \
+ n2 = 10 * n2 + to_digit(*cp); \
+ cp++; \
+ } \
+ if (*cp == '$') { \
+ int hold = nextarg; \
+ if (argtable == NULL) { \
+ argtable = statargtable; \
+ __find_arguments (fmt0, orgap, &argtable); \
+ } \
+ nextarg = n2; \
+ val = GETARG (int); \
+ nextarg = hold; \
+ fmt = ++cp; \
+ } else { \
+ val = GETARG (int); \
+ }
+
+
+ FLOCKFILE(fp);
+ /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
+ if (cantwrite(fp)) {
+ FUNLOCKFILE(fp);
+ return (EOF);
+ }
+
+ /* optimise fprintf(stderr) (and other unbuffered Unix files) */
+ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
+ fp->_file >= 0) {
+ FUNLOCKFILE(fp);
+ return (__sbprintf(fp, fmt0, ap));
+ }
+
+ fmt = (char *)fmt0;
+ argtable = NULL;
+ nextarg = 1;
+ orgap = ap;
+ uio.uio_iov = iovp = iov;
+ uio.uio_resid = 0;
+ uio.uio_iovcnt = 0;
+ ret = 0;
+
+ /*
+ * Scan the format for conversions (`%' character).
+ */
+ for (;;) {
+ for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
+ /* void */;
+ if ((n = fmt - cp) != 0) {
+ if ((unsigned)ret + n > INT_MAX) {
+ ret = EOF;
+ goto error;
+ }
+ PRINT(cp, n);
+ ret += n;
+ }
+ if (ch == '\0')
+ goto done;
+ fmt++; /* skip over '%' */
+
+ flags = 0;
+ dprec = 0;
+ width = 0;
+ prec = -1;
+ sign = '\0';
+
+rflag: ch = *fmt++;
+reswitch: switch (ch) {
+ case ' ':
+ /*
+ * ``If the space and + flags both appear, the space
+ * flag will be ignored.''
+ * -- ANSI X3J11
+ */
+ if (!sign)
+ sign = ' ';
+ goto rflag;
+ case '#':
+ flags |= ALT;
+ goto rflag;
+ case '*':
+ /*
+ * ``A negative field width argument is taken as a
+ * - flag followed by a positive field width.''
+ * -- ANSI X3J11
+ * They don't exclude field widths read from args.
+ */
+ GETASTER (width);
+ if (width >= 0)
+ goto rflag;
+ width = -width;
+ /* FALLTHROUGH */
+ case '-':
+ flags |= LADJUST;
+ goto rflag;
+ case '+':
+ sign = '+';
+ goto rflag;
+ case '.':
+ if ((ch = *fmt++) == '*') {
+ GETASTER (n);
+ prec = n < 0 ? -1 : n;
+ goto rflag;
+ }
+ n = 0;
+ while (is_digit(ch)) {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ }
+ prec = n < 0 ? -1 : n;
+ goto reswitch;
+ case '0':
+ /*
+ * ``Note that 0 is taken as a flag, not as the
+ * beginning of a field width.''
+ * -- ANSI X3J11
+ */
+ flags |= ZEROPAD;
+ goto rflag;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = 0;
+ do {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ } while (is_digit(ch));
+ if (ch == '$') {
+ nextarg = n;
+ if (argtable == NULL) {
+ argtable = statargtable;
+ __find_arguments (fmt0, orgap,
+ &argtable);
+ }
+ goto rflag;
+ }
+ width = n;
+ goto reswitch;
+#ifdef FLOATING_POINT
+ case 'L':
+ flags |= LONGDBL;
+ goto rflag;
+#endif
+ case 'h':
+ flags |= SHORTINT;
+ goto rflag;
+ case 'l':
+ if (flags & LONGINT)
+ flags |= QUADINT;
+ else
+ flags |= LONGINT;
+ goto rflag;
+ case 'q':
+ flags |= QUADINT;
+ goto rflag;
+ case 'c':
+ *(cp = buf) = GETARG(int);
+ size = 1;
+ sign = '\0';
+ break;
+ case 'D':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'd':
+ case 'i':
+ if (flags & QUADINT) {
+ uqval = GETARG(quad_t);
+ if ((quad_t)uqval < 0) {
+ uqval = -uqval;
+ sign = '-';
+ }
+ } else {
+ ulval = SARG();
+ if ((long)ulval < 0) {
+ ulval = -ulval;
+ sign = '-';
+ }
+ }
+ base = 10;
+ goto number;
+#ifdef FLOATING_POINT
+ case 'e':
+ case 'E':
+ case 'f':
+ goto fp_begin;
+ case 'g':
+ case 'G':
+ if (prec == 0)
+ prec = 1;
+fp_begin: if (prec == -1)
+ prec = DEFPREC;
+ if (flags & LONGDBL)
+ /* XXX this loses precision. */
+ _double = (double)GETARG(long double);
+ else
+ _double = GETARG(double);
+ /* do this before tricky precision changes */
+ if (isinf(_double)) {
+ if (_double < 0)
+ sign = '-';
+ cp = "Inf";
+ size = 3;
+ break;
+ }
+ if (isnan(_double)) {
+ cp = "NaN";
+ size = 3;
+ break;
+ }
+ flags |= FPT;
+ cp = cvt(_double, prec, flags, &softsign,
+ &expt, ch, &ndig);
+ if (ch == 'g' || ch == 'G') {
+ if (expt <= -4 || expt > prec)
+ ch = (ch == 'g') ? 'e' : 'E';
+ else
+ ch = 'g';
+ }
+ if (ch <= 'e') { /* 'e' or 'E' fmt */
+ --expt;
+ expsize = exponent(expstr, expt, ch);
+ size = expsize + ndig;
+ if (ndig > 1 || flags & ALT)
+ ++size;
+ } else if (ch == 'f') { /* f fmt */
+ if (expt > 0) {
+ size = expt;
+ if (prec || flags & ALT)
+ size += prec + 1;
+ } else /* "0.X" */
+ size = prec + 2;
+ } else if (expt >= ndig) { /* fixed g fmt */
+ size = expt;
+ if (flags & ALT)
+ ++size;
+ } else
+ size = ndig + (expt > 0 ?
+ 1 : 2 - expt);
+
+ if (softsign)
+ sign = '-';
+ break;
+#endif /* FLOATING_POINT */
+ case 'n':
+ if (flags & QUADINT)
+ *GETARG(quad_t *) = ret;
+ else if (flags & LONGINT)
+ *GETARG(long *) = ret;
+ else if (flags & SHORTINT)
+ *GETARG(short *) = ret;
+ else
+ *GETARG(int *) = ret;
+ continue; /* no output */
+ case 'O':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'o':
+ if (flags & QUADINT)
+ uqval = GETARG(u_quad_t);
+ else
+ ulval = UARG();
+ base = 8;
+ goto nosign;
+ case 'p':
+ /*
+ * ``The argument shall be a pointer to void. The
+ * value of the pointer is converted to a sequence
+ * of printable characters, in an implementation-
+ * defined manner.''
+ * -- ANSI X3J11
+ */
+ ulval = (u_long)GETARG(void *);
+ base = 16;
+ xdigs = "0123456789abcdef";
+ flags = (flags & ~QUADINT) | HEXPREFIX;
+ ch = 'x';
+ goto nosign;
+ case 's':
+ if ((cp = GETARG(char *)) == NULL)
+ cp = "(null)";
+ if (prec >= 0) {
+ /*
+ * can't use strlen; can only look for the
+ * NUL in the first `prec' characters, and
+ * strlen() will go further.
+ */
+ char *p = memchr(cp, 0, (size_t)prec);
+
+ if (p != NULL) {
+ size = p - cp;
+ if (size > prec)
+ size = prec;
+ } else
+ size = prec;
+ } else
+ size = strlen(cp);
+ sign = '\0';
+ break;
+ case 'U':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'u':
+ if (flags & QUADINT)
+ uqval = GETARG(u_quad_t);
+ else
+ ulval = UARG();
+ base = 10;
+ goto nosign;
+ case 'X':
+ xdigs = "0123456789ABCDEF";
+ goto hex;
+ case 'x':
+ xdigs = "0123456789abcdef";
+hex: if (flags & QUADINT)
+ uqval = GETARG(u_quad_t);
+ else
+ ulval = UARG();
+ base = 16;
+ /* leading 0x/X only if non-zero */
+ if (flags & ALT &&
+ (flags & QUADINT ? uqval != 0 : ulval != 0))
+ flags |= HEXPREFIX;
+
+ /* unsigned conversions */
+nosign: sign = '\0';
+ /*
+ * ``... diouXx conversions ... if a precision is
+ * specified, the 0 flag will be ignored.''
+ * -- ANSI X3J11
+ */
+number: if ((dprec = prec) >= 0)
+ flags &= ~ZEROPAD;
+
+ /*
+ * ``The result of converting a zero value with an
+ * explicit precision of zero is no characters.''
+ * -- ANSI X3J11
+ */
+ cp = buf + BUF;
+ if (flags & QUADINT) {
+ if (uqval != 0 || prec != 0)
+ cp = __uqtoa(uqval, cp, base,
+ flags & ALT, xdigs);
+ } else {
+ if (ulval != 0 || prec != 0)
+ cp = __ultoa(ulval, cp, base,
+ flags & ALT, xdigs);
+ }
+ size = buf + BUF - cp;
+ break;
+ default: /* "%?" prints ?, unless ? is NUL */
+ if (ch == '\0')
+ goto done;
+ /* pretend it was %c with argument ch */
+ cp = buf;
+ *cp = ch;
+ size = 1;
+ sign = '\0';
+ break;
+ }
+
+ /*
+ * All reasonable formats wind up here. At this point, `cp'
+ * points to a string which (if not flags&LADJUST) should be
+ * padded out to `width' places. If flags&ZEROPAD, it should
+ * first be prefixed by any sign or other prefix; otherwise,
+ * it should be blank padded before the prefix is emitted.
+ * After any left-hand padding and prefixing, emit zeroes
+ * required by a decimal [diouxX] precision, then print the
+ * string proper, then emit zeroes required by any leftover
+ * floating precision; finally, if LADJUST, pad with blanks.
+ *
+ * Compute actual size, so we know how much to pad.
+ * size excludes decimal prec; realsz includes it.
+ */
+ realsz = dprec > size ? dprec : size;
+ if (sign)
+ realsz++;
+ else if (flags & HEXPREFIX)
+ realsz += 2;
+
+ prsize = width > realsz ? width : realsz;
+ if ((unsigned)ret + prsize > INT_MAX) {
+ ret = EOF;
+ goto error;
+ }
+
+ /* right-adjusting blank padding */
+ if ((flags & (LADJUST|ZEROPAD)) == 0)
+ PAD(width - realsz, blanks);
+
+ /* prefix */
+ if (sign) {
+ PRINT(&sign, 1);
+ } else if (flags & HEXPREFIX) {
+ ox[0] = '0';
+ ox[1] = ch;
+ PRINT(ox, 2);
+ }
+
+ /* right-adjusting zero padding */
+ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
+ PAD(width - realsz, zeroes);
+
+ /* leading zeroes from decimal precision */
+ PAD(dprec - size, zeroes);
+
+ /* the string or number proper */
+#ifdef FLOATING_POINT
+ if ((flags & FPT) == 0) {
+ PRINT(cp, size);
+ } else { /* glue together f_p fragments */
+ if (ch >= 'f') { /* 'f' or 'g' */
+ if (_double == 0) {
+ /* kludge for __dtoa irregularity */
+ if (expt >= ndig &&
+ (flags & ALT) == 0) {
+ PRINT("0", 1);
+ } else {
+ PRINT("0.", 2);
+ PAD(ndig - 1, zeroes);
+ }
+ } else if (expt <= 0) {
+ PRINT("0.", 2);
+ PAD(-expt, zeroes);
+ PRINT(cp, ndig);
+ } else if (expt >= ndig) {
+ PRINT(cp, ndig);
+ PAD(expt - ndig, zeroes);
+ if (flags & ALT)
+ PRINT(".", 1);
+ } else {
+ PRINT(cp, expt);
+ cp += expt;
+ PRINT(".", 1);
+ PRINT(cp, ndig-expt);
+ }
+ } else { /* 'e' or 'E' */
+ if (ndig > 1 || flags & ALT) {
+ ox[0] = *cp++;
+ ox[1] = '.';
+ PRINT(ox, 2);
+ if (_double) {
+ PRINT(cp, ndig-1);
+ } else /* 0.[0..] */
+ /* __dtoa irregularity */
+ PAD(ndig - 1, zeroes);
+ } else /* XeYYY */
+ PRINT(cp, 1);
+ PRINT(expstr, expsize);
+ }
+ }
+#else
+ PRINT(cp, size);
+#endif
+ /* left-adjusting padding (always blank) */
+ if (flags & LADJUST)
+ PAD(width - realsz, blanks);
+
+ /* finally, adjust ret */
+ ret += prsize;
+
+ FLUSH(); /* copy out the I/O vectors */
+ }
+done:
+ FLUSH();
+error:
+ if (__sferror(fp))
+ ret = EOF;
+ FUNLOCKFILE(fp);
+ if ((argtable != NULL) && (argtable != statargtable))
+ free (argtable);
+ return (ret);
+ /* NOTREACHED */
+}
+
+/*
+ * Type ids for argument type table.
+ */
+#define T_UNUSED 0
+#define T_SHORT 1
+#define T_U_SHORT 2
+#define TP_SHORT 3
+#define T_INT 4
+#define T_U_INT 5
+#define TP_INT 6
+#define T_LONG 7
+#define T_U_LONG 8
+#define TP_LONG 9
+#define T_QUAD 10
+#define T_U_QUAD 11
+#define TP_QUAD 12
+#define T_DOUBLE 13
+#define T_LONG_DOUBLE 14
+#define TP_CHAR 15
+#define TP_VOID 16
+
+/*
+ * Find all arguments when a positional parameter is encountered. Returns a
+ * table, indexed by argument number, of pointers to each arguments. The
+ * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
+ * It will be replaces with a malloc-ed on if it overflows.
+ */
+static void
+__find_arguments (fmt0, ap, argtable)
+ const char *fmt0;
+ va_list ap;
+ void ***argtable;
+{
+ register char *fmt; /* format string */
+ register int ch; /* character from fmt */
+ register int n, n2; /* handy integer (short term usage) */
+ register char *cp; /* handy char pointer (short term usage) */
+ register int flags; /* flags as above */
+ int width; /* width from format (%8d), or 0 */
+ unsigned char *typetable; /* table of types */
+ unsigned char stattypetable [STATIC_ARG_TBL_SIZE];
+ int tablesize; /* current size of type table */
+ int tablemax; /* largest used index in table */
+ int nextarg; /* 1-based argument index */
+
+ /*
+ * Add an argument type to the table, expanding if necessary.
+ */
+#define ADDTYPE(type) \
+ ((nextarg >= tablesize) ? \
+ __grow_type_table(nextarg, &typetable, &tablesize) : 0, \
+ typetable[nextarg++] = type, \
+ (nextarg > tablemax) ? tablemax = nextarg : 0)
+
+#define ADDSARG() \
+ ((flags&LONGINT) ? ADDTYPE(T_LONG) : \
+ ((flags&SHORTINT) ? ADDTYPE(T_SHORT) : ADDTYPE(T_INT)))
+
+#define ADDUARG() \
+ ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : \
+ ((flags&SHORTINT) ? ADDTYPE(T_U_SHORT) : ADDTYPE(T_U_INT)))
+
+ /*
+ * Add * arguments to the type array.
+ */
+#define ADDASTER() \
+ n2 = 0; \
+ cp = fmt; \
+ while (is_digit(*cp)) { \
+ n2 = 10 * n2 + to_digit(*cp); \
+ cp++; \
+ } \
+ if (*cp == '$') { \
+ int hold = nextarg; \
+ nextarg = n2; \
+ ADDTYPE (T_INT); \
+ nextarg = hold; \
+ fmt = ++cp; \
+ } else { \
+ ADDTYPE (T_INT); \
+ }
+ fmt = (char *)fmt0;
+ typetable = stattypetable;
+ tablesize = STATIC_ARG_TBL_SIZE;
+ tablemax = 0;
+ nextarg = 1;
+ memset (typetable, T_UNUSED, STATIC_ARG_TBL_SIZE);
+
+ /*
+ * Scan the format for conversions (`%' character).
+ */
+ for (;;) {
+ for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
+ /* void */;
+ if (ch == '\0')
+ goto done;
+ fmt++; /* skip over '%' */
+
+ flags = 0;
+ width = 0;
+
+rflag: ch = *fmt++;
+reswitch: switch (ch) {
+ case ' ':
+ case '#':
+ goto rflag;
+ case '*':
+ ADDASTER ();
+ goto rflag;
+ case '-':
+ case '+':
+ goto rflag;
+ case '.':
+ if ((ch = *fmt++) == '*') {
+ ADDASTER ();
+ goto rflag;
+ }
+ while (is_digit(ch)) {
+ ch = *fmt++;
+ }
+ goto reswitch;
+ case '0':
+ goto rflag;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = 0;
+ do {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ } while (is_digit(ch));
+ if (ch == '$') {
+ nextarg = n;
+ goto rflag;
+ }
+ width = n;
+ goto reswitch;
+#ifdef FLOATING_POINT
+ case 'L':
+ flags |= LONGDBL;
+ goto rflag;
+#endif
+ case 'h':
+ flags |= SHORTINT;
+ goto rflag;
+ case 'l':
+ if (flags & LONGINT)
+ flags |= QUADINT;
+ else
+ flags |= LONGINT;
+ goto rflag;
+ case 'q':
+ flags |= QUADINT;
+ goto rflag;
+ case 'c':
+ ADDTYPE(T_INT);
+ break;
+ case 'D':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'd':
+ case 'i':
+ if (flags & QUADINT) {
+ ADDTYPE(T_QUAD);
+ } else {
+ ADDSARG();
+ }
+ break;
+#ifdef FLOATING_POINT
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'g':
+ case 'G':
+ if (flags & LONGDBL)
+ ADDTYPE(T_LONG_DOUBLE);
+ else
+ ADDTYPE(T_DOUBLE);
+ break;
+#endif /* FLOATING_POINT */
+ case 'n':
+ if (flags & QUADINT)
+ ADDTYPE(TP_QUAD);
+ else if (flags & LONGINT)
+ ADDTYPE(TP_LONG);
+ else if (flags & SHORTINT)
+ ADDTYPE(TP_SHORT);
+ else
+ ADDTYPE(TP_INT);
+ continue; /* no output */
+ case 'O':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'o':
+ if (flags & QUADINT)
+ ADDTYPE(T_U_QUAD);
+ else
+ ADDUARG();
+ break;
+ case 'p':
+ ADDTYPE(TP_VOID);
+ break;
+ case 's':
+ ADDTYPE(TP_CHAR);
+ break;
+ case 'U':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'u':
+ if (flags & QUADINT)
+ ADDTYPE(T_U_QUAD);
+ else
+ ADDUARG();
+ break;
+ case 'X':
+ case 'x':
+ if (flags & QUADINT)
+ ADDTYPE(T_U_QUAD);
+ else
+ ADDUARG();
+ break;
+ default: /* "%?" prints ?, unless ? is NUL */
+ if (ch == '\0')
+ goto done;
+ break;
+ }
+ }
+done:
+ /*
+ * Build the argument table.
+ */
+ if (tablemax >= STATIC_ARG_TBL_SIZE) {
+ *argtable = (void **)
+ malloc (sizeof (void *) * (tablemax + 1));
+ }
+
+ (*argtable) [0] = NULL;
+ for (n = 1; n <= tablemax; n++) {
+ switch (typetable [n]) {
+ case T_UNUSED:
+ (*argtable) [n] = (void *) &va_arg (ap, int);
+ break;
+ case T_SHORT:
+ (*argtable) [n] = (void *) &va_arg (ap, int);
+ break;
+ case T_U_SHORT:
+ (*argtable) [n] = (void *) &va_arg (ap, int);
+ break;
+ case TP_SHORT:
+ (*argtable) [n] = (void *) &va_arg (ap, short *);
+ break;
+ case T_INT:
+ (*argtable) [n] = (void *) &va_arg (ap, int);
+ break;
+ case T_U_INT:
+ (*argtable) [n] = (void *) &va_arg (ap, unsigned int);
+ break;
+ case TP_INT:
+ (*argtable) [n] = (void *) &va_arg (ap, int *);
+ break;
+ case T_LONG:
+ (*argtable) [n] = (void *) &va_arg (ap, long);
+ break;
+ case T_U_LONG:
+ (*argtable) [n] = (void *) &va_arg (ap, unsigned long);
+ break;
+ case TP_LONG:
+ (*argtable) [n] = (void *) &va_arg (ap, long *);
+ break;
+ case T_QUAD:
+ (*argtable) [n] = (void *) &va_arg (ap, quad_t);
+ break;
+ case T_U_QUAD:
+ (*argtable) [n] = (void *) &va_arg (ap, u_quad_t);
+ break;
+ case TP_QUAD:
+ (*argtable) [n] = (void *) &va_arg (ap, quad_t *);
+ break;
+ case T_DOUBLE:
+ (*argtable) [n] = (void *) &va_arg (ap, double);
+ break;
+ case T_LONG_DOUBLE:
+ (*argtable) [n] = (void *) &va_arg (ap, long double);
+ break;
+ case TP_CHAR:
+ (*argtable) [n] = (void *) &va_arg (ap, char *);
+ break;
+ case TP_VOID:
+ (*argtable) [n] = (void *) &va_arg (ap, void *);
+ break;
+ }
+ }
+
+ if ((typetable != NULL) && (typetable != stattypetable))
+ free (typetable);
+}
+
+/*
+ * Increase the size of the type table.
+ */
+static void
+__grow_type_table (nextarg, typetable, tablesize)
+ int nextarg;
+ unsigned char **typetable;
+ int *tablesize;
+{
+ unsigned char *oldtable = *typetable;
+ int newsize = *tablesize * 2;
+
+ if (*tablesize == STATIC_ARG_TBL_SIZE) {
+ *typetable = (unsigned char *)
+ malloc (sizeof (unsigned char) * newsize);
+ bcopy (oldtable, *typetable, *tablesize);
+ } else {
+ *typetable = (unsigned char *)
+ reallocf (typetable, sizeof (unsigned char) * newsize);
+
+ }
+ memset (&typetable [*tablesize], T_UNUSED, (newsize - *tablesize));
+
+ *tablesize = newsize;
+}
+
+
+#ifdef FLOATING_POINT
+
+extern char *__dtoa __P((double, int, int, int *, int *, char **));
+
+static char *
+cvt(value, ndigits, flags, sign, decpt, ch, length)
+ double value;
+ int ndigits, flags, *decpt, ch, *length;
+ char *sign;
+{
+ int mode, dsgn;
+ char *digits, *bp, *rve;
+
+ if (ch == 'f')
+ mode = 3; /* ndigits after the decimal point */
+ else {
+ /*
+ * To obtain ndigits after the decimal point for the 'e'
+ * and 'E' formats, round to ndigits + 1 significant
+ * figures.
+ */
+ if (ch == 'e' || ch == 'E')
+ ndigits++;
+ mode = 2; /* ndigits significant digits */
+ }
+ if (value < 0) {
+ value = -value;
+ *sign = '-';
+ } else
+ *sign = '\000';
+ digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
+ if ((ch != 'g' && ch != 'G') || flags & ALT) {
+ /* print trailing zeros */
+ bp = digits + ndigits;
+ if (ch == 'f') {
+ if (*digits == '0' && value)
+ *decpt = -ndigits + 1;
+ bp += *decpt;
+ }
+ if (value == 0) /* kludge for __dtoa irregularity */
+ rve = bp;
+ while (rve < bp)
+ *rve++ = '0';
+ }
+ *length = rve - digits;
+ return (digits);
+}
+
+static int
+exponent(p0, exp, fmtch)
+ char *p0;
+ int exp, fmtch;
+{
+ register char *p, *t;
+ char expbuf[MAXEXP];
+
+ p = p0;
+ *p++ = fmtch;
+ if (exp < 0) {
+ exp = -exp;
+ *p++ = '-';
+ }
+ else
+ *p++ = '+';
+ t = expbuf + MAXEXP;
+ if (exp > 9) {
+ do {
+ *--t = to_char(exp % 10);
+ } while ((exp /= 10) > 9);
+ *--t = to_char(exp);
+ for (; t < expbuf + MAXEXP; *p++ = *t++);
+ }
+ else {
+ *p++ = '0';
+ *p++ = to_char(exp);
+ }
+ return (p - p0);
+}
+#endif /* FLOATING_POINT */
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
new file mode 100644
index 0000000..6a83216
--- /dev/null
+++ b/lib/libc/stdio/vfscanf.c
@@ -0,0 +1,786 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <string.h>
+
+#include "collate.h"
+#include "local.h"
+
+#define FLOATING_POINT
+
+#include "floatio.h"
+#define BUF 513 /* Maximum length of numeric string. */
+
+/*
+ * Flags used during conversion.
+ */
+#define LONG 0x01 /* l: long or double */
+#define LONGDBL 0x02 /* L: long double */
+#define SHORT 0x04 /* h: short */
+#define SUPPRESS 0x08 /* suppress assignment */
+#define POINTER 0x10 /* weird %p pointer (`fake hex') */
+#define NOSKIP 0x20 /* do not skip blanks */
+#define QUAD 0x400
+
+/*
+ * The following are used in numeric conversions only:
+ * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
+ * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
+ */
+#define SIGNOK 0x40 /* +/- is (still) legal */
+#define NDIGITS 0x80 /* no digits detected */
+
+#define DPTOK 0x100 /* (float) decimal point is still legal */
+#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
+
+#define PFXOK 0x100 /* 0x prefix is (still) legal */
+#define NZDIGITS 0x200 /* no zero digits detected */
+
+/*
+ * Conversion types.
+ */
+#define CT_CHAR 0 /* %c conversion */
+#define CT_CCL 1 /* %[...] conversion */
+#define CT_STRING 2 /* %s conversion */
+#define CT_INT 3 /* integer, i.e., strtoq or strtouq */
+#define CT_FLOAT 4 /* floating, i.e., strtod */
+
+#define u_char unsigned char
+#define u_long unsigned long
+
+static u_char *__sccl(char *, u_char *);
+
+/*
+ * vfscanf
+ */
+int
+__svfscanf(fp, fmt0, ap)
+ register FILE *fp;
+ char const *fmt0;
+ va_list ap;
+{
+ register u_char *fmt = (u_char *)fmt0;
+ register int c; /* character from format, or conversion */
+ register size_t width; /* field width, or 0 */
+ register char *p; /* points into all kinds of strings */
+ register int n; /* handy integer */
+ register int flags; /* flags as defined above */
+ register char *p0; /* saves original value of p when necessary */
+ int nassigned; /* number of fields assigned */
+ int nconversions; /* number of conversions */
+ int nread; /* number of characters consumed from fp */
+ int base; /* base argument to strtoq/strtouq */
+ u_quad_t(*ccfn)(); /* conversion function (strtoq/strtouq) */
+ char ccltab[256]; /* character class table for %[...] */
+ char buf[BUF]; /* buffer for numeric conversions */
+
+ /* `basefix' is used to avoid `if' tests in the integer scanner */
+ static short basefix[17] =
+ { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+
+ nassigned = 0;
+ nconversions = 0;
+ nread = 0;
+ base = 0; /* XXX just to keep gcc happy */
+ ccfn = NULL; /* XXX just to keep gcc happy */
+ for (;;) {
+ c = *fmt++;
+ if (c == 0)
+ return (nassigned);
+ if (isspace(c)) {
+ while ((fp->_r > 0 || __srefill(fp) == 0) && isspace(*fp->_p))
+ nread++, fp->_r--, fp->_p++;
+ continue;
+ }
+ if (c != '%')
+ goto literal;
+ width = 0;
+ flags = 0;
+ /*
+ * switch on the format. continue if done;
+ * break once format type is derived.
+ */
+again: c = *fmt++;
+ switch (c) {
+ case '%':
+literal:
+ if (fp->_r <= 0 && __srefill(fp))
+ goto input_failure;
+ if (*fp->_p != c)
+ goto match_failure;
+ fp->_r--, fp->_p++;
+ nread++;
+ continue;
+
+ case '*':
+ flags |= SUPPRESS;
+ goto again;
+ case 'l':
+ flags |= LONG;
+ goto again;
+ case 'q':
+ flags |= QUAD;
+ goto again;
+ case 'L':
+ flags |= LONGDBL;
+ goto again;
+ case 'h':
+ flags |= SHORT;
+ goto again;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ width = width * 10 + c - '0';
+ goto again;
+
+ /*
+ * Conversions.
+ * Those marked `compat' are for 4.[123]BSD compatibility.
+ *
+ * (According to ANSI, E and X formats are supposed
+ * to the same as e and x. Sorry about that.)
+ */
+ case 'D': /* compat */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'd':
+ c = CT_INT;
+ ccfn = (u_quad_t (*)())strtoq;
+ base = 10;
+ break;
+
+ case 'i':
+ c = CT_INT;
+ ccfn = (u_quad_t (*)())strtoq;
+ base = 0;
+ break;
+
+ case 'O': /* compat */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'o':
+ c = CT_INT;
+ ccfn = strtouq;
+ base = 8;
+ break;
+
+ case 'u':
+ c = CT_INT;
+ ccfn = strtouq;
+ base = 10;
+ break;
+
+ case 'X': /* compat XXX */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'x':
+ flags |= PFXOK; /* enable 0x prefixing */
+ c = CT_INT;
+ ccfn = strtouq;
+ base = 16;
+ break;
+
+#ifdef FLOATING_POINT
+ case 'E': /* compat XXX */
+ case 'F': /* compat */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'e': case 'f': case 'g':
+ c = CT_FLOAT;
+ break;
+#endif
+
+ case 's':
+ c = CT_STRING;
+ break;
+
+ case '[':
+ fmt = __sccl(ccltab, fmt);
+ flags |= NOSKIP;
+ c = CT_CCL;
+ break;
+
+ case 'c':
+ flags |= NOSKIP;
+ c = CT_CHAR;
+ break;
+
+ case 'p': /* pointer format is like hex */
+ flags |= POINTER | PFXOK;
+ c = CT_INT;
+ ccfn = strtouq;
+ base = 16;
+ break;
+
+ case 'n':
+ nconversions++;
+ if (flags & SUPPRESS) /* ??? */
+ continue;
+ if (flags & SHORT)
+ *va_arg(ap, short *) = nread;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = nread;
+ else if (flags & QUAD)
+ *va_arg(ap, quad_t *) = nread;
+ else
+ *va_arg(ap, int *) = nread;
+ continue;
+
+ /*
+ * Disgusting backwards compatibility hacks. XXX
+ */
+ case '\0': /* compat */
+ return (EOF);
+
+ default: /* compat */
+ if (isupper(c))
+ flags |= LONG;
+ c = CT_INT;
+ ccfn = (u_quad_t (*)())strtoq;
+ base = 10;
+ break;
+ }
+
+ /*
+ * We have a conversion that requires input.
+ */
+ if (fp->_r <= 0 && __srefill(fp))
+ goto input_failure;
+
+ /*
+ * Consume leading white space, except for formats
+ * that suppress this.
+ */
+ if ((flags & NOSKIP) == 0) {
+ while (isspace(*fp->_p)) {
+ nread++;
+ if (--fp->_r > 0)
+ fp->_p++;
+ else if (__srefill(fp))
+ goto input_failure;
+ }
+ /*
+ * Note that there is at least one character in
+ * the buffer, so conversions that do not set NOSKIP
+ * ca no longer result in an input failure.
+ */
+ }
+
+ /*
+ * Do the conversion.
+ */
+ switch (c) {
+
+ case CT_CHAR:
+ /* scan arbitrary characters (sets NOSKIP) */
+ if (width == 0)
+ width = 1;
+ if (flags & SUPPRESS) {
+ size_t sum = 0;
+ for (;;) {
+ if ((n = fp->_r) < width) {
+ sum += n;
+ width -= n;
+ fp->_p += n;
+ if (__srefill(fp)) {
+ if (sum == 0)
+ goto input_failure;
+ break;
+ }
+ } else {
+ sum += width;
+ fp->_r -= width;
+ fp->_p += width;
+ break;
+ }
+ }
+ nread += sum;
+ } else {
+ size_t r = fread((void *)va_arg(ap, char *), 1,
+ width, fp);
+
+ if (r == 0)
+ goto input_failure;
+ nread += r;
+ nassigned++;
+ }
+ nconversions++;
+ break;
+
+ case CT_CCL:
+ /* scan a (nonempty) character class (sets NOSKIP) */
+ if (width == 0)
+ width = (size_t)~0; /* `infinity' */
+ /* take only those things in the class */
+ if (flags & SUPPRESS) {
+ n = 0;
+ while (ccltab[*fp->_p]) {
+ n++, fp->_r--, fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp)) {
+ if (n == 0)
+ goto input_failure;
+ break;
+ }
+ }
+ if (n == 0)
+ goto match_failure;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (ccltab[*fp->_p]) {
+ fp->_r--;
+ *p++ = *fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp)) {
+ if (p == p0)
+ goto input_failure;
+ break;
+ }
+ }
+ n = p - p0;
+ if (n == 0)
+ goto match_failure;
+ *p = 0;
+ nassigned++;
+ }
+ nread += n;
+ nconversions++;
+ break;
+
+ case CT_STRING:
+ /* like CCL, but zero-length string OK, & no NOSKIP */
+ if (width == 0)
+ width = (size_t)~0;
+ if (flags & SUPPRESS) {
+ n = 0;
+ while (!isspace(*fp->_p)) {
+ n++, fp->_r--, fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp))
+ break;
+ }
+ nread += n;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (!isspace(*fp->_p)) {
+ fp->_r--;
+ *p++ = *fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp))
+ break;
+ }
+ *p = 0;
+ nread += p - p0;
+ nassigned++;
+ }
+ nconversions++;
+ continue;
+
+ case CT_INT:
+ /* scan an integer as if by strtoq/strtouq */
+#ifdef hardway
+ if (width == 0 || width > sizeof(buf) - 1)
+ width = sizeof(buf) - 1;
+#else
+ /* size_t is unsigned, hence this optimisation */
+ if (--width > sizeof(buf) - 2)
+ width = sizeof(buf) - 2;
+ width++;
+#endif
+ flags |= SIGNOK | NDIGITS | NZDIGITS;
+ for (p = buf; width; width--) {
+ c = *fp->_p;
+ /*
+ * Switch on the character; `goto ok'
+ * if we accept it as a part of number.
+ */
+ switch (c) {
+
+ /*
+ * The digit 0 is always legal, but is
+ * special. For %i conversions, if no
+ * digits (zero or nonzero) have been
+ * scanned (only signs), we will have
+ * base==0. In that case, we should set
+ * it to 8 and enable 0x prefixing.
+ * Also, if we have not scanned zero digits
+ * before this, do not turn off prefixing
+ * (someone else will turn it off if we
+ * have scanned any nonzero digits).
+ */
+ case '0':
+ if (base == 0) {
+ base = 8;
+ flags |= PFXOK;
+ }
+ if (flags & NZDIGITS)
+ flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
+ else
+ flags &= ~(SIGNOK|PFXOK|NDIGITS);
+ goto ok;
+
+ /* 1 through 7 always legal */
+ case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ base = basefix[base];
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* digits 8 and 9 ok iff decimal or hex */
+ case '8': case '9':
+ base = basefix[base];
+ if (base <= 8)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* letters ok iff hex */
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F':
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f':
+ /* no need to fix base here */
+ if (base <= 10)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* sign ok only as first character */
+ case '+': case '-':
+ if (flags & SIGNOK) {
+ flags &= ~SIGNOK;
+ goto ok;
+ }
+ break;
+
+ /* x ok iff flag still set & 2nd char */
+ case 'x': case 'X':
+ if (flags & PFXOK && p == buf + 1) {
+ base = 16; /* if %i */
+ flags &= ~PFXOK;
+ goto ok;
+ }
+ break;
+ }
+
+ /*
+ * If we got here, c is not a legal character
+ * for a number. Stop accumulating digits.
+ */
+ break;
+ ok:
+ /*
+ * c is legal: store it and look at the next.
+ */
+ *p++ = c;
+ if (--fp->_r > 0)
+ fp->_p++;
+ else if (__srefill(fp))
+ break; /* EOF */
+ }
+ /*
+ * If we had only a sign, it is no good; push
+ * back the sign. If the number ends in `x',
+ * it was [sign] '0' 'x', so push back the x
+ * and treat it as [sign] '0'.
+ */
+ if (flags & NDIGITS) {
+ if (p > buf)
+ (void) ungetc(*(u_char *)--p, fp);
+ goto match_failure;
+ }
+ c = ((u_char *)p)[-1];
+ if (c == 'x' || c == 'X') {
+ --p;
+ (void) ungetc(c, fp);
+ }
+ if ((flags & SUPPRESS) == 0) {
+ u_quad_t res;
+
+ *p = 0;
+ res = (*ccfn)(buf, (char **)NULL, base);
+ if (flags & POINTER)
+ *va_arg(ap, void **) =
+ (void *)(u_long)res;
+ else if (flags & SHORT)
+ *va_arg(ap, short *) = res;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = res;
+ else if (flags & QUAD)
+ *va_arg(ap, quad_t *) = res;
+ else
+ *va_arg(ap, int *) = res;
+ nassigned++;
+ }
+ nread += p - buf;
+ nconversions++;
+ break;
+
+#ifdef FLOATING_POINT
+ case CT_FLOAT:
+ /* scan a floating point number as if by strtod */
+#ifdef hardway
+ if (width == 0 || width > sizeof(buf) - 1)
+ width = sizeof(buf) - 1;
+#else
+ /* size_t is unsigned, hence this optimisation */
+ if (--width > sizeof(buf) - 2)
+ width = sizeof(buf) - 2;
+ width++;
+#endif
+ flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
+ for (p = buf; width; width--) {
+ c = *fp->_p;
+ /*
+ * This code mimicks the integer conversion
+ * code, but is much simpler.
+ */
+ switch (c) {
+
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9':
+ flags &= ~(SIGNOK | NDIGITS);
+ goto fok;
+
+ case '+': case '-':
+ if (flags & SIGNOK) {
+ flags &= ~SIGNOK;
+ goto fok;
+ }
+ break;
+ case '.':
+ if (flags & DPTOK) {
+ flags &= ~(SIGNOK | DPTOK);
+ goto fok;
+ }
+ break;
+ case 'e': case 'E':
+ /* no exponent without some digits */
+ if ((flags&(NDIGITS|EXPOK)) == EXPOK) {
+ flags =
+ (flags & ~(EXPOK|DPTOK)) |
+ SIGNOK | NDIGITS;
+ goto fok;
+ }
+ break;
+ }
+ break;
+ fok:
+ *p++ = c;
+ if (--fp->_r > 0)
+ fp->_p++;
+ else if (__srefill(fp))
+ break; /* EOF */
+ }
+ /*
+ * If no digits, might be missing exponent digits
+ * (just give back the exponent) or might be missing
+ * regular digits, but had sign and/or decimal point.
+ */
+ if (flags & NDIGITS) {
+ if (flags & EXPOK) {
+ /* no digits at all */
+ while (p > buf)
+ ungetc(*(u_char *)--p, fp);
+ goto match_failure;
+ }
+ /* just a bad exponent (e and maybe sign) */
+ c = *(u_char *)--p;
+ if (c != 'e' && c != 'E') {
+ (void) ungetc(c, fp);/* sign */
+ c = *(u_char *)--p;
+ }
+ (void) ungetc(c, fp);
+ }
+ if ((flags & SUPPRESS) == 0) {
+ double res;
+
+ *p = 0;
+ /* XXX this loses precision for long doubles. */
+ res = strtod(buf, (char **) NULL);
+ if (flags & LONGDBL)
+ *va_arg(ap, long double *) = res;
+ else if (flags & LONG)
+ *va_arg(ap, double *) = res;
+ else
+ *va_arg(ap, float *) = res;
+ nassigned++;
+ }
+ nread += p - buf;
+ nconversions++;
+ break;
+#endif /* FLOATING_POINT */
+ }
+ }
+input_failure:
+ return (nconversions != 0 ? nassigned : EOF);
+match_failure:
+ return (nassigned);
+}
+
+/*
+ * Fill in the given table from the scanset at the given format
+ * (just after `['). Return a pointer to the character past the
+ * closing `]'. The table has a 1 wherever characters should be
+ * considered part of the scanset.
+ */
+static u_char *
+__sccl(tab, fmt)
+ register char *tab;
+ register u_char *fmt;
+{
+ register int c, n, v, i;
+
+ /* first `clear' the whole table */
+ c = *fmt++; /* first char hat => negated scanset */
+ if (c == '^') {
+ v = 1; /* default => accept */
+ c = *fmt++; /* get new first char */
+ } else
+ v = 0; /* default => reject */
+
+ /* XXX: Will not work if sizeof(tab*) > sizeof(char) */
+ (void) memset(tab, v, 256);
+
+ if (c == 0)
+ return (fmt - 1);/* format ended before closing ] */
+
+ /*
+ * Now set the entries corresponding to the actual scanset
+ * to the opposite of the above.
+ *
+ * The first character may be ']' (or '-') without being special;
+ * the last character may be '-'.
+ */
+ v = 1 - v;
+ for (;;) {
+ tab[c] = v; /* take character c */
+doswitch:
+ n = *fmt++; /* and examine the next */
+ switch (n) {
+
+ case 0: /* format ended too soon */
+ return (fmt - 1);
+
+ case '-':
+ /*
+ * A scanset of the form
+ * [01+-]
+ * is defined as `the digit 0, the digit 1,
+ * the character +, the character -', but
+ * the effect of a scanset such as
+ * [a-zA-Z0-9]
+ * is implementation defined. The V7 Unix
+ * scanf treats `a-z' as `the letters a through
+ * z', but treats `a-a' as `the letter a, the
+ * character -, and the letter a'.
+ *
+ * For compatibility, the `-' is not considerd
+ * to define a range if the character following
+ * it is either a close bracket (required by ANSI)
+ * or is not numerically greater than the character
+ * we just stored in the table (c).
+ */
+ n = *fmt;
+ if (n == ']'
+ || (__collate_load_error ? n < c :
+ __collate_range_cmp (n, c) < 0
+ )
+ ) {
+ c = '-';
+ break; /* resume the for(;;) */
+ }
+ fmt++;
+ /* fill in the range */
+ if (__collate_load_error) {
+ do {
+ tab[++c] = v;
+ } while (c < n);
+ } else {
+ for (i = 0; i < 256; i ++)
+ if ( __collate_range_cmp (c, i) < 0
+ && __collate_range_cmp (i, n) <= 0
+ )
+ tab[i] = v;
+ }
+#if 1 /* XXX another disgusting compatibility hack */
+ c = n;
+ /*
+ * Alas, the V7 Unix scanf also treats formats
+ * such as [a-c-e] as `the letters a through e'.
+ * This too is permitted by the standard....
+ */
+ goto doswitch;
+#else
+ c = *fmt++;
+ if (c == 0)
+ return (fmt - 1);
+ if (c == ']')
+ return (fmt);
+#endif
+ break;
+
+ case ']': /* end of scanset */
+ return (fmt);
+
+ default: /* just another character */
+ c = n;
+ break;
+ }
+ }
+ /* NOTREACHED */
+}
diff --git a/lib/libc/stdio/vprintf.c b/lib/libc/stdio/vprintf.c
new file mode 100644
index 0000000..a3a2f63
--- /dev/null
+++ b/lib/libc/stdio/vprintf.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)vprintf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+int
+vprintf(fmt, ap)
+ char const *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ return (vfprintf(stdout, fmt, ap));
+}
diff --git a/lib/libc/stdio/vscanf.c b/lib/libc/stdio/vscanf.c
new file mode 100644
index 0000000..53fb362
--- /dev/null
+++ b/lib/libc/stdio/vscanf.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Donn Seeley at UUNET Technologies, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)vscanf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "libc_private.h"
+
+int
+vscanf(fmt, ap)
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ int retval;
+
+ FLOCKFILE(stdin);
+ retval = __svfscanf(stdin, fmt, ap);
+ FUNLOCKFILE(stdin);
+ return (retval);
+}
diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c
new file mode 100644
index 0000000..b8e4c8c
--- /dev/null
+++ b/lib/libc/stdio/vsnprintf.c
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)vsnprintf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <stdio.h>
+
+int
+vsnprintf(str, n, fmt, ap)
+ char *str;
+ size_t n;
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ size_t on;
+ int ret;
+ FILE f;
+
+ on = n;
+ if (n != 0)
+ n--;
+ if (n > INT_MAX)
+ n = INT_MAX;
+ f._file = -1;
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = n;
+ ret = vfprintf(&f, fmt, ap);
+ if (on > 0)
+ *f._p = '\0';
+ return (ret);
+}
diff --git a/lib/libc/stdio/vsprintf.c b/lib/libc/stdio/vsprintf.c
new file mode 100644
index 0000000..d357af0
--- /dev/null
+++ b/lib/libc/stdio/vsprintf.c
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)vsprintf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <limits.h>
+
+int
+vsprintf(str, fmt, ap)
+ char *str;
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ int ret;
+ FILE f;
+
+ f._file = -1;
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = INT_MAX;
+ ret = vfprintf(&f, fmt, ap);
+ *f._p = 0;
+ return (ret);
+}
diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c
new file mode 100644
index 0000000..5a5f8c8
--- /dev/null
+++ b/lib/libc/stdio/vsscanf.c
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Donn Seeley at UUNET Technologies, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)vsscanf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+
+static int
+eofread __P((void *, char *, int));
+
+/* ARGSUSED */
+static int
+eofread(cookie, buf, len)
+ void *cookie;
+ char *buf;
+ int len;
+{
+
+ return (0);
+}
+
+int
+vsscanf(str, fmt, ap)
+ const char *str;
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ FILE f;
+
+ f._file = -1;
+ f._flags = __SRD;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._r = strlen(str);
+ f._read = eofread;
+ f._ub._base = NULL;
+ f._lb._base = NULL;
+ return (__svfscanf(&f, fmt, ap));
+}
diff --git a/lib/libc/stdio/wbuf.c b/lib/libc/stdio/wbuf.c
new file mode 100644
index 0000000..847699a
--- /dev/null
+++ b/lib/libc/stdio/wbuf.c
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)wbuf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "local.h"
+
+/*
+ * Write the given character into the (probably full) buffer for
+ * the given file. Flush the buffer out if it is or becomes full,
+ * or if c=='\n' and the file is line buffered.
+ */
+int
+__swbuf(c, fp)
+ register int c;
+ register FILE *fp;
+{
+ register int n;
+
+ /*
+ * In case we cannot write, or longjmp takes us out early,
+ * make sure _w is 0 (if fully- or un-buffered) or -_bf._size
+ * (if line buffered) so that we will get called again.
+ * If we did not do this, a sufficient number of putc()
+ * calls might wrap _w from negative to positive.
+ */
+ fp->_w = fp->_lbfsize;
+ if (cantwrite(fp))
+ return (EOF);
+ c = (unsigned char)c;
+
+ /*
+ * If it is completely full, flush it out. Then, in any case,
+ * stuff c into the buffer. If this causes the buffer to fill
+ * completely, or if c is '\n' and the file is line buffered,
+ * flush it (perhaps a second time). The second flush will always
+ * happen on unbuffered streams, where _bf._size==1; fflush()
+ * guarantees that putc() will always call wbuf() by setting _w
+ * to 0, so we need not do anything else.
+ */
+ n = fp->_p - fp->_bf._base;
+ if (n >= fp->_bf._size) {
+ if (fflush(fp))
+ return (EOF);
+ n = 0;
+ }
+ fp->_w--;
+ *fp->_p++ = c;
+ if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n'))
+ if (fflush(fp))
+ return (EOF);
+ return (c);
+}
diff --git a/lib/libc/stdio/wsetup.c b/lib/libc/stdio/wsetup.c
new file mode 100644
index 0000000..074a880
--- /dev/null
+++ b/lib/libc/stdio/wsetup.c
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)wsetup.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+/*
+ * Various output routines call wsetup to be sure it is safe to write,
+ * because either _flags does not include __SWR, or _buf is NULL.
+ * _wsetup returns 0 if OK to write, nonzero otherwise.
+ */
+int
+__swsetup(fp)
+ register FILE *fp;
+{
+ /* make sure stdio is set up */
+ if (!__sdidinit)
+ __sinit();
+
+ /*
+ * If we are not writing, we had better be reading and writing.
+ */
+ if ((fp->_flags & __SWR) == 0) {
+ if ((fp->_flags & __SRW) == 0)
+ return (EOF);
+ if (fp->_flags & __SRD) {
+ /* clobber any ungetc data */
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_flags &= ~(__SRD|__SEOF);
+ fp->_r = 0;
+ fp->_p = fp->_bf._base;
+ }
+ fp->_flags |= __SWR;
+ }
+
+ /*
+ * Make a buffer if necessary, then set _w.
+ */
+ if (fp->_bf._base == NULL)
+ __smakebuf(fp);
+ if (fp->_flags & __SLBF) {
+ /*
+ * It is line buffered, so make _lbfsize be -_bufsize
+ * for the putc() macro. We will change _lbfsize back
+ * to 0 whenever we turn off __SWR.
+ */
+ fp->_w = 0;
+ fp->_lbfsize = -fp->_bf._size;
+ } else
+ fp->_w = fp->_flags & __SNBF ? 0 : fp->_bf._size;
+ return (0);
+}
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
new file mode 100644
index 0000000..d1b4b2a
--- /dev/null
+++ b/lib/libc/stdlib/Makefile.inc
@@ -0,0 +1,39 @@
+# from @(#)Makefile.inc 8.3 (Berkeley) 2/4/95
+# $FreeBSD$
+
+# machine-independent stdlib sources
+.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/stdlib ${.CURDIR}/../libc/stdlib
+
+MISRCS+=abort.c abs.c atexit.c atof.c atoi.c atol.c bsearch.c calloc.c div.c \
+ exit.c getenv.c getopt.c getsubopt.c heapsort.c labs.c ldiv.c \
+ malloc.c merge.c putenv.c qsort.c radixsort.c rand.c random.c \
+ reallocf.c realpath.c setenv.c strhash.c strtol.c strtoq.c strtoul.c \
+ strtouq.c system.c
+
+.if ${MACHINE_ARCH} == "alpha"
+# XXX Temporary until the assumption that a long is 32-bits is resolved
+# XXX FreeBSD's code. NetBSD kludged this with Long = int32_t and
+# XXX ULong = u_int32_t
+SRCS+= netbsd_strtod.c
+.else
+SRCS+= strtod.c
+.endif
+
+# machine-dependent stdlib sources
+.include "${.CURDIR}/../libc/${MACHINE_ARCH}/stdlib/Makefile.inc"
+
+.if ${LIB} == "c"
+MAN3+= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
+ div.3 exit.3 getenv.3 getopt.3 getsubopt.3 labs.3 \
+ ldiv.3 malloc.3 memory.3 qsort.3 radixsort.3 rand.3 random.3 \
+ realpath.3 strtod.3 strtol.3 strtoul.3 system.3
+
+MLINKS+=getenv.3 putenv.3 getenv.3 setenv.3 getenv.3 unsetenv.3
+MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
+MLINKS+=rand.3 srand.3
+MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 \
+ random.3 srandomdev.3
+MLINKS+=strtol.3 strtoq.3
+MLINKS+=strtoul.3 strtouq.3
+MLINKS+=malloc.3 calloc.3 malloc.3 free.3 malloc.3 realloc.3 malloc.3 reallocf.3
+.endif
diff --git a/lib/libc/stdlib/abort.3 b/lib/libc/stdlib/abort.3
new file mode 100644
index 0000000..02f369e
--- /dev/null
+++ b/lib/libc/stdlib/abort.3
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)abort.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ABORT 3
+.Os
+.Sh NAME
+.Nm abort
+.Nd cause abnormal program termination
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft void
+.Fn abort void
+.Sh DESCRIPTION
+The
+.Fn abort
+function causes abnormal program termination to occur, unless the
+signal
+.Dv SIGABRT
+is being caught and the signal handler does not return.
+.Pp
+Any open streams are flushed and closed.
+.Sh RETURN VALUES
+The
+.Fn abort
+function
+never returns.
+.Sh SEE ALSO
+.Xr sigaction 2 ,
+.Xr exit 3
+.Sh STANDARDS
+The
+.Fn abort
+function
+conforms to
+.St -p1003.1-90 .
diff --git a/lib/libc/stdlib/abort.c b/lib/libc/stdlib/abort.c
new file mode 100644
index 0000000..b6b4be9
--- /dev/null
+++ b/lib/libc/stdlib/abort.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)abort.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <signal.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
+
+void (*__cleanup)();
+
+void
+abort()
+{
+ sigset_t mask;
+
+ /*
+ * POSIX requires we flush stdio buffers on abort
+ */
+ if (__cleanup)
+ (*__cleanup)();
+
+ sigfillset(&mask);
+ /*
+ * don't block SIGABRT to give any handler a chance; we ignore
+ * any errors -- X311J doesn't allow abort to return anyway.
+ */
+ sigdelset(&mask, SIGABRT);
+#ifdef _THREAD_SAFE
+ (void) _thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+#else
+ (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+#endif
+ (void)kill(getpid(), SIGABRT);
+
+ /*
+ * if SIGABRT ignored, or caught and the handler returns, do
+ * it again, only harder.
+ */
+ (void)signal(SIGABRT, SIG_DFL);
+#ifdef _THREAD_SAFE
+ (void) _thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+#else
+ (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+#endif
+ (void)kill(getpid(), SIGABRT);
+ exit(1);
+}
diff --git a/lib/libc/stdlib/abs.3 b/lib/libc/stdlib/abs.3
new file mode 100644
index 0000000..85a89ff
--- /dev/null
+++ b/lib/libc/stdlib/abs.3
@@ -0,0 +1,75 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)abs.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ABS 3
+.Os
+.Sh NAME
+.Nm abs
+.Nd integer absolute value function
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft int
+.Fn abs "int j"
+.Sh DESCRIPTION
+The
+.Fn abs
+function
+computes
+the absolute value of the integer
+.Ar j .
+.Sh RETURN VALUES
+The
+.Fn abs
+function
+returns
+the absolute value.
+.Sh SEE ALSO
+.Xr cabs 3 ,
+.Xr fabs 3 ,
+.Xr floor 3 ,
+.Xr hypot 3 ,
+.Xr labs 3 ,
+.Xr math 3
+.Sh STANDARDS
+The
+.Fn abs
+function conforms to
+.St -ansiC .
+.Sh BUGS
+The absolute value of the most negative integer remains negative.
diff --git a/lib/libc/stdlib/abs.c b/lib/libc/stdlib/abs.c
new file mode 100644
index 0000000..013fe53
--- /dev/null
+++ b/lib/libc/stdlib/abs.c
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)abs.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+
+int
+abs(j)
+ int j;
+{
+ return(j < 0 ? -j : j);
+}
diff --git a/lib/libc/stdlib/alloca.3 b/lib/libc/stdlib/alloca.3
new file mode 100644
index 0000000..e3edce8
--- /dev/null
+++ b/lib/libc/stdlib/alloca.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)alloca.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ALLOCA 3
+.Os BSD 4
+.Sh NAME
+.Nm alloca
+.Nd memory allocator
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft void *
+.Fn alloca "size_t size"
+.Sh DESCRIPTION
+The
+.Fn alloca
+function
+allocates
+.Fa size
+bytes of space in the stack frame of the caller.
+This temporary space is automatically freed on
+return.
+.Sh RETURN VALUES
+The
+.Fn alloca
+function returns a pointer to the beginning of the allocated space.
+If the allocation failed, a
+.Dv NULL
+pointer is returned.
+.Sh SEE ALSO
+.Xr brk 2 ,
+.Xr calloc 3 ,
+.Xr getpagesize 3 ,
+.Xr malloc 3 ,
+.Xr realloc 3
+.Sh BUGS
+The
+.Fn alloca
+function
+is machine dependent; its use is discouraged.
+.\" .Sh HISTORY
+.\" The
+.\" .Fn alloca
+.\" function appeared in
+.\" .Bx ?? .
+.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd
+.\" The first man page (or link to a man page that I can find at the
+.\" moment is 4.3...
diff --git a/lib/libc/stdlib/atexit.3 b/lib/libc/stdlib/atexit.3
new file mode 100644
index 0000000..1ba69fb
--- /dev/null
+++ b/lib/libc/stdlib/atexit.3
@@ -0,0 +1,78 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)atexit.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ATEXIT 3
+.Os
+.Sh NAME
+.Nm atexit
+.Nd register a function to be called on exit
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft int
+.Fn atexit "void (*function)(void)"
+.Sh DESCRIPTION
+The
+.Fn atexit
+function
+registers the given
+.Ar function
+to be called at program exit, whether via
+.Xr exit 3
+or via return from the program's
+.Em main .
+Functions so registered are called in reverse order;
+no arguments are passed.
+At least 32 functions can always be registered,
+and more are allowed as long as sufficient memory can be allocated.
+.Sh RETURN VALUES
+.Rv -std atexit
+.Sh ERRORS
+.Bl -tag -width [ENOMEM]
+.It Bq Er ENOMEM
+No memory was available to add the function to the list.
+The existing list of functions is unmodified.
+.El
+.Sh SEE ALSO
+.Xr exit 3
+.Sh STANDARDS
+The
+.Fn atexit
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/stdlib/atexit.c b/lib/libc/stdlib/atexit.c
new file mode 100644
index 0000000..a65dae5
--- /dev/null
+++ b/lib/libc/stdlib/atexit.c
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)atexit.c 8.2 (Berkeley) 7/3/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "atexit.h"
+
+struct atexit *__atexit; /* points to head of LIFO stack */
+
+/*
+ * Register a function to be performed at exit.
+ */
+int
+atexit(fn)
+ void (*fn)();
+{
+ static struct atexit __atexit0; /* one guaranteed table */
+ register struct atexit *p;
+
+ if ((p = __atexit) == NULL)
+ __atexit = p = &__atexit0;
+ else if (p->ind >= ATEXIT_SIZE) {
+ if ((p = (struct atexit *)sbrk(sizeof(*p))) == (struct atexit *)-1)
+ return (-1);
+ p->ind = 0;
+ p->next = __atexit;
+ __atexit = p;
+ }
+ p->fns[p->ind++] = fn;
+ return (0);
+}
diff --git a/lib/libc/stdlib/atexit.h b/lib/libc/stdlib/atexit.h
new file mode 100644
index 0000000..819151e
--- /dev/null
+++ b/lib/libc/stdlib/atexit.h
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)atexit.h 8.2 (Berkeley) 7/3/94
+ */
+
+/* must be at least 32 to guarantee ANSI conformance */
+#define ATEXIT_SIZE 32
+
+struct atexit {
+ struct atexit *next; /* next in list */
+ int ind; /* next index in this table */
+ void (*fns[ATEXIT_SIZE])(); /* the table itself */
+};
+
+extern struct atexit *__atexit; /* points to head of LIFO stack */
diff --git a/lib/libc/stdlib/atof.3 b/lib/libc/stdlib/atof.3
new file mode 100644
index 0000000..d09bcee
--- /dev/null
+++ b/lib/libc/stdlib/atof.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)atof.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ATOF 3
+.Os
+.Sh NAME
+.Nm atof
+.Nd convert
+.Tn ASCII
+string to double
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft double
+.Fn atof "const char *nptr"
+.Sh DESCRIPTION
+The
+.Fn atof
+function converts the initial portion of the string pointed to by
+.Ar nptr
+to
+.Ar double
+representation.
+.Pp
+It is equivalent to:
+.Bd -literal -offset indent
+strtod(nptr, (char **)NULL);
+.Ed
+.Sh SEE ALSO
+.Xr atoi 3 ,
+.Xr atol 3 ,
+.Xr strtod 3 ,
+.Xr strtol 3 ,
+.Xr strtoul 3
+.Sh STANDARDS
+The
+.Fn atof
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/stdlib/atof.c b/lib/libc/stdlib/atof.c
new file mode 100644
index 0000000..130e285
--- /dev/null
+++ b/lib/libc/stdlib/atof.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)atof.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <stddef.h>
+
+double
+atof(ascii)
+ const char *ascii;
+{
+ return (strtod(ascii, NULL));
+}
diff --git a/lib/libc/stdlib/atoi.3 b/lib/libc/stdlib/atoi.3
new file mode 100644
index 0000000..8292c91
--- /dev/null
+++ b/lib/libc/stdlib/atoi.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)atoi.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ATOI 3
+.Os
+.Sh NAME
+.Nm atoi
+.Nd convert
+.Tn ASCII
+string to integer
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft int
+.Fn atoi "const char *nptr"
+.Sh DESCRIPTION
+The
+.Fn atoi
+function converts the initial portion of the string pointed to by
+.Em nptr
+to
+.Em integer
+representation.
+.Pp
+It is equivalent to:
+.Bd -literal -offset indent
+(int)strtol(nptr, (char **)NULL, 10);
+.Ed
+.Sh SEE ALSO
+.Xr atof 3 ,
+.Xr atol 3 ,
+.Xr strtod 3 ,
+.Xr strtol 3 ,
+.Xr strtoul 3
+.Sh STANDARDS
+The
+.Fn atoi
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/stdlib/atoi.c b/lib/libc/stdlib/atoi.c
new file mode 100644
index 0000000..48e508a
--- /dev/null
+++ b/lib/libc/stdlib/atoi.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)atoi.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <stddef.h>
+
+int
+atoi(str)
+ const char *str;
+{
+ return((int)strtol(str, (char **)NULL, 10));
+}
diff --git a/lib/libc/stdlib/atol.3 b/lib/libc/stdlib/atol.3
new file mode 100644
index 0000000..0165f60
--- /dev/null
+++ b/lib/libc/stdlib/atol.3
@@ -0,0 +1,75 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)atol.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ATOL 3
+.Os
+.Sh NAME
+.Nm atol
+.Nd convert
+.Tn ASCII
+string to long integer
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft long
+.Fn atol "const char *nptr"
+.Sh DESCRIPTION
+The
+.Fn atol
+function converts the initial portion of the string pointed to by
+.Ar nptr
+to
+.Em long integer
+representation.
+.Pp
+It is equivalent to:
+.Bd -literal -offset indent
+strtol(nptr, (char **)NULL, 10);
+.Ed
+.Sh SEE ALSO
+.Xr atof 3 ,
+.Xr atoi 3 ,
+.Xr strtod 3 ,
+.Xr strtol 3 ,
+.Xr strtoul 3
+.Sh STANDARDS
+The
+.Fn atol
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/stdlib/atol.c b/lib/libc/stdlib/atol.c
new file mode 100644
index 0000000..31bcaa6
--- /dev/null
+++ b/lib/libc/stdlib/atol.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)atol.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <stdlib.h>
+
+long
+atol(str)
+ const char *str;
+{
+ return(strtol(str, (char **)NULL, 10));
+}
diff --git a/lib/libc/stdlib/bsearch.3 b/lib/libc/stdlib/bsearch.3
new file mode 100644
index 0000000..6a7c06f
--- /dev/null
+++ b/lib/libc/stdlib/bsearch.3
@@ -0,0 +1,91 @@
+.\" Copyright (c) 1990, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)bsearch.3 8.3 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt BSEARCH 3
+.Os
+.Sh NAME
+.Nm bsearch
+.Nd binary search of a sorted table
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft void *
+.Fn bsearch "const void *key" "const void *base" "size_t nmemb" "size_t size" "int (*compar) (const void *, const void *)"
+.Sh DESCRIPTION
+The
+.Fn bsearch
+function searches an array of
+.Fa nmemb
+objects, the initial member of which is
+pointed to by
+.Fa base ,
+for a member that matches the object pointed to by
+.Fa key .
+The size of each member of the array is specified by
+.Fa size .
+.Pp
+The contents of the array should be in ascending sorted order according
+to the comparison function referenced by
+.Fa compar .
+The
+.Fa compar
+routine
+is expected to have
+two arguments which point to the
+.Fa key
+object and to an array member, in that order, and should return an integer
+less than, equal to, or greater than zero if the
+.Fa key
+object is found, respectively, to be less than, to match, or be
+greater than the array member.
+.Sh RETURN VALUES
+The
+.Fn bsearch
+function returns a pointer to a matching member of the array, or a null
+pointer if no match is found.
+If two members compare as equal, which member is matched is unspecified.
+.Sh SEE ALSO
+.Xr db 3 ,
+.Xr lsearch 3 ,
+.Xr qsort 3
+.\" .Xr tsearch 3
+.Sh STANDARDS
+The
+.Fn bsearch
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/stdlib/bsearch.c b/lib/libc/stdlib/bsearch.c
new file mode 100644
index 0000000..4cee9de
--- /dev/null
+++ b/lib/libc/stdlib/bsearch.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bsearch.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <stdlib.h>
+
+/*
+ * Perform a binary search.
+ *
+ * The code below is a bit sneaky. After a comparison fails, we
+ * divide the work in half by moving either left or right. If lim
+ * is odd, moving left simply involves halving lim: e.g., when lim
+ * is 5 we look at item 2, so we change lim to 2 so that we will
+ * look at items 0 & 1. If lim is even, the same applies. If lim
+ * is odd, moving right again involes halving lim, this time moving
+ * the base up one item past p: e.g., when lim is 5 we change base
+ * to item 3 and make lim 2 so that we will look at items 3 and 4.
+ * If lim is even, however, we have to shrink it by one before
+ * halving: e.g., when lim is 4, we still looked at item 2, so we
+ * have to make lim 3, then halve, obtaining 1, so that we will only
+ * look at item 3.
+ */
+void *
+bsearch(key, base0, nmemb, size, compar)
+ register const void *key;
+ const void *base0;
+ size_t nmemb;
+ register size_t size;
+ register int (*compar) __P((const void *, const void *));
+{
+ register const char *base = base0;
+ register size_t lim;
+ register int cmp;
+ register const void *p;
+
+ for (lim = nmemb; lim != 0; lim >>= 1) {
+ p = base + (lim >> 1) * size;
+ cmp = (*compar)(key, p);
+ if (cmp == 0)
+ return ((void *)p);
+ if (cmp > 0) { /* key > p: move right */
+ base = (char *)p + size;
+ lim--;
+ } /* else move left */
+ }
+ return (NULL);
+}
diff --git a/lib/libc/stdlib/calloc.c b/lib/libc/stdlib/calloc.c
new file mode 100644
index 0000000..7a83603
--- /dev/null
+++ b/lib/libc/stdlib/calloc.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)calloc.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <string.h>
+
+void *
+calloc(num, size)
+ size_t num;
+ register size_t size;
+{
+ register void *p;
+
+ size *= num;
+ if ( (p = malloc(size)) )
+ bzero(p, size);
+ return(p);
+}
diff --git a/lib/libc/stdlib/div.3 b/lib/libc/stdlib/div.3
new file mode 100644
index 0000000..f596aa3
--- /dev/null
+++ b/lib/libc/stdlib/div.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)div.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt DIV 3
+.Os
+.Sh NAME
+.Nm div
+.Nd return quotient and remainder from division
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft div_t
+.Fn div "int num" "int denom"
+.Sh DESCRIPTION
+The
+.Fn div
+function
+computes the value
+.Fa num/denom
+and returns the quotient and remainder in a structure named
+.Fa div_t
+that contains two
+.Em int
+members named
+.Fa quot
+and
+.Fa rem .
+.Sh SEE ALSO
+.Xr ldiv 3
+.Sh STANDARDS
+The
+.Fn div
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/stdlib/div.c b/lib/libc/stdlib/div.c
new file mode 100644
index 0000000..d7bde163
--- /dev/null
+++ b/lib/libc/stdlib/div.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)div.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h> /* div_t */
+
+div_t
+div(num, denom)
+ int num, denom;
+{
+ div_t r;
+
+ r.quot = num / denom;
+ r.rem = num % denom;
+ /*
+ * The ANSI standard says that |r.quot| <= |n/d|, where
+ * n/d is to be computed in infinite precision. In other
+ * words, we should always truncate the quotient towards
+ * 0, never -infinity.
+ *
+ * Machine division and remainer may work either way when
+ * one or both of n or d is negative. If only one is
+ * negative and r.quot has been truncated towards -inf,
+ * r.rem will have the same sign as denom and the opposite
+ * sign of num; if both are negative and r.quot has been
+ * truncated towards -inf, r.rem will be positive (will
+ * have the opposite sign of num). These are considered
+ * `wrong'.
+ *
+ * If both are num and denom are positive, r will always
+ * be positive.
+ *
+ * This all boils down to:
+ * if num >= 0, but r.rem < 0, we got the wrong answer.
+ * In that case, to get the right answer, add 1 to r.quot and
+ * subtract denom from r.rem.
+ */
+ if (num >= 0 && r.rem < 0) {
+ r.quot++;
+ r.rem -= denom;
+ }
+ return (r);
+}
diff --git a/lib/libc/stdlib/exit.3 b/lib/libc/stdlib/exit.3
new file mode 100644
index 0000000..15531f9
--- /dev/null
+++ b/lib/libc/stdlib/exit.3
@@ -0,0 +1,96 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)exit.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt EXIT 3
+.Os
+.Sh NAME
+.Nm exit
+.Nd perform normal program termination
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft void
+.Fn exit "int status"
+.Sh DESCRIPTION
+.Fn Exit
+terminates a process.
+.Pp
+Before termination it performs the following functions in the
+order listed:
+.Bl -enum -offset indent
+.It
+Call the functions registered with the
+.Xr atexit 3
+function, in the reverse order of their registration.
+.It
+Flush all open output streams.
+.It
+Close all open streams.
+.It
+Unlink all files created with the
+.Xr tmpfile 3
+function.
+.El
+.Pp
+Passing arbitrary values back to the environment as
+.Ar status
+is considered bad style;
+you should use the values
+.Dv EXIT_SUCCESS
+and
+.Dv EXIT_FAILURE .
+If portability is not a concern, you may
+use the values described in
+.Xr sysexits 3 .
+.Sh RETURN VALUES
+The
+.Fn exit
+function
+never returns.
+.Sh SEE ALSO
+.Xr _exit 2 ,
+.Xr atexit 3 ,
+.Xr intro 3 ,
+.Xr sysexits 3 ,
+.Xr tmpfile 3
+.Sh STANDARDS
+The
+.Fn exit
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/stdlib/exit.c b/lib/libc/stdlib/exit.c
new file mode 100644
index 0000000..b0f6d3a
--- /dev/null
+++ b/lib/libc/stdlib/exit.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)exit.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include "atexit.h"
+
+void (*__cleanup)();
+
+/*
+ * This variable is zero until a process has created a thread.
+ * It is used to avoid calling locking functions in libc when they
+ * are not required. By default, libc is intended to be(come)
+ * thread-safe, but without a (significant) penalty to non-threaded
+ * processes.
+ */
+int __isthreaded = 0;
+
+/*
+ * Exit, flushing stdio buffers if necessary.
+ */
+void
+exit(status)
+ int status;
+{
+ register struct atexit *p;
+ register int n;
+
+#ifdef _THREAD_SAFE
+ extern int _thread_autoinit_dummy_decl;
+ /* Ensure that the auto-initialization routine is linked in: */
+ _thread_autoinit_dummy_decl = 1;
+#endif
+
+ for (p = __atexit; p; p = p->next)
+ for (n = p->ind; --n >= 0;)
+ (*p->fns[n])();
+ if (__cleanup)
+ (*__cleanup)();
+ _exit(status);
+}
diff --git a/lib/libc/stdlib/getenv.3 b/lib/libc/stdlib/getenv.3
new file mode 100644
index 0000000..3347bda
--- /dev/null
+++ b/lib/libc/stdlib/getenv.3
@@ -0,0 +1,152 @@
+.\" Copyright (c) 1988, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getenv.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt GETENV 3
+.Os
+.Sh NAME
+.Nm getenv ,
+.Nm putenv ,
+.Nm setenv ,
+.Nm unsetenv
+.Nd environment variable functions
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft char *
+.Fn getenv "const char *name"
+.Ft int
+.Fn setenv "const char *name" "const char *value" "int overwrite"
+.Ft int
+.Fn putenv "const char *string"
+.Ft void
+.Fn unsetenv "const char *name"
+.Sh DESCRIPTION
+These functions set, unset and fetch environment variables from the
+host
+.Em environment list .
+For compatibility with differing environment conventions,
+the given arguments
+.Ar name
+and
+.Ar value
+may be appended and prepended,
+respectively,
+with an equal sign
+.Dq Li \&= .
+.Pp
+The
+.Fn getenv
+function obtains the current value of the environment variable,
+.Ar name .
+If the variable
+.Ar name
+is not in the current environment,
+a null pointer is returned.
+.Pp
+The
+.Fn setenv
+function inserts or resets the environment variable
+.Ar name
+in the current environment list.
+If the variable
+.Ar name
+does not exist in the list,
+it is inserted with the given
+.Ar value.
+If the variable does exist, the argument
+.Ar overwrite
+is tested; if
+.Ar overwrite is
+zero, the
+variable is not reset, otherwise it is reset
+to the given
+.Ar value .
+.Pp
+The
+.Fn putenv
+function takes an argument of the form ``name=value'' and is
+equivalent to:
+.Bd -literal -offset indent
+setenv(name, value, 1);
+.Ed
+.Pp
+The
+.Fn unsetenv
+function
+deletes all instances of the variable name pointed to by
+.Fa name
+from the list.
+.Sh RETURN VALUES
+The functions
+.Fn setenv
+and
+.Fn putenv
+return zero if successful; otherwise the global variable
+.Va errno
+is set to indicate the error and a
+\-1 is returned.
+.Sh ERRORS
+.Bl -tag -width [ENOMEM]
+.It Bq Er ENOMEM
+The function
+.Fn setenv
+or
+.Fn putenv
+failed because they were unable to allocate memory for the environment.
+.El
+.Sh SEE ALSO
+.Xr csh 1 ,
+.Xr sh 1 ,
+.Xr execve 2 ,
+.Xr environ 7
+.Sh STANDARDS
+The
+.Fn getenv
+function conforms to
+.St -ansiC .
+.Sh HISTORY
+The functions
+.Fn setenv
+and
+.Fn unsetenv
+appeared in
+.At v7 .
+The
+.Fn putenv
+function appeared in
+.Bx 4.3 Reno .
diff --git a/lib/libc/stdlib/getenv.c b/lib/libc/stdlib/getenv.c
new file mode 100644
index 0000000..a6bbd35
--- /dev/null
+++ b/lib/libc/stdlib/getenv.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getenv.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+inline char *__findenv __P((const char *, int *));
+
+/*
+ * __findenv --
+ * Returns pointer to value associated with name, if any, else NULL.
+ * Sets offset to be the offset of the name/value combination in the
+ * environmental array, for use by setenv(3) and unsetenv(3).
+ * Explicitly removes '=' in argument name.
+ *
+ * This routine *should* be a static; don't use it.
+ */
+inline char *
+__findenv(name, offset)
+ register const char *name;
+ int *offset;
+{
+ extern char **environ;
+ register int len, i;
+ register const char *np;
+ register char **p, *cp;
+
+ if (name == NULL || environ == NULL)
+ return (NULL);
+ for (np = name; *np && *np != '='; ++np)
+ continue;
+ len = np - name;
+ for (p = environ; (cp = *p) != NULL; ++p) {
+ for (np = name, i = len; i && *cp; i--)
+ if (*cp++ != *np++)
+ break;
+ if (i == 0 && *cp++ == '=') {
+ *offset = p - environ;
+ return (cp);
+ }
+ }
+ return (NULL);
+}
+
+/*
+ * getenv --
+ * Returns ptr to value associated with name, if any, else NULL.
+ */
+char *
+getenv(name)
+ const char *name;
+{
+ int offset;
+
+ return (__findenv(name, &offset));
+}
diff --git a/lib/libc/stdlib/getopt.3 b/lib/libc/stdlib/getopt.3
new file mode 100644
index 0000000..51f7ffb
--- /dev/null
+++ b/lib/libc/stdlib/getopt.3
@@ -0,0 +1,262 @@
+.\" Copyright (c) 1988, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getopt.3 8.5 (Berkeley) 4/27/95
+.\" $FreeBSD$
+.\"
+.Dd April 27, 1995
+.Dt GETOPT 3
+.Os BSD 4.3
+.Sh NAME
+.Nm getopt
+.Nd get option character from command line argument list
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Vt extern char *optarg;
+.Vt extern int optind;
+.Vt extern int optopt;
+.Vt extern int opterr;
+.Vt extern int optreset;
+.Ft int
+.Fn getopt "int argc" "char * const *argv" "const char *optstring"
+.Sh DESCRIPTION
+The
+.Fn getopt
+function incrementally parses a command line argument list
+.Fa argv
+and returns the next
+.Em known
+option character.
+An option character is
+.Em known
+if it has been specified in the string of accepted option characters,
+.Fa optstring .
+.Pp
+The option string
+.Fa optstring
+may contain the following elements: individual characters, and
+characters followed by a colon to indicate an option argument
+is to follow.
+For example, an option string
+.Li "\&""x""
+recognizes an option
+.Dq Fl x ,
+and an option string
+.Li "\&""x:""
+recognizes an option and argument
+.Dq Fl x Ar argument .
+It does not matter to
+.Fn getopt
+if a following argument has leading white space.
+.Pp
+On return from
+.Fn getopt ,
+.Va optarg
+points to an option argument, if it is anticipated,
+and the variable
+.Va optind
+contains the index to the next
+.Fa argv
+argument for a subsequent call
+to
+.Fn getopt .
+The variable
+.Va optopt
+saves the last
+.Em known
+option character returned by
+.Fn getopt .
+.Pp
+The variable
+.Va opterr
+and
+.Va optind
+are both initialized to 1.
+The
+.Va optind
+variable may be set to another value before a set of calls to
+.Fn getopt
+in order to skip over more or less argv entries.
+.Pp
+In order to use
+.Fn getopt
+to evaluate multiple sets of arguments, or to evaluate a single set of
+arguments multiple times,
+the variable
+.Va optreset
+must be set to 1 before the second and each additional set of calls to
+.Fn getopt ,
+and the variable
+.Va optind
+must be reinitialized.
+.Pp
+The
+.Fn getopt
+function
+returns \-1
+when the argument list is exhausted, or
+.Ql ?
+if a non-recognized
+option is encountered.
+The interpretation of options in the argument list may be canceled
+by the option
+.Ql --
+(double dash) which causes
+.Fn getopt
+to signal the end of argument processing and return \-1.
+When all options have been processed (i.e., up to the first non-option
+argument),
+.Fn getopt
+returns \-1.
+.Sh DIAGNOSTICS
+If the
+.Fn getopt
+function encounters a character not found in the string
+.Va optarg
+or detects
+a missing option argument it writes an error message to the
+.Em stderr
+and returns
+.Ql ? .
+Setting
+.Va opterr
+to a zero will disable these error messages.
+If
+.Va optstring
+has a leading
+.Ql \&:
+then a missing option argument causes a
+.Ql \&:
+to be returned in addition to suppressing any error messages.
+.Pp
+Option arguments are allowed to begin with
+.Dq Li \- ;
+this is reasonable but
+reduces the amount of error checking possible.
+.Sh EXTENSIONS
+The
+.Va optreset
+variable was added to make it possible to call the
+.Fn getopt
+function multiple times.
+This is an extension to the
+.St -p1003.2
+specification.
+.Sh EXAMPLE
+.Bd -literal -compact
+extern char *optarg;
+extern int optind;
+int bflag, ch, fd;
+
+bflag = 0;
+while ((ch = getopt(argc, argv, "bf:")) != -1)
+ switch (ch) {
+ case 'b':
+ bflag = 1;
+ break;
+ case 'f':
+ if ((fd = open(optarg, O_RDONLY, 0)) < 0) {
+ (void)fprintf(stderr,
+ "myname: %s: %s\en", optarg, strerror(errno));
+ exit(1);
+ }
+ break;
+ case '?':
+ default:
+ usage();
+ }
+argc -= optind;
+argv += optind;
+.Ed
+.Sh HISTORY
+The
+.Fn getopt
+function appeared in
+.Bx 4.3 .
+.Sh BUGS
+The
+.Fn getopt
+function was once specified to return
+.Dv EOF
+instead of \-1.
+This was changed by
+.St -p1003.2-92
+to decouple
+.Fn getopt
+from
+.Pa <stdio.h> .
+.Pp
+A single dash
+.Dq Li -
+may be specified as a character in
+.Fa optstring ,
+however it should
+.Em never
+have an argument associated with it.
+This allows
+.Fn getopt
+to be used with programs that expect
+.Dq Li -
+as an option flag.
+This practice is wrong, and should not be used in any current development.
+It is provided for backward compatibility
+.Em only .
+By default, a single dash causes
+.Fn getopt
+to return \-1.
+This is, we believe, compatible with System V.
+.Pp
+It is also possible to handle digits as option letters.
+This allows
+.Fn getopt
+to be used with programs that expect a number
+.Pq Dq Li \&-\&3
+as an option.
+This practice is wrong, and should not be used in any current development.
+It is provided for backward compatibility
+.Em only .
+The following code fragment works in most cases.
+.Bd -literal -offset indent
+int length;
+char *p;
+
+while ((ch = getopt(argc, argv, "0123456789")) != -1)
+ switch (ch) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ p = argv[optind - 1];
+ if (p[0] == '-' && p[1] == ch && !p[2])
+ length = atoi(++p);
+ else
+ length = atoi(argv[optind] + 1);
+ break;
+ }
+.Ed
diff --git a/lib/libc/stdlib/getopt.c b/lib/libc/stdlib/getopt.c
new file mode 100644
index 0000000..1b297a7
--- /dev/null
+++ b/lib/libc/stdlib/getopt.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
+#endif
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int opterr = 1, /* if error message should be printed */
+ optind = 1, /* index into parent argv vector */
+ optopt, /* character checked for validity */
+ optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define BADARG (int)':'
+#define EMSG ""
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt(nargc, nargv, ostr)
+ int nargc;
+ char * const *nargv;
+ const char *ostr;
+{
+ extern char *__progname;
+ static char *place = EMSG; /* option letter processing */
+ char *oli; /* option letter list index */
+ int ret;
+
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc || *(place = nargv[optind]) != '-') {
+ place = EMSG;
+ return (-1);
+ }
+ if (place[1] && *++place == '-') { /* found "--" */
+ ++optind;
+ place = EMSG;
+ return (-1);
+ }
+ } /* option letter okay? */
+ if ((optopt = (int)*place++) == (int)':' ||
+ !(oli = strchr(ostr, optopt))) {
+ /*
+ * if the user didn't specify '-' as an option,
+ * assume it means -1.
+ */
+ if (optopt == (int)'-')
+ return (-1);
+ if (!*place)
+ ++optind;
+ if (opterr && *ostr != ':')
+ (void)fprintf(stderr,
+ "%s: illegal option -- %c\n", __progname, optopt);
+ return (BADCH);
+ }
+ if (*++oli != ':') { /* don't need argument */
+ optarg = NULL;
+ if (!*place)
+ ++optind;
+ }
+ else { /* need an argument */
+ if (*place) /* no white space */
+ optarg = place;
+ else if (nargc <= ++optind) { /* no arg */
+ place = EMSG;
+ if (*ostr == ':')
+ ret = BADARG;
+ else
+ ret = BADCH;
+ if (opterr)
+ (void)fprintf(stderr,
+ "%s: option requires an argument -- %c\n",
+ __progname, optopt);
+ return (ret);
+ }
+ else /* white space */
+ optarg = nargv[optind];
+ place = EMSG;
+ ++optind;
+ }
+ return (optopt); /* dump back option letter */
+}
diff --git a/lib/libc/stdlib/getsubopt.3 b/lib/libc/stdlib/getsubopt.3
new file mode 100644
index 0000000..62898dc
--- /dev/null
+++ b/lib/libc/stdlib/getsubopt.3
@@ -0,0 +1,147 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getsubopt.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt GETSUBOPT 3
+.Os
+.Sh NAME
+.Nm getsubopt
+.Nd get sub options from an argument
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Vt extern char *suboptarg
+.Ft int
+.Fn getsubopt "char **optionp" "char * const *tokens" "char **valuep"
+.Sh DESCRIPTION
+The
+.Fn getsubopt
+function
+parses a string containing tokens delimited by one or more tab, space or
+comma
+.Pq Ql \&,
+characters.
+It is intended for use in parsing groups of option arguments provided
+as part of a utility command line.
+.Pp
+The argument
+.Fa optionp
+is a pointer to a pointer to the string.
+The argument
+.Fa tokens
+is a pointer to a
+.Dv NULL Ns -terminated
+array of pointers to strings.
+.Pp
+The
+.Fn getsubopt
+function
+returns the zero-based offset of the pointer in the
+.Fa tokens
+array referencing a string which matches the first token
+in the string, or, \-1 if the string contains no tokens or
+.Fa tokens
+does not contain a matching string.
+.Pp
+If the token is of the form ``name=value'', the location referenced by
+.Fa valuep
+will be set to point to the start of the ``value'' portion of the token.
+.Pp
+On return from
+.Fn getsubopt ,
+.Fa optionp
+will be set to point to the start of the next token in the string,
+or the null at the end of the string if no more tokens are present.
+The external variable
+.Fa suboptarg
+will be set to point to the start of the current token, or
+.Dv NULL
+if no
+tokens were present.
+The argument
+.Fa valuep
+will be set to point to the ``value'' portion of the token, or
+.Dv NULL
+if no ``value'' portion was present.
+.Sh EXAMPLE
+.Bd -literal -compact
+char *tokens[] = {
+ #define ONE 0
+ "one",
+ #define TWO 1
+ "two",
+ NULL
+};
+
+\&...
+
+extern char *optarg, *suboptarg;
+char *options, *value;
+
+while ((ch = getopt(argc, argv, "ab:")) != \-1) {
+ switch(ch) {
+ case 'a':
+ /* process ``a'' option */
+ break;
+ case 'b':
+ options = optarg;
+ while (*options) {
+ switch(getsubopt(&options, tokens, &value)) {
+ case ONE:
+ /* process ``one'' sub option */
+ break;
+ case TWO:
+ /* process ``two'' sub option */
+ if (!value)
+ error("no value for two");
+ i = atoi(value);
+ break;
+ case \-1:
+ if (suboptarg)
+ error("illegal sub option %s",
+ suboptarg);
+ else
+ error("missing sub option");
+ break;
+ }
+ break;
+ }
+.Ed
+.Sh SEE ALSO
+.Xr getopt 3 ,
+.Xr strsep 3
+.Sh HISTORY
+The
+.Fn getsubopt
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/stdlib/getsubopt.c b/lib/libc/stdlib/getsubopt.c
new file mode 100644
index 0000000..bc055b8
--- /dev/null
+++ b/lib/libc/stdlib/getsubopt.c
@@ -0,0 +1,99 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)getsubopt.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <unistd.h>
+#include <stdlib.h>
+
+/*
+ * The SVID interface to getsubopt provides no way of figuring out which
+ * part of the suboptions list wasn't matched. This makes error messages
+ * tricky... The extern variable suboptarg is a pointer to the token
+ * which didn't match.
+ */
+char *suboptarg;
+
+int
+getsubopt(optionp, tokens, valuep)
+ register char **optionp, **valuep;
+ register char * const *tokens;
+{
+ register int cnt;
+ register char *p;
+
+ suboptarg = *valuep = NULL;
+
+ if (!optionp || !*optionp)
+ return(-1);
+
+ /* skip leading white-space, commas */
+ for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
+
+ if (!*p) {
+ *optionp = p;
+ return(-1);
+ }
+
+ /* save the start of the token, and skip the rest of the token. */
+ for (suboptarg = p;
+ *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
+
+ if (*p) {
+ /*
+ * If there's an equals sign, set the value pointer, and
+ * skip over the value part of the token. Terminate the
+ * token.
+ */
+ if (*p == '=') {
+ *p = '\0';
+ for (*valuep = ++p;
+ *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
+ if (*p)
+ *p++ = '\0';
+ } else
+ *p++ = '\0';
+ /* Skip any whitespace or commas after this token. */
+ for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
+ }
+
+ /* set optionp for next round. */
+ *optionp = p;
+
+ for (cnt = 0; *tokens; ++tokens, ++cnt)
+ if (!strcmp(suboptarg, *tokens))
+ return(cnt);
+ return(-1);
+}
diff --git a/lib/libc/stdlib/heapsort.c b/lib/libc/stdlib/heapsort.c
new file mode 100644
index 0000000..9649553
--- /dev/null
+++ b/lib/libc/stdlib/heapsort.c
@@ -0,0 +1,183 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ronnie Kon at Mindcraft Inc., Kevin Lew and Elmer Yglesias.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)heapsort.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+/*
+ * Swap two areas of size number of bytes. Although qsort(3) permits random
+ * blocks of memory to be sorted, sorting pointers is almost certainly the
+ * common case (and, were it not, could easily be made so). Regardless, it
+ * isn't worth optimizing; the SWAP's get sped up by the cache, and pointer
+ * arithmetic gets lost in the time required for comparison function calls.
+ */
+#define SWAP(a, b, count, size, tmp) { \
+ count = size; \
+ do { \
+ tmp = *a; \
+ *a++ = *b; \
+ *b++ = tmp; \
+ } while (--count); \
+}
+
+/* Copy one block of size size to another. */
+#define COPY(a, b, count, size, tmp1, tmp2) { \
+ count = size; \
+ tmp1 = a; \
+ tmp2 = b; \
+ do { \
+ *tmp1++ = *tmp2++; \
+ } while (--count); \
+}
+
+/*
+ * Build the list into a heap, where a heap is defined such that for
+ * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N.
+ *
+ * There two cases. If j == nmemb, select largest of Ki and Kj. If
+ * j < nmemb, select largest of Ki, Kj and Kj+1.
+ */
+#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \
+ for (par_i = initval; (child_i = par_i * 2) <= nmemb; \
+ par_i = child_i) { \
+ child = base + child_i * size; \
+ if (child_i < nmemb && compar(child, child + size) < 0) { \
+ child += size; \
+ ++child_i; \
+ } \
+ par = base + par_i * size; \
+ if (compar(child, par) <= 0) \
+ break; \
+ SWAP(par, child, count, size, tmp); \
+ } \
+}
+
+/*
+ * Select the top of the heap and 'heapify'. Since by far the most expensive
+ * action is the call to the compar function, a considerable optimization
+ * in the average case can be achieved due to the fact that k, the displaced
+ * elememt, is ususally quite small, so it would be preferable to first
+ * heapify, always maintaining the invariant that the larger child is copied
+ * over its parent's record.
+ *
+ * Then, starting from the *bottom* of the heap, finding k's correct place,
+ * again maintianing the invariant. As a result of the invariant no element
+ * is 'lost' when k is assigned its correct place in the heap.
+ *
+ * The time savings from this optimization are on the order of 15-20% for the
+ * average case. See Knuth, Vol. 3, page 158, problem 18.
+ *
+ * XXX Don't break the #define SELECT line, below. Reiser cpp gets upset.
+ */
+#define SELECT(par_i, child_i, nmemb, par, child, size, k, count, tmp1, tmp2) { \
+ for (par_i = 1; (child_i = par_i * 2) <= nmemb; par_i = child_i) { \
+ child = base + child_i * size; \
+ if (child_i < nmemb && compar(child, child + size) < 0) { \
+ child += size; \
+ ++child_i; \
+ } \
+ par = base + par_i * size; \
+ COPY(par, child, count, size, tmp1, tmp2); \
+ } \
+ for (;;) { \
+ child_i = par_i; \
+ par_i = child_i / 2; \
+ child = base + child_i * size; \
+ par = base + par_i * size; \
+ if (child_i == 1 || compar(k, par) < 0) { \
+ COPY(child, k, count, size, tmp1, tmp2); \
+ break; \
+ } \
+ COPY(child, par, count, size, tmp1, tmp2); \
+ } \
+}
+
+/*
+ * Heapsort -- Knuth, Vol. 3, page 145. Runs in O (N lg N), both average
+ * and worst. While heapsort is faster than the worst case of quicksort,
+ * the BSD quicksort does median selection so that the chance of finding
+ * a data set that will trigger the worst case is nonexistent. Heapsort's
+ * only advantage over quicksort is that it requires little additional memory.
+ */
+int
+heapsort(vbase, nmemb, size, compar)
+ void *vbase;
+ size_t nmemb, size;
+ int (*compar) __P((const void *, const void *));
+{
+ register int cnt, i, j, l;
+ register char tmp, *tmp1, *tmp2;
+ char *base, *k, *p, *t;
+
+ if (nmemb <= 1)
+ return (0);
+
+ if (!size) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if ((k = malloc(size)) == NULL)
+ return (-1);
+
+ /*
+ * Items are numbered from 1 to nmemb, so offset from size bytes
+ * below the starting address.
+ */
+ base = (char *)vbase - size;
+
+ for (l = nmemb / 2 + 1; --l;)
+ CREATE(l, nmemb, i, j, t, p, size, cnt, tmp);
+
+ /*
+ * For each element of the heap, save the largest element into its
+ * final slot, save the displaced element (k), then recreate the
+ * heap.
+ */
+ while (nmemb > 1) {
+ COPY(k, base + nmemb * size, cnt, size, tmp1, tmp2);
+ COPY(base + nmemb * size, base + size, cnt, size, tmp1, tmp2);
+ --nmemb;
+ SELECT(i, j, nmemb, t, p, size, k, cnt, tmp1, tmp2);
+ }
+ free(k);
+ return (0);
+}
diff --git a/lib/libc/stdlib/labs.3 b/lib/libc/stdlib/labs.3
new file mode 100644
index 0000000..88dfbd6
--- /dev/null
+++ b/lib/libc/stdlib/labs.3
@@ -0,0 +1,67 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)labs.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt LABS 3
+.Os
+.Sh NAME
+.Nm labs
+.Nd return the absolute value of a long integer
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft long
+.Fn labs "long j"
+.Sh DESCRIPTION
+The
+.Fn labs
+function
+returns the absolute value of the long integer
+.Ar j .
+.Sh SEE ALSO
+.Xr abs 3 ,
+.Xr cabs 3 ,
+.Xr floor 3 ,
+.Xr math 3
+.Sh STANDARDS
+The
+.Fn labs
+function
+conforms to
+.St -ansiC .
+.Sh BUGS
+The absolute value of the most negative integer remains negative.
diff --git a/lib/libc/stdlib/labs.c b/lib/libc/stdlib/labs.c
new file mode 100644
index 0000000..4adc398
--- /dev/null
+++ b/lib/libc/stdlib/labs.c
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)labs.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+
+long
+labs(j)
+ long j;
+{
+ return(j < 0 ? -j : j);
+}
diff --git a/lib/libc/stdlib/ldiv.3 b/lib/libc/stdlib/ldiv.3
new file mode 100644
index 0000000..d3b65a8f
--- /dev/null
+++ b/lib/libc/stdlib/ldiv.3
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ldiv.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt LDIV 3
+.Os
+.Sh NAME
+.Nm ldiv
+.Nd return quotient and remainder from division
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft ldiv_t
+.Fn ldiv "long num" "long denom"
+.Sh DESCRIPTION
+The
+.Fn ldiv
+function
+computes the value
+.Ar num/denom
+and returns the quotient and remainder in a structure named
+.Ar ldiv_t
+that contains two
+.Em long integer
+members named
+.Ar quot
+and
+.Ar rem .
+.Sh SEE ALSO
+.Xr div 3 ,
+.Xr math 3
+.Sh STANDARDS
+The
+.Fn ldiv
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/stdlib/ldiv.c b/lib/libc/stdlib/ldiv.c
new file mode 100644
index 0000000..d458efd
--- /dev/null
+++ b/lib/libc/stdlib/ldiv.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ldiv.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h> /* ldiv_t */
+
+ldiv_t
+ldiv(num, denom)
+ long num, denom;
+{
+ ldiv_t r;
+
+ /* see div.c for comments */
+
+ r.quot = num / denom;
+ r.rem = num % denom;
+ if (num >= 0 && r.rem < 0) {
+ r.quot++;
+ r.rem -= denom;
+ }
+ return (r);
+}
diff --git a/lib/libc/stdlib/malloc.3 b/lib/libc/stdlib/malloc.3
new file mode 100644
index 0000000..764bad1
--- /dev/null
+++ b/lib/libc/stdlib/malloc.3
@@ -0,0 +1,448 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)malloc.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd August 27, 1996
+.Dt MALLOC 3
+.Os FreeBSD 2
+.Sh NAME
+.Nm malloc, calloc, realloc, free, reallocf
+.Nd general purpose memory allocation functions
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft void *
+.Fn malloc "size_t size"
+.Ft void *
+.Fn calloc "size_t number" "size_t size"
+.Ft void *
+.Fn realloc "void *ptr" "size_t size"
+.Ft void *
+.Fn reallocf "void *ptr" "size_t size"
+.Ft void
+.Fn free "void *ptr"
+.Ft char *
+.Va malloc_options;
+.Sh DESCRIPTION
+The
+.Fn malloc
+function allocates
+.Fa size
+bytes of memory.
+The allocated space is suitably aligned (after possible pointer coercion)
+for storage of any type of object.
+If the space is at least
+.Em pagesize
+bytes in length (see
+.Xr getpagesize 3 ),
+the returned memory will be page boundary aligned as well.
+If
+.Fn malloc
+fails, a NULL pointer is returned.
+.Pp
+Note that
+.Fn malloc
+does
+.Em NOT
+normally initialize the returned memory to zero bytes.
+.Pp
+The
+.Fn calloc
+function allocates space for
+.Fa number
+objects,
+each
+.Fa size
+bytes in length.
+The result is identical to calling
+.Fn malloc
+with an argument of
+.Dq "number * size" ,
+with the exception that the allocated memory is explicitly initialized
+to zero bytes.
+.Pp
+The
+.Fn realloc
+function changes the size of the previously allocated memory referenced by
+.Fa ptr
+to
+.Fa size
+bytes.
+The contents of the memory are unchanged up to the lesser of the new and
+old sizes.
+If the new size is larger,
+the value of the newly allocated portion of the memory is undefined.
+If the requested memory cannot be allocated, NULL is returned and
+the memory referenced by
+.Fa ptr
+is valid and unchanged.
+If
+.Fa ptr
+is NULL, the
+.Fn realloc
+function behaves identically to
+.Fn malloc
+for the specified size.
+.Pp
+The
+.Fn reallocf
+function call is identical to the realloc function call, except that it
+will free the passed pointer when the requested memory cannot be allocated.
+This is a FreeBSD
+specific API designed to ease the problems with traditional coding styles
+for realloc causing memory leaks in libraries.
+.Pp
+The
+.Fn free
+function causes the allocated memory referenced by
+.Fa ptr
+to be made available for future allocations.
+If
+.Fa ptr
+is NULL, no action occurs.
+.Sh TUNING
+Once, when the first call is made to one of these memory allocation
+routines, various flags will be set or reset, which affect the
+workings of this allocation implementation.
+.Pp
+The ``name'' of the file referenced by the symbolic link named
+.Pa /etc/malloc.conf ,
+the value of the environment variable
+.Ev MALLOC_OPTIONS ,
+and the string pointed to by the global variable
+.Va malloc_options
+will be interpreted, in that order, character by character as flags.
+.Pp
+Most flags are single letters,
+where uppercase indicates that the behavior is set, or on,
+and lowercase means that the behavior is not set, or off.
+.Bl -tag -width indent
+.It A
+All warnings (except for the warning about unknown
+flags being set), and failure to allocate memory become fatal.
+The process will call
+.Xr abort 3
+in these cases.
+.It J
+Each byte of new memory allocated by
+.Fn malloc ,
+.Fn realloc
+or
+.Fn reallocf
+as well as all memory returned by
+.Fn free ,
+.Fn realloc
+or
+.Fn reallocf
+will be initialized to 0xd0.
+This options also sets the
+.Dq R
+option.
+This is intended for debugging and will impact performance negatively.
+.It H
+Pass a hint to the kernel about pages unused by the allocation functions.
+This will help performance if the system is paging excessively. This
+option is off by default.
+.It R
+Causes the
+.Fn realloc
+and
+.Fn reallocf
+functions to always reallocate memory even if the initial allocation was
+sufficiently large.
+This can substantially aid in compacting memory.
+.It U
+Generate
+.Dq utrace
+entries for
+.Xr ktrace 1 ,
+for all operations.
+Consult the source for details on this option.
+.It V
+Attempting to allocate zero bytes will return a NULL pointer instead of
+a valid pointer.
+(The default behavior is to make a minimal allocation and return a
+pointer to it.)
+This option is provided for System V compatibility.
+This option is incompatible with the
+.Dq X
+option.
+.It X
+Rather than return failure for any allocation function,
+display a diagnostic message on stderr and cause the program to drop
+core (using
+.Xr abort 3 ).
+This option should be set at compile time by including the following in
+the source code:
+.Bd -literal -offset indent
+extern char *malloc_options;
+malloc_options = "X";
+.Ed
+.It Z
+This option implicitly sets the
+.Dq J
+and
+.Dq R
+options, and then zeros out the bytes that were requested.
+This is intended for debugging and will impact performance negatively.
+.It <
+Reduce the size of the cache by a factor of two.
+The default cache size is 16 pages.
+This option can be specified multiple times.
+.It >
+Double the size of the cache by a factor of two.
+The default cache size is 16 pages.
+This option can be specified multiple times.
+.El
+.Pp
+The
+.Dq J
+and
+.Dq Z
+options are intended for testing and debugging.
+An application which changes its behavior when these options are used
+is flawed.
+.Sh EXAMPLES
+To set a systemwide reduction of cache size, and to dump core whenever
+a problem occurs:
+.Pp
+.Bd -literal -offset indent
+ln -s 'A<' /etc/malloc.conf
+.Ed
+.Pp
+To specify in the source that a program does no return value checking
+on calls to these functions:
+.Bd -literal -offset indent
+extern char *malloc_options;
+malloc_options = "X";
+.Ed
+.Sh ENVIRONMENT
+The following environment variables affect the execution of the allocation
+functions:
+.Bl -tag -width MMM
+.It Ev MALLOC_OPTIONS
+If the environment variable
+.Ev MALLOC_OPTIONS
+is set, the characters it contains will be interpreted as flags to the
+allocation functions.
+.Sh RETURN VALUES
+The
+.Fn malloc
+and
+.Fn calloc
+functions return a pointer to the allocated memory if successful; otherwise
+a NULL pointer is returned.
+.Pp
+The
+.Fn realloc
+and
+.Fn reallocf
+functions return a pointer, possibly identical to
+.Fa ptr ,
+to the allocated memory
+if successful; otherwise a NULL pointer is returned, in which case the
+memory referenced by
+.Fa ptr
+is still available and intact.
+.Pp
+The
+.Fn free
+function returns no value.
+.Sh DEBUGGING MALLOC PROBLEMS
+.Pp
+The major difference between this implementation and other allocation
+implementations is that the free pages are not accessed unless allocated,
+and are aggressively returned to the kernel for reuse.
+.Bd -filled -offset indent
+Most allocation implementations will store a data structure containing a
+linked list in the free chunks of memory,
+used to tie all the free memory together.
+That can be suboptimal,
+as every time the free-list is traversed,
+the otherwise unused, and likely paged out,
+pages are faulted into primary memory.
+On systems which are paging,
+this can result in a factor of five increase in the number of page-faults
+done by a process.
+.Ed
+.Pp
+A side effect of this architecture is that many minor transgressions on
+the interface which would traditionally not be detected are in fact
+detected. As a result, programs that have been running happily for
+years may suddenly start to complain loudly, when linked with this
+allocation implementation.
+.Pp
+The first and most important thing to do is to set the
+.Dq A
+option.
+This option forces a coredump (if possible) at the first sign of trouble,
+rather than the normal policy of trying to continue if at all possible.
+.Pp
+It is probably also a good idea to recompile the program with suitable
+options and symbols for debugger support.
+.Pp
+If the program starts to give unusual results, coredump or generally behave
+differently without emitting any of the messages listed in the next
+section, it is likely because it depends on the storage being filled with
+zero bytes. Try running it with
+.Dq Z
+option set;
+if that improves the situation, this diagnosis has been confirmed.
+If the program still misbehaves,
+the likely problem is accessing memory outside the allocated area,
+more likely after than before the allocated area.
+.Pp
+Alternatively, if the symptoms are not easy to reproduce, setting the
+.Dq J
+option may help provoke the problem.
+.Pp
+In truly difficult cases, the
+.Dq U
+option, if supported by the kernel, can provide a detailed trace of
+all calls made to these functions.
+.Pp
+Unfortunately this implementation does not provide much detail about
+the problems it detects, the performance impact for storing such information
+would be prohibitive.
+There are a number of allocation implementations available on the 'Net
+which focus on detecting and pinpointing problems by trading performance
+for extra sanity checks and detailed diagnostics.
+.Sh DIAGNOSTIC MESSAGES
+If
+.Fn malloc ,
+.Fn calloc ,
+.Fn realloc
+or
+.Fn free
+detect an error or warning condition,
+a message will be printed to file descriptor STDERR_FILENO.
+Errors will result in the process dumping core.
+If the
+.Dq A
+option is set, all warnings are treated as errors.
+.Pp
+The following is a brief description of possible error messages and
+their meanings:
+.Pp
+.Bl -tag -width indent
+.It "(ES): mumble mumble mumble
+The allocation functions were compiled with
+.Dq EXTRA_SANITY
+defined, and an error was found during the additional error checking.
+Consult the source code for further information.
+.It "allocation failed
+If the
+.Dq A
+option is specified it is a fatal error for an allocation function to fail.
+.It "mmap(2) failed, check limits
+This most likely means that the system is dangerously overloaded or that
+the process' limits are incorrectly specified.
+.It "freelist is destroyed
+The internal free-list has been corrupted.
+.El
+.Pp
+.Bl -tag -width indent
+The following is a brief description of possible warning messages and
+their meanings:
+.Pp
+.It "chunk/page is already free
+The process attempted to
+.Fn free
+memory which had already been freed.
+.It "junk pointer ...
+A pointer specified to one of the allocation functions points outside the
+bounds of the memory of which they are aware.
+.It "malloc() has never been called
+No memory has been allocated,
+yet something is being freed or
+realloc'ed.
+.It "modified (chunk-/page-) pointer
+The pointer passed to
+.Fn free
+or
+.Fn realloc
+has been modified.
+.It "pointer to wrong page
+The pointer that
+.Fn malloc
+or
+.Fn calloc
+is trying to free does not reference a possible page.
+.It "recursive call
+A process has attempted to call an allocation function recursively.
+This is not permitted. In particular, signal handlers should not
+attempt to allocate memory.
+.It "out of memory
+The
+.Dq X
+option was specified and an allocation of memory failed.
+.It "unknown char in MALLOC_OPTIONS
+An unknown option was specified.
+Even with the
+.Dq A
+option set, this warning is still only a warning.
+.Sh SEE ALSO
+.Xr brk 2 ,
+.Xr alloca 3 ,
+.Xr getpagesize 3 ,
+.Xr memory 3
+.Pa /usr/share/doc/papers/malloc.ascii.gz
+.Sh STANDARDS
+The
+.Fn malloc ,
+.Fn calloc ,
+.Fn realloc
+and
+.Fn free
+functions conform to
+.St -ansiC .
+.Sh BUGS
+The messages printed in case of problems provide no detail about the
+actual values.
+.Pp
+It can be argued that returning a null pointer when asked to
+allocate zero bytes is a silly response to a silly question.
+.Pp
+This implementation was authored by Poul-Henning Kamp.
+Please report any problems to him at
+.Li <phk@FreeBSD.org> .
+.Sh HISTORY
+The present allocation implementation started out as a filesystem for a
+drum attached to a 20bit binary challenged computer which was built
+with discrete germanium transistors. It has since graduated to
+handle primary storage rather than secondary.
+It first appeared in its new shape and ability in
+.Fx 2.2 .
diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c
new file mode 100644
index 0000000..02d9364
--- /dev/null
+++ b/lib/libc/stdlib/malloc.c
@@ -0,0 +1,1138 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+/*
+ * Defining EXTRA_SANITY will enable extra checks which are related
+ * to internal conditions and consistency in malloc.c. This has a
+ * noticeable runtime performance hit, and generally will not do you
+ * any good unless you fiddle with the internals of malloc or want
+ * to catch random pointer corruption as early as possible.
+ */
+#ifndef MALLOC_EXTRA_SANITY
+#undef MALLOC_EXTRA_SANITY
+#endif
+
+/*
+ * What to use for Junk. This is the byte value we use to fill with
+ * when the 'J' option is enabled.
+ */
+#define SOME_JUNK 0xd0 /* as in "Duh" :-) */
+
+/*
+ * The basic parameters you can tweak.
+ *
+ * malloc_pageshift pagesize = 1 << malloc_pageshift
+ * It's probably best if this is the native
+ * page size, but it doesn't have to be.
+ *
+ * malloc_minsize minimum size of an allocation in bytes.
+ * If this is too small it's too much work
+ * to manage them. This is also the smallest
+ * unit of alignment used for the storage
+ * returned by malloc/realloc.
+ *
+ */
+
+#if defined(__FreeBSD__)
+# if defined(__i386__)
+# define malloc_pageshift 12U
+# define malloc_minsize 16U
+# endif
+# if defined(__alpha__)
+# define malloc_pageshift 13U
+# define malloc_minsize 16U
+# endif
+# if !defined(__NETBSD_SYSCALLS)
+# define HAS_UTRACE
+# endif
+ /*
+ * Make malloc/free/realloc thread-safe in libc for use with
+ * kernel threads.
+ */
+# include "libc_private.h"
+# include "spinlock.h"
+ static spinlock_t thread_lock = _SPINLOCK_INITIALIZER;
+# define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&thread_lock);
+# define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&thread_lock);
+#endif /* __FreeBSD__ */
+
+#if defined(__sparc__) && defined(sun)
+# define malloc_pageshift 12U
+# define malloc_minsize 16U
+# define MAP_ANON (0)
+ static int fdzero;
+# define MMAP_FD fdzero
+# define INIT_MMAP() \
+ { if ((fdzero=open("/dev/zero", O_RDWR, 0000)) == -1) \
+ wrterror("open of /dev/zero"); }
+# define MADV_FREE MADV_DONTNEED
+#endif /* __sparc__ */
+
+/* Insert your combination here... */
+#if defined(__FOOCPU__) && defined(__BAROS__)
+# define malloc_pageshift 12U
+# define malloc_minsize 16U
+#endif /* __FOOCPU__ && __BAROS__ */
+
+
+/*
+ * No user serviceable parts behind this point.
+ */
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * This structure describes a page worth of chunks.
+ */
+
+struct pginfo {
+ struct pginfo *next; /* next on the free list */
+ void *page; /* Pointer to the page */
+ u_short size; /* size of this page's chunks */
+ u_short shift; /* How far to shift for this size chunks */
+ u_short free; /* How many free chunks */
+ u_short total; /* How many chunk */
+ u_int bits[1]; /* Which chunks are free */
+};
+
+/*
+ * This structure describes a number of free pages.
+ */
+
+struct pgfree {
+ struct pgfree *next; /* next run of free pages */
+ struct pgfree *prev; /* prev run of free pages */
+ void *page; /* pointer to free pages */
+ void *end; /* pointer to end of free pages */
+ size_t size; /* number of bytes free */
+};
+
+/*
+ * How many bits per u_int in the bitmap.
+ * Change only if not 8 bits/byte
+ */
+#define MALLOC_BITS (8*sizeof(u_int))
+
+/*
+ * Magic values to put in the page_directory
+ */
+#define MALLOC_NOT_MINE ((struct pginfo*) 0)
+#define MALLOC_FREE ((struct pginfo*) 1)
+#define MALLOC_FIRST ((struct pginfo*) 2)
+#define MALLOC_FOLLOW ((struct pginfo*) 3)
+#define MALLOC_MAGIC ((struct pginfo*) 4)
+
+#ifndef malloc_pageshift
+#define malloc_pageshift 12U
+#endif
+
+#ifndef malloc_minsize
+#define malloc_minsize 16U
+#endif
+
+#if !defined(malloc_pagesize)
+#define malloc_pagesize (1UL<<malloc_pageshift)
+#endif
+
+#if ((1<<malloc_pageshift) != malloc_pagesize)
+#error "(1<<malloc_pageshift) != malloc_pagesize"
+#endif
+
+#ifndef malloc_maxsize
+#define malloc_maxsize ((malloc_pagesize)>>1)
+#endif
+
+/* A mask for the offset inside a page. */
+#define malloc_pagemask ((malloc_pagesize)-1)
+
+#define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask)))
+#define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo)
+
+#ifndef THREAD_LOCK
+#define THREAD_LOCK()
+#endif
+
+#ifndef THREAD_UNLOCK
+#define THREAD_UNLOCK()
+#endif
+
+#ifndef MMAP_FD
+#define MMAP_FD (-1)
+#endif
+
+#ifndef INIT_MMAP
+#define INIT_MMAP()
+#endif
+
+/* Set when initialization has been done */
+static unsigned malloc_started;
+
+/* Recusion flag for public interface. */
+static int malloc_active;
+
+/* Number of free pages we cache */
+static unsigned malloc_cache = 16;
+
+/* The offset from pagenumber to index into the page directory */
+static u_long malloc_origo;
+
+/* The last index in the page directory we care about */
+static u_long last_index;
+
+/* Pointer to page directory. Allocated "as if with" malloc */
+static struct pginfo **page_dir;
+
+/* How many slots in the page directory */
+static unsigned malloc_ninfo;
+
+/* Free pages line up here */
+static struct pgfree free_list;
+
+/* Abort(), user doesn't handle problems. */
+static int malloc_abort;
+
+/* Are we trying to die ? */
+static int suicide;
+
+/* always realloc ? */
+static int malloc_realloc;
+
+/* pass the kernel a hint on free pages ? */
+static int malloc_hint = 0;
+
+/* xmalloc behaviour ? */
+static int malloc_xmalloc;
+
+/* sysv behaviour for malloc(0) ? */
+static int malloc_sysv;
+
+/* zero fill ? */
+static int malloc_zero;
+
+/* junk fill ? */
+static int malloc_junk;
+
+#ifdef HAS_UTRACE
+
+/* utrace ? */
+static int malloc_utrace;
+
+struct ut { void *p; size_t s; void *r; };
+
+void utrace __P((struct ut *, int));
+
+#define UTRACE(a, b, c) \
+ if (malloc_utrace) \
+ {struct ut u; u.p=a; u.s = b; u.r=c; utrace(&u, sizeof u);}
+#else /* !HAS_UTRACE */
+#define UTRACE(a,b,c)
+#endif /* HAS_UTRACE */
+
+/* my last break. */
+static void *malloc_brk;
+
+/* one location cache for free-list holders */
+static struct pgfree *px;
+
+/* compile-time options */
+char *malloc_options;
+
+/* Name of the current public function */
+static char *malloc_func;
+
+/* Macro for mmap */
+#define MMAP(size) \
+ mmap(0, (size), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, \
+ MMAP_FD, 0);
+
+/*
+ * Necessary function declarations
+ */
+static int extend_pgdir(u_long index);
+static void *imalloc(size_t size);
+static void ifree(void *ptr);
+static void *irealloc(void *ptr, size_t size);
+
+extern char *__progname;
+
+static void
+wrterror(char *p)
+{
+ char *q = " error: ";
+ write(STDERR_FILENO, __progname, strlen(__progname));
+ write(STDERR_FILENO, malloc_func, strlen(malloc_func));
+ write(STDERR_FILENO, q, strlen(q));
+ write(STDERR_FILENO, p, strlen(p));
+ suicide = 1;
+ abort();
+}
+
+static void
+wrtwarning(char *p)
+{
+ char *q = " warning: ";
+ if (malloc_abort)
+ wrterror(p);
+ write(STDERR_FILENO, __progname, strlen(__progname));
+ write(STDERR_FILENO, malloc_func, strlen(malloc_func));
+ write(STDERR_FILENO, q, strlen(q));
+ write(STDERR_FILENO, p, strlen(p));
+}
+
+
+/*
+ * Allocate a number of pages from the OS
+ */
+static void *
+map_pages(int pages)
+{
+ caddr_t result, tail;
+
+ result = (caddr_t)pageround((u_long)sbrk(0));
+ tail = result + (pages << malloc_pageshift);
+
+ if (brk(tail)) {
+#ifdef EXTRA_SANITY
+ wrterror("(ES): map_pages fails\n");
+#endif /* EXTRA_SANITY */
+ return 0;
+ }
+
+ last_index = ptr2index(tail) - 1;
+ malloc_brk = tail;
+
+ if ((last_index+1) >= malloc_ninfo && !extend_pgdir(last_index))
+ return 0;;
+
+ return result;
+}
+
+/*
+ * Extend page directory
+ */
+static int
+extend_pgdir(u_long index)
+{
+ struct pginfo **new, **old;
+ int i, oldlen;
+
+ /* Make it this many pages */
+ i = index * sizeof *page_dir;
+ i /= malloc_pagesize;
+ i += 2;
+
+ /* remember the old mapping size */
+ oldlen = malloc_ninfo * sizeof *page_dir;
+
+ /*
+ * NOTE: we allocate new pages and copy the directory rather than tempt
+ * fate by trying to "grow" the region.. There is nothing to prevent
+ * us from accidently re-mapping space that's been allocated by our caller
+ * via dlopen() or other mmap().
+ *
+ * The copy problem is not too bad, as there is 4K of page index per
+ * 4MB of malloc arena.
+ *
+ * We can totally avoid the copy if we open a file descriptor to associate
+ * the anon mappings with. Then, when we remap the pages at the new
+ * address, the old pages will be "magically" remapped.. But this means
+ * keeping open a "secret" file descriptor.....
+ */
+
+ /* Get new pages */
+ new = (struct pginfo**) MMAP(i * malloc_pagesize);
+ if (new == (struct pginfo **)-1)
+ return 0;
+
+ /* Copy the old stuff */
+ memcpy(new, page_dir,
+ malloc_ninfo * sizeof *page_dir);
+
+ /* register the new size */
+ malloc_ninfo = i * malloc_pagesize / sizeof *page_dir;
+
+ /* swap the pointers */
+ old = page_dir;
+ page_dir = new;
+
+ /* Now free the old stuff */
+ munmap(old, oldlen);
+ return 1;
+}
+
+/*
+ * Initialize the world
+ */
+static void
+malloc_init ()
+{
+ char *p, b[64];
+ int i, j;
+ int errnosave;
+
+ INIT_MMAP();
+
+#ifdef EXTRA_SANITY
+ malloc_junk = 1;
+#endif /* EXTRA_SANITY */
+
+ for (i = 0; i < 3; i++) {
+ if (i == 0) {
+ errnosave = errno;
+ j = readlink("/etc/malloc.conf", b, sizeof b - 1);
+ errno = errnosave;
+ if (j <= 0)
+ continue;
+ b[j] = '\0';
+ p = b;
+ } else if (i == 1) {
+ p = getenv("MALLOC_OPTIONS");
+ } else {
+ p = malloc_options;
+ }
+ for (; p && *p; p++) {
+ switch (*p) {
+ case '>': malloc_cache <<= 1; break;
+ case '<': malloc_cache >>= 1; break;
+ case 'a': malloc_abort = 0; break;
+ case 'A': malloc_abort = 1; break;
+ case 'h': malloc_hint = 0; break;
+ case 'H': malloc_hint = 1; break;
+ case 'r': malloc_realloc = 0; break;
+ case 'R': malloc_realloc = 1; break;
+ case 'j': malloc_junk = 0; break;
+ case 'J': malloc_junk = 1; break;
+#ifdef HAS_UTRACE
+ case 'u': malloc_utrace = 0; break;
+ case 'U': malloc_utrace = 1; break;
+#endif
+ case 'v': malloc_sysv = 0; break;
+ case 'V': malloc_sysv = 1; break;
+ case 'x': malloc_xmalloc = 0; break;
+ case 'X': malloc_xmalloc = 1; break;
+ case 'z': malloc_zero = 0; break;
+ case 'Z': malloc_zero = 1; break;
+ default:
+ j = malloc_abort;
+ malloc_abort = 0;
+ wrtwarning("unknown char in MALLOC_OPTIONS\n");
+ malloc_abort = j;
+ break;
+ }
+ }
+ }
+
+ UTRACE(0, 0, 0);
+
+ /*
+ * We want junk in the entire allocation, and zero only in the part
+ * the user asked for.
+ */
+ if (malloc_zero)
+ malloc_junk=1;
+
+ /*
+ * If we run with junk (or implicitly from above: zero), we want to
+ * force realloc() to get new storage, so we can DTRT with it.
+ */
+ if (malloc_junk)
+ malloc_realloc=1;
+
+ /* Allocate one page for the page directory */
+ page_dir = (struct pginfo **) MMAP(malloc_pagesize);
+
+ if (page_dir == (struct pginfo **) -1)
+ wrterror("mmap(2) failed, check limits.\n");
+
+ /*
+ * We need a maximum of malloc_pageshift buckets, steal these from the
+ * front of the page_directory;
+ */
+ malloc_origo = ((u_long)pageround((u_long)sbrk(0))) >> malloc_pageshift;
+ malloc_origo -= malloc_pageshift;
+
+ malloc_ninfo = malloc_pagesize / sizeof *page_dir;
+
+ /* Recalculate the cache size in bytes, and make sure it's nonzero */
+
+ if (!malloc_cache)
+ malloc_cache++;
+
+ malloc_cache <<= malloc_pageshift;
+
+ /*
+ * This is a nice hack from Kaleb Keithly (kaleb@x.org).
+ * We can sbrk(2) further back when we keep this on a low address.
+ */
+ px = (struct pgfree *) imalloc (sizeof *px);
+
+ /* Been here, done that */
+ malloc_started++;
+}
+
+/*
+ * Allocate a number of complete pages
+ */
+static void *
+malloc_pages(size_t size)
+{
+ void *p, *delay_free = 0;
+ int i;
+ struct pgfree *pf;
+ u_long index;
+
+ size = pageround(size);
+
+ p = 0;
+
+ /* Look for free pages before asking for more */
+ for(pf = free_list.next; pf; pf = pf->next) {
+
+#ifdef EXTRA_SANITY
+ if (pf->size & malloc_pagemask)
+ wrterror("(ES): junk length entry on free_list\n");
+ if (!pf->size)
+ wrterror("(ES): zero length entry on free_list\n");
+ if (pf->page == pf->end)
+ wrterror("(ES): zero entry on free_list\n");
+ if (pf->page > pf->end)
+ wrterror("(ES): sick entry on free_list\n");
+ if ((void*)pf->page >= (void*)sbrk(0))
+ wrterror("(ES): entry on free_list past brk\n");
+ if (page_dir[ptr2index(pf->page)] != MALLOC_FREE)
+ wrterror("(ES): non-free first page on free-list\n");
+ if (page_dir[ptr2index(pf->end)-1] != MALLOC_FREE)
+ wrterror("(ES): non-free last page on free-list\n");
+#endif /* EXTRA_SANITY */
+
+ if (pf->size < size)
+ continue;
+
+ if (pf->size == size) {
+ p = pf->page;
+ if (pf->next)
+ pf->next->prev = pf->prev;
+ pf->prev->next = pf->next;
+ delay_free = pf;
+ break;
+ }
+
+ p = pf->page;
+ pf->page = (char *)pf->page + size;
+ pf->size -= size;
+ break;
+ }
+
+#ifdef EXTRA_SANITY
+ if (p && page_dir[ptr2index(p)] != MALLOC_FREE)
+ wrterror("(ES): allocated non-free page on free-list\n");
+#endif /* EXTRA_SANITY */
+
+ size >>= malloc_pageshift;
+
+ /* Map new pages */
+ if (!p)
+ p = map_pages(size);
+
+ if (p) {
+
+ index = ptr2index(p);
+ page_dir[index] = MALLOC_FIRST;
+ for (i=1;i<size;i++)
+ page_dir[index+i] = MALLOC_FOLLOW;
+
+ if (malloc_junk)
+ memset(p, SOME_JUNK, size << malloc_pageshift);
+ }
+
+ if (delay_free) {
+ if (!px)
+ px = delay_free;
+ else
+ ifree(delay_free);
+ }
+
+ return p;
+}
+
+/*
+ * Allocate a page of fragments
+ */
+
+static __inline__ int
+malloc_make_chunks(int bits)
+{
+ struct pginfo *bp;
+ void *pp;
+ int i, k, l;
+
+ /* Allocate a new bucket */
+ pp = malloc_pages(malloc_pagesize);
+ if (!pp)
+ return 0;
+
+ /* Find length of admin structure */
+ l = offsetof(struct pginfo, bits[0]);
+ l += sizeof bp->bits[0] *
+ (((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS);
+
+ /* Don't waste more than two chunks on this */
+ if ((1<<(bits)) <= l+l) {
+ bp = (struct pginfo *)pp;
+ } else {
+ bp = (struct pginfo *)imalloc(l);
+ if (!bp) {
+ ifree(pp);
+ return 0;
+ }
+ }
+
+ bp->size = (1<<bits);
+ bp->shift = bits;
+ bp->total = bp->free = malloc_pagesize >> bits;
+ bp->page = pp;
+
+ /* set all valid bits in the bitmap */
+ k = bp->total;
+ i = 0;
+
+ /* Do a bunch at a time */
+ for(;k-i >= MALLOC_BITS; i += MALLOC_BITS)
+ bp->bits[i / MALLOC_BITS] = ~0;
+
+ for(; i < k; i++)
+ bp->bits[i/MALLOC_BITS] |= 1<<(i%MALLOC_BITS);
+
+ if (bp == bp->page) {
+ /* Mark the ones we stole for ourselves */
+ for(i=0;l > 0;i++) {
+ bp->bits[i/MALLOC_BITS] &= ~(1<<(i%MALLOC_BITS));
+ bp->free--;
+ bp->total--;
+ l -= (1 << bits);
+ }
+ }
+
+ /* MALLOC_LOCK */
+
+ page_dir[ptr2index(pp)] = bp;
+
+ bp->next = page_dir[bits];
+ page_dir[bits] = bp;
+
+ /* MALLOC_UNLOCK */
+
+ return 1;
+}
+
+/*
+ * Allocate a fragment
+ */
+static void *
+malloc_bytes(size_t size)
+{
+ int i,j;
+ u_int u;
+ struct pginfo *bp;
+ int k;
+ u_int *lp;
+
+ /* Don't bother with anything less than this */
+ if (size < malloc_minsize)
+ size = malloc_minsize;
+
+ /* Find the right bucket */
+ j = 1;
+ i = size-1;
+ while (i >>= 1)
+ j++;
+
+ /* If it's empty, make a page more of that size chunks */
+ if (!page_dir[j] && !malloc_make_chunks(j))
+ return 0;
+
+ bp = page_dir[j];
+
+ /* Find first word of bitmap which isn't empty */
+ for (lp = bp->bits; !*lp; lp++)
+ ;
+
+ /* Find that bit, and tweak it */
+ u = 1;
+ k = 0;
+ while (!(*lp & u)) {
+ u += u;
+ k++;
+ }
+ *lp ^= u;
+
+ /* If there are no more free, remove from free-list */
+ if (!--bp->free) {
+ page_dir[j] = bp->next;
+ bp->next = 0;
+ }
+
+ /* Adjust to the real offset of that chunk */
+ k += (lp-bp->bits)*MALLOC_BITS;
+ k <<= bp->shift;
+
+ if (malloc_junk)
+ memset((u_char*)bp->page + k, SOME_JUNK, bp->size);
+
+ return (u_char *)bp->page + k;
+}
+
+/*
+ * Allocate a piece of memory
+ */
+static void *
+imalloc(size_t size)
+{
+ void *result;
+
+ if (suicide)
+ abort();
+
+ if ((size + malloc_pagesize) < size) /* Check for overflow */
+ result = 0;
+ else if (size <= malloc_maxsize)
+ result = malloc_bytes(size);
+ else
+ result = malloc_pages(size);
+
+ if (malloc_abort && !result)
+ wrterror("allocation failed.\n");
+
+ if (malloc_zero && result)
+ memset(result, 0, size);
+
+ return result;
+}
+
+/*
+ * Change the size of an allocation.
+ */
+static void *
+irealloc(void *ptr, size_t size)
+{
+ void *p;
+ u_long osize, index;
+ struct pginfo **mp;
+ int i;
+
+ if (suicide)
+ abort();
+
+ index = ptr2index(ptr);
+
+ if (index < malloc_pageshift) {
+ wrtwarning("junk pointer, too low to make sense.\n");
+ return 0;
+ }
+
+ if (index > last_index) {
+ wrtwarning("junk pointer, too high to make sense.\n");
+ return 0;
+ }
+
+ mp = &page_dir[index];
+
+ if (*mp == MALLOC_FIRST) { /* Page allocation */
+
+ /* Check the pointer */
+ if ((u_long)ptr & malloc_pagemask) {
+ wrtwarning("modified (page-) pointer.\n");
+ return 0;
+ }
+
+ /* Find the size in bytes */
+ for (osize = malloc_pagesize; *++mp == MALLOC_FOLLOW;)
+ osize += malloc_pagesize;
+
+ if (!malloc_realloc && /* unless we have to, */
+ size <= osize && /* .. or are too small, */
+ size > (osize - malloc_pagesize)) { /* .. or can free a page, */
+ return ptr; /* don't do anything. */
+ }
+
+ } else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */
+
+ /* Check the pointer for sane values */
+ if (((u_long)ptr & ((*mp)->size-1))) {
+ wrtwarning("modified (chunk-) pointer.\n");
+ return 0;
+ }
+
+ /* Find the chunk index in the page */
+ i = ((u_long)ptr & malloc_pagemask) >> (*mp)->shift;
+
+ /* Verify that it isn't a free chunk already */
+ if ((*mp)->bits[i/MALLOC_BITS] & (1<<(i%MALLOC_BITS))) {
+ wrtwarning("chunk is already free.\n");
+ return 0;
+ }
+
+ osize = (*mp)->size;
+
+ if (!malloc_realloc && /* Unless we have to, */
+ size < osize && /* ..or are too small, */
+ (size > osize/2 || /* ..or could use a smaller size, */
+ osize == malloc_minsize)) { /* ..(if there is one) */
+ return ptr; /* ..Don't do anything */
+ }
+
+ } else {
+ wrtwarning("pointer to wrong page.\n");
+ return 0;
+ }
+
+ p = imalloc(size);
+
+ if (p) {
+ /* copy the lesser of the two sizes, and free the old one */
+ if (!size || !osize)
+ ;
+ else if (osize < size)
+ memcpy(p, ptr, osize);
+ else
+ memcpy(p, ptr, size);
+ ifree(ptr);
+ }
+ return p;
+}
+
+/*
+ * Free a sequence of pages
+ */
+
+static __inline__ void
+free_pages(void *ptr, int index, struct pginfo *info)
+{
+ int i;
+ struct pgfree *pf, *pt=0;
+ u_long l;
+ void *tail;
+
+ if (info == MALLOC_FREE) {
+ wrtwarning("page is already free.\n");
+ return;
+ }
+
+ if (info != MALLOC_FIRST) {
+ wrtwarning("pointer to wrong page.\n");
+ return;
+ }
+
+ if ((u_long)ptr & malloc_pagemask) {
+ wrtwarning("modified (page-) pointer.\n");
+ return;
+ }
+
+ /* Count how many pages and mark them free at the same time */
+ page_dir[index] = MALLOC_FREE;
+ for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++)
+ page_dir[index + i] = MALLOC_FREE;
+
+ l = i << malloc_pageshift;
+
+ if (malloc_junk)
+ memset(ptr, SOME_JUNK, l);
+
+ if (malloc_hint)
+ madvise(ptr, l, MADV_FREE);
+
+ tail = (char *)ptr+l;
+
+ /* add to free-list */
+ if (!px)
+ px = imalloc(sizeof *pt); /* This cannot fail... */
+ px->page = ptr;
+ px->end = tail;
+ px->size = l;
+ if (!free_list.next) {
+
+ /* Nothing on free list, put this at head */
+ px->next = free_list.next;
+ px->prev = &free_list;
+ free_list.next = px;
+ pf = px;
+ px = 0;
+
+ } else {
+
+ /* Find the right spot, leave pf pointing to the modified entry. */
+ tail = (char *)ptr+l;
+
+ for(pf = free_list.next; pf->end < ptr && pf->next; pf = pf->next)
+ ; /* Race ahead here */
+
+ if (pf->page > tail) {
+ /* Insert before entry */
+ px->next = pf;
+ px->prev = pf->prev;
+ pf->prev = px;
+ px->prev->next = px;
+ pf = px;
+ px = 0;
+ } else if (pf->end == ptr ) {
+ /* Append to the previous entry */
+ pf->end = (char *)pf->end + l;
+ pf->size += l;
+ if (pf->next && pf->end == pf->next->page ) {
+ /* And collapse the next too. */
+ pt = pf->next;
+ pf->end = pt->end;
+ pf->size += pt->size;
+ pf->next = pt->next;
+ if (pf->next)
+ pf->next->prev = pf;
+ }
+ } else if (pf->page == tail) {
+ /* Prepend to entry */
+ pf->size += l;
+ pf->page = ptr;
+ } else if (!pf->next) {
+ /* Append at tail of chain */
+ px->next = 0;
+ px->prev = pf;
+ pf->next = px;
+ pf = px;
+ px = 0;
+ } else {
+ wrterror("freelist is destroyed.\n");
+ }
+ }
+
+ /* Return something to OS ? */
+ if (!pf->next && /* If we're the last one, */
+ pf->size > malloc_cache && /* ..and the cache is full, */
+ pf->end == malloc_brk && /* ..and none behind us, */
+ malloc_brk == sbrk(0)) { /* ..and it's OK to do... */
+
+ /*
+ * Keep the cache intact. Notice that the '>' above guarantees that
+ * the pf will always have at least one page afterwards.
+ */
+ pf->end = (char *)pf->page + malloc_cache;
+ pf->size = malloc_cache;
+
+ brk(pf->end);
+ malloc_brk = pf->end;
+
+ index = ptr2index(pf->end);
+ last_index = index - 1;
+
+ for(i=index;i <= last_index;)
+ page_dir[i++] = MALLOC_NOT_MINE;
+
+ /* XXX: We could realloc/shrink the pagedir here I guess. */
+ }
+ if (pt)
+ ifree(pt);
+}
+
+/*
+ * Free a chunk, and possibly the page it's on, if the page becomes empty.
+ */
+
+static __inline__ void
+free_bytes(void *ptr, int index, struct pginfo *info)
+{
+ int i;
+ struct pginfo **mp;
+ void *vp;
+
+ /* Find the chunk number on the page */
+ i = ((u_long)ptr & malloc_pagemask) >> info->shift;
+
+ if (((u_long)ptr & (info->size-1))) {
+ wrtwarning("modified (chunk-) pointer.\n");
+ return;
+ }
+
+ if (info->bits[i/MALLOC_BITS] & (1<<(i%MALLOC_BITS))) {
+ wrtwarning("chunk is already free.\n");
+ return;
+ }
+
+ if (malloc_junk)
+ memset(ptr, SOME_JUNK, info->size);
+
+ info->bits[i/MALLOC_BITS] |= 1<<(i%MALLOC_BITS);
+ info->free++;
+
+ mp = page_dir + info->shift;
+
+ if (info->free == 1) {
+
+ /* Page became non-full */
+
+ mp = page_dir + info->shift;
+ /* Insert in address order */
+ while (*mp && (*mp)->next && (*mp)->next->page < info->page)
+ mp = &(*mp)->next;
+ info->next = *mp;
+ *mp = info;
+ return;
+ }
+
+ if (info->free != info->total)
+ return;
+
+ /* Find & remove this page in the queue */
+ while (*mp != info) {
+ mp = &((*mp)->next);
+#ifdef EXTRA_SANITY
+ if (!*mp)
+ wrterror("(ES): Not on queue\n");
+#endif /* EXTRA_SANITY */
+ }
+ *mp = info->next;
+
+ /* Free the page & the info structure if need be */
+ page_dir[ptr2index(info->page)] = MALLOC_FIRST;
+ vp = info->page; /* Order is important ! */
+ if(vp != (void*)info)
+ ifree(info);
+ ifree(vp);
+}
+
+static void
+ifree(void *ptr)
+{
+ struct pginfo *info;
+ int index;
+
+ /* This is legal */
+ if (!ptr)
+ return;
+
+ if (!malloc_started) {
+ wrtwarning("malloc() has never been called.\n");
+ return;
+ }
+
+ /* If we're already sinking, don't make matters any worse. */
+ if (suicide)
+ return;
+
+ index = ptr2index(ptr);
+
+ if (index < malloc_pageshift) {
+ wrtwarning("junk pointer, too low to make sense.\n");
+ return;
+ }
+
+ if (index > last_index) {
+ wrtwarning("junk pointer, too high to make sense.\n");
+ return;
+ }
+
+ info = page_dir[index];
+
+ if (info < MALLOC_MAGIC)
+ free_pages(ptr, index, info);
+ else
+ free_bytes(ptr, index, info);
+ return;
+}
+
+/*
+ * These are the public exported interface routines.
+ */
+
+
+void *
+malloc(size_t size)
+{
+ register void *r;
+
+ THREAD_LOCK();
+ malloc_func = " in malloc():";
+ if (malloc_active++) {
+ wrtwarning("recursive call.\n");
+ malloc_active--;
+ return (0);
+ }
+ if (!malloc_started)
+ malloc_init();
+ if (malloc_sysv && !size)
+ r = 0;
+ else
+ r = imalloc(size);
+ UTRACE(0, size, r);
+ malloc_active--;
+ THREAD_UNLOCK();
+ if (malloc_xmalloc && !r)
+ wrterror("out of memory.\n");
+ return (r);
+}
+
+void
+free(void *ptr)
+{
+ THREAD_LOCK();
+ malloc_func = " in free():";
+ if (malloc_active++) {
+ wrtwarning("recursive call.\n");
+ malloc_active--;
+ return;
+ } else {
+ ifree(ptr);
+ UTRACE(ptr, 0, 0);
+ }
+ malloc_active--;
+ THREAD_UNLOCK();
+ return;
+}
+
+void *
+realloc(void *ptr, size_t size)
+{
+ register void *r;
+
+ THREAD_LOCK();
+ malloc_func = " in realloc():";
+ if (malloc_active++) {
+ wrtwarning("recursive call.\n");
+ malloc_active--;
+ return (0);
+ }
+ if (ptr && !malloc_started) {
+ wrtwarning("malloc() has never been called.\n");
+ ptr = 0;
+ }
+ if (!malloc_started)
+ malloc_init();
+ if (malloc_sysv && !size) {
+ ifree(ptr);
+ r = 0;
+ } else if (!ptr) {
+ r = imalloc(size);
+ } else {
+ r = irealloc(ptr, size);
+ }
+ UTRACE(ptr, size, r);
+ malloc_active--;
+ THREAD_UNLOCK();
+ if (malloc_xmalloc && !r)
+ wrterror("out of memory.\n");
+ return (r);
+}
+
diff --git a/lib/libc/stdlib/memory.3 b/lib/libc/stdlib/memory.3
new file mode 100644
index 0000000..4480338
--- /dev/null
+++ b/lib/libc/stdlib/memory.3
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)memory.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt MEMORY 3
+.Os BSD 4
+.Sh NAME
+.Nm malloc ,
+.Nm free ,
+.Nm realloc ,
+.Nm calloc ,
+.Nm alloca
+.Nd general memory allocation operations
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft void *
+.Fn malloc "size_t size"
+.Ft void
+.Fn free "void *ptr"
+.Ft void *
+.Fn realloc "void *ptr" "size_t size"
+.Ft void *
+.Fn calloc "size_t nelem" "size_t elsize"
+.Ft void *
+.Fn alloca "size_t size"
+.Sh DESCRIPTION
+These functions allocate and free memory for the calling process.
+They are described in the
+individual manual pages.
+.Sh SEE ALSO
+.Xr alloca 3 ,
+.Xr calloc 3 ,
+.Xr free 3 ,
+.Xr malloc 3 ,
+.Xr realloc 3
+.Sh STANDARDS
+These functions, with the exception of
+.Fn alloca
+conform to
+.St -ansiC .
diff --git a/lib/libc/stdlib/merge.c b/lib/libc/stdlib/merge.c
new file mode 100644
index 0000000..083a964
--- /dev/null
+++ b/lib/libc/stdlib/merge.c
@@ -0,0 +1,350 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Peter McIlroy.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)merge.c 8.2 (Berkeley) 2/14/94";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Hybrid exponential search/linear search merge sort with hybrid
+ * natural/pairwise first pass. Requires about .3% more comparisons
+ * for random data than LSMS with pairwise first pass alone.
+ * It works for objects as small as two bytes.
+ */
+
+#define NATURAL
+#define THRESHOLD 16 /* Best choice for natural merge cut-off. */
+
+/* #define NATURAL to get hybrid natural merge.
+ * (The default is pairwise merging.)
+ */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void setup __P((u_char *, u_char *, size_t, size_t, int (*)()));
+static void insertionsort __P((u_char *, size_t, size_t, int (*)()));
+
+#define ISIZE sizeof(int)
+#define PSIZE sizeof(u_char *)
+#define ICOPY_LIST(src, dst, last) \
+ do \
+ *(int*)dst = *(int*)src, src += ISIZE, dst += ISIZE; \
+ while(src < last)
+#define ICOPY_ELT(src, dst, i) \
+ do \
+ *(int*) dst = *(int*) src, src += ISIZE, dst += ISIZE; \
+ while (i -= ISIZE)
+
+#define CCOPY_LIST(src, dst, last) \
+ do \
+ *dst++ = *src++; \
+ while (src < last)
+#define CCOPY_ELT(src, dst, i) \
+ do \
+ *dst++ = *src++; \
+ while (i -= 1)
+
+/*
+ * Find the next possible pointer head. (Trickery for forcing an array
+ * to do double duty as a linked list when objects do not align with word
+ * boundaries.
+ */
+/* Assumption: PSIZE is a power of 2. */
+#define EVAL(p) (u_char **) \
+ ((u_char *)0 + \
+ (((u_char *)p + PSIZE - 1 - (u_char *) 0) & ~(PSIZE - 1)))
+
+/*
+ * Arguments are as for qsort.
+ */
+int
+mergesort(base, nmemb, size, cmp)
+ void *base;
+ size_t nmemb;
+ register size_t size;
+ int (*cmp) __P((const void *, const void *));
+{
+ register int i, sense;
+ int big, iflag;
+ register u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2;
+ u_char *list2, *list1, *p2, *p, *last, **p1;
+
+ if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (nmemb == 0)
+ return (0);
+
+ /*
+ * XXX
+ * Stupid subtraction for the Cray.
+ */
+ iflag = 0;
+ if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE))
+ iflag = 1;
+
+ if ((list2 = malloc(nmemb * size + PSIZE)) == NULL)
+ return (-1);
+
+ list1 = base;
+ setup(list1, list2, nmemb, size, cmp);
+ last = list2 + nmemb * size;
+ i = big = 0;
+ while (*EVAL(list2) != last) {
+ l2 = list1;
+ p1 = EVAL(list1);
+ for (tp2 = p2 = list2; p2 != last; p1 = EVAL(l2)) {
+ p2 = *EVAL(p2);
+ f1 = l2;
+ f2 = l1 = list1 + (p2 - list2);
+ if (p2 != last)
+ p2 = *EVAL(p2);
+ l2 = list1 + (p2 - list2);
+ while (f1 < l1 && f2 < l2) {
+ if ((*cmp)(f1, f2) <= 0) {
+ q = f2;
+ b = f1, t = l1;
+ sense = -1;
+ } else {
+ q = f1;
+ b = f2, t = l2;
+ sense = 0;
+ }
+ if (!big) { /* here i = 0 */
+ while ((b += size) < t && cmp(q, b) >sense)
+ if (++i == 6) {
+ big = 1;
+ goto EXPONENTIAL;
+ }
+ } else {
+EXPONENTIAL: for (i = size; ; i <<= 1)
+ if ((p = (b + i)) >= t) {
+ if ((p = t - size) > b &&
+ (*cmp)(q, p) <= sense)
+ t = p;
+ else
+ b = p;
+ break;
+ } else if ((*cmp)(q, p) <= sense) {
+ t = p;
+ if (i == size)
+ big = 0;
+ goto FASTCASE;
+ } else
+ b = p;
+ while (t > b+size) {
+ i = (((t - b) / size) >> 1) * size;
+ if ((*cmp)(q, p = b + i) <= sense)
+ t = p;
+ else
+ b = p;
+ }
+ goto COPY;
+FASTCASE: while (i > size)
+ if ((*cmp)(q,
+ p = b + (i >>= 1)) <= sense)
+ t = p;
+ else
+ b = p;
+COPY: b = t;
+ }
+ i = size;
+ if (q == f1) {
+ if (iflag) {
+ ICOPY_LIST(f2, tp2, b);
+ ICOPY_ELT(f1, tp2, i);
+ } else {
+ CCOPY_LIST(f2, tp2, b);
+ CCOPY_ELT(f1, tp2, i);
+ }
+ } else {
+ if (iflag) {
+ ICOPY_LIST(f1, tp2, b);
+ ICOPY_ELT(f2, tp2, i);
+ } else {
+ CCOPY_LIST(f1, tp2, b);
+ CCOPY_ELT(f2, tp2, i);
+ }
+ }
+ }
+ if (f2 < l2) {
+ if (iflag)
+ ICOPY_LIST(f2, tp2, l2);
+ else
+ CCOPY_LIST(f2, tp2, l2);
+ } else if (f1 < l1) {
+ if (iflag)
+ ICOPY_LIST(f1, tp2, l1);
+ else
+ CCOPY_LIST(f1, tp2, l1);
+ }
+ *p1 = l2;
+ }
+ tp2 = list1; /* swap list1, list2 */
+ list1 = list2;
+ list2 = tp2;
+ last = list2 + nmemb*size;
+ }
+ if (base == list2) {
+ memmove(list2, list1, nmemb*size);
+ list2 = list1;
+ }
+ free(list2);
+ return (0);
+}
+
+#define swap(a, b) { \
+ s = b; \
+ i = size; \
+ do { \
+ tmp = *a; *a++ = *s; *s++ = tmp; \
+ } while (--i); \
+ a -= size; \
+ }
+#define reverse(bot, top) { \
+ s = top; \
+ do { \
+ i = size; \
+ do { \
+ tmp = *bot; *bot++ = *s; *s++ = tmp; \
+ } while (--i); \
+ s -= size2; \
+ } while(bot < s); \
+}
+
+/*
+ * Optional hybrid natural/pairwise first pass. Eats up list1 in runs of
+ * increasing order, list2 in a corresponding linked list. Checks for runs
+ * when THRESHOLD/2 pairs compare with same sense. (Only used when NATURAL
+ * is defined. Otherwise simple pairwise merging is used.)
+ */
+void
+setup(list1, list2, n, size, cmp)
+ size_t n, size;
+ int (*cmp) __P((const void *, const void *));
+ u_char *list1, *list2;
+{
+ int i, length, size2, tmp, sense;
+ u_char *f1, *f2, *s, *l2, *last, *p2;
+
+ size2 = size*2;
+ if (n <= 5) {
+ insertionsort(list1, n, size, cmp);
+ *EVAL(list2) = (u_char*) list2 + n*size;
+ return;
+ }
+ /*
+ * Avoid running pointers out of bounds; limit n to evens
+ * for simplicity.
+ */
+ i = 4 + (n & 1);
+ insertionsort(list1 + (n - i) * size, i, size, cmp);
+ last = list1 + size * (n - i);
+ *EVAL(list2 + (last - list1)) = list2 + n * size;
+
+#ifdef NATURAL
+ p2 = list2;
+ f1 = list1;
+ sense = (cmp(f1, f1 + size) > 0);
+ for (; f1 < last; sense = !sense) {
+ length = 2;
+ /* Find pairs with same sense. */
+ for (f2 = f1 + size2; f2 < last; f2 += size2) {
+ if ((cmp(f2, f2+ size) > 0) != sense)
+ break;
+ length += 2;
+ }
+ if (length < THRESHOLD) { /* Pairwise merge */
+ do {
+ p2 = *EVAL(p2) = f1 + size2 - list1 + list2;
+ if (sense > 0)
+ swap (f1, f1 + size);
+ } while ((f1 += size2) < f2);
+ } else { /* Natural merge */
+ l2 = f2;
+ for (f2 = f1 + size2; f2 < l2; f2 += size2) {
+ if ((cmp(f2-size, f2) > 0) != sense) {
+ p2 = *EVAL(p2) = f2 - list1 + list2;
+ if (sense > 0)
+ reverse(f1, f2-size);
+ f1 = f2;
+ }
+ }
+ if (sense > 0)
+ reverse (f1, f2-size);
+ f1 = f2;
+ if (f2 < last || cmp(f2 - size, f2) > 0)
+ p2 = *EVAL(p2) = f2 - list1 + list2;
+ else
+ p2 = *EVAL(p2) = list2 + n*size;
+ }
+ }
+#else /* pairwise merge only. */
+ for (f1 = list1, p2 = list2; f1 < last; f1 += size2) {
+ p2 = *EVAL(p2) = p2 + size2;
+ if (cmp (f1, f1 + size) > 0)
+ swap(f1, f1 + size);
+ }
+#endif /* NATURAL */
+}
+
+/*
+ * This is to avoid out-of-bounds addresses in sorting the
+ * last 4 elements.
+ */
+static void
+insertionsort(a, n, size, cmp)
+ u_char *a;
+ size_t n, size;
+ int (*cmp) __P((const void *, const void *));
+{
+ u_char *ai, *s, *t, *u, tmp;
+ int i;
+
+ for (ai = a+size; --n >= 1; ai += size)
+ for (t = ai; t > a; t -= size) {
+ u = t - size;
+ if (cmp(u, t) <= 0)
+ break;
+ swap(u, t);
+ }
+}
diff --git a/lib/libc/stdlib/netbsd_strtod.c b/lib/libc/stdlib/netbsd_strtod.c
new file mode 100644
index 0000000..a402b68
--- /dev/null
+++ b/lib/libc/stdlib/netbsd_strtod.c
@@ -0,0 +1,2517 @@
+/* From: NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp */
+/* $FreeBSD$ */
+
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991 by AT&T.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to
+ David M. Gay
+ AT&T Bell Laboratories, Room 2C-463
+ 600 Mountain Avenue
+ Murray Hill, NJ 07974-2070
+ U.S.A.
+ dmg@research.att.com or research!dmg
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
+ * significant byte has the lowest address.
+ * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
+ * significant byte has the lowest address.
+ * #define Long int on machines with 32-bit ints and 64-bit longs.
+ * #define Sudden_Underflow for IEEE-format machines without gradual
+ * underflow (i.e., that flush to zero on underflow).
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic.
+ * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
+ * #define No_leftright to omit left-right logic in fast floating-point
+ * computation of dtoa.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ * that use extended-precision instructions to compute rounded
+ * products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ * products but inaccurate quotients, e.g., for Intel i860.
+ * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
+ * integer arithmetic. Whether this speeds things up or slows things
+ * down depends on the machine and the number being converted.
+ * #define KR_headers for old-style C function headers.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
+ * if memory is available and otherwise does something you deem
+ * appropriate. If MALLOC is undefined, malloc will be invoked
+ * directly -- and assumed always to succeed.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
+ defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
+ defined(__powerpc__)
+#include <sys/types.h>
+#if BYTE_ORDER == BIG_ENDIAN
+#define IEEE_BIG_ENDIAN
+#else
+#define IEEE_LITTLE_ENDIAN
+#endif
+#endif
+
+#ifdef __arm32__
+/*
+ * Although the CPU is little endian the FP has different
+ * byte and word endianness. The byte order is still little endian
+ * but the word order is big endian.
+ */
+#define IEEE_BIG_ENDIAN
+#endif
+
+#ifdef vax
+#define VAX
+#endif
+
+#define Long int32_t
+#define ULong u_int32_t
+
+#ifdef DEBUG
+#include "stdio.h"
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+#ifdef __cplusplus
+#include "malloc.h"
+#include "memory.h"
+#else
+#ifndef KR_headers
+#include "stdlib.h"
+#include "string.h"
+#include "locale.h"
+#else
+#include "malloc.h"
+#include "memory.h"
+#endif
+#endif
+char *__dtoa __P((double, int, int, int *, int *, char **));
+
+#ifdef MALLOC
+#ifdef KR_headers
+extern char *MALLOC();
+#else
+extern void *MALLOC(size_t);
+#endif
+#else
+#define MALLOC malloc
+#endif
+
+#include "ctype.h"
+#include "errno.h"
+
+#ifdef Bad_float_h
+#undef __STDC__
+#ifdef IEEE_BIG_ENDIAN
+#define IEEE_ARITHMETIC
+#endif
+#ifdef IEEE_LITTLE_ENDIAN
+#define IEEE_ARITHMETIC
+#endif
+
+#ifdef IEEE_ARITHMETIC
+#define DBL_DIG 15
+#define DBL_MAX_10_EXP 308
+#define DBL_MAX_EXP 1024
+#define FLT_RADIX 2
+#define FLT_ROUNDS 1
+#define DBL_MAX 1.7976931348623157e+308
+#endif
+
+#ifdef IBM
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 75
+#define DBL_MAX_EXP 63
+#define FLT_RADIX 16
+#define FLT_ROUNDS 0
+#define DBL_MAX 7.2370055773322621e+75
+#endif
+
+#ifdef VAX
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 38
+#define DBL_MAX_EXP 127
+#define FLT_RADIX 2
+#define FLT_ROUNDS 1
+#define DBL_MAX 1.7014118346046923e+38
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX 2147483647
+#endif
+#else
+#include "float.h"
+#endif
+#ifndef __MATH_H__
+#include "math.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CONST
+#ifdef KR_headers
+#define CONST /* blank */
+#else
+#define CONST const
+#endif
+#endif
+
+#ifdef Unsigned_Shifts
+#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
+#else
+#define Sign_Extend(a,b) /*no-op*/
+#endif
+
+#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
+ defined(IBM) != 1
+Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
+IBM should be defined.
+#endif
+
+#ifdef IEEE_LITTLE_ENDIAN
+#define word0(x) ((ULong *)&x)[1]
+#define word1(x) ((ULong *)&x)[0]
+#else
+#define word0(x) ((ULong *)&x)[0]
+#define word1(x) ((ULong *)&x)[1]
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm32__)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+((unsigned short *)a)[1] = (unsigned short)c, a++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN)
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 0x100000
+#define Exp_msk11 0x100000
+#define Exp_mask 0x7ff00000
+#define P 53
+#define Bias 1023
+#define IEEE_Arith
+#define Emin (-1022)
+#define Exp_1 0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask 0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask 0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
+#else
+#undef Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#define Exp_shift 24
+#define Exp_shift1 24
+#define Exp_msk1 0x1000000
+#define Exp_msk11 0x1000000
+#define Exp_mask 0x7f000000
+#define P 14
+#define Bias 65
+#define Exp_1 0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask 0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask 0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#define Exp_shift 23
+#define Exp_shift1 7
+#define Exp_msk1 0x80
+#define Exp_msk11 0x800000
+#define Exp_mask 0x7f80
+#define P 56
+#define Bias 129
+#define Exp_1 0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask 0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask 0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif
+#endif
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+#ifdef KR_headers
+extern double rnd_prod(), rnd_quot();
+#else
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#endif
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#ifndef Just_16
+/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower. Hence the default is now to store 32 bits per Long.
+ */
+#ifndef Pack_32
+#define Pack_32
+#endif
+#endif
+
+#define Kmax 15
+
+#ifdef __cplusplus
+extern "C" double strtod(const char *s00, char **se);
+extern "C" char *__dtoa(double d, int mode, int ndigits,
+ int *decpt, int *sign, char **rve);
+#endif
+
+ struct
+Bigint {
+ struct Bigint *next;
+ int k, maxwds, sign, wds;
+ ULong x[1];
+ };
+
+ typedef struct Bigint Bigint;
+
+ static Bigint *freelist[Kmax+1];
+
+ static Bigint *
+Balloc
+#ifdef KR_headers
+ (k) int k;
+#else
+ (int k)
+#endif
+{
+ int x;
+ Bigint *rv;
+
+ if ((rv = freelist[k]) != NULL) {
+ freelist[k] = rv->next;
+ }
+ else {
+ x = 1 << k;
+ rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long));
+ rv->k = k;
+ rv->maxwds = x;
+ }
+ rv->sign = rv->wds = 0;
+ return rv;
+ }
+
+ static void
+Bfree
+#ifdef KR_headers
+ (v) Bigint *v;
+#else
+ (Bigint *v)
+#endif
+{
+ if (v) {
+ v->next = freelist[v->k];
+ freelist[v->k] = v;
+ }
+ }
+
+#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
+y->wds*sizeof(Long) + 2*sizeof(int))
+
+ static Bigint *
+multadd
+#ifdef KR_headers
+ (b, m, a) Bigint *b; int m, a;
+#else
+ (Bigint *b, int m, int a) /* multiply by m and add a */
+#endif
+{
+ int i, wds;
+ ULong *x, y;
+#ifdef Pack_32
+ ULong xi, z;
+#endif
+ Bigint *b1;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ do {
+#ifdef Pack_32
+ xi = *x;
+ y = (xi & 0xffff) * m + a;
+ z = (xi >> 16) * m + (y >> 16);
+ a = (int)(z >> 16);
+ *x++ = (z << 16) + (y & 0xffff);
+#else
+ y = *x * m + a;
+ a = (int)(y >> 16);
+ *x++ = y & 0xffff;
+#endif
+ }
+ while(++i < wds);
+ if (a) {
+ if (wds >= b->maxwds) {
+ b1 = Balloc(b->k+1);
+ Bcopy(b1, b);
+ Bfree(b);
+ b = b1;
+ }
+ b->x[wds++] = a;
+ b->wds = wds;
+ }
+ return b;
+ }
+
+ static Bigint *
+s2b
+#ifdef KR_headers
+ (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
+#else
+ (CONST char *s, int nd0, int nd, ULong y9)
+#endif
+{
+ Bigint *b;
+ int i, k;
+ Long x, y;
+
+ x = (nd + 8) / 9;
+ for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+#ifdef Pack_32
+ b = Balloc(k);
+ b->x[0] = y9;
+ b->wds = 1;
+#else
+ b = Balloc(k+1);
+ b->x[0] = y9 & 0xffff;
+ b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+ i = 9;
+ if (9 < nd0) {
+ s += 9;
+ do b = multadd(b, 10, *s++ - '0');
+ while(++i < nd0);
+ s++;
+ }
+ else
+ s += 10;
+ for(; i < nd; i++)
+ b = multadd(b, 10, *s++ - '0');
+ return b;
+ }
+
+ static int
+hi0bits
+#ifdef KR_headers
+ (x) ULong x;
+#else
+ (ULong x)
+#endif
+{
+ int k = 0;
+
+ if (!(x & 0xffff0000)) {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000)) {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000)) {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000)) {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000)) {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+ }
+
+ static int
+lo0bits
+#ifdef KR_headers
+ (y) ULong *y;
+#else
+ (ULong *y)
+#endif
+{
+ int k;
+ ULong x = *y;
+
+ if (x & 7) {
+ if (x & 1)
+ return 0;
+ if (x & 2) {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff)) {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff)) {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf)) {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3)) {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1)) {
+ k++;
+ x >>= 1;
+ if (!x & 1)
+ return 32;
+ }
+ *y = x;
+ return k;
+ }
+
+ static Bigint *
+i2b
+#ifdef KR_headers
+ (i) int i;
+#else
+ (int i)
+#endif
+{
+ Bigint *b;
+
+ b = Balloc(1);
+ b->x[0] = i;
+ b->wds = 1;
+ return b;
+ }
+
+ static Bigint *
+mult
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ Bigint *c;
+ int k, wa, wb, wc;
+ ULong carry, y, z;
+ ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+#ifdef Pack_32
+ ULong z2;
+#endif
+
+ if (a->wds < b->wds) {
+ c = a;
+ a = b;
+ b = c;
+ }
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds)
+ k++;
+ c = Balloc(k);
+ for(x = c->x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->x;
+ xae = xa + wa;
+ xb = b->x;
+ xbe = xb + wb;
+ xc0 = c->x;
+#ifdef Pack_32
+ for(; xb < xbe; xb++, xc0++) {
+ if ((y = *xb & 0xffff) != 0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+ carry = z >> 16;
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+ carry = z2 >> 16;
+ Storeinc(xc, z2, z);
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ if ((y = *xb >> 16) != 0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ z2 = *xc;
+ do {
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+ carry = z >> 16;
+ Storeinc(xc, z, z2);
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+ carry = z2 >> 16;
+ }
+ while(x < xae);
+ *xc = z2;
+ }
+ }
+#else
+ for(; xb < xbe; xc0++) {
+ if (y = *xb++) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * y + *xc + carry;
+ carry = z >> 16;
+ *xc++ = z & 0xffff;
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ }
+#endif
+ for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+ c->wds = wc;
+ return c;
+ }
+
+ static Bigint *p5s;
+
+ static Bigint *
+pow5mult
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ Bigint *b1, *p5, *p51;
+ int i;
+ static int p05[3] = { 5, 25, 125 };
+
+ if ((i = k & 3) != 0)
+ b = multadd(b, p05[i-1], 0);
+
+ if (!(k >>= 2))
+ return b;
+ if (!(p5 = p5s)) {
+ /* first time */
+ p5 = p5s = i2b(625);
+ p5->next = 0;
+ }
+ for(;;) {
+ if (k & 1) {
+ b1 = mult(b, p5);
+ Bfree(b);
+ b = b1;
+ }
+ if (!(k >>= 1))
+ break;
+ if (!(p51 = p5->next)) {
+ p51 = p5->next = mult(p5,p5);
+ p51->next = 0;
+ }
+ p5 = p51;
+ }
+ return b;
+ }
+
+ static Bigint *
+lshift
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ int i, k1, n, n1;
+ Bigint *b1;
+ ULong *x, *x1, *xe, z;
+
+#ifdef Pack_32
+ n = k >> 5;
+#else
+ n = k >> 4;
+#endif
+ k1 = b->k;
+ n1 = n + b->wds + 1;
+ for(i = b->maxwds; n1 > i; i <<= 1)
+ k1++;
+ b1 = Balloc(k1);
+ x1 = b1->x;
+ for(i = 0; i < n; i++)
+ *x1++ = 0;
+ x = b->x;
+ xe = x + b->wds;
+#ifdef Pack_32
+ if (k &= 0x1f) {
+ k1 = 32 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if ((*x1 = z) != 0)
+ ++n1;
+ }
+#else
+ if (k &= 0xf) {
+ k1 = 16 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k & 0xffff | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if (*x1 = z)
+ ++n1;
+ }
+#endif
+ else do
+ *x1++ = *x++;
+ while(x < xe);
+ b1->wds = n1 - 1;
+ Bfree(b);
+ return b1;
+ }
+
+ static int
+cmp
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ ULong *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->wds;
+ j = b->wds;
+#ifdef DEBUG
+ if (i > 1 && !a->x[i-1])
+ Bug("cmp called with a->x[a->wds-1] == 0");
+ if (j > 1 && !b->x[j-1])
+ Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->x;
+ xa = xa0 + j;
+ xb0 = b->x;
+ xb = xb0 + j;
+ for(;;) {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+ }
+
+ static Bigint *
+diff
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ Bigint *c;
+ int i, wa, wb;
+ Long borrow, y; /* We need signed shifts here. */
+ ULong *xa, *xae, *xb, *xbe, *xc;
+#ifdef Pack_32
+ Long z;
+#endif
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Balloc(0);
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Balloc(a->k);
+ c->sign = i;
+ wa = a->wds;
+ xa = a->x;
+ xae = xa + wa;
+ wb = b->wds;
+ xb = b->x;
+ xbe = xb + wb;
+ xc = c->x;
+ borrow = 0;
+#ifdef Pack_32
+ do {
+ y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(xc, z, y);
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = (*xa & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*xa++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(xc, z, y);
+ }
+#else
+ do {
+ y = *xa++ - *xb++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *xc++ = y & 0xffff;
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = *xa++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *xc++ = y & 0xffff;
+ }
+#endif
+ while(!*--xc)
+ wa--;
+ c->wds = wa;
+ return c;
+ }
+
+ static double
+ulp
+#ifdef KR_headers
+ (x) double x;
+#else
+ (double x)
+#endif
+{
+ Long L;
+ double a;
+
+ L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Sudden_Underflow
+ if (L > 0) {
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ word0(a) = L;
+ word1(a) = 0;
+#ifndef Sudden_Underflow
+ }
+ else {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift) {
+ word0(a) = 0x80000 >> L;
+ word1(a) = 0;
+ }
+ else {
+ word0(a) = 0;
+ L -= Exp_shift;
+ word1(a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+ }
+#endif
+ return a;
+ }
+
+ static double
+b2d
+#ifdef KR_headers
+ (a, e) Bigint *a; int *e;
+#else
+ (Bigint *a, int *e)
+#endif
+{
+ ULong *xa, *xa0, w, y, z;
+ int k;
+ double d;
+#ifdef VAX
+ ULong d0, d1;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+ xa0 = a->x;
+ xa = xa0 + a->wds;
+ y = *--xa;
+#ifdef DEBUG
+ if (!y) Bug("zero y in b2d");
+#endif
+ k = hi0bits(y);
+ *e = 32 - k;
+#ifdef Pack_32
+ if (k < Ebits) {
+ d0 = Exp_1 | y >> (Ebits - k);
+ w = xa > xa0 ? *--xa : 0;
+ d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits) {
+ d0 = Exp_1 | y << k | z >> (32 - k);
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k | y >> (32 - k);
+ }
+ else {
+ d0 = Exp_1 | y;
+ d1 = z;
+ }
+#else
+ if (k < Ebits + 16) {
+ z = xa > xa0 ? *--xa : 0;
+ d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
+ w = xa > xa0 ? *--xa : 0;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ w = xa > xa0 ? *--xa : 0;
+ k -= Ebits + 16;
+ d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = w << k + 16 | y << k;
+#endif
+ ret_d:
+#ifdef VAX
+ word0(d) = d0 >> 16 | d0 << 16;
+ word1(d) = d1 >> 16 | d1 << 16;
+#else
+#undef d0
+#undef d1
+#endif
+ return d;
+ }
+
+ static Bigint *
+d2b
+#ifdef KR_headers
+ (d, e, bits) double d; int *e, *bits;
+#else
+ (double d, int *e, int *bits)
+#endif
+{
+ Bigint *b;
+ int de, i, k;
+ ULong *x, y, z;
+#ifdef VAX
+ ULong d0, d1;
+ d0 = word0(d) >> 16 | word0(d) << 16;
+ d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+#ifdef Pack_32
+ b = Balloc(1);
+#else
+ b = Balloc(2);
+#endif
+ x = b->x;
+
+ z = d0 & Frac_mask;
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+ de = (int)(d0 >> Exp_shift);
+#ifndef IBM
+ z |= Exp_msk11;
+#endif
+#else
+ if ((de = (int)(d0 >> Exp_shift)) != 0)
+ z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+ if ((y = d1) != 0) {
+ if ((k = lo0bits(&y)) != 0) {
+ x[0] = y | z << (32 - k);
+ z >>= k;
+ }
+ else
+ x[0] = y;
+ i = b->wds = (x[1] = z) ? 2 : 1;
+ }
+ else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ x[0] = z;
+ i = b->wds = 1;
+ k += 32;
+ }
+#else
+ if (y = d1) {
+ if (k = lo0bits(&y))
+ if (k >= 16) {
+ x[0] = y | z << 32 - k & 0xffff;
+ x[1] = z >> k - 16 & 0xffff;
+ x[2] = z >> k;
+ i = 2;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16 | z << 16 - k & 0xffff;
+ x[2] = z >> k & 0xffff;
+ x[3] = z >> k+16;
+ i = 3;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16;
+ x[2] = z & 0xffff;
+ x[3] = z >> 16;
+ i = 3;
+ }
+ }
+ else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ if (k >= 16) {
+ x[0] = z;
+ i = 0;
+ }
+ else {
+ x[0] = z & 0xffff;
+ x[1] = z >> 16;
+ i = 1;
+ }
+ k += 32;
+ }
+ while(!x[i])
+ --i;
+ b->wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+ if (de) {
+#endif
+#ifdef IBM
+ *e = (de - Bias - (P-1) << 2) + k;
+ *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+#else
+ *e = de - Bias - (P-1) + k;
+ *bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+ }
+ else {
+ *e = de - Bias - (P-1) + 1 + k;
+#ifdef Pack_32
+ *bits = 32*i - hi0bits(x[i-1]);
+#else
+ *bits = (i+2)*16 - hi0bits(x[i]);
+#endif
+ }
+#endif
+ return b;
+ }
+#undef d0
+#undef d1
+
+ static double
+ratio
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ double da, db;
+ int k, ka, kb;
+
+ da = b2d(a, &ka);
+ db = b2d(b, &kb);
+#ifdef Pack_32
+ k = ka - kb + 32*(a->wds - b->wds);
+#else
+ k = ka - kb + 16*(a->wds - b->wds);
+#endif
+#ifdef IBM
+ if (k > 0) {
+ word0(da) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ da *= 1 << k;
+ }
+ else {
+ k = -k;
+ word0(db) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ db *= 1 << k;
+ }
+#else
+ if (k > 0)
+ word0(da) += k*Exp_msk1;
+ else {
+ k = -k;
+ word0(db) += k*Exp_msk1;
+ }
+#endif
+ return da / db;
+ }
+
+static CONST double
+tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+#ifdef VAX
+ , 1e23, 1e24
+#endif
+ };
+
+#ifdef IEEE_Arith
+static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
+#define n_bigtens 5
+#else
+#ifdef IBM
+static CONST double bigtens[] = { 1e16, 1e32, 1e64 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+static CONST double bigtens[] = { 1e16, 1e32 };
+static CONST double tinytens[] = { 1e-16, 1e-32 };
+#define n_bigtens 2
+#endif
+#endif
+
+ double
+strtod
+#ifdef KR_headers
+ (s00, se) CONST char *s00; char **se;
+#else
+ (CONST char *s00, char **se)
+#endif
+{
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
+ e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
+ CONST char *s, *s0, *s1;
+ double aadj, aadj1, adj, rv, rv0;
+ Long L;
+ ULong y, z;
+ Bigint *bb1, *bd0;
+ Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */
+
+#ifndef KR_headers
+ CONST char decimal_point = localeconv()->decimal_point[0];
+#else
+ CONST char decimal_point = '.';
+#endif
+
+ sign = nz0 = nz = 0;
+ rv = 0.;
+
+
+ for(s = s00; isspace((unsigned char) *s); s++)
+ ;
+
+ if (*s == '-') {
+ sign = 1;
+ s++;
+ } else if (*s == '+') {
+ s++;
+ }
+
+ if (*s == '\0') {
+ s = s00;
+ goto ret;
+ }
+
+ if (*s == '0') {
+ nz0 = 1;
+ while(*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ s0 = s;
+ y = z = 0;
+ for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < 16)
+ z = 10*z + c - '0';
+ nd0 = nd;
+ if (c == decimal_point) {
+ c = *++s;
+ if (!nd) {
+ for(; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+ nz++;
+ if (c -= '0') {
+ nf += nz;
+ for(i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 1)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 1)
+ z = 10*z + c;
+ nz = 0;
+ }
+ }
+ }
+ dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ s = s00;
+ goto ret;
+ }
+ s00 = s;
+ esign = 0;
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while(c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ L = c - '0';
+ s1 = s;
+ while((c = *++s) >= '0' && c <= '9')
+ L = 10*L + c - '0';
+ if (s - s1 > 8 || L > 19999)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 19999; /* safe for 16 bit ints */
+ else
+ e = (int)L;
+ if (esign)
+ e = -e;
+ }
+ else
+ e = 0;
+ }
+ else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0)
+ s = s00;
+ goto ret;
+ }
+ e1 = e -= nf;
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ rv = y;
+ if (k > 9)
+ rv = tens[k - 9] * rv + z;
+ bd0 = 0;
+ if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+ && FLT_ROUNDS == 1
+#endif
+ ) {
+ if (!e)
+ goto ret;
+ if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+ goto ret;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+ e -= i;
+ rv *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ word0(rv) -= P*Exp_msk1;
+ /* rv = */ rounded_product(rv, tens[e]);
+ if ((word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto ovfl;
+ word0(rv) += P*Exp_msk1;
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+#endif
+ goto ret;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+ /* rv = */ rounded_quotient(rv, tens[-e]);
+ goto ret;
+ }
+#endif
+ }
+ e1 += nd - k;
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ if (e1 > 0) {
+ if ((i = e1 & 15) != 0)
+ rv *= tens[i];
+ if (e1 &= ~15) {
+ if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+ errno = ERANGE;
+#ifdef __STDC__
+ rv = HUGE_VAL;
+#else
+ /* Can't trust HUGE_VAL */
+#ifdef IEEE_Arith
+ word0(rv) = Exp_mask;
+ word1(rv) = 0;
+#else
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+#endif
+#endif
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+ if (e1 >>= 4) {
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= bigtens[j];
+ /* The last multiplication could overflow. */
+ word0(rv) -= P*Exp_msk1;
+ rv *= bigtens[j];
+ if ((z = word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+ goto ovfl;
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ }
+ else
+ word0(rv) += P*Exp_msk1;
+ }
+
+ }
+ }
+ else if (e1 < 0) {
+ e1 = -e1;
+ if ((i = e1 & 15) != 0)
+ rv /= tens[i];
+ if (e1 &= ~15) {
+ e1 >>= 4;
+ if (e1 >= 1 << n_bigtens)
+ goto undfl;
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= tinytens[j];
+ /* The last multiplication could underflow. */
+ rv0 = rv;
+ rv *= tinytens[j];
+ if (!rv) {
+ rv = 2.*rv0;
+ rv *= tinytens[j];
+ if (!rv) {
+ undfl:
+ rv = 0.;
+ errno = ERANGE;
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ /* The refinement below will clean
+ * this approximation up.
+ */
+ }
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b(s0, nd0, nd, y);
+
+ for(;;) {
+ bd = Balloc(bd0->k);
+ Bcopy(bd, bd0);
+ bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
+ bs = i2b(1);
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+#ifdef Sudden_Underflow
+#ifdef IBM
+ j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+ j = P + 1 - bbbits;
+#endif
+#else
+ i = bbe + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j = bbe + (P-Emin);
+ else
+ j = P + 1 - bbbits;
+#endif
+ bb2 += j;
+ bd2 += j;
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0) {
+ bs = pow5mult(bs, bb5);
+ bb1 = mult(bs, bb);
+ Bfree(bb);
+ bb = bb1;
+ }
+ if (bb2 > 0)
+ bb = lshift(bb, bb2);
+ if (bd5 > 0)
+ bd = pow5mult(bd, bd5);
+ if (bd2 > 0)
+ bd = lshift(bd, bd2);
+ if (bs2 > 0)
+ bs = lshift(bs, bs2);
+ delta = diff(bb, bd);
+ dsign = delta->sign;
+ delta->sign = 0;
+ i = cmp(delta, bs);
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask)
+ break;
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if ((word0(rv) & Bndry_mask1) == Bndry_mask1
+ && word1(rv) == 0xffffffff) {
+ /*boundary case -- increment exponent*/
+ word0(rv) = (word0(rv) & Exp_mask)
+ + Exp_msk1
+#ifdef IBM
+ | Exp_msk1 >> 4
+#endif
+ ;
+ word1(rv) = 0;
+ break;
+ }
+ }
+ else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+ drop_down:
+ /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow
+ L = word0(rv) & Exp_mask;
+#ifdef IBM
+ if (L < Exp_msk1)
+#else
+ if (L <= Exp_msk1)
+#endif
+ goto undfl;
+ L -= Exp_msk1;
+#else
+ L = (word0(rv) & Exp_mask) - Exp_msk1;
+#endif
+ word0(rv) = L | Bndry_mask1;
+ word1(rv) = 0xffffffff;
+#ifdef IBM
+ goto cont;
+#else
+ break;
+#endif
+ }
+#ifndef ROUND_BIASED
+ if (!(word1(rv) & LSB))
+ break;
+#endif
+ if (dsign)
+ rv += ulp(rv);
+#ifndef ROUND_BIASED
+ else {
+ rv -= ulp(rv);
+#ifndef Sudden_Underflow
+ if (!rv)
+ goto undfl;
+#endif
+ }
+#endif
+ break;
+ }
+ if ((aadj = ratio(delta, bs)) <= 2.) {
+ if (dsign)
+ aadj = aadj1 = 1.;
+ else if (word1(rv) || word0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+ if (word1(rv) == Tiny1 && !word0(rv))
+ goto undfl;
+#endif
+ aadj = 1.;
+ aadj1 = -1.;
+ }
+ else {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2./FLT_RADIX)
+ aadj = 1./FLT_RADIX;
+ else
+ aadj *= 0.5;
+ aadj1 = -aadj;
+ }
+ }
+ else {
+ aadj *= 0.5;
+ aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+ switch(FLT_ROUNDS) {
+ case 2: /* towards +infinity */
+ aadj1 -= 0.5;
+ break;
+ case 0: /* towards 0 */
+ case 3: /* towards -infinity */
+ aadj1 += 0.5;
+ }
+#else
+ if (FLT_ROUNDS == 0)
+ aadj1 += 0.5;
+#endif
+ }
+ y = word0(rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+ rv0 = rv;
+ word0(rv) -= P*Exp_msk1;
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ if ((word0(rv) & Exp_mask) >=
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+ if (word0(rv0) == Big0 && word1(rv0) == Big1)
+ goto ovfl;
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ goto cont;
+ }
+ else
+ word0(rv) += P*Exp_msk1;
+ }
+ else {
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+ rv0 = rv;
+ word0(rv) += P*Exp_msk1;
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#ifdef IBM
+ if ((word0(rv) & Exp_mask) < P*Exp_msk1)
+#else
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+ {
+ if (word0(rv0) == Tiny0
+ && word1(rv0) == Tiny1)
+ goto undfl;
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ goto cont;
+ }
+ else
+ word0(rv) -= P*Exp_msk1;
+ }
+ else {
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ }
+#else
+ /* Compute adj so that the IEEE rounding rules will
+ * correctly round rv + adj in some half-way cases.
+ * If rv * ulp(rv) is denormalized (i.e.,
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+ * trouble from bits lost to denormalization;
+ * example: 1.2e-307 .
+ */
+ if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
+ aadj1 = (double)(int)(aadj + 0.5);
+ if (!dsign)
+ aadj1 = -aadj1;
+ }
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#endif
+ }
+ z = word0(rv) & Exp_mask;
+ if (y == z) {
+ /* Can we stop now? */
+ L = aadj;
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ }
+ else if (aadj < .4999999/FLT_RADIX)
+ break;
+ }
+ cont:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(delta);
+ }
+ retfree:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ ret:
+ if (se)
+ *se = (char *)s;
+ return sign ? -rv : rv;
+ }
+
+ static int
+quorem
+#ifdef KR_headers
+ (b, S) Bigint *b, *S;
+#else
+ (Bigint *b, Bigint *S)
+#endif
+{
+ int n;
+ Long borrow, y;
+ ULong carry, q, ys;
+ ULong *bx, *bxe, *sx, *sxe;
+#ifdef Pack_32
+ Long z;
+ ULong si, zs;
+#endif
+
+ n = S->wds;
+#ifdef DEBUG
+ /*debug*/ if (b->wds > n)
+ /*debug*/ Bug("oversize b in quorem");
+#endif
+ if (b->wds < n)
+ return 0;
+ sx = S->x;
+ sxe = sx + --n;
+ bx = b->x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug("oversized quotient in quorem");
+#endif
+ if (q) {
+ borrow = 0;
+ carry = 0;
+ do {
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) * q + carry;
+ zs = (si >> 16) * q + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ * q + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ }
+ while(sx <= sxe);
+ if (!*bxe) {
+ bx = b->x;
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ if (cmp(b, S) >= 0) {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->x;
+ sx = S->x;
+ do {
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) + carry;
+ zs = (si >> 16) + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ }
+ while(sx <= sxe);
+ bx = b->x;
+ bxe = bx + n;
+ if (!*bxe) {
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ return q;
+ }
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the Long
+ * calculation.
+ */
+
+ char *
+__dtoa
+#ifdef KR_headers
+ (d, mode, ndigits, decpt, sign, rve)
+ double d; int mode, ndigits, *decpt, *sign; char **rve;
+#else
+ (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
+#endif
+{
+ /* Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4-9 should give the same return values as 2-3, i.e.,
+ 4 <= mode <= 9 ==> same return as mode
+ 2 + (mode & 1). These modes are mainly for
+ debugging; often they run slower but sometimes
+ faster than modes 2-3.
+ 4,5,8,9 ==> left-to-right digit generation.
+ 6-9 ==> don't try fast floating-point estimate
+ (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be, dig, i, ieps, ilim0,
+ j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+ try_quick;
+ int ilim = 0, ilim1 = 0, spec_case = 0; /* pacify gcc */
+ Long L;
+#ifndef Sudden_Underflow
+ int denorm;
+ ULong x;
+#endif
+ Bigint *b, *b1, *delta, *mhi, *S;
+ Bigint *mlo = NULL; /* pacify gcc */
+ double d2, ds, eps;
+ char *s, *s0;
+ static Bigint *result;
+ static int result_k;
+
+ if (result) {
+ result->k = result_k;
+ result->maxwds = 1 << result_k;
+ Bfree(result);
+ result = 0;
+ }
+
+ if (word0(d) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ word0(d) &= ~Sign_bit; /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((word0(d) & Exp_mask) == Exp_mask)
+#else
+ if (word0(d) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+ s =
+#ifdef IEEE_Arith
+ !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" :
+#endif
+ "NaN";
+ if (rve)
+ *rve =
+#ifdef IEEE_Arith
+ s[3] ? s + 8 :
+#endif
+ s + 3;
+ return s;
+ }
+#endif
+#ifdef IBM
+ d += 0; /* normalize */
+#endif
+ if (!d) {
+ *decpt = 1;
+ s = "0";
+ if (rve)
+ *rve = s + 1;
+ return s;
+ }
+
+ b = d2b(d, &be, &bbits);
+#ifdef Sudden_Underflow
+ i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#else
+ if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
+#endif
+ d2 = d;
+ word0(d2) &= Frac_mask1;
+ word0(d2) |= Exp_11;
+#ifdef IBM
+ if (j = 11 - hi0bits(word0(d2) & Frac_mask))
+ d2 /= 1 << j;
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ }
+ else {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)
+ : word1(d) << (32 - i);
+ d2 = x;
+ word0(d2) -= 31*Exp_msk1; /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+ ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (d < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+ try_quick = 1;
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch(mode) {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ j = sizeof(ULong);
+ for(result_k = 0; sizeof(Bigint) - sizeof(ULong) + j <= i;
+ j <<= 1) result_k++;
+ result = Balloc(result_k);
+ s = s0 = (char *)result;
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ d2 = d;
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ d /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ d /= ds;
+ }
+ else if ((j1 = -k) != 0) {
+ d *= tens[j1 & 0xf];
+ for(j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ d *= bigtens[i];
+ }
+ }
+ if (k_check && d < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ d *= 10.;
+ ieps++;
+ }
+ eps = ieps*d + 7.;
+ word0(eps) -= (P-1)*Exp_msk1;
+ if (ilim == 0) {
+ S = mhi = 0;
+ d -= 5.;
+ if (d > eps)
+ goto one_digit;
+ if (d < -eps)
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ eps = 0.5/tens[ilim-1] - eps;
+ for(i = 0;;) {
+ L = d;
+ d -= L;
+ *s++ = '0' + (int)L;
+ if (d < eps)
+ goto ret1;
+ if (1. - d < eps)
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ eps *= 10.;
+ d *= 10.;
+ }
+ }
+ else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ eps *= tens[ilim-1];
+ for(i = 1;; i++, d *= 10.) {
+ L = d;
+ d -= L;
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ if (d > 0.5 + eps)
+ goto bump_up;
+ else if (d < 0.5 - eps) {
+ while(*--s == '0');
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ d = d2;
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = 0;
+ if (ilim < 0 || d <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for(i = 1;; i++) {
+ L = d / ds;
+ d -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (d < 0) {
+ L--;
+ d += ds;
+ }
+#endif
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ d += d;
+ if (d > ds || (d == ds && L & 1)) {
+ bump_up:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ if (!(d *= 10.))
+ break;
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ if (leftright) {
+ if (mode < 2) {
+ i =
+#ifndef Sudden_Underflow
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+ 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ }
+ else {
+ j = ilim - 1;
+ if (m5 >= j)
+ m5 -= j;
+ else {
+ s5 += j -= m5;
+ b5 += j;
+ m5 = 0;
+ }
+ if ((i = ilim) < 0) {
+ m2 -= i;
+ i = 0;
+ }
+ }
+ b2 += i;
+ s2 += i;
+ mhi = i2b(1);
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ mhi = pow5mult(mhi, m5);
+ b1 = mult(mhi, b);
+ Bfree(b);
+ b = b1;
+ }
+ if ((j = b5 - m5) != 0)
+ b = pow5mult(b, j);
+ }
+ else
+ b = pow5mult(b, b5);
+ }
+ S = i2b(1);
+ if (s5 > 0)
+ S = pow5mult(S, s5);
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ if (mode < 2) {
+ if (!word1(d) && !(word0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+ && word0(d) & Exp_mask
+#endif
+ ) {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ }
+ else
+ spec_case = 0;
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+#ifdef Pack_32
+ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
+ i = 32 - i;
+#else
+ if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
+ i = 16 - i;
+#endif
+ if (i > 4) {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4) {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0)
+ b = lshift(b, b2);
+ if (s2 > 0)
+ S = lshift(S, s2);
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0); /* we botched the k estimate */
+ if (leftright)
+ mhi = multadd(mhi, 10, 0);
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && mode > 2) {
+ if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0)
+ mhi = lshift(mhi, m2);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = Balloc(mhi->k);
+ Bcopy(mhi, mlo);
+ mhi = lshift(mhi, Log2P);
+ }
+
+ for(i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ delta = diff(S, mhi);
+ j1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(delta);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && !mode && !(word1(d) & 1)) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || (j == 0 && !mode
+#ifndef ROUND_BIASED
+ && !(word1(d) & 1)
+#endif
+ )) {
+ if (j1 > 0) {
+ b = lshift(b, 1);
+ j1 = cmp(b, S);
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
+ && dig++ == '9')
+ goto round_9_up;
+ }
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0) {
+ if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = dig + 1;
+ goto ret;
+ }
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (mlo == mhi)
+ mlo = mhi = multadd(mhi, 10, 0);
+ else {
+ mlo = multadd(mlo, 10, 0);
+ mhi = multadd(mhi, 10, 0);
+ }
+ }
+ }
+ else
+ for(i = 1;; i++) {
+ *s++ = dig = quorem(b,S) + '0';
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0);
+ }
+
+ /* Round off last digit */
+
+ b = lshift(b, 1);
+ j = cmp(b, S);
+ if (j > 0 || (j == 0 && dig & 1)) {
+ roundoff:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ else {
+ while(*--s == '0');
+ s++;
+ }
+ ret:
+ Bfree(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ ret1:
+ Bfree(b);
+ if (s == s0) { /* don't return empty string */
+ *s++ = '0';
+ k = 0;
+ }
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+ }
+#ifdef __cplusplus
+}
+#endif
diff --git a/lib/libc/stdlib/putenv.c b/lib/libc/stdlib/putenv.c
new file mode 100644
index 0000000..eb5e805
--- /dev/null
+++ b/lib/libc/stdlib/putenv.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)putenv.c 8.2 (Berkeley) 3/27/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <string.h>
+
+int
+putenv(str)
+ const char *str;
+{
+ char *p, *equal;
+ int rval;
+
+ if ((p = strdup(str)) == NULL)
+ return (-1);
+ if ((equal = index(p, '=')) == NULL) {
+ (void)free(p);
+ return (-1);
+ }
+ *equal = '\0';
+ rval = setenv(p, equal + 1, 1);
+ (void)free(p);
+ return (rval);
+}
diff --git a/lib/libc/stdlib/qsort.3 b/lib/libc/stdlib/qsort.3
new file mode 100644
index 0000000..0351df2
--- /dev/null
+++ b/lib/libc/stdlib/qsort.3
@@ -0,0 +1,236 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)qsort.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt QSORT 3
+.Os
+.Sh NAME
+.Nm qsort, heapsort, mergesort
+.Nd sort functions
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft void
+.Fn qsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
+.Ft int
+.Fn heapsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
+.Ft int
+.Fn mergesort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
+.Sh DESCRIPTION
+The
+.Fn qsort
+function is a modified partition-exchange sort, or quicksort.
+The
+.Fn heapsort
+function is a modified selection sort.
+The
+.Fn mergesort
+function is a modified merge sort with exponential search
+intended for sorting data with pre-existing order.
+.Pp
+The
+.Fn qsort
+and
+.Fn heapsort
+functions sort an array of
+.Fa nmemb
+objects, the initial member of which is pointed to by
+.Fa base .
+The size of each object is specified by
+.Fa size .
+.Fn Mergesort
+behaves similarly, but
+.Em requires
+that
+.Fa size
+be greater than
+.Dq "sizeof(void *) / 2" .
+.Pp
+The contents of the array
+.Fa base
+are sorted in ascending order according to
+a comparison function pointed to by
+.Fa compar ,
+which requires two arguments pointing to the objects being
+compared.
+.Pp
+The comparison function must return an integer less than, equal to, or
+greater than zero if the first argument is considered to be respectively
+less than, equal to, or greater than the second.
+.Pp
+The functions
+.Fn qsort
+and
+.Fn heapsort
+are
+.Em not
+stable, that is, if two members compare as equal, their order in
+the sorted array is undefined.
+The function
+.Fn mergesort
+is stable.
+.Pp
+The
+.Fn qsort
+function is an implementation of C.A.R. Hoare's ``quicksort'' algorithm,
+a variant of partition-exchange sorting; in particular, see D.E. Knuth's
+Algorithm Q.
+.Fn Qsort
+takes O N lg N average time.
+This implementation uses median selection to avoid its
+O N**2 worst-case behavior.
+.Pp
+The
+.Fn heapsort
+function is an implementation of J.W.J. William's ``heapsort'' algorithm,
+a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H.
+.Fn Heapsort
+takes O N lg N worst-case time.
+Its
+.Em only
+advantage over
+.Fn qsort
+is that it uses almost no additional memory; while
+.Fn qsort
+does not allocate memory, it is implemented using recursion.
+.Pp
+The function
+.Fn mergesort
+requires additional memory of size
+.Fa nmemb *
+.Fa size
+bytes; it should be used only when space is not at a premium.
+.Fn Mergesort
+is optimized for data with pre-existing order; its worst case
+time is O N lg N; its best case is O N.
+.Pp
+Normally,
+.Fn qsort
+is faster than
+.Fn mergesort
+is faster than
+.Fn heapsort .
+Memory availability and pre-existing order in the data can make this
+untrue.
+.Sh RETURN VALUES
+The
+.Fn qsort
+function
+returns no value.
+.Pp
+Upon successful completion,
+.Fn heapsort
+and
+.Fn mergesort
+return 0.
+Otherwise, they return \-1 and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn heapsort
+and
+.Fn mergesort
+functions succeed unless:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa size
+argument is zero, or,
+the
+.Fa size
+argument to
+.Fn mergesort
+is less than
+.Dq "sizeof(void *) / 2" .
+.It Bq Er ENOMEM
+.Fn Heapsort
+or
+.Fn mergesort
+were unable to allocate memory.
+.El
+.Sh COMPATIBILITY
+Previous versions of
+.Fn qsort
+did not permit the comparison routine itself to call
+.Fn qsort 3 .
+This is no longer true.
+.Sh SEE ALSO
+.Xr sort 1 ,
+.Xr radixsort 3
+.Rs
+.%A Hoare, C.A.R.
+.%D 1962
+.%T "Quicksort"
+.%J "The Computer Journal"
+.%V 5:1
+.%P pp. 10-15
+.Re
+.Rs
+.%A Williams, J.W.J
+.%D 1964
+.%T "Heapsort"
+.%J "Communications of the ACM"
+.%V 7:1
+.%P pp. 347-348
+.Re
+.Rs
+.%A Knuth, D.E.
+.%D 1968
+.%B "The Art of Computer Programming"
+.%V Vol. 3
+.%T "Sorting and Searching"
+.%P pp. 114-123, 145-149
+.Re
+.Rs
+.%A Mcilroy, P.M.
+.%T "Optimistic Sorting and Information Theoretic Complexity"
+.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms"
+.%V January 1992
+.Re
+.Rs
+.%A Bentley, J.L.
+.%T "Engineering a Sort Function"
+.%J "bentley@research.att.com"
+.%V January 1992
+.Re
+.Sh STANDARDS
+The
+.Fn qsort
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/stdlib/qsort.c b/lib/libc/stdlib/qsort.c
new file mode 100644
index 0000000..8adb714
--- /dev/null
+++ b/lib/libc/stdlib/qsort.c
@@ -0,0 +1,178 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+
+typedef int cmp_t __P((const void *, const void *));
+static inline char *med3 __P((char *, char *, char *, cmp_t *));
+static inline void swapfunc __P((char *, char *, int, int));
+
+#define min(a, b) (a) < (b) ? a : b
+
+/*
+ * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
+ */
+#define swapcode(TYPE, parmi, parmj, n) { \
+ long i = (n) / sizeof (TYPE); \
+ register TYPE *pi = (TYPE *) (parmi); \
+ register TYPE *pj = (TYPE *) (parmj); \
+ do { \
+ register TYPE t = *pi; \
+ *pi++ = *pj; \
+ *pj++ = t; \
+ } while (--i > 0); \
+}
+
+#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
+ es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
+
+static inline void
+swapfunc(a, b, n, swaptype)
+ char *a, *b;
+ int n, swaptype;
+{
+ if(swaptype <= 1)
+ swapcode(long, a, b, n)
+ else
+ swapcode(char, a, b, n)
+}
+
+#define swap(a, b) \
+ if (swaptype == 0) { \
+ long t = *(long *)(a); \
+ *(long *)(a) = *(long *)(b); \
+ *(long *)(b) = t; \
+ } else \
+ swapfunc(a, b, es, swaptype)
+
+#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
+
+static inline char *
+med3(a, b, c, cmp)
+ char *a, *b, *c;
+ cmp_t *cmp;
+{
+ return cmp(a, b) < 0 ?
+ (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
+ :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
+}
+
+void
+qsort(a, n, es, cmp)
+ void *a;
+ size_t n, es;
+ cmp_t *cmp;
+{
+ char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
+ int d, r, swaptype, swap_cnt;
+
+loop: SWAPINIT(a, es);
+ swap_cnt = 0;
+ if (n < 7) {
+ for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
+ for (pl = pm; pl > (char *)a && cmp(pl - es, pl) > 0;
+ pl -= es)
+ swap(pl, pl - es);
+ return;
+ }
+ pm = (char *)a + (n / 2) * es;
+ if (n > 7) {
+ pl = a;
+ pn = (char *)a + (n - 1) * es;
+ if (n > 40) {
+ d = (n / 8) * es;
+ pl = med3(pl, pl + d, pl + 2 * d, cmp);
+ pm = med3(pm - d, pm, pm + d, cmp);
+ pn = med3(pn - 2 * d, pn - d, pn, cmp);
+ }
+ pm = med3(pl, pm, pn, cmp);
+ }
+ swap(a, pm);
+ pa = pb = (char *)a + es;
+
+ pc = pd = (char *)a + (n - 1) * es;
+ for (;;) {
+ while (pb <= pc && (r = cmp(pb, a)) <= 0) {
+ if (r == 0) {
+ swap_cnt = 1;
+ swap(pa, pb);
+ pa += es;
+ }
+ pb += es;
+ }
+ while (pb <= pc && (r = cmp(pc, a)) >= 0) {
+ if (r == 0) {
+ swap_cnt = 1;
+ swap(pc, pd);
+ pd -= es;
+ }
+ pc -= es;
+ }
+ if (pb > pc)
+ break;
+ swap(pb, pc);
+ swap_cnt = 1;
+ pb += es;
+ pc -= es;
+ }
+ if (swap_cnt == 0) { /* Switch to insertion sort */
+ for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
+ for (pl = pm; pl > (char *)a && cmp(pl - es, pl) > 0;
+ pl -= es)
+ swap(pl, pl - es);
+ return;
+ }
+
+ pn = (char *)a + n * es;
+ r = min(pa - (char *)a, pb - pa);
+ vecswap(a, pb - r, r);
+ r = min(pd - pc, pn - pd - es);
+ vecswap(pb, pn - r, r);
+ if ((r = pb - pa) > es)
+ qsort(a, r / es, es, cmp);
+ if ((r = pd - pc) > es) {
+ /* Iterate rather than recurse to save stack space */
+ a = pn - r;
+ n = r / es;
+ goto loop;
+ }
+/* qsort(pn - r, r / es, es, cmp);*/
+}
diff --git a/lib/libc/stdlib/radixsort.3 b/lib/libc/stdlib/radixsort.3
new file mode 100644
index 0000000..7212a2e
--- /dev/null
+++ b/lib/libc/stdlib/radixsort.3
@@ -0,0 +1,162 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)radixsort.3 8.2 (Berkeley) 1/27/94
+.\" $FreeBSD$
+.\"
+.Dd January 27, 1994
+.Dt RADIXSORT 3
+.Os
+.Sh NAME
+.Nm radixsort
+.Nd radix sort
+.Sh SYNOPSIS
+.Fd #include <limits.h>
+.Fd #include <stdlib.h>
+.Ft int
+.Fn radixsort "const unsigned char **base" "int nmemb" "const unsigned char *table" "unsigned endbyte"
+.Ft int
+.Fn sradixsort "const unsigned char **base" "int nmemb" "const unsigned char *table" "unsigned endbyte"
+.Sh DESCRIPTION
+The
+.Fn radixsort
+and
+.Fn sradixsort
+functions
+are implementations of radix sort.
+.Pp
+These functions sort an array of pointers to byte strings, the initial
+member of which is referenced by
+.Fa base .
+The byte strings may contain any values; the end of each string
+is denoted by the user-specified value
+.Fa endbyte .
+.Pp
+Applications may specify a sort order by providing the
+.Fa table
+argument.
+If
+.Pf non- Dv NULL ,
+.Fa table
+must reference an array of
+.Dv UCHAR_MAX
++ 1 bytes which contains the sort
+weight of each possible byte value.
+The end-of-string byte must have a sort weight of 0 or 255
+(for sorting in reverse order).
+More than one byte may have the same sort weight.
+The
+.Fa table
+argument
+is useful for applications which wish to sort different characters
+equally, for example, providing a table with the same weights
+for A-Z as for a-z will result in a case-insensitive sort.
+If
+.Fa table
+is NULL, the contents of the array are sorted in ascending order
+according to the
+.Tn ASCII
+order of the byte strings they reference and
+.Fa endbyte
+has a sorting weight of 0.
+.Pp
+The
+.Fn sradixsort
+function is stable, that is, if two elements compare as equal, their
+order in the sorted array is unchanged.
+The
+.Fn sradixsort
+function uses additional memory sufficient to hold
+.Fa nmemb
+pointers.
+.Pp
+The
+.Fn radixsort
+function is not stable, but uses no additional memory.
+.Pp
+These functions are variants of most-significant-byte radix sorting; in
+particular, see D.E. Knuth's Algorithm R and section 5.2.5, exercise 10.
+They take linear time relative to the number of bytes in the strings.
+.Sh RETURN VALUES
+Upon successful completion 0 is returned.
+Otherwise, \-1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value of the
+.Fa endbyte
+element of
+.Fa table
+is not 0 or 255.
+.El
+.Pp
+Additionally, the
+.Fn sradixsort
+function
+may fail and set
+.Va errno
+for any of the errors specified for the library routine
+.Xr malloc 3 .
+.Sh SEE ALSO
+.Xr sort 1 ,
+.Xr qsort 3
+.Pp
+.Rs
+.%A Knuth, D.E.
+.%D 1968
+.%B "The Art of Computer Programming"
+.%T "Sorting and Searching"
+.%V Vol. 3
+.%P pp. 170-178
+.Re
+.Rs
+.%A Paige, R.
+.%D 1987
+.%T "Three Partition Refinement Algorithms"
+.%J "SIAM J. Comput."
+.%V Vol. 16
+.%N No. 6
+.Re
+.Rs
+.%A McIlroy, P.
+.%D 1993
+.%B "Engineering Radix Sort"
+.%T "Computing Systems"
+.%V Vol. 6:1
+.%P pp. 5-27
+.Re
+.Sh HISTORY
+The
+.Fn radixsort
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/stdlib/radixsort.c b/lib/libc/stdlib/radixsort.c
new file mode 100644
index 0000000..0a583ac
--- /dev/null
+++ b/lib/libc/stdlib/radixsort.c
@@ -0,0 +1,318 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Peter McIlroy and by Dan Bernstein at New York University,
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)radixsort.c 8.2 (Berkeley) 4/28/95";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Radixsort routines.
+ *
+ * Program r_sort_a() is unstable but uses O(logN) extra memory for a stack.
+ * Use radixsort(a, n, trace, endchar) for this case.
+ *
+ * For stable sorting (using N extra pointers) use sradixsort(), which calls
+ * r_sort_b().
+ *
+ * For a description of this code, see D. McIlroy, P. McIlroy, K. Bostic,
+ * "Engineering Radix Sort".
+ */
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+
+typedef struct {
+ const u_char **sa;
+ int sn, si;
+} stack;
+
+static inline void simplesort
+ __P((const u_char **, int, int, const u_char *, u_int));
+static void r_sort_a __P((const u_char **, int, int, const u_char *, u_int));
+static void r_sort_b __P((const u_char **,
+ const u_char **, int, int, const u_char *, u_int));
+
+#define THRESHOLD 20 /* Divert to simplesort(). */
+#define SIZE 512 /* Default stack size. */
+
+#define SETUP { \
+ if (tab == NULL) { \
+ tr = tr0; \
+ for (c = 0; c < endch; c++) \
+ tr0[c] = c + 1; \
+ tr0[c] = 0; \
+ for (c++; c < 256; c++) \
+ tr0[c] = c; \
+ endch = 0; \
+ } else { \
+ endch = tab[endch]; \
+ tr = tab; \
+ if (endch != 0 && endch != 255) { \
+ errno = EINVAL; \
+ return (-1); \
+ } \
+ } \
+}
+
+int
+radixsort(a, n, tab, endch)
+ const u_char **a, *tab;
+ int n;
+ u_int endch;
+{
+ const u_char *tr;
+ int c;
+ u_char tr0[256];
+
+ SETUP;
+ r_sort_a(a, n, 0, tr, endch);
+ return (0);
+}
+
+int
+sradixsort(a, n, tab, endch)
+ const u_char **a, *tab;
+ int n;
+ u_int endch;
+{
+ const u_char *tr, **ta;
+ int c;
+ u_char tr0[256];
+
+ SETUP;
+ if (n < THRESHOLD)
+ simplesort(a, n, 0, tr, endch);
+ else {
+ if ((ta = malloc(n * sizeof(a))) == NULL)
+ return (-1);
+ r_sort_b(a, ta, n, 0, tr, endch);
+ free(ta);
+ }
+ return (0);
+}
+
+#define empty(s) (s >= sp)
+#define pop(a, n, i) a = (--sp)->sa, n = sp->sn, i = sp->si
+#define push(a, n, i) sp->sa = a, sp->sn = n, (sp++)->si = i
+#define swap(a, b, t) t = a, a = b, b = t
+
+/* Unstable, in-place sort. */
+static void
+r_sort_a(a, n, i, tr, endch)
+ const u_char **a;
+ int n, i;
+ const u_char *tr;
+ u_int endch;
+{
+ static int count[256], nc, bmin;
+ register int c;
+ register const u_char **ak, *r;
+ stack s[SIZE], *sp, *sp0, *sp1, temp;
+ int *cp, bigc;
+ const u_char **an, *t, **aj, **top[256];
+
+ /* Set up stack. */
+ sp = s;
+ push(a, n, i);
+ while (!empty(s)) {
+ pop(a, n, i);
+ if (n < THRESHOLD) {
+ simplesort(a, n, i, tr, endch);
+ continue;
+ }
+ an = a + n;
+
+ /* Make character histogram. */
+ if (nc == 0) {
+ bmin = 255; /* First occupied bin, excluding eos. */
+ for (ak = a; ak < an;) {
+ c = tr[(*ak++)[i]];
+ if (++count[c] == 1 && c != endch) {
+ if (c < bmin)
+ bmin = c;
+ nc++;
+ }
+ }
+ if (sp + nc > s + SIZE) { /* Get more stack. */
+ r_sort_a(a, n, i, tr, endch);
+ continue;
+ }
+ }
+
+ /*
+ * Set top[]; push incompletely sorted bins onto stack.
+ * top[] = pointers to last out-of-place element in bins.
+ * count[] = counts of elements in bins.
+ * Before permuting: top[c-1] + count[c] = top[c];
+ * during deal: top[c] counts down to top[c-1].
+ */
+ sp0 = sp1 = sp; /* Stack position of biggest bin. */
+ bigc = 2; /* Size of biggest bin. */
+ if (endch == 0) /* Special case: set top[eos]. */
+ top[0] = ak = a + count[0];
+ else {
+ ak = a;
+ top[255] = an;
+ }
+ for (cp = count + bmin; nc > 0; cp++) {
+ while (*cp == 0) /* Find next non-empty pile. */
+ cp++;
+ if (*cp > 1) {
+ if (*cp > bigc) {
+ bigc = *cp;
+ sp1 = sp;
+ }
+ push(ak, *cp, i+1);
+ }
+ top[cp-count] = ak += *cp;
+ nc--;
+ }
+ swap(*sp0, *sp1, temp); /* Play it safe -- biggest bin last. */
+
+ /*
+ * Permute misplacements home. Already home: everything
+ * before aj, and in bin[c], items from top[c] on.
+ * Inner loop:
+ * r = next element to put in place;
+ * ak = top[r[i]] = location to put the next element.
+ * aj = bottom of 1st disordered bin.
+ * Outer loop:
+ * Once the 1st disordered bin is done, ie. aj >= ak,
+ * aj<-aj + count[c] connects the bins in a linked list;
+ * reset count[c].
+ */
+ for (aj = a; aj < an; *aj = r, aj += count[c], count[c] = 0)
+ for (r = *aj; aj < (ak = --top[c = tr[r[i]]]);)
+ swap(*ak, r, t);
+ }
+}
+
+/* Stable sort, requiring additional memory. */
+static void
+r_sort_b(a, ta, n, i, tr, endch)
+ const u_char **a, **ta;
+ int n, i;
+ const u_char *tr;
+ u_int endch;
+{
+ static int count[256], nc, bmin;
+ register int c;
+ register const u_char **ak, **ai;
+ stack s[512], *sp, *sp0, *sp1, temp;
+ const u_char **top[256];
+ int *cp, bigc;
+
+ sp = s;
+ push(a, n, i);
+ while (!empty(s)) {
+ pop(a, n, i);
+ if (n < THRESHOLD) {
+ simplesort(a, n, i, tr, endch);
+ continue;
+ }
+
+ if (nc == 0) {
+ bmin = 255;
+ for (ak = a + n; --ak >= a;) {
+ c = tr[(*ak)[i]];
+ if (++count[c] == 1 && c != endch) {
+ if (c < bmin)
+ bmin = c;
+ nc++;
+ }
+ }
+ if (sp + nc > s + SIZE) {
+ r_sort_b(a, ta, n, i, tr, endch);
+ continue;
+ }
+ }
+
+ sp0 = sp1 = sp;
+ bigc = 2;
+ if (endch == 0) {
+ top[0] = ak = a + count[0];
+ count[0] = 0;
+ } else {
+ ak = a;
+ top[255] = a + n;
+ count[255] = 0;
+ }
+ for (cp = count + bmin; nc > 0; cp++) {
+ while (*cp == 0)
+ cp++;
+ if ((c = *cp) > 1) {
+ if (c > bigc) {
+ bigc = c;
+ sp1 = sp;
+ }
+ push(ak, c, i+1);
+ }
+ top[cp-count] = ak += c;
+ *cp = 0; /* Reset count[]. */
+ nc--;
+ }
+ swap(*sp0, *sp1, temp);
+
+ for (ak = ta + n, ai = a+n; ak > ta;) /* Copy to temp. */
+ *--ak = *--ai;
+ for (ak = ta+n; --ak >= ta;) /* Deal to piles. */
+ *--top[tr[(*ak)[i]]] = *ak;
+ }
+}
+
+static inline void
+simplesort(a, n, b, tr, endch) /* insertion sort */
+ register const u_char **a;
+ int n, b;
+ register const u_char *tr;
+ u_int endch;
+{
+ register u_char ch;
+ const u_char **ak, **ai, *s, *t;
+
+ for (ak = a+1; --n >= 1; ak++)
+ for (ai = ak; ai > a; ai--) {
+ for (s = ai[0] + b, t = ai[-1] + b;
+ (ch = tr[*s]) != endch; s++, t++)
+ if (ch != tr[*t])
+ break;
+ if (ch >= tr[*t])
+ break;
+ swap(ai[0], ai[-1], s);
+ }
+}
diff --git a/lib/libc/stdlib/rand.3 b/lib/libc/stdlib/rand.3
new file mode 100644
index 0000000..1330cc7
--- /dev/null
+++ b/lib/libc/stdlib/rand.3
@@ -0,0 +1,103 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)rand.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd May 25, 1999
+.Dt RAND 3
+.Os
+.Sh NAME
+.Nm rand ,
+.Nm srand ,
+.Nm rand_r
+.Nd bad random number generator
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft void
+.Fn srand "unsigned seed"
+.Ft int
+.Fn rand void
+.Ft int
+.Fn rand_r "unsigned *ctx"
+.Sh DESCRIPTION
+.Bf -symbolic
+These interfaces are obsoleted by random(3).
+.Ef
+.Pp
+The
+.Fn rand
+function computes a sequence of pseudo-random integers in the range
+of 0 to
+.Dv RAND_MAX
+(as defined by the header file
+.Aq Pa stdlib.h ) .
+.Pp
+The
+.Fn srand
+function sets its argument
+.Fa seed
+as the seed for a new sequence of
+pseudo-random numbers to be returned by
+.Fn rand .
+These sequences are repeatable by calling
+.Fn srand
+with the same seed value.
+.Pp
+If no
+.Fa seed
+value is provided, the functions are automatically
+seeded with a value of 1.
+.Pp
+.Fn rand_r
+provides the same functionality as
+.Fn rand .
+A pointer to the context value
+.Fa ctx
+must be supplied by the caller.
+.Sh SEE ALSO
+.Xr random 3
+.Sh STANDARDS
+The
+.Fn rand
+and
+.Fn srand
+functions
+conform to
+.St -ansiC .
+.Pp
+The
+.Fn rand_r
+function is as proposed in the POSIX.4a Draft #6 document.
diff --git a/lib/libc/stdlib/rand.c b/lib/libc/stdlib/rand.c
new file mode 100644
index 0000000..94f6b50
--- /dev/null
+++ b/lib/libc/stdlib/rand.c
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Posix rand_r function added May 1999 by Wes Peters <wes@softweyr.com>.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rand.c 8.1 (Berkeley) 6/14/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <stdlib.h>
+
+#ifdef TEST
+#include <stdio.h>
+#endif /* TEST */
+
+static int
+do_rand(unsigned long *ctx)
+{
+ return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)RAND_MAX + 1));
+}
+
+
+int
+rand_r(unsigned int *ctx)
+{
+ u_long val = (u_long) *ctx;
+ *ctx = do_rand(&val);
+ return (int) *ctx;
+}
+
+
+static u_long next = 1;
+
+int
+rand()
+{
+ return do_rand(&next);
+}
+
+void
+srand(seed)
+u_int seed;
+{
+ next = seed;
+}
+
+#ifdef TEST
+
+main()
+{
+ int i;
+ unsigned myseed;
+
+ printf("seeding rand with 0x19610910: \n");
+ srand(0x19610910);
+
+ printf("generating three pseudo-random numbers:\n");
+ for (i = 0; i < 3; i++)
+ {
+ printf("next random number = %d\n", rand());
+ }
+
+ printf("generating the same sequence with rand_r:\n");
+ myseed = 0x19610910;
+ for (i = 0; i < 3; i++)
+ {
+ printf("next random number = %d\n", rand_r(&myseed));
+ }
+
+ return 0;
+}
+
+#endif /* TEST */
+
diff --git a/lib/libc/stdlib/random.3 b/lib/libc/stdlib/random.3
new file mode 100644
index 0000000..9cd2e0d
--- /dev/null
+++ b/lib/libc/stdlib/random.3
@@ -0,0 +1,190 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)random.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt RANDOM 3
+.Os BSD 4.2
+.Sh NAME
+.Nm random ,
+.Nm srandom ,
+.Nm srandomdev ,
+.Nm initstate ,
+.Nm setstate
+.Nd better random number generator; routines for changing generators
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft long
+.Fn random void
+.Ft void
+.Fn srandom "unsigned long seed"
+.Ft void
+.Fn srandomdev void
+.Ft char *
+.Fn initstate "unsigned long seed" "char *state" "long n"
+.Ft char *
+.Fn setstate "char *state"
+.Sh DESCRIPTION
+The
+.Fn random
+function
+uses a non-linear additive feedback random number generator employing a
+default table of size 31 long integers to return successive pseudo-random
+numbers in the range from 0 to
+.if t 2\u\s731\s10\d\(mi1.
+.if n (2**31)\(mi1.
+The period of this random number generator is very large, approximately
+.if t 16\(mu(2\u\s731\s10\d\(mi1).
+.if n 16*((2**31)\(mi1).
+.Pp
+The
+.Fn random
+and
+.Fn srandom
+functions have (almost) the same calling sequence and initialization properties as the
+.Xr rand 3
+and
+.Xr srand 3
+functions.
+The difference is that
+.Xr rand 3
+produces a much less random sequence \(em in fact, the low dozen bits
+generated by rand go through a cyclic pattern. All the bits generated by
+.Fn random
+are usable. For example,
+.Sq Li random()&01
+will produce a random binary
+value.
+.Pp
+Like
+.Xr rand 3 ,
+.Fn random
+will by default produce a sequence of numbers that can be duplicated
+by calling
+.Fn srandom
+with
+.Ql 1
+as the seed.
+.Pp
+The
+.Fn srandomdev
+routine initialize a state array using
+.Xr urandom 4
+random number device which returns good random numbers,
+suitable for cryptographic use.
+Note that this particular seeding
+procedure can generate states which are impossible to reproduce by
+calling
+.Fn srandom
+with any value, since the succeeding terms in the
+state buffer are no longer derived from the LC algorithm applied to
+a fixed seed.
+.Pp
+The
+.Fn initstate
+routine allows a state array, passed in as an argument, to be initialized
+for future use. The size of the state array (in bytes) is used by
+.Fn initstate
+to decide how sophisticated a random number generator it should use \(em the
+more state, the better the random numbers will be.
+(Current "optimal" values for the amount of state information are
+8, 32, 64, 128, and 256 bytes; other amounts will be rounded down to
+the nearest known amount. Using less than 8 bytes will cause an error.)
+The seed for the initialization (which specifies a starting point for
+the random number sequence, and provides for restarting at the same
+point) is also an argument.
+The
+.Fn initstate
+function
+returns a pointer to the previous state information array.
+.Pp
+Once a state has been initialized, the
+.Fn setstate
+routine provides for rapid switching between states.
+The
+.Fn setstate
+function
+returns a pointer to the previous state array; its
+argument state array is used for further random number generation
+until the next call to
+.Fn initstate
+or
+.Fn setstate .
+.Pp
+Once a state array has been initialized, it may be restarted at a
+different point either by calling
+.Fn initstate
+(with the desired seed, the state array, and its size) or by calling
+both
+.Fn setstate
+(with the state array) and
+.Fn srandom
+(with the desired seed).
+The advantage of calling both
+.Fn setstate
+and
+.Fn srandom
+is that the size of the state array does not have to be remembered after
+it is initialized.
+.Pp
+With 256 bytes of state information, the period of the random number
+generator is greater than
+.if t 2\u\s769\s10\d,
+.if n 2**69
+which should be sufficient for most purposes.
+.Sh AUTHORS
+.An Earl T. Cohen
+.Sh DIAGNOSTICS
+If
+.Fn initstate
+is called with less than 8 bytes of state information, or if
+.Fn setstate
+detects that the state information has been garbled, error
+messages are printed on the standard error output.
+.Sh SEE ALSO
+.Xr rand 3 ,
+.Xr srand 3 ,
+.Xr urandom 4
+.Sh HISTORY
+These
+functions appeared in
+.Bx 4.2 .
+.Sh BUGS
+.Pp
+About 2/3 the speed of
+.Xr rand 3 .
+.Pp
+The historical implementation used to have a very weak seeding; the
+random sequence did not vary much with the seed.
+The current implementation employs a better pseudo-random number
+generator for the initial state calculation.
diff --git a/lib/libc/stdlib/random.c b/lib/libc/stdlib/random.c
new file mode 100644
index 0000000..8be99b4
--- /dev/null
+++ b/lib/libc/stdlib/random.c
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)random.c 8.2 (Berkeley) 5/19/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/time.h> /* for srandomdev() */
+#include <fcntl.h> /* for srandomdev() */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h> /* for srandomdev() */
+
+/*
+ * random.c:
+ *
+ * An improved random number generation package. In addition to the standard
+ * rand()/srand() like interface, this package also has a special state info
+ * interface. The initstate() routine is called with a seed, an array of
+ * bytes, and a count of how many bytes are being passed in; this array is
+ * then initialized to contain information for random number generation with
+ * that much state information. Good sizes for the amount of state
+ * information are 32, 64, 128, and 256 bytes. The state can be switched by
+ * calling the setstate() routine with the same array as was initiallized
+ * with initstate(). By default, the package runs with 128 bytes of state
+ * information and generates far better random numbers than a linear
+ * congruential generator. If the amount of state information is less than
+ * 32 bytes, a simple linear congruential R.N.G. is used.
+ *
+ * Internally, the state information is treated as an array of longs; the
+ * zeroeth element of the array is the type of R.N.G. being used (small
+ * integer); the remainder of the array is the state information for the
+ * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
+ * state information, which will allow a degree seven polynomial. (Note:
+ * the zeroeth word of state information also has some other information
+ * stored in it -- see setstate() for details).
+ *
+ * The random number generation technique is a linear feedback shift register
+ * approach, employing trinomials (since there are fewer terms to sum up that
+ * way). In this approach, the least significant bit of all the numbers in
+ * the state table will act as a linear feedback shift register, and will
+ * have period 2^deg - 1 (where deg is the degree of the polynomial being
+ * used, assuming that the polynomial is irreducible and primitive). The
+ * higher order bits will have longer periods, since their values are also
+ * influenced by pseudo-random carries out of the lower bits. The total
+ * period of the generator is approximately deg*(2**deg - 1); thus doubling
+ * the amount of state information has a vast influence on the period of the
+ * generator. Note: the deg*(2**deg - 1) is an approximation only good for
+ * large deg, when the period of the shift register is the dominant factor.
+ * With deg equal to seven, the period is actually much longer than the
+ * 7*(2**7 - 1) predicted by this formula.
+ *
+ * Modified 28 December 1994 by Jacob S. Rosenberg.
+ * The following changes have been made:
+ * All references to the type u_int have been changed to unsigned long.
+ * All references to type int have been changed to type long. Other
+ * cleanups have been made as well. A warning for both initstate and
+ * setstate has been inserted to the effect that on Sparc platforms
+ * the 'arg_state' variable must be forced to begin on word boundaries.
+ * This can be easily done by casting a long integer array to char *.
+ * The overall logic has been left STRICTLY alone. This software was
+ * tested on both a VAX and Sun SpacsStation with exactly the same
+ * results. The new version and the original give IDENTICAL results.
+ * The new version is somewhat faster than the original. As the
+ * documentation says: "By default, the package runs with 128 bytes of
+ * state information and generates far better random numbers than a linear
+ * congruential generator. If the amount of state information is less than
+ * 32 bytes, a simple linear congruential R.N.G. is used." For a buffer of
+ * 128 bytes, this new version runs about 19 percent faster and for a 16
+ * byte buffer it is about 5 percent faster.
+ */
+
+/*
+ * For each of the currently supported random number generators, we have a
+ * break value on the amount of state information (you need at least this
+ * many bytes of state info to support this random number generator), a degree
+ * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
+ * the separation between the two lower order coefficients of the trinomial.
+ */
+#define TYPE_0 0 /* linear congruential */
+#define BREAK_0 8
+#define DEG_0 0
+#define SEP_0 0
+
+#define TYPE_1 1 /* x**7 + x**3 + 1 */
+#define BREAK_1 32
+#define DEG_1 7
+#define SEP_1 3
+
+#define TYPE_2 2 /* x**15 + x + 1 */
+#define BREAK_2 64
+#define DEG_2 15
+#define SEP_2 1
+
+#define TYPE_3 3 /* x**31 + x**3 + 1 */
+#define BREAK_3 128
+#define DEG_3 31
+#define SEP_3 3
+
+#define TYPE_4 4 /* x**63 + x + 1 */
+#define BREAK_4 256
+#define DEG_4 63
+#define SEP_4 1
+
+/*
+ * Array versions of the above information to make code run faster --
+ * relies on fact that TYPE_i == i.
+ */
+#define MAX_TYPES 5 /* max number of types above */
+
+static long degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
+static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
+
+/*
+ * Initially, everything is set up as if from:
+ *
+ * initstate(1, randtbl, 128);
+ *
+ * Note that this initialization takes advantage of the fact that srandom()
+ * advances the front and rear pointers 10*rand_deg times, and hence the
+ * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
+ * element of the state information, which contains info about the current
+ * position of the rear pointer is just
+ *
+ * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
+ */
+
+static long randtbl[DEG_3 + 1] = {
+ TYPE_3,
+#ifdef USE_WEAK_SEEDING
+/* Historic implementation compatibility */
+/* The random sequences do not vary much with the seed */
+ 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5,
+ 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
+ 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88,
+ 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
+ 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b,
+ 0x27fb47b9,
+#else /* !USE_WEAK_SEEDING */
+ 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
+ 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
+ 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
+ 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
+ 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
+ 0xf3bec5da
+#endif /* !USE_WEAK_SEEDING */
+};
+
+/*
+ * fptr and rptr are two pointers into the state info, a front and a rear
+ * pointer. These two pointers are always rand_sep places aparts, as they
+ * cycle cyclically through the state information. (Yes, this does mean we
+ * could get away with just one pointer, but the code for random() is more
+ * efficient this way). The pointers are left positioned as they would be
+ * from the call
+ *
+ * initstate(1, randtbl, 128);
+ *
+ * (The position of the rear pointer, rptr, is really 0 (as explained above
+ * in the initialization of randtbl) because the state table pointer is set
+ * to point to randtbl[1] (as explained below).
+ */
+static long *fptr = &randtbl[SEP_3 + 1];
+static long *rptr = &randtbl[1];
+
+/*
+ * The following things are the pointer to the state information table, the
+ * type of the current generator, the degree of the current polynomial being
+ * used, and the separation between the two pointers. Note that for efficiency
+ * of random(), we remember the first location of the state information, not
+ * the zeroeth. Hence it is valid to access state[-1], which is used to
+ * store the type of the R.N.G. Also, we remember the last location, since
+ * this is more efficient than indexing every time to find the address of
+ * the last element to see if the front and rear pointers have wrapped.
+ */
+static long *state = &randtbl[1];
+static long rand_type = TYPE_3;
+static long rand_deg = DEG_3;
+static long rand_sep = SEP_3;
+static long *end_ptr = &randtbl[DEG_3 + 1];
+
+static inline long good_rand __P((long));
+
+static inline long good_rand (x)
+ register long x;
+{
+#ifdef USE_WEAK_SEEDING
+/*
+ * Historic implementation compatibility.
+ * The random sequences do not vary much with the seed,
+ * even with overflowing.
+ */
+ return (1103515245 * x + 12345);
+#else /* !USE_WEAK_SEEDING */
+/*
+ * Compute x = (7^5 * x) mod (2^31 - 1)
+ * wihout overflowing 31 bits:
+ * (2^31 - 1) = 127773 * (7^5) + 2836
+ * From "Random number generators: good ones are hard to find",
+ * Park and Miller, Communications of the ACM, vol. 31, no. 10,
+ * October 1988, p. 1195.
+ */
+ register long hi, lo;
+
+ hi = x / 127773;
+ lo = x % 127773;
+ x = 16807 * lo - 2836 * hi;
+ if (x <= 0)
+ x += 0x7fffffff;
+ return (x);
+#endif /* !USE_WEAK_SEEDING */
+}
+
+/*
+ * srandom:
+ *
+ * Initialize the random number generator based on the given seed. If the
+ * type is the trivial no-state-information type, just remember the seed.
+ * Otherwise, initializes state[] based on the given "seed" via a linear
+ * congruential generator. Then, the pointers are set to known locations
+ * that are exactly rand_sep places apart. Lastly, it cycles the state
+ * information a given number of times to get rid of any initial dependencies
+ * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
+ * for default usage relies on values produced by this routine.
+ */
+void
+srandom(x)
+ unsigned long x;
+{
+ register long i;
+
+ if (rand_type == TYPE_0)
+ state[0] = x;
+ else {
+ state[0] = x;
+ for (i = 1; i < rand_deg; i++)
+ state[i] = good_rand(state[i - 1]);
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ for (i = 0; i < 10 * rand_deg; i++)
+ (void)random();
+ }
+}
+
+/*
+ * srandomdev:
+ *
+ * Many programs choose the seed value in a totally predictable manner.
+ * This often causes problems. We seed the generator using the much more
+ * secure urandom(4) interface. Note that this particular seeding
+ * procedure can generate states which are impossible to reproduce by
+ * calling srandom() with any value, since the succeeding terms in the
+ * state buffer are no longer derived from the LC algorithm applied to
+ * a fixed seed.
+ */
+void
+srandomdev()
+{
+ int fd, done;
+ size_t len;
+
+ if (rand_type == TYPE_0)
+ len = sizeof state[0];
+ else
+ len = rand_deg * sizeof state[0];
+
+ done = 0;
+ fd = open("/dev/urandom", O_RDONLY, 0);
+ if (fd >= 0) {
+ if (read(fd, (void *) state, len) == (ssize_t) len)
+ done = 1;
+ close(fd);
+ }
+
+ if (!done) {
+ struct timeval tv;
+ unsigned long junk;
+
+ gettimeofday(&tv, NULL);
+ srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk);
+ return;
+ }
+
+ if (rand_type != TYPE_0) {
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ }
+}
+
+/*
+ * initstate:
+ *
+ * Initialize the state information in the given array of n bytes for future
+ * random number generation. Based on the number of bytes we are given, and
+ * the break values for the different R.N.G.'s, we choose the best (largest)
+ * one we can and set things up for it. srandom() is then called to
+ * initialize the state information.
+ *
+ * Note that on return from srandom(), we set state[-1] to be the type
+ * multiplexed with the current value of the rear pointer; this is so
+ * successive calls to initstate() won't lose this information and will be
+ * able to restart with setstate().
+ *
+ * Note: the first thing we do is save the current state, if any, just like
+ * setstate() so that it doesn't matter when initstate is called.
+ *
+ * Returns a pointer to the old state.
+ *
+ * Note: The Sparc platform requires that arg_state begin on a long
+ * word boundary; otherwise a bus error will occur. Even so, lint will
+ * complain about mis-alignment, but you should disregard these messages.
+ */
+char *
+initstate(seed, arg_state, n)
+ unsigned long seed; /* seed for R.N.G. */
+ char *arg_state; /* pointer to state array */
+ long n; /* # bytes of state info */
+{
+ register char *ostate = (char *)(&state[-1]);
+ register long *long_arg_state = (long *) arg_state;
+
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = MAX_TYPES * (rptr - state) + rand_type;
+ if (n < BREAK_0) {
+ (void)fprintf(stderr,
+ "random: not enough state (%ld bytes); ignored.\n", n);
+ return(0);
+ }
+ if (n < BREAK_1) {
+ rand_type = TYPE_0;
+ rand_deg = DEG_0;
+ rand_sep = SEP_0;
+ } else if (n < BREAK_2) {
+ rand_type = TYPE_1;
+ rand_deg = DEG_1;
+ rand_sep = SEP_1;
+ } else if (n < BREAK_3) {
+ rand_type = TYPE_2;
+ rand_deg = DEG_2;
+ rand_sep = SEP_2;
+ } else if (n < BREAK_4) {
+ rand_type = TYPE_3;
+ rand_deg = DEG_3;
+ rand_sep = SEP_3;
+ } else {
+ rand_type = TYPE_4;
+ rand_deg = DEG_4;
+ rand_sep = SEP_4;
+ }
+ state = (long *) (long_arg_state + 1); /* first location */
+ end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
+ srandom(seed);
+ if (rand_type == TYPE_0)
+ long_arg_state[0] = rand_type;
+ else
+ long_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type;
+ return(ostate);
+}
+
+/*
+ * setstate:
+ *
+ * Restore the state from the given state array.
+ *
+ * Note: it is important that we also remember the locations of the pointers
+ * in the current state information, and restore the locations of the pointers
+ * from the old state information. This is done by multiplexing the pointer
+ * location into the zeroeth word of the state information.
+ *
+ * Note that due to the order in which things are done, it is OK to call
+ * setstate() with the same state as the current state.
+ *
+ * Returns a pointer to the old state information.
+ *
+ * Note: The Sparc platform requires that arg_state begin on a long
+ * word boundary; otherwise a bus error will occur. Even so, lint will
+ * complain about mis-alignment, but you should disregard these messages.
+ */
+char *
+setstate(arg_state)
+ char *arg_state; /* pointer to state array */
+{
+ register long *new_state = (long *) arg_state;
+ register long type = new_state[0] % MAX_TYPES;
+ register long rear = new_state[0] / MAX_TYPES;
+ char *ostate = (char *)(&state[-1]);
+
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = MAX_TYPES * (rptr - state) + rand_type;
+ switch(type) {
+ case TYPE_0:
+ case TYPE_1:
+ case TYPE_2:
+ case TYPE_3:
+ case TYPE_4:
+ rand_type = type;
+ rand_deg = degrees[type];
+ rand_sep = seps[type];
+ break;
+ default:
+ (void)fprintf(stderr,
+ "random: state info corrupted; not changed.\n");
+ }
+ state = (long *) (new_state + 1);
+ if (rand_type != TYPE_0) {
+ rptr = &state[rear];
+ fptr = &state[(rear + rand_sep) % rand_deg];
+ }
+ end_ptr = &state[rand_deg]; /* set end_ptr too */
+ return(ostate);
+}
+
+/*
+ * random:
+ *
+ * If we are using the trivial TYPE_0 R.N.G., just do the old linear
+ * congruential bit. Otherwise, we do our fancy trinomial stuff, which is
+ * the same in all the other cases due to all the global variables that have
+ * been set up. The basic operation is to add the number at the rear pointer
+ * into the one at the front pointer. Then both pointers are advanced to
+ * the next location cyclically in the table. The value returned is the sum
+ * generated, reduced to 31 bits by throwing away the "least random" low bit.
+ *
+ * Note: the code takes advantage of the fact that both the front and
+ * rear pointers can't wrap on the same call by not testing the rear
+ * pointer if the front one has wrapped.
+ *
+ * Returns a 31-bit random number.
+ */
+long
+random()
+{
+ register long i;
+ register long *f, *r;
+
+ if (rand_type == TYPE_0) {
+ i = state[0];
+ state[0] = i = (good_rand(i)) & 0x7fffffff;
+ } else {
+ /*
+ * Use local variables rather than static variables for speed.
+ */
+ f = fptr; r = rptr;
+ *f += *r;
+ i = (*f >> 1) & 0x7fffffff; /* chucking least random bit */
+ if (++f >= end_ptr) {
+ f = state;
+ ++r;
+ }
+ else if (++r >= end_ptr) {
+ r = state;
+ }
+
+ fptr = f; rptr = r;
+ }
+ return(i);
+}
diff --git a/lib/libc/stdlib/reallocf.c b/lib/libc/stdlib/reallocf.c
new file mode 100644
index 0000000..e9327e6
--- /dev/null
+++ b/lib/libc/stdlib/reallocf.c
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 1998, M. Warner Losh <imp@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+
+void *
+reallocf(void *ptr, size_t size)
+{
+ void *nptr;
+
+ nptr = realloc(ptr, size);
+ if (!nptr && ptr)
+ free(ptr);
+ return (nptr);
+}
diff --git a/lib/libc/stdlib/realpath.3 b/lib/libc/stdlib/realpath.3
new file mode 100644
index 0000000..fa7323d
--- /dev/null
+++ b/lib/libc/stdlib/realpath.3
@@ -0,0 +1,126 @@
+.\" Copyright (c) 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Jan-Simon Pendry.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)realpath.3 8.2 (Berkeley) 2/16/94
+.\" $FreeBSD$
+.\"
+.Dd February 16, 1994
+.Dt REALPATH 3
+.Os
+.Sh NAME
+.Nm realpath
+.Nd returns the canonicalized absolute pathname
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <stdlib.h>
+.Ft "char *"
+.Fn realpath "const char *pathname" "char resolvedname[MAXPATHLEN]"
+.Sh DESCRIPTION
+The
+.Fn realpath
+function resolves all symbolic links, extra
+.Dq /
+characters and references to
+.Pa /./
+and
+.Pa /../
+in
+.Fa pathname ,
+and copies the resulting absolute pathname into
+the memory referenced by
+.Fa resolvedname .
+The
+.Fa resolvedname
+argument
+.Em must
+refer to a buffer capable of storing at least
+.Dv MAXPATHLEN
+characters.
+.Pp
+The
+.Fn realpath
+function will resolve both absolute and relative paths
+and return the absolute pathname corresponding to
+.Fa pathname .
+All but the last component of
+.Fa pathname
+must exist when
+.Fn realpath
+is called.
+.Sh "RETURN VALUES"
+The
+.Fn realpath
+function returns
+.Fa resolved_name
+on success.
+If an error occurs,
+.Fn realpath
+returns
+.Dv NULL ,
+and
+.Fa resolved_name
+contains the pathname which caused the problem.
+.Sh ERRORS
+The function
+.Fn realpath
+may fail and set the external variable
+.Va errno
+for any of the errors specified for the library functions
+.Xr chdir 2 ,
+.Xr close 2 ,
+.Xr fchdir 2 ,
+.Xr lstat 2 ,
+.Xr open 2 ,
+.Xr readlink 2
+and
+.Xr getcwd 3 .
+.Sh CAVEATS
+This implementation of
+.Fn realpath
+differs slightly from the Solaris implementation.
+The
+.Bx 4.4
+version always returns absolute pathnames,
+whereas the Solaris implementation will,
+under certain circumstances, return a relative
+.Fa resolved_path
+when given a relative
+.Fa pathname .
+.Sh "SEE ALSO"
+.Xr getcwd 3
+.Sh HISTORY
+The
+.Fn realpath
+function call first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c
new file mode 100644
index 0000000..80ed43f
--- /dev/null
+++ b/lib/libc/stdlib/realpath.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)realpath.c 8.1 (Berkeley) 2/16/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * char *realpath(const char *path, char resolved_path[MAXPATHLEN]);
+ *
+ * Find the real name of path, by removing all ".", ".." and symlink
+ * components. Returns (resolved) on success, or (NULL) on failure,
+ * in which case the path which caused trouble is left in (resolved).
+ */
+char *
+realpath(path, resolved)
+ const char *path;
+ char *resolved;
+{
+ struct stat sb;
+ int fd, n, rootd, serrno;
+ char *p, *q, wbuf[MAXPATHLEN];
+ int symlinks = 0;
+
+ /* Save the starting point. */
+ if ((fd = open(".", O_RDONLY)) < 0) {
+ (void)strcpy(resolved, ".");
+ return (NULL);
+ }
+
+ /*
+ * Find the dirname and basename from the path to be resolved.
+ * Change directory to the dirname component.
+ * lstat the basename part.
+ * if it is a symlink, read in the value and loop.
+ * if it is a directory, then change to that directory.
+ * get the current directory name and append the basename.
+ */
+ (void)strncpy(resolved, path, MAXPATHLEN - 1);
+ resolved[MAXPATHLEN - 1] = '\0';
+loop:
+ q = strrchr(resolved, '/');
+ if (q != NULL) {
+ p = q + 1;
+ if (q == resolved)
+ q = "/";
+ else {
+ do {
+ --q;
+ } while (q > resolved && *q == '/');
+ q[1] = '\0';
+ q = resolved;
+ }
+ if (chdir(q) < 0)
+ goto err1;
+ } else
+ p = resolved;
+
+ /* Deal with the last component. */
+ if (*p != '\0' && lstat(p, &sb) == 0) {
+ if (S_ISLNK(sb.st_mode)) {
+ if (++symlinks > MAXSYMLINKS) {
+ errno = ELOOP;
+ goto err1;
+ }
+ n = readlink(p, resolved, MAXPATHLEN - 1);
+ if (n < 0)
+ goto err1;
+ resolved[n] = '\0';
+ goto loop;
+ }
+ if (S_ISDIR(sb.st_mode)) {
+ if (chdir(p) < 0)
+ goto err1;
+ p = "";
+ }
+ }
+
+ /*
+ * Save the last component name and get the full pathname of
+ * the current directory.
+ */
+ (void)strcpy(wbuf, p);
+ if (getcwd(resolved, MAXPATHLEN) == 0)
+ goto err1;
+
+ /*
+ * Join the two strings together, ensuring that the right thing
+ * happens if the last component is empty, or the dirname is root.
+ */
+ if (resolved[0] == '/' && resolved[1] == '\0')
+ rootd = 1;
+ else
+ rootd = 0;
+
+ if (*wbuf) {
+ if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ goto err1;
+ }
+ if (rootd == 0)
+ (void)strcat(resolved, "/");
+ (void)strcat(resolved, wbuf);
+ }
+
+ /* Go back to where we came from. */
+ if (fchdir(fd) < 0) {
+ serrno = errno;
+ goto err2;
+ }
+
+ /* It's okay if the close fails, what's an fd more or less? */
+ (void)close(fd);
+ return (resolved);
+
+err1: serrno = errno;
+ (void)fchdir(fd);
+err2: (void)close(fd);
+ errno = serrno;
+ return (NULL);
+}
diff --git a/lib/libc/stdlib/setenv.c b/lib/libc/stdlib/setenv.c
new file mode 100644
index 0000000..4c00b6e
--- /dev/null
+++ b/lib/libc/stdlib/setenv.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setenv.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *__findenv __P((const char *, int *));
+
+/*
+ * setenv --
+ * Set the value of the environmental variable "name" to be
+ * "value". If rewrite is set, replace any current value.
+ */
+int
+setenv(name, value, rewrite)
+ register const char *name;
+ register const char *value;
+ int rewrite;
+{
+ extern char **environ;
+ static int alloced; /* if allocated space before */
+ register char *c;
+ int l_value, offset;
+
+ if (*value == '=') /* no `=' in value */
+ ++value;
+ l_value = strlen(value);
+ if ((c = __findenv(name, &offset))) { /* find if already exists */
+ if (!rewrite)
+ return (0);
+ if (strlen(c) >= l_value) { /* old larger; copy over */
+ while ( (*c++ = *value++) );
+ return (0);
+ }
+ } else { /* create new slot */
+ register int cnt;
+ register char **p;
+
+ for (p = environ, cnt = 0; *p; ++p, ++cnt);
+ if (alloced) { /* just increase size */
+ environ = (char **)reallocf((char *)environ,
+ (size_t)(sizeof(char *) * (cnt + 2)));
+ if (!environ)
+ return (-1);
+ }
+ else { /* get new space */
+ alloced = 1; /* copy old entries into it */
+ p = malloc((size_t)(sizeof(char *) * (cnt + 2)));
+ if (!p)
+ return (-1);
+ bcopy(environ, p, cnt * sizeof(char *));
+ environ = p;
+ }
+ environ[cnt + 1] = NULL;
+ offset = cnt;
+ }
+ for (c = (char *)name; *c && *c != '='; ++c); /* no `=' in name */
+ if (!(environ[offset] = /* name + `=' + value */
+ malloc((size_t)((int)(c - name) + l_value + 2))))
+ return (-1);
+ for (c = environ[offset]; (*c = *name++) && *c != '='; ++c);
+ for (*c++ = '='; (*c++ = *value++); );
+ return (0);
+}
+
+/*
+ * unsetenv(name) --
+ * Delete environmental variable "name".
+ */
+void
+unsetenv(name)
+ const char *name;
+{
+ extern char **environ;
+ register char **p;
+ int offset;
+
+ while (__findenv(name, &offset)) /* if set multiple times */
+ for (p = &environ[offset];; ++p)
+ if (!(*p = *(p + 1)))
+ break;
+}
diff --git a/lib/libc/stdlib/strhash.c b/lib/libc/stdlib/strhash.c
new file mode 100644
index 0000000..8de4f3f
--- /dev/null
+++ b/lib/libc/stdlib/strhash.c
@@ -0,0 +1,410 @@
+#ifndef lint
+static const char *rcsid =
+"$FreeBSD$";
+#endif
+
+/*
+ *
+ * Copyright 1990
+ * Terry Jones & Jordan Hubbard
+ *
+ * PCS Computer Systeme, GmbH.
+ * Munich, West Germany
+ *
+ *
+ * All rights reserved.
+ *
+ * This is unsupported software and is subject to change without notice.
+ * the author makes no representations about the suitability of this software
+ * for any purpose. It is supplied "as is" without express or implied
+ * warranty.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ */
+
+/*
+ * This is a fairly simple open addressing hash scheme.
+ * Terry did all the code, I just did the spec.
+ * Thanks again, you crazy Aussie..
+ *
+ */
+
+/*
+ * $Log: strhash.c,v $
+ * Revision 2.0 90/03/26 01:44:26 jkh
+ * pre-beta check-in
+ *
+ * Revision 1.8 90/03/09 19:22:35 jkh
+ * Fixed bogus comment.
+ *
+ * Revision 1.7 90/03/09 19:01:08 jkh
+ * Added comments, GPL.
+ *
+ * Revision 1.6 90/03/08 17:55:58 terry
+ * Rearranged hash_purge to be a tiny bit more efficient.
+ * Added verbose option to hash_stats.
+ *
+ * Revision 1.5 90/03/08 17:19:54 terry
+ * Added hash_purge. Added arg to hash_traverse. Changed all
+ * void * to Generic.
+ *
+ * Revision 1.4 90/03/08 12:02:35 terry
+ * Fixed problems with allocation that I screwed up last night.
+ * Changed bucket lists to be singly linked. Thanks to JKH, my hero.
+ *
+ * Revision 1.3 90/03/07 21:33:33 terry
+ * Cleaned up a few decls to keep gcc -Wall quiet.
+ *
+ * Revision 1.2 90/03/07 21:14:53 terry
+ * Comments. Added HASH_STATS define. Removed hash_find()
+ * and new_node().
+ *
+ * Revision 1.1 90/03/07 20:49:45 terry
+ * Initial revision
+ *
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <strhash.h>
+
+#define HASH_NULL (hash_table *)0
+#define NODE_NULL (hash_node *)0
+#define GENERIC_NULL (void *)0
+
+#define HASH_SZ 97
+
+
+static int _hash(int size, char *key);
+static hash_node *list_find(caddr_t key, hash_node *head);
+
+
+/*
+ * hash_create()
+ *
+ * Malloc room for a new hash table and then room for its
+ * bucket pointers. Then set all the buckets to
+ * point to 0. Return the address of the new table.
+ */
+hash_table *
+hash_create(int size)
+{
+ register int i;
+ hash_table *new = (hash_table *)malloc(sizeof(hash_table));
+
+ if (!new || size < 0){
+ return HASH_NULL;
+ }
+
+ if (size == 0){
+ size = HASH_SZ;
+ }
+
+ if (!(new->buckets = (hash_node **)malloc(size * sizeof(hash_node *)))){
+ return HASH_NULL;
+ }
+
+ for (i = 0; i < size; i++){
+ new->buckets[i] = NODE_NULL;
+ }
+ new->size = size;
+
+ return new;
+}
+
+
+/*
+ * list_find()
+ *
+ * Find the key in the linked list pointed to by head.
+ */
+static hash_node *
+list_find(caddr_t key, hash_node *head)
+{
+ while (head){
+ if (!strcmp(head->key, key)){
+ return head;
+ }
+ head = head->next;
+ }
+ return NODE_NULL;
+}
+
+
+/*
+ * _hash()
+ *
+ * Compute the hash value for the given key.
+ */
+static int
+_hash(int size, char *key)
+{
+ unsigned int h = 0x0;
+
+ while (*key){
+ h = (h << 1) ^ (h ^ (unsigned char) *key++);
+ }
+
+ h %= size;
+ return h;
+}
+
+/*
+ * hash_destroy()
+ *
+ * Find the key and (if it's there) remove it entirely.
+ * The function (*nukefunc)() is in charge of disposing
+ * of the storage help by the data associated with the node.
+ */
+void
+hash_destroy(hash_table *table, char *key, void (*nukefunc)())
+{
+ int bucket = _hash(table->size, key);
+ hash_node *found = table->buckets[bucket];
+ hash_node *to_free = NODE_NULL;
+
+ if (!found) {
+ return;
+ }
+
+ if (!strcmp(found->key, key)) {
+ /*
+ * It was the head of the list.
+ */
+ table->buckets[bucket] = found->next;
+ to_free = found;
+ }
+ else {
+ /*
+ * Walk the list, looking one ahead.
+ */
+ while (found->next) {
+ if (!strcmp(found->next->key, key)) {
+ to_free = found->next;
+ found->next = found->next->next;
+ break;
+ }
+ found = found->next;
+ }
+
+ if (!to_free){
+ return;
+ }
+ }
+
+ if (nukefunc)
+ (*nukefunc)(to_free->key, to_free->data);
+ free(to_free);
+ return;
+}
+
+
+/*
+ * hash_search()
+ *
+ * Search the table for the given key. Then:
+ *
+ * 1) If you find it and there is no replacement function, just
+ * return what you found. (This is a simple search).
+ * 2) If you find it and there is a replacement function, run
+ * the function on the data you found, and replace the old
+ * data with whatever is passed in datum. Return 0.
+ * 3) If you don't find it and there is some datum, insert a
+ * new item into the table. Insertions go at the front of
+ * the bucket. Return 0.
+ * 4) Otherwise just return 0.
+ *
+ */
+void *
+hash_search(hash_table *table, caddr_t key, void *datum,
+ void (*replace_func)())
+{
+ int bucket = _hash(table->size, key);
+ hash_node *found = list_find(key, table->buckets[bucket]);
+
+ if (found){
+ if (!replace_func){
+ return found->data;
+ }
+ else{
+ (*replace_func)(found->data);
+ found->data = datum;
+ }
+ }
+ else{
+ if (datum){
+
+ static int assign_key();
+
+ hash_node *new = (hash_node *)malloc(sizeof(hash_node));
+
+ if (!new || !assign_key(key, new)){
+ return GENERIC_NULL;
+ }
+ new->data = datum;
+ new->next = table->buckets[bucket];
+ table->buckets[bucket] = new;
+ return new;
+ }
+ }
+ return GENERIC_NULL;
+}
+
+
+/*
+ * assign_key()
+ *
+ * Set the key value of a node to be 'key'. Get some space from
+ * malloc and copy it in etc. Return 1 if all is well, 0 otherwise.
+ */
+static int
+assign_key(char *key, hash_node *node)
+{
+ if (!node || !key){
+ return 0;
+ }
+
+ if (!(node->key = (char *)malloc(strlen(key) + 1))){
+ return 0;
+ }
+
+ node->key[0] = '\0';
+ strcat(node->key, key);
+ return 1;
+}
+
+/*
+ * hash_traverse()
+ *
+ * Traverse the hash table and run the function func on the
+ * data found at each node and the argument we're passed for it.
+ */
+void
+hash_traverse(hash_table *table, int (*func)(), void *arg)
+{
+ register int i;
+ register int size = table->size;
+
+ if (!func)
+ return;
+
+ for (i = 0; i < size; i++) {
+ hash_node *n = table->buckets[i];
+ while (n) {
+ if ((*func)(n->key, n->data, arg) == 0)
+ return;
+ n = n->next;
+ }
+ }
+ return;
+}
+
+/*
+ * hash_purge()
+ *
+ * Run through the entire hash table. Call purge_func
+ * on the data found at each node, and then free the node.
+ * Set all the bucket pointers to 0.
+ */
+void
+hash_purge(hash_table *table, void (*purge_func)(char *p1, void *p2))
+{
+ register int i;
+ register int size = table->size;
+
+ for (i = 0; i < size; i++) {
+ hash_node *n = table->buckets[i];
+ if (n) {
+ do {
+ hash_node *to_free = n;
+ if (purge_func) {
+ (*purge_func)(n->key, n->data);
+ }
+ n = n->next;
+ free(to_free);
+ } while (n);
+ table->buckets[i] = NODE_NULL;
+ }
+ }
+}
+
+#undef min
+#define min(a, b) (a) < (b) ? (a) : (b)
+
+/*
+ * hash_stats()
+ *
+ * Print statistics about the current table allocation to stdout.
+ */
+void
+hash_stats(hash_table *table, int verbose)
+{
+ register int i;
+ int total_elements = 0;
+ int non_empty_buckets = 0;
+ int max_count = 0;
+ int max_repeats = 0;
+ int *counts;
+ int size = table->size;
+
+ if (!(counts = (int *)malloc(size * sizeof(int)))){
+ fprintf(stderr, "malloc returns 0\n");
+ exit(1);
+ }
+
+ for (i = 0; i < size; i++){
+ int x = 0;
+ hash_node *n = table->buckets[i];
+ counts[i] = 0;
+ while (n){
+ if (!x){
+ x = 1;
+ non_empty_buckets++;
+ if (verbose){
+ printf("bucket %2d: ", i);
+ }
+ }
+ if (verbose){
+ printf(" %s", n->key);
+ }
+ counts[i]++;
+ n = n->next;
+ }
+
+ total_elements += counts[i];
+ if (counts[i] > max_count){
+ max_count = counts[i];
+ max_repeats = 1;
+ }
+ else if (counts[i] == max_count){
+ max_repeats++;
+ }
+
+ if (counts[i] && verbose){
+ printf(" (%d)\n", counts[i]);
+ }
+ }
+
+ printf("\n");
+ printf("%d element%s in storage.\n", total_elements, total_elements == 1 ? "" : "s");
+
+ if (total_elements){
+ printf("%d of %d (%.2f%%) buckets are in use\n", non_empty_buckets, size,
+ (double)100 * (double)non_empty_buckets / (double)(size));
+ printf("the maximum number of elements in a bucket is %d (%d times)\n", max_count, max_repeats);
+ printf("average per bucket is %f\n", (double)total_elements / (double)non_empty_buckets);
+ printf("optimal would be %f\n", (double)total_elements / (double)(min(size, total_elements)));
+ }
+ return;
+}
diff --git a/lib/libc/stdlib/strtod.3 b/lib/libc/stdlib/strtod.3
new file mode 100644
index 0000000..aa8054f
--- /dev/null
+++ b/lib/libc/stdlib/strtod.3
@@ -0,0 +1,134 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strtod.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRTOD 3
+.Os
+.Sh NAME
+.Nm strtod
+.Nd convert
+.Tn ASCII
+string to double
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft double
+.Fn strtod "const char *nptr" "char **endptr"
+.Sh DESCRIPTION
+The
+.Fn strtod
+function converts the initial portion of the string
+pointed to by
+.Fa nptr
+to
+.Em double
+representation.
+.Pp
+The expected form of the string is an optional plus (``+'') or minus
+sign (``\-'') followed by a sequence of digits optionally containing
+a decimal-point character, optionally followed by an exponent.
+An exponent consists of an ``E'' or ``e'', followed by an optional plus
+or minus sign, followed by a sequence of digits.
+.Pp
+Leading white-space characters in the string (as defined by the
+.Xr isspace 3
+function) are skipped.
+.Sh RETURN VALUES
+The
+.Fn strtod
+function returns the converted value, if any.
+.Pp
+If
+.Fa endptr
+is not
+.Dv NULL ,
+a pointer to the character after the last character used
+in the conversion is stored in the location referenced by
+.Fa endptr .
+.Pp
+If no conversion is performed, zero is returned and the value of
+.Fa nptr
+is stored in the location referenced by
+.Fa endptr .
+.Pp
+If the correct value would cause overflow, plus or minus
+.Dv HUGE_VAL
+is returned (according to the sign of the value), and
+.Dv ERANGE
+is stored in
+.Va errno .
+If the correct value would cause underflow, zero is
+returned and
+.Dv ERANGE
+is stored in
+.Va errno .
+.Sh ERRORS
+.Bl -tag -width [ERANGE]
+.It Bq Er ERANGE
+Overflow or underflow occurred.
+.Sh SEE ALSO
+.Xr atof 3 ,
+.Xr atoi 3 ,
+.Xr atol 3 ,
+.Xr strtol 3 ,
+.Xr strtoul 3
+.Sh STANDARDS
+The
+.Fn strtod
+function
+conforms to
+.St -ansiC .
+.Sh AUTHORS
+The author of this software is
+.An David M. Gay .
+.Pp
+Copyright (c) 1991 by AT&T.
+.Pp
+Permission to use, copy, modify, and distribute this software for any
+purpose without fee is hereby granted, provided that this entire notice
+is included in all copies of any software which is or includes a copy
+or modification of this software and in all copies of the supporting
+documentation for such software.
+.Pp
+THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+.Pp
+Contact your vendor for a free copy of the source code to
+.Fn strtod
+and accompanying functions.
diff --git a/lib/libc/stdlib/strtod.c b/lib/libc/stdlib/strtod.c
new file mode 100644
index 0000000..27fb499
--- /dev/null
+++ b/lib/libc/stdlib/strtod.c
@@ -0,0 +1,2443 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtod.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991 by AT&T.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to
+ David M. Gay
+ AT&T Bell Laboratories, Room 2C-463
+ 600 Mountain Avenue
+ Murray Hill, NJ 07974-2070
+ U.S.A.
+ dmg@research.att.com or research!dmg
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_8087 for IEEE-arithmetic machines where the least
+ * significant byte has the lowest address.
+ * #define IEEE_MC68k for IEEE-arithmetic machines where the most
+ * significant byte has the lowest address.
+ * #define Sudden_Underflow for IEEE-format machines without gradual
+ * underflow (i.e., that flush to zero on underflow).
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic.
+ * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
+ * #define No_leftright to omit left-right logic in fast floating-point
+ * computation of dtoa.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ * that use extended-precision instructions to compute rounded
+ * products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ * products but inaccurate quotients, e.g., for Intel i860.
+ * #define Just_16 to store 16 bits per 32-bit long when doing high-precision
+ * integer arithmetic. Whether this speeds things up or slows things
+ * down depends on the machine and the number being converted.
+ * #define KR_headers for old-style C function headers.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ */
+
+#if defined(i386) || defined(mips) && defined(MIPSEL)
+#define IEEE_8087
+#else
+#define IEEE_MC68k
+#endif
+
+#ifdef DEBUG
+#include "stdio.h"
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+#ifdef __cplusplus
+#include "malloc.h"
+#include "memory.h"
+#else
+#ifndef KR_headers
+#include "stdlib.h"
+#include "string.h"
+#else
+#include "malloc.h"
+#include "memory.h"
+#endif
+#endif
+
+#include "errno.h"
+#include <ctype.h>
+#ifdef Bad_float_h
+#undef __STDC__
+#ifdef IEEE_MC68k
+#define IEEE_ARITHMETIC
+#endif
+#ifdef IEEE_8087
+#define IEEE_ARITHMETIC
+#endif
+#ifdef IEEE_ARITHMETIC
+#define DBL_DIG 15
+#define DBL_MAX_10_EXP 308
+#define DBL_MAX_EXP 1024
+#define FLT_RADIX 2
+#define FLT_ROUNDS 1
+#define DBL_MAX 1.7976931348623157e+308
+#endif
+
+#ifdef IBM
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 75
+#define DBL_MAX_EXP 63
+#define FLT_RADIX 16
+#define FLT_ROUNDS 0
+#define DBL_MAX 7.2370055773322621e+75
+#endif
+
+#ifdef VAX
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 38
+#define DBL_MAX_EXP 127
+#define FLT_RADIX 2
+#define FLT_ROUNDS 1
+#define DBL_MAX 1.7014118346046923e+38
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX 2147483647
+#endif
+#else
+#include "float.h"
+#endif
+#ifndef __MATH_H__
+#include "math.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CONST
+#ifdef KR_headers
+#define CONST /* blank */
+#else
+#define CONST const
+#endif
+#endif
+
+#ifdef Unsigned_Shifts
+#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
+#else
+#define Sign_Extend(a,b) /*no-op*/
+#endif
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
+Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
+#endif
+
+#ifdef IEEE_8087
+#define word0(x) ((unsigned long *)&x)[1]
+#define word1(x) ((unsigned long *)&x)[0]
+#else
+#define word0(x) ((unsigned long *)&x)[0]
+#define word1(x) ((unsigned long *)&x)[1]
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_8087) + defined(VAX)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+((unsigned short *)a)[1] = (unsigned short)c, a++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k)
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 0x100000
+#define Exp_msk11 0x100000
+#define Exp_mask 0x7ff00000
+#define P 53
+#define Bias 1023
+#define IEEE_Arith
+#define Emin (-1022)
+#define Exp_1 0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask 0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask 0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
+#else
+#undef Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#define Exp_shift 24
+#define Exp_shift1 24
+#define Exp_msk1 0x1000000
+#define Exp_msk11 0x1000000
+#define Exp_mask 0x7f000000
+#define P 14
+#define Bias 65
+#define Exp_1 0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask 0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask 0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#define Exp_shift 23
+#define Exp_shift1 7
+#define Exp_msk1 0x80
+#define Exp_msk11 0x800000
+#define Exp_mask 0x7f80
+#define P 56
+#define Bias 129
+#define Exp_1 0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask 0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask 0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif
+#endif
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+#ifdef KR_headers
+extern double rnd_prod(), rnd_quot();
+#else
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#endif
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#ifndef Just_16
+/* When Pack_32 is not defined, we store 16 bits per 32-bit long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower. Hence the default is now to store 32 bits per long.
+ */
+#ifndef Pack_32
+#define Pack_32
+#endif
+#endif
+
+#define Kmax 15
+
+#ifdef __cplusplus
+extern "C" double strtod(const char *s00, char **se);
+extern "C" char *dtoa(double d, int mode, int ndigits,
+ int *decpt, int *sign, char **rve);
+#endif
+
+ struct
+Bigint {
+ struct Bigint *next;
+ int k, maxwds, sign, wds;
+ unsigned long x[1];
+};
+
+ typedef struct Bigint Bigint;
+
+ static Bigint *freelist[Kmax+1];
+
+ static Bigint *
+Balloc
+#ifdef KR_headers
+ (k) int k;
+#else
+ (int k)
+#endif
+{
+ int x;
+ Bigint *rv;
+
+ if ( (rv = freelist[k]) ) {
+ freelist[k] = rv->next;
+ } else {
+ x = 1 << k;
+ rv = (Bigint *)malloc(sizeof(Bigint) + (x-1)*sizeof(long));
+ rv->k = k;
+ rv->maxwds = x;
+ }
+ rv->sign = rv->wds = 0;
+ return rv;
+}
+
+ static void
+Bfree
+#ifdef KR_headers
+ (v) Bigint *v;
+#else
+ (Bigint *v)
+#endif
+{
+ if (v) {
+ v->next = freelist[v->k];
+ freelist[v->k] = v;
+ }
+}
+
+#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
+y->wds*sizeof(long) + 2*sizeof(int))
+
+ static Bigint *
+multadd
+#ifdef KR_headers
+ (b, m, a) Bigint *b; int m, a;
+#else
+ (Bigint *b, int m, int a) /* multiply by m and add a */
+#endif
+{
+ int i, wds;
+ unsigned long *x, y;
+#ifdef Pack_32
+ unsigned long xi, z;
+#endif
+ Bigint *b1;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ do {
+#ifdef Pack_32
+ xi = *x;
+ y = (xi & 0xffff) * m + a;
+ z = (xi >> 16) * m + (y >> 16);
+ a = (int)(z >> 16);
+ *x++ = (z << 16) + (y & 0xffff);
+#else
+ y = *x * m + a;
+ a = (int)(y >> 16);
+ *x++ = y & 0xffff;
+#endif
+ } while (++i < wds);
+ if (a) {
+ if (wds >= b->maxwds) {
+ b1 = Balloc(b->k+1);
+ Bcopy(b1, b);
+ Bfree(b);
+ b = b1;
+ }
+ b->x[wds++] = a;
+ b->wds = wds;
+ }
+ return b;
+}
+
+ static Bigint *
+s2b
+#ifdef KR_headers
+ (s, nd0, nd, y9) CONST char *s; int nd0, nd; unsigned long y9;
+#else
+ (CONST char *s, int nd0, int nd, unsigned long y9)
+#endif
+{
+ Bigint *b;
+ int i, k;
+ long x, y;
+
+ x = (nd + 8) / 9;
+ for (k = 0, y = 1; x > y; y <<= 1, k++) ;
+#ifdef Pack_32
+ b = Balloc(k);
+ b->x[0] = y9;
+ b->wds = 1;
+#else
+ b = Balloc(k+1);
+ b->x[0] = y9 & 0xffff;
+ b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+ i = 9;
+ if (9 < nd0) {
+ s += 9;
+ do
+ b = multadd(b, 10, *s++ - '0');
+ while (++i < nd0);
+ s++;
+ } else
+ s += 10;
+ for (; i < nd; i++)
+ b = multadd(b, 10, *s++ - '0');
+ return b;
+}
+
+ static int
+hi0bits
+#ifdef KR_headers
+ (x) register unsigned long x;
+#else
+ (register unsigned long x)
+#endif
+{
+ register int k = 0;
+
+ if (!(x & 0xffff0000)) {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000)) {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000)) {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000)) {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000)) {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+}
+
+ static int
+lo0bits
+#ifdef KR_headers
+ (y) unsigned long *y;
+#else
+ (unsigned long *y)
+#endif
+{
+ register int k;
+ register unsigned long x = *y;
+
+ if (x & 7) {
+ if (x & 1)
+ return 0;
+ if (x & 2) {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff)) {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff)) {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf)) {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3)) {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1)) {
+ k++;
+ x >>= 1;
+ if (!x & 1)
+ return 32;
+ }
+ *y = x;
+ return k;
+}
+
+ static Bigint *
+i2b
+#ifdef KR_headers
+ (i) int i;
+#else
+ (int i)
+#endif
+{
+ Bigint *b;
+
+ b = Balloc(1);
+ b->x[0] = i;
+ b->wds = 1;
+ return b;
+ }
+
+ static Bigint *
+mult
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ Bigint *c;
+ int k, wa, wb, wc;
+ unsigned long carry, y, z;
+ unsigned long *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+#ifdef Pack_32
+ unsigned long z2;
+#endif
+
+ if (a->wds < b->wds) {
+ c = a;
+ a = b;
+ b = c;
+ }
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds)
+ k++;
+ c = Balloc(k);
+ for (x = c->x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->x;
+ xae = xa + wa;
+ xb = b->x;
+ xbe = xb + wb;
+ xc0 = c->x;
+#ifdef Pack_32
+ for (; xb < xbe; xb++, xc0++) {
+ if ( (y = *xb & 0xffff) ) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+ carry = z >> 16;
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+ carry = z2 >> 16;
+ Storeinc(xc, z2, z);
+ } while (x < xae);
+ *xc = carry;
+ }
+ if ( (y = *xb >> 16) ) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ z2 = *xc;
+ do {
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+ carry = z >> 16;
+ Storeinc(xc, z, z2);
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+ carry = z2 >> 16;
+ } while (x < xae);
+ *xc = z2;
+ }
+ }
+#else
+ for (; xb < xbe; xc0++) {
+ if (y = *xb++) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * y + *xc + carry;
+ carry = z >> 16;
+ *xc++ = z & 0xffff;
+ } while (x < xae);
+ *xc = carry;
+ }
+ }
+#endif
+ for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+ c->wds = wc;
+ return c;
+}
+
+ static Bigint *p5s;
+
+ static Bigint *
+pow5mult
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ Bigint *b1, *p5, *p51;
+ int i;
+ static int p05[3] = { 5, 25, 125 };
+
+ if ( (i = k & 3) )
+ b = multadd(b, p05[i-1], 0);
+
+ if (!(k >>= 2))
+ return b;
+ if (!(p5 = p5s)) {
+ /* first time */
+ p5 = p5s = i2b(625);
+ p5->next = 0;
+ }
+ for (;;) {
+ if (k & 1) {
+ b1 = mult(b, p5);
+ Bfree(b);
+ b = b1;
+ }
+ if (!(k >>= 1))
+ break;
+ if (!(p51 = p5->next)) {
+ p51 = p5->next = mult(p5,p5);
+ p51->next = 0;
+ }
+ p5 = p51;
+ }
+ return b;
+}
+
+ static Bigint *
+lshift
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ int i, k1, n, n1;
+ Bigint *b1;
+ unsigned long *x, *x1, *xe, z;
+
+#ifdef Pack_32
+ n = k >> 5;
+#else
+ n = k >> 4;
+#endif
+ k1 = b->k;
+ n1 = n + b->wds + 1;
+ for (i = b->maxwds; n1 > i; i <<= 1)
+ k1++;
+ b1 = Balloc(k1);
+ x1 = b1->x;
+ for (i = 0; i < n; i++)
+ *x1++ = 0;
+ x = b->x;
+ xe = x + b->wds;
+#ifdef Pack_32
+ if (k &= 0x1f) {
+ k1 = 32 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ } while (x < xe);
+ if ( (*x1 = z) )
+ ++n1;
+ }
+#else
+ if (k &= 0xf) {
+ k1 = 16 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k & 0xffff | z;
+ z = *x++ >> k1;
+ } while (x < xe);
+ if (*x1 = z)
+ ++n1;
+ }
+#endif
+ else
+ do
+ *x1++ = *x++;
+ while (x < xe);
+ b1->wds = n1 - 1;
+ Bfree(b);
+ return b1;
+}
+
+ static int
+cmp
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ unsigned long *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->wds;
+ j = b->wds;
+#ifdef DEBUG
+ if (i > 1 && !a->x[i-1])
+ Bug("cmp called with a->x[a->wds-1] == 0");
+ if (j > 1 && !b->x[j-1])
+ Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->x;
+ xa = xa0 + j;
+ xb0 = b->x;
+ xb = xb0 + j;
+ for (;;) {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+}
+
+ static Bigint *
+diff
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ Bigint *c;
+ int i, wa, wb;
+ long borrow, y; /* We need signed shifts here. */
+ unsigned long *xa, *xae, *xb, *xbe, *xc;
+#ifdef Pack_32
+ long z;
+#endif
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Balloc(0);
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ } else
+ i = 0;
+ c = Balloc(a->k);
+ c->sign = i;
+ wa = a->wds;
+ xa = a->x;
+ xae = xa + wa;
+ wb = b->wds;
+ xb = b->x;
+ xbe = xb + wb;
+ xc = c->x;
+ borrow = 0;
+#ifdef Pack_32
+ do {
+ y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(xc, z, y);
+ } while (xb < xbe);
+ while (xa < xae) {
+ y = (*xa & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*xa++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(xc, z, y);
+ }
+#else
+ do {
+ y = *xa++ - *xb++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *xc++ = y & 0xffff;
+ } while (xb < xbe);
+ while (xa < xae) {
+ y = *xa++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *xc++ = y & 0xffff;
+ }
+#endif
+ while (!*--xc)
+ wa--;
+ c->wds = wa;
+ return c;
+}
+
+ static double
+ulp
+#ifdef KR_headers
+ (x) double x;
+#else
+ (double x)
+#endif
+{
+ register long L;
+ double a;
+
+ L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Sudden_Underflow
+ if (L > 0) {
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ word0(a) = L;
+ word1(a) = 0;
+#ifndef Sudden_Underflow
+ } else {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift) {
+ word0(a) = 0x80000 >> L;
+ word1(a) = 0;
+ } else {
+ word0(a) = 0;
+ L -= Exp_shift;
+ word1(a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+ }
+#endif
+ return a;
+}
+
+ static double
+b2d
+#ifdef KR_headers
+ (a, e) Bigint *a; int *e;
+#else
+ (Bigint *a, int *e)
+#endif
+{
+ unsigned long *xa, *xa0, w, y, z;
+ int k;
+ double d;
+#ifdef VAX
+ unsigned long d0, d1;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+ xa0 = a->x;
+ xa = xa0 + a->wds;
+ y = *--xa;
+#ifdef DEBUG
+ if (!y) Bug("zero y in b2d");
+#endif
+ k = hi0bits(y);
+ *e = 32 - k;
+#ifdef Pack_32
+ if (k < Ebits) {
+ d0 = Exp_1 | (y >> (Ebits - k));
+ w = xa > xa0 ? *--xa : 0;
+ d1 = (y << ((32-Ebits) + k)) | (w >> (Ebits - k));
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits) {
+ d0 = Exp_1 | (y << k) | (z >> (32 - k));
+ y = xa > xa0 ? *--xa : 0;
+ d1 = (z << k) | (y >> (32 - k));
+ } else {
+ d0 = Exp_1 | y;
+ d1 = z;
+ }
+#else
+ if (k < Ebits + 16) {
+ z = xa > xa0 ? *--xa : 0;
+ d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
+ w = xa > xa0 ? *--xa : 0;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ w = xa > xa0 ? *--xa : 0;
+ k -= Ebits + 16;
+ d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = w << k + 16 | y << k;
+#endif
+ ret_d:
+#ifdef VAX
+ word0(d) = d0 >> 16 | d0 << 16;
+ word1(d) = d1 >> 16 | d1 << 16;
+#else
+#undef d0
+#undef d1
+#endif
+ return d;
+}
+
+ static Bigint *
+d2b
+#ifdef KR_headers
+ (d, e, bits) double d; int *e, *bits;
+#else
+ (double d, int *e, int *bits)
+#endif
+{
+ Bigint *b;
+ int de, i, k;
+ unsigned long *x, y, z;
+#ifdef VAX
+ unsigned long d0, d1;
+ d0 = word0(d) >> 16 | word0(d) << 16;
+ d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+#ifdef Pack_32
+ b = Balloc(1);
+#else
+ b = Balloc(2);
+#endif
+ x = b->x;
+
+ z = d0 & Frac_mask;
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+ de = (int)(d0 >> Exp_shift);
+#ifndef IBM
+ z |= Exp_msk11;
+#endif
+#else
+ if ( (de = (int)(d0 >> Exp_shift)) )
+ z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+ if ( (y = d1) ) {
+ if ( (k = lo0bits(&y)) ) {
+ x[0] = y | (z << (32 - k));
+ z >>= k;
+ }
+ else
+ x[0] = y;
+ i = b->wds = (x[1] = z) ? 2 : 1;
+ } else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ x[0] = z;
+ i = b->wds = 1;
+ k += 32;
+ }
+#else
+ if (y = d1) {
+ if (k = lo0bits(&y))
+ if (k >= 16) {
+ x[0] = y | z << 32 - k & 0xffff;
+ x[1] = z >> k - 16 & 0xffff;
+ x[2] = z >> k;
+ i = 2;
+ } else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16 | z << 16 - k & 0xffff;
+ x[2] = z >> k & 0xffff;
+ x[3] = z >> k+16;
+ i = 3;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16;
+ x[2] = z & 0xffff;
+ x[3] = z >> 16;
+ i = 3;
+ }
+ } else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ if (k >= 16) {
+ x[0] = z;
+ i = 0;
+ } else {
+ x[0] = z & 0xffff;
+ x[1] = z >> 16;
+ i = 1;
+ }
+ k += 32;
+ }
+ while (!x[i])
+ --i;
+ b->wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+ if (de) {
+#endif
+#ifdef IBM
+ *e = (de - Bias - (P-1) << 2) + k;
+ *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+#else
+ *e = de - Bias - (P-1) + k;
+ *bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+ } else {
+ *e = de - Bias - (P-1) + 1 + k;
+#ifdef Pack_32
+ *bits = 32*i - hi0bits(x[i-1]);
+#else
+ *bits = (i+2)*16 - hi0bits(x[i]);
+#endif
+ }
+#endif
+ return b;
+}
+#undef d0
+#undef d1
+
+ static double
+ratio
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ double da, db;
+ int k, ka, kb;
+
+ da = b2d(a, &ka);
+ db = b2d(b, &kb);
+#ifdef Pack_32
+ k = ka - kb + 32*(a->wds - b->wds);
+#else
+ k = ka - kb + 16*(a->wds - b->wds);
+#endif
+#ifdef IBM
+ if (k > 0) {
+ word0(da) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ da *= 1 << k;
+ } else {
+ k = -k;
+ word0(db) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ db *= 1 << k;
+ }
+#else
+ if (k > 0)
+ word0(da) += k*Exp_msk1;
+ else {
+ k = -k;
+ word0(db) += k*Exp_msk1;
+ }
+#endif
+ return da / db;
+}
+
+ static double
+tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+#ifdef VAX
+ , 1e23, 1e24
+#endif
+ };
+
+ static double
+#ifdef IEEE_Arith
+bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
+#define n_bigtens 5
+#else
+#ifdef IBM
+bigtens[] = { 1e16, 1e32, 1e64 };
+static double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+bigtens[] = { 1e16, 1e32 };
+static double tinytens[] = { 1e-16, 1e-32 };
+#define n_bigtens 2
+#endif
+#endif
+
+ double
+strtod
+#ifdef KR_headers
+ (s00, se) CONST char *s00; char **se;
+#else
+ (CONST char *s00, char **se)
+#endif
+{
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
+ e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
+ CONST char *s, *s0, *s1;
+ double aadj, aadj1, adj, rv, rv0;
+ long L;
+ unsigned long y, z;
+ Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+ sign = nz0 = nz = 0;
+ rv = 0.;
+ for (s = s00;;s++) switch(*s) {
+ case '-':
+ sign = 1;
+ /* no break */
+ case '+':
+ if (*++s)
+ goto break2;
+ /* no break */
+ case 0:
+ s = s00;
+ goto ret;
+ default:
+ if (isspace((unsigned char)*s))
+ continue;
+ goto break2;
+ }
+ break2:
+ if (*s == '0') {
+ nz0 = 1;
+ while (*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ s0 = s;
+ y = z = 0;
+ for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < 16)
+ z = 10*z + c - '0';
+ nd0 = nd;
+ if (c == '.') {
+ c = *++s;
+ if (!nd) {
+ for (; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for (; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+ nz++;
+ if (c -= '0') {
+ nf += nz;
+ for (i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 1)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 1)
+ z = 10*z + c;
+ nz = 0;
+ }
+ }
+ }
+ dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ s = s00;
+ goto ret;
+ }
+ s00 = s;
+ esign = 0;
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while (c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ L = c - '0';
+ s1 = s;
+ while ((c = *++s) >= '0' && c <= '9')
+ L = 10*L + c - '0';
+ if (s - s1 > 8 || L > 19999)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 19999; /* safe for 16 bit ints */
+ else
+ e = (int)L;
+ if (esign)
+ e = -e;
+ } else
+ e = 0;
+ } else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0)
+ s = s00;
+ goto ret;
+ }
+ e1 = e -= nf;
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ rv = y;
+ if (k > 9)
+ rv = tens[k - 9] * rv + z;
+ if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+ && FLT_ROUNDS == 1
+#endif
+ ) {
+ if (!e)
+ goto ret;
+ if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+ goto ret;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+ e -= i;
+ rv *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ word0(rv) -= P*Exp_msk1;
+ /* rv = */ rounded_product(rv, tens[e]);
+ if ((word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto ovfl;
+ word0(rv) += P*Exp_msk1;
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+#endif
+ goto ret;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+ /* rv = */ rounded_quotient(rv, tens[-e]);
+ goto ret;
+ }
+#endif
+ }
+ e1 += nd - k;
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ if (e1 > 0) {
+ if ( (i = e1 & 15) )
+ rv *= tens[i];
+ if ( (e1 &= ~15) ) {
+ if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+ errno = ERANGE;
+#ifdef __STDC__
+ rv = HUGE_VAL;
+#else
+ /* Can't trust HUGE_VAL */
+#ifdef IEEE_Arith
+ word0(rv) = Exp_mask;
+ word1(rv) = 0;
+#else
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+#endif
+#endif
+ goto ret;
+ }
+ if (e1 >>= 4) {
+ for (j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= bigtens[j];
+ /* The last multiplication could overflow. */
+ word0(rv) -= P*Exp_msk1;
+ rv *= bigtens[j];
+ if ((z = word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+ goto ovfl;
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ }
+ else
+ word0(rv) += P*Exp_msk1;
+ }
+ }
+ } else if (e1 < 0) {
+ e1 = -e1;
+ if ( (i = e1 & 15) )
+ rv /= tens[i];
+ if ( (e1 &= ~15) ) {
+ e1 >>= 4;
+ for (j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= tinytens[j];
+ /* The last multiplication could underflow. */
+ rv0 = rv;
+ rv *= tinytens[j];
+ if (!rv) {
+ rv = 2.*rv0;
+ rv *= tinytens[j];
+ if (!rv) {
+ undfl:
+ rv = 0.;
+ errno = ERANGE;
+ goto ret;
+ }
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ /* The refinement below will clean
+ * this approximation up.
+ */
+ }
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b(s0, nd0, nd, y);
+
+ for (;;) {
+ bd = Balloc(bd0->k);
+ Bcopy(bd, bd0);
+ bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
+ bs = i2b(1);
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ } else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+#ifdef Sudden_Underflow
+#ifdef IBM
+ j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+ j = P + 1 - bbbits;
+#endif
+#else
+ i = bbe + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j = bbe + (P-Emin);
+ else
+ j = P + 1 - bbbits;
+#endif
+ bb2 += j;
+ bd2 += j;
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0) {
+ bs = pow5mult(bs, bb5);
+ bb1 = mult(bs, bb);
+ Bfree(bb);
+ bb = bb1;
+ }
+ if (bb2 > 0)
+ bb = lshift(bb, bb2);
+ if (bd5 > 0)
+ bd = pow5mult(bd, bd5);
+ if (bd2 > 0)
+ bd = lshift(bd, bd2);
+ if (bs2 > 0)
+ bs = lshift(bs, bs2);
+ delta = diff(bb, bd);
+ dsign = delta->sign;
+ delta->sign = 0;
+ i = cmp(delta, bs);
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask)
+ break;
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if ((word0(rv) & Bndry_mask1) == Bndry_mask1
+ && word1(rv) == 0xffffffff) {
+ /*boundary case -- increment exponent*/
+ word0(rv) = (word0(rv) & Exp_mask)
+ + Exp_msk1
+#ifdef IBM
+ | Exp_msk1 >> 4
+#endif
+ ;
+ word1(rv) = 0;
+ break;
+ }
+ } else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+ drop_down:
+ /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow
+ L = word0(rv) & Exp_mask;
+#ifdef IBM
+ if (L < Exp_msk1)
+#else
+ if (L <= Exp_msk1)
+#endif
+ goto undfl;
+ L -= Exp_msk1;
+#else
+ L = (word0(rv) & Exp_mask) - Exp_msk1;
+#endif
+ word0(rv) = L | Bndry_mask1;
+ word1(rv) = 0xffffffff;
+#ifdef IBM
+ goto cont;
+#else
+ break;
+#endif
+ }
+#ifndef ROUND_BIASED
+ if (!(word1(rv) & LSB))
+ break;
+#endif
+ if (dsign)
+ rv += ulp(rv);
+#ifndef ROUND_BIASED
+ else {
+ rv -= ulp(rv);
+#ifndef Sudden_Underflow
+ if (!rv)
+ goto undfl;
+#endif
+ }
+#endif
+ break;
+ }
+ if ((aadj = ratio(delta, bs)) <= 2.) {
+ if (dsign)
+ aadj = aadj1 = 1.;
+ else if (word1(rv) || word0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+ if (word1(rv) == Tiny1 && !word0(rv))
+ goto undfl;
+#endif
+ aadj = 1.;
+ aadj1 = -1.;
+ } else {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2./FLT_RADIX)
+ aadj = 1./FLT_RADIX;
+ else
+ aadj *= 0.5;
+ aadj1 = -aadj;
+ }
+ } else {
+ aadj *= 0.5;
+ aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+ switch(FLT_ROUNDS) {
+ case 2: /* towards +infinity */
+ aadj1 -= 0.5;
+ break;
+ case 0: /* towards 0 */
+ case 3: /* towards -infinity */
+ aadj1 += 0.5;
+ }
+#else
+ if (FLT_ROUNDS == 0)
+ aadj1 += 0.5;
+#endif
+ }
+ y = word0(rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+ rv0 = rv;
+ word0(rv) -= P*Exp_msk1;
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ if ((word0(rv) & Exp_mask) >=
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+ if (word0(rv0) == Big0 && word1(rv0) == Big1)
+ goto ovfl;
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ goto cont;
+ } else
+ word0(rv) += P*Exp_msk1;
+ } else {
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+ rv0 = rv;
+ word0(rv) += P*Exp_msk1;
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#ifdef IBM
+ if ((word0(rv) & Exp_mask) < P*Exp_msk1)
+#else
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+ {
+ if (word0(rv0) == Tiny0
+ && word1(rv0) == Tiny1)
+ goto undfl;
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ goto cont;
+ } else
+ word0(rv) -= P*Exp_msk1;
+ } else {
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ }
+#else
+ /* Compute adj so that the IEEE rounding rules will
+ * correctly round rv + adj in some half-way cases.
+ * If rv * ulp(rv) is denormalized (i.e.,
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+ * trouble from bits lost to denormalization;
+ * example: 1.2e-307 .
+ */
+ if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
+ aadj1 = (double)(int)(aadj + 0.5);
+ if (!dsign)
+ aadj1 = -aadj1;
+ }
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#endif
+ }
+ z = word0(rv) & Exp_mask;
+ if (y == z) {
+ /* Can we stop now? */
+ L = aadj;
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ } else if (aadj < .4999999/FLT_RADIX)
+ break;
+ }
+ cont:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(delta);
+ }
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ ret:
+ if (se)
+ *se = (char *)s;
+ return sign ? -rv : rv;
+}
+
+ static int
+quorem
+#ifdef KR_headers
+ (b, S) Bigint *b, *S;
+#else
+ (Bigint *b, Bigint *S)
+#endif
+{
+ int n;
+ long borrow, y;
+ unsigned long carry, q, ys;
+ unsigned long *bx, *bxe, *sx, *sxe;
+#ifdef Pack_32
+ long z;
+ unsigned long si, zs;
+#endif
+
+ n = S->wds;
+#ifdef DEBUG
+ /*debug*/ if (b->wds > n)
+ /*debug*/ Bug("oversize b in quorem");
+#endif
+ if (b->wds < n)
+ return 0;
+ sx = S->x;
+ sxe = sx + --n;
+ bx = b->x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug("oversized quotient in quorem");
+#endif
+ if (q) {
+ borrow = 0;
+ carry = 0;
+ do {
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) * q + carry;
+ zs = (si >> 16) * q + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ * q + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ } while (sx <= sxe);
+ if (!*bxe) {
+ bx = b->x;
+ while (--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ if (cmp(b, S) >= 0) {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->x;
+ sx = S->x;
+ do {
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) + carry;
+ zs = (si >> 16) + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ } while (sx <= sxe);
+ bx = b->x;
+ bxe = bx + n;
+ if (!*bxe) {
+ while (--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ return q;
+}
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the long
+ * calculation.
+ */
+
+char *
+__dtoa
+#ifdef KR_headers
+ (d, mode, ndigits, decpt, sign, rve)
+ double d; int mode, ndigits, *decpt, *sign; char **rve;
+#else
+ (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
+#endif
+{
+ /* Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4-9 should give the same return values as 2-3, i.e.,
+ 4 <= mode <= 9 ==> same return as mode
+ 2 + (mode & 1). These modes are mainly for
+ debugging; often they run slower but sometimes
+ faster than modes 2-3.
+ 4,5,8,9 ==> left-to-right digit generation.
+ 6-9 ==> don't try fast floating-point estimate
+ (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
+ j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+ spec_case, try_quick;
+ long L;
+#ifndef Sudden_Underflow
+ int denorm;
+ unsigned long x;
+#endif
+ Bigint *b, *b1, *delta, *mlo, *mhi, *S;
+ double d2, ds, eps;
+ char *s, *s0;
+ static Bigint *result;
+ static int result_k;
+
+ if (result) {
+ result->k = result_k;
+ result->maxwds = 1 << result_k;
+ Bfree(result);
+ result = 0;
+ }
+
+ if (word0(d) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ word0(d) &= ~Sign_bit; /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((word0(d) & Exp_mask) == Exp_mask)
+#else
+ if (word0(d) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+ s =
+#ifdef IEEE_Arith
+ !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" :
+#endif
+ "NaN";
+ if (rve)
+ *rve =
+#ifdef IEEE_Arith
+ s[3] ? s + 8 :
+#endif
+ s + 3;
+ return s;
+ }
+#endif
+#ifdef IBM
+ d += 0; /* normalize */
+#endif
+ if (!d) {
+ *decpt = 1;
+ s = "0";
+ if (rve)
+ *rve = s + 1;
+ return s;
+ }
+
+ b = d2b(d, &be, &bbits);
+#ifdef Sudden_Underflow
+ i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#else
+ if ( (i = (int)((word0(d) >> Exp_shift1) & (Exp_mask>>Exp_shift1))) ) {
+#endif
+ d2 = d;
+ word0(d2) &= Frac_mask1;
+ word0(d2) |= Exp_11;
+#ifdef IBM
+ if ( (j = 11 - hi0bits(word0(d2) & Frac_mask)) )
+ d2 /= 1 << j;
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ } else {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? ((word0(d) << (64 - i)) | (word1(d) >> (i - 32)))
+ : (word1(d) << (32 - i));
+ d2 = x;
+ word0(d2) -= 31*Exp_msk1; /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+ ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (d < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ } else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ } else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+ try_quick = 1;
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch(mode) {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ j = sizeof(unsigned long);
+ for (result_k = 0; sizeof(Bigint) - sizeof(unsigned long) + j < i;
+ j <<= 1) result_k++;
+ result = Balloc(result_k);
+ s = s0 = (char *)result;
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ d2 = d;
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ d /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for (; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ d /= ds;
+ } else if ( (j1 = -k) ) {
+ d *= tens[j1 & 0xf];
+ for (j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ d *= bigtens[i];
+ }
+ }
+ if (k_check && d < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ d *= 10.;
+ ieps++;
+ }
+ eps = ieps*d + 7.;
+ word0(eps) -= (P-1)*Exp_msk1;
+ if (ilim == 0) {
+ S = mhi = 0;
+ d -= 5.;
+ if (d > eps)
+ goto one_digit;
+ if (d < -eps)
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ eps = 0.5/tens[ilim-1] - eps;
+ for (i = 0;;) {
+ L = d;
+ d -= L;
+ *s++ = '0' + (int)L;
+ if (d < eps)
+ goto ret1;
+ if (1. - d < eps)
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ eps *= 10.;
+ d *= 10.;
+ }
+ } else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ eps *= tens[ilim-1];
+ for (i = 1;; i++, d *= 10.) {
+ L = d;
+ d -= L;
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ if (d > 0.5 + eps)
+ goto bump_up;
+ else if (d < 0.5 - eps) {
+ while (*--s == '0');
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ d = d2;
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = 0;
+ if (ilim < 0 || d <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for (i = 1;; i++) {
+ L = d / ds;
+ d -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (d < 0) {
+ L--;
+ d += ds;
+ }
+#endif
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ d += d;
+ if (d > ds || (d == ds && L & 1)) {
+ bump_up:
+ while (*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ if (!(d *= 10.))
+ break;
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ if (leftright) {
+ if (mode < 2) {
+ i =
+#ifndef Sudden_Underflow
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+ 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ } else {
+ j = ilim - 1;
+ if (m5 >= j)
+ m5 -= j;
+ else {
+ s5 += j -= m5;
+ b5 += j;
+ m5 = 0;
+ }
+ if ((i = ilim) < 0) {
+ m2 -= i;
+ i = 0;
+ }
+ }
+ b2 += i;
+ s2 += i;
+ mhi = i2b(1);
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ mhi = pow5mult(mhi, m5);
+ b1 = mult(mhi, b);
+ Bfree(b);
+ b = b1;
+ }
+ if ( (j = b5 - m5) )
+ b = pow5mult(b, j);
+ } else
+ b = pow5mult(b, b5);
+ }
+ S = i2b(1);
+ if (s5 > 0)
+ S = pow5mult(S, s5);
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ if (mode < 2) {
+ if (!word1(d) && !(word0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+ && word0(d) & Exp_mask
+#endif
+ ) {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ } else
+ spec_case = 0;
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+#ifdef Pack_32
+ if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) )
+ i = 32 - i;
+#else
+ if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) )
+ i = 16 - i;
+#endif
+ if (i > 4) {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ } else if (i < 4) {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0)
+ b = lshift(b, b2);
+ if (s2 > 0)
+ S = lshift(S, s2);
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0); /* we botched the k estimate */
+ if (leftright)
+ mhi = multadd(mhi, 10, 0);
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && mode > 2) {
+ if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0)
+ mhi = lshift(mhi, m2);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = Balloc(mhi->k);
+ Bcopy(mhi, mlo);
+ mhi = lshift(mhi, Log2P);
+ }
+
+ for (i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ delta = diff(S, mhi);
+ j1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(delta);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && !mode && !(word1(d) & 1)) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || (j == 0 && !mode
+#ifndef ROUND_BIASED
+ && !(word1(d) & 1)
+#endif
+ )) {
+ if (j1 > 0) {
+ b = lshift(b, 1);
+ j1 = cmp(b, S);
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
+ && dig++ == '9')
+ goto round_9_up;
+ }
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0) {
+ if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = dig + 1;
+ goto ret;
+ }
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (mlo == mhi)
+ mlo = mhi = multadd(mhi, 10, 0);
+ else {
+ mlo = multadd(mlo, 10, 0);
+ mhi = multadd(mhi, 10, 0);
+ }
+ }
+ } else
+ for (i = 1;; i++) {
+ *s++ = dig = quorem(b,S) + '0';
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0);
+ }
+
+ /* Round off last digit */
+
+ b = lshift(b, 1);
+ j = cmp(b, S);
+ if (j > 0 || (j == 0 && dig & 1)) {
+ roundoff:
+ while (*--s == '9')
+ if (s == s0) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ } else {
+ while (*--s == '0');
+ s++;
+ }
+ ret:
+ Bfree(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ ret1:
+ Bfree(b);
+ if (s == s0) { /* don't return empty string */
+ *s++ = '0';
+ k = 0;
+ }
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+ }
+#ifdef __cplusplus
+}
+#endif
diff --git a/lib/libc/stdlib/strtol.3 b/lib/libc/stdlib/strtol.3
new file mode 100644
index 0000000..898f657
--- /dev/null
+++ b/lib/libc/stdlib/strtol.3
@@ -0,0 +1,169 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strtol.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRTOL 3
+.Os
+.Sh NAME
+.Nm strtol, strtoq
+.Nd convert string value to a long or quad_t integer
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Fd #include <limits.h>
+.Ft long
+.Fn strtol "const char *nptr" "char **endptr" "int base"
+
+.Fd #include <sys/types.h>
+.Fd #include <stdlib.h>
+.Fd #include <limits.h>
+.Ft quad_t
+.Fn strtoq "const char *nptr" "char **endptr" "int base"
+.Sh DESCRIPTION
+The
+.Fn strtol
+function
+converts the string in
+.Fa nptr
+to a
+.Em long
+value.
+The
+.Fn strtoq
+function
+converts the string in
+.Fa nptr
+to a
+.Em quad_t
+value.
+The conversion is done according to the given
+.Fa base ,
+which must be between 2 and 36 inclusive,
+or be the special value 0.
+.Pp
+The string may begin with an arbitrary amount of white space
+(as determined by
+.Xr isspace 3 )
+followed by a single optional
+.Ql +
+or
+.Ql -
+sign.
+If
+.Fa base
+is zero or 16,
+the string may then include a
+.Ql 0x
+prefix,
+and the number will be read in base 16; otherwise, a zero
+.Fa base
+is taken as 10 (decimal) unless the next character is
+.Ql 0 ,
+in which case it is taken as 8 (octal).
+.Pp
+The remainder of the string is converted to a
+.Em long
+value in the obvious manner,
+stopping at the first character which is not a valid digit
+in the given base.
+(In bases above 10, the letter
+.Ql A
+in either upper or lower case
+represents 10,
+.Ql B
+represents 11, and so forth, with
+.Ql Z
+representing 35.)
+.Pp
+If
+.Fa endptr
+is non nil,
+.Fn strtol
+stores the address of the first invalid character in
+.Fa *endptr .
+If there were no digits at all, however,
+.Fn strtol
+stores the original value of
+.Fa nptr
+in
+.Fa *endptr .
+(Thus, if
+.Fa *nptr
+is not
+.Ql \e0
+but
+.Fa **endptr
+is
+.Ql \e0
+on return, the entire string was valid.)
+.Sh RETURN VALUES
+The
+.Fn strtol
+function
+returns the result of the conversion,
+unless the value would underflow or overflow.
+If an underflow occurs,
+.Fn strtol
+returns
+.Dv LONG_MIN .
+If an overflow occurs,
+.Fn strtol
+returns
+.Dv LONG_MAX .
+In both cases,
+.Va errno
+is set to
+.Er ERANGE .
+.Sh ERRORS
+.Bl -tag -width [ERANGE]
+.It Bq Er ERANGE
+The given string was out of range; the value converted has been clamped.
+.El
+.Sh SEE ALSO
+.Xr atof 3 ,
+.Xr atoi 3 ,
+.Xr atol 3 ,
+.Xr strtod 3 ,
+.Xr strtoul 3
+.Sh STANDARDS
+The
+.Fn strtol
+function
+conforms to
+.St -ansiC .
+.Sh BUGS
+Ignores the current locale.
diff --git a/lib/libc/stdlib/strtol.c b/lib/libc/stdlib/strtol.c
new file mode 100644
index 0000000..18e3972
--- /dev/null
+++ b/lib/libc/stdlib/strtol.c
@@ -0,0 +1,131 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+
+
+/*
+ * Convert a string to a long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+long
+strtol(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ register int base;
+{
+ register const char *s = nptr;
+ register unsigned long acc;
+ register unsigned char c;
+ register unsigned long cutoff;
+ register int neg = 0, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for longs is
+ * [-2147483648..2147483647] and the input base is 10,
+ * cutoff will be set to 214748364 and cutlim to either
+ * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+ * a value > 214748364, or equal but the next digit is > 7 (or 8),
+ * the number is too big, and we will return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+ cutlim = cutoff % (unsigned long)base;
+ cutoff /= (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LONG_MIN : LONG_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/lib/libc/stdlib/strtoll.c b/lib/libc/stdlib/strtoll.c
new file mode 100644
index 0000000..f84e030
--- /dev/null
+++ b/lib/libc/stdlib/strtoll.c
@@ -0,0 +1,138 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <limits.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to a quad integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+quad_t
+strtoq(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ register int base;
+{
+ register const char *s;
+ register u_quad_t acc;
+ register unsigned char c;
+ register u_quad_t qbase, cutoff;
+ register int neg, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for quads is
+ * [-9223372036854775808..9223372036854775807] and the input base
+ * is 10, cutoff will be set to 922337203685477580 and cutlim to
+ * either 7 (neg==0) or 8 (neg==1), meaning that if we have
+ * accumulated a value > 922337203685477580, or equal but the
+ * next digit is > 7 (or 8), the number is too big, and we will
+ * return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ qbase = (unsigned)base;
+ cutoff = neg ? (u_quad_t)-(QUAD_MIN + QUAD_MAX) + QUAD_MAX : QUAD_MAX;
+ cutlim = cutoff % qbase;
+ cutoff /= qbase;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= qbase;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? QUAD_MIN : QUAD_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/lib/libc/stdlib/strtoq.c b/lib/libc/stdlib/strtoq.c
new file mode 100644
index 0000000..f84e030
--- /dev/null
+++ b/lib/libc/stdlib/strtoq.c
@@ -0,0 +1,138 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <limits.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to a quad integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+quad_t
+strtoq(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ register int base;
+{
+ register const char *s;
+ register u_quad_t acc;
+ register unsigned char c;
+ register u_quad_t qbase, cutoff;
+ register int neg, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for quads is
+ * [-9223372036854775808..9223372036854775807] and the input base
+ * is 10, cutoff will be set to 922337203685477580 and cutlim to
+ * either 7 (neg==0) or 8 (neg==1), meaning that if we have
+ * accumulated a value > 922337203685477580, or equal but the
+ * next digit is > 7 (or 8), the number is too big, and we will
+ * return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ qbase = (unsigned)base;
+ cutoff = neg ? (u_quad_t)-(QUAD_MIN + QUAD_MAX) + QUAD_MAX : QUAD_MAX;
+ cutlim = cutoff % qbase;
+ cutoff /= qbase;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= qbase;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? QUAD_MIN : QUAD_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/lib/libc/stdlib/strtoul.3 b/lib/libc/stdlib/strtoul.3
new file mode 100644
index 0000000..a877ce2
--- /dev/null
+++ b/lib/libc/stdlib/strtoul.3
@@ -0,0 +1,164 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strtoul.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRTOUL 3
+.Os
+.Sh NAME
+.Nm strtoul, strtouq
+.Nd convert a string to an unsigned long or uquad_t integer
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Fd #include <limits.h>
+.Ft unsigned long
+.Fn strtoul "const char *nptr" "char **endptr" "int base"
+
+.Fd #include <sys/types.h>
+.Fd #include <stdlib.h>
+.Fd #include <limits.h>
+.Ft u_quad_t
+.Fn strtouq "const char *nptr" "char **endptr" "int base"
+.Sh DESCRIPTION
+The
+.Fn strtoul
+function
+converts the string in
+.Fa nptr
+to an
+.Em unsigned long
+value.
+The
+.Fn strtouq
+function
+converts the string in
+.Fa nptr
+to a
+.Em u_quad_t
+value.
+The conversion is done according to the given
+.Fa base ,
+which must be between 2 and 36 inclusive,
+or be the special value 0.
+.Pp
+The string may begin with an arbitrary amount of white space
+(as determined by
+.Xr isspace 3 )
+followed by a single optional
+.Ql +
+or
+.Ql -
+sign.
+If
+.Fa base
+is zero or 16,
+the string may then include a
+.Ql 0x
+prefix,
+and the number will be read in base 16; otherwise, a zero
+.Fa base
+is taken as 10 (decimal) unless the next character is
+.Ql 0 ,
+in which case it is taken as 8 (octal).
+.Pp
+The remainder of the string is converted to an
+.Em unsigned long
+value in the obvious manner,
+stopping at the end of the string
+or at the first character that does not produce a valid digit
+in the given base.
+(In bases above 10, the letter
+.Ql A
+in either upper or lower case
+represents 10,
+.Ql B
+represents 11, and so forth, with
+.Ql Z
+representing 35.)
+.Pp
+If
+.Fa endptr
+is non nil,
+.Fn strtoul
+stores the address of the first invalid character in
+.Fa *endptr .
+If there were no digits at all, however,
+.Fn strtoul
+stores the original value of
+.Fa nptr
+in
+.Fa *endptr .
+(Thus, if
+.Fa *nptr
+is not
+.Ql \e0
+but
+.Fa **endptr
+is
+.Ql \e0
+on return, the entire string was valid.)
+.Sh RETURN VALUES
+The
+.Fn strtoul
+function
+returns either the result of the conversion
+or, if there was a leading minus sign,
+the negation of the result of the conversion,
+unless the original (non-negated) value would overflow;
+in the latter case,
+.Fn strtoul
+returns
+.Dv ULONG_MAX
+and sets the global variable
+.Va errno
+to
+.Er ERANGE .
+.Sh ERRORS
+.Bl -tag -width [ERANGE]
+.It Bq Er ERANGE
+The given string was out of range; the value converted has been clamped.
+.El
+.Sh SEE ALSO
+.Xr strtol 3
+.Sh STANDARDS
+The
+.Fn strtoul
+function
+conforms to
+.St -ansiC .
+.Sh BUGS
+Ignores the current locale.
diff --git a/lib/libc/stdlib/strtoul.c b/lib/libc/stdlib/strtoul.c
new file mode 100644
index 0000000..304150a
--- /dev/null
+++ b/lib/libc/stdlib/strtoul.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long
+strtoul(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ register int base;
+{
+ register const char *s = nptr;
+ register unsigned long acc;
+ register unsigned char c;
+ register unsigned long cutoff;
+ register int neg = 0, any, cutlim;
+
+ /*
+ * See strtol for comments as to the logic used.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
+ cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = ULONG_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/lib/libc/stdlib/strtoull.c b/lib/libc/stdlib/strtoull.c
new file mode 100644
index 0000000..7656a3c
--- /dev/null
+++ b/lib/libc/stdlib/strtoull.c
@@ -0,0 +1,116 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <limits.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to an unsigned quad integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+u_quad_t
+strtouq(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ register int base;
+{
+ register const char *s = nptr;
+ register u_quad_t acc;
+ register unsigned char c;
+ register u_quad_t qbase, cutoff;
+ register int neg, any, cutlim;
+
+ /*
+ * See strtoq for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ qbase = (unsigned)base;
+ cutoff = (u_quad_t)UQUAD_MAX / qbase;
+ cutlim = (u_quad_t)UQUAD_MAX % qbase;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= qbase;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = UQUAD_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/lib/libc/stdlib/strtouq.c b/lib/libc/stdlib/strtouq.c
new file mode 100644
index 0000000..7656a3c
--- /dev/null
+++ b/lib/libc/stdlib/strtouq.c
@@ -0,0 +1,116 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <limits.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to an unsigned quad integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+u_quad_t
+strtouq(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ register int base;
+{
+ register const char *s = nptr;
+ register u_quad_t acc;
+ register unsigned char c;
+ register u_quad_t qbase, cutoff;
+ register int neg, any, cutlim;
+
+ /*
+ * See strtoq for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ qbase = (unsigned)base;
+ cutoff = (u_quad_t)UQUAD_MAX / qbase;
+ cutlim = (u_quad_t)UQUAD_MAX % qbase;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= qbase;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = UQUAD_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/lib/libc/stdlib/system.3 b/lib/libc/stdlib/system.3
new file mode 100644
index 0000000..218a459
--- /dev/null
+++ b/lib/libc/stdlib/system.3
@@ -0,0 +1,101 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)system.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SYSTEM 3
+.Os
+.Sh NAME
+.Nm system
+.Nd pass a command to the shell
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft int
+.Fn system "const char *string"
+.Sh DESCRIPTION
+The
+.Fn system
+function
+hands the argument
+.Fa string
+to the command interpreter
+.Xr sh 1 .
+The calling process waits for the shell
+to finish executing the command,
+ignoring
+.Dv SIGINT
+and
+.Dv SIGQUIT ,
+and blocking
+.Dv SIGCHLD .
+.Pp
+If
+.Fa string
+is a
+.Dv NULL
+pointer,
+.Fn system
+will return non-zero if the command interpreter
+.Xr sh 1
+is available, and zero if it is not.
+.Pp
+The
+.Fn system
+function
+returns the exit status of the shell as returned by
+.Xr waitpid 2 ,
+or \-1 if an error occurred when invoking
+.Xr fork 2
+or
+.Xr waitpid 2 .
+A return value of 127 means the execution of the shell
+failed.
+.Sh SEE ALSO
+.Xr sh 1 ,
+.Xr execve 2 ,
+.Xr fork 2 ,
+.Xr waitpid 2 ,
+.Xr popen 3
+.Sh STANDARDS
+The
+.Fn system
+function
+conforms to
+.St -ansiC .
+and is expected to be
+.St -p1003.2
+compatible.
diff --git a/lib/libc/stdlib/system.c b/lib/libc/stdlib/system.c
new file mode 100644
index 0000000..00db7d6
--- /dev/null
+++ b/lib/libc/stdlib/system.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)system.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <paths.h>
+#include <errno.h>
+
+int system(command)
+ const char *command;
+{
+ pid_t pid;
+ int pstat;
+ struct sigaction ign, intact, quitact;
+ sigset_t newsigblock, oldsigblock;
+
+ if (!command) /* just checking... */
+ return(1);
+
+ /*
+ * Ignore SIGINT and SIGQUIT, block SIGCHLD. Remember to save
+ * existing signal dispositions.
+ */
+ ign.sa_handler = SIG_IGN;
+ (void)sigemptyset(&ign.sa_mask);
+ ign.sa_flags = 0;
+ (void)sigaction(SIGINT, &ign, &intact);
+ (void)sigaction(SIGQUIT, &ign, &quitact);
+ (void)sigemptyset(&newsigblock);
+ (void)sigaddset(&newsigblock, SIGCHLD);
+ (void)sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
+ switch(pid = fork()) {
+ case -1: /* error */
+ break;
+ case 0: /* child */
+ /*
+ * Restore original signal dispositions and exec the command.
+ */
+ (void)sigaction(SIGINT, &intact, NULL);
+ (void)sigaction(SIGQUIT, &quitact, NULL);
+ (void)sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
+ execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL);
+ _exit(127);
+ default: /* parent */
+ do {
+ pid = waitpid(pid, &pstat, 0);
+ } while (pid == -1 && errno == EINTR);
+ break;
+ }
+ (void)sigaction(SIGINT, &intact, NULL);
+ (void)sigaction(SIGQUIT, &quitact, NULL);
+ (void)sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
+ return(pid == -1 ? -1 : pstat);
+}
diff --git a/lib/libc/stdtime/Makefile.inc b/lib/libc/stdtime/Makefile.inc
new file mode 100644
index 0000000..39daaa6
--- /dev/null
+++ b/lib/libc/stdtime/Makefile.inc
@@ -0,0 +1,15 @@
+# Makefile.inc,v 1.2 1994/09/13 21:26:01 wollman Exp
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libc/stdtime
+
+SRCS+= asctime.c difftime.c localtime.c strftime.c strptime.c timelocal.c
+
+.if ${LIB} == "c"
+MAN3+= ctime.3 strftime.3 strptime.3 time2posix.3
+MAN5+= tzfile.5
+
+MLINKS+=ctime.3 asctime.3 ctime.3 difftime.3 ctime.3 gmtime.3 \
+ ctime.3 localtime.3 ctime.3 mktime.3 ctime.3 timegm.3
+MLINKS+=time2posix.3 posix2time.3
+.endif
diff --git a/lib/libc/stdtime/asctime.c b/lib/libc/stdtime/asctime.c
new file mode 100644
index 0000000..832f185
--- /dev/null
+++ b/lib/libc/stdtime/asctime.c
@@ -0,0 +1,70 @@
+/*
+** This file is in the public domain, so clarified as of
+** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
+*/
+
+#ifndef lint
+#ifndef NOID
+static char elsieid[] = "@(#)asctime.c 7.7";
+#endif /* !defined NOID */
+#endif /* !defined lint */
+
+/*LINTLIBRARY*/
+
+#include "private.h"
+#include "tzfile.h"
+
+/*
+** A la X3J11, with core dump avoidance.
+*/
+
+
+char *
+asctime(timeptr)
+const struct tm * timeptr;
+{
+ static char result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) +
+ 3 + 2 + 1 + 1];
+ return(asctime_r(timeptr, result));
+}
+
+char *
+asctime_r(timeptr, result)
+const struct tm * timeptr;
+char *result;
+{
+ static const char wday_name[][3] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+ static const char mon_name[][3] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+ /*
+ ** Big enough for something such as
+ ** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
+ ** (two three-character abbreviations, five strings denoting integers,
+ ** three explicit spaces, two explicit colons, a newline,
+ ** and a trailing ASCII nul).
+ */
+ register const char * wn;
+ register const char * mn;
+
+ if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
+ wn = "???";
+ else wn = wday_name[timeptr->tm_wday];
+ if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
+ mn = "???";
+ else mn = mon_name[timeptr->tm_mon];
+ /*
+ ** The X3J11-suggested format is
+ ** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n"
+ ** Since the .2 in 02.2d is ignored, we drop it.
+ */
+ (void) sprintf(result, "%.3s %.3s%3d %02d:%02d:%02d %d\n",
+ wn, mn,
+ timeptr->tm_mday, timeptr->tm_hour,
+ timeptr->tm_min, timeptr->tm_sec,
+ TM_YEAR_BASE + timeptr->tm_year);
+ return result;
+}
diff --git a/lib/libc/stdtime/ctime.3 b/lib/libc/stdtime/ctime.3
new file mode 100644
index 0000000..ae5c6a1
--- /dev/null
+++ b/lib/libc/stdtime/ctime.3
@@ -0,0 +1,349 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Arthur Olson.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)ctime.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd January 2, 1999
+.Dt CTIME 3
+.Os BSD 4.3
+.Sh NAME
+.Nm asctime ,
+.Nm asctime_r ,
+.Nm ctime ,
+.Nm ctime_r ,
+.Nm difftime ,
+.Nm gmtime ,
+.Nm gmtime_r ,
+.Nm localtime ,
+.Nm localtime_r ,
+.Nm mktime ,
+.Nm timegm
+.Nd transform binary date and time values
+.Sh SYNOPSIS
+.Fd #include <time.h>
+.Vt extern char *tzname[2];
+.Ft char *
+.Fn ctime "const time_t *clock"
+.Ft double
+.Fn difftime "time_t time1" "time_t time0"
+.Ft char *
+.Fn asctime "const struct tm *tm"
+.Ft struct tm *
+.Fn localtime "const time_t *clock"
+.Ft struct tm *
+.Fn gmtime "const time_t *clock"
+.Ft time_t
+.Fn mktime "struct tm *tm"
+.Ft time_t
+.Fn timegm "struct tm *tm"
+.Ft char *
+.Fn ctime_r "const time_t *clock" "char *buf"
+.Ft struct tm *
+.Fn localtime_r "const time_t *clock" "struct tm *result"
+.Ft struct tm *
+.Fn gmtime_r "const time_t *clock" "struct tm *result"
+.Ft char *
+.Fn asctime_r "const struct tm *tm" "char *buf"
+.Sh DESCRIPTION
+The functions
+.Fn ctime ,
+.Fn gmtime
+and
+.Fn localtime
+all take as an argument a time value representing the time in seconds since
+the Epoch (00:00:00
+.Tn UTC ,
+January 1, 1970; see
+.Xr time 3 ) .
+.Pp
+The function
+.Fn localtime
+converts the time value pointed at by
+.Fa clock ,
+and returns a pointer to a
+.Dq Fa struct tm
+(described below) which contains
+the broken-out time information for the value after adjusting for the current
+time zone (and any other factors such as Daylight Saving Time).
+Time zone adjustments are performed as specified by the
+.Ev TZ
+environment variable (see
+.Xr tzset 3 ) .
+The function
+.Fn localtime
+uses
+.Xr tzset 3
+to initialize time conversion information if
+.Xr tzset 3
+has not already been called by the process.
+.Pp
+After filling in the tm structure,
+.Fn localtime
+sets the
+.Fa tm_isdst Ns 'th
+element of
+.Fa tzname
+to a pointer to an
+.Tn ASCII
+string that's the time zone abbreviation to be
+used with
+.Fn localtime Ns 's
+return value.
+.Pp
+The function
+.Fn gmtime
+similarly converts the time value, but without any time zone adjustment,
+and returns a pointer to a tm structure (described below).
+.Pp
+The
+.Fn ctime
+function
+adjusts the time value for the current time zone in the same manner as
+.Fn localtime ,
+and returns a pointer to a 26-character string of the form:
+.Bd -literal -offset indent
+Thu Nov 24 18:22:48 1986\en\e0
+.Ed
+.Pp
+All the fields have constant width.
+.Pp
+.Fn ctime_r
+provides the same functionality as
+.Fn ctime
+except the caller must provide the output buffer
+.Fa buf
+to store the result, which must be at least 26 characters long.
+.Fn localtime_r
+and
+.Fn gmtime_r
+provide the same functionality as
+.Fn localtime
+and
+.Fn gmtime
+respectively, except the caller must provide the output buffer
+.Fa result .
+.Pp
+The
+.Fn asctime
+function
+converts the broken down time in the structure
+.Fa tm
+pointed at by
+.Fa *tm
+to the form
+shown in the example above.
+.Pp
+.Fn asctime_r
+provides the same functionality as
+.Fn asctime
+except the caller provide the output buffer
+.Fa buf
+to store the result, which must be at least 26 characters long.
+.Pp
+The functions
+.Fn mktime
+and
+.Fn timegm
+convert the broken-down time in the structure
+pointed to by tm into a time value with the same encoding as that of the
+values returned by the
+.Xr time 3
+function (that is, seconds from the Epoch,
+.Tn UTC ) .
+.Fn mktime
+interprets the input structure according to the current timezone setting
+(see
+.Xr tzset 3 ) .
+.Fn timegm
+interprets the input structure as representing Universal Coordinated Time
+.Pq Tn UTC .
+.Pp
+The original values of the
+.Fa tm_wday
+and
+.Fa tm_yday
+components of the structure are ignored, and the original values of the
+other components are not restricted to their normal ranges.
+(A positive or zero value for
+.Fa tm_isdst
+causes
+.Fn mktime
+to presume initially that summer time (for example, Daylight Saving Time)
+is or is not in effect for the specified time, respectively.
+A negative value for
+.Fa tm_isdst
+causes the
+.Fn mktime
+function to attempt to divine whether summer time is in effect for the
+specified time.
+The
+.Fa tm_isdst
+and
+.Fa tm_gmtoff
+members are forced to zero by
+.Fn timegm . )
+.Pp
+On successful completion, the values of the
+.Fa tm_wday
+and
+.Fa tm_yday
+components of the structure are set appropriately, and the other components
+are set to represent the specified calendar time, but with their values
+forced to their normal ranges; the final value of
+.Fa tm_mday
+is not set until
+.Fa tm_mon
+and
+.Fa tm_year
+are determined.
+.Fn Mktime
+returns the specified calendar time; if the calendar time cannot be
+represented, it returns \-1;
+.Pp
+The
+.Fn difftime
+function
+returns the difference between two calendar times,
+.Pf ( Fa time1
+-
+.Fa time0 ) ,
+expressed in seconds.
+.Pp
+External declarations as well as the tm structure definition are in the
+.Aq Pa time.h
+include file.
+The tm structure includes at least the following fields:
+.Bd -literal -offset indent
+int tm_sec; /\(** seconds (0 - 60) \(**/
+int tm_min; /\(** minutes (0 - 59) \(**/
+int tm_hour; /\(** hours (0 - 23) \(**/
+int tm_mday; /\(** day of month (1 - 31) \(**/
+int tm_mon; /\(** month of year (0 - 11) \(**/
+int tm_year; /\(** year \- 1900 \(**/
+int tm_wday; /\(** day of week (Sunday = 0) \(**/
+int tm_yday; /\(** day of year (0 - 365) \(**/
+int tm_isdst; /\(** is summer time in effect? \(**/
+char \(**tm_zone; /\(** abbreviation of timezone name \(**/
+long tm_gmtoff; /\(** offset from UTC in seconds \(**/
+.Ed
+.Pp
+The
+field
+.Fa tm_isdst
+is non-zero if summer time is in effect.
+.Pp
+The field
+.Fa tm_gmtoff
+is the offset (in seconds) of the time represented from
+.Tn UTC ,
+with positive
+values indicating east of the Prime Meridian.
+.Sh SEE ALSO
+.Xr date 1 ,
+.Xr gettimeofday 2 ,
+.Xr getenv 3 ,
+.Xr time 3 ,
+.Xr tzset 3 ,
+.Xr tzfile 5
+.Sh STANDARDS
+The
+.Fn asctime ,
+.Fn ctime ,
+.Fn difftime ,
+.Fn gmtime ,
+.Fn localtime ,
+and
+.Fn mktime
+functions conform to
+.St -isoC ,
+and conform to
+.St -p1003.1
+provided the selected local timezone does not contain a leap-second table
+(see
+.Xr zic 8 ) .
+.Pp
+The
+.Fn asctime_r ,
+.Fn ctime_r ,
+.Fn gmtime_r ,
+and
+.Fn localtime_r
+functions are expected to conform to
+.St -iso9945-1
+(again provided the selected local timezone does not contain a leap-second
+table).
+.Pp
+The
+.Fn timegm
+function is not specified by any standard; its function cannot be
+completely emulated using the standard functions described above.
+.Sh HISTORY
+This manual page is derived from
+the time package contributed to Berkeley by
+.An Arthur Olson
+and which appeared in
+.Bx 4.3 .
+.Sh BUGS
+Except for
+.Fn difftime ,
+.Fn mktime ,
+and the
+.Fn \&_r
+variants of the other functions,
+these functions leaves their result in an internal static object and return
+a pointer to that object. Subsequent calls to these
+function will modify the same object.
+.Pp
+The C Standard provides no mechanism for a program to modify its current
+local timezone setting, and the
+.Tn POSIX Ns No \&-standard
+method is not reentrant. (However, thread-safe implementations are provided
+in the
+.Tn POSIX
+threaded environment.)
+.Pp
+The
+.Fa tm_zone
+field of a returned tm structure points to a static array of characters,
+which will also be overwritten by any subsequent calls (as well as by
+subsequent calls to
+.Xr tzset 3
+and
+.Xr tzsetwall 3 ) .
+.Pp
+Use of the external variable
+.Fa tzname
+is discouraged; the
+.Fa tm_zone
+entry in the tm structure is preferred.
diff --git a/lib/libc/stdtime/difftime.c b/lib/libc/stdtime/difftime.c
new file mode 100644
index 0000000..f178524
--- /dev/null
+++ b/lib/libc/stdtime/difftime.c
@@ -0,0 +1,77 @@
+/*
+** This file is in the public domain, so clarified as of
+** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
+*/
+
+#ifndef lint
+#ifndef NOID
+static char elsieid[] = "@(#)difftime.c 7.7";
+#endif /* !defined NOID */
+#endif /* !defined lint */
+
+/*LINTLIBRARY*/
+
+#include "private.h"
+
+/*
+** Algorithm courtesy Paul Eggert (eggert@twinsun.com).
+*/
+
+#ifdef HAVE_LONG_DOUBLE
+#define long_double long double
+#endif /* defined HAVE_LONG_DOUBLE */
+#ifndef HAVE_LONG_DOUBLE
+#define long_double double
+#endif /* !defined HAVE_LONG_DOUBLE */
+
+double
+difftime(time1, time0)
+const time_t time1;
+const time_t time0;
+{
+ time_t delta;
+ time_t hibit;
+
+ if (sizeof(time_t) < sizeof(double))
+ return (double) time1 - (double) time0;
+ if (sizeof(time_t) < sizeof(long_double))
+ return (long_double) time1 - (long_double) time0;
+ if (time1 < time0)
+ return -difftime(time0, time1);
+ /*
+ ** As much as possible, avoid loss of precision
+ ** by computing the difference before converting to double.
+ */
+ delta = time1 - time0;
+ if (delta >= 0)
+ return delta;
+ /*
+ ** Repair delta overflow.
+ */
+ hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1);
+ /*
+ ** The following expression rounds twice, which means
+ ** the result may not be the closest to the true answer.
+ ** For example, suppose time_t is 64-bit signed int,
+ ** long_double is IEEE 754 double with default rounding,
+ ** time1 = 9223372036854775807 and time0 = -1536.
+ ** Then the true difference is 9223372036854777343,
+ ** which rounds to 9223372036854777856
+ ** with a total error of 513.
+ ** But delta overflows to -9223372036854774273,
+ ** which rounds to -9223372036854774784, and correcting
+ ** this by subtracting 2 * (long_double) hibit
+ ** (i.e. by adding 2**64 = 18446744073709551616)
+ ** yields 9223372036854776832, which
+ ** rounds to 9223372036854775808
+ ** with a total error of 1535 instead.
+ ** This problem occurs only with very large differences.
+ ** It's too painful to fix this portably.
+ ** We are not alone in this problem;
+ ** some C compilers round twice when converting
+ ** large unsigned types to small floating types,
+ ** so if time_t is unsigned the "return delta" above
+ ** has the same double-rounding problem with those compilers.
+ */
+ return delta - 2 * (long_double) hibit;
+}
diff --git a/lib/libc/stdtime/localtime.c b/lib/libc/stdtime/localtime.c
new file mode 100644
index 0000000..6603336
--- /dev/null
+++ b/lib/libc/stdtime/localtime.c
@@ -0,0 +1,1770 @@
+/*
+** This file is in the public domain, so clarified as of
+** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
+*/
+
+#ifndef lint
+#ifndef NOID
+static char elsieid[] = "@(#)localtime.c 7.57";
+#endif /* !defined NOID */
+#endif /* !defined lint */
+
+/*
+** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu).
+** POSIX-style TZ environment variable handling from Guy Harris
+** (guy@auspex.com).
+*/
+
+/*LINTLIBRARY*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "private.h"
+#include "tzfile.h"
+#include "fcntl.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
+
+/*
+** SunOS 4.1.1 headers lack O_BINARY.
+*/
+
+#ifdef O_BINARY
+#define OPEN_MODE (O_RDONLY | O_BINARY)
+#endif /* defined O_BINARY */
+#ifndef O_BINARY
+#define OPEN_MODE O_RDONLY
+#endif /* !defined O_BINARY */
+
+#ifndef WILDABBR
+/*
+** Someone might make incorrect use of a time zone abbreviation:
+** 1. They might reference tzname[0] before calling tzset (explicitly
+** or implicitly).
+** 2. They might reference tzname[1] before calling tzset (explicitly
+** or implicitly).
+** 3. They might reference tzname[1] after setting to a time zone
+** in which Daylight Saving Time is never observed.
+** 4. They might reference tzname[0] after setting to a time zone
+** in which Standard Time is never observed.
+** 5. They might reference tm.TM_ZONE after calling offtime.
+** What's best to do in the above cases is open to debate;
+** for now, we just set things up so that in any of the five cases
+** WILDABBR is used. Another possibility: initialize tzname[0] to the
+** string "tzname[0] used before set", and similarly for the other cases.
+** And another: initialize tzname[0] to "ERA", with an explanation in the
+** manual page of what this "time zone abbreviation" means (doing this so
+** that tzname[0] has the "normal" length of three characters).
+*/
+#define WILDABBR " "
+#endif /* !defined WILDABBR */
+
+static char wildabbr[] = "WILDABBR";
+
+static const char gmt[] = "GMT";
+
+struct ttinfo { /* time type information */
+ long tt_gmtoff; /* GMT offset in seconds */
+ int tt_isdst; /* used to set tm_isdst */
+ int tt_abbrind; /* abbreviation list index */
+ int tt_ttisstd; /* TRUE if transition is std time */
+ int tt_ttisgmt; /* TRUE if transition is GMT */
+};
+
+struct lsinfo { /* leap second information */
+ time_t ls_trans; /* transition time */
+ long ls_corr; /* correction to apply */
+};
+
+#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
+
+#ifdef TZNAME_MAX
+#define MY_TZNAME_MAX TZNAME_MAX
+#endif /* defined TZNAME_MAX */
+#ifndef TZNAME_MAX
+#define MY_TZNAME_MAX 255
+#endif /* !defined TZNAME_MAX */
+
+struct state {
+ int leapcnt;
+ int timecnt;
+ int typecnt;
+ int charcnt;
+ time_t ats[TZ_MAX_TIMES];
+ unsigned char types[TZ_MAX_TIMES];
+ struct ttinfo ttis[TZ_MAX_TYPES];
+ char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
+ (2 * (MY_TZNAME_MAX + 1)))];
+ struct lsinfo lsis[TZ_MAX_LEAPS];
+};
+
+struct rule {
+ int r_type; /* type of rule--see below */
+ int r_day; /* day number of rule */
+ int r_week; /* week number of rule */
+ int r_mon; /* month number of rule */
+ long r_time; /* transition time of rule */
+};
+
+#define JULIAN_DAY 0 /* Jn - Julian day */
+#define DAY_OF_YEAR 1 /* n - day of year */
+#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
+
+/*
+** Prototypes for static functions.
+*/
+
+static long detzcode P((const char * codep));
+static const char * getzname P((const char * strp));
+static const char * getnum P((const char * strp, int * nump, int min,
+ int max));
+static const char * getsecs P((const char * strp, long * secsp));
+static const char * getoffset P((const char * strp, long * offsetp));
+static const char * getrule P((const char * strp, struct rule * rulep));
+static void gmtload P((struct state * sp));
+static void gmtsub P((const time_t * timep, long offset,
+ struct tm * tmp));
+static void localsub P((const time_t * timep, long offset,
+ struct tm * tmp));
+static int increment_overflow P((int * number, int delta));
+static int normalize_overflow P((int * tensptr, int * unitsptr,
+ int base));
+static void settzname P((void));
+static time_t time1 P((struct tm * tmp,
+ void(*funcp) P((const time_t *,
+ long, struct tm *)),
+ long offset));
+static time_t time2 P((struct tm *tmp,
+ void(*funcp) P((const time_t *,
+ long, struct tm*)),
+ long offset, int * okayp));
+static void timesub P((const time_t * timep, long offset,
+ const struct state * sp, struct tm * tmp));
+static int tmcomp P((const struct tm * atmp,
+ const struct tm * btmp));
+static time_t transtime P((time_t janfirst, int year,
+ const struct rule * rulep, long offset));
+static int tzload P((const char * name, struct state * sp));
+static int tzparse P((const char * name, struct state * sp,
+ int lastditch));
+
+#ifdef ALL_STATE
+static struct state * lclptr;
+static struct state * gmtptr;
+#endif /* defined ALL_STATE */
+
+#ifndef ALL_STATE
+static struct state lclmem;
+static struct state gmtmem;
+#define lclptr (&lclmem)
+#define gmtptr (&gmtmem)
+#endif /* State Farm */
+
+#ifndef TZ_STRLEN_MAX
+#define TZ_STRLEN_MAX 255
+#endif /* !defined TZ_STRLEN_MAX */
+
+static char lcl_TZname[TZ_STRLEN_MAX + 1];
+static int lcl_is_set;
+static int gmt_is_set;
+#ifdef _THREAD_SAFE
+static struct pthread_mutex _lcl_mutexd = PTHREAD_MUTEX_STATIC_INITIALIZER;
+static struct pthread_mutex _gmt_mutexd = PTHREAD_MUTEX_STATIC_INITIALIZER;
+static pthread_mutex_t lcl_mutex = &_lcl_mutexd;
+static pthread_mutex_t gmt_mutex = &_gmt_mutexd;
+#endif
+
+char * tzname[2] = {
+ wildabbr,
+ wildabbr
+};
+
+/*
+** Section 4.12.3 of X3.159-1989 requires that
+** Except for the strftime function, these functions [asctime,
+** ctime, gmtime, localtime] return values in one of two static
+** objects: a broken-down time structure and an array of char.
+** Thanks to Paul Eggert (eggert@twinsun.com) for noting this.
+*/
+
+static struct tm tm;
+
+#ifdef USG_COMPAT
+time_t timezone = 0;
+int daylight = 0;
+#endif /* defined USG_COMPAT */
+
+#ifdef ALTZONE
+time_t altzone = 0;
+#endif /* defined ALTZONE */
+
+static long
+detzcode(codep)
+const char * const codep;
+{
+ register long result;
+ register int i;
+
+ result = (codep[0] & 0x80) ? ~0L : 0L;
+ for (i = 0; i < 4; ++i)
+ result = (result << 8) | (codep[i] & 0xff);
+ return result;
+}
+
+static void
+settzname P((void))
+{
+ register struct state * const sp = lclptr;
+ register int i;
+
+ tzname[0] = wildabbr;
+ tzname[1] = wildabbr;
+#ifdef USG_COMPAT
+ daylight = 0;
+ timezone = 0;
+#endif /* defined USG_COMPAT */
+#ifdef ALTZONE
+ altzone = 0;
+#endif /* defined ALTZONE */
+#ifdef ALL_STATE
+ if (sp == NULL) {
+ tzname[0] = tzname[1] = gmt;
+ return;
+ }
+#endif /* defined ALL_STATE */
+ for (i = 0; i < sp->typecnt; ++i) {
+ register const struct ttinfo * const ttisp = &sp->ttis[i];
+
+ tzname[ttisp->tt_isdst] =
+ &sp->chars[ttisp->tt_abbrind];
+#ifdef USG_COMPAT
+ if (ttisp->tt_isdst)
+ daylight = 1;
+ if (i == 0 || !ttisp->tt_isdst)
+ timezone = -(ttisp->tt_gmtoff);
+#endif /* defined USG_COMPAT */
+#ifdef ALTZONE
+ if (i == 0 || ttisp->tt_isdst)
+ altzone = -(ttisp->tt_gmtoff);
+#endif /* defined ALTZONE */
+ }
+ /*
+ ** And to get the latest zone names into tzname. . .
+ */
+ for (i = 0; i < sp->timecnt; ++i) {
+ register const struct ttinfo * const ttisp =
+ &sp->ttis[
+ sp->types[i]];
+
+ tzname[ttisp->tt_isdst] =
+ &sp->chars[ttisp->tt_abbrind];
+ }
+}
+
+static int
+tzload(name, sp)
+register const char * name;
+register struct state * const sp;
+{
+ register const char * p;
+ register int i;
+ register int fid;
+
+ /* XXX The following is from OpenBSD, and I'm not sure it is correct */
+ if (name != NULL && issetugid() != 0)
+ if ((name[0] == ':' && name[1] == '/') ||
+ name[0] == '/' || strchr(name, '.'))
+ name = NULL;
+ if (name == NULL && (name = TZDEFAULT) == NULL)
+ return -1;
+ {
+ register int doaccess;
+ struct stat stab;
+ /*
+ ** Section 4.9.1 of the C standard says that
+ ** "FILENAME_MAX expands to an integral constant expression
+ ** that is the size needed for an array of char large enough
+ ** to hold the longest file name string that the implementation
+ ** guarantees can be opened."
+ */
+ char fullname[FILENAME_MAX + 1];
+
+ if (name[0] == ':')
+ ++name;
+ doaccess = name[0] == '/';
+ if (!doaccess) {
+ if ((p = TZDIR) == NULL)
+ return -1;
+ if ((strlen(p) + 1 + strlen(name) + 1) >= sizeof fullname)
+ return -1;
+ (void) strcpy(fullname, p);
+ (void) strcat(fullname, "/");
+ (void) strcat(fullname, name);
+ /*
+ ** Set doaccess if '.' (as in "../") shows up in name.
+ */
+ if (strchr(name, '.') != NULL)
+ doaccess = TRUE;
+ name = fullname;
+ }
+ if (doaccess && access(name, R_OK) != 0)
+ return -1;
+ if ((fid = open(name, OPEN_MODE)) == -1)
+ return -1;
+ if ((fstat(fid, &stab) < 0) || !S_ISREG(stab.st_mode))
+ return -1;
+ }
+ {
+ struct tzhead * tzhp;
+ char buf[sizeof *sp + sizeof *tzhp];
+ int ttisstdcnt;
+ int ttisgmtcnt;
+
+ i = read(fid, buf, sizeof buf);
+ if (close(fid) != 0)
+ return -1;
+ p = buf;
+ p += (sizeof tzhp->tzh_magic) + (sizeof tzhp->tzh_reserved);
+ ttisstdcnt = (int) detzcode(p);
+ p += 4;
+ ttisgmtcnt = (int) detzcode(p);
+ p += 4;
+ sp->leapcnt = (int) detzcode(p);
+ p += 4;
+ sp->timecnt = (int) detzcode(p);
+ p += 4;
+ sp->typecnt = (int) detzcode(p);
+ p += 4;
+ sp->charcnt = (int) detzcode(p);
+ p += 4;
+ if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
+ sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
+ sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
+ sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
+ (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
+ (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
+ return -1;
+ if (i - (p - buf) < sp->timecnt * 4 + /* ats */
+ sp->timecnt + /* types */
+ sp->typecnt * (4 + 2) + /* ttinfos */
+ sp->charcnt + /* chars */
+ sp->leapcnt * (4 + 4) + /* lsinfos */
+ ttisstdcnt + /* ttisstds */
+ ttisgmtcnt) /* ttisgmts */
+ return -1;
+ for (i = 0; i < sp->timecnt; ++i) {
+ sp->ats[i] = detzcode(p);
+ p += 4;
+ }
+ for (i = 0; i < sp->timecnt; ++i) {
+ sp->types[i] = (unsigned char) *p++;
+ if (sp->types[i] >= sp->typecnt)
+ return -1;
+ }
+ for (i = 0; i < sp->typecnt; ++i) {
+ register struct ttinfo * ttisp;
+
+ ttisp = &sp->ttis[i];
+ ttisp->tt_gmtoff = detzcode(p);
+ p += 4;
+ ttisp->tt_isdst = (unsigned char) *p++;
+ if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
+ return -1;
+ ttisp->tt_abbrind = (unsigned char) *p++;
+ if (ttisp->tt_abbrind < 0 ||
+ ttisp->tt_abbrind > sp->charcnt)
+ return -1;
+ }
+ for (i = 0; i < sp->charcnt; ++i)
+ sp->chars[i] = *p++;
+ sp->chars[i] = '\0'; /* ensure '\0' at end */
+ for (i = 0; i < sp->leapcnt; ++i) {
+ register struct lsinfo * lsisp;
+
+ lsisp = &sp->lsis[i];
+ lsisp->ls_trans = detzcode(p);
+ p += 4;
+ lsisp->ls_corr = detzcode(p);
+ p += 4;
+ }
+ for (i = 0; i < sp->typecnt; ++i) {
+ register struct ttinfo * ttisp;
+
+ ttisp = &sp->ttis[i];
+ if (ttisstdcnt == 0)
+ ttisp->tt_ttisstd = FALSE;
+ else {
+ ttisp->tt_ttisstd = *p++;
+ if (ttisp->tt_ttisstd != TRUE &&
+ ttisp->tt_ttisstd != FALSE)
+ return -1;
+ }
+ }
+ for (i = 0; i < sp->typecnt; ++i) {
+ register struct ttinfo * ttisp;
+
+ ttisp = &sp->ttis[i];
+ if (ttisgmtcnt == 0)
+ ttisp->tt_ttisgmt = FALSE;
+ else {
+ ttisp->tt_ttisgmt = *p++;
+ if (ttisp->tt_ttisgmt != TRUE &&
+ ttisp->tt_ttisgmt != FALSE)
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+static const int mon_lengths[2][MONSPERYEAR] = {
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+static const int year_lengths[2] = {
+ DAYSPERNYEAR, DAYSPERLYEAR
+};
+
+/*
+** Given a pointer into a time zone string, scan until a character that is not
+** a valid character in a zone name is found. Return a pointer to that
+** character.
+*/
+
+static const char *
+getzname(strp)
+register const char * strp;
+{
+ register char c;
+
+ while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
+ c != '+')
+ ++strp;
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract a number from that string.
+** Check that the number is within a specified range; if it is not, return
+** NULL.
+** Otherwise, return a pointer to the first character not part of the number.
+*/
+
+static const char *
+getnum(strp, nump, min, max)
+register const char * strp;
+int * const nump;
+const int min;
+const int max;
+{
+ register char c;
+ register int num;
+
+ if (strp == NULL || !is_digit(c = *strp))
+ return NULL;
+ num = 0;
+ do {
+ num = num * 10 + (c - '0');
+ if (num > max)
+ return NULL; /* illegal value */
+ c = *++strp;
+ } while (is_digit(c));
+ if (num < min)
+ return NULL; /* illegal value */
+ *nump = num;
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract a number of seconds,
+** in hh[:mm[:ss]] form, from the string.
+** If any error occurs, return NULL.
+** Otherwise, return a pointer to the first character not part of the number
+** of seconds.
+*/
+
+static const char *
+getsecs(strp, secsp)
+register const char * strp;
+long * const secsp;
+{
+ int num;
+
+ /*
+ ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
+ ** "M10.4.6/26", which does not conform to Posix,
+ ** but which specifies the equivalent of
+ ** ``02:00 on the first Sunday on or after 23 Oct''.
+ */
+ strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
+ if (strp == NULL)
+ return NULL;
+ *secsp = num * (long) SECSPERHOUR;
+ if (*strp == ':') {
+ ++strp;
+ strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
+ if (strp == NULL)
+ return NULL;
+ *secsp += num * SECSPERMIN;
+ if (*strp == ':') {
+ ++strp;
+ /* `SECSPERMIN' allows for leap seconds. */
+ strp = getnum(strp, &num, 0, SECSPERMIN);
+ if (strp == NULL)
+ return NULL;
+ *secsp += num;
+ }
+ }
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract an offset, in
+** [+-]hh[:mm[:ss]] form, from the string.
+** If any error occurs, return NULL.
+** Otherwise, return a pointer to the first character not part of the time.
+*/
+
+static const char *
+getoffset(strp, offsetp)
+register const char * strp;
+long * const offsetp;
+{
+ register int neg = 0;
+
+ if (*strp == '-') {
+ neg = 1;
+ ++strp;
+ } else if (*strp == '+')
+ ++strp;
+ strp = getsecs(strp, offsetp);
+ if (strp == NULL)
+ return NULL; /* illegal time */
+ if (neg)
+ *offsetp = -*offsetp;
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract a rule in the form
+** date[/time]. See POSIX section 8 for the format of "date" and "time".
+** If a valid rule is not found, return NULL.
+** Otherwise, return a pointer to the first character not part of the rule.
+*/
+
+static const char *
+getrule(strp, rulep)
+const char * strp;
+register struct rule * const rulep;
+{
+ if (*strp == 'J') {
+ /*
+ ** Julian day.
+ */
+ rulep->r_type = JULIAN_DAY;
+ ++strp;
+ strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
+ } else if (*strp == 'M') {
+ /*
+ ** Month, week, day.
+ */
+ rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
+ ++strp;
+ strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
+ if (strp == NULL)
+ return NULL;
+ if (*strp++ != '.')
+ return NULL;
+ strp = getnum(strp, &rulep->r_week, 1, 5);
+ if (strp == NULL)
+ return NULL;
+ if (*strp++ != '.')
+ return NULL;
+ strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
+ } else if (is_digit(*strp)) {
+ /*
+ ** Day of year.
+ */
+ rulep->r_type = DAY_OF_YEAR;
+ strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
+ } else return NULL; /* invalid format */
+ if (strp == NULL)
+ return NULL;
+ if (*strp == '/') {
+ /*
+ ** Time specified.
+ */
+ ++strp;
+ strp = getsecs(strp, &rulep->r_time);
+ } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
+ return strp;
+}
+
+/*
+** Given the Epoch-relative time of January 1, 00:00:00 GMT, in a year, the
+** year, a rule, and the offset from GMT at the time that rule takes effect,
+** calculate the Epoch-relative time that rule takes effect.
+*/
+
+static time_t
+transtime(janfirst, year, rulep, offset)
+const time_t janfirst;
+const int year;
+register const struct rule * const rulep;
+const long offset;
+{
+ register int leapyear;
+ register time_t value;
+ register int i;
+ int d, m1, yy0, yy1, yy2, dow;
+
+ INITIALIZE(value);
+ leapyear = isleap(year);
+ switch (rulep->r_type) {
+
+ case JULIAN_DAY:
+ /*
+ ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
+ ** years.
+ ** In non-leap years, or if the day number is 59 or less, just
+ ** add SECSPERDAY times the day number-1 to the time of
+ ** January 1, midnight, to get the day.
+ */
+ value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
+ if (leapyear && rulep->r_day >= 60)
+ value += SECSPERDAY;
+ break;
+
+ case DAY_OF_YEAR:
+ /*
+ ** n - day of year.
+ ** Just add SECSPERDAY times the day number to the time of
+ ** January 1, midnight, to get the day.
+ */
+ value = janfirst + rulep->r_day * SECSPERDAY;
+ break;
+
+ case MONTH_NTH_DAY_OF_WEEK:
+ /*
+ ** Mm.n.d - nth "dth day" of month m.
+ */
+ value = janfirst;
+ for (i = 0; i < rulep->r_mon - 1; ++i)
+ value += mon_lengths[leapyear][i] * SECSPERDAY;
+
+ /*
+ ** Use Zeller's Congruence to get day-of-week of first day of
+ ** month.
+ */
+ m1 = (rulep->r_mon + 9) % 12 + 1;
+ yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
+ yy1 = yy0 / 100;
+ yy2 = yy0 % 100;
+ dow = ((26 * m1 - 2) / 10 +
+ 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
+ if (dow < 0)
+ dow += DAYSPERWEEK;
+
+ /*
+ ** "dow" is the day-of-week of the first day of the month. Get
+ ** the day-of-month (zero-origin) of the first "dow" day of the
+ ** month.
+ */
+ d = rulep->r_day - dow;
+ if (d < 0)
+ d += DAYSPERWEEK;
+ for (i = 1; i < rulep->r_week; ++i) {
+ if (d + DAYSPERWEEK >=
+ mon_lengths[leapyear][rulep->r_mon - 1])
+ break;
+ d += DAYSPERWEEK;
+ }
+
+ /*
+ ** "d" is the day-of-month (zero-origin) of the day we want.
+ */
+ value += d * SECSPERDAY;
+ break;
+ }
+
+ /*
+ ** "value" is the Epoch-relative time of 00:00:00 GMT on the day in
+ ** question. To get the Epoch-relative time of the specified local
+ ** time on that day, add the transition time and the current offset
+ ** from GMT.
+ */
+ return value + rulep->r_time + offset;
+}
+
+/*
+** Given a POSIX section 8-style TZ string, fill in the rule tables as
+** appropriate.
+*/
+
+static int
+tzparse(name, sp, lastditch)
+const char * name;
+register struct state * const sp;
+const int lastditch;
+{
+ const char * stdname;
+ const char * dstname;
+ size_t stdlen;
+ size_t dstlen;
+ long stdoffset;
+ long dstoffset;
+ register time_t * atp;
+ register unsigned char * typep;
+ register char * cp;
+ register int load_result;
+
+ INITIALIZE(dstname);
+ stdname = name;
+ if (lastditch) {
+ stdlen = strlen(name); /* length of standard zone name */
+ name += stdlen;
+ if (stdlen >= sizeof sp->chars)
+ stdlen = (sizeof sp->chars) - 1;
+ stdoffset = 0;
+ } else {
+ name = getzname(name);
+ stdlen = name - stdname;
+ if (stdlen < 3)
+ return -1;
+ if (*name == '\0')
+ return -1; /* was "stdoffset = 0;" */
+ else {
+ name = getoffset(name, &stdoffset);
+ if (name == NULL)
+ return -1;
+ }
+ }
+ load_result = tzload(TZDEFRULES, sp);
+ if (load_result != 0)
+ sp->leapcnt = 0; /* so, we're off a little */
+ if (*name != '\0') {
+ dstname = name;
+ name = getzname(name);
+ dstlen = name - dstname; /* length of DST zone name */
+ if (dstlen < 3)
+ return -1;
+ if (*name != '\0' && *name != ',' && *name != ';') {
+ name = getoffset(name, &dstoffset);
+ if (name == NULL)
+ return -1;
+ } else dstoffset = stdoffset - SECSPERHOUR;
+ if (*name == ',' || *name == ';') {
+ struct rule start;
+ struct rule end;
+ register int year;
+ register time_t janfirst;
+ time_t starttime;
+ time_t endtime;
+
+ ++name;
+ if ((name = getrule(name, &start)) == NULL)
+ return -1;
+ if (*name++ != ',')
+ return -1;
+ if ((name = getrule(name, &end)) == NULL)
+ return -1;
+ if (*name != '\0')
+ return -1;
+ sp->typecnt = 2; /* standard time and DST */
+ /*
+ ** Two transitions per year, from EPOCH_YEAR to 2037.
+ */
+ sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
+ if (sp->timecnt > TZ_MAX_TIMES)
+ return -1;
+ sp->ttis[0].tt_gmtoff = -dstoffset;
+ sp->ttis[0].tt_isdst = 1;
+ sp->ttis[0].tt_abbrind = stdlen + 1;
+ sp->ttis[1].tt_gmtoff = -stdoffset;
+ sp->ttis[1].tt_isdst = 0;
+ sp->ttis[1].tt_abbrind = 0;
+ atp = sp->ats;
+ typep = sp->types;
+ janfirst = 0;
+ for (year = EPOCH_YEAR; year <= 2037; ++year) {
+ starttime = transtime(janfirst, year, &start,
+ stdoffset);
+ endtime = transtime(janfirst, year, &end,
+ dstoffset);
+ if (starttime > endtime) {
+ *atp++ = endtime;
+ *typep++ = 1; /* DST ends */
+ *atp++ = starttime;
+ *typep++ = 0; /* DST begins */
+ } else {
+ *atp++ = starttime;
+ *typep++ = 0; /* DST begins */
+ *atp++ = endtime;
+ *typep++ = 1; /* DST ends */
+ }
+ janfirst += year_lengths[isleap(year)] *
+ SECSPERDAY;
+ }
+ } else {
+ register long theirstdoffset;
+ register long theirdstoffset;
+ register long theiroffset;
+ register int isdst;
+ register int i;
+ register int j;
+
+ if (*name != '\0')
+ return -1;
+ if (load_result != 0)
+ return -1;
+ /*
+ ** Initial values of theirstdoffset and theirdstoffset.
+ */
+ theirstdoffset = 0;
+ for (i = 0; i < sp->timecnt; ++i) {
+ j = sp->types[i];
+ if (!sp->ttis[j].tt_isdst) {
+ theirstdoffset =
+ -sp->ttis[j].tt_gmtoff;
+ break;
+ }
+ }
+ theirdstoffset = 0;
+ for (i = 0; i < sp->timecnt; ++i) {
+ j = sp->types[i];
+ if (sp->ttis[j].tt_isdst) {
+ theirdstoffset =
+ -sp->ttis[j].tt_gmtoff;
+ break;
+ }
+ }
+ /*
+ ** Initially we're assumed to be in standard time.
+ */
+ isdst = FALSE;
+ theiroffset = theirstdoffset;
+ /*
+ ** Now juggle transition times and types
+ ** tracking offsets as you do.
+ */
+ for (i = 0; i < sp->timecnt; ++i) {
+ j = sp->types[i];
+ sp->types[i] = sp->ttis[j].tt_isdst;
+ if (sp->ttis[j].tt_ttisgmt) {
+ /* No adjustment to transition time */
+ } else {
+ /*
+ ** If summer time is in effect, and the
+ ** transition time was not specified as
+ ** standard time, add the summer time
+ ** offset to the transition time;
+ ** otherwise, add the standard time
+ ** offset to the transition time.
+ */
+ /*
+ ** Transitions from DST to DDST
+ ** will effectively disappear since
+ ** POSIX provides for only one DST
+ ** offset.
+ */
+ if (isdst && !sp->ttis[j].tt_ttisstd) {
+ sp->ats[i] += dstoffset -
+ theirdstoffset;
+ } else {
+ sp->ats[i] += stdoffset -
+ theirstdoffset;
+ }
+ }
+ theiroffset = -sp->ttis[j].tt_gmtoff;
+ if (sp->ttis[j].tt_isdst)
+ theirdstoffset = theiroffset;
+ else theirstdoffset = theiroffset;
+ }
+ /*
+ ** Finally, fill in ttis.
+ ** ttisstd and ttisgmt need not be handled.
+ */
+ sp->ttis[0].tt_gmtoff = -stdoffset;
+ sp->ttis[0].tt_isdst = FALSE;
+ sp->ttis[0].tt_abbrind = 0;
+ sp->ttis[1].tt_gmtoff = -dstoffset;
+ sp->ttis[1].tt_isdst = TRUE;
+ sp->ttis[1].tt_abbrind = stdlen + 1;
+ }
+ } else {
+ dstlen = 0;
+ sp->typecnt = 1; /* only standard time */
+ sp->timecnt = 0;
+ sp->ttis[0].tt_gmtoff = -stdoffset;
+ sp->ttis[0].tt_isdst = 0;
+ sp->ttis[0].tt_abbrind = 0;
+ }
+ sp->charcnt = stdlen + 1;
+ if (dstlen != 0)
+ sp->charcnt += dstlen + 1;
+ if (sp->charcnt > sizeof sp->chars)
+ return -1;
+ cp = sp->chars;
+ (void) strncpy(cp, stdname, stdlen);
+ cp += stdlen;
+ *cp++ = '\0';
+ if (dstlen != 0) {
+ (void) strncpy(cp, dstname, dstlen);
+ *(cp + dstlen) = '\0';
+ }
+ return 0;
+}
+
+static void
+gmtload(sp)
+struct state * const sp;
+{
+ if (tzload(gmt, sp) != 0)
+ (void) tzparse(gmt, sp, TRUE);
+}
+
+#ifndef STD_INSPIRED
+/*
+** A non-static declaration of tzsetwall in a system header file
+** may cause a warning about this upcoming static declaration...
+*/
+static
+#endif /* !defined STD_INSPIRED */
+#ifdef _THREAD_SAFE
+void
+tzsetwall_basic P((void))
+#else
+void
+tzsetwall P((void))
+#endif
+{
+ if (lcl_is_set < 0)
+ return;
+ lcl_is_set = -1;
+
+#ifdef ALL_STATE
+ if (lclptr == NULL) {
+ lclptr = (struct state *) malloc(sizeof *lclptr);
+ if (lclptr == NULL) {
+ settzname(); /* all we can do */
+ return;
+ }
+ }
+#endif /* defined ALL_STATE */
+ if (tzload((char *) NULL, lclptr) != 0)
+ gmtload(lclptr);
+ settzname();
+}
+
+#ifdef _THREAD_SAFE
+void
+tzsetwall P((void))
+{
+ pthread_mutex_lock(&lcl_mutex);
+ tzsetwall_basic();
+ pthread_mutex_unlock(&lcl_mutex);
+}
+#endif
+
+#ifdef _THREAD_SAFE
+static void
+tzset_basic P((void))
+#else
+void
+tzset P((void))
+#endif
+{
+ register const char * name;
+
+ name = getenv("TZ");
+ if (name == NULL) {
+ tzsetwall();
+ return;
+ }
+
+ if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
+ return;
+ lcl_is_set = (strlen(name) < sizeof(lcl_TZname));
+ if (lcl_is_set)
+ (void) strcpy(lcl_TZname, name);
+
+#ifdef ALL_STATE
+ if (lclptr == NULL) {
+ lclptr = (struct state *) malloc(sizeof *lclptr);
+ if (lclptr == NULL) {
+ settzname(); /* all we can do */
+ return;
+ }
+ }
+#endif /* defined ALL_STATE */
+ if (*name == '\0') {
+ /*
+ ** User wants it fast rather than right.
+ */
+ lclptr->leapcnt = 0; /* so, we're off a little */
+ lclptr->timecnt = 0;
+ lclptr->ttis[0].tt_gmtoff = 0;
+ lclptr->ttis[0].tt_abbrind = 0;
+ (void) strcpy(lclptr->chars, gmt);
+ } else if (tzload(name, lclptr) != 0)
+ if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
+ (void) gmtload(lclptr);
+ settzname();
+}
+
+#ifdef _THREAD_SAFE
+void
+tzset P((void))
+{
+ pthread_mutex_lock(&lcl_mutex);
+ tzset_basic();
+ pthread_mutex_unlock(&lcl_mutex);
+}
+#endif
+
+/*
+** The easy way to behave "as if no library function calls" localtime
+** is to not call it--so we drop its guts into "localsub", which can be
+** freely called. (And no, the PANS doesn't require the above behavior--
+** but it *is* desirable.)
+**
+** The unused offset argument is for the benefit of mktime variants.
+*/
+
+/*ARGSUSED*/
+static void
+localsub(timep, offset, tmp)
+const time_t * const timep;
+const long offset;
+struct tm * const tmp;
+{
+ register struct state * sp;
+ register const struct ttinfo * ttisp;
+ register int i;
+ const time_t t = *timep;
+
+ sp = lclptr;
+#ifdef ALL_STATE
+ if (sp == NULL) {
+ gmtsub(timep, offset, tmp);
+ return;
+ }
+#endif /* defined ALL_STATE */
+ if (sp->timecnt == 0 || t < sp->ats[0]) {
+ i = 0;
+ while (sp->ttis[i].tt_isdst)
+ if (++i >= sp->typecnt) {
+ i = 0;
+ break;
+ }
+ } else {
+ for (i = 1; i < sp->timecnt; ++i)
+ if (t < sp->ats[i])
+ break;
+ i = sp->types[i - 1];
+ }
+ ttisp = &sp->ttis[i];
+ /*
+ ** To get (wrong) behavior that's compatible with System V Release 2.0
+ ** you'd replace the statement below with
+ ** t += ttisp->tt_gmtoff;
+ ** timesub(&t, 0L, sp, tmp);
+ */
+ timesub(&t, ttisp->tt_gmtoff, sp, tmp);
+ tmp->tm_isdst = ttisp->tt_isdst;
+ tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
+#ifdef TM_ZONE
+ tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
+#endif /* defined TM_ZONE */
+}
+
+struct tm *
+localtime_r(timep, p_tm)
+const time_t * const timep;
+struct tm *p_tm;
+{
+#ifdef _THREAD_SAFE
+ pthread_mutex_lock(&lcl_mutex);
+#endif
+ tzset();
+ localsub(timep, 0L, p_tm);
+#ifdef _THREAD_SAFE
+ pthread_mutex_unlock(&lcl_mutex);
+#endif
+ return(p_tm);
+}
+
+struct tm *
+localtime(timep)
+const time_t * const timep;
+{
+#ifdef _THREAD_SAFE
+ static struct pthread_mutex _localtime_mutex = PTHREAD_MUTEX_STATIC_INITIALIZER;
+ static pthread_mutex_t localtime_mutex = &_localtime_mutex;
+ static pthread_key_t localtime_key = -1;
+ struct tm *p_tm;
+
+ pthread_mutex_lock(&localtime_mutex);
+ if (localtime_key < 0) {
+ if (pthread_key_create(&localtime_key, free) < 0) {
+ pthread_mutex_unlock(&localtime_mutex);
+ return(NULL);
+ }
+ }
+ pthread_mutex_unlock(&localtime_mutex);
+ p_tm = pthread_getspecific(localtime_key);
+ if (p_tm == NULL) {
+ if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) == NULL)
+ return(NULL);
+ pthread_setspecific(localtime_key, p_tm);
+ }
+ pthread_mutex_lock(&lcl_mutex);
+ tzset();
+ localsub(timep, 0L, p_tm);
+ pthread_mutex_unlock(&lcl_mutex);
+ return p_tm;
+#else
+ tzset();
+ localsub(timep, 0L, &tm);
+ return &tm;
+#endif
+}
+
+/*
+** gmtsub is to gmtime as localsub is to localtime.
+*/
+
+static void
+gmtsub(timep, offset, tmp)
+const time_t * const timep;
+const long offset;
+struct tm * const tmp;
+{
+#ifdef _THREAD_SAFE
+ pthread_mutex_lock(&gmt_mutex);
+#endif
+ if (!gmt_is_set) {
+ gmt_is_set = TRUE;
+#ifdef ALL_STATE
+ gmtptr = (struct state *) malloc(sizeof *gmtptr);
+ if (gmtptr != NULL)
+#endif /* defined ALL_STATE */
+ gmtload(gmtptr);
+ }
+#ifdef _THREAD_SAFE
+ pthread_mutex_unlock(&gmt_mutex);
+#endif
+ timesub(timep, offset, gmtptr, tmp);
+#ifdef TM_ZONE
+ /*
+ ** Could get fancy here and deliver something such as
+ ** "GMT+xxxx" or "GMT-xxxx" if offset is non-zero,
+ ** but this is no time for a treasure hunt.
+ */
+ if (offset != 0)
+ tmp->TM_ZONE = wildabbr;
+ else {
+#ifdef ALL_STATE
+ if (gmtptr == NULL)
+ tmp->TM_ZONE = gmt;
+ else tmp->TM_ZONE = gmtptr->chars;
+#endif /* defined ALL_STATE */
+#ifndef ALL_STATE
+ tmp->TM_ZONE = gmtptr->chars;
+#endif /* State Farm */
+ }
+#endif /* defined TM_ZONE */
+}
+
+struct tm *
+gmtime(timep)
+const time_t * const timep;
+{
+#ifdef _THREAD_SAFE
+ static struct pthread_mutex _gmtime_mutex = PTHREAD_MUTEX_STATIC_INITIALIZER;
+ static pthread_mutex_t gmtime_mutex = &_gmtime_mutex;
+ static pthread_key_t gmtime_key = -1;
+ struct tm *p_tm;
+
+ pthread_mutex_lock(&gmtime_mutex);
+ if (gmtime_key < 0) {
+ if (pthread_key_create(&gmtime_key, free) < 0) {
+ pthread_mutex_unlock(&gmtime_mutex);
+ return(NULL);
+ }
+ }
+ pthread_mutex_unlock(&gmtime_mutex);
+ /*
+ * Changed to follow draft 4 pthreads standard, which
+ * is what BSD currently has.
+ */
+ if ((p_tm = pthread_getspecific(gmtime_key)) == NULL) {
+ if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) {
+ return(NULL);
+ }
+ pthread_setspecific(gmtime_key, p_tm);
+ }
+ gmtsub(timep, 0L, p_tm);
+ return(p_tm);
+#else
+ gmtsub(timep, 0L, &tm);
+ return &tm;
+#endif
+}
+
+struct tm *
+gmtime_r(const time_t * timep, struct tm * tm)
+{
+ gmtsub(timep, 0L, tm);
+ return(tm);
+}
+
+#ifdef STD_INSPIRED
+
+struct tm *
+offtime(timep, offset)
+const time_t * const timep;
+const long offset;
+{
+ gmtsub(timep, offset, &tm);
+ return &tm;
+}
+
+#endif /* defined STD_INSPIRED */
+
+static void
+timesub(timep, offset, sp, tmp)
+const time_t * const timep;
+const long offset;
+register const struct state * const sp;
+register struct tm * const tmp;
+{
+ register const struct lsinfo * lp;
+ register long days;
+ register long rem;
+ register int y;
+ register int yleap;
+ register const int * ip;
+ register long corr;
+ register int hit;
+ register int i;
+
+ corr = 0;
+ hit = 0;
+#ifdef ALL_STATE
+ i = (sp == NULL) ? 0 : sp->leapcnt;
+#endif /* defined ALL_STATE */
+#ifndef ALL_STATE
+ i = sp->leapcnt;
+#endif /* State Farm */
+ while (--i >= 0) {
+ lp = &sp->lsis[i];
+ if (*timep >= lp->ls_trans) {
+ if (*timep == lp->ls_trans) {
+ hit = ((i == 0 && lp->ls_corr > 0) ||
+ lp->ls_corr > sp->lsis[i - 1].ls_corr);
+ if (hit)
+ while (i > 0 &&
+ sp->lsis[i].ls_trans ==
+ sp->lsis[i - 1].ls_trans + 1 &&
+ sp->lsis[i].ls_corr ==
+ sp->lsis[i - 1].ls_corr + 1) {
+ ++hit;
+ --i;
+ }
+ }
+ corr = lp->ls_corr;
+ break;
+ }
+ }
+ days = *timep / SECSPERDAY;
+ rem = *timep % SECSPERDAY;
+#ifdef mc68k
+ if (*timep == 0x80000000) {
+ /*
+ ** A 3B1 muffs the division on the most negative number.
+ */
+ days = -24855;
+ rem = -11648;
+ }
+#endif /* defined mc68k */
+ rem += (offset - corr);
+ while (rem < 0) {
+ rem += SECSPERDAY;
+ --days;
+ }
+ while (rem >= SECSPERDAY) {
+ rem -= SECSPERDAY;
+ ++days;
+ }
+ tmp->tm_hour = (int) (rem / SECSPERHOUR);
+ rem = rem % SECSPERHOUR;
+ tmp->tm_min = (int) (rem / SECSPERMIN);
+ /*
+ ** A positive leap second requires a special
+ ** representation. This uses "... ??:59:60" et seq.
+ */
+ tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
+ tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
+ if (tmp->tm_wday < 0)
+ tmp->tm_wday += DAYSPERWEEK;
+ y = EPOCH_YEAR;
+#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
+ while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
+ register int newy;
+
+ newy = y + days / DAYSPERNYEAR;
+ if (days < 0)
+ --newy;
+ days -= (newy - y) * DAYSPERNYEAR +
+ LEAPS_THRU_END_OF(newy - 1) -
+ LEAPS_THRU_END_OF(y - 1);
+ y = newy;
+ }
+ tmp->tm_year = y - TM_YEAR_BASE;
+ tmp->tm_yday = (int) days;
+ ip = mon_lengths[yleap];
+ for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
+ days = days - (long) ip[tmp->tm_mon];
+ tmp->tm_mday = (int) (days + 1);
+ tmp->tm_isdst = 0;
+#ifdef TM_GMTOFF
+ tmp->TM_GMTOFF = offset;
+#endif /* defined TM_GMTOFF */
+}
+
+char *
+ctime(timep)
+const time_t * const timep;
+{
+/*
+** Section 4.12.3.2 of X3.159-1989 requires that
+** The ctime funciton converts the calendar time pointed to by timer
+** to local time in the form of a string. It is equivalent to
+** asctime(localtime(timer))
+*/
+ return asctime(localtime(timep));
+}
+
+char *
+ctime_r(timep, buf)
+const time_t * const timep;
+char *buf;
+{
+ struct tm tm;
+ return asctime_r(localtime_r(timep, &tm), buf);
+}
+
+/*
+** Adapted from code provided by Robert Elz, who writes:
+** The "best" way to do mktime I think is based on an idea of Bob
+** Kridle's (so its said...) from a long time ago.
+** [kridle@xinet.com as of 1996-01-16.]
+** It does a binary search of the time_t space. Since time_t's are
+** just 32 bits, its a max of 32 iterations (even at 64 bits it
+** would still be very reasonable).
+*/
+
+#ifndef WRONG
+#define WRONG (-1)
+#endif /* !defined WRONG */
+
+/*
+** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com).
+*/
+
+static int
+increment_overflow(number, delta)
+int * number;
+int delta;
+{
+ int number0;
+
+ number0 = *number;
+ *number += delta;
+ return (*number < number0) != (delta < 0);
+}
+
+static int
+normalize_overflow(tensptr, unitsptr, base)
+int * const tensptr;
+int * const unitsptr;
+const int base;
+{
+ register int tensdelta;
+
+ tensdelta = (*unitsptr >= 0) ?
+ (*unitsptr / base) :
+ (-1 - (-1 - *unitsptr) / base);
+ *unitsptr -= tensdelta * base;
+ return increment_overflow(tensptr, tensdelta);
+}
+
+static int
+tmcomp(atmp, btmp)
+register const struct tm * const atmp;
+register const struct tm * const btmp;
+{
+ register int result;
+
+ if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
+ (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
+ (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
+ (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
+ (result = (atmp->tm_min - btmp->tm_min)) == 0)
+ result = atmp->tm_sec - btmp->tm_sec;
+ return result;
+}
+
+static time_t
+time2(tmp, funcp, offset, okayp)
+struct tm * const tmp;
+void (* const funcp) P((const time_t*, long, struct tm*));
+const long offset;
+int * const okayp;
+{
+ register const struct state * sp;
+ register int dir;
+ register int bits;
+ register int i, j ;
+ register int saved_seconds;
+ time_t newt;
+ time_t t;
+ struct tm yourtm, mytm;
+
+ *okayp = FALSE;
+ yourtm = *tmp;
+ if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
+ return WRONG;
+ if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
+ return WRONG;
+ if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR))
+ return WRONG;
+ /*
+ ** Turn yourtm.tm_year into an actual year number for now.
+ ** It is converted back to an offset from TM_YEAR_BASE later.
+ */
+ if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE))
+ return WRONG;
+ while (yourtm.tm_mday <= 0) {
+ if (increment_overflow(&yourtm.tm_year, -1))
+ return WRONG;
+ i = yourtm.tm_year + (1 < yourtm.tm_mon);
+ yourtm.tm_mday += year_lengths[isleap(i)];
+ }
+ while (yourtm.tm_mday > DAYSPERLYEAR) {
+ i = yourtm.tm_year + (1 < yourtm.tm_mon);
+ yourtm.tm_mday -= year_lengths[isleap(i)];
+ if (increment_overflow(&yourtm.tm_year, 1))
+ return WRONG;
+ }
+ for ( ; ; ) {
+ i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon];
+ if (yourtm.tm_mday <= i)
+ break;
+ yourtm.tm_mday -= i;
+ if (++yourtm.tm_mon >= MONSPERYEAR) {
+ yourtm.tm_mon = 0;
+ if (increment_overflow(&yourtm.tm_year, 1))
+ return WRONG;
+ }
+ }
+ if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE))
+ return WRONG;
+ if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) {
+ /*
+ ** We can't set tm_sec to 0, because that might push the
+ ** time below the minimum representable time.
+ ** Set tm_sec to 59 instead.
+ ** This assumes that the minimum representable time is
+ ** not in the same minute that a leap second was deleted from,
+ ** which is a safer assumption than using 58 would be.
+ */
+ if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
+ return WRONG;
+ saved_seconds = yourtm.tm_sec;
+ yourtm.tm_sec = SECSPERMIN - 1;
+ } else {
+ saved_seconds = yourtm.tm_sec;
+ yourtm.tm_sec = 0;
+ }
+ /*
+ ** Divide the search space in half
+ ** (this works whether time_t is signed or unsigned).
+ */
+ bits = TYPE_BIT(time_t) - 1;
+ /*
+ ** If time_t is signed, then 0 is just above the median,
+ ** assuming two's complement arithmetic.
+ ** If time_t is unsigned, then (1 << bits) is just above the median.
+ */
+ t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits);
+ for ( ; ; ) {
+ (*funcp)(&t, offset, &mytm);
+ dir = tmcomp(&mytm, &yourtm);
+ if (dir != 0) {
+ if (bits-- < 0)
+ return WRONG;
+ if (bits < 0)
+ --t; /* may be needed if new t is minimal */
+ else if (dir > 0)
+ t -= ((time_t) 1) << bits;
+ else t += ((time_t) 1) << bits;
+ continue;
+ }
+ if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
+ break;
+ /*
+ ** Right time, wrong type.
+ ** Hunt for right time, right type.
+ ** It's okay to guess wrong since the guess
+ ** gets checked.
+ */
+ /*
+ ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
+ */
+ sp = (const struct state *)
+ (((void *) funcp == (void *) localsub) ?
+ lclptr : gmtptr);
+#ifdef ALL_STATE
+ if (sp == NULL)
+ return WRONG;
+#endif /* defined ALL_STATE */
+ for (i = sp->typecnt - 1; i >= 0; --i) {
+ if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
+ continue;
+ for (j = sp->typecnt - 1; j >= 0; --j) {
+ if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
+ continue;
+ newt = t + sp->ttis[j].tt_gmtoff -
+ sp->ttis[i].tt_gmtoff;
+ (*funcp)(&newt, offset, &mytm);
+ if (tmcomp(&mytm, &yourtm) != 0)
+ continue;
+ if (mytm.tm_isdst != yourtm.tm_isdst)
+ continue;
+ /*
+ ** We have a match.
+ */
+ t = newt;
+ goto label;
+ }
+ }
+ return WRONG;
+ }
+label:
+ newt = t + saved_seconds;
+ if ((newt < t) != (saved_seconds < 0))
+ return WRONG;
+ t = newt;
+ (*funcp)(&t, offset, tmp);
+ *okayp = TRUE;
+ return t;
+}
+
+static time_t
+time1(tmp, funcp, offset)
+struct tm * const tmp;
+void (* const funcp) P((const time_t *, long, struct tm *));
+const long offset;
+{
+ register time_t t;
+ register const struct state * sp;
+ register int samei, otheri;
+ int okay;
+
+ if (tmp->tm_isdst > 1)
+ tmp->tm_isdst = 1;
+ t = time2(tmp, funcp, offset, &okay);
+#ifdef PCTS
+ /*
+ ** PCTS code courtesy Grant Sullivan (grant@osf.org).
+ */
+ if (okay)
+ return t;
+ if (tmp->tm_isdst < 0)
+ tmp->tm_isdst = 0; /* reset to std and try again */
+#endif /* defined PCTS */
+#ifndef PCTS
+ if (okay || tmp->tm_isdst < 0)
+ return t;
+#endif /* !defined PCTS */
+ /*
+ ** We're supposed to assume that somebody took a time of one type
+ ** and did some math on it that yielded a "struct tm" that's bad.
+ ** We try to divine the type they started from and adjust to the
+ ** type they need.
+ */
+ /*
+ ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
+ */
+ sp = (const struct state *) (((void *) funcp == (void *) localsub) ?
+ lclptr : gmtptr);
+#ifdef ALL_STATE
+ if (sp == NULL)
+ return WRONG;
+#endif /* defined ALL_STATE */
+ for (samei = sp->typecnt - 1; samei >= 0; --samei) {
+ if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
+ continue;
+ for (otheri = sp->typecnt - 1; otheri >= 0; --otheri) {
+ if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
+ continue;
+ tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
+ sp->ttis[samei].tt_gmtoff;
+ tmp->tm_isdst = !tmp->tm_isdst;
+ t = time2(tmp, funcp, offset, &okay);
+ if (okay)
+ return t;
+ tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
+ sp->ttis[samei].tt_gmtoff;
+ tmp->tm_isdst = !tmp->tm_isdst;
+ }
+ }
+ return WRONG;
+}
+
+time_t
+mktime(tmp)
+struct tm * const tmp;
+{
+ time_t mktime_return_value;
+#ifdef _THREAD_SAFE
+ pthread_mutex_lock(&lcl_mutex);
+#endif
+ tzset();
+ mktime_return_value = time1(tmp, localsub, 0L);
+#ifdef _THREAD_SAFE
+ pthread_mutex_unlock(&lcl_mutex);
+#endif
+ return(mktime_return_value);
+}
+
+#ifdef STD_INSPIRED
+
+time_t
+timelocal(tmp)
+struct tm * const tmp;
+{
+ tmp->tm_isdst = -1; /* in case it wasn't initialized */
+ return mktime(tmp);
+}
+
+time_t
+timegm(tmp)
+struct tm * const tmp;
+{
+ tmp->tm_isdst = 0;
+ return time1(tmp, gmtsub, 0L);
+}
+
+time_t
+timeoff(tmp, offset)
+struct tm * const tmp;
+const long offset;
+{
+ tmp->tm_isdst = 0;
+ return time1(tmp, gmtsub, offset);
+}
+
+#endif /* defined STD_INSPIRED */
+
+#ifdef CMUCS
+
+/*
+** The following is supplied for compatibility with
+** previous versions of the CMUCS runtime library.
+*/
+
+long
+gtime(tmp)
+struct tm * const tmp;
+{
+ const time_t t = mktime(tmp);
+
+ if (t == WRONG)
+ return -1;
+ return t;
+}
+
+#endif /* defined CMUCS */
+
+/*
+** XXX--is the below the right way to conditionalize??
+*/
+
+#ifdef STD_INSPIRED
+
+/*
+** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
+** shall correspond to "Wed Dec 31 23:59:59 GMT 1986", which
+** is not the case if we are accounting for leap seconds.
+** So, we provide the following conversion routines for use
+** when exchanging timestamps with POSIX conforming systems.
+*/
+
+static long
+leapcorr(timep)
+time_t * timep;
+{
+ register struct state * sp;
+ register struct lsinfo * lp;
+ register int i;
+
+ sp = lclptr;
+ i = sp->leapcnt;
+ while (--i >= 0) {
+ lp = &sp->lsis[i];
+ if (*timep >= lp->ls_trans)
+ return lp->ls_corr;
+ }
+ return 0;
+}
+
+time_t
+time2posix(t)
+time_t t;
+{
+ tzset();
+ return t - leapcorr(&t);
+}
+
+time_t
+posix2time(t)
+time_t t;
+{
+ time_t x;
+ time_t y;
+
+ tzset();
+ /*
+ ** For a positive leap second hit, the result
+ ** is not unique. For a negative leap second
+ ** hit, the corresponding time doesn't exist,
+ ** so we return an adjacent second.
+ */
+ x = t + leapcorr(&t);
+ y = x - leapcorr(&x);
+ if (y < t) {
+ do {
+ x++;
+ y = x - leapcorr(&x);
+ } while (y < t);
+ if (t != y)
+ return x - 1;
+ } else if (y > t) {
+ do {
+ --x;
+ y = x - leapcorr(&x);
+ } while (y > t);
+ if (t != y)
+ return x + 1;
+ }
+ return x;
+}
+
+#endif /* defined STD_INSPIRED */
diff --git a/lib/libc/stdtime/private.h b/lib/libc/stdtime/private.h
new file mode 100644
index 0000000..d8fa906
--- /dev/null
+++ b/lib/libc/stdtime/private.h
@@ -0,0 +1,218 @@
+#ifndef PRIVATE_H
+
+#define PRIVATE_H
+/*
+** This file is in the public domain, so clarified as of
+** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
+*/
+
+/* Stuff moved from Makefile.inc to reduce clutter */
+#ifndef TM_GMTOFF
+#define TM_GMTOFF tm_gmtoff
+#define TM_ZONE tm_zone
+#define STD_INSPIRED 1
+#define PCTS 1
+#define HAVE_LONG_DOUBLE 1
+#define HAVE_STRERROR 1
+#define HAVE_UNISTD_H 1
+#define LOCALE_HOME _PATH_LOCALE
+#define TZDIR "/usr/share/zoneinfo"
+#endif /* ndef TM_GMTOFF */
+
+/*
+** This header is for use ONLY with the time conversion code.
+** There is no guarantee that it will remain unchanged,
+** or that it will remain at all.
+** Do NOT copy it to any system include directory.
+** Thank you!
+*/
+
+/*
+** ID
+*/
+
+#ifndef lint
+#ifndef NOID
+/*
+static char privatehid[] = "@(#)private.h 7.43";
+*/
+#endif /* !defined NOID */
+#endif /* !defined lint */
+
+/*
+** Defaults for preprocessor symbols.
+** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'.
+*/
+
+#ifndef HAVE_ADJTIME
+#define HAVE_ADJTIME 1
+#endif /* !defined HAVE_ADJTIME */
+
+#ifndef HAVE_GETTEXT
+#define HAVE_GETTEXT 0
+#endif /* !defined HAVE_GETTEXT */
+
+#ifndef HAVE_SETTIMEOFDAY
+#define HAVE_SETTIMEOFDAY 3
+#endif /* !defined HAVE_SETTIMEOFDAY */
+
+#ifndef HAVE_STRERROR
+#define HAVE_STRERROR 0
+#endif /* !defined HAVE_STRERROR */
+
+#ifndef HAVE_UNISTD_H
+#define HAVE_UNISTD_H 1
+#endif /* !defined HAVE_UNISTD_H */
+
+#ifndef HAVE_UTMPX_H
+#define HAVE_UTMPX_H 0
+#endif /* !defined HAVE_UTMPX_H */
+
+#ifndef LOCALE_HOME
+#define LOCALE_HOME "/usr/lib/locale"
+#endif /* !defined LOCALE_HOME */
+
+/*
+** Nested includes
+*/
+
+#include "sys/types.h" /* for time_t */
+#include "stdio.h"
+#include "errno.h"
+#include "string.h"
+#include "limits.h" /* for CHAR_BIT */
+#include "time.h"
+#include "stdlib.h"
+
+#if HAVE_GETTEXT - 0
+#include "libintl.h"
+#endif /* HAVE_GETTEXT - 0 */
+
+#if HAVE_UNISTD_H - 0
+#include "unistd.h" /* for F_OK and R_OK */
+#endif /* HAVE_UNISTD_H - 0 */
+
+#if !(HAVE_UNISTD_H - 0)
+#ifndef F_OK
+#define F_OK 0
+#endif /* !defined F_OK */
+#ifndef R_OK
+#define R_OK 4
+#endif /* !defined R_OK */
+#endif /* !(HAVE_UNISTD_H - 0) */
+
+/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
+#define is_digit(c) ((unsigned)(c) - '0' <= 9)
+
+/*
+** Workarounds for compilers/systems.
+*/
+
+#ifndef P
+#ifdef __STDC__
+#define P(x) x
+#endif /* defined __STDC__ */
+#ifndef __STDC__
+#define P(x) ()
+#endif /* !defined __STDC__ */
+#endif /* !defined P */
+
+/*
+** SunOS 4.1.1 headers lack FILENAME_MAX.
+*/
+
+#ifndef FILENAME_MAX
+
+#ifndef MAXPATHLEN
+#ifdef unix
+#include "sys/param.h"
+#endif /* defined unix */
+#endif /* !defined MAXPATHLEN */
+
+#ifdef MAXPATHLEN
+#define FILENAME_MAX MAXPATHLEN
+#endif /* defined MAXPATHLEN */
+#ifndef MAXPATHLEN
+#define FILENAME_MAX 1024 /* Pure guesswork */
+#endif /* !defined MAXPATHLEN */
+
+#endif /* !defined FILENAME_MAX */
+
+/*
+** Finally, some convenience items.
+*/
+
+#ifndef TRUE
+#define TRUE 1
+#endif /* !defined TRUE */
+
+#ifndef FALSE
+#define FALSE 0
+#endif /* !defined FALSE */
+
+#ifndef TYPE_BIT
+#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
+#endif /* !defined TYPE_BIT */
+
+#ifndef TYPE_SIGNED
+#define TYPE_SIGNED(type) (((type) -1) < 0)
+#endif /* !defined TYPE_SIGNED */
+
+#ifndef INT_STRLEN_MAXIMUM
+/*
+** 302 / 1000 is log10(2.0) rounded up.
+** Subtract one for the sign bit if the type is signed;
+** add one for integer division truncation;
+** add one more for a minus sign if the type is signed.
+*/
+#define INT_STRLEN_MAXIMUM(type) \
+ ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 100 + 1 + TYPE_SIGNED(type))
+#endif /* !defined INT_STRLEN_MAXIMUM */
+
+/*
+** INITIALIZE(x)
+*/
+
+#ifndef GNUC_or_lint
+#ifdef lint
+#define GNUC_or_lint
+#endif /* defined lint */
+#ifndef lint
+#ifdef __GNUC__
+#define GNUC_or_lint
+#endif /* defined __GNUC__ */
+#endif /* !defined lint */
+#endif /* !defined GNUC_or_lint */
+
+#ifndef INITIALIZE
+#ifdef GNUC_or_lint
+#define INITIALIZE(x) ((x) = 0)
+#endif /* defined GNUC_or_lint */
+#ifndef GNUC_or_lint
+#define INITIALIZE(x)
+#endif /* !defined GNUC_or_lint */
+#endif /* !defined INITIALIZE */
+
+/*
+** For the benefit of GNU folk...
+** `_(MSGID)' uses the current locale's message library string for MSGID.
+** The default is to use gettext if available, and use MSGID otherwise.
+*/
+
+#ifndef _
+#if HAVE_GETTEXT - 0
+#define _(msgid) gettext(msgid)
+#else /* !(HAVE_GETTEXT - 0) */
+#define _(msgid) msgid
+#endif /* !(HAVE_GETTEXT - 0) */
+#endif /* !defined _ */
+
+#ifndef TZ_DOMAIN
+#define TZ_DOMAIN "tz"
+#endif /* !defined TZ_DOMAIN */
+
+/*
+** UNIX was a registered trademark of UNIX System Laboratories in 1993.
+*/
+
+#endif /* !defined PRIVATE_H */
diff --git a/lib/libc/stdtime/strftime.3 b/lib/libc/stdtime/strftime.3
new file mode 100644
index 0000000..c4d2d8c
--- /dev/null
+++ b/lib/libc/stdtime/strftime.3
@@ -0,0 +1,254 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strftime.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd October 4, 1997
+.Dt STRFTIME 3
+.Os
+.Sh NAME
+.Nm strftime
+.Nd format date and time
+.Sh SYNOPSIS
+.Fd #include <time.h>
+.Ft size_t
+.Fn strftime "char *buf" "size_t maxsize" "const char *format" "const struct tm *timeptr"
+.Sh DESCRIPTION
+The
+.Fn strftime
+function formats the information from
+.Fa timeptr
+into the buffer
+.Fa buf
+according to the string pointed to by
+.Fa format .
+.Pp
+The
+.Fa format
+string consists of zero or more conversion specifications and
+ordinary characters.
+All ordinary characters are copied directly into the buffer.
+A conversion specification consists of a percent sign
+.Dq Ql %
+and one other character.
+.Pp
+No more than
+.Fa maxsize
+characters will be placed into the array.
+If the total number of resulting characters, including the terminating
+NUL character, is not more than
+.Fa maxsize ,
+.Fn strftime
+returns the number of characters in the array, not counting the
+terminating NUL.
+Otherwise, zero is returned and the buffer contents is indeterminate.
+.Pp
+The conversion specifications are copied to the buffer after expansion
+as follows:-
+.Bl -tag -width "xxxx"
+.It Cm \&%A
+is replaced by national representation of the full weekday name.
+.It Cm %a
+is replaced by national representation of
+the abbreviated weekday name, where the abbreviation
+is the first three characters.
+.It Cm \&%B
+is replaced by national representation of the full month name.
+.It Cm %b
+is replaced by national representation of
+the abbreviated month name, where the abbreviation is
+the first three characters.
+.It Cm \&%C
+is replaced by (year / 100) as decimal number; single
+digits are preceded by a zero.
+.It Cm %c
+is replaced by national representation of time and date
+(the format is similar with produced by
+.Xr asctime 3 ) .
+.It Cm \&%D
+is equivalent to
+.Dq Li %m/%d/%y .
+.It Cm %d
+is replaced by the day of the month as a decimal number (01-31).
+.It Cm \&%E* Cm \&%O*
+POSIX locale extensions.
+The sequences
+%Ec %EC %Ex %EX %Ey %EY
+%Od %Oe %OH %OI %Om %OM
+%OS %Ou %OU %OV %Ow %OW %Oy
+are supposed to provide alternate
+representations.
+.Pp
+Additionly %Ef implemented to represent short month name / day
+order of the date, %EF to represent long month name / day
+order
+and %OB to represent alternative months names
+(used standalone, without day mentioned).
+.It Cm %e
+is replaced by the day of month as a decimal number (1-31); single
+digits are preceded by a blank.
+.It Cm \&%G
+is replaced by a year as a decimal number with century.
+This year is the one that contains the greater part of
+the week (Monday as the first day of the week).
+.It Cm %g
+is replaced by the same year as in
+.Dq Li %G ,
+but as a decimal number without century (00-99).
+.It Cm \&%H
+is replaced by the hour (24-hour clock) as a decimal number (00-23).
+.It Cm %h
+the same as %b.
+.It Cm \&%I
+is replaced by the hour (12-hour clock) as a decimal number (01-12).
+.It Cm %j
+is replaced by the day of the year as a decimal number (001-366).
+.It Cm %k
+is replaced by the hour (24-hour clock) as a decimal number (0-23);
+single digits are preceded by a blank.
+.It Cm %l
+is replaced by the hour (12-hour clock) as a decimal number (1-12);
+single digits are preceded by a blank.
+.It Cm \&%M
+is replaced by the minute as a decimal number (00-59).
+.It Cm %m
+is replaced by the month as a decimal number (01-12).
+.It Cm %n
+is replaced by a newline.
+.It Cm \&%O*
+the same as %E*.
+.It Cm %p
+is replaced by national representation of either
+"ante meridiem"
+or
+"post meridiem"
+as appropriate.
+.It Cm \&%R
+is equivalent to
+.Dq Li %H:%M .
+.It Cm %r
+is equivalent to
+.Dq Li %I:%M:%S %p .
+.It Cm \&%S
+is replaced by the second as a decimal number (00-60).
+.It Cm %s
+is replaced by the number of seconds since the Epoch, UTC (see
+.Xr mktime 3 ) .
+.It Cm \&%T
+is equivalent to
+.Dq Li %H:%M:%S .
+.It Cm %t
+is replaced by a tab.
+.It Cm \&%U
+is replaced by the week number of the year (Sunday as the first day of
+the week) as a decimal number (00-53).
+.It Cm %u
+is replaced by the weekday (Monday as the first day of the week)
+as a decimal number (1-7).
+.It Cm \&%V
+is replaced by the week number of the year (Monday as the first day of
+the week) as a decimal number (01-53). If the week containing January
+1 has four or more days in the new year, then it is week 1; otherwise
+it is the last week of the previous year, and the next week is week 1.
+.It Cm %v
+is equivalent to
+.Dq Li %e-%b-%Y .
+.It Cm \&%W
+is replaced by the week number of the year (Monday as the first day of
+the week) as a decimal number (00-53).
+.It Cm %w
+is replaced by the weekday (Sunday as the first day of the week)
+as a decimal number (0-6).
+.It Cm \&%X
+is replaced by national representation of the time.
+.It Cm %x
+is replaced by national representation of the date.
+.It Cm \&%Y
+is replaced by the year with century as a decimal number.
+.It Cm %y
+is replaced by the year without century as a decimal number (00-99).
+.It Cm \&%Z
+is replaced by the time zone name.
+.It Cm %+
+is replaced by national representation of the date and time
+(the format is similar to that produced by
+.Xr date 1 ) .
+.It Cm %%
+is replaced by
+.Ql % .
+.El
+.Sh SEE ALSO
+.Xr date 1 ,
+.Xr printf 1 ,
+.Xr ctime 3 ,
+.Xr printf 3 ,
+.Xr strptime 3
+.Sh STANDARDS
+The
+.Fn strftime
+function
+conforms to
+.St -ansiC
+with a lot of extensions including
+.Ql %C ,
+.Ql %D ,
+.Ql %E* ,
+.Ql %e ,
+.Ql %G ,
+.Ql %g ,
+.Ql %h ,
+.Ql %k ,
+.Ql %l ,
+.Ql %n ,
+.Ql %O* ,
+.Ql \&%R ,
+.Ql %r ,
+.Ql %s ,
+.Ql \&%T ,
+.Ql %t ,
+.Ql %u ,
+.Ql \&%V ,
+.Ql %+ .
+
+The peculiar week number and year in the replacements of
+.Ql %G ,
+.Ql %g
+and
+.Ql \&%V
+are defined in ISO 8601: 1988.
+
+.Sh BUGS
+There is no conversion specification for the phase of the moon.
diff --git a/lib/libc/stdtime/strftime.c b/lib/libc/stdtime/strftime.c
new file mode 100644
index 0000000..9aa891f
--- /dev/null
+++ b/lib/libc/stdtime/strftime.c
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifdef LIBC_RCS
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+
+#ifndef lint
+#ifndef NOID
+static const char elsieid[] = "@(#)strftime.c 7.38";
+/*
+** Based on the UCB version with the ID appearing below.
+** This is ANSIish only when "multibyte character == plain character".
+*/
+#endif /* !defined NOID */
+#endif /* !defined lint */
+
+#include "private.h"
+
+#ifndef LIBC_SCCS
+#ifndef lint
+static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89";
+#endif /* !defined lint */
+#endif /* !defined LIBC_SCCS */
+
+#include "tzfile.h"
+#include <fcntl.h>
+#include <sys/stat.h>
+#include "timelocal.h"
+
+static char * _add P((const char *, char *, const char *));
+static char * _conv P((int, const char *, char *, const char *));
+static char * _fmt P((const char *, const struct tm *, char *, const char *));
+
+size_t strftime P((char *, size_t, const char *, const struct tm *));
+
+extern char * tzname[];
+
+size_t
+strftime(s, maxsize, format, t)
+ char *const s;
+ const size_t maxsize;
+ const char *const format;
+ const struct tm *const t;
+{
+ char *p;
+
+ tzset();
+ p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize);
+ if (p == s + maxsize)
+ return 0;
+ *p = '\0';
+ return p - s;
+}
+
+static char *
+_fmt(format, t, pt, ptlim)
+ const char *format;
+ const struct tm *const t;
+ char *pt;
+ const char *const ptlim;
+{
+ int Ealternative, Oalternative;
+
+ for ( ; *format; ++format) {
+ if (*format == '%') {
+ Ealternative = 0;
+ Oalternative = 0;
+label:
+ switch (*++format) {
+ case '\0':
+ --format;
+ break;
+ case 'A':
+ pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ?
+ "?" : Locale->weekday[t->tm_wday],
+ pt, ptlim);
+ continue;
+ case 'a':
+ pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ?
+ "?" : Locale->wday[t->tm_wday],
+ pt, ptlim);
+ continue;
+ case 'B':
+ pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ?
+ "?" : (Oalternative ? Locale->alt_month :
+ Locale->month)[t->tm_mon],
+ pt, ptlim);
+ continue;
+ case 'b':
+ case 'h':
+ pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ?
+ "?" : Locale->mon[t->tm_mon],
+ pt, ptlim);
+ continue;
+ case 'C':
+ /*
+ ** %C used to do a...
+ ** _fmt("%a %b %e %X %Y", t);
+ ** ...whereas now POSIX 1003.2 calls for
+ ** something completely different.
+ ** (ado, 5/24/93)
+ */
+ pt = _conv((t->tm_year + TM_YEAR_BASE) / 100,
+ "%02d", pt, ptlim);
+ continue;
+ case 'c':
+ pt = _fmt(Locale->c_fmt, t, pt, ptlim);
+ continue;
+ case 'D':
+ pt = _fmt("%m/%d/%y", t, pt, ptlim);
+ continue;
+ case 'd':
+ pt = _conv(t->tm_mday, "%02d", pt, ptlim);
+ continue;
+ case 'E':
+ if (Ealternative || Oalternative)
+ break;
+ Ealternative++;
+ goto label;
+ case 'O':
+ /*
+ ** POSIX locale extensions, a la
+ ** Arnold Robbins' strftime version 3.0.
+ ** The sequences
+ ** %Ec %EC %Ex %EX %Ey %EY
+ ** %Od %oe %OH %OI %Om %OM
+ ** %OS %Ou %OU %OV %Ow %OW %Oy
+ ** are supposed to provide alternate
+ ** representations.
+ ** (ado, 5/24/93)
+ **
+ ** FreeBSD extensions
+ ** %OB %Ef %EF
+ */
+ if (Ealternative || Oalternative)
+ break;
+ Oalternative++;
+ goto label;
+ case 'e':
+ pt = _conv(t->tm_mday, "%2d", pt, ptlim);
+ continue;
+ case 'f':
+ if (!Ealternative)
+ break;
+ pt = _fmt(Locale->Ef_fmt, t, pt, ptlim);
+ continue;
+ case 'F':
+ if (!Ealternative)
+ break;
+ pt = _fmt(Locale->EF_fmt, t, pt, ptlim);
+ continue;
+ case 'H':
+ pt = _conv(t->tm_hour, "%02d", pt, ptlim);
+ continue;
+ case 'I':
+ pt = _conv((t->tm_hour % 12) ?
+ (t->tm_hour % 12) : 12,
+ "%02d", pt, ptlim);
+ continue;
+ case 'j':
+ pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim);
+ continue;
+ case 'k':
+ /*
+ ** This used to be...
+ ** _conv(t->tm_hour % 12 ?
+ ** t->tm_hour % 12 : 12, 2, ' ');
+ ** ...and has been changed to the below to
+ ** match SunOS 4.1.1 and Arnold Robbins'
+ ** strftime version 3.0. That is, "%k" and
+ ** "%l" have been swapped.
+ ** (ado, 5/24/93)
+ */
+ pt = _conv(t->tm_hour, "%2d", pt, ptlim);
+ continue;
+#ifdef KITCHEN_SINK
+ case 'K':
+ /*
+ ** After all this time, still unclaimed!
+ */
+ pt = _add("kitchen sink", pt, ptlim);
+ continue;
+#endif /* defined KITCHEN_SINK */
+ case 'l':
+ /*
+ ** This used to be...
+ ** _conv(t->tm_hour, 2, ' ');
+ ** ...and has been changed to the below to
+ ** match SunOS 4.1.1 and Arnold Robbin's
+ ** strftime version 3.0. That is, "%k" and
+ ** "%l" have been swapped.
+ ** (ado, 5/24/93)
+ */
+ pt = _conv((t->tm_hour % 12) ?
+ (t->tm_hour % 12) : 12,
+ "%2d", pt, ptlim);
+ continue;
+ case 'M':
+ pt = _conv(t->tm_min, "%02d", pt, ptlim);
+ continue;
+ case 'm':
+ pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim);
+ continue;
+ case 'n':
+ pt = _add("\n", pt, ptlim);
+ continue;
+ case 'p':
+ pt = _add((t->tm_hour >= 12) ?
+ Locale->pm :
+ Locale->am,
+ pt, ptlim);
+ continue;
+ case 'R':
+ pt = _fmt("%H:%M", t, pt, ptlim);
+ continue;
+ case 'r':
+ pt = _fmt("%I:%M:%S %p", t, pt, ptlim);
+ continue;
+ case 'S':
+ pt = _conv(t->tm_sec, "%02d", pt, ptlim);
+ continue;
+ case 's':
+ {
+ struct tm tm;
+ char buf[INT_STRLEN_MAXIMUM(
+ time_t) + 1];
+ time_t mkt;
+
+ tm = *t;
+ mkt = mktime(&tm);
+ if (TYPE_SIGNED(time_t))
+ (void) sprintf(buf, "%ld",
+ (long) mkt);
+ else (void) sprintf(buf, "%lu",
+ (unsigned long) mkt);
+ pt = _add(buf, pt, ptlim);
+ }
+ continue;
+ case 'T':
+ pt = _fmt("%H:%M:%S", t, pt, ptlim);
+ continue;
+ case 't':
+ pt = _add("\t", pt, ptlim);
+ continue;
+ case 'U':
+ pt = _conv((t->tm_yday + 7 - t->tm_wday) / 7,
+ "%02d", pt, ptlim);
+ continue;
+ case 'u':
+ /*
+ ** From Arnold Robbins' strftime version 3.0:
+ ** "ISO 8601: Weekday as a decimal number
+ ** [1 (Monday) - 7]"
+ ** (ado, 5/24/93)
+ */
+ pt = _conv((t->tm_wday == 0) ? 7 : t->tm_wday,
+ "%d", pt, ptlim);
+ continue;
+ case 'V': /* ISO 8601 week number */
+ case 'G': /* ISO 8601 year (four digits) */
+ case 'g': /* ISO 8601 year (two digits) */
+/*
+** From Arnold Robbins' strftime version 3.0: "the week number of the
+** year (the first Monday as the first day of week 1) as a decimal number
+** (01-53)."
+** (ado, 1993-05-24)
+**
+** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
+** "Week 01 of a year is per definition the first week which has the
+** Thursday in this year, which is equivalent to the week which contains
+** the fourth day of January. In other words, the first week of a new year
+** is the week which has the majority of its days in the new year. Week 01
+** might also contain days from the previous year and the week before week
+** 01 of a year is the last week (52 or 53) of the previous year even if
+** it contains days from the new year. A week starts with Monday (day 1)
+** and ends with Sunday (day 7). For example, the first week of the year
+** 1997 lasts from 1996-12-30 to 1997-01-05..."
+** (ado, 1996-01-02)
+*/
+ {
+ int year;
+ int yday;
+ int wday;
+ int w;
+
+ year = t->tm_year + TM_YEAR_BASE;
+ yday = t->tm_yday;
+ wday = t->tm_wday;
+ for ( ; ; ) {
+ int len;
+ int bot;
+ int top;
+
+ len = isleap(year) ?
+ DAYSPERLYEAR :
+ DAYSPERNYEAR;
+ /*
+ ** What yday (-3 ... 3) does
+ ** the ISO year begin on?
+ */
+ bot = ((yday + 11 - wday) %
+ DAYSPERWEEK) - 3;
+ /*
+ ** What yday does the NEXT
+ ** ISO year begin on?
+ */
+ top = bot -
+ (len % DAYSPERWEEK);
+ if (top < -3)
+ top += DAYSPERWEEK;
+ top += len;
+ if (yday >= top) {
+ ++year;
+ w = 1;
+ break;
+ }
+ if (yday >= bot) {
+ w = 1 + ((yday - bot) /
+ DAYSPERWEEK);
+ break;
+ }
+ --year;
+ yday += isleap(year) ?
+ DAYSPERLYEAR :
+ DAYSPERNYEAR;
+ }
+#ifdef XPG4_1994_04_09
+ if ((w == 52
+ && t->tm_mon == TM_JANUARY)
+ || (w == 1
+ && t->tm_mon == TM_DECEMBER))
+ w = 53;
+#endif /* defined XPG4_1994_04_09 */
+ if (*format == 'V')
+ pt = _conv(w, "%02d",
+ pt, ptlim);
+ else if (*format == 'g') {
+ pt = _conv(year % 100, "%02d",
+ pt, ptlim);
+ } else pt = _conv(year, "%04d",
+ pt, ptlim);
+ }
+ continue;
+ case 'v':
+ /*
+ ** From Arnold Robbins' strftime version 3.0:
+ ** "date as dd-bbb-YYYY"
+ ** (ado, 5/24/93)
+ */
+ pt = _fmt("%e-%b-%Y", t, pt, ptlim);
+ continue;
+ case 'W':
+ pt = _conv((t->tm_yday + 7 -
+ (t->tm_wday ?
+ (t->tm_wday - 1) : 6)) / 7,
+ "%02d", pt, ptlim);
+ continue;
+ case 'w':
+ pt = _conv(t->tm_wday, "%d", pt, ptlim);
+ continue;
+ case 'X':
+ pt = _fmt(Locale->X_fmt, t, pt, ptlim);
+ continue;
+ case 'x':
+ pt = _fmt(Locale->x_fmt, t, pt, ptlim);
+ continue;
+ case 'y':
+ pt = _conv((t->tm_year + TM_YEAR_BASE) % 100,
+ "%02d", pt, ptlim);
+ continue;
+ case 'Y':
+ pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d",
+ pt, ptlim);
+ continue;
+ case 'Z':
+ if (t->tm_zone != NULL)
+ pt = _add(t->tm_zone, pt, ptlim);
+ else
+ if (t->tm_isdst == 0 || t->tm_isdst == 1) {
+ pt = _add(tzname[t->tm_isdst],
+ pt, ptlim);
+ } else pt = _add("?", pt, ptlim);
+ continue;
+ case '+':
+ pt = _fmt(Locale->date_fmt, t, pt, ptlim);
+ continue;
+ case '%':
+ /*
+ * X311J/88-090 (4.12.3.5): if conversion char is
+ * undefined, behavior is undefined. Print out the
+ * character itself as printf(3) also does.
+ */
+ default:
+ break;
+ }
+ }
+ if (pt == ptlim)
+ break;
+ *pt++ = *format;
+ }
+ return pt;
+}
+
+static char *
+_conv(n, format, pt, ptlim)
+ const int n;
+ const char *const format;
+ char *const pt;
+ const char *const ptlim;
+{
+ char buf[INT_STRLEN_MAXIMUM(int) + 1];
+
+ (void) sprintf(buf, format, n);
+ return _add(buf, pt, ptlim);
+}
+
+static char *
+_add(str, pt, ptlim)
+ const char *str;
+ char *pt;
+ const char *const ptlim;
+{
+ while (pt < ptlim && (*pt = *str++) != '\0')
+ ++pt;
+ return pt;
+}
diff --git a/lib/libc/stdtime/strptime.3 b/lib/libc/stdtime/strptime.3
new file mode 100644
index 0000000..c93dc89
--- /dev/null
+++ b/lib/libc/stdtime/strptime.3
@@ -0,0 +1,139 @@
+.\"
+.\" Copyright (c) 1997 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" "
+.Dd May 8, 1997
+.Dt STRPTIME 3
+.Os
+.Sh NAME
+.Nm strptime
+.Nd parse date and time string
+.Sh SYNOPSIS
+.Fd #include <time.h>
+.Ft char *
+.Fn strptime "const char *buf" "const char *format" "struct tm *timeptr"
+.Sh DESCRIPTION
+The
+.Fn strptime
+function parses the string in the buffer
+.Fa buf
+according to the string pointed to by
+.Fa format ,
+and fills in the elements of the structure pointed to by
+.Fa timeptr .
+The resulting values will be relative to the local time zone.
+Thus, it can be considered the reverse operation of
+.Xr strftime 3 .
+.Pp
+The
+.Fa format
+string consists of zero or more conversion specifications and
+ordinary characters.
+All ordinary characters are matched exactly with the buffer, where
+white space in the format string will match any amount of white space
+in the buffer.
+All conversion specifications are identical to those described in
+.Xr strftime 3 .
+.Pp
+Two-digit year values, including formats
+.Fa %y
+and
+.Fa %D ,
+are now interpreted as beginning at 1969 per POSIX requirements.
+Years 69-00 are interpreted in the 20th century (1969-2000), years
+01-68 in the 21st century (2001-2068).
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn strptime
+returns the pointer to the first character in
+.Fa buf
+that has not been required to satisfy the specified conversions in
+.Fa format .
+It returns
+.Dv NULL
+if one of the conversions failed.
+.Sh SEE ALSO
+.Xr date 1 ,
+.Xr scanf 3 ,
+.Xr strftime 3
+.Sh AUTHORS
+The
+.Fn strptime
+function has been contributed by Powerdog Industries.
+.Pp
+This man page was written by
+.ie t J\(:org Wunsch.
+.el Joerg Wunsch.
+.Sh HISTORY
+The
+.Fn strptime
+function appeared in
+.Fx 3.0 .
+.Pp
+.Sh BUGS
+Both the
+.Fa %e
+and
+.Fa %l
+format specifiers may incorrectly scan one too many digits
+if the intended values comprise only a single digit
+and that digit is followed immediately by another digit.
+Both specifiers accept zero-padded values,
+even though they are both defined as taking unpadded values.
+.Pp
+The
+.Fa %p
+format specifier has no effect unless it is parsed
+.Em after
+hour-related specifiers.
+Specifying
+.Fa %l
+without
+.Fa %p
+will produce undefined results.
+Note that 12AM
+.Pq ante meridiem
+is taken as midnight
+and 12PM
+.Pq post meridiem
+is taken as noon.
+.Pp
+The
+.Fa %U
+and
+.Fa %W
+format specifiers accept any value within the range 00 to 53
+without validating against other values supplied (like month
+or day of the year, for example).
+.Pp
+The
+.Fa %Z
+format specifier only accepts time zone abbreviations of the local time zone,
+or the value "GMT".
+This limitation is because of ambiguity due to of the over loading of time
+zone abbreviations. One such example is
+.Fa EST
+which is both Eastern Standard Time and Eastern Australia Summer Time.
diff --git a/lib/libc/stdtime/strptime.c b/lib/libc/stdtime/strptime.c
new file mode 100644
index 0000000..ef1e09d
--- /dev/null
+++ b/lib/libc/stdtime/strptime.c
@@ -0,0 +1,543 @@
+/*
+ * Powerdog Industries kindly requests feedback from anyone modifying
+ * this function:
+ *
+ * Date: Thu, 05 Jun 1997 23:17:17 -0400
+ * From: Kevin Ruddy <kevin.ruddy@powerdog.com>
+ * To: James FitzGibbon <james@nexis.net>
+ * Subject: Re: Use of your strptime(3) code (fwd)
+ *
+ * The reason for the "no mod" clause was so that modifications would
+ * come back and we could integrate them and reissue so that a wider
+ * audience could use it (thereby spreading the wealth). This has
+ * made it possible to get strptime to work on many operating systems.
+ * I'm not sure why that's "plain unacceptable" to the FreeBSD team.
+ *
+ * Anyway, you can change it to "with or without modification" as
+ * you see fit. Enjoy.
+ *
+ * Kevin Ruddy
+ * Powerdog Industries, Inc.
+ */
+/*
+ * Copyright (c) 1994 Powerdog Industries. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgement:
+ * This product includes software developed by Powerdog Industries.
+ * 4. The name of Powerdog Industries may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE POWERDOG INDUSTRIES BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef LIBC_RCS
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+
+#ifndef lint
+#ifndef NOID
+static char copyright[] =
+"@(#) Copyright (c) 1994 Powerdog Industries. All rights reserved.";
+static char sccsid[] = "@(#)strptime.c 0.1 (Powerdog) 94/03/27";
+#endif /* !defined NOID */
+#endif /* not lint */
+
+#include <time.h>
+#include <ctype.h>
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
+#include "timelocal.h"
+
+static char * _strptime(const char *, const char *, struct tm *);
+
+#ifdef _THREAD_SAFE
+static struct pthread_mutex _gotgmt_mutexd = PTHREAD_MUTEX_STATIC_INITIALIZER;
+static pthread_mutex_t gotgmt_mutex = &_gotgmt_mutexd;
+#endif
+static int got_GMT;
+
+#define asizeof(a) (sizeof (a) / sizeof ((a)[0]))
+
+static char *
+_strptime(const char *buf, const char *fmt, struct tm *tm)
+{
+ char c;
+ const char *ptr;
+ int i,
+ len;
+ int Ealternative, Oalternative;
+
+ ptr = fmt;
+ while (*ptr != 0) {
+ if (*buf == 0)
+ break;
+
+ c = *ptr++;
+
+ if (c != '%') {
+ if (isspace((unsigned char)c))
+ while (*buf != 0 && isspace((unsigned char)*buf))
+ buf++;
+ else if (c != *buf++)
+ return 0;
+ continue;
+ }
+
+ Ealternative = 0;
+ Oalternative = 0;
+label:
+ c = *ptr++;
+ switch (c) {
+ case 0:
+ case '%':
+ if (*buf++ != '%')
+ return 0;
+ break;
+
+ case '+':
+ buf = _strptime(buf, Locale->date_fmt, tm);
+ if (buf == 0)
+ return 0;
+ break;
+
+ case 'C':
+ if (!isdigit((unsigned char)*buf))
+ return 0;
+
+ /* XXX This will break for 3-digit centuries. */
+ len = 2;
+ for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
+ i *= 10;
+ i += *buf - '0';
+ len--;
+ }
+ if (i < 19)
+ return 0;
+
+ tm->tm_year = i * 100 - 1900;
+ break;
+
+ case 'c':
+ buf = _strptime(buf, Locale->c_fmt, tm);
+ if (buf == 0)
+ return 0;
+ break;
+
+ case 'D':
+ buf = _strptime(buf, "%m/%d/%y", tm);
+ if (buf == 0)
+ return 0;
+ break;
+
+ case 'E':
+ if (Ealternative || Oalternative)
+ break;
+ Ealternative++;
+ goto label;
+
+ case 'O':
+ if (Ealternative || Oalternative)
+ break;
+ Oalternative++;
+ goto label;
+
+ case 'F':
+ case 'f':
+ if (!Ealternative)
+ break;
+ buf = _strptime(buf, (c == 'f') ? Locale->Ef_fmt : Locale->EF_fmt, tm);
+ if (buf == 0)
+ return 0;
+ break;
+
+ case 'R':
+ buf = _strptime(buf, "%H:%M", tm);
+ if (buf == 0)
+ return 0;
+ break;
+
+ case 'r':
+ buf = _strptime(buf, "%I:%M:%S %p", tm);
+ if (buf == 0)
+ return 0;
+ break;
+
+ case 'T':
+ buf = _strptime(buf, "%H:%M:%S", tm);
+ if (buf == 0)
+ return 0;
+ break;
+
+ case 'X':
+ buf = _strptime(buf, Locale->X_fmt, tm);
+ if (buf == 0)
+ return 0;
+ break;
+
+ case 'x':
+ buf = _strptime(buf, Locale->x_fmt, tm);
+ if (buf == 0)
+ return 0;
+ break;
+
+ case 'j':
+ if (!isdigit((unsigned char)*buf))
+ return 0;
+
+ len = 3;
+ for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
+ i *= 10;
+ i += *buf - '0';
+ len--;
+ }
+ if (i < 1 || i > 366)
+ return 0;
+
+ tm->tm_yday = i - 1;
+ break;
+
+ case 'M':
+ case 'S':
+ if (*buf == 0 || isspace((unsigned char)*buf))
+ break;
+
+ if (!isdigit((unsigned char)*buf))
+ return 0;
+
+ len = 2;
+ for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
+ i *= 10;
+ i += *buf - '0';
+ len--;
+ }
+
+ if (c == 'M') {
+ if (i > 59)
+ return 0;
+ tm->tm_min = i;
+ } else {
+ if (i > 60)
+ return 0;
+ tm->tm_sec = i;
+ }
+
+ if (*buf != 0 && isspace((unsigned char)*buf))
+ while (*ptr != 0 && !isspace((unsigned char)*ptr))
+ ptr++;
+ break;
+
+ case 'H':
+ case 'I':
+ case 'k':
+ case 'l':
+ /*
+ * Of these, %l is the only specifier explicitly
+ * documented as not being zero-padded. However,
+ * there is no harm in allowing zero-padding.
+ *
+ * XXX The %l specifier may gobble one too many
+ * digits if used incorrectly.
+ */
+ if (!isdigit((unsigned char)*buf))
+ return 0;
+
+ len = 2;
+ for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
+ i *= 10;
+ i += *buf - '0';
+ len--;
+ }
+ if (c == 'H' || c == 'k') {
+ if (i > 23)
+ return 0;
+ } else if (i > 12)
+ return 0;
+
+ tm->tm_hour = i;
+
+ if (*buf != 0 && isspace((unsigned char)*buf))
+ while (*ptr != 0 && !isspace((unsigned char)*ptr))
+ ptr++;
+ break;
+
+ case 'p':
+ /*
+ * XXX This is bogus if parsed before hour-related
+ * specifiers.
+ */
+ len = strlen(Locale->am);
+ if (strncasecmp(buf, Locale->am, len) == 0) {
+ if (tm->tm_hour > 12)
+ return 0;
+ if (tm->tm_hour == 12)
+ tm->tm_hour = 0;
+ buf += len;
+ break;
+ }
+
+ len = strlen(Locale->pm);
+ if (strncasecmp(buf, Locale->pm, len) == 0) {
+ if (tm->tm_hour > 12)
+ return 0;
+ if (tm->tm_hour != 12)
+ tm->tm_hour += 12;
+ buf += len;
+ break;
+ }
+
+ return 0;
+
+ case 'A':
+ case 'a':
+ for (i = 0; i < asizeof(Locale->weekday); i++) {
+ if (c == 'A') {
+ len = strlen(Locale->weekday[i]);
+ if (strncasecmp(buf,
+ Locale->weekday[i],
+ len) == 0)
+ break;
+ } else {
+ len = strlen(Locale->wday[i]);
+ if (strncasecmp(buf,
+ Locale->wday[i],
+ len) == 0)
+ break;
+ }
+ }
+ if (i == asizeof(Locale->weekday))
+ return 0;
+
+ tm->tm_wday = i;
+ buf += len;
+ break;
+
+ case 'U':
+ case 'W':
+ /*
+ * XXX This is bogus, as we can not assume any valid
+ * information present in the tm structure at this
+ * point to calculate a real value, so just check the
+ * range for now.
+ */
+ if (!isdigit((unsigned char)*buf))
+ return 0;
+
+ len = 2;
+ for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
+ i *= 10;
+ i += *buf - '0';
+ len--;
+ }
+ if (i > 53)
+ return 0;
+
+ if (*buf != 0 && isspace((unsigned char)*buf))
+ while (*ptr != 0 && !isspace((unsigned char)*ptr))
+ ptr++;
+ break;
+
+ case 'w':
+ if (!isdigit((unsigned char)*buf))
+ return 0;
+
+ i = *buf - '0';
+ if (i > 6)
+ return 0;
+
+ tm->tm_wday = i;
+
+ if (*buf != 0 && isspace((unsigned char)*buf))
+ while (*ptr != 0 && !isspace((unsigned char)*ptr))
+ ptr++;
+ break;
+
+ case 'd':
+ case 'e':
+ /*
+ * The %e specifier is explicitly documented as not
+ * being zero-padded but there is no harm in allowing
+ * such padding.
+ *
+ * XXX The %e specifier may gobble one too many
+ * digits if used incorrectly.
+ */
+ if (!isdigit((unsigned char)*buf))
+ return 0;
+
+ len = 2;
+ for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
+ i *= 10;
+ i += *buf - '0';
+ len--;
+ }
+ if (i > 31)
+ return 0;
+
+ tm->tm_mday = i;
+
+ if (*buf != 0 && isspace((unsigned char)*buf))
+ while (*ptr != 0 && !isspace((unsigned char)*ptr))
+ ptr++;
+ break;
+
+ case 'B':
+ case 'b':
+ case 'h':
+ for (i = 0; i < asizeof(Locale->month); i++) {
+ if (Oalternative) {
+ if (c == 'B') {
+ len = strlen(Locale->alt_month[i]);
+ if (strncasecmp(buf,
+ Locale->alt_month[i],
+ len) == 0)
+ break;
+ }
+ } else {
+ if (c == 'B') {
+ len = strlen(Locale->month[i]);
+ if (strncasecmp(buf,
+ Locale->month[i],
+ len) == 0)
+ break;
+ } else {
+ len = strlen(Locale->mon[i]);
+ if (strncasecmp(buf,
+ Locale->mon[i],
+ len) == 0)
+ break;
+ }
+ }
+ }
+ if (i == asizeof(Locale->month))
+ return 0;
+
+ tm->tm_mon = i;
+ buf += len;
+ break;
+
+ case 'm':
+ if (!isdigit((unsigned char)*buf))
+ return 0;
+
+ len = 2;
+ for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
+ i *= 10;
+ i += *buf - '0';
+ len--;
+ }
+ if (i < 1 || i > 12)
+ return 0;
+
+ tm->tm_mon = i - 1;
+
+ if (*buf != 0 && isspace((unsigned char)*buf))
+ while (*ptr != 0 && !isspace((unsigned char)*ptr))
+ ptr++;
+ break;
+
+ case 'Y':
+ case 'y':
+ if (*buf == 0 || isspace((unsigned char)*buf))
+ break;
+
+ if (!isdigit((unsigned char)*buf))
+ return 0;
+
+ len = (c == 'Y') ? 4 : 2;
+ for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
+ i *= 10;
+ i += *buf - '0';
+ len--;
+ }
+ if (c == 'Y')
+ i -= 1900;
+ if (c == 'y' && i < 69)
+ i += 100;
+ if (i < 0)
+ return 0;
+
+ tm->tm_year = i;
+
+ if (*buf != 0 && isspace((unsigned char)*buf))
+ while (*ptr != 0 && !isspace((unsigned char)*ptr))
+ ptr++;
+ break;
+
+ case 'Z':
+ {
+ const char *cp;
+ char *zonestr;
+
+ for (cp = buf; *cp && isupper((unsigned char)*cp); ++cp) {/*empty*/}
+ if (cp - buf) {
+ zonestr = alloca(cp - buf + 1);
+ strncpy(zonestr, buf, cp - buf);
+ zonestr[cp - buf] = '\0';
+ tzset();
+ if (0 == strcmp(zonestr, "GMT")) {
+ got_GMT = 1;
+ } else if (0 == strcmp(zonestr, tzname[0])) {
+ tm->tm_isdst = 0;
+ } else if (0 == strcmp(zonestr, tzname[1])) {
+ tm->tm_isdst = 1;
+ } else {
+ return 0;
+ }
+ buf += cp - buf;
+ }
+ }
+ break;
+ }
+ }
+ return (char *)buf;
+}
+
+
+char *
+strptime(const char *buf, const char *fmt, struct tm *tm)
+{
+ char *ret;
+
+#ifdef _THREAD_SAFE
+ pthread_mutex_lock(&gotgmt_mutex);
+#endif
+
+ got_GMT = 0;
+ ret = _strptime(buf, fmt, tm);
+ if (ret && got_GMT) {
+ time_t t = timegm(tm);
+ localtime_r(&t, tm);
+ got_GMT = 0;
+ }
+
+#ifdef _THREAD_SAFE
+ pthread_mutex_unlock(&gotgmt_mutex);
+#endif
+
+ return ret;
+}
diff --git a/lib/libc/stdtime/time2posix.3 b/lib/libc/stdtime/time2posix.3
new file mode 100644
index 0000000..7abd261
--- /dev/null
+++ b/lib/libc/stdtime/time2posix.3
@@ -0,0 +1,116 @@
+.\" $FreeBSD$
+.\"
+.Dd May 1, 1996
+.Dt TIME2POSIX 3
+.Os
+.Sh NAME
+.Nm time2posix ,
+.Nm posix2time
+.Nd convert seconds since the Epoch
+.Sh SYNOPSIS
+.Fd #include <time.h>
+.Ft time_t
+.Fn time2posix "const time_t *t"
+.Ft time_t
+.Fn posix2time "const time_t *t"
+.Sh DESCRIPTION
+.St -p1003.1-88
+legislates that a time_t value of
+536457599 shall correspond to "Wed Dec 31 23:59:59 GMT 1986."
+This effectively implies that POSIX time_t's cannot include leap
+seconds and,
+therefore,
+that the system time must be adjusted as each leap occurs.
+.Pp
+If the time package is configured with leap-second support
+enabled,
+however,
+no such adjustment is needed and
+time_t values continue to increase over leap events
+(as a true `seconds since...' value).
+This means that these values will differ from those required by POSIX
+by the net number of leap seconds inserted since the Epoch.
+.Pp
+Typically this is not a problem as the type time_t is intended
+to be
+(mostly)
+opaque\(emtime_t values should only be obtained-from and
+passed-to functions such as
+.Xr time 3 ,
+.Xr localtime 3 ,
+.Xr mktime 3
+and
+.Xr difftime 3 .
+However,
+.St -p1003.1-88
+gives an arithmetic
+expression for directly computing a time_t value from a given date/time,
+and the same relationship is assumed by some
+(usually older)
+applications.
+Any programs creating/dissecting time_t's
+using such a relationship will typically not handle intervals
+over leap seconds correctly.
+.Pp
+The
+.Fn time2posix
+and
+.Fn posix2time
+functions are provided to address this time_t mismatch by converting
+between local time_t values and their POSIX equivalents.
+This is done by accounting for the number of time-base changes that
+would have taken place on a POSIX system as leap seconds were inserted
+or deleted.
+These converted values can then be used in lieu of correcting the older
+applications,
+or when communicating with POSIX-compliant systems.
+.Pp
+The
+.Fn time2posix
+function is single-valued.
+That is,
+every local time_t
+corresponds to a single POSIX time_t.
+The
+.Fn posix2time
+function is less well-behaved:
+for a positive leap second hit the result is not unique,
+and for a negative leap second hit the corresponding
+POSIX time_t doesn't exist so an adjacent value is returned.
+Both of these are good indicators of the inferiority of the
+POSIX representation.
+.Pp
+The following table summarizes the relationship between time_t
+and its conversion to,
+and back from,
+the POSIX representation over the leap second inserted at the end of June,
+1993.
+.ta \w'93/06/30 'u +\w'23:59:59 'u +\w'A+0 'u +\w'X=time2posix(T) 'u
+DATE TIME T X=time2posix(T) posix2time(X)
+93/06/30 23:59:59 A+0 B+0 A+0
+93/06/30 23:59:60 A+1 B+1 A+1 or A+2
+93/07/01 00:00:00 A+2 B+1 A+1 or A+2
+93/07/01 00:00:01 A+3 B+2 A+3
+
+A leap second deletion would look like...
+
+DATE TIME T X=time2posix(T) posix2time(X)
+??/06/30 23:59:58 A+0 B+0 A+0
+??/07/01 00:00:00 A+1 B+2 A+1
+??/07/01 00:00:01 A+2 B+3 A+2
+.Pp
+ [Note: posix2time(B+1) => A+0 or A+1]
+.Pp
+If leap-second support is not enabled,
+local time_t's and
+POSIX time_t's are equivalent,
+and both
+.Fn time2posix
+and
+.Fn posix2time
+degenerate to the identity function.
+.Sh "SEE ALSO"
+.Xr difftime 3 ,
+.Xr localtime 3 ,
+.Xr mktime 3 ,
+.Xr time 3
diff --git a/lib/libc/stdtime/timelocal.c b/lib/libc/stdtime/timelocal.c
new file mode 100644
index 0000000..a7d91e5
--- /dev/null
+++ b/lib/libc/stdtime/timelocal.c
@@ -0,0 +1,245 @@
+/*-
+ * Copyright (c) 1997 FreeBSD Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syslimits.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include "setlocale.h"
+#include "timelocal.h"
+
+static int split_lines(char *, const char *);
+static void set_from_buf(const char *, int);
+
+struct lc_time_T _time_localebuf;
+int _time_using_locale;
+
+#define LCTIME_SIZE_FULL (sizeof(struct lc_time_T) / sizeof(char *))
+#define LCTIME_SIZE_1 \
+ (offsetof(struct lc_time_T, alt_month[0]) / sizeof(char *))
+#define LCTIME_SIZE_2 \
+ (offsetof(struct lc_time_T, Ef_fmt) / sizeof(char *))
+
+const struct lc_time_T _C_time_locale = {
+ {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ }, {
+ "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"
+ }, {
+ "Sun", "Mon", "Tue", "Wed",
+ "Thu", "Fri", "Sat"
+ }, {
+ "Sunday", "Monday", "Tuesday", "Wednesday",
+ "Thursday", "Friday", "Saturday"
+ },
+
+ /* X_fmt */
+ "%H:%M:%S",
+
+ /*
+ ** x_fmt
+ ** Since the C language standard calls for
+ ** "date, using locale's date format," anything goes.
+ ** Using just numbers (as here) makes Quakers happier;
+ ** it's also compatible with SVR4.
+ */
+ "%m/%d/%y",
+
+ /*
+ ** c_fmt (ctime-compatible)
+ ** Note that
+ ** "%a %b %d %H:%M:%S %Y"
+ ** is used by Solaris 2.3.
+ */
+ "%a %Ef %X %Y",
+
+ /* am */
+ "AM",
+
+ /* pm */
+ "PM",
+
+ /* date_fmt */
+ "%a %Ef %X %Z %Y",
+
+ {
+ "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"
+ },
+
+ /* Ef_fmt
+ ** To determine short months / day order
+ */
+ "%b %e",
+
+ /* EF_fmt
+ ** To determine long months / day order
+ */
+ "%B %e"
+};
+
+
+int
+__time_load_locale(const char *name)
+{
+ static char * locale_buf;
+ static char locale_buf_C[] = "C";
+ static int num_lines;
+
+ int fd;
+ char * lbuf;
+ char * p;
+ const char * plim;
+ char filename[PATH_MAX];
+ struct stat st;
+ size_t namesize;
+ size_t bufsize;
+ int save_using_locale;
+
+ save_using_locale = _time_using_locale;
+ _time_using_locale = 0;
+
+ if (name == NULL)
+ goto no_locale;
+
+ if (!strcmp(name, "C") || !strcmp(name, "POSIX"))
+ return 0;
+
+ /*
+ ** If the locale name is the same as our cache, use the cache.
+ */
+ lbuf = locale_buf;
+ if (lbuf != NULL && strcmp(name, lbuf) == 0) {
+ set_from_buf(lbuf, num_lines);
+ _time_using_locale = 1;
+ return 0;
+ }
+ /*
+ ** Slurp the locale file into the cache.
+ */
+ namesize = strlen(name) + 1;
+
+ if (!_PathLocale)
+ goto no_locale;
+ /* Range checking not needed, 'name' size is limited */
+ strcpy(filename, _PathLocale);
+ strcat(filename, "/");
+ strcat(filename, name);
+ strcat(filename, "/LC_TIME");
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ goto no_locale;
+ if (fstat(fd, &st) != 0)
+ goto bad_locale;
+ if (st.st_size <= 0)
+ goto bad_locale;
+ bufsize = namesize + st.st_size;
+ locale_buf = NULL;
+ lbuf = (lbuf == NULL || lbuf == locale_buf_C) ?
+ malloc(bufsize) : reallocf(lbuf, bufsize);
+ if (lbuf == NULL)
+ goto bad_locale;
+ (void) strcpy(lbuf, name);
+ p = lbuf + namesize;
+ plim = p + st.st_size;
+ if (read(fd, p, (size_t) st.st_size) != st.st_size)
+ goto bad_lbuf;
+ if (close(fd) != 0)
+ goto bad_lbuf;
+ /*
+ ** Parse the locale file into localebuf.
+ */
+ if (plim[-1] != '\n')
+ goto bad_lbuf;
+ num_lines = split_lines(p, plim);
+ if (num_lines >= LCTIME_SIZE_FULL)
+ num_lines = LCTIME_SIZE_FULL;
+ else if (num_lines >= LCTIME_SIZE_2)
+ num_lines = LCTIME_SIZE_2;
+ else if (num_lines >= LCTIME_SIZE_1)
+ num_lines = LCTIME_SIZE_1;
+ else
+ goto reset_locale;
+ set_from_buf(lbuf, num_lines);
+ /*
+ ** Record the successful parse in the cache.
+ */
+ locale_buf = lbuf;
+
+ _time_using_locale = 1;
+ return 0;
+
+reset_locale:
+ /*
+ * XXX - This may not be the correct thing to do in this case.
+ * setlocale() assumes that we left the old locale alone.
+ */
+ locale_buf = locale_buf_C;
+ _time_localebuf = _C_time_locale;
+ save_using_locale = 0;
+bad_lbuf:
+ free(lbuf);
+bad_locale:
+ (void) close(fd);
+no_locale:
+ _time_using_locale = save_using_locale;
+ return -1;
+}
+
+static int
+split_lines(char *p, const char *plim)
+{
+ int i;
+
+ for (i = 0; p < plim; i++) {
+ p = strchr(p, '\n');
+ *p++ = '\0';
+ }
+ return i;
+}
+
+static void
+set_from_buf(const char *p, int num_lines)
+{
+ const char **ap;
+ int i;
+
+ for (ap = (const char **) &_time_localebuf, i = 0;
+ i < num_lines; ++ap, ++i)
+ *ap = p += strlen(p) + 1;
+ if (num_lines == LCTIME_SIZE_FULL)
+ return;
+ for (i = 0; i < 12; i++)
+ _time_localebuf.alt_month[i] = _time_localebuf.month[i];
+}
diff --git a/lib/libc/stdtime/timelocal.h b/lib/libc/stdtime/timelocal.h
new file mode 100644
index 0000000..19b9d21
--- /dev/null
+++ b/lib/libc/stdtime/timelocal.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1997 FreeBSD Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Private header file for the strftime and strptime localization
+ * stuff.
+ */
+struct lc_time_T {
+ const char * mon[12];
+ const char * month[12];
+ const char * wday[7];
+ const char * weekday[7];
+ const char * X_fmt;
+ const char * x_fmt;
+ const char * c_fmt;
+ const char * am;
+ const char * pm;
+ const char * date_fmt;
+ const char * alt_month[12];
+ const char * Ef_fmt;
+ const char * EF_fmt;
+};
+
+extern struct lc_time_T _time_localebuf;
+extern int _time_using_locale;
+extern const struct lc_time_T _C_time_locale;
+
+#define Locale (_time_using_locale ? &_time_localebuf : &_C_time_locale)
+
diff --git a/lib/libc/stdtime/tzfile.5 b/lib/libc/stdtime/tzfile.5
new file mode 100644
index 0000000..c7b1fc7
--- /dev/null
+++ b/lib/libc/stdtime/tzfile.5
@@ -0,0 +1,138 @@
+.\" $FreeBSD$
+.Dd September 13, 1994
+.Dt TZFILE 5
+.Os FreeBSD 3.0
+.Sh NAME
+.Nm tzfile
+.Nd timezone information
+.Sh SYNOPSIS
+.Fd #include "/usr/src/lib/libc/stdtime/tzfile.h"
+.Sh DESCRIPTION
+The time zone information files used by
+.Xr tzset 3
+begin with the magic characters
+.Dq Li TZif
+to identify them as
+time zone information files,
+followed by sixteen bytes reserved for future use,
+followed by four four-byte values
+written in a ``standard'' byte order
+(the high-order byte of the value is written first).
+These values are,
+in order:
+.Pp
+.Bl -tag -compact -width tzh_ttisstdcnt
+.It Va tzh_ttisgmtcnt
+The number of UTC/local indicators stored in the file.
+.It Va tzh_ttisstdcnt
+The number of standard/wall indicators stored in the file.
+.It Va tzh_leapcnt
+The number of leap seconds for which data is stored in the file.
+.It Va tzh_timecnt
+The number of ``transition times'' for which data is stored
+in the file.
+.It Va tzh_typecnt
+The number of ``local time types'' for which data is stored
+in the file (must not be zero).
+.It Va tzh_charcnt
+The number of characters of ``time zone abbreviation strings''
+stored in the file.
+.El
+.Pp
+The above header is followed by
+.Va tzh_timecnt
+four-byte values of type
+.Fa long ,
+sorted in ascending order.
+These values are written in ``standard'' byte order.
+Each is used as a transition time (as returned by
+.Xr time 3 )
+at which the rules for computing local time change.
+Next come
+.Va tzh_timecnt
+one-byte values of type
+.Fa "unsigned char" ;
+each one tells which of the different types of ``local time'' types
+described in the file is associated with the same-indexed transition time.
+These values serve as indices into an array of
+.Fa ttinfo
+structures that appears next in the file;
+these structures are defined as follows:
+.Pp
+.Bd -literal -offset indent
+struct ttinfo {
+ long tt_gmtoff;
+ int tt_isdst;
+ unsigned int tt_abbrind;
+};
+.Ed
+.Pp
+Each structure is written as a four-byte value for
+.Va tt_gmtoff
+of type
+.Fa long ,
+in a standard byte order, followed by a one-byte value for
+.Va tt_isdst
+and a one-byte value for
+.Va tt_abbrind .
+In each structure,
+.Va tt_gmtoff
+gives the number of seconds to be added to UTC,
+.Li tt_isdst
+tells whether
+.Li tm_isdst
+should be set by
+.Xr localtime 3
+and
+.Va tt_abbrind
+serves as an index into the array of time zone abbreviation characters
+that follow the
+.Li ttinfo
+structure(s) in the file.
+.Pp
+Then there are
+.Va tzh_leapcnt
+pairs of four-byte values, written in standard byte order;
+the first value of each pair gives the time
+(as returned by
+.Xr time 3 )
+at which a leap second occurs;
+the second gives the
+.Em total
+number of leap seconds to be applied after the given time.
+The pairs of values are sorted in ascending order by time.
+.Pp
+Then there are
+.Va tzh_ttisstdcnt
+standard/wall indicators, each stored as a one-byte value;
+they tell whether the transition times associated with local time types
+were specified as standard time or wall clock time,
+and are used when a time zone file is used in handling POSIX-style
+time zone environment variables.
+.Pp
+Finally there are
+.Va tzh_ttisgmtcnt
+UTC/local indicators, each stored as a one-byte value;
+they tell whether the transition times associated with local time types
+were specified as UTC or local time,
+and are used when a time zone file is used in handling POSIX-style
+time zone environment variables.
+.Pp
+.Nm localtime
+uses the first standard-time
+.Li ttinfo
+structure in the file
+(or simply the first
+.Li ttinfo
+structure in the absence of a standard-time structure)
+if either
+.Li tzh_timecnt
+is zero or the time argument is less than the first transition time recorded
+in the file.
+.Sh SEE ALSO
+.Xr ctime 3 ,
+.Xr time2posix 3 ,
+.Xr zic 8
+.\" @(#)tzfile.5 7.2
+.\" This file is in the public domain, so clarified as of
+.\" 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
diff --git a/lib/libc/stdtime/tzfile.h b/lib/libc/stdtime/tzfile.h
new file mode 100644
index 0000000..c1b27ea
--- /dev/null
+++ b/lib/libc/stdtime/tzfile.h
@@ -0,0 +1,190 @@
+#ifndef TZFILE_H
+
+#define TZFILE_H
+
+/*
+** This file is in the public domain, so clarified as of
+** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
+*/
+
+/*
+** This header is for use ONLY with the time conversion code.
+** There is no guarantee that it will remain unchanged,
+** or that it will remain at all.
+** Do NOT copy it to any system include directory.
+** Thank you!
+*/
+
+/*
+** ID
+*/
+
+#ifndef lint
+#ifndef NOID
+/*
+static char tzfilehid[] = "@(#)tzfile.h 7.14";
+*/
+#endif /* !defined NOID */
+#endif /* !defined lint */
+
+/*
+** Information about time zone files.
+*/
+
+#ifndef TZDIR
+#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
+#endif /* !defined TZDIR */
+
+#ifndef TZDEFAULT
+#define TZDEFAULT "/etc/localtime"
+#endif /* !defined TZDEFAULT */
+
+#ifndef TZDEFRULES
+#define TZDEFRULES "posixrules"
+#endif /* !defined TZDEFRULES */
+
+/*
+** Each file begins with. . .
+*/
+
+#define TZ_MAGIC "TZif"
+
+struct tzhead {
+ char tzh_magic[4]; /* TZ_MAGIC */
+ char tzh_reserved[16]; /* reserved for future use */
+ char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
+ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
+ char tzh_leapcnt[4]; /* coded number of leap seconds */
+ char tzh_timecnt[4]; /* coded number of transition times */
+ char tzh_typecnt[4]; /* coded number of local time types */
+ char tzh_charcnt[4]; /* coded number of abbr. chars */
+};
+
+/*
+** . . .followed by. . .
+**
+** tzh_timecnt (char [4])s coded transition times a la time(2)
+** tzh_timecnt (unsigned char)s types of local time starting at above
+** tzh_typecnt repetitions of
+** one (char [4]) coded UTC offset in seconds
+** one (unsigned char) used to set tm_isdst
+** one (unsigned char) that's an abbreviation list index
+** tzh_charcnt (char)s '\0'-terminated zone abbreviations
+** tzh_leapcnt repetitions of
+** one (char [4]) coded leap second transition times
+** one (char [4]) total correction after above
+** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition
+** time is standard time, if FALSE,
+** transition time is wall clock time
+** if absent, transition times are
+** assumed to be wall clock time
+** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition
+** time is UTC, if FALSE,
+** transition time is local time
+** if absent, transition times are
+** assumed to be local time
+*/
+
+/*
+** In the current implementation, "tzset()" refuses to deal with files that
+** exceed any of the limits below.
+*/
+
+#ifndef TZ_MAX_TIMES
+/*
+** The TZ_MAX_TIMES value below is enough to handle a bit more than a
+** year's worth of solar time (corrected daily to the nearest second) or
+** 138 years of Pacific Presidential Election time
+** (where there are three time zone transitions every fourth year).
+*/
+#define TZ_MAX_TIMES 370
+#endif /* !defined TZ_MAX_TIMES */
+
+#ifndef TZ_MAX_TYPES
+#ifndef NOSOLAR
+#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
+#endif /* !defined NOSOLAR */
+#ifdef NOSOLAR
+/*
+** Must be at least 14 for Europe/Riga as of Jan 12 1995,
+** as noted by Earl Chew <earl@hpato.aus.hp.com>.
+*/
+#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
+#endif /* !defined NOSOLAR */
+#endif /* !defined TZ_MAX_TYPES */
+
+#ifndef TZ_MAX_CHARS
+#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
+ /* (limited by what unsigned chars can hold) */
+#endif /* !defined TZ_MAX_CHARS */
+
+#ifndef TZ_MAX_LEAPS
+#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
+#endif /* !defined TZ_MAX_LEAPS */
+
+#define SECSPERMIN 60
+#define MINSPERHOUR 60
+#define HOURSPERDAY 24
+#define DAYSPERWEEK 7
+#define DAYSPERNYEAR 365
+#define DAYSPERLYEAR 366
+#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR 12
+
+#define TM_SUNDAY 0
+#define TM_MONDAY 1
+#define TM_TUESDAY 2
+#define TM_WEDNESDAY 3
+#define TM_THURSDAY 4
+#define TM_FRIDAY 5
+#define TM_SATURDAY 6
+
+#define TM_JANUARY 0
+#define TM_FEBRUARY 1
+#define TM_MARCH 2
+#define TM_APRIL 3
+#define TM_MAY 4
+#define TM_JUNE 5
+#define TM_JULY 6
+#define TM_AUGUST 7
+#define TM_SEPTEMBER 8
+#define TM_OCTOBER 9
+#define TM_NOVEMBER 10
+#define TM_DECEMBER 11
+
+#define TM_YEAR_BASE 1900
+
+#define EPOCH_YEAR 1970
+#define EPOCH_WDAY TM_THURSDAY
+
+/*
+** Accurate only for the past couple of centuries;
+** that will probably do.
+*/
+
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
+
+#ifndef USG
+
+/*
+** Use of the underscored variants may cause problems if you move your code to
+** certain System-V-based systems; for maximum portability, use the
+** underscore-free variants. The underscored variants are provided for
+** backward compatibility only; they may disappear from future versions of
+** this file.
+*/
+
+#define SECS_PER_MIN SECSPERMIN
+#define MINS_PER_HOUR MINSPERHOUR
+#define HOURS_PER_DAY HOURSPERDAY
+#define DAYS_PER_WEEK DAYSPERWEEK
+#define DAYS_PER_NYEAR DAYSPERNYEAR
+#define DAYS_PER_LYEAR DAYSPERLYEAR
+#define SECS_PER_HOUR SECSPERHOUR
+#define SECS_PER_DAY SECSPERDAY
+#define MONS_PER_YEAR MONSPERYEAR
+
+#endif /* !defined USG */
+
+#endif /* !defined TZFILE_H */
diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc
new file mode 100644
index 0000000..6e05691
--- /dev/null
+++ b/lib/libc/string/Makefile.inc
@@ -0,0 +1,33 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/string ${.CURDIR}/../libc/string
+
+CFLAGS += -I${.CURDIR}/../libc/locale
+
+# machine-independent string sources
+MISRCS+=bcmp.c bcopy.c bzero.c ffs.c index.c memccpy.c memchr.c memcmp.c \
+ memcpy.c memmove.c memset.c rindex.c strcasecmp.c strcat.c strchr.c \
+ strcmp.c strcoll.c strcpy.c strcspn.c strdup.c strerror.c \
+ strlcat.c strlcpy.c strlen.c strmode.c strncat.c strncmp.c strncpy.c \
+ strpbrk.c strrchr.c strsep.c strsignal.c strspn.c strstr.c strtok.c \
+ strxfrm.c swab.c
+
+# machine-dependent string sources
+.include "${.CURDIR}/../libc/${MACHINE_ARCH}/string/Makefile.inc"
+
+.if ${LIB} == "c"
+MAN3+= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \
+ memcmp.3 memcpy.3 memmove.3 memset.3 rindex.3 strcasecmp.3 strcat.3 \
+ strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strdup.3 strerror.3 \
+ string.3 strlcpy.3 strlen.3 strmode.3 strpbrk.3 strrchr.3 strsep.3 \
+ strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3
+
+MLINKS+=strcasecmp.3 strncasecmp.3
+MLINKS+=strcat.3 strncat.3
+MLINKS+=strcmp.3 strncmp.3
+MLINKS+=strcpy.3 strncpy.3
+MLINKS+=strerror.3 perror.3 strerror.3 sys_errlist.3 strerror.3 sys_nerr.3
+MLINKS+=strlcpy.3 strlcat.3
+MLINKS+=strtok.3 strtok_r.3
+.endif
diff --git a/lib/libc/string/bcmp.3 b/lib/libc/string/bcmp.3
new file mode 100644
index 0000000..808cf0d
--- /dev/null
+++ b/lib/libc/string/bcmp.3
@@ -0,0 +1,72 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)bcmp.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt BCMP 3
+.Os BSD 4.2
+.Sh NAME
+.Nm bcmp
+.Nd compare byte string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft int
+.Fn bcmp "const void *b1" "const void *b2" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn bcmp
+function
+compares byte string
+.Fa b1
+against byte string
+.Fa b2 ,
+returning zero if they are identical, non-zero otherwise.
+Both strings are assumed to be
+.Fa len
+bytes long.
+Zero-length strings are always identical.
+.Pp
+The strings may overlap.
+.Sh SEE ALSO
+.Xr memcmp 3 ,
+.Xr strcasecmp 3 ,
+.Xr strcmp 3 ,
+.Xr strcoll 3 ,
+.Xr strxfrm 3
+.Sh HISTORY
+A
+.Fn bcmp
+function first appeared in
+.Bx 4.2 .
diff --git a/lib/libc/string/bcmp.c b/lib/libc/string/bcmp.c
new file mode 100644
index 0000000..5a3ae61
--- /dev/null
+++ b/lib/libc/string/bcmp.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bcmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <string.h>
+
+/*
+ * bcmp -- vax cmpc3 instruction
+ */
+int
+bcmp(b1, b2, length)
+ const void *b1, *b2;
+ register size_t length;
+{
+ register char *p1, *p2;
+
+ if (length == 0)
+ return(0);
+ p1 = (char *)b1;
+ p2 = (char *)b2;
+ do
+ if (*p1++ != *p2++)
+ break;
+ while (--length);
+ return(length);
+}
diff --git a/lib/libc/string/bcopy.3 b/lib/libc/string/bcopy.3
new file mode 100644
index 0000000..7d44916
--- /dev/null
+++ b/lib/libc/string/bcopy.3
@@ -0,0 +1,72 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)bcopy.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt BCOPY 3
+.Os BSD 4.2
+.Sh NAME
+.Nm bcopy
+.Nd copy byte string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft void
+.Fn bcopy "const void *src" "void *dst" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn bcopy
+function
+copies
+.Fa len
+bytes from string
+.Fa src
+to string
+.Fa dst .
+The two strings may overlap.
+If
+.Fa len
+is zero, no bytes are copied.
+.Sh SEE ALSO
+.Xr memccpy 3 ,
+.Xr memcpy 3 ,
+.Xr memmove 3 ,
+.Xr strcpy 3 ,
+.Xr strncpy 3
+.Sh HISTORY
+A
+.Fn bcopy
+function appeared in
+.Bx 4.2 .
diff --git a/lib/libc/string/bcopy.c b/lib/libc/string/bcopy.c
new file mode 100644
index 0000000..f90b09c
--- /dev/null
+++ b/lib/libc/string/bcopy.c
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+/*
+ * sizeof(word) MUST BE A POWER OF TWO
+ * SO THAT wmask BELOW IS ALL ONES
+ */
+typedef int word; /* "word" used for optimal copy speed */
+
+#define wsize sizeof(word)
+#define wmask (wsize - 1)
+
+/*
+ * Copy a block of memory, handling overlap.
+ * This is the routine that actually implements
+ * (the portable versions of) bcopy, memcpy, and memmove.
+ */
+#ifdef MEMCOPY
+void *
+memcpy(dst0, src0, length)
+#else
+#ifdef MEMMOVE
+void *
+memmove(dst0, src0, length)
+#else
+void
+bcopy(src0, dst0, length)
+#endif
+#endif
+ void *dst0;
+ const void *src0;
+ register size_t length;
+{
+ register char *dst = dst0;
+ register const char *src = src0;
+ register size_t t;
+
+ if (length == 0 || dst == src) /* nothing to do */
+ goto done;
+
+ /*
+ * Macros: loop-t-times; and loop-t-times, t>0
+ */
+#define TLOOP(s) if (t) TLOOP1(s)
+#define TLOOP1(s) do { s; } while (--t)
+
+ if ((unsigned long)dst < (unsigned long)src) {
+ /*
+ * Copy forward.
+ */
+ t = (int)src; /* only need low bits */
+ if ((t | (int)dst) & wmask) {
+ /*
+ * Try to align operands. This cannot be done
+ * unless the low bits match.
+ */
+ if ((t ^ (int)dst) & wmask || length < wsize)
+ t = length;
+ else
+ t = wsize - (t & wmask);
+ length -= t;
+ TLOOP1(*dst++ = *src++);
+ }
+ /*
+ * Copy whole words, then mop up any trailing bytes.
+ */
+ t = length / wsize;
+ TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
+ t = length & wmask;
+ TLOOP(*dst++ = *src++);
+ } else {
+ /*
+ * Copy backwards. Otherwise essentially the same.
+ * Alignment works as before, except that it takes
+ * (t&wmask) bytes to align, not wsize-(t&wmask).
+ */
+ src += length;
+ dst += length;
+ t = (int)src;
+ if ((t | (int)dst) & wmask) {
+ if ((t ^ (int)dst) & wmask || length <= wsize)
+ t = length;
+ else
+ t &= wmask;
+ length -= t;
+ TLOOP1(*--dst = *--src);
+ }
+ t = length / wsize;
+ TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
+ t = length & wmask;
+ TLOOP(*--dst = *--src);
+ }
+done:
+#if defined(MEMCOPY) || defined(MEMMOVE)
+ return (dst0);
+#else
+ return;
+#endif
+}
diff --git a/lib/libc/string/bstring.3 b/lib/libc/string/bstring.3
new file mode 100644
index 0000000..a1c091f
--- /dev/null
+++ b/lib/libc/string/bstring.3
@@ -0,0 +1,110 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)bstring.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt BSTRING 3
+.Os
+.Sh NAME
+.Nm bcmp ,
+.Nm bcopy ,
+.Nm bzero ,
+.Nm memccpy ,
+.Nm memchr ,
+.Nm memcmp ,
+.Nm memcpy ,
+.Nm memmove,
+.Nm memset
+.Nd byte string operations
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft int
+.Fn bcmp "const void *b1" "const void *b2" "size_t len"
+.Ft void
+.Fn bcopy "const void *src" "void *dst" "size_t len"
+.Ft void
+.Fn bzero "void *b" "size_t len"
+.Ft void *
+.Fn memchr "const void *b" "int c" "size_t len"
+.Ft int
+.Fn memcmp "const void *b1" "const void *b2" "size_t len"
+.Ft void *
+.Fn memccpy "void *dst" "const void *src" "int c" "size_t len"
+.Ft void *
+.Fn memcpy "void *dst" "const void *src" "size_t len"
+.Ft void *
+.Fn memmove "void *dst" "const void *src" "size_t len"
+.Ft void *
+.Fn memset "void *b" "int c" "size_t len"
+.Sh DESCRIPTION
+These functions operate on variable length strings of bytes.
+They do not check for terminating null bytes as the routines
+listed in
+.Xr string 3
+do.
+.Pp
+See the specific manual pages for more information.
+.Sh SEE ALSO
+.Xr bcmp 3 ,
+.Xr bcopy 3 ,
+.Xr bzero 3 ,
+.Xr memccpy 3 ,
+.Xr memchr 3 ,
+.Xr memcmp 3 ,
+.Xr memcpy 3 ,
+.Xr memmove 3 ,
+.Xr memset 3
+.Sh STANDARDS
+The functions
+.Fn memchr ,
+.Fn memcmp ,
+.Fn memcpy ,
+.Fn memmove ,
+and
+.Fn memset
+conform to
+.St -ansiC .
+.Sh HISTORY
+The functions
+.Fn bzero
+and
+.Fn memccpy
+appeared in
+.Bx 4.3 ;
+the functions
+.Fn bcmp ,
+.Fn bcopy ,
+appeared in
+.Bx 4.2 .
diff --git a/lib/libc/string/bzero.3 b/lib/libc/string/bzero.3
new file mode 100644
index 0000000..78dd8c0
--- /dev/null
+++ b/lib/libc/string/bzero.3
@@ -0,0 +1,69 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)bzero.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt BZERO 3
+.Os BSD 4.3
+.Sh NAME
+.Nm bzero
+.Nd write zeroes to a byte string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft void
+.Fn bzero "void *b" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn bzero
+function
+writes
+.Fa len
+zero bytes to the string
+.Fa b .
+If
+.Fa len
+is zero,
+.Fn bzero
+does nothing.
+.Sh SEE ALSO
+.Xr memset 3 ,
+.Xr swab 3
+.Sh HISTORY
+A
+.Fn bzero
+function
+appeared in
+.Bx 4.3 .
diff --git a/lib/libc/string/bzero.c b/lib/libc/string/bzero.c
new file mode 100644
index 0000000..7bc2b3a
--- /dev/null
+++ b/lib/libc/string/bzero.c
@@ -0,0 +1,2 @@
+#define BZERO
+#include "memset.c"
diff --git a/lib/libc/string/ffs.3 b/lib/libc/string/ffs.3
new file mode 100644
index 0000000..2794a44
--- /dev/null
+++ b/lib/libc/string/ffs.3
@@ -0,0 +1,62 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ffs.3 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt FFS 3
+.Os
+.Sh NAME
+.Nm ffs
+.Nd find first bit set in a bit string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft int
+.Fn ffs "int value"
+.Sh DESCRIPTION
+The
+.Fn ffs
+function finds the first bit set in
+.Fa value
+and returns the index of that bit.
+Bits are numbered starting from 1, starting at the right-most
+bit.
+A return value of 0 means that the argument was zero.
+.Sh SEE ALSO
+.Xr bitstring 3
+.Sh HISTORY
+The
+.Fn ffs
+function appeared in
+.Bx 4.3 .
diff --git a/lib/libc/string/ffs.c b/lib/libc/string/ffs.c
new file mode 100644
index 0000000..099ff8e
--- /dev/null
+++ b/lib/libc/string/ffs.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ffs.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <string.h>
+
+/*
+ * ffs -- vax ffs instruction
+ */
+int
+ffs(mask)
+ register int mask;
+{
+ register int bit;
+
+ if (mask == 0)
+ return(0);
+ for (bit = 1; !(mask & 1); bit++)
+ mask >>= 1;
+ return(bit);
+}
diff --git a/lib/libc/string/index.3 b/lib/libc/string/index.3
new file mode 100644
index 0000000..298101d
--- /dev/null
+++ b/lib/libc/string/index.3
@@ -0,0 +1,81 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)index.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt INDEX 3
+.Os
+.Sh NAME
+.Nm index
+.Nd locate character in string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn index "const char *s" "int c"
+.Sh DESCRIPTION
+The
+.Fn index
+function
+locates the first character matching
+.Fa c
+(converted to a
+.Em char )
+in the null-terminated string
+.Fa s .
+.Sh RETURN VALUES
+A pointer to the character is returned if it is found; otherwise
+.Dv NULL
+is returned.
+If
+.Fa c
+is '\e0',
+.Fn index
+locates the terminating '\e0'.
+.Sh SEE ALSO
+.Xr memchr 3 ,
+.Xr rindex 3 ,
+.Xr strchr 3 ,
+.Xr strcspn 3 ,
+.Xr strpbrk 3 ,
+.Xr strrchr 3 ,
+.Xr strsep 3 ,
+.Xr strspn 3 ,
+.Xr strstr 3 ,
+.Xr strtok 3
+.Sh HISTORY
+A
+.Fn index
+function appeared in
+.At v6 .
diff --git a/lib/libc/string/index.c b/lib/libc/string/index.c
new file mode 100644
index 0000000..37e505f
--- /dev/null
+++ b/lib/libc/string/index.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)index.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+#include <stddef.h>
+
+char *
+#ifdef STRCHR
+strchr(p, ch)
+#else
+index(p, ch)
+#endif
+ register const char *p, ch;
+{
+ for (;; ++p) {
+ if (*p == ch)
+ return((char *)p);
+ if (!*p)
+ return((char *)NULL);
+ }
+ /* NOTREACHED */
+}
diff --git a/lib/libc/string/memccpy.3 b/lib/libc/string/memccpy.3
new file mode 100644
index 0000000..794486f
--- /dev/null
+++ b/lib/libc/string/memccpy.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)memccpy.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt MEMCCPY 3
+.Os
+.Sh NAME
+.Nm memccpy
+.Nd copy string until character found
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft void *
+.Fn memccpy "void *dst" "const void *src" "int c" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn memccpy
+function
+copies bytes from string
+.Fa src
+to string
+.Fa dst .
+If the character
+.Fa c
+(as converted to an unsigned char) occurs in the string
+.Fa src ,
+the copy stops and a pointer to the byte after the copy of
+.Fa c
+in the string
+.Fa dst
+is returned.
+Otherwise,
+.Fa len
+bytes are copied, and a NULL pointer is returned.
+.Sh SEE ALSO
+.Xr bcopy 3 ,
+.Xr memcpy 3 ,
+.Xr memmove 3 ,
+.Xr strcpy 3
+.Sh HISTORY
+The
+.Fn memccpy
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/string/memccpy.c b/lib/libc/string/memccpy.c
new file mode 100644
index 0000000..c457110
--- /dev/null
+++ b/lib/libc/string/memccpy.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)memccpy.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+void *
+memccpy(t, f, c, n)
+ void *t;
+ const void *f;
+ int c;
+ register size_t n;
+{
+
+ if (n) {
+ register unsigned char *tp = t;
+ register const unsigned char *fp = f;
+ register unsigned char uc = c;
+ do {
+ if ((*tp++ = *fp++) == uc)
+ return (tp);
+ } while (--n != 0);
+ }
+ return (0);
+}
diff --git a/lib/libc/string/memchr.3 b/lib/libc/string/memchr.3
new file mode 100644
index 0000000..2469d60
--- /dev/null
+++ b/lib/libc/string/memchr.3
@@ -0,0 +1,82 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)memchr.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt MEMCHR 3
+.Os
+.Sh NAME
+.Nm memchr
+.Nd locate byte in byte string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft void *
+.Fn memchr "const void *b" "int c" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn memchr
+function
+locates the first occurrence of
+.Fa c
+(converted to an unsigned char)
+in string
+.Fa b .
+.Sh RETURN VALUES
+The
+.Fn memchr
+function
+returns a pointer to the byte located,
+or NULL if no such byte exists within
+.Fa len
+bytes.
+.Sh SEE ALSO
+.Xr index 3 ,
+.Xr rindex 3 ,
+.Xr strchr 3 ,
+.Xr strcspn 3 ,
+.Xr strpbrk 3 ,
+.Xr strrchr 3 ,
+.Xr strsep 3 ,
+.Xr strspn 3 ,
+.Xr strstr 3 ,
+.Xr strtok 3
+.Sh STANDARDS
+The
+.Fn memchr
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/memchr.c b/lib/libc/string/memchr.c
new file mode 100644
index 0000000..7200894
--- /dev/null
+++ b/lib/libc/string/memchr.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)memchr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+void *
+memchr(s, c, n)
+ const void *s;
+ register unsigned char c;
+ register size_t n;
+{
+ if (n != 0) {
+ register const unsigned char *p = s;
+
+ do {
+ if (*p++ == c)
+ return ((void *)(p - 1));
+ } while (--n != 0);
+ }
+ return (NULL);
+}
diff --git a/lib/libc/string/memcmp.3 b/lib/libc/string/memcmp.3
new file mode 100644
index 0000000..3939425
--- /dev/null
+++ b/lib/libc/string/memcmp.3
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)memcmp.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt MEMCMP 3
+.Os
+.Sh NAME
+.Nm memcmp
+.Nd compare byte string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft int
+.Fn memcmp "const void *b1" "const void *b2" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn memcmp
+function
+compares byte string
+.Fa b1
+against byte string
+.Fa b2 .
+Both strings are assumed to be
+.Fa len
+bytes long.
+.Sh RETURN VALUES
+The
+.Fn memcmp
+function
+returns zero if the two strings are identical,
+otherwise returns the difference between the first two differing bytes
+(treated as unsigned char values, so that
+.Sq Li \e200
+is greater than
+.Sq Li \&\e0 ,
+for example).
+Zero-length strings are always identical.
+.Sh SEE ALSO
+.Xr bcmp 3 ,
+.Xr strcasecmp 3 ,
+.Xr strcmp 3 ,
+.Xr strcoll 3 ,
+.Xr strxfrm 3
+.Sh STANDARDS
+The
+.Fn memcmp
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/memcmp.c b/lib/libc/string/memcmp.c
new file mode 100644
index 0000000..d025d89
--- /dev/null
+++ b/lib/libc/string/memcmp.c
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+/*
+ * Compare memory regions.
+ */
+int
+memcmp(s1, s2, n)
+ const void *s1, *s2;
+ size_t n;
+{
+ if (n != 0) {
+ register const unsigned char *p1 = s1, *p2 = s2;
+
+ do {
+ if (*p1++ != *p2++)
+ return (*--p1 - *--p2);
+ } while (--n != 0);
+ }
+ return (0);
+}
diff --git a/lib/libc/string/memcpy.3 b/lib/libc/string/memcpy.3
new file mode 100644
index 0000000..942c521
--- /dev/null
+++ b/lib/libc/string/memcpy.3
@@ -0,0 +1,84 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)memcpy.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt MEMCPY 3
+.Os
+.Sh NAME
+.Nm memcpy
+.Nd copy byte string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft void *
+.Fn memcpy "void *dst" "const void *src" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn memcpy
+function
+copies
+.Fa len
+bytes from string
+.Fa src
+to string
+.Fa dst .
+.Sh RETURN VALUES
+The
+.Fn memcpy
+function
+returns the original value of
+.Fa dst .
+.Sh SEE ALSO
+.Xr bcopy 3 ,
+.Xr memccpy 3 ,
+.Xr memmove 3 ,
+.Xr strcpy 3
+.Sh STANDARDS
+The
+.Fn memcpy
+function
+conforms to
+.St -ansiC .
+.Sh BUGS
+In this implementation
+.Fn memcpy
+is implemented using
+.Xr bcopy 3 ,
+and therefore the strings may overlap.
+On other systems, copying overlapping strings may produce surprises.
+A simpler solution is to not use
+.Fn memcpy .
diff --git a/lib/libc/string/memcpy.c b/lib/libc/string/memcpy.c
new file mode 100644
index 0000000..ee11504
--- /dev/null
+++ b/lib/libc/string/memcpy.c
@@ -0,0 +1,2 @@
+#define MEMCOPY
+#include "bcopy.c"
diff --git a/lib/libc/string/memmove.3 b/lib/libc/string/memmove.3
new file mode 100644
index 0000000..7355600
--- /dev/null
+++ b/lib/libc/string/memmove.3
@@ -0,0 +1,76 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)memmove.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt MEMMOVE 3
+.Os
+.Sh NAME
+.Nm memmove
+.Nd copy byte string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft void *
+.Fn memmove "void *dst" "const void *src" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn memmove
+function
+copies
+.Fa len
+bytes from string
+.Fa src
+to string
+.Fa dst .
+The two strings may overlap;
+the copy is always done in a non-destructive manner.
+.Sh RETURN VALUES
+The
+.Fn memmove
+function returns the original value of
+.Fa dst .
+.Sh SEE ALSO
+.Xr bcopy 3 ,
+.Xr memccpy 3 ,
+.Xr memcpy 3 ,
+.Xr strcpy 3
+.Sh STANDARDS
+The
+.Fn memmove
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/memmove.c b/lib/libc/string/memmove.c
new file mode 100644
index 0000000..e9bb2c2
--- /dev/null
+++ b/lib/libc/string/memmove.c
@@ -0,0 +1,2 @@
+#define MEMMOVE
+#include "bcopy.c"
diff --git a/lib/libc/string/memset.3 b/lib/libc/string/memset.3
new file mode 100644
index 0000000..9896514
--- /dev/null
+++ b/lib/libc/string/memset.3
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)memset.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt MEMSET 3
+.Os
+.Sh NAME
+.Nm memset
+.Nd write a byte to byte string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft void *
+.Fn memset "void *b" "int c" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn memset
+function
+writes
+.Fa len
+bytes of value
+.Fa c
+(converted to an unsigned char) to the string
+.Fa b .
+.Sh RETURNS
+The
+.Fn memset
+function returns its first argument.
+.Sh SEE ALSO
+.Xr bzero 3 ,
+.Xr swab 3
+.Sh STANDARDS
+The
+.Fn memset
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/memset.c b/lib/libc/string/memset.c
new file mode 100644
index 0000000..afe5f96
--- /dev/null
+++ b/lib/libc/string/memset.c
@@ -0,0 +1,132 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Hibler and Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)memset.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <limits.h>
+#include <string.h>
+
+#define wsize sizeof(u_int)
+#define wmask (wsize - 1)
+
+#ifdef BZERO
+#define RETURN return
+#define VAL 0
+#define WIDEVAL 0
+
+void
+bzero(dst0, length)
+ void *dst0;
+ register size_t length;
+#else
+#define RETURN return (dst0)
+#define VAL c0
+#define WIDEVAL c
+
+void *
+memset(dst0, c0, length)
+ void *dst0;
+ register int c0;
+ register size_t length;
+#endif
+{
+ register size_t t;
+#ifndef BZERO
+ register u_int c;
+#endif
+ register u_char *dst;
+
+ dst = dst0;
+ /*
+ * If not enough words, just fill bytes. A length >= 2 words
+ * guarantees that at least one of them is `complete' after
+ * any necessary alignment. For instance:
+ *
+ * |-----------|-----------|-----------|
+ * |00|01|02|03|04|05|06|07|08|09|0A|00|
+ * ^---------------------^
+ * dst dst+length-1
+ *
+ * but we use a minimum of 3 here since the overhead of the code
+ * to do word writes is substantial.
+ */
+ if (length < 3 * wsize) {
+ while (length != 0) {
+ *dst++ = VAL;
+ --length;
+ }
+ RETURN;
+ }
+
+#ifndef BZERO
+ if ((c = (u_char)c0) != 0) { /* Fill the word. */
+ c = (c << 8) | c; /* u_int is 16 bits. */
+#if UINT_MAX > 0xffff
+ c = (c << 16) | c; /* u_int is 32 bits. */
+#endif
+#if UINT_MAX > 0xffffffff
+ c = (c << 32) | c; /* u_int is 64 bits. */
+#endif
+ }
+#endif
+ /* Align destination by filling in bytes. */
+ if ((t = (long)dst & wmask) != 0) {
+ t = wsize - t;
+ length -= t;
+ do {
+ *dst++ = VAL;
+ } while (--t != 0);
+ }
+
+ /* Fill words. Length was >= 2*words so we know t >= 1 here. */
+ t = length / wsize;
+ do {
+ *(u_int *)dst = WIDEVAL;
+ dst += wsize;
+ } while (--t != 0);
+
+ /* Mop up trailing bytes, if any. */
+ t = length & wmask;
+ if (t != 0)
+ do {
+ *dst++ = VAL;
+ } while (--t != 0);
+ RETURN;
+}
diff --git a/lib/libc/string/rindex.3 b/lib/libc/string/rindex.3
new file mode 100644
index 0000000..7a5c478
--- /dev/null
+++ b/lib/libc/string/rindex.3
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)rindex.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt RINDEX 3
+.Os
+.Sh NAME
+.Nm rindex
+.Nd locate character in string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn rindex "const char *s" "int c"
+.Sh DESCRIPTION
+The
+.Fn rindex
+function
+locates the last character
+matching
+.Fa c
+(converted to a
+.Em char )
+in the null-terminated string
+.Fa s .
+.Sh RETURN VALUES
+A pointer to the character is returned if it is found; otherwise
+NULL is returned.
+If
+.Fa c
+is
+.Ql \e0 ,
+.Fn rindex
+locates the terminating
+.Ql \e0 .
+.Sh SEE ALSO
+.Xr index 3 ,
+.Xr memchr 3 ,
+.Xr strchr 3 ,
+.Xr strcspn 3 ,
+.Xr strpbrk 3 ,
+.Xr strrchr 3 ,
+.Xr strsep 3 ,
+.Xr strspn 3 ,
+.Xr strstr 3 ,
+.Xr strtok 3
+.Sh HISTORY
+A
+.Fn rindex
+function appeared in
+.At v6 .
diff --git a/lib/libc/string/rindex.c b/lib/libc/string/rindex.c
new file mode 100644
index 0000000..69dced4
--- /dev/null
+++ b/lib/libc/string/rindex.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rindex.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <string.h>
+
+char *
+#ifdef STRRCHR
+strrchr(p, ch)
+#else
+rindex(p, ch)
+#endif
+ register const char *p;
+ register int ch;
+{
+ register char *save;
+
+ for (save = NULL;; ++p) {
+ if (*p == ch)
+ save = (char *)p;
+ if (!*p)
+ return(save);
+ }
+ /* NOTREACHED */
+}
diff --git a/lib/libc/string/strcasecmp.3 b/lib/libc/string/strcasecmp.3
new file mode 100644
index 0000000..1dd5f80
--- /dev/null
+++ b/lib/libc/string/strcasecmp.3
@@ -0,0 +1,89 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt STRCASECMP 3
+.Os
+.Sh NAME
+.Nm strcasecmp ,
+.Nm strncasecmp
+.Nd compare strings, ignoring case
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft int
+.Fn strcasecmp "const char *s1" "const char *s2"
+.Ft int
+.Fn strncasecmp "const char *s1" "const char *s2" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn strcasecmp
+and
+.Fn strncasecmp
+functions
+compare the null-terminated strings
+.Fa s1
+and
+.Fa s2
+and return an integer greater than, equal to, or less than 0,
+according as
+.Fa s1
+is lexicographically greater than, equal to, or less than
+.Fa s2
+after translation of each corresponding character to lower-case.
+The strings themselves are not modified.
+The comparison is done using unsigned characters, so that
+.Sq Li \e200
+is greater than
+.Ql \e0 .
+.Pp
+The
+.Fn strncasecmp
+compares at most
+.Fa len
+characters.
+.Sh SEE ALSO
+.Xr bcmp 3 ,
+.Xr memcmp 3 ,
+.Xr strcmp 3 ,
+.Xr strcoll 3 ,
+.Xr strxfrm 3
+.Sh HISTORY
+The
+.Fn strcasecmp
+and
+.Fn strncasecmp
+functions first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/string/strcasecmp.c b/lib/libc/string/strcasecmp.c
new file mode 100644
index 0000000..463c4de
--- /dev/null
+++ b/lib/libc/string/strcasecmp.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <string.h>
+#include <ctype.h>
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+typedef unsigned char u_char;
+
+int
+strcasecmp(s1, s2)
+ const char *s1, *s2;
+{
+ register const u_char
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ while (tolower(*us1) == tolower(*us2++))
+ if (*us1++ == '\0')
+ return (0);
+ return (tolower(*us1) - tolower(*--us2));
+}
+
+int
+strncasecmp(s1, s2, n)
+ const char *s1, *s2;
+ register size_t n;
+{
+ if (n != 0) {
+ register const u_char
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ do {
+ if (tolower(*us1) != tolower(*us2++))
+ return (tolower(*us1) - tolower(*--us2));
+ if (*us1++ == '\0')
+ break;
+ } while (--n != 0);
+ }
+ return (0);
+}
diff --git a/lib/libc/string/strcat.3 b/lib/libc/string/strcat.3
new file mode 100644
index 0000000..1f0aad2
--- /dev/null
+++ b/lib/libc/string/strcat.3
@@ -0,0 +1,99 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strcat.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRCAT 3
+.Os
+.Sh NAME
+.Nm strcat
+.Nd concatenate strings
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn strcat "char *s" "const char *append"
+.Ft char *
+.Fn strncat "char *s" "const char *append" "size_t count"
+.Sh DESCRIPTION
+The
+.Fn strcat
+and
+.Fn strncat
+functions
+append a copy of the null-terminated string
+.Fa append
+to the end of the null-terminated string
+.Fa s ,
+then add a terminating
+.Ql \e0 .
+The string
+.Fa s
+must have sufficient space to hold the result.
+.Pp
+The
+.Fn strncat
+function
+appends not more than
+.Fa count
+characters from
+.Fa append ,
+and then adds a terminating
+.Ql \e0.
+.Sh RETURN VALUES
+The
+.Fn strcat
+and
+.Fn strncat
+functions
+return the pointer
+.Fa s .
+.Sh SEE ALSO
+.Xr bcopy 3 ,
+.Xr memccpy 3 ,
+.Xr memcpy 3 ,
+.Xr memmove 3 ,
+.Xr strcpy 3 ,
+.Xr strlcat 3 ,
+.Xr strlcpy 3
+.Sh STANDARDS
+The
+.Fn strcat
+and
+.Fn strncat
+functions
+conform to
+.St -ansiC .
diff --git a/lib/libc/string/strcat.c b/lib/libc/string/strcat.c
new file mode 100644
index 0000000..95dcd1d
--- /dev/null
+++ b/lib/libc/string/strcat.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcat.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <string.h>
+
+char *
+strcat(s, append)
+ register char *s;
+ register const char *append;
+{
+ char *save = s;
+
+ for (; *s; ++s);
+ while ((*s++ = *append++));
+ return(save);
+}
diff --git a/lib/libc/string/strchr.3 b/lib/libc/string/strchr.3
new file mode 100644
index 0000000..8b5b892
--- /dev/null
+++ b/lib/libc/string/strchr.3
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strchr.3 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt STRCHR 3
+.Os
+.Sh NAME
+.Nm strchr
+.Nd locate character in string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn strchr "const char *s" "int c"
+.Sh DESCRIPTION
+The
+.Fn strchr
+function locates the first occurrence of
+.Ar c
+in the string pointed to by
+.Ar s .
+The terminating
+.Dv NUL
+character is considered part of the string.
+If
+.Fa c
+is
+.Ql \e0 ,
+.Fn strchr
+locates the terminating
+.Ql \e0 .
+.Sh RETURN VALUES
+The function
+.Fn strchr
+returns a pointer to the located character, or
+.Dv NULL
+if the character does not appear in the string.
+.Sh SEE ALSO
+.Xr index 3 ,
+.Xr memchr 3 ,
+.Xr rindex 3 ,
+.Xr strcspn 3 ,
+.Xr strpbrk 3 ,
+.Xr strrchr 3 ,
+.Xr strsep 3 ,
+.Xr strspn 3 ,
+.Xr strstr 3 ,
+.Xr strtok 3
+.Sh STANDARDS
+The
+.Fn strchr
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/strchr.c b/lib/libc/string/strchr.c
new file mode 100644
index 0000000..ee33662
--- /dev/null
+++ b/lib/libc/string/strchr.c
@@ -0,0 +1,2 @@
+#define STRCHR
+#include "index.c"
diff --git a/lib/libc/string/strcmp.3 b/lib/libc/string/strcmp.3
new file mode 100644
index 0000000..45abbc4
--- /dev/null
+++ b/lib/libc/string/strcmp.3
@@ -0,0 +1,95 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strcmp.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRCMP 3
+.Os
+.Sh NAME
+.Nm strcmp ,
+.Nm strncmp
+.Nd compare strings
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft int
+.Fn strcmp "const char *s1" "const char *s2"
+.Ft int
+.Fn strncmp "const char *s1" "const char *s2" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn strcmp
+and
+.Fn strncmp
+functions
+lexicographically compare the null-terminated strings
+.Fa s1
+and
+.Fa s2 .
+.Pp
+The
+.Fn strncmp
+compares not more than
+.Fa len
+characters.
+.Sh RETURN VALUES
+The
+.Fn strcmp
+and
+.Fn strncmp
+return an integer greater than, equal to, or less than 0, according
+as the string
+.Fa s1
+is greater than, equal to, or less than the string
+.Fa s2 .
+The comparison is done using unsigned characters, so that
+.Ql \e200
+is greater than
+.Ql \e0 .
+.Sh SEE ALSO
+.Xr bcmp 3 ,
+.Xr memcmp 3 ,
+.Xr strcasecmp 3 ,
+.Xr strcoll 3 ,
+.Xr strxfrm 3
+.Sh STANDARDS
+The
+.Fn strcmp
+and
+.Fn strncmp
+functions
+conform to
+.St -ansiC .
diff --git a/lib/libc/string/strcmp.c b/lib/libc/string/strcmp.c
new file mode 100644
index 0000000..cf25e50
--- /dev/null
+++ b/lib/libc/string/strcmp.c
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+/*
+ * Compare strings.
+ */
+int
+strcmp(s1, s2)
+ register const char *s1, *s2;
+{
+ while (*s1 == *s2++)
+ if (*s1++ == 0)
+ return (0);
+ return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
+}
diff --git a/lib/libc/string/strcoll.3 b/lib/libc/string/strcoll.3
new file mode 100644
index 0000000..2d72fe3
--- /dev/null
+++ b/lib/libc/string/strcoll.3
@@ -0,0 +1,73 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strcoll.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRCOLL 3
+.Os
+.Sh NAME
+.Nm strcoll
+.Nd compare strings according to current collation
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft int
+.Fn strcoll "const char *s1" "const char *s2"
+.Sh DESCRIPTION
+The
+.Fn strcoll
+function
+lexicographically compares the null-terminated strings
+.Fa s1
+and
+.Fa s2
+according to the current locale collation if any, otherwise call
+.Fa strcmp ,
+and returns an integer greater than, equal to, or less than 0,
+according as
+.Fa s1
+is greater than, equal to, or less than
+.Fa s2 .
+.Sh SEE ALSO
+.Xr setlocale 3 ,
+.Xr strcmp 3 ,
+.Xr strxfrm 3
+.Sh STANDARDS
+The
+.Fn strcoll
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/strcoll.c b/lib/libc/string/strcoll.c
new file mode 100644
index 0000000..5213cf8
--- /dev/null
+++ b/lib/libc/string/strcoll.c
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
+ * at Electronni Visti IA, Kiev, Ukraine.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "collate.h"
+
+int
+strcoll(s, s2)
+ const char *s, *s2;
+{
+ int len, len2, prim, prim2, sec, sec2, ret, ret2;
+ const char *t, *t2;
+ char *tt, *tt2;
+
+ if (__collate_load_error)
+ return strcmp(s, s2);
+
+ len = len2 = 1;
+ ret = ret2 = 0;
+ if (__collate_substitute_nontrivial) {
+ t = tt = __collate_substitute(s);
+ t2 = tt2 = __collate_substitute(s2);
+ } else {
+ tt = tt2 = NULL;
+ t = s;
+ t2 = s2;
+ }
+ while(*t && *t2) {
+ prim = prim2 = 0;
+ while(*t && !prim) {
+ __collate_lookup(t, &len, &prim, &sec);
+ t += len;
+ }
+ while(*t2 && !prim2) {
+ __collate_lookup(t2, &len2, &prim2, &sec2);
+ t2 += len2;
+ }
+ if(!prim || !prim2)
+ break;
+ if(prim != prim2) {
+ ret = prim - prim2;
+ goto end;
+ }
+ if(!ret2)
+ ret2 = sec - sec2;
+ }
+ if(!*t && *t2)
+ ret = -(int)((u_char)*t2);
+ else if(*t && !*t2)
+ ret = (u_char)*t;
+ else if(!*t && !*t2)
+ ret = ret2;
+ end:
+ free(tt);
+ free(tt2);
+
+ return ret;
+}
diff --git a/lib/libc/string/strcpy.3 b/lib/libc/string/strcpy.3
new file mode 100644
index 0000000..0ecb732
--- /dev/null
+++ b/lib/libc/string/strcpy.3
@@ -0,0 +1,123 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strcpy.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRCPY 3
+.Os BSD 4
+.Sh NAME
+.Nm strcpy
+.Nd copy strings
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn strcpy "char *dst" "const char *src"
+.Ft char *
+.Fn strncpy "char *dst" "const char *src" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn strcpy
+and
+.Fn strncpy
+functions
+copy the string
+.Fa src
+to
+.Fa dst
+(including the terminating
+.Ql \e0
+character).
+.Pp
+The
+.Fn strncpy
+copies not more than
+.Fa len
+characters into
+.Fa dst ,
+appending
+.Ql \e0
+characters if
+.Fa src
+is less than
+.Fa len
+characters long, and
+.Em not
+terminating
+.Fa dst
+if
+.Fa src
+is more than
+.Fa len
+characters long.
+.Sh RETURN VALUES
+The
+.Fn strcpy
+and
+.Fn strncpy
+functions
+return
+.Fa dst .
+.Sh EXAMPLES
+The following sets
+.Dq Li chararray
+to
+.Dq Li abc\e0\e0\e0 :
+.Bd -literal -offset indent
+(void)strncpy(chararray, "abc", 6).
+.Ed
+.Pp
+The following sets
+.Dq Li chararray
+to
+.Dq Li abcdef :
+.Bd -literal -offset indent
+(void)strncpy(chararray, "abcdefgh", 6);
+.Ed
+.Sh SEE ALSO
+.Xr bcopy 3 ,
+.Xr memccpy 3 ,
+.Xr memcpy 3 ,
+.Xr memmove 3 ,
+.Xr strlcpy 3
+.Sh STANDARDS
+The
+.Fn strcpy
+and
+.Fn strncpy
+functions
+conform to
+.St -ansiC .
diff --git a/lib/libc/string/strcpy.c b/lib/libc/string/strcpy.c
new file mode 100644
index 0000000..c9b44b1
--- /dev/null
+++ b/lib/libc/string/strcpy.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcpy.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+char *
+strcpy(to, from)
+ register char *to;
+ register const char *from;
+{
+ char *save = to;
+
+ for (; (*to = *from); ++from, ++to);
+ return(save);
+}
diff --git a/lib/libc/string/strcspn.3 b/lib/libc/string/strcspn.3
new file mode 100644
index 0000000..6590cb5
--- /dev/null
+++ b/lib/libc/string/strcspn.3
@@ -0,0 +1,85 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strcspn.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRCSPN 3
+.Os
+.Sh NAME
+.Nm strcspn
+.Nd span the complement of a string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft size_t
+.Fn strcspn "const char *s" "const char *charset"
+.Sh DESCRIPTION
+The
+.Fn strcspn
+function
+spans the initial part of the null-terminated string
+.Fa s
+as long as the characters from
+.Fa s
+do not occur in string
+.Fa charset
+(it
+spans the
+.Em complement
+of
+.Fa charset ) .
+.Sh RETURN VALUES
+The
+.Fn strcspn
+function
+returns the number of characters spanned.
+.Sh SEE ALSO
+.Xr index 3 ,
+.Xr memchr 3 ,
+.Xr rindex 3 ,
+.Xr strchr 3 ,
+.Xr strpbrk 3 ,
+.Xr strrchr 3 ,
+.Xr strsep 3 ,
+.Xr strspn 3 ,
+.Xr strstr 3 ,
+.Xr strtok 3
+.Sh STANDARDS
+The
+.Fn strcspn
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/strcspn.c b/lib/libc/string/strcspn.c
new file mode 100644
index 0000000..a1c2e1d
--- /dev/null
+++ b/lib/libc/string/strcspn.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcspn.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+/*
+ * Span the complement of string s2.
+ */
+size_t
+strcspn(s1, s2)
+ const char *s1;
+ register const char *s2;
+{
+ register const char *p, *spanp;
+ register char c, sc;
+
+ /*
+ * Stop as soon as we find any character from s2. Note that there
+ * must be a NUL in s2; it suffices to stop when we find that, too.
+ */
+ for (p = s1;;) {
+ c = *p++;
+ spanp = s2;
+ do {
+ if ((sc = *spanp++) == c)
+ return (p - 1 - s1);
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
diff --git a/lib/libc/string/strdup.3 b/lib/libc/string/strdup.3
new file mode 100644
index 0000000..53c1d39
--- /dev/null
+++ b/lib/libc/string/strdup.3
@@ -0,0 +1,65 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strdup.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt STRDUP 3
+.Os
+.Sh NAME
+.Nm strdup
+.Nd save a copy of a string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn strdup "const char *str"
+.Sh DESCRIPTION
+The
+.Fn strdup
+function
+allocates sufficient memory for a copy
+of the string
+.Fa str ,
+does the copy, and returns a pointer to it.
+The pointer may subsequently be used as an
+argument to the function
+.Xr free 3 .
+.Pp
+If insufficient memory is available, NULL is returned.
+.Sh SEE ALSO
+.Xr free 3 ,
+.Xr malloc 3
+.Sh HISTORY
+The
+.Fn strdup
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/string/strdup.c b/lib/libc/string/strdup.c
new file mode 100644
index 0000000..a1c2eed
--- /dev/null
+++ b/lib/libc/string/strdup.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strdup.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *
+strdup(str)
+ const char *str;
+{
+ size_t len;
+ char *copy;
+
+ len = strlen(str) + 1;
+ if ((copy = malloc(len)) == NULL)
+ return (NULL);
+ memcpy(copy, str, len);
+ return (copy);
+}
diff --git a/lib/libc/string/strerror.3 b/lib/libc/string/strerror.3
new file mode 100644
index 0000000..a0f6b42
--- /dev/null
+++ b/lib/libc/string/strerror.3
@@ -0,0 +1,128 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strerror.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt STRERROR 3
+.Os BSD 4
+.Sh NAME
+.Nm perror ,
+.Nm strerror ,
+.Nm sys_errlist ,
+.Nm sys_nerr
+.Nd system error messages
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft void
+.Fn perror "const char *string"
+.Vt extern const char * const sys_errlist[];
+.Vt extern const int sys_nerr;
+.Fd #include <string.h>
+.Ft char *
+.Fn strerror "int errnum"
+.Sh DESCRIPTION
+The
+.Fn strerror
+and
+.Fn perror
+functions look up the error message string corresponding to an
+error number.
+.Pp
+The
+.Fn strerror
+function accepts an error number argument
+.Fa errnum
+and
+returns a pointer to the corresponding
+message string.
+.Pp
+The
+.Fn perror
+function finds the error message corresponding to the current
+value of the global variable
+.Va errno
+.Pq Xr intro 2
+and writes it, followed by a newline, to the
+standard error file descriptor.
+If the argument
+.Fa string
+is
+.Pf non- Dv NULL
+and does not point to the null character,
+this string is prepended to the message
+string and separated from it by
+a colon and space
+.Pq Ql \&:\ \& ;
+otherwise, only the error message string is printed.
+.Pp
+If
+.Fa errnum
+is not a recognized error number,
+the error message string will contain
+.Dq Li "Unknown error:\0
+followed by the error number in decimal.
+.Pp
+The message strings can be accessed directly using the external
+array
+.Va sys_errlist .
+The external value
+.Va sys_nerr
+contains a count of the messages in
+.Va sys_errlist .
+The use of these variables is deprecated;
+.Fn strerror
+should be used instead.
+.Sh SEE ALSO
+.Xr intro 2 ,
+.Xr psignal 3
+.Sh HISTORY
+The
+.Fn strerror
+and
+.Fn perror
+functions first appeared in
+.Bx 4.4 .
+.Sh BUGS
+For unknown error numbers, the
+.Fn strerror
+function will return its result in a static buffer which
+may be overwritten by subsequent calls.
+.Pp
+Programs that use the deprecated
+.Va sys_errlist
+variable often fail to compile because they declare it
+inconsistently.
diff --git a/lib/libc/string/strerror.c b/lib/libc/string/strerror.c
new file mode 100644
index 0000000..5acefd9
--- /dev/null
+++ b/lib/libc/string/strerror.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+
+char *
+strerror(num)
+ int num;
+{
+#define UPREFIX "Unknown error: "
+ static char ebuf[40] = UPREFIX; /* 64-bit number + slop */
+ register unsigned int errnum;
+ register char *p, *t;
+ char tmp[40];
+
+ errnum = num; /* convert to unsigned */
+ if (errnum < sys_nerr)
+ return ((char *)sys_errlist[errnum]);
+
+ /* Do this by hand, so we don't link to stdio(3). */
+ t = tmp;
+ if (num < 0)
+ errnum = -errnum;
+ do {
+ *t++ = "0123456789"[errnum % 10];
+ } while (errnum /= 10);
+ if (num < 0)
+ *t++ = '-';
+ for (p = ebuf + sizeof(UPREFIX) - 1;;) {
+ *p++ = *--t;
+ if (t <= tmp)
+ break;
+ }
+ *p = '\0';
+ return (ebuf);
+}
diff --git a/lib/libc/string/string.3 b/lib/libc/string/string.3
new file mode 100644
index 0000000..947a745
--- /dev/null
+++ b/lib/libc/string/string.3
@@ -0,0 +1,156 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)string.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt STRING 3
+.Os BSD 4
+.Sh NAME
+.Nm strcat ,
+.Nm strncat ,
+.Nm strchr ,
+.Nm strrchr ,
+.Nm strcmp ,
+.Nm strncmp ,
+.Nm strcasecmp,
+.Nm strncasecmp ,
+.Nm strcpy ,
+.Nm strncpy ,
+.Nm strerror ,
+.Nm strlen ,
+.Nm strpbrk ,
+.Nm strsep,
+.Nm strspn ,
+.Nm strcspn ,
+.Nm strstr ,
+.Nm strtok ,
+.Nm index ,
+.Nm rindex
+.Nd string specific functions
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn strcat "char *s" "const char * append"
+.Ft char *
+.Fn strncat "char *s" "const char *append" "size_t count"
+.Ft char *
+.Fn strchr "const char *s" "int c"
+.Ft char *
+.Fn strrchr "const char *s" "int c"
+.Ft int
+.Fn strcmp "const char *s1" "const char *s2"
+.Ft int
+.Fn strncmp "const char *s1" "const char *s2" "size_t count"
+.Ft int
+.Fn strcasecmp "const char *s1" "const char *s2"
+.Ft int
+.Fn strncasecmp "const char *s1" "const char *s2" "size_t count"
+.Ft char *
+.Fn strcpy "char *dst" "const char *src"
+.Ft char *
+.Fn strncpy "char *dst" "const char *src" "size_t count"
+.Ft char *
+.Fn strerror "int errno"
+.Ft size_t
+.Fn strlen "const char *s"
+.Ft char *
+.Fn strpbrk "const char *s" "const char *charset"
+.Ft char *
+.Fn strsep "char **stringp" "const char *delim"
+.Ft size_t
+.Fn strspn "const char *s" "const char *charset"
+.Ft size_t
+.Fn strcspn "const char *s" "const char *charset"
+.Ft char *
+.Fn strstr "const char *big" "const char *little"
+.Ft char *
+.Fn strtok "char *s" "const char *delim"
+.Ft char *
+.Fn index "const char *s" "int c"
+.Ft char *
+.Fn rindex "const char *s" "int c"
+.Sh DESCRIPTION
+The string
+functions manipulate strings terminated by a
+null byte.
+.Pp
+See the specific manual pages for more information.
+For manipulating variable length generic objects as byte
+strings (without the null byte check), see
+.Xr bstring 3 .
+.Pp
+Except as noted in their specific manual pages,
+the string functions do not test the destination
+for size limitations.
+.Sh SEE ALSO
+.Xr bstring 3 ,
+.Xr index 3 ,
+.Xr rindex 3 ,
+.Xr strcasecmp 3 ,
+.Xr strcat 3 ,
+.Xr strchr 3 ,
+.Xr strcmp 3 ,
+.Xr strcpy 3 ,
+.Xr strcspn 3 ,
+.Xr strerror 3 ,
+.Xr strlen 3 ,
+.Xr strpbrk 3 ,
+.Xr strrchr 3 ,
+.Xr strsep 3 ,
+.Xr strspn 3 ,
+.Xr strstr 3 ,
+.Xr strtok 3
+.Sh STANDARDS
+The
+.Fn strcat ,
+.Fn strncat ,
+.Fn strchr ,
+.Fn strrchr ,
+.Fn strcmp ,
+.Fn strncmp ,
+.Fn strcpy ,
+.Fn strncpy ,
+.Fn strerror ,
+.Fn strlen ,
+.Fn strpbrk ,
+.Fn strsep ,
+.Fn strspn ,
+.Fn strcspn ,
+.Fn strstr ,
+and
+.Fn strtok
+functions
+conform to
+.St -ansiC .
diff --git a/lib/libc/string/strlcat.c b/lib/libc/string/strlcat.c
new file mode 100644
index 0000000..599994e
--- /dev/null
+++ b/lib/libc/string/strlcat.c
@@ -0,0 +1,71 @@
+/* $OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $ */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Appends src to string dst of size siz (unlike strncat, siz is the
+ * full size of dst, not space left). At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t strlcat(dst, src, siz)
+ char *dst;
+ const char *src;
+ size_t siz;
+{
+ register char *d = dst;
+ register const char *s = src;
+ register size_t n = siz;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past end */
+ while (*d != '\0' && n-- != 0)
+ d++;
+ dlen = d - dst;
+ n = siz - dlen;
+
+ if (n == 0)
+ return(dlen + strlen(s));
+ while (*s != '\0') {
+ if (n != 1) {
+ *d++ = *s;
+ n--;
+ }
+ s++;
+ }
+ *d = '\0';
+
+ return(dlen + (s - src)); /* count does not include NUL */
+}
diff --git a/lib/libc/string/strlcpy.3 b/lib/libc/string/strlcpy.3
new file mode 100644
index 0000000..e1dddee
--- /dev/null
+++ b/lib/libc/string/strlcpy.3
@@ -0,0 +1,157 @@
+.\" $OpenBSD: strlcpy.3,v 1.5 1999/06/06 15:17:32 aaron Exp $
+.\"
+.\" Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 22, 1998
+.Dt STRLCPY 3
+.Os
+.Sh NAME
+.Nm strlcpy ,
+.Nm strlcat
+.Nd size-bounded string copying and concatenation
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft size_t
+.Fn strlcpy "char *dst" "const char *src" "size_t size"
+.Ft size_t
+.Fn strlcat "char *dst" "const char *src" "size_t size"
+.Sh DESCRIPTION
+The
+.Fn strlcpy
+and
+.Fn strlcat
+functions copy and concatenate strings respectively. They are designed
+to be safer, more consistent, and less error prone replacements for
+.Xr strncpy 3
+and
+.Xr strncat 3 .
+Unlike those functions,
+.Fn strlcpy
+and
+.Fn strlcat
+take the full size of the buffer (not just the length) and guarantee to
+NUL-terminate the result (as long as
+.Fa size
+is larger than 0). Note that you should include a byte for the NUL in
+.Fa size .
+.Pp
+The
+.Fn strlcpy
+function copies up to
+.Fa size
+- 1 characters from the NUL-terminated string
+.Fa src
+to
+.Fa dst ,
+NUL-terminating the result.
+.Pp
+The
+.Fn strlcat
+function appends the NUL-terminated string
+.Fa src
+to the end of
+.Fa dst .
+It will append at most
+.Fa size
+- strlen(dst) - 1 bytes, NUL-terminating the result.
+.Sh RETURN VALUES
+The
+.Fn strlcpy
+and
+.Fn strlcat
+functions return the total length of the string they tried to
+create. For
+.Fn strlcpy
+that means the length of
+.Fa src .
+For
+.Fn strlcat
+that means the initial length of
+.Fa dst
+plus
+the length of
+.Fa src .
+While this may seem somewhat confusing it was done to make
+truncation detection simple.
+.Sh EXAMPLES
+The following code fragment illustrates the simple case:
+.Bd -literal -offset indent
+char *s, *p, buf[BUFSIZ];
+
+.Li ...
+
+(void)strlcpy(buf, s, sizeof(buf));
+(void)strlcat(buf, p, sizeof(buf));
+.Ed
+.Pp
+To detect truncation, perhaps while building a pathname, something
+like the following might be used:
+.Bd -literal -offset indent
+char *dir, *file, pname[MAXPATHNAMELEN];
+
+.Li ...
+
+if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
+ goto toolong;
+if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
+ goto toolong;
+.Ed
+.Pp
+Since we know how many characters we copied the first time, we can
+speed things up a bit by using a copy instead on an append:
+.Bd -literal -offset indent
+char *dir, *file, pname[MAXPATHNAMELEN];
+size_t n;
+
+.Li ...
+
+n = strlcpy(pname, dir, sizeof(pname));
+if (n >= sizeof(pname))
+ goto toolong;
+if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n)
+ goto toolong;
+.Ed
+.Pp
+However, one may question the validity of such optimizations, as they
+defeat the whole purpose of
+.Fn strlcpy
+and
+.Fn strlcat .
+As a matter of fact, the first version of this manual page got it wrong.
+.Sh SEE ALSO
+.Xr snprintf 3 ,
+.Xr strncat 3 ,
+.Xr strncpy 3
+.Sh HISTORY
+.Fn strlcpy
+and
+.Fn strlcat
+functions first appeared in
+.Ox 2.4 ,
+and made their appearance in
+.Fx 3.3 .
diff --git a/lib/libc/string/strlcpy.c b/lib/libc/string/strlcpy.c
new file mode 100644
index 0000000..300a28b
--- /dev/null
+++ b/lib/libc/string/strlcpy.c
@@ -0,0 +1,68 @@
+/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Copy src to string dst of size siz. At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t strlcpy(dst, src, siz)
+ char *dst;
+ const char *src;
+ size_t siz;
+{
+ register char *d = dst;
+ register const char *s = src;
+ register size_t n = siz;
+
+ /* Copy as many bytes as will fit */
+ if (n != 0 && --n != 0) {
+ do {
+ if ((*d++ = *s++) == 0)
+ break;
+ } while (--n != 0);
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src */
+ if (n == 0) {
+ if (siz != 0)
+ *d = '\0'; /* NUL-terminate dst */
+ while (*s++)
+ ;
+ }
+
+ return(s - src - 1); /* count does not include NUL */
+}
diff --git a/lib/libc/string/strlen.3 b/lib/libc/string/strlen.3
new file mode 100644
index 0000000..6514424
--- /dev/null
+++ b/lib/libc/string/strlen.3
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strlen.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRLEN 3
+.Os
+.Sh NAME
+.Nm strlen
+.Nd find length of string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft size_t
+.Fn strlen "const char *s"
+.Sh DESCRIPTION
+The
+.Fn strlen
+function
+computes the length of the string
+.Fa s .
+.Sh RETURN VALUES
+The
+.Fn strlen
+function
+returns
+the number of characters that precede the
+terminating
+.Dv NUL
+character.
+.Sh SEE ALSO
+.Xr string 3
+.Sh STANDARDS
+The
+.Fn strlen
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/strlen.c b/lib/libc/string/strlen.c
new file mode 100644
index 0000000..323fbe4
--- /dev/null
+++ b/lib/libc/string/strlen.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strlen.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+size_t
+strlen(str)
+ const char *str;
+{
+ register const char *s;
+
+ for (s = str; *s; ++s);
+ return(s - str);
+}
+
diff --git a/lib/libc/string/strmode.3 b/lib/libc/string/strmode.3
new file mode 100644
index 0000000..ca9bbc1
--- /dev/null
+++ b/lib/libc/string/strmode.3
@@ -0,0 +1,151 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strmode.3 8.3 (Berkeley) 7/28/94
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1994
+.Dt STRMODE 3
+.Os
+.Sh NAME
+.Nm strmode
+.Nd convert inode status information into a symbolic string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft void
+.Fn strmode "mode_t mode" "char *bp"
+.Sh DESCRIPTION
+The
+.Fn strmode
+function
+converts a file
+.Fa mode
+(the type and permission information associated with an inode, see
+.Xr stat 2 )
+into a symbolic string which is stored in the location referenced by
+.Fa bp .
+This stored string is eleven characters in length plus a trailing
+.Dv NUL .
+.Pp
+The first character is the inode type, and will be one of the following:
+.Pp
+.Bl -tag -width flag -offset indent -compact
+.It \-
+regular file
+.It b
+block special
+.It c
+character special
+.It d
+directory
+.It l
+symbolic link
+.It p
+fifo
+.It s
+socket
+.It w
+whiteout
+.It ?
+unknown inode type
+.El
+.Pp
+The next nine characters encode three sets of permissions, in three
+characters each.
+The first three characters are the permissions for the owner of the
+file, the second three for the group the file belongs to, and the
+third for the ``other'', or default, set of users.
+.Pp
+Permission checking is done as specifically as possible.
+If read permission is denied to the owner of a file in the first set
+of permissions, the owner of the file will not be able to read the file.
+This is true even if the owner is in the file's group and the group
+permissions allow reading or the ``other'' permissions allow reading.
+.Pp
+If the first character of the three character set is an ``r'', the file is
+readable for that set of users; if a dash ``\-'', it is not readable.
+.Pp
+If the second character of the three character set is a ``w'', the file is
+writable for that set of users; if a dash ``\-'', it is not writable.
+.Pp
+The third character is the first of the following characters that apply:
+.Bl -tag -width xxxx
+.It S
+If the character is part of the owner permissions and the file is not
+executable or the directory is not searchable by the owner, and the
+set-user-id bit is set.
+.It S
+If the character is part of the group permissions and the file is not
+executable or the directory is not searchable by the group, and the
+set-group-id bit is set.
+.It T
+If the character is part of the other permissions and the file is not
+executable or the directory is not searchable by others, and the ``sticky''
+.Pq Dv S_ISVTX
+bit is set.
+.It s
+If the character is part of the owner permissions and the file is
+executable or the directory searchable by the owner, and the set-user-id
+bit is set.
+.It s
+If the character is part of the group permissions and the file is
+executable or the directory searchable by the group, and the set-group-id
+bit is set.
+.It t
+If the character is part of the other permissions and the file is
+executable or the directory searchable by others, and the ``sticky''
+.Pq Dv S_ISVTX
+bit is set.
+.It x
+The file is executable or the directory is searchable.
+.It \-
+None of the above apply.
+.El
+.Pp
+The last character is a plus sign ``+'' if any there are any alternate
+or additional access control methods associated with the inode, otherwise
+it will be a space.
+.Sh RETURN VALUES
+The
+.Fn strmode
+function
+always returns 0.
+.Sh SEE ALSO
+.Xr chmod 1 ,
+.Xr find 1 ,
+.Xr stat 2 ,
+.Xr getmode 3 ,
+.Xr setmode 3
+.Sh HISTORY
+The
+.Fn strmode
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/string/strmode.c b/lib/libc/string/strmode.c
new file mode 100644
index 0000000..2c3f44a
--- /dev/null
+++ b/lib/libc/string/strmode.c
@@ -0,0 +1,152 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strmode.c 8.3 (Berkeley) 8/15/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+void
+strmode(mode, p)
+ register mode_t mode;
+ register char *p;
+{
+ /* print type */
+ switch (mode & S_IFMT) {
+ case S_IFDIR: /* directory */
+ *p++ = 'd';
+ break;
+ case S_IFCHR: /* character special */
+ *p++ = 'c';
+ break;
+ case S_IFBLK: /* block special */
+ *p++ = 'b';
+ break;
+ case S_IFREG: /* regular */
+ *p++ = '-';
+ break;
+ case S_IFLNK: /* symbolic link */
+ *p++ = 'l';
+ break;
+ case S_IFSOCK: /* socket */
+ *p++ = 's';
+ break;
+#ifdef S_IFIFO
+ case S_IFIFO: /* fifo */
+ *p++ = 'p';
+ break;
+#endif
+#ifdef S_IFWHT
+ case S_IFWHT: /* whiteout */
+ *p++ = 'w';
+ break;
+#endif
+ default: /* unknown */
+ *p++ = '?';
+ break;
+ }
+ /* usr */
+ if (mode & S_IRUSR)
+ *p++ = 'r';
+ else
+ *p++ = '-';
+ if (mode & S_IWUSR)
+ *p++ = 'w';
+ else
+ *p++ = '-';
+ switch (mode & (S_IXUSR | S_ISUID)) {
+ case 0:
+ *p++ = '-';
+ break;
+ case S_IXUSR:
+ *p++ = 'x';
+ break;
+ case S_ISUID:
+ *p++ = 'S';
+ break;
+ case S_IXUSR | S_ISUID:
+ *p++ = 's';
+ break;
+ }
+ /* group */
+ if (mode & S_IRGRP)
+ *p++ = 'r';
+ else
+ *p++ = '-';
+ if (mode & S_IWGRP)
+ *p++ = 'w';
+ else
+ *p++ = '-';
+ switch (mode & (S_IXGRP | S_ISGID)) {
+ case 0:
+ *p++ = '-';
+ break;
+ case S_IXGRP:
+ *p++ = 'x';
+ break;
+ case S_ISGID:
+ *p++ = 'S';
+ break;
+ case S_IXGRP | S_ISGID:
+ *p++ = 's';
+ break;
+ }
+ /* other */
+ if (mode & S_IROTH)
+ *p++ = 'r';
+ else
+ *p++ = '-';
+ if (mode & S_IWOTH)
+ *p++ = 'w';
+ else
+ *p++ = '-';
+ switch (mode & (S_IXOTH | S_ISVTX)) {
+ case 0:
+ *p++ = '-';
+ break;
+ case S_IXOTH:
+ *p++ = 'x';
+ break;
+ case S_ISVTX:
+ *p++ = 'T';
+ break;
+ case S_IXOTH | S_ISVTX:
+ *p++ = 't';
+ break;
+ }
+ *p++ = ' '; /* will be a '+' if ACL's implemented */
+ *p = '\0';
+}
diff --git a/lib/libc/string/strncat.c b/lib/libc/string/strncat.c
new file mode 100644
index 0000000..1b82a75
--- /dev/null
+++ b/lib/libc/string/strncat.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strncat.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+/*
+ * Concatenate src on the end of dst. At most strlen(dst)+n+1 bytes
+ * are written at dst (at most n+1 bytes being appended). Return dst.
+ */
+char *
+strncat(dst, src, n)
+ char *dst;
+ const char *src;
+ register size_t n;
+{
+ if (n != 0) {
+ register char *d = dst;
+ register const char *s = src;
+
+ while (*d != 0)
+ d++;
+ do {
+ if ((*d = *s++) == 0)
+ break;
+ d++;
+ } while (--n != 0);
+ *d = 0;
+ }
+ return (dst);
+}
diff --git a/lib/libc/string/strncmp.c b/lib/libc/string/strncmp.c
new file mode 100644
index 0000000..4b701a9
--- /dev/null
+++ b/lib/libc/string/strncmp.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strncmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+int
+strncmp(s1, s2, n)
+ register const char *s1, *s2;
+ register size_t n;
+{
+
+ if (n == 0)
+ return (0);
+ do {
+ if (*s1 != *s2++)
+ return (*(const unsigned char *)s1 -
+ *(const unsigned char *)(s2 - 1));
+ if (*s1++ == 0)
+ break;
+ } while (--n != 0);
+ return (0);
+}
diff --git a/lib/libc/string/strncpy.c b/lib/libc/string/strncpy.c
new file mode 100644
index 0000000..9e72740
--- /dev/null
+++ b/lib/libc/string/strncpy.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strncpy.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+/*
+ * Copy src to dst, truncating or null-padding to always copy n bytes.
+ * Return dst.
+ */
+char *
+strncpy(dst, src, n)
+ char *dst;
+ const char *src;
+ register size_t n;
+{
+ if (n != 0) {
+ register char *d = dst;
+ register const char *s = src;
+
+ do {
+ if ((*d++ = *s++) == 0) {
+ /* NUL pad the remaining n-1 bytes */
+ while (--n != 0)
+ *d++ = 0;
+ break;
+ }
+ } while (--n != 0);
+ }
+ return (dst);
+}
diff --git a/lib/libc/string/strpbrk.3 b/lib/libc/string/strpbrk.3
new file mode 100644
index 0000000..2b5cf12
--- /dev/null
+++ b/lib/libc/string/strpbrk.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strpbrk.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRPBRK 3
+.Os
+.Sh NAME
+.Nm strpbrk
+.Nd locate multiple characters in string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn strpbrk "const char *s" "const char *charset"
+.Sh DESCRIPTION
+The
+.Fn strpbrk
+function
+locates in the null-terminated string
+.Fa s
+the first occurrence of any character in the string
+.Fa charset
+and returns a pointer to this character.
+If no characters from
+.Fa charset
+occur anywhere in
+.Fa s
+.Fn strpbrk
+returns NULL.
+.Sh SEE ALSO
+.Xr index 3 ,
+.Xr memchr 3 ,
+.Xr rindex 3 ,
+.Xr strchr 3 ,
+.Xr strcspn 3 ,
+.Xr strrchr 3 ,
+.Xr strsep 3 ,
+.Xr strspn 3 ,
+.Xr strstr 3 ,
+.Xr strtok 3
+.Sh STANDARDS
+The
+.Fn strpbrk
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/strpbrk.c b/lib/libc/string/strpbrk.c
new file mode 100644
index 0000000..119d8b7
--- /dev/null
+++ b/lib/libc/string/strpbrk.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strpbrk.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+/*
+ * Find the first occurrence in s1 of a character in s2 (excluding NUL).
+ */
+char *
+strpbrk(s1, s2)
+ register const char *s1, *s2;
+{
+ register const char *scanp;
+ register int c, sc;
+
+ while ((c = *s1++) != 0) {
+ for (scanp = s2; (sc = *scanp++) != 0;)
+ if (sc == c)
+ return ((char *)(s1 - 1));
+ }
+ return (NULL);
+}
diff --git a/lib/libc/string/strrchr.3 b/lib/libc/string/strrchr.3
new file mode 100644
index 0000000..c44996a
--- /dev/null
+++ b/lib/libc/string/strrchr.3
@@ -0,0 +1,91 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strrchr.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRRCHR 3
+.Os
+.Sh NAME
+.Nm strrchr
+.Nd locate character in string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn strrchr "const char *s" "int c"
+.Sh DESCRIPTION
+The
+.Fn strrchr
+function
+locates the last occurrence of
+.Fa c
+(converted to a char)
+in the string
+.Fa s .
+If
+.Fa c
+is
+.Ql \e0 ,
+.Fn strrchr
+locates the terminating
+.Ql \e0 .
+.Sh RETURN VALUES
+The
+.Fn strrchr
+function
+returns a pointer to the character,
+or a null
+pointer if
+.Fa c
+does not occur anywhere in
+.Fa s .
+.Sh SEE ALSO
+.Xr index 3 ,
+.Xr memchr 3 ,
+.Xr rindex 3 ,
+.Xr strchr 3 ,
+.Xr strcspn 3 ,
+.Xr strpbrk 3 ,
+.Xr strsep 3 ,
+.Xr strspn 3 ,
+.Xr strstr 3 ,
+.Xr strtok 3
+.Sh STANDARDS
+The
+.Fn strrchr
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/strrchr.c b/lib/libc/string/strrchr.c
new file mode 100644
index 0000000..8fcf3a1
--- /dev/null
+++ b/lib/libc/string/strrchr.c
@@ -0,0 +1,2 @@
+#define STRRCHR
+#include "rindex.c"
diff --git a/lib/libc/string/strsep.3 b/lib/libc/string/strsep.3
new file mode 100644
index 0000000..f66d79e
--- /dev/null
+++ b/lib/libc/string/strsep.3
@@ -0,0 +1,110 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strsep.3 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt STRSEP 3
+.Os
+.Sh NAME
+.Nm strsep
+.Nd separate strings
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn strsep "char **stringp" "const char *delim"
+.Sh DESCRIPTION
+The
+.Fn strsep
+function locates, in the string referenced by
+.Fa *stringp ,
+the first occurrence of any character in the string
+.Fa delim
+(or the terminating
+.Ql \e0
+character) and replaces it with a
+.Ql \e0 .
+The location of the next character after the delimiter character
+(or NULL, if the end of the string was reached) is stored in
+.Fa *stringp .
+The original value of
+.Fa *stringp
+is returned.
+.Pp
+An ``empty'' field, i.e. one caused by two adjacent delimiter characters,
+can be detected by comparing the location referenced by the pointer returned
+in
+.Fa *stringp
+to
+.Ql \e0 .
+.Pp
+If
+.Fa *stringp
+is initially
+.Dv NULL ,
+.Fn strsep
+returns
+.Dv NULL .
+.Sh EXAMPLES
+The following uses
+.Fn strsep
+to parse a string, containing tokens delimited by white space, into an
+argument vector:
+.Bd -literal -offset indent
+char **ap, *argv[10], *inputstring;
+
+for (ap = argv; (*ap = strsep(&inputstring, " \et")) != NULL;)
+ if (**ap != '\e0')
+ if (++ap >= &argv[10])
+ break;
+.Ed
+.Sh HISTORY
+The
+.Fn strsep
+function
+is intended as a replacement for the
+.Fn strtok
+function.
+While the
+.Fn strtok
+function should be preferred for portability reasons (it conforms to
+.St -ansiC )
+it is unable to handle empty fields, i.e. detect fields delimited by
+two adjacent delimiter characters, or to be used for more than a single
+string at a time.
+The
+.Fn strsep
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/string/strsep.c b/lib/libc/string/strsep.c
new file mode 100644
index 0000000..ddad596
--- /dev/null
+++ b/lib/libc/string/strsep.c
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <string.h>
+#include <stdio.h>
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Get next token from string *stringp, where tokens are possibly-empty
+ * strings separated by characters from delim.
+ *
+ * Writes NULs into the string at *stringp to end tokens.
+ * delim need not remain constant from call to call.
+ * On return, *stringp points past the last NUL written (if there might
+ * be further tokens), or is NULL (if there are definitely no more tokens).
+ *
+ * If *stringp is NULL, strsep returns NULL.
+ */
+char *
+strsep(stringp, delim)
+ register char **stringp;
+ register const char *delim;
+{
+ register char *s;
+ register const char *spanp;
+ register int c, sc;
+ char *tok;
+
+ if ((s = *stringp) == NULL)
+ return (NULL);
+ for (tok = s;;) {
+ c = *s++;
+ spanp = delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *stringp = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
diff --git a/lib/libc/string/strsignal.c b/lib/libc/string/strsignal.c
new file mode 100644
index 0000000..5ec6365
--- /dev/null
+++ b/lib/libc/string/strsignal.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+char *
+strsignal(num)
+ int num;
+{
+#define UPREFIX "Unknown signal: "
+ static char ebuf[40] = UPREFIX; /* 64-bit number + slop */
+ register unsigned int signum;
+ register char *p, *t;
+ char tmp[40];
+
+ signum = num; /* convert to unsigned */
+ if (signum < sys_nsig)
+ return ((char *)sys_siglist[signum]);
+
+ /* Do this by hand, so we don't link to stdio(3). */
+ t = tmp;
+ if (num < 0)
+ signum = -signum;
+ do {
+ *t++ = "0123456789"[signum % 10];
+ } while (signum /= 10);
+ if (num < 0)
+ *t++ = '-';
+ for (p = ebuf + sizeof(UPREFIX) - 1;;) {
+ *p++ = *--t;
+ if (t <= tmp)
+ break;
+ }
+ *p = '\0';
+ return (ebuf);
+}
diff --git a/lib/libc/string/strspn.3 b/lib/libc/string/strspn.3
new file mode 100644
index 0000000..a33abc7
--- /dev/null
+++ b/lib/libc/string/strspn.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strspn.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRSPN 3
+.Os
+.Sh NAME
+.Nm strspn
+.Nd span a string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft size_t
+.Fn strspn "const char *s" "const char *charset"
+.Sh DESCRIPTION
+The
+.Fn strspn
+function
+spans the initial part of the null-terminated string
+.Fa s
+as long as the characters from
+.Fa s
+occur in string
+.Fa charset .
+.Sh RETURN VALUES
+The
+.Fn strspn
+function
+returns the number of characters spanned.
+.Sh SEE ALSO
+.Xr index 3 ,
+.Xr memchr 3 ,
+.Xr rindex 3 ,
+.Xr strchr 3 ,
+.Xr strcspn 3 ,
+.Xr strpbrk 3 ,
+.Xr strrchr 3 ,
+.Xr strsep 3 ,
+.Xr strstr 3 ,
+.Xr strtok 3
+.Sh STANDARDS
+The
+.Fn strspn
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/strspn.c b/lib/libc/string/strspn.c
new file mode 100644
index 0000000..4676bd4
--- /dev/null
+++ b/lib/libc/string/strspn.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strspn.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+/*
+ * Span the string s2 (skip characters that are in s2).
+ */
+size_t
+strspn(s1, s2)
+ const char *s1;
+ register const char *s2;
+{
+ register const char *p = s1, *spanp;
+ register char c, sc;
+
+ /*
+ * Skip any characters in s2, excluding the terminating \0.
+ */
+cont:
+ c = *p++;
+ for (spanp = s2; (sc = *spanp++) != 0;)
+ if (sc == c)
+ goto cont;
+ return (p - 1 - s1);
+}
diff --git a/lib/libc/string/strstr.3 b/lib/libc/string/strstr.3
new file mode 100644
index 0000000..dfd7ac2
--- /dev/null
+++ b/lib/libc/string/strstr.3
@@ -0,0 +1,89 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strstr.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRSTR 3
+.Os
+.Sh NAME
+.Nm strstr
+.Nd locate a substring in a string
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn strstr "const char *big" "const char *little"
+.Sh DESCRIPTION
+The
+.Fn strstr
+function
+locates the first occurrence of the null-terminated string
+.Fa little
+in the null-terminated string
+.Fa big .
+If
+.Fa little
+is the empty string,
+.Fn strstr
+returns
+.Fa big ;
+if
+.Fa little
+occurs nowhere in
+.Fa big ,
+.Fn strstr
+returns NULL;
+otherwise
+.Fn strstr
+returns a pointer to the first character of the first occurrence of
+.Fa little .
+.Sh SEE ALSO
+.Xr index 3 ,
+.Xr memchr 3 ,
+.Xr rindex 3 ,
+.Xr strchr 3 ,
+.Xr strcspn 3 ,
+.Xr strpbrk 3 ,
+.Xr strrchr 3 ,
+.Xr strsep 3 ,
+.Xr strspn 3 ,
+.Xr strtok 3
+.Sh STANDARDS
+The
+.Fn strstr
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/strstr.c b/lib/libc/string/strstr.c
new file mode 100644
index 0000000..1f10961
--- /dev/null
+++ b/lib/libc/string/strstr.c
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strstr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+/*
+ * Find the first occurrence of find in s.
+ */
+char *
+strstr(s, find)
+ register const char *s, *find;
+{
+ register char c, sc;
+ register size_t len;
+
+ if ((c = *find++) != 0) {
+ len = strlen(find);
+ do {
+ do {
+ if ((sc = *s++) == 0)
+ return (NULL);
+ } while (sc != c);
+ } while (strncmp(s, find, len) != 0);
+ s--;
+ }
+ return ((char *)s);
+}
diff --git a/lib/libc/string/strtok.3 b/lib/libc/string/strtok.3
new file mode 100644
index 0000000..26b3a1d
--- /dev/null
+++ b/lib/libc/string/strtok.3
@@ -0,0 +1,169 @@
+.\" Copyright (c) 1998 Softweyr LLC. All rights reserved.
+.\"
+.\" strtok_r, from Berkeley strtok
+.\" Oct 13, 1998 by Wes Peters <wes@softweyr.com>
+.\"
+.\" Copyright (c) 1988, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notices, this list of conditions and the following disclaimer.
+.\"
+.\" 2. Redistributions in binary form must reproduce the above
+.\" copyright notices, this list of conditions and the following
+.\" disclaimer in the documentation and/or other materials provided
+.\" with the distribution.
+.\"
+.\" 3. All advertising materials mentioning features or use of this
+.\" software must display the following acknowledgement:
+.\"
+.\" This product includes software developed by Softweyr LLC, the
+.\" University of California, Berkeley, and its contributors.
+.\"
+.\" 4. Neither the name of Softweyr LLC, the University nor the names
+.\" of its contributors may be used to endorse or promote products
+.\" derived from this software without specific prior written
+.\" permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND
+.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+.\" DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE REGENTS, OR
+.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strtok.3 8.2 (Berkeley) 2/3/94
+.\" $FreeBSD$
+.\"
+.Dd November 27, 1998
+.Dt STRTOK 3
+.Os FreeBSD 3.0
+.Sh NAME
+.Nm strtok, strtok_r
+.Nd string tokens
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn strtok "char *str" "const char *sep"
+.Ft char *
+.Fn strtok_r "char *str" "const char *sep" "char **last"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is obsoleted by strsep(3).
+.Ef
+.Pp
+The
+.Fn strtok
+function
+is used to isolate sequential tokens in a null-terminated string,
+.Fa str .
+These tokens are separated in the string by at least one of the
+characters in
+.Fa sep .
+The first time that
+.Fn strtok
+is called,
+.Fa str
+should be specified; subsequent calls, wishing to obtain further tokens
+from the same string, should pass a null pointer instead.
+The separator string,
+.Fa sep ,
+must be supplied each time, and may change between calls.
+.Pp
+The
+.Fn strtok_r
+function is a reentrant version of
+.Fn strtok .
+The context pointer
+.Fa last
+must be provided on each call.
+.Fn strtok_r
+may also be used to nest two parsing loops within one another, as
+long as separate context pointers are used.
+.Pp
+The
+.Fn strtok
+and
+.Fn strtok_r
+functions
+return a pointer to the beginning of each subsequent token in the string,
+after replacing the token itself with a
+.Dv NUL
+character.
+When no more tokens remain, a null pointer is returned.
+.Sh EXAMPLE
+The following uses
+.Fn strtok_r
+to parse two strings using separate contexts:
+.Bd -literal
+char test[80], blah[80];
+char *sep = "\e\e/:;=-";
+char *word, *phrase, *brkt, *brkb;
+
+strcpy(test, "This;is.a:test:of=the/string\e\etokenizer-function.");
+
+for (word = strtok_r(test, sep, &brkt);
+ word;
+ word = strtok_r(NULL, sep, &brkt))
+{
+ strcpy(blah, "blah:blat:blab:blag");
+
+ for (phrase = strtok_r(blah, sep, &brkb);
+ phrase;
+ phrase = strtok_r(NULL, sep, &brkb))
+ {
+ printf("So far we're at %s:%s\en", word, phrase);
+ }
+}
+.Ed
+.Sh SEE ALSO
+.Xr index 3 ,
+.Xr memchr 3 ,
+.Xr rindex 3 ,
+.Xr strchr 3 ,
+.Xr strcspn 3 ,
+.Xr strpbrk 3 ,
+.Xr strrchr 3 ,
+.Xr strsep 3 ,
+.Xr strspn 3 ,
+.Xr strstr 3
+.Sh STANDARDS
+The
+.Fn strtok
+function
+conforms to
+.St -ansiC .
+.Sh BUGS
+The System V
+.Fn strtok ,
+if handed a string containing only delimiter characters,
+will not alter the next starting point, so that a call to
+.Fn strtok
+with a different (or empty) delimiter string
+may return a
+.Pf non- Dv NULL
+value.
+Since this implementation always alters the next starting point,
+such a sequence of calls would always return
+.Dv NULL .
+.Sh AUTHORS
+.An Wes Peters, Softweyr LLC: Aq wes@softweyr.com
+.br
+Based on the
+.Fx 3.0
+implementation.
diff --git a/lib/libc/string/strtok.c b/lib/libc/string/strtok.c
new file mode 100644
index 0000000..1140bfc
--- /dev/null
+++ b/lib/libc/string/strtok.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 1998 Softweyr LLC. All rights reserved.
+ *
+ * strtok_r, from Berkeley strtok
+ * Oct 13, 1998 by Wes Peters <wes@softweyr.com>
+ *
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notices, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notices, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *
+ * This product includes software developed by Softweyr LLC, the
+ * University of California, Berkeley, and its contributors.
+ *
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE
+ * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+char *
+strtok_r(char *s, const char *delim, char **last)
+{
+ char *spanp;
+ int c, sc;
+ char *tok;
+
+ if (s == NULL && (s = *last) == NULL)
+ {
+ return NULL;
+ }
+
+ /*
+ * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+ */
+cont:
+ c = *s++;
+ for (spanp = (char *)delim; (sc = *spanp++) != 0; )
+ {
+ if (c == sc)
+ {
+ goto cont;
+ }
+ }
+
+ if (c == 0) /* no non-delimiter characters */
+ {
+ *last = NULL;
+ return NULL;
+ }
+ tok = s - 1;
+
+ /*
+ * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+ * Note that delim must have one NUL; we stop if we see that, too.
+ */
+ for (;;)
+ {
+ c = *s++;
+ spanp = (char *)delim;
+ do
+ {
+ if ((sc = *spanp++) == c)
+ {
+ if (c == 0)
+ {
+ s = NULL;
+ }
+ else
+ {
+ char *w = s - 1;
+ *w = '\0';
+ }
+ *last = s;
+ return tok;
+ }
+ }
+ while (sc != 0);
+ }
+ /* NOTREACHED */
+}
+
+
+char *
+strtok(char *s, const char *delim)
+{
+ static char *last;
+
+ return strtok_r(s, delim, &last);
+}
+
+
+#if defined(DEBUG_STRTOK)
+
+/*
+ * Test the tokenizer.
+ */
+int
+main()
+{
+ char test[80], blah[80];
+ char *sep = "\\/:;=-";
+ char *word, *phrase, *brkt, *brkb;
+
+ printf("String tokenizer test:\n");
+
+ strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function.");
+
+ for (word = strtok(test, sep);
+ word;
+ word = strtok(NULL, sep))
+ {
+ printf("Next word is \"%s\".\n", word);
+ }
+
+ phrase = "foo";
+
+ strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function.");
+
+ for (word = strtok_r(test, sep, &brkt);
+ word;
+ word = strtok_r(NULL, sep, &brkt))
+ {
+ strcpy(blah, "blah:blat:blab:blag");
+
+ for (phrase = strtok_r(blah, sep, &brkb);
+ phrase;
+ phrase = strtok_r(NULL, sep, &brkb))
+ {
+ printf("So far we're at %s:%s\n", word, phrase);
+ }
+ }
+
+ return 0;
+}
+
+#endif /* DEBUG_STRTOK */
diff --git a/lib/libc/string/strxfrm.3 b/lib/libc/string/strxfrm.3
new file mode 100644
index 0000000..81b07f6
--- /dev/null
+++ b/lib/libc/string/strxfrm.3
@@ -0,0 +1,96 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)strxfrm.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STRXFRM 3
+.Os
+.Sh NAME
+.Nm strxfrm
+.Nd transform a string under locale
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft size_t
+.Fn strxfrm "char *dst" "const char *src" "size_t n"
+.Sh DESCRIPTION
+The
+.Fn strxfrm
+function transforms a null-terminated string pointed to by
+.Fa src
+according to the current locale collation if any,
+then copies the transformed string
+into
+.Fa dst .
+Not more than
+.Fa n
+characters are copied into
+.Fa dst ,
+including the terminating null character added.
+If
+.Fa n
+is set to 0
+(it helps to determine an actual size needed
+for transformation),
+.Fa dst
+is permitted to be a NULL pointer.
+.Pp
+Comparing two strings using
+.Fn strcmp
+after
+.Fn strxfrm
+is equal to comparing
+two original strings with
+.Fn strcoll .
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn strxfrm
+returns the length of the transformed string not including
+the terminating null character. If this value is
+.Fa n
+or more, the contents of
+.Fa dst
+are indeterminate.
+.Sh SEE ALSO
+.Xr setlocale 3 ,
+.Xr strcmp 3 ,
+.Xr strcoll 3
+.Sh STANDARDS
+The
+.Fn strxfrm
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/string/strxfrm.c b/lib/libc/string/strxfrm.c
new file mode 100644
index 0000000..ac172f8
--- /dev/null
+++ b/lib/libc/string/strxfrm.c
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
+ * at Electronni Visti IA, Kiev, Ukraine.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "collate.h"
+
+size_t
+strxfrm(dest, src, len)
+ char *dest;
+ const char *src;
+ size_t len;
+{
+ int prim, sec, l;
+ size_t slen;
+ char *s, *ss;
+
+ if (!*src) {
+ if (len > 0)
+ *dest = '\0';
+ return 0;
+ }
+
+ if (__collate_load_error) {
+ slen = strlen(src);
+ if (len > 0) {
+ if (slen < len)
+ strcpy(dest, src);
+ else {
+ strncpy(dest, src, len - 1);
+ dest[len - 1] = '\0';
+ }
+ }
+ return slen;
+ }
+
+ slen = 0;
+ prim = sec = 0;
+ ss = s = __collate_substitute(src);
+ while (*s) {
+ while (*s && !prim) {
+ __collate_lookup(s, &l, &prim, &sec);
+ s += l;
+ }
+ if (prim) {
+ if (len > 1) {
+ *dest++ = (char)prim;
+ len--;
+ }
+ slen++;
+ prim = 0;
+ }
+ }
+ free(ss);
+ if (len > 0)
+ *dest = '\0';
+
+ return slen;
+}
diff --git a/lib/libc/string/swab.3 b/lib/libc/string/swab.3
new file mode 100644
index 0000000..13be3eb
--- /dev/null
+++ b/lib/libc/string/swab.3
@@ -0,0 +1,66 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)swab.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SWAB 3
+.Os
+.Sh NAME
+.Nm swab
+.Nd swap adjacent bytes
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft void
+.Fn swab "const void *src" "void *dst" "size_t len"
+.Sh DESCRIPTION
+The function
+.Fn swab
+copies
+.Fa len
+bytes from the location referenced by
+.Fa src
+to the location referenced by
+.Fa dst ,
+swapping adjacent bytes.
+.Pp
+The argument
+.Fa len
+must be even number.
+.Sh SEE ALSO
+.Xr bzero 3 ,
+.Xr memset 3
+.Sh HISTORY
+A
+.Fn swab
+function appeared in
+.At v7 .
diff --git a/lib/libc/string/swab.c b/lib/libc/string/swab.c
new file mode 100644
index 0000000..a4fc3b9
--- /dev/null
+++ b/lib/libc/string/swab.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jeffrey Mogul.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)swab.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <string.h>
+
+void
+swab(from, to, len)
+ const void *from;
+ void *to;
+ size_t len;
+{
+ register unsigned long temp;
+ register int n;
+ register char *fp, *tp;
+
+ n = (len >> 1) + 1;
+ fp = (char *)from;
+ tp = (char *)to;
+#define STEP temp = *fp++,*tp++ = *fp++,*tp++ = temp
+ /* round to multiple of 8 */
+ while ((--n) & 07)
+ STEP;
+ n >>= 3;
+ while (--n >= 0) {
+ STEP; STEP; STEP; STEP;
+ STEP; STEP; STEP; STEP;
+ }
+}
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
new file mode 100644
index 0000000..8576ef6
--- /dev/null
+++ b/lib/libc/sys/Makefile.inc
@@ -0,0 +1,151 @@
+# @(#)Makefile.inc 8.3 (Berkeley) 10/24/94
+# $FreeBSD$
+
+# sys sources
+.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/sys ${.CURDIR}/../libc/sys
+
+# Include the generated makefile containing the *complete* list
+# of syscall names in MIASM.
+.include "${.CURDIR}/../../sys/sys/syscall.mk"
+
+# Include machine dependent definitions.
+#
+# MDASM names override the default syscall names in MIASM.
+# NOASM will prevent the default syscall code from being generated.
+#
+.include "${.CURDIR}/../libc/${MACHINE_ARCH}/sys/Makefile.inc"
+
+# Sources common to both syscall interfaces:
+SRCS+= ftruncate.c lseek.c mmap.c pread.c pwrite.c truncate.c
+
+# Build __error() into libc, but not libc_r which has its own:
+.if ${LIB} == "c"
+SRCS+= __error.c
+.endif
+
+# Add machine dependent asm sources:
+SRCS+=${MDASM}
+
+# Look though the complete list of syscalls (MIASM) for names that are
+# not defined with machine dependent implementations (MDASM) and are
+# not declared for no generation of default code (NOASM). If the
+# syscall is not hidden, add it to the ASM list, otherwise add it
+# to the ASMR list.
+.for _asm in ${MIASM}
+.if (${MDASM:R:M${_asm:R}} == "")
+.if (${NOASM:R:M${_asm:R}} == "")
+.if (${HIDDEN_SYSCALLS:R:M${_asm:R}} == "")
+ASM+=$(_asm)
+.else
+ASMR+=$(_asm)
+.endif
+.endif
+.endif
+.endfor
+
+OBJS+= ${ASM} ${ASMR} ${PSEUDO} ${PSEUDOR}
+
+SASM= ${ASM:S/.o/.S/}
+
+SASMR= ${ASMR:S/.o/.S/}
+
+SPSEUDO= ${PSEUDO:S/.o/.S/}
+
+SPSEUDOR= ${PSEUDOR:S/.o/.S/}
+
+SRCS+= ${SASM} ${SASMR} ${SPSEUDO} ${SPSEUDOR}
+
+# Generated files
+CLEANFILES+= ${SASM} ${SASMR} ${SPSEUDO} ${SPSEUDOR}
+
+${SASM}:
+ printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' > ${.TARGET}
+
+${SASMR}:
+ printf '#include "SYS.h"\nPRSYSCALL(${.PREFIX})\n' > ${.TARGET}
+
+${SPSEUDO}:
+ printf '#include "SYS.h"\nPSEUDO(${.PREFIX},${.PREFIX:S/_//})\n' \
+ > ${.TARGET}
+
+${SPSEUDOR}:
+ printf '#include "SYS.h"\nPPSEUDO(${.PREFIX},${.PREFIX:S/_//})\n' \
+ > ${.TARGET}
+
+.if ${LIB} == "c"
+MAN2+= _exit.2 accept.2 access.2 acct.2 adjtime.2 \
+ aio_cancel.2 aio_error.2 aio_read.2 aio_return.2 \
+ aio_suspend.2 aio_write.2 \
+ bind.2 brk.2 chdir.2 chflags.2 \
+ chmod.2 chown.2 chroot.2 clock_gettime.2 close.2 \
+ connect.2 dup.2 execve.2 \
+ fcntl.2 fhopen.2 flock.2 fork.2 fsync.2 \
+ getdirentries.2 getdtablesize.2 \
+ getfh.2 getfsstat.2 getgid.2 getgroups.2 getitimer.2 getlogin.2 \
+ getpeername.2 getpgrp.2 getpid.2 getpriority.2 getrlimit.2 \
+ getrusage.2 getsid.2 getsockname.2 \
+ getsockopt.2 gettimeofday.2 getuid.2 \
+ intro.2 ioctl.2 issetugid.2 jail.2 kill.2 \
+ kldfind.2 kldfirstmod.2 kldload.2 kldnext.2 kldstat.2 kldunload.2 \
+ ktrace.2 link.2 listen.2 lseek.2 \
+ madvise.2 mincore.2 minherit.2 mkdir.2 mkfifo.2 mknod.2 mlock.2 mmap.2 \
+ mount.2 mprotect.2 msync.2 munmap.2 nanosleep.2 \
+ nfssvc.2 open.2 pathconf.2 pipe.2 poll.2 profil.2 ptrace.2 quotactl.2 \
+ read.2 readlink.2 reboot.2 recv.2 rename.2 revoke.2 rfork.2 rmdir.2 \
+ rtprio.2 select.2 semctl.2 semget.2 semop.2 send.2 sendfile.2 \
+ setgroups.2 setpgid.2 setregid.2 setreuid.2 setsid.2 setuid.2 \
+ shmat.2 shmctl.2 shmget.2 shutdown.2 \
+ sigaction.2 sigaltstack.2 sigpending.2 sigprocmask.2 sigreturn.2 \
+ sigstack.2 sigsuspend.2 socket.2 socketpair.2 stat.2 statfs.2 \
+ swapon.2 symlink.2 sync.2 sysarch.2 syscall.2 \
+ truncate.2 umask.2 undelete.2 \
+ unlink.2 utimes.2 vfork.2 wait.2 write.2
+.if !defined(NO_P1003_1B)
+MAN2+= sched_get_priority_max.2 sched_setparam.2 \
+ sched_setscheduler.2 sched_yield.2
+.endif
+
+MLINKS+=brk.2 sbrk.2
+MLINKS+=chdir.2 fchdir.2
+MLINKS+=chflags.2 fchflags.2
+MLINKS+=chmod.2 fchmod.2 chmod.2 lchmod.2
+MLINKS+=chown.2 fchown.2 chown.2 lchown.2
+MLINKS+=clock_gettime.2 clock_getres.2 clock_gettime.2 clock_settime.2
+MLINKS+=dup.2 dup2.2
+MLINKS+=fhopen.2 fhstat.2 fhopen.2 fhstatfs.2
+MLINKS+=getdirentries.2 getdents.2
+MLINKS+=getgid.2 getegid.2
+MLINKS+=getitimer.2 setitimer.2
+MLINKS+=getlogin.2 setlogin.2
+MLINKS+=getpgrp.2 getpgid.2
+MLINKS+=getpid.2 getppid.2
+MLINKS+=getpriority.2 setpriority.2
+MLINKS+=getrlimit.2 setrlimit.2
+MLINKS+=getsockopt.2 setsockopt.2
+MLINKS+=gettimeofday.2 settimeofday.2
+MLINKS+=getuid.2 geteuid.2
+MLINKS+=intro.2 errno.2
+MLINKS+=lseek.2 seek.2
+MLINKS+=mlock.2 munlock.2
+MLINKS+=mount.2 unmount.2
+MLINKS+=pathconf.2 fpathconf.2
+MLINKS+=read.2 pread.2 read.2 readv.2
+MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2
+MLINKS+=send.2 sendmsg.2 send.2 sendto.2
+MLINKS+=setpgid.2 setpgrp.2
+MLINKS+=setuid.2 setegid.2 setuid.2 seteuid.2 setuid.2 setgid.2
+MLINKS+=shmat.2 shmdt.2
+MLINKS+=stat.2 fstat.2 stat.2 lstat.2
+MLINKS+=statfs.2 fstatfs.2
+MLINKS+=syscall.2 __syscall.2
+MLINKS+=truncate.2 ftruncate.2
+MLINKS+=utimes.2 futimes.2 utimes.2 lutimes.2
+MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2
+MLINKS+=write.2 pwrite.2 write.2 writev.2
+.if !defined(NO_P1003_1B)
+MLINKS+=sched_get_priority_max.2 sched_get_priority_min.2 \
+ sched_get_priority_max.2 sched_rr_get_interval.2
+MLINKS+=sched_setparam.2 sched_getparam.2
+MLINKS+=sched_setscheduler.2 sched_getscheduler.2
+.endif
+.endif
diff --git a/lib/libc/sys/__error.c b/lib/libc/sys/__error.c
new file mode 100644
index 0000000..9b0c25f
--- /dev/null
+++ b/lib/libc/sys/__error.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+
+extern int errno;
+
+/*
+ * Declare a weak reference in case the application is not linked
+ * with libpthread.
+ */
+#pragma weak __error=__error_unthreaded
+
+int * __error_unthreaded()
+{
+ return(&errno);
+}
diff --git a/lib/libc/sys/_exit.2 b/lib/libc/sys/_exit.2
new file mode 100644
index 0000000..a7d282d
--- /dev/null
+++ b/lib/libc/sys/_exit.2
@@ -0,0 +1,120 @@
+.\" Copyright (c) 1980, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)_exit.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt EXIT 2
+.Os BSD 4
+.Sh NAME
+.Nm _exit
+.Nd terminate the calling process
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft void
+.Fn _exit "int status"
+.Sh DESCRIPTION
+The
+.Fn _exit
+function
+terminates a process with the following consequences:
+.Bl -bullet
+.It
+All of the descriptors open in the calling process are closed.
+This may entail delays, for example, waiting for output to drain;
+a process in this state may not be killed, as it is already dying.
+.It
+If the parent process of the calling process has an outstanding
+.Xr wait 2
+call
+or catches the
+.Dv SIGCHLD
+signal,
+it is notified of the calling process's termination and
+the
+.Em status
+is set as defined by
+.Xr wait 2 .
+.It
+The parent process-ID of all of the calling process's existing child
+processes are set to 1; the initialization process
+(see the
+.Sx DEFINITIONS
+section of
+.Xr intro 2 )
+inherits each of these processes.
+.It
+If the termination of the process causes any process group
+to become orphaned (usually because the parents of all members
+of the group have now exited; see
+.Dq orphaned process group
+in
+.Xr intro 2 ) ,
+and if any member of the orphaned group is stopped,
+the
+.Dv SIGHUP
+signal and the
+.Dv SIGCONT
+signal are sent to all members of the newly-orphaned process group.
+.It
+If the process is a controlling process (see
+.Xr intro 2 ) ,
+the
+.Dv SIGHUP
+signal is sent to the foreground process group of the controlling terminal,
+and all current access to the controlling terminal is revoked.
+.El
+.Pp
+Most C programs call the library routine
+.Xr exit 3 ,
+which flushes buffers, closes streams, unlinks temporary files, etc.,
+before
+calling
+.Fn _exit .
+.Sh RETURN VALUES
+.Fn _exit
+can never return.
+.Sh SEE ALSO
+.Xr fork 2 ,
+.Xr sigaction 2 ,
+.Xr wait 2 ,
+.Xr exit 3
+.Sh STANDARDS
+The
+.Fn _exit
+function call is expected to conform to
+.St -p1003.1-90 .
+.Sh HISTORY
+An
+.Fn _exit
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/accept.2 b/lib/libc/sys/accept.2
new file mode 100644
index 0000000..384823e
--- /dev/null
+++ b/lib/libc/sys/accept.2
@@ -0,0 +1,201 @@
+.\" Copyright (c) 1983, 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)accept.2 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt ACCEPT 2
+.Os BSD 4.2
+.Sh NAME
+.Nm accept
+.Nd accept a connection on a socket
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft int
+.Fn accept "int s" "struct sockaddr *addr" "socklen_t *addrlen"
+.Sh DESCRIPTION
+The argument
+.Fa s
+is a socket that has been created with
+.Xr socket 2 ,
+bound to an address with
+.Xr bind 2 ,
+and is listening for connections after a
+.Xr listen 2 .
+The
+.Fn accept
+argument
+extracts the first connection request
+on the queue of pending connections, creates
+a new socket with the same properties of
+.Fa s
+and allocates a new file descriptor
+for the socket. If no pending connections are
+present on the queue, and the socket is not marked
+as non-blocking,
+.Fn accept
+blocks the caller until a connection is present.
+If the socket is marked non-blocking and no pending
+connections are present on the queue,
+.Fn accept
+returns an error as described below.
+The accepted socket
+may not be used
+to accept more connections. The original socket
+.Fa s
+remains open.
+.Pp
+The argument
+.Fa addr
+is a result parameter that is filled in with
+the address of the connecting entity,
+as known to the communications layer.
+The exact format of the
+.Fa addr
+parameter is determined by the domain in which the communication
+is occurring.
+The
+.Fa addrlen
+is a value-result parameter; it should initially contain the
+amount of space pointed to by
+.Fa addr ;
+on return it will contain the actual length (in bytes) of the
+address returned.
+This call
+is used with connection-based socket types, currently with
+.Dv SOCK_STREAM .
+.Pp
+It is possible to
+.Xr select 2
+a socket for the purposes of doing an
+.Fn accept
+by selecting it for read.
+.Pp
+For certain protocols which require an explicit confirmation,
+such as
+.Tn ISO
+or
+.Tn DATAKIT ,
+.Fn accept
+can be thought of
+as merely dequeueing the next connection
+request and not implying confirmation.
+Confirmation can be implied by a normal read or write on the new
+file descriptor, and rejection can be implied by closing the
+new socket.
+.Pp
+One can obtain user connection request data without confirming
+the connection by issuing a
+.Xr recvmsg 2
+call with an
+.Fa msg_iovlen
+of 0 and a non-zero
+.Fa msg_controllen ,
+or by issuing a
+.Xr getsockopt 2
+request.
+Similarly, one can provide user connection rejection information
+by issuing a
+.Xr sendmsg 2
+call with providing only the control information,
+or by calling
+.Xr setsockopt 2 .
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn accept
+is implemented as the
+.Va accept
+syscall.
+.Pp
+In the threaded library, the
+.Va accept
+syscall is assembled to
+.Fn _thread_sys_accept
+and
+.Fn accept
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_accept .
+If the call to
+.Fn _thread_sys_accept
+would block, a context switch is performed. Before returning,
+.Fn accept
+unlocks
+.Va s .
+.Pp
+.Sh RETURN VALUES
+The call returns \-1 on error. If it succeeds, it returns a non-negative
+integer that is a descriptor for the accepted socket.
+.Sh ERRORS
+The
+.Fn accept
+will fail if:
+.Bl -tag -width EWOULDBLOCK
+.It Bq Er EBADF
+The descriptor is invalid.
+.It Bq Er EINTR
+The
+.Fn accept
+operation was interrupted.
+.It Bq Er EMFILE
+The per-process descriptor table is full.
+.It Bq Er ENFILE
+The system file table is full.
+.It Bq Er ENOTSOCK
+The descriptor references a file, not a socket.
+.It Bq Er EINVAL
+.Xr listen 2
+has not been called on the socket descriptor.
+.It Bq Er EFAULT
+The
+.Fa addr
+parameter is not in a writable part of the
+user address space.
+.It Bq Er EWOULDBLOCK
+The socket is marked non-blocking and no connections
+are present to be accepted.
+.El
+.Sh SEE ALSO
+.Xr bind 2 ,
+.Xr connect 2 ,
+.Xr getpeername 2 ,
+.Xr listen 2 ,
+.Xr select 2 ,
+.Xr socket 2
+.Sh HISTORY
+The
+.Fn accept
+function appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/access.2 b/lib/libc/sys/access.2
new file mode 100644
index 0000000..9b1c036
--- /dev/null
+++ b/lib/libc/sys/access.2
@@ -0,0 +1,135 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)access.2 8.2 (Berkeley) 4/1/94
+.\" $FreeBSD$
+.\"
+.Dd April 1, 1994
+.Dt ACCESS 2
+.Os BSD 4
+.Sh NAME
+.Nm access
+.Nd check access permissions of a file or pathname
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn access "const char *path" "int mode"
+.Sh DESCRIPTION
+The
+.Fn access
+function checks the accessibility of the
+file named by
+.Fa path
+for the access permissions indicated by
+.Fa mode .
+The value of
+.Fa mode
+is the bitwise inclusive OR of the access permissions to be
+checked
+.Pf ( Dv R_OK
+for read permission,
+.Dv W_OK
+for write permission and
+.Dv X_OK
+for execute/search permission) or the existence test,
+.Dv F_OK .
+All components of the pathname
+.Fa path
+are checked for access permissions (including
+.Dv F_OK ) .
+.Pp
+The real user ID is used in place of the effective user ID
+and the real group access list
+(including the real group ID) are
+used in place of the effective ID for verifying permission.
+.Pp
+Even if a process has appropriate privileges and indicates success for
+.Dv X_OK ,
+the file may not actually have execute permission bits set.
+Likewise for
+.Dv R_OK
+and
+.Dv W_OK .
+.Sh RETURN VALUES
+If
+.Fa path
+cannot be found or if any of the desired access modes would
+not be granted, then a -1 value is returned; otherwise
+a 0 value is returned.
+.Sh ERRORS
+Access to the file is denied if:
+.Bl -tag -width Er
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named file does not exist.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EROFS
+Write access is requested for a file on a read-only file system.
+.It Bq Er ETXTBSY
+Write access is requested for a pure procedure (shared text)
+file presently being executed.
+.It Bq Er EACCES
+Permission bits of the file mode do not permit the requested
+access, or search permission is denied on a component of the
+path prefix. The owner of a file has permission checked with
+respect to the ``owner'' read, write, and execute mode bits,
+members of the file's group other than the owner have permission
+checked with respect to the ``group'' mode bits, and all
+others have permissions checked with respect to the ``other''
+mode bits.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.El
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr stat 2
+.Sh STANDARDS
+The
+.Fn access
+function call is expected to conform to
+.St -p1003.1-90 .
+.Sh CAVEAT
+.Fn Access
+is a potential security hole and
+should never be used.
+.Sh HISTORY
+An
+.Fn access
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/acct.2 b/lib/libc/sys/acct.2
new file mode 100644
index 0000000..e0d93ae
--- /dev/null
+++ b/lib/libc/sys/acct.2
@@ -0,0 +1,115 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)acct.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ACCT 2
+.Os BSD 4
+.Sh NAME
+.Nm acct
+.Nd enable or disable process accounting
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn acct "const char *file"
+.Sh DESCRIPTION
+The
+.Fn acct
+call enables or disables the collection of system accounting
+records.
+If the argument
+.Fa file
+is a nil pointer, accounting is disabled.
+If
+.Fa file
+is an
+.Em existing
+pathname (null-terminated), record collection is enabled and for
+every process initiated which terminates under normal
+conditions an accounting record is appended to
+.Fa file .
+Abnormal conditions of termination are reboots
+or other fatal system problems.
+Records for processes which never terminate can not be
+produced by
+.Fn acct .
+.Pp
+For more information on the record structure used by
+.Fn acct ,
+see
+.Pa /usr/include/sys/acct.h
+and
+.Xr acct 5 .
+.Pp
+This call is permitted only to the super-user.
+.Sh NOTES
+Accounting is automatically disabled when the file system the
+accounting file resides on runs out of space; it is enabled when
+space once again becomes available.
+.Sh RETURN VALUES
+On error -1 is returned.
+The file must exist and the call may be exercised only by the super-user.
+.Sh ERRORS
+.Fn Acct
+will fail if one of the following is true:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The caller is not the super-user.
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named file does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix,
+or the path name is not a regular file.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EROFS
+The named file resides on a read-only file system.
+.It Bq Er EFAULT
+.Fa File
+points outside the process's allocated address space.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.El
+.Sh SEE ALSO
+.Xr acct 5 ,
+.Xr sa 8
+.Sh HISTORY
+An
+.Fn acct
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/adjtime.2 b/lib/libc/sys/adjtime.2
new file mode 100644
index 0000000..03f1b58
--- /dev/null
+++ b/lib/libc/sys/adjtime.2
@@ -0,0 +1,112 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)adjtime.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ADJTIME 2
+.Os BSD 4.3
+.Sh NAME
+.Nm adjtime
+.Nd "correct the time to allow synchronization of the system clock"
+.Sh SYNOPSIS
+.Fd #include <sys/time.h>
+.Ft int
+.Fn adjtime "const struct timeval *delta" "struct timeval *olddelta"
+.Sh DESCRIPTION
+.Fn Adjtime
+makes small adjustments to the system time, as returned by
+.Xr gettimeofday 2 ,
+advancing or retarding it
+by the time specified by the timeval
+.Fa delta .
+If
+.Fa delta
+is negative, the clock is
+slowed down by incrementing it more slowly than normal until
+the correction is complete.
+If
+.Fa delta
+is positive, a larger increment than normal
+is used.
+The skew used to perform the correction is generally a fraction of one percent.
+Thus, the time is always
+a monotonically increasing function.
+A time correction from an earlier call to
+.Fn adjtime
+may not be finished when
+.Fn adjtime
+is called again.
+If
+.Fa olddelta
+is non-nil,
+the structure pointed to will contain, upon return, the
+number of microseconds still to be corrected
+from the earlier call.
+.Pp
+This call may be used by time servers that synchronize the clocks
+of computers in a local area network.
+Such time servers would slow down the clocks of some machines
+and speed up the clocks of others to bring them to the average network time.
+.Pp
+The call
+.Fn adjtime
+is restricted to the super-user.
+.Sh RETURN VALUES
+A return value of 0 indicates that the call succeeded.
+A return value of -1 indicates that an error occurred, and in this
+case an error code is stored in the global variable
+.Va errno .
+.Sh ERRORS
+.Fn Adjtime
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+An argument points outside the process's allocated address space.
+.It Bq Er EPERM
+The process's effective user ID is not that of the super-user.
+.El
+.Sh SEE ALSO
+.Xr date 1 ,
+.Xr gettimeofday 2 ,
+.Xr timed 8 ,
+.Xr timedc 8
+.Rs
+.%T "TSP: The Time Synchronization Protocol for UNIX 4.3BSD"
+.%A R. Gusella
+.%A S. Zatti
+.Re
+.Sh HISTORY
+The
+.Fn adjtime
+function call appeared in
+.Bx 4.3 .
diff --git a/lib/libc/sys/aio_cancel.2 b/lib/libc/sys/aio_cancel.2
new file mode 100644
index 0000000..275c3eb
--- /dev/null
+++ b/lib/libc/sys/aio_cancel.2
@@ -0,0 +1,78 @@
+.\" Copyright (c) 1999 Softweyr LLC.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Softweyr LLC AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL Softweyr LLC OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1999
+.Dt AIO_CANCEL 2
+.Os
+.Sh NAME
+.Nm aio_cancel
+.Nd cancel an outstanding asynchronous I/O operation (REALTIME)
+.Sh SYNOPSIS
+.Fd #include <aio.h>
+.Ft int
+.Fn aio_cancel "int something" "struct aiocb * iocb"
+.Sh DESCRIPTION
+The
+.Fn aio_cancel
+function is supposed to cancel the specified outstanding asynchronous
+I/O request.
+.Fn aio_cancel
+is not implemented at this time, and always fails returning
+.Dv ENOSYS .
+.Sh RETURN VALUES
+When
+.Fn aio_cancel
+inevitably fails, it returns
+.Dv ENOSYS
+to signify it is not supported.
+.Sh SEE ALSO
+.Xr aio_error 2 ,
+.Xr aio_read 2 ,
+.Xr aio_return 2 ,
+.Xr aio_suspend 2 ,
+.Xr aio_write 2 .
+.Sh ERRORS
+The
+.Fn aio_cancel
+function currently always fails, due to:
+.Bl -tag -width Er
+.It Bq Er ENOSYS
+this operation is not implemented at this time.
+.El
+.Sh STANDARDS
+.Nm
+fails to conform to the
+.St -p1003.2
+standard.
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Fx 3.0 .
+.Sh AUTHORS
+This
+manual page was written by
+.An Wes Peters Aq wes@softweyr.com .
diff --git a/lib/libc/sys/aio_error.2 b/lib/libc/sys/aio_error.2
new file mode 100644
index 0000000..ae959ab
--- /dev/null
+++ b/lib/libc/sys/aio_error.2
@@ -0,0 +1,93 @@
+.\" Copyright (c) 1999 Softweyr LLC.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Softweyr LLC AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL Softweyr LLC OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1999
+.Dt AIO_ERROR 2
+.Os
+.Sh NAME
+.Nm aio_error
+.Nd retrieve error status of asynchronous I/O operation (REALTIME)
+.Sh SYNOPSIS
+.Fd #include <aio.h>
+.Ft int
+.Fn aio_error "struct aiocb *iocb"
+.Sh DESCRIPTION
+The
+.Fn aio_error
+function returns the error status of the asynchronous I/O request
+associated with the structure pointed to by
+.Ar iocb .
+.Sh RETURN VALUES
+If the asynchronous I/O request has completed successfully,
+.Fn aio_error
+returns 0. If the request has not yet completed,
+.Dv EINPROGRESS
+is returned. If the request has completed unsuccessfully the error
+status is returned as described in
+.Xr read 2 ,
+.Xr write 2 ,
+or
+.Xr fsync 2
+is returned.
+On failure,
+.Fn aio_error
+returns
+.Dv -1
+and sets
+.Dv errno
+to indicate the error condition.
+.Sh ERRORS
+The
+.Fn aio_error
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+.Ar iocb
+does not reference an outstanding asynchronous I/O request.
+.El
+.Sh SEE ALSO
+.Xr aio_cancel 2 ,
+.Xr aio_read 2 ,
+.Xr aio_return 2 ,
+.Xr aio_suspend 2 ,
+.Xr aio_write 2 ,
+.Xr fsync 2 ,
+.Xr read 2 ,
+.Xr write 2 .
+.Sh STANDARDS
+.Fn aio_error
+is expected to conform to the
+.St -p1003.2
+standard.
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Fx 3.0 .
+.Sh AUTHORS
+This
+manual page was written by
+.An Wes Peters Aq wes@softweyr.com .
diff --git a/lib/libc/sys/aio_read.2 b/lib/libc/sys/aio_read.2
new file mode 100644
index 0000000..438b647
--- /dev/null
+++ b/lib/libc/sys/aio_read.2
@@ -0,0 +1,200 @@
+.\" Copyright (c) 1998 Terry Lambert
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd November 17, 1998
+.Dt AIO_READ 2
+.Os
+.Sh NAME
+.Nm aio_read
+.Nd asynchronous read from a file (REALTIME)
+.Sh SYNOPSIS
+.Fd #include <time.h>
+.Fd #include <aio.h>
+.Ft int
+.Fn aio_read "struct aiocb *iocb"
+.Sh DESCRIPTION
+The
+.Fn aio_read
+function allows the calling process to read
+.Ar iocb->aio_nbytes
+from the descriptor
+.Ar iocb->aio_fildes
+beginning at the offset
+.Ar iocb->aio_offset
+into the buffer pointed to by
+.Ar iocb->aio_buf .
+The call returns immediately after the read request has
+been enqueued to the descriptor; the read may or may not have
+completed at the time the call returns.
+.Pp
+If _POSIX_PRIORITIZED_IO is defined, and the descriptor supports it,
+then the enqueued operation is submitted at a priority equal to that
+of the calling process minus
+.Ar iocb->aio_reqprio .
+.Pp
+The
+.Ar iocb->aio_lio_opcode
+is ignored by the
+.Fn aio_read
+call.
+.Pp
+The
+.Ar iocb
+pointer may be subsequently used as an argument to
+.Fn aio_return
+and
+.Fn aio_error
+in order to determine return or error status for the enqueued operation
+while it is in progress.
+.Pp
+If the request could not be enqueued (generally due to invalid arguments),
+then the call returns without having enqueued the request.
+.Pp
+If the request is successfully enqueued, the value of
+.Ar iocb->aio_offset
+can be modified during the request as context, so this value must
+not be referenced after the request is enqueued.
+.Sh RESTRICTIONS
+The Asynchronous I/O Control Block structure pointed to by
+.Ar iocb
+and the buffer that the
+.Ar iocb->aio_buf
+member of that structure references must remain valid until the
+operation has completed. For this reason, use of auto (stack) variables
+for these objects is discouraged.
+.Pp
+The asynchronous I/O control buffer
+.Ar iocb
+should be zeroed before the
+.Fn aio_read
+call to avoid passing bogus context information to the kernel.
+.Pp
+Modifications of the Asynchronous I/O Control Block structure or the
+buffer contents after the request has been enqueued, but before the
+request has completed, are not allowed.
+.Pp
+If the file offset in
+.Ar iocb->aio_offset
+is past the offset maximum for
+.Ar iocb->aio_fildes ,
+no I/O will occur.
+.Sh RETURN VALUES
+.Rv -std aio_read
+.Sh DIAGNOSTICS
+None.
+.Sh ERRORS
+The
+.Fn aio_read
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The request was not queued because of system resource limitations.
+.It Bq Er ENOSYS
+The
+.Fn aio_read
+call is not supported.
+.El
+.Pp
+The following conditions may be synchronously detected when the
+.Fn aio_read
+call is made, or asynchronously, at any time thereafter. If they
+are detected at call time,
+.Fn aio_read
+returns -1 and sets
+.Ar errno
+appropriately; otherwise the
+.Fn aio_return
+function must be called, and will return -1, and
+.Fn aio_error
+must be called to determine the actual calue that would have been
+returned in
+.Ar errno .
+.Pp
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Ar iocb->aio_fildes
+is invalid.
+.It Bq Er EINVAL
+The offset
+.Ar iocb->aio_offset
+is not valid, the priority specified by
+.Ar iocb->aio_reqprio
+is not a valid priority, or the number of bytes specified by
+.Ar iocb->aio_nbytes
+is not valid.
+.It Bq Er EOVERFLOW
+The file is a regular file,
+.Ar iocb->aio_nbytes
+is greater than zero, the starting offset in
+.Ar iocb->aio_offset
+is before the end of the file, but is at or beyond the
+.Ar iocb->aio_fildes
+offset maximum.
+.El
+.Pp
+If the request is successfully enqueued, but subsequently cancelled
+or an error occurs, the value returned by the
+.Fn aio_return
+function is per the
+.Xr read 2
+call, and the value returned by the
+.Fn aio_error
+function is either one of the error returns from the
+.Xr read 2
+call, or one of:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Ar iocb->aio_fildes
+is invalid for reading.
+.It Bq Er ECANCELED
+The request was explicitly cancelled via a call to
+.Fn aio_cancel .
+.It Bq Er EINVAL
+The offset
+.Ar iocb->aio_offset
+would be invalid.
+.El
+.Sh STANDARDS
+The
+.Fn aio_read
+call is expected to conform to the
+.St -p1003.2
+standard.
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Fx 3.0 .
+.Sh AUTHORS
+This
+manual page was written by
+.An Terry Lambert Aq terry@whistle.com .
+.Sh BUGS
+The value of
+.Ar iocb->aio_offset
+is ignored. Invalid information in
+.Ar iocb->_aiocb_private
+may confuse the kernel.
diff --git a/lib/libc/sys/aio_return.2 b/lib/libc/sys/aio_return.2
new file mode 100644
index 0000000..7f70fc3
--- /dev/null
+++ b/lib/libc/sys/aio_return.2
@@ -0,0 +1,95 @@
+.\" Copyright (c) 1999 Softweyr LLC.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Softweyr LLC AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL Softweyr LLC OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1999
+.Dt AIO_RETURN 2
+.Os
+.Sh NAME
+.Nm aio_return
+.Nd retrieve return status of asynchronous I/O operation (REALTIME)
+.Sh SYNOPSIS
+.Fd #include <aio.h>
+.Ft int
+.Fn aio_return "struct aiocb *iocb"
+.Sh DESCRIPTION
+The
+.Fn aio_return
+function returns the final status of the asynchronous I/O request
+associated with the structure pointed to by
+.Ar iocb .
+.Pp
+.Fn aio_return
+should only be called once, to obtain the final status of an asynchronous
+I/O operation once
+.Xr aio_error 2
+returns something other than
+.Dv EINPROGRESS .
+.Sh RETURN VALUES
+If the asynchronous I/O request has completed, the status is returned
+as described in
+.Xr read 2 ,
+.Xr write 2 ,
+or
+.Xr fsync 2 .
+On failure,
+.Fn aio_return
+returns
+.Dv -1
+and sets
+.Dv errno
+to indicate the error condition.
+.Sh SEE ALSO
+.Xr aio_cancel 2 ,
+.Xr aio_error 2 ,
+.Xr aio_read 2 ,
+.Xr aio_suspend 2 ,
+.Xr aio_write 2 ,
+.Xr fsync 2 ,
+.Xr read 2 ,
+.Xr write 2 .
+.Sh ERRORS
+The
+.Fn aio_return
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+.Ar iocb
+does not reference an outstanding asynchronous I/O request.
+.El
+.Sh STANDARDS
+.Fn aio_return
+is expected to conform to the
+.St -p1003.2
+standard.
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Fx 3.0 .
+.Sh AUTHORS
+This
+manual page was written by
+.An Wes Peters Aq wes@softweyr.com .
diff --git a/lib/libc/sys/aio_suspend.2 b/lib/libc/sys/aio_suspend.2
new file mode 100644
index 0000000..908492b
--- /dev/null
+++ b/lib/libc/sys/aio_suspend.2
@@ -0,0 +1,105 @@
+.\" Copyright (c) 1999 Softweyr LLC.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Softweyr LLC AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL Softweyr LLC OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1999
+.Dt AIO_SUSPEND 2
+.Os
+.Sh NAME
+.Nm aio_suspend
+.Nd suspend until asynchronous I/O operations or timeout complete (REALTIME)
+.Sh SYNOPSIS
+.Fd #include <aio.h>
+.Ft int
+.Fn aio_suspend "const struct aiocb * const iocbs[]" "int niocb" "const struct timespec * timeout"
+.Sh DESCRIPTION
+The
+.Fn aio_suspend
+function suspends the calling process until at least one of the
+specified asynchronous I/O requests have completed, a signal is
+delivered, or the
+.Ar timeout
+has passed.
+.Pp
+.Ar iocbs
+is an array of
+.Ar niocb
+pointers to asynchronous I/O requests. Array members containing
+NULL will be silently ignored.
+.Pp
+If
+.Ar timeout
+is a non-nil pointer, it specifies a maximum interval to suspend.
+If
+.Ar timeout
+is a nil pointer, the suspend blocks indefinitely. To effect a
+poll, the
+.Ar timeout
+should point to a zero-value timespec structure.
+.Sh RETURN VALUES
+If one or more of the specified asynchronous I/O requests have
+completed,
+.Fn aio_suspend
+returns 0. Otherwise it returns -1 and sets
+.Va errno
+to indicate the error, as enumerated below.
+.Sh SEE ALSO
+.Xr aio_cancel 2 ,
+.Xr aio_error 2 ,
+.Xr aio_read 2 ,
+.Xr aio_suspend 2 ,
+.Xr aio_write 2 .
+.Sh ERRORS
+The
+.Fn aio_suspend
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+the
+.Ar timeout
+expired before any I/O requests completed.
+.It Bq Er EINVAL
+.Ar iocbs
+contains more than
+.Dv AIO_LISTIO_MAX
+asynchronous I/O requests, or at least one of the requests is not
+valid.
+.It Bq Er EINTR
+the suspend was interrupted by a signal.
+.El
+.Sh STANDARDS
+.Fn aio_suspend
+is expected to conform to the
+.St -p1003.2
+standard.
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Fx 3.0 .
+.Sh AUTHORS
+This
+manual page was written by
+.An Wes Peters Aq wes@softweyr.com .
diff --git a/lib/libc/sys/aio_write.2 b/lib/libc/sys/aio_write.2
new file mode 100644
index 0000000..8e55423
--- /dev/null
+++ b/lib/libc/sys/aio_write.2
@@ -0,0 +1,192 @@
+.\" Copyright (c) 1999 Softweyr LLC.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Softweyr LLC AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL Softweyr LLC OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1999
+.Dt AIO_WRITE 2
+.Os
+.Sh NAME
+.Nm aio_write
+.Nd asynchronous write to a file (REALTIME)
+.Sh SYNOPSIS
+.Fd #include <aio.h>
+.Ft int
+.Fn aio_write "struct aiocb *iocb"
+.Sh DESCRIPTION
+The
+.Fn aio_write
+function allows the calling process to write
+.Ar iocb->aio_nbytes
+from the buffer pointed to by
+.Ar iocb->aio_buf
+to the descriptor
+.Ar iocb->aio_fildes .
+The call returns immediately after the write request has been enqueued
+to the descriptor; the write may or may not have completed at the time
+the call returns. If the request could not be enqueued, generally due
+to invalid arguments, the call returns without having enqueued the
+request.
+.Pp
+If
+.Dv O_APPEND
+is set for
+.Ar iocb->aio_fildes ,
+.Fn aio_write
+operations append to the file in the same order as the calls were
+made. If
+.Dv O_APPEND
+is not set for the file descriptor, the write operation will occur at
+the absolute position from the beginning of the file plus
+.Ar iocb->aio_offset .
+.Pp
+If
+.Dv _POSIX_PRIORITIZED_IO
+is defined, and the descriptor supports it, then the enqueued
+operation is submitted at a priority equal to that of the calling
+process minus
+.Ar iocb->aio_reqprio .
+.Pp
+The
+.Ar iocb
+pointer may be subsequently used as an argument to
+.Fn aio_return
+and
+.Fn aio_error
+in order to determine return or error status for the enqueued operation
+while it is in progress.
+.Pp
+If the request is successfully enqueued, the value of
+.Ar iocb->aio_offset
+can be modified during the request as context, so this value must not
+be referenced after the request is enqueued.
+.Sh RESTRICTIONS
+The Asynchronous I/O Control Block structure pointed to by
+.Ar iocb
+and the buffer that the
+.Ar iocb->aio_buf
+member of that structure references must remain valid until the
+operation has completed. For this reason, use of auto (stack) variables
+for these objects is discouraged.
+.Pp
+The asynchronous I/O control buffer
+.Ar iocb
+should be zeroed before the
+.Fn aio_read
+call to avoid passing bogus context information to the kernel.
+.Pp
+Modifications of the Asynchronous I/O Control Block structure or the
+buffer contents after the request has been enqueued, but before the
+request has completed, are not allowed.
+.Pp
+If the file offset in
+.Ar iocb->aio_offset
+is past the offset maximum for
+.Ar iocb->aio_fildes ,
+no I/O will occur.
+.Sh RETURN VALUES
+.Rv -std aio_write
+.Sh ERRORS
+The
+.Fn aio_write
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The request was not queued because of system resource limitations.
+.It Bq Er ENOSYS
+The
+.Fn aio_write
+call is not supported.
+.El
+.Pp
+The following conditions may be synchronously detected when the
+.Fn aio_write
+call is made, or asynchronously, at any time thereafter. If they
+are detected at call time,
+.Fn aio_write
+returns -1 and sets
+.Ar errno
+appropriately; otherwise the
+.Fn aio_return
+function must be called, and will return -1, and
+.Fn aio_error
+must be called to determine the actual value that would have been
+returned in
+.Ar errno .
+.Pp
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Ar iocb->aio_fildes
+is invalid, or is not opened for writing.
+.It Bq Er EINVAL
+The offset
+.Ar iocb->aio_offset
+is not valid, the priority specified by
+.Ar iocb->aio_reqprio
+is not a valid priority, or the number of bytes specified by
+.Ar iocb->aio_nbytes
+is not valid.
+.El
+.Pp
+If the request is successfully enqueued, but subsequently canceled
+or an error occurs, the value returned by the
+.Fn aio_return
+function is per the
+.Xr write 2
+call, and the value returned by the
+.Fn aio_error
+function is either one of the error returns from the
+.Xr write 2
+call, or one of:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Ar iocb->aio_fildes
+is invalid for writing.
+.It Bq Er ECANCELED
+The request was explicitly canceled via a call to
+.Fn aio_cancel .
+.It Bq Er EINVAL
+The offset
+.Ar iocb->aio_offset
+would be invalid.
+.El
+.Sh STANDARDS
+.Fn aio_write
+is expected to conform to the
+.St -p1003.2
+standard.
+.Sh HISTORY
+The
+.Nm
+Function first appeared in
+.Fx 3.0 .
+.Sh AUTHORS
+This manual page was written by
+.An Wes Peters Aq wes@softweyr.com .
+.Sh BUGS
+Asynchronous I/O operations cannot be canceled in this implementation.
+Invalid information in
+.Ar iocb->_aiocb_private
+may confuse the kernel.
+
diff --git a/lib/libc/sys/bind.2 b/lib/libc/sys/bind.2
new file mode 100644
index 0000000..316ed18
--- /dev/null
+++ b/lib/libc/sys/bind.2
@@ -0,0 +1,147 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)bind.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt BIND 2
+.Os BSD 4.2
+.Sh NAME
+.Nm bind
+.Nd assign a local protocol address to a socket.
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft int
+.Fn bind "int s" "const struct sockaddr *addr" "socklen_t addrlen"
+.Sh DESCRIPTION
+.Fn Bind
+assigns the local protocol address to a socket.
+When a socket is created
+with
+.Xr socket 2
+it exists in an address family space but has no protocol address assigned.
+.Fn Bind
+requests that
+.Fa addr
+be assigned to the socket.
+.Sh NOTES
+Binding an address in the UNIX domain creates a socket in the file
+system that must be deleted by the caller when it is no longer
+needed (using
+.Xr unlink 2 ) .
+.Pp
+The rules used in address binding vary between communication domains.
+Consult the manual entries in section 4 for detailed information.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn bind
+is implemented as the
+.Va bind
+syscall.
+.Pp
+In the threaded library, the
+.Va bind
+syscall is assembled to
+.Fn _thread_sys_bind
+and
+.Fn bind
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_bind .
+Before returning,
+.Fn bind
+unlocks
+.Va s .
+.Sh RETURN VALUES
+If the bind is successful, a 0 value is returned.
+A return value of -1 indicates an error, which is
+further specified in the global
+.Va errno .
+.Sh ERRORS
+The
+.Fn bind
+call will fail if:
+.Bl -tag -width EADDRNOTAVA
+.It Bq Er EAGAIN
+Kernel resources to complete the request are
+temporarily unavilable.
+.It Bq Er EBADF
+.Fa S
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+.Fa S
+is not a socket.
+.It Bq Er EADDRNOTAVAIL
+The specified address is not available from the local machine.
+.It Bq Er EADDRINUSE
+The specified address is already in use.
+.It Bq Er EACCES
+The requested address is protected, and the current user
+has inadequate permission to access it.
+.It Bq Er EFAULT
+The
+.Fa addr
+parameter is not in a valid part of the user
+address space.
+.El
+.Pp
+The following errors are specific to binding addresses in the UNIX domain.
+.Bl -tag -width EADDRNOTAVA
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+A prefix component of the path name does not exist.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EIO
+An I/O error occurred while making the directory entry or allocating the inode.
+.It Bq Er EROFS
+The name would reside on a read-only file system.
+.It Bq Er EISDIR
+An empty pathname was specified.
+.El
+.Sh SEE ALSO
+.Xr connect 2 ,
+.Xr getsockname 2 ,
+.Xr listen 2 ,
+.Xr socket 2
+.Sh HISTORY
+The
+.Fn bind
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/brk.2 b/lib/libc/sys/brk.2
new file mode 100644
index 0000000..4db6072
--- /dev/null
+++ b/lib/libc/sys/brk.2
@@ -0,0 +1,150 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)brk.2 8.4 (Berkeley) 5/1/95
+.\" $FreeBSD$
+.\"
+.Dd May 1, 1995
+.Dt BRK 2
+.Os BSD 4
+.Sh NAME
+.Nm brk ,
+.Nm sbrk
+.Nd change data segment size
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft char *
+.Fn brk "const char *addr"
+.Ft char *
+.Fn sbrk "int incr"
+.Sh DESCRIPTION
+.Bf -symbolic
+The brk and sbrk functions are historical curiosities
+left over from earlier days before the advent of virtual memory management.
+.Ef
+The
+.Fn brk
+function
+sets the break or lowest address
+of a process's data segment (uninitialized data) to
+.Fa addr
+(immediately above bss).
+Data addressing is restricted between
+.Fa addr
+and the lowest stack pointer to the stack segment.
+Memory is allocated by
+.Fa brk
+in page size pieces;
+if
+.Fa addr
+is not evenly divisible by the system page size, it is
+increased to the next page boundary.
+.Pp
+.\" The
+.\" .Nm sbrk
+.\" function
+.\" allocates chunks of
+.\" .Fa incr
+.\" bytes
+.\" to the process's data space
+.\" and returns an address pointer.
+.\" The
+.\" .Xr malloc 3
+.\" function utilizes
+.\" .Nm sbrk .
+.\" .Pp
+The current value of the program break is reliably returned by
+.Dq Li sbrk(0)
+(see also
+.Xr end 3 ) .
+The
+.Xr getrlimit 2
+system call may be used to determine
+the maximum permissible size of the
+.Em data
+segment;
+it will not be possible to set the break
+beyond the
+.Em rlim_max
+value returned from a call to
+.Xr getrlimit 2 ,
+e.g.
+.Dq etext + rlp\(->rlim_max.
+(see
+.Xr end 3
+for the definition of
+.Em etext ) .
+.Sh RETURN VALUES
+.Fn Brk
+returns 0 if successful;
+otherwise -1 with
+.Va errno
+set to indicate why the allocation failed.
+The
+.Fn sbrk
+function returns a pointer to the base of the new storage if successful;
+otherwise -1 with
+.Va errno
+set to indicate why the allocation failed.
+.Sh ERRORS
+.Fn Brk
+or
+.Fn sbrk
+will fail and no additional memory will be allocated if
+one of the following are true:
+.Bl -tag -width [ENOMEM]
+.It Bq Er ENOMEM
+The limit, as set by
+.Xr setrlimit 2 ,
+was exceeded.
+.It Bq Er ENOMEM
+The maximum possible size of a data segment (compiled into the
+system) was exceeded.
+.It Bq Er ENOMEM
+Insufficient space existed in the swap area
+to support the expansion.
+.El
+.Sh SEE ALSO
+.Xr execve 2 ,
+.Xr getrlimit 2 ,
+.Xr end 3 ,
+.Xr malloc 3
+.Sh BUGS
+Setting the break may fail due to a temporary lack of
+swap space. It is not possible to distinguish this
+from a failure caused by exceeding the maximum size of
+the data segment without consulting
+.Xr getrlimit 2 .
+.Sh HISTORY
+A
+.Fn brk
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/chdir.2 b/lib/libc/sys/chdir.2
new file mode 100644
index 0000000..51622f8
--- /dev/null
+++ b/lib/libc/sys/chdir.2
@@ -0,0 +1,133 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)chdir.2 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt CHDIR 2
+.Os BSD 4
+.Sh NAME
+.Nm chdir ,
+.Nm fchdir
+.Nd change current working directory
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn chdir "const char *path"
+.Ft int
+.Fn fchdir "int fd"
+.Sh DESCRIPTION
+The
+.Fa path
+argument points to the pathname of a directory.
+The
+.Fn chdir
+function
+causes the named directory
+to become the current working directory, that is,
+the starting point for path searches of pathnames not beginning with
+a slash,
+.Ql / .
+.Pp
+The
+.Fn fchdir
+function
+causes the directory referenced by
+.Fa fd
+to become the current working directory,
+the starting point for path searches of pathnames not beginning with
+a slash,
+.Ql / .
+.Pp
+In order for a directory to become the current directory,
+a process must have execute (search) access to the directory.
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned.
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate
+the error.
+.Sh ERRORS
+.Fn Chdir
+will fail and the current working directory will be unchanged if
+one or more of the following are true:
+.Bl -tag -width Er
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named directory does not exist.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EACCES
+Search permission is denied for any component of
+the path name.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.El
+.Pp
+.Fn Fchdir
+will fail and the current working directory will be unchanged if
+one or more of the following are true:
+.Bl -tag -width Er
+.It Bq Er EACCES
+Search permission is denied for the directory referenced by the
+file descriptor.
+.It Bq Er ENOTDIR
+The file descriptor does not reference a directory.
+.It Bq Er EBADF
+The argument
+.Fa fd
+is not a valid file descriptor.
+.El
+.Sh SEE ALSO
+.Xr chroot 2
+.Sh STANDARDS
+The
+.Fn chdir
+function call is expected to conform to
+.St -p1003.1-90 .
+.Sh HISTORY
+A
+.Fn chdir
+function call appeared in
+.At v7 .
+The
+.Fn fchdir
+function call
+appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/chflags.2 b/lib/libc/sys/chflags.2
new file mode 100644
index 0000000..9325686
--- /dev/null
+++ b/lib/libc/sys/chflags.2
@@ -0,0 +1,169 @@
+.\" Copyright (c) 1989, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)chflags.2 8.3 (Berkeley) 5/2/95
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1995
+.Dt CHFLAGS 2
+.Os
+.Sh NAME
+.Nm chflags ,
+.Nm fchflags
+.Nd set file flags
+.Sh SYNOPSIS
+.Fd #include <sys/stat.h>
+.Fd #include <unistd.h>
+.Ft int
+.Fn chflags "const char *path" "u_long flags"
+.Ft int
+.Fn fchflags "int fd" "u_long flags"
+.Sh DESCRIPTION
+The file whose name
+is given by
+.Fa path
+or referenced by the descriptor
+.Fa fd
+has its flags changed to
+.Fa flags .
+.Pp
+The flags specified are formed by
+.Em or Ns 'ing
+the following values
+.Pp
+.Bl -tag -width "SF_IMMUTABLE" -compact -offset indent
+.It UF_NODUMP
+Do not dump the file.
+.It UF_IMMUTABLE
+The file may not be changed.
+.It UF_APPEND
+The file may only be appended to.
+.It UF_NOUNLINK
+The file may not be renamed or deleted.
+.It UF_OPAQUE
+The directory is opaque when viewed through a union stack.
+.\".It ARCHIVED
+.\"File is archived.
+.It SF_IMMUTABLE
+The file may not be changed.
+.It SF_APPEND
+The file may only be appended to.
+.It SF_NOUNLINK
+The file may not be renamed or deleted.
+.El
+.Pp
+The
+.Dq UF_IMMUTABLE ,
+.Dq UF_APPEND
+and
+.Dq UF_NOUNLINK
+flags may be set or unset by either the owner of a file or the super-user.
+.Pp
+The
+.Dq SF_IMMUTABLE ,
+.Dq SF_APPEND
+and
+.Dq SF_NOUNLINK
+flags may only be set or unset by the super-user.
+Attempts by the non-super-user to set the super-user only flags
+are silently ignored.
+These flags may be set at any time, but normally may only be unset when
+the system is in single-user mode.
+(See
+.Xr init 8
+for details.)
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned.
+Otherwise, -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Chflags
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named file does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EPERM
+The effective user ID does not match the owner of the file and
+the effective user ID is not the super-user.
+.It Bq Er EROFS
+The named file resides on a read-only file system.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.It Bq Er EIO
+An
+.Tn I/O
+error occurred while reading from or writing to the file system.
+.It Bq Er EOPNOTSUPP
+The underlying file system does not support file flags.
+.El
+.Pp
+.Fn Fchflags
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The descriptor is not valid.
+.It Bq Er EINVAL
+.Fa Fd
+refers to a socket, not to a file.
+.It Bq Er EPERM
+The effective user ID does not match the owner of the file and
+the effective user ID is not the super-user.
+.It Bq Er EROFS
+The file resides on a read-only file system.
+.It Bq Er EIO
+An
+.Tn I/O
+error occurred while reading from or writing to the file system.
+.It Bq Er EOPNOTSUPP
+The underlying file system does not support file flags.
+.El
+.Sh SEE ALSO
+.Xr chflags 1 ,
+.Xr init 8 ,
+.Xr mount_union 8
+.Sh HISTORY
+The
+.Nm chflags
+and
+.Nm fchflags
+functions first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/chmod.2 b/lib/libc/sys/chmod.2
new file mode 100644
index 0000000..87e171f
--- /dev/null
+++ b/lib/libc/sys/chmod.2
@@ -0,0 +1,223 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)chmod.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt CHMOD 2
+.Os BSD 4
+.Sh NAME
+.Nm chmod ,
+.Nm fchmod ,
+.Nm lchmod
+.Nd change mode of file
+.Sh SYNOPSIS
+.Fd #include <sys/stat.h>
+.Ft int
+.Fn chmod "const char *path" "mode_t mode"
+.Ft int
+.Fn fchmod "int fd" "mode_t mode"
+.Ft int
+.Fn lchmod "const char *path" "mode_t mode"
+.Sh DESCRIPTION
+The file permission bits of the file named specified by
+.Fa path
+or referenced by the file descriptor
+.Fa fd
+are changed to
+.Fa mode .
+The
+.Fn chmod
+function verifies that the process owner (user) either owns
+the file specified by
+.Fa path
+(or
+.Fa fd ) ,
+or
+is the super-user.
+The
+.Fn chmod
+function follows symbolic links to operate on the target of the link
+rather than the link itself.
+.Pp
+The
+.Fa lchmod
+function is similar to
+.Fn chmod
+but does not follow symbolic links.
+.Pp
+A mode is created from
+.Em or'd
+permission bit masks
+defined in
+.Aq Pa sys/stat.h :
+.Pp
+.Bd -literal -offset indent -compact
+#define S_IRWXU 0000700 /* RWX mask for owner */
+#define S_IRUSR 0000400 /* R for owner */
+#define S_IWUSR 0000200 /* W for owner */
+#define S_IXUSR 0000100 /* X for owner */
+
+#define S_IRWXG 0000070 /* RWX mask for group */
+#define S_IRGRP 0000040 /* R for group */
+#define S_IWGRP 0000020 /* W for group */
+#define S_IXGRP 0000010 /* X for group */
+
+#define S_IRWXO 0000007 /* RWX mask for other */
+#define S_IROTH 0000004 /* R for other */
+#define S_IWOTH 0000002 /* W for other */
+#define S_IXOTH 0000001 /* X for other */
+
+#define S_ISUID 0004000 /* set user id on execution */
+#define S_ISGID 0002000 /* set group id on execution */
+#define S_ISVTX 0001000 /* sticky bit */
+#ifndef _POSIX_SOURCE
+#define S_ISTXT 0001000
+#endif
+.Ed
+.Pp
+The
+.Tn FreeBSD
+VM system totally ignores the sticky bit
+.Pf ( Dv ISVTX
+) for executables. On UFS-based filesystems (FFS, MFS, LFS) the sticky
+bit may only be set upon directories.
+.Pp
+If mode
+.Dv ISVTX
+(the `sticky bit') is set on a directory,
+an unprivileged user may not delete or rename
+files of other users in that directory. The sticky bit may be
+set by any user on a directory which the user owns or has appropriate
+permissions.
+For more details of the properties of the sticky bit, see
+.Xr sticky 8 .
+.Pp
+If mode ISUID (set UID) is set on a directory,
+and the MNT_SUIDDIR option was used in the mount of the filesystem,
+then the owner of any new files and sub-directories
+created within this directory are set
+to be the same as the owner of that directory.
+If this function is enabled, new directories will inherit
+the bit from their parents. Execute bits are removed from
+the file, and it will not be given to root. This behavior does not change the
+requirements for the user to be allowed to write the file, but only the eventual
+owner after it has been created. Group inheritance is not effected.
+.Pp
+This feature is designed for use on fileservers serving PC users via
+ftp, SAMBA, or netatalk. It provides security holes for shell users and as
+such should not be used on shell machines, especially on home directories.
+This option requires the SUIDDIR
+option in the kernel to work. Only UFS filesystems support this option.
+For more details of the suiddir mount option, see
+.Xr mount 8 .
+.Pp
+Writing or changing the owner of a file
+turns off the set-user-id and set-group-id bits
+unless the user is the super-user.
+This makes the system somewhat more secure
+by protecting set-user-id (set-group-id) files
+from remaining set-user-id (set-group-id) if they are modified,
+at the expense of a degree of compatibility.
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned.
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Chmod
+will fail and the file mode will be unchanged if:
+.Bl -tag -width Er
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named file does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EPERM
+The effective user ID does not match the owner of the file and
+the effective user ID is not the super-user.
+.It Bq Er EROFS
+The named file resides on a read-only file system.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.It Bq Er EFTYPE
+An attempt was made to set the sticky bit upon an executable.
+.El
+.Pp
+.Fn Fchmod
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The descriptor is not valid.
+.It Bq Er EINVAL
+.Fa Fd
+refers to a socket, not to a file.
+.It Bq Er EROFS
+The file resides on a read-only file system.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.El
+.Sh SEE ALSO
+.Xr chmod 1 ,
+.Xr chown 2 ,
+.Xr open 2 ,
+.Xr stat 2 ,
+.Xr sticky 8
+.Sh STANDARDS
+The
+.Fn chmod
+function call is expected to conform to
+.St -p1003.1-90 ,
+except for the return of EFTYPE and the use of S_ISTXT.
+.Sh HISTORY
+A
+.Fn chmod
+function call appeared in
+.At v7 .
+The
+.Fn fchmod
+function call
+appeared in
+.Bx 4.2 .
+The
+.Fn lchmod
+function call appeared in
+.Fx 3.0 .
diff --git a/lib/libc/sys/chown.2 b/lib/libc/sys/chown.2
new file mode 100644
index 0000000..6411045
--- /dev/null
+++ b/lib/libc/sys/chown.2
@@ -0,0 +1,169 @@
+.\" Copyright (c) 1980, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)chown.2 8.4 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt CHOWN 2
+.Os BSD 4
+.Sh NAME
+.Nm chown ,
+.Nm fchown ,
+.Nm lchown
+.Nd change owner and group of a file
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn chown "const char *path" "uid_t owner" "gid_t group"
+.Ft int
+.Fn fchown "int fd" "uid_t owner" "gid_t group"
+.Ft int
+.Fn lchown "const char *path" "uid_t owner" "gid_t group"
+.Sh DESCRIPTION
+The owner ID and group ID of the file
+named by
+.Fa path
+or referenced by
+.Fa fd
+is changed as specified by the arguments
+.Fa owner
+and
+.Fa group .
+The owner of a file may change the
+.Fa group
+to a group of which
+he or she is a member,
+but the change
+.Fa owner
+capability is restricted to the super-user.
+.Pp
+.Fn Chown
+clears the set-user-id and set-group-id bits
+on the file
+to prevent accidental or mischievous creation of
+set-user-id and set-group-id programs if not executed
+by the super-user.
+.Fn chown
+follows symbolic links to operate on the target of the link
+rather than the link itself.
+.Pp
+.Fn Fchown
+is particularly useful when used in conjunction
+with the file locking primitives (see
+.Xr flock 2 ) .
+.Pp
+.Fn Lchown
+is similar to
+.Fn chown
+but does not follow symbolic links.
+.Pp
+One of the owner or group id's
+may be left unchanged by specifying it as -1.
+.Sh RETURN VALUES
+Zero is returned if the operation was successful;
+-1 is returned if an error occurs, with a more specific
+error code being placed in the global variable
+.Va errno .
+.Sh ERRORS
+.Fn Chown
+and
+.Fn lchown
+will fail and the file will be unchanged if:
+.Bl -tag -width Er
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named file does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EPERM
+The effective user ID is not the super-user.
+.It Bq Er EROFS
+The named file resides on a read-only file system.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.El
+.Pp
+.Fn Fchown
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa Fd
+does not refer to a valid descriptor.
+.It Bq Er EINVAL
+.Fa Fd
+refers to a socket, not a file.
+.It Bq Er EPERM
+The effective user ID is not the super-user.
+.It Bq Er EROFS
+The named file resides on a read-only file system.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.El
+.Sh SEE ALSO
+.Xr chgrp 1 ,
+.Xr chmod 2 ,
+.Xr flock 2 ,
+.Xr chown 8
+.Sh STANDARDS
+The
+.Fn chown
+function call is expected to conform to
+.St -p1003.1-90 .
+.Sh HISTORY
+A
+.Fn chown
+function call appeared in
+.At v7 .
+The
+.Fn fchown
+function call
+appeared in
+.Bx 4.2 .
+.Pp
+The
+.Fn chown
+function was changed to follow symbolic links in
+.Bx 4.4 .
+The
+.Fn lchown
+function was added in
+.Fx 3.0
+to compensate for the loss of functionality.
diff --git a/lib/libc/sys/chroot.2 b/lib/libc/sys/chroot.2
new file mode 100644
index 0000000..7f1a866
--- /dev/null
+++ b/lib/libc/sys/chroot.2
@@ -0,0 +1,125 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)chroot.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt CHROOT 2
+.Os BSD 4.2
+.Sh NAME
+.Nm chroot
+.Nd change root directory
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn chroot "const char *dirname"
+.Sh DESCRIPTION
+.Fa Dirname
+is the address of the pathname of a directory, terminated by an ASCII NUL.
+.Fn Chroot
+causes
+.Fa dirname
+to become the root directory,
+that is, the starting point for path searches of pathnames
+beginning with
+.Ql / .
+.Pp
+In order for a directory to become the root directory
+a process must have execute (search) access for that directory.
+.Pp
+It should be noted that
+.Fn chroot
+has no effect on the process's current directory.
+.Pp
+This call is restricted to the super-user.
+.Pp
+Depending on the setting of the
+.Ql kern.chroot_allow_open_directories
+sysctl variable, open filedescriptors which reference directories
+will make the
+.Fn chroot
+fail as follows:
+.Pp
+If
+.Ql kern.chroot_allow_open_directories
+is set to zero,
+.Fn chroot
+will always fail with EPERM if there are any directories open.
+.Pp
+If
+.Ql kern.chroot_allow_open_directories
+is set to one (the default),
+.Fn chroot
+will fail with EPERM if there are any directories open and the
+process is already subject to a
+.Fn chroot
+call.
+.Pp
+Any other value for
+.Ql kern.chroot_allow_open_directories
+will bypass the check for open directories
+.Pp
+Upon successful completion, a value of 0 is returned. Otherwise,
+a value of -1 is returned and
+.Va errno
+is set to indicate an error.
+.Sh ERRORS
+.Fn Chroot
+will fail and the root directory will be unchanged if:
+.Bl -tag -width [ENOTDIR]
+.It Bq Er ENOTDIR
+A component of the path name is not a directory.
+.It Bq Er EPERM
+The effective user ID is not the super-user, or one or more
+filedescriptors are open directories.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named directory does not exist.
+.It Bq Er EACCES
+Search permission is denied for any component of the path name.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.El
+.Sh SEE ALSO
+.Xr chdir 2
+.Sh HISTORY
+The
+.Fn chroot
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/clock_gettime.2 b/lib/libc/sys/clock_gettime.2
new file mode 100644
index 0000000..4e0dd55
--- /dev/null
+++ b/lib/libc/sys/clock_gettime.2
@@ -0,0 +1,124 @@
+.\" $OpenBSD: clock_gettime.2,v 1.4 1997/05/08 20:21:16 kstailey Exp $
+.\" $FreeBSD$
+.\"
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd May 8, 1997
+.Dt CLOCK_GETTIME 2
+.Os BSD 4
+.Sh NAME
+.Nm clock_gettime ,
+.Nm clock_settime ,
+.Nm clock_getres
+.Nd get/set/calibrate date and time
+.Sh SYNOPSIS
+.Fd #include <sys/time.h>
+.Ft int
+.Fn clock_gettime "clockid_t clock_id" "struct timespec *tp"
+.Ft int
+.Fn clock_settime "clockid_t clock_id" "const struct timespec *tp"
+.Ft int
+.Fn clock_getres "clockid_t clock_id" "struct timespec *tp"
+.Sh DESCRIPTION
+The
+.Fn clock_gettime
+and
+.Fn clock_settime
+allow the calling process to retrieve or set the value used by a clock
+which is specifed by
+.Fa clock_id .
+.Pp
+.Fa clock_id
+can be one of three values: CLOCK_REALTIME for time that increments as
+a wall clock should, CLOCK_VIRTUAL for time that increments only when
+the CPU is running in user mode on behalf of the calling process, or
+CLOCK_PROF for time that increments when the CPU is running in user or
+kernel mode.
+.Pp
+The structure pointed to by
+.Fa tp
+is defined in
+.Ao Pa sys/time.h Ac
+as:
+.Pp
+.Bd -literal
+struct timespec {
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* and nanoseconds */
+};
+.Ed
+.Pp
+Only the super-user may set the time of day.
+If the system securelevel is greater than 1 (see
+.Xr init 8 ),
+the time may only be advanced.
+This limitation is imposed to prevent a malicious super-user
+from setting arbitrary time stamps on files.
+The system time can still be adjusted backwards using the
+.Xr adjtime 2
+system call even when the system is secure.
+.Pp
+The resolution (granularity) of a clock is returned by the
+.Fn clock_getres
+call. This value is placed in a (non-NULL)
+.Fa *tp .
+.Sh RETURN
+A 0 return value indicates that the call succeeded.
+A -1 return value indicates an error occurred, and in this
+case an error code is stored into the global variable
+.Va errno .
+.Sh ERRORS
+The following error codes may be set in
+.Va errno :
+.Bl -tag -width [EFAULT]
+.It Bq Er EINVAL
+The
+.Fa clock_id
+was not a valid value.
+.It Bq Er EFAULT
+The
+.Fa *tp
+argument address referenced invalid memory.
+.It Bq Er EPERM
+A user other than the super-user attempted to set the time.
+.El
+.Sh SEE ALSO
+.Xr date 1 ,
+.Xr adjtime 2 ,
+.Xr ctime 3 ,
+.Xr timed 8
+.Sh STANDARDS
+The
+.Fn clock_gettime ,
+etc.
+functions conform to
+.St -p1003.1b-93 .
diff --git a/lib/libc/sys/close.2 b/lib/libc/sys/close.2
new file mode 100644
index 0000000..4a478e4
--- /dev/null
+++ b/lib/libc/sys/close.2
@@ -0,0 +1,157 @@
+.\" Copyright (c) 1980, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)close.2 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt CLOSE 2
+.Os BSD 4
+.Sh NAME
+.Nm close
+.Nd delete a descriptor
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn close "int d"
+.Sh DESCRIPTION
+The
+.Fn close
+call deletes a descriptor from the per-process object
+reference table.
+If this is the last reference to the underlying object, the
+object will be deactivated.
+For example, on the last close of a file
+the current
+.Em seek
+pointer associated with the file is lost;
+on the last close of a
+.Xr socket 2
+associated naming information and queued data are discarded;
+on the last close of a file holding an advisory lock
+the lock is released (see further
+.Xr flock 2 ) .
+However, the semantics of System V and
+.St -p1003.1-88
+dictate that all
+.Xr fcntl 2
+advisory record locks associated with a file for a given process
+are removed when
+.Em any
+file descriptor for that file is closed by that process.
+.Pp
+When a process exits,
+all associated file descriptors are freed, but since there is
+a limit on active descriptors per processes, the
+.Fn close
+function call
+is useful when a large quantity of file descriptors are being handled.
+.Pp
+When a process forks (see
+.Xr fork 2 ) ,
+all descriptors for the new child process reference the same
+objects as they did in the parent before the fork.
+If a new process is then to be run using
+.Xr execve 2 ,
+the process would normally inherit these descriptors. Most
+of the descriptors can be rearranged with
+.Xr dup2 2
+or deleted with
+.Fn close
+before the
+.Xr execve 2
+is attempted, but if some of these descriptors will still
+be needed if the execve fails, it is necessary to arrange for them
+to be closed if the execve succeeds.
+For this reason, the call
+.Dq Li fcntl(d, F_SETFD, 1)
+is provided,
+which arranges that a descriptor will be closed after a successful
+execve; the call
+.Dq Li fcntl(d, F_SETFD, 0)
+restores the default,
+which is to not close the descriptor.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn close
+is implemented as the
+.Va close
+syscall.
+.Pp
+In the threaded library, the
+.Va close
+syscall is assembled to
+.Fn _thread_sys_close
+and
+.Fn close
+is implemented as a function which locks
+.Va d
+for read and write, then calls
+.Fn _thread_sys_close .
+Before returning,
+.Fn close
+unlocks
+.Va d .
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned.
+Otherwise, a value of -1 is returned and the global integer variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Close
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa D
+is not an active descriptor.
+.It Bq Er EINTR
+An interrupt was received.
+.El
+.Sh SEE ALSO
+.Xr accept 2 ,
+.Xr execve 2 ,
+.Xr fcntl 2 ,
+.Xr flock 2 ,
+.Xr open 2 ,
+.Xr pipe 2 ,
+.Xr socket 2 ,
+.Xr socketpair 2
+.Sh STANDARDS
+The
+.Fn close
+function call is expected to conform to
+.St -p1003.1-90 .
+.Sh HISTORY
+A
+.Fn close
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/connect.2 b/lib/libc/sys/connect.2
new file mode 100644
index 0000000..aef52f1
--- /dev/null
+++ b/lib/libc/sys/connect.2
@@ -0,0 +1,171 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)connect.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt CONNECT 2
+.Os BSD 4.2
+.Sh NAME
+.Nm connect
+.Nd initiate a connection on a socket
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft int
+.Fn connect "int s" "const struct sockaddr *name" "socklen_t namelen"
+.Sh DESCRIPTION
+The parameter
+.Fa s
+is a socket.
+If it is of type
+.Dv SOCK_DGRAM ,
+this call specifies the peer with which the socket is to be associated;
+this address is that to which datagrams are to be sent,
+and the only address from which datagrams are to be received.
+If the socket is of type
+.Dv SOCK_STREAM ,
+this call attempts to make a connection to
+another socket.
+The other socket is specified by
+.Fa name ,
+which is an address in the communications space of the socket.
+Each communications space interprets the
+.Fa name
+parameter in its own way.
+Generally, stream sockets may successfully
+.Fn connect
+only once; datagram sockets may use
+.Fn connect
+multiple times to change their association.
+Datagram sockets may dissolve the association
+by connecting to an invalid address, such as a null address.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn connect
+is implemented as the
+.Va connect
+syscall.
+.Pp
+In the threaded library, the
+.Va connect
+syscall is assembled to
+.Fn _thread_sys_connect
+and
+.Fn connect
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_connect .
+If the call to
+.Fn _thread_sys_connect
+would block, a context switch is performed. Before returning,
+.Fn connect
+unlocks
+.Va s .
+.Sh RETURN VALUES
+If the connection or binding succeeds, 0 is returned.
+Otherwise a -1 is returned, and a more specific error
+code is stored in
+.Va errno .
+.Sh ERRORS
+The
+.Fn connect
+call fails if:
+.Bl -tag -width EADDRNOTAVAILABB
+.It Bq Er EBADF
+.Fa s
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+.Fa s
+is a descriptor for a file, not a socket.
+.It Bq Er EADDRNOTAVAIL
+The specified address is not available on this machine.
+.It Bq Er EAFNOSUPPORT
+Addresses in the specified address family cannot be used with this socket.
+.It Bq Er EISCONN
+The socket is already connected.
+.It Bq Er ETIMEDOUT
+Connection establishment timed out without establishing a connection.
+.It Bq Er ECONNREFUSED
+The attempt to connect was forcefully rejected.
+.It Bq Er ENETUNREACH
+The network isn't reachable from this host.
+.It Bq Er EADDRINUSE
+The address is already in use.
+.It Bq Er EFAULT
+The
+.Fa name
+parameter specifies an area outside
+the process address space.
+.It Bq Er EINPROGRESS
+The socket is non-blocking
+and the connection cannot
+be completed immediately.
+It is possible to
+.Xr select 2
+for completion by selecting the socket for writing.
+.It Bq Er EALREADY
+The socket is non-blocking
+and a previous connection attempt
+has not yet been completed.
+.El
+.Pp
+The following errors are specific to connecting names in the UNIX domain.
+These errors may not apply in future versions of the UNIX IPC domain.
+.Bl -tag -width EADDRNOTAVAILABB
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named socket does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er EACCES
+Write access to the named socket is denied.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.El
+.Sh SEE ALSO
+.Xr accept 2 ,
+.Xr getpeername 2 ,
+.Xr getsockname 2 ,
+.Xr select 2 ,
+.Xr socket 2
+.Sh HISTORY
+The
+.Fn connect
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/dup.2 b/lib/libc/sys/dup.2
new file mode 100644
index 0000000..6f86325
--- /dev/null
+++ b/lib/libc/sys/dup.2
@@ -0,0 +1,204 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)dup.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt DUP 2
+.Os BSD 4
+.Sh NAME
+.Nm dup ,
+.Nm dup2
+.Nd duplicate an existing file descriptor
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn dup "int oldd"
+.Ft int
+.Fn dup2 "int oldd" "int newd"
+.Sh DESCRIPTION
+.Fn Dup
+duplicates an existing object descriptor and returns its value to
+the calling process
+.Fa ( newd
+=
+.Fn dup oldd ) .
+The argument
+.Fa oldd
+is a small non-negative integer index in
+the per-process descriptor table. The value must be less
+than the size of the table, which is returned by
+.Xr getdtablesize 2 .
+The new descriptor returned by the call
+is the lowest numbered descriptor
+currently not in use by the process.
+.Pp
+The object referenced by the descriptor does not distinguish
+between
+.Fa oldd
+and
+.Fa newd
+in any way.
+Thus if
+.Fa newd
+and
+.Fa oldd
+are duplicate references to an open
+file,
+.Xr read 2 ,
+.Xr write 2
+and
+.Xr lseek 2
+calls all move a single pointer into the file,
+and append mode, non-blocking I/O and asynchronous I/O options
+are shared between the references.
+If a separate pointer into the file is desired, a different
+object reference to the file must be obtained by issuing an
+additional
+.Xr open 2
+call.
+The close-on-exec flag on the new file descriptor is unset.
+.Pp
+In
+.Fn dup2 ,
+the value of the new descriptor
+.Fa newd
+is specified. If this descriptor is already in use and
+.Fa oldd
+!=
+.Fa newd ,
+the descriptor is first deallocated as if a
+.Xr close 2
+call had been used.
+If
+.Fa oldd
+is not a valid descriptor, then
+.Fa newd
+is not closed.
+If
+.Fa oldd
+==
+.Fa newd
+and
+.Fa oldd
+is a valid descriptor, then
+.Fn dup2
+is successful, and does nothing.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn dup
+is implemented as the
+.Va dup
+syscall.
+.Pp
+In the threaded library, the
+.Va dup
+syscall is assembled to
+.Fn _thread_sys_dup
+and
+.Fn dup
+is implemented as a function which locks
+.Va oldd
+for read and write, then calls
+.Fn _thread_sys_dup .
+Before returning,
+.Fn dup
+unlocks
+.Va oldd .
+.Pp
+In the non-threaded library
+.Fn dup2
+is implemented as the
+.Va dup2
+syscall.
+.Pp
+In the threaded library, the
+.Va dup2
+syscall is assembled to
+.Fn _thread_sys_dup2
+and
+.Fn dup2
+is implemented as a function which locks both
+.Va oldd
+and
+.Va newd
+for read and write, then calls
+.Fn _thread_sys_dup2 .
+Before returning,
+.Fn dup2
+unlocks
+.Va oldd .
+and
+.Va newd .
+.Sh RETURN VALUES
+The value -1 is returned if an error occurs in either call.
+The external variable
+.Va errno
+indicates the cause of the error.
+.Sh ERRORS
+.Fn Dup
+and
+.Fn dup2
+fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa Oldd
+or
+.Fa newd
+is not a valid active descriptor
+.It Bq Er EMFILE
+Too many descriptors are active.
+.El
+.Sh SEE ALSO
+.Xr accept 2 ,
+.Xr close 2 ,
+.Xr fcntl 2 ,
+.Xr getdtablesize 2 ,
+.Xr open 2 ,
+.Xr pipe 2 ,
+.Xr socket 2 ,
+.Xr socketpair 2
+.Sh STANDARDS
+The
+.Fn dup
+and
+.Fn dup2
+function calls are expected to conform to
+.St -p1003.1-90 .
+.Sh HISTORY
+A
+.Fn dup
+and a
+.Fn dup2
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/execve.2 b/lib/libc/sys/execve.2
new file mode 100644
index 0000000..2adc7c9
--- /dev/null
+++ b/lib/libc/sys/execve.2
@@ -0,0 +1,288 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)execve.2 8.5 (Berkeley) 6/1/94
+.\" $FreeBSD$
+.\"
+.Dd June 1, 1994
+.Dt EXECVE 2
+.Os BSD 4
+.Sh NAME
+.Nm execve
+.Nd execute a file
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn execve "const char *path" "char *const argv[]" "char *const envp[]"
+.Sh DESCRIPTION
+.Fn Execve
+transforms the calling process into a new process.
+The new process is constructed from an ordinary file,
+whose name is pointed to by
+.Fa path ,
+called the
+.Em new process file .
+This file is either an executable object file,
+or a file of data for an interpreter.
+An executable object file consists of an identifying header,
+followed by pages of data representing the initial program (text)
+and initialized data pages. Additional pages may be specified
+by the header to be initialized with zero data; see
+.Xr a.out 5 .
+.Pp
+An interpreter file begins with a line of the form:
+.Pp
+.Bd -filled -offset indent -compact
+.Sy \&#!
+.Em interpreter
+.Bq Em arg
+.Ed
+.Pp
+When an interpreter file is
+.Sy execve Ap d ,
+the system actually
+.Sy execve Ap s
+the specified
+.Em interpreter .
+If the optional
+.Em arg
+is specified, it becomes the first argument to the
+.Em interpreter ,
+and the name of the originally
+.Sy execve Ap d
+file becomes the second argument;
+otherwise, the name of the originally
+.Sy execve Ap d
+file becomes the first argument. The original arguments are shifted over to
+become the subsequent arguments. The zeroth argument, normally the name of the
+.Sy execve Ap d
+file, is left unchanged.
+.Pp
+The argument
+.Fa argv
+is a pointer to a null-terminated array of
+character pointers to null-terminated character strings.
+These strings construct the argument list to be made available to the new
+process. At least one argument must be present in
+the array; by custom, the first element should be
+the name of the executed program (for example, the last component of
+.Fa path ) .
+.Pp
+The argument
+.Fa envp
+is also a pointer to a null-terminated array of
+character pointers to null-terminated strings.
+A pointer to this array is normally stored in the global variable
+.Va environ.
+These strings pass information to the
+new process that is not directly an argument to the command (see
+.Xr environ 7 ) .
+.Pp
+File descriptors open in the calling process image remain open in
+the new process image, except for those for which the close-on-exec
+flag is set (see
+.Xr close 2
+and
+.Xr fcntl 2 ) .
+Descriptors that remain open are unaffected by
+.Fn execve .
+.Pp
+Signals set to be ignored in the calling process are set to be ignored in
+the
+new process. Signals which are set to be caught in the calling process image
+are set to default action in the new process image.
+Blocked signals remain blocked regardless of changes to the signal action.
+The signal stack is reset to be undefined (see
+.Xr sigaction 2
+for more information).
+.Pp
+If the set-user-ID mode bit of the new process image file is set
+(see
+.Xr chmod 2 ) ,
+the effective user ID of the new process image is set to the owner ID
+of the new process image file.
+If the set-group-ID mode bit of the new process image file is set,
+the effective group ID of the new process image is set to the group ID
+of the new process image file.
+(The effective group ID is the first element of the group list.)
+The real user ID, real group ID and
+other group IDs of the new process image remain the same as the calling
+process image.
+After any set-user-ID and set-group-ID processing,
+the effective user ID is recorded as the saved set-user-ID,
+and the effective group ID is recorded as the saved set-group-ID.
+These values may be used in changing the effective IDs later (see
+.Xr setuid 2 ) .
+.ne 1i
+.Pp
+The set-ID bits are not honored if the respective file system has the
+.Ar nosuid
+option enabled or if the new process file is an interpreter file. Syscall
+tracing is disabled if effective IDs are changed.
+.Pp
+The new process also inherits the following attributes from
+the calling process:
+.Pp
+.Bl -column parent_process_ID -offset indent -compact
+.It process ID Ta see Xr getpid 2
+.It parent process ID Ta see Xr getppid 2
+.It process group ID Ta see Xr getpgrp 2
+.It access groups Ta see Xr getgroups 2
+.It working directory Ta see Xr chdir 2
+.It root directory Ta see Xr chroot 2
+.It control terminal Ta see Xr termios 4
+.It resource usages Ta see Xr getrusage 2
+.It interval timers Ta see Xr getitimer 2
+.It resource limits Ta see Xr getrlimit 2
+.It file mode mask Ta see Xr umask 2
+.It signal mask Ta see Xr sigvec 2 ,
+.Xr sigsetmask 2
+.El
+.Pp
+When a program is executed as a result of an
+.Fn execve
+call, it is entered as follows:
+.Bd -literal -offset indent
+main(argc, argv, envp)
+int argc;
+char **argv, **envp;
+.Ed
+.Pp
+where
+.Fa argc
+is the number of elements in
+.Fa argv
+(the ``arg count'')
+and
+.Fa argv
+points to the array of character pointers
+to the arguments themselves.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn execve
+is implemented as the
+.Va execve
+syscall.
+.Pp
+In the threaded library, the
+.Va execve
+syscall is assembled to
+.Fn _thread_sys_execve
+and
+.Fn execve
+is implemented as a function which performs user-thread
+library re-initialization and then calls
+.Fn _thread_sys_execve .
+.Sh RETURN VALUES
+As the
+.Fn execve
+function overlays the current process image
+with a new process image the successful call
+has no process to return to.
+If
+.Fn execve
+does return to the calling process an error has occurred; the
+return value will be -1 and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Execve
+will fail and return to the calling process if:
+.Bl -tag -width [ENAMETOOLONG]
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The new process file does not exist.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er EACCES
+The new process file is not an ordinary file.
+.It Bq Er EACCES
+The new process file mode denies execute permission.
+.It Bq Er ENOEXEC
+The new process file has the appropriate access
+permission, but has an invalid magic number in its header.
+.It Bq Er ETXTBSY
+The new process file is a pure procedure (shared text)
+file that is currently open for writing or reading by some process.
+.ne 1i
+.It Bq Er ENOMEM
+The new process requires more virtual memory than
+is allowed by the imposed maximum
+.Pq Xr getrlimit 2 .
+.It Bq Er E2BIG
+The number of bytes in the new process' argument list
+is larger than the system-imposed limit.
+This limit is specified by the
+.Xr sysctl 3
+MIB variable
+.Dv KERN_ARGMAX .
+.It Bq Er EFAULT
+The new process file is not as long as indicated by
+the size values in its header.
+.It Bq Er EFAULT
+.Fa Path ,
+.Fa argv ,
+or
+.Fa envp
+point
+to an illegal address.
+.It Bq Er EIO
+An I/O error occurred while reading from the file system.
+.El
+.Sh CAVEAT
+If a program is
+.Em setuid
+to a non-super-user, but is executed when
+the real
+.Em uid
+is ``root'', then the program has some of the powers
+of a super-user as well.
+.Sh SEE ALSO
+.Xr ktrace 1 ,
+.Xr _exit 2 ,
+.Xr fork 2 ,
+.Xr execl 3 ,
+.Xr exit 3 ,
+.Xr sysctl 3 ,
+.Xr environ 7 ,
+.Xr mount 8
+.Sh HISTORY
+The
+.Fn execve
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/fcntl.2 b/lib/libc/sys/fcntl.2
new file mode 100644
index 0000000..97236fe
--- /dev/null
+++ b/lib/libc/sys/fcntl.2
@@ -0,0 +1,530 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fcntl.2 8.2 (Berkeley) 1/12/94
+.\" $FreeBSD$
+.\"
+.Dd January 12, 1994
+.Dt FCNTL 2
+.Os BSD 4.2
+.Sh NAME
+.Nm fcntl
+.Nd file control
+.Sh SYNOPSIS
+.Fd #include <fcntl.h>
+.Ft int
+.Fn fcntl "int fd" "int cmd" "..."
+.Sh DESCRIPTION
+.Fn Fcntl
+provides for control over descriptors.
+The argument
+.Fa fd
+is a descriptor to be operated on by
+.Fa cmd
+as described below. Depending on the value of
+.Fa cmd ,
+.Nm
+can take an additional third argument
+.Fa "int arg" .
+.Bl -tag -width F_GETOWNX
+.It Dv F_DUPFD
+Return a new descriptor as follows:
+.Pp
+.Bl -bullet -compact -offset 4n
+.It
+Lowest numbered available descriptor greater than or equal to
+.Fa arg .
+.It
+Same object references as the original descriptor.
+.It
+New descriptor shares the same file offset if the object
+was a file.
+.It
+Same access mode (read, write or read/write).
+.It
+Same file status flags (i.e., both file descriptors
+share the same file status flags).
+.It
+The close-on-exec flag associated with the new file descriptor
+is set to remain open across
+.Xr execve 2
+system calls.
+.El
+.It Dv F_GETFD
+Get the close-on-exec flag associated with the file descriptor
+.Fa fd .
+If the low-order bit of the returned value is 0,
+the file will remain open across
+.Fn exec ,
+otherwise the file will be closed upon execution of
+.Fn exec
+.Fa ( arg
+is ignored).
+.It Dv F_SETFD
+Set the close-on-exec flag associated with
+.Fa fd
+to the low order bit of
+.Fa arg
+(0 or 1 as above).
+.It Dv F_GETFL
+Get descriptor status flags, as described below
+.Fa ( arg
+is ignored).
+.It Dv F_SETFL
+Set descriptor status flags to
+.Fa arg .
+.It Dv F_GETOWN
+Get the process ID or process group
+currently receiving
+.Dv SIGIO
+and
+.Dv SIGURG
+signals; process groups are returned
+as negative values
+.Fa ( arg
+is ignored).
+.It Dv F_SETOWN
+Set the process or process group
+to receive
+.Dv SIGIO
+and
+.Dv SIGURG
+signals;
+process groups are specified by supplying
+.Fa arg
+as negative, otherwise
+.Fa arg
+is interpreted as a process ID.
+.El
+.Pp
+The flags for the
+.Dv F_GETFL
+and
+.Dv F_SETFL
+flags are as follows:
+.Bl -tag -width O_NONBLOCKX
+.It Dv O_NONBLOCK
+Non-blocking I/O; if no data is available to a
+.Xr read 2
+call, or if a
+.Xr write 2
+operation would block,
+the read or write call returns -1 with the error
+.Er EAGAIN .
+.It Dv O_APPEND
+Force each write to append at the end of file;
+corresponds to the
+.Dv O_APPEND
+flag of
+.Xr open 2 .
+.It Dv O_ASYNC
+Enable the
+.Dv SIGIO
+signal to be sent to the process group
+when I/O is possible, e.g.,
+upon availability of data to be read.
+.El
+.Pp
+Several commands are available for doing advisory file locking;
+they all operate on the following structure:
+.ne 7v
+.Bd -literal
+struct flock {
+ off_t l_start; /* starting offset */
+ off_t l_len; /* len = 0 means until end of file */
+ pid_t l_pid; /* lock owner */
+ short l_type; /* lock type: read/write, etc. */
+ short l_whence; /* type of l_start */
+};
+.Ed
+The commands available for advisory record locking are as follows:
+.Bl -tag -width F_SETLKWX
+.It Dv F_GETLK
+Get the first lock that blocks the lock description pointed to by the
+third argument,
+.Fa arg ,
+taken as a pointer to a
+.Fa "struct flock"
+(see above).
+The information retrieved overwrites the information passed to
+.Fn fcntl
+in the
+.Fa flock
+structure.
+If no lock is found that would prevent this lock from being created,
+the structure is left unchanged by this function call except for the
+lock type which is set to
+.Dv F_UNLCK .
+.It Dv F_SETLK
+Set or clear a file segment lock according to the lock description
+pointed to by the third argument,
+.Fa arg ,
+taken as a pointer to a
+.Fa "struct flock"
+(see above).
+.Dv F_SETLK
+is used to establish shared (or read) locks
+.Dv (F_RDLCK)
+or exclusive (or write) locks,
+.Dv (F_WRLCK) ,
+as well as remove either type of lock
+.Dv (F_UNLCK) .
+If a shared or exclusive lock cannot be set,
+.Fn fcntl
+returns immediately with
+.Er EAGAIN .
+.It Dv F_SETLKW
+This command is the same as
+.Dv F_SETLK
+except that if a shared or exclusive lock is blocked by other locks,
+the process waits until the request can be satisfied.
+If a signal that is to be caught is received while
+.Fn fcntl
+is waiting for a region, the
+.Fn fcntl
+will be interrupted if the signal handler has not specified the
+.Dv SA_RESTART
+(see
+.Xr sigaction 2 ) .
+.El
+.Pp
+When a shared lock has been set on a segment of a file,
+other processes can set shared locks on that segment
+or a portion of it.
+A shared lock prevents any other process from setting an exclusive
+lock on any portion of the protected area.
+A request for a shared lock fails if the file descriptor was not
+opened with read access.
+.Pp
+An exclusive lock prevents any other process from setting a shared lock or
+an exclusive lock on any portion of the protected area.
+A request for an exclusive lock fails if the file was not
+opened with write access.
+.Pp
+The value of
+.Fa l_whence
+is
+.Dv SEEK_SET ,
+.Dv SEEK_CUR ,
+or
+.Dv SEEK_END
+to indicate that the relative offset,
+.Fa l_start
+bytes, will be measured from the start of the file,
+current position, or end of the file, respectively.
+The value of
+.Fa l_len
+is the number of consecutive bytes to be locked.
+If
+.Fa l_len
+is negative, the result is undefined.
+The
+.Fa l_pid
+field is only used with
+.Dv F_GETLK
+to return the process ID of the process holding a blocking lock.
+After a successful
+.Dv F_GETLK
+request, the value of
+.Fa l_whence
+is
+.Dv SEEK_SET .
+.Pp
+Locks may start and extend beyond the current end of a file,
+but may not start or extend before the beginning of the file.
+A lock is set to extend to the largest possible value of the
+file offset for that file if
+.Fa l_len
+is set to zero. If
+.Fa l_whence
+and
+.Fa l_start
+point to the beginning of the file, and
+.Fa l_len
+is zero, the entire file is locked.
+If an application wishes only to do entire file locking, the
+.Xr flock 2
+system call is much more efficient.
+.Pp
+There is at most one type of lock set for each byte in the file.
+Before a successful return from an
+.Dv F_SETLK
+or an
+.Dv F_SETLKW
+request when the calling process has previously existing locks
+on bytes in the region specified by the request,
+the previous lock type for each byte in the specified
+region is replaced by the new lock type.
+As specified above under the descriptions
+of shared locks and exclusive locks, an
+.Dv F_SETLK
+or an
+.Dv F_SETLKW
+request fails or blocks respectively when another process has existing
+locks on bytes in the specified region and the type of any of those
+locks conflicts with the type specified in the request.
+.Pp
+This interface follows the completely stupid semantics of System V and
+.St -p1003.1-88
+that require that all locks associated with a file for a given process are
+removed when
+.Em any
+file descriptor for that file is closed by that process.
+This semantic means that applications must be aware of any files that
+a subroutine library may access.
+For example if an application for updating the password file locks the
+password file database while making the update, and then calls
+.Xr getpwnam 3
+to retrieve a record,
+the lock will be lost because
+.Xr getpwnam 3
+opens, reads, and closes the password database.
+The database close will release all locks that the process has
+associated with the database, even if the library routine never
+requested a lock on the database.
+Another minor semantic problem with this interface is that
+locks are not inherited by a child process created using the
+.Xr fork 2
+function.
+The
+.Xr flock 2
+interface has much more rational last close semantics and
+allows locks to be inherited by child processes.
+.Xr Flock 2
+is recommended for applications that want to ensure the integrity
+of their locks when using library routines or wish to pass locks
+to their children.
+Note that
+.Xr flock 2
+and
+.Xr fcntl 2
+locks may be safely used concurrently.
+.Pp
+All locks associated with a file for a given process are
+removed when the process terminates.
+.Pp
+A potential for deadlock occurs if a process controlling a locked region
+is put to sleep by attempting to lock the locked region of another process.
+This implementation detects that sleeping until a locked region is unlocked
+would cause a deadlock and fails with an
+.Er EDEADLK
+error.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn fcntl
+is implemented as the
+.Va fcntl
+syscall.
+.Pp
+In the threaded library, the
+.Va fcntl
+syscall is assembled to
+.Fn _thread_sys_fcntl
+and
+.Fn fcntl
+is implemented as a function which disables thread rescheduling, locks
+.Va fd
+for read and write, then calls
+.Fn _thread_sys_fcntl .
+Before returning,
+.Fn fcntl
+unlocks
+.Va fd
+and enables thread rescheduling.
+.Sh RETURN VALUES
+Upon successful completion, the value returned depends on
+.Fa cmd
+as follows:
+.Bl -tag -width F_GETOWNX -offset indent
+.It Dv F_DUPFD
+A new file descriptor.
+.It Dv F_GETFD
+Value of flag (only the low-order bit is defined).
+.It Dv F_GETFL
+Value of flags.
+.It Dv F_GETOWN
+Value of file descriptor owner.
+.It other
+Value other than -1.
+.El
+.Pp
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Fcntl
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The argument
+.Fa cmd
+is
+.Dv F_SETLK ,
+the type of lock
+.Fa (l_type)
+is a shared lock
+.Dv (F_RDLCK)
+or exclusive lock
+.Dv (F_WRLCK) ,
+and the segment of a file to be locked is already
+exclusive-locked by another process;
+or the type is an exclusive lock and some portion of the
+segment of a file to be locked is already shared-locked or
+exclusive-locked by another process.
+.It Bq Er EBADF
+.Fa Fildes
+is not a valid open file descriptor.
+.Pp
+The argument
+.Fa cmd
+is
+.Dv F_SETLK
+or
+.Dv F_SETLKW ,
+the type of lock
+.Fa (l_type)
+is a shared lock
+.Dv (F_RDLCK) ,
+and
+.Fa fildes
+is not a valid file descriptor open for reading.
+.Pp
+The argument
+.Fa cmd
+is
+.Dv F_SETLK
+or
+.Dv F_SETLKW ,
+the type of lock
+.Fa (l_type)
+is an exclusive lock
+.Dv (F_WRLCK) ,
+and
+.Fa fildes
+is not a valid file descriptor open for writing.
+.It Bq Er EDEADLK
+The argument
+.Fa cmd
+is
+.Dv F_SETLKW ,
+and a deadlock condition was detected.
+.It Bq Er EINTR
+The argument
+.Fa cmd
+is
+.Dv F_SETLKW ,
+and the function was interrupted by a signal.
+.It Bq Er EINVAL
+.Fa Cmd
+is
+.Dv F_DUPFD
+and
+.Fa arg
+is negative or greater than the maximum allowable number
+(see
+.Xr getdtablesize 2 ) .
+.Pp
+The argument
+.Fa cmd
+is
+.Dv F_GETLK ,
+.Dv F_SETLK ,
+or
+.Dv F_SETLKW
+and the data to which
+.Fa arg
+points is not valid, or
+.Fa fildes
+refers to a file that does not support locking.
+.It Bq Er EMFILE
+The argument
+.Fa cmd
+is
+.Dv F_DUPFD
+and the maximum number of file descriptors permitted for the
+process are already in use,
+or no file descriptors greater than or equal to
+.Fa arg
+are available.
+.It Bq Er ENOLCK
+The argument
+.Fa cmd
+is
+.Dv F_SETLK
+or
+.Dv F_SETLKW ,
+and satisfying the lock or unlock request would result in the
+number of locked regions in the system exceeding a system-imposed limit.
+.It Bq Er EPERM
+.Fa Cmd
+is
+.Dv F_SETOWN
+and
+the process ID or process group given as an argument is in a
+different session than the caller.
+.It Bq Er ESRCH
+.Fa Cmd
+is
+.Dv F_SETOWN
+and
+the process ID given as argument is not in use.
+.El
+.Pp
+In addition, if
+.Fa fd
+refers to a descriptor open on a terminal device (as opposed to a
+descriptor open on a socket), a
+.Fa cmd
+of
+.Dv F_SETOWN
+can fail for the same reasons as in
+.Xr tcsetpgrp 3 ,
+and a
+.Fa cmd
+of
+.Dv F_GETOWN
+for the reasons as stated in
+.Xr tcgetpgrp 3 .
+.Sh SEE ALSO
+.Xr close 2 ,
+.Xr execve 2 ,
+.Xr flock 2 ,
+.Xr getdtablesize 2 ,
+.Xr open 2 ,
+.Xr sigvec 2 ,
+.Xr tcgetpgrp 3 ,
+.Xr tcsetpgrp 3
+.Sh HISTORY
+The
+.Fn fcntl
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/fhopen.2 b/lib/libc/sys/fhopen.2
new file mode 100644
index 0000000..18838a2
--- /dev/null
+++ b/lib/libc/sys/fhopen.2
@@ -0,0 +1,137 @@
+.\" $NetBSD: fhopen.2,v 1.1 1999/06/30 01:32:15 wrstuden Exp $
+.\" $FreeBSD$
+.\"
+.\" Copyright (c) 1999 National Aeronautics & Space Administration
+.\" All rights reserved.
+.\"
+.\" This software was written by William Studenmund of the
+.\" Numerical Aerospace Similation Facility, NASA Ames Research Center.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the the name of the National Aeronautics & Space Administration
+.\" nor the names of its contributors may be used to endorse or promote
+.\" products derived from this software without specific prior written
+.\" permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NATIONAL AERONAUTICS & SPACE ADMINISTRATION
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ADMINISTRATION OR CONTRIB-
+.\" UTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+.\" OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"/
+.Dd June 29, 1999
+.Dt FHOPEN 2
+.Os
+.Sh NAME
+.Nm fhopen ,
+.Nm fhstat ,
+.Nm fhstatfs
+.Nd access file via file handle
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/stat.h>
+.Fd #include <sys/mount.h>
+.Ft int
+.Fn fhopen "const fhandle_t *fhp" "int flags"
+.Ft int
+.Fn fhstat "const fhandle_t *fhp" "struct stat *sb"
+.Ft int
+.Fn fhstatfs "const fhandle_t *fhp" "struct statfs *buf"
+.Sh DESCRIPTION
+These functions provide a means to access a file given the file handle
+.Fa fhp.
+As this method bypasses directory access restrictions, these calls are
+restricted to the superuser.
+.Pp
+.Fn fhopen
+opens the file referenced by
+.Fa fhp
+for reading and/or writing as specified by the argument
+.Fa flags
+and returns the file descriptor to the calling process. The
+.Fa flags
+are specified by
+.Em or Ns 'ing
+together the flags used for the
+.Xr open 2
+call. All said flags are valid except for
+.Dv O_CREAT .
+.Pp
+.Fn fhstat
+and
+.Fn fhstatfs
+provide the functionality of the
+.Xr fstat 2
+and
+.Xr fstatfs 2
+calls except that they return information for the file refered to by
+.Fa fhp
+rather than an open file.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn fhopen
+returns the file descriptor for the opened file, while
+.Fn fhstat
+and
+.Fn fhstatfs
+return 0.
+Otherwise, -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+In addition to the errors returned by
+.Xr open 2 ,
+.Xr fstat 2 ,
+and
+.Xr fstatfs 2
+respectivly,
+.Fn fhopen ,
+.Fn fhstat ,
+and
+.Fn fhstatfs
+will return
+.Bl -tag -width Er
+.It Bq Er EINVAL
+Calling
+.Fn fhopen
+with
+.Dv O_CREAT
+set.
+.It Bq Er ESTALE
+The file handle
+.Fa fhp
+is no longer valid.
+.El
+.Sh SEE ALSO
+.Xr getfh 2 ,
+.Xr open 2 ,
+.Xr fstat 2 ,
+.Xr fstatfs 2
+.Sh HISTORY
+The
+.Fn fhopen ,
+.Fn fhstat ,
+and
+.Fn fhstatfs
+functions first appeared in
+.Nx 1.5
+and was adapted to
+.Fx 4.0
+by Alfred Perlstein.
+.Sh AUTHORS
+This man page was written by
+.An William Studenmund
+for NetBSD.
diff --git a/lib/libc/sys/flock.2 b/lib/libc/sys/flock.2
new file mode 100644
index 0000000..4d3fb06
--- /dev/null
+++ b/lib/libc/sys/flock.2
@@ -0,0 +1,172 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)flock.2 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt FLOCK 2
+.Os BSD 4.2
+.Sh NAME
+.Nm flock
+.Nd "apply or remove an advisory lock on an open file"
+.Sh SYNOPSIS
+.Fd #include <sys/file.h>
+.Fd #define LOCK_SH 0x01 /* shared file lock */
+.Fd #define LOCK_EX 0x02 /* exclusive file lock */
+.Fd #define LOCK_NB 0x04 /* don't block when locking */
+.Fd #define LOCK_UN 0x08 /* unlock file */
+.Ft int
+.Fn flock "int fd" "int operation"
+.Sh DESCRIPTION
+.Fn Flock
+applies or removes an
+.Em advisory
+lock on the file associated with the file descriptor
+.Fa fd .
+A lock is applied by specifying an
+.Fa operation
+parameter that is one of
+.Dv LOCK_SH
+or
+.Dv LOCK_EX
+with the optional addition of
+.Dv LOCK_NB .
+To unlock
+an existing lock
+.Dv operation
+should be
+.Dv LOCK_UN .
+.Pp
+Advisory locks allow cooperating processes to perform
+consistent operations on files, but do not guarantee
+consistency (i.e., processes may still access files
+without using advisory locks possibly resulting in
+inconsistencies).
+.Pp
+The locking mechanism allows two types of locks:
+.Em shared
+locks and
+.Em exclusive
+locks.
+At any time multiple shared locks may be applied to a file,
+but at no time are multiple exclusive, or both shared and exclusive,
+locks allowed simultaneously on a file.
+.Pp
+A shared lock may be
+.Em upgraded
+to an exclusive lock, and vice versa, simply by specifying
+the appropriate lock type; this results in the previous
+lock being released and the new lock applied (possibly
+after other processes have gained and released the lock).
+.Pp
+Requesting a lock on an object that is already locked
+normally causes the caller to be blocked until the lock may be
+acquired. If
+.Dv LOCK_NB
+is included in
+.Fa operation ,
+then this will not happen; instead the call will fail and
+the error
+.Er EWOULDBLOCK
+will be returned.
+.Sh NOTES
+Locks are on files, not file descriptors. That is, file descriptors
+duplicated through
+.Xr dup 2
+or
+.Xr fork 2
+do not result in multiple instances of a lock, but rather multiple
+references to a single lock. If a process holding a lock on a file
+forks and the child explicitly unlocks the file, the parent will
+lose its lock.
+.Pp
+Processes blocked awaiting a lock may be awakened by signals.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn flock
+is implemented as the
+.Va flock
+syscall.
+.Pp
+In the threaded library, the
+.Va flock
+syscall is assembled to
+.Fn _thread_sys_flock
+and
+.Fn flock
+is implemented as a function which locks
+.Va fd
+for read and write, then calls
+.Fn _thread_sys_flock .
+Before returning,
+.Fn flock
+unlocks
+.Va fd .
+.Sh RETURN VALUES
+Zero is returned if the operation was successful;
+on an error a -1 is returned and an error code is left in
+the global location
+.Va errno .
+.Sh ERRORS
+The
+.Fn flock
+call fails if:
+.Bl -tag -width EWOULDBLOCKAA
+.It Bq Er EWOULDBLOCK
+The file is locked and the
+.Dv LOCK_NB
+option was specified.
+.It Bq Er EBADF
+The argument
+.Fa fd
+is an invalid descriptor.
+.It Bq Er EINVAL
+The argument
+.Fa fd
+refers to an object other than a file.
+.It Bq Er EOPNOTSUPP
+The argument
+.Fa fd
+refers to an object that does not support file locking.
+.El
+.Sh SEE ALSO
+.Xr close 2 ,
+.Xr dup 2 ,
+.Xr execve 2 ,
+.Xr fork 2 ,
+.Xr open 2
+.Sh HISTORY
+The
+.Fn flock
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/fork.2 b/lib/libc/sys/fork.2
new file mode 100644
index 0000000..d01e600
--- /dev/null
+++ b/lib/libc/sys/fork.2
@@ -0,0 +1,127 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fork.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt FORK 2
+.Os BSD 4
+.Sh NAME
+.Nm fork
+.Nd create a new process
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <unistd.h>
+.Ft pid_t
+.Fn fork void
+.Sh DESCRIPTION
+.Fn Fork
+causes creation of a new process.
+The new process (child process) is an exact copy of the
+calling process (parent process) except for the following:
+.Bl -bullet -offset indent
+.It
+The child process has a unique process ID.
+.It
+The child process has a different parent
+process ID (i.e., the process ID of the parent process).
+.It
+The child process has its own copy of the parent's descriptors.
+These descriptors reference the same underlying objects, so that,
+for instance, file pointers in file objects are shared between
+the child and the parent, so that an
+.Xr lseek 2
+on a descriptor in the child process can affect a subsequent
+.Xr read 2
+or
+.Xr write 2
+by the parent.
+This descriptor copying is also used by the shell to
+establish standard input and output for newly created processes
+as well as to set up pipes.
+.It
+The child process' resource utilizations
+are set to 0; see
+.Xr setrlimit 2 .
+.El
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn fork
+returns a value
+of 0 to the child process and returns the process ID of the child
+process to the parent process. Otherwise, a value of -1 is returned
+to the parent process, no child process is created, and the global
+variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Fork
+will fail and no child process will be created if:
+.Bl -tag -width [EAGAIN]
+.It Bq Er EAGAIN
+The system-imposed limit on the total
+number of processes under execution would be exceeded.
+The limit is given by the
+.Xr sysctl 3
+MIB variable
+.Dv KERN_MAXPROC .
+(The limit is actually one less than this
+except for the super user).
+.It Bq Er EAGAIN
+The user is not the super user, and
+the system-imposed limit
+on the total number of
+processes under execution by a single user would be exceeded.
+The limit is given by the
+.Xr sysctl 3
+MIB variable
+.Dv KERN_MAXPROCPERUID .
+.It Bq Er EAGAIN
+The user is not the super user, and
+the soft resource limit corresponding to the resource parameter
+.Dv RLIMIT_NPROC
+would be exceeded (see
+.Xr getrlimit 2 ) .
+.It Bq Er ENOMEM
+There is insufficient swap space for the new process.
+.El
+.Sh SEE ALSO
+.Xr execve 2 ,
+.Xr rfork 2 ,
+.Xr setrlimit 2 ,
+.Xr vfork 2 ,
+.Xr wait 2
+.Sh HISTORY
+A
+.Fn fork
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/fsync.2 b/lib/libc/sys/fsync.2
new file mode 100644
index 0000000..a83ebcb
--- /dev/null
+++ b/lib/libc/sys/fsync.2
@@ -0,0 +1,104 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fsync.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt FSYNC 2
+.Os BSD 4.2
+.Sh NAME
+.Nm fsync
+.Nd "synchronize a file's in-core state with that on disk"
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn fsync "int fd"
+.Sh DESCRIPTION
+.Fn Fsync
+causes all modified data and attributes of
+.Fa fd
+to be moved to a permanent storage device.
+This normally results in all in-core modified copies
+of buffers for the associated file to be written to a disk.
+.Pp
+.Fn Fsync
+should be used by programs that require a file to be
+in a known state, for example, in building a simple transaction
+facility.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn fsync
+is implemented as the
+.Va fsync
+syscall.
+.Pp
+In the threaded library, the
+.Va fsync
+syscall is assembled to
+.Fn _thread_sys_fsync
+and
+.Fn fsync
+is implemented as a function which locks
+.Va fd
+for read and write, then calls
+.Fn _thread_sys_fsync .
+Before returning,
+.Fn fsync
+unlocks
+.Va fd .
+.Sh RETURN VALUES
+A 0 value is returned on success. A -1 value indicates
+an error.
+.Sh ERRORS
+The
+.Fn fsync
+fails if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa Fd
+is not a valid descriptor.
+.It Bq Er EINVAL
+.Fa Fd
+refers to a socket, not to a file.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.El
+.Sh SEE ALSO
+.Xr sync 2 ,
+.Xr update 4 ,
+.Xr sync 8
+.Sh HISTORY
+The
+.Fn fsync
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/ftruncate.c b/lib/libc/sys/ftruncate.c
new file mode 100644
index 0000000..9d7d5fb
--- /dev/null
+++ b/lib/libc/sys/ftruncate.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ftruncate.c 8.1 (Berkeley) 6/17/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
+
+/*
+ * This function provides 64-bit offset padding that
+ * is not supplied by GCC 1.X but is supplied by GCC 2.X.
+ */
+int
+ftruncate(fd, length)
+ int fd;
+ off_t length;
+{
+
+#ifdef _THREAD_SAFE
+ int retval;
+ if (_FD_LOCK(fd, FD_RDWR, NULL) != 0) {
+ retval = -1;
+ } else {
+ retval = __syscall((quad_t)SYS_ftruncate, fd, 0, length);
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ return(retval);
+#else
+ return(__syscall((quad_t)SYS_ftruncate, fd, 0, length));
+#endif
+}
diff --git a/lib/libc/sys/getdirentries.2 b/lib/libc/sys/getdirentries.2
new file mode 100644
index 0000000..a3ca671
--- /dev/null
+++ b/lib/libc/sys/getdirentries.2
@@ -0,0 +1,204 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getdirentries.2 8.2 (Berkeley) 5/3/95
+.\" $FreeBSD$
+.\"
+.Dd May 3, 1995
+.Dt GETDIRENTRIES 2
+.Os
+.Sh NAME
+.Nm getdirentries ,
+.Nm getdents
+.Nd "get directory entries in a filesystem independent format"
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <dirent.h>
+.Ft int
+.Fn getdirentries "int fd" "char *buf" "int nbytes" "long *basep"
+.Ft int
+.Fn getdents "int fd" "char *buf" "int nbytes"
+.Sh DESCRIPTION
+The
+.Fn getdirentries
+and
+.Fn getdents
+functions read directory entries from the directory
+referenced by the file descriptor
+.Fa fd
+into the buffer pointed to by
+.Fa buf ,
+in a filesystem independent format.
+Up to
+.Fa nbytes
+of data will be transferred.
+The
+.Fa nbytes
+argument must be greater than or equal to the
+block size associated with the file,
+see
+.Xr stat 2 .
+Some filesystems may not support these functions
+with buffers smaller than this size.
+.Pp
+The data in the buffer is a series of
+.Em dirent
+structures each containing the following entries:
+.Bd -literal -offset indent
+u_int32_t d_fileno;
+u_int16_t d_reclen;
+u_int8_t d_type;
+u_int8_t d_namlen;
+char d_name[MAXNAMELEN + 1]; /* see below */
+.Ed
+.Pp
+The
+.Fa d_fileno
+entry is a number which is unique for each
+distinct file in the filesystem.
+Files that are linked by hard links (see
+.Xr link 2 )
+have the same
+.Fa d_fileno .
+The
+.Fa d_reclen
+entry is the length, in bytes, of the directory record.
+The
+.Fa d_type
+entry is the type of the file pointed to by the directory record.
+The file type values are defined in
+.Fa <sys/dirent.h> .
+The
+.Fa d_name
+entry contains a null terminated file name.
+The
+.Fa d_namlen
+entry specifies the length of the file name excluding the null byte.
+Thus the actual size of
+.Fa d_name
+may vary from 1 to
+.Dv MAXNAMELEN
+\&+ 1.
+.Pp
+Entries may be separated by extra space.
+The
+.Fa d_reclen
+entry may be used as an offset from the start of a
+.Fa dirent
+structure to the next structure, if any.
+.Pp
+The actual number of bytes transferred is returned.
+The current position pointer associated with
+.Fa fd
+is set to point to the next block of entries.
+The pointer may not advance by the number of bytes returned by
+.Fn getdirentries
+or
+.Fn getdents .
+A value of zero is returned when
+the end of the directory has been reached.
+.Pp
+The
+.Fn getdirentries
+function writes the position of the block read into the location pointed to by
+.Fa basep .
+Alternatively, the current position pointer may be set and retrieved by
+.Xr lseek 2 .
+The current position pointer should only be set to a value returned by
+.Xr lseek 2 ,
+a value returned in the location pointed to by
+.Fa basep ( Ns Fn getdirentries
+only)
+or zero.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn getdirentries
+is implemented as the
+.Va getdirentries
+syscall.
+.Pp
+In the threaded library, the
+.Va getdirentries
+syscall is assembled to
+.Fn _thread_sys_getdirentries
+and
+.Fn getdirentries
+is implemented as a function which locks
+.Va fd
+for read and write, then calls
+.Fn _thread_sys_getdirentries .
+Before returning,
+.Fn getdirentries
+unlocks
+.Va fd .
+.Sh RETURN VALUES
+If successful, the number of bytes actually transferred is returned.
+Otherwise, -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Getdirentries
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa fd
+is not a valid file descriptor open for reading.
+.It Bq Er EFAULT
+Either
+.Fa buf
+or
+.Fa basep
+point outside the allocated address space.
+.It Bq Er EINVAL
+The file referenced by
+.Fa fd
+is not a directory, or
+.Fa nbytes
+is too small for returning a directory entry or block of entries,
+or the current position pointer is invalid.
+.It Bq Er EIO
+An
+.Tn I/O
+error occurred while reading from or writing to the file system.
+.El
+.Sh SEE ALSO
+.Xr lseek 2 ,
+.Xr open 2
+.Sh HISTORY
+The
+.Fn getdirentries
+function first appeared in
+.Bx 4.4 .
+The
+.Fn getdents
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc/sys/getdtablesize.2 b/lib/libc/sys/getdtablesize.2
new file mode 100644
index 0000000..a41980c
--- /dev/null
+++ b/lib/libc/sys/getdtablesize.2
@@ -0,0 +1,61 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getdtablesize.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETDTABLESIZE 2
+.Os BSD 4.2
+.Sh NAME
+.Nm getdtablesize
+.Nd get descriptor table size
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn getdtablesize void
+.Sh DESCRIPTION
+Each process has a fixed size descriptor table,
+which is guaranteed to have at least 20 slots. The entries in
+the descriptor table are numbered with small integers starting at 0.
+The call
+.Fn getdtablesize
+returns the size of this table.
+.Sh SEE ALSO
+.Xr close 2 ,
+.Xr dup 2 ,
+.Xr open 2 ,
+.Xr select 2
+.Sh HISTORY
+The
+.Fn getdtablesize
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/getfh.2 b/lib/libc/sys/getfh.2
new file mode 100644
index 0000000..e64babf
--- /dev/null
+++ b/lib/libc/sys/getfh.2
@@ -0,0 +1,95 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getfh.2 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt GETFH 2
+.Os
+.Sh NAME
+.Nm getfh
+.Nd get file handle
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/mount.h>
+.Ft int
+.Fn getfh "const char *path" "fhandle_t *fhp"
+.Sh DESCRIPTION
+.Fn Getfh
+returns a file handle for the specified file or directory
+in the file handle pointed to by
+.Fa fhp .
+This system call is restricted to the superuser.
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned.
+Otherwise, -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Getfh
+fails if one or more of the following are true:
+.Bl -tag -width Er
+.It Bq ENOTDIR
+A component of the path prefix of
+.Fa path
+is not a directory.
+.It Bq ENAMETOOLONG
+The length of a component of
+.Fa path
+exceeds 255 characters,
+or the length of
+.Fa path
+exceeds 1023 characters.
+.It Bq ENOENT
+The file referred to by
+.Fa path
+does not exist.
+.It Bq EACCES
+Search permission is denied for a component of the path prefix of
+.Fa path .
+.It Bq ELOOP
+Too many symbolic links were encountered in translating
+.Fa path .
+.It Bq EFAULT
+.Fa Fhp
+points to an invalid address.
+.It Bq EIO
+An
+.Tn I/O
+error occurred while reading from or writing to the file system.
+.El
+.Sh HISTORY
+The
+.Fn getfh
+function
+first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/getfsstat.2 b/lib/libc/sys/getfsstat.2
new file mode 100644
index 0000000..3dc87bc
--- /dev/null
+++ b/lib/libc/sys/getfsstat.2
@@ -0,0 +1,172 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getfsstat.2 8.3 (Berkeley) 5/25/95
+.\" $FreeBSD$
+.\"
+.Dd May 25, 1995
+.Dt GETFSSTAT 2
+.Os
+.Sh NAME
+.Nm getfsstat
+.Nd get list of all mounted filesystems
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/ucred.h>
+.Fd #include <sys/mount.h>
+.Ft int
+.Fn getfsstat "struct statfs *buf" "long bufsize" "int flags"
+.Sh DESCRIPTION
+.Fn Getfsstat
+returns information about all mounted filesystems.
+.Fa Buf
+is a pointer to
+.Xr statfs
+structures defined as follows:
+.Bd -literal
+typedef struct fsid { int32_t val[2]; } fsid_t; /* file system id type */
+
+/*
+ * file system statistics
+ */
+
+#define MFSNAMELEN 16 /* length of fs type name, including null */
+#define MNAMELEN 90 /* length of buffer for returned name */
+
+struct statfs {
+ long f_spare2; /* placeholder */
+ long f_bsize; /* fundamental file system block size */
+ long f_iosize; /* optimal transfer block size */
+ long f_blocks; /* total data blocks in file system */
+ long f_bfree; /* free blocks in fs */
+ long f_bavail; /* free blocks avail to non-superuser */
+ long f_files; /* total file nodes in file system */
+ long f_ffree; /* free file nodes in fs */
+ fsid_t f_fsid; /* file system id */
+ uid_t f_owner; /* user that mounted the filesystem */
+ int f_type; /* type of filesystem (see below) */
+ int f_flags; /* copy of mount flags */
+ long f_spare[2]; /* spare for later */
+ char f_fstypename[MFSNAMELEN];/* fs type name */
+ char f_mntonname[MNAMELEN];/* directory on which mounted */
+ char f_mntfromname[MNAMELEN];/* mounted filesystem */
+};
+.Ed
+.Pp
+The flags that may be returned include:
+.Bl -tag -width MNT_ASYNCHRONOUS
+.It Dv MNT_RDONLY
+The filesystem is mounted read-only;
+Even the super-user may not write on it.
+.It Dv MNT_NOEXEC
+Files may not be executed from the filesystem.
+.It Dv MNT_NOSUID
+Setuid and setgid bits on files are not honored when they are executed.
+.It Dv MNT_NODEV
+Special files in the filesystem may not be opened.
+.It Dv MNT_SYNCHRONOUS
+All I/O to the filesystem is done synchronously.
+.It Dv MNT_ASYNCHRONOUS
+No filesystem I/O is done synchronously.
+.It Dv MNT_LOCAL
+The filesystem resides locally.
+.It Dv MNT_QUOTA
+The filesystem has quotas enabled on it.
+.It Dv MNT_ROOTFS
+Identifies the root filesystem.
+.It Dv MNT_EXRDONLY
+The filesystem is exported read-only.
+.It Dv MNT_EXPORTED
+The filesystem is exported for both reading and writing.
+.It Dv MNT_DEFEXPORTED
+The filesystem is exported for both reading and writing to any Internet host.
+.It Dv MNT_EXPORTANON
+The filesystem maps all remote accesses to the anonymous user.
+.It Dv MNT_EXKERB
+The filesystem is exported with Kerberos uid mapping.
+.El
+.Pp
+Fields that are undefined for a particular filesystem are set to -1.
+The buffer is filled with an array of
+.Fa fsstat
+structures, one for each mounted filesystem
+up to the size specified by
+.Fa bufsize .
+.Pp
+If
+.Fa buf
+is given as NULL,
+.Fn getfsstat
+returns just the number of mounted filesystems.
+.Pp
+Normally
+.Fa flags
+should be specified as
+.Dv MNT_WAIT .
+If
+.Fa flags
+is set to
+.Dv MNT_NOWAIT ,
+.Fn getfsstat
+will return the information it has available without requesting
+an update from each filesystem.
+Thus, some of the information will be out of date, but
+.Fn getfsstat
+will not block waiting for information from a filesystem that is
+unable to respond.
+.Sh RETURN VALUES
+Upon successful completion, the number of
+.Fa fsstat
+structures is returned.
+Otherwise, -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Getfsstat
+fails if one or more of the following are true:
+.Bl -tag -width Er
+.It EFAULT
+.Fa Buf
+points to an invalid address.
+.It EIO
+An
+.Tn I/O
+error occurred while reading from or writing to the filesystem.
+.El
+.Sh SEE ALSO
+.Xr statfs 2 ,
+.Xr fstab 5 ,
+.Xr mount 8
+.Sh HISTORY
+The
+.Fn getfsstat
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/getgid.2 b/lib/libc/sys/getgid.2
new file mode 100644
index 0000000..d9c4db4
--- /dev/null
+++ b/lib/libc/sys/getgid.2
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getgid.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETGID 2
+.Os BSD 4.2
+.Sh NAME
+.Nm getgid ,
+.Nm getegid
+.Nd get group process identification
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <unistd.h>
+.Ft gid_t
+.Fn getgid void
+.Ft gid_t
+.Fn getegid void
+.Sh DESCRIPTION
+The
+.Fn getgid
+function returns the real group ID of the calling process,
+.Fn getegid
+returns the effective group ID of the calling process.
+.Pp
+The real group ID is specified at login time.
+.Pp
+The real group ID is the group of the user who invoked the program.
+As the effective group ID gives the process additional permissions
+during the execution of
+.Dq Em set-group-ID
+mode processes,
+.Fn getgid
+is used to determine the real-user-id of the calling process.
+.Sh ERRORS
+The
+.Fn getgid
+and
+.Fn getegid
+functions are always successful, and no return value is reserved to
+indicate an error.
+.Sh SEE ALSO
+.Xr getuid 2 ,
+.Xr issetugid 2 ,
+.Xr setgid 2 ,
+.Xr setregid 2
+.Sh STANDARDS
+The
+.Fn getgid
+and
+.Fn getegid
+function calls are expected to conform to
+.St -p1003.1-90 .
diff --git a/lib/libc/sys/getgroups.2 b/lib/libc/sys/getgroups.2
new file mode 100644
index 0000000..ab1d029
--- /dev/null
+++ b/lib/libc/sys/getgroups.2
@@ -0,0 +1,96 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getgroups.2 8.2 (Berkeley) 4/16/94
+.\" $FreeBSD$
+.\"
+.Dd March 5, 1999
+.Dt GETGROUPS 2
+.Os BSD 4.2
+.Sh NAME
+.Nm getgroups
+.Nd get group access list
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <unistd.h>
+.Ft int
+.Fn getgroups "int gidsetlen" "gid_t *gidset"
+.Sh DESCRIPTION
+.Fn Getgroups
+gets the current group access list of the user process
+and stores it in the array
+.Fa gidset .
+The parameter
+.Fa gidsetlen
+indicates the number of entries that may be placed in
+.Fa gidset .
+.Fn Getgroups
+returns the actual number of groups returned in
+.Fa gidset .
+No more than
+.Dv NGROUPS_MAX
+will ever
+be returned.
+If
+.Fa gidsetlen
+is zero,
+.Fn getgroups
+returns the number of supplementary group IDs associated with
+the calling process without modifying the array pointed to by
+.Fa gidset .
+.Sh RETURN VALUES
+A successful call returns the number of groups in the group set.
+A value of -1 indicates that an error occurred, and the error
+code is stored in the global variable
+.Va errno .
+.Sh ERRORS
+The possible errors for
+.Fn getgroups
+are:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Fa gidsetlen
+is smaller than the number of groups in the group set.
+.It Bq Er EFAULT
+The argument
+.Fa gidset
+specifies
+an invalid address.
+.El
+.Sh SEE ALSO
+.Xr setgroups 2 ,
+.Xr initgroups 3
+.Sh HISTORY
+The
+.Fn getgroups
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/getitimer.2 b/lib/libc/sys/getitimer.2
new file mode 100644
index 0000000..b60349a
--- /dev/null
+++ b/lib/libc/sys/getitimer.2
@@ -0,0 +1,177 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getitimer.2 8.3 (Berkeley) 5/16/95
+.\" $FreeBSD$
+.\"
+.Dd May 16, 1995
+.Dt GETITIMER 2
+.Os BSD 4.2
+.Sh NAME
+.Nm getitimer ,
+.Nm setitimer
+.Nd get/set value of interval timer
+.Sh SYNOPSIS
+.Fd #include <sys/time.h>
+.Fd #define ITIMER_REAL 0
+.Fd #define ITIMER_VIRTUAL 1
+.Fd #define ITIMER_PROF 2
+.Ft int
+.Fn getitimer "int which" "struct itimerval *value"
+.Ft int
+.Fn setitimer "int which" "const struct itimerval *value" "struct itimerval *ovalue"
+.Sh DESCRIPTION
+The system provides each process with three interval timers,
+defined in
+.Ao Pa sys/time.h Ac .
+The
+.Fn getitimer
+call returns the current value for the timer specified in
+.Fa which
+in the structure at
+.Fa value .
+The
+.Fn setitimer
+call sets a timer to the specified
+.Fa value
+(returning the previous value of the timer if
+.Fa ovalue
+is non-nil).
+.Pp
+A timer value is defined by the
+.Fa itimerval
+structure:
+.Bd -literal -offset indent
+struct itimerval {
+ struct timeval it_interval; /* timer interval */
+ struct timeval it_value; /* current value */
+};
+.Ed
+.Pp
+If
+.Fa it_value
+is non-zero, it indicates the time to the next timer expiration.
+If
+.Fa it_interval
+is non-zero, it specifies a value to be used in reloading
+.Fa it_value
+when the timer expires.
+Setting
+.Fa it_value
+to 0 disables a timer, regardless of the value of
+.Fa it_interval .
+Setting
+.Fa it_interval
+to 0 causes a timer to be disabled after its next expiration (assuming
+.Fa it_value
+is non-zero).
+.Pp
+Time values smaller than the resolution of the
+system clock are rounded up to this resolution
+(typically 10 milliseconds).
+.Pp
+The
+.Dv ITIMER_REAL
+timer decrements in real time. A
+.Dv SIGALRM
+signal is
+delivered when this timer expires.
+.Pp
+The
+.Dv ITIMER_VIRTUAL
+timer decrements in process virtual time.
+It runs only when the process is executing. A
+.Dv SIGVTALRM
+signal
+is delivered when it expires.
+.Pp
+The
+.Dv ITIMER_PROF
+timer decrements both in process virtual time and
+when the system is running on behalf of the process. It is designed
+to be used by interpreters in statistically profiling the execution
+of interpreted programs.
+Each time the
+.Dv ITIMER_PROF
+timer expires, the
+.Dv SIGPROF
+signal is
+delivered. Because this signal may interrupt in-progress
+system calls, programs using this timer must be prepared to
+restart interrupted system calls.
+.Pp
+The maximum number of seconds allowed for
+.Fa it_interval
+and
+.Fa it_value
+in
+.Fn setitimer
+is 100000000.
+.Sh NOTES
+Three macros for manipulating time values are defined in
+.Ao Pa sys/time.h Ac .
+.Fa Timerclear
+sets a time value to zero,
+.Fa timerisset
+tests if a time value is non-zero, and
+.Fa timercmp
+compares two time values.
+.Sh RETURN VALUES
+If the calls succeed, a value of 0 is returned. If an error occurs,
+the value -1 is returned, and a more precise error code is placed
+in the global variable
+.Va errno .
+.Sh ERRORS
+.Fn Getitimer
+and
+.Fn setitimer
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+The
+.Fa value
+parameter specified a bad address.
+.It Bq Er EINVAL
+A
+.Fa value
+parameter specified a time that was too large
+to be handled.
+.El
+.Sh SEE ALSO
+.Xr gettimeofday 2 ,
+.Xr select 2 ,
+.Xr sigvec 2 ,
+.Xr clocks 7
+.Sh HISTORY
+The
+.Fn getitimer
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/getlogin.2 b/lib/libc/sys/getlogin.2
new file mode 100644
index 0000000..122431d5
--- /dev/null
+++ b/lib/libc/sys/getlogin.2
@@ -0,0 +1,186 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getlogin.2 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt GETLOGIN 2
+.Os BSD 4.4
+.Sh NAME
+.Nm getlogin ,
+.Nm getlogin_r ,
+.Nm setlogin
+.Nd get/set login name
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft char *
+.Fn getlogin void
+.Fd #include <sys/param.h>
+.Ft char *
+.Fn getlogin_r "char *name" "int len"
+.Ft int
+.Fn setlogin "const char *name"
+.Sh DESCRIPTION
+The
+.Fn getlogin
+routine
+returns the login name of the user associated with the current session,
+as previously set by
+.Fn setlogin .
+The name is normally associated with a login shell
+at the time a session is created,
+and is inherited by all processes descended from the login shell.
+(This is true even if some of those processes assume another user ID,
+for example when
+.Xr su 1
+is used).
+.Pp
+.Fn getlogin_r
+provides the same service as
+.Fn getlogin
+except the caller must provide the buffer
+.Fa name
+with length
+.Fa len
+bytes
+to hold the result. The buffer should be at least
+.Dv MAXLOGNAME
+bytes in length.
+.Pp
+.Fn Setlogin
+sets the login name of the user associated with the current session to
+.Fa name .
+This call is restricted to the super-user, and
+is normally used only when a new session is being created on behalf
+of the named user
+(for example, at login time, or when a remote shell is invoked).
+.Pp
+.Em NOTE:
+There is only one `login name' per `session .
+.Pp
+It is
+.Em CRITICALLY
+important to ensure that
+.Fn setlogin
+is only ever called after the process has taken adequate steps to ensure
+that it is detached from its parent's session.
+Making a
+.Fn setsid
+system call is the
+.Em ONLY
+way to do this. The
+.Fn daemon
+library call calls
+.Fn setsid
+which is an ideal way of detaching from a controlling terminal and
+forking into the background.
+.Pp
+In particular, doing a
+.Fn ioctl ttyfd TIOCNOTTY ...
+or
+.Fn setpgrp ...
+is
+.Em NOT
+sufficient.
+.Pp
+Once a parent process does a
+.Fn setsid
+call, it is acceptable for some child of that process to then do a
+.Fn setlogin
+even though it is not the session leader, but beware that ALL processes
+in the session will change their login name at the same time, even the
+parent.
+.Pp
+This is not the same as the traditional UNIX behavior of inheriting privilege.
+.Pp
+Since the
+.Fn setlogin
+system call is restricted to the super-user, it is assumed that (like
+all other privileged programs) the programmer has taken adequate
+precautions to prevent security violations.
+.Sh RETURN VALUES
+If a call to
+.Fn getlogin
+succeeds, it returns a pointer to a null-terminated string in a static buffer.
+.Fn getlogin_r
+returns a pointer to the buffer passed in by the caller on success.
+Both return
+.Dv NULL
+if the name has not been set.
+.Pp
+If a call to
+.Fn setlogin
+succeeds, a value of 0 is returned. If
+.Fn setlogin
+fails, a value of -1 is returned and an error code is
+placed in the global location
+.Va errno .
+.Sh ERRORS
+The following errors may be returned by these calls:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+The
+.Fa name
+parameter gave an
+invalid address.
+.It Bq Er EINVAL
+The
+.Fa name
+parameter
+pointed to a string that was too long.
+Login names are limited to
+.Dv MAXLOGNAME
+(from
+.Ao Pa sys/param.h Ac )
+characters, currently 17 including null.
+.It Bq Er EPERM
+The caller tried to set the login name and was not the super-user.
+.El
+.Sh SEE ALSO
+.Xr setsid 2 ,
+.Xr daemon 3
+.Sh BUGS
+In earlier versions of the system,
+.Fn getlogin
+failed unless the process was associated with a login terminal.
+The current implementation (using
+.Fn setlogin )
+allows getlogin to succeed even when the process has no controlling terminal.
+In earlier versions of the system, the value returned by
+.Fn getlogin
+could not be trusted without checking the user ID.
+Portable programs should probably still make this check.
+.Sh HISTORY
+The
+.Fn getlogin
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/getpeername.2 b/lib/libc/sys/getpeername.2
new file mode 100644
index 0000000..109d195
--- /dev/null
+++ b/lib/libc/sys/getpeername.2
@@ -0,0 +1,114 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getpeername.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETPEERNAME 2
+.Os BSD 4.2
+.Sh NAME
+.Nm getpeername
+.Nd get name of connected peer
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft int
+.Fn getpeername "int s" "struct sockaddr *name" "socklen_t *namelen"
+.Sh DESCRIPTION
+.Fn Getpeername
+returns the name of the peer connected to
+socket
+.Fa s .
+The
+.Fa namelen
+parameter should be initialized to indicate
+the amount of space pointed to by
+.Fa name .
+On return it contains the actual size of the name
+returned (in bytes).
+The name is truncated if the buffer provided is too small.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn getpeername
+is implemented as the
+.Va getpeername
+syscall.
+.Pp
+In the threaded library, the
+.Va getpeername
+syscall is assembled to
+.Fn _thread_sys_getpeername
+and
+.Fn getpeername
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_getpeername .
+Before returning,
+.Fn getpeername
+unlocks
+.Va s .
+.Sh RETURN VALUES
+A 0 is returned if the call succeeds, -1 if it fails.
+.Sh ERRORS
+The call succeeds unless:
+.Bl -tag -width ENOTSOCKAA
+.It Bq Er EBADF
+The argument
+.Fa s
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is a file, not a socket.
+.It Bq Er ENOTCONN
+The socket is not connected.
+.It Bq Er ENOBUFS
+Insufficient resources were available in the system
+to perform the operation.
+.It Bq Er EFAULT
+The
+.Fa name
+parameter points to memory not in a valid part of the
+process address space.
+.El
+.Sh SEE ALSO
+.Xr accept 2 ,
+.Xr bind 2 ,
+.Xr getsockname 2 ,
+.Xr socket 2
+.Sh HISTORY
+The
+.Fn getpeername
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/getpgrp.2 b/lib/libc/sys/getpgrp.2
new file mode 100644
index 0000000..9f5ba3e
--- /dev/null
+++ b/lib/libc/sys/getpgrp.2
@@ -0,0 +1,123 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getpgrp.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETPGRP 2
+.Os BSD 4.2
+.Sh NAME
+.Nm getpgrp
+.Nd get process group
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft pid_t
+.Fn getpgrp void
+.Ft pid_t
+.Fn getpgid "pid_t pid"
+.Sh DESCRIPTION
+The process group of the current process is returned by
+.Fn getpgrp .
+The process group of the process identified by
+.Fa pid
+is returned by
+.Fn getpgid .
+If
+.Fa pid
+is zero,
+.Fn getpgid
+returns the process group of the current process.
+.Pp
+Process groups are used for distribution of signals, and
+by terminals to arbitrate requests for their input: processes
+that have the same process group as the terminal are foreground
+and may read, while others will block with a signal if they attempt
+to read.
+.Pp
+This call is thus used by programs such as
+.Xr csh 1
+to create
+process groups
+in implementing job control.
+The
+.Fn tcgetpgrp
+and
+.Fn tcsetpgrp
+calls
+are used to get/set the process group of the control terminal.
+.Sh SEE ALSO
+.Xr getsid 2 ,
+.Xr setpgid 2 ,
+.Xr termios 4
+.Sh HISTORY
+The
+.Fn getpgrp
+function call appeared in
+.Bx 4.0 .
+The
+.Fn getpgid
+function call is derived from it's usage in System V Release 4.
+.Sh STANDARDS
+The
+.Fn getpgrp
+function call is expected to conform to
+.St -p1003.1-90 .
+.Sh COMPATIBILITY
+This version of
+.Fn getpgrp
+differs from past Berkeley versions by not taking a
+.Fa "pid_t pid"
+argument.
+This incompatibility is required by
+.St -p1003.1-90 .
+.Pp
+From the
+.St -p1003.1-90
+Rationale:
+.Pp
+.Bx 4.3
+provides a
+.Fn getpgrp
+function that returns the process group ID for a specified process.
+Although this function is used to support job control, all known
+job-control shells always specify the calling process with this
+function.
+Thus, the simpler
+.At V
+.Fn getpgrp
+suffices, and the added complexity of the
+.Bx 4.3
+.Fn getpgrp
+has been omitted from POSIX.1.
+The old functionality is available from the
+.Fn getpgid
+function.
diff --git a/lib/libc/sys/getpid.2 b/lib/libc/sys/getpid.2
new file mode 100644
index 0000000..5a282b1
--- /dev/null
+++ b/lib/libc/sys/getpid.2
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getpid.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETPID 2
+.Os BSD 4
+.Sh NAME
+.Nm getpid ,
+.Nm getppid
+.Nd get parent or calling process identification
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <unistd.h>
+.Ft pid_t
+.Fn getpid void
+.Ft pid_t
+.Fn getppid void
+.Sh DESCRIPTION
+.Fn Getpid
+returns
+the process ID of
+the calling process.
+The ID is guaranteed to be unique and is
+useful for constructing temporary file names.
+.Pp
+.Fn Getppid
+returns the process ID of the parent
+of the calling process.
+.Sh ERRORS
+The
+.Fn getpid
+and
+.Fn getppid
+functions are always successful, and no return value is reserved to
+indicate an error.
+.Sh SEE ALSO
+.Xr gethostid 3
+.Sh STANDARDS
+The
+.Fn getpid
+and
+.Fn getppid
+function calls are expected to conform to
+.St -p1003.1-90 .
+.Sh HISTORY
+A
+.Fn getpid
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/getpriority.2 b/lib/libc/sys/getpriority.2
new file mode 100644
index 0000000..3a6eee4
--- /dev/null
+++ b/lib/libc/sys/getpriority.2
@@ -0,0 +1,143 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getpriority.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETPRIORITY 2
+.Os BSD 4
+.Sh NAME
+.Nm getpriority ,
+.Nm setpriority
+.Nd get/set program scheduling priority
+.Sh SYNOPSIS
+.Fd #include <sys/time.h>
+.Fd #include <sys/resource.h>
+.Ft int
+.Fn getpriority "int which" "int who"
+.Ft int
+.Fn setpriority "int which" "int who" "int prio"
+.Sh DESCRIPTION
+The scheduling
+priority of the process, process group, or user, as indicated by
+.Fa which
+and
+.Fa who
+is obtained with the
+.Fn getpriority
+call and set with the
+.Fn setpriority
+call.
+.Fa Which
+is one of
+.Dv PRIO_PROCESS ,
+.Dv PRIO_PGRP ,
+or
+.Dv PRIO_USER ,
+and
+.Fa who
+is interpreted relative to
+.Fa which
+(a process identifier for
+.Dv PRIO_PROCESS ,
+process group
+identifier for
+.Dv PRIO_PGRP ,
+and a user ID for
+.Dv PRIO_USER ) .
+A zero value of
+.Fa who
+denotes the current process, process group, or user.
+.Fa Prio
+is a value in the range -20 to 20. The default priority is 0;
+lower priorities cause more favorable scheduling.
+.Pp
+The
+.Fn getpriority
+call returns the highest priority (lowest numerical value)
+enjoyed by any of the specified processes. The
+.Fn setpriority
+call sets the priorities of all of the specified processes
+to the specified value. Only the super-user may lower priorities.
+.Sh RETURN VALUES
+Since
+.Fn getpriority
+can legitimately return the value -1, it is necessary
+to clear the external variable
+.Va errno
+prior to the
+call, then check it afterward to determine
+if a -1 is an error or a legitimate value.
+The
+.Fn setpriority
+call returns 0 if there is no error, or
+-1 if there is.
+.Sh ERRORS
+.Fn Getpriority
+and
+.Fn setpriority
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ESRCH
+No process was located using the
+.Fa which
+and
+.Fa who
+values specified.
+.It Bq Er EINVAL
+.Fa Which
+was not one of
+.Dv PRIO_PROCESS ,
+.Dv PRIO_PGRP ,
+or
+.Dv PRIO_USER .
+.El
+.Pp
+.Bl -tag -width Er
+In addition to the errors indicated above,
+.Fn setpriority
+will fail if:
+.It Bq Er EPERM
+A process was located, but neither its effective nor real user
+ID matched the effective user ID of the caller.
+.It Bq Er EACCES
+A non super-user attempted to lower a process priority.
+.El
+.Sh SEE ALSO
+.Xr nice 1 ,
+.Xr fork 2 ,
+.Xr renice 8
+.Sh HISTORY
+The
+.Fn getpriority
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/getrlimit.2 b/lib/libc/sys/getrlimit.2
new file mode 100644
index 0000000..eebb874
--- /dev/null
+++ b/lib/libc/sys/getrlimit.2
@@ -0,0 +1,188 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getrlimit.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETRLIMIT 2
+.Os BSD 4
+.Sh NAME
+.Nm getrlimit ,
+.Nm setrlimit
+.Nd control maximum system resource consumption
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/time.h>
+.Fd #include <sys/resource.h>
+.Ft int
+.Fn getrlimit "int resource" "struct rlimit *rlp"
+.Ft int
+.Fn setrlimit "int resource" "const struct rlimit *rlp"
+.Sh DESCRIPTION
+Limits on the consumption of system resources by the current process
+and each process it creates may be obtained with the
+.Fn getrlimit
+call, and set with the
+.Fn setrlimit
+call.
+.Pp
+The
+.Fa resource
+parameter is one of the following:
+.Bl -tag -width RLIMIT_FSIZEAA
+.It Li RLIMIT_CORE
+The largest size (in bytes)
+.Xr core 5
+file that may be created.
+.It Li RLIMIT_CPU
+The maximum amount of cpu time (in seconds) to be used by
+each process.
+.It Li RLIMIT_DATA
+The maximum size (in bytes) of the data segment for a process;
+this defines how far a program may extend its break with the
+.Xr sbrk 2
+system call.
+.It Li RLIMIT_FSIZE
+The largest size (in bytes) file that may be created.
+.It Li RLIMIT_MEMLOCK
+The maximum size (in bytes) which a process may lock into memory
+using the
+.Xr mlock 2
+function.
+.It Li RLIMIT_NOFILE
+The maximum number of open files for this process.
+.It Li RLIMIT_NPROC
+The maximum number of simultaneous processes for this user id.
+.It Li RLIMIT_RSS
+The maximum size (in bytes) to which a process's resident set size may
+grow.
+This imposes a limit on the amount of physical memory to be given to
+a process; if memory is tight, the system will prefer to take memory
+from processes that are exceeding their declared resident set size.
+.It Li RLIMIT_STACK
+The maximum size (in bytes) of the stack segment for a process;
+this defines how far a program's stack segment may be extended.
+Stack extension is performed automatically by the system.
+.It Li RLIMIT_SBSIZE
+The maximum size (in bytes) of socket buffer usage for this user.
+This limits the amount of network memory, and hence the amount of
+mbufs, that this user may hold at any time.
+.El
+.Pp
+A resource limit is specified as a soft limit and a hard limit. When a
+soft limit is exceeded a process may receive a signal (for example, if
+the cpu time or file size is exceeded), but it will be allowed to
+continue execution until it reaches the hard limit (or modifies
+its resource limit). The
+.Em rlimit
+structure is used to specify the hard and soft limits on a resource,
+.Bd -literal -offset indent
+struct rlimit {
+ rlim_t rlim_cur; /* current (soft) limit */
+ rlim_t rlim_max; /* maximum value for rlim_cur */
+};
+.Ed
+.Pp
+Only the super-user may raise the maximum limits. Other users
+may only alter
+.Fa rlim_cur
+within the range from 0 to
+.Fa rlim_max
+or (irreversibly) lower
+.Fa rlim_max .
+.Pp
+An
+.Dq infinite
+value for a limit is defined as
+.Dv RLIM_INFINITY .
+.Pp
+Because this information is stored in the per-process information,
+this system call must be executed directly by the shell if it
+is to affect all future processes created by the shell;
+.Ic limit
+is thus a built-in command to
+.Xr csh 1 .
+.Pp
+The system refuses to extend the data or stack space when the limits
+would be exceeded in the normal way: a
+.Xr brk 2
+call fails if the data space limit is reached.
+When the stack limit is reached, the process receives
+a segmentation fault
+.Pq Dv SIGSEGV ;
+if this signal is not
+caught by a handler using the signal stack, this signal
+will kill the process.
+.Pp
+A file I/O operation that would create a file larger that the process'
+soft limit will cause the write to fail and a signal
+.Dv SIGXFSZ
+to be
+generated; this normally terminates the process, but may be caught. When
+the soft cpu time limit is exceeded, a signal
+.Dv SIGXCPU
+is sent to the
+offending process.
+.Sh RETURN VALUES
+A 0 return value indicates that the call succeeded, changing
+or returning the resource limit. A return value of -1 indicates
+that an error occurred, and an error code is stored in the global
+location
+.Va errno .
+.Sh ERRORS
+.Fn Getrlimit
+and
+.Fn setrlimit
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+The address specified for
+.Fa rlp
+is invalid.
+.It Bq Er EPERM
+The limit specified to
+.Fn setrlimit
+would have
+raised the maximum limit value, and the caller is not the super-user.
+.El
+.Sh SEE ALSO
+.Xr csh 1 ,
+.Xr quota 1 ,
+.Xr quotactl 2 ,
+.Xr sigaltstack 2 ,
+.Xr sigvec 2 ,
+.Xr sysctl 3
+.Sh HISTORY
+The
+.Fn getrlimit
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/getrusage.2 b/lib/libc/sys/getrusage.2
new file mode 100644
index 0000000..dcbda2d
--- /dev/null
+++ b/lib/libc/sys/getrusage.2
@@ -0,0 +1,177 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getrusage.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETRUSAGE 2
+.Os BSD 4
+.Sh NAME
+.Nm getrusage
+.Nd get information about resource utilization
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/time.h>
+.Fd #include <sys/resource.h>
+.Fd #define RUSAGE_SELF 0
+.Fd #define RUSAGE_CHILDREN -1
+.Ft int
+.Fn getrusage "int who" "struct rusage *rusage"
+.Sh DESCRIPTION
+.Fn Getrusage
+returns information describing the resources utilized by the current
+process, or all its terminated child processes.
+The
+.Fa who
+parameter is either
+.Dv RUSAGE_SELF
+or
+.Dv RUSAGE_CHILDREN .
+The buffer to which
+.Fa rusage
+points will be filled in with
+the following structure:
+.Bd -literal
+struct rusage {
+ struct timeval ru_utime; /* user time used */
+ struct timeval ru_stime; /* system time used */
+ long ru_maxrss; /* max resident set size */
+ long ru_ixrss; /* integral shared text memory size */
+ long ru_idrss; /* integral unshared data size */
+ long ru_isrss; /* integral unshared stack size */
+ long ru_minflt; /* page reclaims */
+ long ru_majflt; /* page faults */
+ long ru_nswap; /* swaps */
+ long ru_inblock; /* block input operations */
+ long ru_oublock; /* block output operations */
+ long ru_msgsnd; /* messages sent */
+ long ru_msgrcv; /* messages received */
+ long ru_nsignals; /* signals received */
+ long ru_nvcsw; /* voluntary context switches */
+ long ru_nivcsw; /* involuntary context switches */
+};
+.Ed
+.Pp
+The fields are interpreted as follows:
+.Bl -tag -width ru_minfltaa
+.It Fa ru_utime
+the total amount of time spent executing in user mode.
+.It Fa ru_stime
+the total amount of time spent in the system executing on behalf
+of the process(es).
+.It Fa ru_maxrss
+the maximum resident set size utilized (in kilobytes).
+.It Fa ru_ixrss
+an \*(lqintegral\*(rq value indicating the amount of memory used
+by the text segment
+that was also shared among other processes. This value is expressed
+in units of kilobytes * ticks-of-execution.
+Ticks are statistics clock ticks.
+The statistics clock has a frequency of
+.Fn sysconf _SC_CLOCK_TCK
+ticks per second.
+.It Fa ru_idrss
+an integral value of the amount of unshared memory residing in the
+data segment of a process (expressed in units of
+kilobytes * ticks-of-execution).
+.It Fa ru_isrss
+an integral value of the amount of unshared memory residing in the
+stack segment of a process (expressed in units of
+kilobytes * ticks-of-execution).
+.It Fa ru_minflt
+the number of page faults serviced without any I/O activity; here
+I/O activity is avoided by \*(lqreclaiming\*(rq a page frame from
+the list of pages awaiting reallocation.
+.It Fa ru_majflt
+the number of page faults serviced that required I/O activity.
+.It Fa ru_nswap
+the number of times a process was \*(lqswapped\*(rq out of main
+memory.
+.It Fa ru_inblock
+the number of times the file system had to perform input.
+.It Fa ru_oublock
+the number of times the file system had to perform output.
+.It Fa ru_msgsnd
+the number of IPC messages sent.
+.It Fa ru_msgrcv
+the number of IPC messages received.
+.It Fa ru_nsignals
+the number of signals delivered.
+.It Fa ru_nvcsw
+the number of times a context switch resulted due to a process
+voluntarily giving up the processor before its time slice was
+completed (usually to await availability of a resource).
+.It Fa ru_nivcsw
+the number of times a context switch resulted due to a higher
+priority process becoming runnable or because the current process
+exceeded its time slice.
+.El
+.Sh NOTES
+The numbers
+.Fa ru_inblock
+and
+.Fa ru_oublock
+account only for real
+I/O; data supplied by the caching mechanism is charged only
+to the first process to read or write the data.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn getrusage
+returns 0. Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn getrusage
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa who
+parameter is not a valid value.
+.It Bq Er EFAULT
+The address specified by the
+.Fa rusage
+parameter is not in a valid part of the process address space.
+.El
+.Sh SEE ALSO
+.Xr gettimeofday 2 ,
+.Xr wait 2 ,
+.Xr clocks 7
+.Sh BUGS
+There is no way to obtain information about a child process
+that has not yet terminated.
+.Sh HISTORY
+The
+.Fn getrusage
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/getsid.2 b/lib/libc/sys/getsid.2
new file mode 100644
index 0000000..4a7f13e
--- /dev/null
+++ b/lib/libc/sys/getsid.2
@@ -0,0 +1,77 @@
+.\" Copyright (c) 1997 Peter Wemm <peter@freebsd.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 19, 1997
+.Dt GETSID 2
+.Os BSD 4.2
+.Sh NAME
+.Nm getsid
+.Nd get process session
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft pid_t
+.Fn getsid "pid_t pid"
+.Sh DESCRIPTION
+The session ID of the process identified by
+.Fa pid
+is returned by
+.Fn getsid .
+If
+.Fa pid
+is zero,
+.Fn getsid
+returns the session ID of the current process.
+.Sh RETURN VALUES
+Upon successful completion, the function
+.Fn getsid
+returns the session ID of
+the specified process; otherwise, it returns a value of -1 and
+sets errno to indicate an error.
+.Sh ERRORS
+.Fn getsid
+will succeed unless:
+.Bl -tag -width Er
+.It Bq Er ESRCH
+if there is no process with a process ID equal to
+.Fa pid .
+.El
+.Pp
+Note that an implementation may restrict this function call to
+processes within the same session ID as the calling process.
+.Sh SEE ALSO
+.Xr getpgid 2 ,
+.Xr getpgrp 2 ,
+.Xr setpgid 2 ,
+.Xr setsid 2 ,
+.Xr termios 4
+.Sh HISTORY
+The
+.Fn setsid
+function call appeared in
+.Fx 3.0 .
+The
+.Fn getsid
+function call is derived from it's usage in
+.At V .
diff --git a/lib/libc/sys/getsockname.2 b/lib/libc/sys/getsockname.2
new file mode 100644
index 0000000..9355596
--- /dev/null
+++ b/lib/libc/sys/getsockname.2
@@ -0,0 +1,113 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getsockname.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETSOCKNAME 2
+.Os BSD 4.2
+.Sh NAME
+.Nm getsockname
+.Nd get socket name
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft int
+.Fn getsockname "int s" "struct sockaddr *name" "socklen_t *namelen"
+.Sh DESCRIPTION
+.Fn Getsockname
+returns the current
+.Fa name
+for the specified socket. The
+.Fa namelen
+parameter should be initialized to indicate
+the amount of space pointed to by
+.Fa name .
+On return it contains the actual size of the name
+returned (in bytes).
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn getsockname
+is implemented as the
+.Va getsockname
+syscall.
+.Pp
+In the threaded library, the
+.Va getsockname
+syscall is assembled to
+.Fn _thread_sys_getsockname
+and
+.Fn getsockname
+is implemented as a function which locks
+.Va fd
+for read and write, then calls
+.Fn _thread_sys_getsockname .
+Before returning,
+.Fn getsockname
+unlocks
+.Va fd .
+.Sh RETURN VALUES
+A 0 is returned if the call succeeds, -1 if it fails.
+.Sh ERRORS
+The call succeeds unless:
+.Bl -tag -width ENOTSOCKAA
+.It Bq Er EBADF
+The argument
+.Fa s
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is a file, not a socket.
+.It Bq Er ENOBUFS
+Insufficient resources were available in the system
+to perform the operation.
+.It Bq Er EFAULT
+The
+.Fa name
+parameter points to memory not in a valid part of the
+process address space.
+.El
+.Sh SEE ALSO
+.Xr bind 2 ,
+.Xr getpeername 2 ,
+.Xr socket 2
+.Sh BUGS
+Names bound to sockets in the UNIX domain are inaccessible;
+.Xr getsockname
+returns a zero length name.
+.Sh HISTORY
+The
+.Fn getsockname
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/getsockopt.2 b/lib/libc/sys/getsockopt.2
new file mode 100644
index 0000000..db1f834
--- /dev/null
+++ b/lib/libc/sys/getsockopt.2
@@ -0,0 +1,397 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getsockopt.2 8.4 (Berkeley) 5/2/95
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1995
+.Dt GETSOCKOPT 2
+.Os BSD 4.3r
+.Sh NAME
+.Nm getsockopt ,
+.Nm setsockopt
+.Nd get and set options on sockets
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft int
+.Fn getsockopt "int s" "int level" "int optname" "void *optval" "socklen_t *optlen"
+.Ft int
+.Fn setsockopt "int s" "int level" "int optname" "const void *optval" "socklen_t optlen"
+.Sh DESCRIPTION
+.Fn Getsockopt
+and
+.Fn setsockopt
+manipulate the
+.Em options
+associated with a socket. Options may exist at multiple
+protocol levels; they are always present at the uppermost
+.Dq socket
+level.
+.Pp
+When manipulating socket options the level at which the
+option resides and the name of the option must be specified.
+To manipulate options at the socket level,
+.Fa level
+is specified as
+.Dv SOL_SOCKET .
+To manipulate options at any
+other level the protocol number of the appropriate protocol
+controlling the option is supplied. For example,
+to indicate that an option is to be interpreted by the
+.Tn TCP
+protocol,
+.Fa level
+should be set to the protocol number of
+.Tn TCP ;
+see
+.Xr getprotoent 3 .
+.Pp
+The parameters
+.Fa optval
+and
+.Fa optlen
+are used to access option values for
+.Fn setsockopt .
+For
+.Fn getsockopt
+they identify a buffer in which the value for the
+requested option(s) are to be returned. For
+.Fn getsockopt ,
+.Fa optlen
+is a value-result parameter, initially containing the
+size of the buffer pointed to by
+.Fa optval ,
+and modified on return to indicate the actual size of
+the value returned. If no option value is
+to be supplied or returned,
+.Fa optval
+may be NULL.
+.Pp
+.Fa Optname
+and any specified options are passed uninterpreted to the appropriate
+protocol module for interpretation.
+The include file
+.Ao Pa sys/socket.h Ac
+contains definitions for
+socket level options, described below.
+Options at other protocol levels vary in format and
+name; consult the appropriate entries in
+section
+4 of the manual.
+.Pp
+Most socket-level options utilize an
+.Fa int
+parameter for
+.Fa optval .
+For
+.Fn setsockopt ,
+the parameter should be non-zero to enable a boolean option,
+or zero if the option is to be disabled.
+.Dv SO_LINGER
+uses a
+.Fa struct linger
+parameter, defined in
+.Ao Pa sys/socket.h Ac ,
+which specifies the desired state of the option and the
+linger interval (see below).
+.Dv SO_SNDTIMEO
+and
+.Dv SO_RCVTIMEO
+use a
+.Fa struct timeval
+parameter, defined in
+.Ao Pa sys/time.h Ac .
+.Pp
+The following options are recognized at the socket level.
+Except as noted, each may be examined with
+.Fn getsockopt
+and set with
+.Fn setsockopt .
+.Bl -column SO_OOBINLINE -offset indent
+.It Dv SO_DEBUG Ta "enables recording of debugging information"
+.It Dv SO_REUSEADDR Ta "enables local address reuse"
+.It Dv SO_REUSEPORT Ta "enables duplicate address and port bindings"
+.It Dv SO_KEEPALIVE Ta "enables keep connections alive"
+.It Dv SO_DONTROUTE Ta "enables routing bypass for outgoing messages"
+.It Dv SO_LINGER Ta "linger on close if data present"
+.It Dv SO_BROADCAST Ta "enables permission to transmit broadcast messages"
+.It Dv SO_OOBINLINE Ta "enables reception of out-of-band data in band"
+.It Dv SO_SNDBUF Ta "set buffer size for output"
+.It Dv SO_RCVBUF Ta "set buffer size for input"
+.It Dv SO_SNDLOWAT Ta "set minimum count for output"
+.It Dv SO_RCVLOWAT Ta "set minimum count for input"
+.It Dv SO_SNDTIMEO Ta "set timeout value for output"
+.It Dv SO_RCVTIMEO Ta "set timeout value for input"
+.It Dv SO_TYPE Ta "get the type of the socket (get only)"
+.It Dv SO_ERROR Ta "get and clear error on the socket (get only)"
+.El
+.Pp
+.Dv SO_DEBUG
+enables debugging in the underlying protocol modules.
+.Dv SO_REUSEADDR
+indicates that the rules used in validating addresses supplied
+in a
+.Xr bind 2
+call should allow reuse of local addresses.
+.Dv SO_REUSEPORT
+allows completely duplicate bindings by multiple processes
+if they all set
+.Dv SO_REUSEPORT
+before binding the port.
+This option permits multiple instances of a program to each
+receive UDP/IP multicast or broadcast datagrams destined for the bound port.
+.Dv SO_KEEPALIVE
+enables the
+periodic transmission of messages on a connected socket. Should the
+connected party fail to respond to these messages, the connection is
+considered broken and processes using the socket are notified via a
+.Dv SIGPIPE
+signal when attempting to send data.
+.Dv SO_DONTROUTE
+indicates that outgoing messages should
+bypass the standard routing facilities. Instead, messages are directed
+to the appropriate network interface according to the network portion
+of the destination address.
+.Pp
+.Dv SO_LINGER
+controls the action taken when unsent messages
+are queued on socket and a
+.Xr close 2
+is performed.
+If the socket promises reliable delivery of data and
+.Dv SO_LINGER is set,
+the system will block the process on the
+.Xr close 2
+attempt until it is able to transmit the data or until it decides it
+is unable to deliver the information (a timeout period, termed the
+linger interval, is specified in seconds in the
+.Fn setsockopt
+call when
+.Dv SO_LINGER
+is requested).
+If
+.Dv SO_LINGER
+is disabled and a
+.Xr close 2
+is issued, the system will process the close in a manner that allows
+the process to continue as quickly as possible.
+.Pp
+The option
+.Dv SO_BROADCAST
+requests permission to send broadcast datagrams
+on the socket.
+Broadcast was a privileged operation in earlier versions of the system.
+With protocols that support out-of-band data, the
+.Dv SO_OOBINLINE
+option
+requests that out-of-band data be placed in the normal data input queue
+as received; it will then be accessible with
+.Xr recv 2
+or
+.Xr read 2
+calls without the
+.Dv MSG_OOB
+flag.
+Some protocols always behave as if this option is set.
+.Dv SO_SNDBUF
+and
+.Dv SO_RCVBUF
+are options to adjust the normal
+buffer sizes allocated for output and input buffers, respectively.
+The buffer size may be increased for high-volume connections,
+or may be decreased to limit the possible backlog of incoming data.
+The system places an absolute maximum on these values, which is accessible
+through the
+.Xr sysctl 3
+MIB variable
+.Dq Li kern.ipc.maxsockbuf .
+.Pp
+.Dv SO_SNDLOWAT
+is an option to set the minimum count for output operations.
+Most output operations process all of the data supplied
+by the call, delivering data to the protocol for transmission
+and blocking as necessary for flow control.
+Nonblocking output operations will process as much data as permitted
+subject to flow control without blocking, but will process no data
+if flow control does not allow the smaller of the low water mark value
+or the entire request to be processed.
+A
+.Xr select 2
+operation testing the ability to write to a socket will return true
+only if the low water mark amount could be processed.
+The default value for
+.Dv SO_SNDLOWAT
+is set to a convenient size for network efficiency, often 1024.
+.Dv SO_RCVLOWAT
+is an option to set the minimum count for input operations.
+In general, receive calls will block until any (non-zero) amount of data
+is received, then return with the smaller of the amount available or the amount
+requested.
+The default value for
+.Dv SO_RCVLOWAT
+is 1.
+If
+.Dv SO_RCVLOWAT
+is set to a larger value, blocking receive calls normally
+wait until they have received the smaller of the low water mark value
+or the requested amount.
+Receive calls may still return less than the low water mark if an error
+occurs, a signal is caught, or the type of data next in the receive queue
+is different from that which was returned.
+.Pp
+.Dv SO_SNDTIMEO
+is an option to set a timeout value for output operations.
+It accepts a
+.Fa struct timeval
+parameter with the number of seconds and microseconds
+used to limit waits for output operations to complete.
+If a send operation has blocked for this much time,
+it returns with a partial count
+or with the error
+.Er EWOULDBLOCK
+if no data were sent.
+In the current implementation, this timer is restarted each time additional
+data are delivered to the protocol,
+implying that the limit applies to output portions ranging in size
+from the low water mark to the high water mark for output.
+.Dv SO_RCVTIMEO
+is an option to set a timeout value for input operations.
+It accepts a
+.Fa struct timeval
+parameter with the number of seconds and microseconds
+used to limit waits for input operations to complete.
+In the current implementation, this timer is restarted each time additional
+data are received by the protocol,
+and thus the limit is in effect an inactivity timer.
+If a receive operation has been blocked for this much time without
+receiving additional data, it returns with a short count
+or with the error
+.Er EWOULDBLOCK
+if no data were received.
+.Pp
+Finally,
+.Dv SO_TYPE
+and
+.Dv SO_ERROR
+are options used only with
+.Fn getsockopt .
+.Dv SO_TYPE
+returns the type of the socket, such as
+.Dv SOCK_STREAM ;
+it is useful for servers that inherit sockets on startup.
+.Dv SO_ERROR
+returns any pending error on the socket and clears
+the error status.
+It may be used to check for asynchronous errors on connected
+datagram sockets or for other asynchronous errors.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn getsockopt
+is implemented as the
+.Va getsockopt
+syscall.
+.Pp
+In the threaded library, the
+.Va getsockopt
+syscall is assembled to
+.Fn _thread_sys_getsockopt
+and
+.Fn getsockopt
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_getsockopt .
+Before returning,
+.Fn getsockopt
+unlocks
+.Va s .
+.Pp
+In the non-threaded library
+.Fn setsockopt
+is implemented as the
+.Va setsockopt
+syscall.
+.Pp
+In the threaded library, the
+.Va setsockopt
+syscall is assembled to
+.Fn _thread_sys_setsockopt
+and
+.Fn setsockopt
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_setsockopt .
+Before returning,
+.Fn setsockopt
+unlocks
+.Va s .
+.Sh RETURN VALUES
+A 0 is returned if the call succeeds, -1 if it fails.
+.Sh ERRORS
+The call succeeds unless:
+.Bl -tag -width ENOPROTOOPTAA
+.It Bq Er EBADF
+The argument
+.Fa s
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is a file, not a socket.
+.It Bq Er ENOPROTOOPT
+The option is unknown at the level indicated.
+.It Bq Er EFAULT
+The address pointed to by
+.Fa optval
+is not in a valid part of the process address space.
+For
+.Fn getsockopt ,
+this error may also be returned if
+.Fa optlen
+is not in a valid part of the process address space.
+.El
+.Sh SEE ALSO
+.Xr ioctl 2 ,
+.Xr socket 2 ,
+.Xr getprotoent 3 ,
+.Xr sysctl 3 ,
+.Xr protocols 5 ,
+.Xr sysctl 8
+.Sh BUGS
+Several of the socket options should be handled at lower levels of the system.
+.Sh HISTORY
+The
+.Fn getsockopt
+system call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/gettimeofday.2 b/lib/libc/sys/gettimeofday.2
new file mode 100644
index 0000000..cb385a4
--- /dev/null
+++ b/lib/libc/sys/gettimeofday.2
@@ -0,0 +1,132 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)gettimeofday.2 8.2 (Berkeley) 5/26/95
+.\" $FreeBSD$
+.\"
+.Dd May 26, 1995
+.Dt GETTIMEOFDAY 2
+.Os BSD 4
+.Sh NAME
+.Nm gettimeofday ,
+.Nm settimeofday
+.Nd get/set date and time
+.Sh SYNOPSIS
+.Fd #include <sys/time.h>
+.Ft int
+.Fn gettimeofday "struct timeval *tp" "struct timezone *tzp"
+.Ft int
+.Fn settimeofday "const struct timeval *tp" "const struct timezone *tzp"
+.Sh DESCRIPTION
+.Bf -symbolic
+Note: timezone is no longer used; this information is kept outside
+the kernel.
+.Ef
+.Pp
+The system's notion of the current Greenwich time and the current time
+zone is obtained with the
+.Fn gettimeofday
+call, and set with the
+.Fn settimeofday
+call. The time is expressed in seconds and microseconds
+since midnight (0 hour), January 1, 1970. The resolution of the system
+clock is hardware dependent, and the time may be updated continuously or
+in
+.Dq ticks .
+If
+.Fa tp
+or
+.Fa tzp
+is NULL, the associated time
+information will not be returned or set.
+.Pp
+The structures pointed to by
+.Fa tp
+and
+.Fa tzp
+are defined in
+.Ao Pa sys/time.h Ac
+as:
+.Pp
+.Bd -literal
+struct timeval {
+ long tv_sec; /* seconds since Jan. 1, 1970 */
+ long tv_usec; /* and microseconds */
+};
+
+struct timezone {
+ int tz_minuteswest; /* minutes west of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+.Ed
+.Pp
+The
+.Fa timezone
+structure indicates the local time zone
+(measured in minutes of time westward from Greenwich),
+and a flag that, if nonzero, indicates that
+Daylight Saving time applies locally during
+the appropriate part of the year.
+.Pp
+Only the super-user may set the time of day or time zone.
+If the system is running in secure mode (see
+.Xr init 8 ),
+the time may only be advanced.
+This limitation is imposed to prevent a malicious super-user
+from setting arbitrary time stamps on files.
+The system time can still be adjusted backwards using the
+.Xr adjtime 2
+system call even when the system is secure.
+.Sh RETURN
+A 0 return value indicates that the call succeeded.
+A -1 return value indicates an error occurred, and in this
+case an error code is stored into the global variable
+.Va errno .
+.Sh ERRORS
+The following error codes may be set in
+.Va errno :
+.Bl -tag -width [EFAULT]
+.It Bq Er EFAULT
+An argument address referenced invalid memory.
+.It Bq Er EPERM
+A user other than the super-user attempted to set the time.
+.El
+.Sh SEE ALSO
+.Xr date 1 ,
+.Xr adjtime 2 ,
+.Xr ctime 3 ,
+.Xr clocks 7 ,
+.Xr timed 8
+.Sh HISTORY
+The
+.Fn gettimeofday
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/getuid.2 b/lib/libc/sys/getuid.2
new file mode 100644
index 0000000..ae6c946
--- /dev/null
+++ b/lib/libc/sys/getuid.2
@@ -0,0 +1,92 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getuid.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETUID 2
+.Os BSD 4
+.Sh NAME
+.Nm getuid ,
+.Nm geteuid
+.Nd get user identification
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Fd #include <sys/types.h>
+.Ft uid_t
+.Fn getuid void
+.Ft uid_t
+.Fn geteuid void
+.Sh DESCRIPTION
+The
+.Fn getuid
+function returns the real user ID of the calling process.
+The
+.Fn geteuid
+function
+returns the effective user ID of the calling process.
+.Pp
+The real user ID is that of the user who has invoked the program.
+As the effective user ID
+gives the process additional permissions during
+execution of
+.Dq Em set-user-ID
+mode processes,
+.Fn getuid
+is used to determine the real-user-id of the calling process.
+.Sh ERRORS
+The
+.Fn getuid
+and
+.Fn geteuid
+functions are always successful, and no return value is reserved to
+indicate an error.
+.Sh SEE ALSO
+.Xr getgid 2 ,
+.Xr issetugid 2 ,
+.Xr setgid 2 ,
+.Xr setreuid 2 ,
+.Xr setuid 2
+.Sh STANDARDS
+The
+.Fn geteuid
+and
+.Fn getuid
+function calls are expected to conform to
+.St -p1003.1-90 .
+.Sh HISTORY
+A
+.Fn getuid
+and a
+.Fn geteuid
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/intro.2 b/lib/libc/sys/intro.2
new file mode 100644
index 0000000..fd978ca
--- /dev/null
+++ b/lib/libc/sys/intro.2
@@ -0,0 +1,712 @@
+.\" Copyright (c) 1980, 1983, 1986, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)intro.2 8.5 (Berkeley) 2/27/95
+.\" $FreeBSD$
+.\"
+.Dd February 27, 1995
+.Dt INTRO 2
+.Os BSD 4
+.Sh NAME
+.Nm intro
+.Nd introduction to system calls and error numbers
+.Sh SYNOPSIS
+.Fd #include <errno.h>
+.Sh DESCRIPTION
+This section provides an overview of the system calls,
+their error returns, and other common definitions and concepts.
+.\".Pp
+.\".Sy System call restart
+.\".Pp
+.\"<more later...>
+.Sh RETURN VALUES
+Nearly all of the system calls provide an error number referenced via
+the external identifier errno. This identifier is defined in
+.Aq Pa sys/errno.h
+as
+.Pp
+.Dl extern int * __error();
+.Dl #define errno (* __error())
+.Pp
+The
+.Va __error()
+function returns a pointer to a field in the thread specific structure for
+threads other than the initial thread. For the initial thread and
+non-threaded processes,
+.Va __error()
+returns a pointer to a global
+.Va errno
+variable that is compatible with the previous definition.
+.Pp
+When a system call detects an error,
+it returns an integer value
+indicating failure (usually -1)
+and sets the variable
+.Va errno
+accordingly.
+<This allows interpretation of the failure on receiving
+a -1 and to take action accordingly.>
+Successful calls never set
+.Va errno ;
+once set, it remains until another error occurs.
+It should only be examined after an error.
+Note that a number of system calls overload the meanings of these
+error numbers, and that the meanings must be interpreted according
+to the type and circumstances of the call.
+.Pp
+The following is a complete list of the errors and their
+names as given in
+.Aq Pa sys/errno.h .
+.Bl -hang -width Ds
+.It Er 0 Em "Error 0" .
+Not used.
+.It Er 1 EPERM Em "Operation not permitted" .
+An attempt was made to perform an operation limited to processes
+with appropriate privileges or to the owner of a file or other
+resources.
+.It Er 2 ENOENT Em "No such file or directory" .
+A component of a specified pathname did not exist, or the
+pathname was an empty string.
+.It Er 3 ESRCH Em "No such process" .
+No process could be found corresponding to that specified by the given
+process ID.
+.It Er 4 EINTR Em "Interrupted function call" .
+An asynchronous signal (such as
+.Dv SIGINT
+or
+.Dv SIGQUIT )
+was caught by the process during the execution of an interruptible
+function. If the signal handler performs a normal return, the
+interrupted function call will seem to have returned the error condition.
+.It Er 5 EIO Em "Input/output error" .
+Some physical input or output error occurred.
+This error will not be reported until a subsequent operation on the same file
+descriptor and may be lost (over written) by any subsequent errors.
+.It Er 6 ENXIO Em "\&No such device or address" .
+Input or output on a special file referred to a device that did not
+exist, or
+made a request beyond the limits of the device.
+This error may also occur when, for example,
+a tape drive is not online or no disk pack is
+loaded on a drive.
+.It Er 7 E2BIG Em "Arg list too long" .
+The number of bytes used for the argument and environment
+list of the new process exceeded the current limit
+of 65536 bytes
+.Pf ( Dv NCARGS
+in
+.Aq Pa sys/param.h ) .
+.It Er 8 ENOEXEC Em "Exec format error" .
+A request was made to execute a file
+that, although it has the appropriate permissions,
+was not in the format required for an
+executable file.
+.It Er 9 EBADF Em "Bad file descriptor" .
+A file descriptor argument was out of range, referred to no open file,
+or a read (write) request was made to a file that was only open for
+writing (reading).
+.Pp
+.It Er 10 ECHILD Em "\&No child processes" .
+A
+.Xr wait 2
+or
+.Xr waitpid 2
+function was executed by a process that had no existing or unwaited-for
+child processes.
+.It Er 11 EDEADLK Em "Resource deadlock avoided" .
+An attempt was made to lock a system resource that
+would have resulted in a deadlock situation.
+.It Er 12 ENOMEM Em "Cannot allocate memory" .
+The new process image required more memory than was allowed by the hardware
+or by system-imposed memory management constraints.
+A lack of swap space is normally temporary; however,
+a lack of core is not.
+Soft limits may be increased to their corresponding hard limits.
+.It Er 13 EACCES Em "Permission denied" .
+An attempt was made to access a file in a way forbidden
+by its file access permissions.
+.It Er 14 EFAULT Em "Bad address" .
+The system detected an invalid address in attempting to
+use an argument of a call.
+.It Er 15 ENOTBLK Em "Not a block device" .
+A block device operation was attempted on a non-block device or file.
+.It Er 16 EBUSY Em "Resource busy" .
+An attempt to use a system resource which was in use at the time
+in a manner which would have conflicted with the request.
+.It Er 17 EEXIST Em "File exists" .
+An existing file was mentioned in an inappropriate context,
+for instance, as the new link name in a
+.Xr link 2
+function.
+.It Er 18 EXDEV Em "Improper link" .
+A hard link to a file on another file system
+was attempted.
+.It Er 19 ENODEV Em "Operation not supported by device" .
+An attempt was made to apply an inappropriate
+function to a device,
+for example,
+trying to read a write-only device such as a printer.
+.It Er 20 ENOTDIR Em "Not a directory" .
+A component of the specified pathname existed, but it was
+not a directory, when a directory was expected.
+.It Er 21 EISDIR Em "Is a directory" .
+An attempt was made to open a directory with write mode specified.
+.It Er 22 EINVAL Em "Invalid argument" .
+Some invalid argument was supplied. (For example,
+specifying an undefined signal to a
+.Xr signal 3
+or
+.Xr kill 2
+function).
+.It Er 23 ENFILE Em "Too many open files in system" .
+Maximum number of file descriptors allowable on the system
+has been reached and a requests for an open cannot be satisfied
+until at least one has been closed.
+.It Er 24 EMFILE Em "Too many open files" .
+<As released, the limit on the number of
+open files per process is 64.>
+.Xr Getdtablesize 2
+will obtain the current limit.
+.It Er 25 ENOTTY Em "Inappropriate ioctl for device" .
+A control function (see
+.Xr ioctl 2 )
+was attempted for a file or
+special device for which the operation was inappropriate.
+.It Er 26 ETXTBSY Em "Text file busy" .
+The new process was a pure procedure (shared text) file
+which was open for writing by another process, or
+while the pure procedure file was being executed an
+.Xr open 2
+call requested write access.
+.It Er 27 EFBIG Em "File too large" .
+The size of a file exceeded the maximum (about
+.if t 2\u\s-231\s+2\d
+.if n 2.1E9
+bytes).
+.It Er 28 ENOSPC Em "Device out of space" .
+A
+.Xr write 2
+to an ordinary file, the creation of a
+directory or symbolic link, or the creation of a directory
+entry failed because no more disk blocks were available
+on the file system, or the allocation of an inode for a newly
+created file failed because no more inodes were available
+on the file system.
+.It Er 29 ESPIPE Em "Illegal seek" .
+An
+.Xr lseek 2
+function was issued on a socket, pipe or
+.Tn FIFO .
+.It Er 30 EROFS Em "Read-only file system" .
+An attempt was made to modify a file or directory
+was made
+on a file system that was read-only at the time.
+.It Er 31 EMLINK Em "Too many links" .
+Maximum allowable hard links to a single file has been exceeded (limit
+of 32767 hard links per file).
+.It Er 32 EPIPE Em "Broken pipe" .
+A write on a pipe, socket or
+.Tn FIFO
+for which there is no process
+to read the data.
+.It Er 33 EDOM Em "Numerical argument out of domain" .
+A numerical input argument was outside the defined domain of the mathematical
+function.
+.It Er 34 ERANGE Em "Numerical result out of range" .
+A numerical result of the function was too large to fit in the
+available space (perhaps exceeded precision).
+.It Er 35 EAGAIN Em "Resource temporarily unavailable" .
+This is a temporary condition and later calls to the
+same routine may complete normally.
+.It Er 36 EINPROGRESS Em "Operation now in progress" .
+An operation that takes a long time to complete (such as
+a
+.Xr connect 2 )
+was attempted on a non-blocking object (see
+.Xr fcntl 2 ) .
+.It Er 37 EALREADY Em "Operation already in progress" .
+An operation was attempted on a non-blocking object that already
+had an operation in progress.
+.It Er 38 ENOTSOCK Em "Socket operation on non-socket" .
+Self-explanatory.
+.It Er 39 EDESTADDRREQ Em "Destination address required" .
+A required address was omitted from an operation on a socket.
+.It Er 40 EMSGSIZE Em "Message too long" .
+A message sent on a socket was larger than the internal message buffer
+or some other network limit.
+.It Er 41 EPROTOTYPE Em "Protocol wrong type for socket" .
+A protocol was specified that does not support the semantics of the
+socket type requested. For example, you cannot use the
+.Tn ARPA
+Internet
+.Tn UDP
+protocol with type
+.Dv SOCK_STREAM .
+.It Er 42 ENOPROTOOPT Em "Protocol not available" .
+A bad option or level was specified in a
+.Xr getsockopt 2
+or
+.Xr setsockopt 2
+call.
+.It Er 43 EPROTONOSUPPORT Em "Protocol not supported" .
+The protocol has not been configured into the
+system or no implementation for it exists.
+.It Er 44 ESOCKTNOSUPPORT Em "Socket type not supported" .
+The support for the socket type has not been configured into the
+system or no implementation for it exists.
+.It Er 45 EOPNOTSUPP Em "Operation not supported" .
+The attempted operation is not supported for the type of object referenced.
+Usually this occurs when a file descriptor refers to a file or socket
+that cannot support this operation,
+for example, trying to
+.Em accept
+a connection on a datagram socket.
+.It Er 46 EPFNOSUPPORT Em "Protocol family not supported" .
+The protocol family has not been configured into the
+system or no implementation for it exists.
+.It Er 47 EAFNOSUPPORT Em "Address family not supported by protocol family" .
+An address incompatible with the requested protocol was used.
+For example, you shouldn't necessarily expect to be able to use
+.Tn NS
+addresses with
+.Tn ARPA
+Internet protocols.
+.It Er 48 EADDRINUSE Em "Address already in use" .
+Only one usage of each address is normally permitted.
+.Pp
+.It Er 49 EADDRNOTAVAIL Em "Cannot assign requested address" .
+Normally results from an attempt to create a socket with an
+address not on this machine.
+.It Er 50 ENETDOWN Em "Network is down" .
+A socket operation encountered a dead network.
+.It Er 51 ENETUNREACH Em "Network is unreachable" .
+A socket operation was attempted to an unreachable network.
+.It Er 52 ENETRESET Em "Network dropped connection on reset" .
+The host you were connected to crashed and rebooted.
+.It Er 53 ECONNABORTED Em "Software caused connection abort" .
+A connection abort was caused internal to your host machine.
+.It Er 54 ECONNRESET Em "Connection reset by peer" .
+A connection was forcibly closed by a peer. This normally
+results from a loss of the connection on the remote socket
+due to a timeout or a reboot.
+.It Er 55 ENOBUFS Em "\&No buffer space available" .
+An operation on a socket or pipe was not performed because
+the system lacked sufficient buffer space or because a queue was full.
+.It Er 56 EISCONN Em "Socket is already connected" .
+A
+.Xr connect 2
+request was made on an already connected socket; or,
+a
+.Xr sendto 2
+or
+.Xr sendmsg 2
+request on a connected socket specified a destination
+when already connected.
+.It Er 57 ENOTCONN Em "Socket is not connected" .
+An request to send or receive data was disallowed because
+the socket was not connected and (when sending on a datagram socket)
+no address was supplied.
+.It Er 58 ESHUTDOWN Em "Cannot send after socket shutdown" .
+A request to send data was disallowed because the socket
+had already been shut down with a previous
+.Xr shutdown 2
+call.
+.It Er 60 ETIMEDOUT Em "Operation timed out" .
+A
+.Xr connect 2
+or
+.Xr send 2
+request failed because the connected party did not
+properly respond after a period of time. (The timeout
+period is dependent on the communication protocol.)
+.It Er 61 ECONNREFUSED Em "Connection refused" .
+No connection could be made because the target machine actively
+refused it. This usually results from trying to connect
+to a service that is inactive on the foreign host.
+.It Er 62 ELOOP Em "Too many levels of symbolic links" .
+A path name lookup involved more than 32
+.Pq Dv MAXSYMLINKS
+symbolic links.
+.It Er 63 ENAMETOOLONG Em "File name too long" .
+A component of a path name exceeded 255
+.Pq Dv MAXNAMELEN
+characters, or an entire
+path name exceeded 1023
+.Pq Dv MAXPATHLEN Ns -1
+characters.
+.It Er 64 EHOSTDOWN Em "Host is down" .
+A socket operation failed because the destination host was down.
+.It Er 65 EHOSTUNREACH Em "No route to host" .
+A socket operation was attempted to an unreachable host.
+.It Er 66 ENOTEMPTY Em "Directory not empty" .
+A directory with entries other than
+.Ql \&.
+and
+.Ql \&..
+was supplied to a remove directory or rename call.
+.It Er 67 EPROCLIM Em "Too many processes" .
+.It Er 68 EUSERS Em "Too many users" .
+The quota system ran out of table entries.
+.It Er 69 EDQUOT Em "Disc quota exceeded" .
+A
+.Xr write 2
+to an ordinary file, the creation of a
+directory or symbolic link, or the creation of a directory
+entry failed because the user's quota of disk blocks was
+exhausted, or the allocation of an inode for a newly
+created file failed because the user's quota of inodes
+was exhausted.
+.ne 1i
+.It Er 70 ESTALE Em "Stale NFS file handle" .
+An attempt was made to access an open file (on an
+.Tn NFS
+filesystem)
+which is now unavailable as referenced by the file descriptor.
+This may indicate the file was deleted on the
+.Tn NFS
+server or some
+other catastrophic event occurred.
+.It Er 72 EBADRPC Em "RPC struct is bad" .
+Exchange of
+.Tn RPC
+information was unsuccessful.
+.It Er 73 ERPCMISMATCH Em "RPC version wrong" .
+The version of
+.Tn RPC
+on the remote peer is not compatible with
+the local version.
+.It Er 74 EPROGUNAVAIL Em "RPC prog. not avail" .
+The requested program is not registered on the remote host.
+.It Er 75 EPROGMISMATCH Em "Program version wrong" .
+The requested version of the program is not available
+on the remote host
+.Pq Tn RPC .
+.It Er 76 EPROCUNAVAIL Em "Bad procedure for program" .
+An
+.Tn RPC
+call was attempted for a procedure which doesn't exist
+in the remote program.
+.It Er 77 ENOLCK Em "No locks available" .
+A system-imposed limit on the number of simultaneous file
+locks was reached.
+.It Er 78 ENOSYS Em "Function not implemented" .
+Attempted a system call that is not available on this
+system.
+.It Er 79 EFTYPE Em "Inappropriate file type or format" .
+The file was the wrong type for the operation, or a data file had
+the wrong format.
+.It Er 80 EAUTH Em "Authentication error" .
+Attempted to use an invalid authentication ticket to mount a
+.Tn NFS
+filesystem.
+.It Er 81 ENEEDAUTH Em "Need authenticator" .
+An authentication ticket must be obtained before the given
+.Tn NFS
+filesystem may be mounted.
+.It Er 82 EIDRM Em "Identifier removed" .
+An IPC identifier was removed while the current process was waiting on it.
+.It Er 83 ENOMSG Em "No message of desired type" .
+An IPC message queue does not contain a message of the desired type, or a
+message catalog does not contain the requested message.
+.It Er 84 EOVERFLOW Em "Value too large to be stored in data type" .
+A numerical result of the function was too large to be stored in the caller
+provided space.
+.It Er 85 ECANCELED Em "Operation canceled" .
+The scheduled operation was canceled.
+.It Er 86 EILSEQ Em "Illegal byte sequence" .
+While decoding a multibyte character the function came along an
+invalid or an incomplete sequence of bytes or the given wide
+character is invalid.
+.Sh DEFINITIONS
+.Bl -tag -width Ds
+.It Process ID .
+Each active process in the system is uniquely identified by a non-negative
+integer called a process ID. The range of this ID is from 0 to 99999.
+.It Parent process ID
+A new process is created by a currently active process; (see
+.Xr fork 2 ) .
+The parent process ID of a process is initially the process ID of its creator.
+If the creating process exits,
+the parent process ID of each child is set to the ID of a system process,
+.Xr init 8 .
+.It Process Group
+Each active process is a member of a process group that is identified by
+a non-negative integer called the process group ID. This is the process
+ID of the group leader. This grouping permits the signaling of related
+processes (see
+.Xr termios 4 )
+and the job control mechanisms of
+.Xr csh 1 .
+.It Session
+A session is a set of one or more process groups.
+A session is created by a successful call to
+.Xr setsid 2 ,
+which causes the caller to become the only member of the only process
+group in the new session.
+.It Session leader
+A process that has created a new session by a successful call to
+.Xr setsid 2 ,
+is known as a session leader.
+Only a session leader may acquire a terminal as its controlling terminal (see
+.Xr termios 4 ) .
+.It Controlling process
+A session leader with a controlling terminal is a controlling process.
+.It Controlling terminal
+A terminal that is associated with a session is known as the controlling
+terminal for that session and its members.
+.ne 1i
+.It "Terminal Process Group ID"
+A terminal may be acquired by a session leader as its controlling terminal.
+Once a terminal is associated with a session, any of the process groups
+within the session may be placed into the foreground by setting
+the terminal process group ID to the ID of the process group.
+This facility is used
+to arbitrate between multiple jobs contending for the same terminal;
+(see
+.Xr csh 1
+and
+.Xr tty 4 ) .
+.It "Orphaned Process Group"
+A process group is considered to be
+.Em orphaned
+if it is not under the control of a job control shell.
+More precisely, a process group is orphaned
+when none of its members has a parent process that is in the same session
+as the group,
+but is in a different process group.
+Note that when a process exits, the parent process for its children
+is changed to be
+.Xr init 8 ,
+which is in a separate session.
+Not all members of an orphaned process group are necessarily orphaned
+processes (those whose creating process has exited).
+The process group of a session leader is orphaned by definition.
+.It "Real User ID and Real Group ID"
+Each user on the system is identified by a positive integer
+termed the real user ID.
+.Pp
+Each user is also a member of one or more groups.
+One of these groups is distinguished from others and
+used in implementing accounting facilities. The positive
+integer corresponding to this distinguished group is termed
+the real group ID.
+.Pp
+All processes have a real user ID and real group ID.
+These are initialized from the equivalent attributes
+of the process that created it.
+.It "Effective User Id, Effective Group Id, and Group Access List"
+Access to system resources is governed by two values:
+the effective user ID, and the group access list.
+The first member of the group access list is also known as the
+effective group ID.
+(In POSIX.1, the group access list is known as the set of supplementary
+group IDs, and it is unspecified whether the effective group ID is
+a member of the list.)
+.Pp
+The effective user ID and effective group ID are initially the
+process's real user ID and real group ID respectively. Either
+may be modified through execution of a set-user-ID or set-group-ID
+file (possibly by one its ancestors) (see
+.Xr execve 2 ) .
+By convention, the effective group ID (the first member of the group access
+list) is duplicated, so that the execution of a set-group-ID program
+does not result in the loss of the original (real) group ID.
+.Pp
+The group access list is a set of group IDs
+used only in determining resource accessibility. Access checks
+are performed as described below in ``File Access Permissions''.
+.It "Saved Set User ID and Saved Set Group ID"
+When a process executes a new file, the effective user ID is set
+to the owner of the file if the file is set-user-ID, and the effective
+group ID (first element of the group access list) is set to the group
+of the file if the file is set-group-ID.
+The effective user ID of the process is then recorded as the saved set-user-ID,
+and the effective group ID of the process is recorded as the saved set-group-ID.
+These values may be used to regain those values as the effective user
+or group ID after reverting to the real ID (see
+.Xr setuid 2 ) .
+(In POSIX.1, the saved set-user-ID and saved set-group-ID are optional,
+and are used in setuid and setgid, but this does not work as desired
+for the super-user.)
+.It Super-user
+A process is recognized as a
+.Em super-user
+process and is granted special privileges if its effective user ID is 0.
+.ne 1i
+.It Special Processes
+The processes with process IDs of 0, 1, and 2 are special.
+Process 0 is the scheduler. Process 1 is the initialization process
+.Xr init 8 ,
+and is the ancestor of every other process in the system.
+It is used to control the process structure.
+Process 2 is the paging daemon.
+.It Descriptor
+An integer assigned by the system when a file is referenced
+by
+.Xr open 2
+or
+.Xr dup 2 ,
+or when a socket is created by
+.Xr pipe 2 ,
+.Xr socket 2
+or
+.Xr socketpair 2 ,
+which uniquely identifies an access path to that file or socket from
+a given process or any of its children.
+.It File Name
+Names consisting of up to 255
+.Pq Dv MAXNAMELEN
+characters may be used to name
+an ordinary file, special file, or directory.
+.Pp
+These characters may be selected from the set of all
+.Tn ASCII
+character
+excluding 0 (NUL) and the
+.Tn ASCII
+code for
+.Ql \&/
+(slash).
+.Pp
+Note that it is generally unwise to use
+.Ql \&* ,
+.Ql \&? ,
+.Ql \&[
+or
+.Ql \&]
+as part of
+file names because of the special meaning attached to these characters
+by the shell.
+.It Path Name
+A path name is a
+.Tn NUL Ns -terminated
+character string starting with an
+optional slash
+.Ql \&/ ,
+followed by zero or more directory names separated
+by slashes, optionally followed by a file name.
+The total length of a path name must be less than 1024
+.Pq Dv MAXPATHLEN
+characters.
+.Pp
+If a path name begins with a slash, the path search begins at the
+.Em root
+directory.
+Otherwise, the search begins from the current working directory.
+A slash by itself names the root directory. An empty
+pathname refers to the current directory.
+.It Directory
+A directory is a special type of file that contains entries
+that are references to other files.
+Directory entries are called links. By convention, a directory
+contains at least two links,
+.Ql \&.
+and
+.Ql \&.. ,
+referred to as
+.Em dot
+and
+.Em dot-dot
+respectively. Dot refers to the directory itself and
+dot-dot refers to its parent directory.
+.It "Root Directory and Current Working Directory"
+Each process has associated with it a concept of a root directory
+and a current working directory for the purpose of resolving path
+name searches. A process's root directory need not be the root
+directory of the root file system.
+.It File Access Permissions
+Every file in the file system has a set of access permissions.
+These permissions are used in determining whether a process
+may perform a requested operation on the file (such as opening
+a file for writing). Access permissions are established at the
+time a file is created. They may be changed at some later time
+through the
+.Xr chmod 2
+call.
+.Pp
+File access is broken down according to whether a file may be: read,
+written, or executed. Directory files use the execute
+permission to control if the directory may be searched.
+.Pp
+File access permissions are interpreted by the system as
+they apply to three different classes of users: the owner
+of the file, those users in the file's group, anyone else.
+Every file has an independent set of access permissions for
+each of these classes. When an access check is made, the system
+decides if permission should be granted by checking the access
+information applicable to the caller.
+.Pp
+Read, write, and execute/search permissions on
+a file are granted to a process if:
+.Pp
+The process's effective user ID is that of the super-user. (Note:
+even the super-user cannot execute a non-executable file.)
+.Pp
+The process's effective user ID matches the user ID of the owner
+of the file and the owner permissions allow the access.
+.Pp
+The process's effective user ID does not match the user ID of the
+owner of the file, and either the process's effective
+group ID matches the group ID
+of the file, or the group ID of the file is in
+the process's group access list,
+and the group permissions allow the access.
+.Pp
+Neither the effective user ID nor effective group ID
+and group access list of the process
+match the corresponding user ID and group ID of the file,
+but the permissions for ``other users'' allow access.
+.Pp
+Otherwise, permission is denied.
+.It Sockets and Address Families
+.Pp
+A socket is an endpoint for communication between processes.
+Each socket has queues for sending and receiving data.
+.Pp
+Sockets are typed according to their communications properties.
+These properties include whether messages sent and received
+at a socket require the name of the partner, whether communication
+is reliable, the format used in naming message recipients, etc.
+.Pp
+Each instance of the system supports some
+collection of socket types; consult
+.Xr socket 2
+for more information about the types available and
+their properties.
+.Pp
+Each instance of the system supports some number of sets of
+communications protocols. Each protocol set supports addresses
+of a certain format. An Address Family is the set of addresses
+for a specific group of protocols. Each socket has an address
+chosen from the address family in which the socket was created.
+.Sh SEE ALSO
+.Xr intro 3 ,
+.Xr perror 3
diff --git a/lib/libc/sys/ioctl.2 b/lib/libc/sys/ioctl.2
new file mode 100644
index 0000000..703e1ee
--- /dev/null
+++ b/lib/libc/sys/ioctl.2
@@ -0,0 +1,144 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ioctl.2 8.2 (Berkeley) 12/11/93
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt IOCTL 2
+.Os BSD 4
+.Sh NAME
+.Nm ioctl
+.Nd control device
+.Sh SYNOPSIS
+.Fd #include <sys/ioctl.h>
+.Ft int
+.Fn ioctl "int d" "unsigned long request" ...
+.Sh DESCRIPTION
+The
+.Fn ioctl
+function manipulates the underlying device parameters of special files.
+In particular, many operating
+characteristics of character special files (e.g. terminals)
+may be controlled with
+.Fn ioctl
+requests.
+The argument
+.Fa d
+must be an open file descriptor.
+.Pp
+The third argument to
+.Nm
+is traditionally named
+.Ar "char *argp" .
+Most uses of
+.Nm
+in
+.Fx 3.0
+however, require the third argument to be a
+.Ar caddr_t
+or an
+.Ar int .
+.Pp
+An ioctl
+.Fa request
+has encoded in it whether the argument is an
+.Dq in
+parameter
+or
+.Dq out
+parameter, and the size of the argument
+.Fa argp
+in bytes.
+Macros and defines used in specifying an ioctl
+.Fa request
+are located in the file
+.Ao Pa sys/ioctl.h Ac .
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn ioctl
+is implemented as the
+.Va ioctl
+syscall.
+.Pp
+In the threaded library, the
+.Va ioctl
+syscall is assembled to
+.Fn _thread_sys_ioctl
+and
+.Fn ioctl
+is implemented as a function which locks
+.Va d
+for read and write, then calls
+.Fn _thread_sys_ioctl .
+Before returning,
+.Fn ioctl
+unlocks
+.Va d .
+.Sh RETURN VALUES
+If an error has occurred, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Ioctl
+will fail if:
+.Bl -tag -width [ENOTTY]
+.It Bq Er EBADF
+.Fa d
+is not a valid descriptor.
+.It Bq Er ENOTTY
+.Fa d
+is not associated with a character
+special device.
+.It Bq Er ENOTTY
+The specified request does not apply to the kind
+of object that the descriptor
+.Fa d
+references.
+.It Bq Er EINVAL
+.Fa Request
+or
+.Fa argp
+is not valid.
+.El
+.Sh SEE ALSO
+.Xr mt 1 ,
+.Xr execve 2 ,
+.Xr fcntl 2 ,
+.Xr intro 4 ,
+.Xr tty 4
+.Sh HISTORY
+An
+.Fn ioctl
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/issetugid.2 b/lib/libc/sys/issetugid.2
new file mode 100644
index 0000000..91adf6c
--- /dev/null
+++ b/lib/libc/sys/issetugid.2
@@ -0,0 +1,99 @@
+.\" $OpenBSD: issetugid.2,v 1.7 1997/02/18 00:16:09 deraadt Exp $
+.\"
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August, 25 1996
+.Dt ISSETUGID 2
+.Os
+.Sh NAME
+.Nm issetugid
+.Nd is current process tainted by uid or gid changes
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn issetugid void
+.Sh DESCRIPTION
+The
+.Fn issetugid
+function returns 1 if the process environment or memory address space
+is considered
+.Dq tainted ,
+and returns 0 otherwise.
+.Pp
+A process is tainted if it was created as a result of an
+.Xr execve 2
+system call which had either of the setuid or setgid bits set (and extra
+privileges were given as a result) or if it has changed any of it's real,
+effective or saved user or group ID's since it began execution.
+.Pp
+This system call exists so that library routines (eg: libc, libtermcap)
+can reliably determine if it is safe to use information
+that was obtained from the user, in particular the results from
+.Xr getenv 3
+should be viewed with suspicion if it is used to control operation.
+.Pp
+A
+.Dq tainted
+status is inherited by child processes as a result of the
+.Xr fork 2
+system call (or other library code that calls fork, such as
+.Xr popen 3 ) .
+.Pp
+It is assumed that a program that clears all privileges as it prepares
+to execute another will also reset the environment, hence the
+.Dq tainted
+status will not be passed on. This is important for programs such as
+.Xr su 1
+which begin setuid but need to be able to create an untainted process.
+.Sh ERRORS
+The
+.Fn issetugid
+function is always successful, and no return value is reserved to
+indicate an error.
+.Sh SEE ALSO
+.Xr execve 2 ,
+.Xr fork 2 ,
+.Xr setegid 2 ,
+.Xr seteuid 2 ,
+.Xr setgid 2 ,
+.Xr setregid 2 ,
+.Xr setreuid 2 ,
+.Xr setuid 2
+.Sh HISTORY
+A
+.Fn issetugid
+function call first appeared in
+.Ox 2.0
+and was also implemented in
+.Fx 3.0 .
diff --git a/lib/libc/sys/jail.2 b/lib/libc/sys/jail.2
new file mode 100644
index 0000000..00aae7e
--- /dev/null
+++ b/lib/libc/sys/jail.2
@@ -0,0 +1,105 @@
+.\"
+.\"----------------------------------------------------------------------------
+.\""THE BEER-WARE LICENSE" (Revision 42):
+.\"<phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
+.\"can do whatever you want with this stuff. If we meet some day, and you think
+.\"this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+.\"----------------------------------------------------------------------------
+.\"
+.\"$FreeBSD$
+.\"
+.\"
+.Dd April 28, 1999
+.Dt JAIL 2
+.Os FreeBSD 4.0
+.Sh NAME
+.Nm jail
+.Nd Imprison current process and future decendants.
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/jail.h>
+.Ft int
+.Fn jail "struct jail *jail"
+.Sh DESCRIPTION
+The
+.Nm
+system call sets up a jail and locks the current process in it.
+.Pp
+The argument is a pointer to a structure describing the prison:
+.Bd -literal -offset indent
+struct jail {
+ u_int32_t version;
+ char *path;
+ char *hostname;
+ u_int32_t ip_number;
+};
+.Ed
+.Pp
+.Dq Li version
+defines the version of the API in use. It should be set to zero at this time.
+.Pp
+The
+.Dq Li path
+pointer should be set to the directory which is to be the root of the
+prison.
+.Pp
+The
+.Dq Li hostname
+pointer can be set the hostname of the prison. This can be changed
+from the inside of the prison.
+.Pp
+The
+.Dq Li ip_number
+can be set to the IP number assigned to the prison.
+.Sh PRISON ?
+Once a process has been put in a prison, it and its decendants cannot escape
+the prison. It is not possible to add a process to a preexisting prison.
+.Pp
+Inside the prison, the concept of "superuser" is very diluted. In general,
+it can be assumed that nothing can be mangled from inside a prison which
+doesn't exist entirely inside that prison. For instance the directory
+tree below
+.Dq Li path
+can be manipulated all the ways a root can normally do it, including
+.Dq Li "rm -rf /*"
+but new device special notes cannot be created because the reference
+shared resources (the device drivers in the kernel).
+.Pp
+All IP activity will be forced to happen to/from the IP number specified,
+which should be an alias on one of the network interfaces.
+.Pp
+It is possible to identify a process as jailed by examining
+.Dq Li /proc/<pid>/status :
+it will show a field near the end of the line, either as
+a single hyphen for a process at large, or the hostname currently
+set for the prison for jailed processes.
+.Sh ERRORS
+.Fn jail
+will fail if:
+.Bl -tag -width EWOULDBLOCK
+.It Bq Er EINVAL
+The version number of the argument is not correct.
+.El
+Further
+.Fn Jail
+calls
+.Xr chroot 2
+internally, so the it can fail for all the same reasons.
+Please consult the
+.Xr chroot 2
+manual page for details.
+.Sh SEE ALSO
+.Xr chdir 2 ,
+.Xr chroot 2
+.Sh HISTORY
+The
+.Fn jail
+function call appeared in
+.Fx 4.0 .
+.Pp
+The jail feature was written by
+.An Poul-Henning Kamp
+for R&D Associates
+.Dq Li http://www.rndassociates.com/
+who contributed it to
+.Fx .
diff --git a/lib/libc/sys/kill.2 b/lib/libc/sys/kill.2
new file mode 100644
index 0000000..c8667d8
--- /dev/null
+++ b/lib/libc/sys/kill.2
@@ -0,0 +1,142 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)kill.2 8.3 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt KILL 2
+.Os BSD 4
+.Sh NAME
+.Nm kill
+.Nd send signal to a process
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <signal.h>
+.Ft int
+.Fn kill "pid_t pid" "int sig"
+.Sh DESCRIPTION
+The
+.Fn kill
+function sends the signal given by
+.Fa sig
+to
+.Fa pid ,
+a
+process or a group of processes.
+.Fa Sig
+may be one of the signals specified in
+.Xr sigaction 2
+or it may be 0, in which case
+error checking is performed but no
+signal is actually sent.
+This can be used to check the validity of
+.Fa pid .
+.Pp
+For a process to have permission to send a signal to a process designated
+by
+.Fa pid ,
+the real or effective user ID of the receiving process must match
+that of the sending process or the user must have appropriate privileges
+(such as given by a set-user-ID program or the user is the super-user).
+A single exception is the signal SIGCONT, which may always be sent
+to any descendant of the current process.
+.Bl -tag -width Ds
+.It \&If Fa pid No \&is greater than zero :
+.Fa Sig
+is sent to the process whose ID is equal to
+.Fa pid.
+.It \&If Fa pid No \&is zero :
+.Fa Sig
+is sent to all processes whose group ID is equal
+to the process group ID of the sender, and for which the
+process has permission;
+this is a variant of
+.Xr killpg 2 .
+.It \&If Fa pid No \&is -1 :
+If the user has super-user privileges,
+the signal is sent to all processes excluding
+system processes
+.Pq with Dv P_SYSTEM flag set ,
+process with ID 1
+.Pq usually Xr init 8 ,
+and the process sending the signal.
+If the user is not the super user, the signal is sent to all processes
+with the same uid as the user excluding the process sending the signal.
+No error is returned if any process could be signaled.
+.El
+.Pp
+For compatibility with System V,
+if the process number is negative but not -1,
+the signal is sent to all processes whose process group ID
+is equal to the absolute value of the process number.
+This is a variant of
+.Xr killpg 2 .
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned.
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Kill
+will fail and no signal will be sent if:
+.Bl -tag -width [EINVAL]
+.It Bq Er EINVAL
+.Fa Sig
+is not a valid signal number.
+.It Bq Er ESRCH
+No process can be found corresponding to that specified by
+.Fa pid .
+.It Bq Er ESRCH
+The process id was given as 0
+but the sending process does not have a process group.
+.It Bq Er EPERM
+The sending process is not the super-user and its effective
+user id does not match the effective user-id of the receiving process.
+When signaling a process group, this error is returned if any members
+of the group could not be signaled.
+.El
+.Sh SEE ALSO
+.Xr getpgrp 2 ,
+.Xr getpid 2 ,
+.Xr killpg 2 ,
+.Xr sigaction 2 ,
+.Xr init 8
+.Sh STANDARDS
+The
+.Fn kill
+function call is expected to conform to
+.St -p1003.1-90 .
+.Sh HISTORY
+A
+.Fn kill
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/kldfind.2 b/lib/libc/sys/kldfind.2
new file mode 100644
index 0000000..96be122
--- /dev/null
+++ b/lib/libc/sys/kldfind.2
@@ -0,0 +1,74 @@
+.\"
+.\" Copyright (c) 1999 Chris Costello
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 3, 1999
+.Dt KLDFIND 2
+.Os FreeBSD
+.Sh NAME
+.Nm kldfind
+.Nd returns the fileid of a kld file
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/linker.h>
+.Ft int
+.Fn kldfind "const char *file"
+.Sh DESCRIPTION
+The function
+.Fn kldfind
+returns the fileid of the kld file referenced by
+.Va file .
+.Sh RETURN VALUES
+.Fn kldfind
+returns the fileid of the kld file referenced by
+.Va file .
+Upon error,
+.Fn kldfind
+returns -1 and sets
+.Va errno
+to indicate the error.
+.Sh ERRORS
+.Va errno
+is set to the following if
+.Fn kldfind
+fails:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+The data required for this operation could not be read from the kernel space.
+.It Bq Er ENOENT
+The file specified is not loaded in the kernel.
+.Sh SEE ALSO
+.Xr kldfirstmod 2 ,
+.Xr kldload 2 ,
+.Xr kldnext 2 ,
+.Xr kldstat 2 ,
+.Xr kldunload 2 ,
+.Xr kld 4
+.Sh HISTORY
+The
+.Nm kld
+interface first appeared in
+.Fx 3.0 .
diff --git a/lib/libc/sys/kldfirstmod.2 b/lib/libc/sys/kldfirstmod.2
new file mode 100644
index 0000000..29e43d6
--- /dev/null
+++ b/lib/libc/sys/kldfirstmod.2
@@ -0,0 +1,67 @@
+.\"
+.\" Copyright (c) 1999 Chris Costello
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 3, 1999
+.Dt KLDFIRSTMOD 2
+.Os FreeBSD
+.Sh NAME
+.Nm kldfirstmod
+.Nd "return first module id from the kld file specified"
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/linker.h>
+.Ft int
+.Fn kldfirstmod "int fileid"
+.Sh DESCRIPTION
+The
+.Fn kldfirstmod
+function returns the module id pertaining to the first module referenced by
+.Va fileid .
+.Sh RETURN VALUES
+The
+.Fn kldfirstmod
+will return the id of the first module referenced by
+.Va fileid
+or 0 if there are no references.
+.Sh ERRORS
+.Bl -tag -width Er
+.It Bq Er ENOENT
+The kld file referenced by
+.Va fileid
+was not found.
+.Sh SEE ALSO
+.Xr kldfind 2 ,
+.Xr kldload 2 ,
+.Xr kldnext 2 ,
+.Xr kldstat 2 ,
+.Xr kldunload 2 ,
+.Xr kld 4
+.Sh HISTORY
+The
+.Nm kld
+interface first appeared in
+.Fx 3.0 .
diff --git a/lib/libc/sys/kldload.2 b/lib/libc/sys/kldload.2
new file mode 100644
index 0000000..7a2f9a1
--- /dev/null
+++ b/lib/libc/sys/kldload.2
@@ -0,0 +1,83 @@
+.\"
+.\" Copyright (c) 1999 Chris Costello
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+
+.Dd March 3, 1999
+.Dt KLDLOAD 2
+.Os FreeBSD
+.Sh NAME
+.Nm kldload
+.Nd load KLD files into the kernel
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/linker.h>
+.Ft int
+.Fn kldload "const char *file"
+.Sh DESCRIPTION
+The function
+.Fn kldload
+loads a kld file into the kernel using the kernel linker.
+.Sh RETURN VALUES
+The function
+.Fn kldload
+returns the fileid of the kld file which was loaded into the kernel. If
+an error occurs,
+.Fn kldload
+will return -1 and set
+.Va errno
+to indicate the error.
+.Sh ERRORS
+The named file is loaded unless:
+.Bl -tag -width Er
+.It Bq Er EPERM
+You do not have access to read the file or link it with the kernel. You should
+be the root user to be able to use the
+.Nm kld
+functions.
+.It Bq Er EFAULT
+Bad address encountered when adding kld info into the kernel space.
+.It Bq Er ENOMEM
+There is no memory to load the file into the kernel.
+.It Bq Er ENOENT
+The file was not found.
+.It Bq Er ENOEXEC
+The file format of
+.Va file
+was unrecognized.
+.Sh SEE ALSO
+.Xr kldfind 2 ,
+.Xr kldfirstmod 2 ,
+.Xr kldnext 2 ,
+.Xr kldstat 2 ,
+.Xr kldunload 2 ,
+.Xr kld 4 ,
+.Xr kldload 8
+.Sh HISTORY
+The
+.Nm kld
+interface first appeared in
+.Fx 3.0 .
diff --git a/lib/libc/sys/kldnext.2 b/lib/libc/sys/kldnext.2
new file mode 100644
index 0000000..9e73564
--- /dev/null
+++ b/lib/libc/sys/kldnext.2
@@ -0,0 +1,70 @@
+.\"
+.\" Copyright (c) 1999 Chris Costello
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 3, 1999
+.Dt KLDNEXT 2
+.Os FreeBSD
+.Sh NAME
+.Nm kldnext
+.Nd return the fileid of the next kld file
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/linker.h>
+.Ft int
+.Fn kldnext "int fileid"
+.Sh DESCRIPTION
+The function
+.Fn kldnext
+returns the fileid of the next kld file (that is, the one after
+.Va fileid )
+or 0 if
+.Va fileid
+is the last file loaded.
+.Sh RETURN VALUES
+.Fn kldnext
+returns the fileid of the next kld file (see DESCRIPTION) or 0. If an error
+occurs,
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The only error set by
+.Fn kldnext
+is ENOENT, which is set when
+.Va fileid
+refers to a kld file that does not exist (isn't loaded).
+.Sh SEE ALSO
+.Xr kldfind 2 ,
+.Xr kldfirstmod 2 ,
+.Xr kldload 2 ,
+.Xr kldstat 2 ,
+.Xr kldunload 2 ,
+.Xr kld 4
+.Sh HISTORY
+The
+.Nm kld
+interface first appeared in
+.Fx 3.0 .
diff --git a/lib/libc/sys/kldstat.2 b/lib/libc/sys/kldstat.2
new file mode 100644
index 0000000..bc9adb3
--- /dev/null
+++ b/lib/libc/sys/kldstat.2
@@ -0,0 +1,116 @@
+.\"
+.\" Copyright (c) 1999 Chris Costello
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 3, 1999
+.Dt KLDSTAT 2
+.Os FreeBSD
+.Sh NAME
+.Nm kldstat
+.Nd get status of kld file
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/linker.h>
+.Ft int
+.Fn kldstat "int fileid" "struct kld_file_stat *stat"
+.Sh DESCRIPTION
+The
+.Fn kldstat
+function writes the info for the file referred to by
+.Va fileid
+into
+.Va stat .
+.Bd -literal
+struct kld_file_stat {
+ int version; /* set to sizeof(linker_file_stat) */
+ char name[MAXPATHLEN];
+ int refs;
+ int id;
+ caddr_t address; /* load address */
+ size_t size; /* size in bytes */
+};
+.Ed
+.Pp
+.Bl -tag -width XXXaddress
+.It version
+This field is set to the size of the structure mentioned above by the code
+calling
+.Fn kldstat ,
+and not
+.Fn kldstat
+itself.
+.It name
+The name of the file referred to by
+.Va fileid .
+.It refs
+The number of modules referenced by
+.Va fileid .
+.It id
+The id of the file specified in
+.Va fileid .
+.It address
+The load address of the kld file.
+.It size
+The size of the file.
+.Sh RETURN VALUES
+.Fn kldstat
+seems to always return 0.
+.Sh ERRORS
+The information for the file referred to by
+.Va fileid
+is filled into the structure pointed to by
+.Va stat
+unless:
+.Bl -tag -width Er
+.It Bq Er ENOENT
+The file was not found (probably not loaded).
+.It Bq Er EINVAL
+The version specified in the
+.Va version
+field of stat is not the proper version. You would need to rebuild world, the
+kernel, or your application, if this error occurs, given that you did properly
+fill in the
+.Va version
+field.
+.It Bq Er EFAULT
+There was a problem copying one, some, or all of the fields into
+.Va stat
+in the
+.Fn copyout
+function.
+.Sh SEE ALSO
+.Xr kldfind 2 ,
+.Xr kldfirstmod 2 ,
+.Xr kldload 2 ,
+.Xr kldnext 2 ,
+.Xr kldunload 2 ,
+.Xr kld 4 ,
+.Xr kldstat 8
+.Sh HISTORY
+The
+.Nm kld
+interface first appeared in
+.Fx 3.0 .
diff --git a/lib/libc/sys/kldunload.2 b/lib/libc/sys/kldunload.2
new file mode 100644
index 0000000..fd803e7
--- /dev/null
+++ b/lib/libc/sys/kldunload.2
@@ -0,0 +1,78 @@
+.\"
+.\" Copyright (c) 1999 Chris Costello
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+
+.Dd March 3, 1999
+.Dt KLDUNLOAD 2
+.Os FreeBSD
+.Sh NAME
+.Nm kldunload
+.Nd unload kld files
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/linker.h>
+.Ft int
+.Fn kldunload "int fileid"
+.Sh DESCRIPTION
+The function
+.Fn kldunload
+unloads a kld file from the kernel that was previously linked via
+.Xr kldload 2 .
+.Sh RETURN VALUES
+The function
+.Fn kldunload
+returns the fileid of the kld file which was previously loaded into memory via
+.Fn kldload .
+If an error occurs,
+.Fn kldunload
+will return -1 and set
+.Va errno
+to indicate the error.
+.Sh ERRORS
+The file referred to by
+.Va fileid
+is unloaded unless:
+.Bl -tag -width Er
+.It Bq Er EPERM
+You don't have access to unlink the file from the kernel.
+.It Bq Er ENOENT
+The file was not found.
+.It Bq Er EBUSY
+You attempted to unload a file linked by the kernel.
+.Sh SEE ALSO
+.Xr kldfind 2 ,
+.Xr kldfirstmod 2 ,
+.Xr kldload 2 ,
+.Xr kldnext 2 ,
+.Xr kldstat 2 ,
+.Xr kld 4 ,
+.Xr kldunload 8
+.Sh HISTORY
+The
+.Nm kld
+interface first appeared in
+.Fx 3.0 .
diff --git a/lib/libc/sys/ktrace.2 b/lib/libc/sys/ktrace.2
new file mode 100644
index 0000000..9b25bdb
--- /dev/null
+++ b/lib/libc/sys/ktrace.2
@@ -0,0 +1,167 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ktrace.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt KTRACE 2
+.Os BSD 4
+.Sh NAME
+.Nm ktrace
+.Nd process tracing
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/time.h>
+.Fd #include <sys/uio.h>
+.Fd #include <sys/ktrace.h>
+.Ft int
+.Fn ktrace "const char *tracefile" "int ops" "int trpoints" "int pid"
+.Sh DESCRIPTION
+The
+.Fn ktrace
+function enables or disables tracing of one or more processes.
+Users may only trace their own processes.
+Only the super-user can trace setuid or setgid programs.
+.Pp
+The
+.Ar tracefile
+gives the pathname of the file to be used for tracing.
+The file must exist and be a regular file writable by the calling process.
+All trace records are always appended to the file,
+so the file must be truncated to zero length to discard
+previous trace data.
+If tracing points are being disabled (see KTROP_CLEAR below),
+.Ar tracefile
+may be NULL.
+.Pp
+The
+.Nm ops
+parameter specifies the requested ktrace operation.
+The defined operations are:
+.Bl -column KTRFLAG_DESCENDXXX -offset indent
+.It KTROP_SET Enable trace points specified in Ar trpoints .
+.It KTROP_CLEAR Disable trace points specified in Ar trpoints .
+.It KTROP_CLEARFILE Stop all tracing.
+.It KTRFLAG_DESCEND The tracing change should apply to the
+specified process and all its current children.
+.El
+.Pp
+The
+.Nm trpoints
+parameter specifies the trace points of interest.
+The defined trace points are:
+.Bl -column KTRFAC_SYSCALLXXX -offset indent
+.It KTRFAC_SYSCALL Trace system calls.
+.It KTRFAC_SYSRET Trace return values from system calls.
+.It KTRFAC_NAMEI Trace name lookup operations.
+.It KTRFAC_GENIO Trace all I/O (note that this option can
+generate much output).
+.It KTRFAC_PSIG Trace posted signals.
+.It KTRFAC_CSW Trace context switch points.
+.It KTRFAC_INHERIT Inherit tracing to future children.
+.El
+.Pp
+Each tracing event outputs a record composed of a generic header
+followed by a trace point specific structure.
+The generic header is:
+.Bd -literal
+struct ktr_header {
+ int ktr_len; /* length of buf */
+ short ktr_type; /* trace record type */
+ pid_t ktr_pid; /* process id */
+ char ktr_comm[MAXCOMLEN+1]; /* command name */
+ struct timeval ktr_time; /* timestamp */
+ caddr_t ktr_buf;
+};
+.Ed
+.Pp
+The
+.Nm ktr_len
+field specifies the length of the
+.Nm ktr_type
+data that follows this header.
+The
+.Nm ktr_pid
+and
+.Nm ktr_comm
+fields specify the process and command generating the record.
+The
+.Nm ktr_time
+field gives the time (with microsecond resolution)
+that the record was generated.
+The
+.Nm ktr_buf
+is an internal kernel pointer and is not useful.
+.Pp
+The generic header is followed by
+.Nm ktr_len
+bytes of a
+.Nm ktr_type
+record.
+The type specific records are defined in the
+.Pa <sys/ktrace.h>
+include file.
+.Sh RETURN VALUES
+On successful completion a value of 0 is returned.
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to show the error.
+.Sh ERRORS
+.Fn Ktrace
+will fail if:
+.Bl -tag -width ENAMETOOLONGAA
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named tracefile does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.It Bq Er ENOSYS
+The kernel was not compiled with
+.Nm
+support.
+.El
+.Sh SEE ALSO
+.Xr kdump 1 ,
+.Xr ktrace 1
+.Sh HISTORY
+A
+.Fn ktrace
+function call first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/link.2 b/lib/libc/sys/link.2
new file mode 100644
index 0000000..a1b6d4b
--- /dev/null
+++ b/lib/libc/sys/link.2
@@ -0,0 +1,168 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)link.2 8.3 (Berkeley) 1/12/94
+.\" $FreeBSD$
+.\"
+.Dd Mar 5, 1999
+.Dt LINK 2
+.Os BSD 4
+.Sh NAME
+.Nm link
+.Nd make a hard file link
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn link "const char *name1" "const char *name2"
+.Sh DESCRIPTION
+The
+.Fn link
+function call
+atomically creates the specified directory entry (hard link)
+.Fa name2
+with the attributes of the underlying object pointed at by
+.Fa name1 .
+If the link is successful: the link count of the underlying object
+is incremented;
+.Fa name1
+and
+.Fa name2
+share equal access and rights
+to the
+underlying object.
+.Pp
+If
+.Fa name1
+is removed, the file
+.Fa name2
+is not deleted and the link count of the
+underlying object is
+decremented.
+.Pp
+.Fa Name1
+must exist for the hard link to
+succeed and
+both
+.Fa name1
+and
+.Fa name2
+must be in the same file system.
+.Fa name1
+may not be a directory.
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned. Otherwise,
+a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Link
+will fail and no link will be created if:
+.Bl -tag -width Ar
+.It Bq Er ENOTDIR
+A component of either path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of either pathname exceeded 255 characters,
+or entire length of either path name exceeded 1023 characters.
+.It Bq Er ENOENT
+A component of either path prefix does not exist.
+.It Bq Er EOPNOTSUPP
+The file system containing the file named by
+.Fa name1
+does not support links.
+.It Bq Er EMLINK
+The link count of the file named by
+.Fa name1
+would exceed 32767.
+.It Bq Er EACCES
+A component of either path prefix denies search permission.
+.It Bq Er EACCES
+The requested link requires writing in a directory with a mode
+that denies write permission.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating one of the pathnames.
+.It Bq Er ENOENT
+The file named by
+.Fa name1
+does not exist.
+.It Bq Er EEXIST
+The link named by
+.Fa name2
+does exist.
+.It Bq Er EPERM
+The file named by
+.Fa name1
+is a directory.
+.It Bq Er EXDEV
+The link named by
+.Fa name2
+and the file named by
+.Fa name1
+are on different file systems.
+.It Bq Er ENOSPC
+The directory in which the entry for the new link is being placed
+cannot be extended because there is no space left on the file
+system containing the directory.
+.ne 3v
+.It Bq Er EDQUOT
+The directory in which the entry for the new link
+is being placed cannot be extended because the
+user's quota of disk blocks on the file system
+containing the directory has been exhausted.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to
+the file system to make the directory entry.
+.It Bq Er EROFS
+The requested link requires writing in a directory on a read-only file
+system.
+.It Bq Er EFAULT
+One of the pathnames specified
+is outside the process's allocated address space.
+.El
+.Sh SEE ALSO
+.Xr readlink 2 ,
+.Xr symlink 2 ,
+.Xr unlink 2
+.Sh STANDARDS
+The
+.Fn link
+function call is expected to conform to
+.St -p1003.1-90 .
+.Sh HISTORY
+A
+.Fn link
+function call appeared in
+.At v7 .
+.Pp
+The
+.Fn link
+system call traditionally allows the super-user to link directories which
+corrupts the filesystem coherency. This implementation no longer permits
+it.
diff --git a/lib/libc/sys/listen.2 b/lib/libc/sys/listen.2
new file mode 100644
index 0000000..4f87434
--- /dev/null
+++ b/lib/libc/sys/listen.2
@@ -0,0 +1,142 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)listen.2 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd November 3, 1995
+.Dt LISTEN 2
+.Os BSD 4.2
+.Sh NAME
+.Nm listen
+.Nd listen for connections on a socket
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft int
+.Fn listen "int s" "int backlog"
+.Sh DESCRIPTION
+To accept connections, a socket
+is first created with
+.Xr socket 2 ,
+a willingness to accept incoming connections and
+a queue limit for incoming connections are specified with
+.Fn listen ,
+and then the connections are
+accepted with
+.Xr accept 2 .
+The
+.Fn listen
+call applies only to sockets of type
+.Dv SOCK_STREAM
+or
+.Dv SOCK_SEQPACKET.
+.Pp
+The
+.Fa backlog
+parameter defines the maximum length the queue of
+pending connections may grow to.
+If a connection
+request arrives with the queue full the client may
+receive an error with an indication of
+.Er ECONNREFUSED ,
+or, if the underlying protocol supports retransmission,
+the request may be ignored so that retries may succeed.
+.Pp
+The
+.Xr sysctl 3
+MIB variable
+.Dq Li kern.ipc.somaxconn
+specifies a hard limit on
+.Fa backlog ;
+if a value greater than
+.Li kern.ipc.somaxconn
+or less than zero is specified,
+.Fa backlog
+is silently forced to
+.Li kern.ipc.somaxconn .
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn listen
+is implemented as the
+.Va listen
+syscall.
+.Pp
+In the threaded library, the
+.Va listen
+syscall is assembled to
+.Fn _thread_sys_listen
+and
+.Fn listen
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_listen .
+Before returning,
+.Fn listen
+unlocks
+.Va s .
+.Sh RETURN VALUES
+A 0 return value indicates success; -1 indicates an error.
+.Sh ERRORS
+.Fn Listen
+will fail if:
+.Bl -tag -width [EOPNOTSUPP]
+.It Bq Er EBADF
+The argument
+.Fa s
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is not a socket.
+.It Bq Er EOPNOTSUPP
+The socket is not of a type that supports the operation
+.Fn listen .
+.El
+.Sh SEE ALSO
+.Xr accept 2 ,
+.Xr connect 2 ,
+.Xr socket 2 ,
+.Xr sysctl 3 ,
+.Xr sysctl 8
+.Sh HISTORY
+The
+.Fn listen
+function call appeared in
+.Bx 4.2 .
+The ability to configure the maximum
+.Fa backlog
+at run-time, and to use a negative
+.Fa backlog
+to request the maximum allowable value, was introduced in
+.Fx 2.2 .
diff --git a/lib/libc/sys/lseek.2 b/lib/libc/sys/lseek.2
new file mode 100644
index 0000000..aaccac7
--- /dev/null
+++ b/lib/libc/sys/lseek.2
@@ -0,0 +1,141 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)lseek.2 8.3 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt LSEEK 2
+.Os BSD 4
+.Sh NAME
+.Nm lseek
+.Nd reposition read/write file offset
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft off_t
+.Fn lseek "int fildes" "off_t offset" "int whence"
+.Sh DESCRIPTION
+The
+.Fn lseek
+function repositions the offset of the file descriptor
+.Fa fildes
+to the
+argument
+.Fa offset
+according to the directive
+.Fa whence.
+The argument
+.Fa fildes
+must be an open
+file descriptor.
+.Fn Lseek
+repositions the file position pointer associated with the file
+descriptor
+.Fa fildes
+as follows:
+.Bl -item -offset indent
+.It
+If
+.Fa whence
+is
+.Dv SEEK_SET ,
+the offset is set to
+.Fa offset
+bytes.
+.It
+If
+.Fa whence
+is
+.Dv SEEK_CUR ,
+the offset is set to its current location plus
+.Fa offset
+bytes.
+.It
+If
+.Fa whence
+is
+.Dv SEEK_END ,
+the offset is set to the size of the
+file plus
+.Fa offset
+bytes.
+.El
+.Pp
+The
+.Fn lseek
+function allows the file offset to be set beyond the end
+of the existing end-of-file of the file. If data is later written
+at this point, subsequent reads of the data in the gap return
+bytes of zeros (until data is actually written into the gap).
+.Pp
+Some devices are incapable of seeking. The value of the pointer
+associated with such a device is undefined.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn lseek
+returns the resulting offset location as measured in bytes from the
+beginning of the file.
+Otherwise,
+a value of -1 is returned and
+.Va errno
+is set to indicate
+the error.
+.Sh ERRORS
+.Fn Lseek
+will fail and the file position pointer will remain unchanged if:
+.Bl -tag -width [EINVAL]
+.It Bq Er EBADF
+.Em Fildes
+is not an open file descriptor.
+.It Bq Er ESPIPE
+.Em Fildes
+is associated with a pipe, socket, or FIFO.
+.It Bq Er EINVAL
+.Fa Whence
+is not a proper value.
+.El
+.Sh SEE ALSO
+.Xr dup 2 ,
+.Xr open 2
+.Sh BUGS
+This document's use of
+.Fa whence
+is incorrect English, but is maintained for historical reasons.
+.Sh STANDARDS
+The
+.Fn lseek
+function call is expected to conform to
+.St -p1003.1-90 .
+.Sh HISTORY
+A
+.Fn lseek
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/lseek.c b/lib/libc/sys/lseek.c
new file mode 100644
index 0000000..284885f
--- /dev/null
+++ b/lib/libc/sys/lseek.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)lseek.c 8.1 (Berkeley) 6/17/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
+
+/*
+ * This function provides 64-bit offset padding that
+ * is not supplied by GCC 1.X but is supplied by GCC 2.X.
+ */
+off_t
+lseek(fd, offset, whence)
+ int fd;
+ off_t offset;
+ int whence;
+{
+#ifdef _THREAD_SAFE
+ off_t offs;
+ if (_FD_LOCK(fd, FD_RDWR, NULL) != 0) {
+ offs = -1;
+ } else {
+ offs = __syscall((quad_t) SYS_lseek,fd, 0, offset, whence);
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ return(offs);
+
+#else
+ return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
+#endif
+}
diff --git a/lib/libc/sys/madvise.2 b/lib/libc/sys/madvise.2
new file mode 100644
index 0000000..9a82782
--- /dev/null
+++ b/lib/libc/sys/madvise.2
@@ -0,0 +1,154 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)madvise.2 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd Jul 19, 1996
+.Dt MADVISE 2
+.Os
+.Sh NAME
+.Nm madvise
+.Nd give advice about use of memory
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/mman.h>
+.Ft int
+.Fn madvise "void *addr" "size_t len" "int behav"
+.Sh DESCRIPTION
+The
+.Fn madvise
+system call
+allows a process that has knowledge of its memory behavior
+to describe it to the system.
+The known behaviors are given in
+.Aq Pa sys/mman.h :
+.Bd -literal
+#define MADV_NORMAL 0 /* no further special treatment */
+#define MADV_RANDOM 1 /* expect random page references */
+#define MADV_SEQUENTIAL 2 /* expect sequential references */
+#define MADV_WILLNEED 3 /* will need these pages */
+#define MADV_DONTNEED 4 /* don't need these pages */
+#define MADV_FREE 5 /* data is now unimportant */
+#define MADV_NOSYNC 6 /* no explicit commit to physical backing store */
+#define MADV_AUTOSYNC 7 /* default commit method to physical backing store */
+.Ed
+.Pp
+.Bl -tag -width MADV_SEQUENTIAL
+.It Dv MADV_NORMAL
+Tells the system to revert to the default paging
+behavior.
+.It Dv MADV_RANDOM
+Is a hint that pages will be accessed randomly, and prefetching
+is likely not advantageous.
+.It Dv MADV_SEQUENTIAL
+Causes the VM system to depress the priority of
+pages immediately preceding a given page when it is faulted in.
+.It Dv MADV_WILLNEED
+Causes pages that are in a given virtual address range
+to temporarily have higher priority, and if they are in
+memory, decrease the likelihood of them being freed. Additionally,
+the pages that are already in memory will be immediately mapped into
+the process, thereby eliminating unnecessary overhead of going through
+the entire process of faulting the pages in. This WILL NOT fault
+pages in from backing store, but quickly map the pages already in memory
+into the calling process.
+.It Dv MADV_DONTNEED
+Allows the VM system to decrease the in-memory priority
+of pages in the specified range. Additionally future references to
+this address range will incur a page fault.
+.It Dv MADV_FREE
+Gives the VM system the freedom to free pages,
+and tells the system that information in the specified page range
+is no longer important. This is an efficient way of allowing
+.Xr malloc 3
+to free pages anywhere in the address space, while keeping the address space
+valid. The next time that the page is referenced, the page might be demand
+zeroed, or might contain the data that was there before the
+.Dv MADV_FREE
+call.
+References made to that address space range will not make the VM system
+page the information back in from backing store until the page is
+modified again.
+.It Dv MADV_NOSYNC
+Request that the system not flush the data associated with this map to
+physical backing store unless it needs to. Typically this prevents the
+filesystem update daemon from gratuitously writing pages dirtied
+by the VM system to physical disk. Note that VM/filesystem coherency is
+always maintained, this feature simply ensures that the mapped data is
+only flush when it needs to be, usually by the system pager.
+.Pp
+This feature is typically used when you want to use a file-backed shared
+memory area to communicate between processes (IPC) and do not particularly
+need the data being stored in that area to be physically written to disk.
+With this feature you get the equivalent performance with mmap that you
+would expect to get with SysV shared memory calls, but in a more controllable
+and less restrictive manner. However, note that this feature is not portable
+across UNIX platforms (though some may do the right thing by default).
+For more information see the MAP_NOSYNC section of
+.Xr mmap 2
+.It Dv MADV_AUTOSYNC
+Undoes the effects of MADV_NOSYNC for any future pages dirtied within the
+address range. The effect on pages already dirtied is indeterminate - they
+may or may not be reverted. You can guarentee reversion by using the
+.Xr msync 2
+or
+.Xr fsync 2
+system calls.
+.El
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn madvise
+returns 0. Otherwise a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn madvise
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The virtual address range specified by the
+.Fa addr
+and
+.Fa len
+arguments is not valid.
+.El
+.Sh SEE ALSO
+.Xr mincore 2 ,
+.Xr mprotect 2 ,
+.Xr msync 2 ,
+.Xr munmap 2 .
+.Sh HISTORY
+The
+.Fn madvise
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/mincore.2 b/lib/libc/sys/mincore.2
new file mode 100644
index 0000000..533c153
--- /dev/null
+++ b/lib/libc/sys/mincore.2
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mincore.2 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt MINCORE 2
+.Os
+.Sh NAME
+.Nm mincore
+.Nd get advice about use of memory
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/mman.h>
+.Ft int
+.Fn mincore "const void *addr" "size_t len" "char *vec"
+.Sh DESCRIPTION
+The
+.Fn mincore
+system call
+allows a process to obtain information about whether pages are
+core resident.
+Here the current core residency of the pages is returned
+in the character array
+.Fa vec ,
+with a value of 1 meaning
+that the page is in-core.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn mincore
+returns 0 and
+.Fa vec
+is updated to reflect the page status. Otherwise a value of -1
+is returned and
+.Va error
+is set to indicate the error.
+.Sh ERRORS
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The virtial address range specified by the
+.Fa addr
+and
+.Fa len
+arguments is not valid.
+.It Bq Er EFAULT
+The
+.Fa vec
+argument points to an illegal address.
+.El
+.Sh SEE ALSO
+.Xr madvise 2 ,
+.Xr mprotect 2 ,
+.Xr msync 2 ,
+.Xr munmap 2
+.Sh HISTORY
+The
+.Fn mincore
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/minherit.2 b/lib/libc/sys/minherit.2
new file mode 100644
index 0000000..66dbb0b
--- /dev/null
+++ b/lib/libc/sys/minherit.2
@@ -0,0 +1,94 @@
+.\" $FreeBSD$
+.\"
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)minherit.2 8.1 (Berkeley) 6/9/93
+.\"
+.Dd Feb 17, 1996
+.Dt MINHERIT 2
+.Os
+.Sh NAME
+.Nm minherit
+.Nd control the inheritance of pages
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/mman.h>
+.Ft int
+.Fn minherit "void *addr" "size_t len" "int inherit"
+.Sh DESCRIPTION
+The
+.Fn minherit
+system call
+changes the specified pages to have the inheritance characteristic
+.Fa inherit .
+Not all implementations will guarantee that the inheritance characteristic
+can be set on a page basis;
+the granularity of changes may be as large as an entire region.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn minherit
+returns 0. Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn minherit
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The virtual address range specified by the
+.Fa addr
+and
+.Fa len
+arguments is not valid.
+.It Bq Er EACCES
+The flags specified by the
+.Fa inherit
+argument were not valid for the pages specified
+by the
+.Fa addr
+and
+.Fa len
+arguments.
+.El
+.Sh SEE ALSO
+.Xr fork 2 ,
+.Xr madvise 2 ,
+.Xr mincore 2 ,
+.Xr mprotect 2 ,
+.Xr msync 2 ,
+.Xr munmap 2 ,
+.Xr rfork 2
+.Sh HISTORY
+The
+.Fn minherit
+function first appeared in OpenBSD.
diff --git a/lib/libc/sys/mkdir.2 b/lib/libc/sys/mkdir.2
new file mode 100644
index 0000000..c2d8835
--- /dev/null
+++ b/lib/libc/sys/mkdir.2
@@ -0,0 +1,110 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mkdir.2 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt MKDIR 2
+.Os BSD 4.2
+.Sh NAME
+.Nm mkdir
+.Nd make a directory file
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/stat.h>
+.Ft int
+.Fn mkdir "const char *path" "mode_t mode"
+.Sh DESCRIPTION
+The directory
+.Fa path
+is created with the access permissions specified by
+.Fa mode
+and restricted by the
+.Xr umask 2
+of the calling process.
+.Pp
+The directory's owner ID is set to the process's effective user ID.
+The directory's group ID is set to that of the parent directory in
+which it is created.
+.Sh RETURN VALUES
+A 0 return value indicates success. A -1 return value
+indicates an error, and an error code is stored in
+.Va errno .
+.Sh ERRORS
+.Fn Mkdir
+will fail and no directory will be created if:
+.Bl -tag -width ENAMETOOLO
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+A component of the path prefix does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EROFS
+The named file resides on a read-only file system.
+.It Bq Er EEXIST
+The named file exists.
+.It Bq Er ENOSPC
+The new directory cannot be created because there is no space left
+on the file system that will contain the directory.
+.It Bq Er ENOSPC
+There are no free inodes on the file system on which the
+directory is being created.
+.It Bq Er EDQUOT
+The new directory cannot be created because the user's
+quota of disk blocks on the file system that will
+contain the directory has been exhausted.
+.It Bq Er EDQUOT
+The user's quota of inodes on the file system on
+which the directory is being created has been exhausted.
+.It Bq Er EIO
+An I/O error occurred while making the directory entry or allocating the inode.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.El
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr stat 2 ,
+.Xr umask 2
+.Sh STANDARDS
+The
+.Fn mkdir
+function call is expected to conform to
+.St -p1003.1-90 .
diff --git a/lib/libc/sys/mkfifo.2 b/lib/libc/sys/mkfifo.2
new file mode 100644
index 0000000..36ab734
--- /dev/null
+++ b/lib/libc/sys/mkfifo.2
@@ -0,0 +1,121 @@
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mkfifo.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt MKFIFO 2
+.Os
+.Sh NAME
+.Nm mkfifo
+.Nd make a fifo file
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/stat.h>
+.Ft int
+.Fn mkfifo "const char *path" "mode_t mode"
+.Sh DESCRIPTION
+.Fn Mkfifo
+creates a new fifo file with name
+.Fa path .
+The access permissions are
+specified by
+.Fa mode
+and restricted by the
+.Xr umask 2
+of the calling process.
+.Pp
+The fifo's owner ID is set to the process's effective user ID.
+The fifo's group ID is set to that of the parent directory in
+which it is created.
+.Sh RETURN VALUES
+A 0 return value indicates success. A -1 return value
+indicates an error, and an error code is stored in
+.Va errno .
+.Sh ERRORS
+.Fn Mkfifo
+will fail and no fifo will be created if:
+.Bl -tag -width ENAMETOOLO
+.It Bq Er ENOTSUPP
+The kernel has not been configured to support fifo's.
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+A component of the path prefix does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EROFS
+The named file resides on a read-only file system.
+.It Bq Er EEXIST
+The named file exists.
+.It Bq Er ENOSPC
+The directory in which the entry for the new fifo is being placed
+cannot be extended because there is no space left on the file
+system containing the directory.
+.It Bq Er ENOSPC
+There are no free inodes on the file system on which the
+fifo is being created.
+.It Bq Er EDQUOT
+The directory in which the entry for the new fifo
+is being placed cannot be extended because the
+user's quota of disk blocks on the file system
+containing the directory has been exhausted.
+.It Bq Er EDQUOT
+The user's quota of inodes on the file system on
+which the fifo is being created has been exhausted.
+.It Bq Er EIO
+An
+.Tn I/O
+error occurred while making the directory entry or allocating the inode.
+.It Bq Er EIO
+An
+.Tn I/O
+error occurred while reading from or writing to the file system.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.El
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr mknod 2 ,
+.Xr stat 2 ,
+.Xr umask 2
+.Sh STANDARDS
+The
+.Fn mkfifo
+function call is expected to conform to
+.St -p1003.1-90 .
diff --git a/lib/libc/sys/mknod.2 b/lib/libc/sys/mknod.2
new file mode 100644
index 0000000..90287b2
--- /dev/null
+++ b/lib/libc/sys/mknod.2
@@ -0,0 +1,125 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mknod.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt MKNOD 2
+.Os BSD 4
+.Sh NAME
+.Nm mknod
+.Nd make a special file node
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn mknod "const char *path" "mode_t mode" "dev_t dev"
+.Sh DESCRIPTION
+The filesystem node
+.Fa path
+is created with the file type and access permissions specified in
+.Fa mode .
+The access permissions are modified by the process's umask value.
+.Pp
+If
+.Fa mode
+indicates a block or character special file,
+.Fa dev
+is a configuration dependent specification denoting a particular device
+on the system.
+Otherwise,
+.Fa dev
+is ignored.
+.Pp
+.Fn Mknod
+requires super-user privileges.
+.Sh RETURN VALUES
+Upon successful completion a value of 0 is returned.
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Mknod
+will fail and the file will be not created if:
+.Bl -tag -width Er
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+A component of the path prefix does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EPERM
+The process's effective user ID is not super-user.
+.It Bq Er EIO
+An I/O error occurred while making the directory entry or allocating the inode.
+.It Bq Er ENOSPC
+The directory in which the entry for the new node is being placed
+cannot be extended because there is no space left on the file
+system containing the directory.
+.It Bq Er ENOSPC
+There are no free inodes on the file system on which the
+node is being created.
+.It Bq Er EDQUOT
+The directory in which the entry for the new node
+is being placed cannot be extended because the
+user's quota of disk blocks on the file system
+containing the directory has been exhausted.
+.It Bq Er EDQUOT
+The user's quota of inodes on the file system on
+which the node is being created has been exhausted.
+.It Bq Er EROFS
+The named file resides on a read-only file system.
+.It Bq Er EEXIST
+The named file exists.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.It Bq Er EINVAL
+Creating anything else than a block or character special
+file (or a
+.Em whiteout )
+is not supported.
+.El
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr mkfifo 2 ,
+.Xr stat 2 ,
+.Xr umask 2
+.Sh HISTORY
+A
+.Fn mknod
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/mlock.2 b/lib/libc/sys/mlock.2
new file mode 100644
index 0000000..b5706b0
--- /dev/null
+++ b/lib/libc/sys/mlock.2
@@ -0,0 +1,173 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mlock.2 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd June 2, 1993
+.Dt MLOCK 2
+.Os
+.Sh NAME
+.Nm mlock ,
+.Nm munlock
+.Nd lock (unlock) physical pages in memory
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/mman.h>
+.Ft int
+.Fn mlock "const void *addr" "size_t len"
+.Ft int
+.Fn munlock "const void *addr" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn mlock
+system call
+locks into memory the physical pages associated with the virtual address
+range starting at
+.Fa addr
+for
+.Fa len
+bytes.
+The
+.Fn munlock
+call unlocks pages previously locked by one or more
+.Fn mlock
+calls.
+For both, the
+.Fa addr
+parameter should be aligned to a multiple of the page size.
+If the
+.Fa len
+parameter is not a multiple of the page size, it will be rounded up
+to be so.
+The entire range must be allocated.
+.Pp
+After an
+.Fn mlock
+call, the indicated pages will cause neither a non-resident page
+nor address-translation fault until they are unlocked.
+They may still cause protection-violation faults or TLB-miss faults on
+architectures with software-managed TLBs.
+The physical pages remain in memory until all locked mappings for the pages
+are removed.
+Multiple processes may have the same physical pages locked via their own
+virtual address mappings.
+A single process may likewise have pages multiply-locked via different virtual
+mappings of the same pages or via nested
+.Fn mlock
+calls on the same address range.
+Unlocking is performed explicitly by
+.Fn munlock
+or implicitly by a call to
+.Fn munmap
+which deallocates the unmapped address range.
+Locked mappings are not inherited by the child process after a
+.Xr fork 2 .
+.Pp
+Since physical memory is a potentially scarce resource, processes are
+limited in how much they can lock down.
+A single process can
+.Fn mlock
+the minimum of
+a system-wide ``wired pages'' limit and
+the per-process
+.Li RLIMIT_MEMLOCK
+resource limit.
+.Pp
+These calls are only available to the super-user.
+.Sh RETURN VALUES
+A return value of 0 indicates that the call
+succeeded and all pages in the range have either been locked or unlocked.
+A return value of -1 indicates an error occurred and the locked
+status of all pages in the range remains unchanged.
+In this case, the global location
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Mlock
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The caller is not the super-user.
+.It Bq Er EINVAL
+The address given is not page aligned or the length is negative.
+.It Bq Er EAGAIN
+Locking the indicated range would exceed either the system or per-process
+limit for locked memory.
+.It Bq Er ENOMEM
+Some portion of the indicated address range is not allocated.
+There was an error faulting/mapping a page.
+.El
+.Fn Munlock
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The caller is not the super-user.
+.It Bq Er EINVAL
+The address given is not page aligned or the length is negative.
+.It Bq Er ENOMEM
+Some portion of the indicated address range is not allocated.
+Some portion of the indicated address range is not locked.
+.El
+.Sh "SEE ALSO"
+.Xr fork 2 ,
+.Xr mincore 2 ,
+.Xr minherit 2 ,
+.Xr mmap 2 ,
+.Xr munmap 2 ,
+.Xr setrlimit 2 ,
+.Xr getpagesize 3
+.Sh BUGS
+Unlike The Sun implementation, multiple
+.Fn mlock
+calls on the same address range require the corresponding number of
+.Fn munlock
+calls to actually unlock the pages, i.e.
+.Fn mlock
+nests.
+This should be considered a consequence of the implementation
+and not a feature.
+.Pp
+The per-process resource limit is a limit on the amount of virtual
+memory locked, while the system-wide limit is for the number of locked
+physical pages.
+Hence a process with two distinct locked mappings of the same physical page
+counts as 2 pages against the per-process limit and as only a single page
+in the system limit.
+
+The per-process resource limit is not currently supported.
+.Sh HISTORY
+The
+.Fn mlock
+and
+.Fn munlock
+functions first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/mmap.2 b/lib/libc/sys/mmap.2
new file mode 100644
index 0000000..e165d32
--- /dev/null
+++ b/lib/libc/sys/mmap.2
@@ -0,0 +1,290 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mmap.2 8.4 (Berkeley) 5/11/95
+.\" $FreeBSD$
+.\"
+.Dd May 11, 1995
+.Dt MMAP 2
+.Os BSD 4
+.Sh NAME
+.Nm mmap
+.Nd map files or devices into memory
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/mman.h>
+.Ft void *
+.Fn mmap "void * addr" "size_t len" "int prot" "int flags" "int fd" "off_t offset"
+.Sh DESCRIPTION
+The
+.Fn mmap
+function causes the pages starting at
+.Fa addr
+and continuing for at most
+.Fa len
+bytes to be mapped from the object described by
+.Fa fd ,
+starting at byte offset
+.Fa offset .
+If
+.Fa len
+is not a multiple of the pagesize, the mapped region may extend past the
+specified range.
+Any such extension beyond the end of the mapped object will be zero-filled.
+.Pp
+If
+.Fa addr
+is non-zero, it is used as a hint to the system.
+(As a convenience to the system, the actual address of the region may differ
+from the address supplied.)
+If
+.Fa addr
+is zero, an address will be selected by the system.
+The actual starting address of the region is returned.
+A successful
+.Fa mmap
+deletes any previous mapping in the allocated address range.
+.Pp
+The protections (region accessibility) are specified in the
+.Fa prot
+argument by
+.Em or Ns 'ing
+the following values:
+.Pp
+.Bl -tag -width MAP_FIXEDX
+.It Dv PROT_EXEC
+Pages may be executed.
+.It Dv PROT_READ
+Pages may be read.
+.It Dv PROT_WRITE
+Pages may be written.
+.El
+.Pp
+The
+.Fa flags
+parameter specifies the type of the mapped object, mapping options and
+whether modifications made to the mapped copy of the page are private
+to the process or are to be shared with other references.
+Sharing, mapping type and options are specified in the
+.Fa flags
+argument by
+.Em or Ns 'ing
+the following values:
+.Pp
+.Bl -tag -width MAP_FIXEDX
+.It Dv MAP_ANON
+Map anonymous memory not associated with any specific file.
+The file descriptor used for creating
+.Dv MAP_ANON
+must be \-1.
+The
+.Fa offset
+parameter is ignored.
+.\".It Dv MAP_FILE
+.\"Mapped from a regular file or character-special device memory.
+.It Dv MAP_FIXED
+Do not permit the system to select a different address than the one
+specified.
+If the specified address cannot be used,
+.Fn mmap
+will fail.
+If MAP_FIXED is specified,
+.Fa addr
+must be a multiple of the pagesize.
+Use of this option is discouraged.
+.It Dv MAP_HASSEMAPHORE
+Notify the kernel that the region may contain semaphores and that special
+handling may be necessary.
+.It Dv MAP_INHERIT
+Permit regions to be inherited across
+.Xr execve 2
+system calls.
+.It Dv MAP_PRIVATE
+Modifications are private.
+.It Dv MAP_SHARED
+Modifications are shared.
+.It Dv MAP_STACK
+This option is only available if your system has been compiled with
+VM_STACK defined when compiling the kernel. This is the default for
+i386 only. Consider adding -DVM_STACK to COPTFLAGS in your /etc/make.conf
+to enable this option for other architechures. MAP_STACK implies
+MAP_ANON, and
+.Fa offset
+of 0.
+.Fa fd
+must be -1 and
+.Fa prot
+must include at least PROT_READ and PROT_WRITE. This option creates
+a memory region that grows to at most
+.Fa len
+bytes in size, starting from the stack top and growing down. The
+stack top is the starting address returned by the call, plus
+.Fa len
+bytes. The bottom of the stack at maximum growth is the starting
+address returned by the call.
+.It Dv MAP_NOSYNC
+Causes data dirtied via this VM map to be flushed to physical media
+only when necessary (usually by the pager) rather then gratuitously.
+Typically this prevents the update daemons from flushing pages dirtied
+through such maps and thus allows efficient sharing of memory across
+unassociated processes using a file-backed shared memory map. Without
+this option any VM pages you dirty may be flushed to disk every so often
+(every 30-60 seconds usually) which can create performance problems if you
+do not need that to occur (such as when you are using shared file-backed
+mmap regions for IPC purposes). Note that VM/filesystem coherency is
+maintained whether you use MAP_NOSYNC or not. This option is not portable
+across UNIX platforms (yet), though some may implement the same behavior
+by default.
+.Pp
+The
+.Xr fsync 2
+function will flush all dirty data and metadata associated with a file,
+including dirty NOSYNC VM data, to physical media. The
+.Xr sync 1
+command and
+.Xr sync 2
+system call generally do not flush dirty NOSYNC VM data.
+The
+.Xr msync 2
+system call is obsolete since
+.Os BSD
+implements a coherent filesystem buffer cache. However, it may be
+used to associate dirty VM pages with filesystem buffers and thus cause
+them to be flushed to physical media sooner rather then later.
+.El
+.Pp
+The
+.Xr close 2
+function does not unmap pages, see
+.Xr munmap 2
+for further information.
+.Pp
+The current design does not allow a process to specify the location of
+swap space.
+In the future we may define an additional mapping type,
+.Dv MAP_SWAP ,
+in which
+the file descriptor argument specifies a file or device to which swapping
+should be done.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn mmap
+returns a pointer to the mapped region.
+Otherwise, a value of MAP_FAILED is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Mmap
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EACCES
+The flag
+.Dv PROT_READ
+was specified as part of the
+.Fa prot
+parameter and
+.Fa fd
+was not open for reading.
+The flags
+.Dv MAP_SHARED
+and
+.Dv PROT_WRITE
+were specified as part of the
+.Fa flags
+and
+.Fa prot
+parameters and
+.Fa fd
+was not open for writing.
+.It Bq Er EBADF
+.Fa Fd
+is not a valid open file descriptor.
+.It Bq Er EINVAL
+.Dv MAP_FIXED
+was specified and the
+.Fa addr
+parameter was not page aligned, or part of the desired address space
+resides out of the valid address space for a user process.
+.It Bq Er EINVAL
+.Fa Len
+was negative.
+.It Bq Er EINVAL
+.Dv MAP_ANON
+was specified and the
+.Fa fd
+parameter was not -1.
+.It Bq Er EINVAL
+.Dv MAP_ANON
+has not been specified and
+.Fa fd
+did not reference a regular or character special file.
+.It Bq Er EINVAL
+.Fa Offset
+was not page-aligned. (See BUGS below.)
+.It Bq Er ENOMEM
+.Dv MAP_FIXED
+was specified and the
+.Fa addr
+parameter wasn't available.
+.Dv MAP_ANON
+was specified and insufficient memory was available.
+.Sh "SEE ALSO"
+.Xr madvise 2 ,
+.Xr mincore 2 ,
+.Xr mlock 2 ,
+.Xr mprotect 2 ,
+.Xr msync 2 ,
+.Xr munlock 2 ,
+.Xr munmap 2 ,
+.Xr getpagesize 3
+.Sh BUGS
+.Ar len
+is limited to 2GB. Mmapping slightly more than 2GB doesn't work, but
+it is possible to map a window of size (filesize % 2GB) for file sizes
+of slightly less than 2G, 4GB, 6GB and 8GB.
+.Pp
+The limit is imposed for a variety of reasons. Most of them have to do
+with
+.Tn FreeBSD
+not wanting to use 64 bit offsets in the VM system due to
+the extreme performance penalty. So
+.Tn FreeBSD
+uses 32bit page indexes and
+this gives
+.Tn FreeBSD
+a maximum of 8TB filesizes. It's actually bugs in
+the filesystem code that causes the limit to be further restricted to
+1TB (loss of precision when doing blockno calculations).
+.Pp
+Another reason for the 2GB limit is that filesystem metadata can
+reside at negative offsets.
+.Pp
+We currently can only deal with page aligned file offsets.
diff --git a/lib/libc/sys/mmap.c b/lib/libc/sys/mmap.c
new file mode 100644
index 0000000..32aeffb
--- /dev/null
+++ b/lib/libc/sys/mmap.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)mmap.c 8.1 (Berkeley) 6/17/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+/*
+ * This function provides 64-bit offset padding that
+ * is not supplied by GCC 1.X but is supplied by GCC 2.X.
+ */
+void *
+mmap(addr, len, prot, flags, fd, offset)
+ void * addr;
+ size_t len;
+ int prot;
+ int flags;
+ int fd;
+ off_t offset;
+{
+
+ return((void *)(long)__syscall((quad_t)SYS_mmap, addr, len, prot, flags,
+ fd, 0, offset));
+}
diff --git a/lib/libc/sys/mount.2 b/lib/libc/sys/mount.2
new file mode 100644
index 0000000..d4959ed
--- /dev/null
+++ b/lib/libc/sys/mount.2
@@ -0,0 +1,324 @@
+.\" Copyright (c) 1980, 1989, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mount.2 8.3 (Berkeley) 5/24/95
+.\" $FreeBSD$
+.\"
+.Dd May 24, 1995
+.Dt MOUNT 2
+.Os BSD 4
+.Sh NAME
+.Nm mount ,
+.Nm unmount
+.Nd mount or dismount a filesystem
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/mount.h>
+.Ft int
+.Fn mount "const char *type" "const char *dir" "int flags" "void *data"
+.Ft int
+.Fn unmount "const char *dir" "int flags"
+.Sh DESCRIPTION
+The
+.Fn mount
+function grafts
+a filesystem object onto the system file tree
+at the point
+.Ar dir .
+The argument
+.Ar data
+describes the filesystem object to be mounted.
+The argument
+.Ar type
+tells the kernel how to interpret
+.Ar data
+(See
+.Ar type
+below).
+The contents of the filesystem
+become available through the new mount point
+.Ar dir .
+Any files in
+.Ar dir
+at the time
+of a successful mount are swept under the carpet so to speak, and
+are unavailable until the filesystem is unmounted.
+.Pp
+The following
+.Ar flags
+may be specified to
+suppress default semantics which affect filesystem access.
+.Bl -tag -width MNT_SYNCHRONOUS
+.It Dv MNT_RDONLY
+The filesystem should be treated as read-only;
+Even the super-user may not write on it.
+Specifying MNT_UPDATE without this option will upgrade
+a read-only filesystem to read/write.
+.It Dv MNT_NOEXEC
+Do not allow files to be executed from the filesystem.
+.It Dv MNT_NOSUID
+Do not honor setuid or setgid bits on files when executing them.
+.It Dv MNT_NOATIME
+Disable update of file access times.
+.It Dv MNT_NODEV
+Do not interpret special files on the filesystem.
+.It Dv MNT_SUIDDIR
+Directories with the SUID bit set chown new files to their own owner.
+.It Dv MNT_SYNCHRONOUS
+All I/O to the filesystem should be done synchronously.
+.It Dv MNT_ASYNC
+All I/O to the filesystem should be done asynchronously.
+.It Dv MNT_FORCE
+Force a read-write mount even if the filesystem appears to be unclean.
+Dangerous.
+.It Dv MNT_NOCLUSTERR
+Disable read clustering.
+.It Dv MNT_NOCLUSTERW
+Disable write clustering.
+.El
+.Pp
+The flag
+.Dv MNT_UPDATE
+indicates that the mount command is being applied
+to an already mounted filesystem.
+This allows the mount flags to be changed without requiring
+that the filesystem be unmounted and remounted.
+Some filesystems may not allow all flags to be changed.
+For example,
+many filesystems will not allow a change from read-write to read-only.
+.Pp
+The flag
+.Dv MNT_RELOAD
+causes the vfs subsystem to update its data structures pertaining to
+the specified already mounted filesystem.
+.Pp
+The
+.Fa type
+argument names the filesystem.
+The types of filesystems known to the system can be obtained with
+.Xr lsvfs 1 .
+.Pp
+.Fa Data
+is a pointer to a structure that contains the type
+specific arguments to mount.
+The format for these argument structures is described in the
+manual page for each filesystem.
+By convention filesystem manual pages are named
+by prefixing ``mount_'' to the name of the filesystem as returned by
+.Xr lsvfs 1 .
+Thus the
+.Nm NFS
+filesystem is described by the
+.Xr mount_nfs 8
+manual page.
+.Pp
+The
+.Fn unmount
+function call disassociates the filesystem from the specified
+mount point
+.Fa dir .
+.Pp
+The
+.Fa flags
+argument may specify
+.Dv MNT_FORCE
+to specify that the filesystem should be forcibly unmounted or made read-only
+(if MNT_UPDATE and MNT_RDONLY are also specified)
+even if files are still active.
+Active special devices continue to work,
+but any further accesses to any other active files result in errors
+even if the filesystem is later remounted.
+.Pp
+The
+.Dv MNT_SUIDDIR
+option requires the SUIDDIR option to have been compiled into the kernel
+to have any effect.
+See the
+.Xr mount 8
+and
+.Xr chmod 2
+pages for more information.
+.Sh RETURN VALUES
+The
+.Fn mount
+returns the value 0 if the mount was successful, otherwise -1 is returned
+and the variable
+.Va errno
+is set to indicate the error.
+.Pp
+The
+.Fn unmount
+function returns the value 0 if the umount succeeded; otherwise -1 is returned
+and the variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn mount
+function will fail when one of the following occurs:
+.Bl -tag -width [ENOTBLK]
+.It Bq Er EPERM
+The caller is not the super-user.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or the entire length of a path name exceeded 1023 characters.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating a pathname.
+.It Bq Er ENOENT
+A component of
+.Fa dir
+does not exist.
+.It Bq Er ENOTDIR
+A component of
+.Ar name
+is not a directory,
+or a path prefix of
+.Ar special
+is not a directory.
+.It Bq Er EBUSY
+Another process currently holds a reference to
+.Fa dir .
+.It Bq Er EFAULT
+.Fa Dir
+points outside the process's allocated address space.
+.El
+.Pp
+The following errors can occur for a
+.Em ufs
+filesystem mount:
+.Bl -tag -width [ENOTBLK]
+.It Bq Er ENODEV
+A component of ufs_args
+.Ar fspec
+does not exist.
+.It Bq Er ENOTBLK
+.Ar Fspec
+is not a block device.
+.It Bq Er ENXIO
+The major device number of
+.Ar fspec
+is out of range (this indicates no device driver exists
+for the associated hardware).
+.It Bq Er EBUSY
+.Ar Fspec
+is already mounted.
+.It Bq Er EMFILE
+No space remains in the mount table.
+.It Bq Er EINVAL
+The super block for the filesystem had a bad magic
+number or an out of range block size.
+.It Bq Er ENOMEM
+Not enough memory was available to read the cylinder
+group information for the filesystem.
+.It Bq Er EIO
+An I/O error occurred while reading the super block or
+cylinder group information.
+.It Bq Er EFAULT
+.Ar Fspec
+points outside the process's allocated address space.
+.El
+.Pp
+The following errors can occur for a
+.Em nfs
+filesystem mount:
+.Bl -tag -width [ENOTBLK]
+.It Bq Er ETIMEDOUT
+.Em Nfs
+timed out trying to contact the server.
+.It Bq Er EFAULT
+Some part of the information described by nfs_args
+points outside the process's allocated address space.
+.El
+.Pp
+The following errors can occur for a
+.Em mfs
+filesystem mount:
+.Bl -tag -width [ENOTBLK]
+.It Bq Er EMFILE
+No space remains in the mount table.
+.It Bq Er EINVAL
+The super block for the filesystem had a bad magic
+number or an out of range block size.
+.It Bq Er ENOMEM
+Not enough memory was available to read the cylinder
+group information for the filesystem.
+.It Bq Er EIO
+A paging error occurred while reading the super block or
+cylinder group information.
+.It Bq Er EFAULT
+.Em Name
+points outside the process's allocated address space.
+.El
+.Pp
+The
+.Fn unmount
+function may fail with one of the following errors:
+.Bl -tag -width [ENOTBLK]
+.It Bq Er EPERM
+The caller is not the super-user.
+.It Bq Er ENOTDIR
+A component of the path is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EINVAL
+The requested directory is not in the mount table.
+.It Bq Er EBUSY
+A process is holding a reference to a file located
+on the filesystem.
+.It Bq Er EIO
+An I/O error occurred while writing cached filesystem information.
+.It Bq Er EFAULT
+.Fa Dir
+points outside the process's allocated address space.
+.El
+.Pp
+A
+.Em ufs
+or
+.Em mfs
+mount can also fail if the maximum number of filesystems are currently
+mounted.
+.Sh SEE ALSO
+.Xr lsvfs 1 ,
+.Xr mfs 8 ,
+.Xr mount 8 ,
+.Xr umount 8
+.Sh BUGS
+Some of the error codes need translation to more obvious messages.
+.Sh HISTORY
+.Fn Mount
+and
+.Fn unmount
+function calls appeared in
+.At v6 .
diff --git a/lib/libc/sys/mprotect.2 b/lib/libc/sys/mprotect.2
new file mode 100644
index 0000000..533b1fe
--- /dev/null
+++ b/lib/libc/sys/mprotect.2
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mprotect.2 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt MPROTECT 2
+.Os
+.Sh NAME
+.Nm mprotect
+.Nd control the protection of pages
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/mman.h>
+.Ft int
+.Fn mprotect "const void *addr" "size_t len" "int prot"
+.Sh DESCRIPTION
+The
+.Fn mprotect
+system call
+changes the specified pages to have protection
+.Fa prot .
+Not all implementations will guarantee protection on a page basis;
+the granularity of protection changes may be as large as an entire region.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn mprotect
+returns 0. Otherwise a value of -1 is returned
+and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn mprotect
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The virtual address range specified by the
+.Fa addr
+and
+.Fa len
+arguments is not valid.
+.It Bq Er EACCES
+The calling process was not allowed to change
+the protection to the value specified by
+the
+.Fa prot
+argument.
+.El
+.Sh SEE ALSO
+.Xr madvise 2 ,
+.Xr mincore 2 ,
+.Xr msync 2 ,
+.Xr munmap 2
+.Sh HISTORY
+The
+.Fn mprotect
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/msync.2 b/lib/libc/sys/msync.2
new file mode 100644
index 0000000..7a86cd4
--- /dev/null
+++ b/lib/libc/sys/msync.2
@@ -0,0 +1,99 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)msync.2 8.2 (Berkeley) 6/21/94
+.\" $FreeBSD$
+.\"
+.Dd June 21, 1994
+.Dt MSYNC 2
+.Os
+.Sh NAME
+.Nm msync
+.Nd synchronize a mapped region
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/mman.h>
+.Ft int
+.Fn msync "void *addr" "size_t len" "int flags"
+.Sh DESCRIPTION
+The
+.Fn msync
+system call
+writes any modified pages back to the filesystem and updates
+the file modification time.
+If
+.Fa len
+is 0, all modified pages within the region containing
+.Fa addr
+will be flushed;
+if
+.Fa len
+is non-zero, only those pages containing
+.Fa addr
+and
+.Fa len-1
+succeeding locations will be examined.
+The
+.Fa flags
+argument may be specified as follows:
+.Bd -literal
+MS_ASYNC Return immediately (not currently implemented)
+MS_SYNC Perform synchronous writes
+MS_INVALIDATE Invalidate all cached data
+.Ed
+.Sh RETURN VALUES
+If any errors occur, -1 is returned and errno is set to indicate the
+error. Otherwise, a 0 value is returned.
+.Sh ERRORS
+.Fn msync
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+.Fa addr
+is not a multiple of the hardware page size.
+.It Bq Er EINVAL
+.Fa len
+is too large or negative.
+.It Bq Er EINVAL
+.Fa flags
+was both MS_ASYNC and MS_INVALIDATE. Only one of these flags is allowed.
+.It Bq Er EIO
+An I/O error occurred while writing to the file system.
+.Sh SEE ALSO
+.Xr madvise 2 ,
+.Xr mincore 2 ,
+.Xr mprotect 2 ,
+.Xr munmap 2
+.Sh HISTORY
+The
+.Fn msync
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/munmap.2 b/lib/libc/sys/munmap.2
new file mode 100644
index 0000000..e2c89bf
--- /dev/null
+++ b/lib/libc/sys/munmap.2
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)munmap.2 8.3 (Berkeley) 5/27/94
+.\" $FreeBSD$
+.\"
+.Dd May 27, 1994
+.Dt MUNMAP 2
+.Os
+.Sh NAME
+.Nm munmap
+.Nd remove a mapping
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/mman.h>
+.Ft int
+.Fn munmap "void *addr" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn munmap
+system call
+deletes the mappings for the specified address range,
+and causes further references to addresses within the range
+to generate invalid memory references.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn munmap
+returns zero.
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Munmap
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa addr
+parameter was not page aligned, the
+.Fa len
+parameter was negative, or
+some part of the region being unmapped is outside the
+valid address range for a process.
+.Sh "SEE ALSO"
+.Xr madvise 2 ,
+.Xr mincore 2 ,
+.Xr mprotect 2 ,
+.Xr msync 2 ,
+.Xr munmap 2 ,
+.Xr getpagesize 3
+.Sh HISTORY
+The
+.Fn munmap
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/nanosleep.2 b/lib/libc/sys/nanosleep.2
new file mode 100644
index 0000000..fe39fd7
--- /dev/null
+++ b/lib/libc/sys/nanosleep.2
@@ -0,0 +1,104 @@
+.\" $FreeBSD$
+.\" $OpenBSD: nanosleep.2,v 1.1 1997/04/20 20:56:20 tholo Exp $
+.\" $NetBSD: nanosleep.2,v 1.1 1997/04/17 18:12:02 jtc Exp $
+.\"
+.\" Copyright (c) 1986, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sleep.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd April 17, 1997
+.Dt NANOSLEEP 2
+.Os
+.Sh NAME
+.Nm nanosleep
+.Nd suspend process execution for an interval measured in nanoseconds
+.Sh SYNOPSIS
+.Fd #include <time.h>
+.Ft int
+.Fn nanosleep "const struct timespec *rqtp" "struct timespec *rmtp"
+.Sh DESCRIPTION
+.Fn Nanosleep
+causes the process to sleep for the specified time. An unmasked signal will
+cause it to terminate the sleep early, regardless of the
+.Dv SA_RESTART
+value on the interrupting signal.
+.Sh RETURN VALUES
+If the
+.Fn nanosleep
+function returns because the requested time has elapsed, the value
+returned will be zero.
+.Pp
+If the
+.Fn nanosleep
+function returns due to the delivery of a signal, the value returned
+will be the -1, and the global variable
+.Va errno
+will be set to indicate the interruption.
+If
+.Fa rmtp
+is
+.Pf non- Dv NULL ,
+the timespec structure it references is updated to contain the
+unslept amount (the request time minus the time actually slept).
+.Pp
+If any of the following conditions occur, the
+.Fn nanosleep
+function shall return -1 and set
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+Either
+.Fa rqtp
+or
+.Fa rmtp
+points to memory that is not a valid part of the process
+address space.
+.It Bq Er EINTR
+.Fn nanosleep
+was interrupted by the delivery of a signal.
+.It Bq Er EINVAL
+.Fa rqtp
+specified a nanosecond value less than zero
+or greater than or equal to 1000 million.
+.It Bq Er ENOSYS
+.Fn nanosleep
+is not supported by this implementation.
+.El
+.Sh SEE ALSO
+.Xr sigsuspend 2 ,
+.Xr sleep 3
+.Sh STANDARDS
+The
+.Fn nanosleep
+function conforms to
+.St -p1003.1b-93 .
diff --git a/lib/libc/sys/nfssvc.2 b/lib/libc/sys/nfssvc.2
new file mode 100644
index 0000000..5d0eb3b
--- /dev/null
+++ b/lib/libc/sys/nfssvc.2
@@ -0,0 +1,252 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)nfssvc.2 8.1 (Berkeley) 6/9/93
+.\" $FreeBSD$
+.\"
+.Dd June 9, 1993
+.Dt NFSSVC 2
+.Os
+.Sh NAME
+.Nm nfssvc
+.Nd NFS services
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/mount.h>
+.Fd #include <sys/time.h>
+.Fd #include <nfs/rpcv2.h>
+.Fd #include <nfs/nfs.h>
+.Fd #include <unistd.h>
+.Ft int
+.Fn nfssvc "int flags" "void *argstructp"
+.Sh DESCRIPTION
+The
+.Fn nfssvc
+function is used by the NFS daemons to pass information into and out
+of the kernel and also to enter the kernel as a server daemon.
+The
+.Fa flags
+argument consists of several bits that show what action is to be taken
+once in the kernel and the
+.Fa argstructp
+points to one of three structures depending on which bits are set in
+flags.
+.Pp
+On the client side,
+.Xr nfsiod 8
+calls
+.Fn nfssvc
+with the
+.Fa flags
+argument set to
+.Dv NFSSVC_BIOD
+and
+.Fa argstructp
+set to
+.Dv NULL
+to enter the kernel as a block I/O server daemon.
+For
+.Nm NQNFS ,
+.Xr mount_nfs 8
+calls
+.Fn nfssvc
+with the
+.Dv NFSSVC_MNTD
+flag, optionally or'd with the flags
+.Dv NFSSVC_GOTAUTH
+and
+.Dv NFSSVC_AUTHINFAIL
+along with a pointer to a
+.Bd -literal
+struct nfsd_cargs {
+ char *ncd_dirp; /* Mount dir path */
+ uid_t ncd_authuid; /* Effective uid */
+ int ncd_authtype; /* Type of authenticator */
+ int ncd_authlen; /* Length of authenticator string */
+ u_char *ncd_authstr; /* Authenticator string */
+ int ncd_verflen; /* and the verifier */
+ u_char *ncd_verfstr;
+ NFSKERBKEY_T ncd_key; /* Session key */
+};
+.Ed
+.Pp
+structure.
+The initial call has only the
+.Dv NFSSVC_MNTD
+flag set to specify service for the mount point.
+If the mount point is using Kerberos, then the
+.Xr mount_nfs 8
+daemon will return from
+.Fn nfssvc
+with errno == ENEEDAUTH whenever the client side requires an ``rcmd''
+authentication ticket for the user.
+.Xr Mount_nfs 8
+will attempt to get the Kerberos ticket, and if successful will call
+.Fn nfssvc
+with the flags
+.Dv NFSSVC_MNTD
+and
+.Dv NFSSVC_GOTAUTH
+after filling the ticket into the
+ncd_authstr field
+and
+setting the ncd_authlen and ncd_authtype
+fields of the nfsd_cargs structure.
+If
+.Xr mount_nfs 8
+failed to get the ticket,
+.Fn nfssvc
+will be called with the flags
+.Dv NFSSVC_MNTD ,
+.Dv NFSSVC_GOTAUTH
+and
+.Dv NFSSVC_AUTHINFAIL
+to denote a failed authentication attempt.
+.Pp
+On the server side,
+.Fn nfssvc
+is called with the flag
+.Dv NFSSVC_NFSD
+and a pointer to a
+.Bd -literal
+struct nfsd_srvargs {
+ struct nfsd *nsd_nfsd; /* Pointer to in kernel nfsd struct */
+ uid_t nsd_uid; /* Effective uid mapped to cred */
+ u_long nsd_haddr; /* Ip address of client */
+ struct ucred nsd_cr; /* Cred. uid maps to */
+ int nsd_authlen; /* Length of auth string (ret) */
+ u_char *nsd_authstr; /* Auth string (ret) */
+ int nsd_verflen; /* and the verfier */
+ u_char *nsd_verfstr;
+ struct timeval nsd_timestamp; /* timestamp from verifier */
+ u_long nsd_ttl; /* credential ttl (sec) */
+ NFSKERBKEY_T nsd_key; /* Session key */
+};
+.Ed
+.Pp
+to enter the kernel as an
+.Xr nfsd 8
+daemon.
+Whenever an
+.Xr nfsd 8
+daemon receives a Kerberos authentication ticket, it will return from
+.Fn nfssvc
+with errno == ENEEDAUTH.
+The
+.Xr nfsd 8
+will attempt to authenticate the ticket and generate a set of credentials
+on the server for the ``user id'' specified in the field nsd_uid.
+This is done by first authenticating the Kerberos ticket and then mapping
+the Kerberos principal to a local name and getting a set of credentials for
+that user via.
+.Xr getpwnam 3
+and
+.Xr getgrouplist 3 .
+If successful, the
+.Xr nfsd 8
+will call
+.Fn nfssvc
+with the
+.Dv NFSSVC_NFSD
+and
+.Dv NFSSVC_AUTHIN
+flags set to pass the credential mapping in nsd_cr into the
+kernel to be cached on the server socket for that client.
+If the authentication failed,
+.Xr nfsd 8
+calls
+.Fn nfssvc
+with the flags
+.Dv NFSSVC_NFSD
+and
+.Dv NFSSVC_AUTHINFAIL
+to denote an authentication failure.
+.Pp
+The master
+.Xr nfsd 8
+server daemon calls
+.Fn nfssvc
+with the flag
+.Dv NFSSVC_ADDSOCK
+and a pointer to a
+.Bd -literal
+struct nfsd_args {
+ int sock; /* Socket to serve */
+ caddr_t name; /* Client address for connection based sockets */
+ int namelen;/* Length of name */
+};
+.Ed
+.Pp
+to pass a server side
+.Tn NFS
+socket into the kernel for servicing by the
+.Xr nfsd 8
+daemons.
+.Sh RETURN VALUES
+Normally
+.Fn nfssvc
+does not return unless the server
+is terminated by a signal when a value of 0 is returned.
+Otherwise, -1 is returned and the global variable
+.Va errno
+is set to specify the error.
+.Sh ERRORS
+.Bl -tag -width [ENEEDAUTH]
+.It Bq Er ENEEDAUTH
+This special error value
+is really used for authentication support, particularly Kerberos,
+as explained above.
+.It Bq Er EPERM
+The caller is not the super-user.
+.El
+.Sh SEE ALSO
+.Xr mount_nfs 8 ,
+.Xr nfsd 8 ,
+.Xr nfsiod 8
+.Sh HISTORY
+The
+.Fn nfssvc
+function first appeared in
+.Bx 4.4 .
+.Sh BUGS
+The
+.Fn nfssvc
+system call is designed specifically for the
+.Tn NFS
+support daemons and as such is specific to their requirements.
+It should really return values to indicate the need for authentication
+support, since
+.Dv ENEEDAUTH
+is not really an error.
+Several fields of the argument structures are assumed to be valid and
+sometimes to be unchanged from a previous call, such that
+.Fn nfssvc
+must be used with extreme care.
diff --git a/lib/libc/sys/open.2 b/lib/libc/sys/open.2
new file mode 100644
index 0000000..2a91040
--- /dev/null
+++ b/lib/libc/sys/open.2
@@ -0,0 +1,301 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)open.2 8.2 (Berkeley) 11/16/93
+.\" $FreeBSD$
+.\"
+.Dd November 16, 1993
+.Dt OPEN 2
+.Os BSD 4
+.Sh NAME
+.Nm open
+.Nd open or create a file for reading or writing
+.Sh SYNOPSIS
+.Fd #include <fcntl.h>
+.Ft int
+.Fn open "const char *path" "int flags" "..."
+.Sh DESCRIPTION
+The file name specified by
+.Fa path
+is opened
+for reading and/or writing as specified by the
+argument
+.Fa flags
+and the file descriptor returned to the calling process.
+The
+.Fa flags
+argument may indicate the file is to be
+created if it does not exist (by specifying the
+.Dv O_CREAT
+flag). In this case
+.Nm
+requires a third argument
+.Fa "mode_t mode" ,
+and the file is created with mode
+.Fa mode
+as described in
+.Xr chmod 2
+and modified by the process' umask value (see
+.Xr umask 2 ) .
+.Pp
+The flags specified are formed by
+.Em or Ns 'ing
+the following values
+.Pp
+.Bd -literal -offset indent -compact
+O_RDONLY open for reading only
+O_WRONLY open for writing only
+O_RDWR open for reading and writing
+O_NONBLOCK do not block on open
+O_APPEND append on each write
+O_CREAT create file if it does not exist
+O_TRUNC truncate size to 0
+O_EXCL error if create and file exists
+O_SHLOCK atomically obtain a shared lock
+O_EXLOCK atomically obtain an exclusive lock
+.Ed
+.Pp
+Opening a file with
+.Dv O_APPEND
+set causes each write on the file
+to be appended to the end. If
+.Dv O_TRUNC
+is specified and the
+file exists, the file is truncated to zero length.
+If
+.Dv O_EXCL
+is set with
+.Dv O_CREAT
+and the file already
+exists,
+.Fn open
+returns an error. This may be used to
+implement a simple exclusive access locking mechanism.
+If
+.Dv O_EXCL
+is set and the last component of the pathname is
+a symbolic link,
+.Fn open
+will fail even if the symbolic
+link points to a non-existent name.
+If the
+.Dv O_NONBLOCK
+flag is specified and the
+.Fn open
+call would result
+in the process being blocked for some reason (e.g., waiting for
+carrier on a dialup line),
+.Fn open
+returns immediately.
+The first time the process attempts to perform I/O on the open
+file it will block (not currently implemented).
+.Pp
+When opening a file, a lock with
+.Xr flock 2
+semantics can be obtained by setting
+.Dv O_SHLOCK
+for a shared lock, or
+.Dv O_EXLOCK
+for an exclusive lock.
+If creating a file with
+.Dv O_CREAT ,
+the request for the lock will never fail
+(provided that the underlying filesystem supports locking).
+.Pp
+If successful,
+.Fn open
+returns a non-negative integer, termed a file descriptor.
+It returns -1 on failure.
+The file pointer used to mark the current position within the
+file is set to the beginning of the file.
+.Pp
+When a new file is created it is given the group of the directory
+which contains it.
+.Pp
+The new descriptor is set to remain open across
+.Xr execve 2
+system calls; see
+.Xr close 2
+and
+.Xr fcntl 2 .
+.Pp
+The system imposes a limit on the number of file descriptors
+open simultaneously by one process.
+.Xr Getdtablesize 2
+returns the current system limit.
+.Pp
+.Sh IMPLEMENTATION NOTES
+In the non-threaded library
+.Fn open
+is implemented as the
+.Va open
+syscall.
+.Pp
+In the threaded library, the
+.Va open
+syscall is assembled to
+.Fn _thread_sys_open
+and
+.Fn open
+is implemented as a function which disables thread rescheduling
+and calls
+.Fn _thread_sys_open .
+Before returning,
+.Fn open
+enables thread rescheduling.
+.Sh RETURN VALUES
+If successful,
+.Fn open
+returns a non-negative integer, termed a file descriptor.
+It returns -1 on failure, and sets
+.Va errno
+to indicate the error.
+.Sh ERRORS
+The named file is opened unless:
+.Bl -tag -width Er
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+.Dv O_CREAT
+is not set and the named file does not exist.
+.It Bq Er ENOENT
+A component of the path name that must exist does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er EACCES
+The required permissions (for reading and/or writing)
+are denied for the given flags.
+.It Bq Er EACCES
+.Dv O_CREAT
+is specified,
+the file does not exist,
+and the directory in which it is to be created
+does not permit writing.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EISDIR
+The named file is a directory, and the arguments specify
+it is to be opened for writing.
+.It Bq Er EROFS
+The named file resides on a read-only file system,
+and the file is to be modified.
+.It Bq Er EMFILE
+The process has already reached its limit for open file descriptors.
+.It Bq Er ENFILE
+The system file table is full.
+.It Bq Er ENXIO
+The named file is a character special or block
+special file, and the device associated with this special file
+does not exist.
+.It Bq Er ENXIO
+The named file is a fifo, no process has
+it open for reading, and the arguments specify it is
+to be opened for writing.
+.It Bq Er EINTR
+The
+.Fn open
+operation was interrupted by a signal.
+.It Bq Er EOPNOTSUPP
+.Dv O_SHLOCK
+or
+.Dv O_EXLOCK
+is specified but the underlying filesystem does not support locking.
+.It Bq Er ENOSPC
+.Dv O_CREAT
+is specified,
+the file does not exist,
+and the directory in which the entry for the new file is being placed
+cannot be extended because there is no space left on the file
+system containing the directory.
+.It Bq Er ENOSPC
+.Dv O_CREAT
+is specified,
+the file does not exist,
+and there are no free inodes on the file system on which the
+file is being created.
+.It Bq Er EDQUOT
+.Dv O_CREAT
+is specified,
+the file does not exist,
+and the directory in which the entry for the new file
+is being placed cannot be extended because the
+user's quota of disk blocks on the file system
+containing the directory has been exhausted.
+.It Bq Er EDQUOT
+.Dv O_CREAT
+is specified,
+the file does not exist,
+and the user's quota of inodes on the file system on
+which the file is being created has been exhausted.
+.It Bq Er EIO
+An I/O error occurred while making the directory entry or
+allocating the inode for
+.Dv O_CREAT .
+.It Bq Er ETXTBSY
+The file is a pure procedure (shared text) file that is being
+executed and the
+.Fn open
+call requests write access.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.It Bq Er EEXIST
+.Dv O_CREAT
+and
+.Dv O_EXCL
+were specified and the file exists.
+.It Bq Er EOPNOTSUPP
+An attempt was made to open a socket (not currently implemented).
+.It Bq Er EINVAL
+An attempt was made to open a descriptor with an illegal combination
+of
+.Dv O_RDONLY ,
+.Dv O_WRONLY ,
+and
+.Dv O_RDWR .
+.El
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr close 2 ,
+.Xr dup 2 ,
+.Xr getdtablesize 2 ,
+.Xr lseek 2 ,
+.Xr read 2 ,
+.Xr umask 2 ,
+.Xr write 2
+.Sh HISTORY
+An
+.Fn open
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/pathconf.2 b/lib/libc/sys/pathconf.2
new file mode 100644
index 0000000..8631648
--- /dev/null
+++ b/lib/libc/sys/pathconf.2
@@ -0,0 +1,165 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)pathconf.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt PATHCONF 2
+.Os BSD 4
+.Sh NAME
+.Nm pathconf ,
+.Nm fpathconf
+.Nd get configurable pathname variables
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft long
+.Fn pathconf "const char *path" "int name"
+.Ft long
+.Fn fpathconf "int fd" "int name"
+.Sh DESCRIPTION
+.Pp
+The
+.Fn pathconf
+and
+.Fn fpathconf
+functions provides a method for applications to determine the current
+value of a configurable system limit or option variable associated
+with a pathname or file descriptor.
+.Pp
+For
+.Fn pathconf ,
+the
+.Fa path
+argument is the name of a file or directory.
+For
+.Fn fpathconf ,
+the
+.Fa fd
+argument is an open file descriptor.
+The
+.Fa name
+argument specifies the system variable to be queried.
+Symbolic constants for each name value are found in the include file
+.Li <unistd.h> .
+.Pp
+The available values are as follows:
+.Pp
+.Bl -tag -width "123456"
+.Pp
+.It Li _PC_LINK_MAX
+The maximum file link count.
+.It Li _PC_MAX_CANON
+The maximum number of bytes in terminal canonical input line.
+.It Li _PC_MAX_INPUT
+The minimum maximum number of bytes for which space is available in
+a terminal input queue.
+.It Li _PC_NAME_MAX
+The maximum number of bytes in a file name.
+.It Li _PC_PATH_MAX
+The maximum number of bytes in a pathname.
+.It Li _PC_PIPE_BUF
+The maximum number of bytes which will be written atomically to a pipe.
+.It Li _PC_CHOWN_RESTRICTED
+Return 1 if appropriate privileges are required for the
+.Xr chown 2
+system call, otherwise 0.
+.It Li _PC_NO_TRUNC
+Return 1 if file names longer than KERN_NAME_MAX are truncated.
+.It Li _PC_VDISABLE
+Returns the terminal character disabling value.
+.El
+.Sh RETURN VALUES
+If the call to
+.Fn pathconf
+or
+.Fn fpathconf
+is not successful, \-1 is returned and
+.Va errno
+is set appropriately.
+Otherwise, if the variable is associated with functionality that does
+not have a limit in the system, \-1 is returned and
+.Va errno
+is not modified.
+Otherwise, the current variable value is returned.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn pathconf
+and
+.Fn fpathconf
+functions shall return -1 and set
+.Va errno
+to the corresponding value.
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value of the
+.Fa name
+argument is invalid.
+.It Bq Er EINVAL
+The implementation does not support an association of the variable
+name with the associated file.
+.El
+.Fn Pathconf
+will fail if:
+.Bl -tag -width ENAMETOOLONGAA
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named file does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.El
+.Pp
+.Bl -tag -width [EFAULT]
+.Fn Fpathconf
+will fail if:
+.It Bq Er EBADF
+.Fa fd
+is not a valid open file descriptor.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.El
+.Sh SEE ALSO
+.Xr sysctl 3
+.Sh HISTORY
+The
+.Fn pathconf
+and
+.Fn fpathconf
+functions first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/pipe.2 b/lib/libc/sys/pipe.2
new file mode 100644
index 0000000..1151505
--- /dev/null
+++ b/lib/libc/sys/pipe.2
@@ -0,0 +1,122 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)pipe.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt PIPE 2
+.Os BSD 4
+.Sh NAME
+.Nm pipe
+.Nd create descriptor pair for interprocess communication
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn pipe "int *fildes"
+.Sh DESCRIPTION
+The
+.Fn pipe
+function
+creates a
+.Em pipe ,
+which is an object allowing
+bidirectional data flow,
+and allocates a pair of file descriptors.
+.Pp
+By convention, the first descriptor is normally used as the
+.Em read end
+of the pipe,
+and the second is normally the
+.Em write end ,
+so that data written to
+.Fa fildes[1]
+appears on (i.e., can be read from)
+.Fa fildes[0] .
+This allows the output of one program to be
+sent
+to another program:
+the source's standard output is set up to be
+the write end of the pipe,
+and the sink's standard input is set up to be
+the read end of the pipe.
+The pipe itself persists until all its associated descriptors are
+closed.
+.Pp
+A pipe that has had an end closed is considered
+.Em widowed .
+Writing on such a pipe causes the writing process to receive
+a
+.Dv SIGPIPE
+signal.
+Widowing a pipe is the only way to deliver end-of-file to a reader:
+after the reader consumes any buffered data, reading a widowed pipe
+returns a zero count.
+.Pp
+The bidirectional nature of this implementation of pipes is not
+portable to older systems, so it is recommended to use the convention
+for using the endpoints in the traditional manner when using a
+pipe in one direction.
+.Sh RETURN VALUES
+On successful creation of the pipe, zero is returned. Otherwise,
+a value of -1 is returned and the variable
+.Va errno
+set to indicate the
+error.
+.Sh ERRORS
+The
+.Fn pipe
+call will fail if:
+.Bl -tag -width [EMFILE]
+.It Bq Er EMFILE
+Too many descriptors are active.
+.It Bq Er ENFILE
+The system file table is full.
+.It Bq Er EFAULT
+The
+.Fa fildes
+buffer is in an invalid area of the process's address
+space.
+.El
+.Sh SEE ALSO
+.Xr sh 1 ,
+.Xr fork 2 ,
+.Xr read 2 ,
+.Xr socketpair 2 ,
+.Xr write 2
+.Sh HISTORY
+A
+.Fn pipe
+function call appeared in
+.At v3 .
+.Pp
+Bidirectional pipes were first used on
+.At V.4 .
diff --git a/lib/libc/sys/poll.2 b/lib/libc/sys/poll.2
new file mode 100644
index 0000000..ea5b270
--- /dev/null
+++ b/lib/libc/sys/poll.2
@@ -0,0 +1,190 @@
+.\" $NetBSD: poll.2,v 1.3 1996/09/07 21:53:08 mycroft Exp $
+.\" $FreeBSD$
+.\"
+.\" Copyright (c) 1996 Charles M. Hannum. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Charles M. Hannum.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd September 7, 1996
+.Dt POLL 2
+.Os
+.Sh NAME
+.Nm poll
+.Nd synchronous I/O multiplexing
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <poll.h>
+.Ft int
+.Fn poll "struct pollfd *fds" "unsigned int nfds" "int timeout"
+.Sh DESCRIPTION
+.Fn Poll
+examines a set of file descriptors to see if some of them are ready for
+I/O.
+The
+.Fa fds
+argument is a pointer to an array of pollfd structures as defined in
+.Aq Pa poll.h
+(shown below). The
+.Fa nfds
+argument determines the size of the
+.Fa fds
+array.
+.Bd -literal
+struct pollfd {
+ int fd; /* file descriptor */
+ short events; /* events to look for */
+ short revents; /* events returned */
+};
+.Ed
+.Pp
+The fields of
+.Fa struct pollfd
+are as follows:
+.Bl -tag -width XXXrevents
+.It fd
+File descriptor to poll. If fd is equal to -1 then
+.Fa revents
+is cleared (set to zero), and that pollfd is not checked.
+.It events
+Events to poll for. (See below.)
+.It revents
+Events which may occur. (See below.)
+.El
+.Pp
+The event bitmasks in
+.Fa events
+and
+.Fa revents
+have the following bits:
+.Bl -tag -width XXXPOLLWRNORM
+.It POLLIN
+Data other than high priority data may be read without blocking.
+.It POLLRDNORM
+Normal data may be read without blocking.
+.It POLLRDBAND
+Data with a non-zero priority may be read without blocking.
+.It POLLPRI
+High priority data may be read without blocking.
+.It POLLOUT
+.It POLLWRNORM
+Normal data may be written without blocking.
+.It POLLWRBAND
+Data with a non-zero priority may be written without blocking.
+.It POLLERR
+An exceptional condition has occurred on the device or socket. This
+flag is always checked, even if not present in the
+.Fa events
+bitmask.
+.It POLLHUP
+The device or socket has been disconnected. This flag is always
+checked, even if not present in the
+.Fa events
+bitmask. Note that
+POLLHUP
+and
+POLLOUT
+should never be present in the
+.Fa revents
+bitmask at the same time.
+.It POLLNVAL
+The file descriptor is not open. This flag is always checked, even
+if not present in the
+.Fa events
+bitmask.
+.El
+.Pp
+If
+.Fa timeout
+is neither zero nor INFTIM (-1), it specifies a maximum interval to
+wait for any file descriptor to become ready, in milliseconds. If
+.Fa timeout
+is INFTIM (-1), the poll blocks indefinitely. If
+.Fa timeout
+is zero, then
+.Fn poll
+will return without blocking.
+.Sh RETURN VALUES
+.Fn Poll
+returns the number of descriptors that are ready for I/O, or -1 if an
+error occured. If the time limit expires,
+.Fn poll
+returns 0.
+If
+.Fn poll
+returns with an error,
+including one due to an interrupted call,
+the
+.Fa fds
+array will be unmodified.
+.Sh COMPATIBILITY
+This implementation differs from the historical one in that a given
+file descriptor may not cause
+.Fn poll
+to return with an error. In cases where this would have happened in
+the historical implementation (e.g. trying to poll a
+.Xr revoke 2 ed
+descriptor), this implementation instead copies the
+.Fa events
+bitmask to the
+.Fa revents
+bitmask. Attempting to perform I/O on this descriptor will then
+return an error. This behaviour is believed to be more useful.
+.Sh ERRORS
+An error return from
+.Fn poll
+indicates:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+.Fa Fds
+points outside the process's allocated address space.
+.It Bq Er EINTR
+A signal was delivered before the time limit expired and
+before any of the selected events occurred.
+.It Bq Er EINVAL
+The specified time limit is negative.
+.El
+.Sh SEE ALSO
+.Xr accept 2 ,
+.Xr connect 2 ,
+.Xr read 2 ,
+.Xr recv 2 ,
+.Xr select 2 ,
+.Xr send 2 ,
+.Xr write 2
+.Sh BUGS
+The distinction between some of the fields in the
+.Fa events
+and
+.Fa revents
+bitmasks is really not useful without STREAMS. The fields are
+defined for compatibility with existing software.
+.Sh HISTORY
+The
+.Fn poll
+function call appeared in
+.At V .
+This manual page and the core of the implementation was taken from
+.Nx .
diff --git a/lib/libc/sys/pread.c b/lib/libc/sys/pread.c
new file mode 100644
index 0000000..b639383
--- /dev/null
+++ b/lib/libc/sys/pread.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)mmap.c 8.1 (Berkeley) 6/17/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+/*
+ * This function provides 64-bit offset padding that
+ * is not supplied by GCC 1.X but is supplied by GCC 2.X.
+ */
+ssize_t
+pread(fd, buf, nbyte, offset)
+ int fd;
+ void *buf;
+ size_t nbyte;
+ off_t offset;
+{
+ return ((ssize_t)__syscall((quad_t)SYS_pread, fd, buf, nbyte, 0, offset));
+}
diff --git a/lib/libc/sys/profil.2 b/lib/libc/sys/profil.2
new file mode 100644
index 0000000..a629803
--- /dev/null
+++ b/lib/libc/sys/profil.2
@@ -0,0 +1,136 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Donn Seeley of BSDI.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)profil.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt PROFIL 2
+.Os
+.Sh NAME
+.Nm profil
+.Nd control process profiling
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn profil "char *samples" "size_t size" "vm_offset_t offset" "int scale"
+.Sh DESCRIPTION
+The
+.Fn profil
+function enables or disables
+program counter profiling of the current process.
+If profiling is enabled,
+then at every profiling clock tick,
+the kernel updates an appropriate count in the
+.Fa samples
+buffer.
+The frequency of the profiling clock is recorded
+in the header in the profiling output file.
+.Pp
+The buffer
+.Fa samples
+contains
+.Fa size
+bytes and is divided into
+a series of 16-bit bins.
+Each bin counts the number of times the program counter
+was in a particular address range in the process
+when a profiling clock tick occurred while profiling was enabled.
+For a given program counter address,
+the number of the corresponding bin is given
+by the relation:
+.Bd -literal -offset indent
+[(pc - offset) / 2] * scale / 65536
+.Ed
+.Pp
+The
+.Fa offset
+parameter is the lowest address at which
+the kernel takes program counter samples.
+The
+.Fa scale
+parameter ranges from 1 to 65536 and
+can be used to change the span of the bins.
+A scale of 65536 maps each bin to 2 bytes of address range;
+a scale of 32768 gives 4 bytes, 16384 gives 8 bytes and so on.
+Intermediate values provide approximate intermediate ranges.
+A
+.Fa scale
+value of 0 disables profiling.
+.Sh RETURN VALUES
+If the
+.Fa scale
+value is nonzero and the buffer
+.Fa samples
+contains an illegal address,
+.Fn profil
+returns \-1,
+profiling is terminated and
+.Va errno
+is set appropriately.
+Otherwise
+.Fn profil
+returns 0.
+.Sh FILES
+.Bl -tag -width /usr/lib/gcrt0.o -compact
+.It Pa /usr/lib/gcrt0.o
+profiling C run-time startup file
+.It Pa gmon.out
+conventional name for profiling output file
+.El
+.Sh ERRORS
+The following error may be reported:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+The buffer
+.Fa samples
+contains an invalid address.
+.El
+.Sh SEE ALSO
+.Xr gprof 1
+.Sh HISTORY
+A
+.Fn profil
+function call appeared in
+.At v7 .
+.Sh BUGS
+This routine should be named
+.Fn profile .
+.Pp
+The
+.Fa samples
+argument should really be a vector of type
+.Fa "unsigned short" .
+.Pp
+The format of the gmon.out file is undocumented.
diff --git a/lib/libc/sys/ptrace.2 b/lib/libc/sys/ptrace.2
index 69477e9..37eca05 100644
--- a/lib/libc/sys/ptrace.2
+++ b/lib/libc/sys/ptrace.2
@@ -1,9 +1,10 @@
+.\" $FreeBSD$
.\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
.\"
.\" This file is in the public domain.
-.Dd November 7, 1994
+.Dd January 20, 1996
.Dt PTRACE 2
-.Os NetBSD 1.0BETA
+.Os FreeBSD 2
.Sh NAME
.Nm ptrace
.Nd process tracing and debugging
@@ -74,7 +75,9 @@ and data, which is why there are two requests: conceptually,
.Dv PT_READ_I
reads from the instruction space and
.Dv PT_READ_D
-reads from the data space. In the current NetBSD implementation, these
+reads from the data space. In the current
+.Tn FreeBSD
+implementation, these
two requests are completely identical. The
.Fa addr
argument specifies the address (in the traced process' virtual address
@@ -163,7 +166,7 @@ succeeds, the traced process is no longer traced and continues
execution normally.
.El
.Pp
-Additionally, machine-specific requests can exist. On the SPARC, these
+Additionally, machine-specific requests can exist. On the i386, these
are:
.Bl -tag -width 12n
.It Dv PT_GETREGS
@@ -199,114 +202,25 @@ it loads the traced process' floating-point registers from the
.Aq Pa machine/reg.h )
pointed to by
.Fa addr .
-.It Dv PT_SYSCALL
-This request is like
-.Dv PT_CONTINUE
-except that the process will stop next time it executes any system
-call. Information about the system call can be examined with
-.Dv PT_READ_U
-and potentially modified with
-.Dv PT_WRITE_U
-through the
-.Li u_kproc.kp_proc.p_md
-element of the user structure (see below). If the process is continued
-with another
-.Dv PT_SYSCALL
-request, it will stop again on exit from the syscall, at which point
-the return values can be examined and potentially changed. The
-.Li u_kproc.kp_proc.p_md
-element is of type
-.Dq Li "struct mdproc" ,
-which should be declared by including
-.Aq Pa sys/param.h ,
-.Aq Pa sys/user.h ,
-and
-.Aq Pa machine/proc.h ,
-and contains the following fields (among others):
-.Bl -item -compact -offset indent
-.It
-.Li syscall_num
-.It
-.Li syscall_nargs
-.It
-.Li syscall_args[8]
-.It
-.Li syscall_err
-.It
-.Li syscall_rv[2]
-.El
-When a process stops on entry to a syscall,
-.Li syscall_num
-holds the number of the syscall,
-.Li syscall_nargs
-holds the number of arguments it expects, and
-.Li syscall_args
-holds the arguments themselves. (Only the first
-.Li syscall_nargs
-elements of
-.Li syscall_args
-are guaranteed to be useful.) When a process stops on exit from a
-syscall,
-.Li syscall_num
-is
-.Eo \&
-.Li -1
-.Ec ,
-.Li syscall_err
-holds the error number
-.Po
-see
-.Xr errno 2
-.Pc ,
-or 0 if no error occurred, and
-.Li syscall_rv
-holds the return values. (If the syscall returns only one value, only
-.Li syscall_rv[0]
-is useful.) The tracing process can modify any of these with
-.Dv PT_WRITE_U ;
-only some modifications are useful.
-.Pp
-On entry to a syscall,
-.Li syscall_num
-can be changed, and the syscall actually performed will correspond to
-the new number (it is the responsibility of the tracing process to fill
-in
-.Li syscall_args
-appropriately for the new call, but there is no need to modify
-.Eo \&
-.Li syscall_nargs
-.Ec ).
-If the new syscall number is 0, no syscall is actually performed;
-instead,
-.Li syscall_err
-and
-.Li syscall_rv
-are passed back to the traced process directly (and therefore should be
-filled in). If the syscall number is otherwise out of range, a dummy
-syscall which simply produces an
-.Er ENOSYS
-error is effectively performed.
-.Pp
-On exit from a syscall, only
-.Li syscall_err
-and
-.Li syscall_rv
-can usefully be changed; they are set to the values returned by the
-syscall and will be passed back to the traced process by the normal
-syscall return mechanism.
.El
-.Sh ERRORS
+.Sh RETURN VALUES
Some requests can cause
.Fn ptrace
to return
.Li -1
as a non-error value; to disambiguate,
.Va errno
-can be set to 0 before the call and checked afterwards. The possible
-errors are:
+can be set to 0 before the call and checked afterwards.
+.Sh ERRORS
+The
+.Fn ptrace
+function may fail if:
.Bl -tag -width 4n
.It Bq Er ESRCH
+.Bl -bullet -compact
+.It
No process having the specified process ID exists.
+.El
.It Bq Er EINVAL
.Bl -bullet -compact
.It
@@ -331,8 +245,6 @@ The signal number (in
.Fa data )
to
.Dv PT_CONTINUE
-or
-.Dv PT_SYSCALL
was neither 0 nor a legal signal number.
.It
.Dv PT_GETREGS ,
@@ -369,27 +281,13 @@ on a process in violation of the requirements listed under
.Dv PT_ATTACH
above.
.El
-.Sh BUGS
-On the SPARC, the PC is set to the provided PC value for
-.Dv PT_CONTINUE
-and similar calls, but the NPC is set willy-nilly to 4 greater than the
-PC value. Using
-.Dv PT_GETREGS
-and
-.Dv PT_SETREGS
-to modify the PC, passing
-.Li (caddr_t)1
-to
-.Eo \&
+.Sh SEE ALSO
+.Xr execve 2 ,
+.Xr sigaction 2 ,
+.Xr wait 2 ,
+.Xr execv 3
+.Sh HISTORY
+A
.Fn ptrace
-.Ec ,
-should be able to sidestep this.
-.Pp
-Single-stepping is not available.
-.Pp
-When using
-.Dv PT_SYSCALL ,
-there is no easy way to tell whether the traced process stopped because
-it made a syscall or because a signal was sent at a moment that it just
-happened to have valid-looking garbage in its
-.Dq Li "struct mdproc" .
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/pwrite.c b/lib/libc/sys/pwrite.c
new file mode 100644
index 0000000..6fb3c5a
--- /dev/null
+++ b/lib/libc/sys/pwrite.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)mmap.c 8.1 (Berkeley) 6/17/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+/*
+ * This function provides 64-bit offset padding that
+ * is not supplied by GCC 1.X but is supplied by GCC 2.X.
+ */
+ssize_t
+pwrite(fd, buf, nbyte, offset)
+ int fd;
+ const void *buf;
+ size_t nbyte;
+ off_t offset;
+{
+ return ((ssize_t)__syscall((quad_t)SYS_pwrite, fd, buf, nbyte, 0, offset));
+}
diff --git a/lib/libc/sys/quotactl.2 b/lib/libc/sys/quotactl.2
new file mode 100644
index 0000000..a98cb1c
--- /dev/null
+++ b/lib/libc/sys/quotactl.2
@@ -0,0 +1,222 @@
+.\" Copyright (c) 1983, 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Robert Elz at The University of Melbourne.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)quotactl.2 8.2 (Berkeley) 3/10/95
+.\" $FreeBSD$
+.\"
+.Dd March 5, 1999
+.Dt QUOTACTL 2
+.Os
+.Sh NAME
+.Nm quotactl
+.Nd manipulate filesystem quotas
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <ufs/ufs/quota.h>
+.Ft int
+.Fn quotactl "const char *path" "int cmd" "int id" "void *addr"
+.Sh DESCRIPTION
+The
+.Fn quotactl
+call enables, disables and
+manipulates filesystem quotas.
+A quota control command
+given by
+.Fa cmd
+operates on the given filename
+.Fa path
+for the given user
+.Fa id .
+(NOTE: One should use the QCMD macro defined in
+.Ao Pa ufs/ufs/quota.h Ac
+to formulate the value for
+.Fa cmd . )
+The address of an optional command specific data structure,
+.Fa addr ,
+may be given; its interpretation
+is discussed below with each command.
+.Pp
+Currently quotas are supported only for the
+.Dq ufs
+filesystem.
+For
+.Dq ufs ,
+a command is composed of a primary command (see below)
+and a command type used to interpret the
+.Fa id .
+Types are supported for interpretation of user identifiers (USRQUOTA)
+and group identifiers (GRPQUOTA).
+The
+.Dq ufs
+specific commands are:
+.Bl -tag -width Q_QUOTAOFFxx
+.It Dv Q_QUOTAON
+Enable disk quotas for the filesystem specified by
+.Fa path .
+The command type specifies the type of the quotas being enabled.
+The
+.Fa addr
+argument specifies a file from which to take the quotas.
+The quota file must exist;
+it is normally created with the
+.Xr quotacheck 8
+program.
+The
+.Fa id
+argument is unused.
+Only the super-user may turn quotas on.
+.It Dv Q_QUOTAOFF
+Disable disk quotas for the filesystem specified by
+.Fa path .
+The command type specifies the type of the quotas being disabled.
+The
+.Fa addr
+and
+.Fa id
+arguments are unused.
+Only the super-user may turn quotas off.
+.It Dv Q_GETQUOTA
+Get disk quota limits and current usage for the user or group
+(as determined by the command type) with identifier
+.Fa id .
+.Fa Addr
+is a pointer to a
+.Fa struct dqblk
+structure (defined in
+.Ao Pa ufs/ufs/quota.h Ac ) .
+.It Dv Q_SETQUOTA
+Set disk quota limits for the user or group
+(as determined by the command type) with identifier
+.Fa id .
+.Fa Addr
+is a pointer to a
+.Fa struct dqblk
+structure (defined in
+.Ao Pa ufs/ufs/quota.h Ac ) .
+The usage fields of the
+.Fa dqblk
+structure are ignored.
+This call is restricted to the super-user.
+.It Dv Q_SETUSE
+Set disk usage limits for the user or group
+(as determined by the command type) with identifier
+.Fa id .
+.Fa Addr
+is a pointer to a
+.Fa struct dqblk
+structure (defined in
+.Ao Pa ufs/ufs/quota.h Ac ) .
+Only the usage fields are used.
+This call is restricted to the super-user.
+.It Dv Q_SYNC
+Update the on-disk copy of quota usages.
+The command type specifies which type of quotas are to be updated.
+The
+.Fa id
+and
+.Fa addr
+parameters are ignored.
+.El
+.Sh RETURN VALUES
+A successful call returns 0,
+otherwise the value -1 is returned and the global variable
+.Va errno
+indicates the reason for the failure.
+.Sh ERRORS
+A
+.Fn quotactl
+call will fail if:
+.Bl -tag -width ENAMETOOLONGAA
+.It Bq Er EOPNOTSUPP
+The kernel has not been compiled with the
+.Dv QUOTA
+option.
+.It Bq Er EUSERS
+The quota table cannot be expanded.
+.It Bq Er EINVAL
+.Fa Cmd
+or the command type is invalid.
+.It Bq Er EACCES
+In
+.Dv Q_QUOTAON ,
+the quota file is not a plain file.
+.It Bq Er EACCES
+Search permission is denied for a component of a path prefix.
+.It Bq Er ENOTDIR
+A component of a path prefix was not a directory.
+.It Bq Er ENAMETOOLONG
+A component of either pathname exceeded 255 characters,
+or the entire length of either path name exceeded 1023 characters.
+.It Bq Er ENOENT
+A filename does not exist.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating a pathname.
+.It Bq Er EROFS
+In
+.Dv Q_QUOTAON ,
+the quota file resides on a read-only filesystem.
+.It Bq Er EIO
+An
+.Tn I/O
+error occurred while reading from or writing
+to a file containing quotas.
+.It Bq Er EFAULT
+An invalid
+.Fa addr
+was supplied; the associated structure could not be copied in or out
+of the kernel.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.It Bq Er EPERM
+The call was privileged and the caller was not the super-user.
+.El
+.Sh SEE ALSO
+.Xr quota 1 ,
+.Xr fstab 5 ,
+.Xr edquota 8 ,
+.Xr quotacheck 8 ,
+.Xr quotaon 8 ,
+.Xr repquota 8
+.Sh BUGS
+There should be some way to integrate this call with the resource
+limit interface provided by
+.Xr setrlimit 2
+and
+.Xr getrlimit 2 .
+.Sh HISTORY
+The
+.Fn quotactl
+function call appeared in
+.Bx 4.3 Reno .
diff --git a/lib/libc/sys/read.2 b/lib/libc/sys/read.2
new file mode 100644
index 0000000..b8c451d
--- /dev/null
+++ b/lib/libc/sys/read.2
@@ -0,0 +1,266 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)read.2 8.4 (Berkeley) 2/26/94
+.\" $FreeBSD$
+.\"
+.Dd February 26, 1994
+.Dt READ 2
+.Os BSD 4
+.Sh NAME
+.Nm read ,
+.Nm readv ,
+.Nm pread
+.Nd read input
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/uio.h>
+.Fd #include <unistd.h>
+.Ft ssize_t
+.Fn read "int d" "void *buf" "size_t nbytes"
+.Ft ssize_t
+.Fn readv "int d" "const struct iovec *iov" "int iovcnt"
+.Ft ssize_t
+.Fn pread "int d" "void *buf" "size_t nbytes" "off_t offset"
+.Sh DESCRIPTION
+.Fn Read
+attempts to read
+.Fa nbytes
+of data from the object referenced by the descriptor
+.Fa d
+into the buffer pointed to by
+.Fa buf .
+.Fn Readv
+performs the same action, but scatters the input data
+into the
+.Fa iovcnt
+buffers specified by the members of the
+.Fa iov
+array: iov[0], iov[1], ..., iov[iovcnt\|\-\|1].
+.Fn Pread
+performs the same function, but reads from the specified position in
+the file without modifying the file pointer.
+.Pp
+For
+.Fn readv ,
+the
+.Fa iovec
+structure is defined as:
+.Pp
+.Bd -literal -offset indent -compact
+struct iovec {
+ char *iov_base; /* Base address. */
+ size_t iov_len; /* Length. */
+};
+.Ed
+.Pp
+Each
+.Fa iovec
+entry specifies the base address and length of an area
+in memory where data should be placed.
+.Fn Readv
+will always fill an area completely before proceeding
+to the next.
+.Pp
+On objects capable of seeking, the
+.Fn read
+starts at a position
+given by the pointer associated with
+.Fa d
+(see
+.Xr lseek 2 ) .
+Upon return from
+.Fn read ,
+the pointer is incremented by the number of bytes actually read.
+.Pp
+Objects that are not capable of seeking always read from the current
+position. The value of the pointer associated with such an
+object is undefined.
+.Pp
+Upon successful completion,
+.Fn read ,
+.Fn readv ,
+and
+.Fn pread
+return the number of bytes actually read and placed in the buffer.
+The system guarantees to read the number of bytes requested if
+the descriptor references a normal file that has that many bytes left
+before the end-of-file, but in no other case.
+.Pp
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn read
+is implemented as the
+.Va read
+syscall.
+.Pp
+In the threaded library, the
+.Va read
+syscall is assembled to
+.Fn _thread_sys_read
+and
+.Fn read
+is implemented as a function which locks
+.Va d
+for read, then calls
+.Fn _thread_sys_read .
+If the call to
+.Fn _thread_sys_read
+would block, a context switch is performed. Before returning,
+.Fn read
+unlocks
+.Va d .
+.Pp
+In the non-threaded library
+.Fn readv
+is implemented as the
+.Va readv
+syscall.
+.Pp
+In the threaded library, the
+.Va readv
+syscall is assembled to
+.Fn _thread_sys_readv
+and
+.Fn readv
+is implemented as a function which locks
+.Va d
+for read, then calls
+.Fn _thread_sys_readv .
+If the call to
+.Fn _thread_sys_readv
+would block, a context switch is performed. Before returning,
+.Fn readv
+unlocks
+.Va d .
+.Sh RETURN VALUES
+If successful, the
+number of bytes actually read is returned. Upon reading end-of-file,
+zero is returned.
+Otherwise, a -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Read ,
+.Fn readv ,
+and
+.Fn pread
+will succeed unless:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa D
+is not a valid file or socket descriptor open for reading.
+.It Bq Er EFAULT
+.Fa Buf
+points outside the allocated address space.
+.It Bq Er EIO
+An I/O error occurred while reading from the file system.
+.It Bq Er EINTR
+A read from a slow device was interrupted before
+any data arrived by the delivery of a signal.
+.It Bq Er EINVAL
+The pointer associated with
+.Fa d
+was negative.
+.It Bq Er EAGAIN
+The file was marked for non-blocking I/O,
+and no data were ready to be read.
+.El
+.Pp
+In addition,
+.Fn readv
+may return one of the following errors:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+.Fa Iovcnt
+was less than or equal to 0, or greater than 16.
+.It Bq Er EINVAL
+One of the
+.Fa iov_len
+values in the
+.Fa iov
+array was negative.
+.It Bq Er EINVAL
+The sum of the
+.Fa iov_len
+values in the
+.Fa iov
+array overflowed a 32-bit integer.
+.It Bq Er EFAULT
+Part of the
+.Fa iov
+points outside the process's allocated address space.
+.El
+.Pp
+The
+.Fn pread
+call may also return the following errors:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The specified file offset is invalid.
+.It Bq Er ESPIPE
+The file descriptor is associated with a pipe, socket, or FIFO.
+.El
+.Sh SEE ALSO
+.Xr dup 2 ,
+.Xr fcntl 2 ,
+.Xr open 2 ,
+.Xr pipe 2 ,
+.Xr select 2 ,
+.Xr socket 2 ,
+.Xr socketpair 2
+.Sh STANDARDS
+The
+.Fn read
+function call is expected to conform to
+.St -p1003.1-90 .
+The
+.Fn readv
+and
+.Fn pread
+functions are expected to conform to
+.St -xpg4.2 .
+.Sh HISTORY
+The
+.Fn pread
+function call
+appeared in
+.At V.4 .
+The
+.Fn readv
+function call
+appeared in
+.Bx 4.2 .
+A
+.Fn read
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/readlink.2 b/lib/libc/sys/readlink.2
new file mode 100644
index 0000000..b395dc1
--- /dev/null
+++ b/lib/libc/sys/readlink.2
@@ -0,0 +1,96 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)readlink.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt READLINK 2
+.Os BSD 4.2
+.Sh NAME
+.Nm readlink
+.Nd read value of a symbolic link
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn readlink "const char *path" "char *buf" "int bufsiz"
+.Sh DESCRIPTION
+.Fn Readlink
+places the contents of the symbolic link
+.Fa path
+in the buffer
+.Fa buf ,
+which has size
+.Fa bufsiz .
+The
+.Fn readlink
+function does not append a
+.Dv NUL
+character to
+.Fa buf .
+.Sh RETURN VALUES
+The call returns the count of characters placed in the buffer
+if it succeeds, or a -1 if an error occurs, placing the error
+code in the global variable
+.Va errno .
+.Sh ERRORS
+.Fn Readlink
+will fail if:
+.Bl -tag -width ENAMETOOLONG
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named file does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EINVAL
+The named file is not a symbolic link.
+.It Bq Er EIO
+An I/O error occurred while reading from the file system.
+.It Bq Er EFAULT
+.Fa Buf
+extends outside the process's allocated address space.
+.El
+.Sh SEE ALSO
+.Xr lstat 2 ,
+.Xr stat 2 ,
+.Xr symlink 2 ,
+.Xr symlink 7
+.Sh HISTORY
+The
+.Fn readlink
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/reboot.2 b/lib/libc/sys/reboot.2
new file mode 100644
index 0000000..00d750c
--- /dev/null
+++ b/lib/libc/sys/reboot.2
@@ -0,0 +1,163 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)reboot.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt REBOOT 2
+.Os BSD 4
+.Sh NAME
+.Nm reboot
+.Nd reboot system or halt processor
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Fd #include <sys/reboot.h>
+.Ft int
+.Fn reboot "int howto"
+.Sh DESCRIPTION
+.Fn Reboot
+reboots the system.
+Only the super-user may reboot a machine on demand.
+However, a reboot is invoked
+automatically in the event of unrecoverable system failures.
+.Pp
+.Fa Howto
+is a mask of options; the system call interface allows the following
+options, defined in the include file
+.Aq Pa sys/reboot.h ,
+to be passed
+to the new kernel or the new bootstrap and init programs.
+.Bl -tag -width RB_INITNAMEA
+.It Dv RB_AUTOBOOT
+The default, causing the system to reboot in its usual fashion.
+.It Dv RB_ASKNAME
+Interpreted by the bootstrap program itself, causing it to
+prompt on the console as to what file should be booted.
+Normally, the system is booted from the file
+.Dq Em xx Ns No (0,0)kernel ,
+where
+.Em xx
+is the default disk name,
+without prompting for the file name.
+.It Dv RB_DFLTROOT
+Use the compiled in root device.
+Normally, the system uses the device from which it was booted
+as the root device if possible.
+(The default behavior is dependent on the ability of the bootstrap program
+to determine the drive from which it was loaded, which is not possible
+on all systems.)
+.It Dv RB_DUMP
+Dump kernel memory before rebooting; see
+.Xr savecore 8
+for more information.
+.It Dv RB_HALT
+the processor is simply halted; no reboot takes place.
+This option should be used with caution.
+.It Dv RB_POWEROFF
+After halting, the shutdown code will do what it can to turn
+of the power. This requires hardware support.
+.It Dv RB_INITNAME
+An option allowing the specification of an init program (see
+.Xr init 8 )
+other than
+.Pa /sbin/init
+to be run when the system reboots.
+This switch is not currently available.
+.It Dv RB_KDB
+Load the symbol table and enable a built-in debugger in the system.
+This option will have no useful function if the kernel is not configured
+for debugging.
+Several other options have different meaning if combined
+with this option, although their use may not be possible
+via the
+.Fn reboot
+call.
+See
+.Xr kadb 4
+for more information.
+.It Dv RB_NOSYNC
+Normally, the disks are sync'd (see
+.Xr sync 8 )
+before the processor is halted or rebooted.
+This option may be useful if file system changes have been made manually
+or if the processor is on fire.
+.It Dv RB_RDONLY
+Initially mount the root file system read-only.
+This is currently the default, and this option has been deprecated.
+.It Dv RB_SINGLE
+Normally, the reboot procedure involves an automatic disk consistency
+check and then multi-user operations.
+.Dv RB_SINGLE
+prevents this, booting the system with a single-user shell
+on the console.
+.Dv RB_SINGLE
+is actually interpreted by the
+.Xr init 8
+program in the newly booted system.
+.El
+.Pp
+When no options are given (i.e.,
+.Dv RB_AUTOBOOT
+is used), the system is
+rebooted from file
+.Dq kernel
+in the root file system of unit 0
+of a disk chosen in a processor specific way.
+An automatic consistency check of the disks is normally performed
+(see
+.Xr fsck 8 ) .
+.Sh RETURN VALUES
+If successful, this call never returns.
+Otherwise, a -1 is returned and an error is returned in the global
+variable
+.Va errno .
+.Sh ERRORS
+.Bl -tag -width Er
+.It Bq Er EPERM
+The caller is not the super-user.
+.El
+.Sh SEE ALSO
+.Xr crash 8 ,
+.Xr halt 8 ,
+.Xr init 8 ,
+.Xr reboot 8 ,
+.Xr savecore 8
+.Sh BUGS
+The HP300 implementation supports neither
+.Dv RB_DFLTROOT
+nor
+.Dv RB_KDB .
+.Sh HISTORY
+The
+.Fn reboot
+function call appeared in
+.Bx 4.0 .
diff --git a/lib/libc/sys/recv.2 b/lib/libc/sys/recv.2
new file mode 100644
index 0000000..bf73dd5
--- /dev/null
+++ b/lib/libc/sys/recv.2
@@ -0,0 +1,294 @@
+.\" Copyright (c) 1983, 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)recv.2 8.3 (Berkeley) 2/21/94
+.\" $FreeBSD$
+.\"
+.Dd February 21, 1994
+.Dt RECV 2
+.Os BSD 4.3r
+.Sh NAME
+.Nm recv ,
+.Nm recvfrom ,
+.Nm recvmsg
+.Nd receive a message from a socket
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft ssize_t
+.Fn recv "int s" "void *buf" "size_t len" "int flags"
+.Ft ssize_t
+.Fn recvfrom "int s" "void *buf" "size_t len" "int flags" "struct sockaddr *from" "socklen_t *fromlen"
+.Ft ssize_t
+.Fn recvmsg "int s" "struct msghdr *msg" "int flags"
+.Sh DESCRIPTION
+.Fn Recvfrom
+and
+.Fn recvmsg
+are used to receive messages from a socket,
+and may be used to receive data on a socket whether or not
+it is connection-oriented.
+.Pp
+If
+.Fa from
+is non-nil, and the socket is not connection-oriented,
+the source address of the message is filled in.
+.Fa Fromlen
+is a value-result parameter, initialized to the size of
+the buffer associated with
+.Fa from ,
+and modified on return to indicate the actual size of the
+address stored there.
+.Pp
+The
+.Fn recv
+call is normally used only on a
+.Em connected
+socket (see
+.Xr connect 2 )
+and is identical to
+.Fn recvfrom
+with a nil
+.Fa from
+parameter.
+As it is redundant, it may not be supported in future releases.
+.Pp
+All three routines return the length of the message on successful
+completion.
+If a message is too long to fit in the supplied buffer,
+excess bytes may be discarded depending on the type of socket
+the message is received from (see
+.Xr socket 2 ) .
+.Pp
+If no messages are available at the socket, the
+receive call waits for a message to arrive, unless
+the socket is nonblocking (see
+.Xr fcntl 2 )
+in which case the value
+-1 is returned and the external variable
+.Va errno
+set to
+.Er EAGAIN .
+The receive calls normally return any data available,
+up to the requested amount,
+rather than waiting for receipt of the full amount requested;
+this behavior is affected by the socket-level options
+.Dv SO_RCVLOWAT
+and
+.Dv SO_RCVTIMEO
+described in
+.Xr getsockopt 2 .
+.Pp
+The
+.Xr select 2
+call may be used to determine when more data arrive.
+.Pp
+The
+.Fa flags
+argument to a recv call is formed by
+.Em or Ap ing
+one or more of the values:
+.Bl -column MSG_WAITALL -offset indent
+.It Dv MSG_OOB Ta process out-of-band data
+.It Dv MSG_PEEK Ta peek at incoming message
+.It Dv MSG_WAITALL Ta wait for full request or error
+.El
+.Pp
+The
+.Dv MSG_OOB
+flag requests receipt of out-of-band data
+that would not be received in the normal data stream.
+Some protocols place expedited data at the head of the normal
+data queue, and thus this flag cannot be used with such protocols.
+The MSG_PEEK flag causes the receive operation to return data
+from the beginning of the receive queue without removing that
+data from the queue.
+Thus, a subsequent receive call will return the same data.
+The MSG_WAITALL flag requests that the operation block until
+the full request is satisfied.
+However, the call may still return less data than requested
+if a signal is caught, an error or disconnect occurs,
+or the next data to be received is of a different type than that returned.
+.Pp
+The
+.Fn recvmsg
+call uses a
+.Fa msghdr
+structure to minimize the number of directly supplied parameters.
+This structure has the following form, as defined in
+.Ao Pa sys/socket.h Ac :
+.Pp
+.Bd -literal
+struct msghdr {
+ caddr_t msg_name; /* optional address */
+ u_int msg_namelen; /* size of address */
+ struct iovec *msg_iov; /* scatter/gather array */
+ u_int msg_iovlen; /* # elements in msg_iov */
+ caddr_t msg_control; /* ancillary data, see below */
+ u_int msg_controllen; /* ancillary data buffer len */
+ int msg_flags; /* flags on received message */
+};
+.Ed
+.Pp
+Here
+.Fa msg_name
+and
+.Fa msg_namelen
+specify the destination address if the socket is unconnected;
+.Fa msg_name
+may be given as a null pointer if no names are desired or required.
+.Fa Msg_iov
+and
+.Fa msg_iovlen
+describe scatter gather locations, as discussed in
+.Xr read 2 .
+.Fa Msg_control ,
+which has length
+.Fa msg_controllen ,
+points to a buffer for other protocol control related messages
+or other miscellaneous ancillary data.
+The messages are of the form:
+.Bd -literal
+struct cmsghdr {
+ u_int cmsg_len; /* data byte count, including hdr */
+ int cmsg_level; /* originating protocol */
+ int cmsg_type; /* protocol-specific type */
+/* followed by
+ u_char cmsg_data[]; */
+};
+.Pp
+.Ed
+As an example, one could use this to learn of changes in the data-stream
+in XNS/SPP, or in ISO, to obtain user-connection-request data by requesting
+a recvmsg with no data buffer provided immediately after an
+.Fn accept
+call.
+.Pp
+Open file descriptors are now passed as ancillary data for
+.Dv AF_UNIX
+domain sockets, with
+.Fa cmsg_level
+set to
+.Dv SOL_SOCKET
+and
+.Fa cmsg_type
+set to
+.Dv SCM_RIGHTS .
+.Pp
+Process credentials can also be passed as ancillary data for
+.Dv AF_UNIX
+domain sockets using a
+.Fa cmsg_type
+of
+.Dv SCM_CREDS.
+In this case,
+.Fa cmsg_data
+should be a structure of type
+.Fa cmsgcred ,
+which is defined in
+.Ao Pa sys/socket.h Ac
+as follows:
+.Pp
+.Bd -literal
+struct cmsgcred {
+ pid_t cmcred_pid; /* PID of sending process */
+ uid_t cmcred_uid; /* real UID of sending process */
+ uid_t cmcred_euid; /* effective UID of sending process */
+ gid_t cmcred_gid; /* real GID of sending process */
+ short cmcred_ngroups; /* number or groups */
+ gid_t cmcred_groups[CMGROUP_MAX]; /* groups */
+};
+.Ed
+.Pp
+The kernel will fill in the credential information of the sending process
+and deliver it to the receiver.
+.Pp
+The
+.Fa msg_flags
+field is set on return according to the message received.
+.Dv MSG_EOR
+indicates end-of-record;
+the data returned completed a record (generally used with sockets of type
+.Dv SOCK_SEQPACKET ) .
+.Dv MSG_TRUNC
+indicates that
+the trailing portion of a datagram was discarded because the datagram
+was larger than the buffer supplied.
+.Dv MSG_CTRUNC
+indicates that some
+control data were discarded due to lack of space in the buffer
+for ancillary data.
+.Dv MSG_OOB
+is returned to indicate that expedited or out-of-band data were received.
+.Pp
+.Sh RETURN VALUES
+These calls return the number of bytes received, or -1
+if an error occurred.
+.Sh ERRORS
+The calls fail if:
+.Bl -tag -width ENOTCONNAA
+.It Bq Er EBADF
+The argument
+.Fa s
+is an invalid descriptor.
+.It Bq Er ENOTCONN
+The socket is associated with a connection-oriented protocol
+and has not been connected (see
+.Xr connect 2
+and
+.Xr accept 2 ).
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+does not refer to a socket.
+.It Bq Er EAGAIN
+The socket is marked non-blocking, and the receive operation
+would block, or
+a receive timeout had been set,
+and the timeout expired before data were received.
+.It Bq Er EINTR
+The receive was interrupted by delivery of a signal before
+any data were available.
+.It Bq Er EFAULT
+The receive buffer pointer(s) point outside the process's
+address space.
+.El
+.Sh SEE ALSO
+.Xr fcntl 2 ,
+.Xr getsockopt 2 ,
+.Xr read 2 ,
+.Xr select 2 ,
+.Xr socket 2
+.Sh HISTORY
+The
+.Fn recv
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/rename.2 b/lib/libc/sys/rename.2
new file mode 100644
index 0000000..cce01d6
--- /dev/null
+++ b/lib/libc/sys/rename.2
@@ -0,0 +1,199 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)rename.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt RENAME 2
+.Os BSD 4.2
+.Sh NAME
+.Nm rename
+.Nd change the name of a file
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft int
+.Fn rename "const char *from" "const char *to"
+.Sh DESCRIPTION
+.Fn Rename
+causes the link named
+.Fa from
+to be renamed as
+.Fa to .
+If
+.Fa to
+exists, it is first removed.
+Both
+.Fa from
+and
+.Fa to
+must be of the same type (that is, both directories or both
+non-directories), and must reside on the same file system.
+.Pp
+.Fn Rename
+guarantees that an instance of
+.Fa to
+will always exist, even if the system should crash in
+the middle of the operation.
+.Pp
+If the final component of
+.Fa from
+is a symbolic link,
+the symbolic link is renamed,
+not the file or directory to which it points.
+.\".Sh CAVEAT
+.\"The system can deadlock if a loop in the file system graph is present.
+.\"This loop takes the form of an entry in directory
+.\".Ql Pa a ,
+.\"say
+.\".Ql Pa a/foo ,
+.\"being a hard link to directory
+.\".Ql Pa b ,
+.\"and an entry in
+.\"directory
+.\".Ql Pa b ,
+.\"say
+.\".Ql Pa b/bar ,
+.\"being a hard link
+.\"to directory
+.\".Ql Pa a .
+.\"When such a loop exists and two separate processes attempt to
+.\"perform
+.\".Ql rename a/foo b/bar
+.\"and
+.\".Ql rename b/bar a/foo ,
+.\"respectively,
+.\"the system may deadlock attempting to lock
+.\"both directories for modification.
+.\"Hard links to directories should be
+.\"replaced by symbolic links by the system administrator.
+.Sh RETURN VALUES
+A 0 value is returned if the operation succeeds, otherwise
+.Fn rename
+returns -1 and the global variable
+.Va errno
+indicates the reason for the failure.
+.Sh ERRORS
+.Fn Rename
+will fail and neither of the argument files will be
+affected if:
+.Bl -tag -width ENAMETOOLONG
+.It Bq Er ENAMETOOLONG
+A component of either pathname exceeded 255 characters,
+or the entire length of either path name exceeded 1023 characters.
+.It Bq Er ENOENT
+A component of the
+.Fa from
+path does not exist,
+or a path prefix of
+.Fa to
+does not exist.
+.It Bq Er EACCES
+A component of either path prefix denies search permission.
+.It Bq Er EACCES
+The requested link requires writing in a directory with a mode
+that denies write permission.
+.It Bq Er EPERM
+The directory containing
+.Fa from
+is marked sticky,
+and neither the containing directory nor
+.Fa from
+are owned by the effective user ID.
+.It Bq Er EPERM
+The
+.Fa to
+file exists,
+the directory containing
+.Fa to
+is marked sticky,
+and neither the containing directory nor
+.Fa to
+are owned by the effective user ID.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating either pathname.
+.It Bq Er ENOTDIR
+A component of either path prefix is not a directory.
+.It Bq Er ENOTDIR
+.Fa from
+is a directory, but
+.Fa to
+is not a directory.
+.It Bq Er EISDIR
+.Fa to
+is a directory, but
+.Fa from
+is not a directory.
+.It Bq Er EXDEV
+The link named by
+.Fa to
+and the file named by
+.Fa from
+are on different logical devices (file systems). Note that this error
+code will not be returned if the implementation permits cross-device
+links.
+.It Bq Er ENOSPC
+The directory in which the entry for the new name is being placed
+cannot be extended because there is no space left on the file
+system containing the directory.
+.It Bq Er EDQUOT
+The directory in which the entry for the new name
+is being placed cannot be extended because the
+user's quota of disk blocks on the file system
+containing the directory has been exhausted.
+.It Bq Er EIO
+An I/O error occurred while making or updating a directory entry.
+.It Bq Er EROFS
+The requested link requires writing in a directory on a read-only file
+system.
+.It Bq Er EFAULT
+.Em Path
+points outside the process's allocated address space.
+.It Bq Er EINVAL
+.Fa From
+is a parent directory of
+.Fa to ,
+or an attempt is made to rename
+.Ql \&.
+or
+.Ql \&.. .
+.It Bq Er ENOTEMPTY
+.Fa To
+is a directory and is not empty.
+.El
+.Sh SEE ALSO
+.Xr open 2 ,
+.Xr symlink 7
+.Sh STANDARDS
+The
+.Fn rename
+function call is expected to conform to
+.St -p1003.1-90 .
diff --git a/lib/libc/sys/revoke.2 b/lib/libc/sys/revoke.2
new file mode 100644
index 0000000..cafdf89
--- /dev/null
+++ b/lib/libc/sys/revoke.2
@@ -0,0 +1,108 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Berkeley Software Design, Inc.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)revoke.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt REVOKE 2
+.Os
+.Sh NAME
+.Nm revoke
+.Nd revoke file access
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn revoke "const char *path"
+.Sh DESCRIPTION
+The
+.Fn revoke
+function invalidates all current open file descriptors in the system
+for the file named by
+.Fa path .
+Subsequent operations on any such descriptors
+fail, with the exceptions that a
+.Fn read
+from a character device file which has been revoked
+returns a count of zero (end of file),
+and a
+.Fn close
+call will succeed.
+If the file is a special file for a device which is open,
+the device close function
+is called as if all open references to the file had been closed.
+.Pp
+Access to a file may be revoked only by its owner or the super user.
+The
+.Fn revoke
+function is currently supported only for block and character special
+device files.
+It is normally used to prepare a terminal device for a new login session,
+preventing any access by a previous user of the terminal.
+.Sh RETURN VALUES
+A 0 value indicated that the call succeeded. A \-1 return value
+indicates an error occurred and
+.Va errno
+is set to indicated the reason.
+.Sh ERRORS
+Access to the named file is revoked unless one of the following:
+.Bl -tag -width Er
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1024 characters.
+.It Bq Er ENOENT
+The named file or a component of the path name does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.It Bq Er EINVAL
+The implementation does not support the
+.Fn revoke
+operation on the named file.
+.It Bq Er EPERM
+The caller is neither the owner of the file nor the super user.
+.El
+.Sh SEE ALSO
+.Xr close 2
+.Sh HISTORY
+The
+.Fn revoke
+function was introduced in
+.Bx 4.3 Reno .
diff --git a/lib/libc/sys/rfork.2 b/lib/libc/sys/rfork.2
new file mode 100644
index 0000000..c5825cb
--- /dev/null
+++ b/lib/libc/sys/rfork.2
@@ -0,0 +1,145 @@
+.\"
+.\" This manual page is taken directly from Plan9, and modified to
+.\" describe the actual BSD implementation. Permission for
+.\" use of this page comes from Rob Pike <rob@plan9.att.com>.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd Jan 12, 1996
+.Dt RFORK 2
+.Os
+.Sh NAME
+.Nm rfork
+.Nd manipulate process resources
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn rfork "int flags"
+.Sh DESCRIPTION
+Forking, vforking or rforking are the only ways new processes are created.
+The
+.Fa flags
+argument to
+.Fn rfork
+selects which resources of the
+invoking process (parent) are shared
+by the new process (child) or initialized to
+their default values.
+The resources include
+the open file descriptor table (which, when shared, permits processes
+to open and close files for other processes),
+and open files.
+.Fa Flags
+is the logical OR of some subset of:
+.Bl -tag -width "RFCNAMEG" -compact -offset indent
+.It RFPROC
+If set a new process is created; otherwise changes affect the
+current process.
+The current implementation requires this flag to always be set.
+.It RFNOWAIT
+If set, the child process will be dissociated from the parent. Upon
+exit the child will not leave a status for the parent to collect.
+See
+.Xr wait 2 .
+.It RFFDG
+If set, the invoker's file descriptor table (see
+.Xr intro 2
+) is copied; otherwise the two processes share a
+single table.
+.It RFCFDG
+If set, the new process starts with a clean file descriptor table.
+Is mutually exclusive with
+.Dv RFFDG .
+.It RFMEM
+If set, the kernel will force sharing of the entire address space.
+The child
+will then inherit all the shared segments the parent process owns. Other segment
+types will be unaffected. Subsequent forks by the parent will then
+propagate the shared data and bss between children. The stack segment
+is always split. May be set only with
+.Dv RFPROC .
+.It RFSIGSHARE
+If set, the kernel will force sharing the sigacts structure between the
+child and the parent.
+.It RFLINUXTHPN
+If set, the kernel will return SIGUSR1 instead of SIGCHILD upon thread
+exit for the child. This is intended to mimic certain Linux clone behaviour.
+.El
+.Pp
+File descriptors in a shared file descriptor table are kept
+open until either they are explicitly closed
+or all processes sharing the table exit.
+.Pp
+If
+.Dv RFPROC
+is set, the
+value returned in the parent process
+is the process id
+of the child process; the value returned in the child is zero.
+Without
+.Dv RFPROC ,
+the return value is zero.
+Process id's range from 1 to the maximum integer
+.Ft ( int )
+value.
+.Fn Rfork
+will sleep, if necessary, until required process resources are available.
+.Pp
+.Fn Fork
+can be implemented as a call to
+.Fn rfork "RFFDG | RFPROC"
+but isn't for backwards compatibility.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn rfork
+returns a value
+of 0 to the child process and returns the process ID of the child
+process to the parent process. Otherwise, a value of -1 is returned
+to the parent process, no child process is created, and the global
+variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Rfork
+will fail and no child process will be created if:
+.Bl -tag -width [EAGAIN]
+.It Bq Er EAGAIN
+The system-imposed limit on the total
+number of processes under execution would be exceeded.
+The limit is given by the
+.Xr sysctl 3
+MIB variable
+.Dv KERN_MAXPROC .
+(The limit is actually one less than this
+except for the super user).
+.It Bq Er EAGAIN
+The user is not the super user, and
+the system-imposed limit
+on the total number of
+processes under execution by a single user would be exceeded.
+The limit is given by the
+.Xr sysctl 3
+MIB variable
+.Dv KERN_MAXPROCPERUID .
+.It Bq Er EAGAIN
+The user is not the super user, and
+the soft resource limit corresponding to the resource parameter
+.Dv RLIMIT_NOFILE
+would be exceeded (see
+.Xr getrlimit 2 ) .
+.It Bq Er EINVAL
+The RFPROC flag was not specified.
+.It Bq Er EINVAL
+Both the RFFDG and the RFCFDG flags were specified.
+.It Bq Er ENOMEM
+There is insufficient swap space for the new process.
+.El
+.Sh SEE ALSO
+.Xr fork 2 ,
+.Xr intro 2 ,
+.Xr minherit 2 ,
+.Xr vfork 2
+.Sh HISTORY
+The
+.Fn rfork
+function call first appeared in Plan9.
diff --git a/lib/libc/sys/rmdir.2 b/lib/libc/sys/rmdir.2
new file mode 100644
index 0000000..d618287
--- /dev/null
+++ b/lib/libc/sys/rmdir.2
@@ -0,0 +1,105 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)rmdir.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt RMDIR 2
+.Os BSD 4.2
+.Sh NAME
+.Nm rmdir
+.Nd remove a directory file
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn rmdir "const char *path"
+.Sh DESCRIPTION
+.Fn Rmdir
+removes a directory file
+whose name is given by
+.Fa path .
+The directory must not have any entries other
+than
+.Ql \&.
+and
+.Ql \&.. .
+.Sh RETURN VALUES
+A 0 is returned if the remove succeeds; otherwise a -1 is
+returned and an error code is stored in the global location
+.Va errno .
+.Sh ERRORS
+The named file is removed unless:
+.Bl -tag -width [ENAMETOOLONG]
+.It Bq Er ENOTDIR
+A component of the path is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named directory does not exist.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er ENOTEMPTY
+The named directory contains files other than
+.Ql \&.
+and
+.Ql \&..
+in it.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er EACCES
+Write permission is denied on the directory containing the link
+to be removed.
+.It Bq Er EPERM
+The directory containing the directory to be removed is marked sticky,
+and neither the containing directory nor the directory to be removed
+are owned by the effective user ID.
+.It Bq Er EBUSY
+The directory to be removed is the mount point
+for a mounted file system.
+.It Bq Er EIO
+An I/O error occurred while deleting the directory entry
+or deallocating the inode.
+.It Bq Er EROFS
+The directory entry to be removed resides on a read-only file system.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.El
+.Sh SEE ALSO
+.Xr mkdir 2 ,
+.Xr unlink 2
+.Sh HISTORY
+The
+.Fn rmdir
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/rtprio.2 b/lib/libc/sys/rtprio.2
new file mode 100644
index 0000000..579ed1b
--- /dev/null
+++ b/lib/libc/sys/rtprio.2
@@ -0,0 +1,110 @@
+.\" Copyright (c) 1994, Henrik Vestergaard Draboel
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Henrik Vestergaard Draboel.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 23, 1994
+.Dt RTPRIO 2
+.Sh NAME
+.Nm rtprio
+.Nd examine or modify a process realtime or idle priority
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/rtprio.h>
+.Ft int
+.Fn rtprio "int function" "pid_t pid" "struct rtprio *rtp"
+.Sh DESCRIPTION
+.Fn rtprio
+is used to lookup or change the realtime or idle priority of a process.
+
+.Fa function
+specifies the operation to be performed. RTP_LOOKUP to lookup the current priority,
+and RTP_SET to set the priority.
+.Fa pid
+specifies the process to be used, 0 for the current process.
+
+.Fa *rtp
+is a pointer to a struct rtprio which is used to specify the priority and priority type.
+This structure has the following form:
+.Bd -literal
+struct rtprio {
+ u_short type;
+ u_short prio;
+};
+.Ed
+.Pp
+The value of the
+.Nm type
+field may be RTP_PRIO_REALTIME for realtime priorities,
+RTP_PRIO_NORMAL for normal priorities, and RTP_PRIO_IDLE for idle priorities.
+The priority specified by the
+.Nm prio
+field ranges between 0 and
+.Dv RTP_PRIO_MAX (usually 31) .
+0 is the highest possible priority.
+
+Realtime and idle priority is inherited through fork() and exec().
+
+A realtime process can only be preempted by a process of equal or
+higher priority, or by an interrupt; idle priority processes will run only
+when no other real/normal priority process is runnable. Higher real/idle priority processes
+preempt lower real/idle priority processes. Processes of equal real/idle priority are run round-robin.
+.Sh RETURN VALUES
+.Fn rtprio
+will return 0 for success and -1 for all errors. The global variable
+.Va errno
+will be set to indicate the error.
+.Sh ERRORS
+.Fn rtprio
+will fail if
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The specified
+.Fa prio
+was out of range.
+.It Bq Er EPERM
+The calling process is not allowed to set the realtime priority. Only
+root is allowed to change the realtime priority of any process, and non-root
+may only change the idle priority of the current process.
+.It Bq Er ESRCH
+The specified process was not found.
+.Sh AUTHORS
+The original author was
+.An Henrik Vestergaard Draboel Aq hvd@terry.ping.dk .
+This implementation in
+.Fx
+was substantially rewritten by
+.An David Greenman .
+.Sh SEE ALSO
+.Xr nice 1 ,
+.Xr ps 1 ,
+.Xr rtprio 1 ,
+.Xr setpriority 2 ,
+.Xr nice 3 ,
+.Xr renice 8
diff --git a/lib/libc/sys/sched_get_priority_max.2 b/lib/libc/sys/sched_get_priority_max.2
new file mode 100644
index 0000000..185f561
--- /dev/null
+++ b/lib/libc/sys/sched_get_priority_max.2
@@ -0,0 +1,121 @@
+.\" $FreeBSD$
+.\" Copyright (c) 1998 HD Associates, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd Mar 12, 1998
+.Dt SCHED_GET_PRIORITY_MAX 2
+.Os BSD 4
+.Sh NAME
+.Nm sched_get_priority_max ,
+.Nm sched_get_priority_min ,
+.Nm sched_rr_get_interval
+.Nd Get scheduling parameter limits
+.Sh SYNOPSIS
+.Fd #include <sched.h>
+.Ft int
+.Fn sched_get_priority_max "int policy"
+.Ft int
+.Fn sched_get_priority_min "int policy"
+.Ft int
+.Fn sched_rr_get_interval "pid_t pid" "struct timespec *interval"
+.Sh DESCRIPTION
+The
+.Fn sched_get_priority_max
+and
+.Fn sched_get_priority_min
+functions return the appropriate maximum or minimum, respectfully,
+for the scheduling policy specified by policy. The
+.Fn sched_rr_get_interval
+function updates the
+.Fa timespec
+structure referenced by the
+.Fa interval
+argument to contain the current execution time limit (i.e., time
+quantum) for the process specified by
+.Fa pid .
+If
+.Fa pid
+is zero, the current execution time limit for the calling process is
+returned.
+.Pp
+The value of
+.Fa policy
+should be one of the scheduling policy values defined in
+.Fa <sched.h> :
+.Bl -tag -width [SCHED_OTHER]
+.It Bq Er SCHED_FIFO
+First-in-first-out fixed priority scheduling with no round robin scheduling;
+.It Bq Er SCHED_OTHER
+The standard time sharing scheduler;
+.It Bq Er SCHED_RR
+Round-robin scheduling across same priority processes.
+.El
+.Sh RETURN
+If successful, the
+.Fn sched_get_priority_max
+and
+.Fn sched_get_priority_min
+functions shall return the appropriate maximum or minimum values,
+respectively. If unsuccessful, the shall return a value of -1 and set
+.Fa errno
+to indicate the error.
+.Pp
+If successful, the
+.Fn sched_rr_get_interval
+function will return 0. Otherwise, it will
+return a value of -1 and set
+.Fa errno
+to indicate the error.
+.Sh ERRORS
+On failure
+.Va errno
+will be set to the corresponding value:
+.Bl -tag -width [EFAULT]
+.It Bq Er EINVAL
+The value of the
+.Fa policy
+parameter does not represent a defined scheduling policy.
+.It Bq Er ENOSYS
+The
+.Fn sched_get_priority_max ,
+.Fn sched_get_priority_min ,
+and
+.Fn sched_rr_get_interval
+functions are not supported by the implementation.
+.It Bq Er ESRCH
+No process can be found corresponding to that specified by
+.Fa pid .
+.El
+.Sh SEE ALSO
+.Xr sched_get_scheduler 2 ,
+.Xr sched_getparam 2 ,
+.Xr sched_set_scheduler 2 ,
+.Xr sched_setparam 2
+.Sh STANDARDS
+The
+.Fn sched_setscheduler
+and
+.Fn sched_getscheduler
+functions conform to
+.St -p1003.1b-93 .
diff --git a/lib/libc/sys/sched_setparam.2 b/lib/libc/sys/sched_setparam.2
new file mode 100644
index 0000000..b627e69
--- /dev/null
+++ b/lib/libc/sys/sched_setparam.2
@@ -0,0 +1,172 @@
+.\" $FreeBSD$
+.\" Copyright (c) 1998 HD Associates, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd Mar 12, 1998
+.Dt SCHED_SETPARAM 2
+.Os BSD 4
+.Sh NAME
+.Nm sched_setparam ,
+.Nm sched_getparam
+.Nd set/get scheduling parameters
+.Sh SYNOPSIS
+.Fd #include <sched.h>
+.Ft int
+.Fn sched_setparam "pid_t pid" "const struct sched_param *param"
+.Ft int
+.Fn sched_getparam "pid_t pid" "struct sched_param *param"
+.Sh DESCRIPTION
+The
+.Fn sched_setparam
+function sets the scheduling parameters of the process specified by
+.Fa pid
+to the values specified by the
+.Fa sched_param
+structure pointed to by
+.Fa param .
+The value of the
+.Fa sched_priority
+member in the
+.Fa param
+structure must be any integer within the inclusive priority range for
+the current scheduling policy of the process specified by
+.Fa pid .
+Higher numerical values for the priority represent higher priorities.
+.Pp
+In this implementation, if the value of
+.Fa pid
+is negative the function will fail.
+.Pp
+If a process specified by
+.Fa pid
+exists and if the calling process has permission, the scheduling
+parameters are set for the process whose process ID is equal to
+.Fa pid .
+.Pp
+If
+.Fa pid
+is zero, the scheduling parameters are set for the calling process.
+.Pp
+In this implementation, the policy of when a process can affect
+the scheduling parameters of another process is specified in
+.Xr p1003_1b
+as a write-style operation.
+.Pp
+The target process, whether it is running or not running, will resume
+execution after all other runnable processes of equal or greater
+priority have been scheduled to run.
+.Pp
+If the priority of the process specified by the
+.Fa pid
+argument is set higher than that of the lowest priority running process
+and if the specified process is ready to run, the process specified by
+the
+.Fa pid
+argument will preempt a lowest priority running process. Similarly, if
+the process calling
+.Fn sched_setparam
+sets its own priority lower than that of one or more other nonempty
+process lists, then the process that is the head of the highest priority
+list will also preempt the calling process. Thus, in either case, the
+originating process might not receive notification of the completion of
+the requested priority change until the higher priority process has
+executed.
+.Pp
+In this implementation, when the current scheduling policy for the
+process specified by
+.Fa pid
+is normal timesharing (SCHED_OTHER, aka SCHED_NORMAL when not POSIX-source)
+or the idle policy (SCHED_IDLE when not POSIX-source) then the behavior
+is as if the process had been running under SCHED_RR with a priority
+lower than any actual realtime priority.
+.Pp
+The
+.Fn sched_getparam
+function will return the scheduling parameters of a process specified
+by
+.Fa pid
+in the
+.Fa sched_param
+structure pointed to by
+.Fa param .
+.Pp
+If a process specified by
+.Fa pid
+exists and if the calling process has permission,
+the scheduling parameters for the process whose process ID is equal to
+.Fa pid
+are returned.
+.Pp
+In this implementation, the policy of when a process can obtain the
+scheduling parameters of another process are detailed in
+.Xr p1003_1b
+as a read-style operation.
+.Pp
+If
+.Fa pid
+is zero, the scheduling parameters for the calling process will be
+returned. In this implementation, the
+.Fa sched_getparam
+function will fail if
+.Fa pid
+is negative.
+.Sh RETURN
+The function will return zero if it completes successfully, or it
+will return a value of -1 and set
+.Va errno
+to indicate the error.
+.Sh ERRORS
+On failure
+.Va errno
+will be set to the corresponding value:
+.Bl -tag -width [EFAULT]
+.It Bq Er ENOSYS
+The system is not configured to support this functionality.
+.It Bq Er EPERM
+The requesting process doesn not have permission as detailed in
+.Xr p1003_1b .
+.It Bq Er ESRCH
+No process can be found corresponding to that specified by
+.Fa pid .
+.It Bq Er EINVAL
+For
+.Fn sched_setparam :
+one or more of the requested scheduling parameters
+is outside the range defined for the scheduling policy of the specified
+.Fa pid .
+.El
+.Sh SEE ALSO
+.Xr sched_get_priority_max 2 ,
+.Xr sched_get_priority_min 2 ,
+.Xr sched_getscheduler 2 ,
+.Xr sched_rr_get_interval 2 ,
+.Xr sched_setscheduler 2 ,
+.Xr sched_yield 2
+.Sh STANDARDS
+The
+.Fn sched_setparam
+and
+.Fn sched_getparam
+functions conform to
+.St -p1003.1b-93 .
diff --git a/lib/libc/sys/sched_setscheduler.2 b/lib/libc/sys/sched_setscheduler.2
new file mode 100644
index 0000000..94d9f57
--- /dev/null
+++ b/lib/libc/sys/sched_setscheduler.2
@@ -0,0 +1,167 @@
+.\" $FreeBSD$
+.\" Copyright (c) 1998 HD Associates, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd Mar 12, 1998
+.Dt SCHED_SETSCHEDULER 2
+.Os BSD 4
+.Sh NAME
+.Nm sched_setscheduler ,
+.Nm sched_getscheduler
+.Nd set/get scheduling policy and scheduler parameters
+.Sh SYNOPSIS
+.Fd #include <sched.h>
+.Ft int
+.Fn sched_setscheduler "pid_t pid" "int policy" "const struct sched_param *param"
+.Ft int
+.Fn sched_getscheduler "pid_t pid"
+.Sh DESCRIPTION
+The
+.Fn sched_setscheduler
+function sets the scheduling policy and scheduling parameters
+of the process specified by
+.Fa pid
+to
+.Fa policy
+and the parameters specified in the
+.Fa sched_param
+structure pointed to by
+.Fa param ,
+respectively.
+The value of the
+.Fa sched_priority
+member in the
+.Fa param
+structure must be any integer within the inclusive priority range for
+the scheduling policy specified by
+.Fa policy .
+.Pp
+In this implementation, if the value of
+.Fa pid
+is negative the function will fail.
+.Pp
+If a process specified by
+.Fa pid
+exists and if the calling process has permission, the scheduling
+policy and scheduling parameters will be set for the process
+whose process ID is equal to
+.Fa pid .
+.Pp
+If
+.Fa pid
+is zero, the scheduling policy and scheduling
+parameters are set for the calling process.
+.Pp
+In this implementation, the policy of when a process can affect
+the scheduling parameters of another process is specified in
+.Xr p1003_1b
+as a write-style operation.
+.Pp
+The scheduling policies are in
+.Fa <sched.h> :
+.Bl -tag -width [SCHED_OTHER]
+.It Bq Er SCHED_FIFO
+First-in-first-out fixed priority scheduling with no round robin scheduling;
+.It Bq Er SCHED_OTHER
+The standard time sharing scheduler;
+.It Bq Er SCHED_RR
+Round-robin scheduling across same priority processes.
+.El
+.Pp
+The
+.Fa sched_param
+structure is defined in
+.Fa <sched.h> :
+
+.Bd -literal -offset indent
+struct sched_param {
+ int sched_priority; /* scheduling priority */
+};
+.Ed
+.Pp
+The
+.Fn sched_getscheduler
+function returns the scheduling policy of the process specified
+by
+.Fa pid .
+.Pp
+If a process specified by
+.Fa pid
+exists and if the calling process has permission,
+the scheduling parameters for the process whose process ID is equal to
+.Fa pid
+are returned.
+.Pp
+In this implementation, the policy of when a process can obtain the
+scheduling parameters of another process are detailed in
+.Xr p1003_1b
+as a read-style operation.
+.Pp
+If
+.Fa pid
+is zero, the scheduling parameters for the calling process will be
+returned. In this implementation, the
+.Fa sched_getscheduler
+function will fail if
+.Fa pid
+is negative.
+.Sh RETURN
+The function will return zero if it completes successfully, or it
+will return a value of -1 and set
+.Va errno
+to indicate the error.
+.Sh ERRORS
+On failure
+.Va errno
+will be set to the corresponding value:
+.Bl -tag -width [EFAULT]
+.It Bq Er ENOSYS
+The system is not configured to support this functionality.
+.It Bq Er EPERM
+The requesting process doesn not have permission as detailed in
+.Xr p1003_1b .
+.It Bq Er ESRCH
+No process can be found corresponding to that specified by
+.Fa pid .
+.It Bq Er EINVAL
+The value of the
+.Fa policy
+parameter is invalid, or one or more of the parameters contained in
+.Fa param
+is outside the valid range for the specified scheduling policy.
+.El
+.Sh SEE ALSO
+.Xr sched_get_priority_max 2 ,
+.Xr sched_get_priority_min 2 ,
+.Xr sched_getparam 2 ,
+.Xr sched_rr_get_interval 2 ,
+.Xr sched_setparam 2 ,
+.Xr sched_yield 2
+.Sh STANDARDS
+The
+.Fn sched_setscheduler
+and
+.Fn sched_getscheduler
+functions conform to
+.St -p1003.1b-93 .
diff --git a/lib/libc/sys/sched_yield.2 b/lib/libc/sys/sched_yield.2
new file mode 100644
index 0000000..28ac9cc
--- /dev/null
+++ b/lib/libc/sys/sched_yield.2
@@ -0,0 +1,59 @@
+.\" $FreeBSD$
+.\" Copyright (c) 1998 HD Associates, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd Mar 12, 1998
+.Dt SCHED_YIELD 2
+.Os BSD 4
+.Sh NAME
+.Nm sched_yield
+.Nd yield processor
+.Sh SYNOPSIS
+.Fd #include <sched.h>
+.Ft int
+.Fn sched_yield void
+.Sh DESCRIPTION
+The
+.Fn sched_yield
+function forces the running process to relinquish the processor until it
+again becomes the head of its process list. It takes no arguments.
+.Sh RETURN
+The
+.Fn sched_yield
+function will return zero if it completes successfully, or it
+will return a value of -1 and set
+.Va errno
+to indicate the error.
+.Sh ERRORS
+On failure
+.Va errno
+will be set to the corresponding value:
+.Bl -tag -width [EFAULT]
+.It Bq Er ENOSYS
+The system is not configured to support this functionality.
+.Sh STANDARDS
+The
+.Fn sched_yield
+function conforms to
+.St -p1003.1b-93 .
diff --git a/lib/libc/sys/select.2 b/lib/libc/sys/select.2
new file mode 100644
index 0000000..938f0ec
--- /dev/null
+++ b/lib/libc/sys/select.2
@@ -0,0 +1,194 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)select.2 8.2 (Berkeley) 3/25/94
+.\" $FreeBSD$
+.\"
+.Dd March 25, 1994
+.Dt SELECT 2
+.Os BSD 4.2
+.Sh NAME
+.Nm select
+.Nd synchronous I/O multiplexing
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/time.h>
+.Fd #include <unistd.h>
+.Ft int
+.Fn select "int nfds" "fd_set *readfds" "fd_set *writefds" "fd_set *exceptfds" "struct timeval *timeout"
+.Fn FD_SET fd &fdset
+.Fn FD_CLR fd &fdset
+.Fn FD_ISSET fd &fdset
+.Fn FD_ZERO &fdset
+.Sh DESCRIPTION
+.Fn Select
+examines the I/O descriptor sets whose addresses are passed in
+.Fa readfds ,
+.Fa writefds ,
+and
+.Fa exceptfds
+to see if some of their descriptors
+are ready for reading, are ready for writing, or have an exceptional
+condition pending, respectively.
+The only exceptional condition detectable is out-of-band
+data received on a socket.
+The first
+.Fa nfds
+descriptors are checked in each set;
+i.e., the descriptors from 0 through
+.Fa nfds Ns No -1
+in the descriptor sets are examined.
+On return,
+.Fn select
+replaces the given descriptor sets
+with subsets consisting of those descriptors that are ready
+for the requested operation.
+.Fn Select
+returns the total number of ready descriptors in all the sets.
+.Pp
+The descriptor sets are stored as bit fields in arrays of integers.
+The following macros are provided for manipulating such descriptor sets:
+.Fn FD_ZERO &fdset
+initializes a descriptor set
+.Fa fdset
+to the null set.
+.Fn FD_SET fd &fdset
+includes a particular descriptor
+.Fa fd
+in
+.Fa fdset .
+.Fn FD_CLR fd &fdset
+removes
+.Fa fd
+from
+.Fa fdset .
+.Fn FD_ISSET fd &fdset
+is non-zero if
+.Fa fd
+is a member of
+.Fa fdset ,
+zero otherwise.
+The behavior of these macros is undefined if
+a descriptor value is less than zero or greater than or equal to
+.Dv FD_SETSIZE ,
+which is normally at least equal
+to the maximum number of descriptors supported by the system.
+.Pp
+If
+.Fa timeout
+is a non-nil pointer, it specifies a maximum interval to wait for the
+selection to complete. If
+.Fa timeout
+is a nil pointer, the select blocks indefinitely. To effect a poll, the
+.Fa timeout
+argument should be non-nil, pointing to a zero-valued timeval structure.
+.Pp
+Any of
+.Fa readfds ,
+.Fa writefds ,
+and
+.Fa exceptfds
+may be given as nil pointers if no descriptors are of interest.
+.Sh RETURN VALUES
+.Fn Select
+returns the number of ready descriptors that are contained in
+the descriptor sets,
+or -1 if an error occurred.
+If the time limit expires,
+.Fn select
+returns 0.
+If
+.Fn select
+returns with an error,
+including one due to an interrupted call,
+the descriptor sets will be unmodified.
+.Sh ERRORS
+An error return from
+.Fn select
+indicates:
+.Bl -tag -width Er
+.It Bq Er EBADF
+One of the descriptor sets specified an invalid descriptor.
+.It Bq Er EINTR
+A signal was delivered before the time limit expired and
+before any of the selected events occurred.
+.It Bq Er EINVAL
+The specified time limit is invalid. One of its components is
+negative or too large.
+.It Bq Er EINVAL
+.Fa nfds
+was invalid.
+.El
+.Sh SEE ALSO
+.Xr accept 2 ,
+.Xr connect 2 ,
+.Xr getdtablesize 2 ,
+.Xr gettimeofday 2 ,
+.Xr read 2 ,
+.Xr recv 2 ,
+.Xr send 2 ,
+.Xr write 2 ,
+.Xr clocks 7
+.Sh NOTES
+The default size of
+.Dv FD_SETSIZE
+is currently 1024.
+In order to accommodate programs which might potentially
+use a larger number of open files with
+.Fn select
+, it is possible
+to increase this size by having the program define
+.Dv FD_SETSIZE
+before the inclusion of any header which includes
+.Aq Pa sys/types.h .
+.Pp
+If
+.Fa nfds
+is greater than the number of open files,
+.Fn select
+is not guaranteed to examine the unused file descriptors. For historical
+reasons,
+.Fn select
+will always examine the first 256 descriptors.
+.Sh BUGS
+.Fn select
+should probably return the time remaining from the original timeout,
+if any, by modifying the time value in place.
+This may be implemented in future versions of the system.
+Thus, it is unwise to assume that the timeout value will be unmodified
+by the
+.Fn select
+call.
+.Sh HISTORY
+The
+.Fn select
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/semctl.2 b/lib/libc/sys/semctl.2
new file mode 100644
index 0000000..1983f86
--- /dev/null
+++ b/lib/libc/sys/semctl.2
@@ -0,0 +1,177 @@
+.\"
+.\" Copyright (c) 1995 David Hovemeyer <daveho@infocom.com>
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 12, 1995
+.Dt SEMCTL 2
+.Os FreeBSD
+.Sh NAME
+.Nm semctl
+.Nd control operations on a semaphore set
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/ipc.h>
+.Fd #include <sys/sem.h>
+.Ft int
+.Fn semctl "int semid" "int semnum" "int cmd" ...
+.Sh DESCRIPTION
+.Fn Semctl
+performs the operation indicated by
+.Fa cmd
+on the semaphore set indicated by
+.Fa semid .
+A fourth argument, a
+.Fa "union semun arg" ,
+is required for certain values of
+.Fa cmd .
+For the commands that use the
+.Fa arg
+parameter,
+.Fa "union semun"
+is defined as follows:
+.Bd -literal
+.\"
+.\" From <sys/sem.h>:
+.\"
+union semun {
+ int val; /* value for SETVAL */
+ struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
+ u_short *array; /* array for GETALL & SETALL */
+};
+.Ed
+.Pp
+Commands are performed as follows:
+.\"
+.\" This section based on Stevens, _Advanced Programming in the UNIX
+.\" Environment_.
+.\"
+.Bl -tag -width IPC_RMIDXXX
+.It Dv IPC_STAT
+Fetch the semaphore set's
+.Fa "struct semid_ds" ,
+storing it in the memory pointed to by
+.Fa arg.buf .
+.It Dv IPC_SET
+Changes the
+.Fa sem_perm.uid ,
+.Fa sem_perm.gid ,
+and
+.Fa sem_perm.mode
+members of the semaphore set's
+.Fa "struct semid_ds"
+to match those of the struct pointed to by
+.Fa arg.buf .
+The calling process's effective uid must
+match either
+.Fa sem_perm.uid
+or
+.Fa sem_perm.cuid ,
+or it must have superuser privileges.
+.It IPC_RMID
+Immediately removes the semaphore set from the system. The calling
+process's effective uid must equal the semaphore set's
+.Fa sem_perm.uid
+or
+.Fa sem_perm.cuid ,
+or the process must have superuser privileges.
+.It Dv GETVAL
+Return the value of semaphore number
+.Fa semnum .
+.It Dv SETVAL
+Set the value of semaphore number
+.Fa semnum
+to
+.Fa arg.val .
+.It Dv GETPID
+Return the pid of the last process to perform an operation on
+semaphore number
+.Fa semnum .
+.It Dv GETNCNT
+Return the number of processes waiting for semaphore number
+.Fa semnum Ns 's
+value to become greater than its current value.
+.It Dv GETZCNT
+Return the number of processes waiting for semaphore number
+.Fa semnum Ns 's
+value to become 0.
+.It Dv GETALL
+Fetch the value of all of the semaphores in the set into the
+array pointed to by
+.Fa arg.array .
+.It Dv SETALL
+Set the values of all of the semaphores in the set to the values
+in the array pointed to by
+.Fa arg.array .
+.El
+.Pp
+The
+.Fa "struct semid_ds"
+is defined as follows:
+.Bd -literal
+.\"
+.\" Taken straight from <sys/sem.h>.
+.\"
+struct semid_ds {
+ struct ipc_perm sem_perm; /* operation permission struct */
+ struct sem *sem_base; /* pointer to first semaphore in set */
+ u_short sem_nsems; /* number of sems in set */
+ time_t sem_otime; /* last operation time */
+ long sem_pad1; /* SVABI/386 says I need this here */
+ time_t sem_ctime; /* last change time */
+ /* Times measured in secs since */
+ /* 00:00:00 GMT, Jan. 1, 1970 */
+ long sem_pad2; /* SVABI/386 says I need this here */
+ long sem_pad3[4]; /* SVABI/386 says I need this here */
+};
+.Ed
+.Sh RETURN VALUES
+On success, when
+.Fa cmd
+is one of GETVAL, GETNCNT, or GETZCNT,
+.Fn semctl
+returns the corresponding value; otherwise, 0 is returned.
+On failure, -1 is returned, and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Semctl
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+No semaphore set corresponds to
+.Fa semid .
+.It Bq Er EINVAL
+.Fa semnum
+is not in the range of valid semaphores for given semaphore set.
+.It Bq Er EPERM
+The calling process's effective uid does not match the uid of
+the semaphore set's owner or creator.
+.It Bq Er EACCES
+Permission denied due to mismatch between operation and mode of
+semaphore set.
+.Sh SEE ALSO
+.Xr semget 2 ,
+.Xr semop 2
diff --git a/lib/libc/sys/semget.2 b/lib/libc/sys/semget.2
new file mode 100644
index 0000000..edb0c87
--- /dev/null
+++ b/lib/libc/sys/semget.2
@@ -0,0 +1,138 @@
+.\"
+.\" Copyright (c) 1995 David Hovemeyer <daveho@infocom.com>
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 12, 1995
+.Dt SEMGET 2
+.Os FreeBSD
+.Sh NAME
+.Nm semget
+.Nd obtain a semaphore id
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/ipc.h>
+.Fd #include <sys/sem.h>
+.Ft int
+.Fn semget "key_t key" "int nsems" "int flag"
+.Sh DESCRIPTION
+Based on the values of
+.Fa key
+and
+.Fa flag ,
+.Fn semget
+returns the identifier of a newly created or previously existing
+set of semaphores.
+.\"
+.\" This is copied verbatim from the shmget manpage. Perhaps
+.\" it should go in a common manpage, such as .Xr ipc 2
+.\"
+The key
+is analogous to a filename: it provides a handle that names an
+IPC object. There are three ways to specify a key:
+.Bl -bullet
+.It
+IPC_PRIVATE may be specified, in which case a new IPC object
+will be created.
+.It
+An integer constant may be specified. If no IPC object corresponding
+to
+.Fa key
+is specified and the IPC_CREAT bit is set in
+.Fa flag ,
+a new one will be created.
+.It
+.Fn ftok
+may be used to generate a key from a pathname. See
+.Xr ftok 3 .
+.El
+.\"
+.\" Likewise for this section, except SHM_* becomes SEM_*.
+.\"
+.Pp
+The mode of a newly created IPC object is determined by
+.Em OR Ns 'ing
+the following constants into the
+.Fa flag
+parameter:
+.Bl -tag -width XSEM_WXX6XXX
+.It Dv SEM_R
+Read access for user.
+.It Dv SEM_A
+Alter access for user.
+.It Dv (SEM_R>>3)
+Read access for group.
+.It Dv (SEM_A>>3)
+Alter access for group.
+.It Dv (SEM_R>>6)
+Read access for other.
+.It Dv (SEM_A>>6)
+Alter access for other.
+.El
+.Pp
+If a new set of semaphores is being created,
+.Fa nsems
+is used to indicate the number of semaphores the set should contain.
+Otherwise,
+.Fa nsems
+may be specified as 0.
+.Sh RETURN VALUES
+.Fn Semget
+returns the id of a semaphore set if successful; otherwise, -1
+is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Semget
+will fail if:
+.Bl -tag -width Er
+.\" ipcperm could fail (we're opening to read and write, as it were)
+.It Bq Er EACCES
+Access permission failure.
+.\"
+.\" sysv_sem.c is quite explicit about these, so I'm pretty sure
+.\" this is accurate
+.\"
+.It Bq Er EEXIST
+IPC_CREAT and IPC_EXCL were specified, and a semaphore set
+corresponding to
+.Fa key
+already exists.
+.It Bq Er EINVAL
+The number of semaphores requested exceeds the system imposed maximum
+per set.
+.It Bq Er ENOSPC
+Insufficiently many semaphores are available.
+.It Bq Er ENOSPC
+The kernel could not allocate a
+.Fa "struct semid_ds" .
+.It Bq Er ENOENT
+No semaphore set was found corresponding to
+.Fa key ,
+and IPC_CREAT was not specified.
+.Sh SEE ALSO
+.Xr semctl 2 ,
+.Xr semop 2 ,
+.Xr ftok 3
diff --git a/lib/libc/sys/semop.2 b/lib/libc/sys/semop.2
new file mode 100644
index 0000000..abae921
--- /dev/null
+++ b/lib/libc/sys/semop.2
@@ -0,0 +1,192 @@
+.\"
+.\" Copyright (c) 1995 David Hovemeyer <daveho@infocom.com>
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 22, 1995
+.Dt SEMOP 2
+.Os FreeBSD
+.Sh NAME
+.Nm semop
+.Nd atomic array of operations on a semaphore set
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/ipc.h>
+.Fd #include <sys/sem.h>
+.Ft int
+.Fn semop "int semid" "struct sembuf array[]" "unsigned nops"
+.Sh DESCRIPTION
+.Fn Semop
+atomically performs the array of operations indicated by
+.Fa array
+on the semaphore set indicated by
+.Fa semid .
+The length of
+.Fa array
+is indicated by
+.Fa nops .
+Each operation is encoded in a
+.Fa "struct sembuf" ,
+which is defined as follows:
+.Bd -literal
+.\"
+.\" From <sys/sem.h>
+.\"
+struct sembuf {
+ u_short sem_num; /* semaphore # */
+ short sem_op; /* semaphore operation */
+ short sem_flg; /* operation flags */
+};
+.Ed
+.Pp
+For each element in
+.Fa array ,
+.Fa sem_op
+and
+.Fa sem_flg
+determine an operation to be performed on semaphore number
+.Fa sem_num
+in the set. The values SEM_UNDO and IPC_NOWAIT may be
+.Em OR Ns 'ed
+into the
+.Fa sem_flg
+member in order to modify the behavior of the given operation.
+.Pp
+The operation performed depends as follows on the value of
+.Fa sem_op :
+.\"
+.\" This section is based on the description of semop() in
+.\" Stevens, _Advanced Programming in the UNIX Environment_.
+.\"
+.Bl -bullet
+.It
+When
+.Fa sem_op
+is positive, the semaphore's value is incremented by
+.Fa sem_op Ns 's
+value. If SEM_UNDO is specified, the semaphore's adjust on exit
+value is decremented by
+.Fa sem_op Ns 's
+value. A positive value for
+.Fa sem_op
+generally corresponds to a process releasing a resource
+associated with the semaphore.
+.It
+The behavior when
+.Fa sem_op
+is negative depends on the current value of the semaphore:
+.Bl -bullet
+.It
+If the current value of the semaphore is greater than or equal to
+the absolute value of
+.Fa sem_op ,
+then the value is decremented by the absolute value of
+.Fa sem_op .
+If SEM_UNDO is specified, the semaphore's adjust on exit
+value is incremented by the absolute value of
+.Fa sem_op .
+.It
+If the current value of the semaphore is less than
+.Fa sem_op Ns 's
+value, one of the following happens:
+.\" XXX a *second* sublist?
+.Bl -bullet
+.It
+If IPC_NOWAIT was specified, then
+.Fn semop
+returns immediately with a return value of EAGAIN.
+.It
+If some other process has removed the semaphore with the IPC_RMID
+option of
+.Fn semctl ,
+then
+.Fn semop
+returns immediately with a return value of EINVAL.
+.It
+Otherwise, the calling process is put to sleep until the semaphore's
+value is greater than or equal to the absolute value of
+.Fa sem_op .
+When this condition becomes true, the semaphore's value is decremented
+by the absolute value of
+.Fa sem_op ,
+and the semaphore's adjust on exit value is incremented by the
+absolute value of
+.Fa sem_op .
+.El
+.Pp
+A negative value for
+.Fa sem_op
+generally means that a process is waiting for a resource to become
+available.
+.El
+.Pp
+.It
+When
+.Fa sem_op
+is zero, the process waits for the semaphore's value to become zero.
+If it is already zero, the call to
+.Fn semop
+can return immediately. Otherwise, the calling process is put to
+sleep until the semaphore's value becomes zero.
+.El
+.Pp
+For each semaphore a process has in use, the kernel maintains an
+`adjust on exit' value, as alluded to earlier. When a process
+exits, either voluntarily or involuntarily, the adjust on exit value
+for each semaphore is added to the semaphore's value. This can
+be used to insure that a resource is released if a process terminates
+unexpectedly.
+.Sh RETURN VALUES
+On success,
+.Fn semop
+returns 0; otherwise, -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Semop
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+No semaphore set corresponds to
+.Fa semid .
+.It Bq Er EACCES
+Permission denied due to mismatch between operation and mode of
+semaphore set.
+.It Bq Er EAGAIN
+The semaphore's value was less than
+.Fa sem_op ,
+and IPC_NOWAIT was specified.
+.It Bq Er E2BIG
+Too many operations were specified.
+.It Bq Er EFBIG
+.\"
+.\" I'd have thought this would be EINVAL, but the source says
+.\" EFBIG.
+.\"
+.Fa sem_num
+was not in the range of valid semaphores for the set.
+.Sh SEE ALSO
+.Xr semctl 2 ,
+.Xr semget 2
diff --git a/lib/libc/sys/send.2 b/lib/libc/sys/send.2
new file mode 100644
index 0000000..327307c
--- /dev/null
+++ b/lib/libc/sys/send.2
@@ -0,0 +1,198 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94
+.\" $FreeBSD$
+.\"
+.Dd February 15, 1995
+.Dt SEND 2
+.Os BSD 4.2
+.Sh NAME
+.Nm send ,
+.Nm sendto ,
+.Nm sendmsg
+.Nd send a message from a socket
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft ssize_t
+.Fn send "int s" "const void *msg" "size_t len" "int flags"
+.Ft ssize_t
+.Fn sendto "int s" "const void *msg" "size_t len" "int flags" "const struct sockaddr *to" "socklen_t tolen"
+.Ft ssize_t
+.Fn sendmsg "int s" "const struct msghdr *msg" "int flags"
+.Sh DESCRIPTION
+.Fn Send ,
+.Fn sendto ,
+and
+.Fn sendmsg
+are used to transmit a message to another socket.
+.Fn Send
+may be used only when the socket is in a
+.Em connected
+state, while
+.Fn sendto
+and
+.Fn sendmsg
+may be used at any time.
+.Pp
+The address of the target is given by
+.Fa to
+with
+.Fa tolen
+specifying its size.
+The length of the message is given by
+.Fa len .
+If the message is too long to pass atomically through the
+underlying protocol, the error
+.Er EMSGSIZE
+is returned, and
+the message is not transmitted.
+.Pp
+No indication of failure to deliver is implicit in a
+.Fn send .
+Locally detected errors are indicated by a return value of -1.
+.Pp
+If no messages space is available at the socket to hold
+the message to be transmitted, then
+.Fn send
+normally blocks, unless the socket has been placed in
+non-blocking I/O mode.
+The
+.Xr select 2
+call may be used to determine when it is possible to
+send more data.
+.Pp
+The
+.Fa flags
+parameter may include one or more of the following:
+.Bd -literal
+#define MSG_OOB 0x1 /* process out-of-band data */
+#define MSG_PEEK 0x2 /* peek at incoming message */
+#define MSG_DONTROUTE 0x4 /* bypass routing, use direct interface */
+#define MSG_EOR 0x8 /* data completes record */
+#define MSG_EOF 0x100 /* data completes transaction */
+.Ed
+.Pp
+The flag
+.Dv MSG_OOB
+is used to send
+.Dq out-of-band
+data on sockets that support this notion (e.g.
+.Dv SOCK_STREAM ) ;
+the underlying protocol must also support
+.Dq out-of-band
+data.
+.Dv MSG_EOR
+is used to indicate a record mark for protocols which support the
+concept.
+.Dv MSG_EOF
+requests that the sender side of a socket be shut down, and that an
+appropriate indication be sent at the end of the specified data;
+this flag is only implemented for
+.Dv SOCK_STREAM
+sockets in the
+.Dv PF_INET
+protocol family, and is used to implement Transaction
+.Tn TCP
+(see
+.Xr ttcp 4 ) .
+.Dv MSG_DONTROUTE
+is usually used only by diagnostic or routing programs.
+.Pp
+See
+.Xr recv 2
+for a description of the
+.Fa msghdr
+structure.
+.Sh RETURN VALUES
+The call returns the number of characters sent, or -1
+if an error occurred.
+.Sh ERRORS
+.Fn Send ,
+.Fn sendto ,
+and
+.Fn sendmsg
+fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+An invalid descriptor was specified.
+.It Bq Er EACCES
+The destination address is a broadcast address, and
+.Dv SO_BROADCAST
+has not been set on the socket.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is not a socket.
+.It Bq Er EFAULT
+An invalid user space address was specified for a parameter.
+.It Bq Er EMSGSIZE
+The socket requires that message be sent atomically,
+and the size of the message to be sent made this impossible.
+.It Bq Er EAGAIN
+The socket is marked non-blocking and the requested operation
+would block.
+.It Bq Er ENOBUFS
+The system was unable to allocate an internal buffer.
+The operation may succeed when buffers become available.
+.It Bq Er ENOBUFS
+The output queue for a network interface was full.
+This generally indicates that the interface has stopped sending,
+but may be caused by transient congestion.
+.It Bq Er EHOSTUNREACH
+The remote host was unreachable.
+.El
+.Sh BUGS
+Because
+.Fn sendmsg
+doesn't necessarily block until the data has been transferred, it
+is possible to transfer an open file descriptor across an
+.Dv AF_UNIX
+domain socket
+.Pq see Xr recv 2 ,
+then
+.Fn close
+it before it has actually been sent, the result being that the receiver
+gets a closed file descriptor. It is left to the application to
+implement an acknowlegment mechanism to prevent this from happening.
+.Sh SEE ALSO
+.Xr fcntl 2 ,
+.Xr getsockopt 2 ,
+.Xr recv 2 ,
+.Xr select 2 ,
+.Xr socket 2 ,
+.Xr write 2
+.Sh HISTORY
+The
+.Fn send
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/sendfile.2 b/lib/libc/sys/sendfile.2
new file mode 100644
index 0000000..87b9bac
--- /dev/null
+++ b/lib/libc/sys/sendfile.2
@@ -0,0 +1,155 @@
+.\" Copyright (c) 1998, David Greenman
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice unmodified, this list of conditions, and the following
+.\" disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd November 5, 1998
+.Dt SENDFILE 2
+.Os
+.Sh NAME
+.Nm sendfile
+.Nd send a file to a socket
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Fd #include <sys/uio.h>
+.Ft int
+.Fn sendfile "int fd" "int s" "off_t offset" "size_t nbytes" "struct sf_hdtr *hdtr" "off_t *sbytes" "int flags"
+.Sh DESCRIPTION
+.Fn Sendfile
+sends a regular file specified by descriptor
+.Fa fd
+out a stream socket specified by descriptor
+.Fa s .
+.Pp
+The
+.Fa offset
+argument specifies where to begin in the file. The
+.Fa nbytes
+argument specifies how many bytes of the file should be sent, with 0 having the special
+meaning of send until the end of file has been reached.
+.Pp
+An optional header and/or trailer can be sent before and after the file data by specifying
+a pointer to a struct sf_hdtr, which has the following structure:
+.Pp
+.Bd -literal -offset indent -compact
+struct sf_hdtr {
+ struct iovec *headers; /* pointer to header iovecs */
+ int hdr_cnt; /* number of header iovecs */
+ struct iovec *trailers; /* pointer to trailer iovecs */
+ int trl_cnt; /* number of trailer iovecs */
+};
+.Ed
+.Pp
+The
+.Fa headers
+and
+.Fa tailers
+pointers, if non-NULL, point to arrays of struct iovec structures. See the
+.Fn writev
+system call for information on the iovec structure. The number of iovecs in these
+arrays is specified by
+.Fa hdr_cnt
+and
+.Fa trl_cnt .
+.Pp
+If non-NULL, the system will write the total number of bytes sent on the socket to the
+variable pointed to by
+.Fa sbytes .
+.Pp
+The
+.Fa flags
+argument is currently undefined and should be specified as 0.
+.Pp
+When using a socket marked for non-blocking I/O,
+.Fn sendfile
+may send fewer bytes than requested. In this case, the number of bytes successfully
+written is returned in
+.Fa *sbytes
+(if specified),
+and the error
+.Er EAGAIN
+is returned.
+.Sh IMPLEMENTATION NOTES
+.Pp
+The FreeBSD implementation of
+.Fn sendfile
+is "zero-copy", meaning that it has been optimized so that copying of the file data is avoided.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn sendfile
+returns 0. Otherwise a -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa fd
+is not a valid file descriptor.
+.It Bq Er EBADF
+.Fa s
+is not a valid socket descriptor.
+.It Bq Er ENOTSOCK
+.Fa s
+is not a socket.
+.It Bq Er EINVAL
+.Fa fd
+is not a regular file.
+.It Bq Er EINVAL
+.Fa s
+is not a SOCK_STREAM type socket.
+.It Bq Er EINVAL
+.Fa offset
+is negative or out of range.
+.It Bq Er ENOTCONN
+.Fa s
+points to an unconnected socket.
+.It Bq Er EPIPE
+The socket peer has closed the connection.
+.It Bq Er EIO
+An error occurred while reading from
+.Fa fd .
+.It Bq Er EFAULT
+An invalid address was specified for a parameter.
+.It Bq Er EAGAIN
+The socket is marked for non-blocking I/O and not all data was sent due to the socket buffer being filled.
+If specified, the number of bytes successfully sent will be returned in
+.Fa *sbytes .
+.El
+.Sh SEE ALSO
+.Xr open 2 ,
+.Xr send 2 ,
+.Xr socket 2 ,
+.Xr writev 2
+.Sh HISTORY
+.Fn sendfile
+first appeared in
+.Fx 3.0 .
+This manual page first appeared in
+.Fx 3.1 .
+.Sh AUTHORS
+.Fn sendfile
+and this manual page were written by
+.An David Greenman Aq dg@root.com .
diff --git a/lib/libc/sys/setgroups.2 b/lib/libc/sys/setgroups.2
new file mode 100644
index 0000000..f11cbd56
--- /dev/null
+++ b/lib/libc/sys/setgroups.2
@@ -0,0 +1,84 @@
+.\" Copyright (c) 1983, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)setgroups.2 8.2 (Berkeley) 4/16/94
+.\" $FreeBSD$
+.\"
+.Dd April 16, 1994
+.Dt SETGROUPS 2
+.Os BSD 4.2
+.Sh NAME
+.Nm setgroups
+.Nd set group access list
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <unistd.h>
+.Ft int
+.Fn setgroups "int ngroups" "const gid_t *gidset"
+.Sh DESCRIPTION
+.Fn Setgroups
+sets the group access list of the current user process
+according to the array
+.Fa gidset .
+The parameter
+.Fa ngroups
+indicates the number of entries in the array and must be no
+more than
+.Dv NGROUPS ,
+as defined in
+.Ao Pa sys/param.h Ac .
+.Pp
+Only the super-user may set new groups.
+.Sh RETURN VALUES
+A 0 value is returned on success, -1 on error, with
+an error code stored in
+.Va errno .
+.Sh ERRORS
+The
+.Fn setgroups
+call will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The caller is not the super-user.
+.It Bq Er EFAULT
+The address specified for
+.Fa gidset
+is outside the process
+address space.
+.El
+.Sh SEE ALSO
+.Xr getgroups 2 ,
+.Xr initgroups 3
+.Sh HISTORY
+The
+.Fn setgroups
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/setpgid.2 b/lib/libc/sys/setpgid.2
new file mode 100644
index 0000000..19af6f7
--- /dev/null
+++ b/lib/libc/sys/setpgid.2
@@ -0,0 +1,91 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)setpgid.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SETPGID 2
+.Os BSD 4
+.Sh NAME
+.Nm setpgid ,
+.Nm setpgrp
+.Nd set process group
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn setpgid "pid_t pid" "pid_t pgrp"
+.Ft int
+.Fn setpgrp "pid_t pid" "pid_t pgrp"
+.Sh DESCRIPTION
+.Fn Setpgid
+sets the process group of the specified process
+.Ar pid
+to the specified
+.Ar pgrp .
+If
+.Ar pid
+is zero, then the call applies to the current process.
+.Pp
+If the invoker is not the super-user, then the affected process
+must have the same effective user-id as the invoker or be a descendant
+of the invoking process.
+.Sh RETURN VALUES
+.Fn Setpgid
+returns 0 when the operation was successful.
+If the request failed, -1 is returned and the global variable
+.Va errno
+indicates the reason.
+.Sh ERRORS
+.Fn Setpgid
+will fail and the process group will not be altered if:
+.Bl -tag -width indent
+.It Bq Er ESRCH
+The requested process does not exist.
+.It Bq Er EPERM
+The effective user ID of the requested process is different
+from that of the caller and the process is not a descendent
+of the calling process.
+.El
+.Sh SEE ALSO
+.Xr getpgrp 2
+.Sh STANDARDS
+The
+.Fn setpgid
+function call is expected to conform to
+.St -p1003.1-90 .
+.Sh COMPATIBILITY
+.Fn Setpgrp
+is identical to
+.Fn setpgid ,
+and is retained for calling convention compatibility with historical
+versions of
+.Bx .
diff --git a/lib/libc/sys/setregid.2 b/lib/libc/sys/setregid.2
new file mode 100644
index 0000000..1802e6e
--- /dev/null
+++ b/lib/libc/sys/setregid.2
@@ -0,0 +1,93 @@
+.\" Copyright (c) 1980, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)setregid.2 8.2 (Berkeley) 4/16/94
+.\" $FreeBSD$
+.\"
+.Dd April 16, 1994
+.Dt SETREGID 2
+.Os BSD 4.2
+.Sh NAME
+.Nm setregid
+.Nd set real and effective group ID
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn setregid "gid_t rgid" "gid_t egid"
+.Sh DESCRIPTION
+The real and effective group ID's of the current process
+are set to the arguments.
+Unprivileged users may change the real group
+ID to the effective group ID and vice-versa; only the super-user may
+make other changes.
+.Pp
+Supplying a value of -1 for either the real or effective
+group ID forces the system to substitute the current
+ID in place of the -1 parameter.
+.Pp
+The
+.Fn setregid
+function was intended to allow swapping
+the real and effective group IDs
+in set-group-ID programs to temporarily relinquish the set-group-ID value.
+This function did not work correctly,
+and its purpose is now better served by the use of the
+.Fn setegid
+function (see
+.Xr setuid 2 ) .
+.Pp
+When setting the real and effective group IDs to the same value,
+the standard
+.Fn setgid
+function is preferred.
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned. Otherwise,
+a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Bl -tag -width [EPERM]
+.It Bq Er EPERM
+The current process is not the super-user and a change
+other than changing the effective group-id to the real group-id
+was specified.
+.El
+.Sh SEE ALSO
+.Xr getgid 2 ,
+.Xr issetugid 2 ,
+.Xr setegid 2 ,
+.Xr setgid 2 ,
+.Xr setuid 2
+.Sh HISTORY
+The
+.Fn setregid
+system call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/setreuid.2 b/lib/libc/sys/setreuid.2
new file mode 100644
index 0000000..32d35ee
--- /dev/null
+++ b/lib/libc/sys/setreuid.2
@@ -0,0 +1,91 @@
+.\" Copyright (c) 1980, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)setreuid.2 8.2 (Berkeley) 4/16/94
+.\" $FreeBSD$
+.\"
+.Dd April 16, 1994
+.Dt SETREUID 2
+.Os BSD 4
+.Sh NAME
+.Nm setreuid
+.Nd set real and effective user ID's
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn setreuid "uid_t ruid" "uid_t euid"
+.Sh DESCRIPTION
+The real and effective user IDs of the
+current process are set according to the arguments.
+If
+.Fa ruid
+or
+.Fa euid
+is -1, the current uid is filled in by the system.
+Unprivileged users may change the real user
+ID to the effective user ID and vice-versa; only the super-user may
+make other changes.
+.Pp
+The
+.Fn setreuid
+function has been used to swap the real and effective user IDs
+in set-user-ID programs to temporarily relinquish the set-user-ID value.
+This purpose is now better served by the use of the
+.Fn seteuid
+function (see
+.Xr setuid 2 ) .
+.Pp
+When setting the real and effective user IDs to the same value,
+the standard
+.Fn setuid
+function is preferred.
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned. Otherwise,
+a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Bl -tag -width [EPERM]
+.It Bq Er EPERM
+The current process is not the super-user and a change
+other than changing the effective user-id to the real user-id
+was specified.
+.El
+.Sh SEE ALSO
+.Xr getuid 2 ,
+.Xr issetugid 2 ,
+.Xr seteuid 2 ,
+.Xr setuid 2
+.Sh HISTORY
+The
+.Fn setreuid
+system call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/setsid.2 b/lib/libc/sys/setsid.2
new file mode 100644
index 0000000..631cc13
--- /dev/null
+++ b/lib/libc/sys/setsid.2
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)setsid.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SETSID 2
+.Os
+.Sh NAME
+.Nm setsid
+.Nd create session and set process group ID
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft pid_t
+.Fn setsid void
+.Sh DESCRIPTION
+The
+.Fn setsid
+function creates a new session.
+The calling process is the session leader of the new session, is the
+process group leader of a new process group and has no controlling
+terminal.
+The calling process is the only process in either the session or the
+process group.
+.Sh RETURN VALUES
+Upon successful completion, the
+.Fn setsid
+function returns the value of the process group ID of the new process
+group, which is the same as the process ID of the calling process.
+If an error occurs,
+.Fn setsid
+returns -1 and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn setsid
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The calling process is already a process group leader, or the process
+group ID of a process other than the calling process matches the process
+ID of the calling process.
+.El
+.Sh SEE ALSO
+.Xr setpgid 2 ,
+.Xr tcgetpgrp 3 ,
+.Xr tcsetpgrp 3
+.Sh STANDARDS
+The
+.Fn setsid
+function is expected to be compliant with the
+.St -p1003.1-90
+specification.
diff --git a/lib/libc/sys/setuid.2 b/lib/libc/sys/setuid.2
new file mode 100644
index 0000000..0fc6890
--- /dev/null
+++ b/lib/libc/sys/setuid.2
@@ -0,0 +1,161 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)setuid.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SETUID 2
+.Os BSD 4.2
+.Sh NAME
+.Nm setuid ,
+.Nm seteuid ,
+.Nm setgid ,
+.Nm setegid ,
+.Nd set user and group ID
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <unistd.h>
+.Ft int
+.Fn setuid "uid_t uid"
+.Ft int
+.Fn seteuid "uid_t euid"
+.Ft int
+.Fn setgid "gid_t gid"
+.Ft int
+.Fn setegid "gid_t egid"
+.Sh DESCRIPTION
+The
+.Fn setuid
+function
+sets the real and effective
+user IDs and the saved set-user-ID of the current process
+to the specified value.
+.\" Comment out next block for !_POSIX_SAVED_IDS
+.\" The real user ID and the saved set-user-ID are changed only if the
+.\" effective user ID is that of the super user.
+.\" I.e.
+.\" .Fn setuid
+.\" function is equal to
+.\" .Fn seteuid
+.\" function if the effective user ID is not that of the super user.
+.\" End of block
+The
+.Fn setuid
+function is permitted if the specified ID is equal to the real user ID
+.\" Comment out next line for !_POSIX_SAVED_IDS
+.\" or the saved set-user-ID
+.\" Next line is for Appendix B.4.2.2 case.
+or the effective user ID
+of the process, or if the effective user ID is that of the super user.
+.Pp
+The
+.Fn setgid
+function
+sets the real and effective
+group IDs and the saved set-group-ID of the current process
+to the specified value.
+.\" Comment out next block for !_POSIX_SAVED_IDS
+.\" The real group ID and the saved set-group-ID are changed only if the
+.\" effective user ID is that of the super user.
+.\" I.e.
+.\" .Fn setgid
+.\" function is equal to
+.\" .Fn setegid
+.\" function if the effective user ID is not that of the super user.
+.\" End of block
+The
+.Fn setgid
+function is permitted if the specified ID is equal to the real group ID
+.\" Comment out next line for !_POSIX_SAVED_IDS
+.\" or the saved set-group-ID
+.\" Next line is for Appendix B.4.2.2 case.
+or the effective group ID
+of the process, or if the effective user ID is that of the super user.
+.Pp
+The
+.Fn seteuid
+function
+.Pq Fn setegid
+sets the effective user ID (group ID) of the
+current process.
+The effective user ID may be set to the value
+of the real user ID or the saved set-user-ID (see
+.Xr intro 2
+and
+.Xr execve 2 ) ;
+in this way, the effective user ID of a set-user-ID executable
+may be toggled by switching to the real user ID, then re-enabled
+by reverting to the set-user-ID value.
+Similarly, the effective group ID may be set to the value
+of the real group ID or the saved set-user-ID.
+.Pp
+.Sh RETURN VALUES
+Upon success, these functions return 0;
+otherwise \-1 is returned.
+.Pp
+If the user is not the super user, or the uid
+specified is not the real, effective ID, or saved ID,
+these functions return \-1.
+.Sh SEE ALSO
+.Xr getgid 2 ,
+.Xr getuid 2 ,
+.Xr issetugid 2 ,
+.Xr setregid 2 ,
+.Xr setreuid 2
+.Sh STANDARDS
+The
+.Fn setuid
+and
+.Fn setgid
+functions are compliant with the
+.St -p1003.1-90
+specification with
+.Li _POSIX_SAVED_IDS
+.\" Uncomment next line for !_POSIX_SAVED_IDS
+not
+defined with the permitted extensions from Appendix B.4.2.2.
+The
+.Fn seteuid
+and
+.Fn setegid
+functions are extensions based on the
+.Tn POSIX
+concept of
+.Li _POSIX_SAVED_IDS ,
+and have been proposed for a future revision of the standard.
+.Sh HISTORY
+A
+.Fn setuid
+and a
+.Fn setgid
+function calls appeared in
+.At v7 .
diff --git a/lib/libc/sys/shmat.2 b/lib/libc/sys/shmat.2
new file mode 100644
index 0000000..331a4c9
--- /dev/null
+++ b/lib/libc/sys/shmat.2
@@ -0,0 +1,111 @@
+.\"
+.\" Copyright (c) 1995 David Hovemeyer <daveho@infocom.com>
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 2, 1995
+.Dt SHMAT 2
+.Os FreeBSD
+.Sh NAME
+.Nm shmat ,
+.Nm shmdt
+.Nd attach or detach shared memory
+.Sh SYNOPSIS
+.Fd #include <machine/param.h>
+.Fd #include <sys/types.h>
+.Fd #include <sys/ipc.h>
+.Fd #include <sys/shm.h>
+.Ft void *
+.Fn shmat "int shmid" "void *addr" "int flag"
+.Ft int
+.Fn shmdt "void *addr"
+.Sh DESCRIPTION
+.Fn Shmat
+attaches the shared memory segment identified by
+.Fa shmid
+to the calling process's address space. The address where the segment
+is attached is determined as follows:
+.\"
+.\" These are cribbed almost exactly from Stevens, _Advanced Programming in
+.\" the UNIX Environment_.
+.\"
+.Bl -bullet
+.It
+If
+.Fa addr
+is 0, the segment is attached at an address selected by the
+kernel.
+.It
+If
+.Fa addr
+is nonzero and SHM_RND is not specified in
+.Fa flag ,
+the segment is attached the specified address.
+.It
+If
+.Fa addr
+is specified and SHM_RND is specified,
+.Fa addr
+is rounded down to the nearest multiple of SHMLBA.
+.El
+.Pp
+.Fn Shmdt
+detaches the shared memory segment at the address specified by
+.Fa addr
+from the calling process's address space.
+.Sh RETURN VALUES
+Upon success,
+.Fn shmat
+returns the address where the segment is attached; otherwise, -1
+is returned and
+.Va errno
+is set to indicate the error.
+.Pp
+Upon success,
+.Fn shmdt
+returns 0; otherwise, -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Shmat
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+No shared memory segment was found corresponding to
+.Fa shmid .
+.It Bq Er EINVAL
+.Fa addr
+was not an acceptable address.
+.El
+.Pp
+.Fn Shmdt
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+.Fa addr
+does not point to a shared memory segment.
+.Sh "SEE ALSO"
+.Xr shmctl 2 ,
+.Xr shmget 2
diff --git a/lib/libc/sys/shmctl.2 b/lib/libc/sys/shmctl.2
new file mode 100644
index 0000000..e24d226
--- /dev/null
+++ b/lib/libc/sys/shmctl.2
@@ -0,0 +1,137 @@
+.\"
+.\" Copyright (c) 1995 David Hovemeyer <daveho@infocom.com>
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 17, 1995
+.Dt SHMCTL 2
+.Os FreeBSD
+.Sh NAME
+.Nm shmctl
+.Nd shared memory control
+.Sh SYNOPSIS
+.Fd #include <machine/param.h>
+.Fd #include <sys/types.h>
+.Fd #include <sys/ipc.h>
+.Fd #include <sys/shm.h>
+.Ft int
+.Fn shmctl "int shmid" "int cmd" "struct shmid_ds *buf"
+.Sh DESCRIPTION
+Performs the action specified by
+.Fa cmd
+on the shared memory segment identified by
+.Fa shmid :
+.Bl -tag -width SHM_UNLOCKX
+.It Dv IPC_STAT
+Fetch the segment's
+.Fa "struct shmid_ds" ,
+storing it in the memory pointed to by
+.Fa buf .
+.\"
+.\" XXX need to make sure that this is correct for FreeBSD
+.\"
+.It Dv IPC_SET
+Changes the
+.Fa shm_perm.uid ,
+.Fa shm_perm.gid ,
+and
+.Fa shm_perm.mode
+members of the segment's
+.Fa "struct shmid_ds"
+to match those of the struct pointed to by
+.Fa buf .
+The calling process's effective uid must
+match either
+.Fa shm_perm.uid
+or
+.Fa shm_perm.cuid ,
+or it must have superuser privileges.
+.It Dv IPC_RMID
+Removes the segment from the system. The removal will not take
+effect until all processes having attached the segment have exited;
+however, once the IPC_RMID operation has taken place, no further
+processes will be allowed to attach the segment. For the operation
+to succeed, the calling process's effective uid must match
+.Fa shm_perm.uid
+or
+.Fa shm_perm.cuid ,
+or the process must have superuser privileges.
+.\" .It Dv SHM_LOCK
+.\" Locks the segment in memory. The calling process must have
+.\" superuser privileges. Not implemented in FreeBSD.
+.\" .It Dv SHM_UNLOCK
+.\" Unlocks the segment from memory. The calling process must
+.\" have superuser privileges. Not implemented in FreeBSD.
+.El
+.Pp
+The
+.Fa shmid_ds
+struct is defined as follows:
+.\"
+.\" I fiddled with the spaces a bit to make it fit well when viewed
+.\" with nroff, but otherwise it's straight from sys/shm.h
+.\"
+.Bd -literal
+struct shmid_ds {
+ struct ipc_perm shm_perm; /* operation permission structure */
+ int shm_segsz; /* size of segment in bytes */
+ pid_t shm_lpid; /* process ID of last shared memory op */
+ pid_t shm_cpid; /* process ID of creator */
+ short shm_nattch; /* number of current attaches */
+ time_t shm_atime; /* time of last shmat() */
+ time_t shm_dtime; /* time of last shmdt() */
+ time_t shm_ctime; /* time of last change by shmctl() */
+ void *shm_internal; /* sysv stupidity */
+};
+.Ed
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn shmctl
+returns 0. Otherwise, it returns -1 and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Shmctl
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+Invalid operation, or
+no shared memory segment was found corresponding to
+.Fa shmid .
+.\"
+.\" XXX I think the following is right: ipcperm() only returns EPERM
+.\" when an attempt is made to modify (IPC_M) by a non-creator
+.\" non-owner
+.It Bq Er EPERM
+The calling process's effective uid does not match the uid of
+the shared memory segment's owner or creator.
+.It Bq Er EACCES
+Permission denied due to mismatch between operation and mode of
+shared memory segment.
+.Sh "SEE ALSO"
+.Xr shmat 2 ,
+.Xr shmdt 2 ,
+.Xr shmget 2 ,
+.Xr ftok 3
diff --git a/lib/libc/sys/shmget.2 b/lib/libc/sys/shmget.2
new file mode 100644
index 0000000..db5917f
--- /dev/null
+++ b/lib/libc/sys/shmget.2
@@ -0,0 +1,139 @@
+.\"
+.\" Copyright (c) 1995 David Hovemeyer <daveho@infocom.com>
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 3, 1995
+.Dt SHMGET 2
+.Os FreeBSD
+.Sh NAME
+.Nm shmget
+.Nd obtain a shared memory identifier
+.Sh SYNOPSIS
+.Fd #include <machine/param.h>
+.Fd #include <sys/types.h>
+.Fd #include <sys/ipc.h>
+.Fd #include <sys/shm.h>
+.Ft int
+.Fn shmget "key_t key" "int size" "int flag"
+.Sh DESCRIPTION
+Based on the values of
+.Fa key
+and
+.Fa flag ,
+.Fn shmget
+returns the identifier of a newly created or previously existing shared
+memory segment.
+.\"
+.\" The following bit about keys and modes also applies to semaphores
+.\" and message queues.
+.\"
+The key
+is analogous to a filename: it provides a handle that names an
+IPC object. There are three ways to specify a key:
+.Bl -bullet
+.It
+IPC_PRIVATE may be specified, in which case a new IPC object
+will be created.
+.It
+An integer constant may be specified. If no IPC object corresponding
+to
+.Fa key
+is specified and the IPC_CREAT bit is set in
+.Fa flag ,
+a new one will be created.
+.It
+.Fn ftok
+may be used to generate a key from a pathname. See
+.Xr ftok 3 .
+.El
+.Pp
+The mode of a newly created IPC object is determined by
+.Em OR Ns 'ing
+the following constants into the
+.Fa flag
+parameter:
+.Bl -tag -width XSHM_WXX6XXX
+.It Dv SHM_R
+Read access for user.
+.It Dv SHM_W
+Write access for user.
+.It Dv (SHM_R>>3)
+Read access for group.
+.It Dv (SHM_W>>3)
+Write access for group.
+.It Dv (SHM_R>>6)
+Read access for other.
+.It Dv (SHM_W>>6)
+Write access for other.
+.El
+.\"
+.\" XXX - we should also mention how uid, euid, and gid affect ownership
+.\" and use
+.\"
+.\" end section about keys and modes
+.\"
+.Pp
+When creating a new shared memory segment,
+.Fa size
+indicates the desired size of the new segment in bytes. The size
+of the segment may be rounded up to a multiple convenient to the
+kernel (i.e., the page size).
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn shmget
+returns the positive integer identifier of a shared memory segment.
+Otherwise, -1 is returned and
+.Va errno
+set to indicate the error.
+.Sh ERRORS
+.Fn Shmget
+will fail if:
+.Bl -tag -width Er
+.\"
+.\" XXX What about ipcperm failing?
+.\"
+.It Bq Er EINVAL
+Size specified is greater than the size of the previously existing segment.
+Size specified is less than the system imposed minimum, or greater than
+the system imposed maximum.
+.It Bq Er ENOENT
+No shared memory segment was found matching
+.Fa key ,
+and IPC_CREAT was not specified.
+.It Bq Er ENOSPC
+The kernel was unable to allocate enough memory to
+satisfy the request.
+.It Bq Er EEXIST
+IPC_CREAT and IPC_EXCL were specified, and a shared memory segment
+corresponding to
+.Fa key
+already exists.
+.Pp
+.Sh "SEE ALSO"
+.Xr shmat 2 ,
+.Xr shmctl 2 ,
+.Xr shmdt 2 ,
+.Xr ftok 3
diff --git a/lib/libc/sys/shutdown.2 b/lib/libc/sys/shutdown.2
new file mode 100644
index 0000000..b35a55d
--- /dev/null
+++ b/lib/libc/sys/shutdown.2
@@ -0,0 +1,100 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)shutdown.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SHUTDOWN 2
+.Os BSD 4.2
+.Sh NAME
+.Nm shutdown
+.Nd shut down part of a full-duplex connection
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft int
+.Fn shutdown "int s" "int how"
+.Sh DESCRIPTION
+The
+.Fn shutdown
+call causes all or part of a full-duplex connection on
+the socket associated with
+.Fa s
+to be shut down.
+If
+.Fa how
+is
+.No Dv SHUT_RD Pq 0 ,
+further receives will be disallowed.
+If
+.Fa how
+is
+.No Dv SHUT_WR Pq 1 ,
+further sends will be disallowed.
+If
+.Fa how
+is
+.No Dv SHUT_RDWR Pq 2 ,
+further sends and receives will be disallowed.
+.Sh RETURN VALUES
+A 0 is returned if the call succeeds, -1 if it fails.
+.Sh ERRORS
+The call succeeds unless:
+.Bl -tag -width ENOTCONNAA
+.It Bq Er EBADF
+.Fa S
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+.Fa S
+is a file, not a socket.
+.It Bq Er ENOTCONN
+The specified socket is not connected.
+.El
+.Sh SEE ALSO
+.Xr connect 2 ,
+.Xr socket 2
+.Sh STANDARDS
+The
+.Fn shutdown
+function is expected to comply with
+.St -p1003.1g ,
+when finalized.
+.Sh HISTORY
+The
+.Fn shutdown
+function call appeared in
+.Bx 4.2 .
+The
+.Dv SHUT_
+constants appeared in
+.St -p1003.1g .
+
diff --git a/lib/libc/sys/sigaction.2 b/lib/libc/sys/sigaction.2
new file mode 100644
index 0000000..c3c41f7
--- /dev/null
+++ b/lib/libc/sys/sigaction.2
@@ -0,0 +1,577 @@
+.\" Copyright (c) 1980, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)sigaction.2 8.2 (Berkeley) 4/3/94
+.\" $FreeBSD$
+.\"
+.Dd April 3, 1994
+.Dt SIGACTION 2
+.Os
+.Sh NAME
+.Nm sigaction
+.Nd software signal facilities
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Bd -literal
+struct sigaction {
+ /*
+ * Signal handler function if flag SA_SIGINFO is not used and for
+ * SIG_DFL and SIG_IGN.
+ */
+ void (*sa_handler)(int);
+
+ /* Signal handler function if flag SA_SIGINFO is used */
+ void (*sa_sigaction)(int, siginfo_t *, void *);
+
+ sigset_t sa_mask; /* signal mask to apply */
+ int sa_flags; /* see signal options below */
+};
+.Ed
+.Ft int
+.Fn sigaction "int sig" "const struct sigaction *act" "struct sigaction *oact"
+.Sh DESCRIPTION
+The system defines a set of signals that may be delivered to a process.
+Signal delivery resembles the occurrence of a hardware interrupt:
+the signal is normally blocked from further occurrence, the current process
+context is saved, and a new one is built. A process may specify a
+.Em handler
+to which a signal is delivered, or specify that a signal is to be
+.Em ignored .
+A process may also specify that a default action is to be taken
+by the system when a signal occurs.
+A signal may also be
+.Em blocked ,
+in which case its delivery is postponed until it is
+.Em unblocked .
+The action to be taken on delivery is determined at the time
+of delivery.
+Normally, signal handlers execute on the current stack
+of the process. This may be changed, on a per-handler basis,
+so that signals are taken on a special
+.Em "signal stack" .
+.Pp
+Signal routines normally execute with the signal that caused their
+invocation
+.Em blocked ,
+but other signals may yet occur.
+A global
+.Em "signal mask"
+defines the set of signals currently blocked from delivery
+to a process. The signal mask for a process is initialized
+from that of its parent (normally empty). It
+may be changed with a
+.Xr sigprocmask 2
+call, or when a signal is delivered to the process.
+.Pp
+When a signal
+condition arises for a process, the signal is added to a set of
+signals pending for the process.
+If the signal is not currently
+.Em blocked
+by the process then it is delivered to the process.
+Signals may be delivered any time a process enters the operating system
+(e.g., during a system call, page fault or trap, or clock interrupt).
+If multiple signals are ready to be delivered at the same time,
+any signals that could be caused by traps are delivered first.
+Additional signals may be processed at the same time, with each
+appearing to interrupt the handlers for the previous signals
+before their first instructions.
+The set of pending signals is returned by the
+.Xr sigpending 2
+function.
+When a caught signal
+is delivered, the current state of the process is saved,
+a new signal mask is calculated (as described below),
+and the signal handler is invoked. The call to the handler
+is arranged so that if the signal handling routine returns
+normally the process will resume execution in the context
+from before the signal's delivery.
+If the process wishes to resume in a different context, then it
+must arrange to restore the previous context itself.
+.Pp
+When a signal is delivered to a process a new signal mask is
+installed for the duration of the process' signal handler
+(or until a
+.Xr sigprocmask
+call is made).
+This mask is formed by taking the union of the current signal mask set,
+the signal to be delivered, and
+the signal mask associated with the handler to be invoked.
+.Pp
+.Fn Sigaction
+assigns an action for a signal specified by
+.Fa sig .
+If
+.Fa act
+is non-zero, it
+specifies an action
+.Pf ( Dv SIG_DFL ,
+.Dv SIG_IGN ,
+or a handler routine) and mask
+to be used when delivering the specified signal.
+If
+.Fa oact
+is non-zero, the previous handling information for the signal
+is returned to the user.
+.Pp
+Once a signal handler is installed, it normally remains installed
+until another
+.Fn sigaction
+call is made, or an
+.Xr execve 2
+is performed.
+A signal-specific default action may be reset by
+setting
+.Fa sa_handler
+to
+.Dv SIG_DFL .
+The defaults are process termination, possibly with core dump;
+no action; stopping the process; or continuing the process.
+See the signal list below for each signal's default action.
+If
+.Fa sa_handler
+is
+.Dv SIG_DFL ,
+the default action for the signal is to discard the signal,
+and if a signal is pending,
+the pending signal is discarded even if the signal is masked.
+If
+.Fa sa_handler
+is set to
+.Dv SIG_IGN
+current and pending instances
+of the signal are ignored and discarded.
+.Pp
+Options may be specified by setting
+.Em sa_flags .
+The meaning of the various bits is as follows:
+.Bl -tag -offset indent -width SA_RESETHANDXX
+.It Dv SA_NOCLDSTOP
+If this bit is set when installing a catching function
+for the
+.Dv SIGCHLD
+signal,
+the
+.Dv SIGCHLD
+signal will be generated only when a child process exits,
+not when a child process stops.
+.It Dv SA_NOCLDWAIT
+If this bit is set when calling
+.Fn sigaction
+for the
+.Dv SIGCHLD
+signal, the system will not create zombie processes when children of
+the calling process exit. If the calling process subsequently issues
+a
+.Xr wait 2
+(or equivalent), it blocks until all of the calling process's child
+processes terminate, and then returns a value of -1 with errno set to
+.Dv ECHILD .
+.It Dv SA_ONSTACK
+If this bit is set, the system will deliver the signal to the process
+on a
+.Em "signal stack" ,
+specified with
+.Xr sigaltstack 2 .
+.It Dv SA_NODEFER
+If this bit is set, further occurrences of the delivered signal are
+not masked during the execution of the handler.
+.It Dv SA_RESETHAND
+If this bit is set, the handler is reset back to
+.Dv SIG_DFL
+at the moment the signal is delivered.
+.It Dv SA_SIGINFO
+If this bit is set, the handler function is assumed to be pointed to
+by the sa_sigaction member of struct sigaction and should match the
+prototype shown above or as below in
+.Sx EXAMPLES .
+This bit should not be set when assigning
+.Dv SIG_DFL
+or
+.Dv SIG_IGN .
+.El
+.Pp
+If a signal is caught during the system calls listed below,
+the call may be forced to terminate
+with the error
+.Dv EINTR ,
+the call may return with a data transfer shorter than requested,
+or the call may be restarted.
+Restart of pending calls is requested
+by setting the
+.Dv SA_RESTART
+bit in
+.Ar sa_flags .
+The affected system calls include
+.Xr open 2 ,
+.Xr read 2 ,
+.Xr write 2 ,
+.Xr sendto 2 ,
+.Xr recvfrom 2 ,
+.Xr sendmsg 2
+and
+.Xr recvmsg 2
+on a communications channel or a slow device (such as a terminal,
+but not a regular file)
+and during a
+.Xr wait 2
+or
+.Xr ioctl 2 .
+However, calls that have already committed are not restarted,
+but instead return a partial success (for example, a short read count).
+.Pp
+After a
+.Xr fork 2
+or
+.Xr vfork 2
+all signals, the signal mask, the signal stack,
+and the restart/interrupt flags are inherited by the child.
+.Pp
+.Xr Execve 2
+reinstates the default
+action for all signals which were caught and
+resets all signals to be caught on the user stack.
+Ignored signals remain ignored;
+the signal mask remains the same;
+signals that restart pending system calls continue to do so.
+.Pp
+The following is a list of all signals
+with names as in the include file
+.Aq Pa signal.h :
+.Bl -column SIGVTALARMXX "create core imagexxx"
+.It Sy " NAME " " Default Action " " Description"
+.It Dv SIGHUP No " terminate process" " terminal line hangup"
+.It Dv SIGINT No " terminate process" " interrupt program"
+.It Dv SIGQUIT No " create core image" " quit program"
+.It Dv SIGILL No " create core image" " illegal instruction"
+.It Dv SIGTRAP No " create core image" " trace trap"
+.It Dv SIGABRT No " create core image" Xr abort 3
+call (formerly
+.Dv SIGIOT )
+.It Dv SIGEMT No " create core image" " emulate instruction executed"
+.It Dv SIGFPE No " create core image" " floating-point exception"
+.It Dv SIGKILL No " terminate process" " kill program"
+.It Dv SIGBUS No " create core image" " bus error"
+.It Dv SIGSEGV No " create core image" " segmentation violation"
+.It Dv SIGSYS No " create core image" " non-existent system call invoked"
+.It Dv SIGPIPE No " terminate process" " write on a pipe with no reader"
+.It Dv SIGALRM No " terminate process" " real-time timer expired"
+.It Dv SIGTERM No " terminate process" " software termination signal"
+.It Dv SIGURG No " discard signal" " urgent condition present on socket"
+.It Dv SIGSTOP No " stop process" " stop (cannot be caught or ignored)"
+.It Dv SIGTSTP No " stop process" " stop signal generated from keyboard"
+.It Dv SIGCONT No " discard signal" " continue after stop"
+.It Dv SIGCHLD No " discard signal" " child status has changed"
+.It Dv SIGTTIN No " stop process" " background read attempted from control terminal"
+.It Dv SIGTTOU No " stop process" " background write attempted to control terminal"
+.It Dv SIGIO No " discard signal" Tn " I/O"
+is possible on a descriptor (see
+.Xr fcntl 2 )
+.It Dv SIGXCPU No " terminate process" " cpu time limit exceeded (see"
+.Xr setrlimit 2 )
+.It Dv SIGXFSZ No " terminate process" " file size limit exceeded (see"
+.Xr setrlimit 2 )
+.It Dv SIGVTALRM No " terminate process" " virtual time alarm (see"
+.Xr setitimer 2 )
+.It Dv SIGPROF No " terminate process" " profiling timer alarm (see"
+.Xr setitimer 2 )
+.It Dv SIGWINCH No " discard signal" " Window size change"
+.It Dv SIGINFO No " discard signal" " status request from keyboard"
+.It Dv SIGUSR1 No " terminate process" " User defined signal 1"
+.It Dv SIGUSR2 No " terminate process" " User defined signal 2"
+.El
+.Sh NOTE
+The
+.Fa sa_mask
+field specified in
+.Fa act
+is not allowed to block
+.Dv SIGKILL
+or
+.Dv SIGSTOP .
+Any attempt to do so will be silently ignored.
+.Pp
+The following functions are either reentrant or not interruptible
+by signals and are async-signal safe. Therefore applications may
+invoke them, without restriction, from signal-catching functions:
+.Pp
+Base Interfaces:
+.Pp
+.Fn _exit ,
+.Fn access ,
+.Fn alarm ,
+.Fn cfgetispeed ,
+.Fn cfgetospeed ,
+.Fn cfsetispeed ,
+.Fn cfsetospeed ,
+.Fn chdir ,
+.Fn chmod ,
+.Fn chown ,
+.Fn close ,
+.Fn creat ,
+.Fn dup ,
+.Fn dup2 ,
+.Fn execle ,
+.Fn execve ,
+.Fn fcntl ,
+.Fn fork ,
+.Fn fpathconf ,
+.Fn fstat ,
+.Fn fsync ,
+.Fn getegid ,
+.Fn geteuid ,
+.Fn getgid ,
+.Fn getgroups ,
+.Fn getpgrp ,
+.Fn getpid ,
+.Fn getppid ,
+.Fn getuid ,
+.Fn kill ,
+.Fn link ,
+.Fn lseek ,
+.Fn mkdir ,
+.Fn mkfifo ,
+.Fn open ,
+.Fn pathconf ,
+.Fn pause ,
+.Fn pipe ,
+.Fn raise ,
+.Fn read ,
+.Fn rename ,
+.Fn rmdir ,
+.Fn setgid ,
+.Fn setpgid ,
+.Fn setsid ,
+.Fn setuid ,
+.Fn sigaction ,
+.Fn sigaddset ,
+.Fn sigdelset ,
+.Fn sigemptyset ,
+.Fn sigfillset ,
+.Fn sigismember ,
+.Fn signal ,
+.Fn sigpending ,
+.Fn sigprocmask ,
+.Fn sigsuspend ,
+.Fn sleep ,
+.Fn stat ,
+.Fn sysconf ,
+.Fn tcdrain ,
+.Fn tcflow ,
+.Fn tcflush ,
+.Fn tcgetattr ,
+.Fn tcgetpgrp ,
+.Fn tcsendbreak ,
+.Fn tcsetattr ,
+.Fn tcsetpgrp ,
+.Fn time ,
+.Fn times ,
+.Fn umask ,
+.Fn uname ,
+.Fn unlink ,
+.Fn utime ,
+.Fn wait ,
+.Fn waitpid ,
+.Fn write .
+.Pp
+Realtime Interfaces:
+.Pp
+.Fn aio_error ,
+.Fn clock_gettime ,
+.Fn sigpause ,
+.Fn timer_getoverrun ,
+.Fn aio_return ,
+.Fn fdatasync ,
+.Fn sigqueue ,
+.Fn timer_gettime ,
+.Fn aio_suspend ,
+.Fn sem_post ,
+.Fn sigset ,
+.Fn timer_settime .
+.Pp
+All functions not in the above lists are considered to be unsafe
+with respect to signals. That is to say, the behaviour of such
+functions when called from a signal handler is undefined.
+.Sh RETURN VALUES
+A 0 value indicated that the call succeeded. A \-1 return value
+indicates an error occurred and
+.Va errno
+is set to indicated the reason.
+.Sh EXAMPLES
+There are three possible prototypes the handler may match:
+.Bl -tag -offset indent -width short
+.It ANSI C:
+.Fd
+void handler(int);
+.It Traditional BSD style:
+.Fd
+void handler(int, int code, struct sigcontext *scp);
+.It POSIX SA_SIGINFO:
+.Fd
+void handler(int, siginfo_t *info, void *context);
+.El
+.Pp
+The handler function should match the SA_SIGINFO prototype if the
+SA_SIGINFO bit is set in flags.
+It then should be pointed to by the
+.Dv sa_siginfo
+member of
+.Dv struct sigaction .
+Note that you should not assign SIG_DFL or SIG_IGN this way.
+.Pp
+If the SA_SIGINFO flag is not set, the handler function should match
+either the ANSI C or traditional BSD prototype and be pointed to by
+the
+.Dv sa_handler
+member of
+.Dv struct sigaction .
+In pratice,
+.Fx
+always sends the three arguments of the latter and since the ANSI C
+prototype is a subset, both will work.
+The
+.Dv sa_handler
+member declaration in
+.Fx
+include files is that of ANSI C (as required by POSIX),
+so a function pointer of a BSD-style function needs to be casted to
+compile without warning.
+The traditional BSD style is not portable and since its capabilities
+are a full subset of a SA_SIGINFO handler,
+its use is deprecated.
+.Pp
+The
+.Fa sig
+argument is the signal number, one of the
+.Dv SIG...
+values from <signal.h>.
+.Pp
+The
+.Fa code
+argument of the BSD-style handler and the
+.Dv si_code
+member of the
+.Dv info
+argument to a SA_SIGINFO handler contain a numeric code explaning the
+cause of the signal, usually one of the
+.Dv SI_...
+values from
+<sys/signal.h> or codes specific to a signal, i.e. one of the
+.Dv FPE_...
+values for SIGFPE.
+.Pp
+The
+.Fa scp
+argument to a BSD-style handler points to an instance of struct
+sigcontext.
+.Pp
+The
+.Fa context
+argument to a POSIX SA_SIGINFO handler points to an instance of
+mcontext_t.
+.Sh ERRORS
+.Fn Sigaction
+will fail and no new signal handler will be installed if one
+of the following occurs:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+Either
+.Fa act
+or
+.Fa oact
+points to memory that is not a valid part of the process
+address space.
+.It Bq Er EINVAL
+.Fa Sig
+is not a valid signal number.
+.It Bq Er EINVAL
+An attempt is made to ignore or supply a handler for
+.Dv SIGKILL
+or
+.Dv SIGSTOP .
+.El
+.Sh STANDARDS
+The
+.Fn sigaction
+function call is expected to conform to
+.St -p1003.1-90 .
+The
+.Dv SA_ONSTACK
+and
+.Dv SA_RESTART
+flags are Berkeley extensions,
+as are the signals,
+.Dv SIGTRAP ,
+.Dv SIGEMT ,
+.Dv SIGBUS ,
+.Dv SIGSYS ,
+.Dv SIGURG ,
+.Dv SIGIO ,
+.Dv SIGXCPU ,
+.Dv SIGXFSZ ,
+.Dv SIGVTALRM ,
+.Dv SIGPROF ,
+.Dv SIGWINCH ,
+and
+.Dv SIGINFO .
+Those signals are available on most
+.Tn BSD Ns \-derived
+systems.
+The
+.Dv SA_NODEFER
+and
+.Dv SA_RESETHAND
+flags are intended for backwards compatibility with other operating
+systems. The
+.Dv SA_NOCLDSTOP ,
+and
+.Dv SA_NOCLDWAIT
+.\" and
+.\" SA_SIGINFO
+flags are featuring options commonly found in other operating systems.
+.Sh SEE ALSO
+.Xr kill 1 ,
+.Xr kill 2 ,
+.Xr ptrace 2 ,
+.Xr sigaltstack 2 ,
+.Xr sigblock 2 ,
+.Xr sigpause 2 ,
+.Xr sigpending 2 ,
+.Xr sigprocmask 2 ,
+.Xr sigsetmask 2 ,
+.Xr sigsuspend 2 ,
+.Xr sigvec 2 ,
+.Xr wait 2 ,
+.Xr fpsetmask 3 ,
+.Xr setjmp 3 ,
+.Xr siginterrupt 3 ,
+.Xr sigsetops 3 ,
+.Xr tty 4
diff --git a/lib/libc/sys/sigaltstack.2 b/lib/libc/sys/sigaltstack.2
new file mode 100644
index 0000000..d16612c
--- /dev/null
+++ b/lib/libc/sys/sigaltstack.2
@@ -0,0 +1,165 @@
+.\" Copyright (c) 1983, 1991, 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sigaltstack.2 8.2 (Berkeley) 5/1/95
+.\" $FreeBSD$
+.\"
+.Dd May 1, 1995
+.Dt SIGALTSTACK 2
+.Os BSD 4.2
+.Sh NAME
+.Nm sigaltstack
+.Nd set and/or get signal stack context
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Bd -literal
+struct sigaltstack {
+ char *ss_sp;
+ size_t ss_size;
+ int ss_flags;
+};
+.Ed
+.Ft int
+.Fn sigaltstack "const struct sigaltstack *ss" "struct sigaltstack *oss"
+.Sh DESCRIPTION
+.Fn Sigaltstack
+allows users to define an alternate stack on which signals
+are to be processed.
+If
+.Fa ss
+is non-zero,
+it specifies a pointer to and the size of a
+.Em "signal stack"
+on which to deliver signals,
+and tells the system if the process is currently executing
+on that stack.
+When a signal's action indicates its handler
+should execute on the signal stack (specified with a
+.Xr sigaction 2
+call), the system checks to see
+if the process is currently executing on that stack.
+If the process is not currently executing on the signal stack,
+the system arranges a switch to the signal stack for the
+duration of the signal handler's execution.
+.Pp
+If
+.Dv SS_DISABLE
+is set in
+.Fa ss_flags ,
+.Fa ss_sp
+and
+.Fa ss_size
+are ignored and the signal stack will be disabled.
+Trying to disable an active stack will cause
+.Fn sigaltstack
+to return -1 with
+.Va errno
+set to
+.Dv EINVAL .
+A disabled stack will cause all signals to be
+taken on the regular user stack.
+If the stack is later re-enabled then all signals that were specified
+to be processed on an alternate stack will resume doing so.
+.Pp
+If
+.Fa oss
+is non-zero, the current signal stack state is returned.
+The
+.Fa ss_flags
+field will contain the value
+.Dv SS_ONSTACK
+if the process is currently on a signal stack and
+.Dv SS_DISABLE
+if the signal stack is currently disabled.
+.Sh NOTES
+The value
+.Dv SIGSTKSZ
+is defined to be the number of bytes/chars that would be used to cover
+the usual case when allocating an alternate stack area.
+The following code fragment is typically used to allocate an alternate stack.
+.Bd -literal -offset indent
+if ((sigstk.ss_sp = malloc(SIGSTKSZ)) == NULL)
+ /* error return */
+sigstk.ss_size = SIGSTKSZ;
+sigstk.ss_flags = 0;
+if (sigaltstack(&sigstk,0) < 0)
+ perror("sigaltstack");
+.Ed
+An alternative approach is provided for programs with signal handlers
+that require a specific amount of stack space other than the default size.
+The value
+.Dv MINSIGSTKSZ
+is defined to be the number of bytes/chars that is required by
+the operating system to implement the alternate stack feature.
+In computing an alternate stack size,
+programs should add
+.Dv MINSIGSTKSZ
+to their stack requirements to allow for the operating system overhead.
+.Pp
+Signal stacks are automatically adjusted for the direction of stack
+growth and alignment requirements.
+Signal stacks may or may not be protected by the hardware and
+are not ``grown'' automatically as is done for the normal stack.
+If the stack overflows and this space is not protected
+unpredictable results may occur.
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned.
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Sigaltstack
+will fail and the signal stack context will remain unchanged
+if one of the following occurs.
+.Bl -tag -width [ENOMEM]
+.It Bq Er EFAULT
+Either
+.Fa ss
+or
+.Fa oss
+points to memory that is not a valid part of the process
+address space.
+.It Bq Er EINVAL
+An attempt was made to disable an active stack.
+.It Bq Er ENOMEM
+Size of alternate stack area is less than or equal to
+.Dv MINSIGSTKSZ .
+.El
+.Sh SEE ALSO
+.Xr sigaction 2 ,
+.Xr setjmp 3
+.Sh HISTORY
+The predecessor to
+.Fn sigaltstack ,
+the
+.Fn sigstack
+system call, appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/sigpending.2 b/lib/libc/sys/sigpending.2
new file mode 100644
index 0000000..481bd19
--- /dev/null
+++ b/lib/libc/sys/sigpending.2
@@ -0,0 +1,73 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Berkeley Software Design, Inc.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sigpending.2 8.3 (Berkeley) 1/12/94
+.\" $FreeBSD$
+.\"
+.Dd January 12, 1994
+.Dt SIGPENDING 2
+.Os
+.Sh NAME
+.Nm sigpending
+.Nd get pending signals
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Ft int
+.Fn sigpending "sigset_t *set"
+.Sh DESCRIPTION
+The
+.Fn sigpending
+function returns a mask of the signals pending for delivery
+to the calling process in the location indicated by
+.Fa set .
+Signals may be pending because they are currently masked,
+or transiently before delivery (although the latter case is not
+normally detectable).
+.Sh RETURN VALUES
+A 0 value indicated that the call succeeded. A \-1 return value
+indicates an error occurred and
+.Va errno
+is set to indicated the reason.
+.Sh ERRORS
+The
+.Fn sigpending
+function does not currently detect any errors.
+.Sh SEE ALSO
+.Xr sigaction 2 ,
+.Xr sigprocmask 2
+.Sh STANDARDS
+The
+.Fn sigpending
+function call is expected to conform to
+.St -p1003.1-90 .
diff --git a/lib/libc/sys/sigprocmask.2 b/lib/libc/sys/sigprocmask.2
new file mode 100644
index 0000000..8f58f96
--- /dev/null
+++ b/lib/libc/sys/sigprocmask.2
@@ -0,0 +1,121 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sigprocmask.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SIGPROCMASK 2
+.Os
+.Sh NAME
+.Nm sigprocmask
+.Nd manipulate current signal mask
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Ft int
+.Fn sigprocmask "int how" "const sigset_t *set" "sigset_t *oset"
+.Sh DESCRIPTION
+The
+.Fn sigprocmask
+function examines and/or changes the current signal mask (those signals
+that are blocked from delivery).
+Signals are blocked if they are members of the current signal mask set.
+.Pp
+If
+.Fa set
+is not null, the action of
+.Fn sigprocmask
+depends on the value of the parameter
+.Fa how .
+The signal mask is changed as a function of the specified
+.Fa set
+and the current mask.
+The function is specified by
+.Fa how
+using one of the following values from
+.Aq Pa signal.h :
+.Bl -tag -width SIG_UNBLOCK
+.It Dv SIG_BLOCK
+The new mask is the union of the current mask and the specified
+.Fa set .
+.It Dv SIG_UNBLOCK
+The new mask is the intersection of the current mask
+and the complement of the specified
+.Fa set .
+.It Dv SIG_SETMASK
+The current mask is replaced by the specified
+.Fa set .
+.El
+.Pp
+If
+.Fa oset
+is not null, it is set to
+the previous value of the signal mask.
+When
+.Fa set
+is null,
+the value of
+.Ar how
+is insignificant and the mask remains unset
+providing a way to examine the signal mask without modification.
+.Pp
+The system
+quietly disallows
+.Dv SIGKILL
+or
+.Dv SIGSTOP
+to be blocked.
+.Sh RETURN VALUES
+A 0 value indicated that the call succeeded. A -1 return value
+indicates an error occurred and
+.Va errno
+is set to indicated the reason.
+.Sh ERRORS
+The
+.Fn sigprocmask
+call will fail and the signal mask will be unchanged if one
+of the following occurs:
+.Bl -tag -width Bq Er EINVAL
+.It Bq Er EINVAL
+.Fa how
+has a value other than those listed here.
+.Sh SEE ALSO
+.Xr kill 2 ,
+.Xr sigaction 2 ,
+.Xr sigsuspend 2 ,
+.Xr fpsetmask 3 ,
+.Xr sigsetops 3
+.Sh STANDARDS
+The
+.Fn sigprocmask
+function call is expected to
+conform to
+.St -p1003.1-90 .
diff --git a/lib/libc/sys/sigreturn.2 b/lib/libc/sys/sigreturn.2
new file mode 100644
index 0000000..f00e464
--- /dev/null
+++ b/lib/libc/sys/sigreturn.2
@@ -0,0 +1,113 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sigreturn.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SIGRETURN 2
+.Os BSD 4.3
+.Sh NAME
+.Nm sigreturn
+.Nd return from signal
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Pp
+.Bd -literal
+struct sigcontext {
+ int sc_onstack; /* sigstack state to restore */
+ int sc_mask; /* signal mask to restore */
+ int sc_esp; /* machine state */
+ int sc_ebp;
+ int sc_isp;
+ int sc_eip;
+ int sc_efl;
+ int sc_es;
+ int sc_ds;
+ int sc_cs;
+ int sc_ss;
+ int sc_edi;
+ int sc_esi;
+ int sc_ebx;
+ int sc_edx;
+ int sc_ecx;
+ int sc_eax;
+# define sc_sp sc_esp
+# define sc_fp sc_ebp
+# define sc_pc sc_eip
+# define sc_ps sc_efl
+};
+.Ed
+.Ft int
+.Fn sigreturn "struct sigcontext *scp"
+.Sh DESCRIPTION
+.Fn Sigreturn
+allows users to atomically unmask, switch stacks,
+and return from a signal context.
+The processes signal mask and stack status are
+restored from the context.
+The system call does not return;
+the users stack pointer, frame pointer, argument pointer,
+and processor status longword are restored from the context.
+Execution resumes at the specified pc.
+This system call is used by the trampoline code and
+.Xr longjmp 3
+when returning from a signal to the previously executing program.
+.Sh NOTES
+This system call is not available in 4.2
+.Tn BSD
+hence it should not be used if backward compatibility is needed.
+.Sh RETURN VALUES
+If successful, the system call does not return.
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Sigreturn
+will fail and the process context will remain unchanged
+if one of the following occurs.
+.Bl -tag -width [EINVAL]
+.It Bq Er EFAULT
+.Fa Scp
+points to memory that is not a valid part of the process
+address space.
+.It Bq Er EINVAL
+The process status longword is invalid or would improperly
+raise the privilege level of the process.
+.El
+.Sh SEE ALSO
+.Xr sigvec 2 ,
+.Xr setjmp 3
+.Sh HISTORY
+The
+.Fn sigreturn
+function call appeared in
+.Bx 4.3 .
diff --git a/lib/libc/sys/sigstack.2 b/lib/libc/sys/sigstack.2
new file mode 100644
index 0000000..404fc3e
--- /dev/null
+++ b/lib/libc/sys/sigstack.2
@@ -0,0 +1,52 @@
+.\" Copyright (c) 1983, 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sigstack.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SIGSTACK 2
+.Os BSD 4.2
+.Sh NAME
+.Nm sigstack
+.Nd set and/or get signal stack context
+.Sh DESCRIPTION
+The
+.Fn sigstack
+function has been deprecated in favor of the interface described in
+.Xr sigaltstack 2 .
+.Sh SEE ALSO
+.Xr sigaltstack 2
+.Sh HISTORY
+The
+.Fn sigstack
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/sigsuspend.2 b/lib/libc/sys/sigsuspend.2
new file mode 100644
index 0000000..c3e36ad
--- /dev/null
+++ b/lib/libc/sys/sigsuspend.2
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sigsuspend.2 8.2 (Berkeley) 5/16/95
+.\" $FreeBSD$
+.\"
+.Dd May 16, 1995
+.Dt SIGSUSPEND 2
+.Os
+.Sh NAME
+.Nm sigsuspend
+.Nd atomically release blocked signals and wait for interrupt
+.Sh SYNOPSIS
+.Fd #include <signal.h>
+.Ft int
+.Fn sigsuspend "const sigset_t *sigmask"
+.Sh DESCRIPTION
+.Fn Sigsuspend
+temporarily changes the blocked signal mask to the set to which
+.Fa sigmask
+points,
+and then waits for a signal to arrive;
+on return the previous set of masked signals is restored.
+The signal mask set
+is usually empty to indicate that all
+signals are to be unblocked for the duration of the call.
+.Pp
+In normal usage, a signal is blocked using
+.Xr sigprocmask 2
+to begin a critical section, variables modified on the occurrence
+of the signal are examined to determine that there is no work
+to be done, and the process pauses awaiting work by using
+.Fn sigsuspend
+with the previous mask returned by
+.Xr sigprocmask .
+.Sh RETURN VALUES
+The
+.Fn sigsuspend
+function
+always terminates by being interrupted, returning -1 with
+.Va errno
+set to
+.Dv EINTR .
+.Sh SEE ALSO
+.Xr sigaction 2 ,
+.Xr sigprocmask 2 ,
+.Xr sigsetops 3
+.Sh STANDARDS
+The
+.Fn sigsupend
+function call is expected to conform to
+.St -p1003.1-90 .
diff --git a/lib/libc/sys/socket.2 b/lib/libc/sys/socket.2
new file mode 100644
index 0000000..7fbe976
--- /dev/null
+++ b/lib/libc/sys/socket.2
@@ -0,0 +1,300 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" From: @(#)socket.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd November 24, 1997
+.Dt SOCKET 2
+.Os BSD 4.2
+.Sh NAME
+.Nm socket
+.Nd create an endpoint for communication
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft int
+.Fn socket "int domain" "int type" "int protocol"
+.Sh DESCRIPTION
+.Fn Socket
+creates an endpoint for communication and returns a descriptor.
+.Pp
+The
+.Fa domain
+parameter specifies a communications domain within which
+communication will take place; this selects the protocol family
+which should be used.
+These families are defined in the include file
+.Ao Pa sys/socket.h Ac .
+The currently understood formats are:
+.Pp
+.Bd -literal -offset indent -compact
+PF_LOCAL Host-internal protocols, formerly called PF_UNIX,
+PF_UNIX Host-internal protocols, depreciated, use PF_LOCAL,
+PF_INET Internet version 4 protocols,
+PF_IMPLINK ARPAnet IMP addresses,
+PF_PUP PUP protocols, like BSP,
+PF_CHAOS MIT CHAOS protocols,
+PF_NS Xerox Network Systems protocols,
+PF_ISO ISO protocols,
+PF_OSI Open Systems Interconnection protocols,
+PF_ECMA European Computer Manufacturers,
+PF_DATAKIT Datakit protocols,
+PF_CCITT ITU-T protocols, like X.25,
+PF_SNA IBM SNA,
+PF_DECnet DECnet,
+PF_DLI DEC Direct Data Link Interface protocol,
+PF_LAT LAT protocol,
+PF_HYLINK NSC Hyperchannel,
+PF_APPLETALK AppleTalk protocols,
+PF_ROUTE Internal Routing protocol,
+PF_LINK Link layer interface,
+PF_XTP eXpress Transfer Protocol,
+PF_COIP Connection-Oriented IP, aka ST II,
+PF_CNT Computer Network Technology,
+PF_SIP Simple Internet Protocol,
+PF_IPX Novell Intenet Packet eXchange protocol,
+PF_RTIP Help Identify RTIP packets,
+PF_PIP Help Identify PIP packets,
+PF_ISDN Integrated Services Digital Network,
+PF_KEY Internal key-management function,
+PF_INET6 Internet version 6 protocols,
+PF_NATM Native ATM access,
+PF_ATM ATM,
+PF_NETGRAPH Netgraph sockets
+.Ed
+.Pp
+The socket has the indicated
+.Fa type ,
+which specifies the semantics of communication. Currently
+defined types are:
+.Pp
+.Bd -literal -offset indent -compact
+SOCK_STREAM Stream socket,
+SOCK_DGRAM Datagram socket,
+SOCK_RAW Raw-protocol interface,
+SOCK_RDM Sequenced packet stream,
+SOCK_SEQPACKET Reliably-delivered packet
+.Ed
+.Pp
+A
+.Dv SOCK_STREAM
+type provides sequenced, reliable,
+two-way connection based byte streams.
+An out-of-band data transmission mechanism may be supported.
+A
+.Dv SOCK_DGRAM
+socket supports
+datagrams (connectionless, unreliable messages of
+a fixed (typically small) maximum length).
+A
+.Dv SOCK_SEQPACKET
+socket may provide a sequenced, reliable,
+two-way connection-based data transmission path for datagrams
+of fixed maximum length; a consumer may be required to read
+an entire packet with each read system call.
+This facility is protocol specific, and presently implemented
+only for
+.Dv PF_NS .
+.Dv SOCK_RAW
+sockets provide access to internal network protocols and interfaces.
+The types
+.Dv SOCK_RAW ,
+which is available only to the super-user, and
+.Dv SOCK_RDM ,
+which is planned,
+but not yet implemented, are not described here.
+.Pp
+The
+.Fa protocol
+specifies a particular protocol to be used with the socket.
+Normally only a single protocol exists to support a particular
+socket type within a given protocol family. However, it is possible
+that many protocols may exist, in which case a particular protocol
+must be specified in this manner. The protocol number to use is
+particular to the \*(lqcommunication domain\*(rq in which communication
+is to take place; see
+.Xr protocols 5 .
+.Pp
+Sockets of type
+.Dv SOCK_STREAM
+are full-duplex byte streams, similar
+to pipes. A stream socket must be in a
+.Em connected
+state before any data may be sent or received
+on it. A connection to another socket is created with a
+.Xr connect 2
+call.
+Once connected, data may be transferred using
+.Xr read 2
+and
+.Xr write 2
+calls or some variant of the
+.Xr send 2
+and
+.Xr recv 2
+calls.
+(Some protocol families, such as the Internet family,
+support the notion of an
+.Dq implied connect,
+which permits data to be sent piggybacked onto a connect operation by
+using the
+.Xr sendto 2
+call.)
+When a session has been completed a
+.Xr close 2
+may be performed.
+Out-of-band data may also be transmitted as described in
+.Xr send 2
+and received as described in
+.Xr recv 2 .
+.Pp
+The communications protocols used to implement a
+.Dv SOCK_STREAM
+insure that data
+is not lost or duplicated. If a piece of data for which the
+peer protocol has buffer space cannot be successfully transmitted
+within a reasonable length of time, then
+the connection is considered broken and calls
+will indicate an error with
+-1 returns and with
+.Dv ETIMEDOUT
+as the specific code
+in the global variable
+.Va errno .
+The protocols optionally keep sockets
+.Dq warm
+by forcing transmissions
+roughly every minute in the absence of other activity.
+An error is then indicated if no response can be
+elicited on an otherwise
+idle connection for a extended period (e.g. 5 minutes).
+A
+.Dv SIGPIPE
+signal is raised if a process sends
+on a broken stream; this causes naive processes,
+which do not handle the signal, to exit.
+.Pp
+.Dv SOCK_SEQPACKET
+sockets employ the same system calls
+as
+.Dv SOCK_STREAM
+sockets. The only difference
+is that
+.Xr read 2
+calls will return only the amount of data requested,
+and any remaining in the arriving packet will be discarded.
+.Pp
+.Dv SOCK_DGRAM
+and
+.Dv SOCK_RAW
+sockets allow sending of datagrams to correspondents
+named in
+.Xr send 2
+calls. Datagrams are generally received with
+.Xr recvfrom 2 ,
+which returns the next datagram with its return address.
+.Pp
+An
+.Xr fcntl 2
+call can be used to specify a process group to receive
+a
+.Dv SIGURG
+signal when the out-of-band data arrives.
+It may also enable non-blocking I/O
+and asynchronous notification of I/O events
+via
+.Dv SIGIO .
+.Pp
+The operation of sockets is controlled by socket level
+.Em options .
+These options are defined in the file
+.Ao Pa sys/socket.h Ac .
+.Xr Setsockopt 2
+and
+.Xr getsockopt 2
+are used to set and get options, respectively.
+.Sh RETURN VALUES
+A -1 is returned if an error occurs, otherwise the return
+value is a descriptor referencing the socket.
+.Sh ERRORS
+The
+.Fn socket
+call fails if:
+.Bl -tag -width EPROTONOPSUPPORTA
+.It Bq Er EPROTONOSUPPORT
+The protocol type or the specified protocol is not supported
+within this domain.
+.It Bq Er EMFILE
+The per-process descriptor table is full.
+.It Bq Er ENFILE
+The system file table is full.
+.It Bq Er EACCES
+Permission to create a socket of the specified type and/or protocol
+is denied.
+.It Bq Er ENOBUFS
+Insufficient buffer space is available.
+The socket cannot be created until sufficient resources are freed.
+.El
+.Sh SEE ALSO
+.Xr accept 2 ,
+.Xr bind 2 ,
+.Xr connect 2 ,
+.Xr getpeername 2 ,
+.Xr getsockname 2 ,
+.Xr getsockopt 2 ,
+.Xr ioctl 2 ,
+.Xr listen 2 ,
+.Xr read 2 ,
+.Xr recv 2 ,
+.Xr select 2 ,
+.Xr send 2 ,
+.Xr shutdown 2 ,
+.Xr socketpair 2 ,
+.Xr write 2 ,
+.Xr getprotoent 3 ,
+.Xr netgraph 4 ,
+.Xr protocols 5
+.Rs
+.%T "An Introductory 4.3 BSD Interprocess Communication Tutorial"
+.%B PS1
+.%N 7
+.Re
+.Rs
+.%T "BSD Interprocess Communication Tutorial"
+.%B PS1
+.%N 8
+.Re
+.Sh HISTORY
+The
+.Fn socket
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/socketpair.2 b/lib/libc/sys/socketpair.2
new file mode 100644
index 0000000..bf4e842
--- /dev/null
+++ b/lib/libc/sys/socketpair.2
@@ -0,0 +1,92 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)socketpair.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SOCKETPAIR 2
+.Os BSD 4.2
+.Sh NAME
+.Nm socketpair
+.Nd create a pair of connected sockets
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft int
+.Fn socketpair "int d" "int type" "int protocol" "int *sv"
+.Sh DESCRIPTION
+The
+.Fn socketpair
+call creates an unnamed pair of connected sockets in
+the specified domain
+.Fa d ,
+of the specified
+.Fa type ,
+and using the optionally specified
+.Fa protocol .
+The descriptors used in referencing the new sockets
+are returned in
+.Fa sv Ns [0]
+and
+.Fa sv Ns [1] .
+The two sockets are indistinguishable.
+.Sh RETURN VALUES
+A 0 is returned if the call succeeds, -1 if it fails.
+.Sh ERRORS
+The call succeeds unless:
+.Bl -tag -width EPROTONOSUPPORTA
+.It Bq Er EMFILE
+Too many descriptors are in use by this process.
+.It Bq Er EAFNOSUPPORT
+The specified address family is not supported on this machine.
+.It Bq Er EPROTONOSUPPORT
+The specified protocol is not supported on this machine.
+.It Bq Er EOPNOSUPPORT
+The specified protocol does not support creation of socket pairs.
+.It Bq Er EFAULT
+The address
+.Fa sv
+does not specify a valid part of the
+process address space.
+.Sh SEE ALSO
+.Xr pipe 2 ,
+.Xr read 2 ,
+.Xr write 2
+.Sh BUGS
+This call is currently implemented only for the
+.Tn UNIX
+domain.
+.Sh HISTORY
+The
+.Fn socketpair
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/stat.2 b/lib/libc/sys/stat.2
new file mode 100644
index 0000000..5617c36
--- /dev/null
+++ b/lib/libc/sys/stat.2
@@ -0,0 +1,284 @@
+.\" Copyright (c) 1980, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)stat.2 8.4 (Berkeley) 5/1/95
+.\" $FreeBSD$
+.\"
+.Dd May 1, 1995
+.Dt STAT 2
+.Os BSD 4
+.Sh NAME
+.Nm stat ,
+.Nm lstat ,
+.Nm fstat
+.Nd get file status
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/stat.h>
+.Ft int
+.Fn stat "const char *path" "struct stat *sb"
+.Ft int
+.Fn lstat "const char *path" "struct stat *sb"
+.Ft int
+.Fn fstat "int fd" "struct stat *sb"
+.Sh DESCRIPTION
+The
+.Fn stat
+function obtains information about the file pointed to by
+.Fa path .
+Read, write or execute
+permission of the named file is not required, but all directories
+listed in the path name leading to the file must be searchable.
+.Pp
+.Fn Lstat
+is like
+.Fn stat
+except in the case where the named file is a symbolic link,
+in which case
+.Fn lstat
+returns information about the link,
+while
+.Fn stat
+returns information about the file the link references.
+.Pp
+The
+.Fn fstat
+obtains the same information about an open file
+known by the file descriptor
+.Fa fd .
+.Pp
+The
+.Fa sb
+argument is a pointer to a
+.Fn stat
+structure
+as defined by
+.Aq Pa sys/stat.h
+(shown below)
+and into which information is placed concerning the file.
+.Bd -literal
+struct stat {
+ dev_t st_dev; /* inode's device */
+ ino_t st_ino; /* inode's number */
+ mode_t st_mode; /* inode protection mode */
+ nlink_t st_nlink; /* number of hard links */
+ uid_t st_uid; /* user ID of the file's owner */
+ gid_t st_gid; /* group ID of the file's group */
+ dev_t st_rdev; /* device type */
+#ifndef _POSIX_SOURCE
+ struct timespec st_atimespec; /* time of last access */
+ struct timespec st_mtimespec; /* time of last data modification */
+ struct timespec st_ctimespec; /* time of last file status change */
+#else
+ time_t st_atime; /* time of last access */
+ long st_atimensec; /* nsec of last access */
+ time_t st_mtime; /* time of last data modification */
+ long st_mtimensec; /* nsec of last data modification */
+ time_t st_ctime; /* time of last file status change */
+ long st_ctimensec; /* nsec of last file status change */
+#endif
+ off_t st_size; /* file size, in bytes */
+ int64_t st_blocks; /* blocks allocated for file */
+ u_int32_t st_blksize; /* optimal blocksize for I/O */
+ u_int32_t st_flags; /* user defined flags for file */
+ u_int32_t st_gen; /* file generation number */
+};
+.Ed
+.Pp
+The time-related fields of
+.Fa struct stat
+are as follows:
+.Bl -tag -width XXXst_mtime
+.It st_atime
+Time when file data last accessed.
+Changed by the
+.Xr mknod 2 ,
+.Xr utimes 2
+and
+.Xr read 2
+system calls.
+.It st_mtime
+Time when file data last modified.
+Changed by the
+.Xr mknod 2 ,
+.Xr utimes 2
+and
+.Xr write 2
+system calls.
+.It st_ctime
+Time when file status was last changed (inode data modification).
+Changed by the
+.Xr chmod 2 ,
+.Xr chown 2 ,
+.Xr link 2 ,
+.Xr mknod 2 ,
+.Xr rename 2 ,
+.Xr unlink 2 ,
+.Xr utimes 2
+and
+.Xr write 2
+system calls.
+.El
+.Pp
+If
+.Dv _POSIX_SOURCE
+is not defined, the time-related fields are defined as:
+.Bd -literal
+#ifndef _POSIX_SOURCE
+#define st_atime st_atimespec.tv_sec
+#define st_mtime st_mtimespec.tv_sec
+#define st_ctime st_ctimespec.tv_sec
+#endif
+.Ed
+.Pp
+The size-related fields of the
+.Fa struct stat
+are as follows:
+.Bl -tag -width XXXst_blksize
+.It st_blksize
+The optimal I/O block size for the file.
+.It st_blocks
+The actual number of blocks allocated for the file in 512-byte units.
+As short symbolic links are stored in the inode, this number may
+be zero.
+.El
+.Pp
+The status information word
+.Fa st_mode
+has the following bits:
+.Bd -literal
+#define S_IFMT 0170000 /* type of file */
+#define S_IFIFO 0010000 /* named pipe (fifo) */
+#define S_IFCHR 0020000 /* character special */
+#define S_IFDIR 0040000 /* directory */
+#define S_IFBLK 0060000 /* block special */
+#define S_IFREG 0100000 /* regular */
+#define S_IFLNK 0120000 /* symbolic link */
+#define S_IFSOCK 0140000 /* socket */
+#define S_IFWHT 0160000 /* whiteout */
+#define S_ISUID 0004000 /* set user id on execution */
+#define S_ISGID 0002000 /* set group id on execution */
+#define S_ISVTX 0001000 /* save swapped text even after use */
+#define S_IRUSR 0000400 /* read permission, owner */
+#define S_IWUSR 0000200 /* write permission, owner */
+#define S_IXUSR 0000100 /* execute/search permission, owner */
+.Ed
+.Pp
+For a list of access modes, see
+.Aq Pa sys/stat.h ,
+.Xr access 2
+and
+.Xr chmod 2 .
+.Sh RETURN VALUES
+Upon successful completion a value of 0 is returned.
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh COMPATIBILITY
+Previous versions of the system used different types for the
+.Li st_dev ,
+.Li st_uid ,
+.Li st_gid ,
+.Li st_rdev ,
+.Li st_size ,
+.Li st_blksize
+and
+.Li st_blocks
+fields.
+.Sh ERRORS
+.Fn Stat
+and
+.Fn lstat
+will fail if:
+.Bl -tag -width ENAMETOOLONGAA
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named file does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EFAULT
+.Fa Sb
+or
+.Em name
+points to an invalid address.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.El
+.Pp
+.Bl -tag -width [EFAULT]
+.Fn Fstat
+will fail if:
+.It Bq Er EBADF
+.Fa fd
+is not a valid open file descriptor.
+.It Bq Er EFAULT
+.Fa Sb
+points to an invalid address.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.El
+.Sh SEE ALSO
+.Xr access 2 ,
+.Xr chmod 2 ,
+.Xr chown 2 ,
+.Xr utimes 2 ,
+.Xr symlink 7
+.Sh BUGS
+Applying
+.Fn fstat
+to a socket (and thus to a pipe)
+returns a zeroed buffer,
+except for the blocksize field,
+and a unique device and inode number.
+.Sh STANDARDS
+The
+.Fn stat
+and
+.Fn fstat
+function calls are expected to conform to
+.St -p1003.1-90 .
+.Sh HISTORY
+A
+.Fn stat
+and a
+.Fn fstat
+function call appeared in
+.At v7 .
+A
+.Fn lstat
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/statfs.2 b/lib/libc/sys/statfs.2
new file mode 100644
index 0000000..e1ccb69
--- /dev/null
+++ b/lib/libc/sys/statfs.2
@@ -0,0 +1,183 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)statfs.2 8.5 (Berkeley) 5/24/95
+.\" $FreeBSD$
+.\"
+.Dd May 24, 1995
+.Dt STATFS 2
+.Os
+.Sh NAME
+.Nm statfs
+.Nd get file system statistics
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <sys/mount.h>
+.Ft int
+.Fn statfs "const char *path" "struct statfs *buf"
+.Ft int
+.Fn fstatfs "int fd" "struct statfs *buf"
+.Sh DESCRIPTION
+.Fn Statfs
+returns information about a mounted file system.
+.Fa Path
+is the path name of any file within the mounted filesystem.
+.Fa Buf
+is a pointer to a
+.Fn statfs
+structure defined as follows:
+.Bd -literal
+typedef struct fsid { int32_t val[2]; } fsid_t; /* file system id type */
+
+/*
+ * file system statistics
+ */
+
+#define MFSNAMELEN 16 /* length of fs type name, including null */
+#define MNAMELEN 90 /* length of buffer for returned name */
+
+struct statfs {
+long f_spare2; /* placeholder */
+long f_bsize; /* fundamental file system block size */
+long f_iosize; /* optimal transfer block size */
+long f_blocks; /* total data blocks in file system */
+long f_bfree; /* free blocks in fs */
+long f_bavail; /* free blocks avail to non-superuser */
+long f_files; /* total file nodes in file system */
+long f_ffree; /* free file nodes in fs */
+fsid_t f_fsid; /* file system id */
+uid_t f_owner; /* user that mounted the filesystem */
+int f_type; /* type of filesystem (see below) */
+int f_flags; /* copy of mount flags */
+long f_syncwrites; /* count of sync writes since mount */
+long f_asyncwrites; /* count of async writes since mount */
+char f_fstypename[MFSNAMELEN];/* fs type name */
+char f_mntonname[MNAMELEN]; /* mount point */
+char f_mntfromname[MNAMELEN]; /* mounted filesystem */
+};
+.Ed
+The flags that may be returned include:
+.Bl -tag -width MNT_ASYNCHRONOUS
+.It Dv MNT_RDONLY
+The filesystem is mounted read-only;
+Even the super-user may not write on it.
+.It Dv MNT_NOEXEC
+Files may not be executed from the filesystem.
+.It Dv MNT_NOSUID
+Setuid and setgid bits on files are not honored when they are executed.
+.It Dv MNT_NODEV
+Special files in the filesystem may not be opened.
+.It Dv MNT_SYNCHRONOUS
+All I/O to the filesystem is done synchronously.
+.It Dv MNT_ASYNCHRONOUS
+No filesystem I/O is done synchronously.
+.It Dv MNT_LOCAL
+The filesystem resides locally.
+.It Dv MNT_QUOTA
+The filesystem has quotas enabled on it.
+.It Dv MNT_ROOTFS
+Identifies the root filesystem.
+.It Dv MNT_EXRDONLY
+The filesystem is exported read-only.
+.It Dv MNT_EXPORTED
+The filesystem is exported for both reading and writing.
+.It Dv MNT_DEFEXPORTED
+The filesystem is exported for both reading and writing to any Internet host.
+.It Dv MNT_EXPORTANON
+The filesystem maps all remote accesses to the anonymous user.
+.It Dv MNT_EXKERB
+The filesystem is exported with Kerberos uid mapping.
+.El
+.Pp
+Fields that are undefined for a particular file system are set to -1.
+.Fn Fstatfs
+returns the same information about an open file referenced by descriptor
+.Fa fd .
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned.
+Otherwise, -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Statfs
+fails if one or more of the following are true:
+.Bl -tag -width ENAMETOOLONGA
+.It Bq Er ENOTDIR
+A component of the path prefix of
+.Fa Path
+is not a directory.
+.It Bq Er ENAMETOOLONG
+The length of a component of
+.Fa path
+exceeds 255 characters,
+or the length of
+.Fa path
+exceeds 1023 characters.
+.It Bq Er ENOENT
+The file referred to by
+.Fa path
+does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix of
+.Fa path .
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating
+.Fa path .
+.It Bq Er EFAULT
+.Fa Buf
+or
+.Fa path
+points to an invalid address.
+.It Bq Er EIO
+An
+.Tn I/O
+error occurred while reading from or writing to the file system.
+.El
+.Pp
+.Fn Fstatfs
+fails if one or more of the following are true:
+.Bl -tag -width ENAMETOOLONGA
+.It Bq Er EBADF
+.Fa Fd
+is not a valid open file descriptor.
+.It Bq Er EFAULT
+.Fa Buf
+points to an invalid address.
+.It Bq Er EIO
+An
+.Tn I/O
+error occurred while reading from or writing to the file system.
+.El
+.Sh HISTORY
+The
+.Fn statfs
+function first appeared in
+.Bx 4.4 .
diff --git a/lib/libc/sys/swapon.2 b/lib/libc/sys/swapon.2
new file mode 100644
index 0000000..0ab908c
--- /dev/null
+++ b/lib/libc/sys/swapon.2
@@ -0,0 +1,112 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)swapon.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SWAPON 2
+.Os BSD 4
+.Sh NAME
+.Nm swapon
+.Nd add a swap device for interleaved paging/swapping
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn swapon "const char *special"
+.Sh DESCRIPTION
+.Fn Swapon
+makes the block device
+.Fa special
+available to the system for
+allocation for paging and swapping. The names of potentially
+available devices are known to the system and defined at system
+configuration time. The size of the swap area on
+.Fa special
+is calculated at the time the device is first made available
+for swapping.
+.Sh RETURN VALUES
+If an error has occurred, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Swapon
+succeeds unless:
+.Bl -tag -width ENAMETOOLONG
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named device does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EPERM
+The caller is not the super-user.
+.It Bq Er ENOTBLK
+.Fa Special
+is not a block device.
+.It Bq Er EBUSY
+The device specified by
+.Fa special
+has already
+been made available for swapping
+.It Bq Er EINVAL
+The device configured by
+.Fa special
+was not
+configured into the system as a swap device.
+.It Bq Er ENXIO
+The major device number of
+.Fa special
+is out of range (this indicates no device driver exists
+for the associated hardware).
+.It Bq Er EIO
+An I/O error occurred while opening the swap device.
+.It Bq Er EFAULT
+.Fa Special
+points outside the process's allocated address space.
+.Sh SEE ALSO
+.Xr config 8 ,
+.Xr swapon 8
+.Sh BUGS
+There is no way to stop swapping on a disk so that the pack may be
+dismounted.
+.Pp
+This call will be upgraded in future versions of the system.
+.Sh HISTORY
+The
+.Fn swapon
+function call appeared in
+.Bx 4.0 .
diff --git a/lib/libc/sys/symlink.2 b/lib/libc/sys/symlink.2
new file mode 100644
index 0000000..f88a309
--- /dev/null
+++ b/lib/libc/sys/symlink.2
@@ -0,0 +1,137 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)symlink.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SYMLINK 2
+.Os BSD 4.2
+.Sh NAME
+.Nm symlink
+.Nd make symbolic link to a file
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn symlink "const char *name1" "const char *name2"
+.Sh DESCRIPTION
+A symbolic link
+.Fa name2
+is created to
+.Fa name1
+.Pf ( Fa name2
+is the name of the
+file created,
+.Fa name1
+is the string
+used in creating the symbolic link).
+Either name may be an arbitrary path name; the files need not
+be on the same file system.
+.Sh RETURN VALUES
+Upon successful completion, a zero value is returned.
+If an error occurs, the error code is stored in
+.Va errno
+and a -1 value is returned.
+.Sh ERRORS
+The symbolic link succeeds unless:
+.Bl -tag -width ENAMETOO
+.It Bq Er ENOTDIR
+A component of the
+.Fa name2
+prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of either pathname exceeded 255 characters,
+or the entire length of either path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named file does not exist.
+.It Bq Er EACCES
+A component of the
+.Fa name2
+path prefix denies search permission.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EEXIST
+.Fa Name2
+already exists.
+.It Bq Er EIO
+An I/O error occurred while making the directory entry for
+.Fa name2 ,
+or allocating the inode for
+.Fa name2 ,
+or writing out the link contents of
+.Fa name2 .
+.It Bq Er EROFS
+The file
+.Fa name2
+would reside on a read-only file system.
+.It Bq Er ENOSPC
+The directory in which the entry for the new symbolic link is being placed
+cannot be extended because there is no space left on the file
+system containing the directory.
+.It Bq Er ENOSPC
+The new symbolic link cannot be created because
+there is no space left on the file
+system that will contain the symbolic link.
+.It Bq Er ENOSPC
+There are no free inodes on the file system on which the
+symbolic link is being created.
+.It Bq Er EDQUOT
+The directory in which the entry for the new symbolic link
+is being placed cannot be extended because the
+user's quota of disk blocks on the file system
+containing the directory has been exhausted.
+.It Bq Er EDQUOT
+The new symbolic link cannot be created because the user's
+quota of disk blocks on the file system that will
+contain the symbolic link has been exhausted.
+.It Bq Er EDQUOT
+The user's quota of inodes on the file system on
+which the symbolic link is being created has been exhausted.
+.It Bq Er EIO
+An I/O error occurred while making the directory entry or allocating the inode.
+.It Bq Er EFAULT
+.Fa Name1
+or
+.Fa name2
+points outside the process's allocated address space.
+.El
+.Sh SEE ALSO
+.Xr ln 1 ,
+.Xr link 2 ,
+.Xr lstat 2 ,
+.Xr readlink 2 ,
+.Xr unlink 2 ,
+.Xr symlink 7
+.Sh HISTORY
+The
+.Fn symlink
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/sync.2 b/lib/libc/sys/sync.2
new file mode 100644
index 0000000..a989e8d5
--- /dev/null
+++ b/lib/libc/sys/sync.2
@@ -0,0 +1,75 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sync.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SYNC 2
+.Os BSD 4
+.Sh NAME
+.Nm sync
+.Nd "synchronize disk block in-core status with that on disk"
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft void
+.Fn sync void
+.Sh DESCRIPTION
+The
+.Fn sync
+function forces a write of dirty (modified) buffers
+in the block buffer cache out
+to disk. The kernel keeps this information in core to reduce
+the number of disk I/O transfers required by the system.
+As information in the cache is lost after a system crash a
+.Fn sync
+call is issued
+frequently
+by the user process
+.Xr update 4
+(about every 30 seconds).
+.Pp
+The function
+.Xr fsync 2
+may be used to synchronize individual file descriptor
+attributes.
+.Sh SEE ALSO
+.Xr fsync 2 ,
+.Xr update 4 ,
+.Xr sync 8
+.Sh BUGS
+.Fn Sync
+may return before the buffers are completely flushed.
+.Sh HISTORY
+A
+.Fn sync
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/sysarch.2 b/lib/libc/sys/sysarch.2
new file mode 100644
index 0000000..c3840e9
--- /dev/null
+++ b/lib/libc/sys/sysarch.2
@@ -0,0 +1,79 @@
+.\" $NetBSD: sysarch.2,v 1.6 1998/02/25 21:24:57 perry Exp $
+.\" $FreeBSD$
+.\"
+.\" Copyright (c) 1980, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)syscall.2 6.3 (Berkeley) 3/10/91
+.\"
+.Dd October 11, 1993
+.Dt SYSARCH 2
+.Os
+.Sh NAME
+.Nm sysarch
+.Nd architecture-dependent system call
+.Sh SYNOPSIS
+.Fd #include <machine/sysarch.h>
+.Ft int
+.Fn sysarch "int number" "void *args"
+.Sh DESCRIPTION
+.Fn Sysarch
+performs the architecture-dependent function
+specified by
+.Fa number
+with the arguments specified by the
+.Fa args
+pointer.
+.Fa Args
+is a pointer to a structure defining the actual
+arguments of the function.
+Symbolic constants and argument structures
+for the architecture-dependent
+functions can be found in the header file
+.Ao Pa machine/sysarch.h Ac .
+.Pp
+The
+.Fn sysarch
+system call should never be called directly by
+user programs. Instead, they should access
+its functions using the architecture-dependent
+library.
+.Pp
+.Sh RETURN VALUES
+See the manual pages for specific architecture-dependent function calls
+for information about their return values.
+.Sh SEE ALSO
+.Xr i386_get_ioperm 2 ,
+.Xr i386_get_ldt 2 ,
+.Xr i386_vm86 2
+.Sh HISTORY
+This manual page was taken from
+.Nx .
diff --git a/lib/libc/sys/syscall.2 b/lib/libc/sys/syscall.2
new file mode 100644
index 0000000..c5192fb
--- /dev/null
+++ b/lib/libc/sys/syscall.2
@@ -0,0 +1,77 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)syscall.2 8.1 (Berkeley) 6/16/93
+.\" $FreeBSD$
+.\"
+.Dd June 16, 1993
+.Dt SYSCALL 2
+.Os BSD 4
+.Sh NAME
+.Nm syscall ,
+.Nm __syscall
+.Nd indirect system call
+.Sh SYNOPSIS
+.Fd #include <sys/syscall.h>
+.Fd #include <unistd.h>
+.Ft int
+.Fn syscall "int number" ...
+.Ft off_t
+.Fn __syscall "quad_t number" ...
+.Sh DESCRIPTION
+.Fn Syscall
+performs the system call whose assembly language
+interface has the specified
+.Fa number
+with the specified arguments.
+Symbolic constants for system calls can be found in the header file
+.Ao Pa sys/syscall.h Ac .
+The
+.Fn __syscall
+form should be used when one or more of the parameters is a
+64-bit argument to ensure that argument alignment is correct.
+This system call is useful for testing new system calls that
+do not have entries in the C library.
+.Sh RETURN VALUES
+The return values are defined by the system call being invoked.
+In general, a 0 return value indicates success.
+A -1 return value indicates an error,
+and an error code is stored in
+.Va errno .
+.Sh BUGS
+There is no way to simulate system calls that have multiple return values
+such as
+.Xr pipe 2 .
+.Sh HISTORY
+The
+.Fn syscall
+function call appeared in
+.Bx 4.0 .
diff --git a/lib/libc/sys/truncate.2 b/lib/libc/sys/truncate.2
new file mode 100644
index 0000000..ce17ff2
--- /dev/null
+++ b/lib/libc/sys/truncate.2
@@ -0,0 +1,129 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)truncate.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt TRUNCATE 2
+.Os BSD 4.2
+.Sh NAME
+.Nm truncate ,
+.Nm ftruncate
+.Nd truncate or extend a file to a specified length
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn truncate "const char *path" "off_t length"
+.Ft int
+.Fn ftruncate "int fd" "off_t length"
+.Sh DESCRIPTION
+.Fn Truncate
+causes the file named by
+.Fa path
+or referenced by
+.Fa fd
+to be truncated or extended to
+.Fa length
+bytes in size. If the file
+was larger than this size, the extra data
+is lost.
+If the file was smaller than this size,
+it will be extended as if by writing bytes
+with the value zero.
+With
+.Fn ftruncate ,
+the file must be open for writing.
+.Sh RETURN VALUES
+A value of 0 is returned if the call succeeds. If the call
+fails a -1 is returned, and the global variable
+.Va errno
+specifies the error.
+.Sh ERRORS
+.Fn Truncate
+succeeds unless:
+.Bl -tag -width [ENOTDIR]
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named file does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er EACCES
+The named file is not writable by the user.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EISDIR
+The named file is a directory.
+.It Bq Er EROFS
+The named file resides on a read-only file system.
+.It Bq Er ETXTBSY
+The file is a pure procedure (shared text) file that is being executed.
+.It Bq Er EIO
+An I/O error occurred updating the inode.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.El
+.Pp
+.Fn Ftruncate
+succeeds unless:
+.Bl -tag -width [ENOTDIR]
+.It Bq Er EBADF
+The
+.Fa fd
+is not a valid descriptor.
+.It Bq Er EINVAL
+The
+.Fa fd
+references a socket, not a file.
+.It Bq Er EINVAL
+The
+.Fa fd
+is not open for writing.
+.El
+.Sh SEE ALSO
+.Xr open 2
+.Sh BUGS
+These calls should be generalized to allow ranges
+of bytes in a file to be discarded.
+.Pp
+Use of
+.Fn truncate
+to extend a file is not portable.
+.Sh HISTORY
+The
+.Fn truncate
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/truncate.c b/lib/libc/sys/truncate.c
new file mode 100644
index 0000000..5bfeeb6
--- /dev/null
+++ b/lib/libc/sys/truncate.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)truncate.c 8.1 (Berkeley) 6/17/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/syscall.h>
+
+#include <unistd.h>
+
+/*
+ * This function provides 64-bit offset padding that
+ * is not supplied by GCC 1.X but is supplied by GCC 2.X.
+ */
+int
+truncate(path, length)
+ const char *path;
+ off_t length;
+{
+
+ return(__syscall((quad_t)SYS_truncate, path, 0, length));
+}
diff --git a/lib/libc/sys/umask.2 b/lib/libc/sys/umask.2
new file mode 100644
index 0000000..aaeaaa5
--- /dev/null
+++ b/lib/libc/sys/umask.2
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)umask.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt UMASK 2
+.Os BSD 4
+.Sh NAME
+.Nm umask
+.Nd set file creation mode mask
+.Sh SYNOPSIS
+.Fd #include <sys/stat.h>
+.Ft mode_t
+.Fn umask "mode_t numask"
+.Sh DESCRIPTION
+The
+.Fn umask
+routine sets the process's file mode creation mask to
+.Fa numask
+and returns the previous value of the mask. The 9 low-order
+access permission
+bits of
+.Fa numask
+are used by system calls, including
+.Xr open 2 ,
+.Xr mkdir 2 ,
+and
+.Xr mkfifo 2 ,
+to turn off corresponding bits
+requested in file mode.
+(See
+.Xr chmod 2 ) .
+This clearing allows each user to restrict the default access
+to his files.
+.Pp
+The default mask value is S_IWGRP|S_IWOTH (022, write access for the
+owner only).
+Child processes inherit the mask of the calling process.
+.Sh RETURN VALUES
+The previous value of the file mode mask is returned by the call.
+.Sh ERRORS
+The
+.Fn umask
+function is always successful.
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr mknod 2 ,
+.Xr open 2
+.Sh STANDARDS
+The
+.Fn umask
+function call is expected to conform to
+.St -p1003.1-90 .
+.Sh HISTORY
+An
+.Fn umask
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/undelete.2 b/lib/libc/sys/undelete.2
new file mode 100644
index 0000000..b95a3a6
--- /dev/null
+++ b/lib/libc/sys/undelete.2
@@ -0,0 +1,104 @@
+.\" Copyright (c) 1994
+.\" Jan-Simon Pendry
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)undelete.2 8.4 (Berkeley) 10/18/94
+.\" $FreeBSD$
+.\"
+.Dd October 18, 1994
+.Dt UNDELETE 2
+.Os BSD 4
+.Sh NAME
+.Nm undelete
+.Nd attempt to recover a deleted file
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn undelete "const char *path"
+.Sh DESCRIPTION
+The
+.Fn undelete
+function attempts to recover the deleted file named by
+.Fa path .
+Currently, this works only when the named object
+is a whiteout in a union filesystem.
+The system call removes the whiteout causing
+any objects in a lower layer of the
+union stack to become visible once more.
+.Pp
+Eventually, the
+.Nm undelete
+functionality may be expanded to other filesystems able to recover
+deleted files such as the log-structured filesystem.
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned.
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn undelete
+succeeds unless:
+.Bl -tag -width ENAMETOOLONGAA
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er EEXIST
+The path does not reference a whiteout.
+.It Bq Er ENOENT
+The named whiteout does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er EACCES
+Write permission is denied on the directory containing the name
+to be undeleted.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EPERM
+The directory containing the name is marked sticky,
+and the containing directory is not owned by the effective user ID.
+.It Bq Er EIO
+An I/O error occurred while updating the directory entry.
+.It Bq Er EROFS
+The name resides on a read-only file system.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.El
+.Sh SEE ALSO
+.Xr unlink 2 ,
+.Xr mount_union 8
+.Sh HISTORY
+An
+.Nm undelete
+function call first appeared in 4.4BSD-Lite.
diff --git a/lib/libc/sys/unlink.2 b/lib/libc/sys/unlink.2
new file mode 100644
index 0000000..874a001
--- /dev/null
+++ b/lib/libc/sys/unlink.2
@@ -0,0 +1,119 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)unlink.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt UNLINK 2
+.Os BSD 4
+.Sh NAME
+.Nm unlink
+.Nd remove directory entry
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn unlink "const char *path"
+.Sh DESCRIPTION
+The
+.Fn unlink
+function
+removes the link named by
+.Fa path
+from its directory and decrements the link count of the
+file which was referenced by the link.
+If that decrement reduces the link count of the file
+to zero,
+and no process has the file open, then
+all resources associated with the file are reclaimed.
+If one or more process have the file open when the last link is removed,
+the link is removed, but the removal of the file is delayed until
+all references to it have been closed.
+.Fa path
+may not be a directory.
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned.
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn unlink
+succeeds unless:
+.Bl -tag -width ENAMETOOLONGAA
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire path name exceeded 1023 characters.
+.It Bq Er ENOENT
+The named file does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er EACCES
+Write permission is denied on the directory containing the link
+to be removed.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EPERM
+The named file is a directory.
+.It Bq Er EPERM
+The directory containing the file is marked sticky,
+and neither the containing directory nor the file to be removed
+are owned by the effective user ID.
+.It Bq Er EBUSY
+The entry to be unlinked is the mount point for a
+mounted file system.
+.It Bq Er EIO
+An I/O error occurred while deleting the directory entry
+or deallocating the inode.
+.It Bq Er EROFS
+The named file resides on a read-only file system.
+.It Bq Er EFAULT
+.Fa Path
+points outside the process's allocated address space.
+.El
+.Sh SEE ALSO
+.Xr close 2 ,
+.Xr link 2 ,
+.Xr rmdir 2 ,
+.Xr symlink 7
+.Sh HISTORY
+An
+.Fn unlink
+function call appeared in
+.At v6 .
+.Pp
+The
+.Fn unlink
+system call traditionally allows the super-user to unlink directories which
+can damage the filesystem integrity. This implementation no longer permits
+it.
diff --git a/lib/libc/sys/utimes.2 b/lib/libc/sys/utimes.2
new file mode 100644
index 0000000..ea04d85
--- /dev/null
+++ b/lib/libc/sys/utimes.2
@@ -0,0 +1,187 @@
+.\" $NetBSD: utimes.2,v 1.13 1999/03/22 19:45:11 garbled Exp $
+.\"
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)utimes.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt UTIMES 2
+.Os
+.Sh NAME
+.Nm utimes ,
+.Nm lutimes ,
+.Nm futimes
+.Nd set file access and modification times
+.Sh SYNOPSIS
+.Fd #include <sys/time.h>
+.Ft int
+.Fn utimes "const char *path" "const struct timeval *times"
+.Ft int
+.Fn lutimes "const char *path" "const struct timeval *times"
+.Ft int
+.Fn futimes "int fd" "const struct timeval *times"
+.Sh DESCRIPTION
+The access and modification times of the file named by
+.Fa path
+or referenced by
+.Fa fd
+are changed as specified by the argument
+.Fa times .
+.Pp
+If
+.Fa times
+is
+.Dv NULL ,
+the access and modification times are set to the current time.
+The caller must be the owner of the file, have permission to
+write the file, or be the super-user.
+.Pp
+If
+.Fa times
+is
+.Pf non- Dv NULL ,
+it is assumed to point to an array of two timeval structures.
+The access time is set to the value of the first element, and the
+modification time is set to the value of the second element.
+The caller must be the owner of the file or be the super-user.
+.Pp
+In either case, the inode-change-time of the file is set to the current
+time.
+.Pp
+.Fn lutimes
+is like
+.Fn utimes
+except in the case where the named file is a symbolic link,
+in which case
+.Fn lutimes
+changes the access and modification times of the link,
+while
+.Fn utimes
+changes the times of the file the link references.
+.Sh RETURN VALUES
+Upon successful completion, a value of 0 is returned.
+Otherwise, a value of -1 is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn utimes
+and
+.Fn lutimes
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix;
+or the
+.Fa times
+argument is
+.Dv NULL
+and the effective user ID of the process does not
+match the owner of the file, and is not the super-user, and write
+access is denied.
+.It Bq Er EFAULT
+.Fa path
+or
+.Fa times
+points outside the process's allocated address space.
+.It Bq Er EIO
+An I/O error occurred while reading or writing the affected inode.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded
+.Dv NAME_MAX
+characters, or an entire path name exceeded
+.Dv PATH_MAX
+characters.
+.It Bq Er ENOENT
+The named file does not exist.
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er EPERM
+The
+.Fa times
+argument is not
+.Dv NULL
+and the calling process's effective user ID
+does not match the owner of the file and is not the super-user.
+.It Bq Er EROFS
+The file system containing the file is mounted read-only.
+.El
+.Pp
+.Fn futimes
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa fd
+does not refer to a valid descriptor.
+.El
+.Pp
+All of the functions will fail if:
+.Bl -tag -width Er
+.It Bq Er EACCES
+The
+.Fa times
+argument is
+.Dv NULL
+and the effective user ID of the process does not
+match the owner of the file, and is not the super-user, and write
+access is denied.
+.It Bq Er EFAULT
+.Fa times
+points outside the process's allocated address space.
+.It Bq Er EIO
+An I/O error occurred while reading or writing the affected inode.
+.It Bq Er EPERM
+The
+.Fa times
+argument is not
+.Dv NULL
+and the calling process's effective user ID
+does not match the owner of the file and is not the super-user.
+.It Bq Er EROFS
+The file system containing the file is mounted read-only.
+.El
+.Sh SEE ALSO
+.Xr stat 2 ,
+.Xr utime 3
+.Sh HISTORY
+The
+.Fn utimes
+function call appeared in
+.Bx 4.2 .
+The
+.Fn futimes
+and
+.Fn lutimes
+function calls first appeared in
+.Fx 3.0 .
diff --git a/lib/libc/sys/vfork.2 b/lib/libc/sys/vfork.2
new file mode 100644
index 0000000..7363c55
--- /dev/null
+++ b/lib/libc/sys/vfork.2
@@ -0,0 +1,130 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)vfork.2 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt VFORK 2
+.Os BSD 4
+.Sh NAME
+.Nm vfork
+.Nd spawn new process in a virtual memory efficient way
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn vfork void
+.Sh DESCRIPTION
+.Fn Vfork
+can be used to create new processes without fully copying the address
+space of the old process, which is horrendously inefficient in a paged
+environment. It is useful when the purpose of
+.Xr fork 2
+would have been to create a new system context for an
+.Xr execve 2 .
+.Fn Vfork
+differs from
+.Xr fork 2
+in that the child borrows the parent's memory and thread of
+control until a call to
+.Xr execve 2
+or an exit (either by a call to
+.Xr _exit 2
+or abnormally).
+The parent process is suspended while the child is using its resources.
+.Pp
+.Fn Vfork
+returns 0 in the child's context and (later) the pid of the child in
+the parent's context.
+.Pp
+.Fn Vfork
+can normally be used just like
+.Xr fork 2 .
+It does not work, however, to return while running in the childs context
+from the procedure that called
+.Fn vfork
+since the eventual return from
+.Fn vfork
+would then return to a no longer existent stack frame.
+Be careful, also, to call
+.Xr _exit 2
+rather than
+.Xr exit 3
+if you can't
+.Xr execve 2 ,
+since
+.Xr exit 3
+will flush and close standard I/O channels, and thereby mess up the
+parent processes standard I/O data structures.
+(Even with
+.Xr fork 2
+it is wrong to call
+.Xr exit 3
+since buffered data would then be flushed twice.)
+.Sh SEE ALSO
+.Xr _exit 2 ,
+.Xr execve 2 ,
+.Xr fork 2 ,
+.Xr rfork 2 ,
+.Xr sigvec 2 ,
+.Xr wait 2 ,
+.Xr exit 3
+.Sh RETURN VALUES
+Same as for
+.Xr fork 2 .
+.Sh BUGS
+This system call will be eliminated when proper system sharing
+mechanisms are implemented.
+Users should not depend on the memory
+sharing semantics of
+.Xr vfork 2
+as it will, in that case, be made synonymous to
+.Xr fork 2 .
+.Pp
+To avoid a possible deadlock situation,
+processes that are children in the middle
+of a
+.Fn vfork
+are never sent
+.Dv SIGTTOU
+or
+.Dv SIGTTIN
+signals; rather,
+output or
+.Xr ioctl 2
+calls
+are allowed
+and input attempts result in an end-of-file indication.
+.Sh HISTORY
+The
+.Fn vfork
+function call appeared in
+.Bx 3.0 .
diff --git a/lib/libc/sys/wait.2 b/lib/libc/sys/wait.2
new file mode 100644
index 0000000..5cbd812
--- /dev/null
+++ b/lib/libc/sys/wait.2
@@ -0,0 +1,299 @@
+.\" Copyright (c) 1980, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)wait.2 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt WAIT 2
+.Os BSD 4
+.Sh NAME
+.Nm wait ,
+.Nm waitpid ,
+.Nm wait4 ,
+.Nm wait3
+.Nd wait for process termination
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/wait.h>
+.Ft pid_t
+.Fn wait "int *status"
+.Fd #include <sys/time.h>
+.Fd #include <sys/resource.h>
+.Ft pid_t
+.Fn waitpid "pid_t wpid" "int *status" "int options"
+.Ft pid_t
+.Fn wait3 "int *status" "int options" "struct rusage *rusage"
+.Ft pid_t
+.Fn wait4 "pid_t wpid" "int *status" "int options" "struct rusage *rusage"
+.Sh DESCRIPTION
+The
+.Fn wait
+function suspends execution of its calling process until
+.Fa status
+information is available for a terminated child process,
+or a signal is received.
+On return from a successful
+.Fn wait
+call,
+the
+.Fa status
+area contains termination information about the process that exited
+as defined below.
+.Pp
+The
+.Fn wait4
+call provides a more general interface for programs
+that need to wait for certain child processes,
+that need resource utilization statistics accumulated by child processes,
+or that require options.
+The other wait functions are implemented using
+.Fn wait4 .
+.Pp
+The
+.Fa wpid
+parameter specifies the set of child processes for which to wait.
+If
+.Fa wpid
+is -1, the call waits for any child process.
+If
+.Fa wpid
+is 0,
+the call waits for any child process in the process group of the caller.
+If
+.Fa wpid
+is greater than zero, the call waits for the process with process id
+.Fa wpid .
+If
+.Fa wpid
+is less than -1, the call waits for any process whose process group id
+equals the absolute value of
+.Fa wpid .
+.Pp
+The
+.Fa status
+parameter is defined below. The
+.Fa options
+parameter contains the bitwise OR of any of the following options.
+The
+.Dv WNOHANG
+option
+is used to indicate that the call should not block if
+there are no processes that wish to report status.
+If the
+.Dv WUNTRACED
+option is set,
+children of the current process that are stopped
+due to a
+.Dv SIGTTIN , SIGTTOU , SIGTSTP ,
+or
+.Dv SIGSTOP
+signal also have
+their status reported.
+.Pp
+If
+.Fa rusage
+is non-zero, a summary of the resources used by the terminated
+process and all its
+children is returned (this information is currently not available
+for stopped processes).
+.Pp
+When the
+.Dv WNOHANG
+option is specified and no processes
+wish to report status,
+.Fn wait4
+returns a
+process id
+of 0.
+.Pp
+The
+.Fn waitpid
+call is identical to
+.Fn wait4
+with an
+.Fa rusage
+value of zero.
+The older
+.Fn wait3
+call is the same as
+.Fn wait4
+with a
+.Fa wpid
+value of -1.
+.Pp
+The following macros may be used to test the manner of exit of the process.
+One of the first three macros will evaluate to a non-zero (true) value:
+.Bl -tag -width Ds
+.It Fn WIFEXITED status
+True if the process terminated normally by a call to
+.Xr _exit 2
+or
+.Xr exit 3 .
+.It Fn WIFSIGNALED status
+True if the process terminated due to receipt of a signal.
+.It Fn WIFSTOPPED status
+True if the process has not terminated, but has stopped and can be restarted.
+This macro can be true only if the wait call specified the
+.Dv WUNTRACED
+option
+or if the child process is being traced (see
+.Xr ptrace 2 ) .
+.El
+.Pp
+Depending on the values of those macros, the following macros
+produce the remaining status information about the child process:
+.Bl -tag -width Ds
+.It Fn WEXITSTATUS status
+If
+.Fn WIFEXITED status
+is true, evaluates to the low-order 8 bits
+of the argument passed to
+.Xr _exit 2
+or
+.Xr exit 3
+by the child.
+.It Fn WTERMSIG status
+If
+.Fn WIFSIGNALED status
+is true, evaluates to the number of the signal
+that caused the termination of the process.
+.It Fn WCOREDUMP status
+If
+.Fn WIFSIGNALED status
+is true, evaluates as true if the termination
+of the process was accompanied by the creation of a core file
+containing an image of the process when the signal was received.
+.It Fn WSTOPSIG status
+If
+.Fn WIFSTOPPED status
+is true, evaluates to the number of the signal
+that caused the process to stop.
+.El
+.Sh NOTES
+See
+.Xr sigaction 2
+for a list of termination signals.
+A status of 0 indicates normal termination.
+.Pp
+If a parent process terminates without
+waiting for all of its child processes to terminate,
+the remaining child processes are assigned the parent
+process 1 ID (the init process ID).
+.Pp
+If a signal is caught while any of the
+.Fn wait
+calls is pending,
+the call may be interrupted or restarted when the signal-catching routine
+returns,
+depending on the options in effect for the signal;
+see
+.Xr intro 2 ,
+System call restart.
+.Sh RETURN VALUES
+If
+.Fn wait
+returns due to a stopped
+or terminated child process, the process ID of the child
+is returned to the calling process. Otherwise, a value of -1
+is returned and
+.Va errno
+is set to indicate the error.
+.Pp
+If
+.Fn wait4 ,
+.Fn wait3
+or
+.Fn waitpid
+returns due to a stopped
+or terminated child process, the process ID of the child
+is returned to the calling process.
+If there are no children not previously awaited,
+-1 is returned with
+.Va errno
+set to
+.Bq Er ECHILD .
+Otherwise, if
+.Dv WNOHANG
+is specified and there are
+no stopped or exited children,
+0 is returned.
+If an error is detected or a caught signal aborts the call,
+a value of -1
+is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Wait
+will fail and return immediately if:
+.Bl -tag -width Er
+.It Bq Er ECHILD
+The calling process has no existing unwaited-for
+child processes.
+.It Bq Er EFAULT
+The
+.Fa status
+or
+.Fa rusage
+arguments point to an illegal address.
+(May not be detected before exit of a child process.)
+.It Bq Er EINTR
+The call was interrupted by a caught signal,
+or the signal did not have the
+.Dv SA_RESTART
+flag set.
+.El
+.Sh STANDARDS
+The
+.Fn wait
+and
+.Fn waitpid
+functions are defined by POSIX;
+.Fn wait4
+and
+.Fn wait3
+are not specified by POSIX.
+The
+.Fn WCOREDUMP
+macro
+and the ability to restart a pending
+.Fn wait
+call are extensions to the POSIX interface.
+.Sh SEE ALSO
+.Xr _exit 2 ,
+.Xr ptrace 2 ,
+.Xr sigaction 2 ,
+.Xr exit 3
+.Sh HISTORY
+A
+.Fn wait
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/write.2 b/lib/libc/sys/write.2
new file mode 100644
index 0000000..ab5d236
--- /dev/null
+++ b/lib/libc/sys/write.2
@@ -0,0 +1,289 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)write.2 8.5 (Berkeley) 4/2/94
+.\" $FreeBSD$
+.\"
+.Dd April 2, 1994
+.Dt WRITE 2
+.Os BSD 4
+.Sh NAME
+.Nm write ,
+.Nm writev ,
+.Nm pwrite
+.Nd write output
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/uio.h>
+.Fd #include <unistd.h>
+.Ft ssize_t
+.Fn write "int d" "const void *buf" "size_t nbytes"
+.Ft ssize_t
+.Fn writev "int d" "const struct iovec *iov" "int iovcnt"
+.Ft ssize_t
+.Fn pwrite "int d" "const void *buf" "size_t nbytes" "off_t offset"
+.Sh DESCRIPTION
+.Fn Write
+attempts to write
+.Fa nbytes
+of data to the object referenced by the descriptor
+.Fa d
+from the buffer pointed to by
+.Fa buf .
+.Fn Writev
+performs the same action, but gathers the output data
+from the
+.Fa iovcnt
+buffers specified by the members of the
+.Fa iov
+array: iov[0], iov[1], ..., iov[iovcnt\|-\|1].
+.Fn Pwrite
+performs the same function, but writes to the specified position in
+the file without modifying the file pointer.
+.Pp
+For
+.Fn writev ,
+the
+.Fa iovec
+structure is defined as:
+.Pp
+.Bd -literal -offset indent -compact
+struct iovec {
+ char *iov_base; /* Base address. */
+ size_t iov_len; /* Length. */
+};
+.Ed
+.Pp
+Each
+.Fa iovec
+entry specifies the base address and length of an area
+in memory from which data should be written.
+.Fn Writev
+will always write a complete area before proceeding
+to the next.
+.Pp
+On objects capable of seeking, the
+.Fn write
+starts at a position
+given by the pointer associated with
+.Fa d ,
+see
+.Xr lseek 2 .
+Upon return from
+.Fn write ,
+the pointer is incremented by the number of bytes which were written.
+.Pp
+Objects that are not capable of seeking always write from the current
+position. The value of the pointer associated with such an object
+is undefined.
+.Pp
+If the real user is not the super-user, then
+.Fn write
+clears the set-user-id bit on a file.
+This prevents penetration of system security
+by a user who
+.Dq captures
+a writable set-user-id file
+owned by the super-user.
+.Pp
+When using non-blocking I/O on objects such as sockets that are subject
+to flow control,
+.Fn write
+and
+.Fn writev
+may write fewer bytes than requested;
+the return value must be noted,
+and the remainder of the operation should be retried when possible.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn write
+is implemented as the
+.Va write
+syscall.
+.Pp
+In the threaded library, the
+.Va write
+syscall is assembled to
+.Fn _thread_sys_write
+and
+.Fn write
+is implemented as a function which locks
+.Va d
+for read and write, then calls
+.Fn _thread_sys_write .
+If the call to
+.Fn _thread_sys_write
+would block, a context switch is performed. Before returning,
+.Fn write
+unlocks
+.Va d .
+.Pp
+In the non-threaded library
+.Fn writev
+is implemented as the
+.Va writev
+syscall.
+.Pp
+In the threaded library, the
+.Va writev
+syscall is assembled to
+.Fn _thread_sys_writev
+and
+.Fn writev
+is implemented as a function which locks
+.Va d
+for read and write, then calls
+.Fn _thread_sys_writev .
+If the call to
+.Fn _thread_sys_writev
+would block, a context switch is performed. Before returning,
+.Fn writev
+unlocks
+.Va d .
+.Sh RETURN VALUES
+Upon successful completion the number of bytes which were written
+is returned. Otherwise a -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn Write ,
+.Fn writev ,
+and
+.Fn pwrite
+will fail and the file pointer will remain unchanged if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa D
+is not a valid descriptor open for writing.
+.It Bq Er EPIPE
+An attempt is made to write to a pipe that is not open
+for reading by any process.
+.It Bq Er EPIPE
+An attempt is made to write to a socket of type
+.Dv SOCK_STREAM
+that is not connected to a peer socket.
+.It Bq Er EFBIG
+An attempt was made to write a file that exceeds the process's
+file size limit or the maximum file size.
+.It Bq Er EFAULT
+Part of
+.Fa iov
+or data to be written to the file
+points outside the process's allocated address space.
+.It Bq Er EINVAL
+The pointer associated with
+.Fa d
+was negative.
+.It Bq Er ENOSPC
+There is no free space remaining on the file system
+containing the file.
+.It Bq Er EDQUOT
+The user's quota of disk blocks on the file system
+containing the file has been exhausted.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.It Bq Er EAGAIN
+The file was marked for non-blocking I/O,
+and no data could be written immediately.
+.El
+.Pp
+In addition,
+.Fn writev
+may return one of the following errors:
+.Bl -tag -width Er
+.It Bq Er EDESTADDRREQ
+The destination is no longer available when writing to a
+.Ux
+domain datagram socket on which
+.Xr connect 2
+had been used to set a destination address.
+.It Bq Er EINVAL
+.Fa Iovcnt
+was less than or equal to 0, or greater than
+.Dv UIO_MAXIOV .
+.It Bq Er EINVAL
+One of the
+.Fa iov_len
+values in the
+.Fa iov
+array was negative.
+.It Bq Er EINVAL
+The sum of the
+.Fa iov_len
+values in the
+.Fa iov
+array overflowed a 32-bit integer.
+.It Bq Er ENOBUFS
+The mbuf pool has been completely exhausted when writing to a socket.
+.El
+.Pp
+The
+.Fn pwrite
+call may also return the following errors:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The specified file offset is invalid.
+.It Bq Er ESPIPE
+The file descriptor is associated with a pipe, socket, or FIFO.
+.El
+.Sh SEE ALSO
+.Xr fcntl 2 ,
+.Xr lseek 2 ,
+.Xr open 2 ,
+.Xr pipe 2 ,
+.Xr select 2
+.Sh STANDARDS
+The
+.Fn write
+function call is expected to conform to
+.St -p1003.1-90 .
+The
+.Fn writev
+and
+.Fn pwrite
+functions are expected to conform to
+.St -xpg4.2 .
+.Sh HISTORY
+The
+.Fn pwrite
+function call
+appeared in
+.At V.4 .
+The
+.Fn writev
+function call
+appeared in
+.Bx 4.2 .
+A
+.Fn write
+function call appeared in
+.At v6 .
diff --git a/lib/libc/xdr/Makefile.inc b/lib/libc/xdr/Makefile.inc
new file mode 100644
index 0000000..1837ef8
--- /dev/null
+++ b/lib/libc/xdr/Makefile.inc
@@ -0,0 +1,43 @@
+# @(#)Makefile 5.11 (Berkeley) 9/6/90
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../libc/xdr ${.CURDIR}/.
+SRCS+= xdr.c xdr_array.c xdr_float.c xdr_mem.c \
+ xdr_rec.c xdr_reference.c xdr_stdio.c xdr_sizeof.c
+
+.if ${LIB} == "c"
+MAN3+= xdr.3
+
+MLINKS+= xdr.3 xdr_array.3 \
+ xdr.3 xdr_bool.3 \
+ xdr.3 xdr_bytes.3 \
+ xdr.3 xdr_char.3 \
+ xdr.3 xdr_destroy.3 \
+ xdr.3 xdr_double.3 \
+ xdr.3 xdr_enum.3 \
+ xdr.3 xdr_float.3 \
+ xdr.3 xdr_free.3 \
+ xdr.3 xdr_getpos.3 \
+ xdr.3 xdr_inline.3 \
+ xdr.3 xdr_int.3 \
+ xdr.3 xdr_long.3 \
+ xdr.3 xdrmem_create.3 \
+ xdr.3 xdr_opaque.3 \
+ xdr.3 xdr_pointer.3 \
+ xdr.3 xdrrec_create.3 \
+ xdr.3 xdrrec_endofrecord.3 \
+ xdr.3 xdrrec_eof.3 \
+ xdr.3 xdrrec_skiprecord.3 \
+ xdr.3 xdr_reference.3 \
+ xdr.3 xdr_setpos.3 \
+ xdr.3 xdr_short.3 \
+ xdr.3 xdrstdio_create.3 \
+ xdr.3 xdr_string.3 \
+ xdr.3 xdr_u_char.3 \
+ xdr.3 xdr_u_long.3 \
+ xdr.3 xdr_u_short.3 \
+ xdr.3 xdr_union.3 \
+ xdr.3 xdr_vector.3 \
+ xdr.3 xdr_void.3 \
+ xdr.3 xdr_wrapstring.3
+.endif
diff --git a/lib/libc/xdr/xdr.3 b/lib/libc/xdr/xdr.3
new file mode 100644
index 0000000..979b54e
--- /dev/null
+++ b/lib/libc/xdr/xdr.3
@@ -0,0 +1,825 @@
+.\" @(#)xdr.3n 2.2 88/08/03 4.0 RPCSRC; from 1.16 88/03/14 SMI
+.\" $FreeBSD$
+.\"
+.TH XDR 3 "16 February 1988"
+.SH NAME
+xdr \- library routines for external data representation
+.SH SYNOPSIS AND DESCRIPTION
+.LP
+These routines allow C programmers to describe
+arbitrary data structures in a machine-independent fashion.
+Data for remote procedure calls are transmitted using these
+routines.
+.LP
+.ft B
+.nf
+.sp .5
+xdr_array(xdrs, arrp, sizep, maxsize, elsize, elproc)
+\s-1XDR\s0 *xdrs;
+char **arrp;
+u_int *sizep, maxsize, elsize;
+xdrproc_t elproc;
+.fi
+.ft R
+.IP
+A filter primitive that translates between variable-length
+arrays
+and their corresponding external representations. The
+parameter
+.I arrp
+is the address of the pointer to the array, while
+.I sizep
+is the address of the element count of the array;
+this element count cannot exceed
+.IR maxsize .
+The parameter
+.I elsize
+is the
+.I sizeof
+each of the array's elements, and
+.I elproc
+is an
+.SM XDR
+filter that translates between
+the array elements' C form, and their external
+representation.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_bool(xdrs, bp)
+\s-1XDR\s0 *xdrs;
+bool_t *bp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between booleans (C
+integers)
+and their external representations. When encoding data, this
+filter produces values of either one or zero.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_bytes(xdrs, sp, sizep, maxsize)
+\s-1XDR\s0 *xdrs;
+char **sp;
+u_int *sizep, maxsize;
+.fi
+.ft R
+.IP
+A filter primitive that translates between counted byte
+strings and their external representations.
+The parameter
+.I sp
+is the address of the string pointer. The length of the
+string is located at address
+.IR sizep ;
+strings cannot be longer than
+.IR maxsize .
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_char(xdrs, cp)
+\s-1XDR\s0 *xdrs;
+char *cp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C characters
+and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+Note: encoded characters are not packed, and occupy 4 bytes
+each. For arrays of characters, it is worthwhile to
+consider
+.BR xdr_bytes(\|) ,
+.B xdr_opaque(\|)
+or
+.BR xdr_string(\|) .
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdr_destroy(xdrs)
+\s-1XDR\s0 *xdrs;
+.fi
+.ft R
+.IP
+A macro that invokes the destroy routine associated with the
+.SM XDR
+stream,
+.IR xdrs .
+Destruction usually involves freeing private data structures
+associated with the stream. Using
+.I xdrs
+after invoking
+.B xdr_destroy(\|)
+is undefined.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_double(xdrs, dp)
+\s-1XDR\s0 *xdrs;
+double *dp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B double
+precision numbers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_enum(xdrs, ep)
+\s-1XDR\s0 *xdrs;
+enum_t *ep;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.BR enum s
+(actually integers) and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_float(xdrs, fp)
+\s-1XDR\s0 *xdrs;
+float *fp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.BR float s
+and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdr_free(proc, objp)
+xdrproc_t proc;
+char *objp;
+.fi
+.ft R
+.IP
+Generic freeing routine. The first argument is the
+.SM XDR
+routine for the object being freed. The second argument
+is a pointer to the object itself. Note: the pointer passed
+to this routine is
+.I not
+freed, but what it points to
+.I is
+freed (recursively).
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+u_int
+xdr_getpos(xdrs)
+\s-1XDR\s0 *xdrs;
+.fi
+.ft R
+.IP
+A macro that invokes the get-position routine
+associated with the
+.SM XDR
+stream,
+.IR xdrs .
+The routine returns an unsigned integer,
+which indicates the position of the
+.SM XDR
+byte stream.
+A desirable feature of
+.SM XDR
+streams is that simple arithmetic works with this number,
+although the
+.SM XDR
+stream instances need not guarantee this.
+.br
+.if t .ne 4
+.LP
+.ft B
+.nf
+.sp .5
+.br
+long *
+xdr_inline(xdrs, len)
+\s-1XDR\s0 *xdrs;
+int len;
+.fi
+.ft R
+.IP
+A macro that invokes the in-line routine associated with the
+.SM XDR
+stream,
+.IR xdrs .
+The routine returns a pointer
+to a contiguous piece of the stream's buffer;
+.I len
+is the byte length of the desired buffer.
+Note: pointer is cast to
+.BR "long *" .
+.IP
+Warning:
+.B xdr_inline(\|)
+may return
+.SM NULL
+(0)
+if it cannot allocate a contiguous piece of a buffer.
+Therefore the behavior may vary among stream instances;
+it exists for the sake of efficiency.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_int(xdrs, ip)
+\s-1XDR\s0 *xdrs;
+int *ip;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C integers
+and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_long(xdrs, lp)
+\s-1XDR\s0 *xdrs;
+long *lp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B long
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 12
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdrmem_create(xdrs, addr, size, op)
+\s-1XDR\s0 *xdrs;
+char *addr;
+u_int size;
+enum xdr_op op;
+.fi
+.ft R
+.IP
+This routine initializes the
+.SM XDR
+stream object pointed to by
+.IR xdrs .
+The stream's data is written to, or read from,
+a chunk of memory at location
+.I addr
+whose length is no more than
+.I size
+bytes long. The
+.I op
+determines the direction of the
+.SM XDR
+stream
+(either
+.BR \s-1XDR_ENCODE\s0 ,
+.BR \s-1XDR_DECODE\s0 ,
+or
+.BR \s-1XDR_FREE\s0 ).
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_opaque(xdrs, cp, cnt)
+\s-1XDR\s0 *xdrs;
+char *cp;
+u_int cnt;
+.fi
+.ft R
+.IP
+A filter primitive that translates between fixed size opaque
+data
+and its external representation.
+The parameter
+.I cp
+is the address of the opaque object, and
+.I cnt
+is its size in bytes.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_pointer(xdrs, objpp, objsize, xdrobj)
+\s-1XDR\s0 *xdrs;
+char **objpp;
+u_int objsize;
+xdrproc_t xdrobj;
+.fi
+.ft R
+.IP
+Like
+.B xdr_reference(\|)
+execpt that it serializes
+.SM NULL
+pointers, whereas
+.B xdr_reference(\|)
+does not. Thus,
+.B xdr_pointer(\|)
+can represent
+recursive data structures, such as binary trees or
+linked lists.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdrrec_create(xdrs, sendsize, recvsize, handle, readit, writeit)
+\s-1XDR\s0 *xdrs;
+u_int sendsize, recvsize;
+char *handle;
+int (*readit) (\|), (*writeit) (\|);
+.fi
+.ft R
+.IP
+This routine initializes the
+.SM XDR
+stream object pointed to by
+.IR xdrs .
+The stream's data is written to a buffer of size
+.IR sendsize ;
+a value of zero indicates the system should use a suitable
+default. The stream's data is read from a buffer of size
+.IR recvsize ;
+it too can be set to a suitable default by passing a zero
+value.
+When a stream's output buffer is full,
+.I writeit
+is called. Similarly, when a stream's input buffer is empty,
+.I readit
+is called. The behavior of these two routines is similar to
+the
+system calls
+.B read
+and
+.BR write ,
+except that
+.I handle
+is passed to the former routines as the first parameter.
+Note: the
+.SM XDR
+stream's
+.I op
+field must be set by the caller.
+.IP
+Warning: this
+.SM XDR
+stream implements an intermediate record stream.
+Therefore there are additional bytes in the stream
+to provide record boundary information.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+xdrrec_endofrecord(xdrs, sendnow)
+\s-1XDR\s0 *xdrs;
+int sendnow;
+.fi
+.ft R
+.IP
+This routine can be invoked only on
+streams created by
+.BR xdrrec_create(\|) .
+The data in the output buffer is marked as a completed
+record,
+and the output buffer is optionally written out if
+.I sendnow
+is non-zero. This routine returns one if it succeeds, zero
+otherwise.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdrrec_eof(xdrs)
+\s-1XDR\s0 *xdrs;
+int empty;
+.fi
+.ft R
+.IP
+This routine can be invoked only on
+streams created by
+.BR xdrrec_create(\|) .
+After consuming the rest of the current record in the stream,
+this routine returns one if the stream has no more input,
+zero otherwise.
+.br
+.if t .ne 3
+.LP
+.ft B
+.nf
+.sp .5
+xdrrec_skiprecord(xdrs)
+\s-1XDR\s0 *xdrs;
+.fi
+.ft R
+.IP
+This routine can be invoked only on
+streams created by
+.BR xdrrec_create(\|) .
+It tells the
+.SM XDR
+implementation that the rest of the current record
+in the stream's input buffer should be discarded.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+xdr_reference(xdrs, pp, size, proc)
+\s-1XDR\s0 *xdrs;
+char **pp;
+u_int size;
+xdrproc_t proc;
+.fi
+.ft R
+.IP
+A primitive that provides pointer chasing within structures.
+The parameter
+.I pp
+is the address of the pointer;
+.I size
+is the
+.I sizeof
+the structure that
+.I *pp
+points to; and
+.I proc
+is an
+.SM XDR
+procedure that filters the structure
+between its C form and its external representation.
+This routine returns one if it succeeds, zero otherwise.
+.IP
+Warning: this routine does not understand
+.SM NULL
+pointers. Use
+.B xdr_pointer(\|)
+instead.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_setpos(xdrs, pos)
+\s-1XDR\s0 *xdrs;
+u_int pos;
+.fi
+.ft R
+.IP
+A macro that invokes the set position routine associated with
+the
+.SM XDR
+stream
+.IR xdrs .
+The parameter
+.I pos
+is a position value obtained from
+.BR xdr_getpos(\|) .
+This routine returns one if the
+.SM XDR
+stream could be repositioned,
+and zero otherwise.
+.IP
+Warning: it is difficult to reposition some types of
+.SM XDR
+streams, so this routine may fail with one
+type of stream and succeed with another.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_short(xdrs, sp)
+\s-1XDR\s0 *xdrs;
+short *sp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B short
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdrstdio_create(xdrs, file, op)
+\s-1XDR\s0 *xdrs;
+\s-1FILE\s0 *file;
+enum xdr_op op;
+.fi
+.ft R
+.IP
+This routine initializes the
+.SM XDR
+stream object pointed to by
+.IR xdrs .
+The
+.SM XDR
+stream data is written to, or read from, the Standard
+.B I/O
+stream
+.IR file .
+The parameter
+.I op
+determines the direction of the
+.SM XDR
+stream (either
+.BR \s-1XDR_ENCODE\s0 ,
+.BR \s-1XDR_DECODE\s0 ,
+or
+.BR \s-1XDR_FREE\s0 ).
+.IP
+Warning: the destroy routine associated with such
+.SM XDR
+streams calls
+.B fflush(\|)
+on the
+.I file
+stream, but never
+.BR fclose(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+xdr_string(xdrs, sp, maxsize)
+\s-1XDR\s0
+*xdrs;
+char **sp;
+u_int maxsize;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C strings and
+their
+corresponding external representations.
+Strings cannot be longer than
+.IR maxsize .
+Note:
+.I sp
+is the address of the string's pointer.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_u_char(xdrs, ucp)
+\s-1XDR\s0 *xdrs;
+unsigned char *ucp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between
+.B unsigned
+C characters and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+xdr_u_int(xdrs, up)
+\s-1XDR\s0 *xdrs;
+unsigned *up;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B unsigned
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_u_long(xdrs, ulp)
+\s-1XDR\s0 *xdrs;
+unsigned long *ulp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B "unsigned long"
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_u_short(xdrs, usp)
+\s-1XDR\s0 *xdrs;
+unsigned short *usp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B "unsigned short"
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 16
+.LP
+.ft B
+.nf
+.sp .5
+xdr_union(xdrs, dscmp, unp, choices, dfault)
+\s-1XDR\s0 *xdrs;
+int *dscmp;
+char *unp;
+struct xdr_discrim *choices;
+bool_t (*defaultarm) (\|); /* may equal \s-1NULL\s0 */
+.fi
+.ft R
+.IP
+A filter primitive that translates between a discriminated C
+.B union
+and its corresponding external representation. It first
+translates the discriminant of the union located at
+.IR dscmp .
+This discriminant is always an
+.BR enum_t .
+Next the union located at
+.I unp
+is translated. The parameter
+.I choices
+is a pointer to an array of
+.B xdr_discrim(\|)
+structures. Each structure contains an ordered pair of
+.RI [ value , proc ].
+If the union's discriminant is equal to the associated
+.IR value ,
+then the
+.I proc
+is called to translate the union. The end of the
+.B xdr_discrim(\|)
+structure array is denoted by a routine of value
+.SM NULL\s0.
+If the discriminant is not found in the
+.I choices
+array, then the
+.I defaultarm
+procedure is called (if it is not
+.SM NULL\s0).
+Returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+xdr_vector(xdrs, arrp, size, elsize, elproc)
+\s-1XDR\s0 *xdrs;
+char *arrp;
+u_int size, elsize;
+xdrproc_t elproc;
+.fi
+.ft R
+.IP
+A filter primitive that translates between fixed-length
+arrays
+and their corresponding external representations. The
+parameter
+.I arrp
+is the address of the pointer to the array, while
+.I size
+is the element count of the array. The parameter
+.I elsize
+is the
+.I sizeof
+each of the array's elements, and
+.I elproc
+is an
+.SM XDR
+filter that translates between
+the array elements' C form, and their external
+representation.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 5
+.LP
+.ft B
+.nf
+.sp .5
+xdr_void(\|)
+.fi
+.ft R
+.IP
+This routine always returns one.
+It may be passed to
+.SM RPC
+routines that require a function parameter,
+where nothing is to be done.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_wrapstring(xdrs, sp)
+\s-1XDR\s0 *xdrs;
+char **sp;
+.fi
+.ft R
+.IP
+A primitive that calls
+.B "xdr_string(xdrs, sp,\s-1MAXUN.UNSIGNED\s0 );"
+where
+.B
+.SM MAXUN.UNSIGNED
+is the maximum value of an unsigned integer.
+.B xdr_wrapstring(\|)
+is handy because the
+.SM RPC
+package passes a maximum of two
+.SM XDR
+routines as parameters, and
+.BR xdr_string(\|) ,
+one of the most frequently used primitives, requires three.
+Returns one if it succeeds, zero otherwise.
+.SH SEE ALSO
+.BR rpc (3)
+.LP
+The following manuals:
+.RS
+.ft I
+eXternal Data Representation Standard: Protocol Specification
+.br
+eXternal Data Representation: Sun Technical Notes
+.ft R
+.br
+.IR "\s-1XDR\s0: External Data Representation Standard" ,
+.SM RFC1014, Sun Microsystems, Inc.,
+.SM USC-ISI\s0.
diff --git a/lib/libc/xdr/xdr.c b/lib/libc/xdr/xdr.c
new file mode 100644
index 0000000..956e2ff
--- /dev/null
+++ b/lib/libc/xdr/xdr.c
@@ -0,0 +1,775 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr.c 1.35 87/08/12";*/
+/*static char *sccsid = "from: @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * xdr.c, Generic XDR routines implementation.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ *
+ * These are the "generic" xdr routines used to serialize and de-serialize
+ * most common data items. See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+/*
+ * constants specific to the xdr "protocol"
+ */
+#define XDR_FALSE ((long) 0)
+#define XDR_TRUE ((long) 1)
+#define LASTUNSIGNED ((u_int) 0-1)
+
+/*
+ * for unit alignment
+ */
+static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
+
+/*
+ * Free a data structure using XDR
+ * Not a filter, but a convenient utility nonetheless
+ */
+void
+xdr_free(proc, objp)
+ xdrproc_t proc;
+ char *objp;
+{
+ XDR x;
+
+ x.x_op = XDR_FREE;
+ (*proc)(&x, objp);
+}
+
+/*
+ * XDR nothing
+ */
+bool_t
+xdr_void(/* xdrs, addr */)
+ /* XDR *xdrs; */
+ /* caddr_t addr; */
+{
+
+ return (TRUE);
+}
+
+
+/*
+ * XDR integers
+ */
+bool_t
+xdr_int(xdrs, ip)
+ XDR *xdrs;
+ int *ip;
+{
+ long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (long) *ip;
+ return (XDR_PUTLONG(xdrs, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *ip = (int) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned integers
+ */
+bool_t
+xdr_u_int(xdrs, up)
+ XDR *xdrs;
+ u_int *up;
+{
+ u_long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (u_long) *up;
+ return (XDR_PUTLONG(xdrs, (long *)&l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, (long *)&l)) {
+ return (FALSE);
+ }
+ *up = (u_int) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+
+/*
+ * XDR long integers
+ * same as xdr_u_long - open coded to save a proc call!
+ */
+bool_t
+xdr_long(xdrs, lp)
+ register XDR *xdrs;
+ long *lp;
+{
+ switch (xdrs->x_op) {
+ case XDR_ENCODE:
+ return (XDR_PUTLONG(xdrs, lp));
+ case XDR_DECODE:
+ return (XDR_GETLONG(xdrs, lp));
+ case XDR_FREE:
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned long integers
+ * same as xdr_long - open coded to save a proc call!
+ */
+bool_t
+xdr_u_long(xdrs, ulp)
+ register XDR *xdrs;
+ u_long *ulp;
+{
+ switch (xdrs->x_op) {
+ case XDR_ENCODE:
+ return (XDR_PUTLONG(xdrs, (long *)ulp));
+ case XDR_DECODE:
+ return (XDR_GETLONG(xdrs, (long *)ulp));
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+
+/*
+ * XDR 32-bit integers
+ * same as xdr_u_int32_t - open coded to save a proc call!
+ */
+bool_t
+xdr_int32_t(xdrs, int32_p)
+ register XDR *xdrs;
+ int32_t *int32_p;
+{
+ long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (long) *int32_p;
+ return (XDR_PUTLONG(xdrs, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *int32_p = (int32_t) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned 32-bit integers
+ * same as xdr_int32_t - open coded to save a proc call!
+ */
+bool_t
+xdr_u_int32_t(xdrs, u_int32_p)
+ register XDR *xdrs;
+ u_int32_t *u_int32_p;
+{
+ u_long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (u_long) *u_int32_p;
+ return (XDR_PUTLONG(xdrs, (long *)&l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, (long *)&l)) {
+ return (FALSE);
+ }
+ *u_int32_p = (u_int32_t) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * XDR 64-bit integers
+ */
+bool_t
+xdr_int64_t(xdrs, int64_p)
+ register XDR *xdrs;
+ int64_t *int64_p;
+{
+ int64_t x;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ return (xdr_opaque(xdrs, (caddr_t)int64_p, sizeof(int64_t)));
+
+ case XDR_DECODE:
+ if (!xdr_opaque(xdrs, (caddr_t)&x, sizeof x)) {
+ return (FALSE);
+ }
+ *int64_p = x;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned 64-bit integers
+ */
+bool_t
+xdr_u_int64_t(xdrs, uint64_p)
+ register XDR *xdrs;
+ u_int64_t *uint64_p;
+{
+ u_int64_t x;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ return (xdr_opaque(xdrs, (caddr_t)uint64_p, sizeof(u_int64_t)));
+
+ case XDR_DECODE:
+ if (!xdr_opaque(xdrs, (caddr_t)&x, sizeof x)) {
+ return (FALSE);
+ }
+ *uint64_p = x;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+
+/*
+ * XDR short integers
+ */
+bool_t
+xdr_short(xdrs, sp)
+ register XDR *xdrs;
+ short *sp;
+{
+ long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (long) *sp;
+ return (XDR_PUTLONG(xdrs, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *sp = (short) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned short integers
+ */
+bool_t
+xdr_u_short(xdrs, usp)
+ register XDR *xdrs;
+ u_short *usp;
+{
+ u_long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (u_long) *usp;
+ return (XDR_PUTLONG(xdrs, (long *)&l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, (long *)&l)) {
+ return (FALSE);
+ }
+ *usp = (u_short) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+
+/*
+ * XDR 16-bit integers
+ */
+bool_t
+xdr_int16_t(xdrs, int16_p)
+ register XDR *xdrs;
+ int16_t *int16_p;
+{
+ long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (long) *int16_p;
+ return (XDR_PUTLONG(xdrs, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *int16_p = (int16_t) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned 16-bit integers
+ */
+bool_t
+xdr_u_int16_t(xdrs, u_int16_p)
+ register XDR *xdrs;
+ u_int16_t *u_int16_p;
+{
+ u_long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (u_long) *u_int16_p;
+ return (XDR_PUTLONG(xdrs, (long *)&l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, (long *)&l)) {
+ return (FALSE);
+ }
+ *u_int16_p = (u_int16_t) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+
+/*
+ * XDR a char
+ */
+bool_t
+xdr_char(xdrs, cp)
+ XDR *xdrs;
+ char *cp;
+{
+ int i;
+
+ i = (*cp);
+ if (!xdr_int(xdrs, &i)) {
+ return (FALSE);
+ }
+ *cp = i;
+ return (TRUE);
+}
+
+/*
+ * XDR an unsigned char
+ */
+bool_t
+xdr_u_char(xdrs, cp)
+ XDR *xdrs;
+ u_char *cp;
+{
+ u_int u;
+
+ u = (*cp);
+ if (!xdr_u_int(xdrs, &u)) {
+ return (FALSE);
+ }
+ *cp = u;
+ return (TRUE);
+}
+
+/*
+ * XDR booleans
+ */
+bool_t
+xdr_bool(xdrs, bp)
+ register XDR *xdrs;
+ bool_t *bp;
+{
+ long lb;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ lb = *bp ? XDR_TRUE : XDR_FALSE;
+ return (XDR_PUTLONG(xdrs, &lb));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &lb)) {
+ return (FALSE);
+ }
+ *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * XDR enumerations
+ */
+bool_t
+xdr_enum(xdrs, ep)
+ XDR *xdrs;
+ enum_t *ep;
+{
+#ifndef lint
+ enum sizecheck { SIZEVAL }; /* used to find the size of an enum */
+
+ /*
+ * enums are treated as ints
+ */
+ if (sizeof (enum sizecheck) == sizeof (long)) {
+ return (xdr_long(xdrs, (long *)ep));
+ } else if (sizeof (enum sizecheck) == sizeof (int)) {
+ return (xdr_int(xdrs, (int *)ep));
+ } else if (sizeof (enum sizecheck) == sizeof (short)) {
+ return (xdr_short(xdrs, (short *)ep));
+ } else {
+ return (FALSE);
+ }
+#else
+ (void) (xdr_short(xdrs, (short *)ep));
+ (void) (xdr_int(xdrs, (int *)ep));
+ return (xdr_long(xdrs, (long *)ep));
+#endif
+}
+
+/*
+ * XDR opaque data
+ * Allows the specification of a fixed size sequence of opaque bytes.
+ * cp points to the opaque object and cnt gives the byte length.
+ */
+bool_t
+xdr_opaque(xdrs, cp, cnt)
+ register XDR *xdrs;
+ caddr_t cp;
+ register u_int cnt;
+{
+ register u_int rndup;
+ static crud[BYTES_PER_XDR_UNIT];
+
+ /*
+ * if no data we are done
+ */
+ if (cnt == 0)
+ return (TRUE);
+
+ /*
+ * round byte count to full xdr units
+ */
+ rndup = cnt % BYTES_PER_XDR_UNIT;
+ if (rndup > 0)
+ rndup = BYTES_PER_XDR_UNIT - rndup;
+
+ if (xdrs->x_op == XDR_DECODE) {
+ if (!XDR_GETBYTES(xdrs, cp, cnt)) {
+ return (FALSE);
+ }
+ if (rndup == 0)
+ return (TRUE);
+ return (XDR_GETBYTES(xdrs, (caddr_t)crud, rndup));
+ }
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
+ return (FALSE);
+ }
+ if (rndup == 0)
+ return (TRUE);
+ return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
+ }
+
+ if (xdrs->x_op == XDR_FREE) {
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+/*
+ * XDR counted bytes
+ * *cpp is a pointer to the bytes, *sizep is the count.
+ * If *cpp is NULL maxsize bytes are allocated
+ */
+bool_t
+xdr_bytes(xdrs, cpp, sizep, maxsize)
+ register XDR *xdrs;
+ char **cpp;
+ register u_int *sizep;
+ u_int maxsize;
+{
+ register char *sp = *cpp; /* sp is the actual string pointer */
+ register u_int nodesize;
+
+ /*
+ * first deal with the length since xdr bytes are counted
+ */
+ if (! xdr_u_int(xdrs, sizep)) {
+ return (FALSE);
+ }
+ nodesize = *sizep;
+ if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
+ return (FALSE);
+ }
+
+ /*
+ * now deal with the actual bytes
+ */
+ switch (xdrs->x_op) {
+
+ case XDR_DECODE:
+ if (nodesize == 0) {
+ return (TRUE);
+ }
+ if (sp == NULL) {
+ *cpp = sp = (char *)mem_alloc(nodesize);
+ }
+ if (sp == NULL) {
+ (void) fprintf(stderr, "xdr_bytes: out of memory\n");
+ return (FALSE);
+ }
+ /* fall into ... */
+
+ case XDR_ENCODE:
+ return (xdr_opaque(xdrs, sp, nodesize));
+
+ case XDR_FREE:
+ if (sp != NULL) {
+ mem_free(sp, nodesize);
+ *cpp = NULL;
+ }
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * Implemented here due to commonality of the object.
+ */
+bool_t
+xdr_netobj(xdrs, np)
+ XDR *xdrs;
+ struct netobj *np;
+{
+
+ return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
+}
+
+/*
+ * XDR a descriminated union
+ * Support routine for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * an entry with a null procedure pointer. The routine gets
+ * the discriminant value and then searches the array of xdrdiscrims
+ * looking for that value. It calls the procedure given in the xdrdiscrim
+ * to handle the discriminant. If there is no specific routine a default
+ * routine may be called.
+ * If there is no specific or default routine an error is returned.
+ */
+bool_t
+xdr_union(xdrs, dscmp, unp, choices, dfault)
+ register XDR *xdrs;
+ enum_t *dscmp; /* enum to decide which arm to work on */
+ char *unp; /* the union itself */
+ struct xdr_discrim *choices; /* [value, xdr proc] for each arm */
+ xdrproc_t dfault; /* default xdr routine */
+{
+ register enum_t dscm;
+
+ /*
+ * we deal with the discriminator; it's an enum
+ */
+ if (! xdr_enum(xdrs, dscmp)) {
+ return (FALSE);
+ }
+ dscm = *dscmp;
+
+ /*
+ * search choices for a value that matches the discriminator.
+ * if we find one, execute the xdr routine for that value.
+ */
+ for (; choices->proc != NULL_xdrproc_t; choices++) {
+ if (choices->value == dscm)
+ return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
+ }
+
+ /*
+ * no match - execute the default xdr routine if there is one
+ */
+ return ((dfault == NULL_xdrproc_t) ? FALSE :
+ (*dfault)(xdrs, unp, LASTUNSIGNED));
+}
+
+
+/*
+ * Non-portable xdr primitives.
+ * Care should be taken when moving these routines to new architectures.
+ */
+
+
+/*
+ * XDR null terminated ASCII strings
+ * xdr_string deals with "C strings" - arrays of bytes that are
+ * terminated by a NULL character. The parameter cpp references a
+ * pointer to storage; If the pointer is null, then the necessary
+ * storage is allocated. The last parameter is the max allowed length
+ * of the string as specified by a protocol.
+ */
+bool_t
+xdr_string(xdrs, cpp, maxsize)
+ register XDR *xdrs;
+ char **cpp;
+ u_int maxsize;
+{
+ register char *sp = *cpp; /* sp is the actual string pointer */
+ u_int size;
+ u_int nodesize;
+
+ /*
+ * first deal with the length since xdr strings are counted-strings
+ */
+ switch (xdrs->x_op) {
+ case XDR_FREE:
+ if (sp == NULL) {
+ return(TRUE); /* already free */
+ }
+ /* fall through... */
+ case XDR_ENCODE:
+ size = strlen(sp);
+ break;
+ }
+ if (! xdr_u_int(xdrs, &size)) {
+ return (FALSE);
+ }
+ if (size > maxsize) {
+ return (FALSE);
+ }
+ nodesize = size + 1;
+
+ /*
+ * now deal with the actual bytes
+ */
+ switch (xdrs->x_op) {
+
+ case XDR_DECODE:
+ if (nodesize == 0) {
+ return (TRUE);
+ }
+ if (sp == NULL)
+ *cpp = sp = (char *)mem_alloc(nodesize);
+ if (sp == NULL) {
+ (void) fprintf(stderr, "xdr_string: out of memory\n");
+ return (FALSE);
+ }
+ sp[size] = 0;
+ /* fall into ... */
+
+ case XDR_ENCODE:
+ return (xdr_opaque(xdrs, sp, size));
+
+ case XDR_FREE:
+ mem_free(sp, nodesize);
+ *cpp = NULL;
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * Wrapper for xdr_string that can be called directly from
+ * routines like clnt_call
+ */
+bool_t
+xdr_wrapstring(xdrs, cpp)
+ XDR *xdrs;
+ char **cpp;
+{
+ return xdr_string(xdrs, cpp, LASTUNSIGNED);
+}
diff --git a/lib/libc/xdr/xdr_array.c b/lib/libc/xdr/xdr_array.c
new file mode 100644
index 0000000..b7d36fe
--- /dev/null
+++ b/lib/libc/xdr/xdr_array.c
@@ -0,0 +1,155 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * xdr_array.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * arrays. See xdr.h for more info on the interface to xdr.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#define LASTUNSIGNED ((u_int) 0-1)
+
+/*
+ * XDR an array of arbitrary elements
+ * *addrp is a pointer to the array, *sizep is the number of elements.
+ * If addrp is NULL (*sizep * elsize) bytes are allocated.
+ * elsize is the size (in bytes) of each element, and elproc is the
+ * xdr procedure to call to handle each element of the array.
+ */
+bool_t
+xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc)
+ register XDR *xdrs;
+ caddr_t *addrp; /* array pointer */
+ u_int *sizep; /* number of elements */
+ u_int maxsize; /* max numberof elements */
+ u_int elsize; /* size in bytes of each element */
+ xdrproc_t elproc; /* xdr routine to handle each element */
+{
+ register u_int i;
+ register caddr_t target = *addrp;
+ register u_int c; /* the actual element count */
+ register bool_t stat = TRUE;
+ register u_int nodesize;
+
+ /* like strings, arrays are really counted arrays */
+ if (! xdr_u_int(xdrs, sizep)) {
+ return (FALSE);
+ }
+ c = *sizep;
+ if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
+ return (FALSE);
+ }
+ nodesize = c * elsize;
+
+ /*
+ * if we are deserializing, we may need to allocate an array.
+ * We also save time by checking for a null array if we are freeing.
+ */
+ if (target == NULL)
+ switch (xdrs->x_op) {
+ case XDR_DECODE:
+ if (c == 0)
+ return (TRUE);
+ *addrp = target = mem_alloc(nodesize);
+ if (target == NULL) {
+ (void) fprintf(stderr,
+ "xdr_array: out of memory\n");
+ return (FALSE);
+ }
+ memset(target, 0, nodesize);
+ break;
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+
+ /*
+ * now we xdr each element of array
+ */
+ for (i = 0; (i < c) && stat; i++) {
+ stat = (*elproc)(xdrs, target, LASTUNSIGNED);
+ target += elsize;
+ }
+
+ /*
+ * the array may need freeing
+ */
+ if (xdrs->x_op == XDR_FREE) {
+ mem_free(*addrp, nodesize);
+ *addrp = NULL;
+ }
+ return (stat);
+}
+
+/*
+ * xdr_vector():
+ *
+ * XDR a fixed length array. Unlike variable-length arrays,
+ * the storage of fixed length arrays is static and unfreeable.
+ * > basep: base of the array
+ * > size: size of the array
+ * > elemsize: size of each element
+ * > xdr_elem: routine to XDR each element
+ */
+bool_t
+xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem)
+ register XDR *xdrs;
+ register char *basep;
+ register u_int nelem;
+ register u_int elemsize;
+ register xdrproc_t xdr_elem;
+{
+ register u_int i;
+ register char *elptr;
+
+ elptr = basep;
+ for (i = 0; i < nelem; i++) {
+ if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) {
+ return(FALSE);
+ }
+ elptr += elemsize;
+ }
+ return(TRUE);
+}
+
diff --git a/lib/libc/xdr/xdr_float.c b/lib/libc/xdr/xdr_float.c
new file mode 100644
index 0000000..0ffbeb3
--- /dev/null
+++ b/lib/libc/xdr/xdr_float.c
@@ -0,0 +1,314 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * xdr_float.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "floating point" xdr routines used to (de)serialize
+ * most common data items. See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+/*
+ * NB: Not portable.
+ * This routine works on machines with IEEE754 FP and Vaxen.
+ */
+
+#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
+ defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
+ defined(__arm32__) || defined(__ppc__)
+#include <machine/endian.h>
+#define IEEEFP
+#endif
+
+#ifdef vax
+
+/* What IEEE single precision floating point looks like on a Vax */
+struct ieee_single {
+ unsigned int mantissa: 23;
+ unsigned int exp : 8;
+ unsigned int sign : 1;
+};
+
+/* Vax single precision floating point */
+struct vax_single {
+ unsigned int mantissa1 : 7;
+ unsigned int exp : 8;
+ unsigned int sign : 1;
+ unsigned int mantissa2 : 16;
+};
+
+#define VAX_SNG_BIAS 0x81
+#define IEEE_SNG_BIAS 0x7f
+
+static struct sgl_limits {
+ struct vax_single s;
+ struct ieee_single ieee;
+} sgl_limits[2] = {
+ {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */
+ { 0x0, 0xff, 0x0 }}, /* Max IEEE */
+ {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
+ { 0x0, 0x0, 0x0 }} /* Min IEEE */
+};
+#endif /* vax */
+
+bool_t
+xdr_float(xdrs, fp)
+ register XDR *xdrs;
+ register float *fp;
+{
+#ifdef IEEEFP
+ bool_t rv;
+ long tmpl;
+#else
+ struct ieee_single is;
+ struct vax_single vs, *vsp;
+ struct sgl_limits *lim;
+ int i;
+#endif
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+#ifdef IEEEFP
+ tmpl = *(int32_t *)fp;
+ return (XDR_PUTLONG(xdrs, &tmpl));
+#else
+ vs = *((struct vax_single *)fp);
+ for (i = 0, lim = sgl_limits;
+ i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
+ i++, lim++) {
+ if ((vs.mantissa2 == lim->s.mantissa2) &&
+ (vs.exp == lim->s.exp) &&
+ (vs.mantissa1 == lim->s.mantissa1)) {
+ is = lim->ieee;
+ goto shipit;
+ }
+ }
+ is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
+ is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
+ shipit:
+ is.sign = vs.sign;
+ return (XDR_PUTLONG(xdrs, (long *)&is));
+#endif
+
+ case XDR_DECODE:
+#ifdef IEEEFP
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *(int32_t *)fp = tmpl;
+ return (rv);
+#else
+ vsp = (struct vax_single *)fp;
+ if (!XDR_GETLONG(xdrs, (long *)&is))
+ return (FALSE);
+ for (i = 0, lim = sgl_limits;
+ i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
+ i++, lim++) {
+ if ((is.exp == lim->ieee.exp) &&
+ (is.mantissa == lim->ieee.mantissa)) {
+ *vsp = lim->s;
+ goto doneit;
+ }
+ }
+ vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
+ vsp->mantissa2 = is.mantissa;
+ vsp->mantissa1 = (is.mantissa >> 16);
+ doneit:
+ vsp->sign = is.sign;
+ return (TRUE);
+#endif
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+#ifdef vax
+/* What IEEE double precision floating point looks like on a Vax */
+struct ieee_double {
+ unsigned int mantissa1 : 20;
+ unsigned int exp : 11;
+ unsigned int sign : 1;
+ unsigned int mantissa2 : 32;
+};
+
+/* Vax double precision floating point */
+struct vax_double {
+ unsigned int mantissa1 : 7;
+ unsigned int exp : 8;
+ unsigned int sign : 1;
+ unsigned int mantissa2 : 16;
+ unsigned int mantissa3 : 16;
+ unsigned int mantissa4 : 16;
+};
+
+#define VAX_DBL_BIAS 0x81
+#define IEEE_DBL_BIAS 0x3ff
+#define MASK(nbits) ((1 << nbits) - 1)
+
+static struct dbl_limits {
+ struct vax_double d;
+ struct ieee_double ieee;
+} dbl_limits[2] = {
+ {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
+ { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */
+ {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
+ { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
+};
+
+#endif /* vax */
+
+
+bool_t
+xdr_double(xdrs, dp)
+ register XDR *xdrs;
+ double *dp;
+{
+#ifdef IEEEFP
+ register int32_t *i32p;
+ bool_t rv;
+ long tmpl;
+#else
+ register long *lp;
+ struct ieee_double id;
+ struct vax_double vd;
+ register struct dbl_limits *lim;
+ int i;
+#endif
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+#ifdef IEEEFP
+ i32p = (int32_t *)dp;
+#if BYTE_ORDER == BIG_ENDIAN
+ tmpl = *i32p++;
+ rv = XDR_PUTLONG(xdrs, &tmpl);
+ if (!rv)
+ return (rv);
+ tmpl = *i32p;
+ rv = XDR_PUTLONG(xdrs, &tmpl);
+#else
+ tmpl = *(i32p+1);
+ rv = XDR_PUTLONG(xdrs, &tmpl);
+ if (!rv)
+ return (rv);
+ tmpl = *i32p;
+ rv = XDR_PUTLONG(xdrs, &tmpl);
+#endif
+ return (rv);
+#else
+ vd = *((struct vax_double *)dp);
+ for (i = 0, lim = dbl_limits;
+ i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
+ i++, lim++) {
+ if ((vd.mantissa4 == lim->d.mantissa4) &&
+ (vd.mantissa3 == lim->d.mantissa3) &&
+ (vd.mantissa2 == lim->d.mantissa2) &&
+ (vd.mantissa1 == lim->d.mantissa1) &&
+ (vd.exp == lim->d.exp)) {
+ id = lim->ieee;
+ goto shipit;
+ }
+ }
+ id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
+ id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
+ id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
+ (vd.mantissa3 << 13) |
+ ((vd.mantissa4 >> 3) & MASK(13));
+ shipit:
+ id.sign = vd.sign;
+ lp = (long *)&id;
+ return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
+#endif
+
+ case XDR_DECODE:
+#ifdef IEEEFP
+ i32p = (int32_t *)dp;
+#if BYTE_ORDER == BIG_ENDIAN
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *i32p++ = tmpl;
+ if (!rv)
+ return (rv);
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *i32p = tmpl;
+#else
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *(i32p+1) = tmpl;
+ if (!rv)
+ return (rv);
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *i32p = tmpl;
+#endif
+ return (rv);
+#else
+ lp = (long *)&id;
+ if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
+ return (FALSE);
+ for (i = 0, lim = dbl_limits;
+ i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
+ i++, lim++) {
+ if ((id.mantissa2 == lim->ieee.mantissa2) &&
+ (id.mantissa1 == lim->ieee.mantissa1) &&
+ (id.exp == lim->ieee.exp)) {
+ vd = lim->d;
+ goto doneit;
+ }
+ }
+ vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
+ vd.mantissa1 = (id.mantissa1 >> 13);
+ vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
+ (id.mantissa2 >> 29);
+ vd.mantissa3 = (id.mantissa2 >> 13);
+ vd.mantissa4 = (id.mantissa2 << 3);
+ doneit:
+ vd.sign = id.sign;
+ *dp = *((double *)&vd);
+ return (TRUE);
+#endif
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
diff --git a/lib/libc/xdr/xdr_mem.c b/lib/libc/xdr/xdr_mem.c
new file mode 100644
index 0000000..3193e64
--- /dev/null
+++ b/lib/libc/xdr/xdr_mem.c
@@ -0,0 +1,242 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * xdr_mem.h, XDR implementation using memory buffers.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * If you have some data to be interpreted as external data representation
+ * or to be converted to external data representation in a memory buffer,
+ * then this is the package for you.
+ *
+ */
+
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+static bool_t xdrmem_getlong_aligned();
+static bool_t xdrmem_putlong_aligned();
+static bool_t xdrmem_getlong_unaligned();
+static bool_t xdrmem_putlong_unaligned();
+static bool_t xdrmem_getbytes();
+static bool_t xdrmem_putbytes();
+static u_int xdrmem_getpos(); /* XXX w/64-bit pointers, u_int not enough! */
+static bool_t xdrmem_setpos();
+static int32_t *xdrmem_inline_aligned();
+static int32_t *xdrmem_inline_unaligned();
+static void xdrmem_destroy();
+
+static struct xdr_ops xdrmem_ops_aligned = {
+ xdrmem_getlong_aligned,
+ xdrmem_putlong_aligned,
+ xdrmem_getbytes,
+ xdrmem_putbytes,
+ xdrmem_getpos,
+ xdrmem_setpos,
+ xdrmem_inline_aligned,
+ xdrmem_destroy
+};
+
+static struct xdr_ops xdrmem_ops_unaligned = {
+ xdrmem_getlong_unaligned,
+ xdrmem_putlong_unaligned,
+ xdrmem_getbytes,
+ xdrmem_putbytes,
+ xdrmem_getpos,
+ xdrmem_setpos,
+ xdrmem_inline_unaligned,
+ xdrmem_destroy
+};
+
+/*
+ * The procedure xdrmem_create initializes a stream descriptor for a
+ * memory buffer.
+ */
+void
+xdrmem_create(xdrs, addr, size, op)
+ register XDR *xdrs;
+ caddr_t addr;
+ u_int size;
+ enum xdr_op op;
+{
+
+ xdrs->x_op = op;
+ xdrs->x_ops = ((size_t)addr & (sizeof(int32_t) - 1))
+ ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
+ xdrs->x_private = xdrs->x_base = addr;
+ xdrs->x_handy = size;
+}
+
+static void
+xdrmem_destroy(/*xdrs*/)
+ /*XDR *xdrs;*/
+{
+
+}
+
+static bool_t
+xdrmem_getlong_aligned(xdrs, lp)
+ register XDR *xdrs;
+ long *lp;
+{
+
+ if ((xdrs->x_handy -= sizeof(int32_t)) < 0)
+ return (FALSE);
+ *lp = ntohl(*(int32_t *)(xdrs->x_private));
+ xdrs->x_private += sizeof(int32_t);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_putlong_aligned(xdrs, lp)
+ register XDR *xdrs;
+ long *lp;
+{
+
+ if ((xdrs->x_handy -= sizeof(int32_t)) < 0)
+ return (FALSE);
+ *(int32_t *)xdrs->x_private = htonl(*lp);
+ xdrs->x_private += sizeof(int32_t);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_getlong_unaligned(xdrs, lp)
+ register XDR *xdrs;
+ long *lp;
+{
+ int32_t l;
+
+ if ((xdrs->x_handy -= sizeof(int32_t)) < 0)
+ return (FALSE);
+ memcpy(&l, xdrs->x_private, sizeof(int32_t));
+ *lp = ntohl(l);
+ xdrs->x_private += sizeof(int32_t);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_putlong_unaligned(xdrs, lp)
+ register XDR *xdrs;
+ long *lp;
+{
+ int32_t l;
+
+ if ((xdrs->x_handy -= sizeof(int32_t)) < 0)
+ return (FALSE);
+ l = htonl(*lp);
+ memcpy(xdrs->x_private, &l, sizeof(int32_t));
+ xdrs->x_private += sizeof(int32_t);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_getbytes(xdrs, addr, len)
+ register XDR *xdrs;
+ caddr_t addr;
+ register u_int len;
+{
+
+ if ((xdrs->x_handy -= len) < 0)
+ return (FALSE);
+ memcpy(addr, xdrs->x_private, len);
+ xdrs->x_private += len;
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_putbytes(xdrs, addr, len)
+ register XDR *xdrs;
+ caddr_t addr;
+ register u_int len;
+{
+
+ if ((xdrs->x_handy -= len) < 0)
+ return (FALSE);
+ memcpy(xdrs->x_private, addr, len);
+ xdrs->x_private += len;
+ return (TRUE);
+}
+
+static u_int
+xdrmem_getpos(xdrs)
+ register XDR *xdrs;
+{
+
+ /* XXX w/64-bit pointers, u_int not enough! */
+ return ((u_long)xdrs->x_private - (u_long)xdrs->x_base);
+}
+
+static bool_t
+xdrmem_setpos(xdrs, pos)
+ register XDR *xdrs;
+ u_int pos;
+{
+ register caddr_t newaddr = xdrs->x_base + pos;
+ register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
+
+ if ((long)newaddr > (long)lastaddr)
+ return (FALSE);
+ xdrs->x_private = newaddr;
+ xdrs->x_handy = (long)lastaddr - (long)newaddr;
+ return (TRUE);
+}
+
+static int32_t *
+xdrmem_inline_aligned(xdrs, len)
+ register XDR *xdrs;
+ int len;
+{
+ int32_t *buf = 0;
+
+ if (xdrs->x_handy >= len) {
+ xdrs->x_handy -= len;
+ buf = (int32_t *) xdrs->x_private;
+ xdrs->x_private += len;
+ }
+ return (buf);
+}
+
+static int32_t *
+xdrmem_inline_unaligned(xdrs, len)
+ register XDR *xdrs;
+ int len;
+{
+
+ return (0);
+}
diff --git a/lib/libc/xdr/xdr_rec.c b/lib/libc/xdr/xdr_rec.c
new file mode 100644
index 0000000..b96b634
--- /dev/null
+++ b/lib/libc/xdr/xdr_rec.c
@@ -0,0 +1,596 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
+ * layer above tcp (for rpc's use).
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These routines interface XDRSTREAMS to a tcp/ip connection.
+ * There is a record marking layer between the xdr stream
+ * and the tcp transport level. A record is composed on one or more
+ * record fragments. A record fragment is a thirty-two bit header followed
+ * by n bytes of data, where n is contained in the header. The header
+ * is represented as a htonl(u_long). Thegh order bit encodes
+ * whether or not the fragment is the last fragment of the record
+ * (1 => fragment is last, 0 => more fragments to follow.
+ * The other 31 bits encode the byte length of the fragment.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+static u_int fix_buf_size();
+static bool_t flush_out();
+static bool_t get_input_bytes();
+static bool_t set_input_fragment();
+static bool_t skip_input_bytes();
+
+static bool_t xdrrec_getlong();
+static bool_t xdrrec_putlong();
+static bool_t xdrrec_getbytes();
+static bool_t xdrrec_putbytes();
+static u_int xdrrec_getpos();
+static bool_t xdrrec_setpos();
+static int32_t *xdrrec_inline();
+static void xdrrec_destroy();
+
+static struct xdr_ops xdrrec_ops = {
+ xdrrec_getlong,
+ xdrrec_putlong,
+ xdrrec_getbytes,
+ xdrrec_putbytes,
+ xdrrec_getpos,
+ xdrrec_setpos,
+ xdrrec_inline,
+ xdrrec_destroy
+};
+
+/*
+ * A record is composed of one or more record fragments.
+ * A record fragment is a two-byte header followed by zero to
+ * 2**32-1 bytes. The header is treated as a long unsigned and is
+ * encode/decoded to the network via htonl/ntohl. The low order 31 bits
+ * are a byte count of the fragment. The highest order bit is a boolean:
+ * 1 => this fragment is the last fragment of the record,
+ * 0 => this fragment is followed by more fragment(s).
+ *
+ * The fragment/record machinery is not general; it is constructed to
+ * meet the needs of xdr and rpc based on tcp.
+ */
+
+#define LAST_FRAG ((u_int32_t)(1 << 31))
+
+typedef struct rec_strm {
+ caddr_t tcp_handle;
+ caddr_t the_buffer;
+ /*
+ * out-goung bits
+ */
+ int (*writeit) __P((caddr_t, caddr_t, int));
+ caddr_t out_base; /* output buffer (points to frag header) */
+ caddr_t out_finger; /* next output position */
+ caddr_t out_boundry; /* data cannot up to this address */
+ u_int32_t *frag_header; /* beginning of current fragment */
+ bool_t frag_sent; /* true if buffer sent in middle of record */
+ /*
+ * in-coming bits
+ */
+ int (*readit) __P((caddr_t, caddr_t, int));
+ u_long in_size; /* fixed size of the input buffer */
+ caddr_t in_base;
+ caddr_t in_finger; /* location of next byte to be had */
+ caddr_t in_boundry; /* can read up to this location */
+ long fbtbc; /* fragment bytes to be consumed */
+ bool_t last_frag;
+ u_int sendsize;
+ u_int recvsize;
+} RECSTREAM;
+
+
+/*
+ * Create an xdr handle for xdrrec
+ * xdrrec_create fills in xdrs. Sendsize and recvsize are
+ * send and recv buffer sizes (0 => use default).
+ * tcp_handle is an opaque handle that is passed as the first parameter to
+ * the procedures readit and writeit. Readit and writeit are read and
+ * write respectively. They are like the system
+ * calls expect that they take an opaque handle rather than an fd.
+ */
+void
+xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit)
+ register XDR *xdrs;
+ register u_int sendsize;
+ register u_int recvsize;
+ caddr_t tcp_handle;
+ int (*readit)(); /* like read, but pass it a tcp_handle, not sock */
+ int (*writeit)(); /* like write, but pass it a tcp_handle, not sock */
+{
+ register RECSTREAM *rstrm =
+ (RECSTREAM *)mem_alloc(sizeof(RECSTREAM));
+
+ if (rstrm == NULL) {
+ (void)fprintf(stderr, "xdrrec_create: out of memory\n");
+ /*
+ * This is bad. Should rework xdrrec_create to
+ * return a handle, and in this case return NULL
+ */
+ return;
+ }
+ /*
+ * adjust sizes and allocate buffer quad byte aligned
+ */
+ rstrm->sendsize = sendsize = fix_buf_size(sendsize);
+ rstrm->recvsize = recvsize = fix_buf_size(recvsize);
+ rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT);
+ if (rstrm->the_buffer == NULL) {
+ (void)fprintf(stderr, "xdrrec_create: out of memory\n");
+ return;
+ }
+ for (rstrm->out_base = rstrm->the_buffer;
+ (u_long)rstrm->out_base % BYTES_PER_XDR_UNIT != 0;
+ rstrm->out_base++);
+ rstrm->in_base = rstrm->out_base + sendsize;
+ /*
+ * now the rest ...
+ */
+ xdrs->x_ops = &xdrrec_ops;
+ xdrs->x_private = (caddr_t)rstrm;
+ rstrm->tcp_handle = tcp_handle;
+ rstrm->readit = readit;
+ rstrm->writeit = writeit;
+ rstrm->out_finger = rstrm->out_boundry = rstrm->out_base;
+ rstrm->frag_header = (u_int32_t *)rstrm->out_base;
+ rstrm->out_finger += sizeof(u_int32_t);
+ rstrm->out_boundry += sendsize;
+ rstrm->frag_sent = FALSE;
+ rstrm->in_size = recvsize;
+ rstrm->in_boundry = rstrm->in_base;
+ rstrm->in_finger = (rstrm->in_boundry += recvsize);
+ rstrm->fbtbc = 0;
+ rstrm->last_frag = TRUE;
+}
+
+
+/*
+ * The reoutines defined below are the xdr ops which will go into the
+ * xdr handle filled in by xdrrec_create.
+ */
+
+static bool_t
+xdrrec_getlong(xdrs, lp)
+ XDR *xdrs;
+ long *lp;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ register int32_t *buflp = (int32_t *)(rstrm->in_finger);
+ int32_t mylong;
+
+ /* first try the inline, fast case */
+ if ((rstrm->fbtbc >= sizeof(int32_t)) &&
+ (((long)rstrm->in_boundry - (long)buflp) >= sizeof(int32_t))) {
+ *lp = (long)ntohl((u_int32_t)(*buflp));
+ rstrm->fbtbc -= sizeof(int32_t);
+ rstrm->in_finger += sizeof(int32_t);
+ } else {
+ if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(int32_t)))
+ return (FALSE);
+ *lp = (long)ntohl((u_int32_t)mylong);
+ }
+ return (TRUE);
+}
+
+static bool_t
+xdrrec_putlong(xdrs, lp)
+ XDR *xdrs;
+ long *lp;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ register int32_t *dest_lp = ((int32_t *)(rstrm->out_finger));
+
+ if ((rstrm->out_finger += sizeof(int32_t)) > rstrm->out_boundry) {
+ /*
+ * this case should almost never happen so the code is
+ * inefficient
+ */
+ rstrm->out_finger -= sizeof(int32_t);
+ rstrm->frag_sent = TRUE;
+ if (! flush_out(rstrm, FALSE))
+ return (FALSE);
+ dest_lp = ((int32_t *)(rstrm->out_finger));
+ rstrm->out_finger += sizeof(int32_t);
+ }
+ *dest_lp = (int32_t)htonl((u_int32_t)(*lp));
+ return (TRUE);
+}
+
+static bool_t /* must manage buffers, fragments, and records */
+xdrrec_getbytes(xdrs, addr, len)
+ XDR *xdrs;
+ register caddr_t addr;
+ register u_int len;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ register int current;
+
+ while (len > 0) {
+ current = rstrm->fbtbc;
+ if (current == 0) {
+ if (rstrm->last_frag)
+ return (FALSE);
+ if (! set_input_fragment(rstrm))
+ return (FALSE);
+ continue;
+ }
+ current = (len < current) ? len : current;
+ if (! get_input_bytes(rstrm, addr, current))
+ return (FALSE);
+ addr += current;
+ rstrm->fbtbc -= current;
+ len -= current;
+ }
+ return (TRUE);
+}
+
+static bool_t
+xdrrec_putbytes(xdrs, addr, len)
+ XDR *xdrs;
+ register caddr_t addr;
+ register u_int len;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ register long current;
+
+ while (len > 0) {
+ current = (u_long)rstrm->out_boundry -
+ (u_long)rstrm->out_finger;
+ current = (len < current) ? len : current;
+ memcpy(rstrm->out_finger, addr, current);
+ rstrm->out_finger += current;
+ addr += current;
+ len -= current;
+ if (rstrm->out_finger == rstrm->out_boundry) {
+ rstrm->frag_sent = TRUE;
+ if (! flush_out(rstrm, FALSE))
+ return (FALSE);
+ }
+ }
+ return (TRUE);
+}
+
+static u_int
+xdrrec_getpos(xdrs)
+ register XDR *xdrs;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+ register long pos;
+
+ pos = lseek((int)(long)rstrm->tcp_handle, (off_t) 0, 1);
+ if (pos != -1)
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ pos += rstrm->out_finger - rstrm->out_base;
+ break;
+
+ case XDR_DECODE:
+ pos -= rstrm->in_boundry - rstrm->in_finger;
+ break;
+
+ default:
+ pos = -1;
+ break;
+ }
+ return ((u_int) pos);
+}
+
+static bool_t
+xdrrec_setpos(xdrs, pos)
+ register XDR *xdrs;
+ u_int pos;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+ u_int currpos = xdrrec_getpos(xdrs);
+ int delta = currpos - pos;
+ caddr_t newpos;
+
+ if ((int)currpos != -1)
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ newpos = rstrm->out_finger - delta;
+ if ((newpos > (caddr_t)(rstrm->frag_header)) &&
+ (newpos < rstrm->out_boundry)) {
+ rstrm->out_finger = newpos;
+ return (TRUE);
+ }
+ break;
+
+ case XDR_DECODE:
+ newpos = rstrm->in_finger - delta;
+ if ((delta < (int)(rstrm->fbtbc)) &&
+ (newpos <= rstrm->in_boundry) &&
+ (newpos >= rstrm->in_base)) {
+ rstrm->in_finger = newpos;
+ rstrm->fbtbc -= delta;
+ return (TRUE);
+ }
+ break;
+ }
+ return (FALSE);
+}
+
+static int32_t *
+xdrrec_inline(xdrs, len)
+ register XDR *xdrs;
+ int len;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+ int32_t * buf = NULL;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
+ buf = (int32_t *) rstrm->out_finger;
+ rstrm->out_finger += len;
+ }
+ break;
+
+ case XDR_DECODE:
+ if ((len <= rstrm->fbtbc) &&
+ ((rstrm->in_finger + len) <= rstrm->in_boundry)) {
+ buf = (int32_t *) rstrm->in_finger;
+ rstrm->fbtbc -= len;
+ rstrm->in_finger += len;
+ }
+ break;
+ }
+ return (buf);
+}
+
+static void
+xdrrec_destroy(xdrs)
+ register XDR *xdrs;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+
+ mem_free(rstrm->the_buffer,
+ rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT);
+ mem_free((caddr_t)rstrm, sizeof(RECSTREAM));
+}
+
+
+/*
+ * Exported routines to manage xdr records
+ */
+
+/*
+ * Before reading (deserializing from the stream, one should always call
+ * this procedure to guarantee proper record alignment.
+ */
+bool_t
+xdrrec_skiprecord(xdrs)
+ XDR *xdrs;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+
+ while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
+ if (! skip_input_bytes(rstrm, rstrm->fbtbc))
+ return (FALSE);
+ rstrm->fbtbc = 0;
+ if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
+ return (FALSE);
+ }
+ rstrm->last_frag = FALSE;
+ return (TRUE);
+}
+
+/*
+ * Look ahead fuction.
+ * Returns TRUE iff there is no more input in the buffer
+ * after consuming the rest of the current record.
+ */
+bool_t
+xdrrec_eof(xdrs)
+ XDR *xdrs;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+
+ while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
+ if (! skip_input_bytes(rstrm, rstrm->fbtbc))
+ return (TRUE);
+ rstrm->fbtbc = 0;
+ if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
+ return (TRUE);
+ }
+ if (rstrm->in_finger == rstrm->in_boundry)
+ return (TRUE);
+ return (FALSE);
+}
+
+/*
+ * The client must tell the package when an end-of-record has occurred.
+ * The second paraemters tells whether the record should be flushed to the
+ * (output) tcp stream. (This let's the package support batched or
+ * pipelined procedure calls.) TRUE => immmediate flush to tcp connection.
+ */
+bool_t
+xdrrec_endofrecord(xdrs, sendnow)
+ XDR *xdrs;
+ bool_t sendnow;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ register u_long len; /* fragment length */
+
+ if (sendnow || rstrm->frag_sent ||
+ ((u_long)rstrm->out_finger + sizeof(u_int32_t) >=
+ (u_long)rstrm->out_boundry)) {
+ rstrm->frag_sent = FALSE;
+ return (flush_out(rstrm, TRUE));
+ }
+ len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) -
+ sizeof(u_int32_t);
+ *(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG);
+ rstrm->frag_header = (u_int32_t *)rstrm->out_finger;
+ rstrm->out_finger += sizeof(u_int32_t);
+ return (TRUE);
+}
+
+
+/*
+ * Internal useful routines
+ */
+static bool_t
+flush_out(rstrm, eor)
+ register RECSTREAM *rstrm;
+ bool_t eor;
+{
+ register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0;
+ register u_int32_t len = (u_long)(rstrm->out_finger) -
+ (u_long)(rstrm->frag_header) - sizeof(u_int32_t);
+
+ *(rstrm->frag_header) = htonl(len | eormask);
+ len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base);
+ if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
+ != (int)len)
+ return (FALSE);
+ rstrm->frag_header = (u_int32_t *)rstrm->out_base;
+ rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_int32_t);
+ return (TRUE);
+}
+
+static bool_t /* knows nothing about records! Only about input buffers */
+fill_input_buf(rstrm)
+ register RECSTREAM *rstrm;
+{
+ register caddr_t where;
+ u_long i;
+ register long len;
+
+ where = rstrm->in_base;
+ i = (u_long)rstrm->in_boundry % BYTES_PER_XDR_UNIT;
+ where += i;
+ len = rstrm->in_size - i;
+ if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
+ return (FALSE);
+ rstrm->in_finger = where;
+ where += len;
+ rstrm->in_boundry = where;
+ return (TRUE);
+}
+
+static bool_t /* knows nothing about records! Only about input buffers */
+get_input_bytes(rstrm, addr, len)
+ register RECSTREAM *rstrm;
+ register caddr_t addr;
+ register int len;
+{
+ register long current;
+
+ while (len > 0) {
+ current = (long)rstrm->in_boundry - (long)rstrm->in_finger;
+ if (current == 0) {
+ if (! fill_input_buf(rstrm))
+ return (FALSE);
+ continue;
+ }
+ current = (len < current) ? len : current;
+ memcpy(addr, rstrm->in_finger, current);
+ rstrm->in_finger += current;
+ addr += current;
+ len -= current;
+ }
+ return (TRUE);
+}
+
+static bool_t /* next two bytes of the input stream are treated as a header */
+set_input_fragment(rstrm)
+ register RECSTREAM *rstrm;
+{
+ u_int32_t header;
+
+ if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header)))
+ return (FALSE);
+ header = (long)ntohl(header);
+ rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
+ /*
+ * Sanity check. Try not to accept wildly incorrect
+ * record sizes. Unfortunately, the only record size
+ * we can positively identify as being 'wildly incorrect'
+ * is zero. Ridiculously large record sizes may look wrong,
+ * but we don't have any way to be certain that they aren't
+ * what the client actually intended to send us.
+ */
+ if ((header & (~LAST_FRAG)) == 0)
+ return(FALSE);
+ rstrm->fbtbc = header & (~LAST_FRAG);
+ return (TRUE);
+}
+
+static bool_t /* consumes input bytes; knows nothing about records! */
+skip_input_bytes(rstrm, cnt)
+ register RECSTREAM *rstrm;
+ long cnt;
+{
+ register long current;
+
+ while (cnt > 0) {
+ current = (long)rstrm->in_boundry - (long)rstrm->in_finger;
+ if (current == 0) {
+ if (! fill_input_buf(rstrm))
+ return (FALSE);
+ continue;
+ }
+ current = (cnt < current) ? cnt : current;
+ rstrm->in_finger += current;
+ cnt -= current;
+ }
+ return (TRUE);
+}
+
+static u_int
+fix_buf_size(s)
+ register u_int s;
+{
+
+ if (s < 100)
+ s = 4000;
+ return (RNDUP(s));
+}
diff --git a/lib/libc/xdr/xdr_reference.c b/lib/libc/xdr/xdr_reference.c
new file mode 100644
index 0000000..b0cdbce
--- /dev/null
+++ b/lib/libc/xdr/xdr_reference.c
@@ -0,0 +1,136 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_reference.c 1.11 87/08/11 SMI";*/
+/*static char *sccsid = "from: @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * xdr_reference.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * "pointers". See xdr.h for more info on the interface to xdr.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#define LASTUNSIGNED ((u_int) 0-1)
+
+/*
+ * XDR an indirect pointer
+ * xdr_reference is for recursively translating a structure that is
+ * referenced by a pointer inside the structure that is currently being
+ * translated. pp references a pointer to storage. If *pp is null
+ * the necessary storage is allocated.
+ * size is the sizeof the referneced structure.
+ * proc is the routine to handle the referenced structure.
+ */
+bool_t
+xdr_reference(xdrs, pp, size, proc)
+ register XDR *xdrs;
+ caddr_t *pp; /* the pointer to work on */
+ u_int size; /* size of the object pointed to */
+ xdrproc_t proc; /* xdr routine to handle the object */
+{
+ register caddr_t loc = *pp;
+ register bool_t stat;
+
+ if (loc == NULL)
+ switch (xdrs->x_op) {
+ case XDR_FREE:
+ return (TRUE);
+
+ case XDR_DECODE:
+ *pp = loc = (caddr_t) mem_alloc(size);
+ if (loc == NULL) {
+ (void) fprintf(stderr,
+ "xdr_reference: out of memory\n");
+ return (FALSE);
+ }
+ memset(loc, 0, (int)size);
+ break;
+ }
+
+ stat = (*proc)(xdrs, loc, LASTUNSIGNED);
+
+ if (xdrs->x_op == XDR_FREE) {
+ mem_free(loc, size);
+ *pp = NULL;
+ }
+ return (stat);
+}
+
+
+/*
+ * xdr_pointer():
+ *
+ * XDR a pointer to a possibly recursive data structure. This
+ * differs with xdr_reference in that it can serialize/deserialiaze
+ * trees correctly.
+ *
+ * What's sent is actually a union:
+ *
+ * union object_pointer switch (boolean b) {
+ * case TRUE: object_data data;
+ * case FALSE: void nothing;
+ * }
+ *
+ * > objpp: Pointer to the pointer to the object.
+ * > obj_size: size of the object.
+ * > xdr_obj: routine to XDR an object.
+ *
+ */
+bool_t
+xdr_pointer(xdrs,objpp,obj_size,xdr_obj)
+ register XDR *xdrs;
+ char **objpp;
+ u_int obj_size;
+ xdrproc_t xdr_obj;
+{
+
+ bool_t more_data;
+
+ more_data = (*objpp != NULL);
+ if (! xdr_bool(xdrs,&more_data)) {
+ return (FALSE);
+ }
+ if (! more_data) {
+ *objpp = NULL;
+ return (TRUE);
+ }
+ return (xdr_reference(xdrs,objpp,obj_size,xdr_obj));
+}
diff --git a/lib/libc/xdr/xdr_sizeof.c b/lib/libc/xdr/xdr_sizeof.c
new file mode 100644
index 0000000..5a4c1a7
--- /dev/null
+++ b/lib/libc/xdr/xdr_sizeof.c
@@ -0,0 +1,163 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * xdr_sizeof.c
+ *
+ * Copyright 1990 Sun Microsystems, Inc.
+ *
+ * General purpose routine to see how much space something will use
+ * when serialized using XDR.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+/* ARGSUSED */
+static bool_t
+x_putlong(xdrs, longp)
+ XDR *xdrs;
+ long *longp;
+{
+ xdrs->x_handy += BYTES_PER_XDR_UNIT;
+ return (TRUE);
+}
+
+/* ARGSUSED */
+static bool_t
+x_putbytes(xdrs, bp, len)
+ XDR *xdrs;
+ char *bp;
+ int len;
+{
+ xdrs->x_handy += len;
+ return (TRUE);
+}
+
+static u_int
+x_getpostn(xdrs)
+ XDR *xdrs;
+{
+ return (xdrs->x_handy);
+}
+
+/* ARGSUSED */
+static bool_t
+x_setpostn(xdrs, pos)
+ XDR *xdrs;
+ u_int pos;
+{
+ /* This is not allowed */
+ return (FALSE);
+}
+
+static int32_t *
+x_inline(xdrs, len)
+ XDR *xdrs;
+ long len;
+{
+ if (len == 0) {
+ return (NULL);
+ }
+ if (xdrs->x_op != XDR_ENCODE) {
+ return (NULL);
+ }
+ if (len < (long) xdrs->x_base) {
+ /* x_private was already allocated */
+ xdrs->x_handy += len;
+ return ((int32_t *) xdrs->x_private);
+ } else {
+ /* Free the earlier space and allocate new area */
+ if (xdrs->x_private)
+ free(xdrs->x_private);
+ if ((xdrs->x_private = (caddr_t) malloc(len)) == NULL) {
+ xdrs->x_base = 0;
+ return (NULL);
+ }
+ xdrs->x_base = (caddr_t) len;
+ xdrs->x_handy += len;
+ return ((int32_t *) xdrs->x_private);
+ }
+}
+
+static int
+harmless()
+{
+ /* Always return FALSE/NULL, as the case may be */
+ return (0);
+}
+
+static void
+x_destroy(xdrs)
+ XDR *xdrs;
+{
+ xdrs->x_handy = 0;
+ xdrs->x_base = 0;
+ if (xdrs->x_private) {
+ free(xdrs->x_private);
+ xdrs->x_private = NULL;
+ }
+ return;
+}
+
+unsigned long
+xdr_sizeof(func, data)
+ xdrproc_t func;
+ void *data;
+{
+ XDR x;
+ struct xdr_ops ops;
+ bool_t stat;
+ /* to stop ANSI-C compiler from complaining */
+ typedef bool_t (* dummyfunc1)(XDR *, long *);
+ typedef bool_t (* dummyfunc2)(XDR *, caddr_t, u_int);
+
+ ops.x_putlong = x_putlong;
+ ops.x_putbytes = x_putbytes;
+ ops.x_inline = x_inline;
+ ops.x_getpostn = x_getpostn;
+ ops.x_setpostn = x_setpostn;
+ ops.x_destroy = x_destroy;
+
+ /* the other harmless ones */
+ ops.x_getlong = (dummyfunc1) harmless;
+ ops.x_getbytes = (dummyfunc2) harmless;
+
+ x.x_op = XDR_ENCODE;
+ x.x_ops = &ops;
+ x.x_handy = 0;
+ x.x_private = (caddr_t) NULL;
+ x.x_base = (caddr_t) 0;
+
+ stat = func(&x, data);
+ if (x.x_private)
+ free(x.x_private);
+ return (stat == TRUE ? (unsigned) x.x_handy: 0);
+}
diff --git a/lib/libc/xdr/xdr_stdio.c b/lib/libc/xdr/xdr_stdio.c
new file mode 100644
index 0000000..708573c
--- /dev/null
+++ b/lib/libc/xdr/xdr_stdio.c
@@ -0,0 +1,189 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_stdio.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD$";
+#endif
+
+/*
+ * xdr_stdio.c, XDR implementation on standard i/o file.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements a XDR on a stdio stream.
+ * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
+ * from the stream.
+ */
+
+#include <rpc/types.h>
+#include <stdio.h>
+#include <rpc/xdr.h>
+
+static bool_t xdrstdio_getlong();
+static bool_t xdrstdio_putlong();
+static bool_t xdrstdio_getbytes();
+static bool_t xdrstdio_putbytes();
+static u_int xdrstdio_getpos();
+static bool_t xdrstdio_setpos();
+static int32_t *xdrstdio_inline();
+static void xdrstdio_destroy();
+
+/*
+ * Ops vector for stdio type XDR
+ */
+static struct xdr_ops xdrstdio_ops = {
+ xdrstdio_getlong, /* deseraialize a long int */
+ xdrstdio_putlong, /* seraialize a long int */
+ xdrstdio_getbytes, /* deserialize counted bytes */
+ xdrstdio_putbytes, /* serialize counted bytes */
+ xdrstdio_getpos, /* get offset in the stream */
+ xdrstdio_setpos, /* set offset in the stream */
+ xdrstdio_inline, /* prime stream for inline macros */
+ xdrstdio_destroy /* destroy stream */
+};
+
+/*
+ * Initialize a stdio xdr stream.
+ * Sets the xdr stream handle xdrs for use on the stream file.
+ * Operation flag is set to op.
+ */
+void
+xdrstdio_create(xdrs, file, op)
+ register XDR *xdrs;
+ FILE *file;
+ enum xdr_op op;
+{
+
+ xdrs->x_op = op;
+ xdrs->x_ops = &xdrstdio_ops;
+ xdrs->x_private = (caddr_t)file;
+ xdrs->x_handy = 0;
+ xdrs->x_base = 0;
+}
+
+/*
+ * Destroy a stdio xdr stream.
+ * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
+ */
+static void
+xdrstdio_destroy(xdrs)
+ register XDR *xdrs;
+{
+ (void)fflush((FILE *)xdrs->x_private);
+ /* xx should we close the file ?? */
+}
+
+static bool_t
+xdrstdio_getlong(xdrs, lp)
+ XDR *xdrs;
+ register long *lp;
+{
+
+ if (fread((caddr_t)lp, sizeof(int32_t), 1,
+ (FILE *)xdrs->x_private) != 1)
+ return (FALSE);
+ *lp = (long)ntohl((int32_t)*lp);
+ return (TRUE);
+}
+
+static bool_t
+xdrstdio_putlong(xdrs, lp)
+ XDR *xdrs;
+ long *lp;
+{
+
+ long mycopy = (long)htonl((int32_t)*lp);
+
+ if (fwrite((caddr_t)&mycopy, sizeof(int32_t), 1,
+ (FILE *)xdrs->x_private) != 1)
+ return (FALSE);
+ return (TRUE);
+}
+
+static bool_t
+xdrstdio_getbytes(xdrs, addr, len)
+ XDR *xdrs;
+ caddr_t addr;
+ u_int len;
+{
+
+ if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
+ return (FALSE);
+ return (TRUE);
+}
+
+static bool_t
+xdrstdio_putbytes(xdrs, addr, len)
+ XDR *xdrs;
+ caddr_t addr;
+ u_int len;
+{
+
+ if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
+ return (FALSE);
+ return (TRUE);
+}
+
+static u_int
+xdrstdio_getpos(xdrs)
+ XDR *xdrs;
+{
+
+ return ((u_int) ftell((FILE *)xdrs->x_private));
+}
+
+static bool_t
+xdrstdio_setpos(xdrs, pos)
+ XDR *xdrs;
+ u_int pos;
+{
+
+ return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
+ FALSE : TRUE);
+}
+
+static int32_t *
+xdrstdio_inline(xdrs, len)
+ XDR *xdrs;
+ u_int len;
+{
+
+ /*
+ * Must do some work to implement this: must insure
+ * enough data in the underlying stdio buffer,
+ * that the buffer is aligned so that we can indirect through a
+ * long *, and stuff this pointer in xdrs->x_buf. Doing
+ * a fread or fwrite to a scratch buffer would defeat
+ * most of the gains to be had here and require storage
+ * management on this buffer, so we don't do this.
+ */
+ return (NULL);
+}
diff --git a/lib/libc/yp/Makefile.inc b/lib/libc/yp/Makefile.inc
new file mode 100644
index 0000000..2112aeb
--- /dev/null
+++ b/lib/libc/yp/Makefile.inc
@@ -0,0 +1,17 @@
+# from: @(#)Makefile.inc 5.3 (Berkeley) 2/20/91
+# $FreeBSD$
+
+# yp sources
+.PATH: ${.CURDIR}/../libc/yp
+
+SRCS+= xdryp.c yp.h yp_xdr.c yplib.c
+CLEANFILES+= yp.h yp_xdr.c
+
+RPCSRC= ${DESTDIR}/usr/include/rpcsvc/yp.x
+RPCGEN= rpcgen -C
+
+yp_xdr.c: ${RPCSRC}
+ ${RPCGEN} -c -o ${.TARGET} ${RPCSRC}
+
+yp.h: ${RPCSRC}
+ ${RPCGEN} -h -o ${.TARGET} ${RPCSRC}
diff --git a/lib/libc/yp/xdryp.c b/lib/libc/yp/xdryp.c
new file mode 100644
index 0000000..1805288
--- /dev/null
+++ b/lib/libc/yp/xdryp.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char *rcsid = "$FreeBSD$";
+#endif
+
+#include <rpc/rpc.h>
+#include <rpcsvc/yp.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern int (*ypresp_allfn)();
+extern void *ypresp_data;
+
+/*
+ * I'm leaving the xdr_datum() function in purely for backwards
+ * compatibility. yplib.c doesn't actually use it, but it's listed
+ * in yp_prot.h as being available, so it's probably a good idea to
+ * leave it in in case somebody goes looking for it.
+ */
+typedef struct {
+ char *dptr;
+ int dsize;
+} datum;
+
+bool_t
+xdr_datum(xdrs, objp)
+XDR *xdrs;
+datum *objp;
+{
+ if (!xdr_bytes(xdrs, (char **)&objp->dptr, (u_int *)&objp->dsize, YPMAXRECORD)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypresp_all_seq(xdrs, objp)
+XDR *xdrs;
+u_long *objp;
+{
+ struct ypresp_all out;
+ u_long status;
+ char *key, *val;
+ int r;
+
+ bzero(&out, sizeof out);
+ while(1) {
+ if( !xdr_ypresp_all(xdrs, &out)) {
+ xdr_free(xdr_ypresp_all, (char *)&out);
+ *objp = YP_YPERR;
+ return FALSE;
+ }
+ if(out.more == 0) {
+ xdr_free(xdr_ypresp_all, (char *)&out);
+ *objp = YP_NOMORE;
+ return TRUE;
+ }
+ status = out.ypresp_all_u.val.stat;
+ switch(status) {
+ case YP_TRUE:
+ key = (char *)malloc(out.ypresp_all_u.val.key.keydat_len + 1);
+ bcopy(out.ypresp_all_u.val.key.keydat_val, key,
+ out.ypresp_all_u.val.key.keydat_len);
+ key[out.ypresp_all_u.val.key.keydat_len] = '\0';
+ val = (char *)malloc(out.ypresp_all_u.val.val.valdat_len + 1);
+ bcopy(out.ypresp_all_u.val.val.valdat_val, val,
+ out.ypresp_all_u.val.val.valdat_len);
+ val[out.ypresp_all_u.val.val.valdat_len] = '\0';
+ xdr_free(xdr_ypresp_all, (char *)&out);
+
+ r = (*ypresp_allfn)(status,
+ key, out.ypresp_all_u.val.key.keydat_len,
+ val, out.ypresp_all_u.val.val.valdat_len,
+ ypresp_data);
+ *objp = status;
+ free(key);
+ free(val);
+ if(r)
+ return TRUE;
+ break;
+ case YP_NOMORE:
+ xdr_free(xdr_ypresp_all, (char *)&out);
+ *objp = YP_NOMORE;
+ return TRUE;
+ default:
+ xdr_free(xdr_ypresp_all, (char *)&out);
+ *objp = status;
+ return TRUE;
+ }
+ }
+}
diff --git a/lib/libc/yp/yplib.c b/lib/libc/yp/yplib.c
new file mode 100644
index 0000000..f5f348b
--- /dev/null
+++ b/lib/libc/yp/yplib.c
@@ -0,0 +1,1115 @@
+/*
+ * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
+ * Copyright (c) 1998 Bill Paul <wpaul@ctr.columbia.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char *rcsid = "$FreeBSD$";
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+
+/*
+ * We have to define these here due to clashes between yp_prot.h and
+ * yp.h.
+ */
+
+#define YPMATCHCACHE
+
+#ifdef YPMATCHCACHE
+struct ypmatch_ent {
+ char *ypc_map;
+ keydat ypc_key;
+ valdat ypc_val;
+ time_t ypc_expire_t;
+ struct ypmatch_ent *ypc_next;
+};
+#define YPLIB_MAXCACHE 5 /* At most 5 entries */
+#define YPLIB_EXPIRE 5 /* Expire after 5 seconds */
+#endif
+
+struct dom_binding {
+ struct dom_binding *dom_pnext;
+ char dom_domain[YPMAXDOMAIN + 1];
+ struct sockaddr_in dom_server_addr;
+ u_short dom_server_port;
+ int dom_socket;
+ CLIENT *dom_client;
+ u_short dom_local_port; /* now I finally know what this is for. */
+ long dom_vers;
+#ifdef YPMATCHCACHE
+ struct ypmatch_ent *cache;
+ int ypmatch_cachecnt;
+#endif
+};
+
+#include <rpcsvc/ypclnt.h>
+
+#ifndef BINDINGDIR
+#define BINDINGDIR "/var/yp/binding"
+#endif
+#define MAX_RETRIES 20
+
+extern bool_t xdr_domainname(), xdr_ypbind_resp();
+extern bool_t xdr_ypreq_key(), xdr_ypresp_val();
+extern bool_t xdr_ypreq_nokey(), xdr_ypresp_key_val();
+extern bool_t xdr_ypresp_all(), xdr_ypresp_all_seq();
+extern bool_t xdr_ypresp_master();
+
+int (*ypresp_allfn)();
+void *ypresp_data;
+
+static void _yp_unbind __P(( struct dom_binding * ));
+struct dom_binding *_ypbindlist;
+static char _yp_domain[MAXHOSTNAMELEN];
+int _yplib_timeout = 10;
+
+#ifdef YPMATCHCACHE
+static void ypmatch_cache_delete(ypdb, prev, cur)
+ struct dom_binding *ypdb;
+ struct ypmatch_ent *prev;
+ struct ypmatch_ent *cur;
+{
+ if (prev == NULL)
+ ypdb->cache = cur->ypc_next;
+ else
+ prev->ypc_next = cur->ypc_next;
+
+ free(cur->ypc_map);
+ free(cur->ypc_key.keydat_val);
+ free(cur->ypc_val.valdat_val);
+ free(cur);
+
+ ypdb->ypmatch_cachecnt--;
+
+ return;
+}
+
+static void ypmatch_cache_flush(ypdb)
+ struct dom_binding *ypdb;
+{
+ struct ypmatch_ent *n, *c = ypdb->cache;
+
+ while (c != NULL) {
+ n = c->ypc_next;
+ ypmatch_cache_delete(ypdb, NULL, c);
+ c = n;
+ }
+
+ return;
+}
+
+static void ypmatch_cache_expire(ypdb)
+ struct dom_binding *ypdb;
+{
+ struct ypmatch_ent *c = ypdb->cache;
+ struct ypmatch_ent *n, *p = NULL;
+ time_t t;
+
+ time(&t);
+
+ while (c != NULL) {
+ if (t >= c->ypc_expire_t) {
+ n = c->ypc_next;
+ ypmatch_cache_delete(ypdb, p, c);
+ c = n;
+ } else {
+ p = c;
+ c = c->ypc_next;
+ }
+ }
+
+ return;
+}
+
+static void ypmatch_cache_insert(ypdb, map, key, val)
+ struct dom_binding *ypdb;
+ char *map;
+ keydat *key;
+ valdat *val;
+{
+ struct ypmatch_ent *new;
+
+ /* Do an expire run to maybe open up a slot. */
+ if (ypdb->ypmatch_cachecnt)
+ ypmatch_cache_expire(ypdb);
+
+ /*
+ * If there are no slots free, then force an expire of
+ * the least recently used entry.
+ */
+ if (ypdb->ypmatch_cachecnt >= YPLIB_MAXCACHE) {
+ struct ypmatch_ent *o = NULL, *c = ypdb->cache;
+ time_t oldest = 0;
+
+ oldest = ~oldest;
+
+ while(c != NULL) {
+ if (c->ypc_expire_t < oldest) {
+ oldest = c->ypc_expire_t;
+ o = c;
+ }
+ c = c->ypc_next;
+ }
+
+ if (o == NULL)
+ return;
+ o->ypc_expire_t = 0;
+ ypmatch_cache_expire(ypdb);
+ }
+
+ new = malloc(sizeof(struct ypmatch_ent));
+ if (new == NULL)
+ return;
+
+ new->ypc_map = strdup(map);
+ if (new->ypc_map == NULL) {
+ free(new);
+ return;
+ }
+ new->ypc_key.keydat_val = malloc(key->keydat_len);
+ if (new->ypc_key.keydat_val == NULL) {
+ free(new->ypc_map);
+ free(new);
+ return;
+ }
+ new->ypc_val.valdat_val = malloc(val->valdat_len);
+ if (new->ypc_val.valdat_val == NULL) {
+ free(new->ypc_val.valdat_val);
+ free(new->ypc_map);
+ free(new);
+ return;
+ }
+
+ new->ypc_expire_t = time(NULL) + YPLIB_EXPIRE;
+ new->ypc_key.keydat_len = key->keydat_len;
+ new->ypc_val.valdat_len = val->valdat_len;
+ bcopy(key->keydat_val, new->ypc_key.keydat_val, key->keydat_len);
+ bcopy(val->valdat_val, new->ypc_val.valdat_val, val->valdat_len);
+
+ new->ypc_next = ypdb->cache;
+ ypdb->cache = new;
+
+ ypdb->ypmatch_cachecnt++;
+
+ return;
+}
+
+static bool_t ypmatch_cache_lookup(ypdb, map, key, val)
+ struct dom_binding *ypdb;
+ char *map;
+ keydat *key;
+ valdat *val;
+{
+ struct ypmatch_ent *c = ypdb->cache;
+
+ ypmatch_cache_expire(ypdb);
+
+ for (c = ypdb->cache; c != NULL; c = c->ypc_next) {
+ if (strcmp(map, c->ypc_map))
+ continue;
+ if (key->keydat_len != c->ypc_key.keydat_len)
+ continue;
+ if (bcmp(key->keydat_val, c->ypc_key.keydat_val,
+ key->keydat_len))
+ continue;
+ }
+
+ if (c == NULL)
+ return(FALSE);
+
+ val->valdat_len = c->ypc_val.valdat_len;
+ val->valdat_val = c->ypc_val.valdat_val;
+
+ return(TRUE);
+}
+#endif
+
+char *
+ypbinderr_string(incode)
+ int incode;
+{
+ static char err[80];
+ switch(incode) {
+ case 0:
+ return "Success";
+ case YPBIND_ERR_ERR:
+ return "Internal ypbind error";
+ case YPBIND_ERR_NOSERV:
+ return "Domain not bound";
+ case YPBIND_ERR_RESC:
+ return "System resource allocation failure";
+ }
+ sprintf(err, "Unknown ypbind error: #%d\n", incode);
+ return err;
+}
+
+int
+_yp_dobind(dom, ypdb)
+ char *dom;
+ struct dom_binding **ypdb;
+{
+ static pid_t pid = -1;
+ char path[MAXPATHLEN];
+ struct dom_binding *ysd, *ysd2;
+ struct ypbind_resp ypbr;
+ struct timeval tv;
+ struct sockaddr_in clnt_sin;
+ int clnt_sock, fd;
+ pid_t gpid;
+ CLIENT *client;
+ int new = 0, r;
+ int retries = 0;
+ struct sockaddr_in check;
+ int checklen = sizeof(struct sockaddr_in);
+
+ /* Not allowed; bad doggie. Bad. */
+ if (strchr(dom, '/') != NULL)
+ return(YPERR_BADARGS);
+
+ gpid = getpid();
+ if( !(pid==-1 || pid==gpid) ) {
+ ysd = _ypbindlist;
+ while(ysd) {
+ if(ysd->dom_client != NULL)
+ _yp_unbind(ysd);
+ ysd2 = ysd->dom_pnext;
+ free(ysd);
+ ysd = ysd2;
+ }
+ _ypbindlist = NULL;
+ }
+ pid = gpid;
+
+ if(ypdb!=NULL)
+ *ypdb = NULL;
+
+ if(dom==NULL || strlen(dom)==0)
+ return YPERR_BADARGS;
+
+ for(ysd = _ypbindlist; ysd; ysd = ysd->dom_pnext)
+ if( strcmp(dom, ysd->dom_domain) == 0)
+ break;
+
+
+ if(ysd==NULL) {
+ ysd = (struct dom_binding *)malloc(sizeof *ysd);
+ bzero((char *)ysd, sizeof *ysd);
+ ysd->dom_socket = -1;
+ ysd->dom_vers = 0;
+ new = 1;
+ } else {
+ /* Check the socket -- may have been hosed by the caller. */
+ if (getsockname(ysd->dom_socket, (struct sockaddr *)&check,
+ &checklen) == -1 || check.sin_family != AF_INET ||
+ check.sin_port != ysd->dom_local_port) {
+ /* Socket became bogus somehow... need to rebind. */
+ int save, sock;
+
+ sock = ysd->dom_socket;
+ save = dup(ysd->dom_socket);
+ if (ysd->dom_client != NULL)
+ clnt_destroy(ysd->dom_client);
+ ysd->dom_vers = 0;
+ ysd->dom_client = NULL;
+ sock = dup2(save, sock);
+ close(save);
+ }
+ }
+
+again:
+ retries++;
+ if (retries > MAX_RETRIES) {
+ if (new)
+ free(ysd);
+ return(YPERR_YPBIND);
+ }
+#ifdef BINDINGDIR
+ if(ysd->dom_vers==0) {
+ /*
+ * We're trying to make a new binding: zorch the
+ * existing handle now (if any).
+ */
+ if(ysd->dom_client != NULL) {
+ clnt_destroy(ysd->dom_client);
+ ysd->dom_client = NULL;
+ ysd->dom_socket = -1;
+ }
+ snprintf(path, sizeof(path), "%s/%s.%d", BINDINGDIR, dom, 2);
+ if( (fd=open(path, O_RDONLY)) == -1) {
+ /* no binding file, YP is dead. */
+ /* Try to bring it back to life. */
+ close(fd);
+ goto skipit;
+ }
+ if( flock(fd, LOCK_EX|LOCK_NB) == -1 && errno==EWOULDBLOCK) {
+ struct iovec iov[2];
+ struct ypbind_resp ybr;
+ u_short ypb_port;
+
+ iov[0].iov_base = (caddr_t)&ypb_port;
+ iov[0].iov_len = sizeof ypb_port;
+ iov[1].iov_base = (caddr_t)&ybr;
+ iov[1].iov_len = sizeof ybr;
+
+ r = readv(fd, iov, 2);
+ if(r != iov[0].iov_len + iov[1].iov_len) {
+ close(fd);
+ ysd->dom_vers = -1;
+ goto again;
+ }
+
+ bzero(&ysd->dom_server_addr, sizeof ysd->dom_server_addr);
+ ysd->dom_server_addr.sin_family = AF_INET;
+ ysd->dom_server_addr.sin_len = sizeof(struct sockaddr_in);
+ ysd->dom_server_addr.sin_addr.s_addr =
+ *(u_long *)&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr;
+ ysd->dom_server_addr.sin_port =
+ *(u_short *)&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port;
+
+ ysd->dom_server_port = ysd->dom_server_addr.sin_port;
+ close(fd);
+ goto gotit;
+ } else {
+ /* no lock on binding file, YP is dead. */
+ /* Try to bring it back to life. */
+ close(fd);
+ goto skipit;
+ }
+ }
+skipit:
+#endif
+ if(ysd->dom_vers==-1 || ysd->dom_vers==0) {
+ /*
+ * We're trying to make a new binding: zorch the
+ * existing handle now (if any).
+ */
+ if(ysd->dom_client != NULL) {
+ clnt_destroy(ysd->dom_client);
+ ysd->dom_client = NULL;
+ ysd->dom_socket = -1;
+ }
+ bzero((char *)&clnt_sin, sizeof clnt_sin);
+ clnt_sin.sin_family = AF_INET;
+ clnt_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ clnt_sock = RPC_ANYSOCK;
+ client = clnttcp_create(&clnt_sin, YPBINDPROG, YPBINDVERS, &clnt_sock,
+ 0, 0);
+ if(client==NULL) {
+ /*
+ * These conditions indicate ypbind just isn't
+ * alive -- we probably don't want to shoot our
+ * mouth off in this case; instead generate error
+ * messages only for really exotic problems.
+ */
+ if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED &&
+ (rpc_createerr.cf_stat != RPC_SYSTEMERROR &&
+ rpc_createerr.cf_error.re_errno == ECONNREFUSED))
+ clnt_pcreateerror("clnttcp_create");
+ if(new)
+ free(ysd);
+ return (YPERR_YPBIND);
+ }
+
+ /*
+ * Check the port number -- should be < IPPORT_RESERVED.
+ * If not, it's possible someone has registered a bogus
+ * ypbind with the portmapper and is trying to trick us.
+ */
+ if (ntohs(clnt_sin.sin_port) >= IPPORT_RESERVED) {
+ if (client != NULL)
+ clnt_destroy(client);
+ if (new)
+ free(ysd);
+ return(YPERR_YPBIND);
+ }
+ tv.tv_sec = _yplib_timeout/2;
+ tv.tv_usec = 0;
+ r = clnt_call(client, YPBINDPROC_DOMAIN,
+ xdr_domainname, (char *)&dom, xdr_ypbind_resp, &ypbr, tv);
+ if(r != RPC_SUCCESS) {
+ clnt_destroy(client);
+ ysd->dom_vers = -1;
+ if (r == RPC_PROGUNAVAIL || r == RPC_PROCUNAVAIL) {
+ if (new)
+ free(ysd);
+ return(YPERR_YPBIND);
+ }
+ fprintf(stderr,
+ "YP: server for domain %s not responding, retrying\n", dom);
+ goto again;
+ } else {
+ if (ypbr.ypbind_status != YPBIND_SUCC_VAL) {
+ clnt_destroy(client);
+ ysd->dom_vers = -1;
+ sleep(_yplib_timeout/2);
+ goto again;
+ }
+ }
+ clnt_destroy(client);
+
+ bzero((char *)&ysd->dom_server_addr, sizeof ysd->dom_server_addr);
+ ysd->dom_server_addr.sin_family = AF_INET;
+ ysd->dom_server_addr.sin_port =
+ *(u_short *)&ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port;
+ ysd->dom_server_addr.sin_addr.s_addr =
+ *(u_long *)&ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr;
+
+ /*
+ * We could do a reserved port check here too, but this
+ * could pose compatibility problems. The local ypbind is
+ * supposed to decide whether or not to trust yp servers
+ * on insecure ports. For now, we trust its judgement.
+ */
+ ysd->dom_server_port =
+ *(u_short *)&ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port;
+gotit:
+ ysd->dom_vers = YPVERS;
+ strlcpy(ysd->dom_domain, dom, sizeof(ysd->dom_domain));
+ }
+
+ /* Don't rebuild the connection to the server unless we have to. */
+ if (ysd->dom_client == NULL) {
+ tv.tv_sec = _yplib_timeout/2;
+ tv.tv_usec = 0;
+ ysd->dom_socket = RPC_ANYSOCK;
+ ysd->dom_client = clntudp_bufcreate(&ysd->dom_server_addr,
+ YPPROG, YPVERS, tv, &ysd->dom_socket, 1280, 2304);
+ if(ysd->dom_client==NULL) {
+ clnt_pcreateerror("clntudp_create");
+ ysd->dom_vers = -1;
+ goto again;
+ }
+ if( fcntl(ysd->dom_socket, F_SETFD, 1) == -1)
+ perror("fcntl: F_SETFD");
+ /*
+ * We want a port number associated with this socket
+ * so that we can check its authenticity later.
+ */
+ checklen = sizeof(struct sockaddr_in);
+ bzero((char *)&check, checklen);
+ bind(ysd->dom_socket, (struct sockaddr *)&check, checklen);
+ check.sin_family = AF_INET;
+ if (!getsockname(ysd->dom_socket,
+ (struct sockaddr *)&check, &checklen)) {
+ ysd->dom_local_port = check.sin_port;
+ } else {
+ clnt_destroy(ysd->dom_client);
+ if (new)
+ free(ysd);
+ return(YPERR_YPBIND);
+ }
+ }
+
+ if(new) {
+ ysd->dom_pnext = _ypbindlist;
+ _ypbindlist = ysd;
+ }
+
+ if(ypdb!=NULL)
+ *ypdb = ysd;
+ return 0;
+}
+
+static void
+_yp_unbind(ypb)
+ struct dom_binding *ypb;
+{
+ struct sockaddr_in check;
+ int checklen = sizeof(struct sockaddr_in);
+
+ if (ypb->dom_client != NULL) {
+ /* Check the socket -- may have been hosed by the caller. */
+ if (getsockname(ypb->dom_socket, (struct sockaddr *)&check,
+ &checklen) == -1 || check.sin_family != AF_INET ||
+ check.sin_port != ypb->dom_local_port) {
+ int save, sock;
+
+ sock = ypb->dom_socket;
+ save = dup(ypb->dom_socket);
+ clnt_destroy(ypb->dom_client);
+ sock = dup2(save, sock);
+ close(save);
+ } else
+ clnt_destroy(ypb->dom_client);
+ }
+
+ ypb->dom_client = NULL;
+ ypb->dom_socket = -1;
+ ypb->dom_vers = -1;
+#ifdef YPMATCHCACHE
+ ypmatch_cache_flush(ypb);
+#endif
+}
+
+int
+yp_bind(dom)
+ char *dom;
+{
+ return _yp_dobind(dom, NULL);
+}
+
+void
+yp_unbind(dom)
+ char *dom;
+{
+ struct dom_binding *ypb, *ypbp;
+
+ ypbp = NULL;
+ for(ypb=_ypbindlist; ypb; ypb=ypb->dom_pnext) {
+ if( strcmp(dom, ypb->dom_domain) == 0) {
+ _yp_unbind(ypb);
+ if(ypbp)
+ ypbp->dom_pnext = ypb->dom_pnext;
+ else
+ _ypbindlist = ypb->dom_pnext;
+ free(ypb);
+ return;
+ }
+ ypbp = ypb;
+ }
+ return;
+}
+
+int
+yp_match(indomain, inmap, inkey, inkeylen, outval, outvallen)
+ char *indomain;
+ char *inmap;
+ const char *inkey;
+ int inkeylen;
+ char **outval;
+ int *outvallen;
+{
+ struct dom_binding *ysd;
+ struct ypresp_val yprv;
+ struct timeval tv;
+ struct ypreq_key yprk;
+ int r;
+
+ *outval = NULL;
+ *outvallen = 0;
+
+ /* Sanity check */
+
+ if (inkey == NULL || !strlen(inkey) || inkeylen <= 0 ||
+ inmap == NULL || !strlen(inmap) ||
+ indomain == NULL || !strlen(indomain))
+ return YPERR_BADARGS;
+
+ if (_yp_dobind(indomain, &ysd) != 0)
+ return(YPERR_DOMAIN);
+
+ yprk.domain = indomain;
+ yprk.map = inmap;
+ yprk.key.keydat_val = (char *)inkey;
+ yprk.key.keydat_len = inkeylen;
+
+#ifdef YPMATCHCACHE
+ if (ypmatch_cache_lookup(ysd, yprk.map, &yprk.key, &yprv.val) == TRUE) {
+/*
+ if( !strcmp(_yp_domain, indomain) && ypmatch_find(inmap, inkey,
+ inkeylen, &yprv.val.valdat_val, &yprv.val.valdat_len)) {
+*/
+ *outvallen = yprv.val.valdat_len;
+ *outval = (char *)malloc(*outvallen+1);
+ bcopy(yprv.val.valdat_val, *outval, *outvallen);
+ (*outval)[*outvallen] = '\0';
+ return 0;
+ }
+#endif
+
+again:
+ if( _yp_dobind(indomain, &ysd) != 0)
+ return YPERR_DOMAIN;
+
+ tv.tv_sec = _yplib_timeout;
+ tv.tv_usec = 0;
+
+ bzero((char *)&yprv, sizeof yprv);
+
+ r = clnt_call(ysd->dom_client, YPPROC_MATCH,
+ xdr_ypreq_key, &yprk, xdr_ypresp_val, &yprv, tv);
+ if(r != RPC_SUCCESS) {
+ clnt_perror(ysd->dom_client, "yp_match: clnt_call");
+ _yp_unbind(ysd);
+ goto again;
+ }
+
+ if( !(r=ypprot_err(yprv.stat)) ) {
+ *outvallen = yprv.val.valdat_len;
+ *outval = (char *)malloc(*outvallen+1);
+ bcopy(yprv.val.valdat_val, *outval, *outvallen);
+ (*outval)[*outvallen] = '\0';
+#ifdef YPMATCHCACHE
+ ypmatch_cache_insert(ysd, yprk.map, &yprk.key, &yprv.val);
+#endif
+ }
+
+ xdr_free(xdr_ypresp_val, (char *)&yprv);
+ return r;
+}
+
+int
+yp_get_default_domain(domp)
+char **domp;
+{
+ *domp = NULL;
+ if(_yp_domain[0] == '\0')
+ if( getdomainname(_yp_domain, sizeof _yp_domain))
+ return YPERR_NODOM;
+ *domp = _yp_domain;
+ return 0;
+}
+
+int
+yp_first(indomain, inmap, outkey, outkeylen, outval, outvallen)
+ char *indomain;
+ char *inmap;
+ char **outkey;
+ int *outkeylen;
+ char **outval;
+ int *outvallen;
+{
+ struct ypresp_key_val yprkv;
+ struct ypreq_nokey yprnk;
+ struct dom_binding *ysd;
+ struct timeval tv;
+ int r;
+
+ /* Sanity check */
+
+ if (indomain == NULL || !strlen(indomain) ||
+ inmap == NULL || !strlen(inmap))
+ return YPERR_BADARGS;
+
+ *outkey = *outval = NULL;
+ *outkeylen = *outvallen = 0;
+
+again:
+ if( _yp_dobind(indomain, &ysd) != 0)
+ return YPERR_DOMAIN;
+
+ tv.tv_sec = _yplib_timeout;
+ tv.tv_usec = 0;
+
+ yprnk.domain = indomain;
+ yprnk.map = inmap;
+ bzero((char *)&yprkv, sizeof yprkv);
+
+ r = clnt_call(ysd->dom_client, YPPROC_FIRST,
+ xdr_ypreq_nokey, &yprnk, xdr_ypresp_key_val, &yprkv, tv);
+ if(r != RPC_SUCCESS) {
+ clnt_perror(ysd->dom_client, "yp_first: clnt_call");
+ _yp_unbind(ysd);
+ goto again;
+ }
+ if( !(r=ypprot_err(yprkv.stat)) ) {
+ *outkeylen = yprkv.key.keydat_len;
+ *outkey = (char *)malloc(*outkeylen+1);
+ bcopy(yprkv.key.keydat_val, *outkey, *outkeylen);
+ (*outkey)[*outkeylen] = '\0';
+ *outvallen = yprkv.val.valdat_len;
+ *outval = (char *)malloc(*outvallen+1);
+ bcopy(yprkv.val.valdat_val, *outval, *outvallen);
+ (*outval)[*outvallen] = '\0';
+ }
+
+ xdr_free(xdr_ypresp_key_val, (char *)&yprkv);
+ return r;
+}
+
+int
+yp_next(indomain, inmap, inkey, inkeylen, outkey, outkeylen, outval, outvallen)
+ char *indomain;
+ char *inmap;
+ char *inkey;
+ int inkeylen;
+ char **outkey;
+ int *outkeylen;
+ char **outval;
+ int *outvallen;
+{
+ struct ypresp_key_val yprkv;
+ struct ypreq_key yprk;
+ struct dom_binding *ysd;
+ struct timeval tv;
+ int r;
+
+ /* Sanity check */
+
+ if (inkey == NULL || !strlen(inkey) || inkeylen <= 0 ||
+ inmap == NULL || !strlen(inmap) ||
+ indomain == NULL || !strlen(indomain))
+ return YPERR_BADARGS;
+
+ *outkey = *outval = NULL;
+ *outkeylen = *outvallen = 0;
+
+again:
+ if( _yp_dobind(indomain, &ysd) != 0)
+ return YPERR_DOMAIN;
+
+ tv.tv_sec = _yplib_timeout;
+ tv.tv_usec = 0;
+
+ yprk.domain = indomain;
+ yprk.map = inmap;
+ yprk.key.keydat_val = inkey;
+ yprk.key.keydat_len = inkeylen;
+ bzero((char *)&yprkv, sizeof yprkv);
+
+ r = clnt_call(ysd->dom_client, YPPROC_NEXT,
+ xdr_ypreq_key, &yprk, xdr_ypresp_key_val, &yprkv, tv);
+ if(r != RPC_SUCCESS) {
+ clnt_perror(ysd->dom_client, "yp_next: clnt_call");
+ _yp_unbind(ysd);
+ goto again;
+ }
+ if( !(r=ypprot_err(yprkv.stat)) ) {
+ *outkeylen = yprkv.key.keydat_len;
+ *outkey = (char *)malloc(*outkeylen+1);
+ bcopy(yprkv.key.keydat_val, *outkey, *outkeylen);
+ (*outkey)[*outkeylen] = '\0';
+ *outvallen = yprkv.val.valdat_len;
+ *outval = (char *)malloc(*outvallen+1);
+ bcopy(yprkv.val.valdat_val, *outval, *outvallen);
+ (*outval)[*outvallen] = '\0';
+ }
+
+ xdr_free(xdr_ypresp_key_val, (char *)&yprkv);
+ return r;
+}
+
+int
+yp_all(indomain, inmap, incallback)
+ char *indomain;
+ char *inmap;
+ struct ypall_callback *incallback;
+{
+ struct ypreq_nokey yprnk;
+ struct dom_binding *ysd;
+ struct timeval tv;
+ struct sockaddr_in clnt_sin;
+ CLIENT *clnt;
+ u_long status, savstat;
+ int clnt_sock;
+
+ /* Sanity check */
+
+ if (indomain == NULL || !strlen(indomain) ||
+ inmap == NULL || !strlen(inmap))
+ return YPERR_BADARGS;
+
+again:
+
+ if( _yp_dobind(indomain, &ysd) != 0)
+ return YPERR_DOMAIN;
+
+ tv.tv_sec = _yplib_timeout;
+ tv.tv_usec = 0;
+
+ /* YPPROC_ALL manufactures its own channel to ypserv using TCP */
+
+ clnt_sock = RPC_ANYSOCK;
+ clnt_sin = ysd->dom_server_addr;
+ clnt_sin.sin_port = 0;
+ clnt = clnttcp_create(&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0);
+ if(clnt==NULL) {
+ printf("clnttcp_create failed\n");
+ return YPERR_PMAP;
+ }
+
+ yprnk.domain = indomain;
+ yprnk.map = inmap;
+ ypresp_allfn = incallback->foreach;
+ ypresp_data = (void *)incallback->data;
+
+ if (clnt_call(clnt, YPPROC_ALL,
+ xdr_ypreq_nokey, &yprnk,
+ xdr_ypresp_all_seq, &status, tv) != RPC_SUCCESS) {
+ clnt_perror(ysd->dom_client, "yp_next: clnt_call");
+ clnt_destroy(clnt);
+ _yp_unbind(ysd);
+ goto again;
+ }
+
+ clnt_destroy(clnt);
+ savstat = status;
+ xdr_free(xdr_ypresp_all_seq, (char *)&status); /* not really needed... */
+ if(savstat != YP_NOMORE)
+ return ypprot_err(savstat);
+ return 0;
+}
+
+int
+yp_order(indomain, inmap, outorder)
+ char *indomain;
+ char *inmap;
+ int *outorder;
+{
+ struct dom_binding *ysd;
+ struct ypresp_order ypro;
+ struct ypreq_nokey yprnk;
+ struct timeval tv;
+ int r;
+
+ /* Sanity check */
+
+ if (indomain == NULL || !strlen(indomain) ||
+ inmap == NULL || !strlen(inmap))
+ return YPERR_BADARGS;
+
+again:
+ if( _yp_dobind(indomain, &ysd) != 0)
+ return YPERR_DOMAIN;
+
+ tv.tv_sec = _yplib_timeout;
+ tv.tv_usec = 0;
+
+ yprnk.domain = indomain;
+ yprnk.map = inmap;
+
+ bzero((char *)(char *)&ypro, sizeof ypro);
+
+ r = clnt_call(ysd->dom_client, YPPROC_ORDER,
+ xdr_ypreq_nokey, &yprnk, xdr_ypresp_order, &ypro, tv);
+
+ /*
+ * NIS+ in YP compat mode doesn't support the YPPROC_ORDER
+ * procedure.
+ */
+ if (r == RPC_PROCUNAVAIL) {
+ return(YPERR_YPERR);
+ }
+
+ if(r != RPC_SUCCESS) {
+ clnt_perror(ysd->dom_client, "yp_order: clnt_call");
+ _yp_unbind(ysd);
+ goto again;
+ }
+
+ if( !(r=ypprot_err(ypro.stat)) ) {
+ *outorder = ypro.ordernum;
+ }
+
+ xdr_free(xdr_ypresp_order, (char *)&ypro);
+ return (r);
+}
+
+int
+yp_master(indomain, inmap, outname)
+ char *indomain;
+ char *inmap;
+ char **outname;
+{
+ struct dom_binding *ysd;
+ struct ypresp_master yprm;
+ struct ypreq_nokey yprnk;
+ struct timeval tv;
+ int r;
+
+ /* Sanity check */
+
+ if (indomain == NULL || !strlen(indomain) ||
+ inmap == NULL || !strlen(inmap))
+ return YPERR_BADARGS;
+again:
+ if( _yp_dobind(indomain, &ysd) != 0)
+ return YPERR_DOMAIN;
+
+ tv.tv_sec = _yplib_timeout;
+ tv.tv_usec = 0;
+
+ yprnk.domain = indomain;
+ yprnk.map = inmap;
+
+ bzero((char *)&yprm, sizeof yprm);
+
+ r = clnt_call(ysd->dom_client, YPPROC_MASTER,
+ xdr_ypreq_nokey, &yprnk, xdr_ypresp_master, &yprm, tv);
+ if(r != RPC_SUCCESS) {
+ clnt_perror(ysd->dom_client, "yp_master: clnt_call");
+ _yp_unbind(ysd);
+ goto again;
+ }
+
+ if( !(r=ypprot_err(yprm.stat)) ) {
+ *outname = (char *)strdup(yprm.peer);
+ }
+
+ xdr_free(xdr_ypresp_master, (char *)&yprm);
+ return (r);
+}
+int
+yp_maplist(indomain, outmaplist)
+ char *indomain;
+ struct ypmaplist **outmaplist;
+{
+ struct dom_binding *ysd;
+ struct ypresp_maplist ypml;
+ struct timeval tv;
+ int r;
+
+ /* Sanity check */
+
+ if (indomain == NULL || !strlen(indomain))
+ return YPERR_BADARGS;
+
+again:
+ if( _yp_dobind(indomain, &ysd) != 0)
+ return YPERR_DOMAIN;
+
+ tv.tv_sec = _yplib_timeout;
+ tv.tv_usec = 0;
+
+ bzero((char *)&ypml, sizeof ypml);
+
+ r = clnt_call(ysd->dom_client, YPPROC_MAPLIST,
+ xdr_domainname,(char *)&indomain,xdr_ypresp_maplist,&ypml,tv);
+ if (r != RPC_SUCCESS) {
+ clnt_perror(ysd->dom_client, "yp_maplist: clnt_call");
+ _yp_unbind(ysd);
+ goto again;
+ }
+ if( !(r=ypprot_err(ypml.stat)) ) {
+ *outmaplist = ypml.maps;
+ }
+
+ /* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/
+ return (r);
+}
+
+char *
+yperr_string(incode)
+ int incode;
+{
+ static char err[80];
+
+ switch(incode) {
+ case 0:
+ return "Success";
+ case YPERR_BADARGS:
+ return "Request arguments bad";
+ case YPERR_RPC:
+ return "RPC failure";
+ case YPERR_DOMAIN:
+ return "Can't bind to server which serves this domain";
+ case YPERR_MAP:
+ return "No such map in server's domain";
+ case YPERR_KEY:
+ return "No such key in map";
+ case YPERR_YPERR:
+ return "YP server error";
+ case YPERR_RESRC:
+ return "Local resource allocation failure";
+ case YPERR_NOMORE:
+ return "No more records in map database";
+ case YPERR_PMAP:
+ return "Can't communicate with portmapper";
+ case YPERR_YPBIND:
+ return "Can't communicate with ypbind";
+ case YPERR_YPSERV:
+ return "Can't communicate with ypserv";
+ case YPERR_NODOM:
+ return "Local domain name not set";
+ case YPERR_BADDB:
+ return "Server data base is bad";
+ case YPERR_VERS:
+ return "YP server version mismatch - server can't supply service.";
+ case YPERR_ACCESS:
+ return "Access violation";
+ case YPERR_BUSY:
+ return "Database is busy";
+ }
+ sprintf(err, "YP unknown error %d\n", incode);
+ return err;
+}
+
+int
+ypprot_err(incode)
+ unsigned int incode;
+{
+ switch(incode) {
+ case YP_TRUE:
+ return 0;
+ case YP_FALSE:
+ return YPERR_YPBIND;
+ case YP_NOMORE:
+ return YPERR_NOMORE;
+ case YP_NOMAP:
+ return YPERR_MAP;
+ case YP_NODOM:
+ return YPERR_DOMAIN;
+ case YP_NOKEY:
+ return YPERR_KEY;
+ case YP_BADOP:
+ return YPERR_YPERR;
+ case YP_BADDB:
+ return YPERR_BADDB;
+ case YP_YPERR:
+ return YPERR_YPERR;
+ case YP_BADARGS:
+ return YPERR_BADARGS;
+ case YP_VERS:
+ return YPERR_VERS;
+ }
+ return YPERR_YPERR;
+}
+
+int
+_yp_check(dom)
+ char **dom;
+{
+ char *unused;
+
+ if( _yp_domain[0]=='\0' )
+ if( yp_get_default_domain(&unused) )
+ return 0;
+
+ if(dom)
+ *dom = _yp_domain;
+
+ if( yp_bind(_yp_domain)==0 ) {
+ yp_unbind(_yp_domain);
+ return 1;
+ }
+ return 0;
+}
diff --git a/lib/libc_r/Makefile b/lib/libc_r/Makefile
new file mode 100644
index 0000000..e79d5c5
--- /dev/null
+++ b/lib/libc_r/Makefile
@@ -0,0 +1,45 @@
+# $FreeBSD$
+#
+# All library objects contain rcsid strings by default; they may be
+# excluded as a space-saving measure. To produce a library that does
+# not contain these strings, delete -DLIBC_RCS and -DSYSLIBC_RCS
+# from CFLAGS below. To remove these strings from just the system call
+# stubs, remove just -DSYSLIBC_RCS from CFLAGS.
+LIB=c_r
+SHLIB_MAJOR= 4
+SHLIB_MINOR= 0
+CFLAGS+=-DLIBC_RCS -DSYSLIBC_RCS -I${.CURDIR}/../libc/include
+CFLAGS+=-DPTHREAD_KERNEL -D_THREAD_SAFE -I${.CURDIR}/uthread
+CFLAGS+=-I${.CURDIR}/../../include
+
+# Uncomment this if you want libc_r to contain debug information for
+# thread locking.
+CFLAGS+=-D_LOCK_DEBUG
+
+# enable extra internal consistancy checks
+# CFLAGS+=-D_PTHREADS_INVARIANTS
+
+AINC= -I${.CURDIR}/../libc/${MACHINE_ARCH} -I${.CURDIR}/uthread
+PRECIOUSLIB= yes
+
+#
+# This is a list of syscalls that are renamed as _thread_sys_{syscall}
+# so that libc_r can provide replacement functions.
+#
+HIDDEN_SYSCALLS= accept.o bind.o close.o connect.o dup.o dup2.o \
+ execve.o fchflags.o fchmod.o fchown.o fcntl.o \
+ flock.o fpathconf.o fstat.o fstatfs.o fsync.o getdirentries.o \
+ getlogin.o getpeername.o getsockname.o getsockopt.o ioctl.o listen.o \
+ msync.o nanosleep.o nfssvc.o open.o poll.o read.o readv.o recvfrom.o \
+ recvmsg.o sched_yield.o select.o sendmsg.o sendto.o \
+ setsockopt.o shutdown.o sigaction.o sigaltstack.o \
+ signanosleep.o sigpending.o sigprocmask.o sigreturn.o sigsetmask.o \
+ sigsuspend.o socket.o \
+ socketpair.o wait4.o write.o writev.o
+
+.include "${.CURDIR}/../libc/Makefile.inc"
+.include "${.CURDIR}/man/Makefile.inc"
+.include "${.CURDIR}/uthread/Makefile.inc"
+.include "${.CURDIR}/sys/Makefile.inc"
+
+.include <bsd.lib.mk>
diff --git a/lib/libc_r/arch/alpha/_atomic_lock.S b/lib/libc_r/arch/alpha/_atomic_lock.S
new file mode 100644
index 0000000..1cfb52f
--- /dev/null
+++ b/lib/libc_r/arch/alpha/_atomic_lock.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ * copyright Douglas Santry 1996
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the above copyright is retained
+ * in the source form.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Douglas Santry AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Douglas Santry OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include "SYS.h"
+
+/*
+ * Atomicly lock a location with an identifier provided the location
+ * is not currently locked.
+ *
+ * long _atomic_lock(long *);
+ * v0 will contain the return value (zero if lock obtained).
+ */
+LEAF(_atomic_lock,0)
+ LDGP(pv)
+
+0: ldq_l v0, 0(a0) /* read existing lock value */
+ mov 1, t0 /* locked value to store */
+ stq_c t0, 0(a0) /* attempt to store, status in t0 */
+ beq t0, 1f /* branch foward to optimise prediction */
+ mb /* sync with other processors */
+ RET /* return with v0==0 if lock obtained */
+1: br 0b /* loop to try again */
+END(_atomic_lock)
diff --git a/lib/libc_r/arch/amd64/_atomic_lock.S b/lib/libc_r/arch/amd64/_atomic_lock.S
new file mode 100644
index 0000000..afaec71
--- /dev/null
+++ b/lib/libc_r/arch/amd64/_atomic_lock.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ * copyright Douglas Santry 1996
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the above copyright is retained
+ * in the source form.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Douglas Santry AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Douglas Santry OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * Atomicly lock a location with an identifier provided the location
+ * is not currently locked.
+ *
+ * long _atomic_lock(long *);
+ * eax will contain the return value (zero if lock obtained).
+ */
+ENTRY(_atomic_lock)
+ movl 4(%esp), %ecx
+ movl $1, %eax
+ xchg %eax, (%ecx)
+ ret
+
diff --git a/lib/libc_r/arch/i386/_atomic_lock.S b/lib/libc_r/arch/i386/_atomic_lock.S
new file mode 100644
index 0000000..afaec71
--- /dev/null
+++ b/lib/libc_r/arch/i386/_atomic_lock.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ * copyright Douglas Santry 1996
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the above copyright is retained
+ * in the source form.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Douglas Santry AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Douglas Santry OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * Atomicly lock a location with an identifier provided the location
+ * is not currently locked.
+ *
+ * long _atomic_lock(long *);
+ * eax will contain the return value (zero if lock obtained).
+ */
+ENTRY(_atomic_lock)
+ movl 4(%esp), %ecx
+ movl $1, %eax
+ xchg %eax, (%ecx)
+ ret
+
diff --git a/lib/libc_r/man/Makefile.inc b/lib/libc_r/man/Makefile.inc
new file mode 100644
index 0000000..b4c9370
--- /dev/null
+++ b/lib/libc_r/man/Makefile.inc
@@ -0,0 +1,44 @@
+# $FreeBSD$
+
+# POSIX thread man files
+
+.PATH: ${.CURDIR}/man
+
+MAN3+= pthread_cleanup_pop.3 \
+ pthread_cleanup_push.3 \
+ pthread_cond_broadcast.3 \
+ pthread_cond_destroy.3 \
+ pthread_cond_init.3 \
+ pthread_cond_signal.3 \
+ pthread_cond_timedwait.3 \
+ pthread_cond_wait.3 \
+ pthread_cancel.3 \
+ pthread_create.3 \
+ pthread_detach.3 \
+ pthread_equal.3 \
+ pthread_exit.3 \
+ pthread_getspecific.3 \
+ pthread_join.3 \
+ pthread_key_create.3 \
+ pthread_key_delete.3 \
+ pthread_mutex_destroy.3 \
+ pthread_mutex_init.3 \
+ pthread_mutex_lock.3 \
+ pthread_mutex_trylock.3 \
+ pthread_mutex_unlock.3 \
+ pthread_once.3 \
+ pthread_rwlock_destroy.3 \
+ pthread_rwlock_init.3 \
+ pthread_rwlock_rdlock.3 \
+ pthread_rwlock_unlock.3 \
+ pthread_rwlock_wrlock.3 \
+ pthread_rwlockattr_destroy.3 \
+ pthread_rwlockattr_getpshared.3 \
+ pthread_rwlockattr_init.3 \
+ pthread_rwlockattr_setpshared.3 \
+ pthread_self.3 \
+ pthread_setspecific.3 \
+ pthread_testcancel.3
+
+MLINKS+= pthread_cancel.3 pthread_setcancelstate.3 \
+ pthread_cancel.3 pthread_getcancelstate.3
diff --git a/lib/libc_r/man/pthread_cancel.3 b/lib/libc_r/man/pthread_cancel.3
new file mode 100644
index 0000000..5d02554
--- /dev/null
+++ b/lib/libc_r/man/pthread_cancel.3
@@ -0,0 +1,73 @@
+.\" $FreeBSD$
+.Dd January 17, 1999
+.Dt PTHREAD_CANCEL 3
+.Os
+.Sh NAME
+.Nm pthread_cancel
+.Nd cancel execution of a thread
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cancel "pthread_t thread"
+.Sh DESCRIPTION
+The
+.Fn pthread_cancel
+function requests that
+.Fa thread
+be canceled. The target thread's cancelability state and type determines
+when the cancellation takes effect. When the cancellation is acted on,
+the cancellation cleanup handlers for
+.Fa thread
+are called. When the last cancellation cleanup handler returns,
+the thread-specific data destructor functions will be called for
+.Fa thread .
+When the last destructor function returns,
+.Fa thread
+will be terminated.
+.Pp
+The cancellation processing in the target thread runs asynchronously with
+respect to the calling thread returning from
+.Fn pthread_cancel .
+.Pp
+A status of
+.Dv PTHREAD_CANCELED
+is made available to any threads joining with the target. The symbolic
+constant
+.Dv PTHREAD_CANCELED
+expands to a constant expression of type
+.Ft "(void *)" ,
+whose value matches no pointer to an object in memory nor the value
+.Dv NULL .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cancel
+functions will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_cancel
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ESRCH
+No thread could be found corresponding to that specified by the given
+thread ID.
+.El
+.Sh SEE ALSO
+.Xr pthread_cleanup_pop 3 ,
+.Xr pthread_cleanup_push 3 ,
+.Xr pthread_exit 3 ,
+.Xr pthread_join 3 ,
+.Xr pthread_setcancelstate 3 ,
+.Xr pthread_setcanceltype 3 ,
+.Xr pthread_testcancel 3
+.Sh STANDARDS
+.Fn pthread_cancel
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
+.Sh AUTHORS
+This man page was written by
+.An David Leonard Aq d@openbsd.org
+for the
+.Ox
+implementation of
+.Fn pthread_cancel .
diff --git a/lib/libc_r/man/pthread_cleanup_pop.3 b/lib/libc_r/man/pthread_cleanup_pop.3
new file mode 100644
index 0000000..faae8ba
--- /dev/null
+++ b/lib/libc_r/man/pthread_cleanup_pop.3
@@ -0,0 +1,62 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 30, 1998
+.Dt PTHREAD_CLEANUP_POP 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cleanup_pop
+.Nd call the first cleanup routine
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft void
+.Fn pthread_cleanup_pop "int execute"
+.Sh DESCRIPTION
+The
+.Fn pthread_cleanup_pop
+function pops the top cleanup routine off of the current threads cleanup
+routine stack, and, if
+.Fa execute
+is non-zero, it will execute the function. If there is no cleanup routine
+then
+.Fn pthread_cleanup_pop
+does nothing.
+.Sh RETURN VALUES
+.Fn pthread_cleanup_pop
+does not return any value.
+.Sh ERRORS
+None
+.Sh SEE ALSO
+.Xr pthread_cleanup_push 3 ,
+.Xr pthread_exit 3
+.Sh STANDARDS
+.Fn pthread_cleanup_pop
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_cleanup_push.3 b/lib/libc_r/man/pthread_cleanup_push.3
new file mode 100644
index 0000000..4f260af
--- /dev/null
+++ b/lib/libc_r/man/pthread_cleanup_push.3
@@ -0,0 +1,65 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 30, 1998
+.Dt PTHREAD_CLEANUP_PUSH 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cleanup_push
+.Nd add a cleanup function for thread exit
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft void
+.Fn pthread_cleanup_push "void (*cleanup_routine)(void *)" "void *arg"
+.Sh DESCRIPTION
+The
+.Fn pthread_cleanup_push
+function adds
+.Fa cleanup_routine
+to the top of the stack of cleanup handlers that
+get called when the current thread exits.
+.Pp
+When
+.Fn pthread_cleanup_push
+is called, it is passed
+.Fa arg
+as its only argument.
+.Sh RETURN VALUES
+.Fn pthread_cleanup_push
+does not return any value.
+.Sh ERRORS
+None
+.Sh SEE ALSO
+.Xr pthread_cleanup_pop 3 ,
+.Xr pthread_exit 3
+.Sh STANDARDS
+.Fn pthread_cleanup_push
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_cond_broadcast.3 b/lib/libc_r/man/pthread_cond_broadcast.3
new file mode 100644
index 0000000..6112695
--- /dev/null
+++ b/lib/libc_r/man/pthread_cond_broadcast.3
@@ -0,0 +1,70 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1998
+.Dt PTHREAD_COND_BROADCAST 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cond_broadcast
+.Nd unblock all threads waiting for a condition variable
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cond_broadcast "pthread_cond_t *cond"
+.Sh DESCRIPTION
+The
+.Fn pthread_cond_broadcast
+function unblocks all threads waiting for the condition variable
+.Fa cond .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cond_broadcast
+function will return zero, otherwise an error number will be returned
+to indicate the error.
+.Sh ERRORS
+.Fn pthread_cond_broadcast
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa cond
+is invalid.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_cond_destroy 3 ,
+.Xr pthread_cond_init 3 ,
+.Xr pthread_cond_signal 3 ,
+.Xr pthread_cond_timedwait 3 ,
+.Xr pthread_cond_wait 3
+.Sh STANDARDS
+.Fn pthread_cond_broadcast
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_cond_destroy.3 b/lib/libc_r/man/pthread_cond_destroy.3
new file mode 100644
index 0000000..a9c4a9d
--- /dev/null
+++ b/lib/libc_r/man/pthread_cond_destroy.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1998
+.Dt PTHREAD_COND_DESTROY 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cond_destroy
+.Nd destroy a condition variable
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cond_destroy "pthread_cond_t *cond"
+.Sh DESCRIPTION
+The
+.Fn pthread_cond_destroy
+function frees the resources allocated by the condition variable
+.Fa cond .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cond_destroy
+function will return zero, otherwise an error number will be returned
+to indicate the error.
+.Sh ERRORS
+.Fn pthread_cond_destroy
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa cond
+is invalid.
+.It Bq Er EBUSY
+The variable
+.Fa cond
+is locked by another thread.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_cond_broadcast 3 ,
+.Xr pthread_cond_init 3 ,
+.Xr pthread_cond_signal 3 ,
+.Xr pthread_cond_timedwait 3 ,
+.Xr pthread_cond_wait 3
+.Sh STANDARDS
+.Fn pthread_cond_destroy
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_cond_init.3 b/lib/libc_r/man/pthread_cond_init.3
new file mode 100644
index 0000000..2783672
--- /dev/null
+++ b/lib/libc_r/man/pthread_cond_init.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1998
+.Dt PTHREAD_COND_INIT 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cond_init
+.Nd create a condition variable
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cond_init "pthread_cond_t *cond" "const pthread_condattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_cond_init
+function creates a new condition variable, with attributes specified with
+.Fa attr .
+If
+.Fa attr
+is NULL the default attributes are used.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cond_init
+function will return zero and put the new condition variable id into
+.Fa cond ,
+otherwise an error number will be returned to indicate the error.
+.Sh ERRORS
+.Fn pthread_cond_init
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.It Bq Er ENOMEM
+The process cannot allocate enough memory to create another condition
+variable.
+.It Bq Er EAGAIN
+The temporarily lacks the resources to create another condition variable.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_cond_broadcast 3 ,
+.Xr pthread_cond_destroy 3 ,
+.Xr pthread_cond_signal 3 ,
+.Xr pthread_cond_timedwait 3 ,
+.Xr pthread_cond_wait 3
+.Sh STANDARDS
+.Fn pthread_cond_init
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_cond_signal.3 b/lib/libc_r/man/pthread_cond_signal.3
new file mode 100644
index 0000000..e3a22f8
--- /dev/null
+++ b/lib/libc_r/man/pthread_cond_signal.3
@@ -0,0 +1,70 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1998
+.Dt PTHREAD_COND_SIGNAL 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cond_signal
+.Nd unblock a thread waiting for a condition variable
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cond_signal "pthread_cond_t *cond"
+.Sh DESCRIPTION
+The
+.Fn pthread_cond_signal
+function unblocks one thread waiting for the condition variable
+.Fa cond .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cond_signal
+function will return zero, otherwise an error number will be returned
+to indicate the error.
+.Sh ERRORS
+.Fn pthread_cond_signal
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa cond
+is invalid.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_cond_broadcast 3 ,
+.Xr pthread_cond_destroy 3 ,
+.Xr pthread_cond_init 3 ,
+.Xr pthread_cond_timedwait 3 ,
+.Xr pthread_cond_wait 3
+.Sh STANDARDS
+.Fn pthread_cond_signal
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_cond_timedwait.3 b/lib/libc_r/man/pthread_cond_timedwait.3
new file mode 100644
index 0000000..40cf5ec
--- /dev/null
+++ b/lib/libc_r/man/pthread_cond_timedwait.3
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1998
+.Dt PTHREAD_COND_TIMEDWAIT 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cond_timedwait
+.Nd wait on a condition variable for a specific amount of time
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cond_timedwait "pthread_cond_t *cond" "pthread_mutex_t *mutex" "const struct timespec *abstime"
+.Sh DESCRIPTION
+The
+.Fn pthread_cond_timedwait
+function atomically blocks the current thread waiting on the condition
+variable specified by
+.Fa cond ,
+and unblocks the mutex specified by
+.Fa mutex .
+The waiting thread unblocks only after another thread calls
+.Xr pthread_cond_signal 3 ,
+or
+.Xr pthread_cond_broadcast 3
+with the same condition variable, or if the system time reaches the
+time specified in
+.Fa abstime ,
+and the current thread requires the lock on
+.Fa mutex .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cond_timedwait
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_cond_timedwait
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa cond ,
+.Fa mutex
+or
+.Fa abstime
+is invalid.
+.It Bq Er ETIMEDOUT
+The system time has reached or exceeded the time specified in
+.Fa abstime .
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_cond_broadcast 3 ,
+.Xr pthread_cond_destroy 3 ,
+.Xr pthread_cond_init 3 ,
+.Xr pthread_cond_signal 3 ,
+.Xr pthread_cond_wait 3
+.Sh STANDARDS
+.Fn pthread_cond_timedwait
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_cond_wait.3 b/lib/libc_r/man/pthread_cond_wait.3
new file mode 100644
index 0000000..7e6da6c
--- /dev/null
+++ b/lib/libc_r/man/pthread_cond_wait.3
@@ -0,0 +1,81 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1998
+.Dt PTHREAD_COND_WAIT 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cond_wait
+.Nd wait on a condition variable
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cond_wait "pthread_cond_t *cond" "pthread_mutex_t *mutex"
+.Sh DESCRIPTION
+The
+.Fn pthread_cond_wait
+function atomically blocks the current thread waiting on the condition
+variable specified by
+.Fa cond ,
+and unblocks the mutex specified by
+.Fa mutex .
+The waiting thread unblocks only after another thread calls
+.Xr pthread_cond_signal 3 , or
+.Xr pthread_cond_broadcast 3
+with the same condition variable, and the current thread requires the lock
+on
+.Fa mutex .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cond_wait
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_cond_wait
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa cond
+or the value specified by
+.Fa mutex
+is invalid.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_cond_broadcast 3 ,
+.Xr pthread_cond_destroy 3 ,
+.Xr pthread_cond_init 3 ,
+.Xr pthread_cond_signal 3 ,
+.Xr pthread_cond_timedwait 3
+.Sh STANDARDS
+.Fn pthread_cond_wait
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_create.3 b/lib/libc_r/man/pthread_create.3
new file mode 100644
index 0000000..cdc28a5
--- /dev/null
+++ b/lib/libc_r/man/pthread_create.3
@@ -0,0 +1,114 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_CREATE 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_create
+.Nd create a new thread
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_create "pthread_t *thread" "const pthread_attr_t *attr" "void *(*start_routine)(void *)" "void *arg"
+.Sh DESCRIPTION
+The
+.Fn pthread_create
+function is used to create a new thread, with attributes specified by
+.Fa attr ,
+within a process. If
+.Fa attr
+is NULL, the default attributes are used. If the attributes specified by
+.Fa attr
+are modified later, the thread's attributes are not affected. Upon
+successful completion
+.Fn pthread_create
+will store the ID of the created thread in the location specified by
+.Fa thread .
+.Pp
+The thread is created executing
+.Fa start_routine
+with
+.Fa arg
+as its sole argument. If the
+.Fa start_routine
+returns, the effect is as if there was an implicit call to
+.Fn pthread_exit
+using the return value of
+.Fa start_routine
+as the exit status. Note that the thread in which
+.Fn main
+was originally invoked differs from this. When it returns from
+.Fn main ,
+the effect is as if there was an implicit call to
+.Fn exit
+using the return value of
+.Fn main
+as the exit status.
+.Pp
+The signal state of the new thread is initialized as:
+.Bl -bullet -offset indent
+.It
+The signal mask is inherited from the creating thread.
+.It
+The set of signals pending for the new thread is empty.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_create
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_create
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The system lacked the necessary resources to create another thread, or
+the system-imposed limit on the total number of threads in a process
+[PTHREAD_THREADS_MAX] would be exceeded.
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr fork 2 ,
+.Xr pthread_cleanup_pop 3 ,
+.Xr pthread_cleanup_push 3 ,
+.Xr pthread_exit 3 ,
+.Xr pthread_join 3
+.Sh STANDARDS
+.Fn pthread_create
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_detach.3 b/lib/libc_r/man/pthread_detach.3
new file mode 100644
index 0000000..a3fffc6
--- /dev/null
+++ b/lib/libc_r/man/pthread_detach.3
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1996-1998 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_DETACH 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_detach
+.Nd detach a thread
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_detach "pthread_t thread"
+.Sh DESCRIPTION
+The
+.Fn pthread_detach
+function is used to indicate to the implementation that storage for the
+thread
+.Fa thread
+can be reclaimed when the thread terminates. If
+.Fa thread
+has not terminated,
+.Fn pthread_detach
+will not cause it to terminate. The effect of multiple
+.Fn pthread_detach
+calls on the same target thread is unspecified.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_detach
+function will return zero. Otherwise an error number will be returned to
+indicate the error. Note that the function does not change the value
+of errno as it did for some drafts of the standard. These early drafts
+also passed a pointer to pthread_t as the argument. Beware!
+.Sh ERRORS
+.Fn pthread_detach
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The implementation has detected that the value specified by
+.Fa thread
+does not refer to a joinable thread.
+.It Bq Er ESRCH
+No thread could be found corresponding to that specified by the given
+thread ID,
+.Fa thread .
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_join 3
+.Sh STANDARDS
+.Fn pthread_detach
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_equal.3 b/lib/libc_r/man/pthread_equal.3
new file mode 100644
index 0000000..5d443b3
--- /dev/null
+++ b/lib/libc_r/man/pthread_equal.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_EQUAL 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_equal
+.Nd compare thread IDs
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_equal "pthread_t t1" "pthread_t t2"
+.Sh DESCRIPTION
+The
+.Fn pthread_equal
+function compares the thread IDs
+.Fa t1
+and
+.Fa t2 .
+.Sh RETURN VALUES
+The
+.Fn pthread_equal
+function will non-zero if the thread IDs
+.Fa t1
+and
+.Fa t2
+correspond to the same thread, otherwise it will return zero.
+.Sh ERRORS
+None.
+.Pp
+.Sh SEE ALSO
+.Xr pthread_create 3 ,
+.Xr pthread_exit 3
+.Sh STANDARDS
+.Fn pthread_equal
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_exit.3 b/lib/libc_r/man/pthread_exit.3
new file mode 100644
index 0000000..ff452ca
--- /dev/null
+++ b/lib/libc_r/man/pthread_exit.3
@@ -0,0 +1,101 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_EXIT 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_exit
+.Nd terminate the calling thread
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft void
+.Fn pthread_exit "void *value_ptr"
+.Sh DESCRIPTION
+The
+.Fn pthread_exit
+function terminates the calling thread and makes the value
+.Fa value_ptr
+available to any successful join with the terminating thread. Any
+cancellation cleanup handlers that have been pushed and are not yet popped
+are popped in the reverse order that they were pushed and then executed.
+After all cancellation handlers have been executed, if the thread has any
+thread-specific data, appropriate destructor functions are called in an
+unspecified order. Thread termination does not release any application
+visible process resources, including, but not limited to, mutexes and
+file descriptors, nor does it perform any process level cleanup
+actions, including, but not limited to, calling
+.Fn atexit
+routines that may exist.
+.Pp
+An implicit call to
+.Fn pthread_exit
+is made when a thread other than the thread in which
+.Fn main
+was first invoked returns from the start routine that was used to create
+it. The function's return value serves as the thread's exit status.
+.Pp
+The behavior of
+.Fn pthread_exit
+is undefied if called from a cancellation handler or destructor function
+that was invoked as the result of an implicit or explicit call to
+.Fn pthread_exit .
+.Pp
+After a thread has terminated, the result of access to local (auto)
+variables of the thread is undefined. Thus, references to local variables
+of the exiting thread should not be used for the
+.Fn pthread_exit
+.Fa value_ptr
+parameter value.
+.Pp
+The process will exit with an exit status of 0 after the last thread has
+been terminated. The behavior is as if the implementation called
+.Fn exit
+with a zero argument at thread termination time.
+.Pp
+.Sh RETURN VALUES
+The
+.Fn pthread_exit
+function cannot return to its caller.
+.Sh ERRORS
+None.
+.Pp
+.Sh SEE ALSO
+.Xr _exit 2 ,
+.Xr exit 3 ,
+.Xr pthread_create 3 ,
+.Xr pthread_join 3
+.Sh STANDARDS
+.Fn pthread_exit
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_getspecific.3 b/lib/libc_r/man/pthread_getspecific.3
new file mode 100644
index 0000000..a562541
--- /dev/null
+++ b/lib/libc_r/man/pthread_getspecific.3
@@ -0,0 +1,82 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_GETSPECIFIC 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_getspecific
+.Nd get a thread-specific data value
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft void *
+.Fn pthread_getspecific "pthread_key_t key"
+.Sh DESCRIPTION
+The
+.Fn pthread_getspecific
+function returns the value currently bound to the specified
+.Fa key
+on behalf of the calling thread.
+.Pp
+The effect of calling
+.Fn pthread_getspecific
+with a
+.Fa key
+value not obtained from
+.Fn pthread_key_create
+or after
+.Fa key
+has been deleted with
+.Fn pthread_key_delete
+is undefined.
+.Pp
+.Fn pthread_getspecific
+may be called from a thread-specific data destructor function.
+.Sh RETURN VALUES
+The
+.Fn pthread_getspecific
+function will return the thread-specific data value associated with the given
+.Fa key .
+If no thread-specific data value is associated with
+.Fa key ,
+then the value NULL is returned.
+.Sh ERRORS
+None.
+.Sh SEE ALSO
+.Xr pthread_key_create 3 ,
+.Xr pthread_key_delete 3 ,
+.Xr pthread_setspecific 3
+.Sh STANDARDS
+.Fn pthread_getspecific
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_join.3 b/lib/libc_r/man/pthread_join.3
new file mode 100644
index 0000000..e32ad40
--- /dev/null
+++ b/lib/libc_r/man/pthread_join.3
@@ -0,0 +1,102 @@
+.\" Copyright (c) 1996-1998 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_JOIN 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_join
+.Nd wait for thread termination
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_join "pthread_t thread" "void **value_ptr"
+.Sh DESCRIPTION
+The
+.Fn pthread_join
+function suspends execution of the calling thread until the target
+.Fa thread
+terminates unless the target
+.Fa thread
+has already terminated.
+.Pp
+On return from a successful
+.Fn pthread_join
+call with a non-NULL
+.Fa value_ptr
+argument, the value passed to
+.Fn pthread_exit
+by the terminating thread is stored in the location referenced by
+.Fa value_ptr .
+When a
+.Fn pthread_join
+returns successfully, the target thread has been terminated. The results
+of multiple simultaneous calls to
+.Fn pthread_join
+specifying the same target thread are undefined. If the thread calling
+.Fn pthread_join
+is cancelled, then the target thread is not detached.
+.Pp
+A thread that has exited but remains unjoined counts against
+[_POSIX_THREAD_THREADS_MAX].
+.Pp
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_join
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_join
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The implementation has detected that the value specified by
+.Fa thread
+does not refer to a joinable thread.
+.It Bq Er ESRCH
+No thread could be found corresponding to that specified by the given
+thread ID,
+.Fa thread .
+.It Bq Er EDEADLK
+A deadlock was detected or the value of
+.Fa thread
+specifies the calling thread.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr wait 2 ,
+.Xr pthread_create 3
+.Sh STANDARDS
+.Fn pthread_join
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_key_create.3 b/lib/libc_r/man/pthread_key_create.3
new file mode 100644
index 0000000..76fc187
--- /dev/null
+++ b/lib/libc_r/man/pthread_key_create.3
@@ -0,0 +1,100 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_KEY_CREATE 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_key_create
+.Nd thread-specific data key creation
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_key_create "pthread_key_t *key" "void (*destructor)(void *)"
+.Sh DESCRIPTION
+The
+.Fn pthread_key_create
+function creates a thread-specific data key visible to all threads in the
+process. Key values provided by
+.Fn pthread_key_create
+are opaque objects used to locate thread-specific data. Although the same
+key value may be used by different threads, the values bound to the key
+by
+.Fn pthread_setspecific
+are maintained on a per-thread basis and persist for the life of the calling
+thread.
+.Pp
+Upon key creation, the value NULL is associated with the new key in all
+active threads. Upon thread creation, the value NULL is associated with all
+defined keys in the new thread.
+.Pp
+An optional destructor function may be associated with each key value. At
+thread exit, if a key value has a non-NULL destructor pointer, and the
+thread has a non-NULL value associated with the key, the function pointed
+to is called with the current associated value as its sole argument. The
+order of destructor calls is unspecified if more than one destructor exists
+for a thread when it exits.
+.Pp
+If, after all the destructors have been called for all non-NULL values
+with associated destructors, there are still some non-NULL values with
+associated destructors, then the process is repeated. If, after at least
+[PTHREAD_DESTRUCTOR_ITERATIONS] iterations of destructor calls for
+outstanding non-NULL values, there are still some non-NULL values with
+associated destructors, the implementation stops calling destructors.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_key_create
+function will store the newly created key value at the location specified by
+.Fa key
+and returns zero. Otherwise an error number will be returned to indicate
+the error.
+.Sh ERRORS
+.Fn pthread_key_create
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The system lacked the necessary resources to create another thread-specific
+data key, or the system-imposed limit on the total number of keys per process
+[PTHREAD_KEYS_MAX] would be exceeded.
+.It Bq Er ENOMEM
+Insufficient memory exists to create the key.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_getspecific 3 ,
+.Xr pthread_key_delete 3 ,
+.Xr pthread_setspecific 3
+.Sh STANDARDS
+.Fn pthread_key_create
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_key_delete.3 b/lib/libc_r/man/pthread_key_delete.3
new file mode 100644
index 0000000..39fb19e
--- /dev/null
+++ b/lib/libc_r/man/pthread_key_delete.3
@@ -0,0 +1,94 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_KEY_DELETE 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_key_delete
+.Nd delete a thread-specific data key
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_key_delete "pthread_key_t key"
+.Sh DESCRIPTION
+The
+.Fn pthread_key_delete
+function deletes a thread-specific data key previously returned by
+.Fn pthread_key_create .
+The thread-specific data values associated with
+.Fa key
+need not be NULL at the time that
+.Fn pthread_key_delete
+is called. It is the responsibility of the application to free any
+application storage or perform any cleanup actions for data structures
+related to the deleted key or associated thread-specific data in any threads;
+this cleanup can be done either before or after
+.Fn pthread_key_delete
+is called. Any attempt to use
+.Fa key
+following the call to
+.Fn pthread_key_delete
+results in undefined behavior.
+.Pp
+The
+.Fn pthread_key_delete
+function is callable from within destructor functions. Destructor functions
+are not invoked by
+.Fn pthread_key_delete .
+Any destructor function that may have been associated with
+.Fa key
+will no longer be called upon thread exit.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_key_delete
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_key_delete
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa key
+value is invalid.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_getspecific 3 ,
+.Xr pthread_key_create 3 ,
+.Xr pthread_setspecific 3
+.Sh STANDARDS
+.Fn pthread_key_delete
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_mutex_destroy.3 b/lib/libc_r/man/pthread_mutex_destroy.3
new file mode 100644
index 0000000..517d6eb
--- /dev/null
+++ b/lib/libc_r/man/pthread_mutex_destroy.3
@@ -0,0 +1,72 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 29, 1998
+.Dt PTHREAD_MUTEX_DESTROY 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_mutex_destroy
+.Nd free resources allocated for a mutex
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_mutex_destroy "pthread_mutex_t *mutex"
+.Sh DESCRIPTION
+The
+.Fn pthread_mutex_destroy
+function frees the resources allocated for
+.Fa mutex .
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_mutex_destroy
+will return zero, otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_mutex_destroy
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa mutex
+is invalid.
+.It Bq Er EBUSY
+.Fa Mutex
+is locked by another thread.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_mutex_init 3 ,
+.Xr pthread_mutex_lock 3 ,
+.Xr pthread_mutex_trylock 3 ,
+.Xr pthread_mutex_unlock 3
+.Sh STANDARDS
+.Fn pthread_mutex_destroy
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_mutex_init.3 b/lib/libc_r/man/pthread_mutex_init.3
new file mode 100644
index 0000000..926b034
--- /dev/null
+++ b/lib/libc_r/man/pthread_mutex_init.3
@@ -0,0 +1,77 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 29, 1998
+.Dt PTHREAD_MUTEX_INIT 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_mutex_init
+.Nd create a mutex
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_mutex_init "pthread_mutex_t *mutex" "const pthread_mutexattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_mutex_init
+function creates a new mutex, with attributes specified with
+.Fa attr .
+If
+.Fa attr
+is NULL the default attributes are used.
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_mutex_init
+will return zero and put the new mutex id into
+.Fa mutex ,
+otherwise an error number will be returned to indicate the error.
+.Sh ERRORS
+.Fn pthread_mutex_init
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.It Bq Er ENOMEM
+The process cannot allocate enough memory to create another mutex.
+.It Bq Er EAGAIN
+The temporarily lacks the resources to create another mutex.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_mutex_destroy 3 ,
+.Xr pthread_mutex_lock 3 ,
+.Xr pthread_mutex_trylock 3 ,
+.Xr pthread_mutex_unlock 3
+.Sh STANDARDS
+.Fn pthread_mutex_init
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_mutex_lock.3 b/lib/libc_r/man/pthread_mutex_lock.3
new file mode 100644
index 0000000..3647373
--- /dev/null
+++ b/lib/libc_r/man/pthread_mutex_lock.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 30, 1998
+.Dt PTHREAD_MUTEX_LOCK 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_mutex_lock
+.Nd lock a mutex
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_mutex_lock "pthread_mutex_t *mutex"
+.Sh DESCRIPTION
+The
+.Fn pthread_mutex_lock
+function locks
+.Fa mutex .
+If the mutex is already locked, the calling thread will block until the
+mutex becomes available.
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_mutex_lock
+will return zero, otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_mutex_lock
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa mutex
+is invalid.
+.It Bq Er EDEADLK
+A deadlock would occur if the thread blocked waiting for
+.Fa mutex .
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_mutex_destroy 3 ,
+.Xr pthread_mutex_init 3 ,
+.Xr pthread_mutex_trylock 3 ,
+.Xr pthread_mutex_unlock 3
+.Sh STANDARDS
+.Fn pthread_mutex_lock
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_mutex_trylock.3 b/lib/libc_r/man/pthread_mutex_trylock.3
new file mode 100644
index 0000000..30faaa8
--- /dev/null
+++ b/lib/libc_r/man/pthread_mutex_trylock.3
@@ -0,0 +1,75 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 30, 1998
+.Dt PTHREAD_MUTEX_TRYLOCK 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_mutex_trylock
+.Nd attempt to lock a mutex without blocking
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_mutex_trylock "pthread_mutex_t *mutex"
+.Sh DESCRIPTION
+The
+.Fn pthread_mutex_trylock
+function locks
+.Fa mutex .
+If the mutex is already locked,
+.Fn pthread_mutex_trylock
+will not block waiting for the mutex, but will return an error condition.
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_mutex_trylock
+will return zero, otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_mutex_trylock
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa mutex
+is invalid.
+.It Bq Er EBUSY
+.Fa Mutex
+is already locked.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_mutex_destroy 3 ,
+.Xr pthread_mutex_init 3 ,
+.Xr pthread_mutex_lock 3 ,
+.Xr pthread_mutex_unlock 3
+.Sh STANDARDS
+.Fn pthread_mutex_trylock
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_mutex_unlock.3 b/lib/libc_r/man/pthread_mutex_unlock.3
new file mode 100644
index 0000000..27a4c33
--- /dev/null
+++ b/lib/libc_r/man/pthread_mutex_unlock.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 30, 1998
+.Dt PTHREAD_MUTEX_UNLOCK 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_mutex_unlock
+.Nd unlock a mutex
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_mutex_unlock "pthread_mutex_t *mutex"
+.Sh DESCRIPTION
+If the current thread holds the lock on
+.Fa mutex ,
+then the
+.Fn pthread_mutex_unlock
+function unlocks
+.Fa mutex .
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_mutex_unlock
+will return zero, otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_mutex_trylock
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa mutex
+is invalid.
+.It Bq Er EPERM
+The current thread does not hold a lock on
+.Fa mutex .
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_mutex_destroy 3 ,
+.Xr pthread_mutex_init 3 ,
+.Xr pthread_mutex_lock 3 ,
+.Xr pthread_mutex_trylock 3
+.Sh STANDARDS
+.Fn pthread_mutex_unlock
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_once.3 b/lib/libc_r/man/pthread_once.3
new file mode 100644
index 0000000..2dcea49
--- /dev/null
+++ b/lib/libc_r/man/pthread_once.3
@@ -0,0 +1,102 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_ONCE 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_once
+.Nd dynamic package initialization
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Pp
+pthread_once
+.Fa once_control
+= PTHREAD_ONCE_INIT;
+.Ft int
+.Fn pthread_once "pthread_once_t *once_control" "void (*init_routine)(void)"
+.Sh DESCRIPTION
+The first call to
+.Fn pthread_once
+by any thread in a process, with a given
+.Fa once_control ,
+will call the
+.Fn init_routine
+with no arguments. Subsequent calls to
+.Fn pthread_once
+with the same
+.Fa once_control
+will not call the
+.Fn init_routine .
+On return from
+.Fn pthread_once ,
+it is guaranteed that
+.Fn init_routine
+has completed. The
+.Fa once_control
+parameter is used to determine whether the associated initialization
+routine has been called.
+.Pp
+The function
+.Fn pthread_once
+is not a cancellation point. However, if
+.Fn init_routine
+is a cancellation point and is cancelled, the effect on
+.Fa once_control is as if
+.Fn pthread_once
+was never called.
+.Pp
+The constant
+.Fa PTHREAD_ONCE_INIT
+is defined by header
+.Aq Pa pthread.h .
+.Pp
+The behavior of
+.Fn pthread_once
+is undefined if
+.Fa once_control
+has automatic storage duration or is not initialized by
+.Fa PTHREAD_ONCE_INIT .
+.Pp
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_once
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+None.
+.Pp
+.Sh STANDARDS
+.Fn pthread_once
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_rwlock_destroy.3 b/lib/libc_r/man/pthread_rwlock_destroy.3
new file mode 100644
index 0000000..14691c4
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlock_destroy.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_DESTROY 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_destroy
+.Nd destroy a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_destroy "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_destroy
+function is used to destroy a read/write lock previously created with
+.Fn pthread_rwlock_init .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_destroy
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_destroy
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_destroy
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The caller does not have the privilege to perform the operation.
+.El
+.Pp
+The
+.Fn pthread_rwlock_destroy
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The system has detected an attempt to destroy the object referenced by
+.Fa lock
+while it is locked.
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_destroy
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlock_init.3 b/lib/libc_r/man/pthread_rwlock_init.3
new file mode 100644
index 0000000..306af61
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlock_init.3
@@ -0,0 +1,99 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_INIT 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_init
+.Nd initialize a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_init "pthread_rwlock_t *lock" "const pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_init
+function is used to initialize a read/write lock, with attributes
+specified by
+.Fa attr .
+If
+.Fa attr
+is NULL, the default read/write lock attributes are used.
+.Pp
+The results of calling
+.Fn pthread_rwlock_init
+with an already initialized lock are undefined.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_init
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_destroy 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_init
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_init
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The system lacked the necessary resources (other than memory) to
+initialize the lock.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock.
+.It Bq Er EPERM
+The caller does not have sufficient privilege to perform the
+operation.
+.El
+.Pp
+The
+.Fn pthread_rwlock_init
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The system has detected an attempt to re-initialize the object
+referenced by
+.Fa lock ,
+a previously initialized but not yet destroyed read/write lock.
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_init
+function first appeared in
+.Fx 3.0 .
+.Sh BUGS
+The PTHREAD_PROCESS_SHARED attribute is not supported.
diff --git a/lib/libc_r/man/pthread_rwlock_rdlock.3 b/lib/libc_r/man/pthread_rwlock_rdlock.3
new file mode 100644
index 0000000..bea219d
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlock_rdlock.3
@@ -0,0 +1,122 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_RDLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_rdlock ,
+.Nm pthread_rwlock_tryrdlock
+.Nd acquire a read/write lock for reading
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_rdlock "pthread_rwlock_t *lock"
+.Ft int
+.Fn pthread_rwlock_tryrdlock "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_rdlock
+function acquires a read lock on
+.Fa lock
+provided that
+.Fa lock
+is not presently held for writing and no writer threads are
+presently blocked on the lock. If the read lock cannot be
+immediately acquired, the calling thread blocks until it can
+acquire the lock.
+.Pp
+The
+.Fn pthread_rwlock_tryrdlock
+function performs the same action, but does not block if the lock
+cannot be immediately obtained (i.e. the lock is held for writing
+or there are waiting writers).
+.Pp
+A thread may hold multiple concurrent read locks. If so,
+.Fn pthread_rwlock_unlock
+must be called once for each lock obtained.
+.Pp
+The results of acquiring a read lock while the calling thread holds
+a write lock are undefined.
+.Sh IMPLEMENTATION NOTES
+To prevent writer starvation, writers are favored over readers.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlock_trywrlock 3 ,
+.Xr pthread_rwlock_unlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions are expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_tryrdlock
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The lock could not be acquired because a writer holds the lock or
+was blocked on it.
+.El
+.Pp
+The
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The lock could not be acquired because the maximum number of read locks
+against
+.Fa lock
+has been exceeded.
+.It Bq Er EDEADLK
+The current thread already owns
+.Fa lock
+for writing.
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock (applies to
+statically initialized locks only).
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_rdlock
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlock_unlock.3 b/lib/libc_r/man/pthread_rwlock_unlock.3
new file mode 100644
index 0000000..7ad52b2
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlock_unlock.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_UNLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_unlock
+.Nd release a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_unlock "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_unlock
+function is used to release the read/write lock previously obtained by
+.Fn pthread_rwlock_rdlock ,
+.Fn pthread_rwlock_wrlock ,
+.Fn pthread_rwlock_tryrdlock ,
+or
+.Fn pthread_rwlock_trywrlock .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_unlock
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Pp
+The results are undefined if
+.Fa lock
+is not held by the calling thread.
+.Sh SEE ALSO
+.Xr pthread_rwlock_rdlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_unlock
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_unlock
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er EPERM
+The current thread does not own the read/write lock.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_unlock
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlock_wrlock.3 b/lib/libc_r/man/pthread_rwlock_wrlock.3
new file mode 100644
index 0000000..b6a2312
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlock_wrlock.3
@@ -0,0 +1,102 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_WRLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_wrlock ,
+.Nm pthread_rwlock_trywrlock
+.Nd acquire a read/write lock for writing
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_wrlock "pthread_rwlock_t *lock"
+.Ft int
+.Fn pthread_rwlock_trywrlock "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_wrlock
+function blocks until a write lock can be acquired against
+.Fa lock .
+The
+.Fn pthread_rwlock_trywrlock
+function performs the same action, but does not block if the lock
+cannot be immediately obtained.
+.Pp
+The results are undefined if the calling thread already holds the
+lock at the time the call is made.
+.Sh IMPLEMENTATION NOTES
+To prevent writer starvation, writers are favored over readers.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_trywrlock 3 ,
+.Xr pthread_rwlock_unlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions are expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_trywrlock
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The calling thread is not able to acquire the lock without blocking.
+.El
+.Pp
+The
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EDEADLK
+The calling thread already owns the read/write lock (for reading
+or writing).
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock (applies to
+statically initialized locks only).
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_wrlock
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlockattr_destroy.3 b/lib/libc_r/man/pthread_rwlockattr_destroy.3
new file mode 100644
index 0000000..2d67041
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlockattr_destroy.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_DESTROY 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_destroy
+.Nd destroy a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_destroy "pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_destroy
+function is used to destroy a read/write lock attribute object
+previously created with
+.Fn pthread_rwlockattr_init .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_destroy
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlockattr_init 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_destroy
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_destroy
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_destroy
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlockattr_getpshared.3 b/lib/libc_r/man/pthread_rwlockattr_getpshared.3
new file mode 100644
index 0000000..d2028dc
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlockattr_getpshared.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 22, 1999
+.Dt PTHREAD_RWLOCKATTR_GETPSHARED 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_getpshared
+.Nd get the process shared attribute
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_getpshared "const pthread_rwlockattr_t *attr" "int *pshared"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_getpshared
+function is used to get the process shared setting of a read/write
+lock attribute object. The setting is returned via
+.Fa pshared ,
+and may be one of two values:
+.Bl -hang -offset flag -width 123456789012345678901234
+.It Ar PTHREAD_PROCESS_SHARED
+Any thread of any process that has access to the memory where the
+read/write lock resides can manipulate the lock.
+.It Ar PTHREAD_PROCESS_PRIVATE
+Only threads created within the same process as the thread that
+initialized the read/write lock can manipulate the lock. This is
+the default value.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_getpshared
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_getpshared
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_getpshared
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_getpshared
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlockattr_init.3 b/lib/libc_r/man/pthread_rwlockattr_init.3
new file mode 100644
index 0000000..ac19126
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlockattr_init.3
@@ -0,0 +1,67 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_INIT 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_init
+.Nd initialize a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_init "pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_init
+function is used to initialize a read/write lock attributes object.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_init
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_destroy 3 ,
+.Xr pthread_rwlockattr_getpshared 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_init
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_init
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the attribute object.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_init
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlockattr_setpshared.3 b/lib/libc_r/man/pthread_rwlockattr_setpshared.3
new file mode 100644
index 0000000..b98e081
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlockattr_setpshared.3
@@ -0,0 +1,86 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_SETPSHARED 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_setpshared
+.Nd set the process shared attribute
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_setpshared "pthread_rwlockattr_t *attr" "int *pshared"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_setpshared
+function sets the process shared attribute of
+.Fa attr
+to the value referenced by
+.Fa pshared .
+.Fa pshared
+may be one of two values:
+.Bl -hang -offset flag -width 123456789012345678901234
+.It Ar PTHREAD_PROCESS_SHARED
+Any thread of any process that has access to the memory where the
+read/write lock resides can manipulate the lock.
+.It Ar PTHREAD_PROCESS_PRIVATE
+Only threads created within the same process as the thread that
+initialized the read/write lock can manipulate the lock. This is
+the default value.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_setpshared
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_setpshared
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_setpshared
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+or
+.Fa pshared
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_setpshared
+function first appeared in
+.Fx 3.0 .
+.Sh BUGS
+The PTHREAD_PROCESS_SHARED attribute is not supported.
diff --git a/lib/libc_r/man/pthread_self.3 b/lib/libc_r/man/pthread_self.3
new file mode 100644
index 0000000..be524b9
--- /dev/null
+++ b/lib/libc_r/man/pthread_self.3
@@ -0,0 +1,61 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_SELF 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_self
+.Nd get the calling thread's ID
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft pthread_t
+.Fn pthread_self "void"
+.Sh DESCRIPTION
+The
+.Fn pthread_self
+function returns the thread ID of the calling thread.
+.Sh RETURN VALUES
+The
+.Fn pthread_self
+function returns the thread ID of the calling thread.
+.Sh ERRORS
+None.
+.Pp
+.Sh SEE ALSO
+.Xr pthread_create 3 ,
+.Xr pthread_equal 3
+.Sh STANDARDS
+.Fn pthread_self
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_setspecific.3 b/lib/libc_r/man/pthread_setspecific.3
new file mode 100644
index 0000000..89a416f
--- /dev/null
+++ b/lib/libc_r/man/pthread_setspecific.3
@@ -0,0 +1,93 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_SETSPECIFIC 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_setspecific
+.Nd set a thread-specific data value
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_setspecific "pthread_key_t key" "const void *value"
+.Sh DESCRIPTION
+The
+.Fn pthread_setspecific
+function associates a thread-specific value with a
+.Fa key
+obtained via a previous call to
+.Fn pthread_key_create .
+Different threads man bind different values to the same key. These values are
+typically pointers to blocks of dynamically allocated memory that have been
+reserved for use by the calling thread.
+.Pp
+The effect of calling
+.Fn pthread_setspecific
+with a key value not obtained from
+.Fn pthread_key_create
+or after
+.Fa key
+has been deleted with
+.Fn pthread_key_delete
+is undefined.
+.Pp
+.Fn pthread_setspecific
+may be called from a thread-specific data destructor function, however this
+may result in lost storage or infinite loops.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_setspecific
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_setspecific
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+Insufficient memory exists to associate the value with the
+.Fa key .
+.It Bq Er EINVAL
+The
+.Fa key
+value is invalid.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_getspecific 3 ,
+.Xr pthread_key_create 3 ,
+.Xr pthread_key_delete 3
+.Sh STANDARDS
+.Fn pthread_setspecific
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libc_r/man/pthread_testcancel.3 b/lib/libc_r/man/pthread_testcancel.3
new file mode 100644
index 0000000..670c47c
--- /dev/null
+++ b/lib/libc_r/man/pthread_testcancel.3
@@ -0,0 +1,187 @@
+.\" $FreeBSD$
+.Dd January 17, 1999
+.Dt PTHREAD_TESTCANCEL 3
+.Os
+.Sh NAME
+.Nm pthread_setcancelstate ,
+.Nm pthread_setcanceltype ,
+.Nm pthread_testcancel
+.Nd set cancelability state
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_setcancelstate "int state" "int *oldstate"
+.Ft int
+.Fn pthread_setcanceltype "int type" "int *oldtype"
+.Ft void
+.Fn pthread_testcancel "void"
+.Sh DESCRIPTION
+The
+.Fn pthread_setcancelstate
+function atomically both sets the calling thread's cancelability state
+to the indicated
+.Fa state
+and returns the previous cancelability state at the location referenced by
+.Fa oldstate .
+Legal values for
+.Fa state
+are
+.Dv PTHREAD_CANCEL_ENABLE
+and
+.Dv PTHREAD_CANCEL_DISABLE .
+.Pp
+The
+.Fn pthread_setcanceltype
+function atomically both sets the calling thread's cancelability type
+to the indicated
+.Fa type
+and returns the previous cancelability type at the location referenced by
+.Fa oldtype .
+Legal values for
+.Fa type
+are
+.Dv PTHREAD_CANCEL_DEFERRED
+and
+.Dv PTHREAD_CANCEL_ASYNCHRONOUS .
+.Pp
+The cancelability state and type of any newly created threads, including the
+thread in which
+.Fn main
+was first invoked, are
+.Dv PTHREAD_CANCEL_ENABLE
+and
+.Dv PTHREAD_CANCEL_DEFERRED
+respectively.
+.Pp
+The
+.Fn pthread_testcancel
+function creates a cancellation point in the calling thread. The
+.Fn pthread_testcancel
+function has no effect if cancelability is disabled.
+.Pp
+.Ss Cancelability States
+The cancelability state of a thread determines the action taken upon
+receipt of a cancellation request. The thread may control cancellation in
+a number of ways.
+.Pp
+Each thread maintains its own
+.Dq cancelability state
+which may be encoded in two bits:
+.Bl -hang
+.It Em Cancelability Enable
+When cancelability is
+.Dv PTHREAD_CANCEL_DISABLE ,
+cancellation requests against the target thread are held pending.
+.It Em Cancelability Type
+When cancelability is enabled and the cancelability type is
+.Dv PTHREAD_CANCEL_ASYNCHRONOUS ,
+new or pending cancellation requests may be acted upon at any time.
+When cancelability is enabled and the cancelability type is
+.Dv PTHREAD_CANCEL_DEFERRED ,
+cancellation requests are held pending until a cancellation point (see
+below) is reached. If cancelability is disabled, the setting of the
+cancelability type has no immediate effect as all cancellation requests
+are held pending; however, once cancelability is enabled again the new
+type will be in effect.
+.El
+.Ss Cancellation Points
+Cancellation points will occur when a thread is executing the following
+functions:
+.Fn close ,
+.Fn creat ,
+.Fn fcntl ,
+.Fn fsync ,
+.Fn msync ,
+.Fn nanosleep ,
+.Fn open ,
+.Fn pause ,
+.Fn pthread_cond_timedwait ,
+.Fn pthread_cond_wait ,
+.Fn pthread_join ,
+.Fn pthread_testcancel ,
+.Fn read ,
+.Fn sigwaitinfo ,
+.Fn sigsuspend ,
+.Fn sigwait ,
+.Fn sleep ,
+.Fn system ,
+.Fn tcdrain ,
+.Fn wait ,
+.Fn waitpid ,
+.Fn write .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_setcancelstate
+and
+.Fn pthread_setcanceltype
+functions will return zero. Otherwise, an error number shall be returned to
+indicate the error.
+.Pp
+The
+.Fn pthread_setcancelstate
+and
+.Fn pthread_setcanceltype
+functions are used to control the points at which a thread may be
+asynchronously canceled. For cancellation control to be usable in modular
+fashion, some rules must be followed.
+.Pp
+For purposes of this discussion, consider an object to be a generalization
+of a procedure. It is a set of procedures and global variables written as
+a unit and called by clients not known by the object. Objects may depend
+on other objects.
+.Pp
+First, cancelability should only be disabled on entry to an object, never
+explicitly enabled. On exit from an object, the cancelability state should
+always be restored to its value on entry to the object.
+.Pp
+This follows from a modularity argument: if the client of an object (or the
+client of an object that uses that object) has disabled cancelability, it is
+because the client doesn't want to have to worry about how to clean up if the
+thread is canceled while executing some sequence of actions. If an object
+is called in such a state and it enables cancelability and a cancellation
+request is pending for that thread, then the thread will be canceled,
+contrary to the wish of the client that disabled.
+.Pp
+Second, the cancelability type may be explicitly set to either
+.Em deferred
+or
+.Em asynchronous
+upon entry to an object. But as with the cancelability state, on exit from
+an object that cancelability type should always be restored to its value on
+entry to the object.
+.Pp
+Finally, only functions that are cancel-safe may be called from a thread that
+is asynchronously cancelable.
+.Sh ERRORS
+The function
+.Fn pthread_setcancelstate
+may fail with:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The specified state is not
+.Dv PTHREAD_CANCEL_ENABLE
+or
+.Dv PTHREAD_CANCEL_DISABLE .
+.El
+.Pp
+The function
+.Fn pthread_setcanceltype
+may fail with:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The specified state is not
+.Dv PTHREAD_CANCEL_DEFERRED
+or
+.Dv PTHREAD_CANCEL_ASYNCHRONOUS .
+.El
+.Sh SEE ALSO
+.Xr pthread_cancel 3
+.Sh STANDARDS
+.Fn pthread_testcancel
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
+.Sh AUTHORS
+This man page was written by
+.An David Leonard <d@openbsd.org>
+for the OpenBSD implementation of pthread_cancel.
diff --git a/lib/libc_r/sys/Makefile.inc b/lib/libc_r/sys/Makefile.inc
new file mode 100644
index 0000000..e608afa
--- /dev/null
+++ b/lib/libc_r/sys/Makefile.inc
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/sys ${.CURDIR}/arch/${MACHINE_ARCH}
+
+SRCS+= uthread_error.c _atomic_lock.S
+
diff --git a/lib/libc_r/sys/uthread_error.c b/lib/libc_r/sys/uthread_error.c
new file mode 100644
index 0000000..0d08ae8
--- /dev/null
+++ b/lib/libc_r/sys/uthread_error.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell
+ * and Chris Provenzano.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+extern int errno;
+
+int * __error()
+{
+ int *p_errno;
+ if (_thread_run == _thread_initial) {
+ p_errno = &errno;
+ } else {
+ p_errno = &_thread_run->error;
+ }
+ return(p_errno);
+}
+#endif
diff --git a/lib/libc_r/test/Makefile b/lib/libc_r/test/Makefile
new file mode 100644
index 0000000..90ee5ad
--- /dev/null
+++ b/lib/libc_r/test/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+#
+# Tests for libc_r functionality.
+#
+
+SUBDIR= mutex sigsuspend sigwait
+
+.include <bsd.subdir.mk>
diff --git a/lib/libc_r/test/mutex/Makefile b/lib/libc_r/test/mutex/Makefile
new file mode 100644
index 0000000..19f4ce3
--- /dev/null
+++ b/lib/libc_r/test/mutex/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+PROG= mutex
+SRCS= mutex.c
+NOMAN= 1
+LDFLAGS= -pthread
+
+.include <bsd.prog.mk>
diff --git a/lib/libc_r/test/mutex/mutex.c b/lib/libc_r/test/mutex/mutex.c
new file mode 100644
index 0000000..02689d3
--- /dev/null
+++ b/lib/libc_r/test/mutex/mutex.c
@@ -0,0 +1,1549 @@
+/*
+ * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel M. Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+#include <assert.h>
+#include <errno.h>
+#include "pthread.h"
+#include <sched.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <sysexits.h>
+
+#if defined(__FreeBSD__)
+#include <pthread_np.h>
+#endif
+
+#ifndef NELEMENTS
+#define NELEMENTS(arr) (sizeof (arr) / sizeof (arr[0]))
+#endif
+
+#ifndef NUM_THREADS
+#define NUM_THREADS 10
+#endif
+
+#define MAX_THREAD_CMDS 10
+
+
+/*------------------------------------------------------------
+ * Types
+ *----------------------------------------------------------*/
+
+typedef enum {
+ STAT_INITIAL, /* initial state */
+ STAT_WAITCONDVAR, /* waiting for condition variable signal */
+ STAT_WAITMUTEX /* waiting for mutex lock */
+} thread_status_t;
+
+typedef enum {
+ FLAGS_REPORT_WAITCONDMUTEX = 0x01,
+ FLAGS_REPORT_WAITCONDVAR = 0x02,
+ FLAGS_REPORT_WAITMUTEX = 0x04,
+ FLAGS_REPORT_BUSY_LOOP = 0x08,
+ FLAGS_IS_BUSY = 0x10,
+ FLAGS_WAS_BUSY = 0x20
+} thread_flags_t;
+
+typedef enum {
+ CMD_NONE,
+ CMD_TAKE_MUTEX,
+ CMD_RELEASE_MUTEX,
+ CMD_WAIT_FOR_SIGNAL,
+ CMD_BUSY_LOOP,
+ CMD_PROTECTED_OP,
+ CMD_RELEASE_ALL
+} thread_cmd_id_t;
+
+typedef struct {
+ thread_cmd_id_t cmd_id;
+ pthread_mutex_t *mutex;
+ pthread_cond_t *cond;
+} thread_cmd_t;
+
+typedef struct {
+ pthread_cond_t cond_var;
+ thread_status_t status;
+ thread_cmd_t cmd;
+ int flags;
+ int priority;
+ int ret;
+ pthread_t tid;
+ u_int8_t id;
+} thread_state_t;
+
+typedef enum {
+ M_POSIX,
+ M_SS2_DEFAULT,
+ M_SS2_ERRORCHECK,
+ M_SS2_NORMAL,
+ M_SS2_RECURSIVE
+} mutex_kind_t;
+
+
+/*------------------------------------------------------------
+ * Constants
+ *----------------------------------------------------------*/
+
+const char *protocol_strs[] = {
+ "PTHREAD_PRIO_NONE",
+ "PTHREAD_PRIO_INHERIT",
+ "PTHREAD_PRIO_PROTECT"
+};
+
+const int protocols[] = {
+ PTHREAD_PRIO_NONE,
+ PTHREAD_PRIO_INHERIT,
+ PTHREAD_PRIO_PROTECT
+};
+
+const char *mutextype_strs[] = {
+ "POSIX (type not specified)",
+ "SS2 PTHREAD_MUTEX_DEFAULT",
+ "SS2 PTHREAD_MUTEX_ERRORCHECK",
+ "SS2 PTHREAD_MUTEX_NORMAL",
+ "SS2 PTHREAD_MUTEX_RECURSIVE"
+};
+
+const int mutex_types[] = {
+ 0, /* M_POSIX */
+ PTHREAD_MUTEX_DEFAULT, /* M_SS2_DEFAULT */
+ PTHREAD_MUTEX_ERRORCHECK, /* M_SS2_ERRORCHECK */
+ PTHREAD_MUTEX_NORMAL, /* M_SS2_NORMAL */
+ PTHREAD_MUTEX_RECURSIVE /* M_SS2_RECURSIVE */
+};
+
+
+/*------------------------------------------------------------
+ * Objects
+ *----------------------------------------------------------*/
+
+static int done = 0;
+static int trace_enabled = 0;
+static int use_global_condvar = 0;
+static thread_state_t states[NUM_THREADS];
+static int pipefd[2];
+
+static pthread_mutex_t waiter_mutex;
+static pthread_mutex_t cond_mutex;
+static pthread_cond_t cond_var;
+
+static FILE *logfile = stdout;
+static int error_count = 0, pass_count = 0, total = 0;
+
+
+/*------------------------------------------------------------
+ * Prototypes
+ *----------------------------------------------------------*/
+extern char *strtok_r(char *str, const char *sep, char **last);
+
+
+/*------------------------------------------------------------
+ * Functions
+ *----------------------------------------------------------*/
+
+#ifdef DEBUG
+static void
+kern_switch (pthread_t pthread_out, pthread_t pthread_in)
+{
+ if (pthread_out != NULL)
+ printf ("Swapping out thread 0x%x, ", (int) pthread_out);
+ else
+ printf ("Swapping out kernel thread, ");
+
+ if (pthread_in != NULL)
+ printf ("swapping in thread 0x%x\n", (int) pthread_in);
+ else
+ printf ("swapping in kernel thread.\n");
+}
+#endif
+
+
+static void
+log_error (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ fprintf (logfile, "FAIL: ");
+ vfprintf (logfile, fmt, ap);
+ error_count = error_count + 1;
+ total = total + 1;
+}
+
+
+static void
+log_pass (void)
+{
+ fprintf (logfile, "PASS\n");
+ pass_count = pass_count + 1;
+ total = total + 1;
+}
+
+
+static void
+log_trace (const char *fmt, ...)
+{
+ va_list ap;
+
+ if (trace_enabled) {
+ va_start (ap, fmt);
+ vfprintf (logfile, fmt, ap);
+ }
+}
+
+
+static void
+log (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ vfprintf (logfile, fmt, ap);
+}
+
+
+static void
+check_result (int expected, int actual)
+{
+ if (expected != actual)
+ log_error ("expected %d, returned %d\n", expected, actual);
+ else
+ log_pass ();
+}
+
+
+/*
+ * Check to see that the threads ran in the specified order.
+ */
+static void
+check_run_order (char *order)
+{
+ const char *sep = ":,";
+ char *tok, *last, *idstr, *endptr;
+ int expected_id, bytes, count = 0, errors = 0;
+ u_int8_t id;
+
+ assert ((tok = (char *) malloc (strlen(order) + 1)) != NULL);
+ strcpy (tok, order); /* tok has to be larger than order */
+ assert (ioctl (pipefd[0], FIONREAD, &bytes) == 0);
+ log_trace ("%d bytes read from FIFO.\n", bytes);
+
+ for (idstr = strtok_r (tok, sep, &last);
+ (idstr != NULL) && (count < bytes);
+ idstr = strtok_r (NULL, sep, &last)) {
+
+ /* Get the expected id: */
+ expected_id = (int) strtol (idstr, &endptr, 10);
+ assert ((endptr != NULL) && (*endptr == '\0'));
+
+ /* Read the actual id from the pipe: */
+ assert (read (pipefd[0], &id, sizeof (id)) == sizeof (id));
+ count = count + sizeof (id);
+
+ if (id != expected_id) {
+ log_trace ("Thread %d ran out of order.\n", id);
+ errors = errors + 1;
+ }
+ else {
+ log_trace ("Thread %d at priority %d reporting.\n",
+ (int) id, states[id].priority);
+ }
+ }
+
+ if (count < bytes) {
+ /* Clear the pipe: */
+ while (count < bytes) {
+ read (pipefd[0], &id, sizeof (id));
+ count = count + 1;
+ errors = errors + 1;
+ }
+ }
+ else if (bytes < count)
+ errors = errors + count - bytes;
+
+ if (errors == 0)
+ log_pass ();
+ else
+ log_error ("%d threads ran out of order", errors);
+}
+
+
+static void *
+waiter (void *arg)
+{
+ thread_state_t *statep = (thread_state_t *) arg;
+ pthread_mutex_t *held_mutex[MAX_THREAD_CMDS];
+ int held_mutex_owned[MAX_THREAD_CMDS];
+ sigset_t mask;
+ struct timeval tv1, tv2;
+ thread_cmd_t cmd;
+ int i, mutex_count = 0;
+
+ statep->status = STAT_INITIAL;
+
+ /* Block all signals except for interrupt.*/
+ sigfillset (&mask);
+ sigdelset (&mask, SIGINT);
+ sigprocmask (SIG_BLOCK, &mask, NULL);
+
+ while (done == 0) {
+ /* Wait for signal from the main thread to continue. */
+ statep->status = STAT_WAITMUTEX;
+ log_trace ("Thread %d: locking cond_mutex.\n",
+ (int) statep->id);
+ pthread_mutex_lock (&cond_mutex);
+
+ /* Do we report our status. */
+ if (statep->flags & FLAGS_REPORT_WAITCONDMUTEX)
+ write (pipefd[1], &statep->id, sizeof (statep->id));
+ log_trace ("Thread %d: waiting for cond_var.\n",
+ (int) statep->id);
+
+ /* Wait for a command. */
+ statep->status = STAT_WAITCONDVAR;
+
+ /*
+ * The threads are allowed commanded to wait either on
+ * their own unique condition variable (so they may be
+ * separately signaled) or on one global condition variable
+ * (so they may be signaled together).
+ */
+ if (use_global_condvar != 0)
+ pthread_cond_wait (&cond_var, &cond_mutex);
+ else
+ pthread_cond_wait (&statep->cond_var, &cond_mutex);
+
+ /* Do we report our status? */
+ if (statep->flags & FLAGS_REPORT_WAITCONDVAR) {
+ write (pipefd[1], &statep->id, sizeof (statep->id));
+ log_trace ("Thread %d: wrote %d to pipe.\n",
+ (int) statep->id);
+ }
+ log_trace ("Thread %d: received cond_var signal.\n",
+ (int) statep->id);
+
+ /* Get a copy of the command before releasing the mutex. */
+ cmd = statep->cmd;
+
+ /* Clear the command after copying it. */
+ statep->cmd.cmd_id = CMD_NONE;
+
+ /* Unlock the condition variable mutex. */
+ assert (pthread_mutex_unlock (&cond_mutex) == 0);
+
+ /* Peform the command.*/
+ switch (cmd.cmd_id) {
+ case CMD_TAKE_MUTEX:
+ statep->ret = pthread_mutex_lock (cmd.mutex);
+ if (statep->ret == 0) {
+ assert (mutex_count < sizeof (held_mutex));
+ held_mutex[mutex_count] = cmd.mutex;
+ held_mutex_owned[mutex_count] = 1;
+ mutex_count++;
+ }
+ else {
+ held_mutex_owned[mutex_count] = 0;
+ log_trace ("Thread id %d unable to lock mutex, "
+ "error = %d\n", (int) statep->id,
+ statep->ret);
+ }
+ break;
+
+ case CMD_RELEASE_MUTEX:
+ assert ((mutex_count <= sizeof (held_mutex)) &&
+ (mutex_count > 0));
+ mutex_count--;
+ if (held_mutex_owned[mutex_count] != 0)
+ assert (pthread_mutex_unlock
+ (held_mutex[mutex_count]) == 0);
+ break;
+
+ case CMD_WAIT_FOR_SIGNAL:
+ assert (pthread_mutex_lock (cmd.mutex) == 0);
+ assert (pthread_cond_wait (cmd.cond, cmd.mutex) == 0);
+ assert (pthread_mutex_unlock (cmd.mutex) == 0);
+ break;
+
+ case CMD_BUSY_LOOP:
+ log_trace ("Thread %d: Entering busy loop.\n",
+ (int) statep->id);
+ /* Spin for 15 seconds. */
+ assert (gettimeofday (&tv2, NULL) == 0);
+ tv1.tv_sec = tv2.tv_sec + 5;
+ tv1.tv_usec = tv2.tv_usec;
+ statep->flags |= FLAGS_IS_BUSY;
+ while (timercmp (&tv2, &tv1,<)) {
+ assert (gettimeofday (&tv2, NULL) == 0);
+ }
+ statep->flags &= ~FLAGS_IS_BUSY;
+ statep->flags |= FLAGS_WAS_BUSY;
+
+ /* Do we report our status? */
+ if (statep->flags & FLAGS_REPORT_BUSY_LOOP)
+ write (pipefd[1], &statep->id,
+ sizeof (statep->id));
+
+ log_trace ("Thread %d: Leaving busy loop.\n",
+ (int) statep->id);
+ break;
+
+ case CMD_PROTECTED_OP:
+ assert (pthread_mutex_lock (cmd.mutex) == 0);
+ statep->flags |= FLAGS_WAS_BUSY;
+ /* Do we report our status? */
+ if (statep->flags & FLAGS_REPORT_BUSY_LOOP)
+ write (pipefd[1], &statep->id,
+ sizeof (statep->id));
+
+ assert (pthread_mutex_unlock (cmd.mutex) == 0);
+ break;
+
+ case CMD_RELEASE_ALL:
+ assert ((mutex_count <= sizeof (held_mutex)) &&
+ (mutex_count > 0));
+ for (i = mutex_count - 1; i >= 0; i--) {
+ if (held_mutex_owned[i] != 0)
+ assert (pthread_mutex_unlock
+ (held_mutex[i]) == 0);
+ }
+ mutex_count = 0;
+ break;
+
+ case CMD_NONE:
+ default:
+ break;
+ }
+
+ /* Wait for the big giant waiter lock. */
+ statep->status = STAT_WAITMUTEX;
+ log_trace ("Thread %d: waiting for big giant lock.\n",
+ (int) statep->id);
+ pthread_mutex_lock (&waiter_mutex);
+ if (statep->flags & FLAGS_REPORT_WAITMUTEX)
+ write (pipefd[1], &statep->id, sizeof (statep->id));
+ log_trace ("Thread %d: got big giant lock.\n",
+ (int) statep->id);
+ statep->status = STAT_INITIAL;
+ pthread_mutex_unlock (&waiter_mutex);
+ }
+
+ log_trace ("Thread %d: Exiting thread 0x%x\n", (int) statep->id,
+ (int) pthread_self());
+ pthread_exit (arg);
+ return (NULL);
+}
+
+
+static void *
+lock_twice (void *arg)
+{
+ thread_state_t *statep = (thread_state_t *) arg;
+ sigset_t mask;
+
+ statep->status = STAT_INITIAL;
+
+ /* Block all signals except for interrupt.*/
+ sigfillset (&mask);
+ sigdelset (&mask, SIGINT);
+ sigprocmask (SIG_BLOCK, &mask, NULL);
+
+ /* Wait for a signal to continue. */
+ log_trace ("Thread %d: locking cond_mutex.\n", (int) statep->id);
+ pthread_mutex_lock (&cond_mutex);
+
+ log_trace ("Thread %d: waiting for cond_var.\n", (int) statep->id);
+ statep->status = STAT_WAITCONDVAR;
+ pthread_cond_wait (&cond_var, &cond_mutex);
+
+ log_trace ("Thread %d: received cond_var signal.\n", (int) statep->id);
+
+ /* Unlock the condition variable mutex. */
+ assert (pthread_mutex_unlock (&cond_mutex) == 0);
+
+ statep->status = STAT_WAITMUTEX;
+ /* Lock the mutex once. */
+ assert (pthread_mutex_lock (statep->cmd.mutex) == 0);
+
+ /* Lock it again and capture the error. */
+ statep->ret = pthread_mutex_lock (statep->cmd.mutex);
+ statep->status = 0;
+
+ assert (pthread_mutex_unlock (statep->cmd.mutex) == 0);
+
+ /* Unlock it again if it is locked recursively. */
+ if (statep->ret == 0)
+ pthread_mutex_unlock (statep->cmd.mutex);
+
+ log_trace ("Thread %d: Exiting thread 0x%x\n", (int) statep->id,
+ (int) pthread_self());
+ pthread_exit (arg);
+ return (NULL);
+}
+
+
+static void
+sighandler (int signo)
+{
+ log ("Signal handler caught signal %d, thread id 0x%x\n",
+ signo, (int) pthread_self());
+
+ if (signo == SIGINT)
+ done = 1;
+}
+
+
+static void
+send_cmd (int id, thread_cmd_id_t cmd)
+{
+ assert (pthread_mutex_lock (&cond_mutex) == 0);
+ assert (states[id].status == STAT_WAITCONDVAR);
+ states[id].cmd.cmd_id = cmd;
+ states[id].cmd.mutex = NULL;
+ states[id].cmd.cond = NULL;
+ /* Clear the busy flags. */
+ states[id].flags &= ~(FLAGS_WAS_BUSY | FLAGS_IS_BUSY);
+ assert (pthread_cond_signal (&states[id].cond_var) == 0);
+ assert (pthread_mutex_unlock (&cond_mutex) == 0);
+}
+
+
+static void
+send_mutex_cmd (int id, thread_cmd_id_t cmd, pthread_mutex_t *m)
+{
+ assert (pthread_mutex_lock (&cond_mutex) == 0);
+ assert (states[id].status == STAT_WAITCONDVAR);
+ states[id].cmd.cmd_id = cmd;
+ states[id].cmd.mutex = m;
+ states[id].cmd.cond = NULL;
+ /* Clear the busy flags. */
+ states[id].flags &= ~(FLAGS_WAS_BUSY | FLAGS_IS_BUSY);
+ assert (pthread_cond_signal (&states[id].cond_var) == 0);
+ assert (pthread_mutex_unlock (&cond_mutex) == 0);
+}
+
+
+static void
+send_mutex_cv_cmd (int id, thread_cmd_id_t cmd, pthread_mutex_t *m,
+ pthread_cond_t *cv)
+{
+ assert (pthread_mutex_lock (&cond_mutex) == 0);
+ assert (states[id].status == STAT_WAITCONDVAR);
+ states[id].cmd.cmd_id = cmd;
+ states[id].cmd.mutex = m;
+ states[id].cmd.cond = cv;
+ /* Clear the busy flags. */
+ states[id].flags &= ~(FLAGS_WAS_BUSY | FLAGS_IS_BUSY);
+ assert (pthread_cond_signal (&states[id].cond_var) == 0);
+ assert (pthread_mutex_unlock (&cond_mutex) == 0);
+}
+
+
+static void
+mutex_init_test (void)
+{
+ pthread_mutexattr_t mattr;
+ pthread_mutex_t mutex;
+ mutex_kind_t mkind;
+ int mproto, ret;
+
+ /*
+ * Initialize a mutex attribute.
+ *
+ * pthread_mutexattr_init not tested for: ENOMEM
+ */
+ assert (pthread_mutexattr_init (&mattr) == 0);
+
+ /*
+ * Initialize a mutex.
+ *
+ * pthread_mutex_init not tested for: EAGAIN ENOMEM EPERM EBUSY
+ */
+ log ("Testing pthread_mutex_init\n");
+ log ("--------------------------\n");
+
+ for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) {
+ for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) {
+ /* Initialize the mutex attribute. */
+ assert (pthread_mutexattr_init (&mattr) == 0);
+ assert (pthread_mutexattr_setprotocol (&mattr,
+ protocols[mproto]) == 0);
+
+ /*
+ * Ensure that the first mutex type is a POSIX
+ * compliant mutex.
+ */
+ if (mkind != M_POSIX) {
+ assert (pthread_mutexattr_settype (&mattr,
+ mutex_types[mkind]) == 0);
+ }
+
+ log (" Protocol %s, Type %s - ",
+ protocol_strs[mproto], mutextype_strs[mkind]);
+ ret = pthread_mutex_init (&mutex, &mattr);
+ check_result (/* expected */ 0, ret);
+ assert (pthread_mutex_destroy (&mutex) == 0);
+
+ /*
+ * Destroy a mutex attribute.
+ *
+ * XXX - There should probably be a magic number
+ * associated with a mutex attribute so that
+ * destroy can be reasonably sure the attribute
+ * is valid.
+ *
+ * pthread_mutexattr_destroy not tested for: EINVAL
+ */
+ assert (pthread_mutexattr_destroy (&mattr) == 0);
+ }
+ }
+}
+
+
+static void
+mutex_destroy_test (void)
+{
+ pthread_mutexattr_t mattr;
+ pthread_mutex_t mutex;
+ pthread_condattr_t cattr;
+ pthread_cond_t cv;
+ pthread_attr_t pattr;
+ int mproto, ret;
+ mutex_kind_t mkind;
+ thread_state_t state;
+
+ /*
+ * Destroy a mutex.
+ *
+ * XXX - There should probably be a magic number associated
+ * with a mutex so that destroy can be reasonably sure
+ * the mutex is valid.
+ *
+ * pthread_mutex_destroy not tested for:
+ */
+ log ("Testing pthread_mutex_destroy\n");
+ log ("-----------------------------\n");
+
+ assert (pthread_attr_init (&pattr) == 0);
+ assert (pthread_attr_setdetachstate (&pattr,
+ PTHREAD_CREATE_DETACHED) == 0);
+ state.flags = 0; /* No flags yet. */
+
+ for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) {
+ for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) {
+ /* Initialize the mutex attribute. */
+ assert (pthread_mutexattr_init (&mattr) == 0);
+ assert (pthread_mutexattr_setprotocol (&mattr,
+ protocols[mproto]) == 0);
+
+ /*
+ * Ensure that the first mutex type is a POSIX
+ * compliant mutex.
+ */
+ if (mkind != M_POSIX) {
+ assert (pthread_mutexattr_settype (&mattr,
+ mutex_types[mkind]) == 0);
+ }
+
+ /* Create the mutex. */
+ assert (pthread_mutex_init (&mutex, &mattr) == 0);
+
+ log (" Protocol %s, Type %s\n",
+ protocol_strs[mproto], mutextype_strs[mkind]);
+
+ log (" Destruction of unused mutex - ");
+ assert (pthread_mutex_init (&mutex, &mattr) == 0);
+ ret = pthread_mutex_destroy (&mutex);
+ check_result (/* expected */ 0, ret);
+
+ log (" Destruction of mutex locked by self - ");
+ assert (pthread_mutex_init (&mutex, &mattr) == 0);
+ assert (pthread_mutex_lock (&mutex) == 0);
+ ret = pthread_mutex_destroy (&mutex);
+ check_result (/* expected */ EBUSY, ret);
+ assert (pthread_mutex_unlock (&mutex) == 0);
+ assert (pthread_mutex_destroy (&mutex) == 0);
+
+ log (" Destruction of mutex locked by another "
+ "thread - ");
+ assert (pthread_mutex_init (&mutex, &mattr) == 0);
+ send_mutex_cmd (0, CMD_TAKE_MUTEX, &mutex);
+ sleep (1);
+ ret = pthread_mutex_destroy (&mutex);
+ check_result (/* expected */ EBUSY, ret);
+ send_cmd (0, CMD_RELEASE_ALL);
+ sleep (1);
+ assert (pthread_mutex_destroy (&mutex) == 0);
+
+ log (" Destruction of mutex while being used in "
+ "cond_wait - ");
+ assert (pthread_mutex_init (&mutex, &mattr) == 0);
+ assert (pthread_condattr_init (&cattr) == 0);
+ assert (pthread_cond_init (&cv, &cattr) == 0);
+ send_mutex_cv_cmd (0, CMD_WAIT_FOR_SIGNAL, &mutex, &cv);
+ sleep (1);
+ ret = pthread_mutex_destroy (&mutex);
+ check_result (/* expected */ EBUSY, ret);
+ pthread_cond_signal (&cv);
+ sleep (1);
+ assert (pthread_mutex_destroy (&mutex) == 0);
+ }
+ }
+}
+
+
+static void
+mutex_lock_test (void)
+{
+ pthread_mutexattr_t mattr;
+ pthread_mutex_t mutex;
+ pthread_attr_t pattr;
+ int mproto, ret;
+ mutex_kind_t mkind;
+ thread_state_t state;
+
+ /*
+ * Lock a mutex.
+ *
+ * pthread_lock not tested for:
+ */
+ log ("Testing pthread_mutex_lock\n");
+ log ("--------------------------\n");
+
+ assert (pthread_attr_init (&pattr) == 0);
+ assert (pthread_attr_setdetachstate (&pattr,
+ PTHREAD_CREATE_DETACHED) == 0);
+ state.flags = 0; /* No flags yet. */
+
+ for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) {
+ for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) {
+ /* Initialize the mutex attribute. */
+ assert (pthread_mutexattr_init (&mattr) == 0);
+ assert (pthread_mutexattr_setprotocol (&mattr,
+ protocols[mproto]) == 0);
+
+ /*
+ * Ensure that the first mutex type is a POSIX
+ * compliant mutex.
+ */
+ if (mkind != M_POSIX) {
+ assert (pthread_mutexattr_settype (&mattr,
+ mutex_types[mkind]) == 0);
+ }
+
+ /* Create the mutex. */
+ assert (pthread_mutex_init (&mutex, &mattr) == 0);
+
+ log (" Protocol %s, Type %s\n",
+ protocol_strs[mproto], mutextype_strs[mkind]);
+
+ log (" Lock on unlocked mutex - ");
+ ret = pthread_mutex_lock (&mutex);
+ check_result (/* expected */ 0, ret);
+ pthread_mutex_unlock (&mutex);
+
+ log (" Lock on invalid mutex - ");
+ ret = pthread_mutex_lock (NULL);
+ check_result (/* expected */ EINVAL, ret);
+
+ log (" Lock on mutex held by self - ");
+ assert (pthread_create (&state.tid, &pattr, lock_twice,
+ (void *) &state) == 0);
+ /* Let the thread start. */
+ sleep (1);
+ state.cmd.mutex = &mutex;
+ state.ret = 0xdeadbeef;
+ assert (pthread_mutex_lock (&cond_mutex) == 0);
+ assert (pthread_cond_signal (&cond_var) == 0);
+ assert (pthread_mutex_unlock (&cond_mutex) == 0);
+ /* Let the thread receive and process the command. */
+ sleep (1);
+
+ switch (mkind) {
+ case M_POSIX:
+ check_result (/* expected */ EDEADLK,
+ state.ret);
+ break;
+ case M_SS2_DEFAULT:
+ check_result (/* expected */ EDEADLK,
+ state.ret);
+ break;
+ case M_SS2_ERRORCHECK:
+ check_result (/* expected */ EDEADLK,
+ state.ret);
+ break;
+ case M_SS2_NORMAL:
+ check_result (/* expected */ 0xdeadbeef,
+ state.ret);
+ break;
+ case M_SS2_RECURSIVE:
+ check_result (/* expected */ 0, state.ret);
+ break;
+ }
+ pthread_mutex_destroy (&mutex);
+ pthread_mutexattr_destroy (&mattr);
+ }
+ }
+}
+
+
+static void
+mutex_unlock_test (void)
+{
+ const int test_thread_id = 0; /* ID of test thread */
+ pthread_mutexattr_t mattr;
+ pthread_mutex_t mutex;
+ int mproto, ret;
+ mutex_kind_t mkind;
+
+ /*
+ * Unlock a mutex.
+ *
+ * pthread_unlock not tested for:
+ */
+ log ("Testing pthread_mutex_unlock\n");
+ log ("----------------------------\n");
+
+ for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) {
+ for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) {
+ /* Initialize the mutex attribute. */
+ assert (pthread_mutexattr_init (&mattr) == 0);
+ assert (pthread_mutexattr_setprotocol (&mattr,
+ protocols[mproto]) == 0);
+
+ /*
+ * Ensure that the first mutex type is a POSIX
+ * compliant mutex.
+ */
+ if (mkind != M_POSIX) {
+ assert (pthread_mutexattr_settype (&mattr,
+ mutex_types[mkind]) == 0);
+ }
+
+ /* Create the mutex. */
+ assert (pthread_mutex_init (&mutex, &mattr) == 0);
+
+ log (" Protocol %s, Type %s\n",
+ protocol_strs[mproto], mutextype_strs[mkind]);
+
+ log (" Unlock on mutex held by self - ");
+ assert (pthread_mutex_lock (&mutex) == 0);
+ ret = pthread_mutex_unlock (&mutex);
+ check_result (/* expected */ 0, ret);
+
+ log (" Unlock on invalid mutex - ");
+ ret = pthread_mutex_unlock (NULL);
+ check_result (/* expected */ EINVAL, ret);
+
+ log (" Unlock on mutex locked by another thread - ");
+ send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &mutex);
+ sleep (1);
+ ret = pthread_mutex_unlock (&mutex);
+ switch (mkind) {
+ case M_POSIX:
+ check_result (/* expected */ EPERM, ret);
+ break;
+ case M_SS2_DEFAULT:
+ check_result (/* expected */ EPERM, ret);
+ break;
+ case M_SS2_ERRORCHECK:
+ check_result (/* expected */ EPERM, ret);
+ break;
+ case M_SS2_NORMAL:
+ check_result (/* expected */ EPERM, ret);
+ break;
+ case M_SS2_RECURSIVE:
+ check_result (/* expected */ EPERM, ret);
+ break;
+ }
+ if (ret == 0) {
+ /*
+ * If for some reason we were able to unlock
+ * the mutex, relock it so that the test
+ * thread has no problems releasing the mutex.
+ */
+ pthread_mutex_lock (&mutex);
+ }
+ send_cmd (test_thread_id, CMD_RELEASE_ALL);
+ sleep (1);
+
+ pthread_mutex_destroy (&mutex);
+ pthread_mutexattr_destroy (&mattr);
+ }
+ }
+}
+
+
+static void
+queueing_order_test (void)
+{
+ int i;
+
+ log ("Testing queueing order\n");
+ log ("----------------------\n");
+ assert (pthread_mutex_lock (&waiter_mutex) == 0);
+ /*
+ * Tell the threads to report when they take the waiters mutex.
+ */
+ assert (pthread_mutex_lock (&cond_mutex) == 0);
+ for (i = 0; i < NUM_THREADS; i++) {
+ states[i].flags = FLAGS_REPORT_WAITMUTEX;
+ assert (pthread_cond_signal (&states[i].cond_var) == 0);
+ }
+ assert (pthread_mutex_unlock (&cond_mutex) == 0);
+
+ /* Signal the threads to continue. */
+ sleep (1);
+
+ /* Use the global condition variable next time. */
+ use_global_condvar = 1;
+
+ /* Release the waiting threads and allow them to run again. */
+ assert (pthread_mutex_unlock (&waiter_mutex) == 0);
+ sleep (1);
+
+ log (" Queueing order on a mutex - ");
+ check_run_order ("9,8,7,6,5,4,3,2,1,0");
+ for (i = 0; i < NUM_THREADS; i = i + 1) {
+ /* Tell the threads to report when they've been signaled. */
+ states[i].flags = FLAGS_REPORT_WAITCONDVAR;
+ }
+
+ /*
+ * Prevent the threads from continuing their loop after we
+ * signal them.
+ */
+ assert (pthread_mutex_lock (&waiter_mutex) == 0);
+
+
+ log (" Queueing order on a condition variable - ");
+ /*
+ * Signal one thread to run and see that the highest priority
+ * thread executes.
+ */
+ assert (pthread_mutex_lock (&cond_mutex) == 0);
+ assert (pthread_cond_signal (&cond_var) == 0);
+ assert (pthread_mutex_unlock (&cond_mutex) == 0);
+ sleep (1);
+ if (states[NUM_THREADS - 1].status != STAT_WAITMUTEX)
+ log_error ("highest priority thread does not run.\n");
+
+ /* Signal the remaining threads. */
+ assert (pthread_mutex_lock (&cond_mutex) == 0);
+ assert (pthread_cond_broadcast (&cond_var) == 0);
+ assert (pthread_mutex_unlock (&cond_mutex) == 0);
+ sleep (1);
+
+ check_run_order ("9,8,7,6,5,4,3,2,1,0");
+ for (i = 0; i < NUM_THREADS; i = i + 1) {
+ /* Tell the threads not to report anything. */
+ states[i].flags = 0;
+ }
+
+ /* Use the thread unique condition variable next time. */
+ use_global_condvar = 0;
+
+ /* Allow the threads to continue their loop. */
+ assert (pthread_mutex_unlock (&waiter_mutex) == 0);
+ sleep (1);
+}
+
+
+static void
+mutex_prioceiling_test (void)
+{
+ const int test_thread_id = 0; /* ID of test thread */
+ pthread_mutexattr_t mattr;
+ struct sched_param param;
+ pthread_mutex_t m[3];
+ mutex_kind_t mkind;
+ int i, ret, policy, my_prio, old_ceiling;
+
+ log ("Testing priority ceilings\n");
+ log ("-------------------------\n");
+ for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) {
+
+ log (" Protype PTHREAD_PRIO_PROTECT, Type %s\n",
+ mutextype_strs[mkind]);
+
+ /*
+ * Initialize and create a mutex.
+ */
+ assert (pthread_mutexattr_init (&mattr) == 0);
+
+ /* Get this threads current priority. */
+ assert (pthread_getschedparam (pthread_self(), &policy,
+ &param) == 0);
+ my_prio = param.sched_priority; /* save for later use */
+ log_trace ("Current scheduling policy %d, priority %d\n",
+ policy, my_prio);
+
+ /*
+ * Initialize and create 3 priority protection mutexes with
+ * default (max priority) ceilings.
+ */
+ assert (pthread_mutexattr_setprotocol(&mattr,
+ PTHREAD_PRIO_PROTECT) == 0);
+
+ /*
+ * Ensure that the first mutex type is a POSIX
+ * compliant mutex.
+ */
+ if (mkind != M_POSIX) {
+ assert (pthread_mutexattr_settype (&mattr,
+ mutex_types[mkind]) == 0);
+ }
+
+ for (i = 0; i < 3; i++)
+ assert (pthread_mutex_init (&m[i], &mattr) == 0);
+
+ /*
+ * Set the ceiling priorities for the 3 priority protection
+ * mutexes to, 5 less than, equal to, and 5 greater than,
+ * this threads current priority.
+ */
+ for (i = 0; i < 3; i++)
+ assert (pthread_mutex_setprioceiling (&m[i],
+ my_prio - 5 + 5*i, &old_ceiling) == 0);
+
+ /*
+ * Check that if we attempt to take a mutex whose priority
+ * ceiling is lower than our priority, we get an error.
+ */
+ log (" Lock with ceiling priority < thread priority - ");
+ ret = pthread_mutex_lock (&m[0]);
+ check_result (/* expected */ EINVAL, ret);
+ if (ret == 0)
+ pthread_mutex_unlock (&m[0]);
+
+ /*
+ * Check that we can take a mutex whose priority ceiling
+ * is equal to our priority.
+ */
+ log (" Lock with ceiling priority = thread priority - ");
+ ret = pthread_mutex_lock (&m[1]);
+ check_result (/* expected */ 0, ret);
+ if (ret == 0)
+ pthread_mutex_unlock (&m[1]);
+
+ /*
+ * Check that we can take a mutex whose priority ceiling
+ * is higher than our priority.
+ */
+ log (" Lock with ceiling priority > thread priority - ");
+ ret = pthread_mutex_lock (&m[2]);
+ check_result (/* expected */ 0, ret);
+ if (ret == 0)
+ pthread_mutex_unlock (&m[2]);
+
+ /*
+ * Have the test thread go into a busy loop for 5 seconds
+ * and see that it doesn't block this thread (since the
+ * priority ceiling of mutex 0 and the priority of the test
+ * thread are both less than the priority of this thread).
+ */
+ log (" Preemption with ceiling priority < thread "
+ "priority - ");
+ /* Have the test thread take mutex 0. */
+ send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[0]);
+ sleep (1);
+
+ log_trace ("Sending busy command.\n");
+ send_cmd (test_thread_id, CMD_BUSY_LOOP);
+ log_trace ("Busy sent, yielding\n");
+ pthread_yield ();
+ log_trace ("Returned from yield.\n");
+ if (states[test_thread_id].flags &
+ (FLAGS_IS_BUSY | FLAGS_WAS_BUSY))
+ log_error ("test thread inproperly preempted us.\n");
+ else {
+ /* Let the thread finish its busy loop. */
+ sleep (6);
+ if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0)
+ log_error ("test thread never finished.\n");
+ else
+ log_pass ();
+ }
+ states[test_thread_id].flags &= ~FLAGS_WAS_BUSY;
+
+ /* Have the test thread release mutex 0. */
+ send_cmd (test_thread_id, CMD_RELEASE_ALL);
+ sleep (1);
+
+ /*
+ * Have the test thread go into a busy loop for 5 seconds
+ * and see that it preempts this thread (since the priority
+ * ceiling of mutex 1 is the same as the priority of this
+ * thread). The test thread should not run to completion
+ * as its time quantum should expire before the 5 seconds
+ * are up.
+ */
+ log (" Preemption with ceiling priority = thread "
+ "priority - ");
+
+ /* Have the test thread take mutex 1. */
+ send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[1]);
+ sleep (1);
+
+ log_trace ("Sending busy\n");
+ send_cmd (test_thread_id, CMD_BUSY_LOOP);
+ log_trace ("Busy sent, yielding\n");
+ pthread_yield ();
+ log_trace ("Returned from yield.\n");
+ if ((states[test_thread_id].flags & FLAGS_IS_BUSY) == 0)
+ log_error ("test thread did not switch in on yield.\n");
+ else if (states[test_thread_id].flags & FLAGS_WAS_BUSY)
+ log_error ("test thread ran to completion.\n");
+ else {
+ /* Let the thread finish its busy loop. */
+ sleep (6);
+ if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0)
+ log_error ("test thread never finished.\n");
+ else
+ log_pass ();
+ }
+ states[test_thread_id].flags &= ~FLAGS_WAS_BUSY;
+
+ /* Have the test thread release mutex 1. */
+ send_cmd (test_thread_id, CMD_RELEASE_ALL);
+ sleep (1);
+
+ /*
+ * Set the scheduling policy of the test thread to SCHED_FIFO
+ * and have it go into a busy loop for 5 seconds. This
+ * thread is SCHED_RR, and since the priority ceiling of
+ * mutex 1 is the same as the priority of this thread, the
+ * test thread should run to completion once it is switched
+ * in.
+ */
+ log (" SCHED_FIFO scheduling and ceiling priority = "
+ "thread priority - ");
+ param.sched_priority = states[test_thread_id].priority;
+ assert (pthread_setschedparam (states[test_thread_id].tid,
+ SCHED_FIFO, &param) == 0);
+
+ /* Have the test thread take mutex 1. */
+ send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[1]);
+ sleep (1);
+
+ log_trace ("Sending busy\n");
+ send_cmd (test_thread_id, CMD_BUSY_LOOP);
+ log_trace ("Busy sent, yielding\n");
+ pthread_yield ();
+ log_trace ("Returned from yield.\n");
+ if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) {
+ log_error ("test thread did not run to completion.\n");
+ /* Let the thread finish it's busy loop. */
+ sleep (6);
+ }
+ else
+ log_pass ();
+ states[test_thread_id].flags &= ~FLAGS_WAS_BUSY;
+
+ /* Restore the test thread scheduling parameters. */
+ param.sched_priority = states[test_thread_id].priority;
+ assert (pthread_setschedparam (states[test_thread_id].tid,
+ SCHED_RR, &param) == 0);
+
+ /* Have the test thread release mutex 1. */
+ send_cmd (test_thread_id, CMD_RELEASE_ALL);
+ sleep (1);
+
+ /*
+ * Have the test thread go into a busy loop for 5 seconds
+ * and see that it preempts this thread (since the priority
+ * ceiling of mutex 2 is the greater than the priority of
+ * this thread). The test thread should run to completion
+ * and block this thread because its active priority is
+ * higher.
+ */
+ log (" SCHED_FIFO scheduling and ceiling priority > "
+ "thread priority - ");
+ /* Have the test thread take mutex 2. */
+ send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[2]);
+ sleep (1);
+
+ log_trace ("Sending busy\n");
+ send_cmd (test_thread_id, CMD_BUSY_LOOP);
+ log_trace ("Busy sent, yielding\n");
+ pthread_yield ();
+ log_trace ("Returned from yield.\n");
+ if ((states[test_thread_id].flags & FLAGS_IS_BUSY) != 0) {
+ log_error ("test thread did not run to completion.\n");
+ /* Let the thread finish it's busy loop. */
+ sleep (6);
+ }
+ else if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0)
+ log_error ("test thread never finished.\n");
+ else
+ log_pass ();
+ states[test_thread_id].flags &= ~FLAGS_WAS_BUSY;
+
+ /* Have the test thread release mutex 2. */
+ send_cmd (test_thread_id, CMD_RELEASE_ALL);
+ sleep (1);
+
+ /* Destroy the mutexes. */
+ for (i = 0; i < 3; i++)
+ assert (pthread_mutex_destroy (&m[i]) == 0);
+ }
+}
+
+
+static void
+mutex_prioinherit_test (void)
+{
+ pthread_mutexattr_t mattr;
+ struct sched_param param;
+ pthread_mutex_t m[3];
+ mutex_kind_t mkind;
+ int i, policy, my_prio;
+
+ /* Get this threads current priority. */
+ assert (pthread_getschedparam (pthread_self(), &policy,
+ &param) == 0);
+ my_prio = param.sched_priority; /* save for later use */
+ log_trace ("Current scheduling policy %d, priority %d\n",
+ policy, my_prio);
+
+ log ("Testing priority inheritence\n");
+ log ("----------------------------\n");
+ for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) {
+
+ log (" Protype PTHREAD_PRIO_INHERIT, Type %s\n",
+ mutextype_strs[mkind]);
+
+ /*
+ * Initialize and create a mutex.
+ */
+ assert (pthread_mutexattr_init (&mattr) == 0);
+
+ /*
+ * Initialize and create 3 priority inheritence mutexes with
+ * default (max priority) ceilings.
+ */
+ assert (pthread_mutexattr_setprotocol(&mattr,
+ PTHREAD_PRIO_INHERIT) == 0);
+
+ /*
+ * Ensure that the first mutex type is a POSIX
+ * compliant mutex.
+ */
+ if (mkind != M_POSIX) {
+ assert (pthread_mutexattr_settype (&mattr,
+ mutex_types[mkind]) == 0);
+ }
+
+ for (i = 0; i < 3; i++)
+ assert (pthread_mutex_init (&m[i], &mattr) == 0);
+
+ /*
+ * Test setup:
+ * Thread 4 - take mutex 0, 1
+ * Thread 2 - enter protected busy loop with mutex 0
+ * Thread 3 - enter protected busy loop with mutex 1
+ * Thread 4 - enter protected busy loop with mutex 2
+ * Thread 5 - enter busy loop
+ * Thread 6 - enter protected busy loop with mutex 0
+ * Thread 4 - releases mutexes 1 and 0.
+ *
+ * Expected results:
+ * Threads complete in order 4, 6, 5, 3, 2
+ */
+ log (" Simple inheritence test - ");
+
+ /*
+ * Command thread 4 to take mutexes 0 and 1.
+ */
+ send_mutex_cmd (4, CMD_TAKE_MUTEX, &m[0]);
+ sleep (1); /* Allow command to be received. */
+ send_mutex_cmd (4, CMD_TAKE_MUTEX, &m[1]);
+ sleep (1);
+
+ /*
+ * Tell the threads to report themselves when they are
+ * at the bottom of their loop (waiting on wait_mutex).
+ */
+ for (i = 0; i < NUM_THREADS; i++)
+ states[i].flags |= FLAGS_REPORT_WAITMUTEX;
+
+ /*
+ * Command thread 2 to take mutex 0 and thread 3 to take
+ * mutex 1, both via a protected operation command. Since
+ * thread 4 owns mutexes 0 and 1, both threads 2 and 3
+ * will block until the mutexes are released by thread 4.
+ */
+ log_trace ("Commanding protected operation to thread 2.\n");
+ send_mutex_cmd (2, CMD_PROTECTED_OP, &m[0]);
+ log_trace ("Commanding protected operation to thread 3.\n");
+ send_mutex_cmd (3, CMD_PROTECTED_OP, &m[1]);
+ sleep (1);
+
+ /*
+ * Command thread 4 to take mutex 2 via a protected operation
+ * and thread 5 to enter a busy loop for 5 seconds. Since
+ * thread 5 has higher priority than thread 4, thread 5 will
+ * enter the busy loop before thread 4 is activated.
+ */
+ log_trace ("Commanding protected operation to thread 4.\n");
+ send_mutex_cmd (4, CMD_PROTECTED_OP, &m[2]);
+ log_trace ("Commanding busy loop to thread 5.\n");
+ send_cmd (5, CMD_BUSY_LOOP);
+ sleep (1);
+ if ((states[5].flags & FLAGS_IS_BUSY) == 0)
+ log_error ("thread 5 is not running.\n");
+ log_trace ("Commanding protected operation thread 6.\n");
+ send_mutex_cmd (6, CMD_PROTECTED_OP, &m[0]);
+ sleep (1);
+ if ((states[4].flags & FLAGS_WAS_BUSY) == 0)
+ log_error ("thread 4 failed to inherit priority.\n");
+ states[4].flags = 0;
+ send_cmd (4, CMD_RELEASE_ALL);
+ sleep (5);
+ check_run_order ("4,6,5,3,2");
+
+ /*
+ * Clear the flags.
+ */
+ for (i = 0; i < NUM_THREADS; i++)
+ states[i].flags = 0;
+
+ /*
+ * Test setup:
+ * Thread 2 - enter busy loop (SCHED_FIFO)
+ * Thread 4 - take mutex 0
+ * Thread 4 - priority change to same priority as thread 2
+ * Thread 4 - release mutex 0
+ *
+ * Expected results:
+ * Since thread 4 owns a priority mutex, it should be
+ * placed at the front of the run queue (for its new
+ * priority slot) when its priority is lowered to the
+ * same priority as thread 2. If thread 4 did not own
+ * a priority mutex, then it would have been added to
+ * the end of the run queue and thread 2 would have
+ * executed until it blocked (because it's scheduling
+ * policy is SCHED_FIFO).
+ *
+ */
+ log (" Inheritence test with change of priority - ");
+
+ /*
+ * Change threads 2 and 4 scheduling policies to be
+ * SCHED_FIFO.
+ */
+ param.sched_priority = states[2].priority;
+ assert (pthread_setschedparam (states[2].tid, SCHED_FIFO,
+ &param) == 0);
+ param.sched_priority = states[4].priority;
+ assert (pthread_setschedparam (states[4].tid, SCHED_FIFO,
+ &param) == 0);
+
+ /*
+ * Command thread 4 to take mutex 0.
+ */
+ send_mutex_cmd (4, CMD_TAKE_MUTEX, &m[0]);
+ sleep (1);
+
+ /*
+ * Command thread 2 to enter busy loop.
+ */
+ send_cmd (2, CMD_BUSY_LOOP);
+ sleep (1); /* Allow command to be received. */
+
+ /*
+ * Command thread 4 to enter busy loop.
+ */
+ send_cmd (4, CMD_BUSY_LOOP);
+ sleep (1); /* Allow command to be received. */
+
+ /* Have threads 2 and 4 report themselves. */
+ states[2].flags = FLAGS_REPORT_WAITMUTEX;
+ states[4].flags = FLAGS_REPORT_WAITMUTEX;
+
+ /* Change the priority of thread 4. */
+ param.sched_priority = states[2].priority;
+ assert (pthread_setschedparam (states[4].tid, SCHED_FIFO,
+ &param) == 0);
+ sleep (5);
+ check_run_order ("4,2");
+
+ /* Clear the flags */
+ states[2].flags = 0;
+ states[4].flags = 0;
+
+ /* Reset the policies. */
+ param.sched_priority = states[2].priority;
+ assert (pthread_setschedparam (states[2].tid, SCHED_RR,
+ &param) == 0);
+ param.sched_priority = states[4].priority;
+ assert (pthread_setschedparam (states[4].tid, SCHED_RR,
+ &param) == 0);
+
+ send_cmd (4, CMD_RELEASE_MUTEX);
+ sleep (1);
+
+ /* Destroy the mutexes. */
+ for (i = 0; i < 3; i++)
+ assert (pthread_mutex_destroy (&m[i]) == 0);
+ }
+}
+
+
+int main (int argc, char *argv[])
+{
+ pthread_mutexattr_t mattr;
+ pthread_condattr_t cattr;
+ pthread_attr_t pattr;
+ int i, policy, main_prio;
+ void * exit_status;
+ sigset_t mask;
+ struct sigaction act;
+ struct sched_param param;
+
+ assert (pthread_getschedparam (pthread_self (), &policy, &param) == 0);
+ main_prio = param.sched_priority;
+
+ /* Setupt our signal mask. */
+ sigfillset (&mask);
+ sigdelset (&mask, SIGINT);
+ sigprocmask (SIG_SETMASK, &mask, NULL);
+
+ /* Install a signal handler for SIGINT */
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGINT);
+ act.sa_handler = sighandler;
+ act.sa_flags = SA_RESTART;
+ sigaction (SIGINT, &act, NULL);
+
+ /*
+ * Initialize the thread attribute.
+ */
+ assert (pthread_attr_init (&pattr) == 0);
+ assert (pthread_attr_setdetachstate (&pattr,
+ PTHREAD_CREATE_JOINABLE) == 0);
+
+ /*
+ * Initialize and create the waiter and condvar mutexes.
+ */
+ assert (pthread_mutexattr_init (&mattr) == 0);
+ assert (pthread_mutex_init (&waiter_mutex, &mattr) == 0);
+ assert (pthread_mutex_init (&cond_mutex, &mattr) == 0);
+
+ /*
+ * Initialize and create a condition variable.
+ */
+ assert (pthread_condattr_init (&cattr) == 0);
+ assert (pthread_cond_init (&cond_var, &cattr) == 0);
+
+ /* Create a pipe to catch the results of thread wakeups. */
+ assert (pipe (pipefd) == 0);
+
+#ifdef DEBUG
+ assert (pthread_switch_add_np (kern_switch) == 0);
+#endif
+
+ /*
+ * Create the waiting threads.
+ */
+ for (i = 0; i < NUM_THREADS; i++) {
+ assert (pthread_cond_init (&states[i].cond_var, &cattr) == 0);
+ states[i].id = (u_int8_t) i; /* NUM_THREADS must be <= 256 */
+ states[i].status = 0;
+ states[i].cmd.cmd_id = CMD_NONE;
+ states[i].flags = 0; /* No flags yet. */
+ assert (pthread_create (&states[i].tid, &pattr, waiter,
+ (void *) &states[i]) == 0);
+ param.sched_priority = main_prio - 10 + i;
+ states[i].priority = param.sched_priority;
+ assert (pthread_setschedparam (states[i].tid, SCHED_OTHER,
+ &param) == 0);
+#if defined(__FreeBSD__)
+ {
+ char buf[30];
+
+ snprintf (buf, sizeof(buf), "waiter_%d", i);
+ pthread_set_name_np (states[i].tid, buf);
+ }
+#endif
+ }
+
+ /* Allow the threads to start. */
+ sleep (1);
+ log_trace ("Done creating threads.\n");
+
+ log ("\n");
+ mutex_init_test ();
+ log ("\n");
+ mutex_destroy_test ();
+ log ("\n");
+ mutex_lock_test ();
+ log ("\n");
+ mutex_unlock_test ();
+ log ("\n");
+ queueing_order_test ();
+ log ("\n");
+ mutex_prioinherit_test ();
+ log ("\n");
+ mutex_prioceiling_test ();
+ log ("\n");
+
+ log ("Total tests %d, passed %d, failed %d\n",
+ total, pass_count, error_count);
+
+ /* Set the done flag and signal the threads to exit. */
+ log_trace ("Setting done flag.\n");
+ done = 1;
+
+ /*
+ * Wait for the threads to finish.
+ */
+ log_trace ("Trying to join threads.\n");
+ for (i = 0; i < NUM_THREADS; i++) {
+ send_cmd (i, CMD_NONE);
+ assert (pthread_join (states[i].tid, &exit_status) == 0);
+ }
+
+ /* Clean up after ourselves. */
+ close (pipefd[0]);
+ close (pipefd[1]);
+
+ if (error_count != 0)
+ exit (EX_OSERR); /* any better ideas??? */
+ else
+ exit (EX_OK);
+}
diff --git a/lib/libc_r/test/sigsuspend/Makefile b/lib/libc_r/test/sigsuspend/Makefile
new file mode 100644
index 0000000..7fb52c8
--- /dev/null
+++ b/lib/libc_r/test/sigsuspend/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+PROG= sigsuspend
+SRCS= sigsuspend.c
+NOMAN= 1
+LDFLAGS= -pthread
+
+.include <bsd.prog.mk>
diff --git a/lib/libc_r/test/sigsuspend/sigsuspend.c b/lib/libc_r/test/sigsuspend/sigsuspend.c
new file mode 100644
index 0000000..113b2d6
--- /dev/null
+++ b/lib/libc_r/test/sigsuspend/sigsuspend.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel M. Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+
+#if defined(__FreeBSD__)
+#include <pthread_np.h>
+#endif
+
+static int sigcounts[NSIG + 1];
+static int sigfifo[NSIG + 1];
+static int fifo_depth = 0;
+static sigset_t suspender_mask;
+static pthread_t suspender_tid;
+
+
+static void *
+sigsuspender (void *arg)
+{
+ int save_count, status, i;
+ sigset_t run_mask;
+
+ /* Run with all signals blocked. */
+ sigfillset (&run_mask);
+ sigprocmask (SIG_SETMASK, &run_mask, NULL);
+
+ /* Allow these signals to wake us up during a sigsuspend. */
+ sigfillset (&suspender_mask); /* Default action */
+ sigdelset (&suspender_mask, SIGINT); /* terminate */
+ sigdelset (&suspender_mask, SIGHUP); /* terminate */
+ sigdelset (&suspender_mask, SIGQUIT); /* create core image */
+ sigdelset (&suspender_mask, SIGURG); /* ignore */
+ sigdelset (&suspender_mask, SIGIO); /* ignore */
+ sigdelset (&suspender_mask, SIGUSR2); /* terminate */
+
+ while (sigcounts[SIGINT] == 0) {
+ save_count = sigcounts[SIGUSR2];
+
+ status = sigsuspend (&suspender_mask);
+ if ((status == 0) || (errno != EINTR)) {
+ printf ("Unable to suspend for signals, "
+ "errno %d, return value %d\n",
+ errno, status);
+ exit (1);
+ }
+ for (i = 0; i < fifo_depth; i++)
+ printf ("Sigsuspend woke up by signal %d\n",
+ sigfifo[i]);
+ fifo_depth = 0;
+ }
+
+ pthread_exit (arg);
+ return (NULL);
+}
+
+
+static void
+sighandler (int signo)
+{
+ sigset_t set, suspend_set;
+ pthread_t self;
+
+ if ((signo >= 0) && (signo <= NSIG))
+ sigcounts[signo]++;
+
+ /*
+ * If we are running on behalf of the suspender thread,
+ * ensure that we have the correct mask set.
+ */
+ self = pthread_self ();
+ if (self == suspender_tid) {
+ sigfifo[fifo_depth] = signo;
+ fifo_depth++;
+ printf (" -> Suspender thread signal handler caught signal %d\n",
+ signo);
+
+ /* Get the current signal mask. */
+ sigprocmask (SIG_SETMASK, NULL, &set);
+
+ /* The handler should run with the current signal masked. */
+ suspend_set = suspender_mask;
+ sigaddset(&suspend_set, signo);
+
+ if (memcmp(&set, &suspend_set, sizeof(set)))
+ printf (" >>> FAIL: sigsuspender signal handler running "
+ "with incorrect mask.\n");
+ }
+ else
+ printf (" -> Main thread signal handler caught signal %d\n",
+ signo);
+}
+
+
+static void
+send_thread_signal (pthread_t tid, int signo)
+{
+ if (pthread_kill (tid, signo) != 0) {
+ printf ("Unable to send thread signal, errno %d.\n", errno);
+ exit (1);
+ }
+}
+
+
+static void
+send_process_signal (int signo)
+{
+ if (kill (getpid (), signo) != 0) {
+ printf ("Unable to send process signal, errno %d.\n", errno);
+ exit (1);
+ }
+}
+
+
+int main (int argc, char *argv[])
+{
+ pthread_attr_t pattr;
+ void * exit_status;
+ struct sigaction act;
+ sigset_t oldset;
+ sigset_t newset;
+
+ /* Initialize our signal counts. */
+ memset ((void *) sigcounts, 0, NSIG * sizeof (int));
+
+ /* Ignore signal SIGIO. */
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGIO);
+ act.sa_handler = SIG_IGN;
+ act.sa_flags = 0;
+ sigaction (SIGIO, &act, NULL);
+
+ /* Install a signal handler for SIGURG. */
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGURG);
+ act.sa_handler = sighandler;
+ act.sa_flags = SA_RESTART;
+ sigaction (SIGURG, &act, NULL);
+
+ /* Install a signal handler for SIGXCPU */
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGXCPU);
+ sigaction (SIGXCPU, &act, NULL);
+
+ /* Get our current signal mask. */
+ sigprocmask (SIG_SETMASK, NULL, &oldset);
+
+ /* Mask out SIGUSR1 and SIGUSR2. */
+ newset = oldset;
+ sigaddset (&newset, SIGUSR1);
+ sigaddset (&newset, SIGUSR2);
+ sigprocmask (SIG_SETMASK, &newset, NULL);
+
+ /* Install a signal handler for SIGUSR1 */
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGUSR1);
+ sigaction (SIGUSR1, &act, NULL);
+
+ /* Install a signal handler for SIGUSR2 */
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGUSR2);
+ sigaction (SIGUSR2, &act, NULL);
+
+ /*
+ * Initialize the thread attribute.
+ */
+ if ((pthread_attr_init (&pattr) != 0) ||
+ (pthread_attr_setdetachstate (&pattr,
+ PTHREAD_CREATE_JOINABLE) != 0)) {
+ printf ("Unable to initialize thread attributes.\n");
+ exit (1);
+ }
+
+ /*
+ * Create the sigsuspender thread.
+ */
+ if (pthread_create (&suspender_tid, &pattr, sigsuspender, NULL) != 0) {
+ printf ("Unable to create thread, errno %d.\n", errno);
+ exit (1);
+ }
+#if defined(__FreeBSD__)
+ pthread_set_name_np (suspender_tid, "sigsuspender");
+#endif
+
+ /*
+ * Verify that an ignored signal doesn't cause a wakeup.
+ * We don't have a handler installed for SIGIO.
+ */
+ send_thread_signal (suspender_tid, SIGIO);
+ sleep (1);
+ send_process_signal (SIGIO);
+ sleep (1);
+ if (sigcounts[SIGIO] != 0)
+ printf ("FAIL: sigsuspend wakes up for ignored signal "
+ "SIGIO.\n");
+
+ /*
+ * Verify that a signal with a default action of ignore, for
+ * which we have a signal handler installed, will release a
+ * sigsuspend.
+ */
+ send_thread_signal (suspender_tid, SIGURG);
+ sleep (1);
+ send_process_signal (SIGURG);
+ sleep (1);
+ if (sigcounts[SIGURG] != 2)
+ printf ("FAIL: sigsuspend doesn't wake up for SIGURG.\n");
+
+ /*
+ * Verify that a SIGUSR2 signal will release a sigsuspended
+ * thread.
+ */
+ send_thread_signal (suspender_tid, SIGUSR2);
+ sleep (1);
+ send_process_signal (SIGUSR2);
+ sleep (1);
+ if (sigcounts[SIGUSR2] != 2)
+ printf ("FAIL: sigsuspend doesn't wake up for SIGUSR2.\n");
+
+ /*
+ * Verify that a signal, blocked in both the main and
+ * sigsuspender threads, does not cause the signal handler
+ * to be called.
+ */
+ send_thread_signal (suspender_tid, SIGUSR1);
+ sleep (1);
+ send_process_signal (SIGUSR1);
+ sleep (1);
+ if (sigcounts[SIGUSR1] != 0)
+ printf ("FAIL: signal hander called for SIGUSR1.\n");
+
+ /*
+ * Verify that we can still kill the process for a signal
+ * not being waited on by sigwait.
+ */
+ send_process_signal (SIGPIPE);
+ printf ("FAIL: SIGPIPE did not terminate process.\n");
+
+ /*
+ * Wait for the thread to finish.
+ */
+ pthread_join (suspender_tid, &exit_status);
+
+ return (0);
+}
+
diff --git a/lib/libc_r/test/sigwait/Makefile b/lib/libc_r/test/sigwait/Makefile
new file mode 100644
index 0000000..31520c1
--- /dev/null
+++ b/lib/libc_r/test/sigwait/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+PROG= sigwait
+SRCS= sigwait.c
+NOMAN= 1
+LDFLAGS= -pthread
+
+.include <bsd.prog.mk>
diff --git a/lib/libc_r/test/sigwait/sigwait.c b/lib/libc_r/test/sigwait/sigwait.c
new file mode 100644
index 0000000..961691d
--- /dev/null
+++ b/lib/libc_r/test/sigwait/sigwait.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel M. Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+
+#if defined(__FreeBSD__)
+#include <pthread_np.h>
+#endif
+
+static int sigcounts[NSIG + 1];
+static sigset_t wait_mask;
+static pthread_mutex_t waiter_mutex;
+
+
+static void *
+sigwaiter (void *arg)
+{
+ int signo;
+ sigset_t mask;
+
+ /* Block SIGHUP */
+ sigemptyset (&mask);
+ sigaddset (&mask, SIGHUP);
+ sigprocmask (SIG_BLOCK, &mask, NULL);
+
+ while (sigcounts[SIGINT] == 0) {
+ if (sigwait (&wait_mask, &signo) != 0) {
+ printf ("Unable to wait for signal, errno %d\n",
+ errno);
+ exit (1);
+ }
+ sigcounts[signo]++;
+ printf ("Sigwait caught signal %d\n", signo);
+
+ /* Allow the main thread to prevent the sigwait. */
+ pthread_mutex_lock (&waiter_mutex);
+ pthread_mutex_unlock (&waiter_mutex);
+ }
+
+ pthread_exit (arg);
+ return (NULL);
+}
+
+
+static void
+sighandler (int signo)
+{
+ printf (" -> Signal handler caught signal %d\n", signo);
+
+ if ((signo >= 0) && (signo <= NSIG))
+ sigcounts[signo]++;
+}
+
+static void
+send_thread_signal (pthread_t tid, int signo)
+{
+ if (pthread_kill (tid, signo) != 0) {
+ printf ("Unable to send thread signal, errno %d.\n", errno);
+ exit (1);
+ }
+}
+
+static void
+send_process_signal (int signo)
+{
+ if (kill (getpid (), signo) != 0) {
+ printf ("Unable to send process signal, errno %d.\n", errno);
+ exit (1);
+ }
+}
+
+
+int main (int argc, char *argv[])
+{
+ pthread_mutexattr_t mattr;
+ pthread_attr_t pattr;
+ pthread_t tid;
+ void * exit_status;
+ struct sigaction act;
+
+ /* Initialize our signal counts. */
+ memset ((void *) sigcounts, 0, NSIG * sizeof (int));
+
+ /* Setup our wait mask. */
+ sigemptyset (&wait_mask); /* Default action */
+ sigaddset (&wait_mask, SIGHUP); /* terminate */
+ sigaddset (&wait_mask, SIGINT); /* terminate */
+ sigaddset (&wait_mask, SIGQUIT); /* create core image */
+ sigaddset (&wait_mask, SIGURG); /* ignore */
+ sigaddset (&wait_mask, SIGIO); /* ignore */
+ sigaddset (&wait_mask, SIGUSR1); /* terminate */
+
+ /* Ignore signals SIGHUP and SIGIO. */
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGHUP);
+ sigaddset (&act.sa_mask, SIGIO);
+ act.sa_handler = SIG_IGN;
+ act.sa_flags = 0;
+ sigaction (SIGHUP, &act, NULL);
+ sigaction (SIGIO, &act, NULL);
+
+ /* Install a signal handler for SIGURG */
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGURG);
+ act.sa_handler = sighandler;
+ act.sa_flags = SA_RESTART;
+ sigaction (SIGURG, &act, NULL);
+
+ /* Install a signal handler for SIGXCPU */
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGXCPU);
+ sigaction (SIGXCPU, &act, NULL);
+
+ /*
+ * Initialize the thread attribute.
+ */
+ if ((pthread_attr_init (&pattr) != 0) ||
+ (pthread_attr_setdetachstate (&pattr,
+ PTHREAD_CREATE_JOINABLE) != 0)) {
+ printf ("Unable to initialize thread attributes.\n");
+ exit (1);
+ }
+
+ /*
+ * Initialize and create a mutex.
+ */
+ if ((pthread_mutexattr_init (&mattr) != 0) ||
+ (pthread_mutex_init (&waiter_mutex, &mattr) != 0)) {
+ printf ("Unable to create waiter mutex.\n");
+ exit (1);
+ }
+
+ /*
+ * Create the sigwaiter thread.
+ */
+ if (pthread_create (&tid, &pattr, sigwaiter, NULL) != 0) {
+ printf ("Unable to create thread.\n");
+ exit (1);
+ }
+#if defined(__FreeBSD__)
+ pthread_set_name_np (tid, "sigwaiter");
+#endif
+
+ /*
+ * Verify that an ignored signal doesn't cause a wakeup.
+ * We don't have a handler installed for SIGIO.
+ */
+ send_thread_signal (tid, SIGIO);
+ sleep (1);
+ send_process_signal (SIGIO);
+ sleep (1);
+ if (sigcounts[SIGIO] != 0)
+ printf ("FAIL: sigwait wakes up for ignored signal SIGIO.\n");
+
+ /*
+ * Verify that a signal with a default action of ignore, for
+ * which we have a signal handler installed, will release a sigwait.
+ */
+ send_thread_signal (tid, SIGURG);
+ sleep (1);
+ send_process_signal (SIGURG);
+ sleep (1);
+ if (sigcounts[SIGURG] != 2)
+ printf ("FAIL: sigwait doesn't wake up for SIGURG.\n");
+
+ /*
+ * Verify that a signal with a default action that terminates
+ * the process will release a sigwait.
+ */
+ send_thread_signal (tid, SIGUSR1);
+ sleep (1);
+ send_process_signal (SIGUSR1);
+ sleep (1);
+ if (sigcounts[SIGUSR1] != 2)
+ printf ("FAIL: sigwait doesn't wake up for SIGUSR1.\n");
+
+ /*
+ * Verify that if we install a signal handler for a previously
+ * ignored signal, an occurrence of this signal will release
+ * the (already waiting) sigwait.
+ */
+
+ /* Install a signal handler for SIGHUP. */
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGHUP);
+ act.sa_handler = sighandler;
+ act.sa_flags = SA_RESTART;
+ sigaction (SIGHUP, &act, NULL);
+
+ /* Sending SIGHUP should release the sigwait. */
+ send_process_signal (SIGHUP);
+ sleep (1);
+ send_thread_signal (tid, SIGHUP);
+ sleep (1);
+ if (sigcounts[SIGHUP] != 2)
+ printf ("FAIL: sigwait doesn't wake up for SIGHUP.\n");
+
+ /*
+ * Verify that a pending signal in the waiters mask will
+ * cause sigwait to return the pending signal. We do this
+ * by taking the waiters mutex and signaling the waiter to
+ * release him from the sigwait. The waiter will block
+ * on taking the mutex, and we can then send the waiter a
+ * signal which should be added to his pending signals.
+ * The next time the waiter does a sigwait, he should
+ * return with the pending signal.
+ */
+ sigcounts[SIGHUP] = 0;
+ pthread_mutex_lock (&waiter_mutex);
+ /* Release the waiter from sigwait. */
+ send_process_signal (SIGHUP);
+ sleep (1);
+ if (sigcounts[SIGHUP] != 1)
+ printf ("FAIL: sigwait doesn't wake up for SIGHUP.\n");
+ /*
+ * Add SIGHUP to the process pending signals. Since there is
+ * a signal handler installed for SIGHUP and this signal is
+ * blocked from the waiter thread and unblocked in the main
+ * thread, the signal handler should be called once for SIGHUP.
+ */
+ send_process_signal (SIGHUP);
+ /* Release the waiter thread and allow him to run. */
+ pthread_mutex_unlock (&waiter_mutex);
+ sleep (1);
+ if (sigcounts[SIGHUP] != 2)
+ printf ("FAIL: sigwait doesn't return for pending SIGHUP.\n");
+
+ /*
+ * Repeat the above test using pthread_kill and SIGUSR1.
+ */
+ sigcounts[SIGUSR1] = 0;
+ pthread_mutex_lock (&waiter_mutex);
+ /* Release the waiter from sigwait. */
+ send_thread_signal (tid, SIGUSR1);
+ sleep (1);
+ if (sigcounts[SIGUSR1] != 1)
+ printf ("FAIL: sigwait doesn't wake up for SIGUSR1.\n");
+ /* Add SIGHUP to the waiters pending signals. */
+ send_thread_signal (tid, SIGUSR1);
+ /* Release the waiter thread and allow him to run. */
+ pthread_mutex_unlock (&waiter_mutex);
+ sleep (1);
+ if (sigcounts[SIGUSR1] != 2)
+ printf ("FAIL: sigwait doesn't return for pending SIGUSR1.\n");
+
+ /*
+ * Verify that we can still kill the process for a signal
+ * not being waited on by sigwait.
+ */
+ send_process_signal (SIGPIPE);
+ printf ("FAIL: SIGPIPE did not terminate process.\n");
+
+ /*
+ * Wait for the thread to finish.
+ */
+ pthread_join (tid, &exit_status);
+
+ return (0);
+}
diff --git a/lib/libc_r/uthread/Makefile.inc b/lib/libc_r/uthread/Makefile.inc
new file mode 100644
index 0000000..4697305
--- /dev/null
+++ b/lib/libc_r/uthread/Makefile.inc
@@ -0,0 +1,117 @@
+# $FreeBSD$
+
+# uthread sources
+.PATH: ${.CURDIR}/uthread
+
+SRCS+= \
+ uthread_accept.c \
+ uthread_attr_destroy.c \
+ uthread_attr_init.c \
+ uthread_attr_getdetachstate.c \
+ uthread_attr_getinheritsched.c \
+ uthread_attr_getschedparam.c \
+ uthread_attr_getschedpolicy.c \
+ uthread_attr_getscope.c \
+ uthread_attr_getstackaddr.c \
+ uthread_attr_getstacksize.c \
+ uthread_attr_setcreatesuspend_np.c \
+ uthread_attr_setdetachstate.c \
+ uthread_attr_setinheritsched.c \
+ uthread_attr_setschedparam.c \
+ uthread_attr_setschedpolicy.c \
+ uthread_attr_setscope.c \
+ uthread_attr_setstackaddr.c \
+ uthread_attr_setstacksize.c \
+ uthread_autoinit.cc \
+ uthread_bind.c \
+ uthread_cancel.c \
+ uthread_clean.c \
+ uthread_close.c \
+ uthread_cond.c \
+ uthread_condattr_destroy.c \
+ uthread_condattr_init.c \
+ uthread_connect.c \
+ uthread_create.c \
+ uthread_detach.c \
+ uthread_dup.c \
+ uthread_dup2.c \
+ uthread_equal.c \
+ uthread_execve.c \
+ uthread_exit.c \
+ uthread_fchflags.c \
+ uthread_fchmod.c \
+ uthread_fchown.c \
+ uthread_fcntl.c \
+ uthread_fd.c \
+ uthread_file.c \
+ uthread_find_thread.c \
+ uthread_flock.c \
+ uthread_fork.c \
+ uthread_fstat.c \
+ uthread_fstatfs.c \
+ uthread_fsync.c \
+ uthread_gc.c \
+ uthread_getdirentries.c \
+ uthread_getpeername.c \
+ uthread_getprio.c \
+ uthread_getschedparam.c \
+ uthread_getsockname.c \
+ uthread_getsockopt.c \
+ uthread_info.c \
+ uthread_init.c \
+ uthread_ioctl.c \
+ uthread_join.c \
+ uthread_kern.c \
+ uthread_kill.c \
+ uthread_listen.c \
+ uthread_mattr_init.c \
+ uthread_mattr_kind_np.c \
+ uthread_msync.c \
+ uthread_multi_np.c \
+ uthread_mutex.c \
+ uthread_mutex_prioceiling.c \
+ uthread_mutex_protocol.c \
+ uthread_mutexattr_destroy.c \
+ uthread_nanosleep.c \
+ uthread_once.c \
+ uthread_open.c \
+ uthread_pipe.c \
+ uthread_poll.c \
+ uthread_priority_queue.c \
+ uthread_read.c \
+ uthread_readv.c \
+ uthread_recvfrom.c \
+ uthread_recvmsg.c \
+ uthread_resume_np.c \
+ uthread_rwlock.c \
+ uthread_rwlockattr.c \
+ uthread_select.c \
+ uthread_self.c \
+ uthread_sendmsg.c \
+ uthread_sendto.c \
+ uthread_seterrno.c \
+ uthread_setprio.c \
+ uthread_setschedparam.c \
+ uthread_setsockopt.c \
+ uthread_shutdown.c \
+ uthread_sig.c \
+ uthread_sigaction.c \
+ uthread_sigblock.c \
+ uthread_sigmask.c \
+ uthread_sigpending.c \
+ uthread_sigprocmask.c \
+ uthread_sigsetmask.c \
+ uthread_sigsuspend.c \
+ uthread_sigwait.c \
+ uthread_single_np.c \
+ uthread_socket.c \
+ uthread_socketpair.c \
+ uthread_spec.c \
+ uthread_spinlock.c \
+ uthread_suspend_np.c \
+ uthread_switch_np.c \
+ uthread_vfork.c \
+ uthread_wait4.c \
+ uthread_write.c \
+ uthread_writev.c \
+ uthread_yield.c
diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h
new file mode 100644
index 0000000..4326bf6
--- /dev/null
+++ b/lib/libc_r/uthread/pthread_private.h
@@ -0,0 +1,1182 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Private thread definitions for the uthread kernel.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PTHREAD_PRIVATE_H
+#define _PTHREAD_PRIVATE_H
+
+/*
+ * Evaluate the storage class specifier.
+ */
+#ifdef GLOBAL_PTHREAD_PRIVATE
+#define SCLASS
+#else
+#define SCLASS extern
+#endif
+
+/*
+ * Include files.
+ */
+#include <setjmp.h>
+#include <signal.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sched.h>
+#include <spinlock.h>
+#include <pthread_np.h>
+
+/*
+ * Kernel fatal error handler macro.
+ */
+#define PANIC(string) _thread_exit(__FILE__,__LINE__,string)
+
+/* Output debug messages like this: */
+#define stdout_debug(_x) _thread_sys_write(1,_x,strlen(_x));
+#define stderr_debug(_x) _thread_sys_write(2,_x,strlen(_x));
+
+
+/*
+ * Priority queue manipulation macros (using pqe link):
+ */
+#define PTHREAD_PRIOQ_INSERT_HEAD(thrd) _pq_insert_head(&_readyq,thrd)
+#define PTHREAD_PRIOQ_INSERT_TAIL(thrd) _pq_insert_tail(&_readyq,thrd)
+#define PTHREAD_PRIOQ_REMOVE(thrd) _pq_remove(&_readyq,thrd)
+#define PTHREAD_PRIOQ_FIRST() _pq_first(&_readyq)
+
+/*
+ * Waiting queue manipulation macros (using pqe link):
+ */
+#if defined(_PTHREADS_INVARIANTS)
+#define PTHREAD_WAITQ_REMOVE(thrd) _waitq_remove(thrd)
+#define PTHREAD_WAITQ_INSERT(thrd) _waitq_insert(thrd)
+#define PTHREAD_WAITQ_CLEARACTIVE() _waitq_clearactive()
+#define PTHREAD_WAITQ_SETACTIVE() _waitq_setactive()
+#else
+#define PTHREAD_WAITQ_REMOVE(thrd) TAILQ_REMOVE(&_waitingq,thrd,pqe)
+#define PTHREAD_WAITQ_INSERT(thrd) do { \
+ if ((thrd)->wakeup_time.tv_sec == -1) \
+ TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe); \
+ else { \
+ pthread_t tid = TAILQ_FIRST(&_waitingq); \
+ while ((tid != NULL) && (tid->wakeup_time.tv_sec != -1) && \
+ ((tid->wakeup_time.tv_sec < (thrd)->wakeup_time.tv_sec) || \
+ ((tid->wakeup_time.tv_sec == (thrd)->wakeup_time.tv_sec) && \
+ (tid->wakeup_time.tv_nsec <= (thrd)->wakeup_time.tv_nsec)))) \
+ tid = TAILQ_NEXT(tid, pqe); \
+ if (tid == NULL) \
+ TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe); \
+ else \
+ TAILQ_INSERT_BEFORE(tid,thrd,pqe); \
+ } \
+} while (0)
+#define PTHREAD_WAITQ_CLEARACTIVE()
+#define PTHREAD_WAITQ_SETACTIVE()
+#endif
+
+/*
+ * Work queue manipulation macros (using qe link):
+ */
+#define PTHREAD_WORKQ_INSERT(thrd) do { \
+ TAILQ_INSERT_TAIL(&_workq,thrd,qe); \
+ (thrd)->flags |= PTHREAD_FLAGS_IN_WORKQ; \
+} while (0)
+#define PTHREAD_WORKQ_REMOVE(thrd) do { \
+ TAILQ_REMOVE(&_workq,thrd,qe); \
+ (thrd)->flags &= ~PTHREAD_FLAGS_IN_WORKQ; \
+} while (0)
+
+
+/*
+ * State change macro without scheduling queue change:
+ */
+#define PTHREAD_SET_STATE(thrd, newstate) do { \
+ (thrd)->state = newstate; \
+ (thrd)->fname = __FILE__; \
+ (thrd)->lineno = __LINE__; \
+} while (0)
+
+/*
+ * State change macro with scheduling queue change - This must be
+ * called with preemption deferred (see thread_kern_sched_[un]defer).
+ */
+#if defined(_PTHREADS_INVARIANTS)
+#define PTHREAD_NEW_STATE(thrd, newstate) do { \
+ if (_thread_kern_new_state != 0) \
+ PANIC("Recursive PTHREAD_NEW_STATE"); \
+ _thread_kern_new_state = 1; \
+ if ((thrd)->state != newstate) { \
+ if ((thrd)->state == PS_RUNNING) { \
+ PTHREAD_PRIOQ_REMOVE(thrd); \
+ PTHREAD_WAITQ_INSERT(thrd); \
+ } else if (newstate == PS_RUNNING) { \
+ PTHREAD_WAITQ_REMOVE(thrd); \
+ PTHREAD_PRIOQ_INSERT_TAIL(thrd); \
+ } \
+ } \
+ _thread_kern_new_state = 0; \
+ PTHREAD_SET_STATE(thrd, newstate); \
+} while (0)
+#else
+#define PTHREAD_NEW_STATE(thrd, newstate) do { \
+ if ((thrd)->state != newstate) { \
+ if ((thrd)->state == PS_RUNNING) { \
+ PTHREAD_PRIOQ_REMOVE(thrd); \
+ PTHREAD_WAITQ_INSERT(thrd); \
+ } else if (newstate == PS_RUNNING) { \
+ PTHREAD_WAITQ_REMOVE(thrd); \
+ PTHREAD_PRIOQ_INSERT_TAIL(thrd); \
+ } \
+ } \
+ PTHREAD_SET_STATE(thrd, newstate); \
+} while (0)
+#endif
+
+/*
+ * Define the signals to be used for scheduling.
+ */
+#if defined(_PTHREADS_COMPAT_SCHED)
+#define _ITIMER_SCHED_TIMER ITIMER_VIRTUAL
+#define _SCHED_SIGNAL SIGVTALRM
+#else
+#define _ITIMER_SCHED_TIMER ITIMER_PROF
+#define _SCHED_SIGNAL SIGPROF
+#endif
+
+/*
+ * Priority queues.
+ *
+ * XXX It'd be nice if these were contained in uthread_priority_queue.[ch].
+ */
+typedef struct pq_list {
+ TAILQ_HEAD(, pthread) pl_head; /* list of threads at this priority */
+ TAILQ_ENTRY(pq_list) pl_link; /* link for queue of priority lists */
+ int pl_prio; /* the priority of this list */
+ int pl_queued; /* is this in the priority queue */
+} pq_list_t;
+
+typedef struct pq_queue {
+ TAILQ_HEAD(, pq_list) pq_queue; /* queue of priority lists */
+ pq_list_t *pq_lists; /* array of all priority lists */
+ int pq_size; /* number of priority lists */
+} pq_queue_t;
+
+
+/*
+ * TailQ initialization values.
+ */
+#define TAILQ_INITIALIZER { NULL, NULL }
+
+/*
+ * Mutex definitions.
+ */
+union pthread_mutex_data {
+ void *m_ptr;
+ int m_count;
+};
+
+struct pthread_mutex {
+ enum pthread_mutextype m_type;
+ int m_protocol;
+ TAILQ_HEAD(mutex_head, pthread) m_queue;
+ struct pthread *m_owner;
+ union pthread_mutex_data m_data;
+ long m_flags;
+ int m_refcount;
+
+ /*
+ * Used for priority inheritence and protection.
+ *
+ * m_prio - For priority inheritence, the highest active
+ * priority (threads locking the mutex inherit
+ * this priority). For priority protection, the
+ * ceiling priority of this mutex.
+ * m_saved_prio - mutex owners inherited priority before
+ * taking the mutex, restored when the owner
+ * unlocks the mutex.
+ */
+ int m_prio;
+ int m_saved_prio;
+
+ /*
+ * Link for list of all mutexes a thread currently owns.
+ */
+ TAILQ_ENTRY(pthread_mutex) m_qe;
+
+ /*
+ * Lock for accesses to this structure.
+ */
+ spinlock_t lock;
+};
+
+/*
+ * Flags for mutexes.
+ */
+#define MUTEX_FLAGS_PRIVATE 0x01
+#define MUTEX_FLAGS_INITED 0x02
+#define MUTEX_FLAGS_BUSY 0x04
+
+/*
+ * Static mutex initialization values.
+ */
+#define PTHREAD_MUTEX_STATIC_INITIALIZER \
+ { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, TAILQ_INITIALIZER, \
+ NULL, { NULL }, MUTEX_FLAGS_PRIVATE, 0, 0, 0, TAILQ_INITIALIZER, \
+ _SPINLOCK_INITIALIZER }
+
+struct pthread_mutex_attr {
+ enum pthread_mutextype m_type;
+ int m_protocol;
+ int m_ceiling;
+ long m_flags;
+};
+
+/*
+ * Condition variable definitions.
+ */
+enum pthread_cond_type {
+ COND_TYPE_FAST,
+ COND_TYPE_MAX
+};
+
+struct pthread_cond {
+ enum pthread_cond_type c_type;
+ TAILQ_HEAD(cond_head, pthread) c_queue;
+ pthread_mutex_t c_mutex;
+ void *c_data;
+ long c_flags;
+
+ /*
+ * Lock for accesses to this structure.
+ */
+ spinlock_t lock;
+};
+
+struct pthread_cond_attr {
+ enum pthread_cond_type c_type;
+ long c_flags;
+};
+
+/*
+ * Flags for condition variables.
+ */
+#define COND_FLAGS_PRIVATE 0x01
+#define COND_FLAGS_INITED 0x02
+#define COND_FLAGS_BUSY 0x04
+
+/*
+ * Static cond initialization values.
+ */
+#define PTHREAD_COND_STATIC_INITIALIZER \
+ { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \
+ 0, _SPINLOCK_INITIALIZER }
+
+/*
+ * Cleanup definitions.
+ */
+struct pthread_cleanup {
+ struct pthread_cleanup *next;
+ void (*routine) ();
+ void *routine_arg;
+};
+
+struct pthread_attr {
+ int sched_policy;
+ int sched_inherit;
+ int sched_interval;
+ int prio;
+ int suspend;
+ int flags;
+ void *arg_attr;
+ void (*cleanup_attr) ();
+ void *stackaddr_attr;
+ size_t stacksize_attr;
+};
+
+/*
+ * Thread creation state attributes.
+ */
+#define PTHREAD_CREATE_RUNNING 0
+#define PTHREAD_CREATE_SUSPENDED 1
+
+/*
+ * Miscellaneous definitions.
+ */
+#define PTHREAD_STACK_DEFAULT 65536
+/* Size of red zone at the end of each stack. */
+#define PTHREAD_STACK_GUARD PAGE_SIZE
+
+/*
+ * Maximum size of initial thread's stack. This perhaps deserves to be larger
+ * than the stacks of other threads, since many applications are likely to run
+ * almost entirely on this stack.
+ */
+#define PTHREAD_STACK_INITIAL 0x100000
+/* Address immediately beyond the beginning of the initial thread stack. */
+#define PTHREAD_DEFAULT_PRIORITY 64
+#define PTHREAD_MAX_PRIORITY 126
+#define PTHREAD_MIN_PRIORITY 0
+#define _POSIX_THREAD_ATTR_STACKSIZE
+
+/*
+ * Clock resolution in nanoseconds.
+ */
+#define CLOCK_RES_NSEC 10000000
+
+/*
+ * Time slice period in microseconds.
+ */
+#define TIMESLICE_USEC 100000
+
+struct pthread_key {
+ spinlock_t lock;
+ volatile int allocated;
+ volatile int count;
+ void (*destructor) ();
+};
+
+struct pthread_rwlockattr {
+ int pshared;
+};
+
+struct pthread_rwlock {
+ pthread_mutex_t lock; /* monitor lock */
+ int state; /* 0 = idle >0 = # of readers -1 = writer */
+ pthread_cond_t read_signal;
+ pthread_cond_t write_signal;
+ int blocked_writers;
+};
+
+/*
+ * Thread states.
+ */
+enum pthread_state {
+ PS_RUNNING,
+ PS_SIGTHREAD,
+ PS_MUTEX_WAIT,
+ PS_COND_WAIT,
+ PS_FDLR_WAIT,
+ PS_FDLW_WAIT,
+ PS_FDR_WAIT,
+ PS_FDW_WAIT,
+ PS_FILE_WAIT,
+ PS_POLL_WAIT,
+ PS_SELECT_WAIT,
+ PS_SLEEP_WAIT,
+ PS_WAIT_WAIT,
+ PS_SIGSUSPEND,
+ PS_SIGWAIT,
+ PS_SPINBLOCK,
+ PS_JOIN,
+ PS_SUSPENDED,
+ PS_DEAD,
+ PS_DEADLOCK,
+ PS_STATE_MAX
+};
+
+
+/*
+ * File descriptor locking definitions.
+ */
+#define FD_READ 0x1
+#define FD_WRITE 0x2
+#define FD_RDWR (FD_READ | FD_WRITE)
+
+/*
+ * File descriptor table structure.
+ */
+struct fd_table_entry {
+ /*
+ * Lock for accesses to this file descriptor table
+ * entry. This is passed to _spinlock() to provide atomic
+ * access to this structure. It does *not* represent the
+ * state of the lock on the file descriptor.
+ */
+ spinlock_t lock;
+ TAILQ_HEAD(, pthread) r_queue; /* Read queue. */
+ TAILQ_HEAD(, pthread) w_queue; /* Write queue. */
+ struct pthread *r_owner; /* Ptr to thread owning read lock. */
+ struct pthread *w_owner; /* Ptr to thread owning write lock. */
+ char *r_fname; /* Ptr to read lock source file name */
+ int r_lineno; /* Read lock source line number. */
+ char *w_fname; /* Ptr to write lock source file name */
+ int w_lineno; /* Write lock source line number. */
+ int r_lockcount; /* Count for FILE read locks. */
+ int w_lockcount; /* Count for FILE write locks. */
+ int flags; /* Flags used in open. */
+};
+
+struct pthread_poll_data {
+ int nfds;
+ struct pollfd *fds;
+};
+
+union pthread_wait_data {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ const sigset_t *sigwait; /* Waiting on a signal in sigwait */
+ struct {
+ short fd; /* Used when thread waiting on fd */
+ short branch; /* Line number, for debugging. */
+ char *fname; /* Source file name for debugging.*/
+ } fd;
+ struct pthread_poll_data * poll_data;
+ spinlock_t *spinlock;
+};
+
+/*
+ * Thread structure.
+ */
+struct pthread {
+ /*
+ * Magic value to help recognize a valid thread structure
+ * from an invalid one:
+ */
+#define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115)
+ u_int32_t magic;
+ char *name;
+ u_int64_t uniqueid; /* for gdb */
+
+ /*
+ * Lock for accesses to this thread structure.
+ */
+ spinlock_t lock;
+
+ /* Queue entry for list of all threads: */
+ TAILQ_ENTRY(pthread) tle;
+
+ /* Queue entry for list of dead threads: */
+ TAILQ_ENTRY(pthread) dle;
+
+ /*
+ * Thread start routine, argument, stack pointer and thread
+ * attributes.
+ */
+ void *(*start_routine)(void *);
+ void *arg;
+ void *stack;
+ struct pthread_attr attr;
+
+#if (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(__i386__)
+ /*
+ * Saved floating point registers on systems where they are not
+ * saved in the signal context.
+ */
+ char saved_fp[108];
+#endif
+
+ /*
+ * Saved signal context used in call to sigreturn by
+ * _thread_kern_sched if sig_saved is TRUE.
+ */
+ ucontext_t saved_sigcontext;
+
+ /*
+ * Saved jump buffer used in call to longjmp by _thread_kern_sched
+ * if sig_saved is FALSE.
+ */
+ jmp_buf saved_jmp_buf;
+
+ /*
+ * TRUE if the last state saved was a signal context. FALSE if the
+ * last state saved was a jump buffer.
+ */
+ int sig_saved;
+
+ /*
+ * Cancelability flags - the lower 2 bits are used by cancel
+ * definitions in pthread.h
+ */
+#define PTHREAD_AT_CANCEL_POINT 0x0004
+#define PTHREAD_CANCELLING 0x0008
+#define PTHREAD_CANCEL_NEEDED 0x0010
+ int cancelflags;
+
+ /*
+ * Current signal mask and pending signals.
+ */
+ sigset_t sigmask;
+ sigset_t sigpend;
+
+ /* Thread state: */
+ enum pthread_state state;
+
+ /* Time that this thread was last made active. */
+ struct timeval last_active;
+
+ /* Time that this thread was last made inactive. */
+ struct timeval last_inactive;
+
+ /*
+ * Number of microseconds accumulated by this thread when
+ * time slicing is active.
+ */
+ long slice_usec;
+
+ /*
+ * Incremental priority accumulated by thread while it is ready to
+ * run but is denied being run.
+ */
+ int inc_prio;
+
+ /*
+ * Time to wake up thread. This is used for sleeping threads and
+ * for any operation which may time out (such as select).
+ */
+ struct timespec wakeup_time;
+
+ /* TRUE if operation has timed out. */
+ int timeout;
+
+ /*
+ * Error variable used instead of errno. The function __error()
+ * returns a pointer to this.
+ */
+ int error;
+
+ /* Join queue head and link for waiting threads: */
+ TAILQ_HEAD(join_head, pthread) join_queue;
+
+ /*
+ * The current thread can belong to only one scheduling queue at
+ * a time (ready or waiting queue). It can also belong to (only)
+ * one of:
+ *
+ * o A queue of threads waiting for a mutex
+ * o A queue of threads waiting for a condition variable
+ * o A queue of threads waiting for another thread to terminate
+ * (the join queue above)
+ * o A queue of threads waiting for a file descriptor lock
+ * o A queue of threads needing work done by the kernel thread
+ * (waiting for a spinlock or file I/O)
+ *
+ * Use pqe for the scheduling queue link (both ready and waiting),
+ * and qe for other links.
+ */
+
+ /* Priority queue entry for this thread: */
+ TAILQ_ENTRY(pthread) pqe;
+
+ /* Queue entry for this thread: */
+ TAILQ_ENTRY(pthread) qe;
+
+ /* Wait data. */
+ union pthread_wait_data data;
+
+ /*
+ * Allocated for converting select into poll.
+ */
+ struct pthread_poll_data poll_data;
+
+ /*
+ * Set to TRUE if a blocking operation was
+ * interrupted by a signal:
+ */
+ int interrupted;
+
+ /* Signal number when in state PS_SIGWAIT: */
+ int signo;
+
+ /*
+ * Set to non-zero when this thread has deferred signals.
+ * We allow for recursive deferral.
+ */
+ int sig_defer_count;
+
+ /*
+ * Set to TRUE if this thread should yield after undeferring
+ * signals.
+ */
+ int yield_on_sig_undefer;
+
+ /* Miscellaneous flags; only set with signals deferred. */
+ int flags;
+#define PTHREAD_FLAGS_PRIVATE 0x0001
+#define PTHREAD_EXITING 0x0002
+#define PTHREAD_FLAGS_IN_CONDQ 0x0004 /* in condition queue using qe link*/
+#define PTHREAD_FLAGS_IN_WORKQ 0x0008 /* in work queue using qe link */
+#define PTHREAD_FLAGS_IN_WAITQ 0x0010 /* in waiting queue using pqe link */
+#define PTHREAD_FLAGS_IN_PRIOQ 0x0020 /* in priority queue using pqe link */
+#define PTHREAD_FLAGS_IN_MUTEXQ 0x0040 /* in mutex queue using qe link */
+#define PTHREAD_FLAGS_IN_FILEQ 0x0080 /* in file lock queue using qe link */
+#define PTHREAD_FLAGS_IN_FDQ 0x0100 /* in fd lock queue using qe link */
+#define PTHREAD_FLAGS_TRACE 0x0200 /* for debugging purposes */
+
+ /*
+ * Base priority is the user setable and retrievable priority
+ * of the thread. It is only affected by explicit calls to
+ * set thread priority and upon thread creation via a thread
+ * attribute or default priority.
+ */
+ char base_priority;
+
+ /*
+ * Inherited priority is the priority a thread inherits by
+ * taking a priority inheritence or protection mutex. It
+ * is not affected by base priority changes. Inherited
+ * priority defaults to and remains 0 until a mutex is taken
+ * that is being waited on by any other thread whose priority
+ * is non-zero.
+ */
+ char inherited_priority;
+
+ /*
+ * Active priority is always the maximum of the threads base
+ * priority and inherited priority. When there is a change
+ * in either the base or inherited priority, the active
+ * priority must be recalculated.
+ */
+ char active_priority;
+
+ /* Number of priority ceiling or protection mutexes owned. */
+ int priority_mutex_count;
+
+ /*
+ * Queue of currently owned mutexes.
+ */
+ TAILQ_HEAD(, pthread_mutex) mutexq;
+
+ void *ret;
+ const void **specific_data;
+ int specific_data_count;
+
+ /* Cleanup handlers Link List */
+ struct pthread_cleanup *cleanup;
+ char *fname; /* Ptr to source file name */
+ int lineno; /* Source line number. */
+};
+
+/* Spare thread stack. */
+struct stack {
+ SLIST_ENTRY(stack) qe; /* Queue entry for this stack. */
+};
+
+/*
+ * Global variables for the uthread kernel.
+ */
+
+/* Kernel thread structure used when there are no running threads: */
+SCLASS struct pthread _thread_kern_thread;
+
+/* Ptr to the thread structure for the running thread: */
+SCLASS struct pthread * volatile _thread_run
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= &_thread_kern_thread;
+#else
+;
+#endif
+
+/* Ptr to the thread structure for the last user thread to run: */
+SCLASS struct pthread * volatile _last_user_thread
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= &_thread_kern_thread;
+#else
+;
+#endif
+
+/*
+ * Ptr to the thread running in single-threaded mode or NULL if
+ * running multi-threaded (default POSIX behaviour).
+ */
+SCLASS struct pthread * volatile _thread_single
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL;
+#else
+;
+#endif
+
+/* List of all threads: */
+SCLASS TAILQ_HEAD(, pthread) _thread_list
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= TAILQ_HEAD_INITIALIZER(_thread_list);
+#else
+;
+#endif
+
+/*
+ * Array of kernel pipe file descriptors that are used to ensure that
+ * no signals are missed in calls to _select.
+ */
+SCLASS int _thread_kern_pipe[2]
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= {
+ -1,
+ -1
+};
+#else
+;
+#endif
+SCLASS int volatile _queue_signals
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0;
+#else
+;
+#endif
+SCLASS int _thread_kern_in_sched
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0;
+#else
+;
+#endif
+
+/* Last time that an incremental priority update was performed: */
+SCLASS struct timeval kern_inc_prio_time
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= { 0, 0 };
+#else
+;
+#endif
+
+/* Dead threads: */
+SCLASS TAILQ_HEAD(, pthread) _dead_list
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= TAILQ_HEAD_INITIALIZER(_dead_list);
+#else
+;
+#endif
+
+/* Initial thread: */
+SCLASS struct pthread *_thread_initial
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL;
+#else
+;
+#endif
+
+/* Default thread attributes: */
+SCLASS struct pthread_attr pthread_attr_default
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY, PTHREAD_CREATE_RUNNING,
+ PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, PTHREAD_STACK_DEFAULT };
+#else
+;
+#endif
+
+/* Default mutex attributes: */
+SCLASS struct pthread_mutex_attr pthread_mutexattr_default
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 };
+#else
+;
+#endif
+
+/* Default condition variable attributes: */
+SCLASS struct pthread_cond_attr pthread_condattr_default
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= { COND_TYPE_FAST, 0 };
+#else
+;
+#endif
+
+/*
+ * Standard I/O file descriptors need special flag treatment since
+ * setting one to non-blocking does all on *BSD. Sigh. This array
+ * is used to store the initial flag settings.
+ */
+SCLASS int _pthread_stdio_flags[3];
+
+/* File table information: */
+SCLASS struct fd_table_entry **_thread_fd_table
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL;
+#else
+;
+#endif
+
+/* Table for polling file descriptors: */
+SCLASS struct pollfd *_thread_pfd_table
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL;
+#else
+;
+#endif
+
+SCLASS const int dtablecount
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 4096/sizeof(struct fd_table_entry);
+#else
+;
+#endif
+SCLASS int _thread_dtablesize /* Descriptor table size. */
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0;
+#else
+;
+#endif
+
+SCLASS int _clock_res_nsec /* Clock resolution in nsec. */
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= CLOCK_RES_NSEC;
+#else
+;
+#endif
+
+/* Garbage collector mutex and condition variable. */
+SCLASS pthread_mutex_t _gc_mutex
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL
+#endif
+;
+SCLASS pthread_cond_t _gc_cond
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL
+#endif
+;
+
+/*
+ * Array of signal actions for this process.
+ */
+SCLASS struct sigaction _thread_sigact[NSIG];
+
+/*
+ * Pending signals for this process.
+ */
+SCLASS sigset_t _process_sigpending;
+
+/*
+ * Scheduling queues:
+ */
+SCLASS pq_queue_t _readyq;
+SCLASS TAILQ_HEAD(, pthread) _waitingq;
+
+/*
+ * Work queue:
+ */
+SCLASS TAILQ_HEAD(, pthread) _workq;
+
+/* Tracks the number of threads blocked while waiting for a spinlock. */
+SCLASS volatile int _spinblock_count
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0
+#endif
+;
+
+/* Indicates that the signal queue needs to be checked. */
+SCLASS volatile int _sigq_check_reqd
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0
+#endif
+;
+
+/* Thread switch hook. */
+SCLASS pthread_switch_routine_t _sched_switch_hook
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL
+#endif
+;
+
+/*
+ * Spare stack queue. Stacks of default size are cached in order to reduce
+ * thread creation time. Spare stacks are used in LIFO order to increase cache
+ * locality.
+ */
+SCLASS SLIST_HEAD(, stack) _stackq;
+
+/* Base address of next unallocated default-size stack. Stacks are allocated
+ * contiguously, starting below the beginning of the main stack. When a new
+ * stack is created, a guard page is created just above it in order to (usually)
+ * detect attempts by the adjacent stack to trounce the next thread stack. */
+SCLASS void * _next_stack
+#ifdef GLOBAL_PTHREAD_PRIVATE
+/* main stack top - main stack size - stack size - (red zone + main stack red zone) */
+= (void *) USRSTACK - PTHREAD_STACK_INITIAL - PTHREAD_STACK_DEFAULT - (2 * PTHREAD_STACK_GUARD)
+#endif
+;
+
+/* Used for _PTHREADS_INVARIANTS checking. */
+SCLASS int _thread_kern_new_state
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0
+#endif
+;
+
+/* Undefine the storage class specifier: */
+#undef SCLASS
+
+#ifdef _LOCK_DEBUG
+#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock_debug(_fd, _type, \
+ _ts, __FILE__, __LINE__)
+#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock_debug(_fd, _type, \
+ __FILE__, __LINE__)
+#else
+#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock(_fd, _type, _ts)
+#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock(_fd, _type)
+#endif
+
+/*
+ * Function prototype definitions.
+ */
+__BEGIN_DECLS
+char *__ttyname_basic(int);
+char *__ttyname_r_basic(int, char *, size_t);
+char *ttyname_r(int, char *, size_t);
+int _find_dead_thread(pthread_t);
+int _find_thread(pthread_t);
+void _funlock_owned(pthread_t);
+int _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t);
+int _thread_fd_lock(int, int, struct timespec *);
+int _thread_fd_lock_debug(int, int, struct timespec *,char *fname,int lineno);
+void _dispatch_signals(void);
+int _mutex_cv_lock(pthread_mutex_t *);
+int _mutex_cv_unlock(pthread_mutex_t *);
+void _mutex_notify_priochange(pthread_t);
+int _mutex_reinit(pthread_mutex_t *);
+void _mutex_unlock_private(pthread_t);
+int _cond_reinit(pthread_cond_t *);
+int _pq_alloc(struct pq_queue *, int, int);
+int _pq_init(struct pq_queue *);
+void _pq_remove(struct pq_queue *pq, struct pthread *);
+void _pq_insert_head(struct pq_queue *pq, struct pthread *);
+void _pq_insert_tail(struct pq_queue *pq, struct pthread *);
+struct pthread *_pq_first(struct pq_queue *pq);
+#if defined(_PTHREADS_INVARIANTS)
+void _waitq_insert(pthread_t pthread);
+void _waitq_remove(pthread_t pthread);
+void _waitq_setactive(void);
+void _waitq_clearactive(void);
+#endif
+void _thread_exit(char *, int, char *);
+void _thread_exit_cleanup(void);
+void _thread_fd_unlock(int, int);
+void _thread_fd_unlock_debug(int, int, char *, int);
+void _thread_fd_unlock_owned(pthread_t);
+void *_thread_cleanup(pthread_t);
+void _thread_cleanupspecific(void);
+void _thread_dump_info(void);
+void _thread_init(void);
+void _thread_kern_sched(ucontext_t *);
+void _thread_kern_sched_state(enum pthread_state,char *fname,int lineno);
+void _thread_kern_sched_state_unlock(enum pthread_state state,
+ spinlock_t *lock, char *fname, int lineno);
+void _thread_kern_set_timeout(struct timespec *);
+void _thread_kern_sig_defer(void);
+void _thread_kern_sig_undefer(void);
+void _thread_sig_handler(int, int, ucontext_t *);
+pthread_t _thread_sig_handle(int, ucontext_t *);
+void _thread_sig_init(void);
+void _thread_sig_send(pthread_t pthread, int sig);
+void _thread_sig_deliver(pthread_t pthread, int sig);
+void _thread_start(void);
+void _thread_start_sig_handler(void);
+void _thread_seterrno(pthread_t,int);
+int _thread_fd_table_init(int fd);
+pthread_addr_t _thread_gc(pthread_addr_t);
+void _thread_enter_cancellation_point(void);
+void _thread_leave_cancellation_point(void);
+void _thread_cancellation_point(void);
+
+/* #include <signal.h> */
+int _thread_sys_sigaction(int, const struct sigaction *, struct sigaction *);
+int _thread_sys_sigpending(sigset_t *);
+int _thread_sys_sigprocmask(int, const sigset_t *, sigset_t *);
+int _thread_sys_sigsuspend(const sigset_t *);
+int _thread_sys_siginterrupt(int, int);
+int _thread_sys_sigpause(int);
+int _thread_sys_sigreturn(ucontext_t *);
+int _thread_sys_sigstack(const struct sigstack *, struct sigstack *);
+int _thread_sys_sigvec(int, struct sigvec *, struct sigvec *);
+void _thread_sys_psignal(unsigned int, const char *);
+void (*_thread_sys_signal(int, void (*)(int)))(int);
+
+/* #include <sys/stat.h> */
+#ifdef _SYS_STAT_H_
+int _thread_sys_fchmod(int, mode_t);
+int _thread_sys_fstat(int, struct stat *);
+int _thread_sys_fchflags(int, u_long);
+#endif
+
+/* #include <sys/mount.h> */
+#ifdef _SYS_MOUNT_H_
+int _thread_sys_fstatfs(int, struct statfs *);
+#endif
+int _thread_sys_pipe(int *);
+
+/* #include <sys/socket.h> */
+#ifdef _SYS_SOCKET_H_
+int _thread_sys_accept(int, struct sockaddr *, int *);
+int _thread_sys_bind(int, const struct sockaddr *, int);
+int _thread_sys_connect(int, const struct sockaddr *, int);
+int _thread_sys_getpeername(int, struct sockaddr *, int *);
+int _thread_sys_getsockname(int, struct sockaddr *, int *);
+int _thread_sys_getsockopt(int, int, int, void *, int *);
+int _thread_sys_listen(int, int);
+int _thread_sys_setsockopt(int, int, int, const void *, int);
+int _thread_sys_shutdown(int, int);
+int _thread_sys_socket(int, int, int);
+int _thread_sys_socketpair(int, int, int, int *);
+ssize_t _thread_sys_recv(int, void *, size_t, int);
+ssize_t _thread_sys_recvfrom(int, void *, size_t, int, struct sockaddr *, int *);
+ssize_t _thread_sys_recvmsg(int, struct msghdr *, int);
+ssize_t _thread_sys_send(int, const void *, size_t, int);
+ssize_t _thread_sys_sendmsg(int, const struct msghdr *, int);
+ssize_t _thread_sys_sendto(int, const void *,size_t, int, const struct sockaddr *, int);
+#endif
+
+/* #include <stdio.h> */
+#ifdef _STDIO_H_
+FILE *_thread_sys_fdopen(int, const char *);
+FILE *_thread_sys_fopen(const char *, const char *);
+FILE *_thread_sys_freopen(const char *, const char *, FILE *);
+FILE *_thread_sys_popen(const char *, const char *);
+FILE *_thread_sys_tmpfile(void);
+char *_thread_sys_ctermid(char *);
+char *_thread_sys_cuserid(char *);
+char *_thread_sys_fgetln(FILE *, size_t *);
+char *_thread_sys_fgets(char *, int, FILE *);
+char *_thread_sys_gets(char *);
+char *_thread_sys_tempnam(const char *, const char *);
+char *_thread_sys_tmpnam(char *);
+int _thread_sys_fclose(FILE *);
+int _thread_sys_feof(FILE *);
+int _thread_sys_ferror(FILE *);
+int _thread_sys_fflush(FILE *);
+int _thread_sys_fgetc(FILE *);
+int _thread_sys_fgetpos(FILE *, fpos_t *);
+int _thread_sys_fileno(FILE *);
+int _thread_sys_fprintf(FILE *, const char *, ...);
+int _thread_sys_fpurge(FILE *);
+int _thread_sys_fputc(int, FILE *);
+int _thread_sys_fputs(const char *, FILE *);
+int _thread_sys_fscanf(FILE *, const char *, ...);
+int _thread_sys_fseek(FILE *, long, int);
+int _thread_sys_fsetpos(FILE *, const fpos_t *);
+int _thread_sys_getc(FILE *);
+int _thread_sys_getchar(void);
+int _thread_sys_getw(FILE *);
+int _thread_sys_pclose(FILE *);
+int _thread_sys_printf(const char *, ...);
+int _thread_sys_putc(int, FILE *);
+int _thread_sys_putchar(int);
+int _thread_sys_puts(const char *);
+int _thread_sys_putw(int, FILE *);
+int _thread_sys_remove(const char *);
+int _thread_sys_rename (const char *, const char *);
+int _thread_sys_scanf(const char *, ...);
+int _thread_sys_setlinebuf(FILE *);
+int _thread_sys_setvbuf(FILE *, char *, int, size_t);
+int _thread_sys_snprintf(char *, size_t, const char *, ...);
+int _thread_sys_sprintf(char *, const char *, ...);
+int _thread_sys_sscanf(const char *, const char *, ...);
+int _thread_sys_ungetc(int, FILE *);
+int _thread_sys_vfprintf(FILE *, const char *, _BSD_VA_LIST_);
+int _thread_sys_vprintf(const char *, _BSD_VA_LIST_);
+int _thread_sys_vscanf(const char *, _BSD_VA_LIST_);
+int _thread_sys_vsnprintf(char *, size_t, const char *, _BSD_VA_LIST_);
+int _thread_sys_vsprintf(char *, const char *, _BSD_VA_LIST_);
+int _thread_sys_vsscanf(const char *, const char *, _BSD_VA_LIST_);
+long _thread_sys_ftell(FILE *);
+size_t _thread_sys_fread(void *, size_t, size_t, FILE *);
+size_t _thread_sys_fwrite(const void *, size_t, size_t, FILE *);
+void _thread_sys_clearerr(FILE *);
+void _thread_sys_perror(const char *);
+void _thread_sys_rewind(FILE *);
+void _thread_sys_setbuf(FILE *, char *);
+void _thread_sys_setbuffer(FILE *, char *, int);
+#endif
+
+/* #include <unistd.h> */
+#ifdef _UNISTD_H_
+char *_thread_sys_ttyname(int);
+int _thread_sys_close(int);
+int _thread_sys_dup(int);
+int _thread_sys_dup2(int, int);
+int _thread_sys_exect(const char *, char * const *, char * const *);
+int _thread_sys_execve(const char *, char * const *, char * const *);
+int _thread_sys_fchdir(int);
+int _thread_sys_fchown(int, uid_t, gid_t);
+int _thread_sys_fsync(int);
+int _thread_sys_ftruncate(int, off_t);
+int _thread_sys_pause(void);
+int _thread_sys_pipe(int *);
+int _thread_sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+off_t _thread_sys_lseek(int, off_t, int);
+pid_t _thread_sys_fork(void);
+pid_t _thread_sys_tcgetpgrp(int);
+ssize_t _thread_sys_read(int, void *, size_t);
+ssize_t _thread_sys_write(int, const void *, size_t);
+void _thread_sys__exit(int);
+#endif
+
+/* #include <fcntl.h> */
+#ifdef _SYS_FCNTL_H_
+int _thread_sys_creat(const char *, mode_t);
+int _thread_sys_fcntl(int, int, ...);
+int _thread_sys_flock(int, int);
+int _thread_sys_open(const char *, int, ...);
+#endif
+
+/* #include <sys/ioctl.h> */
+#ifdef _SYS_IOCTL_H_
+int _thread_sys_ioctl(int, unsigned long, ...);
+#endif
+
+/* #include <dirent.h> */
+#ifdef _DIRENT_H_
+DIR *___thread_sys_opendir2(const char *, int);
+DIR *_thread_sys_opendir(const char *);
+int _thread_sys_alphasort(const void *, const void *);
+int _thread_sys_scandir(const char *, struct dirent ***,
+ int (*)(struct dirent *), int (*)(const void *, const void *));
+int _thread_sys_closedir(DIR *);
+int _thread_sys_getdirentries(int, char *, int, long *);
+long _thread_sys_telldir(const DIR *);
+struct dirent *_thread_sys_readdir(DIR *);
+void _thread_sys_rewinddir(DIR *);
+void _thread_sys_seekdir(DIR *, long);
+#endif
+
+/* #include <sys/uio.h> */
+#ifdef _SYS_UIO_H_
+ssize_t _thread_sys_readv(int, const struct iovec *, int);
+ssize_t _thread_sys_writev(int, const struct iovec *, int);
+#endif
+
+/* #include <sys/wait.h> */
+#ifdef WNOHANG
+pid_t _thread_sys_wait(int *);
+pid_t _thread_sys_waitpid(pid_t, int *, int);
+pid_t _thread_sys_wait3(int *, int, struct rusage *);
+pid_t _thread_sys_wait4(pid_t, int *, int, struct rusage *);
+#endif
+
+/* #include <poll.h> */
+#ifdef _SYS_POLL_H_
+int _thread_sys_poll(struct pollfd *, unsigned, int);
+#endif
+/* #include <sys/mman.h> */
+int _thread_sys_msync(void *, size_t, int);
+__END_DECLS
+
+#endif /* !_PTHREAD_PRIVATE_H */
diff --git a/lib/libc_r/uthread/uthread_accept.c b/lib/libc_r/uthread/uthread_accept.c
new file mode 100644
index 0000000..c703b8c
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_accept.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+accept(int fd, struct sockaddr * name, socklen_t *namelen)
+{
+ int ret;
+
+ /* Lock the file descriptor: */
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ /* Enter a loop to wait for a connection request: */
+ while ((ret = _thread_sys_accept(fd, name, namelen)) < 0) {
+ /* Check if the socket is to block: */
+ if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
+ /* Save the socket file descriptor: */
+ _thread_run->data.fd.fd = fd;
+ _thread_run->data.fd.fname = __FILE__;
+ _thread_run->data.fd.branch = __LINE__;
+
+ /* Set the timeout: */
+ _thread_kern_set_timeout(NULL);
+ _thread_run->interrupted = 0;
+
+ /* Schedule the next thread: */
+ _thread_kern_sched_state(PS_FDR_WAIT, __FILE__, __LINE__);
+
+ /* Check if the wait was interrupted: */
+ if (_thread_run->interrupted) {
+ /* Return an error status: */
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ } else {
+ /*
+ * Another error has occurred, so exit the
+ * loop here:
+ */
+ break;
+ }
+ }
+
+ /* Check for errors: */
+ if (ret < 0) {
+ }
+ /* Initialise the file descriptor table for the new socket: */
+ else if (_thread_fd_table_init(ret) != 0) {
+ /* Quietly close the socket: */
+ _thread_sys_close(ret);
+
+ /* Return an error: */
+ ret = -1;
+ }
+ /*
+ * If the parent socket was blocking, make sure that
+ * the new socket is also set blocking here (as the
+ * call to _thread_fd_table_init() above will always
+ * set the new socket flags to non-blocking, as that
+ * will be the inherited state of the new socket.
+ */
+ if((ret > 0) && (_thread_fd_table[fd]->flags & O_NONBLOCK) == 0)
+ _thread_fd_table[ret]->flags &= ~O_NONBLOCK;
+
+ /* Unlock the file descriptor: */
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ /* Return the socket file descriptor or -1 on error: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_destroy.c b/lib/libc_r/uthread/uthread_attr_destroy.c
new file mode 100644
index 0000000..dfe668e
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_destroy.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_destroy(pthread_attr_t *attr)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL)
+ /* Invalid argument: */
+ ret = EINVAL;
+ else {
+ /* Free the memory allocated to the attribute object: */
+ free(*attr);
+
+ /*
+ * Leave the attribute pointer NULL now that the memory
+ * has been freed:
+ */
+ *attr = NULL;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_getdetachstate.c b/lib/libc_r/uthread/uthread_attr_getdetachstate.c
new file mode 100644
index 0000000..fee1e8b
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_getdetachstate.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || detachstate == NULL)
+ ret = EINVAL;
+ else {
+ /* Check if the detached flag is set: */
+ if ((*attr)->flags & PTHREAD_DETACHED)
+ /* Return detached: */
+ *detachstate = PTHREAD_CREATE_DETACHED;
+ else
+ /* Return joinable: */
+ *detachstate = PTHREAD_CREATE_JOINABLE;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_getinheritsched.c b/lib/libc_r/uthread/uthread_attr_getinheritsched.c
new file mode 100644
index 0000000..7e243ed
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_getinheritsched.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_getinheritsched(const pthread_attr_t *attr, int *sched_inherit)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL))
+ ret = EINVAL;
+ else
+ *sched_inherit = (*attr)->sched_inherit;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_getschedparam.c b/lib/libc_r/uthread/uthread_attr_getschedparam.c
new file mode 100644
index 0000000..46586ff
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_getschedparam.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (param == NULL))
+ ret = EINVAL;
+ else
+ param->sched_priority = (*attr)->prio;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_getschedpolicy.c b/lib/libc_r/uthread/uthread_attr_getschedpolicy.c
new file mode 100644
index 0000000..19f835c
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_getschedpolicy.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (policy == NULL))
+ ret = EINVAL;
+ else
+ *policy = (*attr)->sched_policy;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_getscope.c b/lib/libc_r/uthread/uthread_attr_getscope.c
new file mode 100644
index 0000000..176f01b
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_getscope.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (contentionscope == NULL))
+ /* Return an invalid argument: */
+ ret = EINVAL;
+
+ else
+ *contentionscope = (*attr)->flags & PTHREAD_SCOPE_SYSTEM ?
+ PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_getstackaddr.c b/lib/libc_r/uthread/uthread_attr_getstackaddr.c
new file mode 100644
index 0000000..1fee4a5
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_getstackaddr.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || stackaddr == NULL)
+ ret = EINVAL;
+ else {
+ /* Return the stack address: */
+ *stackaddr = (*attr)->stackaddr_attr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_getstacksize.c b/lib/libc_r/uthread/uthread_attr_getstacksize.c
new file mode 100644
index 0000000..5c7a9e0
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_getstacksize.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || stacksize == NULL)
+ ret = EINVAL;
+ else {
+ /* Return the stack size: */
+ *stacksize = (*attr)->stacksize_attr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_init.c b/lib/libc_r/uthread/uthread_attr_init.c
new file mode 100644
index 0000000..dbe3091
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_init.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_init(pthread_attr_t *attr)
+{
+ int ret;
+ pthread_attr_t pattr;
+
+ /* Allocate memory for the attribute object: */
+ if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL)
+ /* Insufficient memory: */
+ ret = ENOMEM;
+ else {
+ /* Initialise the attribute object with the defaults: */
+ memcpy(pattr, &pthread_attr_default, sizeof(struct pthread_attr));
+
+ /* Return a pointer to the attribute object: */
+ *attr = pattr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_setcreatesuspend_np.c b/lib/libc_r/uthread/uthread_attr_setcreatesuspend_np.c
new file mode 100644
index 0000000..d230397
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_setcreatesuspend_np.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setcreatesuspend_np(pthread_attr_t *attr)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->suspend = PTHREAD_CREATE_SUSPENDED;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_setdetachstate.c b/lib/libc_r/uthread/uthread_attr_setdetachstate.c
new file mode 100644
index 0000000..36a846a
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_setdetachstate.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL ||
+ (detachstate != PTHREAD_CREATE_DETACHED &&
+ detachstate != PTHREAD_CREATE_JOINABLE))
+ ret = EINVAL;
+ else {
+ /* Check if detached state: */
+ if (detachstate == PTHREAD_CREATE_DETACHED)
+ /* Set the detached flag: */
+ (*attr)->flags |= PTHREAD_DETACHED;
+ else
+ /* Reset the detached flag: */
+ (*attr)->flags &= ~PTHREAD_DETACHED;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_setinheritsched.c b/lib/libc_r/uthread/uthread_attr_setinheritsched.c
new file mode 100644
index 0000000..eb2384b
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_setinheritsched.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setinheritsched(pthread_attr_t *attr, int sched_inherit)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL))
+ ret = EINVAL;
+ else
+ (*attr)->sched_inherit = sched_inherit;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_setprio.c b/lib/libc_r/uthread/uthread_attr_setprio.c
new file mode 100644
index 0000000..4bd6b66
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_setprio.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_setprio(pthread_attr_t *attr, int priority)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->prio = priority;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_setschedparam.c b/lib/libc_r/uthread/uthread_attr_setschedparam.c
new file mode 100644
index 0000000..17b93b4
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_setschedparam.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param *param)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (param == NULL))
+ ret = EINVAL;
+ else
+ (*attr)->prio = param->sched_priority;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_setschedpolicy.c b/lib/libc_r/uthread/uthread_attr_setschedpolicy.c
new file mode 100644
index 0000000..640cb38
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_setschedpolicy.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (policy < SCHED_FIFO) ||
+ (policy > SCHED_RR))
+ ret = EINVAL;
+ else
+ (*attr)->sched_policy = policy;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_setscope.c b/lib/libc_r/uthread/uthread_attr_setscope.c
new file mode 100644
index 0000000..84239d7
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_setscope.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) ||
+ (contentionscope != PTHREAD_SCOPE_PROCESS) ||
+ (contentionscope != PTHREAD_SCOPE_SYSTEM))
+ /* Return an invalid argument: */
+ ret = EINVAL;
+
+ else if (contentionscope == PTHREAD_SCOPE_SYSTEM)
+ /* We don't support system wide contention: */
+#ifdef NOT_YET
+ ret = ENOTSUP;
+#else
+ ret = EOPNOTSUPP;
+#endif
+
+ else
+ (*attr)->flags |= contentionscope;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_setstackaddr.c b/lib/libc_r/uthread/uthread_attr_setstackaddr.c
new file mode 100644
index 0000000..7eb8c5d
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_setstackaddr.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || stackaddr == NULL)
+ ret = EINVAL;
+ else {
+ /* Save the stack address: */
+ (*attr)->stackaddr_attr = stackaddr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_attr_setstacksize.c b/lib/libc_r/uthread/uthread_attr_setstacksize.c
new file mode 100644
index 0000000..2a2d854
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_attr_setstacksize.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN)
+ ret = EINVAL;
+ else {
+ /* Save the stack size: */
+ (*attr)->stacksize_attr = stacksize;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_autoinit.cc b/lib/libc_r/uthread/uthread_autoinit.cc
new file mode 100644
index 0000000..033f01f
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_autoinit.cc
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/*
+ * This module uses the magic of C++ static constructors to initialize the
+ * threads package at program start-up time.
+ *
+ * Note: Because of a bug in certain versions of "/usr/lib/c++rt0.o", you
+ * should _not_ enclose the body of this module in an "#ifdef _THREAD_SAFE"
+ * conditional.
+ */
+
+extern "C" void _thread_init(void);
+
+/*
+ * First, we declare a class with a constructor.
+ */
+class _thread_init_invoker {
+public:
+ _thread_init_invoker(); /* Constructor declaration. */
+};
+
+/*
+ * Here is the definition of the constructor. All it does is call the
+ * threads initialization function, "_thread_init".
+ */
+_thread_init_invoker::_thread_init_invoker()
+{
+ _thread_init();
+}
+
+/*
+ * Here is a single, static instance of our "_thread_init_invoker" class.
+ * The mere existance of this instance will result in its constructor
+ * being called, automatically, at program start-up time.
+ */
+static _thread_init_invoker the_thread_init_invoker;
+
+/*
+ * For the shared version of the threads library, the above is sufficient.
+ * But for the archive version of the library, we need a little bit more.
+ * Namely, we must arrange for this particular module to be pulled in from
+ * the archive library at link time. To accomplish that, we define and
+ * initialize a variable, "_thread_autoinit_dummy_decl". This variable is
+ * referenced (as an extern) from libc/stdlib/exit.c. This will always
+ * create a need for this module, ensuring that it is present in the
+ * executable.
+ *
+ * We know that, if the user does _anything_ at all with threads, then the
+ * "uthread_init.c" module will be linked in. That is the case because
+ * "uthread_init.c" is the module that defines all of the global variables
+ * used by the threads library. The presence of "uthread_init.c" will, in
+ * turn, force this module to be linked in. And the presence of this module
+ * in the executable will result in the constructor being invoked, and
+ * "_thread_init" being called.
+ */
+extern "C" int _thread_autoinit_dummy_decl; /* Declare with "C" linkage */
+int _thread_autoinit_dummy_decl = 0;
diff --git a/lib/libc_r/uthread/uthread_bind.c b/lib/libc_r/uthread/uthread_bind.c
new file mode 100644
index 0000000..e6989a0
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_bind.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+bind(int fd, const struct sockaddr * name, socklen_t namelen)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ ret = _thread_sys_bind(fd, name, namelen);
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_cancel.c b/lib/libc_r/uthread/uthread_cancel.c
new file mode 100644
index 0000000..de7c491
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_cancel.c
@@ -0,0 +1,188 @@
+/*
+ * David Leonard <d@openbsd.org>, 1999. Public domain.
+ * $FreeBSD$
+ */
+
+#include <sys/errno.h>
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_cancel(pthread_t pthread)
+{
+ int ret;
+
+ if ((ret = _find_thread(pthread)) != 0) {
+ /* NOTHING */
+ } else if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK) {
+ ret = 0;
+ } else {
+ /* Protect the scheduling queues: */
+ _thread_kern_sig_defer();
+
+ if (((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) != 0) ||
+ (((pthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) == 0) &&
+ ((pthread->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0)))
+ /* Just mark it for cancellation: */
+ pthread->cancelflags |= PTHREAD_CANCELLING;
+ else {
+ /*
+ * Check if we need to kick it back into the
+ * run queue:
+ */
+ switch (pthread->state) {
+ case PS_RUNNING:
+ /* No need to resume: */
+ pthread->cancelflags |= PTHREAD_CANCELLING;
+ break;
+
+ case PS_SPINBLOCK:
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Remove these threads from the work queue: */
+ if ((pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ != 0)
+ PTHREAD_WORKQ_REMOVE(pthread);
+ /* Fall through: */
+ case PS_SIGTHREAD:
+ case PS_SLEEP_WAIT:
+ case PS_WAIT_WAIT:
+ case PS_SIGSUSPEND:
+ case PS_SIGWAIT:
+ case PS_SUSPENDED:
+ /* Interrupt and resume: */
+ pthread->interrupted = 1;
+ pthread->cancelflags |= PTHREAD_CANCELLING;
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ break;
+
+ case PS_MUTEX_WAIT:
+ case PS_COND_WAIT:
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ case PS_JOIN:
+ /*
+ * Threads in these states may be in queues.
+ * In order to preserve queue integrity, the
+ * cancelled thread must remove itself from the
+ * queue. Mark the thread as interrupted and
+ * needing cancellation, and set the state to
+ * running. When the thread resumes, it will
+ * exit after removing itself from the queue.
+ */
+ pthread->interrupted = 1;
+ pthread->cancelflags |= PTHREAD_CANCEL_NEEDED;
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ break;
+
+ case PS_DEAD:
+ case PS_DEADLOCK:
+ case PS_STATE_MAX:
+ /* Ignore - only here to silence -Wall: */
+ break;
+ }
+ }
+
+ /* Unprotect the scheduling queues: */
+ _thread_kern_sig_undefer();
+
+ ret = 0;
+ }
+ return (ret);
+}
+
+int
+pthread_setcancelstate(int state, int *oldstate)
+{
+ int ostate;
+ int ret;
+
+ ostate = _thread_run->cancelflags & PTHREAD_CANCEL_DISABLE;
+
+ switch (state) {
+ case PTHREAD_CANCEL_ENABLE:
+ if (oldstate != NULL)
+ *oldstate = ostate;
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_DISABLE;
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)
+ pthread_testcancel();
+ ret = 0;
+ break;
+ case PTHREAD_CANCEL_DISABLE:
+ if (oldstate != NULL)
+ *oldstate = ostate;
+ _thread_run->cancelflags |= PTHREAD_CANCEL_DISABLE;
+ ret = 0;
+ break;
+ default:
+ ret = EINVAL;
+ }
+
+ return (ret);
+}
+
+int
+pthread_setcanceltype(int type, int *oldtype)
+{
+ int otype;
+ int ret;
+
+ otype = _thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS;
+ switch (type) {
+ case PTHREAD_CANCEL_ASYNCHRONOUS:
+ if (oldtype != NULL)
+ *oldtype = otype;
+ _thread_run->cancelflags |= PTHREAD_CANCEL_ASYNCHRONOUS;
+ pthread_testcancel();
+ ret = 0;
+ break;
+ case PTHREAD_CANCEL_DEFERRED:
+ if (oldtype != NULL)
+ *oldtype = otype;
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_ASYNCHRONOUS;
+ ret = 0;
+ break;
+ default:
+ ret = EINVAL;
+ }
+
+ return (ret);
+}
+
+void
+pthread_testcancel(void)
+{
+ if (((_thread_run->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) &&
+ ((_thread_run->cancelflags & PTHREAD_CANCELLING) != 0)) {
+ /*
+ * It is possible for this thread to be swapped out
+ * while performing cancellation; do not allow it
+ * to be cancelled again.
+ */
+ _thread_run->cancelflags &= ~PTHREAD_CANCELLING;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ PANIC("cancel");
+ }
+}
+
+void
+_thread_enter_cancellation_point(void)
+{
+
+ /* Look for a cancellation before we block: */
+ pthread_testcancel();
+ _thread_run->cancelflags |= PTHREAD_AT_CANCEL_POINT;
+}
+
+void
+_thread_leave_cancellation_point(void)
+{
+
+ _thread_run->cancelflags &= ~PTHREAD_AT_CANCEL_POINT;
+ /* Look for a cancellation after we unblock: */
+ pthread_testcancel();
+}
diff --git a/lib/libc_r/uthread/uthread_clean.c b/lib/libc_r/uthread/uthread_clean.c
new file mode 100644
index 0000000..bba5500
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_clean.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#include <stdlib.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+void
+pthread_cleanup_push(void (*routine) (void *), void *routine_arg)
+{
+ struct pthread_cleanup *new;
+
+ if ((new = (struct pthread_cleanup *) malloc(sizeof(struct pthread_cleanup))) != NULL) {
+ new->routine = routine;
+ new->routine_arg = routine_arg;
+ new->next = _thread_run->cleanup;
+
+ _thread_run->cleanup = new;
+ }
+}
+
+void
+pthread_cleanup_pop(int execute)
+{
+ struct pthread_cleanup *old;
+
+ if ((old = _thread_run->cleanup) != NULL) {
+ _thread_run->cleanup = old->next;
+ if (execute) {
+ old->routine(old->routine_arg);
+ }
+ free(old);
+ }
+}
+
+#endif
diff --git a/lib/libc_r/uthread/uthread_close.c b/lib/libc_r/uthread/uthread_close.c
new file mode 100644
index 0000000..2580fce
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_close.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+close(int fd)
+{
+ int flags;
+ int ret;
+ struct stat sb;
+ struct fd_table_entry *entry;
+
+ _thread_enter_cancellation_point();
+
+ if ((fd == _thread_kern_pipe[0]) || (fd == _thread_kern_pipe[1])) {
+ /*
+ * Don't allow silly programs to close the kernel pipe.
+ */
+ errno = EBADF;
+ ret = -1;
+ }
+ /*
+ * Lock the file descriptor while the file is closed and get
+ * the file descriptor status:
+ */
+ else if (((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) &&
+ ((ret = _thread_sys_fstat(fd, &sb)) == 0)) {
+ /*
+ * Check if the file should be left as blocking.
+ *
+ * This is so that the file descriptors shared with a parent
+ * process aren't left set to non-blocking if the child
+ * closes them prior to exit. An example where this causes
+ * problems with /bin/sh is when a child closes stdin.
+ *
+ * Setting a file as blocking causes problems if a threaded
+ * parent accesses the file descriptor before the child exits.
+ * Once the threaded parent receives a SIGCHLD then it resets
+ * all of its files to non-blocking, and so it is then safe
+ * to access them.
+ *
+ * Pipes are not set to blocking when they are closed, as
+ * the parent and child will normally close the file
+ * descriptor of the end of the pipe that they are not
+ * using, which would then cause any reads to block
+ * indefinitely.
+ */
+ if ((S_ISREG(sb.st_mode) || S_ISCHR(sb.st_mode)) && (_thread_fd_table[fd]->flags & O_NONBLOCK) == 0) {
+ /* Get the current flags: */
+ flags = _thread_sys_fcntl(fd, F_GETFL, NULL);
+ /* Clear the nonblocking file descriptor flag: */
+ _thread_sys_fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+ }
+
+ /* XXX: Assumes well behaved threads. */
+ /* XXX: Defer real close to avoid race condition */
+ entry = _thread_fd_table[fd];
+ _thread_fd_table[fd] = NULL;
+ free(entry);
+
+ /* Close the file descriptor: */
+ ret = _thread_sys_close(fd);
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_cond.c b/lib/libc_r/uthread/uthread_cond.c
new file mode 100644
index 0000000..3e215af
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_cond.c
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/*
+ * Prototypes
+ */
+static inline pthread_t cond_queue_deq(pthread_cond_t);
+static inline void cond_queue_remove(pthread_cond_t, pthread_t);
+static inline void cond_queue_enq(pthread_cond_t, pthread_t);
+
+/* Reinitialize a condition variable to defaults. */
+int
+_cond_reinit(pthread_cond_t * cond)
+{
+ int ret = 0;
+
+ if (cond == NULL)
+ ret = EINVAL;
+ else if (*cond == NULL)
+ ret = pthread_cond_init(cond, NULL);
+ else {
+ /*
+ * Initialize the condition variable structure:
+ */
+ TAILQ_INIT(&(*cond)->c_queue);
+ (*cond)->c_flags = COND_FLAGS_INITED;
+ (*cond)->c_type = COND_TYPE_FAST;
+ (*cond)->c_mutex = NULL;
+ memset(&(*cond)->lock, 0, sizeof((*cond)->lock));
+ }
+ return (ret);
+}
+
+int
+pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t * cond_attr)
+{
+ enum pthread_cond_type type;
+ pthread_cond_t pcond;
+ int rval = 0;
+
+ if (cond == NULL)
+ rval = EINVAL;
+ else {
+ /*
+ * Check if a pointer to a condition variable attribute
+ * structure was passed by the caller:
+ */
+ if (cond_attr != NULL && *cond_attr != NULL) {
+ /* Default to a fast condition variable: */
+ type = (*cond_attr)->c_type;
+ } else {
+ /* Default to a fast condition variable: */
+ type = COND_TYPE_FAST;
+ }
+
+ /* Process according to condition variable type: */
+ switch (type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ /* Nothing to do here. */
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ /* Check for no errors: */
+ if (rval == 0) {
+ if ((pcond = (pthread_cond_t)
+ malloc(sizeof(struct pthread_cond))) == NULL) {
+ rval = ENOMEM;
+ } else {
+ /*
+ * Initialise the condition variable
+ * structure:
+ */
+ TAILQ_INIT(&pcond->c_queue);
+ pcond->c_flags |= COND_FLAGS_INITED;
+ pcond->c_type = type;
+ pcond->c_mutex = NULL;
+ memset(&pcond->lock,0,sizeof(pcond->lock));
+ *cond = pcond;
+ }
+ }
+ }
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_destroy(pthread_cond_t * cond)
+{
+ int rval = 0;
+
+ if (cond == NULL || *cond == NULL)
+ rval = EINVAL;
+ else {
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /*
+ * Free the memory allocated for the condition
+ * variable structure:
+ */
+ free(*cond);
+
+ /*
+ * NULL the caller's pointer now that the condition
+ * variable has been destroyed:
+ */
+ *cond = NULL;
+ }
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
+{
+ int rval = 0;
+
+ if (cond == NULL)
+ rval = EINVAL;
+
+ /*
+ * If the condition variable is statically initialized,
+ * perform the dynamic initialization:
+ */
+ else if (*cond != NULL ||
+ (rval = pthread_cond_init(cond,NULL)) == 0) {
+
+ _thread_enter_cancellation_point();
+
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /*
+ * If the condvar was statically allocated, properly
+ * initialize the tail queue.
+ */
+ if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) {
+ TAILQ_INIT(&(*cond)->c_queue);
+ (*cond)->c_flags |= COND_FLAGS_INITED;
+ }
+
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ if ((mutex == NULL) || (((*cond)->c_mutex != NULL) &&
+ ((*cond)->c_mutex != *mutex))) {
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /* Return invalid argument error: */
+ rval = EINVAL;
+ } else {
+ /* Reset the timeout and interrupted flags: */
+ _thread_run->timeout = 0;
+ _thread_run->interrupted = 0;
+
+ /*
+ * Queue the running thread for the condition
+ * variable:
+ */
+ cond_queue_enq(*cond, _thread_run);
+
+ /* Remember the mutex that is being used: */
+ (*cond)->c_mutex = *mutex;
+
+ /* Wait forever: */
+ _thread_run->wakeup_time.tv_sec = -1;
+
+ /* Unlock the mutex: */
+ if ((rval = _mutex_cv_unlock(mutex)) != 0) {
+ /*
+ * Cannot unlock the mutex, so remove
+ * the running thread from the condition
+ * variable queue:
+ */
+ cond_queue_remove(*cond, _thread_run);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) ==
+ NULL)
+ (*cond)->c_mutex = NULL;
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+ }
+ else {
+ /*
+ * Schedule the next thread and unlock
+ * the condition variable structure:
+ */
+ _thread_kern_sched_state_unlock(PS_COND_WAIT,
+ &(*cond)->lock, __FILE__, __LINE__);
+
+ if (_thread_run->interrupted != 0) {
+ /*
+ * Lock the condition variable
+ * while removing the thread.
+ */
+ _SPINLOCK(&(*cond)->lock);
+
+ cond_queue_remove(*cond,
+ _thread_run);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) == NULL)
+ (*cond)->c_mutex = NULL;
+
+ _SPINUNLOCK(&(*cond)->lock);
+ }
+
+ /*
+ * Note that even though this thread may have
+ * been canceled, POSIX requires that the mutex
+ * be reaquired prior to cancellation.
+ */
+ rval = _mutex_cv_lock(mutex);
+ }
+ }
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+
+ _thread_leave_cancellation_point();
+ }
+
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
+ const struct timespec * abstime)
+{
+ int rval = 0;
+
+ if (cond == NULL || abstime == NULL)
+ rval = EINVAL;
+
+ if (abstime->tv_sec < 0 ||
+ abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /*
+ * If the condition variable is statically initialized,
+ * perform the dynamic initialization:
+ */
+ if (*cond != NULL ||
+ (rval = pthread_cond_init(cond,NULL)) == 0) {
+
+ _thread_enter_cancellation_point();
+
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /*
+ * If the condvar was statically allocated, properly
+ * initialize the tail queue.
+ */
+ if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) {
+ TAILQ_INIT(&(*cond)->c_queue);
+ (*cond)->c_flags |= COND_FLAGS_INITED;
+ }
+
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ if ((mutex == NULL) || (((*cond)->c_mutex != NULL) &&
+ ((*cond)->c_mutex != *mutex))) {
+ /* Return invalid argument error: */
+ rval = EINVAL;
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+ } else {
+ /* Set the wakeup time: */
+ _thread_run->wakeup_time.tv_sec =
+ abstime->tv_sec;
+ _thread_run->wakeup_time.tv_nsec =
+ abstime->tv_nsec;
+
+ /* Reset the timeout and interrupted flags: */
+ _thread_run->timeout = 0;
+ _thread_run->interrupted = 0;
+
+ /*
+ * Queue the running thread for the condition
+ * variable:
+ */
+ cond_queue_enq(*cond, _thread_run);
+
+ /* Remember the mutex that is being used: */
+ (*cond)->c_mutex = *mutex;
+
+ /* Unlock the mutex: */
+ if ((rval = _mutex_cv_unlock(mutex)) != 0) {
+ /*
+ * Cannot unlock the mutex, so remove
+ * the running thread from the condition
+ * variable queue:
+ */
+ cond_queue_remove(*cond, _thread_run);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) == NULL)
+ (*cond)->c_mutex = NULL;
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+ } else {
+ /*
+ * Schedule the next thread and unlock
+ * the condition variable structure:
+ */
+ _thread_kern_sched_state_unlock(PS_COND_WAIT,
+ &(*cond)->lock, __FILE__, __LINE__);
+
+ /*
+ * Check if the wait timedout or was
+ * interrupted (canceled):
+ */
+ if ((_thread_run->timeout == 0) &&
+ (_thread_run->interrupted == 0)) {
+ /* Lock the mutex: */
+ rval = _mutex_cv_lock(mutex);
+
+ } else {
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /*
+ * The wait timed out; remove
+ * the thread from the condition
+ * variable queue:
+ */
+ cond_queue_remove(*cond,
+ _thread_run);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) == NULL)
+ (*cond)->c_mutex = NULL;
+
+ /* Unock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /* Return a timeout error: */
+ rval = ETIMEDOUT;
+
+ /*
+ * Lock the mutex and ignore any
+ * errors. Note that even though
+ * this thread may have been
+ * canceled, POSIX requires that
+ * the mutex be reaquired prior
+ * to cancellation.
+ */
+ (void)_mutex_cv_lock(mutex);
+ }
+ }
+ }
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+
+ _thread_leave_cancellation_point();
+ }
+
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_signal(pthread_cond_t * cond)
+{
+ int rval = 0;
+ pthread_t pthread;
+
+ if (cond == NULL || *cond == NULL)
+ rval = EINVAL;
+ else {
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ if ((pthread = cond_queue_deq(*cond)) != NULL)
+ /* Allow the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) == NULL)
+ (*cond)->c_mutex = NULL;
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_broadcast(pthread_cond_t * cond)
+{
+ int rval = 0;
+ pthread_t pthread;
+
+ if (cond == NULL || *cond == NULL)
+ rval = EINVAL;
+ else {
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ /*
+ * Enter a loop to bring all threads off the
+ * condition queue:
+ */
+ while ((pthread = cond_queue_deq(*cond)) != NULL) {
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ }
+
+ /* There are no more waiting threads: */
+ (*cond)->c_mutex = NULL;
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (rval);
+}
+
+/*
+ * Dequeue a waiting thread from the head of a condition queue in
+ * descending priority order.
+ */
+static inline pthread_t
+cond_queue_deq(pthread_cond_t cond)
+{
+ pthread_t pthread;
+
+ while ((pthread = TAILQ_FIRST(&cond->c_queue)) != NULL) {
+ TAILQ_REMOVE(&cond->c_queue, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_CONDQ;
+ if ((pthread->timeout == 0) && (pthread->interrupted == 0))
+ /*
+ * Only exit the loop when we find a thread
+ * that hasn't timed out or been canceled;
+ * those threads are already running and don't
+ * need their run state changed.
+ */
+ break;
+ }
+
+ return(pthread);
+}
+
+/*
+ * Remove a waiting thread from a condition queue in descending priority
+ * order.
+ */
+static inline void
+cond_queue_remove(pthread_cond_t cond, pthread_t pthread)
+{
+ /*
+ * Because pthread_cond_timedwait() can timeout as well
+ * as be signaled by another thread, it is necessary to
+ * guard against removing the thread from the queue if
+ * it isn't in the queue.
+ */
+ if (pthread->flags & PTHREAD_FLAGS_IN_CONDQ) {
+ TAILQ_REMOVE(&cond->c_queue, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_CONDQ;
+ }
+}
+
+/*
+ * Enqueue a waiting thread to a condition queue in descending priority
+ * order.
+ */
+static inline void
+cond_queue_enq(pthread_cond_t cond, pthread_t pthread)
+{
+ pthread_t tid = TAILQ_LAST(&cond->c_queue, cond_head);
+
+ /*
+ * For the common case of all threads having equal priority,
+ * we perform a quick check against the priority of the thread
+ * at the tail of the queue.
+ */
+ if ((tid == NULL) || (pthread->active_priority <= tid->active_priority))
+ TAILQ_INSERT_TAIL(&cond->c_queue, pthread, qe);
+ else {
+ tid = TAILQ_FIRST(&cond->c_queue);
+ while (pthread->active_priority <= tid->active_priority)
+ tid = TAILQ_NEXT(tid, qe);
+ TAILQ_INSERT_BEFORE(tid, pthread, qe);
+ }
+ pthread->flags |= PTHREAD_FLAGS_IN_CONDQ;
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_condattr_destroy.c b/lib/libc_r/uthread/uthread_condattr_destroy.c
new file mode 100644
index 0000000..ad91228
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_condattr_destroy.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_condattr_destroy(pthread_condattr_t *attr)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ ret = EINVAL;
+ } else {
+ free(*attr);
+ *attr = NULL;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_condattr_init.c b/lib/libc_r/uthread/uthread_condattr_init.c
new file mode 100644
index 0000000..3379898
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_condattr_init.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_condattr_init(pthread_condattr_t *attr)
+{
+ int ret;
+ pthread_condattr_t pattr;
+
+ if ((pattr = (pthread_condattr_t)
+ malloc(sizeof(struct pthread_cond_attr))) == NULL) {
+ ret = ENOMEM;
+ } else {
+ memcpy(pattr, &pthread_condattr_default,
+ sizeof(struct pthread_cond_attr));
+ *attr = pattr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_connect.c b/lib/libc_r/uthread/uthread_connect.c
new file mode 100644
index 0000000..7c60f63
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_connect.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+connect(int fd, const struct sockaddr * name, socklen_t namelen)
+{
+ struct sockaddr tmpname;
+ int errnolen, ret, tmpnamelen;
+
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ if ((ret = _thread_sys_connect(fd, name, namelen)) < 0) {
+ if (!(_thread_fd_table[fd]->flags & O_NONBLOCK) &&
+ ((errno == EWOULDBLOCK) || (errno == EINPROGRESS) ||
+ (errno == EALREADY) || (errno == EAGAIN))) {
+ _thread_run->data.fd.fd = fd;
+
+ /* Set the timeout: */
+ _thread_kern_set_timeout(NULL);
+ _thread_kern_sched_state(PS_FDW_WAIT, __FILE__, __LINE__);
+
+ tmpnamelen = sizeof(tmpname);
+ /* 0 now lets see if it really worked */
+ if (((ret = _thread_sys_getpeername(fd, &tmpname, &tmpnamelen)) < 0) && (errno == ENOTCONN)) {
+
+ /*
+ * Get the error, this function
+ * should not fail
+ */
+ errnolen = sizeof(errno);
+ _thread_sys_getsockopt(fd, SOL_SOCKET, SO_ERROR, &errno, &errnolen);
+ }
+ } else {
+ ret = -1;
+ }
+ }
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_create.c b/lib/libc_r/uthread/uthread_create.c
new file mode 100644
index 0000000..8621c05
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_create.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/mman.h>
+#ifdef _THREAD_SAFE
+#include <machine/reg.h>
+#include <pthread.h>
+#include "pthread_private.h"
+#include "libc_private.h"
+
+static u_int64_t next_uniqueid = 1;
+
+#define OFF(f) offsetof(struct pthread, f)
+int _thread_next_offset = OFF(tle.tqe_next);
+int _thread_uniqueid_offset = OFF(uniqueid);
+int _thread_state_offset = OFF(state);
+int _thread_name_offset = OFF(name);
+int _thread_sig_saved_offset = OFF(sig_saved);
+int _thread_saved_sigcontext_offset = OFF(saved_sigcontext);
+int _thread_saved_jmp_buf_offset = OFF(saved_jmp_buf);
+#undef OFF
+
+int _thread_PS_RUNNING_value = PS_RUNNING;
+int _thread_PS_DEAD_value = PS_DEAD;
+
+int
+pthread_create(pthread_t * thread, const pthread_attr_t * attr,
+ void *(*start_routine) (void *), void *arg)
+{
+ int f_gc = 0;
+ int ret = 0;
+ pthread_t gc_thread;
+ pthread_t new_thread;
+ pthread_attr_t pattr;
+ void *stack;
+
+ /*
+ * Locking functions in libc are required when there are
+ * threads other than the initial thread.
+ */
+ __isthreaded = 1;
+
+ /* Allocate memory for the thread structure: */
+ if ((new_thread = (pthread_t) malloc(sizeof(struct pthread))) == NULL) {
+ /* Insufficient memory to create a thread: */
+ ret = EAGAIN;
+ } else {
+ /* Check if default thread attributes are required: */
+ if (attr == NULL || *attr == NULL) {
+ /* Use the default thread attributes: */
+ pattr = &pthread_attr_default;
+ } else {
+ pattr = *attr;
+ }
+ /* Check if a stack was specified in the thread attributes: */
+ if ((stack = pattr->stackaddr_attr) != NULL) {
+ }
+ /* Allocate memory for a default-size stack: */
+ else if (pattr->stacksize_attr == PTHREAD_STACK_DEFAULT) {
+ struct stack *spare_stack;
+
+ /* Allocate or re-use a default-size stack. */
+
+ /*
+ * Use the garbage collector mutex for synchronization
+ * of the spare stack list.
+ */
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ if ((spare_stack = SLIST_FIRST(&_stackq)) != NULL) {
+ /* Use the spare stack. */
+ SLIST_REMOVE_HEAD(&_stackq, qe);
+
+ /* Unlock the garbage collector mutex. */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
+
+ stack = sizeof(struct stack)
+ + (void *) spare_stack
+ - PTHREAD_STACK_DEFAULT;
+ } else {
+ /* Unlock the garbage collector mutex. */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
+
+ /* Allocate a new stack. */
+ stack = _next_stack + PTHREAD_STACK_GUARD;
+ /*
+ * Even if stack allocation fails, we don't want
+ * to try to use this location again, so
+ * unconditionally decrement _next_stack. Under
+ * normal operating conditions, the most likely
+ * reason for an mmap() error is a stack
+ * overflow of the adjacent thread stack.
+ */
+ _next_stack -= (PTHREAD_STACK_DEFAULT
+ + PTHREAD_STACK_GUARD);
+
+ /* Red zone: */
+ if (mmap(_next_stack, PTHREAD_STACK_GUARD, 0,
+ MAP_ANON, -1, 0) == MAP_FAILED) {
+ ret = EAGAIN;
+ free(new_thread);
+ }
+ /* Stack: */
+ else if (mmap(stack,
+ PTHREAD_STACK_DEFAULT,
+ PROT_READ | PROT_WRITE,
+ MAP_STACK,
+ -1, 0) == MAP_FAILED) {
+ ret = EAGAIN;
+ munmap(_next_stack,
+ PTHREAD_STACK_GUARD);
+ free(new_thread);
+ }
+ }
+ }
+ /*
+ * The user wants a stack of a particular size. Lets hope they
+ * really know what they want, and simply malloc the stack.
+ */
+ else if ((stack = (void *) malloc(pattr->stacksize_attr))
+ == NULL) {
+ /* Insufficient memory to create a thread: */
+ ret = EAGAIN;
+ free(new_thread);
+ }
+
+ /* Check for errors: */
+ if (ret != 0) {
+ } else {
+ /* Initialise the thread structure: */
+ memset(new_thread, 0, sizeof(struct pthread));
+ new_thread->slice_usec = -1;
+ new_thread->sig_saved = 0;
+ new_thread->stack = stack;
+ new_thread->start_routine = start_routine;
+ new_thread->arg = arg;
+
+ new_thread->cancelflags = PTHREAD_CANCEL_ENABLE |
+ PTHREAD_CANCEL_DEFERRED;
+
+ /*
+ * Write a magic value to the thread structure
+ * to help identify valid ones:
+ */
+ new_thread->magic = PTHREAD_MAGIC;
+
+ /* Initialise the thread for signals: */
+ new_thread->sigmask = _thread_run->sigmask;
+
+ /* Initialise the jump buffer: */
+ setjmp(new_thread->saved_jmp_buf);
+
+ /*
+ * Set up new stack frame so that it looks like it
+ * returned from a longjmp() to the beginning of
+ * _thread_start().
+ */
+#if defined(__FreeBSD__)
+#if defined(__alpha__)
+ new_thread->saved_jmp_buf[0]._jb[2] = (long) _thread_start;
+ new_thread->saved_jmp_buf[0]._jb[4 + R_RA] = 0;
+ new_thread->saved_jmp_buf[0]._jb[4 + R_T12] = (long) _thread_start;
+#else
+ new_thread->saved_jmp_buf[0]._jb[0] = (long) _thread_start;
+#endif
+#elif defined(__NetBSD__)
+#if defined(__alpha__)
+ new_thread->saved_jmp_buf[2] = (long) _thread_start;
+ new_thread->saved_jmp_buf[4 + R_RA] = 0;
+ new_thread->saved_jmp_buf[4 + R_T12] = (long) _thread_start;
+#else
+ new_thread->saved_jmp_buf[0] = (long) _thread_start;
+#endif
+#else
+#error "Don't recognize this operating system!"
+#endif
+
+ /* The stack starts high and builds down: */
+#if defined(__FreeBSD__)
+#if defined(__alpha__)
+ new_thread->saved_jmp_buf[0]._jb[4 + R_SP] = (long) new_thread->stack + pattr->stacksize_attr - sizeof(double);
+#else
+ new_thread->saved_jmp_buf[0]._jb[2] = (int) (new_thread->stack + pattr->stacksize_attr - sizeof(double));
+#endif
+#elif defined(__NetBSD__)
+#if defined(__alpha__)
+ new_thread->saved_jmp_buf[4 + R_SP] = (long) new_thread->stack + pattr->stacksize_attr - sizeof(double);
+#else
+ new_thread->saved_jmp_buf[2] = (long) new_thread->stack + pattr->stacksize_attr - sizeof(double);
+#endif
+#else
+#error "Don't recognize this operating system!"
+#endif
+
+ /* Copy the thread attributes: */
+ memcpy(&new_thread->attr, pattr, sizeof(struct pthread_attr));
+
+ /*
+ * Check if this thread is to inherit the scheduling
+ * attributes from its parent:
+ */
+ if (new_thread->attr.flags & PTHREAD_INHERIT_SCHED) {
+ /* Copy the scheduling attributes: */
+ new_thread->base_priority
+ = _thread_run->base_priority;
+ new_thread->attr.prio
+ = _thread_run->base_priority;
+ new_thread->attr.sched_policy
+ = _thread_run->attr.sched_policy;
+ } else {
+ /*
+ * Use just the thread priority, leaving the
+ * other scheduling attributes as their
+ * default values:
+ */
+ new_thread->base_priority
+ = new_thread->attr.prio;
+ }
+ new_thread->active_priority = new_thread->base_priority;
+ new_thread->inherited_priority = 0;
+
+ /* Initialise the join queue for the new thread: */
+ TAILQ_INIT(&(new_thread->join_queue));
+
+ /* Initialize the mutex queue: */
+ TAILQ_INIT(&new_thread->mutexq);
+
+ /* Initialise hooks in the thread structure: */
+ new_thread->specific_data = NULL;
+ new_thread->cleanup = NULL;
+ new_thread->flags = 0;
+ new_thread->poll_data.nfds = 0;
+ new_thread->poll_data.fds = NULL;
+
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /*
+ * Initialise the unique id which GDB uses to
+ * track threads.
+ */
+ new_thread->uniqueid = next_uniqueid++;
+
+ /*
+ * Check if the garbage collector thread
+ * needs to be started.
+ */
+ f_gc = (TAILQ_FIRST(&_thread_list) == _thread_initial);
+
+ /* Add the thread to the linked list of all threads: */
+ TAILQ_INSERT_HEAD(&_thread_list, new_thread, tle);
+
+ if (pattr->suspend == PTHREAD_CREATE_SUSPENDED) {
+ new_thread->state = PS_SUSPENDED;
+ PTHREAD_WAITQ_INSERT(new_thread);
+ } else {
+ new_thread->state = PS_RUNNING;
+ PTHREAD_PRIOQ_INSERT_TAIL(new_thread);
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding
+ * if necessary.
+ */
+ _thread_kern_sig_undefer();
+
+ /* Return a pointer to the thread structure: */
+ (*thread) = new_thread;
+
+ /* Schedule the new user thread: */
+ _thread_kern_sched(NULL);
+
+ /*
+ * Start a garbage collector thread
+ * if necessary.
+ */
+ if (f_gc && pthread_create(&gc_thread,NULL,
+ _thread_gc,NULL) != 0)
+ PANIC("Can't create gc thread");
+ }
+ }
+
+ /* Return the status: */
+ return (ret);
+}
+
+void
+_thread_start(void)
+{
+ /* We just left the scheduler via longjmp: */
+ _thread_kern_in_sched = 0;
+
+ /* Run the current thread's start routine with argument: */
+ pthread_exit(_thread_run->start_routine(_thread_run->arg));
+
+ /* This point should never be reached. */
+ PANIC("Thread has resumed after exit");
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_detach.c b/lib/libc_r/uthread/uthread_detach.c
new file mode 100644
index 0000000..164c7df
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_detach.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_detach(pthread_t pthread)
+{
+ int rval = 0;
+ int status;
+ pthread_t next_thread;
+
+ /* Check for invalid calling parameters: */
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+
+ /* Check if the thread has not been detached: */
+ else if ((pthread->attr.flags & PTHREAD_DETACHED) == 0) {
+ /* Flag the thread as detached: */
+ pthread->attr.flags |= PTHREAD_DETACHED;
+
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Enter a loop to bring all threads off the join queue: */
+ while ((next_thread = TAILQ_FIRST(&pthread->join_queue)) != NULL) {
+ /* Remove the thread from the queue: */
+ TAILQ_REMOVE(&pthread->join_queue, next_thread, qe);
+
+ /* Make the thread run: */
+ PTHREAD_NEW_STATE(next_thread,PS_RUNNING);
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding if a
+ * scheduling signal occurred while in the critical region.
+ */
+ _thread_kern_sig_undefer();
+ } else
+ /* Return an error: */
+ rval = EINVAL;
+
+ /* Return the completion status: */
+ return (rval);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_dup.c b/lib/libc_r/uthread/uthread_dup.c
new file mode 100644
index 0000000..e32751a
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_dup.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+dup(int fd)
+{
+ int ret;
+
+ /* Lock the file descriptor: */
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ /* Perform the 'dup' syscall: */
+ if ((ret = _thread_sys_dup(fd)) < 0) {
+ }
+ /* Initialise the file descriptor table entry: */
+ else if (_thread_fd_table_init(ret) != 0) {
+ /* Quietly close the file: */
+ _thread_sys_close(ret);
+
+ /* Reset the file descriptor: */
+ ret = -1;
+ } else {
+ /*
+ * Save the file open flags so that they can be
+ * checked later:
+ */
+ _thread_fd_table[ret]->flags = _thread_fd_table[fd]->flags;
+ }
+
+ /* Unlock the file descriptor: */
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_dup2.c b/lib/libc_r/uthread/uthread_dup2.c
new file mode 100644
index 0000000..2c9e9de
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_dup2.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+dup2(int fd, int newfd)
+{
+ int ret;
+ int newfd_opened;
+
+ /* Check if the file descriptor is out of range: */
+ if (newfd < 0 || newfd >= _thread_dtablesize) {
+ /* Return a bad file descriptor error: */
+ errno = EBADF;
+ ret = -1;
+ }
+
+ /* Lock the file descriptor: */
+ else if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ /* Lock the file descriptor: */
+ if (!(newfd_opened = (_thread_fd_table[newfd] != NULL)) ||
+ (ret = _FD_LOCK(newfd, FD_RDWR, NULL)) == 0) {
+ /* Perform the 'dup2' syscall: */
+ if ((ret = _thread_sys_dup2(fd, newfd)) < 0) {
+ }
+ /* Initialise the file descriptor table entry: */
+ else if (_thread_fd_table_init(ret) != 0) {
+ /* Quietly close the file: */
+ _thread_sys_close(ret);
+
+ /* Reset the file descriptor: */
+ ret = -1;
+ } else {
+ /*
+ * Save the file open flags so that they can
+ * be checked later:
+ */
+ _thread_fd_table[ret]->flags = _thread_fd_table[fd]->flags;
+ }
+
+ /* Unlock the file descriptor: */
+ if (newfd_opened)
+ _FD_UNLOCK(newfd, FD_RDWR);
+ }
+ /* Unlock the file descriptor: */
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_equal.c b/lib/libc_r/uthread/uthread_equal.c
new file mode 100644
index 0000000..e03ba4a
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_equal.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_equal(pthread_t t1, pthread_t t2)
+{
+ /* Compare the two thread pointers: */
+ return (t1 == t2);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_execve.c b/lib/libc_r/uthread/uthread_execve.c
new file mode 100644
index 0000000..32b9e2e
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_execve.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+execve(const char *name, char *const * argv, char *const * envp)
+{
+ int flags;
+ int i;
+ int ret;
+ struct sigaction act;
+ struct sigaction oact;
+ struct itimerval itimer;
+
+ /* Disable the interval timer: */
+ itimer.it_interval.tv_sec = 0;
+ itimer.it_interval.tv_usec = 0;
+ itimer.it_value.tv_sec = 0;
+ itimer.it_value.tv_usec = 0;
+ setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL);
+
+ /* Close the pthread kernel pipe: */
+ _thread_sys_close(_thread_kern_pipe[0]);
+ _thread_sys_close(_thread_kern_pipe[1]);
+
+ /*
+ * Enter a loop to set all file descriptors to blocking
+ * if they were not created as non-blocking:
+ */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /* Check if this file descriptor is in use: */
+ if (_thread_fd_table[i] != NULL &&
+ !(_thread_fd_table[i]->flags & O_NONBLOCK)) {
+ /* Get the current flags: */
+ flags = _thread_sys_fcntl(i, F_GETFL, NULL);
+ /* Clear the nonblocking file descriptor flag: */
+ _thread_sys_fcntl(i, F_SETFL, flags & ~O_NONBLOCK);
+ }
+ }
+
+ /* Enter a loop to adopt the signal actions for the running thread: */
+ for (i = 1; i < NSIG; i++) {
+ /* Check for signals which cannot be caught: */
+ if (i == SIGKILL || i == SIGSTOP) {
+ /* Don't do anything with these signals. */
+ } else {
+ /* Check if ignoring this signal: */
+ if (_thread_sigact[i - 1].sa_handler == SIG_IGN) {
+ /* Continue to ignore this signal: */
+ act.sa_handler = SIG_IGN;
+ } else {
+ /* Use the default handler for this signal: */
+ act.sa_handler = SIG_DFL;
+ }
+
+ /* Copy the mask and flags for this signal: */
+ act.sa_mask = _thread_sigact[i - 1].sa_mask;
+ act.sa_flags = _thread_sigact[i - 1].sa_flags;
+
+ /* Ensure the scheduling signal is masked: */
+ sigaddset(&act.sa_mask, _SCHED_SIGNAL);
+
+ /* Change the signal action for the process: */
+ _thread_sys_sigaction(i, &act, &oact);
+ }
+ }
+
+ /* Set the signal mask: */
+ _thread_sys_sigprocmask(SIG_SETMASK, &_thread_run->sigmask, NULL);
+
+ /* Execute the process: */
+ ret = _thread_sys_execve(name, argv, envp);
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_exit.c b/lib/libc_r/uthread/uthread_exit.c
new file mode 100644
index 0000000..abe4b27
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_exit.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+void _exit(int status)
+{
+ int flags;
+ int i;
+ struct itimerval itimer;
+
+ /* Disable the interval timer: */
+ itimer.it_interval.tv_sec = 0;
+ itimer.it_interval.tv_usec = 0;
+ itimer.it_value.tv_sec = 0;
+ itimer.it_value.tv_usec = 0;
+ setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL);
+
+ /* Close the pthread kernel pipe: */
+ _thread_sys_close(_thread_kern_pipe[0]);
+ _thread_sys_close(_thread_kern_pipe[1]);
+
+ /*
+ * Enter a loop to set all file descriptors to blocking
+ * if they were not created as non-blocking:
+ */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /* Check if this file descriptor is in use: */
+ if (_thread_fd_table[i] != NULL &&
+ !(_thread_fd_table[i]->flags & O_NONBLOCK)) {
+ /* Get the current flags: */
+ flags = _thread_sys_fcntl(i, F_GETFL, NULL);
+ /* Clear the nonblocking file descriptor flag: */
+ _thread_sys_fcntl(i, F_SETFL, flags & ~O_NONBLOCK);
+ }
+ }
+
+ /* Call the _exit syscall: */
+ _thread_sys__exit(status);
+}
+
+void
+_thread_exit(char *fname, int lineno, char *string)
+{
+ char s[256];
+
+ /* Prepare an error message string: */
+ strcpy(s, "Fatal error '");
+ strcat(s, string);
+ strcat(s, "' at line ? ");
+ strcat(s, "in file ");
+ strcat(s, fname);
+ strcat(s, " (errno = ?");
+ strcat(s, ")\n");
+
+ /* Write the string to the standard error file descriptor: */
+ _thread_sys_write(2, s, strlen(s));
+
+ /* Force this process to exit: */
+ /* XXX - Do we want abort to be conditional on _PTHREADS_INVARIANTS? */
+#if defined(_PTHREADS_INVARIANTS)
+ abort();
+#else
+ _exit(1);
+#endif
+}
+
+/*
+ * Only called when a thread is cancelled. It may be more useful
+ * to call it from pthread_exit() if other ways of asynchronous or
+ * abnormal thread termination can be found.
+ */
+void
+_thread_exit_cleanup(void)
+{
+ /*
+ * POSIX states that cancellation/termination of a thread should
+ * not release any visible resources (such as mutexes) and that
+ * it is the applications responsibility. Resources that are
+ * internal to the threads library, including file and fd locks,
+ * are not visible to the application and need to be released.
+ */
+ /* Unlock all owned fd locks: */
+ _thread_fd_unlock_owned(_thread_run);
+
+ /* Unlock all owned file locks: */
+ _funlock_owned(_thread_run);
+
+ /* Unlock all private mutexes: */
+ _mutex_unlock_private(_thread_run);
+
+ /*
+ * This still isn't quite correct because we don't account
+ * for held spinlocks (see libc/stdlib/malloc.c).
+ */
+}
+
+void
+pthread_exit(void *status)
+{
+ pthread_t pthread;
+
+ /* Check if this thread is already in the process of exiting: */
+ if ((_thread_run->flags & PTHREAD_EXITING) != 0) {
+ char msg[128];
+ snprintf(msg, sizeof(msg), "Thread %p has called pthread_exit() from a destructor. POSIX 1003.1 1996 s16.2.5.2 does not allow this!",_thread_run);
+ PANIC(msg);
+ }
+
+ /* Flag this thread as exiting: */
+ _thread_run->flags |= PTHREAD_EXITING;
+
+ /* Save the return value: */
+ _thread_run->ret = status;
+
+ while (_thread_run->cleanup != NULL) {
+ pthread_cleanup_pop(1);
+ }
+
+ if (_thread_run->attr.cleanup_attr != NULL) {
+ _thread_run->attr.cleanup_attr(_thread_run->attr.arg_attr);
+ }
+ /* Check if there is thread specific data: */
+ if (_thread_run->specific_data != NULL) {
+ /* Run the thread-specific data destructors: */
+ _thread_cleanupspecific();
+ }
+
+ /* Free thread-specific poll_data structure, if allocated: */
+ if (_thread_run->poll_data.fds != NULL) {
+ free(_thread_run->poll_data.fds);
+ _thread_run->poll_data.fds = NULL;
+ }
+
+ /*
+ * Defer signals to protect the scheduling queues from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Check if there are any threads joined to this one: */
+ while ((pthread = TAILQ_FIRST(&(_thread_run->join_queue))) != NULL) {
+ /* Remove the thread from the queue: */
+ TAILQ_REMOVE(&_thread_run->join_queue, pthread, qe);
+
+ /* Wake the joined thread and let it detach this thread: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding if necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ /*
+ * Lock the garbage collector mutex to ensure that the garbage
+ * collector is not using the dead thread list.
+ */
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* Add this thread to the list of dead threads. */
+ TAILQ_INSERT_HEAD(&_dead_list, _thread_run, dle);
+
+ /*
+ * Defer signals to protect the scheduling queues from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Remove this thread from the thread list: */
+ TAILQ_REMOVE(&_thread_list, _thread_run, tle);
+
+ /*
+ * Undefer and handle pending signals, yielding if necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ /*
+ * Signal the garbage collector thread that there is something
+ * to clean up.
+ */
+ if (pthread_cond_signal(&_gc_cond) != 0)
+ PANIC("Cannot signal gc cond");
+
+ /*
+ * Mark the thread as dead so it will not return if it
+ * gets context switched out when the mutex is unlocked.
+ */
+ PTHREAD_SET_STATE(_thread_run, PS_DEAD);
+
+ /* Unlock the garbage collector mutex: */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* This this thread will never be re-scheduled. */
+ _thread_kern_sched(NULL);
+
+ /* This point should not be reached. */
+ PANIC("Dead thread has resumed");
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_fchflags.c b/lib/libc_r/uthread/uthread_fchflags.c
new file mode 100644
index 0000000..ec4e747
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_fchflags.c
@@ -0,0 +1,25 @@
+/*
+ * David Leonard <d@openbsd.org>, 1999. Public Domain.
+ *
+ * $OpenBSD: uthread_fchflags.c,v 1.1 1999/01/08 05:42:18 d Exp $
+ * $FreeBSD$
+ */
+
+#include <sys/stat.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+fchflags(int fd, u_long flags)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ ret = _thread_sys_fchflags(fd, flags);
+ _FD_UNLOCK(fd, FD_WRITE);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_fchmod.c b/lib/libc_r/uthread/uthread_fchmod.c
new file mode 100644
index 0000000..536c4b8
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_fchmod.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+fchmod(int fd, mode_t mode)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ ret = _thread_sys_fchmod(fd, mode);
+ _FD_UNLOCK(fd, FD_WRITE);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_fchown.c b/lib/libc_r/uthread/uthread_fchown.c
new file mode 100644
index 0000000..185fb25
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_fchown.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <unistd.h>
+#include <dirent.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+fchown(int fd, uid_t owner, gid_t group)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ ret = _thread_sys_fchown(fd, owner, group);
+ _FD_UNLOCK(fd, FD_WRITE);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_fcntl.c b/lib/libc_r/uthread/uthread_fcntl.c
new file mode 100644
index 0000000..878554c
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_fcntl.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+fcntl(int fd, int cmd,...)
+{
+ int flags = 0;
+ int nonblock;
+ int oldfd;
+ int ret;
+ va_list ap;
+
+ _thread_enter_cancellation_point();
+
+ /* Lock the file descriptor: */
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ /* Initialise the variable argument list: */
+ va_start(ap, cmd);
+
+ /* Process according to file control command type: */
+ switch (cmd) {
+ /* Duplicate a file descriptor: */
+ case F_DUPFD:
+ /*
+ * Get the file descriptor that the caller wants to
+ * use:
+ */
+ oldfd = va_arg(ap, int);
+
+ /* Initialise the file descriptor table entry: */
+ if ((ret = _thread_sys_fcntl(fd, cmd, oldfd)) < 0) {
+ }
+ /* Initialise the file descriptor table entry: */
+ else if (_thread_fd_table_init(ret) != 0) {
+ /* Quietly close the file: */
+ _thread_sys_close(ret);
+
+ /* Reset the file descriptor: */
+ ret = -1;
+ } else {
+ /*
+ * Save the file open flags so that they can
+ * be checked later:
+ */
+ _thread_fd_table[ret]->flags = _thread_fd_table[fd]->flags;
+ }
+ break;
+ case F_SETFD:
+ flags = va_arg(ap, int);
+ ret = _thread_sys_fcntl(fd, cmd, flags);
+ break;
+ case F_GETFD:
+ ret = _thread_sys_fcntl(fd, cmd, 0);
+ break;
+ case F_GETFL:
+ ret = _thread_fd_table[fd]->flags;
+ break;
+ case F_SETFL:
+ /*
+ * Get the file descriptor flags passed by the
+ * caller:
+ */
+ flags = va_arg(ap, int);
+
+ /*
+ * Check if the user wants a non-blocking file
+ * descriptor:
+ */
+ nonblock = flags & O_NONBLOCK;
+
+ /* Set the file descriptor flags: */
+ if ((ret = _thread_sys_fcntl(fd, cmd, flags | O_NONBLOCK)) != 0) {
+
+ /* Get the flags so that we behave like the kernel: */
+ } else if ((flags = _thread_sys_fcntl(fd,
+ F_GETFL, 0)) == -1) {
+ /* Error getting flags: */
+ ret = -1;
+
+ /*
+ * Check if the file descriptor is non-blocking
+ * with respect to the user:
+ */
+ } else if (nonblock)
+ /* A non-blocking descriptor: */
+ _thread_fd_table[fd]->flags = flags | O_NONBLOCK;
+ else
+ /* Save the flags: */
+ _thread_fd_table[fd]->flags = flags & ~O_NONBLOCK;
+ break;
+ default:
+ /* Might want to make va_arg use a union */
+ ret = _thread_sys_fcntl(fd, cmd, va_arg(ap, void *));
+ break;
+ }
+
+ /* Free variable arguments: */
+ va_end(ap);
+
+ /* Unlock the file descriptor: */
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ _thread_leave_cancellation_point();
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_fd.c b/lib/libc_r/uthread/uthread_fd.c
new file mode 100644
index 0000000..d9a1636
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_fd.c
@@ -0,0 +1,946 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+#define FDQ_INSERT(q,p) \
+do { \
+ TAILQ_INSERT_TAIL(q,p,qe); \
+ p->flags |= PTHREAD_FLAGS_IN_FDQ; \
+} while (0)
+
+#define FDQ_REMOVE(q,p) \
+do { \
+ if ((p->flags & PTHREAD_FLAGS_IN_FDQ) != 0) { \
+ TAILQ_REMOVE(q,p,qe); \
+ p->flags &= ~PTHREAD_FLAGS_IN_FDQ; \
+ } \
+} while (0)
+
+
+/* Static variables: */
+static spinlock_t fd_table_lock = _SPINLOCK_INITIALIZER;
+
+/* Prototypes: */
+static inline pthread_t fd_next_reader(int fd);
+static inline pthread_t fd_next_writer(int fd);
+
+
+/*
+ * This function *must* return -1 and set the thread specific errno
+ * as a system call. This is because the error return from this
+ * function is propagated directly back from thread-wrapped system
+ * calls.
+ */
+
+int
+_thread_fd_table_init(int fd)
+{
+ int ret = 0;
+ struct fd_table_entry *entry;
+ int saved_errno;
+
+ /* Check if the file descriptor is out of range: */
+ if (fd < 0 || fd >= _thread_dtablesize) {
+ /* Return a bad file descriptor error: */
+ errno = EBADF;
+ ret = -1;
+ }
+
+ /*
+ * Check if memory has already been allocated for this file
+ * descriptor:
+ */
+ else if (_thread_fd_table[fd] != NULL) {
+ /* Memory has already been allocated. */
+
+ /* Allocate memory for the file descriptor table entry: */
+ } else if ((entry = (struct fd_table_entry *)
+ malloc(sizeof(struct fd_table_entry))) == NULL) {
+ /* Return an insufficient memory error: */
+ errno = ENOMEM;
+ ret = -1;
+ } else {
+ /* Initialise the file locks: */
+ memset(&entry->lock, 0, sizeof(entry->lock));
+ entry->r_owner = NULL;
+ entry->w_owner = NULL;
+ entry->r_fname = NULL;
+ entry->w_fname = NULL;
+ entry->r_lineno = 0;
+ entry->w_lineno = 0;
+ entry->r_lockcount = 0;
+ entry->w_lockcount = 0;
+
+ /* Initialise the read/write queues: */
+ TAILQ_INIT(&entry->r_queue);
+ TAILQ_INIT(&entry->w_queue);
+
+ /* Get the flags for the file: */
+ if (((fd >= 3) || (_pthread_stdio_flags[fd] == -1)) &&
+ (entry->flags = _thread_sys_fcntl(fd, F_GETFL, 0)) == -1) {
+ ret = -1;
+ }
+ else {
+ /* Check if a stdio descriptor: */
+ if ((fd < 3) && (_pthread_stdio_flags[fd] != -1))
+ /*
+ * Use the stdio flags read by
+ * _pthread_init() to avoid
+ * mistaking the non-blocking
+ * flag that, when set on one
+ * stdio fd, is set on all stdio
+ * fds.
+ */
+ entry->flags = _pthread_stdio_flags[fd];
+
+ /*
+ * Make the file descriptor non-blocking.
+ * This might fail if the device driver does
+ * not support non-blocking calls, or if the
+ * driver is naturally non-blocking.
+ */
+ saved_errno = errno;
+ _thread_sys_fcntl(fd, F_SETFL,
+ entry->flags | O_NONBLOCK);
+ errno = saved_errno;
+
+ /* Lock the file descriptor table: */
+ _SPINLOCK(&fd_table_lock);
+
+ /*
+ * Check if another thread allocated the
+ * file descriptor entry while this thread
+ * was doing the same thing. The table wasn't
+ * kept locked during this operation because
+ * it has the potential to recurse.
+ */
+ if (_thread_fd_table[fd] == NULL) {
+ /* This thread wins: */
+ _thread_fd_table[fd] = entry;
+ entry = NULL;
+ }
+
+ /* Unlock the file descriptor table: */
+ _SPINUNLOCK(&fd_table_lock);
+ }
+
+ /*
+ * Check if another thread initialised the table entry
+ * before this one could:
+ */
+ if (entry != NULL)
+ /*
+ * Throw away the table entry that this thread
+ * prepared. The other thread wins.
+ */
+ free(entry);
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+void
+_thread_fd_unlock(int fd, int lock_type)
+{
+ int ret;
+
+ /*
+ * Check that the file descriptor table is initialised for this
+ * entry:
+ */
+ if ((ret = _thread_fd_table_init(fd)) == 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /*
+ * Lock the file descriptor table entry to prevent
+ * other threads for clashing with the current
+ * thread's accesses:
+ */
+ _SPINLOCK(&_thread_fd_table[fd]->lock);
+
+ /* Check if the running thread owns the read lock: */
+ if (_thread_fd_table[fd]->r_owner == _thread_run) {
+ /* Check the file descriptor and lock types: */
+ if (lock_type == FD_READ || lock_type == FD_RDWR) {
+ /*
+ * Decrement the read lock count for the
+ * running thread:
+ */
+ _thread_fd_table[fd]->r_lockcount--;
+
+ /*
+ * Check if the running thread still has read
+ * locks on this file descriptor:
+ */
+ if (_thread_fd_table[fd]->r_lockcount != 0) {
+ }
+ /*
+ * Get the next thread in the queue for a
+ * read lock on this file descriptor:
+ */
+ else if ((_thread_fd_table[fd]->r_owner = fd_next_reader(fd)) == NULL) {
+ } else {
+ /* Remove this thread from the queue: */
+ FDQ_REMOVE(&_thread_fd_table[fd]->r_queue,
+ _thread_fd_table[fd]->r_owner);
+
+ /*
+ * Set the state of the new owner of
+ * the thread to running:
+ */
+ PTHREAD_NEW_STATE(_thread_fd_table[fd]->r_owner,PS_RUNNING);
+
+ /*
+ * Reset the number of read locks.
+ * This will be incremented by the
+ * new owner of the lock when it sees
+ * that it has the lock.
+ */
+ _thread_fd_table[fd]->r_lockcount = 0;
+ }
+ }
+ }
+ /* Check if the running thread owns the write lock: */
+ if (_thread_fd_table[fd]->w_owner == _thread_run) {
+ /* Check the file descriptor and lock types: */
+ if (lock_type == FD_WRITE || lock_type == FD_RDWR) {
+ /*
+ * Decrement the write lock count for the
+ * running thread:
+ */
+ _thread_fd_table[fd]->w_lockcount--;
+
+ /*
+ * Check if the running thread still has
+ * write locks on this file descriptor:
+ */
+ if (_thread_fd_table[fd]->w_lockcount != 0) {
+ }
+ /*
+ * Get the next thread in the queue for a
+ * write lock on this file descriptor:
+ */
+ else if ((_thread_fd_table[fd]->w_owner = fd_next_writer(fd)) == NULL) {
+ } else {
+ /* Remove this thread from the queue: */
+ FDQ_REMOVE(&_thread_fd_table[fd]->w_queue,
+ _thread_fd_table[fd]->w_owner);
+
+ /*
+ * Set the state of the new owner of
+ * the thread to running:
+ */
+ PTHREAD_NEW_STATE(_thread_fd_table[fd]->w_owner,PS_RUNNING);
+
+ /*
+ * Reset the number of write locks.
+ * This will be incremented by the
+ * new owner of the lock when it
+ * sees that it has the lock.
+ */
+ _thread_fd_table[fd]->w_lockcount = 0;
+ }
+ }
+ }
+
+ /* Unlock the file descriptor table entry: */
+ _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Nothing to return. */
+ return;
+}
+
+int
+_thread_fd_lock(int fd, int lock_type, struct timespec * timeout)
+{
+ int ret;
+
+ /*
+ * Check that the file descriptor table is initialised for this
+ * entry:
+ */
+ if ((ret = _thread_fd_table_init(fd)) == 0) {
+ /* Clear the interrupted flag: */
+ _thread_run->interrupted = 0;
+
+ /*
+ * Lock the file descriptor table entry to prevent
+ * other threads for clashing with the current
+ * thread's accesses:
+ */
+ _SPINLOCK(&_thread_fd_table[fd]->lock);
+
+ /* Check the file descriptor and lock types: */
+ if (lock_type == FD_READ || lock_type == FD_RDWR) {
+ /*
+ * Wait for the file descriptor to be locked
+ * for read for the current thread:
+ */
+ if (_thread_fd_table[fd]->r_owner != _thread_run) {
+ /*
+ * Check if the file descriptor is locked by
+ * another thread:
+ */
+ if (_thread_fd_table[fd]->r_owner != NULL) {
+ /*
+ * Another thread has locked the file
+ * descriptor for read, so join the
+ * queue of threads waiting for a
+ * read lock on this file descriptor:
+ */
+ FDQ_INSERT(&_thread_fd_table[fd]->r_queue, _thread_run);
+
+ /*
+ * Save the file descriptor details
+ * in the thread structure for the
+ * running thread:
+ */
+ _thread_run->data.fd.fd = fd;
+
+ /* Set the timeout: */
+ _thread_kern_set_timeout(timeout);
+
+ /*
+ * Unlock the file descriptor
+ * table entry:
+ */
+ _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+
+ /*
+ * Schedule this thread to wait on
+ * the read lock. It will only be
+ * woken when it becomes the next in
+ * the queue and is granted access
+ * to the lock by the thread
+ * that is unlocking the file
+ * descriptor.
+ */
+ _thread_kern_sched_state(PS_FDLR_WAIT, __FILE__, __LINE__);
+
+ /*
+ * Lock the file descriptor
+ * table entry again:
+ */
+ _SPINLOCK(&_thread_fd_table[fd]->lock);
+
+ if (_thread_run->interrupted != 0) {
+ FDQ_REMOVE(&_thread_fd_table[fd]->r_queue,
+ _thread_run);
+ }
+ } else {
+ /*
+ * The running thread now owns the
+ * read lock on this file descriptor:
+ */
+ _thread_fd_table[fd]->r_owner = _thread_run;
+
+ /*
+ * Reset the number of read locks for
+ * this file descriptor:
+ */
+ _thread_fd_table[fd]->r_lockcount = 0;
+ }
+ }
+
+ if (_thread_fd_table[fd]->r_owner == _thread_run)
+ /* Increment the read lock count: */
+ _thread_fd_table[fd]->r_lockcount++;
+ }
+
+ /* Check the file descriptor and lock types: */
+ if (_thread_run->interrupted == 0 &&
+ (lock_type == FD_WRITE || lock_type == FD_RDWR)) {
+ /*
+ * Wait for the file descriptor to be locked
+ * for write for the current thread:
+ */
+ if (_thread_fd_table[fd]->w_owner != _thread_run) {
+ /*
+ * Check if the file descriptor is locked by
+ * another thread:
+ */
+ if (_thread_fd_table[fd]->w_owner != NULL) {
+ /*
+ * Another thread has locked the file
+ * descriptor for write, so join the
+ * queue of threads waiting for a
+ * write lock on this file
+ * descriptor:
+ */
+ FDQ_INSERT(&_thread_fd_table[fd]->w_queue, _thread_run);
+
+ /*
+ * Save the file descriptor details
+ * in the thread structure for the
+ * running thread:
+ */
+ _thread_run->data.fd.fd = fd;
+
+ /* Set the timeout: */
+ _thread_kern_set_timeout(timeout);
+
+ /*
+ * Unlock the file descriptor
+ * table entry:
+ */
+ _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+
+ /*
+ * Schedule this thread to wait on
+ * the write lock. It will only be
+ * woken when it becomes the next in
+ * the queue and is granted access to
+ * the lock by the thread that is
+ * unlocking the file descriptor.
+ */
+ _thread_kern_sched_state(PS_FDLW_WAIT, __FILE__, __LINE__);
+
+ /*
+ * Lock the file descriptor
+ * table entry again:
+ */
+ _SPINLOCK(&_thread_fd_table[fd]->lock);
+
+ if (_thread_run->interrupted != 0) {
+ FDQ_REMOVE(&_thread_fd_table[fd]->w_queue,
+ _thread_run);
+ }
+ } else {
+ /*
+ * The running thread now owns the
+ * write lock on this file
+ * descriptor:
+ */
+ _thread_fd_table[fd]->w_owner = _thread_run;
+
+ /*
+ * Reset the number of write locks
+ * for this file descriptor:
+ */
+ _thread_fd_table[fd]->w_lockcount = 0;
+ }
+ }
+
+ if (_thread_fd_table[fd]->w_owner == _thread_run)
+ /* Increment the write lock count: */
+ _thread_fd_table[fd]->w_lockcount++;
+ }
+
+ /* Unlock the file descriptor table entry: */
+ _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+
+ if (_thread_run->interrupted != 0) {
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) == 0) {
+ ret = -1;
+ errno = EINTR;
+ } else {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+ }
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+void
+_thread_fd_unlock_debug(int fd, int lock_type, char *fname, int lineno)
+{
+ int ret;
+
+ /*
+ * Check that the file descriptor table is initialised for this
+ * entry:
+ */
+ if ((ret = _thread_fd_table_init(fd)) == 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /*
+ * Lock the file descriptor table entry to prevent
+ * other threads for clashing with the current
+ * thread's accesses:
+ */
+ _spinlock_debug(&_thread_fd_table[fd]->lock, fname, lineno);
+
+ /* Check if the running thread owns the read lock: */
+ if (_thread_fd_table[fd]->r_owner == _thread_run) {
+ /* Check the file descriptor and lock types: */
+ if (lock_type == FD_READ || lock_type == FD_RDWR) {
+ /*
+ * Decrement the read lock count for the
+ * running thread:
+ */
+ _thread_fd_table[fd]->r_lockcount--;
+
+ /*
+ * Check if the running thread still has read
+ * locks on this file descriptor:
+ */
+ if (_thread_fd_table[fd]->r_lockcount != 0) {
+ }
+ /*
+ * Get the next thread in the queue for a
+ * read lock on this file descriptor:
+ */
+ else if ((_thread_fd_table[fd]->r_owner = fd_next_reader(fd)) == NULL) {
+ } else {
+ /* Remove this thread from the queue: */
+ FDQ_REMOVE(&_thread_fd_table[fd]->r_queue,
+ _thread_fd_table[fd]->r_owner);
+
+ /*
+ * Set the state of the new owner of
+ * the thread to running:
+ */
+ PTHREAD_NEW_STATE(_thread_fd_table[fd]->r_owner,PS_RUNNING);
+
+ /*
+ * Reset the number of read locks.
+ * This will be incremented by the
+ * new owner of the lock when it sees
+ * that it has the lock.
+ */
+ _thread_fd_table[fd]->r_lockcount = 0;
+ }
+ }
+ }
+ /* Check if the running thread owns the write lock: */
+ if (_thread_fd_table[fd]->w_owner == _thread_run) {
+ /* Check the file descriptor and lock types: */
+ if (lock_type == FD_WRITE || lock_type == FD_RDWR) {
+ /*
+ * Decrement the write lock count for the
+ * running thread:
+ */
+ _thread_fd_table[fd]->w_lockcount--;
+
+ /*
+ * Check if the running thread still has
+ * write locks on this file descriptor:
+ */
+ if (_thread_fd_table[fd]->w_lockcount != 0) {
+ }
+ /*
+ * Get the next thread in the queue for a
+ * write lock on this file descriptor:
+ */
+ else if ((_thread_fd_table[fd]->w_owner = fd_next_writer(fd)) == NULL) {
+ } else {
+ /* Remove this thread from the queue: */
+ FDQ_REMOVE(&_thread_fd_table[fd]->w_queue,
+ _thread_fd_table[fd]->w_owner);
+
+ /*
+ * Set the state of the new owner of
+ * the thread to running:
+ */
+ PTHREAD_NEW_STATE(_thread_fd_table[fd]->w_owner,PS_RUNNING);
+
+ /*
+ * Reset the number of write locks.
+ * This will be incremented by the
+ * new owner of the lock when it
+ * sees that it has the lock.
+ */
+ _thread_fd_table[fd]->w_lockcount = 0;
+ }
+ }
+ }
+
+ /* Unlock the file descriptor table entry: */
+ _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary.
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Nothing to return. */
+ return;
+}
+
+int
+_thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout,
+ char *fname, int lineno)
+{
+ int ret;
+
+ /*
+ * Check that the file descriptor table is initialised for this
+ * entry:
+ */
+ if ((ret = _thread_fd_table_init(fd)) == 0) {
+ /* Clear the interrupted flag: */
+ _thread_run->interrupted = 0;
+
+ /*
+ * Lock the file descriptor table entry to prevent
+ * other threads for clashing with the current
+ * thread's accesses:
+ */
+ _spinlock_debug(&_thread_fd_table[fd]->lock, fname, lineno);
+
+ /* Check the file descriptor and lock types: */
+ if (lock_type == FD_READ || lock_type == FD_RDWR) {
+ /*
+ * Wait for the file descriptor to be locked
+ * for read for the current thread:
+ */
+ if (_thread_fd_table[fd]->r_owner != _thread_run) {
+ /*
+ * Check if the file descriptor is locked by
+ * another thread:
+ */
+ if (_thread_fd_table[fd]->r_owner != NULL) {
+ /*
+ * Another thread has locked the file
+ * descriptor for read, so join the
+ * queue of threads waiting for a
+ * read lock on this file descriptor:
+ */
+ FDQ_INSERT(&_thread_fd_table[fd]->r_queue, _thread_run);
+
+ /*
+ * Save the file descriptor details
+ * in the thread structure for the
+ * running thread:
+ */
+ _thread_run->data.fd.fd = fd;
+ _thread_run->data.fd.branch = lineno;
+ _thread_run->data.fd.fname = fname;
+
+ /* Set the timeout: */
+ _thread_kern_set_timeout(timeout);
+
+ /*
+ * Unlock the file descriptor
+ * table entry:
+ */
+ _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+
+ /*
+ * Schedule this thread to wait on
+ * the read lock. It will only be
+ * woken when it becomes the next in
+ * the queue and is granted access
+ * to the lock by the thread
+ * that is unlocking the file
+ * descriptor.
+ */
+ _thread_kern_sched_state(PS_FDLR_WAIT, __FILE__, __LINE__);
+
+ /*
+ * Lock the file descriptor
+ * table entry again:
+ */
+ _SPINLOCK(&_thread_fd_table[fd]->lock);
+
+ if (_thread_run->interrupted != 0) {
+ FDQ_REMOVE(&_thread_fd_table[fd]->r_queue,
+ _thread_run);
+ }
+ } else {
+ /*
+ * The running thread now owns the
+ * read lock on this file descriptor:
+ */
+ _thread_fd_table[fd]->r_owner = _thread_run;
+
+ /*
+ * Reset the number of read locks for
+ * this file descriptor:
+ */
+ _thread_fd_table[fd]->r_lockcount = 0;
+
+ /*
+ * Save the source file details for
+ * debugging:
+ */
+ _thread_fd_table[fd]->r_fname = fname;
+ _thread_fd_table[fd]->r_lineno = lineno;
+ }
+ }
+
+ if (_thread_fd_table[fd]->r_owner == _thread_run)
+ /* Increment the read lock count: */
+ _thread_fd_table[fd]->r_lockcount++;
+ }
+
+ /* Check the file descriptor and lock types: */
+ if (_thread_run->interrupted == 0 &&
+ (lock_type == FD_WRITE || lock_type == FD_RDWR)) {
+ /*
+ * Wait for the file descriptor to be locked
+ * for write for the current thread:
+ */
+ if (_thread_fd_table[fd]->w_owner != _thread_run) {
+ /*
+ * Check if the file descriptor is locked by
+ * another thread:
+ */
+ if (_thread_fd_table[fd]->w_owner != NULL) {
+ /*
+ * Another thread has locked the file
+ * descriptor for write, so join the
+ * queue of threads waiting for a
+ * write lock on this file
+ * descriptor:
+ */
+ FDQ_INSERT(&_thread_fd_table[fd]->w_queue, _thread_run);
+
+ /*
+ * Save the file descriptor details
+ * in the thread structure for the
+ * running thread:
+ */
+ _thread_run->data.fd.fd = fd;
+ _thread_run->data.fd.branch = lineno;
+ _thread_run->data.fd.fname = fname;
+
+ /* Set the timeout: */
+ _thread_kern_set_timeout(timeout);
+
+ /*
+ * Unlock the file descriptor
+ * table entry:
+ */
+ _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+
+ /*
+ * Schedule this thread to wait on
+ * the write lock. It will only be
+ * woken when it becomes the next in
+ * the queue and is granted access to
+ * the lock by the thread that is
+ * unlocking the file descriptor.
+ */
+ _thread_kern_sched_state(PS_FDLW_WAIT, __FILE__, __LINE__);
+
+ /*
+ * Lock the file descriptor
+ * table entry again:
+ */
+ _SPINLOCK(&_thread_fd_table[fd]->lock);
+
+ if (_thread_run->interrupted != 0) {
+ FDQ_REMOVE(&_thread_fd_table[fd]->w_queue,
+ _thread_run);
+ }
+ } else {
+ /*
+ * The running thread now owns the
+ * write lock on this file
+ * descriptor:
+ */
+ _thread_fd_table[fd]->w_owner = _thread_run;
+
+ /*
+ * Reset the number of write locks
+ * for this file descriptor:
+ */
+ _thread_fd_table[fd]->w_lockcount = 0;
+
+ /*
+ * Save the source file details for
+ * debugging:
+ */
+ _thread_fd_table[fd]->w_fname = fname;
+ _thread_fd_table[fd]->w_lineno = lineno;
+ }
+ }
+
+ if (_thread_fd_table[fd]->w_owner == _thread_run)
+ /* Increment the write lock count: */
+ _thread_fd_table[fd]->w_lockcount++;
+ }
+
+ /* Unlock the file descriptor table entry: */
+ _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+
+ if (_thread_run->interrupted != 0) {
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) == 0) {
+ ret = -1;
+ errno = EINTR;
+ } else {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+ }
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+void
+_thread_fd_unlock_owned(pthread_t pthread)
+{
+ int fd;
+
+ for (fd = 0; fd < _thread_dtablesize; fd++) {
+ if ((_thread_fd_table[fd] != NULL) &&
+ ((_thread_fd_table[fd]->r_owner == pthread) ||
+ (_thread_fd_table[fd]->w_owner == pthread))) {
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /*
+ * Lock the file descriptor table entry to prevent
+ * other threads for clashing with the current
+ * thread's accesses:
+ */
+ _SPINLOCK(&_thread_fd_table[fd]->lock);
+
+ /* Check if the thread owns the read lock: */
+ if (_thread_fd_table[fd]->r_owner == pthread) {
+ /* Clear the read lock count: */
+ _thread_fd_table[fd]->r_lockcount = 0;
+
+ /*
+ * Get the next thread in the queue for a
+ * read lock on this file descriptor:
+ */
+ if ((_thread_fd_table[fd]->r_owner = fd_next_reader(fd)) != NULL) {
+ /* Remove this thread from the queue: */
+ FDQ_REMOVE(&_thread_fd_table[fd]->r_queue,
+ _thread_fd_table[fd]->r_owner);
+
+ /*
+ * Set the state of the new owner of
+ * the thread to running:
+ */
+ PTHREAD_NEW_STATE(_thread_fd_table[fd]->r_owner,PS_RUNNING);
+ }
+ }
+
+ /* Check if the thread owns the write lock: */
+ if (_thread_fd_table[fd]->w_owner == pthread) {
+ /* Clear the write lock count: */
+ _thread_fd_table[fd]->w_lockcount = 0;
+
+ /*
+ * Get the next thread in the queue for a
+ * write lock on this file descriptor:
+ */
+ if ((_thread_fd_table[fd]->w_owner = fd_next_writer(fd)) != NULL) {
+ /* Remove this thread from the queue: */
+ FDQ_REMOVE(&_thread_fd_table[fd]->w_queue,
+ _thread_fd_table[fd]->w_owner);
+
+ /*
+ * Set the state of the new owner of
+ * the thread to running:
+ */
+ PTHREAD_NEW_STATE(_thread_fd_table[fd]->w_owner,PS_RUNNING);
+
+ }
+ }
+
+ /* Unlock the file descriptor table entry: */
+ _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary.
+ */
+ _thread_kern_sig_undefer();
+ }
+ }
+}
+
+static inline pthread_t
+fd_next_reader(int fd)
+{
+ pthread_t pthread;
+
+ while (((pthread = TAILQ_FIRST(&_thread_fd_table[fd]->r_queue)) != NULL) &&
+ (pthread->interrupted != 0)) {
+ /*
+ * This thread has either been interrupted by a signal or
+ * it has been canceled. Remove it from the queue.
+ */
+ FDQ_REMOVE(&_thread_fd_table[fd]->r_queue, pthread);
+ }
+
+ return (pthread);
+}
+
+static inline pthread_t
+fd_next_writer(int fd)
+{
+ pthread_t pthread;
+
+ while (((pthread = TAILQ_FIRST(&_thread_fd_table[fd]->w_queue)) != NULL) &&
+ (pthread->interrupted != 0)) {
+ /*
+ * This thread has either been interrupted by a signal or
+ * it has been canceled. Remove it from the queue.
+ */
+ FDQ_REMOVE(&_thread_fd_table[fd]->w_queue, pthread);
+ }
+
+ return (pthread);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_file.c b/lib/libc_r/uthread/uthread_file.c
new file mode 100644
index 0000000..f1bac17
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_file.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ * POSIX stdio FILE locking functions. These assume that the locking
+ * is only required at FILE structure level, not at file descriptor
+ * level too.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/queue.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/*
+ * Weak symbols for externally visible functions in this file:
+ */
+#pragma weak flockfile=_flockfile
+#pragma weak ftrylockfile=_ftrylockfile
+#pragma weak funlockfile=_funlockfile
+
+/*
+ * The FILE lock structure. The FILE *fp is locked if the owner is
+ * not NULL. If not locked, the file lock structure can be
+ * reassigned to a different file by setting fp.
+ */
+struct file_lock {
+ LIST_ENTRY(file_lock) entry; /* Entry if file list. */
+ TAILQ_HEAD(lock_head, pthread)
+ l_head; /* Head of queue for threads */
+ /* waiting on this lock. */
+ FILE *fp; /* The target file. */
+ pthread_t owner; /* Thread that owns lock. */
+ int count; /* Lock count for owner. */
+};
+
+/*
+ * The number of file lock lists into which the file pointer is
+ * hashed. Ideally, the FILE structure size would have been increased,
+ * but this causes incompatibility, so separate data structures are
+ * required.
+ */
+#define NUM_HEADS 128
+
+/*
+ * This macro casts a file pointer to a long integer and right
+ * shifts this by the number of bytes in a pointer. The shifted
+ * value is then remaindered using the maximum number of hash
+ * entries to produce and index into the array of static lock
+ * structures. If there is a collision, a linear search of the
+ * dynamic list of locks linked to each static lock is perfomed.
+ */
+#define file_idx(_p) ((((u_long) _p) >> sizeof(void *)) % NUM_HEADS)
+
+/*
+ * Global array of file locks. The first lock for each hash bucket is
+ * allocated statically in the hope that there won't be too many
+ * collisions that require a malloc and an element added to the list.
+ */
+struct static_file_lock {
+ LIST_HEAD(file_list_head, file_lock) head;
+ struct file_lock fl;
+} flh[NUM_HEADS];
+
+/* Set to non-zero when initialisation is complete: */
+static int init_done = 0;
+
+/* Lock for accesses to the hash table: */
+static spinlock_t hash_lock = _SPINLOCK_INITIALIZER;
+
+/*
+ * Find a lock structure for a FILE, return NULL if the file is
+ * not locked:
+ */
+static
+struct file_lock *
+find_lock(int idx, FILE *fp)
+{
+ struct file_lock *p;
+
+ /* Check if the file is locked using the static structure: */
+ if (flh[idx].fl.fp == fp && flh[idx].fl.owner != NULL)
+ /* Return a pointer to the static lock: */
+ p = &flh[idx].fl;
+ else {
+ /* Point to the first dynamic lock: */
+ p = flh[idx].head.lh_first;
+
+ /*
+ * Loop through the dynamic locks looking for the
+ * target file:
+ */
+ while (p != NULL && (p->fp != fp || p->owner == NULL))
+ /* Not this file, try the next: */
+ p = p->entry.le_next;
+ }
+ return(p);
+}
+
+/*
+ * Lock a file, assuming that there is no lock structure currently
+ * assigned to it.
+ */
+static
+struct file_lock *
+do_lock(int idx, FILE *fp)
+{
+ struct file_lock *p;
+
+ /* Check if the static structure is not being used: */
+ if (flh[idx].fl.owner == NULL) {
+ /* Return a pointer to the static lock: */
+ p = &flh[idx].fl;
+ }
+ else {
+ /* Point to the first dynamic lock: */
+ p = flh[idx].head.lh_first;
+
+ /*
+ * Loop through the dynamic locks looking for a
+ * lock structure that is not being used:
+ */
+ while (p != NULL && p->owner != NULL)
+ /* This one is used, try the next: */
+ p = p->entry.le_next;
+ }
+
+ /*
+ * If an existing lock structure has not been found,
+ * allocate memory for a new one:
+ */
+ if (p == NULL && (p = (struct file_lock *)
+ malloc(sizeof(struct file_lock))) != NULL) {
+ /* Add the new element to the list: */
+ LIST_INSERT_HEAD(&flh[idx].head, p, entry);
+ }
+
+ /* Check if there is a lock structure to acquire: */
+ if (p != NULL) {
+ /* Acquire the lock for the running thread: */
+ p->fp = fp;
+ p->owner = _thread_run;
+ p->count = 1;
+ TAILQ_INIT(&p->l_head);
+ }
+ return(p);
+}
+
+void
+_flockfile_debug(FILE * fp, char *fname, int lineno)
+{
+ int idx = file_idx(fp);
+ struct file_lock *p;
+
+ /* Check if this is a real file: */
+ if (fp->_file >= 0) {
+ /* Lock the hash table: */
+ _SPINLOCK(&hash_lock);
+
+ /* Check if the static array has not been initialised: */
+ if (!init_done) {
+ /* Initialise the global array: */
+ memset(flh,0,sizeof(flh));
+
+ /* Flag the initialisation as complete: */
+ init_done = 1;
+ }
+
+ /* Get a pointer to any existing lock for the file: */
+ if ((p = find_lock(idx, fp)) == NULL) {
+ /*
+ * The file is not locked, so this thread can
+ * grab the lock:
+ */
+ p = do_lock(idx, fp);
+
+ /* Unlock the hash table: */
+ _SPINUNLOCK(&hash_lock);
+
+ /*
+ * The file is already locked, so check if the
+ * running thread is the owner:
+ */
+ } else if (p->owner == _thread_run) {
+ /*
+ * The running thread is already the
+ * owner, so increment the count of
+ * the number of times it has locked
+ * the file:
+ */
+ p->count++;
+
+ /* Unlock the hash table: */
+ _SPINUNLOCK(&hash_lock);
+ } else {
+ /* Clear the interrupted flag: */
+ _thread_run->interrupted = 0;
+
+ /*
+ * Prevent being context switched out while
+ * adding this thread to the file lock queue.
+ */
+ _thread_kern_sig_defer();
+
+ /*
+ * The file is locked for another thread.
+ * Append this thread to the queue of
+ * threads waiting on the lock.
+ */
+ TAILQ_INSERT_TAIL(&p->l_head,_thread_run,qe);
+ _thread_run->flags |= PTHREAD_FLAGS_IN_FILEQ;
+
+ /* Unlock the hash table: */
+ _SPINUNLOCK(&hash_lock);
+
+ /* Wait on the FILE lock: */
+ _thread_kern_sched_state(PS_FILE_WAIT, fname, lineno);
+
+ if ((_thread_run->flags & PTHREAD_FLAGS_IN_FILEQ) != 0) {
+ TAILQ_REMOVE(&p->l_head,_thread_run,qe);
+ _thread_run->flags &= ~PTHREAD_FLAGS_IN_FILEQ;
+ }
+
+ _thread_kern_sig_undefer();
+
+ if (((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) &&
+ (_thread_run->cancelflags & PTHREAD_CANCEL_DISABLE) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+ }
+ }
+ return;
+}
+
+void
+_flockfile(FILE * fp)
+{
+ _flockfile_debug(fp, __FILE__, __LINE__);
+ return;
+}
+
+int
+_ftrylockfile(FILE * fp)
+{
+ int ret = -1;
+ int idx = file_idx(fp);
+ struct file_lock *p;
+
+ /* Check if this is a real file: */
+ if (fp->_file >= 0) {
+ /* Lock the hash table: */
+ _SPINLOCK(&hash_lock);
+
+ /* Get a pointer to any existing lock for the file: */
+ if ((p = find_lock(idx, fp)) == NULL) {
+ /*
+ * The file is not locked, so this thread can
+ * grab the lock:
+ */
+ p = do_lock(idx, fp);
+
+ /*
+ * The file is already locked, so check if the
+ * running thread is the owner:
+ */
+ } else if (p->owner == _thread_run) {
+ /*
+ * The running thread is already the
+ * owner, so increment the count of
+ * the number of times it has locked
+ * the file:
+ */
+ p->count++;
+ } else {
+ /*
+ * The file is locked for another thread,
+ * so this try fails.
+ */
+ p = NULL;
+ }
+
+ /* Check if the lock was obtained: */
+ if (p != NULL)
+ /* Return success: */
+ ret = 0;
+
+ /* Unlock the hash table: */
+ _SPINUNLOCK(&hash_lock);
+
+ }
+ return (ret);
+}
+
+void
+_funlockfile(FILE * fp)
+{
+ int idx = file_idx(fp);
+ struct file_lock *p;
+
+ /* Check if this is a real file: */
+ if (fp->_file >= 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the hash table: */
+ _SPINLOCK(&hash_lock);
+
+ /*
+ * Get a pointer to the lock for the file and check that
+ * the running thread is the one with the lock:
+ */
+ if ((p = find_lock(idx, fp)) != NULL &&
+ p->owner == _thread_run) {
+ /*
+ * Check if this thread has locked the FILE
+ * more than once:
+ */
+ if (p->count > 1)
+ /*
+ * Decrement the count of the number of
+ * times the running thread has locked this
+ * file:
+ */
+ p->count--;
+ else {
+ /*
+ * The running thread will release the
+ * lock now:
+ */
+ p->count = 0;
+
+ /* Get the new owner of the lock: */
+ while ((p->owner = TAILQ_FIRST(&p->l_head)) != NULL) {
+ /* Pop the thread off the queue: */
+ TAILQ_REMOVE(&p->l_head,p->owner,qe);
+ p->owner->flags &= ~PTHREAD_FLAGS_IN_FILEQ;
+
+ if (p->owner->interrupted == 0) {
+ /*
+ * This is the first lock for
+ * the new owner:
+ */
+ p->count = 1;
+
+ /* Allow the new owner to run: */
+ PTHREAD_NEW_STATE(p->owner,PS_RUNNING);
+
+ /* End the loop when we find a
+ * thread that hasn't been
+ * cancelled or interrupted;
+ */
+ break;
+ }
+ }
+ }
+ }
+
+ /* Unlock the hash table: */
+ _SPINUNLOCK(&hash_lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+ return;
+}
+
+void
+_funlock_owned(pthread_t pthread)
+{
+ int idx;
+ struct file_lock *p, *next_p;
+
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the hash table: */
+ _SPINLOCK(&hash_lock);
+
+ for (idx = 0; idx < NUM_HEADS; idx++) {
+ /* Check the static file lock first: */
+ p = &flh[idx].fl;
+ next_p = LIST_FIRST(&flh[idx].head);
+
+ while (p != NULL) {
+ if (p->owner == pthread) {
+ /*
+ * The running thread will release the
+ * lock now:
+ */
+ p->count = 0;
+
+ /* Get the new owner of the lock: */
+ while ((p->owner = TAILQ_FIRST(&p->l_head)) != NULL) {
+ /* Pop the thread off the queue: */
+ TAILQ_REMOVE(&p->l_head,p->owner,qe);
+ p->owner->flags &= ~PTHREAD_FLAGS_IN_FILEQ;
+
+ if (p->owner->interrupted == 0) {
+ /*
+ * This is the first lock for
+ * the new owner:
+ */
+ p->count = 1;
+
+ /* Allow the new owner to run: */
+ PTHREAD_NEW_STATE(p->owner,PS_RUNNING);
+
+ /* End the loop when we find a
+ * thread that hasn't been
+ * cancelled or interrupted;
+ */
+ break;
+ }
+ }
+ }
+ p = next_p;
+ if (next_p != NULL)
+ next_p = LIST_NEXT(next_p, entry);
+ }
+ }
+
+ /* Unlock the hash table: */
+ _SPINUNLOCK(&hash_lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+}
+
+#endif
diff --git a/lib/libc_r/uthread/uthread_find_thread.c b/lib/libc_r/uthread/uthread_find_thread.c
new file mode 100644
index 0000000..d4a3bbd
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_find_thread.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Find a thread in the linked list of active threads: */
+int
+_find_thread(pthread_t pthread)
+{
+ pthread_t pthread1;
+
+ /* Check if the caller has specified an invalid thread: */
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
+ /* Invalid thread: */
+ return(EINVAL);
+
+ /*
+ * Defer signals to protect the thread list from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Search for the specified thread: */
+ TAILQ_FOREACH(pthread1, &_thread_list, tle) {
+ if (pthread == pthread1)
+ break;
+ }
+
+ /* Undefer and handle pending signals, yielding if necessary: */
+ _thread_kern_sig_undefer();
+
+ /* Return zero if the thread exists: */
+ return ((pthread1 != NULL) ? 0:ESRCH);
+}
+
+/* Find a thread in the linked list of dead threads: */
+int
+_find_dead_thread(pthread_t pthread)
+{
+ pthread_t pthread1;
+
+ /* Check if the caller has specified an invalid thread: */
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
+ /* Invalid thread: */
+ return(EINVAL);
+
+ /*
+ * Lock the garbage collector mutex to ensure that the garbage
+ * collector is not using the dead thread list.
+ */
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* Search for the specified thread: */
+ TAILQ_FOREACH(pthread1, &_dead_list, dle) {
+ if (pthread1 == pthread)
+ break;
+ }
+
+ /* Unlock the garbage collector mutex: */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* Return zero if the thread exists: */
+ return ((pthread1 != NULL) ? 0:ESRCH);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_flock.c b/lib/libc_r/uthread/uthread_flock.c
new file mode 100644
index 0000000..901ab9d
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_flock.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/file.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+flock(int fd, int operation)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ ret = _thread_sys_flock(fd, operation);
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_fork.c b/lib/libc_r/uthread/uthread_fork.c
new file mode 100644
index 0000000..b8d72dc
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_fork.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+pid_t
+fork(void)
+{
+ int i, flags;
+ pid_t ret;
+ pthread_t pthread;
+ pthread_t pthread_save;
+
+ /*
+ * Defer signals to protect the scheduling queues from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Fork a new process: */
+ if ((ret = _thread_sys_fork()) != 0) {
+ /* Parent process or error. Nothing to do here. */
+ } else {
+ /* Close the pthread kernel pipe: */
+ _thread_sys_close(_thread_kern_pipe[0]);
+ _thread_sys_close(_thread_kern_pipe[1]);
+
+ /* Reset signals pending for the running thread: */
+ sigemptyset(&_thread_run->sigpend);
+
+ /*
+ * Create a pipe that is written to by the signal handler to
+ * prevent signals being missed in calls to
+ * _thread_sys_select:
+ */
+ if (_thread_sys_pipe(_thread_kern_pipe) != 0) {
+ /* Cannot create pipe, so abort: */
+ PANIC("Cannot create pthread kernel pipe for forked process");
+ }
+ /* Get the flags for the read pipe: */
+ else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[0], F_GETFL, NULL)) == -1) {
+ /* Abort this application: */
+ abort();
+ }
+ /* Make the read pipe non-blocking: */
+ else if (_thread_sys_fcntl(_thread_kern_pipe[0], F_SETFL, flags | O_NONBLOCK) == -1) {
+ /* Abort this application: */
+ abort();
+ }
+ /* Get the flags for the write pipe: */
+ else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[1], F_GETFL, NULL)) == -1) {
+ /* Abort this application: */
+ abort();
+ }
+ /* Make the write pipe non-blocking: */
+ else if (_thread_sys_fcntl(_thread_kern_pipe[1], F_SETFL, flags | O_NONBLOCK) == -1) {
+ /* Abort this application: */
+ abort();
+ }
+ /* Reinitialize the GC mutex: */
+ else if (_mutex_reinit(&_gc_mutex) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot initialize GC mutex for forked process");
+ }
+ /* Reinitialize the GC condition variable: */
+ else if (_cond_reinit(&_gc_cond) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot initialize GC condvar for forked process");
+ }
+ /* Initialize the ready queue: */
+ else if (_pq_init(&_readyq) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot initialize priority ready queue.");
+ } else {
+ /*
+ * Enter a loop to remove all threads other than
+ * the running thread from the thread list:
+ */
+ pthread = TAILQ_FIRST(&_thread_list);
+ while (pthread != NULL) {
+ /* Save the thread to be freed: */
+ pthread_save = pthread;
+
+ /*
+ * Advance to the next thread before
+ * destroying the current thread:
+ */
+ pthread = TAILQ_NEXT(pthread, dle);
+
+ /* Make sure this isn't the running thread: */
+ if (pthread_save != _thread_run) {
+ /* Remove this thread from the list: */
+ TAILQ_REMOVE(&_thread_list,
+ pthread_save, tle);
+
+ if (pthread_save->attr.stackaddr_attr ==
+ NULL && pthread_save->stack != NULL)
+ if (pthread_save->attr.stacksize_attr
+ == PTHREAD_STACK_DEFAULT) {
+ /*
+ * Default-size stack. Cache
+ * it:
+ */
+ struct stack *spare_stack;
+
+ spare_stack
+ = (pthread_save->stack
+ + PTHREAD_STACK_DEFAULT
+ - sizeof(struct stack));
+ SLIST_INSERT_HEAD(
+ &_stackq,
+ spare_stack,
+ qe);
+ } else
+ /*
+ * Free the stack of
+ * the dead thread:
+ */
+ free(pthread_save->stack);
+
+ if (pthread_save->specific_data != NULL)
+ free(pthread_save->specific_data);
+
+ if (pthread_save->poll_data.fds != NULL)
+ free(pthread_save->poll_data.fds);
+
+ free(pthread_save);
+ }
+ }
+
+ /* Treat the current thread as the initial thread: */
+ _thread_initial = _thread_run;
+
+ /* Re-init the dead thread list: */
+ TAILQ_INIT(&_dead_list);
+
+ /* Re-init the waiting and work queues. */
+ TAILQ_INIT(&_waitingq);
+ TAILQ_INIT(&_workq);
+
+ /* Re-init the threads mutex queue: */
+ TAILQ_INIT(&_thread_run->mutexq);
+
+ /* No spinlocks yet: */
+ _spinblock_count = 0;
+
+ /* Don't queue signals yet: */
+ _queue_signals = 0;
+
+ /* Initialize signal handling: */
+ _thread_sig_init();
+
+ /* Initialize the scheduling switch hook routine: */
+ _sched_switch_hook = NULL;
+
+ /* Clear out any locks in the file descriptor table: */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ if (_thread_fd_table[i] != NULL) {
+ /* Initialise the file locks: */
+ memset(&_thread_fd_table[i]->lock, 0,
+ sizeof(_thread_fd_table[i]->lock));
+ _thread_fd_table[i]->r_owner = NULL;
+ _thread_fd_table[i]->w_owner = NULL;
+ _thread_fd_table[i]->r_fname = NULL;
+ _thread_fd_table[i]->w_fname = NULL;
+ _thread_fd_table[i]->r_lineno = 0;;
+ _thread_fd_table[i]->w_lineno = 0;;
+ _thread_fd_table[i]->r_lockcount = 0;;
+ _thread_fd_table[i]->w_lockcount = 0;;
+
+ /* Initialise the read/write queues: */
+ TAILQ_INIT(&_thread_fd_table[i]->r_queue);
+ TAILQ_INIT(&_thread_fd_table[i]->w_queue);
+ }
+ }
+ }
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding if necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ /* Return the process ID: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_fstat.c b/lib/libc_r/uthread/uthread_fstat.c
new file mode 100644
index 0000000..8e9e7a4
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_fstat.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+fstat(int fd, struct stat * buf)
+{
+ int ret;
+
+ /* Lock the file descriptor for read: */
+ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ /* Get the file status: */
+ ret = _thread_sys_fstat(fd, buf);
+ /* Unlock the file descriptor: */
+ _FD_UNLOCK(fd, FD_READ);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_fstatfs.c b/lib/libc_r/uthread/uthread_fstatfs.c
new file mode 100644
index 0000000..d7a8a21
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_fstatfs.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+fstatfs(int fd, struct statfs * buf)
+{
+ int ret;
+
+ /* Lock the file descriptor for read: */
+ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ /* Get the file system status: */
+ ret = _thread_sys_fstatfs(fd, buf);
+ /* Unlock the file descriptor: */
+ _FD_UNLOCK(fd, FD_READ);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_fsync.c b/lib/libc_r/uthread/uthread_fsync.c
new file mode 100644
index 0000000..21c3b56
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_fsync.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+fsync(int fd)
+{
+ int ret;
+
+ _thread_enter_cancellation_point();
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ ret = _thread_sys_fsync(fd);
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_gc.c b/lib/libc_r/uthread/uthread_gc.c
new file mode 100644
index 0000000..d748049
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_gc.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ * Garbage collector thread. Frees memory allocated for dead threads.
+ *
+ */
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <pthread.h>
+#include "pthread_private.h"
+
+pthread_addr_t
+_thread_gc(pthread_addr_t arg)
+{
+ int f_debug;
+ int f_done = 0;
+ int ret;
+ sigset_t mask;
+ pthread_t pthread;
+ pthread_t pthread_cln;
+ pthread_t pthread_nxt;
+ pthread_t pthread_prv;
+ struct timespec abstime;
+ void *p_stack;
+
+ /* Block all signals */
+ sigfillset (&mask);
+ sigprocmask (SIG_BLOCK, &mask, NULL);
+
+ /* Mark this thread as a library thread (not a user thread). */
+ _thread_run->flags |= PTHREAD_FLAGS_PRIVATE;
+
+ /* Set a debug flag based on an environment variable. */
+ f_debug = (getenv("LIBC_R_DEBUG") != NULL);
+
+ /* Set the name of this thread. */
+ pthread_set_name_np(_thread_run,"GC");
+
+ while (!f_done) {
+ /* Check if debugging this application. */
+ if (f_debug)
+ /* Dump thread info to file. */
+ _thread_dump_info();
+
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Check if this is the last running thread: */
+ if (TAILQ_FIRST(&_thread_list) == _thread_run &&
+ TAILQ_NEXT(_thread_run, tle) == NULL)
+ /*
+ * This is the last thread, so it can exit
+ * now.
+ */
+ f_done = 1;
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ /*
+ * Lock the garbage collector mutex which ensures that
+ * this thread sees another thread exit:
+ */
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* No stack of thread structure to free yet: */
+ p_stack = NULL;
+ pthread_cln = NULL;
+
+ /*
+ * Enter a loop to search for the first dead thread that
+ * has memory to free.
+ */
+ for (pthread = TAILQ_FIRST(&_dead_list);
+ p_stack == NULL && pthread_cln == NULL && pthread != NULL;
+ pthread = TAILQ_NEXT(pthread, dle)) {
+ /* Check if the initial thread: */
+ if (pthread == _thread_initial) {
+ /* Don't destroy the initial thread. */
+ }
+ /*
+ * Check if this thread has detached:
+ */
+ else if ((pthread->attr.flags &
+ PTHREAD_DETACHED) != 0) {
+ /* Remove this thread from the dead list: */
+ TAILQ_REMOVE(&_dead_list, pthread, dle);
+
+ /*
+ * Check if the stack was not specified by
+ * the caller to pthread_create and has not
+ * been destroyed yet:
+ */
+ if (pthread->attr.stackaddr_attr == NULL &&
+ pthread->stack != NULL) {
+ if (pthread->attr.stacksize_attr
+ == PTHREAD_STACK_DEFAULT) {
+ /*
+ * Default-size stack. Cache
+ * it:
+ */
+ struct stack *spare_stack;
+
+ spare_stack
+ = (pthread->stack
+ + PTHREAD_STACK_DEFAULT
+ - sizeof(struct stack));
+ SLIST_INSERT_HEAD(&_stackq,
+ spare_stack,
+ qe);
+ } else {
+ /*
+ * Non-standard stack size.
+ * free() it outside the locks.
+ */
+ p_stack = pthread->stack;
+ }
+ }
+
+ /*
+ * Point to the thread structure that must
+ * be freed outside the locks:
+ */
+ pthread_cln = pthread;
+
+ } else {
+ /*
+ * This thread has not detached, so do
+ * not destroy it.
+ *
+ * Check if the stack was not specified by
+ * the caller to pthread_create and has not
+ * been destroyed yet:
+ */
+ if (pthread->attr.stackaddr_attr == NULL &&
+ pthread->stack != NULL) {
+ if (pthread->attr.stacksize_attr
+ == PTHREAD_STACK_DEFAULT) {
+ /*
+ * Default-size stack. Cache
+ * it:
+ */
+ struct stack *spare_stack;
+
+ spare_stack
+ = (pthread->stack
+ + PTHREAD_STACK_DEFAULT
+ - sizeof(struct stack));
+ SLIST_INSERT_HEAD(&_stackq,
+ spare_stack,
+ qe);
+ } else {
+ /*
+ * Non-standard stack size.
+ * free() it outside the locks:
+ */
+ p_stack = pthread->stack;
+ }
+
+ /*
+ * NULL the stack pointer now
+ * that the memory has been freed:
+ */
+ pthread->stack = NULL;
+ }
+ }
+ }
+
+ /*
+ * Check if this is not the last thread and there is no
+ * memory to free this time around.
+ */
+ if (!f_done && p_stack == NULL && pthread_cln == NULL) {
+ /* Get the current time. */
+ if (clock_gettime(CLOCK_REALTIME,&abstime) != 0)
+ PANIC("gc cannot get time");
+
+ /*
+ * Do a backup poll in 10 seconds if no threads
+ * die before then.
+ */
+ abstime.tv_sec += 10;
+
+ /*
+ * Wait for a signal from a dying thread or a
+ * timeout (for a backup poll).
+ */
+ if ((ret = pthread_cond_timedwait(&_gc_cond,
+ &_gc_mutex, &abstime)) != 0 && ret != ETIMEDOUT)
+ PANIC("gc cannot wait for a signal");
+ }
+
+ /* Unlock the garbage collector mutex: */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
+
+ /*
+ * If there is memory to free, do it now. The call to
+ * free() might block, so this must be done outside the
+ * locks.
+ */
+ if (p_stack != NULL)
+ free(p_stack);
+ if (pthread_cln != NULL)
+ /*
+ * Free the memory allocated for the thread
+ * structure.
+ */
+ free(pthread_cln);
+ }
+ return (NULL);
+}
diff --git a/lib/libc_r/uthread/uthread_getdirentries.c b/lib/libc_r/uthread/uthread_getdirentries.c
new file mode 100644
index 0000000..e3c5c76
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_getdirentries.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <dirent.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+getdirentries(int fd, char *buf, int nbytes, long *basep)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ ret = _thread_sys_getdirentries(fd, buf, nbytes, basep);
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_getpeername.c b/lib/libc_r/uthread/uthread_getpeername.c
new file mode 100644
index 0000000..4e972a6
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_getpeername.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+getpeername(int fd, struct sockaddr * peer, socklen_t *paddrlen)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ ret = _thread_sys_getpeername(fd, peer, paddrlen);
+ _FD_UNLOCK(fd, FD_READ);
+ }
+ return ret;
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_getprio.c b/lib/libc_r/uthread/uthread_getprio.c
new file mode 100644
index 0000000..2f94b86
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_getprio.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_getprio(pthread_t pthread)
+{
+ int policy, ret;
+ struct sched_param param;
+
+ if ((ret = pthread_getschedparam(pthread, &policy, &param)) == 0)
+ ret = param.sched_priority;
+ else {
+ /* Invalid thread: */
+ errno = ret;
+ ret = -1;
+ }
+
+ /* Return the thread priority or an error status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_getschedparam.c b/lib/libc_r/uthread/uthread_getschedparam.c
new file mode 100644
index 0000000..09d8c1b
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_getschedparam.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_getschedparam(pthread_t pthread, int *policy,
+ struct sched_param *param)
+{
+ int ret;
+
+ if ((param == NULL) || (policy == NULL))
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+
+ /* Find the thread in the list of active threads: */
+ else if ((ret = _find_thread(pthread)) == 0) {
+ /* Return the threads base priority and scheduling policy: */
+ param->sched_priority = pthread->base_priority;
+ *policy = pthread->attr.sched_policy;
+ }
+
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_getsockname.c b/lib/libc_r/uthread/uthread_getsockname.c
new file mode 100644
index 0000000..691394c
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_getsockname.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+getsockname(int s, struct sockaddr * name, socklen_t *namelen)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(s, FD_READ, NULL)) == 0) {
+ ret = _thread_sys_getsockname(s, name, namelen);
+ _FD_UNLOCK(s, FD_READ);
+ }
+ return ret;
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_getsockopt.c b/lib/libc_r/uthread/uthread_getsockopt.c
new file mode 100644
index 0000000..ad293fa
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_getsockopt.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ ret = _thread_sys_getsockopt(fd, level, optname, optval, optlen);
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ return ret;
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_info.c b/lib/libc_r/uthread/uthread_info.c
new file mode 100644
index 0000000..06b556e
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_info.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include <errno.h>
+#include "pthread_private.h"
+
+struct s_thread_info {
+ enum pthread_state state;
+ char *name;
+};
+
+/* Static variables: */
+static const struct s_thread_info thread_info[] = {
+ {PS_RUNNING , "Running"},
+ {PS_SIGTHREAD , "Waiting on signal thread"},
+ {PS_MUTEX_WAIT , "Waiting on a mutex"},
+ {PS_COND_WAIT , "Waiting on a condition variable"},
+ {PS_FDLR_WAIT , "Waiting for a file read lock"},
+ {PS_FDLW_WAIT , "Waiting for a file write lock"},
+ {PS_FDR_WAIT , "Waiting for read"},
+ {PS_FDW_WAIT , "Waiting for write"},
+ {PS_FILE_WAIT , "Waiting for FILE lock"},
+ {PS_POLL_WAIT , "Waiting on poll"},
+ {PS_SELECT_WAIT , "Waiting on select"},
+ {PS_SLEEP_WAIT , "Sleeping"},
+ {PS_WAIT_WAIT , "Waiting process"},
+ {PS_SIGSUSPEND , "Suspended, waiting for a signal"},
+ {PS_SIGWAIT , "Waiting for a signal"},
+ {PS_SPINBLOCK , "Waiting for a spinlock"},
+ {PS_JOIN , "Waiting to join"},
+ {PS_SUSPENDED , "Suspended"},
+ {PS_DEAD , "Dead"},
+ {PS_DEADLOCK , "Deadlocked"},
+ {PS_STATE_MAX , "Not a real state!"}
+};
+
+void
+_thread_dump_info(void)
+{
+ char s[512];
+ int fd;
+ int i;
+ int j;
+ pthread_t pthread;
+ char tmpfile[128];
+ pq_list_t *pq_list;
+
+ for (i = 0; i < 100000; i++) {
+ snprintf(tmpfile, sizeof(tmpfile), "/tmp/uthread.dump.%u.%i",
+ getpid(), i);
+ /* Open the dump file for append and create it if necessary: */
+ if ((fd = _thread_sys_open(tmpfile, O_RDWR | O_CREAT | O_EXCL,
+ 0666)) < 0) {
+ /* Can't open the dump file. */
+ if (errno == EEXIST)
+ continue;
+ /*
+ * We only need to continue in case of
+ * EEXIT error. Most other error
+ * codes means that we will fail all
+ * the times.
+ */
+ return;
+ } else {
+ break;
+ }
+ }
+ if (i==100000) {
+ /* all 100000 possibilities are in use :( */
+ return;
+ } else {
+ /* Output a header for active threads: */
+ strcpy(s, "\n\n=============\nACTIVE THREADS\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report each thread in the global list: */
+ TAILQ_FOREACH(pthread, &_thread_list, tle) {
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
+ break;
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->base_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Check if this is the running thread: */
+ if (pthread == _thread_run) {
+ /* Output a record for the running thread: */
+ strcpy(s, "This is the running thread\n");
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ /* Check if this is the initial thread: */
+ if (pthread == _thread_initial) {
+ /* Output a record for the initial thread: */
+ strcpy(s, "This is the initial thread\n");
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ /* Process according to thread state: */
+ switch (pthread->state) {
+ /* File descriptor read lock wait: */
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ /* Write the lock details: */
+ snprintf(s, sizeof(s), "fd %d[%s:%d]",
+ pthread->data.fd.fd,
+ pthread->data.fd.fname,
+ pthread->data.fd.branch);
+ _thread_sys_write(fd, s, strlen(s));
+ snprintf(s, sizeof(s), "owner %pr/%pw\n",
+ _thread_fd_table[pthread->data.fd.fd]->r_owner,
+ _thread_fd_table[pthread->data.fd.fd]->w_owner);
+ _thread_sys_write(fd, s, strlen(s));
+ break;
+ case PS_SIGWAIT:
+ snprintf(s, sizeof(s), "sigmask (hi)");
+ _thread_sys_write(fd, s, strlen(s));
+ for (i = _SIG_WORDS - 1; i >= 0; i--) {
+ snprintf(s, sizeof(s), "%08x\n",
+ pthread->sigmask.__bits[i]);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ snprintf(s, sizeof(s), "(lo)\n");
+ _thread_sys_write(fd, s, strlen(s));
+ break;
+
+ /*
+ * Trap other states that are not explicitly
+ * coded to dump information:
+ */
+ default:
+ /* Nothing to do here. */
+ break;
+ }
+ }
+
+ /* Output a header for ready threads: */
+ strcpy(s, "\n\n=============\nREADY THREADS\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report each thread in the ready queue: */
+ TAILQ_FOREACH (pq_list, &_readyq.pq_queue, pl_link) {
+ TAILQ_FOREACH(pthread, &pq_list->pl_head, pqe) {
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
+ break;
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->base_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ }
+
+ /* Output a header for waiting threads: */
+ strcpy(s, "\n\n=============\nWAITING THREADS\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report each thread in the waiting queue: */
+ TAILQ_FOREACH (pthread, &_waitingq, pqe) {
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
+ break;
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->base_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+
+ /* Output a header for threads in the work queue: */
+ strcpy(s, "\n\n=============\nTHREADS IN WORKQ\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report each thread in the waiting queue: */
+ TAILQ_FOREACH (pthread, &_workq, qe) {
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
+ break;
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->base_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+
+ /* Check if there are no dead threads: */
+ if (TAILQ_FIRST(&_dead_list) == NULL) {
+ /* Output a record: */
+ strcpy(s, "\n\nTHERE ARE NO DEAD THREADS\n");
+ _thread_sys_write(fd, s, strlen(s));
+ } else {
+ /* Output a header for dead threads: */
+ strcpy(s, "\n\nDEAD THREADS\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /*
+ * Enter a loop to report each thread in the global
+ * dead thread list:
+ */
+ TAILQ_FOREACH(pthread, &_dead_list, dle) {
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "Thread %p prio %3d [%s:%d]\n",
+ pthread, pthread->base_priority,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ }
+
+ /* Output a header for file descriptors: */
+ snprintf(s, sizeof(s), "\n\n=============\nFILE DESCRIPTOR TABLE (table size %d)\n\n",_thread_dtablesize);
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report file descriptor lock usage: */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /*
+ * Check if memory is allocated for this file
+ * descriptor:
+ */
+ if (_thread_fd_table[i] != NULL) {
+ /* Report the file descriptor lock status: */
+ snprintf(s, sizeof(s),
+ "fd[%3d] read owner %p count %d [%s:%d]\n write owner %p count %d [%s:%d]\n",
+ i,
+ _thread_fd_table[i]->r_owner,
+ _thread_fd_table[i]->r_lockcount,
+ _thread_fd_table[i]->r_fname,
+ _thread_fd_table[i]->r_lineno,
+ _thread_fd_table[i]->w_owner,
+ _thread_fd_table[i]->w_lockcount,
+ _thread_fd_table[i]->w_fname,
+ _thread_fd_table[i]->w_lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ }
+
+ /* Close the dump file: */
+ _thread_sys_close(fd);
+ }
+ return;
+}
+
+/* Set the thread name for debug: */
+void
+pthread_set_name_np(pthread_t thread, char *name)
+{
+ /* Check if the caller has specified a valid thread: */
+ if (thread != NULL && thread->magic == PTHREAD_MAGIC)
+ thread->name = strdup(name);
+ return;
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_init.c b/lib/libc_r/uthread/uthread_init.c
new file mode 100644
index 0000000..bab7e5b
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_init.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/* Allocate space for global thread variables here: */
+#define GLOBAL_PTHREAD_PRIVATE
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <poll.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/ttycom.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/mman.h>
+#ifdef _THREAD_SAFE
+#include <machine/reg.h>
+#include <pthread.h>
+#include "pthread_private.h"
+
+#ifdef GCC_2_8_MADE_THREAD_AWARE
+typedef void *** (*dynamic_handler_allocator)();
+extern void __set_dynamic_handler_allocator(dynamic_handler_allocator);
+
+static pthread_key_t except_head_key;
+
+typedef struct {
+ void **__dynamic_handler_chain;
+ void *top_elt[2];
+} except_struct;
+
+static void ***dynamic_allocator_handler_fn()
+{
+ except_struct *dh = (except_struct *)pthread_getspecific(except_head_key);
+
+ if(dh == NULL) {
+ dh = (except_struct *)malloc( sizeof(except_struct) );
+ memset(dh, '\0', sizeof(except_struct));
+ dh->__dynamic_handler_chain= dh->top_elt;
+ pthread_setspecific(except_head_key, (void *)dh);
+ }
+ return &dh->__dynamic_handler_chain;
+}
+#endif /* GCC_2_8_MADE_THREAD_AWARE */
+
+/*
+ * Threaded process initialization
+ */
+void
+_thread_init(void)
+{
+ int fd;
+ int flags;
+ int i;
+ size_t len;
+ int mib[2];
+ struct clockinfo clockinfo;
+ struct sigaction act;
+
+ /* Check if this function has already been called: */
+ if (_thread_initial)
+ /* Only initialise the threaded application once. */
+ return;
+
+ /*
+ * Check for the special case of this process running as
+ * or in place of init as pid = 1:
+ */
+ if (getpid() == 1) {
+ /*
+ * Setup a new session for this process which is
+ * assumed to be running as root.
+ */
+ if (setsid() == -1)
+ PANIC("Can't set session ID");
+ if (revoke(_PATH_CONSOLE) != 0)
+ PANIC("Can't revoke console");
+ if ((fd = _thread_sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
+ PANIC("Can't open console");
+ if (setlogin("root") == -1)
+ PANIC("Can't set login to root");
+ if (_thread_sys_ioctl(fd,TIOCSCTTY, (char *) NULL) == -1)
+ PANIC("Can't set controlling terminal");
+ if (_thread_sys_dup2(fd,0) == -1 ||
+ _thread_sys_dup2(fd,1) == -1 ||
+ _thread_sys_dup2(fd,2) == -1)
+ PANIC("Can't dup2");
+ }
+
+ /* Get the standard I/O flags before messing with them : */
+ for (i = 0; i < 3; i++)
+ if (((_pthread_stdio_flags[i] =
+ _thread_sys_fcntl(i,F_GETFL, NULL)) == -1) &&
+ (errno != EBADF))
+ PANIC("Cannot get stdio flags");
+
+ /*
+ * Create a pipe that is written to by the signal handler to prevent
+ * signals being missed in calls to _select:
+ */
+ if (_thread_sys_pipe(_thread_kern_pipe) != 0) {
+ /* Cannot create pipe, so abort: */
+ PANIC("Cannot create kernel pipe");
+ }
+ /* Get the flags for the read pipe: */
+ else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[0], F_GETFL, NULL)) == -1) {
+ /* Abort this application: */
+ PANIC("Cannot get kernel read pipe flags");
+ }
+ /* Make the read pipe non-blocking: */
+ else if (_thread_sys_fcntl(_thread_kern_pipe[0], F_SETFL, flags | O_NONBLOCK) == -1) {
+ /* Abort this application: */
+ PANIC("Cannot make kernel read pipe non-blocking");
+ }
+ /* Get the flags for the write pipe: */
+ else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[1], F_GETFL, NULL)) == -1) {
+ /* Abort this application: */
+ PANIC("Cannot get kernel write pipe flags");
+ }
+ /* Make the write pipe non-blocking: */
+ else if (_thread_sys_fcntl(_thread_kern_pipe[1], F_SETFL, flags | O_NONBLOCK) == -1) {
+ /* Abort this application: */
+ PANIC("Cannot get kernel write pipe flags");
+ }
+ /* Allocate and initialize the ready queue: */
+ else if (_pq_alloc(&_readyq, PTHREAD_MIN_PRIORITY, PTHREAD_MAX_PRIORITY) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot allocate priority ready queue.");
+ }
+ /* Allocate memory for the thread structure of the initial thread: */
+ else if ((_thread_initial = (pthread_t) malloc(sizeof(struct pthread))) == NULL) {
+ /*
+ * Insufficient memory to initialise this application, so
+ * abort:
+ */
+ PANIC("Cannot allocate memory for initial thread");
+ } else {
+ /* Zero the global kernel thread structure: */
+ memset(&_thread_kern_thread, 0, sizeof(struct pthread));
+ _thread_kern_thread.flags = PTHREAD_FLAGS_PRIVATE;
+ memset(_thread_initial, 0, sizeof(struct pthread));
+
+ /* Initialize the waiting and work queues: */
+ TAILQ_INIT(&_waitingq);
+ TAILQ_INIT(&_workq);
+
+ /* Initialize the scheduling switch hook routine: */
+ _sched_switch_hook = NULL;
+
+ /* Initialize the thread stack cache: */
+ SLIST_INIT(&_stackq);
+
+ /* Create the red zone for the main stack. */
+ if (mmap((void *) USRSTACK
+ - PTHREAD_STACK_INITIAL,
+ PTHREAD_STACK_GUARD, 0, MAP_ANON,
+ -1, 0) == MAP_FAILED) {
+ PANIC("Cannot allocate red zone for initial thread");
+ }
+
+ /*
+ * Write a magic value to the thread structure
+ * to help identify valid ones:
+ */
+ _thread_initial->magic = PTHREAD_MAGIC;
+
+ /* Set the initial cancel state */
+ _thread_initial->cancelflags = PTHREAD_CANCEL_ENABLE |
+ PTHREAD_CANCEL_DEFERRED;
+
+ /* Default the priority of the initial thread: */
+ _thread_initial->base_priority = PTHREAD_DEFAULT_PRIORITY;
+ _thread_initial->active_priority = PTHREAD_DEFAULT_PRIORITY;
+ _thread_initial->inherited_priority = 0;
+
+ /* Initialise the state of the initial thread: */
+ _thread_initial->state = PS_RUNNING;
+
+ /* Initialise the queue: */
+ TAILQ_INIT(&(_thread_initial->join_queue));
+
+ /* Initialize the owned mutex queue and count: */
+ TAILQ_INIT(&(_thread_initial->mutexq));
+ _thread_initial->priority_mutex_count = 0;
+
+ /* Initialise the rest of the fields: */
+ _thread_initial->poll_data.nfds = 0;
+ _thread_initial->poll_data.fds = NULL;
+ _thread_initial->sig_defer_count = 0;
+ _thread_initial->yield_on_sig_undefer = 0;
+ _thread_initial->specific_data = NULL;
+ _thread_initial->cleanup = NULL;
+ _thread_initial->flags = 0;
+ _thread_initial->error = 0;
+ TAILQ_INIT(&_thread_list);
+ TAILQ_INSERT_HEAD(&_thread_list, _thread_initial, tle);
+ _thread_run = _thread_initial;
+
+ /* Initialise the global signal action structure: */
+ sigfillset(&act.sa_mask);
+ act.sa_handler = (void (*) ()) _thread_sig_handler;
+ act.sa_flags = 0;
+
+ /* Initialize signal handling: */
+ _thread_sig_init();
+
+ /* Enter a loop to get the existing signal status: */
+ for (i = 1; i < NSIG; i++) {
+ /* Check for signals which cannot be trapped: */
+ if (i == SIGKILL || i == SIGSTOP) {
+ }
+
+ /* Get the signal handler details: */
+ else if (_thread_sys_sigaction(i, NULL,
+ &_thread_sigact[i - 1]) != 0) {
+ /*
+ * Abort this process if signal
+ * initialisation fails:
+ */
+ PANIC("Cannot read signal handler info");
+ }
+ }
+
+ /*
+ * Install the signal handler for the most important
+ * signals that the user-thread kernel needs. Actually
+ * SIGINFO isn't really needed, but it is nice to have.
+ */
+ if (_thread_sys_sigaction(_SCHED_SIGNAL, &act, NULL) != 0 ||
+ _thread_sys_sigaction(SIGINFO, &act, NULL) != 0 ||
+ _thread_sys_sigaction(SIGCHLD, &act, NULL) != 0) {
+ /*
+ * Abort this process if signal initialisation fails:
+ */
+ PANIC("Cannot initialise signal handler");
+ }
+
+ /* Get the kernel clockrate: */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_CLOCKRATE;
+ len = sizeof (struct clockinfo);
+ if (sysctl(mib, 2, &clockinfo, &len, NULL, 0) == 0)
+ _clock_res_nsec = clockinfo.tick * 1000;
+
+ /* Get the table size: */
+ if ((_thread_dtablesize = getdtablesize()) < 0) {
+ /*
+ * Cannot get the system defined table size, so abort
+ * this process.
+ */
+ PANIC("Cannot get dtablesize");
+ }
+ /* Allocate memory for the file descriptor table: */
+ if ((_thread_fd_table = (struct fd_table_entry **) malloc(sizeof(struct fd_table_entry *) * _thread_dtablesize)) == NULL) {
+ /* Avoid accesses to file descriptor table on exit: */
+ _thread_dtablesize = 0;
+
+ /*
+ * Cannot allocate memory for the file descriptor
+ * table, so abort this process.
+ */
+ PANIC("Cannot allocate memory for file descriptor table");
+ }
+ /* Allocate memory for the pollfd table: */
+ if ((_thread_pfd_table = (struct pollfd *) malloc(sizeof(struct pollfd) * _thread_dtablesize)) == NULL) {
+ /*
+ * Cannot allocate memory for the file descriptor
+ * table, so abort this process.
+ */
+ PANIC("Cannot allocate memory for pollfd table");
+ } else {
+ /*
+ * Enter a loop to initialise the file descriptor
+ * table:
+ */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /* Initialise the file descriptor table: */
+ _thread_fd_table[i] = NULL;
+ }
+
+ /* Initialize stdio file descriptor table entries: */
+ for (i = 0; i < 3; i++) {
+ if ((_thread_fd_table_init(i) != 0) &&
+ (errno != EBADF))
+ PANIC("Cannot initialize stdio file "
+ "descriptor table entry");
+ }
+ }
+ }
+
+#ifdef GCC_2_8_MADE_THREAD_AWARE
+ /* Create the thread-specific data for the exception linked list. */
+ if(pthread_key_create(&except_head_key, NULL) != 0)
+ PANIC("Failed to create thread specific execption head");
+
+ /* Setup the gcc exception handler per thread. */
+ __set_dynamic_handler_allocator( dynamic_allocator_handler_fn );
+#endif /* GCC_2_8_MADE_THREAD_AWARE */
+
+ /* Initialise the garbage collector mutex and condition variable. */
+ if (pthread_mutex_init(&_gc_mutex,NULL) != 0 ||
+ pthread_cond_init(&_gc_cond,NULL) != 0)
+ PANIC("Failed to initialise garbage collector mutex or condvar");
+
+ gettimeofday(&kern_inc_prio_time, NULL);
+
+ return;
+}
+
+/*
+ * Special start up code for NetBSD/Alpha
+ */
+#if defined(__NetBSD__) && defined(__alpha__)
+int
+main(int argc, char *argv[], char *env);
+
+int
+_thread_main(int argc, char *argv[], char *env)
+{
+ _thread_init();
+ return (main(argc, argv, env));
+}
+#endif
+#else
+/*
+ * A stub for non-threaded programs.
+ */
+void
+_thread_init(void)
+{
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_ioctl.c b/lib/libc_r/uthread/uthread_ioctl.c
new file mode 100644
index 0000000..f2c4531
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_ioctl.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdarg.h>
+#include <sys/ioctl.h>
+#ifdef _THREAD_SAFE
+#include <sys/fcntl.h> /* O_NONBLOCK*/
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+ioctl(int fd, unsigned long request,...)
+{
+ int ret;
+ int *op;
+ va_list ap;
+
+ /* Lock the file descriptor: */
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ /* Initialise the variable argument list: */
+ va_start(ap, request);
+
+ switch( request) {
+ case FIONBIO:
+ /*
+ * descriptors must be non-blocking; we are only
+ * twiddling the flag based on the request
+ */
+ op = va_arg(ap, int *);
+ _thread_fd_table[fd]->flags &= ~O_NONBLOCK;
+ _thread_fd_table[fd]->flags |= ((*op) ? O_NONBLOCK : 0);
+ ret = 0;
+ break;
+ default:
+ ret = _thread_sys_ioctl(fd, request, va_arg(ap, char *));
+ break;
+ }
+
+ /* Free variable arguments: */
+ va_end(ap);
+
+ /* Unlock the file descriptor: */
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_join.c b/lib/libc_r/uthread/uthread_join.c
new file mode 100644
index 0000000..155dc64
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_join.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_join(pthread_t pthread, void **thread_return)
+{
+ int ret = 0;
+ pthread_t pthread1 = NULL;
+
+ _thread_enter_cancellation_point();
+
+ /* Check if the caller has specified an invalid thread: */
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) {
+ /* Invalid thread: */
+ _thread_leave_cancellation_point();
+ return(EINVAL);
+ }
+
+ /* Check if the caller has specified itself: */
+ if (pthread == _thread_run) {
+ /* Avoid a deadlock condition: */
+ _thread_leave_cancellation_point();
+ return(EDEADLK);
+ }
+
+ /*
+ * Find the thread in the list of active threads or in the
+ * list of dead threads:
+ */
+ if (_find_thread(pthread) == 0 ||
+ _find_dead_thread(pthread) == 0)
+ pthread1 = pthread;
+
+ if (pthread1 == NULL)
+ /* Return an error: */
+ ret = ESRCH;
+
+ /* Check if this thread has been detached: */
+ else if ((pthread->attr.flags & PTHREAD_DETACHED) != 0)
+ /* Return an error: */
+ ret = ESRCH;
+
+ /* Check if the thread is not dead: */
+ else if (pthread->state != PS_DEAD) {
+ /* Clear the interrupted flag: */
+ _thread_run->interrupted = 0;
+
+ /*
+ * Protect against being context switched out while
+ * adding this thread to the join queue.
+ */
+ _thread_kern_sig_defer();
+
+ /* Add the running thread to the join queue: */
+ TAILQ_INSERT_TAIL(&(pthread->join_queue), _thread_run, qe);
+
+ /* Schedule the next thread: */
+ _thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__);
+
+ if (_thread_run->interrupted != 0)
+ TAILQ_REMOVE(&(pthread->join_queue), _thread_run, qe);
+
+ _thread_kern_sig_undefer();
+
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+
+ /* Check if the thread is not detached: */
+ if ((pthread->attr.flags & PTHREAD_DETACHED) == 0) {
+ /* Check if the return value is required: */
+ if (thread_return)
+ /* Return the thread's return value: */
+ *thread_return = pthread->ret;
+ }
+ else
+ /* Return an error: */
+ ret = ESRCH;
+
+ /* Check if the return value is required: */
+ } else if (thread_return != NULL)
+ /* Return the thread's return value: */
+ *thread_return = pthread->ret;
+
+ _thread_leave_cancellation_point();
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_kern.c b/lib/libc_r/uthread/uthread_kern.c
new file mode 100644
index 0000000..b3fbc3a
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_kern.c
@@ -0,0 +1,1135 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <errno.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <setjmp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Static function prototype definitions: */
+static void
+_thread_kern_poll(int wait_reqd);
+
+static void
+dequeue_signals(void);
+
+static inline void
+thread_run_switch_hook(pthread_t thread_out, pthread_t thread_in);
+
+void
+_thread_kern_sched(ucontext_t * scp)
+{
+#ifndef __alpha__
+ char *fdata;
+#endif
+ pthread_t pthread, pthread_h = NULL;
+ struct itimerval itimer;
+ struct timespec ts, ts1;
+ struct timeval tv, tv1;
+ int set_timer = 0;
+
+ /*
+ * Flag the pthread kernel as executing scheduler code
+ * to avoid a scheduler signal from interrupting this
+ * execution and calling the scheduler again.
+ */
+ _thread_kern_in_sched = 1;
+
+ /* Check if this function was called from the signal handler: */
+ if (scp != NULL) {
+ /*
+ * Copy the signal context to the current thread's jump
+ * buffer:
+ */
+ memcpy(&_thread_run->saved_sigcontext, scp, sizeof(_thread_run->saved_sigcontext));
+
+#ifndef __alpha__
+ /* Point to the floating point data in the running thread: */
+ fdata = _thread_run->saved_fp;
+
+ /* Save the floating point data: */
+__asm__("fnsave %0": :"m"(*fdata));
+#endif
+
+ /* Flag the signal context as the last state saved: */
+ _thread_run->sig_saved = 1;
+ }
+ /* Save the state of the current thread: */
+ else if (setjmp(_thread_run->saved_jmp_buf) != 0) {
+ /*
+ * This point is reached when a longjmp() is called to
+ * restore the state of a thread.
+ *
+ * This is the normal way out of the scheduler.
+ */
+ _thread_kern_in_sched = 0;
+
+ if (((_thread_run->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0) &&
+ ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)) {
+ /*
+ * Cancellations override signals.
+ *
+ * Stick a cancellation point at the start of
+ * each async-cancellable thread's resumption.
+ *
+ * We allow threads woken at cancel points to do their
+ * own checks.
+ */
+ pthread_testcancel();
+ }
+
+ if (_sched_switch_hook != NULL) {
+ /* Run the installed switch hook: */
+ thread_run_switch_hook(_last_user_thread, _thread_run);
+ }
+
+ return;
+ } else
+ /* Flag the jump buffer was the last state saved: */
+ _thread_run->sig_saved = 0;
+
+ /* If the currently running thread is a user thread, save it: */
+ if ((_thread_run->flags & PTHREAD_FLAGS_PRIVATE) == 0)
+ _last_user_thread = _thread_run;
+
+ /*
+ * Enter a scheduling loop that finds the next thread that is
+ * ready to run. This loop completes when there are no more threads
+ * in the global list or when a thread has its state restored by
+ * either a sigreturn (if the state was saved as a sigcontext) or a
+ * longjmp (if the state was saved by a setjmp).
+ */
+ while (!(TAILQ_EMPTY(&_thread_list))) {
+ /* Get the current time of day: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
+
+ /*
+ * Protect the scheduling queues from access by the signal
+ * handler.
+ */
+ _queue_signals = 1;
+
+ if (_thread_run != &_thread_kern_thread) {
+
+ /*
+ * This thread no longer needs to yield the CPU.
+ */
+ _thread_run->yield_on_sig_undefer = 0;
+
+ /*
+ * Save the current time as the time that the thread
+ * became inactive:
+ */
+ _thread_run->last_inactive.tv_sec = tv.tv_sec;
+ _thread_run->last_inactive.tv_usec = tv.tv_usec;
+
+ /*
+ * Place the currently running thread into the
+ * appropriate queue(s).
+ */
+ switch (_thread_run->state) {
+ case PS_DEAD:
+ case PS_STATE_MAX: /* to silence -Wall */
+ /*
+ * Dead threads are not placed in any queue:
+ */
+ break;
+
+ case PS_RUNNING:
+ /*
+ * Runnable threads can't be placed in the
+ * priority queue until after waiting threads
+ * are polled (to preserve round-robin
+ * scheduling).
+ */
+ if ((_thread_run->slice_usec != -1) &&
+ (_thread_run->attr.sched_policy != SCHED_FIFO)) {
+ /*
+ * Accumulate the number of microseconds that
+ * this thread has run for:
+ */
+ _thread_run->slice_usec +=
+ (_thread_run->last_inactive.tv_sec -
+ _thread_run->last_active.tv_sec) * 1000000 +
+ _thread_run->last_inactive.tv_usec -
+ _thread_run->last_active.tv_usec;
+
+ /* Check for time quantum exceeded: */
+ if (_thread_run->slice_usec > TIMESLICE_USEC)
+ _thread_run->slice_usec = -1;
+ }
+ break;
+
+ /*
+ * States which do not depend on file descriptor I/O
+ * operations or timeouts:
+ */
+ case PS_DEADLOCK:
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ case PS_JOIN:
+ case PS_MUTEX_WAIT:
+ case PS_SIGSUSPEND:
+ case PS_SIGTHREAD:
+ case PS_SIGWAIT:
+ case PS_SUSPENDED:
+ case PS_WAIT_WAIT:
+ /* No timeouts for these states: */
+ _thread_run->wakeup_time.tv_sec = -1;
+ _thread_run->wakeup_time.tv_nsec = -1;
+
+ /* Restart the time slice: */
+ _thread_run->slice_usec = -1;
+
+ /* Insert into the waiting queue: */
+ PTHREAD_WAITQ_INSERT(_thread_run);
+ break;
+
+ /* States which can timeout: */
+ case PS_COND_WAIT:
+ case PS_SLEEP_WAIT:
+ /* Restart the time slice: */
+ _thread_run->slice_usec = -1;
+
+ /* Insert into the waiting queue: */
+ PTHREAD_WAITQ_INSERT(_thread_run);
+ break;
+
+ /* States that require periodic work: */
+ case PS_SPINBLOCK:
+ /* No timeouts for this state: */
+ _thread_run->wakeup_time.tv_sec = -1;
+ _thread_run->wakeup_time.tv_nsec = -1;
+
+ /* Increment spinblock count: */
+ _spinblock_count++;
+
+ /* fall through */
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Restart the time slice: */
+ _thread_run->slice_usec = -1;
+
+ /* Insert into the waiting queue: */
+ PTHREAD_WAITQ_INSERT(_thread_run);
+
+ /* Insert into the work queue: */
+ PTHREAD_WORKQ_INSERT(_thread_run);
+ break;
+ }
+ }
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ /*
+ * Poll file descriptors to update the state of threads
+ * waiting on file I/O where data may be available:
+ */
+ _thread_kern_poll(0);
+
+ /* Protect the scheduling queues: */
+ _queue_signals = 1;
+
+ /*
+ * Wake up threads that have timedout. This has to be
+ * done after polling in case a thread does a poll or
+ * select with zero time.
+ */
+ PTHREAD_WAITQ_SETACTIVE();
+ while (((pthread = TAILQ_FIRST(&_waitingq)) != NULL) &&
+ (pthread->wakeup_time.tv_sec != -1) &&
+ (((pthread->wakeup_time.tv_sec == 0) &&
+ (pthread->wakeup_time.tv_nsec == 0)) ||
+ (pthread->wakeup_time.tv_sec < ts.tv_sec) ||
+ ((pthread->wakeup_time.tv_sec == ts.tv_sec) &&
+ (pthread->wakeup_time.tv_nsec <= ts.tv_nsec)))) {
+ switch (pthread->state) {
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Return zero file descriptors ready: */
+ pthread->data.poll_data->nfds = 0;
+ /* fall through */
+ default:
+ /*
+ * Remove this thread from the waiting queue
+ * (and work queue if necessary) and place it
+ * in the ready queue.
+ */
+ PTHREAD_WAITQ_CLEARACTIVE();
+ if (pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread, PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ break;
+ }
+ /*
+ * Flag the timeout in the thread structure:
+ */
+ pthread->timeout = 1;
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+
+ /*
+ * Check if there is a current runnable thread that isn't
+ * already in the ready queue:
+ */
+ if ((_thread_run != &_thread_kern_thread) &&
+ (_thread_run->state == PS_RUNNING) &&
+ ((_thread_run->flags & PTHREAD_FLAGS_IN_PRIOQ) == 0)) {
+ if (_thread_run->slice_usec == -1) {
+ /*
+ * The thread exceeded its time
+ * quantum or it yielded the CPU;
+ * place it at the tail of the
+ * queue for its priority.
+ */
+ PTHREAD_PRIOQ_INSERT_TAIL(_thread_run);
+ } else {
+ /*
+ * The thread hasn't exceeded its
+ * interval. Place it at the head
+ * of the queue for its priority.
+ */
+ PTHREAD_PRIOQ_INSERT_HEAD(_thread_run);
+ }
+ }
+
+ /*
+ * Get the highest priority thread in the ready queue.
+ */
+ pthread_h = PTHREAD_PRIOQ_FIRST();
+
+ /* Check if there are no threads ready to run: */
+ if (pthread_h == NULL) {
+ /*
+ * Lock the pthread kernel by changing the pointer to
+ * the running thread to point to the global kernel
+ * thread structure:
+ */
+ _thread_run = &_thread_kern_thread;
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ /*
+ * There are no threads ready to run, so wait until
+ * something happens that changes this condition:
+ */
+ _thread_kern_poll(1);
+ }
+ else {
+ /* Remove the thread from the ready queue: */
+ PTHREAD_PRIOQ_REMOVE(pthread_h);
+
+ /* Get first thread on the waiting list: */
+ pthread = TAILQ_FIRST(&_waitingq);
+
+ /* Check to see if there is more than one thread: */
+ if (pthread_h != TAILQ_FIRST(&_thread_list) ||
+ TAILQ_NEXT(pthread_h, tle) != NULL)
+ set_timer = 1;
+ else
+ set_timer = 0;
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ /*
+ * Check for signals queued while the scheduling
+ * queues were protected:
+ */
+ while (_sigq_check_reqd != 0) {
+ /* Clear before handling queued signals: */
+ _sigq_check_reqd = 0;
+
+ /* Protect the scheduling queues again: */
+ _queue_signals = 1;
+
+ dequeue_signals();
+
+ /*
+ * Check for a higher priority thread that
+ * became runnable due to signal handling.
+ */
+ if (((pthread = PTHREAD_PRIOQ_FIRST()) != NULL) &&
+ (pthread->active_priority > pthread_h->active_priority)) {
+ /*
+ * Insert the lower priority thread
+ * at the head of its priority list:
+ */
+ PTHREAD_PRIOQ_INSERT_HEAD(pthread_h);
+
+ /* Remove the thread from the ready queue: */
+ PTHREAD_PRIOQ_REMOVE(pthread);
+
+ /* There's a new thread in town: */
+ pthread_h = pthread;
+ }
+
+ /* Get first thread on the waiting list: */
+ pthread = TAILQ_FIRST(&_waitingq);
+
+ /*
+ * Check to see if there is more than one
+ * thread:
+ */
+ if (pthread_h != TAILQ_FIRST(&_thread_list) ||
+ TAILQ_NEXT(pthread_h, tle) != NULL)
+ set_timer = 1;
+ else
+ set_timer = 0;
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+ }
+
+ /* Make the selected thread the current thread: */
+ _thread_run = pthread_h;
+
+ /*
+ * Save the current time as the time that the thread
+ * became active:
+ */
+ _thread_run->last_active.tv_sec = tv.tv_sec;
+ _thread_run->last_active.tv_usec = tv.tv_usec;
+
+ /*
+ * Define the maximum time before a scheduling signal
+ * is required:
+ */
+ itimer.it_value.tv_sec = 0;
+ itimer.it_value.tv_usec = TIMESLICE_USEC;
+
+ /*
+ * The interval timer is not reloaded when it
+ * times out. The interval time needs to be
+ * calculated every time.
+ */
+ itimer.it_interval.tv_sec = 0;
+ itimer.it_interval.tv_usec = 0;
+
+ /* Get first thread on the waiting list: */
+ if ((pthread != NULL) &&
+ (pthread->wakeup_time.tv_sec != -1)) {
+ /*
+ * Calculate the time until this thread
+ * is ready, allowing for the clock
+ * resolution:
+ */
+ ts1.tv_sec = pthread->wakeup_time.tv_sec
+ - ts.tv_sec;
+ ts1.tv_nsec = pthread->wakeup_time.tv_nsec
+ - ts.tv_nsec + _clock_res_nsec;
+
+ /*
+ * Check for underflow of the nanosecond field:
+ */
+ while (ts1.tv_nsec < 0) {
+ /*
+ * Allow for the underflow of the
+ * nanosecond field:
+ */
+ ts1.tv_sec--;
+ ts1.tv_nsec += 1000000000;
+ }
+ /*
+ * Check for overflow of the nanosecond field:
+ */
+ while (ts1.tv_nsec >= 1000000000) {
+ /*
+ * Allow for the overflow of the
+ * nanosecond field:
+ */
+ ts1.tv_sec++;
+ ts1.tv_nsec -= 1000000000;
+ }
+ /*
+ * Convert the timespec structure to a
+ * timeval structure:
+ */
+ TIMESPEC_TO_TIMEVAL(&tv1, &ts1);
+
+ /*
+ * Check if the thread will be ready
+ * sooner than the earliest ones found
+ * so far:
+ */
+ if (timercmp(&tv1, &itimer.it_value, <)) {
+ /*
+ * Update the time value:
+ */
+ itimer.it_value.tv_sec = tv1.tv_sec;
+ itimer.it_value.tv_usec = tv1.tv_usec;
+ }
+ }
+
+ /*
+ * Check if this thread is running for the first time
+ * or running again after using its full time slice
+ * allocation:
+ */
+ if (_thread_run->slice_usec == -1) {
+ /* Reset the accumulated time slice period: */
+ _thread_run->slice_usec = 0;
+ }
+
+ /* Check if there is more than one thread: */
+ if (set_timer != 0) {
+ /*
+ * Start the interval timer for the
+ * calculated time interval:
+ */
+ if (setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL) != 0) {
+ /*
+ * Cannot initialise the timer, so
+ * abort this process:
+ */
+ PANIC("Cannot set scheduling timer");
+ }
+ }
+
+ /* Check if a signal context was saved: */
+ if (_thread_run->sig_saved == 1) {
+#ifndef __alpha__
+ /*
+ * Point to the floating point data in the
+ * running thread:
+ */
+ fdata = _thread_run->saved_fp;
+
+ /* Restore the floating point state: */
+ __asm__("frstor %0": :"m"(*fdata));
+#endif
+ /*
+ * Do a sigreturn to restart the thread that
+ * was interrupted by a signal:
+ */
+ _thread_kern_in_sched = 0;
+
+ /*
+ * If we had a context switch, run any
+ * installed switch hooks.
+ */
+ if ((_sched_switch_hook != NULL) &&
+ (_last_user_thread != _thread_run)) {
+ thread_run_switch_hook(_last_user_thread,
+ _thread_run);
+ }
+ _thread_sys_sigreturn(&_thread_run->saved_sigcontext);
+ } else {
+ /*
+ * Do a longjmp to restart the thread that
+ * was context switched out (by a longjmp to
+ * a different thread):
+ */
+ longjmp(_thread_run->saved_jmp_buf, 1);
+ }
+
+ /* This point should not be reached. */
+ PANIC("Thread has returned from sigreturn or longjmp");
+ }
+ }
+
+ /* There are no more threads, so exit this process: */
+ exit(0);
+}
+
+void
+_thread_kern_sched_state(enum pthread_state state, char *fname, int lineno)
+{
+ /*
+ * Flag the pthread kernel as executing scheduler code
+ * to avoid a scheduler signal from interrupting this
+ * execution and calling the scheduler again.
+ */
+ _thread_kern_in_sched = 1;
+
+ /*
+ * Prevent the signal handler from fiddling with this thread
+ * before its state is set and is placed into the proper queue.
+ */
+ _queue_signals = 1;
+
+ /* Change the state of the current thread: */
+ _thread_run->state = state;
+ _thread_run->fname = fname;
+ _thread_run->lineno = lineno;
+
+ /* Schedule the next thread that is ready: */
+ _thread_kern_sched(NULL);
+ return;
+}
+
+void
+_thread_kern_sched_state_unlock(enum pthread_state state,
+ spinlock_t *lock, char *fname, int lineno)
+{
+ /*
+ * Flag the pthread kernel as executing scheduler code
+ * to avoid a scheduler signal from interrupting this
+ * execution and calling the scheduler again.
+ */
+ _thread_kern_in_sched = 1;
+
+ /*
+ * Prevent the signal handler from fiddling with this thread
+ * before its state is set and it is placed into the proper
+ * queue(s).
+ */
+ _queue_signals = 1;
+
+ /* Change the state of the current thread: */
+ _thread_run->state = state;
+ _thread_run->fname = fname;
+ _thread_run->lineno = lineno;
+
+ _SPINUNLOCK(lock);
+
+ /* Schedule the next thread that is ready: */
+ _thread_kern_sched(NULL);
+ return;
+}
+
+static void
+_thread_kern_poll(int wait_reqd)
+{
+ int count = 0;
+ int i, found;
+ int kern_pipe_added = 0;
+ int nfds = 0;
+ int timeout_ms = 0;
+ struct pthread *pthread;
+ struct timespec ts;
+ struct timeval tv;
+
+ /* Check if the caller wants to wait: */
+ if (wait_reqd == 0) {
+ timeout_ms = 0;
+ }
+ else {
+ /* Get the current time of day: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
+
+ _queue_signals = 1;
+ pthread = TAILQ_FIRST(&_waitingq);
+ _queue_signals = 0;
+
+ if ((pthread == NULL) || (pthread->wakeup_time.tv_sec == -1)) {
+ /*
+ * Either there are no threads in the waiting queue,
+ * or there are no threads that can timeout.
+ */
+ timeout_ms = INFTIM;
+ }
+ else {
+ /*
+ * Calculate the time left for the next thread to
+ * timeout allowing for the clock resolution:
+ */
+ timeout_ms = ((pthread->wakeup_time.tv_sec - ts.tv_sec) *
+ 1000) + ((pthread->wakeup_time.tv_nsec - ts.tv_nsec +
+ _clock_res_nsec) / 1000000);
+ /*
+ * Don't allow negative timeouts:
+ */
+ if (timeout_ms < 0)
+ timeout_ms = 0;
+ }
+ }
+
+ /* Protect the scheduling queues: */
+ _queue_signals = 1;
+
+ /*
+ * Check to see if the signal queue needs to be walked to look
+ * for threads awoken by a signal while in the scheduler.
+ */
+ if (_sigq_check_reqd != 0) {
+ /* Reset flag before handling queued signals: */
+ _sigq_check_reqd = 0;
+
+ dequeue_signals();
+ }
+
+ /*
+ * Check for a thread that became runnable due to a signal:
+ */
+ if (PTHREAD_PRIOQ_FIRST() != NULL) {
+ /*
+ * Since there is at least one runnable thread,
+ * disable the wait.
+ */
+ timeout_ms = 0;
+ }
+
+ /*
+ * Form the poll table:
+ */
+ nfds = 0;
+ if (timeout_ms != 0) {
+ /* Add the kernel pipe to the poll table: */
+ _thread_pfd_table[nfds].fd = _thread_kern_pipe[0];
+ _thread_pfd_table[nfds].events = POLLRDNORM;
+ _thread_pfd_table[nfds].revents = 0;
+ nfds++;
+ kern_pipe_added = 1;
+ }
+
+ PTHREAD_WAITQ_SETACTIVE();
+ TAILQ_FOREACH(pthread, &_workq, qe) {
+ switch (pthread->state) {
+ case PS_SPINBLOCK:
+ /*
+ * If the lock is available, let the thread run.
+ */
+ if (pthread->data.spinlock->access_lock == 0) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ /* One less thread in a spinblock state: */
+ _spinblock_count--;
+ /*
+ * Since there is at least one runnable
+ * thread, disable the wait.
+ */
+ timeout_ms = 0;
+ }
+ break;
+
+ /* File descriptor read wait: */
+ case PS_FDR_WAIT:
+ /* Limit number of polled files to table size: */
+ if (nfds < _thread_dtablesize) {
+ _thread_pfd_table[nfds].events = POLLRDNORM;
+ _thread_pfd_table[nfds].fd = pthread->data.fd.fd;
+ nfds++;
+ }
+ break;
+
+ /* File descriptor write wait: */
+ case PS_FDW_WAIT:
+ /* Limit number of polled files to table size: */
+ if (nfds < _thread_dtablesize) {
+ _thread_pfd_table[nfds].events = POLLWRNORM;
+ _thread_pfd_table[nfds].fd = pthread->data.fd.fd;
+ nfds++;
+ }
+ break;
+
+ /* File descriptor poll or select wait: */
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Limit number of polled files to table size: */
+ if (pthread->data.poll_data->nfds + nfds <
+ _thread_dtablesize) {
+ for (i = 0; i < pthread->data.poll_data->nfds; i++) {
+ _thread_pfd_table[nfds + i].fd =
+ pthread->data.poll_data->fds[i].fd;
+ _thread_pfd_table[nfds + i].events =
+ pthread->data.poll_data->fds[i].events;
+ }
+ nfds += pthread->data.poll_data->nfds;
+ }
+ break;
+
+ /* Other states do not depend on file I/O. */
+ default:
+ break;
+ }
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+
+ /*
+ * Wait for a file descriptor to be ready for read, write, or
+ * an exception, or a timeout to occur:
+ */
+ count = _thread_sys_poll(_thread_pfd_table, nfds, timeout_ms);
+
+ if (kern_pipe_added != 0)
+ /*
+ * Remove the pthread kernel pipe file descriptor
+ * from the pollfd table:
+ */
+ nfds = 1;
+ else
+ nfds = 0;
+
+ /*
+ * Check if it is possible that there are bytes in the kernel
+ * read pipe waiting to be read:
+ */
+ if (count < 0 || ((kern_pipe_added != 0) &&
+ (_thread_pfd_table[0].revents & POLLRDNORM))) {
+ /*
+ * If the kernel read pipe was included in the
+ * count:
+ */
+ if (count > 0) {
+ /* Decrement the count of file descriptors: */
+ count--;
+ }
+
+ if (_sigq_check_reqd != 0) {
+ /* Reset flag before handling signals: */
+ _sigq_check_reqd = 0;
+
+ dequeue_signals();
+ }
+ }
+
+ /*
+ * Check if any file descriptors are ready:
+ */
+ if (count > 0) {
+ /*
+ * Enter a loop to look for threads waiting on file
+ * descriptors that are flagged as available by the
+ * _poll syscall:
+ */
+ PTHREAD_WAITQ_SETACTIVE();
+ TAILQ_FOREACH(pthread, &_workq, qe) {
+ switch (pthread->state) {
+ case PS_SPINBLOCK:
+ /*
+ * If the lock is available, let the thread run.
+ */
+ if (pthread->data.spinlock->access_lock == 0) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+
+ /*
+ * One less thread in a spinblock state:
+ */
+ _spinblock_count--;
+ }
+ break;
+
+ /* File descriptor read wait: */
+ case PS_FDR_WAIT:
+ if ((nfds < _thread_dtablesize) &&
+ (_thread_pfd_table[nfds].revents & POLLRDNORM)) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ }
+ nfds++;
+ break;
+
+ /* File descriptor write wait: */
+ case PS_FDW_WAIT:
+ if ((nfds < _thread_dtablesize) &&
+ (_thread_pfd_table[nfds].revents & POLLWRNORM)) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ }
+ nfds++;
+ break;
+
+ /* File descriptor poll or select wait: */
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ if (pthread->data.poll_data->nfds + nfds <
+ _thread_dtablesize) {
+ /*
+ * Enter a loop looking for I/O
+ * readiness:
+ */
+ found = 0;
+ for (i = 0; i < pthread->data.poll_data->nfds; i++) {
+ if (_thread_pfd_table[nfds + i].revents != 0) {
+ pthread->data.poll_data->fds[i].revents =
+ _thread_pfd_table[nfds + i].revents;
+ found++;
+ }
+ }
+
+ /* Increment before destroying: */
+ nfds += pthread->data.poll_data->nfds;
+
+ if (found != 0) {
+ pthread->data.poll_data->nfds = found;
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ }
+ }
+ else
+ nfds += pthread->data.poll_data->nfds;
+ break;
+
+ /* Other states do not depend on file I/O. */
+ default:
+ break;
+ }
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+ }
+ else if (_spinblock_count != 0) {
+ /*
+ * Enter a loop to look for threads waiting on a spinlock
+ * that is now available.
+ */
+ PTHREAD_WAITQ_SETACTIVE();
+ TAILQ_FOREACH(pthread, &_workq, qe) {
+ if (pthread->state == PS_SPINBLOCK) {
+ /*
+ * If the lock is available, let the thread run.
+ */
+ if (pthread->data.spinlock->access_lock == 0) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+
+ /*
+ * One less thread in a spinblock state:
+ */
+ _spinblock_count--;
+ }
+ }
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+ }
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ while (_sigq_check_reqd != 0) {
+ /* Handle queued signals: */
+ _sigq_check_reqd = 0;
+
+ /* Protect the scheduling queues: */
+ _queue_signals = 1;
+
+ dequeue_signals();
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+ }
+
+ /* Nothing to return. */
+ return;
+}
+
+void
+_thread_kern_set_timeout(struct timespec * timeout)
+{
+ struct timespec current_time;
+ struct timeval tv;
+
+ /* Reset the timeout flag for the running thread: */
+ _thread_run->timeout = 0;
+
+ /* Check if the thread is to wait forever: */
+ if (timeout == NULL) {
+ /*
+ * Set the wakeup time to something that can be recognised as
+ * different to an actual time of day:
+ */
+ _thread_run->wakeup_time.tv_sec = -1;
+ _thread_run->wakeup_time.tv_nsec = -1;
+ }
+ /* Check if no waiting is required: */
+ else if (timeout->tv_sec == 0 && timeout->tv_nsec == 0) {
+ /* Set the wake up time to 'immediately': */
+ _thread_run->wakeup_time.tv_sec = 0;
+ _thread_run->wakeup_time.tv_nsec = 0;
+ } else {
+ /* Get the current time: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &current_time);
+
+ /* Calculate the time for the current thread to wake up: */
+ _thread_run->wakeup_time.tv_sec = current_time.tv_sec + timeout->tv_sec;
+ _thread_run->wakeup_time.tv_nsec = current_time.tv_nsec + timeout->tv_nsec;
+
+ /* Check if the nanosecond field needs to wrap: */
+ if (_thread_run->wakeup_time.tv_nsec >= 1000000000) {
+ /* Wrap the nanosecond field: */
+ _thread_run->wakeup_time.tv_sec += 1;
+ _thread_run->wakeup_time.tv_nsec -= 1000000000;
+ }
+ }
+ return;
+}
+
+void
+_thread_kern_sig_defer(void)
+{
+ /* Allow signal deferral to be recursive. */
+ _thread_run->sig_defer_count++;
+}
+
+void
+_thread_kern_sig_undefer(void)
+{
+ pthread_t pthread;
+ int need_resched = 0;
+
+ /*
+ * Perform checks to yield only if we are about to undefer
+ * signals.
+ */
+ if (_thread_run->sig_defer_count > 1) {
+ /* Decrement the signal deferral count. */
+ _thread_run->sig_defer_count--;
+ }
+ else if (_thread_run->sig_defer_count == 1) {
+ /* Reenable signals: */
+ _thread_run->sig_defer_count = 0;
+
+ /*
+ * Check if there are queued signals:
+ */
+ while (_sigq_check_reqd != 0) {
+ /* Defer scheduling while we process queued signals: */
+ _thread_run->sig_defer_count = 1;
+
+ /* Clear the flag before checking the signal queue: */
+ _sigq_check_reqd = 0;
+
+ /* Dequeue and handle signals: */
+ dequeue_signals();
+
+ /*
+ * Avoiding an unnecessary check to reschedule, check
+ * to see if signal handling caused a higher priority
+ * thread to become ready.
+ */
+ if ((need_resched == 0) &&
+ (((pthread = PTHREAD_PRIOQ_FIRST()) != NULL) &&
+ (pthread->active_priority > _thread_run->active_priority))) {
+ need_resched = 1;
+ }
+
+ /* Reenable signals: */
+ _thread_run->sig_defer_count = 0;
+ }
+
+ /* Yield the CPU if necessary: */
+ if (need_resched || _thread_run->yield_on_sig_undefer != 0) {
+ _thread_run->yield_on_sig_undefer = 0;
+ _thread_kern_sched(NULL);
+ }
+ }
+}
+
+static void
+dequeue_signals(void)
+{
+ char bufr[128];
+ int i, num;
+ pthread_t pthread;
+
+ /*
+ * Enter a loop to read and handle queued signals from the
+ * pthread kernel pipe:
+ */
+ while (((num = _thread_sys_read(_thread_kern_pipe[0], bufr,
+ sizeof(bufr))) > 0) || (num == -1 && errno == EINTR)) {
+ /*
+ * The buffer read contains one byte per signal and
+ * each byte is the signal number.
+ */
+ for (i = 0; i < num; i++) {
+ if ((int) bufr[i] == _SCHED_SIGNAL) {
+ /*
+ * Scheduling signals shouldn't ever be
+ * queued; just ignore it for now.
+ */
+ }
+ else {
+ /* Handle this signal: */
+ pthread = _thread_sig_handle((int) bufr[i],
+ NULL);
+ if (pthread != NULL)
+ _thread_sig_deliver(pthread,
+ (int) bufr[i]);
+ }
+ }
+ }
+ if ((num < 0) && (errno != EAGAIN)) {
+ /*
+ * The only error we should expect is if there is
+ * no data to read.
+ */
+ PANIC("Unable to read from thread kernel pipe");
+ }
+}
+
+static inline void
+thread_run_switch_hook(pthread_t thread_out, pthread_t thread_in)
+{
+ pthread_t tid_out = thread_out;
+ pthread_t tid_in = thread_in;
+
+ if ((tid_out != NULL) &&
+ (tid_out->flags & PTHREAD_FLAGS_PRIVATE) != 0)
+ tid_out = NULL;
+ if ((tid_in != NULL) &&
+ (tid_in->flags & PTHREAD_FLAGS_PRIVATE) != 0)
+ tid_in = NULL;
+
+ if ((_sched_switch_hook != NULL) && (tid_out != tid_in)) {
+ /* Run the scheduler switch hook: */
+ _sched_switch_hook(tid_out, tid_in);
+ }
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_kill.c b/lib/libc_r/uthread/uthread_kill.c
new file mode 100644
index 0000000..4bf1761
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_kill.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <signal.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_kill(pthread_t pthread, int sig)
+{
+ int ret;
+
+ /* Check for invalid signal numbers: */
+ if (sig < 0 || sig >= NSIG)
+ /* Invalid signal: */
+ ret = EINVAL;
+ /*
+ * Ensure the thread is in the list of active threads, and the
+ * signal is valid (signal 0 specifies error checking only) and
+ * not being ignored:
+ */
+ else if (((ret = _find_thread(pthread)) == 0) && (sig > 0) &&
+ (_thread_sigact[sig - 1].sa_handler != SIG_IGN)) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ _thread_sig_send(pthread, sig);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_listen.c b/lib/libc_r/uthread/uthread_listen.c
new file mode 100644
index 0000000..dc90107
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_listen.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+listen(int fd, int backlog)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ ret = _thread_sys_listen(fd, backlog);
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_mattr_init.c b/lib/libc_r/uthread/uthread_mattr_init.c
new file mode 100644
index 0000000..63d4401
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_mattr_init.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996 Jeffrey Hsu <hsu@freebsd.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_mutexattr_init(pthread_mutexattr_t *attr)
+{
+ int ret;
+ pthread_mutexattr_t pattr;
+
+ if ((pattr = (pthread_mutexattr_t)
+ malloc(sizeof(struct pthread_mutex_attr))) == NULL) {
+ ret = ENOMEM;
+ } else {
+ memcpy(pattr, &pthread_mutexattr_default,
+ sizeof(struct pthread_mutex_attr));
+ *attr = pattr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_mattr_kind_np.c b/lib/libc_r/uthread/uthread_mattr_kind_np.c
new file mode 100644
index 0000000..8b3b8cb
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_mattr_kind_np.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1996 Jeffrey Hsu <hsu@freebsd.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->m_type = kind;
+ ret = 0;
+ }
+ return(ret);
+}
+
+int
+pthread_mutexattr_getkind_np(pthread_mutexattr_t attr)
+{
+ int ret;
+ if (attr == NULL) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ ret = attr->m_type;
+ }
+ return(ret);
+}
+
+int
+pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL || type >= MUTEX_TYPE_MAX) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->m_type = type;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_msync.c b/lib/libc_r/uthread/uthread_msync.c
new file mode 100644
index 0000000..209286d
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_msync.c
@@ -0,0 +1,40 @@
+/*
+ * David Leonard <d@openbsd.org>, 1999. Public Domain.
+ *
+ * $OpenBSD: uthread_msync.c,v 1.2 1999/06/09 07:16:17 d Exp $
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+msync(addr, len, flags)
+ void *addr;
+ size_t len;
+ int flags;
+{
+ int ret;
+
+ /*
+ * XXX This is quite pointless unless we know how to get the
+ * file descriptor associated with the memory, and lock it for
+ * write. The only real use of this wrapper is to guarantee
+ * a cancellation point, as per the standard. sigh.
+ */
+
+ /* This is a cancellation point: */
+ _thread_enter_cancellation_point();
+
+ ret = _thread_sys_msync(addr, len, flags);
+
+ /* No longer in a cancellation point: */
+ _thread_leave_cancellation_point();
+
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_multi_np.c b/lib/libc_r/uthread/uthread_multi_np.c
new file mode 100644
index 0000000..39dd948
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_multi_np.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_multi_np()
+{
+ /* Return to multi-threaded scheduling mode: */
+ _thread_single = NULL;
+ return(0);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_mutex.c b/lib/libc_r/uthread/uthread_mutex.c
new file mode 100644
index 0000000..c625ef2
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_mutex.c
@@ -0,0 +1,1406 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+#if defined(_PTHREADS_INVARIANTS)
+#define _MUTEX_INIT_LINK(m) do { \
+ (m)->m_qe.tqe_prev = NULL; \
+ (m)->m_qe.tqe_next = NULL; \
+} while (0)
+#define _MUTEX_ASSERT_IS_OWNED(m) do { \
+ if ((m)->m_qe.tqe_prev == NULL) \
+ PANIC("mutex is not on list"); \
+} while (0)
+#define _MUTEX_ASSERT_NOT_OWNED(m) do { \
+ if (((m)->m_qe.tqe_prev != NULL) || \
+ ((m)->m_qe.tqe_next != NULL)) \
+ PANIC("mutex is on list"); \
+} while (0)
+#else
+#define _MUTEX_INIT_LINK(m)
+#define _MUTEX_ASSERT_IS_OWNED(m)
+#define _MUTEX_ASSERT_NOT_OWNED(m)
+#endif
+
+/*
+ * Prototypes
+ */
+static inline int mutex_self_trylock(pthread_mutex_t);
+static inline int mutex_self_lock(pthread_mutex_t);
+static inline int mutex_unlock_common(pthread_mutex_t *, int);
+static void mutex_priority_adjust(pthread_mutex_t);
+static void mutex_rescan_owned (pthread_t, pthread_mutex_t);
+static inline pthread_t mutex_queue_deq(pthread_mutex_t);
+static inline void mutex_queue_remove(pthread_mutex_t, pthread_t);
+static inline void mutex_queue_enq(pthread_mutex_t, pthread_t);
+
+
+static spinlock_t static_init_lock = _SPINLOCK_INITIALIZER;
+
+/* Reinitialize a mutex to defaults. */
+int
+_mutex_reinit(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+ else if (*mutex == NULL)
+ ret = pthread_mutex_init(mutex, NULL);
+ else {
+ /*
+ * Initialize the mutex structure:
+ */
+ (*mutex)->m_type = PTHREAD_MUTEX_DEFAULT;
+ (*mutex)->m_protocol = PTHREAD_PRIO_NONE;
+ TAILQ_INIT(&(*mutex)->m_queue);
+ (*mutex)->m_owner = NULL;
+ (*mutex)->m_data.m_count = 0;
+ (*mutex)->m_flags &= MUTEX_FLAGS_PRIVATE;
+ (*mutex)->m_flags |= MUTEX_FLAGS_INITED;
+ (*mutex)->m_refcount = 0;
+ (*mutex)->m_prio = 0;
+ (*mutex)->m_saved_prio = 0;
+ _MUTEX_INIT_LINK(*mutex);
+ memset(&(*mutex)->lock, 0, sizeof((*mutex)->lock));
+ }
+ return (ret);
+}
+
+int
+pthread_mutex_init(pthread_mutex_t * mutex,
+ const pthread_mutexattr_t * mutex_attr)
+{
+ enum pthread_mutextype type;
+ int protocol;
+ int ceiling;
+ pthread_mutex_t pmutex;
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+
+ /* Check if default mutex attributes: */
+ else if (mutex_attr == NULL || *mutex_attr == NULL) {
+ /* Default to a (error checking) POSIX mutex: */
+ type = PTHREAD_MUTEX_ERRORCHECK;
+ protocol = PTHREAD_PRIO_NONE;
+ ceiling = PTHREAD_MAX_PRIORITY;
+ }
+
+ /* Check mutex type: */
+ else if (((*mutex_attr)->m_type < PTHREAD_MUTEX_ERRORCHECK) ||
+ ((*mutex_attr)->m_type >= MUTEX_TYPE_MAX))
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+
+ /* Check mutex protocol: */
+ else if (((*mutex_attr)->m_protocol < PTHREAD_PRIO_NONE) ||
+ ((*mutex_attr)->m_protocol > PTHREAD_MUTEX_RECURSIVE))
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+
+ else {
+ /* Use the requested mutex type and protocol: */
+ type = (*mutex_attr)->m_type;
+ protocol = (*mutex_attr)->m_protocol;
+ ceiling = (*mutex_attr)->m_ceiling;
+ }
+
+ /* Check no errors so far: */
+ if (ret == 0) {
+ if ((pmutex = (pthread_mutex_t)
+ malloc(sizeof(struct pthread_mutex))) == NULL)
+ ret = ENOMEM;
+ else {
+ /* Reset the mutex flags: */
+ pmutex->m_flags = 0;
+
+ /* Process according to mutex type: */
+ switch (type) {
+ /* case PTHREAD_MUTEX_DEFAULT: */
+ case PTHREAD_MUTEX_ERRORCHECK:
+ case PTHREAD_MUTEX_NORMAL:
+ /* Nothing to do here. */
+ break;
+
+ /* Single UNIX Spec 2 recursive mutex: */
+ case PTHREAD_MUTEX_RECURSIVE:
+ /* Reset the mutex count: */
+ pmutex->m_data.m_count = 0;
+ break;
+
+ /* Trap invalid mutex types: */
+ default:
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ break;
+ }
+ if (ret == 0) {
+ /* Initialise the rest of the mutex: */
+ TAILQ_INIT(&pmutex->m_queue);
+ pmutex->m_flags |= MUTEX_FLAGS_INITED;
+ pmutex->m_owner = NULL;
+ pmutex->m_type = type;
+ pmutex->m_protocol = protocol;
+ pmutex->m_refcount = 0;
+ if (protocol == PTHREAD_PRIO_PROTECT)
+ pmutex->m_prio = ceiling;
+ else
+ pmutex->m_prio = 0;
+ pmutex->m_saved_prio = 0;
+ _MUTEX_INIT_LINK(pmutex);
+ memset(&pmutex->lock, 0, sizeof(pmutex->lock));
+ *mutex = pmutex;
+ } else {
+ free(pmutex);
+ *mutex = NULL;
+ }
+ }
+ }
+ /* Return the completion status: */
+ return(ret);
+}
+
+int
+pthread_mutex_destroy(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL || *mutex == NULL)
+ ret = EINVAL;
+ else {
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
+ * Check to see if this mutex is in use:
+ */
+ if (((*mutex)->m_owner != NULL) ||
+ (TAILQ_FIRST(&(*mutex)->m_queue) != NULL) ||
+ ((*mutex)->m_refcount != 0)) {
+ ret = EBUSY;
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&(*mutex)->lock);
+ }
+ else {
+ /*
+ * Free the memory allocated for the mutex
+ * structure:
+ */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ free(*mutex);
+
+ /*
+ * Leave the caller's pointer NULL now that
+ * the mutex has been destroyed:
+ */
+ *mutex = NULL;
+ }
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+static int
+init_static (pthread_mutex_t *mutex)
+{
+ int ret;
+
+ _SPINLOCK(&static_init_lock);
+
+ if (*mutex == NULL)
+ ret = pthread_mutex_init(mutex, NULL);
+ else
+ ret = 0;
+
+ _SPINUNLOCK(&static_init_lock);
+
+ return(ret);
+}
+
+int
+pthread_mutex_trylock(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+
+ /*
+ * If the mutex is statically initialized, perform the dynamic
+ * initialization:
+ */
+ else if (*mutex != NULL || (ret = init_static(mutex)) == 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
+ * If the mutex was statically allocated, properly
+ * initialize the tail queue.
+ */
+ if (((*mutex)->m_flags & MUTEX_FLAGS_INITED) == 0) {
+ TAILQ_INIT(&(*mutex)->m_queue);
+ _MUTEX_INIT_LINK(*mutex);
+ (*mutex)->m_flags |= MUTEX_FLAGS_INITED;
+ }
+
+ /* Process according to mutex type: */
+ switch ((*mutex)->m_protocol) {
+ /* Default POSIX mutex: */
+ case PTHREAD_PRIO_NONE:
+ /* Check if this mutex is not locked: */
+ if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for the running thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_trylock(*mutex);
+ else
+ /* Return a busy error: */
+ ret = EBUSY;
+ break;
+
+ /* POSIX priority inheritence mutex: */
+ case PTHREAD_PRIO_INHERIT:
+ /* Check if this mutex is not locked: */
+ if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for the running thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Track number of priority mutexes owned: */
+ _thread_run->priority_mutex_count++;
+
+ /*
+ * The mutex takes on the attributes of the
+ * running thread when there are no waiters.
+ */
+ (*mutex)->m_prio = _thread_run->active_priority;
+ (*mutex)->m_saved_prio =
+ _thread_run->inherited_priority;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_trylock(*mutex);
+ else
+ /* Return a busy error: */
+ ret = EBUSY;
+ break;
+
+ /* POSIX priority protection mutex: */
+ case PTHREAD_PRIO_PROTECT:
+ /* Check for a priority ceiling violation: */
+ if (_thread_run->active_priority > (*mutex)->m_prio)
+ ret = EINVAL;
+
+ /* Check if this mutex is not locked: */
+ else if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for the running thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Track number of priority mutexes owned: */
+ _thread_run->priority_mutex_count++;
+
+ /*
+ * The running thread inherits the ceiling
+ * priority of the mutex and executes at that
+ * priority.
+ */
+ _thread_run->active_priority = (*mutex)->m_prio;
+ (*mutex)->m_saved_prio =
+ _thread_run->inherited_priority;
+ _thread_run->inherited_priority =
+ (*mutex)->m_prio;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_trylock(*mutex);
+ else
+ /* Return a busy error: */
+ ret = EBUSY;
+ break;
+
+ /* Trap invalid mutex types: */
+ default:
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ break;
+ }
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&(*mutex)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+int
+pthread_mutex_lock(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+
+ /*
+ * If the mutex is statically initialized, perform the dynamic
+ * initialization:
+ */
+ else if (*mutex != NULL || (ret = init_static(mutex)) == 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
+ * If the mutex was statically allocated, properly
+ * initialize the tail queue.
+ */
+ if (((*mutex)->m_flags & MUTEX_FLAGS_INITED) == 0) {
+ TAILQ_INIT(&(*mutex)->m_queue);
+ (*mutex)->m_flags |= MUTEX_FLAGS_INITED;
+ _MUTEX_INIT_LINK(*mutex);
+ }
+
+ /* Reset the interrupted flag: */
+ _thread_run->interrupted = 0;
+
+ /* Process according to mutex type: */
+ switch ((*mutex)->m_protocol) {
+ /* Default POSIX mutex: */
+ case PTHREAD_PRIO_NONE:
+ if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for this thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_lock(*mutex);
+ else {
+ /*
+ * Join the queue of threads waiting to lock
+ * the mutex:
+ */
+ mutex_queue_enq(*mutex, _thread_run);
+
+ /*
+ * Keep a pointer to the mutex this thread
+ * is waiting on:
+ */
+ _thread_run->data.mutex = *mutex;
+
+ /*
+ * Unlock the mutex structure and schedule the
+ * next thread:
+ */
+ _thread_kern_sched_state_unlock(PS_MUTEX_WAIT,
+ &(*mutex)->lock, __FILE__, __LINE__);
+
+ /* Lock the mutex structure again: */
+ _SPINLOCK(&(*mutex)->lock);
+ }
+ break;
+
+ /* POSIX priority inheritence mutex: */
+ case PTHREAD_PRIO_INHERIT:
+ /* Check if this mutex is not locked: */
+ if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for this thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Track number of priority mutexes owned: */
+ _thread_run->priority_mutex_count++;
+
+ /*
+ * The mutex takes on attributes of the
+ * running thread when there are no waiters.
+ */
+ (*mutex)->m_prio = _thread_run->active_priority;
+ (*mutex)->m_saved_prio =
+ _thread_run->inherited_priority;
+ _thread_run->inherited_priority =
+ (*mutex)->m_prio;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_lock(*mutex);
+ else {
+ /*
+ * Join the queue of threads waiting to lock
+ * the mutex:
+ */
+ mutex_queue_enq(*mutex, _thread_run);
+
+ /*
+ * Keep a pointer to the mutex this thread
+ * is waiting on:
+ */
+ _thread_run->data.mutex = *mutex;
+
+ if (_thread_run->active_priority >
+ (*mutex)->m_prio)
+ /* Adjust priorities: */
+ mutex_priority_adjust(*mutex);
+
+ /*
+ * Unlock the mutex structure and schedule the
+ * next thread:
+ */
+ _thread_kern_sched_state_unlock(PS_MUTEX_WAIT,
+ &(*mutex)->lock, __FILE__, __LINE__);
+
+ /* Lock the mutex structure again: */
+ _SPINLOCK(&(*mutex)->lock);
+ }
+ break;
+
+ /* POSIX priority protection mutex: */
+ case PTHREAD_PRIO_PROTECT:
+ /* Check for a priority ceiling violation: */
+ if (_thread_run->active_priority > (*mutex)->m_prio)
+ ret = EINVAL;
+
+ /* Check if this mutex is not locked: */
+ else if ((*mutex)->m_owner == NULL) {
+ /*
+ * Lock the mutex for the running
+ * thread:
+ */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Track number of priority mutexes owned: */
+ _thread_run->priority_mutex_count++;
+
+ /*
+ * The running thread inherits the ceiling
+ * priority of the mutex and executes at that
+ * priority:
+ */
+ _thread_run->active_priority = (*mutex)->m_prio;
+ (*mutex)->m_saved_prio =
+ _thread_run->inherited_priority;
+ _thread_run->inherited_priority =
+ (*mutex)->m_prio;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_lock(*mutex);
+ else {
+ /*
+ * Join the queue of threads waiting to lock
+ * the mutex:
+ */
+ mutex_queue_enq(*mutex, _thread_run);
+
+ /*
+ * Keep a pointer to the mutex this thread
+ * is waiting on:
+ */
+ _thread_run->data.mutex = *mutex;
+
+ /* Clear any previous error: */
+ _thread_run->error = 0;
+
+ /*
+ * Unlock the mutex structure and schedule the
+ * next thread:
+ */
+ _thread_kern_sched_state_unlock(PS_MUTEX_WAIT,
+ &(*mutex)->lock, __FILE__, __LINE__);
+
+ /* Lock the mutex structure again: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
+ * The threads priority may have changed while
+ * waiting for the mutex causing a ceiling
+ * violation.
+ */
+ ret = _thread_run->error;
+ _thread_run->error = 0;
+ }
+ break;
+
+ /* Trap invalid mutex types: */
+ default:
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ break;
+ }
+
+ /*
+ * Check to see if this thread was interrupted and
+ * is still in the mutex queue of waiting threads:
+ */
+ if (_thread_run->interrupted != 0)
+ mutex_queue_remove(*mutex, _thread_run);
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&(*mutex)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+int
+pthread_mutex_unlock(pthread_mutex_t * mutex)
+{
+ return (mutex_unlock_common(mutex, /* add reference */ 0));
+}
+
+int
+_mutex_cv_unlock(pthread_mutex_t * mutex)
+{
+ return (mutex_unlock_common(mutex, /* add reference */ 1));
+}
+
+int
+_mutex_cv_lock(pthread_mutex_t * mutex)
+{
+ int ret;
+ if ((ret = pthread_mutex_lock(mutex)) == 0)
+ (*mutex)->m_refcount--;
+ return (ret);
+}
+
+static inline int
+mutex_self_trylock(pthread_mutex_t mutex)
+{
+ int ret = 0;
+
+ switch (mutex->m_type) {
+
+ /* case PTHREAD_MUTEX_DEFAULT: */
+ case PTHREAD_MUTEX_ERRORCHECK:
+ case PTHREAD_MUTEX_NORMAL:
+ /*
+ * POSIX specifies that mutexes should return EDEADLK if a
+ * recursive lock is detected.
+ */
+ ret = EBUSY;
+ break;
+
+ case PTHREAD_MUTEX_RECURSIVE:
+ /* Increment the lock count: */
+ mutex->m_data.m_count++;
+ break;
+
+ default:
+ /* Trap invalid mutex types; */
+ ret = EINVAL;
+ }
+
+ return(ret);
+}
+
+static inline int
+mutex_self_lock(pthread_mutex_t mutex)
+{
+ int ret = 0;
+
+ switch (mutex->m_type) {
+ /* case PTHREAD_MUTEX_DEFAULT: */
+ case PTHREAD_MUTEX_ERRORCHECK:
+ /*
+ * POSIX specifies that mutexes should return EDEADLK if a
+ * recursive lock is detected.
+ */
+ ret = EDEADLK;
+ break;
+
+ case PTHREAD_MUTEX_NORMAL:
+ /*
+ * What SS2 define as a 'normal' mutex. Intentionally
+ * deadlock on attempts to get a lock you already own.
+ */
+ _thread_kern_sched_state_unlock(PS_DEADLOCK,
+ &mutex->lock, __FILE__, __LINE__);
+ break;
+
+ case PTHREAD_MUTEX_RECURSIVE:
+ /* Increment the lock count: */
+ mutex->m_data.m_count++;
+ break;
+
+ default:
+ /* Trap invalid mutex types; */
+ ret = EINVAL;
+ }
+
+ return(ret);
+}
+
+static inline int
+mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
+{
+ int ret = 0;
+
+ if (mutex == NULL || *mutex == NULL) {
+ ret = EINVAL;
+ } else {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /* Process according to mutex type: */
+ switch ((*mutex)->m_protocol) {
+ /* Default POSIX mutex: */
+ case PTHREAD_PRIO_NONE:
+ /*
+ * Check if the running thread is not the owner of the
+ * mutex:
+ */
+ if ((*mutex)->m_owner != _thread_run) {
+ /*
+ * Return an invalid argument error for no
+ * owner and a permission error otherwise:
+ */
+ ret = (*mutex)->m_owner == NULL ? EINVAL : EPERM;
+ }
+ else if (((*mutex)->m_type == PTHREAD_MUTEX_RECURSIVE) &&
+ ((*mutex)->m_data.m_count > 1)) {
+ /* Decrement the count: */
+ (*mutex)->m_data.m_count--;
+ } else {
+ /*
+ * Clear the count in case this is recursive
+ * mutex.
+ */
+ (*mutex)->m_data.m_count = 0;
+
+ /* Remove the mutex from the threads queue. */
+ _MUTEX_ASSERT_IS_OWNED(*mutex);
+ TAILQ_REMOVE(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+ _MUTEX_INIT_LINK(*mutex);
+
+ /*
+ * Get the next thread from the queue of
+ * threads waiting on the mutex:
+ */
+ if (((*mutex)->m_owner =
+ mutex_queue_deq(*mutex)) != NULL) {
+ /*
+ * Allow the new owner of the mutex to
+ * run:
+ */
+ PTHREAD_NEW_STATE((*mutex)->m_owner,
+ PS_RUNNING);
+
+ /*
+ * Add the mutex to the threads list of
+ * owned mutexes:
+ */
+ TAILQ_INSERT_TAIL(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+
+ /*
+ * The owner is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
+ }
+ }
+ break;
+
+ /* POSIX priority inheritence mutex: */
+ case PTHREAD_PRIO_INHERIT:
+ /*
+ * Check if the running thread is not the owner of the
+ * mutex:
+ */
+ if ((*mutex)->m_owner != _thread_run) {
+ /*
+ * Return an invalid argument error for no
+ * owner and a permission error otherwise:
+ */
+ ret = (*mutex)->m_owner == NULL ? EINVAL : EPERM;
+ }
+ else if (((*mutex)->m_type == PTHREAD_MUTEX_RECURSIVE) &&
+ ((*mutex)->m_data.m_count > 1)) {
+ /* Decrement the count: */
+ (*mutex)->m_data.m_count--;
+ } else {
+ /*
+ * Clear the count in case this is recursive
+ * mutex.
+ */
+ (*mutex)->m_data.m_count = 0;
+
+ /*
+ * Restore the threads inherited priority and
+ * recompute the active priority (being careful
+ * not to override changes in the threads base
+ * priority subsequent to locking the mutex).
+ */
+ _thread_run->inherited_priority =
+ (*mutex)->m_saved_prio;
+ _thread_run->active_priority =
+ MAX(_thread_run->inherited_priority,
+ _thread_run->base_priority);
+
+ /*
+ * This thread now owns one less priority mutex.
+ */
+ _thread_run->priority_mutex_count--;
+
+ /* Remove the mutex from the threads queue. */
+ _MUTEX_ASSERT_IS_OWNED(*mutex);
+ TAILQ_REMOVE(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+ _MUTEX_INIT_LINK(*mutex);
+
+ /*
+ * Get the next thread from the queue of threads
+ * waiting on the mutex:
+ */
+ if (((*mutex)->m_owner =
+ mutex_queue_deq(*mutex)) == NULL)
+ /* This mutex has no priority. */
+ (*mutex)->m_prio = 0;
+ else {
+ /*
+ * Track number of priority mutexes owned:
+ */
+ (*mutex)->m_owner->priority_mutex_count++;
+
+ /*
+ * Add the mutex to the threads list
+ * of owned mutexes:
+ */
+ TAILQ_INSERT_TAIL(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+
+ /*
+ * The owner is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
+
+ /*
+ * Set the priority of the mutex. Since
+ * our waiting threads are in descending
+ * priority order, the priority of the
+ * mutex becomes the active priority of
+ * the thread we just dequeued.
+ */
+ (*mutex)->m_prio =
+ (*mutex)->m_owner->active_priority;
+
+ /*
+ * Save the owning threads inherited
+ * priority:
+ */
+ (*mutex)->m_saved_prio =
+ (*mutex)->m_owner->inherited_priority;
+
+ /*
+ * The owning threads inherited priority
+ * now becomes his active priority (the
+ * priority of the mutex).
+ */
+ (*mutex)->m_owner->inherited_priority =
+ (*mutex)->m_prio;
+
+ /*
+ * Allow the new owner of the mutex to
+ * run:
+ */
+ PTHREAD_NEW_STATE((*mutex)->m_owner,
+ PS_RUNNING);
+ }
+ }
+ break;
+
+ /* POSIX priority ceiling mutex: */
+ case PTHREAD_PRIO_PROTECT:
+ /*
+ * Check if the running thread is not the owner of the
+ * mutex:
+ */
+ if ((*mutex)->m_owner != _thread_run) {
+ /*
+ * Return an invalid argument error for no
+ * owner and a permission error otherwise:
+ */
+ ret = (*mutex)->m_owner == NULL ? EINVAL : EPERM;
+ }
+ else if (((*mutex)->m_type == PTHREAD_MUTEX_RECURSIVE) &&
+ ((*mutex)->m_data.m_count > 1)) {
+ /* Decrement the count: */
+ (*mutex)->m_data.m_count--;
+ } else {
+ /*
+ * Clear the count in case this is recursive
+ * mutex.
+ */
+ (*mutex)->m_data.m_count = 0;
+
+ /*
+ * Restore the threads inherited priority and
+ * recompute the active priority (being careful
+ * not to override changes in the threads base
+ * priority subsequent to locking the mutex).
+ */
+ _thread_run->inherited_priority =
+ (*mutex)->m_saved_prio;
+ _thread_run->active_priority =
+ MAX(_thread_run->inherited_priority,
+ _thread_run->base_priority);
+
+ /*
+ * This thread now owns one less priority mutex.
+ */
+ _thread_run->priority_mutex_count--;
+
+ /* Remove the mutex from the threads queue. */
+ _MUTEX_ASSERT_IS_OWNED(*mutex);
+ TAILQ_REMOVE(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+ _MUTEX_INIT_LINK(*mutex);
+
+ /*
+ * Enter a loop to find a waiting thread whose
+ * active priority will not cause a ceiling
+ * violation:
+ */
+ while ((((*mutex)->m_owner =
+ mutex_queue_deq(*mutex)) != NULL) &&
+ ((*mutex)->m_owner->active_priority >
+ (*mutex)->m_prio)) {
+ /*
+ * Either the mutex ceiling priority
+ * been lowered and/or this threads
+ * priority has been raised subsequent
+ * to this thread being queued on the
+ * waiting list.
+ */
+ (*mutex)->m_owner->error = EINVAL;
+ PTHREAD_NEW_STATE((*mutex)->m_owner,
+ PS_RUNNING);
+ /*
+ * The thread is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
+ }
+
+ /* Check for a new owner: */
+ if ((*mutex)->m_owner != NULL) {
+ /*
+ * Track number of priority mutexes owned:
+ */
+ (*mutex)->m_owner->priority_mutex_count++;
+
+ /*
+ * Add the mutex to the threads list
+ * of owned mutexes:
+ */
+ TAILQ_INSERT_TAIL(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+
+ /*
+ * The owner is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
+
+ /*
+ * Save the owning threads inherited
+ * priority:
+ */
+ (*mutex)->m_saved_prio =
+ (*mutex)->m_owner->inherited_priority;
+
+ /*
+ * The owning thread inherits the
+ * ceiling priority of the mutex and
+ * executes at that priority:
+ */
+ (*mutex)->m_owner->inherited_priority =
+ (*mutex)->m_prio;
+ (*mutex)->m_owner->active_priority =
+ (*mutex)->m_prio;
+
+ /*
+ * Allow the new owner of the mutex to
+ * run:
+ */
+ PTHREAD_NEW_STATE((*mutex)->m_owner,
+ PS_RUNNING);
+ }
+ }
+ break;
+
+ /* Trap invalid mutex types: */
+ default:
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ break;
+ }
+
+ if ((ret == 0) && (add_reference != 0)) {
+ /* Increment the reference count: */
+ (*mutex)->m_refcount++;
+ }
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&(*mutex)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+
+/*
+ * This function is called when a change in base priority occurs for
+ * a thread that is holding or waiting for a priority protection or
+ * inheritence mutex. A change in a threads base priority can effect
+ * changes to active priorities of other threads and to the ordering
+ * of mutex locking by waiting threads.
+ *
+ * This must be called while thread scheduling is deferred.
+ */
+void
+_mutex_notify_priochange(pthread_t pthread)
+{
+ /* Adjust the priorites of any owned priority mutexes: */
+ if (pthread->priority_mutex_count > 0) {
+ /*
+ * Rescan the mutexes owned by this thread and correct
+ * their priorities to account for this threads change
+ * in priority. This has the side effect of changing
+ * the threads active priority.
+ */
+ mutex_rescan_owned(pthread, /* rescan all owned */ NULL);
+ }
+
+ /*
+ * If this thread is waiting on a priority inheritence mutex,
+ * check for priority adjustments. A change in priority can
+ * also effect a ceiling violation(*) for a thread waiting on
+ * a priority protection mutex; we don't perform the check here
+ * as it is done in pthread_mutex_unlock.
+ *
+ * (*) It should be noted that a priority change to a thread
+ * _after_ taking and owning a priority ceiling mutex
+ * does not affect ownership of that mutex; the ceiling
+ * priority is only checked before mutex ownership occurs.
+ */
+ if (pthread->state == PS_MUTEX_WAIT) {
+ /* Lock the mutex structure: */
+ _SPINLOCK(&pthread->data.mutex->lock);
+
+ /*
+ * Check to make sure this thread is still in the same state
+ * (the spinlock above can yield the CPU to another thread):
+ */
+ if (pthread->state == PS_MUTEX_WAIT) {
+ /*
+ * Remove and reinsert this thread into the list of
+ * waiting threads to preserve decreasing priority
+ * order.
+ */
+ mutex_queue_remove(pthread->data.mutex, pthread);
+ mutex_queue_enq(pthread->data.mutex, pthread);
+
+ if (pthread->data.mutex->m_protocol ==
+ PTHREAD_PRIO_INHERIT) {
+ /* Adjust priorities: */
+ mutex_priority_adjust(pthread->data.mutex);
+ }
+ }
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&pthread->data.mutex->lock);
+ }
+}
+
+/*
+ * Called when a new thread is added to the mutex waiting queue or
+ * when a threads priority changes that is already in the mutex
+ * waiting queue.
+ */
+static void
+mutex_priority_adjust(pthread_mutex_t mutex)
+{
+ pthread_t pthread_next, pthread = mutex->m_owner;
+ int temp_prio;
+ pthread_mutex_t m = mutex;
+
+ /*
+ * Calculate the mutex priority as the maximum of the highest
+ * active priority of any waiting threads and the owning threads
+ * active priority(*).
+ *
+ * (*) Because the owning threads current active priority may
+ * reflect priority inherited from this mutex (and the mutex
+ * priority may have changed) we must recalculate the active
+ * priority based on the threads saved inherited priority
+ * and its base priority.
+ */
+ pthread_next = TAILQ_FIRST(&m->m_queue); /* should never be NULL */
+ temp_prio = MAX(pthread_next->active_priority,
+ MAX(m->m_saved_prio, pthread->base_priority));
+
+ /* See if this mutex really needs adjusting: */
+ if (temp_prio == m->m_prio)
+ /* No need to propagate the priority: */
+ return;
+
+ /* Set new priority of the mutex: */
+ m->m_prio = temp_prio;
+
+ while (m != NULL) {
+ /*
+ * Save the threads priority before rescanning the
+ * owned mutexes:
+ */
+ temp_prio = pthread->active_priority;
+
+ /*
+ * Fix the priorities for all the mutexes this thread has
+ * locked since taking this mutex. This also has a
+ * potential side-effect of changing the threads priority.
+ */
+ mutex_rescan_owned(pthread, m);
+
+ /*
+ * If the thread is currently waiting on a mutex, check
+ * to see if the threads new priority has affected the
+ * priority of the mutex.
+ */
+ if ((temp_prio != pthread->active_priority) &&
+ (pthread->state == PS_MUTEX_WAIT) &&
+ (pthread->data.mutex->m_protocol == PTHREAD_PRIO_INHERIT)) {
+ /* Grab the mutex this thread is waiting on: */
+ m = pthread->data.mutex;
+
+ /*
+ * The priority for this thread has changed. Remove
+ * and reinsert this thread into the list of waiting
+ * threads to preserve decreasing priority order.
+ */
+ mutex_queue_remove(m, pthread);
+ mutex_queue_enq(m, pthread);
+
+ /* Grab the waiting thread with highest priority: */
+ pthread_next = TAILQ_FIRST(&m->m_queue);
+
+ /*
+ * Calculate the mutex priority as the maximum of the
+ * highest active priority of any waiting threads and
+ * the owning threads active priority.
+ */
+ temp_prio = MAX(pthread_next->active_priority,
+ MAX(m->m_saved_prio, m->m_owner->base_priority));
+
+ if (temp_prio != m->m_prio) {
+ /*
+ * The priority needs to be propagated to the
+ * mutex this thread is waiting on and up to
+ * the owner of that mutex.
+ */
+ m->m_prio = temp_prio;
+ pthread = m->m_owner;
+ }
+ else
+ /* We're done: */
+ m = NULL;
+
+ }
+ else
+ /* We're done: */
+ m = NULL;
+ }
+}
+
+static void
+mutex_rescan_owned (pthread_t pthread, pthread_mutex_t mutex)
+{
+ int active_prio, inherited_prio;
+ pthread_mutex_t m;
+ pthread_t pthread_next;
+
+ /*
+ * Start walking the mutexes the thread has taken since
+ * taking this mutex.
+ */
+ if (mutex == NULL) {
+ /*
+ * A null mutex means start at the beginning of the owned
+ * mutex list.
+ */
+ m = TAILQ_FIRST(&pthread->mutexq);
+
+ /* There is no inherited priority yet. */
+ inherited_prio = 0;
+ }
+ else {
+ /*
+ * The caller wants to start after a specific mutex. It
+ * is assumed that this mutex is a priority inheritence
+ * mutex and that its priority has been correctly
+ * calculated.
+ */
+ m = TAILQ_NEXT(mutex, m_qe);
+
+ /* Start inheriting priority from the specified mutex. */
+ inherited_prio = mutex->m_prio;
+ }
+ active_prio = MAX(inherited_prio, pthread->base_priority);
+
+ while (m != NULL) {
+ /*
+ * We only want to deal with priority inheritence
+ * mutexes. This might be optimized by only placing
+ * priority inheritence mutexes into the owned mutex
+ * list, but it may prove to be useful having all
+ * owned mutexes in this list. Consider a thread
+ * exiting while holding mutexes...
+ */
+ if (m->m_protocol == PTHREAD_PRIO_INHERIT) {
+ /*
+ * Fix the owners saved (inherited) priority to
+ * reflect the priority of the previous mutex.
+ */
+ m->m_saved_prio = inherited_prio;
+
+ if ((pthread_next = TAILQ_FIRST(&m->m_queue)) != NULL)
+ /* Recalculate the priority of the mutex: */
+ m->m_prio = MAX(active_prio,
+ pthread_next->active_priority);
+ else
+ m->m_prio = active_prio;
+
+ /* Recalculate new inherited and active priorities: */
+ inherited_prio = m->m_prio;
+ active_prio = MAX(m->m_prio, pthread->base_priority);
+ }
+
+ /* Advance to the next mutex owned by this thread: */
+ m = TAILQ_NEXT(m, m_qe);
+ }
+
+ /*
+ * Fix the threads inherited priority and recalculate its
+ * active priority.
+ */
+ pthread->inherited_priority = inherited_prio;
+ active_prio = MAX(inherited_prio, pthread->base_priority);
+
+ if (active_prio != pthread->active_priority) {
+ /*
+ * If this thread is in the priority queue, it must be
+ * removed and reinserted for its new priority.
+ */
+ if (pthread->flags & PTHREAD_FLAGS_IN_PRIOQ) {
+ /*
+ * Remove the thread from the priority queue
+ * before changing its priority:
+ */
+ PTHREAD_PRIOQ_REMOVE(pthread);
+
+ /*
+ * POSIX states that if the priority is being
+ * lowered, the thread must be inserted at the
+ * head of the queue for its priority if it owns
+ * any priority protection or inheritence mutexes.
+ */
+ if ((active_prio < pthread->active_priority) &&
+ (pthread->priority_mutex_count > 0)) {
+ /* Set the new active priority. */
+ pthread->active_priority = active_prio;
+
+ PTHREAD_PRIOQ_INSERT_HEAD(pthread);
+ }
+ else {
+ /* Set the new active priority. */
+ pthread->active_priority = active_prio;
+
+ PTHREAD_PRIOQ_INSERT_TAIL(pthread);
+ }
+ }
+ else {
+ /* Set the new active priority. */
+ pthread->active_priority = active_prio;
+ }
+ }
+}
+
+void
+_mutex_unlock_private(pthread_t pthread)
+{
+ struct pthread_mutex *m, *m_next;
+
+ for (m = TAILQ_FIRST(&pthread->mutexq); m != NULL; m = m_next) {
+ m_next = TAILQ_NEXT(m, m_qe);
+ if ((m->m_flags & MUTEX_FLAGS_PRIVATE) != 0)
+ pthread_mutex_unlock(&m);
+ }
+}
+
+/*
+ * Dequeue a waiting thread from the head of a mutex queue in descending
+ * priority order.
+ */
+static inline pthread_t
+mutex_queue_deq(pthread_mutex_t mutex)
+{
+ pthread_t pthread;
+
+ while ((pthread = TAILQ_FIRST(&mutex->m_queue)) != NULL) {
+ TAILQ_REMOVE(&mutex->m_queue, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_MUTEXQ;
+
+ /*
+ * Only exit the loop if the thread hasn't been
+ * cancelled.
+ */
+ if (pthread->interrupted == 0)
+ break;
+ }
+
+ return(pthread);
+}
+
+/*
+ * Remove a waiting thread from a mutex queue in descending priority order.
+ */
+static inline void
+mutex_queue_remove(pthread_mutex_t mutex, pthread_t pthread)
+{
+ if ((pthread->flags & PTHREAD_FLAGS_IN_MUTEXQ) != 0) {
+ TAILQ_REMOVE(&mutex->m_queue, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_MUTEXQ;
+ }
+}
+
+/*
+ * Enqueue a waiting thread to a queue in descending priority order.
+ */
+static inline void
+mutex_queue_enq(pthread_mutex_t mutex, pthread_t pthread)
+{
+ pthread_t tid = TAILQ_LAST(&mutex->m_queue, mutex_head);
+
+ /*
+ * For the common case of all threads having equal priority,
+ * we perform a quick check against the priority of the thread
+ * at the tail of the queue.
+ */
+ if ((tid == NULL) || (pthread->active_priority <= tid->active_priority))
+ TAILQ_INSERT_TAIL(&mutex->m_queue, pthread, qe);
+ else {
+ tid = TAILQ_FIRST(&mutex->m_queue);
+ while (pthread->active_priority <= tid->active_priority)
+ tid = TAILQ_NEXT(tid, qe);
+ TAILQ_INSERT_BEFORE(tid, pthread, qe);
+ }
+ pthread->flags |= PTHREAD_FLAGS_IN_MUTEXQ;
+}
+
+#endif
diff --git a/lib/libc_r/uthread/uthread_mutex_prioceiling.c b/lib/libc_r/uthread/uthread_mutex_prioceiling.c
new file mode 100644
index 0000000..c193c82
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_mutex_prioceiling.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_mutexattr_getprioceiling(pthread_mutexattr_t *mattr, int *prioceiling)
+{
+ int ret = 0;
+
+ if ((mattr == NULL) || (*mattr == NULL))
+ ret = EINVAL;
+ else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT)
+ ret = EINVAL;
+ else
+ *prioceiling = (*mattr)->m_ceiling;
+
+ return(ret);
+}
+
+int
+pthread_mutexattr_setprioceiling(pthread_mutexattr_t *mattr, int prioceiling)
+{
+ int ret = 0;
+
+ if ((mattr == NULL) || (*mattr == NULL))
+ ret = EINVAL;
+ else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT)
+ ret = EINVAL;
+ else
+ (*mattr)->m_ceiling = prioceiling;
+
+ return(ret);
+}
+
+int
+pthread_mutex_getprioceiling(pthread_mutex_t *mutex,
+ int *prioceiling)
+{
+ int ret;
+
+ if ((mutex == NULL) || (*mutex == NULL))
+ ret = EINVAL;
+ else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT)
+ ret = EINVAL;
+ else
+ ret = (*mutex)->m_prio;
+
+ return(ret);
+}
+
+int
+pthread_mutex_setprioceiling(pthread_mutex_t *mutex,
+ int prioceiling, int *old_ceiling)
+{
+ int ret = 0;
+
+ if ((mutex == NULL) || (*mutex == NULL))
+ ret = EINVAL;
+ else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT)
+ ret = EINVAL;
+ else {
+ /* Lock the mutex: */
+ if ((ret = pthread_mutex_lock(mutex)) == 0) {
+ /* Return the old ceiling and set the new ceiling: */
+ *old_ceiling = (*mutex)->m_prio;
+ (*mutex)->m_prio = prioceiling;
+
+ /* Unlock the mutex: */
+ ret = pthread_mutex_unlock(mutex);
+ }
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_mutex_protocol.c b/lib/libc_r/uthread/uthread_mutex_protocol.c
new file mode 100644
index 0000000..9847ae5
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_mutex_protocol.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_mutexattr_getprotocol(pthread_mutexattr_t *mattr, int *protocol)
+{
+ int ret = 0;
+
+ if ((mattr == NULL) || (*mattr == NULL))
+ ret = EINVAL;
+ else
+ *protocol = (*mattr)->m_protocol;
+
+ return(ret);
+}
+
+int
+pthread_mutexattr_setprotocol(pthread_mutexattr_t *mattr, int protocol)
+{
+ int ret = 0;
+
+ if ((mattr == NULL) || (*mattr == NULL) ||
+ (protocol < PTHREAD_PRIO_NONE) || (protocol > PTHREAD_PRIO_PROTECT))
+ ret = EINVAL;
+ else {
+ (*mattr)->m_protocol = protocol;
+ (*mattr)->m_ceiling = PTHREAD_MAX_PRIORITY;
+ }
+ return(ret);
+}
+
+#endif
diff --git a/lib/libc_r/uthread/uthread_mutexattr_destroy.c b/lib/libc_r/uthread/uthread_mutexattr_destroy.c
new file mode 100644
index 0000000..9afebad
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_mutexattr_destroy.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ ret = EINVAL;
+ } else {
+ free(*attr);
+ *attr = NULL;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_nanosleep.c b/lib/libc_r/uthread/uthread_nanosleep.c
new file mode 100644
index 0000000..e4772b4
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_nanosleep.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdio.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+nanosleep(const struct timespec * time_to_sleep,
+ struct timespec * time_remaining)
+{
+ int ret = 0;
+ struct timespec current_time;
+ struct timespec current_time1;
+ struct timespec remaining_time;
+ struct timeval tv;
+
+ _thread_enter_cancellation_point();
+ /* Check if the time to sleep is legal: */
+ if (time_to_sleep == NULL || time_to_sleep->tv_sec < 0 ||
+ time_to_sleep->tv_nsec < 0 || time_to_sleep->tv_nsec >= 1000000000) {
+ /* Return an EINVAL error : */
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ /* Get the current time: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &current_time);
+
+ /* Calculate the time for the current thread to wake up: */
+ _thread_run->wakeup_time.tv_sec = current_time.tv_sec + time_to_sleep->tv_sec;
+ _thread_run->wakeup_time.tv_nsec = current_time.tv_nsec + time_to_sleep->tv_nsec;
+
+ /* Check if the nanosecond field has overflowed: */
+ if (_thread_run->wakeup_time.tv_nsec >= 1000000000) {
+ /* Wrap the nanosecond field: */
+ _thread_run->wakeup_time.tv_sec += 1;
+ _thread_run->wakeup_time.tv_nsec -= 1000000000;
+ }
+ _thread_run->interrupted = 0;
+
+ /* Reschedule the current thread to sleep: */
+ _thread_kern_sched_state(PS_SLEEP_WAIT, __FILE__, __LINE__);
+
+ /* Get the current time: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &current_time1);
+
+ /* Calculate the remaining time to sleep: */
+ remaining_time.tv_sec = time_to_sleep->tv_sec + current_time.tv_sec - current_time1.tv_sec;
+ remaining_time.tv_nsec = time_to_sleep->tv_nsec + current_time.tv_nsec - current_time1.tv_nsec;
+
+ /* Check if the nanosecond field has underflowed: */
+ if (remaining_time.tv_nsec < 0) {
+ /* Handle the underflow: */
+ remaining_time.tv_sec -= 1;
+ remaining_time.tv_nsec += 1000000000;
+ }
+
+ /* Check if the nanosecond field has overflowed: */
+ if (remaining_time.tv_nsec >= 1000000000) {
+ /* Handle the overflow: */
+ remaining_time.tv_sec += 1;
+ remaining_time.tv_nsec -= 1000000000;
+ }
+
+ /* Check if the sleep was longer than the required time: */
+ if (remaining_time.tv_sec < 0) {
+ /* Reset the time left: */
+ remaining_time.tv_sec = 0;
+ remaining_time.tv_nsec = 0;
+ }
+
+ /* Check if the time remaining is to be returned: */
+ if (time_remaining != NULL) {
+ /* Return the actual time slept: */
+ time_remaining->tv_sec = remaining_time.tv_sec;
+ time_remaining->tv_nsec = remaining_time.tv_nsec;
+ }
+
+ /* Check if the sleep was interrupted: */
+ if (_thread_run->interrupted) {
+ /* Return an EINTR error : */
+ errno = EINTR;
+ ret = -1;
+ }
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_once.c b/lib/libc_r/uthread/uthread_once.c
new file mode 100644
index 0000000..ea56d82
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_once.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_once(pthread_once_t * once_control, void (*init_routine) (void))
+{
+ if (once_control->state == PTHREAD_NEEDS_INIT) {
+ pthread_mutex_lock(&(once_control->mutex));
+ if (once_control->state == PTHREAD_NEEDS_INIT) {
+ init_routine();
+ once_control->state = PTHREAD_DONE_INIT;
+ }
+ pthread_mutex_unlock(&(once_control->mutex));
+ }
+ return (0);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_open.c b/lib/libc_r/uthread/uthread_open.c
new file mode 100644
index 0000000..4e9993e
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_open.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+open(const char *path, int flags,...)
+{
+ int fd;
+ int mode = 0;
+ va_list ap;
+
+ _thread_enter_cancellation_point();
+
+ /* Check if the file is being created: */
+ if (flags & O_CREAT) {
+ /* Get the creation mode: */
+ va_start(ap, flags);
+ mode = va_arg(ap, int);
+ va_end(ap);
+ }
+ /* Open the file: */
+ if ((fd = _thread_sys_open(path, flags, mode)) < 0) {
+ }
+ /* Initialise the file descriptor table entry: */
+ else if (_thread_fd_table_init(fd) != 0) {
+ /* Quietly close the file: */
+ _thread_sys_close(fd);
+
+ /* Reset the file descriptor: */
+ fd = -1;
+ }
+
+ _thread_leave_cancellation_point();
+
+ /* Return the file descriptor or -1 on error: */
+ return (fd);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_pipe.c b/lib/libc_r/uthread/uthread_pipe.c
new file mode 100644
index 0000000..72ed6c9
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_pipe.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pipe(int fds[2])
+{
+ int ret;
+ if ((ret = _thread_sys_pipe(fds)) >= 0) {
+ if (_thread_fd_table_init(fds[0]) != 0 ||
+ _thread_fd_table_init(fds[1]) != 0) {
+ _thread_sys_close(fds[0]);
+ _thread_sys_close(fds[1]);
+ ret = -1;
+ }
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_poll.c b/lib/libc_r/uthread/uthread_poll.c
new file mode 100644
index 0000000..01916ad
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_poll.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+
+int
+poll(struct pollfd *fds, unsigned int nfds, int timeout)
+{
+ struct timespec ts;
+ int numfds = nfds;
+ int i, ret = 0, found = 0;
+ struct pthread_poll_data data;
+
+ if (numfds > _thread_dtablesize) {
+ numfds = _thread_dtablesize;
+ }
+ /* Check if a timeout was specified: */
+ if (timeout == INFTIM) {
+ /* Wait for ever: */
+ _thread_kern_set_timeout(NULL);
+ } else if (timeout > 0) {
+ /* Convert the timeout in msec to a timespec: */
+ ts.tv_sec = timeout / 1000;
+ ts.tv_nsec = (timeout % 1000) * 1000;
+
+ /* Set the wake up time: */
+ _thread_kern_set_timeout(&ts);
+ } else if (timeout < 0) {
+ /* a timeout less than zero but not == INFTIM is invalid */
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (((ret = _thread_sys_poll(fds, numfds, 0)) == 0) && (timeout != 0)) {
+ data.nfds = numfds;
+ data.fds = fds;
+
+ /*
+ * Clear revents in case of a timeout which leaves fds
+ * unchanged:
+ */
+ for (i = 0; i < numfds; i++) {
+ fds[i].revents = 0;
+ }
+
+ _thread_run->data.poll_data = &data;
+ _thread_run->interrupted = 0;
+ _thread_kern_sched_state(PS_POLL_WAIT, __FILE__, __LINE__);
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ } else {
+ ret = data.nfds;
+ }
+ }
+
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_priority_queue.c b/lib/libc_r/uthread/uthread_priority_queue.c
new file mode 100644
index 0000000..5bd8a8c
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_priority_queue.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <sys/queue.h>
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Prototypes: */
+static void pq_insert_prio_list(pq_queue_t *pq, int prio);
+
+#if defined(_PTHREADS_INVARIANTS)
+
+static int _pq_active = 0;
+
+#define _PQ_IN_SCHEDQ (PTHREAD_FLAGS_IN_PRIOQ | PTHREAD_FLAGS_IN_WAITQ | PTHREAD_FLAGS_IN_WORKQ)
+
+#define _PQ_SET_ACTIVE() _pq_active = 1
+#define _PQ_CLEAR_ACTIVE() _pq_active = 0
+#define _PQ_ASSERT_ACTIVE(msg) do { \
+ if (_pq_active == 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_INACTIVE(msg) do { \
+ if (_pq_active != 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_IN_WAITQ(thrd, msg) do { \
+ if (((thrd)->flags & PTHREAD_FLAGS_IN_WAITQ) == 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_IN_PRIOQ(thrd, msg) do { \
+ if (((thrd)->flags & PTHREAD_FLAGS_IN_PRIOQ) == 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_NOT_QUEUED(thrd, msg) do { \
+ if ((thrd)->flags & _PQ_IN_SCHEDQ) \
+ PANIC(msg); \
+} while (0)
+
+#else
+
+#define _PQ_SET_ACTIVE()
+#define _PQ_CLEAR_ACTIVE()
+#define _PQ_ASSERT_ACTIVE(msg)
+#define _PQ_ASSERT_INACTIVE(msg)
+#define _PQ_ASSERT_IN_WAITQ(thrd, msg)
+#define _PQ_ASSERT_IN_PRIOQ(thrd, msg)
+#define _PQ_ASSERT_NOT_QUEUED(thrd, msg)
+#define _PQ_CHECK_PRIO()
+
+#endif
+
+
+int
+_pq_alloc(pq_queue_t *pq, int minprio, int maxprio)
+{
+ int i, ret = 0;
+ int prioslots = maxprio - minprio + 1;
+
+ if (pq == NULL)
+ ret = -1;
+
+ /* Create the priority queue with (maxprio - minprio + 1) slots: */
+ else if ((pq->pq_lists =
+ (pq_list_t *) malloc(sizeof(pq_list_t) * prioslots)) == NULL)
+ ret = -1;
+
+ else {
+ /* Remember the queue size: */
+ pq->pq_size = prioslots;
+
+ ret = _pq_init(pq);
+
+ }
+ return (ret);
+}
+
+int
+_pq_init(pq_queue_t *pq)
+{
+ int i, ret = 0;
+
+ if ((pq == NULL) || (pq->pq_lists == NULL))
+ ret = -1;
+
+ else {
+ /* Initialize the queue for each priority slot: */
+ for (i = 0; i < pq->pq_size; i++) {
+ TAILQ_INIT(&pq->pq_lists[i].pl_head);
+ pq->pq_lists[i].pl_prio = i;
+ pq->pq_lists[i].pl_queued = 0;
+ }
+
+ /* Initialize the priority queue: */
+ TAILQ_INIT(&pq->pq_queue);
+ _PQ_CLEAR_ACTIVE();
+ }
+ return (ret);
+}
+
+void
+_pq_remove(pq_queue_t *pq, pthread_t pthread)
+{
+ int prio = pthread->active_priority;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_remove: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_IN_PRIOQ(pthread, "_pq_remove: Not in priority queue");
+
+ /*
+ * Remove this thread from priority list. Note that if
+ * the priority list becomes empty, it is not removed
+ * from the priority queue because another thread may be
+ * added to the priority list (resulting in a needless
+ * removal/insertion). Priority lists are only removed
+ * from the priority queue when _pq_first is called.
+ */
+ TAILQ_REMOVE(&pq->pq_lists[prio].pl_head, pthread, pqe);
+
+ /* This thread is now longer in the priority queue. */
+ pthread->flags &= ~PTHREAD_FLAGS_IN_PRIOQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+
+void
+_pq_insert_head(pq_queue_t *pq, pthread_t pthread)
+{
+ int prio = pthread->active_priority;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_insert_head: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_NOT_QUEUED(pthread,
+ "_pq_insert_head: Already in priority queue");
+
+ TAILQ_INSERT_HEAD(&pq->pq_lists[prio].pl_head, pthread, pqe);
+ if (pq->pq_lists[prio].pl_queued == 0)
+ /* Insert the list into the priority queue: */
+ pq_insert_prio_list(pq, prio);
+
+ /* Mark this thread as being in the priority queue. */
+ pthread->flags |= PTHREAD_FLAGS_IN_PRIOQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+
+void
+_pq_insert_tail(pq_queue_t *pq, pthread_t pthread)
+{
+ int prio = pthread->active_priority;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_insert_tail: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_NOT_QUEUED(pthread,
+ "_pq_insert_tail: Already in priority queue");
+
+ TAILQ_INSERT_TAIL(&pq->pq_lists[prio].pl_head, pthread, pqe);
+ if (pq->pq_lists[prio].pl_queued == 0)
+ /* Insert the list into the priority queue: */
+ pq_insert_prio_list(pq, prio);
+
+ /* Mark this thread as being in the priority queue. */
+ pthread->flags |= PTHREAD_FLAGS_IN_PRIOQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+
+pthread_t
+_pq_first(pq_queue_t *pq)
+{
+ pq_list_t *pql;
+ pthread_t pthread = NULL;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_first: pq_active");
+ _PQ_SET_ACTIVE();
+
+ while (((pql = TAILQ_FIRST(&pq->pq_queue)) != NULL) &&
+ (pthread == NULL)) {
+ if ((pthread = TAILQ_FIRST(&pql->pl_head)) == NULL) {
+ /*
+ * The priority list is empty; remove the list
+ * from the queue.
+ */
+ TAILQ_REMOVE(&pq->pq_queue, pql, pl_link);
+
+ /* Mark the list as not being in the queue: */
+ pql->pl_queued = 0;
+ }
+ }
+
+ _PQ_CLEAR_ACTIVE();
+ return (pthread);
+}
+
+
+static void
+pq_insert_prio_list(pq_queue_t *pq, int prio)
+{
+ pq_list_t *pql;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_ACTIVE("pq_insert_prio_list: pq_active");
+
+ /*
+ * The priority queue is in descending priority order. Start at
+ * the beginning of the queue and find the list before which the
+ * new list should be inserted.
+ */
+ pql = TAILQ_FIRST(&pq->pq_queue);
+ while ((pql != NULL) && (pql->pl_prio > prio))
+ pql = TAILQ_NEXT(pql, pl_link);
+
+ /* Insert the list: */
+ if (pql == NULL)
+ TAILQ_INSERT_TAIL(&pq->pq_queue, &pq->pq_lists[prio], pl_link);
+ else
+ TAILQ_INSERT_BEFORE(pql, &pq->pq_lists[prio], pl_link);
+
+ /* Mark this list as being in the queue: */
+ pq->pq_lists[prio].pl_queued = 1;
+}
+
+#if defined(_PTHREADS_INVARIANTS)
+void
+_waitq_insert(pthread_t pthread)
+{
+ pthread_t tid;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_waitq_insert: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_NOT_QUEUED(pthread, "_waitq_insert: Already in queue");
+
+ if (pthread->wakeup_time.tv_sec == -1)
+ TAILQ_INSERT_TAIL(&_waitingq, pthread, pqe);
+ else {
+ tid = TAILQ_FIRST(&_waitingq);
+ while ((tid != NULL) && (tid->wakeup_time.tv_sec != -1) &&
+ ((tid->wakeup_time.tv_sec < pthread->wakeup_time.tv_sec) ||
+ ((tid->wakeup_time.tv_sec == pthread->wakeup_time.tv_sec) &&
+ (tid->wakeup_time.tv_nsec <= pthread->wakeup_time.tv_nsec))))
+ tid = TAILQ_NEXT(tid, pqe);
+ if (tid == NULL)
+ TAILQ_INSERT_TAIL(&_waitingq, pthread, pqe);
+ else
+ TAILQ_INSERT_BEFORE(tid, pthread, pqe);
+ }
+ pthread->flags |= PTHREAD_FLAGS_IN_WAITQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+void
+_waitq_remove(pthread_t pthread)
+{
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_waitq_remove: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_IN_WAITQ(pthread, "_waitq_remove: Not in queue");
+
+ TAILQ_REMOVE(&_waitingq, pthread, pqe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_WAITQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+void
+_waitq_setactive(void)
+{
+ _PQ_ASSERT_INACTIVE("_waitq_setactive: pq_active");
+ _PQ_SET_ACTIVE();
+}
+
+void
+_waitq_clearactive(void)
+{
+ _PQ_ASSERT_ACTIVE("_waitq_clearactive: ! pq_active");
+ _PQ_CLEAR_ACTIVE();
+}
+#endif
+#endif
diff --git a/lib/libc_r/uthread/uthread_read.c b/lib/libc_r/uthread/uthread_read.c
new file mode 100644
index 0000000..8cbb5be
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_read.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+read(int fd, void *buf, size_t nbytes)
+{
+ int ret;
+ int type;
+
+ _thread_enter_cancellation_point();
+
+ /* POSIX says to do just this: */
+ if (nbytes == 0) {
+ _thread_leave_cancellation_point();
+ return (0);
+ }
+
+ /* Lock the file descriptor for read: */
+ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ /* Get the read/write mode type: */
+ type = _thread_fd_table[fd]->flags & O_ACCMODE;
+
+ /* Check if the file is not open for read: */
+ if (type != O_RDONLY && type != O_RDWR) {
+ /* File is not open for read: */
+ errno = EBADF;
+ _FD_UNLOCK(fd, FD_READ);
+ _thread_leave_cancellation_point();
+ return (-1);
+ }
+
+ /* Perform a non-blocking read syscall: */
+ while ((ret = _thread_sys_read(fd, buf, nbytes)) < 0) {
+ if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0 &&
+ (errno == EWOULDBLOCK || errno == EAGAIN)) {
+ _thread_run->data.fd.fd = fd;
+ _thread_kern_set_timeout(NULL);
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDR_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ _FD_UNLOCK(fd, FD_READ);
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_readv.c b/lib/libc_r/uthread/uthread_readv.c
new file mode 100644
index 0000000..a1a862d
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_readv.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+readv(int fd, const struct iovec * iov, int iovcnt)
+{
+ int ret;
+ int type;
+
+ /* Lock the file descriptor for read: */
+ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ /* Get the read/write mode type: */
+ type = _thread_fd_table[fd]->flags & O_ACCMODE;
+
+ /* Check if the file is not open for read: */
+ if (type != O_RDONLY && type != O_RDWR) {
+ /* File is not open for read: */
+ errno = EBADF;
+ _FD_UNLOCK(fd, FD_READ);
+ return (-1);
+ }
+
+ /* Perform a non-blocking readv syscall: */
+ while ((ret = _thread_sys_readv(fd, iov, iovcnt)) < 0) {
+ if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0 &&
+ (errno == EWOULDBLOCK || errno == EAGAIN)) {
+ _thread_run->data.fd.fd = fd;
+ _thread_kern_set_timeout(NULL);
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDR_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ _FD_UNLOCK(fd, FD_READ);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_recvfrom.c b/lib/libc_r/uthread/uthread_recvfrom.c
new file mode 100644
index 0000000..3130dfd
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_recvfrom.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr * from, socklen_t *from_len)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ while ((ret = _thread_sys_recvfrom(fd, buf, len, flags, from, from_len)) < 0) {
+ if (!(_thread_fd_table[fd]->flags & O_NONBLOCK) && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
+ _thread_run->data.fd.fd = fd;
+
+ /* Set the timeout: */
+ _thread_kern_set_timeout(NULL);
+ _thread_run->interrupted = 0;
+ _thread_kern_sched_state(PS_FDR_WAIT, __FILE__, __LINE__);
+
+ /* Check if the wait was interrupted: */
+ if (_thread_run->interrupted) {
+ /* Return an error status: */
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ } else {
+ ret = -1;
+ break;
+ }
+ }
+ _FD_UNLOCK(fd, FD_READ);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_recvmsg.c b/lib/libc_r/uthread/uthread_recvmsg.c
new file mode 100644
index 0000000..dff8941
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_recvmsg.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+recvmsg(int fd, struct msghdr *msg, int flags)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ while ((ret = _thread_sys_recvmsg(fd, msg, flags)) < 0) {
+ if (!(_thread_fd_table[fd]->flags & O_NONBLOCK) && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
+ _thread_run->data.fd.fd = fd;
+
+ /* Set the timeout: */
+ _thread_kern_set_timeout(NULL);
+ _thread_run->interrupted = 0;
+ _thread_kern_sched_state(PS_FDR_WAIT, __FILE__, __LINE__);
+
+ /* Check if the wait was interrupted: */
+ if (_thread_run->interrupted) {
+ /* Return an error status: */
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ } else {
+ ret = -1;
+ break;
+ }
+ }
+ _FD_UNLOCK(fd, FD_READ);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_resume_np.c b/lib/libc_r/uthread/uthread_resume_np.c
new file mode 100644
index 0000000..98ec718
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_resume_np.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Resume a thread: */
+int
+pthread_resume_np(pthread_t thread)
+{
+ int ret;
+
+ /* Find the thread in the list of active threads: */
+ if ((ret = _find_thread(thread)) == 0) {
+ /* The thread exists. Is it suspended? */
+ if (thread->state != PS_SUSPENDED) {
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Allow the thread to run. */
+ PTHREAD_NEW_STATE(thread,PS_RUNNING);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_rwlock.c b/lib/libc_r/uthread/uthread_rwlock.c
new file mode 100644
index 0000000..648e8a3
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_rwlock.c
@@ -0,0 +1,335 @@
+/*-
+ * Copyright (c) 1998 Alex Nash
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifdef _THREAD_SAFE
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* maximum number of times a read lock may be obtained */
+#define MAX_READ_LOCKS (INT_MAX - 1)
+
+static int init_static (pthread_rwlock_t *rwlock);
+
+static spinlock_t static_init_lock = _SPINLOCK_INITIALIZER;
+
+static int
+init_static (pthread_rwlock_t *rwlock)
+{
+ int ret;
+
+ _SPINLOCK(&static_init_lock);
+
+ if (*rwlock == NULL)
+ ret = pthread_rwlock_init(rwlock, NULL);
+ else
+ ret = 0;
+
+ _SPINUNLOCK(&static_init_lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
+{
+ int ret;
+
+ if (rwlock == NULL)
+ ret = EINVAL;
+ else {
+ pthread_rwlock_t prwlock;
+
+ prwlock = *rwlock;
+
+ pthread_mutex_destroy(&prwlock->lock);
+ pthread_cond_destroy(&prwlock->read_signal);
+ pthread_cond_destroy(&prwlock->write_signal);
+ free(prwlock);
+
+ *rwlock = NULL;
+
+ ret = 0;
+ }
+
+ return(ret);
+}
+
+int
+pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ /* allocate rwlock object */
+ prwlock = (pthread_rwlock_t)malloc(sizeof(struct pthread_rwlock));
+
+ if (prwlock == NULL)
+ return(ENOMEM);
+
+ /* initialize the lock */
+ if ((ret = pthread_mutex_init(&prwlock->lock, NULL)) != 0)
+ free(prwlock);
+ else {
+ /* initialize the read condition signal */
+ ret = pthread_cond_init(&prwlock->read_signal, NULL);
+
+ if (ret != 0) {
+ pthread_mutex_destroy(&prwlock->lock);
+ free(prwlock);
+ } else {
+ /* initialize the write condition signal */
+ ret = pthread_cond_init(&prwlock->write_signal, NULL);
+
+ if (ret != 0) {
+ pthread_cond_destroy(&prwlock->read_signal);
+ pthread_mutex_destroy(&prwlock->lock);
+ free(prwlock);
+ } else {
+ /* success */
+ prwlock->state = 0;
+ prwlock->blocked_writers = 0;
+
+ *rwlock = prwlock;
+ }
+ }
+ }
+
+ return(ret);
+}
+
+int
+pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ /* give writers priority over readers */
+ while (prwlock->blocked_writers || prwlock->state < 0) {
+ ret = pthread_cond_wait(&prwlock->read_signal, &prwlock->lock);
+
+ if (ret != 0) {
+ /* can't do a whole lot if this fails */
+ pthread_mutex_unlock(&prwlock->lock);
+ return(ret);
+ }
+ }
+
+ /* check lock count */
+ if (prwlock->state == MAX_READ_LOCKS)
+ ret = EAGAIN;
+ else
+ ++prwlock->state; /* indicate we are locked for reading */
+
+ /*
+ * Something is really wrong if this call fails. Returning
+ * error won't do because we've already obtained the read
+ * lock. Decrementing 'state' is no good because we probably
+ * don't have the monitor lock.
+ */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ /* give writers priority over readers */
+ if (prwlock->blocked_writers || prwlock->state < 0)
+ ret = EWOULDBLOCK;
+ else if (prwlock->state == MAX_READ_LOCKS)
+ ret = EAGAIN; /* too many read locks acquired */
+ else
+ ++prwlock->state; /* indicate we are locked for reading */
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ if (prwlock->state != 0)
+ ret = EWOULDBLOCK;
+ else
+ /* indicate we are locked for writing */
+ prwlock->state = -1;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ if (prwlock == NULL)
+ return(EINVAL);
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ if (prwlock->state > 0) {
+ if (--prwlock->state == 0 && prwlock->blocked_writers)
+ ret = pthread_cond_signal(&prwlock->write_signal);
+ } else if (prwlock->state < 0) {
+ prwlock->state = 0;
+
+ if (prwlock->blocked_writers)
+ ret = pthread_cond_signal(&prwlock->write_signal);
+ else
+ ret = pthread_cond_broadcast(&prwlock->read_signal);
+ } else
+ ret = EINVAL;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ while (prwlock->state != 0) {
+ ++prwlock->blocked_writers;
+
+ ret = pthread_cond_wait(&prwlock->write_signal, &prwlock->lock);
+
+ if (ret != 0) {
+ --prwlock->blocked_writers;
+ pthread_mutex_unlock(&prwlock->lock);
+ return(ret);
+ }
+
+ --prwlock->blocked_writers;
+ }
+
+ /* indicate we are locked for writing */
+ prwlock->state = -1;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+#endif /* _THREAD_SAFE */
diff --git a/lib/libc_r/uthread/uthread_rwlockattr.c b/lib/libc_r/uthread/uthread_rwlockattr.c
new file mode 100644
index 0000000..7a56bca
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_rwlockattr.c
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 1998 Alex Nash
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifdef _THREAD_SAFE
+#include <errno.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr)
+{
+ pthread_rwlockattr_t prwlockattr;
+
+ if (rwlockattr == NULL)
+ return(EINVAL);
+
+ prwlockattr = *rwlockattr;
+
+ if (prwlockattr == NULL)
+ return(EINVAL);
+
+ free(prwlockattr);
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *rwlockattr,
+ int *pshared)
+{
+ *pshared = (*rwlockattr)->pshared;
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr)
+{
+ pthread_rwlockattr_t prwlockattr;
+
+ if (rwlockattr == NULL)
+ return(EINVAL);
+
+ prwlockattr = (pthread_rwlockattr_t)
+ malloc(sizeof(struct pthread_rwlockattr));
+
+ if (prwlockattr == NULL)
+ return(ENOMEM);
+
+ prwlockattr->pshared = PTHREAD_PROCESS_PRIVATE;
+ *rwlockattr = prwlockattr;
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_setpshared (pthread_rwlockattr_t *rwlockattr, int pshared)
+{
+ /* Only PTHREAD_PROCESS_PRIVATE is supported. */
+ if (pshared != PTHREAD_PROCESS_PRIVATE)
+ return(EINVAL);
+
+ (*rwlockattr)->pshared = pshared;
+
+ return(0);
+}
+
+#endif /* _THREAD_SAFE */
diff --git a/lib/libc_r/uthread/uthread_select.c b/lib/libc_r/uthread/uthread_select.c
new file mode 100644
index 0000000..9bfae89
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_select.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <unistd.h>
+#include <errno.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+select(int numfds, fd_set * readfds, fd_set * writefds,
+ fd_set * exceptfds, struct timeval * timeout)
+{
+ struct timespec ts;
+ int i, ret = 0, f_wait = 1;
+ int pfd_index, got_one = 0, fd_count = 0;
+ struct pthread_poll_data data;
+
+ if (numfds > _thread_dtablesize) {
+ numfds = _thread_dtablesize;
+ }
+ /* Check if a timeout was specified: */
+ if (timeout) {
+ if (timeout->tv_sec < 0 ||
+ timeout->tv_usec < 0 || timeout->tv_usec >= 1000000) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /* Convert the timeval to a timespec: */
+ TIMEVAL_TO_TIMESPEC(timeout, &ts);
+
+ /* Set the wake up time: */
+ _thread_kern_set_timeout(&ts);
+ if (ts.tv_sec == 0 && ts.tv_nsec == 0)
+ f_wait = 0;
+ } else {
+ /* Wait for ever: */
+ _thread_kern_set_timeout(NULL);
+ }
+
+ /* Count the number of file descriptors to be polled: */
+ if (readfds || writefds || exceptfds) {
+ for (i = 0; i < numfds; i++) {
+ if ((readfds && FD_ISSET(i, readfds)) ||
+ (exceptfds && FD_ISSET(i, exceptfds)) ||
+ (writefds && FD_ISSET(i, writefds))) {
+ fd_count++;
+ }
+ }
+ }
+
+ /*
+ * Allocate memory for poll data if it hasn't already been
+ * allocated or if previously allocated memory is insufficient.
+ */
+ if ((_thread_run->poll_data.fds == NULL) ||
+ (_thread_run->poll_data.nfds < fd_count)) {
+ data.fds = (struct pollfd *) realloc(_thread_run->poll_data.fds,
+ sizeof(struct pollfd) * MAX(128, fd_count));
+ if (data.fds == NULL) {
+ errno = ENOMEM;
+ ret = -1;
+ }
+ else {
+ /*
+ * Note that the threads poll data always
+ * indicates what is allocated, not what is
+ * currently being polled.
+ */
+ _thread_run->poll_data.fds = data.fds;
+ _thread_run->poll_data.nfds = MAX(128, fd_count);
+ }
+ }
+ if (ret == 0) {
+ /* Setup the wait data. */
+ data.fds = _thread_run->poll_data.fds;
+ data.nfds = fd_count;
+
+ /*
+ * Setup the array of pollfds. Optimize this by
+ * running the loop in reverse and stopping when
+ * the number of selected file descriptors is reached.
+ */
+ for (i = numfds - 1, pfd_index = fd_count - 1;
+ (i >= 0) && (pfd_index >= 0); i--) {
+ data.fds[pfd_index].events = 0;
+ if (readfds && FD_ISSET(i, readfds)) {
+ data.fds[pfd_index].events = POLLRDNORM;
+ }
+ if (exceptfds && FD_ISSET(i, exceptfds)) {
+ data.fds[pfd_index].events |= POLLRDBAND;
+ }
+ if (writefds && FD_ISSET(i, writefds)) {
+ data.fds[pfd_index].events |= POLLWRNORM;
+ }
+ if (data.fds[pfd_index].events != 0) {
+ /*
+ * Set the file descriptor to be polled and
+ * clear revents in case of a timeout which
+ * leaves fds unchanged:
+ */
+ data.fds[pfd_index].fd = i;
+ data.fds[pfd_index].revents = 0;
+ pfd_index--;
+ }
+ }
+ if (((ret = _thread_sys_poll(data.fds, data.nfds, 0)) == 0) &&
+ (f_wait != 0)) {
+ _thread_run->data.poll_data = &data;
+ _thread_run->interrupted = 0;
+ _thread_kern_sched_state(PS_SELECT_WAIT, __FILE__, __LINE__);
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ data.nfds = 0;
+ ret = -1;
+ } else
+ ret = data.nfds;
+ }
+ }
+
+ if (ret >= 0) {
+ numfds = 0;
+ for (i = 0; i < fd_count; i++) {
+ /*
+ * Check the results of the poll and clear
+ * this file descriptor from the fdset if
+ * the requested event wasn't ready.
+ */
+ got_one = 0;
+ if (readfds != NULL) {
+ if (FD_ISSET(data.fds[i].fd, readfds)) {
+ if (data.fds[i].revents & (POLLIN |
+ POLLRDNORM))
+ got_one = 1;
+ else
+ FD_CLR(data.fds[i].fd, readfds);
+ }
+ }
+ if (writefds != NULL) {
+ if (FD_ISSET(data.fds[i].fd, writefds)) {
+ if (data.fds[i].revents & (POLLOUT |
+ POLLWRNORM | POLLWRBAND))
+ got_one = 1;
+ else
+ FD_CLR(data.fds[i].fd,
+ writefds);
+ }
+ }
+ if (exceptfds != NULL) {
+ if (FD_ISSET(data.fds[i].fd, exceptfds)) {
+ if (data.fds[i].revents & (POLLRDBAND |
+ POLLPRI | POLLHUP | POLLERR |
+ POLLNVAL))
+ got_one = 1;
+ else
+ FD_CLR(data.fds[i].fd,
+ exceptfds);
+ }
+ }
+ if (got_one)
+ numfds++;
+ }
+ ret = numfds;
+ }
+
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_self.c b/lib/libc_r/uthread/uthread_self.c
new file mode 100644
index 0000000..81ec427
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_self.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+pthread_t
+pthread_self(void)
+{
+ /* Return the running thread pointer: */
+ return (_thread_run);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_sendmsg.c b/lib/libc_r/uthread/uthread_sendmsg.c
new file mode 100644
index 0000000..6834104
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sendmsg.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+sendmsg(int fd, const struct msghdr *msg, int flags)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ while ((ret = _thread_sys_sendmsg(fd, msg, flags)) < 0) {
+ if (!(_thread_fd_table[fd]->flags & O_NONBLOCK) && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
+ _thread_run->data.fd.fd = fd;
+
+ /* Set the timeout: */
+ _thread_kern_set_timeout(NULL);
+ _thread_run->interrupted = 0;
+ _thread_kern_sched_state(PS_FDW_WAIT, __FILE__, __LINE__);
+
+ /* Check if the operation was interrupted: */
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ } else {
+ ret = -1;
+ break;
+ }
+ }
+ _FD_UNLOCK(fd, FD_WRITE);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_sendto.c b/lib/libc_r/uthread/uthread_sendto.c
new file mode 100644
index 0000000..348affc
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sendto.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+sendto(int fd, const void *msg, size_t len, int flags, const struct sockaddr * to, socklen_t to_len)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ while ((ret = _thread_sys_sendto(fd, msg, len, flags, to, to_len)) < 0) {
+ if (!(_thread_fd_table[fd]->flags & O_NONBLOCK) && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
+ _thread_run->data.fd.fd = fd;
+
+ /* Set the timeout: */
+ _thread_kern_set_timeout(NULL);
+ _thread_run->interrupted = 0;
+ _thread_kern_sched_state(PS_FDW_WAIT, __FILE__, __LINE__);
+
+ /* Check if the operation was interrupted: */
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ } else {
+ ret = -1;
+ break;
+ }
+ }
+ _FD_UNLOCK(fd, FD_WRITE);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_seterrno.c b/lib/libc_r/uthread/uthread_seterrno.c
new file mode 100644
index 0000000..1934aac
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_seterrno.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/*
+ * This function needs to reference the global error variable which is
+ * normally hidden from the user.
+ */
+#ifdef errno
+#undef errno;
+#endif
+extern int errno;
+
+void
+_thread_seterrno(pthread_t thread, int error)
+{
+ /* Check for the initial thread: */
+ if (thread == _thread_initial)
+ /* The initial thread always uses the global error variable: */
+ errno = error;
+ else
+ /*
+ * Threads other than the initial thread always use the error
+ * field in the thread structureL
+ */
+ thread->error = error;
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_setprio.c b/lib/libc_r/uthread/uthread_setprio.c
new file mode 100644
index 0000000..5f7b44a
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_setprio.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_setprio(pthread_t pthread, int prio)
+{
+ int ret, policy;
+ struct sched_param param;
+
+ if ((ret = pthread_getschedparam(pthread, &policy, &param)) == 0) {
+ param.sched_priority = prio;
+ ret = pthread_setschedparam(pthread, policy, &param);
+ }
+
+ /* Return the error status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_setschedparam.c b/lib/libc_r/uthread/uthread_setschedparam.c
new file mode 100644
index 0000000..57e24e8
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_setschedparam.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <sys/param.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_setschedparam(pthread_t pthread, int policy,
+ const struct sched_param *param)
+{
+ int old_prio, in_readyq = 0, ret = 0;
+
+ if ((param == NULL) || (param->sched_priority < PTHREAD_MIN_PRIORITY) ||
+ (param->sched_priority > PTHREAD_MAX_PRIORITY) ||
+ (policy < SCHED_FIFO) || (policy > SCHED_RR))
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+
+ /* Find the thread in the list of active threads: */
+ else if ((ret = _find_thread(pthread)) == 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ if (param->sched_priority != pthread->base_priority) {
+ /*
+ * Remove the thread from its current priority
+ * queue before any adjustments are made to its
+ * active priority:
+ */
+ if ((pthread->flags & PTHREAD_FLAGS_IN_PRIOQ) != 0) {
+ in_readyq = 1;
+ old_prio = pthread->active_priority;
+ PTHREAD_PRIOQ_REMOVE(pthread);
+ }
+
+ /* Set the thread base priority: */
+ pthread->base_priority = param->sched_priority;
+
+ /* Recalculate the active priority: */
+ pthread->active_priority = MAX(pthread->base_priority,
+ pthread->inherited_priority);
+
+ if (in_readyq) {
+ if ((pthread->priority_mutex_count > 0) &&
+ (old_prio > pthread->active_priority)) {
+ /*
+ * POSIX states that if the priority is
+ * being lowered, the thread must be
+ * inserted at the head of the queue for
+ * its priority if it owns any priority
+ * protection or inheritence mutexes.
+ */
+ PTHREAD_PRIOQ_INSERT_HEAD(pthread);
+ }
+ else
+ PTHREAD_PRIOQ_INSERT_TAIL(pthread);
+ }
+
+ /*
+ * Check for any mutex priority adjustments. This
+ * includes checking for a priority mutex on which
+ * this thread is waiting.
+ */
+ _mutex_notify_priochange(pthread);
+ }
+
+ /* Set the scheduling policy: */
+ pthread->attr.sched_policy = policy;
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_setsockopt.c b/lib/libc_r/uthread/uthread_setsockopt.c
new file mode 100644
index 0000000..ed1155b
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_setsockopt.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
+{
+ int ret;
+
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ ret = _thread_sys_setsockopt(fd, level, optname, optval, optlen);
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ return ret;
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_shutdown.c b/lib/libc_r/uthread/uthread_shutdown.c
new file mode 100644
index 0000000..ccb087d
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_shutdown.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+shutdown(int fd, int how)
+{
+ int ret;
+
+ switch (how) {
+ case 0:
+ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ ret = _thread_sys_shutdown(fd, how);
+ _FD_UNLOCK(fd, FD_READ);
+ }
+ break;
+ case 1:
+ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ ret = _thread_sys_shutdown(fd, how);
+ _FD_UNLOCK(fd, FD_WRITE);
+ }
+ break;
+ case 2:
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ ret = _thread_sys_shutdown(fd, how);
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ break;
+ default:
+ errno = EBADF;
+ ret = -1;
+ break;
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_sig.c b/lib/libc_r/uthread/uthread_sig.c
new file mode 100644
index 0000000..b744659
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sig.c
@@ -0,0 +1,584 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Prototypes: */
+static void _thread_sig_check_state(pthread_t pthread, int sig);
+
+/* Static variables: */
+static spinlock_t signal_lock = _SPINLOCK_INITIALIZER;
+static unsigned int pending_sigs[NSIG];
+static unsigned int handled_sigs[NSIG];
+static int volatile check_pending = 0;
+
+/* Initialize signal handling facility: */
+void
+_thread_sig_init(void)
+{
+ int i;
+
+ /* Clear pending and handled signal counts: */
+ for (i = 1; i < NSIG; i++) {
+ pending_sigs[i - 1] = 0;
+ handled_sigs[i - 1] = 0;
+ }
+
+ /* Clear the lock: */
+ signal_lock.access_lock = 0;
+
+ /* Clear the process pending signals: */
+ sigemptyset(&_process_sigpending);
+}
+
+void
+_thread_sig_handler(int sig, int code, ucontext_t * scp)
+{
+ pthread_t pthread;
+ int i;
+ char c;
+
+ /* Check if an interval timer signal: */
+ if (sig == _SCHED_SIGNAL) {
+ if (_thread_kern_in_sched != 0) {
+ /*
+ * The scheduler is already running; ignore this
+ * signal.
+ */
+ }
+ /*
+ * Check if the scheduler interrupt has come when
+ * the currently running thread has deferred thread
+ * signals.
+ */
+ else if (_thread_run->sig_defer_count > 0)
+ _thread_run->yield_on_sig_undefer = 1;
+
+ else {
+ /*
+ * Schedule the next thread. This function is not
+ * expected to return because it will do a longjmp
+ * instead.
+ */
+ _thread_kern_sched(scp);
+
+ /*
+ * This point should not be reached, so abort the
+ * process:
+ */
+ PANIC("Returned to signal function from scheduler");
+ }
+ }
+ /*
+ * Check if the kernel has been interrupted while the scheduler
+ * is accessing the scheduling queues or if there is a currently
+ * running thread that has deferred signals.
+ */
+ else if ((_queue_signals != 0) || ((_thread_kern_in_sched == 0) &&
+ (_thread_run->sig_defer_count > 0))) {
+ /* Cast the signal number to a character variable: */
+ c = sig;
+
+ /*
+ * Write the signal number to the kernel pipe so that it will
+ * be ready to read when this signal handler returns.
+ */
+ _thread_sys_write(_thread_kern_pipe[1], &c, 1);
+
+ /* Indicate that there are queued signals in the pipe. */
+ _sigq_check_reqd = 1;
+ }
+ else {
+ if (_atomic_lock(&signal_lock.access_lock)) {
+ /* There is another signal handler running: */
+ pending_sigs[sig - 1]++;
+ check_pending = 1;
+ }
+ else {
+ /* It's safe to handle the signal now. */
+ pthread = _thread_sig_handle(sig, scp);
+
+ /* Reset the pending and handled count back to 0: */
+ pending_sigs[sig - 1] = 0;
+ handled_sigs[sig - 1] = 0;
+
+ if (pthread == NULL)
+ signal_lock.access_lock = 0;
+ else {
+ sigaddset(&pthread->sigmask, sig);
+ signal_lock.access_lock = 0;
+ _thread_sig_deliver(pthread, sig);
+ sigdelset(&pthread->sigmask, sig);
+ }
+ }
+
+ /* Enter a loop to process pending signals: */
+ while ((check_pending != 0) &&
+ (_atomic_lock(&signal_lock.access_lock) == 0)) {
+ check_pending = 0;
+ for (i = 1; i < NSIG; i++) {
+ if (pending_sigs[i - 1] > handled_sigs[i - 1]) {
+ pending_sigs[i - 1] = handled_sigs[i - 1];
+ pthread = _thread_sig_handle(i, scp);
+ if (pthread != NULL) {
+ sigaddset(&pthread->sigmask, i);
+ signal_lock.access_lock = 0;
+ _thread_sig_deliver(pthread, i);
+ sigdelset(&pthread->sigmask, i);
+ if (_atomic_lock(&signal_lock.access_lock)) {
+ check_pending = 1;
+ return;
+ }
+ }
+ }
+ }
+ signal_lock.access_lock = 0;
+ }
+ }
+}
+
+pthread_t
+_thread_sig_handle(int sig, ucontext_t * scp)
+{
+ int i;
+ pthread_t pthread, pthread_next;
+ pthread_t suspended_thread, signaled_thread;
+
+ /* Check if the signal requires a dump of thread information: */
+ if (sig == SIGINFO)
+ /* Dump thread information to file: */
+ _thread_dump_info();
+
+ /* Check if an interval timer signal: */
+ else if (sig == _SCHED_SIGNAL) {
+ /*
+ * This shouldn't ever occur (should this panic?).
+ */
+ } else {
+ /* Check if a child has terminated: */
+ if (sig == SIGCHLD) {
+ /*
+ * Go through the file list and set all files
+ * to non-blocking again in case the child
+ * set some of them to block. Sigh.
+ */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /* Check if this file is used: */
+ if (_thread_fd_table[i] != NULL) {
+ /*
+ * Set the file descriptor to
+ * non-blocking:
+ */
+ _thread_sys_fcntl(i, F_SETFL,
+ _thread_fd_table[i]->flags |
+ O_NONBLOCK);
+ }
+ }
+ /*
+ * Enter a loop to wake up all threads waiting
+ * for a process to complete:
+ */
+ for (pthread = TAILQ_FIRST(&_waitingq);
+ pthread != NULL; pthread = pthread_next) {
+ /*
+ * Grab the next thread before possibly
+ * destroying the link entry:
+ */
+ pthread_next = TAILQ_NEXT(pthread, pqe);
+
+ /*
+ * If this thread is waiting for a child
+ * process to complete, wake it up:
+ */
+ if (pthread->state == PS_WAIT_WAIT) {
+ /* Make the thread runnable: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ }
+ }
+ }
+
+ /*
+ * POSIX says that pending SIGCONT signals are
+ * discarded when one of these signals occurs.
+ */
+ if (sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU) {
+ /*
+ * Enter a loop to discard pending SIGCONT
+ * signals:
+ */
+ TAILQ_FOREACH(pthread, &_thread_list, tle) {
+ sigdelset(&pthread->sigpend,SIGCONT);
+ }
+ }
+
+ /*
+ * Enter a loop to look for threads that have the
+ * signal unmasked. POSIX specifies that a thread
+ * in a sigwait will get the signal over any other
+ * threads. Second preference will be threads in
+ * in a sigsuspend. If none of the above, then the
+ * signal is delivered to the first thread we find.
+ */
+ suspended_thread = NULL;
+ signaled_thread = NULL;
+ for (pthread = TAILQ_FIRST(&_waitingq);
+ pthread != NULL; pthread = pthread_next) {
+ /*
+ * Grab the next thread before possibly destroying
+ * the link entry.
+ */
+ pthread_next = TAILQ_NEXT(pthread, pqe);
+
+ if ((pthread->state == PS_SIGWAIT) &&
+ sigismember(pthread->data.sigwait, sig)) {
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+
+ /*
+ * POSIX doesn't doesn't specify which thread
+ * will get the signal if there are multiple
+ * waiters, so we give it to the first thread
+ * we find.
+ *
+ * Do not attempt to deliver this signal
+ * to other threads.
+ */
+ return (NULL);
+ }
+ else if (!sigismember(&pthread->sigmask, sig)) {
+ if (pthread->state == PS_SIGSUSPEND) {
+ if (suspended_thread == NULL)
+ suspended_thread = pthread;
+ } else if (signaled_thread == NULL)
+ signaled_thread = pthread;
+ }
+ }
+
+ /*
+ * If we didn't find a thread in the waiting queue,
+ * check the all threads queue:
+ */
+ if (suspended_thread == NULL && signaled_thread == NULL) {
+ /*
+ * Enter a loop to look for other threads capable
+ * of receiving the signal:
+ */
+ TAILQ_FOREACH(pthread, &_thread_list, tle) {
+ if (!sigismember(&pthread->sigmask, sig)) {
+ signaled_thread = pthread;
+ break;
+ }
+ }
+ }
+
+ /* Check if the signal is not being ignored: */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) {
+ if (suspended_thread == NULL &&
+ signaled_thread == NULL)
+ /*
+ * Add it to the set of signals pending
+ * on the process:
+ */
+ sigaddset(&_process_sigpending, sig);
+ else {
+ /*
+ * We only deliver the signal to one thread;
+ * give preference to the suspended thread:
+ */
+ if (suspended_thread != NULL)
+ pthread = suspended_thread;
+ else
+ pthread = signaled_thread;
+
+ /*
+ * Perform any state changes due to signal
+ * arrival:
+ */
+ _thread_sig_check_state(pthread, sig);
+ return (pthread);
+ }
+ }
+ }
+
+ /* Returns nothing. */
+ return (NULL);
+}
+
+/* Perform thread specific actions in response to a signal: */
+static void
+_thread_sig_check_state(pthread_t pthread, int sig)
+{
+ /*
+ * Process according to thread state:
+ */
+ switch (pthread->state) {
+ /*
+ * States which do not change when a signal is trapped:
+ */
+ case PS_COND_WAIT:
+ case PS_DEAD:
+ case PS_DEADLOCK:
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ case PS_JOIN:
+ case PS_MUTEX_WAIT:
+ case PS_RUNNING:
+ case PS_STATE_MAX:
+ case PS_SIGTHREAD:
+ case PS_SPINBLOCK:
+ case PS_SUSPENDED:
+ /* Increment the pending signal count. */
+ sigaddset(&pthread->sigpend,sig);
+ break;
+
+ case PS_SIGWAIT:
+ /* Wake up the thread if the signal is blocked. */
+ if (sigismember(pthread->data.sigwait, sig)) {
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ } else
+ /* Increment the pending signal count. */
+ sigaddset(&pthread->sigpend,sig);
+ break;
+
+
+ /*
+ * The wait state is a special case due to the handling of
+ * SIGCHLD signals.
+ */
+ case PS_WAIT_WAIT:
+ /*
+ * Check for signals other than the death of a child
+ * process:
+ */
+ if (sig != SIGCHLD)
+ /* Flag the operation as interrupted: */
+ pthread->interrupted = 1;
+
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ break;
+
+ /*
+ * States that are interrupted by the occurrence of a signal
+ * other than the scheduling alarm:
+ */
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ case PS_POLL_WAIT:
+ case PS_SLEEP_WAIT:
+ case PS_SELECT_WAIT:
+ if ((_thread_sigact[sig - 1].sa_flags & SA_RESTART) == 0) {
+ /* Flag the operation as interrupted: */
+ pthread->interrupted = 1;
+
+ if (pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ PTHREAD_WORKQ_REMOVE(pthread);
+
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ }
+ break;
+
+ case PS_SIGSUSPEND:
+ /*
+ * Only wake up the thread if there is a handler installed
+ * for the signal.
+ */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_DFL) {
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ }
+ break;
+ }
+}
+
+/* Send a signal to a specific thread (ala pthread_kill): */
+void
+_thread_sig_send(pthread_t pthread, int sig)
+{
+ /*
+ * Check that the signal is not being ignored:
+ */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) {
+ if (pthread->state == PS_SIGWAIT &&
+ sigismember(pthread->data.sigwait, sig)) {
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ } else if (pthread->state != PS_SIGWAIT &&
+ !sigismember(&pthread->sigmask, sig)) {
+ /* Perform any state changes due to signal arrival: */
+ _thread_sig_check_state(pthread, sig);
+
+ /* Call the installed signal handler: */
+ _thread_sig_deliver(pthread, sig);
+ }
+ else {
+ /* Increment the pending signal count. */
+ sigaddset(&pthread->sigpend,sig);
+ }
+ }
+}
+
+/* Dispatch pending signals to the running thread: */
+void
+_dispatch_signals()
+{
+ sigset_t sigset, mask;
+ int i;
+
+ /*
+ * Check if there are pending signals for the running
+ * thread or process that aren't blocked:
+ */
+ sigset = _thread_run->sigpend;
+ SIGSETOR(sigset, _process_sigpending);
+ SIGSETNAND(sigset, _thread_run->sigmask);
+ if (SIGNOTEMPTY(sigset)) {
+ /*
+ * Enter a loop to calculate deliverable pending signals
+ * before actually delivering them. The pending signals
+ * must be removed from the pending signal sets before
+ * calling the signal handler because the handler may
+ * call library routines that again check for and deliver
+ * pending signals.
+ */
+ for (i = 1; i < NSIG; i++) {
+ /*
+ * Check that a custom handler is installed
+ * and if the signal is not blocked:
+ */
+ if (_thread_sigact[i - 1].sa_handler != SIG_DFL &&
+ _thread_sigact[i - 1].sa_handler != SIG_IGN &&
+ sigismember(&sigset, i)) {
+ if (sigismember(&_thread_run->sigpend,i))
+ /* Clear the thread pending signal: */
+ sigdelset(&_thread_run->sigpend,i);
+ else
+ /* Clear the process pending signal: */
+ sigdelset(&_process_sigpending,i);
+ }
+ else
+ /* Remove the signal if it can't be handled: */
+ sigdelset(&sigset, i);
+ }
+
+ /* Now deliver the signals: */
+ for (i = 1; i < NSIG; i++) {
+ if (sigismember(&sigset, i))
+ /* Deliver the signal to the running thread: */
+ _thread_sig_deliver(_thread_run, i);
+ }
+ }
+}
+
+/* Deliver a signal to a thread: */
+void
+_thread_sig_deliver(pthread_t pthread, int sig)
+{
+ sigset_t mask;
+ pthread_t pthread_saved;
+
+ /*
+ * Check that a custom handler is installed
+ * and if the signal is not blocked:
+ */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_DFL &&
+ _thread_sigact[sig - 1].sa_handler != SIG_IGN) {
+ /* Save the current thread: */
+ pthread_saved = _thread_run;
+
+ /* Save the threads signal mask: */
+ mask = pthread->sigmask;
+
+ /*
+ * Add the current signal and signal handler
+ * mask to the threads current signal mask:
+ */
+ SIGSETOR(pthread->sigmask, _thread_sigact[sig - 1].sa_mask);
+ sigaddset(&pthread->sigmask, sig);
+
+ /* Current thread inside critical region? */
+ if (_thread_run->sig_defer_count > 0)
+ pthread->sig_defer_count++;
+
+ _thread_run = pthread;
+
+ /*
+ * Dispatch the signal via the custom signal
+ * handler:
+ */
+ (*(_thread_sigact[sig - 1].sa_handler))(sig);
+
+ _thread_run = pthread_saved;
+
+ /* Current thread inside critical region? */
+ if (_thread_run->sig_defer_count > 0)
+ pthread->sig_defer_count--;
+
+ /* Restore the threads signal mask: */
+ pthread->sigmask = mask;
+ }
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_sigaction.c b/lib/libc_r/uthread/uthread_sigaction.c
new file mode 100644
index 0000000..7fa8ebf
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sigaction.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigaction(int sig, const struct sigaction * act, struct sigaction * oact)
+{
+ int ret = 0;
+ struct sigaction gact;
+
+ /* Check if the signal number is out of range: */
+ if (sig < 1 || sig > NSIG) {
+ /* Return an invalid argument: */
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ /*
+ * Check if the existing signal action structure contents are
+ * to be returned:
+ */
+ if (oact != NULL) {
+ /* Return the existing signal action contents: */
+ oact->sa_handler = _thread_sigact[sig - 1].sa_handler;
+ oact->sa_mask = _thread_sigact[sig - 1].sa_mask;
+ oact->sa_flags = _thread_sigact[sig - 1].sa_flags;
+ }
+
+ /* Check if a signal action was supplied: */
+ if (act != NULL) {
+ /* Set the new signal handler: */
+ _thread_sigact[sig - 1].sa_mask = act->sa_mask;
+ _thread_sigact[sig - 1].sa_flags = act->sa_flags;
+ _thread_sigact[sig - 1].sa_handler = act->sa_handler;
+ }
+
+ /*
+ * Check if the kernel needs to be advised of a change
+ * in signal action:
+ */
+ if (act != NULL && sig != _SCHED_SIGNAL && sig != SIGCHLD &&
+ sig != SIGINFO) {
+ /* Initialise the global signal action structure: */
+ gact.sa_mask = act->sa_mask;
+ gact.sa_flags = 0;
+
+ /* Ensure the scheduling signal is masked: */
+ sigaddset(&gact.sa_mask, _SCHED_SIGNAL);
+
+ /*
+ * Check if the signal handler is being set to
+ * the default or ignore handlers:
+ */
+ if (act->sa_handler == SIG_DFL ||
+ act->sa_handler == SIG_IGN)
+ /* Specify the built in handler: */
+ gact.sa_handler = act->sa_handler;
+ else
+ /*
+ * Specify the thread kernel signal
+ * handler:
+ */
+ gact.sa_handler = (void (*) ()) _thread_sig_handler;
+
+ /* Change the signal action in the kernel: */
+ if (_thread_sys_sigaction(sig,&gact,NULL) != 0)
+ ret = -1;
+ }
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_sigblock.c b/lib/libc_r/uthread/uthread_sigblock.c
new file mode 100644
index 0000000..986379b
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sigblock.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+_thread_sys_sigblock(int mask)
+{
+ int omask, n;
+
+ n = _thread_sys_sigprocmask(SIG_BLOCK, (sigset_t *) & mask, (sigset_t *) & omask);
+ if (n)
+ return (n);
+ return (omask);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_sigmask.c b/lib/libc_r/uthread/uthread_sigmask.c
new file mode 100644
index 0000000..b880d9c
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sigmask.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <errno.h>
+#include <signal.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
+{
+ int ret = 0;
+
+ /* Check if the existing signal process mask is to be returned: */
+ if (oset != NULL) {
+ /* Return the current mask: */
+ *oset = _thread_run->sigmask;
+ }
+ /* Check if a new signal set was provided by the caller: */
+ if (set != NULL) {
+ /* Process according to what to do: */
+ switch (how) {
+ /* Block signals: */
+ case SIG_BLOCK:
+ /* Add signals to the existing mask: */
+ SIGSETOR(_thread_run->sigmask, *set);
+ break;
+
+ /* Unblock signals: */
+ case SIG_UNBLOCK:
+ /* Clear signals from the existing mask: */
+ SIGSETNAND(_thread_run->sigmask, *set);
+ break;
+
+ /* Set the signal process mask: */
+ case SIG_SETMASK:
+ /* Set the new mask: */
+ _thread_run->sigmask = *set;
+ break;
+
+ /* Trap invalid actions: */
+ default:
+ /* Return an invalid argument: */
+ errno = EINVAL;
+ ret = -1;
+ break;
+ }
+
+ /*
+ * Dispatch signals to the running thread that are pending
+ * and now unblocked:
+ */
+ _dispatch_signals();
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_signal.c b/lib/libc_r/uthread/uthread_signal.c
new file mode 100644
index 0000000..2b8f46a
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_signal.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+sig_t
+_thread_sys_signal(int s, sig_t a)
+{
+ struct sigaction sa;
+ struct sigaction osa;
+
+ /* Initialise the signal action structure: */
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = a;
+ sa.sa_flags = 0;
+
+ /* Perform the sigaction syscall: */
+ if (_thread_sys_sigaction(s, &sa, &osa) < 0) {
+ /* Return an error: */
+ return (SIG_ERR);
+ }
+ /* Return a pointer to the old signal handler: */
+ return (osa.sa_handler);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_sigpending.c b/lib/libc_r/uthread/uthread_sigpending.c
new file mode 100644
index 0000000..2d61e21
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sigpending.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigpending(sigset_t * set)
+{
+ int ret = 0;
+
+ /* Check for a null signal set pointer: */
+ if (set == NULL) {
+ /* Return an invalid argument: */
+ ret = EINVAL;
+ }
+ else {
+ *set = _thread_run->sigpend;
+ }
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_sigprocmask.c b/lib/libc_r/uthread/uthread_sigprocmask.c
new file mode 100644
index 0000000..592a61e
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sigprocmask.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <signal.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigprocmask(int how, const sigset_t * set, sigset_t * oset)
+{
+ int ret = 0;
+
+ /* Check if the existing signal process mask is to be returned: */
+ if (oset != NULL) {
+ /* Return the current mask: */
+ *oset = _thread_run->sigmask;
+ }
+ /* Check if a new signal set was provided by the caller: */
+ if (set != NULL) {
+ /* Process according to what to do: */
+ switch (how) {
+ /* Block signals: */
+ case SIG_BLOCK:
+ /* Add signals to the existing mask: */
+ SIGSETOR(_thread_run->sigmask, *set);
+ break;
+
+ /* Unblock signals: */
+ case SIG_UNBLOCK:
+ /* Clear signals from the existing mask: */
+ SIGSETNAND(_thread_run->sigmask, *set);
+ break;
+
+ /* Set the signal process mask: */
+ case SIG_SETMASK:
+ /* Set the new mask: */
+ _thread_run->sigmask = *set;
+ break;
+
+ /* Trap invalid actions: */
+ default:
+ /* Return an invalid argument: */
+ errno = EINVAL;
+ ret = -1;
+ break;
+ }
+
+ /*
+ * Dispatch signals to the running thread that are pending
+ * and now unblocked:
+ */
+ _dispatch_signals();
+ }
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_sigsetmask.c b/lib/libc_r/uthread/uthread_sigsetmask.c
new file mode 100644
index 0000000..b02196b
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sigsetmask.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+_thread_sys_sigsetmask(int mask)
+{
+ int omask, n;
+
+ n = _thread_sys_sigprocmask(SIG_SETMASK, (sigset_t *) & mask, (sigset_t *) & omask);
+ if (n)
+ return (n);
+ return (omask);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_sigsuspend.c b/lib/libc_r/uthread/uthread_sigsuspend.c
new file mode 100644
index 0000000..ac06ff7
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sigsuspend.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigsuspend(const sigset_t * set)
+{
+ int ret = -1;
+ sigset_t oset;
+
+ /* Check if a new signal set was provided by the caller: */
+ if (set != NULL) {
+ /* Save the current signal mask: */
+ oset = _thread_run->sigmask;
+
+ /* Change the caller's mask: */
+ _thread_run->sigmask = *set;
+
+ /* Wait for a signal: */
+ _thread_kern_sched_state(PS_SIGSUSPEND, __FILE__, __LINE__);
+
+ /* Always return an interrupted error: */
+ errno = EINTR;
+
+ /* Restore the signal mask: */
+ _thread_run->sigmask = oset;
+ } else {
+ /* Return an invalid argument error: */
+ errno = EINVAL;
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_sigwait.c b/lib/libc_r/uthread/uthread_sigwait.c
new file mode 100644
index 0000000..faa227e
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_sigwait.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <sys/param.h>
+#include <sys/signalvar.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigwait(const sigset_t * set, int *sig)
+{
+ int ret = 0;
+ int i;
+ sigset_t tempset, waitset;
+ struct sigaction act;
+
+ _thread_enter_cancellation_point();
+ /*
+ * Specify the thread kernel signal handler.
+ */
+ act.sa_handler = (void (*) ()) _thread_sig_handler;
+ act.sa_flags = SA_RESTART;
+ act.sa_mask = *set;
+
+ /* Ensure the scheduling signal is masked: */
+ sigaddset(&act.sa_mask, _SCHED_SIGNAL);
+
+ /*
+ * Initialize the set of signals that will be waited on:
+ */
+ waitset = *set;
+
+ /* These signals can't be waited on. */
+ sigdelset(&waitset, SIGKILL);
+ sigdelset(&waitset, SIGSTOP);
+ sigdelset(&waitset, _SCHED_SIGNAL);
+ sigdelset(&waitset, SIGCHLD);
+ sigdelset(&waitset, SIGINFO);
+
+ /* Check to see if a pending signal is in the wait mask. */
+ tempset = _thread_run->sigpend;
+ SIGSETOR(tempset, _process_sigpending);
+ SIGSETAND(tempset, waitset);
+ if (SIGNOTEMPTY(tempset)) {
+ /* Enter a loop to find a pending signal: */
+ for (i = 1; i < NSIG; i++) {
+ if (sigismember (&tempset, i))
+ break;
+ }
+
+ /* Clear the pending signal: */
+ if (sigismember(&_thread_run->sigpend,i))
+ sigdelset(&_thread_run->sigpend,i);
+ else
+ sigdelset(&_process_sigpending,i);
+
+ /* Return the signal number to the caller: */
+ *sig = i;
+
+ _thread_leave_cancellation_point();
+ return (0);
+ }
+
+ /*
+ * Enter a loop to find the signals that are SIG_DFL. For
+ * these signals we must install a dummy signal handler in
+ * order for the kernel to pass them in to us. POSIX says
+ * that the _application_ must explicitly install a dummy
+ * handler for signals that are SIG_IGN in order to sigwait
+ * on them. Note that SIG_IGN signals are left in the
+ * mask because a subsequent sigaction could enable an
+ * ignored signal.
+ */
+ for (i = 1; i < NSIG; i++) {
+ if (sigismember(&waitset, i) &&
+ (_thread_sigact[i - 1].sa_handler == SIG_DFL)) {
+ if (_thread_sys_sigaction(i,&act,NULL) != 0)
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ /*
+ * Save the wait signal mask. The wait signal
+ * mask is independent of the threads signal mask
+ * and requires separate storage.
+ */
+ _thread_run->data.sigwait = &waitset;
+
+ /* Wait for a signal: */
+ _thread_kern_sched_state(PS_SIGWAIT, __FILE__, __LINE__);
+
+ /* Return the signal number to the caller: */
+ *sig = _thread_run->signo;
+
+ /*
+ * Probably unnecessary, but since it's in a union struct
+ * we don't know how it could be used in the future.
+ */
+ _thread_run->data.sigwait = NULL;
+ }
+
+ /* Restore the sigactions: */
+ act.sa_handler = SIG_DFL;
+ for (i = 1; i < NSIG; i++) {
+ if (sigismember(&waitset, i) &&
+ (_thread_sigact[i - 1].sa_handler == SIG_DFL)) {
+ if (_thread_sys_sigaction(i,&act,NULL) != 0)
+ ret = -1;
+ }
+ }
+
+ _thread_leave_cancellation_point();
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_single_np.c b/lib/libc_r/uthread/uthread_single_np.c
new file mode 100644
index 0000000..d6ecb48
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_single_np.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_single_np()
+{
+ /* Enter single-threaded (non-POSIX) scheduling mode: */
+ _thread_single = _thread_run;
+ return(0);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_socket.c b/lib/libc_r/uthread/uthread_socket.c
new file mode 100644
index 0000000..5772bc8
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_socket.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+socket(int af, int type, int protocol)
+{
+ int fd;
+
+ /* Create a socket: */
+ if ((fd = _thread_sys_socket(af, type, protocol)) < 0) {
+ /* Error creating socket. */
+
+ /* Initialise the entry in the file descriptor table: */
+ } else if (_thread_fd_table_init(fd) != 0) {
+ _thread_sys_close(fd);
+ fd = -1;
+ }
+ return (fd);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_socketpair.c b/lib/libc_r/uthread/uthread_socketpair.c
new file mode 100644
index 0000000..8c21801
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_socketpair.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+socketpair(int af, int type, int protocol, int pair[2])
+{
+ int ret;
+ if (!((ret = _thread_sys_socketpair(af, type, protocol, pair)) < 0))
+ if (_thread_fd_table_init(pair[0]) != 0 ||
+ _thread_fd_table_init(pair[1]) != 0) {
+ _thread_sys_close(pair[0]);
+ _thread_sys_close(pair[1]);
+ ret = -1;
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_spec.c b/lib/libc_r/uthread/uthread_spec.c
new file mode 100644
index 0000000..f1e9f5c
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_spec.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Static variables: */
+static struct pthread_key key_table[PTHREAD_KEYS_MAX];
+
+int
+pthread_key_create(pthread_key_t * key, void (*destructor) (void *))
+{
+ for ((*key) = 0; (*key) < PTHREAD_KEYS_MAX; (*key)++) {
+ /* Lock the key table entry: */
+ _SPINLOCK(&key_table[*key].lock);
+
+ if (key_table[(*key)].allocated == 0) {
+ key_table[(*key)].allocated = 1;
+ key_table[(*key)].destructor = destructor;
+
+ /* Unlock the key table entry: */
+ _SPINUNLOCK(&key_table[*key].lock);
+ return (0);
+ }
+
+ /* Unlock the key table entry: */
+ _SPINUNLOCK(&key_table[*key].lock);
+ }
+ return (EAGAIN);
+}
+
+int
+pthread_key_delete(pthread_key_t key)
+{
+ int ret = 0;
+
+ if (key < PTHREAD_KEYS_MAX) {
+ /* Lock the key table entry: */
+ _SPINLOCK(&key_table[key].lock);
+
+ if (key_table[key].allocated)
+ key_table[key].allocated = 0;
+ else
+ ret = EINVAL;
+
+ /* Unlock the key table entry: */
+ _SPINUNLOCK(&key_table[key].lock);
+ } else
+ ret = EINVAL;
+ return (ret);
+}
+
+void
+_thread_cleanupspecific(void)
+{
+ void *data;
+ int key;
+ int itr;
+ void (*destructor)( void *);
+
+ for (itr = 0; itr < PTHREAD_DESTRUCTOR_ITERATIONS; itr++) {
+ for (key = 0; key < PTHREAD_KEYS_MAX; key++) {
+ if (_thread_run->specific_data_count) {
+ /* Lock the key table entry: */
+ _SPINLOCK(&key_table[key].lock);
+ destructor = NULL;
+
+ if (key_table[key].allocated) {
+ if (_thread_run->specific_data[key]) {
+ data = (void *) _thread_run->specific_data[key];
+ _thread_run->specific_data[key] = NULL;
+ _thread_run->specific_data_count--;
+ destructor = key_table[key].destructor;
+ }
+ }
+
+ /* Unlock the key table entry: */
+ _SPINUNLOCK(&key_table[key].lock);
+
+ /*
+ * If there is a destructore, call it
+ * with the key table entry unlocked:
+ */
+ if (destructor)
+ destructor(data);
+ } else {
+ free(_thread_run->specific_data);
+ _thread_run->specific_data = NULL;
+ return;
+ }
+ }
+ }
+ free(_thread_run->specific_data);
+ _thread_run->specific_data = NULL;
+}
+
+static inline const void **
+pthread_key_allocate_data(void)
+{
+ const void **new_data;
+ if ((new_data = (const void **) malloc(sizeof(void *) * PTHREAD_KEYS_MAX)) != NULL) {
+ memset((void *) new_data, 0, sizeof(void *) * PTHREAD_KEYS_MAX);
+ }
+ return (new_data);
+}
+
+int
+pthread_setspecific(pthread_key_t key, const void *value)
+{
+ pthread_t pthread;
+ int ret = 0;
+
+ /* Point to the running thread: */
+ pthread = _thread_run;
+
+ if ((pthread->specific_data) ||
+ (pthread->specific_data = pthread_key_allocate_data())) {
+ if (key < PTHREAD_KEYS_MAX) {
+ if (key_table[key].allocated) {
+ if (pthread->specific_data[key] == NULL) {
+ if (value != NULL)
+ pthread->specific_data_count++;
+ } else {
+ if (value == NULL)
+ pthread->specific_data_count--;
+ }
+ pthread->specific_data[key] = value;
+ ret = 0;
+ } else
+ ret = EINVAL;
+ } else
+ ret = EINVAL;
+ } else
+ ret = ENOMEM;
+ return (ret);
+}
+
+void *
+pthread_getspecific(pthread_key_t key)
+{
+ pthread_t pthread;
+ void *data;
+
+ /* Point to the running thread: */
+ pthread = _thread_run;
+
+ /* Check if there is specific data: */
+ if (pthread->specific_data != NULL && key < PTHREAD_KEYS_MAX) {
+ /* Check if this key has been used before: */
+ if (key_table[key].allocated) {
+ /* Return the value: */
+ data = (void *) pthread->specific_data[key];
+ } else {
+ /*
+ * This key has not been used before, so return NULL
+ * instead:
+ */
+ data = NULL;
+ }
+ } else
+ /* No specific data has been created, so just return NULL: */
+ data = NULL;
+ return (data);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_spinlock.c b/lib/libc_r/uthread/uthread_spinlock.c
new file mode 100644
index 0000000..4e94ffc
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_spinlock.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <sched.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+#include "pthread_private.h"
+
+extern char *__progname;
+
+/*
+ * Lock a location for the running thread. Yield to allow other
+ * threads to run if this thread is blocked because the lock is
+ * not available. Note that this function does not sleep. It
+ * assumes that the lock will be available very soon.
+ */
+void
+_spinlock(spinlock_t *lck)
+{
+ /*
+ * Try to grab the lock and loop if another thread grabs
+ * it before we do.
+ */
+ while(_atomic_lock(&lck->access_lock)) {
+ /* Block the thread until the lock. */
+ _thread_run->data.spinlock = lck;
+ _thread_kern_sched_state(PS_SPINBLOCK, __FILE__, __LINE__);
+ }
+
+ /* The running thread now owns the lock: */
+ lck->lock_owner = (long) _thread_run;
+}
+
+/*
+ * Lock a location for the running thread. Yield to allow other
+ * threads to run if this thread is blocked because the lock is
+ * not available. Note that this function does not sleep. It
+ * assumes that the lock will be available very soon.
+ *
+ * This function checks if the running thread has already locked the
+ * location, warns if this occurs and creates a thread dump before
+ * returning.
+ */
+void
+_spinlock_debug(spinlock_t *lck, char *fname, int lineno)
+{
+ int cnt = 0;
+
+ /*
+ * Try to grab the lock and loop if another thread grabs
+ * it before we do.
+ */
+ while(_atomic_lock(&lck->access_lock)) {
+ cnt++;
+ if (cnt > 100) {
+ char str[256];
+ snprintf(str, sizeof(str), "%s - Warning: Thread %p attempted to lock %p from %s (%d) was left locked from %s (%d)\n", __progname, _thread_run, lck, fname, lineno, lck->fname, lck->lineno);
+ _thread_sys_write(2,str,strlen(str));
+ sleep(1);
+ cnt = 0;
+ }
+
+ /* Block the thread until the lock. */
+ _thread_run->data.spinlock = lck;
+ _thread_kern_sched_state(PS_SPINBLOCK, fname, lineno);
+ }
+
+ /* The running thread now owns the lock: */
+ lck->lock_owner = (long) _thread_run;
+ lck->fname = fname;
+ lck->lineno = lineno;
+}
diff --git a/lib/libc_r/uthread/uthread_suspend_np.c b/lib/libc_r/uthread/uthread_suspend_np.c
new file mode 100644
index 0000000..ea9b1f8
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_suspend_np.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Suspend a thread: */
+int
+pthread_suspend_np(pthread_t thread)
+{
+ int ret;
+
+ /* Find the thread in the list of active threads: */
+ if ((ret = _find_thread(thread)) == 0) {
+ /* The thread exists. Is it running? */
+ if (thread->state != PS_RUNNING &&
+ thread->state != PS_SUSPENDED) {
+ /* The thread operation has been interrupted */
+ _thread_seterrno(thread,EINTR);
+ thread->interrupted = 1;
+ }
+
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Suspend the thread. */
+ PTHREAD_NEW_STATE(thread,PS_SUSPENDED);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_switch_np.c b/lib/libc_r/uthread/uthread_switch_np.c
new file mode 100644
index 0000000..9b83545
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_switch_np.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include <pthread_np.h>
+#include "pthread_private.h"
+
+
+int
+pthread_switch_add_np(pthread_switch_routine_t routine)
+{
+ int ret = 0;
+
+ if (routine == NULL)
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ else
+ /* Shouldn't need a lock to protect this assigment. */
+ _sched_switch_hook = routine;
+
+ return(ret);
+}
+
+int
+pthread_switch_delete_np(pthread_switch_routine_t routine)
+{
+ int ret = 0;
+
+ if (routine != _sched_switch_hook)
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ else
+ /* Shouldn't need a lock to protect this assigment. */
+ _sched_switch_hook = NULL;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_vfork.c b/lib/libc_r/uthread/uthread_vfork.c
new file mode 100644
index 0000000..bbfcf00
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_vfork.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+
+int
+vfork(void)
+{
+ return (fork());
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_wait4.c b/lib/libc_r/uthread/uthread_wait4.c
new file mode 100644
index 0000000..4a58a70
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_wait4.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <sys/wait.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+pid_t
+wait4(pid_t pid, int *istat, int options, struct rusage * rusage)
+{
+ pid_t ret;
+
+ _thread_enter_cancellation_point();
+ _thread_kern_sig_defer();
+
+ /* Perform a non-blocking wait4 syscall: */
+ while ((ret = _thread_sys_wait4(pid, istat, options | WNOHANG, rusage)) == 0 && (options & WNOHANG) == 0) {
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ /* Schedule the next thread while this one waits: */
+ _thread_kern_sched_state(PS_WAIT_WAIT, __FILE__, __LINE__);
+
+ /* Check if this call was interrupted by a signal: */
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ }
+
+ _thread_kern_sig_undefer();
+ _thread_leave_cancellation_point();
+
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_write.c b/lib/libc_r/uthread/uthread_write.c
new file mode 100644
index 0000000..40c4cc5
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_write.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+write(int fd, const void *buf, size_t nbytes)
+{
+ int blocking;
+ int type;
+ ssize_t n;
+ ssize_t num = 0;
+ ssize_t ret;
+
+ _thread_enter_cancellation_point();
+ /* POSIX says to do just this: */
+ if (nbytes == 0) {
+ _thread_leave_cancellation_point();
+ return (0);
+ }
+
+ /* Lock the file descriptor for write: */
+ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ /* Get the read/write mode type: */
+ type = _thread_fd_table[fd]->flags & O_ACCMODE;
+
+ /* Check if the file is not open for write: */
+ if (type != O_WRONLY && type != O_RDWR) {
+ /* File is not open for write: */
+ errno = EBADF;
+ _FD_UNLOCK(fd, FD_WRITE);
+ _thread_leave_cancellation_point();
+ return (-1);
+ }
+
+ /* Check if file operations are to block */
+ blocking = ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0);
+
+ /*
+ * Loop while no error occurs and until the expected number
+ * of bytes are written if performing a blocking write:
+ */
+ while (ret == 0) {
+ /* Perform a non-blocking write syscall: */
+ n = _thread_sys_write(fd, buf + num, nbytes - num);
+
+ /* Check if one or more bytes were written: */
+ if (n > 0)
+ /*
+ * Keep a count of the number of bytes
+ * written:
+ */
+ num += n;
+
+ /*
+ * If performing a blocking write, check if the
+ * write would have blocked or if some bytes
+ * were written but there are still more to
+ * write:
+ */
+ if (blocking && ((n < 0 && (errno == EWOULDBLOCK ||
+ errno == EAGAIN)) || (n >= 0 && num < nbytes))) {
+ _thread_run->data.fd.fd = fd;
+ _thread_kern_set_timeout(NULL);
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDW_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
+ /* Return an error: */
+ ret = -1;
+ }
+
+ /*
+ * If performing a non-blocking write or if an
+ * error occurred, just return whatever the write
+ * syscall did:
+ */
+ } else if (!blocking || n < 0) {
+ /* A non-blocking call might return zero: */
+ ret = n;
+ break;
+
+ /* Check if the write has completed: */
+ } else if (num >= nbytes)
+ /* Return the number of bytes written: */
+ ret = num;
+ }
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_writev.c b/lib/libc_r/uthread/uthread_writev.c
new file mode 100644
index 0000000..375f599
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_writev.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+writev(int fd, const struct iovec * iov, int iovcnt)
+{
+ int blocking;
+ int idx = 0;
+ int type;
+ ssize_t cnt;
+ ssize_t n;
+ ssize_t num = 0;
+ ssize_t ret;
+ struct iovec liov[20];
+ struct iovec *p_iov = liov;
+
+ /* Check if the array size exceeds to compiled in size: */
+ if (iovcnt > (sizeof(liov) / sizeof(struct iovec))) {
+ /* Allocate memory for the local array: */
+ if ((p_iov = (struct iovec *)
+ malloc(iovcnt * sizeof(struct iovec))) == NULL) {
+ /* Insufficient memory: */
+ errno = ENOMEM;
+ return (-1);
+ }
+ }
+
+ /* Copy the caller's array so that it can be modified locally: */
+ memcpy(p_iov,iov,iovcnt * sizeof(struct iovec));
+
+ /* Lock the file descriptor for write: */
+ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ /* Get the read/write mode type: */
+ type = _thread_fd_table[fd]->flags & O_ACCMODE;
+
+ /* Check if the file is not open for write: */
+ if (type != O_WRONLY && type != O_RDWR) {
+ /* File is not open for write: */
+ errno = EBADF;
+ _FD_UNLOCK(fd, FD_WRITE);
+ return (-1);
+ }
+
+ /* Check if file operations are to block */
+ blocking = ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0);
+
+ /*
+ * Loop while no error occurs and until the expected number
+ * of bytes are written if performing a blocking write:
+ */
+ while (ret == 0) {
+ /* Perform a non-blocking write syscall: */
+ n = _thread_sys_writev(fd, &p_iov[idx], iovcnt - idx);
+
+ /* Check if one or more bytes were written: */
+ if (n > 0) {
+ /*
+ * Keep a count of the number of bytes
+ * written:
+ */
+ num += n;
+
+ /*
+ * Enter a loop to check if a short write
+ * occurred and move the index to the
+ * array entry where the short write
+ * ended:
+ */
+ cnt = n;
+ while (cnt > 0 && idx < iovcnt) {
+ /*
+ * If the residual count exceeds
+ * the size of this vector, then
+ * it was completely written:
+ */
+ if (cnt >= p_iov[idx].iov_len)
+ /*
+ * Decrement the residual
+ * count and increment the
+ * index to the next array
+ * entry:
+ */
+ cnt -= p_iov[idx++].iov_len;
+ else {
+ /*
+ * This entry was only
+ * partially written, so
+ * adjust it's length
+ * and base pointer ready
+ * for the next write:
+ */
+ p_iov[idx].iov_len -= cnt;
+ p_iov[idx].iov_base += cnt;
+ cnt = 0;
+ }
+ }
+ } else if (n == 0) {
+ /*
+ * Avoid an infinite loop if the last iov_len is
+ * 0.
+ */
+ while (idx < iovcnt && p_iov[idx].iov_len == 0)
+ idx++;
+
+ if (idx == iovcnt) {
+ ret = num;
+ break;
+ }
+ }
+
+ /*
+ * If performing a blocking write, check if the
+ * write would have blocked or if some bytes
+ * were written but there are still more to
+ * write:
+ */
+ if (blocking && ((n < 0 && (errno == EWOULDBLOCK ||
+ errno == EAGAIN)) || (n >= 0 && idx < iovcnt))) {
+ _thread_run->data.fd.fd = fd;
+ _thread_kern_set_timeout(NULL);
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDW_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
+ /* Return an error: */
+ ret = -1;
+ }
+
+ /*
+ * If performing a non-blocking write or if an
+ * error occurred, just return whatever the write
+ * syscall did:
+ */
+ } else if (!blocking || n < 0) {
+ /* A non-blocking call might return zero: */
+ ret = n;
+ break;
+
+ /* Check if the write has completed: */
+ } else if (idx == iovcnt)
+ /* Return the number of bytes written: */
+ ret = num;
+ }
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+
+ /* If memory was allocated for the array, free it: */
+ if (p_iov != liov)
+ free(p_iov);
+
+ return (ret);
+}
+#endif
diff --git a/lib/libc_r/uthread/uthread_yield.c b/lib/libc_r/uthread/uthread_yield.c
new file mode 100644
index 0000000..064dd82
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_yield.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sched_yield(void)
+{
+ /* Reset the accumulated time slice value for the current thread: */
+ _thread_run->slice_usec = -1;
+
+ /* Schedule the next thread: */
+ _thread_kern_sched(NULL);
+
+ /* Always return no error. */
+ return(0);
+}
+
+/* Draft 4 yield */
+void
+pthread_yield(void)
+{
+ /* Reset the accumulated time slice value for the current thread: */
+ _thread_run->slice_usec = -1;
+
+ /* Schedule the next thread: */
+ _thread_kern_sched(NULL);
+
+ /* Nothing to return. */
+ return;
+}
+#endif
diff --git a/lib/libcalendar/Makefile b/lib/libcalendar/Makefile
new file mode 100644
index 0000000..4ecd11a
--- /dev/null
+++ b/lib/libcalendar/Makefile
@@ -0,0 +1,20 @@
+# $FreeBSD$
+
+LIB= calendar
+
+SRCS= calendar.c easter.c
+
+MAN3= calendar.3
+
+MLINKS= calendar.3 easterg.3 calendar.3 easterog.3 calendar.3 easteroj.3 \
+ calendar.3 gdate.3 calendar.3 jdate.3 \
+ calendar.3 ndaysg.3 calendar.3 ndaysj.3 \
+ calendar.3 week.3 calendar.3 weekday.3
+
+CFLAGS+=-I. -I${.CURDIR} -Wall
+
+beforeinstall:
+ ${INSTALL} -C -m 444 -o $(BINOWN) -g $(BINGRP) ${.CURDIR}/calendar.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libcalendar/calendar.3 b/lib/libcalendar/calendar.3
new file mode 100644
index 0000000..ba889bf
--- /dev/null
+++ b/lib/libcalendar/calendar.3
@@ -0,0 +1,197 @@
+.\" Copyright (c) 1997 Wolfgang Helbig
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd November 29, 1997
+.Dt CALENDAR 3
+.Os
+.Sh NAME
+.Nm easterg ,
+.Nm easterog ,
+.Nm easteroj ,
+.Nm gdate ,
+.Nm jdate ,
+.Nm ndaysg ,
+.Nm ndaysj ,
+.Nm week ,
+.Nm weekday
+.Nd Calendar arithmetic for the Christian era.
+.Sh SYNOPSIS
+.Fd #include <calendar.h>
+.Ft struct date *
+.Fn easterg "int year" "struct date *dt"
+.Ft struct date *
+.Fn easterog "int year" "struct date *dt"
+.Ft struct date *
+.Fn easteroj "int year" "struct date *dt"
+.Ft struct date *
+.Fn gdate "int nd" "struct date *dt"
+.Ft struct date *
+.Fn jdate "int nd" "struct date *dt"
+.Ft int
+.Fn ndaysg "struct date *dt"
+.Ft int
+.Fn ndaysj "struct date *dt"
+.Ft int
+.Fn week "int nd" "int *year"
+.Ft int
+.Fn weekday "int nd"
+.Sh DESCRIPTION
+These functions provide calendar arithmetic for a large range of years,
+starting at March 1st, year zero (i. e. 1 B.C.) and ending way beyond
+year 100000.
+.Pp
+Programs should be linked with
+.Fl lcalendar .
+.Pp
+The functions
+.Fn easterg ,
+.Fn easterog
+and
+.Fn easteroj
+store the date of Easter Sunday into the structure pointed at by
+.Fa dt
+and return a pointer to this structure.
+The function
+.Fn easterg
+assumes Gregorian Calendar (adopted by most western churches after 1582) and
+the functions
+.Fn easterog
+and
+.Fn easteroj
+compute the date of Easter Sunday according to the orthodox rules
+(Western churches before 1582, Greek and Russian Orthodox Church
+until today).
+The result returned by
+.Fn easterog
+is the date in Gregorian Calendar, whereas
+.Fn easteroj
+returns the date in Julian Calendar.
+.Pp
+The functions
+.Fn gdate ,
+.Fn jdate ,
+.Fn ndaysg
+and
+.Fn ndaysj
+provide conversions between the common "year, month, day" notation
+of a date and the "number of days" representation, which is better suited
+for calculations. The days are numbered from March 1st year 1 B.C., starting
+with zero, so the number of a day gives the number of days since March 1st,
+year 1 B.C. The conversions work for nonnegative day numbers only.
+.Pp
+The
+.Fn gdate
+and
+.Fn jdate
+functions
+store the date corresponding to the day number
+.Fa nd
+into the structure pointed at by
+.Fa dt
+and return a pointer to this structure.
+.Pp
+The
+.Fn ndaysg
+and
+.Fn ndaysj
+functions
+return the day number of the date pointed at by
+.Fa dt .
+.Pp
+The
+.Fn gdate
+and
+.Fn ndaysg
+functions
+assume Gregorian Calendar after October 4, 1582 and Julian Calendar before,
+whereas
+.Fn jdate
+and
+.Fn ndaysj
+assume Julian Calendar throughout.
+.Pp
+The two calendars differ by the definition of the leap year. The
+Julian Calendar says every year that is a multiple of four is a
+leap year. The Gregorian Calendar excludes years that are multiples of
+100 and not multiples of 400.
+This means the years 1700, 1800, 1900, 2100 are not leap years
+and the year 2000 is
+a leap year.
+The new rules were inaugurated on October 4, 1582 by deleting ten
+days following this date. Most catholic countries adopted the new
+calendar by the end of the 16th century, whereas others stayed with
+the Julian Calendar until the 20th century. The United Kingdom and
+their colonies switched on September 2, 1752. They already had to
+delete 11 days.
+.Pp
+The function
+.Fn week
+returns the number of the week which contains the day numbered
+.Fa nd .
+The argument
+.Fa *year
+is set with the year that contains (the greater part of) the week.
+The weeks are numbered per year starting with week 1, which is the
+first week in a year that includes more than three days of the year.
+Weeks start on Monday.
+This function is defined for Gregorian Calendar only.
+.Pp
+The function
+.Fn weekday
+returns the weekday (Mo = 0 .. Su = 6) of the day numbered
+.Fa nd .
+.Pp
+The structure
+.Fa date
+is defined in
+.Aq Pa calendar.h .
+It contains these fields:
+.Bd -literal -offset indent
+int y; /\(** year (0000 - ????) \(**/
+int m; /\(** month (1 - 12) \(**/
+int d; /\(** day of month (1 - 31) \(**/
+.Ed
+.Pp
+The year zero is written as "1 B.C." by historians and "0" by astronomers
+and in this library.
+.Sh SEE ALSO
+.Xr ncal 1 ,
+.Xr strftime 3
+.Rs
+.%A A. B. Author
+.%D November 1997
+.Sh STANDARDS
+The week number conforms to ISO 8601: 1988.
+.Sh HISTORY
+The
+.Nm calendar
+library first appeared in
+.Fx 3.0 .
+.Sh AUTHORS
+This manual page and the library was written by
+.An Wolfgang Helbig Aq helbig@FreeBSD.org .
+.Sh BUGS
+The library was coded with great care so there are no bugs left.
diff --git a/lib/libcalendar/calendar.c b/lib/libcalendar/calendar.c
new file mode 100644
index 0000000..3f5ca07
--- /dev/null
+++ b/lib/libcalendar/calendar.c
@@ -0,0 +1,329 @@
+/*-
+ * Copyright (c) 1997 Wolfgang Helbig
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "calendar.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ * For each month tabulate the number of days elapsed in a year before the
+ * month. This assumes the internal date representation, where a year
+ * starts on March 1st. So we don't need a special table for leap years.
+ * But we do need a special table for the year 1582, since 10 days are
+ * deleted in October. This is month1s for the switch from Julian to
+ * Gregorian calendar.
+ */
+static int const month1[] =
+ {0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337};
+ /* M A M J J A S O N D J */
+static int const month1s[]=
+ {0, 31, 61, 92, 122, 153, 184, 214, 235, 265, 296, 327};
+
+typedef struct date date;
+
+/* The last day of Julian calendar, in internal and ndays representation */
+static int nswitch; /* The last day of Julian calendar */
+static date jiswitch = {1582, 7, 3};
+
+static date *date2idt(date *idt, date *dt);
+static date *idt2date(date *dt, date *idt);
+static int ndaysji(date *idt);
+static int ndaysgi(date *idt);
+static int firstweek(int year);
+
+/*
+ * Compute the Julian date from the number of days elapsed since
+ * March 1st of year zero.
+ */
+date *
+jdate(int ndays, date *dt)
+{
+ date idt; /* Internal date representation */
+ int r; /* hold the rest of days */
+
+ /*
+ * Compute the year by starting with an approximation not smaller
+ * than the answer and using linear search for the greatest
+ * year which does not begin after ndays.
+ */
+ idt.y = ndays / 365;
+ idt.m = 0;
+ idt.d = 0;
+ while ((r = ndaysji(&idt)) > ndays)
+ idt.y--;
+
+ /*
+ * Set r to the days left in the year and compute the month by
+ * linear search as the largest month that does not begin after r
+ * days.
+ */
+ r = ndays - r;
+ for (idt.m = 11; month1[idt.m] > r; idt.m--)
+ ;
+
+ /* Compute the days left in the month */
+ idt.d = r - month1[idt.m];
+
+ /* return external representation of the date */
+ return (idt2date(dt, &idt));
+}
+
+/*
+ * Return the number of days since March 1st of the year zero.
+ * The date is given according to Julian calendar.
+ */
+int
+ndaysj(date *dt)
+{
+ date idt; /* Internal date representation */
+
+ if (date2idt(&idt, dt) == NULL)
+ return (-1);
+ else
+ return (ndaysji(&idt));
+}
+
+/*
+ * Same as above, where the Julian date is given in internal notation.
+ * This formula shows the beauty of this notation.
+ */
+static int
+ndaysji(date * idt)
+{
+
+ return (idt->d + month1[idt->m] + idt->y * 365 + idt->y / 4);
+}
+
+/*
+ * Compute the date according to the Gregorian calendar from the number of
+ * days since March 1st, year zero. The date computed will be Julian if it
+ * is older than 1582-10-05. This is the reverse of the function ndaysg().
+ */
+date *
+gdate(int ndays, date *dt)
+{
+ int const *montht; /* month-table */
+ date idt; /* for internal date representation */
+ int r; /* holds the rest of days */
+
+ /*
+ * Compute the year by starting with an approximation not smaller
+ * than the answer and search linearly for the greatest year not
+ * starting after ndays.
+ */
+ idt.y = ndays / 365;
+ idt.m = 0;
+ idt.d = 0;
+ while ((r = ndaysgi(&idt)) > ndays)
+ idt.y--;
+
+ /*
+ * Set ndays to the number of days left and compute by linear
+ * search the greatest month which does not start after ndays. We
+ * use the table month1 which provides for each month the number
+ * of days that elapsed in the year before that month. Here the
+ * year 1582 is special, as 10 days are left out in October to
+ * resynchronize the calendar with the earth's orbit. October 4th
+ * 1582 is followed by October 15th 1582. We use the "switch"
+ * table month1s for this year.
+ */
+ ndays = ndays - r;
+ if (idt.y == 1582)
+ montht = month1s;
+ else
+ montht = month1;
+
+ for (idt.m = 11; montht[idt.m] > ndays; idt.m--)
+ ;
+
+ idt.d = ndays - montht[idt.m]; /* the rest is the day in month */
+
+ /* Advance ten days deleted from October if after switch in Oct 1582 */
+ if (idt.y == jiswitch.y && idt.m == jiswitch.m && jiswitch.d < idt.d)
+ idt.d += 10;
+
+ /* return external representation of found date */
+ return (idt2date(dt, &idt));
+}
+
+/*
+ * Return the number of days since March 1st of the year zero. The date is
+ * assumed Gregorian if younger than 1582-10-04 and Julian otherwise. This
+ * is the reverse of gdate.
+ */
+int
+ndaysg(date *dt)
+{
+ date idt; /* Internal date representation */
+
+ if (date2idt(&idt, dt) == NULL)
+ return (-1);
+ return (ndaysgi(&idt));
+}
+
+/*
+ * Same as above, but with the Gregorian date given in internal
+ * representation.
+ */
+static int
+ndaysgi(date *idt)
+{
+ int nd; /* Number of days--return value */
+
+ /* Cache nswitch if not already done */
+ if (nswitch == 0)
+ nswitch = ndaysji(&jiswitch);
+
+ /*
+ * Assume Julian calendar and adapt to Gregorian if necessary, i. e.
+ * younger than nswitch. Gregori deleted
+ * the ten days from Oct 5th to Oct 14th 1582.
+ * Thereafter years which are multiples of 100 and not multiples
+ * of 400 were not leap years anymore.
+ * This makes the average length of a year
+ * 365d +.25d - .01d + .0025d = 365.2425d. But the tropical
+ * year measures 365.2422d. So in 10000/3 years we are
+ * again one day ahead of the earth. Sigh :-)
+ * (d is the average length of a day and tropical year is the
+ * time from one spring point to the next.)
+ */
+ if ((nd = ndaysji(idt)) == -1)
+ return (-1);
+ if (idt->y >= 1600)
+ nd = (nd - 10 - (idt->y - 1600) / 100 + (idt->y - 1600) / 400);
+ else if (nd > nswitch)
+ nd -= 10;
+ return (nd);
+}
+
+/*
+ * Compute the week number from the number of days since March 1st year 0.
+ * The weeks are numbered per year starting with 1. If the first
+ * week of a year includes at least four days of that year it is week 1,
+ * otherwise it gets the number of the last week of the previous year.
+ * The variable y will be filled with the year that contains the greater
+ * part of the week.
+ */
+int
+week(int nd, int *y)
+{
+ date dt;
+ int fw; /* 1st day of week 1 of previous, this and
+ * next year */
+ gdate(nd, &dt);
+ for (*y = dt.y + 1; nd < (fw = firstweek(*y)); (*y)--)
+ ;
+ return ((nd - fw) / 7 + 1);
+}
+
+/* return the first day of week 1 of year y */
+static int
+firstweek(int y)
+{
+ date idt;
+ int nd, wd;
+
+ idt.y = y - 1; /* internal representation of y-1-1 */
+ idt.m = 10;
+ idt.d = 0;
+
+ nd = ndaysgi(&idt);
+ /*
+ * If more than 3 days of this week are in the preceding year, the
+ * next week is week 1 (and the next monday is the answer),
+ * otherwise this week is week 1 and the last monday is the
+ * answer.
+ */
+ if ((wd = weekday(nd)) > 3)
+ return (nd - wd + 7);
+ else
+ return (nd - wd);
+}
+
+/* return the weekday (Mo = 0 .. Su = 6) */
+int
+weekday(int nd)
+{
+ date dmondaygi = {1997, 8, 16}; /* Internal repr. of 1997-11-17 */
+ static int nmonday; /* ... which is a monday */
+
+ /* Cache the daynumber of one monday */
+ if (nmonday == 0)
+ nmonday = ndaysgi(&dmondaygi);
+
+ /* return (nd - nmonday) modulo 7 which is the weekday */
+ nd = (nd - nmonday) % 7;
+ if (nd < 0)
+ return (nd + 7);
+ else
+ return (nd);
+}
+
+/*
+ * Convert a date to internal date representation: The year starts on
+ * March 1st, month and day numbering start at zero. E. g. March 1st of
+ * year zero is written as y=0, m=0, d=0.
+ */
+static date *
+date2idt(date *idt, date *dt)
+{
+
+ idt->d = dt->d - 1;
+ if (dt->m > 2) {
+ idt->m = dt->m - 3;
+ idt->y = dt->y;
+ } else {
+ idt->m = dt->m + 9;
+ idt->y = dt->y - 1;
+ }
+ if (idt->m < 0 || idt->m > 11 || idt->y < 0)
+ return (NULL);
+ else
+ return idt;
+}
+
+/* Reverse of date2idt */
+static date *
+idt2date(date *dt, date *idt)
+{
+
+ dt->d = idt->d + 1;
+ if (idt->m < 10) {
+ dt->m = idt->m + 3;
+ dt->y = idt->y;
+ } else {
+ dt->m = idt->m - 9;
+ dt->y = idt->y + 1;
+ }
+ if (dt->m < 1)
+ return (NULL);
+ else
+ return (dt);
+}
diff --git a/lib/libcalendar/calendar.h b/lib/libcalendar/calendar.h
new file mode 100644
index 0000000..2c42d6c
--- /dev/null
+++ b/lib/libcalendar/calendar.h
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 1997 Wolfgang Helbig
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+struct date {
+ int y; /* year */
+ int m; /* month */
+ int d; /* day */
+};
+
+struct date *easterg(int _year, struct date *_dt);
+struct date *easterog(int _year, struct date *_dt);
+struct date *easteroj(int _year, struct date *_dt);
+struct date *gdate(int _nd, struct date *_dt);
+struct date *jdate(int _nd, struct date *_dt);
+int ndaysg(struct date *_dt);
+int ndaysj(struct date *_dt);
+int week(int _nd, int *_year);
+int weekday(int _nd);
diff --git a/lib/libcalendar/easter.c b/lib/libcalendar/easter.c
new file mode 100644
index 0000000..333665b
--- /dev/null
+++ b/lib/libcalendar/easter.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 1997 Wolfgang Helbig
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "calendar.h"
+
+typedef struct date date;
+
+static int easterodn(int y);
+
+/* Compute Easter Sunday in Gregorian Calendar */
+date *
+easterg(int y, date *dt)
+{
+ int c, i, j, k, l, n;
+
+ n = y % 19;
+ c = y / 100;
+ k = (c - 17) / 25;
+ i = (c - c/4 -(c-k)/3 + 19 * n + 15) % 30;
+ i = i -(i/28) * (1 - (i/28) * (29/(i + 1)) * ((21 - n)/11));
+ j = (y + y/4 + i + 2 - c + c/4) % 7;
+ l = i - j;
+ dt->m = 3 + (l + 40) / 44;
+ dt->d = l + 28 - 31*(dt->m / 4);
+ dt->y = y;
+ return (dt);
+}
+
+/* Compute the Gregorian date of Easter Sunday in Julian Calendar */
+date *
+easterog(int y, date *dt)
+{
+
+ return (gdate(easterodn(y), dt));
+}
+
+/* Compute the Julian date of Easter Sunday in Julian Calendar */
+date *
+easteroj(int y, date * dt)
+{
+
+ return (jdate(easterodn(y), dt));
+}
+
+/* Compute the day number of Easter Sunday in Julian Calendar */
+static int
+easterodn(int y)
+{
+ /*
+ * Table for the easter limits in one metonic (19-year) cycle. 21
+ * to 31 is in March, 1 through 18 in April. Easter is the first
+ * sunday after the easter limit.
+ */
+ int mc[] = {5, 25, 13, 2, 22, 10, 30, 18, 7, 27, 15, 4,
+ 24, 12, 1, 21, 9, 29, 17};
+
+ /* Offset from a weekday to next sunday */
+ int ns[] = {6, 5, 4, 3, 2, 1, 7};
+ date dt;
+ int dn;
+
+ /* Assign the easter limit of y to dt */
+ dt.d = mc[y % 19];
+
+ if (dt.d < 21)
+ dt.m = 4;
+ else
+ dt.m = 3;
+
+ dt.y = y;
+
+ /* Return the next sunday after the easter limit */
+ dn = ndaysj(&dt);
+ return (dn + ns[weekday(dn)]);
+}
diff --git a/lib/libcam/Makefile b/lib/libcam/Makefile
new file mode 100644
index 0000000..6f47001
--- /dev/null
+++ b/lib/libcam/Makefile
@@ -0,0 +1,40 @@
+MAINTAINER=ken@FreeBSD.ORG
+
+LIB= cam
+SRCS= camlib.c scsi_cmdparse.c scsi_all.c scsi_sa.c cam.c
+
+MAN3= cam.3 cam_cdbparse.3
+
+
+MLINKS+=cam.3 cam_open_device.3 \
+ cam.3 cam_open_spec_device.3 \
+ cam.3 cam_open_btl.3 \
+ cam.3 cam_open_pass.3 \
+ cam.3 cam_close_device.3 \
+ cam.3 cam_close_spec_device.3 \
+ cam.3 cam_getccb.3 \
+ cam.3 cam_send_ccb.3 \
+ cam.3 cam_freeccb.3 \
+ cam.3 cam_path_string.3 \
+ cam.3 cam_device_dup.3 \
+ cam.3 cam_device_copy.3 \
+ cam.3 cam_get_device.3 \
+ cam_cdbparse.3 csio_build.3 \
+ cam_cdbparse.3 csio_build_visit.3 \
+ cam_cdbparse.3 csio_decode.3 \
+ cam_cdbparse.3 csio_decode_visit.3 \
+ cam_cdbparse.3 buff_decode.3 \
+ cam_cdbparse.3 buff_decode_visit.3 \
+ cam_cdbparse.3 csio_encode.3 \
+ cam_cdbparse.3 csio_encode_visit.3 \
+ cam_cdbparse.3 buff_encode_visit.3
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/camlib.h \
+ ${DESTDIR}/usr/include
+
+.PATH: ${.CURDIR}/../../sys/cam/scsi ${.CURDIR}/../../sys/cam
+
+CFLAGS+=-I${.CURDIR} -I${.CURDIR}/../../sys
+
+.include <bsd.lib.mk>
diff --git a/lib/libcam/cam.3 b/lib/libcam/cam.3
new file mode 100644
index 0000000..8cd898c
--- /dev/null
+++ b/lib/libcam/cam.3
@@ -0,0 +1,416 @@
+.\"
+.\" Copyright (c) 1998 Kenneth D. Merry.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd October 10, 1998
+.Os FreeBSD 3.0
+.Dt CAM 3
+.Sh NAME
+.Nm cam_open_device ,
+.Nm cam_open_spec_device ,
+.Nm cam_open_btl ,
+.Nm cam_open_pass ,
+.Nm cam_close_device ,
+.Nm cam_close_spec_device ,
+.Nm cam_getccb ,
+.Nm cam_send_ccb ,
+.Nm cam_freeccb ,
+.Nm cam_path_string ,
+.Nm cam_device_dup ,
+.Nm cam_device_copy ,
+.Nm cam_get_device
+.Nd CAM user library
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Fd #include <camlib.h>
+.Ft struct cam_device *
+.Fo cam_open_device
+.Fa "const char *path"
+.Fa "int flags"
+.Fc
+.Ft struct cam_device *
+.Fo cam_open_spec_device
+.Fa "const char *dev_name"
+.Fa "int unit"
+.Fa "int flags"
+.Fa "struct cam_device *device"
+.Fc
+.Ft struct cam_device *
+.Fo cam_open_btl
+.Fa "path_id_t path_id"
+.Fa "target_id_t target_id"
+.Fa "lun_id_t target_lun"
+.Fa "int flags"
+.Fa "struct cam_device *device"
+.Fc
+.Ft struct cam_device *
+.Fo cam_open_pass
+.Fa "const char *path"
+.Fa "int flags"
+.Fa "struct cam_device *device"
+.Fc
+.Ft void
+.Fo cam_close_device
+.Fa "struct cam_device *dev"
+.Fc
+.Ft void
+.Fo cam_close_spec_device
+.Fa "struct cam_device *dev"
+.Fc
+.Ft union ccb *
+.Fo cam_getccb
+.Fa "struct cam_device *dev"
+.Fc
+.Ft int
+.Fo cam_send_ccb
+.Fa "struct cam_device *device"
+.Fa "union ccb *ccb"
+.Fc
+.Ft void
+.Fo cam_freeccb
+.Fa "union ccb *ccb"
+.Fc
+.Ft char *
+.Fo cam_path_string
+.Fa "struct cam_device *dev"
+.Fa "char *str"
+.Fa "int len"
+.Fc
+.Ft struct cam_device *
+.Fo cam_device_dup
+.Fa "struct cam_device *device"
+.Fc
+.Ft void
+.Fo cam_device_copy
+.Fa "struct cam_device *src"
+.Fa "struct cam_device *dst"
+.Fc
+.Ft int
+.Fo cam_get_device
+.Fa "const char *path"
+.Fa "char *dev_name"
+.Fa "int devnamelen"
+.Fa "int *unit"
+.Fc
+.Sh DESCRIPTION
+The CAM library consists of a number of functions designed to aid in
+programming with the CAM subsystem. This man page covers the basic set of
+library functions. More functions are documented in the man pages listed
+below.
+.Pp
+Many of the CAM library functions use the
+.Va cam_device
+structure:
+.Bd -literal
+struct cam_device {
+ char device_path[MAXPATHLEN+1];/*
+ * Pathname of the
+ * device given by the
+ * user. This may be
+ * null if the user
+ * states the device
+ * name and unit number
+ * separately.
+ */
+ char given_dev_name[DEV_IDLEN+1];/*
+ * Device name given by
+ * the user.
+ */
+ u_int32_t given_unit_number; /*
+ * Unit number given by
+ * the user.
+ */
+ char device_name[DEV_IDLEN+1];/*
+ * Name of the device,
+ * e.g. 'pass'
+ */
+ u_int32_t dev_unit_num; /* Unit number of the passthrough
+ * device associated with this
+ * particular device.
+ */
+
+ char sim_name[SIM_IDLEN+1];/*
+ * Controller name, e.g.'ahc'
+ */
+ u_int32_t sim_unit_number; /* Controller unit number */
+ u_int32_t bus_id; /* Controller bus number */
+ lun_id_t target_lun; /* Logical Unit Number */
+ target_id_t target_id; /* Target ID */
+ path_id_t path_id; /* System SCSI bus number */
+ u_int16_t pd_type; /* type of peripheral device */
+ struct scsi_inquiry_data inq_data; /* SCSI Inquiry data */
+ u_int8_t serial_num[252]; /* device serial number */
+ u_int8_t serial_num_len; /* length of the serial number */
+ u_int8_t sync_period; /* Negotiated sync period */
+ u_int8_t sync_offset; /* Negotiated sync offset */
+ u_int8_t bus_width; /* Negotiated bus width */
+ int fd; /* file descriptor for device */
+};
+.Ed
+.Pp
+.Fn cam_open_device
+takes as arguments a string describing the device it is to open, and
+.Ar flags
+suitable for passing to
+.Xr open 2 .
+The "path" passed in may actually be most any type of string that contains
+a device name and unit number to be opened. The string will be parsed by
+.Fn cam_get_device
+into a device name and unit number. Once the device name and unit number
+are determined, a lookup is performed to determine the passthrough device
+that corresponds to the given device.
+.Fn cam_open_device
+is rather simple to use, but it isn't really suitable for general use
+because its behavior isn't necessarily deterministic. Programmers writing
+new applications should make the extra effort to use one of the other open
+routines documented below.
+.Pp
+.Fn cam_open_spec_device
+opens the
+.Xr pass 4
+device that corresponds to the device name and unit number passed in. The
+.Ar flags
+should be flags suitable for passing to
+.Xr open 2 .
+The
+.Ar device
+argument is optional. The user may supply pre-allocated space for the
+.Va cam_device
+structure. If the
+.Ar device
+argument is
+.Va NULL ,
+.Fn cam_open_spec_device
+will allocate space for the
+.Va cam_device
+structure using
+.Xr malloc 3 .
+.Pp
+.Fn cam_open_btl
+is similar to
+.Fn cam_open_spec_device ,
+except that it takes a
+.Tn SCSI
+bus, target and logical unit instead of a device name and unit number as
+arguments. The
+.Va path_id
+argument is the CAM equivalent of a
+.Tn SCSI
+bus number. It represents the logical bus number in the system. The
+.Ar flags
+should be flags suitable for passing to
+.Xr open 2 .
+As with
+.Fn cam_open_spec_device ,
+the
+.Fa device
+argument is optional.
+.Pp
+.Fn cam_open_pass
+takes as an argument the
+.Fa path
+of a
+.Xr pass 4
+device to open. No translation or lookup is performed, so the path passed
+in must be that of a CAM
+.Xr pass 4
+device. The
+.Fa flags
+should be flags suitable for passing to
+.Xr open 2 .
+The
+.Fa device
+argument, as with
+.Fn cam_open_spec_device
+and
+.Fn cam_open_btl ,
+should be NULL if the user wants the CAM library to allocate space for the
+.Va cam_device
+structure.
+.Fn cam_close_device
+frees the
+.Va cam_device
+structure allocated by one of the above open() calls, and closes the file
+descriptor to the passthrough device. This routine should not be called if
+the user allocated space for the
+.Va cam_device
+structure. Instead, the user should call
+.Fn cam_close_spec_device .
+.Pp
+.Fn cam_close_spec_device
+merely closes the file descriptor opened in one of the open() routines
+described above. This function should be called when the
+.Va cam_device
+structure was allocated by the caller, rather than the CAM library.
+.Pp
+.Fn cam_getccb
+allocates a CCB
+using
+.Xr malloc 3
+and sets fields in the CCB header using values from the
+.Va cam_device
+structure.
+.Pp
+.Fn cam_send_ccb
+sends the given
+.Va ccb
+to the
+.Fa device
+described in the
+.Va cam_device
+structure.
+.Pp
+.Fn cam_freeccb
+frees CCBs allocated by
+.Fn cam_getccb .
+.Pp
+.Fn cam_path_string
+takes as arguments a
+.Va cam_device
+structure, and a string with length
+.Fa len .
+It creates a colon-terminated printing prefix string similar to the ones
+used by the kernel. e.g.: "(cd0:ahc1:0:4:0): ".
+.Fn cam_path_string
+will place at most
+.Fa len Ns \-1
+characters into
+.Ar str .
+The
+.Ar len Ns 'th
+character will be the terminating
+.Ql \e0 .
+.Pp
+.Fn cam_device_dup
+operates in a fashion similar to
+.Xr strdup 3 .
+It allocates space for a
+.Va cam_device
+structure and copies the contents of the passed-in
+.Fa device
+structure to the newly allocated structure.
+.Pp
+.Fn cam_device_copy
+copies the
+.Fa src
+structure to
+.Fa dst .
+.Pp
+.Fn cam_get_device
+takes a
+.Fa path
+argument containing a string with a device name followed by a unit number.
+It then breaks the string down into a device name and unit number, and
+passes them back in
+.Fa dev_name
+and
+.Fa unit ,
+respectively.
+.Fn cam_get_device
+can handle strings of the following forms, at least:
+.Pp
+.Bl -tag -width 1234 -compact
+.It /dev/foo0a
+.It /dev/rfoo0a
+.It /dev/rfoo1s2c
+.It foo0
+.It foo0a
+.It rfoo0
+.It rfoo0a
+.It nrfoo0
+.El
+.Pp
+.Fn cam_get_device
+is provided as a convenience function for applications that need to provide
+functionality similar to
+.Fn cam_open_device .
+Programmers are encouraged to use more deterministic methods of obtaining
+device names and unit numbers if possible.
+.Sh RETURN VALUES
+.Fn cam_open_device ,
+.Fn cam_open_spec_device ,
+.Fn cam_open_btl ,
+and
+.Fn cam_open_pass
+return a pointer to a
+.Va cam_device
+structure, or NULL if there was an error.
+.Pp
+.Fn cam_getccb
+returns an allocated and partially initialized CCB, or NULL if allocation
+of the CCB failed.
+.Pp
+.Fn cam_send_ccb
+returns a value of -1 if an error occured, and
+.Va errno
+is set to indicate the error.
+.Pp
+.Fn cam_path_string
+returns a filled printing prefix string as a convenience. This is the same
+.Fa str
+that is passed into
+.Fn cam_path_string .
+.Pp
+.Fn cam_device_dup
+returns a copy of the
+.Va device
+passed in, or NULL if an error occurred.
+.Pp
+.Fn cam_get_device
+returns 0 for success, and -1 to indicate failure.
+.Pp
+If an error is returned from one of the base CAM library functions
+described here, the reason for the error is generally printed in the global
+string
+.Va cam_errbuf
+which is
+.Dv CAM_ERRBUF_SIZE
+characters long.
+.Sh SEE ALSO
+.Xr cam_cdbparse 3 ,
+.Xr pass 4 ,
+.Xr camcontrol 8
+.Sh HISTORY
+The CAM library first appeared in
+.Fx 3.0 .
+.Sh AUTHORS
+.An Kenneth Merry Aq ken@FreeBSD.org
+.Sh BUGS
+.Fn cam_open_device
+doesn't check to see if the
+.Fa path
+passed in is a symlink to something. It also doesn't check to see if the
+.Fa path
+passed in is an actual
+.Xr pass 4
+device. The former would be rather easy to implement, but the latter would
+require a definitive way to identify a device node as a
+.Xr pass 4
+device.
+.Pp
+Some of the functions are possibly mis-named or poorly named.
diff --git a/lib/libcam/cam_cdbparse.3 b/lib/libcam/cam_cdbparse.3
new file mode 100644
index 0000000..42c5dac
--- /dev/null
+++ b/lib/libcam/cam_cdbparse.3
@@ -0,0 +1,543 @@
+.\"
+.\" Copyright (c) 1998 Kenneth D. Merry.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.\" This man page borrows heavily from the old scsi(3) man page, which had
+.\" the following copyright:
+.\"
+.\" Copyright (c) 1994 HD Associates (hd@world.std.com)
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by HD Associates
+.\" 4. Neither the name of the HD Associates nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"
+.Dd October 13, 1998
+.Os FreeBSD 3.0
+.Dt CAM_CDBPARSE 3
+.Sh NAME
+.Nm csio_build ,
+.Nm csio_build_visit ,
+.Nm csio_decode ,
+.Nm csio_decode_visit ,
+.Nm buff_decode ,
+.Nm buff_decode_visit ,
+.Nm csio_encode ,
+.Nm csio_encode_visit ,
+.Nm buff_encode_visit
+.Nd CAM user library SCSI buffer parsing routines
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Fd #include <camlib.h>
+.Ft int
+.Fo csio_build
+.Fa "struct ccb_scsiio *csio"
+.Fa "u_int8_t *data_ptr"
+.Fa "u_int32_t dxfer_len"
+.Fa "u_int32_t flags"
+.Fa "int retry_count"
+.Fa "int timeout"
+.Fa "char *cmd_spec"
+.Fa "..."
+.Fc
+.Ft int
+.Fo csio_build_visit
+.Fa "struct ccb_scsiio *csio"
+.Fa "u_int8_t *data_ptr"
+.Fa "u_int32_t dxfer_len"
+.Fa "u_int32_t flags"
+.Fa "int retry_count"
+.Fa "int timeout"
+.Fa "char *cmd_spec"
+.Fa "int (*arg_get)(void *hook, char *field_name)"
+.Fa "void *gethook"
+.Fc
+.Ft int
+.Fo csio_decode
+.Fa "struct ccb_scsiio *csio"
+.Fa "char *fmt"
+.Fa "..."
+.Fc
+.Ft int
+.Fo csio_decode_visit
+.Fa "struct ccb_scsiio *csio"
+.Fa "char *fmt"
+.Fa "void (*arg_put)(void *hook"
+.Fa "int letter"
+.Fa "void *val"
+.Fa "int count"
+.Fa "char *name)"
+.Fa "void *puthook"
+.Fc
+.Ft int
+.Fo buff_decode
+.Fa "u_int8_t *buff"
+.Fa "size_t len"
+.Fa "char *fmt"
+.Fa "..."
+.Fc
+.Ft int
+.Fo buff_decode_visit
+.Fa "u_int8_t *buff"
+.Fa "size_t len"
+.Fa "char *fmt"
+.Fa "void (*arg_put)(void *, int, void *, int, char *)"
+.Fa "void *puthook"
+.Fc
+.Ft int
+.Fo csio_encode
+.Fa "struct ccb_scsiio *csio"
+.Fa "char *fmt"
+.Fa "..."
+.Fc
+.Ft int
+.Fo csio_encode_visit
+.Fa "struct ccb_scsiio *csio"
+.Fa "char *fmt"
+.Fa "int (*arg_get)(void *hook, char *field_name)"
+.Fa "void *gethook"
+.Fc
+.Ft int
+.Fo buff_encode_visit
+.Fa "u_int8_t *buff"
+.Fa "size_t len"
+.Fa "char *fmt"
+.Fa "int (*arg_get)(void *hook, char *field_name)"
+.Fa "void *gethook"
+.Fc
+.Sh DESCRIPTION
+The CAM buffer/CDB encoding and decoding routines provide a relatively easy
+migration path for userland
+.Tn SCSI
+applications written with the similarly-named
+.Va scsireq_ Ns *
+functions from the old FreeBSD
+.Tn SCSI
+layer.
+.Pp
+These functions may be used in new applications, but users may find it
+easier to use the various SCSI CCB building functions included with the
+.Xr cam 3
+library. (e.g.
+.Fn cam_fill_csio ,
+.Fn scsi_start_stop ,
+and
+.Fn scsi_read_write )
+.Pp
+.Fn csio_build
+builds up a
+.Va ccb_scsiio
+structure based on the information provided in
+the variable argument list.
+It gracefully handles a NULL
+.Fa data_ptr
+argument passed to it.
+.Pp
+.Fa dxfer_len
+is the length of the data phase; the data transfer direction is
+determined by the
+.Fa flags
+argument.
+.Pp
+.Fa data_ptr
+is the data buffer used during the
+.Tn SCSI
+data phase. If no data is to be
+transferred for the
+.Tn SCSI
+command in question, this should be set to NULL. If there is data to
+transfer for the command, this buffer must be at least
+.Fa dxfer_len
+long.
+.Pp
+.Fa flags
+are the flags defined in
+.Aq Pa cam/cam_ccb.h :
+.Bd -literal
+/* Common CCB header */
+/* CAM CCB flags */
+typedef enum {
+ CAM_CDB_POINTER = 0x00000001,/* The CDB field is a pointer */
+ CAM_QUEUE_ENABLE = 0x00000002,/* SIM queue actions are enabled */
+ CAM_CDB_LINKED = 0x00000004,/* CCB contains a linked CDB */
+ CAM_SCATTER_VALID = 0x00000010,/* Scatter/gather list is valid */
+ CAM_DIS_AUTOSENSE = 0x00000020,/* Disable autosense feature */
+ CAM_DIR_RESV = 0x00000000,/* Data direction (00:reserved) */
+ CAM_DIR_IN = 0x00000040,/* Data direction (01:DATA IN) */
+ CAM_DIR_OUT = 0x00000080,/* Data direction (10:DATA OUT) */
+ CAM_DIR_NONE = 0x000000C0,/* Data direction (11:no data) */
+ CAM_DIR_MASK = 0x000000C0,/* Data direction Mask */
+ CAM_SOFT_RST_OP = 0x00000100,/* Use Soft reset alternative */
+ CAM_ENG_SYNC = 0x00000200,/* Flush resid bytes on complete */
+ CAM_DEV_QFRZDIS = 0x00000400,/* Disable DEV Q freezing */
+ CAM_DEV_QFREEZE = 0x00000800,/* Freeze DEV Q on execution */
+ CAM_HIGH_POWER = 0x00001000,/* Command takes a lot of power */
+ CAM_SENSE_PTR = 0x00002000,/* Sense data is a pointer */
+ CAM_SENSE_PHYS = 0x00004000,/* Sense pointer is physical addr*/
+ CAM_TAG_ACTION_VALID = 0x00008000,/* Use the tag action in this ccb*/
+ CAM_PASS_ERR_RECOVER = 0x00010000,/* Pass driver does err. recovery*/
+ CAM_DIS_DISCONNECT = 0x00020000,/* Disable disconnect */
+ CAM_SG_LIST_PHYS = 0x00040000,/* SG list has physical addrs. */
+ CAM_MSG_BUF_PHYS = 0x00080000,/* Message buffer ptr is physical*/
+ CAM_SNS_BUF_PHYS = 0x00100000,/* Autosense data ptr is physical*/
+ CAM_DATA_PHYS = 0x00200000,/* SG/Buffer data ptrs are phys. */
+ CAM_CDB_PHYS = 0x00400000,/* CDB poiner is physical */
+ CAM_ENG_SGLIST = 0x00800000,/* SG list is for the HBA engine */
+
+/* Phase cognizant mode flags */
+ CAM_DIS_AUTOSRP = 0x01000000,/* Diable autosave/restore ptrs */
+ CAM_DIS_AUTODISC = 0x02000000,/* Disable auto disconnect */
+ CAM_TGT_CCB_AVAIL = 0x04000000,/* Target CCB available */
+ CAM_TGT_PHASE_MODE = 0x08000000,/* The SIM runs in phase mode */
+ CAM_MSGB_VALID = 0x20000000,/* Message buffer valid */
+ CAM_STATUS_VALID = 0x40000000,/* Status buffer valid */
+ CAM_DATAB_VALID = 0x80000000,/* Data buffer valid */
+
+/* Host target Mode flags */
+ CAM_TERM_IO = 0x20000000,/* Terminate I/O Message sup. */
+ CAM_DISCONNECT = 0x40000000,/* Disconnects are mandatory */
+ CAM_SEND_STATUS = 0x80000000,/* Send status after data phase */
+} ccb_flags;
+.Ed
+.Pp
+Multiple flags should be ORed together. Any of the CCB flags may be used,
+although it is worth noting several important ones here:
+.Pp
+.Bl -tag -width CAM_PASS_ERR_RECOVER
+.It Dv CAM_DIR_IN
+This indicates that the operation in question is a read operation. i.e.,
+data is being read from the
+.Tn SCSI
+device to the user-supplied buffer.
+.It Dv CAM_DIR_OUT
+This indicates that the operation is a write operation. i.e. data is being
+written from the user-supplied buffer to the device.
+.It Dv CAM_DIR_NONE
+This indicates that there is no data to be transferred for this command.
+.It Dv CAM_DEV_QFRZDIS
+This flag disables device queue freezing as an error recovery mechanism.
+.It Dv CAM_PASS_ERR_RECOVER
+This flag tells the
+.Xr pass 4
+driver to enable error recovery. The default is to not perform error
+recovery, which means that the retry count won't be honored without this
+flag, among other things.
+.It Dv CAM_DATA_PHYS
+This indicates that the address contained in
+.Fa data_ptr
+is a physical address, not a virtual address.
+.El
+.Pp
+The
+.Fa retry_count
+tells the kernel how many times to retry the command in question. The
+retry count is ignored unless the
+.Xr pass 4
+driver is told to enable error recovery via the
+.Dv CAM_PASS_ERR_RECOVER
+flag.
+.Pp
+The
+.Fa timeout
+tells the kernel how long to wait for the given command to complete. If
+the timeout expires and the command hasn't completed, the CCB will be
+returned from the kernel with an appropriate error status.
+.Pp
+.Fa cmd_spec
+is a CDB format specifier used to build up the SCSI CDB.
+This text string is made up of a list of field specifiers. Field
+specifiers specify the value for each CDB field (including indicating
+that the value be taken from the next argument in the
+variable argument list), the width
+of the field in bits or bytes, and an optional name. White space is
+ignored, and the pound sign ('#') introduces a comment that ends at the
+end of the current line.
+.Pp
+The optional name is the first part of a field specifier and
+is in curly braces. The text in curly braces in this example are
+the names:
+.Bd -literal -offset indent
+.Fa "{PS} v:b1 {Reserved} 0:b1 {Page Code} v:b6 # Mode select page"
+.Ed
+.Pp
+This field specifier has two one bit fields and one six bit field.
+The second one bit field is the constant value 0 and the first
+one bit field and the six bit field are taken from the variable
+argument list.
+Multi byte fields are swapped into the SCSI byte order in the
+CDB and white space is ignored.
+.Pp
+When the field is a hex value or the letter v, (e.g.,
+.Fa "1A"
+or
+.Fa "v" )
+then a single byte value
+is copied to the next unused byte of the CDB.
+When the letter
+.Fa v
+is used the next integer argument is taken from the variable argument list
+and that value used.
+.Pp
+A constant hex value followed by a field width specifier or the letter
+.Fa v
+followed by a field width specifier (e.g.,
+.Fa 3:4 ,
+.Fa 3:b4 ,
+.Fa 3:i3 ,
+.FR v:i3 )
+specifies a field of a given bit or byte width.
+Either the constant value or (for the V specifier) the next integer value from
+the variable argument list is copied to the next unused
+bits or bytes of the CDB.
+.Pp
+A decimal number or the letter
+.Fa b
+followed by a decimal number field width indicates a bit field of that width.
+The bit fields are packed as tightly as possible beginning with the
+high bit (so that it reads the same as the SCSI spec), and a new byte of
+the CDB is started whenever a byte fills completely or when an
+.Fa i
+field is encountered.
+.Pp
+A field width specifier consisting of the letter
+.Fa i
+followed by either
+1, 2, 3 or 4 indicates a 1, 2, 3 or 4 byte integral value that must
+be swapped into SCSI byte order (MSB first).
+.Pp
+For the
+.Fa v
+field specifier the next integer argument is taken from the variable argument
+list and that value is used swapped into SCSI byte order.
+.Pp
+.Fn csio_build_visit
+operates similarly to
+.Fn csio_build ,
+except that the values to substitute for variable arguments in
+.Fa cmd_spec
+are retrieved via the
+.Fn arg_get
+function passed in to
+.Fn csio_build_visit
+instead of via
+.Xr stdarg 3 .
+The
+.Fn arg_get
+function takes two arguments:
+.Bl -tag -width field_name
+.It Fa gethook
+is passed into the
+.Fn arg_get
+function at each invocation. This enables the
+.Fn arg_get
+function to keep some state in between calls without using global or static
+variables.
+.It Fa field_name
+is the field name supplied in
+.Fa fmt ,
+if any.
+.El
+.Pp
+.Fn csio_decode
+is used to decode information from the data in phase of the SCSI
+transfer.
+.Pp
+The decoding is similar to
+the command specifier processing of
+.Fn csio_build
+except that the data is extracted from the data pointed to by
+.Fa csio->data_ptr .
+The stdarg list should be pointers to integers instead of integer
+values.
+A seek field type and a suppression modifier are added.
+The
+.Fa *
+suppression modifier (e.g.,
+.Fa *i3
+or
+.Fa *b4 )
+suppresses assignment from the field and can be used to skip
+over bytes or bits in the data, without having to copy
+them to a dummy variable in the arg list.
+.Pp
+The seek field type
+.Fa s
+permits you to skip over data.
+This seeks to an absolute position (
+.Fa s3 )
+or a relative position (
+.Fa s+3 )
+in the data, based on whether or not the presence of the '+' sign.
+The seek value can be specified as
+.Fa v
+and the next integer value from the argument list will be
+used as the seek value.
+.Pp
+.Fn csio_decode_visit
+operates like
+.Fn csio_decode
+except that instead of placing the decoded contents of the buffer in
+varardic arguments, the decoded buffer contents are returned to the user
+via the
+.Fn arg_put
+function that is passed in.
+The
+.Fn arg_put
+function takes several arguments:
+.Bl -tag -width letter
+.It Fa hook
+The "hook" is a mechanism to allow the
+.Fn arg_put
+function to save state in between calls.
+.It Fa letter
+is the letter describing the format of the argument being passed into the
+function.
+.It Fa val
+is a void pointer to the value being passed into the function.
+.It Fa count
+is the number of arguments being passed into the
+.Fn arg_put
+function. At present this will only be set to 1.
+.It Fa name
+This is a text description of the field, if one was provided in the
+.Fa fmt .
+.El
+.Pp
+.Fn buff_decode
+decodes an arbitrary data buffer using the method
+described above for
+.Fn csio_decode .
+.Pp
+.Fn buff_decode_visit
+decodes an arbitrary data buffer using the method described above for
+.Fn csio_decode_visit .
+.Pp
+.Fn csio_encode
+encodes the
+.Fa data_ptr
+portion (not the CDB!) of a
+.Va ccb_scsiio
+structure, using the method described above for
+.Fn csio_build .
+.Pp
+.Fn csio_encode_visit
+encodes the
+.Fa data_ptr
+portion (not the CDB!) of a
+.Va ccb_scsiio
+structure, using the method described above for
+.Fn csio_build_visit .
+.Pp
+.Fn buff_encode_visit
+encodes an arbitrary data pointer, using the method described
+above for
+.Fn csio_build_visit .
+.Sh RETURN VALUES
+.Fn csio_build ,
+.Fn csio_build_visit ,
+.Fn csio_encode ,
+.Fn csio_encode_visit ,
+and
+.Fn buff_encode_visit
+return the number of fields processed.
+.Pp
+.Fn csio_decode ,
+.Fn csio_decode_visit ,
+.Fn buff_decode ,
+and
+.Fn buff_decode_visit
+return the number of assignments performed.
+.Sh SEE ALSO
+.Xr cam 3 ,
+.Xr pass 4 ,
+.Xr camcontrol 8
+.Sh HISTORY
+.Pp
+The CAM versions of these functions are based upon similar functions
+implemented for the old FreeBSD
+.Tn SCSI
+layer. The encoding/decoding functions in the old
+.Tn SCSI
+code were written by Peter Dufault.
+.Pp
+Many systems have comparable interfaces to permit a user to construct a
+SCSI command in user space.
+.Pp
+The old
+.Va scsireq
+data structure was almost identical to the SGI /dev/scsi data
+structure. If anyone knows the name of the authors it should
+go here; Peter Dufault first read about it in a 1989 Sun Expert magazine.
+.Pp
+The new CCB data structures are derived from the CAM-2 and CAM-3
+specifications.
+.Pp
+Peter Dufault implemented a clone of SGI's interface in 386bsd that
+led to the original FreeBSD
+.Tn SCSI
+library and the related kernel ioctl.
+If anyone needs that for compatibility contact dufault@hda.com.
+.Sh AUTHORS
+Kenneth Merry implemented the CAM versions of these encoding and decoding
+functions. This current work is based upon earlier work by Peter Dufault.
+.Sh BUGS
+There should probably be a function that encodes both the CDB and the data
+buffer portions of a
+.Tn SCSI
+CCB. I discovered this while implementing the arbitrary command execution
+code in
+.Xr camcontrol 8 ,
+but I haven't yet had time to implement such a function.
+.Pp
+Some of the CCB flag descriptions really don't belong here. Rather they
+belong in a generic CCB man page. Since that man page hasn't yet been
+written, the shorter descriptions here will have to suffice.
diff --git a/lib/libcam/camlib.c b/lib/libcam/camlib.c
new file mode 100644
index 0000000..648b030
--- /dev/null
+++ b/lib/libcam/camlib.c
@@ -0,0 +1,785 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kenneth D. Merry.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include <cam/cam.h>
+#include <cam/scsi/scsi_all.h>
+#include <cam/cam_ccb.h>
+#include <cam/scsi/scsi_pass.h>
+#include "camlib.h"
+
+struct cam_devequiv {
+ char *given_dev;
+ char *real_dev;
+};
+
+struct cam_devequiv devmatchtable[] = {
+ {"sd", "da"},
+ {"st", "sa"}
+};
+
+char cam_errbuf[CAM_ERRBUF_SIZE];
+
+static struct cam_device *cam_real_open_device(const char *path, int flags,
+ struct cam_device *device,
+ const char *given_path,
+ const char *given_dev_name,
+ int given_unit_number);
+static struct cam_device *cam_lookup_pass(const char *dev_name, int unit,
+ int flags, const char *given_path,
+ struct cam_device *device);
+
+/*
+ * Send a ccb to a passthrough device.
+ */
+int
+cam_send_ccb(struct cam_device *device, union ccb *ccb)
+{
+ return(ioctl(device->fd, CAMIOCOMMAND, ccb));
+}
+
+/*
+ * Malloc a CCB, zero out the header and set its path, target and lun ids.
+ */
+union ccb *
+cam_getccb(struct cam_device *dev)
+{
+ union ccb *ccb;
+
+ ccb = (union ccb *)malloc(sizeof(union ccb));
+ if (ccb != NULL) {
+ bzero(&ccb->ccb_h, sizeof(struct ccb_hdr));
+ ccb->ccb_h.path_id = dev->path_id;
+ ccb->ccb_h.target_id = dev->target_id;
+ ccb->ccb_h.target_lun = dev->target_lun;
+ }
+
+ return(ccb);
+}
+
+/*
+ * Free a CCB.
+ */
+void
+cam_freeccb(union ccb *ccb)
+{
+ if (ccb != NULL)
+ free(ccb);
+}
+
+/*
+ * Take a device name or path passed in by the user, and attempt to figure
+ * out the device name and unit number. Some possible device name formats are:
+ * /dev/foo0a
+ * /dev/rfoo0a
+ * /dev/rfoos2c
+ * foo0
+ * foo0a
+ * rfoo0
+ * rfoo0a
+ * nrfoo0
+ *
+ * If the caller passes in an old style device name like 'sd' or 'st',
+ * it will be converted to the new style device name based upon devmatchtable
+ * above.
+ *
+ * Input parameters: device name/path, length of devname string
+ * Output: device name, unit number
+ * Return values: returns 0 for success, -1 for failure
+ */
+int
+cam_get_device(const char *path, char *dev_name, int devnamelen, int *unit)
+{
+ char *func_name = "cam_get_device";
+ char *tmpstr, *tmpstr2;
+ char *newpath;
+ int unit_offset;
+ int i, found = 0;
+
+
+ if (path == NULL) {
+ sprintf(cam_errbuf, "%s: device pathname was NULL", func_name);
+ return(-1);
+ }
+
+ /*
+ * We can be rather destructive to the path string. Make a copy of
+ * it so we don't hose the user's string.
+ */
+ newpath = (char *)strdup(path);
+ tmpstr = newpath;
+
+ /* Get rid of any leading white space */
+ while (isspace(*tmpstr) && (*tmpstr != '\0'))
+ tmpstr++;
+
+ /*
+ * Check to see whether we have an absolute pathname.
+ */
+ if (*tmpstr == '/') {
+ tmpstr2 = tmpstr;
+ tmpstr = (char *)rindex(tmpstr2, '/');
+ if ((tmpstr != NULL) && (*tmpstr != '\0'))
+ tmpstr++;
+ }
+
+ if (*tmpstr == '\0') {
+ sprintf(cam_errbuf, "%s: no text after slash", func_name);
+ free(newpath);
+ return(-1);
+ }
+
+ /*
+ * Check to see whether the user has given us a nonrewound tape
+ * device.
+ */
+ if (*tmpstr == 'n')
+ tmpstr++;
+
+ if (*tmpstr == '\0') {
+ sprintf(cam_errbuf, "%s: no text after leading 'n'", func_name);
+ free(newpath);
+ return(-1);
+ }
+
+ /*
+ * See if the user has given us a character device.
+ */
+ if (*tmpstr == 'r')
+ tmpstr++;
+
+ if (*tmpstr == '\0') {
+ sprintf(cam_errbuf, "%s: no text after leading 'r'", func_name);
+ free(newpath);
+ return(-1);
+ }
+
+ /*
+ * Try to get rid of any trailing white space or partition letters.
+ */
+ tmpstr2 = &tmpstr[strlen(tmpstr) - 1];
+
+ while ((*tmpstr2 != '\0') && (tmpstr2 > tmpstr) &&(!isdigit(*tmpstr2))){
+ *tmpstr2 = '\0';
+ tmpstr2--;
+ }
+
+ /*
+ * Check to see whether we have been given a partition with a slice
+ * name. If so, get rid of the slice name/number.
+ */
+ if (strlen(tmpstr) > 3) {
+ /*
+ * Basically, we're looking for a string that ends in the
+ * following general manner: 1s1 -- a number, the letter
+ * s, and then another number. This indicates that the
+ * user has given us a slice. We substitute nulls for the
+ * s and the slice number.
+ */
+ if ((isdigit(tmpstr[strlen(tmpstr) - 1]))
+ && (tmpstr[strlen(tmpstr) - 2] == 's')
+ && (isdigit(tmpstr[strlen(tmpstr) - 3]))) {
+ tmpstr[strlen(tmpstr) - 1] = '\0';
+ tmpstr[strlen(tmpstr) - 1] = '\0';
+ }
+ }
+
+ /*
+ * After we nuke off the slice, we should have just a device name
+ * and unit number. That means there must be at least 2
+ * characters. If we only have 1, we don't have a valid device name.
+ */
+ if (strlen(tmpstr) < 2) {
+ sprintf(cam_errbuf,
+ "%s: must have both device name and unit number",
+ func_name);
+ free(newpath);
+ return(-1);
+ }
+
+ /*
+ * If the first character of the string is a digit, then the user
+ * has probably given us all numbers. Point out the error.
+ */
+ if (isdigit(*tmpstr)) {
+ sprintf(cam_errbuf,
+ "%s: device name cannot begin with a number",
+ func_name);
+ free(newpath);
+ return(-1);
+ }
+
+ /*
+ * At this point, if the last character of the string isn't a
+ * number, we know the user either didn't give us a device number,
+ * or he gave us a device name/number format we don't recognize.
+ */
+ if (!isdigit(tmpstr[strlen(tmpstr) - 1])) {
+ sprintf(cam_errbuf, "%s: unable to find device unit number",
+ func_name);
+ free(newpath);
+ return(-1);
+ }
+
+ /*
+ * Attempt to figure out where the device name ends and the unit
+ * number begins. As long as unit_offset is at least 1 less than
+ * the length of the string, we can still potentially have a device
+ * name at the front of the string. When we get to something that
+ * isn't a digit, we've hit the device name. Because of the check
+ * above, we know that this cannot happen when unit_offset == 1.
+ * Therefore it is okay to decrement unit_offset -- it won't cause
+ * us to go past the end of the character array.
+ */
+ for (unit_offset = 1;
+ (unit_offset < (strlen(tmpstr)))
+ && (isdigit(tmpstr[strlen(tmpstr) - unit_offset])); unit_offset++);
+
+ unit_offset--;
+
+ /*
+ * Grab the unit number.
+ */
+ *unit = atoi(&tmpstr[strlen(tmpstr) - unit_offset]);
+
+ /*
+ * Put a null in place of the first number of the unit number so
+ * that all we have left is the device name.
+ */
+ tmpstr[strlen(tmpstr) - unit_offset] = '\0';
+
+ /*
+ * Look through our equivalency table and see if the device name
+ * the user gave us is an old style device name. If so, translate
+ * it to the new style device name.
+ */
+ for (i = 0;i < (sizeof(devmatchtable)/sizeof(struct cam_devequiv));i++){
+ if (strcmp(tmpstr, devmatchtable[i].given_dev) == 0) {
+ strncpy(dev_name,devmatchtable[i].real_dev, devnamelen);
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0)
+ strncpy(dev_name, tmpstr, devnamelen);
+
+ /* Make sure we pass back a null-terminated string */
+ dev_name[devnamelen - 1] = '\0';
+
+ /* Clean up allocated memory */
+ free(newpath);
+
+ return(0);
+
+}
+
+/*
+ * Backwards compatible wrapper for the real open routine. This translates
+ * a pathname into a device name and unit number for use with the real open
+ * routine.
+ */
+struct cam_device *
+cam_open_device(const char *path, int flags)
+{
+ int unit;
+ char dev_name[DEV_IDLEN + 1];
+
+ /*
+ * cam_get_device() has already put an error message in cam_errbuf,
+ * so we don't need to.
+ */
+ if (cam_get_device(path, dev_name, DEV_IDLEN + 1, &unit) == -1)
+ return(NULL);
+
+ return(cam_lookup_pass(dev_name, unit, flags, path, NULL));
+}
+
+/*
+ * Open the passthrough device for a given bus, target and lun, if the
+ * passthrough device exists.
+ */
+struct cam_device *
+cam_open_btl(path_id_t path_id, target_id_t target_id, lun_id_t target_lun,
+ int flags, struct cam_device *device)
+{
+ union ccb ccb;
+ struct periph_match_pattern *match_pat;
+ char *func_name = "cam_open_btl";
+ int fd, bufsize;
+
+ if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
+ snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
+ "%s: couldn't open %s\n%s: %s", func_name, XPT_DEVICE,
+ func_name, strerror(errno));
+ return(NULL);
+ }
+
+ bzero(&ccb, sizeof(union ccb));
+ ccb.ccb_h.func_code = XPT_DEV_MATCH;
+
+ /* Setup the result buffer */
+ bufsize = sizeof(struct dev_match_result);
+ ccb.cdm.match_buf_len = bufsize;
+ ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
+ if (ccb.cdm.matches == NULL) {
+ snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
+ "%s: couldn't malloc match buffer", func_name);
+ close(fd);
+ return(NULL);
+ }
+ ccb.cdm.num_matches = 0;
+
+ /* Setup the pattern buffer */
+ ccb.cdm.num_patterns = 1;
+ ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
+ ccb.cdm.patterns = (struct dev_match_pattern *)malloc(
+ sizeof(struct dev_match_pattern));
+ if (ccb.cdm.patterns == NULL) {
+ snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
+ "%s: couldn't malloc pattern buffer", func_name);
+ free(ccb.cdm.matches);
+ close(fd);
+ return(NULL);
+ }
+ ccb.cdm.patterns[0].type = DEV_MATCH_PERIPH;
+ match_pat = &ccb.cdm.patterns[0].pattern.periph_pattern;
+
+ /*
+ * We're looking for the passthrough device associated with this
+ * particular bus/target/lun.
+ */
+ sprintf(match_pat->periph_name, "pass");
+ match_pat->path_id = path_id;
+ match_pat->target_id = target_id;
+ match_pat->target_lun = target_lun;
+ /* Now set the flags to indicate what we're looking for. */
+ match_pat->flags = PERIPH_MATCH_PATH | PERIPH_MATCH_TARGET |
+ PERIPH_MATCH_LUN | PERIPH_MATCH_NAME;
+
+ if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
+ sprintf(cam_errbuf, "%s: CAMIOCOMMAND ioctl failed\n"
+ "%s: %s", func_name, func_name, strerror(errno));
+ goto btl_bailout;
+ }
+
+ /*
+ * Check for an outright error.
+ */
+ if ((ccb.ccb_h.status != CAM_REQ_CMP)
+ || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
+ && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
+ sprintf(cam_errbuf, "%s: CAM error %#x, CDM error %d "
+ "returned from XPT_DEV_MATCH ccb", func_name,
+ ccb.ccb_h.status, ccb.cdm.status);
+ goto btl_bailout;
+ }
+
+ if (ccb.cdm.status == CAM_DEV_MATCH_MORE) {
+ sprintf(cam_errbuf, "%s: CDM reported more than one"
+ " passthrough device at %d:%d:%d!!\n",
+ func_name, path_id, target_id, target_lun);
+ goto btl_bailout;
+ }
+
+ if (ccb.cdm.num_matches == 0) {
+ sprintf(cam_errbuf, "%s: no passthrough device found at"
+ " %d:%d:%d", func_name, path_id, target_id,
+ target_lun);
+ goto btl_bailout;
+ }
+
+ switch(ccb.cdm.matches[0].type) {
+ case DEV_MATCH_PERIPH: {
+ int pass_unit;
+ char dev_path[256];
+ struct periph_match_result *periph_result;
+
+ periph_result = &ccb.cdm.matches[0].result.periph_result;
+ pass_unit = periph_result->unit_number;
+ free(ccb.cdm.matches);
+ free(ccb.cdm.patterns);
+ close(fd);
+ sprintf(dev_path, "/dev/pass%d", pass_unit);
+ return(cam_real_open_device(dev_path, flags, device, NULL,
+ NULL, 0));
+ break; /* NOTREACHED */
+ }
+ default:
+ sprintf(cam_errbuf, "%s: asked for a peripheral match, but"
+ " got a bus or device match??!!", func_name);
+ goto btl_bailout;
+ break; /* NOTREACHED */
+ }
+
+btl_bailout:
+ free(ccb.cdm.matches);
+ free(ccb.cdm.patterns);
+ close(fd);
+ return(NULL);
+}
+
+struct cam_device *
+cam_open_spec_device(const char *dev_name, int unit, int flags,
+ struct cam_device *device)
+{
+ return(cam_lookup_pass(dev_name, unit, flags, NULL, device));
+}
+
+struct cam_device *
+cam_open_pass(const char *path, int flags, struct cam_device *device)
+{
+ return(cam_real_open_device(path, flags, device, path, NULL, 0));
+}
+
+static struct cam_device *
+cam_lookup_pass(const char *dev_name, int unit, int flags,
+ const char *given_path, struct cam_device *device)
+{
+ int fd;
+ union ccb ccb;
+ char dev_path[256];
+ char *func_name = "cam_lookup_pass";
+
+ /*
+ * The flags argument above only applies to the actual passthrough
+ * device open, not our open of the given device to find the
+ * passthrough device.
+ */
+ if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
+ snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
+ "%s: couldn't open %s\n%s: %s", func_name, XPT_DEVICE,
+ func_name, strerror(errno));
+ return(NULL);
+ }
+
+ /* This isn't strictly necessary for the GETPASSTHRU ioctl. */
+ ccb.ccb_h.func_code = XPT_GDEVLIST;
+
+ /* These two are necessary for the GETPASSTHRU ioctl to work. */
+ strncpy(ccb.cgdl.periph_name, dev_name, DEV_IDLEN - 1);
+ ccb.cgdl.periph_name[DEV_IDLEN - 1] = '\0';
+ ccb.cgdl.unit_number = unit;
+
+ /*
+ * Attempt to get the passthrough device. This ioctl will fail if
+ * the device name is null, if the device doesn't exist, or if the
+ * passthrough driver isn't in the kernel.
+ */
+ if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
+ char tmpstr[256];
+
+ /*
+ * If we get ENOENT from the transport layer version of
+ * the CAMGETPASSTHRU ioctl, it means one of two things:
+ * either the device name/unit number passed in doesn't
+ * exist, or the passthrough driver isn't in the kernel.
+ */
+ if (errno == ENOENT) {
+ snprintf(tmpstr, sizeof(tmpstr),
+ "\n%s: either the pass driver isn't in "
+ "your kernel\n%s: or %s%d doesn't exist",
+ func_name, func_name, dev_name, unit);
+ }
+ snprintf(cam_errbuf, sizeof(cam_errbuf),
+ "%s: CAMGETPASSTHRU ioctl failed\n"
+ "%s: %s%s", func_name, func_name, strerror(errno),
+ (errno == ENOENT) ? tmpstr : "");
+
+ return(NULL);
+ }
+
+ close(fd);
+
+ /*
+ * If the ioctl returned the right status, but we got an error back
+ * in the ccb, that means that the kernel found the device the user
+ * passed in, but was unable to find the passthrough device for
+ * the device the user gave us.
+ */
+ if (ccb.cgdl.status == CAM_GDEVLIST_ERROR) {
+ sprintf(cam_errbuf, "%s: device %s%d does not exist",
+ func_name, dev_name, unit);
+ return(NULL);
+ }
+
+ sprintf(dev_path, "/dev/%s%d", ccb.cgdl.periph_name,
+ ccb.cgdl.unit_number);
+
+ return(cam_real_open_device(dev_path, flags, device, NULL,
+ dev_name, unit));
+}
+
+/*
+ * Open a given device. The path argument isn't strictly necessary, but it
+ * is copied into the cam_device structure as a convenience to the user.
+ */
+static struct cam_device *
+cam_real_open_device(const char *path, int flags, struct cam_device *device,
+ const char *given_path, const char *given_dev_name,
+ int given_unit_number)
+{
+ char newpath[MAXPATHLEN+1];
+ char *func_name = "cam_real_open_device";
+ union ccb ccb;
+ int fd, malloced_device = 0;
+
+ /*
+ * See if the user wants us to malloc a device for him.
+ */
+ if (device == NULL) {
+ if ((device = (struct cam_device *)malloc(
+ sizeof(struct cam_device))) == NULL) {
+ sprintf(cam_errbuf, "%s: device structure malloc"
+ " failed\n%s: %s", func_name, func_name,
+ strerror(errno));
+ return(NULL);
+ }
+ malloced_device = 1;
+ }
+
+ /*
+ * If the user passed in a path, save it for him.
+ */
+ if (given_path != NULL)
+ strncpy(device->device_path, given_path, MAXPATHLEN + 1);
+ else
+ device->device_path[0] = '\0';
+
+ /*
+ * If the user passed in a device name and unit number pair, save
+ * those as well.
+ */
+ if (given_dev_name != NULL)
+ strncpy(device->given_dev_name, given_dev_name, DEV_IDLEN);
+ else
+ device->given_dev_name[0] = '\0';
+ device->given_unit_number = given_unit_number;
+
+ if ((fd = open(path, flags)) < 0) {
+ snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
+ "%s: couldn't open passthrough device %s\n"
+ "%s: %s", func_name, path, func_name,
+ strerror(errno));
+ goto crod_bailout;
+ }
+
+ device->fd = fd;
+
+ bzero(&ccb, sizeof(union ccb));
+
+ /*
+ * Unlike the transport layer version of the GETPASSTHRU ioctl,
+ * we don't have to set any fields.
+ */
+ ccb.ccb_h.func_code = XPT_GDEVLIST;
+
+ /*
+ * We're only doing this to get some information on the device in
+ * question. Otherwise, we'd have to pass in yet another
+ * parameter: the passthrough driver unit number.
+ */
+ if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
+ /*
+ * At this point we know the passthrough device must exist
+ * because we just opened it above. The only way this
+ * ioctl can fail is if the ccb size is wrong.
+ */
+ sprintf(cam_errbuf, "%s: CAMGETPASSTHRU ioctl failed\n"
+ "%s: %s", func_name, func_name, strerror(errno));
+ goto crod_bailout;
+ }
+
+ /*
+ * If the ioctl returned the right status, but we got an error back
+ * in the ccb, that means that the kernel found the device the user
+ * passed in, but was unable to find the passthrough device for
+ * the device the user gave us.
+ */
+ if (ccb.cgdl.status == CAM_GDEVLIST_ERROR) {
+ sprintf(cam_errbuf, "%s: passthrough device does not exist??!!",
+ func_name);
+ goto crod_bailout;
+ }
+
+ device->dev_unit_num = ccb.cgdl.unit_number;
+ strcpy(device->device_name, ccb.cgdl.periph_name);
+ device->path_id = ccb.ccb_h.path_id;
+ device->target_id = ccb.ccb_h.target_id;
+ device->target_lun = ccb.ccb_h.target_lun;
+
+ ccb.ccb_h.func_code = XPT_PATH_INQ;
+ if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
+ sprintf(cam_errbuf, "%s: Path Inquiry CCB failed\n"
+ "%s: %s", func_name, func_name, strerror(errno));
+ goto crod_bailout;
+ }
+ strncpy(device->sim_name, ccb.cpi.dev_name, SIM_IDLEN);
+ device->sim_unit_number = ccb.cpi.unit_number;
+ device->bus_id = ccb.cpi.bus_id;
+
+ /*
+ * It doesn't really matter what is in the payload for a getdev
+ * CCB, the kernel doesn't look at it.
+ */
+ ccb.ccb_h.func_code = XPT_GDEV_TYPE;
+ if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
+ sprintf(cam_errbuf, "%s: Get Device Type CCB failed\n"
+ "%s: %s", func_name, func_name, strerror(errno));
+ goto crod_bailout;
+ }
+ device->pd_type = ccb.cgd.pd_type;
+ bcopy(&ccb.cgd.inq_data, &device->inq_data,
+ sizeof(struct scsi_inquiry_data));
+ device->serial_num_len = ccb.cgd.serial_num_len;
+ bcopy(&ccb.cgd.serial_num, &device->serial_num, device->serial_num_len);
+
+ /*
+ * Zero the payload, the kernel does look at the flags.
+ */
+ bzero(&(&ccb.ccb_h)[1], sizeof(struct ccb_trans_settings));
+
+ /*
+ * Get transfer settings for this device.
+ */
+ ccb.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
+
+ ccb.cts.flags = CCB_TRANS_CURRENT_SETTINGS;
+
+ if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
+ sprintf(cam_errbuf, "%s: Get Transfer Settings CCB failed\n"
+ "%s: %s", func_name, func_name, strerror(errno));
+ goto crod_bailout;
+ }
+ device->sync_period = ccb.cts.sync_period;
+ device->sync_offset = ccb.cts.sync_offset;
+ device->bus_width = ccb.cts.bus_width;
+
+ return(device);
+
+crod_bailout:
+
+ if (malloced_device)
+ free(device);
+
+ return(NULL);
+}
+
+void
+cam_close_device(struct cam_device *dev)
+{
+ if (dev == NULL)
+ return;
+
+ cam_close_spec_device(dev);
+
+ if (dev != NULL)
+ free(dev);
+}
+
+void
+cam_close_spec_device(struct cam_device *dev)
+{
+ if (dev == NULL)
+ return;
+
+ if (dev->fd >= 0)
+ close(dev->fd);
+}
+
+char *
+cam_path_string(struct cam_device *dev, char *str, int len)
+{
+ if (dev == NULL) {
+ snprintf(str, len, "No path");
+ return(str);
+ }
+
+ snprintf(str, len, "(%s%d:%s%d:%d:%d:%d): ",
+ (dev->device_name[0] != '\0') ? dev->device_name : "pass",
+ dev->dev_unit_num,
+ (dev->sim_name[0] != '\0') ? dev->sim_name : "unknown",
+ dev->sim_unit_number,
+ dev->bus_id,
+ dev->target_id,
+ dev->target_lun);
+
+ return(str);
+}
+
+/*
+ * Malloc/duplicate a CAM device structure.
+ */
+struct cam_device *
+cam_device_dup(struct cam_device *device)
+{
+ char *func_name = "cam_device_dup";
+ struct cam_device *newdev;
+
+ if (device == NULL) {
+ sprintf(cam_errbuf, "%s: device is NULL", func_name);
+ return(NULL);
+ }
+
+ newdev = malloc(sizeof(struct cam_device));
+
+ bcopy(device, newdev, sizeof(struct cam_device));
+
+ return(newdev);
+}
+
+/*
+ * Copy a CAM device structure.
+ */
+void
+cam_device_copy(struct cam_device *src, struct cam_device *dst)
+{
+ char *func_name = "cam_device_copy";
+
+ if (src == NULL) {
+ sprintf(cam_errbuf, "%s: source device struct was NULL",
+ func_name);
+ return;
+ }
+
+ if (dst == NULL) {
+ sprintf(cam_errbuf, "%s: destination device struct was NULL",
+ func_name);
+ return;
+ }
+
+ bcopy(src, dst, sizeof(struct cam_device));
+
+}
diff --git a/lib/libcam/camlib.h b/lib/libcam/camlib.h
new file mode 100644
index 0000000..4201294
--- /dev/null
+++ b/lib/libcam/camlib.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 1997, 1998 Kenneth D. Merry.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/*
+ * Buffer encoding/decoding routines taken from the original FreeBSD SCSI
+ * library and slightly modified. The original header file had the following
+ * copyright:
+ */
+/* Copyright (c) 1994 HD Associates (hd@world.std.com)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by HD Associates
+ * 4. Neither the name of the HD Associaates nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#ifndef _CAMLIB_H
+#define _CAMLIB_H
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+
+#define CAM_ERRBUF_SIZE 2048 /* sizeof the CAM libarary error string */
+
+/*
+ * Right now we hard code the transport layer device, but this will change
+ * if we ever get more than one transport layer.
+ */
+#define XPT_DEVICE "/dev/xpt0"
+
+
+extern char cam_errbuf[];
+
+struct cam_device {
+ char device_path[MAXPATHLEN+1];/*
+ * Pathname of the device
+ * given by the user. This
+ * may be null if the
+ * user states the device
+ * name and unit number
+ * separately.
+ */
+ char given_dev_name[DEV_IDLEN+1];/*
+ * Device name given by
+ * the user.
+ */
+ u_int32_t given_unit_number; /*
+ * Unit number given by
+ * the user.
+ */
+ char device_name[DEV_IDLEN+1];/*
+ * Name of the device,
+ * e.g. 'pass'
+ */
+ u_int32_t dev_unit_num; /* Unit number of the passthrough
+ * device associated with this
+ * particular device.
+ */
+
+ char sim_name[SIM_IDLEN+1]; /* Controller name, e.g. 'ahc' */
+ u_int32_t sim_unit_number; /* Controller unit number */
+ u_int32_t bus_id; /* Controller bus number */
+ lun_id_t target_lun; /* Logical Unit Number */
+ target_id_t target_id; /* Target ID */
+ path_id_t path_id; /* System SCSI bus number */
+ u_int16_t pd_type; /* type of peripheral device */
+ struct scsi_inquiry_data inq_data; /* SCSI Inquiry data */
+ u_int8_t serial_num[252]; /* device serial number */
+ u_int8_t serial_num_len; /* length of the serial number */
+ u_int8_t sync_period; /* Negotiated sync period */
+ u_int8_t sync_offset; /* Negotiated sync offset */
+ u_int8_t bus_width; /* Negotiated bus width */
+ int fd; /* file descriptor for device */
+};
+
+__BEGIN_DECLS
+/* Basic utility commands */
+struct cam_device * cam_open_device(const char *path, int flags);
+void cam_close_device(struct cam_device *dev);
+void cam_close_spec_device(struct cam_device *dev);
+struct cam_device * cam_open_spec_device(const char *dev_name,
+ int unit, int flags,
+ struct cam_device *device);
+struct cam_device * cam_open_btl(path_id_t path_id, target_id_t target_id,
+ lun_id_t target_lun, int flags,
+ struct cam_device *device);
+struct cam_device * cam_open_pass(const char *path, int flags,
+ struct cam_device *device);
+union ccb * cam_getccb(struct cam_device *dev);
+void cam_freeccb(union ccb *ccb);
+int cam_send_ccb(struct cam_device *device, union ccb *ccb);
+char * cam_path_string(struct cam_device *dev, char *str,
+ int len);
+struct cam_device * cam_device_dup(struct cam_device *device);
+void cam_device_copy(struct cam_device *src,
+ struct cam_device *dst);
+int cam_get_device(const char *path, char *dev_name,
+ int devnamelen, int *unit);
+
+/*
+ * Buffer encoding/decoding routines, from the old SCSI library.
+ */
+int csio_decode(struct ccb_scsiio *csio, char *fmt, ...);
+int csio_decode_visit(struct ccb_scsiio *csio, char *fmt,
+ void (*arg_put)(void *, int, void *, int, char *),
+ void *puthook);
+int buff_decode(u_int8_t *buff, size_t len, char *fmt, ...);
+int buff_decode_visit(u_int8_t *buff, size_t len, char *fmt,
+ void (*arg_put)(void *, int, void *, int, char *),
+ void *puthook);
+int csio_build(struct ccb_scsiio *csio, u_int8_t *data_ptr,
+ u_int32_t dxfer_len, u_int32_t flags, int retry_count,
+ int timeout, char *cmd_spec, ...);
+int csio_build_visit(struct ccb_scsiio *csio, u_int8_t *data_ptr,
+ u_int32_t dxfer_len, u_int32_t flags, int retry_count,
+ int timeout, char *cmd_spec,
+ int (*arg_get)(void *hook, char *field_name),
+ void *gethook);
+int csio_encode(struct ccb_scsiio *csio, char *fmt, ...);
+int buff_encode_visit(u_int8_t *buff, size_t len, char *fmt,
+ int (*arg_get)(void *hook, char *field_name),
+ void *gethook);
+int csio_encode_visit(struct ccb_scsiio *csio, char *fmt,
+ int (*arg_get)(void *hook, char *field_name),
+ void *gethook);
+__END_DECLS
+
+#endif /* _CAMLIB_H */
diff --git a/lib/libcam/scsi_cmdparse.c b/lib/libcam/scsi_cmdparse.c
new file mode 100644
index 0000000..ad1cbb0
--- /dev/null
+++ b/lib/libcam/scsi_cmdparse.c
@@ -0,0 +1,827 @@
+/*
+ * Taken from the original FreeBSD user SCSI library.
+ */
+/* Copyright (c) 1994 HD Associates
+ * (contact: dufault@hda.com)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by HD Associates
+ * 4. Neither the name of the HD Associaates nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * From: scsi.c,v 1.8 1997/02/22 15:07:54 peter Exp $
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/errno.h>
+#include <stdarg.h>
+#include <fcntl.h>
+
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+#include <cam/scsi/scsi_message.h>
+#include "camlib.h"
+
+/*
+ * Decode: Decode the data section of a scsireq. This decodes
+ * trivial grammar:
+ *
+ * fields : field fields
+ * ;
+ *
+ * field : field_specifier
+ * | control
+ * ;
+ *
+ * control : 's' seek_value
+ * | 's' '+' seek_value
+ * ;
+ *
+ * seek_value : DECIMAL_NUMBER
+ * | 'v' // For indirect seek, i.e., value from the arg list
+ * ;
+ *
+ * field_specifier : type_specifier field_width
+ * | '{' NAME '}' type_specifier field_width
+ * ;
+ *
+ * field_width : DECIMAL_NUMBER
+ * ;
+ *
+ * type_specifier : 'i' // Integral types (i1, i2, i3, i4)
+ * | 'b' // Bits
+ * | 't' // Bits
+ * | 'c' // Character arrays
+ * | 'z' // Character arrays with zeroed trailing spaces
+ * ;
+ *
+ * Notes:
+ * 1. Integral types are swapped into host order.
+ * 2. Bit fields are allocated MSB to LSB to match the SCSI spec documentation.
+ * 3. 's' permits "seeking" in the string. "s+DECIMAL" seeks relative to
+ * DECIMAL; "sDECIMAL" seeks absolute to decimal.
+ * 4. 's' permits an indirect reference. "sv" or "s+v" will get the
+ * next integer value from the arg array.
+ * 5. Field names can be anything between the braces
+ *
+ * BUGS:
+ * i and b types are promoted to ints.
+ *
+ */
+
+static int
+do_buff_decode(u_int8_t *databuf, size_t len,
+ void (*arg_put)(void *, int , void *, int, char *),
+ void *puthook, char *fmt, va_list ap)
+{
+ int assigned = 0;
+ int width;
+ int suppress;
+ int plus;
+ int done = 0;
+ static u_char mask[] = {0, 0x01, 0x03, 0x07, 0x0f,
+ 0x1f, 0x3f, 0x7f, 0xff};
+ int value;
+ u_char *base = databuf;
+ char letter;
+ char field_name[80];
+
+# define ARG_PUT(ARG) \
+ do \
+ { \
+ if (!suppress) \
+ { \
+ if (arg_put) \
+ (*arg_put)(puthook, (letter == 't' ? \
+ 'b' : letter), \
+ (void *)((long)(ARG)), 1, field_name); \
+ else \
+ *(va_arg(ap, int *)) = (ARG); \
+ assigned++; \
+ } \
+ field_name[0] = 0; \
+ suppress = 0; \
+ } while (0)
+
+ u_char bits = 0; /* For bit fields */
+ int shift = 0; /* Bits already shifted out */
+ suppress = 0;
+ field_name[0] = 0;
+
+ while (!done) {
+ switch(letter = *fmt) {
+ case ' ': /* White space */
+ case '\t':
+ case '\r':
+ case '\n':
+ case '\f':
+ fmt++;
+ break;
+
+ case '#': /* Comment */
+ while (*fmt && (*fmt != '\n'))
+ fmt++;
+ if (fmt)
+ fmt++; /* Skip '\n' */
+ break;
+
+ case '*': /* Suppress assignment */
+ fmt++;
+ suppress = 1;
+ break;
+
+ case '{': /* Field Name */
+ {
+ int i = 0;
+ fmt++; /* Skip '{' */
+ while (*fmt && (*fmt != '}')) {
+ if (i < sizeof(field_name))
+ field_name[i++] = *fmt;
+
+ fmt++;
+ }
+ if (fmt)
+ fmt++; /* Skip '}' */
+ field_name[i] = 0;
+ break;
+ }
+
+ case 't': /* Bit (field) */
+ case 'b': /* Bits */
+ fmt++;
+ width = strtol(fmt, &fmt, 10);
+ if (width > 8)
+ done = 1;
+ else {
+ if (shift <= 0) {
+ bits = *databuf++;
+ shift = 8;
+ }
+ value = (bits >> (shift - width)) &
+ mask[width];
+
+#if 0
+ printf("shift %2d bits %02x value %02x width %2d mask %02x\n",
+ shift, bits, value, width, mask[width]);
+#endif
+
+ ARG_PUT(value);
+
+ shift -= width;
+ }
+ break;
+
+ case 'i': /* Integral values */
+ shift = 0;
+ fmt++;
+ width = strtol(fmt, &fmt, 10);
+ switch(width) {
+ case 1:
+ ARG_PUT(*databuf);
+ databuf++;
+ break;
+
+ case 2:
+ ARG_PUT((*databuf) << 8 | *(databuf + 1));
+ databuf += 2;
+ break;
+
+ case 3:
+ ARG_PUT((*databuf) << 16 |
+ (*(databuf + 1)) << 8 | *(databuf + 2));
+ databuf += 3;
+ break;
+
+ case 4:
+ ARG_PUT((*databuf) << 24 |
+ (*(databuf + 1)) << 16 |
+ (*(databuf + 2)) << 8 |
+ *(databuf + 3));
+ databuf += 4;
+ break;
+
+ default:
+ done = 1;
+ break;
+ }
+
+ break;
+
+ case 'c': /* Characters (i.e., not swapped) */
+ case 'z': /* Characters with zeroed trailing
+ spaces */
+ shift = 0;
+ fmt++;
+ width = strtol(fmt, &fmt, 10);
+ if (!suppress) {
+ if (arg_put)
+ (*arg_put)(puthook,
+ (letter == 't' ? 'b' : letter),
+ databuf, width, field_name);
+ else {
+ char *dest;
+ dest = va_arg(ap, char *);
+ bcopy(databuf, dest, width);
+ if (letter == 'z') {
+ char *p;
+ for (p = dest + width - 1;
+ (p >= (char *)dest)
+ && (*p == ' '); p--)
+ *p = 0;
+ }
+ }
+ assigned++;
+ }
+ databuf += width;
+ field_name[0] = 0;
+ suppress = 0;
+ break;
+
+ case 's': /* Seek */
+ shift = 0;
+ fmt++;
+ if (*fmt == '+') {
+ plus = 1;
+ fmt++;
+ } else
+ plus = 0;
+
+ if (tolower(*fmt) == 'v') {
+ /*
+ * You can't suppress a seek value. You also
+ * can't have a variable seek when you are using
+ * "arg_put".
+ */
+ width = (arg_put) ? 0 : va_arg(ap, int);
+ fmt++;
+ } else
+ width = strtol(fmt, &fmt, 10);
+
+ if (plus)
+ databuf += width; /* Relative seek */
+ else
+ databuf = base + width; /* Absolute seek */
+
+ break;
+
+ case 0:
+ done = 1;
+ break;
+
+ default:
+ fprintf(stderr, "Unknown letter in format: %c\n",
+ letter);
+ fmt++;
+ break;
+ }
+ }
+
+ return (assigned);
+}
+
+/* next_field: Return the next field in a command specifier. This
+ * builds up a SCSI command using this trivial grammar:
+ *
+ * fields : field fields
+ * ;
+ *
+ * field : value
+ * | value ':' field_width
+ * ;
+ *
+ * field_width : digit
+ * | 'i' digit // i2 = 2 byte integer, i3 = 3 byte integer etc.
+ * ;
+ *
+ * value : HEX_NUMBER
+ * | 'v' // For indirection.
+ * ;
+ *
+ * Notes:
+ * Bit fields are specified MSB first to match the SCSI spec.
+ *
+ * Examples:
+ * TUR: "0 0 0 0 0 0"
+ * WRITE BUFFER: "38 v:3 0:2 0:3 v v:i3 v:i3 0", mode, buffer_id, list_length
+ *
+ * The function returns the value:
+ * 0: For reached end, with error_p set if an error was found
+ * 1: For valid stuff setup
+ * 2: For "v" was entered as the value (implies use varargs)
+ *
+ */
+
+static int
+next_field(char **pp, char *fmt, int *width_p, int *value_p, char *name,
+ int n_name, int *error_p, int *suppress_p)
+{
+ char *p = *pp;
+
+ int something = 0;
+
+ enum {
+ BETWEEN_FIELDS,
+ START_FIELD,
+ GET_FIELD,
+ DONE,
+ } state;
+
+ int value = 0;
+ int field_size; /* Default to byte field type... */
+ int field_width; /* 1 byte wide */
+ int is_error = 0;
+ int suppress = 0;
+
+ field_size = 8; /* Default to byte field type... */
+ *fmt = 'i';
+ field_width = 1; /* 1 byte wide */
+ if (name)
+ *name = 0;
+
+ state = BETWEEN_FIELDS;
+
+ while (state != DONE) {
+ switch(state) {
+ case BETWEEN_FIELDS:
+ if (*p == 0)
+ state = DONE;
+ else if (isspace(*p))
+ p++;
+ else if (*p == '#') {
+ while (*p && *p != '\n')
+ p++;
+ if (p)
+ p++;
+ } else if (*p == '{') {
+ int i = 0;
+
+ p++;
+
+ while (*p && *p != '}') {
+ if(name && i < n_name) {
+ name[i] = *p;
+ i++;
+ }
+ p++;
+ }
+
+ if(name && i < n_name)
+ name[i] = 0;
+
+ if (*p == '}')
+ p++;
+ } else if (*p == '*') {
+ p++;
+ suppress = 1;
+ } else if (isxdigit(*p)) {
+ something = 1;
+ value = strtol(p, &p, 16);
+ state = START_FIELD;
+ } else if (tolower(*p) == 'v') {
+ p++;
+ something = 2;
+ value = *value_p;
+ state = START_FIELD;
+ } else if (tolower(*p) == 'i') {
+ /*
+ * Try to work without the "v".
+ */
+ something = 2;
+ value = *value_p;
+ p++;
+
+ *fmt = 'i';
+ field_size = 8;
+ field_width = strtol(p, &p, 10);
+ state = DONE;
+
+ } else if (tolower(*p) == 't') {
+ /*
+ * XXX: B can't work: Sees the 'b' as a
+ * hex digit in "isxdigit". try "t" for
+ * bit field.
+ */
+ something = 2;
+ value = *value_p;
+ p++;
+
+ *fmt = 'b';
+ field_size = 1;
+ field_width = strtol(p, &p, 10);
+ state = DONE;
+ } else if (tolower(*p) == 's') {
+ /* Seek */
+ *fmt = 's';
+ p++;
+ if (tolower(*p) == 'v') {
+ p++;
+ something = 2;
+ value = *value_p;
+ } else {
+ something = 1;
+ value = strtol(p, &p, 0);
+ }
+ state = DONE;
+ } else {
+ fprintf(stderr, "Invalid starting "
+ "character: %c\n", *p);
+ is_error = 1;
+ state = DONE;
+ }
+ break;
+
+ case START_FIELD:
+ if (*p == ':') {
+ p++;
+ field_size = 1; /* Default to bits
+ when specified */
+ state = GET_FIELD;
+ } else
+ state = DONE;
+ break;
+
+ case GET_FIELD:
+ if (isdigit(*p)) {
+ *fmt = 'b';
+ field_size = 1;
+ field_width = strtol(p, &p, 10);
+ state = DONE;
+ } else if (*p == 'i') {
+
+ /* Integral (bytes) */
+ p++;
+
+ *fmt = 'i';
+ field_size = 8;
+ field_width = strtol(p, &p, 10);
+ state = DONE;
+ } else if (*p == 'b') {
+
+ /* Bits */
+ p++;
+
+ *fmt = 'b';
+ field_size = 1;
+ field_width = strtol(p, &p, 10);
+ state = DONE;
+ } else {
+ fprintf(stderr, "Invalid startfield %c "
+ "(%02x)\n", *p, *p);
+ is_error = 1;
+ state = DONE;
+ }
+ break;
+
+ case DONE:
+ break;
+ }
+ }
+
+ if (is_error) {
+ *error_p = 1;
+ return 0;
+ }
+
+ *error_p = 0;
+ *pp = p;
+ *width_p = field_width * field_size;
+ *value_p = value;
+ *suppress_p = suppress;
+
+ return (something);
+}
+
+static int
+do_encode(u_char *buff, size_t vec_max, size_t *used,
+ int (*arg_get)(void *, char *), void *gethook, char *fmt, va_list ap)
+{
+ int ind;
+ int shift;
+ u_char val;
+ int ret;
+ int width, value, error, suppress;
+ char c;
+ int encoded = 0;
+ char field_name[80];
+
+ ind = 0;
+ shift = 0;
+ val = 0;
+
+ while ((ret = next_field(&fmt, &c, &width, &value, field_name,
+ sizeof(field_name), &error, &suppress))) {
+ encoded++;
+
+ if (ret == 2) {
+ if (suppress)
+ value = 0;
+ else
+ value = arg_get ?
+ (*arg_get)(gethook, field_name) :
+ va_arg(ap, int);
+ }
+
+#if 0
+ printf(
+"do_encode: ret %d fmt %c width %d value %d name \"%s\" error %d suppress %d\n",
+ ret, c, width, value, field_name, error, suppress);
+#endif
+ /* Absolute seek */
+ if (c == 's') {
+ ind = value;
+ continue;
+ }
+
+ /* A width of < 8 is a bit field. */
+ if (width < 8) {
+
+ /* This is a bit field. We start with the high bits
+ * so it reads the same as the SCSI spec.
+ */
+
+ shift += width;
+
+ val |= (value << (8 - shift));
+
+ if (shift == 8) {
+ if (ind < vec_max) {
+ buff[ind++] = val;
+ val = 0;
+ }
+ shift = 0;
+ }
+ } else {
+ if (shift) {
+ if (ind < vec_max) {
+ buff[ind++] = val;
+ val = 0;
+ }
+ shift = 0;
+ }
+ switch(width) {
+ case 8: /* 1 byte integer */
+ if (ind < vec_max)
+ buff[ind++] = value;
+ break;
+
+ case 16: /* 2 byte integer */
+ if (ind < vec_max - 2 + 1) {
+ buff[ind++] = value >> 8;
+ buff[ind++] = value;
+ }
+ break;
+
+ case 24: /* 3 byte integer */
+ if (ind < vec_max - 3 + 1) {
+ buff[ind++] = value >> 16;
+ buff[ind++] = value >> 8;
+ buff[ind++] = value;
+ }
+ break;
+
+ case 32: /* 4 byte integer */
+ if (ind < vec_max - 4 + 1) {
+ buff[ind++] = value >> 24;
+ buff[ind++] = value >> 16;
+ buff[ind++] = value >> 8;
+ buff[ind++] = value;
+ }
+ break;
+
+ default:
+ fprintf(stderr, "do_encode: Illegal width\n");
+ break;
+ }
+ }
+ }
+
+ /* Flush out any remaining bits
+ */
+ if (shift && ind < vec_max) {
+ buff[ind++] = val;
+ val = 0;
+ }
+
+
+ if (used)
+ *used = ind;
+
+ if (error)
+ return -1;
+
+ return encoded;
+}
+
+int
+csio_decode(struct ccb_scsiio *csio, char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ return(do_buff_decode(csio->data_ptr, (size_t)csio->dxfer_len,
+ 0, 0, fmt, ap));
+}
+
+int
+csio_decode_visit(struct ccb_scsiio *csio, char *fmt,
+ void (*arg_put)(void *, int, void *, int, char *),
+ void *puthook)
+{
+ va_list ap;
+
+ /*
+ * We need some way to output things; we can't do it without
+ * the arg_put function.
+ */
+ if (arg_put == NULL)
+ return(-1);
+
+ bzero(&ap, sizeof(ap));
+
+ return(do_buff_decode(csio->data_ptr, (size_t)csio->dxfer_len,
+ arg_put, puthook, fmt, ap));
+}
+
+int
+buff_decode(u_int8_t *buff, size_t len, char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ return(do_buff_decode(buff, len, 0, 0, fmt, ap));
+}
+
+int
+buff_decode_visit(u_int8_t *buff, size_t len, char *fmt,
+ void (*arg_put)(void *, int, void *, int, char *),
+ void *puthook)
+{
+ va_list ap;
+
+ /*
+ * We need some way to output things; we can't do it without
+ * the arg_put function.
+ */
+ if (arg_put == NULL)
+ return(-1);
+
+ bzero(&ap, sizeof(ap));
+
+ return(do_buff_decode(buff, len, arg_put, puthook, fmt, ap));
+}
+
+/*
+ * Build a SCSI CCB, given the command and data pointers and a format
+ * string describing the
+ */
+int
+csio_build(struct ccb_scsiio *csio, u_int8_t *data_ptr, u_int32_t dxfer_len,
+ u_int32_t flags, int retry_count, int timeout, char *cmd_spec, ...)
+{
+ size_t cmdlen;
+ int retval;
+ va_list ap;
+
+ if (csio == NULL)
+ return(0);
+
+ bzero(csio, sizeof(struct ccb_scsiio));
+
+ va_start(ap, cmd_spec);
+
+ if ((retval = do_encode(csio->cdb_io.cdb_bytes, SCSI_MAX_CDBLEN,
+ &cmdlen, NULL, NULL, cmd_spec, ap)) == -1)
+ return(retval);
+
+ cam_fill_csio(csio,
+ /* retries */ retry_count,
+ /* cbfcnp */ NULL,
+ /* flags */ flags,
+ /* tag_action */ MSG_SIMPLE_Q_TAG,
+ /* data_ptr */ data_ptr,
+ /* dxfer_len */ dxfer_len,
+ /* sense_len */ SSD_FULL_SIZE,
+ /* cdb_len */ cmdlen,
+ /* timeout */ timeout ? timeout : 5000);
+
+ return(retval);
+}
+
+int
+csio_build_visit(struct ccb_scsiio *csio, u_int8_t *data_ptr,
+ u_int32_t dxfer_len, u_int32_t flags, int retry_count,
+ int timeout, char *cmd_spec,
+ int (*arg_get)(void *hook, char *field_name), void *gethook)
+{
+ va_list ap;
+ size_t cmdlen;
+ int retval;
+
+ if (csio == NULL)
+ return(0);
+
+ /*
+ * We need something to encode, but we can't get it without the
+ * arg_get function.
+ */
+ if (arg_get == NULL)
+ return(-1);
+
+ bzero(&ap, sizeof(ap));
+
+ bzero(csio, sizeof(struct ccb_scsiio));
+
+ if ((retval = do_encode(csio->cdb_io.cdb_bytes, SCSI_MAX_CDBLEN,
+ &cmdlen, arg_get, gethook, cmd_spec, ap)) == -1)
+ return(retval);
+
+ cam_fill_csio(csio,
+ /* retries */ retry_count,
+ /* cbfcnp */ NULL,
+ /* flags */ flags,
+ /* tag_action */ MSG_SIMPLE_Q_TAG,
+ /* data_ptr */ data_ptr,
+ /* dxfer_len */ dxfer_len,
+ /* sense_len */ SSD_FULL_SIZE,
+ /* cdb_len */ cmdlen,
+ /* timeout */ timeout ? timeout : 5000);
+
+ return(retval);
+}
+
+int
+csio_encode(struct ccb_scsiio *csio, char *fmt, ...)
+{
+ va_list ap;
+
+ if (csio == NULL)
+ return(0);
+
+ va_start(ap, fmt);
+
+ return(do_encode(csio->data_ptr, csio->dxfer_len, 0, 0, 0, fmt, ap));
+}
+
+int
+buff_encode_visit(u_int8_t *buff, size_t len, char *fmt,
+ int (*arg_get)(void *hook, char *field_name), void *gethook)
+{
+ va_list ap;
+
+ /*
+ * We need something to encode, but we can't get it without the
+ * arg_get function.
+ */
+ if (arg_get == NULL)
+ return(-1);
+
+ bzero(&ap, sizeof(ap));
+
+ return(do_encode(buff, len, 0, arg_get, gethook, fmt, ap));
+}
+
+int
+csio_encode_visit(struct ccb_scsiio *csio, char *fmt,
+ int (*arg_get)(void *hook, char *field_name), void *gethook)
+{
+ va_list ap;
+
+ /*
+ * We need something to encode, but we can't get it without the
+ * arg_get function.
+ */
+ if (arg_get == NULL)
+ return(-1);
+
+ bzero(&ap, sizeof(ap));
+
+ return(do_encode(csio->data_ptr, csio->dxfer_len, 0, arg_get,
+ gethook, fmt, ap));
+}
diff --git a/lib/libcom_err/Makefile b/lib/libcom_err/Makefile
new file mode 100644
index 0000000..847497d
--- /dev/null
+++ b/lib/libcom_err/Makefile
@@ -0,0 +1,18 @@
+# $FreeBSD$
+
+LIB= com_err
+SRCS= com_err.c error.c
+MAN3= com_err.3
+COM_ERRDIR= ${.CURDIR}/../../contrib/com_err
+CFLAGS+= -I${COM_ERRDIR}
+
+SUBDIR= doc
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${COM_ERRDIR}/com_err.h ${COM_ERRDIR}/com_right.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
+
+.PATH: ${COM_ERRDIR}
diff --git a/lib/libcom_err/doc/Makefile b/lib/libcom_err/doc/Makefile
new file mode 100644
index 0000000..4c3c0bb
--- /dev/null
+++ b/lib/libcom_err/doc/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+INFO= com_err
+INFOSECTION= "Programming & development tools."
+INFOENTRY_com_err= "* libcom_err: (com_err). A Common Error Description Library for UNIX."
+
+.include <bsd.info.mk>
diff --git a/lib/libcom_err/doc/com_err.texinfo b/lib/libcom_err/doc/com_err.texinfo
new file mode 100644
index 0000000..6c71da8
--- /dev/null
+++ b/lib/libcom_err/doc/com_err.texinfo
@@ -0,0 +1,615 @@
+\input texinfo @c -*-texinfo-*-
+
+@c $FreeBSD$
+
+@c Note that although this source file is in texinfo format (more
+@c or less), it is not yet suitable for turning into an ``info''
+@c file. Sorry, maybe next time.
+@c
+@c In order to produce hardcopy documentation from a texinfo file,
+@c run ``tex com_err.texinfo'' which will load in texinfo.tex,
+@c provided in this distribution. (texinfo.tex is from the Free
+@c Software Foundation, and is under different copyright restrictions
+@c from the rest of this package.)
+
+@ifinfo
+@barfo
+@end ifinfo
+
+@iftex
+@tolerance 10000
+
+@c Mutate section headers...
+@begingroup
+ @catcode#=6
+ @gdef@secheading#1#2#3{@secheadingi {#3@enspace #1}}
+@endgroup
+@end iftex
+
+@c %**start of header (This is for running Texinfo on a region.)
+@setfilename com_err
+@settitle A Common Error Description Library for UNIX
+@c %**end of header (This is for running Texinfo on a region.)
+
+@ifinfo
+This file documents the use of the Common Error Description library.
+
+Copyright (C) 1987, 1988 Student Information Processing Board of the
+Massachusetts Institute of Technology.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+used in advertising or publicity pertaining to distribution of the software
+without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B.
+make no representations about the suitability of this software for any
+purpose. It is provided "as is" without express or implied warranty.
+
+Note that the file texinfo.tex, provided with this distribution, is from
+the Free Software Foundation, and is under different copyright restrictions
+from the remainder of this package.
+
+@end ifinfo
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+
+@setchapternewpage odd
+
+@titlepage
+@center @titlefont{A Common Error Description}
+@center @titlefont{Library for UNIX}
+@sp 2
+@center Ken Raeburn
+@center Bill Sommerfeld
+@sp 1
+@center MIT Student Information Processing Board
+@sp 3
+@center last updated 1 January 1989
+@center for version 1.2
+@center ***DRAFT COPY ONLY***
+
+@vskip 2in
+
+@center @b{Abstract}
+
+UNIX has always had a clean and simple system call interface, with a
+standard set of error codes passed between the kernel and user
+programs. Unfortunately, the same cannot be said of many of the
+libraries layered on top of the primitives provided by the kernel.
+Typically, each one has used a different style of indicating errors to
+their callers, leading to a total hodgepodge of error handling, and
+considerable amounts of work for the programmer. This paper describes
+a library and associated utilities which allows a more uniform way for
+libraries to return errors to their callers, and for programs to
+describe errors and exceptional conditions to their users.
+
+@page
+@vskip 0pt plus 1filll
+
+Copyright @copyright{} 1987, 1988 by the Student Information Processing
+Board of the Massachusetts Institute of Technology.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+used in advertising or publicity pertaining to distribution of the software
+without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B.
+make no representations about the suitability of this software for any
+purpose. It is provided "as is" without express or implied warranty.
+
+Note that the file texinfo.tex, provided with this distribution, is from
+the Free Software Foundation, and is under different copyright restrictions
+from the remainder of this package.
+
+@end titlepage
+
+@ifinfo
+@node Top, Why com_err?, (dir), (dir)
+@comment node-name, next, previous, up
+@top General Introduction
+
+@menu
+* Why com_err?:: What is all this for?
+* Error codes:: What's an error code, anyway?
+* Error table source file:: How to describe an error table.
+* The error-table compiler:: How to compile the table.
+* Run-time support routines:: How to use from within your program.
+* Coding Conventions:: Stylistic issues.
+* Building and Installation:: How to build and install.
+* Bug Reports:: You have found a bug? Report it.
+* Acknowledgements:: Whom to thank...
+
+@end menu
+
+@end ifinfo
+
+@page
+
+@ifinfo
+@node Why com_err?, Error codes, Top, (dir)
+@comment node-name, next, previous, up
+@end ifinfo
+
+@section Why com_err?
+
+In building application software packages, a programmer often has to
+deal with a number of libraries, each of which can use a different
+error-reporting mechanism. Sometimes one of two values is returned,
+indicating simply SUCCESS or FAILURE, with no description of errors
+encountered. Sometimes it is an index into a table of text strings,
+where the name of the table used is dependent on the library being
+used when the error is generated; since each table starts numbering at
+0 or 1, additional information as to the source of the error code is
+needed to determine which table to look at. Sometimes no text messages are
+supplied at all, and the programmer must supply them at any point at which
+he may wish to report error conditions.
+Often, a global variable is assigned some value describing the error, but
+the programmer has to know in each case whether to look at @code{errno},
+@code{h_errno}, the return value from @code{hes_err()}, or whatever other
+variables or routines are specified.
+And what happens if something
+in the procedure of
+examining or reporting the error changes the same variable?
+
+The package we have developed is an attempt to present a common
+error-handling mechanism to manipulate the most common form of error code
+in a fashion that does not have the problems listed above.
+
+A list of up to 256 text messages is supplied to a translator we have
+written, along with the three- to four-character ``name'' of the error
+table. The library using this error table need only call a routine
+generated from this error-table source to make the table ``known'' to the
+com_err library, and any error code the library generates can be converted
+to the corresponding error message. There is also a default format for
+error codes accidentally returned before making the table known, which is
+of the form @samp{unknown code foo 32}, where @samp{foo} would be the name
+of the table.
+
+@ifinfo
+@node Error codes, Error table source file, Why com_err?, (dir)
+@comment node-name, next, previous, up
+@end ifinfo
+
+@section Error codes
+
+Error codes themselves are 32 bit (signed) integers, of which the high
+order 24 bits are an identifier of which error table the error code is
+from, and the low order 8 bits are a sequential error number within
+the table. An error code may thus be easily decomposed into its component
+parts. Only the lowest 32 bits of an error code are considered significant
+on systems which support wider values.
+
+Error table 0 is defined to match the UNIX system call error table
+(@code{sys_errlist}); this allows @code{errno} values to be used directly
+in the library (assuming that @code{errno} is of a type with the same width
+as @t{long}). Other error table numbers are formed by compacting together
+the first four characters of the error table name. The mapping between
+characters in the name and numeric values in the error code are defined in
+a system-independent fashion, so that two systems that can pass integral
+values between them can reliably pass error codes without loss of meaning;
+this should work even if the character sets used are not the same.
+(However, if this is to be done, error table 0 should be avoided, since the
+local system call error tables may differ.)
+
+Any variable which is to contain an error code should be declared @t{long}.
+The draft proposed American National Standard for C (as of May, 1988)
+requires that @t{long} variables be at least 32 bits; any system which does
+not support 32-bit @t{long} values cannot make use of this package (nor
+much other software that assumes an ANSI-C environment base) without
+significant effort.
+
+@ifinfo
+@node Error table source file, The error-table compiler, Error codes, (dir)
+@comment node-name, next, previous, up
+@end ifinfo
+
+@section Error table source file
+
+The error table source file begins with the declaration of the table name,
+as
+
+@example
+error_table @var{tablename}
+@end example
+
+Individual error codes are
+specified with
+
+@example
+error_code @var{ERROR_NAME}, @var{"text message"}
+@end example
+
+where @samp{ec} can also be used as a short form of @samp{error_code}. To
+indicate the end of the table, use @samp{end}. Thus, a (short) sample
+error table might be:
+
+@example
+
+ error_table dsc
+
+ error_code DSC_DUP_MTG_NAME,
+ "Meeting already exists"
+
+ ec DSC_BAD_PATH,
+ "A bad meeting pathname was given"
+
+ ec DSC_BAD_MODES,
+ "Invalid mode for this access control list"
+
+ end
+
+@end example
+
+@ifinfo
+@node The error-table compiler, Run-time support routines, Error table source file, (dir)
+@comment node-name, next, previous, up
+@end ifinfo
+
+@section The error-table compiler
+
+The error table compiler is named @code{compile_et}. It takes one
+argument, the pathname of a file (ending in @samp{.et}, e.g.,
+@samp{dsc_err.et}) containing an error table source file. It parses the
+error table, and generates two output files -- a C header file
+(@samp{discuss_err.h}) which contains definitions of the numerical values
+of the error codes defined in the error table, and a C source file which
+should be compiled and linked with the executable. The header file must be
+included in the source of a module which wishes to reference the error
+codes defined; the object module generated from the C code may be linked in
+to a program which wishes to use the printed forms of the error codes.
+
+This translator accepts a @kbd{-language @var{lang}} argument, which
+determines for which language (or language variant) the output should be
+written. At the moment, @var{lang} is currently limited to @kbd{ANSI-C}
+and @kbd{K&R-C}, and some abbreviated forms of each. Eventually, this will
+be extended to include some support for C++. The default is currently
+@kbd{K&R-C}, though the generated sources will have ANSI-C code
+conditionalized on the symbol @t{__STDC__}.
+
+@ifinfo
+@node Run-time support routines, Coding Conventions, The error-table compiler, (dir)
+@comment node-name, next, previous, up
+@end ifinfo
+
+@section Run-time support routines
+
+Any source file which uses the routines supplied with or produced by the
+com_err package should include the header file @file{<com_err.h>}. It
+contains declarations and definitions which may be needed on some systems.
+(Some functions cannot be referenced properly without the return type
+declarations in this file. Some functions may work properly on most
+architectures even without the header file, but relying on this is not
+recommended.)
+
+The run-time support routines and variables provided via this package
+include the following:
+
+@example
+void initialize_@var{xxxx}_error_table (void);
+@end example
+
+One of these routines is built by the error compiler for each error table.
+It makes the @var{xxxx} error table ``known'' to the error reporting
+system. By convention, this routine should be called in the initialization
+routine of the @var{xxxx} library. If the library has no initialization
+routine, some combination of routines which form the core of the library
+should ensure that this routine is called. It is not advised to leave it
+the caller to make this call.
+
+There is no harm in calling this routine more than once.
+
+@example
+#define ERROR_TABLE_BASE_@var{xxxx} @var{nnnnn}L
+@end example
+
+This symbol contains the value of the first error code entry in the
+specified table.
+This rarely needs be used by the
+programmer.
+
+@example
+const char *error_message (long code);
+@end example
+
+This routine returns the character string error message associated
+with @code{code}; if this is associated with an unknown error table, or
+if the code is associated with a known error table but the code is not
+in the table, a string of the form @samp{Unknown code @var{xxxx nn}} is
+returned, where @var{xxxx} is the error table name produced by
+reversing the compaction performed on the error table number implied
+by that error code, and @var{nn} is the offset from that base value.
+
+Although this routine is available for use when needed, its use should be
+left to circumstances which render @code{com_err} (below) unusable.
+
+@example
+void com_err (const char *whoami, /* module reporting error */
+ long code, /* error code */
+ const char *format, /* format for additional detail */
+ ...); /* (extra parameters) */
+@end example
+
+This routine provides an alternate way to print error messages to
+standard error; it allows the error message to be passed in as a
+parameter, rather than in an external variable. @emph{Provide grammatical
+context for ``message.''}
+
+If @var{format} is @code{(char *)NULL}, the formatted message will not be
+printed. @var{format} may not be omitted.
+
+@example
+#include <stdarg.h>
+
+void com_err_va (const char *whoami,
+ long code,
+ const char *format,
+ va_list args);
+@end example
+
+This routine provides an interface, equivalent to @code{com_err} above,
+which may be used by higher-level variadic functions (functions which
+accept variable numbers of arguments).
+
+@example
+#include <stdarg.h>
+
+void (*set_com_err_hook (void (*proc) ())) ();
+
+void (*@var{proc}) (const char *whoami, long code, va_list args);
+
+void reset_com_err_hook ();
+@end example
+
+These two routines allow a routine to be dynamically substituted for
+@samp{com_err}. After @samp{set_com_err_hook} has been called,
+calls to @samp{com_err} will turn into calls to the new hook routine.
+@samp{reset_com_err_hook} turns off this hook. This may intended to
+be used in daemons (to use a routine which calls @var{syslog(3)}), or
+in a window system application (which could pop up a dialogue box).
+
+If a program is to be used in an environment in which simply printing
+messages to the @code{stderr} stream would be inappropriate (such as in a
+daemon program which runs without a terminal attached),
+@code{set_com_err_hook} may be used to redirect output from @code{com_err}.
+The following is an example of an error handler which uses @var{syslog(3)}
+as supplied in BSD 4.3:
+
+@example
+#include <stdio.h>
+#include <stdarg.h>
+#include <syslog.h>
+
+/* extern openlog (const char * name, int logopt, int facility); */
+/* extern syslog (int priority, char * message, ...); */
+
+void hook (const char * whoami, long code,
+ const char * format, va_list args)
+@{
+ char buffer[BUFSIZ];
+ static int initialized = 0;
+ if (!initialized) @{
+ openlog (whoami,
+ LOG_NOWAIT|LOG_CONS|LOG_PID|LOG_NDELAY,
+ LOG_DAEMON);
+ initialized = 1;
+ @}
+ vsprintf (buffer, format, args);
+ syslog (LOG_ERR, "%s %s", error_message (code), buffer);
+@}
+@end example
+
+After making the call
+@code{set_com_err_hook (hook);},
+any calls to @code{com_err} will result in messages being sent to the
+@var{syslogd} daemon for logging.
+The name of the program, @samp{whoami}, is supplied to the
+@samp{openlog()} call, and the message is formatted into a buffer and
+passed to @code{syslog}.
+
+Note that since the extra arguments to @code{com_err} are passed by
+reference via the @code{va_list} value @code{args}, the hook routine may
+place any form of interpretation on them, including ignoring them. For
+consistency, @code{printf}-style interpretation is suggested, via
+@code{vsprintf} (or @code{_doprnt} on BSD systems without full support for
+the ANSI C library).
+
+@ifinfo
+@node Coding Conventions, Building and Installation, Run-time support routines, (dir)
+@comment node-name, next, previous, up
+@end ifinfo
+
+@section Coding Conventions
+
+The following conventions are just some general stylistic conventions
+to follow when writing robust libraries and programs. Conventions
+similar to this are generally followed inside the UNIX kernel and most
+routines in the Multics operating system. In general, a routine
+either succeeds (returning a zero error code, and doing some side
+effects in the process), or it fails, doing minimal side effects; in
+any event, any invariant which the library assumes must be maintained.
+
+In general, it is not in the domain of non user-interface library
+routines to write error messages to the user's terminal, or halt the
+process. Such forms of ``error handling'' should be reserved for
+failures of internal invariants and consistancy checks only, as it
+provides the user of the library no way to clean up for himself in the
+event of total failure.
+
+Library routines which can fail should be set up to return an error
+code. This should usually be done as the return value of the
+function; if this is not acceptable, the routine should return a
+``null'' value, and put the error code into a parameter passed by
+reference.
+
+Routines which use the first style of interface can be used from
+user-interface levels of a program as follows:
+
+@example
+@{
+ if ((code = initialize_world(getuid(), random())) != 0) @{
+ com_err("demo", code,
+ "when trying to initialize world");
+ exit(1);
+ @}
+ if ((database = open_database("my_secrets", &code))==NULL) @{
+ com_err("demo", code,
+ "while opening my_secrets");
+ exit(1);
+ @}
+@}
+@end example
+
+A caller which fails to check the return status is in error. It is
+possible to look for code which ignores error returns by using lint;
+look for error messages of the form ``foobar returns value which is
+sometimes ignored'' or ``foobar returns value which is always
+ignored.''
+
+Since libraries may be built out of other libraries, it is often necessary
+for the success of one routine to depend on another. When a lower level
+routine returns an error code, the middle level routine has a few possible
+options. It can simply return the error code to its caller after doing
+some form of cleanup, it can substitute one of its own, or it can take
+corrective action of its own and continue normally. For instance, a
+library routine which makes a ``connect'' system call to make a network
+connection may reflect the system error code @code{ECONNREFUSED}
+(Connection refused) to its caller, or it may return a ``server not
+available, try again later,'' or it may try a different server.
+
+Cleanup which is typically necessary may include, but not be limited
+to, freeing allocated memory which will not be needed any more,
+unlocking concurrancy locks, dropping reference counts, closing file
+descriptors, or otherwise undoing anything which the procedure did up
+to this point. When there are a lot of things which can go wrong, it
+is generally good to write one block of error-handling code which is
+branched to, using a goto, in the event of failure. A common source
+of errors in UNIX programs is failing to close file descriptors on
+error returns; this leaves a number of ``zombied'' file descriptors
+open, which eventually causes the process to run out of file
+descriptors and fall over.
+
+@example
+@{
+ FILE *f1=NULL, *f2=NULL, *f3=NULL;
+ int status = 0;
+
+ if ( (f1 = fopen(FILE1, "r")) == NULL) @{
+ status = errno;
+ goto error;
+ @}
+
+ /*
+ * Crunch for a while
+ */
+
+ if ( (f2 = fopen(FILE2, "w")) == NULL) @{
+ status = errno;
+ goto error;
+ @}
+
+ if ( (f3 = fopen(FILE3, "a+")) == NULL) @{
+ status = errno;
+ goto error;
+ @}
+
+ /*
+ * Do more processing.
+ */
+ fclose(f1);
+ fclose(f2);
+ fclose(f3);
+ return 0;
+
+error:
+ if (f1) fclose(f1);
+ if (f2) fclose(f2);
+ if (f3) fclose(f3);
+ return status;
+@}
+@end example
+
+@ifinfo
+@node Building and Installation, Bug Reports, Coding Conventions, (dir)
+@comment node-name, next, previous, up
+@end ifinfo
+
+@section Building and Installation
+
+The distribution of this package will probably be done as a compressed
+``tar''-format file available via anonymous FTP from SIPB.MIT.EDU.
+Retrieve @samp{pub/com_err.tar.Z} and extract the contents. A subdirectory
+@t{profiled} should be created to hold objects compiled for profiling.
+Running ``make all'' should then be sufficient to build the library and
+error-table compiler. The files @samp{libcom_err.a},
+@samp{libcom_err_p.a}, @samp{com_err.h}, and @samp{compile_et} should be
+installed for use; @samp{com_err.3} and @samp{compile_et.1} can also be
+installed as manual pages.
+
+Potential problems:
+
+@itemize @bullet
+
+@item Use of @code{strcasecmp}, a routine provided in BSD for
+case-insensitive string comparisons. If an equivalent routine is
+available, you can modify @code{CFLAGS} in the makefile to define
+@code{strcasecmp} to the name of that routine.
+
+@item Compilers that defined @code{__STDC__} without providing the header
+file @code{<stdarg.h>}. One such example is Metaware's High ``C''
+compiler, as provided at Project Athena on the IBM RT/PC workstation; if
+@code{__HIGHC__} is defined, it is assumed that @code{<stdarg.h>} is not
+available, and therefore @code{<varargs.h>} must be used. If the symbol
+@code{VARARGS} is defined (e.g., in the makefile), @code{<varargs.h>} will
+be used.
+
+@item If your linker rejects symbols that are simultaneously defined in two
+library files, edit @samp{Makefile} to remove @samp{perror.c} from the
+library. This file contains a version of @var{perror(3)} which calls
+@code{com_err} instead of calling @code{write} directly.
+
+@end itemize
+
+As I do not have access to non-BSD systems, there are probably
+bugs present that may interfere with building or using this package on
+other systems. If they are reported to me, they can probably be fixed for
+the next version.
+
+@ifinfo
+@node Bug Reports, Acknowledgements, Building and Installation, (dir)
+@comment node-name, next, previous, up
+@end ifinfo
+
+@section Bug Reports
+
+Please send any comments or bug reports to the principal author: Ken
+Raeburn, @t{Raeburn@@Athena.MIT.EDU}.
+
+@ifinfo
+@node Acknowledgements, , Bug Reports, (dir)
+@comment node-name, next, previous, up
+@end ifinfo
+
+@section Acknowledgements
+
+I would like to thank: Bill Sommerfeld, for his help with some of this
+documentation, and catching some of the bugs the first time around;
+Honeywell Information Systems, for not killing off the @emph{Multics}
+operating system before I had an opportunity to use it; Honeywell's
+customers, who persuaded them not to do so, for a while; Ted Anderson of
+CMU, for catching some problems before version 1.2 left the nest; Stan
+Zanarotti and several others of MIT's Student Information Processing Board,
+for getting us started with ``discuss,'' for which this package was
+originally written; and everyone I've talked into --- I mean, asked to read
+this document and the ``man'' pages.
+
+@bye
diff --git a/lib/libcompat/4.1/ascftime.c b/lib/libcompat/4.1/ascftime.c
new file mode 100644
index 0000000..088143c
--- /dev/null
+++ b/lib/libcompat/4.1/ascftime.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1994 Joerg Wunsch
+ *
+ * All rights reserved.
+ *
+ * This program is free software.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Joerg Wunsch
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <time.h>
+
+#define MAXLEN 1000 /* just a guess, only the user knows... */
+
+int
+#if __STDC__
+ascftime(char *s, const char *format, const struct tm *tmptr)
+#else
+ascftime(s, format, tmptr)
+ char *s;
+ char *format;
+ struct tm *tmptr;
+#endif
+{
+ return strftime(s, MAXLEN, format? format: "%C", tmptr);
+}
diff --git a/lib/libcompat/4.1/cftime.3 b/lib/libcompat/4.1/cftime.3
new file mode 100644
index 0000000..6b20797
--- /dev/null
+++ b/lib/libcompat/4.1/cftime.3
@@ -0,0 +1,99 @@
+.\"
+.\" Copyright (c) 1994, 1995 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" This program is free software.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Joerg Wunsch
+.\" 4. The name of the developer may not be used to endorse or promote
+.\" products derived from this software without specific prior written
+.\" permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 15, 1993
+.Os
+.Dt CFTIME 3
+.Sh NAME
+.Nm cftime
+.Nm ascftime
+.Nd convert date and time to string
+.Sh SYNOPSIS
+.Fd #include <time.h>
+.Ft int
+.Fn cftime "char *s" "char *format" "const time_t *clock"
+.Ft int
+.Fn ascftime "char *s" "const char *format" "const struct tm *tmptr"
+.Sh DESCRIPTION
+.Bf -symbolic
+The cftime and ascftime functions are made obsolete by strftime(3).
+.br
+They are available from the compatibility library, libcompat.
+.Ef
+.Pp
+Use of the functions
+.Nm cftime
+and
+.Nm ascftime
+is strongly deprecated, since there is no way to check for a buffer
+overflow condition. Use
+.Xr strftime 3
+instead.
+
+.Nm Ascftime
+is almost identical with
+.Xr strftime 3 ,
+with the only exception there's no parameter to tell about the
+maximal buffer length, and the
+.Fa format
+parameter defaults to
+.Dq %C
+if a
+.Em NULL
+pointer is given.
+
+.Nm Cftime
+does the same job, but it first invokes
+.Xr localtime 3
+in order to convert the given
+.Fa clock ,
+then also performs the conversions as requested by the
+.Fa format
+argument.
+
+.Sh RETURN VALUES
+The
+.Nm cftime
+and
+.Nm ascftime
+functions return the number of characters written to the output
+buffer
+.Fa s ,
+not counting the trailing null character.
+
+.Sh SEE ALSO
+.Xr localtime 3 ,
+.Xr strftime 3 .
diff --git a/lib/libcompat/4.1/cftime.c b/lib/libcompat/4.1/cftime.c
new file mode 100644
index 0000000..777055f
--- /dev/null
+++ b/lib/libcompat/4.1/cftime.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1994 Joerg Wunsch
+ *
+ * All rights reserved.
+ *
+ * This program is free software.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Joerg Wunsch
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <time.h>
+
+#define MAXLEN 1000 /* just a guess, only the user knows... */
+
+int
+#if __STDC__
+cftime(char *s, char *format, const time_t *clock)
+#else
+cftime(s, format, clock)
+ char *s;
+ char *format;
+ time_t *clock;
+#endif
+{
+ return strftime(s, MAXLEN, format? format: "%C", localtime(clock));
+}
+
diff --git a/lib/libcompat/4.1/ftime.3 b/lib/libcompat/4.1/ftime.3
new file mode 100644
index 0000000..e676a95
--- /dev/null
+++ b/lib/libcompat/4.1/ftime.3
@@ -0,0 +1,85 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ftime.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt FTIME 3
+.Os BSD 4
+.Sh NAME
+.Nm ftime
+.Nd get date and time
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/timeb.h>
+.Ft int
+.Fn ftime "struct timeb *tp"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is obsoleted by gettimeofday(2).
+.Pp
+It is available from the compatibility library, libcompat.
+.Ef
+.Pp
+The
+.Fn ftime
+routine fills in a structure pointed to by its argument,
+as defined by
+.Aq Pa sys/timeb.h :
+.Bd -literal -offset indent
+/*
+ * Structure returned by ftime system call
+ */
+struct timeb
+{
+ time_t time;
+ unsigned short millitm;
+ short timezone;
+ short dstflag;
+};
+.Ed
+.Pp
+The structure contains the time since the epoch in seconds,
+up to 1000 milliseconds of more-precise interval,
+the local time zone (measured in minutes of time westward from Greenwich),
+and a flag that, if nonzero, indicates that
+Daylight Saving time applies locally during the appropriate part of the year.
+.Sh SEE ALSO
+.Xr gettimeofday 2 ,
+.Xr settimeofday 2 ,
+.Xr ctime 3 ,
+.Xr time 3
+.Sh HISTORY
+The
+.Nm
+function appeared in
+.Bx 4.2 .
diff --git a/lib/libcompat/4.1/ftime.c b/lib/libcompat/4.1/ftime.c
index ccd3a64..cc4a7f9 100644
--- a/lib/libcompat/4.1/ftime.c
+++ b/lib/libcompat/4.1/ftime.c
@@ -29,13 +29,14 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: ftime.c,v 1.3 1994/05/06 06:42:21 cgd Exp $";
+static char rcsid[] = "$FreeBSD$";
#endif /* not lint */
#include <sys/types.h>
#include <sys/time.h>
#include <sys/timeb.h>
+int
ftime(tbp)
struct timeb *tbp;
{
diff --git a/lib/libcompat/4.1/getpw.3 b/lib/libcompat/4.1/getpw.3
new file mode 100644
index 0000000..523a95c
--- /dev/null
+++ b/lib/libcompat/4.1/getpw.3
@@ -0,0 +1,89 @@
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)getpw.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt GETPW 3
+.Os
+.Sh NAME
+.Nm getpw
+.Nd get name from uid
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Ft int
+.Fn getpw "uid_t uid" "char *buf"
+.Sh DESCRIPTION
+.Bf -symbolic
+The getpw function is made obsolete by getpwuid(3).
+.br
+It is available from the compatibility library, libcompat.
+.Ef
+.Pp
+The
+.Fn getpw
+function reads the file
+.Pa /etc/passwd ,
+and if it finds
+the specified
+.Fa uid ,
+copies the password entry line into the string pointed to by
+.Fa buf .
+the null terminated entry line from the password database,
+and appends the
+.Dv NUL
+character.
+.Sh RETURN VALUES
+The
+.Fn getpw
+function returns the zero if successful, otherwise
+a non-zero if the entry does not exist.
+.Sh FILES
+.Bl -tag -width /etc/passwd - compact
+.It Pa /etc/passwd
+.El
+.Sh SEE ALSO
+.Xr getpwent 3 ,
+.Xr passwd 5
+.Sh HISTORY
+A
+.Fn getpw
+function appeared in
+.At v6 .
+.Sh BUGS
+The area pointed to by
+.Fa buf
+must be large enough to hold the user name.
+
+All of the bugs from
+.Xr getpwent 3
+hold valid as well.
diff --git a/lib/libcompat/4.1/getpw.c b/lib/libcompat/4.1/getpw.c
new file mode 100644
index 0000000..96b4c12
--- /dev/null
+++ b/lib/libcompat/4.1/getpw.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1995 Joerg Wunsch
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Joerg Wunsch
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <string.h>
+#include <stdio.h>
+
+int
+#if __STDC__
+getpw(uid_t uid, char *buf)
+#else
+getpw(uid, buf)
+ uid_t uid;
+ char *buf;
+#endif
+{
+ struct passwd *pw;
+
+ pw = getpwuid(uid);
+ endpwent();
+
+ if(pw == 0) return -1;
+
+ strncpy(buf, pw->pw_name, L_cuserid);
+ return 0;
+}
diff --git a/lib/libcompat/4.1/gtty.c b/lib/libcompat/4.1/gtty.c
index a6a9c64..524f1a6 100644
--- a/lib/libcompat/4.1/gtty.c
+++ b/lib/libcompat/4.1/gtty.c
@@ -29,7 +29,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: gtty.c,v 1.1 1994/05/21 05:20:34 cgd Exp $";
+static char rcsid[] = "$FreeBSD$";
#endif /* not lint */
#include <sgtty.h>
@@ -39,6 +39,9 @@ static char rcsid[] = "$Id: gtty.c,v 1.1 1994/05/21 05:20:34 cgd Exp $";
* This was defined in ioctl_compat.h as:
* #define gtty(fd, tty) ioctl(fd, TIOCGETP, tty)
*/
+
+#undef gtty
+
int
gtty(fd, tty)
int fd;
diff --git a/lib/libcompat/4.1/stty.3 b/lib/libcompat/4.1/stty.3
new file mode 100644
index 0000000..564bf5b
--- /dev/null
+++ b/lib/libcompat/4.1/stty.3
@@ -0,0 +1,96 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)stty.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt STTY 3
+.Os BSD 4.2
+.Sh NAME
+.Nm stty ,
+.Nm gtty
+.Nd set and get terminal state (defunct)
+.Sh SYNOPSIS
+.Fd #include <sgtty.h>
+.Ft int
+.Fn stty "int fd" "struct sgttyb *buf"
+.Ft int
+.Fn gtty "int fd" "struct sgttyb *buf"
+.Sh DESCRIPTION
+.Bf -symbolic
+These interfaces are obsoleted by ioctl(2).
+They are available from the compatibility library, libcompat.
+.Ef
+.Pp
+The
+.Fn stty
+function
+sets the state of the terminal associated with
+.Fa fd .
+The
+.Fn gtty
+function
+retrieves the state of the terminal associated
+with
+.Fa fd .
+To set the state of a terminal the call must have
+write permission.
+.Pp
+The
+.Fn stty
+call is actually
+.Ql ioctl(fd, TIOCSETP, buf) ,
+while
+the
+.Fn gtty
+call is
+.Ql ioctl(fd, TIOCGETP, buf) .
+See
+.Xr ioctl 2
+and
+.Xr tty 4
+for an explanation.
+.Sh DIAGNOSTICS
+If the call is successful 0 is returned, otherwise \-1 is
+returned and the global variable
+.Va errno
+contains the reason for the failure.
+.Sh SEE ALSO
+.Xr ioctl 2 ,
+.Xr tty 4
+.Sh HISTORY
+The
+.Fn stty
+and
+.Fn gtty
+functions appeared in
+.Bx 4.2 .
diff --git a/lib/libcompat/4.1/stty.c b/lib/libcompat/4.1/stty.c
index 3e89506..cf0137f 100644
--- a/lib/libcompat/4.1/stty.c
+++ b/lib/libcompat/4.1/stty.c
@@ -29,7 +29,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: stty.c,v 1.1 1994/05/21 05:20:41 cgd Exp $";
+static char rcsid[] = "$FreeBSD$";
#endif /* not lint */
#include <sgtty.h>
@@ -39,6 +39,9 @@ static char rcsid[] = "$Id: stty.c,v 1.1 1994/05/21 05:20:41 cgd Exp $";
* This was defined in ioctl_compat.h as:
* #define stty(fd, tty) ioctl(fd, TIOCSETP, tty)
*/
+
+#undef stty
+
int
stty(fd, tty)
int fd;
diff --git a/lib/libcompat/4.1/vlimit.3 b/lib/libcompat/4.1/vlimit.3
new file mode 100644
index 0000000..d484a20
--- /dev/null
+++ b/lib/libcompat/4.1/vlimit.3
@@ -0,0 +1,126 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)vlimit.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt VLIMIT 3
+.Os BSD 4
+.Sh NAME
+.Nm vlimit
+.Nd control maximum system resource consumption
+.Sh SYNOPSIS
+.Fd #include <sys/vlimit.h>
+.Fn vlimit resource value
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is obsoleted by getrlimit(2).
+It is available from the compatibility library, libcompat.
+.Ef
+.Pp
+Limits the consumption by the current process and each process
+it creates to not individually exceed
+.Fa value
+on the specified
+.Fa resource .
+If
+.Fa value
+is specified as \-1, then the current limit is returned and the
+limit is unchanged.
+The resources which are currently controllable are:
+.Bl -tag -width LIM_NORAISE
+.It Dv LIM_NORAISE
+A pseudo-limit; if set non-zero then the limits may not be raised.
+Only the super-user may remove the
+.Em noraise
+restriction.
+.It Dv LIM_CPU
+the maximum
+number of cpu-seconds to be used by each process
+.It Dv LIM_FSIZE
+the largest single file which can be created
+.It Dv LIM_DATA
+the maximum growth of the data+stack region via
+.Xr sbrk 2
+beyond the end of the program text
+.It Dv LIM_STACK
+the maximum
+size of the automatically-extended stack region
+.It Dv LIM_CORE
+the size of the largest core dump that will be created.
+.It Dv LIM_MAXRSS
+a soft limit for the amount of physical memory (in bytes) to be given
+to the program. If memory is tight, the system will prefer to take memory
+from processes which are exceeding their declared
+.Dv LIM_MAXRSS.
+.El
+.Pp
+Because this information is stored in the per-process information
+this system call must be executed directly by the shell if it
+is to affect all future processes created by the shell;
+.Xr limit
+is thus a built-in command to
+.Xr csh 1 .
+.Pp
+The system refuses to extend the data or stack space when the limits
+would be exceeded in the normal way; a
+.Xr brk 2
+call fails if the data space limit is reached, or the process is
+killed when the stack limit is reached (since the stack cannot be
+extended, there is no way to send a signal!).
+.Pp
+A file
+.Tn I/O
+operation which would create a file which is too large
+will cause a signal
+.Dv SIGXFSZ
+to be generated, this normally terminates
+the process, but may be caught.
+When the cpu time limit is exceeded, a signal
+.Dv SIGXCPU
+is sent to the
+offending process; to allow it time to process the signal it is
+given 5 seconds grace by raising the
+.Tn CPU
+time limit.
+.Sh SEE ALSO
+.Xr csh 1
+.Sh HISTORY
+The
+.Fn vlimit
+function appeared in
+.Bx 4.2 .
+.Sh BUGS
+.Dv LIM_NORAISE
+no longer exists.
+
+This function has not yet been reimplemented.
diff --git a/lib/libcompat/4.1/vtimes.3 b/lib/libcompat/4.1/vtimes.3
new file mode 100644
index 0000000..73de4b0
--- /dev/null
+++ b/lib/libcompat/4.1/vtimes.3
@@ -0,0 +1,144 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)vtimes.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt VTIMES 3
+.Os BSD 4
+.Sh NAME
+.Nm vtimes
+.Nd get information about resource utilization
+.Sh SYNOPSIS
+.Fd #include <sys/vtimes.h>
+.Fn vtimes "struct vtimes *par_vm" "struct vtimes *ch_vm"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is obsoleted by getrusage(2).
+It is available from the compatibility library, libcompat.
+.Ef
+.Pp
+The
+.Fn vtimes
+function
+returns accounting information for the current process and for
+the terminated child processes of the current
+process. Either
+.Fa par_vm
+or
+.Fa ch_vm
+or both may be 0, in which case only the information for the pointers
+which are non-zero is returned.
+.Pp
+After the call, each buffer contains information as defined by the
+contents of the include file
+.Pa /usr/include/sys/vtimes.h :
+.Bd -literal -offset indent
+struct vtimes {
+ int vm_utime; /* user time (*HZ) */
+ int vm_stime; /* system time (*HZ) */
+ /* divide next two by utime+stime to get averages */
+ unsigned vm_idsrss; /* integral of d+s rss */
+ unsigned vm_ixrss; /* integral of text rss */
+ int vm_maxrss; /* maximum rss */
+ int vm_majflt; /* major page faults */
+ int vm_minflt; /* minor page faults */
+ int vm_nswap; /* number of swaps */
+ int vm_inblk; /* block reads */
+ int vm_oublk; /* block writes */
+};
+.Ed
+.Pp
+The
+.Fa vm_utime
+and
+.Fa vm_stime
+fields give the user and system
+time respectively in 60ths of a second (or 50ths if that
+is the frequency of wall current in your locality.) The
+.Fa vm_idrss
+and
+.Fa vm_ixrss
+measure memory usage. They are computed by integrating the number of
+memory pages in use each
+over
+.Tn CPU
+time. They are reported as though computed
+discretely, adding the current memory usage (in 512 byte
+pages) each time the clock ticks. If a process used 5 core
+pages over 1 cpu-second for its data and stack, then
+.Fa vm_idsrss
+would have the value 5*60, where
+.Fa vm_utime+vm_stime
+would be the 60.
+The
+.Fa Vm_idsrss
+argument
+integrates data and stack segment
+usage, while
+.Fa vm_ixrss
+integrates text segment usage.
+The
+.Fa Vm_maxrss
+function
+reports the maximum instantaneous sum of the
+text+data+stack core-resident page count.
+.Pp
+The
+.Fa vm_majflt
+field gives the number of page faults which
+resulted in disk activity; the
+.Fa vm_minflt
+field gives the
+number of page faults incurred in simulation of reference
+bits;
+.Fa vm_nswap
+is the number of swaps which occurred. The
+number of file system input/output events are reported in
+.Fa vm_inblk
+and
+.Fa vm_oublk
+These numbers account only for real
+.Tn I/O ;
+data supplied by the caching mechanism is charged only
+to the first process to read or write the data.
+.Sh SEE ALSO
+.Xr getrusage 2 ,
+.Xr wait3 2 ,
+.Xr time 3
+.Sh HISTORY
+The
+.Fn vlimit
+function appeared in
+.Bx 4.2 .
+.Sh BUGS
+This function has not yet been re-implemented.
diff --git a/lib/libcompat/4.3/cfree.3 b/lib/libcompat/4.3/cfree.3
new file mode 100644
index 0000000..7e3bdce
--- /dev/null
+++ b/lib/libcompat/4.3/cfree.3
@@ -0,0 +1,49 @@
+.\"
+.\" Copyright (c) 1995 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" " <- this is for hilit19 :)
+.Dd November 23, 1995
+.Dt CFREE 3
+.Os
+.Sh NAME
+.Nm cfree
+.Nd free up allocated memory
+.Sh SYNOPSIS
+.Ft void
+.Fn cfree "void *"
+.Sh DESCRIPTION
+.Bf -symbolic
+The cfree function considered obsolete.
+.br
+It is available from the compatibility library, libcompat.
+.Ef
+.Pp
+The
+.Nm
+function is a synonym for
+.Xr free 3 .
+.Sh SEE ALSO
+.Xr free 3 .
diff --git a/lib/libcompat/4.3/cfree.c b/lib/libcompat/4.3/cfree.c
new file mode 100644
index 0000000..7f029ff
--- /dev/null
+++ b/lib/libcompat/4.3/cfree.c
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)cfree.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+
+void
+cfree(p)
+ void *p;
+{
+ free(p);
+}
diff --git a/lib/libcompat/4.3/insque.3 b/lib/libcompat/4.3/insque.3
new file mode 100644
index 0000000..4f21d1d
--- /dev/null
+++ b/lib/libcompat/4.3/insque.3
@@ -0,0 +1,89 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)insque.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt INSQUE 3
+.Os BSD 4.2
+.Sh NAME
+.Nm insque ,
+.Nm remque
+.Nd insert/remove element from a queue
+.Sh SYNOPSIS
+.Bd -literal
+struct qelem {
+ struct qelem *q_forw;
+ struct qelem *q_back;
+ char q_data[];
+};
+.Ed
+
+.Ft void
+.Fn insque "struct qelem *elem" "struct qelem *pred"
+.Ft void
+.Fn remque "struct qelem *elem"
+.Sh DESCRIPTION
+.Bf -symbolic
+The insque and remque functions are considered obsolete.
+.br
+They are available from the compatibility library, libcompat.
+.Ef
+.Pp
+The
+.Fn insque
+and
+.Fn remque
+functions
+manipulate queues built from doubly linked lists. Each
+element in the queue must be in the form of
+.Dq Li struct qelem .
+The function
+.Fn insque
+inserts
+.Fa elem
+in a queue immediately after
+.Fa pred ;
+.Fn remque
+removes an entry
+.Fa elem
+from a queue.
+.Sh SEE ALSO
+.%T "VAX Architecture Handbook" ,
+pp. 228-235.
+.Sh HISTORY
+The
+.Fn insque
+and
+.Fn remque
+functions appeared in
+.Bx 4.2 .
diff --git a/lib/libcompat/4.3/insque.c b/lib/libcompat/4.3/insque.c
new file mode 100644
index 0000000..3035976
--- /dev/null
+++ b/lib/libcompat/4.3/insque.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)insque.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * insque -- vax insque instruction
+ *
+ * NOTE: this implementation is non-atomic!!
+ */
+
+struct vaxque { /* queue format expected by VAX queue instructions */
+ struct vaxque *vq_next;
+ struct vaxque *vq_prev;
+};
+
+void
+insque(e, prev)
+ register struct vaxque *e, *prev;
+{
+ e->vq_prev = prev;
+ e->vq_next = prev->vq_next;
+ prev->vq_next->vq_prev = e;
+ prev->vq_next = e;
+}
diff --git a/lib/libcompat/4.3/lsearch.3 b/lib/libcompat/4.3/lsearch.3
new file mode 100644
index 0000000..3a98ed9
--- /dev/null
+++ b/lib/libcompat/4.3/lsearch.3
@@ -0,0 +1,104 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)lsearch.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt LSEARCH 3
+.Os
+.Sh NAME
+.Nm lsearch ,
+.Nm lfind,
+.Nd linear searching routines
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Ft char *
+.Fn lsearch "const void *key" "const void *base" "size_t *nelp" "size_t width" "int (*compar)(void *, void *)"
+.Ft char *
+.Fn lfind "const void *key" "const void *base" "size_t *nelp" "size_t width" "int (*compar)(void *, void *)"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface was obsolete before it was written.
+It is available from the compatibility library, libcompat.
+.Ef
+.Pp
+The functions
+.Fn lsearch ,
+and
+.Fn lfind
+provide basic linear searching functionality.
+.Pp
+.Fa Base
+is the pointer to the beginning of an array.
+The argument
+.Fa nelp
+is the current number of elements in the array, where each element
+is
+.Fa width
+bytes long.
+The
+.Fa compar
+function
+is a comparison routine which is used to compare two elements.
+It takes two arguments which point to the
+.Fa key
+object and to an array member, in that order, and must return an integer
+less than, equivalent to, or greater than zero if the
+.Fa key
+object is considered, respectively, to be less than, equal to, or greater
+than the array member.
+.Pp
+The
+.Fn lsearch
+and
+.Fn lfind
+functions
+return a pointer into the array referenced by
+.Fa base
+where
+.Fa key
+is located.
+If
+.Fa key
+does not exist,
+.Fn lfind
+will return a null pointer and
+.Fn lsearch
+will add it to the array.
+When an element is added to the array by
+.Fn lsearch
+the location referenced by the argument
+.Fa nelp
+is incremented by one.
+.Sh SEE ALSO
+.Xr bsearch 3 ,
+.Xr db 3
diff --git a/lib/libcompat/4.3/lsearch.c b/lib/libcompat/4.3/lsearch.c
new file mode 100644
index 0000000..be650b4
--- /dev/null
+++ b/lib/libcompat/4.3/lsearch.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Roger L. Snyder.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)lsearch.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+
+static char *linear_base();
+
+char *
+lsearch(key, base, nelp, width, compar)
+ char *key, *base;
+ u_int *nelp, width;
+ int (*compar)();
+{
+ return(linear_base(key, base, nelp, width, compar, 1));
+}
+
+char *
+lfind(key, base, nelp, width, compar)
+ char *key, *base;
+ u_int *nelp, width;
+ int (*compar)();
+{
+ return(linear_base(key, base, nelp, width, compar, 0));
+}
+
+static char *
+linear_base(key, base, nelp, width, compar, add_flag)
+ char *key, *base;
+ u_int *nelp, width;
+ int (*compar)(), add_flag;
+{
+ register char *element, *end;
+
+ end = base + *nelp * width;
+ for (element = base; element < end; element += width)
+ if (!compar(element, key)) /* key found */
+ return(element);
+
+ if (!add_flag) /* key not found */
+ return(NULL);
+
+ /*
+ * The UNIX System User's Manual, 1986 edition claims that
+ * a NULL pointer is returned by lsearch with errno set
+ * appropriately, if there is not enough room in the table
+ * to add a new item. This can't be done as none of these
+ * routines have any method of determining the size of the
+ * table. This comment was isn't in the 1986-87 System V
+ * manual.
+ */
+ ++*nelp;
+ bcopy(key, end, (int)width);
+ return(end);
+}
diff --git a/lib/libcompat/4.3/re_comp.3 b/lib/libcompat/4.3/re_comp.3
new file mode 100644
index 0000000..34cd19d
--- /dev/null
+++ b/lib/libcompat/4.3/re_comp.3
@@ -0,0 +1,125 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)re_comp.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt RE_COMP 3
+.Os
+.Sh NAME
+.Nm re_comp ,
+.Nm re_exec
+.Nd regular expression handler
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft char *
+.Fn re_comp "const char *s"
+.Ft int
+.Fn re_exec "const char *s"
+.Sh DESCRIPTION
+This interface is made obsolete by
+.Xr regex 3 .
+It is available from the compatibility library, libcompat.
+.Pp
+The
+.Fn re_comp
+function
+compiles a string into an internal form suitable for pattern matching.
+The
+.Fn re_exec
+function
+checks the argument string against the last string passed to
+.Fn re_comp .
+.Pp
+The
+.Fn re_comp
+function
+returns 0 if the string
+.Fa s
+was compiled successfully; otherwise a string containing an
+error message is returned. If
+.Fn re_comp
+is passed 0 or a null string, it returns without changing the currently
+compiled regular expression.
+.Pp
+The
+.Fn re_exec
+function
+returns 1 if the string
+.Fa s
+matches the last compiled regular expression, 0 if the string
+.Fa s
+failed to match the last compiled regular expression, and \-1 if the compiled
+regular expression was invalid (indicating an internal error).
+.Pp
+The strings passed to both
+.Fn re_comp
+and
+.Fn re_exec
+may have trailing or embedded newline characters;
+they are terminated by
+.Dv NUL Ns s.
+The regular expressions recognized are described in the manual entry for
+.Xr ed 1 ,
+given the above difference.
+.Sh DIAGNOSTICS
+The
+.Fn re_exec
+function
+returns \-1 for an internal error.
+.Pp
+The
+.Fn re_comp
+function
+returns one of the following strings if an error occurs:
+.Bd -unfilled -offset indent
+No previous regular expression,
+Regular expression too long,
+unmatched \e(,
+missing ],
+too many \e(\e) pairs,
+unmatched \e).
+.Ed
+.Sh SEE ALSO
+.Xr ed 1 ,
+.Xr egrep 1 ,
+.Xr ex 1 ,
+.Xr fgrep 1 ,
+.Xr grep 1 ,
+.Xr regex 3
+.Sh HISTORY
+The
+.Fn re_comp
+and
+.Fn re_exec
+functions appeared in
+.Bx 4.0 .
diff --git a/lib/libcompat/4.3/regex.c b/lib/libcompat/4.3/regex.c
new file mode 100644
index 0000000..07566b5
--- /dev/null
+++ b/lib/libcompat/4.3/regex.c
@@ -0,0 +1,96 @@
+/*-
+ * Copyright (c) 1992 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James da Silva at the University of Maryland at College Park.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Compatibility routines that implement the old re_comp/re_exec interface in
+ * terms of the regcomp/regexec interface. It's possible that some programs
+ * rely on dark corners of re_comp/re_exec and won't work with this version,
+ * but most programs should be fine.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)regex.c 5.1 (Berkeley) 3/29/92";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <stddef.h>
+#include <regexp.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>
+
+static regexp *re_regexp;
+static int re_goterr;
+static char *re_errstr;
+
+char *
+re_comp(s)
+ char *s;
+{
+ if (s == NULL || *s == '\0') {
+ if (re_regexp == NULL)
+ return "no previous regular expression";
+ return (NULL);
+ }
+ if (re_regexp)
+ free(re_regexp);
+ if (re_errstr)
+ free(re_errstr);
+ re_goterr = 0;
+ re_regexp = regcomp(s);
+ return (re_goterr ? re_errstr : NULL);
+}
+
+int
+re_exec(s)
+ char *s;
+{
+ int rc;
+
+ re_goterr = 0;
+ rc = regexec(re_regexp, s);
+ return (re_goterr ? -1 : rc);
+}
+
+void
+regerror(s)
+ const char *s;
+{
+ re_goterr = 1;
+ if (re_errstr)
+ free(re_errstr);
+ re_errstr = strdup(s);
+}
diff --git a/lib/libcompat/4.3/remque.c b/lib/libcompat/4.3/remque.c
new file mode 100644
index 0000000..e0f9aa3
--- /dev/null
+++ b/lib/libcompat/4.3/remque.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)remque.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * remque -- vax remque instruction
+ *
+ * NOTE: this implementation is non-atomic!!
+ */
+
+struct vaxque { /* queue format expected by VAX queue instructions */
+ struct vaxque *vq_next;
+ struct vaxque *vq_prev;
+};
+
+void
+remque(e)
+ register struct vaxque *e;
+{
+ e->vq_prev->vq_next = e->vq_next;
+ e->vq_next->vq_prev = e->vq_prev;
+}
diff --git a/lib/libcompat/4.3/rexec.3 b/lib/libcompat/4.3/rexec.3
new file mode 100644
index 0000000..34d53ff
--- /dev/null
+++ b/lib/libcompat/4.3/rexec.3
@@ -0,0 +1,133 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)rexec.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt REXEC 3
+.Os BSD 4.2
+.Sh NAME
+.Nm rexec
+.Nd return stream to a remote command
+.Sh SYNOPSIS
+.Ft int
+.Fn rexec "char **ahost" "int inport" "char *user" "char *passwd" "char *cmd" "int *fd2p"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is obsoleted by
+.Xr rcmd 3 .
+It is available from the compatibility library, libcompat.
+.Ef
+.Pp
+The
+.Fn rexec
+function
+looks up the host
+.Fa *ahost
+using
+.Xr gethostbyname 3 ,
+returning \-1 if the host does not exist.
+Otherwise
+.Fa *ahost
+is set to the standard name of the host.
+If a username and password are both specified, then these
+are used to authenticate to the foreign host; otherwise
+the environment and then the user's
+.Pa .netrc
+file in his
+home directory are searched for appropriate information.
+If all this fails, the user is prompted for the information.
+.Pp
+The port
+.Fa inport
+specifies which well-known
+.Tn DARPA
+Internet port to use for
+the connection; the call
+.Ql getservbyname(\\*qexec\\*q, \\*qtcp\\*q)
+(see
+.Xr getservent 3 )
+will return a pointer to a structure, which contains the
+necessary port.
+The protocol for connection is described in detail in
+.Xr rexecd 8 .
+.Pp
+If the connection succeeds,
+a socket in the Internet domain of type
+.Dv SOCK_STREAM
+is returned to
+the caller, and given to the remote command as
+.Em stdin
+and
+.Em stdout .
+If
+.Fa fd2p
+is non-zero, then an auxiliary channel to a control
+process will be setup, and a descriptor for it will be placed
+in
+.Fa *fd2p .
+The control process will return diagnostic
+output from the command (unit 2) on this channel, and will also
+accept bytes on this channel as being
+.Tn UNIX
+signal numbers, to be
+forwarded to the process group of the command. The diagnostic
+information returned does not include remote authorization failure,
+as the secondary connection is set up after authorization has been
+verified.
+If
+.Fa fd2p
+is 0, then the
+.Em stderr
+(unit 2 of the remote
+command) will be made the same as the
+.Em stdout
+and no
+provision is made for sending arbitrary signals to the remote process,
+although you may be able to get its attention by using out-of-band data.
+.Sh SEE ALSO
+.Xr rcmd 3 ,
+.Xr rexecd 8
+.Sh HISTORY
+The
+.Fn rexec
+function appeared in
+.Bx 4.2 .
+.Sh BUGS
+The
+.Fn rexec
+function sends the unencrypted password across the network.
+.Pp
+The underlying service is considered a big security hole and therefore
+not enabled on many sites, see
+.Xr rexecd 8
+for explanations.
diff --git a/lib/libcompat/4.3/rexec.c b/lib/libcompat/4.3/rexec.c
new file mode 100644
index 0000000..beb2108
--- /dev/null
+++ b/lib/libcompat/4.3/rexec.c
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rexec.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <netdb.h>
+#include <errno.h>
+#include <ctype.h>
+#include <err.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int rexecoptions;
+char *getpass(), *getlogin();
+
+/*
+ * Options and other state info.
+ */
+struct macel {
+ char mac_name[9]; /* macro name */
+ char *mac_start; /* start of macro in macbuf */
+ char *mac_end; /* end of macro in macbuf */
+};
+
+int macnum; /* number of defined macros */
+struct macel macros[16];
+char macbuf[4096];
+
+static FILE *cfile;
+
+#define DEFAULT 1
+#define LOGIN 2
+#define PASSWD 3
+#define ACCOUNT 4
+#define MACDEF 5
+#define ID 10
+#define MACH 11
+
+static char tokval[100];
+
+static struct toktab {
+ char *tokstr;
+ int tval;
+} toktab[]= {
+ { "default", DEFAULT },
+ { "login", LOGIN },
+ { "password", PASSWD },
+ { "passwd", PASSWD },
+ { "account", ACCOUNT },
+ { "machine", MACH },
+ { "macdef", MACDEF },
+ { NULL, 0 }
+};
+
+static int
+token()
+{
+ char *cp;
+ int c;
+ struct toktab *t;
+
+ if (feof(cfile) || ferror(cfile))
+ return (0);
+ while ((c = getc(cfile)) != EOF &&
+ (c == '\n' || c == '\t' || c == ' ' || c == ','))
+ continue;
+ if (c == EOF)
+ return (0);
+ cp = tokval;
+ if (c == '"') {
+ while ((c = getc(cfile)) != EOF && c != '"') {
+ if (c == '\\')
+ c = getc(cfile);
+ *cp++ = c;
+ }
+ } else {
+ *cp++ = c;
+ while ((c = getc(cfile)) != EOF
+ && c != '\n' && c != '\t' && c != ' ' && c != ',') {
+ if (c == '\\')
+ c = getc(cfile);
+ *cp++ = c;
+ }
+ }
+ *cp = 0;
+ if (tokval[0] == 0)
+ return (0);
+ for (t = toktab; t->tokstr; t++)
+ if (!strcmp(t->tokstr, tokval))
+ return (t->tval);
+ return (ID);
+}
+
+static int
+ruserpass(host, aname, apass, aacct)
+ char *host, **aname, **apass, **aacct;
+{
+ char *hdir, buf[BUFSIZ], *tmp;
+ char myname[MAXHOSTNAMELEN], *mydomain;
+ int t, i, c, usedefault = 0;
+ struct stat stb;
+
+ hdir = getenv("HOME");
+ if (hdir == NULL)
+ hdir = ".";
+ (void) sprintf(buf, "%s/.netrc", hdir);
+ cfile = fopen(buf, "r");
+ if (cfile == NULL) {
+ if (errno != ENOENT)
+ warn("%s", buf);
+ return (0);
+ }
+ if (gethostname(myname, sizeof(myname)) < 0)
+ myname[0] = '\0';
+ if ((mydomain = strchr(myname, '.')) == NULL)
+ mydomain = "";
+next:
+ while ((t = token())) switch(t) {
+
+ case DEFAULT:
+ usedefault = 1;
+ /* FALL THROUGH */
+
+ case MACH:
+ if (!usedefault) {
+ if (token() != ID)
+ continue;
+ /*
+ * Allow match either for user's input host name
+ * or official hostname. Also allow match of
+ * incompletely-specified host in local domain.
+ */
+ if (strcasecmp(host, tokval) == 0)
+ goto match;
+ if ((tmp = strchr(host, '.')) != NULL &&
+ strcasecmp(tmp, mydomain) == 0 &&
+ strncasecmp(host, tokval, tmp - host) == 0 &&
+ tokval[tmp - host] == '\0')
+ goto match;
+ continue;
+ }
+ match:
+ while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
+
+ case LOGIN:
+ if (token())
+ if (*aname == 0) {
+ *aname = malloc((unsigned) strlen(tokval) + 1);
+ (void) strcpy(*aname, tokval);
+ } else {
+ if (strcmp(*aname, tokval))
+ goto next;
+ }
+ break;
+ case PASSWD:
+ if ((*aname == 0 || strcmp(*aname, "anonymous")) &&
+ fstat(fileno(cfile), &stb) >= 0 &&
+ (stb.st_mode & 077) != 0) {
+ warnx("Error: .netrc file is readable by others.");
+ warnx("Remove password or make file unreadable by others.");
+ goto bad;
+ }
+ if (token() && *apass == 0) {
+ *apass = malloc((unsigned) strlen(tokval) + 1);
+ (void) strcpy(*apass, tokval);
+ }
+ break;
+ case ACCOUNT:
+ if (fstat(fileno(cfile), &stb) >= 0
+ && (stb.st_mode & 077) != 0) {
+ warnx("Error: .netrc file is readable by others.");
+ warnx("Remove account or make file unreadable by others.");
+ goto bad;
+ }
+ if (token() && *aacct == 0) {
+ *aacct = malloc((unsigned) strlen(tokval) + 1);
+ (void) strcpy(*aacct, tokval);
+ }
+ break;
+ case MACDEF:
+ while ((c=getc(cfile)) != EOF &&
+ (c == ' ' || c == '\t'))
+ ;
+ if (c == EOF || c == '\n') {
+ printf("Missing macdef name argument.\n");
+ goto bad;
+ }
+ if (macnum == 16) {
+ printf("Limit of 16 macros have already been defined\n");
+ goto bad;
+ }
+ tmp = macros[macnum].mac_name;
+ *tmp++ = c;
+ for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
+ !isspace(c); ++i) {
+ *tmp++ = c;
+ }
+ if (c == EOF) {
+ printf("Macro definition missing null line terminator.\n");
+ goto bad;
+ }
+ *tmp = '\0';
+ if (c != '\n') {
+ while ((c=getc(cfile)) != EOF && c != '\n');
+ }
+ if (c == EOF) {
+ printf("Macro definition missing null line terminator.\n");
+ goto bad;
+ }
+ if (macnum == 0) {
+ macros[macnum].mac_start = macbuf;
+ }
+ else {
+ macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
+ }
+ tmp = macros[macnum].mac_start;
+ while (tmp != macbuf + 4096) {
+ if ((c=getc(cfile)) == EOF) {
+ printf("Macro definition missing null line terminator.\n");
+ goto bad;
+ }
+ *tmp = c;
+ if (*tmp == '\n') {
+ if (*(tmp-1) == '\0') {
+ macros[macnum++].mac_end = tmp - 1;
+ break;
+ }
+ *tmp = '\0';
+ }
+ tmp++;
+ }
+ if (tmp == macbuf + 4096) {
+ printf("4K macro buffer exceeded\n");
+ goto bad;
+ }
+ break;
+ default:
+ warnx("Unknown .netrc keyword %s", tokval);
+ break;
+ }
+ goto done;
+ }
+done:
+ (void) fclose(cfile);
+ return (0);
+bad:
+ (void) fclose(cfile);
+ return (-1);
+}
+
+int
+rexec(ahost, rport, name, pass, cmd, fd2p)
+ char **ahost;
+ int rport;
+ char *name, *pass, *cmd;
+ int *fd2p;
+{
+ struct sockaddr_in sin, sin2, from;
+ struct hostent *hp;
+ u_short port;
+ int s, timo = 1, s3;
+ char c;
+
+ hp = gethostbyname(*ahost);
+ if (hp == 0) {
+ herror(*ahost);
+ return (-1);
+ }
+ *ahost = hp->h_name;
+ ruserpass(hp->h_name, &name, &pass);
+retry:
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0) {
+ perror("rexec: socket");
+ return (-1);
+ }
+ sin.sin_family = hp->h_addrtype;
+ sin.sin_port = rport;
+ bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+ if (errno == ECONNREFUSED && timo <= 16) {
+ (void) close(s);
+ sleep(timo);
+ timo *= 2;
+ goto retry;
+ }
+ perror(hp->h_name);
+ return (-1);
+ }
+ if (fd2p == 0) {
+ (void) write(s, "", 1);
+ port = 0;
+ } else {
+ char num[8];
+ int s2, sin2len;
+
+ s2 = socket(AF_INET, SOCK_STREAM, 0);
+ if (s2 < 0) {
+ (void) close(s);
+ return (-1);
+ }
+ listen(s2, 1);
+ sin2len = sizeof (sin2);
+ if (getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 ||
+ sin2len != sizeof (sin2)) {
+ perror("getsockname");
+ (void) close(s2);
+ goto bad;
+ }
+ port = ntohs((u_short)sin2.sin_port);
+ (void) sprintf(num, "%u", port);
+ (void) write(s, num, strlen(num)+1);
+ { int len = sizeof (from);
+ s3 = accept(s2, (struct sockaddr *)&from, &len);
+ close(s2);
+ if (s3 < 0) {
+ perror("accept");
+ port = 0;
+ goto bad;
+ }
+ }
+ *fd2p = s3;
+ }
+ (void) write(s, name, strlen(name) + 1);
+ /* should public key encypt the password here */
+ (void) write(s, pass, strlen(pass) + 1);
+ (void) write(s, cmd, strlen(cmd) + 1);
+ if (read(s, &c, 1) != 1) {
+ perror(*ahost);
+ goto bad;
+ }
+ if (c != 0) {
+ while (read(s, &c, 1) == 1) {
+ (void) write(2, &c, 1);
+ if (c == '\n')
+ break;
+ }
+ goto bad;
+ }
+ return (s);
+bad:
+ if (port)
+ (void) close(*fd2p);
+ (void) close(s);
+ return (-1);
+}
diff --git a/lib/libcompat/4.4/cuserid.3 b/lib/libcompat/4.4/cuserid.3
new file mode 100644
index 0000000..f3b4fc6
--- /dev/null
+++ b/lib/libcompat/4.4/cuserid.3
@@ -0,0 +1,82 @@
+.\"
+.\" Copyright (c) 1995 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Joerg Wunsch
+.\" 4. The name of the developer may not be used to endorse or promote
+.\" products derived from this software without specific prior written
+.\" permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 10, 1995
+.Os
+.Dt CUSERID 3
+.Sh NAME
+.Nm cuserid
+.Nd get user name associated with effective UID
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Ft char *
+.Fn cuserid "char *s"
+.Sh DESCRIPTION
+.Bf -symbolic
+The cuserid function is made obsolete by getpwuid.
+.br
+It is available from the compatibility library, libcompat.
+.Ef
+.Pp
+The function
+.Nm cuserid
+gets the user name associated with the effective UID of the current
+process. If the argument
+.Fa s
+is non-NULL, the name is copied to the buffer it points to,
+and that address is being returned. This buffer must provide space
+for at least
+.Em L_cuserid
+characters. The L_cuserid constant is defined in
+.Pa Aq stdio.h .
+
+If
+.Fa s
+is NULL, an internal array is used and its address will be returned.
+.Sh RETURN VALUES
+.Nm cuserid
+returns the address of an array in which the name has been stored.
+
+If the name associated with the effective UID of the current process
+could not be found, either a null pointer will be returned, or
+.Po
+if
+.Fa s
+is non-NULL
+.Pc
+the buffer
+.Fa s
+will be filled with a null string.
+.Sh SEE ALSO
+.Xr geteuid 2 ,
+.Xr getpwuid 3
diff --git a/lib/libcompat/4.4/cuserid.c b/lib/libcompat/4.4/cuserid.c
new file mode 100644
index 0000000..2fc5cc8
--- /dev/null
+++ b/lib/libcompat/4.4/cuserid.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)cuserid.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+char *
+cuserid(s)
+ char *s;
+{
+ register struct passwd *pwd;
+
+ if ((pwd = getpwuid(geteuid())) == NULL) {
+ if (s)
+ *s = '\0';
+ return (s);
+ }
+ if (s) {
+ (void)strncpy(s, pwd->pw_name, L_cuserid);
+ return (s);
+ }
+ return (pwd->pw_name);
+}
diff --git a/lib/libcompat/Makefile b/lib/libcompat/Makefile
new file mode 100644
index 0000000..f57107e
--- /dev/null
+++ b/lib/libcompat/Makefile
@@ -0,0 +1,50 @@
+# @(#)Makefile 8.1 (Berkeley) 6/4/93
+
+LIB=compat
+CFLAGS+=-DLIBC_SCCS -DSYSLIBC_SCCS -I${.CURDIR}/../libc/locale
+AINC= -I${.CURDIR}/../libc/${MACHINE_ARCH}
+NOPIC=
+
+.PATH: ${.CURDIR}/4.1/${MACHINE_ARCH} ${.CURDIR}/4.1 \
+ ${.CURDIR}/4.3/${MACHINE_ARCH} ${.CURDIR}/4.3 \
+ ${.CURDIR}/4.4/${MACHINE_ARCH} ${.CURDIR}/4.4 \
+ ${.CURDIR}/regexp
+
+# compat 4.1 sources
+# XXX MISSING: tell.c vlimit.c vtimes.c
+SRCS+= ascftime.c cftime.c ftime.c getpw.c gtty.c stty.c
+
+MAN3+= 4.1/ftime.3 4.1/getpw.3 4.1/stty.3 4.1/vlimit.3 4.1/vtimes.3
+MAN3+= 4.1/cftime.3
+
+MLINKS+=stty.3 gtty.3
+MLINKS+=cftime.3 ascftime.3
+
+# compat 4.3 sources
+# XXX MISSING: ecvt.c gcvt.c sibuf.c sobuf.c strout.c
+SRCS+= cfree.c lsearch.c regex.c rexec.c
+SRCS+= insque.c remque.c
+
+# XXX MISSING: ecvt.0
+MAN3+= 4.3/cfree.3 4.3/insque.3 4.3/lsearch.3 4.3/re_comp.3 4.3/rexec.3
+
+# XXX MISSING: ecvt.3, so can't MLINK
+#MLINKS+=ecvt.3 fcvt.3 ecvt.3 gcvt.3
+MLINKS+=insque.3 remque.3
+MLINKS+=re_comp.3 re_exec.3
+MLINKS+=lsearch.3 lfind.3
+
+# compat 4.4 sources
+SRCS+= cuserid.c
+MAN3+= 4.4/cuserid.3
+
+# regexp sources
+SRCS+= regerror.c regexp.c regsub.c
+
+MAN3+= regexp/regexp.3
+
+# XXX name clash with libc
+# MLINKS+=regexp.3 regcomp.3 regexp.3 regexec.3 regexp.3 regerror.3
+MLINKS+=regexp.3 regsub.3
+
+.include <bsd.lib.mk>
diff --git a/lib/libcompat/regexp/COPYRIGHT b/lib/libcompat/regexp/COPYRIGHT
new file mode 100644
index 0000000..48b3f43
--- /dev/null
+++ b/lib/libcompat/regexp/COPYRIGHT
@@ -0,0 +1,22 @@
+This entire subtree is copyright the University of Toronto.
+The following copyright notice applies to all files found here. None of
+these files contain AT&T proprietary source code.
+_____________________________________________________________________________
+
+ Copyright (c) 1986 by University of Toronto.
+ Written by Henry Spencer. Not derived from licensed software.
+
+ Permission is granted to anyone to use this software for any
+ purpose on any computer system, and to redistribute it freely,
+ subject to the following restrictions:
+
+ 1. The author is not responsible for the consequences of use of
+ this software, no matter how awful, even if they arise
+ from defects in it.
+
+ 2. The origin of this software must not be misrepresented, either
+ by explicit claim or by omission.
+
+ 3. Altered versions must be plainly marked as such, and must not
+ be misrepresented as being the original software.
+
diff --git a/lib/libcompat/regexp/README b/lib/libcompat/regexp/README
new file mode 100644
index 0000000..37d6f51
--- /dev/null
+++ b/lib/libcompat/regexp/README
@@ -0,0 +1,84 @@
+This is a nearly-public-domain reimplementation of the V8 regexp(3) package.
+It gives C programs the ability to use egrep-style regular expressions, and
+does it in a much cleaner fashion than the analogous routines in SysV.
+
+ Copyright (c) 1986 by University of Toronto.
+ Written by Henry Spencer. Not derived from licensed software.
+
+ Permission is granted to anyone to use this software for any
+ purpose on any computer system, and to redistribute it freely,
+ subject to the following restrictions:
+
+ 1. The author is not responsible for the consequences of use of
+ this software, no matter how awful, even if they arise
+ from defects in it.
+
+ 2. The origin of this software must not be misrepresented, either
+ by explicit claim or by omission.
+
+ 3. Altered versions must be plainly marked as such, and must not
+ be misrepresented as being the original software.
+
+Barring a couple of small items in the BUGS list, this implementation is
+believed 100% compatible with V8. It should even be binary-compatible,
+sort of, since the only fields in a "struct regexp" that other people have
+any business touching are declared in exactly the same way at the same
+location in the struct (the beginning).
+
+This implementation is *NOT* AT&T/Bell code, and is not derived from licensed
+software. Even though U of T is a V8 licensee. This software is based on
+a V8 manual page sent to me by Dennis Ritchie (the manual page enclosed
+here is a complete rewrite and hence is not covered by AT&T copyright).
+The software was nearly complete at the time of arrival of our V8 tape.
+I haven't even looked at V8 yet, although a friend elsewhere at U of T has
+been kind enough to run a few test programs using the V8 regexp(3) to resolve
+a few fine points. I admit to some familiarity with regular-expression
+implementations of the past, but the only one that this code traces any
+ancestry to is the one published in Kernighan & Plauger (from which this
+one draws ideas but not code).
+
+Simplistically: put this stuff into a source directory, copy regexp.h into
+/usr/include, inspect Makefile for compilation options that need changing
+to suit your local environment, and then do "make r". This compiles the
+regexp(3) functions, compiles a test program, and runs a large set of
+regression tests. If there are no complaints, then put regexp.o, regsub.o,
+and regerror.o into your C library, and regexp.3 into your manual-pages
+directory.
+
+Note that if you don't put regexp.h into /usr/include *before* compiling,
+you'll have to add "-I." to CFLAGS before compiling.
+
+The files are:
+
+Makefile instructions to make everything
+regexp.3 manual page
+regexp.h header file, for /usr/include
+regexp.c source for regcomp() and regexec()
+regsub.c source for regsub()
+regerror.c source for default regerror()
+regmagic.h internal header file
+try.c source for test program
+timer.c source for timing program
+tests test list for try and timer
+
+This implementation uses nondeterministic automata rather than the
+deterministic ones found in some other implementations, which makes it
+simpler, smaller, and faster at compiling regular expressions, but slower
+at executing them. In theory, anyway. This implementation does employ
+some special-case optimizations to make the simpler cases (which do make
+up the bulk of regular expressions actually used) run quickly. In general,
+if you want blazing speed you're in the wrong place. Replacing the insides
+of egrep with this stuff is probably a mistake; if you want your own egrep
+you're going to have to do a lot more work. But if you want to use regular
+expressions a little bit in something else, you're in luck. Note that many
+existing text editors use nondeterministic regular-expression implementations,
+so you're in good company.
+
+This stuff should be pretty portable, given appropriate option settings.
+If your chars have less than 8 bits, you're going to have to change the
+internal representation of the automaton, although knowledge of the details
+of this is fairly localized. There are no "reserved" char values except for
+NUL, and no special significance is attached to the top bit of chars.
+The string(3) functions are used a fair bit, on the grounds that they are
+probably faster than coding the operations in line. Some attempts at code
+tuning have been made, but this is invariably a bit machine-specific.
diff --git a/lib/libcompat/regexp/regerror.c b/lib/libcompat/regexp/regerror.c
new file mode 100644
index 0000000..6d0077d
--- /dev/null
+++ b/lib/libcompat/regexp/regerror.c
@@ -0,0 +1,18 @@
+#include <regexp.h>
+#include <stdio.h>
+
+void
+regerror(s)
+const char *s;
+{
+#ifdef ERRAVAIL
+ error("regexp: %s", s);
+#else
+/*
+ fprintf(stderr, "regexp(3): %s\n", s);
+ exit(1);
+*/
+ return; /* let std. egrep handle errors */
+#endif
+ /* NOTREACHED */
+}
diff --git a/lib/libcompat/regexp/regexp.3 b/lib/libcompat/regexp/regexp.3
new file mode 100644
index 0000000..0d5c5a7
--- /dev/null
+++ b/lib/libcompat/regexp/regexp.3
@@ -0,0 +1,321 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)regexp.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt REGEXP 3
+.Os
+.Sh NAME
+.Nm regcomp ,
+.Nm regexec ,
+.Nm regsub ,
+.Nm regerror
+.Nd regular expression handlers
+.Sh SYNOPSIS
+.Fd #include <regexp.h>
+.Ft regexp *
+.Fn regcomp "const char *exp"
+.Ft int
+.Fn regexec "const regexp *prog" "const char *string"
+.Ft void
+.Fn regsub "const regexp *prog" "const char *source" "char *dest"
+.Sh DESCRIPTION
+This interface is made obsolete by
+.Xr regex 3 .
+.br
+It is available from the compatibility library, libcompat.
+.Pp
+The
+.Fn regcomp ,
+.Fn regexec ,
+.Fn regsub ,
+and
+.Fn regerror
+functions
+implement
+.Xr egrep 1 Ns -style
+regular expressions and supporting facilities.
+.Pp
+The
+.Fn regcomp
+function
+compiles a regular expression into a structure of type
+.Xr regexp ,
+and returns a pointer to it.
+The space has been allocated using
+.Xr malloc 3
+and may be released by
+.Xr free .
+.Pp
+The
+.Fn regexec
+function
+matches a
+.Dv NUL Ns -terminated
+.Fa string
+against the compiled regular expression
+in
+.Fa prog .
+It returns 1 for success and 0 for failure, and adjusts the contents of
+.Fa prog Ns 's
+.Em startp
+and
+.Em endp
+(see below) accordingly.
+.Pp
+The members of a
+.Xr regexp
+structure include at least the following (not necessarily in order):
+.Bd -literal -offset indent
+char *startp[NSUBEXP];
+char *endp[NSUBEXP];
+.Ed
+.Pp
+where
+.Dv NSUBEXP
+is defined (as 10) in the header file.
+Once a successful
+.Fn regexec
+has been done using the
+.Fn regexp ,
+each
+.Em startp Ns - Em endp
+pair describes one substring
+within the
+.Fa string ,
+with the
+.Em startp
+pointing to the first character of the substring and
+the
+.Em endp
+pointing to the first character following the substring.
+The 0th substring is the substring of
+.Fa string
+that matched the whole
+regular expression.
+The others are those substrings that matched parenthesized expressions
+within the regular expression, with parenthesized expressions numbered
+in left-to-right order of their opening parentheses.
+.Pp
+The
+.Fn regsub
+function
+copies
+.Fa source
+to
+.Fa dest ,
+making substitutions according to the
+most recent
+.Fn regexec
+performed using
+.Fa prog .
+Each instance of `&' in
+.Fa source
+is replaced by the substring
+indicated by
+.Em startp Ns Bq
+and
+.Em endp Ns Bq .
+Each instance of
+.Sq \e Ns Em n ,
+where
+.Em n
+is a digit, is replaced by
+the substring indicated by
+.Em startp Ns Bq Em n
+and
+.Em endp Ns Bq Em n .
+To get a literal `&' or
+.Sq \e Ns Em n
+into
+.Fa dest ,
+prefix it with `\e';
+to get a literal `\e' preceding `&' or
+.Sq \e Ns Em n ,
+prefix it with
+another `\e'.
+.Pp
+The
+.Fn regerror
+function
+is called whenever an error is detected in
+.Fn regcomp ,
+.Fn regexec ,
+or
+.Fn regsub .
+The default
+.Fn regerror
+writes the string
+.Fa msg ,
+with a suitable indicator of origin,
+on the standard
+error output
+and invokes
+.Xr exit 3 .
+The
+.Fn regerror
+function
+can be replaced by the user if other actions are desirable.
+.Sh REGULAR EXPRESSION SYNTAX
+A regular expression is zero or more
+.Em branches ,
+separated by `|'.
+It matches anything that matches one of the branches.
+.Pp
+A branch is zero or more
+.Em pieces ,
+concatenated.
+It matches a match for the first, followed by a match for the second, etc.
+.Pp
+A piece is an
+.Em atom
+possibly followed by `*', `+', or `?'.
+An atom followed by `*' matches a sequence of 0 or more matches of the atom.
+An atom followed by `+' matches a sequence of 1 or more matches of the atom.
+An atom followed by `?' matches a match of the atom, or the null string.
+.Pp
+An atom is a regular expression in parentheses (matching a match for the
+regular expression), a
+.Em range
+(see below), `.'
+(matching any single character), `^' (matching the null string at the
+beginning of the input string), `$' (matching the null string at the
+end of the input string), a `\e' followed by a single character (matching
+that character), or a single character with no other significance
+(matching that character).
+.Pp
+A
+.Em range
+is a sequence of characters enclosed in `[]'.
+It normally matches any single character from the sequence.
+If the sequence begins with `^',
+it matches any single character
+.Em not
+from the rest of the sequence.
+If two characters in the sequence are separated by `\-', this is shorthand
+for the full list of
+.Tn ASCII
+characters between them
+(e.g. `[0-9]' matches any decimal digit).
+To include a literal `]' in the sequence, make it the first character
+(following a possible `^').
+To include a literal `\-', make it the first or last character.
+.Sh AMBIGUITY
+If a regular expression could match two different parts of the input string,
+it will match the one which begins earliest.
+If both begin in the same place but match different lengths, or match
+the same length in different ways, life gets messier, as follows.
+.Pp
+In general, the possibilities in a list of branches are considered in
+left-to-right order, the possibilities for `*', `+', and `?' are
+considered longest-first, nested constructs are considered from the
+outermost in, and concatenated constructs are considered leftmost-first.
+The match that will be chosen is the one that uses the earliest
+possibility in the first choice that has to be made.
+If there is more than one choice, the next will be made in the same manner
+(earliest possibility) subject to the decision on the first choice.
+And so forth.
+.Pp
+For example,
+.Sq Li (ab|a)b*c
+could match
+`abc' in one of two ways.
+The first choice is between `ab' and `a'; since `ab' is earlier, and does
+lead to a successful overall match, it is chosen.
+Since the `b' is already spoken for,
+the `b*' must match its last possibility\(emthe empty string\(emsince
+it must respect the earlier choice.
+.Pp
+In the particular case where no `|'s are present and there is only one
+`*', `+', or `?', the net effect is that the longest possible
+match will be chosen.
+So
+.Sq Li ab* ,
+presented with `xabbbby', will match `abbbb'.
+Note that if
+.Sq Li ab* ,
+is tried against `xabyabbbz', it
+will match `ab' just after `x', due to the begins-earliest rule.
+(In effect, the decision on where to start the match is the first choice
+to be made, hence subsequent choices must respect it even if this leads them
+to less-preferred alternatives.)
+.Sh RETURN VALUES
+The
+.Fn regcomp
+function
+returns
+.Dv NULL
+for a failure
+.Pf ( Fn regerror
+permitting),
+where failures are syntax errors, exceeding implementation limits,
+or applying `+' or `*' to a possibly-null operand.
+.Sh SEE ALSO
+.Xr ed 1 ,
+.Xr egrep 1 ,
+.Xr ex 1 ,
+.Xr expr 1 ,
+.Xr fgrep 1 ,
+.Xr grep 1 ,
+.Xr regex 3
+.Sh HISTORY
+Both code and manual page for
+.Fn regcomp ,
+.Fn regexec ,
+.Fn regsub ,
+and
+.Fn regerror
+were written at the University of Toronto
+and appeared in
+.Bx 4.3 tahoe .
+They are intended to be compatible with the Bell V8
+.Xr regexp 3 ,
+but are not derived from Bell code.
+.Sh BUGS
+Empty branches and empty regular expressions are not portable to V8.
+.Pp
+The restriction against
+applying `*' or `+' to a possibly-null operand is an artifact of the
+simplistic implementation.
+.Pp
+Does not support
+.Xr egrep Ns 's
+newline-separated branches;
+neither does the V8
+.Xr regexp 3 ,
+though.
+.Pp
+Due to emphasis on
+compactness and simplicity,
+it's not strikingly fast.
+It does give special attention to handling simple cases quickly.
diff --git a/lib/libcompat/regexp/regexp.c b/lib/libcompat/regexp/regexp.c
new file mode 100644
index 0000000..fc97378
--- /dev/null
+++ b/lib/libcompat/regexp/regexp.c
@@ -0,0 +1,1333 @@
+/*
+ * regcomp and regexec -- regsub and regerror are elsewhere
+ *
+ * Copyright (c) 1986 by University of Toronto.
+ * Written by Henry Spencer. Not derived from licensed software.
+ *
+ * Permission is granted to anyone to use this software for any
+ * purpose on any computer system, and to redistribute it freely,
+ * subject to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of
+ * this software, no matter how awful, even if they arise
+ * from defects in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either
+ * by explicit claim or by omission.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not
+ * be misrepresented as being the original software.
+ *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
+ *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to |
+ *** to assist in implementing egrep.
+ *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
+ *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching
+ *** as in BSD grep and ex.
+ *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
+ *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \.
+ *** THIS IS AN ALTERED VERSION. It was altered by James A. Woods,
+ *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy.
+ *
+ * Beware that some of this code is subtly aware of the way operator
+ * precedence is structured in regular expressions. Serious changes in
+ * regular-expression syntax might require a total rethink.
+ */
+#include <limits.h>
+#include <regexp.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "collate.h"
+#include "regmagic.h"
+
+/*
+ * The "internal use only" fields in regexp.h are present to pass info from
+ * compile to execute that permits the execute phase to run lots faster on
+ * simple cases. They are:
+ *
+ * regstart char that must begin a match; '\0' if none obvious
+ * reganch is the match anchored (at beginning-of-line only)?
+ * regmust string (pointer into program) that match must include, or NULL
+ * regmlen length of regmust string
+ *
+ * Regstart and reganch permit very fast decisions on suitable starting points
+ * for a match, cutting down the work a lot. Regmust permits fast rejection
+ * of lines that cannot possibly match. The regmust tests are costly enough
+ * that regcomp() supplies a regmust only if the r.e. contains something
+ * potentially expensive (at present, the only such thing detected is * or +
+ * at the start of the r.e., which can involve a lot of backup). Regmlen is
+ * supplied because the test in regexec() needs it and regcomp() is computing
+ * it anyway.
+ */
+
+/*
+ * Structure for regexp "program". This is essentially a linear encoding
+ * of a nondeterministic finite-state machine (aka syntax charts or
+ * "railroad normal form" in parsing technology). Each node is an opcode
+ * plus a "next" pointer, possibly plus an operand. "Next" pointers of
+ * all nodes except BRANCH implement concatenation; a "next" pointer with
+ * a BRANCH on both ends of it is connecting two alternatives. (Here we
+ * have one of the subtle syntax dependencies: an individual BRANCH (as
+ * opposed to a collection of them) is never concatenated with anything
+ * because of operator precedence.) The operand of some types of node is
+ * a literal string; for others, it is a node leading into a sub-FSM. In
+ * particular, the operand of a BRANCH node is the first node of the branch.
+ * (NB this is *not* a tree structure: the tail of the branch connects
+ * to the thing following the set of BRANCHes.) The opcodes are:
+ */
+
+/* definition number opnd? meaning */
+#define END 0 /* no End of program. */
+#define BOL 1 /* no Match "" at beginning of line. */
+#define EOL 2 /* no Match "" at end of line. */
+#define ANY 3 /* no Match any one character. */
+#define ANYOF 4 /* str Match any character in this string. */
+#define ANYBUT 5 /* str Match any character not in this string. */
+#define BRANCH 6 /* node Match this alternative, or the next... */
+#define BACK 7 /* no Match "", "next" ptr points backward. */
+#define EXACTLY 8 /* str Match this string. */
+#define NOTHING 9 /* no Match empty string. */
+#define STAR 10 /* node Match this (simple) thing 0 or more times. */
+#define PLUS 11 /* node Match this (simple) thing 1 or more times. */
+#define WORDA 12 /* no Match "" at wordchar, where prev is nonword */
+#define WORDZ 13 /* no Match "" at nonwordchar, where prev is word */
+#define OPEN 20 /* no Mark this point in input as start of #n. */
+ /* OPEN+1 is number 1, etc. */
+#define CLOSE 30 /* no Analogous to OPEN. */
+
+/*
+ * Opcode notes:
+ *
+ * BRANCH The set of branches constituting a single choice are hooked
+ * together with their "next" pointers, since precedence prevents
+ * anything being concatenated to any individual branch. The
+ * "next" pointer of the last BRANCH in a choice points to the
+ * thing following the whole choice. This is also where the
+ * final "next" pointer of each individual branch points; each
+ * branch starts with the operand node of a BRANCH node.
+ *
+ * BACK Normal "next" pointers all implicitly point forward; BACK
+ * exists to make loop structures possible.
+ *
+ * STAR,PLUS '?', and complex '*' and '+', are implemented as circular
+ * BRANCH structures using BACK. Simple cases (one character
+ * per match) are implemented with STAR and PLUS for speed
+ * and to minimize recursive plunges.
+ *
+ * OPEN,CLOSE ...are numbered at compile time.
+ */
+
+/*
+ * A node is one char of opcode followed by two chars of "next" pointer.
+ * "Next" pointers are stored as two 8-bit pieces, high order first. The
+ * value is a positive offset from the opcode of the node containing it.
+ * An operand, if any, simply follows the node. (Note that much of the
+ * code generation knows about this implicit relationship.)
+ *
+ * Using two bytes for the "next" pointer is vast overkill for most things,
+ * but allows patterns to get big without disasters.
+ */
+#define OP(p) (*(p))
+#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
+#define OPERAND(p) ((p) + 3)
+
+/*
+ * See regmagic.h for one further detail of program structure.
+ */
+
+
+/*
+ * Utility definitions.
+ */
+#ifndef CHARBITS
+#define UCHARAT(p) ((int)*(unsigned char *)(p))
+#else
+#define UCHARAT(p) ((int)*(p)&CHARBITS)
+#endif
+
+#define FAIL(m) { regerror(m); return(NULL); }
+#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
+
+/*
+ * Flags to be passed up and down.
+ */
+#define HASWIDTH 01 /* Known never to match null string. */
+#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
+#define SPSTART 04 /* Starts with * or +. */
+#define WORST 0 /* Worst case. */
+
+/*
+ * Global work variables for regcomp().
+ */
+static char *regparse; /* Input-scan pointer. */
+static int regnpar; /* () count. */
+static char regdummy;
+static char *regcode; /* Code-emit pointer; &regdummy = don't. */
+static long regsize; /* Code size. */
+
+/*
+ * Forward declarations for regcomp()'s friends.
+ */
+#ifndef STATIC
+#define STATIC static
+#endif
+STATIC char *reg();
+STATIC char *regbranch();
+STATIC char *regpiece();
+STATIC char *regatom();
+STATIC char *regnode();
+STATIC char *regnext();
+STATIC void regc();
+STATIC void reginsert();
+STATIC void regtail();
+STATIC void regoptail();
+#ifdef STRCSPN
+STATIC int strcspn();
+#endif
+
+/*
+ - regcomp - compile a regular expression into internal code
+ *
+ * We can't allocate space until we know how big the compiled form will be,
+ * but we can't compile it (and thus know how big it is) until we've got a
+ * place to put the code. So we cheat: we compile it twice, once with code
+ * generation turned off and size counting turned on, and once "for real".
+ * This also means that we don't allocate space until we are sure that the
+ * thing really will compile successfully, and we never have to move the
+ * code and thus invalidate pointers into it. (Note that it has to be in
+ * one piece because free() must be able to free it all.)
+ *
+ * Beware that the optimization-preparation code in here knows about some
+ * of the structure of the compiled regexp.
+ */
+regexp *
+regcomp(exp)
+const char *exp;
+{
+ register regexp *r;
+ register char *scan;
+ register char *longest;
+ register int len;
+ int flags;
+
+ if (exp == NULL)
+ FAIL("NULL argument");
+
+ /* First pass: determine size, legality. */
+#ifdef notdef
+ if (exp[0] == '.' && exp[1] == '*') exp += 2; /* aid grep */
+#endif
+ regparse = (char *)exp;
+ regnpar = 1;
+ regsize = 0L;
+ regcode = &regdummy;
+ regc(MAGIC);
+ if (reg(0, &flags) == NULL)
+ return(NULL);
+
+ /* Small enough for pointer-storage convention? */
+ if (regsize >= 32767L) /* Probably could be 65535L. */
+ FAIL("regexp too big");
+
+ /* Allocate space. */
+ r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize);
+ if (r == NULL)
+ FAIL("out of space");
+
+ /* Second pass: emit code. */
+ regparse = (char *)exp;
+ regnpar = 1;
+ regcode = r->program;
+ regc(MAGIC);
+ if (reg(0, &flags) == NULL)
+ return(NULL);
+
+ /* Dig out information for optimizations. */
+ r->regstart = '\0'; /* Worst-case defaults. */
+ r->reganch = 0;
+ r->regmust = NULL;
+ r->regmlen = 0;
+ scan = r->program+1; /* First BRANCH. */
+ if (OP(regnext(scan)) == END) { /* Only one top-level choice. */
+ scan = OPERAND(scan);
+
+ /* Starting-point info. */
+ if (OP(scan) == EXACTLY)
+ r->regstart = *OPERAND(scan);
+ else if (OP(scan) == BOL)
+ r->reganch++;
+
+ /*
+ * If there's something expensive in the r.e., find the
+ * longest literal string that must appear and make it the
+ * regmust. Resolve ties in favor of later strings, since
+ * the regstart check works with the beginning of the r.e.
+ * and avoiding duplication strengthens checking. Not a
+ * strong reason, but sufficient in the absence of others.
+ */
+ if (flags&SPSTART) {
+ longest = NULL;
+ len = 0;
+ for (; scan != NULL; scan = regnext(scan))
+ if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
+ longest = OPERAND(scan);
+ len = strlen(OPERAND(scan));
+ }
+ r->regmust = longest;
+ r->regmlen = len;
+ }
+ }
+
+ return(r);
+}
+
+/*
+ - reg - regular expression, i.e. main body or parenthesized thing
+ *
+ * Caller must absorb opening parenthesis.
+ *
+ * Combining parenthesis handling with the base level of regular expression
+ * is a trifle forced, but the need to tie the tails of the branches to what
+ * follows makes it hard to avoid.
+ */
+static char *
+reg(paren, flagp)
+int paren; /* Parenthesized? */
+int *flagp;
+{
+ register char *ret;
+ register char *br;
+ register char *ender;
+ register int parno;
+ int flags;
+
+ *flagp = HASWIDTH; /* Tentatively. */
+
+ /* Make an OPEN node, if parenthesized. */
+ if (paren) {
+ if (regnpar >= NSUBEXP)
+ FAIL("too many ()");
+ parno = regnpar;
+ regnpar++;
+ ret = regnode(OPEN+parno);
+ } else
+ ret = NULL;
+
+ /* Pick up the branches, linking them together. */
+ br = regbranch(&flags);
+ if (br == NULL)
+ return(NULL);
+ if (ret != NULL)
+ regtail(ret, br); /* OPEN -> first. */
+ else
+ ret = br;
+ if (!(flags&HASWIDTH))
+ *flagp &= ~HASWIDTH;
+ *flagp |= flags&SPSTART;
+ while (*regparse == '|' || *regparse == '\n') {
+ regparse++;
+ br = regbranch(&flags);
+ if (br == NULL)
+ return(NULL);
+ regtail(ret, br); /* BRANCH -> BRANCH. */
+ if (!(flags&HASWIDTH))
+ *flagp &= ~HASWIDTH;
+ *flagp |= flags&SPSTART;
+ }
+
+ /* Make a closing node, and hook it on the end. */
+ ender = regnode((paren) ? CLOSE+parno : END);
+ regtail(ret, ender);
+
+ /* Hook the tails of the branches to the closing node. */
+ for (br = ret; br != NULL; br = regnext(br))
+ regoptail(br, ender);
+
+ /* Check for proper termination. */
+ if (paren && *regparse++ != ')') {
+ FAIL("unmatched ()");
+ } else if (!paren && *regparse != '\0') {
+ if (*regparse == ')') {
+ FAIL("unmatched ()");
+ } else
+ FAIL("junk on end"); /* "Can't happen". */
+ /* NOTREACHED */
+ }
+
+ return(ret);
+}
+
+/*
+ - regbranch - one alternative of an | operator
+ *
+ * Implements the concatenation operator.
+ */
+static char *
+regbranch(flagp)
+int *flagp;
+{
+ register char *ret;
+ register char *chain;
+ register char *latest;
+ int flags;
+
+ *flagp = WORST; /* Tentatively. */
+
+ ret = regnode(BRANCH);
+ chain = NULL;
+ while (*regparse != '\0' && *regparse != ')' &&
+ *regparse != '\n' && *regparse != '|') {
+ latest = regpiece(&flags);
+ if (latest == NULL)
+ return(NULL);
+ *flagp |= flags&HASWIDTH;
+ if (chain == NULL) /* First piece. */
+ *flagp |= flags&SPSTART;
+ else
+ regtail(chain, latest);
+ chain = latest;
+ }
+ if (chain == NULL) /* Loop ran zero times. */
+ (void) regnode(NOTHING);
+
+ return(ret);
+}
+
+/*
+ - regpiece - something followed by possible [*+?]
+ *
+ * Note that the branching code sequences used for ? and the general cases
+ * of * and + are somewhat optimized: they use the same NOTHING node as
+ * both the endmarker for their branch list and the body of the last branch.
+ * It might seem that this node could be dispensed with entirely, but the
+ * endmarker role is not redundant.
+ */
+static char *
+regpiece(flagp)
+int *flagp;
+{
+ register char *ret;
+ register char op;
+ register char *next;
+ int flags;
+
+ ret = regatom(&flags);
+ if (ret == NULL)
+ return(NULL);
+
+ op = *regparse;
+ if (!ISMULT(op)) {
+ *flagp = flags;
+ return(ret);
+ }
+
+ if (!(flags&HASWIDTH) && op != '?')
+ FAIL("*+ operand could be empty");
+ *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
+
+ if (op == '*' && (flags&SIMPLE))
+ reginsert(STAR, ret);
+ else if (op == '*') {
+ /* Emit x* as (x&|), where & means "self". */
+ reginsert(BRANCH, ret); /* Either x */
+ regoptail(ret, regnode(BACK)); /* and loop */
+ regoptail(ret, ret); /* back */
+ regtail(ret, regnode(BRANCH)); /* or */
+ regtail(ret, regnode(NOTHING)); /* null. */
+ } else if (op == '+' && (flags&SIMPLE))
+ reginsert(PLUS, ret);
+ else if (op == '+') {
+ /* Emit x+ as x(&|), where & means "self". */
+ next = regnode(BRANCH); /* Either */
+ regtail(ret, next);
+ regtail(regnode(BACK), ret); /* loop back */
+ regtail(next, regnode(BRANCH)); /* or */
+ regtail(ret, regnode(NOTHING)); /* null. */
+ } else if (op == '?') {
+ /* Emit x? as (x|) */
+ reginsert(BRANCH, ret); /* Either x */
+ regtail(ret, regnode(BRANCH)); /* or */
+ next = regnode(NOTHING); /* null. */
+ regtail(ret, next);
+ regoptail(ret, next);
+ }
+ regparse++;
+ if (ISMULT(*regparse))
+ FAIL("nested *?+");
+
+ return(ret);
+}
+
+/*
+ - regatom - the lowest level
+ *
+ * Optimization: gobbles an entire sequence of ordinary characters so that
+ * it can turn them into a single node, which is smaller to store and
+ * faster to run. Backslashed characters are exceptions, each becoming a
+ * separate node; the code is simpler that way and it's not worth fixing.
+ */
+static char *
+regatom(flagp)
+int *flagp;
+{
+ register char *ret;
+ int flags;
+
+ *flagp = WORST; /* Tentatively. */
+
+ switch (*regparse++) {
+ /* FIXME: these chars only have meaning at beg/end of pat? */
+ case '^':
+ ret = regnode(BOL);
+ break;
+ case '$':
+ ret = regnode(EOL);
+ break;
+ case '.':
+ ret = regnode(ANY);
+ *flagp |= HASWIDTH|SIMPLE;
+ break;
+ case '[': {
+ register int class;
+ register int classend;
+ int i;
+
+ if (*regparse == '^') { /* Complement of range. */
+ ret = regnode(ANYBUT);
+ regparse++;
+ } else
+ ret = regnode(ANYOF);
+ if (*regparse == ']' || *regparse == '-')
+ regc(*regparse++);
+ while (*regparse != '\0' && *regparse != ']') {
+ if (*regparse == '-') {
+ regparse++;
+ if (*regparse == ']' || *regparse == '\0')
+ regc('-');
+ else {
+ class = UCHARAT(regparse-2);
+ classend = UCHARAT(regparse);
+ if (__collate_load_error) {
+ if (class > classend)
+ FAIL("invalid [] range");
+ for (class++; class <= classend; class++)
+ regc(class);
+ } else {
+ if (__collate_range_cmp(class, classend) > 0)
+ FAIL("invalid [] range");
+ for (i = 0; i <= UCHAR_MAX; i++)
+ if ( i != class
+ && __collate_range_cmp(class, i) <= 0
+ && __collate_range_cmp(i, classend) <= 0
+ )
+ regc(i);
+ }
+ regparse++;
+ }
+ } else
+ regc(*regparse++);
+ }
+ regc('\0');
+ if (*regparse != ']')
+ FAIL("unmatched []");
+ regparse++;
+ *flagp |= HASWIDTH|SIMPLE;
+ }
+ break;
+ case '(':
+ ret = reg(1, &flags);
+ if (ret == NULL)
+ return(NULL);
+ *flagp |= flags&(HASWIDTH|SPSTART);
+ break;
+ case '\0':
+ case '|':
+ case '\n':
+ case ')':
+ FAIL("internal urp"); /* Supposed to be caught earlier. */
+ break;
+ case '?':
+ case '+':
+ case '*':
+ FAIL("?+* follows nothing");
+ break;
+ case '\\':
+ switch (*regparse++) {
+ case '\0':
+ FAIL("trailing \\");
+ break;
+ case '<':
+ ret = regnode(WORDA);
+ break;
+ case '>':
+ ret = regnode(WORDZ);
+ break;
+ /* FIXME: Someday handle \1, \2, ... */
+ default:
+ /* Handle general quoted chars in exact-match routine */
+ goto de_fault;
+ }
+ break;
+ de_fault:
+ default:
+ /*
+ * Encode a string of characters to be matched exactly.
+ *
+ * This is a bit tricky due to quoted chars and due to
+ * '*', '+', and '?' taking the SINGLE char previous
+ * as their operand.
+ *
+ * On entry, the char at regparse[-1] is going to go
+ * into the string, no matter what it is. (It could be
+ * following a \ if we are entered from the '\' case.)
+ *
+ * Basic idea is to pick up a good char in ch and
+ * examine the next char. If it's *+? then we twiddle.
+ * If it's \ then we frozzle. If it's other magic char
+ * we push ch and terminate the string. If none of the
+ * above, we push ch on the string and go around again.
+ *
+ * regprev is used to remember where "the current char"
+ * starts in the string, if due to a *+? we need to back
+ * up and put the current char in a separate, 1-char, string.
+ * When regprev is NULL, ch is the only char in the
+ * string; this is used in *+? handling, and in setting
+ * flags |= SIMPLE at the end.
+ */
+ {
+ char *regprev;
+ register char ch;
+
+ regparse--; /* Look at cur char */
+ ret = regnode(EXACTLY);
+ for ( regprev = 0 ; ; ) {
+ ch = *regparse++; /* Get current char */
+ switch (*regparse) { /* look at next one */
+
+ default:
+ regc(ch); /* Add cur to string */
+ break;
+
+ case '.': case '[': case '(':
+ case ')': case '|': case '\n':
+ case '$': case '^':
+ case '\0':
+ /* FIXME, $ and ^ should not always be magic */
+ magic:
+ regc(ch); /* dump cur char */
+ goto done; /* and we are done */
+
+ case '?': case '+': case '*':
+ if (!regprev) /* If just ch in str, */
+ goto magic; /* use it */
+ /* End mult-char string one early */
+ regparse = regprev; /* Back up parse */
+ goto done;
+
+ case '\\':
+ regc(ch); /* Cur char OK */
+ switch (regparse[1]){ /* Look after \ */
+ case '\0':
+ case '<':
+ case '>':
+ /* FIXME: Someday handle \1, \2, ... */
+ goto done; /* Not quoted */
+ default:
+ /* Backup point is \, scan * point is after it. */
+ regprev = regparse;
+ regparse++;
+ continue; /* NOT break; */
+ }
+ }
+ regprev = regparse; /* Set backup point */
+ }
+ done:
+ regc('\0');
+ *flagp |= HASWIDTH;
+ if (!regprev) /* One char? */
+ *flagp |= SIMPLE;
+ }
+ break;
+ }
+
+ return(ret);
+}
+
+/*
+ - regnode - emit a node
+ */
+static char * /* Location. */
+regnode(op)
+char op;
+{
+ register char *ret;
+ register char *ptr;
+
+ ret = regcode;
+ if (ret == &regdummy) {
+ regsize += 3;
+ return(ret);
+ }
+
+ ptr = ret;
+ *ptr++ = op;
+ *ptr++ = '\0'; /* Null "next" pointer. */
+ *ptr++ = '\0';
+ regcode = ptr;
+
+ return(ret);
+}
+
+/*
+ - regc - emit (if appropriate) a byte of code
+ */
+static void
+regc(b)
+char b;
+{
+ if (regcode != &regdummy)
+ *regcode++ = b;
+ else
+ regsize++;
+}
+
+/*
+ - reginsert - insert an operator in front of already-emitted operand
+ *
+ * Means relocating the operand.
+ */
+static void
+reginsert(op, opnd)
+char op;
+char *opnd;
+{
+ register char *src;
+ register char *dst;
+ register char *place;
+
+ if (regcode == &regdummy) {
+ regsize += 3;
+ return;
+ }
+
+ src = regcode;
+ regcode += 3;
+ dst = regcode;
+ while (src > opnd)
+ *--dst = *--src;
+
+ place = opnd; /* Op node, where operand used to be. */
+ *place++ = op;
+ *place++ = '\0';
+ *place++ = '\0';
+}
+
+/*
+ - regtail - set the next-pointer at the end of a node chain
+ */
+static void
+regtail(p, val)
+char *p;
+char *val;
+{
+ register char *scan;
+ register char *temp;
+ register int offset;
+
+ if (p == &regdummy)
+ return;
+
+ /* Find last node. */
+ scan = p;
+ for (;;) {
+ temp = regnext(scan);
+ if (temp == NULL)
+ break;
+ scan = temp;
+ }
+
+ if (OP(scan) == BACK)
+ offset = scan - val;
+ else
+ offset = val - scan;
+ *(scan+1) = (offset>>8)&0377;
+ *(scan+2) = offset&0377;
+}
+
+/*
+ - regoptail - regtail on operand of first argument; nop if operandless
+ */
+static void
+regoptail(p, val)
+char *p;
+char *val;
+{
+ /* "Operandless" and "op != BRANCH" are synonymous in practice. */
+ if (p == NULL || p == &regdummy || OP(p) != BRANCH)
+ return;
+ regtail(OPERAND(p), val);
+}
+
+/*
+ * regexec and friends
+ */
+
+/*
+ * Global work variables for regexec().
+ */
+static char *reginput; /* String-input pointer. */
+static char *regbol; /* Beginning of input, for ^ check. */
+static char **regstartp; /* Pointer to startp array. */
+static char **regendp; /* Ditto for endp. */
+
+/*
+ * Forwards.
+ */
+STATIC int regtry();
+STATIC int regmatch();
+STATIC int regrepeat();
+
+#ifdef DEBUG
+int regnarrate = 0;
+void regdump();
+STATIC char *regprop();
+#endif
+
+/*
+ - regexec - match a regexp against a string
+ */
+int
+regexec(prog, string)
+register const regexp *prog;
+register const char *string;
+{
+ register char *s;
+ extern char *strchr();
+
+ /* Be paranoid... */
+ if (prog == NULL || string == NULL) {
+ regerror("NULL parameter");
+ return(0);
+ }
+
+ /* Check validity of program. */
+ if (UCHARAT(prog->program) != MAGIC) {
+ regerror("corrupted program");
+ return(0);
+ }
+
+ /* If there is a "must appear" string, look for it. */
+ if (prog->regmust != NULL) {
+ s = (char *)string;
+ while ((s = strchr(s, prog->regmust[0])) != NULL) {
+ if (strncmp(s, prog->regmust, prog->regmlen) == 0)
+ break; /* Found it. */
+ s++;
+ }
+ if (s == NULL) /* Not present. */
+ return(0);
+ }
+
+ /* Mark beginning of line for ^ . */
+ regbol = (char *)string;
+
+ /* Simplest case: anchored match need be tried only once. */
+ if (prog->reganch)
+ return(regtry(prog, string));
+
+ /* Messy cases: unanchored match. */
+ s = (char *)string;
+ if (prog->regstart != '\0')
+ /* We know what char it must start with. */
+ while ((s = strchr(s, prog->regstart)) != NULL) {
+ if (regtry(prog, s))
+ return(1);
+ s++;
+ }
+ else
+ /* We don't -- general case. */
+ do {
+ if (regtry(prog, s))
+ return(1);
+ } while (*s++ != '\0');
+
+ /* Failure. */
+ return(0);
+}
+
+/*
+ - regtry - try match at specific point
+ */
+static int /* 0 failure, 1 success */
+regtry(prog, string)
+regexp *prog;
+char *string;
+{
+ register int i;
+ register char **sp;
+ register char **ep;
+
+ reginput = string;
+ regstartp = prog->startp;
+ regendp = prog->endp;
+
+ sp = prog->startp;
+ ep = prog->endp;
+ for (i = NSUBEXP; i > 0; i--) {
+ *sp++ = NULL;
+ *ep++ = NULL;
+ }
+ if (regmatch(prog->program + 1)) {
+ prog->startp[0] = string;
+ prog->endp[0] = reginput;
+ return(1);
+ } else
+ return(0);
+}
+
+/*
+ - regmatch - main matching routine
+ *
+ * Conceptually the strategy is simple: check to see whether the current
+ * node matches, call self recursively to see whether the rest matches,
+ * and then act accordingly. In practice we make some effort to avoid
+ * recursion, in particular by going through "ordinary" nodes (that don't
+ * need to know whether the rest of the match failed) by a loop instead of
+ * by recursion.
+ */
+static int /* 0 failure, 1 success */
+regmatch(prog)
+char *prog;
+{
+ register char *scan; /* Current node. */
+ char *next; /* Next node. */
+
+ scan = prog;
+#ifdef DEBUG
+ if (scan != NULL && regnarrate)
+ fprintf(stderr, "%s(\n", regprop(scan));
+#endif
+ while (scan != NULL) {
+#ifdef DEBUG
+ if (regnarrate)
+ fprintf(stderr, "%s...\n", regprop(scan));
+#endif
+ next = regnext(scan);
+
+ switch (OP(scan)) {
+ case BOL:
+ if (reginput != regbol)
+ return(0);
+ break;
+ case EOL:
+ if (*reginput != '\0')
+ return(0);
+ break;
+ case WORDA:
+ /* Must be looking at a letter, digit, or _ */
+ if ((!isalnum((unsigned char)*reginput)) && *reginput != '_')
+ return(0);
+ /* Prev must be BOL or nonword */
+ if (reginput > regbol &&
+ (isalnum((unsigned char)reginput[-1]) || reginput[-1] == '_'))
+ return(0);
+ break;
+ case WORDZ:
+ /* Must be looking at non letter, digit, or _ */
+ if (isalnum((unsigned char)*reginput) || *reginput == '_')
+ return(0);
+ /* We don't care what the previous char was */
+ break;
+ case ANY:
+ if (*reginput == '\0')
+ return(0);
+ reginput++;
+ break;
+ case EXACTLY: {
+ register int len;
+ register char *opnd;
+
+ opnd = OPERAND(scan);
+ /* Inline the first character, for speed. */
+ if (*opnd != *reginput)
+ return(0);
+ len = strlen(opnd);
+ if (len > 1 && strncmp(opnd, reginput, len) != 0)
+ return(0);
+ reginput += len;
+ }
+ break;
+ case ANYOF:
+ if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
+ return(0);
+ reginput++;
+ break;
+ case ANYBUT:
+ if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
+ return(0);
+ reginput++;
+ break;
+ case NOTHING:
+ break;
+ case BACK:
+ break;
+ case OPEN+1:
+ case OPEN+2:
+ case OPEN+3:
+ case OPEN+4:
+ case OPEN+5:
+ case OPEN+6:
+ case OPEN+7:
+ case OPEN+8:
+ case OPEN+9: {
+ register int no;
+ register char *save;
+
+ no = OP(scan) - OPEN;
+ save = reginput;
+
+ if (regmatch(next)) {
+ /*
+ * Don't set startp if some later
+ * invocation of the same parentheses
+ * already has.
+ */
+ if (regstartp[no] == NULL)
+ regstartp[no] = save;
+ return(1);
+ } else
+ return(0);
+ }
+ break;
+ case CLOSE+1:
+ case CLOSE+2:
+ case CLOSE+3:
+ case CLOSE+4:
+ case CLOSE+5:
+ case CLOSE+6:
+ case CLOSE+7:
+ case CLOSE+8:
+ case CLOSE+9: {
+ register int no;
+ register char *save;
+
+ no = OP(scan) - CLOSE;
+ save = reginput;
+
+ if (regmatch(next)) {
+ /*
+ * Don't set endp if some later
+ * invocation of the same parentheses
+ * already has.
+ */
+ if (regendp[no] == NULL)
+ regendp[no] = save;
+ return(1);
+ } else
+ return(0);
+ }
+ break;
+ case BRANCH: {
+ register char *save;
+
+ if (OP(next) != BRANCH) /* No choice. */
+ next = OPERAND(scan); /* Avoid recursion. */
+ else {
+ do {
+ save = reginput;
+ if (regmatch(OPERAND(scan)))
+ return(1);
+ reginput = save;
+ scan = regnext(scan);
+ } while (scan != NULL && OP(scan) == BRANCH);
+ return(0);
+ /* NOTREACHED */
+ }
+ }
+ break;
+ case STAR:
+ case PLUS: {
+ register char nextch;
+ register int no;
+ register char *save;
+ register int min;
+
+ /*
+ * Lookahead to avoid useless match attempts
+ * when we know what character comes next.
+ */
+ nextch = '\0';
+ if (OP(next) == EXACTLY)
+ nextch = *OPERAND(next);
+ min = (OP(scan) == STAR) ? 0 : 1;
+ save = reginput;
+ no = regrepeat(OPERAND(scan));
+ while (no >= min) {
+ /* If it could work, try it. */
+ if (nextch == '\0' || *reginput == nextch)
+ if (regmatch(next))
+ return(1);
+ /* Couldn't or didn't -- back up. */
+ no--;
+ reginput = save + no;
+ }
+ return(0);
+ }
+ break;
+ case END:
+ return(1); /* Success! */
+ break;
+ default:
+ regerror("memory corruption");
+ return(0);
+ break;
+ }
+
+ scan = next;
+ }
+
+ /*
+ * We get here only if there's trouble -- normally "case END" is
+ * the terminating point.
+ */
+ regerror("corrupted pointers");
+ return(0);
+}
+
+/*
+ - regrepeat - repeatedly match something simple, report how many
+ */
+static int
+regrepeat(p)
+char *p;
+{
+ register int count = 0;
+ register char *scan;
+ register char *opnd;
+
+ scan = reginput;
+ opnd = OPERAND(p);
+ switch (OP(p)) {
+ case ANY:
+ count = strlen(scan);
+ scan += count;
+ break;
+ case EXACTLY:
+ while (*opnd == *scan) {
+ count++;
+ scan++;
+ }
+ break;
+ case ANYOF:
+ while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
+ count++;
+ scan++;
+ }
+ break;
+ case ANYBUT:
+ while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
+ count++;
+ scan++;
+ }
+ break;
+ default: /* Oh dear. Called inappropriately. */
+ regerror("internal foulup");
+ count = 0; /* Best compromise. */
+ break;
+ }
+ reginput = scan;
+
+ return(count);
+}
+
+/*
+ - regnext - dig the "next" pointer out of a node
+ */
+static char *
+regnext(p)
+register char *p;
+{
+ register int offset;
+
+ if (p == &regdummy)
+ return(NULL);
+
+ offset = NEXT(p);
+ if (offset == 0)
+ return(NULL);
+
+ if (OP(p) == BACK)
+ return(p-offset);
+ else
+ return(p+offset);
+}
+
+#ifdef DEBUG
+
+STATIC char *regprop();
+
+/*
+ - regdump - dump a regexp onto stdout in vaguely comprehensible form
+ */
+void
+regdump(r)
+regexp *r;
+{
+ register char *s;
+ register char op = EXACTLY; /* Arbitrary non-END op. */
+ register char *next;
+ extern char *strchr();
+
+
+ s = r->program + 1;
+ while (op != END) { /* While that wasn't END last time... */
+ op = OP(s);
+ printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
+ next = regnext(s);
+ if (next == NULL) /* Next ptr. */
+ printf("(0)");
+ else
+ printf("(%d)", (s-r->program)+(next-s));
+ s += 3;
+ if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
+ /* Literal string, where present. */
+ while (*s != '\0') {
+ putchar(*s);
+ s++;
+ }
+ s++;
+ }
+ putchar('\n');
+ }
+
+ /* Header fields of interest. */
+ if (r->regstart != '\0')
+ printf("start `%c' ", r->regstart);
+ if (r->reganch)
+ printf("anchored ");
+ if (r->regmust != NULL)
+ printf("must have \"%s\"", r->regmust);
+ printf("\n");
+}
+
+/*
+ - regprop - printable representation of opcode
+ */
+static char *
+regprop(op)
+char *op;
+{
+ register char *p;
+ static char buf[50];
+
+ (void) strcpy(buf, ":");
+
+ switch (OP(op)) {
+ case BOL:
+ p = "BOL";
+ break;
+ case EOL:
+ p = "EOL";
+ break;
+ case ANY:
+ p = "ANY";
+ break;
+ case ANYOF:
+ p = "ANYOF";
+ break;
+ case ANYBUT:
+ p = "ANYBUT";
+ break;
+ case BRANCH:
+ p = "BRANCH";
+ break;
+ case EXACTLY:
+ p = "EXACTLY";
+ break;
+ case NOTHING:
+ p = "NOTHING";
+ break;
+ case BACK:
+ p = "BACK";
+ break;
+ case END:
+ p = "END";
+ break;
+ case OPEN+1:
+ case OPEN+2:
+ case OPEN+3:
+ case OPEN+4:
+ case OPEN+5:
+ case OPEN+6:
+ case OPEN+7:
+ case OPEN+8:
+ case OPEN+9:
+ sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
+ p = NULL;
+ break;
+ case CLOSE+1:
+ case CLOSE+2:
+ case CLOSE+3:
+ case CLOSE+4:
+ case CLOSE+5:
+ case CLOSE+6:
+ case CLOSE+7:
+ case CLOSE+8:
+ case CLOSE+9:
+ sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
+ p = NULL;
+ break;
+ case STAR:
+ p = "STAR";
+ break;
+ case PLUS:
+ p = "PLUS";
+ break;
+ case WORDA:
+ p = "WORDA";
+ break;
+ case WORDZ:
+ p = "WORDZ";
+ break;
+ default:
+ regerror("corrupted opcode");
+ break;
+ }
+ if (p != NULL)
+ (void) strcat(buf, p);
+ return(buf);
+}
+#endif
+
+/*
+ * The following is provided for those people who do not have strcspn() in
+ * their C libraries. They should get off their butts and do something
+ * about it; at least one public-domain implementation of those (highly
+ * useful) string routines has been published on Usenet.
+ */
+#ifdef STRCSPN
+/*
+ * strcspn - find length of initial segment of s1 consisting entirely
+ * of characters not from s2
+ */
+
+static int
+strcspn(s1, s2)
+char *s1;
+char *s2;
+{
+ register char *scan1;
+ register char *scan2;
+ register int count;
+
+ count = 0;
+ for (scan1 = s1; *scan1 != '\0'; scan1++) {
+ for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */
+ if (*scan1 == *scan2++)
+ return(count);
+ count++;
+ }
+ return(count);
+}
+#endif
diff --git a/lib/libcompat/regexp/regmagic.h b/lib/libcompat/regexp/regmagic.h
new file mode 100644
index 0000000..5acf447
--- /dev/null
+++ b/lib/libcompat/regexp/regmagic.h
@@ -0,0 +1,5 @@
+/*
+ * The first byte of the regexp internal "program" is actually this magic
+ * number; the start node begins in the second byte.
+ */
+#define MAGIC 0234
diff --git a/lib/libcompat/regexp/regsub.c b/lib/libcompat/regexp/regsub.c
new file mode 100644
index 0000000..e55b9b6
--- /dev/null
+++ b/lib/libcompat/regexp/regsub.c
@@ -0,0 +1,81 @@
+/*
+ * regsub
+ *
+ * Copyright (c) 1986 by University of Toronto.
+ * Written by Henry Spencer. Not derived from licensed software.
+ *
+ * Permission is granted to anyone to use this software for any
+ * purpose on any computer system, and to redistribute it freely,
+ * subject to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of
+ * this software, no matter how awful, even if they arise
+ * from defects in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either
+ * by explicit claim or by omission.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not
+ * be misrepresented as being the original software.
+ */
+#include <regexp.h>
+#include <stdio.h>
+#include <string.h>
+#include "regmagic.h"
+
+#ifndef CHARBITS
+#define UCHARAT(p) ((int)*(unsigned char *)(p))
+#else
+#define UCHARAT(p) ((int)*(p)&CHARBITS)
+#endif
+
+/*
+ - regsub - perform substitutions after a regexp match
+ */
+void
+regsub(prog, source, dest)
+const regexp *prog;
+const char *source;
+char *dest;
+{
+ register char *src;
+ register char *dst;
+ register char c;
+ register int no;
+ register int len;
+ extern char *strncpy();
+
+ if (prog == NULL || source == NULL || dest == NULL) {
+ regerror("NULL parm to regsub");
+ return;
+ }
+ if (UCHARAT(prog->program) != MAGIC) {
+ regerror("damaged regexp fed to regsub");
+ return;
+ }
+
+ src = (char *)source;
+ dst = dest;
+ while ((c = *src++) != '\0') {
+ if (c == '&')
+ no = 0;
+ else if (c == '\\' && '0' <= *src && *src <= '9')
+ no = *src++ - '0';
+ else
+ no = -1;
+ if (no < 0) { /* Ordinary character. */
+ if (c == '\\' && (*src == '\\' || *src == '&'))
+ c = *src++;
+ *dst++ = c;
+ } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) {
+ len = prog->endp[no] - prog->startp[no];
+ (void) strncpy(dst, prog->startp[no], len);
+ dst += len;
+ if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */
+ regerror("damaged match string");
+ return;
+ }
+ }
+ }
+ *dst++ = '\0';
+}
diff --git a/lib/libcrypt/Makefile b/lib/libcrypt/Makefile
new file mode 100644
index 0000000..ef66357
--- /dev/null
+++ b/lib/libcrypt/Makefile
@@ -0,0 +1,67 @@
+#
+# $FreeBSD$
+#
+
+SHLIB_MAJOR= 2
+LIB= scrypt
+
+LCRYPTBASE= libcrypt
+LSCRYPTBASE= lib${LIB}
+
+LCRYPTSO= ${LCRYPTBASE}.so.${SHLIB_MAJOR}
+LSCRYPTSO= ${LSCRYPTBASE}.so.${SHLIB_MAJOR}
+
+.if ${OBJFORMAT} == elf
+SONAME= ${LCRYPTSO}
+.endif
+
+.PATH: ${.CURDIR}/../libmd
+SRCS= crypt.c crypt-md5.c crypt-shs.c misc.c
+STATICSRCS= md5c.c sha0c.c sha1c.c
+STATICOBJS= ${STATICSRCS:S/.c/.o/g}
+MAN3= crypt.3
+CFLAGS+= -I${.CURDIR}/../libmd
+CFLAGS+= -DLIBC_SCCS -Wall
+PRECIOUSLIB= yes
+
+# Include this early to pick up the definitions of SHLIB_MAJOR and
+# SHLIB_MINOR which are used in the existence tests.
+.include "${.CURDIR}/../Makefile.inc"
+
+# We only install the links if they do not already exist.
+# This may have to be revised
+.if !exists(${DESTDIR}${LIBDIR}/${LCRYPTBASE}.a)
+SYMLINKS+= ${LSCRYPTBASE}.a ${LIBDIR}/${LCRYPTBASE}.a
+.endif
+.if !defined(NOPROFILE) && !exists(${DESTDIR}${LIBDIR}/${LCRYPTBASE}_p.a)
+SYMLINKS+= ${LSCRYPTBASE}_p.a ${LIBDIR}/${LCRYPTBASE}_p.a
+.endif
+.if !defined(NOPIC) && !exists(${DESTDIR}${SHLIBDIR}/${LCRYPTSO})
+SYMLINKS+= ${LSCRYPTSO} ${SHLIBDIR}/${LCRYPTSO}
+.endif
+.if !defined(NOPIC) && ${OBJFORMAT} == elf && \
+ !exists(${DESTDIR}${SHLIBDIR}/${LCRYPTBASE}.so)
+SYMLINKS+= ${LSCRYPTBASE}.so ${SHLIBDIR}/${LCRYPTBASE}.so
+.endif
+
+.include <bsd.lib.mk>
+
+afterinstall:
+.if !defined(NOPIC)
+ @cd ${DESTDIR}${SHLIBDIR}; \
+ rm -f ${LCRYPTSO}; \
+ ln -sf ${LSCRYPTSO} ${LCRYPTSO};
+.endif
+.if !defined(NOPIC) && ${OBJFORMAT} == elf
+ @cd ${DESTDIR}${SHLIBDIR}; \
+ rm -f ${LCRYPTBASE}.so; \
+ ln -sf ${LSCRYPTBASE}.so libcrypt.so
+.endif
+ @cd ${DESTDIR}${LIBDIR}; \
+ rm -f ${LCRYPTBASE}.a; \
+ ln -sf ${LSCRYPTBASE}.a libcrypt.a
+.if !defined(NOPROFILE)
+ @cd ${DESTDIR}${LIBDIR}; \
+ rm -f ${LCRYPTBASE}_p.a; \
+ ln -sf ${LSCRYPTBASE}_p.a libcrypt_p.a
+.endif
diff --git a/lib/libcrypt/crypt-md5.c b/lib/libcrypt/crypt-md5.c
new file mode 100644
index 0000000..c112bd8
--- /dev/null
+++ b/lib/libcrypt/crypt-md5.c
@@ -0,0 +1,187 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = \
+"$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <md5.h>
+#include <err.h>
+#include "crypt.h"
+
+#ifdef __PIC__
+#include <dlfcn.h>
+
+#define MD5Init(ctx) dl_MD5Init(ctx)
+#define MD5Update(ctx, data, len) dl_MD5Update(ctx, data, len)
+#define MD5Final(dgst, ctx) dl_MD5Final(dgst, ctx)
+
+static void (*dl_MD5Init)(MD5_CTX *);
+static void (*dl_MD5Update)(MD5_CTX *, const unsigned char *, unsigned int);
+static void (*dl_MD5Final)(unsigned char digest[16], MD5_CTX *);
+#endif
+
+/*
+ * UNIX password
+ */
+
+char *
+crypt_md5(pw, salt)
+ const char *pw;
+ const char *salt;
+{
+ static char *magic = "$1$"; /*
+ * This string is magic for
+ * this algorithm. Having
+ * it this way, we can get
+ * get better later on
+ */
+ static char passwd[120], *p;
+ static const char *sp,*ep;
+ unsigned char final[MD5_SIZE];
+ int sl,pl,i;
+ MD5_CTX ctx,ctx1;
+ unsigned long l;
+#ifdef __PIC__
+ void *libmd;
+#endif
+
+ /* Refine the Salt first */
+ sp = salt;
+
+ /* If it starts with the magic string, then skip that */
+ if(!strncmp(sp,magic,strlen(magic)))
+ sp += strlen(magic);
+
+ /* It stops at the first '$', max 8 chars */
+ for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
+ continue;
+
+ /* get the length of the true salt */
+ sl = ep - sp;
+
+#ifdef __PIC__
+ libmd = dlopen("libmd.so", RTLD_NOW);
+ if (libmd == NULL) {
+ warnx("libcrypt-md5: dlopen(libmd.so): %s\n", dlerror());
+ return NULL;
+ }
+ dl_MD5Init = dlsym(libmd, "MD5Init");
+ if (dl_MD5Init == NULL) {
+ warnx("libcrypt-md5: looking for MD5Init: %s\n", dlerror());
+ dlclose(libmd);
+ return NULL;
+ }
+ dl_MD5Update = dlsym(libmd, "MD5Update");
+ if (dl_MD5Update == NULL) {
+ warnx("libcrypt-md5: looking for MD5Update: %s\n", dlerror());
+ dlclose(libmd);
+ return NULL;
+ }
+ dl_MD5Final = dlsym(libmd, "MD5Final");
+ if (dl_MD5Final == NULL) {
+ warnx("libcrypt-md5: looking for MD5Final: %s\n", dlerror());
+ dlclose(libmd);
+ return NULL;
+ }
+#endif
+ MD5Init(&ctx);
+
+ /* The password first, since that is what is most unknown */
+ MD5Update(&ctx,pw,strlen(pw));
+
+ /* Then our magic string */
+ MD5Update(&ctx,magic,strlen(magic));
+
+ /* Then the raw salt */
+ MD5Update(&ctx,sp,sl);
+
+ /* Then just as many characters of the MD5(pw,salt,pw) */
+ MD5Init(&ctx1);
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Update(&ctx1,sp,sl);
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Final(final,&ctx1);
+ for(pl = strlen(pw); pl > 0; pl -= MD5_SIZE)
+ MD5Update(&ctx,final,pl>MD5_SIZE ? MD5_SIZE : pl);
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final,0,sizeof final);
+
+ /* Then something really weird... */
+ for (i = strlen(pw); i ; i >>= 1)
+ if(i&1)
+ MD5Update(&ctx, final, 1);
+ else
+ MD5Update(&ctx, pw, 1);
+
+ /* Now make the output string */
+ strcpy(passwd,magic);
+ strncat(passwd,sp,sl);
+ strcat(passwd,"$");
+
+ MD5Final(final,&ctx);
+
+ /*
+ * and now, just to make sure things don't run too fast
+ * On a 60 Mhz Pentium this takes 34 msec, so you would
+ * need 30 seconds to build a 1000 entry dictionary...
+ */
+ for(i=0;i<1000;i++) {
+ MD5Init(&ctx1);
+ if(i & 1)
+ MD5Update(&ctx1,pw,strlen(pw));
+ else
+ MD5Update(&ctx1,final,MD5_SIZE);
+
+ if(i % 3)
+ MD5Update(&ctx1,sp,sl);
+
+ if(i % 7)
+ MD5Update(&ctx1,pw,strlen(pw));
+
+ if(i & 1)
+ MD5Update(&ctx1,final,MD5_SIZE);
+ else
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Final(final,&ctx1);
+ }
+
+#ifdef __PIC__
+ dlclose(libmd);
+#endif
+ p = passwd + strlen(passwd);
+
+ l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 4]<<16) | (final[10]<<8) | final[ 5];
+ _crypt_to64(p,l,4); p += 4;
+ l = final[11] ;
+ _crypt_to64(p,l,2); p += 2;
+ *p = '\0';
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final,0,sizeof final);
+
+ return passwd;
+}
+
diff --git a/lib/libcrypt/crypt-shs.c b/lib/libcrypt/crypt-shs.c
new file mode 100644
index 0000000..11a7aaf
--- /dev/null
+++ b/lib/libcrypt/crypt-shs.c
@@ -0,0 +1,190 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = \
+"$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sha.h>
+#include <err.h>
+#include "crypt.h"
+
+#ifdef __PIC__
+#include <dlfcn.h>
+
+#define SHA_Init(ctx) dl_SHA_Init(ctx)
+#define SHA_Update(ctx, data, len) dl_SHA_Update(ctx, data, len)
+#define SHA_Final(dgst, ctx) dl_SHA_Final(dgst, ctx)
+
+static void (*dl_SHA_Init)(SHA_CTX *);
+static void (*dl_SHA_Update)(SHA_CTX *, const unsigned char *, unsigned int);
+static void (*dl_SHA_Final)(unsigned char digest[20], SHA_CTX *);
+#endif
+
+/*
+ * UNIX password
+ */
+
+char *
+crypt_sha(pw, salt)
+ const char *pw;
+ const char *salt;
+{
+ static char *magic = "$3$"; /*
+ * This string is magic for
+ * this algorithm. Having
+ * it this way, we can get
+ * get better later on
+ */
+ static char passwd[120], *p;
+ static const char *sp,*ep;
+ unsigned char final[SHS_SIZE];
+ int sl,pl,i;
+ SHA_CTX ctx,ctx1;
+ unsigned long l;
+#ifdef __PIC__
+ void *libmd;
+#endif
+
+ /* Refine the Salt first */
+ sp = salt;
+
+ /* If it starts with the magic string, then skip that */
+ if(!strncmp(sp,magic,strlen(magic)))
+ sp += strlen(magic);
+
+ /* It stops at the first '$', max 8 chars */
+ for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
+ continue;
+
+ /* get the length of the true salt */
+ sl = ep - sp;
+
+#ifdef __PIC__
+ libmd = dlopen("libmd.so", RTLD_NOW);
+ if (libmd == NULL) {
+ warnx("libcrypt-md5: dlopen(libmd.so): %s\n", dlerror());
+ return NULL;
+ }
+ dl_SHA_Init = dlsym(libmd, "SHA_Init");
+ if (dl_SHA_Init == NULL) {
+ warnx("libcrypt-md5: looking for SHA_Init: %s\n", dlerror());
+ dlclose(libmd);
+ return NULL;
+ }
+ dl_SHA_Update = dlsym(libmd, "SHA_Update");
+ if (dl_SHA_Update == NULL) {
+ warnx("libcrypt-md5: looking for SHA_Update: %s\n", dlerror());
+ dlclose(libmd);
+ return NULL;
+ }
+ dl_SHA_Final = dlsym(libmd, "SHA_Final");
+ if (dl_SHA_Final == NULL) {
+ warnx("libcrypt-md5: looking for SHA_Final: %s\n", dlerror());
+ dlclose(libmd);
+ return NULL;
+ }
+#endif
+ SHA_Init(&ctx);
+
+ /* The password first, since that is what is most unknown */
+ SHA_Update(&ctx,pw,strlen(pw));
+
+ /* Then our magic string */
+ SHA_Update(&ctx,magic,strlen(magic));
+
+ /* Then the raw salt */
+ SHA_Update(&ctx,sp,sl);
+
+ /* Then just as many characters of the SHA(pw,salt,pw) */
+ SHA_Init(&ctx1);
+ SHA_Update(&ctx1,pw,strlen(pw));
+ SHA_Update(&ctx1,sp,sl);
+ SHA_Update(&ctx1,pw,strlen(pw));
+ SHA_Final(final,&ctx1);
+ for(pl = strlen(pw); pl > 0; pl -= SHS_SIZE)
+ SHA_Update(&ctx,final,pl>SHS_SIZE ? SHS_SIZE : pl);
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final,0,sizeof final);
+
+ /* Then something really weird... */
+ for (i = strlen(pw); i ; i >>= 1)
+ if(i&1)
+ SHA_Update(&ctx, final, 1);
+ else
+ SHA_Update(&ctx, pw, 1);
+
+ /* Now make the output string */
+ strcpy(passwd,magic);
+ strncat(passwd,sp,sl);
+ strcat(passwd,"$");
+
+ SHA_Final(final,&ctx);
+
+ /*
+ * and now, just to make sure things don't run too fast
+ * On a 60 Mhz Pentium this takes 34 msec, so you would
+ * need 30 seconds to build a 1000 entry dictionary...
+ */
+ for(i=0;i<1000;i++) {
+ SHA_Init(&ctx1);
+ if(i & 1)
+ SHA_Update(&ctx1,pw,strlen(pw));
+ else
+ SHA_Update(&ctx1,final,SHS_SIZE);
+
+ if(i % 3)
+ SHA_Update(&ctx1,sp,sl);
+
+ if(i % 7)
+ SHA_Update(&ctx1,pw,strlen(pw));
+
+ if(i & 1)
+ SHA_Update(&ctx1,final,SHS_SIZE);
+ else
+ SHA_Update(&ctx1,pw,strlen(pw));
+ SHA_Final(final,&ctx1);
+ }
+
+#ifdef __PIC__
+ dlclose(libmd);
+#endif
+ p = passwd + strlen(passwd);
+
+ l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 4]<<16) | (final[10]<<8) | final[16];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 5]<<16) | (final[11]<<8) | final[17];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[18]<<8) | final[19];
+ _crypt_to64(p,l,3); p += 3;
+
+ *p = '\0';
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final,0,sizeof final);
+
+ return passwd;
+}
+
diff --git a/lib/libcrypt/crypt.3 b/lib/libcrypt/crypt.3
new file mode 100644
index 0000000..5ce36a1
--- /dev/null
+++ b/lib/libcrypt/crypt.3
@@ -0,0 +1,203 @@
+.\" FreeSec: libcrypt for NetBSD
+.\"
+.\" Copyright (c) 1994 David Burren
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 4. Neither the name of the author nor the names of other contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.\" Manual page, using -mandoc macros
+.\"
+.Dd January 19, 1997
+.Dt CRYPT 3
+.Os "FreeSec 1.0"
+.Sh NAME
+.Nm crypt
+.Nd Trapdoor encryption
+.Sh SYNOPSIS
+.Ft char
+.Fn *crypt "const char *key" "const char *salt"
+.Sh DESCRIPTION
+The
+.Fn crypt
+function performs password hashing with additional code added to
+deter key search attempts. Different algorithms can be used to
+in the hash.
+.\"
+.\" NOTICE:
+.\" If you add more algorithms, make sure to update this list
+.\" and the default used for the Traditional format, below.
+.\"
+Currently these include the
+.Tn NBS
+Data Encryption Standard (DES), MD5 or SHS. The algorithm
+used will depend upon the format of the Salt--following the Modular
+Crypt Format (MCF)--and if DES is installed or not.
+.Pp
+The first argument to
+.Nm crypt
+is the data to hash (usually a password), in a
+.Dv null Ns -terminated
+string.
+The second is the salt, in one of three forms:
+.Pp
+.Bl -tag -width Traditional -compact -offset indent
+.It Extended
+If it begins with an underscore (``_'') then the DES Extended Format
+is used in interpreting both the the key and the salt, as outlined below.
+.It Modular
+If it begins with the string ``$digit$'' then the Modular Crypt Format
+is used, as outlined below.
+.It Traditional
+If neither of the above is true, it assumes the Traditional Format,
+using the entire string as the salt (or the first portion).
+.El
+.Pp
+All routines are designed to be time-consuming. A brief test on a
+Pentium 166/MMX shows the DES crypt to do approximately 2640 crypts
+a CPU second, MD5 to do about 62 crypts a CPU second and SHA1
+to do about 18 crypts a CPU second.
+.Ss DES Extended Format:
+.Pp
+The
+.Ar key
+is divided into groups of 8 characters (the last group is null-padded)
+and the low-order 7 bits of each each character (56 bits per group) are
+used to form the DES key as follows:
+the first group of 56 bits becomes the initial DES key.
+For each additional group, the XOR of the encryption of the current DES
+key with itself and the group bits becomes the next DES key.
+.Pp
+The salt is a 9-character array consisting of an underscore followed
+by 4 bytes of iteration count and 4 bytes of salt.
+These are encoded as printable characters, 6 bits per character,
+least significant character first.
+The values 0 to 63 are encoded as ``./0-9A-Za-z''.
+This allows 24 bits for both
+.Fa count
+and
+.Fa salt .
+.Pp
+The
+.Fa salt
+introduces disorder in the
+.Tn DES
+algorithm in one of 16777216 or 4096 possible ways
+(ie. with 24 or 12 bits: if bit
+.Em i
+of the
+.Ar salt
+is set, then bits
+.Em i
+and
+.Em i+24
+are swapped in the
+.Tn DES
+E-box output).
+.Pp
+The DES key is used to encrypt a 64-bit constant using
+.Ar count
+iterations of
+.Tn DES .
+The value returned is a
+.Dv null Ns -terminated
+string, 20 or 13 bytes (plus null) in length, consisting of the
+.Ar salt
+followed by the encoded 64-bit encryption.
+.Ss "Modular" crypt:
+.Pp
+If the salt begins with the string
+.Fa $digit$
+then the Modular Crypt Format is used. The
+.Fa digit
+represents which algorithm is used in encryption. Following the token is
+the actual salt to use in the encryption. The length of the salt is limited
+to 16 characters--because the length of the returned output is also limited
+(_PASSWORD_LEN). The salt must be terminated with the end of the string
+(NULL) or a dollar sign. Any characters after the dollar sign are ignored.
+.Pp
+Currently supported algorithms are:
+.Pp
+.Bl -tag -width 012345678 -compact -offset indent
+.It 1
+MD5
+.It 3
+SHA1
+.El
+.Pp
+Other crypt formats may be easilly added. An example salt would be:
+.Bl -tag -offset indent
+.It Cm "$3$thesalt$rest"
+.El
+.Pp
+.Ss "Traditional" crypt:
+.Pp
+The algorithm used will depend upon whether DES is installed or not. If it is,
+DES will be used. Otherwise, the best algorithm is used, which is currently
+.\"
+.\" NOTICE: Also make sure to update this
+.\"
+SHA-1.
+.Pp
+How the salt is used will depend upon the algorithm for the hash. For
+best results, specify at least two characters of salt.
+.Sh RETURN VALUES
+.Pp
+.Fn crypt
+returns a pointer to the encrypted value on success, and NULL on failure.
+Note: this is not a standard behaviour, AT&T
+.Fn crypt
+will always return a pointer to a string.
+.Sh SEE ALSO
+.Xr login 1 ,
+.Xr passwd 1 ,
+.Xr getpass 3 ,
+.Xr passwd 5 ,
+.Xr shs 3 ,
+.Sh BUGS
+The
+.Fn crypt
+function returns a pointer to static data, and subsequent calls to
+.Fn crypt
+will modify the same data.
+.Sh HISTORY
+A rotor-based
+.Fn crypt
+function appeared in
+.At v6 .
+The current style
+.Fn crypt
+first appeared in
+.At v7 .
+.Pp
+The DES section of the code (FreeSec 1.0) was developed outside the United
+States of America as an unencumbered replacement for the U.S.-only NetBSD
+libcrypt encryption library.
+Users should be aware that this code (and programs staticly linked with it)
+may not be exported from the U.S., although it apparently can be imported.
+.Sh AUTHORS
+Originally written by David Burren <davidb@werj.com.au>, later additions
+and changes by Brandon Gillespie, Poul-henning Kamp and Mark R V Murray.
diff --git a/lib/libcrypt/crypt.c b/lib/libcrypt/crypt.c
new file mode 100644
index 0000000..e3fb989
--- /dev/null
+++ b/lib/libcrypt/crypt.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1999
+ * Mark Murray. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MARK MURRAY AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL MARK MURRAY OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <string.h>
+#include "crypt.h"
+
+char *
+crypt(char *passwd, char *salt)
+{
+ if (!strncmp(salt, "$1$", 3))
+ return crypt_md5(passwd, salt);
+ if (!strncmp(salt, "$3$", 3))
+ return crypt_sha(passwd, salt);
+#ifdef NONEXPORTABLE_CRYPT
+ return crypt_des(passwd, salt);
+#else
+ return crypt_md5(passwd, salt);
+#endif
+}
diff --git a/lib/libcrypt/crypt.h b/lib/libcrypt/crypt.h
new file mode 100644
index 0000000..21e7691
--- /dev/null
+++ b/lib/libcrypt/crypt.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1999
+ * Mark Murray. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MARK MURRAY AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL MARK MURRAY OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+/* magic sizes */
+#define MD5_SIZE 16
+#define SHS_SIZE 20
+
+char *crypt_des(const char *pw, const char *salt);
+char *crypt_md5(const char *pw, const char *salt);
+char *crypt_sha(const char *pw, const char *salt);
+
+extern void _crypt_to64(char *s, unsigned long v, int n);
+
diff --git a/lib/libcrypt/misc.c b/lib/libcrypt/misc.c
new file mode 100644
index 0000000..5cad45d
--- /dev/null
+++ b/lib/libcrypt/misc.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1999
+ * University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+void
+_crypt_to64(s, v, n)
+ char *s;
+ unsigned long v;
+ int n;
+{
+ while (--n >= 0) {
+ *s++ = itoa64[v&0x3f];
+ v >>= 6;
+ }
+}
diff --git a/lib/libdevstat/Makefile b/lib/libdevstat/Makefile
new file mode 100644
index 0000000..8a3b2b2
--- /dev/null
+++ b/lib/libdevstat/Makefile
@@ -0,0 +1,24 @@
+MAINTAINER=ken@FreeBSD.ORG
+
+LIB= devstat
+SRCS= devstat.c
+
+MAN3= devstat.3
+
+MLINKS+=devstat.3 getnumdevs.3
+MLINKS+=devstat.3 getgeneration.3
+MLINKS+=devstat.3 getversion.3
+MLINKS+=devstat.3 checkversion.3
+MLINKS+=devstat.3 getdevs.3
+MLINKS+=devstat.3 selectdevs.3
+MLINKS+=devstat.3 buildmatch.3
+MLINKS+=devstat.3 compute_stats.3
+MLINKS+=devstat.3 compute_etime.3
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/devstat.h \
+ ${DESTDIR}/usr/include
+
+CFLAGS+=-I${.CURDIR} -I${.CURDIR}/../../sys
+
+.include <bsd.lib.mk>
diff --git a/lib/libdevstat/devstat.3 b/lib/libdevstat/devstat.3
new file mode 100644
index 0000000..69a4d74
--- /dev/null
+++ b/lib/libdevstat/devstat.3
@@ -0,0 +1,541 @@
+.\"
+.\" Copyright (c) 1998, 1999 Kenneth D. Merry.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 21, 1998
+.Dt DEVSTAT 3
+.Os FreeBSD 3.0
+.Sh NAME
+.Nm devstat ,
+.Nm getnumdevs ,
+.Nm getgeneration ,
+.Nm getversion ,
+.Nm checkversion ,
+.Nm getdevs ,
+.Nm selectdevs ,
+.Nm buildmatch ,
+.Nm compute_stats ,
+.Nm compute_etime
+.Nd device statistics utility library
+.Sh SYNOPSIS
+.Fd #include <sys/dkstat.h>
+.Fd #include <devstat.h>
+.Ft int
+.Fn getnumdevs "void"
+.Ft long
+.Fn getgeneration "void"
+.Ft int
+.Fn getversion "void"
+.Ft int
+.Fn checkversion "void"
+.Ft int
+.Fn getdevs "struct statinfo *stats"
+.Ft int
+.Fo selectdevs
+.Fa "struct device_selection **dev_select"
+.Fa "int *num_selected"
+.Fa "int *num_selections"
+.Fa "long *select_generation"
+.Fa "long current_generation"
+.Fa "struct devstat *devices"
+.Fa "int numdevs"
+.Fa "struct devstat_match *matches"
+.Fa "int num_matches"
+.Fa "char **dev_selections"
+.Fa "int num_dev_selections"
+.Fa "devstat_select_mode select_mode"
+.Fa "int maxshowdevs"
+.Fa "int perf_select"
+.Fc
+.Ft int
+.Fo buildmatch
+.Fa "char *match_str"
+.Fa "struct devstat_match **matches"
+.Fa "int *num_matches"
+.Fc
+.Ft int
+.Fo compute_stats
+.Fa "struct devstat *current"
+.Fa "struct devstat *previous"
+.Fa "long double etime"
+.Fa "u_int64_t *total_bytes"
+.Fa "u_int64_t *total_transfers"
+.Fa "u_int64_t *total_blocks"
+.Fa "long double *kb_per_transfer"
+.Fa "long double *transfers_per_second"
+.Fa "long double *mb_per_second"
+.Fa "long double *blocks_per_second"
+.Fa "long double *ms_per_transaction"
+.Fc
+.Ft long double
+.Fo compute_etime
+.Fa "struct timeval cur_time"
+.Fa "struct timeval prev_time"
+.Fc
+.Sh DESCRIPTION
+The
+.Nm
+library is a library of helper functions for dealing with the kernel
+.Xr devstat 9
+interface, which is accessible to users via
+.Xr sysctl 3 .
+.Pp
+.Fn getnumdevs
+returns the number of devices registered with the
+.Nm devstat
+subsystem in the kernel.
+.Pp
+.Fn getgeneration
+returns the current generation of the
+.Nm devstat
+list of devices in the kernel.
+.Pp
+.Fn getversion
+returns the current kernel
+.Nm devstat
+version.
+.Pp
+.Fn checkversion
+checks the userland devstat version against the kernel devstat version. If
+the two are identical, it returns zero. Otherwise, it prints an
+appropriate error in
+.Va devstat_errbuf
+and returns -1.
+.Pp
+.Fn getdevs
+fetches the current list of devices and statistics into the supplied
+.Va statinfo
+structure. The
+.Va statinfo
+structure can be found in
+.Aq Pa devstat.h :
+.Bd -literal -offset indent
+struct statinfo {
+ long cp_time[CPUSTATES];
+ long tk_nin;
+ long tk_nout;
+ struct devinfo *dinfo;
+ struct timeval busy_time;
+};
+.Ed
+.Pp
+.Fn getdevs
+expects the
+.Va statinfo
+structure to be allocated, and it also expects the
+.Va dinfo
+subelement to be allocated and zeroed prior to the first invocation of
+.Fn getdevs .
+The
+.Va dinfo
+subelement is used to store state between calls, and should not be modified
+after the first call to
+.Fn getdevs .
+The
+.Va dinfo
+subelement contains the following elements:
+.Bd -literal -offset indent
+struct devinfo {
+ struct devstat *devices;
+ u_int8_t *mem_ptr;
+ long generation;
+ int numdevs;
+};
+.Ed
+.Pp
+The
+.Va kern.devstat.all
+.Nm sysctl
+variable contains an array of
+.Nm devstat
+structures, but at the head of the array is the current
+.Nm devstat
+generation. The reason the generation is at the head of the buffer is so
+that userland software accessing the devstat statistics information can
+atomically get both the statistics information and the corresponding
+generation number. If client software were forced to get the generation
+number via a separate
+.Nm sysctl
+variable (which is available for convenience), the list of devices could
+change between the time the client gets the generation and the time the
+client gets the device list.
+.Pp
+The
+.Va mem_ptr
+subelement of the
+.Va devinfo
+structure is a pointer to memory that is allocated, and resized if
+necessary, by
+.Fn getdevs .
+The devices subelement of the
+.Va devinfo
+structure is basically a pointer to the beginning of the array of devstat
+structures from the
+.Va kern.devstat.all
+.Nm sysctl
+variable. The generation subelement of the
+.Nm devinfo
+structure contains the generation number from the
+.Va kern.devstat.all
+.Nm sysctl
+variable.
+The
+.Va numdevs
+subelement of the
+.Va devinfo
+structure contains the current
+number of devices registered with the kernel
+.Nm devstat
+subsystem.
+.Pp
+.Fn selectdevs
+selects devices to display based upon a number of criteria:
+.Bl -tag -width flag
+.It specified devices
+Specified devices are the first selection priority. These are generally
+devices specified by name by the user. e.g. da0, da1, cd0.
+.It match patterns
+These are pattern matching expressions generated by
+.Fn buildmatch
+from user input.
+.It performance
+If performance mode is enabled, devices will be sorted based on the
+.Va bytes
+field in the
+.Va device_selection
+structure passed in to
+.Fn selectdevs .
+The
+.Va bytes
+value currently must be maintained by the user. In the future,
+this may be done for him in a
+.Nm
+library routine.
+If no devices have been selected by name or by pattern, the performance
+tracking code will select every device in the system, and sort them by
+performance. If devices have been selected by name or pattern, the
+performance tracking code will honor those selections and will only sort
+among the selected devices.
+.It order in the devstat list
+If the selection mode is set to DS_SELECT_ADD, and if there are still less
+than
+.Va maxshowdevs
+devices selected,
+.Fn selectdevs
+will automatically select up to
+.Va maxshowdevs
+devices.
+.El
+.Pp
+.Fn selectdevs
+performs selections in four different modes:
+.Bl -tag -width DS_SELECT_ADDONLY
+.It DS_SELECT_ADD
+In add mode,
+.Fn selectdevs
+will select any unselected devices specified by name or matching pattern.
+It will also select more devices, in devstat list order, until the number
+of selected devices is equal to
+.Va maxshowdevs
+or until all devices are
+selected.
+.It DS_SELECT_ONLY
+In only mode,
+.Fn selectdevs
+will clear all current selections, and will only select devices specified
+by name or by matching pattern.
+.It DS_SELECT_REMOVE
+In remove mode,
+.Fn selectdevs
+will remove devices specified by name or by matching pattern. It will not
+select any additional devices.
+.It DS_SELECT_ADDONLY
+In add only mode,
+.Fn selectdevs
+will select any unselected devices specified by name or matching pattern.
+In this respect it is identical to add mode. It will not, however, select
+any devices other than those specified.
+.El
+.Pp
+In all selection modes,
+.Fn selectdevs
+will not select any more than
+.Va maxshowdevs
+devices. One exception to
+this is when you are in
+.Dq top
+mode and no devices have been selected. In
+this case,
+.Fn selectdevs
+will select every device in the system. Client programs must pay attention
+to selection order when deciding whether to pay attention to a particular
+device. This may be the wrong behavior, and probably requires additional
+thought.
+.Pp
+.Fn selectdevs
+handles allocation and resizing of the
+.Va dev_select
+structure passed in
+by the client.
+.Fn selectdevs
+uses the
+.Va numdevs
+and
+.Va current_generation
+fields to track the
+current
+.Nm
+generation and number of devices. If
+.Va num_selections
+is not the same
+as
+.Va numdevs
+or if
+.Va select_generation
+is not the same as
+.Va current_generation ,
+.Fn selectdevs
+will resize the selection list as necessary, and re-initialize the
+selection array.
+.Pp
+.Fn buildmatch
+takes a comma separated match string and compiles it into a
+\fBdevstat_match\fR structure that is understood by
+.Fn selectdevs .
+Match strings have the following format:
+.Pp
+.Bd -literal -offset indent
+device,type,if
+.Ed
+.Pp
+.Fn buildmatch
+takes care of allocating and reallocating the match list as necessary.
+Currently known match types include:
+.Pp
+.Bl -tag -width indent -compact
+.It device type:
+.Bl -tag -width 123456789 -compact
+.It da
+Direct Access devices
+.It sa
+Sequential Access devices
+.It printer
+Printers
+.It proc
+Processor devices
+.It worm
+Write Once Read Multiple devices
+.It cd
+CD devices
+.It scanner
+Scanner devices
+.It optical
+Optical Memory devices
+.It changer
+Medium Changer devices
+.It comm
+Communication devices
+.It array
+Storage Array devices
+.It enclosure
+Enclosure Services devices
+.It floppy
+Floppy devices
+.El
+.Pp
+.It interface:
+.Bl -tag -width 123456789 -compact
+.It IDE
+Integrated Drive Electronics devices
+.It SCSI
+Small Computer System Interface devices
+.It other
+Any other device interface
+.El
+.Pp
+.It passthrough:
+.Bl -tag -width 123456789 -compact
+.It pass
+Passthrough devices
+.El
+.El
+.Pp
+.Fn compute_stats
+provides an easy way to obtain various device statistics. Only two
+arguments are mandatory:
+.Va current
+and
+.Va etime .
+Every other argument is optional. For most applications, the user will
+want to supply both
+.Va current
+and
+.Va previous
+devstat structures so that statistics may be calculated over a given period
+of time. In some instances, for instance when calculating statistics since
+system boot, the user may pass in a NULL pointer for the
+.Va previous
+argument. In that case,
+.Fn compute_stats
+will use the total stats in the
+.Va current
+structure to calculate statistics over
+.Va etime .
+The various statistics that may be calculated by
+.Fn compute_stats
+should be mostly explained by the function declaration itself, but for
+completeness here is a list of variable names and the statistics that will
+be put in them:
+.Bl -tag -width transfers_per_second
+.It total_bytes
+This is the total number of bytes transferred on the given device, both
+reads and writes, between the acquisition of
+.Va previous
+and the acquisition of
+.Va current .
+If
+.Va previous
+is NULL, the result will be the total reads and writes given in
+.Va current .
+.It total_transfers
+This is the total number of transfers completed between the
+acquisition of
+.Va previous
+and the acquisition of
+.Va current .
+If
+.Va previous
+is NULL, the result will be the total number of transactions listed in
+.Va current .
+.It total_blocks
+This is basically
+.Va total_bytes
+divided by the device blocksize. If the device blocksize is listed as
+.Sq 0 ,
+the device blocksize will default to 512 bytes.
+.It kb_per_transfer
+This is the average number of kilobytes per transfer during the measurement
+period.
+.It transfers_per_second
+This is the average number of transfers per second.
+.It mb_per_second
+This is average megabytes per second.
+.It blocks_per_second
+This is average blocks per second. If the device blocksize is
+.Sq 0 ,
+a default blocksize of 512 bytes will be used instead.
+.It ms_per_transaction
+The average number of milliseconds per transaction.
+.El
+.Pp
+.Fn compute_etime
+provides an easy way to find the difference in seconds between two
+.Va timeval
+structures. This is most commonly used in conjunction with the time
+recorded by the
+.Fn getdevs
+function (in struct
+.Va statinfo )
+each time it fetches the current
+.Nm
+list.
+.Sh RETURN VALUES
+.Fn getnumdevs ,
+.Fn getgeneration ,
+and
+.Fn getversion
+return the indicated \fBsysctl\fR variable, or -1 if there is an error
+fetching the variable.
+.Pp
+.Fn checkversion
+returns 0 if the kernel and userland
+.Nm devstat
+versions match. If they do not match, it returns -1.
+.Pp
+.Fn getdevs
+and
+.Fn selectdevs
+return -1 in case of an error, 0 if there is no error and 1 if the device
+list or selected devices have changed. A return value of 1 from
+.Fn getdevs
+is usually a hint to re-run
+.Fn selectdevs
+because the device list has changed.
+.Pp
+.Fn buildmatch
+returns -1 for error, and 0 if there is no error.
+.Pp
+.Fn compute_stats
+returns -1 for error, and 0 for success.
+.Pp
+.Fn compute_etime
+returns the computed elapsed time.
+.Pp
+If an error is returned from one of the
+.Nm
+library functions, the reason for the error is generally printed in
+the global string
+.Va devstat_errbuf
+which is
+.Dv DEVSTAT_ERRBUF_SIZE
+characters long.
+.Sh SEE ALSO
+.Xr systat 1 ,
+.Xr iostat 8 ,
+.Xr rpc.rstatd 8 ,
+.Xr vmstat 8 ,
+.Xr devstat 9
+.Sh HISTORY
+The
+.Nm
+statistics system first appeared in
+.Fx 3.0 .
+.Sh AUTHORS
+.An Kenneth Merry Aq ken@FreeBSD.ORG
+.Sh BUGS
+There should probably be an interface to de-allocate memory allocated by
+.Fn getdevs ,
+.Fn selectdevs ,
+and
+.Fn buildmatch .
+.Pp
+.Fn selectdevs
+should probably not select more than
+.Va maxshowdevs
+devices in
+.Dq top
+mode when no devices have been selected previously.
+.Pp
+There should probably be functions to perform the statistics buffer
+swapping that goes on in most of the clients of this library.
+.Pp
+The
+.Va statinfo
+and
+.Va devinfo
+structures should probably be cleaned up and thought out a little more.
diff --git a/lib/libdevstat/devstat.c b/lib/libdevstat/devstat.c
new file mode 100644
index 0000000..ed9ea3b
--- /dev/null
+++ b/lib/libdevstat/devstat.c
@@ -0,0 +1,1128 @@
+/*
+ * Copyright (c) 1997, 1998 Kenneth D. Merry.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/errno.h>
+#include <sys/dkstat.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "devstat.h"
+
+char devstat_errbuf[DEVSTAT_ERRBUF_SIZE];
+
+/*
+ * Table to match descriptive strings with device types. These are in
+ * order from most common to least common to speed search time.
+ */
+struct devstat_match_table match_table[] = {
+ {"da", DEVSTAT_TYPE_DIRECT, DEVSTAT_MATCH_TYPE},
+ {"cd", DEVSTAT_TYPE_CDROM, DEVSTAT_MATCH_TYPE},
+ {"scsi", DEVSTAT_TYPE_IF_SCSI, DEVSTAT_MATCH_IF},
+ {"ide", DEVSTAT_TYPE_IF_IDE, DEVSTAT_MATCH_IF},
+ {"other", DEVSTAT_TYPE_IF_OTHER, DEVSTAT_MATCH_IF},
+ {"worm", DEVSTAT_TYPE_WORM, DEVSTAT_MATCH_TYPE},
+ {"sa", DEVSTAT_TYPE_SEQUENTIAL,DEVSTAT_MATCH_TYPE},
+ {"pass", DEVSTAT_TYPE_PASS, DEVSTAT_MATCH_PASS},
+ {"optical", DEVSTAT_TYPE_OPTICAL, DEVSTAT_MATCH_TYPE},
+ {"array", DEVSTAT_TYPE_STORARRAY, DEVSTAT_MATCH_TYPE},
+ {"changer", DEVSTAT_TYPE_CHANGER, DEVSTAT_MATCH_TYPE},
+ {"scanner", DEVSTAT_TYPE_SCANNER, DEVSTAT_MATCH_TYPE},
+ {"printer", DEVSTAT_TYPE_PRINTER, DEVSTAT_MATCH_TYPE},
+ {"floppy", DEVSTAT_TYPE_FLOPPY, DEVSTAT_MATCH_TYPE},
+ {"proc", DEVSTAT_TYPE_PROCESSOR, DEVSTAT_MATCH_TYPE},
+ {"comm", DEVSTAT_TYPE_COMM, DEVSTAT_MATCH_TYPE},
+ {"enclosure", DEVSTAT_TYPE_ENCLOSURE, DEVSTAT_MATCH_TYPE},
+ {NULL, 0, 0}
+};
+
+/*
+ * Local function declarations.
+ */
+static int compare_select(const void *arg1, const void *arg2);
+
+int
+getnumdevs(void)
+{
+ size_t numdevsize;
+ int numdevs;
+ char *func_name = "getnumdevs";
+
+ numdevsize = sizeof(int);
+
+ /*
+ * Find out how many devices we have in the system.
+ */
+ if (sysctlbyname("kern.devstat.numdevs", &numdevs,
+ &numdevsize, NULL, 0) == -1) {
+ sprintf(devstat_errbuf, "%s: error getting number of devices\n"
+ "%s: %s", func_name, func_name, strerror(errno));
+ return(-1);
+ } else
+ return(numdevs);
+}
+
+/*
+ * This is an easy way to get the generation number, but the generation is
+ * supplied in a more atmoic manner by the kern.devstat.all sysctl.
+ * Because this generation sysctl is separate from the statistics sysctl,
+ * the device list and the generation could change between the time that
+ * this function is called and the device list is retreived.
+ */
+long
+getgeneration(void)
+{
+ size_t gensize;
+ long generation;
+ char *func_name = "getgeneration";
+
+ gensize = sizeof(long);
+
+ /*
+ * Get the current generation number.
+ */
+ if (sysctlbyname("kern.devstat.generation", &generation,
+ &gensize, NULL, 0) == -1) {
+ sprintf(devstat_errbuf,"%s: error getting devstat generation\n"
+ "%s: %s", func_name, func_name, strerror(errno));
+ return(-1);
+ } else
+ return(generation);
+}
+
+/*
+ * Get the current devstat version. The return value of this function
+ * should be compared with DEVSTAT_VERSION, which is defined in
+ * sys/devicestat.h. This will enable userland programs to determine
+ * whether they are out of sync with the kernel.
+ */
+int
+getversion(void)
+{
+ size_t versize;
+ int version;
+ char *func_name = "getversion";
+
+ versize = sizeof(int);
+
+ /*
+ * Get the current devstat version.
+ */
+ if (sysctlbyname("kern.devstat.version", &version, &versize,
+ NULL, 0) == -1) {
+ sprintf(devstat_errbuf, "%s: error getting devstat version\n"
+ "%s: %s", func_name, func_name, strerror(errno));
+ return(-1);
+ } else
+ return(version);
+}
+
+/*
+ * Check the devstat version we know about against the devstat version the
+ * kernel knows about. If they don't match, print an error into the
+ * devstat error buffer, and return -1. If they match, return 0.
+ */
+int
+checkversion(void)
+{
+ int retval = 0;
+ int errlen = 0;
+ char *func_name = "checkversion";
+ int version;
+
+ version = getversion();
+
+ if (version != DEVSTAT_VERSION) {
+ int buflen = 0;
+ char tmpstr[256];
+
+ /*
+ * This is really pretty silly, but basically the idea is
+ * that if getversion() returns an error (i.e. -1), then it
+ * has printed an error message in the buffer. Therefore,
+ * we need to add a \n to the end of that message before we
+ * print our own message in the buffer.
+ */
+ if (version == -1) {
+ buflen = strlen(devstat_errbuf);
+ errlen = snprintf(tmpstr, sizeof(tmpstr), "\n");
+ strncat(devstat_errbuf, tmpstr,
+ DEVSTAT_ERRBUF_SIZE - buflen - 1);
+ buflen += errlen;
+ }
+
+ errlen = snprintf(tmpstr, sizeof(tmpstr),
+ "%s: userland devstat version %d is not "
+ "the same as the kernel\n%s: devstat "
+ "version %d\n", func_name, DEVSTAT_VERSION,
+ func_name, version);
+
+ if (version == -1) {
+ strncat(devstat_errbuf, tmpstr,
+ DEVSTAT_ERRBUF_SIZE - buflen - 1);
+ buflen += errlen;
+ } else {
+ strncpy(devstat_errbuf, tmpstr, DEVSTAT_ERRBUF_SIZE);
+ devstat_errbuf[DEVSTAT_ERRBUF_SIZE - 1] = '\0';
+ }
+
+ if (version < DEVSTAT_VERSION)
+ snprintf(tmpstr, sizeof(tmpstr),
+ "%s: libdevstat newer than kernel\n",
+ func_name);
+ else
+ snprintf(tmpstr, sizeof(tmpstr),
+ "%s: kernel newer than libdevstat\n",
+ func_name);
+
+ strncat(devstat_errbuf, tmpstr,
+ DEVSTAT_ERRBUF_SIZE - buflen - 1);
+
+ retval = -1;
+ }
+
+ return(retval);
+}
+
+/*
+ * Get the current list of devices and statistics, and the current
+ * generation number.
+ *
+ * Return values:
+ * -1 -- error
+ * 0 -- device list is unchanged
+ * 1 -- device list has changed
+ */
+int
+getdevs(struct statinfo *stats)
+{
+ int error;
+ size_t dssize;
+ int oldnumdevs;
+ long oldgeneration;
+ int retval = 0;
+ struct devinfo *dinfo;
+ char *func_name = "getdevs";
+
+ dinfo = stats->dinfo;
+
+ if (dinfo == NULL) {
+ sprintf(devstat_errbuf, "%s: stats->dinfo was NULL", func_name);
+ return(-1);
+ }
+
+ oldnumdevs = dinfo->numdevs;
+ oldgeneration = dinfo->generation;
+
+ /*
+ * If this is our first time through, mem_ptr will be null.
+ */
+ if (dinfo->mem_ptr == NULL) {
+ /*
+ * Get the number of devices. If it's negative, it's an
+ * error. Don't bother setting the error string, since
+ * getnumdevs() has already done that for us.
+ */
+ if ((dinfo->numdevs = getnumdevs()) < 0)
+ return(-1);
+
+ /*
+ * The kern.devstat.all sysctl returns the current generation
+ * number, as well as all the devices. So we need four
+ * bytes more.
+ */
+ dssize =(dinfo->numdevs * sizeof(struct devstat)) +sizeof(long);
+ dinfo->mem_ptr = (u_int8_t *)malloc(dssize);
+ } else
+ dssize =(dinfo->numdevs * sizeof(struct devstat)) +sizeof(long);
+
+ /* Get the current time when we get the stats */
+ gettimeofday(&stats->busy_time, NULL);
+
+ /*
+ * Request all of the devices. We only really allow for one
+ * ENOMEM failure. It would, of course, be possible to just go in
+ * a loop and keep reallocing the device structure until we don't
+ * get ENOMEM back. I'm not sure it's worth it, though. If
+ * devices are being added to the system that quickly, maybe the
+ * user can just wait until all devices are added.
+ */
+ if ((error = sysctlbyname("kern.devstat.all", dinfo->mem_ptr,
+ &dssize, NULL, 0)) == -1) {
+ /*
+ * If we get ENOMEM back, that means that there are
+ * more devices now, so we need to allocate more
+ * space for the device array.
+ */
+ if (errno == ENOMEM) {
+ /*
+ * No need to set the error string here, getnumdevs()
+ * will do that if it fails.
+ */
+ if ((dinfo->numdevs = getnumdevs()) < 0)
+ return(-1);
+
+ dssize = (dinfo->numdevs * sizeof(struct devstat)) +
+ sizeof(long);
+ dinfo->mem_ptr = (u_int8_t *)realloc(dinfo->mem_ptr,
+ dssize);
+ if ((error = sysctlbyname("kern.devstat.all",
+ dinfo->mem_ptr, &dssize, NULL, 0)) == -1) {
+ sprintf(devstat_errbuf,
+ "%s: error getting device stats\n"
+ "%s: %s", func_name, func_name,
+ strerror(errno));
+ return(-1);
+ }
+ } else {
+ sprintf(devstat_errbuf,
+ "%s: error getting device stats\n"
+ "%s: %s", func_name, func_name,
+ strerror(errno));
+ return(-1);
+ }
+ }
+
+ /*
+ * The sysctl spits out the generation as the first four bytes,
+ * then all of the device statistics structures.
+ */
+ dinfo->generation = *(long *)dinfo->mem_ptr;
+
+ /*
+ * If the generation has changed, and if the current number of
+ * devices is not the same as the number of devices recorded in the
+ * devinfo structure, it is likely that the device list has shrunk.
+ * The reason that it is likely that the device list has shrunk in
+ * this case is that if the device list has grown, the sysctl above
+ * will return an ENOMEM error, and we will reset the number of
+ * devices and reallocate the device array. If the second sysctl
+ * fails, we will return an error and therefore never get to this
+ * point. If the device list has shrunk, the sysctl will not
+ * return an error since we have more space allocated than is
+ * necessary. So, in the shrinkage case, we catch it here and
+ * reallocate the array so that we don't use any more space than is
+ * necessary.
+ */
+ if (oldgeneration != dinfo->generation) {
+ if (getnumdevs() != dinfo->numdevs) {
+ if ((dinfo->numdevs = getnumdevs()) < 0)
+ return(-1);
+ dssize = (dinfo->numdevs * sizeof(struct devstat)) +
+ sizeof(long);
+ dinfo->mem_ptr = (u_int8_t *)realloc(dinfo->mem_ptr,
+ dssize);
+ }
+ retval = 1;
+ }
+
+ dinfo->devices = (struct devstat *)(dinfo->mem_ptr + sizeof(long));
+
+ return(retval);
+}
+
+/*
+ * selectdevs():
+ *
+ * Devices are selected/deselected based upon the following criteria:
+ * - devices specified by the user on the command line
+ * - devices matching any device type expressions given on the command line
+ * - devices with the highest I/O, if 'top' mode is enabled
+ * - the first n unselected devices in the device list, if maxshowdevs
+ * devices haven't already been selected and if the user has not
+ * specified any devices on the command line and if we're in "add" mode.
+ *
+ * Input parameters:
+ * - device selection list (dev_select)
+ * - current number of devices selected (num_selected)
+ * - total number of devices in the selection list (num_selections)
+ * - devstat generation as of the last time selectdevs() was called
+ * (select_generation)
+ * - current devstat generation (current_generation)
+ * - current list of devices and statistics (devices)
+ * - number of devices in the current device list (numdevs)
+ * - compiled version of the command line device type arguments (matches)
+ * - This is optional. If the number of devices is 0, this will be ignored.
+ * - The matching code pays attention to the current selection mode. So
+ * if you pass in a matching expression, it will be evaluated based
+ * upon the selection mode that is passed in. See below for details.
+ * - number of device type matching expressions (num_matches)
+ * - Set to 0 to disable the matching code.
+ * - list of devices specified on the command line by the user (dev_selections)
+ * - number of devices selected on the command line by the user
+ * (num_dev_selections)
+ * - Our selection mode. There are four different selection modes:
+ * - add mode. (DS_SELECT_ADD) Any devices matching devices explicitly
+ * selected by the user or devices matching a pattern given by the
+ * user will be selected in addition to devices that are already
+ * selected. Additional devices will be selected, up to maxshowdevs
+ * number of devices.
+ * - only mode. (DS_SELECT_ONLY) Only devices matching devices
+ * explicitly given by the user or devices matching a pattern
+ * given by the user will be selected. No other devices will be
+ * selected.
+ * - addonly mode. (DS_SELECT_ADDONLY) This is similar to add and
+ * only. Basically, this will not de-select any devices that are
+ * current selected, as only mode would, but it will also not
+ * gratuitously select up to maxshowdevs devices as add mode would.
+ * - remove mode. (DS_SELECT_REMOVE) Any devices matching devices
+ * explicitly selected by the user or devices matching a pattern
+ * given by the user will be de-selected.
+ * - maximum number of devices we can select (maxshowdevs)
+ * - flag indicating whether or not we're in 'top' mode (perf_select)
+ *
+ * Output data:
+ * - the device selection list may be modified and passed back out
+ * - the number of devices selected and the total number of items in the
+ * device selection list may be changed
+ * - the selection generation may be changed to match the current generation
+ *
+ * Return values:
+ * -1 -- error
+ * 0 -- selected devices are unchanged
+ * 1 -- selected devices changed
+ */
+int
+selectdevs(struct device_selection **dev_select, int *num_selected,
+ int *num_selections, long *select_generation,
+ long current_generation, struct devstat *devices, int numdevs,
+ struct devstat_match *matches, int num_matches,
+ char **dev_selections, int num_dev_selections,
+ devstat_select_mode select_mode, int maxshowdevs, int perf_select)
+{
+ register int i, j, k;
+ int init_selections = 0, init_selected_var = 0;
+ struct device_selection *old_dev_select = NULL;
+ int old_num_selections = 0, old_num_selected;
+ int selection_number = 0;
+ int changed = 0, found = 0;
+
+ if ((dev_select == NULL) || (devices == NULL) || (numdevs <= 0))
+ return(-1);
+
+ /*
+ * We always want to make sure that we have as many dev_select
+ * entries as there are devices.
+ */
+ /*
+ * In this case, we haven't selected devices before.
+ */
+ if (*dev_select == NULL) {
+ *dev_select = (struct device_selection *)malloc(numdevs *
+ sizeof(struct device_selection));
+ *select_generation = current_generation;
+ init_selections = 1;
+ changed = 1;
+ /*
+ * In this case, we have selected devices before, but the device
+ * list has changed since we last selected devices, so we need to
+ * either enlarge or reduce the size of the device selection list.
+ */
+ } else if (*num_selections != numdevs) {
+ *dev_select = (struct device_selection *)realloc(*dev_select,
+ numdevs * sizeof(struct device_selection));
+ *select_generation = current_generation;
+ init_selections = 1;
+ /*
+ * In this case, we've selected devices before, and the selection
+ * list is the same size as it was the last time, but the device
+ * list has changed.
+ */
+ } else if (*select_generation < current_generation) {
+ *select_generation = current_generation;
+ init_selections = 1;
+ }
+
+ /*
+ * If we're in "only" mode, we want to clear out the selected
+ * variable since we're going to select exactly what the user wants
+ * this time through.
+ */
+ if (select_mode == DS_SELECT_ONLY)
+ init_selected_var = 1;
+
+ /*
+ * In all cases, we want to back up the number of selected devices.
+ * It is a quick and accurate way to determine whether the selected
+ * devices have changed.
+ */
+ old_num_selected = *num_selected;
+
+ /*
+ * We want to make a backup of the current selection list if
+ * the list of devices has changed, or if we're in performance
+ * selection mode. In both cases, we don't want to make a backup
+ * if we already know for sure that the list will be different.
+ * This is certainly the case if this is our first time through the
+ * selection code.
+ */
+ if (((init_selected_var != 0) || (init_selections != 0)
+ || (perf_select != 0)) && (changed == 0)){
+ old_dev_select = (struct device_selection *)malloc(
+ *num_selections * sizeof(struct device_selection));
+ old_num_selections = *num_selections;
+ bcopy(*dev_select, old_dev_select,
+ sizeof(struct device_selection) * *num_selections);
+ }
+
+ if (init_selections != 0) {
+ bzero(*dev_select, sizeof(struct device_selection) * numdevs);
+
+ for (i = 0; i < numdevs; i++) {
+ (*dev_select)[i].device_number =
+ devices[i].device_number;
+ strncpy((*dev_select)[i].device_name,
+ devices[i].device_name,
+ DEVSTAT_NAME_LEN);
+ (*dev_select)[i].device_name[DEVSTAT_NAME_LEN - 1]='\0';
+ (*dev_select)[i].unit_number = devices[i].unit_number;
+ (*dev_select)[i].position = i;
+ }
+ *num_selections = numdevs;
+ } else if (init_selected_var != 0) {
+ for (i = 0; i < numdevs; i++)
+ (*dev_select)[i].selected = 0;
+ }
+
+ /* we haven't gotten around to selecting anything yet.. */
+ if ((select_mode == DS_SELECT_ONLY) || (init_selections != 0)
+ || (init_selected_var != 0))
+ *num_selected = 0;
+
+ /*
+ * Look through any devices the user specified on the command line
+ * and see if they match known devices. If so, select them.
+ */
+ for (i = 0; (i < *num_selections) && (num_dev_selections > 0); i++) {
+ char tmpstr[80];
+
+ snprintf(tmpstr, sizeof(tmpstr), "%s%d",
+ (*dev_select)[i].device_name,
+ (*dev_select)[i].unit_number);
+ for (j = 0; j < num_dev_selections; j++) {
+ if (strcmp(tmpstr, dev_selections[j]) == 0) {
+ /*
+ * Here we do different things based on the
+ * mode we're in. If we're in add or
+ * addonly mode, we only select this device
+ * if it hasn't already been selected.
+ * Otherwise, we would be unnecessarily
+ * changing the selection order and
+ * incrementing the selection count. If
+ * we're in only mode, we unconditionally
+ * select this device, since in only mode
+ * any previous selections are erased and
+ * manually specified devices are the first
+ * ones to be selected. If we're in remove
+ * mode, we de-select the specified device and
+ * decrement the selection count.
+ */
+ switch(select_mode) {
+ case DS_SELECT_ADD:
+ case DS_SELECT_ADDONLY:
+ if ((*dev_select)[i].selected)
+ break;
+ /* FALLTHROUGH */
+ case DS_SELECT_ONLY:
+ (*dev_select)[i].selected =
+ ++selection_number;
+ (*num_selected)++;
+ break;
+ case DS_SELECT_REMOVE:
+ (*dev_select)[i].selected = 0;
+ (*num_selected)--;
+ /*
+ * This isn't passed back out, we
+ * just use it to keep track of
+ * how many devices we've removed.
+ */
+ num_dev_selections--;
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ /*
+ * Go through the user's device type expressions and select devices
+ * accordingly. We only do this if the number of devices already
+ * selected is less than the maximum number we can show.
+ */
+ for (i = 0; (i < num_matches) && (*num_selected < maxshowdevs); i++) {
+ /* We should probably indicate some error here */
+ if ((matches[i].match_fields == DEVSTAT_MATCH_NONE)
+ || (matches[i].num_match_categories <= 0))
+ continue;
+
+ for (j = 0; j < numdevs; j++) {
+ int num_match_categories;
+
+ num_match_categories = matches[i].num_match_categories;
+
+ /*
+ * Determine whether or not the current device
+ * matches the given matching expression. This if
+ * statement consists of three components:
+ * - the device type check
+ * - the device interface check
+ * - the passthrough check
+ * If a the matching test is successful, it
+ * decrements the number of matching categories,
+ * and if we've reached the last element that
+ * needed to be matched, the if statement succeeds.
+ *
+ */
+ if ((((matches[i].match_fields & DEVSTAT_MATCH_TYPE)!=0)
+ && ((devices[j].device_type & DEVSTAT_TYPE_MASK) ==
+ (matches[i].device_type & DEVSTAT_TYPE_MASK))
+ &&(((matches[i].match_fields & DEVSTAT_MATCH_PASS)!=0)
+ || (((matches[i].match_fields &
+ DEVSTAT_MATCH_PASS) == 0)
+ && ((devices[j].device_type &
+ DEVSTAT_TYPE_PASS) == 0)))
+ && (--num_match_categories == 0))
+ || (((matches[i].match_fields & DEVSTAT_MATCH_IF) != 0)
+ && ((devices[j].device_type & DEVSTAT_TYPE_IF_MASK) ==
+ (matches[i].device_type & DEVSTAT_TYPE_IF_MASK))
+ &&(((matches[i].match_fields & DEVSTAT_MATCH_PASS)!=0)
+ || (((matches[i].match_fields &
+ DEVSTAT_MATCH_PASS) == 0)
+ && ((devices[j].device_type &
+ DEVSTAT_TYPE_PASS) == 0)))
+ && (--num_match_categories == 0))
+ || (((matches[i].match_fields & DEVSTAT_MATCH_PASS)!=0)
+ && ((devices[j].device_type & DEVSTAT_TYPE_PASS) != 0)
+ && (--num_match_categories == 0))) {
+
+ /*
+ * This is probably a non-optimal solution
+ * to the problem that the devices in the
+ * device list will not be in the same
+ * order as the devices in the selection
+ * array.
+ */
+ for (k = 0; k < numdevs; k++) {
+ if ((*dev_select)[k].position == j) {
+ found = 1;
+ break;
+ }
+ }
+
+ /*
+ * There shouldn't be a case where a device
+ * in the device list is not in the
+ * selection list...but it could happen.
+ */
+ if (found != 1) {
+ fprintf(stderr, "selectdevs: couldn't"
+ " find %s%d in selection "
+ "list\n",
+ devices[j].device_name,
+ devices[j].unit_number);
+ break;
+ }
+
+ /*
+ * We do different things based upon the
+ * mode we're in. If we're in add or only
+ * mode, we go ahead and select this device
+ * if it hasn't already been selected. If
+ * it has already been selected, we leave
+ * it alone so we don't mess up the
+ * selection ordering. Manually specified
+ * devices have already been selected, and
+ * they have higher priority than pattern
+ * matched devices. If we're in remove
+ * mode, we de-select the given device and
+ * decrement the selected count.
+ */
+ switch(select_mode) {
+ case DS_SELECT_ADD:
+ case DS_SELECT_ADDONLY:
+ case DS_SELECT_ONLY:
+ if ((*dev_select)[k].selected != 0)
+ break;
+ (*dev_select)[k].selected =
+ ++selection_number;
+ (*num_selected)++;
+ break;
+ case DS_SELECT_REMOVE:
+ (*dev_select)[k].selected = 0;
+ (*num_selected)--;
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * Here we implement "top" mode. Devices are sorted in the
+ * selection array based on two criteria: whether or not they are
+ * selected (not selection number, just the fact that they are
+ * selected!) and the number of bytes in the "bytes" field of the
+ * selection structure. The bytes field generally must be kept up
+ * by the user. In the future, it may be maintained by library
+ * functions, but for now the user has to do the work.
+ *
+ * At first glance, it may seem wrong that we don't go through and
+ * select every device in the case where the user hasn't specified
+ * any devices or patterns. In fact, though, it won't make any
+ * difference in the device sorting. In that particular case (i.e.
+ * when we're in "add" or "only" mode, and the user hasn't
+ * specified anything) the first time through no devices will be
+ * selected, so the only criterion used to sort them will be their
+ * performance. The second time through, and every time thereafter,
+ * all devices will be selected, so again selection won't matter.
+ */
+ if (perf_select != 0) {
+
+ /* Sort the device array by throughput */
+ qsort(*dev_select, *num_selections,
+ sizeof(struct device_selection),
+ compare_select);
+
+ if (*num_selected == 0) {
+ /*
+ * Here we select every device in the array, if it
+ * isn't already selected. Because the 'selected'
+ * variable in the selection array entries contains
+ * the selection order, the devstats routine can show
+ * the devices that were selected first.
+ */
+ for (i = 0; i < *num_selections; i++) {
+ if ((*dev_select)[i].selected == 0) {
+ (*dev_select)[i].selected =
+ ++selection_number;
+ (*num_selected)++;
+ }
+ }
+ } else {
+ selection_number = 0;
+ for (i = 0; i < *num_selections; i++) {
+ if ((*dev_select)[i].selected != 0) {
+ (*dev_select)[i].selected =
+ ++selection_number;
+ }
+ }
+ }
+ }
+
+ /*
+ * If we're in the "add" selection mode and if we haven't already
+ * selected maxshowdevs number of devices, go through the array and
+ * select any unselected devices. If we're in "only" mode, we
+ * obviously don't want to select anything other than what the user
+ * specifies. If we're in "remove" mode, it probably isn't a good
+ * idea to go through and select any more devices, since we might
+ * end up selecting something that the user wants removed. Through
+ * more complicated logic, we could actually figure this out, but
+ * that would probably require combining this loop with the various
+ * selections loops above.
+ */
+ if ((select_mode == DS_SELECT_ADD) && (*num_selected < maxshowdevs)) {
+ for (i = 0; i < *num_selections; i++)
+ if ((*dev_select)[i].selected == 0) {
+ (*dev_select)[i].selected = ++selection_number;
+ (*num_selected)++;
+ }
+ }
+
+ /*
+ * Look at the number of devices that have been selected. If it
+ * has changed, set the changed variable. Otherwise, if we've
+ * made a backup of the selection list, compare it to the current
+ * selection list to see if the selected devices have changed.
+ */
+ if ((changed == 0) && (old_num_selected != *num_selected))
+ changed = 1;
+ else if ((changed == 0) && (old_dev_select != NULL)) {
+ /*
+ * Now we go through the selection list and we look at
+ * it three different ways.
+ */
+ for (i = 0; (i < *num_selections) && (changed == 0) &&
+ (i < old_num_selections); i++) {
+ /*
+ * If the device at index i in both the new and old
+ * selection arrays has the same device number and
+ * selection status, it hasn't changed. We
+ * continue on to the next index.
+ */
+ if (((*dev_select)[i].device_number ==
+ old_dev_select[i].device_number)
+ && ((*dev_select)[i].selected ==
+ old_dev_select[i].selected))
+ continue;
+
+ /*
+ * Now, if we're still going through the if
+ * statement, the above test wasn't true. So we
+ * check here to see if the device at index i in
+ * the current array is the same as the device at
+ * index i in the old array. If it is, that means
+ * that its selection number has changed. Set
+ * changed to 1 and exit the loop.
+ */
+ else if ((*dev_select)[i].device_number ==
+ old_dev_select[i].device_number) {
+ changed = 1;
+ break;
+ }
+ /*
+ * If we get here, then the device at index i in
+ * the current array isn't the same device as the
+ * device at index i in the old array.
+ */
+ else {
+ int found = 0;
+
+ /*
+ * Search through the old selection array
+ * looking for a device with the same
+ * device number as the device at index i
+ * in the current array. If the selection
+ * status is the same, then we mark it as
+ * found. If the selection status isn't
+ * the same, we break out of the loop.
+ * Since found isn't set, changed will be
+ * set to 1 below.
+ */
+ for (j = 0; j < old_num_selections; j++) {
+ if (((*dev_select)[i].device_number ==
+ old_dev_select[j].device_number)
+ && ((*dev_select)[i].selected ==
+ old_dev_select[j].selected)){
+ found = 1;
+ break;
+ }
+ else if ((*dev_select)[i].device_number
+ == old_dev_select[j].device_number)
+ break;
+ }
+ if (found == 0)
+ changed = 1;
+ }
+ }
+ }
+ if (old_dev_select != NULL)
+ free(old_dev_select);
+
+ return(changed);
+}
+
+/*
+ * Comparison routine for qsort() above. Note that the comparison here is
+ * backwards -- generally, it should return a value to indicate whether
+ * arg1 is <, =, or > arg2. Instead, it returns the opposite. The reason
+ * it returns the opposite is so that the selection array will be sorted in
+ * order of decreasing performance. We sort on two parameters. The first
+ * sort key is whether or not one or the other of the devices in question
+ * has been selected. If one of them has, and the other one has not, the
+ * selected device is automatically more important than the unselected
+ * device. If neither device is selected, we judge the devices based upon
+ * performance.
+ */
+static int
+compare_select(const void *arg1, const void *arg2)
+{
+ if ((((struct device_selection *)arg1)->selected)
+ && (((struct device_selection *)arg2)->selected == 0))
+ return(-1);
+ else if ((((struct device_selection *)arg1)->selected == 0)
+ && (((struct device_selection *)arg2)->selected))
+ return(1);
+ else if (((struct device_selection *)arg2)->bytes <
+ ((struct device_selection *)arg1)->bytes)
+ return(-1);
+ else if (((struct device_selection *)arg2)->bytes >
+ ((struct device_selection *)arg1)->bytes)
+ return(1);
+ else
+ return(0);
+}
+
+/*
+ * Take a string with the general format "arg1,arg2,arg3", and build a
+ * device matching expression from it.
+ */
+int
+buildmatch(char *match_str, struct devstat_match **matches, int *num_matches)
+{
+ char *tstr[5];
+ char **tempstr;
+ int num_args;
+ register int i, j;
+ char *func_name = "buildmatch";
+
+ /* We can't do much without a string to parse */
+ if (match_str == NULL) {
+ sprintf(devstat_errbuf, "%s: no match expression", func_name);
+ return(-1);
+ }
+
+ /*
+ * Break the (comma delimited) input string out into separate strings.
+ */
+ for (tempstr = tstr, num_args = 0;
+ (*tempstr = strsep(&match_str, ",")) != NULL && (num_args < 5);
+ num_args++)
+ if (**tempstr != '\0')
+ if (++tempstr >= &tstr[5])
+ break;
+
+ /* The user gave us too many type arguments */
+ if (num_args > 3) {
+ sprintf(devstat_errbuf, "%s: too many type arguments",
+ func_name);
+ return(-1);
+ }
+
+ /*
+ * Since you can't realloc a pointer that hasn't been malloced
+ * first, we malloc first and then realloc.
+ */
+ if (*num_matches == 0)
+ *matches = (struct devstat_match *)malloc(
+ sizeof(struct devstat_match));
+ else
+ *matches = (struct devstat_match *)realloc(*matches,
+ sizeof(struct devstat_match) * (*num_matches + 1));
+
+ /* Make sure the current entry is clear */
+ bzero(&matches[0][*num_matches], sizeof(struct devstat_match));
+
+ /*
+ * Step through the arguments the user gave us and build a device
+ * matching expression from them.
+ */
+ for (i = 0; i < num_args; i++) {
+ char *tempstr2, *tempstr3;
+
+ /*
+ * Get rid of leading white space.
+ */
+ tempstr2 = tstr[i];
+ while (isspace(*tempstr2) && (*tempstr2 != '\0'))
+ tempstr2++;
+
+ /*
+ * Get rid of trailing white space.
+ */
+ tempstr3 = &tempstr2[strlen(tempstr2) - 1];
+
+ while ((*tempstr3 != '\0') && (tempstr3 > tempstr2)
+ && (isspace(*tempstr3))) {
+ *tempstr3 = '\0';
+ tempstr3--;
+ }
+
+ /*
+ * Go through the match table comparing the user's
+ * arguments to known device types, interfaces, etc.
+ */
+ for (j = 0; match_table[j].match_str != NULL; j++) {
+ /*
+ * We do case-insensitive matching, in case someone
+ * wants to enter "SCSI" instead of "scsi" or
+ * something like that. Only compare as many
+ * characters as are in the string in the match
+ * table. This should help if someone tries to use
+ * a super-long match expression.
+ */
+ if (strncasecmp(tempstr2, match_table[j].match_str,
+ strlen(match_table[j].match_str)) == 0) {
+ /*
+ * Make sure the user hasn't specified two
+ * items of the same type, like "da" and
+ * "cd". One device cannot be both.
+ */
+ if (((*matches)[*num_matches].match_fields &
+ match_table[j].match_field) != 0) {
+ sprintf(devstat_errbuf,
+ "%s: cannot have more than "
+ "one match item in a single "
+ "category", func_name);
+ return(-1);
+ }
+ /*
+ * If we've gotten this far, we have a
+ * winner. Set the appropriate fields in
+ * the match entry.
+ */
+ (*matches)[*num_matches].match_fields |=
+ match_table[j].match_field;
+ (*matches)[*num_matches].device_type |=
+ match_table[j].type;
+ (*matches)[*num_matches].num_match_categories++;
+ break;
+ }
+ }
+ /*
+ * We should have found a match in the above for loop. If
+ * not, that means the user entered an invalid device type
+ * or interface.
+ */
+ if ((*matches)[*num_matches].num_match_categories != (i + 1)) {
+ snprintf(devstat_errbuf, sizeof(devstat_errbuf),
+ "%s: unknown match item \"%s\"", func_name,
+ tstr[i]);
+ return(-1);
+ }
+ }
+
+ (*num_matches)++;
+
+ return(0);
+}
+
+/*
+ * Compute a number of device statistics. Only one field is mandatory, and
+ * that is "current". Everything else is optional. The caller passes in
+ * pointers to variables to hold the various statistics he desires. If he
+ * doesn't want a particular staistic, he should pass in a NULL pointer.
+ * Return values:
+ * 0 -- success
+ * -1 -- failure
+ */
+int
+compute_stats(struct devstat *current, struct devstat *previous,
+ long double etime, u_int64_t *total_bytes,
+ u_int64_t *total_transfers, u_int64_t *total_blocks,
+ long double *kb_per_transfer, long double *transfers_per_second,
+ long double *mb_per_second, long double *blocks_per_second,
+ long double *ms_per_transaction)
+{
+ u_int64_t totalbytes, totaltransfers, totalblocks;
+ char *func_name = "compute_stats";
+
+ /*
+ * current is the only mandatory field.
+ */
+ if (current == NULL) {
+ sprintf(devstat_errbuf, "%s: current stats structure was NULL",
+ func_name);
+ return(-1);
+ }
+
+ totalbytes = (current->bytes_written + current->bytes_read) -
+ ((previous) ? (previous->bytes_written +
+ previous->bytes_read) : 0);
+
+ if (total_bytes)
+ *total_bytes = totalbytes;
+
+ totaltransfers = (current->num_reads +
+ current->num_writes +
+ current->num_other) -
+ ((previous) ?
+ (previous->num_reads +
+ previous->num_writes +
+ previous->num_other) : 0);
+ if (total_transfers)
+ *total_transfers = totaltransfers;
+
+ if (transfers_per_second) {
+ if (etime > 0.0) {
+ *transfers_per_second = totaltransfers;
+ *transfers_per_second /= etime;
+ } else
+ *transfers_per_second = 0.0;
+ }
+
+ if (kb_per_transfer) {
+ *kb_per_transfer = totalbytes;
+ *kb_per_transfer /= 1024;
+ if (totaltransfers > 0)
+ *kb_per_transfer /= totaltransfers;
+ else
+ *kb_per_transfer = 0.0;
+ }
+
+ if (mb_per_second) {
+ *mb_per_second = totalbytes;
+ *mb_per_second /= 1024 * 1024;
+ if (etime > 0.0)
+ *mb_per_second /= etime;
+ else
+ *mb_per_second = 0.0;
+ }
+
+ totalblocks = totalbytes;
+ if (current->block_size > 0)
+ totalblocks /= current->block_size;
+ else
+ totalblocks /= 512;
+
+ if (total_blocks)
+ *total_blocks = totalblocks;
+
+ if (blocks_per_second) {
+ *blocks_per_second = totalblocks;
+ if (etime > 0.0)
+ *blocks_per_second /= etime;
+ else
+ *blocks_per_second = 0.0;
+ }
+
+ if (ms_per_transaction) {
+ if (totaltransfers > 0) {
+ *ms_per_transaction = etime;
+ *ms_per_transaction /= totaltransfers;
+ *ms_per_transaction *= 1000;
+ } else
+ *ms_per_transaction = 0.0;
+ }
+
+ return(0);
+}
+
+long double
+compute_etime(struct timeval cur_time, struct timeval prev_time)
+{
+ struct timeval busy_time;
+ u_int64_t busy_usec;
+ long double etime;
+
+ timersub(&cur_time, &prev_time, &busy_time);
+
+ busy_usec = busy_time.tv_sec;
+ busy_usec *= 1000000;
+ busy_usec += busy_time.tv_usec;
+ etime = busy_usec;
+ etime /= 1000000;
+
+ return(etime);
+}
diff --git a/lib/libdevstat/devstat.h b/lib/libdevstat/devstat.h
new file mode 100644
index 0000000..fd0941c
--- /dev/null
+++ b/lib/libdevstat/devstat.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1997, 1998 Kenneth D. Merry.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _DEVSTAT_H
+#define _DEVSTAT_H
+#include <sys/cdefs.h>
+#include <sys/devicestat.h>
+
+#define DEVSTAT_ERRBUF_SIZE 2048 /* size of the devstat library error string */
+
+extern char devstat_errbuf[];
+
+typedef enum {
+ DEVSTAT_MATCH_NONE = 0x00,
+ DEVSTAT_MATCH_TYPE = 0x01,
+ DEVSTAT_MATCH_IF = 0x02,
+ DEVSTAT_MATCH_PASS = 0x04
+} devstat_match_flags;
+
+struct devstat_match {
+ devstat_match_flags match_fields;
+ devstat_type_flags device_type;
+ int num_match_categories;
+};
+
+struct devstat_match_table {
+ char *match_str;
+ devstat_type_flags type;
+ devstat_match_flags match_field;
+};
+
+struct device_selection {
+ u_int32_t device_number;
+ char device_name[DEVSTAT_NAME_LEN];
+ int unit_number;
+ int selected;
+ u_int64_t bytes;
+ int position;
+};
+
+struct devinfo {
+ struct devstat *devices;
+ u_int8_t *mem_ptr;
+ long generation;
+ int numdevs;
+};
+
+struct statinfo {
+ long cp_time[CPUSTATES];
+ long tk_nin;
+ long tk_nout;
+ struct devinfo *dinfo;
+ struct timeval busy_time;
+};
+
+typedef enum {
+ DS_SELECT_ADD,
+ DS_SELECT_ONLY,
+ DS_SELECT_REMOVE,
+ DS_SELECT_ADDONLY
+} devstat_select_mode;
+
+__BEGIN_DECLS
+int getnumdevs(void);
+long getgeneration(void);
+int getversion(void);
+int checkversion(void);
+int getdevs(struct statinfo *stats);
+int selectdevs(struct device_selection **dev_select, int *num_selected,
+ int *num_selections, long *select_generation,
+ long current_generation, struct devstat *devices, int numdevs,
+ struct devstat_match *matches, int num_matches,
+ char **dev_selections, int num_dev_selections,
+ devstat_select_mode select_mode, int maxshowdevs,
+ int perf_select);
+int buildmatch(char *match_str, struct devstat_match **matches,
+ int *num_matches);
+int compute_stats(struct devstat *current, struct devstat *previous,
+ long double etime, u_int64_t *total_bytes,
+ u_int64_t *total_transfers, u_int64_t *total_blocks,
+ long double *kb_per_transfer,
+ long double *transfers_per_second, long double *mb_per_second,
+ long double *blocks_per_second,
+ long double *ms_per_transaction);
+long double compute_etime(struct timeval cur_time, struct timeval prev_time);
+__END_DECLS
+
+#endif /* _DEVSTAT_H */
diff --git a/lib/libdisk/Makefile b/lib/libdisk/Makefile
new file mode 100644
index 0000000..355018a
--- /dev/null
+++ b/lib/libdisk/Makefile
@@ -0,0 +1,51 @@
+# $FreeBSD$
+
+LIB= disk
+SRCS= blocks.c disklabel.c dkcksum.c chunk.c disk.c change.c \
+ create_chunk.c rules.c write_disk.c
+
+CFLAGS+= -Wall
+CLEANFILES+= tmp.c tst01 tst01.o
+VPATH= ${.CURDIR}/../../sbin/disklabel
+NOPROFILE= yes
+NOSHARED= yes
+NOPIC= yes
+
+MAN3= libdisk.3
+MLINKS+= libdisk.3 Open_Disk.3 \
+ libdisk.3 Clone_Disk.3 \
+ libdisk.3 Free_Disk.3 \
+ libdisk.3 Debug_Disk.3 \
+ libdisk.3 Set_Bios_Geom.3 \
+ libdisk.3 Delete_Chunk.3 \
+ libdisk.3 Collapse_Disk.3 \
+ libdisk.3 Collapse_Chunk.3 \
+ libdisk.3 Create_Chunk.3 \
+ libdisk.3 All_FreeBSD.3 \
+ libdisk.3 CheckRules.3 \
+ libdisk.3 Disk_Names.3 \
+ libdisk.3 Set_Boot_Mgr.3 \
+ libdisk.3 Set_Boot_Blocks.3 \
+ libdisk.3 Write_Disk.3 \
+ libdisk.3 Cyl_Aligned.3 \
+ libdisk.3 Next_Cyl_Aligned.3 \
+ libdisk.3 Prev_Cyl_Aligned.3 \
+ libdisk.3 Track_Aligned.3 \
+ libdisk.3 Next_Track_Aligned.3 \
+ libdisk.3 Prev_Track_Aligned.3 \
+ libdisk.3 Create_Chunk_DWIM.3 \
+ libdisk.3 MakeDev.3 \
+ libdisk.3 MakeDevDisk.3 \
+ libdisk.3 ShowChunkFlags.3 \
+ libdisk.3 ChunkCanBeRoot.3 \
+ libdisk.3 slice_type_name.3
+
+.include <bsd.lib.mk>
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/libdisk.h \
+ ${DESTDIR}/usr/include/libdisk.h
+
+
+tst01: tst01.o libdisk.a
+ cc ${CFLAGS} -static tst01.o -o tst01 libdisk.a
diff --git a/lib/libdisk/blocks.c b/lib/libdisk/blocks.c
new file mode 100644
index 0000000..10f5b31
--- /dev/null
+++ b/lib/libdisk/blocks.c
@@ -0,0 +1,41 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+#include "libdisk.h"
+
+void *
+read_block(int fd, daddr_t block)
+{
+ void *foo;
+
+ foo = malloc(512);
+ if (!foo)
+ err(1,"malloc");
+ if (-1 == lseek(fd, (off_t)block * 512, SEEK_SET))
+ err(1, "lseek");
+ if (512 != read(fd,foo, 512))
+ err(1,"read");
+ return foo;
+}
+
+void
+write_block(int fd, daddr_t block, void *foo)
+{
+ if (-1 == lseek(fd, (off_t)block * 512, SEEK_SET))
+ err(1, "lseek");
+ if (512 != write(fd,foo, 512))
+ err(1,"write");
+}
diff --git a/lib/libdisk/change.c b/lib/libdisk/change.c
new file mode 100644
index 0000000..6a506f8
--- /dev/null
+++ b/lib/libdisk/change.c
@@ -0,0 +1,82 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <err.h>
+#include <sys/types.h>
+#include "libdisk.h"
+
+void
+Set_Bios_Geom(struct disk *disk, u_long cyl, u_long hd, u_long sect)
+{
+ disk->bios_cyl = cyl;
+ disk->bios_hd = hd;
+ disk->bios_sect = sect;
+ Bios_Limit_Chunk(disk->chunks,1024*hd*sect);
+}
+
+void
+Sanitize_Bios_Geom(struct disk *disk)
+{
+ int sane = 1;
+
+ if (disk->bios_cyl > 1024)
+ sane = 0;
+ if (disk->bios_hd > 16)
+ sane = 0;
+ if (disk->bios_sect > 63)
+ sane = 0;
+ if (disk->bios_cyl*disk->bios_hd*disk->bios_sect !=
+ disk->chunks->size)
+ sane = 0;
+ if (sane)
+ return;
+
+ /* First try something that IDE can handle */
+ disk->bios_sect = 63;
+ disk->bios_hd = 16;
+ disk->bios_cyl = disk->chunks->size/(disk->bios_sect*disk->bios_hd);
+
+ if (disk->bios_cyl < 1024)
+ return;
+
+ /* Hmm, try harder... */
+ disk->bios_hd = 255;
+ disk->bios_cyl = disk->chunks->size/(disk->bios_sect*disk->bios_hd);
+
+ return;
+}
+
+void
+All_FreeBSD(struct disk *d, int force_all)
+{
+ struct chunk *c;
+
+ again:
+ for (c=d->chunks->part;c;c=c->next)
+ if (c->type != unused) {
+ Delete_Chunk(d,c);
+ goto again;
+ }
+ c=d->chunks;
+ if (force_all) {
+ Sanitize_Bios_Geom(d);
+ Create_Chunk(d,c->offset,c->size,freebsd,0xa5,
+ CHUNK_FORCE_ALL);
+ } else {
+ Create_Chunk(d,c->offset,c->size,freebsd,0xa5, 0);
+ }
+}
diff --git a/lib/libdisk/chunk.c b/lib/libdisk/chunk.c
new file mode 100644
index 0000000..6116f54
--- /dev/null
+++ b/lib/libdisk/chunk.c
@@ -0,0 +1,433 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <err.h>
+#include "libdisk.h"
+
+#define new_chunk() memset(malloc(sizeof(struct chunk)), 0, sizeof(struct chunk))
+
+/* Is c2 completely inside c1 ? */
+
+static int
+Chunk_Inside(struct chunk *c1, struct chunk *c2)
+{
+ /* if c1 ends before c2 do */
+ if (c1->end < c2->end)
+ return 0;
+ /* if c1 starts after c2 do */
+ if (c1->offset > c2->offset)
+ return 0;
+ return 1;
+}
+
+struct chunk *
+Find_Mother_Chunk(struct chunk *chunks, u_long offset, u_long end, chunk_e type)
+{
+ struct chunk *c1,*c2,ct;
+ ct.offset = offset;
+ ct.end = end;
+ switch (type) {
+ case whole:
+ if (Chunk_Inside(chunks,&ct))
+ return chunks;
+ case extended:
+ for(c1=chunks->part;c1;c1=c1->next) {
+ if (c1->type != type)
+ continue;
+ if (Chunk_Inside(c1,&ct))
+ return c1;
+ }
+ return 0;
+ case freebsd:
+ for(c1=chunks->part;c1;c1=c1->next) {
+ if (c1->type == type)
+ if (Chunk_Inside(c1,&ct))
+ return c1;
+ if (c1->type != extended)
+ continue;
+ for(c2=c1->part;c2;c2=c2->next)
+ if (c2->type == type
+ && Chunk_Inside(c2,&ct))
+ return c2;
+ }
+ return 0;
+ default:
+ warn("Unsupported mother type in Find_Mother_Chunk");
+ return 0;
+ }
+}
+
+void
+Free_Chunk(struct chunk *c1)
+{
+ if(!c1) return;
+ if(c1->private_data && c1->private_free)
+ (*c1->private_free)(c1->private_data);
+ if(c1->part)
+ Free_Chunk(c1->part);
+ if(c1->next)
+ Free_Chunk(c1->next);
+ free(c1->name);
+ free(c1);
+}
+
+struct chunk *
+Clone_Chunk(struct chunk *c1)
+{
+ struct chunk *c2;
+ if(!c1)
+ return 0;
+ c2 = new_chunk();
+ if (!c2) err(1,"malloc failed");
+ *c2 = *c1;
+ if (c1->private_data && c1->private_clone)
+ c2->private_data = c2->private_clone(c2->private_data);
+ c2->name = strdup(c2->name);
+ c2->next = Clone_Chunk(c2->next);
+ c2->part = Clone_Chunk(c2->part);
+ return c2;
+}
+
+int
+Insert_Chunk(struct chunk *c2, u_long offset, u_long size, const char *name,
+ chunk_e type, int subtype, u_long flags)
+{
+ struct chunk *ct,*cs;
+
+ /* We will only insert into empty spaces */
+ if (c2->type != unused)
+ return __LINE__;
+
+ ct = new_chunk();
+ if (!ct) err(1,"malloc failed");
+ memset(ct,0,sizeof *ct);
+ ct->disk = c2->disk;
+ ct->offset = offset;
+ ct->size = size;
+ ct->end = offset + size - 1;
+ ct->type = type;
+ ct->name = strdup(name);
+ ct->subtype = subtype;
+ ct->flags = flags;
+
+ if (!Chunk_Inside(c2,ct)) {
+ Free_Chunk(ct);
+ return __LINE__;
+ }
+
+ if(type==freebsd || type==extended) {
+ cs = new_chunk();
+ if (!cs) err(1,"malloc failed");
+ memset(cs,0,sizeof *cs);
+ cs->disk = c2->disk;
+ cs->offset = offset;
+ cs->size = size;
+ cs->end = offset + size - 1;
+ cs->type = unused;
+ cs->name = strdup("-");
+ ct->part = cs;
+ }
+
+ /* Make a new chunk for any trailing unused space */
+ if (c2->end > ct->end) {
+ cs = new_chunk();
+ if (!cs) err(1,"malloc failed");
+ *cs = *c2;
+ cs->disk = c2->disk;
+ cs->offset = ct->end + 1;
+ cs->size = c2->end - ct->end;
+ if(c2->name)
+ cs->name = strdup(c2->name);
+ c2->next = cs;
+ c2->size -= c2->end - ct->end;
+ c2->end = ct->end;
+ }
+ /* If no leading unused space just occupy the old chunk */
+ if (c2->offset == ct->offset) {
+ c2->name = ct->name;
+ c2->type = ct->type;
+ c2->part = ct->part;
+ c2->subtype = ct->subtype;
+ c2->flags = ct->flags;
+ ct->name = 0;
+ ct->part = 0;
+ Free_Chunk(ct);
+ return 0;
+ }
+ /* else insert new chunk and adjust old one */
+ c2->end = ct->offset - 1;
+ c2->size -= ct->size;
+ ct->next = c2->next;
+ c2->next = ct;
+ return 0;
+}
+
+int
+Add_Chunk(struct disk *d, long offset, u_long size, const char *name,
+ chunk_e type, int subtype, u_long flags)
+{
+ struct chunk *c1,*c2,ct;
+ u_long end = offset + size - 1;
+ ct.offset = offset;
+ ct.end = end;
+ ct.size = size;
+
+ if (type == whole) {
+ d->chunks = c1 = new_chunk();
+ if (!c1) err(1,"malloc failed");
+ memset(c1,0,sizeof *c1);
+ c2 = c1->part = new_chunk();
+ if (!c2) err(1,"malloc failed");
+ memset(c2,0,sizeof *c2);
+ c2->disk = c1->disk = d;
+ c2->offset = c1->offset = offset;
+ c2->size = c1->size = size;
+ c2->end = c1->end = end;
+ c1->name = strdup(name);
+ c2->name = strdup("-");
+ c1->type = type;
+ c2->type = unused;
+ c1->flags = flags;
+ c1->subtype = subtype;
+ return 0;
+ }
+ if (type == freebsd)
+ subtype = 0xa5;
+ c1 = 0;
+ if(!c1 && (type == freebsd || type == fat || type == unknown))
+ c1 = Find_Mother_Chunk(d->chunks,offset,end,extended);
+ if(!c1 && (type == freebsd || type == fat || type == unknown))
+ c1 = Find_Mother_Chunk(d->chunks,offset,end,whole);
+ if(!c1 && type == extended)
+ c1 = Find_Mother_Chunk(d->chunks,offset,end,whole);
+ if(!c1 && type == part)
+ c1 = Find_Mother_Chunk(d->chunks,offset,end,freebsd);
+ if(!c1)
+ return __LINE__;
+ for(c2=c1->part;c2;c2=c2->next) {
+ if (c2->type != unused)
+ continue;
+ if(Chunk_Inside(c2,&ct)) {
+ if (type != freebsd)
+ goto doit;
+ if (!(flags & CHUNK_ALIGN))
+ goto doit;
+ if (offset == d->chunks->offset
+ && end == d->chunks->end)
+ goto doit;
+
+ /* Round down to prev cylinder */
+ offset = Prev_Cyl_Aligned(d,offset);
+ /* Stay inside the parent */
+ if (offset < c2->offset)
+ offset = c2->offset;
+ /* Round up to next cylinder */
+ offset = Next_Cyl_Aligned(d,offset);
+ /* Keep one track clear in front of parent */
+ if (offset == c1->offset)
+ offset = Next_Track_Aligned(d,offset+1);
+
+ /* Work on the (end+1) */
+ size += offset;
+ /* Round up to cylinder */
+ size = Next_Cyl_Aligned(d,size);
+ /* Stay inside parent */
+ if ((size-1) > c2->end)
+ size = c2->end+1;
+ /* Round down to cylinder */
+ size = Prev_Cyl_Aligned(d,size);
+
+ /* Convert back to size */
+ size -= offset;
+
+ doit:
+ return Insert_Chunk(c2,offset,size,name,
+ type,subtype,flags);
+ }
+ }
+ return __LINE__;
+}
+
+char *
+ShowChunkFlags(struct chunk *c)
+{
+ static char ret[10];
+
+ int i=0;
+ if (c->flags & CHUNK_BSD_COMPAT) ret[i++] = 'C';
+ if (c->flags & CHUNK_ACTIVE) ret[i++] = 'A';
+ if (c->flags & CHUNK_ALIGN) ret[i++] = '=';
+ if (c->flags & CHUNK_PAST_1024) ret[i++] = '>';
+ if (c->flags & CHUNK_IS_ROOT) ret[i++] = 'R';
+ ret[i++] = '\0';
+ return ret;
+}
+
+void
+Print_Chunk(struct chunk *c1,int offset)
+{
+ int i;
+ if(!c1) return;
+ for(i=0;i<offset-2;i++) putchar(' ');
+ for(;i<offset;i++) putchar('-');
+ putchar('>');
+ for(;i<10;i++) putchar(' ');
+ printf("%p %8ld %8lu %8lu %-8s %-8s 0x%02x %s",
+ c1, c1->offset, c1->size, c1->end, c1->name,
+ chunk_n[c1->type],c1->subtype,
+ ShowChunkFlags(c1));
+ putchar('\n');
+ Print_Chunk(c1->part,offset + 2);
+ Print_Chunk(c1->next,offset);
+}
+
+void
+Debug_Chunk(struct chunk *c1)
+{
+ Print_Chunk(c1,2);
+}
+
+void
+Bios_Limit_Chunk(struct chunk *c1, u_long limit)
+{
+ if (c1->part)
+ Bios_Limit_Chunk(c1->part,limit);
+ if (c1->next)
+ Bios_Limit_Chunk(c1->next,limit);
+ if (c1->end >= limit) {
+ c1->flags |= CHUNK_PAST_1024;
+ } else {
+ c1->flags &= ~CHUNK_PAST_1024;
+ }
+}
+
+int
+Delete_Chunk(struct disk *d, struct chunk *c)
+{
+ struct chunk *c1=0,*c2,*c3;
+ chunk_e type = c->type;
+
+ if(type == whole)
+ return 1;
+ if(!c1 && (type == freebsd || type == fat || type == unknown))
+ c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,extended);
+ if(!c1 && (type == freebsd || type == fat || type == unknown))
+ c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,whole);
+ if(!c1 && type == extended)
+ c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,whole);
+ if(!c1 && type == part)
+ c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,freebsd);
+ if(!c1)
+ return 1;
+ for(c2=c1->part;c2;c2=c2->next) {
+ if (c2 == c) {
+ c2->type = unused;
+ c2->subtype = 0;
+ c2->flags = 0;
+ free(c2->name);
+ c2->name = strdup("-");
+ Free_Chunk(c2->part);
+ c2->part =0;
+ goto scan;
+ }
+ }
+ return 1;
+ scan:
+ for(c2=c1->part;c2;c2=c2->next) {
+ if (c2->type != unused)
+ continue;
+ if (!c2->next)
+ continue;
+ if (c2->next->type != unused)
+ continue;
+ c3 = c2->next;
+ c2->size += c3->size;
+ c2->end = c3->end;
+ c2->next = c3->next;
+ c3->next = 0;
+ Free_Chunk(c3);
+ goto scan;
+ }
+ Fixup_Names(d);
+ return 0;
+}
+
+#if 0
+int
+Collapse_Chunk(struct disk *d, struct chunk *c1)
+{
+ struct chunk *c2, *c3;
+
+ if(c1->next && Collapse_Chunk(d,c1->next))
+ return 1;
+
+ if(c1->type == unused && c1->next && c1->next->type == unused) {
+ c3 = c1->next;
+ c1->size += c3->size;
+ c1->end = c3->end;
+ c1->next = c3->next;
+ c3->next = 0;
+ Free_Chunk(c3);
+ return 1;
+ }
+ c3 = c1->part;
+ if(!c3)
+ return 0;
+ if (Collapse_Chunk(d,c1->part))
+ return 1;
+
+ if (c1->type == whole)
+ return 0;
+
+ if(c3->type == unused && c3->size == c1->size) {
+ Delete_Chunk(d,c1);
+ return 1;
+ }
+ if(c3->type == unused) {
+ c2 = new_chunk();
+ if (!c2) err(1,"malloc failed");
+ *c2 = *c1;
+ c1->next = c2;
+ c1->disk = d;
+ c1->name = strdup("-");
+ c1->part = 0;
+ c1->type = unused;
+ c1->flags = 0;
+ c1->subtype = 0;
+ c1->size = c3->size;
+ c1->end = c3->end;
+ c2->offset += c1->size;
+ c2->size -= c1->size;
+ c2->part = c3->next;
+ c3->next = 0;
+ Free_Chunk(c3);
+ return 1;
+ }
+ for(c2=c3;c2->next;c2 = c2->next)
+ c3 = c2;
+ if (c2 && c2->type == unused) {
+ c3->next = 0;
+ c2->next = c1->next;
+ c1->next = c2;
+ c1->size -= c2->size;
+ c1->end -= c2->size;
+ return 1;
+ }
+
+ return 0;
+}
+#endif
diff --git a/lib/libdisk/create_chunk.c b/lib/libdisk/create_chunk.c
new file mode 100644
index 0000000..47b1e41
--- /dev/null
+++ b/lib/libdisk/create_chunk.c
@@ -0,0 +1,396 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/disklabel.h>
+#include <sys/diskslice.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <err.h>
+#include <grp.h>
+#include <pwd.h>
+#include "libdisk.h"
+
+/* Clone these two from sysinstall because we need our own copies
+ * due to link order problems with `crunch'. Feh!
+ */
+static int
+isDebug()
+{
+ static int debug = 0; /* Allow debugger to tweak it */
+
+ return debug;
+}
+
+/* Write something to the debugging port */
+static void
+msgDebug(char *fmt, ...)
+{
+ va_list args;
+ char *dbg;
+ static int DebugFD = -1;
+
+ if (DebugFD == -1)
+ DebugFD = open("/dev/ttyv1", O_RDWR);
+ dbg = (char *)alloca(FILENAME_MAX);
+ strcpy(dbg, "DEBUG: ");
+ va_start(args, fmt);
+ vsnprintf((char *)(dbg + strlen(dbg)), FILENAME_MAX, fmt, args);
+ va_end(args);
+ write(DebugFD, dbg, strlen(dbg));
+}
+
+void
+Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
+{
+ struct chunk *c1, *c3;
+ int j;
+
+ if (!strcmp(c->name, "X")) return;
+
+ /* reset all names to "X" */
+ for (c1 = c->part; c1 ; c1 = c1->next) {
+ c1->oname = c1->name;
+ c1->name = malloc(12);
+ if(!c1->name) err(1,"Malloc failed");
+ strcpy(c1->name,"X");
+ }
+
+ /* Allocate the first swap-partition we find */
+ for (c1 = c->part; c1 ; c1 = c1->next) {
+ if (c1->type == unused) continue;
+ if (c1->subtype != FS_SWAP) continue;
+ sprintf(c1->name,"%s%c",c->name,SWAP_PART+'a');
+ break;
+ }
+
+ /* Allocate the first root-partition we find */
+ for (c1 = c->part; c1 ; c1 = c1->next) {
+ if (c1->type == unused) continue;
+ if (!(c1->flags & CHUNK_IS_ROOT)) continue;
+ sprintf(c1->name,"%s%c",c->name,0+'a');
+ break;
+ }
+
+ /* Try to give them the same as they had before */
+ for (c1 = c->part; c1 ; c1 = c1->next) {
+ if (strcmp(c1->name,"X")) continue;
+ for(c3 = c->part; c3 ; c3 = c3->next)
+ if (c1 != c3 && !strcmp(c3->name, c1->oname)) {
+ goto newname;
+ }
+ strcpy(c1->name,c1->oname);
+ newname:
+ }
+
+
+ /* Allocate the rest sequentially */
+ for (c1 = c->part; c1 ; c1 = c1->next) {
+ const char order[] = "efghabd";
+ if (c1->type == unused) continue;
+ if (strcmp("X",c1->name)) continue;
+
+ for(j=0;j<strlen(order);j++) {
+ sprintf(c1->name,"%s%c",c->name,order[j]);
+ for(c3 = c->part; c3 ; c3 = c3->next)
+ if (c1 != c3 && !strcmp(c3->name, c1->name))
+ goto match;
+ break;
+ match:
+ strcpy(c1->name,"X");
+ continue;
+ }
+ }
+ for (c1 = c->part; c1 ; c1 = c1->next) {
+ free(c1->oname);
+ c1->oname = 0;
+ }
+}
+
+void
+Fixup_Extended_Names(struct disk *d, struct chunk *c)
+{
+ struct chunk *c1;
+ int j=5;
+
+ for (c1 = c->part; c1 ; c1 = c1->next) {
+ if (c1->type == unused) continue;
+ free(c1->name);
+ c1->name = malloc(12);
+ if(!c1->name) err(1,"malloc failed");
+ sprintf(c1->name,"%ss%d",d->chunks->name,j++);
+ if (c1->type == freebsd)
+ Fixup_FreeBSD_Names(d,c1);
+ }
+}
+
+void
+Fixup_Names(struct disk *d)
+{
+ struct chunk *c1, *c2, *c3;
+ int i,j;
+
+ c1 = d->chunks;
+ for(i=1,c2 = c1->part; c2 ; c2 = c2->next) {
+ c2->flags &= ~CHUNK_BSD_COMPAT;
+ if (c2->type == unused)
+ continue;
+ if (strcmp(c2->name,"X"))
+ continue;
+#ifndef __alpha__
+ c2->oname = malloc(12);
+ if(!c2->oname) err(1,"malloc failed");
+ for(j=1;j<=NDOSPART;j++) {
+ sprintf(c2->oname,"%ss%d",c1->name,j);
+ for(c3 = c1->part; c3 ; c3 = c3->next)
+ if (c3 != c2 && !strcmp(c3->name, c2->oname))
+ goto match;
+ free(c2->name);
+ c2->name = c2->oname;
+ c2->oname = 0;
+ break;
+ match:
+ continue;
+ }
+ if (c2->oname)
+ free(c2->oname);
+#else
+ free(c2->name);
+ c2->name = strdup(c1->name);
+#endif
+ }
+ for(c2 = c1->part; c2 ; c2 = c2->next) {
+ if (c2->type == freebsd) {
+ c2->flags |= CHUNK_BSD_COMPAT;
+ break;
+ }
+ }
+ for(c2 = c1->part; c2 ; c2 = c2->next) {
+ if (c2->type == freebsd)
+ Fixup_FreeBSD_Names(d,c2);
+ if (c2->type == extended)
+ Fixup_Extended_Names(d,c2);
+ }
+}
+
+int
+Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags)
+{
+ int i;
+ u_long l;
+
+ if(!(flags & CHUNK_FORCE_ALL))
+ {
+ /* Never use the first track */
+ if (!offset) {
+ offset += d->bios_sect;
+ size -= d->bios_sect;
+ }
+
+ /* Always end on cylinder boundary */
+ l = (offset+size) % (d->bios_sect * d->bios_hd);
+ size -= l;
+ }
+
+ i = Add_Chunk(d,offset,size,"X",type,subtype,flags);
+ Fixup_Names(d);
+ return i;
+}
+
+struct chunk *
+Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size, chunk_e type, int subtype, u_long flags)
+{
+ int i;
+ struct chunk *c1;
+ u_long offset;
+
+ if (!parent)
+ parent = d->chunks;
+ for (c1=parent->part; c1 ; c1 = c1->next) {
+ if (c1->type != unused) continue;
+ if (c1->size < size) continue;
+ offset = c1->offset;
+ goto found;
+ }
+ return 0;
+ found:
+ i = Add_Chunk(d,offset,size,"X",type,subtype,flags);
+ if (i)
+ return 0;
+ Fixup_Names(d);
+ for (c1=parent->part; c1 ; c1 = c1->next)
+ if (c1->offset == offset)
+ return c1;
+ err(1,"Serious internal trouble");
+}
+
+int
+MakeDev(struct chunk *c1, const char *path)
+{
+ char *p = c1->name;
+ u_long cmaj, min, unit, part, slice;
+ char buf[BUFSIZ], buf2[BUFSIZ];
+ struct group *grp;
+ struct passwd *pwd;
+
+ *buf2 = '\0';
+ if (isDebug())
+ msgDebug("MakeDev: Called with %s on path %s\n", p, path);
+ if (!strcmp(p, "X"))
+ return 0;
+
+ if (!strncmp(p, "wd", 2))
+ cmaj = 3, p += 2;
+ else if (!strncmp(p, "ad", 2))
+ cmaj = 116, p += 2;
+ else if (!strncmp(p, "wfd", 3))
+ cmaj = 87, p += 3;
+ else if (!strncmp(p, "afd", 3))
+ cmaj = 118, p += 3;
+ else if (!strncmp(p, "fla", 3))
+ cmaj = 102, p += 3;
+ else if (!strncmp(p, "ida", 3))
+ cmaj = 109, p += 3;
+ else if (!strncmp(p, "mlxd", 4))
+ cmaj = 131, p += 4;
+ else if (!strncmp(p, "amrd", 4))
+ cmaj = 133, p += 4;
+ else if (!strncmp(p, "da", 2)) /* CAM support */
+ cmaj = 13, p += 2;
+ else {
+ msgDebug("MakeDev: Unknown major/minor for devtype %s\n", p);
+ return 0;
+ }
+ if (!isdigit(*p)) {
+ msgDebug("MakeDev: Invalid disk unit passed: %s\n", p);
+ return 0;
+ }
+ unit = *p - '0';
+ p++;
+ if (!*p) {
+ slice = 1;
+ part = 2;
+ goto done;
+ }
+ else if (isdigit(*p)) {
+ unit *= 10;
+ unit += (*p - '0');
+ p++;
+ }
+#ifndef __alpha__
+ if (*p != 's') {
+ msgDebug("MakeDev: `%s' is not a valid slice delimiter\n", p);
+ return 0;
+ }
+ p++;
+ if (!isdigit(*p)) {
+ msgDebug("MakeDev: `%s' is an invalid slice number\n", p);
+ return 0;
+ }
+ slice = *p - '0';
+ p++;
+ if (isdigit(*p)) {
+ slice *= 10;
+ slice += (*p - '0');
+ p++;
+ }
+ slice = slice + 1;
+#else
+ slice = 0;
+#endif
+ if (!*p) {
+ part = 2;
+ if(c1->type == freebsd)
+ sprintf(buf2, "%sc", c1->name);
+ goto done;
+ }
+ if (*p < 'a' || *p > 'h') {
+ msgDebug("MakeDev: `%s' is not a valid partition name.\n", p);
+ return 0;
+ }
+ part = *p - 'a';
+ done:
+ if (isDebug())
+ msgDebug("MakeDev: Unit %d, Slice %d, Part %d\n", unit, slice, part);
+ if (unit > 32)
+ return 0;
+ if (slice > 32)
+ return 0;
+ if ((pwd = getpwnam("root")) == NULL) {
+ msgDebug("MakeDev: Unable to lookup user \"root\".\n");
+ return 0;
+ }
+ if ((grp = getgrnam("operator")) == NULL) {
+ msgDebug("MakeDev: Unable to lookup group \"operator\".\n");
+ return 0;
+ }
+ min = unit * 8 + 65536 * slice + part;
+ sprintf(buf, "%s/r%s", path, c1->name);
+ unlink(buf);
+ if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
+ msgDebug("mknod of %s returned failure status!\n", buf);
+ return 0;
+ }
+ if (chown(buf, pwd->pw_uid, grp->gr_gid) == -1) {
+ msgDebug("chown of %s returned failure status!\n", buf);
+ return 0;
+ }
+ if (*buf2) {
+ sprintf(buf, "%s/r%s", path, buf2);
+ unlink(buf);
+ if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
+ msgDebug("mknod of %s returned failure status!\n", buf);
+ return 0;
+ }
+ if (chown(buf, pwd->pw_uid, grp->gr_gid) == -1) {
+ msgDebug("chown of %s returned failure status!\n", buf);
+ return 0;
+ }
+ }
+ sprintf(buf, "%s/%s", path, c1->name);
+ unlink(buf);
+ if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
+ msgDebug("mknod of %s returned failure status!\n", buf);
+ return 0;
+ }
+ if (chown(buf, pwd->pw_uid, grp->gr_gid) == -1) {
+ msgDebug("chown of %s returned failure status!\n", buf);
+ return 0;
+ }
+ return 1;
+}
+
+int
+MakeDevChunk(struct chunk *c1, const char *path)
+{
+ int i;
+
+ i = MakeDev(c1, path);
+ if (c1->next)
+ MakeDevChunk(c1->next, path);
+ if (c1->part)
+ MakeDevChunk(c1->part, path);
+ return i;
+}
+
+int
+MakeDevDisk(struct disk *d, const char *path)
+{
+ return MakeDevChunk(d->chunks, path);
+}
diff --git a/lib/libdisk/disk.c b/lib/libdisk/disk.c
new file mode 100644
index 0000000..cae69a0
--- /dev/null
+++ b/lib/libdisk/disk.c
@@ -0,0 +1,494 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <err.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/disklabel.h>
+#include <sys/diskslice.h>
+#include "libdisk.h"
+
+#define DOSPTYP_EXTENDED 5
+#define DOSPTYP_ONTRACK 84
+
+const char *chunk_n[] = {
+ "whole",
+ "unknown",
+ "fat",
+ "freebsd",
+ "extended",
+ "part",
+ "unused",
+ NULL
+};
+
+struct disk *
+Open_Disk(const char *name)
+{
+ return Int_Open_Disk(name,0);
+}
+
+static u_int32_t
+Read_Int32(u_int32_t *p)
+{
+ u_int8_t *bp = (u_int8_t *)p;
+ return bp[0] | (bp[1] << 8) | (bp[2] << 16) | (bp[3] << 24);
+}
+
+struct disk *
+Int_Open_Disk(const char *name, u_long size)
+{
+ int i,fd;
+ struct diskslices ds;
+ struct disklabel dl;
+ char device[64];
+ struct disk *d;
+ struct dos_partition *dp;
+ void *p;
+ u_long offset = 0;
+
+ strcpy(device,"/dev/r");
+ strcat(device,name);
+
+ d = (struct disk *)malloc(sizeof *d);
+ if(!d) err(1,"malloc failed");
+ memset(d,0,sizeof *d);
+
+ fd = open(device,O_RDONLY);
+ if (fd < 0) {
+#ifdef DEBUG
+ warn("open(%s) failed",device);
+#endif
+ return 0;
+ }
+
+ memset(&dl,0,sizeof dl);
+ ioctl(fd,DIOCGDINFO,&dl);
+ i = ioctl(fd,DIOCGSLICEINFO,&ds);
+ if (i < 0) {
+#ifdef DEBUG
+ warn("DIOCGSLICEINFO(%s) failed",device);
+#endif
+ close(fd);
+ return 0;
+ }
+
+#ifdef DEBUG
+ for(i=0;i<ds.dss_nslices;i++)
+ if(ds.dss_slices[i].ds_openmask)
+ printf(" open(%d)=0x%2x",
+ i,ds.dss_slices[i].ds_openmask);
+ printf("\n");
+#endif
+
+ if (!size)
+ size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size;
+
+ p = read_block(fd,0);
+ dp = (struct dos_partition*)(p+DOSPARTOFF);
+ for (i=0; i < NDOSPART; i++) {
+ if (Read_Int32(&dp->dp_start) >= size)
+ continue;
+ if (Read_Int32(&dp->dp_start) + Read_Int32(&dp->dp_size) >= size)
+ continue;
+ if (!Read_Int32(&dp->dp_size))
+ continue;
+
+ if (dp->dp_typ == DOSPTYP_ONTRACK) {
+ d->flags |= DISK_ON_TRACK;
+ offset = 63;
+ }
+
+ }
+ free(p);
+
+ d->bios_sect = dl.d_nsectors;
+ d->bios_hd = dl.d_ntracks;
+
+ d->name = strdup(name);
+
+
+ if (dl.d_ntracks && dl.d_nsectors)
+ d->bios_cyl = size/(dl.d_ntracks*dl.d_nsectors);
+
+ if (Add_Chunk(d, -offset, size, name, whole, 0, 0))
+#ifdef DEBUG
+ warn("Failed to add 'whole' chunk");
+#else
+ {}
+#endif
+
+#ifdef __i386__
+ for(i=BASE_SLICE;i<ds.dss_nslices;i++) {
+ char sname[20];
+ chunk_e ce;
+ u_long flags=0;
+ int subtype=0;
+ if (! ds.dss_slices[i].ds_size)
+ continue;
+ ds.dss_slices[i].ds_offset -= offset;
+ sprintf(sname,"%ss%d",name,i-1);
+ subtype = ds.dss_slices[i].ds_type;
+ switch (ds.dss_slices[i].ds_type) {
+ case 0xa5:
+ ce = freebsd;
+ break;
+ case 0x1:
+ case 0x6:
+ case 0x4:
+ case 0xb:
+ case 0xc:
+ case 0xe:
+ ce = fat;
+ break;
+ case DOSPTYP_EXTENDED:
+ case 0xf:
+ ce = extended;
+ break;
+ default:
+ ce = unknown;
+ break;
+ }
+ if (Add_Chunk(d, ds.dss_slices[i].ds_offset,
+ ds.dss_slices[i].ds_size, sname, ce, subtype, flags))
+#ifdef DEBUG
+ warn("failed to add chunk for slice %d", i - 1);
+#else
+ {}
+#endif
+
+ if (ds.dss_slices[i].ds_type != 0xa5)
+ continue;
+ {
+ struct disklabel dl;
+ char pname[20];
+ int j,k;
+
+ strcpy(pname,"/dev/r");
+ strcat(pname,sname);
+ j = open(pname,O_RDONLY);
+ if (j < 0) {
+#ifdef DEBUG
+ warn("open(%s)",pname);
+#endif
+ continue;
+ }
+ k = ioctl(j,DIOCGDINFO,&dl);
+ if (k < 0) {
+#ifdef DEBUG
+ warn("ioctl(%s,DIOCGDINFO)",pname);
+#endif
+ close(j);
+ continue;
+ }
+ close(j);
+
+ for(j=0; j <= dl.d_npartitions; j++) {
+ if (j == RAW_PART)
+ continue;
+ if (j == 3)
+ continue;
+ if (j == dl.d_npartitions) {
+ j = 3;
+ dl.d_npartitions=0;
+ }
+ if (!dl.d_partitions[j].p_size)
+ continue;
+ if (dl.d_partitions[j].p_size +
+ dl.d_partitions[j].p_offset >
+ ds.dss_slices[i].ds_size)
+ continue;
+ sprintf(pname,"%s%c",sname,j+'a');
+ if (Add_Chunk(d,
+ dl.d_partitions[j].p_offset +
+ ds.dss_slices[i].ds_offset,
+ dl.d_partitions[j].p_size,
+ pname,part,
+ dl.d_partitions[j].p_fstype,
+ 0) && j != 3)
+#ifdef DEBUG
+ warn(
+ "Failed to add chunk for partition %c [%lu,%lu]",
+ j + 'a',dl.d_partitions[j].p_offset,
+ dl.d_partitions[j].p_size);
+#else
+ {}
+#endif
+ }
+ }
+ }
+#endif /* __i386__ */
+#ifdef __alpha__
+ {
+ struct disklabel dl;
+ char pname[20];
+ int j,k;
+
+ strcpy(pname,"/dev/r");
+ strcat(pname,name);
+ j = open(pname,O_RDONLY);
+ if (j < 0) {
+#ifdef DEBUG
+ warn("open(%s)",pname);
+#endif
+ goto nolabel;
+ }
+ k = ioctl(j,DIOCGDINFO,&dl);
+ if (k < 0) {
+#ifdef DEBUG
+ warn("ioctl(%s,DIOCGDINFO)",pname);
+#endif
+ close(j);
+ goto nolabel;
+ }
+ close(j);
+ All_FreeBSD(d, 1);
+
+ for(j=0; j <= dl.d_npartitions; j++) {
+ if (j == RAW_PART)
+ continue;
+ if (j == 3)
+ continue;
+ if (j == dl.d_npartitions) {
+ j = 3;
+ dl.d_npartitions=0;
+ }
+ if (!dl.d_partitions[j].p_size)
+ continue;
+ if (dl.d_partitions[j].p_size +
+ dl.d_partitions[j].p_offset >
+ ds.dss_slices[WHOLE_DISK_SLICE].ds_size)
+ continue;
+ sprintf(pname,"%s%c",name,j+'a');
+ if (Add_Chunk(d,
+ dl.d_partitions[j].p_offset,
+ dl.d_partitions[j].p_size,
+ pname,part,
+ dl.d_partitions[j].p_fstype,
+ 0) && j != 3)
+#ifdef DEBUG
+ warn(
+ "Failed to add chunk for partition %c [%lu,%lu]",
+ j + 'a',dl.d_partitions[j].p_offset,
+ dl.d_partitions[j].p_size);
+#else
+ {}
+#endif
+ }
+ nolabel:;
+ }
+#endif /* __alpha__ */
+ close(fd);
+ Fixup_Names(d);
+ Bios_Limit_Chunk(d->chunks,1024*d->bios_hd*d->bios_sect);
+ return d;
+}
+
+void
+Debug_Disk(struct disk *d)
+{
+ printf("Debug_Disk(%s)",d->name);
+ printf(" flags=%lx",d->flags);
+#if 0
+ printf(" real_geom=%lu/%lu/%lu",d->real_cyl,d->real_hd,d->real_sect);
+#endif
+ printf(" bios_geom=%lu/%lu/%lu = %lu\n",
+ d->bios_cyl,d->bios_hd,d->bios_sect,
+ d->bios_cyl*d->bios_hd*d->bios_sect);
+#if defined(__i386__)
+ printf(" boot1=%p, boot2=%p, bootmgr=%p\n",
+ d->boot1,d->boot2,d->bootmgr);
+#elif defined(__alpha__)
+ printf(" boot1=%p, bootmgr=%p\n",
+ d->boot1,d->bootmgr);
+#endif
+ Debug_Chunk(d->chunks);
+}
+
+void
+Free_Disk(struct disk *d)
+{
+ if(d->chunks) Free_Chunk(d->chunks);
+ if(d->name) free(d->name);
+ if(d->bootmgr) free(d->bootmgr);
+ if(d->boot1) free(d->boot1);
+#if defined(__i386__)
+ if(d->boot2) free(d->boot2);
+#endif
+ free(d);
+}
+
+struct disk *
+Clone_Disk(struct disk *d)
+{
+ struct disk *d2;
+
+ d2 = (struct disk*) malloc(sizeof *d2);
+ if(!d2) err(1,"malloc failed");
+ *d2 = *d;
+ d2->name = strdup(d2->name);
+ d2->chunks = Clone_Chunk(d2->chunks);
+ if(d2->bootmgr) {
+ d2->bootmgr = malloc(DOSPARTOFF);
+ memcpy(d2->bootmgr,d->bootmgr,DOSPARTOFF);
+ }
+#if defined(__i386__)
+ if(d2->boot1) {
+ d2->boot1 = malloc(512);
+ memcpy(d2->boot1,d->boot1,512);
+ }
+ if(d2->boot2) {
+ d2->boot2 = malloc(512*15);
+ memcpy(d2->boot2,d->boot2,512*15);
+ }
+#elif defined(__alpha__)
+ if(d2->boot1) {
+ d2->boot1 = malloc(512*15);
+ memcpy(d2->boot1,d->boot1,512*15);
+ }
+#endif
+ return d2;
+}
+
+#if 0
+void
+Collapse_Disk(struct disk *d)
+{
+
+ while(Collapse_Chunk(d,d->chunks))
+ ;
+}
+#endif
+
+static char * device_list[] = {"wd", "ad", "da", "wfd", "fla", "ida", "mlxd", "amrd", 0};
+
+char **
+Disk_Names()
+{
+ int i,j,k;
+ char disk[25];
+ char diskname[25];
+ struct stat st;
+ struct diskslices ds;
+ int fd;
+ static char **disks;
+
+ disks = malloc(sizeof *disks * (1 + MAX_NO_DISKS));
+ memset(disks,0,sizeof *disks * (1 + MAX_NO_DISKS));
+ k = 0;
+ for (j = 0; device_list[j]; j++) {
+ for (i = 0; i < MAX_NO_DISKS; i++) {
+ sprintf(diskname, "%s%d", device_list[j], i);
+ sprintf(disk, "/dev/r%s", diskname);
+ if (stat(disk, &st) || !(st.st_mode & S_IFCHR))
+ continue;
+ if ((fd = open(disk, O_RDWR)) == -1)
+ continue;
+ if (ioctl(fd, DIOCGSLICEINFO, &ds) == -1) {
+ close(fd);
+ continue;
+ }
+ disks[k++] = strdup(diskname);
+ if(k == MAX_NO_DISKS)
+ return disks;
+ }
+ }
+ return disks;
+}
+
+void
+Set_Boot_Mgr(struct disk *d, const u_char *b)
+{
+ if (d->bootmgr)
+ free(d->bootmgr);
+ if (!b) {
+ d->bootmgr = 0;
+ } else {
+ d->bootmgr = malloc(DOSPARTOFF);
+ if(!d->bootmgr) err(1,"malloc failed");
+ memcpy(d->bootmgr,b,DOSPARTOFF);
+ }
+}
+
+void
+Set_Boot_Blocks(struct disk *d, const u_char *b1, const u_char *b2)
+{
+#if defined(__i386__)
+ if (d->boot1) free(d->boot1);
+ d->boot1 = malloc(512);
+ if(!d->boot1) err(1,"malloc failed");
+ memcpy(d->boot1,b1,512);
+ if (d->boot2) free(d->boot2);
+ d->boot2 = malloc(15*512);
+ if(!d->boot2) err(1,"malloc failed");
+ memcpy(d->boot2,b2,15*512);
+#elif defined(__alpha__)
+ if (d->boot1) free(d->boot1);
+ d->boot1 = malloc(15*512);
+ if(!d->boot1) err(1,"malloc failed");
+ memcpy(d->boot1,b1,15*512);
+#endif
+}
+
+const char *
+slice_type_name( int type, int subtype )
+{
+ switch (type) {
+ case 0: return "whole";
+ case 1: switch (subtype) {
+ case 1: return "fat (12-bit)";
+ case 2: return "XENIX /";
+ case 3: return "XENIX /usr";
+ case 4: return "fat (16-bit,<=32Mb)";
+ case 5: return "extended DOS";
+ case 6: return "fat (16-bit,>32Mb)";
+ case 7: return "NTFS/HPFS/QNX";
+ case 8: return "AIX bootable";
+ case 9: return "AIX data";
+ case 10: return "OS/2 bootmgr";
+ case 11: return "fat (32-bit)";
+ case 12: return "fat (32-bit,LBA)";
+ case 14: return "fat (16-bit,>32Mb,LBA)";
+ case 15: return "extended DOS, LBA";
+ case 18: return "Compaq Diagnostic";
+ case 84: return "OnTrack diskmgr";
+ case 100: return "Netware 2.x";
+ case 101: return "Netware 3.x";
+ case 115: return "SCO UnixWare";
+ case 128: return "Minix 1.1";
+ case 129: return "Minix 1.5";
+ case 130: return "linux_swap";
+ case 131: return "ext2fs";
+ case 166: return "OpenBSD FFS"; /* 0xA6 */
+ case 169: return "NetBSD FFS"; /* 0xA9 */
+ case 182: return "OpenBSD"; /* dedicated */
+ case 183: return "bsd/os";
+ case 184: return "bsd/os swap";
+ default: return "unknown";
+ }
+ case 2: return "fat";
+ case 3: switch (subtype) {
+ case 165: return "freebsd";
+ default: return "unknown";
+ }
+ case 4: return "extended";
+ case 5: return "part";
+ case 6: return "unused";
+ default: return "unknown";
+ }
+}
diff --git a/lib/libdisk/disklabel.c b/lib/libdisk/disklabel.c
new file mode 100644
index 0000000..2ee6503
--- /dev/null
+++ b/lib/libdisk/disklabel.c
@@ -0,0 +1,33 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+#include <sys/disklabel.h>
+#include "libdisk.h"
+
+struct disklabel *
+read_disklabel(int fd, daddr_t block)
+{
+ struct disklabel *dp;
+
+ dp = (struct disklabel *) read_block(fd,block);
+ if (dp->d_magic != DISKMAGIC)
+ return 0;
+ if (dp->d_magic2 != DISKMAGIC)
+ return 0;
+ if (dkcksum(dp) != 0)
+ return 0;
+ return dp;
+}
diff --git a/lib/libdisk/libdisk.3 b/lib/libdisk/libdisk.3
new file mode 100644
index 0000000..07c1ffe
--- /dev/null
+++ b/lib/libdisk/libdisk.3
@@ -0,0 +1,331 @@
+.\"
+.\" Copyright (c) 1996 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" This program is free software.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" "
+.Dd March 15, 1996
+.Dt LIBDISK 3
+.Os
+.Sh NAME
+.Nm Open_Disk ,
+.Nm Clone_Disk ,
+.Nm Free_Disk ,
+.Nm Debug_Disk ,
+.Nm Set_Bios_Geom ,
+.Nm Delete_Chunk ,
+.Nm Collapse_Disk ,
+.Nm Collapse_Chunk ,
+.Nm Create_Chunk ,
+.Nm All_FreeBSD ,
+.Nm CheckRules ,
+.Nm Disk_Names ,
+.Nm Set_Boot_Mgr ,
+.Nm Set_Boot_Blocks ,
+.Nm Write_Disk ,
+.Nm Cyl_Aligned ,
+.Nm Next_Cyl_Aligned ,
+.Nm Prev_Cyl_Aligned ,
+.Nm Track_Aligned ,
+.Nm Next_Track_Aligned ,
+.Nm Prev_Track_Aligned ,
+.Nm Create_Chunk_DWIM ,
+.Nm MakeDev ,
+.Nm MakeDevDisk ,
+.Nm ShowChunkFlags ,
+.Nm ChunkCanBeRoot ,
+.Nm chunk_n ,
+.Nm slice_type_name
+.Nd library interface to slice and partition labels (libdisk)
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <libdisk.h>
+
+.Dv extern const char *chunk_n[];
+.Ft const char *
+.Fn slice_type_name "int type" "int subtype"
+.Ft struct disk *
+.Fn Open_Disk "const char *devname"
+.Ft struct disk *
+.Fn Clone_Disk "struct disk *disk"
+.Ft void
+.Fn Free_Disk "struct disk *disk"
+.Ft void
+.Fn Debug_Disk "struct disk *disk"
+.Ft void
+.Fn Set_Bios_Geom "struct disk *disk" "u_long cyl" "u_long heads" "u_long sects"
+.Ft int
+.Fn Delete_Chunk "struct disk *disk" "struct chunk *"
+.Ft void
+.Fn Collapse_Disk "struct disk *disk"
+.Ft int
+.Fn Collapse_Chunk "struct disk *disk" "struct chunk *chunk"
+.Ft int
+.Fn Create_Chunk "struct disk *disk" "u_long offset" "u_long size" "chunk_e type" "int subtype" "u_long flags"
+.Ft void
+.Fn All_FreeBSD "struct disk *d" "int force_all"
+.Ft char *
+.Fn CheckRules "struct disk *"
+.Ft char **
+.Fn Disk_Names "void"
+.Ft void
+.Fn Set_Boot_Mgr "struct disk *d" "const u_char *bootmgr"
+.Ft void
+.Fn Set_Boot_Blocks "struct disk *d" "const u_char *boot1" "const u_char *boot2"
+.Ft int
+.Fn Write_Disk "struct disk *d"
+.Ft int
+.Fn Cyl_Aligned "struct disk *d" "u_long offset"
+.Ft u_long
+.Fn Next_Cyl_Aligned "struct disk *d" "u_long offset"
+.Ft u_long
+.Fn Prev_Cyl_Aligned "struct disk *d" "u_long offset"
+.Ft int
+.Fn Track_Aligned "struct disk *d" "u_long offset"
+.Ft u_long
+.Fn Next_Track_Aligned "struct disk *d" "u_long offset"
+.Ft u_long
+.Fn Prev_Track_Aligned "struct disk *d" "u_long offset"
+.Ft struct chunk *
+.Fn Create_Chunk_DWIM "struct disk *d" "struct chunk *parent" "u_long size" "chunk_e type" "int subtype" "u_long flags"
+.Ft int
+.Fn MakeDev "struct chunk *c" "const char *path"
+.Ft int
+.Fn MakeDevDisk "struct disk *d" "const char *path"
+.Ft char *
+.Fn ShowChunkFlags "struct chunk *c"
+.Ft char *
+.Fn ChunkCanBeRoot "struct chunk *c"
+.Sh DESCRIPTION
+.Nm Libdisk
+provides an interface to the low-level disk slice and partition labels.
+Most functions operate with arguments of the types
+.Ql struct disk ,
+or
+.Ql struct chunk .
+.Pp
+While both types are mostly opaque to the programmer, the internal
+structure is mentioned below for the sake of completeness.
+.Bd -literal -offset indent
+struct disk {
+ char *name;
+ u_long flags;
+ u_long bios_cyl;
+ u_long bios_hd;
+ u_long bios_sect;
+ u_char *bootmgr;
+ u_char *boot1;
+ u_char *boot2;
+ struct chunk *chunks;
+};
+.Ed
+The only flag value by now is
+.Ql DISK_ON_TRACK ,
+meaning that this disk is handled by the On-Track Disk Manager.
+.Pp
+.Bd -literal -offset indent
+struct chunk {
+ struct chunk *next;
+ struct chunk *part;
+ struct disk *disk;
+ long offset;
+ u_long size;
+ u_long end;
+ char *name;
+ char *oname;
+ chunk_e type;
+ int subtype;
+ u_long flags;
+ void (*private_free)(void*);
+ void *(*private_clone)(void*);
+ void *private_data;
+};
+.Ed
+The
+.Ql type
+field can be one of the following values:
+.Ql whole, unknown, fat, freebsd, extended, part, unused .
+.Pp
+These are the valid
+.Ql flag
+values for a
+.Ql struct chunk .
+.Bl -tag -offset indent -width CHUNK_BSD_COMPATXX
+.It CHUNK_PAST_1024
+This chunk cannot be booted from because it extends past cylinder 1024.
+.It CHUNK_BSD_COMPAT
+This chunk is in the BSD-compatibility, and has a short name too, i.e.
+.Ql wd0s4f -> wd0f .
+.It CHUNK_ALIGN
+This chunk should be aligned.
+.It CHUNK_IS_ROOT
+This
+.Ql part
+is a rootfs, allocate partition
+.Sq a .
+.It CHUNK_ACTIVE
+This is the active slice in the MBR.
+.It CHUNK_FORCE_ALL
+Force a dedicated disk for
+.Fx ,
+bypassing all BIOS geometry considerations.
+.El
+.Pp
+The
+.Ql private_data ,
+.Ql private_free ,
+and
+.Ql private_clone
+fields are for data private to the application, and the management
+thereof. If the functions are not provided, no storage management is
+done, cloning will just copy the pointer and freeing will just forget
+it.
+.Pp
+.Fn Open_Disk
+will open the named disk, and return populated tree.
+.Pp
+.Fn Clone_Disk
+clones a copy of a tree. Useful for
+.Dq Undo
+functionality.
+.Pp
+.Fn Free_Disk
+frees a tree made with
+.Fn Open_Disk
+or
+.Fn Clone_Disk .
+.Pp
+.Fn Debug_Disk
+prints the content of the tree to stdout.
+.Pp
+.Fn Set_Bios_Geom
+sets the geometry the bios uses.
+.Pp
+.Fn Delete_Chunk
+frees a chunk of disk_space.
+.Pp
+.Fn Collapse_Disk
+and
+.Fn Collapse_Chunk
+are experimental, do not use.
+.Pp
+.Fn Create_Chunk
+creates a chunk with the specified parameters.
+.Pp
+.Fn All_FreeBSD
+makes one FreeBSD chunk covering the entire disk; if
+.Ql force_all
+is set, bypass all BIOS geometry considerations.
+.Pp
+.Fn CheckRules
+returns
+.Ql char*
+to warnings about broken design rules in this disklayout.
+.Pp
+.Fn Disk_Names
+returns
+.Ql char**
+with all disk's names (wd0, wd1 ...). You must free each pointer, as
+well as the array by hand.
+.Pp
+.Fn Set_Boot_Mgr
+sets this boot-manager for use on this disk. Gets written when
+.Fn Write_Disk
+is called.
+.Pp
+.Fn Set_Boot_Blocks
+sets the boot-blocks for use on this disk. Gets written when
+.Fn Write_Disk
+is called.
+.Pp
+.Fn Write_Disk
+writes all the MBRs, disklabels, bootblocks and boot managers.
+.Pp
+.Fn Cyl_Aligned
+checks if
+.Ql offset
+is aligned on a cylinder according to the BIOS geometry.
+.Pp
+.Fn Next_Cyl_Aligned
+rounds
+.Ql offset
+up to next cylinder according to the BIOS geometry.
+.Pp
+.Fn Prev_Cyl_Aligned
+rounds
+.Ql offset
+down to previous cylinder according to the BIOS geometry.
+.Pp
+.Fn Track_Aligned
+checks if
+.Ql offset
+is aligned on a track according to the BIOS geometry.
+.Pp
+.Fn Next_Track_Aligned
+rounds
+.Ql offset
+up to next track according to the BIOS geometry.
+.Pp
+.Fn Prev_Track_Aligned
+checks if
+.Ql offset
+is aligned on a track according to the BIOS geometry.
+.Pp
+.Fn Create_Chunk_DWIM
+creates a partition inside the given parent of the given size, and
+returns a pointer to it. The first unused chunk big enough is used.
+.Pp
+.Fn MakeDev
+makes the device nodes for this chunk.
+.Pp
+.Fn MakeDevDisk
+makes the device nodes for all chunks on this disk.
+.Pp
+.Fn ShowChunkFlags
+returns a string to show flags.
+.Pp
+.Fn ChunkCanBeRoot
+returns NULL if chunk can be
+.Pp
+Chunk name strings can be accessed directly using the external array
+.Va chunk_n .
+.Pp
+.Fn slice_type_name
+returns the name strings associated with the specified
+.Ql type .
+.Ql subtype .
+If
+.Fn slice_type_name
+returns "unknown" for slices it isn't familiar with.
+.Ql / .
+.Sh AUTHORS
+.Nm Libdisk
+has been written by
+.An Poul-Henning Kamp .
+.Pp
+This man page by
+.ie t J\(:org Wunsch.
+.el Joerg Wunsch.
diff --git a/lib/libdisk/libdisk.h b/lib/libdisk/libdisk.h
new file mode 100644
index 0000000..bf9eff1
--- /dev/null
+++ b/lib/libdisk/libdisk.h
@@ -0,0 +1,325 @@
+/*
+* ----------------------------------------------------------------------------
+* "THE BEER-WARE LICENSE" (Revision 42):
+* <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+* can do whatever you want with this stuff. If we meet some day, and you think
+* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+* ----------------------------------------------------------------------------
+*
+* $FreeBSD$
+*
+*/
+
+#define MAX_NO_DISKS 20
+/* Max # of disks Disk_Names() will return */
+
+typedef enum {
+ whole,
+ unknown,
+ fat,
+ freebsd,
+ extended,
+ part,
+ unused
+} chunk_e;
+
+__BEGIN_DECLS
+struct disk {
+ char *name;
+ u_long flags;
+# define DISK_ON_TRACK 1
+ u_long bios_cyl;
+ u_long bios_hd;
+ u_long bios_sect;
+ u_char *bootmgr;
+ u_char *boot1;
+#if defined(__i386__) /* the alpha only has one boot program */
+ u_char *boot2;
+#endif
+ struct chunk *chunks;
+};
+
+struct chunk {
+ struct chunk *next;
+ struct chunk *part;
+ struct disk *disk;
+ long offset;
+ u_long size;
+ u_long end;
+ char *name;
+ char *oname;
+ /* Used during Fixup_Names() to avoid renaming more than
+ * absolutely needed.
+ */
+ chunk_e type;
+ int subtype;
+ u_long flags;
+# define CHUNK_PAST_1024 1
+ /* this chunk cannot be booted from because it
+ * extends past cylinder 1024
+ */
+# define CHUNK_BSD_COMPAT 2
+ /* this chunk is in the BSD-compatibility, and has a
+ * short name too, ie wd0s4f -> wd0f
+ */
+# define CHUNK_ALIGN 8
+ /* This chunk should be aligned */
+# define CHUNK_IS_ROOT 16
+ /* This 'part' is a rootfs, allocate 'a' */
+# define CHUNK_ACTIVE 32
+ /* This is the active slice in the MBR */
+# define CHUNK_FORCE_ALL 64
+ /* Force a dedicated disk for FreeBSD, bypassing
+ * all BIOS geometry considerations
+ */
+
+ void (*private_free)(void*);
+ void *(*private_clone)(void*);
+ void *private_data;
+ /* For data private to the application, and the management
+ * thereof. If the functions are not provided, no storage
+ * management is done, Cloning will just copy the pointer
+ * and freeing will just forget it.
+ */
+};
+
+extern const char *chunk_n[];
+
+const char *
+slice_type_name( int type, int subtype );
+/* "chunk_n" for subtypes too
+ */
+
+struct disk *
+Open_Disk(const char *devname);
+/* Will open the named disk, and return populated tree.
+ */
+
+struct disk *
+Clone_Disk(struct disk *disk);
+/* Clone a copy of a tree. Useful for "Undo" functionality
+ */
+
+void
+Free_Disk(struct disk *disk);
+/* Free a tree made with Open_Disk() or Clone_Disk()
+ */
+
+void
+Debug_Disk(struct disk *disk);
+/* Print the content of the tree to stdout
+ */
+
+void
+Set_Bios_Geom(struct disk *disk, u_long cyl, u_long heads, u_long sects);
+/* Set the geometry the bios uses.
+ */
+
+void
+Sanitize_Bios_Geom(struct disk *disk);
+/* Set the bios geometry to something sane
+ */
+
+int
+Delete_Chunk(struct disk *disk, struct chunk *);
+/* Free a chunk of disk_space
+ */
+
+void
+Collapse_Disk(struct disk *disk);
+/* Experimental, do not use.
+ */
+int
+Collapse_Chunk(struct disk *disk, struct chunk *chunk);
+/* Experimental, do not use.
+ */
+
+int
+Create_Chunk(struct disk *disk, u_long offset, u_long size, chunk_e type,
+ int subtype, u_long flags);
+/* Create a chunk with the specified paramters
+ */
+
+void
+All_FreeBSD(struct disk *d, int force_all);
+/* Make one FreeBSD chunk covering the entire disk;
+ * if force_all is set, bypass all BIOS geometry
+ * considerations.
+ */
+
+char *
+CheckRules(struct disk *);
+/* Return char* to warnings about broken design rules in this disklayout
+ */
+
+char **
+Disk_Names();
+/* Return char** with all disk's names (wd0, wd1 ...). You must free
+ * each pointer, as well as the array by hand
+ */
+
+void
+Set_Boot_Mgr(struct disk *d, const u_char *bootmgr);
+/* Use this boot-manager on this disk. Gets written when Write_Disk()
+ * is called
+ */
+
+void
+Set_Boot_Blocks(struct disk *d, const u_char *_boot1, const u_char *_boot2);
+/* Use these boot-blocks on this disk. Gets written when Write_Disk()
+ * is called
+ */
+
+int
+Write_Disk(struct disk *d);
+/* Write all the MBRs, disklabels, bootblocks and boot managers
+ */
+
+int
+Cyl_Aligned(struct disk *d, u_long offset);
+/* Check if offset is aligned on a cylinder according to the
+ * bios geometry
+ */
+
+u_long
+Next_Cyl_Aligned(struct disk *d, u_long offset);
+/* Round offset up to next cylinder according to the bios-geometry
+ */
+
+u_long
+Prev_Cyl_Aligned(struct disk *d, u_long offset);
+/* Round offset down to previous cylinder according to the bios-
+ * geometry
+ */
+
+int
+Track_Aligned(struct disk *d, u_long offset);
+/* Check if offset is aligned on a track according to the
+ * bios geometry
+ */
+
+u_long
+Next_Track_Aligned(struct disk *d, u_long offset);
+/* Round offset up to next track according to the bios-geometry
+ */
+
+u_long
+Prev_Track_Aligned(struct disk *d, u_long offset);
+/* Check if offset is aligned on a track according to the
+ * bios geometry
+ */
+
+struct chunk *
+Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size,
+ chunk_e type, int subtype, u_long flags);
+/* This one creates a partition inside the given parent of the given
+ * size, and returns a pointer to it. The first unused chunk big
+ * enough is used.
+ */
+
+int
+MakeDev(struct chunk *c, const char *path);
+
+int
+MakeDevDisk(struct disk *d, const char *path);
+/* Make device nodes for all chunks on this disk */
+
+char *
+ShowChunkFlags(struct chunk *c);
+/* Return string to show flags. */
+
+char *
+ChunkCanBeRoot(struct chunk *c);
+/* Return NULL if chunk can be /, explanation otherwise */
+
+/*
+ * Implementation details >>> DO NOT USE <<<
+ */
+
+void Debug_Chunk(struct chunk *);
+void Free_Chunk(struct chunk *);
+struct chunk * Clone_Chunk(struct chunk *);
+int Add_Chunk(struct disk *, long, u_long, const char *, chunk_e, int, u_long);
+void Bios_Limit_Chunk(struct chunk *, u_long);
+void * read_block(int, daddr_t);
+void write_block(int fd, daddr_t block, void *foo);
+struct disklabel * read_disklabel(int, daddr_t);
+u_short dkcksum(struct disklabel *);
+struct chunk * Find_Mother_Chunk(struct chunk *, u_long, u_long, chunk_e);
+struct disk * Int_Open_Disk(const char *name, u_long size);
+void Fixup_Names(struct disk *);
+__END_DECLS
+
+#define dprintf printf
+
+/* TODO
+ *
+ * Need a error string mechanism from the functions instead of warn()
+ *
+ * Make sure only FreeBSD start at offset==0
+ *
+ * Collapse must align.
+ *
+ * Make Write_Disk(struct disk*)
+ *
+ * Consider booting from OnTrack'ed disks.
+ *
+ * Get Bios-geom, ST506 & OnTrack from driver (or otherwise)
+ *
+ * Make Create_DWIM().
+ *
+ * Make Is_Unchanged(struct disk *d1, struct chunk *c1)
+ *
+ * don't rename slices unless we have to
+ *
+ *Sample output from tst01:
+ *
+ * Debug_Disk(wd0) flags=0 bios_geom=0/0/0
+ * >> 0x3d040 0 1411200 1411199 wd0 0 whole 0 0
+ * >>>> 0x3d080 0 960120 960119 wd0s1 3 freebsd 0 8
+ * >>>>>> 0x3d100 0 40960 40959 wd0s1a 5 part 0 0
+ * >>>>>> 0x3d180 40960 131072 172031 wd0s1b 5 part 0 0
+ * >>>>>> 0x3d1c0 172032 409600 581631 wd0s1e 5 part 0 0
+ * >>>>>> 0x3d200 581632 378488 960119 wd0s1f 5 part 0 0
+ * >>>> 0x3d140 960120 5670 965789 wd0s2 4 extended 0 8
+ * >>>>>> 0x3d2c0 960120 63 960182 - 6 unused 0 0
+ * >>>>>> 0x3d0c0 960183 5607 965789 wd0s5 2 fat 0 8
+ * >>>> 0x3d280 965790 1890 967679 wd0s3 1 foo -2 8
+ * >>>> 0x3d300 967680 443520 1411199 wd0s4 3 freebsd 0 8
+ * >>>>>> 0x3d340 967680 443520 1411199 wd0s4a 5 part 0 0
+ *
+ * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+ * level chunkptr start size end name type subtype flags
+ *
+ * Underlying data structure:
+ *
+ * Legend:
+ * <struct chunk> --> part
+ * |
+ * v next
+ *
+ * <wd0> --> <wd0s1> --> <wd0s1a>
+ * | |
+ * | v
+ * | <wd0s1b>
+ * | |
+ * | v
+ * | <wd0s1e>
+ * | |
+ * | v
+ * | <wd0s1f>
+ * |
+ * v
+ * <wd0s2> --> <unused>
+ * | |
+ * | v
+ * | <wd0s5>
+ * |
+ * v
+ * <wd0s3>
+ * |
+ * v
+ * <wd0s4> --> <wd0s4a>
+ *
+ *
+ */
diff --git a/lib/libdisk/rules.c b/lib/libdisk/rules.c
new file mode 100644
index 0000000..fcc3d3b
--- /dev/null
+++ b/lib/libdisk/rules.c
@@ -0,0 +1,285 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/diskslice.h>
+#include <sys/disklabel.h>
+#include <err.h>
+#include "libdisk.h"
+
+int
+Track_Aligned(struct disk *d, u_long offset)
+{
+ if (!d->bios_sect)
+ return 1;
+ if (offset % d->bios_sect)
+ return 0;
+ return 1;
+}
+
+u_long
+Prev_Track_Aligned(struct disk *d, u_long offset)
+{
+ if (!d->bios_sect)
+ return offset;
+ return (offset / d->bios_sect) * d->bios_sect;
+}
+
+u_long
+Next_Track_Aligned(struct disk *d, u_long offset)
+{
+ if (!d->bios_sect)
+ return offset;
+ return Prev_Track_Aligned(d,offset + d->bios_sect-1);
+}
+
+int
+Cyl_Aligned(struct disk *d, u_long offset)
+{
+ if (!d->bios_sect || !d->bios_hd)
+ return 1;
+ if (offset % (d->bios_sect * d->bios_hd))
+ return 0;
+ return 1;
+}
+
+u_long
+Prev_Cyl_Aligned(struct disk *d, u_long offset)
+{
+ if (!d->bios_sect || !d->bios_hd)
+ return offset;
+ return (offset / (d->bios_sect*d->bios_hd)) * d->bios_sect * d->bios_hd;
+}
+
+u_long
+Next_Cyl_Aligned(struct disk *d, u_long offset)
+{
+ if (!d->bios_sect || !d->bios_hd)
+ return offset;
+ return Prev_Cyl_Aligned(d,offset + (d->bios_sect * d->bios_hd)-1);
+}
+
+/*
+ * Rule#0:
+ * Chunks of type 'whole' can have max NDOSPART children.
+ * Only one of them can have the "active" flag
+ */
+void
+Rule_000(struct disk *d, struct chunk *c, char *msg)
+{
+ int i=0,j=0;
+ struct chunk *c1;
+
+ if (c->type != whole)
+ return;
+ for (c1=c->part; c1; c1=c1->next) {
+ if (c1->type != unused) continue;
+ if (c1->flags & CHUNK_ACTIVE)
+ j++;
+ i++;
+ }
+ if (i > NDOSPART)
+ sprintf(msg+strlen(msg),
+ "%d is too many children of the 'whole' chunk. Max is %d\n",
+ i, NDOSPART);
+ if (j > 1)
+ sprintf(msg+strlen(msg),
+ "Too many active children of 'whole'");
+}
+
+/*
+ * Rule#1:
+ * All children of 'whole' and 'extended' must be track-aligned.
+ * Exception: the end can be unaligned if it matches the end of 'whole'
+ */
+void
+Rule_001(struct disk *d, struct chunk *c, char *msg)
+{
+ int i;
+ struct chunk *c1;
+
+ if (c->type != whole && c->type != extended)
+ return;
+ for (i=0, c1=c->part; c1; c1=c1->next) {
+ if (c1->type == unused) continue;
+ c1->flags |= CHUNK_ALIGN;
+ if (!Track_Aligned(d,c1->offset))
+ sprintf(msg+strlen(msg),
+ "chunk '%s' [%ld..%ld] does not start on a track boundary\n",
+ c1->name,c1->offset,c1->end);
+ if ((c->type == whole || c->end == c1->end)
+ || Cyl_Aligned(d,c1->end+1))
+ ;
+ else
+ sprintf(msg+strlen(msg),
+ "chunk '%s' [%ld..%ld] does not end on a cylinder boundary\n",
+ c1->name,c1->offset,c1->end);
+ }
+}
+
+/*
+ * Rule#2:
+ * Max one 'fat' as child of 'whole'
+ */
+void
+Rule_002(struct disk *d, struct chunk *c, char *msg)
+{
+ int i;
+ struct chunk *c1;
+
+ if (c->type != whole)
+ return;
+ for (i=0, c1=c->part; c1; c1=c1->next) {
+ if (c1->type != fat)
+ continue;
+ i++;
+ }
+ if (i > 1) {
+ sprintf(msg+strlen(msg),
+ "Max one 'fat' allowed as child of 'whole'\n");
+ }
+}
+
+/*
+ * Rule#3:
+ * Max one extended as child of 'whole'
+ */
+void
+Rule_003(struct disk *d, struct chunk *c, char *msg)
+{
+ int i;
+ struct chunk *c1;
+
+ if (c->type != whole)
+ return;
+ for (i=0, c1=c->part; c1; c1=c1->next) {
+ if (c1->type != extended)
+ continue;
+ i++;
+ }
+ if (i > 1) {
+ sprintf(msg+strlen(msg),
+ "Max one 'extended' allowed as child of 'whole'\n");
+ }
+}
+
+/*
+ * Rule#4:
+ * Max seven 'part' as children of 'freebsd'
+ * Max one CHUNK_IS_ROOT child per 'freebsd'
+ * If Bad144, space for table must exist.
+ * If Bad144 & root, bad144 table must be inside 1024
+ */
+void
+Rule_004(struct disk *d, struct chunk *c, char *msg)
+{
+ int i=0,k=0;
+ struct chunk *c1;
+
+ if (c->type != freebsd)
+ return;
+
+ for (c1=c->part; c1; c1=c1->next) {
+ if (c1->type != part)
+ continue;
+ if (c1->flags & CHUNK_IS_ROOT) {
+ k++;
+ if (c1->flags & CHUNK_PAST_1024)
+ sprintf(msg+strlen(msg),
+ "Root filesystem extends past cylinder 1024, and cannot be booted from\n");
+ }
+ i++;
+ }
+ if (i > 7) {
+ sprintf(msg+strlen(msg),
+ "Max seven partitions per freebsd slice\n");
+ }
+ if (k > 1) {
+ sprintf(msg+strlen(msg),
+ "Max one root partition child per freebsd slice\n");
+ }
+}
+
+void
+Check_Chunk(struct disk *d, struct chunk *c, char *msg)
+{
+ Rule_000(d,c,msg);
+ Rule_001(d,c,msg);
+ Rule_002(d,c,msg);
+ Rule_003(d,c,msg);
+ Rule_004(d,c,msg);
+ if (c->part)
+ Check_Chunk(d,c->part,msg);
+ if (c->next)
+ Check_Chunk(d,c->next,msg);
+
+ if (c->end >= 1024*d->bios_hd*d->bios_sect)
+ c->flags |= CHUNK_PAST_1024;
+ else
+ c->flags &= ~CHUNK_PAST_1024;
+}
+
+char *
+CheckRules(struct disk *d)
+{
+ char msg[BUFSIZ];
+
+ *msg = '\0';
+ Check_Chunk(d,d->chunks,msg);
+ if (*msg)
+ return strdup(msg);
+ return 0;
+}
+
+char *
+ChunkCanBeRoot(struct chunk *c)
+{
+ struct chunk *c1;
+ struct disk *d = c->disk;
+ char msg[BUFSIZ];
+
+ *msg = '\0';
+ if (c->flags & CHUNK_PAST_1024) {
+ strcat(msg,
+"The root partition must end before cylinder 1024 seen from\n");
+ strcat(msg,
+"the BIOS' point of view, or it cannot be booted from.\n");
+ return strdup(msg);
+ }
+ for (c1=d->chunks->part;;) {
+ for (; c1; c1=c1->next)
+ if (c1->offset <= c->offset && c1->end >= c->end)
+ break;
+ if (!c1) {
+ strcat(msg,
+"Internal trouble, cannot find this chunk in the chunk-tree\n");
+ return strdup(msg);
+ }
+ if (c1->type == freebsd)
+ break;
+ c1 = c1->part;
+ }
+
+ if (c1->type != freebsd) {
+ strcat(msg,
+"The root partition must be in a FreeBSD slice, otherwise\n");
+ strcat(msg,
+"the kernel cannot be booted from it\n");
+ return strdup(msg);
+ }
+
+ return NULL;
+}
diff --git a/lib/libdisk/tst01.c b/lib/libdisk/tst01.c
new file mode 100644
index 0000000..e8c34d9
--- /dev/null
+++ b/lib/libdisk/tst01.c
@@ -0,0 +1,298 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <err.h>
+#ifdef READLINE
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif
+#include <sys/types.h>
+#include "libdisk.h"
+
+u_char mbr[] = {
+250,51,192,142,208,188,0,124,139,244,80,7,80,31,251,252,191,0,6,185,0,1,
+242,165,234,29,6,0,0,190,190,7,179,4,128,60,128,116,14,128,60,0,117,28,
+131,198,16,254,203,117,239,205,24,139,20,139,76,2,139,238,131,198,16,254,
+203,116,26,128,60,0,116,244,190,139,6,172,60,0,116,11,86,187,7,0,180,14,
+205,16,94,235,240,235,254,191,5,0,187,0,124,184,1,2,87,205,19,95,115,12,
+51,192,205,19,79,117,237,190,163,6,235,211,190,194,6,191,254,125,129,61,
+85,170,117,199,139,245,234,0,124,0,0,73,110,118,97,108,105,100,32,112,97,
+114,116,105,116,105,111,110,32,116,97,98,108,101,0,69,114,114,111,114,32,
+108,111,97,100,105,110,103,32,111,112,101,114,97,116,105,110,103,32,115,
+121,115,116,101,109,0,77,105,115,115,105,110,103,32,111,112,101,114,97,
+116,105,110,103,32,115,121,115,116,101,109,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,
+1,1,0,4,15,63,60,63,0,0,0,241,239,0,0,0,0,1,61,5,15,63,243,48,240,0,0,144,
+208,2,0,0,0,1,244,165,15,63,170,192,192,3,0,144,208,2,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,85,170
+};
+
+u_char bteasy17[] = {
+51,192,142,192,142,216,142,208,188,0,124,252,139,244,191,0,6,185,0,1,242,
+165,234,96,6,0,0,139,213,88,162,72,7,60,53,116,28,180,16,246,228,5,174,
+4,150,246,68,4,255,116,62,198,4,128,232,218,0,138,116,1,139,76,2,235,8,
+232,207,0,185,1,0,50,209,187,0,124,184,1,2,205,19,114,30,129,191,254,1,
+85,170,117,22,234,0,124,0,0,128,250,129,116,2,178,128,139,234,66,128,242,
+179,136,22,58,7,191,190,7,185,4,0,198,6,45,7,49,50,246,136,45,138,69,4,
+60,0,116,35,60,5,116,31,254,198,190,42,7,232,113,0,190,72,7,70,70,139,28,
+10,255,116,5,50,125,4,117,243,141,183,114,7,232,90,0,131,199,16,254,6,45,
+7,226,203,128,62,117,4,2,116,11,190,59,7,10,246,117,10,205,24,235,172,190,
+42,7,232,57,0,232,54,0,50,228,205,26,139,218,131,195,96,180,1,205,22,180,
+0,117,11,205,26,59,211,114,242,160,72,7,235,10,205,22,138,196,60,28,116,
+243,4,246,60,49,114,214,60,53,119,210,80,190,40,7,187,27,6,83,252,172,80,
+36,127,180,14,205,16,88,168,128,116,242,195,86,184,1,3,187,0,6,185,1,0,
+50,246,205,19,94,198,6,72,7,63,195,13,138,13,10,70,48,32,46,32,46,32,46,
+160,100,105,115,107,32,49,13,10,10,68,101,102,97,117,108,116,58,32,70,63,
+160,0,1,0,4,0,6,3,7,7,10,10,99,14,100,14,101,20,128,20,129,25,130,30,147,
+36,165,39,159,43,117,47,82,47,219,50,64,55,242,61,0,100,111,243,72,80,70,
+211,79,115,178,85,110,105,248,78,111,118,101,108,236,77,105,110,105,248,
+76,105,110,117,248,65,109,111,101,98,225,66,83,196,66,83,68,233,80,67,73,
+216,67,80,205,86,101,110,105,248,68,111,115,115,101,227,63,191,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,85,170
+};
+
+int
+scan_block(int fd, daddr_t block)
+{
+ u_char foo[512];
+
+ if (-1 == lseek(fd, (off_t)block * 512, SEEK_SET))
+ err(1, "lseek");
+ if (512 != read(fd,foo, 512))
+ return 1;
+ return 0;
+}
+
+void
+Scan_Disk(struct disk *d)
+{
+ char device[64];
+ u_long l;
+ int i,j,fd;
+
+ strcpy(device,"/dev/r");
+ strcat(device,d->name);
+
+ fd = open(device,O_RDWR);
+ if (fd < 0) {
+ warn("open(%s) failed",device);
+ return;
+ }
+ for(i=-1,l=0;;l++) {
+ j = scan_block(fd,l);
+ if (j != i) {
+ if (i == -1) {
+ printf("%c: %lu.",j ? 'B' : 'G', l);
+ fflush(stdout);
+ } else if (i == 0) {
+ printf(".%lu\nB: %lu.",l-1,l);
+ fflush(stdout);
+ } else {
+ printf(".%lu\nG: %lu.",l-1,l);
+ fflush(stdout);
+ }
+ i = j;
+ }
+ }
+ close(fd);
+}
+
+int
+main(int argc, char **argv)
+{
+ struct disk *d,*db;
+ char myprompt[BUFSIZ];
+#ifndef READLINE
+ char input[BUFSIZ];
+#endif
+ char *p,*q=0;
+ char **cp,*cmds[200];
+ int ncmd,i;
+
+ if (argc < 2) {
+ fprintf(stderr,"Usage:\n\t%s diskname\n",argv[0]);
+ exit(1);
+ }
+ d = Open_Disk(argv[1]);
+ if (!d)
+ err(1,"Couldn't open disk %s",argv[1]);
+
+ sprintf(myprompt,"%s %s> ",argv[0],argv[1]);
+ while(1) {
+ printf("--==##==--\n");
+ p = CheckRules(d);
+ Debug_Disk(d);
+ if (p) {
+ printf("%s",p);
+ free(p);
+ }
+#ifdef READLINE
+ if (q)
+ free(q);
+ q = p = readline(myprompt);
+#else
+ printf(myprompt);
+ fflush(stdout);
+ q = p = fgets(input,sizeof(input),stdin);
+#endif
+ if(!p)
+ break;
+ for(cp = cmds; (*cp = strsep(&p, " \t\n")) != NULL;)
+ if (**cp != '\0')
+ cp++;
+ ncmd = cp - cmds;
+ if(!ncmd)
+ continue;
+ if (!strcasecmp(*cmds,"quit")) { break; }
+ if (!strcasecmp(*cmds,"exit")) { break; }
+ if (!strcasecmp(*cmds,"q")) { break; }
+ if (!strcasecmp(*cmds,"x")) { break; }
+ if (!strcasecmp(*cmds,"dwim") && ncmd == 6) {
+ printf("dwim = %p\n",
+ Create_Chunk_DWIM(d,
+ (struct chunk *)strtol(cmds[1],0,0),
+ strtol(cmds[2],0,0),
+ strtol(cmds[3],0,0),
+ strtol(cmds[4],0,0),
+ strtol(cmds[5],0,0)));
+ continue;
+ }
+ if (!strcasecmp(*cmds,"mknod")) {
+ MakeDevDisk(d,"/tmp");
+ continue;
+ }
+ if (!strcasecmp(*cmds,"delete") && ncmd == 2) {
+ printf("delete = %d\n",
+ Delete_Chunk(d,
+ (struct chunk *)strtol(cmds[1],0,0)));
+ continue;
+ }
+ if (!strcasecmp(*cmds,"allfreebsd")) {
+ All_FreeBSD(d, 0);
+ continue;
+ }
+ if (!strcasecmp(*cmds,"dedicate")) {
+ All_FreeBSD(d, 1);
+ continue;
+ }
+ if (!strcasecmp(*cmds,"sanitize")) {
+ Sanitize_Bios_Geom(d);
+ continue;
+ }
+ if (!strcasecmp(*cmds,"bios") && ncmd == 4) {
+ Set_Bios_Geom(d,
+ strtol(cmds[1],0,0),
+ strtol(cmds[2],0,0),
+ strtol(cmds[3],0,0));
+ continue;
+ }
+ if (!strcasecmp(*cmds,"list")) {
+ cp = Disk_Names();
+ printf("Disks:");
+ for(i=0;cp[i];i++) {
+ printf(" %s",cp[i]);
+ free(cp[i]);
+ }
+ free(cp);
+ continue;
+ }
+ if (!strcasecmp(*cmds,"create") && ncmd == 6) {
+
+ printf("Create=%d\n",
+ Create_Chunk(d,
+ strtol(cmds[1],0,0),
+ strtol(cmds[2],0,0),
+ strtol(cmds[3],0,0),
+ strtol(cmds[4],0,0),
+ strtol(cmds[5],0,0)));
+ continue;
+ }
+ if (!strcasecmp(*cmds,"read")) {
+ db = d;
+ if (ncmd > 1)
+ d = Open_Disk(cmds[1]);
+ else
+ d = Open_Disk(argv[1]);
+ if (d)
+ Free_Disk(db);
+ else
+ d = db;
+ continue;
+ }
+ if (!strcasecmp(*cmds,"scan")) {
+ Scan_Disk(d);
+ continue;
+ }
+ if (!strcasecmp(*cmds,"bteasy")) {
+ Set_Boot_Mgr(d,bteasy17);
+ continue;
+ }
+ if (!strcasecmp(*cmds,"mbr")) {
+ Set_Boot_Mgr(d,mbr);
+ continue;
+ }
+#ifndef __alpha__ /* don't think this compiles on i386 either */
+ if (!strcasecmp(*cmds,"boot")) {
+ Set_Boot_Blocks(d,boot1,boot2);
+ continue;
+ }
+#endif
+ if (!strcasecmp(*cmds,"write")) {
+ printf("Write=%d\n",
+ Write_Disk(d));
+ Free_Disk(d);
+ d = Open_Disk(d->name);
+ continue;
+ }
+ if (strcasecmp(*cmds,"help"))
+ printf("\007ERROR\n");
+ printf("CMDS:\n");
+ printf("\tallfreebsd\n");
+ printf("\tdedicate\n");
+ printf("\tbios cyl hd sect\n");
+ printf("\tboot\n");
+ printf("\tbteasy17\n");
+#if 0
+ printf("\tcollapse [pointer]\n");
+#endif
+ printf("\tcreate offset size enum subtype flags\n");
+ printf("\t\tsubtype(part): swap=1, ffs=7\n");
+ printf("\tdelete pointer\n");
+ printf("\tlist\n");
+ printf("\tmbr\n");
+#if 0
+ printf("\tphys cyl hd sect\n");
+#endif
+ printf("\tquit\n");
+ printf("\tread [disk]\n");
+ printf("\tscan\n");
+ printf("\twrite\n");
+ printf("\nENUM:\n\t");
+ for(i=0;chunk_n[i];i++)
+ printf("%d = %s%s",i,chunk_n[i],i == 4 ? "\n\t" : " ");
+ printf("\n");
+
+ }
+ exit (0);
+}
diff --git a/lib/libdisk/write_disk.c b/lib/libdisk/write_disk.c
new file mode 100644
index 0000000..60ddbda
--- /dev/null
+++ b/lib/libdisk/write_disk.c
@@ -0,0 +1,284 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <err.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/disklabel.h>
+#include <sys/diskslice.h>
+#include "libdisk.h"
+
+#define DOSPTYP_EXTENDED 5
+#define BBSIZE 8192
+#define SBSIZE 8192
+#define DEF_RPM 3600
+#define DEF_INTERLEAVE 1
+
+#define WHERE(offset,disk) (disk->flags & DISK_ON_TRACK ? offset + 63 : offset)
+int
+Write_FreeBSD(int fd, struct disk *new, struct disk *old, struct chunk *c1)
+{
+ struct disklabel *dl;
+ struct chunk *c2;
+ int i,j;
+ void *p;
+ u_char buf[BBSIZE];
+#ifdef __alpha__
+ u_long *lp, sum;
+#endif
+
+ for(i=0;i<BBSIZE/512;i++) {
+ p = read_block(fd,WHERE(i + c1->offset,new));
+ memcpy(buf+512*i,p,512);
+ free(p);
+ }
+#if defined(__i386__)
+ if(new->boot1)
+ memcpy(buf,new->boot1,512);
+
+ if(new->boot2)
+ memcpy(buf+512,new->boot2,BBSIZE-512);
+#elif defined(__alpha__)
+ if(new->boot1)
+ memcpy(buf+512,new->boot1,BBSIZE-512);
+#endif
+
+ dl = (struct disklabel *) (buf+512*LABELSECTOR+LABELOFFSET);
+ memset(dl,0,sizeof *dl);
+
+ for(c2=c1->part;c2;c2=c2->next) {
+ if (c2->type == unused) continue;
+ if (!strcmp(c2->name,"X")) continue;
+#ifdef __alpha__
+ j = c2->name[strlen(c2->name) - 1] - 'a';
+#else
+ j = c2->name[strlen(new->name) + 2] - 'a';
+#endif
+ if (j < 0 || j >= MAXPARTITIONS || j == RAW_PART) {
+#ifdef DEBUG
+ warn("Weird parititon letter %c",c2->name[strlen(new->name) + 2]);
+#endif
+ continue;
+ }
+ dl->d_partitions[j].p_size = c2->size;
+ dl->d_partitions[j].p_offset = c2->offset;
+ dl->d_partitions[j].p_fstype = c2->subtype;
+ }
+
+ dl->d_bbsize = BBSIZE;
+ /*
+ * Add in defaults for superblock size, interleave, and rpms
+ */
+ dl->d_sbsize = SBSIZE;
+ dl->d_interleave = DEF_INTERLEAVE;
+ dl->d_rpm = DEF_RPM;
+
+ strcpy(dl->d_typename,c1->name);
+
+ dl->d_secsize = 512;
+ dl->d_secperunit = new->chunks->size;
+ dl->d_ncylinders = new->bios_cyl;
+ dl->d_ntracks = new->bios_hd;
+ dl->d_nsectors = new->bios_sect;
+ dl->d_secpercyl = dl->d_ntracks * dl->d_nsectors;
+
+ dl->d_npartitions = MAXPARTITIONS;
+
+ dl->d_type = new->name[0] == 's' || new->name[0] == 'd' ||
+ new->name[0] == 'o' ? DTYPE_SCSI : DTYPE_ESDI;
+ dl->d_partitions[RAW_PART].p_size = c1->size;
+ dl->d_partitions[RAW_PART].p_offset = c1->offset;
+
+ if(new->flags & DISK_ON_TRACK)
+ for(i=0;i<MAXPARTITIONS;i++)
+ if (dl->d_partitions[i].p_size)
+ dl->d_partitions[i].p_offset += 63;
+ dl->d_magic = DISKMAGIC;
+ dl->d_magic2 = DISKMAGIC;
+ dl->d_checksum = dkcksum(dl);
+
+#ifdef __alpha__
+ /*
+ * Tell SRM where the bootstrap is.
+ */
+ lp = (u_long *)buf;
+ lp[60] = 15;
+ lp[61] = 1;
+ lp[62] = 0;
+
+ /*
+ * Generate the bootblock checksum for the SRM console.
+ */
+ for (lp = (u_long *)buf, i = 0, sum = 0; i < 63; i++)
+ sum += lp[i];
+ lp[63] = sum;
+#endif
+
+ for(i=0;i<BBSIZE/512;i++) {
+ write_block(fd,WHERE(i + c1->offset,new),buf+512*i);
+ }
+
+ return 0;
+}
+
+int
+Write_Extended(int fd, struct disk *new, struct disk *old, struct chunk *c1)
+{
+ return 0;
+}
+
+static void
+Write_Int32(u_int32_t *p, u_int32_t v)
+{
+ u_int8_t *bp = (u_int8_t *)p;
+ bp[0] = (v >> 0) & 0xff;
+ bp[1] = (v >> 8) & 0xff;
+ bp[2] = (v >> 16) & 0xff;
+ bp[3] = (v >> 24) & 0xff;
+}
+
+int
+Write_Disk(struct disk *d1)
+{
+ int fd,i,j;
+ struct disk *old = 0;
+ struct chunk *c1;
+ int ret = 0;
+ char device[64];
+ u_char *mbr;
+ struct dos_partition *dp,work[NDOSPART];
+ int s[4];
+ int one = 1;
+ int zero = 0;
+
+ strcpy(device,"/dev/r");
+ strcat(device,d1->name);
+
+ fd = open(device,O_RDWR);
+ if (fd < 0) {
+#ifdef DEBUG
+ warn("open(%s) failed",device);
+#endif
+ return 1;
+ }
+ ioctl(fd, DIOCWLABEL, &one);
+
+ memset(s,0,sizeof s);
+ mbr = read_block(fd,WHERE(0,d1));
+ dp = (struct dos_partition*) (mbr + DOSPARTOFF);
+ memcpy(work,dp,sizeof work);
+ dp = work;
+ free(mbr);
+ for (c1=d1->chunks->part; c1 ; c1 = c1->next) {
+ if (c1->type == unused) continue;
+ if (!strcmp(c1->name,"X")) continue;
+#ifndef __alpha__
+ j = c1->name[4] - '1';
+ j = c1->name[strlen(d1->name) + 1] - '1';
+ if (j < 0 || j > 3)
+ continue;
+ s[j]++;
+#endif
+ if (c1->type == extended)
+ ret += Write_Extended(fd, d1,old,c1);
+ if (c1->type == freebsd)
+ ret += Write_FreeBSD(fd, d1,old,c1);
+
+#ifndef __alpha__
+ Write_Int32(&dp[j].dp_start, c1->offset);
+ Write_Int32(&dp[j].dp_size, c1->size);
+
+ i = c1->offset;
+ if (i >= 1024*d1->bios_sect*d1->bios_hd) {
+ dp[j].dp_ssect = 0xff;
+ dp[j].dp_shd = 0xff;
+ dp[j].dp_scyl = 0xff;
+ } else {
+ dp[j].dp_ssect = i % d1->bios_sect;
+ i -= dp[j].dp_ssect++;
+ i /= d1->bios_sect;
+ dp[j].dp_shd = i % d1->bios_hd;
+ i -= dp[j].dp_shd;
+ i /= d1->bios_hd;
+ dp[j].dp_scyl = i;
+ i -= dp[j].dp_scyl;
+ dp[j].dp_ssect |= i >> 2;
+ }
+
+#ifdef DEBUG
+ printf("S:%lu = (%x/%x/%x)",
+ c1->offset,dp[j].dp_scyl,dp[j].dp_shd,dp[j].dp_ssect);
+#endif
+
+ i = c1->end;
+ dp[j].dp_esect = i % d1->bios_sect;
+ i -= dp[j].dp_esect++;
+ i /= d1->bios_sect;
+ dp[j].dp_ehd = i % d1->bios_hd;
+ i -= dp[j].dp_ehd;
+ i /= d1->bios_hd;
+ if (i>1023) i = 1023;
+ dp[j].dp_ecyl = i;
+ i -= dp[j].dp_ecyl;
+ dp[j].dp_esect |= i >> 2;
+
+#ifdef DEBUG
+ printf(" E:%lu = (%x/%x/%x)\n",
+ c1->end,dp[j].dp_ecyl,dp[j].dp_ehd,dp[j].dp_esect);
+#endif
+
+ dp[j].dp_typ = c1->subtype;
+ if (c1->flags & CHUNK_ACTIVE)
+ dp[j].dp_flag = 0x80;
+ else
+ dp[j].dp_flag = 0;
+#endif
+ }
+#ifndef __alpha__
+ j = 0;
+ for(i=0;i<NDOSPART;i++) {
+ if (!s[i])
+ memset(dp+i,0,sizeof *dp);
+ if (dp[i].dp_flag)
+ j++;
+ }
+ if (!j)
+ for(i=0;i<NDOSPART;i++)
+ if (dp[i].dp_typ == 0xa5)
+ dp[i].dp_flag = 0x80;
+
+ mbr = read_block(fd,WHERE(0,d1));
+ if (d1->bootmgr)
+ memcpy(mbr,d1->bootmgr,DOSPARTOFF);
+ memcpy(mbr+DOSPARTOFF,dp,sizeof *dp * NDOSPART);
+ mbr[512-2] = 0x55;
+ mbr[512-1] = 0xaa;
+ write_block(fd,WHERE(0,d1),mbr);
+#endif
+
+ i = 1;
+ i = ioctl(fd,DIOCSYNCSLICEINFO,&i);
+#ifdef DEBUG
+ if (i != 0)
+ warn("ioctl(DIOCSYNCSLICEINFO)");
+#endif
+ ioctl(fd, DIOCWLABEL, &zero);
+ close(fd);
+ return 0;
+}
+
diff --git a/lib/libedit/Makefile b/lib/libedit/Makefile
new file mode 100644
index 0000000..af1bb95
--- /dev/null
+++ b/lib/libedit/Makefile
@@ -0,0 +1,70 @@
+# @(#)Makefile 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+LIB= edit
+SHLIB_MAJOR= 3
+SHLIB_MINOR= 0
+
+OSRCS= chared.c common.c el.c emacs.c fcns.c help.c hist.c key.c map.c \
+ parse.c prompt.c read.c refresh.c search.c sig.c term.c tty.c vi.c
+
+DPADD= ${LIBTERMCAP}
+LDADD= -ltermcap
+
+MAN3= editline.3
+MAN5= editrc.5
+
+MLINKS= editline.3 el_init.3 editline.3 el_end.3 editline.3 el_reset.3 \
+ editline.3 el_gets.3 editline.3 el_getc.3 editline.3 el_push.3 \
+ editline.3 el_parse.3 editline.3 el_set.3 editline.3 el_source.3 \
+ editline.3 el_resize.3 editline.3 el_line.3 \
+ editline.3 el_insertstr.3 editline.3 el_deletestr.3 \
+ editline.3 history_init.3 editline.3 history_end.3 \
+ editline.3 history.3 editline.3 el_data_get.3 editline.3 el_data_set.3
+
+# For speed and debugging
+#SRCS= ${OSRCS} tokenizer.c history.c
+# For protection
+SRCS= editline.c tokenizer.c history.c
+
+SRCS+= common.h emacs.h fcns.h help.h vi.h
+
+CLEANFILES+=common.h editline.c emacs.h fcns.c fcns.h help.c help.h vi.h
+CFLAGS+=-I. -I${.CURDIR}
+CFLAGS+=#-DDEBUG_TTY -DDEBUG_KEY -DDEBUG_READ -DDEBUG -DDEBUG_REFRESH
+CFLAGS+=#-DDEBUG_PASTE
+
+AHDR=vi.h emacs.h common.h
+ASRC=${.CURDIR}/vi.c ${.CURDIR}/emacs.c ${.CURDIR}/common.c
+
+vi.h: vi.c makelist
+ sh ${.CURDIR}/makelist -h ${.CURDIR}/vi.c > ${.TARGET}
+
+emacs.h: emacs.c makelist
+ sh ${.CURDIR}/makelist -h ${.CURDIR}/emacs.c > ${.TARGET}
+
+common.h: common.c makelist
+ sh ${.CURDIR}/makelist -h ${.CURDIR}/common.c > ${.TARGET}
+
+fcns.h: ${AHDR} makelist
+ sh ${.CURDIR}/makelist -fh ${AHDR} > ${.TARGET}
+
+fcns.c: ${AHDR} fcns.h makelist
+ sh ${.CURDIR}/makelist -fc ${AHDR} > ${.TARGET}
+
+help.c: ${ASRC} makelist
+ sh ${.CURDIR}/makelist -bc ${ASRC} > ${.TARGET}
+
+help.h: ${ASRC} makelist
+ sh ${.CURDIR}/makelist -bh ${ASRC} > ${.TARGET}
+
+editline.c:
+ sh ${.CURDIR}/makelist -e ${OSRCS} > ${.TARGET}
+
+beforedepend editline.o editline.po editline.So: \
+ vi.h emacs.h common.h fcns.h fcns.c help.h help.c
+
+test: test.o libedit.a ${DPADD} ${LIBTERMCAP}
+ ${CC} ${CFLAGS} ${.ALLSRC} -o ${.TARGET} libedit.a ${LDADD}
+
+.include <bsd.lib.mk>
diff --git a/lib/libedit/TEST/test.c b/lib/libedit/TEST/test.c
new file mode 100644
index 0000000..097055a
--- /dev/null
+++ b/lib/libedit/TEST/test.c
@@ -0,0 +1,241 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1992, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * test.c: A little test program
+ */
+#include "sys.h"
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include "histedit.h"
+#include "tokenizer.h"
+
+static int continuation = 0;
+static EditLine *el = NULL;
+
+static char *
+/*ARGSUSED*/
+prompt(el)
+ EditLine *el;
+{
+ static char a[] = "Edit$";
+ static char b[] = "Edit>";
+ return continuation ? b : a;
+}
+
+static void
+sig(i)
+ int i;
+{
+ (void) fprintf(stderr, "Got signal %d.\n", i);
+ el_reset(el);
+}
+
+static unsigned char
+/*ARGSUSED*/
+complete(el, ch)
+ EditLine *el;
+ int ch;
+{
+ DIR *dd = opendir(".");
+ struct dirent *dp;
+ const char* ptr;
+ const LineInfo *lf = el_line(el);
+ int len;
+
+ /*
+ * Find the last word
+ */
+ for (ptr = lf->cursor - 1; !isspace(*ptr) && ptr > lf->buffer; ptr--)
+ continue;
+ len = lf->cursor - ++ptr;
+
+ for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
+ if (len > strlen(dp->d_name))
+ continue;
+ if (strncmp(dp->d_name, ptr, len) == 0) {
+ closedir(dd);
+ if (el_insertstr(el, &dp->d_name[len]) == -1)
+ return CC_ERROR;
+ else
+ return CC_REFRESH;
+ }
+ }
+
+ closedir(dd);
+ return CC_ERROR;
+}
+
+int
+/*ARGSUSED*/
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int num;
+ const char *buf;
+ Tokenizer *tok;
+ History *hist;
+
+ (void) signal(SIGINT, sig);
+ (void) signal(SIGQUIT, sig);
+ (void) signal(SIGHUP, sig);
+ (void) signal(SIGTERM, sig);
+
+ hist = history_init(); /* Init the builtin history */
+ history(hist, H_EVENT, 100); /* Remember 100 events */
+
+ tok = tok_init(NULL); /* Initialize the tokenizer */
+
+ el = el_init(*argv, stdin, stdout); /* Initialize editline */
+
+ el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */
+ el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */
+ el_set(el, EL_PROMPT, prompt); /* Set the prompt function */
+
+ /* Tell editline to use this history interface */
+ el_set(el, EL_HIST, history, hist);
+
+ /* Add a user-defined function */
+ el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete);
+
+ el_set(el, EL_BIND, "^I", "ed-complete", NULL);/* Bind tab to it */
+
+ /*
+ * Bind j, k in vi command mode to previous and next line, instead
+ * of previous and next history.
+ */
+ el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL);
+ el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL);
+
+ /*
+ * Source the user's defaults file.
+ */
+ el_source(el, NULL);
+
+ while ((buf = el_gets(el, &num)) != NULL && num != 0) {
+ int ac;
+ char **av;
+#ifdef DEBUG
+ (void) fprintf(stderr, "got %d %s", num, buf);
+#endif
+ if (!continuation && num == 1)
+ continue;
+ if (tok_line(tok, buf, &ac, &av) > 0) {
+ history(hist, continuation ? H_ADD : H_ENTER, buf);
+ continuation = 1;
+ continue;
+ }
+ history(hist, continuation ? H_ADD : H_ENTER, buf);
+
+ continuation = 0;
+
+ if (strcmp(av[0], "history") == 0) {
+ const struct HistEvent *he;
+
+ switch (ac) {
+ case 1:
+ for (he = history(hist, H_LAST); he;
+ he = history(hist, H_PREV))
+ (void) fprintf(stdout, "%4d %s", he->num, he->str);
+ break;
+
+ case 2:
+ if (strcmp(av[1], "clear") == 0)
+ history(hist, H_CLEAR);
+ else
+ goto badhist;
+ break;
+
+ case 3:
+ if (strcmp(av[1], "load") == 0)
+ history(hist, H_LOAD, av[2]);
+ else if (strcmp(av[1], "save") == 0)
+ history(hist, H_SAVE, av[2]);
+ break;
+
+ badhist:
+ default:
+ (void) fprintf(stderr, "Bad history arguments\n");
+ break;
+ }
+ }
+ else if (el_parse(el, ac, av) == -1) {
+ switch (fork()) {
+ case 0:
+ execvp(av[0], av);
+ perror(av[0]);
+ _exit(1);
+ /*NOTREACHED*/
+ break;
+
+ case -1:
+ perror("fork");
+ break;
+
+ default:
+ if (wait(&num) == -1)
+ perror("wait");
+ (void) fprintf(stderr, "Exit %x\n", num);
+ break;
+ }
+ }
+ tok_reset(tok);
+ }
+
+ el_end(el);
+ tok_end(tok);
+ history_end(hist);
+
+ return 0;
+}
diff --git a/lib/libedit/chared.c b/lib/libedit/chared.c
new file mode 100644
index 0000000..ed6a7c7
--- /dev/null
+++ b/lib/libedit/chared.c
@@ -0,0 +1,654 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * chared.c: Character editor utilities
+ */
+#include "sys.h"
+
+#include <stdlib.h>
+#include "el.h"
+
+/* cv_undo():
+ * Handle state for the vi undo command
+ */
+protected void
+cv_undo(el, action, size, ptr)
+ EditLine *el;
+ int action, size;
+ char *ptr;
+{
+ c_undo_t *vu = &el->el_chared.c_undo;
+ vu->action = action;
+ vu->ptr = ptr;
+ vu->isize = size;
+ (void) memcpy(vu->buf, vu->ptr, size);
+#ifdef DEBUG_UNDO
+ (void) fprintf(el->el_errfile, "Undo buffer \"%s\" size = +%d -%d\n",
+ vu->ptr, vu->isize, vu->dsize);
+#endif
+}
+
+
+/* c_insert():
+ * Insert num characters
+ */
+protected void
+c_insert(el, num)
+ EditLine *el;
+ int num;
+{
+ char *cp;
+
+ if (el->el_line.lastchar + num >= el->el_line.limit)
+ return; /* can't go past end of buffer */
+
+ if (el->el_line.cursor < el->el_line.lastchar) {
+ /* if I must move chars */
+ for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
+ cp[num] = *cp;
+ }
+ el->el_line.lastchar += num;
+} /* end c_insert */
+
+
+/* c_delafter():
+ * Delete num characters after the cursor
+ */
+protected void
+c_delafter(el, num)
+ EditLine *el;
+ int num;
+{
+
+ if (el->el_line.cursor + num > el->el_line.lastchar)
+ num = el->el_line.lastchar - el->el_line.cursor;
+
+ if (num > 0) {
+ char *cp;
+
+ if (el->el_map.current != el->el_map.emacs)
+ cv_undo(el, INSERT, num, el->el_line.cursor);
+
+ for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
+ *cp = cp[num];
+
+ el->el_line.lastchar -= num;
+ }
+}
+
+
+/* c_delbefore():
+ * Delete num characters before the cursor
+ */
+protected void
+c_delbefore(el, num)
+ EditLine *el;
+ int num;
+{
+
+ if (el->el_line.cursor - num < el->el_line.buffer)
+ num = el->el_line.cursor - el->el_line.buffer;
+
+ if (num > 0) {
+ char *cp;
+
+ if (el->el_map.current != el->el_map.emacs)
+ cv_undo(el, INSERT, num, el->el_line.cursor - num);
+
+ for (cp = el->el_line.cursor - num; cp <= el->el_line.lastchar; cp++)
+ *cp = cp[num];
+
+ el->el_line.lastchar -= num;
+ }
+}
+
+
+/* ce__isword():
+ * Return if p is part of a word according to emacs
+ */
+protected int
+ce__isword(p)
+ int p;
+{
+ return isalpha((unsigned char) p) || isdigit((unsigned char) p) || strchr("*?_-.[]~=", p) != NULL;
+}
+
+
+/* cv__isword():
+ * Return type of word for p according to vi
+ */
+protected int
+cv__isword(p)
+ int p;
+{
+ if (isspace((unsigned char) p))
+ return 0;
+ if ((unsigned char) p == '_' || isalnum((unsigned char) p))
+ return 1;
+ return 2;
+}
+
+
+/* c___isword():
+ * Return if p is part of a space-delimited word (!isspace)
+ */
+protected int
+c___isword(p)
+ int p;
+{
+ return !isspace((unsigned char) p);
+}
+
+
+/* c__prev_word():
+ * Find the previous word
+ */
+protected char *
+c__prev_word(p, low, n, wtest)
+ register char *p, *low;
+ register int n;
+ int (*wtest) __P((int));
+{
+ p--;
+
+ while (n--) {
+ while ((p >= low) && !(*wtest)((unsigned char) *p))
+ p--;
+ while ((p >= low) && (*wtest)((unsigned char) *p))
+ p--;
+ }
+
+ /* cp now points to one character before the word */
+ p++;
+ if (p < low)
+ p = low;
+ /* cp now points where we want it */
+ return p;
+}
+
+
+/* c__next_word():
+ * Find the next word
+ */
+protected char *
+c__next_word(p, high, n, wtest)
+ register char *p, *high;
+ register int n;
+ int (*wtest) __P((int));
+{
+ while (n--) {
+ while ((p < high) && !(*wtest)((unsigned char) *p))
+ p++;
+ while ((p < high) && (*wtest)((unsigned char) *p))
+ p++;
+ }
+ if (p > high)
+ p = high;
+ /* p now points where we want it */
+ return p;
+}
+
+/* cv_next_word():
+ * Find the next word vi style
+ */
+protected char *
+cv_next_word(el, p, high, n, wtest)
+ EditLine *el;
+ register char *p, *high;
+ register int n;
+ int (*wtest) __P((int));
+{
+ int test;
+
+ while (n--) {
+ test = (*wtest)((unsigned char) *p);
+ while ((p < high) && (*wtest)((unsigned char) *p) == test)
+ p++;
+ /*
+ * vi historically deletes with cw only the word preserving the
+ * trailing whitespace! This is not what 'w' does..
+ */
+ if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
+ while ((p < high) && isspace((unsigned char) *p))
+ p++;
+ }
+
+ /* p now points where we want it */
+ if (p > high)
+ return high;
+ else
+ return p;
+}
+
+
+/* cv_prev_word():
+ * Find the previous word vi style
+ */
+protected char *
+cv_prev_word(el, p, low, n, wtest)
+ EditLine *el;
+ register char *p, *low;
+ register int n;
+ int (*wtest) __P((int));
+{
+ int test;
+
+ while (n--) {
+ p--;
+ /*
+ * vi historically deletes with cb only the word preserving the
+ * leading whitespace! This is not what 'b' does..
+ */
+ if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
+ while ((p > low) && isspace((unsigned char) *p))
+ p--;
+ test = (*wtest)((unsigned char) *p);
+ while ((p >= low) && (*wtest)((unsigned char) *p) == test)
+ p--;
+ p++;
+ while (isspace((unsigned char) *p))
+ p++;
+ }
+
+ /* p now points where we want it */
+ if (p < low)
+ return low;
+ else
+ return p;
+}
+
+
+#ifdef notdef
+/* c__number():
+ * Ignore character p points to, return number appearing after that.
+ * A '$' by itself means a big number; "$-" is for negative; '^' means 1.
+ * Return p pointing to last char used.
+ */
+protected char *
+c__number(p, num, dval)
+ char *p; /* character position */
+ int *num; /* Return value */
+ int dval; /* dval is the number to subtract from like $-3 */
+{
+ register int i;
+ register int sign = 1;
+
+ if (*++p == '^') {
+ *num = 1;
+ return p;
+ }
+ if (*p == '$') {
+ if (*++p != '-') {
+ *num = 0x7fffffff; /* Handle $ */
+ return --p;
+ }
+ sign = -1; /* Handle $- */
+ ++p;
+ }
+ for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
+ continue;
+ *num = (sign < 0 ? dval - i : i);
+ return --p;
+}
+#endif
+
+/* cv_delfini():
+ * Finish vi delete action
+ */
+protected void
+cv_delfini(el)
+ EditLine *el;
+{
+ register int size;
+ int oaction;
+
+ if (el->el_chared.c_vcmd.action & INSERT)
+ el->el_map.current = el->el_map.key;
+
+ oaction = el->el_chared.c_vcmd.action;
+ el->el_chared.c_vcmd.action = NOP;
+
+ if (el->el_chared.c_vcmd.pos == 0)
+ return;
+
+
+ if (el->el_line.cursor > el->el_chared.c_vcmd.pos) {
+ size = (int) (el->el_line.cursor - el->el_chared.c_vcmd.pos);
+ c_delbefore(el, size);
+ el->el_line.cursor = el->el_chared.c_vcmd.pos;
+ re_refresh_cursor(el);
+ }
+ else if (el->el_line.cursor < el->el_chared.c_vcmd.pos) {
+ size = (int)(el->el_chared.c_vcmd.pos - el->el_line.cursor);
+ c_delafter(el, size);
+ }
+ else {
+ size = 1;
+ c_delafter(el, size);
+ }
+ switch (oaction) {
+ case DELETE|INSERT:
+ el->el_chared.c_undo.action = DELETE|INSERT;
+ break;
+ case DELETE:
+ el->el_chared.c_undo.action = INSERT;
+ break;
+ case NOP:
+ case INSERT:
+ default:
+ abort();
+ break;
+ }
+
+
+ el->el_chared.c_undo.ptr = el->el_line.cursor;
+ el->el_chared.c_undo.dsize = size;
+}
+
+
+#ifdef notdef
+/* ce__endword():
+ * Go to the end of this word according to emacs
+ */
+protected char *
+ce__endword(p, high, n)
+ char *p, *high;
+ int n;
+{
+ p++;
+
+ while (n--) {
+ while ((p < high) && isspace((unsigned char) *p))
+ p++;
+ while ((p < high) && !isspace((unsigned char) *p))
+ p++;
+ }
+
+ p--;
+ return p;
+}
+#endif
+
+
+/* cv__endword():
+ * Go to the end of this word according to vi
+ */
+protected char *
+cv__endword(p, high, n)
+ char *p, *high;
+ int n;
+{
+ p++;
+
+ while (n--) {
+ while ((p < high) && isspace((unsigned char) *p))
+ p++;
+
+ if (isalnum((unsigned char) *p))
+ while ((p < high) && isalnum((unsigned char) *p))
+ p++;
+ else
+ while ((p < high) && !(isspace((unsigned char) *p) ||
+ isalnum((unsigned char) *p)))
+ p++;
+ }
+ p--;
+ return p;
+}
+
+/* ch_init():
+ * Initialize the character editor
+ */
+protected int
+ch_init(el)
+ EditLine *el;
+{
+ el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ);
+ (void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
+ el->el_line.cursor = el->el_line.buffer;
+ el->el_line.lastchar = el->el_line.buffer;
+ el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - 2];
+
+ el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ);
+ (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
+ el->el_chared.c_undo.action = NOP;
+ el->el_chared.c_undo.isize = 0;
+ el->el_chared.c_undo.dsize = 0;
+ el->el_chared.c_undo.ptr = el->el_line.buffer;
+
+ el->el_chared.c_vcmd.action = NOP;
+ el->el_chared.c_vcmd.pos = el->el_line.buffer;
+ el->el_chared.c_vcmd.ins = el->el_line.buffer;
+
+ el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ);
+ (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
+ el->el_chared.c_kill.mark = el->el_line.buffer;
+ el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
+
+ el->el_map.current = el->el_map.key;
+
+ el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
+ el->el_state.doingarg = 0;
+ el->el_state.metanext = 0;
+ el->el_state.argument = 1;
+ el->el_state.lastcmd = ED_UNASSIGNED;
+
+ el->el_chared.c_macro.nline = NULL;
+ el->el_chared.c_macro.level = -1;
+ el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO *
+ sizeof(char *));
+ return 0;
+}
+
+/* ch_reset():
+ * Reset the character editor
+ */
+protected void
+ch_reset(el)
+ EditLine *el;
+{
+ el->el_line.cursor = el->el_line.buffer;
+ el->el_line.lastchar = el->el_line.buffer;
+
+ el->el_chared.c_undo.action = NOP;
+ el->el_chared.c_undo.isize = 0;
+ el->el_chared.c_undo.dsize = 0;
+ el->el_chared.c_undo.ptr = el->el_line.buffer;
+
+ el->el_chared.c_vcmd.action = NOP;
+ el->el_chared.c_vcmd.pos = el->el_line.buffer;
+ el->el_chared.c_vcmd.ins = el->el_line.buffer;
+
+ el->el_chared.c_kill.mark = el->el_line.buffer;
+
+ el->el_map.current = el->el_map.key;
+
+ el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
+ el->el_state.doingarg = 0;
+ el->el_state.metanext = 0;
+ el->el_state.argument = 1;
+ el->el_state.lastcmd = ED_UNASSIGNED;
+
+ el->el_chared.c_macro.level = -1;
+
+ el->el_history.eventno = 0;
+}
+
+
+/* ch_end():
+ * Free the data structures used by the editor
+ */
+protected void
+ch_end(el)
+ EditLine *el;
+{
+ el_free((ptr_t) el->el_line.buffer);
+ el->el_line.buffer = NULL;
+ el->el_line.limit = NULL;
+ el_free((ptr_t) el->el_chared.c_undo.buf);
+ el->el_chared.c_undo.buf = NULL;
+ el_free((ptr_t) el->el_chared.c_kill.buf);
+ el->el_chared.c_kill.buf = NULL;
+ el_free((ptr_t) el->el_chared.c_macro.macro);
+ el->el_chared.c_macro.macro = NULL;
+ ch_reset(el);
+}
+
+
+/* el_insertstr():
+ * Insert string at cursorI
+ */
+public int
+el_insertstr(el, s)
+ EditLine *el;
+ char *s;
+{
+ int len;
+
+ if ((len = strlen(s)) == 0)
+ return -1;
+ if (el->el_line.lastchar + len >= el->el_line.limit)
+ return -1;
+
+ c_insert(el, len);
+ while (*s)
+ *el->el_line.cursor++ = *s++;
+ return 0;
+}
+
+
+/* el_deletestr():
+ * Delete num characters before the cursor
+ */
+public void
+el_deletestr(el, n)
+ EditLine *el;
+ int n;
+{
+ if (n <= 0)
+ return;
+
+ if (el->el_line.cursor < &el->el_line.buffer[n])
+ return;
+
+ c_delbefore(el, n); /* delete before dot */
+ el->el_line.cursor -= n;
+ if (el->el_line.cursor < el->el_line.buffer)
+ el->el_line.cursor = el->el_line.buffer;
+}
+
+/* c_gets():
+ * Get a string
+ */
+protected int
+c_gets(el, buf)
+ EditLine *el;
+ char *buf;
+{
+ char ch;
+ int len = 0;
+
+ for (ch = 0; ch == 0;) {
+ if (el_getc(el, &ch) != 1)
+ return ed_end_of_file(el, 0);
+ switch (ch) {
+ case '\010': /* Delete and backspace */
+ case '\177':
+ if (len > 1) {
+ *el->el_line.cursor-- = '\0';
+ el->el_line.lastchar = el->el_line.cursor;
+ buf[len--] = '\0';
+ }
+ else {
+ el->el_line.buffer[0] = '\0';
+ el->el_line.lastchar = el->el_line.buffer;
+ el->el_line.cursor = el->el_line.buffer;
+ return CC_REFRESH;
+ }
+ re_refresh(el);
+ ch = 0;
+ break;
+
+ case '\033': /* ESC */
+ case '\r': /* Newline */
+ case '\n':
+ break;
+
+ default:
+ if (len >= EL_BUFSIZ)
+ term_beep(el);
+ else {
+ buf[len++] = ch;
+ *el->el_line.cursor++ = ch;
+ el->el_line.lastchar = el->el_line.cursor;
+ }
+ re_refresh(el);
+ ch = 0;
+ break;
+ }
+ }
+ buf[len] = ch;
+ return len;
+}
+
+
+/* c_hpos():
+ * Return the current horizontal position of the cursor
+ */
+protected int
+c_hpos(el)
+ EditLine *el;
+{
+ char *ptr;
+
+ /*
+ * Find how many characters till the beginning of this line.
+ */
+ if (el->el_line.cursor == el->el_line.buffer)
+ return 0;
+ else {
+ for (ptr = el->el_line.cursor - 1;
+ ptr >= el->el_line.buffer && *ptr != '\n';
+ ptr--)
+ continue;
+ return el->el_line.cursor - ptr - 1;
+ }
+}
diff --git a/lib/libedit/chared.h b/lib/libedit/chared.h
new file mode 100644
index 0000000..f979b93
--- /dev/null
+++ b/lib/libedit/chared.h
@@ -0,0 +1,159 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)chared.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.chared.h: Character editor interface
+ */
+#ifndef _h_el_chared
+#define _h_el_chared
+
+#include <ctype.h>
+#include <string.h>
+
+#include "histedit.h"
+
+#define EL_MAXMACRO 10
+
+/*
+ * This is a issue of basic "vi" look-and-feel. Defining VI_MOVE works
+ * like real vi: i.e. the transition from command<->insert modes moves
+ * the cursor.
+ *
+ * On the other hand we really don't want to move the cursor, because
+ * all the editing commands don't include the character under the cursor.
+ * Probably the best fix is to make all the editing commands aware of
+ * this fact.
+ */
+#define VI_MOVE
+
+
+typedef struct c_macro_t {
+ int level;
+ char **macro;
+ char *nline;
+} c_macro_t;
+
+/*
+ * Undo information for both vi and emacs
+ */
+typedef struct c_undo_t {
+ int action;
+ int isize;
+ int dsize;
+ char *ptr;
+ char *buf;
+} c_undo_t;
+
+/*
+ * Current action information for vi
+ */
+typedef struct c_vcmd_t {
+ int action;
+ char *pos;
+ char *ins;
+} c_vcmd_t;
+
+/*
+ * Kill buffer for emacs
+ */
+typedef struct c_kill_t {
+ char *buf;
+ char *last;
+ char *mark;
+} c_kill_t;
+
+/*
+ * Note that we use both data structures because the user can bind
+ * commands from both editors!
+ */
+typedef struct el_chared_t {
+ c_undo_t c_undo;
+ c_kill_t c_kill;
+ c_vcmd_t c_vcmd;
+ c_macro_t c_macro;
+} el_chared_t;
+
+
+#define STReof "^D\b\b"
+#define STRQQ "\"\""
+
+#define isglob(a) (strchr("*[]?", (a)) != NULL)
+#define isword(a) (isprint(a))
+
+#define NOP 0x00
+#define DELETE 0x01
+#define INSERT 0x02
+#define CHANGE 0x04
+
+#define CHAR_FWD 0
+#define CHAR_BACK 1
+
+#define MODE_INSERT 0
+#define MODE_REPLACE 1
+#define MODE_REPLACE_1 2
+
+#include "common.h"
+#include "vi.h"
+#include "emacs.h"
+#include "search.h"
+#include "fcns.h"
+
+
+protected int cv__isword __P((int));
+protected void cv_delfini __P((EditLine *));
+protected char *cv__endword __P((char *, char *, int));
+protected int ce__isword __P((int));
+protected int c___isword __P((int));
+protected void cv_undo __P((EditLine *, int, int, char *));
+protected char *cv_next_word __P((EditLine*, char *, char *, int,
+ int (*)(int)));
+protected char *cv_prev_word __P((EditLine*, char *, char *, int,
+ int (*)(int)));
+protected char *c__next_word __P((char *, char *, int, int (*)(int)));
+protected char *c__prev_word __P((char *, char *, int, int (*)(int)));
+protected void c_insert __P((EditLine *, int));
+protected void c_delbefore __P((EditLine *, int));
+protected void c_delafter __P((EditLine *, int));
+protected int c_gets __P((EditLine *, char *));
+protected int c_hpos __P((EditLine *));
+
+protected int ch_init __P((EditLine *));
+protected void ch_reset __P((EditLine *));
+protected void ch_end __P((EditLine *));
+
+#endif /* _h_el_chared */
diff --git a/lib/libedit/common.c b/lib/libedit/common.c
new file mode 100644
index 0000000..66b7c90
--- /dev/null
+++ b/lib/libedit/common.c
@@ -0,0 +1,995 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * common.c: Common Editor functions
+ */
+#include "sys.h"
+#include "el.h"
+
+/* ed_end_of_file():
+ * Indicate end of file
+ * [^D]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_end_of_file(el, c)
+ EditLine *el;
+ int c;
+{
+ re_goto_bottom(el);
+ *el->el_line.lastchar = '\0';
+ return CC_EOF;
+}
+
+
+/* ed_insert():
+ * Add character to the line
+ * Insert a character [bound to all insert keys]
+ */
+protected el_action_t
+ed_insert(el, c)
+ EditLine *el;
+ int c;
+{
+ int i;
+
+ if (c == '\0')
+ return CC_ERROR;
+
+ if (el->el_line.lastchar + el->el_state.argument >=
+ el->el_line.limit)
+ return CC_ERROR; /* end of buffer space */
+
+ if (el->el_state.argument == 1) {
+ if (el->el_state.inputmode != MODE_INSERT) {
+ el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
+ *el->el_line.cursor;
+ el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0';
+ c_delafter(el, 1);
+ }
+
+ c_insert(el, 1);
+
+ *el->el_line.cursor++ = c;
+ el->el_state.doingarg = 0; /* just in case */
+ re_fastaddc(el); /* fast refresh for one char. */
+ }
+ else {
+ if (el->el_state.inputmode != MODE_INSERT) {
+
+ for(i = 0;i < el->el_state.argument; i++)
+ el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
+ el->el_line.cursor[i];
+
+ el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0';
+ c_delafter(el, el->el_state.argument);
+ }
+
+ c_insert(el, el->el_state.argument);
+
+ while (el->el_state.argument--)
+ *el->el_line.cursor++ = c;
+ re_refresh(el);
+ }
+
+ if (el->el_state.inputmode == MODE_REPLACE_1 || el->el_state.inputmode == MODE_REPLACE)
+ el->el_chared.c_undo.action=CHANGE;
+
+ if (el->el_state.inputmode == MODE_REPLACE_1)
+ return vi_command_mode(el, 0);
+
+ return CC_NORM;
+}
+
+
+/* ed_delete_prev_word():
+ * Delete from beginning of current word to cursor
+ * [M-^?] [^W]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_delete_prev_word(el, c)
+ EditLine *el;
+ int c;
+{
+ char *cp, *p, *kp;
+
+ if (el->el_line.cursor == el->el_line.buffer)
+ return CC_ERROR;
+
+ cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
+ el->el_state.argument, ce__isword);
+
+ for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
+ *kp++ = *p;
+ el->el_chared.c_kill.last = kp;
+
+ c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */
+ el->el_line.cursor = cp;
+ if (el->el_line.cursor < el->el_line.buffer)
+ el->el_line.cursor = el->el_line.buffer; /* bounds check */
+ return CC_REFRESH;
+}
+
+
+/* ed_delete_next_char():
+ * Delete character under cursor
+ * [^D] [x]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_delete_next_char(el, c)
+ EditLine *el;
+ int c;
+{
+#ifdef notdef /* XXX */
+#define EL el->el_line
+fprintf(stderr, "\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n",
+ EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar, EL.lastchar, EL.limit, EL.limit);
+#endif
+ if (el->el_line.cursor == el->el_line.lastchar) {/* if I'm at the end */
+ if (el->el_map.type == MAP_VI) {
+ if (el->el_line.cursor == el->el_line.buffer) {
+ /* if I'm also at the beginning */
+#ifdef KSHVI
+ return CC_ERROR;
+#else
+ term_overwrite(el, STReof, 4);/* then do a EOF */
+ term__flush();
+ return CC_EOF;
+#endif
+ }
+ else {
+#ifdef KSHVI
+ el->el_line.cursor--;
+#else
+ return CC_ERROR;
+#endif
+ }
+ }
+ else {
+ if (el->el_line.cursor != el->el_line.buffer)
+ el->el_line.cursor--;
+ else
+ return CC_ERROR;
+ }
+ }
+ c_delafter(el, el->el_state.argument); /* delete after dot */
+ if (el->el_line.cursor >= el->el_line.lastchar && el->el_line.cursor > el->el_line.buffer)
+ el->el_line.cursor = el->el_line.lastchar - 1; /* bounds check */
+ return CC_REFRESH;
+}
+
+
+/* ed_kill_line():
+ * Cut to the end of line
+ * [^K] [^K]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_kill_line(el, c)
+ EditLine *el;
+ int c;
+{
+ char *kp, *cp;
+
+ cp = el->el_line.cursor;
+ kp = el->el_chared.c_kill.buf;
+ while (cp < el->el_line.lastchar)
+ *kp++ = *cp++; /* copy it */
+ el->el_chared.c_kill.last = kp;
+ el->el_line.lastchar = el->el_line.cursor; /* zap! -- delete to end */
+ return CC_REFRESH;
+}
+
+
+/* ed_move_to_end():
+ * Move cursor to the end of line
+ * [^E] [^E]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_move_to_end(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_line.cursor = el->el_line.lastchar;
+ if (el->el_map.type == MAP_VI) {
+#ifdef VI_MOVE
+ el->el_line.cursor--;
+#endif
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+ }
+ return CC_CURSOR;
+}
+
+
+/* ed_move_to_beg():
+ * Move cursor to the beginning of line
+ * [^A] [^A]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_move_to_beg(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_line.cursor = el->el_line.buffer;
+
+ if (el->el_map.type == MAP_VI) {
+ /* We want FIRST non space character */
+ while (isspace((unsigned char) *el->el_line.cursor))
+ el->el_line.cursor++;
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+ }
+
+ return CC_CURSOR;
+}
+
+
+/* ed_transpose_chars():
+ * Exchange the character to the left of the cursor with the one under it
+ * [^T] [^T]
+ */
+protected el_action_t
+ed_transpose_chars(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor < el->el_line.lastchar) {
+ if (el->el_line.lastchar <= &el->el_line.buffer[1])
+ return CC_ERROR;
+ else
+ el->el_line.cursor++;
+ }
+ if (el->el_line.cursor > &el->el_line.buffer[1]) {
+ /* must have at least two chars entered */
+ c = el->el_line.cursor[-2];
+ el->el_line.cursor[-2] = el->el_line.cursor[-1];
+ el->el_line.cursor[-1] = c;
+ return CC_REFRESH;
+ }
+ else
+ return CC_ERROR;
+}
+
+
+/* ed_next_char():
+ * Move to the right one character
+ * [^F] [^F]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_next_char(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor >= el->el_line.lastchar)
+ return CC_ERROR;
+
+ el->el_line.cursor += el->el_state.argument;
+ if (el->el_line.cursor > el->el_line.lastchar)
+ el->el_line.cursor = el->el_line.lastchar;
+
+ if (el->el_map.type == MAP_VI)
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+
+ return CC_CURSOR;
+}
+
+
+/* ed_prev_word():
+ * Move to the beginning of the current word
+ * [M-b] [b]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_prev_word(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor == el->el_line.buffer)
+ return CC_ERROR;
+
+ el->el_line.cursor = c__prev_word(el->el_line.cursor, el->el_line.buffer,
+ el->el_state.argument,
+ ce__isword);
+
+ if (el->el_map.type == MAP_VI)
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+
+ return CC_CURSOR;
+}
+
+
+/* ed_prev_char():
+ * Move to the left one character
+ * [^B] [^B]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_prev_char(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor > el->el_line.buffer) {
+ el->el_line.cursor -= el->el_state.argument;
+ if (el->el_line.cursor < el->el_line.buffer)
+ el->el_line.cursor = el->el_line.buffer;
+
+ if (el->el_map.type == MAP_VI)
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+
+ return CC_CURSOR;
+ }
+ else
+ return CC_ERROR;
+}
+
+
+/* ed_quoted_insert():
+ * Add the next character typed verbatim
+ * [^V] [^V]
+ */
+protected el_action_t
+ed_quoted_insert(el, c)
+ EditLine *el;
+ int c;
+{
+ int num;
+ char tc;
+
+ tty_quotemode(el);
+ num = el_getc(el, &tc);
+ c = (unsigned char) tc;
+ tty_noquotemode(el);
+ if (num == 1)
+ return ed_insert(el, c);
+ else
+ return ed_end_of_file(el, 0);
+}
+
+
+/* ed_digit():
+ * Adds to argument or enters a digit
+ */
+protected el_action_t
+ed_digit(el, c)
+ EditLine *el;
+ int c;
+{
+ if (!isdigit((unsigned char) c))
+ return CC_ERROR;
+
+ if (el->el_state.doingarg) {
+ /* if doing an arg, add this in... */
+ if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
+ el->el_state.argument = c - '0';
+ else {
+ if (el->el_state.argument > 1000000)
+ return CC_ERROR;
+ el->el_state.argument =
+ (el->el_state.argument * 10) + (c - '0');
+ }
+ return CC_ARGHACK;
+ }
+ else {
+ if (el->el_line.lastchar + 1 >= el->el_line.limit)
+ return CC_ERROR;
+
+ if (el->el_state.inputmode != MODE_INSERT) {
+ el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
+ *el->el_line.cursor;
+ el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0';
+ c_delafter(el, 1);
+ }
+ c_insert(el, 1);
+ *el->el_line.cursor++ = c;
+ el->el_state.doingarg = 0;
+ re_fastaddc(el);
+ }
+ return CC_NORM;
+}
+
+
+/* ed_argument_digit():
+ * Digit that starts argument
+ * For ESC-n
+ */
+protected el_action_t
+ed_argument_digit(el, c)
+ EditLine *el;
+ register int c;
+{
+ if (!isdigit((unsigned char) c))
+ return CC_ERROR;
+
+ if (el->el_state.doingarg) {
+ if (el->el_state.argument > 1000000)
+ return CC_ERROR;
+ el->el_state.argument = (el->el_state.argument * 10) + (c - '0');
+ }
+ else { /* else starting an argument */
+ el->el_state.argument = c - '0';
+ el->el_state.doingarg = 1;
+ }
+ return CC_ARGHACK;
+}
+
+
+/* ed_unassigned():
+ * Indicates unbound character
+ * Bound to keys that are not assigned
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_unassigned(el, c)
+ EditLine *el;
+ int c;
+{
+ term_beep(el);
+ term__flush();
+ return CC_NORM;
+}
+
+
+/**
+ ** TTY key handling.
+ **/
+
+/* ed_tty_sigint():
+ * Tty interrupt character
+ * [^C]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_tty_sigint(el, c)
+ EditLine *el;
+ int c;
+{
+ return CC_NORM;
+}
+
+
+/* ed_tty_dsusp():
+ * Tty delayed suspend character
+ * [^Y]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_tty_dsusp(el, c)
+ EditLine *el;
+ int c;
+{
+ return CC_NORM;
+}
+
+
+/* ed_tty_flush_output():
+ * Tty flush output characters
+ * [^O]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_tty_flush_output(el, c)
+ EditLine *el;
+ int c;
+{
+ return CC_NORM;
+}
+
+
+/* ed_tty_sigquit():
+ * Tty quit character
+ * [^\]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_tty_sigquit(el, c)
+ EditLine *el;
+ int c;
+{
+ return CC_NORM;
+}
+
+
+/* ed_tty_sigtstp():
+ * Tty suspend character
+ * [^Z]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_tty_sigtstp(el, c)
+ EditLine *el;
+ int c;
+{
+ return CC_NORM;
+}
+
+
+/* ed_tty_stop_output():
+ * Tty disallow output characters
+ * [^S]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_tty_stop_output(el, c)
+ EditLine *el;
+ int c;
+{
+ return CC_NORM;
+}
+
+
+/* ed_tty_start_output():
+ * Tty allow output characters
+ * [^Q]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_tty_start_output(el, c)
+ EditLine *el;
+ int c;
+{
+ return CC_NORM;
+}
+
+
+/* ed_newline():
+ * Execute command
+ * [^J]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_newline(el, c)
+ EditLine *el;
+ int c;
+{
+ re_goto_bottom(el);
+ *el->el_line.lastchar++ = '\n';
+ *el->el_line.lastchar = '\0';
+ if (el->el_map.type == MAP_VI)
+ el->el_chared.c_vcmd.ins = el->el_line.buffer;
+ return CC_NEWLINE;
+}
+
+
+/* ed_delete_prev_char():
+ * Delete the character to the left of the cursor
+ * [^?]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_delete_prev_char(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor <= el->el_line.buffer)
+ return CC_ERROR;
+
+ c_delbefore(el, el->el_state.argument);
+ el->el_line.cursor -= el->el_state.argument;
+ if (el->el_line.cursor < el->el_line.buffer)
+ el->el_line.cursor = el->el_line.buffer;
+ return CC_REFRESH;
+}
+
+
+/* ed_clear_screen():
+ * Clear screen leaving current line at the top
+ * [^L]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_clear_screen(el, c)
+ EditLine *el;
+ int c;
+{
+ term_clear_screen(el); /* clear the whole real screen */
+ re_clear_display(el); /* reset everything */
+ return CC_REFRESH;
+}
+
+
+/* ed_redisplay():
+ * Redisplay everything
+ * ^R
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_redisplay(el, c)
+ EditLine *el;
+ int c;
+{
+ return CC_REDISPLAY;
+}
+
+
+/* ed_start_over():
+ * Erase current line and start from scratch
+ * [^G]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_start_over(el, c)
+ EditLine *el;
+ int c;
+{
+ ch_reset(el);
+ return CC_REFRESH;
+}
+
+
+/* ed_sequence_lead_in():
+ * First character in a bound sequence
+ * Placeholder for external keys
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_sequence_lead_in(el, c)
+ EditLine *el;
+ int c;
+{
+ return CC_NORM;
+}
+
+
+/* ed_prev_history():
+ * Move to the previous history line
+ * [^P] [k]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_prev_history(el, c)
+ EditLine *el;
+ int c;
+{
+ char beep = 0;
+
+ el->el_chared.c_undo.action = NOP;
+ *el->el_line.lastchar = '\0'; /* just in case */
+
+ if (el->el_history.eventno == 0) { /* save the current buffer away */
+ (void) strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ);
+ el->el_history.last = el->el_history.buf +
+ (el->el_line.lastchar - el->el_line.buffer);
+ }
+
+ el->el_history.eventno += el->el_state.argument;
+
+ if (hist_get(el) == CC_ERROR) {
+ beep = 1;
+ /* el->el_history.eventno was fixed by first call */
+ (void) hist_get(el);
+ }
+
+ re_refresh(el);
+ if (beep)
+ return CC_ERROR;
+ else
+ return CC_NORM; /* was CC_UP_HIST */
+}
+
+
+/* ed_next_history():
+ * Move to the next history line
+ * [^N] [j]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_next_history(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_chared.c_undo.action = NOP;
+ *el->el_line.lastchar = '\0'; /* just in case */
+
+ el->el_history.eventno -= el->el_state.argument;
+
+ if (el->el_history.eventno < 0) {
+ el->el_history.eventno = 0;
+ return CC_ERROR; /* make it beep */
+ }
+
+ return hist_get(el);
+}
+
+
+/* ed_search_prev_history():
+ * Search previous in history for a line matching the current
+ * next search history [M-P] [K]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_search_prev_history(el, c)
+ EditLine *el;
+ int c;
+{
+ const char *hp;
+ int h;
+ bool_t found = 0;
+
+ el->el_chared.c_vcmd.action = NOP;
+ el->el_chared.c_undo.action = NOP;
+ *el->el_line.lastchar = '\0'; /* just in case */
+ if (el->el_history.eventno < 0) {
+#ifdef DEBUG_EDIT
+ (void) fprintf(el->el_errfile, "e_prev_search_hist(): eventno < 0;\n");
+#endif
+ el->el_history.eventno = 0;
+ return CC_ERROR;
+ }
+
+ if (el->el_history.eventno == 0) {
+ (void) strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ);
+ el->el_history.last = el->el_history.buf +
+ (el->el_line.lastchar - el->el_line.buffer);
+ }
+
+
+ if (el->el_history.ref == NULL)
+ return CC_ERROR;
+
+ hp = HIST_FIRST(el);
+ if (hp == NULL)
+ return CC_ERROR;
+
+ c_setpat(el); /* Set search pattern !! */
+
+ for (h = 1; h <= el->el_history.eventno; h++)
+ hp = HIST_NEXT(el);
+
+ while (hp != NULL) {
+#ifdef SDEBUG
+ (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
+#endif
+ if ((strncmp(hp, el->el_line.buffer,
+ el->el_line.lastchar - el->el_line.buffer) ||
+ hp[el->el_line.lastchar-el->el_line.buffer]) &&
+ c_hmatch(el, hp)) {
+ found++;
+ break;
+ }
+ h++;
+ hp = HIST_NEXT(el);
+ }
+
+ if (!found) {
+#ifdef SDEBUG
+ (void) fprintf(el->el_errfile, "not found\n");
+#endif
+ return CC_ERROR;
+ }
+
+ el->el_history.eventno = h;
+
+ return hist_get(el);
+}
+
+
+/* ed_search_next_history():
+ * Search next in history for a line matching the current
+ * [M-N] [J]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_search_next_history(el, c)
+ EditLine *el;
+ int c;
+{
+ const char *hp;
+ int h;
+ bool_t found = 0;
+
+ el->el_chared.c_vcmd.action = NOP;
+ el->el_chared.c_undo.action = NOP;
+ *el->el_line.lastchar = '\0'; /* just in case */
+
+ if (el->el_history.eventno == 0)
+ return CC_ERROR;
+
+ if (el->el_history.ref == NULL)
+ return CC_ERROR;
+
+ hp = HIST_FIRST(el);
+ if (hp == NULL)
+ return CC_ERROR;
+
+ c_setpat(el); /* Set search pattern !! */
+
+ for (h = 1; h < el->el_history.eventno && hp; h++) {
+#ifdef SDEBUG
+ (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
+#endif
+ if ((strncmp(hp, el->el_line.buffer,
+ el->el_line.lastchar - el->el_line.buffer) ||
+ hp[el->el_line.lastchar-el->el_line.buffer]) &&
+ c_hmatch(el, hp))
+ found = h;
+ hp = HIST_NEXT(el);
+ }
+
+ if (!found) { /* is it the current history number? */
+ if (!c_hmatch(el, el->el_history.buf)) {
+#ifdef SDEBUG
+ (void) fprintf(el->el_errfile, "not found\n");
+#endif
+ return CC_ERROR;
+ }
+ }
+
+ el->el_history.eventno = found;
+
+ return hist_get(el);
+}
+
+
+/* ed_prev_line():
+ * Move up one line
+ * Could be [k] [^p]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_prev_line(el, c)
+ EditLine *el;
+ int c;
+{
+ char *ptr;
+ int nchars = c_hpos(el);
+
+ /*
+ * Move to the line requested
+ */
+ if (*(ptr = el->el_line.cursor) == '\n')
+ ptr--;
+
+ for (; ptr >= el->el_line.buffer; ptr--)
+ if (*ptr == '\n' && --el->el_state.argument <= 0)
+ break;
+
+ if (el->el_state.argument > 0)
+ return CC_ERROR;
+
+ /*
+ * Move to the beginning of the line
+ */
+ for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
+ continue;
+
+ /*
+ * Move to the character requested
+ */
+ for (ptr++;
+ nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
+ ptr++)
+ continue;
+
+ el->el_line.cursor = ptr;
+ return CC_CURSOR;
+}
+
+
+/* ed_next_line():
+ * Move down one line
+ * Could be [j] [^n]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_next_line(el, c)
+ EditLine *el;
+ int c;
+{
+ char *ptr;
+ int nchars = c_hpos(el);
+
+ /*
+ * Move to the line requested
+ */
+ for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
+ if (*ptr == '\n' && --el->el_state.argument <= 0)
+ break;
+
+ if (el->el_state.argument > 0)
+ return CC_ERROR;
+
+ /*
+ * Move to the character requested
+ */
+ for (ptr++;
+ nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
+ ptr++)
+ continue;
+
+ el->el_line.cursor = ptr;
+ return CC_CURSOR;
+}
+
+
+/* ed_command():
+ * Editline extended command
+ * [M-X] [:]
+ */
+protected el_action_t
+/*ARGSUSED*/
+ed_command(el, c)
+ EditLine *el;
+ int c;
+{
+ char tmpbuf[EL_BUFSIZ];
+ int tmplen;
+
+ el->el_line.buffer[0] = '\0';
+ el->el_line.lastchar = el->el_line.buffer;
+ el->el_line.cursor = el->el_line.buffer;
+
+ c_insert(el, 3); /* prompt + ": " */
+ *el->el_line.cursor++ = '\n';
+ *el->el_line.cursor++ = ':';
+ *el->el_line.cursor++ = ' ';
+ re_refresh(el);
+
+ tmplen = c_gets(el, tmpbuf);
+ tmpbuf[tmplen] = '\0';
+
+ el->el_line.buffer[0] = '\0';
+ el->el_line.lastchar = el->el_line.buffer;
+ el->el_line.cursor = el->el_line.buffer;
+
+ if (parse_line(el, tmpbuf) == -1)
+ return CC_ERROR;
+ else
+ return CC_REFRESH;
+}
diff --git a/lib/libedit/editline.3 b/lib/libedit/editline.3
new file mode 100644
index 0000000..c1fed73
--- /dev/null
+++ b/lib/libedit/editline.3
@@ -0,0 +1,548 @@
+.\" $NetBSD: editline.3,v 1.4 1997/01/14 04:17:23 lukem Exp $
+.\"
+.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the NetBSD
+.\" Foundation, Inc. and its contributors.
+.\" 4. Neither the name of The NetBSD Foundation nor the names of its
+.\" contributors may be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd January 11, 1997
+.Os BSD 4.4
+.Dt EDITLINE 3
+.Sh NAME
+.Nm editline ,
+.Nm el_init ,
+.Nm el_end ,
+.Nm el_reset ,
+.Nm el_gets ,
+.Nm el_getc ,
+.Nm el_push ,
+.Nm el_parse ,
+.Nm el_set ,
+.Nm el_source ,
+.Nm el_resize ,
+.Nm el_line ,
+.Nm el_insertstr ,
+.Nm el_deletestr ,
+.Nm el_data_set ,
+.Nm el_data_get ,
+.Nm history_init ,
+.Nm history_end ,
+.Nm history
+.Nd line editor and history functions
+.Sh SYNOPSIS
+.Fd #include <histedit.h>
+.Ft EditLine *
+.Fn el_init "const char *prog" "FILE *fin" "FILE *fout"
+.Ft void
+.Fn el_end "EditLine *e"
+.Ft void
+.Fn el_reset "EditLine *e"
+.Ft const char *
+.Fn el_gets "EditLine *e" "int *count"
+.Ft int
+.Fn el_getc "EditLine *e" "char *ch"
+.Ft void
+.Fn el_push "EditLine *e" "const char *str"
+.Ft int
+.Fn el_parse "EditLine *e" "int argc" "char *argv[]"
+.Ft int
+.Fn el_set "EditLine *e" "int op" "..."
+.Ft int
+.Fn el_source "EditLine *e" "const char *file"
+.Ft void
+.Fn el_resize "EditLine *e"
+.Ft const LineInfo *
+.Fn el_line "EditLine *e"
+.Ft int
+.Fn el_insertstr "EditLine *e" "char *str"
+.Ft void
+.Fn el_deletestr "EditLine *e" "int count"
+.Ft void
+.Fn el_data_set "EditLine *e" "void *data"
+.Ft void *
+.Fn el_data_get "EditLine *e"
+.Ft History *
+.Fn history_init
+.Ft void
+.Fn history_end "History *h"
+.Ft const HistEvent *
+.Fn history "History *h" "int op" "..."
+.Sh DESCRIPTION
+The
+.Nm
+library provides generic line editing and history functions,
+similar to those found in
+.Xr sh 1 .
+.Pp
+These functions are available in the
+.Nm libedit
+library (which needs the
+.Nm libtermcap
+library).
+Programs should be linked with
+.Fl ledit ltermcap .
+.Sh LINE EDITING FUNCTIONS
+The line editing functions use a common data structure,
+.Fa EditLine ,
+which is created by
+.Fn el_init
+and freed by
+.Fn el_end .
+.Pp
+The following functions are available:
+.Bl -tag -width 4n
+.It Fn el_init
+Initialise the line editor, and return a data structure
+to be used by all other line editing functions.
+.Fa prog
+is the name of the invoking program, used when reading the
+.Xr editrc 5
+file to determine which settings to use.
+.Fa fin
+and
+.Fa fout
+are the input and output streams (respectively) to use.
+In this documentation, references to
+.Dq the tty
+are actually to this input/output stream combination.
+.It Fn el_end
+Clean up and finish with
+.Fa e ,
+assumed to have been created with
+.Fn el_init .
+.It Fn el_reset
+Reset the tty and the parser.
+This should be called after an error which may have upset the tty's
+state.
+.It Fn el_gets
+Read a line from the tty.
+.Fa count
+is modified to contain the number of characters read.
+Returns the line read if successful, or
+.Dv NULL
+if no characters were read or if an error occurred.
+.It Fn el_getc
+Read a character from the tty.
+.Fa ch
+is modified to contain the character read.
+Returns the number of characters read if successful, -1 otherwise.
+.It Fn el_push
+Pushes
+.Fa str
+back onto the input stream.
+This is used by the macro expansion mechanism.
+Refer to the description of
+.Ic bind
+.Fl s
+in
+.Xr editrc 5
+for more information.
+.It Fn el_parse
+Parses the
+.Fa argv
+array (which is
+.Fa argc
+elements in size)
+to execute builtin
+.Nm
+commands.
+If the command is prefixed with
+.Dq prog:
+then
+.Fn el_parse
+will only execute the command if
+.Dq prog
+matches the
+.Fa prog
+argument supplied to
+.Fn el_init .
+The return value is
+-1 if the command is unknown,
+0 if there was no error or
+.Dq prog
+didn't match, or
+1 if the command returned an error.
+Refer to
+.Xr editrc 5
+for more information.
+.Pp
+.Em NOTE:
+.Va argv[0]
+may be modified by
+.Fn el_parse .
+The colon between
+.Dq prog
+and the command,
+.Ar command ,
+will be replaced with a NUL
+.Po
+.Dq \e0
+.Pc .
+.It Fn el_set
+Set
+.Nm
+parameters.
+.Fa op
+determines which parameter to set, and each operation has its
+own parameter list.
+.Pp
+The following values for
+.Fa op
+are supported, along with the required argument list:
+.Bl -tag -width 4n
+.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)"
+Define prompt printing function as
+.Fa f ,
+which is to return a string that contains the prompt.
+.It Dv EL_TERMINAL , Fa "const char *type"
+Define terminal type of the tty to be
+.Fa type ,
+or to
+.Ev TERM
+if
+.Fa type
+is
+.Dv NULL .
+.It Dv EL_EDITOR , Fa "const char *mode"
+Set editing mode to
+.Fa mode ,
+which must be one of
+.Dq emacs
+or
+.Dq vi .
+.It Dv EL_SIGNAL , Fa "int flag"
+If
+.Fa flag
+is non-zero,
+.Nm
+will install its own signal handler for the following signals when
+reading command input:
+.Dv SIGCONT ,
+.Dv SIGHUP ,
+.Dv SIGINT ,
+.Dv SIGQUIT ,
+.Dv SIGSTOP ,
+.Dv SIGTERM ,
+.Dv SIGTSTP ,
+and
+.Dv SIGWINCH .
+Otherwise, the current signal handlers will be used.
+.It Dv EL_BIND , Xo
+.Fa "const char *" ,
+.Fa "..." ,
+.Dv NULL
+.Xc
+Perform the
+.Ic bind
+builtin command.
+Refer to
+.Xr editrc 5
+for more information.
+.It Dv EL_ECHOTC , Xo
+.Fa "const char *" ,
+.Fa "..." ,
+.Dv NULL
+.Xc
+Perform the
+.Ic echotc
+builtin command.
+Refer to
+.Xr editrc 5
+for more information.
+.It Dv EL_SETTC , Xo
+.Fa "const char *" ,
+.Fa "..." ,
+.Dv NULL
+.Xc
+Perform the
+.Ic settc
+builtin command.
+Refer to
+.Xr editrc 5
+for more information.
+.It Dv EL_SETTY , Xo
+.Fa "const char *" ,
+.Fa "..." ,
+.Dv NULL
+.Xc
+Perform the
+.Ic setty
+builtin command.
+Refer to
+.Xr editrc 5
+for more information.
+.It Dv EL_TELLTC , Xo
+.Fa "const char *" ,
+.Fa "..." ,
+.Dv NULL
+.Xc
+Perform the
+.Ic telltc
+builtin command.
+Refer to
+.Xr editrc 5
+for more information.
+.It Dv EL_ADDFN , Xo
+.Fa "const char *name" ,
+.Fa "const char *help" ,
+.Fa "unsigned char (*func)(EditLine *e, int ch)
+.Xc
+Add a user defined function,
+.Fn func ,
+referred to as
+.Fa name
+which is invoked when a key which is bound to
+.Fa name
+is entered.
+.Fa help
+is a description of
+.Fa name .
+At invocation time,
+.Fa ch
+is the key which caused the invocation.
+The return value of
+.Fn func
+should be one of:
+.Bl -tag -width "CC_REDISPLAY"
+.It Dv CC_NORM
+Add a normal character.
+.It Dv CC_NEWLINE
+End of line was entered.
+.It Dv CC_EOF
+EOF was entered.
+.It Dv CC_ARGHACK
+Expecting further command input as arguments, do nothing visually.
+.It Dv CC_REFRESH
+Refresh display.
+.It Dv CC_CURSOR
+Cursor moved, so update and perform
+.Dv CC_REFRESH.
+.It Dv CC_REDISPLAY
+Redisplay entire input line.
+This is useful if a key binding outputs extra information.
+.It Dv CC_ERROR
+An error occurred.
+Beep, and flush tty.
+.It Dv CC_FATAL
+Fatal error, reset tty to known state.
+.El
+.It Dv EL_HIST , Xo
+.Fa "History *(*func)(History *, int op, ...)" ,
+.Fa "const char *ptr"
+.Xc
+Defines which history function to use, which is usually
+.Fn history .
+.Fa ptr
+should be the value returned by
+.Fn history_init .
+.El
+.It Fn el_source
+Initialise
+.Nm
+by reading the contents of
+.Fa file .
+.Fn el_parse
+is called for each line in
+.Fa file .
+If
+.Fa file
+is
+.Dv NULL ,
+try
+.Pa $PWD/.editrc
+then
+.Pa $HOME/.editrc .
+Refer to
+.Xr editrc 5
+for details on the format of
+.Fa file .
+.It Fn el_resize
+Must be called if the terminal size changes.
+If
+.Dv EL_SIGNAL
+has been set with
+.Fn el_set ,
+then this is done automatically.
+Otherwise, it's the responsibility of the application to call
+.Fn el_resize
+on the appropriate occasions.
+.It Fn el_line
+Return the editing information for the current line in a
+.Fa LineInfo
+structure, which is defined as follows:
+.Bd -literal
+typedef struct lineinfo {
+ const char *buffer; /* address of buffer */
+ const char *cursor; /* address of cursor */
+ const char *lastchar; /* address of last character */
+} LineInfo;
+.Ed
+.It Fn el_insertstr
+Insert
+.Fa str
+into the line at the cursor.
+Returns -1 if
+.Fa str
+is empty or won't fit, and 0 otherwise.
+.It Fn el_deletestr
+Delete
+.Fa num
+characters before the cursor.
+.It Fn el_data_set
+Set the user data to
+.Fa data
+.
+.It Fn el_data_get
+Get the user data.
+.El
+.Sh HISTORY LIST FUNCTIONS
+The history functions use a common data structure,
+.Fa History ,
+which is created by
+.Fn history_init
+and freed by
+.Fn history_end .
+.Pp
+The following functions are available:
+.Bl -tag -width 4n
+.It Fn history_init
+Initialise the history list, and return a data structure
+to be used by all other history list functions.
+.It Fn history_end
+Clean up and finish with
+.Fa h ,
+assumed to have been created with
+.Fn history_init .
+.It Fn history
+Perform operation
+.Fa op
+on the history list, with optional arguments as needed by the
+operation.
+The following values for
+.Fa op
+are supported, along with the required argument list:
+.Bl -tag -width 4n
+.It Dv H_EVENT , Fa "int size"
+Set size of history to
+.Fa size
+elements.
+.It Dv H_END
+Cleans up and finishes with
+.Fa h ,
+assumed to be created with
+.Fn history_init .
+.It Dv H_CLEAR
+Clear the history.
+.It Dv H_FUNC , Xo
+.Fa "void *ptr" ,
+.Fa "history_gfun_t first" ,
+.Fa "history_gfun_t next" ,
+.Fa "history_gfun_t last" ,
+.Fa "history_gfun_t prev" ,
+.Fa "history_gfun_t curr" ,
+.Fa "history_vfun_t clear" ,
+.Fa "history_efun_t enter" ,
+.Fa "history_efun_t add"
+.Xc
+Define functions to perform various history operations.
+.Fa ptr
+is the argument given to a function when it's invoked.
+.It Dv H_FIRST
+Return the first element in the history.
+.It Dv H_LAST
+Return the last element in the history.
+.It Dv H_PREV
+Return the previous element in the history.
+.It Dv H_NEXT
+Return the next element in the history.
+.It Dv H_CURR
+Return the current element in the history.
+.It Dv H_ADD , Fa "const char *str"
+Append
+.Fa str
+to the current element of the history, or create an element with
+.Dv H_ENTER
+if there isn't one.
+.It Dv H_ENTER , Fa "const char *str"
+Add
+.Fa str
+as a new element to the history, and, if necessary,
+removing the oldest entry to keep the list to the created size.
+.It Dv H_PREV_STR , Fa "const char *str"
+Return the closest previous event that starts with
+.Fa str .
+.It Dv H_NEXT_STR , Fa "const char *str"
+Return the closest next event that starts with
+.Fa str .
+.It Dv H_PREV_EVENT , Fa "int e"
+Return the previous event numbered
+.Fa e .
+.It Dv H_NEXT_EVENT , Fa "int e"
+Return the next event numbered
+.Fa e .
+.It Dv H_LOAD , Fa "const char *file"
+Load the history list stored in
+.Fa file .
+.It Dv H_SAVE , Fa "const char *file"
+Save the history list to
+.Fa file .
+.El
+.El
+.\"XXX.Sh EXAMPLES
+.\"XXX: provide some examples
+.Sh SEE ALSO
+.Xr sh 1 ,
+.Xr signal 3 ,
+.Xr termcap 3 ,
+.Xr editrc 5
+.Sh HISTORY
+The
+.Nm
+library first appeared in
+.Bx 4.4 .
+.Sh AUTHORS
+The
+.Nm
+library was written by
+.An Christos Zoulas ,
+and this manual was written by
+.An Luke Mewburn .
+.Sh BUGS
+This documentation is probably incomplete.
+.Pp
+.Fn el_parse
+should not modify the supplied
+.Va argv[0] .
+.Pp
+The tokenization functions are not publicly defined in
+.Li <histedit.h> .
diff --git a/lib/libedit/editrc.5 b/lib/libedit/editrc.5
new file mode 100644
index 0000000..907a464
--- /dev/null
+++ b/lib/libedit/editrc.5
@@ -0,0 +1,296 @@
+.\" $NetBSD: editrc.5,v 1.4 1997/04/24 20:20:31 christos Exp $
+.\"
+.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the NetBSD
+.\" Foundation, Inc. and its contributors.
+.\" 4. Neither the name of The NetBSD Foundation nor the names of its
+.\" contributors may be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd January 11, 1997
+.Os BSD 4.4
+.Dt EDITRC 5
+.Sh NAME
+.Nm editrc
+.Nd configuration file for editline library
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+The
+.Nm
+file defines various settings to be used by the
+.Xr editline 3
+library.
+.Pp
+The format of each line is either:
+.Dl prog:command [arg [...]]
+or
+.Dl command [arg [...]]
+.Pp
+.Ar command
+is one of the
+.Xr editline 3
+builtin commands.
+Refer to
+.Sx BUILTIN COMMANDS
+for more information.
+.Pp
+.Ar prog
+is the program name string that a program defines when it calls
+.Xr el_init 3
+to setup
+.Xr editline 3 ,
+which is usually
+.Va argv[0] .
+.Ar command
+will be executed for any program which matches
+.Ar prog .
+.Pp
+.Ar prog
+may also be a
+.Xr regex 3
+style
+regular expression, in which case
+.Ar command
+will be executed for any program that matches the regular expression.
+.Sh BUILTIN COMMANDS
+The
+.Nm editline
+library has some builtin commands, which affect the way
+that the line editing and history functions operate.
+These are based on similar named builtins present in the
+.Xr tcsh 1
+shell.
+.Pp
+The following builtin commands are available:
+.Bl -tag -width 4n
+.It Ic bind Xo
+.Op Fl a
+.Op Fl e
+.Op Fl k
+.Op Fl l
+.Op Fl r
+.Op Fl s
+.Op Fl v
+.Op Ar key Op Ar command
+.Xc
+Without options, list all bound keys, and the editor command to which
+each is bound.
+If
+.Ar key
+is supplied, show the bindings for
+.Ar key .
+If
+.Ar key command
+is supplied, bind
+.Ar command
+to
+.Ar key .
+Options include:
+.Bl -tag -width 4n
+.It Fl e
+Bind all keys to the standard GNU Emacs-like bindings.
+.It Fl v
+Bind all keys to the standard
+.Xr vi 1 -like
+bindings.
+.It Fl a
+List or change key bindings in the
+.Xr vi 1
+mode alternate (command mode) key map.
+.It Fl k
+.Ar key
+is interpreted as a symbolic arrow key name, which may be one of
+.Sq up ,
+.Sq down ,
+.Sq left
+or
+.Sq right .
+.It Fl l
+List all editor commands and a short description of each.
+.It Fl r
+Remove a key's binding.
+.It Fl s
+.Ar command
+is taken as a literal string and treated as terminal input when
+.Ar key
+is typed.
+Bound keys in
+.Ar command
+are themselves reinterpreted, and this continues for ten levels of
+interpretation.
+.El
+.Pp
+.Ar key
+and
+.Ar command
+can contain control characters of the form
+.Sm off
+.Sq No ^ Ar character
+.Sm on
+.Po
+e.g.
+.Sq ^A
+.Pc ,
+and the following backslashed escape sequences:
+.Pp
+.Bl -tag -compact -offset indent -width 4n
+.It Ic \ea
+Bell
+.It Ic \eb
+Backspace
+.It Ic \ee
+Escape
+.It Ic \ef
+Formfeed
+.It Ic \en
+Newline
+.It Ic \er
+Carriage return
+.It Ic \et
+Horizontal tab
+.It Ic \ev
+Vertical tab
+.Sm off
+.It Sy \e Ar nnn
+.Sm on
+The ASCII character corresponding to the octal number
+.Ar nnn .
+.El
+.Pp
+.Sq \e
+nullifies the special meaning of the following character,
+if it has any, notably
+.Sq \e
+and
+.Sq ^ .
+.It Ic echotc Xo
+.Op Fl sv
+.Ar arg
+.Ar ...
+.Xc
+Exercise terminal capabilities given in
+.Ar arg Ar ... .
+If
+.Ar arg
+is
+.Sq baud ,
+.Sq cols ,
+.Sq lines ,
+.Sq rows ,
+.Sq meta or
+.Sq tabs ,
+the value of that capability is printed, with
+.Dq yes
+or
+.Dq no
+indicating that the terminal does or does not have that capability.
+.Pp
+.Fl s
+returns an empty string for non-existent capabilities, rather than
+causing an error.
+.Fl v
+causes messages to be verbose.
+.It Ic history
+List the history.
+.It Ic telltc
+List the values of all the terminal capabilities (see
+.Xr termcap 5 ).
+.It Ic settc Ar cap Ar val
+Set the terminal capability
+.Ar cap
+to
+.Ar val ,
+as defined in
+.Xr termcap 5 .
+No sanity checking is done.
+.It Ic setty Xo
+.Op Fl a
+.Op Fl d
+.Op Fl q
+.Op Fl x
+.Op Ar +mode
+.Op Ar -mode
+.Op Ar mode
+.Xc
+Control which tty modes that
+.Nm
+won't allow the user to change.
+.Fl d ,
+.Fl q
+or
+.Fl x
+tells
+.Ic setty
+to act on the
+.Sq edit ,
+.Sq quote
+or
+.Sq execute
+set of tty modes respectively; defaulting to
+.Fl x .
+.Pp
+Without other arguments,
+.Ic setty
+lists the modes in the chosen set which are fixed on
+.Po
+.Sq +mode
+.Pc
+or off
+.Po
+.Sq -mode
+.Pc .
+.Fl a
+lists all tty modes in the chosen set regardless of the setting.
+With
+.Ar +mode ,
+.Ar -mode
+or
+.Ar mode ,
+fixes
+.Ar mode
+on or off or removes control of
+.Ar mode
+in the chosen set.
+.El
+.Sh SEE ALSO
+.Xr editline 3 ,
+.Xr regex 3 ,
+.Xr termcap 5
+.Sh AUTHORS
+The
+.Nm editline
+library was written by
+.An Christos Zoulas ,
+and this manual was written by
+.An Luke Mewburn ,
+with some sections inspired by
+.Xr tcsh 1 .
diff --git a/lib/libedit/el.c b/lib/libedit/el.c
new file mode 100644
index 0000000..87f6813
--- /dev/null
+++ b/lib/libedit/el.c
@@ -0,0 +1,358 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
+#endif /* not lint && not SCCSID */
+
+/*
+ * el.c: EditLine interface functions
+ */
+#include "sys.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <string.h>
+#include <stdlib.h>
+#if __STDC__
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+#include "el.h"
+
+/* el_init():
+ * Initialize editline and set default parameters.
+ */
+public EditLine *
+el_init(prog, fin, fout)
+ const char *prog;
+ FILE *fin, *fout;
+{
+ EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
+#ifdef DEBUG
+ char *tty;
+#endif
+
+ if (el == NULL)
+ return NULL;
+
+ memset(el, 0, sizeof(EditLine));
+
+ el->el_infd = fileno(fin);
+ el->el_outfile = fout;
+ el->el_prog = strdup(prog);
+
+#ifdef DEBUG
+ if (issetugid() == 0 && (tty = getenv("DEBUGTTY")) != NULL) {
+ el->el_errfile = fopen(tty, "w");
+ if (el->el_errfile == NULL) {
+ extern errno;
+ (void) fprintf(stderr, "Cannot open %s (%s).\n",
+ tty, strerror(errno));
+ return NULL;
+ }
+ }
+ else
+#endif
+ el->el_errfile = stderr;
+
+ /*
+ * Initialize all the modules. Order is important!!!
+ */
+ (void) term_init(el);
+ (void) tty_init(el);
+ (void) key_init(el);
+ (void) map_init(el);
+ (void) ch_init(el);
+ (void) search_init(el);
+ (void) hist_init(el);
+ (void) prompt_init(el);
+ (void) sig_init(el);
+ el->el_flags = 0;
+ el->data = NULL;
+
+ return el;
+} /* end el_init */
+
+
+/* el_end():
+ * Clean up.
+ */
+public void
+el_end(el)
+ EditLine *el;
+{
+ if (el == NULL)
+ return;
+
+ el_reset(el);
+
+ term_end(el);
+ tty_end(el);
+ key_end(el);
+ map_end(el);
+ ch_end(el);
+ search_end(el);
+ hist_end(el);
+ prompt_end(el);
+ sig_end(el);
+
+ el_free((ptr_t) el->el_prog);
+ el_free((ptr_t) el);
+} /* end el_end */
+
+
+/* el_reset():
+ * Reset the tty and the parser
+ */
+public void
+el_reset(el)
+ EditLine *el;
+{
+ tty_cookedmode(el);
+ ch_reset(el); /* XXX: Do we want that? */
+}
+
+
+/* el_set():
+ * set the editline parameters
+ */
+public int
+#if __STDC__
+el_set(EditLine *el, int op, ...)
+#else
+el_set(va_alist)
+ va_dcl
+#endif
+{
+ va_list va;
+ int rv;
+#if __STDC__
+ va_start(va, op);
+#else
+ EditLine *el;
+ int op;
+
+ va_start(va);
+ el = va_arg(va, EditLine *);
+ op = va_arg(va, int);
+#endif
+
+ switch (op) {
+ case EL_PROMPT:
+ rv = prompt_set(el, va_arg(va, el_pfunc_t));
+ break;
+
+ case EL_TERMINAL:
+ rv = term_set(el, va_arg(va, char *));
+ break;
+
+ case EL_EDITOR:
+ rv = map_set_editor(el, va_arg(va, char *));
+ break;
+
+ case EL_SIGNAL:
+ if (va_arg(va, int))
+ el->el_flags |= HANDLE_SIGNALS;
+ else
+ el->el_flags &= ~HANDLE_SIGNALS;
+ rv = 0;
+ break;
+
+ case EL_BIND:
+ case EL_TELLTC:
+ case EL_SETTC:
+ case EL_ECHOTC:
+ case EL_SETTY:
+ {
+ char *argv[20];
+ int i;
+ for (i = 1; i < 20; i++)
+ if ((argv[i] = va_arg(va, char *)) == NULL)
+ break;
+
+ switch (op) {
+ case EL_BIND:
+ argv[0] = "bind";
+ rv = map_bind(el, i, argv);
+ break;
+
+ case EL_TELLTC:
+ argv[0] = "telltc";
+ rv = term_telltc(el, i, argv);
+ break;
+
+ case EL_SETTC:
+ argv[0] = "settc";
+ rv = term_settc(el, i, argv);
+ break;
+
+ case EL_ECHOTC:
+ argv[0] = "echotc";
+ rv = term_echotc(el, i, argv);
+ break;
+
+ case EL_SETTY:
+ argv[0] = "setty";
+ rv = tty_stty(el, i, argv);
+ break;
+
+ default:
+ rv = -1;
+ abort();
+ break;
+ }
+ }
+ break;
+
+ case EL_ADDFN:
+ {
+ char *name = va_arg(va, char *);
+ char *help = va_arg(va, char *);
+ el_func_t func = va_arg(va, el_func_t);
+ rv = map_addfunc(el, name, help, func);
+ }
+ break;
+
+ case EL_HIST:
+ {
+ hist_fun_t func = va_arg(va, hist_fun_t);
+ ptr_t ptr = va_arg(va, char *);
+ rv = hist_set(el, func, ptr);
+ }
+ break;
+
+ default:
+ rv = -1;
+ }
+
+ va_end(va);
+ return rv;
+} /* end el_set */
+
+
+/* el_line():
+ * Return editing info
+ */
+public const LineInfo *
+el_line(el)
+ EditLine *el;
+{
+ return (const LineInfo *) &el->el_line;
+}
+
+static const char elpath[] = "/.editrc";
+
+/* el_source():
+ * Source a file
+ */
+public int
+el_source(el, fname)
+ EditLine *el;
+ const char *fname;
+{
+ FILE *fp;
+ size_t len;
+ char *ptr, path[MAXPATHLEN];
+
+ if (fname == NULL) {
+ fname = &elpath[1];
+ if ((fp = fopen(fname, "r")) == NULL) {
+ if (issetugid() != 0 || (ptr = getenv("HOME")) == NULL)
+ return -1;
+ (void)snprintf(path, sizeof(path), "%s%s", ptr, elpath);
+ fname = path;
+ }
+ }
+
+ if ((fp = fopen(fname, "r")) == NULL)
+ return -1;
+
+ while ((ptr = fgetln(fp, &len)) != NULL) {
+ if (ptr[len - 1] == '\n')
+ --len;
+ ptr[len] = '\0';
+
+ if (parse_line(el, ptr) == -1) {
+ (void) fclose(fp);
+ return -1;
+ }
+ }
+
+ (void) fclose(fp);
+ return 0;
+}
+
+
+/* el_resize():
+ * Called from program when terminal is resized
+ */
+public void
+el_resize(el)
+ EditLine *el;
+{
+ int lins, cols;
+ sigset_t oset, nset;
+ (void) sigemptyset(&nset);
+ (void) sigaddset(&nset, SIGWINCH);
+ (void) sigprocmask(SIG_BLOCK, &nset, &oset);
+
+ /* get the correct window size */
+ if (term_get_size(el, &lins, &cols))
+ term_change_size(el, lins, cols);
+
+ (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+}
+
+public void
+el_data_set (el, data)
+ EditLine *el;
+ void *data;
+{
+ el->data = data;
+
+ return;
+}
+
+public void *
+el_data_get (el)
+ EditLine *el;
+{
+ if (el->data)
+ return (el->data);
+ return (NULL);
+}
diff --git a/lib/libedit/el.h b/lib/libedit/el.h
new file mode 100644
index 0000000..9514a70
--- /dev/null
+++ b/lib/libedit/el.h
@@ -0,0 +1,132 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)el.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.h: Internal structures.
+ */
+#ifndef _h_el
+#define _h_el
+/*
+ * Local defaults
+ */
+#define KSHVI
+#define VIDEFAULT
+#define ANCHOR
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#define EL_BUFSIZ 1024 /* Maximum line size */
+
+#define HANDLE_SIGNALS 1
+
+typedef int bool_t; /* True or not */
+
+typedef unsigned char el_action_t; /* Index to command array */
+
+typedef struct coord_t { /* Position on the screen */
+ int h, v;
+} coord_t;
+
+typedef struct el_line_t {
+ char *buffer, /* Input line */
+ *cursor, /* Cursor position */
+ *lastchar, /* Last character */
+ *limit; /* Max position */
+} el_line_t;
+
+/*
+ * Editor state
+ */
+typedef struct el_state_t {
+ int inputmode; /* What mode are we in? */
+ int doingarg; /* Are we getting an argument? */
+ int argument; /* Numeric argument */
+ int metanext; /* Is the next char a meta char */
+ el_action_t lastcmd; /* Previous command */
+} el_state_t;
+
+/*
+ * Until we come up with something better...
+ */
+#define el_malloc(a) malloc(a)
+#define el_realloc(a,b) realloc(a, b)
+#define el_reallocf(a,b) reallocf(a, b)
+#define el_free(a) free(a)
+
+#include "tty.h"
+#include "prompt.h"
+#include "key.h"
+#include "term.h"
+#include "refresh.h"
+#include "chared.h"
+#include "common.h"
+#include "search.h"
+#include "hist.h"
+#include "map.h"
+#include "parse.h"
+#include "sig.h"
+#include "help.h"
+
+struct editline {
+ char *el_prog; /* the program name */
+ FILE *el_outfile; /* Stdio stuff */
+ FILE *el_errfile; /* Stdio stuff */
+ int el_infd; /* Input file descriptor */
+ int el_flags; /* Various flags. */
+ coord_t el_cursor; /* Cursor location */
+ char **el_display, /* Real screen image = what is there */
+ **el_vdisplay; /* Virtual screen image = what we see */
+
+ el_line_t el_line; /* The current line information */
+ el_state_t el_state; /* Current editor state */
+ el_term_t el_term; /* Terminal dependent stuff */
+ el_tty_t el_tty; /* Tty dependent stuff */
+ el_refresh_t el_refresh; /* Refresh stuff */
+ el_prompt_t el_prompt; /* Prompt stuff */
+ el_chared_t el_chared; /* Characted editor stuff */
+ el_map_t el_map; /* Key mapping stuff */
+ el_key_t el_key; /* Key binding stuff */
+ el_history_t el_history; /* History stuff */
+ el_search_t el_search; /* Search stuff */
+ el_signal_t el_signal; /* Signal handling stuff */
+
+ void *data; /* user data */
+};
+
+#endif /* _h_el */
diff --git a/lib/libedit/emacs.c b/lib/libedit/emacs.c
new file mode 100644
index 0000000..d84c360
--- /dev/null
+++ b/lib/libedit/emacs.c
@@ -0,0 +1,504 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * emacs.c: Emacs functions
+ */
+#include "sys.h"
+#include "el.h"
+
+/* em_delete_or_list():
+ * Delete character under cursor or list completions if at end of line
+ * [^D]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_delete_or_list(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor == el->el_line.lastchar) { /* if I'm at the end */
+ if (el->el_line.cursor == el->el_line.buffer) { /* and the beginning */
+ term_overwrite(el, STReof, 4);/* then do a EOF */
+ term__flush();
+ return CC_EOF;
+ }
+ else {
+ /* Here we could list completions, but it is an error right now */
+ term_beep(el);
+ return CC_ERROR;
+ }
+ }
+ else {
+ c_delafter(el, el->el_state.argument); /* delete after dot */
+ if (el->el_line.cursor > el->el_line.lastchar)
+ el->el_line.cursor = el->el_line.lastchar; /* bounds check */
+ return CC_REFRESH;
+ }
+}
+
+
+/* em_delete_next_word():
+ * Cut from cursor to end of current word
+ * [M-d]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_delete_next_word(el, c)
+ EditLine *el;
+ int c;
+{
+ char *cp, *p, *kp;
+
+ if (el->el_line.cursor == el->el_line.lastchar)
+ return CC_ERROR;
+
+ cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
+ el->el_state.argument, ce__isword);
+
+ for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
+ /* save the text */
+ *kp++ = *p;
+ el->el_chared.c_kill.last = kp;
+
+ c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
+ if (el->el_line.cursor > el->el_line.lastchar)
+ el->el_line.cursor = el->el_line.lastchar; /* bounds check */
+ return CC_REFRESH;
+}
+
+
+/* em_yank():
+ * Paste cut buffer at cursor position
+ * [^Y]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_yank(el, c)
+ EditLine *el;
+ int c;
+{
+ char *kp, *cp;
+
+ if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
+ return CC_ERROR;
+
+ if (el->el_line.lastchar +
+ (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
+ el->el_line.limit)
+ return CC_ERROR;
+
+ el->el_chared.c_kill.mark = el->el_line.cursor;
+ cp = el->el_line.cursor;
+
+ /* open the space, */
+ c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
+ /* copy the chars */
+ for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
+ *cp++ = *kp;
+
+ /* if an arg, cursor at beginning else cursor at end */
+ if (el->el_state.argument == 1)
+ el->el_line.cursor = cp;
+
+ return CC_REFRESH;
+}
+
+
+/* em_kill_line():
+ * Cut the entire line and save in cut buffer
+ * [^U]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_kill_line(el, c)
+ EditLine *el;
+ int c;
+{
+ char *kp, *cp;
+
+ cp = el->el_line.buffer;
+ kp = el->el_chared.c_kill.buf;
+ while (cp < el->el_line.lastchar)
+ *kp++ = *cp++; /* copy it */
+ el->el_chared.c_kill.last = kp;
+ el->el_line.lastchar = el->el_line.buffer; /* zap! -- delete all of it */
+ el->el_line.cursor = el->el_line.buffer;
+ return CC_REFRESH;
+}
+
+
+/* em_kill_region():
+ * Cut area between mark and cursor and save in cut buffer
+ * [^W]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_kill_region(el, c)
+ EditLine *el;
+ int c;
+{
+ char *kp, *cp;
+
+ if (!el->el_chared.c_kill.mark)
+ return CC_ERROR;
+
+ if (el->el_chared.c_kill.mark > el->el_line.cursor) {
+ cp = el->el_line.cursor;
+ kp = el->el_chared.c_kill.buf;
+ while (cp < el->el_chared.c_kill.mark)
+ *kp++ = *cp++; /* copy it */
+ el->el_chared.c_kill.last = kp;
+ c_delafter(el, cp - el->el_line.cursor);
+ }
+ else { /* mark is before cursor */
+ cp = el->el_chared.c_kill.mark;
+ kp = el->el_chared.c_kill.buf;
+ while (cp < el->el_line.cursor)
+ *kp++ = *cp++; /* copy it */
+ el->el_chared.c_kill.last = kp;
+ c_delbefore(el, cp - el->el_chared.c_kill.mark);
+ el->el_line.cursor = el->el_chared.c_kill.mark;
+ }
+ return CC_REFRESH;
+}
+
+
+/* em_copy_region():
+ * Copy area between mark and cursor to cut buffer
+ * [M-W]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_copy_region(el, c)
+ EditLine *el;
+ int c;
+{
+ char *kp, *cp;
+
+ if (el->el_chared.c_kill.mark)
+ return CC_ERROR;
+
+ if (el->el_chared.c_kill.mark > el->el_line.cursor) {
+ cp = el->el_line.cursor;
+ kp = el->el_chared.c_kill.buf;
+ while (cp < el->el_chared.c_kill.mark)
+ *kp++ = *cp++; /* copy it */
+ el->el_chared.c_kill.last = kp;
+ }
+ else {
+ cp = el->el_chared.c_kill.mark;
+ kp = el->el_chared.c_kill.buf;
+ while (cp < el->el_line.cursor)
+ *kp++ = *cp++; /* copy it */
+ el->el_chared.c_kill.last = kp;
+ }
+ return CC_NORM;
+}
+
+
+/* em_gosmacs_traspose():
+ * Exchange the two characters before the cursor
+ * Gosling emacs transpose chars [^T]
+ */
+protected el_action_t
+em_gosmacs_traspose(el, c)
+ EditLine *el;
+ int c;
+{
+
+ if (el->el_line.cursor > &el->el_line.buffer[1]) {
+ /* must have at least two chars entered */
+ c = el->el_line.cursor[-2];
+ el->el_line.cursor[-2] = el->el_line.cursor[-1];
+ el->el_line.cursor[-1] = c;
+ return CC_REFRESH;
+ }
+ else
+ return CC_ERROR;
+}
+
+
+/* em_next_word():
+ * Move next to end of current word
+ * [M-f]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_next_word(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor == el->el_line.lastchar)
+ return CC_ERROR;
+
+ el->el_line.cursor = c__next_word(el->el_line.cursor, el->el_line.lastchar,
+ el->el_state.argument,
+ ce__isword);
+
+ if (el->el_map.type == MAP_VI)
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+
+ return CC_CURSOR;
+}
+
+/* em_upper_case():
+ * Uppercase the characters from cursor to end of current word
+ * [M-u]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_upper_case(el, c)
+ EditLine *el;
+ int c;
+{
+ char *cp, *ep;
+
+ ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
+ el->el_state.argument, ce__isword);
+
+ for (cp = el->el_line.cursor; cp < ep; cp++)
+ if (islower((unsigned char)*cp))
+ *cp = toupper((unsigned char)*cp);
+
+ el->el_line.cursor = ep;
+ if (el->el_line.cursor > el->el_line.lastchar)
+ el->el_line.cursor = el->el_line.lastchar;
+ return CC_REFRESH;
+}
+
+
+/* em_capitol_case():
+ * Capitalize the characters from cursor to end of current word
+ * [M-c]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_capitol_case(el, c)
+ EditLine *el;
+ int c;
+{
+ char *cp, *ep;
+
+ ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
+ el->el_state.argument, ce__isword);
+
+ for (cp = el->el_line.cursor; cp < ep; cp++) {
+ if (isalpha((unsigned char)*cp)) {
+ if (islower((unsigned char)*cp))
+ *cp = toupper((unsigned char)*cp);
+ cp++;
+ break;
+ }
+ }
+ for (; cp < ep; cp++)
+ if (isupper((unsigned char)*cp))
+ *cp = tolower((unsigned char)*cp);
+
+ el->el_line.cursor = ep;
+ if (el->el_line.cursor > el->el_line.lastchar)
+ el->el_line.cursor = el->el_line.lastchar;
+ return CC_REFRESH;
+}
+
+/* em_lower_case():
+ * Lowercase the characters from cursor to end of current word
+ * [M-l]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_lower_case(el, c)
+ EditLine *el;
+ int c;
+{
+ char *cp, *ep;
+
+ ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
+ el->el_state.argument, ce__isword);
+
+ for (cp = el->el_line.cursor; cp < ep; cp++)
+ if (isupper((unsigned char)*cp))
+ *cp = tolower((unsigned char)*cp);
+
+ el->el_line.cursor = ep;
+ if (el->el_line.cursor > el->el_line.lastchar)
+ el->el_line.cursor = el->el_line.lastchar;
+ return CC_REFRESH;
+}
+
+
+/* em_set_mark():
+ * Set the mark at cursor
+ * [^@]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_set_mark(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_chared.c_kill.mark = el->el_line.cursor;
+ return CC_NORM;
+}
+
+
+/* em_exchange_mark():
+ * Exchange the cursor and mark
+ * [^X^X]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_exchange_mark(el, c)
+ EditLine *el;
+ int c;
+{
+ register char *cp;
+
+ cp = el->el_line.cursor;
+ el->el_line.cursor = el->el_chared.c_kill.mark;
+ el->el_chared.c_kill.mark = cp;
+ return CC_CURSOR;
+}
+
+/* em_universal_argument():
+ * Universal argument (argument times 4)
+ * [^U]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_universal_argument(el, c)
+ EditLine *el;
+ int c;
+{ /* multiply current argument by 4 */
+ if (el->el_state.argument > 1000000)
+ return CC_ERROR;
+ el->el_state.doingarg = 1;
+ el->el_state.argument *= 4;
+ return CC_ARGHACK;
+}
+
+/* em_meta_next():
+ * Add 8th bit to next character typed
+ * [<ESC>]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_meta_next(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_state.metanext = 1;
+ return CC_ARGHACK;
+}
+
+
+/* em_toggle_overwrite():
+ * Switch from insert to overwrite mode or vice versa
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_toggle_overwrite(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_state.inputmode =
+ (el->el_state.inputmode == MODE_INSERT) ? MODE_REPLACE : MODE_INSERT;
+ return CC_NORM;
+}
+
+
+/* em_copy_prev_word():
+ * Copy current word to cursor
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_copy_prev_word(el, c)
+ EditLine *el;
+ int c;
+{
+ char *cp, *oldc, *dp;
+
+ if (el->el_line.cursor == el->el_line.buffer)
+ return CC_ERROR;
+
+ oldc = el->el_line.cursor;
+ /* does a bounds check */
+ cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
+ el->el_state.argument, ce__isword);
+
+ c_insert(el, oldc - cp);
+ for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
+ *dp++ = *cp;
+
+ el->el_line.cursor = dp; /* put cursor at end */
+
+ return CC_REFRESH;
+}
+
+
+/* em_inc_search_next():
+ * Emacs incremental next search
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_inc_search_next(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_search.patlen = 0;
+ return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
+}
+
+
+/* em_inc_search_prev():
+ * Emacs incremental reverse search
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_inc_search_prev(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_search.patlen = 0;
+ return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
+}
diff --git a/lib/libedit/hist.c b/lib/libedit/hist.c
new file mode 100644
index 0000000..27dacd1
--- /dev/null
+++ b/lib/libedit/hist.c
@@ -0,0 +1,170 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * hist.c: History access functions
+ */
+#include "sys.h"
+#include <stdlib.h>
+#include "el.h"
+
+/* hist_init():
+ * Initialization function.
+ */
+protected int
+hist_init(el)
+ EditLine *el;
+{
+ el->el_history.fun = NULL;
+ el->el_history.ref = NULL;
+ el->el_history.buf = (char *) el_malloc(EL_BUFSIZ);
+ el->el_history.last = el->el_history.buf;
+ return 0;
+}
+
+
+/* hist_end():
+ * clean up history;
+ */
+protected void
+hist_end(el)
+ EditLine *el;
+{
+ el_free((ptr_t) el->el_history.buf);
+ el->el_history.buf = NULL;
+}
+
+
+/* hist_set():
+ * Set new history interface
+ */
+protected int
+hist_set(el, fun, ptr)
+ EditLine *el;
+ hist_fun_t fun;
+ ptr_t ptr;
+
+{
+ el->el_history.ref = ptr;
+ el->el_history.fun = fun;
+ return 0;
+}
+
+
+/* hist_get():
+ * Get a history line and update it in the buffer.
+ * eventno tells us the event to get.
+ */
+protected el_action_t
+hist_get(el)
+ EditLine *el;
+{
+ const char *hp;
+ int h;
+
+ if (el->el_history.eventno == 0) { /* if really the current line */
+ (void) strncpy(el->el_line.buffer, el->el_history.buf, EL_BUFSIZ);
+ el->el_line.lastchar = el->el_line.buffer +
+ (el->el_history.last - el->el_history.buf);
+
+#ifdef KSHVI
+ if (el->el_map.type == MAP_VI)
+ el->el_line.cursor = el->el_line.buffer;
+ else
+#endif /* KSHVI */
+ el->el_line.cursor = el->el_line.lastchar;
+
+ return CC_REFRESH;
+ }
+
+ if (el->el_history.ref == NULL)
+ return CC_ERROR;
+
+ hp = HIST_FIRST(el);
+
+ if (hp == NULL)
+ return CC_ERROR;
+
+ for (h = 1; h < el->el_history.eventno; h++)
+ if ((hp = HIST_NEXT(el)) == NULL) {
+ el->el_history.eventno = h;
+ return CC_ERROR;
+ }
+
+ (void) strncpy(el->el_line.buffer, hp, EL_BUFSIZ);
+ el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer);
+
+ if (el->el_line.lastchar > el->el_line.buffer) {
+ if (el->el_line.lastchar[-1] == '\n')
+ el->el_line.lastchar--;
+ if (el->el_line.lastchar[-1] == ' ')
+ el->el_line.lastchar--;
+ if (el->el_line.lastchar < el->el_line.buffer)
+ el->el_line.lastchar = el->el_line.buffer;
+ }
+
+#ifdef KSHVI
+ if (el->el_map.type == MAP_VI)
+ el->el_line.cursor = el->el_line.buffer;
+ else
+#endif /* KSHVI */
+ el->el_line.cursor = el->el_line.lastchar;
+
+ return CC_REFRESH;
+}
+
+/* hist_list()
+ * List history entries
+ */
+protected int
+/*ARGSUSED*/
+hist_list(el, argc, argv)
+ EditLine *el;
+ int argc;
+ char **argv;
+{
+ const char *str;
+
+ if (el->el_history.ref == NULL)
+ return -1;
+ for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
+ (void) fprintf(el->el_outfile, "%d %s", el->el_history.ev->num, str);
+ return 0;
+}
diff --git a/lib/libedit/hist.h b/lib/libedit/hist.h
new file mode 100644
index 0000000..3f0fb9e
--- /dev/null
+++ b/lib/libedit/hist.h
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)hist.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.hist.c: History functions
+ */
+#ifndef _h_el_hist
+#define _h_el_hist
+
+#include "histedit.h"
+
+typedef const HistEvent * (*hist_fun_t) __P((ptr_t, int, ...));
+
+typedef struct el_history_t {
+ char *buf; /* The history buffer */
+ char *last; /* The last character */
+ int eventno; /* Event we are looking for */
+ ptr_t ref; /* Argument for history fcns */
+ hist_fun_t fun; /* Event access */
+ const HistEvent *ev; /* Event cookie */
+} el_history_t;
+
+#define HIST_FUN(el, fn, arg) \
+ ((((el)->el_history.ev = \
+ (*(el)->el_history.fun)((el)->el_history.ref, fn, arg)) == NULL) ? \
+ NULL : (el)->el_history.ev->str)
+
+#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL)
+#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL)
+#define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL)
+#define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL)
+#define HIST_EVENT(el, num) HIST_FUN(el, H_EVENT, num)
+#define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname)
+#define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname)
+
+protected int hist_init __P((EditLine *));
+protected void hist_end __P((EditLine *));
+protected el_action_t hist_get __P((EditLine *));
+protected int hist_set __P((EditLine *, hist_fun_t, ptr_t));
+protected int hist_list __P((EditLine *, int, char **));
+
+#endif /* _h_el_hist */
diff --git a/lib/libedit/history.c b/lib/libedit/history.c
new file mode 100644
index 0000000..ac9c3a9
--- /dev/null
+++ b/lib/libedit/history.c
@@ -0,0 +1,685 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * hist.c: History access functions
+ */
+#include "sys.h"
+
+#include <string.h>
+#include <stdlib.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+static const char hist_cookie[] = "_HiStOrY_V1_\n";
+
+#include "histedit.h"
+
+typedef const HistEvent * (*history_gfun_t) __P((ptr_t));
+typedef const HistEvent * (*history_efun_t) __P((ptr_t, const char *));
+typedef void (*history_vfun_t) __P((ptr_t));
+
+struct history {
+ ptr_t h_ref; /* Argument for history fcns */
+ history_gfun_t h_first; /* Get the first element */
+ history_gfun_t h_next; /* Get the next element */
+ history_gfun_t h_last; /* Get the last element */
+ history_gfun_t h_prev; /* Get the previous element */
+ history_gfun_t h_curr; /* Get the current element */
+ history_vfun_t h_clear; /* Clear the history list */
+ history_efun_t h_enter; /* Add an element */
+ history_efun_t h_add; /* Append to an element */
+};
+
+#define HNEXT(h) (*(h)->h_next)((h)->h_ref)
+#define HFIRST(h) (*(h)->h_first)((h)->h_ref)
+#define HPREV(h) (*(h)->h_prev)((h)->h_ref)
+#define HLAST(h) (*(h)->h_last)((h)->h_ref)
+#define HCURR(h) (*(h)->h_curr)((h)->h_ref)
+#define HCLEAR(h) (*(h)->h_clear)((h)->h_ref)
+#define HENTER(h, str) (*(h)->h_enter)((h)->h_ref, str)
+#define HADD(h, str) (*(h)->h_add)((h)->h_ref, str)
+
+#define h_malloc(a) malloc(a)
+#define h_free(a) free(a)
+
+
+private int history_set_num __P((History *, int));
+private int history_set_fun __P((History *, History *));
+private int history_load __P((History *, const char *));
+private int history_save __P((History *, const char *));
+private const HistEvent *history_prev_event __P((History *, int));
+private const HistEvent *history_next_event __P((History *, int));
+private const HistEvent *history_next_string __P((History *, const char *));
+private const HistEvent *history_prev_string __P((History *, const char *));
+
+
+/***********************************************************************/
+
+/*
+ * Builtin- history implementation
+ */
+typedef struct hentry_t {
+ HistEvent ev; /* What we return */
+ struct hentry_t *next; /* Next entry */
+ struct hentry_t *prev; /* Previous entry */
+} hentry_t;
+
+typedef struct history_t {
+ hentry_t list; /* Fake list header element */
+ hentry_t *cursor; /* Current element in the list */
+ int max; /* Maximum number of events */
+ int cur; /* Current number of events */
+ int eventno; /* Current event number */
+} history_t;
+
+private const HistEvent *history_def_first __P((ptr_t));
+private const HistEvent *history_def_last __P((ptr_t));
+private const HistEvent *history_def_next __P((ptr_t));
+private const HistEvent *history_def_prev __P((ptr_t));
+private const HistEvent *history_def_curr __P((ptr_t));
+private const HistEvent *history_def_enter __P((ptr_t, const char *));
+private const HistEvent *history_def_add __P((ptr_t, const char *));
+private void history_def_init __P((ptr_t *, int));
+private void history_def_clear __P((ptr_t));
+private const HistEvent *history_def_insert __P((history_t *, const char *));
+private void history_def_delete __P((history_t *, hentry_t *));
+
+#define history_def_set(p, num) (void) (((history_t *) p)->max = (num))
+
+
+/* history_def_first():
+ * Default function to return the first event in the history.
+ */
+private const HistEvent *
+history_def_first(p)
+ ptr_t p;
+{
+ history_t *h = (history_t *) p;
+ h->cursor = h->list.next;
+ if (h->cursor != &h->list)
+ return &h->cursor->ev;
+ else
+ return NULL;
+}
+
+/* history_def_last():
+ * Default function to return the last event in the history.
+ */
+private const HistEvent *
+history_def_last(p)
+ ptr_t p;
+{
+ history_t *h = (history_t *) p;
+ h->cursor = h->list.prev;
+ if (h->cursor != &h->list)
+ return &h->cursor->ev;
+ else
+ return NULL;
+}
+
+/* history_def_next():
+ * Default function to return the next event in the history.
+ */
+private const HistEvent *
+history_def_next(p)
+ ptr_t p;
+{
+ history_t *h = (history_t *) p;
+
+ if (h->cursor != &h->list)
+ h->cursor = h->cursor->next;
+ else
+ return NULL;
+
+ if (h->cursor != &h->list)
+ return &h->cursor->ev;
+ else
+ return NULL;
+}
+
+
+/* history_def_prev():
+ * Default function to return the previous event in the history.
+ */
+private const HistEvent *
+history_def_prev(p)
+ ptr_t p;
+{
+ history_t *h = (history_t *) p;
+
+ if (h->cursor != &h->list)
+ h->cursor = h->cursor->prev;
+ else
+ return NULL;
+
+ if (h->cursor != &h->list)
+ return &h->cursor->ev;
+ else
+ return NULL;
+}
+
+
+/* history_def_curr():
+ * Default function to return the current event in the history.
+ */
+private const HistEvent *
+history_def_curr(p)
+ ptr_t p;
+{
+ history_t *h = (history_t *) p;
+
+ if (h->cursor != &h->list)
+ return &h->cursor->ev;
+ else
+ return NULL;
+}
+
+
+/* history_def_add():
+ * Append string to element
+ */
+private const HistEvent *
+history_def_add(p, str)
+ ptr_t p;
+ const char *str;
+{
+ history_t *h = (history_t *) p;
+ size_t len;
+ char *s;
+
+ if (h->cursor == &h->list)
+ return (history_def_enter(p, str));
+ len = strlen(h->cursor->ev.str) + strlen(str) + 1;
+ s = (char *) h_malloc(len);
+ (void)strcpy(s, h->cursor->ev.str); /* XXX strcpy is safe */
+ (void)strcat(s, str); /* XXX strcat is safe */
+ h_free((ptr_t) h->cursor->ev.str);
+ h->cursor->ev.str = s;
+ return &h->cursor->ev;
+}
+
+
+/* history_def_delete():
+ * Delete element hp of the h list
+ */
+private void
+history_def_delete(h, hp)
+ history_t *h;
+ hentry_t *hp;
+{
+ if (hp == &h->list)
+ abort();
+ hp->prev->next = hp->next;
+ hp->next->prev = hp->prev;
+ h_free((ptr_t) hp->ev.str);
+ h_free(hp);
+ h->cur--;
+}
+
+
+/* history_def_insert():
+ * Insert element with string str in the h list
+ */
+private const HistEvent *
+history_def_insert(h, str)
+ history_t *h;
+ const char *str;
+{
+ h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
+ h->cursor->ev.str = strdup(str);
+ h->cursor->next = h->list.next;
+ h->cursor->prev = &h->list;
+ h->list.next->prev = h->cursor;
+ h->list.next = h->cursor;
+ h->cur++;
+
+ return &h->cursor->ev;
+}
+
+
+/* history_def_enter():
+ * Default function to enter an item in the history
+ */
+private const HistEvent *
+history_def_enter(p, str)
+ ptr_t p;
+ const char *str;
+{
+ history_t *h = (history_t *) p;
+ const HistEvent *ev;
+
+
+ ev = history_def_insert(h, str);
+ ((HistEvent*) ev)->num = ++h->eventno;
+
+ /*
+ * Always keep at least one entry.
+ * This way we don't have to check for the empty list.
+ */
+ while (h->cur > h->max + 1)
+ history_def_delete(h, h->list.prev);
+ return ev;
+}
+
+
+/* history_def_init():
+ * Default history initialization function
+ */
+private void
+history_def_init(p, n)
+ ptr_t *p;
+ int n;
+{
+ history_t *h = (history_t *) h_malloc(sizeof(history_t));
+ if (n <= 0)
+ n = 0;
+ h->eventno = 0;
+ h->cur = 0;
+ h->max = n;
+ h->list.next = h->list.prev = &h->list;
+ h->list.ev.str = NULL;
+ h->list.ev.num = 0;
+ h->cursor = &h->list;
+ *p = (ptr_t) h;
+}
+
+
+/* history_def_clear():
+ * Default history cleanup function
+ */
+private void
+history_def_clear(p)
+ ptr_t p;
+{
+ history_t *h = (history_t *) p;
+
+ while (h->list.prev != &h->list)
+ history_def_delete(h, h->list.prev);
+ h->eventno = 0;
+ h->cur = 0;
+}
+
+/************************************************************************/
+
+/* history_init():
+ * Initialization function.
+ */
+public History *
+history_init()
+{
+ History *h = (History *) h_malloc(sizeof(History));
+
+ history_def_init(&h->h_ref, 0);
+
+ h->h_next = history_def_next;
+ h->h_first = history_def_first;
+ h->h_last = history_def_last;
+ h->h_prev = history_def_prev;
+ h->h_curr = history_def_curr;
+ h->h_clear = history_def_clear;
+ h->h_enter = history_def_enter;
+ h->h_add = history_def_add;
+
+ return h;
+}
+
+
+/* history_end():
+ * clean up history;
+ */
+public void
+history_end(h)
+ History *h;
+{
+ if (h->h_next == history_def_next)
+ history_def_clear(h->h_ref);
+}
+
+
+
+/* history_set_num():
+ * Set history number of events
+ */
+private int
+history_set_num(h, num)
+ History *h;
+ int num;
+{
+ if (h->h_next != history_def_next || num < 0)
+ return -1;
+ history_def_set(h->h_ref, num);
+ return 0;
+}
+
+
+/* history_set_fun():
+ * Set history functions
+ */
+private int
+history_set_fun(h, nh)
+ History *h, *nh;
+{
+ if (nh->h_first == NULL || nh->h_next == NULL ||
+ nh->h_last == NULL || nh->h_prev == NULL || nh->h_curr == NULL ||
+ nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL ||
+ nh->h_ref == NULL) {
+ if (h->h_next != history_def_next) {
+ history_def_init(&h->h_ref, 0);
+ h->h_first = history_def_first;
+ h->h_next = history_def_next;
+ h->h_last = history_def_last;
+ h->h_prev = history_def_prev;
+ h->h_curr = history_def_curr;
+ h->h_clear = history_def_clear;
+ h->h_enter = history_def_enter;
+ h->h_add = history_def_add;
+ }
+ return -1;
+ }
+
+ if (h->h_next == history_def_next)
+ history_def_clear(h->h_ref);
+
+ h->h_first = nh->h_first;
+ h->h_next = nh->h_next;
+ h->h_last = nh->h_last;
+ h->h_prev = nh->h_prev;
+ h->h_curr = nh->h_curr;
+ h->h_clear = nh->h_clear;
+ h->h_enter = nh->h_enter;
+ h->h_add = nh->h_add;
+ return 0;
+}
+
+
+/* history_load():
+ * History load function
+ */
+private int
+history_load(h, fname)
+ History *h;
+ const char *fname;
+{
+ FILE *fp;
+ char *line;
+ size_t sz;
+ int i = -1;
+
+ if ((fp = fopen(fname, "r")) == NULL)
+ return i;
+
+ if ((line = fgetln(fp, &sz)) == NULL)
+ goto done;
+
+ if (strncmp(line, hist_cookie, sz) != 0)
+ goto done;
+
+ for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) {
+ char c = line[sz];
+ line[sz] = '\0';
+ HENTER(h, line);
+ line[sz] = c;
+ }
+
+done:
+ (void) fclose(fp);
+ return i;
+}
+
+
+/* history_save():
+ * History save function
+ */
+private int
+history_save(h, fname)
+ History *h;
+ const char *fname;
+{
+ FILE *fp;
+ const HistEvent *ev;
+ int i = 0;
+
+ if ((fp = fopen(fname, "w")) == NULL)
+ return -1;
+
+ (void) fputs(hist_cookie, fp);
+ for (ev = HLAST(h); ev != NULL; ev = HPREV(h), i++)
+ (void) fprintf(fp, "%s", ev->str);
+ (void) fclose(fp);
+ return i;
+}
+
+
+/* history_prev_event():
+ * Find the previous event, with number given
+ */
+private const HistEvent *
+history_prev_event(h, num)
+ History *h;
+ int num;
+{
+ const HistEvent *ev;
+ for (ev = HCURR(h); ev != NULL; ev = HPREV(h))
+ if (ev->num == num)
+ return ev;
+ return NULL;
+}
+
+
+/* history_next_event():
+ * Find the next event, with number given
+ */
+private const HistEvent *
+history_next_event(h, num)
+ History *h;
+ int num;
+{
+ const HistEvent *ev;
+ for (ev = HCURR(h); ev != NULL; ev = HNEXT(h))
+ if (ev->num == num)
+ return ev;
+ return NULL;
+}
+
+
+/* history_prev_string():
+ * Find the previous event beginning with string
+ */
+private const HistEvent *
+history_prev_string(h, str)
+ History *h;
+ const char* str;
+{
+ const HistEvent *ev;
+ size_t len = strlen(str);
+
+ for (ev = HCURR(h); ev != NULL; ev = HNEXT(h))
+ if (strncmp(str, ev->str, len) == 0)
+ return ev;
+ return NULL;
+}
+
+
+/* history_next_string():
+ * Find the next event beginning with string
+ */
+private const HistEvent *
+history_next_string(h, str)
+ History *h;
+ const char* str;
+{
+ const HistEvent *ev;
+ size_t len = strlen(str);
+
+ for (ev = HCURR(h); ev != NULL; ev = HPREV(h))
+ if (strncmp(str, ev->str, len) == 0)
+ return ev;
+ return NULL;
+}
+
+
+/* history():
+ * User interface to history functions.
+ */
+const HistEvent *
+#if __STDC__
+history(History *h, int fun, ...)
+#else
+history(va_alist)
+ va_dcl
+#endif
+{
+ va_list va;
+ const HistEvent *ev = NULL;
+ const char *str;
+ static HistEvent sev = { 0, "" };
+
+#if __STDC__
+ va_start(va, fun);
+#else
+ History *h;
+ int fun;
+ va_start(va);
+ h = va_arg(va, History *);
+ fun = va_arg(va, int);
+#endif
+
+ switch (fun) {
+ case H_ADD:
+ str = va_arg(va, const char *);
+ ev = HADD(h, str);
+ break;
+
+ case H_ENTER:
+ str = va_arg(va, const char *);
+ ev = HENTER(h, str);
+ break;
+
+ case H_FIRST:
+ ev = HFIRST(h);
+ break;
+
+ case H_NEXT:
+ ev = HNEXT(h);
+ break;
+
+ case H_LAST:
+ ev = HLAST(h);
+ break;
+
+ case H_PREV:
+ ev = HPREV(h);
+ break;
+
+ case H_CURR:
+ ev = HCURR(h);
+ break;
+
+ case H_CLEAR:
+ HCLEAR(h);
+ break;
+
+ case H_LOAD:
+ sev.num = history_load(h, va_arg(va, const char *));
+ ev = &sev;
+ break;
+
+ case H_SAVE:
+ sev.num = history_save(h, va_arg(va, const char *));
+ ev = &sev;
+ break;
+
+ case H_PREV_EVENT:
+ ev = history_prev_event(h, va_arg(va, int));
+ break;
+
+ case H_NEXT_EVENT:
+ ev = history_next_event(h, va_arg(va, int));
+ break;
+
+ case H_PREV_STR:
+ ev = history_prev_string(h, va_arg(va, const char*));
+ break;
+
+ case H_NEXT_STR:
+ ev = history_next_string(h, va_arg(va, const char*));
+ break;
+
+ case H_EVENT:
+ if (history_set_num(h, va_arg(va, int)) == 0) {
+ sev.num = -1;
+ ev = &sev;
+ }
+ break;
+
+ case H_FUNC:
+ {
+ History hf;
+ hf.h_ref = va_arg(va, ptr_t);
+ hf.h_first = va_arg(va, history_gfun_t);
+ hf.h_next = va_arg(va, history_gfun_t);
+ hf.h_last = va_arg(va, history_gfun_t);
+ hf.h_prev = va_arg(va, history_gfun_t);
+ hf.h_curr = va_arg(va, history_gfun_t);
+ hf.h_clear = va_arg(va, history_vfun_t);
+ hf.h_enter = va_arg(va, history_efun_t);
+ hf.h_add = va_arg(va, history_efun_t);
+
+ if (history_set_fun(h, &hf) == 0) {
+ sev.num = -1;
+ ev = &sev;
+ }
+ }
+ break;
+
+ case H_END:
+ history_end(h);
+ break;
+
+ default:
+ break;
+ }
+ va_end(va);
+ return ev;
+}
diff --git a/lib/libedit/key.c b/lib/libedit/key.c
new file mode 100644
index 0000000..3da65d5
--- /dev/null
+++ b/lib/libedit/key.c
@@ -0,0 +1,728 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * key.c: This module contains the procedures for maintaining
+ * the extended-key map.
+ *
+ * An extended-key (key) is a sequence of keystrokes introduced
+ * with an sequence introducer and consisting of an arbitrary
+ * number of characters. This module maintains a map (the el->el_key.map)
+ * to convert these extended-key sequences into input strs
+ * (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE).
+ *
+ * Warning:
+ * If key is a substr of some other keys, then the longer
+ * keys are lost!! That is, if the keys "abcd" and "abcef"
+ * are in el->el_key.map, adding the key "abc" will cause the first two
+ * definitions to be lost.
+ *
+ * Restrictions:
+ * -------------
+ * 1) It is not possible to have one key that is a
+ * substr of another.
+ */
+#include "sys.h"
+#include <string.h>
+#include <stdlib.h>
+
+#include "el.h"
+
+/*
+ * The Nodes of the el->el_key.map. The el->el_key.map is a linked list
+ * of these node elements
+ */
+struct key_node_t {
+ char ch; /* single character of key */
+ int type; /* node type */
+ key_value_t val; /* command code or pointer to str, */
+ /* if this is a leaf */
+ struct key_node_t *next; /* ptr to next char of this key */
+ struct key_node_t *sibling; /* ptr to another key with same prefix */
+};
+
+private int node_trav __P((EditLine *, key_node_t *, char *,
+ key_value_t *));
+private int node__try __P((key_node_t *, char *,
+ key_value_t *, int));
+private key_node_t *node__get __P((int));
+private void node__put __P((key_node_t *));
+private int node__delete __P((key_node_t **, char *));
+private int node_lookup __P((EditLine *, char *, key_node_t *,
+ int));
+private int node_enum __P((EditLine *, key_node_t *, int));
+private int key__decode_char __P((char *, int, int));
+
+#define KEY_BUFSIZ EL_BUFSIZ
+
+
+/* key_init():
+ * Initialize the key maps
+ */
+protected int
+key_init(el)
+ EditLine *el;
+{
+ el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ);
+ el->el_key.map = NULL;
+ key_reset(el);
+ return 0;
+}
+
+
+/* key_end():
+ * Free the key maps
+ */
+protected void
+key_end(el)
+ EditLine *el;
+{
+ el_free((ptr_t) el->el_key.buf);
+ el->el_key.buf = NULL;
+ /* XXX: provide a function to clear the keys */
+ el->el_key.map = NULL;
+}
+
+
+/* key_map_cmd():
+ * Associate cmd with a key value
+ */
+protected key_value_t *
+key_map_cmd(el, cmd)
+ EditLine *el;
+ int cmd;
+{
+ el->el_key.val.cmd = (el_action_t) cmd;
+ return &el->el_key.val;
+}
+
+
+/* key_map_str():
+ * Associate str with a key value
+ */
+protected key_value_t *
+key_map_str(el, str)
+ EditLine *el;
+ char *str;
+{
+ el->el_key.val.str = str;
+ return &el->el_key.val;
+}
+
+
+/* key_reset():
+ * Takes all nodes on el->el_key.map and puts them on free list. Then
+ * initializes el->el_key.map with arrow keys
+ * [Always bind the ansi arrow keys?]
+ */
+protected void
+key_reset(el)
+ EditLine *el;
+{
+ node__put(el->el_key.map);
+ el->el_key.map = NULL;
+ return;
+}
+
+
+/* key_get():
+ * Calls the recursive function with entry point el->el_key.map
+ * Looks up *ch in map and then reads characters until a
+ * complete match is found or a mismatch occurs. Returns the
+ * type of the match found (XK_STR, XK_CMD, or XK_EXE).
+ * Returns NULL in val.str and XK_STR for no match.
+ * The last character read is returned in *ch.
+ */
+protected int
+key_get(el, ch, val)
+ EditLine *el;
+ char *ch;
+ key_value_t *val;
+{
+ return node_trav(el, el->el_key.map, ch, val);
+}
+
+
+
+/* key_add():
+ * Adds key to the el->el_key.map and associates the value in val with it.
+ * If key is already is in el->el_key.map, the new code is applied to the
+ * existing key. Ntype specifies if code is a command, an
+ * out str or a unix command.
+ */
+protected void
+key_add(el, key, val, ntype)
+ EditLine *el;
+ char *key;
+ key_value_t *val;
+ int ntype;
+{
+ if (key[0] == '\0') {
+ (void) fprintf(el->el_errfile,
+ "key_add: Null extended-key not allowed.\n");
+ return;
+ }
+
+ if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) {
+ (void) fprintf(el->el_errfile,
+ "key_add: sequence-lead-in command not allowed\n");
+ return;
+ }
+
+ if (el->el_key.map == NULL)
+ /* tree is initially empty. Set up new node to match key[0] */
+ el->el_key.map = node__get(key[0]); /* it is properly initialized */
+
+ /* Now recurse through el->el_key.map */
+ (void) node__try(el->el_key.map, key, val, ntype);
+ return;
+}
+
+
+/* key_clear():
+ *
+ */
+protected void
+key_clear(el, map, in)
+ EditLine *el;
+ el_action_t *map;
+ char *in;
+{
+ if ((map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN) &&
+ ((map == el->el_map.key &&
+ el->el_map.alt[(unsigned char) *in] != ED_SEQUENCE_LEAD_IN) ||
+ (map == el->el_map.alt &&
+ el->el_map.key[(unsigned char) *in] != ED_SEQUENCE_LEAD_IN)))
+ (void) key_delete(el, in);
+}
+
+
+/* key_delete():
+ * Delete the key and all longer keys staring with key, if
+ * they exists.
+ */
+protected int
+key_delete(el, key)
+ EditLine *el;
+ char *key;
+{
+ if (key[0] == '\0') {
+ (void) fprintf(el->el_errfile,
+ "key_delete: Null extended-key not allowed.\n");
+ return -1;
+ }
+
+ if (el->el_key.map == NULL)
+ return 0;
+
+ (void) node__delete(&el->el_key.map, key);
+ return 0;
+}
+
+
+/* key_print():
+ * Print the binding associated with key key.
+ * Print entire el->el_key.map if null
+ */
+protected void
+key_print(el, key)
+ EditLine *el;
+ char *key;
+{
+ /* do nothing if el->el_key.map is empty and null key specified */
+ if (el->el_key.map == NULL && *key == 0)
+ return;
+
+ el->el_key.buf[0] = '"';
+ if (node_lookup(el, key, el->el_key.map, 1) <= -1)
+ /* key is not bound */
+ (void) fprintf(el->el_errfile, "Unbound extended key \"%s\"\n", key);
+ return;
+}
+
+
+/* node_trav():
+ * recursively traverses node in tree until match or mismatch is
+ * found. May read in more characters.
+ */
+private int
+node_trav(el, ptr, ch, val)
+ EditLine *el;
+ key_node_t *ptr;
+ char *ch;
+ key_value_t *val;
+{
+ if (ptr->ch == *ch) {
+ /* match found */
+ if (ptr->next) {
+ /* key not complete so get next char */
+ if (el_getc(el, ch) != 1) { /* if EOF or error */
+ val->cmd = ED_END_OF_FILE;
+ return XK_CMD;/* PWP: Pretend we just read an end-of-file */
+ }
+ return node_trav(el, ptr->next, ch, val);
+ }
+ else {
+ *val = ptr->val;
+ if (ptr->type != XK_CMD)
+ *ch = '\0';
+ return ptr->type;
+ }
+ }
+ else {
+ /* no match found here */
+ if (ptr->sibling) {
+ /* try next sibling */
+ return node_trav(el, ptr->sibling, ch, val);
+ }
+ else {
+ /* no next sibling -- mismatch */
+ val->str = NULL;
+ return XK_STR;
+ }
+ }
+}
+
+
+/* node__try():
+ * Find a node that matches *str or allocate a new one
+ */
+private int
+node__try(ptr, str, val, ntype)
+ key_node_t *ptr;
+ char *str;
+ key_value_t *val;
+ int ntype;
+{
+ if (ptr->ch != *str) {
+ key_node_t *xm;
+
+ for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
+ if (xm->sibling->ch == *str)
+ break;
+ if (xm->sibling == NULL)
+ xm->sibling = node__get(*str); /* setup new node */
+ ptr = xm->sibling;
+ }
+
+ if (*++str == '\0') {
+ /* we're there */
+ if (ptr->next != NULL) {
+ node__put(ptr->next); /* lose longer keys with this prefix */
+ ptr->next = NULL;
+ }
+ switch (ptr->type) {
+ case XK_CMD:
+ case XK_NOD:
+ break;
+ case XK_STR:
+ case XK_EXE:
+ if (ptr->val.str)
+ el_free((ptr_t) ptr->val.str);
+ break;
+ default:
+ abort();
+ break;
+ }
+
+ switch (ptr->type = ntype) {
+ case XK_CMD:
+ ptr->val = *val;
+ break;
+ case XK_STR:
+ case XK_EXE:
+ ptr->val.str = strdup(val->str);
+ break;
+ default:
+ abort();
+ break;
+ }
+ }
+ else {
+ /* still more chars to go */
+ if (ptr->next == NULL)
+ ptr->next = node__get(*str); /* setup new node */
+ (void) node__try(ptr->next, str, val, ntype);
+ }
+ return 0;
+}
+
+
+/* node__delete():
+ * Delete node that matches str
+ */
+private int
+node__delete(inptr, str)
+ key_node_t **inptr;
+ char *str;
+{
+ key_node_t *ptr;
+ key_node_t *prev_ptr = NULL;
+
+ ptr = *inptr;
+
+ if (ptr->ch != *str) {
+ key_node_t *xm;
+
+ for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
+ if (xm->sibling->ch == *str)
+ break;
+ if (xm->sibling == NULL)
+ return 0;
+ prev_ptr = xm;
+ ptr = xm->sibling;
+ }
+
+ if (*++str == '\0') {
+ /* we're there */
+ if (prev_ptr == NULL)
+ *inptr = ptr->sibling;
+ else
+ prev_ptr->sibling = ptr->sibling;
+ ptr->sibling = NULL;
+ node__put(ptr);
+ return 1;
+ }
+ else if (ptr->next != NULL && node__delete(&ptr->next, str) == 1) {
+ if (ptr->next != NULL)
+ return 0;
+ if (prev_ptr == NULL)
+ *inptr = ptr->sibling;
+ else
+ prev_ptr->sibling = ptr->sibling;
+ ptr->sibling = NULL;
+ node__put(ptr);
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+/* node__put():
+ * Puts a tree of nodes onto free list using free(3).
+ */
+private void
+node__put(ptr)
+ key_node_t *ptr;
+{
+ if (ptr == NULL)
+ return;
+
+ if (ptr->next != NULL) {
+ node__put(ptr->next);
+ ptr->next = NULL;
+ }
+
+ node__put(ptr->sibling);
+
+ switch (ptr->type) {
+ case XK_CMD:
+ case XK_NOD:
+ break;
+ case XK_EXE:
+ case XK_STR:
+ if (ptr->val.str != NULL)
+ el_free((ptr_t) ptr->val.str);
+ break;
+ default:
+ abort();
+ break;
+ }
+ el_free((ptr_t) ptr);
+}
+
+
+/* node__get():
+ * Returns pointer to an key_node_t for ch.
+ */
+private key_node_t *
+node__get(ch)
+ int ch;
+{
+ key_node_t *ptr;
+
+ ptr = (key_node_t *) el_malloc((size_t) sizeof(key_node_t));
+ ptr->ch = ch;
+ ptr->type = XK_NOD;
+ ptr->val.str = NULL;
+ ptr->next = NULL;
+ ptr->sibling = NULL;
+ return ptr;
+}
+
+
+
+/* node_lookup():
+ * look for the str starting at node ptr.
+ * Print if last node
+ */
+private int
+node_lookup(el, str, ptr, cnt)
+ EditLine *el;
+ char *str;
+ key_node_t *ptr;
+ int cnt;
+{
+ int ncnt;
+
+ if (ptr == NULL)
+ return -1; /* cannot have null ptr */
+
+ if (*str == 0) {
+ /* no more chars in str. node_enum from here. */
+ (void) node_enum(el, ptr, cnt);
+ return 0;
+ }
+ else {
+ /* If match put this char into el->el_key.buf. Recurse */
+ if (ptr->ch == *str) {
+ /* match found */
+ ncnt = key__decode_char(el->el_key.buf, cnt,
+ (unsigned char) ptr->ch);
+ if (ptr->next != NULL)
+ /* not yet at leaf */
+ return node_lookup(el, str + 1, ptr->next, ncnt + 1);
+ else {
+ /* next node is null so key should be complete */
+ if (str[1] == 0) {
+ el->el_key.buf[ncnt + 1] = '"';
+ el->el_key.buf[ncnt + 2] = '\0';
+ key_kprint(el, el->el_key.buf, &ptr->val, ptr->type);
+ return 0;
+ }
+ else
+ return -1;/* mismatch -- str still has chars */
+ }
+ }
+ else {
+ /* no match found try sibling */
+ if (ptr->sibling)
+ return node_lookup(el, str, ptr->sibling, cnt);
+ else
+ return -1;
+ }
+ }
+}
+
+
+/* node_enum():
+ * Traverse the node printing the characters it is bound in buffer
+ */
+private int
+node_enum(el, ptr, cnt)
+ EditLine *el;
+ key_node_t *ptr;
+ int cnt;
+{
+ int ncnt;
+
+ if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */
+ el->el_key.buf[++cnt] = '"';
+ el->el_key.buf[++cnt] = '\0';
+ (void) fprintf(el->el_errfile,
+ "Some extended keys too long for internal print buffer");
+ (void) fprintf(el->el_errfile, " \"%s...\"\n", el->el_key.buf);
+ return 0;
+ }
+
+ if (ptr == NULL) {
+#ifdef DEBUG_EDIT
+ (void) fprintf(el->el_errfile, "node_enum: BUG!! Null ptr passed\n!");
+#endif
+ return -1;
+ }
+
+ /* put this char at end of str */
+ ncnt = key__decode_char(el->el_key.buf, cnt, (unsigned char) ptr->ch);
+ if (ptr->next == NULL) {
+ /* print this key and function */
+ el->el_key.buf[ncnt + 1] = '"';
+ el->el_key.buf[ncnt + 2] = '\0';
+ key_kprint(el, el->el_key.buf, &ptr->val, ptr->type);
+ }
+ else
+ (void) node_enum(el, ptr->next, ncnt + 1);
+
+ /* go to sibling if there is one */
+ if (ptr->sibling)
+ (void) node_enum(el, ptr->sibling, cnt);
+ return 0;
+}
+
+
+/* key_kprint():
+ * Print the specified key and its associated
+ * function specified by val
+ */
+protected void
+key_kprint(el, key, val, ntype)
+ EditLine *el;
+ char *key;
+ key_value_t *val;
+ int ntype;
+{
+ el_bindings_t *fp;
+ char unparsbuf[EL_BUFSIZ];
+ static char *fmt = "%-15s-> %s\n";
+
+ if (val != NULL)
+ switch (ntype) {
+ case XK_STR:
+ case XK_EXE:
+ (void) fprintf(el->el_errfile, fmt, key,
+ key__decode_str(val->str, unparsbuf,
+ ntype == XK_STR ? "\"\"" : "[]"));
+ break;
+ case XK_CMD:
+ for (fp = el->el_map.help; fp->name; fp++)
+ if (val->cmd == fp->func) {
+ (void) fprintf(el->el_errfile, fmt, key, fp->name);
+ break;
+ }
+#ifdef DEBUG_KEY
+ if (fp->name == NULL)
+ (void) fprintf(el->el_errfile, "BUG! Command not found.\n");
+#endif
+
+ break;
+ default:
+ abort();
+ break;
+ }
+ else
+ (void) fprintf(el->el_errfile, fmt, key, "no input");
+}
+
+
+/* key__decode_char():
+ * Put a printable form of char in buf.
+ */
+private int
+key__decode_char(buf, cnt, ch)
+ char *buf;
+ int cnt, ch;
+{
+ ch = (unsigned char)ch;
+
+ if (ch == 0) {
+ buf[cnt++] = '^';
+ buf[cnt] = '@';
+ return cnt;
+ }
+
+ if (iscntrl(ch)) {
+ buf[cnt++] = '^';
+ if (ch == 0177)
+ buf[cnt] = '?';
+ else
+ buf[cnt] = toascii(ch) | 0100;
+ }
+ else if (ch == '^') {
+ buf[cnt++] = '\\';
+ buf[cnt] = '^';
+ }
+ else if (ch == '\\') {
+ buf[cnt++] = '\\';
+ buf[cnt] = '\\';
+ }
+ else if (ch == ' ' || (isprint(ch) && !isspace(ch))) {
+ buf[cnt] = ch;
+ }
+ else {
+ buf[cnt++] = '\\';
+ buf[cnt++] = ((ch >> 6) & 7) + '0';
+ buf[cnt++] = ((ch >> 3) & 7) + '0';
+ buf[cnt] = (ch & 7) + '0';
+ }
+ return cnt;
+}
+
+/* key__decode_str():
+ * Make a printable version of the ey
+ */
+protected char *
+key__decode_str(str, buf, sep)
+ char *str;
+ char *buf;
+ char *sep;
+{
+ char *b, *p;
+
+ b = buf;
+ if (sep[0] != '\0')
+ *b++ = sep[0];
+ if (*str == 0) {
+ *b++ = '^';
+ *b++ = '@';
+ if (sep[0] != '\0' && sep[1] != '\0')
+ *b++ = sep[1];
+ *b++ = 0;
+ return buf;
+ }
+
+ for (p = str; *p != 0; p++) {
+ if (iscntrl((unsigned char) *p)) {
+ *b++ = '^';
+ if (*p == '\177')
+ *b++ = '?';
+ else
+ *b++ = toascii(*p) | 0100;
+ }
+ else if (*p == '^' || *p == '\\') {
+ *b++ = '\\';
+ *b++ = *p;
+ }
+ else if (*p == ' ' || (isprint((unsigned char) *p) &&
+ !isspace((unsigned char) *p))) {
+ *b++ = *p;
+ }
+ else {
+ *b++ = '\\';
+ *b++ = ((*p >> 6) & 7) + '0';
+ *b++ = ((*p >> 3) & 7) + '0';
+ *b++ = (*p & 7) + '0';
+ }
+ }
+ if (sep[0] != '\0' && sep[1] != '\0')
+ *b++ = sep[1];
+ *b++ = 0;
+ return buf; /* should check for overflow */
+}
diff --git a/lib/libedit/key.h b/lib/libedit/key.h
new file mode 100644
index 0000000..eed0818
--- /dev/null
+++ b/lib/libedit/key.h
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)key.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.key.h: Key macro header
+ */
+#ifndef _h_el_key
+#define _h_el_key
+
+typedef union key_value_t {
+ el_action_t cmd; /* If it is a command the # */
+ char *str; /* If it is a string... */
+} key_value_t;
+
+typedef struct key_node_t key_node_t;
+
+typedef struct el_key_t {
+ char *buf; /* Key print buffer */
+ key_node_t *map; /* Key map */
+ key_value_t val; /* Local conversion buffer */
+} el_key_t;
+
+#define XK_CMD 0
+#define XK_STR 1
+#define XK_NOD 2
+#define XK_EXE 3
+
+protected int key_init __P((EditLine *));
+protected void key_end __P((EditLine *));
+protected key_value_t * key_map_cmd __P((EditLine *, int));
+protected key_value_t * key_map_str __P((EditLine *, char *));
+protected void key_reset __P((EditLine *));
+protected int key_get __P((EditLine *, char *,
+ key_value_t *));
+protected void key_add __P((EditLine *, char *, key_value_t *,
+ int));
+protected void key_clear __P((EditLine *, el_action_t *,
+ char *));
+protected int key_delete __P((EditLine *, char *));
+protected void key_print __P((EditLine *, char *));
+protected void key_kprint __P((EditLine *, char *,
+ key_value_t *, int));
+protected char *key__decode_str __P((char *, char *, char *));
+
+#endif /* _h_el_key */
diff --git a/lib/libedit/makelist b/lib/libedit/makelist
new file mode 100644
index 0000000..a2c54e0
--- /dev/null
+++ b/lib/libedit/makelist
@@ -0,0 +1,188 @@
+#!/bin/sh -
+#
+# Copyright (c) 1992, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# This code is derived from software contributed to Berkeley by
+# Christos Zoulas of Cornell University.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# @(#)makelist 5.3 (Berkeley) 6/4/93
+
+# makelist.sh: Automatically generate header files...
+
+AWK=awk
+USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh <filenames>"
+
+if [ "x$1" = "x" ]
+then
+ echo $USAGE 1>&2
+ exit 1
+fi
+
+FLAG="$1"
+shift
+
+FILES="$@"
+
+case $FLAG in
+-h)
+ fn=`basename $FILES`
+ OIFS="$IFS"
+ IFS=".$IFS"
+ set - $fn
+ IFS="$OIFS"
+ hdr="_h_$1_$2"
+ cat $FILES | $AWK '
+ BEGIN {
+ printf("/* Automatically generated file, do not edit */\n");
+ printf("#ifndef %s\n#define %s\n", "'$hdr'", "'$hdr'");
+ }
+ /\(\):/ {
+ pr = substr($2, 1, 2);
+ if (pr == "vi" || pr == "em" || pr == "ed") {
+ name = substr($2, 1, length($2) - 3);
+ printf("protected el_action_t\t%-25.25s __P((EditLine *, int));\n", name);
+ }
+ }
+ END {
+ printf("#endif /* %s */\n", "'$hdr'");
+ }';;
+-bc)
+ cat $FILES | $AWK '
+ BEGIN {
+ printf("/* Automatically generated file, do not edit */\n");
+ printf("#include \"sys.h\"\n#include \"el.h\"\n");
+ printf("private struct el_bindings_t el_func_help[] = {\n");
+ low = "abcdefghijklmnopqrstuvwxyz_";
+ high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
+ for (i = 1; i <= length(low); i++)
+ tr[substr(low, i, 1)] = substr(high, i, 1);
+ }
+ /\(\):/ {
+ pr = substr($2, 1, 2);
+ if (pr == "vi" || pr == "em" || pr == "ed") {
+ name = substr($2, 1, length($2) - 3);
+ uname = "";
+ fname = "";
+ for (i = 1; i <= length(name); i++) {
+ s = substr(name, i, 1);
+ uname = uname tr[s];
+ if (s == "_")
+ s = "-";
+ fname = fname s;
+ }
+
+ printf(" { %-30.30s %-30.30s\n","\"" fname "\",", uname ",");
+ ok = 1;
+ }
+ }
+ /^ \*/ {
+ if (ok) {
+ printf(" \"");
+ for (i = 2; i < NF; i++)
+ printf("%s ", $i);
+ printf("%s\" },\n", $i);
+ ok = 0;
+ }
+ }
+ END {
+ printf(" { NULL, 0, NULL }\n");
+ printf("};\n");
+ printf("\nprotected el_bindings_t* help__get()");
+ printf("{ return el_func_help; }\n");
+ }';;
+-bh)
+ $AWK '
+ BEGIN {
+ printf("/* Automatically generated file, do not edit */\n");
+ printf("#ifndef _h_help_c\n#define _h_help_c\n");
+ printf("protected el_bindings_t *help__get\t__P((void));\n");
+ printf("#endif /* _h_help_c */\n");
+ }' /dev/null;;
+-fh)
+ cat $FILES | $AWK '/el_action_t/ { print $3 }' | \
+ sort | tr '[a-z]' '[A-Z]' | $AWK '
+ BEGIN {
+ printf("/* Automatically generated file, do not edit */\n");
+ printf("#ifndef _h_fcns_c\n#define _h_fcns_c\n");
+ count = 0;
+ }
+ {
+ printf("#define\t%-30.30s\t%3d\n", $1, count++);
+ }
+ END {
+ printf("#define\t%-30.30s\t%3d\n", "EL_NUM_FCNS", count);
+
+ printf("typedef el_action_t (*el_func_t) __P((EditLine *, int));");
+ printf("\nprotected el_func_t* func__get __P((void));\n");
+ printf("#endif /* _h_fcns_c */\n");
+ }';;
+-fc)
+ cat $FILES | $AWK '/el_action_t/ { print $3 }' | sort | $AWK '
+ BEGIN {
+ printf("/* Automatically generated file, do not edit */\n");
+ printf("#include \"sys.h\"\n#include \"el.h\"\n");
+ printf("private el_func_t el_func[] = {");
+ maxlen = 80;
+ needn = 1;
+ len = 0;
+ }
+ {
+ clen = 25 + 2;
+ len += clen;
+ if (len >= maxlen)
+ needn = 1;
+ if (needn) {
+ printf("\n ");
+ needn = 0;
+ len = 4 + clen;
+ }
+ s = $1 ",";
+ printf("%-26.26s ", s);
+ }
+ END {
+ printf("\n};\n");
+ printf("\nprotected el_func_t* func__get() { return el_func; }\n");
+ }';;
+-e)
+ echo "$FILES" | tr ' ' '\012' | $AWK '
+ BEGIN {
+ printf("/* Automatically generated file, do not edit */\n");
+ printf("#define protected static\n");
+ printf("#define SCCSID\n");
+ }
+ {
+ printf("#include \"%s\"\n", $1);
+ }';;
+*)
+ echo $USAGE 1>&2
+ exit 1;;
+esac
diff --git a/lib/libedit/map.c b/lib/libedit/map.c
new file mode 100644
index 0000000..4b940d4
--- /dev/null
+++ b/lib/libedit/map.c
@@ -0,0 +1,1397 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * map.c: Editor function definitions
+ */
+#include "sys.h"
+#include <stdlib.h>
+#include "el.h"
+
+#define N_KEYS 256
+
+private void map_print_key __P((EditLine *, el_action_t *, char *));
+private void map_print_some_keys __P((EditLine *, el_action_t *, int, int));
+private void map_print_all_keys __P((EditLine *));
+private void map_init_nls __P((EditLine *));
+private void map_init_meta __P((EditLine *));
+
+/* keymap tables ; should be N_KEYS*sizeof(KEYCMD) bytes long */
+
+private el_action_t el_map_emacs[] = {
+ /* 0 */ EM_SET_MARK, /* ^@ */
+ /* 1 */ ED_MOVE_TO_BEG, /* ^A */
+ /* 2 */ ED_PREV_CHAR, /* ^B */
+ /* 3 */ ED_TTY_SIGINT, /* ^C */
+ /* 4 */ EM_DELETE_OR_LIST, /* ^D */
+ /* 5 */ ED_MOVE_TO_END, /* ^E */
+ /* 6 */ ED_NEXT_CHAR, /* ^F */
+ /* 7 */ ED_UNASSIGNED, /* ^G */
+ /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */
+ /* 9 */ ED_UNASSIGNED, /* ^I */
+ /* 10 */ ED_NEWLINE, /* ^J */
+ /* 11 */ ED_KILL_LINE, /* ^K */
+ /* 12 */ ED_CLEAR_SCREEN, /* ^L */
+ /* 13 */ ED_NEWLINE, /* ^M */
+ /* 14 */ ED_NEXT_HISTORY, /* ^N */
+ /* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */
+ /* 16 */ ED_PREV_HISTORY, /* ^P */
+ /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
+ /* 18 */ ED_REDISPLAY, /* ^R */
+ /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
+ /* 20 */ ED_TRANSPOSE_CHARS, /* ^T */
+ /* 21 */ EM_KILL_LINE, /* ^U */
+ /* 22 */ ED_QUOTED_INSERT, /* ^V */
+ /* 23 */ EM_KILL_REGION, /* ^W */
+ /* 24 */ ED_SEQUENCE_LEAD_IN, /* ^X */
+ /* 25 */ EM_YANK, /* ^Y */
+ /* 26 */ ED_TTY_SIGTSTP, /* ^Z */
+ /* 27 */ EM_META_NEXT, /* ^[ */
+ /* 28 */ ED_TTY_SIGQUIT, /* ^\ */
+ /* 29 */ ED_TTY_DSUSP, /* ^] */
+ /* 30 */ ED_UNASSIGNED, /* ^^ */
+ /* 31 */ ED_UNASSIGNED, /* ^_ */
+ /* 32 */ ED_INSERT, /* SPACE */
+ /* 33 */ ED_INSERT, /* ! */
+ /* 34 */ ED_INSERT, /* " */
+ /* 35 */ ED_INSERT, /* # */
+ /* 36 */ ED_INSERT, /* $ */
+ /* 37 */ ED_INSERT, /* % */
+ /* 38 */ ED_INSERT, /* & */
+ /* 39 */ ED_INSERT, /* ' */
+ /* 40 */ ED_INSERT, /* ( */
+ /* 41 */ ED_INSERT, /* ) */
+ /* 42 */ ED_INSERT, /* * */
+ /* 43 */ ED_INSERT, /* + */
+ /* 44 */ ED_INSERT, /* , */
+ /* 45 */ ED_INSERT, /* - */
+ /* 46 */ ED_INSERT, /* . */
+ /* 47 */ ED_INSERT, /* / */
+ /* 48 */ ED_DIGIT, /* 0 */
+ /* 49 */ ED_DIGIT, /* 1 */
+ /* 50 */ ED_DIGIT, /* 2 */
+ /* 51 */ ED_DIGIT, /* 3 */
+ /* 52 */ ED_DIGIT, /* 4 */
+ /* 53 */ ED_DIGIT, /* 5 */
+ /* 54 */ ED_DIGIT, /* 6 */
+ /* 55 */ ED_DIGIT, /* 7 */
+ /* 56 */ ED_DIGIT, /* 8 */
+ /* 57 */ ED_DIGIT, /* 9 */
+ /* 58 */ ED_INSERT, /* : */
+ /* 59 */ ED_INSERT, /* ; */
+ /* 60 */ ED_INSERT, /* < */
+ /* 61 */ ED_INSERT, /* = */
+ /* 62 */ ED_INSERT, /* > */
+ /* 63 */ ED_INSERT, /* ? */
+ /* 64 */ ED_INSERT, /* @ */
+ /* 65 */ ED_INSERT, /* A */
+ /* 66 */ ED_INSERT, /* B */
+ /* 67 */ ED_INSERT, /* C */
+ /* 68 */ ED_INSERT, /* D */
+ /* 69 */ ED_INSERT, /* E */
+ /* 70 */ ED_INSERT, /* F */
+ /* 71 */ ED_INSERT, /* G */
+ /* 72 */ ED_INSERT, /* H */
+ /* 73 */ ED_INSERT, /* I */
+ /* 74 */ ED_INSERT, /* J */
+ /* 75 */ ED_INSERT, /* K */
+ /* 76 */ ED_INSERT, /* L */
+ /* 77 */ ED_INSERT, /* M */
+ /* 78 */ ED_INSERT, /* N */
+ /* 79 */ ED_INSERT, /* O */
+ /* 80 */ ED_INSERT, /* P */
+ /* 81 */ ED_INSERT, /* Q */
+ /* 82 */ ED_INSERT, /* R */
+ /* 83 */ ED_INSERT, /* S */
+ /* 84 */ ED_INSERT, /* T */
+ /* 85 */ ED_INSERT, /* U */
+ /* 86 */ ED_INSERT, /* V */
+ /* 87 */ ED_INSERT, /* W */
+ /* 88 */ ED_INSERT, /* X */
+ /* 89 */ ED_INSERT, /* Y */
+ /* 90 */ ED_INSERT, /* Z */
+ /* 91 */ ED_INSERT, /* [ */
+ /* 92 */ ED_INSERT, /* \ */
+ /* 93 */ ED_INSERT, /* ] */
+ /* 94 */ ED_INSERT, /* ^ */
+ /* 95 */ ED_INSERT, /* _ */
+ /* 96 */ ED_INSERT, /* ` */
+ /* 97 */ ED_INSERT, /* a */
+ /* 98 */ ED_INSERT, /* b */
+ /* 99 */ ED_INSERT, /* c */
+ /* 100 */ ED_INSERT, /* d */
+ /* 101 */ ED_INSERT, /* e */
+ /* 102 */ ED_INSERT, /* f */
+ /* 103 */ ED_INSERT, /* g */
+ /* 104 */ ED_INSERT, /* h */
+ /* 105 */ ED_INSERT, /* i */
+ /* 106 */ ED_INSERT, /* j */
+ /* 107 */ ED_INSERT, /* k */
+ /* 108 */ ED_INSERT, /* l */
+ /* 109 */ ED_INSERT, /* m */
+ /* 110 */ ED_INSERT, /* n */
+ /* 111 */ ED_INSERT, /* o */
+ /* 112 */ ED_INSERT, /* p */
+ /* 113 */ ED_INSERT, /* q */
+ /* 114 */ ED_INSERT, /* r */
+ /* 115 */ ED_INSERT, /* s */
+ /* 116 */ ED_INSERT, /* t */
+ /* 117 */ ED_INSERT, /* u */
+ /* 118 */ ED_INSERT, /* v */
+ /* 119 */ ED_INSERT, /* w */
+ /* 120 */ ED_INSERT, /* x */
+ /* 121 */ ED_INSERT, /* y */
+ /* 122 */ ED_INSERT, /* z */
+ /* 123 */ ED_INSERT, /* { */
+ /* 124 */ ED_INSERT, /* | */
+ /* 125 */ ED_INSERT, /* } */
+ /* 126 */ ED_INSERT, /* ~ */
+ /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */
+ /* 128 */ ED_UNASSIGNED, /* M-^@ */
+ /* 129 */ ED_UNASSIGNED, /* M-^A */
+ /* 130 */ ED_UNASSIGNED, /* M-^B */
+ /* 131 */ ED_UNASSIGNED, /* M-^C */
+ /* 132 */ ED_UNASSIGNED, /* M-^D */
+ /* 133 */ ED_UNASSIGNED, /* M-^E */
+ /* 134 */ ED_UNASSIGNED, /* M-^F */
+ /* 135 */ ED_UNASSIGNED, /* M-^G */
+ /* 136 */ ED_DELETE_PREV_WORD, /* M-^H */
+ /* 137 */ ED_UNASSIGNED, /* M-^I */
+ /* 138 */ ED_UNASSIGNED, /* M-^J */
+ /* 139 */ ED_UNASSIGNED, /* M-^K */
+ /* 140 */ ED_CLEAR_SCREEN, /* M-^L */
+ /* 141 */ ED_UNASSIGNED, /* M-^M */
+ /* 142 */ ED_UNASSIGNED, /* M-^N */
+ /* 143 */ ED_UNASSIGNED, /* M-^O */
+ /* 144 */ ED_UNASSIGNED, /* M-^P */
+ /* 145 */ ED_UNASSIGNED, /* M-^Q */
+ /* 146 */ ED_UNASSIGNED, /* M-^R */
+ /* 147 */ ED_UNASSIGNED, /* M-^S */
+ /* 148 */ ED_UNASSIGNED, /* M-^T */
+ /* 149 */ ED_UNASSIGNED, /* M-^U */
+ /* 150 */ ED_UNASSIGNED, /* M-^V */
+ /* 151 */ ED_UNASSIGNED, /* M-^W */
+ /* 152 */ ED_UNASSIGNED, /* M-^X */
+ /* 153 */ ED_UNASSIGNED, /* M-^Y */
+ /* 154 */ ED_UNASSIGNED, /* M-^Z */
+ /* 155 */ ED_UNASSIGNED, /* M-^[ */
+ /* 156 */ ED_UNASSIGNED, /* M-^\ */
+ /* 157 */ ED_UNASSIGNED, /* M-^] */
+ /* 158 */ ED_UNASSIGNED, /* M-^^ */
+ /* 159 */ EM_COPY_PREV_WORD, /* M-^_ */
+ /* 160 */ ED_UNASSIGNED, /* M-SPACE */
+ /* 161 */ ED_UNASSIGNED, /* M-! */
+ /* 162 */ ED_UNASSIGNED, /* M-" */
+ /* 163 */ ED_UNASSIGNED, /* M-# */
+ /* 164 */ ED_UNASSIGNED, /* M-$ */
+ /* 165 */ ED_UNASSIGNED, /* M-% */
+ /* 166 */ ED_UNASSIGNED, /* M-& */
+ /* 167 */ ED_UNASSIGNED, /* M-' */
+ /* 168 */ ED_UNASSIGNED, /* M-( */
+ /* 169 */ ED_UNASSIGNED, /* M-) */
+ /* 170 */ ED_UNASSIGNED, /* M-* */
+ /* 171 */ ED_UNASSIGNED, /* M-+ */
+ /* 172 */ ED_UNASSIGNED, /* M-, */
+ /* 173 */ ED_UNASSIGNED, /* M-- */
+ /* 174 */ ED_UNASSIGNED, /* M-. */
+ /* 175 */ ED_UNASSIGNED, /* M-/ */
+ /* 176 */ ED_ARGUMENT_DIGIT, /* M-0 */
+ /* 177 */ ED_ARGUMENT_DIGIT, /* M-1 */
+ /* 178 */ ED_ARGUMENT_DIGIT, /* M-2 */
+ /* 179 */ ED_ARGUMENT_DIGIT, /* M-3 */
+ /* 180 */ ED_ARGUMENT_DIGIT, /* M-4 */
+ /* 181 */ ED_ARGUMENT_DIGIT, /* M-5 */
+ /* 182 */ ED_ARGUMENT_DIGIT, /* M-6 */
+ /* 183 */ ED_ARGUMENT_DIGIT, /* M-7 */
+ /* 184 */ ED_ARGUMENT_DIGIT, /* M-8 */
+ /* 185 */ ED_ARGUMENT_DIGIT, /* M-9 */
+ /* 186 */ ED_UNASSIGNED, /* M-: */
+ /* 187 */ ED_UNASSIGNED, /* M-; */
+ /* 188 */ ED_UNASSIGNED, /* M-< */
+ /* 189 */ ED_UNASSIGNED, /* M-= */
+ /* 190 */ ED_UNASSIGNED, /* M-> */
+ /* 191 */ ED_UNASSIGNED, /* M-? */
+ /* 192 */ ED_UNASSIGNED, /* M-@ */
+ /* 193 */ ED_UNASSIGNED, /* M-A */
+ /* 194 */ ED_PREV_WORD, /* M-B */
+ /* 195 */ EM_CAPITOL_CASE, /* M-C */
+ /* 196 */ EM_DELETE_NEXT_WORD, /* M-D */
+ /* 197 */ ED_UNASSIGNED, /* M-E */
+ /* 198 */ EM_NEXT_WORD, /* M-F */
+ /* 199 */ ED_UNASSIGNED, /* M-G */
+ /* 200 */ ED_UNASSIGNED, /* M-H */
+ /* 201 */ ED_UNASSIGNED, /* M-I */
+ /* 202 */ ED_UNASSIGNED, /* M-J */
+ /* 203 */ ED_UNASSIGNED, /* M-K */
+ /* 204 */ EM_LOWER_CASE, /* M-L */
+ /* 205 */ ED_UNASSIGNED, /* M-M */
+ /* 206 */ ED_SEARCH_NEXT_HISTORY, /* M-N */
+ /* 207 */ ED_SEQUENCE_LEAD_IN, /* M-O */
+ /* 208 */ ED_SEARCH_PREV_HISTORY, /* M-P */
+ /* 209 */ ED_UNASSIGNED, /* M-Q */
+ /* 210 */ ED_UNASSIGNED, /* M-R */
+ /* 211 */ ED_UNASSIGNED, /* M-S */
+ /* 212 */ ED_UNASSIGNED, /* M-T */
+ /* 213 */ EM_UPPER_CASE, /* M-U */
+ /* 214 */ ED_UNASSIGNED, /* M-V */
+ /* 215 */ EM_COPY_REGION, /* M-W */
+ /* 216 */ ED_COMMAND, /* M-X */
+ /* 217 */ ED_UNASSIGNED, /* M-Y */
+ /* 218 */ ED_UNASSIGNED, /* M-Z */
+ /* 219 */ ED_SEQUENCE_LEAD_IN, /* M-[ */
+ /* 220 */ ED_UNASSIGNED, /* M-\ */
+ /* 221 */ ED_UNASSIGNED, /* M-] */
+ /* 222 */ ED_UNASSIGNED, /* M-^ */
+ /* 223 */ ED_UNASSIGNED, /* M-_ */
+ /* 223 */ ED_UNASSIGNED, /* M-` */
+ /* 224 */ ED_UNASSIGNED, /* M-a */
+ /* 225 */ ED_PREV_WORD, /* M-b */
+ /* 226 */ EM_CAPITOL_CASE, /* M-c */
+ /* 227 */ EM_DELETE_NEXT_WORD, /* M-d */
+ /* 228 */ ED_UNASSIGNED, /* M-e */
+ /* 229 */ EM_NEXT_WORD, /* M-f */
+ /* 230 */ ED_UNASSIGNED, /* M-g */
+ /* 231 */ ED_UNASSIGNED, /* M-h */
+ /* 232 */ ED_UNASSIGNED, /* M-i */
+ /* 233 */ ED_UNASSIGNED, /* M-j */
+ /* 234 */ ED_UNASSIGNED, /* M-k */
+ /* 235 */ EM_LOWER_CASE, /* M-l */
+ /* 236 */ ED_UNASSIGNED, /* M-m */
+ /* 237 */ ED_SEARCH_NEXT_HISTORY, /* M-n */
+ /* 238 */ ED_UNASSIGNED, /* M-o */
+ /* 239 */ ED_SEARCH_PREV_HISTORY, /* M-p */
+ /* 240 */ ED_UNASSIGNED, /* M-q */
+ /* 241 */ ED_UNASSIGNED, /* M-r */
+ /* 242 */ ED_UNASSIGNED, /* M-s */
+ /* 243 */ ED_UNASSIGNED, /* M-t */
+ /* 244 */ EM_UPPER_CASE, /* M-u */
+ /* 245 */ ED_UNASSIGNED, /* M-v */
+ /* 246 */ EM_COPY_REGION, /* M-w */
+ /* 247 */ ED_COMMAND, /* M-x */
+ /* 248 */ ED_UNASSIGNED, /* M-y */
+ /* 249 */ ED_UNASSIGNED, /* M-z */
+ /* 250 */ ED_UNASSIGNED, /* M-{ */
+ /* 251 */ ED_UNASSIGNED, /* M-| */
+ /* 252 */ ED_UNASSIGNED, /* M-} */
+ /* 253 */ ED_UNASSIGNED, /* M-~ */
+ /* 254 */ ED_DELETE_PREV_WORD /* M-^? */
+ /* 255 */
+};
+
+/*
+ * keymap table for vi. Each index into above tbl; should be
+ * N_KEYS entries long. Vi mode uses a sticky-extend to do command mode:
+ * insert mode characters are in the normal keymap, and command mode
+ * in the extended keymap.
+ */
+private el_action_t el_map_vi_insert[] = {
+#ifdef KSHVI
+ /* 0 */ ED_UNASSIGNED, /* ^@ */
+ /* 1 */ ED_INSERT, /* ^A */
+ /* 2 */ ED_INSERT, /* ^B */
+ /* 3 */ ED_INSERT, /* ^C */
+ /* 4 */ VI_LIST_OR_EOF, /* ^D */
+ /* 5 */ ED_INSERT, /* ^E */
+ /* 6 */ ED_INSERT, /* ^F */
+ /* 7 */ ED_INSERT, /* ^G */
+ /* 8 */ VI_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */
+ /* 9 */ ED_INSERT, /* ^I */ /* Tab Key */
+ /* 10 */ ED_NEWLINE, /* ^J */
+ /* 11 */ ED_INSERT, /* ^K */
+ /* 12 */ ED_INSERT, /* ^L */
+ /* 13 */ ED_NEWLINE, /* ^M */
+ /* 14 */ ED_INSERT, /* ^N */
+ /* 15 */ ED_INSERT, /* ^O */
+ /* 16 */ ED_INSERT, /* ^P */
+ /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
+ /* 18 */ ED_INSERT, /* ^R */
+ /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
+ /* 20 */ ED_INSERT, /* ^T */
+ /* 21 */ VI_KILL_LINE_PREV, /* ^U */
+ /* 22 */ ED_QUOTED_INSERT, /* ^V */
+ /* 23 */ ED_DELETE_PREV_WORD, /* ^W */ /* Only until strt edit pos */
+ /* 24 */ ED_INSERT, /* ^X */
+ /* 25 */ ED_INSERT, /* ^Y */
+ /* 26 */ ED_INSERT, /* ^Z */
+ /* 27 */ VI_COMMAND_MODE, /* ^[ */ /* [ Esc ] key */
+ /* 28 */ ED_TTY_SIGQUIT, /* ^\ */
+ /* 29 */ ED_INSERT, /* ^] */
+ /* 30 */ ED_INSERT, /* ^^ */
+ /* 31 */ ED_INSERT, /* ^_ */
+#else /* !KSHVI */
+ /* 0 */ ED_UNASSIGNED, /* ^@ */ /* NOTE: These mappings do */
+ /* 1 */ ED_MOVE_TO_BEG, /* ^A */ /* NOT Correspond well to */
+ /* 2 */ ED_PREV_CHAR, /* ^B */ /* the KSH VI editing as- */
+ /* 3 */ ED_TTY_SIGINT, /* ^C */ /* signments. On the other */
+ /* 4 */ VI_LIST_OR_EOF, /* ^D */ /* hand they are convenient*/
+ /* 5 */ ED_MOVE_TO_END, /* ^E */ /* and many people have */
+ /* 6 */ ED_NEXT_CHAR, /* ^F */ /* have gotten used to them*/
+ /* 7 */ ED_UNASSIGNED, /* ^G */
+ /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */
+ /* 9 */ ED_UNASSIGNED, /* ^I */ /* Tab Key */
+ /* 10 */ ED_NEWLINE, /* ^J */
+ /* 11 */ ED_KILL_LINE, /* ^K */
+ /* 12 */ ED_CLEAR_SCREEN, /* ^L */
+ /* 13 */ ED_NEWLINE, /* ^M */
+ /* 14 */ ED_NEXT_HISTORY, /* ^N */
+ /* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */
+ /* 16 */ ED_PREV_HISTORY, /* ^P */
+ /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
+ /* 18 */ ED_REDISPLAY, /* ^R */
+ /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
+ /* 20 */ ED_TRANSPOSE_CHARS, /* ^T */
+ /* 21 */ VI_KILL_LINE_PREV, /* ^U */
+ /* 22 */ ED_QUOTED_INSERT, /* ^V */
+ /* 23 */ ED_DELETE_PREV_WORD, /* ^W */
+ /* 24 */ ED_UNASSIGNED, /* ^X */
+ /* 25 */ ED_TTY_DSUSP, /* ^Y */
+ /* 26 */ ED_TTY_SIGTSTP, /* ^Z */
+ /* 27 */ VI_COMMAND_MODE, /* ^[ */
+ /* 28 */ ED_TTY_SIGQUIT, /* ^\ */
+ /* 29 */ ED_UNASSIGNED, /* ^] */
+ /* 30 */ ED_UNASSIGNED, /* ^^ */
+ /* 31 */ ED_UNASSIGNED, /* ^_ */
+#endif /* KSHVI */
+ /* 32 */ ED_INSERT, /* SPACE */
+ /* 33 */ ED_INSERT, /* ! */
+ /* 34 */ ED_INSERT, /* " */
+ /* 35 */ ED_INSERT, /* # */
+ /* 36 */ ED_INSERT, /* $ */
+ /* 37 */ ED_INSERT, /* % */
+ /* 38 */ ED_INSERT, /* & */
+ /* 39 */ ED_INSERT, /* ' */
+ /* 40 */ ED_INSERT, /* ( */
+ /* 41 */ ED_INSERT, /* ) */
+ /* 42 */ ED_INSERT, /* * */
+ /* 43 */ ED_INSERT, /* + */
+ /* 44 */ ED_INSERT, /* , */
+ /* 45 */ ED_INSERT, /* - */
+ /* 46 */ ED_INSERT, /* . */
+ /* 47 */ ED_INSERT, /* / */
+ /* 48 */ ED_INSERT, /* 0 */
+ /* 49 */ ED_INSERT, /* 1 */
+ /* 50 */ ED_INSERT, /* 2 */
+ /* 51 */ ED_INSERT, /* 3 */
+ /* 52 */ ED_INSERT, /* 4 */
+ /* 53 */ ED_INSERT, /* 5 */
+ /* 54 */ ED_INSERT, /* 6 */
+ /* 55 */ ED_INSERT, /* 7 */
+ /* 56 */ ED_INSERT, /* 8 */
+ /* 57 */ ED_INSERT, /* 9 */
+ /* 58 */ ED_INSERT, /* : */
+ /* 59 */ ED_INSERT, /* ; */
+ /* 60 */ ED_INSERT, /* < */
+ /* 61 */ ED_INSERT, /* = */
+ /* 62 */ ED_INSERT, /* > */
+ /* 63 */ ED_INSERT, /* ? */
+ /* 64 */ ED_INSERT, /* @ */
+ /* 65 */ ED_INSERT, /* A */
+ /* 66 */ ED_INSERT, /* B */
+ /* 67 */ ED_INSERT, /* C */
+ /* 68 */ ED_INSERT, /* D */
+ /* 69 */ ED_INSERT, /* E */
+ /* 70 */ ED_INSERT, /* F */
+ /* 71 */ ED_INSERT, /* G */
+ /* 72 */ ED_INSERT, /* H */
+ /* 73 */ ED_INSERT, /* I */
+ /* 74 */ ED_INSERT, /* J */
+ /* 75 */ ED_INSERT, /* K */
+ /* 76 */ ED_INSERT, /* L */
+ /* 77 */ ED_INSERT, /* M */
+ /* 78 */ ED_INSERT, /* N */
+ /* 79 */ ED_INSERT, /* O */
+ /* 80 */ ED_INSERT, /* P */
+ /* 81 */ ED_INSERT, /* Q */
+ /* 82 */ ED_INSERT, /* R */
+ /* 83 */ ED_INSERT, /* S */
+ /* 84 */ ED_INSERT, /* T */
+ /* 85 */ ED_INSERT, /* U */
+ /* 86 */ ED_INSERT, /* V */
+ /* 87 */ ED_INSERT, /* W */
+ /* 88 */ ED_INSERT, /* X */
+ /* 89 */ ED_INSERT, /* Y */
+ /* 90 */ ED_INSERT, /* Z */
+ /* 91 */ ED_INSERT, /* [ */
+ /* 92 */ ED_INSERT, /* \ */
+ /* 93 */ ED_INSERT, /* ] */
+ /* 94 */ ED_INSERT, /* ^ */
+ /* 95 */ ED_INSERT, /* _ */
+ /* 96 */ ED_INSERT, /* ` */
+ /* 97 */ ED_INSERT, /* a */
+ /* 98 */ ED_INSERT, /* b */
+ /* 99 */ ED_INSERT, /* c */
+ /* 100 */ ED_INSERT, /* d */
+ /* 101 */ ED_INSERT, /* e */
+ /* 102 */ ED_INSERT, /* f */
+ /* 103 */ ED_INSERT, /* g */
+ /* 104 */ ED_INSERT, /* h */
+ /* 105 */ ED_INSERT, /* i */
+ /* 106 */ ED_INSERT, /* j */
+ /* 107 */ ED_INSERT, /* k */
+ /* 108 */ ED_INSERT, /* l */
+ /* 109 */ ED_INSERT, /* m */
+ /* 110 */ ED_INSERT, /* n */
+ /* 111 */ ED_INSERT, /* o */
+ /* 112 */ ED_INSERT, /* p */
+ /* 113 */ ED_INSERT, /* q */
+ /* 114 */ ED_INSERT, /* r */
+ /* 115 */ ED_INSERT, /* s */
+ /* 116 */ ED_INSERT, /* t */
+ /* 117 */ ED_INSERT, /* u */
+ /* 118 */ ED_INSERT, /* v */
+ /* 119 */ ED_INSERT, /* w */
+ /* 120 */ ED_INSERT, /* x */
+ /* 121 */ ED_INSERT, /* y */
+ /* 122 */ ED_INSERT, /* z */
+ /* 123 */ ED_INSERT, /* { */
+ /* 124 */ ED_INSERT, /* | */
+ /* 125 */ ED_INSERT, /* } */
+ /* 126 */ ED_INSERT, /* ~ */
+ /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */
+ /* 128 */ ED_UNASSIGNED, /* M-^@ */
+ /* 129 */ ED_UNASSIGNED, /* M-^A */
+ /* 130 */ ED_UNASSIGNED, /* M-^B */
+ /* 131 */ ED_UNASSIGNED, /* M-^C */
+ /* 132 */ ED_UNASSIGNED, /* M-^D */
+ /* 133 */ ED_UNASSIGNED, /* M-^E */
+ /* 134 */ ED_UNASSIGNED, /* M-^F */
+ /* 135 */ ED_UNASSIGNED, /* M-^G */
+ /* 136 */ ED_UNASSIGNED, /* M-^H */
+ /* 137 */ ED_UNASSIGNED, /* M-^I */
+ /* 138 */ ED_UNASSIGNED, /* M-^J */
+ /* 139 */ ED_UNASSIGNED, /* M-^K */
+ /* 140 */ ED_UNASSIGNED, /* M-^L */
+ /* 141 */ ED_UNASSIGNED, /* M-^M */
+ /* 142 */ ED_UNASSIGNED, /* M-^N */
+ /* 143 */ ED_UNASSIGNED, /* M-^O */
+ /* 144 */ ED_UNASSIGNED, /* M-^P */
+ /* 145 */ ED_UNASSIGNED, /* M-^Q */
+ /* 146 */ ED_UNASSIGNED, /* M-^R */
+ /* 147 */ ED_UNASSIGNED, /* M-^S */
+ /* 148 */ ED_UNASSIGNED, /* M-^T */
+ /* 149 */ ED_UNASSIGNED, /* M-^U */
+ /* 150 */ ED_UNASSIGNED, /* M-^V */
+ /* 151 */ ED_UNASSIGNED, /* M-^W */
+ /* 152 */ ED_UNASSIGNED, /* M-^X */
+ /* 153 */ ED_UNASSIGNED, /* M-^Y */
+ /* 154 */ ED_UNASSIGNED, /* M-^Z */
+ /* 155 */ ED_UNASSIGNED, /* M-^[ */
+ /* 156 */ ED_UNASSIGNED, /* M-^\ */
+ /* 157 */ ED_UNASSIGNED, /* M-^] */
+ /* 158 */ ED_UNASSIGNED, /* M-^^ */
+ /* 159 */ ED_UNASSIGNED, /* M-^_ */
+ /* 160 */ ED_UNASSIGNED, /* M-SPACE */
+ /* 161 */ ED_UNASSIGNED, /* M-! */
+ /* 162 */ ED_UNASSIGNED, /* M-" */
+ /* 163 */ ED_UNASSIGNED, /* M-# */
+ /* 164 */ ED_UNASSIGNED, /* M-$ */
+ /* 165 */ ED_UNASSIGNED, /* M-% */
+ /* 166 */ ED_UNASSIGNED, /* M-& */
+ /* 167 */ ED_UNASSIGNED, /* M-' */
+ /* 168 */ ED_UNASSIGNED, /* M-( */
+ /* 169 */ ED_UNASSIGNED, /* M-) */
+ /* 170 */ ED_UNASSIGNED, /* M-* */
+ /* 171 */ ED_UNASSIGNED, /* M-+ */
+ /* 172 */ ED_UNASSIGNED, /* M-, */
+ /* 173 */ ED_UNASSIGNED, /* M-- */
+ /* 174 */ ED_UNASSIGNED, /* M-. */
+ /* 175 */ ED_UNASSIGNED, /* M-/ */
+ /* 176 */ ED_UNASSIGNED, /* M-0 */
+ /* 177 */ ED_UNASSIGNED, /* M-1 */
+ /* 178 */ ED_UNASSIGNED, /* M-2 */
+ /* 179 */ ED_UNASSIGNED, /* M-3 */
+ /* 180 */ ED_UNASSIGNED, /* M-4 */
+ /* 181 */ ED_UNASSIGNED, /* M-5 */
+ /* 182 */ ED_UNASSIGNED, /* M-6 */
+ /* 183 */ ED_UNASSIGNED, /* M-7 */
+ /* 184 */ ED_UNASSIGNED, /* M-8 */
+ /* 185 */ ED_UNASSIGNED, /* M-9 */
+ /* 186 */ ED_UNASSIGNED, /* M-: */
+ /* 187 */ ED_UNASSIGNED, /* M-; */
+ /* 188 */ ED_UNASSIGNED, /* M-< */
+ /* 189 */ ED_UNASSIGNED, /* M-= */
+ /* 190 */ ED_UNASSIGNED, /* M-> */
+ /* 191 */ ED_UNASSIGNED, /* M-? */
+ /* 192 */ ED_UNASSIGNED, /* M-@ */
+ /* 193 */ ED_UNASSIGNED, /* M-A */
+ /* 194 */ ED_UNASSIGNED, /* M-B */
+ /* 195 */ ED_UNASSIGNED, /* M-C */
+ /* 196 */ ED_UNASSIGNED, /* M-D */
+ /* 197 */ ED_UNASSIGNED, /* M-E */
+ /* 198 */ ED_UNASSIGNED, /* M-F */
+ /* 199 */ ED_UNASSIGNED, /* M-G */
+ /* 200 */ ED_UNASSIGNED, /* M-H */
+ /* 201 */ ED_UNASSIGNED, /* M-I */
+ /* 202 */ ED_UNASSIGNED, /* M-J */
+ /* 203 */ ED_UNASSIGNED, /* M-K */
+ /* 204 */ ED_UNASSIGNED, /* M-L */
+ /* 205 */ ED_UNASSIGNED, /* M-M */
+ /* 206 */ ED_UNASSIGNED, /* M-N */
+ /* 207 */ ED_UNASSIGNED, /* M-O */
+ /* 208 */ ED_UNASSIGNED, /* M-P */
+ /* 209 */ ED_UNASSIGNED, /* M-Q */
+ /* 210 */ ED_UNASSIGNED, /* M-R */
+ /* 211 */ ED_UNASSIGNED, /* M-S */
+ /* 212 */ ED_UNASSIGNED, /* M-T */
+ /* 213 */ ED_UNASSIGNED, /* M-U */
+ /* 214 */ ED_UNASSIGNED, /* M-V */
+ /* 215 */ ED_UNASSIGNED, /* M-W */
+ /* 216 */ ED_UNASSIGNED, /* M-X */
+ /* 217 */ ED_UNASSIGNED, /* M-Y */
+ /* 218 */ ED_UNASSIGNED, /* M-Z */
+ /* 219 */ ED_UNASSIGNED, /* M-[ */
+ /* 220 */ ED_UNASSIGNED, /* M-\ */
+ /* 221 */ ED_UNASSIGNED, /* M-] */
+ /* 222 */ ED_UNASSIGNED, /* M-^ */
+ /* 223 */ ED_UNASSIGNED, /* M-_ */
+ /* 224 */ ED_UNASSIGNED, /* M-` */
+ /* 225 */ ED_UNASSIGNED, /* M-a */
+ /* 226 */ ED_UNASSIGNED, /* M-b */
+ /* 227 */ ED_UNASSIGNED, /* M-c */
+ /* 228 */ ED_UNASSIGNED, /* M-d */
+ /* 229 */ ED_UNASSIGNED, /* M-e */
+ /* 230 */ ED_UNASSIGNED, /* M-f */
+ /* 231 */ ED_UNASSIGNED, /* M-g */
+ /* 232 */ ED_UNASSIGNED, /* M-h */
+ /* 233 */ ED_UNASSIGNED, /* M-i */
+ /* 234 */ ED_UNASSIGNED, /* M-j */
+ /* 235 */ ED_UNASSIGNED, /* M-k */
+ /* 236 */ ED_UNASSIGNED, /* M-l */
+ /* 237 */ ED_UNASSIGNED, /* M-m */
+ /* 238 */ ED_UNASSIGNED, /* M-n */
+ /* 239 */ ED_UNASSIGNED, /* M-o */
+ /* 240 */ ED_UNASSIGNED, /* M-p */
+ /* 241 */ ED_UNASSIGNED, /* M-q */
+ /* 242 */ ED_UNASSIGNED, /* M-r */
+ /* 243 */ ED_UNASSIGNED, /* M-s */
+ /* 244 */ ED_UNASSIGNED, /* M-t */
+ /* 245 */ ED_UNASSIGNED, /* M-u */
+ /* 246 */ ED_UNASSIGNED, /* M-v */
+ /* 247 */ ED_UNASSIGNED, /* M-w */
+ /* 248 */ ED_UNASSIGNED, /* M-x */
+ /* 249 */ ED_UNASSIGNED, /* M-y */
+ /* 250 */ ED_UNASSIGNED, /* M-z */
+ /* 251 */ ED_UNASSIGNED, /* M-{ */
+ /* 252 */ ED_UNASSIGNED, /* M-| */
+ /* 253 */ ED_UNASSIGNED, /* M-} */
+ /* 254 */ ED_UNASSIGNED, /* M-~ */
+ /* 255 */ ED_UNASSIGNED /* M-^? */
+};
+
+private el_action_t el_map_vi_command[] = {
+ /* 0 */ ED_UNASSIGNED, /* ^@ */
+ /* 1 */ ED_MOVE_TO_BEG, /* ^A */
+ /* 2 */ ED_UNASSIGNED, /* ^B */
+ /* 3 */ ED_TTY_SIGINT, /* ^C */
+ /* 4 */ ED_UNASSIGNED, /* ^D */
+ /* 5 */ ED_MOVE_TO_END, /* ^E */
+ /* 6 */ ED_UNASSIGNED, /* ^F */
+ /* 7 */ ED_UNASSIGNED, /* ^G */
+ /* 8 */ ED_PREV_CHAR, /* ^H */
+ /* 9 */ ED_UNASSIGNED, /* ^I */
+ /* 10 */ ED_NEWLINE, /* ^J */
+ /* 11 */ ED_KILL_LINE, /* ^K */
+ /* 12 */ ED_CLEAR_SCREEN, /* ^L */
+ /* 13 */ ED_NEWLINE, /* ^M */
+ /* 14 */ ED_NEXT_HISTORY, /* ^N */
+ /* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */
+ /* 16 */ ED_PREV_HISTORY, /* ^P */
+ /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
+ /* 18 */ ED_REDISPLAY, /* ^R */
+ /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
+ /* 20 */ ED_UNASSIGNED, /* ^T */
+ /* 21 */ VI_KILL_LINE_PREV, /* ^U */
+ /* 22 */ ED_UNASSIGNED, /* ^V */
+ /* 23 */ ED_DELETE_PREV_WORD, /* ^W */
+ /* 24 */ ED_UNASSIGNED, /* ^X */
+ /* 25 */ ED_UNASSIGNED, /* ^Y */
+ /* 26 */ ED_UNASSIGNED, /* ^Z */
+ /* 27 */ EM_META_NEXT, /* ^[ */
+ /* 28 */ ED_TTY_SIGQUIT, /* ^\ */
+ /* 29 */ ED_UNASSIGNED, /* ^] */
+ /* 30 */ ED_UNASSIGNED, /* ^^ */
+ /* 31 */ ED_UNASSIGNED, /* ^_ */
+ /* 32 */ ED_NEXT_CHAR, /* SPACE */
+ /* 33 */ ED_UNASSIGNED, /* ! */
+ /* 34 */ ED_UNASSIGNED, /* " */
+ /* 35 */ ED_UNASSIGNED, /* # */
+ /* 36 */ ED_MOVE_TO_END, /* $ */
+ /* 37 */ ED_UNASSIGNED, /* % */
+ /* 38 */ ED_UNASSIGNED, /* & */
+ /* 39 */ ED_UNASSIGNED, /* ' */
+ /* 40 */ ED_UNASSIGNED, /* ( */
+ /* 41 */ ED_UNASSIGNED, /* ) */
+ /* 42 */ ED_UNASSIGNED, /* * */
+ /* 43 */ ED_NEXT_HISTORY, /* + */
+ /* 44 */ VI_REPEAT_PREV_CHAR, /* , */
+ /* 45 */ ED_PREV_HISTORY, /* - */
+ /* 46 */ ED_UNASSIGNED, /* . */
+ /* 47 */ VI_SEARCH_PREV, /* / */
+ /* 48 */ VI_ZERO, /* 0 */
+ /* 49 */ ED_ARGUMENT_DIGIT, /* 1 */
+ /* 50 */ ED_ARGUMENT_DIGIT, /* 2 */
+ /* 51 */ ED_ARGUMENT_DIGIT, /* 3 */
+ /* 52 */ ED_ARGUMENT_DIGIT, /* 4 */
+ /* 53 */ ED_ARGUMENT_DIGIT, /* 5 */
+ /* 54 */ ED_ARGUMENT_DIGIT, /* 6 */
+ /* 55 */ ED_ARGUMENT_DIGIT, /* 7 */
+ /* 56 */ ED_ARGUMENT_DIGIT, /* 8 */
+ /* 57 */ ED_ARGUMENT_DIGIT, /* 9 */
+ /* 58 */ ED_COMMAND, /* : */
+ /* 59 */ VI_REPEAT_NEXT_CHAR, /* ; */
+ /* 60 */ ED_UNASSIGNED, /* < */
+ /* 61 */ ED_UNASSIGNED, /* = */
+ /* 62 */ ED_UNASSIGNED, /* > */
+ /* 63 */ VI_SEARCH_NEXT, /* ? */
+ /* 64 */ ED_UNASSIGNED, /* @ */
+ /* 65 */ VI_ADD_AT_EOL, /* A */
+ /* 66 */ VI_PREV_SPACE_WORD, /* B */
+ /* 67 */ VI_CHANGE_TO_EOL, /* C */
+ /* 68 */ ED_KILL_LINE, /* D */
+ /* 69 */ VI_TO_END_WORD, /* E */
+ /* 70 */ VI_PREV_CHAR, /* F */
+ /* 71 */ ED_UNASSIGNED, /* G */
+ /* 72 */ ED_UNASSIGNED, /* H */
+ /* 73 */ VI_INSERT_AT_BOL, /* I */
+ /* 74 */ ED_SEARCH_NEXT_HISTORY, /* J */
+ /* 75 */ ED_SEARCH_PREV_HISTORY, /* K */
+ /* 76 */ ED_UNASSIGNED, /* L */
+ /* 77 */ ED_UNASSIGNED, /* M */
+ /* 78 */ VI_REPEAT_SEARCH_PREV, /* N */
+ /* 79 */ ED_SEQUENCE_LEAD_IN, /* O */
+ /* 80 */ VI_PASTE_PREV, /* P */
+ /* 81 */ ED_UNASSIGNED, /* Q */
+ /* 82 */ VI_REPLACE_MODE, /* R */
+ /* 83 */ VI_SUBSTITUTE_LINE, /* S */
+ /* 84 */ VI_TO_PREV_CHAR, /* T */
+ /* 85 */ VI_UNDO_LINE, /* U */
+ /* 86 */ ED_UNASSIGNED, /* V */
+ /* 87 */ VI_NEXT_SPACE_WORD, /* W */
+ /* 88 */ ED_DELETE_PREV_CHAR, /* X */
+ /* 89 */ ED_UNASSIGNED, /* Y */
+ /* 90 */ ED_UNASSIGNED, /* Z */
+ /* 91 */ ED_SEQUENCE_LEAD_IN, /* [ */
+ /* 92 */ ED_UNASSIGNED, /* \ */
+ /* 93 */ ED_UNASSIGNED, /* ] */
+ /* 94 */ ED_MOVE_TO_BEG, /* ^ */
+ /* 95 */ ED_UNASSIGNED, /* _ */
+ /* 96 */ ED_UNASSIGNED, /* ` */
+ /* 97 */ VI_ADD, /* a */
+ /* 98 */ VI_PREV_WORD, /* b */
+ /* 99 */ VI_CHANGE_META, /* c */
+ /* 100 */ VI_DELETE_META, /* d */
+ /* 101 */ VI_END_WORD, /* e */
+ /* 102 */ VI_NEXT_CHAR, /* f */
+ /* 103 */ ED_UNASSIGNED, /* g */
+ /* 104 */ ED_PREV_CHAR, /* h */
+ /* 105 */ VI_INSERT, /* i */
+ /* 106 */ ED_NEXT_HISTORY, /* j */
+ /* 107 */ ED_PREV_HISTORY, /* k */
+ /* 108 */ ED_NEXT_CHAR, /* l */
+ /* 109 */ ED_UNASSIGNED, /* m */
+ /* 110 */ VI_REPEAT_SEARCH_NEXT, /* n */
+ /* 111 */ ED_UNASSIGNED, /* o */
+ /* 112 */ VI_PASTE_NEXT, /* p */
+ /* 113 */ ED_UNASSIGNED, /* q */
+ /* 114 */ VI_REPLACE_CHAR, /* r */
+ /* 115 */ VI_SUBSTITUTE_CHAR, /* s */
+ /* 116 */ VI_TO_NEXT_CHAR, /* t */
+ /* 117 */ VI_UNDO, /* u */
+ /* 118 */ ED_UNASSIGNED, /* v */
+ /* 119 */ VI_NEXT_WORD, /* w */
+ /* 120 */ ED_DELETE_NEXT_CHAR, /* x */
+ /* 121 */ ED_UNASSIGNED, /* y */
+ /* 122 */ ED_UNASSIGNED, /* z */
+ /* 123 */ ED_UNASSIGNED, /* { */
+ /* 124 */ ED_UNASSIGNED, /* | */
+ /* 125 */ ED_UNASSIGNED, /* } */
+ /* 126 */ VI_CHANGE_CASE, /* ~ */
+ /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */
+ /* 128 */ ED_UNASSIGNED, /* M-^@ */
+ /* 129 */ ED_UNASSIGNED, /* M-^A */
+ /* 130 */ ED_UNASSIGNED, /* M-^B */
+ /* 131 */ ED_UNASSIGNED, /* M-^C */
+ /* 132 */ ED_UNASSIGNED, /* M-^D */
+ /* 133 */ ED_UNASSIGNED, /* M-^E */
+ /* 134 */ ED_UNASSIGNED, /* M-^F */
+ /* 135 */ ED_UNASSIGNED, /* M-^G */
+ /* 136 */ ED_UNASSIGNED, /* M-^H */
+ /* 137 */ ED_UNASSIGNED, /* M-^I */
+ /* 138 */ ED_UNASSIGNED, /* M-^J */
+ /* 139 */ ED_UNASSIGNED, /* M-^K */
+ /* 140 */ ED_UNASSIGNED, /* M-^L */
+ /* 141 */ ED_UNASSIGNED, /* M-^M */
+ /* 142 */ ED_UNASSIGNED, /* M-^N */
+ /* 143 */ ED_UNASSIGNED, /* M-^O */
+ /* 144 */ ED_UNASSIGNED, /* M-^P */
+ /* 145 */ ED_UNASSIGNED, /* M-^Q */
+ /* 146 */ ED_UNASSIGNED, /* M-^R */
+ /* 147 */ ED_UNASSIGNED, /* M-^S */
+ /* 148 */ ED_UNASSIGNED, /* M-^T */
+ /* 149 */ ED_UNASSIGNED, /* M-^U */
+ /* 150 */ ED_UNASSIGNED, /* M-^V */
+ /* 151 */ ED_UNASSIGNED, /* M-^W */
+ /* 152 */ ED_UNASSIGNED, /* M-^X */
+ /* 153 */ ED_UNASSIGNED, /* M-^Y */
+ /* 154 */ ED_UNASSIGNED, /* M-^Z */
+ /* 155 */ ED_UNASSIGNED, /* M-^[ */
+ /* 156 */ ED_UNASSIGNED, /* M-^\ */
+ /* 157 */ ED_UNASSIGNED, /* M-^] */
+ /* 158 */ ED_UNASSIGNED, /* M-^^ */
+ /* 159 */ ED_UNASSIGNED, /* M-^_ */
+ /* 160 */ ED_UNASSIGNED, /* M-SPACE */
+ /* 161 */ ED_UNASSIGNED, /* M-! */
+ /* 162 */ ED_UNASSIGNED, /* M-" */
+ /* 163 */ ED_UNASSIGNED, /* M-# */
+ /* 164 */ ED_UNASSIGNED, /* M-$ */
+ /* 165 */ ED_UNASSIGNED, /* M-% */
+ /* 166 */ ED_UNASSIGNED, /* M-& */
+ /* 167 */ ED_UNASSIGNED, /* M-' */
+ /* 168 */ ED_UNASSIGNED, /* M-( */
+ /* 169 */ ED_UNASSIGNED, /* M-) */
+ /* 170 */ ED_UNASSIGNED, /* M-* */
+ /* 171 */ ED_UNASSIGNED, /* M-+ */
+ /* 172 */ ED_UNASSIGNED, /* M-, */
+ /* 173 */ ED_UNASSIGNED, /* M-- */
+ /* 174 */ ED_UNASSIGNED, /* M-. */
+ /* 175 */ ED_UNASSIGNED, /* M-/ */
+ /* 176 */ ED_UNASSIGNED, /* M-0 */
+ /* 177 */ ED_UNASSIGNED, /* M-1 */
+ /* 178 */ ED_UNASSIGNED, /* M-2 */
+ /* 179 */ ED_UNASSIGNED, /* M-3 */
+ /* 180 */ ED_UNASSIGNED, /* M-4 */
+ /* 181 */ ED_UNASSIGNED, /* M-5 */
+ /* 182 */ ED_UNASSIGNED, /* M-6 */
+ /* 183 */ ED_UNASSIGNED, /* M-7 */
+ /* 184 */ ED_UNASSIGNED, /* M-8 */
+ /* 185 */ ED_UNASSIGNED, /* M-9 */
+ /* 186 */ ED_UNASSIGNED, /* M-: */
+ /* 187 */ ED_UNASSIGNED, /* M-; */
+ /* 188 */ ED_UNASSIGNED, /* M-< */
+ /* 189 */ ED_UNASSIGNED, /* M-= */
+ /* 190 */ ED_UNASSIGNED, /* M-> */
+ /* 191 */ ED_UNASSIGNED, /* M-? */
+ /* 192 */ ED_UNASSIGNED, /* M-@ */
+ /* 193 */ ED_UNASSIGNED, /* M-A */
+ /* 194 */ ED_UNASSIGNED, /* M-B */
+ /* 195 */ ED_UNASSIGNED, /* M-C */
+ /* 196 */ ED_UNASSIGNED, /* M-D */
+ /* 197 */ ED_UNASSIGNED, /* M-E */
+ /* 198 */ ED_UNASSIGNED, /* M-F */
+ /* 199 */ ED_UNASSIGNED, /* M-G */
+ /* 200 */ ED_UNASSIGNED, /* M-H */
+ /* 201 */ ED_UNASSIGNED, /* M-I */
+ /* 202 */ ED_UNASSIGNED, /* M-J */
+ /* 203 */ ED_UNASSIGNED, /* M-K */
+ /* 204 */ ED_UNASSIGNED, /* M-L */
+ /* 205 */ ED_UNASSIGNED, /* M-M */
+ /* 206 */ ED_UNASSIGNED, /* M-N */
+ /* 207 */ ED_SEQUENCE_LEAD_IN, /* M-O */
+ /* 208 */ ED_UNASSIGNED, /* M-P */
+ /* 209 */ ED_UNASSIGNED, /* M-Q */
+ /* 210 */ ED_UNASSIGNED, /* M-R */
+ /* 211 */ ED_UNASSIGNED, /* M-S */
+ /* 212 */ ED_UNASSIGNED, /* M-T */
+ /* 213 */ ED_UNASSIGNED, /* M-U */
+ /* 214 */ ED_UNASSIGNED, /* M-V */
+ /* 215 */ ED_UNASSIGNED, /* M-W */
+ /* 216 */ ED_UNASSIGNED, /* M-X */
+ /* 217 */ ED_UNASSIGNED, /* M-Y */
+ /* 218 */ ED_UNASSIGNED, /* M-Z */
+ /* 219 */ ED_SEQUENCE_LEAD_IN, /* M-[ */
+ /* 220 */ ED_UNASSIGNED, /* M-\ */
+ /* 221 */ ED_UNASSIGNED, /* M-] */
+ /* 222 */ ED_UNASSIGNED, /* M-^ */
+ /* 223 */ ED_UNASSIGNED, /* M-_ */
+ /* 224 */ ED_UNASSIGNED, /* M-` */
+ /* 225 */ ED_UNASSIGNED, /* M-a */
+ /* 226 */ ED_UNASSIGNED, /* M-b */
+ /* 227 */ ED_UNASSIGNED, /* M-c */
+ /* 228 */ ED_UNASSIGNED, /* M-d */
+ /* 229 */ ED_UNASSIGNED, /* M-e */
+ /* 230 */ ED_UNASSIGNED, /* M-f */
+ /* 231 */ ED_UNASSIGNED, /* M-g */
+ /* 232 */ ED_UNASSIGNED, /* M-h */
+ /* 233 */ ED_UNASSIGNED, /* M-i */
+ /* 234 */ ED_UNASSIGNED, /* M-j */
+ /* 235 */ ED_UNASSIGNED, /* M-k */
+ /* 236 */ ED_UNASSIGNED, /* M-l */
+ /* 237 */ ED_UNASSIGNED, /* M-m */
+ /* 238 */ ED_UNASSIGNED, /* M-n */
+ /* 239 */ ED_UNASSIGNED, /* M-o */
+ /* 240 */ ED_UNASSIGNED, /* M-p */
+ /* 241 */ ED_UNASSIGNED, /* M-q */
+ /* 242 */ ED_UNASSIGNED, /* M-r */
+ /* 243 */ ED_UNASSIGNED, /* M-s */
+ /* 244 */ ED_UNASSIGNED, /* M-t */
+ /* 245 */ ED_UNASSIGNED, /* M-u */
+ /* 246 */ ED_UNASSIGNED, /* M-v */
+ /* 247 */ ED_UNASSIGNED, /* M-w */
+ /* 248 */ ED_UNASSIGNED, /* M-x */
+ /* 249 */ ED_UNASSIGNED, /* M-y */
+ /* 250 */ ED_UNASSIGNED, /* M-z */
+ /* 251 */ ED_UNASSIGNED, /* M-{ */
+ /* 252 */ ED_UNASSIGNED, /* M-| */
+ /* 253 */ ED_UNASSIGNED, /* M-} */
+ /* 254 */ ED_UNASSIGNED, /* M-~ */
+ /* 255 */ ED_UNASSIGNED /* M-^? */
+};
+
+
+/* map_init():
+ * Initialize and allocate the maps
+ */
+protected int
+map_init(el)
+ EditLine *el;
+{
+
+ /*
+ * Make sure those are correct before starting.
+ */
+#ifdef MAP_DEBUG
+ if (sizeof(el_map_emacs) != N_KEYS * sizeof(el_action_t))
+ abort();
+ if (sizeof(el_map_vi_command) != N_KEYS * sizeof(el_action_t))
+ abort();
+ if (sizeof(el_map_vi_insert) != N_KEYS * sizeof(el_action_t))
+ abort();
+#endif
+
+ el->el_map.alt = (el_action_t *) el_malloc(sizeof(el_action_t) * N_KEYS);
+ el->el_map.key = (el_action_t *) el_malloc(sizeof(el_action_t) * N_KEYS);
+ el->el_map.emacs = el_map_emacs;
+ el->el_map.vic = el_map_vi_command;
+ el->el_map.vii = el_map_vi_insert;
+ el->el_map.help = (el_bindings_t *) el_malloc(sizeof(el_bindings_t) *
+ EL_NUM_FCNS);
+ (void) memcpy(el->el_map.help, help__get(),
+ sizeof(el_bindings_t) * EL_NUM_FCNS);
+ el->el_map.func = (el_func_t *) el_malloc(sizeof(el_func_t) * EL_NUM_FCNS);
+ memcpy(el->el_map.func, func__get(), sizeof(el_func_t) * EL_NUM_FCNS);
+ el->el_map.nfunc = EL_NUM_FCNS;
+
+#ifdef VIDEFAULT
+ map_init_vi(el);
+#else
+ map_init_emacs(el);
+#endif /* VIDEFAULT */
+ return 0;
+}
+
+
+/* map_end():
+ * Free the space taken by the editor maps
+ */
+protected void
+map_end(el)
+ EditLine *el;
+{
+ el_free((ptr_t) el->el_map.alt);
+ el->el_map.alt = NULL;
+ el_free((ptr_t) el->el_map.key);
+ el->el_map.key = NULL;
+ el->el_map.emacs = NULL;
+ el->el_map.vic = NULL;
+ el->el_map.vii = NULL;
+ el_free((ptr_t) el->el_map.help);
+ el->el_map.help = NULL;
+ el_free((ptr_t) el->el_map.func);
+ el->el_map.func = NULL;
+}
+
+
+/* map_init_nls():
+ * Find all the printable keys and bind them to self insert
+ */
+private void
+map_init_nls(el)
+ EditLine *el;
+{
+ int i;
+ el_action_t *map = el->el_map.key;
+
+ for (i = 0200; i <= 0377; i++)
+ if (isprint(i))
+ map[i] = ED_INSERT;
+}
+
+
+/* map_init_meta():
+ * Bind all the meta keys to the appropriate ESC-<key> sequence
+ */
+private void
+map_init_meta(el)
+ EditLine *el;
+{
+ char buf[3];
+ register int i;
+ el_action_t *map = el->el_map.key;
+ el_action_t *alt = el->el_map.alt;
+
+ for (i = 0; i <= 0377 && map[i] != EM_META_NEXT; i++)
+ continue;
+
+ if (i > 0377) {
+ for (i = 0; i <= 0377 && alt[i] != EM_META_NEXT; i++)
+ continue;
+ if (i > 0377) {
+ i = 033;
+ if (el->el_map.type == MAP_VI)
+ map = alt;
+ }
+ else
+ map = alt;
+ }
+ buf[0] = (char) i;
+ buf[2] = 0;
+ for (i = 0200; i <= 0377; i++)
+ switch (map[i]) {
+ case ED_INSERT:
+ case ED_UNASSIGNED:
+ case ED_SEQUENCE_LEAD_IN:
+ break;
+ default:
+ buf[1] = i & 0177;
+ key_add(el, buf, key_map_cmd(el, (int) map[i]), XK_CMD);
+ break;
+ }
+ map[buf[0]] = ED_SEQUENCE_LEAD_IN;
+}
+
+
+/* map_init_vi():
+ * Initialize the vi bindings
+ */
+protected void
+map_init_vi(el)
+ EditLine *el;
+{
+ register int i;
+ el_action_t *key = el->el_map.key;
+ el_action_t *alt = el->el_map.alt;
+ el_action_t *vii = el->el_map.vii;
+ el_action_t *vic = el->el_map.vic;
+
+ el->el_map.type = MAP_VI;
+ el->el_map.current = el->el_map.key;
+
+ key_reset(el);
+
+ for (i = 0; i < N_KEYS; i++) {
+ key[i] = vii[i];
+ alt[i] = vic[i];
+ }
+
+ map_init_meta(el);
+#ifdef notyet
+ if (0 /* XXX: USER has set LC_CTYPE */)
+ map_init_nls(el);
+#endif
+
+ tty_bind_char(el, 1);
+ term_bind_arrow(el);
+}
+
+
+/* map_init_emacs():
+ * Initialize the emacs bindings
+ */
+protected void
+map_init_emacs(el)
+ EditLine *el;
+{
+ int i;
+ char buf[3];
+ el_action_t *key = el->el_map.key;
+ el_action_t *alt = el->el_map.alt;
+ el_action_t *emacs = el->el_map.emacs;
+
+ el->el_map.type = MAP_EMACS;
+ el->el_map.current = el->el_map.key;
+ key_reset(el);
+
+ for (i = 0; i < N_KEYS; i++) {
+ key[i] = emacs[i];
+ alt[i] = ED_UNASSIGNED;
+ }
+
+ map_init_meta(el);
+#ifdef notyet
+ if (0 /* XXX: USER has set LC_CTYPE */)
+ map_init_nls(el);
+#endif
+ map_init_nls(el);
+
+ buf[0] = CONTROL('X');
+ buf[1] = CONTROL('X');
+ buf[2] = 0;
+ key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
+
+ tty_bind_char(el, 1);
+ term_bind_arrow(el);
+}
+
+
+/* map_set_editor():
+ * Set the editor
+ */
+protected int
+map_set_editor(el, editor)
+ EditLine *el;
+ char *editor;
+{
+ if (strcmp(editor, "emacs") == 0) {
+ map_init_emacs(el);
+ return 0;
+ }
+ if (strcmp(editor, "vi") == 0) {
+ map_init_vi(el);
+ return 0;
+ }
+ return -1;
+}
+
+
+/* map_print_key():
+ * Print the function description for 1 key
+ */
+private void
+map_print_key(el, map, in)
+ EditLine *el;
+ el_action_t *map;
+ char *in;
+{
+ char outbuf[EL_BUFSIZ];
+ el_bindings_t *bp;
+
+ if (in[0] == '\0' || in[1] == '\0') {
+ (void) key__decode_str(in, outbuf, "");
+ for (bp = el->el_map.help; bp->name != NULL; bp++)
+ if (bp->func == map[(unsigned char) *in]) {
+ (void) fprintf(el->el_outfile,
+ "%s\t->\t%s\n", outbuf, bp->name);
+ return;
+ }
+ }
+ else
+ key_print(el, in);
+}
+
+
+/* map_print_some_keys():
+ * Print keys from first to last
+ */
+private void
+map_print_some_keys(el, map, first, last)
+ EditLine *el;
+ el_action_t *map;
+ int first, last;
+{
+ el_bindings_t *bp;
+ char firstbuf[2], lastbuf[2];
+ char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ];
+
+ firstbuf[0] = first;
+ firstbuf[1] = 0;
+ lastbuf[0] = last;
+ lastbuf[1] = 0;
+ if (map[first] == ED_UNASSIGNED) {
+ if (first == last)
+ (void) fprintf(el->el_outfile, "%-15s-> is undefined\n",
+ key__decode_str(firstbuf, unparsbuf, STRQQ));
+ return;
+ }
+
+ for (bp = el->el_map.help; bp->name != NULL; bp++) {
+ if (bp->func == map[first]) {
+ if (first == last) {
+ (void) fprintf(el->el_outfile, "%-15s-> %s\n",
+ key__decode_str(firstbuf, unparsbuf, STRQQ),
+ bp->name);
+ }
+ else {
+ (void) fprintf(el->el_outfile, "%-4s to %-7s-> %s\n",
+ key__decode_str(firstbuf, unparsbuf, STRQQ),
+ key__decode_str(lastbuf, extrabuf, STRQQ),
+ bp->name);
+ }
+ return;
+ }
+ }
+#ifdef MAP_DEBUG
+ if (map == el->el_map.key) {
+ (void) fprintf(el->el_outfile, "BUG!!! %s isn't bound to anything.\n",
+ key__decode_str(firstbuf, unparsbuf, STRQQ));
+ (void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n",
+ first, el->el_map.key[first]);
+ }
+ else {
+ (void) fprintf(el->el_outfile, "BUG!!! %s isn't bound to anything.\n",
+ key__decode_str(firstbuf, unparsbuf, STRQQ));
+ (void) fprintf(el->el_outfile, "el->el_map.alt[%d] == %d\n",
+ first, el->el_map.alt[first]);
+ }
+#endif
+ abort();
+}
+
+
+/* map_print_all_keys():
+ * Print the function description for all keys.
+ */
+private void
+map_print_all_keys(el)
+ EditLine *el;
+{
+ int prev, i;
+
+ (void) fprintf(el->el_outfile, "Standard key bindings\n");
+ prev = 0;
+ for (i = 0; i < N_KEYS; i++) {
+ if (el->el_map.key[prev] == el->el_map.key[i])
+ continue;
+ map_print_some_keys(el, el->el_map.key, prev, i - 1);
+ prev = i;
+ }
+ map_print_some_keys(el, el->el_map.key, prev, i - 1);
+
+ (void) fprintf(el->el_outfile, "Alternative key bindings\n");
+ prev = 0;
+ for (i = 0; i < N_KEYS; i++) {
+ if (el->el_map.alt[prev] == el->el_map.alt[i])
+ continue;
+ map_print_some_keys(el, el->el_map.alt, prev, i - 1);
+ prev = i;
+ }
+ map_print_some_keys(el, el->el_map.alt, prev, i - 1);
+
+ (void) fprintf(el->el_outfile, "Multi-character bindings\n");
+ key_print(el, "");
+ (void) fprintf(el->el_outfile, "Arrow key bindings\n");
+ term_print_arrow(el, "");
+}
+
+
+/* map_bind():
+ * Add/remove/change bindings
+ */
+protected int
+map_bind(el, argc, argv)
+ EditLine *el;
+ int argc;
+ char **argv;
+{
+ el_action_t *map;
+ int ntype, remove;
+ char *p;
+ char inbuf[EL_BUFSIZ];
+ char outbuf[EL_BUFSIZ];
+ char *in = NULL;
+ char *out = NULL;
+ el_bindings_t *bp;
+ int cmd;
+ int key;
+
+ if (argv == NULL)
+ return -1;
+
+ map = el->el_map.key;
+ ntype = XK_CMD;
+ key = remove = 0;
+ for (argc = 1; (p = argv[argc]) != NULL; argc++)
+ if (p[0] == '-')
+ switch (p[1]) {
+ case 'a':
+ map = el->el_map.alt;
+ break;
+
+ case 's':
+ ntype = XK_STR;
+ break;
+#ifdef notyet
+ case 'c':
+ ntype = XK_EXE;
+ break;
+#endif
+ case 'k':
+ key = 1;
+ break;
+
+ case 'r':
+ remove = 1;
+ break;
+
+ case 'v':
+ map_init_vi(el);
+ return 0;
+
+ case 'e':
+ map_init_emacs(el);
+ return 0;
+
+ case 'l':
+ for (bp = el->el_map.help; bp->name != NULL; bp++)
+ (void) fprintf(el->el_outfile, "%s\n\t%s\n",
+ bp->name, bp->description);
+ return 0;
+ default:
+ (void) fprintf(el->el_errfile, "%s: Invalid switch `%c'.\n",
+ argv[0], p[1]);
+ }
+ else
+ break;
+
+ if (argv[argc] == NULL) {
+ map_print_all_keys(el);
+ return 0;
+ }
+
+ if (key)
+ in = argv[argc++];
+ else
+ if ((in = parse__string(inbuf, argv[argc++])) == NULL) {
+ (void) fprintf(el->el_errfile, "%s: Invalid \\ or ^ in instring.\n",
+ argv[0]);
+ return -1;
+ }
+
+ if (remove) {
+ if (key) {
+ (void) term_clear_arrow(el, in);
+ return -1;
+ }
+ if (in[1])
+ (void) key_delete(el, in);
+ else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN)
+ (void) key_delete(el, in);
+ else
+ map[(unsigned char) *in] = ED_UNASSIGNED;
+ return 0;
+ }
+
+ if (argv[argc] == NULL) {
+ if (key)
+ term_print_arrow(el, in);
+ else
+ map_print_key(el, map, in);
+ return 0;
+ }
+
+#ifdef notyet
+ if (argv[argc + 1] != NULL) {
+ bindkey_usage();
+ return -1;
+ }
+#endif
+
+ switch (ntype) {
+ case XK_STR:
+ case XK_EXE:
+ if ((out = parse__string(outbuf, argv[argc])) == NULL) {
+ (void) fprintf(el->el_errfile,
+ "%s: Invalid \\ or ^ in outstring.\n", argv[0]);
+ return -1;
+ }
+ if (key)
+ term_set_arrow(el, in, key_map_str(el, out), ntype);
+ else
+ key_add(el, in, key_map_str(el, out), ntype);
+ map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
+ break;
+
+ case XK_CMD:
+ if ((cmd = parse_cmd(el, argv[argc])) == -1) {
+ (void) fprintf(el->el_errfile,
+ "%s: Invalid command `%s'.\n", argv[0], argv[argc]);
+ return -1;
+ }
+ if (key)
+ term_set_arrow(el, in, key_map_str(el, out), ntype);
+ else {
+ if (in[1]) {
+ key_add(el, in, key_map_cmd(el, cmd), ntype);
+ map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
+ }
+ else {
+ key_clear(el, map, in);
+ map[(unsigned char) *in] = cmd;
+ }
+ }
+ break;
+
+ default:
+ abort();
+ break;
+ }
+ return 0;
+}
+
+
+/* map_addfunc():
+ * add a user defined function
+ */
+protected int
+map_addfunc(el, name, help, func)
+ EditLine *el;
+ const char *name;
+ const char *help;
+ el_func_t func;
+{
+ int nf = el->el_map.nfunc + 2;
+ if (name == NULL || help == NULL || func == NULL)
+ return -1;
+
+ el->el_map.func = (el_func_t *)
+ el_reallocf(el->el_map.func, nf * sizeof(el_func_t));
+ el->el_map.help = (el_bindings_t *)
+ el_reallocf(el->el_map.help, nf * sizeof(el_bindings_t));
+
+ nf = el->el_map.nfunc;
+ el->el_map.func[nf] = func;
+
+ el->el_map.help[nf].name = name;
+ el->el_map.help[nf].func = nf;
+ el->el_map.help[nf].description = help;
+ el->el_map.help[++nf].name = NULL;
+ el->el_map.nfunc++;
+
+ return 0;
+}
diff --git a/lib/libedit/map.h b/lib/libedit/map.h
new file mode 100644
index 0000000..c0f16f1
--- /dev/null
+++ b/lib/libedit/map.h
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)map.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.map.h: Editor maps
+ */
+#ifndef _h_el_map
+#define _h_el_map
+
+typedef struct el_bindings_t { /* for the "bind" shell command */
+ const char *name; /* function name for bind command */
+ int func; /* function numeric value */
+ const char *description; /* description of function */
+} el_bindings_t;
+
+
+typedef struct el_map_t {
+ el_action_t *alt; /* The current alternate key map */
+ el_action_t *key; /* The current normal key map */
+ el_action_t *current; /* The keymap we are using */
+ el_action_t *emacs; /* The default emacs key map */
+ el_action_t *vic; /* The vi command mode key map */
+ el_action_t *vii; /* The vi insert mode key map */
+ int type; /* Emacs or vi */
+ el_bindings_t *help; /* The help for the editor functions */
+ el_func_t *func; /* List of available functions */
+ int nfunc; /* The number of functions/help items */
+} el_map_t;
+
+#define MAP_EMACS 0
+#define MAP_VI 1
+
+protected int map_bind __P((EditLine *, int, char **));
+protected int map_init __P((EditLine *));
+protected void map_end __P((EditLine *));
+protected void map_init_vi __P((EditLine *));
+protected void map_init_emacs __P((EditLine *));
+protected int map_set_editor __P((EditLine *, char *));
+protected int map_addfunc __P((EditLine *, const char *,
+ const char *, el_func_t));
+
+#endif /* _h_el_map */
diff --git a/lib/libedit/parse.c b/lib/libedit/parse.c
new file mode 100644
index 0000000..dd5bd94
--- /dev/null
+++ b/lib/libedit/parse.c
@@ -0,0 +1,250 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * parse.c: parse an editline extended command
+ *
+ * commands are:
+ *
+ * bind
+ * echotc
+ * settc
+ * gettc
+ * history
+ * settc
+ * setty
+ */
+#include "sys.h"
+#include "el.h"
+#include "tokenizer.h"
+
+private struct {
+ char *name;
+ int (*func) __P((EditLine *, int, char **));
+} cmds[] = {
+ { "bind", map_bind },
+ { "echotc", term_echotc },
+ { "history", hist_list },
+ { "telltc", term_telltc },
+ { "settc", term_settc },
+ { "setty", tty_stty },
+ { NULL, NULL }
+};
+
+
+/* parse_line():
+ * Parse a line and dispatch it
+ */
+protected int
+parse_line(el, line)
+ EditLine *el;
+ const char *line;
+{
+ char **argv;
+ int argc;
+ Tokenizer *tok;
+
+ tok = tok_init(NULL);
+ tok_line(tok, line, &argc, &argv);
+ argc = el_parse(el, argc, argv);
+ tok_end(tok);
+ return argc;
+}
+
+/* el_parse():
+ * Command dispatcher
+ */
+public int
+el_parse(el, argc, argv)
+ EditLine *el;
+ int argc;
+ char *argv[];
+{
+ char *ptr;
+ int i;
+
+ if (argc < 1)
+ return -1;
+ ptr = strchr(argv[0], ':');
+ if (ptr != NULL) {
+ *ptr++ = '\0';
+ if (! el_match(el->el_prog, argv[0]))
+ return 0;
+ }
+ else
+ ptr = argv[0];
+
+ for (i = 0; cmds[i].name != NULL; i++)
+ if (strcmp(cmds[i].name, ptr) == 0) {
+ i = (*cmds[i].func)(el, argc, argv);
+ return -i;
+ }
+
+ return -1;
+}
+
+
+/* parse__escape():
+ * Parse a string of the form ^<char> \<odigit> \<char> and return
+ * the appropriate character or -1 if the escape is not valid
+ */
+protected int
+parse__escape(ptr)
+ const char ** const ptr;
+{
+ const char *p;
+ int c;
+
+ p = *ptr;
+
+ if (p[1] == 0)
+ return -1;
+
+ if (*p == '\\') {
+ p++;
+ switch (*p) {
+ case 'a':
+ c = '\007'; /* Bell */
+ break;
+ case 'b':
+ c = '\010'; /* Backspace */
+ break;
+ case 't':
+ c = '\011'; /* Horizontal Tab */
+ break;
+ case 'n':
+ c = '\012'; /* New Line */
+ break;
+ case 'v':
+ c = '\013'; /* Vertical Tab */
+ break;
+ case 'f':
+ c = '\014'; /* Form Feed */
+ break;
+ case 'r':
+ c = '\015'; /* Carriage Return */
+ break;
+ case 'e':
+ c = '\033'; /* Escape */
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ {
+ int cnt, ch;
+
+ for (cnt = 0, c = 0; cnt < 3; cnt++) {
+ ch = *p++;
+ if (ch < '0' || ch > '7') {
+ p--;
+ break;
+ }
+ c = (c << 3) | (ch - '0');
+ }
+ if ((c & 0xffffff00) != 0)
+ return -1;
+ --p;
+ }
+ break;
+ default:
+ c = *p;
+ break;
+ }
+ }
+ else if (*p == '^' && isascii(p[1]) && (p[1] == '?' || isalpha(p[1]))) {
+ p++;
+ c = (*p == '?') ? '\177' : (*p & 0237);
+ }
+ else
+ c = *p;
+ *ptr = ++p;
+ return (unsigned char)c;
+}
+
+/* parse__string():
+ * Parse the escapes from in and put the raw string out
+ */
+protected char *
+parse__string(out, in)
+ char *out;
+ const char *in;
+{
+ char *rv = out;
+ int n;
+ for (;;)
+ switch (*in) {
+ case '\0':
+ *out = '\0';
+ return rv;
+
+ case '\\':
+ case '^':
+ if ((n = parse__escape(&in)) == -1)
+ return NULL;
+ *out++ = n;
+ break;
+
+ default:
+ *out++ = *in++;
+ break;
+ }
+}
+
+/* parse_cmd():
+ * Return the command number for the command string given
+ * or -1 if one is not found
+ */
+protected int
+parse_cmd(el, cmd)
+ EditLine *el;
+ const char *cmd;
+{
+ el_bindings_t *b;
+
+ for (b = el->el_map.help; b->name != NULL; b++)
+ if (strcmp(b->name, cmd) == 0)
+ return b->func;
+ return -1;
+}
diff --git a/lib/libedit/parse.h b/lib/libedit/parse.h
new file mode 100644
index 0000000..0601746
--- /dev/null
+++ b/lib/libedit/parse.h
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)parse.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.parse.h: Parser functions
+ */
+#ifndef _h_el_parse
+#define _h_el_parse
+
+protected int parse_line __P((EditLine *, const char *));
+protected int parse__escape __P((const char ** const));
+protected char * parse__string __P((char *, const char *));
+protected int parse_cmd __P((EditLine *, const char *));
+
+#endif /* _h_el_parse */
diff --git a/lib/libedit/prompt.c b/lib/libedit/prompt.c
new file mode 100644
index 0000000..59ba200
--- /dev/null
+++ b/lib/libedit/prompt.c
@@ -0,0 +1,123 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * prompt.c: Prompt printing functions
+ */
+#include "sys.h"
+#include <stdio.h>
+#include "el.h"
+
+private char *prompt_default __P((EditLine *));
+
+/* prompt_default():
+ * Just a default prompt, in case the user did not provide one
+ */
+private char *
+/*ARGSUSED*/
+prompt_default(el)
+ EditLine *el;
+{
+ static char a[3] = { '?', ' ', '\0' };
+ return a;
+}
+
+
+/* prompt_print():
+ * Print the prompt and update the prompt position.
+ * We use an array of integers in case we want to pass
+ * literal escape sequences in the prompt and we want a
+ * bit to flag them
+ */
+protected void
+prompt_print(el)
+ EditLine *el;
+{
+ char *p = (*el->el_prompt.p_func)(el);
+ while (*p)
+ re_putc(el, *p++);
+
+ el->el_prompt.p_pos.v = el->el_refresh.r_cursor.v;
+ el->el_prompt.p_pos.h = el->el_refresh.r_cursor.h;
+
+} /* end prompt_print */
+
+
+/* prompt_init():
+ * Initialize the prompt stuff
+ */
+protected int
+prompt_init(el)
+ EditLine *el;
+{
+ el->el_prompt.p_func = prompt_default;
+ el->el_prompt.p_pos.v = 0;
+ el->el_prompt.p_pos.h = 0;
+ return 0;
+} /* end prompt_init */
+
+
+/* prompt_end():
+ * Clean up the prompt stuff
+ */
+protected void
+/*ARGSUSED*/
+prompt_end(el)
+ EditLine *el;
+{
+} /* end prompt_end */
+
+
+/* prompt_set():
+ * Install a prompt printing function
+ */
+protected int
+prompt_set(el, prf)
+ EditLine *el;
+ el_pfunc_t prf;
+{
+ if (prf == NULL)
+ el->el_prompt.p_func = prompt_default;
+ else
+ el->el_prompt.p_func = prf;
+ el->el_prompt.p_pos.v = 0;
+ el->el_prompt.p_pos.h = 0;
+ return 0;
+} /* end prompt_set */
diff --git a/lib/libedit/prompt.h b/lib/libedit/prompt.h
new file mode 100644
index 0000000..a624fc0
--- /dev/null
+++ b/lib/libedit/prompt.h
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)prompt.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.prompt.h: Prompt printing stuff
+ */
+#ifndef _h_el_prompt
+#define _h_el_prompt
+
+#include "histedit.h"
+
+typedef char * (*el_pfunc_t) __P((EditLine*));
+
+typedef struct el_prompt_t {
+ el_pfunc_t p_func; /* Function to return the prompt */
+ coord_t p_pos; /* position in the line after prompt */
+} el_prompt_t;
+
+protected void prompt_print __P((EditLine *));
+protected int prompt_set __P((EditLine *, el_pfunc_t));
+protected int prompt_init __P((EditLine *));
+protected void prompt_end __P((EditLine *));
+
+#endif /* _h_el_prompt */
diff --git a/lib/libedit/read.c b/lib/libedit/read.c
new file mode 100644
index 0000000..d8d6628
--- /dev/null
+++ b/lib/libedit/read.c
@@ -0,0 +1,446 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
+
+#endif /* not lint && not SCCSID */
+/*
+ * read.c: Clean this junk up! This is horrible code.
+ * Terminal read functions
+ */
+#include "sys.h"
+#include <sys/errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+extern int errno;
+#include "el.h"
+
+#define OKCMD -1
+
+private int read__fixio __P((int, int));
+private int read_preread __P((EditLine *));
+private int read_getcmd __P((EditLine *, el_action_t *, char *));
+
+#ifdef DEBUG_EDIT
+private void
+read_debug(el)
+ EditLine *el;
+{
+
+ if (el->el_line.cursor > el->el_line.lastchar)
+ (void) fprintf(el->el_errfile, "cursor > lastchar\r\n");
+ if (el->el_line.cursor < el->el_line.buffer)
+ (void) fprintf(el->el_errfile, "cursor < buffer\r\n");
+ if (el->el_line.cursor > el->el_line.limit)
+ (void) fprintf(el->el_errfile, "cursor > limit\r\n");
+ if (el->el_line.lastchar > el->el_line.limit)
+ (void) fprintf(el->el_errfile, "lastchar > limit\r\n");
+ if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2])
+ (void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n");
+}
+#endif /* DEBUG_EDIT */
+
+/* read__fixio():
+ * Try to recover from a read error
+ */
+private int
+read__fixio(fd, e)
+ int fd, e;
+{
+ switch (e) {
+ case -1: /* Make sure that the code is reachable */
+
+#ifdef EWOULDBLOCK
+ case EWOULDBLOCK:
+# ifndef TRY_AGAIN
+# define TRY_AGAIN
+# endif
+#endif /* EWOULDBLOCK */
+
+#if defined(POSIX) && defined(EAGAIN)
+# if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
+ case EAGAIN:
+# ifndef TRY_AGAIN
+# define TRY_AGAIN
+# endif
+# endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
+#endif /* POSIX && EAGAIN */
+
+ e = 0;
+#ifdef TRY_AGAIN
+# if defined(F_SETFL) && defined(O_NDELAY)
+ if ((e = fcntl(fd, F_GETFL, 0)) == -1)
+ return -1;
+
+ if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
+ return -1;
+ else
+ e = 1;
+# endif /* F_SETFL && O_NDELAY */
+
+# ifdef FIONBIO
+ if (ioctl(fd, FIONBIO, (ioctl_t) &e) == -1)
+ return -1;
+ else
+ e = 1;
+# endif /* FIONBIO */
+
+#endif /* TRY_AGAIN */
+ return e ? 0 : -1;
+
+ case EINTR:
+ return 0;
+
+ default:
+ return -1;
+ }
+}
+
+
+/* read_preread():
+ * Try to read the stuff in the input queue;
+ */
+private int
+read_preread(el)
+ EditLine *el;
+{
+ int chrs = 0;
+
+ if (el->el_chared.c_macro.nline) {
+ el_free((ptr_t) el->el_chared.c_macro.nline);
+ el->el_chared.c_macro.nline = NULL;
+ }
+
+ if (el->el_tty.t_mode == ED_IO)
+ return 0;
+
+#ifdef FIONREAD
+ (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) &chrs);
+ if (chrs > 0) {
+ char buf[EL_BUFSIZ];
+
+ chrs = read(el->el_infd, buf, (size_t) MIN(chrs, EL_BUFSIZ - 1));
+ if (chrs > 0) {
+ buf[chrs] = '\0';
+ el->el_chared.c_macro.nline = strdup(buf);
+ el_push(el->el_chared.c_macro.nline);
+ }
+ }
+#endif /* FIONREAD */
+
+ return chrs > 0;
+}
+
+
+/* el_push():
+ * Push a macro
+ */
+public void
+el_push(el, str)
+ EditLine *el;
+ const char *str;
+{
+ c_macro_t *ma = &el->el_chared.c_macro;
+
+ if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
+ ma->level++;
+ ma->macro[ma->level] = (char *) str;
+ }
+ else {
+ term_beep(el);
+ term__flush();
+ }
+}
+
+
+/* read_getcmd():
+ * Return next command from the input stream.
+ */
+private int
+read_getcmd(el, cmdnum, ch)
+ EditLine *el;
+ el_action_t *cmdnum;
+ char *ch;
+{
+ el_action_t cmd = ED_UNASSIGNED;
+ int num;
+
+ while (cmd == ED_UNASSIGNED || cmd == ED_SEQUENCE_LEAD_IN) {
+ if ((num = el_getc(el, ch)) != 1) /* if EOF or error */
+ return num;
+
+#ifdef KANJI
+ if ((*ch & 0200)) {
+ el->el_state.metanext = 0;
+ cmd = CcViMap[' '];
+ break;
+ }
+ else
+#endif /* KANJI */
+
+ if (el->el_state.metanext) {
+ el->el_state.metanext = 0;
+ *ch |= 0200;
+ }
+ cmd = el->el_map.current[(unsigned char) *ch];
+ if (cmd == ED_SEQUENCE_LEAD_IN) {
+ key_value_t val;
+ switch (key_get(el, ch, &val)) {
+ case XK_CMD:
+ cmd = val.cmd;
+ break;
+ case XK_STR:
+ el_push(el, val.str);
+ break;
+#ifdef notyet
+ case XK_EXE:
+ /* XXX: In the future to run a user function */
+ RunCommand(val.str);
+ break;
+#endif
+ default:
+ abort();
+ break;
+ }
+ }
+ if (el->el_map.alt == NULL)
+ el->el_map.current = el->el_map.key;
+ }
+ *cmdnum = cmd;
+ return OKCMD;
+}
+
+
+/* el_getc():
+ * Read a character
+ */
+public int
+el_getc(el, cp)
+ EditLine *el;
+ char *cp;
+{
+ int num_read;
+ unsigned char tcp;
+ int tried = 0;
+
+ c_macro_t *ma = &el->el_chared.c_macro;
+
+ term__flush();
+ for (;;) {
+ if (ma->level < 0) {
+ if (!read_preread(el))
+ break;
+ }
+ if (ma->level < 0)
+ break;
+
+ if (*ma->macro[ma->level] == 0) {
+ ma->level--;
+ continue;
+ }
+ *cp = *ma->macro[ma->level]++ & 0377;
+ if (*ma->macro[ma->level] == 0) { /* Needed for QuoteMode On */
+ ma->level--;
+ }
+ return 1;
+ }
+
+#ifdef DEBUG_READ
+ (void) fprintf(el->el_errfile, "Turning raw mode on\n");
+#endif /* DEBUG_READ */
+ if (tty_rawmode(el) < 0) /* make sure the tty is set up correctly */
+ return 0;
+
+#ifdef DEBUG_READ
+ (void) fprintf(el->el_errfile, "Reading a character\n");
+#endif /* DEBUG_READ */
+ while ((num_read = read(el->el_infd, (char *) &tcp, 1)) == -1)
+ if (!tried && read__fixio(el->el_infd, errno) == 0)
+ tried = 1;
+ else {
+ *cp = '\0';
+ return -1;
+ }
+#ifdef DEBUG_READ
+ (void) fprintf(el->el_errfile, "Got it %c\n", tcp);
+#endif /* DEBUG_READ */
+ *cp = tcp;
+ return num_read;
+}
+
+
+
+public const char *
+el_gets(el, nread)
+ EditLine *el;
+ int *nread;
+{
+ int retval;
+ el_action_t cmdnum = 0;
+ int num; /* how many chars we have read at NL */
+ char ch;
+
+ if (el->el_flags & HANDLE_SIGNALS)
+ sig_set(el);
+
+ re_clear_display(el); /* reset the display stuff */
+ ch_reset(el);
+
+#ifdef FIONREAD
+ if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
+ long chrs = 0;
+
+ (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) &chrs);
+ if (chrs == 0) {
+ if (tty_rawmode(el) < 0) {
+ if (nread)
+ *nread = 0;
+ return NULL;
+ }
+ }
+ }
+#endif /* FIONREAD */
+
+ re_refresh(el); /* print the prompt */
+
+ for (num = OKCMD; num == OKCMD;) { /* while still editing this line */
+#ifdef DEBUG_EDIT
+ read_debug(el);
+#endif /* DEBUG_EDIT */
+ /* if EOF or error */
+ if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
+#ifdef DEBUG_READ
+ (void) fprintf(el->el_errfile, "Returning from el_gets %d\n", num);
+#endif /* DEBUG_READ */
+ break;
+ }
+
+ if (cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
+#ifdef DEBUG_EDIT
+ (void) fprintf(el->el_errfile,
+ "ERROR: illegal command from key 0%o\r\n", ch);
+#endif /* DEBUG_EDIT */
+ continue; /* try again */
+ }
+
+ /* now do the real command */
+#ifdef DEBUG_READ
+ {
+ el_bindings_t *b;
+ for (b = el->el_map.help; b->name; b++)
+ if (b->func == cmdnum)
+ break;
+ if (b->name)
+ (void) fprintf(el->el_errfile, "Executing %s\n", b->name);
+ else
+ (void) fprintf(el->el_errfile, "Error command = %d\n", cmdnum);
+ }
+#endif /* DEBUG_READ */
+ retval = (*el->el_map.func[cmdnum])(el, ch);
+
+ /* save the last command here */
+ el->el_state.lastcmd = cmdnum;
+
+ /* use any return value */
+ switch (retval) {
+ case CC_CURSOR:
+ el->el_state.argument = 1;
+ el->el_state.doingarg = 0;
+ re_refresh_cursor(el);
+ break;
+
+ case CC_REDISPLAY:
+ re_clear_lines(el);
+ re_clear_display(el);
+ /* FALLTHROUGH */
+
+ case CC_REFRESH:
+ el->el_state.argument = 1;
+ el->el_state.doingarg = 0;
+ re_refresh(el);
+ break;
+
+ case CC_NORM: /* normal char */
+ el->el_state.argument = 1;
+ el->el_state.doingarg = 0;
+ break;
+
+ case CC_ARGHACK: /* Suggested by Rich Salz */
+ /* <rsalz@pineapple.bbn.com> */
+ break; /* keep going... */
+
+ case CC_EOF: /* end of file typed */
+ num = 0;
+ break;
+
+ case CC_NEWLINE: /* normal end of line */
+ num = el->el_line.lastchar - el->el_line.buffer;
+ break;
+
+ case CC_FATAL: /* fatal error, reset to known state */
+#ifdef DEBUG_READ
+ (void) fprintf(el->el_errfile, "*** editor fatal ERROR ***\r\n\n");
+#endif /* DEBUG_READ */
+ /* put (real) cursor in a known place */
+ re_clear_display(el); /* reset the display stuff */
+ ch_reset(el); /* reset the input pointers */
+ re_refresh(el); /* print the prompt again */
+ el->el_state.argument = 1;
+ el->el_state.doingarg = 0;
+ break;
+
+ case CC_ERROR:
+ default: /* functions we don't know about */
+#ifdef DEBUG_READ
+ (void) fprintf(el->el_errfile, "*** editor ERROR ***\r\n\n");
+#endif /* DEBUG_READ */
+ el->el_state.argument = 1;
+ el->el_state.doingarg = 0;
+ term_beep(el);
+ term__flush();
+ break;
+ }
+ }
+
+ (void) tty_cookedmode(el); /* make sure the tty is set up correctly */
+ term__flush(); /* flush any buffered output */
+ if (el->el_flags & HANDLE_SIGNALS)
+ sig_clr(el);
+ if (nread)
+ *nread = num;
+ return num ? el->el_line.buffer : NULL;
+}
diff --git a/lib/libedit/refresh.c b/lib/libedit/refresh.c
new file mode 100644
index 0000000..6c3ee93
--- /dev/null
+++ b/lib/libedit/refresh.c
@@ -0,0 +1,1015 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * refresh.c: Lower level screen refreshing functions
+ */
+#include "sys.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "el.h"
+
+private void re_addc __P((EditLine *, int));
+private void re_update_line __P((EditLine *, char *, char *, int));
+private void re_insert __P((EditLine *, char *, int, int,
+ char *, int));
+private void re_delete __P((EditLine *, char *, int, int,
+ int));
+private void re_fastputc __P((EditLine *, int));
+
+private void re__strncopy __P((char *, char *, size_t));
+private void re__copy_and_pad __P((char *, char *, size_t));
+
+#ifdef DEBUG_REFRESH
+private void re_printstr __P((EditLine *, char *, char *,
+ char *));
+# define __F el->el_errfile
+# define RE_DEBUG(a, b, c) do \
+ if (a) { \
+ (void) fprintf b; \
+ c; \
+ } \
+ while (0)
+/* re_printstr():
+ * Print a string on the debugging pty
+ */
+private void
+re_printstr(el, str, f, t)
+ EditLine *el;
+ char *str;
+ char *f, *t;
+{
+ RE_DEBUG(1,(__F, "%s:\"", str),);
+ while (f < t)
+ RE_DEBUG(1,(__F, "%c", *f++ & 0177),);
+ RE_DEBUG(1,(__F, "\"\r\n"),);
+}
+#else
+# define RE_DEBUG(a, b, c)
+#endif
+
+
+/* re_addc():
+ * Draw c, expanding tabs, control chars etc.
+ */
+private void
+re_addc(el, c)
+ EditLine *el;
+ int c;
+{
+ c = (unsigned char)c;
+
+ if (isprint(c)) {
+ re_putc(el, c);
+ return;
+ }
+ if (c == '\n') { /* expand the newline */
+ re_putc(el, '\0'); /* assure end of line */
+ el->el_refresh.r_cursor.h = 0; /* reset cursor pos */
+ el->el_refresh.r_cursor.v++;
+ return;
+ }
+ if (c == '\t') { /* expand the tab */
+ for (;;) {
+ re_putc(el, ' ');
+ if ((el->el_refresh.r_cursor.h & 07) == 0)
+ break; /* go until tab stop */
+ }
+ }
+ else if (iscntrl(c)) {
+ re_putc(el, '^');
+ if (c == 0177)
+ re_putc(el, '?');
+ else
+ /* uncontrolify it; works only for iso8859-1 like sets */
+ re_putc(el, (toascii(c) | 0100));
+ }
+ else {
+ re_putc(el, '\\');
+ re_putc(el, ((c >> 6) & 07) + '0');
+ re_putc(el, ((c >> 3) & 07) + '0');
+ re_putc(el, (c & 07) + '0');
+ }
+} /* end re_addc */
+
+
+/* re_putc():
+ * Draw the character given
+ */
+protected void
+re_putc(el, c)
+ EditLine *el;
+ int c;
+{
+ RE_DEBUG(1,(__F, "printing %3.3o '%c'\r\n", c, c),);
+
+ el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_refresh.r_cursor.h] = c;
+ el->el_refresh.r_cursor.h++; /* advance to next place */
+ if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) {
+ el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] = '\0';
+ /* assure end of line */
+ el->el_refresh.r_cursor.h = 0; /* reset it. */
+ el->el_refresh.r_cursor.v++;
+ RE_DEBUG(el->el_refresh.r_cursor.v >= el->el_term.t_size.v,
+ (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
+ el->el_refresh.r_cursor.v, el->el_term.t_size.v), abort());
+ }
+} /* end re_putc */
+
+
+/* re_refresh():
+ * draws the new virtual screen image from the current input
+ * line, then goes line-by-line changing the real image to the new
+ * virtual image. The routine to re-draw a line can be replaced
+ * easily in hopes of a smarter one being placed there.
+ */
+protected void
+re_refresh(el)
+ EditLine *el;
+{
+ int i;
+ char *cp;
+ coord_t cur;
+
+ RE_DEBUG(1,(__F, "el->el_line.buffer = :%s:\r\n", el->el_line.buffer),);
+
+ /* reset the Drawing cursor */
+ el->el_refresh.r_cursor.h = 0;
+ el->el_refresh.r_cursor.v = 0;
+
+ cur.h = -1; /* set flag in case I'm not set */
+ cur.v = 0;
+
+ prompt_print(el);
+
+ /* draw the current input buffer */
+ for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) {
+ if (cp == el->el_line.cursor) {
+ cur.h = el->el_refresh.r_cursor.h; /* save for later */
+ cur.v = el->el_refresh.r_cursor.v;
+ }
+ re_addc(el, *cp);
+ }
+
+ if (cur.h == -1) { /* if I haven't been set yet, I'm at the end */
+ cur.h = el->el_refresh.r_cursor.h;
+ cur.v = el->el_refresh.r_cursor.v;
+ }
+ /* must be done BEFORE the NUL is written */
+ el->el_refresh.r_newcv = el->el_refresh.r_cursor.v;
+ re_putc(el, '\0'); /* put NUL on end */
+
+ RE_DEBUG(1,(__F,
+ "term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
+ el->el_term.t_size.h, el->el_refresh.r_cursor.h,
+ el->el_refresh.r_cursor.v, el->el_vdisplay[0]),);
+
+ RE_DEBUG(1,(__F, "updating %d lines.\r\n", el->el_refresh.r_newcv),);
+ for (i = 0; i <= el->el_refresh.r_newcv; i++) {
+ /* NOTE THAT re_update_line MAY CHANGE el_display[i] */
+ re_update_line(el, el->el_display[i], el->el_vdisplay[i], i);
+
+ /*
+ * Copy the new line to be the current one, and pad out with spaces
+ * to the full width of the terminal so that if we try moving the
+ * cursor by writing the character that is at the end of the
+ * screen line, it won't be a NUL or some old leftover stuff.
+ */
+ re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
+ el->el_term.t_size.h);
+ }
+ RE_DEBUG(1,(__F,
+ "\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
+ el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i),);
+
+ if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
+ for (; i <= el->el_refresh.r_oldcv; i++) {
+ term_move_to_line(el, i);
+ term_move_to_char(el, 0);
+ term_clear_EOL(el, strlen(el->el_display[i]));
+#ifdef DEBUG_REFRESH
+ term_overwrite(el, "C\b", 2);
+#endif /* DEBUG_REFRESH */
+ *el->el_display[i] = '\0';
+ }
+
+ el->el_refresh.r_oldcv = el->el_refresh.r_newcv; /* set for next time */
+ RE_DEBUG(1,(__F,
+ "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
+ el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
+ cur.h, cur.v),);
+ term_move_to_line(el, cur.v); /* go to where the cursor is */
+ term_move_to_char(el, cur.h);
+} /* end re_refresh */
+
+
+/* re_goto_bottom():
+ * used to go to last used screen line
+ */
+protected void
+re_goto_bottom(el)
+ EditLine *el;
+{
+ term_move_to_line(el, el->el_refresh.r_oldcv);
+ term__putc('\r');
+ term__putc('\n');
+ re_clear_display(el);
+ term__flush();
+} /* end re_goto_bottom */
+
+
+/* re_insert():
+ * insert num characters of s into d (in front of the character)
+ * at dat, maximum length of d is dlen
+ */
+private void
+/*ARGSUSED*/
+re_insert(el, d, dat, dlen, s, num)
+ EditLine *el;
+ char *d;
+ int dat, dlen;
+ char *s;
+ int num;
+{
+ char *a, *b;
+
+ if (num <= 0)
+ return;
+ if (num > dlen - dat)
+ num = dlen - dat;
+
+ RE_DEBUG(1,(__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
+ num, dat, dlen, d),);
+ RE_DEBUG(1,(__F, "s == \"%s\"n", s),);
+
+ /* open up the space for num chars */
+ if (num > 0) {
+ b = d + dlen - 1;
+ a = b - num;
+ while (a >= &d[dat])
+ *b-- = *a--;
+ d[dlen] = '\0'; /* just in case */
+ }
+ RE_DEBUG(1,(__F,
+ "re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
+ num, dat, dlen, d),);
+ RE_DEBUG(1,(__F, "s == \"%s\"n", s),);
+
+ /* copy the characters */
+ for (a = d + dat; (a < d + dlen) && (num > 0); num--)
+ *a++ = *s++;
+
+ RE_DEBUG(1,(__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
+ num, dat, dlen, d, s),);
+ RE_DEBUG(1,(__F, "s == \"%s\"n", s),);
+} /* end re_insert */
+
+
+/* re_delete():
+ * delete num characters d at dat, maximum length of d is dlen
+ */
+private void
+/*ARGSUSED*/
+re_delete(el, d, dat, dlen, num)
+ EditLine *el;
+ char *d;
+ int dat, dlen, num;
+{
+ char *a, *b;
+
+ if (num <= 0)
+ return;
+ if (dat + num >= dlen) {
+ d[dat] = '\0';
+ return;
+ }
+
+ RE_DEBUG(1,(__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
+ num, dat, dlen, d),);
+
+ /* open up the space for num chars */
+ if (num > 0) {
+ b = d + dat;
+ a = b + num;
+ while (a < &d[dlen])
+ *b++ = *a++;
+ d[dlen] = '\0'; /* just in case */
+ }
+ RE_DEBUG(1,(__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
+ num, dat, dlen, d),);
+} /* end re_delete */
+
+
+/* re__strncopy():
+ * Like strncpy without padding.
+ */
+private void
+re__strncopy(a, b, n)
+ char *a, *b;
+ size_t n;
+{
+ while (n-- && *b)
+ *a++ = *b++;
+} /* end re__strncopy */
+
+
+/* ****************************************************************
+ re_update_line() is based on finding the middle difference of each line
+ on the screen; vis:
+
+ /old first difference
+ /beginning of line | /old last same /old EOL
+ v v v v
+old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
+new: eddie> Oh, my little buggy says to me, as lurgid as
+ ^ ^ ^ ^
+ \beginning of line | \new last same \new end of line
+ \new first difference
+
+ all are character pointers for the sake of speed. Special cases for
+ no differences, as well as for end of line additions must be handled.
+**************************************************************** */
+
+/* Minimum at which doing an insert it "worth it". This should be about
+ * half the "cost" of going into insert mode, inserting a character, and
+ * going back out. This should really be calculated from the termcap
+ * data... For the moment, a good number for ANSI terminals.
+ */
+#define MIN_END_KEEP 4
+
+private void
+re_update_line(el, old, new, i)
+ EditLine *el;
+ char *old, *new;
+ int i;
+{
+ char *o, *n, *p, c;
+ char *ofd, *ols, *oe, *nfd, *nls, *ne;
+ char *osb, *ose, *nsb, *nse;
+ int fx, sx;
+
+ /*
+ * find first diff
+ */
+ for (o = old, n = new; *o && (*o == *n); o++, n++)
+ continue;
+ ofd = o;
+ nfd = n;
+
+ /*
+ * Find the end of both old and new
+ */
+ while (*o)
+ o++;
+ /*
+ * Remove any trailing blanks off of the end, being careful not to
+ * back up past the beginning.
+ */
+ while (ofd < o) {
+ if (o[-1] != ' ')
+ break;
+ o--;
+ }
+ oe = o;
+ *oe = '\0';
+
+ while (*n)
+ n++;
+
+ /* remove blanks from end of new */
+ while (nfd < n) {
+ if (n[-1] != ' ')
+ break;
+ n--;
+ }
+ ne = n;
+ *ne = '\0';
+
+ /*
+ * if no diff, continue to next line of redraw
+ */
+ if (*ofd == '\0' && *nfd == '\0') {
+ RE_DEBUG(1,(__F, "no difference.\r\n"),);
+ return;
+ }
+
+ /*
+ * find last same pointer
+ */
+ while ((o > ofd) && (n > nfd) && (*--o == *--n))
+ continue;
+ ols = ++o;
+ nls = ++n;
+
+ /*
+ * find same begining and same end
+ */
+ osb = ols;
+ nsb = nls;
+ ose = ols;
+ nse = nls;
+
+ /*
+ * case 1: insert: scan from nfd to nls looking for *ofd
+ */
+ if (*ofd) {
+ for (c = *ofd, n = nfd; n < nls; n++) {
+ if (c == *n) {
+ for (o = ofd, p = n; p < nls && o < ols && *o == *p; o++, p++)
+ continue;
+ /*
+ * if the new match is longer and it's worth keeping, then we
+ * take it
+ */
+ if (((nse - nsb) < (p - n)) && (2 * (p - n) > n - nfd)) {
+ nsb = n;
+ nse = p;
+ osb = ofd;
+ ose = o;
+ }
+ }
+ }
+ }
+
+ /*
+ * case 2: delete: scan from ofd to ols looking for *nfd
+ */
+ if (*nfd) {
+ for (c = *nfd, o = ofd; o < ols; o++) {
+ if (c == *o) {
+ for (n = nfd, p = o; p < ols && n < nls && *p == *n; p++, n++)
+ continue;
+ /*
+ * if the new match is longer and it's worth keeping, then we
+ * take it
+ */
+ if (((ose - osb) < (p - o)) && (2 * (p - o) > o - ofd)) {
+ nsb = nfd;
+ nse = n;
+ osb = o;
+ ose = p;
+ }
+ }
+ }
+ }
+
+ /*
+ * Pragmatics I: If old trailing whitespace or not enough characters to
+ * save to be worth it, then don't save the last same info.
+ */
+ if ((oe - ols) < MIN_END_KEEP) {
+ ols = oe;
+ nls = ne;
+ }
+
+ /*
+ * Pragmatics II: if the terminal isn't smart enough, make the data dumber
+ * so the smart update doesn't try anything fancy
+ */
+
+ /*
+ * fx is the number of characters we need to insert/delete: in the
+ * beginning to bring the two same begins together
+ */
+ fx = (nsb - nfd) - (osb - ofd);
+ /*
+ * sx is the number of characters we need to insert/delete: in the end to
+ * bring the two same last parts together
+ */
+ sx = (nls - nse) - (ols - ose);
+
+ if (!EL_CAN_INSERT) {
+ if (fx > 0) {
+ osb = ols;
+ ose = ols;
+ nsb = nls;
+ nse = nls;
+ }
+ if (sx > 0) {
+ ols = oe;
+ nls = ne;
+ }
+ if ((ols - ofd) < (nls - nfd)) {
+ ols = oe;
+ nls = ne;
+ }
+ }
+ if (!EL_CAN_DELETE) {
+ if (fx < 0) {
+ osb = ols;
+ ose = ols;
+ nsb = nls;
+ nse = nls;
+ }
+ if (sx < 0) {
+ ols = oe;
+ nls = ne;
+ }
+ if ((ols - ofd) > (nls - nfd)) {
+ ols = oe;
+ nls = ne;
+ }
+ }
+
+ /*
+ * Pragmatics III: make sure the middle shifted pointers are correct if
+ * they don't point to anything (we may have moved ols or nls).
+ */
+ /* if the change isn't worth it, don't bother */
+ /* was: if (osb == ose) */
+ if ((ose - osb) < MIN_END_KEEP) {
+ osb = ols;
+ ose = ols;
+ nsb = nls;
+ nse = nls;
+ }
+
+ /*
+ * Now that we are done with pragmatics we recompute fx, sx
+ */
+ fx = (nsb - nfd) - (osb - ofd);
+ sx = (nls - nse) - (ols - ose);
+
+ RE_DEBUG(1,(__F, "\n"),);
+ RE_DEBUG(1,(__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
+ ofd - old, osb - old, ose - old, ols - old, oe - old),);
+ RE_DEBUG(1,(__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n",
+ nfd - new, nsb - new, nse - new, nls - new, ne - new),);
+ RE_DEBUG(1,(__F,
+ "xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n"),);
+ RE_DEBUG(1,(__F,
+ "xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n"),);
+#ifdef DEBUG_REFRESH
+ re_printstr(el, "old- oe", old, oe);
+ re_printstr(el, "new- ne", new, ne);
+ re_printstr(el, "old-ofd", old, ofd);
+ re_printstr(el, "new-nfd", new, nfd);
+ re_printstr(el, "ofd-osb", ofd, osb);
+ re_printstr(el, "nfd-nsb", nfd, nsb);
+ re_printstr(el, "osb-ose", osb, ose);
+ re_printstr(el, "nsb-nse", nsb, nse);
+ re_printstr(el, "ose-ols", ose, ols);
+ re_printstr(el, "nse-nls", nse, nls);
+ re_printstr(el, "ols- oe", ols, oe);
+ re_printstr(el, "nls- ne", nls, ne);
+#endif /* DEBUG_REFRESH */
+
+ /*
+ * el_cursor.v to this line i MUST be in this routine so that if we
+ * don't have to change the line, we don't move to it. el_cursor.h to first
+ * diff char
+ */
+ term_move_to_line(el, i);
+
+ /*
+ * at this point we have something like this:
+ *
+ * /old /ofd /osb /ose /ols /oe
+ * v.....................v v..................v v........v
+ * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as
+ * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as
+ * ^.....................^ ^..................^ ^........^
+ * \new \nfd \nsb \nse \nls \ne
+ *
+ * fx is the difference in length between the the chars between nfd and
+ * nsb, and the chars between ofd and osb, and is thus the number of
+ * characters to delete if < 0 (new is shorter than old, as above),
+ * or insert (new is longer than short).
+ *
+ * sx is the same for the second differences.
+ */
+
+ /*
+ * if we have a net insert on the first difference, AND inserting the net
+ * amount ((nsb-nfd) - (osb-ofd)) won't push the last useful character
+ * (which is ne if nls != ne, otherwise is nse) off the edge of the screen
+ * (el->el_term.t_size.h) else we do the deletes first so that we keep everything we need
+ * to.
+ */
+
+ /*
+ * if the last same is the same like the end, there is no last same part,
+ * otherwise we want to keep the last same part set p to the last useful
+ * old character
+ */
+ p = (ols != oe) ? oe : ose;
+
+ /*
+ * if (There is a diffence in the beginning) && (we need to insert
+ * characters) && (the number of characters to insert is less than the term
+ * width) We need to do an insert! else if (we need to delete characters)
+ * We need to delete characters! else No insert or delete
+ */
+ if ((nsb != nfd) && fx > 0 && ((p - old) + fx <= el->el_term.t_size.h)) {
+ RE_DEBUG(1,(__F, "first diff insert at %d...\r\n", nfd - new),);
+ /*
+ * Move to the first char to insert, where the first diff is.
+ */
+ term_move_to_char(el, nfd - new);
+ /*
+ * Check if we have stuff to keep at end
+ */
+ if (nsb != ne) {
+ RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),);
+ /*
+ * insert fx chars of new starting at nfd
+ */
+ if (fx > 0) {
+ RE_DEBUG(!EL_CAN_INSERT,
+ (__F, "ERROR: cannot insert in early first diff\n"),);
+ term_insertwrite(el, nfd, fx);
+ re_insert(el, old, ofd - old, el->el_term.t_size.h, nfd, fx);
+ }
+ /*
+ * write (nsb-nfd) - fx chars of new starting at (nfd + fx)
+ */
+ term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
+ re__strncopy(ofd + fx, nfd + fx, (nsb - nfd) - fx);
+ }
+ else {
+ RE_DEBUG(1,(__F, "without anything to save\r\n"),);
+ term_overwrite(el, nfd, (nsb - nfd));
+ re__strncopy(ofd, nfd, (nsb - nfd));
+ /*
+ * Done
+ */
+ return;
+ }
+ }
+ else if (fx < 0) {
+ RE_DEBUG(1,(__F, "first diff delete at %d...\r\n", ofd - old),);
+ /*
+ * move to the first char to delete where the first diff is
+ */
+ term_move_to_char(el, ofd - old);
+ /*
+ * Check if we have stuff to save
+ */
+ if (osb != oe) {
+ RE_DEBUG(1,(__F, "with stuff to save at end\r\n"),);
+ /*
+ * fx is less than zero *always* here but we check for code
+ * symmetry
+ */
+ if (fx < 0) {
+ RE_DEBUG(!EL_CAN_DELETE,
+ (__F, "ERROR: cannot delete in first diff\n"),);
+ term_deletechars(el, -fx);
+ re_delete(el, old, ofd - old, el->el_term.t_size.h, -fx);
+ }
+ /*
+ * write (nsb-nfd) chars of new starting at nfd
+ */
+ term_overwrite(el, nfd, (nsb - nfd));
+ re__strncopy(ofd, nfd, (nsb - nfd));
+
+ }
+ else {
+ RE_DEBUG(1,(__F, "but with nothing left to save\r\n"),);
+ /*
+ * write (nsb-nfd) chars of new starting at nfd
+ */
+ term_overwrite(el, nfd, (nsb - nfd));
+ RE_DEBUG(1,(__F, "cleareol %d\n", (oe - old) - (ne - new)),);
+ term_clear_EOL(el, (oe - old) - (ne - new));
+ /*
+ * Done
+ */
+ return;
+ }
+ }
+ else
+ fx = 0;
+
+ if (sx < 0) {
+ RE_DEBUG(1,(__F, "second diff delete at %d...\r\n", (ose - old) + fx),);
+ /*
+ * Check if we have stuff to delete
+ */
+ /*
+ * fx is the number of characters inserted (+) or deleted (-)
+ */
+
+ term_move_to_char(el, (ose - old) + fx);
+ /*
+ * Check if we have stuff to save
+ */
+ if (ols != oe) {
+ RE_DEBUG(1,(__F, "with stuff to save at end\r\n"),);
+ /*
+ * Again a duplicate test.
+ */
+ if (sx < 0) {
+ RE_DEBUG(!EL_CAN_DELETE,
+ (__F, "ERROR: cannot delete in second diff\n"),);
+ term_deletechars(el, -sx);
+ }
+
+ /*
+ * write (nls-nse) chars of new starting at nse
+ */
+ term_overwrite(el, nse, (nls - nse));
+ }
+ else {
+ RE_DEBUG(1,(__F, "but with nothing left to save\r\n"),);
+ term_overwrite(el, nse, (nls - nse));
+ RE_DEBUG(1,(__F, "cleareol %d\n", (oe - old) - (ne - new)),);
+ term_clear_EOL(el, (oe - old) - (ne - new));
+ }
+ }
+
+ /*
+ * if we have a first insert AND WE HAVEN'T ALREADY DONE IT...
+ */
+ if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) {
+ RE_DEBUG(1,(__F, "late first diff insert at %d...\r\n", nfd - new),);
+
+ term_move_to_char(el, nfd - new);
+ /*
+ * Check if we have stuff to keep at the end
+ */
+ if (nsb != ne) {
+ RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),);
+ /*
+ * We have to recalculate fx here because we set it
+ * to zero above as a flag saying that we hadn't done
+ * an early first insert.
+ */
+ fx = (nsb - nfd) - (osb - ofd);
+ if (fx > 0) {
+ /*
+ * insert fx chars of new starting at nfd
+ */
+ RE_DEBUG(!EL_CAN_INSERT,
+ (__F, "ERROR: cannot insert in late first diff\n"),);
+ term_insertwrite(el, nfd, fx);
+ re_insert(el, old, ofd - old, el->el_term.t_size.h, nfd, fx);
+ }
+
+ /*
+ * write (nsb-nfd) - fx chars of new starting at (nfd + fx)
+ */
+ term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
+ re__strncopy(ofd + fx, nfd + fx, (nsb - nfd) - fx);
+ }
+ else {
+ RE_DEBUG(1,(__F, "without anything to save\r\n"),);
+ term_overwrite(el, nfd, (nsb - nfd));
+ re__strncopy(ofd, nfd, (nsb - nfd));
+ }
+ }
+
+ /*
+ * line is now NEW up to nse
+ */
+ if (sx >= 0) {
+ RE_DEBUG(1,(__F, "second diff insert at %d...\r\n", nse - new),);
+ term_move_to_char(el, nse - new);
+ if (ols != oe) {
+ RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),);
+ if (sx > 0) {
+ /* insert sx chars of new starting at nse */
+ RE_DEBUG(!EL_CAN_INSERT,
+ (__F, "ERROR: cannot insert in second diff\n"),);
+ term_insertwrite(el, nse, sx);
+ }
+
+ /*
+ * write (nls-nse) - sx chars of new starting at (nse + sx)
+ */
+ term_overwrite(el, nse + sx, (nls - nse) - sx);
+ }
+ else {
+ RE_DEBUG(1,(__F, "without anything to save\r\n"),);
+ term_overwrite(el, nse, (nls - nse));
+
+ /*
+ * No need to do a clear-to-end here because we were doing
+ * a second insert, so we will have over written all of the
+ * old string.
+ */
+ }
+ }
+ RE_DEBUG(1,(__F, "done.\r\n"),);
+} /* re_update_line */
+
+
+/* re__copy_and_pad():
+ * Copy string and pad with spaces
+ */
+private void
+re__copy_and_pad(dst, src, width)
+ char *dst, *src;
+ size_t width;
+{
+ int i;
+
+ for (i = 0; i < width; i++) {
+ if (*src == '\0')
+ break;
+ *dst++ = *src++;
+ }
+
+ while (i < width) {
+ *dst++ = ' ';
+ i++;
+ }
+ *dst = '\0';
+} /* end re__copy_and_pad */
+
+
+/* re_refresh_cursor():
+ * Move to the new cursor position
+ */
+protected void
+re_refresh_cursor(el)
+ EditLine *el;
+{
+ char *cp;
+ int c;
+ int h, v, th;
+
+ /* first we must find where the cursor is... */
+ h = el->el_prompt.p_pos.h;
+ v = el->el_prompt.p_pos.v;
+ th = el->el_term.t_size.h; /* optimize for speed */
+
+ /* do input buffer to el->el_line.cursor */
+ for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
+ c = (unsigned char)*cp;
+ h++; /* all chars at least this long */
+
+ if (c == '\n') { /* handle newline in data part too */
+ h = 0;
+ v++;
+ }
+ else {
+ if (c == '\t') { /* if a tab, to next tab stop */
+ while (h & 07) {
+ h++;
+ }
+ }
+ else if (iscntrl(c)) { /* if control char */
+ h++;
+ if (h > th) { /* if overflow, compensate */
+ h = 1;
+ v++;
+ }
+ }
+ else if (!isprint(c)) {
+ h += 3;
+ if (h > th) { /* if overflow, compensate */
+ h = h - th;
+ v++;
+ }
+ }
+ }
+
+ if (h >= th) { /* check, extra long tabs picked up here also */
+ h = 0;
+ v++;
+ }
+ }
+
+ /* now go there */
+ term_move_to_line(el, v);
+ term_move_to_char(el, h);
+ term__flush();
+} /* re_refresh_cursor */
+
+
+/* re_fastputc():
+ * Add a character fast.
+ */
+private void
+re_fastputc(el, c)
+ EditLine *el;
+ int c;
+{
+ term__putc(c);
+ el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
+ if (el->el_cursor.h >= el->el_term.t_size.h) {
+ /* if we must overflow */
+ el->el_cursor.h = 0;
+ el->el_cursor.v++;
+ el->el_refresh.r_oldcv++;
+ term__putc('\r');
+ term__putc('\n');
+ }
+} /* end re_fastputc */
+
+
+/* re_fastaddc():
+ * we added just one char, handle it fast.
+ * Assumes that screen cursor == real cursor
+ */
+protected void
+re_fastaddc(el)
+ EditLine *el;
+{
+ int c;
+
+ c = (unsigned char)el->el_line.cursor[-1];
+
+ if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) {
+ re_refresh(el); /* too hard to handle */
+ return;
+ } /* else (only do at end of line, no TAB) */
+
+ if (iscntrl(c)) { /* if control char, do caret */
+ char mc = (c == 0177) ? '?' : (toascii(c) | 0100);
+ re_fastputc(el, '^');
+ re_fastputc(el, mc);
+ }
+ else if (isprint(c)) { /* normal char */
+ re_fastputc(el, c);
+ }
+ else {
+ re_fastputc(el, '\\');
+ re_fastputc(el, ((c >> 6) & 7) + '0');
+ re_fastputc(el, ((c >> 3) & 7) + '0');
+ re_fastputc(el, (c & 7) + '0');
+ }
+ term__flush();
+} /* end re_fastaddc */
+
+
+/* re_clear_display():
+ * clear the screen buffers so that new new prompt starts fresh.
+ */
+protected void
+re_clear_display(el)
+ EditLine *el;
+{
+ int i;
+
+ el->el_cursor.v = 0;
+ el->el_cursor.h = 0;
+ for (i = 0; i < el->el_term.t_size.v; i++)
+ el->el_display[i][0] = '\0';
+ el->el_refresh.r_oldcv = 0;
+} /* end re_clear_display */
+
+
+/* re_clear_lines():
+ * Make sure all lines are *really* blank
+ */
+protected void
+re_clear_lines(el)
+ EditLine *el;
+{
+ if (EL_CAN_CEOL) {
+ int i;
+ term_move_to_char(el, 0);
+ for (i = 0; i <= el->el_refresh.r_oldcv; i++) {
+ /* for each line on the screen */
+ term_move_to_line(el, i);
+ term_clear_EOL(el, el->el_term.t_size.h);
+ }
+ term_move_to_line(el, 0);
+ }
+ else {
+ term_move_to_line(el, el->el_refresh.r_oldcv); /* go to last line */
+ term__putc('\r'); /* go to BOL */
+ term__putc('\n'); /* go to new line */
+ }
+} /* end re_clear_lines */
diff --git a/lib/libedit/refresh.h b/lib/libedit/refresh.h
new file mode 100644
index 0000000..4fe50bc
--- /dev/null
+++ b/lib/libedit/refresh.h
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)refresh.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.refresh.h: Screen refresh functions
+ */
+#ifndef _h_el_refresh
+#define _h_el_refresh
+
+#include "histedit.h"
+
+typedef struct {
+ coord_t r_cursor; /* Refresh cursor position */
+ int r_oldcv, r_newcv; /* Vertical locations */
+} el_refresh_t;
+
+protected void re_putc __P((EditLine *, int));
+protected void re_clear_lines __P((EditLine *));
+protected void re_clear_display __P((EditLine *));
+protected void re_refresh __P((EditLine *));
+protected void re_refresh_cursor __P((EditLine *));
+protected void re_fastaddc __P((EditLine *));
+protected void re_goto_bottom __P((EditLine *));
+
+#endif /* _h_el_refresh */
diff --git a/lib/libedit/search.c b/lib/libedit/search.c
new file mode 100644
index 0000000..0716ff2
--- /dev/null
+++ b/lib/libedit/search.c
@@ -0,0 +1,632 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * search.c: History and character search functions
+ */
+#include "sys.h"
+#include <stdlib.h>
+#if defined(REGEX)
+#include <regex.h>
+#elif defined(REGEXP)
+#include <regexp.h>
+#endif
+#include "el.h"
+
+/*
+ * Adjust cursor in vi mode to include the character under it
+ */
+#define EL_CURSOR(el) \
+ ((el)->el_line.cursor + (((el)->el_map.type == MAP_VI) && \
+ ((el)->el_map.current == (el)->el_map.alt)))
+
+/* search_init():
+ * Initialize the search stuff
+ */
+protected int
+search_init(el)
+ EditLine *el;
+{
+ el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ);
+ el->el_search.patlen = 0;
+ el->el_search.patdir = -1;
+ el->el_search.chacha = '\0';
+ el->el_search.chadir = -1;
+ return 0;
+}
+
+
+/* search_end():
+ * Initialize the search stuff
+ */
+protected void
+search_end(el)
+ EditLine *el;
+{
+ el_free((ptr_t) el->el_search.patbuf);
+ el->el_search.patbuf = NULL;
+}
+
+#ifdef REGEXP
+/* regerror():
+ * Handle regular expression errors
+ */
+public void
+/*ARGSUSED*/
+regerror(msg)
+ const char *msg;
+{
+}
+#endif
+
+/* el_match():
+ * Return if string matches pattern
+ */
+protected int
+el_match(str, pat)
+ const char *str;
+ const char *pat;
+{
+#if defined (REGEX)
+ regex_t re;
+ int rv;
+#elif defined (REGEXP)
+ regexp *rp;
+ int rv;
+#else
+ extern char *re_comp __P((const char *));
+ extern int re_exec __P((const char *));
+#endif
+
+ if (strstr(str, pat) != NULL)
+ return 1;
+
+#if defined(REGEX)
+ if (regcomp(&re, pat, 0) == 0) {
+ rv = regexec(&re, str, 0, NULL, 0) == 0;
+ regfree(&re);
+ } else {
+ rv = 0;
+ }
+ return rv;
+#elif defined(REGEXP)
+ if ((re = regcomp(pat)) != NULL) {
+ rv = regexec(re, str);
+ free((ptr_t) re);
+ } else {
+ rv = 0;
+ }
+ return rv;
+#else
+ if (re_comp(pat) != NULL)
+ return 0;
+ else
+ return re_exec(str) == 1;
+#endif
+}
+
+
+/* c_hmatch():
+ * return True if the pattern matches the prefix
+ */
+protected int
+c_hmatch(el, str)
+ EditLine *el;
+ const char *str;
+{
+#ifdef SDEBUG
+ (void) fprintf(el->el_errfile, "match `%s' with `%s'\n",
+ el->el_search.patbuf, str);
+#endif /* SDEBUG */
+
+ return el_match(str, el->el_search.patbuf);
+}
+
+
+/* c_setpat():
+ * Set the history seatch pattern
+ */
+protected void
+c_setpat(el)
+ EditLine *el;
+{
+ if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY &&
+ el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) {
+ el->el_search.patlen = EL_CURSOR(el) - el->el_line.buffer;
+ if (el->el_search.patlen >= EL_BUFSIZ)
+ el->el_search.patlen = EL_BUFSIZ -1;
+ if (el->el_search.patlen >= 0) {
+ (void) strncpy(el->el_search.patbuf, el->el_line.buffer,
+ el->el_search.patlen);
+ el->el_search.patbuf[el->el_search.patlen] = '\0';
+ }
+ else
+ el->el_search.patlen = strlen(el->el_search.patbuf);
+ }
+#ifdef SDEBUG
+ (void) fprintf(el->el_errfile, "\neventno = %d\n", el->el_history.eventno);
+ (void) fprintf(el->el_errfile, "patlen = %d\n", el->el_search.patlen);
+ (void) fprintf(el->el_errfile, "patbuf = \"%s\"\n", el->el_search.patbuf);
+ (void) fprintf(el->el_errfile, "cursor %d lastchar %d\n",
+ EL_CURSOR(el) - el->el_line.buffer,
+ el->el_line.lastchar - el->el_line.buffer);
+#endif
+}
+
+
+/* ce_inc_search():
+ * Emacs incremental search
+ */
+protected el_action_t
+ce_inc_search(el, dir)
+ EditLine *el;
+ int dir;
+{
+ static char STRfwd[] = { 'f', 'w', 'd', '\0' },
+ STRbck[] = { 'b', 'c', 'k', '\0' };
+ static char pchar = ':'; /* ':' = normal, '?' = failed */
+ static char endcmd[2] = { '\0', '\0' };
+ char ch, *cp, *ocursor = el->el_line.cursor, oldpchar = pchar;
+
+ el_action_t ret = CC_NORM;
+
+ int ohisteventno = el->el_history.eventno,
+ oldpatlen = el->el_search.patlen,
+ newdir = dir,
+ done, redo;
+
+ if (el->el_line.lastchar + sizeof(STRfwd) / sizeof(char) + 2 +
+ el->el_search.patlen >= el->el_line.limit)
+ return CC_ERROR;
+
+ for (;;) {
+
+ if (el->el_search.patlen == 0) { /* first round */
+ pchar = ':';
+#ifdef ANCHOR
+ el->el_search.patbuf[el->el_search.patlen++] = '.';
+ el->el_search.patbuf[el->el_search.patlen++] = '*';
+#endif
+ }
+ done = redo = 0;
+ *el->el_line.lastchar++ = '\n';
+ for (cp = newdir == ED_SEARCH_PREV_HISTORY ? STRbck : STRfwd;
+ *cp; *el->el_line.lastchar++ = *cp++)
+ continue;
+ *el->el_line.lastchar++ = pchar;
+ for (cp = &el->el_search.patbuf[1];
+ cp < &el->el_search.patbuf[el->el_search.patlen];
+ *el->el_line.lastchar++ = *cp++)
+ continue;
+ *el->el_line.lastchar = '\0';
+ re_refresh(el);
+
+ if (el_getc(el, &ch) != 1)
+ return ed_end_of_file(el, 0);
+
+ switch (el->el_map.current[(unsigned char) ch]) {
+ case ED_INSERT:
+ case ED_DIGIT:
+ if (el->el_search.patlen > EL_BUFSIZ - 3)
+ term_beep(el);
+ else {
+ el->el_search.patbuf[el->el_search.patlen++] = ch;
+ *el->el_line.lastchar++ = ch;
+ *el->el_line.lastchar = '\0';
+ re_refresh(el);
+ }
+ break;
+
+ case EM_INC_SEARCH_NEXT:
+ newdir = ED_SEARCH_NEXT_HISTORY;
+ redo++;
+ break;
+
+ case EM_INC_SEARCH_PREV:
+ newdir = ED_SEARCH_PREV_HISTORY;
+ redo++;
+ break;
+
+ case ED_DELETE_PREV_CHAR:
+ if (el->el_search.patlen > 1)
+ done++;
+ else
+ term_beep(el);
+ break;
+
+ default:
+ switch (ch) {
+ case 0007: /* ^G: Abort */
+ ret = CC_ERROR;
+ done++;
+ break;
+
+ case 0027: /* ^W: Append word */
+ /* No can do if globbing characters in pattern */
+ for (cp = &el->el_search.patbuf[1]; ; cp++)
+ if (cp >= &el->el_search.patbuf[el->el_search.patlen]) {
+ el->el_line.cursor += el->el_search.patlen - 1;
+ cp = c__next_word(el->el_line.cursor,
+ el->el_line.lastchar, 1, ce__isword);
+ while (el->el_line.cursor < cp &&
+ *el->el_line.cursor != '\n') {
+ if (el->el_search.patlen > EL_BUFSIZ - 3) {
+ term_beep(el);
+ break;
+ }
+ el->el_search.patbuf[el->el_search.patlen++] =
+ *el->el_line.cursor;
+ *el->el_line.lastchar++ = *el->el_line.cursor++;
+ }
+ el->el_line.cursor = ocursor;
+ *el->el_line.lastchar = '\0';
+ re_refresh(el);
+ break;
+ } else if (isglob(*cp)) {
+ term_beep(el);
+ break;
+ }
+ break;
+
+ default: /* Terminate and execute cmd */
+ endcmd[0] = ch;
+ el_push(el, endcmd);
+ /*FALLTHROUGH*/
+
+ case 0033: /* ESC: Terminate */
+ ret = CC_REFRESH;
+ done++;
+ break;
+ }
+ break;
+ }
+
+ while (el->el_line.lastchar > el->el_line.buffer &&
+ *el->el_line.lastchar != '\n')
+ *el->el_line.lastchar-- = '\0';
+ *el->el_line.lastchar = '\0';
+
+ if (!done) {
+
+ /* Can't search if unmatched '[' */
+ for (cp = &el->el_search.patbuf[el->el_search.patlen-1], ch = ']';
+ cp > el->el_search.patbuf; cp--)
+ if (*cp == '[' || *cp == ']') {
+ ch = *cp;
+ break;
+ }
+
+ if (el->el_search.patlen > 1 && ch != '[') {
+ if (redo && newdir == dir) {
+ if (pchar == '?') { /* wrap around */
+ el->el_history.eventno =
+ newdir == ED_SEARCH_PREV_HISTORY ? 0 : 0x7fffffff;
+ if (hist_get(el) == CC_ERROR)
+ /* el->el_history.eventno was fixed by first call */
+ (void) hist_get(el);
+ el->el_line.cursor = newdir == ED_SEARCH_PREV_HISTORY ?
+ el->el_line.lastchar : el->el_line.buffer;
+ } else
+ el->el_line.cursor +=
+ newdir == ED_SEARCH_PREV_HISTORY ? -1 : 1;
+ }
+#ifdef ANCHOR
+ el->el_search.patbuf[el->el_search.patlen++] = '.';
+ el->el_search.patbuf[el->el_search.patlen++] = '*';
+#endif
+ el->el_search.patbuf[el->el_search.patlen] = '\0';
+ if (el->el_line.cursor < el->el_line.buffer ||
+ el->el_line.cursor > el->el_line.lastchar ||
+ (ret = ce_search_line(el, &el->el_search.patbuf[1],
+ newdir)) == CC_ERROR) {
+ /* avoid c_setpat */
+ el->el_state.lastcmd = (el_action_t) newdir;
+ ret = newdir == ED_SEARCH_PREV_HISTORY ?
+ ed_search_prev_history(el, 0) :
+ ed_search_next_history(el, 0);
+ if (ret != CC_ERROR) {
+ el->el_line.cursor = newdir == ED_SEARCH_PREV_HISTORY ?
+ el->el_line.lastchar : el->el_line.buffer;
+ (void) ce_search_line(el, &el->el_search.patbuf[1],
+ newdir);
+ }
+ }
+ el->el_search.patbuf[--el->el_search.patlen] = '\0';
+ if (ret == CC_ERROR) {
+ term_beep(el);
+ if (el->el_history.eventno != ohisteventno) {
+ el->el_history.eventno = ohisteventno;
+ if (hist_get(el) == CC_ERROR)
+ return CC_ERROR;
+ }
+ el->el_line.cursor = ocursor;
+ pchar = '?';
+ } else {
+ pchar = ':';
+ }
+ }
+
+ ret = ce_inc_search(el, newdir);
+
+ if (ret == CC_ERROR && pchar == '?' && oldpchar == ':')
+ /* break abort of failed search at last non-failed */
+ ret = CC_NORM;
+
+ }
+
+ if (ret == CC_NORM || (ret == CC_ERROR && oldpatlen == 0)) {
+ /* restore on normal return or error exit */
+ pchar = oldpchar;
+ el->el_search.patlen = oldpatlen;
+ if (el->el_history.eventno != ohisteventno) {
+ el->el_history.eventno = ohisteventno;
+ if (hist_get(el) == CC_ERROR)
+ return CC_ERROR;
+ }
+ el->el_line.cursor = ocursor;
+ if (ret == CC_ERROR)
+ re_refresh(el);
+ }
+ if (done || ret != CC_NORM)
+ return ret;
+ }
+}
+
+
+/* cv_search():
+ * Vi search.
+ */
+protected el_action_t
+cv_search(el, dir)
+ EditLine *el;
+ int dir;
+{
+ char ch;
+ char tmpbuf[EL_BUFSIZ];
+ int tmplen;
+
+ tmplen = 0;
+#ifdef ANCHOR
+ tmpbuf[tmplen++] = '.';
+ tmpbuf[tmplen++] = '*';
+#endif
+
+ el->el_line.buffer[0] = '\0';
+ el->el_line.lastchar = el->el_line.buffer;
+ el->el_line.cursor = el->el_line.buffer;
+ el->el_search.patdir = dir;
+
+ c_insert(el, 2); /* prompt + '\n' */
+ *el->el_line.cursor++ = '\n';
+ *el->el_line.cursor++ = dir == ED_SEARCH_PREV_HISTORY ? '/' : '?';
+ re_refresh(el);
+
+#ifdef ANCHOR
+# define LEN 2
+#else
+# define LEN 0
+#endif
+
+ tmplen = c_gets(el, &tmpbuf[LEN]) + LEN;
+ ch = tmpbuf[tmplen];
+ tmpbuf[tmplen] = '\0';
+
+ if (tmplen == LEN) {
+ /*
+ * Use the old pattern, but wild-card it.
+ */
+ if (el->el_search.patlen == 0) {
+ el->el_line.buffer[0] = '\0';
+ el->el_line.lastchar = el->el_line.buffer;
+ el->el_line.cursor = el->el_line.buffer;
+ re_refresh(el);
+ return CC_ERROR;
+ }
+#ifdef ANCHOR
+ if (el->el_search.patbuf[0] != '.' && el->el_search.patbuf[0] != '*') {
+ (void)strncpy(tmpbuf, el->el_search.patbuf, sizeof(tmpbuf) - 1);
+ el->el_search.patbuf[0] = '.';
+ el->el_search.patbuf[1] = '*';
+ (void)strncpy(&el->el_search.patbuf[2], tmpbuf, EL_BUFSIZ - 3);
+ el->el_search.patlen++;
+ el->el_search.patbuf[el->el_search.patlen++] = '.';
+ el->el_search.patbuf[el->el_search.patlen++] = '*';
+ el->el_search.patbuf[el->el_search.patlen] = '\0';
+ }
+#endif
+ }
+ else {
+#ifdef ANCHOR
+ tmpbuf[tmplen++] = '.';
+ tmpbuf[tmplen++] = '*';
+#endif
+ tmpbuf[tmplen] = '\0';
+ (void)strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
+ el->el_search.patlen = tmplen;
+ }
+ el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */
+ el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer;
+ if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) :
+ ed_search_next_history(el, 0)) == CC_ERROR) {
+ re_refresh(el);
+ return CC_ERROR;
+ }
+ else {
+ if (ch == 0033) {
+ re_refresh(el);
+ *el->el_line.lastchar++ = '\n';
+ *el->el_line.lastchar = '\0';
+ re_goto_bottom(el);
+ return CC_NEWLINE;
+ }
+ else
+ return CC_REFRESH;
+ }
+}
+
+
+/* ce_search_line():
+ * Look for a pattern inside a line
+ */
+protected el_action_t
+ce_search_line(el, pattern, dir)
+ EditLine *el;
+ char *pattern;
+ int dir;
+{
+ char *cp;
+
+ if (dir == ED_SEARCH_PREV_HISTORY) {
+ for (cp = el->el_line.cursor; cp >= el->el_line.buffer; cp--)
+ if (el_match(cp, pattern)) {
+ el->el_line.cursor = cp;
+ return CC_NORM;
+ }
+ return CC_ERROR;
+ } else {
+ for (cp = el->el_line.cursor; *cp != '\0' &&
+ cp < el->el_line.limit; cp++)
+ if (el_match(cp, pattern)) {
+ el->el_line.cursor = cp;
+ return CC_NORM;
+ }
+ return CC_ERROR;
+ }
+}
+
+
+/* cv_repeat_srch():
+ * Vi repeat search
+ */
+protected el_action_t
+cv_repeat_srch(el, c)
+ EditLine *el;
+ int c;
+{
+#ifdef SDEBUG
+ (void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n",
+ c, el->el_search.patlen, el->el_search.patbuf);
+#endif
+
+ el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */
+ el->el_line.lastchar = el->el_line.buffer;
+
+ switch (c) {
+ case ED_SEARCH_NEXT_HISTORY:
+ return ed_search_next_history(el, 0);
+ case ED_SEARCH_PREV_HISTORY:
+ return ed_search_prev_history(el, 0);
+ default:
+ return CC_ERROR;
+ }
+}
+
+
+/* cv_csearch_back():
+ * Vi character search reverse
+ */
+protected el_action_t
+cv_csearch_back(el, ch, count, tflag)
+ EditLine *el;
+ int ch, count, tflag;
+{
+ char *cp;
+
+ cp = el->el_line.cursor;
+ while (count--) {
+ if (*cp == ch)
+ cp--;
+ while (cp > el->el_line.buffer && *cp != ch)
+ cp--;
+ }
+
+ if (cp < el->el_line.buffer || (cp == el->el_line.buffer && *cp != ch))
+ return CC_ERROR;
+
+ if (*cp == ch && tflag)
+ cp++;
+
+ el->el_line.cursor = cp;
+
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ el->el_line.cursor++;
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+
+ re_refresh_cursor(el);
+ return CC_NORM;
+}
+
+
+/* cv_csearch_fwd():
+ * Vi character search forward
+ */
+protected el_action_t
+cv_csearch_fwd(el, ch, count, tflag)
+ EditLine *el;
+ int ch, count, tflag;
+{
+ char *cp;
+
+ cp = el->el_line.cursor;
+ while (count--) {
+ if(*cp == ch)
+ cp++;
+ while (cp < el->el_line.lastchar && *cp != ch)
+ cp++;
+ }
+
+ if (cp >= el->el_line.lastchar)
+ return CC_ERROR;
+
+ if (*cp == ch && tflag)
+ cp--;
+
+ el->el_line.cursor = cp;
+
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ el->el_line.cursor++;
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+ re_refresh_cursor(el);
+ return CC_NORM;
+}
diff --git a/lib/libedit/search.h b/lib/libedit/search.h
new file mode 100644
index 0000000..346b38c
--- /dev/null
+++ b/lib/libedit/search.h
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)search.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.search.h: Line and history searching utilities
+ */
+#ifndef _h_el_search
+#define _h_el_search
+
+#include "histedit.h"
+
+typedef struct el_search_t {
+ char *patbuf; /* The pattern buffer */
+ int patlen; /* Length of the pattern buffer */
+ int patdir; /* Direction of the last search */
+ int chadir; /* Character search direction */
+ char chacha; /* Character we are looking for */
+} el_search_t;
+
+
+protected int el_match __P((const char *, const char *));
+protected int search_init __P((EditLine *));
+protected void search_end __P((EditLine *));
+protected int c_hmatch __P((EditLine *, const char *));
+protected void c_setpat __P((EditLine *));
+protected el_action_t ce_inc_search __P((EditLine *, int));
+protected el_action_t cv_search __P((EditLine *, int));
+protected el_action_t ce_search_line __P((EditLine *, char *, int));
+protected el_action_t cv_repeat_srch __P((EditLine *, int));
+protected el_action_t cv_csearch_back __P((EditLine *, int, int, int));
+protected el_action_t cv_csearch_fwd __P((EditLine *, int, int, int));
+
+#endif /* _h_el_search */
diff --git a/lib/libedit/sig.c b/lib/libedit/sig.c
new file mode 100644
index 0000000..d0a780a
--- /dev/null
+++ b/lib/libedit/sig.c
@@ -0,0 +1,193 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * sig.c: Signal handling stuff.
+ * our policy is to trap all signals, set a good state
+ * and pass the ball to our caller.
+ */
+#include "sys.h"
+#include "el.h"
+#include <stdlib.h>
+
+private EditLine *sel = NULL;
+
+private int sighdl[] = {
+#define _DO(a) (a),
+ ALLSIGS
+#undef _DO
+ -1
+};
+
+private void sig_handler __P((int));
+
+/* sig_handler():
+ * This is the handler called for all signals
+ * XXX: we cannot pass any data so we just store the old editline
+ * state in a private variable
+ */
+private void
+sig_handler(signo)
+ int signo;
+{
+ int i;
+ sigset_t nset, oset;
+
+ (void) sigemptyset(&nset);
+ (void) sigaddset(&nset, signo);
+ (void) sigprocmask(SIG_BLOCK, &nset, &oset);
+
+ switch (signo) {
+ case SIGCONT:
+ tty_rawmode(sel);
+ if (ed_redisplay(sel, 0) == CC_REFRESH)
+ re_refresh(sel);
+ term__flush();
+ break;
+
+ case SIGWINCH:
+ el_resize(sel);
+ break;
+
+ default:
+ tty_cookedmode(sel);
+ break;
+ }
+
+ for (i = 0; sighdl[i] != -1; i++)
+ if (signo == sighdl[i])
+ break;
+
+ (void) signal(signo, sel->el_signal[i]);
+ (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+ (void) kill(0, signo);
+}
+
+
+/* sig_init():
+ * Initialize all signal stuff
+ */
+protected int
+sig_init(el)
+ EditLine *el;
+{
+ int i;
+ sigset_t nset, oset;
+
+ (void) sigemptyset(&nset);
+#define _DO(a) (void) sigaddset(&nset, SIGWINCH);
+ ALLSIGS
+#undef _DO
+ (void) sigprocmask(SIG_BLOCK, &nset, &oset);
+
+#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(sig_t))
+
+ el->el_signal = (sig_t *) el_malloc(SIGSIZE);
+ for (i = 0; sighdl[i] != -1; i++)
+ el->el_signal[i] = SIG_ERR;
+
+ (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+
+ return 0;
+}
+
+
+/* sig_end():
+ * Clear all signal stuff
+ */
+protected void
+sig_end(el)
+ EditLine *el;
+{
+ el_free((ptr_t) el->el_signal);
+ el->el_signal = NULL;
+}
+
+
+/* sig_set():
+ * set all the signal handlers
+ */
+protected void
+sig_set(el)
+ EditLine *el;
+{
+ int i;
+ sigset_t nset, oset;
+
+ (void) sigemptyset(&nset);
+#define _DO(a) (void) sigaddset(&nset, SIGWINCH);
+ ALLSIGS
+#undef _DO
+ (void) sigprocmask(SIG_BLOCK, &nset, &oset);
+
+ for (i = 0; sighdl[i] != -1; i++) {
+ sig_t s;
+ /* This could happen if we get interrupted */
+ if ((s = signal(sighdl[i], sig_handler)) != sig_handler)
+ el->el_signal[i] = s;
+ }
+ sel = el;
+ (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+}
+
+
+/* sig_clr():
+ * clear all the signal handlers
+ */
+protected void
+sig_clr(el)
+ EditLine *el;
+{
+ int i;
+ sigset_t nset, oset;
+
+ (void) sigemptyset(&nset);
+#define _DO(a) (void) sigaddset(&nset, SIGWINCH);
+ ALLSIGS
+#undef _DO
+ (void) sigprocmask(SIG_BLOCK, &nset, &oset);
+
+ for (i = 0; sighdl[i] != -1; i++)
+ if (el->el_signal[i] != SIG_ERR)
+ (void) signal(sighdl[i], el->el_signal[i]);
+
+ sel = NULL; /* we are going to die if the handler is called */
+ (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+}
diff --git a/lib/libedit/sig.h b/lib/libedit/sig.h
new file mode 100644
index 0000000..98da74f
--- /dev/null
+++ b/lib/libedit/sig.h
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)sig.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.sig.h: Signal handling functions
+ */
+#ifndef _h_el_sig
+#define _h_el_sig
+
+#include <signal.h>
+
+#include "histedit.h"
+
+/*
+ * Define here all the signals we are going to handle
+ * The _DO macro is used to iterate in the source code
+ */
+#define ALLSIGS \
+ _DO(SIGINT) \
+ _DO(SIGTSTP) \
+ _DO(SIGSTOP) \
+ _DO(SIGQUIT) \
+ _DO(SIGHUP) \
+ _DO(SIGTERM) \
+ _DO(SIGCONT) \
+ _DO(SIGWINCH)
+
+typedef sig_t *el_signal_t;
+
+protected void sig_end __P((EditLine*));
+protected int sig_init __P((EditLine*));
+protected void sig_set __P((EditLine*));
+protected void sig_clr __P((EditLine*));
+
+#endif /* _h_el_sig */
diff --git a/lib/libedit/sys.h b/lib/libedit/sys.h
new file mode 100644
index 0000000..9e5fd0f
--- /dev/null
+++ b/lib/libedit/sys.h
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)sys.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * sys.h: Put all the stupid compiler and system dependencies here...
+ */
+#ifndef _h_sys
+#define _h_sys
+
+#ifndef public
+# define public /* Externally visible functions/variables */
+#endif
+
+#ifndef private
+# define private static /* Always hidden internals */
+#endif
+
+#ifndef protected
+# define protected /* Redefined from elsewhere to "static" */
+ /* When we want to hide everything */
+#endif
+
+#include <sys/cdefs.h>
+
+#ifndef _PTR_T
+# define _PTR_T
+# if __STDC__
+typedef void* ptr_t;
+# else
+typedef char* ptr_t;
+# endif
+#endif
+
+#ifndef _IOCTL_T
+# define _IOCTL_T
+# if __STDC__
+typedef void* ioctl_t;
+# else
+typedef char* ioctl_t;
+# endif
+#endif
+
+#include <stdio.h>
+#define REGEX /* Use POSIX.2 regular expression functions */
+#undef REGEXP /* Use UNIX V8 regular expression functions */
+
+#ifdef SUNOS
+# undef REGEX
+# undef REGEXP
+# include <malloc.h>
+typedef void (*sig_t)__P((int));
+# ifdef __GNUC__
+/*
+ * Broken hdrs.
+ */
+extern char *getenv __P((const char *));
+extern int fprintf __P((FILE *, const char *, ...));
+extern int sigsetmask __P((int));
+extern int sigblock __P((int));
+extern int ioctl __P((int, int, void *));
+extern int fputc __P((int, FILE *));
+extern int fgetc __P((FILE *));
+extern int fflush __P((FILE *));
+extern int tolower __P((int));
+extern int toupper __P((int));
+extern int errno, sys_nerr;
+extern char *sys_errlist[];
+extern void perror __P((const char *));
+extern int read __P((int, const char*, int));
+# include <string.h>
+# define strerror(e) sys_errlist[e]
+# endif
+# ifdef SABER
+extern ptr_t memcpy __P((ptr_t, const ptr_t, size_t));
+extern ptr_t memset __P((ptr_t, int, size_t));
+# endif
+extern char *fgetline __P((FILE *, int *));
+#endif
+
+#endif /* _h_sys */
diff --git a/lib/libedit/term.c b/lib/libedit/term.c
new file mode 100644
index 0000000..90ebf95
--- /dev/null
+++ b/lib/libedit/term.c
@@ -0,0 +1,1378 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
+#endif /* not lint && not SCCSID */
+
+/*
+ * term.c: Editor/termcap-curses interface
+ * We have to declare a static variable here, since the
+ * termcap putchar routine does not take an argument!
+ */
+#include "sys.h"
+#include <stdio.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <termcap.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include "el.h"
+
+/*
+ * IMPORTANT NOTE: these routines are allowed to look at the current screen
+ * and the current possition assuming that it is correct. If this is not
+ * true, then the update will be WRONG! This is (should be) a valid
+ * assumption...
+ */
+
+#define TC_BUFSIZE 2048
+
+#define GoodStr(a) (el->el_term.t_str[a] != NULL && \
+ el->el_term.t_str[a][0] != '\0')
+#define Str(a) el->el_term.t_str[a]
+#define Val(a) el->el_term.t_val[a]
+
+private struct termcapstr {
+ char *name;
+ char *long_name;
+} tstr[] = {
+
+#define T_al 0
+ { "al", "add new blank line" },
+#define T_bl 1
+ { "bl", "audible bell" },
+#define T_cd 2
+ { "cd", "clear to bottom" },
+#define T_ce 3
+ { "ce", "clear to end of line" },
+#define T_ch 4
+ { "ch", "cursor to horiz pos" },
+#define T_cl 5
+ { "cl", "clear screen" },
+#define T_dc 6
+ { "dc", "delete a character" },
+#define T_dl 7
+ { "dl", "delete a line" },
+#define T_dm 8
+ { "dm", "start delete mode" },
+#define T_ed 9
+ { "ed", "end delete mode" },
+#define T_ei 10
+ { "ei", "end insert mode" },
+#define T_fs 11
+ { "fs", "cursor from status line" },
+#define T_ho 12
+ { "ho", "home cursor" },
+#define T_ic 13
+ { "ic", "insert character" },
+#define T_im 14
+ { "im", "start insert mode" },
+#define T_ip 15
+ { "ip", "insert padding" },
+#define T_kd 16
+ { "kd", "sends cursor down" },
+#define T_kl 17
+ { "kl", "sends cursor left" },
+#define T_kr 18
+ { "kr", "sends cursor right" },
+#define T_ku 19
+ { "ku", "sends cursor up" },
+#define T_md 20
+ { "md", "begin bold" },
+#define T_me 21
+ { "me", "end attributes" },
+#define T_nd 22
+ { "nd", "non destructive space" },
+#define T_se 23
+ { "se", "end standout" },
+#define T_so 24
+ { "so", "begin standout" },
+#define T_ts 25
+ { "ts", "cursor to status line" },
+#define T_up 26
+ { "up", "cursor up one" },
+#define T_us 27
+ { "us", "begin underline" },
+#define T_ue 28
+ { "ue", "end underline" },
+#define T_vb 29
+ { "vb", "visible bell" },
+#define T_DC 30
+ { "DC", "delete multiple chars" },
+#define T_DO 31
+ { "DO", "cursor down multiple" },
+#define T_IC 32
+ { "IC", "insert multiple chars" },
+#define T_LE 33
+ { "LE", "cursor left multiple" },
+#define T_RI 34
+ { "RI", "cursor right multiple" },
+#define T_UP 35
+ { "UP", "cursor up multiple" },
+#define T_str 36
+ { NULL, NULL }
+};
+
+private struct termcapval {
+ char *name;
+ char *long_name;
+} tval[] = {
+#define T_pt 0
+ { "pt", "has physical tabs" },
+#define T_li 1
+ { "li", "Number of lines" },
+#define T_co 2
+ { "co", "Number of columns" },
+#define T_km 3
+ { "km", "Has meta key" },
+#define T_xt 4
+ { "xt", "Tab chars destructive" },
+#define T_MT 5
+ { "MT", "Has meta key" }, /* XXX? */
+#define T_val 6
+ { NULL, NULL, }
+};
+
+/* do two or more of the attributes use me */
+
+private void term_rebuffer_display __P((EditLine *));
+private void term_free_display __P((EditLine *));
+private void term_alloc_display __P((EditLine *));
+private void term_alloc __P((EditLine *,
+ struct termcapstr *, char *));
+private void term_init_arrow __P((EditLine *));
+private void term_reset_arrow __P((EditLine *));
+
+
+private FILE *term_outfile = NULL; /* XXX: How do we fix that? */
+
+
+/* term_setflags():
+ * Set the terminal capability flags
+ */
+private void
+term_setflags(el)
+ EditLine *el;
+{
+ EL_FLAGS = 0;
+ if (el->el_tty.t_tabs)
+ EL_FLAGS |= (Val(T_pt) && !Val(T_xt)) ? TERM_CAN_TAB : 0;
+
+ EL_FLAGS |= (Val(T_km) || Val(T_MT)) ? TERM_HAS_META : 0;
+ EL_FLAGS |= GoodStr(T_ce) ? TERM_CAN_CEOL : 0;
+ EL_FLAGS |= (GoodStr(T_dc) || GoodStr(T_DC)) ? TERM_CAN_DELETE : 0;
+ EL_FLAGS |= (GoodStr(T_im) || GoodStr(T_ic) || GoodStr(T_IC)) ?
+ TERM_CAN_INSERT : 0;
+ EL_FLAGS |= (GoodStr(T_up) || GoodStr(T_UP)) ? TERM_CAN_UP : 0;
+
+ if (GoodStr(T_me) && GoodStr(T_ue))
+ EL_FLAGS |= (strcmp(Str(T_me), Str(T_ue)) == 0) ? TERM_CAN_ME : 0;
+ else
+ EL_FLAGS &= ~TERM_CAN_ME;
+ if (GoodStr(T_me) && GoodStr(T_se))
+ EL_FLAGS |= (strcmp(Str(T_me), Str(T_se)) == 0) ? TERM_CAN_ME : 0;
+
+
+#ifdef DEBUG_SCREEN
+ if (!EL_CAN_UP) {
+ (void) fprintf(el->el_errfile, "WARNING: Your terminal cannot move up.\n");
+ (void) fprintf(el->el_errfile, "Editing may be odd for long lines.\n");
+ }
+ if (!EL_CAN_CEOL)
+ (void) fprintf(el->el_errfile, "no clear EOL capability.\n");
+ if (!EL_CAN_DELETE)
+ (void) fprintf(el->el_errfile, "no delete char capability.\n");
+ if (!EL_CAN_INSERT)
+ (void) fprintf(el->el_errfile, "no insert char capability.\n");
+#endif /* DEBUG_SCREEN */
+}
+
+
+/* term_init():
+ * Initialize the terminal stuff
+ */
+protected int
+term_init(el)
+ EditLine *el;
+{
+ el->el_term.t_buf = (char *) el_malloc(TC_BUFSIZE);
+ el->el_term.t_cap = (char *) el_malloc(TC_BUFSIZE);
+ el->el_term.t_fkey = (fkey_t *) el_malloc(4 * sizeof(fkey_t));
+ (void) memset(el->el_term.t_fkey, 0, 4 * sizeof(fkey_t));
+ el->el_term.t_loc = 0;
+ el->el_term.t_str = (char **) el_malloc(T_str * sizeof(char*));
+ (void) memset(el->el_term.t_str, 0, T_str * sizeof(char*));
+ el->el_term.t_val = (int *) el_malloc(T_val * sizeof(int));
+ (void) memset(el->el_term.t_val, 0, T_val * sizeof(int));
+ term_outfile = el->el_outfile;
+ (void) term_set(el, NULL);
+ term_init_arrow(el);
+ return 0;
+}
+
+/* term_end():
+ * Clean up the terminal stuff
+ */
+protected void
+term_end(el)
+ EditLine *el;
+{
+ el_free((ptr_t) el->el_term.t_buf);
+ el->el_term.t_buf = NULL;
+ el_free((ptr_t) el->el_term.t_cap);
+ el->el_term.t_cap = NULL;
+ el->el_term.t_loc = 0;
+ el_free((ptr_t) el->el_term.t_str);
+ el->el_term.t_str = NULL;
+ el_free((ptr_t) el->el_term.t_val);
+ el->el_term.t_val = NULL;
+ term_free_display(el);
+}
+
+
+/* term_alloc():
+ * Maintain a string pool for termcap strings
+ */
+private void
+term_alloc(el, t, cap)
+ EditLine *el;
+ struct termcapstr *t;
+ char *cap;
+{
+ char termbuf[TC_BUFSIZE];
+ int tlen, clen;
+ char **tlist = el->el_term.t_str;
+ char **tmp, **str = &tlist[t - tstr];
+
+ if (cap == NULL || *cap == '\0') {
+ *str = NULL;
+ return;
+ }
+ else
+ clen = strlen(cap);
+
+ tlen = *str == NULL ? 0 : strlen(*str);
+
+ /*
+ * New string is shorter; no need to allocate space
+ */
+ if (clen <= tlen) {
+ (void)strcpy(*str, cap); /* XXX strcpy is safe */
+ return;
+ }
+
+ /*
+ * New string is longer; see if we have enough space to append
+ */
+ if (el->el_term.t_loc + 3 < TC_BUFSIZE) {
+ /* XXX strcpy is safe */
+ (void)strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], cap);
+ el->el_term.t_loc += clen + 1; /* one for \0 */
+ return;
+ }
+
+ /*
+ * Compact our buffer; no need to check compaction, cause we know it
+ * fits...
+ */
+ tlen = 0;
+ for (tmp = tlist; tmp < &tlist[T_str]; tmp++)
+ if (*tmp != NULL && *tmp != '\0' && *tmp != *str) {
+ char *ptr;
+
+ for (ptr = *tmp; *ptr != '\0'; termbuf[tlen++] = *ptr++)
+ continue;
+ termbuf[tlen++] = '\0';
+ }
+ memcpy(el->el_term.t_buf, termbuf, TC_BUFSIZE);
+ el->el_term.t_loc = tlen;
+ if (el->el_term.t_loc + 3 >= TC_BUFSIZE) {
+ (void) fprintf(el->el_errfile, "Out of termcap string space.\n");
+ return;
+ }
+ /* XXX strcpy is safe */
+ (void)strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], cap);
+ el->el_term.t_loc += clen + 1; /* one for \0 */
+ return;
+} /* end term_alloc */
+
+
+/* term_rebuffer_display():
+ * Rebuffer the display after the screen changed size
+ */
+private void
+term_rebuffer_display(el)
+ EditLine *el;
+{
+ coord_t *c = &el->el_term.t_size;
+
+ term_free_display(el);
+
+ /* make this public, -1 to avoid wraps */
+ c->h = Val(T_co) - 1;
+ c->v = (EL_BUFSIZ * 4) / c->h + 1;
+
+ term_alloc_display(el);
+} /* end term_rebuffer_display */
+
+
+/* term_alloc_display():
+ * Allocate a new display.
+ */
+private void
+term_alloc_display(el)
+ EditLine *el;
+{
+ int i;
+ char **b;
+ coord_t *c = &el->el_term.t_size;
+
+ b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1)));
+ for (i = 0; i < c->v; i++)
+ b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1)));
+ b[c->v] = NULL;
+ el->el_display = b;
+
+ b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1)));
+ for (i = 0; i < c->v; i++)
+ b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1)));
+ b[c->v] = NULL;
+ el->el_vdisplay = b;
+
+} /* end term_alloc_display */
+
+
+/* term_free_display():
+ * Free the display buffers
+ */
+private void
+term_free_display(el)
+ EditLine *el;
+{
+ char **b;
+ char **bufp;
+
+ b = el->el_display;
+ el->el_display = NULL;
+ if (b != NULL) {
+ for (bufp = b; *bufp != NULL; bufp++)
+ el_free((ptr_t) *bufp);
+ el_free((ptr_t) b);
+ }
+ b = el->el_vdisplay;
+ el->el_vdisplay = NULL;
+ if (b != NULL) {
+ for (bufp = b; *bufp != NULL; bufp++)
+ el_free((ptr_t) * bufp);
+ el_free((ptr_t) b);
+ }
+} /* end term_free_display */
+
+
+/* term_move_to_line():
+ * move to line <where> (first line == 0)
+ * as efficiently as possible
+ */
+protected void
+term_move_to_line(el, where)
+ EditLine *el;
+ int where;
+{
+ int del, i;
+
+ if (where == el->el_cursor.v)
+ return;
+
+ if (where > el->el_term.t_size.v) {
+#ifdef DEBUG_SCREEN
+ (void) fprintf(el->el_errfile,
+ "term_move_to_line: where is ridiculous: %d\r\n", where);
+#endif /* DEBUG_SCREEN */
+ return;
+ }
+
+ if ((del = where - el->el_cursor.v) > 0) {
+ if ((del > 1) && GoodStr(T_DO))
+ (void) tputs(tgoto(Str(T_DO), del, del), del, term__putc);
+ else {
+ for (i = 0; i < del; i++)
+ term__putc('\n');
+ el->el_cursor.h = 0; /* because the \n will become \r\n */
+ }
+ }
+ else { /* del < 0 */
+ if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up)))
+ (void) tputs(tgoto(Str(T_UP), -del, -del), -del, term__putc);
+ else {
+ if (GoodStr(T_up))
+ for (i = 0; i < -del; i++)
+ (void) tputs(Str(T_up), 1, term__putc);
+ }
+ }
+ el->el_cursor.v = where; /* now where is here */
+} /* end term_move_to_line */
+
+
+/* term_move_to_char():
+ * Move to the character position specified
+ */
+protected void
+term_move_to_char(el, where)
+ EditLine *el;
+ int where;
+{
+ int del, i;
+
+mc_again:
+ if (where == el->el_cursor.h)
+ return;
+
+ if (where > (el->el_term.t_size.h + 1)) {
+#ifdef DEBUG_SCREEN
+ (void) fprintf(el->el_errfile,
+ "term_move_to_char: where is riduculous: %d\r\n", where);
+#endif /* DEBUG_SCREEN */
+ return;
+ }
+
+ if (!where) { /* if where is first column */
+ term__putc('\r'); /* do a CR */
+ el->el_cursor.h = 0;
+ return;
+ }
+
+ del = where - el->el_cursor.h;
+
+ if ((del < -4 || del > 4) && GoodStr(T_ch))
+ /* go there directly */
+ (void) tputs(tgoto(Str(T_ch), where, where), where, term__putc);
+ else {
+ if (del > 0) { /* moving forward */
+ if ((del > 4) && GoodStr(T_RI))
+ (void) tputs(tgoto(Str(T_RI), del, del), del, term__putc);
+ else {
+ if (EL_CAN_TAB) { /* if I can do tabs, use them */
+ if ((el->el_cursor.h & 0370) != (where & 0370)) {
+ /* if not within tab stop */
+ for (i = (el->el_cursor.h & 0370);
+ i < (where & 0370); i += 8)
+ term__putc('\t'); /* then tab over */
+ el->el_cursor.h = where & 0370;
+ }
+ }
+ /* it's usually cheaper to just write the chars, so we do. */
+
+ /* NOTE THAT term_overwrite() WILL CHANGE el->el_cursor.h!!! */
+ term_overwrite(el,
+ &el->el_display[el->el_cursor.v][el->el_cursor.h],
+ where - el->el_cursor.h);
+
+ }
+ }
+ else { /* del < 0 := moving backward */
+ if ((-del > 4) && GoodStr(T_LE))
+ (void) tputs(tgoto(Str(T_LE), -del, -del), -del, term__putc);
+ else { /* can't go directly there */
+ /* if the "cost" is greater than the "cost" from col 0 */
+ if (EL_CAN_TAB ? (-del > ((where >> 3) + (where & 07)))
+ : (-del > where)) {
+ term__putc('\r'); /* do a CR */
+ el->el_cursor.h = 0;
+ goto mc_again; /* and try again */
+ }
+ for (i = 0; i < -del; i++)
+ term__putc('\b');
+ }
+ }
+ }
+ el->el_cursor.h = where; /* now where is here */
+} /* end term_move_to_char */
+
+
+/* term_overwrite():
+ * Overstrike num characters
+ */
+protected void
+term_overwrite(el, cp, n)
+ EditLine *el;
+ char *cp;
+ int n;
+{
+ if (n <= 0)
+ return; /* catch bugs */
+
+ if (n > (el->el_term.t_size.h + 1)) {
+#ifdef DEBUG_SCREEN
+ (void) fprintf(el->el_errfile, "term_overwrite: n is riduculous: %d\r\n", n);
+#endif /* DEBUG_SCREEN */
+ return;
+ }
+
+ do {
+ term__putc(*cp++);
+ el->el_cursor.h++;
+ } while (--n);
+} /* end term_overwrite */
+
+
+/* term_deletechars():
+ * Delete num characters
+ */
+protected void
+term_deletechars(el, num)
+ EditLine *el;
+ int num;
+{
+ if (num <= 0)
+ return;
+
+ if (!EL_CAN_DELETE) {
+#ifdef DEBUG_EDIT
+ (void) fprintf(el->el_errfile, " ERROR: cannot delete \n");
+#endif /* DEBUG_EDIT */
+ return;
+ }
+
+ if (num > el->el_term.t_size.h) {
+#ifdef DEBUG_SCREEN
+ (void) fprintf(el->el_errfile,
+ "term_deletechars: num is riduculous: %d\r\n", num);
+#endif /* DEBUG_SCREEN */
+ return;
+ }
+
+ if (GoodStr(T_DC)) /* if I have multiple delete */
+ if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more expen. */
+ (void) tputs(tgoto(Str(T_DC), num, num), num, term__putc);
+ return;
+ }
+
+ if (GoodStr(T_dm)) /* if I have delete mode */
+ (void) tputs(Str(T_dm), 1, term__putc);
+
+ if (GoodStr(T_dc)) /* else do one at a time */
+ while (num--)
+ (void) tputs(Str(T_dc), 1, term__putc);
+
+ if (GoodStr(T_ed)) /* if I have delete mode */
+ (void) tputs(Str(T_ed), 1, term__putc);
+} /* end term_deletechars */
+
+
+/* term_insertwrite():
+ * Puts terminal in insert character mode or inserts num
+ * characters in the line
+ */
+protected void
+term_insertwrite(el, cp, num)
+ EditLine *el;
+ char *cp;
+ int num;
+{
+ if (num <= 0)
+ return;
+ if (!EL_CAN_INSERT) {
+#ifdef DEBUG_EDIT
+ (void) fprintf(el->el_errfile, " ERROR: cannot insert \n");
+#endif /* DEBUG_EDIT */
+ return;
+ }
+
+ if (num > el->el_term.t_size.h) {
+#ifdef DEBUG_SCREEN
+ (void) fprintf(el->el_errfile, "StartInsert: num is riduculous: %d\r\n", num);
+#endif /* DEBUG_SCREEN */
+ return;
+ }
+
+ if (GoodStr(T_IC)) /* if I have multiple insert */
+ if ((num > 1) || !GoodStr(T_ic)) { /* if ic would be more expen. */
+ (void) tputs(tgoto(Str(T_IC), num, num), num, term__putc);
+ term_overwrite(el, cp, num); /* this updates el_cursor.h */
+ return;
+ }
+
+ if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */
+ (void) tputs(Str(T_im), 1, term__putc);
+
+ el->el_cursor.h += num;
+ do
+ term__putc(*cp++);
+ while (--num);
+
+ if (GoodStr(T_ip)) /* have to make num chars insert */
+ (void) tputs(Str(T_ip), 1, term__putc);
+
+ (void) tputs(Str(T_ei), 1, term__putc);
+ return;
+ }
+
+ do {
+ if (GoodStr(T_ic)) /* have to make num chars insert */
+ (void) tputs(Str(T_ic), 1, term__putc); /* insert a char */
+
+ term__putc(*cp++);
+
+ el->el_cursor.h++;
+
+ if (GoodStr(T_ip)) /* have to make num chars insert */
+ (void) tputs(Str(T_ip), 1, term__putc);/* pad the inserted char */
+
+ } while (--num);
+} /* end term_insertwrite */
+
+
+/* term_clear_EOL():
+ * clear to end of line. There are num characters to clear
+ */
+protected void
+term_clear_EOL(el, num)
+ EditLine *el;
+ int num;
+{
+ int i;
+
+ if (EL_CAN_CEOL && GoodStr(T_ce))
+ (void) tputs(Str(T_ce), 1, term__putc);
+ else {
+ for (i = 0; i < num; i++)
+ term__putc(' ');
+ el->el_cursor.h += num; /* have written num spaces */
+ }
+} /* end term_clear_EOL */
+
+
+/* term_clear_screen():
+ * Clear the screen
+ */
+protected void
+term_clear_screen(el)
+ EditLine *el;
+{ /* clear the whole screen and home */
+ if (GoodStr(T_cl))
+ /* send the clear screen code */
+ (void) tputs(Str(T_cl), Val(T_li), term__putc);
+ else if (GoodStr(T_ho) && GoodStr(T_cd)) {
+ (void) tputs(Str(T_ho), Val(T_li), term__putc); /* home */
+ /* clear to bottom of screen */
+ (void) tputs(Str(T_cd), Val(T_li), term__putc);
+ }
+ else {
+ term__putc('\r');
+ term__putc('\n');
+ }
+} /* end term_clear_screen */
+
+
+/* term_beep():
+ * Beep the way the terminal wants us
+ */
+protected void
+term_beep(el)
+ EditLine *el;
+{
+ if (GoodStr(T_vb))
+ (void) tputs(Str(T_vb), 1, term__putc); /* visible bell */
+ else if (GoodStr(T_bl))
+ /* what termcap says we should use */
+ (void) tputs(Str(T_bl), 1, term__putc);
+ else
+ term__putc('\007'); /* an ASCII bell; ^G */
+} /* end term_beep */
+
+
+#ifdef notdef
+/* term_clear_to_bottom():
+ * Clear to the bottom of the screen
+ */
+protected void
+term_clear_to_bottom(el)
+ EditLine *el;
+{
+ if (GoodStr(T_cd))
+ (void) tputs(Str(T_cd), Val(T_li), term__putc);
+ else if (GoodStr(T_ce))
+ (void) tputs(Str(T_ce), Val(T_li), term__putc);
+} /* end term_clear_to_bottom */
+#endif
+
+
+/* term_set():
+ * Read in the terminal capabilities from the requested terminal
+ */
+protected int
+term_set(el, term)
+ EditLine *el;
+ char *term;
+{
+ int i;
+ char buf[TC_BUFSIZE];
+ char *area;
+ struct termcapstr *t;
+ sigset_t oset, nset;
+ int lins, cols;
+
+ (void) sigemptyset(&nset);
+ (void) sigaddset(&nset, SIGWINCH);
+ (void) sigprocmask(SIG_BLOCK, &nset, &oset);
+
+ area = buf;
+
+
+ if (term == NULL)
+ term = getenv("TERM");
+
+ if (!term || !term[0])
+ term = "dumb";
+
+ memset(el->el_term.t_cap, 0, TC_BUFSIZE);
+
+ i = tgetent(el->el_term.t_cap, term);
+
+ if (i <= 0) {
+ if (i == -1)
+ (void) fprintf(el->el_errfile, "Cannot read termcap database;\n");
+ else if (i == 0)
+ (void) fprintf(el->el_errfile,
+ "No entry for terminal type \"%s\";\n", term);
+ (void) fprintf(el->el_errfile, "using dumb terminal settings.\n");
+ Val(T_co) = 80; /* do a dumb terminal */
+ Val(T_pt) = Val(T_km) = Val(T_li) = 0;
+ Val(T_xt) = Val(T_MT);
+ for (t = tstr; t->name != NULL; t++)
+ term_alloc(el, t, NULL);
+ }
+ else {
+ /* Can we tab */
+ Val(T_pt) = tgetflag("pt");
+ Val(T_xt) = tgetflag("xt");
+ /* do we have a meta? */
+ Val(T_km) = tgetflag("km");
+ Val(T_MT) = tgetflag("MT");
+ /* Get the size */
+ Val(T_co) = tgetnum("co");
+ Val(T_li) = tgetnum("li");
+ for (t = tstr; t->name != NULL; t++)
+ term_alloc(el, t, tgetstr(t->name, &area));
+ }
+
+ if (Val(T_co) < 2)
+ Val(T_co) = 80; /* just in case */
+ if (Val(T_li) < 1)
+ Val(T_li) = 24;
+
+ el->el_term.t_size.v = Val(T_co);
+ el->el_term.t_size.h = Val(T_li);
+
+ term_setflags(el);
+
+ (void) term_get_size(el, &lins, &cols);/* get the correct window size */
+ term_change_size(el, lins, cols);
+ (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+ term_bind_arrow(el);
+ return i <= 0 ? -1 : 0;
+} /* end term_set */
+
+
+/* term_get_size():
+ * Return the new window size in lines and cols, and
+ * true if the size was changed.
+ */
+protected int
+term_get_size(el, lins, cols)
+ EditLine *el;
+ int *lins, *cols;
+{
+
+ *cols = Val(T_co);
+ *lins = Val(T_li);
+
+#ifdef TIOCGWINSZ
+ {
+ struct winsize ws;
+ if (ioctl(el->el_infd, TIOCGWINSZ, (ioctl_t) &ws) != -1) {
+ if (ws.ws_col)
+ *cols = ws.ws_col;
+ if (ws.ws_row)
+ *lins = ws.ws_row;
+ }
+ }
+#endif
+#ifdef TIOCGSIZE
+ {
+ struct ttysize ts;
+ if (ioctl(el->el_infd, TIOCGSIZE, (ioctl_t) &ts) != -1) {
+ if (ts.ts_cols)
+ *cols = ts.ts_cols;
+ if (ts.ts_lines)
+ *lins = ts.ts_lines;
+ }
+ }
+#endif
+ return (Val(T_co) != *cols || Val(T_li) != *lins);
+} /* end term_get_size */
+
+
+/* term_change_size():
+ * Change the size of the terminal
+ */
+protected void
+term_change_size(el, lins, cols)
+ EditLine *el;
+ int lins, cols;
+{
+ /*
+ * Just in case
+ */
+ Val(T_co) = (cols < 2) ? 80 : cols;
+ Val(T_li) = (lins < 1) ? 24 : lins;
+
+ term_rebuffer_display(el); /* re-make display buffers */
+ re_clear_display(el);
+} /* end term_change_size */
+
+
+/* term_init_arrow():
+ * Initialize the arrow key bindings from termcap
+ */
+private void
+term_init_arrow(el)
+ EditLine *el;
+{
+ fkey_t *arrow = el->el_term.t_fkey;
+
+ arrow[A_K_DN].name = "down";
+ arrow[A_K_DN].key = T_kd;
+ arrow[A_K_DN].fun.cmd = ED_NEXT_HISTORY;
+ arrow[A_K_DN].type = XK_CMD;
+
+ arrow[A_K_UP].name = "up";
+ arrow[A_K_UP].key = T_ku;
+ arrow[A_K_UP].fun.cmd = ED_PREV_HISTORY;
+ arrow[A_K_UP].type = XK_CMD;
+
+ arrow[A_K_LT].name = "left";
+ arrow[A_K_LT].key = T_kl;
+ arrow[A_K_LT].fun.cmd = ED_PREV_CHAR;
+ arrow[A_K_LT].type = XK_CMD;
+
+ arrow[A_K_RT].name = "right";
+ arrow[A_K_RT].key = T_kr;
+ arrow[A_K_RT].fun.cmd = ED_NEXT_CHAR;
+ arrow[A_K_RT].type = XK_CMD;
+
+}
+
+
+/* term_reset_arrow():
+ * Reset arrow key bindings
+ */
+private void
+term_reset_arrow(el)
+ EditLine *el;
+{
+ fkey_t *arrow = el->el_term.t_fkey;
+ static char strA[] = {033, '[', 'A', '\0'};
+ static char strB[] = {033, '[', 'B', '\0'};
+ static char strC[] = {033, '[', 'C', '\0'};
+ static char strD[] = {033, '[', 'D', '\0'};
+ static char stOA[] = {033, 'O', 'A', '\0'};
+ static char stOB[] = {033, 'O', 'B', '\0'};
+ static char stOC[] = {033, 'O', 'C', '\0'};
+ static char stOD[] = {033, 'O', 'D', '\0'};
+
+ key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+ key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+ key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+ key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+ key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+ key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+ key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+ key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+
+ if (el->el_map.type == MAP_VI) {
+ key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+ key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+ key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+ key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+ key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+ key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+ key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+ key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+ }
+}
+
+
+/* term_set_arrow():
+ * Set an arrow key binding
+ */
+protected int
+term_set_arrow(el, name, fun, type)
+ EditLine *el;
+ char *name;
+ key_value_t *fun;
+ int type;
+{
+ fkey_t *arrow = el->el_term.t_fkey;
+ int i;
+
+ for (i = 0; i < A_K_NKEYS; i++)
+ if (strcmp(name, arrow[i].name) == 0) {
+ arrow[i].fun = *fun;
+ arrow[i].type = type;
+ return 0;
+ }
+ return -1;
+}
+
+
+/* term_clear_arrow():
+ * Clear an arrow key binding
+ */
+protected int
+term_clear_arrow(el, name)
+ EditLine *el;
+ char *name;
+{
+ fkey_t *arrow = el->el_term.t_fkey;
+ int i;
+
+ for (i = 0; i < A_K_NKEYS; i++)
+ if (strcmp(name, arrow[i].name) == 0) {
+ arrow[i].type = XK_NOD;
+ return 0;
+ }
+ return -1;
+}
+
+
+/* term_print_arrow():
+ * Print the arrow key bindings
+ */
+protected void
+term_print_arrow(el, name)
+ EditLine *el;
+ char *name;
+{
+ int i;
+ fkey_t *arrow = el->el_term.t_fkey;
+
+ for (i = 0; i < A_K_NKEYS; i++)
+ if (*name == '\0' || strcmp(name, arrow[i].name) == 0)
+ if (arrow[i].type != XK_NOD)
+ key_kprint(el, arrow[i].name, &arrow[i].fun, arrow[i].type);
+}
+
+
+/* term_bind_arrow():
+ * Bind the arrow keys
+ */
+protected void
+term_bind_arrow(el)
+ EditLine *el;
+{
+ el_action_t *map, *dmap;
+ int i, j;
+ char *p;
+ fkey_t *arrow = el->el_term.t_fkey;
+
+ /* Check if the components needed are initialized */
+ if (el->el_term.t_buf == NULL || el->el_map.key == NULL)
+ return;
+
+ map = el->el_map.type == MAP_VI ? el->el_map.alt : el->el_map.key;
+ dmap = el->el_map.type == MAP_VI ? el->el_map.vic : el->el_map.emacs;
+
+ term_reset_arrow(el);
+
+ for (i = 0; i < 4; i++) {
+ p = el->el_term.t_str[arrow[i].key];
+ if (p && *p) {
+ j = (unsigned char) *p;
+ /*
+ * Assign the arrow keys only if:
+ *
+ * 1. They are multi-character arrow keys and the user
+ * has not re-assigned the leading character, or
+ * has re-assigned the leading character to be
+ * ED_SEQUENCE_LEAD_IN
+ * 2. They are single arrow keys pointing to an unassigned key.
+ */
+ if (arrow[i].type == XK_NOD)
+ key_clear(el, map, p);
+ else {
+ if (p[1] && (dmap[j] == map[j] ||
+ map[j] == ED_SEQUENCE_LEAD_IN)) {
+ key_add(el, p, &arrow[i].fun, arrow[i].type);
+ map[j] = ED_SEQUENCE_LEAD_IN;
+ }
+ else if (map[j] == ED_UNASSIGNED) {
+ key_clear(el, map, p);
+ if (arrow[i].type == XK_CMD)
+ map[j] = arrow[i].fun.cmd;
+ else
+ key_add(el, p, &arrow[i].fun, arrow[i].type);
+ }
+ }
+ }
+ }
+}
+
+
+/* term__putc():
+ * Add a character
+ */
+protected int
+term__putc(c)
+ int c;
+{
+ return fputc(c, term_outfile);
+} /* end term__putc */
+
+
+/* term__flush():
+ * Flush output
+ */
+protected void
+term__flush()
+{
+ (void) fflush(term_outfile);
+} /* end term__flush */
+
+
+/* term_telltc():
+ * Print the current termcap characteristics
+ */
+protected int
+/*ARGSUSED*/
+term_telltc(el, argc, argv)
+ EditLine *el;
+ int argc;
+ char **argv;
+{
+ struct termcapstr *t;
+ char **ts;
+ char upbuf[EL_BUFSIZ];
+
+ (void) fprintf(el->el_outfile, "\n\tYour terminal has the\n");
+ (void) fprintf(el->el_outfile, "\tfollowing characteristics:\n\n");
+ (void) fprintf(el->el_outfile, "\tIt has %d columns and %d lines\n",
+ Val(T_co), Val(T_li));
+ (void) fprintf(el->el_outfile,
+ "\tIt has %s meta key\n", EL_HAS_META ? "a" : "no");
+ (void) fprintf(el->el_outfile,
+ "\tIt can%suse tabs\n", EL_CAN_TAB ? " " : "not ");
+#ifdef notyet
+ (void) fprintf(el->el_outfile, "\tIt %s automatic margins\n",
+ (T_Margin&MARGIN_AUTO)? "has": "does not have");
+ if (T_Margin & MARGIN_AUTO)
+ (void) fprintf(el->el_outfile, "\tIt %s magic margins\n",
+ (T_Margin&MARGIN_MAGIC)?"has":"does not have");
+#endif
+
+ for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++)
+ (void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n", t->long_name,
+ t->name, *ts && **ts ?
+ key__decode_str(*ts, upbuf, "") : "(empty)");
+ (void) fputc('\n', el->el_outfile);
+ return 0;
+}
+
+
+/* term_settc():
+ * Change the current terminal characteristics
+ */
+protected int
+/*ARGSUSED*/
+term_settc(el, argc, argv)
+ EditLine *el;
+ int argc;
+ char **argv;
+{
+ struct termcapstr *ts;
+ struct termcapval *tv;
+ char *what, *how;
+
+ if (argv == NULL || argv[1] == NULL || argv[2] == NULL)
+ return -1;
+
+ what = argv[1];
+ how = argv[2];
+
+ /*
+ * Do the strings first
+ */
+ for (ts = tstr; ts->name != NULL; ts++)
+ if (strcmp(ts->name, what) == 0)
+ break;
+
+ if (ts->name != NULL) {
+ term_alloc(el, ts, how);
+ term_setflags(el);
+ return 0;
+ }
+
+ /*
+ * Do the numeric ones second
+ */
+ for (tv = tval; tv->name != NULL; tv++)
+ if (strcmp(tv->name, what) == 0)
+ break;
+
+ if (tv->name != NULL) {
+ if (tv == &tval[T_pt] || tv == &tval[T_km]
+#ifdef notyet
+ || tv == &tval[T_am] || tv == &tval[T_xn]
+#endif
+ ) {
+ if (strcmp(how, "yes") == 0)
+ el->el_term.t_val[tv - tval] = 1;
+ else if (strcmp(how, "no") == 0)
+ el->el_term.t_val[tv - tval] = 0;
+ else {
+ (void) fprintf(el->el_errfile, "settc: Bad value `%s'.\n", how);
+ return -1;
+ }
+ term_setflags(el);
+ term_change_size(el, Val(T_li), Val(T_co));
+ return 0;
+ }
+ else {
+ el->el_term.t_val[tv - tval] = atoi(how);
+ el->el_term.t_size.v = Val(T_co);
+ el->el_term.t_size.h = Val(T_li);
+ if (tv == &tval[T_co] || tv == &tval[T_li])
+ term_change_size(el, Val(T_li), Val(T_co));
+ return 0;
+ }
+ }
+ return -1;
+}
+
+
+/* term_echotc():
+ * Print the termcap string out with variable substitution
+ */
+protected int
+/*ARGSUSED*/
+term_echotc(el, argc, argv)
+ EditLine *el;
+ int argc;
+ char **argv;
+{
+ char *cap, *scap;
+ int arg_need, arg_cols, arg_rows;
+ int verbose = 0, silent = 0;
+ char *area;
+ static char *fmts = "%s\n", *fmtd = "%d\n";
+ struct termcapstr *t;
+ char buf[TC_BUFSIZE];
+
+ area = buf;
+
+ if (argv == NULL || argv[1] == NULL)
+ return -1;
+ argv++;
+
+ if (argv[0][0] == '-') {
+ switch (argv[0][1]) {
+ case 'v':
+ verbose = 1;
+ break;
+ case 's':
+ silent = 1;
+ break;
+ default:
+ /* stderror(ERR_NAME | ERR_TCUSAGE); */
+ break;
+ }
+ argv++;
+ }
+ if (!*argv || *argv[0] == '\0')
+ return 0;
+ if (strcmp(*argv, "tabs") == 0) {
+ (void) fprintf(el->el_outfile, fmts, EL_CAN_TAB ? "yes" : "no");
+ return 0;
+ }
+ else if (strcmp(*argv, "meta") == 0) {
+ (void) fprintf(el->el_outfile, fmts, Val(T_km) ? "yes" : "no");
+ return 0;
+ }
+#ifdef notyet
+ else if (strcmp(*argv, "xn") == 0) {
+ (void) fprintf(el->el_outfile, fmts, T_Margin & MARGIN_MAGIC ?
+ "yes" : "no");
+ return 0;
+ }
+ else if (strcmp(*argv, "am") == 0) {
+ (void) fprintf(el->el_outfile, fmts, T_Margin & MARGIN_AUTO ?
+ "yes" : "no");
+ return 0;
+ }
+#endif
+ else if (strcmp(*argv, "baud") == 0) {
+ (void) fprintf(el->el_outfile, "%lu\n", (u_long)el->el_tty.t_speed);
+ return 0;
+ }
+ else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) {
+ (void) fprintf(el->el_outfile, fmtd, Val(T_li));
+ return 0;
+ }
+ else if (strcmp(*argv, "cols") == 0) {
+ (void) fprintf(el->el_outfile, fmtd, Val(T_co));
+ return 0;
+ }
+
+ /*
+ * Try to use our local definition first
+ */
+ scap = NULL;
+ for (t = tstr; t->name != NULL; t++)
+ if (strcmp(t->name, *argv) == 0) {
+ scap = el->el_term.t_str[t - tstr];
+ break;
+ }
+ if (t->name == NULL)
+ scap = tgetstr(*argv, &area);
+ if (!scap || scap[0] == '\0') {
+ if (!silent)
+ (void) fprintf(el->el_errfile,
+ "echotc: Termcap parameter `%s' not found.\n", *argv);
+ return -1;
+ }
+
+ /*
+ * Count home many values we need for this capability.
+ */
+ for (cap = scap, arg_need = 0; *cap; cap++)
+ if (*cap == '%')
+ switch (*++cap) {
+ case 'd':
+ case '2':
+ case '3':
+ case '.':
+ case '+':
+ arg_need++;
+ break;
+ case '%':
+ case '>':
+ case 'i':
+ case 'r':
+ case 'n':
+ case 'B':
+ case 'D':
+ break;
+ default:
+ /*
+ * hpux has lot's of them...
+ */
+ if (verbose)
+ (void) fprintf(el->el_errfile,
+ "echotc: Warning: unknown termcap %% `%c'.\n", *cap);
+ /* This is bad, but I won't complain */
+ break;
+ }
+
+ switch (arg_need) {
+ case 0:
+ argv++;
+ if (*argv && *argv[0]) {
+ if (!silent)
+ (void) fprintf(el->el_errfile,
+ "echotc: Warning: Extra argument `%s'.\n", *argv);
+ return -1;
+ }
+ (void) tputs(scap, 1, term__putc);
+ break;
+ case 1:
+ argv++;
+ if (!*argv || *argv[0] == '\0') {
+ if (!silent)
+ (void) fprintf(el->el_errfile,
+ "echotc: Warning: Missing argument.\n");
+ return -1;
+ }
+ arg_cols = 0;
+ arg_rows = atoi(*argv);
+ argv++;
+ if (*argv && *argv[0]) {
+ if (!silent)
+ (void) fprintf(el->el_errfile,
+ "echotc: Warning: Extra argument `%s'.\n", *argv);
+ return -1;
+ }
+ (void) tputs(tgoto(scap, arg_cols, arg_rows), 1, term__putc);
+ break;
+ default:
+ /* This is wrong, but I will ignore it... */
+ if (verbose)
+ (void) fprintf(el->el_errfile,
+ "echotc: Warning: Too many required arguments (%d).\n",
+ arg_need);
+ /*FALLTHROUGH*/
+ case 2:
+ argv++;
+ if (!*argv || *argv[0] == '\0') {
+ if (!silent)
+ (void) fprintf(el->el_errfile,
+ "echotc: Warning: Missing argument.\n");
+ return -1;
+ }
+ arg_cols = atoi(*argv);
+ argv++;
+ if (!*argv || *argv[0] == '\0') {
+ if (!silent)
+ (void) fprintf(el->el_errfile,
+ "echotc: Warning: Missing argument.\n");
+ return -1;
+ }
+ arg_rows = atoi(*argv);
+ argv++;
+ if (*argv && *argv[0]) {
+ if (!silent)
+ (void) fprintf(el->el_errfile,
+ "echotc: Warning: Extra argument `%s'.\n", *argv);
+ return -1;
+ }
+ (void) tputs(tgoto(scap, arg_cols, arg_rows), arg_rows, term__putc);
+ break;
+ }
+ return 0;
+}
diff --git a/lib/libedit/term.h b/lib/libedit/term.h
new file mode 100644
index 0000000..f9de221
--- /dev/null
+++ b/lib/libedit/term.h
@@ -0,0 +1,118 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)term.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.term.h: Termcap header
+ */
+#ifndef _h_el_term
+#define _h_el_term
+
+#include "histedit.h"
+
+typedef struct { /* Symbolic function key bindings */
+ char *name; /* name of the key */
+ int key; /* Index in termcap table */
+ key_value_t fun; /* Function bound to it */
+ int type; /* Type of function */
+} fkey_t;
+
+typedef struct {
+ coord_t t_size; /* # lines and cols */
+ bool_t t_flags;
+#define TERM_CAN_INSERT 0x01 /* Has insert cap */
+#define TERM_CAN_DELETE 0x02 /* Has delete cap */
+#define TERM_CAN_CEOL 0x04 /* Has CEOL cap */
+#define TERM_CAN_TAB 0x08 /* Can use tabs */
+#define TERM_CAN_ME 0x10 /* Can turn all attrs. */
+#define TERM_CAN_UP 0x20 /* Can move up */
+#define TERM_HAS_META 0x40 /* Has a meta key */
+ char *t_buf; /* Termcap buffer */
+ int t_loc; /* location used */
+ char **t_str; /* termcap strings */
+ int *t_val; /* termcap values */
+ char *t_cap; /* Termcap buffer */
+ fkey_t *t_fkey; /* Array of keys */
+} el_term_t;
+
+/*
+ * fKey indexes
+ */
+#define A_K_DN 0
+#define A_K_UP 1
+#define A_K_LT 2
+#define A_K_RT 3
+#define A_K_NKEYS 4
+
+protected void term_move_to_line __P((EditLine *, int));
+protected void term_move_to_char __P((EditLine *, int));
+protected void term_clear_EOL __P((EditLine *, int));
+protected void term_overwrite __P((EditLine *, char *, int));
+protected void term_insertwrite __P((EditLine *, char *, int));
+protected void term_deletechars __P((EditLine *, int));
+protected void term_clear_screen __P((EditLine *));
+protected void term_beep __P((EditLine *));
+protected void term_change_size __P((EditLine *, int, int));
+protected int term_get_size __P((EditLine *, int *, int *));
+protected int term_init __P((EditLine *));
+protected void term_bind_arrow __P((EditLine *));
+protected void term_print_arrow __P((EditLine *, char *));
+protected int term_clear_arrow __P((EditLine *, char *));
+protected int term_set_arrow __P((EditLine *, char *,
+ key_value_t *, int));
+protected void term_end __P((EditLine *));
+protected int term_set __P((EditLine *, char *));
+protected int term_settc __P((EditLine *, int, char **));
+protected int term_telltc __P((EditLine *, int, char **));
+protected int term_echotc __P((EditLine *, int, char **));
+
+protected int term__putc __P((int));
+protected void term__flush __P((void));
+
+/*
+ * Easy access macros
+ */
+#define EL_FLAGS (el)->el_term.t_flags
+
+#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT)
+#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE)
+#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL)
+#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB)
+#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME)
+#define EL_HAS_META (EL_FLAGS & TERM_HAS_META)
+
+#endif /* _h_el_term */
diff --git a/lib/libedit/tokenizer.c b/lib/libedit/tokenizer.c
new file mode 100644
index 0000000..62c0249
--- /dev/null
+++ b/lib/libedit/tokenizer.c
@@ -0,0 +1,386 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * tokenize.c: Bourne shell like tokenizer
+ */
+#include "sys.h"
+#include <string.h>
+#include <stdlib.h>
+#include "tokenizer.h"
+
+typedef enum { Q_none, Q_single, Q_double, Q_one, Q_doubleone } quote_t;
+
+#define IFS "\t \n"
+
+#define TOK_KEEP 1
+#define TOK_EAT 2
+
+#define WINCR 20
+#define AINCR 10
+
+#define tok_malloc(a) malloc(a)
+#define tok_free(a) free(a)
+#define tok_realloc(a, b) realloc(a, b)
+#define tok_reallocf(a, b) reallocf(a, b)
+
+
+struct tokenizer {
+ char *ifs; /* In field separator */
+ int argc, amax; /* Current and maximum number of args */
+ char **argv; /* Argument list */
+ char *wptr, *wmax; /* Space and limit on the word buffer */
+ char *wstart; /* Beginning of next word */
+ char *wspace; /* Space of word buffer */
+ quote_t quote; /* Quoting state */
+ int flags; /* flags; */
+};
+
+
+private void tok_finish __P((Tokenizer *));
+
+
+/* tok_finish():
+ * Finish a word in the tokenizer.
+ */
+private void
+tok_finish(tok)
+ Tokenizer *tok;
+{
+ *tok->wptr = '\0';
+ if ((tok->flags & TOK_KEEP) || tok->wptr != tok->wstart) {
+ tok->argv[tok->argc++] = tok->wstart;
+ tok->argv[tok->argc] = NULL;
+ tok->wstart = ++tok->wptr;
+ }
+ tok->flags &= ~TOK_KEEP;
+}
+
+
+/* tok_init():
+ * Initialize the tokenizer
+ */
+public Tokenizer *
+tok_init(ifs)
+ const char *ifs;
+{
+ Tokenizer* tok = (Tokenizer*) tok_malloc(sizeof(Tokenizer));
+
+ tok->ifs = strdup(ifs ? ifs : IFS);
+ tok->argc = 0;
+ tok->amax = AINCR;
+ tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax);
+ tok->argv[0] = NULL;
+ tok->wspace = (char *) tok_malloc(WINCR);
+ tok->wmax = tok->wspace + WINCR;
+ tok->wstart = tok->wspace;
+ tok->wptr = tok->wspace;
+ tok->flags = 0;
+ tok->quote = Q_none;
+
+ return tok;
+}
+
+
+/* tok_reset():
+ * Reset the tokenizer
+ */
+public void
+tok_reset(tok)
+ Tokenizer *tok;
+{
+ tok->argc = 0;
+ tok->wstart = tok->wspace;
+ tok->wptr = tok->wspace;
+ tok->flags = 0;
+ tok->quote = Q_none;
+}
+
+
+/* tok_end():
+ * Clean up
+ */
+public void
+tok_end(tok)
+ Tokenizer *tok;
+{
+ tok_free((ptr_t) tok->ifs);
+ tok_free((ptr_t) tok->wspace);
+ tok_free((ptr_t) tok->argv);
+ tok_free((ptr_t) tok);
+}
+
+
+
+/* tok_line():
+ * Bourne shell like tokenizing
+ * Return:
+ * -1: Internal error
+ * 3: Quoted return
+ * 2: Unmatched double quote
+ * 1: Unmatched single quote
+ * 0: Ok
+ */
+public int
+tok_line(tok, line, argc, argv)
+ Tokenizer *tok;
+ const char* line;
+ int *argc;
+ char ***argv;
+{
+ const char *ptr;
+
+ while (1) {
+ switch (*(ptr = line++)) {
+ case '\'':
+ tok->flags |= TOK_KEEP;
+ tok->flags &= ~TOK_EAT;
+ switch (tok->quote) {
+ case Q_none:
+ tok->quote = Q_single; /* Enter single quote mode */
+ break;
+
+ case Q_single: /* Exit single quote mode */
+ tok->quote = Q_none;
+ break;
+
+ case Q_one: /* Quote this ' */
+ tok->quote = Q_none;
+ *tok->wptr++ = *ptr;
+ break;
+
+ case Q_double: /* Stay in double quote mode */
+ *tok->wptr++ = *ptr;
+ break;
+
+ case Q_doubleone: /* Quote this ' */
+ tok->quote = Q_double;
+ *tok->wptr++ = *ptr;
+ break;
+
+ default:
+ return(-1);
+ }
+ break;
+
+ case '"':
+ tok->flags &= ~TOK_EAT;
+ tok->flags |= TOK_KEEP;
+ switch (tok->quote) {
+ case Q_none: /* Enter double quote mode */
+ tok->quote = Q_double;
+ break;
+
+ case Q_double:
+ tok->quote = Q_none; /* Exit double quote mode */
+ break;
+
+ case Q_one: /* Quote this " */
+ tok->quote = Q_none;
+ *tok->wptr++ = *ptr;
+ break;
+
+ case Q_single: /* Stay in single quote mode */
+ *tok->wptr++ = *ptr;
+ break;
+
+ case Q_doubleone: /* Quote this " */
+ tok->quote = Q_double;
+ *tok->wptr++ = *ptr;
+ break;
+
+ default:
+ return(-1);
+ }
+ break;
+
+ case '\\':
+ tok->flags |= TOK_KEEP;
+ tok->flags &= ~TOK_EAT;
+ switch (tok->quote) {
+ case Q_none: /* Quote next character */
+ tok->quote = Q_one;
+ break;
+
+ case Q_double:
+ tok->quote = Q_doubleone;/* Quote next character */
+ break;
+
+ case Q_one:
+ *tok->wptr++ = *ptr;
+ tok->quote = Q_none; /* Quote this, restore state */
+ break;
+
+ case Q_single: /* Stay in single quote mode */
+ *tok->wptr++ = *ptr;
+ break;
+
+ case Q_doubleone: /* Quote this \ */
+ tok->quote = Q_double;
+ *tok->wptr++ = *ptr;
+ break;
+
+ default:
+ return(-1);
+ }
+ break;
+
+ case '\n':
+ tok->flags &= ~TOK_EAT;
+ switch (tok->quote) {
+ case Q_none:
+ tok_finish(tok);
+ *argv = tok->argv;
+ *argc = tok->argc;
+ return(0);
+
+ case Q_single:
+ case Q_double:
+ *tok->wptr++ = *ptr; /* Add the return */
+ break;
+
+ case Q_doubleone:
+ tok->flags |= TOK_EAT;
+ tok->quote = Q_double; /* Back to double, eat the '\n' */
+ break;
+
+ case Q_one:
+ tok->flags |= TOK_EAT;
+ tok->quote = Q_none; /* No quote, more eat the '\n' */
+ break;
+
+ default:
+ return(0);
+ }
+ break;
+
+ case '\0':
+ switch (tok->quote) {
+ case Q_none:
+ /* Finish word and return */
+ if (tok->flags & TOK_EAT) {
+ tok->flags &= ~TOK_EAT;
+ return 3;
+ }
+ tok_finish(tok);
+ *argv = tok->argv;
+ *argc = tok->argc;
+ return(0);
+
+ case Q_single:
+ return(1);
+
+ case Q_double:
+ return(2);
+
+ case Q_doubleone:
+ tok->quote = Q_double;
+ *tok->wptr++ = *ptr;
+ break;
+
+ case Q_one:
+ tok->quote = Q_none;
+ *tok->wptr++ = *ptr;
+ break;
+
+ default:
+ return(-1);
+ }
+ break;
+
+ default:
+ tok->flags &= ~TOK_EAT;
+ switch (tok->quote) {
+ case Q_none:
+ if (strchr(tok->ifs, *ptr) != NULL)
+ tok_finish(tok);
+ else
+ *tok->wptr++ = *ptr;
+ break;
+
+ case Q_single:
+ case Q_double:
+ *tok->wptr++ = *ptr;
+ break;
+
+
+ case Q_doubleone:
+ *tok->wptr++ = '\\';
+ tok->quote = Q_double;
+ *tok->wptr++ = *ptr;
+ break;
+
+ case Q_one:
+ tok->quote = Q_none;
+ *tok->wptr++ = *ptr;
+ break;
+
+ default:
+ return(-1);
+
+ }
+ break;
+ }
+
+ if (tok->wptr >= tok->wmax - 4) {
+ size_t size = tok->wmax - tok->wspace + WINCR;
+ char *s = (char *) tok_realloc(tok->wspace, size);
+ /*SUPPRESS 22*/
+ int offs = s - tok->wspace;
+
+ if (offs != 0) {
+ int i;
+ for (i = 0; i < tok->argc; i++)
+ tok->argv[i] = tok->argv[i] + offs;
+ tok->wptr = tok->wptr + offs;
+ tok->wstart = tok->wstart + offs;
+ tok->wmax = s + size;
+ tok->wspace = s;
+ }
+ }
+
+ if (tok->argc >= tok->amax - 4) {
+ tok->amax += AINCR;
+ tok->argv = (char **) tok_reallocf(tok->argv,
+ tok->amax * sizeof(char*));
+ }
+
+ }
+}
diff --git a/lib/libedit/tokenizer.h b/lib/libedit/tokenizer.h
new file mode 100644
index 0000000..86911e1
--- /dev/null
+++ b/lib/libedit/tokenizer.h
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tokenizer.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * tokenizer.h: Header file for tokenizer routines
+ */
+#ifndef _h_tokenizer
+#define _h_tokenizer
+
+typedef struct tokenizer Tokenizer;
+
+Tokenizer *tok_init __P((const char *));
+void tok_reset __P((Tokenizer *));
+void tok_end __P((Tokenizer *));
+int tok_line __P((Tokenizer *, const char *,
+ int *, char ***));
+
+#endif /* _h_tokenizer */
diff --git a/lib/libedit/tty.c b/lib/libedit/tty.c
new file mode 100644
index 0000000..2a15e3f
--- /dev/null
+++ b/lib/libedit/tty.c
@@ -0,0 +1,1144 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * tty.c: tty interface stuff
+ */
+#include "sys.h"
+#include "tty.h"
+#include "el.h"
+
+typedef struct ttymodes_t {
+ char *m_name;
+ u_int m_value;
+ int m_type;
+} ttymodes_t;
+
+typedef struct ttymap_t {
+ int nch, och; /* Internal and termio rep of chars */
+ el_action_t bind[3]; /* emacs, vi, and vi-cmd */
+} ttymap_t;
+
+
+private ttyperm_t ttyperm = {
+ {
+ { "iflag:", ICRNL, (INLCR|IGNCR) },
+ { "oflag:", (OPOST|ONLCR), ONLRET },
+ { "cflag:", 0, 0 },
+ { "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN),
+ (NOFLSH|ECHONL|EXTPROC|FLUSHO) },
+ { "chars:", 0, 0 },
+ },
+ {
+ { "iflag:", (INLCR|ICRNL), IGNCR },
+ { "oflag:", (OPOST|ONLCR), ONLRET },
+ { "cflag:", 0, 0 },
+ { "lflag:", ISIG,
+ (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO) },
+ { "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)|
+ C_SH(C_SUSP)|C_SH(C_DSUSP)|C_SH(C_EOL)|C_SH(C_DISCARD)|
+ C_SH(C_PGOFF)|C_SH(C_PAGE)|C_SH(C_STATUS)), 0 }
+ },
+ {
+ { "iflag:", 0, IXON | IXOFF | INLCR | ICRNL },
+ { "oflag:", 0, 0 },
+ { "cflag:", 0, 0 },
+ { "lflag:", 0, ISIG | IEXTEN },
+ { "chars:", 0, 0 },
+ }
+};
+
+private ttychar_t ttychar = {
+ {
+ CINTR, CQUIT, CERASE, CKILL,
+ CEOF, CEOL, CEOL2, CSWTCH,
+ CDSWTCH, CERASE2, CSTART, CSTOP,
+ CWERASE, CSUSP, CDSUSP, CREPRINT,
+ CDISCARD, CLNEXT, CSTATUS, CPAGE,
+ CPGOFF, CKILL2, CBRK, CMIN,
+ CTIME
+ },
+ {
+ CINTR, CQUIT, CERASE, CKILL,
+ _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
+ _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
+ _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
+ CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
+ _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
+ 0
+ },
+ {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0
+ }
+};
+
+private ttymap_t tty_map[] = {
+#ifdef VERASE
+ { C_ERASE, VERASE,
+ { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
+#endif /* VERASE */
+#ifdef VERASE2
+ { C_ERASE2, VERASE2,
+ { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
+#endif /* VERASE2 */
+#ifdef VKILL
+ { C_KILL, VKILL,
+ { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
+#endif /* VKILL */
+#ifdef VKILL2
+ { C_KILL2, VKILL2,
+ { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
+#endif /* VKILL2 */
+#ifdef VEOF
+ { C_EOF, VEOF,
+ { EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED } },
+#endif /* VEOF */
+#ifdef VWERASE
+ { C_WERASE, VWERASE,
+ { ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD } },
+#endif /* VWERASE */
+#ifdef VREPRINT
+ { C_REPRINT, VREPRINT,
+ { ED_REDISPLAY, ED_INSERT, ED_REDISPLAY } },
+#endif /* VREPRINT */
+#ifdef VLNEXT
+ { C_LNEXT, VLNEXT,
+ { ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED } },
+#endif /* VLNEXT */
+ { -1, -1,
+ { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } }
+ };
+
+private ttymodes_t ttymodes[] = {
+# ifdef IGNBRK
+ { "ignbrk", IGNBRK, M_INP },
+# endif /* IGNBRK */
+# ifdef BRKINT
+ { "brkint", BRKINT, M_INP },
+# endif /* BRKINT */
+# ifdef IGNPAR
+ { "ignpar", IGNPAR, M_INP },
+# endif /* IGNPAR */
+# ifdef PARMRK
+ { "parmrk", PARMRK, M_INP },
+# endif /* PARMRK */
+# ifdef INPCK
+ { "inpck", INPCK, M_INP },
+# endif /* INPCK */
+# ifdef ISTRIP
+ { "istrip", ISTRIP, M_INP },
+# endif /* ISTRIP */
+# ifdef INLCR
+ { "inlcr", INLCR, M_INP },
+# endif /* INLCR */
+# ifdef IGNCR
+ { "igncr", IGNCR, M_INP },
+# endif /* IGNCR */
+# ifdef ICRNL
+ { "icrnl", ICRNL, M_INP },
+# endif /* ICRNL */
+# ifdef IUCLC
+ { "iuclc", IUCLC, M_INP },
+# endif /* IUCLC */
+# ifdef IXON
+ { "ixon", IXON, M_INP },
+# endif /* IXON */
+# ifdef IXANY
+ { "ixany", IXANY, M_INP },
+# endif /* IXANY */
+# ifdef IXOFF
+ { "ixoff", IXOFF, M_INP },
+# endif /* IXOFF */
+# ifdef IMAXBEL
+ { "imaxbel",IMAXBEL,M_INP },
+# endif /* IMAXBEL */
+
+# ifdef OPOST
+ { "opost", OPOST, M_OUT },
+# endif /* OPOST */
+# ifdef OLCUC
+ { "olcuc", OLCUC, M_OUT },
+# endif /* OLCUC */
+# ifdef ONLCR
+ { "onlcr", ONLCR, M_OUT },
+# endif /* ONLCR */
+# ifdef OCRNL
+ { "ocrnl", OCRNL, M_OUT },
+# endif /* OCRNL */
+# ifdef ONOCR
+ { "onocr", ONOCR, M_OUT },
+# endif /* ONOCR */
+# ifdef ONOEOT
+ { "onoeot", ONOEOT, M_OUT },
+# endif /* ONOEOT */
+# ifdef ONLRET
+ { "onlret", ONLRET, M_OUT },
+# endif /* ONLRET */
+# ifdef OFILL
+ { "ofill", OFILL, M_OUT },
+# endif /* OFILL */
+# ifdef OFDEL
+ { "ofdel", OFDEL, M_OUT },
+# endif /* OFDEL */
+# ifdef NLDLY
+ { "nldly", NLDLY, M_OUT },
+# endif /* NLDLY */
+# ifdef CRDLY
+ { "crdly", CRDLY, M_OUT },
+# endif /* CRDLY */
+# ifdef TABDLY
+ { "tabdly", TABDLY, M_OUT },
+# endif /* TABDLY */
+# ifdef XTABS
+ { "xtabs", XTABS, M_OUT },
+# endif /* XTABS */
+# ifdef BSDLY
+ { "bsdly", BSDLY, M_OUT },
+# endif /* BSDLY */
+# ifdef VTDLY
+ { "vtdly", VTDLY, M_OUT },
+# endif /* VTDLY */
+# ifdef FFDLY
+ { "ffdly", FFDLY, M_OUT },
+# endif /* FFDLY */
+# ifdef PAGEOUT
+ { "pageout",PAGEOUT,M_OUT },
+# endif /* PAGEOUT */
+# ifdef WRAP
+ { "wrap", WRAP, M_OUT },
+# endif /* WRAP */
+
+# ifdef CIGNORE
+ { "cignore",CIGNORE,M_CTL },
+# endif /* CBAUD */
+# ifdef CBAUD
+ { "cbaud", CBAUD, M_CTL },
+# endif /* CBAUD */
+# ifdef CSTOPB
+ { "cstopb", CSTOPB, M_CTL },
+# endif /* CSTOPB */
+# ifdef CREAD
+ { "cread", CREAD, M_CTL },
+# endif /* CREAD */
+# ifdef PARENB
+ { "parenb", PARENB, M_CTL },
+# endif /* PARENB */
+# ifdef PARODD
+ { "parodd", PARODD, M_CTL },
+# endif /* PARODD */
+# ifdef HUPCL
+ { "hupcl", HUPCL, M_CTL },
+# endif /* HUPCL */
+# ifdef CLOCAL
+ { "clocal", CLOCAL, M_CTL },
+# endif /* CLOCAL */
+# ifdef LOBLK
+ { "loblk", LOBLK, M_CTL },
+# endif /* LOBLK */
+# ifdef CIBAUD
+ { "cibaud", CIBAUD, M_CTL },
+# endif /* CIBAUD */
+# ifdef CRTSCTS
+# ifdef CCTS_OFLOW
+ { "ccts_oflow",CCTS_OFLOW,M_CTL },
+# else
+ { "crtscts",CRTSCTS,M_CTL },
+# endif /* CCTS_OFLOW */
+# endif /* CRTSCTS */
+# ifdef CRTS_IFLOW
+ { "crts_iflow",CRTS_IFLOW,M_CTL },
+# endif /* CRTS_IFLOW */
+# ifdef MDMBUF
+ { "mdmbuf", MDMBUF, M_CTL },
+# endif /* MDMBUF */
+# ifdef RCV1EN
+ { "rcv1en", RCV1EN, M_CTL },
+# endif /* RCV1EN */
+# ifdef XMT1EN
+ { "xmt1en", XMT1EN, M_CTL },
+# endif /* XMT1EN */
+
+# ifdef ISIG
+ { "isig", ISIG, M_LIN },
+# endif /* ISIG */
+# ifdef ICANON
+ { "icanon", ICANON, M_LIN },
+# endif /* ICANON */
+# ifdef XCASE
+ { "xcase", XCASE, M_LIN },
+# endif /* XCASE */
+# ifdef ECHO
+ { "echo", ECHO, M_LIN },
+# endif /* ECHO */
+# ifdef ECHOE
+ { "echoe", ECHOE, M_LIN },
+# endif /* ECHOE */
+# ifdef ECHOK
+ { "echok", ECHOK, M_LIN },
+# endif /* ECHOK */
+# ifdef ECHONL
+ { "echonl", ECHONL, M_LIN },
+# endif /* ECHONL */
+# ifdef NOFLSH
+ { "noflsh", NOFLSH, M_LIN },
+# endif /* NOFLSH */
+# ifdef TOSTOP
+ { "tostop", TOSTOP, M_LIN },
+# endif /* TOSTOP */
+# ifdef ECHOCTL
+ { "echoctl",ECHOCTL,M_LIN },
+# endif /* ECHOCTL */
+# ifdef ECHOPRT
+ { "echoprt",ECHOPRT,M_LIN },
+# endif /* ECHOPRT */
+# ifdef ECHOKE
+ { "echoke", ECHOKE, M_LIN },
+# endif /* ECHOKE */
+# ifdef DEFECHO
+ { "defecho",DEFECHO,M_LIN },
+# endif /* DEFECHO */
+# ifdef FLUSHO
+ { "flusho", FLUSHO, M_LIN },
+# endif /* FLUSHO */
+# ifdef PENDIN
+ { "pendin", PENDIN, M_LIN },
+# endif /* PENDIN */
+# ifdef IEXTEN
+ { "iexten", IEXTEN, M_LIN },
+# endif /* IEXTEN */
+# ifdef NOKERNINFO
+ { "nokerninfo",NOKERNINFO,M_LIN },
+# endif /* NOKERNINFO */
+# ifdef ALTWERASE
+ { "altwerase",ALTWERASE,M_LIN },
+# endif /* ALTWERASE */
+# ifdef EXTPROC
+ { "extproc",EXTPROC, M_LIN },
+# endif /* EXTPROC */
+
+# if defined(VINTR)
+ { "intr", C_SH(C_INTR), M_CHAR },
+# endif /* VINTR */
+# if defined(VQUIT)
+ { "quit", C_SH(C_QUIT), M_CHAR },
+# endif /* VQUIT */
+# if defined(VERASE)
+ { "erase", C_SH(C_ERASE), M_CHAR },
+# endif /* VERASE */
+# if defined(VKILL)
+ { "kill", C_SH(C_KILL), M_CHAR },
+# endif /* VKILL */
+# if defined(VEOF)
+ { "eof", C_SH(C_EOF), M_CHAR },
+# endif /* VEOF */
+# if defined(VEOL)
+ { "eol", C_SH(C_EOL), M_CHAR },
+# endif /* VEOL */
+# if defined(VEOL2)
+ { "eol2", C_SH(C_EOL2), M_CHAR },
+# endif /* VEOL2 */
+# if defined(VSWTCH)
+ { "swtch", C_SH(C_SWTCH), M_CHAR },
+# endif /* VSWTCH */
+# if defined(VDSWTCH)
+ { "dswtch", C_SH(C_DSWTCH), M_CHAR },
+# endif /* VDSWTCH */
+# if defined(VERASE2)
+ { "erase2", C_SH(C_ERASE2), M_CHAR },
+# endif /* VERASE2 */
+# if defined(VSTART)
+ { "start", C_SH(C_START), M_CHAR },
+# endif /* VSTART */
+# if defined(VSTOP)
+ { "stop", C_SH(C_STOP), M_CHAR },
+# endif /* VSTOP */
+# if defined(VWERASE)
+ { "werase", C_SH(C_WERASE), M_CHAR },
+# endif /* VWERASE */
+# if defined(VSUSP)
+ { "susp", C_SH(C_SUSP), M_CHAR },
+# endif /* VSUSP */
+# if defined(VDSUSP)
+ { "dsusp", C_SH(C_DSUSP), M_CHAR },
+# endif /* VDSUSP */
+# if defined(VREPRINT)
+ { "reprint", C_SH(C_REPRINT),M_CHAR },
+# endif /* VREPRINT */
+# if defined(VDISCARD)
+ { "discard", C_SH(C_DISCARD),M_CHAR },
+# endif /* VDISCARD */
+# if defined(VLNEXT)
+ { "lnext", C_SH(C_LNEXT), M_CHAR },
+# endif /* VLNEXT */
+# if defined(VSTATUS)
+ { "status", C_SH(C_STATUS), M_CHAR },
+# endif /* VSTATUS */
+# if defined(VPAGE)
+ { "page", C_SH(C_PAGE), M_CHAR },
+# endif /* VPAGE */
+# if defined(VPGOFF)
+ { "pgoff", C_SH(C_PGOFF), M_CHAR },
+# endif /* VPGOFF */
+# if defined(VKILL2)
+ { "kill2", C_SH(C_KILL2), M_CHAR },
+# endif /* VKILL2 */
+# if defined(VBRK)
+ { "brk", C_SH(C_BRK), M_CHAR },
+# endif /* VBRK */
+# if defined(VMIN)
+ { "min", C_SH(C_MIN), M_CHAR },
+# endif /* VMIN */
+# if defined(VTIME)
+ { "time", C_SH(C_TIME), M_CHAR },
+# endif /* VTIME */
+ { NULL, 0, -1 },
+};
+
+
+
+#define tty_getty(el, td) tcgetattr((el)->el_infd, (td))
+#define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td))
+
+#define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
+#define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
+#define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
+
+private void tty__getchar __P((struct termios *, unsigned char *));
+private void tty__setchar __P((struct termios *, unsigned char *));
+private speed_t tty__getspeed __P((struct termios *));
+private int tty_setup __P((EditLine *));
+
+#define t_qu t_ts
+
+
+/* tty_setup():
+ * Get the tty parameters and initialize the editing state
+ */
+private int
+tty_setup(el)
+ EditLine *el;
+{
+ int rst = 1;
+ if (tty_getty(el, &el->el_tty.t_ed) == -1) {
+#ifdef DEBUG_TTY
+ (void) fprintf(el->el_errfile,
+ "tty_setup: tty_getty: %s\n", strerror(errno));
+#endif /* DEBUG_TTY */
+ return(-1);
+ }
+ el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
+
+ el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
+ el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
+ el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
+
+ el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask;
+ el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask;
+
+ el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask;
+ el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask;
+
+ el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask;
+ el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask;
+
+ el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask;
+ el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask;
+
+ /*
+ * Reset the tty chars to reasonable defaults
+ * If they are disabled, then enable them.
+ */
+ if (rst) {
+ if (tty__cooked_mode(&el->el_tty.t_ts)) {
+ tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
+ /*
+ * Don't affect CMIN and CTIME for the editor mode
+ */
+ for (rst = 0; rst < C_NCC - 2; rst++)
+ if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
+ el->el_tty.t_c[ED_IO][rst] != el->el_tty.t_vdisable)
+ el->el_tty.t_c[ED_IO][rst] = el->el_tty.t_c[TS_IO][rst];
+ for (rst = 0; rst < C_NCC; rst++)
+ if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
+ el->el_tty.t_c[EX_IO][rst] != el->el_tty.t_vdisable)
+ el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst];
+ }
+ tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
+ if (tty_setty(el, &el->el_tty.t_ex) == -1) {
+#ifdef DEBUG_TTY
+ (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n",
+ strerror(errno));
+#endif /* DEBUG_TTY */
+ return(-1);
+ }
+ }
+ else
+ tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
+
+ el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
+ el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
+
+ el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
+ el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
+
+ el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
+ el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
+
+ el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
+ el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
+
+ tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
+ return 0;
+}
+
+protected int
+tty_init(el)
+ EditLine *el;
+{
+ el->el_tty.t_mode = EX_IO;
+ el->el_tty.t_vdisable = _POSIX_VDISABLE;
+ (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
+ (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
+ return tty_setup(el);
+} /* end tty_init */
+
+
+/* tty_end():
+ * Restore the tty to its original settings
+ */
+protected void
+/*ARGSUSED*/
+tty_end(el)
+ EditLine *el;
+{
+ /* XXX: Maybe reset to an initial state? */
+}
+
+
+/* tty__getspeed():
+ * Get the tty speed
+ */
+private speed_t
+tty__getspeed(td)
+ struct termios *td;
+{
+ speed_t spd;
+
+ if ((spd = cfgetispeed(td)) == 0)
+ spd = cfgetospeed(td);
+ return spd;
+} /* end tty__getspeed */
+
+
+/* tty__getchar():
+ * Get the tty characters
+ */
+private void
+tty__getchar(td, s)
+ struct termios *td;
+ unsigned char *s;
+{
+# ifdef VINTR
+ s[C_INTR] = td->c_cc[VINTR];
+# endif /* VINTR */
+# ifdef VQUIT
+ s[C_QUIT] = td->c_cc[VQUIT];
+# endif /* VQUIT */
+# ifdef VERASE
+ s[C_ERASE] = td->c_cc[VERASE];
+# endif /* VERASE */
+# ifdef VKILL
+ s[C_KILL] = td->c_cc[VKILL];
+# endif /* VKILL */
+# ifdef VEOF
+ s[C_EOF] = td->c_cc[VEOF];
+# endif /* VEOF */
+# ifdef VEOL
+ s[C_EOL] = td->c_cc[VEOL];
+# endif /* VEOL */
+# ifdef VEOL2
+ s[C_EOL2] = td->c_cc[VEOL2];
+# endif /* VEOL2 */
+# ifdef VSWTCH
+ s[C_SWTCH] = td->c_cc[VSWTCH];
+# endif /* VSWTCH */
+# ifdef VDSWTCH
+ s[C_DSWTCH] = td->c_cc[VDSWTCH];
+# endif /* VDSWTCH */
+# ifdef VERASE2
+ s[C_ERASE2] = td->c_cc[VERASE2];
+# endif /* VERASE2 */
+# ifdef VSTART
+ s[C_START] = td->c_cc[VSTART];
+# endif /* VSTART */
+# ifdef VSTOP
+ s[C_STOP] = td->c_cc[VSTOP];
+# endif /* VSTOP */
+# ifdef VWERASE
+ s[C_WERASE] = td->c_cc[VWERASE];
+# endif /* VWERASE */
+# ifdef VSUSP
+ s[C_SUSP] = td->c_cc[VSUSP];
+# endif /* VSUSP */
+# ifdef VDSUSP
+ s[C_DSUSP] = td->c_cc[VDSUSP];
+# endif /* VDSUSP */
+# ifdef VREPRINT
+ s[C_REPRINT]= td->c_cc[VREPRINT];
+# endif /* VREPRINT */
+# ifdef VDISCARD
+ s[C_DISCARD]= td->c_cc[VDISCARD];
+# endif /* VDISCARD */
+# ifdef VLNEXT
+ s[C_LNEXT] = td->c_cc[VLNEXT];
+# endif /* VLNEXT */
+# ifdef VSTATUS
+ s[C_STATUS] = td->c_cc[VSTATUS];
+# endif /* VSTATUS */
+# ifdef VPAGE
+ s[C_PAGE] = td->c_cc[VPAGE];
+# endif /* VPAGE */
+# ifdef VPGOFF
+ s[C_PGOFF] = td->c_cc[VPGOFF];
+# endif /* VPGOFF */
+# ifdef VKILL2
+ s[C_KILL2] = td->c_cc[VKILL2];
+# endif /* KILL2 */
+# ifdef VMIN
+ s[C_MIN] = td->c_cc[VMIN];
+# endif /* VMIN */
+# ifdef VTIME
+ s[C_TIME] = td->c_cc[VTIME];
+# endif /* VTIME */
+} /* tty__getchar */
+
+
+/* tty__setchar():
+ * Set the tty characters
+ */
+private void
+tty__setchar(td, s)
+ struct termios *td;
+ unsigned char *s;
+{
+# ifdef VINTR
+ td->c_cc[VINTR] = s[C_INTR];
+# endif /* VINTR */
+# ifdef VQUIT
+ td->c_cc[VQUIT] = s[C_QUIT];
+# endif /* VQUIT */
+# ifdef VERASE
+ td->c_cc[VERASE] = s[C_ERASE];
+# endif /* VERASE */
+# ifdef VKILL
+ td->c_cc[VKILL] = s[C_KILL];
+# endif /* VKILL */
+# ifdef VEOF
+ td->c_cc[VEOF] = s[C_EOF];
+# endif /* VEOF */
+# ifdef VEOL
+ td->c_cc[VEOL] = s[C_EOL];
+# endif /* VEOL */
+# ifdef VEOL2
+ td->c_cc[VEOL2] = s[C_EOL2];
+# endif /* VEOL2 */
+# ifdef VSWTCH
+ td->c_cc[VSWTCH] = s[C_SWTCH];
+# endif /* VSWTCH */
+# ifdef VDSWTCH
+ td->c_cc[VDSWTCH] = s[C_DSWTCH];
+# endif /* VDSWTCH */
+# ifdef VERASE2
+ td->c_cc[VERASE2] = s[C_ERASE2];
+# endif /* VERASE2 */
+# ifdef VSTART
+ td->c_cc[VSTART] = s[C_START];
+# endif /* VSTART */
+# ifdef VSTOP
+ td->c_cc[VSTOP] = s[C_STOP];
+# endif /* VSTOP */
+# ifdef VWERASE
+ td->c_cc[VWERASE] = s[C_WERASE];
+# endif /* VWERASE */
+# ifdef VSUSP
+ td->c_cc[VSUSP] = s[C_SUSP];
+# endif /* VSUSP */
+# ifdef VDSUSP
+ td->c_cc[VDSUSP] = s[C_DSUSP];
+# endif /* VDSUSP */
+# ifdef VREPRINT
+ td->c_cc[VREPRINT] = s[C_REPRINT];
+# endif /* VREPRINT */
+# ifdef VDISCARD
+ td->c_cc[VDISCARD] = s[C_DISCARD];
+# endif /* VDISCARD */
+# ifdef VLNEXT
+ td->c_cc[VLNEXT] = s[C_LNEXT];
+# endif /* VLNEXT */
+# ifdef VSTATUS
+ td->c_cc[VSTATUS] = s[C_STATUS];
+# endif /* VSTATUS */
+# ifdef VPAGE
+ td->c_cc[VPAGE] = s[C_PAGE];
+# endif /* VPAGE */
+# ifdef VPGOFF
+ td->c_cc[VPGOFF] = s[C_PGOFF];
+# endif /* VPGOFF */
+# ifdef VKILL2
+ td->c_cc[VKILL2] = s[C_KILL2];
+# endif /* VKILL2 */
+# ifdef VMIN
+ td->c_cc[VMIN] = s[C_MIN];
+# endif /* VMIN */
+# ifdef VTIME
+ td->c_cc[VTIME] = s[C_TIME];
+# endif /* VTIME */
+} /* tty__setchar */
+
+
+/* tty_bind_char():
+ * Rebind the editline functions
+ */
+protected void
+tty_bind_char(el, force)
+ EditLine *el;
+ int force;
+{
+ unsigned char *t_n = el->el_tty.t_c[ED_IO];
+ unsigned char *t_o = el->el_tty.t_ed.c_cc;
+ char new[2], old[2];
+ ttymap_t *tp;
+ el_action_t *dmap, *dalt, *map, *alt;
+ new[1] = old[1] = '\0';
+
+
+ map = el->el_map.key;
+ alt = el->el_map.alt;
+ if (el->el_map.type == MAP_VI) {
+ dmap = el->el_map.vii;
+ dalt = el->el_map.vic;
+ }
+ else {
+ dmap = el->el_map.emacs;
+ dalt = NULL;
+ }
+
+ for (tp = tty_map; tp->nch != -1; tp++) {
+ new[0] = t_n[tp->nch];
+ old[0] = t_o[tp->och];
+ if (new[0] == old[0] && !force)
+ continue;
+ /* Put the old default binding back, and set the new binding */
+ key_clear(el, map, old);
+ map[old[0]] = dmap[old[0]];
+ key_clear(el, map, new);
+ /* MAP_VI == 1, MAP_EMACS == 0... */
+ map[new[0]] = tp->bind[el->el_map.type];
+ if (dalt) {
+ key_clear(el, alt, old);
+ alt[old[0]] = dalt[old[0]];
+ key_clear(el, alt, new);
+ alt[new[0]] = tp->bind[el->el_map.type+1];
+ }
+ }
+}
+
+/* tty_rawmode():
+ * Set terminal into 1 character at a time mode.
+ */
+protected int
+tty_rawmode(el)
+ EditLine *el;
+{
+ if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
+ return (0);
+
+ if (tty_getty(el, &el->el_tty.t_ts) == -1) {
+#ifdef DEBUG_TTY
+ (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", strerror(errno));
+#endif /* DEBUG_TTY */
+ return(-1);
+ }
+
+ /*
+ * We always keep up with the eight bit setting and the speed of the
+ * tty. But only we only believe changes that are made to cooked mode!
+ */
+ el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
+ el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
+
+ if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
+ tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
+ (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
+ (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
+ (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
+ (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
+ }
+
+ if (tty__cooked_mode(&el->el_tty.t_ts)) {
+ if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
+ el->el_tty.t_ex.c_cflag = el->el_tty.t_ts.c_cflag;
+ el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask;
+ el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask;
+
+ el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag;
+ el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
+ el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
+ }
+
+ if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
+ (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
+ el->el_tty.t_ex.c_lflag = el->el_tty.t_ts.c_lflag;
+ el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask;
+ el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask;
+
+ el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag;
+ el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
+ el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
+ }
+
+ if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
+ (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
+ el->el_tty.t_ex.c_iflag = el->el_tty.t_ts.c_iflag;
+ el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask;
+ el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask;
+
+ el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag;
+ el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
+ el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
+ }
+
+ if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
+ (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
+ el->el_tty.t_ex.c_oflag = el->el_tty.t_ts.c_oflag;
+ el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask;
+ el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask;
+
+ el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag;
+ el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
+ el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
+ }
+
+ if (tty__gettabs(&el->el_tty.t_ex) == 0)
+ el->el_tty.t_tabs = 0;
+ else
+ el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
+
+ {
+ int i;
+
+ tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
+ /*
+ * Check if the user made any changes.
+ * If he did, then propagate the changes to the
+ * edit and execute data structures.
+ */
+ for (i = 0; i < C_NCC; i++)
+ if (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])
+ break;
+
+ if (i != C_NCC) {
+ /*
+ * Propagate changes only to the unprotected chars
+ * that have been modified just now.
+ */
+ for (i = 0; i < C_NCC; i++) {
+ if (!((el->el_tty.t_t[ED_IO][M_CHAR].t_setmask & C_SH(i)))
+ && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
+ el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
+ if (el->el_tty.t_t[ED_IO][M_CHAR].t_clrmask & C_SH(i))
+ el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
+ }
+ tty_bind_char(el, 0);
+ tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
+
+ for (i = 0; i < C_NCC; i++) {
+ if (!((el->el_tty.t_t[EX_IO][M_CHAR].t_setmask & C_SH(i)))
+ && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
+ el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
+ if (el->el_tty.t_t[EX_IO][M_CHAR].t_clrmask & C_SH(i))
+ el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
+ }
+ tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
+ }
+
+ }
+ }
+
+ if (tty_setty(el, &el->el_tty.t_ed) == -1) {
+#ifdef DEBUG_TTY
+ (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
+ strerror(errno));
+#endif /* DEBUG_TTY */
+ return -1;
+ }
+ el->el_tty.t_mode = ED_IO;
+ return (0);
+} /* end tty_rawmode */
+
+
+/* tty_cookedmode():
+ * Set the tty back to normal mode
+ */
+protected int
+tty_cookedmode(el)
+ EditLine *el;
+{ /* set tty in normal setup */
+ if (el->el_tty.t_mode == EX_IO)
+ return (0);
+
+ if (tty_setty(el, &el->el_tty.t_ex) == -1) {
+#ifdef DEBUG_TTY
+ (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n",
+ strerror(errno));
+#endif /* DEBUG_TTY */
+ return -1;
+ }
+ el->el_tty.t_mode = EX_IO;
+ return (0);
+} /* end tty_cookedmode */
+
+
+/* tty_quotemode():
+ * Turn on quote mode
+ */
+protected int
+tty_quotemode(el)
+ EditLine *el;
+{
+ if (el->el_tty.t_mode == QU_IO)
+ return 0;
+
+ el->el_tty.t_qu = el->el_tty.t_ed;
+
+ el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][M_INP].t_clrmask;
+ el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][M_INP].t_setmask;
+
+ el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][M_OUT].t_clrmask;
+ el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][M_OUT].t_setmask;
+
+ el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][M_CTL].t_clrmask;
+ el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][M_CTL].t_setmask;
+
+ el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][M_LIN].t_clrmask;
+ el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][M_LIN].t_setmask;
+
+ if (tty_setty(el, &el->el_tty.t_qu) == -1) {
+#ifdef DEBUG_TTY
+ (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
+ strerror(errno));
+#endif /* DEBUG_TTY */
+ return -1;
+ }
+ el->el_tty.t_mode = QU_IO;
+ return 0;
+} /* end tty_quotemode */
+
+
+/* tty_noquotemode():
+ * Turn off quote mode
+ */
+protected int
+tty_noquotemode(el)
+ EditLine *el;
+{
+ if (el->el_tty.t_mode != QU_IO)
+ return 0;
+ if (tty_setty(el, &el->el_tty.t_ed) == -1) {
+#ifdef DEBUG_TTY
+ (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
+ strerror(errno));
+#endif /* DEBUG_TTY */
+ return -1;
+ }
+ el->el_tty.t_mode = ED_IO;
+ return 0;
+}
+
+/* tty_stty():
+ * Stty builtin
+ */
+protected int
+/*ARGSUSED*/
+tty_stty(el, argc, argv)
+ EditLine *el;
+ int argc;
+ char **argv;
+{
+ ttymodes_t *m;
+ char x, *d;
+ int aflag = 0;
+ char *s;
+ char *name;
+ int z = EX_IO;
+
+ if (argv == NULL)
+ return -1;
+ name = *argv++;
+
+ while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
+ switch (argv[0][1]) {
+ case 'a':
+ aflag++;
+ argv++;
+ break;
+ case 'd':
+ argv++;
+ z = ED_IO;
+ break;
+ case 'x':
+ argv++;
+ z = EX_IO;
+ break;
+ case 'q':
+ argv++;
+ z = QU_IO;
+ break;
+ default:
+ (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n",
+ name, argv[0][1]);
+ return -1;
+ }
+
+ if (!argv || !*argv) {
+ int i = -1;
+ int len = 0, st = 0, cu;
+ for (m = ttymodes; m->m_name; m++) {
+ if (m->m_type != i) {
+ (void) fprintf(el->el_outfile, "%s%s", i != -1 ? "\n" : "",
+ el->el_tty.t_t[z][m->m_type].t_name);
+ i = m->m_type;
+ st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name);
+ }
+
+ x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0';
+ x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '-' : x;
+
+ if (x != '\0' || aflag) {
+
+ cu = strlen(m->m_name) + (x != '\0') + 1;
+
+ if (len + cu >= el->el_term.t_size.h) {
+ (void) fprintf(el->el_outfile, "\n%*s", st, "");
+ len = st + cu;
+ }
+ else
+ len += cu;
+
+ if (x != '\0')
+ (void) fprintf(el->el_outfile, "%c%s ", x, m->m_name);
+ else
+ (void) fprintf(el->el_outfile, "%s ", m->m_name);
+ }
+ }
+ (void) fprintf(el->el_outfile, "\n");
+ return 0;
+ }
+
+ while (argv && (s = *argv++)) {
+ switch (*s) {
+ case '+':
+ case '-':
+ x = *s++;
+ break;
+ default:
+ x = '\0';
+ break;
+ }
+ d = s;
+ for (m = ttymodes; m->m_name; m++)
+ if (strcmp(m->m_name, d) == 0)
+ break;
+
+ if (!m->m_name) {
+ (void) fprintf(el->el_errfile, "%s: Invalid argument `%s'.\n",
+ name, d);
+ return -1;
+ }
+
+ switch (x) {
+ case '+':
+ el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
+ el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
+ break;
+ case '-':
+ el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
+ el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
+ break;
+ default:
+ el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
+ el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
+ break;
+ }
+ }
+ return 0;
+} /* end tty_stty */
+
+
+#ifdef notyet
+/* tty_printchar():
+ * DEbugging routine to print the tty characters
+ */
+private void
+tty_printchar(el, s)
+ EditLine *el;
+ unsigned char *s;
+{
+ ttyperm_t *m;
+ int i;
+
+ for (i = 0; i < C_NCC; i++) {
+ for (m = el->el_tty.t_t; m->m_name; m++)
+ if (m->m_type == M_CHAR && C_SH(i) == m->m_value)
+ break;
+ if (m->m_name)
+ (void) fprintf(el->el_errfile, "%s ^%c ", m->m_name, s[i] + 'A'-1);
+ if (i % 5 == 0)
+ (void) fprintf(el->el_errfile, "\n");
+ }
+ (void) fprintf(el->el_errfile, "\n");
+}
+#endif /* notyet */
diff --git a/lib/libedit/tty.h b/lib/libedit/tty.h
new file mode 100644
index 0000000..294c36a
--- /dev/null
+++ b/lib/libedit/tty.h
@@ -0,0 +1,481 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tty.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.tty.h: Local terminal header
+ */
+#ifndef _h_el_tty
+#define _h_el_tty
+
+#include "histedit.h"
+#include <termios.h>
+
+/* Define our own since everyone gets it wrong! */
+#define CONTROL(A) ((A) & 037)
+
+/*
+ * Aix compatible names
+ */
+# if defined(VWERSE) && !defined(VWERASE)
+# define VWERASE VWERSE
+# endif /* VWERSE && !VWERASE */
+
+# if defined(VDISCRD) && !defined(VDISCARD)
+# define VDISCARD VDISCRD
+# endif /* VDISCRD && !VDISCARD */
+
+# if defined(VFLUSHO) && !defined(VDISCARD)
+# define VDISCARD VFLUSHO
+# endif /* VFLUSHO && VDISCARD */
+
+# if defined(VSTRT) && !defined(VSTART)
+# define VSTART VSTRT
+# endif /* VSTRT && ! VSTART */
+
+# if defined(VSTAT) && !defined(VSTATUS)
+# define VSTATUS VSTAT
+# endif /* VSTAT && ! VSTATUS */
+
+# ifndef ONLRET
+# define ONLRET 0
+# endif /* ONLRET */
+
+# ifndef TAB3
+# ifdef OXTABS
+# define TAB3 OXTABS
+# else
+# define TAB3 0
+# endif /* OXTABS */
+# endif /* !TAB3 */
+
+# if defined(OXTABS) && !defined(XTABS)
+# define XTABS OXTABS
+# endif /* OXTABS && !XTABS */
+
+# ifndef ONLCR
+# define ONLCR 0
+# endif /* ONLCR */
+
+# ifndef IEXTEN
+# define IEXTEN 0
+# endif /* IEXTEN */
+
+# ifndef ECHOCTL
+# define ECHOCTL 0
+# endif /* ECHOCTL */
+
+# ifndef PARENB
+# define PARENB 0
+# endif /* PARENB */
+
+# ifndef EXTPROC
+# define EXTPROC 0
+# endif /* EXTPROC */
+
+# ifndef FLUSHO
+# define FLUSHO 0
+# endif /* FLUSHO */
+
+
+# if defined(VDISABLE) && !defined(_POSIX_VDISABLE)
+# define _POSIX_VDISABLE VDISABLE
+# endif /* VDISABLE && ! _POSIX_VDISABLE */
+
+/*
+ * Work around ISC's definition of IEXTEN which is
+ * XCASE!
+ */
+# ifdef ISC
+# if defined(IEXTEN) && defined(XCASE)
+# if IEXTEN == XCASE
+# undef IEXTEN
+# define IEXTEN 0
+# endif /* IEXTEN == XCASE */
+# endif /* IEXTEN && XCASE */
+# if defined(IEXTEN) && !defined(XCASE)
+# define XCASE IEXTEN
+# undef IEXTEN
+# define IEXTEN 0
+# endif /* IEXTEN && !XCASE */
+# endif /* ISC */
+
+/*
+ * Work around convex weirdness where turning off IEXTEN makes us
+ * lose all postprocessing!
+ */
+#if defined(convex) || defined(__convex__)
+# if defined(IEXTEN) && IEXTEN != 0
+# undef IEXTEN
+# define IEXTEN 0
+# endif /* IEXTEN != 0 */
+#endif /* convex || __convex__ */
+
+/*
+ * So that we don't lose job control.
+ */
+#ifdef __SVR4
+# undef CSWTCH
+#endif
+
+#ifndef _POSIX_VDISABLE
+# define _POSIX_VDISABLE ((unsigned char) -1)
+#endif /* _POSIX_VDISABLE */
+
+#if !defined(CREPRINT) && defined(CRPRNT)
+# define CREPRINT CRPRNT
+#endif /* !CREPRINT && CRPRNT */
+#if !defined(CDISCARD) && defined(CFLUSH)
+# define CDISCARD CFLUSH
+#endif /* !CDISCARD && CFLUSH */
+
+#ifndef CINTR
+# define CINTR CONTROL('c')
+#endif /* CINTR */
+#ifndef CQUIT
+# define CQUIT 034 /* ^\ */
+#endif /* CQUIT */
+#ifndef CERASE
+# define CERASE 0177 /* ^? */
+#endif /* CERASE */
+#ifndef CKILL
+# define CKILL CONTROL('u')
+#endif /* CKILL */
+#ifndef CEOF
+# define CEOF CONTROL('d')
+#endif /* CEOF */
+#ifndef CEOL
+# define CEOL _POSIX_VDISABLE
+#endif /* CEOL */
+#ifndef CEOL2
+# define CEOL2 _POSIX_VDISABLE
+#endif /* CEOL2 */
+#ifndef CSWTCH
+# define CSWTCH _POSIX_VDISABLE
+#endif /* CSWTCH */
+#ifndef CDSWTCH
+# define CDSWTCH _POSIX_VDISABLE
+#endif /* CDSWTCH */
+#ifndef CERASE2
+# define CERASE2 _POSIX_VDISABLE
+#endif /* CERASE2 */
+#ifndef CSTART
+# define CSTART CONTROL('q')
+#endif /* CSTART */
+#ifndef CSTOP
+# define CSTOP CONTROL('s')
+#endif /* CSTOP */
+#ifndef CSUSP
+# define CSUSP CONTROL('z')
+#endif /* CSUSP */
+#ifndef CDSUSP
+# define CDSUSP CONTROL('y')
+#endif /* CDSUSP */
+
+#ifdef hpux
+
+# ifndef CREPRINT
+# define CREPRINT _POSIX_VDISABLE
+# endif /* CREPRINT */
+# ifndef CDISCARD
+# define CDISCARD _POSIX_VDISABLE
+# endif /* CDISCARD */
+# ifndef CLNEXT
+# define CLNEXT _POSIX_VDISABLE
+# endif /* CLNEXT */
+# ifndef CWERASE
+# define CWERASE _POSIX_VDISABLE
+# endif /* CWERASE */
+
+#else /* !hpux */
+
+# ifndef CREPRINT
+# define CREPRINT CONTROL('r')
+# endif /* CREPRINT */
+# ifndef CDISCARD
+# define CDISCARD CONTROL('o')
+# endif /* CDISCARD */
+# ifndef CLNEXT
+# define CLNEXT CONTROL('v')
+# endif /* CLNEXT */
+# ifndef CWERASE
+# define CWERASE CONTROL('w')
+# endif /* CWERASE */
+
+#endif /* hpux */
+
+#ifndef CSTATUS
+# define CSTATUS CONTROL('t')
+#endif /* CSTATUS */
+#ifndef CPAGE
+# define CPAGE ' '
+#endif /* CPAGE */
+#ifndef CPGOFF
+# define CPGOFF CONTROL('m')
+#endif /* CPGOFF */
+#ifndef CKILL2
+# define CKILL2 _POSIX_VDISABLE
+#endif /* CKILL2 */
+#ifndef CBRK
+# ifndef masscomp
+# define CBRK 0377
+# else
+# define CBRK '\0'
+# endif /* masscomp */
+#endif /* CBRK */
+#ifndef CMIN
+# define CMIN CEOF
+#endif /* CMIN */
+#ifndef CTIME
+# define CTIME CEOL
+#endif /* CTIME */
+
+/*
+ * Fix for sun inconsistency. On termio VSUSP and the rest of the
+ * ttychars > NCC are defined. So we undefine them.
+ */
+#if defined(TERMIO) || defined(POSIX)
+# if defined(POSIX) && defined(NCCS)
+# define NUMCC NCCS
+# else
+# ifdef NCC
+# define NUMCC NCC
+# endif /* NCC */
+# endif /* POSIX && NCCS */
+# ifdef NUMCC
+# ifdef VINTR
+# if NUMCC <= VINTR
+# undef VINTR
+# endif /* NUMCC <= VINTR */
+# endif /* VINTR */
+# ifdef VQUIT
+# if NUMCC <= VQUIT
+# undef VQUIT
+# endif /* NUMCC <= VQUIT */
+# endif /* VQUIT */
+# ifdef VERASE
+# if NUMCC <= VERASE
+# undef VERASE
+# endif /* NUMCC <= VERASE */
+# endif /* VERASE */
+# ifdef VKILL
+# if NUMCC <= VKILL
+# undef VKILL
+# endif /* NUMCC <= VKILL */
+# endif /* VKILL */
+# ifdef VEOF
+# if NUMCC <= VEOF
+# undef VEOF
+# endif /* NUMCC <= VEOF */
+# endif /* VEOF */
+# ifdef VEOL
+# if NUMCC <= VEOL
+# undef VEOL
+# endif /* NUMCC <= VEOL */
+# endif /* VEOL */
+# ifdef VEOL2
+# if NUMCC <= VEOL2
+# undef VEOL2
+# endif /* NUMCC <= VEOL2 */
+# endif /* VEOL2 */
+# ifdef VSWTCH
+# if NUMCC <= VSWTCH
+# undef VSWTCH
+# endif /* NUMCC <= VSWTCH */
+# endif /* VSWTCH */
+# ifdef VDSWTCH
+# if NUMCC <= VDSWTCH
+# undef VDSWTCH
+# endif /* NUMCC <= VDSWTCH */
+# endif /* VDSWTCH */
+# ifdef VERASE2
+# if NUMCC <= VERASE2
+# undef VERASE2
+# endif /* NUMCC <= VERASE2 */
+# endif /* VERASE2 */
+# ifdef VSTART
+# if NUMCC <= VSTART
+# undef VSTART
+# endif /* NUMCC <= VSTART */
+# endif /* VSTART */
+# ifdef VSTOP
+# if NUMCC <= VSTOP
+# undef VSTOP
+# endif /* NUMCC <= VSTOP */
+# endif /* VSTOP */
+# ifdef VWERASE
+# if NUMCC <= VWERASE
+# undef VWERASE
+# endif /* NUMCC <= VWERASE */
+# endif /* VWERASE */
+# ifdef VSUSP
+# if NUMCC <= VSUSP
+# undef VSUSP
+# endif /* NUMCC <= VSUSP */
+# endif /* VSUSP */
+# ifdef VDSUSP
+# if NUMCC <= VDSUSP
+# undef VDSUSP
+# endif /* NUMCC <= VDSUSP */
+# endif /* VDSUSP */
+# ifdef VREPRINT
+# if NUMCC <= VREPRINT
+# undef VREPRINT
+# endif /* NUMCC <= VREPRINT */
+# endif /* VREPRINT */
+# ifdef VDISCARD
+# if NUMCC <= VDISCARD
+# undef VDISCARD
+# endif /* NUMCC <= VDISCARD */
+# endif /* VDISCARD */
+# ifdef VLNEXT
+# if NUMCC <= VLNEXT
+# undef VLNEXT
+# endif /* NUMCC <= VLNEXT */
+# endif /* VLNEXT */
+# ifdef VSTATUS
+# if NUMCC <= VSTATUS
+# undef VSTATUS
+# endif /* NUMCC <= VSTATUS */
+# endif /* VSTATUS */
+# ifdef VPAGE
+# if NUMCC <= VPAGE
+# undef VPAGE
+# endif /* NUMCC <= VPAGE */
+# endif /* VPAGE */
+# ifdef VPGOFF
+# if NUMCC <= VPGOFF
+# undef VPGOFF
+# endif /* NUMCC <= VPGOFF */
+# endif /* VPGOFF */
+# ifdef VKILL2
+# if NUMCC <= VKILL2
+# undef VKILL2
+# endif /* NUMCC <= VKILL2 */
+# endif /* VKILL2 */
+# ifdef VBRK
+# if NUMCC <= VBRK
+# undef VBRK
+# endif /* NUMCC <= VBRK */
+# endif /* VBRK */
+# ifdef VMIN
+# if NUMCC <= VMIN
+# undef VMIN
+# endif /* NUMCC <= VMIN */
+# endif /* VMIN */
+# ifdef VTIME
+# if NUMCC <= VTIME
+# undef VTIME
+# endif /* NUMCC <= VTIME */
+# endif /* VTIME */
+# endif /* NUMCC */
+#endif /* !POSIX */
+
+#define C_INTR 0
+#define C_QUIT 1
+#define C_ERASE 2
+#define C_KILL 3
+#define C_EOF 4
+#define C_EOL 5
+#define C_EOL2 6
+#define C_SWTCH 7
+#define C_DSWTCH 8
+#define C_ERASE2 9
+#define C_START 10
+#define C_STOP 11
+#define C_WERASE 12
+#define C_SUSP 13
+#define C_DSUSP 14
+#define C_REPRINT 15
+#define C_DISCARD 16
+#define C_LNEXT 17
+#define C_STATUS 18
+#define C_PAGE 19
+#define C_PGOFF 20
+#define C_KILL2 21
+#define C_BRK 22
+#define C_MIN 23
+#define C_TIME 24
+#define C_NCC 25
+#define C_SH(A) (1 << (A))
+
+/*
+ * Terminal dependend data structures
+ */
+#define EX_IO 0 /* while we are executing */
+#define ED_IO 1 /* while we are editing */
+#define TS_IO 2 /* new mode from terminal */
+#define QU_IO 2 /* used only for quoted chars */
+#define NN_IO 3 /* The number of entries */
+
+#define M_INP 0
+#define M_OUT 1
+#define M_CTL 2
+#define M_LIN 3
+#define M_CHAR 4
+#define M_NN 5
+
+typedef struct {
+ char *t_name;
+ u_int t_setmask;
+ u_int t_clrmask;
+} ttyperm_t[NN_IO][M_NN];
+
+typedef unsigned char ttychar_t[NN_IO][C_NCC];
+
+protected int tty_init __P((EditLine *));
+protected void tty_end __P((EditLine *));
+protected int tty_stty __P((EditLine *, int, char**));
+protected int tty_rawmode __P((EditLine *));
+protected int tty_cookedmode __P((EditLine *));
+protected int tty_quotemode __P((EditLine *));
+protected int tty_noquotemode __P((EditLine *));
+protected void tty_bind_char __P((EditLine *, int));
+
+typedef struct {
+ ttyperm_t t_t;
+ ttychar_t t_c;
+ struct termios t_ex, t_ed, t_ts;
+ int t_tabs;
+ int t_eight;
+ speed_t t_speed;
+ int t_mode;
+ unsigned char t_vdisable;
+} el_tty_t;
+
+
+#endif /* _h_el_tty */
diff --git a/lib/libedit/vi.c b/lib/libedit/vi.c
new file mode 100644
index 0000000..5099757
--- /dev/null
+++ b/lib/libedit/vi.c
@@ -0,0 +1,1002 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(lint) && !defined(SCCSID)
+static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint && not SCCSID */
+
+/*
+ * vi.c: Vi mode commands.
+ */
+#include "sys.h"
+#include "el.h"
+
+private el_action_t cv_action __P((EditLine *, int));
+
+/* cv_action():
+ * Handle vi actions.
+ */
+private el_action_t
+cv_action(el, c)
+ EditLine *el;
+ int c;
+{
+ register char *cp, *kp;
+
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ el->el_chared.c_vcmd.action = NOP;
+ el->el_chared.c_vcmd.pos = 0;
+
+ el->el_chared.c_undo.isize = 0;
+ el->el_chared.c_undo.dsize = 0;
+ kp = el->el_chared.c_undo.buf;
+ for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) {
+ *kp++ = *cp;
+ el->el_chared.c_undo.dsize++;
+ }
+
+ el->el_chared.c_undo.action = INSERT;
+ el->el_chared.c_undo.ptr = el->el_line.buffer;
+ el->el_line.lastchar = el->el_line.buffer;
+ el->el_line.cursor = el->el_line.buffer;
+ if (c & INSERT)
+ el->el_map.current = el->el_map.key;
+
+ return CC_REFRESH;
+ }
+
+ el->el_chared.c_vcmd.pos = el->el_line.cursor;
+ el->el_chared.c_vcmd.action = c;
+ return CC_ARGHACK;
+
+#ifdef notdef
+ /*
+ * I don't think that this is needed. But we keep it for now
+ */
+ else if (el_chared.c_vcmd.action == NOP) {
+ el->el_chared.c_vcmd.pos = el->el_line.cursor;
+ el->el_chared.c_vcmd.action = c;
+ return CC_ARGHACK;
+ }
+ else {
+ el->el_chared.c_vcmd.action = 0;
+ el->el_chared.c_vcmd.pos = 0;
+ return CC_ERROR;
+ }
+#endif
+}
+
+
+/* cv_paste():
+ * Paste previous deletion before or after the cursor
+ */
+protected el_action_t
+cv_paste(el, c)
+ EditLine *el;
+ int c;
+{
+ char *ptr;
+ c_undo_t *un = &el->el_chared.c_undo;
+#ifdef DEBUG_PASTE
+ (void) fprintf(el->el_errfile, "Paste: %x \"%s\" +%d -%d\n",
+ un->action, un->buf, un->isize, un->dsize);
+#endif
+ if (un->isize == 0)
+ return CC_ERROR;
+
+ if (!c && el->el_line.cursor < el->el_line.lastchar)
+ el->el_line.cursor++;
+ ptr = el->el_line.cursor;
+
+ c_insert(el, un->isize);
+ if (el->el_line.cursor + un->isize > el->el_line.lastchar)
+ return CC_ERROR;
+ (void) memcpy(ptr, un->buf, un->isize);
+ return CC_REFRESH;
+}
+
+
+/* vi_paste_next():
+ * Vi paste previous deletion to the right of the cursor
+ * [p]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_paste_next(el, c)
+ EditLine *el;
+ int c;
+{
+ return cv_paste(el, 0);
+}
+
+
+/* vi_paste_prev():
+ * Vi paste previous deletion to the left of the cursor
+ * [P]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_paste_prev(el, c)
+ EditLine *el;
+ int c;
+{
+ return cv_paste(el, 1);
+}
+
+
+/* vi_prev_space_word():
+ * Vi move to the previous space delimited word
+ * [B]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_prev_space_word(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor == el->el_line.buffer)
+ return CC_ERROR;
+
+ el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
+ el->el_line.buffer,
+ el->el_state.argument,
+ c___isword);
+
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+
+ return CC_CURSOR;
+}
+
+
+/* vi_prev_word():
+ * Vi move to the previous word
+ * [b]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_prev_word(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor == el->el_line.buffer)
+ return CC_ERROR;
+
+ el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
+ el->el_line.buffer,
+ el->el_state.argument,
+ cv__isword);
+
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+
+ return CC_CURSOR;
+}
+
+
+/* vi_next_space_word():
+ * Vi move to the next space delimited word
+ * [W]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_next_space_word(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor == el->el_line.lastchar)
+ return CC_ERROR;
+
+ el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
+ el->el_line.lastchar,
+ el->el_state.argument,
+ c___isword);
+
+ if (el->el_map.type == MAP_VI)
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+
+ return CC_CURSOR;
+}
+
+/* vi_next_word():
+ * Vi move to the next word
+ * [w]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_next_word(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor == el->el_line.lastchar)
+ return CC_ERROR;
+
+ el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
+ el->el_line.lastchar,
+ el->el_state.argument,
+ cv__isword);
+
+ if (el->el_map.type == MAP_VI)
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+
+ return CC_CURSOR;
+}
+
+
+
+/* vi_change_case():
+ * Vi change case of character under the cursor and advance one character
+ * [~]
+ */
+protected el_action_t
+vi_change_case(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor < el->el_line.lastchar) {
+ c = (unsigned char)*el->el_line.cursor;
+ if (isupper(c))
+ *el->el_line.cursor++ = tolower(c);
+ else if (islower(c))
+ *el->el_line.cursor++ = toupper(c);
+ else
+ el->el_line.cursor++;
+ re_fastaddc(el);
+ return CC_NORM;
+ }
+ return CC_ERROR;
+}
+
+
+/* vi_change_meta():
+ * Vi change prefix command
+ * [c]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_change_meta(el, c)
+ EditLine *el;
+ int c;
+{
+ /*
+ * Delete with insert == change: first we delete and then we leave in
+ * insert mode.
+ */
+ return cv_action(el, DELETE|INSERT);
+}
+
+
+/* vi_insert_at_bol():
+ * Vi enter insert mode at the beginning of line
+ * [I]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_insert_at_bol(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_line.cursor = el->el_line.buffer;
+ el->el_chared.c_vcmd.ins = el->el_line.cursor;
+
+ el->el_chared.c_undo.ptr = el->el_line.cursor;
+ el->el_chared.c_undo.action = DELETE;
+
+ el->el_map.current = el->el_map.key;
+ return CC_CURSOR;
+}
+
+
+/* vi_replace_char():
+ * Vi replace character under the cursor with the next character typed
+ * [r]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_replace_char(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_map.current = el->el_map.key;
+ el->el_state.inputmode = MODE_REPLACE_1;
+ el->el_chared.c_undo.action = CHANGE;
+ el->el_chared.c_undo.ptr = el->el_line.cursor;
+ el->el_chared.c_undo.isize = 0;
+ el->el_chared.c_undo.dsize = 0;
+ return CC_ARGHACK;
+}
+
+
+/* vi_replace_mode():
+ * Vi enter replace mode
+ * [R]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_replace_mode(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_map.current = el->el_map.key;
+ el->el_state.inputmode = MODE_REPLACE;
+ el->el_chared.c_undo.action = CHANGE;
+ el->el_chared.c_undo.ptr = el->el_line.cursor;
+ el->el_chared.c_undo.isize = 0;
+ el->el_chared.c_undo.dsize = 0;
+ return CC_ARGHACK;
+}
+
+
+/* vi_substitute_char():
+ * Vi replace character under the cursor and enter insert mode
+ * [s]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_substitute_char(el, c)
+ EditLine *el;
+ int c;
+{
+ c_delafter(el, el->el_state.argument);
+ el->el_map.current = el->el_map.key;
+ return CC_REFRESH;
+}
+
+
+/* vi_substitute_line():
+ * Vi substitute entire line
+ * [S]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_substitute_line(el, c)
+ EditLine *el;
+ int c;
+{
+ (void) em_kill_line(el, 0);
+ el->el_map.current = el->el_map.key;
+ return CC_REFRESH;
+}
+
+
+/* vi_change_to_eol():
+ * Vi change to end of line
+ * [C]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_change_to_eol(el, c)
+ EditLine *el;
+ int c;
+{
+ (void) ed_kill_line(el, 0);
+ el->el_map.current = el->el_map.key;
+ return CC_REFRESH;
+}
+
+
+/* vi_insert():
+ * Vi enter insert mode
+ * [i]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_insert(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_map.current = el->el_map.key;
+
+ el->el_chared.c_vcmd.ins = el->el_line.cursor;
+ el->el_chared.c_undo.ptr = el->el_line.cursor;
+ el->el_chared.c_undo.action = DELETE;
+
+ return CC_NORM;
+}
+
+
+/* vi_add():
+ * Vi enter insert mode after the cursor
+ * [a]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_add(el, c)
+ EditLine *el;
+ int c;
+{
+ el_action_t ret;
+
+ el->el_map.current = el->el_map.key;
+ if (el->el_line.cursor < el->el_line.lastchar) {
+ el->el_line.cursor++;
+ if (el->el_line.cursor > el->el_line.lastchar)
+ el->el_line.cursor = el->el_line.lastchar;
+ ret = CC_CURSOR;
+ }
+ else
+ ret = CC_NORM;
+
+ el->el_chared.c_vcmd.ins = el->el_line.cursor;
+ el->el_chared.c_undo.ptr = el->el_line.cursor;
+ el->el_chared.c_undo.action = DELETE;
+
+ return ret;
+}
+
+
+/* vi_add_at_eol():
+ * Vi enter insert mode at end of line
+ * [A]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_add_at_eol(el, c)
+ EditLine *el;
+ int c;
+{
+ el->el_map.current = el->el_map.key;
+ el->el_line.cursor = el->el_line.lastchar;
+
+ /* Mark where insertion begins */
+ el->el_chared.c_vcmd.ins = el->el_line.lastchar;
+ el->el_chared.c_undo.ptr = el->el_line.lastchar;
+ el->el_chared.c_undo.action = DELETE;
+ return CC_CURSOR;
+}
+
+
+/* vi_delete_meta():
+ * Vi delete prefix command
+ * [d]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_delete_meta(el, c)
+ EditLine *el;
+ int c;
+{
+ return cv_action(el, DELETE);
+}
+
+
+/* vi_end_word():
+ * Vi move to the end of the current space delimited word
+ * [E]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_end_word(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor == el->el_line.lastchar)
+ return CC_ERROR;
+
+ el->el_line.cursor = cv__endword(el->el_line.cursor, el->el_line.lastchar,
+ el->el_state.argument);
+
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ el->el_line.cursor++;
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+
+ return CC_CURSOR;
+}
+
+
+/* vi_to_end_word():
+ * Vi move to the end of the current word
+ * [e]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_to_end_word(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_line.cursor == el->el_line.lastchar)
+ return CC_ERROR;
+
+ el->el_line.cursor = cv__endword(el->el_line.cursor, el->el_line.lastchar,
+ el->el_state.argument);
+
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ el->el_line.cursor++;
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+
+ return CC_CURSOR;
+}
+
+
+/* vi_undo():
+ * Vi undo last change
+ * [u]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_undo(el, c)
+ EditLine *el;
+ int c;
+{
+ char *cp, *kp;
+ char temp;
+ int i, size;
+ c_undo_t *un = &el->el_chared.c_undo;
+
+#ifdef DEBUG_UNDO
+ (void) fprintf(el->el_errfile, "Undo: %x \"%s\" +%d -%d\n",
+ un->action, un->buf, un->isize, un->dsize);
+#endif
+ switch (un->action) {
+ case DELETE:
+ if (un->dsize == 0)
+ return CC_NORM;
+
+ (void) memcpy(un->buf, un->ptr, un->dsize);
+ for (cp = un->ptr; cp <= el->el_line.lastchar; cp++)
+ *cp = cp[un->dsize];
+
+ el->el_line.lastchar -= un->dsize;
+ el->el_line.cursor = un->ptr;
+
+ un->action = INSERT;
+ un->isize = un->dsize;
+ un->dsize = 0;
+ break;
+
+ case DELETE|INSERT:
+ size = un->isize - un->dsize;
+ if (size > 0)
+ i = un->dsize;
+ else
+ i = un->isize;
+ cp = un->ptr;
+ kp = un->buf;
+ while (i-- > 0) {
+ temp = *kp;
+ *kp++ = *cp;
+ *cp++ = temp;
+ }
+ if (size > 0) {
+ el->el_line.cursor = cp;
+ c_insert(el, size);
+ while (size-- > 0 && cp < el->el_line.lastchar) {
+ temp = *kp;
+ *kp++ = *cp;
+ *cp++ = temp;
+ }
+ }
+ else if (size < 0) {
+ size = -size;
+ for (; cp <= el->el_line.lastchar; cp++) {
+ *kp++ = *cp;
+ *cp = cp[size];
+ }
+ el->el_line.lastchar -= size;
+ }
+ el->el_line.cursor = un->ptr;
+ i = un->dsize;
+ un->dsize = un->isize;
+ un->isize = i;
+ break;
+
+ case INSERT:
+ if (un->isize == 0)
+ return CC_NORM;
+
+ el->el_line.cursor = un->ptr;
+ c_insert(el, un->isize);
+ memcpy(un->ptr, un->buf, un->isize);
+ un->action = DELETE;
+ un->dsize = un->isize;
+ un->isize = 0;
+ break;
+
+ case CHANGE:
+ if (un->isize == 0)
+ return CC_NORM;
+
+ el->el_line.cursor = un->ptr;
+ size = (int) (el->el_line.cursor - el->el_line.lastchar);
+ if (size < un->isize)
+ size = un->isize;
+ cp = un->ptr;
+ kp = un->buf;
+ for(i = 0; i < size; i++) {
+ temp = *kp;
+ *kp++ = *cp;
+ *cp++ = temp;
+ }
+ un->dsize = 0;
+ break;
+
+ default:
+ return CC_ERROR;
+ }
+
+ return CC_REFRESH;
+}
+
+
+/* vi_undo_line():
+ * Vi undo all changes
+ * [U]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_undo_line(el, c)
+ EditLine *el;
+ int c;
+{
+
+ return hist_get(el);
+}
+
+
+/* vi_command_mode():
+ * Vi enter command mode (use alternative key bindings)
+ * [<ESC>]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_command_mode(el, c)
+ EditLine *el;
+ int c;
+{
+ int size;
+ /* [Esc] cancels pending action */
+ el->el_chared.c_vcmd.ins = 0;
+ el->el_chared.c_vcmd.action = NOP;
+ el->el_chared.c_vcmd.pos = 0;
+
+ el->el_state.doingarg = 0;
+ size = el->el_chared.c_undo.ptr - el->el_line.cursor;
+ if (size < 0)
+ size = -size;
+ if (el->el_chared.c_undo.action == (INSERT|DELETE) ||
+ el->el_chared.c_undo.action == DELETE)
+ el->el_chared.c_undo.dsize = size;
+ else
+ el->el_chared.c_undo.isize = size;
+
+ el->el_state.inputmode = MODE_INSERT;
+ el->el_map.current = el->el_map.alt;
+#ifdef VI_MOVE
+ if (el->el_line.cursor > el->el_line.buffer)
+ el->el_line.cursor--;
+#endif
+ return CC_CURSOR;
+}
+
+/* vi_zero():
+ * Vi move to the beginning of line
+ * [0]
+ */
+protected el_action_t
+vi_zero(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_state.doingarg) {
+ if (el->el_state.argument > 1000000)
+ return CC_ERROR;
+ el->el_state.argument =
+ (el->el_state.argument * 10) + (c - '0');
+ return CC_ARGHACK;
+ }
+ else {
+ el->el_line.cursor = el->el_line.buffer;
+ if (el->el_chared.c_vcmd.action & DELETE) {
+ cv_delfini(el);
+ return CC_REFRESH;
+ }
+ return CC_CURSOR;
+ }
+}
+
+
+/* vi_delete_prev_char():
+ * Vi move to previous character (backspace)
+ * [^H]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_delete_prev_char(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_chared.c_vcmd.ins == 0)
+ return CC_ERROR;
+
+ if (el->el_chared.c_vcmd.ins >
+ el->el_line.cursor - el->el_state.argument)
+ return CC_ERROR;
+
+ c_delbefore(el, el->el_state.argument);
+ el->el_line.cursor -= el->el_state.argument;
+
+ return CC_REFRESH;
+} /* end v_del_char_prev */
+
+
+/* vi_list_or_eof():
+ * Vi list choices for completion or indicate end of file if empty line
+ * [^D]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_list_or_eof(el, c)
+ EditLine *el;
+ int c;
+{
+#ifdef notyet
+ if (el->el_line.cursor == el->el_line.lastchar &&
+ el->el_line.cursor == el->el_line.buffer) {
+#endif
+ term_overwrite(el, STReof, 4); /* then do a EOF */
+ term__flush();
+ return CC_EOF;
+#ifdef notyet
+ }
+ else {
+ re_goto_bottom(el);
+ *el->el_line.lastchar = '\0'; /* just in case */
+ return CC_LIST_CHOICES;
+ }
+#endif
+}
+
+
+/* vi_kill_line_prev():
+ * Vi cut from beginning of line to cursor
+ * [^U]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_kill_line_prev(el, c)
+ EditLine *el;
+ int c;
+{
+ char *kp, *cp;
+
+ cp = el->el_line.buffer;
+ kp = el->el_chared.c_kill.buf;
+ while (cp < el->el_line.cursor)
+ *kp++ = *cp++; /* copy it */
+ el->el_chared.c_kill.last = kp;
+ c_delbefore(el, el->el_line.cursor - el->el_line.buffer);
+ el->el_line.cursor = el->el_line.buffer; /* zap! */
+ return CC_REFRESH;
+}
+
+
+/* vi_search_prev():
+ * Vi search history previous
+ * [?]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_search_prev(el, c)
+ EditLine *el;
+ int c;
+{
+ return cv_search(el, ED_SEARCH_PREV_HISTORY);
+}
+
+
+/* vi_search_next():
+ * Vi search history next
+ * [/]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_search_next(el, c)
+ EditLine *el;
+ int c;
+{
+ return cv_search(el, ED_SEARCH_NEXT_HISTORY);
+}
+
+
+/* vi_repeat_search_next():
+ * Vi repeat current search in the same search direction
+ * [n]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_repeat_search_next(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_search.patlen == 0)
+ return CC_ERROR;
+ else
+ return cv_repeat_srch(el, el->el_search.patdir);
+}
+
+
+/* vi_repeat_search_prev():
+ * Vi repeat current search in the opposite search direction
+ * [N]
+ */
+/*ARGSUSED*/
+protected el_action_t
+vi_repeat_search_prev(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_search.patlen == 0)
+ return CC_ERROR;
+ else
+ return cv_repeat_srch(el,
+ el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
+ ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY);
+}
+
+
+/* vi_next_char():
+ * Vi move to the character specified next
+ * [f]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_next_char(el, c)
+ EditLine *el;
+ int c;
+{
+ char ch;
+
+ if (el_getc(el, &ch) != 1)
+ return ed_end_of_file(el, 0);
+
+ el->el_search.chadir = CHAR_FWD;
+ el->el_search.chacha = ch;
+
+ return cv_csearch_fwd(el, ch, el->el_state.argument, 0);
+
+}
+
+
+/* vi_prev_char():
+ * Vi move to the character specified previous
+ * [F]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_prev_char(el, c)
+ EditLine *el;
+ int c;
+{
+ char ch;
+
+ if (el_getc(el, &ch) != 1)
+ return ed_end_of_file(el, 0);
+
+ el->el_search.chadir = CHAR_BACK;
+ el->el_search.chacha = ch;
+
+ return cv_csearch_back(el, ch, el->el_state.argument, 0);
+}
+
+
+/* vi_to_next_char():
+ * Vi move up to the character specified next
+ * [t]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_to_next_char(el, c)
+ EditLine *el;
+ int c;
+{
+ char ch;
+
+ if (el_getc(el, &ch) != 1)
+ return ed_end_of_file(el, 0);
+
+ return cv_csearch_fwd(el, ch, el->el_state.argument, 1);
+
+}
+
+
+/* vi_to_prev_char():
+ * Vi move up to the character specified previous
+ * [T]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_to_prev_char(el, c)
+ EditLine *el;
+ int c;
+{
+ char ch;
+ if (el_getc(el, &ch) != 1)
+ return ed_end_of_file(el, 0);
+
+ return cv_csearch_back(el, ch, el->el_state.argument, 1);
+}
+
+
+/* vi_repeat_next_char():
+ * Vi repeat current character search in the same search direction
+ * [;]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_repeat_next_char(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_search.chacha == 0)
+ return CC_ERROR;
+
+ return el->el_search.chadir == CHAR_FWD ?
+ cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) :
+ cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0);
+}
+
+
+/* vi_repeat_prev_char():
+ * Vi repeat current character search in the opposite search direction
+ * [,]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_repeat_prev_char(el, c)
+ EditLine *el;
+ int c;
+{
+ if (el->el_search.chacha == 0)
+ return CC_ERROR;
+
+ return el->el_search.chadir == CHAR_BACK ?
+ cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) :
+ cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0);
+}
diff --git a/lib/libfetch/Makefile b/lib/libfetch/Makefile
new file mode 100644
index 0000000..f40f2b6
--- /dev/null
+++ b/lib/libfetch/Makefile
@@ -0,0 +1,51 @@
+# $FreeBSD$
+
+MAINTAINER= des@freebsd.org
+LIB= fetch
+CFLAGS+= -I. -Wall -pedantic
+.if !defined(DEBUG)
+CFLAGS+= -DNDEBUG
+.endif
+SRCS= fetch.c common.c ftp.c http.c file.c fetch_err.c \
+ fetch_err.h ftperr.h httperr.h
+MAN3= fetch.3
+CLEANFILES= fetch_err.c fetch_err.h ftperr.h httperr.h
+
+SHLIB_MAJOR= 1
+SHLIB_MINOR= 0
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/fetch.h \
+ ${DESTDIR}/usr/include
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 fetch_err.h \
+ ${DESTDIR}/usr/include
+
+ftperr.h: ftp.errors
+ @echo "static struct fetcherr _ftp_errlist[] = {" > ${.TARGET}
+ @cat ${.ALLSRC} \
+ | grep -v ^# \
+ | sort \
+ | while read NUM CAT STRING; do \
+ echo " { $${NUM}, FETCH_$${CAT}, \"$${STRING}\" },"; \
+ done >> ${.TARGET}
+ @echo " { -1, FETCH_UNKNOWN, \"Unknown FTP error\" }" >> ${.TARGET}
+ @echo "};" >> ${.TARGET}
+
+httperr.h: http.errors
+ @echo "static struct fetcherr _http_errlist[] = {" > ${.TARGET}
+ @cat ${.ALLSRC} \
+ | grep -v ^# \
+ | sort \
+ | while read NUM CAT STRING; do \
+ echo " { $${NUM}, FETCH_$${CAT}, \"$${STRING}\" },"; \
+ done >> ${.TARGET}
+ @echo " { -1, FETCH_UNKNOWN, \"Unknown HTTP error\" }" >> ${.TARGET}
+ @echo "};" >> ${.TARGET}
+
+hdrs: fetch_err.h
+
+.ORDER: fetch_err.c fetch_err.h
+fetch_err.c fetch_err.h: fetch_err.et
+ compile_et ${.ALLSRC}
+
+.include <bsd.lib.mk>
diff --git a/lib/libfetch/README b/lib/libfetch/README
new file mode 100644
index 0000000..7b85376
--- /dev/null
+++ b/lib/libfetch/README
@@ -0,0 +1,10 @@
+This is the new fetch(3) library, which is to replace the ftpio(3)
+library and provide a new, unified backend for all fetch(1),
+pkg_add(1) and sysinstall(8).
+
+Note that this is very much work in progress. It compiles (with a few
+warnings), but there is much left to be implemented. Comments, patches
+etc. of all kinds are welcome, but please don't commit anything
+without talking to me first.
+
+ -- Dag-Erling C. Smørgrav (des@FreeBSD.org)
diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c
new file mode 100644
index 0000000..8b3b891
--- /dev/null
+++ b/lib/libfetch/common.c
@@ -0,0 +1,284 @@
+/*-
+ * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <com_err.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "fetch.h"
+#include "common.h"
+
+
+/*** Local data **************************************************************/
+
+/*
+ * Error messages for resolver errors
+ */
+static struct fetcherr _netdb_errlist[] = {
+ { HOST_NOT_FOUND, FETCH_RESOLV, "Host not found" },
+ { TRY_AGAIN, FETCH_TEMP, "Transient resolver failure" },
+ { NO_RECOVERY, FETCH_RESOLV, "Non-recoverable resolver failure" },
+ { NO_DATA, FETCH_RESOLV, "No address record" },
+ { -1, FETCH_UNKNOWN, "Unknown resolver error" }
+};
+
+static int com_err_initialized;
+
+/*** Error-reporting functions ***********************************************/
+
+/*
+ * Initialize the common error library
+ */
+static void
+_fetch_init_com_err(void)
+{
+ initialize_ftch_error_table();
+ com_err_initialized = 1;
+}
+
+/*
+ * Map error code to string
+ */
+static int
+_fetch_finderr(struct fetcherr *p, int e)
+{
+ int i;
+ for (i = 0; p[i].num != -1; i++)
+ if (p[i].num == e)
+ break;
+ return i;
+}
+
+/*
+ * Set error code
+ */
+void
+_fetch_seterr(struct fetcherr *p, int e)
+{
+ int n;
+
+ if (!com_err_initialized)
+ _fetch_init_com_err();
+
+ n = _fetch_finderr(p, e);
+ fetchLastErrCode = p[n].cat;
+ com_err("libfetch", fetchLastErrCode, "(%03d %s)", e, p[n].string);
+}
+
+/*
+ * Set error code according to errno
+ */
+void
+_fetch_syserr(void)
+{
+ int e;
+ e = errno;
+
+ if (!com_err_initialized)
+ _fetch_init_com_err();
+
+ switch (errno) {
+ case 0:
+ fetchLastErrCode = FETCH_OK;
+ break;
+ case EPERM:
+ case EACCES:
+ case EROFS:
+ case EAUTH:
+ case ENEEDAUTH:
+ fetchLastErrCode = FETCH_AUTH;
+ break;
+ case ENOENT:
+ case EISDIR: /* XXX */
+ fetchLastErrCode = FETCH_UNAVAIL;
+ break;
+ case ENOMEM:
+ fetchLastErrCode = FETCH_MEMORY;
+ break;
+ case EBUSY:
+ case EAGAIN:
+ fetchLastErrCode = FETCH_TEMP;
+ break;
+ case EEXIST:
+ fetchLastErrCode = FETCH_EXISTS;
+ break;
+ case ENOSPC:
+ fetchLastErrCode = FETCH_FULL;
+ break;
+ case EADDRINUSE:
+ case EADDRNOTAVAIL:
+ case ENETDOWN:
+ case ENETUNREACH:
+ case ENETRESET:
+ case EHOSTUNREACH:
+ fetchLastErrCode = FETCH_NETWORK;
+ break;
+ case ECONNABORTED:
+ case ECONNRESET:
+ fetchLastErrCode = FETCH_ABORT;
+ break;
+ case ETIMEDOUT:
+ fetchLastErrCode = FETCH_TIMEOUT;
+ break;
+ case ECONNREFUSED:
+ case EHOSTDOWN:
+ fetchLastErrCode = FETCH_DOWN;
+ break;
+ default:
+ fetchLastErrCode = FETCH_UNKNOWN;
+ }
+ com_err("libfetch", fetchLastErrCode, "(%03d %s)", e, strerror(e));
+}
+
+
+/*
+ * Emit status message
+ */
+int
+_fetch_info(char *fmt, ...)
+{
+ va_list ap;
+ char *s;
+
+ if (!com_err_initialized)
+ _fetch_init_com_err();
+
+ va_start(ap, fmt);
+ vasprintf(&s, fmt, ap);
+ va_end(ap);
+
+ if (s == NULL) {
+ com_err("libfetch", FETCH_MEMORY, "");
+ return -1;
+ } else {
+ com_err("libfetch", FETCH_VERBOSE, "%s", s);
+ free(s);
+ return 0;
+ }
+}
+
+
+/*** Network-related utility functions ***************************************/
+
+/*
+ * Establish a TCP connection to the specified port on the specified host.
+ */
+int
+_fetch_connect(char *host, int port, int verbose)
+{
+ struct sockaddr_in sin;
+ struct hostent *he;
+ int sd;
+
+#ifndef NDEBUG
+ fprintf(stderr, "\033[1m---> %s:%d\033[m\n", host, port);
+#endif
+
+ if (verbose)
+ _fetch_info("looking up %s", host);
+
+ /* look up host name */
+ if ((he = gethostbyname(host)) == NULL) {
+ _netdb_seterr(h_errno);
+ return -1;
+ }
+
+ if (verbose)
+ _fetch_info("connecting to %s:%d", host, port);
+
+ /* set up socket address structure */
+ bzero(&sin, sizeof(sin));
+ bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length);
+ sin.sin_family = he->h_addrtype;
+ sin.sin_port = htons(port);
+
+ /* try to connect */
+ if ((sd = socket(sin.sin_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+ _fetch_syserr();
+ return -1;
+ }
+ if (connect(sd, (struct sockaddr *)&sin, sizeof sin) == -1) {
+ _fetch_syserr();
+ close(sd);
+ return -1;
+ }
+
+ return sd;
+}
+
+
+/*** Directory-related utility functions *************************************/
+
+int
+_fetch_add_entry(struct url_ent **p, int *size, int *len,
+ char *name, struct url_stat *stat)
+{
+ struct url_ent *tmp;
+
+ if (*p == NULL) {
+#define INITIAL_SIZE 8
+ if ((*p = malloc(INITIAL_SIZE * sizeof **p)) == NULL) {
+ errno = ENOMEM;
+ _fetch_syserr();
+ return -1;
+ }
+ *size = INITIAL_SIZE;
+ *len = 0;
+#undef INITIAL_SIZE
+ }
+
+ if (*len >= *size - 1) {
+ tmp = realloc(*p, *size * 2 * sizeof **p);
+ if (tmp == NULL) {
+ errno = ENOMEM;
+ _fetch_syserr();
+ return -1;
+ }
+ *size *= 2;
+ *p = tmp;
+ }
+
+ tmp = *p + *len;
+ snprintf(tmp->name, MAXPATHLEN, "%s", name);
+ bcopy(stat, &tmp->stat, sizeof *stat);
+
+ (*len)++;
+ (++tmp)->name[0] = 0;
+
+ return 0;
+}
diff --git a/lib/libfetch/common.h b/lib/libfetch/common.h
new file mode 100644
index 0000000..aa2059c
--- /dev/null
+++ b/lib/libfetch/common.h
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _COMMON_H_INCLUDED
+#define _COMMON_H_INCLUDED
+
+/* Structure used for error message lists */
+#define ERRCAT_
+struct fetcherr {
+ const int num, cat;
+ const char *string;
+};
+
+void _fetch_seterr(struct fetcherr *, int);
+void _fetch_syserr(void);
+int _fetch_info(char *fmt, ...);
+int _fetch_connect(char *, int, int);
+int _fetch_add_entry(struct url_ent **p, int *size, int *len,
+ char *name, struct url_stat *stat);
+
+#define _ftp_seterr(n) _fetch_seterr(_ftp_errlist, n)
+#define _http_seterr(n) _fetch_seterr(_http_errlist, n)
+#define _netdb_seterr(n) _fetch_seterr(_netdb_errlist, n)
+#define _url_seterr(n) _fetch_seterr(_url_errlist, n)
+
+#ifndef NDEBUG
+#define DEBUG(x) do x; while (0)
+#else
+#define DEBUG(x) do { } while (0)
+#endif
+
+#endif
diff --git a/lib/libfetch/fetch.3 b/lib/libfetch/fetch.3
new file mode 100644
index 0000000..dd0849a
--- /dev/null
+++ b/lib/libfetch/fetch.3
@@ -0,0 +1,406 @@
+.\" Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 1, 1998
+.Dt FETCH 3
+.Os
+.Sh NAME
+.Nm fetchGetURL ,
+.Nm fetchPutURL ,
+.Nm fetchStatURL ,
+.Nm fetchListURL ,
+.Nm fetchParseURL ,
+.Nm fetchGet ,
+.Nm fetchPut ,
+.Nm fetchStat ,
+.Nm fetchList ,
+.Nm fetchGetFile ,
+.Nm fetchPutFile ,
+.Nm fetchStatFile ,
+.Nm fetchListFile ,
+.Nm fetchGetHTTP ,
+.Nm fetchPutHTTP ,
+.Nm fetchStatHTTP ,
+.Nm fetchListHTTP ,
+.Nm fetchGetFTP ,
+.Nm fetchPutFTP
+.Nm fetchStatFTP
+.Nm fetchListFTP ,
+.Nd file transfer library
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Fd #include <stdio.h>
+.Fd #include <fetch.h>
+.Ft FILE *
+.Fn fetchGetURL "char *URL" "char *flags"
+.Ft FILE *
+.Fn fetchPutURL "char *URL" "char *flags"
+.Ft int
+.Fn fetchStatURL "char *URL" "struct url_stat *us" "char *flags"
+.Ft struct url_ent *
+.Fn fetchListURL "char *URL" "char *flags"
+.Ft struct url *
+.Fn fetchParseURL "char *URL"
+.Ft FILE *
+.Fn fetchGet "struct url *URL" "char *flags"
+.Ft FILE *
+.Fn fetchPut "struct url *URL" "char *flags"
+.Ft int
+.Fn fetchStat "struct url *URL" "struct url_stat *us" "char *flags"
+.Ft struct url_ent *
+.Fn fetchList "struct url *" "char *flags"
+.Ft FILE *
+.Fn fetchGetFile "struct url *u" "char *flags"
+.Ft FILE *
+.Fn fetchPutFile "struct url *u" "char *flags"
+.Ft int
+.Fn fetchStatFile "struct url *URL" "struct url_stat *us" "char *flags"
+.Ft struct url_ent *
+.Fn fetchListFile "struct url *" "char *flags"
+.Ft FILE *
+.Fn fetchGetHTTP "struct url *u" "char *flags"
+.Ft FILE *
+.Fn fetchPutHTTP "struct url *u" "char *flags"
+.Ft int
+.Fn fetchStatHTTP "struct url *URL" "struct url_stat *us" "char *flags"
+.Ft struct url_ent *
+.Fn fetchListHTTP "struct url *" "char *flags"
+.Ft FILE *
+.Fn fetchGetFTP "struct url *u" "char *flags"
+.Ft FILE *
+.Fn fetchPutFTP "struct url *u" "char *flags"
+.Ft int
+.Fn fetchStatFTP "struct url *URL" "struct url_stat *us" "char *flags"
+.Ft struct url_ent *
+.Fn fetchListFTP "struct url *" "char *flags"
+.Sh DESCRIPTION
+.Pp
+These functions implement a high-level library for retrieving and
+uploading files using Uniform Resource Locators (URLs).
+.Pp
+.Fn fetchGetURL
+and
+.Fn fetchPutURL
+constitute the recommended interface to the
+.Nm fetch
+library. They examine the URL passed to them to determine the transfer
+method, and call the appropriate lower-level functions to perform the
+actual transfer. The
+.Fa flags
+argument is a string of characters which specify transfer options. The
+meaning of the individual flags is scheme-dependent, and is detailed
+in the appropriate section below.
+.Pp
+.Fn fetchStatURL
+attempts to obtain the requested document's metadata and fill in the
+structure pointed to by it's second argument. The
+.Fa url_stat
+structure is defined as follows in
+.Aq Pa fetch.h :
+.Bd -literal
+struct url_stat {
+ off_t size;
+ time_t atime;
+ time_t mtime;
+};
+.Ed
+.Pp
+.Fn fetchListURL
+attempts to list the contents of the directory pointed to by the URL
+provided. If successful, it returns a malloced array of
+.Fa url_ent
+structures. The
+.Fa url_ent
+structure is defined as follows in
+.Aq Pa fetch.h :
+.Bd -literal
+struct url_ent {
+ char name[MAXPATHLEN];
+ struct url_stat stat;
+};
+.Ed
+.Pp
+The list is terminated by an entry with an empty name.
+.Pp
+The pointer returned by
+.Fn fetchListURL
+should be freed using
+.Fn free .
+.Pp
+.Fn fetchParseURL
+takes a URL in the form of a null-terminated string and splits it into
+its components function according to the Common Internet Scheme Syntax
+detailed in RFC1738. A regular expression which produces this syntax
+is:
+.Bd -literal
+ <scheme>:(//(<user>(:<pwd>)?@)?<host>(:<port>)?)?/(<document>)?
+.Ed
+.Pp
+Note that some components of the URL are not necessarily relevant to
+all URL schemes. For instance, the file scheme only needs the <scheme>
+and <document> components.
+.Pp
+The pointer returned by
+.Fn fetchParseURL
+should be freed using
+.Fn free .
+.Pp
+.Fn fetchGet ,
+.Fn fetchPut
+and
+.Fn fetchStat
+are similar to
+.Fn fetchGetURL ,
+.Fn fetchPutURL
+and
+.Fn fetchStatURL ,
+except that they expect a pre-parsed URL in the form of a pointer to
+a
+.Fa struct url
+rather than a string.
+.Pp
+All of the
+.Fn fetchGetXXX
+and
+.Fn fetchPutXXX
+functions return a pointer to a stream which can be used to read or
+write data from or to the requested document, respectively. Note that
+although the implementation details of the individual access methods
+vary, it can generally be assumed that a stream returned by one of the
+.Fn fetchGetXXX
+functions is read-only, and that a stream returned by one of the
+.Fn fetchPutXXX
+functions is write-only.
+.Sh FILE SCHEME
+.Fn fetchGetFile
+and
+.Fn fetchPutFile
+provide access to documents which are files in a locally mounted file
+system. Only the <document> component of the URL is used.
+.Pp
+.Fn fetchGetFile
+does not accept any flags.
+.Pp
+.Fn fetchPutFile
+accepts the
+.Fa a
+(append to file) flag. If that flag is specified, the data written to
+the stream returned by
+.Fn fetchPutFile
+will be appended to the previous contents of the file, instead of
+replacing them.
+.Sh FTP SCHEME
+.Fn fetchGetFTP
+and
+.Fn fetchPutFTP
+implement the FTP protocol as described in RFC959.
+.Pp
+If the
+.Fa p
+(passive) flag is specified, a passive (rather than active) connection
+will be attempted.
+.Pp
+If no user name or password is given, the
+.Nm fetch
+library will attempt an anonymous login, with user name "ftp" and
+password "ftp".
+.Sh HTTP SCHEME
+The
+.Fn fetchGetHTTP
+and
+.Fn fetchPutHTTP
+functions implement the HTTP/1.1 protocol. With a little luck, there's
+even a chance that they comply with RFC2068.
+.Pp
+Since there seems to be no good way of implementing the HTTP PUT
+method in a manner consistent with the rest of the
+.Nm fetch
+library,
+.Fn fetchPutHTTP
+is currently unimplemented.
+.Sh RETURN VALUES
+.Fn fetchParseURL
+returns a pointer to a
+.Fa struct url
+containing the individual components of the URL. If it is
+unable to allocate memory, or the URL is syntactically incorrect,
+.Fn fetchParseURL
+returns a NULL pointer.
+.Pp
+The
+.Fn fetchStat
+functions return 0 on success and -1 on failure.
+.Pp
+All other functions return a stream pointer which may be used to
+access the requested document, or NULL if an error occurred.
+.Pp
+.Nm Libfetch
+uses the Common Error Library
+.Nm ( libcom_err )
+to report errors. The error code passed to
+.Fn com_err
+is one of:
+.Bl -tag -width Er
+.It Bq Er FETCH_ABORT
+Operation aborted
+.It Bq Er FETCH_AUTH
+Authentication failed
+.It Bq Er FETCH_DOWN
+Service unavailable
+.It Bq Er FETCH_EXISTS
+File exists
+.It Bq Er FETCH_FULL
+File system full
+.It Bq Er FETCH_INFO
+Informational response
+.It Bq Er FETCH_MEMORY
+Insufficient memory
+.It Bq Er FETCH_MOVED
+File has moved
+.It Bq Er FETCH_NETWORK
+Network error
+.It Bq Er FETCH_OK
+No error
+.It Bq Er FETCH_PROTO
+Protocol error
+.It Bq Er FETCH_RESOLV
+Resolver error
+.It Bq Er FETCH_SERVER
+Server error
+.It Bq Er FETCH_TEMP
+Temporary error
+.It Bq Er FETCH_TIMEOUT
+Operation timed out
+.It Bq Er FETCH_UNAVAIL
+File is not available
+.It Bq Er FETCH_UNKNOWN
+Unknown error
+.It Bq Er FETCH_URL
+Invalid URL
+.El
+.Pp
+The accompanying error message includes a protocol-specific error code
+and message, e.g. "File is not available (404 Not Found)"
+.Sh ENVIRONMENT
+The FTP and HTTP related functions use the
+.Ev HTTP_PROXY
+and
+.Ev FTP_PROXY
+environment variables, respectively, as the address of a proxy server
+to use for transferring files.
+.Sh SEE ALSO
+.Xr com_err 3 ,
+.Xr fetch 1 ,
+.Xr ftpio 3
+.Rs
+.%A T. Berners-Lee, L. Masinter & M. McCahill
+.%D December 1994
+.%T Uniform Resource Locators (URL)
+.%O RFC1738
+.Re
+.Rs
+.%A R. Fielding, J. Gettys, J. Mogul, H. Frystyk, T. Berners-Lee
+.%D Januray 1997
+.%B Hypertext Transfer Protocol -- HTTP/1.1
+.%O RFC2068
+.Re
+.Rs
+.%A J. Postel, J. K. Reynolds
+.%D October 1985
+.%B File Transfer Protocol
+.%O RFC959
+.Re
+.Sh NOTES
+The
+.Nm fetch
+library uses the Common Error library, and applications which link
+with
+.Nm libfetch
+must therefore also link with
+.Nm libcom_err .
+.Sh HISTORY
+The
+.Nm fetch
+library first appeared in
+.Fx 3.0 .
+.Sh AUTHORS
+The
+.Nm fetch
+library was mostly written by
+.An Dag-Erling Coïdan Smørgrav Aq des@FreeBSD.org
+with numerous suggestions from
+.An Jordan K. Hubbard Aq jkh@FreeBSD.org ,
+.An Eugene Skepner Aq eu@qub.com
+and other FreeBSD developers.
+It replaces the older
+.Nm ftpio
+library written by
+.An Poul-Henning Kamp Aq pkh@FreeBSD.org
+and
+.An Jordan K. Hubbard Aq jkh@FreeBSD.org .
+.Pp
+This manual page was written by
+.An Dag-Erling Coïdan Smørgrav Aq des@FreeBSD.org
+.Sh BUGS
+Some parts of the library are not yet implemented. The most notable
+examples of this are
+.Fn fetchPutHTTP ,
+.Fn fetchStatHTTP ,
+.Fn fetchListHTTP ,
+.Fn fetchListFTP ,
+and FTP proxy support.
+.Pp
+There's no way to select a proxy at run-time other than setting the
+.Ev HTTP_PROXY
+or
+.Ev FTP_PROXY
+environment variables as appropriate. There is also no way to stop the
+FTP and HTTP functions from trying to use a proxy if these variables
+are set.
+.Pp
+HTTP authentication doesn't work. I'm not sure that's a bug in my
+code; as far as I can determine,
+.Nm libfetch
+handles HTTP/1.1 basic authentication correctly as outlined in
+RFC2068, but I haven't been able to find an HTTP server that honors
+the Authentication: header field. Also,
+.Nm libfetch
+does not attempt to interpret and respond to authentication requests
+from the HTTP server.
+.Pp
+No attempt is made to encode spaces etc. within URLs. Spaces in the
+document part of an URLshould be replaced with "%20" in HTTP URLs and
+"\\ " in FTP URLs.
+.Pp
+Error numbers are unique only within a certain context; the error
+codes used for FTP and HTTP overlap, as do those used for resolver and
+system errors. For instance, error code 202 means "Command not
+implemented, superfluous at this site" in an FTP context and
+"Accepted" in an HTTP context.
+.Pp
+The man page is poorly written and produces badly formatted text.
+.Pp
+Tons of other stuff.
diff --git a/lib/libfetch/fetch.c b/lib/libfetch/fetch.c
new file mode 100644
index 0000000..bf4476f
--- /dev/null
+++ b/lib/libfetch/fetch.c
@@ -0,0 +1,314 @@
+/*-
+ * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/errno.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "fetch.h"
+#include "common.h"
+
+
+int fetchLastErrCode;
+
+
+/*** Local data **************************************************************/
+
+/*
+ * Error messages for parser errors
+ */
+#define URL_MALFORMED 1
+#define URL_BAD_SCHEME 2
+#define URL_BAD_PORT 3
+static struct fetcherr _url_errlist[] = {
+ { URL_MALFORMED, FETCH_URL, "Malformed URL" },
+ { URL_BAD_SCHEME, FETCH_URL, "Invalid URL scheme" },
+ { URL_BAD_PORT, FETCH_URL, "Invalid server port" },
+ { -1, FETCH_UNKNOWN, "Unknown parser error" }
+};
+
+
+/*** Public API **************************************************************/
+
+/*
+ * Select the appropriate protocol for the URL scheme, and return a
+ * read-only stream connected to the document referenced by the URL.
+ */
+FILE *
+fetchGet(struct url *URL, char *flags)
+{
+ if (strcasecmp(URL->scheme, "file") == 0)
+ return fetchGetFile(URL, flags);
+ else if (strcasecmp(URL->scheme, "http") == 0)
+ return fetchGetHTTP(URL, flags);
+ else if (strcasecmp(URL->scheme, "ftp") == 0)
+ return fetchGetFTP(URL, flags);
+ else {
+ _url_seterr(URL_BAD_SCHEME);
+ return NULL;
+ }
+}
+
+/*
+ * Select the appropriate protocol for the URL scheme, and return a
+ * write-only stream connected to the document referenced by the URL.
+ */
+FILE *
+fetchPut(struct url *URL, char *flags)
+{
+ if (strcasecmp(URL->scheme, "file") == 0)
+ return fetchPutFile(URL, flags);
+ else if (strcasecmp(URL->scheme, "http") == 0)
+ return fetchPutHTTP(URL, flags);
+ else if (strcasecmp(URL->scheme, "ftp") == 0)
+ return fetchPutFTP(URL, flags);
+ else {
+ _url_seterr(URL_BAD_SCHEME);
+ return NULL;
+ }
+}
+
+/*
+ * Select the appropriate protocol for the URL scheme, and return the
+ * size of the document referenced by the URL if it exists.
+ */
+int
+fetchStat(struct url *URL, struct url_stat *us, char *flags)
+{
+ if (strcasecmp(URL->scheme, "file") == 0)
+ return fetchStatFile(URL, us, flags);
+ else if (strcasecmp(URL->scheme, "http") == 0)
+ return fetchStatHTTP(URL, us, flags);
+ else if (strcasecmp(URL->scheme, "ftp") == 0)
+ return fetchStatFTP(URL, us, flags);
+ else {
+ _url_seterr(URL_BAD_SCHEME);
+ return -1;
+ }
+}
+
+/*
+ * Select the appropriate protocol for the URL scheme, and return a
+ * list of files in the directory pointed to by the URL.
+ */
+struct url_ent *
+fetchList(struct url *URL, char *flags)
+{
+ if (strcasecmp(URL->scheme, "file") == 0)
+ return fetchListFile(URL, flags);
+ else if (strcasecmp(URL->scheme, "http") == 0)
+ return fetchListHTTP(URL, flags);
+ else if (strcasecmp(URL->scheme, "ftp") == 0)
+ return fetchListFTP(URL, flags);
+ else {
+ _url_seterr(URL_BAD_SCHEME);
+ return NULL;
+ }
+}
+
+/*
+ * Attempt to parse the given URL; if successful, call fetchGet().
+ */
+FILE *
+fetchGetURL(char *URL, char *flags)
+{
+ struct url *u;
+ FILE *f;
+
+ if ((u = fetchParseURL(URL)) == NULL)
+ return NULL;
+
+ f = fetchGet(u, flags);
+
+ free(u);
+ return f;
+}
+
+
+/*
+ * Attempt to parse the given URL; if successful, call fetchPut().
+ */
+FILE *
+fetchPutURL(char *URL, char *flags)
+{
+ struct url *u;
+ FILE *f;
+
+ if ((u = fetchParseURL(URL)) == NULL)
+ return NULL;
+
+ f = fetchPut(u, flags);
+
+ free(u);
+ return f;
+}
+
+/*
+ * Attempt to parse the given URL; if successful, call fetchStat().
+ */
+int
+fetchStatURL(char *URL, struct url_stat *us, char *flags)
+{
+ struct url *u;
+ int s;
+
+ if ((u = fetchParseURL(URL)) == NULL)
+ return -1;
+
+ s = fetchStat(u, us, flags);
+
+ free(u);
+ return s;
+}
+
+/*
+ * Attempt to parse the given URL; if successful, call fetchList().
+ */
+struct url_ent *
+fetchListURL(char *URL, char *flags)
+{
+ struct url *u;
+ struct url_ent *ue;
+
+ if ((u = fetchParseURL(URL)) == NULL)
+ return NULL;
+
+ ue = fetchList(u, flags);
+
+ free(u);
+ return ue;
+}
+
+/*
+ * Split an URL into components. URL syntax is:
+ * method:[//[user[:pwd]@]host[:port]]/[document]
+ * This almost, but not quite, RFC1738 URL syntax.
+ */
+struct url *
+fetchParseURL(char *URL)
+{
+ char *p, *q;
+ struct url *u;
+ int i;
+
+ /* allocate struct url */
+ if ((u = calloc(1, sizeof(struct url))) == NULL) {
+ errno = ENOMEM;
+ _fetch_syserr();
+ return NULL;
+ }
+
+ /* scheme name */
+ for (i = 0; *URL && (*URL != ':'); URL++)
+ if (i < URL_SCHEMELEN)
+ u->scheme[i++] = *URL;
+ if (!URL[0] || (URL[1] != '/')) {
+ _url_seterr(URL_BAD_SCHEME);
+ goto ouch;
+ }
+ else URL++;
+ if (URL[1] != '/') {
+ p = URL;
+ goto nohost;
+ }
+ else URL += 2;
+
+ p = strpbrk(URL, "/@");
+ if (p && *p == '@') {
+ /* username */
+ for (q = URL, i = 0; (*q != ':') && (*q != '@'); q++)
+ if (i < URL_USERLEN)
+ u->user[i++] = *q;
+
+ /* password */
+ if (*q == ':')
+ for (q++, i = 0; (*q != ':') && (*q != '@'); q++)
+ if (i < URL_PWDLEN)
+ u->pwd[i++] = *q;
+
+ p++;
+ } else p = URL;
+
+ /* hostname */
+ for (i = 0; *p && (*p != '/') && (*p != ':'); p++)
+ if (i < MAXHOSTNAMELEN)
+ u->host[i++] = *p;
+
+ /* port */
+ if (*p == ':') {
+ for (q = ++p; *q && (*q != '/'); q++)
+ if (isdigit(*q))
+ u->port = u->port * 10 + (*q - '0');
+ else {
+ /* invalid port */
+ _url_seterr(URL_BAD_PORT);
+ goto ouch;
+ }
+ while (*p && (*p != '/'))
+ p++;
+ }
+
+nohost:
+ /* document */
+ if (*p) {
+ struct url *t;
+ t = realloc(u, sizeof(*u)+strlen(p)-1);
+ if (t == NULL) {
+ errno = ENOMEM;
+ _fetch_syserr();
+ goto ouch;
+ }
+ u = t;
+ strcpy(u->doc, p);
+ } else {
+ u->doc[0] = '/';
+ u->doc[1] = 0;
+ }
+
+ DEBUG(fprintf(stderr,
+ "scheme: [\033[1m%s\033[m]\n"
+ "user: [\033[1m%s\033[m]\n"
+ "password: [\033[1m%s\033[m]\n"
+ "host: [\033[1m%s\033[m]\n"
+ "port: [\033[1m%d\033[m]\n"
+ "document: [\033[1m%s\033[m]\n",
+ u->scheme, u->user, u->pwd,
+ u->host, u->port, u->doc));
+
+ return u;
+
+ouch:
+ free(u);
+ return NULL;
+}
diff --git a/lib/libfetch/fetch.h b/lib/libfetch/fetch.h
new file mode 100644
index 0000000..df34509
--- /dev/null
+++ b/lib/libfetch/fetch.h
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _FETCH_H_INCLUDED
+#define _FETCH_H_INCLUDED
+
+#include <fetch_err.h>
+
+#define _LIBFETCH_VER "libfetch/1.0"
+
+#define URL_SCHEMELEN 16
+#define URL_USERLEN 256
+#define URL_PWDLEN 256
+
+struct url {
+ char scheme[URL_SCHEMELEN+1];
+ char user[URL_USERLEN+1];
+ char pwd[URL_PWDLEN+1];
+ char host[MAXHOSTNAMELEN+1];
+ int port;
+ char doc[2];
+};
+
+struct url_stat {
+ off_t size;
+ time_t atime;
+ time_t mtime;
+};
+
+struct url_ent {
+ char name[MAXPATHLEN];
+ struct url_stat stat;
+};
+
+/* FILE-specific functions */
+FILE *fetchGetFile(struct url *, char *);
+FILE *fetchPutFile(struct url *, char *);
+int fetchStatFile(struct url *, struct url_stat *, char *);
+struct url_ent *fetchListFile(struct url *, char *);
+
+/* HTTP-specific functions */
+char *fetchContentType(FILE *);
+FILE *fetchGetHTTP(struct url *, char *);
+FILE *fetchPutHTTP(struct url *, char *);
+int fetchStatHTTP(struct url *, struct url_stat *, char *);
+struct url_ent *fetchListHTTP(struct url *, char *);
+
+/* FTP-specific functions */
+FILE *fetchGetFTP(struct url *, char *);
+FILE *fetchPutFTP(struct url *, char *);
+int fetchStatFTP(struct url *, struct url_stat *, char *);
+struct url_ent *fetchListFTP(struct url *, char *);
+
+/* Generic functions */
+struct url *fetchParseURL(char *);
+FILE *fetchGetURL(char *, char *);
+FILE *fetchPutURL(char *, char *);
+int fetchStatURL(char *, struct url_stat *, char *);
+struct url_ent *fetchListURL(char *, char *);
+FILE *fetchGet(struct url *, char *);
+FILE *fetchPut(struct url *, char *);
+int fetchStat(struct url *, struct url_stat *, char *);
+struct url_ent *fetchList(struct url *, char *);
+
+/* Last error code */
+extern int fetchLastErrCode;
+
+#endif
diff --git a/lib/libfetch/fetch_err.et b/lib/libfetch/fetch_err.et
new file mode 100644
index 0000000..2593eba
--- /dev/null
+++ b/lib/libfetch/fetch_err.et
@@ -0,0 +1,50 @@
+#-
+# Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer
+# in this position and unchanged.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+et ftch
+ ec FETCH_ABORT, "Operation aborted"
+ ec FETCH_AUTH, "Authentication failed"
+ ec FETCH_DOWN, "Service unavailable"
+ ec FETCH_EXISTS, "File exists"
+ ec FETCH_FULL, "File system full"
+ ec FETCH_INFO, "Informational response"
+ ec FETCH_MEMORY, "Insufficient memory"
+ ec FETCH_MOVED, "File has moved"
+ ec FETCH_NETWORK, "Network error"
+ ec FETCH_OK, "No error"
+ ec FETCH_PROTO, "Protocol error"
+ ec FETCH_RESOLV, "Resolver error"
+ ec FETCH_SERVER, "Server error"
+ ec FETCH_TEMP, "Temporary error"
+ ec FETCH_TIMEOUT, "Operation timed out"
+ ec FETCH_UNAVAIL, "File is not available"
+ ec FETCH_UNKNOWN, "Unknown error"
+ ec FETCH_URL, "Invalid URL"
+ ec FETCH_VERBOSE, ""
+end
diff --git a/lib/libfetch/file.c b/lib/libfetch/file.c
new file mode 100644
index 0000000..5b594c4
--- /dev/null
+++ b/lib/libfetch/file.c
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "fetch.h"
+#include "common.h"
+
+FILE *
+fetchGetFile(struct url *u, char *flags)
+{
+ FILE *f;
+
+ f = fopen(u->doc, "r");
+
+ if (f == NULL)
+ _fetch_syserr();
+ return f;
+}
+
+FILE *
+fetchPutFile(struct url *u, char *flags)
+{
+ FILE *f;
+
+ if (strchr(flags, 'a'))
+ f = fopen(u->doc, "a");
+ else
+ f = fopen(u->doc, "w");
+
+ if (f == NULL)
+ _fetch_syserr();
+ return f;
+}
+
+static int
+_fetch_stat_file(char *fn, struct url_stat *us)
+{
+ struct stat sb;
+
+ if (stat(fn, &sb) == -1) {
+ _fetch_syserr();
+ return -1;
+ }
+ us->size = sb.st_size;
+ us->atime = sb.st_atime;
+ us->mtime = sb.st_mtime;
+ return 0;
+}
+
+int
+fetchStatFile(struct url *u, struct url_stat *us, char *flags)
+{
+ return _fetch_stat_file(u->doc, us);
+}
+
+struct url_ent *
+fetchListFile(struct url *u, char *flags)
+{
+ DIR *dir;
+ struct dirent *de;
+ struct url_stat us;
+ struct url_ent *ue;
+ int size, len;
+ char fn[MAXPATHLEN], *p;
+ int l;
+
+ if ((dir = opendir(u->doc)) == NULL) {
+ _fetch_syserr();
+ return NULL;
+ }
+
+ ue = NULL;
+ strncpy(fn, u->doc, sizeof fn - 2);
+ fn[sizeof fn - 2] = 0;
+ strcat(fn, "/");
+ p = strchr(fn, 0);
+ l = sizeof fn - strlen(fn) - 1;
+
+ while ((de = readdir(dir)) != NULL) {
+ strncpy(p, de->d_name, l - 1);
+ p[l - 1] = 0;
+ if (_fetch_stat_file(fn, &us) == -1)
+ /* should I return a partial result, or abort? */
+ break;
+ _fetch_add_entry(&ue, &size, &len, de->d_name, &us);
+ }
+
+ return ue;
+}
diff --git a/lib/libfetch/ftp.c b/lib/libfetch/ftp.c
new file mode 100644
index 0000000..a3279e1
--- /dev/null
+++ b/lib/libfetch/ftp.c
@@ -0,0 +1,520 @@
+/*-
+ * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Portions of this code were taken from or based on ftpio.c:
+ *
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * Major Changelog:
+ *
+ * Dag-Erling Coïdan Smørgrav
+ * 9 Jun 1998
+ *
+ * Incorporated into libfetch
+ *
+ * Jordan K. Hubbard
+ * 17 Jan 1996
+ *
+ * Turned inside out. Now returns xfers as new file ids, not as a special
+ * `state' of FTP_t
+ *
+ * $ftpioId: ftpio.c,v 1.30 1998/04/11 07:28:53 phk Exp $
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "fetch.h"
+#include "common.h"
+#include "ftperr.h"
+
+#define FTP_ANONYMOUS_USER "ftp"
+#define FTP_ANONYMOUS_PASSWORD "ftp"
+#define FTP_DEFAULT_PORT 21
+
+#define FTP_OPEN_DATA_CONNECTION 150
+#define FTP_OK 200
+#define FTP_FILE_STATUS 213
+#define FTP_SERVICE_READY 220
+#define FTP_PASSIVE_MODE 227
+#define FTP_LOGGED_IN 230
+#define FTP_FILE_ACTION_OK 250
+#define FTP_NEED_PASSWORD 331
+#define FTP_NEED_ACCOUNT 332
+
+#define ENDL "\r\n"
+
+static struct url cached_host;
+static FILE *cached_socket;
+
+static char _ftp_last_reply[1024];
+
+/*
+ * Get server response, check that first digit is a '2'
+ */
+static int
+_ftp_chkerr(FILE *s)
+{
+ char *line;
+ size_t len;
+
+ do {
+ if (((line = fgetln(s, &len)) == NULL) || (len < 4)) {
+ _fetch_syserr();
+ return -1;
+ }
+ } while (len >= 4 && line[3] == '-');
+
+ while (len && isspace(line[len-1]))
+ len--;
+ snprintf(_ftp_last_reply, sizeof(_ftp_last_reply),
+ "%*.*s", (int)len, (int)len, line);
+
+#ifndef NDEBUG
+ fprintf(stderr, "\033[1m<<< ");
+ fprintf(stderr, "%*.*s\n", (int)len, (int)len, line);
+ fprintf(stderr, "\033[m");
+#endif
+
+ if (len < 4 || !isdigit(line[1]) || !isdigit(line[1])
+ || !isdigit(line[2]) || (line[3] != ' ')) {
+ return -1;
+ }
+
+ return (line[0] - '0') * 100 + (line[1] - '0') * 10 + (line[2] - '0');
+}
+
+/*
+ * Send a command and check reply
+ */
+static int
+_ftp_cmd(FILE *f, char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(f, fmt, ap);
+#ifndef NDEBUG
+ fprintf(stderr, "\033[1m>>> ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\033[m");
+#endif
+ va_end(ap);
+
+ return _ftp_chkerr(f);
+}
+
+/*
+ * Transfer file
+ */
+static FILE *
+_ftp_transfer(FILE *cf, char *oper, char *file, char *mode, int pasv)
+{
+ struct sockaddr_in sin;
+ int e, sd = -1, l;
+ char *s;
+ FILE *df;
+
+ /* change directory */
+ if (((s = strrchr(file, '/')) != NULL) && (s != file)) {
+ *s = 0;
+ if ((e = _ftp_cmd(cf, "CWD %s" ENDL, file)) != FTP_FILE_ACTION_OK) {
+ *s = '/';
+ _ftp_seterr(e);
+ return NULL;
+ }
+ *s++ = '/';
+ } else {
+ if ((e = _ftp_cmd(cf, "CWD /" ENDL)) != FTP_FILE_ACTION_OK) {
+ _ftp_seterr(e);
+ return NULL;
+ }
+ }
+
+ /* s now points to file name */
+
+ /* open data socket */
+ if ((sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+ _fetch_syserr();
+ return NULL;
+ }
+
+ if (pasv) {
+ u_char addr[6];
+ char *ln, *p;
+ int i;
+
+ /* send PASV command */
+ if ((e = _ftp_cmd(cf, "PASV" ENDL)) != FTP_PASSIVE_MODE)
+ goto ouch;
+
+ /* find address and port number. The reply to the PASV command
+ is IMHO the one and only weak point in the FTP protocol. */
+ ln = _ftp_last_reply;
+ for (p = ln + 3; !isdigit(*p); p++)
+ /* nothing */ ;
+ for (p--, i = 0; i < 6; i++) {
+ p++; /* skip the comma */
+ addr[i] = strtol(p, &p, 10);
+ }
+
+ /* construct sockaddr for data socket */
+ l = sizeof(sin);
+ if (getpeername(fileno(cf), (struct sockaddr *)&sin, &l) == -1)
+ goto sysouch;
+ bcopy(addr, (char *)&sin.sin_addr, 4);
+ bcopy(addr + 4, (char *)&sin.sin_port, 2);
+
+ /* connect to data port */
+ if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
+ goto sysouch;
+
+ /* make the server initiate the transfer */
+ e = _ftp_cmd(cf, "%s %s" ENDL, oper, s);
+ if (e != FTP_OPEN_DATA_CONNECTION)
+ goto ouch;
+
+ } else {
+ u_int32_t a;
+ u_short p;
+ int d;
+
+ /* find our own address, bind, and listen */
+ l = sizeof(sin);
+ if (getsockname(fileno(cf), (struct sockaddr *)&sin, &l) == -1)
+ goto sysouch;
+ sin.sin_port = 0;
+ if (bind(sd, (struct sockaddr *)&sin, l) == -1)
+ goto sysouch;
+ if (listen(sd, 1) == -1)
+ goto sysouch;
+
+ /* find what port we're on and tell the server */
+ if (getsockname(sd, (struct sockaddr *)&sin, &l) == -1)
+ goto sysouch;
+ a = ntohl(sin.sin_addr.s_addr);
+ p = ntohs(sin.sin_port);
+ e = _ftp_cmd(cf, "PORT %d,%d,%d,%d,%d,%d" ENDL,
+ (a >> 24) & 0xff, (a >> 16) & 0xff,
+ (a >> 8) & 0xff, a & 0xff,
+ (p >> 8) & 0xff, p & 0xff);
+ if (e != FTP_OK)
+ goto ouch;
+
+ /* make the server initiate the transfer */
+ e = _ftp_cmd(cf, "%s %s" ENDL, oper, s);
+ if (e != FTP_OPEN_DATA_CONNECTION)
+ goto ouch;
+
+ /* accept the incoming connection and go to town */
+ if ((d = accept(sd, NULL, NULL)) == -1)
+ goto sysouch;
+ close(sd);
+ sd = d;
+ }
+
+ if ((df = fdopen(sd, mode)) == NULL)
+ goto sysouch;
+ return df;
+
+sysouch:
+ _fetch_syserr();
+ close(sd);
+ return NULL;
+
+ouch:
+ _ftp_seterr(e);
+ close(sd);
+ return NULL;
+}
+
+/*
+ * Log on to FTP server
+ */
+static FILE *
+_ftp_connect(char *host, int port, char *user, char *pwd, int verbose)
+{
+ int sd, e, pp = FTP_DEFAULT_PORT;
+ char *p, *q;
+ FILE *f;
+
+ /* check for proxy */
+ if ((p = getenv("FTP_PROXY")) != NULL) {
+ if ((q = strchr(p, ':')) != NULL) {
+ /* XXX check that it's a valid number */
+ pp = atoi(q+1);
+ }
+ if (q)
+ *q = 0;
+ sd = _fetch_connect(p, pp, verbose);
+ if (q)
+ *q = ':';
+ } else {
+ /* no proxy, go straight to target */
+ sd = _fetch_connect(host, port, verbose);
+ }
+
+ /* check connection */
+ if (sd == -1) {
+ _fetch_syserr();
+ return NULL;
+ }
+
+ /* streams make life easier */
+ if ((f = fdopen(sd, "r+")) == NULL) {
+ _fetch_syserr();
+ close(sd);
+ return NULL;
+ }
+
+ /* expect welcome message */
+ if ((e = _ftp_chkerr(f)) != FTP_SERVICE_READY)
+ goto fouch;
+
+ /* send user name and password */
+ if (!user || !*user)
+ user = FTP_ANONYMOUS_USER;
+ e = p ? _ftp_cmd(f, "USER %s@%s@%d" ENDL, user, host, port)
+ : _ftp_cmd(f, "USER %s" ENDL, user);
+
+ /* did the server request a password? */
+ if (e == FTP_NEED_PASSWORD) {
+ if (!pwd || !*pwd)
+ pwd = FTP_ANONYMOUS_PASSWORD;
+ e = _ftp_cmd(f, "PASS %s" ENDL, pwd);
+ }
+
+ /* did the server request an account? */
+ if (e == FTP_NEED_ACCOUNT)
+ goto fouch;
+
+ /* we should be done by now */
+ if (e != FTP_LOGGED_IN)
+ goto fouch;
+
+ /* might as well select mode and type at once */
+#ifdef FTP_FORCE_STREAM_MODE
+ if ((e = _ftp_cmd(f, "MODE S" ENDL)) != FTP_OK) /* default is S */
+ goto fouch;
+#endif
+ if ((e = _ftp_cmd(f, "TYPE I" ENDL)) != FTP_OK) /* default is A */
+ goto fouch;
+
+ /* done */
+ return f;
+
+fouch:
+ _ftp_seterr(e);
+ fclose(f);
+ return NULL;
+}
+
+/*
+ * Disconnect from server
+ */
+static void
+_ftp_disconnect(FILE *f)
+{
+ (void)_ftp_cmd(f, "QUIT" ENDL);
+ fclose(f);
+}
+
+/*
+ * Check if we're already connected
+ */
+static int
+_ftp_isconnected(struct url *url)
+{
+ return (cached_socket
+ && (strcmp(url->host, cached_host.host) == 0)
+ && (strcmp(url->user, cached_host.user) == 0)
+ && (strcmp(url->pwd, cached_host.pwd) == 0)
+ && (url->port == cached_host.port));
+}
+
+/*
+ * Check the cache, reconnect if no luck
+ */
+static FILE *
+_ftp_cached_connect(struct url *url, char *flags)
+{
+ FILE *cf;
+
+ cf = NULL;
+
+ /* set default port */
+ if (!url->port)
+ url->port = FTP_DEFAULT_PORT;
+
+ /* try to use previously cached connection */
+ if (_ftp_isconnected(url))
+ if (_ftp_cmd(cached_socket, "NOOP" ENDL) != -1)
+ cf = cached_socket;
+
+ /* connect to server */
+ if (!cf) {
+ cf = _ftp_connect(url->host, url->port, url->user, url->pwd,
+ (strchr(flags, 'v') != NULL));
+ if (!cf)
+ return NULL;
+ if (cached_socket)
+ _ftp_disconnect(cached_socket);
+ cached_socket = cf;
+ memcpy(&cached_host, url, sizeof(struct url));
+ }
+
+ return cf;
+}
+
+/*
+ * Get file
+ */
+FILE *
+fetchGetFTP(struct url *url, char *flags)
+{
+ FILE *cf;
+
+ /* connect to server */
+ if ((cf = _ftp_cached_connect(url, flags)) == NULL)
+ return NULL;
+
+ /* initiate the transfer */
+ return _ftp_transfer(cf, "RETR", url->doc, "r",
+ (flags && strchr(flags, 'p')));
+}
+
+/*
+ * Put file
+ */
+FILE *
+fetchPutFTP(struct url *url, char *flags)
+{
+ FILE *cf;
+
+ /* connect to server */
+ if ((cf = _ftp_cached_connect(url, flags)) == NULL)
+ return NULL;
+
+ /* initiate the transfer */
+ return _ftp_transfer(cf, (flags && strchr(flags, 'a')) ? "APPE" : "STOR",
+ url->doc, "w", (flags && strchr(flags, 'p')));
+}
+
+/*
+ * Get file stats
+ */
+int
+fetchStatFTP(struct url *url, struct url_stat *us, char *flags)
+{
+ FILE *cf;
+ char *ln, *s;
+ struct tm tm;
+ time_t t;
+ int e;
+
+ /* connect to server */
+ if ((cf = _ftp_cached_connect(url, flags)) == NULL)
+ return -1;
+
+ /* change directory */
+ if (((s = strrchr(url->doc, '/')) != NULL) && (s != url->doc)) {
+ *s = 0;
+ if ((e = _ftp_cmd(cf, "CWD %s" ENDL, url->doc)) != FTP_FILE_ACTION_OK) {
+ *s = '/';
+ goto ouch;
+ }
+ *s++ = '/';
+ } else {
+ if ((e = _ftp_cmd(cf, "CWD /" ENDL)) != FTP_FILE_ACTION_OK)
+ goto ouch;
+ }
+
+ /* s now points to file name */
+
+ if (_ftp_cmd(cf, "SIZE %s" ENDL, s) != FTP_FILE_STATUS)
+ goto ouch;
+ for (ln = _ftp_last_reply + 4; *ln && isspace(*ln); ln++)
+ /* nothing */ ;
+ for (us->size = 0; *ln && isdigit(*ln); ln++)
+ us->size = us->size * 10 + *ln - '0';
+ if (*ln && !isspace(*ln)) {
+ _ftp_seterr(999); /* XXX should signal a FETCH_PROTO error */
+ return -1;
+ }
+
+ if ((e = _ftp_cmd(cf, "MDTM %s" ENDL, s)) != FTP_FILE_STATUS)
+ goto ouch;
+ for (ln = _ftp_last_reply + 4; *ln && isspace(*ln); ln++)
+ /* nothing */ ;
+ t = time(NULL);
+ us->mtime = localtime(&t)->tm_gmtoff;
+ sscanf(ln, "%04d%02d%02d%02d%02d%02d",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
+ &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
+ /* XXX should check the return value from sscanf */
+ tm.tm_mon--;
+ tm.tm_year -= 1900;
+ tm.tm_isdst = -1;
+ tm.tm_gmtoff = 0;
+ us->mtime += mktime(&tm);
+ us->atime = us->mtime;
+ return 0;
+
+ouch:
+ _ftp_seterr(e);
+ return -1;
+}
+
+/*
+ * List a directory
+ */
+extern void warnx(char *, ...);
+struct url_ent *
+fetchListFTP(struct url *url, char *flags)
+{
+ warnx("fetchListFTP(): not implemented");
+ return NULL;
+}
diff --git a/lib/libfetch/ftp.errors b/lib/libfetch/ftp.errors
new file mode 100644
index 0000000..b9034c5
--- /dev/null
+++ b/lib/libfetch/ftp.errors
@@ -0,0 +1,44 @@
+# $FreeBSD$
+#
+# This list is taken from RFC 959.
+# It probably needs a going over.
+#
+110 OK Restart marker reply
+120 TEMP Service ready in a few minutes
+125 OK Data connection already open; transfer starting
+150 OK File status okay; about to open data connection
+200 OK Command okay
+202 PROTO Command not implemented, superfluous at this site
+211 INFO System status, or system help reply
+212 INFO Directory status
+213 INFO File status
+214 INFO Help message
+215 INFO Set system type
+220 OK Service ready for new user
+221 OK Service closing control connection
+225 OK Data connection open; no transfer in progress
+226 OK Requested file action successful
+227 OK Entering Passive Mode
+230 OK User logged in, proceed
+250 OK Requested file action okay, completed
+257 OK File/directory created
+331 AUTH User name okay, need password
+332 AUTH Need account for login
+350 OK Requested file action pending further information
+421 DOWN Service not available, closing control connection
+425 NETWORK Can't open data connection
+426 ABORT Connection closed; transfer aborted
+450 UNAVAIL File unavailable (e.g., file busy)
+451 SERVER Requested action aborted: local error in processing
+452 FULL Insufficient storage space in system
+500 PROTO Syntax error, command unrecognized
+501 PROTO Syntax error in parameters or arguments
+502 PROTO Command not implemented
+503 PROTO Bad sequence of commands
+504 PROTO Command not implemented for that parameter
+530 AUTH Not logged in
+532 AUTH Need account for storing files
+550 UNAVAIL File unavailable (e.g., file not found, no access)
+551 PROTO Requested action aborted. Page type unknown
+552 FULL Exceeded storage allocation
+553 EXISTS File name not allowed
diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c
new file mode 100644
index 0000000..716d6c2
--- /dev/null
+++ b/lib/libfetch/http.c
@@ -0,0 +1,471 @@
+/*-
+ * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * The base64 code in this file is based on code from MIT fetch, which
+ * has the following copyright and license:
+ *
+ *-
+ * Copyright 1997 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
+
+#include <sys/param.h>
+
+#include <err.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "fetch.h"
+#include "common.h"
+#include "httperr.h"
+
+extern char *__progname;
+
+#define ENDL "\r\n"
+
+struct cookie
+{
+ FILE *real_f;
+#define ENC_NONE 0
+#define ENC_CHUNKED 1
+ int encoding; /* 1 = chunked, 0 = none */
+#define HTTPCTYPELEN 59
+ char content_type[HTTPCTYPELEN+1];
+ char *buf;
+ int b_cur, eof;
+ unsigned b_len, chunksize;
+};
+
+/*
+ * Send a formatted line; optionally echo to terminal
+ */
+static int
+_http_cmd(FILE *f, char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(f, fmt, ap);
+#ifndef NDEBUG
+ fprintf(stderr, "\033[1m>>> ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\033[m");
+#endif
+ va_end(ap);
+
+ return 0; /* XXX */
+}
+
+/*
+ * Fill the input buffer, do chunk decoding on the fly
+ */
+static char *
+_http_fillbuf(struct cookie *c)
+{
+ char *ln;
+ unsigned int len;
+
+ if (c->eof)
+ return NULL;
+
+ if (c->encoding == ENC_NONE) {
+ c->buf = fgetln(c->real_f, &(c->b_len));
+ c->b_cur = 0;
+ } else if (c->encoding == ENC_CHUNKED) {
+ if (c->chunksize == 0) {
+ ln = fgetln(c->real_f, &len);
+ DEBUG(fprintf(stderr, "\033[1m_http_fillbuf(): new chunk: "
+ "%*.*s\033[m\n", (int)len-2, (int)len-2, ln));
+ sscanf(ln, "%x", &(c->chunksize));
+ if (!c->chunksize) {
+ DEBUG(fprintf(stderr, "\033[1m_http_fillbuf(): "
+ "end of last chunk\033[m\n"));
+ c->eof = 1;
+ return NULL;
+ }
+ DEBUG(fprintf(stderr, "\033[1m_http_fillbuf(): "
+ "new chunk: %X\033[m\n", c->chunksize));
+ }
+ c->buf = fgetln(c->real_f, &(c->b_len));
+ if (c->b_len > c->chunksize)
+ c->b_len = c->chunksize;
+ c->chunksize -= c->b_len;
+ c->b_cur = 0;
+ }
+ else return NULL; /* unknown encoding */
+ return c->buf;
+}
+
+/*
+ * Read function
+ */
+static int
+_http_readfn(struct cookie *c, char *buf, int len)
+{
+ int l, pos = 0;
+ while (len) {
+ /* empty buffer */
+ if (!c->buf || (c->b_cur == c->b_len))
+ if (!_http_fillbuf(c))
+ break;
+
+ l = c->b_len - c->b_cur;
+ if (len < l) l = len;
+ memcpy(buf + pos, c->buf + c->b_cur, l);
+ c->b_cur += l;
+ pos += l;
+ len -= l;
+ }
+
+ if (ferror(c->real_f))
+ return -1;
+ else return pos;
+}
+
+/*
+ * Write function
+ */
+static int
+_http_writefn(struct cookie *c, const char *buf, int len)
+{
+ size_t r = fwrite(buf, 1, (size_t)len, c->real_f);
+ return r ? r : -1;
+}
+
+/*
+ * Close function
+ */
+static int
+_http_closefn(struct cookie *c)
+{
+ int r = fclose(c->real_f);
+ free(c);
+ return (r == EOF) ? -1 : 0;
+}
+
+/*
+ * Extract content type from cookie
+ */
+char *
+fetchContentType(FILE *f)
+{
+ /*
+ * We have no way of making sure this really *is* one of our cookies,
+ * so just check for a null pointer and hope for the best.
+ */
+ return f->_cookie ? (((struct cookie *)f->_cookie)->content_type) : NULL;
+}
+
+/*
+ * Base64 encoding
+ */
+int
+_http_base64(char *dst, char *src, int l)
+{
+ static const char base64[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+ int t, r = 0;
+
+ while (l >= 3) {
+ t = (src[0] << 16) | (src[1] << 8) | src[2];
+ dst[0] = base64[(t >> 18) & 0x3f];
+ dst[1] = base64[(t >> 12) & 0x3f];
+ dst[2] = base64[(t >> 6) & 0x3f];
+ dst[3] = base64[(t >> 0) & 0x3f];
+ src += 3; l -= 3;
+ dst += 4; r += 4;
+ }
+
+ switch (l) {
+ case 2:
+ t = (src[0] << 16) | (src[1] << 8);
+ dst[0] = base64[(t >> 18) & 0x3f];
+ dst[1] = base64[(t >> 12) & 0x3f];
+ dst[2] = base64[(t >> 6) & 0x3f];
+ dst[3] = '=';
+ dst += 4;
+ r += 4;
+ break;
+ case 1:
+ t = src[0] << 16;
+ dst[0] = base64[(t >> 18) & 0x3f];
+ dst[1] = base64[(t >> 12) & 0x3f];
+ dst[2] = dst[3] = '=';
+ dst += 4;
+ r += 4;
+ break;
+ case 0:
+ break;
+ }
+
+ *dst = 0;
+ return r;
+}
+
+/*
+ * Encode username and password
+ */
+char *
+_http_auth(char *usr, char *pwd)
+{
+ int len, lu, lp;
+ char *str, *s;
+
+ lu = strlen(usr);
+ lp = strlen(pwd);
+
+ len = (lu * 4 + 2) / 3 /* user name, round up */
+ + 1 /* colon */
+ + (lp * 4 + 2) / 3 /* password, round up */
+ + 1; /* null */
+
+ if ((s = str = (char *)malloc(len)) == NULL)
+ return NULL;
+
+ s += _http_base64(s, usr, lu);
+ *s++ = ':';
+ s += _http_base64(s, pwd, lp);
+ *s = 0;
+
+ return str;
+}
+
+/*
+ * Retrieve a file by HTTP
+ */
+FILE *
+fetchGetHTTP(struct url *URL, char *flags)
+{
+ int sd = -1, e, i, enc = ENC_NONE, verbose;
+ struct cookie *c;
+ char *ln, *p, *px, *q;
+ FILE *f, *cf;
+ size_t len;
+
+ verbose = (strchr(flags, 'v') != NULL);
+
+ /* allocate cookie */
+ if ((c = calloc(1, sizeof(struct cookie))) == NULL)
+ return NULL;
+
+ /* check port */
+ if (!URL->port)
+ URL->port = 80; /* default HTTP port */
+
+ /* attempt to connect to proxy server */
+ if ((px = getenv("HTTP_PROXY")) != NULL) {
+ char host[MAXHOSTNAMELEN];
+ int port = 3128; /* XXX I think 3128 is default... check? */
+
+ /* measure length */
+ len = strcspn(px, ":");
+
+ /* get port (atoi is a little too tolerant perhaps?) */
+ if (px[len] == ':')
+ port = atoi(px+len+1);
+
+ /* get host name */
+ if (len >= MAXHOSTNAMELEN)
+ len = MAXHOSTNAMELEN - 1;
+ strncpy(host, px, len);
+ host[len] = 0;
+
+ /* connect */
+ sd = _fetch_connect(host, port, verbose);
+ }
+
+ /* if no proxy is configured or could be contacted, try direct */
+ if (sd == -1) {
+ if ((sd = _fetch_connect(URL->host, URL->port, verbose)) == -1)
+ goto ouch;
+ }
+
+ /* reopen as stream */
+ if ((f = fdopen(sd, "r+")) == NULL)
+ goto ouch;
+ c->real_f = f;
+
+ /* send request (proxies require absolute form, so use that) */
+ if (verbose)
+ _fetch_info("requesting http://%s:%d%s",
+ URL->host, URL->port, URL->doc);
+ _http_cmd(f, "GET http://%s:%d%s HTTP/1.1" ENDL,
+ URL->host, URL->port, URL->doc);
+
+ /* start sending headers away */
+ if (URL->user[0] || URL->pwd[0]) {
+ char *auth_str = _http_auth(URL->user, URL->pwd);
+ if (!auth_str)
+ goto fouch;
+ _http_cmd(f, "Authorization: Basic %s" ENDL, auth_str);
+ free(auth_str);
+ }
+ _http_cmd(f, "Host: %s:%d" ENDL, URL->host, URL->port);
+ _http_cmd(f, "User-Agent: %s " _LIBFETCH_VER ENDL, __progname);
+ _http_cmd(f, "Connection: close" ENDL ENDL);
+
+ /* get response */
+ if ((ln = fgetln(f, &len)) == NULL)
+ goto fouch;
+ DEBUG(fprintf(stderr, "response: [\033[1m%*.*s\033[m]\n",
+ (int)len-2, (int)len-2, ln));
+
+ /* we can't use strchr() and friends since ln isn't NUL-terminated */
+ p = ln;
+ while ((p < ln + len) && !isspace(*p))
+ p++;
+ while ((p < ln + len) && !isdigit(*p))
+ p++;
+ if (!isdigit(*p))
+ goto fouch;
+ e = atoi(p);
+ DEBUG(fprintf(stderr, "code: [\033[1m%d\033[m]\n", e));
+
+ /* add code to handle redirects later */
+ if (e != 200) {
+ _http_seterr(e);
+ goto fouch;
+ }
+
+ /* browse through header */
+ while (1) {
+ if ((ln = fgetln(f, &len)) == NULL)
+ goto fouch;
+ if ((ln[0] == '\r') || (ln[0] == '\n'))
+ break;
+ DEBUG(fprintf(stderr, "header: [\033[1m%*.*s\033[m]\n",
+ (int)len-2, (int)len-2, ln));
+#define XFERENC "Transfer-Encoding:"
+ if (strncasecmp(ln, XFERENC, sizeof(XFERENC)-1) == 0) {
+ p = ln + sizeof(XFERENC) - 1;
+ while ((p < ln + len) && isspace(*p))
+ p++;
+ for (q = p; (q < ln + len) && !isspace(*q); q++)
+ /* VOID */ ;
+ *q = 0;
+ if (strcasecmp(p, "chunked") == 0)
+ enc = ENC_CHUNKED;
+ DEBUG(fprintf(stderr, "xferenc: [\033[1m%s\033[m]\n", p));
+#undef XFERENC
+#define CONTTYPE "Content-Type:"
+ } else if (strncasecmp(ln, CONTTYPE, sizeof(CONTTYPE)-1) == 0) {
+ p = ln + sizeof(CONTTYPE) - 1;
+ while ((p < ln + len) && isspace(*p))
+ p++;
+ for (i = 0; p < ln + len; p++)
+ if (i < HTTPCTYPELEN)
+ c->content_type[i++] = *p;
+ do c->content_type[i--] = 0; while (isspace(c->content_type[i]));
+ DEBUG(fprintf(stderr, "conttype: [\033[1m%s\033[m]\n",
+ c->content_type));
+#undef CONTTYPE
+ }
+ }
+
+ /* only body remains */
+ c->encoding = enc;
+ cf = funopen(c,
+ (int (*)(void *, char *, int))_http_readfn,
+ (int (*)(void *, const char *, int))_http_writefn,
+ (fpos_t (*)(void *, fpos_t, int))NULL,
+ (int (*)(void *))_http_closefn);
+ if (cf == NULL)
+ goto fouch;
+ return cf;
+
+ouch:
+ if (sd >= 0)
+ close(sd);
+ free(c);
+ _http_seterr(999); /* XXX do this properly RSN */
+ return NULL;
+fouch:
+ fclose(f);
+ free(c);
+ _http_seterr(999); /* XXX do this properly RSN */
+ return NULL;
+}
+
+FILE *
+fetchPutHTTP(struct url *URL, char *flags)
+{
+ warnx("fetchPutHTTP(): not implemented");
+ return NULL;
+}
+
+/*
+ * Get an HTTP document's metadata
+ */
+int
+fetchStatHTTP(struct url *url, struct url_stat *us, char *flags)
+{
+ warnx("fetchStatHTTP(): not implemented");
+ return -1;
+}
+
+/*
+ * List a directory
+ */
+struct url_ent *
+fetchListHTTP(struct url *url, char *flags)
+{
+ warnx("fetchListHTTP(): not implemented");
+ return NULL;
+}
diff --git a/lib/libfetch/http.errors b/lib/libfetch/http.errors
new file mode 100644
index 0000000..37e106c
--- /dev/null
+++ b/lib/libfetch/http.errors
@@ -0,0 +1,41 @@
+# $FreeBSD$
+#
+# This list is taken from RFC 2068.
+#
+100 OK Continue
+101 OK Switching Protocols
+200 OK OK
+201 OK Created
+202 OK Accepted
+203 INFO Non-Authoritative Information
+204 OK No Content
+205 OK Reset Content
+206 OK Partial Content
+300 MOVED Multiple Choices
+301 MOVED Moved Permanently
+302 MOVED Moved Temporarily
+303 MOVED See Other
+304 OK Not Modified
+305 INFO Use Proxy
+400 PROTO Bad Request
+401 AUTH Unauthorized
+402 AUTH Payment Required
+403 AUTH Forbidden
+404 UNAVAIL Not Found
+405 PROTO Method Not Allowed
+406 PROTO Not Acceptable
+407 AUTH Proxy Authentication Required
+408 TIMEOUT Request Time-out
+409 EXISTS Conflict
+410 UNAVAIL Gone
+411 PROTO Length Required
+412 SERVER Precondition Failed
+413 PROTO Request Entity Too Large
+414 PROTO Request-URI Too Large
+415 PROTO Unsupported Media Type
+500 SERVER Internal Server Error
+501 PROTO Not Implemented
+502 SERVER Bad Gateway
+503 TEMP Service Unavailable
+504 TIMEOUT Gateway Time-out
+505 PROTO HTTP Version not supported
diff --git a/lib/libform/Makefile b/lib/libform/Makefile
new file mode 100644
index 0000000..83dfbc6
--- /dev/null
+++ b/lib/libform/Makefile
@@ -0,0 +1,23 @@
+# Makefile for libform
+# $FreeBSD$
+
+NCURSES=${.CURDIR}/../../contrib/ncurses
+
+.PATH: ${NCURSES}/form
+.PATH: ${NCURSES}/menu
+
+LIB= form
+
+SRCS= fty_regex.c fty_num.c fty_int.c fty_ipv4.c fty_enum.c fty_alpha.c \
+ fty_alnum.c \
+ frm_data.c frm_win.c frm_user.c frm_opts.c frm_hook.c frm_req_name.c \
+ fld_user.c fld_type.c fld_stat.c fld_def.c frm_def.c frm_driver.c
+
+CFLAGS+=-I${.CURDIR}/../libncurses -I${NCURSES}/form -I${NCURSES}/menu \
+ -I${NCURSES}/include -Wall -DNDEBUG -DHAVE_CONFIG_H
+
+beforeinstall:
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${NCURSES}/form/form.h ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libftpio/Makefile b/lib/libftpio/Makefile
new file mode 100644
index 0000000..ecbc730
--- /dev/null
+++ b/lib/libftpio/Makefile
@@ -0,0 +1,30 @@
+# $FreeBSD$
+
+LIB= ftpio
+SHLIB_MAJOR= 5
+SHLIB_MINOR= 0
+
+SRCS= ftpio.c ftperr.c
+CFLAGS+= -I${.CURDIR} -Wall
+MAN3= ftpio.3
+CLEANFILES= ftperr.c
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/ftpio.h \
+ ${DESTDIR}/usr/include
+
+ftperr.c: ftp.errors
+ @echo '#include <stdio.h>' > ${.TARGET}
+ @echo '#include "ftpio.h"' >> ${.TARGET}
+ @echo "struct ftperr ftpErrList[] = {" \ >> ${.TARGET}
+ @cat ${.ALLSRC} \
+ | grep -v ^# \
+ | sort \
+ | while read NUM STRING; do \
+ echo " { $${NUM}, \"$${STRING}\" },"; \
+ done >> ${.TARGET}
+ @echo "};" >> ${.TARGET}
+ @echo -n "int const ftpErrListLength = " >> ${.TARGET}
+ @echo "sizeof(ftpErrList) / sizeof(*ftpErrList);" >> ${.TARGET}
+
+.include <bsd.lib.mk>
diff --git a/lib/libftpio/ftp.errors b/lib/libftpio/ftp.errors
new file mode 100644
index 0000000..7ae4445
--- /dev/null
+++ b/lib/libftpio/ftp.errors
@@ -0,0 +1,44 @@
+# $FreeBSD$
+#
+# This list is taken from RFC 959.
+# It probably needs a going over.
+#
+110 Restart marker reply
+120 Service ready in a few minutes
+125 Data connection already open; transfer starting
+150 File status okay; about to open data connection
+200 Command okay
+202 Command not implemented, superfluous at this site
+211 System status, or system help reply
+212 Directory status
+213 File status
+214 Help message
+215 Set system type
+220 Service ready for new user
+221 Service closing control connection
+225 Data connection open; no transfer in progress
+226 Requested file action successful
+227 Entering Passive Mode
+230 User logged in, proceed
+250 Requested file action okay, completed
+257 File/directory created
+331 User name okay, need password
+332 Need account for login
+350 Requested file action pending further information
+421 Service not available, closing control connection
+425 Can't open data connection
+426 Connection closed; transfer aborted
+450 File unavailable (e.g., file busy)
+451 Requested action aborted: local error in processing
+452 Insufficient storage space in system
+500 Syntax error, command unrecognized
+501 Syntax error in parameters or arguments
+502 Command not implemented
+503 Bad sequence of commands
+504 Command not implemented for that parameter
+530 Not logged in
+532 Need account for storing files
+550 File unavailable (e.g., file not found, no access)
+551 Requested action aborted. Page type unknown
+552 Exceeded storage allocation
+553 File name not allowed
diff --git a/lib/libftpio/ftpio.3 b/lib/libftpio/ftpio.3
new file mode 100644
index 0000000..60948ce
--- /dev/null
+++ b/lib/libftpio/ftpio.3
@@ -0,0 +1,212 @@
+.\" Copyright (c) 1996 Jordan Hubbard (jkh@FreeBSD.org)
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 17, 1996
+.Dt FTPIO 3
+.Os
+.Sh NAME
+.Nm ftpLogin ,
+.Nm ftpChdir ,
+.Nm ftpErrno ,
+.Nm ftpGetModtime ,
+.Nm ftpGetSize ,
+.Nm ftpGet ,
+.Nm ftpPut ,
+.Nm ftpBinary ,
+.Nm ftpPassive ,
+.Nm ftpVerbose ,
+.Nm ftpGetURL ,
+.Nm ftpPutURL
+.Nd FTPIO User library
+.Sh SYNOPSIS
+.Fd #include <ftpio.h>
+.Ft FILE *
+.Fn ftpLogin "char *host" "char *user" "char *passwd" "int ftp_port" "int verbose" "int *retcode"
+.Ft int
+.Fn ftpChdir "FILE *stream, char *dirname"
+.Ft int
+.Fn ftpErrno "FILE *stream"
+.Ft const char *
+.Fn ftpErrString "int errno"
+.Ft time_t
+.Fn ftpGetModtime "FILE *stream, char *file"
+.Ft off_t
+.Fn ftpGetSize "FILE *stream, char *file"
+.Ft FILE *
+.Fn ftpGet "FILE *stream, char *file, off_t *seekto"
+.Ft FILE *
+.Fn ftpPut "FILE *stream, char *file"
+.Ft int
+.Fn ftpAscii "FILE *stream"
+.Ft int
+.Fn ftpBinary "FILE *stream"
+.Ft int
+.Fn ftpPassive "FILE *stream, int status"
+.Ft void
+.Fn ftpVerbose "FILE *stream, int status"
+.Ft FILE *
+.Fn ftpGetURL "char *url, char *user, char *passwd, int *retcode"
+.Ft FILE *
+.Fn ftpPutURL "char *url, char *user, char *passwd, int *retcode"
+
+.Sh DESCRIPTION
+These functions implement a high-level library for managing FTP connections.
+.Pp
+.Fn ftpLogin
+attempts to log in using the supplied
+.Fa user ,
+.Fa passwd,
+.Fa ftp_port
+(if passed as 0,
+.Fa ftp_port
+defaults to the standard ftp port of 21) and
+.Fa verbose
+fields. If it is successful, a
+standard stream descriptor is returned which should be passed to
+subsequent FTP operations. On failure, NULL is returned and
+.Fa retcode
+will have the error code returned by the foreign server.
+.Pp
+.Fn ftpChdir
+attempts to issue a server CD command to the directory named in
+.Fa dir.
+On success, zero is returned. On failure, the error code from the server.
+.Pp
+.Fn ftpErrno
+returns the server failure code for the last operation (useful for seeing
+more about what happened if you're familiar with FTP error codes).
+.Fn ftpErrString
+returns a human readable version of the supplied server failure code.
+.Pp
+.Fn ftpGet
+attempts to retreive the file named by the
+.Fa file
+argument (which is assumed to be relative to the FTP server's current directory,
+see
+.Fn ftpChdir )
+and returns a new FILE* pointer for the file or NULL on failure. If
+.Fa seekto
+is non-NULL, the contents of the integer it points to will be used
+as a restart point for the file, that is to say that the stream
+returned will point
+.Fa *seekto
+bytes into the file gotten (this is handy for restarting failed
+transfers efficiently). If the seek operation fails, the value
+of
+.Fa *seekto
+will be zero'd.
+.Pp
+.Fn ftpGetModtime
+returns the last modification time of the file named by the
+.Fa file
+argument. If the file could not be opened or stat'd, 0 is returned.
+.Pp
+.Fn ftpGetSize
+returns the size in bytes of the file named by the
+.Fa file
+argument. If the file could not be opened or stat'd, -1 is returned.
+.Pp
+.Fn ftpPut
+attempts to create a new file named by the
+.Fa file
+argument (which is assumed to be relative to the FTP server's current directory,
+see
+.Fn ftpChdir )
+and returns a new
+.Fa stream
+pointer for the file or NULL on failure.
+.Pp
+.Fn ftpAscii
+sets ASCII mode for the current server connection named by
+.Fa stream .
+.Pp
+.Fn ftpBinary
+sets binary mode for the current server connection named by
+.Fa stream .
+.Pp
+.Fn ftpPassive
+sets passive mode (for firewalls) for the current server connection named by
+.Fa stream
+to boolean value
+.Fa status .
+.Pp
+.Fn ftpVerbose
+sets the verbosity mode for the current server connection named by
+.Fa stream
+to boolean value
+.Fa status .
+.Pp
+.Fn ftpGetURL
+attempts to retreive the file named by the supplied
+.Fa URL
+and can be considered equivalent to the combined
+.Fn ftpLogin ,
+.Fn ftpChdir
+and
+.Fn ftpGet
+operations except that no server
+.Fa stream
+is ever returned - the connection to the server closes when
+the file has been completely read. Use the lower-level routines
+if multiple gets are required as it will be far more efficient.
+.Pp
+.Fn ftpPutURL
+attempts to create the file named by the supplied
+.Fa URL
+and can be considered equivalent to the combined
+.Fn ftpLogin ,
+.Fn ftpChdir
+and
+.Fn ftpPut
+operations except that no server stream is ever returned - the connection
+to the server closes when the file has been completely written. Use the
+lower-level routines if multiple puts are required as it will be far more
+efficient.
+.Sh ENVIRONMENT
+.Bl -tag -width FTP_PASSIVE_MODE -offset 123
+.It Ev FTP_TIMEOUT
+Maximum time, in seconds, to wait for a response
+from the peer before aborting an
+.Tn FTP
+connection.
+.It Ev FTP_PASSIVE_MODE
+Force the use of passive mode
+.Tn FTP .
+.El
+.Sh BUGS
+I'm sure you can get this thing's internal state machine confused if
+you really work at it, but so far it's proven itself pretty robust in
+all my tests.
+.Sh HISTORY
+Started life as Poul-Henning Kamp's ftp driver for the system installation
+utility, later significantly mutated into a more general form as an
+extension of stdio by Jordan Hubbard. Also incorporates some ideas and
+extensions from Jean-Marc Zucconi.
+.Sh AUTHORS
+.An Jordan Hubbard ,
+.An Poul-Henning Kamp
+and
+.An Jean-Marc Zucconi
diff --git a/lib/libftpio/ftpio.c b/lib/libftpio/ftpio.c
new file mode 100644
index 0000000..35f2b15
--- /dev/null
+++ b/lib/libftpio/ftpio.c
@@ -0,0 +1,882 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * Major Changelog:
+ *
+ * Jordan K. Hubbard
+ * 17 Jan 1996
+ *
+ * Turned inside out. Now returns xfers as new file ids, not as a special
+ * `state' of FTP_t
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <ftpio.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define SUCCESS 0
+#define FAILURE -1
+
+#ifndef TRUE
+#define TRUE (1)
+#define FALSE (0)
+#endif
+
+/* How to see by a given code whether or not the connection has timed out */
+#define FTP_TIMEOUT(code) (FtpTimedOut || code == FTP_TIMED_OUT)
+
+/* Internal routines - deal only with internal FTP_t type */
+static FTP_t ftp_new(void);
+static void check_passive(FILE *fp);
+static int ftp_read_method(void *n, char *buf, int nbytes);
+static int ftp_write_method(void *n, const char *buf, int nbytes);
+static int ftp_close_method(void *n);
+static int writes(int fd, char *s);
+static __inline char *get_a_line(FTP_t ftp);
+static int get_a_number(FTP_t ftp, char **q);
+static int botch(char *func, char *botch_state);
+static int cmd(FTP_t ftp, const char *fmt, ...);
+static int ftp_login_session(FTP_t ftp, char *host, char *user, char *passwd, int port, int verbose);
+static int ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode, off_t *seekto);
+static int ftp_close(FTP_t ftp);
+static int get_url_info(char *url_in, char *host_ret, int *port_ret, char *name_ret);
+static void ftp_timeout(int sig);
+static void ftp_set_timeout(void);
+static void ftp_clear_timeout(void);
+
+
+/* Global status variable - ick */
+int FtpTimedOut;
+
+/* FTP happy status codes */
+#define FTP_GENERALLY_HAPPY 200
+#define FTP_ASCII_HAPPY FTP_GENERALLY_HAPPY
+#define FTP_BINARY_HAPPY FTP_GENERALLY_HAPPY
+#define FTP_PORT_HAPPY FTP_GENERALLY_HAPPY
+#define FTP_HAPPY_COMMENT 220
+#define FTP_QUIT_HAPPY 221
+#define FTP_TRANSFER_HAPPY 226
+#define FTP_PASSIVE_HAPPY 227
+#define FTP_CHDIR_HAPPY 250
+
+/* FTP unhappy status codes */
+#define FTP_TIMED_OUT 421
+
+/*
+ * XXX
+ * gross! evil! bad! We really need an access primitive for cookie in stdio itself.
+ * it's too convenient a hook to bury and it's already exported through funopen as it is, so...
+ * XXX
+ */
+#define fcookie(fp) ((fp)->_cookie)
+
+/* Placeholder in case we want to do any pre-init stuff at some point */
+int
+networkInit()
+{
+ return SUCCESS; /* XXX dummy function for now XXX */
+}
+
+/* Check a return code with some lenience for back-dated garbage that might be in the buffer */
+static int
+check_code(FTP_t ftp, int var, int preferred)
+{
+ ftp->error = 0;
+ while (1) {
+ if (var == preferred)
+ return 0;
+ else if (var == FTP_TRANSFER_HAPPY) /* last operation succeeded */
+ var = get_a_number(ftp, NULL);
+ else if (var == FTP_HAPPY_COMMENT) /* chit-chat */
+ var = get_a_number(ftp, NULL);
+ else if (var == FTP_GENERALLY_HAPPY) /* general success code */
+ var = get_a_number(ftp, NULL);
+ else {
+ ftp->error = var;
+ return 1;
+ }
+ }
+}
+
+int
+ftpAscii(FILE *fp)
+{
+ FTP_t ftp = fcookie(fp);
+ int i;
+
+ if (!ftp->is_binary)
+ return SUCCESS;
+ i = cmd(ftp, "TYPE A");
+ if (i < 0 || check_code(ftp, i, FTP_ASCII_HAPPY))
+ return i;
+ ftp->is_binary = FALSE;
+ return SUCCESS;
+}
+
+int
+ftpBinary(FILE *fp)
+{
+ FTP_t ftp = fcookie(fp);
+ int i;
+
+ if (ftp->is_binary)
+ return SUCCESS;
+ i = cmd(ftp, "TYPE I");
+ if (i < 0 || check_code(ftp, i, FTP_BINARY_HAPPY))
+ return i;
+ ftp->is_binary = TRUE;
+ return SUCCESS;
+}
+void
+ftpVerbose(FILE *fp, int status)
+{
+ FTP_t ftp = fcookie(fp);
+ ftp->is_verbose = status;
+}
+
+int
+ftpChdir(FILE *fp, char *dir)
+{
+ int i;
+ FTP_t ftp = fcookie(fp);
+
+ i = cmd(ftp, "CWD %s", dir);
+ if (i < 0 || check_code(ftp, i, FTP_CHDIR_HAPPY))
+ return i;
+ return SUCCESS;
+}
+
+int
+ftpErrno(FILE *fp)
+{
+ FTP_t ftp = fcookie(fp);
+ return ftp->error;
+}
+
+const char *
+ftpErrString(int error)
+{
+ int k;
+
+ if (error == -1)
+ return("connection in wrong state");
+ if (error < 100)
+ /* XXX soon UNIX errnos will catch up with FTP protocol errnos */
+ return strerror(error);
+ for (k = 0; k < ftpErrListLength; k++)
+ if (ftpErrList[k].num == error)
+ return(ftpErrList[k].string);
+ return("Unknown error");
+}
+
+off_t
+ftpGetSize(FILE *fp, char *name)
+{
+ int i;
+ char p[BUFSIZ], *cp, *ep;
+ FTP_t ftp = fcookie(fp);
+ off_t size;
+
+ check_passive(fp);
+ sprintf(p, "SIZE %s\r\n", name);
+ if (ftp->is_verbose)
+ fprintf(stderr, "Sending %s", p);
+ if (writes(ftp->fd_ctrl, p))
+ return (off_t)-1;
+ i = get_a_number(ftp, &cp);
+ if (check_code(ftp, i, 213))
+ return (off_t)-1;
+
+ errno = 0; /* to check for ERANGE */
+ size = (off_t)strtoq(cp, &ep, 10);
+ if (*ep != '\0' || errno == ERANGE)
+ return (off_t)-1;
+ return size;
+}
+
+time_t
+ftpGetModtime(FILE *fp, char *name)
+{
+ char p[BUFSIZ], *cp;
+ struct tm t;
+ time_t t0 = time (0);
+ FTP_t ftp = fcookie(fp);
+ int i;
+
+ check_passive(fp);
+ sprintf(p, "MDTM %s\r\n", name);
+ if (ftp->is_verbose)
+ fprintf(stderr, "Sending %s", p);
+ if (writes(ftp->fd_ctrl, p))
+ return (time_t)0;
+ i = get_a_number(ftp, &cp);
+ if (check_code(ftp, i, 213))
+ return (time_t)0;
+ while (*cp && !isdigit(*cp))
+ cp++;
+ if (!*cp)
+ return (time_t)0;
+ t0 = localtime (&t0)->tm_gmtoff;
+ sscanf(cp, "%04d%02d%02d%02d%02d%02d", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec);
+ t.tm_mon--;
+ t.tm_year -= 1900;
+ t.tm_isdst=-1;
+ t.tm_gmtoff = 0;
+ t0 += mktime (&t);
+ return t0;
+}
+
+FILE *
+ftpGet(FILE *fp, char *file, off_t *seekto)
+{
+ FILE *fp2;
+ FTP_t ftp = fcookie(fp);
+
+ check_passive(fp);
+ if (ftpBinary(fp) != SUCCESS)
+ return NULL;
+
+ if (ftp_file_op(ftp, "RETR", file, &fp2, "r", seekto) == SUCCESS)
+ return fp2;
+ return NULL;
+}
+
+/* Returns a standard FILE pointer type representing an open control connection */
+FILE *
+ftpLogin(char *host, char *user, char *passwd, int port, int verbose, int *retcode)
+{
+ FTP_t n;
+ FILE *fp;
+
+ if (retcode)
+ *retcode = 0;
+ if (networkInit() != SUCCESS)
+ return NULL;
+
+ n = ftp_new();
+ fp = NULL;
+ if (n && ftp_login_session(n, host, user, passwd, port, verbose) == SUCCESS) {
+ fp = funopen(n, ftp_read_method, ftp_write_method, NULL, ftp_close_method); /* BSD 4.4 function! */
+ fp->_file = n->fd_ctrl;
+ }
+ if (retcode) {
+ if (!n)
+ *retcode = (FtpTimedOut ? FTP_TIMED_OUT : -1);
+ /* Poor attempt at mapping real errnos to FTP error codes */
+ else switch(n->error) {
+ case EADDRNOTAVAIL:
+ *retcode = FTP_TIMED_OUT; /* Actually no such host, but we have no way of saying that. :-( */
+ break;
+
+ case ETIMEDOUT:
+ *retcode = FTP_TIMED_OUT;
+ break;
+
+ default:
+ *retcode = n->error;
+ break;
+ }
+ }
+ return fp;
+}
+
+FILE *
+ftpPut(FILE *fp, char *file)
+{
+ FILE *fp2;
+ FTP_t ftp = fcookie(fp);
+
+ check_passive(fp);
+ if (ftp_file_op(ftp, "STOR", file, &fp2, "w", NULL) == SUCCESS)
+ return fp2;
+ return NULL;
+}
+
+/* Unlike binary mode, passive mode is a toggle! :-( */
+int
+ftpPassive(FILE *fp, int st)
+{
+ FTP_t ftp = fcookie(fp);
+ int i;
+
+ if (ftp->is_passive == st)
+ return SUCCESS;
+ i = cmd(ftp, "PASV");
+ if (i < 0)
+ return i;
+ if (i != FTP_PASSIVE_HAPPY)
+ return FAILURE;
+ ftp->is_passive = !ftp->is_passive;
+ return SUCCESS;
+}
+
+FILE *
+ftpGetURL(char *url, char *user, char *passwd, int *retcode)
+{
+ char host[255], name[255];
+ int port;
+ FILE *fp2;
+ static FILE *fp = NULL;
+ static char *prev_host;
+
+ if (retcode)
+ *retcode = 0;
+ if (get_url_info(url, host, &port, name) == SUCCESS) {
+ if (fp && prev_host) {
+ if (!strcmp(prev_host, host)) {
+ /* Try to use cached connection */
+ fp2 = ftpGet(fp, name, NULL);
+ if (!fp2) {
+ /* Connection timed out or was no longer valid */
+ fclose(fp);
+ free(prev_host);
+ prev_host = NULL;
+ }
+ else
+ return fp2;
+ }
+ else {
+ /* It's a different host now, flush old */
+ fclose(fp);
+ free(prev_host);
+ prev_host = NULL;
+ }
+ }
+ fp = ftpLogin(host, user, passwd, port, 0, retcode);
+ if (fp) {
+ fp2 = ftpGet(fp, name, NULL);
+ if (!fp2) {
+ /* Connection timed out or was no longer valid */
+ if (retcode)
+ *retcode = ftpErrno(fp);
+ fclose(fp);
+ fp = NULL;
+ }
+ else
+ prev_host = strdup(host);
+ return fp2;
+ }
+ }
+ return NULL;
+}
+
+FILE *
+ftpPutURL(char *url, char *user, char *passwd, int *retcode)
+{
+ char host[255], name[255];
+ int port;
+ static FILE *fp = NULL;
+ FILE *fp2;
+
+ if (retcode)
+ *retcode = 0;
+ if (fp) { /* Close previous managed connection */
+ fclose(fp);
+ fp = NULL;
+ }
+ if (get_url_info(url, host, &port, name) == SUCCESS) {
+ fp = ftpLogin(host, user, passwd, port, 0, retcode);
+ if (fp) {
+ fp2 = ftpPut(fp, name);
+ if (!fp2) {
+ if (retcode)
+ *retcode = ftpErrno(fp);
+ fclose(fp);
+ fp = NULL;
+ }
+ return fp2;
+ }
+ }
+ return NULL;
+}
+
+/* Internal workhorse function for dissecting URLs. Takes a URL as the first argument and returns the
+ result of such disection in the host, user, passwd, port and name variables. */
+static int
+get_url_info(char *url_in, char *host_ret, int *port_ret, char *name_ret)
+{
+ char *name, *host, *cp, url[BUFSIZ];
+ int port;
+
+ name = host = NULL;
+ /* XXX add http:// here or somewhere reasonable at some point XXX */
+ if (strncmp("ftp://", url_in, 6) != 0)
+ return FAILURE;
+ /* We like to stomp a lot on the URL string in dissecting it, so copy it first */
+ strncpy(url, url_in, BUFSIZ);
+ host = url + 6;
+ if ((cp = index(host, ':')) != NULL) {
+ *(cp++) = '\0';
+ port = strtol(cp, 0, 0);
+ }
+ else
+ port = 0; /* use default */
+ if (port_ret)
+ *port_ret = port;
+
+ if ((name = index(cp ? cp : host, '/')) != NULL)
+ *(name++) = '\0';
+ if (host_ret)
+ strcpy(host_ret, host);
+ if (name && name_ret)
+ strcpy(name_ret, name);
+ return SUCCESS;
+}
+
+static FTP_t
+ftp_new(void)
+{
+ FTP_t ftp;
+
+ ftp = (FTP_t)malloc(sizeof *ftp);
+ if (!ftp)
+ return NULL;
+ memset(ftp, 0, sizeof *ftp);
+ ftp->fd_ctrl = -1;
+ ftp->con_state = init;
+ ftp->is_binary = FALSE;
+ ftp->is_passive = FALSE;
+ ftp->is_verbose = FALSE;
+ ftp->error = 0;
+ return ftp;
+}
+
+static int
+ftp_read_method(void *vp, char *buf, int nbytes)
+{
+ int i, fd;
+ FTP_t n = (FTP_t)vp;
+
+ fd = n->fd_ctrl;
+ i = (fd >= 0) ? read(fd, buf, nbytes) : EOF;
+ return i;
+}
+
+static int
+ftp_write_method(void *vp, const char *buf, int nbytes)
+{
+ int i, fd;
+ FTP_t n = (FTP_t)vp;
+
+ fd = n->fd_ctrl;
+ i = (fd >= 0) ? write(fd, buf, nbytes) : EOF;
+ return i;
+}
+
+static int
+ftp_close_method(void *n)
+{
+ int i;
+
+ i = ftp_close((FTP_t)n);
+ free(n);
+ return i;
+}
+
+static void
+check_passive(FILE *fp)
+{
+ if (getenv("FTP_PASSIVE_MODE"))
+ ftpPassive(fp, TRUE);
+}
+
+static void
+ftp_timeout(int sig)
+{
+ FtpTimedOut = TRUE;
+ /* Debug("ftp_pkg: ftp_timeout called - operation timed out"); */
+}
+
+static void
+ftp_set_timeout(void)
+{
+ struct sigaction new;
+ char *cp;
+ int ival;
+
+ FtpTimedOut = FALSE;
+ sigemptyset(&new.sa_mask);
+ new.sa_flags = 0;
+ new.sa_handler = ftp_timeout;
+ sigaction(SIGALRM, &new, NULL);
+ cp = getenv("FTP_TIMEOUT");
+ if (!cp || !(ival = atoi(cp)))
+ ival = 120;
+ alarm(ival);
+}
+
+static void
+ftp_clear_timeout(void)
+{
+ struct sigaction new;
+
+ alarm(0);
+ sigemptyset(&new.sa_mask);
+ new.sa_flags = 0;
+ new.sa_handler = SIG_DFL;
+ sigaction(SIGALRM, &new, NULL);
+}
+
+static int
+writes(int fd, char *s)
+{
+ int n, i = strlen(s);
+
+ ftp_set_timeout();
+ n = write(fd, s, i);
+ ftp_clear_timeout();
+ if (FtpTimedOut || i != n)
+ return TRUE;
+ return FALSE;
+}
+
+static __inline char *
+get_a_line(FTP_t ftp)
+{
+ static char buf[BUFSIZ];
+ int i,j;
+
+ /* Debug("ftp_pkg: trying to read a line from %d", ftp->fd_ctrl); */
+ for(i = 0; i < BUFSIZ;) {
+ ftp_set_timeout();
+ j = read(ftp->fd_ctrl, buf + i, 1);
+ ftp_clear_timeout();
+ if (FtpTimedOut || j != 1)
+ return NULL;
+ if (buf[i] == '\r' || buf[i] == '\n') {
+ if (!i)
+ continue;
+ buf[i] = '\0';
+ if (ftp->is_verbose == TRUE)
+ fprintf(stderr, "%s\n",buf+4);
+ return buf;
+ }
+ i++;
+ }
+ /* Debug("ftp_pkg: read string \"%s\" from %d", buf, ftp->fd_ctrl); */
+ return buf;
+}
+
+static int
+get_a_number(FTP_t ftp, char **q)
+{
+ char *p;
+ int i = -1, j;
+
+ while(1) {
+ p = get_a_line(ftp);
+ if (!p) {
+ ftp_close(ftp);
+ if (FtpTimedOut)
+ return FTP_TIMED_OUT;
+ return FAILURE;
+ }
+ if (!(isdigit(p[0]) && isdigit(p[1]) && isdigit(p[2])))
+ continue;
+ if (i == -1 && p[3] == '-') {
+ i = strtol(p, 0, 0);
+ continue;
+ }
+ if (p[3] != ' ' && p[3] != '\t')
+ continue;
+ j = strtol(p, 0, 0);
+ if (i == -1) {
+ if (q) *q = p+4;
+ /* Debug("ftp_pkg: read reply %d from server (%s)", j, p); */
+ return j;
+ } else if (j == i) {
+ if (q) *q = p+4;
+ /* Debug("ftp_pkg: read reply %d from server (%s)", j, p); */
+ return j;
+ }
+ }
+}
+
+static int
+ftp_close(FTP_t ftp)
+{
+ int i, rcode;
+
+ rcode = FAILURE;
+ if (ftp->con_state == isopen) {
+ ftp->con_state = quit;
+ /* If last operation timed out, don't try to quit - just close */
+ if (ftp->error != FTP_TIMED_OUT)
+ i = cmd(ftp, "QUIT");
+ else
+ i = FTP_QUIT_HAPPY;
+ if (!check_code(ftp, i, FTP_QUIT_HAPPY))
+ rcode = SUCCESS;
+ close(ftp->fd_ctrl);
+ ftp->fd_ctrl = -1;
+ }
+ else if (ftp->con_state == quit)
+ rcode = SUCCESS;
+ return rcode;
+}
+
+static int
+botch(char *func, char *botch_state)
+{
+ /* Debug("ftp_pkg: botch: %s(%s)", func, botch_state); */
+ return FAILURE;
+}
+
+static int
+cmd(FTP_t ftp, const char *fmt, ...)
+{
+ char p[BUFSIZ];
+ int i;
+
+ va_list ap;
+ va_start(ap, fmt);
+ (void)vsnprintf(p, sizeof p, fmt, ap);
+ va_end(ap);
+
+ if (ftp->con_state == init)
+ return botch("cmd", "open");
+
+ strcat(p, "\r\n");
+ if (ftp->is_verbose)
+ fprintf(stderr, "Sending: %s", p);
+ if (writes(ftp->fd_ctrl, p)) {
+ if (FtpTimedOut)
+ return FTP_TIMED_OUT;
+ return FAILURE;
+ }
+ while ((i = get_a_number(ftp, NULL)) == FTP_HAPPY_COMMENT);
+ return i;
+}
+
+static int
+ftp_login_session(FTP_t ftp, char *host, char *user, char *passwd, int port, int verbose)
+{
+ struct hostent *he = NULL;
+ struct sockaddr_in sin;
+ int s;
+ unsigned long temp;
+ int i;
+
+ if (networkInit() != SUCCESS)
+ return FAILURE;
+
+ if (ftp->con_state != init) {
+ ftp_close(ftp);
+ ftp->error = -1;
+ return FAILURE;
+ }
+
+ if (!user)
+ user = "ftp";
+
+ if (!passwd)
+ passwd = "setup@";
+
+ if (!port)
+ port = 21;
+
+ temp = inet_addr(host);
+ if (temp != INADDR_NONE) {
+ ftp->addrtype = sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = temp;
+ }
+ else {
+ he = gethostbyname(host);
+ if (!he) {
+ ftp->error = 0;
+ return FAILURE;
+ }
+ ftp->addrtype = sin.sin_family = he->h_addrtype;
+ bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length);
+ }
+
+ sin.sin_port = htons(port);
+
+ if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) {
+ ftp->error = -1;
+ return FAILURE;
+ }
+
+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+ (void)close(s);
+ ftp->error = errno;
+ return FAILURE;
+ }
+
+ ftp->fd_ctrl = s;
+ ftp->con_state = isopen;
+ ftp->is_verbose = verbose;
+
+ i = cmd(ftp, "USER %s", user);
+ if (i >= 300 && i < 400)
+ i = cmd(ftp, "PASS %s", passwd);
+ if (i >= 299 || i < 0) {
+ ftp_close(ftp);
+ if (i > 0)
+ ftp->error = i;
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+static int
+ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode, off_t *seekto)
+{
+ int i,s;
+ char *q;
+ unsigned char addr[64];
+ struct sockaddr_in sin;
+ u_long a;
+
+ if (!fp)
+ return FAILURE;
+ *fp = NULL;
+
+ if (ftp->con_state != isopen)
+ return botch("ftp_file_op", "open");
+
+ if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) {
+ ftp->error = errno;
+ return FAILURE;
+ }
+
+ if (ftp->is_passive) {
+ if (ftp->is_verbose)
+ fprintf(stderr, "Sending PASV\n");
+ if (writes(ftp->fd_ctrl, "PASV\r\n")) {
+ ftp_close(ftp);
+ if (FtpTimedOut)
+ ftp->error = FTP_TIMED_OUT;
+ return FTP_TIMED_OUT;
+ }
+ i = get_a_number(ftp, &q);
+ if (check_code(ftp, i, FTP_PASSIVE_HAPPY)) {
+ ftp_close(ftp);
+ return i;
+ }
+ while (*q && !isdigit(*q))
+ q++;
+ if (!*q) {
+ ftp_close(ftp);
+ return FAILURE;
+ }
+ q--;
+ for (i = 0; i < 6; i++) {
+ q++;
+ addr[i] = strtol(q, &q, 10);
+ }
+
+ sin.sin_family = ftp->addrtype;
+ bcopy(addr, (char *)&sin.sin_addr, 4);
+ bcopy(addr + 4, (char *)&sin.sin_port, 2);
+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+ (void)close(s);
+ return FAILURE;
+ }
+
+ if (seekto && *seekto) {
+ i = cmd(ftp, "REST %d", *seekto);
+ if (i < 0 || FTP_TIMEOUT(i)) {
+ close(s);
+ ftp->error = i;
+ *seekto = (off_t)0;
+ return i;
+ }
+ }
+ i = cmd(ftp, "%s %s", operation, file);
+ if (i < 0 || i > 299) {
+ close(s);
+ ftp->error = i;
+ return i;
+ }
+ *fp = fdopen(s, mode);
+ }
+ else {
+ int fd,portrange;
+
+#ifdef IP_PORTRANGE
+ portrange = IP_PORTRANGE_HIGH;
+ if (setsockopt(s, IPPROTO_IP, IP_PORTRANGE, (char *)
+ &portrange, sizeof(portrange)) < 0) {
+ close(s);
+ return FAILURE;
+ };
+#endif
+
+ i = sizeof sin;
+ getsockname(ftp->fd_ctrl, (struct sockaddr *)&sin, &i);
+ sin.sin_port = 0;
+ i = sizeof sin;
+ if (bind(s, (struct sockaddr *)&sin, i) < 0) {
+ close(s);
+ return FAILURE;
+ }
+ getsockname(s,(struct sockaddr *)&sin,&i);
+ if (listen(s, 1) < 0) {
+ close(s);
+ return FAILURE;
+ }
+ a = ntohl(sin.sin_addr.s_addr);
+ i = cmd(ftp, "PORT %d,%d,%d,%d,%d,%d",
+ (a >> 24) & 0xff,
+ (a >> 16) & 0xff,
+ (a >> 8) & 0xff,
+ a & 0xff,
+ (ntohs(sin.sin_port) >> 8) & 0xff,
+ ntohs(sin.sin_port) & 0xff);
+ if (check_code(ftp, i, FTP_PORT_HAPPY)) {
+ close(s);
+ return i;
+ }
+ if (seekto && *seekto) {
+ i = cmd(ftp, "REST %d", *seekto);
+ if (i < 0 || FTP_TIMEOUT(i)) {
+ close(s);
+ ftp->error = i;
+ return i;
+ }
+ else if (i != 350)
+ *seekto = (off_t)0;
+ }
+ i = cmd(ftp, "%s %s", operation, file);
+ if (i < 0 || i > 299) {
+ close(s);
+ ftp->error = i;
+ return FAILURE;
+ }
+ fd = accept(s, 0, 0);
+ if (fd < 0) {
+ close(s);
+ ftp->error = 401;
+ return FAILURE;
+ }
+ close(s);
+ *fp = fdopen(fd, mode);
+ }
+ if (*fp)
+ return SUCCESS;
+ else
+ return FAILURE;
+}
diff --git a/lib/libftpio/ftpio.h b/lib/libftpio/ftpio.h
new file mode 100644
index 0000000..26d4f90
--- /dev/null
+++ b/lib/libftpio/ftpio.h
@@ -0,0 +1,68 @@
+#ifndef _FTP_H_INCLUDE
+#define _FTP_H_INCLUDE
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <stdio.h>
+#include <time.h>
+
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * Major Changelog:
+ *
+ * Jordan K. Hubbard
+ * 17 Jan 1996
+ *
+ * Turned inside out. Now returns xfers as new file ids, not as a special
+ * `state' of FTP_t
+ *
+ * $FreeBSD$
+ */
+
+/* Internal housekeeping data structure for FTP sessions */
+typedef struct {
+ enum { init, isopen, quit } con_state;
+ int fd_ctrl;
+ int addrtype;
+ char *host;
+ char *file;
+ int error;
+ int is_binary;
+ int is_passive;
+ int is_verbose;
+} *FTP_t;
+
+/* Structure we use to match FTP error codes with readable strings */
+struct ftperr {
+ const int num;
+ const char *string;
+};
+
+__BEGIN_DECLS
+extern struct ftperr ftpErrList[];
+extern int const ftpErrListLength;
+
+/* Exported routines - deal only with FILE* type */
+extern FILE *ftpLogin(char *host, char *user, char *passwd, int port, int verbose, int *retcode);
+extern int ftpChdir(FILE *fp, char *dir);
+extern int ftpErrno(FILE *fp);
+extern off_t ftpGetSize(FILE *fp, char *file);
+extern FILE *ftpGet(FILE *fp, char *file, off_t *seekto);
+extern FILE *ftpPut(FILE *fp, char *file);
+extern int ftpAscii(FILE *fp);
+extern int ftpBinary(FILE *fp);
+extern int ftpPassive(FILE *fp, int status);
+extern void ftpVerbose(FILE *fp, int status);
+extern FILE *ftpGetURL(char *url, char *user, char *passwd, int *retcode);
+extern FILE *ftpPutURL(char *url, char *user, char *passwd, int *retcode);
+extern time_t ftpGetModtime(FILE *fp, char *s);
+extern const char *ftpErrString(int error);
+__END_DECLS
+
+#endif /* _FTP_H_INCLUDE */
diff --git a/lib/libgnumalloc/Makefile b/lib/libgnumalloc/Makefile
new file mode 100644
index 0000000..cddf5ba
--- /dev/null
+++ b/lib/libgnumalloc/Makefile
@@ -0,0 +1,37 @@
+# $FreeBSD$
+
+LIB= gnumalloc
+INTERNALLIB= yes # Do not build or install ${LIB}*.a
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 0
+
+SRCS= cfree.c
+
+.if ${OBJFORMAT} != aout
+NOPIC= true
+.endif
+
+#
+# Before complaining about this, please *double-check* that you have
+# updated the ldconfig path in /etc/rc to include /usr/lib/compat that
+# was added in src/etc/rc rev 1.98.
+# This is so that programs that use autoconf will not "detect" -lgnumalloc
+# and continue to propagate the bogosity. The ldconfig path fix will enable
+# you to run programs that were linked with -lgnumalloc (such as XFree86).
+#
+beforeinstall:
+ rm -f ${DESTDIR}${LIBDIR}/lib${LIB}.a \
+ ${DESTDIR}${LIBDIR}/lib${LIB}_p.a \
+ ${DESTDIR}${ORIG_SHLIBDIR}/lib${LIB}.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ ${DESTDIR}/usr/lib/compat/lib${LIB}.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ ${DESTDIR}/usr/lib/compat/lib${LIB}.so.${SHLIB_MAJOR} \
+ ${DESTDIR}/usr/lib/compat/lib${LIB}.so \
+
+.include <bsd.lib.mk>
+
+# This must follow the .include in case SHLIBDIR is defined there.
+ORIG_SHLIBDIR:= ${SHLIBDIR}
+
+# The ldconfig line in/etc/rc doesn't depend on ${LIBDIR} or ${SHLIBDIR},
+# so neither does this.
+SHLIBDIR= /usr/lib/compat/aout
diff --git a/lib/libgnumalloc/cfree.c b/lib/libgnumalloc/cfree.c
new file mode 100644
index 0000000..5191fd6
--- /dev/null
+++ b/lib/libgnumalloc/cfree.c
@@ -0,0 +1,5 @@
+void
+cfree(void *foo)
+{
+ free(foo);
+}
diff --git a/lib/libio/Makefile b/lib/libio/Makefile
new file mode 100644
index 0000000..71e1c9e
--- /dev/null
+++ b/lib/libio/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+LIB= io
+SHLIB_MAJOR= 1
+SRCS= io.c swiz.c bwx.c alpha_sethae.c
+
+CFLAGS+= -Wall -Wa,-mev56
+
+NOMAN=1
+
+.include <bsd.lib.mk>
diff --git a/lib/libio/alpha_sethae.c b/lib/libio/alpha_sethae.c
new file mode 100644
index 0000000..337cafa
--- /dev/null
+++ b/lib/libio/alpha_sethae.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$FreeBSD$";
+#endif /* LIBC_RCS and not lint */
+
+#include <sys/types.h>
+#include <machine/sysarch.h>
+
+extern int sysarch(int, char *);
+
+struct parms {
+ u_int64_t hae;
+};
+
+int
+alpha_sethae(u_int64_t hae)
+{
+ struct parms p;
+
+ p.hae = hae;
+
+ return (sysarch(ALPHA_SETHAE, (char *)&p));
+}
diff --git a/lib/libio/bwx.c b/lib/libio/bwx.c
new file mode 100644
index 0000000..bc3bbb3
--- /dev/null
+++ b/lib/libio/bwx.c
@@ -0,0 +1,242 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/fcntl.h>
+#include <sys/sysctl.h>
+#include <err.h>
+#include <machine/bwx.h>
+#include <machine/sysarch.h>
+#include <stdlib.h>
+#include "io.h"
+
+#define mb() __asm__ __volatile__("mb" : : : "memory")
+#define wmb() __asm__ __volatile__("wmb" : : : "memory")
+
+static int mem_fd; /* file descriptor to /dev/mem */
+static void *bwx_int1_ports; /* mapped int1 io ports */
+static void *bwx_int2_ports; /* mapped int2 io ports */
+static void *bwx_int4_ports; /* mapped int4 io ports */
+static u_int64_t bwx_io_base; /* physical address of ports */
+static u_int64_t bwx_mem_base; /* physical address of bwx mem */
+
+static void
+bwx_init()
+{
+ size_t len = sizeof(u_int64_t);
+ int error;
+
+ mem_fd = open("/dev/mem", O_RDWR);
+ if (mem_fd < 0)
+ err(1, "/dev/mem");
+ bwx_int1_ports = mmap(0, 1L<<32, PROT_READ, MAP_ANON, -1, 0);
+ bwx_int2_ports = mmap(0, 1L<<32, PROT_READ, MAP_ANON, -1, 0);
+ bwx_int4_ports = mmap(0, 1L<<32, PROT_READ, MAP_ANON, -1, 0);
+
+ if ((error = sysctlbyname("hw.chipset.ports", &bwx_io_base, &len,
+ 0, 0)) < 0)
+ err(1, "hw.chipset.ports");
+ if ((error = sysctlbyname("hw.chipset.memory", &bwx_mem_base, &len,
+ 0, 0)) < 0)
+ err(1, "hw.chipset.memory");
+}
+
+static int
+bwx_ioperm(u_int32_t from, u_int32_t num, int on)
+{
+ u_int32_t start, end;
+
+ if (!bwx_int1_ports)
+ bwx_init();
+
+ if (!on)
+ return -1; /* XXX can't unmap yet */
+
+ start = trunc_page(from);
+ end = round_page(from + num);
+
+ munmap(bwx_int1_ports + start, end-start);
+ munmap(bwx_int2_ports + start, end-start);
+ munmap(bwx_int4_ports + start, end-start);
+ mmap(bwx_int1_ports + start, end-start, PROT_READ|PROT_WRITE, MAP_SHARED,
+ mem_fd, bwx_io_base + BWX_EV56_INT1 + start);
+ mmap(bwx_int2_ports + start, end-start, PROT_READ|PROT_WRITE, MAP_SHARED,
+ mem_fd, bwx_io_base + BWX_EV56_INT2 + start);
+ mmap(bwx_int4_ports + start, end-start, PROT_READ|PROT_WRITE, MAP_SHARED,
+ mem_fd, bwx_io_base + BWX_EV56_INT4 + start);
+ return 0;
+}
+
+static u_int8_t
+bwx_inb(u_int32_t port)
+{
+ mb();
+ return ldbu((vm_offset_t)bwx_int1_ports + port);
+}
+
+static u_int16_t
+bwx_inw(u_int32_t port)
+{
+ mb();
+ return ldwu((vm_offset_t)bwx_int2_ports + port);
+}
+
+static u_int32_t
+bwx_inl(u_int32_t port)
+{
+ mb();
+ return ldl((vm_offset_t)bwx_int4_ports + port);
+}
+
+static void
+bwx_outb(u_int32_t port, u_int8_t val)
+{
+ stb((vm_offset_t)bwx_int1_ports + port, val);
+ wmb();
+}
+
+static void
+bwx_outw(u_int32_t port, u_int16_t val)
+{
+ stw((vm_offset_t)bwx_int2_ports + port, val);
+ wmb();
+}
+
+static void
+bwx_outl(u_int32_t port, u_int32_t val)
+{
+ stl((vm_offset_t)bwx_int4_ports + port, val);
+ wmb();
+}
+
+struct bwx_mem_handle {
+ void *virt1; /* int1 address in user address-space */
+ void *virt2; /* int2 address in user address-space */
+ void *virt4; /* int4 address in user address-space */
+};
+
+static void *
+bwx_map_memory(u_int32_t address, u_int32_t size)
+{
+ struct bwx_mem_handle *h;
+ h = malloc(sizeof(struct bwx_mem_handle));
+ if (!h) return 0;
+ h->virt1 = mmap(0, size << 5, PROT_READ|PROT_WRITE, MAP_SHARED,
+ mem_fd, bwx_mem_base + BWX_EV56_INT1 + address);
+ if ((long) h->virt1 == -1) {
+ free(h);
+ return 0;
+ }
+ h->virt2 = mmap(0, size << 5, PROT_READ|PROT_WRITE, MAP_SHARED,
+ mem_fd, bwx_mem_base + BWX_EV56_INT2 + address);
+ if ((long) h->virt2 == -1) {
+ munmap(h->virt1, size);
+ free(h);
+ return 0;
+ }
+ h->virt4 = mmap(0, size << 5, PROT_READ|PROT_WRITE, MAP_SHARED,
+ mem_fd, bwx_mem_base + BWX_EV56_INT4 + address);
+ if ((long) h->virt4 == -1) {
+ munmap(h->virt1, size);
+ munmap(h->virt2, size);
+ free(h);
+ return 0;
+ }
+ return h;
+}
+
+static void
+bwx_unmap_memory(void *handle, u_int32_t size)
+{
+ struct bwx_mem_handle *h = handle;
+ munmap(h->virt1, size);
+ munmap(h->virt2, size);
+ munmap(h->virt4, size);
+ free(h);
+}
+
+static u_int8_t
+bwx_readb(void *handle, u_int32_t offset)
+{
+ struct bwx_mem_handle *h = handle;
+ return ldbu((vm_offset_t)h->virt1 + offset);
+}
+
+static u_int16_t
+bwx_readw(void *handle, u_int32_t offset)
+{
+ struct bwx_mem_handle *h = handle;
+ return ldwu((vm_offset_t)h->virt2 + offset);
+}
+
+static u_int32_t
+bwx_readl(void *handle, u_int32_t offset)
+{
+ struct bwx_mem_handle *h = handle;
+ return ldl((vm_offset_t)h->virt4 + offset);
+}
+
+static void
+bwx_writeb(void *handle, u_int32_t offset, u_int8_t val)
+{
+ struct bwx_mem_handle *h = handle;
+ stb((vm_offset_t)h->virt1 + offset, val);
+}
+
+static void
+bwx_writew(void *handle, u_int32_t offset, u_int16_t val)
+{
+ struct bwx_mem_handle *h = handle;
+ stw((vm_offset_t)h->virt2 + offset, val);
+}
+
+static void
+bwx_writel(void *handle, u_int32_t offset, u_int32_t val)
+{
+ struct bwx_mem_handle *h = handle;
+ stl((vm_offset_t)h->virt4 + offset, val);
+}
+
+struct io_ops bwx_io_ops = {
+ bwx_ioperm,
+ bwx_inb,
+ bwx_inw,
+ bwx_inl,
+ bwx_outb,
+ bwx_outw,
+ bwx_outl,
+ bwx_map_memory,
+ bwx_unmap_memory,
+ bwx_readb,
+ bwx_readw,
+ bwx_readl,
+ bwx_writeb,
+ bwx_writew,
+ bwx_writel,
+};
diff --git a/lib/libio/io.c b/lib/libio/io.c
new file mode 100644
index 0000000..7abfa36
--- /dev/null
+++ b/lib/libio/io.c
@@ -0,0 +1,151 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <err.h>
+#include "io.h"
+
+static struct io_ops *ops;
+
+int
+ioperm(unsigned long from, unsigned long num, int on)
+{
+ int error;
+ int bwx;
+ size_t len = sizeof(bwx);
+
+ if ((error = sysctlbyname("hw.chipset.bwx", &bwx, &len, 0, 0)) < 0)
+ return error;
+ if (bwx)
+ ops = &bwx_io_ops;
+ else
+ ops = &swiz_io_ops;
+
+ return ops->ioperm(from, num, on);
+}
+
+u_int8_t
+inb(u_int32_t port)
+{
+ return ops->inb(port);
+}
+
+u_int16_t
+inw(u_int32_t port)
+{
+ return ops->inw(port);
+}
+
+u_int32_t
+inl(u_int32_t port)
+{
+ return ops->inl(port);
+}
+
+void
+outb(u_int32_t port, u_int8_t val)
+{
+ ops->outb(port, val);
+}
+
+void
+outw(u_int32_t port, u_int16_t val)
+{
+ ops->outw(port, val);
+}
+
+void
+outl(u_int32_t port, u_int32_t val)
+{
+ ops->outl(port, val);
+}
+
+void *
+map_memory(u_int32_t address, u_int32_t size)
+{
+ return ops->map_memory(address, size);
+}
+
+void
+unmap_memory(void *handle, u_int32_t size)
+{
+ ops->unmap_memory(handle, size);
+}
+
+u_int8_t
+readb(void *handle, u_int32_t offset)
+{
+ return ops->readb(handle, offset);
+}
+
+u_int16_t
+readw(void *handle, u_int32_t offset)
+{
+ return ops->readw(handle, offset);
+}
+
+u_int32_t
+readl(void *handle, u_int32_t offset)
+{
+ return ops->readl(handle, offset);
+}
+
+void
+writeb(void *handle, u_int32_t offset, u_int8_t val)
+{
+ return ops->writeb(handle, offset, val);
+}
+
+void
+writew(void *handle, u_int32_t offset, u_int16_t val)
+{
+ return ops->writew(handle, offset, val);
+}
+
+void
+writel(void *handle, u_int32_t offset, u_int32_t val)
+{
+ return ops->writel(handle, offset, val);
+}
+
+u_int64_t
+dense_base(void)
+{
+ static u_int64_t base = 0;
+
+ if (base == 0) {
+ size_t len = sizeof(base);
+ int error;
+ if ((error = sysctlbyname("hw.chipset.dense", &base, &len,
+ 0, 0)) < 0)
+ err(1, "hw.chipset.dense");
+ }
+
+ return base;
+}
diff --git a/lib/libio/io.h b/lib/libio/io.h
new file mode 100644
index 0000000..1f4c620
--- /dev/null
+++ b/lib/libio/io.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+struct io_ops {
+ int (*ioperm)(u_int32_t, u_int32_t, int);
+ u_int8_t (*inb)(u_int32_t);
+ u_int16_t (*inw)(u_int32_t);
+ u_int32_t (*inl)(u_int32_t);
+ void (*outb)(u_int32_t, u_int8_t);
+ void (*outw)(u_int32_t, u_int16_t);
+ void (*outl)(u_int32_t, u_int32_t);
+ void * (*map_memory)(u_int32_t, u_int32_t);
+ void (*unmap_memory)(void *, u_int32_t);
+ u_int8_t (*readb)(void *, u_int32_t);
+ u_int16_t (*readw)(void *, u_int32_t);
+ u_int32_t (*readl)(void *, u_int32_t);
+ void (*writeb)(void *, u_int32_t, u_int8_t);
+ void (*writew)(void *, u_int32_t, u_int16_t);
+ void (*writel)(void *, u_int32_t, u_int32_t);
+};
+
+extern struct io_ops swiz_io_ops;
+extern struct io_ops bwx_io_ops;
diff --git a/lib/libio/swiz.c b/lib/libio/swiz.c
new file mode 100644
index 0000000..bee9f6d
--- /dev/null
+++ b/lib/libio/swiz.c
@@ -0,0 +1,246 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/fcntl.h>
+#include <sys/sysctl.h>
+#include <err.h>
+#include <machine/swiz.h>
+#include <machine/sysarch.h>
+#include <stdlib.h>
+#include "io.h"
+
+#define mb() __asm__ __volatile__("mb" : : : "memory")
+#define wmb() __asm__ __volatile__("wmb" : : : "memory")
+
+static int mem_fd; /* file descriptor to /dev/mem */
+static void *swiz_ports; /* mapped io ports */
+static u_int64_t swiz_io_base; /* physical address of ports */
+static u_int64_t swiz_mem_base; /* physical address of sparse mem */
+static u_int64_t swiz_dense_base; /* physical address of dense mem */
+static u_int64_t swiz_hae_mask; /* mask address bits for hae */
+static u_int32_t swiz_hae; /* cache of current hae */
+
+static void
+swiz_init()
+{
+
+ size_t len = sizeof(u_int64_t);
+ int error;
+
+ mem_fd = open("/dev/mem", O_RDWR);
+ if (mem_fd < 0)
+ err(1, "/dev/mem");
+ swiz_ports = mmap(0, 1L<<32, PROT_READ, MAP_ANON, -1, 0);
+
+ if ((error = sysctlbyname("hw.chipset.ports", &swiz_io_base, &len,
+ 0, 0)) < 0)
+ err(1, "hw.chipset.ports");
+ if ((error = sysctlbyname("hw.chipset.memory", &swiz_mem_base, &len,
+ 0, 0)) < 0)
+ err(1, "hw.chipset.memory");
+ if ((error = sysctlbyname("hw.chipset.dense", &swiz_dense_base, &len,
+ 0, 0)) < 0)
+ err(1, "hw.chipset.memory");
+ if ((error = sysctlbyname("hw.chipset.hae_mask", &swiz_hae_mask, &len,
+ 0, 0)) < 0)
+ err(1, "hw.chipset.memory");
+
+}
+
+static int
+swiz_ioperm(u_int32_t from, u_int32_t num, int on)
+{
+ u_int64_t start, end;
+ void *addr;
+
+ if (!swiz_ports)
+ swiz_init();
+
+ if (!on)
+ return -1; /* XXX can't unmap yet */
+
+ start = trunc_page(from << 5);
+ end = round_page((from + num) << 5);
+ addr = swiz_ports + start;
+ munmap(addr, end - start);
+ mmap(addr, end - start, PROT_READ|PROT_WRITE, MAP_SHARED,
+ mem_fd, swiz_io_base + start);
+ return 0;
+}
+
+static u_int8_t
+swiz_inb(u_int32_t port)
+{
+ mb();
+ return SPARSE_READ_BYTE(swiz_ports, port);
+}
+
+static u_int16_t
+swiz_inw(u_int32_t port)
+{
+ mb();
+ return SPARSE_READ_WORD(swiz_ports, port);
+}
+
+static u_int32_t
+swiz_inl(u_int32_t port)
+{
+ mb();
+ return SPARSE_READ_LONG(swiz_ports, port);
+}
+
+static void
+swiz_outb(u_int32_t port, u_int8_t val)
+{
+ SPARSE_WRITE_BYTE(swiz_ports, port, val);
+ wmb();
+}
+
+static void
+swiz_outw(u_int32_t port, u_int16_t val)
+{
+ SPARSE_WRITE_WORD(swiz_ports, port, val);
+ wmb();
+}
+
+static void
+swiz_outl(u_int32_t port, u_int32_t val)
+{
+ SPARSE_WRITE_LONG(swiz_ports, port, val);
+ wmb();
+}
+
+struct swiz_mem_handle {
+ u_int32_t phys; /* address in PCI address-space */
+ void *virt; /* address in user address-space */
+ u_int32_t size; /* size of mapped region */
+};
+
+static void *
+swiz_map_memory(u_int32_t address, u_int32_t size)
+{
+ struct swiz_mem_handle *h;
+ h = malloc(sizeof(struct swiz_mem_handle));
+ if (!h) return 0;
+ h->phys = address;
+ h->virt = mmap(0, size << 5, PROT_READ|PROT_WRITE, MAP_SHARED,
+ mem_fd,
+ swiz_mem_base + ((address & ~swiz_hae_mask) << 5));
+ if ((long) h->virt == -1) {
+ free(h);
+ return 0;
+ }
+ h->size = size << 5;
+ return h;
+}
+
+static void
+swiz_unmap_memory(void *handle, u_int32_t size)
+{
+ struct swiz_mem_handle *h = handle;
+ munmap(h->virt, h->size);
+ free(h);
+}
+
+static void
+swiz_sethae(vm_offset_t phys)
+{
+ u_int32_t hae = phys & swiz_hae_mask;
+ if (hae != swiz_hae) {
+ alpha_sethae(hae);
+ swiz_hae = hae;
+ }
+}
+
+static u_int8_t
+swiz_readb(void *handle, u_int32_t offset)
+{
+ struct swiz_mem_handle *h = handle;
+ swiz_sethae(h->phys + offset);
+ return SPARSE_READ_BYTE(h->virt, offset);
+}
+
+static u_int16_t
+swiz_readw(void *handle, u_int32_t offset)
+{
+ struct swiz_mem_handle *h = handle;
+ swiz_sethae(h->phys + offset);
+ return SPARSE_READ_WORD(h->virt, offset);
+}
+
+static u_int32_t
+swiz_readl(void *handle, u_int32_t offset)
+{
+ struct swiz_mem_handle *h = handle;
+ swiz_sethae(h->phys + offset);
+ return SPARSE_READ_LONG(h->virt, offset);
+}
+
+static void
+swiz_writeb(void *handle, u_int32_t offset, u_int8_t val)
+{
+ struct swiz_mem_handle *h = handle;
+ swiz_sethae(h->phys + offset);
+ SPARSE_WRITE_BYTE(h->virt, offset, val);
+}
+
+static void
+swiz_writew(void *handle, u_int32_t offset, u_int16_t val)
+{
+ struct swiz_mem_handle *h = handle;
+ swiz_sethae(h->phys + offset);
+ SPARSE_WRITE_WORD(h->virt, offset, val);
+}
+
+static void
+swiz_writel(void *handle, u_int32_t offset, u_int32_t val)
+{
+ struct swiz_mem_handle *h = handle;
+ swiz_sethae(h->phys + offset);
+ SPARSE_WRITE_LONG(h->virt, offset, val);
+}
+
+struct io_ops swiz_io_ops = {
+ swiz_ioperm,
+ swiz_inb,
+ swiz_inw,
+ swiz_inl,
+ swiz_outb,
+ swiz_outw,
+ swiz_outl,
+ swiz_map_memory,
+ swiz_unmap_memory,
+ swiz_readb,
+ swiz_readw,
+ swiz_readl,
+ swiz_writeb,
+ swiz_writew,
+ swiz_writel,
+};
diff --git a/lib/libipx/Makefile b/lib/libipx/Makefile
new file mode 100644
index 0000000..04665ba
--- /dev/null
+++ b/lib/libipx/Makefile
@@ -0,0 +1,9 @@
+LIB= ipx
+#CFLAGS+=-DLIBC_SCCS -I${.CURDIR}/../../sys
+SRCS= ipx_addr.c ipx_ntoa.c
+
+MAN3= ipx.3
+
+MLINKS+=ipx.3 ipx_addr.3 ipx.3 ipx_ntoa.3
+
+.include <bsd.lib.mk>
diff --git a/lib/libipx/ipx.3 b/lib/libipx/ipx.3
new file mode 100644
index 0000000..c005a4d
--- /dev/null
+++ b/lib/libipx/ipx.3
@@ -0,0 +1,126 @@
+.\" Copyright (c) 1986, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt IPX 3
+.Os BSD 4.3
+.Sh NAME
+.Nm ipx_addr ,
+.Nm ipx_ntoa
+.Nd IPX address conversion routines
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <netipx/ipx.h>
+.Ft struct ipx_addr
+.Fn ipx_addr "const char *cp"
+.Ft char *
+.Fn ipx_ntoa "struct ipx_addr ipx"
+.Sh DESCRIPTION
+The routine
+.Fn ipx_addr
+interprets character strings representing
+.Tn IPX
+addresses, returning binary information suitable
+for use in system calls.
+The routine
+.Fn ipx_ntoa
+takes
+.Tn IPX
+addresses and returns
+.Tn ASCII
+strings representing the address in a
+notation in common use:
+.Bd -filled -offset indent
+<network number>.<host number>.<port number>
+.Ed
+.Pp
+Trailing zero fields are suppressed, and each number is printed in hexadecimal,
+in a format suitable for input to
+.Fn ipx_addr .
+Any fields lacking super-decimal digits will have a
+trailing
+.Ql H
+appended.
+.Pp
+An effort has been made to insure that
+.Fn ipx_addr
+be compatible with most formats in common use.
+It will first separate an address into 1 to 3 fields using a single delimiter
+chosen from
+period
+.Ql \&. ,
+colon
+.Ql \&:
+or pound-sign
+.Ql \&# .
+Each field is then examined for byte separators (colon or period).
+If there are byte separators, each subfield separated is taken to be
+a small hexadecimal number, and the entirety is taken as a network-byte-ordered
+quantity to be zero extended in the high-network-order bytes.
+Next, the field is inspected for hyphens, in which case
+the field is assumed to be a number in decimal notation
+with hyphens separating the millenia.
+Next, the field is assumed to be a number:
+It is interpreted
+as hexadecimal if there is a leading
+.Ql 0x
+(as in C),
+a trailing
+.Ql H
+(as in Mesa), or there are any super-decimal digits present.
+It is interpreted as octal is there is a leading
+.Ql 0
+and there are no super-octal digits.
+Otherwise, it is converted as a decimal number.
+.Sh RETURN VALUES
+None. (See
+.Sx BUGS . )
+.Sh SEE ALSO
+.\" .Xr ns 4 ,
+.Xr hosts 5 ,
+.Xr networks 5
+.Sh HISTORY
+The precursor
+.Fn ns_addr
+and
+.Fn ns_toa
+functions appeared in
+.Bx 4.3 .
+.Sh BUGS
+The string returned by
+.Fn ipx_ntoa
+resides in a static memory area.
+The function
+.Fn ipx_addr
+should diagnose improperly formed input, and there should be an unambiguous
+way to recognize this.
diff --git a/lib/libipx/ipx_addr.c b/lib/libipx/ipx_addr.c
new file mode 100644
index 0000000..b83f8be
--- /dev/null
+++ b/lib/libipx/ipx_addr.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * J.Q. Johnson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ipx_addr.c";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netipx/ipx.h>
+#include <stdio.h>
+#include <string.h>
+
+static struct ipx_addr addr, zero_addr;
+
+static void Field(), cvtbase();
+
+struct ipx_addr
+ipx_addr(name)
+ const char *name;
+{
+ char separator;
+ char *hostname, *socketname, *cp;
+ char buf[50];
+
+ (void)strncpy(buf, name, sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+
+ /*
+ * First, figure out what he intends as a field separtor.
+ * Despite the way this routine is written, the prefered
+ * form 2-272.AA001234H.01777, i.e. XDE standard.
+ * Great efforts are made to insure backward compatability.
+ */
+ if ( (hostname = strchr(buf, '#')) )
+ separator = '#';
+ else {
+ hostname = strchr(buf, '.');
+ if ((cp = strchr(buf, ':')) &&
+ ((hostname && cp < hostname) || (hostname == 0))) {
+ hostname = cp;
+ separator = ':';
+ } else
+ separator = '.';
+ }
+ if (hostname)
+ *hostname++ = 0;
+
+ addr = zero_addr;
+ Field(buf, addr.x_net.c_net, 4);
+ if (hostname == 0)
+ return (addr); /* No separator means net only */
+
+ socketname = strchr(hostname, separator);
+ if (socketname) {
+ *socketname++ = 0;
+ Field(socketname, (u_char *)&addr.x_port, 2);
+ }
+
+ Field(hostname, addr.x_host.c_host, 6);
+
+ return (addr);
+}
+
+static void
+Field(buf, out, len)
+ char *buf;
+ u_char *out;
+ int len;
+{
+ register char *bp = buf;
+ int i, ibase, base16 = 0, base10 = 0, clen = 0;
+ int hb[6], *hp;
+ char *fmt;
+
+ /*
+ * first try 2-273#2-852-151-014#socket
+ */
+ if ((*buf != '-') &&
+ (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
+ &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
+ cvtbase(1000L, 256, hb, i, out, len);
+ return;
+ }
+ /*
+ * try form 8E1#0.0.AA.0.5E.E6#socket
+ */
+ if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
+ &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
+ cvtbase(256L, 256, hb, i, out, len);
+ return;
+ }
+ /*
+ * try form 8E1#0:0:AA:0:5E:E6#socket
+ */
+ if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
+ &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
+ cvtbase(256L, 256, hb, i, out, len);
+ return;
+ }
+ /*
+ * This is REALLY stretching it but there was a
+ * comma notation separting shorts -- definitely non standard
+ */
+ if (1 < (i = sscanf(buf,"%x,%x,%x",
+ &hb[0], &hb[1], &hb[2]))) {
+ hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
+ hb[2] = htons(hb[2]);
+ cvtbase(65536L, 256, hb, i, out, len);
+ return;
+ }
+
+ /* Need to decide if base 10, 16 or 8 */
+ while (*bp) switch (*bp++) {
+
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '-':
+ break;
+
+ case '8': case '9':
+ base10 = 1;
+ break;
+
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ base16 = 1;
+ break;
+
+ case 'x': case 'X':
+ *--bp = '0';
+ base16 = 1;
+ break;
+
+ case 'h': case 'H':
+ base16 = 1;
+ /* fall into */
+
+ default:
+ *--bp = 0; /* Ends Loop */
+ }
+ if (base16) {
+ fmt = "%3x";
+ ibase = 4096;
+ } else if (base10 == 0 && *buf == '0') {
+ fmt = "%3o";
+ ibase = 512;
+ } else {
+ fmt = "%3d";
+ ibase = 1000;
+ }
+
+ for (bp = buf; *bp++; ) clen++;
+ if (clen == 0) clen++;
+ if (clen > 18) clen = 18;
+ i = ((clen - 1) / 3) + 1;
+ bp = clen + buf - 3;
+ hp = hb + i - 1;
+
+ while (hp > hb) {
+ (void)sscanf(bp, fmt, hp);
+ bp[0] = 0;
+ hp--;
+ bp -= 3;
+ }
+ (void)sscanf(buf, fmt, hp);
+ cvtbase((long)ibase, 256, hb, i, out, len);
+}
+
+static void
+cvtbase(oldbase,newbase,input,inlen,result,reslen)
+ long oldbase;
+ int newbase;
+ int input[];
+ int inlen;
+ unsigned char result[];
+ int reslen;
+{
+ int d, e;
+ long sum;
+
+ e = 1;
+ while (e > 0 && reslen > 0) {
+ d = 0; e = 0; sum = 0;
+ /* long division: input=input/newbase */
+ while (d < inlen) {
+ sum = sum*oldbase + (long) input[d];
+ e += (sum > 0);
+ input[d++] = sum / newbase;
+ sum %= newbase;
+ }
+ result[--reslen] = sum; /* accumulate remainder */
+ }
+ for (d=0; d < reslen; d++)
+ result[d] = 0;
+}
diff --git a/lib/libipx/ipx_ntoa.c b/lib/libipx/ipx_ntoa.c
new file mode 100644
index 0000000..1bf1c57
--- /dev/null
+++ b/lib/libipx/ipx_ntoa.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ipx_ntoa.c";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netipx/ipx.h>
+#include <stdio.h>
+
+char *
+ipx_ntoa(addr)
+ struct ipx_addr addr;
+{
+ static char obuf[40];
+ union { union ipx_net net_e; u_long long_e; } net;
+ u_short port = htons(addr.x_port);
+ register char *cp;
+ char *cp2;
+ register u_char *up = addr.x_host.c_host;
+ u_char *uplim = up + 6;
+ static char *spectHex();
+
+ net.net_e = addr.x_net;
+ sprintf(obuf, "%lx", (u_long)ntohl(net.long_e));
+ cp = spectHex(obuf);
+ cp2 = cp + 1;
+ while (*up==0 && up < uplim) up++;
+ if (up == uplim) {
+ if (port) {
+ sprintf(cp, ".0");
+ cp += 2;
+ }
+ } else {
+ sprintf(cp, ".%x", *up++);
+ while (up < uplim) {
+ while (*cp) cp++;
+ sprintf(cp, "%02x", *up++);
+ }
+ cp = spectHex(cp2);
+ }
+ if (port) {
+ sprintf(cp, ".%x", port);
+ spectHex(cp + 1);
+ }
+ return (obuf);
+}
+
+static char *
+spectHex(p0)
+ char *p0;
+{
+ int ok = 0;
+ int nonzero = 0;
+ register char *p = p0;
+ for (; *p; p++) switch (*p) {
+
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ ok = 1;
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ nonzero = 1;
+ }
+ if (nonzero && !ok) { *p++ = 'H'; *p = 0; }
+ return (p);
+}
diff --git a/lib/libkse/Makefile b/lib/libkse/Makefile
new file mode 100644
index 0000000..e79d5c5
--- /dev/null
+++ b/lib/libkse/Makefile
@@ -0,0 +1,45 @@
+# $FreeBSD$
+#
+# All library objects contain rcsid strings by default; they may be
+# excluded as a space-saving measure. To produce a library that does
+# not contain these strings, delete -DLIBC_RCS and -DSYSLIBC_RCS
+# from CFLAGS below. To remove these strings from just the system call
+# stubs, remove just -DSYSLIBC_RCS from CFLAGS.
+LIB=c_r
+SHLIB_MAJOR= 4
+SHLIB_MINOR= 0
+CFLAGS+=-DLIBC_RCS -DSYSLIBC_RCS -I${.CURDIR}/../libc/include
+CFLAGS+=-DPTHREAD_KERNEL -D_THREAD_SAFE -I${.CURDIR}/uthread
+CFLAGS+=-I${.CURDIR}/../../include
+
+# Uncomment this if you want libc_r to contain debug information for
+# thread locking.
+CFLAGS+=-D_LOCK_DEBUG
+
+# enable extra internal consistancy checks
+# CFLAGS+=-D_PTHREADS_INVARIANTS
+
+AINC= -I${.CURDIR}/../libc/${MACHINE_ARCH} -I${.CURDIR}/uthread
+PRECIOUSLIB= yes
+
+#
+# This is a list of syscalls that are renamed as _thread_sys_{syscall}
+# so that libc_r can provide replacement functions.
+#
+HIDDEN_SYSCALLS= accept.o bind.o close.o connect.o dup.o dup2.o \
+ execve.o fchflags.o fchmod.o fchown.o fcntl.o \
+ flock.o fpathconf.o fstat.o fstatfs.o fsync.o getdirentries.o \
+ getlogin.o getpeername.o getsockname.o getsockopt.o ioctl.o listen.o \
+ msync.o nanosleep.o nfssvc.o open.o poll.o read.o readv.o recvfrom.o \
+ recvmsg.o sched_yield.o select.o sendmsg.o sendto.o \
+ setsockopt.o shutdown.o sigaction.o sigaltstack.o \
+ signanosleep.o sigpending.o sigprocmask.o sigreturn.o sigsetmask.o \
+ sigsuspend.o socket.o \
+ socketpair.o wait4.o write.o writev.o
+
+.include "${.CURDIR}/../libc/Makefile.inc"
+.include "${.CURDIR}/man/Makefile.inc"
+.include "${.CURDIR}/uthread/Makefile.inc"
+.include "${.CURDIR}/sys/Makefile.inc"
+
+.include <bsd.lib.mk>
diff --git a/lib/libkse/sys/Makefile.inc b/lib/libkse/sys/Makefile.inc
new file mode 100644
index 0000000..e608afa
--- /dev/null
+++ b/lib/libkse/sys/Makefile.inc
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/sys ${.CURDIR}/arch/${MACHINE_ARCH}
+
+SRCS+= uthread_error.c _atomic_lock.S
+
diff --git a/lib/libkse/sys/thr_error.c b/lib/libkse/sys/thr_error.c
new file mode 100644
index 0000000..0d08ae8
--- /dev/null
+++ b/lib/libkse/sys/thr_error.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell
+ * and Chris Provenzano.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+extern int errno;
+
+int * __error()
+{
+ int *p_errno;
+ if (_thread_run == _thread_initial) {
+ p_errno = &errno;
+ } else {
+ p_errno = &_thread_run->error;
+ }
+ return(p_errno);
+}
+#endif
diff --git a/lib/libkse/test/Makefile b/lib/libkse/test/Makefile
new file mode 100644
index 0000000..90ee5ad
--- /dev/null
+++ b/lib/libkse/test/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+#
+# Tests for libc_r functionality.
+#
+
+SUBDIR= mutex sigsuspend sigwait
+
+.include <bsd.subdir.mk>
diff --git a/lib/libkse/thread/Makefile.inc b/lib/libkse/thread/Makefile.inc
new file mode 100644
index 0000000..4697305
--- /dev/null
+++ b/lib/libkse/thread/Makefile.inc
@@ -0,0 +1,117 @@
+# $FreeBSD$
+
+# uthread sources
+.PATH: ${.CURDIR}/uthread
+
+SRCS+= \
+ uthread_accept.c \
+ uthread_attr_destroy.c \
+ uthread_attr_init.c \
+ uthread_attr_getdetachstate.c \
+ uthread_attr_getinheritsched.c \
+ uthread_attr_getschedparam.c \
+ uthread_attr_getschedpolicy.c \
+ uthread_attr_getscope.c \
+ uthread_attr_getstackaddr.c \
+ uthread_attr_getstacksize.c \
+ uthread_attr_setcreatesuspend_np.c \
+ uthread_attr_setdetachstate.c \
+ uthread_attr_setinheritsched.c \
+ uthread_attr_setschedparam.c \
+ uthread_attr_setschedpolicy.c \
+ uthread_attr_setscope.c \
+ uthread_attr_setstackaddr.c \
+ uthread_attr_setstacksize.c \
+ uthread_autoinit.cc \
+ uthread_bind.c \
+ uthread_cancel.c \
+ uthread_clean.c \
+ uthread_close.c \
+ uthread_cond.c \
+ uthread_condattr_destroy.c \
+ uthread_condattr_init.c \
+ uthread_connect.c \
+ uthread_create.c \
+ uthread_detach.c \
+ uthread_dup.c \
+ uthread_dup2.c \
+ uthread_equal.c \
+ uthread_execve.c \
+ uthread_exit.c \
+ uthread_fchflags.c \
+ uthread_fchmod.c \
+ uthread_fchown.c \
+ uthread_fcntl.c \
+ uthread_fd.c \
+ uthread_file.c \
+ uthread_find_thread.c \
+ uthread_flock.c \
+ uthread_fork.c \
+ uthread_fstat.c \
+ uthread_fstatfs.c \
+ uthread_fsync.c \
+ uthread_gc.c \
+ uthread_getdirentries.c \
+ uthread_getpeername.c \
+ uthread_getprio.c \
+ uthread_getschedparam.c \
+ uthread_getsockname.c \
+ uthread_getsockopt.c \
+ uthread_info.c \
+ uthread_init.c \
+ uthread_ioctl.c \
+ uthread_join.c \
+ uthread_kern.c \
+ uthread_kill.c \
+ uthread_listen.c \
+ uthread_mattr_init.c \
+ uthread_mattr_kind_np.c \
+ uthread_msync.c \
+ uthread_multi_np.c \
+ uthread_mutex.c \
+ uthread_mutex_prioceiling.c \
+ uthread_mutex_protocol.c \
+ uthread_mutexattr_destroy.c \
+ uthread_nanosleep.c \
+ uthread_once.c \
+ uthread_open.c \
+ uthread_pipe.c \
+ uthread_poll.c \
+ uthread_priority_queue.c \
+ uthread_read.c \
+ uthread_readv.c \
+ uthread_recvfrom.c \
+ uthread_recvmsg.c \
+ uthread_resume_np.c \
+ uthread_rwlock.c \
+ uthread_rwlockattr.c \
+ uthread_select.c \
+ uthread_self.c \
+ uthread_sendmsg.c \
+ uthread_sendto.c \
+ uthread_seterrno.c \
+ uthread_setprio.c \
+ uthread_setschedparam.c \
+ uthread_setsockopt.c \
+ uthread_shutdown.c \
+ uthread_sig.c \
+ uthread_sigaction.c \
+ uthread_sigblock.c \
+ uthread_sigmask.c \
+ uthread_sigpending.c \
+ uthread_sigprocmask.c \
+ uthread_sigsetmask.c \
+ uthread_sigsuspend.c \
+ uthread_sigwait.c \
+ uthread_single_np.c \
+ uthread_socket.c \
+ uthread_socketpair.c \
+ uthread_spec.c \
+ uthread_spinlock.c \
+ uthread_suspend_np.c \
+ uthread_switch_np.c \
+ uthread_vfork.c \
+ uthread_wait4.c \
+ uthread_write.c \
+ uthread_writev.c \
+ uthread_yield.c
diff --git a/lib/libkse/thread/thr_attr_destroy.c b/lib/libkse/thread/thr_attr_destroy.c
new file mode 100644
index 0000000..dfe668e
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_destroy.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_destroy(pthread_attr_t *attr)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL)
+ /* Invalid argument: */
+ ret = EINVAL;
+ else {
+ /* Free the memory allocated to the attribute object: */
+ free(*attr);
+
+ /*
+ * Leave the attribute pointer NULL now that the memory
+ * has been freed:
+ */
+ *attr = NULL;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_getdetachstate.c b/lib/libkse/thread/thr_attr_getdetachstate.c
new file mode 100644
index 0000000..fee1e8b
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_getdetachstate.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || detachstate == NULL)
+ ret = EINVAL;
+ else {
+ /* Check if the detached flag is set: */
+ if ((*attr)->flags & PTHREAD_DETACHED)
+ /* Return detached: */
+ *detachstate = PTHREAD_CREATE_DETACHED;
+ else
+ /* Return joinable: */
+ *detachstate = PTHREAD_CREATE_JOINABLE;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_getinheritsched.c b/lib/libkse/thread/thr_attr_getinheritsched.c
new file mode 100644
index 0000000..7e243ed
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_getinheritsched.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_getinheritsched(const pthread_attr_t *attr, int *sched_inherit)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL))
+ ret = EINVAL;
+ else
+ *sched_inherit = (*attr)->sched_inherit;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_getschedparam.c b/lib/libkse/thread/thr_attr_getschedparam.c
new file mode 100644
index 0000000..46586ff
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_getschedparam.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (param == NULL))
+ ret = EINVAL;
+ else
+ param->sched_priority = (*attr)->prio;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_getschedpolicy.c b/lib/libkse/thread/thr_attr_getschedpolicy.c
new file mode 100644
index 0000000..19f835c
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_getschedpolicy.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (policy == NULL))
+ ret = EINVAL;
+ else
+ *policy = (*attr)->sched_policy;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_getscope.c b/lib/libkse/thread/thr_attr_getscope.c
new file mode 100644
index 0000000..176f01b
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_getscope.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (contentionscope == NULL))
+ /* Return an invalid argument: */
+ ret = EINVAL;
+
+ else
+ *contentionscope = (*attr)->flags & PTHREAD_SCOPE_SYSTEM ?
+ PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_getstackaddr.c b/lib/libkse/thread/thr_attr_getstackaddr.c
new file mode 100644
index 0000000..1fee4a5
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_getstackaddr.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || stackaddr == NULL)
+ ret = EINVAL;
+ else {
+ /* Return the stack address: */
+ *stackaddr = (*attr)->stackaddr_attr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_getstacksize.c b/lib/libkse/thread/thr_attr_getstacksize.c
new file mode 100644
index 0000000..5c7a9e0
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_getstacksize.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || stacksize == NULL)
+ ret = EINVAL;
+ else {
+ /* Return the stack size: */
+ *stacksize = (*attr)->stacksize_attr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_init.c b/lib/libkse/thread/thr_attr_init.c
new file mode 100644
index 0000000..dbe3091
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_init.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_init(pthread_attr_t *attr)
+{
+ int ret;
+ pthread_attr_t pattr;
+
+ /* Allocate memory for the attribute object: */
+ if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL)
+ /* Insufficient memory: */
+ ret = ENOMEM;
+ else {
+ /* Initialise the attribute object with the defaults: */
+ memcpy(pattr, &pthread_attr_default, sizeof(struct pthread_attr));
+
+ /* Return a pointer to the attribute object: */
+ *attr = pattr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_setcreatesuspend_np.c b/lib/libkse/thread/thr_attr_setcreatesuspend_np.c
new file mode 100644
index 0000000..d230397
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_setcreatesuspend_np.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setcreatesuspend_np(pthread_attr_t *attr)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->suspend = PTHREAD_CREATE_SUSPENDED;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_setdetachstate.c b/lib/libkse/thread/thr_attr_setdetachstate.c
new file mode 100644
index 0000000..36a846a
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_setdetachstate.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL ||
+ (detachstate != PTHREAD_CREATE_DETACHED &&
+ detachstate != PTHREAD_CREATE_JOINABLE))
+ ret = EINVAL;
+ else {
+ /* Check if detached state: */
+ if (detachstate == PTHREAD_CREATE_DETACHED)
+ /* Set the detached flag: */
+ (*attr)->flags |= PTHREAD_DETACHED;
+ else
+ /* Reset the detached flag: */
+ (*attr)->flags &= ~PTHREAD_DETACHED;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_setinheritsched.c b/lib/libkse/thread/thr_attr_setinheritsched.c
new file mode 100644
index 0000000..eb2384b
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_setinheritsched.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setinheritsched(pthread_attr_t *attr, int sched_inherit)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL))
+ ret = EINVAL;
+ else
+ (*attr)->sched_inherit = sched_inherit;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_setschedparam.c b/lib/libkse/thread/thr_attr_setschedparam.c
new file mode 100644
index 0000000..17b93b4
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_setschedparam.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param *param)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (param == NULL))
+ ret = EINVAL;
+ else
+ (*attr)->prio = param->sched_priority;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_setschedpolicy.c b/lib/libkse/thread/thr_attr_setschedpolicy.c
new file mode 100644
index 0000000..640cb38
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_setschedpolicy.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (policy < SCHED_FIFO) ||
+ (policy > SCHED_RR))
+ ret = EINVAL;
+ else
+ (*attr)->sched_policy = policy;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_setscope.c b/lib/libkse/thread/thr_attr_setscope.c
new file mode 100644
index 0000000..84239d7
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_setscope.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) ||
+ (contentionscope != PTHREAD_SCOPE_PROCESS) ||
+ (contentionscope != PTHREAD_SCOPE_SYSTEM))
+ /* Return an invalid argument: */
+ ret = EINVAL;
+
+ else if (contentionscope == PTHREAD_SCOPE_SYSTEM)
+ /* We don't support system wide contention: */
+#ifdef NOT_YET
+ ret = ENOTSUP;
+#else
+ ret = EOPNOTSUPP;
+#endif
+
+ else
+ (*attr)->flags |= contentionscope;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_setstackaddr.c b/lib/libkse/thread/thr_attr_setstackaddr.c
new file mode 100644
index 0000000..7eb8c5d
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_setstackaddr.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || stackaddr == NULL)
+ ret = EINVAL;
+ else {
+ /* Save the stack address: */
+ (*attr)->stackaddr_attr = stackaddr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_attr_setstacksize.c b/lib/libkse/thread/thr_attr_setstacksize.c
new file mode 100644
index 0000000..2a2d854
--- /dev/null
+++ b/lib/libkse/thread/thr_attr_setstacksize.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN)
+ ret = EINVAL;
+ else {
+ /* Save the stack size: */
+ (*attr)->stacksize_attr = stacksize;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_cancel.c b/lib/libkse/thread/thr_cancel.c
new file mode 100644
index 0000000..de7c491
--- /dev/null
+++ b/lib/libkse/thread/thr_cancel.c
@@ -0,0 +1,188 @@
+/*
+ * David Leonard <d@openbsd.org>, 1999. Public domain.
+ * $FreeBSD$
+ */
+
+#include <sys/errno.h>
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_cancel(pthread_t pthread)
+{
+ int ret;
+
+ if ((ret = _find_thread(pthread)) != 0) {
+ /* NOTHING */
+ } else if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK) {
+ ret = 0;
+ } else {
+ /* Protect the scheduling queues: */
+ _thread_kern_sig_defer();
+
+ if (((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) != 0) ||
+ (((pthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) == 0) &&
+ ((pthread->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0)))
+ /* Just mark it for cancellation: */
+ pthread->cancelflags |= PTHREAD_CANCELLING;
+ else {
+ /*
+ * Check if we need to kick it back into the
+ * run queue:
+ */
+ switch (pthread->state) {
+ case PS_RUNNING:
+ /* No need to resume: */
+ pthread->cancelflags |= PTHREAD_CANCELLING;
+ break;
+
+ case PS_SPINBLOCK:
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Remove these threads from the work queue: */
+ if ((pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ != 0)
+ PTHREAD_WORKQ_REMOVE(pthread);
+ /* Fall through: */
+ case PS_SIGTHREAD:
+ case PS_SLEEP_WAIT:
+ case PS_WAIT_WAIT:
+ case PS_SIGSUSPEND:
+ case PS_SIGWAIT:
+ case PS_SUSPENDED:
+ /* Interrupt and resume: */
+ pthread->interrupted = 1;
+ pthread->cancelflags |= PTHREAD_CANCELLING;
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ break;
+
+ case PS_MUTEX_WAIT:
+ case PS_COND_WAIT:
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ case PS_JOIN:
+ /*
+ * Threads in these states may be in queues.
+ * In order to preserve queue integrity, the
+ * cancelled thread must remove itself from the
+ * queue. Mark the thread as interrupted and
+ * needing cancellation, and set the state to
+ * running. When the thread resumes, it will
+ * exit after removing itself from the queue.
+ */
+ pthread->interrupted = 1;
+ pthread->cancelflags |= PTHREAD_CANCEL_NEEDED;
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ break;
+
+ case PS_DEAD:
+ case PS_DEADLOCK:
+ case PS_STATE_MAX:
+ /* Ignore - only here to silence -Wall: */
+ break;
+ }
+ }
+
+ /* Unprotect the scheduling queues: */
+ _thread_kern_sig_undefer();
+
+ ret = 0;
+ }
+ return (ret);
+}
+
+int
+pthread_setcancelstate(int state, int *oldstate)
+{
+ int ostate;
+ int ret;
+
+ ostate = _thread_run->cancelflags & PTHREAD_CANCEL_DISABLE;
+
+ switch (state) {
+ case PTHREAD_CANCEL_ENABLE:
+ if (oldstate != NULL)
+ *oldstate = ostate;
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_DISABLE;
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)
+ pthread_testcancel();
+ ret = 0;
+ break;
+ case PTHREAD_CANCEL_DISABLE:
+ if (oldstate != NULL)
+ *oldstate = ostate;
+ _thread_run->cancelflags |= PTHREAD_CANCEL_DISABLE;
+ ret = 0;
+ break;
+ default:
+ ret = EINVAL;
+ }
+
+ return (ret);
+}
+
+int
+pthread_setcanceltype(int type, int *oldtype)
+{
+ int otype;
+ int ret;
+
+ otype = _thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS;
+ switch (type) {
+ case PTHREAD_CANCEL_ASYNCHRONOUS:
+ if (oldtype != NULL)
+ *oldtype = otype;
+ _thread_run->cancelflags |= PTHREAD_CANCEL_ASYNCHRONOUS;
+ pthread_testcancel();
+ ret = 0;
+ break;
+ case PTHREAD_CANCEL_DEFERRED:
+ if (oldtype != NULL)
+ *oldtype = otype;
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_ASYNCHRONOUS;
+ ret = 0;
+ break;
+ default:
+ ret = EINVAL;
+ }
+
+ return (ret);
+}
+
+void
+pthread_testcancel(void)
+{
+ if (((_thread_run->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) &&
+ ((_thread_run->cancelflags & PTHREAD_CANCELLING) != 0)) {
+ /*
+ * It is possible for this thread to be swapped out
+ * while performing cancellation; do not allow it
+ * to be cancelled again.
+ */
+ _thread_run->cancelflags &= ~PTHREAD_CANCELLING;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ PANIC("cancel");
+ }
+}
+
+void
+_thread_enter_cancellation_point(void)
+{
+
+ /* Look for a cancellation before we block: */
+ pthread_testcancel();
+ _thread_run->cancelflags |= PTHREAD_AT_CANCEL_POINT;
+}
+
+void
+_thread_leave_cancellation_point(void)
+{
+
+ _thread_run->cancelflags &= ~PTHREAD_AT_CANCEL_POINT;
+ /* Look for a cancellation after we unblock: */
+ pthread_testcancel();
+}
diff --git a/lib/libkse/thread/thr_clean.c b/lib/libkse/thread/thr_clean.c
new file mode 100644
index 0000000..bba5500
--- /dev/null
+++ b/lib/libkse/thread/thr_clean.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#include <stdlib.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+void
+pthread_cleanup_push(void (*routine) (void *), void *routine_arg)
+{
+ struct pthread_cleanup *new;
+
+ if ((new = (struct pthread_cleanup *) malloc(sizeof(struct pthread_cleanup))) != NULL) {
+ new->routine = routine;
+ new->routine_arg = routine_arg;
+ new->next = _thread_run->cleanup;
+
+ _thread_run->cleanup = new;
+ }
+}
+
+void
+pthread_cleanup_pop(int execute)
+{
+ struct pthread_cleanup *old;
+
+ if ((old = _thread_run->cleanup) != NULL) {
+ _thread_run->cleanup = old->next;
+ if (execute) {
+ old->routine(old->routine_arg);
+ }
+ free(old);
+ }
+}
+
+#endif
diff --git a/lib/libkse/thread/thr_close.c b/lib/libkse/thread/thr_close.c
new file mode 100644
index 0000000..2580fce
--- /dev/null
+++ b/lib/libkse/thread/thr_close.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+close(int fd)
+{
+ int flags;
+ int ret;
+ struct stat sb;
+ struct fd_table_entry *entry;
+
+ _thread_enter_cancellation_point();
+
+ if ((fd == _thread_kern_pipe[0]) || (fd == _thread_kern_pipe[1])) {
+ /*
+ * Don't allow silly programs to close the kernel pipe.
+ */
+ errno = EBADF;
+ ret = -1;
+ }
+ /*
+ * Lock the file descriptor while the file is closed and get
+ * the file descriptor status:
+ */
+ else if (((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) &&
+ ((ret = _thread_sys_fstat(fd, &sb)) == 0)) {
+ /*
+ * Check if the file should be left as blocking.
+ *
+ * This is so that the file descriptors shared with a parent
+ * process aren't left set to non-blocking if the child
+ * closes them prior to exit. An example where this causes
+ * problems with /bin/sh is when a child closes stdin.
+ *
+ * Setting a file as blocking causes problems if a threaded
+ * parent accesses the file descriptor before the child exits.
+ * Once the threaded parent receives a SIGCHLD then it resets
+ * all of its files to non-blocking, and so it is then safe
+ * to access them.
+ *
+ * Pipes are not set to blocking when they are closed, as
+ * the parent and child will normally close the file
+ * descriptor of the end of the pipe that they are not
+ * using, which would then cause any reads to block
+ * indefinitely.
+ */
+ if ((S_ISREG(sb.st_mode) || S_ISCHR(sb.st_mode)) && (_thread_fd_table[fd]->flags & O_NONBLOCK) == 0) {
+ /* Get the current flags: */
+ flags = _thread_sys_fcntl(fd, F_GETFL, NULL);
+ /* Clear the nonblocking file descriptor flag: */
+ _thread_sys_fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+ }
+
+ /* XXX: Assumes well behaved threads. */
+ /* XXX: Defer real close to avoid race condition */
+ entry = _thread_fd_table[fd];
+ _thread_fd_table[fd] = NULL;
+ free(entry);
+
+ /* Close the file descriptor: */
+ ret = _thread_sys_close(fd);
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_cond.c b/lib/libkse/thread/thr_cond.c
new file mode 100644
index 0000000..3e215af
--- /dev/null
+++ b/lib/libkse/thread/thr_cond.c
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/*
+ * Prototypes
+ */
+static inline pthread_t cond_queue_deq(pthread_cond_t);
+static inline void cond_queue_remove(pthread_cond_t, pthread_t);
+static inline void cond_queue_enq(pthread_cond_t, pthread_t);
+
+/* Reinitialize a condition variable to defaults. */
+int
+_cond_reinit(pthread_cond_t * cond)
+{
+ int ret = 0;
+
+ if (cond == NULL)
+ ret = EINVAL;
+ else if (*cond == NULL)
+ ret = pthread_cond_init(cond, NULL);
+ else {
+ /*
+ * Initialize the condition variable structure:
+ */
+ TAILQ_INIT(&(*cond)->c_queue);
+ (*cond)->c_flags = COND_FLAGS_INITED;
+ (*cond)->c_type = COND_TYPE_FAST;
+ (*cond)->c_mutex = NULL;
+ memset(&(*cond)->lock, 0, sizeof((*cond)->lock));
+ }
+ return (ret);
+}
+
+int
+pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t * cond_attr)
+{
+ enum pthread_cond_type type;
+ pthread_cond_t pcond;
+ int rval = 0;
+
+ if (cond == NULL)
+ rval = EINVAL;
+ else {
+ /*
+ * Check if a pointer to a condition variable attribute
+ * structure was passed by the caller:
+ */
+ if (cond_attr != NULL && *cond_attr != NULL) {
+ /* Default to a fast condition variable: */
+ type = (*cond_attr)->c_type;
+ } else {
+ /* Default to a fast condition variable: */
+ type = COND_TYPE_FAST;
+ }
+
+ /* Process according to condition variable type: */
+ switch (type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ /* Nothing to do here. */
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ /* Check for no errors: */
+ if (rval == 0) {
+ if ((pcond = (pthread_cond_t)
+ malloc(sizeof(struct pthread_cond))) == NULL) {
+ rval = ENOMEM;
+ } else {
+ /*
+ * Initialise the condition variable
+ * structure:
+ */
+ TAILQ_INIT(&pcond->c_queue);
+ pcond->c_flags |= COND_FLAGS_INITED;
+ pcond->c_type = type;
+ pcond->c_mutex = NULL;
+ memset(&pcond->lock,0,sizeof(pcond->lock));
+ *cond = pcond;
+ }
+ }
+ }
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_destroy(pthread_cond_t * cond)
+{
+ int rval = 0;
+
+ if (cond == NULL || *cond == NULL)
+ rval = EINVAL;
+ else {
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /*
+ * Free the memory allocated for the condition
+ * variable structure:
+ */
+ free(*cond);
+
+ /*
+ * NULL the caller's pointer now that the condition
+ * variable has been destroyed:
+ */
+ *cond = NULL;
+ }
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
+{
+ int rval = 0;
+
+ if (cond == NULL)
+ rval = EINVAL;
+
+ /*
+ * If the condition variable is statically initialized,
+ * perform the dynamic initialization:
+ */
+ else if (*cond != NULL ||
+ (rval = pthread_cond_init(cond,NULL)) == 0) {
+
+ _thread_enter_cancellation_point();
+
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /*
+ * If the condvar was statically allocated, properly
+ * initialize the tail queue.
+ */
+ if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) {
+ TAILQ_INIT(&(*cond)->c_queue);
+ (*cond)->c_flags |= COND_FLAGS_INITED;
+ }
+
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ if ((mutex == NULL) || (((*cond)->c_mutex != NULL) &&
+ ((*cond)->c_mutex != *mutex))) {
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /* Return invalid argument error: */
+ rval = EINVAL;
+ } else {
+ /* Reset the timeout and interrupted flags: */
+ _thread_run->timeout = 0;
+ _thread_run->interrupted = 0;
+
+ /*
+ * Queue the running thread for the condition
+ * variable:
+ */
+ cond_queue_enq(*cond, _thread_run);
+
+ /* Remember the mutex that is being used: */
+ (*cond)->c_mutex = *mutex;
+
+ /* Wait forever: */
+ _thread_run->wakeup_time.tv_sec = -1;
+
+ /* Unlock the mutex: */
+ if ((rval = _mutex_cv_unlock(mutex)) != 0) {
+ /*
+ * Cannot unlock the mutex, so remove
+ * the running thread from the condition
+ * variable queue:
+ */
+ cond_queue_remove(*cond, _thread_run);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) ==
+ NULL)
+ (*cond)->c_mutex = NULL;
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+ }
+ else {
+ /*
+ * Schedule the next thread and unlock
+ * the condition variable structure:
+ */
+ _thread_kern_sched_state_unlock(PS_COND_WAIT,
+ &(*cond)->lock, __FILE__, __LINE__);
+
+ if (_thread_run->interrupted != 0) {
+ /*
+ * Lock the condition variable
+ * while removing the thread.
+ */
+ _SPINLOCK(&(*cond)->lock);
+
+ cond_queue_remove(*cond,
+ _thread_run);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) == NULL)
+ (*cond)->c_mutex = NULL;
+
+ _SPINUNLOCK(&(*cond)->lock);
+ }
+
+ /*
+ * Note that even though this thread may have
+ * been canceled, POSIX requires that the mutex
+ * be reaquired prior to cancellation.
+ */
+ rval = _mutex_cv_lock(mutex);
+ }
+ }
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+
+ _thread_leave_cancellation_point();
+ }
+
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
+ const struct timespec * abstime)
+{
+ int rval = 0;
+
+ if (cond == NULL || abstime == NULL)
+ rval = EINVAL;
+
+ if (abstime->tv_sec < 0 ||
+ abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /*
+ * If the condition variable is statically initialized,
+ * perform the dynamic initialization:
+ */
+ if (*cond != NULL ||
+ (rval = pthread_cond_init(cond,NULL)) == 0) {
+
+ _thread_enter_cancellation_point();
+
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /*
+ * If the condvar was statically allocated, properly
+ * initialize the tail queue.
+ */
+ if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) {
+ TAILQ_INIT(&(*cond)->c_queue);
+ (*cond)->c_flags |= COND_FLAGS_INITED;
+ }
+
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ if ((mutex == NULL) || (((*cond)->c_mutex != NULL) &&
+ ((*cond)->c_mutex != *mutex))) {
+ /* Return invalid argument error: */
+ rval = EINVAL;
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+ } else {
+ /* Set the wakeup time: */
+ _thread_run->wakeup_time.tv_sec =
+ abstime->tv_sec;
+ _thread_run->wakeup_time.tv_nsec =
+ abstime->tv_nsec;
+
+ /* Reset the timeout and interrupted flags: */
+ _thread_run->timeout = 0;
+ _thread_run->interrupted = 0;
+
+ /*
+ * Queue the running thread for the condition
+ * variable:
+ */
+ cond_queue_enq(*cond, _thread_run);
+
+ /* Remember the mutex that is being used: */
+ (*cond)->c_mutex = *mutex;
+
+ /* Unlock the mutex: */
+ if ((rval = _mutex_cv_unlock(mutex)) != 0) {
+ /*
+ * Cannot unlock the mutex, so remove
+ * the running thread from the condition
+ * variable queue:
+ */
+ cond_queue_remove(*cond, _thread_run);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) == NULL)
+ (*cond)->c_mutex = NULL;
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+ } else {
+ /*
+ * Schedule the next thread and unlock
+ * the condition variable structure:
+ */
+ _thread_kern_sched_state_unlock(PS_COND_WAIT,
+ &(*cond)->lock, __FILE__, __LINE__);
+
+ /*
+ * Check if the wait timedout or was
+ * interrupted (canceled):
+ */
+ if ((_thread_run->timeout == 0) &&
+ (_thread_run->interrupted == 0)) {
+ /* Lock the mutex: */
+ rval = _mutex_cv_lock(mutex);
+
+ } else {
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /*
+ * The wait timed out; remove
+ * the thread from the condition
+ * variable queue:
+ */
+ cond_queue_remove(*cond,
+ _thread_run);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) == NULL)
+ (*cond)->c_mutex = NULL;
+
+ /* Unock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /* Return a timeout error: */
+ rval = ETIMEDOUT;
+
+ /*
+ * Lock the mutex and ignore any
+ * errors. Note that even though
+ * this thread may have been
+ * canceled, POSIX requires that
+ * the mutex be reaquired prior
+ * to cancellation.
+ */
+ (void)_mutex_cv_lock(mutex);
+ }
+ }
+ }
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+
+ _thread_leave_cancellation_point();
+ }
+
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_signal(pthread_cond_t * cond)
+{
+ int rval = 0;
+ pthread_t pthread;
+
+ if (cond == NULL || *cond == NULL)
+ rval = EINVAL;
+ else {
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ if ((pthread = cond_queue_deq(*cond)) != NULL)
+ /* Allow the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) == NULL)
+ (*cond)->c_mutex = NULL;
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_broadcast(pthread_cond_t * cond)
+{
+ int rval = 0;
+ pthread_t pthread;
+
+ if (cond == NULL || *cond == NULL)
+ rval = EINVAL;
+ else {
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ /*
+ * Enter a loop to bring all threads off the
+ * condition queue:
+ */
+ while ((pthread = cond_queue_deq(*cond)) != NULL) {
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ }
+
+ /* There are no more waiting threads: */
+ (*cond)->c_mutex = NULL;
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (rval);
+}
+
+/*
+ * Dequeue a waiting thread from the head of a condition queue in
+ * descending priority order.
+ */
+static inline pthread_t
+cond_queue_deq(pthread_cond_t cond)
+{
+ pthread_t pthread;
+
+ while ((pthread = TAILQ_FIRST(&cond->c_queue)) != NULL) {
+ TAILQ_REMOVE(&cond->c_queue, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_CONDQ;
+ if ((pthread->timeout == 0) && (pthread->interrupted == 0))
+ /*
+ * Only exit the loop when we find a thread
+ * that hasn't timed out or been canceled;
+ * those threads are already running and don't
+ * need their run state changed.
+ */
+ break;
+ }
+
+ return(pthread);
+}
+
+/*
+ * Remove a waiting thread from a condition queue in descending priority
+ * order.
+ */
+static inline void
+cond_queue_remove(pthread_cond_t cond, pthread_t pthread)
+{
+ /*
+ * Because pthread_cond_timedwait() can timeout as well
+ * as be signaled by another thread, it is necessary to
+ * guard against removing the thread from the queue if
+ * it isn't in the queue.
+ */
+ if (pthread->flags & PTHREAD_FLAGS_IN_CONDQ) {
+ TAILQ_REMOVE(&cond->c_queue, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_CONDQ;
+ }
+}
+
+/*
+ * Enqueue a waiting thread to a condition queue in descending priority
+ * order.
+ */
+static inline void
+cond_queue_enq(pthread_cond_t cond, pthread_t pthread)
+{
+ pthread_t tid = TAILQ_LAST(&cond->c_queue, cond_head);
+
+ /*
+ * For the common case of all threads having equal priority,
+ * we perform a quick check against the priority of the thread
+ * at the tail of the queue.
+ */
+ if ((tid == NULL) || (pthread->active_priority <= tid->active_priority))
+ TAILQ_INSERT_TAIL(&cond->c_queue, pthread, qe);
+ else {
+ tid = TAILQ_FIRST(&cond->c_queue);
+ while (pthread->active_priority <= tid->active_priority)
+ tid = TAILQ_NEXT(tid, qe);
+ TAILQ_INSERT_BEFORE(tid, pthread, qe);
+ }
+ pthread->flags |= PTHREAD_FLAGS_IN_CONDQ;
+}
+#endif
diff --git a/lib/libkse/thread/thr_condattr_destroy.c b/lib/libkse/thread/thr_condattr_destroy.c
new file mode 100644
index 0000000..ad91228
--- /dev/null
+++ b/lib/libkse/thread/thr_condattr_destroy.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_condattr_destroy(pthread_condattr_t *attr)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ ret = EINVAL;
+ } else {
+ free(*attr);
+ *attr = NULL;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_condattr_init.c b/lib/libkse/thread/thr_condattr_init.c
new file mode 100644
index 0000000..3379898
--- /dev/null
+++ b/lib/libkse/thread/thr_condattr_init.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_condattr_init(pthread_condattr_t *attr)
+{
+ int ret;
+ pthread_condattr_t pattr;
+
+ if ((pattr = (pthread_condattr_t)
+ malloc(sizeof(struct pthread_cond_attr))) == NULL) {
+ ret = ENOMEM;
+ } else {
+ memcpy(pattr, &pthread_condattr_default,
+ sizeof(struct pthread_cond_attr));
+ *attr = pattr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_create.c b/lib/libkse/thread/thr_create.c
new file mode 100644
index 0000000..8621c05
--- /dev/null
+++ b/lib/libkse/thread/thr_create.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/mman.h>
+#ifdef _THREAD_SAFE
+#include <machine/reg.h>
+#include <pthread.h>
+#include "pthread_private.h"
+#include "libc_private.h"
+
+static u_int64_t next_uniqueid = 1;
+
+#define OFF(f) offsetof(struct pthread, f)
+int _thread_next_offset = OFF(tle.tqe_next);
+int _thread_uniqueid_offset = OFF(uniqueid);
+int _thread_state_offset = OFF(state);
+int _thread_name_offset = OFF(name);
+int _thread_sig_saved_offset = OFF(sig_saved);
+int _thread_saved_sigcontext_offset = OFF(saved_sigcontext);
+int _thread_saved_jmp_buf_offset = OFF(saved_jmp_buf);
+#undef OFF
+
+int _thread_PS_RUNNING_value = PS_RUNNING;
+int _thread_PS_DEAD_value = PS_DEAD;
+
+int
+pthread_create(pthread_t * thread, const pthread_attr_t * attr,
+ void *(*start_routine) (void *), void *arg)
+{
+ int f_gc = 0;
+ int ret = 0;
+ pthread_t gc_thread;
+ pthread_t new_thread;
+ pthread_attr_t pattr;
+ void *stack;
+
+ /*
+ * Locking functions in libc are required when there are
+ * threads other than the initial thread.
+ */
+ __isthreaded = 1;
+
+ /* Allocate memory for the thread structure: */
+ if ((new_thread = (pthread_t) malloc(sizeof(struct pthread))) == NULL) {
+ /* Insufficient memory to create a thread: */
+ ret = EAGAIN;
+ } else {
+ /* Check if default thread attributes are required: */
+ if (attr == NULL || *attr == NULL) {
+ /* Use the default thread attributes: */
+ pattr = &pthread_attr_default;
+ } else {
+ pattr = *attr;
+ }
+ /* Check if a stack was specified in the thread attributes: */
+ if ((stack = pattr->stackaddr_attr) != NULL) {
+ }
+ /* Allocate memory for a default-size stack: */
+ else if (pattr->stacksize_attr == PTHREAD_STACK_DEFAULT) {
+ struct stack *spare_stack;
+
+ /* Allocate or re-use a default-size stack. */
+
+ /*
+ * Use the garbage collector mutex for synchronization
+ * of the spare stack list.
+ */
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ if ((spare_stack = SLIST_FIRST(&_stackq)) != NULL) {
+ /* Use the spare stack. */
+ SLIST_REMOVE_HEAD(&_stackq, qe);
+
+ /* Unlock the garbage collector mutex. */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
+
+ stack = sizeof(struct stack)
+ + (void *) spare_stack
+ - PTHREAD_STACK_DEFAULT;
+ } else {
+ /* Unlock the garbage collector mutex. */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
+
+ /* Allocate a new stack. */
+ stack = _next_stack + PTHREAD_STACK_GUARD;
+ /*
+ * Even if stack allocation fails, we don't want
+ * to try to use this location again, so
+ * unconditionally decrement _next_stack. Under
+ * normal operating conditions, the most likely
+ * reason for an mmap() error is a stack
+ * overflow of the adjacent thread stack.
+ */
+ _next_stack -= (PTHREAD_STACK_DEFAULT
+ + PTHREAD_STACK_GUARD);
+
+ /* Red zone: */
+ if (mmap(_next_stack, PTHREAD_STACK_GUARD, 0,
+ MAP_ANON, -1, 0) == MAP_FAILED) {
+ ret = EAGAIN;
+ free(new_thread);
+ }
+ /* Stack: */
+ else if (mmap(stack,
+ PTHREAD_STACK_DEFAULT,
+ PROT_READ | PROT_WRITE,
+ MAP_STACK,
+ -1, 0) == MAP_FAILED) {
+ ret = EAGAIN;
+ munmap(_next_stack,
+ PTHREAD_STACK_GUARD);
+ free(new_thread);
+ }
+ }
+ }
+ /*
+ * The user wants a stack of a particular size. Lets hope they
+ * really know what they want, and simply malloc the stack.
+ */
+ else if ((stack = (void *) malloc(pattr->stacksize_attr))
+ == NULL) {
+ /* Insufficient memory to create a thread: */
+ ret = EAGAIN;
+ free(new_thread);
+ }
+
+ /* Check for errors: */
+ if (ret != 0) {
+ } else {
+ /* Initialise the thread structure: */
+ memset(new_thread, 0, sizeof(struct pthread));
+ new_thread->slice_usec = -1;
+ new_thread->sig_saved = 0;
+ new_thread->stack = stack;
+ new_thread->start_routine = start_routine;
+ new_thread->arg = arg;
+
+ new_thread->cancelflags = PTHREAD_CANCEL_ENABLE |
+ PTHREAD_CANCEL_DEFERRED;
+
+ /*
+ * Write a magic value to the thread structure
+ * to help identify valid ones:
+ */
+ new_thread->magic = PTHREAD_MAGIC;
+
+ /* Initialise the thread for signals: */
+ new_thread->sigmask = _thread_run->sigmask;
+
+ /* Initialise the jump buffer: */
+ setjmp(new_thread->saved_jmp_buf);
+
+ /*
+ * Set up new stack frame so that it looks like it
+ * returned from a longjmp() to the beginning of
+ * _thread_start().
+ */
+#if defined(__FreeBSD__)
+#if defined(__alpha__)
+ new_thread->saved_jmp_buf[0]._jb[2] = (long) _thread_start;
+ new_thread->saved_jmp_buf[0]._jb[4 + R_RA] = 0;
+ new_thread->saved_jmp_buf[0]._jb[4 + R_T12] = (long) _thread_start;
+#else
+ new_thread->saved_jmp_buf[0]._jb[0] = (long) _thread_start;
+#endif
+#elif defined(__NetBSD__)
+#if defined(__alpha__)
+ new_thread->saved_jmp_buf[2] = (long) _thread_start;
+ new_thread->saved_jmp_buf[4 + R_RA] = 0;
+ new_thread->saved_jmp_buf[4 + R_T12] = (long) _thread_start;
+#else
+ new_thread->saved_jmp_buf[0] = (long) _thread_start;
+#endif
+#else
+#error "Don't recognize this operating system!"
+#endif
+
+ /* The stack starts high and builds down: */
+#if defined(__FreeBSD__)
+#if defined(__alpha__)
+ new_thread->saved_jmp_buf[0]._jb[4 + R_SP] = (long) new_thread->stack + pattr->stacksize_attr - sizeof(double);
+#else
+ new_thread->saved_jmp_buf[0]._jb[2] = (int) (new_thread->stack + pattr->stacksize_attr - sizeof(double));
+#endif
+#elif defined(__NetBSD__)
+#if defined(__alpha__)
+ new_thread->saved_jmp_buf[4 + R_SP] = (long) new_thread->stack + pattr->stacksize_attr - sizeof(double);
+#else
+ new_thread->saved_jmp_buf[2] = (long) new_thread->stack + pattr->stacksize_attr - sizeof(double);
+#endif
+#else
+#error "Don't recognize this operating system!"
+#endif
+
+ /* Copy the thread attributes: */
+ memcpy(&new_thread->attr, pattr, sizeof(struct pthread_attr));
+
+ /*
+ * Check if this thread is to inherit the scheduling
+ * attributes from its parent:
+ */
+ if (new_thread->attr.flags & PTHREAD_INHERIT_SCHED) {
+ /* Copy the scheduling attributes: */
+ new_thread->base_priority
+ = _thread_run->base_priority;
+ new_thread->attr.prio
+ = _thread_run->base_priority;
+ new_thread->attr.sched_policy
+ = _thread_run->attr.sched_policy;
+ } else {
+ /*
+ * Use just the thread priority, leaving the
+ * other scheduling attributes as their
+ * default values:
+ */
+ new_thread->base_priority
+ = new_thread->attr.prio;
+ }
+ new_thread->active_priority = new_thread->base_priority;
+ new_thread->inherited_priority = 0;
+
+ /* Initialise the join queue for the new thread: */
+ TAILQ_INIT(&(new_thread->join_queue));
+
+ /* Initialize the mutex queue: */
+ TAILQ_INIT(&new_thread->mutexq);
+
+ /* Initialise hooks in the thread structure: */
+ new_thread->specific_data = NULL;
+ new_thread->cleanup = NULL;
+ new_thread->flags = 0;
+ new_thread->poll_data.nfds = 0;
+ new_thread->poll_data.fds = NULL;
+
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /*
+ * Initialise the unique id which GDB uses to
+ * track threads.
+ */
+ new_thread->uniqueid = next_uniqueid++;
+
+ /*
+ * Check if the garbage collector thread
+ * needs to be started.
+ */
+ f_gc = (TAILQ_FIRST(&_thread_list) == _thread_initial);
+
+ /* Add the thread to the linked list of all threads: */
+ TAILQ_INSERT_HEAD(&_thread_list, new_thread, tle);
+
+ if (pattr->suspend == PTHREAD_CREATE_SUSPENDED) {
+ new_thread->state = PS_SUSPENDED;
+ PTHREAD_WAITQ_INSERT(new_thread);
+ } else {
+ new_thread->state = PS_RUNNING;
+ PTHREAD_PRIOQ_INSERT_TAIL(new_thread);
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding
+ * if necessary.
+ */
+ _thread_kern_sig_undefer();
+
+ /* Return a pointer to the thread structure: */
+ (*thread) = new_thread;
+
+ /* Schedule the new user thread: */
+ _thread_kern_sched(NULL);
+
+ /*
+ * Start a garbage collector thread
+ * if necessary.
+ */
+ if (f_gc && pthread_create(&gc_thread,NULL,
+ _thread_gc,NULL) != 0)
+ PANIC("Can't create gc thread");
+ }
+ }
+
+ /* Return the status: */
+ return (ret);
+}
+
+void
+_thread_start(void)
+{
+ /* We just left the scheduler via longjmp: */
+ _thread_kern_in_sched = 0;
+
+ /* Run the current thread's start routine with argument: */
+ pthread_exit(_thread_run->start_routine(_thread_run->arg));
+
+ /* This point should never be reached. */
+ PANIC("Thread has resumed after exit");
+}
+#endif
diff --git a/lib/libkse/thread/thr_detach.c b/lib/libkse/thread/thr_detach.c
new file mode 100644
index 0000000..164c7df
--- /dev/null
+++ b/lib/libkse/thread/thr_detach.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_detach(pthread_t pthread)
+{
+ int rval = 0;
+ int status;
+ pthread_t next_thread;
+
+ /* Check for invalid calling parameters: */
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+
+ /* Check if the thread has not been detached: */
+ else if ((pthread->attr.flags & PTHREAD_DETACHED) == 0) {
+ /* Flag the thread as detached: */
+ pthread->attr.flags |= PTHREAD_DETACHED;
+
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Enter a loop to bring all threads off the join queue: */
+ while ((next_thread = TAILQ_FIRST(&pthread->join_queue)) != NULL) {
+ /* Remove the thread from the queue: */
+ TAILQ_REMOVE(&pthread->join_queue, next_thread, qe);
+
+ /* Make the thread run: */
+ PTHREAD_NEW_STATE(next_thread,PS_RUNNING);
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding if a
+ * scheduling signal occurred while in the critical region.
+ */
+ _thread_kern_sig_undefer();
+ } else
+ /* Return an error: */
+ rval = EINVAL;
+
+ /* Return the completion status: */
+ return (rval);
+}
+#endif
diff --git a/lib/libkse/thread/thr_equal.c b/lib/libkse/thread/thr_equal.c
new file mode 100644
index 0000000..e03ba4a
--- /dev/null
+++ b/lib/libkse/thread/thr_equal.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_equal(pthread_t t1, pthread_t t2)
+{
+ /* Compare the two thread pointers: */
+ return (t1 == t2);
+}
+#endif
diff --git a/lib/libkse/thread/thr_exit.c b/lib/libkse/thread/thr_exit.c
new file mode 100644
index 0000000..abe4b27
--- /dev/null
+++ b/lib/libkse/thread/thr_exit.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+void _exit(int status)
+{
+ int flags;
+ int i;
+ struct itimerval itimer;
+
+ /* Disable the interval timer: */
+ itimer.it_interval.tv_sec = 0;
+ itimer.it_interval.tv_usec = 0;
+ itimer.it_value.tv_sec = 0;
+ itimer.it_value.tv_usec = 0;
+ setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL);
+
+ /* Close the pthread kernel pipe: */
+ _thread_sys_close(_thread_kern_pipe[0]);
+ _thread_sys_close(_thread_kern_pipe[1]);
+
+ /*
+ * Enter a loop to set all file descriptors to blocking
+ * if they were not created as non-blocking:
+ */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /* Check if this file descriptor is in use: */
+ if (_thread_fd_table[i] != NULL &&
+ !(_thread_fd_table[i]->flags & O_NONBLOCK)) {
+ /* Get the current flags: */
+ flags = _thread_sys_fcntl(i, F_GETFL, NULL);
+ /* Clear the nonblocking file descriptor flag: */
+ _thread_sys_fcntl(i, F_SETFL, flags & ~O_NONBLOCK);
+ }
+ }
+
+ /* Call the _exit syscall: */
+ _thread_sys__exit(status);
+}
+
+void
+_thread_exit(char *fname, int lineno, char *string)
+{
+ char s[256];
+
+ /* Prepare an error message string: */
+ strcpy(s, "Fatal error '");
+ strcat(s, string);
+ strcat(s, "' at line ? ");
+ strcat(s, "in file ");
+ strcat(s, fname);
+ strcat(s, " (errno = ?");
+ strcat(s, ")\n");
+
+ /* Write the string to the standard error file descriptor: */
+ _thread_sys_write(2, s, strlen(s));
+
+ /* Force this process to exit: */
+ /* XXX - Do we want abort to be conditional on _PTHREADS_INVARIANTS? */
+#if defined(_PTHREADS_INVARIANTS)
+ abort();
+#else
+ _exit(1);
+#endif
+}
+
+/*
+ * Only called when a thread is cancelled. It may be more useful
+ * to call it from pthread_exit() if other ways of asynchronous or
+ * abnormal thread termination can be found.
+ */
+void
+_thread_exit_cleanup(void)
+{
+ /*
+ * POSIX states that cancellation/termination of a thread should
+ * not release any visible resources (such as mutexes) and that
+ * it is the applications responsibility. Resources that are
+ * internal to the threads library, including file and fd locks,
+ * are not visible to the application and need to be released.
+ */
+ /* Unlock all owned fd locks: */
+ _thread_fd_unlock_owned(_thread_run);
+
+ /* Unlock all owned file locks: */
+ _funlock_owned(_thread_run);
+
+ /* Unlock all private mutexes: */
+ _mutex_unlock_private(_thread_run);
+
+ /*
+ * This still isn't quite correct because we don't account
+ * for held spinlocks (see libc/stdlib/malloc.c).
+ */
+}
+
+void
+pthread_exit(void *status)
+{
+ pthread_t pthread;
+
+ /* Check if this thread is already in the process of exiting: */
+ if ((_thread_run->flags & PTHREAD_EXITING) != 0) {
+ char msg[128];
+ snprintf(msg, sizeof(msg), "Thread %p has called pthread_exit() from a destructor. POSIX 1003.1 1996 s16.2.5.2 does not allow this!",_thread_run);
+ PANIC(msg);
+ }
+
+ /* Flag this thread as exiting: */
+ _thread_run->flags |= PTHREAD_EXITING;
+
+ /* Save the return value: */
+ _thread_run->ret = status;
+
+ while (_thread_run->cleanup != NULL) {
+ pthread_cleanup_pop(1);
+ }
+
+ if (_thread_run->attr.cleanup_attr != NULL) {
+ _thread_run->attr.cleanup_attr(_thread_run->attr.arg_attr);
+ }
+ /* Check if there is thread specific data: */
+ if (_thread_run->specific_data != NULL) {
+ /* Run the thread-specific data destructors: */
+ _thread_cleanupspecific();
+ }
+
+ /* Free thread-specific poll_data structure, if allocated: */
+ if (_thread_run->poll_data.fds != NULL) {
+ free(_thread_run->poll_data.fds);
+ _thread_run->poll_data.fds = NULL;
+ }
+
+ /*
+ * Defer signals to protect the scheduling queues from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Check if there are any threads joined to this one: */
+ while ((pthread = TAILQ_FIRST(&(_thread_run->join_queue))) != NULL) {
+ /* Remove the thread from the queue: */
+ TAILQ_REMOVE(&_thread_run->join_queue, pthread, qe);
+
+ /* Wake the joined thread and let it detach this thread: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding if necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ /*
+ * Lock the garbage collector mutex to ensure that the garbage
+ * collector is not using the dead thread list.
+ */
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* Add this thread to the list of dead threads. */
+ TAILQ_INSERT_HEAD(&_dead_list, _thread_run, dle);
+
+ /*
+ * Defer signals to protect the scheduling queues from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Remove this thread from the thread list: */
+ TAILQ_REMOVE(&_thread_list, _thread_run, tle);
+
+ /*
+ * Undefer and handle pending signals, yielding if necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ /*
+ * Signal the garbage collector thread that there is something
+ * to clean up.
+ */
+ if (pthread_cond_signal(&_gc_cond) != 0)
+ PANIC("Cannot signal gc cond");
+
+ /*
+ * Mark the thread as dead so it will not return if it
+ * gets context switched out when the mutex is unlocked.
+ */
+ PTHREAD_SET_STATE(_thread_run, PS_DEAD);
+
+ /* Unlock the garbage collector mutex: */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* This this thread will never be re-scheduled. */
+ _thread_kern_sched(NULL);
+
+ /* This point should not be reached. */
+ PANIC("Dead thread has resumed");
+}
+#endif
diff --git a/lib/libkse/thread/thr_fcntl.c b/lib/libkse/thread/thr_fcntl.c
new file mode 100644
index 0000000..878554c
--- /dev/null
+++ b/lib/libkse/thread/thr_fcntl.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+fcntl(int fd, int cmd,...)
+{
+ int flags = 0;
+ int nonblock;
+ int oldfd;
+ int ret;
+ va_list ap;
+
+ _thread_enter_cancellation_point();
+
+ /* Lock the file descriptor: */
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ /* Initialise the variable argument list: */
+ va_start(ap, cmd);
+
+ /* Process according to file control command type: */
+ switch (cmd) {
+ /* Duplicate a file descriptor: */
+ case F_DUPFD:
+ /*
+ * Get the file descriptor that the caller wants to
+ * use:
+ */
+ oldfd = va_arg(ap, int);
+
+ /* Initialise the file descriptor table entry: */
+ if ((ret = _thread_sys_fcntl(fd, cmd, oldfd)) < 0) {
+ }
+ /* Initialise the file descriptor table entry: */
+ else if (_thread_fd_table_init(ret) != 0) {
+ /* Quietly close the file: */
+ _thread_sys_close(ret);
+
+ /* Reset the file descriptor: */
+ ret = -1;
+ } else {
+ /*
+ * Save the file open flags so that they can
+ * be checked later:
+ */
+ _thread_fd_table[ret]->flags = _thread_fd_table[fd]->flags;
+ }
+ break;
+ case F_SETFD:
+ flags = va_arg(ap, int);
+ ret = _thread_sys_fcntl(fd, cmd, flags);
+ break;
+ case F_GETFD:
+ ret = _thread_sys_fcntl(fd, cmd, 0);
+ break;
+ case F_GETFL:
+ ret = _thread_fd_table[fd]->flags;
+ break;
+ case F_SETFL:
+ /*
+ * Get the file descriptor flags passed by the
+ * caller:
+ */
+ flags = va_arg(ap, int);
+
+ /*
+ * Check if the user wants a non-blocking file
+ * descriptor:
+ */
+ nonblock = flags & O_NONBLOCK;
+
+ /* Set the file descriptor flags: */
+ if ((ret = _thread_sys_fcntl(fd, cmd, flags | O_NONBLOCK)) != 0) {
+
+ /* Get the flags so that we behave like the kernel: */
+ } else if ((flags = _thread_sys_fcntl(fd,
+ F_GETFL, 0)) == -1) {
+ /* Error getting flags: */
+ ret = -1;
+
+ /*
+ * Check if the file descriptor is non-blocking
+ * with respect to the user:
+ */
+ } else if (nonblock)
+ /* A non-blocking descriptor: */
+ _thread_fd_table[fd]->flags = flags | O_NONBLOCK;
+ else
+ /* Save the flags: */
+ _thread_fd_table[fd]->flags = flags & ~O_NONBLOCK;
+ break;
+ default:
+ /* Might want to make va_arg use a union */
+ ret = _thread_sys_fcntl(fd, cmd, va_arg(ap, void *));
+ break;
+ }
+
+ /* Free variable arguments: */
+ va_end(ap);
+
+ /* Unlock the file descriptor: */
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ _thread_leave_cancellation_point();
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_find_thread.c b/lib/libkse/thread/thr_find_thread.c
new file mode 100644
index 0000000..d4a3bbd
--- /dev/null
+++ b/lib/libkse/thread/thr_find_thread.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Find a thread in the linked list of active threads: */
+int
+_find_thread(pthread_t pthread)
+{
+ pthread_t pthread1;
+
+ /* Check if the caller has specified an invalid thread: */
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
+ /* Invalid thread: */
+ return(EINVAL);
+
+ /*
+ * Defer signals to protect the thread list from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Search for the specified thread: */
+ TAILQ_FOREACH(pthread1, &_thread_list, tle) {
+ if (pthread == pthread1)
+ break;
+ }
+
+ /* Undefer and handle pending signals, yielding if necessary: */
+ _thread_kern_sig_undefer();
+
+ /* Return zero if the thread exists: */
+ return ((pthread1 != NULL) ? 0:ESRCH);
+}
+
+/* Find a thread in the linked list of dead threads: */
+int
+_find_dead_thread(pthread_t pthread)
+{
+ pthread_t pthread1;
+
+ /* Check if the caller has specified an invalid thread: */
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
+ /* Invalid thread: */
+ return(EINVAL);
+
+ /*
+ * Lock the garbage collector mutex to ensure that the garbage
+ * collector is not using the dead thread list.
+ */
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* Search for the specified thread: */
+ TAILQ_FOREACH(pthread1, &_dead_list, dle) {
+ if (pthread1 == pthread)
+ break;
+ }
+
+ /* Unlock the garbage collector mutex: */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* Return zero if the thread exists: */
+ return ((pthread1 != NULL) ? 0:ESRCH);
+}
+#endif
diff --git a/lib/libkse/thread/thr_fork.c b/lib/libkse/thread/thr_fork.c
new file mode 100644
index 0000000..b8d72dc
--- /dev/null
+++ b/lib/libkse/thread/thr_fork.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+pid_t
+fork(void)
+{
+ int i, flags;
+ pid_t ret;
+ pthread_t pthread;
+ pthread_t pthread_save;
+
+ /*
+ * Defer signals to protect the scheduling queues from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Fork a new process: */
+ if ((ret = _thread_sys_fork()) != 0) {
+ /* Parent process or error. Nothing to do here. */
+ } else {
+ /* Close the pthread kernel pipe: */
+ _thread_sys_close(_thread_kern_pipe[0]);
+ _thread_sys_close(_thread_kern_pipe[1]);
+
+ /* Reset signals pending for the running thread: */
+ sigemptyset(&_thread_run->sigpend);
+
+ /*
+ * Create a pipe that is written to by the signal handler to
+ * prevent signals being missed in calls to
+ * _thread_sys_select:
+ */
+ if (_thread_sys_pipe(_thread_kern_pipe) != 0) {
+ /* Cannot create pipe, so abort: */
+ PANIC("Cannot create pthread kernel pipe for forked process");
+ }
+ /* Get the flags for the read pipe: */
+ else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[0], F_GETFL, NULL)) == -1) {
+ /* Abort this application: */
+ abort();
+ }
+ /* Make the read pipe non-blocking: */
+ else if (_thread_sys_fcntl(_thread_kern_pipe[0], F_SETFL, flags | O_NONBLOCK) == -1) {
+ /* Abort this application: */
+ abort();
+ }
+ /* Get the flags for the write pipe: */
+ else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[1], F_GETFL, NULL)) == -1) {
+ /* Abort this application: */
+ abort();
+ }
+ /* Make the write pipe non-blocking: */
+ else if (_thread_sys_fcntl(_thread_kern_pipe[1], F_SETFL, flags | O_NONBLOCK) == -1) {
+ /* Abort this application: */
+ abort();
+ }
+ /* Reinitialize the GC mutex: */
+ else if (_mutex_reinit(&_gc_mutex) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot initialize GC mutex for forked process");
+ }
+ /* Reinitialize the GC condition variable: */
+ else if (_cond_reinit(&_gc_cond) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot initialize GC condvar for forked process");
+ }
+ /* Initialize the ready queue: */
+ else if (_pq_init(&_readyq) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot initialize priority ready queue.");
+ } else {
+ /*
+ * Enter a loop to remove all threads other than
+ * the running thread from the thread list:
+ */
+ pthread = TAILQ_FIRST(&_thread_list);
+ while (pthread != NULL) {
+ /* Save the thread to be freed: */
+ pthread_save = pthread;
+
+ /*
+ * Advance to the next thread before
+ * destroying the current thread:
+ */
+ pthread = TAILQ_NEXT(pthread, dle);
+
+ /* Make sure this isn't the running thread: */
+ if (pthread_save != _thread_run) {
+ /* Remove this thread from the list: */
+ TAILQ_REMOVE(&_thread_list,
+ pthread_save, tle);
+
+ if (pthread_save->attr.stackaddr_attr ==
+ NULL && pthread_save->stack != NULL)
+ if (pthread_save->attr.stacksize_attr
+ == PTHREAD_STACK_DEFAULT) {
+ /*
+ * Default-size stack. Cache
+ * it:
+ */
+ struct stack *spare_stack;
+
+ spare_stack
+ = (pthread_save->stack
+ + PTHREAD_STACK_DEFAULT
+ - sizeof(struct stack));
+ SLIST_INSERT_HEAD(
+ &_stackq,
+ spare_stack,
+ qe);
+ } else
+ /*
+ * Free the stack of
+ * the dead thread:
+ */
+ free(pthread_save->stack);
+
+ if (pthread_save->specific_data != NULL)
+ free(pthread_save->specific_data);
+
+ if (pthread_save->poll_data.fds != NULL)
+ free(pthread_save->poll_data.fds);
+
+ free(pthread_save);
+ }
+ }
+
+ /* Treat the current thread as the initial thread: */
+ _thread_initial = _thread_run;
+
+ /* Re-init the dead thread list: */
+ TAILQ_INIT(&_dead_list);
+
+ /* Re-init the waiting and work queues. */
+ TAILQ_INIT(&_waitingq);
+ TAILQ_INIT(&_workq);
+
+ /* Re-init the threads mutex queue: */
+ TAILQ_INIT(&_thread_run->mutexq);
+
+ /* No spinlocks yet: */
+ _spinblock_count = 0;
+
+ /* Don't queue signals yet: */
+ _queue_signals = 0;
+
+ /* Initialize signal handling: */
+ _thread_sig_init();
+
+ /* Initialize the scheduling switch hook routine: */
+ _sched_switch_hook = NULL;
+
+ /* Clear out any locks in the file descriptor table: */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ if (_thread_fd_table[i] != NULL) {
+ /* Initialise the file locks: */
+ memset(&_thread_fd_table[i]->lock, 0,
+ sizeof(_thread_fd_table[i]->lock));
+ _thread_fd_table[i]->r_owner = NULL;
+ _thread_fd_table[i]->w_owner = NULL;
+ _thread_fd_table[i]->r_fname = NULL;
+ _thread_fd_table[i]->w_fname = NULL;
+ _thread_fd_table[i]->r_lineno = 0;;
+ _thread_fd_table[i]->w_lineno = 0;;
+ _thread_fd_table[i]->r_lockcount = 0;;
+ _thread_fd_table[i]->w_lockcount = 0;;
+
+ /* Initialise the read/write queues: */
+ TAILQ_INIT(&_thread_fd_table[i]->r_queue);
+ TAILQ_INIT(&_thread_fd_table[i]->w_queue);
+ }
+ }
+ }
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding if necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ /* Return the process ID: */
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_fsync.c b/lib/libkse/thread/thr_fsync.c
new file mode 100644
index 0000000..21c3b56
--- /dev/null
+++ b/lib/libkse/thread/thr_fsync.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+fsync(int fd)
+{
+ int ret;
+
+ _thread_enter_cancellation_point();
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ ret = _thread_sys_fsync(fd);
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_getprio.c b/lib/libkse/thread/thr_getprio.c
new file mode 100644
index 0000000..2f94b86
--- /dev/null
+++ b/lib/libkse/thread/thr_getprio.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_getprio(pthread_t pthread)
+{
+ int policy, ret;
+ struct sched_param param;
+
+ if ((ret = pthread_getschedparam(pthread, &policy, &param)) == 0)
+ ret = param.sched_priority;
+ else {
+ /* Invalid thread: */
+ errno = ret;
+ ret = -1;
+ }
+
+ /* Return the thread priority or an error status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_getschedparam.c b/lib/libkse/thread/thr_getschedparam.c
new file mode 100644
index 0000000..09d8c1b
--- /dev/null
+++ b/lib/libkse/thread/thr_getschedparam.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_getschedparam(pthread_t pthread, int *policy,
+ struct sched_param *param)
+{
+ int ret;
+
+ if ((param == NULL) || (policy == NULL))
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+
+ /* Find the thread in the list of active threads: */
+ else if ((ret = _find_thread(pthread)) == 0) {
+ /* Return the threads base priority and scheduling policy: */
+ param->sched_priority = pthread->base_priority;
+ *policy = pthread->attr.sched_policy;
+ }
+
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_info.c b/lib/libkse/thread/thr_info.c
new file mode 100644
index 0000000..06b556e
--- /dev/null
+++ b/lib/libkse/thread/thr_info.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include <errno.h>
+#include "pthread_private.h"
+
+struct s_thread_info {
+ enum pthread_state state;
+ char *name;
+};
+
+/* Static variables: */
+static const struct s_thread_info thread_info[] = {
+ {PS_RUNNING , "Running"},
+ {PS_SIGTHREAD , "Waiting on signal thread"},
+ {PS_MUTEX_WAIT , "Waiting on a mutex"},
+ {PS_COND_WAIT , "Waiting on a condition variable"},
+ {PS_FDLR_WAIT , "Waiting for a file read lock"},
+ {PS_FDLW_WAIT , "Waiting for a file write lock"},
+ {PS_FDR_WAIT , "Waiting for read"},
+ {PS_FDW_WAIT , "Waiting for write"},
+ {PS_FILE_WAIT , "Waiting for FILE lock"},
+ {PS_POLL_WAIT , "Waiting on poll"},
+ {PS_SELECT_WAIT , "Waiting on select"},
+ {PS_SLEEP_WAIT , "Sleeping"},
+ {PS_WAIT_WAIT , "Waiting process"},
+ {PS_SIGSUSPEND , "Suspended, waiting for a signal"},
+ {PS_SIGWAIT , "Waiting for a signal"},
+ {PS_SPINBLOCK , "Waiting for a spinlock"},
+ {PS_JOIN , "Waiting to join"},
+ {PS_SUSPENDED , "Suspended"},
+ {PS_DEAD , "Dead"},
+ {PS_DEADLOCK , "Deadlocked"},
+ {PS_STATE_MAX , "Not a real state!"}
+};
+
+void
+_thread_dump_info(void)
+{
+ char s[512];
+ int fd;
+ int i;
+ int j;
+ pthread_t pthread;
+ char tmpfile[128];
+ pq_list_t *pq_list;
+
+ for (i = 0; i < 100000; i++) {
+ snprintf(tmpfile, sizeof(tmpfile), "/tmp/uthread.dump.%u.%i",
+ getpid(), i);
+ /* Open the dump file for append and create it if necessary: */
+ if ((fd = _thread_sys_open(tmpfile, O_RDWR | O_CREAT | O_EXCL,
+ 0666)) < 0) {
+ /* Can't open the dump file. */
+ if (errno == EEXIST)
+ continue;
+ /*
+ * We only need to continue in case of
+ * EEXIT error. Most other error
+ * codes means that we will fail all
+ * the times.
+ */
+ return;
+ } else {
+ break;
+ }
+ }
+ if (i==100000) {
+ /* all 100000 possibilities are in use :( */
+ return;
+ } else {
+ /* Output a header for active threads: */
+ strcpy(s, "\n\n=============\nACTIVE THREADS\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report each thread in the global list: */
+ TAILQ_FOREACH(pthread, &_thread_list, tle) {
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
+ break;
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->base_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Check if this is the running thread: */
+ if (pthread == _thread_run) {
+ /* Output a record for the running thread: */
+ strcpy(s, "This is the running thread\n");
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ /* Check if this is the initial thread: */
+ if (pthread == _thread_initial) {
+ /* Output a record for the initial thread: */
+ strcpy(s, "This is the initial thread\n");
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ /* Process according to thread state: */
+ switch (pthread->state) {
+ /* File descriptor read lock wait: */
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ /* Write the lock details: */
+ snprintf(s, sizeof(s), "fd %d[%s:%d]",
+ pthread->data.fd.fd,
+ pthread->data.fd.fname,
+ pthread->data.fd.branch);
+ _thread_sys_write(fd, s, strlen(s));
+ snprintf(s, sizeof(s), "owner %pr/%pw\n",
+ _thread_fd_table[pthread->data.fd.fd]->r_owner,
+ _thread_fd_table[pthread->data.fd.fd]->w_owner);
+ _thread_sys_write(fd, s, strlen(s));
+ break;
+ case PS_SIGWAIT:
+ snprintf(s, sizeof(s), "sigmask (hi)");
+ _thread_sys_write(fd, s, strlen(s));
+ for (i = _SIG_WORDS - 1; i >= 0; i--) {
+ snprintf(s, sizeof(s), "%08x\n",
+ pthread->sigmask.__bits[i]);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ snprintf(s, sizeof(s), "(lo)\n");
+ _thread_sys_write(fd, s, strlen(s));
+ break;
+
+ /*
+ * Trap other states that are not explicitly
+ * coded to dump information:
+ */
+ default:
+ /* Nothing to do here. */
+ break;
+ }
+ }
+
+ /* Output a header for ready threads: */
+ strcpy(s, "\n\n=============\nREADY THREADS\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report each thread in the ready queue: */
+ TAILQ_FOREACH (pq_list, &_readyq.pq_queue, pl_link) {
+ TAILQ_FOREACH(pthread, &pq_list->pl_head, pqe) {
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
+ break;
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->base_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ }
+
+ /* Output a header for waiting threads: */
+ strcpy(s, "\n\n=============\nWAITING THREADS\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report each thread in the waiting queue: */
+ TAILQ_FOREACH (pthread, &_waitingq, pqe) {
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
+ break;
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->base_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+
+ /* Output a header for threads in the work queue: */
+ strcpy(s, "\n\n=============\nTHREADS IN WORKQ\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report each thread in the waiting queue: */
+ TAILQ_FOREACH (pthread, &_workq, qe) {
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
+ break;
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->base_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+
+ /* Check if there are no dead threads: */
+ if (TAILQ_FIRST(&_dead_list) == NULL) {
+ /* Output a record: */
+ strcpy(s, "\n\nTHERE ARE NO DEAD THREADS\n");
+ _thread_sys_write(fd, s, strlen(s));
+ } else {
+ /* Output a header for dead threads: */
+ strcpy(s, "\n\nDEAD THREADS\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /*
+ * Enter a loop to report each thread in the global
+ * dead thread list:
+ */
+ TAILQ_FOREACH(pthread, &_dead_list, dle) {
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "Thread %p prio %3d [%s:%d]\n",
+ pthread, pthread->base_priority,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ }
+
+ /* Output a header for file descriptors: */
+ snprintf(s, sizeof(s), "\n\n=============\nFILE DESCRIPTOR TABLE (table size %d)\n\n",_thread_dtablesize);
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report file descriptor lock usage: */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /*
+ * Check if memory is allocated for this file
+ * descriptor:
+ */
+ if (_thread_fd_table[i] != NULL) {
+ /* Report the file descriptor lock status: */
+ snprintf(s, sizeof(s),
+ "fd[%3d] read owner %p count %d [%s:%d]\n write owner %p count %d [%s:%d]\n",
+ i,
+ _thread_fd_table[i]->r_owner,
+ _thread_fd_table[i]->r_lockcount,
+ _thread_fd_table[i]->r_fname,
+ _thread_fd_table[i]->r_lineno,
+ _thread_fd_table[i]->w_owner,
+ _thread_fd_table[i]->w_lockcount,
+ _thread_fd_table[i]->w_fname,
+ _thread_fd_table[i]->w_lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ }
+
+ /* Close the dump file: */
+ _thread_sys_close(fd);
+ }
+ return;
+}
+
+/* Set the thread name for debug: */
+void
+pthread_set_name_np(pthread_t thread, char *name)
+{
+ /* Check if the caller has specified a valid thread: */
+ if (thread != NULL && thread->magic == PTHREAD_MAGIC)
+ thread->name = strdup(name);
+ return;
+}
+#endif
diff --git a/lib/libkse/thread/thr_init.c b/lib/libkse/thread/thr_init.c
new file mode 100644
index 0000000..bab7e5b
--- /dev/null
+++ b/lib/libkse/thread/thr_init.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/* Allocate space for global thread variables here: */
+#define GLOBAL_PTHREAD_PRIVATE
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <poll.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/ttycom.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/mman.h>
+#ifdef _THREAD_SAFE
+#include <machine/reg.h>
+#include <pthread.h>
+#include "pthread_private.h"
+
+#ifdef GCC_2_8_MADE_THREAD_AWARE
+typedef void *** (*dynamic_handler_allocator)();
+extern void __set_dynamic_handler_allocator(dynamic_handler_allocator);
+
+static pthread_key_t except_head_key;
+
+typedef struct {
+ void **__dynamic_handler_chain;
+ void *top_elt[2];
+} except_struct;
+
+static void ***dynamic_allocator_handler_fn()
+{
+ except_struct *dh = (except_struct *)pthread_getspecific(except_head_key);
+
+ if(dh == NULL) {
+ dh = (except_struct *)malloc( sizeof(except_struct) );
+ memset(dh, '\0', sizeof(except_struct));
+ dh->__dynamic_handler_chain= dh->top_elt;
+ pthread_setspecific(except_head_key, (void *)dh);
+ }
+ return &dh->__dynamic_handler_chain;
+}
+#endif /* GCC_2_8_MADE_THREAD_AWARE */
+
+/*
+ * Threaded process initialization
+ */
+void
+_thread_init(void)
+{
+ int fd;
+ int flags;
+ int i;
+ size_t len;
+ int mib[2];
+ struct clockinfo clockinfo;
+ struct sigaction act;
+
+ /* Check if this function has already been called: */
+ if (_thread_initial)
+ /* Only initialise the threaded application once. */
+ return;
+
+ /*
+ * Check for the special case of this process running as
+ * or in place of init as pid = 1:
+ */
+ if (getpid() == 1) {
+ /*
+ * Setup a new session for this process which is
+ * assumed to be running as root.
+ */
+ if (setsid() == -1)
+ PANIC("Can't set session ID");
+ if (revoke(_PATH_CONSOLE) != 0)
+ PANIC("Can't revoke console");
+ if ((fd = _thread_sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
+ PANIC("Can't open console");
+ if (setlogin("root") == -1)
+ PANIC("Can't set login to root");
+ if (_thread_sys_ioctl(fd,TIOCSCTTY, (char *) NULL) == -1)
+ PANIC("Can't set controlling terminal");
+ if (_thread_sys_dup2(fd,0) == -1 ||
+ _thread_sys_dup2(fd,1) == -1 ||
+ _thread_sys_dup2(fd,2) == -1)
+ PANIC("Can't dup2");
+ }
+
+ /* Get the standard I/O flags before messing with them : */
+ for (i = 0; i < 3; i++)
+ if (((_pthread_stdio_flags[i] =
+ _thread_sys_fcntl(i,F_GETFL, NULL)) == -1) &&
+ (errno != EBADF))
+ PANIC("Cannot get stdio flags");
+
+ /*
+ * Create a pipe that is written to by the signal handler to prevent
+ * signals being missed in calls to _select:
+ */
+ if (_thread_sys_pipe(_thread_kern_pipe) != 0) {
+ /* Cannot create pipe, so abort: */
+ PANIC("Cannot create kernel pipe");
+ }
+ /* Get the flags for the read pipe: */
+ else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[0], F_GETFL, NULL)) == -1) {
+ /* Abort this application: */
+ PANIC("Cannot get kernel read pipe flags");
+ }
+ /* Make the read pipe non-blocking: */
+ else if (_thread_sys_fcntl(_thread_kern_pipe[0], F_SETFL, flags | O_NONBLOCK) == -1) {
+ /* Abort this application: */
+ PANIC("Cannot make kernel read pipe non-blocking");
+ }
+ /* Get the flags for the write pipe: */
+ else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[1], F_GETFL, NULL)) == -1) {
+ /* Abort this application: */
+ PANIC("Cannot get kernel write pipe flags");
+ }
+ /* Make the write pipe non-blocking: */
+ else if (_thread_sys_fcntl(_thread_kern_pipe[1], F_SETFL, flags | O_NONBLOCK) == -1) {
+ /* Abort this application: */
+ PANIC("Cannot get kernel write pipe flags");
+ }
+ /* Allocate and initialize the ready queue: */
+ else if (_pq_alloc(&_readyq, PTHREAD_MIN_PRIORITY, PTHREAD_MAX_PRIORITY) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot allocate priority ready queue.");
+ }
+ /* Allocate memory for the thread structure of the initial thread: */
+ else if ((_thread_initial = (pthread_t) malloc(sizeof(struct pthread))) == NULL) {
+ /*
+ * Insufficient memory to initialise this application, so
+ * abort:
+ */
+ PANIC("Cannot allocate memory for initial thread");
+ } else {
+ /* Zero the global kernel thread structure: */
+ memset(&_thread_kern_thread, 0, sizeof(struct pthread));
+ _thread_kern_thread.flags = PTHREAD_FLAGS_PRIVATE;
+ memset(_thread_initial, 0, sizeof(struct pthread));
+
+ /* Initialize the waiting and work queues: */
+ TAILQ_INIT(&_waitingq);
+ TAILQ_INIT(&_workq);
+
+ /* Initialize the scheduling switch hook routine: */
+ _sched_switch_hook = NULL;
+
+ /* Initialize the thread stack cache: */
+ SLIST_INIT(&_stackq);
+
+ /* Create the red zone for the main stack. */
+ if (mmap((void *) USRSTACK
+ - PTHREAD_STACK_INITIAL,
+ PTHREAD_STACK_GUARD, 0, MAP_ANON,
+ -1, 0) == MAP_FAILED) {
+ PANIC("Cannot allocate red zone for initial thread");
+ }
+
+ /*
+ * Write a magic value to the thread structure
+ * to help identify valid ones:
+ */
+ _thread_initial->magic = PTHREAD_MAGIC;
+
+ /* Set the initial cancel state */
+ _thread_initial->cancelflags = PTHREAD_CANCEL_ENABLE |
+ PTHREAD_CANCEL_DEFERRED;
+
+ /* Default the priority of the initial thread: */
+ _thread_initial->base_priority = PTHREAD_DEFAULT_PRIORITY;
+ _thread_initial->active_priority = PTHREAD_DEFAULT_PRIORITY;
+ _thread_initial->inherited_priority = 0;
+
+ /* Initialise the state of the initial thread: */
+ _thread_initial->state = PS_RUNNING;
+
+ /* Initialise the queue: */
+ TAILQ_INIT(&(_thread_initial->join_queue));
+
+ /* Initialize the owned mutex queue and count: */
+ TAILQ_INIT(&(_thread_initial->mutexq));
+ _thread_initial->priority_mutex_count = 0;
+
+ /* Initialise the rest of the fields: */
+ _thread_initial->poll_data.nfds = 0;
+ _thread_initial->poll_data.fds = NULL;
+ _thread_initial->sig_defer_count = 0;
+ _thread_initial->yield_on_sig_undefer = 0;
+ _thread_initial->specific_data = NULL;
+ _thread_initial->cleanup = NULL;
+ _thread_initial->flags = 0;
+ _thread_initial->error = 0;
+ TAILQ_INIT(&_thread_list);
+ TAILQ_INSERT_HEAD(&_thread_list, _thread_initial, tle);
+ _thread_run = _thread_initial;
+
+ /* Initialise the global signal action structure: */
+ sigfillset(&act.sa_mask);
+ act.sa_handler = (void (*) ()) _thread_sig_handler;
+ act.sa_flags = 0;
+
+ /* Initialize signal handling: */
+ _thread_sig_init();
+
+ /* Enter a loop to get the existing signal status: */
+ for (i = 1; i < NSIG; i++) {
+ /* Check for signals which cannot be trapped: */
+ if (i == SIGKILL || i == SIGSTOP) {
+ }
+
+ /* Get the signal handler details: */
+ else if (_thread_sys_sigaction(i, NULL,
+ &_thread_sigact[i - 1]) != 0) {
+ /*
+ * Abort this process if signal
+ * initialisation fails:
+ */
+ PANIC("Cannot read signal handler info");
+ }
+ }
+
+ /*
+ * Install the signal handler for the most important
+ * signals that the user-thread kernel needs. Actually
+ * SIGINFO isn't really needed, but it is nice to have.
+ */
+ if (_thread_sys_sigaction(_SCHED_SIGNAL, &act, NULL) != 0 ||
+ _thread_sys_sigaction(SIGINFO, &act, NULL) != 0 ||
+ _thread_sys_sigaction(SIGCHLD, &act, NULL) != 0) {
+ /*
+ * Abort this process if signal initialisation fails:
+ */
+ PANIC("Cannot initialise signal handler");
+ }
+
+ /* Get the kernel clockrate: */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_CLOCKRATE;
+ len = sizeof (struct clockinfo);
+ if (sysctl(mib, 2, &clockinfo, &len, NULL, 0) == 0)
+ _clock_res_nsec = clockinfo.tick * 1000;
+
+ /* Get the table size: */
+ if ((_thread_dtablesize = getdtablesize()) < 0) {
+ /*
+ * Cannot get the system defined table size, so abort
+ * this process.
+ */
+ PANIC("Cannot get dtablesize");
+ }
+ /* Allocate memory for the file descriptor table: */
+ if ((_thread_fd_table = (struct fd_table_entry **) malloc(sizeof(struct fd_table_entry *) * _thread_dtablesize)) == NULL) {
+ /* Avoid accesses to file descriptor table on exit: */
+ _thread_dtablesize = 0;
+
+ /*
+ * Cannot allocate memory for the file descriptor
+ * table, so abort this process.
+ */
+ PANIC("Cannot allocate memory for file descriptor table");
+ }
+ /* Allocate memory for the pollfd table: */
+ if ((_thread_pfd_table = (struct pollfd *) malloc(sizeof(struct pollfd) * _thread_dtablesize)) == NULL) {
+ /*
+ * Cannot allocate memory for the file descriptor
+ * table, so abort this process.
+ */
+ PANIC("Cannot allocate memory for pollfd table");
+ } else {
+ /*
+ * Enter a loop to initialise the file descriptor
+ * table:
+ */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /* Initialise the file descriptor table: */
+ _thread_fd_table[i] = NULL;
+ }
+
+ /* Initialize stdio file descriptor table entries: */
+ for (i = 0; i < 3; i++) {
+ if ((_thread_fd_table_init(i) != 0) &&
+ (errno != EBADF))
+ PANIC("Cannot initialize stdio file "
+ "descriptor table entry");
+ }
+ }
+ }
+
+#ifdef GCC_2_8_MADE_THREAD_AWARE
+ /* Create the thread-specific data for the exception linked list. */
+ if(pthread_key_create(&except_head_key, NULL) != 0)
+ PANIC("Failed to create thread specific execption head");
+
+ /* Setup the gcc exception handler per thread. */
+ __set_dynamic_handler_allocator( dynamic_allocator_handler_fn );
+#endif /* GCC_2_8_MADE_THREAD_AWARE */
+
+ /* Initialise the garbage collector mutex and condition variable. */
+ if (pthread_mutex_init(&_gc_mutex,NULL) != 0 ||
+ pthread_cond_init(&_gc_cond,NULL) != 0)
+ PANIC("Failed to initialise garbage collector mutex or condvar");
+
+ gettimeofday(&kern_inc_prio_time, NULL);
+
+ return;
+}
+
+/*
+ * Special start up code for NetBSD/Alpha
+ */
+#if defined(__NetBSD__) && defined(__alpha__)
+int
+main(int argc, char *argv[], char *env);
+
+int
+_thread_main(int argc, char *argv[], char *env)
+{
+ _thread_init();
+ return (main(argc, argv, env));
+}
+#endif
+#else
+/*
+ * A stub for non-threaded programs.
+ */
+void
+_thread_init(void)
+{
+}
+#endif
diff --git a/lib/libkse/thread/thr_join.c b/lib/libkse/thread/thr_join.c
new file mode 100644
index 0000000..155dc64
--- /dev/null
+++ b/lib/libkse/thread/thr_join.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_join(pthread_t pthread, void **thread_return)
+{
+ int ret = 0;
+ pthread_t pthread1 = NULL;
+
+ _thread_enter_cancellation_point();
+
+ /* Check if the caller has specified an invalid thread: */
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) {
+ /* Invalid thread: */
+ _thread_leave_cancellation_point();
+ return(EINVAL);
+ }
+
+ /* Check if the caller has specified itself: */
+ if (pthread == _thread_run) {
+ /* Avoid a deadlock condition: */
+ _thread_leave_cancellation_point();
+ return(EDEADLK);
+ }
+
+ /*
+ * Find the thread in the list of active threads or in the
+ * list of dead threads:
+ */
+ if (_find_thread(pthread) == 0 ||
+ _find_dead_thread(pthread) == 0)
+ pthread1 = pthread;
+
+ if (pthread1 == NULL)
+ /* Return an error: */
+ ret = ESRCH;
+
+ /* Check if this thread has been detached: */
+ else if ((pthread->attr.flags & PTHREAD_DETACHED) != 0)
+ /* Return an error: */
+ ret = ESRCH;
+
+ /* Check if the thread is not dead: */
+ else if (pthread->state != PS_DEAD) {
+ /* Clear the interrupted flag: */
+ _thread_run->interrupted = 0;
+
+ /*
+ * Protect against being context switched out while
+ * adding this thread to the join queue.
+ */
+ _thread_kern_sig_defer();
+
+ /* Add the running thread to the join queue: */
+ TAILQ_INSERT_TAIL(&(pthread->join_queue), _thread_run, qe);
+
+ /* Schedule the next thread: */
+ _thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__);
+
+ if (_thread_run->interrupted != 0)
+ TAILQ_REMOVE(&(pthread->join_queue), _thread_run, qe);
+
+ _thread_kern_sig_undefer();
+
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+
+ /* Check if the thread is not detached: */
+ if ((pthread->attr.flags & PTHREAD_DETACHED) == 0) {
+ /* Check if the return value is required: */
+ if (thread_return)
+ /* Return the thread's return value: */
+ *thread_return = pthread->ret;
+ }
+ else
+ /* Return an error: */
+ ret = ESRCH;
+
+ /* Check if the return value is required: */
+ } else if (thread_return != NULL)
+ /* Return the thread's return value: */
+ *thread_return = pthread->ret;
+
+ _thread_leave_cancellation_point();
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c
new file mode 100644
index 0000000..b3fbc3a
--- /dev/null
+++ b/lib/libkse/thread/thr_kern.c
@@ -0,0 +1,1135 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <errno.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <setjmp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Static function prototype definitions: */
+static void
+_thread_kern_poll(int wait_reqd);
+
+static void
+dequeue_signals(void);
+
+static inline void
+thread_run_switch_hook(pthread_t thread_out, pthread_t thread_in);
+
+void
+_thread_kern_sched(ucontext_t * scp)
+{
+#ifndef __alpha__
+ char *fdata;
+#endif
+ pthread_t pthread, pthread_h = NULL;
+ struct itimerval itimer;
+ struct timespec ts, ts1;
+ struct timeval tv, tv1;
+ int set_timer = 0;
+
+ /*
+ * Flag the pthread kernel as executing scheduler code
+ * to avoid a scheduler signal from interrupting this
+ * execution and calling the scheduler again.
+ */
+ _thread_kern_in_sched = 1;
+
+ /* Check if this function was called from the signal handler: */
+ if (scp != NULL) {
+ /*
+ * Copy the signal context to the current thread's jump
+ * buffer:
+ */
+ memcpy(&_thread_run->saved_sigcontext, scp, sizeof(_thread_run->saved_sigcontext));
+
+#ifndef __alpha__
+ /* Point to the floating point data in the running thread: */
+ fdata = _thread_run->saved_fp;
+
+ /* Save the floating point data: */
+__asm__("fnsave %0": :"m"(*fdata));
+#endif
+
+ /* Flag the signal context as the last state saved: */
+ _thread_run->sig_saved = 1;
+ }
+ /* Save the state of the current thread: */
+ else if (setjmp(_thread_run->saved_jmp_buf) != 0) {
+ /*
+ * This point is reached when a longjmp() is called to
+ * restore the state of a thread.
+ *
+ * This is the normal way out of the scheduler.
+ */
+ _thread_kern_in_sched = 0;
+
+ if (((_thread_run->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0) &&
+ ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)) {
+ /*
+ * Cancellations override signals.
+ *
+ * Stick a cancellation point at the start of
+ * each async-cancellable thread's resumption.
+ *
+ * We allow threads woken at cancel points to do their
+ * own checks.
+ */
+ pthread_testcancel();
+ }
+
+ if (_sched_switch_hook != NULL) {
+ /* Run the installed switch hook: */
+ thread_run_switch_hook(_last_user_thread, _thread_run);
+ }
+
+ return;
+ } else
+ /* Flag the jump buffer was the last state saved: */
+ _thread_run->sig_saved = 0;
+
+ /* If the currently running thread is a user thread, save it: */
+ if ((_thread_run->flags & PTHREAD_FLAGS_PRIVATE) == 0)
+ _last_user_thread = _thread_run;
+
+ /*
+ * Enter a scheduling loop that finds the next thread that is
+ * ready to run. This loop completes when there are no more threads
+ * in the global list or when a thread has its state restored by
+ * either a sigreturn (if the state was saved as a sigcontext) or a
+ * longjmp (if the state was saved by a setjmp).
+ */
+ while (!(TAILQ_EMPTY(&_thread_list))) {
+ /* Get the current time of day: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
+
+ /*
+ * Protect the scheduling queues from access by the signal
+ * handler.
+ */
+ _queue_signals = 1;
+
+ if (_thread_run != &_thread_kern_thread) {
+
+ /*
+ * This thread no longer needs to yield the CPU.
+ */
+ _thread_run->yield_on_sig_undefer = 0;
+
+ /*
+ * Save the current time as the time that the thread
+ * became inactive:
+ */
+ _thread_run->last_inactive.tv_sec = tv.tv_sec;
+ _thread_run->last_inactive.tv_usec = tv.tv_usec;
+
+ /*
+ * Place the currently running thread into the
+ * appropriate queue(s).
+ */
+ switch (_thread_run->state) {
+ case PS_DEAD:
+ case PS_STATE_MAX: /* to silence -Wall */
+ /*
+ * Dead threads are not placed in any queue:
+ */
+ break;
+
+ case PS_RUNNING:
+ /*
+ * Runnable threads can't be placed in the
+ * priority queue until after waiting threads
+ * are polled (to preserve round-robin
+ * scheduling).
+ */
+ if ((_thread_run->slice_usec != -1) &&
+ (_thread_run->attr.sched_policy != SCHED_FIFO)) {
+ /*
+ * Accumulate the number of microseconds that
+ * this thread has run for:
+ */
+ _thread_run->slice_usec +=
+ (_thread_run->last_inactive.tv_sec -
+ _thread_run->last_active.tv_sec) * 1000000 +
+ _thread_run->last_inactive.tv_usec -
+ _thread_run->last_active.tv_usec;
+
+ /* Check for time quantum exceeded: */
+ if (_thread_run->slice_usec > TIMESLICE_USEC)
+ _thread_run->slice_usec = -1;
+ }
+ break;
+
+ /*
+ * States which do not depend on file descriptor I/O
+ * operations or timeouts:
+ */
+ case PS_DEADLOCK:
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ case PS_JOIN:
+ case PS_MUTEX_WAIT:
+ case PS_SIGSUSPEND:
+ case PS_SIGTHREAD:
+ case PS_SIGWAIT:
+ case PS_SUSPENDED:
+ case PS_WAIT_WAIT:
+ /* No timeouts for these states: */
+ _thread_run->wakeup_time.tv_sec = -1;
+ _thread_run->wakeup_time.tv_nsec = -1;
+
+ /* Restart the time slice: */
+ _thread_run->slice_usec = -1;
+
+ /* Insert into the waiting queue: */
+ PTHREAD_WAITQ_INSERT(_thread_run);
+ break;
+
+ /* States which can timeout: */
+ case PS_COND_WAIT:
+ case PS_SLEEP_WAIT:
+ /* Restart the time slice: */
+ _thread_run->slice_usec = -1;
+
+ /* Insert into the waiting queue: */
+ PTHREAD_WAITQ_INSERT(_thread_run);
+ break;
+
+ /* States that require periodic work: */
+ case PS_SPINBLOCK:
+ /* No timeouts for this state: */
+ _thread_run->wakeup_time.tv_sec = -1;
+ _thread_run->wakeup_time.tv_nsec = -1;
+
+ /* Increment spinblock count: */
+ _spinblock_count++;
+
+ /* fall through */
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Restart the time slice: */
+ _thread_run->slice_usec = -1;
+
+ /* Insert into the waiting queue: */
+ PTHREAD_WAITQ_INSERT(_thread_run);
+
+ /* Insert into the work queue: */
+ PTHREAD_WORKQ_INSERT(_thread_run);
+ break;
+ }
+ }
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ /*
+ * Poll file descriptors to update the state of threads
+ * waiting on file I/O where data may be available:
+ */
+ _thread_kern_poll(0);
+
+ /* Protect the scheduling queues: */
+ _queue_signals = 1;
+
+ /*
+ * Wake up threads that have timedout. This has to be
+ * done after polling in case a thread does a poll or
+ * select with zero time.
+ */
+ PTHREAD_WAITQ_SETACTIVE();
+ while (((pthread = TAILQ_FIRST(&_waitingq)) != NULL) &&
+ (pthread->wakeup_time.tv_sec != -1) &&
+ (((pthread->wakeup_time.tv_sec == 0) &&
+ (pthread->wakeup_time.tv_nsec == 0)) ||
+ (pthread->wakeup_time.tv_sec < ts.tv_sec) ||
+ ((pthread->wakeup_time.tv_sec == ts.tv_sec) &&
+ (pthread->wakeup_time.tv_nsec <= ts.tv_nsec)))) {
+ switch (pthread->state) {
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Return zero file descriptors ready: */
+ pthread->data.poll_data->nfds = 0;
+ /* fall through */
+ default:
+ /*
+ * Remove this thread from the waiting queue
+ * (and work queue if necessary) and place it
+ * in the ready queue.
+ */
+ PTHREAD_WAITQ_CLEARACTIVE();
+ if (pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread, PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ break;
+ }
+ /*
+ * Flag the timeout in the thread structure:
+ */
+ pthread->timeout = 1;
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+
+ /*
+ * Check if there is a current runnable thread that isn't
+ * already in the ready queue:
+ */
+ if ((_thread_run != &_thread_kern_thread) &&
+ (_thread_run->state == PS_RUNNING) &&
+ ((_thread_run->flags & PTHREAD_FLAGS_IN_PRIOQ) == 0)) {
+ if (_thread_run->slice_usec == -1) {
+ /*
+ * The thread exceeded its time
+ * quantum or it yielded the CPU;
+ * place it at the tail of the
+ * queue for its priority.
+ */
+ PTHREAD_PRIOQ_INSERT_TAIL(_thread_run);
+ } else {
+ /*
+ * The thread hasn't exceeded its
+ * interval. Place it at the head
+ * of the queue for its priority.
+ */
+ PTHREAD_PRIOQ_INSERT_HEAD(_thread_run);
+ }
+ }
+
+ /*
+ * Get the highest priority thread in the ready queue.
+ */
+ pthread_h = PTHREAD_PRIOQ_FIRST();
+
+ /* Check if there are no threads ready to run: */
+ if (pthread_h == NULL) {
+ /*
+ * Lock the pthread kernel by changing the pointer to
+ * the running thread to point to the global kernel
+ * thread structure:
+ */
+ _thread_run = &_thread_kern_thread;
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ /*
+ * There are no threads ready to run, so wait until
+ * something happens that changes this condition:
+ */
+ _thread_kern_poll(1);
+ }
+ else {
+ /* Remove the thread from the ready queue: */
+ PTHREAD_PRIOQ_REMOVE(pthread_h);
+
+ /* Get first thread on the waiting list: */
+ pthread = TAILQ_FIRST(&_waitingq);
+
+ /* Check to see if there is more than one thread: */
+ if (pthread_h != TAILQ_FIRST(&_thread_list) ||
+ TAILQ_NEXT(pthread_h, tle) != NULL)
+ set_timer = 1;
+ else
+ set_timer = 0;
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ /*
+ * Check for signals queued while the scheduling
+ * queues were protected:
+ */
+ while (_sigq_check_reqd != 0) {
+ /* Clear before handling queued signals: */
+ _sigq_check_reqd = 0;
+
+ /* Protect the scheduling queues again: */
+ _queue_signals = 1;
+
+ dequeue_signals();
+
+ /*
+ * Check for a higher priority thread that
+ * became runnable due to signal handling.
+ */
+ if (((pthread = PTHREAD_PRIOQ_FIRST()) != NULL) &&
+ (pthread->active_priority > pthread_h->active_priority)) {
+ /*
+ * Insert the lower priority thread
+ * at the head of its priority list:
+ */
+ PTHREAD_PRIOQ_INSERT_HEAD(pthread_h);
+
+ /* Remove the thread from the ready queue: */
+ PTHREAD_PRIOQ_REMOVE(pthread);
+
+ /* There's a new thread in town: */
+ pthread_h = pthread;
+ }
+
+ /* Get first thread on the waiting list: */
+ pthread = TAILQ_FIRST(&_waitingq);
+
+ /*
+ * Check to see if there is more than one
+ * thread:
+ */
+ if (pthread_h != TAILQ_FIRST(&_thread_list) ||
+ TAILQ_NEXT(pthread_h, tle) != NULL)
+ set_timer = 1;
+ else
+ set_timer = 0;
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+ }
+
+ /* Make the selected thread the current thread: */
+ _thread_run = pthread_h;
+
+ /*
+ * Save the current time as the time that the thread
+ * became active:
+ */
+ _thread_run->last_active.tv_sec = tv.tv_sec;
+ _thread_run->last_active.tv_usec = tv.tv_usec;
+
+ /*
+ * Define the maximum time before a scheduling signal
+ * is required:
+ */
+ itimer.it_value.tv_sec = 0;
+ itimer.it_value.tv_usec = TIMESLICE_USEC;
+
+ /*
+ * The interval timer is not reloaded when it
+ * times out. The interval time needs to be
+ * calculated every time.
+ */
+ itimer.it_interval.tv_sec = 0;
+ itimer.it_interval.tv_usec = 0;
+
+ /* Get first thread on the waiting list: */
+ if ((pthread != NULL) &&
+ (pthread->wakeup_time.tv_sec != -1)) {
+ /*
+ * Calculate the time until this thread
+ * is ready, allowing for the clock
+ * resolution:
+ */
+ ts1.tv_sec = pthread->wakeup_time.tv_sec
+ - ts.tv_sec;
+ ts1.tv_nsec = pthread->wakeup_time.tv_nsec
+ - ts.tv_nsec + _clock_res_nsec;
+
+ /*
+ * Check for underflow of the nanosecond field:
+ */
+ while (ts1.tv_nsec < 0) {
+ /*
+ * Allow for the underflow of the
+ * nanosecond field:
+ */
+ ts1.tv_sec--;
+ ts1.tv_nsec += 1000000000;
+ }
+ /*
+ * Check for overflow of the nanosecond field:
+ */
+ while (ts1.tv_nsec >= 1000000000) {
+ /*
+ * Allow for the overflow of the
+ * nanosecond field:
+ */
+ ts1.tv_sec++;
+ ts1.tv_nsec -= 1000000000;
+ }
+ /*
+ * Convert the timespec structure to a
+ * timeval structure:
+ */
+ TIMESPEC_TO_TIMEVAL(&tv1, &ts1);
+
+ /*
+ * Check if the thread will be ready
+ * sooner than the earliest ones found
+ * so far:
+ */
+ if (timercmp(&tv1, &itimer.it_value, <)) {
+ /*
+ * Update the time value:
+ */
+ itimer.it_value.tv_sec = tv1.tv_sec;
+ itimer.it_value.tv_usec = tv1.tv_usec;
+ }
+ }
+
+ /*
+ * Check if this thread is running for the first time
+ * or running again after using its full time slice
+ * allocation:
+ */
+ if (_thread_run->slice_usec == -1) {
+ /* Reset the accumulated time slice period: */
+ _thread_run->slice_usec = 0;
+ }
+
+ /* Check if there is more than one thread: */
+ if (set_timer != 0) {
+ /*
+ * Start the interval timer for the
+ * calculated time interval:
+ */
+ if (setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL) != 0) {
+ /*
+ * Cannot initialise the timer, so
+ * abort this process:
+ */
+ PANIC("Cannot set scheduling timer");
+ }
+ }
+
+ /* Check if a signal context was saved: */
+ if (_thread_run->sig_saved == 1) {
+#ifndef __alpha__
+ /*
+ * Point to the floating point data in the
+ * running thread:
+ */
+ fdata = _thread_run->saved_fp;
+
+ /* Restore the floating point state: */
+ __asm__("frstor %0": :"m"(*fdata));
+#endif
+ /*
+ * Do a sigreturn to restart the thread that
+ * was interrupted by a signal:
+ */
+ _thread_kern_in_sched = 0;
+
+ /*
+ * If we had a context switch, run any
+ * installed switch hooks.
+ */
+ if ((_sched_switch_hook != NULL) &&
+ (_last_user_thread != _thread_run)) {
+ thread_run_switch_hook(_last_user_thread,
+ _thread_run);
+ }
+ _thread_sys_sigreturn(&_thread_run->saved_sigcontext);
+ } else {
+ /*
+ * Do a longjmp to restart the thread that
+ * was context switched out (by a longjmp to
+ * a different thread):
+ */
+ longjmp(_thread_run->saved_jmp_buf, 1);
+ }
+
+ /* This point should not be reached. */
+ PANIC("Thread has returned from sigreturn or longjmp");
+ }
+ }
+
+ /* There are no more threads, so exit this process: */
+ exit(0);
+}
+
+void
+_thread_kern_sched_state(enum pthread_state state, char *fname, int lineno)
+{
+ /*
+ * Flag the pthread kernel as executing scheduler code
+ * to avoid a scheduler signal from interrupting this
+ * execution and calling the scheduler again.
+ */
+ _thread_kern_in_sched = 1;
+
+ /*
+ * Prevent the signal handler from fiddling with this thread
+ * before its state is set and is placed into the proper queue.
+ */
+ _queue_signals = 1;
+
+ /* Change the state of the current thread: */
+ _thread_run->state = state;
+ _thread_run->fname = fname;
+ _thread_run->lineno = lineno;
+
+ /* Schedule the next thread that is ready: */
+ _thread_kern_sched(NULL);
+ return;
+}
+
+void
+_thread_kern_sched_state_unlock(enum pthread_state state,
+ spinlock_t *lock, char *fname, int lineno)
+{
+ /*
+ * Flag the pthread kernel as executing scheduler code
+ * to avoid a scheduler signal from interrupting this
+ * execution and calling the scheduler again.
+ */
+ _thread_kern_in_sched = 1;
+
+ /*
+ * Prevent the signal handler from fiddling with this thread
+ * before its state is set and it is placed into the proper
+ * queue(s).
+ */
+ _queue_signals = 1;
+
+ /* Change the state of the current thread: */
+ _thread_run->state = state;
+ _thread_run->fname = fname;
+ _thread_run->lineno = lineno;
+
+ _SPINUNLOCK(lock);
+
+ /* Schedule the next thread that is ready: */
+ _thread_kern_sched(NULL);
+ return;
+}
+
+static void
+_thread_kern_poll(int wait_reqd)
+{
+ int count = 0;
+ int i, found;
+ int kern_pipe_added = 0;
+ int nfds = 0;
+ int timeout_ms = 0;
+ struct pthread *pthread;
+ struct timespec ts;
+ struct timeval tv;
+
+ /* Check if the caller wants to wait: */
+ if (wait_reqd == 0) {
+ timeout_ms = 0;
+ }
+ else {
+ /* Get the current time of day: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
+
+ _queue_signals = 1;
+ pthread = TAILQ_FIRST(&_waitingq);
+ _queue_signals = 0;
+
+ if ((pthread == NULL) || (pthread->wakeup_time.tv_sec == -1)) {
+ /*
+ * Either there are no threads in the waiting queue,
+ * or there are no threads that can timeout.
+ */
+ timeout_ms = INFTIM;
+ }
+ else {
+ /*
+ * Calculate the time left for the next thread to
+ * timeout allowing for the clock resolution:
+ */
+ timeout_ms = ((pthread->wakeup_time.tv_sec - ts.tv_sec) *
+ 1000) + ((pthread->wakeup_time.tv_nsec - ts.tv_nsec +
+ _clock_res_nsec) / 1000000);
+ /*
+ * Don't allow negative timeouts:
+ */
+ if (timeout_ms < 0)
+ timeout_ms = 0;
+ }
+ }
+
+ /* Protect the scheduling queues: */
+ _queue_signals = 1;
+
+ /*
+ * Check to see if the signal queue needs to be walked to look
+ * for threads awoken by a signal while in the scheduler.
+ */
+ if (_sigq_check_reqd != 0) {
+ /* Reset flag before handling queued signals: */
+ _sigq_check_reqd = 0;
+
+ dequeue_signals();
+ }
+
+ /*
+ * Check for a thread that became runnable due to a signal:
+ */
+ if (PTHREAD_PRIOQ_FIRST() != NULL) {
+ /*
+ * Since there is at least one runnable thread,
+ * disable the wait.
+ */
+ timeout_ms = 0;
+ }
+
+ /*
+ * Form the poll table:
+ */
+ nfds = 0;
+ if (timeout_ms != 0) {
+ /* Add the kernel pipe to the poll table: */
+ _thread_pfd_table[nfds].fd = _thread_kern_pipe[0];
+ _thread_pfd_table[nfds].events = POLLRDNORM;
+ _thread_pfd_table[nfds].revents = 0;
+ nfds++;
+ kern_pipe_added = 1;
+ }
+
+ PTHREAD_WAITQ_SETACTIVE();
+ TAILQ_FOREACH(pthread, &_workq, qe) {
+ switch (pthread->state) {
+ case PS_SPINBLOCK:
+ /*
+ * If the lock is available, let the thread run.
+ */
+ if (pthread->data.spinlock->access_lock == 0) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ /* One less thread in a spinblock state: */
+ _spinblock_count--;
+ /*
+ * Since there is at least one runnable
+ * thread, disable the wait.
+ */
+ timeout_ms = 0;
+ }
+ break;
+
+ /* File descriptor read wait: */
+ case PS_FDR_WAIT:
+ /* Limit number of polled files to table size: */
+ if (nfds < _thread_dtablesize) {
+ _thread_pfd_table[nfds].events = POLLRDNORM;
+ _thread_pfd_table[nfds].fd = pthread->data.fd.fd;
+ nfds++;
+ }
+ break;
+
+ /* File descriptor write wait: */
+ case PS_FDW_WAIT:
+ /* Limit number of polled files to table size: */
+ if (nfds < _thread_dtablesize) {
+ _thread_pfd_table[nfds].events = POLLWRNORM;
+ _thread_pfd_table[nfds].fd = pthread->data.fd.fd;
+ nfds++;
+ }
+ break;
+
+ /* File descriptor poll or select wait: */
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Limit number of polled files to table size: */
+ if (pthread->data.poll_data->nfds + nfds <
+ _thread_dtablesize) {
+ for (i = 0; i < pthread->data.poll_data->nfds; i++) {
+ _thread_pfd_table[nfds + i].fd =
+ pthread->data.poll_data->fds[i].fd;
+ _thread_pfd_table[nfds + i].events =
+ pthread->data.poll_data->fds[i].events;
+ }
+ nfds += pthread->data.poll_data->nfds;
+ }
+ break;
+
+ /* Other states do not depend on file I/O. */
+ default:
+ break;
+ }
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+
+ /*
+ * Wait for a file descriptor to be ready for read, write, or
+ * an exception, or a timeout to occur:
+ */
+ count = _thread_sys_poll(_thread_pfd_table, nfds, timeout_ms);
+
+ if (kern_pipe_added != 0)
+ /*
+ * Remove the pthread kernel pipe file descriptor
+ * from the pollfd table:
+ */
+ nfds = 1;
+ else
+ nfds = 0;
+
+ /*
+ * Check if it is possible that there are bytes in the kernel
+ * read pipe waiting to be read:
+ */
+ if (count < 0 || ((kern_pipe_added != 0) &&
+ (_thread_pfd_table[0].revents & POLLRDNORM))) {
+ /*
+ * If the kernel read pipe was included in the
+ * count:
+ */
+ if (count > 0) {
+ /* Decrement the count of file descriptors: */
+ count--;
+ }
+
+ if (_sigq_check_reqd != 0) {
+ /* Reset flag before handling signals: */
+ _sigq_check_reqd = 0;
+
+ dequeue_signals();
+ }
+ }
+
+ /*
+ * Check if any file descriptors are ready:
+ */
+ if (count > 0) {
+ /*
+ * Enter a loop to look for threads waiting on file
+ * descriptors that are flagged as available by the
+ * _poll syscall:
+ */
+ PTHREAD_WAITQ_SETACTIVE();
+ TAILQ_FOREACH(pthread, &_workq, qe) {
+ switch (pthread->state) {
+ case PS_SPINBLOCK:
+ /*
+ * If the lock is available, let the thread run.
+ */
+ if (pthread->data.spinlock->access_lock == 0) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+
+ /*
+ * One less thread in a spinblock state:
+ */
+ _spinblock_count--;
+ }
+ break;
+
+ /* File descriptor read wait: */
+ case PS_FDR_WAIT:
+ if ((nfds < _thread_dtablesize) &&
+ (_thread_pfd_table[nfds].revents & POLLRDNORM)) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ }
+ nfds++;
+ break;
+
+ /* File descriptor write wait: */
+ case PS_FDW_WAIT:
+ if ((nfds < _thread_dtablesize) &&
+ (_thread_pfd_table[nfds].revents & POLLWRNORM)) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ }
+ nfds++;
+ break;
+
+ /* File descriptor poll or select wait: */
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ if (pthread->data.poll_data->nfds + nfds <
+ _thread_dtablesize) {
+ /*
+ * Enter a loop looking for I/O
+ * readiness:
+ */
+ found = 0;
+ for (i = 0; i < pthread->data.poll_data->nfds; i++) {
+ if (_thread_pfd_table[nfds + i].revents != 0) {
+ pthread->data.poll_data->fds[i].revents =
+ _thread_pfd_table[nfds + i].revents;
+ found++;
+ }
+ }
+
+ /* Increment before destroying: */
+ nfds += pthread->data.poll_data->nfds;
+
+ if (found != 0) {
+ pthread->data.poll_data->nfds = found;
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ }
+ }
+ else
+ nfds += pthread->data.poll_data->nfds;
+ break;
+
+ /* Other states do not depend on file I/O. */
+ default:
+ break;
+ }
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+ }
+ else if (_spinblock_count != 0) {
+ /*
+ * Enter a loop to look for threads waiting on a spinlock
+ * that is now available.
+ */
+ PTHREAD_WAITQ_SETACTIVE();
+ TAILQ_FOREACH(pthread, &_workq, qe) {
+ if (pthread->state == PS_SPINBLOCK) {
+ /*
+ * If the lock is available, let the thread run.
+ */
+ if (pthread->data.spinlock->access_lock == 0) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+
+ /*
+ * One less thread in a spinblock state:
+ */
+ _spinblock_count--;
+ }
+ }
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+ }
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ while (_sigq_check_reqd != 0) {
+ /* Handle queued signals: */
+ _sigq_check_reqd = 0;
+
+ /* Protect the scheduling queues: */
+ _queue_signals = 1;
+
+ dequeue_signals();
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+ }
+
+ /* Nothing to return. */
+ return;
+}
+
+void
+_thread_kern_set_timeout(struct timespec * timeout)
+{
+ struct timespec current_time;
+ struct timeval tv;
+
+ /* Reset the timeout flag for the running thread: */
+ _thread_run->timeout = 0;
+
+ /* Check if the thread is to wait forever: */
+ if (timeout == NULL) {
+ /*
+ * Set the wakeup time to something that can be recognised as
+ * different to an actual time of day:
+ */
+ _thread_run->wakeup_time.tv_sec = -1;
+ _thread_run->wakeup_time.tv_nsec = -1;
+ }
+ /* Check if no waiting is required: */
+ else if (timeout->tv_sec == 0 && timeout->tv_nsec == 0) {
+ /* Set the wake up time to 'immediately': */
+ _thread_run->wakeup_time.tv_sec = 0;
+ _thread_run->wakeup_time.tv_nsec = 0;
+ } else {
+ /* Get the current time: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &current_time);
+
+ /* Calculate the time for the current thread to wake up: */
+ _thread_run->wakeup_time.tv_sec = current_time.tv_sec + timeout->tv_sec;
+ _thread_run->wakeup_time.tv_nsec = current_time.tv_nsec + timeout->tv_nsec;
+
+ /* Check if the nanosecond field needs to wrap: */
+ if (_thread_run->wakeup_time.tv_nsec >= 1000000000) {
+ /* Wrap the nanosecond field: */
+ _thread_run->wakeup_time.tv_sec += 1;
+ _thread_run->wakeup_time.tv_nsec -= 1000000000;
+ }
+ }
+ return;
+}
+
+void
+_thread_kern_sig_defer(void)
+{
+ /* Allow signal deferral to be recursive. */
+ _thread_run->sig_defer_count++;
+}
+
+void
+_thread_kern_sig_undefer(void)
+{
+ pthread_t pthread;
+ int need_resched = 0;
+
+ /*
+ * Perform checks to yield only if we are about to undefer
+ * signals.
+ */
+ if (_thread_run->sig_defer_count > 1) {
+ /* Decrement the signal deferral count. */
+ _thread_run->sig_defer_count--;
+ }
+ else if (_thread_run->sig_defer_count == 1) {
+ /* Reenable signals: */
+ _thread_run->sig_defer_count = 0;
+
+ /*
+ * Check if there are queued signals:
+ */
+ while (_sigq_check_reqd != 0) {
+ /* Defer scheduling while we process queued signals: */
+ _thread_run->sig_defer_count = 1;
+
+ /* Clear the flag before checking the signal queue: */
+ _sigq_check_reqd = 0;
+
+ /* Dequeue and handle signals: */
+ dequeue_signals();
+
+ /*
+ * Avoiding an unnecessary check to reschedule, check
+ * to see if signal handling caused a higher priority
+ * thread to become ready.
+ */
+ if ((need_resched == 0) &&
+ (((pthread = PTHREAD_PRIOQ_FIRST()) != NULL) &&
+ (pthread->active_priority > _thread_run->active_priority))) {
+ need_resched = 1;
+ }
+
+ /* Reenable signals: */
+ _thread_run->sig_defer_count = 0;
+ }
+
+ /* Yield the CPU if necessary: */
+ if (need_resched || _thread_run->yield_on_sig_undefer != 0) {
+ _thread_run->yield_on_sig_undefer = 0;
+ _thread_kern_sched(NULL);
+ }
+ }
+}
+
+static void
+dequeue_signals(void)
+{
+ char bufr[128];
+ int i, num;
+ pthread_t pthread;
+
+ /*
+ * Enter a loop to read and handle queued signals from the
+ * pthread kernel pipe:
+ */
+ while (((num = _thread_sys_read(_thread_kern_pipe[0], bufr,
+ sizeof(bufr))) > 0) || (num == -1 && errno == EINTR)) {
+ /*
+ * The buffer read contains one byte per signal and
+ * each byte is the signal number.
+ */
+ for (i = 0; i < num; i++) {
+ if ((int) bufr[i] == _SCHED_SIGNAL) {
+ /*
+ * Scheduling signals shouldn't ever be
+ * queued; just ignore it for now.
+ */
+ }
+ else {
+ /* Handle this signal: */
+ pthread = _thread_sig_handle((int) bufr[i],
+ NULL);
+ if (pthread != NULL)
+ _thread_sig_deliver(pthread,
+ (int) bufr[i]);
+ }
+ }
+ }
+ if ((num < 0) && (errno != EAGAIN)) {
+ /*
+ * The only error we should expect is if there is
+ * no data to read.
+ */
+ PANIC("Unable to read from thread kernel pipe");
+ }
+}
+
+static inline void
+thread_run_switch_hook(pthread_t thread_out, pthread_t thread_in)
+{
+ pthread_t tid_out = thread_out;
+ pthread_t tid_in = thread_in;
+
+ if ((tid_out != NULL) &&
+ (tid_out->flags & PTHREAD_FLAGS_PRIVATE) != 0)
+ tid_out = NULL;
+ if ((tid_in != NULL) &&
+ (tid_in->flags & PTHREAD_FLAGS_PRIVATE) != 0)
+ tid_in = NULL;
+
+ if ((_sched_switch_hook != NULL) && (tid_out != tid_in)) {
+ /* Run the scheduler switch hook: */
+ _sched_switch_hook(tid_out, tid_in);
+ }
+}
+#endif
diff --git a/lib/libkse/thread/thr_kill.c b/lib/libkse/thread/thr_kill.c
new file mode 100644
index 0000000..4bf1761
--- /dev/null
+++ b/lib/libkse/thread/thr_kill.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <signal.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_kill(pthread_t pthread, int sig)
+{
+ int ret;
+
+ /* Check for invalid signal numbers: */
+ if (sig < 0 || sig >= NSIG)
+ /* Invalid signal: */
+ ret = EINVAL;
+ /*
+ * Ensure the thread is in the list of active threads, and the
+ * signal is valid (signal 0 specifies error checking only) and
+ * not being ignored:
+ */
+ else if (((ret = _find_thread(pthread)) == 0) && (sig > 0) &&
+ (_thread_sigact[sig - 1].sa_handler != SIG_IGN)) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ _thread_sig_send(pthread, sig);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_mattr_init.c b/lib/libkse/thread/thr_mattr_init.c
new file mode 100644
index 0000000..63d4401
--- /dev/null
+++ b/lib/libkse/thread/thr_mattr_init.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996 Jeffrey Hsu <hsu@freebsd.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_mutexattr_init(pthread_mutexattr_t *attr)
+{
+ int ret;
+ pthread_mutexattr_t pattr;
+
+ if ((pattr = (pthread_mutexattr_t)
+ malloc(sizeof(struct pthread_mutex_attr))) == NULL) {
+ ret = ENOMEM;
+ } else {
+ memcpy(pattr, &pthread_mutexattr_default,
+ sizeof(struct pthread_mutex_attr));
+ *attr = pattr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_mattr_kind_np.c b/lib/libkse/thread/thr_mattr_kind_np.c
new file mode 100644
index 0000000..8b3b8cb
--- /dev/null
+++ b/lib/libkse/thread/thr_mattr_kind_np.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1996 Jeffrey Hsu <hsu@freebsd.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->m_type = kind;
+ ret = 0;
+ }
+ return(ret);
+}
+
+int
+pthread_mutexattr_getkind_np(pthread_mutexattr_t attr)
+{
+ int ret;
+ if (attr == NULL) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ ret = attr->m_type;
+ }
+ return(ret);
+}
+
+int
+pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL || type >= MUTEX_TYPE_MAX) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->m_type = type;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_msync.c b/lib/libkse/thread/thr_msync.c
new file mode 100644
index 0000000..209286d
--- /dev/null
+++ b/lib/libkse/thread/thr_msync.c
@@ -0,0 +1,40 @@
+/*
+ * David Leonard <d@openbsd.org>, 1999. Public Domain.
+ *
+ * $OpenBSD: uthread_msync.c,v 1.2 1999/06/09 07:16:17 d Exp $
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+msync(addr, len, flags)
+ void *addr;
+ size_t len;
+ int flags;
+{
+ int ret;
+
+ /*
+ * XXX This is quite pointless unless we know how to get the
+ * file descriptor associated with the memory, and lock it for
+ * write. The only real use of this wrapper is to guarantee
+ * a cancellation point, as per the standard. sigh.
+ */
+
+ /* This is a cancellation point: */
+ _thread_enter_cancellation_point();
+
+ ret = _thread_sys_msync(addr, len, flags);
+
+ /* No longer in a cancellation point: */
+ _thread_leave_cancellation_point();
+
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_multi_np.c b/lib/libkse/thread/thr_multi_np.c
new file mode 100644
index 0000000..39dd948
--- /dev/null
+++ b/lib/libkse/thread/thr_multi_np.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_multi_np()
+{
+ /* Return to multi-threaded scheduling mode: */
+ _thread_single = NULL;
+ return(0);
+}
+#endif
diff --git a/lib/libkse/thread/thr_mutex.c b/lib/libkse/thread/thr_mutex.c
new file mode 100644
index 0000000..c625ef2
--- /dev/null
+++ b/lib/libkse/thread/thr_mutex.c
@@ -0,0 +1,1406 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+#if defined(_PTHREADS_INVARIANTS)
+#define _MUTEX_INIT_LINK(m) do { \
+ (m)->m_qe.tqe_prev = NULL; \
+ (m)->m_qe.tqe_next = NULL; \
+} while (0)
+#define _MUTEX_ASSERT_IS_OWNED(m) do { \
+ if ((m)->m_qe.tqe_prev == NULL) \
+ PANIC("mutex is not on list"); \
+} while (0)
+#define _MUTEX_ASSERT_NOT_OWNED(m) do { \
+ if (((m)->m_qe.tqe_prev != NULL) || \
+ ((m)->m_qe.tqe_next != NULL)) \
+ PANIC("mutex is on list"); \
+} while (0)
+#else
+#define _MUTEX_INIT_LINK(m)
+#define _MUTEX_ASSERT_IS_OWNED(m)
+#define _MUTEX_ASSERT_NOT_OWNED(m)
+#endif
+
+/*
+ * Prototypes
+ */
+static inline int mutex_self_trylock(pthread_mutex_t);
+static inline int mutex_self_lock(pthread_mutex_t);
+static inline int mutex_unlock_common(pthread_mutex_t *, int);
+static void mutex_priority_adjust(pthread_mutex_t);
+static void mutex_rescan_owned (pthread_t, pthread_mutex_t);
+static inline pthread_t mutex_queue_deq(pthread_mutex_t);
+static inline void mutex_queue_remove(pthread_mutex_t, pthread_t);
+static inline void mutex_queue_enq(pthread_mutex_t, pthread_t);
+
+
+static spinlock_t static_init_lock = _SPINLOCK_INITIALIZER;
+
+/* Reinitialize a mutex to defaults. */
+int
+_mutex_reinit(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+ else if (*mutex == NULL)
+ ret = pthread_mutex_init(mutex, NULL);
+ else {
+ /*
+ * Initialize the mutex structure:
+ */
+ (*mutex)->m_type = PTHREAD_MUTEX_DEFAULT;
+ (*mutex)->m_protocol = PTHREAD_PRIO_NONE;
+ TAILQ_INIT(&(*mutex)->m_queue);
+ (*mutex)->m_owner = NULL;
+ (*mutex)->m_data.m_count = 0;
+ (*mutex)->m_flags &= MUTEX_FLAGS_PRIVATE;
+ (*mutex)->m_flags |= MUTEX_FLAGS_INITED;
+ (*mutex)->m_refcount = 0;
+ (*mutex)->m_prio = 0;
+ (*mutex)->m_saved_prio = 0;
+ _MUTEX_INIT_LINK(*mutex);
+ memset(&(*mutex)->lock, 0, sizeof((*mutex)->lock));
+ }
+ return (ret);
+}
+
+int
+pthread_mutex_init(pthread_mutex_t * mutex,
+ const pthread_mutexattr_t * mutex_attr)
+{
+ enum pthread_mutextype type;
+ int protocol;
+ int ceiling;
+ pthread_mutex_t pmutex;
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+
+ /* Check if default mutex attributes: */
+ else if (mutex_attr == NULL || *mutex_attr == NULL) {
+ /* Default to a (error checking) POSIX mutex: */
+ type = PTHREAD_MUTEX_ERRORCHECK;
+ protocol = PTHREAD_PRIO_NONE;
+ ceiling = PTHREAD_MAX_PRIORITY;
+ }
+
+ /* Check mutex type: */
+ else if (((*mutex_attr)->m_type < PTHREAD_MUTEX_ERRORCHECK) ||
+ ((*mutex_attr)->m_type >= MUTEX_TYPE_MAX))
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+
+ /* Check mutex protocol: */
+ else if (((*mutex_attr)->m_protocol < PTHREAD_PRIO_NONE) ||
+ ((*mutex_attr)->m_protocol > PTHREAD_MUTEX_RECURSIVE))
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+
+ else {
+ /* Use the requested mutex type and protocol: */
+ type = (*mutex_attr)->m_type;
+ protocol = (*mutex_attr)->m_protocol;
+ ceiling = (*mutex_attr)->m_ceiling;
+ }
+
+ /* Check no errors so far: */
+ if (ret == 0) {
+ if ((pmutex = (pthread_mutex_t)
+ malloc(sizeof(struct pthread_mutex))) == NULL)
+ ret = ENOMEM;
+ else {
+ /* Reset the mutex flags: */
+ pmutex->m_flags = 0;
+
+ /* Process according to mutex type: */
+ switch (type) {
+ /* case PTHREAD_MUTEX_DEFAULT: */
+ case PTHREAD_MUTEX_ERRORCHECK:
+ case PTHREAD_MUTEX_NORMAL:
+ /* Nothing to do here. */
+ break;
+
+ /* Single UNIX Spec 2 recursive mutex: */
+ case PTHREAD_MUTEX_RECURSIVE:
+ /* Reset the mutex count: */
+ pmutex->m_data.m_count = 0;
+ break;
+
+ /* Trap invalid mutex types: */
+ default:
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ break;
+ }
+ if (ret == 0) {
+ /* Initialise the rest of the mutex: */
+ TAILQ_INIT(&pmutex->m_queue);
+ pmutex->m_flags |= MUTEX_FLAGS_INITED;
+ pmutex->m_owner = NULL;
+ pmutex->m_type = type;
+ pmutex->m_protocol = protocol;
+ pmutex->m_refcount = 0;
+ if (protocol == PTHREAD_PRIO_PROTECT)
+ pmutex->m_prio = ceiling;
+ else
+ pmutex->m_prio = 0;
+ pmutex->m_saved_prio = 0;
+ _MUTEX_INIT_LINK(pmutex);
+ memset(&pmutex->lock, 0, sizeof(pmutex->lock));
+ *mutex = pmutex;
+ } else {
+ free(pmutex);
+ *mutex = NULL;
+ }
+ }
+ }
+ /* Return the completion status: */
+ return(ret);
+}
+
+int
+pthread_mutex_destroy(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL || *mutex == NULL)
+ ret = EINVAL;
+ else {
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
+ * Check to see if this mutex is in use:
+ */
+ if (((*mutex)->m_owner != NULL) ||
+ (TAILQ_FIRST(&(*mutex)->m_queue) != NULL) ||
+ ((*mutex)->m_refcount != 0)) {
+ ret = EBUSY;
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&(*mutex)->lock);
+ }
+ else {
+ /*
+ * Free the memory allocated for the mutex
+ * structure:
+ */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ free(*mutex);
+
+ /*
+ * Leave the caller's pointer NULL now that
+ * the mutex has been destroyed:
+ */
+ *mutex = NULL;
+ }
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+static int
+init_static (pthread_mutex_t *mutex)
+{
+ int ret;
+
+ _SPINLOCK(&static_init_lock);
+
+ if (*mutex == NULL)
+ ret = pthread_mutex_init(mutex, NULL);
+ else
+ ret = 0;
+
+ _SPINUNLOCK(&static_init_lock);
+
+ return(ret);
+}
+
+int
+pthread_mutex_trylock(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+
+ /*
+ * If the mutex is statically initialized, perform the dynamic
+ * initialization:
+ */
+ else if (*mutex != NULL || (ret = init_static(mutex)) == 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
+ * If the mutex was statically allocated, properly
+ * initialize the tail queue.
+ */
+ if (((*mutex)->m_flags & MUTEX_FLAGS_INITED) == 0) {
+ TAILQ_INIT(&(*mutex)->m_queue);
+ _MUTEX_INIT_LINK(*mutex);
+ (*mutex)->m_flags |= MUTEX_FLAGS_INITED;
+ }
+
+ /* Process according to mutex type: */
+ switch ((*mutex)->m_protocol) {
+ /* Default POSIX mutex: */
+ case PTHREAD_PRIO_NONE:
+ /* Check if this mutex is not locked: */
+ if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for the running thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_trylock(*mutex);
+ else
+ /* Return a busy error: */
+ ret = EBUSY;
+ break;
+
+ /* POSIX priority inheritence mutex: */
+ case PTHREAD_PRIO_INHERIT:
+ /* Check if this mutex is not locked: */
+ if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for the running thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Track number of priority mutexes owned: */
+ _thread_run->priority_mutex_count++;
+
+ /*
+ * The mutex takes on the attributes of the
+ * running thread when there are no waiters.
+ */
+ (*mutex)->m_prio = _thread_run->active_priority;
+ (*mutex)->m_saved_prio =
+ _thread_run->inherited_priority;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_trylock(*mutex);
+ else
+ /* Return a busy error: */
+ ret = EBUSY;
+ break;
+
+ /* POSIX priority protection mutex: */
+ case PTHREAD_PRIO_PROTECT:
+ /* Check for a priority ceiling violation: */
+ if (_thread_run->active_priority > (*mutex)->m_prio)
+ ret = EINVAL;
+
+ /* Check if this mutex is not locked: */
+ else if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for the running thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Track number of priority mutexes owned: */
+ _thread_run->priority_mutex_count++;
+
+ /*
+ * The running thread inherits the ceiling
+ * priority of the mutex and executes at that
+ * priority.
+ */
+ _thread_run->active_priority = (*mutex)->m_prio;
+ (*mutex)->m_saved_prio =
+ _thread_run->inherited_priority;
+ _thread_run->inherited_priority =
+ (*mutex)->m_prio;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_trylock(*mutex);
+ else
+ /* Return a busy error: */
+ ret = EBUSY;
+ break;
+
+ /* Trap invalid mutex types: */
+ default:
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ break;
+ }
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&(*mutex)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+int
+pthread_mutex_lock(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+
+ /*
+ * If the mutex is statically initialized, perform the dynamic
+ * initialization:
+ */
+ else if (*mutex != NULL || (ret = init_static(mutex)) == 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
+ * If the mutex was statically allocated, properly
+ * initialize the tail queue.
+ */
+ if (((*mutex)->m_flags & MUTEX_FLAGS_INITED) == 0) {
+ TAILQ_INIT(&(*mutex)->m_queue);
+ (*mutex)->m_flags |= MUTEX_FLAGS_INITED;
+ _MUTEX_INIT_LINK(*mutex);
+ }
+
+ /* Reset the interrupted flag: */
+ _thread_run->interrupted = 0;
+
+ /* Process according to mutex type: */
+ switch ((*mutex)->m_protocol) {
+ /* Default POSIX mutex: */
+ case PTHREAD_PRIO_NONE:
+ if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for this thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_lock(*mutex);
+ else {
+ /*
+ * Join the queue of threads waiting to lock
+ * the mutex:
+ */
+ mutex_queue_enq(*mutex, _thread_run);
+
+ /*
+ * Keep a pointer to the mutex this thread
+ * is waiting on:
+ */
+ _thread_run->data.mutex = *mutex;
+
+ /*
+ * Unlock the mutex structure and schedule the
+ * next thread:
+ */
+ _thread_kern_sched_state_unlock(PS_MUTEX_WAIT,
+ &(*mutex)->lock, __FILE__, __LINE__);
+
+ /* Lock the mutex structure again: */
+ _SPINLOCK(&(*mutex)->lock);
+ }
+ break;
+
+ /* POSIX priority inheritence mutex: */
+ case PTHREAD_PRIO_INHERIT:
+ /* Check if this mutex is not locked: */
+ if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for this thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Track number of priority mutexes owned: */
+ _thread_run->priority_mutex_count++;
+
+ /*
+ * The mutex takes on attributes of the
+ * running thread when there are no waiters.
+ */
+ (*mutex)->m_prio = _thread_run->active_priority;
+ (*mutex)->m_saved_prio =
+ _thread_run->inherited_priority;
+ _thread_run->inherited_priority =
+ (*mutex)->m_prio;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_lock(*mutex);
+ else {
+ /*
+ * Join the queue of threads waiting to lock
+ * the mutex:
+ */
+ mutex_queue_enq(*mutex, _thread_run);
+
+ /*
+ * Keep a pointer to the mutex this thread
+ * is waiting on:
+ */
+ _thread_run->data.mutex = *mutex;
+
+ if (_thread_run->active_priority >
+ (*mutex)->m_prio)
+ /* Adjust priorities: */
+ mutex_priority_adjust(*mutex);
+
+ /*
+ * Unlock the mutex structure and schedule the
+ * next thread:
+ */
+ _thread_kern_sched_state_unlock(PS_MUTEX_WAIT,
+ &(*mutex)->lock, __FILE__, __LINE__);
+
+ /* Lock the mutex structure again: */
+ _SPINLOCK(&(*mutex)->lock);
+ }
+ break;
+
+ /* POSIX priority protection mutex: */
+ case PTHREAD_PRIO_PROTECT:
+ /* Check for a priority ceiling violation: */
+ if (_thread_run->active_priority > (*mutex)->m_prio)
+ ret = EINVAL;
+
+ /* Check if this mutex is not locked: */
+ else if ((*mutex)->m_owner == NULL) {
+ /*
+ * Lock the mutex for the running
+ * thread:
+ */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Track number of priority mutexes owned: */
+ _thread_run->priority_mutex_count++;
+
+ /*
+ * The running thread inherits the ceiling
+ * priority of the mutex and executes at that
+ * priority:
+ */
+ _thread_run->active_priority = (*mutex)->m_prio;
+ (*mutex)->m_saved_prio =
+ _thread_run->inherited_priority;
+ _thread_run->inherited_priority =
+ (*mutex)->m_prio;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_lock(*mutex);
+ else {
+ /*
+ * Join the queue of threads waiting to lock
+ * the mutex:
+ */
+ mutex_queue_enq(*mutex, _thread_run);
+
+ /*
+ * Keep a pointer to the mutex this thread
+ * is waiting on:
+ */
+ _thread_run->data.mutex = *mutex;
+
+ /* Clear any previous error: */
+ _thread_run->error = 0;
+
+ /*
+ * Unlock the mutex structure and schedule the
+ * next thread:
+ */
+ _thread_kern_sched_state_unlock(PS_MUTEX_WAIT,
+ &(*mutex)->lock, __FILE__, __LINE__);
+
+ /* Lock the mutex structure again: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
+ * The threads priority may have changed while
+ * waiting for the mutex causing a ceiling
+ * violation.
+ */
+ ret = _thread_run->error;
+ _thread_run->error = 0;
+ }
+ break;
+
+ /* Trap invalid mutex types: */
+ default:
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ break;
+ }
+
+ /*
+ * Check to see if this thread was interrupted and
+ * is still in the mutex queue of waiting threads:
+ */
+ if (_thread_run->interrupted != 0)
+ mutex_queue_remove(*mutex, _thread_run);
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&(*mutex)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+int
+pthread_mutex_unlock(pthread_mutex_t * mutex)
+{
+ return (mutex_unlock_common(mutex, /* add reference */ 0));
+}
+
+int
+_mutex_cv_unlock(pthread_mutex_t * mutex)
+{
+ return (mutex_unlock_common(mutex, /* add reference */ 1));
+}
+
+int
+_mutex_cv_lock(pthread_mutex_t * mutex)
+{
+ int ret;
+ if ((ret = pthread_mutex_lock(mutex)) == 0)
+ (*mutex)->m_refcount--;
+ return (ret);
+}
+
+static inline int
+mutex_self_trylock(pthread_mutex_t mutex)
+{
+ int ret = 0;
+
+ switch (mutex->m_type) {
+
+ /* case PTHREAD_MUTEX_DEFAULT: */
+ case PTHREAD_MUTEX_ERRORCHECK:
+ case PTHREAD_MUTEX_NORMAL:
+ /*
+ * POSIX specifies that mutexes should return EDEADLK if a
+ * recursive lock is detected.
+ */
+ ret = EBUSY;
+ break;
+
+ case PTHREAD_MUTEX_RECURSIVE:
+ /* Increment the lock count: */
+ mutex->m_data.m_count++;
+ break;
+
+ default:
+ /* Trap invalid mutex types; */
+ ret = EINVAL;
+ }
+
+ return(ret);
+}
+
+static inline int
+mutex_self_lock(pthread_mutex_t mutex)
+{
+ int ret = 0;
+
+ switch (mutex->m_type) {
+ /* case PTHREAD_MUTEX_DEFAULT: */
+ case PTHREAD_MUTEX_ERRORCHECK:
+ /*
+ * POSIX specifies that mutexes should return EDEADLK if a
+ * recursive lock is detected.
+ */
+ ret = EDEADLK;
+ break;
+
+ case PTHREAD_MUTEX_NORMAL:
+ /*
+ * What SS2 define as a 'normal' mutex. Intentionally
+ * deadlock on attempts to get a lock you already own.
+ */
+ _thread_kern_sched_state_unlock(PS_DEADLOCK,
+ &mutex->lock, __FILE__, __LINE__);
+ break;
+
+ case PTHREAD_MUTEX_RECURSIVE:
+ /* Increment the lock count: */
+ mutex->m_data.m_count++;
+ break;
+
+ default:
+ /* Trap invalid mutex types; */
+ ret = EINVAL;
+ }
+
+ return(ret);
+}
+
+static inline int
+mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
+{
+ int ret = 0;
+
+ if (mutex == NULL || *mutex == NULL) {
+ ret = EINVAL;
+ } else {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /* Process according to mutex type: */
+ switch ((*mutex)->m_protocol) {
+ /* Default POSIX mutex: */
+ case PTHREAD_PRIO_NONE:
+ /*
+ * Check if the running thread is not the owner of the
+ * mutex:
+ */
+ if ((*mutex)->m_owner != _thread_run) {
+ /*
+ * Return an invalid argument error for no
+ * owner and a permission error otherwise:
+ */
+ ret = (*mutex)->m_owner == NULL ? EINVAL : EPERM;
+ }
+ else if (((*mutex)->m_type == PTHREAD_MUTEX_RECURSIVE) &&
+ ((*mutex)->m_data.m_count > 1)) {
+ /* Decrement the count: */
+ (*mutex)->m_data.m_count--;
+ } else {
+ /*
+ * Clear the count in case this is recursive
+ * mutex.
+ */
+ (*mutex)->m_data.m_count = 0;
+
+ /* Remove the mutex from the threads queue. */
+ _MUTEX_ASSERT_IS_OWNED(*mutex);
+ TAILQ_REMOVE(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+ _MUTEX_INIT_LINK(*mutex);
+
+ /*
+ * Get the next thread from the queue of
+ * threads waiting on the mutex:
+ */
+ if (((*mutex)->m_owner =
+ mutex_queue_deq(*mutex)) != NULL) {
+ /*
+ * Allow the new owner of the mutex to
+ * run:
+ */
+ PTHREAD_NEW_STATE((*mutex)->m_owner,
+ PS_RUNNING);
+
+ /*
+ * Add the mutex to the threads list of
+ * owned mutexes:
+ */
+ TAILQ_INSERT_TAIL(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+
+ /*
+ * The owner is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
+ }
+ }
+ break;
+
+ /* POSIX priority inheritence mutex: */
+ case PTHREAD_PRIO_INHERIT:
+ /*
+ * Check if the running thread is not the owner of the
+ * mutex:
+ */
+ if ((*mutex)->m_owner != _thread_run) {
+ /*
+ * Return an invalid argument error for no
+ * owner and a permission error otherwise:
+ */
+ ret = (*mutex)->m_owner == NULL ? EINVAL : EPERM;
+ }
+ else if (((*mutex)->m_type == PTHREAD_MUTEX_RECURSIVE) &&
+ ((*mutex)->m_data.m_count > 1)) {
+ /* Decrement the count: */
+ (*mutex)->m_data.m_count--;
+ } else {
+ /*
+ * Clear the count in case this is recursive
+ * mutex.
+ */
+ (*mutex)->m_data.m_count = 0;
+
+ /*
+ * Restore the threads inherited priority and
+ * recompute the active priority (being careful
+ * not to override changes in the threads base
+ * priority subsequent to locking the mutex).
+ */
+ _thread_run->inherited_priority =
+ (*mutex)->m_saved_prio;
+ _thread_run->active_priority =
+ MAX(_thread_run->inherited_priority,
+ _thread_run->base_priority);
+
+ /*
+ * This thread now owns one less priority mutex.
+ */
+ _thread_run->priority_mutex_count--;
+
+ /* Remove the mutex from the threads queue. */
+ _MUTEX_ASSERT_IS_OWNED(*mutex);
+ TAILQ_REMOVE(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+ _MUTEX_INIT_LINK(*mutex);
+
+ /*
+ * Get the next thread from the queue of threads
+ * waiting on the mutex:
+ */
+ if (((*mutex)->m_owner =
+ mutex_queue_deq(*mutex)) == NULL)
+ /* This mutex has no priority. */
+ (*mutex)->m_prio = 0;
+ else {
+ /*
+ * Track number of priority mutexes owned:
+ */
+ (*mutex)->m_owner->priority_mutex_count++;
+
+ /*
+ * Add the mutex to the threads list
+ * of owned mutexes:
+ */
+ TAILQ_INSERT_TAIL(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+
+ /*
+ * The owner is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
+
+ /*
+ * Set the priority of the mutex. Since
+ * our waiting threads are in descending
+ * priority order, the priority of the
+ * mutex becomes the active priority of
+ * the thread we just dequeued.
+ */
+ (*mutex)->m_prio =
+ (*mutex)->m_owner->active_priority;
+
+ /*
+ * Save the owning threads inherited
+ * priority:
+ */
+ (*mutex)->m_saved_prio =
+ (*mutex)->m_owner->inherited_priority;
+
+ /*
+ * The owning threads inherited priority
+ * now becomes his active priority (the
+ * priority of the mutex).
+ */
+ (*mutex)->m_owner->inherited_priority =
+ (*mutex)->m_prio;
+
+ /*
+ * Allow the new owner of the mutex to
+ * run:
+ */
+ PTHREAD_NEW_STATE((*mutex)->m_owner,
+ PS_RUNNING);
+ }
+ }
+ break;
+
+ /* POSIX priority ceiling mutex: */
+ case PTHREAD_PRIO_PROTECT:
+ /*
+ * Check if the running thread is not the owner of the
+ * mutex:
+ */
+ if ((*mutex)->m_owner != _thread_run) {
+ /*
+ * Return an invalid argument error for no
+ * owner and a permission error otherwise:
+ */
+ ret = (*mutex)->m_owner == NULL ? EINVAL : EPERM;
+ }
+ else if (((*mutex)->m_type == PTHREAD_MUTEX_RECURSIVE) &&
+ ((*mutex)->m_data.m_count > 1)) {
+ /* Decrement the count: */
+ (*mutex)->m_data.m_count--;
+ } else {
+ /*
+ * Clear the count in case this is recursive
+ * mutex.
+ */
+ (*mutex)->m_data.m_count = 0;
+
+ /*
+ * Restore the threads inherited priority and
+ * recompute the active priority (being careful
+ * not to override changes in the threads base
+ * priority subsequent to locking the mutex).
+ */
+ _thread_run->inherited_priority =
+ (*mutex)->m_saved_prio;
+ _thread_run->active_priority =
+ MAX(_thread_run->inherited_priority,
+ _thread_run->base_priority);
+
+ /*
+ * This thread now owns one less priority mutex.
+ */
+ _thread_run->priority_mutex_count--;
+
+ /* Remove the mutex from the threads queue. */
+ _MUTEX_ASSERT_IS_OWNED(*mutex);
+ TAILQ_REMOVE(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+ _MUTEX_INIT_LINK(*mutex);
+
+ /*
+ * Enter a loop to find a waiting thread whose
+ * active priority will not cause a ceiling
+ * violation:
+ */
+ while ((((*mutex)->m_owner =
+ mutex_queue_deq(*mutex)) != NULL) &&
+ ((*mutex)->m_owner->active_priority >
+ (*mutex)->m_prio)) {
+ /*
+ * Either the mutex ceiling priority
+ * been lowered and/or this threads
+ * priority has been raised subsequent
+ * to this thread being queued on the
+ * waiting list.
+ */
+ (*mutex)->m_owner->error = EINVAL;
+ PTHREAD_NEW_STATE((*mutex)->m_owner,
+ PS_RUNNING);
+ /*
+ * The thread is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
+ }
+
+ /* Check for a new owner: */
+ if ((*mutex)->m_owner != NULL) {
+ /*
+ * Track number of priority mutexes owned:
+ */
+ (*mutex)->m_owner->priority_mutex_count++;
+
+ /*
+ * Add the mutex to the threads list
+ * of owned mutexes:
+ */
+ TAILQ_INSERT_TAIL(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+
+ /*
+ * The owner is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
+
+ /*
+ * Save the owning threads inherited
+ * priority:
+ */
+ (*mutex)->m_saved_prio =
+ (*mutex)->m_owner->inherited_priority;
+
+ /*
+ * The owning thread inherits the
+ * ceiling priority of the mutex and
+ * executes at that priority:
+ */
+ (*mutex)->m_owner->inherited_priority =
+ (*mutex)->m_prio;
+ (*mutex)->m_owner->active_priority =
+ (*mutex)->m_prio;
+
+ /*
+ * Allow the new owner of the mutex to
+ * run:
+ */
+ PTHREAD_NEW_STATE((*mutex)->m_owner,
+ PS_RUNNING);
+ }
+ }
+ break;
+
+ /* Trap invalid mutex types: */
+ default:
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ break;
+ }
+
+ if ((ret == 0) && (add_reference != 0)) {
+ /* Increment the reference count: */
+ (*mutex)->m_refcount++;
+ }
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&(*mutex)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+
+/*
+ * This function is called when a change in base priority occurs for
+ * a thread that is holding or waiting for a priority protection or
+ * inheritence mutex. A change in a threads base priority can effect
+ * changes to active priorities of other threads and to the ordering
+ * of mutex locking by waiting threads.
+ *
+ * This must be called while thread scheduling is deferred.
+ */
+void
+_mutex_notify_priochange(pthread_t pthread)
+{
+ /* Adjust the priorites of any owned priority mutexes: */
+ if (pthread->priority_mutex_count > 0) {
+ /*
+ * Rescan the mutexes owned by this thread and correct
+ * their priorities to account for this threads change
+ * in priority. This has the side effect of changing
+ * the threads active priority.
+ */
+ mutex_rescan_owned(pthread, /* rescan all owned */ NULL);
+ }
+
+ /*
+ * If this thread is waiting on a priority inheritence mutex,
+ * check for priority adjustments. A change in priority can
+ * also effect a ceiling violation(*) for a thread waiting on
+ * a priority protection mutex; we don't perform the check here
+ * as it is done in pthread_mutex_unlock.
+ *
+ * (*) It should be noted that a priority change to a thread
+ * _after_ taking and owning a priority ceiling mutex
+ * does not affect ownership of that mutex; the ceiling
+ * priority is only checked before mutex ownership occurs.
+ */
+ if (pthread->state == PS_MUTEX_WAIT) {
+ /* Lock the mutex structure: */
+ _SPINLOCK(&pthread->data.mutex->lock);
+
+ /*
+ * Check to make sure this thread is still in the same state
+ * (the spinlock above can yield the CPU to another thread):
+ */
+ if (pthread->state == PS_MUTEX_WAIT) {
+ /*
+ * Remove and reinsert this thread into the list of
+ * waiting threads to preserve decreasing priority
+ * order.
+ */
+ mutex_queue_remove(pthread->data.mutex, pthread);
+ mutex_queue_enq(pthread->data.mutex, pthread);
+
+ if (pthread->data.mutex->m_protocol ==
+ PTHREAD_PRIO_INHERIT) {
+ /* Adjust priorities: */
+ mutex_priority_adjust(pthread->data.mutex);
+ }
+ }
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&pthread->data.mutex->lock);
+ }
+}
+
+/*
+ * Called when a new thread is added to the mutex waiting queue or
+ * when a threads priority changes that is already in the mutex
+ * waiting queue.
+ */
+static void
+mutex_priority_adjust(pthread_mutex_t mutex)
+{
+ pthread_t pthread_next, pthread = mutex->m_owner;
+ int temp_prio;
+ pthread_mutex_t m = mutex;
+
+ /*
+ * Calculate the mutex priority as the maximum of the highest
+ * active priority of any waiting threads and the owning threads
+ * active priority(*).
+ *
+ * (*) Because the owning threads current active priority may
+ * reflect priority inherited from this mutex (and the mutex
+ * priority may have changed) we must recalculate the active
+ * priority based on the threads saved inherited priority
+ * and its base priority.
+ */
+ pthread_next = TAILQ_FIRST(&m->m_queue); /* should never be NULL */
+ temp_prio = MAX(pthread_next->active_priority,
+ MAX(m->m_saved_prio, pthread->base_priority));
+
+ /* See if this mutex really needs adjusting: */
+ if (temp_prio == m->m_prio)
+ /* No need to propagate the priority: */
+ return;
+
+ /* Set new priority of the mutex: */
+ m->m_prio = temp_prio;
+
+ while (m != NULL) {
+ /*
+ * Save the threads priority before rescanning the
+ * owned mutexes:
+ */
+ temp_prio = pthread->active_priority;
+
+ /*
+ * Fix the priorities for all the mutexes this thread has
+ * locked since taking this mutex. This also has a
+ * potential side-effect of changing the threads priority.
+ */
+ mutex_rescan_owned(pthread, m);
+
+ /*
+ * If the thread is currently waiting on a mutex, check
+ * to see if the threads new priority has affected the
+ * priority of the mutex.
+ */
+ if ((temp_prio != pthread->active_priority) &&
+ (pthread->state == PS_MUTEX_WAIT) &&
+ (pthread->data.mutex->m_protocol == PTHREAD_PRIO_INHERIT)) {
+ /* Grab the mutex this thread is waiting on: */
+ m = pthread->data.mutex;
+
+ /*
+ * The priority for this thread has changed. Remove
+ * and reinsert this thread into the list of waiting
+ * threads to preserve decreasing priority order.
+ */
+ mutex_queue_remove(m, pthread);
+ mutex_queue_enq(m, pthread);
+
+ /* Grab the waiting thread with highest priority: */
+ pthread_next = TAILQ_FIRST(&m->m_queue);
+
+ /*
+ * Calculate the mutex priority as the maximum of the
+ * highest active priority of any waiting threads and
+ * the owning threads active priority.
+ */
+ temp_prio = MAX(pthread_next->active_priority,
+ MAX(m->m_saved_prio, m->m_owner->base_priority));
+
+ if (temp_prio != m->m_prio) {
+ /*
+ * The priority needs to be propagated to the
+ * mutex this thread is waiting on and up to
+ * the owner of that mutex.
+ */
+ m->m_prio = temp_prio;
+ pthread = m->m_owner;
+ }
+ else
+ /* We're done: */
+ m = NULL;
+
+ }
+ else
+ /* We're done: */
+ m = NULL;
+ }
+}
+
+static void
+mutex_rescan_owned (pthread_t pthread, pthread_mutex_t mutex)
+{
+ int active_prio, inherited_prio;
+ pthread_mutex_t m;
+ pthread_t pthread_next;
+
+ /*
+ * Start walking the mutexes the thread has taken since
+ * taking this mutex.
+ */
+ if (mutex == NULL) {
+ /*
+ * A null mutex means start at the beginning of the owned
+ * mutex list.
+ */
+ m = TAILQ_FIRST(&pthread->mutexq);
+
+ /* There is no inherited priority yet. */
+ inherited_prio = 0;
+ }
+ else {
+ /*
+ * The caller wants to start after a specific mutex. It
+ * is assumed that this mutex is a priority inheritence
+ * mutex and that its priority has been correctly
+ * calculated.
+ */
+ m = TAILQ_NEXT(mutex, m_qe);
+
+ /* Start inheriting priority from the specified mutex. */
+ inherited_prio = mutex->m_prio;
+ }
+ active_prio = MAX(inherited_prio, pthread->base_priority);
+
+ while (m != NULL) {
+ /*
+ * We only want to deal with priority inheritence
+ * mutexes. This might be optimized by only placing
+ * priority inheritence mutexes into the owned mutex
+ * list, but it may prove to be useful having all
+ * owned mutexes in this list. Consider a thread
+ * exiting while holding mutexes...
+ */
+ if (m->m_protocol == PTHREAD_PRIO_INHERIT) {
+ /*
+ * Fix the owners saved (inherited) priority to
+ * reflect the priority of the previous mutex.
+ */
+ m->m_saved_prio = inherited_prio;
+
+ if ((pthread_next = TAILQ_FIRST(&m->m_queue)) != NULL)
+ /* Recalculate the priority of the mutex: */
+ m->m_prio = MAX(active_prio,
+ pthread_next->active_priority);
+ else
+ m->m_prio = active_prio;
+
+ /* Recalculate new inherited and active priorities: */
+ inherited_prio = m->m_prio;
+ active_prio = MAX(m->m_prio, pthread->base_priority);
+ }
+
+ /* Advance to the next mutex owned by this thread: */
+ m = TAILQ_NEXT(m, m_qe);
+ }
+
+ /*
+ * Fix the threads inherited priority and recalculate its
+ * active priority.
+ */
+ pthread->inherited_priority = inherited_prio;
+ active_prio = MAX(inherited_prio, pthread->base_priority);
+
+ if (active_prio != pthread->active_priority) {
+ /*
+ * If this thread is in the priority queue, it must be
+ * removed and reinserted for its new priority.
+ */
+ if (pthread->flags & PTHREAD_FLAGS_IN_PRIOQ) {
+ /*
+ * Remove the thread from the priority queue
+ * before changing its priority:
+ */
+ PTHREAD_PRIOQ_REMOVE(pthread);
+
+ /*
+ * POSIX states that if the priority is being
+ * lowered, the thread must be inserted at the
+ * head of the queue for its priority if it owns
+ * any priority protection or inheritence mutexes.
+ */
+ if ((active_prio < pthread->active_priority) &&
+ (pthread->priority_mutex_count > 0)) {
+ /* Set the new active priority. */
+ pthread->active_priority = active_prio;
+
+ PTHREAD_PRIOQ_INSERT_HEAD(pthread);
+ }
+ else {
+ /* Set the new active priority. */
+ pthread->active_priority = active_prio;
+
+ PTHREAD_PRIOQ_INSERT_TAIL(pthread);
+ }
+ }
+ else {
+ /* Set the new active priority. */
+ pthread->active_priority = active_prio;
+ }
+ }
+}
+
+void
+_mutex_unlock_private(pthread_t pthread)
+{
+ struct pthread_mutex *m, *m_next;
+
+ for (m = TAILQ_FIRST(&pthread->mutexq); m != NULL; m = m_next) {
+ m_next = TAILQ_NEXT(m, m_qe);
+ if ((m->m_flags & MUTEX_FLAGS_PRIVATE) != 0)
+ pthread_mutex_unlock(&m);
+ }
+}
+
+/*
+ * Dequeue a waiting thread from the head of a mutex queue in descending
+ * priority order.
+ */
+static inline pthread_t
+mutex_queue_deq(pthread_mutex_t mutex)
+{
+ pthread_t pthread;
+
+ while ((pthread = TAILQ_FIRST(&mutex->m_queue)) != NULL) {
+ TAILQ_REMOVE(&mutex->m_queue, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_MUTEXQ;
+
+ /*
+ * Only exit the loop if the thread hasn't been
+ * cancelled.
+ */
+ if (pthread->interrupted == 0)
+ break;
+ }
+
+ return(pthread);
+}
+
+/*
+ * Remove a waiting thread from a mutex queue in descending priority order.
+ */
+static inline void
+mutex_queue_remove(pthread_mutex_t mutex, pthread_t pthread)
+{
+ if ((pthread->flags & PTHREAD_FLAGS_IN_MUTEXQ) != 0) {
+ TAILQ_REMOVE(&mutex->m_queue, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_MUTEXQ;
+ }
+}
+
+/*
+ * Enqueue a waiting thread to a queue in descending priority order.
+ */
+static inline void
+mutex_queue_enq(pthread_mutex_t mutex, pthread_t pthread)
+{
+ pthread_t tid = TAILQ_LAST(&mutex->m_queue, mutex_head);
+
+ /*
+ * For the common case of all threads having equal priority,
+ * we perform a quick check against the priority of the thread
+ * at the tail of the queue.
+ */
+ if ((tid == NULL) || (pthread->active_priority <= tid->active_priority))
+ TAILQ_INSERT_TAIL(&mutex->m_queue, pthread, qe);
+ else {
+ tid = TAILQ_FIRST(&mutex->m_queue);
+ while (pthread->active_priority <= tid->active_priority)
+ tid = TAILQ_NEXT(tid, qe);
+ TAILQ_INSERT_BEFORE(tid, pthread, qe);
+ }
+ pthread->flags |= PTHREAD_FLAGS_IN_MUTEXQ;
+}
+
+#endif
diff --git a/lib/libkse/thread/thr_mutex_prioceiling.c b/lib/libkse/thread/thr_mutex_prioceiling.c
new file mode 100644
index 0000000..c193c82
--- /dev/null
+++ b/lib/libkse/thread/thr_mutex_prioceiling.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_mutexattr_getprioceiling(pthread_mutexattr_t *mattr, int *prioceiling)
+{
+ int ret = 0;
+
+ if ((mattr == NULL) || (*mattr == NULL))
+ ret = EINVAL;
+ else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT)
+ ret = EINVAL;
+ else
+ *prioceiling = (*mattr)->m_ceiling;
+
+ return(ret);
+}
+
+int
+pthread_mutexattr_setprioceiling(pthread_mutexattr_t *mattr, int prioceiling)
+{
+ int ret = 0;
+
+ if ((mattr == NULL) || (*mattr == NULL))
+ ret = EINVAL;
+ else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT)
+ ret = EINVAL;
+ else
+ (*mattr)->m_ceiling = prioceiling;
+
+ return(ret);
+}
+
+int
+pthread_mutex_getprioceiling(pthread_mutex_t *mutex,
+ int *prioceiling)
+{
+ int ret;
+
+ if ((mutex == NULL) || (*mutex == NULL))
+ ret = EINVAL;
+ else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT)
+ ret = EINVAL;
+ else
+ ret = (*mutex)->m_prio;
+
+ return(ret);
+}
+
+int
+pthread_mutex_setprioceiling(pthread_mutex_t *mutex,
+ int prioceiling, int *old_ceiling)
+{
+ int ret = 0;
+
+ if ((mutex == NULL) || (*mutex == NULL))
+ ret = EINVAL;
+ else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT)
+ ret = EINVAL;
+ else {
+ /* Lock the mutex: */
+ if ((ret = pthread_mutex_lock(mutex)) == 0) {
+ /* Return the old ceiling and set the new ceiling: */
+ *old_ceiling = (*mutex)->m_prio;
+ (*mutex)->m_prio = prioceiling;
+
+ /* Unlock the mutex: */
+ ret = pthread_mutex_unlock(mutex);
+ }
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_mutex_protocol.c b/lib/libkse/thread/thr_mutex_protocol.c
new file mode 100644
index 0000000..9847ae5
--- /dev/null
+++ b/lib/libkse/thread/thr_mutex_protocol.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_mutexattr_getprotocol(pthread_mutexattr_t *mattr, int *protocol)
+{
+ int ret = 0;
+
+ if ((mattr == NULL) || (*mattr == NULL))
+ ret = EINVAL;
+ else
+ *protocol = (*mattr)->m_protocol;
+
+ return(ret);
+}
+
+int
+pthread_mutexattr_setprotocol(pthread_mutexattr_t *mattr, int protocol)
+{
+ int ret = 0;
+
+ if ((mattr == NULL) || (*mattr == NULL) ||
+ (protocol < PTHREAD_PRIO_NONE) || (protocol > PTHREAD_PRIO_PROTECT))
+ ret = EINVAL;
+ else {
+ (*mattr)->m_protocol = protocol;
+ (*mattr)->m_ceiling = PTHREAD_MAX_PRIORITY;
+ }
+ return(ret);
+}
+
+#endif
diff --git a/lib/libkse/thread/thr_mutexattr_destroy.c b/lib/libkse/thread/thr_mutexattr_destroy.c
new file mode 100644
index 0000000..9afebad
--- /dev/null
+++ b/lib/libkse/thread/thr_mutexattr_destroy.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ ret = EINVAL;
+ } else {
+ free(*attr);
+ *attr = NULL;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_nanosleep.c b/lib/libkse/thread/thr_nanosleep.c
new file mode 100644
index 0000000..e4772b4
--- /dev/null
+++ b/lib/libkse/thread/thr_nanosleep.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdio.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+nanosleep(const struct timespec * time_to_sleep,
+ struct timespec * time_remaining)
+{
+ int ret = 0;
+ struct timespec current_time;
+ struct timespec current_time1;
+ struct timespec remaining_time;
+ struct timeval tv;
+
+ _thread_enter_cancellation_point();
+ /* Check if the time to sleep is legal: */
+ if (time_to_sleep == NULL || time_to_sleep->tv_sec < 0 ||
+ time_to_sleep->tv_nsec < 0 || time_to_sleep->tv_nsec >= 1000000000) {
+ /* Return an EINVAL error : */
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ /* Get the current time: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &current_time);
+
+ /* Calculate the time for the current thread to wake up: */
+ _thread_run->wakeup_time.tv_sec = current_time.tv_sec + time_to_sleep->tv_sec;
+ _thread_run->wakeup_time.tv_nsec = current_time.tv_nsec + time_to_sleep->tv_nsec;
+
+ /* Check if the nanosecond field has overflowed: */
+ if (_thread_run->wakeup_time.tv_nsec >= 1000000000) {
+ /* Wrap the nanosecond field: */
+ _thread_run->wakeup_time.tv_sec += 1;
+ _thread_run->wakeup_time.tv_nsec -= 1000000000;
+ }
+ _thread_run->interrupted = 0;
+
+ /* Reschedule the current thread to sleep: */
+ _thread_kern_sched_state(PS_SLEEP_WAIT, __FILE__, __LINE__);
+
+ /* Get the current time: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &current_time1);
+
+ /* Calculate the remaining time to sleep: */
+ remaining_time.tv_sec = time_to_sleep->tv_sec + current_time.tv_sec - current_time1.tv_sec;
+ remaining_time.tv_nsec = time_to_sleep->tv_nsec + current_time.tv_nsec - current_time1.tv_nsec;
+
+ /* Check if the nanosecond field has underflowed: */
+ if (remaining_time.tv_nsec < 0) {
+ /* Handle the underflow: */
+ remaining_time.tv_sec -= 1;
+ remaining_time.tv_nsec += 1000000000;
+ }
+
+ /* Check if the nanosecond field has overflowed: */
+ if (remaining_time.tv_nsec >= 1000000000) {
+ /* Handle the overflow: */
+ remaining_time.tv_sec += 1;
+ remaining_time.tv_nsec -= 1000000000;
+ }
+
+ /* Check if the sleep was longer than the required time: */
+ if (remaining_time.tv_sec < 0) {
+ /* Reset the time left: */
+ remaining_time.tv_sec = 0;
+ remaining_time.tv_nsec = 0;
+ }
+
+ /* Check if the time remaining is to be returned: */
+ if (time_remaining != NULL) {
+ /* Return the actual time slept: */
+ time_remaining->tv_sec = remaining_time.tv_sec;
+ time_remaining->tv_nsec = remaining_time.tv_nsec;
+ }
+
+ /* Check if the sleep was interrupted: */
+ if (_thread_run->interrupted) {
+ /* Return an EINTR error : */
+ errno = EINTR;
+ ret = -1;
+ }
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_once.c b/lib/libkse/thread/thr_once.c
new file mode 100644
index 0000000..ea56d82
--- /dev/null
+++ b/lib/libkse/thread/thr_once.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_once(pthread_once_t * once_control, void (*init_routine) (void))
+{
+ if (once_control->state == PTHREAD_NEEDS_INIT) {
+ pthread_mutex_lock(&(once_control->mutex));
+ if (once_control->state == PTHREAD_NEEDS_INIT) {
+ init_routine();
+ once_control->state = PTHREAD_DONE_INIT;
+ }
+ pthread_mutex_unlock(&(once_control->mutex));
+ }
+ return (0);
+}
+#endif
diff --git a/lib/libkse/thread/thr_open.c b/lib/libkse/thread/thr_open.c
new file mode 100644
index 0000000..4e9993e
--- /dev/null
+++ b/lib/libkse/thread/thr_open.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+open(const char *path, int flags,...)
+{
+ int fd;
+ int mode = 0;
+ va_list ap;
+
+ _thread_enter_cancellation_point();
+
+ /* Check if the file is being created: */
+ if (flags & O_CREAT) {
+ /* Get the creation mode: */
+ va_start(ap, flags);
+ mode = va_arg(ap, int);
+ va_end(ap);
+ }
+ /* Open the file: */
+ if ((fd = _thread_sys_open(path, flags, mode)) < 0) {
+ }
+ /* Initialise the file descriptor table entry: */
+ else if (_thread_fd_table_init(fd) != 0) {
+ /* Quietly close the file: */
+ _thread_sys_close(fd);
+
+ /* Reset the file descriptor: */
+ fd = -1;
+ }
+
+ _thread_leave_cancellation_point();
+
+ /* Return the file descriptor or -1 on error: */
+ return (fd);
+}
+#endif
diff --git a/lib/libkse/thread/thr_poll.c b/lib/libkse/thread/thr_poll.c
new file mode 100644
index 0000000..01916ad
--- /dev/null
+++ b/lib/libkse/thread/thr_poll.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+
+int
+poll(struct pollfd *fds, unsigned int nfds, int timeout)
+{
+ struct timespec ts;
+ int numfds = nfds;
+ int i, ret = 0, found = 0;
+ struct pthread_poll_data data;
+
+ if (numfds > _thread_dtablesize) {
+ numfds = _thread_dtablesize;
+ }
+ /* Check if a timeout was specified: */
+ if (timeout == INFTIM) {
+ /* Wait for ever: */
+ _thread_kern_set_timeout(NULL);
+ } else if (timeout > 0) {
+ /* Convert the timeout in msec to a timespec: */
+ ts.tv_sec = timeout / 1000;
+ ts.tv_nsec = (timeout % 1000) * 1000;
+
+ /* Set the wake up time: */
+ _thread_kern_set_timeout(&ts);
+ } else if (timeout < 0) {
+ /* a timeout less than zero but not == INFTIM is invalid */
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (((ret = _thread_sys_poll(fds, numfds, 0)) == 0) && (timeout != 0)) {
+ data.nfds = numfds;
+ data.fds = fds;
+
+ /*
+ * Clear revents in case of a timeout which leaves fds
+ * unchanged:
+ */
+ for (i = 0; i < numfds; i++) {
+ fds[i].revents = 0;
+ }
+
+ _thread_run->data.poll_data = &data;
+ _thread_run->interrupted = 0;
+ _thread_kern_sched_state(PS_POLL_WAIT, __FILE__, __LINE__);
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ } else {
+ ret = data.nfds;
+ }
+ }
+
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_priority_queue.c b/lib/libkse/thread/thr_priority_queue.c
new file mode 100644
index 0000000..5bd8a8c
--- /dev/null
+++ b/lib/libkse/thread/thr_priority_queue.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <sys/queue.h>
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Prototypes: */
+static void pq_insert_prio_list(pq_queue_t *pq, int prio);
+
+#if defined(_PTHREADS_INVARIANTS)
+
+static int _pq_active = 0;
+
+#define _PQ_IN_SCHEDQ (PTHREAD_FLAGS_IN_PRIOQ | PTHREAD_FLAGS_IN_WAITQ | PTHREAD_FLAGS_IN_WORKQ)
+
+#define _PQ_SET_ACTIVE() _pq_active = 1
+#define _PQ_CLEAR_ACTIVE() _pq_active = 0
+#define _PQ_ASSERT_ACTIVE(msg) do { \
+ if (_pq_active == 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_INACTIVE(msg) do { \
+ if (_pq_active != 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_IN_WAITQ(thrd, msg) do { \
+ if (((thrd)->flags & PTHREAD_FLAGS_IN_WAITQ) == 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_IN_PRIOQ(thrd, msg) do { \
+ if (((thrd)->flags & PTHREAD_FLAGS_IN_PRIOQ) == 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_NOT_QUEUED(thrd, msg) do { \
+ if ((thrd)->flags & _PQ_IN_SCHEDQ) \
+ PANIC(msg); \
+} while (0)
+
+#else
+
+#define _PQ_SET_ACTIVE()
+#define _PQ_CLEAR_ACTIVE()
+#define _PQ_ASSERT_ACTIVE(msg)
+#define _PQ_ASSERT_INACTIVE(msg)
+#define _PQ_ASSERT_IN_WAITQ(thrd, msg)
+#define _PQ_ASSERT_IN_PRIOQ(thrd, msg)
+#define _PQ_ASSERT_NOT_QUEUED(thrd, msg)
+#define _PQ_CHECK_PRIO()
+
+#endif
+
+
+int
+_pq_alloc(pq_queue_t *pq, int minprio, int maxprio)
+{
+ int i, ret = 0;
+ int prioslots = maxprio - minprio + 1;
+
+ if (pq == NULL)
+ ret = -1;
+
+ /* Create the priority queue with (maxprio - minprio + 1) slots: */
+ else if ((pq->pq_lists =
+ (pq_list_t *) malloc(sizeof(pq_list_t) * prioslots)) == NULL)
+ ret = -1;
+
+ else {
+ /* Remember the queue size: */
+ pq->pq_size = prioslots;
+
+ ret = _pq_init(pq);
+
+ }
+ return (ret);
+}
+
+int
+_pq_init(pq_queue_t *pq)
+{
+ int i, ret = 0;
+
+ if ((pq == NULL) || (pq->pq_lists == NULL))
+ ret = -1;
+
+ else {
+ /* Initialize the queue for each priority slot: */
+ for (i = 0; i < pq->pq_size; i++) {
+ TAILQ_INIT(&pq->pq_lists[i].pl_head);
+ pq->pq_lists[i].pl_prio = i;
+ pq->pq_lists[i].pl_queued = 0;
+ }
+
+ /* Initialize the priority queue: */
+ TAILQ_INIT(&pq->pq_queue);
+ _PQ_CLEAR_ACTIVE();
+ }
+ return (ret);
+}
+
+void
+_pq_remove(pq_queue_t *pq, pthread_t pthread)
+{
+ int prio = pthread->active_priority;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_remove: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_IN_PRIOQ(pthread, "_pq_remove: Not in priority queue");
+
+ /*
+ * Remove this thread from priority list. Note that if
+ * the priority list becomes empty, it is not removed
+ * from the priority queue because another thread may be
+ * added to the priority list (resulting in a needless
+ * removal/insertion). Priority lists are only removed
+ * from the priority queue when _pq_first is called.
+ */
+ TAILQ_REMOVE(&pq->pq_lists[prio].pl_head, pthread, pqe);
+
+ /* This thread is now longer in the priority queue. */
+ pthread->flags &= ~PTHREAD_FLAGS_IN_PRIOQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+
+void
+_pq_insert_head(pq_queue_t *pq, pthread_t pthread)
+{
+ int prio = pthread->active_priority;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_insert_head: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_NOT_QUEUED(pthread,
+ "_pq_insert_head: Already in priority queue");
+
+ TAILQ_INSERT_HEAD(&pq->pq_lists[prio].pl_head, pthread, pqe);
+ if (pq->pq_lists[prio].pl_queued == 0)
+ /* Insert the list into the priority queue: */
+ pq_insert_prio_list(pq, prio);
+
+ /* Mark this thread as being in the priority queue. */
+ pthread->flags |= PTHREAD_FLAGS_IN_PRIOQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+
+void
+_pq_insert_tail(pq_queue_t *pq, pthread_t pthread)
+{
+ int prio = pthread->active_priority;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_insert_tail: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_NOT_QUEUED(pthread,
+ "_pq_insert_tail: Already in priority queue");
+
+ TAILQ_INSERT_TAIL(&pq->pq_lists[prio].pl_head, pthread, pqe);
+ if (pq->pq_lists[prio].pl_queued == 0)
+ /* Insert the list into the priority queue: */
+ pq_insert_prio_list(pq, prio);
+
+ /* Mark this thread as being in the priority queue. */
+ pthread->flags |= PTHREAD_FLAGS_IN_PRIOQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+
+pthread_t
+_pq_first(pq_queue_t *pq)
+{
+ pq_list_t *pql;
+ pthread_t pthread = NULL;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_first: pq_active");
+ _PQ_SET_ACTIVE();
+
+ while (((pql = TAILQ_FIRST(&pq->pq_queue)) != NULL) &&
+ (pthread == NULL)) {
+ if ((pthread = TAILQ_FIRST(&pql->pl_head)) == NULL) {
+ /*
+ * The priority list is empty; remove the list
+ * from the queue.
+ */
+ TAILQ_REMOVE(&pq->pq_queue, pql, pl_link);
+
+ /* Mark the list as not being in the queue: */
+ pql->pl_queued = 0;
+ }
+ }
+
+ _PQ_CLEAR_ACTIVE();
+ return (pthread);
+}
+
+
+static void
+pq_insert_prio_list(pq_queue_t *pq, int prio)
+{
+ pq_list_t *pql;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_ACTIVE("pq_insert_prio_list: pq_active");
+
+ /*
+ * The priority queue is in descending priority order. Start at
+ * the beginning of the queue and find the list before which the
+ * new list should be inserted.
+ */
+ pql = TAILQ_FIRST(&pq->pq_queue);
+ while ((pql != NULL) && (pql->pl_prio > prio))
+ pql = TAILQ_NEXT(pql, pl_link);
+
+ /* Insert the list: */
+ if (pql == NULL)
+ TAILQ_INSERT_TAIL(&pq->pq_queue, &pq->pq_lists[prio], pl_link);
+ else
+ TAILQ_INSERT_BEFORE(pql, &pq->pq_lists[prio], pl_link);
+
+ /* Mark this list as being in the queue: */
+ pq->pq_lists[prio].pl_queued = 1;
+}
+
+#if defined(_PTHREADS_INVARIANTS)
+void
+_waitq_insert(pthread_t pthread)
+{
+ pthread_t tid;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_waitq_insert: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_NOT_QUEUED(pthread, "_waitq_insert: Already in queue");
+
+ if (pthread->wakeup_time.tv_sec == -1)
+ TAILQ_INSERT_TAIL(&_waitingq, pthread, pqe);
+ else {
+ tid = TAILQ_FIRST(&_waitingq);
+ while ((tid != NULL) && (tid->wakeup_time.tv_sec != -1) &&
+ ((tid->wakeup_time.tv_sec < pthread->wakeup_time.tv_sec) ||
+ ((tid->wakeup_time.tv_sec == pthread->wakeup_time.tv_sec) &&
+ (tid->wakeup_time.tv_nsec <= pthread->wakeup_time.tv_nsec))))
+ tid = TAILQ_NEXT(tid, pqe);
+ if (tid == NULL)
+ TAILQ_INSERT_TAIL(&_waitingq, pthread, pqe);
+ else
+ TAILQ_INSERT_BEFORE(tid, pthread, pqe);
+ }
+ pthread->flags |= PTHREAD_FLAGS_IN_WAITQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+void
+_waitq_remove(pthread_t pthread)
+{
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_waitq_remove: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_IN_WAITQ(pthread, "_waitq_remove: Not in queue");
+
+ TAILQ_REMOVE(&_waitingq, pthread, pqe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_WAITQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+void
+_waitq_setactive(void)
+{
+ _PQ_ASSERT_INACTIVE("_waitq_setactive: pq_active");
+ _PQ_SET_ACTIVE();
+}
+
+void
+_waitq_clearactive(void)
+{
+ _PQ_ASSERT_ACTIVE("_waitq_clearactive: ! pq_active");
+ _PQ_CLEAR_ACTIVE();
+}
+#endif
+#endif
diff --git a/lib/libkse/thread/thr_private.h b/lib/libkse/thread/thr_private.h
new file mode 100644
index 0000000..4326bf6
--- /dev/null
+++ b/lib/libkse/thread/thr_private.h
@@ -0,0 +1,1182 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Private thread definitions for the uthread kernel.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PTHREAD_PRIVATE_H
+#define _PTHREAD_PRIVATE_H
+
+/*
+ * Evaluate the storage class specifier.
+ */
+#ifdef GLOBAL_PTHREAD_PRIVATE
+#define SCLASS
+#else
+#define SCLASS extern
+#endif
+
+/*
+ * Include files.
+ */
+#include <setjmp.h>
+#include <signal.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sched.h>
+#include <spinlock.h>
+#include <pthread_np.h>
+
+/*
+ * Kernel fatal error handler macro.
+ */
+#define PANIC(string) _thread_exit(__FILE__,__LINE__,string)
+
+/* Output debug messages like this: */
+#define stdout_debug(_x) _thread_sys_write(1,_x,strlen(_x));
+#define stderr_debug(_x) _thread_sys_write(2,_x,strlen(_x));
+
+
+/*
+ * Priority queue manipulation macros (using pqe link):
+ */
+#define PTHREAD_PRIOQ_INSERT_HEAD(thrd) _pq_insert_head(&_readyq,thrd)
+#define PTHREAD_PRIOQ_INSERT_TAIL(thrd) _pq_insert_tail(&_readyq,thrd)
+#define PTHREAD_PRIOQ_REMOVE(thrd) _pq_remove(&_readyq,thrd)
+#define PTHREAD_PRIOQ_FIRST() _pq_first(&_readyq)
+
+/*
+ * Waiting queue manipulation macros (using pqe link):
+ */
+#if defined(_PTHREADS_INVARIANTS)
+#define PTHREAD_WAITQ_REMOVE(thrd) _waitq_remove(thrd)
+#define PTHREAD_WAITQ_INSERT(thrd) _waitq_insert(thrd)
+#define PTHREAD_WAITQ_CLEARACTIVE() _waitq_clearactive()
+#define PTHREAD_WAITQ_SETACTIVE() _waitq_setactive()
+#else
+#define PTHREAD_WAITQ_REMOVE(thrd) TAILQ_REMOVE(&_waitingq,thrd,pqe)
+#define PTHREAD_WAITQ_INSERT(thrd) do { \
+ if ((thrd)->wakeup_time.tv_sec == -1) \
+ TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe); \
+ else { \
+ pthread_t tid = TAILQ_FIRST(&_waitingq); \
+ while ((tid != NULL) && (tid->wakeup_time.tv_sec != -1) && \
+ ((tid->wakeup_time.tv_sec < (thrd)->wakeup_time.tv_sec) || \
+ ((tid->wakeup_time.tv_sec == (thrd)->wakeup_time.tv_sec) && \
+ (tid->wakeup_time.tv_nsec <= (thrd)->wakeup_time.tv_nsec)))) \
+ tid = TAILQ_NEXT(tid, pqe); \
+ if (tid == NULL) \
+ TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe); \
+ else \
+ TAILQ_INSERT_BEFORE(tid,thrd,pqe); \
+ } \
+} while (0)
+#define PTHREAD_WAITQ_CLEARACTIVE()
+#define PTHREAD_WAITQ_SETACTIVE()
+#endif
+
+/*
+ * Work queue manipulation macros (using qe link):
+ */
+#define PTHREAD_WORKQ_INSERT(thrd) do { \
+ TAILQ_INSERT_TAIL(&_workq,thrd,qe); \
+ (thrd)->flags |= PTHREAD_FLAGS_IN_WORKQ; \
+} while (0)
+#define PTHREAD_WORKQ_REMOVE(thrd) do { \
+ TAILQ_REMOVE(&_workq,thrd,qe); \
+ (thrd)->flags &= ~PTHREAD_FLAGS_IN_WORKQ; \
+} while (0)
+
+
+/*
+ * State change macro without scheduling queue change:
+ */
+#define PTHREAD_SET_STATE(thrd, newstate) do { \
+ (thrd)->state = newstate; \
+ (thrd)->fname = __FILE__; \
+ (thrd)->lineno = __LINE__; \
+} while (0)
+
+/*
+ * State change macro with scheduling queue change - This must be
+ * called with preemption deferred (see thread_kern_sched_[un]defer).
+ */
+#if defined(_PTHREADS_INVARIANTS)
+#define PTHREAD_NEW_STATE(thrd, newstate) do { \
+ if (_thread_kern_new_state != 0) \
+ PANIC("Recursive PTHREAD_NEW_STATE"); \
+ _thread_kern_new_state = 1; \
+ if ((thrd)->state != newstate) { \
+ if ((thrd)->state == PS_RUNNING) { \
+ PTHREAD_PRIOQ_REMOVE(thrd); \
+ PTHREAD_WAITQ_INSERT(thrd); \
+ } else if (newstate == PS_RUNNING) { \
+ PTHREAD_WAITQ_REMOVE(thrd); \
+ PTHREAD_PRIOQ_INSERT_TAIL(thrd); \
+ } \
+ } \
+ _thread_kern_new_state = 0; \
+ PTHREAD_SET_STATE(thrd, newstate); \
+} while (0)
+#else
+#define PTHREAD_NEW_STATE(thrd, newstate) do { \
+ if ((thrd)->state != newstate) { \
+ if ((thrd)->state == PS_RUNNING) { \
+ PTHREAD_PRIOQ_REMOVE(thrd); \
+ PTHREAD_WAITQ_INSERT(thrd); \
+ } else if (newstate == PS_RUNNING) { \
+ PTHREAD_WAITQ_REMOVE(thrd); \
+ PTHREAD_PRIOQ_INSERT_TAIL(thrd); \
+ } \
+ } \
+ PTHREAD_SET_STATE(thrd, newstate); \
+} while (0)
+#endif
+
+/*
+ * Define the signals to be used for scheduling.
+ */
+#if defined(_PTHREADS_COMPAT_SCHED)
+#define _ITIMER_SCHED_TIMER ITIMER_VIRTUAL
+#define _SCHED_SIGNAL SIGVTALRM
+#else
+#define _ITIMER_SCHED_TIMER ITIMER_PROF
+#define _SCHED_SIGNAL SIGPROF
+#endif
+
+/*
+ * Priority queues.
+ *
+ * XXX It'd be nice if these were contained in uthread_priority_queue.[ch].
+ */
+typedef struct pq_list {
+ TAILQ_HEAD(, pthread) pl_head; /* list of threads at this priority */
+ TAILQ_ENTRY(pq_list) pl_link; /* link for queue of priority lists */
+ int pl_prio; /* the priority of this list */
+ int pl_queued; /* is this in the priority queue */
+} pq_list_t;
+
+typedef struct pq_queue {
+ TAILQ_HEAD(, pq_list) pq_queue; /* queue of priority lists */
+ pq_list_t *pq_lists; /* array of all priority lists */
+ int pq_size; /* number of priority lists */
+} pq_queue_t;
+
+
+/*
+ * TailQ initialization values.
+ */
+#define TAILQ_INITIALIZER { NULL, NULL }
+
+/*
+ * Mutex definitions.
+ */
+union pthread_mutex_data {
+ void *m_ptr;
+ int m_count;
+};
+
+struct pthread_mutex {
+ enum pthread_mutextype m_type;
+ int m_protocol;
+ TAILQ_HEAD(mutex_head, pthread) m_queue;
+ struct pthread *m_owner;
+ union pthread_mutex_data m_data;
+ long m_flags;
+ int m_refcount;
+
+ /*
+ * Used for priority inheritence and protection.
+ *
+ * m_prio - For priority inheritence, the highest active
+ * priority (threads locking the mutex inherit
+ * this priority). For priority protection, the
+ * ceiling priority of this mutex.
+ * m_saved_prio - mutex owners inherited priority before
+ * taking the mutex, restored when the owner
+ * unlocks the mutex.
+ */
+ int m_prio;
+ int m_saved_prio;
+
+ /*
+ * Link for list of all mutexes a thread currently owns.
+ */
+ TAILQ_ENTRY(pthread_mutex) m_qe;
+
+ /*
+ * Lock for accesses to this structure.
+ */
+ spinlock_t lock;
+};
+
+/*
+ * Flags for mutexes.
+ */
+#define MUTEX_FLAGS_PRIVATE 0x01
+#define MUTEX_FLAGS_INITED 0x02
+#define MUTEX_FLAGS_BUSY 0x04
+
+/*
+ * Static mutex initialization values.
+ */
+#define PTHREAD_MUTEX_STATIC_INITIALIZER \
+ { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, TAILQ_INITIALIZER, \
+ NULL, { NULL }, MUTEX_FLAGS_PRIVATE, 0, 0, 0, TAILQ_INITIALIZER, \
+ _SPINLOCK_INITIALIZER }
+
+struct pthread_mutex_attr {
+ enum pthread_mutextype m_type;
+ int m_protocol;
+ int m_ceiling;
+ long m_flags;
+};
+
+/*
+ * Condition variable definitions.
+ */
+enum pthread_cond_type {
+ COND_TYPE_FAST,
+ COND_TYPE_MAX
+};
+
+struct pthread_cond {
+ enum pthread_cond_type c_type;
+ TAILQ_HEAD(cond_head, pthread) c_queue;
+ pthread_mutex_t c_mutex;
+ void *c_data;
+ long c_flags;
+
+ /*
+ * Lock for accesses to this structure.
+ */
+ spinlock_t lock;
+};
+
+struct pthread_cond_attr {
+ enum pthread_cond_type c_type;
+ long c_flags;
+};
+
+/*
+ * Flags for condition variables.
+ */
+#define COND_FLAGS_PRIVATE 0x01
+#define COND_FLAGS_INITED 0x02
+#define COND_FLAGS_BUSY 0x04
+
+/*
+ * Static cond initialization values.
+ */
+#define PTHREAD_COND_STATIC_INITIALIZER \
+ { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \
+ 0, _SPINLOCK_INITIALIZER }
+
+/*
+ * Cleanup definitions.
+ */
+struct pthread_cleanup {
+ struct pthread_cleanup *next;
+ void (*routine) ();
+ void *routine_arg;
+};
+
+struct pthread_attr {
+ int sched_policy;
+ int sched_inherit;
+ int sched_interval;
+ int prio;
+ int suspend;
+ int flags;
+ void *arg_attr;
+ void (*cleanup_attr) ();
+ void *stackaddr_attr;
+ size_t stacksize_attr;
+};
+
+/*
+ * Thread creation state attributes.
+ */
+#define PTHREAD_CREATE_RUNNING 0
+#define PTHREAD_CREATE_SUSPENDED 1
+
+/*
+ * Miscellaneous definitions.
+ */
+#define PTHREAD_STACK_DEFAULT 65536
+/* Size of red zone at the end of each stack. */
+#define PTHREAD_STACK_GUARD PAGE_SIZE
+
+/*
+ * Maximum size of initial thread's stack. This perhaps deserves to be larger
+ * than the stacks of other threads, since many applications are likely to run
+ * almost entirely on this stack.
+ */
+#define PTHREAD_STACK_INITIAL 0x100000
+/* Address immediately beyond the beginning of the initial thread stack. */
+#define PTHREAD_DEFAULT_PRIORITY 64
+#define PTHREAD_MAX_PRIORITY 126
+#define PTHREAD_MIN_PRIORITY 0
+#define _POSIX_THREAD_ATTR_STACKSIZE
+
+/*
+ * Clock resolution in nanoseconds.
+ */
+#define CLOCK_RES_NSEC 10000000
+
+/*
+ * Time slice period in microseconds.
+ */
+#define TIMESLICE_USEC 100000
+
+struct pthread_key {
+ spinlock_t lock;
+ volatile int allocated;
+ volatile int count;
+ void (*destructor) ();
+};
+
+struct pthread_rwlockattr {
+ int pshared;
+};
+
+struct pthread_rwlock {
+ pthread_mutex_t lock; /* monitor lock */
+ int state; /* 0 = idle >0 = # of readers -1 = writer */
+ pthread_cond_t read_signal;
+ pthread_cond_t write_signal;
+ int blocked_writers;
+};
+
+/*
+ * Thread states.
+ */
+enum pthread_state {
+ PS_RUNNING,
+ PS_SIGTHREAD,
+ PS_MUTEX_WAIT,
+ PS_COND_WAIT,
+ PS_FDLR_WAIT,
+ PS_FDLW_WAIT,
+ PS_FDR_WAIT,
+ PS_FDW_WAIT,
+ PS_FILE_WAIT,
+ PS_POLL_WAIT,
+ PS_SELECT_WAIT,
+ PS_SLEEP_WAIT,
+ PS_WAIT_WAIT,
+ PS_SIGSUSPEND,
+ PS_SIGWAIT,
+ PS_SPINBLOCK,
+ PS_JOIN,
+ PS_SUSPENDED,
+ PS_DEAD,
+ PS_DEADLOCK,
+ PS_STATE_MAX
+};
+
+
+/*
+ * File descriptor locking definitions.
+ */
+#define FD_READ 0x1
+#define FD_WRITE 0x2
+#define FD_RDWR (FD_READ | FD_WRITE)
+
+/*
+ * File descriptor table structure.
+ */
+struct fd_table_entry {
+ /*
+ * Lock for accesses to this file descriptor table
+ * entry. This is passed to _spinlock() to provide atomic
+ * access to this structure. It does *not* represent the
+ * state of the lock on the file descriptor.
+ */
+ spinlock_t lock;
+ TAILQ_HEAD(, pthread) r_queue; /* Read queue. */
+ TAILQ_HEAD(, pthread) w_queue; /* Write queue. */
+ struct pthread *r_owner; /* Ptr to thread owning read lock. */
+ struct pthread *w_owner; /* Ptr to thread owning write lock. */
+ char *r_fname; /* Ptr to read lock source file name */
+ int r_lineno; /* Read lock source line number. */
+ char *w_fname; /* Ptr to write lock source file name */
+ int w_lineno; /* Write lock source line number. */
+ int r_lockcount; /* Count for FILE read locks. */
+ int w_lockcount; /* Count for FILE write locks. */
+ int flags; /* Flags used in open. */
+};
+
+struct pthread_poll_data {
+ int nfds;
+ struct pollfd *fds;
+};
+
+union pthread_wait_data {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ const sigset_t *sigwait; /* Waiting on a signal in sigwait */
+ struct {
+ short fd; /* Used when thread waiting on fd */
+ short branch; /* Line number, for debugging. */
+ char *fname; /* Source file name for debugging.*/
+ } fd;
+ struct pthread_poll_data * poll_data;
+ spinlock_t *spinlock;
+};
+
+/*
+ * Thread structure.
+ */
+struct pthread {
+ /*
+ * Magic value to help recognize a valid thread structure
+ * from an invalid one:
+ */
+#define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115)
+ u_int32_t magic;
+ char *name;
+ u_int64_t uniqueid; /* for gdb */
+
+ /*
+ * Lock for accesses to this thread structure.
+ */
+ spinlock_t lock;
+
+ /* Queue entry for list of all threads: */
+ TAILQ_ENTRY(pthread) tle;
+
+ /* Queue entry for list of dead threads: */
+ TAILQ_ENTRY(pthread) dle;
+
+ /*
+ * Thread start routine, argument, stack pointer and thread
+ * attributes.
+ */
+ void *(*start_routine)(void *);
+ void *arg;
+ void *stack;
+ struct pthread_attr attr;
+
+#if (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(__i386__)
+ /*
+ * Saved floating point registers on systems where they are not
+ * saved in the signal context.
+ */
+ char saved_fp[108];
+#endif
+
+ /*
+ * Saved signal context used in call to sigreturn by
+ * _thread_kern_sched if sig_saved is TRUE.
+ */
+ ucontext_t saved_sigcontext;
+
+ /*
+ * Saved jump buffer used in call to longjmp by _thread_kern_sched
+ * if sig_saved is FALSE.
+ */
+ jmp_buf saved_jmp_buf;
+
+ /*
+ * TRUE if the last state saved was a signal context. FALSE if the
+ * last state saved was a jump buffer.
+ */
+ int sig_saved;
+
+ /*
+ * Cancelability flags - the lower 2 bits are used by cancel
+ * definitions in pthread.h
+ */
+#define PTHREAD_AT_CANCEL_POINT 0x0004
+#define PTHREAD_CANCELLING 0x0008
+#define PTHREAD_CANCEL_NEEDED 0x0010
+ int cancelflags;
+
+ /*
+ * Current signal mask and pending signals.
+ */
+ sigset_t sigmask;
+ sigset_t sigpend;
+
+ /* Thread state: */
+ enum pthread_state state;
+
+ /* Time that this thread was last made active. */
+ struct timeval last_active;
+
+ /* Time that this thread was last made inactive. */
+ struct timeval last_inactive;
+
+ /*
+ * Number of microseconds accumulated by this thread when
+ * time slicing is active.
+ */
+ long slice_usec;
+
+ /*
+ * Incremental priority accumulated by thread while it is ready to
+ * run but is denied being run.
+ */
+ int inc_prio;
+
+ /*
+ * Time to wake up thread. This is used for sleeping threads and
+ * for any operation which may time out (such as select).
+ */
+ struct timespec wakeup_time;
+
+ /* TRUE if operation has timed out. */
+ int timeout;
+
+ /*
+ * Error variable used instead of errno. The function __error()
+ * returns a pointer to this.
+ */
+ int error;
+
+ /* Join queue head and link for waiting threads: */
+ TAILQ_HEAD(join_head, pthread) join_queue;
+
+ /*
+ * The current thread can belong to only one scheduling queue at
+ * a time (ready or waiting queue). It can also belong to (only)
+ * one of:
+ *
+ * o A queue of threads waiting for a mutex
+ * o A queue of threads waiting for a condition variable
+ * o A queue of threads waiting for another thread to terminate
+ * (the join queue above)
+ * o A queue of threads waiting for a file descriptor lock
+ * o A queue of threads needing work done by the kernel thread
+ * (waiting for a spinlock or file I/O)
+ *
+ * Use pqe for the scheduling queue link (both ready and waiting),
+ * and qe for other links.
+ */
+
+ /* Priority queue entry for this thread: */
+ TAILQ_ENTRY(pthread) pqe;
+
+ /* Queue entry for this thread: */
+ TAILQ_ENTRY(pthread) qe;
+
+ /* Wait data. */
+ union pthread_wait_data data;
+
+ /*
+ * Allocated for converting select into poll.
+ */
+ struct pthread_poll_data poll_data;
+
+ /*
+ * Set to TRUE if a blocking operation was
+ * interrupted by a signal:
+ */
+ int interrupted;
+
+ /* Signal number when in state PS_SIGWAIT: */
+ int signo;
+
+ /*
+ * Set to non-zero when this thread has deferred signals.
+ * We allow for recursive deferral.
+ */
+ int sig_defer_count;
+
+ /*
+ * Set to TRUE if this thread should yield after undeferring
+ * signals.
+ */
+ int yield_on_sig_undefer;
+
+ /* Miscellaneous flags; only set with signals deferred. */
+ int flags;
+#define PTHREAD_FLAGS_PRIVATE 0x0001
+#define PTHREAD_EXITING 0x0002
+#define PTHREAD_FLAGS_IN_CONDQ 0x0004 /* in condition queue using qe link*/
+#define PTHREAD_FLAGS_IN_WORKQ 0x0008 /* in work queue using qe link */
+#define PTHREAD_FLAGS_IN_WAITQ 0x0010 /* in waiting queue using pqe link */
+#define PTHREAD_FLAGS_IN_PRIOQ 0x0020 /* in priority queue using pqe link */
+#define PTHREAD_FLAGS_IN_MUTEXQ 0x0040 /* in mutex queue using qe link */
+#define PTHREAD_FLAGS_IN_FILEQ 0x0080 /* in file lock queue using qe link */
+#define PTHREAD_FLAGS_IN_FDQ 0x0100 /* in fd lock queue using qe link */
+#define PTHREAD_FLAGS_TRACE 0x0200 /* for debugging purposes */
+
+ /*
+ * Base priority is the user setable and retrievable priority
+ * of the thread. It is only affected by explicit calls to
+ * set thread priority and upon thread creation via a thread
+ * attribute or default priority.
+ */
+ char base_priority;
+
+ /*
+ * Inherited priority is the priority a thread inherits by
+ * taking a priority inheritence or protection mutex. It
+ * is not affected by base priority changes. Inherited
+ * priority defaults to and remains 0 until a mutex is taken
+ * that is being waited on by any other thread whose priority
+ * is non-zero.
+ */
+ char inherited_priority;
+
+ /*
+ * Active priority is always the maximum of the threads base
+ * priority and inherited priority. When there is a change
+ * in either the base or inherited priority, the active
+ * priority must be recalculated.
+ */
+ char active_priority;
+
+ /* Number of priority ceiling or protection mutexes owned. */
+ int priority_mutex_count;
+
+ /*
+ * Queue of currently owned mutexes.
+ */
+ TAILQ_HEAD(, pthread_mutex) mutexq;
+
+ void *ret;
+ const void **specific_data;
+ int specific_data_count;
+
+ /* Cleanup handlers Link List */
+ struct pthread_cleanup *cleanup;
+ char *fname; /* Ptr to source file name */
+ int lineno; /* Source line number. */
+};
+
+/* Spare thread stack. */
+struct stack {
+ SLIST_ENTRY(stack) qe; /* Queue entry for this stack. */
+};
+
+/*
+ * Global variables for the uthread kernel.
+ */
+
+/* Kernel thread structure used when there are no running threads: */
+SCLASS struct pthread _thread_kern_thread;
+
+/* Ptr to the thread structure for the running thread: */
+SCLASS struct pthread * volatile _thread_run
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= &_thread_kern_thread;
+#else
+;
+#endif
+
+/* Ptr to the thread structure for the last user thread to run: */
+SCLASS struct pthread * volatile _last_user_thread
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= &_thread_kern_thread;
+#else
+;
+#endif
+
+/*
+ * Ptr to the thread running in single-threaded mode or NULL if
+ * running multi-threaded (default POSIX behaviour).
+ */
+SCLASS struct pthread * volatile _thread_single
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL;
+#else
+;
+#endif
+
+/* List of all threads: */
+SCLASS TAILQ_HEAD(, pthread) _thread_list
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= TAILQ_HEAD_INITIALIZER(_thread_list);
+#else
+;
+#endif
+
+/*
+ * Array of kernel pipe file descriptors that are used to ensure that
+ * no signals are missed in calls to _select.
+ */
+SCLASS int _thread_kern_pipe[2]
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= {
+ -1,
+ -1
+};
+#else
+;
+#endif
+SCLASS int volatile _queue_signals
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0;
+#else
+;
+#endif
+SCLASS int _thread_kern_in_sched
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0;
+#else
+;
+#endif
+
+/* Last time that an incremental priority update was performed: */
+SCLASS struct timeval kern_inc_prio_time
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= { 0, 0 };
+#else
+;
+#endif
+
+/* Dead threads: */
+SCLASS TAILQ_HEAD(, pthread) _dead_list
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= TAILQ_HEAD_INITIALIZER(_dead_list);
+#else
+;
+#endif
+
+/* Initial thread: */
+SCLASS struct pthread *_thread_initial
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL;
+#else
+;
+#endif
+
+/* Default thread attributes: */
+SCLASS struct pthread_attr pthread_attr_default
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY, PTHREAD_CREATE_RUNNING,
+ PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, PTHREAD_STACK_DEFAULT };
+#else
+;
+#endif
+
+/* Default mutex attributes: */
+SCLASS struct pthread_mutex_attr pthread_mutexattr_default
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 };
+#else
+;
+#endif
+
+/* Default condition variable attributes: */
+SCLASS struct pthread_cond_attr pthread_condattr_default
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= { COND_TYPE_FAST, 0 };
+#else
+;
+#endif
+
+/*
+ * Standard I/O file descriptors need special flag treatment since
+ * setting one to non-blocking does all on *BSD. Sigh. This array
+ * is used to store the initial flag settings.
+ */
+SCLASS int _pthread_stdio_flags[3];
+
+/* File table information: */
+SCLASS struct fd_table_entry **_thread_fd_table
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL;
+#else
+;
+#endif
+
+/* Table for polling file descriptors: */
+SCLASS struct pollfd *_thread_pfd_table
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL;
+#else
+;
+#endif
+
+SCLASS const int dtablecount
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 4096/sizeof(struct fd_table_entry);
+#else
+;
+#endif
+SCLASS int _thread_dtablesize /* Descriptor table size. */
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0;
+#else
+;
+#endif
+
+SCLASS int _clock_res_nsec /* Clock resolution in nsec. */
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= CLOCK_RES_NSEC;
+#else
+;
+#endif
+
+/* Garbage collector mutex and condition variable. */
+SCLASS pthread_mutex_t _gc_mutex
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL
+#endif
+;
+SCLASS pthread_cond_t _gc_cond
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL
+#endif
+;
+
+/*
+ * Array of signal actions for this process.
+ */
+SCLASS struct sigaction _thread_sigact[NSIG];
+
+/*
+ * Pending signals for this process.
+ */
+SCLASS sigset_t _process_sigpending;
+
+/*
+ * Scheduling queues:
+ */
+SCLASS pq_queue_t _readyq;
+SCLASS TAILQ_HEAD(, pthread) _waitingq;
+
+/*
+ * Work queue:
+ */
+SCLASS TAILQ_HEAD(, pthread) _workq;
+
+/* Tracks the number of threads blocked while waiting for a spinlock. */
+SCLASS volatile int _spinblock_count
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0
+#endif
+;
+
+/* Indicates that the signal queue needs to be checked. */
+SCLASS volatile int _sigq_check_reqd
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0
+#endif
+;
+
+/* Thread switch hook. */
+SCLASS pthread_switch_routine_t _sched_switch_hook
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL
+#endif
+;
+
+/*
+ * Spare stack queue. Stacks of default size are cached in order to reduce
+ * thread creation time. Spare stacks are used in LIFO order to increase cache
+ * locality.
+ */
+SCLASS SLIST_HEAD(, stack) _stackq;
+
+/* Base address of next unallocated default-size stack. Stacks are allocated
+ * contiguously, starting below the beginning of the main stack. When a new
+ * stack is created, a guard page is created just above it in order to (usually)
+ * detect attempts by the adjacent stack to trounce the next thread stack. */
+SCLASS void * _next_stack
+#ifdef GLOBAL_PTHREAD_PRIVATE
+/* main stack top - main stack size - stack size - (red zone + main stack red zone) */
+= (void *) USRSTACK - PTHREAD_STACK_INITIAL - PTHREAD_STACK_DEFAULT - (2 * PTHREAD_STACK_GUARD)
+#endif
+;
+
+/* Used for _PTHREADS_INVARIANTS checking. */
+SCLASS int _thread_kern_new_state
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0
+#endif
+;
+
+/* Undefine the storage class specifier: */
+#undef SCLASS
+
+#ifdef _LOCK_DEBUG
+#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock_debug(_fd, _type, \
+ _ts, __FILE__, __LINE__)
+#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock_debug(_fd, _type, \
+ __FILE__, __LINE__)
+#else
+#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock(_fd, _type, _ts)
+#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock(_fd, _type)
+#endif
+
+/*
+ * Function prototype definitions.
+ */
+__BEGIN_DECLS
+char *__ttyname_basic(int);
+char *__ttyname_r_basic(int, char *, size_t);
+char *ttyname_r(int, char *, size_t);
+int _find_dead_thread(pthread_t);
+int _find_thread(pthread_t);
+void _funlock_owned(pthread_t);
+int _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t);
+int _thread_fd_lock(int, int, struct timespec *);
+int _thread_fd_lock_debug(int, int, struct timespec *,char *fname,int lineno);
+void _dispatch_signals(void);
+int _mutex_cv_lock(pthread_mutex_t *);
+int _mutex_cv_unlock(pthread_mutex_t *);
+void _mutex_notify_priochange(pthread_t);
+int _mutex_reinit(pthread_mutex_t *);
+void _mutex_unlock_private(pthread_t);
+int _cond_reinit(pthread_cond_t *);
+int _pq_alloc(struct pq_queue *, int, int);
+int _pq_init(struct pq_queue *);
+void _pq_remove(struct pq_queue *pq, struct pthread *);
+void _pq_insert_head(struct pq_queue *pq, struct pthread *);
+void _pq_insert_tail(struct pq_queue *pq, struct pthread *);
+struct pthread *_pq_first(struct pq_queue *pq);
+#if defined(_PTHREADS_INVARIANTS)
+void _waitq_insert(pthread_t pthread);
+void _waitq_remove(pthread_t pthread);
+void _waitq_setactive(void);
+void _waitq_clearactive(void);
+#endif
+void _thread_exit(char *, int, char *);
+void _thread_exit_cleanup(void);
+void _thread_fd_unlock(int, int);
+void _thread_fd_unlock_debug(int, int, char *, int);
+void _thread_fd_unlock_owned(pthread_t);
+void *_thread_cleanup(pthread_t);
+void _thread_cleanupspecific(void);
+void _thread_dump_info(void);
+void _thread_init(void);
+void _thread_kern_sched(ucontext_t *);
+void _thread_kern_sched_state(enum pthread_state,char *fname,int lineno);
+void _thread_kern_sched_state_unlock(enum pthread_state state,
+ spinlock_t *lock, char *fname, int lineno);
+void _thread_kern_set_timeout(struct timespec *);
+void _thread_kern_sig_defer(void);
+void _thread_kern_sig_undefer(void);
+void _thread_sig_handler(int, int, ucontext_t *);
+pthread_t _thread_sig_handle(int, ucontext_t *);
+void _thread_sig_init(void);
+void _thread_sig_send(pthread_t pthread, int sig);
+void _thread_sig_deliver(pthread_t pthread, int sig);
+void _thread_start(void);
+void _thread_start_sig_handler(void);
+void _thread_seterrno(pthread_t,int);
+int _thread_fd_table_init(int fd);
+pthread_addr_t _thread_gc(pthread_addr_t);
+void _thread_enter_cancellation_point(void);
+void _thread_leave_cancellation_point(void);
+void _thread_cancellation_point(void);
+
+/* #include <signal.h> */
+int _thread_sys_sigaction(int, const struct sigaction *, struct sigaction *);
+int _thread_sys_sigpending(sigset_t *);
+int _thread_sys_sigprocmask(int, const sigset_t *, sigset_t *);
+int _thread_sys_sigsuspend(const sigset_t *);
+int _thread_sys_siginterrupt(int, int);
+int _thread_sys_sigpause(int);
+int _thread_sys_sigreturn(ucontext_t *);
+int _thread_sys_sigstack(const struct sigstack *, struct sigstack *);
+int _thread_sys_sigvec(int, struct sigvec *, struct sigvec *);
+void _thread_sys_psignal(unsigned int, const char *);
+void (*_thread_sys_signal(int, void (*)(int)))(int);
+
+/* #include <sys/stat.h> */
+#ifdef _SYS_STAT_H_
+int _thread_sys_fchmod(int, mode_t);
+int _thread_sys_fstat(int, struct stat *);
+int _thread_sys_fchflags(int, u_long);
+#endif
+
+/* #include <sys/mount.h> */
+#ifdef _SYS_MOUNT_H_
+int _thread_sys_fstatfs(int, struct statfs *);
+#endif
+int _thread_sys_pipe(int *);
+
+/* #include <sys/socket.h> */
+#ifdef _SYS_SOCKET_H_
+int _thread_sys_accept(int, struct sockaddr *, int *);
+int _thread_sys_bind(int, const struct sockaddr *, int);
+int _thread_sys_connect(int, const struct sockaddr *, int);
+int _thread_sys_getpeername(int, struct sockaddr *, int *);
+int _thread_sys_getsockname(int, struct sockaddr *, int *);
+int _thread_sys_getsockopt(int, int, int, void *, int *);
+int _thread_sys_listen(int, int);
+int _thread_sys_setsockopt(int, int, int, const void *, int);
+int _thread_sys_shutdown(int, int);
+int _thread_sys_socket(int, int, int);
+int _thread_sys_socketpair(int, int, int, int *);
+ssize_t _thread_sys_recv(int, void *, size_t, int);
+ssize_t _thread_sys_recvfrom(int, void *, size_t, int, struct sockaddr *, int *);
+ssize_t _thread_sys_recvmsg(int, struct msghdr *, int);
+ssize_t _thread_sys_send(int, const void *, size_t, int);
+ssize_t _thread_sys_sendmsg(int, const struct msghdr *, int);
+ssize_t _thread_sys_sendto(int, const void *,size_t, int, const struct sockaddr *, int);
+#endif
+
+/* #include <stdio.h> */
+#ifdef _STDIO_H_
+FILE *_thread_sys_fdopen(int, const char *);
+FILE *_thread_sys_fopen(const char *, const char *);
+FILE *_thread_sys_freopen(const char *, const char *, FILE *);
+FILE *_thread_sys_popen(const char *, const char *);
+FILE *_thread_sys_tmpfile(void);
+char *_thread_sys_ctermid(char *);
+char *_thread_sys_cuserid(char *);
+char *_thread_sys_fgetln(FILE *, size_t *);
+char *_thread_sys_fgets(char *, int, FILE *);
+char *_thread_sys_gets(char *);
+char *_thread_sys_tempnam(const char *, const char *);
+char *_thread_sys_tmpnam(char *);
+int _thread_sys_fclose(FILE *);
+int _thread_sys_feof(FILE *);
+int _thread_sys_ferror(FILE *);
+int _thread_sys_fflush(FILE *);
+int _thread_sys_fgetc(FILE *);
+int _thread_sys_fgetpos(FILE *, fpos_t *);
+int _thread_sys_fileno(FILE *);
+int _thread_sys_fprintf(FILE *, const char *, ...);
+int _thread_sys_fpurge(FILE *);
+int _thread_sys_fputc(int, FILE *);
+int _thread_sys_fputs(const char *, FILE *);
+int _thread_sys_fscanf(FILE *, const char *, ...);
+int _thread_sys_fseek(FILE *, long, int);
+int _thread_sys_fsetpos(FILE *, const fpos_t *);
+int _thread_sys_getc(FILE *);
+int _thread_sys_getchar(void);
+int _thread_sys_getw(FILE *);
+int _thread_sys_pclose(FILE *);
+int _thread_sys_printf(const char *, ...);
+int _thread_sys_putc(int, FILE *);
+int _thread_sys_putchar(int);
+int _thread_sys_puts(const char *);
+int _thread_sys_putw(int, FILE *);
+int _thread_sys_remove(const char *);
+int _thread_sys_rename (const char *, const char *);
+int _thread_sys_scanf(const char *, ...);
+int _thread_sys_setlinebuf(FILE *);
+int _thread_sys_setvbuf(FILE *, char *, int, size_t);
+int _thread_sys_snprintf(char *, size_t, const char *, ...);
+int _thread_sys_sprintf(char *, const char *, ...);
+int _thread_sys_sscanf(const char *, const char *, ...);
+int _thread_sys_ungetc(int, FILE *);
+int _thread_sys_vfprintf(FILE *, const char *, _BSD_VA_LIST_);
+int _thread_sys_vprintf(const char *, _BSD_VA_LIST_);
+int _thread_sys_vscanf(const char *, _BSD_VA_LIST_);
+int _thread_sys_vsnprintf(char *, size_t, const char *, _BSD_VA_LIST_);
+int _thread_sys_vsprintf(char *, const char *, _BSD_VA_LIST_);
+int _thread_sys_vsscanf(const char *, const char *, _BSD_VA_LIST_);
+long _thread_sys_ftell(FILE *);
+size_t _thread_sys_fread(void *, size_t, size_t, FILE *);
+size_t _thread_sys_fwrite(const void *, size_t, size_t, FILE *);
+void _thread_sys_clearerr(FILE *);
+void _thread_sys_perror(const char *);
+void _thread_sys_rewind(FILE *);
+void _thread_sys_setbuf(FILE *, char *);
+void _thread_sys_setbuffer(FILE *, char *, int);
+#endif
+
+/* #include <unistd.h> */
+#ifdef _UNISTD_H_
+char *_thread_sys_ttyname(int);
+int _thread_sys_close(int);
+int _thread_sys_dup(int);
+int _thread_sys_dup2(int, int);
+int _thread_sys_exect(const char *, char * const *, char * const *);
+int _thread_sys_execve(const char *, char * const *, char * const *);
+int _thread_sys_fchdir(int);
+int _thread_sys_fchown(int, uid_t, gid_t);
+int _thread_sys_fsync(int);
+int _thread_sys_ftruncate(int, off_t);
+int _thread_sys_pause(void);
+int _thread_sys_pipe(int *);
+int _thread_sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+off_t _thread_sys_lseek(int, off_t, int);
+pid_t _thread_sys_fork(void);
+pid_t _thread_sys_tcgetpgrp(int);
+ssize_t _thread_sys_read(int, void *, size_t);
+ssize_t _thread_sys_write(int, const void *, size_t);
+void _thread_sys__exit(int);
+#endif
+
+/* #include <fcntl.h> */
+#ifdef _SYS_FCNTL_H_
+int _thread_sys_creat(const char *, mode_t);
+int _thread_sys_fcntl(int, int, ...);
+int _thread_sys_flock(int, int);
+int _thread_sys_open(const char *, int, ...);
+#endif
+
+/* #include <sys/ioctl.h> */
+#ifdef _SYS_IOCTL_H_
+int _thread_sys_ioctl(int, unsigned long, ...);
+#endif
+
+/* #include <dirent.h> */
+#ifdef _DIRENT_H_
+DIR *___thread_sys_opendir2(const char *, int);
+DIR *_thread_sys_opendir(const char *);
+int _thread_sys_alphasort(const void *, const void *);
+int _thread_sys_scandir(const char *, struct dirent ***,
+ int (*)(struct dirent *), int (*)(const void *, const void *));
+int _thread_sys_closedir(DIR *);
+int _thread_sys_getdirentries(int, char *, int, long *);
+long _thread_sys_telldir(const DIR *);
+struct dirent *_thread_sys_readdir(DIR *);
+void _thread_sys_rewinddir(DIR *);
+void _thread_sys_seekdir(DIR *, long);
+#endif
+
+/* #include <sys/uio.h> */
+#ifdef _SYS_UIO_H_
+ssize_t _thread_sys_readv(int, const struct iovec *, int);
+ssize_t _thread_sys_writev(int, const struct iovec *, int);
+#endif
+
+/* #include <sys/wait.h> */
+#ifdef WNOHANG
+pid_t _thread_sys_wait(int *);
+pid_t _thread_sys_waitpid(pid_t, int *, int);
+pid_t _thread_sys_wait3(int *, int, struct rusage *);
+pid_t _thread_sys_wait4(pid_t, int *, int, struct rusage *);
+#endif
+
+/* #include <poll.h> */
+#ifdef _SYS_POLL_H_
+int _thread_sys_poll(struct pollfd *, unsigned, int);
+#endif
+/* #include <sys/mman.h> */
+int _thread_sys_msync(void *, size_t, int);
+__END_DECLS
+
+#endif /* !_PTHREAD_PRIVATE_H */
diff --git a/lib/libkse/thread/thr_read.c b/lib/libkse/thread/thr_read.c
new file mode 100644
index 0000000..8cbb5be
--- /dev/null
+++ b/lib/libkse/thread/thr_read.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+read(int fd, void *buf, size_t nbytes)
+{
+ int ret;
+ int type;
+
+ _thread_enter_cancellation_point();
+
+ /* POSIX says to do just this: */
+ if (nbytes == 0) {
+ _thread_leave_cancellation_point();
+ return (0);
+ }
+
+ /* Lock the file descriptor for read: */
+ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ /* Get the read/write mode type: */
+ type = _thread_fd_table[fd]->flags & O_ACCMODE;
+
+ /* Check if the file is not open for read: */
+ if (type != O_RDONLY && type != O_RDWR) {
+ /* File is not open for read: */
+ errno = EBADF;
+ _FD_UNLOCK(fd, FD_READ);
+ _thread_leave_cancellation_point();
+ return (-1);
+ }
+
+ /* Perform a non-blocking read syscall: */
+ while ((ret = _thread_sys_read(fd, buf, nbytes)) < 0) {
+ if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0 &&
+ (errno == EWOULDBLOCK || errno == EAGAIN)) {
+ _thread_run->data.fd.fd = fd;
+ _thread_kern_set_timeout(NULL);
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDR_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ _FD_UNLOCK(fd, FD_READ);
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_readv.c b/lib/libkse/thread/thr_readv.c
new file mode 100644
index 0000000..a1a862d
--- /dev/null
+++ b/lib/libkse/thread/thr_readv.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+readv(int fd, const struct iovec * iov, int iovcnt)
+{
+ int ret;
+ int type;
+
+ /* Lock the file descriptor for read: */
+ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ /* Get the read/write mode type: */
+ type = _thread_fd_table[fd]->flags & O_ACCMODE;
+
+ /* Check if the file is not open for read: */
+ if (type != O_RDONLY && type != O_RDWR) {
+ /* File is not open for read: */
+ errno = EBADF;
+ _FD_UNLOCK(fd, FD_READ);
+ return (-1);
+ }
+
+ /* Perform a non-blocking readv syscall: */
+ while ((ret = _thread_sys_readv(fd, iov, iovcnt)) < 0) {
+ if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0 &&
+ (errno == EWOULDBLOCK || errno == EAGAIN)) {
+ _thread_run->data.fd.fd = fd;
+ _thread_kern_set_timeout(NULL);
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDR_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ _FD_UNLOCK(fd, FD_READ);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_resume_np.c b/lib/libkse/thread/thr_resume_np.c
new file mode 100644
index 0000000..98ec718
--- /dev/null
+++ b/lib/libkse/thread/thr_resume_np.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Resume a thread: */
+int
+pthread_resume_np(pthread_t thread)
+{
+ int ret;
+
+ /* Find the thread in the list of active threads: */
+ if ((ret = _find_thread(thread)) == 0) {
+ /* The thread exists. Is it suspended? */
+ if (thread->state != PS_SUSPENDED) {
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Allow the thread to run. */
+ PTHREAD_NEW_STATE(thread,PS_RUNNING);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_rwlock.c b/lib/libkse/thread/thr_rwlock.c
new file mode 100644
index 0000000..648e8a3
--- /dev/null
+++ b/lib/libkse/thread/thr_rwlock.c
@@ -0,0 +1,335 @@
+/*-
+ * Copyright (c) 1998 Alex Nash
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifdef _THREAD_SAFE
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* maximum number of times a read lock may be obtained */
+#define MAX_READ_LOCKS (INT_MAX - 1)
+
+static int init_static (pthread_rwlock_t *rwlock);
+
+static spinlock_t static_init_lock = _SPINLOCK_INITIALIZER;
+
+static int
+init_static (pthread_rwlock_t *rwlock)
+{
+ int ret;
+
+ _SPINLOCK(&static_init_lock);
+
+ if (*rwlock == NULL)
+ ret = pthread_rwlock_init(rwlock, NULL);
+ else
+ ret = 0;
+
+ _SPINUNLOCK(&static_init_lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
+{
+ int ret;
+
+ if (rwlock == NULL)
+ ret = EINVAL;
+ else {
+ pthread_rwlock_t prwlock;
+
+ prwlock = *rwlock;
+
+ pthread_mutex_destroy(&prwlock->lock);
+ pthread_cond_destroy(&prwlock->read_signal);
+ pthread_cond_destroy(&prwlock->write_signal);
+ free(prwlock);
+
+ *rwlock = NULL;
+
+ ret = 0;
+ }
+
+ return(ret);
+}
+
+int
+pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ /* allocate rwlock object */
+ prwlock = (pthread_rwlock_t)malloc(sizeof(struct pthread_rwlock));
+
+ if (prwlock == NULL)
+ return(ENOMEM);
+
+ /* initialize the lock */
+ if ((ret = pthread_mutex_init(&prwlock->lock, NULL)) != 0)
+ free(prwlock);
+ else {
+ /* initialize the read condition signal */
+ ret = pthread_cond_init(&prwlock->read_signal, NULL);
+
+ if (ret != 0) {
+ pthread_mutex_destroy(&prwlock->lock);
+ free(prwlock);
+ } else {
+ /* initialize the write condition signal */
+ ret = pthread_cond_init(&prwlock->write_signal, NULL);
+
+ if (ret != 0) {
+ pthread_cond_destroy(&prwlock->read_signal);
+ pthread_mutex_destroy(&prwlock->lock);
+ free(prwlock);
+ } else {
+ /* success */
+ prwlock->state = 0;
+ prwlock->blocked_writers = 0;
+
+ *rwlock = prwlock;
+ }
+ }
+ }
+
+ return(ret);
+}
+
+int
+pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ /* give writers priority over readers */
+ while (prwlock->blocked_writers || prwlock->state < 0) {
+ ret = pthread_cond_wait(&prwlock->read_signal, &prwlock->lock);
+
+ if (ret != 0) {
+ /* can't do a whole lot if this fails */
+ pthread_mutex_unlock(&prwlock->lock);
+ return(ret);
+ }
+ }
+
+ /* check lock count */
+ if (prwlock->state == MAX_READ_LOCKS)
+ ret = EAGAIN;
+ else
+ ++prwlock->state; /* indicate we are locked for reading */
+
+ /*
+ * Something is really wrong if this call fails. Returning
+ * error won't do because we've already obtained the read
+ * lock. Decrementing 'state' is no good because we probably
+ * don't have the monitor lock.
+ */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ /* give writers priority over readers */
+ if (prwlock->blocked_writers || prwlock->state < 0)
+ ret = EWOULDBLOCK;
+ else if (prwlock->state == MAX_READ_LOCKS)
+ ret = EAGAIN; /* too many read locks acquired */
+ else
+ ++prwlock->state; /* indicate we are locked for reading */
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ if (prwlock->state != 0)
+ ret = EWOULDBLOCK;
+ else
+ /* indicate we are locked for writing */
+ prwlock->state = -1;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ if (prwlock == NULL)
+ return(EINVAL);
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ if (prwlock->state > 0) {
+ if (--prwlock->state == 0 && prwlock->blocked_writers)
+ ret = pthread_cond_signal(&prwlock->write_signal);
+ } else if (prwlock->state < 0) {
+ prwlock->state = 0;
+
+ if (prwlock->blocked_writers)
+ ret = pthread_cond_signal(&prwlock->write_signal);
+ else
+ ret = pthread_cond_broadcast(&prwlock->read_signal);
+ } else
+ ret = EINVAL;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ while (prwlock->state != 0) {
+ ++prwlock->blocked_writers;
+
+ ret = pthread_cond_wait(&prwlock->write_signal, &prwlock->lock);
+
+ if (ret != 0) {
+ --prwlock->blocked_writers;
+ pthread_mutex_unlock(&prwlock->lock);
+ return(ret);
+ }
+
+ --prwlock->blocked_writers;
+ }
+
+ /* indicate we are locked for writing */
+ prwlock->state = -1;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+#endif /* _THREAD_SAFE */
diff --git a/lib/libkse/thread/thr_rwlockattr.c b/lib/libkse/thread/thr_rwlockattr.c
new file mode 100644
index 0000000..7a56bca
--- /dev/null
+++ b/lib/libkse/thread/thr_rwlockattr.c
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 1998 Alex Nash
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifdef _THREAD_SAFE
+#include <errno.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr)
+{
+ pthread_rwlockattr_t prwlockattr;
+
+ if (rwlockattr == NULL)
+ return(EINVAL);
+
+ prwlockattr = *rwlockattr;
+
+ if (prwlockattr == NULL)
+ return(EINVAL);
+
+ free(prwlockattr);
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *rwlockattr,
+ int *pshared)
+{
+ *pshared = (*rwlockattr)->pshared;
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr)
+{
+ pthread_rwlockattr_t prwlockattr;
+
+ if (rwlockattr == NULL)
+ return(EINVAL);
+
+ prwlockattr = (pthread_rwlockattr_t)
+ malloc(sizeof(struct pthread_rwlockattr));
+
+ if (prwlockattr == NULL)
+ return(ENOMEM);
+
+ prwlockattr->pshared = PTHREAD_PROCESS_PRIVATE;
+ *rwlockattr = prwlockattr;
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_setpshared (pthread_rwlockattr_t *rwlockattr, int pshared)
+{
+ /* Only PTHREAD_PROCESS_PRIVATE is supported. */
+ if (pshared != PTHREAD_PROCESS_PRIVATE)
+ return(EINVAL);
+
+ (*rwlockattr)->pshared = pshared;
+
+ return(0);
+}
+
+#endif /* _THREAD_SAFE */
diff --git a/lib/libkse/thread/thr_select.c b/lib/libkse/thread/thr_select.c
new file mode 100644
index 0000000..9bfae89
--- /dev/null
+++ b/lib/libkse/thread/thr_select.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <unistd.h>
+#include <errno.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+select(int numfds, fd_set * readfds, fd_set * writefds,
+ fd_set * exceptfds, struct timeval * timeout)
+{
+ struct timespec ts;
+ int i, ret = 0, f_wait = 1;
+ int pfd_index, got_one = 0, fd_count = 0;
+ struct pthread_poll_data data;
+
+ if (numfds > _thread_dtablesize) {
+ numfds = _thread_dtablesize;
+ }
+ /* Check if a timeout was specified: */
+ if (timeout) {
+ if (timeout->tv_sec < 0 ||
+ timeout->tv_usec < 0 || timeout->tv_usec >= 1000000) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /* Convert the timeval to a timespec: */
+ TIMEVAL_TO_TIMESPEC(timeout, &ts);
+
+ /* Set the wake up time: */
+ _thread_kern_set_timeout(&ts);
+ if (ts.tv_sec == 0 && ts.tv_nsec == 0)
+ f_wait = 0;
+ } else {
+ /* Wait for ever: */
+ _thread_kern_set_timeout(NULL);
+ }
+
+ /* Count the number of file descriptors to be polled: */
+ if (readfds || writefds || exceptfds) {
+ for (i = 0; i < numfds; i++) {
+ if ((readfds && FD_ISSET(i, readfds)) ||
+ (exceptfds && FD_ISSET(i, exceptfds)) ||
+ (writefds && FD_ISSET(i, writefds))) {
+ fd_count++;
+ }
+ }
+ }
+
+ /*
+ * Allocate memory for poll data if it hasn't already been
+ * allocated or if previously allocated memory is insufficient.
+ */
+ if ((_thread_run->poll_data.fds == NULL) ||
+ (_thread_run->poll_data.nfds < fd_count)) {
+ data.fds = (struct pollfd *) realloc(_thread_run->poll_data.fds,
+ sizeof(struct pollfd) * MAX(128, fd_count));
+ if (data.fds == NULL) {
+ errno = ENOMEM;
+ ret = -1;
+ }
+ else {
+ /*
+ * Note that the threads poll data always
+ * indicates what is allocated, not what is
+ * currently being polled.
+ */
+ _thread_run->poll_data.fds = data.fds;
+ _thread_run->poll_data.nfds = MAX(128, fd_count);
+ }
+ }
+ if (ret == 0) {
+ /* Setup the wait data. */
+ data.fds = _thread_run->poll_data.fds;
+ data.nfds = fd_count;
+
+ /*
+ * Setup the array of pollfds. Optimize this by
+ * running the loop in reverse and stopping when
+ * the number of selected file descriptors is reached.
+ */
+ for (i = numfds - 1, pfd_index = fd_count - 1;
+ (i >= 0) && (pfd_index >= 0); i--) {
+ data.fds[pfd_index].events = 0;
+ if (readfds && FD_ISSET(i, readfds)) {
+ data.fds[pfd_index].events = POLLRDNORM;
+ }
+ if (exceptfds && FD_ISSET(i, exceptfds)) {
+ data.fds[pfd_index].events |= POLLRDBAND;
+ }
+ if (writefds && FD_ISSET(i, writefds)) {
+ data.fds[pfd_index].events |= POLLWRNORM;
+ }
+ if (data.fds[pfd_index].events != 0) {
+ /*
+ * Set the file descriptor to be polled and
+ * clear revents in case of a timeout which
+ * leaves fds unchanged:
+ */
+ data.fds[pfd_index].fd = i;
+ data.fds[pfd_index].revents = 0;
+ pfd_index--;
+ }
+ }
+ if (((ret = _thread_sys_poll(data.fds, data.nfds, 0)) == 0) &&
+ (f_wait != 0)) {
+ _thread_run->data.poll_data = &data;
+ _thread_run->interrupted = 0;
+ _thread_kern_sched_state(PS_SELECT_WAIT, __FILE__, __LINE__);
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ data.nfds = 0;
+ ret = -1;
+ } else
+ ret = data.nfds;
+ }
+ }
+
+ if (ret >= 0) {
+ numfds = 0;
+ for (i = 0; i < fd_count; i++) {
+ /*
+ * Check the results of the poll and clear
+ * this file descriptor from the fdset if
+ * the requested event wasn't ready.
+ */
+ got_one = 0;
+ if (readfds != NULL) {
+ if (FD_ISSET(data.fds[i].fd, readfds)) {
+ if (data.fds[i].revents & (POLLIN |
+ POLLRDNORM))
+ got_one = 1;
+ else
+ FD_CLR(data.fds[i].fd, readfds);
+ }
+ }
+ if (writefds != NULL) {
+ if (FD_ISSET(data.fds[i].fd, writefds)) {
+ if (data.fds[i].revents & (POLLOUT |
+ POLLWRNORM | POLLWRBAND))
+ got_one = 1;
+ else
+ FD_CLR(data.fds[i].fd,
+ writefds);
+ }
+ }
+ if (exceptfds != NULL) {
+ if (FD_ISSET(data.fds[i].fd, exceptfds)) {
+ if (data.fds[i].revents & (POLLRDBAND |
+ POLLPRI | POLLHUP | POLLERR |
+ POLLNVAL))
+ got_one = 1;
+ else
+ FD_CLR(data.fds[i].fd,
+ exceptfds);
+ }
+ }
+ if (got_one)
+ numfds++;
+ }
+ ret = numfds;
+ }
+
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_self.c b/lib/libkse/thread/thr_self.c
new file mode 100644
index 0000000..81ec427
--- /dev/null
+++ b/lib/libkse/thread/thr_self.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+pthread_t
+pthread_self(void)
+{
+ /* Return the running thread pointer: */
+ return (_thread_run);
+}
+#endif
diff --git a/lib/libkse/thread/thr_seterrno.c b/lib/libkse/thread/thr_seterrno.c
new file mode 100644
index 0000000..1934aac
--- /dev/null
+++ b/lib/libkse/thread/thr_seterrno.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/*
+ * This function needs to reference the global error variable which is
+ * normally hidden from the user.
+ */
+#ifdef errno
+#undef errno;
+#endif
+extern int errno;
+
+void
+_thread_seterrno(pthread_t thread, int error)
+{
+ /* Check for the initial thread: */
+ if (thread == _thread_initial)
+ /* The initial thread always uses the global error variable: */
+ errno = error;
+ else
+ /*
+ * Threads other than the initial thread always use the error
+ * field in the thread structureL
+ */
+ thread->error = error;
+}
+#endif
diff --git a/lib/libkse/thread/thr_setprio.c b/lib/libkse/thread/thr_setprio.c
new file mode 100644
index 0000000..5f7b44a
--- /dev/null
+++ b/lib/libkse/thread/thr_setprio.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_setprio(pthread_t pthread, int prio)
+{
+ int ret, policy;
+ struct sched_param param;
+
+ if ((ret = pthread_getschedparam(pthread, &policy, &param)) == 0) {
+ param.sched_priority = prio;
+ ret = pthread_setschedparam(pthread, policy, &param);
+ }
+
+ /* Return the error status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_setschedparam.c b/lib/libkse/thread/thr_setschedparam.c
new file mode 100644
index 0000000..57e24e8
--- /dev/null
+++ b/lib/libkse/thread/thr_setschedparam.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <sys/param.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_setschedparam(pthread_t pthread, int policy,
+ const struct sched_param *param)
+{
+ int old_prio, in_readyq = 0, ret = 0;
+
+ if ((param == NULL) || (param->sched_priority < PTHREAD_MIN_PRIORITY) ||
+ (param->sched_priority > PTHREAD_MAX_PRIORITY) ||
+ (policy < SCHED_FIFO) || (policy > SCHED_RR))
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+
+ /* Find the thread in the list of active threads: */
+ else if ((ret = _find_thread(pthread)) == 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ if (param->sched_priority != pthread->base_priority) {
+ /*
+ * Remove the thread from its current priority
+ * queue before any adjustments are made to its
+ * active priority:
+ */
+ if ((pthread->flags & PTHREAD_FLAGS_IN_PRIOQ) != 0) {
+ in_readyq = 1;
+ old_prio = pthread->active_priority;
+ PTHREAD_PRIOQ_REMOVE(pthread);
+ }
+
+ /* Set the thread base priority: */
+ pthread->base_priority = param->sched_priority;
+
+ /* Recalculate the active priority: */
+ pthread->active_priority = MAX(pthread->base_priority,
+ pthread->inherited_priority);
+
+ if (in_readyq) {
+ if ((pthread->priority_mutex_count > 0) &&
+ (old_prio > pthread->active_priority)) {
+ /*
+ * POSIX states that if the priority is
+ * being lowered, the thread must be
+ * inserted at the head of the queue for
+ * its priority if it owns any priority
+ * protection or inheritence mutexes.
+ */
+ PTHREAD_PRIOQ_INSERT_HEAD(pthread);
+ }
+ else
+ PTHREAD_PRIOQ_INSERT_TAIL(pthread);
+ }
+
+ /*
+ * Check for any mutex priority adjustments. This
+ * includes checking for a priority mutex on which
+ * this thread is waiting.
+ */
+ _mutex_notify_priochange(pthread);
+ }
+
+ /* Set the scheduling policy: */
+ pthread->attr.sched_policy = policy;
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_sig.c b/lib/libkse/thread/thr_sig.c
new file mode 100644
index 0000000..b744659
--- /dev/null
+++ b/lib/libkse/thread/thr_sig.c
@@ -0,0 +1,584 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Prototypes: */
+static void _thread_sig_check_state(pthread_t pthread, int sig);
+
+/* Static variables: */
+static spinlock_t signal_lock = _SPINLOCK_INITIALIZER;
+static unsigned int pending_sigs[NSIG];
+static unsigned int handled_sigs[NSIG];
+static int volatile check_pending = 0;
+
+/* Initialize signal handling facility: */
+void
+_thread_sig_init(void)
+{
+ int i;
+
+ /* Clear pending and handled signal counts: */
+ for (i = 1; i < NSIG; i++) {
+ pending_sigs[i - 1] = 0;
+ handled_sigs[i - 1] = 0;
+ }
+
+ /* Clear the lock: */
+ signal_lock.access_lock = 0;
+
+ /* Clear the process pending signals: */
+ sigemptyset(&_process_sigpending);
+}
+
+void
+_thread_sig_handler(int sig, int code, ucontext_t * scp)
+{
+ pthread_t pthread;
+ int i;
+ char c;
+
+ /* Check if an interval timer signal: */
+ if (sig == _SCHED_SIGNAL) {
+ if (_thread_kern_in_sched != 0) {
+ /*
+ * The scheduler is already running; ignore this
+ * signal.
+ */
+ }
+ /*
+ * Check if the scheduler interrupt has come when
+ * the currently running thread has deferred thread
+ * signals.
+ */
+ else if (_thread_run->sig_defer_count > 0)
+ _thread_run->yield_on_sig_undefer = 1;
+
+ else {
+ /*
+ * Schedule the next thread. This function is not
+ * expected to return because it will do a longjmp
+ * instead.
+ */
+ _thread_kern_sched(scp);
+
+ /*
+ * This point should not be reached, so abort the
+ * process:
+ */
+ PANIC("Returned to signal function from scheduler");
+ }
+ }
+ /*
+ * Check if the kernel has been interrupted while the scheduler
+ * is accessing the scheduling queues or if there is a currently
+ * running thread that has deferred signals.
+ */
+ else if ((_queue_signals != 0) || ((_thread_kern_in_sched == 0) &&
+ (_thread_run->sig_defer_count > 0))) {
+ /* Cast the signal number to a character variable: */
+ c = sig;
+
+ /*
+ * Write the signal number to the kernel pipe so that it will
+ * be ready to read when this signal handler returns.
+ */
+ _thread_sys_write(_thread_kern_pipe[1], &c, 1);
+
+ /* Indicate that there are queued signals in the pipe. */
+ _sigq_check_reqd = 1;
+ }
+ else {
+ if (_atomic_lock(&signal_lock.access_lock)) {
+ /* There is another signal handler running: */
+ pending_sigs[sig - 1]++;
+ check_pending = 1;
+ }
+ else {
+ /* It's safe to handle the signal now. */
+ pthread = _thread_sig_handle(sig, scp);
+
+ /* Reset the pending and handled count back to 0: */
+ pending_sigs[sig - 1] = 0;
+ handled_sigs[sig - 1] = 0;
+
+ if (pthread == NULL)
+ signal_lock.access_lock = 0;
+ else {
+ sigaddset(&pthread->sigmask, sig);
+ signal_lock.access_lock = 0;
+ _thread_sig_deliver(pthread, sig);
+ sigdelset(&pthread->sigmask, sig);
+ }
+ }
+
+ /* Enter a loop to process pending signals: */
+ while ((check_pending != 0) &&
+ (_atomic_lock(&signal_lock.access_lock) == 0)) {
+ check_pending = 0;
+ for (i = 1; i < NSIG; i++) {
+ if (pending_sigs[i - 1] > handled_sigs[i - 1]) {
+ pending_sigs[i - 1] = handled_sigs[i - 1];
+ pthread = _thread_sig_handle(i, scp);
+ if (pthread != NULL) {
+ sigaddset(&pthread->sigmask, i);
+ signal_lock.access_lock = 0;
+ _thread_sig_deliver(pthread, i);
+ sigdelset(&pthread->sigmask, i);
+ if (_atomic_lock(&signal_lock.access_lock)) {
+ check_pending = 1;
+ return;
+ }
+ }
+ }
+ }
+ signal_lock.access_lock = 0;
+ }
+ }
+}
+
+pthread_t
+_thread_sig_handle(int sig, ucontext_t * scp)
+{
+ int i;
+ pthread_t pthread, pthread_next;
+ pthread_t suspended_thread, signaled_thread;
+
+ /* Check if the signal requires a dump of thread information: */
+ if (sig == SIGINFO)
+ /* Dump thread information to file: */
+ _thread_dump_info();
+
+ /* Check if an interval timer signal: */
+ else if (sig == _SCHED_SIGNAL) {
+ /*
+ * This shouldn't ever occur (should this panic?).
+ */
+ } else {
+ /* Check if a child has terminated: */
+ if (sig == SIGCHLD) {
+ /*
+ * Go through the file list and set all files
+ * to non-blocking again in case the child
+ * set some of them to block. Sigh.
+ */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /* Check if this file is used: */
+ if (_thread_fd_table[i] != NULL) {
+ /*
+ * Set the file descriptor to
+ * non-blocking:
+ */
+ _thread_sys_fcntl(i, F_SETFL,
+ _thread_fd_table[i]->flags |
+ O_NONBLOCK);
+ }
+ }
+ /*
+ * Enter a loop to wake up all threads waiting
+ * for a process to complete:
+ */
+ for (pthread = TAILQ_FIRST(&_waitingq);
+ pthread != NULL; pthread = pthread_next) {
+ /*
+ * Grab the next thread before possibly
+ * destroying the link entry:
+ */
+ pthread_next = TAILQ_NEXT(pthread, pqe);
+
+ /*
+ * If this thread is waiting for a child
+ * process to complete, wake it up:
+ */
+ if (pthread->state == PS_WAIT_WAIT) {
+ /* Make the thread runnable: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ }
+ }
+ }
+
+ /*
+ * POSIX says that pending SIGCONT signals are
+ * discarded when one of these signals occurs.
+ */
+ if (sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU) {
+ /*
+ * Enter a loop to discard pending SIGCONT
+ * signals:
+ */
+ TAILQ_FOREACH(pthread, &_thread_list, tle) {
+ sigdelset(&pthread->sigpend,SIGCONT);
+ }
+ }
+
+ /*
+ * Enter a loop to look for threads that have the
+ * signal unmasked. POSIX specifies that a thread
+ * in a sigwait will get the signal over any other
+ * threads. Second preference will be threads in
+ * in a sigsuspend. If none of the above, then the
+ * signal is delivered to the first thread we find.
+ */
+ suspended_thread = NULL;
+ signaled_thread = NULL;
+ for (pthread = TAILQ_FIRST(&_waitingq);
+ pthread != NULL; pthread = pthread_next) {
+ /*
+ * Grab the next thread before possibly destroying
+ * the link entry.
+ */
+ pthread_next = TAILQ_NEXT(pthread, pqe);
+
+ if ((pthread->state == PS_SIGWAIT) &&
+ sigismember(pthread->data.sigwait, sig)) {
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+
+ /*
+ * POSIX doesn't doesn't specify which thread
+ * will get the signal if there are multiple
+ * waiters, so we give it to the first thread
+ * we find.
+ *
+ * Do not attempt to deliver this signal
+ * to other threads.
+ */
+ return (NULL);
+ }
+ else if (!sigismember(&pthread->sigmask, sig)) {
+ if (pthread->state == PS_SIGSUSPEND) {
+ if (suspended_thread == NULL)
+ suspended_thread = pthread;
+ } else if (signaled_thread == NULL)
+ signaled_thread = pthread;
+ }
+ }
+
+ /*
+ * If we didn't find a thread in the waiting queue,
+ * check the all threads queue:
+ */
+ if (suspended_thread == NULL && signaled_thread == NULL) {
+ /*
+ * Enter a loop to look for other threads capable
+ * of receiving the signal:
+ */
+ TAILQ_FOREACH(pthread, &_thread_list, tle) {
+ if (!sigismember(&pthread->sigmask, sig)) {
+ signaled_thread = pthread;
+ break;
+ }
+ }
+ }
+
+ /* Check if the signal is not being ignored: */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) {
+ if (suspended_thread == NULL &&
+ signaled_thread == NULL)
+ /*
+ * Add it to the set of signals pending
+ * on the process:
+ */
+ sigaddset(&_process_sigpending, sig);
+ else {
+ /*
+ * We only deliver the signal to one thread;
+ * give preference to the suspended thread:
+ */
+ if (suspended_thread != NULL)
+ pthread = suspended_thread;
+ else
+ pthread = signaled_thread;
+
+ /*
+ * Perform any state changes due to signal
+ * arrival:
+ */
+ _thread_sig_check_state(pthread, sig);
+ return (pthread);
+ }
+ }
+ }
+
+ /* Returns nothing. */
+ return (NULL);
+}
+
+/* Perform thread specific actions in response to a signal: */
+static void
+_thread_sig_check_state(pthread_t pthread, int sig)
+{
+ /*
+ * Process according to thread state:
+ */
+ switch (pthread->state) {
+ /*
+ * States which do not change when a signal is trapped:
+ */
+ case PS_COND_WAIT:
+ case PS_DEAD:
+ case PS_DEADLOCK:
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ case PS_JOIN:
+ case PS_MUTEX_WAIT:
+ case PS_RUNNING:
+ case PS_STATE_MAX:
+ case PS_SIGTHREAD:
+ case PS_SPINBLOCK:
+ case PS_SUSPENDED:
+ /* Increment the pending signal count. */
+ sigaddset(&pthread->sigpend,sig);
+ break;
+
+ case PS_SIGWAIT:
+ /* Wake up the thread if the signal is blocked. */
+ if (sigismember(pthread->data.sigwait, sig)) {
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ } else
+ /* Increment the pending signal count. */
+ sigaddset(&pthread->sigpend,sig);
+ break;
+
+
+ /*
+ * The wait state is a special case due to the handling of
+ * SIGCHLD signals.
+ */
+ case PS_WAIT_WAIT:
+ /*
+ * Check for signals other than the death of a child
+ * process:
+ */
+ if (sig != SIGCHLD)
+ /* Flag the operation as interrupted: */
+ pthread->interrupted = 1;
+
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ break;
+
+ /*
+ * States that are interrupted by the occurrence of a signal
+ * other than the scheduling alarm:
+ */
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ case PS_POLL_WAIT:
+ case PS_SLEEP_WAIT:
+ case PS_SELECT_WAIT:
+ if ((_thread_sigact[sig - 1].sa_flags & SA_RESTART) == 0) {
+ /* Flag the operation as interrupted: */
+ pthread->interrupted = 1;
+
+ if (pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ PTHREAD_WORKQ_REMOVE(pthread);
+
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ }
+ break;
+
+ case PS_SIGSUSPEND:
+ /*
+ * Only wake up the thread if there is a handler installed
+ * for the signal.
+ */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_DFL) {
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ }
+ break;
+ }
+}
+
+/* Send a signal to a specific thread (ala pthread_kill): */
+void
+_thread_sig_send(pthread_t pthread, int sig)
+{
+ /*
+ * Check that the signal is not being ignored:
+ */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) {
+ if (pthread->state == PS_SIGWAIT &&
+ sigismember(pthread->data.sigwait, sig)) {
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ } else if (pthread->state != PS_SIGWAIT &&
+ !sigismember(&pthread->sigmask, sig)) {
+ /* Perform any state changes due to signal arrival: */
+ _thread_sig_check_state(pthread, sig);
+
+ /* Call the installed signal handler: */
+ _thread_sig_deliver(pthread, sig);
+ }
+ else {
+ /* Increment the pending signal count. */
+ sigaddset(&pthread->sigpend,sig);
+ }
+ }
+}
+
+/* Dispatch pending signals to the running thread: */
+void
+_dispatch_signals()
+{
+ sigset_t sigset, mask;
+ int i;
+
+ /*
+ * Check if there are pending signals for the running
+ * thread or process that aren't blocked:
+ */
+ sigset = _thread_run->sigpend;
+ SIGSETOR(sigset, _process_sigpending);
+ SIGSETNAND(sigset, _thread_run->sigmask);
+ if (SIGNOTEMPTY(sigset)) {
+ /*
+ * Enter a loop to calculate deliverable pending signals
+ * before actually delivering them. The pending signals
+ * must be removed from the pending signal sets before
+ * calling the signal handler because the handler may
+ * call library routines that again check for and deliver
+ * pending signals.
+ */
+ for (i = 1; i < NSIG; i++) {
+ /*
+ * Check that a custom handler is installed
+ * and if the signal is not blocked:
+ */
+ if (_thread_sigact[i - 1].sa_handler != SIG_DFL &&
+ _thread_sigact[i - 1].sa_handler != SIG_IGN &&
+ sigismember(&sigset, i)) {
+ if (sigismember(&_thread_run->sigpend,i))
+ /* Clear the thread pending signal: */
+ sigdelset(&_thread_run->sigpend,i);
+ else
+ /* Clear the process pending signal: */
+ sigdelset(&_process_sigpending,i);
+ }
+ else
+ /* Remove the signal if it can't be handled: */
+ sigdelset(&sigset, i);
+ }
+
+ /* Now deliver the signals: */
+ for (i = 1; i < NSIG; i++) {
+ if (sigismember(&sigset, i))
+ /* Deliver the signal to the running thread: */
+ _thread_sig_deliver(_thread_run, i);
+ }
+ }
+}
+
+/* Deliver a signal to a thread: */
+void
+_thread_sig_deliver(pthread_t pthread, int sig)
+{
+ sigset_t mask;
+ pthread_t pthread_saved;
+
+ /*
+ * Check that a custom handler is installed
+ * and if the signal is not blocked:
+ */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_DFL &&
+ _thread_sigact[sig - 1].sa_handler != SIG_IGN) {
+ /* Save the current thread: */
+ pthread_saved = _thread_run;
+
+ /* Save the threads signal mask: */
+ mask = pthread->sigmask;
+
+ /*
+ * Add the current signal and signal handler
+ * mask to the threads current signal mask:
+ */
+ SIGSETOR(pthread->sigmask, _thread_sigact[sig - 1].sa_mask);
+ sigaddset(&pthread->sigmask, sig);
+
+ /* Current thread inside critical region? */
+ if (_thread_run->sig_defer_count > 0)
+ pthread->sig_defer_count++;
+
+ _thread_run = pthread;
+
+ /*
+ * Dispatch the signal via the custom signal
+ * handler:
+ */
+ (*(_thread_sigact[sig - 1].sa_handler))(sig);
+
+ _thread_run = pthread_saved;
+
+ /* Current thread inside critical region? */
+ if (_thread_run->sig_defer_count > 0)
+ pthread->sig_defer_count--;
+
+ /* Restore the threads signal mask: */
+ pthread->sigmask = mask;
+ }
+}
+#endif
diff --git a/lib/libkse/thread/thr_sigaction.c b/lib/libkse/thread/thr_sigaction.c
new file mode 100644
index 0000000..7fa8ebf
--- /dev/null
+++ b/lib/libkse/thread/thr_sigaction.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigaction(int sig, const struct sigaction * act, struct sigaction * oact)
+{
+ int ret = 0;
+ struct sigaction gact;
+
+ /* Check if the signal number is out of range: */
+ if (sig < 1 || sig > NSIG) {
+ /* Return an invalid argument: */
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ /*
+ * Check if the existing signal action structure contents are
+ * to be returned:
+ */
+ if (oact != NULL) {
+ /* Return the existing signal action contents: */
+ oact->sa_handler = _thread_sigact[sig - 1].sa_handler;
+ oact->sa_mask = _thread_sigact[sig - 1].sa_mask;
+ oact->sa_flags = _thread_sigact[sig - 1].sa_flags;
+ }
+
+ /* Check if a signal action was supplied: */
+ if (act != NULL) {
+ /* Set the new signal handler: */
+ _thread_sigact[sig - 1].sa_mask = act->sa_mask;
+ _thread_sigact[sig - 1].sa_flags = act->sa_flags;
+ _thread_sigact[sig - 1].sa_handler = act->sa_handler;
+ }
+
+ /*
+ * Check if the kernel needs to be advised of a change
+ * in signal action:
+ */
+ if (act != NULL && sig != _SCHED_SIGNAL && sig != SIGCHLD &&
+ sig != SIGINFO) {
+ /* Initialise the global signal action structure: */
+ gact.sa_mask = act->sa_mask;
+ gact.sa_flags = 0;
+
+ /* Ensure the scheduling signal is masked: */
+ sigaddset(&gact.sa_mask, _SCHED_SIGNAL);
+
+ /*
+ * Check if the signal handler is being set to
+ * the default or ignore handlers:
+ */
+ if (act->sa_handler == SIG_DFL ||
+ act->sa_handler == SIG_IGN)
+ /* Specify the built in handler: */
+ gact.sa_handler = act->sa_handler;
+ else
+ /*
+ * Specify the thread kernel signal
+ * handler:
+ */
+ gact.sa_handler = (void (*) ()) _thread_sig_handler;
+
+ /* Change the signal action in the kernel: */
+ if (_thread_sys_sigaction(sig,&gact,NULL) != 0)
+ ret = -1;
+ }
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_sigmask.c b/lib/libkse/thread/thr_sigmask.c
new file mode 100644
index 0000000..b880d9c
--- /dev/null
+++ b/lib/libkse/thread/thr_sigmask.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <errno.h>
+#include <signal.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
+{
+ int ret = 0;
+
+ /* Check if the existing signal process mask is to be returned: */
+ if (oset != NULL) {
+ /* Return the current mask: */
+ *oset = _thread_run->sigmask;
+ }
+ /* Check if a new signal set was provided by the caller: */
+ if (set != NULL) {
+ /* Process according to what to do: */
+ switch (how) {
+ /* Block signals: */
+ case SIG_BLOCK:
+ /* Add signals to the existing mask: */
+ SIGSETOR(_thread_run->sigmask, *set);
+ break;
+
+ /* Unblock signals: */
+ case SIG_UNBLOCK:
+ /* Clear signals from the existing mask: */
+ SIGSETNAND(_thread_run->sigmask, *set);
+ break;
+
+ /* Set the signal process mask: */
+ case SIG_SETMASK:
+ /* Set the new mask: */
+ _thread_run->sigmask = *set;
+ break;
+
+ /* Trap invalid actions: */
+ default:
+ /* Return an invalid argument: */
+ errno = EINVAL;
+ ret = -1;
+ break;
+ }
+
+ /*
+ * Dispatch signals to the running thread that are pending
+ * and now unblocked:
+ */
+ _dispatch_signals();
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_sigpending.c b/lib/libkse/thread/thr_sigpending.c
new file mode 100644
index 0000000..2d61e21
--- /dev/null
+++ b/lib/libkse/thread/thr_sigpending.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigpending(sigset_t * set)
+{
+ int ret = 0;
+
+ /* Check for a null signal set pointer: */
+ if (set == NULL) {
+ /* Return an invalid argument: */
+ ret = EINVAL;
+ }
+ else {
+ *set = _thread_run->sigpend;
+ }
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_sigprocmask.c b/lib/libkse/thread/thr_sigprocmask.c
new file mode 100644
index 0000000..592a61e
--- /dev/null
+++ b/lib/libkse/thread/thr_sigprocmask.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <signal.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigprocmask(int how, const sigset_t * set, sigset_t * oset)
+{
+ int ret = 0;
+
+ /* Check if the existing signal process mask is to be returned: */
+ if (oset != NULL) {
+ /* Return the current mask: */
+ *oset = _thread_run->sigmask;
+ }
+ /* Check if a new signal set was provided by the caller: */
+ if (set != NULL) {
+ /* Process according to what to do: */
+ switch (how) {
+ /* Block signals: */
+ case SIG_BLOCK:
+ /* Add signals to the existing mask: */
+ SIGSETOR(_thread_run->sigmask, *set);
+ break;
+
+ /* Unblock signals: */
+ case SIG_UNBLOCK:
+ /* Clear signals from the existing mask: */
+ SIGSETNAND(_thread_run->sigmask, *set);
+ break;
+
+ /* Set the signal process mask: */
+ case SIG_SETMASK:
+ /* Set the new mask: */
+ _thread_run->sigmask = *set;
+ break;
+
+ /* Trap invalid actions: */
+ default:
+ /* Return an invalid argument: */
+ errno = EINVAL;
+ ret = -1;
+ break;
+ }
+
+ /*
+ * Dispatch signals to the running thread that are pending
+ * and now unblocked:
+ */
+ _dispatch_signals();
+ }
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_sigsuspend.c b/lib/libkse/thread/thr_sigsuspend.c
new file mode 100644
index 0000000..ac06ff7
--- /dev/null
+++ b/lib/libkse/thread/thr_sigsuspend.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigsuspend(const sigset_t * set)
+{
+ int ret = -1;
+ sigset_t oset;
+
+ /* Check if a new signal set was provided by the caller: */
+ if (set != NULL) {
+ /* Save the current signal mask: */
+ oset = _thread_run->sigmask;
+
+ /* Change the caller's mask: */
+ _thread_run->sigmask = *set;
+
+ /* Wait for a signal: */
+ _thread_kern_sched_state(PS_SIGSUSPEND, __FILE__, __LINE__);
+
+ /* Always return an interrupted error: */
+ errno = EINTR;
+
+ /* Restore the signal mask: */
+ _thread_run->sigmask = oset;
+ } else {
+ /* Return an invalid argument error: */
+ errno = EINVAL;
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_sigwait.c b/lib/libkse/thread/thr_sigwait.c
new file mode 100644
index 0000000..faa227e
--- /dev/null
+++ b/lib/libkse/thread/thr_sigwait.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <sys/param.h>
+#include <sys/signalvar.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigwait(const sigset_t * set, int *sig)
+{
+ int ret = 0;
+ int i;
+ sigset_t tempset, waitset;
+ struct sigaction act;
+
+ _thread_enter_cancellation_point();
+ /*
+ * Specify the thread kernel signal handler.
+ */
+ act.sa_handler = (void (*) ()) _thread_sig_handler;
+ act.sa_flags = SA_RESTART;
+ act.sa_mask = *set;
+
+ /* Ensure the scheduling signal is masked: */
+ sigaddset(&act.sa_mask, _SCHED_SIGNAL);
+
+ /*
+ * Initialize the set of signals that will be waited on:
+ */
+ waitset = *set;
+
+ /* These signals can't be waited on. */
+ sigdelset(&waitset, SIGKILL);
+ sigdelset(&waitset, SIGSTOP);
+ sigdelset(&waitset, _SCHED_SIGNAL);
+ sigdelset(&waitset, SIGCHLD);
+ sigdelset(&waitset, SIGINFO);
+
+ /* Check to see if a pending signal is in the wait mask. */
+ tempset = _thread_run->sigpend;
+ SIGSETOR(tempset, _process_sigpending);
+ SIGSETAND(tempset, waitset);
+ if (SIGNOTEMPTY(tempset)) {
+ /* Enter a loop to find a pending signal: */
+ for (i = 1; i < NSIG; i++) {
+ if (sigismember (&tempset, i))
+ break;
+ }
+
+ /* Clear the pending signal: */
+ if (sigismember(&_thread_run->sigpend,i))
+ sigdelset(&_thread_run->sigpend,i);
+ else
+ sigdelset(&_process_sigpending,i);
+
+ /* Return the signal number to the caller: */
+ *sig = i;
+
+ _thread_leave_cancellation_point();
+ return (0);
+ }
+
+ /*
+ * Enter a loop to find the signals that are SIG_DFL. For
+ * these signals we must install a dummy signal handler in
+ * order for the kernel to pass them in to us. POSIX says
+ * that the _application_ must explicitly install a dummy
+ * handler for signals that are SIG_IGN in order to sigwait
+ * on them. Note that SIG_IGN signals are left in the
+ * mask because a subsequent sigaction could enable an
+ * ignored signal.
+ */
+ for (i = 1; i < NSIG; i++) {
+ if (sigismember(&waitset, i) &&
+ (_thread_sigact[i - 1].sa_handler == SIG_DFL)) {
+ if (_thread_sys_sigaction(i,&act,NULL) != 0)
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ /*
+ * Save the wait signal mask. The wait signal
+ * mask is independent of the threads signal mask
+ * and requires separate storage.
+ */
+ _thread_run->data.sigwait = &waitset;
+
+ /* Wait for a signal: */
+ _thread_kern_sched_state(PS_SIGWAIT, __FILE__, __LINE__);
+
+ /* Return the signal number to the caller: */
+ *sig = _thread_run->signo;
+
+ /*
+ * Probably unnecessary, but since it's in a union struct
+ * we don't know how it could be used in the future.
+ */
+ _thread_run->data.sigwait = NULL;
+ }
+
+ /* Restore the sigactions: */
+ act.sa_handler = SIG_DFL;
+ for (i = 1; i < NSIG; i++) {
+ if (sigismember(&waitset, i) &&
+ (_thread_sigact[i - 1].sa_handler == SIG_DFL)) {
+ if (_thread_sys_sigaction(i,&act,NULL) != 0)
+ ret = -1;
+ }
+ }
+
+ _thread_leave_cancellation_point();
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_single_np.c b/lib/libkse/thread/thr_single_np.c
new file mode 100644
index 0000000..d6ecb48
--- /dev/null
+++ b/lib/libkse/thread/thr_single_np.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_single_np()
+{
+ /* Enter single-threaded (non-POSIX) scheduling mode: */
+ _thread_single = _thread_run;
+ return(0);
+}
+#endif
diff --git a/lib/libkse/thread/thr_spec.c b/lib/libkse/thread/thr_spec.c
new file mode 100644
index 0000000..f1e9f5c
--- /dev/null
+++ b/lib/libkse/thread/thr_spec.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Static variables: */
+static struct pthread_key key_table[PTHREAD_KEYS_MAX];
+
+int
+pthread_key_create(pthread_key_t * key, void (*destructor) (void *))
+{
+ for ((*key) = 0; (*key) < PTHREAD_KEYS_MAX; (*key)++) {
+ /* Lock the key table entry: */
+ _SPINLOCK(&key_table[*key].lock);
+
+ if (key_table[(*key)].allocated == 0) {
+ key_table[(*key)].allocated = 1;
+ key_table[(*key)].destructor = destructor;
+
+ /* Unlock the key table entry: */
+ _SPINUNLOCK(&key_table[*key].lock);
+ return (0);
+ }
+
+ /* Unlock the key table entry: */
+ _SPINUNLOCK(&key_table[*key].lock);
+ }
+ return (EAGAIN);
+}
+
+int
+pthread_key_delete(pthread_key_t key)
+{
+ int ret = 0;
+
+ if (key < PTHREAD_KEYS_MAX) {
+ /* Lock the key table entry: */
+ _SPINLOCK(&key_table[key].lock);
+
+ if (key_table[key].allocated)
+ key_table[key].allocated = 0;
+ else
+ ret = EINVAL;
+
+ /* Unlock the key table entry: */
+ _SPINUNLOCK(&key_table[key].lock);
+ } else
+ ret = EINVAL;
+ return (ret);
+}
+
+void
+_thread_cleanupspecific(void)
+{
+ void *data;
+ int key;
+ int itr;
+ void (*destructor)( void *);
+
+ for (itr = 0; itr < PTHREAD_DESTRUCTOR_ITERATIONS; itr++) {
+ for (key = 0; key < PTHREAD_KEYS_MAX; key++) {
+ if (_thread_run->specific_data_count) {
+ /* Lock the key table entry: */
+ _SPINLOCK(&key_table[key].lock);
+ destructor = NULL;
+
+ if (key_table[key].allocated) {
+ if (_thread_run->specific_data[key]) {
+ data = (void *) _thread_run->specific_data[key];
+ _thread_run->specific_data[key] = NULL;
+ _thread_run->specific_data_count--;
+ destructor = key_table[key].destructor;
+ }
+ }
+
+ /* Unlock the key table entry: */
+ _SPINUNLOCK(&key_table[key].lock);
+
+ /*
+ * If there is a destructore, call it
+ * with the key table entry unlocked:
+ */
+ if (destructor)
+ destructor(data);
+ } else {
+ free(_thread_run->specific_data);
+ _thread_run->specific_data = NULL;
+ return;
+ }
+ }
+ }
+ free(_thread_run->specific_data);
+ _thread_run->specific_data = NULL;
+}
+
+static inline const void **
+pthread_key_allocate_data(void)
+{
+ const void **new_data;
+ if ((new_data = (const void **) malloc(sizeof(void *) * PTHREAD_KEYS_MAX)) != NULL) {
+ memset((void *) new_data, 0, sizeof(void *) * PTHREAD_KEYS_MAX);
+ }
+ return (new_data);
+}
+
+int
+pthread_setspecific(pthread_key_t key, const void *value)
+{
+ pthread_t pthread;
+ int ret = 0;
+
+ /* Point to the running thread: */
+ pthread = _thread_run;
+
+ if ((pthread->specific_data) ||
+ (pthread->specific_data = pthread_key_allocate_data())) {
+ if (key < PTHREAD_KEYS_MAX) {
+ if (key_table[key].allocated) {
+ if (pthread->specific_data[key] == NULL) {
+ if (value != NULL)
+ pthread->specific_data_count++;
+ } else {
+ if (value == NULL)
+ pthread->specific_data_count--;
+ }
+ pthread->specific_data[key] = value;
+ ret = 0;
+ } else
+ ret = EINVAL;
+ } else
+ ret = EINVAL;
+ } else
+ ret = ENOMEM;
+ return (ret);
+}
+
+void *
+pthread_getspecific(pthread_key_t key)
+{
+ pthread_t pthread;
+ void *data;
+
+ /* Point to the running thread: */
+ pthread = _thread_run;
+
+ /* Check if there is specific data: */
+ if (pthread->specific_data != NULL && key < PTHREAD_KEYS_MAX) {
+ /* Check if this key has been used before: */
+ if (key_table[key].allocated) {
+ /* Return the value: */
+ data = (void *) pthread->specific_data[key];
+ } else {
+ /*
+ * This key has not been used before, so return NULL
+ * instead:
+ */
+ data = NULL;
+ }
+ } else
+ /* No specific data has been created, so just return NULL: */
+ data = NULL;
+ return (data);
+}
+#endif
diff --git a/lib/libkse/thread/thr_spinlock.c b/lib/libkse/thread/thr_spinlock.c
new file mode 100644
index 0000000..4e94ffc
--- /dev/null
+++ b/lib/libkse/thread/thr_spinlock.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <sched.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+#include "pthread_private.h"
+
+extern char *__progname;
+
+/*
+ * Lock a location for the running thread. Yield to allow other
+ * threads to run if this thread is blocked because the lock is
+ * not available. Note that this function does not sleep. It
+ * assumes that the lock will be available very soon.
+ */
+void
+_spinlock(spinlock_t *lck)
+{
+ /*
+ * Try to grab the lock and loop if another thread grabs
+ * it before we do.
+ */
+ while(_atomic_lock(&lck->access_lock)) {
+ /* Block the thread until the lock. */
+ _thread_run->data.spinlock = lck;
+ _thread_kern_sched_state(PS_SPINBLOCK, __FILE__, __LINE__);
+ }
+
+ /* The running thread now owns the lock: */
+ lck->lock_owner = (long) _thread_run;
+}
+
+/*
+ * Lock a location for the running thread. Yield to allow other
+ * threads to run if this thread is blocked because the lock is
+ * not available. Note that this function does not sleep. It
+ * assumes that the lock will be available very soon.
+ *
+ * This function checks if the running thread has already locked the
+ * location, warns if this occurs and creates a thread dump before
+ * returning.
+ */
+void
+_spinlock_debug(spinlock_t *lck, char *fname, int lineno)
+{
+ int cnt = 0;
+
+ /*
+ * Try to grab the lock and loop if another thread grabs
+ * it before we do.
+ */
+ while(_atomic_lock(&lck->access_lock)) {
+ cnt++;
+ if (cnt > 100) {
+ char str[256];
+ snprintf(str, sizeof(str), "%s - Warning: Thread %p attempted to lock %p from %s (%d) was left locked from %s (%d)\n", __progname, _thread_run, lck, fname, lineno, lck->fname, lck->lineno);
+ _thread_sys_write(2,str,strlen(str));
+ sleep(1);
+ cnt = 0;
+ }
+
+ /* Block the thread until the lock. */
+ _thread_run->data.spinlock = lck;
+ _thread_kern_sched_state(PS_SPINBLOCK, fname, lineno);
+ }
+
+ /* The running thread now owns the lock: */
+ lck->lock_owner = (long) _thread_run;
+ lck->fname = fname;
+ lck->lineno = lineno;
+}
diff --git a/lib/libkse/thread/thr_suspend_np.c b/lib/libkse/thread/thr_suspend_np.c
new file mode 100644
index 0000000..ea9b1f8
--- /dev/null
+++ b/lib/libkse/thread/thr_suspend_np.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Suspend a thread: */
+int
+pthread_suspend_np(pthread_t thread)
+{
+ int ret;
+
+ /* Find the thread in the list of active threads: */
+ if ((ret = _find_thread(thread)) == 0) {
+ /* The thread exists. Is it running? */
+ if (thread->state != PS_RUNNING &&
+ thread->state != PS_SUSPENDED) {
+ /* The thread operation has been interrupted */
+ _thread_seterrno(thread,EINTR);
+ thread->interrupted = 1;
+ }
+
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Suspend the thread. */
+ PTHREAD_NEW_STATE(thread,PS_SUSPENDED);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_switch_np.c b/lib/libkse/thread/thr_switch_np.c
new file mode 100644
index 0000000..9b83545
--- /dev/null
+++ b/lib/libkse/thread/thr_switch_np.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include <pthread_np.h>
+#include "pthread_private.h"
+
+
+int
+pthread_switch_add_np(pthread_switch_routine_t routine)
+{
+ int ret = 0;
+
+ if (routine == NULL)
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ else
+ /* Shouldn't need a lock to protect this assigment. */
+ _sched_switch_hook = routine;
+
+ return(ret);
+}
+
+int
+pthread_switch_delete_np(pthread_switch_routine_t routine)
+{
+ int ret = 0;
+
+ if (routine != _sched_switch_hook)
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ else
+ /* Shouldn't need a lock to protect this assigment. */
+ _sched_switch_hook = NULL;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_vfork.c b/lib/libkse/thread/thr_vfork.c
new file mode 100644
index 0000000..bbfcf00
--- /dev/null
+++ b/lib/libkse/thread/thr_vfork.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+
+int
+vfork(void)
+{
+ return (fork());
+}
+#endif
diff --git a/lib/libkse/thread/thr_wait4.c b/lib/libkse/thread/thr_wait4.c
new file mode 100644
index 0000000..4a58a70
--- /dev/null
+++ b/lib/libkse/thread/thr_wait4.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <sys/wait.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+pid_t
+wait4(pid_t pid, int *istat, int options, struct rusage * rusage)
+{
+ pid_t ret;
+
+ _thread_enter_cancellation_point();
+ _thread_kern_sig_defer();
+
+ /* Perform a non-blocking wait4 syscall: */
+ while ((ret = _thread_sys_wait4(pid, istat, options | WNOHANG, rusage)) == 0 && (options & WNOHANG) == 0) {
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ /* Schedule the next thread while this one waits: */
+ _thread_kern_sched_state(PS_WAIT_WAIT, __FILE__, __LINE__);
+
+ /* Check if this call was interrupted by a signal: */
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ }
+
+ _thread_kern_sig_undefer();
+ _thread_leave_cancellation_point();
+
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_write.c b/lib/libkse/thread/thr_write.c
new file mode 100644
index 0000000..40c4cc5
--- /dev/null
+++ b/lib/libkse/thread/thr_write.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+write(int fd, const void *buf, size_t nbytes)
+{
+ int blocking;
+ int type;
+ ssize_t n;
+ ssize_t num = 0;
+ ssize_t ret;
+
+ _thread_enter_cancellation_point();
+ /* POSIX says to do just this: */
+ if (nbytes == 0) {
+ _thread_leave_cancellation_point();
+ return (0);
+ }
+
+ /* Lock the file descriptor for write: */
+ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ /* Get the read/write mode type: */
+ type = _thread_fd_table[fd]->flags & O_ACCMODE;
+
+ /* Check if the file is not open for write: */
+ if (type != O_WRONLY && type != O_RDWR) {
+ /* File is not open for write: */
+ errno = EBADF;
+ _FD_UNLOCK(fd, FD_WRITE);
+ _thread_leave_cancellation_point();
+ return (-1);
+ }
+
+ /* Check if file operations are to block */
+ blocking = ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0);
+
+ /*
+ * Loop while no error occurs and until the expected number
+ * of bytes are written if performing a blocking write:
+ */
+ while (ret == 0) {
+ /* Perform a non-blocking write syscall: */
+ n = _thread_sys_write(fd, buf + num, nbytes - num);
+
+ /* Check if one or more bytes were written: */
+ if (n > 0)
+ /*
+ * Keep a count of the number of bytes
+ * written:
+ */
+ num += n;
+
+ /*
+ * If performing a blocking write, check if the
+ * write would have blocked or if some bytes
+ * were written but there are still more to
+ * write:
+ */
+ if (blocking && ((n < 0 && (errno == EWOULDBLOCK ||
+ errno == EAGAIN)) || (n >= 0 && num < nbytes))) {
+ _thread_run->data.fd.fd = fd;
+ _thread_kern_set_timeout(NULL);
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDW_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
+ /* Return an error: */
+ ret = -1;
+ }
+
+ /*
+ * If performing a non-blocking write or if an
+ * error occurred, just return whatever the write
+ * syscall did:
+ */
+ } else if (!blocking || n < 0) {
+ /* A non-blocking call might return zero: */
+ ret = n;
+ break;
+
+ /* Check if the write has completed: */
+ } else if (num >= nbytes)
+ /* Return the number of bytes written: */
+ ret = num;
+ }
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_writev.c b/lib/libkse/thread/thr_writev.c
new file mode 100644
index 0000000..375f599
--- /dev/null
+++ b/lib/libkse/thread/thr_writev.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+writev(int fd, const struct iovec * iov, int iovcnt)
+{
+ int blocking;
+ int idx = 0;
+ int type;
+ ssize_t cnt;
+ ssize_t n;
+ ssize_t num = 0;
+ ssize_t ret;
+ struct iovec liov[20];
+ struct iovec *p_iov = liov;
+
+ /* Check if the array size exceeds to compiled in size: */
+ if (iovcnt > (sizeof(liov) / sizeof(struct iovec))) {
+ /* Allocate memory for the local array: */
+ if ((p_iov = (struct iovec *)
+ malloc(iovcnt * sizeof(struct iovec))) == NULL) {
+ /* Insufficient memory: */
+ errno = ENOMEM;
+ return (-1);
+ }
+ }
+
+ /* Copy the caller's array so that it can be modified locally: */
+ memcpy(p_iov,iov,iovcnt * sizeof(struct iovec));
+
+ /* Lock the file descriptor for write: */
+ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ /* Get the read/write mode type: */
+ type = _thread_fd_table[fd]->flags & O_ACCMODE;
+
+ /* Check if the file is not open for write: */
+ if (type != O_WRONLY && type != O_RDWR) {
+ /* File is not open for write: */
+ errno = EBADF;
+ _FD_UNLOCK(fd, FD_WRITE);
+ return (-1);
+ }
+
+ /* Check if file operations are to block */
+ blocking = ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0);
+
+ /*
+ * Loop while no error occurs and until the expected number
+ * of bytes are written if performing a blocking write:
+ */
+ while (ret == 0) {
+ /* Perform a non-blocking write syscall: */
+ n = _thread_sys_writev(fd, &p_iov[idx], iovcnt - idx);
+
+ /* Check if one or more bytes were written: */
+ if (n > 0) {
+ /*
+ * Keep a count of the number of bytes
+ * written:
+ */
+ num += n;
+
+ /*
+ * Enter a loop to check if a short write
+ * occurred and move the index to the
+ * array entry where the short write
+ * ended:
+ */
+ cnt = n;
+ while (cnt > 0 && idx < iovcnt) {
+ /*
+ * If the residual count exceeds
+ * the size of this vector, then
+ * it was completely written:
+ */
+ if (cnt >= p_iov[idx].iov_len)
+ /*
+ * Decrement the residual
+ * count and increment the
+ * index to the next array
+ * entry:
+ */
+ cnt -= p_iov[idx++].iov_len;
+ else {
+ /*
+ * This entry was only
+ * partially written, so
+ * adjust it's length
+ * and base pointer ready
+ * for the next write:
+ */
+ p_iov[idx].iov_len -= cnt;
+ p_iov[idx].iov_base += cnt;
+ cnt = 0;
+ }
+ }
+ } else if (n == 0) {
+ /*
+ * Avoid an infinite loop if the last iov_len is
+ * 0.
+ */
+ while (idx < iovcnt && p_iov[idx].iov_len == 0)
+ idx++;
+
+ if (idx == iovcnt) {
+ ret = num;
+ break;
+ }
+ }
+
+ /*
+ * If performing a blocking write, check if the
+ * write would have blocked or if some bytes
+ * were written but there are still more to
+ * write:
+ */
+ if (blocking && ((n < 0 && (errno == EWOULDBLOCK ||
+ errno == EAGAIN)) || (n >= 0 && idx < iovcnt))) {
+ _thread_run->data.fd.fd = fd;
+ _thread_kern_set_timeout(NULL);
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDW_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
+ /* Return an error: */
+ ret = -1;
+ }
+
+ /*
+ * If performing a non-blocking write or if an
+ * error occurred, just return whatever the write
+ * syscall did:
+ */
+ } else if (!blocking || n < 0) {
+ /* A non-blocking call might return zero: */
+ ret = n;
+ break;
+
+ /* Check if the write has completed: */
+ } else if (idx == iovcnt)
+ /* Return the number of bytes written: */
+ ret = num;
+ }
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+
+ /* If memory was allocated for the array, free it: */
+ if (p_iov != liov)
+ free(p_iov);
+
+ return (ret);
+}
+#endif
diff --git a/lib/libkse/thread/thr_yield.c b/lib/libkse/thread/thr_yield.c
new file mode 100644
index 0000000..064dd82
--- /dev/null
+++ b/lib/libkse/thread/thr_yield.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sched_yield(void)
+{
+ /* Reset the accumulated time slice value for the current thread: */
+ _thread_run->slice_usec = -1;
+
+ /* Schedule the next thread: */
+ _thread_kern_sched(NULL);
+
+ /* Always return no error. */
+ return(0);
+}
+
+/* Draft 4 yield */
+void
+pthread_yield(void)
+{
+ /* Reset the accumulated time slice value for the current thread: */
+ _thread_run->slice_usec = -1;
+
+ /* Schedule the next thread: */
+ _thread_kern_sched(NULL);
+
+ /* Nothing to return. */
+ return;
+}
+#endif
diff --git a/lib/libkvm/Makefile b/lib/libkvm/Makefile
new file mode 100644
index 0000000..75dcc7f
--- /dev/null
+++ b/lib/libkvm/Makefile
@@ -0,0 +1,20 @@
+# @(#)Makefile 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+LIB= kvm
+CFLAGS+=-DLIBC_SCCS -I${.CURDIR}/../../sys
+SRCS= kvm.c kvm_${MACHINE_ARCH}.c kvm_file.c kvm_getloadavg.c \
+ kvm_getswapinfo.c kvm_proc.c
+
+MAN3= kvm.3 kvm_geterr.3 kvm_getfiles.3 kvm_getloadavg.3 kvm_getprocs.3 \
+ kvm_getswapinfo.3 kvm_nlist.3 kvm_open.3 kvm_read.3
+
+MLINKS+=kvm_getprocs.3 kvm_getargv.3 kvm_getprocs.3 kvm_getenvv.3
+MLINKS+=kvm_open.3 kvm_close.3 kvm_open.3 kvm_openfiles.3
+MLINKS+=kvm_read.3 kvm_write.3
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/kvm.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libkvm/kvm.3 b/lib/libkvm/kvm.3
new file mode 100644
index 0000000..7647ca6
--- /dev/null
+++ b/lib/libkvm/kvm.3
@@ -0,0 +1,104 @@
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software developed by the Computer Systems
+.\" Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+.\" BG 91-66 and contributed to Berkeley.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)kvm.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt KVM 3
+.Os
+.Sh NAME
+.Nm kvm
+.Nd kernel memory interface
+.Sh DESCRIPTION
+The
+.Xr kvm 3
+library provides a uniform interface for accessing kernel virtual memory
+images, including live systems and crash dumps.
+Access to live systems is via
+/dev/mem
+while crash dumps can be examined via the core file generated by
+.Xr savecore 8 .
+The interface behaves identically in both cases.
+Memory can be read and written, kernel symbol addresses can be
+looked up efficiently, and information about user processes can
+be gathered.
+.Pp
+.Fn kvm_open
+is first called to obtain a descriptor for all subsequent calls.
+.Sh COMPATIBILITY
+The kvm interface was first introduced in SunOS. A considerable
+number of programs have been developed that use this interface,
+making backward compatibility highly desirable.
+In most respects, the Sun kvm interface is consistent and clean.
+Accordingly, the generic portion of the interface (i.e.,
+.Fn kvm_open ,
+.Fn kvm_close ,
+.Fn kvm_read ,
+.Fn kvm_write ,
+and
+.Fn kvm_nlist )
+has been incorporated into the BSD interface. Indeed, many kvm
+applications (i.e., debuggers and statistical monitors) use only
+this subset of the interface.
+.Pp
+The process interface was not kept. This is not a portability
+issue since any code that manipulates processes is inherently
+machine dependent.
+.Pp
+Finally, the Sun kvm error reporting semantics are poorly defined.
+The library can be configured either to print errors to stderr automatically,
+or to print no error messages at all.
+In the latter case, the nature of the error cannot be determined.
+To overcome this, the BSD interface includes a
+routine,
+.Xr kvm_geterr 3 ,
+to return (not print out) the error message
+corresponding to the most recent error condition on the
+given descriptor.
+.Sh SEE ALSO
+.Xr kvm_close 3 ,
+.Xr kvm_getargv 3 ,
+.Xr kvm_getenvv 3 ,
+.Xr kvm_geterr 3 ,
+.Xr kvm_getfiles 3 ,
+.Xr kvm_getloadavg 3 ,
+.Xr kvm_getprocs 3 ,
+.Xr kvm_getswapinfo 3 ,
+.Xr kvm_nlist 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3
diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c
new file mode 100644
index 0000000..b35eceb
--- /dev/null
+++ b/lib/libkvm/kvm.c
@@ -0,0 +1,543 @@
+/*-
+ * Copyright (c) 1989, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software developed by the Computer Systems
+ * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+ * BG 91-66 and contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)kvm.c 8.2 (Berkeley) 2/13/94";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/swap_pager.h>
+
+#include <machine/vmparam.h>
+
+#include <ctype.h>
+#include <db.h>
+#include <fcntl.h>
+#include <kvm.h>
+#include <limits.h>
+#include <nlist.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "kvm_private.h"
+
+static int kvm_dbopen __P((kvm_t *, const char *));
+
+char *
+kvm_geterr(kd)
+ kvm_t *kd;
+{
+ return (kd->errbuf);
+}
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+/*
+ * Report an error using printf style arguments. "program" is kd->program
+ * on hard errors, and 0 on soft errors, so that under sun error emulation,
+ * only hard errors are printed out (otherwise, programs like gdb will
+ * generate tons of error messages when trying to access bogus pointers).
+ */
+void
+#if __STDC__
+_kvm_err(kvm_t *kd, const char *program, const char *fmt, ...)
+#else
+_kvm_err(kd, program, fmt, va_alist)
+ kvm_t *kd;
+ char *program, *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+
+#ifdef __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ if (program != NULL) {
+ (void)fprintf(stderr, "%s: ", program);
+ (void)vfprintf(stderr, fmt, ap);
+ (void)fputc('\n', stderr);
+ } else
+ (void)vsnprintf(kd->errbuf,
+ sizeof(kd->errbuf), (char *)fmt, ap);
+
+ va_end(ap);
+}
+
+void
+#if __STDC__
+_kvm_syserr(kvm_t *kd, const char *program, const char *fmt, ...)
+#else
+_kvm_syserr(kd, program, fmt, va_alist)
+ kvm_t *kd;
+ char *program, *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+ register int n;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ if (program != NULL) {
+ (void)fprintf(stderr, "%s: ", program);
+ (void)vfprintf(stderr, fmt, ap);
+ (void)fprintf(stderr, ": %s\n", strerror(errno));
+ } else {
+ register char *cp = kd->errbuf;
+
+ (void)vsnprintf(cp, sizeof(kd->errbuf), (char *)fmt, ap);
+ n = strlen(cp);
+ (void)snprintf(&cp[n], sizeof(kd->errbuf) - n, ": %s",
+ strerror(errno));
+ }
+ va_end(ap);
+}
+
+void *
+_kvm_malloc(kd, n)
+ register kvm_t *kd;
+ register size_t n;
+{
+ void *p;
+
+ if ((p = calloc(n, sizeof(char))) == NULL)
+ _kvm_err(kd, kd->program, "can't allocate %u bytes: %s",
+ n, strerror(errno));
+ return (p);
+}
+
+static kvm_t *
+_kvm_open(kd, uf, mf, flag, errout)
+ register kvm_t *kd;
+ const char *uf;
+ const char *mf;
+ int flag;
+ char *errout;
+{
+ struct stat st;
+
+ kd->vmfd = -1;
+ kd->pmfd = -1;
+ kd->nlfd = -1;
+ kd->vmst = 0;
+ kd->db = 0;
+ kd->procbase = 0;
+ kd->argspc = 0;
+ kd->argv = 0;
+
+ if (uf == 0)
+ uf = getbootfile();
+ else if (strlen(uf) >= MAXPATHLEN) {
+ _kvm_err(kd, kd->program, "exec file name too long");
+ goto failed;
+ }
+ if (flag & ~O_RDWR) {
+ _kvm_err(kd, kd->program, "bad flags arg");
+ goto failed;
+ }
+ if (mf == 0)
+ mf = _PATH_MEM;
+
+ if ((kd->pmfd = open(mf, flag, 0)) < 0) {
+ _kvm_syserr(kd, kd->program, "%s", mf);
+ goto failed;
+ }
+ if (fstat(kd->pmfd, &st) < 0) {
+ _kvm_syserr(kd, kd->program, "%s", mf);
+ goto failed;
+ }
+ if (S_ISCHR(st.st_mode)) {
+ /*
+ * If this is a character special device, then check that
+ * it's /dev/mem. If so, open kmem too. (Maybe we should
+ * make it work for either /dev/mem or /dev/kmem -- in either
+ * case you're working with a live kernel.)
+ */
+ if (strcmp(mf, _PATH_DEVNULL) == 0) {
+ kd->vmfd = open(_PATH_DEVNULL, O_RDONLY);
+ } else if (strcmp(mf, _PATH_MEM) != 0) {
+ _kvm_err(kd, kd->program,
+ "%s: not physical memory device", mf);
+ goto failed;
+ } else {
+ if ((kd->vmfd = open(_PATH_KMEM, flag)) < 0) {
+ _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM);
+ goto failed;
+ }
+ }
+ /*
+ * Open kvm nlist database. We go ahead and do this
+ * here so that we don't have to hold on to the kernel
+ * path name. Since a kvm application will surely do
+ * a kvm_nlist(), this probably won't be a wasted effort.
+ * If the database cannot be opened, open the namelist
+ * argument so we revert to slow nlist() calls.
+ */
+ if (kvm_dbopen(kd, uf) < 0 &&
+ (kd->nlfd = open(uf, O_RDONLY, 0)) < 0) {
+ _kvm_syserr(kd, kd->program, "%s", uf);
+ goto failed;
+ }
+ } else {
+ /*
+ * This is a crash dump.
+ * Initialize the virtual address translation machinery,
+ * but first setup the namelist fd.
+ */
+ if ((kd->nlfd = open(uf, O_RDONLY, 0)) < 0) {
+ _kvm_syserr(kd, kd->program, "%s", uf);
+ goto failed;
+ }
+ if (_kvm_initvtop(kd) < 0)
+ goto failed;
+ }
+ return (kd);
+failed:
+ /*
+ * Copy out the error if doing sane error semantics.
+ */
+ if (errout != 0)
+ strcpy(errout, kd->errbuf);
+ (void)kvm_close(kd);
+ return (0);
+}
+
+kvm_t *
+kvm_openfiles(uf, mf, sf, flag, errout)
+ const char *uf;
+ const char *mf;
+ const char *sf;
+ int flag;
+ char *errout;
+{
+ register kvm_t *kd;
+
+ if ((kd = malloc(sizeof(*kd))) == NULL) {
+ (void)strcpy(errout, strerror(errno));
+ return (0);
+ }
+ memset(kd, 0, sizeof(*kd));
+ kd->program = 0;
+ return (_kvm_open(kd, uf, mf, flag, errout));
+}
+
+kvm_t *
+kvm_open(uf, mf, sf, flag, errstr)
+ const char *uf;
+ const char *mf;
+ const char *sf;
+ int flag;
+ const char *errstr;
+{
+ register kvm_t *kd;
+
+ if ((kd = malloc(sizeof(*kd))) == NULL) {
+ if (errstr != NULL)
+ (void)fprintf(stderr, "%s: %s\n",
+ errstr, strerror(errno));
+ return (0);
+ }
+ memset(kd, 0, sizeof(*kd));
+ kd->program = errstr;
+ return (_kvm_open(kd, uf, mf, flag, NULL));
+}
+
+int
+kvm_close(kd)
+ kvm_t *kd;
+{
+ register int error = 0;
+
+ if (kd->pmfd >= 0)
+ error |= close(kd->pmfd);
+ if (kd->vmfd >= 0)
+ error |= close(kd->vmfd);
+ if (kd->nlfd >= 0)
+ error |= close(kd->nlfd);
+ if (kd->db != 0)
+ error |= (kd->db->close)(kd->db);
+ if (kd->vmst)
+ _kvm_freevtop(kd);
+ if (kd->procbase != 0)
+ free((void *)kd->procbase);
+ if (kd->argv != 0)
+ free((void *)kd->argv);
+ free((void *)kd);
+
+ return (0);
+}
+
+/*
+ * Set up state necessary to do queries on the kernel namelist
+ * data base. If the data base is out-of-data/incompatible with
+ * given executable, set up things so we revert to standard nlist call.
+ * Only called for live kernels. Return 0 on success, -1 on failure.
+ */
+static int
+kvm_dbopen(kd, uf)
+ kvm_t *kd;
+ const char *uf;
+{
+ char *cp;
+ DBT rec;
+ int dbversionlen;
+ struct nlist nitem;
+ char dbversion[_POSIX2_LINE_MAX];
+ char kversion[_POSIX2_LINE_MAX];
+ char dbname[MAXPATHLEN];
+
+ if ((cp = rindex(uf, '/')) != 0)
+ uf = cp + 1;
+
+ (void)snprintf(dbname, sizeof(dbname), "%skvm_%s.db", _PATH_VARDB, uf);
+ kd->db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL);
+ if (kd->db == 0)
+ return (-1);
+ /*
+ * read version out of database
+ */
+ rec.data = VRS_KEY;
+ rec.size = sizeof(VRS_KEY) - 1;
+ if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
+ goto close;
+ if (rec.data == 0 || rec.size > sizeof(dbversion))
+ goto close;
+
+ bcopy(rec.data, dbversion, rec.size);
+ dbversionlen = rec.size;
+ /*
+ * Read version string from kernel memory.
+ * Since we are dealing with a live kernel, we can call kvm_read()
+ * at this point.
+ */
+ rec.data = VRS_SYM;
+ rec.size = sizeof(VRS_SYM) - 1;
+ if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
+ goto close;
+ if (rec.data == 0 || rec.size != sizeof(struct nlist))
+ goto close;
+ bcopy((char *)rec.data, (char *)&nitem, sizeof(nitem));
+ if (kvm_read(kd, (u_long)nitem.n_value, kversion, dbversionlen) !=
+ dbversionlen)
+ goto close;
+ /*
+ * If they match, we win - otherwise clear out kd->db so
+ * we revert to slow nlist().
+ */
+ if (bcmp(dbversion, kversion, dbversionlen) == 0)
+ return (0);
+close:
+ (void)(kd->db->close)(kd->db);
+ kd->db = 0;
+
+ return (-1);
+}
+
+int
+kvm_nlist(kd, nl)
+ kvm_t *kd;
+ struct nlist *nl;
+{
+ register struct nlist *p;
+ register int nvalid;
+
+ /*
+ * If we can't use the data base, revert to the
+ * slow library call.
+ */
+ if (kd->db == 0)
+ return (__fdnlist(kd->nlfd, nl));
+
+ /*
+ * We can use the kvm data base. Go through each nlist entry
+ * and look it up with a db query.
+ */
+ nvalid = 0;
+ for (p = nl; p->n_name && p->n_name[0]; ++p) {
+ register int len;
+ DBT rec;
+
+ if ((len = strlen(p->n_name)) > 4096) {
+ /* sanity */
+ _kvm_err(kd, kd->program, "symbol too large");
+ return (-1);
+ }
+ rec.data = p->n_name;
+ rec.size = len;
+ if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
+ continue;
+ if (rec.data == 0 || rec.size != sizeof(struct nlist))
+ continue;
+ ++nvalid;
+ /*
+ * Avoid alignment issues.
+ */
+ bcopy((char *)&((struct nlist *)rec.data)->n_type,
+ (char *)&p->n_type,
+ sizeof(p->n_type));
+ bcopy((char *)&((struct nlist *)rec.data)->n_value,
+ (char *)&p->n_value,
+ sizeof(p->n_value));
+ }
+ /*
+ * Return the number of entries that weren't found.
+ */
+ return ((p - nl) - nvalid);
+}
+
+ssize_t
+kvm_read(kd, kva, buf, len)
+ kvm_t *kd;
+ register u_long kva;
+ register void *buf;
+ register size_t len;
+{
+ register int cc;
+ register void *cp;
+
+ if (ISALIVE(kd)) {
+ /*
+ * We're using /dev/kmem. Just read straight from the
+ * device and let the active kernel do the address translation.
+ */
+ errno = 0;
+ if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) {
+ _kvm_err(kd, 0, "invalid address (%x)", kva);
+ return (0);
+ }
+ cc = read(kd->vmfd, buf, len);
+ if (cc < 0) {
+ _kvm_syserr(kd, 0, "kvm_read");
+ return (0);
+ } else if (cc < len)
+ _kvm_err(kd, kd->program, "short read");
+ return (cc);
+ } else {
+ cp = buf;
+ while (len > 0) {
+ u_long pa;
+
+ cc = _kvm_kvatop(kd, kva, &pa);
+ if (cc == 0)
+ return (0);
+ if (cc > len)
+ cc = len;
+ errno = 0;
+ if (lseek(kd->pmfd, (off_t)pa, 0) == -1 && errno != 0) {
+ _kvm_syserr(kd, 0, _PATH_MEM);
+ break;
+ }
+ cc = read(kd->pmfd, cp, cc);
+ if (cc < 0) {
+ _kvm_syserr(kd, kd->program, "kvm_read");
+ break;
+ }
+ /*
+ * If kvm_kvatop returns a bogus value or our core
+ * file is truncated, we might wind up seeking beyond
+ * the end of the core file in which case the read will
+ * return 0 (EOF).
+ */
+ if (cc == 0)
+ break;
+ (char *)cp += cc;
+ kva += cc;
+ len -= cc;
+ }
+ return ((char *)cp - (char *)buf);
+ }
+ /* NOTREACHED */
+}
+
+ssize_t
+kvm_write(kd, kva, buf, len)
+ kvm_t *kd;
+ register u_long kva;
+ register const void *buf;
+ register size_t len;
+{
+ register int cc;
+
+ if (ISALIVE(kd)) {
+ /*
+ * Just like kvm_read, only we write.
+ */
+ errno = 0;
+ if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) {
+ _kvm_err(kd, 0, "invalid address (%x)", kva);
+ return (0);
+ }
+ cc = write(kd->vmfd, buf, len);
+ if (cc < 0) {
+ _kvm_syserr(kd, 0, "kvm_write");
+ return (0);
+ } else if (cc < len)
+ _kvm_err(kd, kd->program, "short write");
+ return (cc);
+ } else {
+ _kvm_err(kd, kd->program,
+ "kvm_write not implemented for dead kernels");
+ return (0);
+ }
+ /* NOTREACHED */
+}
diff --git a/lib/libkvm/kvm.h b/lib/libkvm/kvm.h
new file mode 100644
index 0000000..b4978be
--- /dev/null
+++ b/lib/libkvm/kvm.h
@@ -0,0 +1,96 @@
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)kvm.h 8.1 (Berkeley) 6/2/93
+ * $FreeBSD$
+ */
+
+#ifndef _KVM_H_
+#define _KVM_H_
+
+#include <sys/cdefs.h>
+#include <machine/ansi.h>
+#include <nlist.h>
+
+/* Default version symbol. */
+#define VRS_SYM "_version"
+#define VRS_KEY "VERSION"
+
+#ifdef _BSD_SIZE_T_
+typedef _BSD_SIZE_T_ size_t;
+#undef _BSD_SIZE_T_
+#endif
+
+#ifdef _BSD_SSIZE_T_
+typedef _BSD_SSIZE_T_ ssize_t;
+#undef _BSD_SSIZE_T_
+#endif
+
+typedef struct __kvm kvm_t;
+
+struct kinfo_proc;
+struct proc;
+
+struct kvm_swap {
+ char ksw_devname[32];
+ int ksw_used;
+ int ksw_total;
+ int ksw_flags;
+ int ksw_reserved1;
+ int ksw_reserved2;
+};
+
+#define SWIF_DUMP_TREE 0x0001
+#define SWIF_DEV_PREFIX 0x0002
+
+__BEGIN_DECLS
+int kvm_close __P((kvm_t *));
+char **kvm_getargv __P((kvm_t *, const struct kinfo_proc *, int));
+char **kvm_getenvv __P((kvm_t *, const struct kinfo_proc *, int));
+char *kvm_geterr __P((kvm_t *));
+char *kvm_getfiles __P((kvm_t *, int, int, int *));
+int kvm_getloadavg __P((kvm_t *, double [], int));
+struct kinfo_proc *
+ kvm_getprocs __P((kvm_t *, int, int, int *));
+int kvm_getswapinfo __P((kvm_t *, struct kvm_swap *, int, int));
+int kvm_nlist __P((kvm_t *, struct nlist *));
+kvm_t *kvm_open
+ __P((const char *, const char *, const char *, int, const char *));
+kvm_t *kvm_openfiles
+ __P((const char *, const char *, const char *, int, char *));
+ssize_t kvm_read __P((kvm_t *, unsigned long, void *, size_t));
+ssize_t kvm_uread
+ __P((kvm_t *, const struct proc *, unsigned long, char *, size_t));
+ssize_t kvm_write __P((kvm_t *, unsigned long, const void *, size_t));
+__END_DECLS
+
+#endif /* !_KVM_H_ */
diff --git a/lib/libkvm/kvm_alpha.c b/lib/libkvm/kvm_alpha.c
new file mode 100644
index 0000000..391a955
--- /dev/null
+++ b/lib/libkvm/kvm_alpha.c
@@ -0,0 +1,212 @@
+/* $FreeBSD$ */
+/* $NetBSD: kvm_alpha.c,v 1.7.2.1 1997/11/02 20:34:26 mellon Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <limits.h>
+#include <db.h>
+#include <stdlib.h>
+#include <machine/pmap.h>
+#include "kvm_private.h"
+
+static off_t _kvm_pa2off(kvm_t *kd, u_long pa);
+
+struct vmstate {
+ u_int64_t lev1map_pa; /* PA of Lev1map */
+ u_int64_t page_size; /* Page size */
+ u_int64_t nmemsegs; /* Number of RAM segm */
+};
+
+void
+_kvm_freevtop(kd)
+ kvm_t *kd;
+{
+
+ /* Not actually used for anything right now, but safe. */
+ if (kd->vmst != 0)
+ free(kd->vmst);
+}
+
+int
+_kvm_initvtop(kd)
+ kvm_t *kd;
+{
+ struct vmstate *vm;
+ struct nlist nlist[2];
+ u_long pa;
+
+ vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
+ if (vm == 0) {
+ _kvm_err(kd, kd->program, "cannot allocate vm");
+ return (-1);
+ }
+ kd->vmst = vm;
+ vm->page_size = ALPHA_PGBYTES;
+
+ nlist[0].n_name = "_Lev1map";
+ nlist[1].n_name = 0;
+
+ if (kvm_nlist(kd, nlist) != 0) {
+ _kvm_err(kd, kd->program, "bad namelist");
+ return (-1);
+ }
+
+ if(!ISALIVE(kd)) {
+ if (kvm_read(kd, (nlist[0].n_value), &pa, sizeof(pa)) != sizeof(pa)) {
+ _kvm_err(kd, kd->program, "cannot read Lev1map");
+ return (-1);
+ }
+ } else
+ if (kvm_read(kd, (nlist[0].n_value), &pa, sizeof(pa)) != sizeof(pa)) {
+ _kvm_err(kd, kd->program, "cannot read Lev1map");
+ return (-1);
+ }
+ vm->lev1map_pa = pa;
+ return (0);
+
+}
+
+int
+_kvm_kvatop(kd, va, pa)
+ kvm_t *kd;
+ u_long va;
+ u_long *pa;
+{
+ u_int64_t lev1map_pa; /* PA of Lev1map */
+ u_int64_t page_size;
+ int rv, page_off;
+ alpha_pt_entry_t pte;
+ off_t pteoff;
+ struct vmstate *vm;
+ vm = kd->vmst ;
+
+
+ if (ISALIVE(kd)) {
+ _kvm_err(kd, 0, "vatop called in live kernel!");
+ return(0);
+ }
+ lev1map_pa = vm->lev1map_pa;
+ page_size = vm->page_size;
+
+ page_off = va & (page_size - 1);
+ if (va >= ALPHA_K0SEG_BASE && va <= ALPHA_K0SEG_END) {
+ /*
+ * Direct-mapped address: just convert it.
+ */
+
+ *pa = ALPHA_K0SEG_TO_PHYS(va);
+ rv = page_size - page_off;
+ } else if (va >= ALPHA_K1SEG_BASE && va <= ALPHA_K1SEG_END) {
+ /*
+ * Real kernel virtual address: do the translation.
+ */
+#define PTMASK ((1 << ALPHA_PTSHIFT) - 1)
+#define pmap_lev1_index(va) (((va) >> ALPHA_L1SHIFT) & PTMASK)
+#define pmap_lev2_index(va) (((va) >> ALPHA_L2SHIFT) & PTMASK)
+#define pmap_lev3_index(va) (((va) >> ALPHA_L3SHIFT) & PTMASK)
+
+ /* Find and read the L1 PTE. */
+ pteoff = lev1map_pa +
+ pmap_lev1_index(va) * sizeof(alpha_pt_entry_t);
+ if (lseek(kd->pmfd, _kvm_pa2off(kd, pteoff), 0) == -1 ||
+ read(kd->pmfd, (char *)&pte, sizeof(pte)) != sizeof(pte)) {
+ _kvm_syserr(kd, 0, "could not read L1 PTE");
+ goto lose;
+ }
+
+ /* Find and read the L2 PTE. */
+ if ((pte & ALPHA_PTE_VALID) == 0) {
+ _kvm_err(kd, 0, "invalid translation (invalid L1 PTE)");
+ goto lose;
+ }
+ pteoff = ALPHA_PTE_TO_PFN(pte) * page_size +
+ pmap_lev2_index(va) * sizeof(alpha_pt_entry_t);
+ if (lseek(kd->pmfd, _kvm_pa2off(kd, pteoff), 0) == -1 ||
+ read(kd->pmfd, (char *)&pte, sizeof(pte)) != sizeof(pte)) {
+ _kvm_syserr(kd, 0, "could not read L2 PTE");
+ goto lose;
+ }
+
+ /* Find and read the L3 PTE. */
+ if ((pte & ALPHA_PTE_VALID) == 0) {
+ _kvm_err(kd, 0, "invalid translation (invalid L2 PTE)");
+ goto lose;
+ }
+ pteoff = ALPHA_PTE_TO_PFN(pte) * page_size +
+ pmap_lev3_index(va) * sizeof(alpha_pt_entry_t);
+ if (lseek(kd->pmfd, _kvm_pa2off(kd, pteoff), 0) == -1 ||
+ read(kd->pmfd, (char *)&pte, sizeof(pte)) != sizeof(pte)) {
+ _kvm_syserr(kd, 0, "could not read L3 PTE");
+ goto lose;
+ }
+
+ /* Fill in the PA. */
+ if ((pte & ALPHA_PTE_VALID) == 0) {
+ _kvm_err(kd, 0, "invalid translation (invalid L3 PTE)");
+ goto lose;
+ }
+ *pa = ALPHA_PTE_TO_PFN(pte) * page_size + page_off;
+ rv = page_size - page_off;
+ } else {
+ /*
+ * Bogus address (not in KV space): punt.
+ */
+
+ _kvm_err(kd, 0, "invalid kernel virtual address");
+lose:
+ *pa = -1;
+ rv = 0;
+ }
+
+ return (rv);
+}
+
+/*
+ * Translate a physical address to a file-offset in the crash-dump.
+ */
+off_t
+_kvm_pa2off(kd, pa)
+ kvm_t *kd;
+ u_long pa;
+{
+ return ALPHA_K0SEG_TO_PHYS(pa);
+}
+
diff --git a/lib/libkvm/kvm_amd64.c b/lib/libkvm/kvm_amd64.c
new file mode 100644
index 0000000..d36b922
--- /dev/null
+++ b/lib/libkvm/kvm_amd64.c
@@ -0,0 +1,194 @@
+/*-
+ * Copyright (c) 1989, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software developed by the Computer Systems
+ * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+ * BG 91-66 and contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * i386 machine dependent routines for kvm. Hopefully, the forthcoming
+ * vm code will one day obsolete this module.
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <limits.h>
+#include <db.h>
+
+#include "kvm_private.h"
+
+#ifndef btop
+#define btop(x) (i386_btop(x))
+#define ptob(x) (i386_ptob(x))
+#endif
+
+struct vmstate {
+ pd_entry_t *PTD;
+};
+
+void
+_kvm_freevtop(kvm_t *kd)
+{
+ if (kd->vmst != 0) {
+ if (kd->vmst->PTD) {
+ free(kd->vmst->PTD);
+ }
+ free(kd->vmst);
+ }
+}
+
+int
+_kvm_initvtop(kvm_t *kd)
+{
+ struct vmstate *vm;
+ struct nlist nlist[2];
+ u_long pa;
+ pd_entry_t *PTD;
+
+ vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
+ if (vm == 0) {
+ _kvm_err(kd, kd->program, "cannot allocate vm");
+ return (-1);
+ }
+ kd->vmst = vm;
+ vm->PTD = 0;
+
+ nlist[0].n_name = "_IdlePTD";
+ nlist[1].n_name = 0;
+
+ if (kvm_nlist(kd, nlist) != 0) {
+ _kvm_err(kd, kd->program, "bad namelist");
+ return (-1);
+ }
+ if (kvm_read(kd, (nlist[0].n_value - KERNBASE), &pa, sizeof(pa)) != sizeof(pa)) {
+ _kvm_err(kd, kd->program, "cannot read IdlePTD");
+ return (-1);
+ }
+ PTD = _kvm_malloc(kd, PAGE_SIZE);
+ if (kvm_read(kd, pa, PTD, PAGE_SIZE) != PAGE_SIZE) {
+ _kvm_err(kd, kd->program, "cannot read PTD");
+ return (-1);
+ }
+ vm->PTD = PTD;
+ return (0);
+}
+
+static int
+_kvm_vatop(kvm_t *kd, u_long va, u_long *pa)
+{
+ struct vmstate *vm;
+ u_long offset;
+ u_long pte_pa;
+ pd_entry_t pde;
+ pt_entry_t pte;
+ u_long pdeindex;
+ u_long pteindex;
+ int i;
+
+ if (ISALIVE(kd)) {
+ _kvm_err(kd, 0, "vatop called in live kernel!");
+ return((off_t)0);
+ }
+
+ vm = kd->vmst;
+ offset = va & (PAGE_SIZE - 1);
+
+ /*
+ * If we are initializing (kernel page table descriptor pointer
+ * not yet set) then return pa == va to avoid infinite recursion.
+ */
+ if (vm->PTD == 0) {
+ *pa = va;
+ return (PAGE_SIZE - offset);
+ }
+
+ pdeindex = va >> PDRSHIFT;
+ pde = vm->PTD[pdeindex];
+ if (((u_long)pde & PG_V) == 0)
+ goto invalid;
+
+ if ((u_long)pde & PG_PS) {
+ /*
+ * No second-level page table; ptd describes one 4MB page.
+ * (We assume that the kernel wouldn't set PG_PS without enabling
+ * it cr0, and that the kernel doesn't support 36-bit physical
+ * addresses).
+ */
+#define PAGE4M_MASK (NBPDR - 1)
+#define PG_FRAME4M (~PAGE4M_MASK)
+ *pa = ((u_long)pde & PG_FRAME4M) + (va & PAGE4M_MASK);
+ return (NBPDR - (va & PAGE4M_MASK));
+ }
+
+ pteindex = (va >> PAGE_SHIFT) & (NPTEPG-1);
+ pte_pa = ((u_long)pde & PG_FRAME) + (pteindex * sizeof(pt_entry_t));
+
+ /* XXX This has to be a physical address read, kvm_read is virtual */
+ if (lseek(kd->pmfd, pte_pa, 0) == -1) {
+ _kvm_syserr(kd, kd->program, "_kvm_vatop: lseek");
+ goto invalid;
+ }
+ if (read(kd->pmfd, &pte, sizeof pte) != sizeof pte) {
+ _kvm_syserr(kd, kd->program, "_kvm_vatop: read");
+ goto invalid;
+ }
+ if (((u_long)pte & PG_V) == 0)
+ goto invalid;
+
+ *pa = ((u_long)pte & PG_FRAME) + offset;
+ return (PAGE_SIZE - offset);
+
+invalid:
+ _kvm_err(kd, 0, "invalid address (%x)", va);
+ return (0);
+}
+
+int
+_kvm_kvatop(kvm_t *kd, u_long va, u_long *pa)
+{
+ return (_kvm_vatop(kd, va, pa));
+}
diff --git a/lib/libkvm/kvm_file.c b/lib/libkvm/kvm_file.c
new file mode 100644
index 0000000..4af6b71
--- /dev/null
+++ b/lib/libkvm/kvm_file.c
@@ -0,0 +1,188 @@
+/*-
+ * Copyright (c) 1989, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm_file.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * File list interface for kvm. pstat, fstat and netstat are
+ * users of this code, so we've factored it out into a separate module.
+ * Thus, we keep this grunge out of the other kvm applications (i.e.,
+ * most other applications are interested only in open/close/read/nlist).
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#define KERNEL
+#include <sys/file.h>
+#undef KERNEL
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/swap_pager.h>
+
+#include <sys/sysctl.h>
+
+#include <limits.h>
+#include <ndbm.h>
+#include <paths.h>
+
+#include "kvm_private.h"
+
+#define KREAD(kd, addr, obj) \
+ (kvm_read(kd, addr, obj, sizeof(*obj)) != sizeof(*obj))
+
+/*
+ * Get file structures.
+ */
+static int
+kvm_deadfiles(kd, op, arg, filehead_o, nfiles)
+ kvm_t *kd;
+ int op, arg, nfiles;
+ long filehead_o;
+{
+ int buflen = kd->arglen, n = 0;
+ struct file *fp;
+ register char *where = kd->argspc;
+ struct filelist filehead;
+
+ /*
+ * first copyout filehead
+ */
+ if (buflen > sizeof (filehead)) {
+ if (KREAD(kd, filehead_o, &filehead)) {
+ _kvm_err(kd, kd->program, "can't read filehead");
+ return (0);
+ }
+ buflen -= sizeof (filehead);
+ where += sizeof (filehead);
+ *(struct filelist *)kd->argspc = filehead;
+ }
+ /*
+ * followed by an array of file structures
+ */
+ for (fp = filehead.lh_first; fp != 0; fp = fp->f_list.le_next) {
+ if (buflen > sizeof (struct file)) {
+ if (KREAD(kd, (long)fp, ((struct file *)where))) {
+ _kvm_err(kd, kd->program, "can't read kfp");
+ return (0);
+ }
+ buflen -= sizeof (struct file);
+ fp = (struct file *)where;
+ where += sizeof (struct file);
+ n++;
+ }
+ }
+ if (n != nfiles) {
+ _kvm_err(kd, kd->program, "inconsistant nfiles");
+ return (0);
+ }
+ return (nfiles);
+}
+
+char *
+kvm_getfiles(kd, op, arg, cnt)
+ kvm_t *kd;
+ int op, arg;
+ int *cnt;
+{
+ int mib[2], st, nfiles;
+ size_t size;
+ struct file *fp, *fplim;
+ struct filelist filehead;
+
+ if (ISALIVE(kd)) {
+ size = 0;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_FILE;
+ st = sysctl(mib, 2, NULL, &size, NULL, 0);
+ if (st == -1) {
+ _kvm_syserr(kd, kd->program, "kvm_getprocs");
+ return (0);
+ }
+ if (kd->argspc == 0)
+ kd->argspc = (char *)_kvm_malloc(kd, size);
+ else if (kd->arglen < size)
+ kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, size);
+ if (kd->argspc == 0)
+ return (0);
+ kd->arglen = size;
+ st = sysctl(mib, 2, kd->argspc, &size, NULL, 0);
+ if (st == -1 || size < sizeof(filehead)) {
+ _kvm_syserr(kd, kd->program, "kvm_getfiles");
+ return (0);
+ }
+ filehead = *(struct filelist *)kd->argspc;
+ fp = (struct file *)(kd->argspc + sizeof (filehead));
+ fplim = (struct file *)(kd->argspc + size);
+ for (nfiles = 0; filehead.lh_first && (fp < fplim); nfiles++, fp++)
+ filehead.lh_first = fp->f_list.le_next;
+ } else {
+ struct nlist nl[3], *p;
+
+ nl[0].n_name = "_filehead";
+ nl[1].n_name = "_nfiles";
+ nl[2].n_name = 0;
+
+ if (kvm_nlist(kd, nl) != 0) {
+ for (p = nl; p->n_type != 0; ++p)
+ ;
+ _kvm_err(kd, kd->program,
+ "%s: no such symbol", p->n_name);
+ return (0);
+ }
+ if (KREAD(kd, nl[0].n_value, &nfiles)) {
+ _kvm_err(kd, kd->program, "can't read nfiles");
+ return (0);
+ }
+ size = sizeof(filehead) + (nfiles + 10) * sizeof(struct file);
+ if (kd->argspc == 0)
+ kd->argspc = (char *)_kvm_malloc(kd, size);
+ else if (kd->arglen < size)
+ kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, size);
+ if (kd->argspc == 0)
+ return (0);
+ kd->arglen = size;
+ nfiles = kvm_deadfiles(kd, op, arg, nl[1].n_value, nfiles);
+ if (nfiles == 0)
+ return (0);
+ }
+ *cnt = nfiles;
+ return (kd->argspc);
+}
diff --git a/lib/libkvm/kvm_geterr.3 b/lib/libkvm/kvm_geterr.3
new file mode 100644
index 0000000..bab730e
--- /dev/null
+++ b/lib/libkvm/kvm_geterr.3
@@ -0,0 +1,81 @@
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software developed by the Computer Systems
+.\" Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+.\" BG 91-66 and contributed to Berkeley.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)kvm_geterr.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt KVM_GETERR 3
+.Os
+.Sh NAME
+.Nm kvm_geterr
+.Nd get error message on kvm descriptor
+.Sh SYNOPSIS
+.Fd #include <kvm.h>
+.br
+.Ft char *
+.Fn kvm_geterr "kvm_t *kd"
+.Sh DESCRIPTION
+This function returns a string describing the most recent error condition
+on the descriptor
+.Fa kd .
+The results are undefined if the most recent
+.Xr kvm 3
+library call did not produce an error.
+The string returned is stored in memory owned by
+.Xr kvm 3
+so the message should be copied out and saved elsewhere if necessary.
+.Sh BUGS
+This routine cannot be used to access error conditions due to a failed
+.Fn kvm_openfiles
+call, since failure is indicated by returning a
+.Dv NULL
+descriptor.
+Therefore, errors on open are output to the special error buffer
+passed to
+.Fn kvm_openfiles .
+This option is not available to
+.Fn kvm_open .
+.Sh SEE ALSO
+.Xr kvm 3 ,
+.Xr kvm_close 3 ,
+.Xr kvm_getargv 3 ,
+.Xr kvm_getenvv 3 ,
+.Xr kvm_getprocs 3 ,
+.Xr kvm_nlist 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3
diff --git a/lib/libkvm/kvm_getfiles.3 b/lib/libkvm/kvm_getfiles.3
new file mode 100644
index 0000000..0f8050d
--- /dev/null
+++ b/lib/libkvm/kvm_getfiles.3
@@ -0,0 +1,86 @@
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software developed by the Computer Systems
+.\" Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+.\" BG 91-66 and contributed to Berkeley.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)kvm_getfiles.3 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt KVM_GETFILES 3
+.Os
+.Sh NAME
+.Nm kvm_getfiles
+.Nd survey open files
+.Sh SYNOPSIS
+.Fd #include <kvm.h>
+.Fd #define KERNEL
+.Fd #include <sys/file.h>
+.Fd #undef KERNEL
+.\" .Fa kvm_t *kd
+.br
+.Ft char *
+.Fn kvm_getfiles "kvm_t *kd" "int op" "int arg" "int *cnt"
+.Sh DESCRIPTION
+.Fn kvm_getfiles
+returns a (sub-)set of the open files in the kernel indicated by
+.Fa kd.
+The
+.Fa op
+and
+.Fa arg
+arguments constitute a predicate which limits the set of files
+returned. No predicates are currently defined.
+.Pp
+The number of processes found is returned in the reference parameter
+.Fa cnt .
+The files are returned as a contiguous array of file structures,
+preceded by the address of the first file entry in the kernel.
+This memory is owned by kvm and is not guaranteed to be persistent across
+subsequent kvm library calls. Data should be copied out if it needs to be
+saved.
+.Sh RETURN VALUES
+.Fn kvm_getfiles
+will return NULL on failure.
+.Pp
+.Sh BUGS
+This routine does not belong in the kvm interface.
+.Sh SEE ALSO
+.Xr kvm 3 ,
+.Xr kvm_close 3 ,
+.Xr kvm_geterr 3 ,
+.Xr kvm_nlist 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3
diff --git a/lib/libkvm/kvm_getloadavg.3 b/lib/libkvm/kvm_getloadavg.3
new file mode 100644
index 0000000..7df1847
--- /dev/null
+++ b/lib/libkvm/kvm_getloadavg.3
@@ -0,0 +1,64 @@
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)kvm_getloadavg.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt KVM_GETLOADAVG 3
+.Os
+.Sh NAME
+.Nm kvm_getloadavg
+.Nd get load average of the system
+.Sh SYNOPSIS
+.Fd #include <kvm.h>
+.Ft int
+.Fn kvm_getloadavg "kvm_t *kd" "double loadavg[]" "int nelem"
+.Sh DESCRIPTION
+The
+.Fn kvm_getloadavg
+function returns the number of processes in the system run queue
+of the kernel indicated by
+.Fa kd ,
+averaged over various periods of time.
+Up to
+.Fa nelem
+samples are retrieved and assigned to successive elements of
+.Fa loadavg Ns Bq .
+The system imposes a maximum of 3 samples, representing averages
+over the last 1, 5, and 15 minutes, respectively.
+.Sh DIAGNOSTICS
+If the load average was unobtainable, \-1 is returned; otherwise,
+the number of samples actually retrieved is returned.
+.Sh SEE ALSO
+.Xr uptime 1 ,
+.Xr getloadavg 3 ,
+.Xr kvm 3
diff --git a/lib/libkvm/kvm_getloadavg.c b/lib/libkvm/kvm_getloadavg.c
new file mode 100644
index 0000000..3368e63
--- /dev/null
+++ b/lib/libkvm/kvm_getloadavg.c
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm_getloadavg.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#include <vm/vm_param.h>
+
+#include <stdlib.h>
+#include <db.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include "kvm_private.h"
+
+static struct nlist nl[] = {
+ { "_averunnable" },
+#define X_AVERUNNABLE 0
+ { "_fscale" },
+#define X_FSCALE 1
+ { "" },
+};
+
+/*
+ * kvm_getloadavg() -- Get system load averages, from live or dead kernels.
+ *
+ * Put `nelem' samples into `loadavg' array.
+ * Return number of samples retrieved, or -1 on error.
+ */
+int
+kvm_getloadavg(kd, loadavg, nelem)
+ kvm_t *kd;
+ double loadavg[];
+ int nelem;
+{
+ struct loadavg loadinfo;
+ struct nlist *p;
+ int fscale, i;
+
+ if (ISALIVE(kd))
+ return (getloadavg(loadavg, nelem));
+
+ if (kvm_nlist(kd, nl) != 0) {
+ for (p = nl; p->n_type != 0; ++p);
+ _kvm_err(kd, kd->program,
+ "%s: no such symbol", p->n_name);
+ return (-1);
+ }
+
+#define KREAD(kd, addr, obj) \
+ (kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj))
+ if (KREAD(kd, nl[X_AVERUNNABLE].n_value, &loadinfo)) {
+ _kvm_err(kd, kd->program, "can't read averunnable");
+ return (-1);
+ }
+
+ /*
+ * Old kernels have fscale separately; if not found assume
+ * running new format.
+ */
+ if (!KREAD(kd, nl[X_FSCALE].n_value, &fscale))
+ loadinfo.fscale = fscale;
+
+ nelem = MIN(nelem, sizeof(loadinfo.ldavg) / sizeof(fixpt_t));
+ for (i = 0; i < nelem; i++)
+ loadavg[i] = (double) loadinfo.ldavg[i] / loadinfo.fscale;
+ return (nelem);
+}
diff --git a/lib/libkvm/kvm_getprocs.3 b/lib/libkvm/kvm_getprocs.3
new file mode 100644
index 0000000..bd6bb74
--- /dev/null
+++ b/lib/libkvm/kvm_getprocs.3
@@ -0,0 +1,164 @@
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software developed by the Computer Systems
+.\" Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+.\" BG 91-66 and contributed to Berkeley.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)kvm_getprocs.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt KVM_GETPROCS 3
+.Os
+.Sh NAME
+.Nm kvm_getprocs ,
+.Nm kvm_getargv ,
+.Nm kvm_getenvv
+.Nd access user process state
+.Sh SYNOPSIS
+.Fd #include <kvm.h>
+.Fd #include <sys/param.h>
+.Fd #include <sys/sysctl.h>
+.\" .Fa kvm_t *kd
+.br
+.Ft struct kinfo_proc *
+.Fn kvm_getprocs "kvm_t *kd" "int op" "int arg" "int *cnt"
+.Ft char **
+.Fn kvm_getargv "kvm_t *kd" "const struct kinfo_proc *p" "int nchr"
+.Ft char **
+.Fn kvm_getenvv "kvm_t *kd" "const struct kinfo_proc *p" "int nchr"
+.Sh DESCRIPTION
+.Fn kvm_getprocs
+returns a (sub-)set of active processes in the kernel indicated by
+.Fa kd.
+The
+.Fa op
+and
+.Fa arg
+arguments constitute a predicate which limits the set of processes
+returned. The value of
+.Fa op
+describes the filtering predicate as follows:
+.Pp
+.Bl -tag -width 20n -offset indent -compact
+.It Sy KERN_PROC_ALL
+all processes
+.It Sy KERN_PROC_PID
+processes with process id
+.Fa arg
+.It Sy KERN_PROC_PGRP
+processes with process group
+.Fa arg
+.It Sy KERN_PROC_SESSION
+processes with session
+.Fa arg
+.It Sy KERN_PROC_TTY
+processes with tty
+.Fa arg
+.It Sy KERN_PROC_UID
+processes with effective user id
+.Fa arg
+.It Sy KERN_PROC_RUID
+processes with real user id
+.Fa arg
+.El
+.Pp
+The number of processes found is returned in the reference parameter
+.Fa cnt .
+The processes are returned as a contiguous array of kinfo_proc structures.
+This memory is locally allocated, and subsequent calls to
+.Fn kvm_getprocs
+and
+.Fn kvm_close
+will overwrite this storage.
+.Pp
+.Fn kvm_getargv
+returns a null-terminated argument vector that corresponds to the
+command line arguments passed to process indicated by
+.Fa p .
+Most likely, these arguments correspond to the values passed to
+.Xr exec 3
+on process creation. This information is, however,
+deliberately under control of the process itself.
+Note that the original command name can be found, unaltered,
+in the p_comm field of the process structure returned by
+.Fn kvm_getprocs .
+.Pp
+The
+.Fa nchr
+argument indicates the maximum number of characters, including null bytes,
+to use in building the strings. If this amount is exceeded, the string
+causing the overflow is truncated and the partial result is returned.
+This is handy for programs like
+.Xr ps 1
+and
+.Xr w 1
+that print only a one line summary of a command and should not copy
+out large amounts of text only to ignore it.
+If
+.Fa nchr
+is zero, no limit is imposed and all argument strings are returned in
+their entirety.
+.Pp
+The memory allocated to the argv pointers and string storage
+is owned by the kvm library. Subsequent
+.Fn kvm_getprocs
+and
+.Xr kvm_close 3
+calls will clobber this storage.
+.Pp
+The
+.Fn kvm_getenvv
+function is similar to
+.Fn kvm_getargv
+but returns the vector of environment strings. This data is
+also alterable by the process.
+.Sh RETURN VALUES
+.Fn kvm_getprocs ,
+.Fn kvm_getargv ,
+and
+.Fn kvm_getenvv ,
+all return
+.Dv NULL
+on failure.
+.Pp
+.Sh BUGS
+These routines do not belong in the kvm interface.
+.Sh SEE ALSO
+.Xr kvm 3 ,
+.Xr kvm_close 3 ,
+.Xr kvm_geterr 3 ,
+.Xr kvm_nlist 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3
diff --git a/lib/libkvm/kvm_getswapinfo.3 b/lib/libkvm/kvm_getswapinfo.3
new file mode 100644
index 0000000..dfcac1f
--- /dev/null
+++ b/lib/libkvm/kvm_getswapinfo.3
@@ -0,0 +1,62 @@
+.\" Copyright (c) 1999, Matthew Dillon. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided under the terms of the BSD
+.\" Copyright as found in /usr/src/COPYRIGHT in the FreeBSD source tree.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd January 22, 1999
+.Dt KVM_SWAPINFO 3
+.Os
+.Sh NAME
+.Nm kvm_getswapinfo
+.Nd return swap summary statistics for the system
+.Sh SYNOPSIS
+.Fd #include <kvm.h>
+.Ft int
+.Fn kvm_getswapinfo "kvm_t *kd" "struct kvm_swap *" "int maxswap" "int flags"
+.Sh DESCRIPTION
+The
+.Fn kvm_getswapinfo
+function fills an array of kvm_swap structures with swap summary
+information for each swap device, for up to maxswap - 1 devices.
+The number of devices, up to maxswap - 1, is returned. A grand
+total of all swap devices ( including any devices that go beyond
+maxswap - 1 ) is returned in one additional array entry. This
+entry is not counted in the return value. Thus, if you specify
+a maxswap value of 1, the function will typically return the
+value 0 and the single kvm_swap structure will be filled with
+the grand total over all swap devices. The grand total is calculated
+from all available swap devices whether or not you made room
+for them all in the array.
+the grant total is returned.
+.Pp
+The flags argument is currently unused and must be passed as 0.
+.Pp
+If an error occurs, -1 is returned.
+.Pp
+Each swap partition and the grand total is summarized in the kvm_swap
+structure. This structure contains the following fields:
+.Bl -inset -width indent
+.It char ksw_devname[];
+.It int ksw_total;
+.It int ksw_used;
+.It int ksw_flags;
+.El
+.Pp
+Values are in PAGE_SIZE'd chunks ( see getpagesize() ). ksw_flags contains
+a copy of the swap device flags.
+.PP
+.Sh CACHING
+This function caches the nlist values for various kernel variables which
+it reuses in successive calls. You may call the function with kd == NULL
+to clear the cache.
+.Sh DIAGNOSTICS
+If the load average was unobtainable, \-1 is returned; otherwise,
+the number of swap devices actually retrieved is returned.
+.Pp
+If the name of the swap device does not fit in the static char buffer
+in the structure, it is truncated. The buffer is always zero terminated.
+.Sh SEE ALSO
+.Xr kvm 3
diff --git a/lib/libkvm/kvm_getswapinfo.c b/lib/libkvm/kvm_getswapinfo.c
new file mode 100644
index 0000000..05aeedf
--- /dev/null
+++ b/lib/libkvm/kvm_getswapinfo.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright (c) 1999, Matthew Dillon. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided under the terms of the BSD
+ * Copyright as found in /usr/src/COPYRIGHT in the FreeBSD source tree.
+ */
+
+#ifndef lint
+static const char copyright[] =
+ "@(#) Copyright (c) 1999\n"
+ "Matthew Dillon. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/vnode.h>
+#include <sys/ucred.h>
+#include <sys/stat.h>
+#include <sys/conf.h>
+#include <sys/blist.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <kvm.h>
+#include <limits.h>
+#include <nlist.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static struct nlist kvm_swap_nl[] = {
+ { "_swapblist" }, /* new radix swap list */
+ { "_swdevt" }, /* list of swap devices and sizes */
+ { "_nswdev" }, /* number of swap devices */
+ { "_dmmax" }, /* maximum size of a swap block */
+ { "" }
+};
+
+#define NL_SWAPBLIST 0
+#define NL_SWDEVT 1
+#define NL_NSWDEV 2
+#define NL_DMMAX 3
+
+static int kvm_swap_nl_cached = 0;
+static int nswdev;
+static int unswdev;
+static int dmmax;
+
+static void getswapinfo_radix(kvm_t *kd, struct kvm_swap *swap_ary,
+ int swap_max, int flags);
+
+#define SVAR(var) __STRING(var) /* to force expansion */
+#define KGET(idx, var) \
+ KGET1(idx, &var, sizeof(var), SVAR(var))
+#define KGET1(idx, p, s, msg) \
+ KGET2(kvm_swap_nl[idx].n_value, p, s, msg)
+#define KGET2(addr, p, s, msg) \
+ if (kvm_read(kd, (u_long)(addr), p, s) != s) \
+ warnx("cannot read %s: %s", msg, kvm_geterr(kd))
+#define KGETN(idx, var) \
+ KGET1N(idx, &var, sizeof(var), SVAR(var))
+#define KGET1N(idx, p, s, msg) \
+ KGET2N(kvm_swap_nl[idx].n_value, p, s, msg)
+#define KGET2N(addr, p, s, msg) \
+ ((kvm_read(kd, (u_long)(addr), p, s) == s) ? 1 : 0)
+#define KGETRET(addr, p, s, msg) \
+ if (kvm_read(kd, (u_long)(addr), p, s) != s) { \
+ warnx("cannot read %s: %s", msg, kvm_geterr(kd)); \
+ return (0); \
+ }
+
+int
+kvm_getswapinfo(
+ kvm_t *kd,
+ struct kvm_swap *swap_ary,
+ int swap_max,
+ int flags
+) {
+ int ti = 0;
+
+ /*
+ * clear cache
+ */
+ if (kd == NULL) {
+ kvm_swap_nl_cached = 0;
+ return(0);
+ }
+
+ /*
+ * namelist
+ */
+ if (kvm_swap_nl_cached == 0) {
+ struct swdevt *sw;
+
+ if (kvm_nlist(kd, kvm_swap_nl) < 0)
+ return(-1);
+
+ /*
+ * required entries
+ */
+
+ if (
+ kvm_swap_nl[NL_SWDEVT].n_value == 0 ||
+ kvm_swap_nl[NL_NSWDEV].n_value == 0 ||
+ kvm_swap_nl[NL_DMMAX].n_value == 0 ||
+ kvm_swap_nl[NL_SWAPBLIST].n_type == 0
+ ) {
+ return(-1);
+ }
+
+ /*
+ * get globals, type of swap
+ */
+
+ KGET(NL_NSWDEV, nswdev);
+ KGET(NL_DMMAX, dmmax);
+
+ /*
+ * figure out how many actual swap devices are enabled
+ */
+
+ KGET(NL_SWDEVT, sw);
+ for (unswdev = nswdev - 1; unswdev >= 0; --unswdev) {
+ struct swdevt swinfo;
+
+ KGET2(&sw[unswdev], &swinfo, sizeof(swinfo), "swinfo");
+ if (swinfo.sw_nblks)
+ break;
+ }
+ ++unswdev;
+
+ kvm_swap_nl_cached = 1;
+ }
+
+
+ {
+ struct swdevt *sw;
+ int i;
+
+ ti = unswdev;
+ if (ti >= swap_max)
+ ti = swap_max - 1;
+
+ if (ti >= 0)
+ bzero(swap_ary, sizeof(struct kvm_swap) * (ti + 1));
+
+ KGET(NL_SWDEVT, sw);
+ for (i = 0; i < unswdev; ++i) {
+ struct swdevt swinfo;
+ int ttl;
+
+ KGET2(&sw[i], &swinfo, sizeof(swinfo), "swinfo");
+
+ /*
+ * old style: everything in DEV_BSIZE'd chunks,
+ * convert to pages.
+ *
+ * new style: swinfo in DEV_BSIZE'd chunks but dmmax
+ * in pages.
+ *
+ * The first dmmax is never allocating to avoid
+ * trashing the disklabels
+ */
+
+ ttl = swinfo.sw_nblks - dmmax;
+
+ if (ttl == 0)
+ continue;
+
+ if (i < ti) {
+ swap_ary[i].ksw_total = ttl;
+ swap_ary[i].ksw_used = ttl;
+ swap_ary[i].ksw_flags = swinfo.sw_flags;
+ if (swinfo.sw_dev == NODEV) {
+ snprintf(
+ swap_ary[i].ksw_devname,
+ sizeof(swap_ary[i].ksw_devname),
+ "%s",
+ "[NFS swap]"
+ );
+ } else {
+ snprintf(
+ swap_ary[i].ksw_devname,
+ sizeof(swap_ary[i].ksw_devname),
+ "%s%s",
+ ((flags & SWIF_DEV_PREFIX) ? "/dev/" : ""),
+ devname(swinfo.sw_dev, S_IFCHR)
+ );
+ }
+ }
+ if (ti >= 0) {
+ swap_ary[ti].ksw_total += ttl;
+ swap_ary[ti].ksw_used += ttl;
+ }
+ }
+ }
+
+ getswapinfo_radix(kd, swap_ary, swap_max, flags);
+ return(ti);
+}
+
+/*
+ * scanradix() - support routine for radix scanner
+ */
+
+#define TABME tab, tab, ""
+
+static int
+scanradix(
+ blmeta_t *scan,
+ daddr_t blk,
+ daddr_t radix,
+ daddr_t skip,
+ daddr_t count,
+ kvm_t *kd,
+ int dmmax,
+ int nswdev,
+ struct kvm_swap *swap_ary,
+ int swap_max,
+ int tab,
+ int flags
+) {
+ blmeta_t meta;
+ int ti = (unswdev >= swap_max) ? swap_max - 1 : unswdev;
+
+ KGET2(scan, &meta, sizeof(meta), "blmeta_t");
+
+ /*
+ * Terminator
+ */
+ if (meta.bm_bighint == (daddr_t)-1) {
+ if (flags & SWIF_DUMP_TREE) {
+ printf("%*.*s(0x%06x,%d) Terminator\n",
+ TABME,
+ blk,
+ radix
+ );
+ }
+ return(-1);
+ }
+
+ if (radix == BLIST_BMAP_RADIX) {
+ /*
+ * Leaf bitmap
+ */
+ int i;
+
+ if (flags & SWIF_DUMP_TREE) {
+ printf("%*.*s(0x%06x,%d) Bitmap %08x big=%d\n",
+ TABME,
+ blk,
+ radix,
+ (int)meta.u.bmu_bitmap,
+ meta.bm_bighint
+ );
+ }
+
+ /*
+ * If not all allocated, count.
+ */
+ if (meta.u.bmu_bitmap != 0) {
+ for (i = 0; i < BLIST_BMAP_RADIX && i < count; ++i) {
+ /*
+ * A 0 bit means allocated
+ */
+ if ((meta.u.bmu_bitmap & (1 << i))) {
+ int t = 0;
+
+ if (nswdev)
+ t = (blk + i) / dmmax % nswdev;
+ if (t < ti)
+ --swap_ary[t].ksw_used;
+ if (ti >= 0)
+ --swap_ary[ti].ksw_used;
+ }
+ }
+ }
+ } else if (meta.u.bmu_avail == radix) {
+ /*
+ * Meta node if all free
+ */
+ if (flags & SWIF_DUMP_TREE) {
+ printf("%*.*s(0x%06x,%d) Submap ALL-FREE {\n",
+ TABME,
+ blk,
+ radix,
+ (int)meta.u.bmu_avail,
+ meta.bm_bighint
+ );
+ }
+ /*
+ * Note: both dmmax and radix are powers of 2. However, dmmax
+ * may be larger then radix so use a smaller increment if
+ * necessary.
+ */
+ {
+ int t;
+ int tinc = dmmax;
+
+ while (tinc > radix)
+ tinc >>= 1;
+
+ for (t = blk; t < blk + radix; t += tinc) {
+ int u = (nswdev) ? (t / dmmax % nswdev) : 0;
+
+ if (u < ti)
+ swap_ary[u].ksw_used -= tinc;
+ if (ti >= 0)
+ swap_ary[ti].ksw_used -= tinc;
+ }
+ }
+ } else if (meta.u.bmu_avail == 0) {
+ /*
+ * Meta node if all used
+ */
+ if (flags & SWIF_DUMP_TREE) {
+ printf("%*.*s(0x%06x,%d) Submap ALL-ALLOCATED\n",
+ TABME,
+ blk,
+ radix,
+ (int)meta.u.bmu_avail,
+ meta.bm_bighint
+ );
+ }
+ } else {
+ /*
+ * Meta node if not all free
+ */
+ int i;
+ int next_skip;
+
+ if (flags & SWIF_DUMP_TREE) {
+ printf("%*.*s(0x%06x,%d) Submap avail=%d big=%d {\n",
+ TABME,
+ blk,
+ radix,
+ (int)meta.u.bmu_avail,
+ meta.bm_bighint
+ );
+ }
+
+ radix >>= BLIST_META_RADIX_SHIFT;
+ next_skip = skip >> BLIST_META_RADIX_SHIFT;
+
+ for (i = 1; i <= skip; i += next_skip) {
+ int r;
+ daddr_t vcount = (count > radix) ? radix : count;
+
+ r = scanradix(
+ &scan[i],
+ blk,
+ radix,
+ next_skip - 1,
+ vcount,
+ kd,
+ dmmax,
+ nswdev,
+ swap_ary,
+ swap_max,
+ tab + 4,
+ flags
+ );
+ if (r < 0)
+ break;
+ blk += radix;
+ }
+ if (flags & SWIF_DUMP_TREE) {
+ printf("%*.*s}\n", TABME);
+ }
+ }
+ return(0);
+}
+
+static void
+getswapinfo_radix(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max, int flags)
+{
+ struct blist *swapblist = NULL;
+ struct blist blcopy = { 0 };
+
+ KGET(NL_SWAPBLIST, swapblist);
+
+ if (swapblist == NULL) {
+ if (flags & SWIF_DUMP_TREE)
+ printf("radix tree: NULL - no swap in system\n");
+ return;
+ }
+
+ KGET2(swapblist, &blcopy, sizeof(blcopy), "*swapblist");
+
+ if (flags & SWIF_DUMP_TREE) {
+ printf("radix tree: %d/%d/%d blocks, %dK wired\n",
+ blcopy.bl_free,
+ blcopy.bl_blocks,
+ blcopy.bl_radix,
+ (blcopy.bl_rootblks * sizeof(blmeta_t) + 1023)/
+ 1024
+ );
+ }
+ scanradix(
+ blcopy.bl_root,
+ 0,
+ blcopy.bl_radix,
+ blcopy.bl_skip,
+ blcopy.bl_rootblks,
+ kd,
+ dmmax,
+ nswdev,
+ swap_ary,
+ swap_max,
+ 0,
+ flags
+ );
+}
diff --git a/lib/libkvm/kvm_i386.c b/lib/libkvm/kvm_i386.c
new file mode 100644
index 0000000..d36b922
--- /dev/null
+++ b/lib/libkvm/kvm_i386.c
@@ -0,0 +1,194 @@
+/*-
+ * Copyright (c) 1989, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software developed by the Computer Systems
+ * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+ * BG 91-66 and contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * i386 machine dependent routines for kvm. Hopefully, the forthcoming
+ * vm code will one day obsolete this module.
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <limits.h>
+#include <db.h>
+
+#include "kvm_private.h"
+
+#ifndef btop
+#define btop(x) (i386_btop(x))
+#define ptob(x) (i386_ptob(x))
+#endif
+
+struct vmstate {
+ pd_entry_t *PTD;
+};
+
+void
+_kvm_freevtop(kvm_t *kd)
+{
+ if (kd->vmst != 0) {
+ if (kd->vmst->PTD) {
+ free(kd->vmst->PTD);
+ }
+ free(kd->vmst);
+ }
+}
+
+int
+_kvm_initvtop(kvm_t *kd)
+{
+ struct vmstate *vm;
+ struct nlist nlist[2];
+ u_long pa;
+ pd_entry_t *PTD;
+
+ vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
+ if (vm == 0) {
+ _kvm_err(kd, kd->program, "cannot allocate vm");
+ return (-1);
+ }
+ kd->vmst = vm;
+ vm->PTD = 0;
+
+ nlist[0].n_name = "_IdlePTD";
+ nlist[1].n_name = 0;
+
+ if (kvm_nlist(kd, nlist) != 0) {
+ _kvm_err(kd, kd->program, "bad namelist");
+ return (-1);
+ }
+ if (kvm_read(kd, (nlist[0].n_value - KERNBASE), &pa, sizeof(pa)) != sizeof(pa)) {
+ _kvm_err(kd, kd->program, "cannot read IdlePTD");
+ return (-1);
+ }
+ PTD = _kvm_malloc(kd, PAGE_SIZE);
+ if (kvm_read(kd, pa, PTD, PAGE_SIZE) != PAGE_SIZE) {
+ _kvm_err(kd, kd->program, "cannot read PTD");
+ return (-1);
+ }
+ vm->PTD = PTD;
+ return (0);
+}
+
+static int
+_kvm_vatop(kvm_t *kd, u_long va, u_long *pa)
+{
+ struct vmstate *vm;
+ u_long offset;
+ u_long pte_pa;
+ pd_entry_t pde;
+ pt_entry_t pte;
+ u_long pdeindex;
+ u_long pteindex;
+ int i;
+
+ if (ISALIVE(kd)) {
+ _kvm_err(kd, 0, "vatop called in live kernel!");
+ return((off_t)0);
+ }
+
+ vm = kd->vmst;
+ offset = va & (PAGE_SIZE - 1);
+
+ /*
+ * If we are initializing (kernel page table descriptor pointer
+ * not yet set) then return pa == va to avoid infinite recursion.
+ */
+ if (vm->PTD == 0) {
+ *pa = va;
+ return (PAGE_SIZE - offset);
+ }
+
+ pdeindex = va >> PDRSHIFT;
+ pde = vm->PTD[pdeindex];
+ if (((u_long)pde & PG_V) == 0)
+ goto invalid;
+
+ if ((u_long)pde & PG_PS) {
+ /*
+ * No second-level page table; ptd describes one 4MB page.
+ * (We assume that the kernel wouldn't set PG_PS without enabling
+ * it cr0, and that the kernel doesn't support 36-bit physical
+ * addresses).
+ */
+#define PAGE4M_MASK (NBPDR - 1)
+#define PG_FRAME4M (~PAGE4M_MASK)
+ *pa = ((u_long)pde & PG_FRAME4M) + (va & PAGE4M_MASK);
+ return (NBPDR - (va & PAGE4M_MASK));
+ }
+
+ pteindex = (va >> PAGE_SHIFT) & (NPTEPG-1);
+ pte_pa = ((u_long)pde & PG_FRAME) + (pteindex * sizeof(pt_entry_t));
+
+ /* XXX This has to be a physical address read, kvm_read is virtual */
+ if (lseek(kd->pmfd, pte_pa, 0) == -1) {
+ _kvm_syserr(kd, kd->program, "_kvm_vatop: lseek");
+ goto invalid;
+ }
+ if (read(kd->pmfd, &pte, sizeof pte) != sizeof pte) {
+ _kvm_syserr(kd, kd->program, "_kvm_vatop: read");
+ goto invalid;
+ }
+ if (((u_long)pte & PG_V) == 0)
+ goto invalid;
+
+ *pa = ((u_long)pte & PG_FRAME) + offset;
+ return (PAGE_SIZE - offset);
+
+invalid:
+ _kvm_err(kd, 0, "invalid address (%x)", va);
+ return (0);
+}
+
+int
+_kvm_kvatop(kvm_t *kd, u_long va, u_long *pa)
+{
+ return (_kvm_vatop(kd, va, pa));
+}
diff --git a/lib/libkvm/kvm_nlist.3 b/lib/libkvm/kvm_nlist.3
new file mode 100644
index 0000000..f5611b3
--- /dev/null
+++ b/lib/libkvm/kvm_nlist.3
@@ -0,0 +1,89 @@
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software developed by the Computer Systems
+.\" Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+.\" BG 91-66 and contributed to Berkeley.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)kvm_nlist.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt KVM_NLIST 3
+.Os
+.Sh NAME
+.Nm kvm_nlist
+.Nd retrieve symbol table names from a kernel image
+.Sh SYNOPSIS
+.Fd #include <kvm.h>
+.Fd #include <nlist.h>
+.Ft int
+.Fn kvm_nlist "kvm_t *kd" "struct nlist *nl"
+.Sh DESCRIPTION
+.Fn kvm_nlist
+retrieves the symbol table entries indicated by the name list argument
+.Fa \&nl .
+This argument points to an array of nlist structures, terminated by
+an entry whose n_name field is
+.Dv NULL
+(see
+.Xr nlist 3 ) .
+Each symbol is looked up using the n_name field, and if found, the
+corresponding n_type and n_value fields are filled in. These fields are set
+to 0 if the symbol is not found.
+.Pp
+The program
+.Xr kvm_mkdb 8
+builds a database from the running kernel's namelist.
+If the database matches the opened kernel,
+.Fn kvm_nlist
+uses it to speed lookups.
+.Sh RETURN VALUES
+The
+.Fn kvm_nlist
+function returns the number of invalid entries found.
+If the kernel symbol table was unreadable, -1 is returned.
+.Sh FILES
+.Bl -tag -width /var/db/kvm_kernel.db -compact
+.It Pa /var/db/kvm_kernel.db
+.El
+.Sh SEE ALSO
+.Xr kvm 3 ,
+.Xr kvm_close 3 ,
+.Xr kvm_getargv 3 ,
+.Xr kvm_getenvv 3 ,
+.Xr kvm_geterr 3 ,
+.Xr kvm_getprocs 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3 ,
+.Xr kvm_mkdb 8
diff --git a/lib/libkvm/kvm_open.3 b/lib/libkvm/kvm_open.3
new file mode 100644
index 0000000..b791708
--- /dev/null
+++ b/lib/libkvm/kvm_open.3
@@ -0,0 +1,186 @@
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software developed by the Computer Systems
+.\" Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+.\" BG 91-66 and contributed to Berkeley.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)kvm_open.3 8.3 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt KVM_OPEN 3
+.Os
+.Sh NAME
+.Nm kvm_open ,
+.Nm kvm_openfiles ,
+.Nm kvm_close
+.Nd initialize kernel virtual memory access
+.Sh SYNOPSIS
+.Fd #include <fcntl.h>
+.Fd #include <kvm.h>
+.br
+.Ft kvm_t *
+.Fn kvm_open "const char *execfile" "const char *corefile" "const char *swapfile" "int flags" "const char *errstr"
+.Ft kvm_t *
+.Fn kvm_openfiles "const char *execfile" "const char *corefile" "const char *swapfile" "int flags" "char *errbuf"
+.Ft int
+.Fn kvm_close "kvm_t *kd"
+.Sh DESCRIPTION
+The functions
+.Fn kvm_open
+and
+.Fn kvm_openfiles
+return a descriptor used to access kernel virtual memory
+via the
+.Xr kvm 3
+library routines. Both active kernels and crash dumps are accessible
+through this interface.
+.Pp
+.Fa execfile
+is the executable image of the kernel being examined.
+This file must contain a symbol table.
+If this argument is
+.Dv NULL ,
+the currently running system is assumed,
+as determined from
+.Xr getbootfile 3 .
+.Pp
+.Fa corefile
+is the kernel memory device file. It can be either /dev/mem
+or a crash dump core generated by
+.Xr savecore 8 .
+If
+.Fa corefile
+is
+.Dv NULL ,
+the default indicated by
+.Dv _PATH_MEM
+from <paths.h> is used.
+.Pp
+.Fa swapfile
+should indicate the swap device. If
+.Dv NULL ,
+.Dv _PATH_DRUM
+from <paths.h> is used.
+.Pp
+The
+.Fa flags
+argument indicates read/write access as in
+.Xr open 2
+and applies only to the core file.
+Only
+.Dv O_RDONLY ,
+.Dv O_WRONLY ,
+and
+.Dv O_RDWR
+are permitted.
+.Pp
+There are two open routines which differ only with respect to
+the error mechanism.
+One provides backward compatibility with the SunOS kvm library, while the
+other provides an improved error reporting framework.
+.Pp
+The
+.Fn kvm_open
+function is the Sun kvm compatible open call. Here, the
+.Fa errstr
+argument indicates how errors should be handled. If it is
+.Dv NULL ,
+no errors are reported and the application cannot know the
+specific nature of the failed kvm call.
+If it is not
+.Dv NULL ,
+errors are printed to stderr with
+.Fa errstr
+prepended to the message, as in
+.Xr perror 3 .
+Normally, the name of the program is used here.
+The string is assumed to persist at least until the corresponding
+.Fn kvm_close
+call.
+.Pp
+The
+.Fn kvm_openfiles
+function provides BSD style error reporting.
+Here, error messages are not printed out by the library.
+Instead, the application obtains the error message
+corresponding to the most recent kvm library call using
+.Fn kvm_geterr
+(see
+.Xr kvm_geterr 3 ).
+The results are undefined if the most recent kvm call did not produce
+an error.
+Since
+.Fn kvm_geterr
+requires a kvm descriptor, but the open routines return
+.Dv NULL
+on failure,
+.Fn kvm_geterr
+cannot be used to get the error message if open fails.
+Thus,
+.Fn kvm_openfiles
+will place any error message in the
+.Fa errbuf
+argument. This buffer should be _POSIX2_LINE_MAX characters large (from
+<limits.h>).
+.Sh RETURN VALUES
+The
+.Fn kvm_open
+and
+.Fn kvm_openfiles
+functions both return a descriptor to be used
+in all subsequent kvm library calls.
+The library is fully re-entrant.
+On failure,
+.Dv NULL
+is returned, in which case
+.Fn kvm_openfiles
+writes the error message into
+.Fa errbuf .
+.Pp
+The
+.Fn kvm_close
+function returns 0 on success and -1 on failure.
+.Sh BUGS
+There should not be two open calls. The ill-defined error semantics
+of the Sun library and the desire to have a backward-compatible library
+for BSD left little choice.
+.Sh SEE ALSO
+.Xr open 2 ,
+.Xr kvm 3 ,
+.Xr kvm_getargv 3 ,
+.Xr kvm_getenvv 3 ,
+.Xr kvm_geterr 3 ,
+.Xr kvm_getprocs 3 ,
+.Xr kvm_nlist 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3
diff --git a/lib/libkvm/kvm_private.h b/lib/libkvm/kvm_private.h
new file mode 100644
index 0000000..2d6d07f
--- /dev/null
+++ b/lib/libkvm/kvm_private.h
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software developed by the Computer Systems
+ * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+ * BG 91-66 and contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)kvm_private.h 8.1 (Berkeley) 6/4/93
+ */
+
+struct __kvm {
+ /*
+ * a string to be prepended to error messages
+ * provided for compatibility with sun's interface
+ * if this value is null, errors are saved in errbuf[]
+ */
+ const char *program;
+ char *errp; /* XXX this can probably go away */
+ char errbuf[_POSIX2_LINE_MAX];
+ DB *db;
+#define ISALIVE(kd) ((kd)->vmfd >= 0)
+ int pmfd; /* physical memory file (or crashdump) */
+ int vmfd; /* virtual memory file (-1 if crashdump) */
+ int unused; /* was: swap file (e.g., /dev/drum) */
+ int nlfd; /* namelist file (e.g., /kernel) */
+ struct kinfo_proc *procbase;
+ char *argspc; /* (dynamic) storage for argv strings */
+ int arglen; /* length of the above */
+ char **argv; /* (dynamic) storage for argv pointers */
+ int argc; /* length of above (not actual # present) */
+ char *argbuf; /* (dynamic) temporary storage */
+ /*
+ * Kernel virtual address translation state. This only gets filled
+ * in for dead kernels; otherwise, the running kernel (i.e. kmem)
+ * will do the translations for us. It could be big, so we
+ * only allocate it if necessary.
+ */
+ struct vmstate *vmst;
+};
+
+/*
+ * Functions used internally by kvm, but across kvm modules.
+ */
+void _kvm_err __P((kvm_t *kd, const char *program, const char *fmt, ...));
+void _kvm_freeprocs __P((kvm_t *kd));
+void _kvm_freevtop __P((kvm_t *));
+int _kvm_initvtop __P((kvm_t *));
+int _kvm_kvatop __P((kvm_t *, u_long, u_long *));
+void *_kvm_malloc __P((kvm_t *kd, size_t));
+void *_kvm_realloc __P((kvm_t *kd, void *, size_t));
+void _kvm_syserr
+ __P((kvm_t *kd, const char *program, const char *fmt, ...));
+int _kvm_uvatop __P((kvm_t *, const struct proc *, u_long, u_long *));
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
new file mode 100644
index 0000000..feba974
--- /dev/null
+++ b/lib/libkvm/kvm_proc.c
@@ -0,0 +1,784 @@
+/*-
+ * Copyright (c) 1989, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software developed by the Computer Systems
+ * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+ * BG 91-66 and contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm_proc.c 8.3 (Berkeley) 9/23/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Proc traversal interface for kvm. ps and w are (probably) the exclusive
+ * users of this code, so we've factored it out into a separate module.
+ * Thus, we keep this grunge out of the other kvm applications (i.e.,
+ * most other applications are interested only in open/close/read/nlist).
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/exec.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/swap_pager.h>
+
+#include <sys/sysctl.h>
+
+#include <limits.h>
+#include <memory.h>
+#include <db.h>
+#include <paths.h>
+
+#include "kvm_private.h"
+
+#if used
+static char *
+kvm_readswap(kd, p, va, cnt)
+ kvm_t *kd;
+ const struct proc *p;
+ u_long va;
+ u_long *cnt;
+{
+#ifdef __FreeBSD__
+ /* XXX Stubbed out, our vm system is differnet */
+ _kvm_err(kd, kd->program, "kvm_readswap not implemented");
+ return(0);
+#endif /* __FreeBSD__ */
+}
+#endif
+
+#define KREAD(kd, addr, obj) \
+ (kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj))
+
+/*
+ * Read proc's from memory file into buffer bp, which has space to hold
+ * at most maxcnt procs.
+ */
+static int
+kvm_proclist(kd, what, arg, p, bp, maxcnt)
+ kvm_t *kd;
+ int what, arg;
+ struct proc *p;
+ struct kinfo_proc *bp;
+ int maxcnt;
+{
+ register int cnt = 0;
+ struct eproc eproc;
+ struct pgrp pgrp;
+ struct session sess;
+ struct tty tty;
+ struct proc proc;
+ struct proc pproc;
+
+ for (; cnt < maxcnt && p != NULL; p = proc.p_list.le_next) {
+ if (KREAD(kd, (u_long)p, &proc)) {
+ _kvm_err(kd, kd->program, "can't read proc at %x", p);
+ return (-1);
+ }
+ if (KREAD(kd, (u_long)proc.p_cred, &eproc.e_pcred) == 0)
+ (void)(KREAD(kd, (u_long)eproc.e_pcred.pc_ucred,
+ &eproc.e_ucred));
+
+ switch(what) {
+
+ case KERN_PROC_PID:
+ if (proc.p_pid != (pid_t)arg)
+ continue;
+ break;
+
+ case KERN_PROC_UID:
+ if (eproc.e_ucred.cr_uid != (uid_t)arg)
+ continue;
+ break;
+
+ case KERN_PROC_RUID:
+ if (eproc.e_pcred.p_ruid != (uid_t)arg)
+ continue;
+ break;
+ }
+ /*
+ * We're going to add another proc to the set. If this
+ * will overflow the buffer, assume the reason is because
+ * nprocs (or the proc list) is corrupt and declare an error.
+ */
+ if (cnt >= maxcnt) {
+ _kvm_err(kd, kd->program, "nprocs corrupt");
+ return (-1);
+ }
+ /*
+ * gather eproc
+ */
+ eproc.e_paddr = p;
+ if (KREAD(kd, (u_long)proc.p_pgrp, &pgrp)) {
+ _kvm_err(kd, kd->program, "can't read pgrp at %x",
+ proc.p_pgrp);
+ return (-1);
+ }
+ if (proc.p_oppid)
+ eproc.e_ppid = proc.p_oppid;
+ else if (proc.p_pptr) {
+ if (KREAD(kd, (u_long)proc.p_pptr, &pproc)) {
+ _kvm_err(kd, kd->program, "can't read pproc at %x",
+ proc.p_pptr);
+ return (-1);
+ }
+ eproc.e_ppid = pproc.p_pid;
+ } else
+ eproc.e_ppid = 0;
+ eproc.e_sess = pgrp.pg_session;
+ eproc.e_pgid = pgrp.pg_id;
+ eproc.e_jobc = pgrp.pg_jobc;
+ if (KREAD(kd, (u_long)pgrp.pg_session, &sess)) {
+ _kvm_err(kd, kd->program, "can't read session at %x",
+ pgrp.pg_session);
+ return (-1);
+ }
+ (void)memcpy(eproc.e_login, sess.s_login,
+ sizeof(eproc.e_login));
+ if ((proc.p_flag & P_CONTROLT) && sess.s_ttyp != NULL) {
+ if (KREAD(kd, (u_long)sess.s_ttyp, &tty)) {
+ _kvm_err(kd, kd->program,
+ "can't read tty at %x", sess.s_ttyp);
+ return (-1);
+ }
+ eproc.e_tdev = tty.t_dev;
+ eproc.e_tsess = tty.t_session;
+ if (tty.t_pgrp != NULL) {
+ if (KREAD(kd, (u_long)tty.t_pgrp, &pgrp)) {
+ _kvm_err(kd, kd->program,
+ "can't read tpgrp at &x",
+ tty.t_pgrp);
+ return (-1);
+ }
+ eproc.e_tpgid = pgrp.pg_id;
+ } else
+ eproc.e_tpgid = -1;
+ } else
+ eproc.e_tdev = NODEV;
+ eproc.e_flag = sess.s_ttyvp ? EPROC_CTTY : 0;
+ if (sess.s_leader == p)
+ eproc.e_flag |= EPROC_SLEADER;
+ if (proc.p_wmesg)
+ (void)kvm_read(kd, (u_long)proc.p_wmesg,
+ eproc.e_wmesg, WMESGLEN);
+
+#ifdef sparc
+ (void)kvm_read(kd, (u_long)&proc.p_vmspace->vm_rssize,
+ (char *)&eproc.e_vm.vm_rssize,
+ sizeof(eproc.e_vm.vm_rssize));
+ (void)kvm_read(kd, (u_long)&proc.p_vmspace->vm_tsize,
+ (char *)&eproc.e_vm.vm_tsize,
+ 3 * sizeof(eproc.e_vm.vm_rssize)); /* XXX */
+#else
+ (void)kvm_read(kd, (u_long)proc.p_vmspace,
+ (char *)&eproc.e_vm, sizeof(eproc.e_vm));
+#endif
+ eproc.e_xsize = eproc.e_xrssize = 0;
+ eproc.e_xccount = eproc.e_xswrss = 0;
+
+ switch (what) {
+
+ case KERN_PROC_PGRP:
+ if (eproc.e_pgid != (pid_t)arg)
+ continue;
+ break;
+
+ case KERN_PROC_TTY:
+ if ((proc.p_flag & P_CONTROLT) == 0 ||
+ eproc.e_tdev != (dev_t)arg)
+ continue;
+ break;
+ }
+ bcopy(&proc, &bp->kp_proc, sizeof(proc));
+ bcopy(&eproc, &bp->kp_eproc, sizeof(eproc));
+ ++bp;
+ ++cnt;
+ }
+ return (cnt);
+}
+
+/*
+ * Build proc info array by reading in proc list from a crash dump.
+ * Return number of procs read. maxcnt is the max we will read.
+ */
+static int
+kvm_deadprocs(kd, what, arg, a_allproc, a_zombproc, maxcnt)
+ kvm_t *kd;
+ int what, arg;
+ u_long a_allproc;
+ u_long a_zombproc;
+ int maxcnt;
+{
+ register struct kinfo_proc *bp = kd->procbase;
+ register int acnt, zcnt;
+ struct proc *p;
+
+ if (KREAD(kd, a_allproc, &p)) {
+ _kvm_err(kd, kd->program, "cannot read allproc");
+ return (-1);
+ }
+ acnt = kvm_proclist(kd, what, arg, p, bp, maxcnt);
+ if (acnt < 0)
+ return (acnt);
+
+ if (KREAD(kd, a_zombproc, &p)) {
+ _kvm_err(kd, kd->program, "cannot read zombproc");
+ return (-1);
+ }
+ zcnt = kvm_proclist(kd, what, arg, p, bp + acnt, maxcnt - acnt);
+ if (zcnt < 0)
+ zcnt = 0;
+
+ return (acnt + zcnt);
+}
+
+struct kinfo_proc *
+kvm_getprocs(kd, op, arg, cnt)
+ kvm_t *kd;
+ int op, arg;
+ int *cnt;
+{
+ int mib[4], st, nprocs;
+ size_t size;
+
+ if (kd->procbase != 0) {
+ free((void *)kd->procbase);
+ /*
+ * Clear this pointer in case this call fails. Otherwise,
+ * kvm_close() will free it again.
+ */
+ kd->procbase = 0;
+ }
+ if (ISALIVE(kd)) {
+ size = 0;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = op;
+ mib[3] = arg;
+ st = sysctl(mib, op == KERN_PROC_ALL ? 3 : 4, NULL, &size, NULL, 0);
+ if (st == -1) {
+ _kvm_syserr(kd, kd->program, "kvm_getprocs");
+ return (0);
+ }
+ do {
+ size += size / 10;
+ kd->procbase = (struct kinfo_proc *)
+ _kvm_realloc(kd, kd->procbase, size);
+ if (kd->procbase == 0)
+ return (0);
+ st = sysctl(mib, op == KERN_PROC_ALL ? 3 : 4,
+ kd->procbase, &size, NULL, 0);
+ } while (st == -1 && errno == ENOMEM);
+ if (st == -1) {
+ _kvm_syserr(kd, kd->program, "kvm_getprocs");
+ return (0);
+ }
+ if (size % sizeof(struct kinfo_proc) != 0) {
+ _kvm_err(kd, kd->program,
+ "proc size mismatch (%d total, %d chunks)",
+ size, sizeof(struct kinfo_proc));
+ return (0);
+ }
+ nprocs = size / sizeof(struct kinfo_proc);
+ } else {
+ struct nlist nl[4], *p;
+
+ nl[0].n_name = "_nprocs";
+ nl[1].n_name = "_allproc";
+ nl[2].n_name = "_zombproc";
+ nl[3].n_name = 0;
+
+ if (kvm_nlist(kd, nl) != 0) {
+ for (p = nl; p->n_type != 0; ++p)
+ ;
+ _kvm_err(kd, kd->program,
+ "%s: no such symbol", p->n_name);
+ return (0);
+ }
+ if (KREAD(kd, nl[0].n_value, &nprocs)) {
+ _kvm_err(kd, kd->program, "can't read nprocs");
+ return (0);
+ }
+ size = nprocs * sizeof(struct kinfo_proc);
+ kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size);
+ if (kd->procbase == 0)
+ return (0);
+
+ nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value,
+ nl[2].n_value, nprocs);
+#ifdef notdef
+ size = nprocs * sizeof(struct kinfo_proc);
+ (void)realloc(kd->procbase, size);
+#endif
+ }
+ *cnt = nprocs;
+ return (kd->procbase);
+}
+
+void
+_kvm_freeprocs(kd)
+ kvm_t *kd;
+{
+ if (kd->procbase) {
+ free(kd->procbase);
+ kd->procbase = 0;
+ }
+}
+
+void *
+_kvm_realloc(kd, p, n)
+ kvm_t *kd;
+ void *p;
+ size_t n;
+{
+ void *np = (void *)realloc(p, n);
+
+ if (np == 0) {
+ free(p);
+ _kvm_err(kd, kd->program, "out of memory");
+ }
+ return (np);
+}
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+/*
+ * Read in an argument vector from the user address space of process p.
+ * addr if the user-space base address of narg null-terminated contiguous
+ * strings. This is used to read in both the command arguments and
+ * environment strings. Read at most maxcnt characters of strings.
+ */
+static char **
+kvm_argv(kd, p, addr, narg, maxcnt)
+ kvm_t *kd;
+ const struct proc *p;
+ register u_long addr;
+ register int narg;
+ register int maxcnt;
+{
+ register char *np, *cp, *ep, *ap;
+ register u_long oaddr = -1;
+ register int len, cc;
+ register char **argv;
+
+ /*
+ * Check that there aren't an unreasonable number of agruments,
+ * and that the address is in user space.
+ */
+ if (narg > 512 || addr < VM_MIN_ADDRESS || addr >= VM_MAXUSER_ADDRESS)
+ return (0);
+
+ /*
+ * kd->argv : work space for fetching the strings from the target
+ * process's space, and is converted for returning to caller
+ */
+ if (kd->argv == 0) {
+ /*
+ * Try to avoid reallocs.
+ */
+ kd->argc = MAX(narg + 1, 32);
+ kd->argv = (char **)_kvm_malloc(kd, kd->argc *
+ sizeof(*kd->argv));
+ if (kd->argv == 0)
+ return (0);
+ } else if (narg + 1 > kd->argc) {
+ kd->argc = MAX(2 * kd->argc, narg + 1);
+ kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc *
+ sizeof(*kd->argv));
+ if (kd->argv == 0)
+ return (0);
+ }
+ /*
+ * kd->argspc : returned to user, this is where the kd->argv
+ * arrays are left pointing to the collected strings.
+ */
+ if (kd->argspc == 0) {
+ kd->argspc = (char *)_kvm_malloc(kd, PAGE_SIZE);
+ if (kd->argspc == 0)
+ return (0);
+ kd->arglen = PAGE_SIZE;
+ }
+ /*
+ * kd->argbuf : used to pull in pages from the target process.
+ * the strings are copied out of here.
+ */
+ if (kd->argbuf == 0) {
+ kd->argbuf = (char *)_kvm_malloc(kd, PAGE_SIZE);
+ if (kd->argbuf == 0)
+ return (0);
+ }
+
+ /* Pull in the target process'es argv vector */
+ cc = sizeof(char *) * narg;
+ if (kvm_uread(kd, p, addr, (char *)kd->argv, cc) != cc)
+ return (0);
+ /*
+ * ap : saved start address of string we're working on in kd->argspc
+ * np : pointer to next place to write in kd->argspc
+ * len: length of data in kd->argspc
+ * argv: pointer to the argv vector that we are hunting around the
+ * target process space for, and converting to addresses in
+ * our address space (kd->argspc).
+ */
+ ap = np = kd->argspc;
+ argv = kd->argv;
+ len = 0;
+ /*
+ * Loop over pages, filling in the argument vector.
+ * Note that the argv strings could be pointing *anywhere* in
+ * the user address space and are no longer contiguous.
+ * Note that *argv is modified when we are going to fetch a string
+ * that crosses a page boundary. We copy the next part of the string
+ * into to "np" and eventually convert the pointer.
+ */
+ while (argv < kd->argv + narg && *argv != 0) {
+
+ /* get the address that the current argv string is on */
+ addr = (u_long)*argv & ~(PAGE_SIZE - 1);
+
+ /* is it the same page as the last one? */
+ if (addr != oaddr) {
+ if (kvm_uread(kd, p, addr, kd->argbuf, PAGE_SIZE) !=
+ PAGE_SIZE)
+ return (0);
+ oaddr = addr;
+ }
+
+ /* offset within the page... kd->argbuf */
+ addr = (u_long)*argv & (PAGE_SIZE - 1);
+
+ /* cp = start of string, cc = count of chars in this chunk */
+ cp = kd->argbuf + addr;
+ cc = PAGE_SIZE - addr;
+
+ /* dont get more than asked for by user process */
+ if (maxcnt > 0 && cc > maxcnt - len)
+ cc = maxcnt - len;
+
+ /* pointer to end of string if we found it in this page */
+ ep = memchr(cp, '\0', cc);
+ if (ep != 0)
+ cc = ep - cp + 1;
+ /*
+ * at this point, cc is the count of the chars that we are
+ * going to retrieve this time. we may or may not have found
+ * the end of it. (ep points to the null if the end is known)
+ */
+
+ /* will we exceed the malloc/realloced buffer? */
+ if (len + cc > kd->arglen) {
+ register int off;
+ register char **pp;
+ register char *op = kd->argspc;
+
+ kd->arglen *= 2;
+ kd->argspc = (char *)_kvm_realloc(kd, kd->argspc,
+ kd->arglen);
+ if (kd->argspc == 0)
+ return (0);
+ /*
+ * Adjust argv pointers in case realloc moved
+ * the string space.
+ */
+ off = kd->argspc - op;
+ for (pp = kd->argv; pp < argv; pp++)
+ *pp += off;
+ ap += off;
+ np += off;
+ }
+ /* np = where to put the next part of the string in kd->argspc*/
+ /* np is kinda redundant.. could use "kd->argspc + len" */
+ memcpy(np, cp, cc);
+ np += cc; /* inc counters */
+ len += cc;
+
+ /*
+ * if end of string found, set the *argv pointer to the
+ * saved beginning of string, and advance. argv points to
+ * somewhere in kd->argv.. This is initially relative
+ * to the target process, but when we close it off, we set
+ * it to point in our address space.
+ */
+ if (ep != 0) {
+ *argv++ = ap;
+ ap = np;
+ } else {
+ /* update the address relative to the target process */
+ *argv += cc;
+ }
+
+ if (maxcnt > 0 && len >= maxcnt) {
+ /*
+ * We're stopping prematurely. Terminate the
+ * current string.
+ */
+ if (ep == 0) {
+ *np = '\0';
+ *argv++ = ap;
+ }
+ break;
+ }
+ }
+ /* Make sure argv is terminated. */
+ *argv = 0;
+ return (kd->argv);
+}
+
+static void
+ps_str_a(p, addr, n)
+ struct ps_strings *p;
+ u_long *addr;
+ int *n;
+{
+ *addr = (u_long)p->ps_argvstr;
+ *n = p->ps_nargvstr;
+}
+
+static void
+ps_str_e(p, addr, n)
+ struct ps_strings *p;
+ u_long *addr;
+ int *n;
+{
+ *addr = (u_long)p->ps_envstr;
+ *n = p->ps_nenvstr;
+}
+
+/*
+ * Determine if the proc indicated by p is still active.
+ * This test is not 100% foolproof in theory, but chances of
+ * being wrong are very low.
+ */
+static int
+proc_verify(kd, kernp, p)
+ kvm_t *kd;
+ u_long kernp;
+ const struct proc *p;
+{
+ struct kinfo_proc kp;
+ int mib[4];
+ size_t len;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = p->p_pid;
+ len = sizeof(kp);
+ if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1)
+ return (0);
+ return (p->p_pid == kp.kp_proc.p_pid &&
+ (kp.kp_proc.p_stat != SZOMB || p->p_stat == SZOMB));
+}
+
+static char **
+kvm_doargv(kd, kp, nchr, info)
+ kvm_t *kd;
+ const struct kinfo_proc *kp;
+ int nchr;
+ void (*info)(struct ps_strings *, u_long *, int *);
+{
+ register const struct proc *p = &kp->kp_proc;
+ register char **ap;
+ u_long addr;
+ int cnt;
+ static struct ps_strings arginfo;
+ static u_long ps_strings;
+ size_t len;
+
+ if (ps_strings == NULL) {
+ len = sizeof(ps_strings);
+ if (sysctlbyname("kern.ps_strings", &ps_strings, &len, NULL,
+ 0) == -1)
+ ps_strings = PS_STRINGS;
+ }
+
+ /*
+ * Pointers are stored at the top of the user stack.
+ */
+ if (p->p_stat == SZOMB ||
+ kvm_uread(kd, p, ps_strings, (char *)&arginfo,
+ sizeof(arginfo)) != sizeof(arginfo))
+ return (0);
+
+ (*info)(&arginfo, &addr, &cnt);
+ if (cnt == 0)
+ return (0);
+ ap = kvm_argv(kd, p, addr, cnt, nchr);
+ /*
+ * For live kernels, make sure this process didn't go away.
+ */
+ if (ap != 0 && ISALIVE(kd) &&
+ !proc_verify(kd, (u_long)kp->kp_eproc.e_paddr, p))
+ ap = 0;
+ return (ap);
+}
+
+/*
+ * Get the command args. This code is now machine independent.
+ */
+char **
+kvm_getargv(kd, kp, nchr)
+ kvm_t *kd;
+ const struct kinfo_proc *kp;
+ int nchr;
+{
+ int oid[4];
+ int i, l;
+ static int buflen;
+ static char *buf, *p;
+ static char **bufp;
+ static int argc;
+
+ if (!buflen) {
+ l = sizeof(buflen);
+ i = sysctlbyname("kern.ps_arg_cache_limit",
+ &buflen, &l, NULL, 0);
+ if (i == -1) {
+ buflen == 0;
+ } else {
+ buf = malloc(buflen);
+ if (buf == NULL)
+ buflen = 0;
+ argc = 32;
+ bufp = malloc(sizeof(char *) * argc);
+ }
+ }
+ if (buf != NULL) {
+ oid[0] = CTL_KERN;
+ oid[1] = KERN_PROC;
+ oid[2] = KERN_PROC_ARGS;
+ oid[3] = kp->kp_proc.p_pid;
+ l = buflen;
+ i = sysctl(oid, 4, buf, &l, 0, 0);
+ if (i == 0 && l > 0) {
+ i = 0;
+ p = buf;
+ do {
+ bufp[i++] = p;
+ p += strlen(p) + 1;
+ if (i >= argc) {
+ argc += argc;
+ bufp = realloc(bufp,
+ sizeof(char *) * argc);
+ }
+ } while (p < buf + l);
+ bufp[i++] = 0;
+ return (bufp);
+ }
+ }
+ if (kp->kp_proc.p_flag & P_SYSTEM)
+ return (NULL);
+ return (kvm_doargv(kd, kp, nchr, ps_str_a));
+}
+
+char **
+kvm_getenvv(kd, kp, nchr)
+ kvm_t *kd;
+ const struct kinfo_proc *kp;
+ int nchr;
+{
+ return (kvm_doargv(kd, kp, nchr, ps_str_e));
+}
+
+/*
+ * Read from user space. The user context is given by p.
+ */
+ssize_t
+kvm_uread(kd, p, uva, buf, len)
+ kvm_t *kd;
+ register const struct proc *p;
+ register u_long uva;
+ register char *buf;
+ register size_t len;
+{
+ register char *cp;
+ char procfile[MAXPATHLEN];
+ ssize_t amount;
+ int fd;
+
+ if (!ISALIVE(kd)) {
+ _kvm_err(kd, kd->program,
+ "cannot read user space from dead kernel");
+ return (0);
+ }
+
+ sprintf(procfile, "/proc/%d/mem", p->p_pid);
+ fd = open(procfile, O_RDONLY, 0);
+ if (fd < 0) {
+ _kvm_err(kd, kd->program, "cannot open %s", procfile);
+ close(fd);
+ return (0);
+ }
+
+ cp = buf;
+ while (len > 0) {
+ errno = 0;
+ if (lseek(fd, (off_t)uva, 0) == -1 && errno != 0) {
+ _kvm_err(kd, kd->program, "invalid address (%x) in %s",
+ uva, procfile);
+ break;
+ }
+ amount = read(fd, cp, len);
+ if (amount < 0) {
+ _kvm_syserr(kd, kd->program, "error reading %s",
+ procfile);
+ break;
+ }
+ if (amount == 0) {
+ _kvm_err(kd, kd->program, "EOF reading %s", procfile);
+ break;
+ }
+ cp += amount;
+ uva += amount;
+ len -= amount;
+ }
+
+ close(fd);
+ return ((ssize_t)(cp - buf));
+}
diff --git a/lib/libkvm/kvm_read.3 b/lib/libkvm/kvm_read.3
new file mode 100644
index 0000000..f8d5e0a
--- /dev/null
+++ b/lib/libkvm/kvm_read.3
@@ -0,0 +1,93 @@
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software developed by the Computer Systems
+.\" Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+.\" BG 91-66 and contributed to Berkeley.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)kvm_read.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt KVM_READ 3
+.Os
+.Sh NAME
+.Nm kvm_read ,
+.Nm kvm_write
+.Nd read or write kernel virtual memory
+.Sh SYNOPSIS
+.Fd #include <kvm.h>
+.Ft ssize_t
+.Fn kvm_read "kvm_t *kd" "unsigned long addr" "void *buf" "size_t nbytes"
+.Ft ssize_t
+.Fn kvm_write "kvm_t *kd" "unsigned long addr" "const void *buf" "size_t nbytes"
+.Sh DESCRIPTION
+The
+.Fn kvm_read
+and
+.Fn kvm_write
+functions are used to read and write kernel virtual memory (or a crash
+dump file). See
+.Fn kvm_open 3
+or
+.Fn kvm_openfiles 3
+for information regarding opening kernel virtual memory and crash dumps.
+.Pp
+The
+.Fn kvm_read
+function transfers
+.Fa nbytes
+bytes of data from
+the kernel space address
+.Fa addr
+to
+.Fa buf .
+Conversely,
+.Fn kvm_write
+transfers data from
+.Fa buf
+to
+.Fa addr .
+Unlike their SunOS counterparts, these functions cannot be used to
+read or write process address spaces.
+.Sh RETURN VALUES
+Upon success, the number of bytes actually transferred is returned.
+Otherwise, -1 is returned.
+.Sh SEE ALSO
+.Xr kvm 3 ,
+.Xr kvm_close 3 ,
+.Xr kvm_getargv 3 ,
+.Xr kvm_getenvv 3 ,
+.Xr kvm_geterr 3 ,
+.Xr kvm_getprocs 3 ,
+.Xr kvm_nlist 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3
diff --git a/lib/libkvm/kvm_sparc.c b/lib/libkvm/kvm_sparc.c
new file mode 100644
index 0000000..a7b9594
--- /dev/null
+++ b/lib/libkvm/kvm_sparc.c
@@ -0,0 +1,236 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software developed by the Computer Systems
+ * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+ * BG 91-66 and contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm_sparc.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Sparc machine dependent routines for kvm. Hopefully, the forthcoming
+ * vm code will one day obsolete this module.
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <limits.h>
+#include <db.h>
+
+#include "kvm_private.h"
+
+#define NPMEG 128
+
+/* XXX from sparc/pmap.c */
+#define MAXMEM (128 * 1024 * 1024) /* no more than 128 MB phys mem */
+#define NPGBANK 16 /* 2^4 pages per bank (64K / bank) */
+#define BSHIFT 4 /* log2(NPGBANK) */
+#define BOFFSET (NPGBANK - 1)
+#define BTSIZE (MAXMEM / NBPG / NPGBANK)
+#define HWTOSW(pmap_stod, pg) (pmap_stod[(pg) >> BSHIFT] | ((pg) & BOFFSET))
+
+struct vmstate {
+ pmeg_t segmap[NKSEG];
+ int pmeg[NPMEG][NPTESG];
+ int pmap_stod[BTSIZE]; /* dense to sparse */
+};
+
+void
+_kvm_freevtop(kd)
+ kvm_t *kd;
+{
+ if (kd->vmst != 0)
+ free(kd->vmst);
+}
+
+int
+_kvm_initvtop(kd)
+ kvm_t *kd;
+{
+ register int i;
+ register int off;
+ register struct vmstate *vm;
+ struct stat st;
+ struct nlist nlist[2];
+
+ vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
+ if (vm == 0)
+ return (-1);
+
+ kd->vmst = vm;
+
+ if (fstat(kd->pmfd, &st) < 0)
+ return (-1);
+ /*
+ * Read segment table.
+ */
+ off = st.st_size - ctob(btoc(sizeof(vm->segmap)));
+ errno = 0;
+ if (lseek(kd->pmfd, (off_t)off, 0) == -1 && errno != 0 ||
+ read(kd->pmfd, (char *)vm->segmap, sizeof(vm->segmap)) < 0) {
+ _kvm_err(kd, kd->program, "cannot read segment map");
+ return (-1);
+ }
+ /*
+ * Read PMEGs.
+ */
+ off = st.st_size - ctob(btoc(sizeof(vm->pmeg)) +
+ btoc(sizeof(vm->segmap)));
+ errno = 0;
+ if (lseek(kd->pmfd, (off_t)off, 0) == -1 && errno != 0 ||
+ read(kd->pmfd, (char *)vm->pmeg, sizeof(vm->pmeg)) < 0) {
+ _kvm_err(kd, kd->program, "cannot read PMEG table");
+ return (-1);
+ }
+ /*
+ * Make pmap_stod be an identity map so we can bootstrap it in.
+ * We assume it's in the first contiguous chunk of physical memory.
+ */
+ for (i = 0; i < BTSIZE; ++i)
+ vm->pmap_stod[i] = i << 4;
+
+ /*
+ * It's okay to do this nlist separately from the one kvm_getprocs()
+ * does, since the only time we could gain anything by combining
+ * them is if we do a kvm_getprocs() on a dead kernel, which is
+ * not too common.
+ */
+ nlist[0].n_name = "_pmap_stod";
+ nlist[1].n_name = 0;
+ if (kvm_nlist(kd, nlist) != 0) {
+ _kvm_err(kd, kd->program, "pmap_stod: no such symbol");
+ return (-1);
+ }
+ if (kvm_read(kd, (u_long)nlist[0].n_value,
+ (char *)vm->pmap_stod, sizeof(vm->pmap_stod))
+ != sizeof(vm->pmap_stod)) {
+ _kvm_err(kd, kd->program, "cannot read pmap_stod");
+ return (-1);
+ }
+ return (0);
+}
+
+#define VA_OFF(va) (va & (NBPG - 1))
+
+/*
+ * Translate a user virtual address to a physical address.
+ */
+int
+_kvm_uvatop(kd, p, va, pa)
+ kvm_t *kd;
+ const struct proc *p;
+ u_long va;
+ u_long *pa;
+{
+ int kva, pte;
+ register int off, frame;
+ register struct vmspace *vms = p->p_vmspace;
+
+ if ((u_long)vms < KERNBASE) {
+ _kvm_err(kd, kd->program, "_kvm_uvatop: corrupt proc");
+ return (0);
+ }
+ if (va >= KERNBASE)
+ return (0);
+ /*
+ * Get the PTE. This takes two steps. We read the
+ * base address of the table, then we index it.
+ * Note that the index pte table is indexed by
+ * virtual segment rather than physical segment.
+ */
+ kva = (u_long)&vms->vm_pmap.pm_rpte[VA_VSEG(va)];
+ if (kvm_read(kd, kva, (char *)&kva, 4) != 4 || kva == 0)
+ goto invalid;
+ kva += sizeof(vms->vm_pmap.pm_rpte[0]) * VA_VPG(va);
+ if (kvm_read(kd, kva, (char *)&pte, 4) == 4 && (pte & PG_V)) {
+ off = VA_OFF(va);
+ /*
+ * /dev/mem adheres to the hardware model of physical memory
+ * (with holes in the address space), while crashdumps
+ * adhere to the contiguous software model.
+ */
+ if (ISALIVE(kd))
+ frame = pte & PG_PFNUM;
+ else
+ frame = HWTOSW(kd->vmst->pmap_stod, pte & PG_PFNUM);
+ *pa = (frame << PGSHIFT) | off;
+ return (NBPG - off);
+ }
+invalid:
+ _kvm_err(kd, 0, "invalid address (%x)", va);
+ return (0);
+}
+
+/*
+ * Translate a kernel virtual address to a physical address using the
+ * mapping information in kd->vm. Returns the result in pa, and returns
+ * the number of bytes that are contiguously available from this
+ * physical address. This routine is used only for crashdumps.
+ */
+int
+_kvm_kvatop(kd, va, pa)
+ kvm_t *kd;
+ u_long va;
+ u_long *pa;
+{
+ register struct vmstate *vm;
+ register int s;
+ register int pte;
+ register int off;
+
+ if (va >= KERNBASE) {
+ vm = kd->vmst;
+ s = vm->segmap[VA_VSEG(va) - NUSEG];
+ pte = vm->pmeg[s][VA_VPG(va)];
+ if ((pte & PG_V) != 0) {
+ off = VA_OFF(va);
+ *pa = (HWTOSW(vm->pmap_stod, pte & PG_PFNUM)
+ << PGSHIFT) | off;
+
+ return (NBPG - off);
+ }
+ }
+ _kvm_err(kd, 0, "invalid address (%x)", va);
+ return (0);
+}
diff --git a/lib/libm/Makefile b/lib/libm/Makefile
new file mode 100644
index 0000000..0752465
--- /dev/null
+++ b/lib/libm/Makefile
@@ -0,0 +1,168 @@
+# From: @(#)Makefile 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+#
+# ieee - for most IEEE machines, we hope.
+# mc68881 - the, ahem, mc68881.
+# national - for those ieee machines whose floating point implementation
+# has similar byte ordering as the NATIONAL 32016 with 32081.
+# i386 - i387 NPX, currently the same as "national"
+# mips - for MIPS achitecture machines
+# tahoe - for the tahoe double format.
+# vax - for the vax D_floating format
+
+LIB= m
+CFLAGS+=-I${.CURDIR}/common_source
+
+.if (${MACHINE_ARCH} == "ieee")
+
+HARDWARE=${MACHINE_ARCH}
+.PATH: ${.CURDIR}/common_source ${.CURDIR}/common ${.CURDIR}/ieee
+# common_source
+SRCS+= acosh.c asincos.c asinh.c atan.c atanh.c cosh.c erf.c exp.c \
+ exp__E.c expm1.c floor.c fmod.c gamma.c lgamma.c j0.c j1.c \
+ jn.c log.c log10.c log1p.c log__L.c pow.c sinh.c tanh.c
+# common
+SRCS+= atan2.c sincos.c tan.c
+# ieee
+SRCS+= cabs.c cbrt.c support.c
+
+.elif (${MACHINE_ARCH} == "hp300" || ${MACHINE_ARCH} == "luna68k")
+
+HARDWARE=mc68881
+.PATH: ${.CURDIR}/mc68881 ${.CURDIR}/common_source ${.CURDIR}/ieee
+# common_source
+SRCS+= acosh.c asinh.c erf.c exp.c exp__E.c fmod.c gamma.c lgamma.c \
+ j0.c j1.c log.c log__L.c pow.c
+# mc68881
+SRCS+= asincos.s atan.s atan2.c atanh.s cosh.s expm1.s floor.s \
+ log10.s log1p.s sincos.s sinh.s sqrt.s support.s tan.s tanh.s
+# ieee
+SRCS+= cabs.c cbrt.c
+
+.elif (${MACHINE_ARCH} == "i386")
+
+HARDWARE=i387
+.PATH: ${.CURDIR}/common_source ${.CURDIR}/common ${.CURDIR}/ieee
+CFLAGS+= -Dnational
+# common_source
+SRCS+= acosh.c asincos.c asinh.c atan.c atanh.c cosh.c erf.c exp.c \
+ exp__E.c expm1.c floor.c fmod.c gamma.c lgamma.c j0.c j1.c \
+ jn.c log.c log10.c log1p.c log__L.c pow.c sinh.c tanh.c
+# common
+SRCS+= atan2.c sincos.c tan.c
+# ieee
+SRCS+= cabs.c cbrt.c support.c
+
+.elif (${MACHINE_ARCH} == "mips")
+
+HARDWARE=${MACHINE_ARCH}
+.PATH: ${.CURDIR}/common_source ${.CURDIR}/common ${.CURDIR}/ieee
+CFLAGS+= -Dnational
+# common_source
+SRCS+= acosh.c asincos.c asinh.c atan.c atanh.c cosh.c erf.c exp.c \
+ exp__E.c expm1.c floor.c fmod.c gamma.c lgamma.c j0.c j1.c \
+ jn.c log.c log10.c log1p.c log__L.c pow.c sinh.c tanh.c
+# common
+SRCS+= atan2.c sincos.c tan.c
+# ieee
+SRCS+= cabs.c cbrt.c support.c
+
+.elif (${MACHINE_ARCH} == "national")
+
+HARDWARE=${MACHINE_ARCH}
+.PATH: ${.CURDIR}/common_source ${.CURDIR}/common ${.CURDIR}/national \
+.elif (${MACHINE_ARCH} == "national")
+
+HARDWARE=${MACHINE_ARCH}
+.PATH: ${.CURDIR}/common_source ${.CURDIR}/common ${.CURDIR}/national \
+ ${.CURDIR}/ieee
+# common_source
+SRCS+= acosh.c asincos.c asinh.c atan.c atanh.c cosh.c erf.c exp.c \
+ exp__E.c expm1.c floor.c fmod.c gamma.c lgamma.c j0.c j1.c jn.c \
+ log.c log10.c log1p.c log__L.c pow.c sinh.c tanh.c
+# common
+SRCS+= atan2.c sincos.c tan.c
+# national
+SRCS+= sqrt.s support.s
+# ieee
+SRCS+= cabs.c cbrt.c
+
+.elif (${MACHINE_ARCH} == "sparc")
+
+HARDWARE=${MACHINE_ARCH}
+.PATH: ${.CURDIR}/common_source ${.CURDIR}/common ${.CURDIR}/ieee
+# common_source
+SRCS+= acosh.c asincos.c asinh.c atan.c atanh.c cosh.c erf.c exp.c \
+ exp__E.c expm1.c floor.c fmod.c gamma.c lgamma.c j0.c j1.c \
+ jn.c log.c log10.c log1p.c log__L.c pow.c sinh.c tanh.c
+# XXX should do sqrt & support functions in assembly
+# common
+SRCS+= atan2.c sincos.c tan.c
+# ieee
+SRCS+= cabs.c cbrt.c support.c
+
+.elif (${MACHINE_ARCH} == "tahoe")
+
+HARDWARE=${MACHINE_ARCH}
+.PATH: ${.CURDIR}/common_source ${.CURDIR}/common ${.CURDIR}/tahoe \
+# common_source
+SRCS+= acosh.c asincos.c asinh.c atan.c atanh.c cosh.c erf.c exp.c \
+ exp__E.c expm1.c floor.c fmod.c gamma.c lgamma.c j0.c j1.c jn.c \
+ log.c log10.c log1p.c log__L.c pow.c sinh.c tanh.c
+# common
+SRCS+= atan2.c sincos.c tan.c
+# tahoe
+SRCS+= cabs.s cbrt.s sqrt.s support.s infnan.s
+
+.elif (${MACHINE_ARCH} == "vax")
+
+HARDWARE=${MACHINE_ARCH}
+.PATH: ${.CURDIR}/common_source ${.CURDIR}/vax
+# common_source
+SRCS+= acosh.c asincos.c asinh.c atan.c atanh.c cosh.c erf.c exp.c \
+ exp__E.c expm1.c floor.c fmod.c gamma.c lgamma.c j0.c j1.c jn.c \
+ log.c log10.c log1p.c log__L.c pow.c sinh.c tanh.c
+# vax
+SRCS+= atan2.s cabs.s cbrt.s sqrt.s sincos.s tan.s argred.s support.s \
+ infnan.s
+
+.endif
+
+MAN3+= common_source/acos.3 common_source/acosh.3 common_source/asin.3 \
+ common_source/asinh.3 common_source/atan.3 common_source/atan2.3 \
+ common_source/atanh.3 common_source/ceil.3 common_source/cos.3 \
+ common_source/cosh.3 common_source/erf.3 common_source/exp.3 \
+ common_source/fabs.3 common_source/floor.3 common_source/fmod.3 \
+ common_source/hypot.3 common_source/ieee.3 common_source/infnan.3 \
+ common_source/j0.3 common_source/lgamma.3 common_source/math.3 \
+ common_source/rint.3 common_source/sin.3 common_source/sinh.3 \
+ common_source/sqrt.3 common_source/tan.3 common_source/tanh.3
+
+MLINKS+=erf.3 erfc.3
+MLINKS+=exp.3 expm1.3 exp.3 log.3 exp.3 log10.3 exp.3 log1p.3 exp.3 pow.3
+MLINKS+=hypot.3 cabs.3
+MLINKS+=ieee.3 copysign.3 ieee.3 drem.3 ieee.3 finite.3 ieee.3 logb.3 \
+ ieee.3 scalb.3
+MLINKS+=j0.3 j1.3 j0.3 jn.3 j0.3 y0.3 j0.3 y1.3 j0.3 yn.3
+MLINKS+=lgamma.3 gamma.3
+
+# can't use the standard mkdep, because there are some .s files that
+# are using '#' as a comment indicator and cpp thinks it's an undefined
+# control.
+
+depend: .depend
+.depend: ${SRCS}
+ mkdep ${CFLAGS:M-[ID]*} ${.ALLSRC:M*.c}
+
+.include <bsd.lib.mk>
+
+.s.o:
+ ${AS} -o ${.TARGET} ${.IMPSRC}
+ @${LD} -x -r ${.TARGET}
+ @mv -f a.out ${.TARGET}
+
+.s.po:
+ sed -f ${.CURDIR}/${HARDWARE}/mcount.sed ${.IMPSRC} | \
+ ${AS} -o ${.TARGET}
+ @${LD} -X -r ${.TARGET}
+ @mv -f a.out ${.TARGET}
diff --git a/lib/libm/README b/lib/libm/README
new file mode 100644
index 0000000..396d1ee
--- /dev/null
+++ b/lib/libm/README
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * K.C. Ng, with Z-S. Alex Liu, S. McDonald, P. Tang, W. Kahan.
+ * Revised on 5/10/85, 5/13/85, 6/14/85, 8/20/85, 8/27/85, 9/11/85.
+ *
+ * @(#)README 8.1 (Berkeley) 6/4/93
+ */
+
+******************************************************************************
+* This is a description of the upgraded elementary functions (listed in 1). *
+* Bessel functions (j0, j1, jn, y0, y1, yn), floor, and fabs passed over *
+* from 4.2BSD without change except perhaps for the way floating point *
+* exception is signaled on a VAX. Three lines that contain "errno" in erf.c*
+* (error functions erf, erfc) have been deleted to prevent overriding the *
+* system "errno". *
+******************************************************************************
+
+0. Total number of files: 40
+
+ IEEE/Makefile VAX/Makefile VAX/support.s erf.c lgamma.c
+ IEEE/atan2.c VAX/argred.s VAX/tan.s exp.c log.c
+ IEEE/cabs.c VAX/atan2.s acosh.c exp__E.c log10.c
+ IEEE/cbrt.c VAX/cabs.s asincos.c expm1.c log1p.c
+ IEEE/support.c VAX/cbrt.s asinh.c floor.c log__L.c
+ IEEE/trig.c VAX/infnan.s atan.c j0.c pow.c
+ Makefile VAX/sincos.s atanh.c j1.c sinh.c
+ README VAX/sqrt.s cosh.c jn.c tanh.c
+
+1. Functions implemented :
+ (A). Standard elementary functions (total 22) :
+ acos(x) ...in file asincos.c
+ asin(x) ...in file asincos.c
+ atan(x) ...in file atan.c
+ atan2(x,y) ...in files IEEE/atan2.c, VAX/atan2.s
+ sin(x) ...in files IEEE/trig.c, VAX/sincos.s
+ cos(x) ...in files IEEE/trig.c, VAX/sincos.s
+ tan(x) ...in files IEEE/trig.c, VAX/tan.s
+ cabs(x,y) ...in files IEEE/cabs.c, VAX/cabs.s
+ hypot(x,y) ...in files IEEE/cabs.c, VAX/cabs.s
+ cbrt(x) ...in files IEEE/cbrt.c, VAX/cbrt.s
+ exp(x) ...in file exp.c
+ expm1(x):=exp(x)-1 ...in file expm1.c
+ log(x) ...in file log.c
+ log10(x) ...in file log10.c
+ log1p(x):=log(1+x) ...in file log1p.c
+ pow(x,y) ...in file pow.c
+ sinh(x) ...in file sinh.c
+ cosh(x) ...in file cosh.c
+ tanh(x) ...in file tanh.c
+ asinh(x) ...in file asinh.c
+ acosh(x) ...in file acosh.c
+ atanh(x) ...in file atanh.c
+
+ (B). Kernel functions :
+ exp__E(x,c) ...in file exp__E.c, used by expm1/exp/pow/cosh
+ log__L(s) ...in file log__L.c, used by log1p/log/pow
+ libm$argred ...in file VAX/argred.s, used by VAX version of sin/cos/tan
+
+ (C). System supported functions :
+ sqrt() ...in files IEEE/support.c, VAX/sqrt.s
+ drem() ...in files IEEE/support.c, VAX/support.s
+ finite() ...in files IEEE/support.c, VAX/support.s
+ logb() ...in files IEEE/support.c, VAX/support.s
+ scalb() ...in files IEEE/support.c, VAX/support.s
+ copysign() ...in files IEEE/support.c, VAX/support.s
+ rint() ...in file floor.c
+
+
+ Notes:
+ i. The codes in files ending with ".s" are written in VAX assembly
+ language. They are intended for VAX computers.
+
+ Files that end with ".c" are written in C. They are intended
+ for either a VAX or a machine that conforms to the IEEE
+ standard 754 for double precision floating-point arithmetic.
+
+ ii. On other than VAX or IEEE machines, run the original math
+ library, formerly "/usr/lib/libm.a", now "/usr/lib/libom.a", if
+ nothing better is available.
+
+ iii. The trigonometric functions sin/cos/tan/atan2 in files "VAX/sincos.s",
+ "VAX/tan.s" and "VAX/atan2.s" are different from those in
+ "IEEE/trig.c" and "IEEE/atan2.c". The VAX assembler code uses the
+ true value of pi to perform argument reduction, while the C code uses
+ a machine value of PI (see "IEEE/trig.c").
+
+
+2. A computer system that conforms to IEEE standard 754 should provide
+ sqrt(x),
+ drem(x,p), (double precision remainder function)
+ copysign(x,y),
+ finite(x),
+ scalb(x,N),
+ logb(x) and
+ rint(x).
+ These functions are either required or recommended by the standard.
+ For convenience, a (slow) C implementation of these functions is
+ provided in the file "IEEE/support.c".
+
+ Warning: The functions in IEEE/support.c are somewhat machine dependent.
+ Some modifications may be necessary to run them on a different machine.
+ Currently, if compiled with a suitable flag, "IEEE/support.c" will work
+ on a National 32000, a Zilog 8000, a VAX, and a SUN (cf. the "Makefile"
+ in this directory). Invoke the C compiler thus:
+
+ cc -c -DVAX IEEE/support.c ... on a VAX, D-format
+ cc -c -DNATIONAL IEEE/support.c ... on a National 32000
+ cc -c IEEE/support.c ... on other IEEE machines,
+ we hope.
+
+ Notes:
+ 1. Faster versions of "drem" and "sqrt" for IEEE double precision
+ (coded in C but intended for assembly language) are given at the
+ end of "IEEE/support.c" but commented out since they require certain
+ machine-dependent functions.
+
+ 2. A fast VAX assembler version of the system supported functions
+ copysign(), logb(), scalb(), finite(), and drem() appears in file
+ "VAX/support.s". A fast VAX assembler version of sqrt() is in
+ file "VAX/sqrt.s".
+
+3. Two formats are supported by all the standard elementary functions:
+ the VAX D-format (56-bit precision), and the IEEE double format
+ (53-bit precision). The cbrt() in "IEEE/cbrt.c" is for IEEE machines
+ only. The functions in files that end with ".s" are for VAX computers
+ only. The functions in files that end with ".c" (except "IEEE/cbrt.c")
+ are for VAX and IEEE machines. To use the VAX D-format, compile the code
+ with -DVAX; to use IEEE double format on various IEEE machines, see
+ "Makefile" in this directory).
+
+ Example:
+ cc -c -DVAX sin.c ... for VAX D-format
+
+ Warning: The values of floating-point constants used in the code are
+ given in both hexadecimal and decimal. The hexadecimal values
+ are the intended ones. The decimal values may be used provided
+ that the compiler converts from decimal to binary accurately
+ enough to produce the hexadecimal values shown. If the
+ conversion is inaccurate, then one must know the exact machine
+ representation of the constants and alter the assembly
+ language output from the compiler, or play tricks like
+ the following in a C program.
+
+ Example: to store the floating-point constant
+
+ p1= 2^-6 * .F83ABE67E1066A (Hexadecimal)
+
+ on a VAX in C, we use two longwords to store its
+ machine value and define p1 to be the double constant
+ at the location of these two longwords:
+
+ static long p1x[] = { 0x3abe3d78, 0x066a67e1};
+ #define p1 (*(double*)p1x)
+
+ Note: On a VAX, some functions have two codes. For example, cabs() has
+ one implementation in "IEEE/cabs.c", and another in "VAX/cabs.s".
+ In this case, the assembly language version is preferred.
+
+
+4. Accuracy.
+
+ The errors in expm1(), log1p(), exp(), log(), cabs(), hypot()
+ and cbrt() are below 1 ULP (Unit in the Last Place).
+
+ The error in pow(x,y) grows with the size of y. Nevertheless,
+ for integers x and y, pow(x,y) returns the correct integer value
+ on all tested machines (VAX, SUN, NATIONAL, ZILOG), provided that
+ x to the power of y is representable exactly.
+
+ cosh, sinh, acosh, asinh, tanh, atanh and log10 have errors below
+ about 3 ULPs.
+
+ For trigonometric and inverse trigonometric functions:
+
+ Let [trig(x)] denote the value actually computed for trig(x),
+
+ 1) Those codes using the machine's value PI (true pi rounded):
+ (source codes: IEEE/{trig.c,atan2.c}, asincos.c and atan.c)
+
+ The errors in [sin(x)], [cos(x)], and [atan(x)] are below
+ 1 ULP compared with sin(x*pi/PI), cos(x*pi/PI), and
+ atan(x)*PI/pi respectively, where PI is the machine's
+ value of pi rounded. [tan(x)] returns tan(x*pi/PI) within
+ about 2 ULPs; [acos(x)], [asin(x)], and [atan2(y,x)]
+ return acos(x)*PI/pi, asin(x)*PI/pi, and atan2(y,x)*PI/pi
+ respectively to similar accuracy.
+
+
+ 2) Those using true pi (for VAX D-format only):
+ (source codes: VAX/{sincos.s,tan.s,atan2.s}, asincos.c and
+ atan.c)
+
+ The errors in [sin(x)], [cos(x)], and [atan(x)] are below
+ 1 ULP. [tan(x)], [atan2(y,x)], [acos(x)], and [asin(x)]
+ have errors below about 2 ULPs.
+
+
+ Here are the results of some test runs to find worst errors on
+ the VAX :
+
+ tan : 2.09 ULPs ...1,024,000 random arguments (machine PI)
+ sin : .861 ULPs ...1,024,000 random arguments (machine PI)
+ cos : .857 ULPs ...1,024,000 random arguments (machine PI)
+ (compared with tan, sin, cos of (x*pi/PI))
+
+ acos : 2.07 ULPs .....200,000 random arguments (machine PI)
+ asin : 2.06 ULPs .....200,000 random arguments (machine PI)
+ atan2 : 1.41 ULPs .....356,000 random arguments (machine PI)
+ atan : 0.86 ULPs ...1,536,000 random arguments (machine PI)
+ (compared with (PI/pi)*(atan, asin, acos, atan2 of x))
+
+ tan : 2.15 ULPs ...1,024,000 random arguments (true pi)
+ sin : .814 ULPs ...1,024,000 random arguments (true pi)
+ cos : .792 ULPs ...1,024,000 random arguments (true pi)
+ acos : 2.15 ULPs ...1,024,000 random arguments (true pi)
+ asin : 1.99 ULPs ...1,024,000 random arguments (true pi)
+ atan2 : 1.48 ULPs ...1,024,000 random arguments (true pi)
+ atan : .850 ULPs ...1,024,000 random arguments (true pi)
+
+ acosh : 3.30 ULPs .....512,000 random arguments
+ asinh : 1.58 ULPs .....512,000 random arguments
+ atanh : 1.71 ULPs .....512,000 random arguments
+ cosh : 1.23 ULPs .....768,000 random arguments
+ sinh : 1.93 ULPs ...1,024,000 random arguments
+ tanh : 2.22 ULPs ...1,024,000 random arguments
+ log10 : 1.74 ULPs ...1,536,000 random arguments
+ pow : 1.79 ULPs .....100,000 random arguments, 0 < x, y < 20.
+
+ exp : .768 ULPs ...1,156,000 random arguments
+ expm1 : .844 ULPs ...1,166,000 random arguments
+ log1p : .846 ULPs ...1,536,000 random arguments
+ log : .826 ULPs ...1,536,000 random arguments
+ cabs : .959 ULPs .....500,000 random arguments
+ cbrt : .666 ULPs ...5,120,000 random arguments
+
+
+5. Speed.
+
+ Some functions coded in VAX assembly language (cabs(), hypot() and
+ sqrt()) are significantly faster than the corresponding ones in 4.2BSD.
+ In general, to improve performance, all functions in "IEEE/support.c"
+ should be written in assembly language and, whenever possible, should
+ be called via short subroutine calls.
+
+
+6. j0, j1, jn.
+
+ The modifications to these routines were only in how an invalid
+ floating point operations is signaled.
diff --git a/lib/libm/common/atan2.c b/lib/libm/common/atan2.c
new file mode 100644
index 0000000..b847a1d
--- /dev/null
+++ b/lib/libm/common/atan2.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)atan2.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ATAN2(Y,X)
+ * RETURN ARG (X+iY)
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/8/85;
+ * REVISED BY K.C. NG on 2/7/85, 2/13/85, 3/7/85, 3/30/85, 6/29/85.
+ *
+ * Required system supported functions :
+ * copysign(x,y)
+ * scalb(x,y)
+ * logb(x)
+ *
+ * Method :
+ * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
+ * 2. Reduce x to positive by (if x and y are unexceptional):
+ * ARG (x+iy) = arctan(y/x) ... if x > 0,
+ * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
+ * 3. According to the integer k=4t+0.25 truncated , t=y/x, the argument
+ * is further reduced to one of the following intervals and the
+ * arctangent of y/x is evaluated by the corresponding formula:
+ *
+ * [0,7/16] atan(y/x) = t - t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
+ * [7/16,11/16] atan(y/x) = atan(1/2) + atan( (y-x/2)/(x+y/2) )
+ * [11/16.19/16] atan(y/x) = atan( 1 ) + atan( (y-x)/(x+y) )
+ * [19/16,39/16] atan(y/x) = atan(3/2) + atan( (y-1.5x)/(x+1.5y) )
+ * [39/16,INF] atan(y/x) = atan(INF) + atan( -x/y )
+ *
+ * Special cases:
+ * Notations: atan2(y,x) == ARG (x+iy) == ARG(x,y).
+ *
+ * ARG( NAN , (anything) ) is NaN;
+ * ARG( (anything), NaN ) is NaN;
+ * ARG(+(anything but NaN), +-0) is +-0 ;
+ * ARG(-(anything but NaN), +-0) is +-PI ;
+ * ARG( 0, +-(anything but 0 and NaN) ) is +-PI/2;
+ * ARG( +INF,+-(anything but INF and NaN) ) is +-0 ;
+ * ARG( -INF,+-(anything but INF and NaN) ) is +-PI;
+ * ARG( +INF,+-INF ) is +-PI/4 ;
+ * ARG( -INF,+-INF ) is +-3PI/4;
+ * ARG( (anything but,0,NaN, and INF),+-INF ) is +-PI/2;
+ *
+ * Accuracy:
+ * atan2(y,x) returns (PI/pi) * the exact ARG (x+iy) nearly rounded,
+ * where
+ *
+ * in decimal:
+ * pi = 3.141592653589793 23846264338327 .....
+ * 53 bits PI = 3.141592653589793 115997963 ..... ,
+ * 56 bits PI = 3.141592653589793 227020265 ..... ,
+ *
+ * in hexadecimal:
+ * pi = 3.243F6A8885A308D313198A2E....
+ * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18 error=.276ulps
+ * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2 error=.206ulps
+ *
+ * In a test run with 356,000 random argument on [-1,1] * [-1,1] on a
+ * VAX, the maximum observed error was 1.41 ulps (units of the last place)
+ * compared with (PI/pi)*(the exact ARG(x+iy)).
+ *
+ * Note:
+ * We use machine PI (the true pi rounded) in place of the actual
+ * value of pi for all the trig and inverse trig functions. In general,
+ * if trig is one of sin, cos, tan, then computed trig(y) returns the
+ * exact trig(y*pi/PI) nearly rounded; correspondingly, computed arctrig
+ * returns the exact arctrig(y)*PI/pi nearly rounded. These guarantee the
+ * trig functions have period PI, and trig(arctrig(x)) returns x for
+ * all critical values x.
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(athfhi, 4.6364760900080611433E-1 ,6338,3fed,da7b,2b0d, -1, .ED63382B0DDA7B)
+vc(athflo, 1.9338828231967579916E-19 ,5005,2164,92c0,9cfe, -62, .E450059CFE92C0)
+vc(PIo4, 7.8539816339744830676E-1 ,0fda,4049,68c2,a221, 0, .C90FDAA22168C2)
+vc(at1fhi, 9.8279372324732906796E-1 ,985e,407b,b4d9,940f, 0, .FB985E940FB4D9)
+vc(at1flo,-3.5540295636764633916E-18 ,1edc,a383,eaea,34d6, -57,-.831EDC34D6EAEA)
+vc(PIo2, 1.5707963267948966135E0 ,0fda,40c9,68c2,a221, 1, .C90FDAA22168C2)
+vc(PI, 3.1415926535897932270E0 ,0fda,4149,68c2,a221, 2, .C90FDAA22168C2)
+vc(a1, 3.3333333333333473730E-1 ,aaaa,3faa,ab75,aaaa, -1, .AAAAAAAAAAAB75)
+vc(a2, -2.0000000000017730678E-1 ,cccc,bf4c,946e,cccd, -2,-.CCCCCCCCCD946E)
+vc(a3, 1.4285714286694640301E-1 ,4924,3f12,4262,9274, -2, .92492492744262)
+vc(a4, -1.1111111135032672795E-1 ,8e38,bee3,6292,ebc6, -3,-.E38E38EBC66292)
+vc(a5, 9.0909091380563043783E-2 ,2e8b,3eba,d70c,b31b, -3, .BA2E8BB31BD70C)
+vc(a6, -7.6922954286089459397E-2 ,89c8,be9d,7f18,27c3, -3,-.9D89C827C37F18)
+vc(a7, 6.6663180891693915586E-2 ,86b4,3e88,9e58,ae37, -3, .8886B4AE379E58)
+vc(a8, -5.8772703698290408927E-2 ,bba5,be70,a942,8481, -4,-.F0BBA58481A942)
+vc(a9, 5.2170707402812969804E-2 ,b0f3,3e55,13ab,a1ab, -4, .D5B0F3A1AB13AB)
+vc(a10, -4.4895863157820361210E-2 ,e4b9,be37,048f,7fd1, -4,-.B7E4B97FD1048F)
+vc(a11, 3.3006147437343875094E-2 ,3174,3e07,2d87,3cf7, -4, .8731743CF72D87)
+vc(a12, -1.4614844866464185439E-2 ,731a,bd6f,76d9,2f34, -6,-.EF731A2F3476D9)
+
+ic(athfhi, 4.6364760900080609352E-1 , -2, 1.DAC670561BB4F)
+ic(athflo, 4.6249969567426939759E-18 , -58, 1.5543B8F253271)
+ic(PIo4, 7.8539816339744827900E-1 , -1, 1.921FB54442D18)
+ic(at1fhi, 9.8279372324732905408E-1 , -1, 1.F730BD281F69B)
+ic(at1flo,-2.4407677060164810007E-17 , -56, -1.C23DFEFEAE6B5)
+ic(PIo2, 1.5707963267948965580E0 , 0, 1.921FB54442D18)
+ic(PI, 3.1415926535897931160E0 , 1, 1.921FB54442D18)
+ic(a1, 3.3333333333333942106E-1 , -2, 1.55555555555C3)
+ic(a2, -1.9999999999979536924E-1 , -3, -1.9999999997CCD)
+ic(a3, 1.4285714278004377209E-1 , -3, 1.24924921EC1D7)
+ic(a4, -1.1111110579344973814E-1 , -4, -1.C71C7059AF280)
+ic(a5, 9.0908906105474668324E-2 , -4, 1.745CE5AA35DB2)
+ic(a6, -7.6919217767468239799E-2 , -4, -1.3B0FA54BEC400)
+ic(a7, 6.6614695906082474486E-2 , -4, 1.10DA924597FFF)
+ic(a8, -5.8358371008508623523E-2 , -5, -1.DE125FDDBD793)
+ic(a9, 4.9850617156082015213E-2 , -5, 1.9860524BDD807)
+ic(a10, -3.6700606902093604877E-2 , -5, -1.2CA6C04C6937A)
+ic(a11, 1.6438029044759730479E-2 , -6, 1.0D52174A1BB54)
+
+#ifdef vccast
+#define athfhi vccast(athfhi)
+#define athflo vccast(athflo)
+#define PIo4 vccast(PIo4)
+#define at1fhi vccast(at1fhi)
+#define at1flo vccast(at1flo)
+#define PIo2 vccast(PIo2)
+#define PI vccast(PI)
+#define a1 vccast(a1)
+#define a2 vccast(a2)
+#define a3 vccast(a3)
+#define a4 vccast(a4)
+#define a5 vccast(a5)
+#define a6 vccast(a6)
+#define a7 vccast(a7)
+#define a8 vccast(a8)
+#define a9 vccast(a9)
+#define a10 vccast(a10)
+#define a11 vccast(a11)
+#define a12 vccast(a12)
+#endif
+
+double atan2(y,x)
+double y,x;
+{
+ static const double zero=0, one=1, small=1.0E-9, big=1.0E18;
+ double t,z,signy,signx,hi,lo;
+ int k,m;
+
+#if !defined(vax)&&!defined(tahoe)
+ /* if x or y is NAN */
+ if(x!=x) return(x); if(y!=y) return(y);
+#endif /* !defined(vax)&&!defined(tahoe) */
+
+ /* copy down the sign of y and x */
+ signy = copysign(one,y) ;
+ signx = copysign(one,x) ;
+
+ /* if x is 1.0, goto begin */
+ if(x==1) { y=copysign(y,one); t=y; if(finite(t)) goto begin;}
+
+ /* when y = 0 */
+ if(y==zero) return((signx==one)?y:copysign(PI,signy));
+
+ /* when x = 0 */
+ if(x==zero) return(copysign(PIo2,signy));
+
+ /* when x is INF */
+ if(!finite(x))
+ if(!finite(y))
+ return(copysign((signx==one)?PIo4:3*PIo4,signy));
+ else
+ return(copysign((signx==one)?zero:PI,signy));
+
+ /* when y is INF */
+ if(!finite(y)) return(copysign(PIo2,signy));
+
+ /* compute y/x */
+ x=copysign(x,one);
+ y=copysign(y,one);
+ if((m=(k=logb(y))-logb(x)) > 60) t=big+big;
+ else if(m < -80 ) t=y/x;
+ else { t = y/x ; y = scalb(y,-k); x=scalb(x,-k); }
+
+ /* begin argument reduction */
+begin:
+ if (t < 2.4375) {
+
+ /* truncate 4(t+1/16) to integer for branching */
+ k = 4 * (t+0.0625);
+ switch (k) {
+
+ /* t is in [0,7/16] */
+ case 0:
+ case 1:
+ if (t < small)
+ { big + small ; /* raise inexact flag */
+ return (copysign((signx>zero)?t:PI-t,signy)); }
+
+ hi = zero; lo = zero; break;
+
+ /* t is in [7/16,11/16] */
+ case 2:
+ hi = athfhi; lo = athflo;
+ z = x+x;
+ t = ( (y+y) - x ) / ( z + y ); break;
+
+ /* t is in [11/16,19/16] */
+ case 3:
+ case 4:
+ hi = PIo4; lo = zero;
+ t = ( y - x ) / ( x + y ); break;
+
+ /* t is in [19/16,39/16] */
+ default:
+ hi = at1fhi; lo = at1flo;
+ z = y-x; y=y+y+y; t = x+x;
+ t = ( (z+z)-x ) / ( t + y ); break;
+ }
+ }
+ /* end of if (t < 2.4375) */
+
+ else
+ {
+ hi = PIo2; lo = zero;
+
+ /* t is in [2.4375, big] */
+ if (t <= big) t = - x / y;
+
+ /* t is in [big, INF] */
+ else
+ { big+small; /* raise inexact flag */
+ t = zero; }
+ }
+ /* end of argument reduction */
+
+ /* compute atan(t) for t in [-.4375, .4375] */
+ z = t*t;
+#if defined(vax)||defined(tahoe)
+ z = t*(z*(a1+z*(a2+z*(a3+z*(a4+z*(a5+z*(a6+z*(a7+z*(a8+
+ z*(a9+z*(a10+z*(a11+z*a12))))))))))));
+#else /* defined(vax)||defined(tahoe) */
+ z = t*(z*(a1+z*(a2+z*(a3+z*(a4+z*(a5+z*(a6+z*(a7+z*(a8+
+ z*(a9+z*(a10+z*a11)))))))))));
+#endif /* defined(vax)||defined(tahoe) */
+ z = lo - z; z += t; z += hi;
+
+ return(copysign((signx>zero)?z:PI-z,signy));
+}
diff --git a/lib/libm/common/sincos.c b/lib/libm/common/sincos.c
new file mode 100644
index 0000000..fc35618
--- /dev/null
+++ b/lib/libm/common/sincos.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)sincos.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include "trig.h"
+double
+sin(x)
+double x;
+{
+ double a,c,z;
+
+ if(!finite(x)) /* sin(NaN) and sin(INF) must be NaN */
+ return x-x;
+ x=drem(x,PI2); /* reduce x into [-PI,PI] */
+ a=copysign(x,one);
+ if (a >= PIo4) {
+ if(a >= PI3o4) /* ... in [3PI/4,PI] */
+ x = copysign((a = PI-a),x);
+ else { /* ... in [PI/4,3PI/4] */
+ a = PIo2-a; /* rtn. sign(x)*C(PI/2-|x|) */
+ z = a*a;
+ c = cos__C(z);
+ z *= half;
+ a = (z >= thresh ? half-((z-half)-c) : one-(z-c));
+ return copysign(a,x);
+ }
+ }
+
+ if (a < small) { /* rtn. S(x) */
+ big+a;
+ return x;
+ }
+ return x+x*sin__S(x*x);
+}
+
+double
+cos(x)
+double x;
+{
+ double a,c,z,s = 1.0;
+
+ if(!finite(x)) /* cos(NaN) and cos(INF) must be NaN */
+ return x-x;
+ x=drem(x,PI2); /* reduce x into [-PI,PI] */
+ a=copysign(x,one);
+ if (a >= PIo4) {
+ if (a >= PI3o4) { /* ... in [3PI/4,PI] */
+ a = PI-a;
+ s = negone;
+ }
+ else { /* ... in [PI/4,3PI/4] */
+ a = PIo2-a;
+ return a+a*sin__S(a*a); /* rtn. S(PI/2-|x|) */
+ }
+ }
+ if (a < small) {
+ big+a;
+ return s; /* rtn. s*C(a) */
+ }
+ z = a*a;
+ c = cos__C(z);
+ z *= half;
+ a = (z >= thresh ? half-((z-half)-c) : one-(z-c));
+ return copysign(a,s);
+}
diff --git a/lib/libm/common/tan.c b/lib/libm/common/tan.c
new file mode 100644
index 0000000..7b49bce
--- /dev/null
+++ b/lib/libm/common/tan.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tan.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include "trig.h"
+double
+tan(x)
+double x;
+{
+ double a,z,ss,cc,c;
+ int k;
+
+ if(!finite(x)) /* tan(NaN) and tan(INF) must be NaN */
+ return x-x;
+ x = drem(x,PI); /* reduce x into [-PI/2, PI/2] */
+ a = copysign(x,one); /* ... = abs(x) */
+ if (a >= PIo4) {
+ k = 1;
+ x = copysign(PIo2-a,x);
+ }
+ else {
+ k = 0;
+ if (a < small) {
+ big+a;
+ return x;
+ }
+ }
+ z = x*x;
+ cc = cos__C(z);
+ ss = sin__S(z);
+ z *= half; /* Next get c = cos(x) accurately */
+ c = (z >= thresh ? half-((z-half)-cc) : one-(z-cc));
+ if (k == 0)
+ return x+(x*(z-(cc-ss)))/c; /* ... sin/cos */
+#ifdef national
+ else if (x == zero)
+ return copysign(fmax,x); /* no inf on 32k */
+#endif /* national */
+ else
+ return c/(x+x*ss); /* ... cos/sin */
+}
diff --git a/lib/libm/common/trig.h b/lib/libm/common/trig.h
new file mode 100644
index 0000000..e31fb4c
--- /dev/null
+++ b/lib/libm/common/trig.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)trig.h 8.1 (Berkeley) 6/4/93
+ */
+
+#include "mathimpl.h"
+
+vc(thresh, 2.6117239648121182150E-1 ,b863,3f85,6ea0,6b02, -1, .85B8636B026EA0)
+vc(PIo4, 7.8539816339744830676E-1 ,0fda,4049,68c2,a221, 0, .C90FDAA22168C2)
+vc(PIo2, 1.5707963267948966135E0 ,0fda,40c9,68c2,a221, 1, .C90FDAA22168C2)
+vc(PI3o4, 2.3561944901923449203E0 ,cbe3,4116,0e92,f999, 2, .96CBE3F9990E92)
+vc(PI, 3.1415926535897932270E0 ,0fda,4149,68c2,a221, 2, .C90FDAA22168C2)
+vc(PI2, 6.2831853071795864540E0 ,0fda,41c9,68c2,a221, 3, .C90FDAA22168C2)
+
+ic(thresh, 2.6117239648121182150E-1 , -2, 1.0B70C6D604DD4)
+ic(PIo4, 7.8539816339744827900E-1 , -1, 1.921FB54442D18)
+ic(PIo2, 1.5707963267948965580E0 , 0, 1.921FB54442D18)
+ic(PI3o4, 2.3561944901923448370E0 , 1, 1.2D97C7F3321D2)
+ic(PI, 3.1415926535897931160E0 , 1, 1.921FB54442D18)
+ic(PI2, 6.2831853071795862320E0 , 2, 1.921FB54442D18)
+
+#ifdef vccast
+#define thresh vccast(thresh)
+#define PIo4 vccast(PIo4)
+#define PIo2 vccast(PIo2)
+#define PI3o4 vccast(PI3o4)
+#define PI vccast(PI)
+#define PI2 vccast(PI2)
+#endif
+
+#ifdef national
+static long fmaxx[] = { 0xffffffff, 0x7fefffff};
+#define fmax (*(double*)fmaxx)
+#endif /* national */
+
+static const double
+ zero = 0,
+ one = 1,
+ negone = -1,
+ half = 1.0/2.0,
+ small = 1E-10, /* 1+small**2 == 1; better values for small:
+ * small = 1.5E-9 for VAX D
+ * = 1.2E-8 for IEEE Double
+ * = 2.8E-10 for IEEE Extended
+ */
+ big = 1E20; /* big := 1/(small**2) */
+
+/* sin__S(x*x) ... re-implemented as a macro
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * STATIC KERNEL FUNCTION OF SIN(X), COS(X), AND TAN(X)
+ * CODED IN C BY K.C. NG, 1/21/85;
+ * REVISED BY K.C. NG on 8/13/85.
+ *
+ * sin(x*k) - x
+ * RETURN --------------- on [-PI/4,PI/4] , where k=pi/PI, PI is the rounded
+ * x
+ * value of pi in machine precision:
+ *
+ * Decimal:
+ * pi = 3.141592653589793 23846264338327 .....
+ * 53 bits PI = 3.141592653589793 115997963 ..... ,
+ * 56 bits PI = 3.141592653589793 227020265 ..... ,
+ *
+ * Hexadecimal:
+ * pi = 3.243F6A8885A308D313198A2E....
+ * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18
+ * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2
+ *
+ * Method:
+ * 1. Let z=x*x. Create a polynomial approximation to
+ * (sin(k*x)-x)/x = z*(S0 + S1*z^1 + ... + S5*z^5).
+ * Then
+ * sin__S(x*x) = z*(S0 + S1*z^1 + ... + S5*z^5)
+ *
+ * The coefficient S's are obtained by a special Remez algorithm.
+ *
+ * Accuracy:
+ * In the absence of rounding error, the approximation has absolute error
+ * less than 2**(-61.11) for VAX D FORMAT, 2**(-57.45) for IEEE DOUBLE.
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ *
+ */
+
+vc(S0, -1.6666666666666646660E-1 ,aaaa,bf2a,aa71,aaaa, -2, -.AAAAAAAAAAAA71)
+vc(S1, 8.3333333333297230413E-3 ,8888,3d08,477f,8888, -6, .8888888888477F)
+vc(S2, -1.9841269838362403710E-4 ,0d00,ba50,1057,cf8a, -12, -.D00D00CF8A1057)
+vc(S3, 2.7557318019967078930E-6 ,ef1c,3738,bedc,a326, -18, .B8EF1CA326BEDC)
+vc(S4, -2.5051841873876551398E-8 ,3195,b3d7,e1d3,374c, -25, -.D73195374CE1D3)
+vc(S5, 1.6028995389845827653E-10 ,3d9c,3030,cccc,6d26, -32, .B03D9C6D26CCCC)
+vc(S6, -6.2723499671769283121E-13 ,8d0b,ac30,ea82,7561, -40, -.B08D0B7561EA82)
+
+ic(S0, -1.6666666666666463126E-1 , -3, -1.555555555550C)
+ic(S1, 8.3333333332992771264E-3 , -7, 1.111111110C461)
+ic(S2, -1.9841269816180999116E-4 , -13, -1.A01A019746345)
+ic(S3, 2.7557309793219876880E-6 , -19, 1.71DE3209CDCD9)
+ic(S4, -2.5050225177523807003E-8 , -26, -1.AE5C0E319A4EF)
+ic(S5, 1.5868926979889205164E-10 , -33, 1.5CF61DF672B13)
+
+#ifdef vccast
+#define S0 vccast(S0)
+#define S1 vccast(S1)
+#define S2 vccast(S2)
+#define S3 vccast(S3)
+#define S4 vccast(S4)
+#define S5 vccast(S5)
+#define S6 vccast(S6)
+#endif
+
+#if defined(vax)||defined(tahoe)
+# define sin__S(z) (z*(S0+z*(S1+z*(S2+z*(S3+z*(S4+z*(S5+z*S6)))))))
+#else /* defined(vax)||defined(tahoe) */
+# define sin__S(z) (z*(S0+z*(S1+z*(S2+z*(S3+z*(S4+z*S5))))))
+#endif /* defined(vax)||defined(tahoe) */
+
+/* cos__C(x*x) ... re-implemented as a macro
+ * DOUBLE PRECISION (VAX D FORMAT 56 BITS, IEEE DOUBLE 53 BITS)
+ * STATIC KERNEL FUNCTION OF SIN(X), COS(X), AND TAN(X)
+ * CODED IN C BY K.C. NG, 1/21/85;
+ * REVISED BY K.C. NG on 8/13/85.
+ *
+ * x*x
+ * RETURN cos(k*x) - 1 + ----- on [-PI/4,PI/4], where k = pi/PI,
+ * 2
+ * PI is the rounded value of pi in machine precision :
+ *
+ * Decimal:
+ * pi = 3.141592653589793 23846264338327 .....
+ * 53 bits PI = 3.141592653589793 115997963 ..... ,
+ * 56 bits PI = 3.141592653589793 227020265 ..... ,
+ *
+ * Hexadecimal:
+ * pi = 3.243F6A8885A308D313198A2E....
+ * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18
+ * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2
+ *
+ *
+ * Method:
+ * 1. Let z=x*x. Create a polynomial approximation to
+ * cos(k*x)-1+z/2 = z*z*(C0 + C1*z^1 + ... + C5*z^5)
+ * then
+ * cos__C(z) = z*z*(C0 + C1*z^1 + ... + C5*z^5)
+ *
+ * The coefficient C's are obtained by a special Remez algorithm.
+ *
+ * Accuracy:
+ * In the absence of rounding error, the approximation has absolute error
+ * less than 2**(-64) for VAX D FORMAT, 2**(-58.3) for IEEE DOUBLE.
+ *
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+vc(C0, 4.1666666666666504759E-2 ,aaaa,3e2a,a9f0,aaaa, -4, .AAAAAAAAAAA9F0)
+vc(C1, -1.3888888888865302059E-3 ,0b60,bbb6,0cca,b60a, -9, -.B60B60B60A0CCA)
+vc(C2, 2.4801587285601038265E-5 ,0d00,38d0,098f,cdcd, -15, .D00D00CDCD098F)
+vc(C3, -2.7557313470902390219E-7 ,f27b,b593,e805,b593, -21, -.93F27BB593E805)
+vc(C4, 2.0875623401082232009E-9 ,74c8,320f,3ff0,fa1e, -28, .8F74C8FA1E3FF0)
+vc(C5, -1.1355178117642986178E-11 ,c32d,ae47,5a63,0a5c, -36, -.C7C32D0A5C5A63)
+
+ic(C0, 4.1666666666666504759E-2 , -5, 1.555555555553E)
+ic(C1, -1.3888888888865301516E-3 , -10, -1.6C16C16C14199)
+ic(C2, 2.4801587269650015769E-5 , -16, 1.A01A01971CAEB)
+ic(C3, -2.7557304623183959811E-7 , -22, -1.27E4F1314AD1A)
+ic(C4, 2.0873958177697780076E-9 , -29, 1.1EE3B60DDDC8C)
+ic(C5, -1.1250289076471311557E-11 , -37, -1.8BD5986B2A52E)
+
+#ifdef vccast
+#define C0 vccast(C0)
+#define C1 vccast(C1)
+#define C2 vccast(C2)
+#define C3 vccast(C3)
+#define C4 vccast(C4)
+#define C5 vccast(C5)
+#endif
+
+#define cos__C(z) (z*z*(C0+z*(C1+z*(C2+z*(C3+z*(C4+z*C5))))))
diff --git a/lib/libm/common_source/acos.3 b/lib/libm/common_source/acos.3
new file mode 100644
index 0000000..a3e5e7a
--- /dev/null
+++ b/lib/libm/common_source/acos.3
@@ -0,0 +1,89 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)acos.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ACOS 3
+.Os
+.Sh NAME
+.Nm acos
+.Nd arc cosine function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn acos "double x"
+.Sh DESCRIPTION
+The
+.Fn acos
+function computes the principal value of the arc cosine of
+.Fa x .
+A domain error occurs for arguments not in the range [-1, +1].
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn acos
+function returns the arc cosine in the range
+.Bq 0 , \*(Pi
+radians.
+On the
+.Tn VAX
+and
+.Tn Tahoe ,
+if:
+.Bd -unfilled -offset indent
+.Pf \&| Ns Ar x Ns \&| > 1 ,
+.Ed
+.Pp
+.Fn acos x
+sets the global variable
+.Va errno
+to
+.Dv EDOM
+and a reserved operand fault is generated.
+.Sh SEE ALSO
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn acos
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/acosh.3 b/lib/libm/common_source/acosh.3
new file mode 100644
index 0000000..578a0df
--- /dev/null
+++ b/lib/libm/common_source/acosh.3
@@ -0,0 +1,82 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)acosh.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ACOSH 3
+.Os BSD 4.3
+.Sh NAME
+.Nm acosh
+.Nd inverse hyperbolic cosine function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn acosh "double x"
+.Sh DESCRIPTION
+The
+.Fn acosh
+function computes the inverse hyperbolic cosine
+of the real
+argument
+.Ar x .
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn acosh
+function
+returns the inverse hyperbolic cosine of
+.Ar x .
+On the
+.Tn VAX
+and
+.Tn Tahoe ,
+if the argument is less than one
+.Fn acosh
+sets the global variable
+.Va errno
+to
+.Er EDOM
+and
+causes a reserved operand fault.
+.Sh SEE ALSO
+.Xr asinh 3 ,
+.Xr atanh 3 ,
+.Xr exp 3 ,
+.Xr infnan 3 ,
+.Xr math 3
+.Sh HISTORY
+The
+.Fn acosh
+function appeared in
+.Bx 4.3 .
diff --git a/lib/libm/common_source/acosh.c b/lib/libm/common_source/acosh.c
new file mode 100644
index 0000000..149e5de
--- /dev/null
+++ b/lib/libm/common_source/acosh.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)acosh.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ACOSH(X)
+ * RETURN THE INVERSE HYPERBOLIC COSINE OF X
+ * DOUBLE PRECISION (VAX D FORMAT 56 BITS, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 2/16/85;
+ * REVISED BY K.C. NG on 3/6/85, 3/24/85, 4/16/85, 8/17/85.
+ *
+ * Required system supported functions :
+ * sqrt(x)
+ *
+ * Required kernel function:
+ * log1p(x) ...return log(1+x)
+ *
+ * Method :
+ * Based on
+ * acosh(x) = log [ x + sqrt(x*x-1) ]
+ * we have
+ * acosh(x) := log1p(x)+ln2, if (x > 1.0E20); else
+ * acosh(x) := log1p( sqrt(x-1) * (sqrt(x-1) + sqrt(x+1)) ) .
+ * These formulae avoid the over/underflow complication.
+ *
+ * Special cases:
+ * acosh(x) is NaN with signal if x<1.
+ * acosh(NaN) is NaN without signal.
+ *
+ * Accuracy:
+ * acosh(x) returns the exact inverse hyperbolic cosine of x nearly
+ * rounded. In a test run with 512,000 random arguments on a VAX, the
+ * maximum observed error was 3.30 ulps (units of the last place) at
+ * x=1.0070493753568216 .
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+
+ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10,-33, 1.A39EF35793C76)
+
+#ifdef vccast
+#define ln2hi vccast(ln2hi)
+#define ln2lo vccast(ln2lo)
+#endif
+
+double acosh(x)
+double x;
+{
+ double t,big=1.E20; /* big+1==big */
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+
+ /* return log1p(x) + log(2) if x is large */
+ if(x>big) {t=log1p(x)+ln2lo; return(t+ln2hi);}
+
+ t=sqrt(x-1.0);
+ return(log1p(t*(t+sqrt(x+1.0))));
+}
diff --git a/lib/libm/common_source/asin.3 b/lib/libm/common_source/asin.3
new file mode 100644
index 0000000..5f04c59
--- /dev/null
+++ b/lib/libm/common_source/asin.3
@@ -0,0 +1,91 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)asin.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ASIN 3
+.Os
+.Sh NAME
+.Nm asin
+.Nd arc sine function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn asin "double x"
+.Sh DESCRIPTION
+The
+.Fn asin
+function computes the principal value of the arc sine of
+.Fa x .
+A domain error occurs for arguments not in the range [-1, +1].
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn asin
+function returns the arc sine in the range
+.Bk -words
+.Bq -\*(Pi/2, +\*(Pi/2
+.Ek
+radians.
+On the
+.Tn VAX ,
+and Tahoe ,
+if:
+.Bd -unfilled -offset indent
+.Pf \&| Ns Ar x Ns \&| > 1
+.Ed
+.Pp
+the
+global variable
+.Va errno
+is set to
+.Er EDOM
+and
+a reserved operand fault generated.
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn asin
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/asincos.c b/lib/libm/common_source/asincos.c
new file mode 100644
index 0000000..12d0e14
--- /dev/null
+++ b/lib/libm/common_source/asincos.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)asincos.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ASIN(X)
+ * RETURNS ARC SINE OF X
+ * DOUBLE PRECISION (IEEE DOUBLE 53 bits, VAX D FORMAT 56 bits)
+ * CODED IN C BY K.C. NG, 4/16/85, REVISED ON 6/10/85.
+ *
+ * Required system supported functions:
+ * copysign(x,y)
+ * sqrt(x)
+ *
+ * Required kernel function:
+ * atan2(y,x)
+ *
+ * Method :
+ * asin(x) = atan2(x,sqrt(1-x*x)); for better accuracy, 1-x*x is
+ * computed as follows
+ * 1-x*x if x < 0.5,
+ * 2*(1-|x|)-(1-|x|)*(1-|x|) if x >= 0.5.
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN.
+ *
+ * Accuracy:
+ * 1) If atan2() uses machine PI, then
+ *
+ * asin(x) returns (PI/pi) * (the exact arc sine of x) nearly rounded;
+ * and PI is the exact pi rounded to machine precision (see atan2 for
+ * details):
+ *
+ * in decimal:
+ * pi = 3.141592653589793 23846264338327 .....
+ * 53 bits PI = 3.141592653589793 115997963 ..... ,
+ * 56 bits PI = 3.141592653589793 227020265 ..... ,
+ *
+ * in hexadecimal:
+ * pi = 3.243F6A8885A308D313198A2E....
+ * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18 error=.276ulps
+ * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2 error=.206ulps
+ *
+ * In a test run with more than 200,000 random arguments on a VAX, the
+ * maximum observed error in ulps (units in the last place) was
+ * 2.06 ulps. (comparing against (PI/pi)*(exact asin(x)));
+ *
+ * 2) If atan2() uses true pi, then
+ *
+ * asin(x) returns the exact asin(x) with error below about 2 ulps.
+ *
+ * In a test run with more than 1,024,000 random arguments on a VAX, the
+ * maximum observed error in ulps (units in the last place) was
+ * 1.99 ulps.
+ */
+
+double asin(x)
+double x;
+{
+ double s,t,copysign(),atan2(),sqrt(),one=1.0;
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ s=copysign(x,one);
+ if(s <= 0.5)
+ return(atan2(x,sqrt(one-x*x)));
+ else
+ { t=one-s; s=t+t; return(atan2(x,sqrt(s-t*t))); }
+
+}
+
+/* ACOS(X)
+ * RETURNS ARC COS OF X
+ * DOUBLE PRECISION (IEEE DOUBLE 53 bits, VAX D FORMAT 56 bits)
+ * CODED IN C BY K.C. NG, 4/16/85, REVISED ON 6/10/85.
+ *
+ * Required system supported functions:
+ * copysign(x,y)
+ * sqrt(x)
+ *
+ * Required kernel function:
+ * atan2(y,x)
+ *
+ * Method :
+ * ________
+ * / 1 - x
+ * acos(x) = 2*atan2( / -------- , 1 ) .
+ * \/ 1 + x
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN.
+ *
+ * Accuracy:
+ * 1) If atan2() uses machine PI, then
+ *
+ * acos(x) returns (PI/pi) * (the exact arc cosine of x) nearly rounded;
+ * and PI is the exact pi rounded to machine precision (see atan2 for
+ * details):
+ *
+ * in decimal:
+ * pi = 3.141592653589793 23846264338327 .....
+ * 53 bits PI = 3.141592653589793 115997963 ..... ,
+ * 56 bits PI = 3.141592653589793 227020265 ..... ,
+ *
+ * in hexadecimal:
+ * pi = 3.243F6A8885A308D313198A2E....
+ * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18 error=.276ulps
+ * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2 error=.206ulps
+ *
+ * In a test run with more than 200,000 random arguments on a VAX, the
+ * maximum observed error in ulps (units in the last place) was
+ * 2.07 ulps. (comparing against (PI/pi)*(exact acos(x)));
+ *
+ * 2) If atan2() uses true pi, then
+ *
+ * acos(x) returns the exact acos(x) with error below about 2 ulps.
+ *
+ * In a test run with more than 1,024,000 random arguments on a VAX, the
+ * maximum observed error in ulps (units in the last place) was
+ * 2.15 ulps.
+ */
+
+double acos(x)
+double x;
+{
+ double t,copysign(),atan2(),sqrt(),one=1.0;
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x);
+#endif /* !defined(vax)&&!defined(tahoe) */
+ if( x != -1.0)
+ t=atan2(sqrt((one-x)/(one+x)),one);
+ else
+ t=atan2(one,0.0); /* t = PI/2 */
+ return(t+t);
+}
diff --git a/lib/libm/common_source/asinh.3 b/lib/libm/common_source/asinh.3
new file mode 100644
index 0000000..657451f
--- /dev/null
+++ b/lib/libm/common_source/asinh.3
@@ -0,0 +1,70 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)asinh.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ASINH 3
+.Os BSD 4.3
+.Sh NAME
+.Nm asinh
+.Nd inverse hyperbolic sine function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn asinh "double x"
+.Sh DESCRIPTION
+The
+.Fn asinh
+function computes the inverse hyperbolic sine
+of the real
+argument
+.Ar x .
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn asinh
+function
+returns the inverse hyperbolic sine of
+.Ar x .
+.Sh SEE ALSO
+.Xr acosh 3 ,
+.Xr atanh 3 ,
+.Xr exp 3 ,
+.Xr infnan 3 ,
+.Xr math 3
+.Sh HISTORY
+The
+.Fn asinh
+function appeared in
+.Bx 4.3 .
diff --git a/lib/libm/common_source/asinh.c b/lib/libm/common_source/asinh.c
new file mode 100644
index 0000000..1804145
--- /dev/null
+++ b/lib/libm/common_source/asinh.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)asinh.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ASINH(X)
+ * RETURN THE INVERSE HYPERBOLIC SINE OF X
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 2/16/85;
+ * REVISED BY K.C. NG on 3/7/85, 3/24/85, 4/16/85.
+ *
+ * Required system supported functions :
+ * copysign(x,y)
+ * sqrt(x)
+ *
+ * Required kernel function:
+ * log1p(x) ...return log(1+x)
+ *
+ * Method :
+ * Based on
+ * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
+ * we have
+ * asinh(x) := x if 1+x*x=1,
+ * := sign(x)*(log1p(x)+ln2)) if sqrt(1+x*x)=x, else
+ * := sign(x)*log1p(|x| + |x|/(1/|x| + sqrt(1+(1/|x|)^2)) )
+ *
+ * Accuracy:
+ * asinh(x) returns the exact inverse hyperbolic sine of x nearly rounded.
+ * In a test run with 52,000 random arguments on a VAX, the maximum
+ * observed error was 1.58 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+
+ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76)
+
+#ifdef vccast
+#define ln2hi vccast(ln2hi)
+#define ln2lo vccast(ln2lo)
+#endif
+
+double asinh(x)
+double x;
+{
+ double t,s;
+ const static double small=1.0E-10, /* fl(1+small*small) == 1 */
+ big =1.0E20, /* fl(1+big) == big */
+ one =1.0 ;
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ if((t=copysign(x,one))>small)
+ if(t<big) {
+ s=one/t; return(copysign(log1p(t+t/(s+sqrt(one+s*s))),x)); }
+ else /* if |x| > big */
+ {s=log1p(t)+ln2lo; return(copysign(s+ln2hi,x));}
+ else /* if |x| < small */
+ return(x);
+}
diff --git a/lib/libm/common_source/atan.3 b/lib/libm/common_source/atan.3
new file mode 100644
index 0000000..a1564bd
--- /dev/null
+++ b/lib/libm/common_source/atan.3
@@ -0,0 +1,75 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)atan.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ATAN 3
+.Os
+.Sh NAME
+.Nm atan
+.Nd arc tangent function of one variable
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn atan "double x"
+.Sh DESCRIPTION
+The
+.Fn atan
+function computes the principal value of the arc tangent of
+.Fa x .
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn atan
+function returns the arc tangent in the range
+.Bk -words
+.Bq -\*(Pi/2 , +\*(Pi/2
+.Ek
+radians.
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn atan
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/atan.c b/lib/libm/common_source/atan.c
new file mode 100644
index 0000000..f29c7d4
--- /dev/null
+++ b/lib/libm/common_source/atan.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)atan.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ATAN(X)
+ * RETURNS ARC TANGENT OF X
+ * DOUBLE PRECISION (IEEE DOUBLE 53 bits, VAX D FORMAT 56 bits)
+ * CODED IN C BY K.C. NG, 4/16/85, REVISED ON 6/10/85.
+ *
+ * Required kernel function:
+ * atan2(y,x)
+ *
+ * Method:
+ * atan(x) = atan2(x,1.0).
+ *
+ * Special case:
+ * if x is NaN, return x itself.
+ *
+ * Accuracy:
+ * 1) If atan2() uses machine PI, then
+ *
+ * atan(x) returns (PI/pi) * (the exact arc tangent of x) nearly rounded;
+ * and PI is the exact pi rounded to machine precision (see atan2 for
+ * details):
+ *
+ * in decimal:
+ * pi = 3.141592653589793 23846264338327 .....
+ * 53 bits PI = 3.141592653589793 115997963 ..... ,
+ * 56 bits PI = 3.141592653589793 227020265 ..... ,
+ *
+ * in hexadecimal:
+ * pi = 3.243F6A8885A308D313198A2E....
+ * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18 error=.276ulps
+ * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2 error=.206ulps
+ *
+ * In a test run with more than 200,000 random arguments on a VAX, the
+ * maximum observed error in ulps (units in the last place) was
+ * 0.86 ulps. (comparing against (PI/pi)*(exact atan(x))).
+ *
+ * 2) If atan2() uses true pi, then
+ *
+ * atan(x) returns the exact atan(x) with error below about 2 ulps.
+ *
+ * In a test run with more than 1,024,000 random arguments on a VAX, the
+ * maximum observed error in ulps (units in the last place) was
+ * 0.85 ulps.
+ */
+
+double atan(x)
+double x;
+{
+ double atan2(),one=1.0;
+ return(atan2(x,one));
+}
diff --git a/lib/libm/common_source/atan2.3 b/lib/libm/common_source/atan2.3
new file mode 100644
index 0000000..027ab8b
--- /dev/null
+++ b/lib/libm/common_source/atan2.3
@@ -0,0 +1,189 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)atan2.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ATAN2 3
+.Os
+.Sh NAME
+.Nm atan2
+.Nd arc tangent function of two variables
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn atan2 "double y" "double x"
+.Sh DESCRIPTION
+The
+.Xr atan2
+function computes the principal value of the arc tangent of
+.Ar y/ Ns Ar x ,
+using the signs of both arguments to determine the quadrant of
+the return value.
+.Sh RETURN VALUES
+The
+.Xr atan2
+function, if successful,
+returns the arc tangent of
+.Ar y/ Ns Ar x
+in the range
+.Bk -words
+.Bq \&- Ns \*(Pi , \&+ Ns \*(Pi
+.Ek
+radians.
+If both
+.Ar x
+and
+.Ar y
+are zero, the global variable
+.Va errno
+is set to
+.Er EDOM .
+On the
+.Tn VAX :
+.Bl -column atan_(y,x)_:=____ sign(y)_(Pi_atan2(Xy_xX))___
+.It Fn atan2 y x No := Ta
+.Fn atan y/x Ta
+if
+.Ar x
+> 0,
+.It Ta sign( Ns Ar y Ns )*(\*(Pi -
+.Fn atan "\\*(Bay/x\\*(Ba" ) Ta
+if
+.Ar x
+< 0,
+.It Ta
+.No 0 Ta
+if x = y = 0, or
+.It Ta
+.Pf sign( Ar y Ns )*\\*(Pi/2 Ta
+if
+.Ar x
+= 0 \*(!=
+.Ar y .
+.El
+.Sh NOTES
+The function
+.Fn atan2
+defines "if x > 0,"
+.Fn atan2 0 0
+= 0 on a
+.Tn VAX
+despite that previously
+.Fn atan2 0 0
+may have generated an error message.
+The reasons for assigning a value to
+.Fn atan2 0 0
+are these:
+.Bl -enum -offset indent
+.It
+Programs that test arguments to avoid computing
+.Fn atan2 0 0
+must be indifferent to its value.
+Programs that require it to be invalid are vulnerable
+to diverse reactions to that invalidity on diverse computer systems.
+.It
+The
+.Fn atan2
+function is used mostly to convert from rectangular (x,y)
+to polar
+.if n\
+(r,theta)
+.if t\
+(r,\(*h)
+coordinates that must satisfy x =
+.if n\
+r\(**cos theta
+.if t\
+r\(**cos\(*h
+and y =
+.if n\
+r\(**sin theta.
+.if t\
+r\(**sin\(*h.
+These equations are satisfied when (x=0,y=0)
+is mapped to
+.if n \
+(r=0,theta=0)
+.if t \
+(r=0,\(*h=0)
+on a VAX. In general, conversions to polar coordinates
+should be computed thus:
+.Bd -unfilled -offset indent
+.if n \{\
+r := hypot(x,y); ... := sqrt(x\(**x+y\(**y)
+theta := atan2(y,x).
+.\}
+.if t \{\
+r := hypot(x,y); ... := \(sr(x\u\s82\s10\d+y\u\s82\s10\d)
+\(*h := atan2(y,x).
+.\}
+.Ed
+.It
+The foregoing formulas need not be altered to cope in a
+reasonable way with signed zeros and infinities
+on a machine that conforms to
+.Tn IEEE 754 ;
+the versions of
+.Xr hypot 3
+and
+.Fn atan2
+provided for
+such a machine are designed to handle all cases.
+That is why
+.Fn atan2 \(+-0 \-0
+= \(+-\*(Pi
+for instance.
+In general the formulas above are equivalent to these:
+.Bd -unfilled -offset indent
+.if n \
+r := sqrt(x\(**x+y\(**y); if r = 0 then x := copysign(1,x);
+.if t \
+r := \(sr(x\(**x+y\(**y);\0\0if r = 0 then x := copysign(1,x);
+.Ed
+.El
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn atan2
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/atanh.3 b/lib/libm/common_source/atanh.3
new file mode 100644
index 0000000..2ddcc3a
--- /dev/null
+++ b/lib/libm/common_source/atanh.3
@@ -0,0 +1,84 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)atanh.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ATANH 3
+.Os BSD 4.3
+.Sh NAME
+.Nm atanh
+.Nd inverse hyperbolic tangent function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn atanh "double x"
+.Sh DESCRIPTION
+The
+.Fn atanh
+function computes the inverse hyperbolic tangent
+of the real
+argument
+.Ar x .
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn atanh
+function
+returns the inverse hyperbolic tangent of
+.Ar x
+if successful.
+On the
+.Tn VAX
+and
+.Tn Tahoe ,
+if the argument has absolute value
+bigger than or equal to 1,
+.Fn atanh
+sets the global variable
+.Va errno
+to
+.Er EDOM
+and
+a reserved operand fault is generated.
+.Sh SEE ALSO
+.Xr acosh 3 ,
+.Xr asinh 3 ,
+.Xr exp 3 ,
+.Xr infnan 3 ,
+.Xr math 3
+.Sh HISTORY
+The
+.Fn atanh
+function appeared in
+.Bx 4.3 .
diff --git a/lib/libm/common_source/atanh.c b/lib/libm/common_source/atanh.c
new file mode 100644
index 0000000..e5cdadd
--- /dev/null
+++ b/lib/libm/common_source/atanh.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)atanh.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ATANH(X)
+ * RETURN THE HYPERBOLIC ARC TANGENT OF X
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/8/85;
+ * REVISED BY K.C. NG on 2/7/85, 3/7/85, 8/18/85.
+ *
+ * Required kernel function:
+ * log1p(x) ...return log(1+x)
+ *
+ * Method :
+ * Return
+ * 1 2x x
+ * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
+ * 2 1 - x 1 - x
+ *
+ * Special cases:
+ * atanh(x) is NaN if |x| > 1 with signal;
+ * atanh(NaN) is that NaN with no signal;
+ * atanh(+-1) is +-INF with signal.
+ *
+ * Accuracy:
+ * atanh(x) returns the exact hyperbolic arc tangent of x nearly rounded.
+ * In a test run with 512,000 random arguments on a VAX, the maximum
+ * observed error was 1.87 ulps (units in the last place) at
+ * x= -3.8962076028810414000e-03.
+ */
+#include "mathimpl.h"
+
+#if defined(vax)||defined(tahoe)
+#include <errno.h>
+#endif /* defined(vax)||defined(tahoe) */
+
+double atanh(x)
+double x;
+{
+ double z;
+ z = copysign(0.5,x);
+ x = copysign(x,1.0);
+#if defined(vax)||defined(tahoe)
+ if (x == 1.0) {
+ return(copysign(1.0,z)*infnan(ERANGE)); /* sign(x)*INF */
+ }
+#endif /* defined(vax)||defined(tahoe) */
+ x = x/(1.0-x);
+ return( z*log1p(x+x) );
+}
diff --git a/lib/libm/common_source/ceil.3 b/lib/libm/common_source/ceil.3
new file mode 100644
index 0000000..aed159f
--- /dev/null
+++ b/lib/libm/common_source/ceil.3
@@ -0,0 +1,66 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ceil.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt CEIL 3
+.Os
+.Sh NAME
+.Nm ceil
+.Nd smallest integral value greather than or equal to x
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn ceil "double x"
+.Sh DESCRIPTION
+The
+.Fn ceil
+function computes the smallest integral value greater than or equal to
+.Fa x .
+.Sh RETURN VALUES
+The
+.Fn ceil
+function returns the smallest integral value
+expressed as a double.
+.Sh SEE ALSO
+.Xr abs 3 ,
+.Xr fabs 3 ,
+.Xr floor 3 ,
+.Xr ieee 3 ,
+.Xr math 3 ,
+.Xr rint 3
+.Sh STANDARDS
+The
+.Fn ceil
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/cos.3 b/lib/libm/common_source/cos.3
new file mode 100644
index 0000000..9de38c1
--- /dev/null
+++ b/lib/libm/common_source/cos.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)cos.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt COS 3
+.Os
+.Sh NAME
+.Nm cos
+.Nd cosine function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn cos "double x"
+.Sh DESCRIPTION
+The
+.Fn cos
+function computes the cosine of
+.Fa x
+(measured in radians).
+A large magnitude argument may yield a result with little or no
+significance.
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn cos
+function returns the cosine value.
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn acos
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/cosh.3 b/lib/libm/common_source/cosh.3
new file mode 100644
index 0000000..311b794
--- /dev/null
+++ b/lib/libm/common_source/cosh.3
@@ -0,0 +1,75 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)cosh.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt COSH 3
+.Os
+.Sh NAME
+.Nm cosh
+.Nd hyperbolic cosine function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn cosh "double x"
+.Sh DESCRIPTION
+The
+.Fn cosh
+function computes the hyperbolic cosine of
+.Fa x .
+.Sh RETURN VALUES
+The
+.Fn cosh
+function returns the hyperbolic cosine unless the magnitude
+of
+.Fa x
+is too large; in this event, the global variable
+.Va errno
+is set to
+.Er ERANGE .
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn cosh
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/cosh.c b/lib/libm/common_source/cosh.c
new file mode 100644
index 0000000..e8d3519
--- /dev/null
+++ b/lib/libm/common_source/cosh.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cosh.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* COSH(X)
+ * RETURN THE HYPERBOLIC COSINE OF X
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/8/85;
+ * REVISED BY K.C. NG on 2/8/85, 2/23/85, 3/7/85, 3/29/85, 4/16/85.
+ *
+ * Required system supported functions :
+ * copysign(x,y)
+ * scalb(x,N)
+ *
+ * Required kernel function:
+ * exp(x)
+ * exp__E(x,c) ...return exp(x+c)-1-x for |x|<0.3465
+ *
+ * Method :
+ * 1. Replace x by |x|.
+ * 2.
+ * [ exp(x) - 1 ]^2
+ * 0 <= x <= 0.3465 : cosh(x) := 1 + -------------------
+ * 2*exp(x)
+ *
+ * exp(x) + 1/exp(x)
+ * 0.3465 <= x <= 22 : cosh(x) := -------------------
+ * 2
+ * 22 <= x <= lnovfl : cosh(x) := exp(x)/2
+ * lnovfl <= x <= lnovfl+log(2)
+ * : cosh(x) := exp(x)/2 (avoid overflow)
+ * log(2)+lnovfl < x < INF: overflow to INF
+ *
+ * Note: .3465 is a number near one half of ln2.
+ *
+ * Special cases:
+ * cosh(x) is x if x is +INF, -INF, or NaN.
+ * only cosh(0)=1 is exact for finite x.
+ *
+ * Accuracy:
+ * cosh(x) returns the exact hyperbolic cosine of x nearly rounded.
+ * In a test run with 768,000 random arguments on a VAX, the maximum
+ * observed error was 1.23 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(mln2hi, 8.8029691931113054792E1 ,0f33,43b0,2bdb,c7e2, 7, .B00F33C7E22BDB)
+vc(mln2lo,-4.9650192275318476525E-16 ,1b60,a70f,582a,279e, -50,-.8F1B60279E582A)
+vc(lnovfl, 8.8029691931113053016E1 ,0f33,43b0,2bda,c7e2, 7, .B00F33C7E22BDA)
+
+ic(mln2hi, 7.0978271289338397310E2, 10, 1.62E42FEFA39EF)
+ic(mln2lo, 2.3747039373786107478E-14, -45, 1.ABC9E3B39803F)
+ic(lnovfl, 7.0978271289338397310E2, 9, 1.62E42FEFA39EF)
+
+#ifdef vccast
+#define mln2hi vccast(mln2hi)
+#define mln2lo vccast(mln2lo)
+#define lnovfl vccast(lnovfl)
+#endif
+
+#if defined(vax)||defined(tahoe)
+static max = 126 ;
+#else /* defined(vax)||defined(tahoe) */
+static max = 1023 ;
+#endif /* defined(vax)||defined(tahoe) */
+
+double cosh(x)
+double x;
+{
+ static const double half=1.0/2.0,
+ one=1.0, small=1.0E-18; /* fl(1+small)==1 */
+ double t;
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ if((x=copysign(x,one)) <= 22)
+ if(x<0.3465)
+ if(x<small) return(one+x);
+ else {t=x+__exp__E(x,0.0);x=t+t; return(one+t*t/(2.0+x)); }
+
+ else /* for x lies in [0.3465,22] */
+ { t=exp(x); return((t+one/t)*half); }
+
+ if( lnovfl <= x && x <= (lnovfl+0.7))
+ /* for x lies in [lnovfl, lnovfl+ln2], decrease x by ln(2^(max+1))
+ * and return 2^max*exp(x) to avoid unnecessary overflow
+ */
+ return(scalb(exp((x-mln2hi)-mln2lo), max));
+
+ else
+ return(exp(x)*half); /* for large x, cosh(x)=exp(x)/2 */
+}
diff --git a/lib/libm/common_source/erf.3 b/lib/libm/common_source/erf.3
new file mode 100644
index 0000000..4618fb9
--- /dev/null
+++ b/lib/libm/common_source/erf.3
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)erf.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt ERF 3
+.Os BSD 4.3
+.Sh NAME
+.Nm erf ,
+.Nm erfc
+.Nd error function operators
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn erf "double x"
+.Ft double
+.Fn erfc "double x"
+.Sh DESCRIPTION
+These functions calculate the error function of
+.Fa x .
+.Pp
+The
+.Fn erf
+calculates the error function of x; where
+.Bd -filled -offset indent
+.if n \{\
+erf(x) = 2/sqrt(pi)\(**\|integral from 0 to x of exp(\-t\(**t) dt. \}
+.if t \{\
+erf\|(x) :=
+(2/\(sr\(*p)\|\(is\d\s8\z0\s10\u\u\s8x\s10\d\|exp(\-t\u\s82\s10\d)\|dt. \}
+.Ed
+.Pp
+The
+.Fn erfc
+function calculates the complementary error function of
+.Fa x ;
+that is
+.Fn erfc
+subtracts the result of the error function
+.Fn erf x
+from 1.0.
+This is useful, since for large
+.Fa x
+places disappear.
+.Sh SEE ALSO
+.Xr math 3
+.Sh HISTORY
+The
+.Fn erf
+and
+.Fn erfc
+functions appeared in
+.Bx 4.3 .
diff --git a/lib/libm/common_source/erf.c b/lib/libm/common_source/erf.c
new file mode 100644
index 0000000..ba0c006
--- /dev/null
+++ b/lib/libm/common_source/erf.c
@@ -0,0 +1,396 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)erf.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* Modified Nov 30, 1992 P. McILROY:
+ * Replaced expansions for x >= 1.25 (error 1.7ulp vs ~6ulp)
+ * Replaced even+odd with direct calculation for x < .84375,
+ * to avoid destructive cancellation.
+ *
+ * Performance of erfc(x):
+ * In 300000 trials in the range [.83, .84375] the
+ * maximum observed error was 3.6ulp.
+ *
+ * In [.84735,1.25] the maximum observed error was <2.5ulp in
+ * 100000 runs in the range [1.2, 1.25].
+ *
+ * In [1.25,26] (Not including subnormal results)
+ * the error is < 1.7ulp.
+ */
+
+/* double erf(double x)
+ * double erfc(double x)
+ * x
+ * 2 |\
+ * erf(x) = --------- | exp(-t*t)dt
+ * sqrt(pi) \|
+ * 0
+ *
+ * erfc(x) = 1-erf(x)
+ *
+ * Method:
+ * 1. Reduce x to |x| by erf(-x) = -erf(x)
+ * 2. For x in [0, 0.84375]
+ * erf(x) = x + x*P(x^2)
+ * erfc(x) = 1 - erf(x) if x<=0.25
+ * = 0.5 + ((0.5-x)-x*P) if x in [0.25,0.84375]
+ * where
+ * 2 2 4 20
+ * P = P(x ) = (p0 + p1 * x + p2 * x + ... + p10 * x )
+ * is an approximation to (erf(x)-x)/x with precision
+ *
+ * -56.45
+ * | P - (erf(x)-x)/x | <= 2
+ *
+ *
+ * Remark. The formula is derived by noting
+ * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ * and that
+ * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ * is close to one. The interval is chosen because the fixed
+ * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
+ * near 0.6174), and by some experiment, 0.84375 is chosen to
+ * guarantee the error is less than one ulp for erf.
+ *
+ * 3. For x in [0.84375,1.25], let s = x - 1, and
+ * c = 0.84506291151 rounded to single (24 bits)
+ * erf(x) = c + P1(s)/Q1(s)
+ * erfc(x) = (1-c) - P1(s)/Q1(s)
+ * |P1/Q1 - (erf(x)-c)| <= 2**-59.06
+ * Remark: here we use the taylor series expansion at x=1.
+ * erf(1+s) = erf(1) + s*Poly(s)
+ * = 0.845.. + P1(s)/Q1(s)
+ * That is, we use rational approximation to approximate
+ * erf(1+s) - (c = (single)0.84506291151)
+ * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ * where
+ * P1(s) = degree 6 poly in s
+ * Q1(s) = degree 6 poly in s
+ *
+ * 4. For x in [1.25, 2]; [2, 4]
+ * erf(x) = 1.0 - tiny
+ * erfc(x) = (1/x)exp(-x*x-(.5*log(pi) -.5z + R(z)/S(z))
+ *
+ * Where z = 1/(x*x), R is degree 9, and S is degree 3;
+ *
+ * 5. For x in [4,28]
+ * erf(x) = 1.0 - tiny
+ * erfc(x) = (1/x)exp(-x*x-(.5*log(pi)+eps + zP(z))
+ *
+ * Where P is degree 14 polynomial in 1/(x*x).
+ *
+ * Notes:
+ * Here 4 and 5 make use of the asymptotic series
+ * exp(-x*x)
+ * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) );
+ * x*sqrt(pi)
+ *
+ * where for z = 1/(x*x)
+ * P(z) ~ z/2*(-1 + z*3/2*(1 + z*5/2*(-1 + z*7/2*(1 +...))))
+ *
+ * Thus we use rational approximation to approximate
+ * erfc*x*exp(x*x) ~ 1/sqrt(pi);
+ *
+ * The error bound for the target function, G(z) for
+ * the interval
+ * [4, 28]:
+ * |eps + 1/(z)P(z) - G(z)| < 2**(-56.61)
+ * for [2, 4]:
+ * |R(z)/S(z) - G(z)| < 2**(-58.24)
+ * for [1.25, 2]:
+ * |R(z)/S(z) - G(z)| < 2**(-58.12)
+ *
+ * 6. For inf > x >= 28
+ * erf(x) = 1 - tiny (raise inexact)
+ * erfc(x) = tiny*tiny (raise underflow)
+ *
+ * 7. Special cases:
+ * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
+ * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
+ * erfc/erf(NaN) is NaN
+ */
+
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+#define TRUNC(x) (double) (float) (x)
+#else
+#define _IEEE 1
+#define TRUNC(x) *(((int *) &x) + 1) &= 0xf8000000
+#define infnan(x) 0.0
+#endif
+
+#ifdef _IEEE_LIBM
+/*
+ * redefining "___function" to "function" in _IEEE_LIBM mode
+ */
+#include "ieee_libm.h"
+#endif
+
+static double
+tiny = 1e-300,
+half = 0.5,
+one = 1.0,
+two = 2.0,
+c = 8.45062911510467529297e-01, /* (float)0.84506291151 */
+/*
+ * Coefficients for approximation to erf in [0,0.84375]
+ */
+p0t8 = 1.02703333676410051049867154944018394163280,
+p0 = 1.283791670955125638123339436800229927041e-0001,
+p1 = -3.761263890318340796574473028946097022260e-0001,
+p2 = 1.128379167093567004871858633779992337238e-0001,
+p3 = -2.686617064084433642889526516177508374437e-0002,
+p4 = 5.223977576966219409445780927846432273191e-0003,
+p5 = -8.548323822001639515038738961618255438422e-0004,
+p6 = 1.205520092530505090384383082516403772317e-0004,
+p7 = -1.492214100762529635365672665955239554276e-0005,
+p8 = 1.640186161764254363152286358441771740838e-0006,
+p9 = -1.571599331700515057841960987689515895479e-0007,
+p10= 1.073087585213621540635426191486561494058e-0008;
+/*
+ * Coefficients for approximation to erf in [0.84375,1.25]
+ */
+static double
+pa0 = -2.362118560752659485957248365514511540287e-0003,
+pa1 = 4.148561186837483359654781492060070469522e-0001,
+pa2 = -3.722078760357013107593507594535478633044e-0001,
+pa3 = 3.183466199011617316853636418691420262160e-0001,
+pa4 = -1.108946942823966771253985510891237782544e-0001,
+pa5 = 3.547830432561823343969797140537411825179e-0002,
+pa6 = -2.166375594868790886906539848893221184820e-0003,
+qa1 = 1.064208804008442270765369280952419863524e-0001,
+qa2 = 5.403979177021710663441167681878575087235e-0001,
+qa3 = 7.182865441419627066207655332170665812023e-0002,
+qa4 = 1.261712198087616469108438860983447773726e-0001,
+qa5 = 1.363708391202905087876983523620537833157e-0002,
+qa6 = 1.198449984679910764099772682882189711364e-0002;
+/*
+ * log(sqrt(pi)) for large x expansions.
+ * The tail (lsqrtPI_lo) is included in the rational
+ * approximations.
+*/
+static double
+ lsqrtPI_hi = .5723649429247000819387380943226;
+/*
+ * lsqrtPI_lo = .000000000000000005132975581353913;
+ *
+ * Coefficients for approximation to erfc in [2, 4]
+*/
+static double
+rb0 = -1.5306508387410807582e-010, /* includes lsqrtPI_lo */
+rb1 = 2.15592846101742183841910806188e-008,
+rb2 = 6.24998557732436510470108714799e-001,
+rb3 = 8.24849222231141787631258921465e+000,
+rb4 = 2.63974967372233173534823436057e+001,
+rb5 = 9.86383092541570505318304640241e+000,
+rb6 = -7.28024154841991322228977878694e+000,
+rb7 = 5.96303287280680116566600190708e+000,
+rb8 = -4.40070358507372993983608466806e+000,
+rb9 = 2.39923700182518073731330332521e+000,
+rb10 = -6.89257464785841156285073338950e-001,
+sb1 = 1.56641558965626774835300238919e+001,
+sb2 = 7.20522741000949622502957936376e+001,
+sb3 = 9.60121069770492994166488642804e+001;
+/*
+ * Coefficients for approximation to erfc in [1.25, 2]
+*/
+static double
+rc0 = -2.47925334685189288817e-007, /* includes lsqrtPI_lo */
+rc1 = 1.28735722546372485255126993930e-005,
+rc2 = 6.24664954087883916855616917019e-001,
+rc3 = 4.69798884785807402408863708843e+000,
+rc4 = 7.61618295853929705430118701770e+000,
+rc5 = 9.15640208659364240872946538730e-001,
+rc6 = -3.59753040425048631334448145935e-001,
+rc7 = 1.42862267989304403403849619281e-001,
+rc8 = -4.74392758811439801958087514322e-002,
+rc9 = 1.09964787987580810135757047874e-002,
+rc10 = -1.28856240494889325194638463046e-003,
+sc1 = 9.97395106984001955652274773456e+000,
+sc2 = 2.80952153365721279953959310660e+001,
+sc3 = 2.19826478142545234106819407316e+001;
+/*
+ * Coefficients for approximation to erfc in [4,28]
+ */
+static double
+rd0 = -2.1491361969012978677e-016, /* includes lsqrtPI_lo */
+rd1 = -4.99999999999640086151350330820e-001,
+rd2 = 6.24999999772906433825880867516e-001,
+rd3 = -1.54166659428052432723177389562e+000,
+rd4 = 5.51561147405411844601985649206e+000,
+rd5 = -2.55046307982949826964613748714e+001,
+rd6 = 1.43631424382843846387913799845e+002,
+rd7 = -9.45789244999420134263345971704e+002,
+rd8 = 6.94834146607051206956384703517e+003,
+rd9 = -5.27176414235983393155038356781e+004,
+rd10 = 3.68530281128672766499221324921e+005,
+rd11 = -2.06466642800404317677021026611e+006,
+rd12 = 7.78293889471135381609201431274e+006,
+rd13 = -1.42821001129434127360582351685e+007;
+
+double erf(x)
+ double x;
+{
+ double R,S,P,Q,ax,s,y,z,r,fabs(),exp();
+ if(!finite(x)) { /* erf(nan)=nan */
+ if (isnan(x))
+ return(x);
+ return (x > 0 ? one : -one); /* erf(+/-inf)= +/-1 */
+ }
+ if ((ax = x) < 0)
+ ax = - ax;
+ if (ax < .84375) {
+ if (ax < 3.7e-09) {
+ if (ax < 1.0e-308)
+ return 0.125*(8.0*x+p0t8*x); /*avoid underflow */
+ return x + p0*x;
+ }
+ y = x*x;
+ r = y*(p1+y*(p2+y*(p3+y*(p4+y*(p5+
+ y*(p6+y*(p7+y*(p8+y*(p9+y*p10)))))))));
+ return x + x*(p0+r);
+ }
+ if (ax < 1.25) { /* 0.84375 <= |x| < 1.25 */
+ s = fabs(x)-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+ if (x>=0)
+ return (c + P/Q);
+ else
+ return (-c - P/Q);
+ }
+ if (ax >= 6.0) { /* inf>|x|>=6 */
+ if (x >= 0.0)
+ return (one-tiny);
+ else
+ return (tiny-one);
+ }
+ /* 1.25 <= |x| < 6 */
+ z = -ax*ax;
+ s = -one/z;
+ if (ax < 2.0) {
+ R = rc0+s*(rc1+s*(rc2+s*(rc3+s*(rc4+s*(rc5+
+ s*(rc6+s*(rc7+s*(rc8+s*(rc9+s*rc10)))))))));
+ S = one+s*(sc1+s*(sc2+s*sc3));
+ } else {
+ R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+
+ s*(rb6+s*(rb7+s*(rb8+s*(rb9+s*rb10)))))))));
+ S = one+s*(sb1+s*(sb2+s*sb3));
+ }
+ y = (R/S -.5*s) - lsqrtPI_hi;
+ z += y;
+ z = exp(z)/ax;
+ if (x >= 0)
+ return (one-z);
+ else
+ return (z-one);
+}
+
+double erfc(x)
+ double x;
+{
+ double R,S,P,Q,s,ax,y,z,r,fabs(),__exp__D();
+ if (!finite(x)) {
+ if (isnan(x)) /* erfc(NaN) = NaN */
+ return(x);
+ else if (x > 0) /* erfc(+-inf)=0,2 */
+ return 0.0;
+ else
+ return 2.0;
+ }
+ if ((ax = x) < 0)
+ ax = -ax;
+ if (ax < .84375) { /* |x|<0.84375 */
+ if (ax < 1.38777878078144568e-17) /* |x|<2**-56 */
+ return one-x;
+ y = x*x;
+ r = y*(p1+y*(p2+y*(p3+y*(p4+y*(p5+
+ y*(p6+y*(p7+y*(p8+y*(p9+y*p10)))))))));
+ if (ax < .0625) { /* |x|<2**-4 */
+ return (one-(x+x*(p0+r)));
+ } else {
+ r = x*(p0+r);
+ r += (x-half);
+ return (half - r);
+ }
+ }
+ if (ax < 1.25) { /* 0.84375 <= |x| < 1.25 */
+ s = ax-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+ if (x>=0) {
+ z = one-c; return z - P/Q;
+ } else {
+ z = c+P/Q; return one+z;
+ }
+ }
+ if (ax >= 28) /* Out of range */
+ if (x>0)
+ return (tiny*tiny);
+ else
+ return (two-tiny);
+ z = ax;
+ TRUNC(z);
+ y = z - ax; y *= (ax+z);
+ z *= -z; /* Here z + y = -x^2 */
+ s = one/(-z-y); /* 1/(x*x) */
+ if (ax >= 4) { /* 6 <= ax */
+ R = s*(rd1+s*(rd2+s*(rd3+s*(rd4+s*(rd5+
+ s*(rd6+s*(rd7+s*(rd8+s*(rd9+s*(rd10
+ +s*(rd11+s*(rd12+s*rd13))))))))))));
+ y += rd0;
+ } else if (ax >= 2) {
+ R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+
+ s*(rb6+s*(rb7+s*(rb8+s*(rb9+s*rb10)))))))));
+ S = one+s*(sb1+s*(sb2+s*sb3));
+ y += R/S;
+ R = -.5*s;
+ } else {
+ R = rc0+s*(rc1+s*(rc2+s*(rc3+s*(rc4+s*(rc5+
+ s*(rc6+s*(rc7+s*(rc8+s*(rc9+s*rc10)))))))));
+ S = one+s*(sc1+s*(sc2+s*sc3));
+ y += R/S;
+ R = -.5*s;
+ }
+ /* return exp(-x^2 - lsqrtPI_hi + R + y)/x; */
+ s = ((R + y) - lsqrtPI_hi) + z;
+ y = (((z-s) - lsqrtPI_hi) + R) + y;
+ r = __exp__D(s, y)/x;
+ if (x>0)
+ return r;
+ else
+ return two-r;
+}
diff --git a/lib/libm/common_source/exp.3 b/lib/libm/common_source/exp.3
new file mode 100644
index 0000000..39e1384
--- /dev/null
+++ b/lib/libm/common_source/exp.3
@@ -0,0 +1,285 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)exp.3 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt EXP 3
+.Os BSD 4
+.Sh NAME
+.Nm exp ,
+.Nm expm1 ,
+.Nm log ,
+.Nm log10 ,
+.Nm log1p ,
+.Nm pow
+.Nd exponential, logarithm, power functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn exp "double x"
+.Ft double
+.Fn expm1 "double x"
+.Ft double
+.Fn log "double x"
+.Ft double
+.Fn log10 "double x"
+.Ft double
+.Fn log1p "double x"
+.Ft double
+.Fn pow "double x" "double y"
+.Sh DESCRIPTION
+The
+.Fn exp
+function computes the exponential value of the given argument
+.Fa x .
+.Pp
+The
+.Fn expm1
+function computes the value exp(x)\-1 accurately even for tiny argument
+.Fa x .
+.Pp
+The
+.Fn log
+function computes the value for the natural logarithm of
+the argument x.
+.Pp
+The
+.Fn log10
+function computes the value for the logarithm of
+argument
+.Fa x
+to base 10.
+.Pp
+The
+.Fn log1p
+function computes
+the value of log(1+x) accurately even for tiny argument
+.Fa x .
+.Pp
+The
+.Fn pow
+computes the value
+of
+.Ar x
+to the exponent
+.Ar y .
+.Sh ERROR (due to Roundoff etc.)
+exp(x), log(x), expm1(x) and log1p(x) are accurate to within
+an
+.Em up ,
+and log10(x) to within about 2
+.Em ups ;
+an
+.Em up
+is one
+.Em Unit
+in the
+.Em Last
+.Em Place .
+The error in
+.Fn pow x y
+is below about 2
+.Em ups
+when its
+magnitude is moderate, but increases as
+.Fn pow x y
+approaches
+the over/underflow thresholds until almost as many bits could be
+lost as are occupied by the floating\-point format's exponent
+field; that is 8 bits for
+.Tn "VAX D"
+and 11 bits for IEEE 754 Double.
+No such drastic loss has been exposed by testing; the worst
+errors observed have been below 20
+.Em ups
+for
+.Tn "VAX D" ,
+300
+.Em ups
+for
+.Tn IEEE
+754 Double.
+Moderate values of
+.Fn pow
+are accurate enough that
+.Fn pow integer integer
+is exact until it is bigger than 2**56 on a
+.Tn VAX ,
+2**53 for
+.Tn IEEE
+754.
+.Sh RETURN VALUES
+These functions will return the appropriate computation unless an error
+occurs or an argument is out of range.
+The functions
+.Fn exp ,
+.Fn expm1
+and
+.Fn pow
+detect if the computed value will overflow,
+set the global variable
+.Va errno to
+.Er RANGE
+and cause a reserved operand fault on a
+.Tn VAX
+or
+.Tn Tahoe .
+The function
+.Fn pow x y
+checks to see if
+.Fa x
+< 0 and
+.Fa y
+is not an integer, in the event this is true,
+the global variable
+.Va errno
+is set to
+.Er EDOM
+and on the
+.Tn VAX
+and
+.Tn Tahoe
+generate a reserved operand fault.
+On a
+.Tn VAX
+and
+.Tn Tahoe ,
+.Va errno
+is set to
+.Er EDOM
+and the reserved operand is returned
+by log unless
+.Fa x
+> 0, by
+.Fn log1p
+unless
+.Fa x
+> \-1.
+.Sh NOTES
+The functions exp(x)\-1 and log(1+x) are called
+expm1 and logp1 in
+.Tn BASIC
+on the Hewlett\-Packard
+.Tn HP Ns \-71B
+and
+.Tn APPLE
+Macintosh,
+.Tn EXP1
+and
+.Tn LN1
+in Pascal, exp1 and log1 in C
+on
+.Tn APPLE
+Macintoshes, where they have been provided to make
+sure financial calculations of ((1+x)**n\-1)/x, namely
+expm1(n\(**log1p(x))/x, will be accurate when x is tiny.
+They also provide accurate inverse hyperbolic functions.
+.Pp
+The function
+.Fn pow x 0
+returns x**0 = 1 for all x including x = 0,
+.if n \
+Infinity
+.if t \
+\(if
+(not found on a
+.Tn VAX ) ,
+and
+.Em NaN
+(the reserved
+operand on a
+.Tn VAX ) . Previous implementations of pow may
+have defined x**0 to be undefined in some or all of these
+cases. Here are reasons for returning x**0 = 1 always:
+.Bl -enum -width indent
+.It
+Any program that already tests whether x is zero (or
+infinite or \*(Na) before computing x**0 cannot care
+whether 0**0 = 1 or not. Any program that depends
+upon 0**0 to be invalid is dubious anyway since that
+expression's meaning and, if invalid, its consequences
+vary from one computer system to another.
+.It
+Some Algebra texts (e.g. Sigler's) define x**0 = 1 for
+all x, including x = 0.
+This is compatible with the convention that accepts a[0]
+as the value of polynomial
+.Bd -literal -offset indent
+p(x) = a[0]\(**x**0 + a[1]\(**x**1 + a[2]\(**x**2 +...+ a[n]\(**x**n
+.Ed
+.Pp
+at x = 0 rather than reject a[0]\(**0**0 as invalid.
+.It
+Analysts will accept 0**0 = 1 despite that x**y can
+approach anything or nothing as x and y approach 0
+independently.
+The reason for setting 0**0 = 1 anyway is this:
+.Bd -filled -offset indent
+If x(z) and y(z) are
+.Em any
+functions analytic (expandable
+in power series) in z around z = 0, and if there
+x(0) = y(0) = 0, then x(z)**y(z) \(-> 1 as z \(-> 0.
+.Ed
+.It
+If 0**0 = 1, then
+.if n \
+infinity**0 = 1/0**0 = 1 too; and
+.if t \
+\(if**0 = 1/0**0 = 1 too; and
+then \*(Na**0 = 1 too because x**0 = 1 for all finite
+and infinite x, i.e., independently of x.
+.El
+.Sh SEE ALSO
+.Xr infnan 3 ,
+.Xr math 3
+.Sh HISTORY
+A
+.Fn exp ,
+.Fn log
+and
+.Fn pow
+function
+appeared in
+.At v6 .
+A
+.Fn log10
+function
+appeared in
+.At v7 .
+The
+.Fn log1p
+and
+.Fn expm1
+functions appeared in
+.Bx 4.3 .
diff --git a/lib/libm/common_source/exp.c b/lib/libm/common_source/exp.c
new file mode 100644
index 0000000..fa6ea75
--- /dev/null
+++ b/lib/libm/common_source/exp.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)exp.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* EXP(X)
+ * RETURN THE EXPONENTIAL OF X
+ * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS)
+ * CODED IN C BY K.C. NG, 1/19/85;
+ * REVISED BY K.C. NG on 2/6/85, 2/15/85, 3/7/85, 3/24/85, 4/16/85, 6/14/86.
+ *
+ * Required system supported functions:
+ * scalb(x,n)
+ * copysign(x,y)
+ * finite(x)
+ *
+ * Method:
+ * 1. Argument Reduction: given the input x, find r and integer k such
+ * that
+ * x = k*ln2 + r, |r| <= 0.5*ln2 .
+ * r will be represented as r := z+c for better accuracy.
+ *
+ * 2. Compute exp(r) by
+ *
+ * exp(r) = 1 + r + r*R1/(2-R1),
+ * where
+ * R1 = x - x^2*(p1+x^2*(p2+x^2*(p3+x^2*(p4+p5*x^2)))).
+ *
+ * 3. exp(x) = 2^k * exp(r) .
+ *
+ * Special cases:
+ * exp(INF) is INF, exp(NaN) is NaN;
+ * exp(-INF)= 0;
+ * for finite argument, only exp(0)=1 is exact.
+ *
+ * Accuracy:
+ * exp(x) returns the exponential of x nearly rounded. In a test run
+ * with 1,156,000 random arguments on a VAX, the maximum observed
+ * error was 0.869 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+vc(lnhuge, 9.4961163736712506989E1 ,ec1d,43bd,9010,a73e, 7, .BDEC1DA73E9010)
+vc(lntiny,-9.5654310917272452386E1 ,4f01,c3bf,33af,d72e, 7,-.BF4F01D72E33AF)
+vc(invln2, 1.4426950408889634148E0 ,aa3b,40b8,17f1,295c, 1, .B8AA3B295C17F1)
+vc(p1, 1.6666666666666602251E-1 ,aaaa,3f2a,a9f1,aaaa, -2, .AAAAAAAAAAA9F1)
+vc(p2, -2.7777777777015591216E-3 ,0b60,bc36,ec94,b5f5, -8,-.B60B60B5F5EC94)
+vc(p3, 6.6137563214379341918E-5 ,b355,398a,f15f,792e, -13, .8AB355792EF15F)
+vc(p4, -1.6533902205465250480E-6 ,ea0e,b6dd,5f84,2e93, -19,-.DDEA0E2E935F84)
+vc(p5, 4.1381367970572387085E-8 ,bb4b,3431,2683,95f5, -24, .B1BB4B95F52683)
+
+#ifdef vccast
+#define ln2hi vccast(ln2hi)
+#define ln2lo vccast(ln2lo)
+#define lnhuge vccast(lnhuge)
+#define lntiny vccast(lntiny)
+#define invln2 vccast(invln2)
+#define p1 vccast(p1)
+#define p2 vccast(p2)
+#define p3 vccast(p3)
+#define p4 vccast(p4)
+#define p5 vccast(p5)
+#endif
+
+ic(p1, 1.6666666666666601904E-1, -3, 1.555555555553E)
+ic(p2, -2.7777777777015593384E-3, -9, -1.6C16C16BEBD93)
+ic(p3, 6.6137563214379343612E-5, -14, 1.1566AAF25DE2C)
+ic(p4, -1.6533902205465251539E-6, -20, -1.BBD41C5D26BF1)
+ic(p5, 4.1381367970572384604E-8, -25, 1.6376972BEA4D0)
+ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10,-33, 1.A39EF35793C76)
+ic(lnhuge, 7.1602103751842355450E2, 9, 1.6602B15B7ECF2)
+ic(lntiny,-7.5137154372698068983E2, 9, -1.77AF8EBEAE354)
+ic(invln2, 1.4426950408889633870E0, 0, 1.71547652B82FE)
+
+double exp(x)
+double x;
+{
+ double z,hi,lo,c;
+ int k;
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ if( x <= lnhuge ) {
+ if( x >= lntiny ) {
+
+ /* argument reduction : x --> x - k*ln2 */
+
+ k=invln2*x+copysign(0.5,x); /* k=NINT(x/ln2) */
+
+ /* express x-k*ln2 as hi-lo and let x=hi-lo rounded */
+
+ hi=x-k*ln2hi;
+ x=hi-(lo=k*ln2lo);
+
+ /* return 2^k*[1+x+x*c/(2+c)] */
+ z=x*x;
+ c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5))));
+ return scalb(1.0+(hi-(lo-(x*c)/(2.0-c))),k);
+
+ }
+ /* end of x > lntiny */
+
+ else
+ /* exp(-big#) underflows to zero */
+ if(finite(x)) return(scalb(1.0,-5000));
+
+ /* exp(-INF) is zero */
+ else return(0.0);
+ }
+ /* end of x < lnhuge */
+
+ else
+ /* exp(INF) is INF, exp(+big#) overflows to INF */
+ return( finite(x) ? scalb(1.0,5000) : x);
+}
+
+/* returns exp(r = x + c) for |c| < |x| with no overlap. */
+
+double __exp__D(x, c)
+double x, c;
+{
+ double z,hi,lo, t;
+ int k;
+
+#if !defined(vax)&&!defined(tahoe)
+ if (x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ if ( x <= lnhuge ) {
+ if ( x >= lntiny ) {
+
+ /* argument reduction : x --> x - k*ln2 */
+ z = invln2*x;
+ k = z + copysign(.5, x);
+
+ /* express (x+c)-k*ln2 as hi-lo and let x=hi-lo rounded */
+
+ hi=(x-k*ln2hi); /* Exact. */
+ x= hi - (lo = k*ln2lo-c);
+ /* return 2^k*[1+x+x*c/(2+c)] */
+ z=x*x;
+ c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5))));
+ c = (x*c)/(2.0-c);
+
+ return scalb(1.+(hi-(lo - c)), k);
+ }
+ /* end of x > lntiny */
+
+ else
+ /* exp(-big#) underflows to zero */
+ if(finite(x)) return(scalb(1.0,-5000));
+
+ /* exp(-INF) is zero */
+ else return(0.0);
+ }
+ /* end of x < lnhuge */
+
+ else
+ /* exp(INF) is INF, exp(+big#) overflows to INF */
+ return( finite(x) ? scalb(1.0,5000) : x);
+}
diff --git a/lib/libm/common_source/exp__E.c b/lib/libm/common_source/exp__E.c
new file mode 100644
index 0000000..16ec4cbb
--- /dev/null
+++ b/lib/libm/common_source/exp__E.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)exp__E.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* exp__E(x,c)
+ * ASSUMPTION: c << x SO THAT fl(x+c)=x.
+ * (c is the correction term for x)
+ * exp__E RETURNS
+ *
+ * / exp(x+c) - 1 - x , 1E-19 < |x| < .3465736
+ * exp__E(x,c) = |
+ * \ 0 , |x| < 1E-19.
+ *
+ * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS)
+ * KERNEL FUNCTION OF EXP, EXPM1, POW FUNCTIONS
+ * CODED IN C BY K.C. NG, 1/31/85;
+ * REVISED BY K.C. NG on 3/16/85, 4/16/85.
+ *
+ * Required system supported function:
+ * copysign(x,y)
+ *
+ * Method:
+ * 1. Rational approximation. Let r=x+c.
+ * Based on
+ * 2 * sinh(r/2)
+ * exp(r) - 1 = ---------------------- ,
+ * cosh(r/2) - sinh(r/2)
+ * exp__E(r) is computed using
+ * x*x (x/2)*W - ( Q - ( 2*P + x*P ) )
+ * --- + (c + x*[---------------------------------- + c ])
+ * 2 1 - W
+ * where P := p1*x^2 + p2*x^4,
+ * Q := q1*x^2 + q2*x^4 (for 56 bits precision, add q3*x^6)
+ * W := x/2-(Q-x*P),
+ *
+ * (See the listing below for the values of p1,p2,q1,q2,q3. The poly-
+ * nomials P and Q may be regarded as the approximations to sinh
+ * and cosh :
+ * sinh(r/2) = r/2 + r * P , cosh(r/2) = 1 + Q . )
+ *
+ * The coefficients were obtained by a special Remez algorithm.
+ *
+ * Approximation error:
+ *
+ * | exp(x) - 1 | 2**(-57), (IEEE double)
+ * | ------------ - (exp__E(x,0)+x)/x | <=
+ * | x | 2**(-69). (VAX D)
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(p1, 1.5150724356786683059E-2 ,3abe,3d78,066a,67e1, -6, .F83ABE67E1066A)
+vc(p2, 6.3112487873718332688E-5 ,5b42,3984,0173,48cd, -13, .845B4248CD0173)
+vc(q1, 1.1363478204690669916E-1 ,b95a,3ee8,ec45,44a2, -3, .E8B95A44A2EC45)
+vc(q2, 1.2624568129896839182E-3 ,7905,3ba5,f5e7,72e4, -9, .A5790572E4F5E7)
+vc(q3, 1.5021856115869022674E-6 ,9eb4,36c9,c395,604a, -19, .C99EB4604AC395)
+
+ic(p1, 1.3887401997267371720E-2, -7, 1.C70FF8B3CC2CF)
+ic(p2, 3.3044019718331897649E-5, -15, 1.15317DF4526C4)
+ic(q1, 1.1110813732786649355E-1, -4, 1.C719538248597)
+ic(q2, 9.9176615021572857300E-4, -10, 1.03FC4CB8C98E8)
+
+#ifdef vccast
+#define p1 vccast(p1)
+#define p2 vccast(p2)
+#define q1 vccast(q1)
+#define q2 vccast(q2)
+#define q3 vccast(q3)
+#endif
+
+double __exp__E(x,c)
+double x,c;
+{
+ const static double zero=0.0, one=1.0, half=1.0/2.0, small=1.0E-19;
+ double z,p,q,xp,xh,w;
+ if(copysign(x,one)>small) {
+ z = x*x ;
+ p = z*( p1 +z* p2 );
+#if defined(vax)||defined(tahoe)
+ q = z*( q1 +z*( q2 +z* q3 ));
+#else /* defined(vax)||defined(tahoe) */
+ q = z*( q1 +z* q2 );
+#endif /* defined(vax)||defined(tahoe) */
+ xp= x*p ;
+ xh= x*half ;
+ w = xh-(q-xp) ;
+ p = p+p;
+ c += x*((xh*w-(q-(p+xp)))/(one-w)+c);
+ return(z*half+c);
+ }
+ /* end of |x| > small */
+
+ else {
+ if(x!=zero) one+small; /* raise the inexact flag */
+ return(copysign(zero,x));
+ }
+}
diff --git a/lib/libm/common_source/expm1.c b/lib/libm/common_source/expm1.c
new file mode 100644
index 0000000..8a84f14
--- /dev/null
+++ b/lib/libm/common_source/expm1.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)expm1.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* EXPM1(X)
+ * RETURN THE EXPONENTIAL OF X MINUS ONE
+ * DOUBLE PRECISION (IEEE 53 BITS, VAX D FORMAT 56 BITS)
+ * CODED IN C BY K.C. NG, 1/19/85;
+ * REVISED BY K.C. NG on 2/6/85, 3/7/85, 3/21/85, 4/16/85.
+ *
+ * Required system supported functions:
+ * scalb(x,n)
+ * copysign(x,y)
+ * finite(x)
+ *
+ * Kernel function:
+ * exp__E(x,c)
+ *
+ * Method:
+ * 1. Argument Reduction: given the input x, find r and integer k such
+ * that
+ * x = k*ln2 + r, |r| <= 0.5*ln2 .
+ * r will be represented as r := z+c for better accuracy.
+ *
+ * 2. Compute EXPM1(r)=exp(r)-1 by
+ *
+ * EXPM1(r=z+c) := z + exp__E(z,c)
+ *
+ * 3. EXPM1(x) = 2^k * ( EXPM1(r) + 1-2^-k ).
+ *
+ * Remarks:
+ * 1. When k=1 and z < -0.25, we use the following formula for
+ * better accuracy:
+ * EXPM1(x) = 2 * ( (z+0.5) + exp__E(z,c) )
+ * 2. To avoid rounding error in 1-2^-k where k is large, we use
+ * EXPM1(x) = 2^k * { [z+(exp__E(z,c)-2^-k )] + 1 }
+ * when k>56.
+ *
+ * Special cases:
+ * EXPM1(INF) is INF, EXPM1(NaN) is NaN;
+ * EXPM1(-INF)= -1;
+ * for finite argument, only EXPM1(0)=0 is exact.
+ *
+ * Accuracy:
+ * EXPM1(x) returns the exact (exp(x)-1) nearly rounded. In a test run with
+ * 1,166,000 random arguments on a VAX, the maximum observed error was
+ * .872 ulps (units of the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+vc(lnhuge, 9.4961163736712506989E1 ,ec1d,43bd,9010,a73e, 7, .BDEC1DA73E9010)
+vc(invln2, 1.4426950408889634148E0 ,aa3b,40b8,17f1,295c, 1, .B8AA3B295C17F1)
+
+ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76)
+ic(lnhuge, 7.1602103751842355450E2, 9, 1.6602B15B7ECF2)
+ic(invln2, 1.4426950408889633870E0, 0, 1.71547652B82FE)
+
+#ifdef vccast
+#define ln2hi vccast(ln2hi)
+#define ln2lo vccast(ln2lo)
+#define lnhuge vccast(lnhuge)
+#define invln2 vccast(invln2)
+#endif
+
+double expm1(x)
+double x;
+{
+ const static double one=1.0, half=1.0/2.0;
+ double z,hi,lo,c;
+ int k;
+#if defined(vax)||defined(tahoe)
+ static prec=56;
+#else /* defined(vax)||defined(tahoe) */
+ static prec=53;
+#endif /* defined(vax)||defined(tahoe) */
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+
+ if( x <= lnhuge ) {
+ if( x >= -40.0 ) {
+
+ /* argument reduction : x - k*ln2 */
+ k= invln2 *x+copysign(0.5,x); /* k=NINT(x/ln2) */
+ hi=x-k*ln2hi ;
+ z=hi-(lo=k*ln2lo);
+ c=(hi-z)-lo;
+
+ if(k==0) return(z+__exp__E(z,c));
+ if(k==1)
+ if(z< -0.25)
+ {x=z+half;x +=__exp__E(z,c); return(x+x);}
+ else
+ {z+=__exp__E(z,c); x=half+z; return(x+x);}
+ /* end of k=1 */
+
+ else {
+ if(k<=prec)
+ { x=one-scalb(one,-k); z += __exp__E(z,c);}
+ else if(k<100)
+ { x = __exp__E(z,c)-scalb(one,-k); x+=z; z=one;}
+ else
+ { x = __exp__E(z,c)+z; z=one;}
+
+ return (scalb(x+z,k));
+ }
+ }
+ /* end of x > lnunfl */
+
+ else
+ /* expm1(-big#) rounded to -1 (inexact) */
+ if(finite(x))
+ { ln2hi+ln2lo; return(-one);}
+
+ /* expm1(-INF) is -1 */
+ else return(-one);
+ }
+ /* end of x < lnhuge */
+
+ else
+ /* expm1(INF) is INF, expm1(+big#) overflows to INF */
+ return( finite(x) ? scalb(one,5000) : x);
+}
diff --git a/lib/libm/common_source/fabs.3 b/lib/libm/common_source/fabs.3
new file mode 100644
index 0000000..7e2c0a7
--- /dev/null
+++ b/lib/libm/common_source/fabs.3
@@ -0,0 +1,67 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" @(#)fabs.3 8.1 (Berkeley) 6/4/93
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fabs.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt FABS 3
+.Os
+.Sh NAME
+.Nm fabs
+.Nd floating-point absolute value function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn fabs "double x"
+.Sh DESCRIPTION
+The
+.Fn fabs
+function computes the absolute value of a floating-point number
+.Fa x .
+.Sh RETURN VALUES
+The
+.Fn fabs
+function returns the absolute value of
+.Fa x .
+.Sh SEE ALSO
+.Xr abs 3 ,
+.Xr ceil 3 ,
+.Xr floor 3 ,
+.Xr ieee 3 ,
+.Xr math 3 ,
+.Xr rint 3
+.Sh STANDARDS
+The
+.Fn fabs
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/floor.3 b/lib/libm/common_source/floor.3
new file mode 100644
index 0000000..5517f00
--- /dev/null
+++ b/lib/libm/common_source/floor.3
@@ -0,0 +1,66 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)floor.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt FLOOR 3
+.Os
+.Sh NAME
+.Nm floor
+.Nd largest integral value less than or equal to x
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn floor "double x"
+.Sh DESCRIPTION
+The
+.Fn floor
+function computes the largest integral value less than or equal to
+.Fa x .
+.Sh RETURN VALUES
+The
+.Fn floor
+function returns the largest integral value
+expressed as a double.
+.Sh SEE ALSO
+.Xr abs 3 ,
+.Xr fabs 3 ,
+.Xr floor 3 ,
+.Xr ieee 3 ,
+.Xr math 3 ,
+.Xr rint 3
+.Sh STANDARDS
+The
+.Fn floor
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/floor.c b/lib/libm/common_source/floor.c
new file mode 100644
index 0000000..5990067
--- /dev/null
+++ b/lib/libm/common_source/floor.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)floor.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include "mathimpl.h"
+
+vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */
+
+ic(L, 4503599627370496.0E0, 52, 1.0) /* 2**52 */
+
+#ifdef vccast
+#define L vccast(L)
+#endif
+
+/*
+ * floor(x) := the largest integer no larger than x;
+ * ceil(x) := -floor(-x), for all real x.
+ *
+ * Note: Inexact will be signaled if x is not an integer, as is
+ * customary for IEEE 754. No other signal can be emitted.
+ */
+double
+floor(x)
+double x;
+{
+ volatile double y;
+
+ if (
+#if !defined(vax)&&!defined(tahoe)
+ x != x || /* NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ x >= L) /* already an even integer */
+ return x;
+ else if (x < (double)0)
+ return -ceil(-x);
+ else { /* now 0 <= x < L */
+ y = L+x; /* destructive store must be forced */
+ y -= L; /* an integer, and |x-y| < 1 */
+ return x < y ? y-(double)1 : y;
+ }
+}
+
+double
+ceil(x)
+double x;
+{
+ volatile double y;
+
+ if (
+#if !defined(vax)&&!defined(tahoe)
+ x != x || /* NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ x >= L) /* already an even integer */
+ return x;
+ else if (x < (double)0)
+ return -floor(-x);
+ else { /* now 0 <= x < L */
+ y = L+x; /* destructive store must be forced */
+ y -= L; /* an integer, and |x-y| < 1 */
+ return x > y ? y+(double)1 : y;
+ }
+}
+
+#ifndef ns32000 /* rint() is in ./NATIONAL/support.s */
+/*
+ * algorithm for rint(x) in pseudo-pascal form ...
+ *
+ * real rint(x): real x;
+ * ... delivers integer nearest x in direction of prevailing rounding
+ * ... mode
+ * const L = (last consecutive integer)/2
+ * = 2**55; for VAX D
+ * = 2**52; for IEEE 754 Double
+ * real s,t;
+ * begin
+ * if x != x then return x; ... NaN
+ * if |x| >= L then return x; ... already an integer
+ * s := copysign(L,x);
+ * t := x + s; ... = (x+s) rounded to integer
+ * return t - s
+ * end;
+ *
+ * Note: Inexact will be signaled if x is not an integer, as is
+ * customary for IEEE 754. No other signal can be emitted.
+ */
+double
+rint(x)
+double x;
+{
+ double s;
+ volatile double t;
+ const double one = 1.0;
+
+#if !defined(vax)&&!defined(tahoe)
+ if (x != x) /* NaN */
+ return (x);
+#endif /* !defined(vax)&&!defined(tahoe) */
+ if (copysign(x,one) >= L) /* already an integer */
+ return (x);
+ s = copysign(L,x);
+ t = x + s; /* x+s rounded to integer */
+ return (t - s);
+}
+#endif /* not national */
diff --git a/lib/libm/common_source/fmod.3 b/lib/libm/common_source/fmod.3
new file mode 100644
index 0000000..43309a5
--- /dev/null
+++ b/lib/libm/common_source/fmod.3
@@ -0,0 +1,76 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)fmod.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt FMOD 3
+.Os
+.Sh NAME
+.Nm fmod
+.Nd floating-point remainder function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn fmod "double x" "double y"
+.Sh DESCRIPTION
+The
+.Fn fmod
+function computes the floating-point remainder of
+.Fa x Ns / Fa y .
+.Sh RETURN VALUES
+The
+.Fn fmod
+function returns the value
+.Sm off
+.Fa x - Em i * Fa y ,
+.Sm on
+for some integer
+.Em i
+such that, if
+.Fa y
+is non-zero, the result has the same sign as
+.Fa x
+and magnitude less than the magnitude of
+.Fa y .
+If
+.Fa y
+is zero, whether a domain error occurs or the
+.Fn fmod
+function returns zero is implementation-defined.
+.Sh SEE ALSO
+.Xr math 3
+.Sh STANDARDS
+The
+.Fn fmod
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/fmod.c b/lib/libm/common_source/fmod.c
new file mode 100644
index 0000000..09a31b2
--- /dev/null
+++ b/lib/libm/common_source/fmod.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)fmod.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* fmod.c
+ *
+ * SYNOPSIS
+ *
+ * #include <math.h>
+ * double fmod(double x, double y)
+ *
+ * DESCRIPTION
+ *
+ * The fmod function computes the floating-point remainder of x/y.
+ *
+ * RETURNS
+ *
+ * The fmod function returns the value x-i*y, for some integer i
+ * such that, if y is nonzero, the result has the same sign as x and
+ * magnitude less than the magnitude of y.
+ *
+ * On a VAX or CCI,
+ *
+ * fmod(x,0) traps/faults on floating-point divided-by-zero.
+ *
+ * On IEEE-754 conforming machines with "isnan()" primitive,
+ *
+ * fmod(x,0), fmod(INF,y) are invalid operations and NaN is returned.
+ *
+ */
+#if !defined(vax) && !defined(tahoe)
+extern int isnan(),finite();
+#endif /* !defined(vax) && !defined(tahoe) */
+extern double frexp(),ldexp(),fabs();
+
+#ifdef TEST_FMOD
+static double
+_fmod(x,y)
+#else /* TEST_FMOD */
+double
+fmod(x,y)
+#endif /* TEST_FMOD */
+double x,y;
+{
+ int ir,iy;
+ double r,w;
+
+ if (y == (double)0
+#if !defined(vax) && !defined(tahoe) /* per "fmod" manual entry, SunOS 4.0 */
+ || isnan(y) || !finite(x)
+#endif /* !defined(vax) && !defined(tahoe) */
+ )
+ return (x*y)/(x*y);
+
+ r = fabs(x);
+ y = fabs(y);
+ (void)frexp(y,&iy);
+ while (r >= y) {
+ (void)frexp(r,&ir);
+ w = ldexp(y,ir-iy);
+ r -= w <= r ? w : w*(double)0.5;
+ }
+ return x >= (double)0 ? r : -r;
+}
+
+#ifdef TEST_FMOD
+extern long random();
+extern double fmod();
+
+#define NTEST 10000
+#define NCASES 3
+
+static int nfail = 0;
+
+static void
+doit(x,y)
+double x,y;
+{
+ double ro = fmod(x,y),rn = _fmod(x,y);
+ if (ro != rn) {
+ (void)printf(" x = 0x%08.8x %08.8x (%24.16e)\n",x,x);
+ (void)printf(" y = 0x%08.8x %08.8x (%24.16e)\n",y,y);
+ (void)printf(" fmod = 0x%08.8x %08.8x (%24.16e)\n",ro,ro);
+ (void)printf("_fmod = 0x%08.8x %08.8x (%24.16e)\n",rn,rn);
+ (void)printf("\n");
+ }
+}
+
+main()
+{
+ register int i,cases;
+ double x,y;
+
+ srandom(12345);
+ for (i = 0; i < NTEST; i++) {
+ x = (double)random();
+ y = (double)random();
+ for (cases = 0; cases < NCASES; cases++) {
+ switch (cases) {
+ case 0:
+ break;
+ case 1:
+ y = (double)1/y; break;
+ case 2:
+ x = (double)1/x; break;
+ default:
+ abort(); break;
+ }
+ doit(x,y);
+ doit(x,-y);
+ doit(-x,y);
+ doit(-x,-y);
+ }
+ }
+ if (nfail)
+ (void)printf("Number of failures: %d (out of a total of %d)\n",
+ nfail,NTEST*NCASES*4);
+ else
+ (void)printf("No discrepancies were found\n");
+ exit(0);
+}
+#endif /* TEST_FMOD */
diff --git a/lib/libm/common_source/gamma.c b/lib/libm/common_source/gamma.c
new file mode 100644
index 0000000..5d270f0
--- /dev/null
+++ b/lib/libm/common_source/gamma.c
@@ -0,0 +1,336 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)gamma.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * This code by P. McIlroy, Oct 1992;
+ *
+ * The financial support of UUNET Communications Services is greatfully
+ * acknowledged.
+ */
+
+#include <math.h>
+#include "mathimpl.h"
+#include <errno.h>
+
+/* METHOD:
+ * x < 0: Use reflection formula, G(x) = pi/(sin(pi*x)*x*G(x))
+ * At negative integers, return +Inf, and set errno.
+ *
+ * x < 6.5:
+ * Use argument reduction G(x+1) = xG(x) to reach the
+ * range [1.066124,2.066124]. Use a rational
+ * approximation centered at the minimum (x0+1) to
+ * ensure monotonicity.
+ *
+ * x >= 6.5: Use the asymptotic approximation (Stirling's formula)
+ * adjusted for equal-ripples:
+ *
+ * log(G(x)) ~= (x-.5)*(log(x)-1) + .5(log(2*pi)-1) + 1/x*P(1/(x*x))
+ *
+ * Keep extra precision in multiplying (x-.5)(log(x)-1), to
+ * avoid premature round-off.
+ *
+ * Special values:
+ * non-positive integer: Set overflow trap; return +Inf;
+ * x > 171.63: Set overflow trap; return +Inf;
+ * NaN: Set invalid trap; return NaN
+ *
+ * Accuracy: Gamma(x) is accurate to within
+ * x > 0: error provably < 0.9ulp.
+ * Maximum observed in 1,000,000 trials was .87ulp.
+ * x < 0:
+ * Maximum observed error < 4ulp in 1,000,000 trials.
+ */
+
+static double neg_gam __P((double));
+static double small_gam __P((double));
+static double smaller_gam __P((double));
+static struct Double large_gam __P((double));
+static struct Double ratfun_gam __P((double, double));
+
+/*
+ * Rational approximation, A0 + x*x*P(x)/Q(x), on the interval
+ * [1.066.., 2.066..] accurate to 4.25e-19.
+ */
+#define LEFT -.3955078125 /* left boundary for rat. approx */
+#define x0 .461632144968362356785 /* xmin - 1 */
+
+#define a0_hi 0.88560319441088874992
+#define a0_lo -.00000000000000004996427036469019695
+#define P0 6.21389571821820863029017800727e-01
+#define P1 2.65757198651533466104979197553e-01
+#define P2 5.53859446429917461063308081748e-03
+#define P3 1.38456698304096573887145282811e-03
+#define P4 2.40659950032711365819348969808e-03
+#define Q0 1.45019531250000000000000000000e+00
+#define Q1 1.06258521948016171343454061571e+00
+#define Q2 -2.07474561943859936441469926649e-01
+#define Q3 -1.46734131782005422506287573015e-01
+#define Q4 3.07878176156175520361557573779e-02
+#define Q5 5.12449347980666221336054633184e-03
+#define Q6 -1.76012741431666995019222898833e-03
+#define Q7 9.35021023573788935372153030556e-05
+#define Q8 6.13275507472443958924745652239e-06
+/*
+ * Constants for large x approximation (x in [6, Inf])
+ * (Accurate to 2.8*10^-19 absolute)
+ */
+#define lns2pi_hi 0.418945312500000
+#define lns2pi_lo -.000006779295327258219670263595
+#define Pa0 8.33333333333333148296162562474e-02
+#define Pa1 -2.77777777774548123579378966497e-03
+#define Pa2 7.93650778754435631476282786423e-04
+#define Pa3 -5.95235082566672847950717262222e-04
+#define Pa4 8.41428560346653702135821806252e-04
+#define Pa5 -1.89773526463879200348872089421e-03
+#define Pa6 5.69394463439411649408050664078e-03
+#define Pa7 -1.44705562421428915453880392761e-02
+
+static const double zero = 0., one = 1.0, tiny = 1e-300;
+static int endian;
+/*
+ * TRUNC sets trailing bits in a floating-point number to zero.
+ * is a temporary variable.
+ */
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+#define TRUNC(x) x = (double) (float) (x)
+#else
+#define _IEEE 1
+#define TRUNC(x) *(((int *) &x) + endian) &= 0xf8000000
+#define infnan(x) 0.0
+#endif
+
+double
+gamma(x)
+ double x;
+{
+ struct Double u;
+ endian = (*(int *) &one) ? 1 : 0;
+
+ if (x >= 6) {
+ if(x > 171.63)
+ return(one/zero);
+ u = large_gam(x);
+ return(__exp__D(u.a, u.b));
+ } else if (x >= 1.0 + LEFT + x0)
+ return (small_gam(x));
+ else if (x > 1.e-17)
+ return (smaller_gam(x));
+ else if (x > -1.e-17) {
+ if (x == 0.0)
+ if (!_IEEE) return (infnan(ERANGE));
+ else return (one/x);
+ one+1e-20; /* Raise inexact flag. */
+ return (one/x);
+ } else if (!finite(x)) {
+ if (_IEEE) /* x = NaN, -Inf */
+ return (x*x);
+ else
+ return (infnan(EDOM));
+ } else
+ return (neg_gam(x));
+}
+/*
+ * Accurate to max(ulp(1/128) absolute, 2^-66 relative) error.
+ */
+static struct Double
+large_gam(x)
+ double x;
+{
+ double z, p;
+ int i;
+ struct Double t, u, v;
+
+ z = one/(x*x);
+ p = Pa0+z*(Pa1+z*(Pa2+z*(Pa3+z*(Pa4+z*(Pa5+z*(Pa6+z*Pa7))))));
+ p = p/x;
+
+ u = __log__D(x);
+ u.a -= one;
+ v.a = (x -= .5);
+ TRUNC(v.a);
+ v.b = x - v.a;
+ t.a = v.a*u.a; /* t = (x-.5)*(log(x)-1) */
+ t.b = v.b*u.a + x*u.b;
+ /* return t.a + t.b + lns2pi_hi + lns2pi_lo + p */
+ t.b += lns2pi_lo; t.b += p;
+ u.a = lns2pi_hi + t.b; u.a += t.a;
+ u.b = t.a - u.a;
+ u.b += lns2pi_hi; u.b += t.b;
+ return (u);
+}
+/*
+ * Good to < 1 ulp. (provably .90 ulp; .87 ulp on 1,000,000 runs.)
+ * It also has correct monotonicity.
+ */
+static double
+small_gam(x)
+ double x;
+{
+ double y, ym1, t, x1;
+ struct Double yy, r;
+ y = x - one;
+ ym1 = y - one;
+ if (y <= 1.0 + (LEFT + x0)) {
+ yy = ratfun_gam(y - x0, 0);
+ return (yy.a + yy.b);
+ }
+ r.a = y;
+ TRUNC(r.a);
+ yy.a = r.a - one;
+ y = ym1;
+ yy.b = r.b = y - yy.a;
+ /* Argument reduction: G(x+1) = x*G(x) */
+ for (ym1 = y-one; ym1 > LEFT + x0; y = ym1--, yy.a--) {
+ t = r.a*yy.a;
+ r.b = r.a*yy.b + y*r.b;
+ r.a = t;
+ TRUNC(r.a);
+ r.b += (t - r.a);
+ }
+ /* Return r*gamma(y). */
+ yy = ratfun_gam(y - x0, 0);
+ y = r.b*(yy.a + yy.b) + r.a*yy.b;
+ y += yy.a*r.a;
+ return (y);
+}
+/*
+ * Good on (0, 1+x0+LEFT]. Accurate to 1ulp.
+ */
+static double
+smaller_gam(x)
+ double x;
+{
+ double t, d;
+ struct Double r, xx;
+ if (x < x0 + LEFT) {
+ t = x, TRUNC(t);
+ d = (t+x)*(x-t);
+ t *= t;
+ xx.a = (t + x), TRUNC(xx.a);
+ xx.b = x - xx.a; xx.b += t; xx.b += d;
+ t = (one-x0); t += x;
+ d = (one-x0); d -= t; d += x;
+ x = xx.a + xx.b;
+ } else {
+ xx.a = x, TRUNC(xx.a);
+ xx.b = x - xx.a;
+ t = x - x0;
+ d = (-x0 -t); d += x;
+ }
+ r = ratfun_gam(t, d);
+ d = r.a/x, TRUNC(d);
+ r.a -= d*xx.a; r.a -= d*xx.b; r.a += r.b;
+ return (d + r.a/x);
+}
+/*
+ * returns (z+c)^2 * P(z)/Q(z) + a0
+ */
+static struct Double
+ratfun_gam(z, c)
+ double z, c;
+{
+ int i;
+ double p, q;
+ struct Double r, t;
+
+ q = Q0 +z*(Q1+z*(Q2+z*(Q3+z*(Q4+z*(Q5+z*(Q6+z*(Q7+z*Q8)))))));
+ p = P0 + z*(P1 + z*(P2 + z*(P3 + z*P4)));
+
+ /* return r.a + r.b = a0 + (z+c)^2*p/q, with r.a truncated to 26 bits. */
+ p = p/q;
+ t.a = z, TRUNC(t.a); /* t ~= z + c */
+ t.b = (z - t.a) + c;
+ t.b *= (t.a + z);
+ q = (t.a *= t.a); /* t = (z+c)^2 */
+ TRUNC(t.a);
+ t.b += (q - t.a);
+ r.a = p, TRUNC(r.a); /* r = P/Q */
+ r.b = p - r.a;
+ t.b = t.b*p + t.a*r.b + a0_lo;
+ t.a *= r.a; /* t = (z+c)^2*(P/Q) */
+ r.a = t.a + a0_hi, TRUNC(r.a);
+ r.b = ((a0_hi-r.a) + t.a) + t.b;
+ return (r); /* r = a0 + t */
+}
+
+static double
+neg_gam(x)
+ double x;
+{
+ int sgn = 1;
+ struct Double lg, lsine;
+ double y, z;
+
+ y = floor(x + .5);
+ if (y == x) /* Negative integer. */
+ if(!_IEEE)
+ return (infnan(ERANGE));
+ else
+ return (one/zero);
+ z = fabs(x - y);
+ y = .5*ceil(x);
+ if (y == ceil(y))
+ sgn = -1;
+ if (z < .25)
+ z = sin(M_PI*z);
+ else
+ z = cos(M_PI*(0.5-z));
+ /* Special case: G(1-x) = Inf; G(x) may be nonzero. */
+ if (x < -170) {
+ if (x < -190)
+ return ((double)sgn*tiny*tiny);
+ y = one - x; /* exact: 128 < |x| < 255 */
+ lg = large_gam(y);
+ lsine = __log__D(M_PI/z); /* = TRUNC(log(u)) + small */
+ lg.a -= lsine.a; /* exact (opposite signs) */
+ lg.b -= lsine.b;
+ y = -(lg.a + lg.b);
+ z = (y + lg.a) + lg.b;
+ y = __exp__D(y, z);
+ if (sgn < 0) y = -y;
+ return (y);
+ }
+ y = one-x;
+ if (one-y == x)
+ y = gamma(y);
+ else /* 1-x is inexact */
+ y = -x*gamma(-x);
+ if (sgn < 0) y = -y;
+ return (M_PI / (y*z));
+}
diff --git a/lib/libm/common_source/hypot.3 b/lib/libm/common_source/hypot.3
new file mode 100644
index 0000000..2d2ad3e
--- /dev/null
+++ b/lib/libm/common_source/hypot.3
@@ -0,0 +1,125 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)hypot.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt HYPOT 3
+.Os BSD 4
+.Sh NAME
+.Nm hypot ,
+.Nm cabs
+.Nd euclidean distance and complex absolute value functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn hypot "double x" "double y"
+.Fd struct {double x, y;} z;
+.Ft double
+.Fn cabs z
+.Sh DESCRIPTION
+The
+.Fn hypot
+and
+.Fn cabs
+functions
+computes the
+sqrt(x*x+y*y)
+in such a way that underflow will not happen, and overflow
+occurs only if the final result deserves it.
+.Pp
+.Fn hypot "\*(If" "v"
+=
+.Fn hypot "v" "\*(If"
+= +\*(If for all
+.Ar v ,
+including \*(Na.
+.Sh ERROR (due to Roundoff, etc.)
+Below 0.97
+.Em ulps .
+Consequently
+.Fn hypot "5.0" "12.0"
+= 13.0
+exactly;
+in general, hypot and cabs return an integer whenever an
+integer might be expected.
+.Pp
+The same cannot be said for the shorter and faster version of hypot
+and cabs that is provided in the comments in cabs.c; its error can
+exceed 1.2
+.Em ulps .
+.Sh NOTES
+As might be expected,
+.Fn hypot "v" "\*(Na"
+and
+.Fn hypot "\*(Na" "v"
+are \*(Na for all
+.Em finite
+.Ar v ;
+with "reserved operand" in place of "\*(Na", the
+same is true on a
+.Tn VAX .
+But programmers on machines other than a
+.Tn VAX
+(if has no \*(If)
+might be surprised at first to discover that
+.Fn hypot "\(+-\*(If" "\*(Na"
+= +\*(If.
+This is intentional; it happens because
+.Fn hypot "\*(If" "v"
+= +\*(If
+for
+.Em all
+.Ar v ,
+finite or infinite.
+Hence
+.Fn hypot "\*(If" "v"
+is independent of
+.Ar v .
+Unlike the reserved operand fault on a
+.Tn VAX ,
+the
+.Tn IEEE
+\*(Na is designed to
+disappear when it turns out to be irrelevant, as it does in
+.Fn hypot "\*(If" "\*(Na" .
+.Sh SEE ALSO
+.Xr math 3 ,
+.Xr sqrt 3
+.Sh HISTORY
+Both a
+.Fn hypot
+function and a
+.Fn cabs
+function
+appeared in
+.At v7 .
diff --git a/lib/libm/common_source/ieee.3 b/lib/libm/common_source/ieee.3
new file mode 100644
index 0000000..29eb44c
--- /dev/null
+++ b/lib/libm/common_source/ieee.3
@@ -0,0 +1,268 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ieee.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt IEEE 3
+.Os BSD 4.3
+.Sh NAME
+.Nm copysign ,
+.Nm drem ,
+.Nm finite ,
+.Nm logb ,
+.Nm scalb
+.Nd "IEEE 754 floating point support
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn copysign "double x" "double y"
+.Ft double
+.Fn drem "double x" "double y"
+.Ft int
+.Fn finite "double x"
+.Ft double
+.Fn logb "double x"
+.Ft double
+.Fn scalb "double x" "int n"
+.Sh DESCRIPTION
+These functions are required for, or recommended by the
+.Tn IEEE
+standard
+754 for floating\-point arithmetic.
+.Pp
+The
+.Fn copysign
+function
+returns
+.Fa x
+with its sign changed to
+.Fa y Ns 's.
+.Pp
+The
+.Fn drem
+function
+returns the remainder
+.Fa r
+:=
+.Fa x
+\-
+.Fa n\(**y
+where
+.Fa n
+is the integer nearest the exact value of
+.Bk -words
+.Fa x Ns / Ns Fa y ;
+.Ek
+moreover if
+.Pf \\*(Ba Fa n
+\-
+.Sm off
+.Fa x No / Fa y No \\*(Ba
+.Sm on
+=
+1/2
+then
+.Fa n
+is even. Consequently
+the remainder is computed exactly and
+.Sm off
+.Pf \\*(Ba Fa r No \\*(Ba
+.Sm on
+\*(Le
+.Sm off
+.Pf \\*(Ba Fa y No \\*(Ba/2.
+.Sm on
+But
+.Fn drem x 0
+is exceptional.
+(See below under
+.Sx DIAGNOSTICS . )
+.Pp
+The
+.Fn finite
+function returns the value 1 just when
+\-\*(If \*(Lt
+.Fa x
+\*(Lt +\*(If;
+otherwise a
+zero is returned
+(when
+.Pf \\*(Ba Ns Fa x Ns \\*(Ba
+= \*(If or
+.Fa x
+is \*(Na or
+is the
+.Tn VAX Ns 's
+reserved operand).
+.Pp
+The
+.Fn logb
+function returns
+.Fa x Ns 's exponent
+.Fa n ,
+a signed integer converted to double\-precision floating\-point and so
+chosen that
+1 (<=
+.Pf \\*(Ba Ns Fa x Ns \\*(Ba2** Ns Fa n
+< 2
+unless
+.Fa x
+= 0 or
+(only on machines that conform to
+.Tn IEEE
+754)
+.Pf \\*(Ba Fa x Ns \\*(Ba
+= \*(If
+or
+.Fa x
+lies between 0 and the Underflow Threshold.
+(See below under
+.Sx BUGS . )
+.Pp
+The
+.Fn scalb
+function returns
+.Fa x Ns \(**(2** Ns Fa n )
+computed, for integer n, without first computing
+.Pf 2\(** Fa n .
+.Sh RETURN VALUES
+The
+.Tn IEEE
+standard
+754 defines
+.Fn drem x 0
+and
+.Fn drem \\*(If y
+to be invalid operations that produce a \*(Na.
+On the
+.Tn VAX ,
+.Fn drem x 0
+generates a reserved operand fault. No \*(If
+exists on a
+.Tn VAX .
+.Pp
+.Tn IEEE
+754 defines
+.if n \
+.Fn logb \(+-\\*(If
+= \*(If and
+.Fn logb 0
+= \-\*(If, and
+requires the latter to signal Division\-by\-Zero.
+But on a
+.Tn VAX ,
+.Fn logb 0
+= 1.0 \- 2.0**31 = \-2,147,483,647.0.
+And if the correct value of
+.Fn scalb
+would overflow on a
+.Tn VAX ,
+it generates a reserved operand fault and sets the global variable
+.Va errno
+to
+.Dv ERANGE .
+.Sh SEE ALSO
+.Xr floor 3 ,
+.Xr infnan 3 ,
+.Xr math 3
+.Sh HISTORY
+The
+.Nm ieee
+functions appeared in
+.Bx 4.3 .
+.Sh BUGS
+Should
+.Fn drem x 0
+and
+.Fn logb 0
+on a
+.Tn VAX
+signal invalidity
+by setting
+.Va errno No = Dv EDOM ?
+Should
+.Fn logb 0
+return \-1.7e38?
+.Pp
+.Tn IEEE
+754 currently specifies that
+.Fn logb "denormalized no."
+=
+.Fn logb "tiniest normalized no. > 0"
+but the consensus has changed to the specification in the new
+proposed
+.Tn IEEE
+standard p854, namely that
+.Fn logb x
+satisfy
+.Bd -filled -offset indent
+1 \(<=
+.Fn scalb \\*(Bax\\*(Ba \-logb(x)
+<
+Radix\0 ... = 2
+for
+.Tn IEEE
+754
+.Ed
+.Pp
+for every x except 0,
+\*(If
+and \*(Na.
+Almost every program that assumes 754's specification will work
+correctly if
+.Fn logb
+follows 854's specification instead.
+.Pp
+.Tn IEEE
+754 requires
+.Fn copysign x \\*(Na)
+=
+.Pf \(+- Ns Fa x
+but says nothing
+else about the sign of a \*(Na. A \*(Na
+.Em (N Ns ot
+.Em a
+.Em N Ns umber )
+is
+similar in spirit to the
+.Tn VAX Ns 's
+reserved operand, but very
+different in important details. Since the sign bit of a
+reserved operand makes it look negative,
+.Bd -filled -offset indent
+.Fn copysign x "reserved operand"
+=
+.Pf \- Fa x ;
+.Ed
+.Pp
+should this return the reserved operand instead?
diff --git a/lib/libm/common_source/infnan.3 b/lib/libm/common_source/infnan.3
new file mode 100644
index 0000000..abb7783
--- /dev/null
+++ b/lib/libm/common_source/infnan.3
@@ -0,0 +1,181 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)infnan.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt INFNAN 3
+.Os BSD 4.3
+.Sh NAME
+.Nm infnan
+.Nd signals invalid floating\-point operations on a
+.Tn VAX
+(temporary)
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn infnan "int iarg"
+.Sh DESCRIPTION
+At some time in the future, some of the useful properties of
+the Infinities and \*(Nas in the
+.Tn IEEE
+standard 754 for Binary
+Floating\-Point Arithmetic will be simulated in
+.Tn UNIX
+on the
+.Tn DEC VAX
+by using its Reserved Operands. Meanwhile, the
+Invalid, Overflow and Divide\-by\-Zero exceptions of the
+.Tn IEEE
+standard are being approximated on a
+.Tn VAX
+by calls to a
+procedure
+.Fn infnan
+in appropriate places in
+.Xr libm 3 .
+When
+better exception\-handling is implemented in
+.Tn UNIX ,
+only
+.Fn infnan
+among the codes in
+.Xr libm
+will have to be changed.
+And users of
+.Xr libm
+can design their own
+.Fn infnan
+now to
+insulate themselves from future changes.
+.Pp
+Whenever an elementary function code in
+.Xr libm
+has to
+simulate one of the aforementioned
+.Tn IEEE
+exceptions, it calls
+.Fn infnan iarg
+with an appropriate value of
+.Fa iarg .
+Then a
+reserved operand fault stops computation. But
+.Fn infnan
+could
+be replaced by a function with the same name that returns
+some plausible value, assigns an apt value to the global
+variable
+.Va errno ,
+and allows computation to resume.
+Alternatively, the Reserved Operand Fault Handler could be
+changed to respond by returning that plausible value, etc.
+instead of aborting.
+.Pp
+In the table below, the first two columns show various
+exceptions signaled by the
+.Tn IEEE
+standard, and the default
+result it prescribes. The third column shows what value is
+given to
+.Fa iarg
+by functions in
+.Xr libm
+when they
+invoke
+.Fn infnan iarg
+under analogous circumstances on a
+.Tn VAX .
+Currently
+.Fn infnan
+stops computation under all those
+circumstances. The last two columns offer an alternative;
+they suggest a setting for
+.Va errno
+and a value for a
+revised
+.Fn infnan
+to return. And a C program to
+implement that suggestion follows.
+.sp 0.5
+.Bd -filled -offset indent
+.Bl -column "IEEE Signal" "IEEE Default" XXERANGE ERANGEXXorXXEDOM
+.It IEEE Signal IEEE Default Ta
+.Fa iarg Ta
+.Va errno Ta
+.Fn infnan
+.It Invalid \*(Na Ta
+.Dv EDOM EDOM 0
+.It Overflow \(+-\*(If Ta
+.Dv ERANGE ERANGE HUGE
+.It Div\-by\-0 \(+-Infinity Ta
+.Dv \(+-ERANGE ERANGE or EDOM \(+-HUGE
+.It ( Ns Dv HUGE No "= 1.7e38 ... nearly 2.0**127)"
+.El
+.Ed
+.Pp
+ALTERNATIVE
+.Fn infnan :
+.Bd -literal -offset indent
+#include <math.h>
+#include <errno.h>
+extern int errno ;
+double infnan(iarg)
+int iarg ;
+{
+ switch(iarg) {
+ case \0ERANGE: errno = ERANGE; return(HUGE);
+ case \-ERANGE: errno = EDOM; return(\-HUGE);
+ default: errno = EDOM; return(0);
+ }
+}
+.Ed
+.Sh SEE ALSO
+.Xr intro 2 ,
+.Xr math 3 ,
+.Xr signal 3 .
+.Pp
+.Dv ERANGE
+and
+.Dv EDOM
+are defined in
+.Aq Pa errno.h .
+(See
+.Xr intro 2
+for explanation of
+.Dv EDOM
+and
+.Dv ERANGE . )
+.Sh HISTORY
+The
+.Fn infnan
+function appeared in
+.Bx 4.3 .
diff --git a/lib/libm/common_source/j0.3 b/lib/libm/common_source/j0.3
new file mode 100644
index 0000000..47f412b
--- /dev/null
+++ b/lib/libm/common_source/j0.3
@@ -0,0 +1,127 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)j0.3 8.2 (Berkeley) 4/19/94
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1994
+.Dt J0 3
+.Os BSD 4
+.Sh NAME
+.Nm j0 ,
+.Nm j1 ,
+.Nm jn ,
+.Nm y0 ,
+.Nm y1 ,
+.Nm yn
+.Nd bessel functions of first and second kind
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn j0 "double x"
+.Ft double
+.Fn j1 "double x"
+.Ft double
+.Fn jn "int n" "double x"
+.Ft double
+.Fn y0 "double x"
+.Ft double
+.Fn y1 "double x"
+.Ft double
+.Fn yn "int n" "double x"
+.Sh DESCRIPTION
+The functions
+.Fn j0
+and
+.Fn j1
+compute the
+.Em Bessel function of the first kind of the order
+0 and the
+.Em order
+1, respectively,
+for the
+real value
+.Fa x ;
+the function
+.Fn jn
+computes the
+.Em Bessel function of the first kind of the integer order
+.Fa n
+for the real value
+.Fa x .
+.Pp
+The functions
+.Fn y0
+and
+.Fn y1
+compute the linearly independent
+.Em Bessel function of the second kind of the order
+0 and the
+.Em order
+1, respectively,
+for the positive
+.Em integer
+value
+.Fa x
+(expressed as a double);
+the function
+.Fn yn
+computes the
+.Em Bessel function of the second kind for the integer order
+.Fa n
+for the positive
+.Em integer
+value
+.Fa x
+(expressed as a double).
+.Sh RETURN VALUES
+If these functions are successful,
+the computed value is returned. On the
+.Tn VAX
+and
+.Tn Tahoe
+architectures,
+a negative
+.Fa x
+value
+results in an error; the global
+variable
+.Va errno
+is set to
+.Er EDOM
+and a reserve operand fault is generated.
+.Sh SEE ALSO
+.Xr infnan 3 ,
+.Xr math 3
+.Sh HISTORY
+A set of these functions
+function appeared in
+.At v7 .
diff --git a/lib/libm/common_source/j0.c b/lib/libm/common_source/j0.c
new file mode 100644
index 0000000..684fb4d
--- /dev/null
+++ b/lib/libm/common_source/j0.c
@@ -0,0 +1,439 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)j0.c 8.2 (Berkeley) 11/30/93";
+#endif /* not lint */
+
+/*
+ * 16 December 1992
+ * Minor modifications by Peter McIlroy to adapt non-IEEE architecture.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1992 by Sun Microsystems, Inc.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ * ******************* WARNING ********************
+ * This is an alpha version of SunPro's FDLIBM (Freely
+ * Distributable Math Library) for IEEE double precision
+ * arithmetic. FDLIBM is a basic math library written
+ * in C that runs on machines that conform to IEEE
+ * Standard 754/854. This alpha version is distributed
+ * for testing purpose. Those who use this software
+ * should report any bugs to
+ *
+ * fdlibm-comments@sunpro.eng.sun.com
+ *
+ * -- K.C. Ng, Oct 12, 1992
+ * ************************************************
+ */
+
+/* double j0(double x), y0(double x)
+ * Bessel function of the first and second kinds of order zero.
+ * Method -- j0(x):
+ * 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ...
+ * 2. Reduce x to |x| since j0(x)=j0(-x), and
+ * for x in (0,2)
+ * j0(x) = 1-z/4+ z^2*R0/S0, where z = x*x;
+ * (precision: |j0-1+z/4-z^2R0/S0 |<2**-63.67 )
+ * for x in (2,inf)
+ * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0))
+ * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
+ * as follow:
+ * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+ * = 1/sqrt(2) * (cos(x) + sin(x))
+ * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * (To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.)
+ *
+ * 3 Special cases
+ * j0(nan)= nan
+ * j0(0) = 1
+ * j0(inf) = 0
+ *
+ * Method -- y0(x):
+ * 1. For x<2.
+ * Since
+ * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...)
+ * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function.
+ * We use the following function to approximate y0,
+ * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2
+ * where
+ * U(z) = u0 + u1*z + ... + u6*z^6
+ * V(z) = 1 + v1*z + ... + v4*z^4
+ * with absolute approximation error bounded by 2**-72.
+ * Note: For tiny x, U/V = u0 and j0(x)~1, hence
+ * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27)
+ * 2. For x>=2.
+ * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0))
+ * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
+ * by the method mentioned above.
+ * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0.
+ */
+
+#include <math.h>
+#include <float.h>
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+#else
+#define _IEEE 1
+#define infnan(x) (0.0)
+#endif
+
+static double pzero __P((double)), qzero __P((double));
+
+static double
+huge = 1e300,
+zero = 0.0,
+one = 1.0,
+invsqrtpi= 5.641895835477562869480794515607725858441e-0001,
+tpi = 0.636619772367581343075535053490057448,
+ /* R0/S0 on [0, 2.00] */
+r02 = 1.562499999999999408594634421055018003102e-0002,
+r03 = -1.899792942388547334476601771991800712355e-0004,
+r04 = 1.829540495327006565964161150603950916854e-0006,
+r05 = -4.618326885321032060803075217804816988758e-0009,
+s01 = 1.561910294648900170180789369288114642057e-0002,
+s02 = 1.169267846633374484918570613449245536323e-0004,
+s03 = 5.135465502073181376284426245689510134134e-0007,
+s04 = 1.166140033337900097836930825478674320464e-0009;
+
+double
+j0(x)
+ double x;
+{
+ double z, s,c,ss,cc,r,u,v;
+
+ if (!finite(x))
+ if (_IEEE) return one/(x*x);
+ else return (0);
+ x = fabs(x);
+ if (x >= 2.0) { /* |x| >= 2.0 */
+ s = sin(x);
+ c = cos(x);
+ ss = s-c;
+ cc = s+c;
+ if (x < .5 * DBL_MAX) { /* make sure x+x not overflow */
+ z = -cos(x+x);
+ if ((s*c)<zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /*
+ * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+ * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+ */
+ if (_IEEE && x> 6.80564733841876927e+38) /* 2^129 */
+ z = (invsqrtpi*cc)/sqrt(x);
+ else {
+ u = pzero(x); v = qzero(x);
+ z = invsqrtpi*(u*cc-v*ss)/sqrt(x);
+ }
+ return z;
+ }
+ if (x < 1.220703125e-004) { /* |x| < 2**-13 */
+ if (huge+x > one) { /* raise inexact if x != 0 */
+ if (x < 7.450580596923828125e-009) /* |x|<2**-27 */
+ return one;
+ else return (one - 0.25*x*x);
+ }
+ }
+ z = x*x;
+ r = z*(r02+z*(r03+z*(r04+z*r05)));
+ s = one+z*(s01+z*(s02+z*(s03+z*s04)));
+ if (x < one) { /* |x| < 1.00 */
+ return (one + z*(-0.25+(r/s)));
+ } else {
+ u = 0.5*x;
+ return ((one+u)*(one-u)+z*(r/s));
+ }
+}
+
+static double
+u00 = -7.380429510868722527422411862872999615628e-0002,
+u01 = 1.766664525091811069896442906220827182707e-0001,
+u02 = -1.381856719455968955440002438182885835344e-0002,
+u03 = 3.474534320936836562092566861515617053954e-0004,
+u04 = -3.814070537243641752631729276103284491172e-0006,
+u05 = 1.955901370350229170025509706510038090009e-0008,
+u06 = -3.982051941321034108350630097330144576337e-0011,
+v01 = 1.273048348341237002944554656529224780561e-0002,
+v02 = 7.600686273503532807462101309675806839635e-0005,
+v03 = 2.591508518404578033173189144579208685163e-0007,
+v04 = 4.411103113326754838596529339004302243157e-0010;
+
+double
+y0(x)
+ double x;
+{
+ double z, s, c, ss, cc, u, v;
+ /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */
+ if (!finite(x))
+ if (_IEEE)
+ return (one/(x+x*x));
+ else
+ return (0);
+ if (x == 0)
+ if (_IEEE) return (-one/zero);
+ else return(infnan(-ERANGE));
+ if (x<0)
+ if (_IEEE) return (zero/zero);
+ else return (infnan(EDOM));
+ if (x >= 2.00) { /* |x| >= 2.0 */
+ /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
+ * where x0 = x-pi/4
+ * Better formula:
+ * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+ * = 1/sqrt(2) * (sin(x) + cos(x))
+ * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.
+ */
+ s = sin(x);
+ c = cos(x);
+ ss = s-c;
+ cc = s+c;
+ /*
+ * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+ * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+ */
+ if (x < .5 * DBL_MAX) { /* make sure x+x not overflow */
+ z = -cos(x+x);
+ if ((s*c)<zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ if (_IEEE && x > 6.80564733841876927e+38) /* > 2^129 */
+ z = (invsqrtpi*ss)/sqrt(x);
+ else {
+ u = pzero(x); v = qzero(x);
+ z = invsqrtpi*(u*ss+v*cc)/sqrt(x);
+ }
+ return z;
+ }
+ if (x <= 7.450580596923828125e-009) { /* x < 2**-27 */
+ return (u00 + tpi*log(x));
+ }
+ z = x*x;
+ u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
+ v = one+z*(v01+z*(v02+z*(v03+z*v04)));
+ return (u/v + tpi*(j0(x)*log(x)));
+}
+
+/* The asymptotic expansions of pzero is
+ * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x.
+ * For x >= 2, We approximate pzero by
+ * pzero(x) = 1 + (R/S)
+ * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10
+ * S = 1 + ps0*s^2 + ... + ps4*s^10
+ * and
+ * | pzero(x)-1-R/S | <= 2 ** ( -60.26)
+ */
+static double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+ 0.0,
+ -7.031249999999003994151563066182798210142e-0002,
+ -8.081670412753498508883963849859423939871e+0000,
+ -2.570631056797048755890526455854482662510e+0002,
+ -2.485216410094288379417154382189125598962e+0003,
+ -5.253043804907295692946647153614119665649e+0003,
+};
+static double ps8[5] = {
+ 1.165343646196681758075176077627332052048e+0002,
+ 3.833744753641218451213253490882686307027e+0003,
+ 4.059785726484725470626341023967186966531e+0004,
+ 1.167529725643759169416844015694440325519e+0005,
+ 4.762772841467309430100106254805711722972e+0004,
+};
+
+static double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+ -1.141254646918944974922813501362824060117e-0011,
+ -7.031249408735992804117367183001996028304e-0002,
+ -4.159610644705877925119684455252125760478e+0000,
+ -6.767476522651671942610538094335912346253e+0001,
+ -3.312312996491729755731871867397057689078e+0002,
+ -3.464333883656048910814187305901796723256e+0002,
+};
+static double ps5[5] = {
+ 6.075393826923003305967637195319271932944e+0001,
+ 1.051252305957045869801410979087427910437e+0003,
+ 5.978970943338558182743915287887408780344e+0003,
+ 9.625445143577745335793221135208591603029e+0003,
+ 2.406058159229391070820491174867406875471e+0003,
+};
+
+static double pr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+ -2.547046017719519317420607587742992297519e-0009,
+ -7.031196163814817199050629727406231152464e-0002,
+ -2.409032215495295917537157371488126555072e+0000,
+ -2.196597747348830936268718293366935843223e+0001,
+ -5.807917047017375458527187341817239891940e+0001,
+ -3.144794705948885090518775074177485744176e+0001,
+};
+static double ps3[5] = {
+ 3.585603380552097167919946472266854507059e+0001,
+ 3.615139830503038919981567245265266294189e+0002,
+ 1.193607837921115243628631691509851364715e+0003,
+ 1.127996798569074250675414186814529958010e+0003,
+ 1.735809308133357510239737333055228118910e+0002,
+};
+
+static double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+ -8.875343330325263874525704514800809730145e-0008,
+ -7.030309954836247756556445443331044338352e-0002,
+ -1.450738467809529910662233622603401167409e+0000,
+ -7.635696138235277739186371273434739292491e+0000,
+ -1.119316688603567398846655082201614524650e+0001,
+ -3.233645793513353260006821113608134669030e+0000,
+};
+static double ps2[5] = {
+ 2.222029975320888079364901247548798910952e+0001,
+ 1.362067942182152109590340823043813120940e+0002,
+ 2.704702786580835044524562897256790293238e+0002,
+ 1.538753942083203315263554770476850028583e+0002,
+ 1.465761769482561965099880599279699314477e+0001,
+};
+
+static double pzero(x)
+ double x;
+{
+ double *p,*q,z,r,s;
+ if (x >= 8.00) {p = pr8; q= ps8;}
+ else if (x >= 4.54545211791992188) {p = pr5; q= ps5;}
+ else if (x >= 2.85714149475097656) {p = pr3; q= ps3;}
+ else if (x >= 2.00) {p = pr2; q= ps2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+ return one+ r/s;
+}
+
+
+/* For x >= 8, the asymptotic expansions of qzero is
+ * -1/8 s + 75/1024 s^3 - ..., where s = 1/x.
+ * We approximate pzero by
+ * qzero(x) = s*(-1.25 + (R/S))
+ * where R = qr0 + qr1*s^2 + qr2*s^4 + ... + qr5*s^10
+ * S = 1 + qs0*s^2 + ... + qs5*s^12
+ * and
+ * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22)
+ */
+static double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+ 0.0,
+ 7.324218749999350414479738504551775297096e-0002,
+ 1.176820646822526933903301695932765232456e+0001,
+ 5.576733802564018422407734683549251364365e+0002,
+ 8.859197207564685717547076568608235802317e+0003,
+ 3.701462677768878501173055581933725704809e+0004,
+};
+static double qs8[6] = {
+ 1.637760268956898345680262381842235272369e+0002,
+ 8.098344946564498460163123708054674227492e+0003,
+ 1.425382914191204905277585267143216379136e+0005,
+ 8.033092571195144136565231198526081387047e+0005,
+ 8.405015798190605130722042369969184811488e+0005,
+ -3.438992935378666373204500729736454421006e+0005,
+};
+
+static double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+ 1.840859635945155400568380711372759921179e-0011,
+ 7.324217666126847411304688081129741939255e-0002,
+ 5.835635089620569401157245917610984757296e+0000,
+ 1.351115772864498375785526599119895942361e+0002,
+ 1.027243765961641042977177679021711341529e+0003,
+ 1.989977858646053872589042328678602481924e+0003,
+};
+static double qs5[6] = {
+ 8.277661022365377058749454444343415524509e+0001,
+ 2.077814164213929827140178285401017305309e+0003,
+ 1.884728877857180787101956800212453218179e+0004,
+ 5.675111228949473657576693406600265778689e+0004,
+ 3.597675384251145011342454247417399490174e+0004,
+ -5.354342756019447546671440667961399442388e+0003,
+};
+
+static double qr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+ 4.377410140897386263955149197672576223054e-0009,
+ 7.324111800429115152536250525131924283018e-0002,
+ 3.344231375161707158666412987337679317358e+0000,
+ 4.262184407454126175974453269277100206290e+0001,
+ 1.708080913405656078640701512007621675724e+0002,
+ 1.667339486966511691019925923456050558293e+0002,
+};
+static double qs3[6] = {
+ 4.875887297245871932865584382810260676713e+0001,
+ 7.096892210566060535416958362640184894280e+0002,
+ 3.704148226201113687434290319905207398682e+0003,
+ 6.460425167525689088321109036469797462086e+0003,
+ 2.516333689203689683999196167394889715078e+0003,
+ -1.492474518361563818275130131510339371048e+0002,
+};
+
+static double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+ 1.504444448869832780257436041633206366087e-0007,
+ 7.322342659630792930894554535717104926902e-0002,
+ 1.998191740938159956838594407540292600331e+0000,
+ 1.449560293478857407645853071687125850962e+0001,
+ 3.166623175047815297062638132537957315395e+0001,
+ 1.625270757109292688799540258329430963726e+0001,
+};
+static double qs2[6] = {
+ 3.036558483552191922522729838478169383969e+0001,
+ 2.693481186080498724211751445725708524507e+0002,
+ 8.447837575953201460013136756723746023736e+0002,
+ 8.829358451124885811233995083187666981299e+0002,
+ 2.126663885117988324180482985363624996652e+0002,
+ -5.310954938826669402431816125780738924463e+0000,
+};
+
+static double qzero(x)
+ double x;
+{
+ double *p,*q, s,r,z;
+ if (x >= 8.00) {p = qr8; q= qs8;}
+ else if (x >= 4.54545211791992188) {p = qr5; q= qs5;}
+ else if (x >= 2.85714149475097656) {p = qr3; q= qs3;}
+ else if (x >= 2.00) {p = qr2; q= qs2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+ return (-.125 + r/s)/x;
+}
diff --git a/lib/libm/common_source/j1.c b/lib/libm/common_source/j1.c
new file mode 100644
index 0000000..e8ca43a
--- /dev/null
+++ b/lib/libm/common_source/j1.c
@@ -0,0 +1,446 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)j1.c 8.2 (Berkeley) 11/30/93";
+#endif /* not lint */
+
+/*
+ * 16 December 1992
+ * Minor modifications by Peter McIlroy to adapt non-IEEE architecture.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1992 by Sun Microsystems, Inc.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ * ******************* WARNING ********************
+ * This is an alpha version of SunPro's FDLIBM (Freely
+ * Distributable Math Library) for IEEE double precision
+ * arithmetic. FDLIBM is a basic math library written
+ * in C that runs on machines that conform to IEEE
+ * Standard 754/854. This alpha version is distributed
+ * for testing purpose. Those who use this software
+ * should report any bugs to
+ *
+ * fdlibm-comments@sunpro.eng.sun.com
+ *
+ * -- K.C. Ng, Oct 12, 1992
+ * ************************************************
+ */
+
+/* double j1(double x), y1(double x)
+ * Bessel function of the first and second kinds of order zero.
+ * Method -- j1(x):
+ * 1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ...
+ * 2. Reduce x to |x| since j1(x)=-j1(-x), and
+ * for x in (0,2)
+ * j1(x) = x/2 + x*z*R0/S0, where z = x*x;
+ * (precision: |j1/x - 1/2 - R0/S0 |<2**-61.51 )
+ * for x in (2,inf)
+ * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1))
+ * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
+ * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
+ * as follows:
+ * cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = -1/sqrt(2) * (sin(x) + cos(x))
+ * (To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.)
+ *
+ * 3 Special cases
+ * j1(nan)= nan
+ * j1(0) = 0
+ * j1(inf) = 0
+ *
+ * Method -- y1(x):
+ * 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN
+ * 2. For x<2.
+ * Since
+ * y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...)
+ * therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function.
+ * We use the following function to approximate y1,
+ * y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2
+ * where for x in [0,2] (abs err less than 2**-65.89)
+ * U(z) = u0 + u1*z + ... + u4*z^4
+ * V(z) = 1 + v1*z + ... + v5*z^5
+ * Note: For tiny x, 1/x dominate y1 and hence
+ * y1(tiny) = -2/pi/tiny, (choose tiny<2**-54)
+ * 3. For x>=2.
+ * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
+ * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
+ * by method mentioned above.
+ */
+
+#include <math.h>
+#include <float.h>
+
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+#else
+#define _IEEE 1
+#define infnan(x) (0.0)
+#endif
+
+static double pone(), qone();
+
+static double
+huge = 1e300,
+zero = 0.0,
+one = 1.0,
+invsqrtpi= 5.641895835477562869480794515607725858441e-0001,
+tpi = 0.636619772367581343075535053490057448,
+
+ /* R0/S0 on [0,2] */
+r00 = -6.250000000000000020842322918309200910191e-0002,
+r01 = 1.407056669551897148204830386691427791200e-0003,
+r02 = -1.599556310840356073980727783817809847071e-0005,
+r03 = 4.967279996095844750387702652791615403527e-0008,
+s01 = 1.915375995383634614394860200531091839635e-0002,
+s02 = 1.859467855886309024045655476348872850396e-0004,
+s03 = 1.177184640426236767593432585906758230822e-0006,
+s04 = 5.046362570762170559046714468225101016915e-0009,
+s05 = 1.235422744261379203512624973117299248281e-0011;
+
+#define two_129 6.80564733841876926e+038 /* 2^129 */
+#define two_m54 5.55111512312578270e-017 /* 2^-54 */
+double j1(x)
+ double x;
+{
+ double z, s,c,ss,cc,r,u,v,y;
+ y = fabs(x);
+ if (!finite(x)) /* Inf or NaN */
+ if (_IEEE && x != x)
+ return(x);
+ else
+ return (copysign(x, zero));
+ y = fabs(x);
+ if (y >= 2) /* |x| >= 2.0 */
+ {
+ s = sin(y);
+ c = cos(y);
+ ss = -s-c;
+ cc = s-c;
+ if (y < .5*DBL_MAX) { /* make sure y+y not overflow */
+ z = cos(y+y);
+ if ((s*c)<zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /*
+ * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
+ * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
+ */
+#if !defined(vax) && !defined(tahoe)
+ if (y > two_129) /* x > 2^129 */
+ z = (invsqrtpi*cc)/sqrt(y);
+ else
+#endif /* defined(vax) || defined(tahoe) */
+ {
+ u = pone(y); v = qone(y);
+ z = invsqrtpi*(u*cc-v*ss)/sqrt(y);
+ }
+ if (x < 0) return -z;
+ else return z;
+ }
+ if (y < 7.450580596923828125e-009) { /* |x|<2**-27 */
+ if(huge+x>one) return 0.5*x;/* inexact if x!=0 necessary */
+ }
+ z = x*x;
+ r = z*(r00+z*(r01+z*(r02+z*r03)));
+ s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
+ r *= x;
+ return (x*0.5+r/s);
+}
+
+static double u0[5] = {
+ -1.960570906462389484206891092512047539632e-0001,
+ 5.044387166398112572026169863174882070274e-0002,
+ -1.912568958757635383926261729464141209569e-0003,
+ 2.352526005616105109577368905595045204577e-0005,
+ -9.190991580398788465315411784276789663849e-0008,
+};
+static double v0[5] = {
+ 1.991673182366499064031901734535479833387e-0002,
+ 2.025525810251351806268483867032781294682e-0004,
+ 1.356088010975162198085369545564475416398e-0006,
+ 6.227414523646214811803898435084697863445e-0009,
+ 1.665592462079920695971450872592458916421e-0011,
+};
+
+double y1(x)
+ double x;
+{
+ double z, s, c, ss, cc, u, v;
+ /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
+ if (!finite(x))
+ if (!_IEEE) return (infnan(EDOM));
+ else if (x < 0)
+ return(zero/zero);
+ else if (x > 0)
+ return (0);
+ else
+ return(x);
+ if (x <= 0) {
+ if (_IEEE && x == 0) return -one/zero;
+ else if(x == 0) return(infnan(-ERANGE));
+ else if(_IEEE) return (zero/zero);
+ else return(infnan(EDOM));
+ }
+ if (x >= 2) /* |x| >= 2.0 */
+ {
+ s = sin(x);
+ c = cos(x);
+ ss = -s-c;
+ cc = s-c;
+ if (x < .5 * DBL_MAX) /* make sure x+x not overflow */
+ {
+ z = cos(x+x);
+ if ((s*c)>zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0))
+ * where x0 = x-3pi/4
+ * Better formula:
+ * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = -1/sqrt(2) * (cos(x) + sin(x))
+ * To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.
+ */
+ if (_IEEE && x>two_129)
+ z = (invsqrtpi*ss)/sqrt(x);
+ else {
+ u = pone(x); v = qone(x);
+ z = invsqrtpi*(u*ss+v*cc)/sqrt(x);
+ }
+ return z;
+ }
+ if (x <= two_m54) { /* x < 2**-54 */
+ return (-tpi/x);
+ }
+ z = x*x;
+ u = u0[0]+z*(u0[1]+z*(u0[2]+z*(u0[3]+z*u0[4])));
+ v = one+z*(v0[0]+z*(v0[1]+z*(v0[2]+z*(v0[3]+z*v0[4]))));
+ return (x*(u/v) + tpi*(j1(x)*log(x)-one/x));
+}
+
+/* For x >= 8, the asymptotic expansions of pone is
+ * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x.
+ * We approximate pone by
+ * pone(x) = 1 + (R/S)
+ * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10
+ * S = 1 + ps0*s^2 + ... + ps4*s^10
+ * and
+ * | pone(x)-1-R/S | <= 2 ** ( -60.06)
+ */
+
+static double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+ 0.0,
+ 1.171874999999886486643746274751925399540e-0001,
+ 1.323948065930735690925827997575471527252e+0001,
+ 4.120518543073785433325860184116512799375e+0002,
+ 3.874745389139605254931106878336700275601e+0003,
+ 7.914479540318917214253998253147871806507e+0003,
+};
+static double ps8[5] = {
+ 1.142073703756784104235066368252692471887e+0002,
+ 3.650930834208534511135396060708677099382e+0003,
+ 3.695620602690334708579444954937638371808e+0004,
+ 9.760279359349508334916300080109196824151e+0004,
+ 3.080427206278887984185421142572315054499e+0004,
+};
+
+static double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+ 1.319905195562435287967533851581013807103e-0011,
+ 1.171874931906140985709584817065144884218e-0001,
+ 6.802751278684328781830052995333841452280e+0000,
+ 1.083081829901891089952869437126160568246e+0002,
+ 5.176361395331997166796512844100442096318e+0002,
+ 5.287152013633375676874794230748055786553e+0002,
+};
+static double ps5[5] = {
+ 5.928059872211313557747989128353699746120e+0001,
+ 9.914014187336144114070148769222018425781e+0002,
+ 5.353266952914879348427003712029704477451e+0003,
+ 7.844690317495512717451367787640014588422e+0003,
+ 1.504046888103610723953792002716816255382e+0003,
+};
+
+static double pr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+ 3.025039161373736032825049903408701962756e-0009,
+ 1.171868655672535980750284752227495879921e-0001,
+ 3.932977500333156527232725812363183251138e+0000,
+ 3.511940355916369600741054592597098912682e+0001,
+ 9.105501107507812029367749771053045219094e+0001,
+ 4.855906851973649494139275085628195457113e+0001,
+};
+static double ps3[5] = {
+ 3.479130950012515114598605916318694946754e+0001,
+ 3.367624587478257581844639171605788622549e+0002,
+ 1.046871399757751279180649307467612538415e+0003,
+ 8.908113463982564638443204408234739237639e+0002,
+ 1.037879324396392739952487012284401031859e+0002,
+};
+
+static double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+ 1.077108301068737449490056513753865482831e-0007,
+ 1.171762194626833490512746348050035171545e-0001,
+ 2.368514966676087902251125130227221462134e+0000,
+ 1.224261091482612280835153832574115951447e+0001,
+ 1.769397112716877301904532320376586509782e+0001,
+ 5.073523125888185399030700509321145995160e+0000,
+};
+static double ps2[5] = {
+ 2.143648593638214170243114358933327983793e+0001,
+ 1.252902271684027493309211410842525120355e+0002,
+ 2.322764690571628159027850677565128301361e+0002,
+ 1.176793732871470939654351793502076106651e+0002,
+ 8.364638933716182492500902115164881195742e+0000,
+};
+
+static double pone(x)
+ double x;
+{
+ double *p,*q,z,r,s;
+ if (x >= 8.0) {p = pr8; q= ps8;}
+ else if (x >= 4.54545211791992188) {p = pr5; q= ps5;}
+ else if (x >= 2.85714149475097656) {p = pr3; q= ps3;}
+ else /* if (x >= 2.0) */ {p = pr2; q= ps2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+ return (one + r/s);
+}
+
+
+/* For x >= 8, the asymptotic expansions of qone is
+ * 3/8 s - 105/1024 s^3 - ..., where s = 1/x.
+ * We approximate pone by
+ * qone(x) = s*(0.375 + (R/S))
+ * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10
+ * S = 1 + qs1*s^2 + ... + qs6*s^12
+ * and
+ * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13)
+ */
+
+static double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+ 0.0,
+ -1.025390624999927207385863635575804210817e-0001,
+ -1.627175345445899724355852152103771510209e+0001,
+ -7.596017225139501519843072766973047217159e+0002,
+ -1.184980667024295901645301570813228628541e+0004,
+ -4.843851242857503225866761992518949647041e+0004,
+};
+static double qs8[6] = {
+ 1.613953697007229231029079421446916397904e+0002,
+ 7.825385999233484705298782500926834217525e+0003,
+ 1.338753362872495800748094112937868089032e+0005,
+ 7.196577236832409151461363171617204036929e+0005,
+ 6.666012326177764020898162762642290294625e+0005,
+ -2.944902643038346618211973470809456636830e+0005,
+};
+
+static double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+ -2.089799311417640889742251585097264715678e-0011,
+ -1.025390502413754195402736294609692303708e-0001,
+ -8.056448281239359746193011295417408828404e+0000,
+ -1.836696074748883785606784430098756513222e+0002,
+ -1.373193760655081612991329358017247355921e+0003,
+ -2.612444404532156676659706427295870995743e+0003,
+};
+static double qs5[6] = {
+ 8.127655013843357670881559763225310973118e+0001,
+ 1.991798734604859732508048816860471197220e+0003,
+ 1.746848519249089131627491835267411777366e+0004,
+ 4.985142709103522808438758919150738000353e+0004,
+ 2.794807516389181249227113445299675335543e+0004,
+ -4.719183547951285076111596613593553911065e+0003,
+};
+
+static double qr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+ -5.078312264617665927595954813341838734288e-0009,
+ -1.025378298208370901410560259001035577681e-0001,
+ -4.610115811394734131557983832055607679242e+0000,
+ -5.784722165627836421815348508816936196402e+0001,
+ -2.282445407376317023842545937526967035712e+0002,
+ -2.192101284789093123936441805496580237676e+0002,
+};
+static double qs3[6] = {
+ 4.766515503237295155392317984171640809318e+0001,
+ 6.738651126766996691330687210949984203167e+0002,
+ 3.380152866795263466426219644231687474174e+0003,
+ 5.547729097207227642358288160210745890345e+0003,
+ 1.903119193388108072238947732674639066045e+0003,
+ -1.352011914443073322978097159157678748982e+0002,
+};
+
+static double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+ -1.783817275109588656126772316921194887979e-0007,
+ -1.025170426079855506812435356168903694433e-0001,
+ -2.752205682781874520495702498875020485552e+0000,
+ -1.966361626437037351076756351268110418862e+0001,
+ -4.232531333728305108194363846333841480336e+0001,
+ -2.137192117037040574661406572497288723430e+0001,
+};
+static double qs2[6] = {
+ 2.953336290605238495019307530224241335502e+0001,
+ 2.529815499821905343698811319455305266409e+0002,
+ 7.575028348686454070022561120722815892346e+0002,
+ 7.393932053204672479746835719678434981599e+0002,
+ 1.559490033366661142496448853793707126179e+0002,
+ -4.959498988226281813825263003231704397158e+0000,
+};
+
+static double qone(x)
+ double x;
+{
+ double *p,*q, s,r,z;
+ if (x >= 8.0) {p = qr8; q= qs8;}
+ else if (x >= 4.54545211791992188) {p = qr5; q= qs5;}
+ else if (x >= 2.85714149475097656) {p = qr3; q= qs3;}
+ else /* if (x >= 2.0) */ {p = qr2; q= qs2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+ return (.375 + r/s)/x;
+}
diff --git a/lib/libm/common_source/jn.c b/lib/libm/common_source/jn.c
new file mode 100644
index 0000000..28d9687
--- /dev/null
+++ b/lib/libm/common_source/jn.c
@@ -0,0 +1,311 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)jn.c 8.2 (Berkeley) 11/30/93";
+#endif /* not lint */
+
+/*
+ * 16 December 1992
+ * Minor modifications by Peter McIlroy to adapt non-IEEE architecture.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1992 by Sun Microsystems, Inc.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ * ******************* WARNING ********************
+ * This is an alpha version of SunPro's FDLIBM (Freely
+ * Distributable Math Library) for IEEE double precision
+ * arithmetic. FDLIBM is a basic math library written
+ * in C that runs on machines that conform to IEEE
+ * Standard 754/854. This alpha version is distributed
+ * for testing purpose. Those who use this software
+ * should report any bugs to
+ *
+ * fdlibm-comments@sunpro.eng.sun.com
+ *
+ * -- K.C. Ng, Oct 12, 1992
+ * ************************************************
+ */
+
+/*
+ * jn(int n, double x), yn(int n, double x)
+ * floating point Bessel's function of the 1st and 2nd kind
+ * of order n
+ *
+ * Special cases:
+ * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
+ * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
+ * Note 2. About jn(n,x), yn(n,x)
+ * For n=0, j0(x) is called,
+ * for n=1, j1(x) is called,
+ * for n<x, forward recursion us used starting
+ * from values of j0(x) and j1(x).
+ * for n>x, a continued fraction approximation to
+ * j(n,x)/j(n-1,x) is evaluated and then backward
+ * recursion is used starting from a supposed value
+ * for j(n,x). The resulting value of j(0,x) is
+ * compared with the actual value to correct the
+ * supposed value of j(n,x).
+ *
+ * yn(n,x) is similar in all respects, except
+ * that forward recursion is used for all
+ * values of n>1.
+ *
+ */
+
+#include <math.h>
+#include <float.h>
+#include <errno.h>
+
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+#else
+#define _IEEE 1
+#define infnan(x) (0.0)
+#endif
+
+static double
+invsqrtpi= 5.641895835477562869480794515607725858441e-0001,
+two = 2.0,
+zero = 0.0,
+one = 1.0;
+
+double jn(n,x)
+ int n; double x;
+{
+ int i, sgn;
+ double a, b, temp;
+ double z, w;
+
+ /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
+ * Thus, J(-n,x) = J(n,-x)
+ */
+ /* if J(n,NaN) is NaN */
+ if (_IEEE && isnan(x)) return x+x;
+ if (n<0){
+ n = -n;
+ x = -x;
+ }
+ if (n==0) return(j0(x));
+ if (n==1) return(j1(x));
+ sgn = (n&1)&(x < zero); /* even n -- 0, odd n -- sign(x) */
+ x = fabs(x);
+ if (x == 0 || !finite (x)) /* if x is 0 or inf */
+ b = zero;
+ else if ((double) n <= x) {
+ /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
+ if (_IEEE && x >= 8.148143905337944345e+090) {
+ /* x >= 2**302 */
+ /* (x >> n**2)
+ * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Let s=sin(x), c=cos(x),
+ * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+ *
+ * n sin(xn)*sqt2 cos(xn)*sqt2
+ * ----------------------------------
+ * 0 s-c c+s
+ * 1 -s-c -c+s
+ * 2 -s+c -c-s
+ * 3 s+c c-s
+ */
+ switch(n&3) {
+ case 0: temp = cos(x)+sin(x); break;
+ case 1: temp = -cos(x)+sin(x); break;
+ case 2: temp = -cos(x)-sin(x); break;
+ case 3: temp = cos(x)-sin(x); break;
+ }
+ b = invsqrtpi*temp/sqrt(x);
+ } else {
+ a = j0(x);
+ b = j1(x);
+ for(i=1;i<n;i++){
+ temp = b;
+ b = b*((double)(i+i)/x) - a; /* avoid underflow */
+ a = temp;
+ }
+ }
+ } else {
+ if (x < 1.86264514923095703125e-009) { /* x < 2**-29 */
+ /* x is tiny, return the first Taylor expansion of J(n,x)
+ * J(n,x) = 1/n!*(x/2)^n - ...
+ */
+ if (n > 33) /* underflow */
+ b = zero;
+ else {
+ temp = x*0.5; b = temp;
+ for (a=one,i=2;i<=n;i++) {
+ a *= (double)i; /* a = n! */
+ b *= temp; /* b = (x/2)^n */
+ }
+ b = b/a;
+ }
+ } else {
+ /* use backward recurrence */
+ /* x x^2 x^2
+ * J(n,x)/J(n-1,x) = ---- ------ ------ .....
+ * 2n - 2(n+1) - 2(n+2)
+ *
+ * 1 1 1
+ * (for large x) = ---- ------ ------ .....
+ * 2n 2(n+1) 2(n+2)
+ * -- - ------ - ------ -
+ * x x x
+ *
+ * Let w = 2n/x and h=2/x, then the above quotient
+ * is equal to the continued fraction:
+ * 1
+ * = -----------------------
+ * 1
+ * w - -----------------
+ * 1
+ * w+h - ---------
+ * w+2h - ...
+ *
+ * To determine how many terms needed, let
+ * Q(0) = w, Q(1) = w(w+h) - 1,
+ * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
+ * When Q(k) > 1e4 good for single
+ * When Q(k) > 1e9 good for double
+ * When Q(k) > 1e17 good for quadruple
+ */
+ /* determine k */
+ double t,v;
+ double q0,q1,h,tmp; int k,m;
+ w = (n+n)/(double)x; h = 2.0/(double)x;
+ q0 = w; z = w+h; q1 = w*z - 1.0; k=1;
+ while (q1<1.0e9) {
+ k += 1; z += h;
+ tmp = z*q1 - q0;
+ q0 = q1;
+ q1 = tmp;
+ }
+ m = n+n;
+ for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t);
+ a = t;
+ b = one;
+ /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
+ * Hence, if n*(log(2n/x)) > ...
+ * single 8.8722839355e+01
+ * double 7.09782712893383973096e+02
+ * long double 1.1356523406294143949491931077970765006170e+04
+ * then recurrent value may overflow and the result will
+ * likely underflow to zero
+ */
+ tmp = n;
+ v = two/x;
+ tmp = tmp*log(fabs(v*tmp));
+ for (i=n-1;i>0;i--){
+ temp = b;
+ b = ((i+i)/x)*b - a;
+ a = temp;
+ /* scale b to avoid spurious overflow */
+# if defined(vax) || defined(tahoe)
+# define BMAX 1e13
+# else
+# define BMAX 1e100
+# endif /* defined(vax) || defined(tahoe) */
+ if (b > BMAX) {
+ a /= b;
+ t /= b;
+ b = one;
+ }
+ }
+ b = (t*j0(x)/b);
+ }
+ }
+ return ((sgn == 1) ? -b : b);
+}
+double yn(n,x)
+ int n; double x;
+{
+ int i, sign;
+ double a, b, temp;
+
+ /* Y(n,NaN), Y(n, x < 0) is NaN */
+ if (x <= 0 || (_IEEE && x != x))
+ if (_IEEE && x < 0) return zero/zero;
+ else if (x < 0) return (infnan(EDOM));
+ else if (_IEEE) return -one/zero;
+ else return(infnan(-ERANGE));
+ else if (!finite(x)) return(0);
+ sign = 1;
+ if (n<0){
+ n = -n;
+ sign = 1 - ((n&1)<<2);
+ }
+ if (n == 0) return(y0(x));
+ if (n == 1) return(sign*y1(x));
+ if(_IEEE && x >= 8.148143905337944345e+090) { /* x > 2**302 */
+ /* (x >> n**2)
+ * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Let s=sin(x), c=cos(x),
+ * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+ *
+ * n sin(xn)*sqt2 cos(xn)*sqt2
+ * ----------------------------------
+ * 0 s-c c+s
+ * 1 -s-c -c+s
+ * 2 -s+c -c-s
+ * 3 s+c c-s
+ */
+ switch (n&3) {
+ case 0: temp = sin(x)-cos(x); break;
+ case 1: temp = -sin(x)-cos(x); break;
+ case 2: temp = -sin(x)+cos(x); break;
+ case 3: temp = sin(x)+cos(x); break;
+ }
+ b = invsqrtpi*temp/sqrt(x);
+ } else {
+ a = y0(x);
+ b = y1(x);
+ /* quit if b is -inf */
+ for (i = 1; i < n && !finite(b); i++){
+ temp = b;
+ b = ((double)(i+i)/x)*b - a;
+ a = temp;
+ }
+ }
+ if (!_IEEE && !finite(b))
+ return (infnan(-sign * ERANGE));
+ return ((sign > 0) ? b : -b);
+}
diff --git a/lib/libm/common_source/lgamma.3 b/lib/libm/common_source/lgamma.3
new file mode 100644
index 0000000..d15c7a4
--- /dev/null
+++ b/lib/libm/common_source/lgamma.3
@@ -0,0 +1,124 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)lgamma.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt LGAMMA 3
+.Os BSD 4.3
+.Sh NAME
+.Nm lgamma
+.Nm gamma
+.Nd log gamma function, gamma function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft extern int
+.Fa signgam ;
+.sp
+.Ft double
+.Fn lgamma "double x"
+.Ft double
+.Fn gamma "double x"
+.Sh DESCRIPTION
+.Fn Lgamma x
+.if t \{\
+returns ln\||\(*G(x)| where
+.Bd -unfilled -offset indent
+\(*G(x) = \(is\d\s8\z0\s10\u\u\s8\(if\s10\d t\u\s8x\-1\s10\d e\u\s8\-t\s10\d dt for x > 0 and
+.br
+\(*G(x) = \(*p/(\(*G(1\-x)\|sin(\(*px)) for x < 1.
+.Ed
+.\}
+.if n \
+returns ln\||\(*G(x)|.
+.Pp
+The external integer
+.Fa signgam
+returns the sign of \(*G(x).
+.Pp
+.Fn Gamma x
+returns \(*G(x), with no effect on
+.Fa signgam .
+.Sh IDIOSYNCRASIES
+Do not use the expression
+.Dq Li signgam\(**exp(lgamma(x))
+to compute g := \(*G(x).
+Instead use a program like this (in C):
+.Bd -literal -offset indent
+lg = lgamma(x); g = signgam\(**exp(lg);
+.Ed
+.Pp
+Only after
+.Fn lgamma
+has returned can signgam be correct.
+.Pp
+For arguments in its range,
+.Fn gamma
+is preferred, as for positive arguments
+it is accurate to within one unit in the last place.
+Exponentiation of
+.Fn lgamma
+will lose up to 10 significant bits.
+.Sh RETURN VALUES
+.Fn Gamma
+and
+.Fn lgamma
+return appropriate values unless an argument is out of range.
+Overflow will occur for sufficiently large positive values, and
+non-positive integers.
+On the
+.Tn VAX,
+the reserved operator is returned,
+and
+.Va errno
+is set to
+.Er ERANGE
+For large non-integer negative values,
+.Fn gamma
+will underflow.
+.Sh SEE ALSO
+.Xr infnan 3 ,
+.Xr math 3
+.Sh HISTORY
+The
+.Nm lgamma
+function appeared in
+.Bx 4.3 .
+The
+.Nm gamma
+function appeared in
+.Bx 4.4 .
+The name
+.Fn gamma
+was originally dedicated to the
+.Fn lgamma
+function, so some old code may no longer be compatible.
diff --git a/lib/libm/common_source/lgamma.c b/lib/libm/common_source/lgamma.c
new file mode 100644
index 0000000..5347c93
--- /dev/null
+++ b/lib/libm/common_source/lgamma.c
@@ -0,0 +1,307 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)lgamma.c 8.2 (Berkeley) 11/30/93";
+#endif /* not lint */
+
+/*
+ * Coded by Peter McIlroy, Nov 1992;
+ *
+ * The financial support of UUNET Communications Services is greatfully
+ * acknowledged.
+ */
+
+#include <math.h>
+#include <errno.h>
+
+#include "mathimpl.h"
+
+/* Log gamma function.
+ * Error: x > 0 error < 1.3ulp.
+ * x > 4, error < 1ulp.
+ * x > 9, error < .6ulp.
+ * x < 0, all bets are off. (When G(x) ~ 1, log(G(x)) ~ 0)
+ * Method:
+ * x > 6:
+ * Use the asymptotic expansion (Stirling's Formula)
+ * 0 < x < 6:
+ * Use gamma(x+1) = x*gamma(x) for argument reduction.
+ * Use rational approximation in
+ * the range 1.2, 2.5
+ * Two approximations are used, one centered at the
+ * minimum to ensure monotonicity; one centered at 2
+ * to maintain small relative error.
+ * x < 0:
+ * Use the reflection formula,
+ * G(1-x)G(x) = PI/sin(PI*x)
+ * Special values:
+ * non-positive integer returns +Inf.
+ * NaN returns NaN
+*/
+static int endian;
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+/* double and float have same size exponent field */
+#define TRUNC(x) x = (double) (float) (x)
+#else
+#define _IEEE 1
+#define TRUNC(x) *(((int *) &x) + endian) &= 0xf8000000
+#define infnan(x) 0.0
+#endif
+
+static double small_lgam(double);
+static double large_lgam(double);
+static double neg_lgam(double);
+static double zero = 0.0, one = 1.0;
+int signgam;
+
+#define UNDERFL (1e-1020 * 1e-1020)
+
+#define LEFT (1.0 - (x0 + .25))
+#define RIGHT (x0 - .218)
+/*
+ * Constants for approximation in [1.244,1.712]
+*/
+#define x0 0.461632144968362356785
+#define x0_lo -.000000000000000015522348162858676890521
+#define a0_hi -0.12148629128932952880859
+#define a0_lo .0000000007534799204229502
+#define r0 -2.771227512955130520e-002
+#define r1 -2.980729795228150847e-001
+#define r2 -3.257411333183093394e-001
+#define r3 -1.126814387531706041e-001
+#define r4 -1.129130057170225562e-002
+#define r5 -2.259650588213369095e-005
+#define s0 1.714457160001714442e+000
+#define s1 2.786469504618194648e+000
+#define s2 1.564546365519179805e+000
+#define s3 3.485846389981109850e-001
+#define s4 2.467759345363656348e-002
+/*
+ * Constants for approximation in [1.71, 2.5]
+*/
+#define a1_hi 4.227843350984671344505727574870e-01
+#define a1_lo 4.670126436531227189e-18
+#define p0 3.224670334241133695662995251041e-01
+#define p1 3.569659696950364669021382724168e-01
+#define p2 1.342918716072560025853732668111e-01
+#define p3 1.950702176409779831089963408886e-02
+#define p4 8.546740251667538090796227834289e-04
+#define q0 1.000000000000000444089209850062e+00
+#define q1 1.315850076960161985084596381057e+00
+#define q2 6.274644311862156431658377186977e-01
+#define q3 1.304706631926259297049597307705e-01
+#define q4 1.102815279606722369265536798366e-02
+#define q5 2.512690594856678929537585620579e-04
+#define q6 -1.003597548112371003358107325598e-06
+/*
+ * Stirling's Formula, adjusted for equal-ripple. x in [6,Inf].
+*/
+#define lns2pi .418938533204672741780329736405
+#define pb0 8.33333333333333148296162562474e-02
+#define pb1 -2.77777777774548123579378966497e-03
+#define pb2 7.93650778754435631476282786423e-04
+#define pb3 -5.95235082566672847950717262222e-04
+#define pb4 8.41428560346653702135821806252e-04
+#define pb5 -1.89773526463879200348872089421e-03
+#define pb6 5.69394463439411649408050664078e-03
+#define pb7 -1.44705562421428915453880392761e-02
+
+__pure double
+lgamma(double x)
+{
+ double r;
+
+ signgam = 1;
+ endian = ((*(int *) &one)) ? 1 : 0;
+
+ if (!finite(x))
+ if (_IEEE)
+ return (x+x);
+ else return (infnan(EDOM));
+
+ if (x > 6 + RIGHT) {
+ r = large_lgam(x);
+ return (r);
+ } else if (x > 1e-16)
+ return (small_lgam(x));
+ else if (x > -1e-16) {
+ if (x < 0)
+ signgam = -1, x = -x;
+ return (-log(x));
+ } else
+ return (neg_lgam(x));
+}
+
+static double
+large_lgam(double x)
+{
+ double z, p, x1;
+ int i;
+ struct Double t, u, v;
+ u = __log__D(x);
+ u.a -= 1.0;
+ if (x > 1e15) {
+ v.a = x - 0.5;
+ TRUNC(v.a);
+ v.b = (x - v.a) - 0.5;
+ t.a = u.a*v.a;
+ t.b = x*u.b + v.b*u.a;
+ if (_IEEE == 0 && !finite(t.a))
+ return(infnan(ERANGE));
+ return(t.a + t.b);
+ }
+ x1 = 1./x;
+ z = x1*x1;
+ p = pb0+z*(pb1+z*(pb2+z*(pb3+z*(pb4+z*(pb5+z*(pb6+z*pb7))))));
+ /* error in approximation = 2.8e-19 */
+
+ p = p*x1; /* error < 2.3e-18 absolute */
+ /* 0 < p < 1/64 (at x = 5.5) */
+ v.a = x = x - 0.5;
+ TRUNC(v.a); /* truncate v.a to 26 bits. */
+ v.b = x - v.a;
+ t.a = v.a*u.a; /* t = (x-.5)*(log(x)-1) */
+ t.b = v.b*u.a + x*u.b;
+ t.b += p; t.b += lns2pi; /* return t + lns2pi + p */
+ return (t.a + t.b);
+}
+
+static double
+small_lgam(double x)
+{
+ int x_int;
+ double y, z, t, r = 0, p, q, hi, lo;
+ struct Double rr;
+ x_int = (x + .5);
+ y = x - x_int;
+ if (x_int <= 2 && y > RIGHT) {
+ t = y - x0;
+ y--; x_int++;
+ goto CONTINUE;
+ } else if (y < -LEFT) {
+ t = y +(1.0-x0);
+CONTINUE:
+ z = t - x0_lo;
+ p = r0+z*(r1+z*(r2+z*(r3+z*(r4+z*r5))));
+ q = s0+z*(s1+z*(s2+z*(s3+z*s4)));
+ r = t*(z*(p/q) - x0_lo);
+ t = .5*t*t;
+ z = 1.0;
+ switch (x_int) {
+ case 6: z = (y + 5);
+ case 5: z *= (y + 4);
+ case 4: z *= (y + 3);
+ case 3: z *= (y + 2);
+ rr = __log__D(z);
+ rr.b += a0_lo; rr.a += a0_hi;
+ return(((r+rr.b)+t+rr.a));
+ case 2: return(((r+a0_lo)+t)+a0_hi);
+ case 0: r -= log1p(x);
+ default: rr = __log__D(x);
+ rr.a -= a0_hi; rr.b -= a0_lo;
+ return(((r - rr.b) + t) - rr.a);
+ }
+ } else {
+ p = p0+y*(p1+y*(p2+y*(p3+y*p4)));
+ q = q0+y*(q1+y*(q2+y*(q3+y*(q4+y*(q5+y*q6)))));
+ p = p*(y/q);
+ t = (double)(float) y;
+ z = y-t;
+ hi = (double)(float) (p+a1_hi);
+ lo = a1_hi - hi; lo += p; lo += a1_lo;
+ r = lo*y + z*hi; /* q + r = y*(a0+p/q) */
+ q = hi*t;
+ z = 1.0;
+ switch (x_int) {
+ case 6: z = (y + 5);
+ case 5: z *= (y + 4);
+ case 4: z *= (y + 3);
+ case 3: z *= (y + 2);
+ rr = __log__D(z);
+ r += rr.b; r += q;
+ return(rr.a + r);
+ case 2: return (q+ r);
+ case 0: rr = __log__D(x);
+ r -= rr.b; r -= log1p(x);
+ r += q; r-= rr.a;
+ return(r);
+ default: rr = __log__D(x);
+ r -= rr.b;
+ q -= rr.a;
+ return (r+q);
+ }
+ }
+}
+
+static double
+neg_lgam(double x)
+{
+ int xi;
+ double y, z, one = 1.0, zero = 0.0;
+ extern double gamma();
+
+ /* avoid destructive cancellation as much as possible */
+ if (x > -170) {
+ xi = x;
+ if (xi == x)
+ if (_IEEE)
+ return(one/zero);
+ else
+ return(infnan(ERANGE));
+ y = gamma(x);
+ if (y < 0)
+ y = -y, signgam = -1;
+ return (log(y));
+ }
+ z = floor(x + .5);
+ if (z == x) { /* convention: G(-(integer)) -> +Inf */
+ if (_IEEE)
+ return (one/zero);
+ else
+ return (infnan(ERANGE));
+ }
+ y = .5*ceil(x);
+ if (y == ceil(y))
+ signgam = -1;
+ x = -x;
+ z = fabs(x + z); /* 0 < z <= .5 */
+ if (z < .25)
+ z = sin(M_PI*z);
+ else
+ z = cos(M_PI*(0.5-z));
+ z = log(M_PI/(z*x));
+ y = large_lgam(x);
+ return (z - y);
+}
diff --git a/lib/libm/common_source/log.c b/lib/libm/common_source/log.c
new file mode 100644
index 0000000..908b8544
--- /dev/null
+++ b/lib/libm/common_source/log.c
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log.c 8.2 (Berkeley) 11/30/93";
+#endif /* not lint */
+
+#include <math.h>
+#include <errno.h>
+
+#include "mathimpl.h"
+
+/* Table-driven natural logarithm.
+ *
+ * This code was derived, with minor modifications, from:
+ * Peter Tang, "Table-Driven Implementation of the
+ * Logarithm in IEEE Floating-Point arithmetic." ACM Trans.
+ * Math Software, vol 16. no 4, pp 378-400, Dec 1990).
+ *
+ * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256,
+ * where F = j/128 for j an integer in [0, 128].
+ *
+ * log(2^m) = log2_hi*m + log2_tail*m
+ * since m is an integer, the dominant term is exact.
+ * m has at most 10 digits (for subnormal numbers),
+ * and log2_hi has 11 trailing zero bits.
+ *
+ * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h
+ * logF_hi[] + 512 is exact.
+ *
+ * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ...
+ * the leading term is calculated to extra precision in two
+ * parts, the larger of which adds exactly to the dominant
+ * m and F terms.
+ * There are two cases:
+ * 1. when m, j are non-zero (m | j), use absolute
+ * precision for the leading term.
+ * 2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1).
+ * In this case, use a relative precision of 24 bits.
+ * (This is done differently in the original paper)
+ *
+ * Special cases:
+ * 0 return signalling -Inf
+ * neg return signalling NaN
+ * +Inf return +Inf
+*/
+
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+#define TRUNC(x) x = (double) (float) (x)
+#else
+#define _IEEE 1
+#define endian (((*(int *) &one)) ? 1 : 0)
+#define TRUNC(x) *(((int *) &x) + endian) &= 0xf8000000
+#define infnan(x) 0.0
+#endif
+
+#define N 128
+
+/* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128.
+ * Used for generation of extend precision logarithms.
+ * The constant 35184372088832 is 2^45, so the divide is exact.
+ * It ensures correct reading of logF_head, even for inaccurate
+ * decimal-to-binary conversion routines. (Everybody gets the
+ * right answer for integers less than 2^53.)
+ * Values for log(F) were generated using error < 10^-57 absolute
+ * with the bc -l package.
+*/
+static double A1 = .08333333333333178827;
+static double A2 = .01250000000377174923;
+static double A3 = .002232139987919447809;
+static double A4 = .0004348877777076145742;
+
+static double logF_head[N+1] = {
+ 0.,
+ .007782140442060381246,
+ .015504186535963526694,
+ .023167059281547608406,
+ .030771658666765233647,
+ .038318864302141264488,
+ .045809536031242714670,
+ .053244514518837604555,
+ .060624621816486978786,
+ .067950661908525944454,
+ .075223421237524235039,
+ .082443669210988446138,
+ .089612158689760690322,
+ .096729626458454731618,
+ .103796793681567578460,
+ .110814366340264314203,
+ .117783035656430001836,
+ .124703478501032805070,
+ .131576357788617315236,
+ .138402322859292326029,
+ .145182009844575077295,
+ .151916042025732167530,
+ .158605030176659056451,
+ .165249572895390883786,
+ .171850256926518341060,
+ .178407657472689606947,
+ .184922338493834104156,
+ .191394852999565046047,
+ .197825743329758552135,
+ .204215541428766300668,
+ .210564769107350002741,
+ .216873938300523150246,
+ .223143551314024080056,
+ .229374101064877322642,
+ .235566071312860003672,
+ .241719936886966024758,
+ .247836163904594286577,
+ .253915209980732470285,
+ .259957524436686071567,
+ .265963548496984003577,
+ .271933715484010463114,
+ .277868451003087102435,
+ .283768173130738432519,
+ .289633292582948342896,
+ .295464212893421063199,
+ .301261330578199704177,
+ .307025035294827830512,
+ .312755710004239517729,
+ .318453731118097493890,
+ .324119468654316733591,
+ .329753286372579168528,
+ .335355541920762334484,
+ .340926586970454081892,
+ .346466767346100823488,
+ .351976423156884266063,
+ .357455888922231679316,
+ .362905493689140712376,
+ .368325561158599157352,
+ .373716409793814818840,
+ .379078352934811846353,
+ .384411698910298582632,
+ .389716751140440464951,
+ .394993808240542421117,
+ .400243164127459749579,
+ .405465108107819105498,
+ .410659924985338875558,
+ .415827895143593195825,
+ .420969294644237379543,
+ .426084395310681429691,
+ .431173464818130014464,
+ .436236766774527495726,
+ .441274560805140936281,
+ .446287102628048160113,
+ .451274644139630254358,
+ .456237433481874177232,
+ .461175715122408291790,
+ .466089729924533457960,
+ .470979715219073113985,
+ .475845904869856894947,
+ .480688529345570714212,
+ .485507815781602403149,
+ .490303988045525329653,
+ .495077266798034543171,
+ .499827869556611403822,
+ .504556010751912253908,
+ .509261901790523552335,
+ .513945751101346104405,
+ .518607764208354637958,
+ .523248143765158602036,
+ .527867089620485785417,
+ .532464798869114019908,
+ .537041465897345915436,
+ .541597282432121573947,
+ .546132437597407260909,
+ .550647117952394182793,
+ .555141507540611200965,
+ .559615787935399566777,
+ .564070138285387656651,
+ .568504735352689749561,
+ .572919753562018740922,
+ .577315365035246941260,
+ .581691739635061821900,
+ .586049045003164792433,
+ .590387446602107957005,
+ .594707107746216934174,
+ .599008189645246602594,
+ .603290851438941899687,
+ .607555250224322662688,
+ .611801541106615331955,
+ .616029877215623855590,
+ .620240409751204424537,
+ .624433288012369303032,
+ .628608659422752680256,
+ .632766669570628437213,
+ .636907462236194987781,
+ .641031179420679109171,
+ .645137961373620782978,
+ .649227946625615004450,
+ .653301272011958644725,
+ .657358072709030238911,
+ .661398482245203922502,
+ .665422632544505177065,
+ .669430653942981734871,
+ .673422675212350441142,
+ .677398823590920073911,
+ .681359224807238206267,
+ .685304003098281100392,
+ .689233281238557538017,
+ .693147180560117703862
+};
+
+static double logF_tail[N+1] = {
+ 0.,
+ -.00000000000000543229938420049,
+ .00000000000000172745674997061,
+ -.00000000000001323017818229233,
+ -.00000000000001154527628289872,
+ -.00000000000000466529469958300,
+ .00000000000005148849572685810,
+ -.00000000000002532168943117445,
+ -.00000000000005213620639136504,
+ -.00000000000001819506003016881,
+ .00000000000006329065958724544,
+ .00000000000008614512936087814,
+ -.00000000000007355770219435028,
+ .00000000000009638067658552277,
+ .00000000000007598636597194141,
+ .00000000000002579999128306990,
+ -.00000000000004654729747598444,
+ -.00000000000007556920687451336,
+ .00000000000010195735223708472,
+ -.00000000000017319034406422306,
+ -.00000000000007718001336828098,
+ .00000000000010980754099855238,
+ -.00000000000002047235780046195,
+ -.00000000000008372091099235912,
+ .00000000000014088127937111135,
+ .00000000000012869017157588257,
+ .00000000000017788850778198106,
+ .00000000000006440856150696891,
+ .00000000000016132822667240822,
+ -.00000000000007540916511956188,
+ -.00000000000000036507188831790,
+ .00000000000009120937249914984,
+ .00000000000018567570959796010,
+ -.00000000000003149265065191483,
+ -.00000000000009309459495196889,
+ .00000000000017914338601329117,
+ -.00000000000001302979717330866,
+ .00000000000023097385217586939,
+ .00000000000023999540484211737,
+ .00000000000015393776174455408,
+ -.00000000000036870428315837678,
+ .00000000000036920375082080089,
+ -.00000000000009383417223663699,
+ .00000000000009433398189512690,
+ .00000000000041481318704258568,
+ -.00000000000003792316480209314,
+ .00000000000008403156304792424,
+ -.00000000000034262934348285429,
+ .00000000000043712191957429145,
+ -.00000000000010475750058776541,
+ -.00000000000011118671389559323,
+ .00000000000037549577257259853,
+ .00000000000013912841212197565,
+ .00000000000010775743037572640,
+ .00000000000029391859187648000,
+ -.00000000000042790509060060774,
+ .00000000000022774076114039555,
+ .00000000000010849569622967912,
+ -.00000000000023073801945705758,
+ .00000000000015761203773969435,
+ .00000000000003345710269544082,
+ -.00000000000041525158063436123,
+ .00000000000032655698896907146,
+ -.00000000000044704265010452446,
+ .00000000000034527647952039772,
+ -.00000000000007048962392109746,
+ .00000000000011776978751369214,
+ -.00000000000010774341461609578,
+ .00000000000021863343293215910,
+ .00000000000024132639491333131,
+ .00000000000039057462209830700,
+ -.00000000000026570679203560751,
+ .00000000000037135141919592021,
+ -.00000000000017166921336082431,
+ -.00000000000028658285157914353,
+ -.00000000000023812542263446809,
+ .00000000000006576659768580062,
+ -.00000000000028210143846181267,
+ .00000000000010701931762114254,
+ .00000000000018119346366441110,
+ .00000000000009840465278232627,
+ -.00000000000033149150282752542,
+ -.00000000000018302857356041668,
+ -.00000000000016207400156744949,
+ .00000000000048303314949553201,
+ -.00000000000071560553172382115,
+ .00000000000088821239518571855,
+ -.00000000000030900580513238244,
+ -.00000000000061076551972851496,
+ .00000000000035659969663347830,
+ .00000000000035782396591276383,
+ -.00000000000046226087001544578,
+ .00000000000062279762917225156,
+ .00000000000072838947272065741,
+ .00000000000026809646615211673,
+ -.00000000000010960825046059278,
+ .00000000000002311949383800537,
+ -.00000000000058469058005299247,
+ -.00000000000002103748251144494,
+ -.00000000000023323182945587408,
+ -.00000000000042333694288141916,
+ -.00000000000043933937969737844,
+ .00000000000041341647073835565,
+ .00000000000006841763641591466,
+ .00000000000047585534004430641,
+ .00000000000083679678674757695,
+ -.00000000000085763734646658640,
+ .00000000000021913281229340092,
+ -.00000000000062242842536431148,
+ -.00000000000010983594325438430,
+ .00000000000065310431377633651,
+ -.00000000000047580199021710769,
+ -.00000000000037854251265457040,
+ .00000000000040939233218678664,
+ .00000000000087424383914858291,
+ .00000000000025218188456842882,
+ -.00000000000003608131360422557,
+ -.00000000000050518555924280902,
+ .00000000000078699403323355317,
+ -.00000000000067020876961949060,
+ .00000000000016108575753932458,
+ .00000000000058527188436251509,
+ -.00000000000035246757297904791,
+ -.00000000000018372084495629058,
+ .00000000000088606689813494916,
+ .00000000000066486268071468700,
+ .00000000000063831615170646519,
+ .00000000000025144230728376072,
+ -.00000000000017239444525614834
+};
+
+double
+#ifdef _ANSI_SOURCE
+log(double x)
+#else
+log(x) double x;
+#endif
+{
+ int m, j;
+ double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0;
+ volatile double u1;
+
+ /* Catch special cases */
+ if (x <= 0)
+ if (_IEEE && x == zero) /* log(0) = -Inf */
+ return (-one/zero);
+ else if (_IEEE) /* log(neg) = NaN */
+ return (zero/zero);
+ else if (x == zero) /* NOT REACHED IF _IEEE */
+ return (infnan(-ERANGE));
+ else
+ return (infnan(EDOM));
+ else if (!finite(x))
+ if (_IEEE) /* x = NaN, Inf */
+ return (x+x);
+ else
+ return (infnan(ERANGE));
+
+ /* Argument reduction: 1 <= g < 2; x/2^m = g; */
+ /* y = F*(1 + f/F) for |f| <= 2^-8 */
+
+ m = logb(x);
+ g = ldexp(x, -m);
+ if (_IEEE && m == -1022) {
+ j = logb(g), m += j;
+ g = ldexp(g, -j);
+ }
+ j = N*(g-1) + .5;
+ F = (1.0/N) * j + 1; /* F*128 is an integer in [128, 512] */
+ f = g - F;
+
+ /* Approximate expansion for log(1+f/F) ~= u + q */
+ g = 1/(2*F+f);
+ u = 2*f*g;
+ v = u*u;
+ q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
+
+ /* case 1: u1 = u rounded to 2^-43 absolute. Since u < 2^-8,
+ * u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits.
+ * It also adds exactly to |m*log2_hi + log_F_head[j] | < 750
+ */
+ if (m | j)
+ u1 = u + 513, u1 -= 513;
+
+ /* case 2: |1-x| < 1/256. The m- and j- dependent terms are zero;
+ * u1 = u to 24 bits.
+ */
+ else
+ u1 = u, TRUNC(u1);
+ u2 = (2.0*(f - F*u1) - u1*f) * g;
+ /* u1 + u2 = 2f/(2F+f) to extra precision. */
+
+ /* log(x) = log(2^m*F*(1+f/F)) = */
+ /* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q); */
+ /* (exact) + (tiny) */
+
+ u1 += m*logF_head[N] + logF_head[j]; /* exact */
+ u2 = (u2 + logF_tail[j]) + q; /* tiny */
+ u2 += logF_tail[N]*m;
+ return (u1 + u2);
+}
+
+/*
+ * Extra precision variant, returning struct {double a, b;};
+ * log(x) = a+b to 63 bits, with a is rounded to 26 bits.
+ */
+struct Double
+#ifdef _ANSI_SOURCE
+__log__D(double x)
+#else
+__log__D(x) double x;
+#endif
+{
+ int m, j;
+ double F, f, g, q, u, v, u2, one = 1.0;
+ volatile double u1;
+ struct Double r;
+
+ /* Argument reduction: 1 <= g < 2; x/2^m = g; */
+ /* y = F*(1 + f/F) for |f| <= 2^-8 */
+
+ m = logb(x);
+ g = ldexp(x, -m);
+ if (_IEEE && m == -1022) {
+ j = logb(g), m += j;
+ g = ldexp(g, -j);
+ }
+ j = N*(g-1) + .5;
+ F = (1.0/N) * j + 1;
+ f = g - F;
+
+ g = 1/(2*F+f);
+ u = 2*f*g;
+ v = u*u;
+ q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
+ if (m | j)
+ u1 = u + 513, u1 -= 513;
+ else
+ u1 = u, TRUNC(u1);
+ u2 = (2.0*(f - F*u1) - u1*f) * g;
+
+ u1 += m*logF_head[N] + logF_head[j];
+
+ u2 += logF_tail[j]; u2 += q;
+ u2 += logF_tail[N]*m;
+ r.a = u1 + u2; /* Only difference is here */
+ TRUNC(r.a);
+ r.b = (u1 - r.a) + u2;
+ return (r);
+}
diff --git a/lib/libm/common_source/log10.c b/lib/libm/common_source/log10.c
new file mode 100644
index 0000000..75205cd
--- /dev/null
+++ b/lib/libm/common_source/log10.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log10.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* LOG10(X)
+ * RETURN THE BASE 10 LOGARITHM OF x
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/20/85;
+ * REVISED BY K.C. NG on 1/23/85, 3/7/85, 4/16/85.
+ *
+ * Required kernel function:
+ * log(x)
+ *
+ * Method :
+ * log(x)
+ * log10(x) = --------- or [1/log(10)]*log(x)
+ * log(10)
+ *
+ * Note:
+ * [log(10)] rounded to 56 bits has error .0895 ulps,
+ * [1/log(10)] rounded to 53 bits has error .198 ulps;
+ * therefore, for better accuracy, in VAX D format, we divide
+ * log(x) by log(10), but in IEEE Double format, we multiply
+ * log(x) by [1/log(10)].
+ *
+ * Special cases:
+ * log10(x) is NaN with signal if x < 0;
+ * log10(+INF) is +INF with no signal; log10(0) is -INF with signal;
+ * log10(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ * log10(X) returns the exact log10(x) nearly rounded. In a test run
+ * with 1,536,000 random arguments on a VAX, the maximum observed
+ * error was 1.74 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(ln10hi, 2.3025850929940456790E0 ,5d8d,4113,a8ac,ddaa, 2, .935D8DDDAAA8AC)
+
+ic(ivln10, 4.3429448190325181667E-1, -2, 1.BCB7B1526E50E)
+
+#ifdef vccast
+#define ln10hi vccast(ln10hi)
+#endif
+
+
+double log10(x)
+double x;
+{
+#if defined(vax)||defined(tahoe)
+ return(log(x)/ln10hi);
+#else /* defined(vax)||defined(tahoe) */
+ return(ivln10*log(x));
+#endif /* defined(vax)||defined(tahoe) */
+}
diff --git a/lib/libm/common_source/log1p.c b/lib/libm/common_source/log1p.c
new file mode 100644
index 0000000..0202667
--- /dev/null
+++ b/lib/libm/common_source/log1p.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log1p.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* LOG1P(x)
+ * RETURN THE LOGARITHM OF 1+x
+ * DOUBLE PRECISION (VAX D FORMAT 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/19/85;
+ * REVISED BY K.C. NG on 2/6/85, 3/7/85, 3/24/85, 4/16/85.
+ *
+ * Required system supported functions:
+ * scalb(x,n)
+ * copysign(x,y)
+ * logb(x)
+ * finite(x)
+ *
+ * Required kernel function:
+ * log__L(z)
+ *
+ * Method :
+ * 1. Argument Reduction: find k and f such that
+ * 1+x = 2^k * (1+f),
+ * where sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ * 2. Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ * log(1+f) is computed by
+ *
+ * log(1+f) = 2s + s*log__L(s*s)
+ * where
+ * log__L(z) = z*(L1 + z*(L2 + z*(... (L6 + z*L7)...)))
+ *
+ * See log__L() for the values of the coefficients.
+ *
+ * 3. Finally, log(1+x) = k*ln2 + log(1+f).
+ *
+ * Remarks 1. In step 3 n*ln2 will be stored in two floating point numbers
+ * n*ln2hi + n*ln2lo, where ln2hi is chosen such that the last
+ * 20 bits (for VAX D format), or the last 21 bits ( for IEEE
+ * double) is 0. This ensures n*ln2hi is exactly representable.
+ * 2. In step 1, f may not be representable. A correction term c
+ * for f is computed. It follows that the correction term for
+ * f - t (the leading term of log(1+f) in step 2) is c-c*x. We
+ * add this correction term to n*ln2lo to attenuate the error.
+ *
+ *
+ * Special cases:
+ * log1p(x) is NaN with signal if x < -1; log1p(NaN) is NaN with no signal;
+ * log1p(INF) is +INF; log1p(-1) is -INF with signal;
+ * only log1p(0)=0 is exact for finite argument.
+ *
+ * Accuracy:
+ * log1p(x) returns the exact log(1+x) nearly rounded. In a test run
+ * with 1,536,000 random arguments on a VAX, the maximum observed
+ * error was .846 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include <errno.h>
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+vc(sqrt2, 1.4142135623730950622E0 ,04f3,40b5,de65,33f9, 1, .B504F333F9DE65)
+
+ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76)
+ic(sqrt2, 1.4142135623730951455E0, 0, 1.6A09E667F3BCD)
+
+#ifdef vccast
+#define ln2hi vccast(ln2hi)
+#define ln2lo vccast(ln2lo)
+#define sqrt2 vccast(sqrt2)
+#endif
+
+double log1p(x)
+double x;
+{
+ const static double zero=0.0, negone= -1.0, one=1.0,
+ half=1.0/2.0, small=1.0E-20; /* 1+small == 1 */
+ double z,s,t,c;
+ int k;
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+
+ if(finite(x)) {
+ if( x > negone ) {
+
+ /* argument reduction */
+ if(copysign(x,one)<small) return(x);
+ k=logb(one+x); z=scalb(x,-k); t=scalb(one,-k);
+ if(z+t >= sqrt2 )
+ { k += 1 ; z *= half; t *= half; }
+ t += negone; x = z + t;
+ c = (t-x)+z ; /* correction term for x */
+
+ /* compute log(1+x) */
+ s = x/(2+x); t = x*x*half;
+ c += (k*ln2lo-c*x);
+ z = c+s*(t+__log__L(s*s));
+ x += (z - t) ;
+
+ return(k*ln2hi+x);
+ }
+ /* end of if (x > negone) */
+
+ else {
+#if defined(vax)||defined(tahoe)
+ if ( x == negone )
+ return (infnan(-ERANGE)); /* -INF */
+ else
+ return (infnan(EDOM)); /* NaN */
+#else /* defined(vax)||defined(tahoe) */
+ /* x = -1, return -INF with signal */
+ if ( x == negone ) return( negone/zero );
+
+ /* negative argument for log, return NaN with signal */
+ else return ( zero / zero );
+#endif /* defined(vax)||defined(tahoe) */
+ }
+ }
+ /* end of if (finite(x)) */
+
+ /* log(-INF) is NaN */
+ else if(x<0)
+ return(zero/zero);
+
+ /* log(+INF) is INF */
+ else return(x);
+}
diff --git a/lib/libm/common_source/log__L.c b/lib/libm/common_source/log__L.c
new file mode 100644
index 0000000..207cb0d
--- /dev/null
+++ b/lib/libm/common_source/log__L.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log__L.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* log__L(Z)
+ * LOG(1+X) - 2S X
+ * RETURN --------------- WHERE Z = S*S, S = ------- , 0 <= Z <= .0294...
+ * S 2 + X
+ *
+ * DOUBLE PRECISION (VAX D FORMAT 56 bits or IEEE DOUBLE 53 BITS)
+ * KERNEL FUNCTION FOR LOG; TO BE USED IN LOG1P, LOG, AND POW FUNCTIONS
+ * CODED IN C BY K.C. NG, 1/19/85;
+ * REVISED BY K.C. Ng, 2/3/85, 4/16/85.
+ *
+ * Method :
+ * 1. Polynomial approximation: let s = x/(2+x).
+ * Based on log(1+x) = log(1+s) - log(1-s)
+ * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ *
+ * (log(1+x) - 2s)/s is computed by
+ *
+ * z*(L1 + z*(L2 + z*(... (L7 + z*L8)...)))
+ *
+ * where z=s*s. (See the listing below for Lk's values.) The
+ * coefficients are obtained by a special Remez algorithm.
+ *
+ * Accuracy:
+ * Assuming no rounding error, the maximum magnitude of the approximation
+ * error (absolute) is 2**(-58.49) for IEEE double, and 2**(-63.63)
+ * for VAX D format.
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(L1, 6.6666666666666703212E-1 ,aaaa,402a,aac5,aaaa, 0, .AAAAAAAAAAAAC5)
+vc(L2, 3.9999999999970461961E-1 ,cccc,3fcc,2684,cccc, -1, .CCCCCCCCCC2684)
+vc(L3, 2.8571428579395698188E-1 ,4924,3f92,5782,92f8, -1, .92492492F85782)
+vc(L4, 2.2222221233634724402E-1 ,8e38,3f63,af2c,39b7, -2, .E38E3839B7AF2C)
+vc(L5, 1.8181879517064680057E-1 ,2eb4,3f3a,655e,cc39, -2, .BA2EB4CC39655E)
+vc(L6, 1.5382888777946145467E-1 ,8551,3f1d,781d,e8c5, -2, .9D8551E8C5781D)
+vc(L7, 1.3338356561139403517E-1 ,95b3,3f08,cd92,907f, -2, .8895B3907FCD92)
+vc(L8, 1.2500000000000000000E-1 ,0000,3f00,0000,0000, -2, .80000000000000)
+
+ic(L1, 6.6666666666667340202E-1, -1, 1.5555555555592)
+ic(L2, 3.9999999999416702146E-1, -2, 1.999999997FF24)
+ic(L3, 2.8571428742008753154E-1, -2, 1.24924941E07B4)
+ic(L4, 2.2222198607186277597E-1, -3, 1.C71C52150BEA6)
+ic(L5, 1.8183562745289935658E-1, -3, 1.74663CC94342F)
+ic(L6, 1.5314087275331442206E-1, -3, 1.39A1EC014045B)
+ic(L7, 1.4795612545334174692E-1, -3, 1.2F039F0085122)
+
+#ifdef vccast
+#define L1 vccast(L1)
+#define L2 vccast(L2)
+#define L3 vccast(L3)
+#define L4 vccast(L4)
+#define L5 vccast(L5)
+#define L6 vccast(L6)
+#define L7 vccast(L7)
+#define L8 vccast(L8)
+#endif
+
+double __log__L(z)
+double z;
+{
+#if defined(vax)||defined(tahoe)
+ return(z*(L1+z*(L2+z*(L3+z*(L4+z*(L5+z*(L6+z*(L7+z*L8))))))));
+#else /* defined(vax)||defined(tahoe) */
+ return(z*(L1+z*(L2+z*(L3+z*(L4+z*(L5+z*(L6+z*L7)))))));
+#endif /* defined(vax)||defined(tahoe) */
+}
diff --git a/lib/libm/common_source/math.3 b/lib/libm/common_source/math.3
new file mode 100644
index 0000000..e935c73
--- /dev/null
+++ b/lib/libm/common_source/math.3
@@ -0,0 +1,631 @@
+.\" Copyright (c) 1985, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)math.3 8.2 (Berkeley) 5/5/94
+.\" $FreeBSD$
+.\"
+.TH MATH 3 "May 5, 1994"
+.UC 4
+.ds up \fIulp\fR
+.ds nn \fINaN\fR
+.de If
+.if n \\
+\\$1Infinity\\$2
+.if t \\
+\\$1\\(if\\$2
+..
+.SH NAME
+math \- introduction to mathematical library functions
+.SH DESCRIPTION
+These functions constitute the C math library,
+.I libm.
+The link editor searches this library under the \*(lq\-lm\*(rq option.
+Declarations for these functions may be obtained from the include file
+.RI < math.h >.
+The Fortran math library is described in ``man 3f intro''.
+.SH "LIST OF FUNCTIONS"
+.sp 2
+.nf
+.ta \w'copysign'u+2n +\w'infnan.3m'u+10n +\w'inverse trigonometric func'u
+\fIName\fP \fIAppears on Page\fP \fIDescription\fP \fIError Bound (ULPs)\fP
+.ta \w'copysign'u+4n +\w'infnan.3m'u+4n +\w'inverse trigonometric function'u+6nC
+.sp 5p
+acos sin.3m inverse trigonometric function 3
+acosh asinh.3m inverse hyperbolic function 3
+asin sin.3m inverse trigonometric function 3
+asinh asinh.3m inverse hyperbolic function 3
+atan sin.3m inverse trigonometric function 1
+atanh asinh.3m inverse hyperbolic function 3
+atan2 sin.3m inverse trigonometric function 2
+cabs hypot.3m complex absolute value 1
+cbrt sqrt.3m cube root 1
+ceil floor.3m integer no less than 0
+copysign ieee.3m copy sign bit 0
+cos sin.3m trigonometric function 1
+cosh sinh.3m hyperbolic function 3
+drem ieee.3m remainder 0
+erf erf.3m error function ???
+erfc erf.3m complementary error function ???
+exp exp.3m exponential 1
+expm1 exp.3m exp(x)\-1 1
+fabs floor.3m absolute value 0
+floor floor.3m integer no greater than 0
+hypot hypot.3m Euclidean distance 1
+infnan infnan.3m signals exceptions
+j0 j0.3m bessel function ???
+j1 j0.3m bessel function ???
+jn j0.3m bessel function ???
+lgamma lgamma.3m log gamma function; (formerly gamma.3m)
+log exp.3m natural logarithm 1
+logb ieee.3m exponent extraction 0
+log10 exp.3m logarithm to base 10 3
+log1p exp.3m log(1+x) 1
+pow exp.3m exponential x**y 60\-500
+rint floor.3m round to nearest integer 0
+scalb ieee.3m exponent adjustment 0
+sin sin.3m trigonometric function 1
+sinh sinh.3m hyperbolic function 3
+sqrt sqrt.3m square root 1
+tan sin.3m trigonometric function 3
+tanh sinh.3m hyperbolic function 3
+y0 j0.3m bessel function ???
+y1 j0.3m bessel function ???
+yn j0.3m bessel function ???
+.ta
+.fi
+.SH NOTES
+In 4.3 BSD, distributed from the University of California
+in late 1985, most of the foregoing functions come in two
+versions, one for the double\-precision "D" format in the
+DEC VAX\-11 family of computers, another for double\-precision
+arithmetic conforming to the IEEE Standard 754 for Binary
+Floating\-Point Arithmetic. The two versions behave very
+similarly, as should be expected from programs more accurate
+and robust than was the norm when UNIX was born. For
+instance, the programs are accurate to within the numbers
+of \*(ups tabulated above; an \*(up is one \fIU\fRnit in the \fIL\fRast
+\fIP\fRlace. And the programs have been cured of anomalies that
+afflicted the older math library \fIlibm\fR in which incidents like
+the following had been reported:
+.RS
+sqrt(\-1.0) = 0.0 and log(\-1.0) = \-1.7e38.
+.br
+cos(1.0e\-11) > cos(0.0) > 1.0.
+.br
+pow(x,1.0)
+.if n \
+!=
+.if t \
+\(!=
+x when x = 2.0, 3.0, 4.0, ..., 9.0.
+.br
+pow(\-1.0,1.0e10) trapped on Integer Overflow.
+.br
+sqrt(1.0e30) and sqrt(1.0e\-30) were very slow.
+.RE
+However the two versions do differ in ways that have to be
+explained, to which end the following notes are provided.
+.PP
+\fBDEC VAX\-11 D_floating\-point:\fR
+.PP
+This is the format for which the original math library \fIlibm\fR
+was developed, and to which this manual is still principally
+dedicated. It is \fIthe\fR double\-precision format for the PDP\-11
+and the earlier VAX\-11 machines; VAX\-11s after 1983 were
+provided with an optional "G" format closer to the IEEE
+double\-precision format. The earlier DEC MicroVAXs have no
+D format, only G double\-precision. (Why? Why not?)
+.PP
+Properties of D_floating\-point:
+.RS
+Wordsize: 64 bits, 8 bytes. Radix: Binary.
+.br
+Precision: 56
+.if n \
+sig.
+.if t \
+significant
+bits, roughly like 17
+.if n \
+sig.
+.if t \
+significant
+decimals.
+.RS
+If x and x' are consecutive positive D_floating\-point
+numbers (they differ by 1 \*(up), then
+.br
+1.3e\-17 < 0.5**56 < (x'\-x)/x \(<= 0.5**55 < 2.8e\-17.
+.RE
+.nf
+.ta \w'Range:'u+1n +\w'Underflow threshold'u+1n +\w'= 2.0**127'u+1n
+Range: Overflow threshold = 2.0**127 = 1.7e38.
+ Underflow threshold = 0.5**128 = 2.9e\-39.
+ NOTE: THIS RANGE IS COMPARATIVELY NARROW.
+.ta
+.fi
+.RS
+Overflow customarily stops computation.
+.br
+Underflow is customarily flushed quietly to zero.
+.br
+CAUTION:
+.RS
+It is possible to have x
+.if n \
+!=
+.if t \
+\(!=
+y and yet
+x\-y = 0 because of underflow. Similarly
+x > y > 0 cannot prevent either x\(**y = 0
+or y/x = 0 from happening without warning.
+.RE
+.RE
+Zero is represented ambiguously.
+.RS
+Although 2**55 different representations of zero are accepted by
+the hardware, only the obvious representation is ever produced.
+There is no \-0 on a VAX.
+.RE
+.If
+is not part of the VAX architecture.
+.br
+Reserved operands:
+.RS
+of the 2**55 that the hardware
+recognizes, only one of them is ever produced.
+Any floating\-point operation upon a reserved
+operand, even a MOVF or MOVD, customarily stops
+computation, so they are not much used.
+.RE
+Exceptions:
+.RS
+Divisions by zero and operations that
+overflow are invalid operations that customarily
+stop computation or, in earlier machines, produce
+reserved operands that will stop computation.
+.RE
+Rounding:
+.RS
+Every rational operation (+, \-, \(**, /) on a
+VAX (but not necessarily on a PDP\-11), if not an
+over/underflow nor division by zero, is rounded to
+within half an \*(up, and when the rounding error is
+exactly half an \*(up then rounding is away from 0.
+.RE
+.RE
+.PP
+Except for its narrow range, D_floating\-point is one of the
+better computer arithmetics designed in the 1960's.
+Its properties are reflected fairly faithfully in the elementary
+functions for a VAX distributed in 4.3 BSD.
+They over/underflow only if their results have to lie out of range
+or very nearly so, and then they behave much as any rational
+arithmetic operation that over/underflowed would behave.
+Similarly, expressions like log(0) and atanh(1) behave
+like 1/0; and sqrt(\-3) and acos(3) behave like 0/0;
+they all produce reserved operands and/or stop computation!
+The situation is described in more detail in manual pages.
+.RS
+.ll -0.5i
+\fIThis response seems excessively punitive, so it is destined
+to be replaced at some time in the foreseeable future by a
+more flexible but still uniform scheme being developed to
+handle all floating\-point arithmetic exceptions neatly.
+See infnan(3M) for the present state of affairs.\fR
+.ll +0.5i
+.RE
+.PP
+How do the functions in 4.3 BSD's new \fIlibm\fR for UNIX
+compare with their counterparts in DEC's VAX/VMS library?
+Some of the VMS functions are a little faster, some are
+a little more accurate, some are more puritanical about
+exceptions (like pow(0.0,0.0) and atan2(0.0,0.0)),
+and most occupy much more memory than their counterparts in
+\fIlibm\fR.
+The VMS codes interpolate in large table to achieve
+speed and accuracy; the \fIlibm\fR codes use tricky formulas
+compact enough that all of them may some day fit into a ROM.
+.PP
+More important, DEC regards the VMS codes as proprietary
+and guards them zealously against unauthorized use. But the
+\fIlibm\fR codes in 4.3 BSD are intended for the public domain;
+they may be copied freely provided their provenance is always
+acknowledged, and provided users assist the authors in their
+researches by reporting experience with the codes.
+Therefore no user of UNIX on a machine whose arithmetic resembles
+VAX D_floating\-point need use anything worse than the new \fIlibm\fR.
+.PP
+\fBIEEE STANDARD 754 Floating\-Point Arithmetic:\fR
+.PP
+This standard is on its way to becoming more widely adopted
+than any other design for computer arithmetic.
+VLSI chips that conform to some version of that standard have been
+produced by a host of manufacturers, among them ...
+.nf
+.ta 0.5i +\w'Intel i8070, i80287'u+6n
+ Intel i8087, i80287 National Semiconductor 32081
+ Motorola 68881 Weitek WTL-1032, ... , -1165
+ Zilog Z8070 Western Electric (AT&T) WE32106.
+.ta
+.fi
+Other implementations range from software, done thoroughly
+in the Apple Macintosh, through VLSI in the Hewlett\-Packard
+9000 series, to the ELXSI 6400 running ECL at 3 Megaflops.
+Several other companies have adopted the formats
+of IEEE 754 without, alas, adhering to the standard's way
+of handling rounding and exceptions like over/underflow.
+The DEC VAX G_floating\-point format is very similar to the IEEE
+754 Double format, so similar that the C programs for the
+IEEE versions of most of the elementary functions listed
+above could easily be converted to run on a MicroVAX, though
+nobody has volunteered to do that yet.
+.PP
+The codes in 4.3 BSD's \fIlibm\fR for machines that conform to
+IEEE 754 are intended primarily for the National Semi. 32081
+and WTL 1164/65. To use these codes with the Intel or Zilog
+chips, or with the Apple Macintosh or ELXSI 6400, is to
+forego the use of better codes provided (perhaps freely) by
+those companies and designed by some of the authors of the
+codes above.
+Except for \fIatan\fR, \fIcabs\fR, \fIcbrt\fR, \fIerf\fR,
+\fIerfc\fR, \fIhypot\fR, \fIj0\-jn\fR, \fIlgamma\fR, \fIpow\fR
+and \fIy0\-yn\fR,
+the Motorola 68881 has all the functions in \fIlibm\fR on chip,
+and faster and more accurate;
+it, Apple, the i8087, Z8070 and WE32106 all use 64
+.if n \
+sig.
+.if t \
+significant
+bits.
+The main virtue of 4.3 BSD's
+\fIlibm\fR codes is that they are intended for the public domain;
+they may be copied freely provided their provenance is always
+acknowledged, and provided users assist the authors in their
+researches by reporting experience with the codes.
+Therefore no user of UNIX on a machine that conforms to
+IEEE 754 need use anything worse than the new \fIlibm\fR.
+.PP
+Properties of IEEE 754 Double\-Precision:
+.RS
+Wordsize: 64 bits, 8 bytes. Radix: Binary.
+.br
+Precision: 53
+.if n \
+sig.
+.if t \
+significant
+bits, roughly like 16
+.if n \
+sig.
+.if t \
+significant
+decimals.
+.RS
+If x and x' are consecutive positive Double\-Precision
+numbers (they differ by 1 \*(up), then
+.br
+1.1e\-16 < 0.5**53 < (x'\-x)/x \(<= 0.5**52 < 2.3e\-16.
+.RE
+.nf
+.ta \w'Range:'u+1n +\w'Underflow threshold'u+1n +\w'= 2.0**1024'u+1n
+Range: Overflow threshold = 2.0**1024 = 1.8e308
+ Underflow threshold = 0.5**1022 = 2.2e\-308
+.ta
+.fi
+.RS
+Overflow goes by default to a signed
+.If "" .
+.br
+Underflow is \fIGradual,\fR rounding to the nearest
+integer multiple of 0.5**1074 = 4.9e\-324.
+.RE
+Zero is represented ambiguously as +0 or \-0.
+.RS
+Its sign transforms correctly through multiplication or
+division, and is preserved by addition of zeros
+with like signs; but x\-x yields +0 for every
+finite x. The only operations that reveal zero's
+sign are division by zero and copysign(x,\(+-0).
+In particular, comparison (x > y, x \(>= y, etc.)
+cannot be affected by the sign of zero; but if
+finite x = y then
+.If
+\&= 1/(x\-y)
+.if n \
+!=
+.if t \
+\(!=
+\-1/(y\-x) =
+.If \- .
+.RE
+.If
+is signed.
+.RS
+it persists when added to itself
+or to any finite number. Its sign transforms
+correctly through multiplication and division, and
+.If (finite)/\(+- \0=\0\(+-0
+(nonzero)/0 =
+.If \(+- .
+But
+.if n \
+Infinity\-Infinity, Infinity\(**0 and Infinity/Infinity
+.if t \
+\(if\-\(if, \(if\(**0 and \(if/\(if
+are, like 0/0 and sqrt(\-3),
+invalid operations that produce \*(nn. ...
+.RE
+Reserved operands:
+.RS
+there are 2**53\-2 of them, all
+called \*(nn (\fIN\fRot \fIa N\fRumber).
+Some, called Signaling \*(nns, trap any floating\-point operation
+performed upon them; they are used to mark missing
+or uninitialized values, or nonexistent elements
+of arrays. The rest are Quiet \*(nns; they are
+the default results of Invalid Operations, and
+propagate through subsequent arithmetic operations.
+If x
+.if n \
+!=
+.if t \
+\(!=
+x then x is \*(nn; every other predicate
+(x > y, x = y, x < y, ...) is FALSE if \*(nn is involved.
+.br
+NOTE: Trichotomy is violated by \*(nn.
+.RS
+Besides being FALSE, predicates that entail ordered
+comparison, rather than mere (in)equality,
+signal Invalid Operation when \*(nn is involved.
+.RE
+.RE
+Rounding:
+.RS
+Every algebraic operation (+, \-, \(**, /,
+.if n \
+sqrt)
+.if t \
+\(sr)
+is rounded by default to within half an \*(up, and
+when the rounding error is exactly half an \*(up then
+the rounded value's least significant bit is zero.
+This kind of rounding is usually the best kind,
+sometimes provably so; for instance, for every
+x = 1.0, 2.0, 3.0, 4.0, ..., 2.0**52, we find
+(x/3.0)\(**3.0 == x and (x/10.0)\(**10.0 == x and ...
+despite that both the quotients and the products
+have been rounded. Only rounding like IEEE 754
+can do that. But no single kind of rounding can be
+proved best for every circumstance, so IEEE 754
+provides rounding towards zero or towards
+.If +
+or towards
+.If \-
+at the programmer's option. And the
+same kinds of rounding are specified for
+Binary\-Decimal Conversions, at least for magnitudes
+between roughly 1.0e\-10 and 1.0e37.
+.RE
+Exceptions:
+.RS
+IEEE 754 recognizes five kinds of floating\-point exceptions,
+listed below in declining order of probable importance.
+.RS
+.nf
+.ta \w'Invalid Operation'u+6n +\w'Gradual Underflow'u+2n
+Exception Default Result
+.sp 0.5
+Invalid Operation \*(nn, or FALSE
+.if n \{\
+Overflow \(+-Infinity
+Divide by Zero \(+-Infinity \}
+.if t \{\
+Overflow \(+-\(if
+Divide by Zero \(+-\(if \}
+Underflow Gradual Underflow
+Inexact Rounded value
+.ta
+.fi
+.RE
+NOTE: An Exception is not an Error unless handled
+badly. What makes a class of exceptions exceptional
+is that no single default response can be satisfactory
+in every instance. On the other hand, if a default
+response will serve most instances satisfactorily,
+the unsatisfactory instances cannot justify aborting
+computation every time the exception occurs.
+.RE
+.PP
+For each kind of floating\-point exception, IEEE 754
+provides a Flag that is raised each time its exception
+is signaled, and stays raised until the program resets
+it. Programs may also test, save and restore a flag.
+Thus, IEEE 754 provides three ways by which programs
+may cope with exceptions for which the default result
+might be unsatisfactory:
+.IP 1) \w'\0\0\0\0'u
+Test for a condition that might cause an exception
+later, and branch to avoid the exception.
+.IP 2) \w'\0\0\0\0'u
+Test a flag to see whether an exception has occurred
+since the program last reset its flag.
+.IP 3) \w'\0\0\0\0'u
+Test a result to see whether it is a value that only
+an exception could have produced.
+.RS
+CAUTION: The only reliable ways to discover
+whether Underflow has occurred are to test whether
+products or quotients lie closer to zero than the
+underflow threshold, or to test the Underflow
+flag. (Sums and differences cannot underflow in
+IEEE 754; if x
+.if n \
+!=
+.if t \
+\(!=
+y then x\-y is correct to
+full precision and certainly nonzero regardless of
+how tiny it may be.) Products and quotients that
+underflow gradually can lose accuracy gradually
+without vanishing, so comparing them with zero
+(as one might on a VAX) will not reveal the loss.
+Fortunately, if a gradually underflowed value is
+destined to be added to something bigger than the
+underflow threshold, as is almost always the case,
+digits lost to gradual underflow will not be missed
+because they would have been rounded off anyway.
+So gradual underflows are usually \fIprovably\fR ignorable.
+The same cannot be said of underflows flushed to 0.
+.RE
+.PP
+At the option of an implementor conforming to IEEE 754,
+other ways to cope with exceptions may be provided:
+.IP 4) \w'\0\0\0\0'u
+ABORT. This mechanism classifies an exception in
+advance as an incident to be handled by means
+traditionally associated with error\-handling
+statements like "ON ERROR GO TO ...". Different
+languages offer different forms of this statement,
+but most share the following characteristics:
+.IP \(em \w'\0\0\0\0'u
+No means is provided to substitute a value for
+the offending operation's result and resume
+computation from what may be the middle of an
+expression. An exceptional result is abandoned.
+.IP \(em \w'\0\0\0\0'u
+In a subprogram that lacks an error\-handling
+statement, an exception causes the subprogram to
+abort within whatever program called it, and so
+on back up the chain of calling subprograms until
+an error\-handling statement is encountered or the
+whole task is aborted and memory is dumped.
+.IP 5) \w'\0\0\0\0'u
+STOP. This mechanism, requiring an interactive
+debugging environment, is more for the programmer
+than the program. It classifies an exception in
+advance as a symptom of a programmer's error; the
+exception suspends execution as near as it can to
+the offending operation so that the programmer can
+look around to see how it happened. Quite often
+the first several exceptions turn out to be quite
+unexceptionable, so the programmer ought ideally
+to be able to resume execution after each one as if
+execution had not been stopped.
+.IP 6) \w'\0\0\0\0'u
+\&... Other ways lie beyond the scope of this document.
+.RE
+.PP
+The crucial problem for exception handling is the problem of
+Scope, and the problem's solution is understood, but not
+enough manpower was available to implement it fully in time
+to be distributed in 4.3 BSD's \fIlibm\fR. Ideally, each
+elementary function should act as if it were indivisible, or
+atomic, in the sense that ...
+.IP i) \w'iii)'u+2n
+No exception should be signaled that is not deserved by
+the data supplied to that function.
+.IP ii) \w'iii)'u+2n
+Any exception signaled should be identified with that
+function rather than with one of its subroutines.
+.IP iii) \w'iii)'u+2n
+The internal behavior of an atomic function should not
+be disrupted when a calling program changes from
+one to another of the five or so ways of handling
+exceptions listed above, although the definition
+of the function may be correlated intentionally
+with exception handling.
+.PP
+Ideally, every programmer should be able \fIconveniently\fR to
+turn a debugged subprogram into one that appears atomic to
+its users. But simulating all three characteristics of an
+atomic function is still a tedious affair, entailing hosts
+of tests and saves\-restores; work is under way to ameliorate
+the inconvenience.
+.PP
+Meanwhile, the functions in \fIlibm\fR are only approximately
+atomic. They signal no inappropriate exception except
+possibly ...
+.RS
+Over/Underflow
+.RS
+when a result, if properly computed, might have lain barely within range, and
+.RE
+Inexact in \fIcabs\fR, \fIcbrt\fR, \fIhypot\fR, \fIlog10\fR and \fIpow\fR
+.RS
+when it happens to be exact, thanks to fortuitous cancellation of errors.
+.RE
+.RE
+Otherwise, ...
+.RS
+Invalid Operation is signaled only when
+.RS
+any result but \*(nn would probably be misleading.
+.RE
+Overflow is signaled only when
+.RS
+the exact result would be finite but beyond the overflow threshold.
+.RE
+Divide\-by\-Zero is signaled only when
+.RS
+a function takes exactly infinite values at finite operands.
+.RE
+Underflow is signaled only when
+.RS
+the exact result would be nonzero but tinier than the underflow threshold.
+.RE
+Inexact is signaled only when
+.RS
+greater range or precision would be needed to represent the exact result.
+.RE
+.RE
+.SH BUGS
+When signals are appropriate, they are emitted by certain
+operations within the codes, so a subroutine\-trace may be
+needed to identify the function with its signal in case
+method 5) above is in use. And the codes all take the
+IEEE 754 defaults for granted; this means that a decision to
+trap all divisions by zero could disrupt a code that would
+otherwise get correct results despite division by zero.
+.SH SEE ALSO
+An explanation of IEEE 754 and its proposed extension p854
+was published in the IEEE magazine MICRO in August 1984 under
+the title "A Proposed Radix\- and Word\-length\-independent
+Standard for Floating\-point Arithmetic" by W. J. Cody et al.
+The manuals for Pascal, C and BASIC on the Apple Macintosh
+document the features of IEEE 754 pretty well.
+Articles in the IEEE magazine COMPUTER vol. 14 no. 3 (Mar.
+1981), and in the ACM SIGNUM Newsletter Special Issue of
+Oct. 1979, may be helpful although they pertain to
+superseded drafts of the standard.
diff --git a/lib/libm/common_source/mathimpl.h b/lib/libm/common_source/mathimpl.h
new file mode 100644
index 0000000..6a2a37d
--- /dev/null
+++ b/lib/libm/common_source/mathimpl.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)mathimpl.h 8.1 (Berkeley) 6/4/93
+ */
+
+#include <sys/cdefs.h>
+#include <math.h>
+
+#if defined(vax)||defined(tahoe)
+
+/* Deal with different ways to concatenate in cpp */
+# ifdef __STDC__
+# define cat3(a,b,c) a ## b ## c
+# else
+# define cat3(a,b,c) a/**/b/**/c
+# endif
+
+/* Deal with vax/tahoe byte order issues */
+# ifdef vax
+# define cat3t(a,b,c) cat3(a,b,c)
+# else
+# define cat3t(a,b,c) cat3(a,c,b)
+# endif
+
+# define vccast(name) (*(const double *)(cat3(name,,x)))
+
+ /*
+ * Define a constant to high precision on a Vax or Tahoe.
+ *
+ * Args are the name to define, the decimal floating point value,
+ * four 16-bit chunks of the float value in hex
+ * (because the vax and tahoe differ in float format!), the power
+ * of 2 of the hex-float exponent, and the hex-float mantissa.
+ * Most of these arguments are not used at compile time; they are
+ * used in a post-check to make sure the constants were compiled
+ * correctly.
+ *
+ * People who want to use the constant will have to do their own
+ * #define foo vccast(foo)
+ * since CPP cannot do this for them from inside another macro (sigh).
+ * We define "vccast" if this needs doing.
+ */
+# define vc(name, value, x1,x2,x3,x4, bexp, xval) \
+ const static long cat3(name,,x)[] = {cat3t(0x,x1,x2), cat3t(0x,x3,x4)};
+
+# define ic(name, value, bexp, xval) ;
+
+#else /* vax or tahoe */
+
+ /* Hooray, we have an IEEE machine */
+# undef vccast
+# define vc(name, value, x1,x2,x3,x4, bexp, xval) ;
+
+# define ic(name, value, bexp, xval) \
+ const static double name = value;
+
+#endif /* defined(vax)||defined(tahoe) */
+
+
+/*
+ * Functions internal to the math package, yet not static.
+ */
+extern double __exp__E();
+extern double __log__L();
+
+struct Double {double a, b;};
+double __exp__D __P((double, double));
+struct Double __log__D __P((double));
diff --git a/lib/libm/common_source/pow.c b/lib/libm/common_source/pow.c
new file mode 100644
index 0000000..9e92985
--- /dev/null
+++ b/lib/libm/common_source/pow.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pow.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* POW(X,Y)
+ * RETURN X**Y
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/8/85;
+ * REVISED BY K.C. NG on 7/10/85.
+ * KERNEL pow_P() REPLACED BY P. McILROY 7/22/92.
+ * Required system supported functions:
+ * scalb(x,n)
+ * logb(x)
+ * copysign(x,y)
+ * finite(x)
+ * drem(x,y)
+ *
+ * Required kernel functions:
+ * exp__D(a,c) exp(a + c) for |a| << |c|
+ * struct d_double dlog(x) r.a + r.b, |r.b| < |r.a|
+ *
+ * Method
+ * 1. Compute and return log(x) in three pieces:
+ * log(x) = n*ln2 + hi + lo,
+ * where n is an integer.
+ * 2. Perform y*log(x) by simulating muti-precision arithmetic and
+ * return the answer in three pieces:
+ * y*log(x) = m*ln2 + hi + lo,
+ * where m is an integer.
+ * 3. Return x**y = exp(y*log(x))
+ * = 2^m * ( exp(hi+lo) ).
+ *
+ * Special cases:
+ * (anything) ** 0 is 1 ;
+ * (anything) ** 1 is itself;
+ * (anything) ** NaN is NaN;
+ * NaN ** (anything except 0) is NaN;
+ * +(anything > 1) ** +INF is +INF;
+ * -(anything > 1) ** +INF is NaN;
+ * +-(anything > 1) ** -INF is +0;
+ * +-(anything < 1) ** +INF is +0;
+ * +(anything < 1) ** -INF is +INF;
+ * -(anything < 1) ** -INF is NaN;
+ * +-1 ** +-INF is NaN and signal INVALID;
+ * +0 ** +(anything except 0, NaN) is +0;
+ * -0 ** +(anything except 0, NaN, odd integer) is +0;
+ * +0 ** -(anything except 0, NaN) is +INF and signal DIV-BY-ZERO;
+ * -0 ** -(anything except 0, NaN, odd integer) is +INF with signal;
+ * -0 ** (odd integer) = -( +0 ** (odd integer) );
+ * +INF ** +(anything except 0,NaN) is +INF;
+ * +INF ** -(anything except 0,NaN) is +0;
+ * -INF ** (odd integer) = -( +INF ** (odd integer) );
+ * -INF ** (even integer) = ( +INF ** (even integer) );
+ * -INF ** -(anything except integer,NaN) is NaN with signal;
+ * -(x=anything) ** (k=integer) is (-1)**k * (x ** k);
+ * -(anything except 0) ** (non-integer) is NaN with signal;
+ *
+ * Accuracy:
+ * pow(x,y) returns x**y nearly rounded. In particular, on a SUN, a VAX,
+ * and a Zilog Z8000,
+ * pow(integer,integer)
+ * always returns the correct integer provided it is representable.
+ * In a test run with 100,000 random arguments with 0 < x, y < 20.0
+ * on a VAX, the maximum observed error was 1.79 ulps (units in the
+ * last place).
+ *
+ * Constants :
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include <errno.h>
+#include <math.h>
+
+#include "mathimpl.h"
+
+#if (defined(vax) || defined(tahoe))
+#define TRUNC(x) x = (double) (float) x
+#define _IEEE 0
+#else
+#define _IEEE 1
+#define endian (((*(int *) &one)) ? 1 : 0)
+#define TRUNC(x) *(((int *) &x)+endian) &= 0xf8000000
+#define infnan(x) 0.0
+#endif /* vax or tahoe */
+
+const static double zero=0.0, one=1.0, two=2.0, negone= -1.0;
+
+static double pow_P __P((double, double));
+
+double pow(x,y)
+double x,y;
+{
+ double t;
+ if (y==zero)
+ return (one);
+ else if (y==one || (_IEEE && x != x))
+ return (x); /* if x is NaN or y=1 */
+ else if (_IEEE && y!=y) /* if y is NaN */
+ return (y);
+ else if (!finite(y)) /* if y is INF */
+ if ((t=fabs(x))==one) /* +-1 ** +-INF is NaN */
+ return (y - y);
+ else if (t>one)
+ return ((y<0)? zero : ((x<zero)? y-y : y));
+ else
+ return ((y>0)? zero : ((x<0)? y-y : -y));
+ else if (y==two)
+ return (x*x);
+ else if (y==negone)
+ return (one/x);
+ /* x > 0, x == +0 */
+ else if (copysign(one, x) == one)
+ return (pow_P(x, y));
+
+ /* sign(x)= -1 */
+ /* if y is an even integer */
+ else if ( (t=drem(y,two)) == zero)
+ return (pow_P(-x, y));
+
+ /* if y is an odd integer */
+ else if (copysign(t,one) == one)
+ return (-pow_P(-x, y));
+
+ /* Henceforth y is not an integer */
+ else if (x==zero) /* x is -0 */
+ return ((y>zero)? -x : one/(-x));
+ else if (_IEEE)
+ return (zero/zero);
+ else
+ return (infnan(EDOM));
+}
+/* kernel function for x >= 0 */
+static double
+#ifdef _ANSI_SOURCE
+pow_P(double x, double y)
+#else
+pow_P(x, y) double x, y;
+#endif
+{
+ struct Double s, t, __log__D();
+ double __exp__D();
+ volatile double huge = 1e300, tiny = 1e-300;
+
+ if (x == zero)
+ if (y > zero)
+ return (zero);
+ else if (_IEEE)
+ return (huge*huge);
+ else
+ return (infnan(ERANGE));
+ if (x == one)
+ return (one);
+ if (!finite(x))
+ if (y < zero)
+ return (zero);
+ else if (_IEEE)
+ return (huge*huge);
+ else
+ return (infnan(ERANGE));
+ if (y >= 7e18) /* infinity */
+ if (x < 1)
+ return(tiny*tiny);
+ else if (_IEEE)
+ return (huge*huge);
+ else
+ return (infnan(ERANGE));
+
+ /* Return exp(y*log(x)), using simulated extended */
+ /* precision for the log and the multiply. */
+
+ s = __log__D(x);
+ t.a = y;
+ TRUNC(t.a);
+ t.b = y - t.a;
+ t.b = s.b*y + t.b*s.a;
+ t.a *= s.a;
+ s.a = t.a + t.b;
+ s.b = (t.a - s.a) + t.b;
+ return (__exp__D(s.a, s.b));
+}
diff --git a/lib/libm/common_source/rint.3 b/lib/libm/common_source/rint.3
new file mode 100644
index 0000000..b8986f1
--- /dev/null
+++ b/lib/libm/common_source/rint.3
@@ -0,0 +1,116 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)rint.3 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd December 11, 1993
+.Dt RINT 3
+.Os
+.Sh NAME
+.Nm rint
+.Nd round-to-closest integer functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn rint "double x"
+.Sh DESCRIPTION
+The
+.Fn rint
+function finds the integer (represented as a double precision number)
+nearest to
+.Fa x
+in the direction of the prevailing rounding mode.
+.Sh NOTES
+On a
+.Tn VAX ,
+.Fn rint x
+is equivalent to adding half to the magnitude
+and then rounding towards zero.
+.Pp
+In the default rounding mode, to nearest,
+on a machine that conforms to
+.Tn IEEE
+754,
+.Fn rint x
+is the integer nearest
+.Fa x
+with the additional stipulation
+that if
+.Li |rint(x)\-x|=1/2
+then
+.Fn rint x
+is even.
+Other rounding modes can make
+.Fn rint
+act like
+.Fn floor ,
+or like
+.Fn ceil ,
+or round towards zero.
+.Pp
+Another way to obtain an integer near
+.Fa x
+is to declare (in C)
+.Bd -literal -offset indent
+double x;\0\0\0\0 int k;\0\0\0\0k\0=\0x;
+.Ed
+.Pp
+Most C compilers round
+.Fa x
+towards 0 to get the integer
+.Fa k ,
+but
+some do otherwise.
+If in doubt, use
+.Fn floor ,
+.Fn ceil ,
+or
+.Fn rint
+first, whichever you intend.
+Also note that, if x is larger than
+.Fa k
+can accommodate, the value of
+.Fa k
+and the presence or absence of an integer overflow are hard to
+predict.
+.Sh SEE ALSO
+.Xr abs 3 ,
+.Xr ceil 3 ,
+.Xr fabs 3 ,
+.Xr floor 3 ,
+.Xr ieee 3 ,
+.Xr math 3
+.Sh HISTORY
+A
+.Fn rint
+function appeared in
+.At v6 .
diff --git a/lib/libm/common_source/sin.3 b/lib/libm/common_source/sin.3
new file mode 100644
index 0000000..87ddc23
--- /dev/null
+++ b/lib/libm/common_source/sin.3
@@ -0,0 +1,73 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" @(#)sin.3 8.1 (Berkeley) 6/4/93
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sin.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SIN 3
+.Os
+.Sh NAME
+.Nm sin
+.Nd sine function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn sin "double x"
+.Sh DESCRIPTION
+The
+.Fn sin
+function computes the sine of
+.Fa x
+(measured in radians).
+A large magnitude argument may yield a result with little
+or no significance.
+.Sh RETURN VALUES
+The
+.Fn sin
+function returns the sine value.
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn sin
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/sinh.3 b/lib/libm/common_source/sinh.3
new file mode 100644
index 0000000..f285d7e
--- /dev/null
+++ b/lib/libm/common_source/sinh.3
@@ -0,0 +1,76 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sinh.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SINH 3
+.Os
+.Sh NAME
+.Nm sinh
+.Nd hyperbolic sine function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn sinh "double x"
+.Sh DESCRIPTION
+The
+.Fn sinh
+function computes the hyperbolic sine of
+.Fa x .
+.Sh RETURN VALUES
+The
+.Fn sinh
+function returns the hyperbolic sine value unless
+the magnitude
+of
+.Fa x
+is too large; in this event, the global variable
+.Va errno
+is set to
+.Er ERANGE .
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn sinh
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/sinh.c b/lib/libm/common_source/sinh.c
new file mode 100644
index 0000000..075172c
--- /dev/null
+++ b/lib/libm/common_source/sinh.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)sinh.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* SINH(X)
+ * RETURN THE HYPERBOLIC SINE OF X
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/8/85;
+ * REVISED BY K.C. NG on 2/8/85, 3/7/85, 3/24/85, 4/16/85.
+ *
+ * Required system supported functions :
+ * copysign(x,y)
+ * scalb(x,N)
+ *
+ * Required kernel functions:
+ * expm1(x) ...return exp(x)-1
+ *
+ * Method :
+ * 1. reduce x to non-negative by sinh(-x) = - sinh(x).
+ * 2.
+ *
+ * expm1(x) + expm1(x)/(expm1(x)+1)
+ * 0 <= x <= lnovfl : sinh(x) := --------------------------------
+ * 2
+ * lnovfl <= x <= lnovfl+ln2 : sinh(x) := expm1(x)/2 (avoid overflow)
+ * lnovfl+ln2 < x < INF : overflow to INF
+ *
+ *
+ * Special cases:
+ * sinh(x) is x if x is +INF, -INF, or NaN.
+ * only sinh(0)=0 is exact for finite argument.
+ *
+ * Accuracy:
+ * sinh(x) returns the exact hyperbolic sine of x nearly rounded. In
+ * a test run with 1,024,000 random arguments on a VAX, the maximum
+ * observed error was 1.93 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(mln2hi, 8.8029691931113054792E1 ,0f33,43b0,2bdb,c7e2, 7, .B00F33C7E22BDB)
+vc(mln2lo,-4.9650192275318476525E-16 ,1b60,a70f,582a,279e, -50,-.8F1B60279E582A)
+vc(lnovfl, 8.8029691931113053016E1 ,0f33,43b0,2bda,c7e2, 7, .B00F33C7E22BDA)
+
+ic(mln2hi, 7.0978271289338397310E2, 10, 1.62E42FEFA39EF)
+ic(mln2lo, 2.3747039373786107478E-14, -45, 1.ABC9E3B39803F)
+ic(lnovfl, 7.0978271289338397310E2, 9, 1.62E42FEFA39EF)
+
+#ifdef vccast
+#define mln2hi vccast(mln2hi)
+#define mln2lo vccast(mln2lo)
+#define lnovfl vccast(lnovfl)
+#endif
+
+#if defined(vax)||defined(tahoe)
+static max = 126 ;
+#else /* defined(vax)||defined(tahoe) */
+static max = 1023 ;
+#endif /* defined(vax)||defined(tahoe) */
+
+
+double sinh(x)
+double x;
+{
+ static const double one=1.0, half=1.0/2.0 ;
+ double t, sign;
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ sign=copysign(one,x);
+ x=copysign(x,one);
+ if(x<lnovfl)
+ {t=expm1(x); return(copysign((t+t/(one+t))*half,sign));}
+
+ else if(x <= lnovfl+0.7)
+ /* subtract x by ln(2^(max+1)) and return 2^max*exp(x)
+ to avoid unnecessary overflow */
+ return(copysign(scalb(one+expm1((x-mln2hi)-mln2lo),max),sign));
+
+ else /* sinh(+-INF) = +-INF, sinh(+-big no.) overflow to +-INF */
+ return( expm1(x)*sign );
+}
diff --git a/lib/libm/common_source/sqrt.3 b/lib/libm/common_source/sqrt.3
new file mode 100644
index 0000000..067a70e
--- /dev/null
+++ b/lib/libm/common_source/sqrt.3
@@ -0,0 +1,121 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sqrt.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt SQRT 3
+.Os
+.Sh NAME
+.Nm cbrt ,
+.Nm sqrt
+.Nd cube root and square root functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn cbrt "double x"
+.Ft double
+.Fn sqrt "double x"
+.Sh DESCRIPTION
+The
+.Fn cbrt
+function computes
+the cube root of
+.Ar x .
+.Pp
+The
+.Fn sqrt
+computes the
+non-negative square root of x.
+.Sh RETURN VALUES
+The
+.Fn cbrt
+function returns the requested cube root.
+The
+.Fn sqrt
+function returns the requested square root
+unless an error occurs.
+On the
+.Tn VAX
+or
+.Tn Tahoe
+processor an attempt to take the
+.Fn sqrt
+of negative
+.Fa x
+causes an error; in this event,
+the global variable
+.Va errno
+is set to
+.Dv EDOM
+and a reserved operand fault is generated.
+.Sh ERROR (due to Roundoff etc.)
+The
+.Fn cbrt
+function
+is accurate to within 0.7
+.Em ulps .
+.Pp
+The
+.Fn sqrt
+function on a
+.Tn VAX
+is accurate to within 0.501
+.Em ulps .
+Sqrt on a machine that conforms to
+.Tn IEEE
+754 is correctly rounded
+in accordance with the rounding mode in force; the error is less than
+half an
+.Em ulp
+in the default mode (round\-to\-nearest).
+An
+.Em ulp
+is one
+.Em U Ns nit
+in the
+.Em L Ns ast
+.Em P Ns lace
+carried.
+.Sh SEE ALSO
+.Xr infnan 3 ,
+.Xr math 3
+.Sh STANDARDS
+The
+.Nm sqrt
+function conforms to
+.St -ansiC .
+.Sh HISTORY
+The
+.Nm cbrt
+function appeared in
+.Bx 4.3 .
diff --git a/lib/libm/common_source/tan.3 b/lib/libm/common_source/tan.3
new file mode 100644
index 0000000..801464b
--- /dev/null
+++ b/lib/libm/common_source/tan.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tan.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt TAN 3
+.Os
+.Sh NAME
+.Nm tan
+.Nd tangent function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn tan "double x"
+.Sh DESCRIPTION
+The
+.Fn tan
+function computes the tangent of
+.Fa x
+(measured in radians).
+A large magnitude argument may yield a result
+with little or no significance.
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn tan
+function returns the tangent value.
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn tan
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/tanh.3 b/lib/libm/common_source/tanh.3
new file mode 100644
index 0000000..102e606
--- /dev/null
+++ b/lib/libm/common_source/tanh.3
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tanh.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD$
+.\"
+.Dd June 4, 1993
+.Dt TANH 3
+.Os
+.Sh NAME
+.Nm tanh
+.Nd hyperbolic tangent function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn tanh "double x"
+.Sh DESCRIPTION
+The
+.Fn tanh
+function computes the hyperbolic tangent of
+.Fa x .
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn tanh
+function returns the hyperbolic tangent value.
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3
+.Sh STANDARDS
+The
+.Fn tanh
+function conforms to
+.St -ansiC .
diff --git a/lib/libm/common_source/tanh.c b/lib/libm/common_source/tanh.c
new file mode 100644
index 0000000..6813b55
--- /dev/null
+++ b/lib/libm/common_source/tanh.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tanh.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* TANH(X)
+ * RETURN THE HYPERBOLIC TANGENT OF X
+ * DOUBLE PRECISION (VAX D FORMAT 56 BITS, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/8/85;
+ * REVISED BY K.C. NG on 2/8/85, 2/11/85, 3/7/85, 3/24/85.
+ *
+ * Required system supported functions :
+ * copysign(x,y)
+ * finite(x)
+ *
+ * Required kernel function:
+ * expm1(x) ...exp(x)-1
+ *
+ * Method :
+ * 1. reduce x to non-negative by tanh(-x) = - tanh(x).
+ * 2.
+ * 0 < x <= 1.e-10 : tanh(x) := x
+ * -expm1(-2x)
+ * 1.e-10 < x <= 1 : tanh(x) := --------------
+ * expm1(-2x) + 2
+ * 2
+ * 1 <= x <= 22.0 : tanh(x) := 1 - ---------------
+ * expm1(2x) + 2
+ * 22.0 < x <= INF : tanh(x) := 1.
+ *
+ * Note: 22 was chosen so that fl(1.0+2/(expm1(2*22)+2)) == 1.
+ *
+ * Special cases:
+ * tanh(NaN) is NaN;
+ * only tanh(0)=0 is exact for finite argument.
+ *
+ * Accuracy:
+ * tanh(x) returns the exact hyperbolic tangent of x nealy rounded.
+ * In a test run with 1,024,000 random arguments on a VAX, the maximum
+ * observed error was 2.22 ulps (units in the last place).
+ */
+
+double tanh(x)
+double x;
+{
+ static double one=1.0, two=2.0, small = 1.0e-10, big = 1.0e10;
+ double expm1(), t, copysign(), sign;
+ int finite();
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+
+ sign=copysign(one,x);
+ x=copysign(x,one);
+ if(x < 22.0)
+ if( x > one )
+ return(copysign(one-two/(expm1(x+x)+two),sign));
+ else if ( x > small )
+ {t= -expm1(-(x+x)); return(copysign(t/(two-t),sign));}
+ else /* raise the INEXACT flag for non-zero x */
+ {big+x; return(copysign(x,sign));}
+ else if(finite(x))
+ return (sign+1.0E-37); /* raise the INEXACT flag */
+ else
+ return(sign); /* x is +- INF */
+}
diff --git a/lib/libm/ieee/cabs.c b/lib/libm/ieee/cabs.c
new file mode 100644
index 0000000..5f1fc62
--- /dev/null
+++ b/lib/libm/ieee/cabs.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cabs.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* HYPOT(X,Y)
+ * RETURN THE SQUARE ROOT OF X^2 + Y^2 WHERE Z=X+iY
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 11/28/84;
+ * REVISED BY K.C. NG, 7/12/85.
+ *
+ * Required system supported functions :
+ * copysign(x,y)
+ * finite(x)
+ * scalb(x,N)
+ * sqrt(x)
+ *
+ * Method :
+ * 1. replace x by |x| and y by |y|, and swap x and
+ * y if y > x (hence x is never smaller than y).
+ * 2. Hypot(x,y) is computed by:
+ * Case I, x/y > 2
+ *
+ * y
+ * hypot = x + -----------------------------
+ * 2
+ * sqrt ( 1 + [x/y] ) + x/y
+ *
+ * Case II, x/y <= 2
+ * y
+ * hypot = x + --------------------------------------------------
+ * 2
+ * [x/y] - 2
+ * (sqrt(2)+1) + (x-y)/y + -----------------------------
+ * 2
+ * sqrt ( 1 + [x/y] ) + sqrt(2)
+ *
+ *
+ *
+ * Special cases:
+ * hypot(x,y) is INF if x or y is +INF or -INF; else
+ * hypot(x,y) is NAN if x or y is NAN.
+ *
+ * Accuracy:
+ * hypot(x,y) returns the sqrt(x^2+y^2) with error less than 1 ulps (units
+ * in the last place). See Kahan's "Interval Arithmetic Options in the
+ * Proposed IEEE Floating Point Arithmetic Standard", Interval Mathematics
+ * 1980, Edited by Karl L.E. Nickel, pp 99-128. (A faster but less accurate
+ * code follows in comments.) In a test run with 500,000 random arguments
+ * on a VAX, the maximum observed error was .959 ulps.
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+#include "mathimpl.h"
+
+vc(r2p1hi, 2.4142135623730950345E0 ,8279,411a,ef32,99fc, 2, .9A827999FCEF32)
+vc(r2p1lo, 1.4349369327986523769E-17 ,597d,2484,754b,89b3, -55, .84597D89B3754B)
+vc(sqrt2, 1.4142135623730950622E0 ,04f3,40b5,de65,33f9, 1, .B504F333F9DE65)
+
+ic(r2p1hi, 2.4142135623730949234E0 , 1, 1.3504F333F9DE6)
+ic(r2p1lo, 1.2537167179050217666E-16 , -53, 1.21165F626CDD5)
+ic(sqrt2, 1.4142135623730951455E0 , 0, 1.6A09E667F3BCD)
+
+#ifdef vccast
+#define r2p1hi vccast(r2p1hi)
+#define r2p1lo vccast(r2p1lo)
+#define sqrt2 vccast(sqrt2)
+#endif
+
+double
+hypot(x,y)
+double x, y;
+{
+ static const double zero=0, one=1,
+ small=1.0E-18; /* fl(1+small)==1 */
+ static const ibig=30; /* fl(1+2**(2*ibig))==1 */
+ double t,r;
+ int exp;
+
+ if(finite(x))
+ if(finite(y))
+ {
+ x=copysign(x,one);
+ y=copysign(y,one);
+ if(y > x)
+ { t=x; x=y; y=t; }
+ if(x == zero) return(zero);
+ if(y == zero) return(x);
+ exp= logb(x);
+ if(exp-(int)logb(y) > ibig )
+ /* raise inexact flag and return |x| */
+ { one+small; return(x); }
+
+ /* start computing sqrt(x^2 + y^2) */
+ r=x-y;
+ if(r>y) { /* x/y > 2 */
+ r=x/y;
+ r=r+sqrt(one+r*r); }
+ else { /* 1 <= x/y <= 2 */
+ r/=y; t=r*(r+2.0);
+ r+=t/(sqrt2+sqrt(2.0+t));
+ r+=r2p1lo; r+=r2p1hi; }
+
+ r=y/r;
+ return(x+r);
+
+ }
+
+ else if(y==y) /* y is +-INF */
+ return(copysign(y,one));
+ else
+ return(y); /* y is NaN and x is finite */
+
+ else if(x==x) /* x is +-INF */
+ return (copysign(x,one));
+ else if(finite(y))
+ return(x); /* x is NaN, y is finite */
+#if !defined(vax)&&!defined(tahoe)
+ else if(y!=y) return(y); /* x and y is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ else return(copysign(y,one)); /* y is INF */
+}
+
+/* CABS(Z)
+ * RETURN THE ABSOLUTE VALUE OF THE COMPLEX NUMBER Z = X + iY
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 11/28/84.
+ * REVISED BY K.C. NG, 7/12/85.
+ *
+ * Required kernel function :
+ * hypot(x,y)
+ *
+ * Method :
+ * cabs(z) = hypot(x,y) .
+ */
+
+struct complex { double x, y; };
+
+double
+cabs(z)
+struct complex z;
+{
+ return hypot(z.x,z.y);
+}
+
+double
+z_abs(z)
+struct complex *z;
+{
+ return hypot(z->x,z->y);
+}
+
+/* A faster but less accurate version of cabs(x,y) */
+#if 0
+double hypot(x,y)
+double x, y;
+{
+ static const double zero=0, one=1;
+ small=1.0E-18; /* fl(1+small)==1 */
+ static const ibig=30; /* fl(1+2**(2*ibig))==1 */
+ double temp;
+ int exp;
+
+ if(finite(x))
+ if(finite(y))
+ {
+ x=copysign(x,one);
+ y=copysign(y,one);
+ if(y > x)
+ { temp=x; x=y; y=temp; }
+ if(x == zero) return(zero);
+ if(y == zero) return(x);
+ exp= logb(x);
+ x=scalb(x,-exp);
+ if(exp-(int)logb(y) > ibig )
+ /* raise inexact flag and return |x| */
+ { one+small; return(scalb(x,exp)); }
+ else y=scalb(y,-exp);
+ return(scalb(sqrt(x*x+y*y),exp));
+ }
+
+ else if(y==y) /* y is +-INF */
+ return(copysign(y,one));
+ else
+ return(y); /* y is NaN and x is finite */
+
+ else if(x==x) /* x is +-INF */
+ return (copysign(x,one));
+ else if(finite(y))
+ return(x); /* x is NaN, y is finite */
+ else if(y!=y) return(y); /* x and y is NaN */
+ else return(copysign(y,one)); /* y is INF */
+}
+#endif
diff --git a/lib/libm/ieee/cbrt.c b/lib/libm/ieee/cbrt.c
new file mode 100644
index 0000000..6d73779
--- /dev/null
+++ b/lib/libm/ieee/cbrt.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cbrt.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/cdefs.h>
+
+/* kahan's cube root (53 bits IEEE double precision)
+ * for IEEE machines only
+ * coded in C by K.C. Ng, 4/30/85
+ *
+ * Accuracy:
+ * better than 0.667 ulps according to an error analysis. Maximum
+ * error observed was 0.666 ulps in an 1,000,000 random arguments test.
+ *
+ * Warning: this code is semi machine dependent; the ordering of words in
+ * a floating point number must be known in advance. I assume that the
+ * long interger at the address of a floating point number will be the
+ * leading 32 bits of that floating point number (i.e., sign, exponent,
+ * and the 20 most significant bits).
+ * On a National machine, it has different ordering; therefore, this code
+ * must be compiled with flag -DNATIONAL.
+ */
+#if !defined(vax)&&!defined(tahoe)
+
+static const unsigned long
+ B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
+ B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
+static const double
+ C= 19./35.,
+ D= -864./1225.,
+ E= 99./70.,
+ F= 45./28.,
+ G= 5./14.;
+
+double cbrt(x)
+double x;
+{
+ double r,s,t=0.0,w;
+ unsigned long *px = (unsigned long *) &x,
+ *pt = (unsigned long *) &t,
+ mexp,sign;
+
+#ifdef national /* ordering of words in a floating points number */
+ const int n0=1,n1=0;
+#else /* national */
+ const int n0=0,n1=1;
+#endif /* national */
+
+ mexp=px[n0]&0x7ff00000;
+ if(mexp==0x7ff00000) return(x); /* cbrt(NaN,INF) is itself */
+ if(x==0.0) return(x); /* cbrt(0) is itself */
+
+ sign=px[n0]&0x80000000; /* sign= sign(x) */
+ px[n0] ^= sign; /* x=|x| */
+
+
+ /* rough cbrt to 5 bits */
+ if(mexp==0) /* subnormal number */
+ {pt[n0]=0x43500000; /* set t= 2**54 */
+ t*=x; pt[n0]=pt[n0]/3+B2;
+ }
+ else
+ pt[n0]=px[n0]/3+B1;
+
+
+ /* new cbrt to 23 bits, may be implemented in single precision */
+ r=t*t/x;
+ s=C+r*t;
+ t*=G+F/(s+E+D/s);
+
+ /* chopped to 20 bits and make it larger than cbrt(x) */
+ pt[n1]=0; pt[n0]+=0x00000001;
+
+
+ /* one step newton iteration to 53 bits with error less than 0.667 ulps */
+ s=t*t; /* t*t is exact */
+ r=x/s;
+ w=t+t;
+ r=(r-t)/(w+r); /* r-t is exact */
+ t=t+t*r;
+
+
+ /* retore the sign bit */
+ pt[n0] |= sign;
+ return(t);
+}
+#endif
diff --git a/lib/libm/ieee/support.c b/lib/libm/ieee/support.c
new file mode 100644
index 0000000..0ae10bb
--- /dev/null
+++ b/lib/libm/ieee/support.c
@@ -0,0 +1,524 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)support.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * Some IEEE standard 754 recommended functions and remainder and sqrt for
+ * supporting the C elementary functions.
+ ******************************************************************************
+ * WARNING:
+ * These codes are developed (in double) to support the C elementary
+ * functions temporarily. They are not universal, and some of them are very
+ * slow (in particular, drem and sqrt is extremely inefficient). Each
+ * computer system should have its implementation of these functions using
+ * its own assembler.
+ ******************************************************************************
+ *
+ * IEEE 754 required operations:
+ * drem(x,p)
+ * returns x REM y = x - [x/y]*y , where [x/y] is the integer
+ * nearest x/y; in half way case, choose the even one.
+ * sqrt(x)
+ * returns the square root of x correctly rounded according to
+ * the rounding mod.
+ *
+ * IEEE 754 recommended functions:
+ * (a) copysign(x,y)
+ * returns x with the sign of y.
+ * (b) scalb(x,N)
+ * returns x * (2**N), for integer values N.
+ * (c) logb(x)
+ * returns the unbiased exponent of x, a signed integer in
+ * double precision, except that logb(0) is -INF, logb(INF)
+ * is +INF, and logb(NAN) is that NAN.
+ * (d) finite(x)
+ * returns the value TRUE if -INF < x < +INF and returns
+ * FALSE otherwise.
+ *
+ *
+ * CODED IN C BY K.C. NG, 11/25/84;
+ * REVISED BY K.C. NG on 1/22/85, 2/13/85, 3/24/85.
+ */
+
+#include "mathimpl.h"
+
+#if defined(vax)||defined(tahoe) /* VAX D format */
+#include <errno.h>
+ static const unsigned short msign=0x7fff , mexp =0x7f80 ;
+ static const short prep1=57, gap=7, bias=129 ;
+ static const double novf=1.7E38, nunf=3.0E-39, zero=0.0 ;
+#else /* defined(vax)||defined(tahoe) */
+ static const unsigned short msign=0x7fff, mexp =0x7ff0 ;
+ static const short prep1=54, gap=4, bias=1023 ;
+ static const double novf=1.7E308, nunf=3.0E-308,zero=0.0;
+#endif /* defined(vax)||defined(tahoe) */
+
+double scalb(x,N)
+double x; int N;
+{
+ int k;
+
+#ifdef national
+ unsigned short *px=(unsigned short *) &x + 3;
+#else /* national */
+ unsigned short *px=(unsigned short *) &x;
+#endif /* national */
+
+ if( x == zero ) return(x);
+
+#if defined(vax)||defined(tahoe)
+ if( (k= *px & mexp ) != ~msign ) {
+ if (N < -260)
+ return(nunf*nunf);
+ else if (N > 260) {
+ return(copysign(infnan(ERANGE),x));
+ }
+#else /* defined(vax)||defined(tahoe) */
+ if( (k= *px & mexp ) != mexp ) {
+ if( N<-2100) return(nunf*nunf); else if(N>2100) return(novf+novf);
+ if( k == 0 ) {
+ x *= scalb(1.0,(int)prep1); N -= prep1; return(scalb(x,N));}
+#endif /* defined(vax)||defined(tahoe) */
+
+ if((k = (k>>gap)+ N) > 0 )
+ if( k < (mexp>>gap) ) *px = (*px&~mexp) | (k<<gap);
+ else x=novf+novf; /* overflow */
+ else
+ if( k > -prep1 )
+ /* gradual underflow */
+ {*px=(*px&~mexp)|(short)(1<<gap); x *= scalb(1.0,k-1);}
+ else
+ return(nunf*nunf);
+ }
+ return(x);
+}
+
+
+double copysign(x,y)
+double x,y;
+{
+#ifdef national
+ unsigned short *px=(unsigned short *) &x+3,
+ *py=(unsigned short *) &y+3;
+#else /* national */
+ unsigned short *px=(unsigned short *) &x,
+ *py=(unsigned short *) &y;
+#endif /* national */
+
+#if defined(vax)||defined(tahoe)
+ if ( (*px & mexp) == 0 ) return(x);
+#endif /* defined(vax)||defined(tahoe) */
+
+ *px = ( *px & msign ) | ( *py & ~msign );
+ return(x);
+}
+
+double logb(x)
+double x;
+{
+
+#ifdef national
+ short *px=(short *) &x+3, k;
+#else /* national */
+ short *px=(short *) &x, k;
+#endif /* national */
+
+#if defined(vax)||defined(tahoe)
+ return (int)(((*px&mexp)>>gap)-bias);
+#else /* defined(vax)||defined(tahoe) */
+ if( (k= *px & mexp ) != mexp )
+ if ( k != 0 )
+ return ( (k>>gap) - bias );
+ else if( x != zero)
+ return ( -1022.0 );
+ else
+ return(-(1.0/zero));
+ else if(x != x)
+ return(x);
+ else
+ {*px &= msign; return(x);}
+#endif /* defined(vax)||defined(tahoe) */
+}
+
+finite(x)
+double x;
+{
+#if defined(vax)||defined(tahoe)
+ return(1);
+#else /* defined(vax)||defined(tahoe) */
+#ifdef national
+ return( (*((short *) &x+3 ) & mexp ) != mexp );
+#else /* national */
+ return( (*((short *) &x ) & mexp ) != mexp );
+#endif /* national */
+#endif /* defined(vax)||defined(tahoe) */
+}
+
+double drem(x,p)
+double x,p;
+{
+ short sign;
+ double hp,dp,tmp;
+ unsigned short k;
+#ifdef national
+ unsigned short
+ *px=(unsigned short *) &x +3,
+ *pp=(unsigned short *) &p +3,
+ *pd=(unsigned short *) &dp +3,
+ *pt=(unsigned short *) &tmp+3;
+#else /* national */
+ unsigned short
+ *px=(unsigned short *) &x ,
+ *pp=(unsigned short *) &p ,
+ *pd=(unsigned short *) &dp ,
+ *pt=(unsigned short *) &tmp;
+#endif /* national */
+
+ *pp &= msign ;
+
+#if defined(vax)||defined(tahoe)
+ if( ( *px & mexp ) == ~msign ) /* is x a reserved operand? */
+#else /* defined(vax)||defined(tahoe) */
+ if( ( *px & mexp ) == mexp )
+#endif /* defined(vax)||defined(tahoe) */
+ return (x-p)-(x-p); /* create nan if x is inf */
+ if (p == zero) {
+#if defined(vax)||defined(tahoe)
+ return(infnan(EDOM));
+#else /* defined(vax)||defined(tahoe) */
+ return zero/zero;
+#endif /* defined(vax)||defined(tahoe) */
+ }
+
+#if defined(vax)||defined(tahoe)
+ if( ( *pp & mexp ) == ~msign ) /* is p a reserved operand? */
+#else /* defined(vax)||defined(tahoe) */
+ if( ( *pp & mexp ) == mexp )
+#endif /* defined(vax)||defined(tahoe) */
+ { if (p != p) return p; else return x;}
+
+ else if ( ((*pp & mexp)>>gap) <= 1 )
+ /* subnormal p, or almost subnormal p */
+ { double b; b=scalb(1.0,(int)prep1);
+ p *= b; x = drem(x,p); x *= b; return(drem(x,p)/b);}
+ else if ( p >= novf/2)
+ { p /= 2 ; x /= 2; return(drem(x,p)*2);}
+ else
+ {
+ dp=p+p; hp=p/2;
+ sign= *px & ~msign ;
+ *px &= msign ;
+ while ( x > dp )
+ {
+ k=(*px & mexp) - (*pd & mexp) ;
+ tmp = dp ;
+ *pt += k ;
+
+#if defined(vax)||defined(tahoe)
+ if( x < tmp ) *pt -= 128 ;
+#else /* defined(vax)||defined(tahoe) */
+ if( x < tmp ) *pt -= 16 ;
+#endif /* defined(vax)||defined(tahoe) */
+
+ x -= tmp ;
+ }
+ if ( x > hp )
+ { x -= p ; if ( x >= hp ) x -= p ; }
+
+#if defined(vax)||defined(tahoe)
+ if (x)
+#endif /* defined(vax)||defined(tahoe) */
+ *px ^= sign;
+ return( x);
+
+ }
+}
+
+
+double sqrt(x)
+double x;
+{
+ double q,s,b,r;
+ double t;
+ double const zero=0.0;
+ int m,n,i;
+#if defined(vax)||defined(tahoe)
+ int k=54;
+#else /* defined(vax)||defined(tahoe) */
+ int k=51;
+#endif /* defined(vax)||defined(tahoe) */
+
+ /* sqrt(NaN) is NaN, sqrt(+-0) = +-0 */
+ if(x!=x||x==zero) return(x);
+
+ /* sqrt(negative) is invalid */
+ if(x<zero) {
+#if defined(vax)||defined(tahoe)
+ return (infnan(EDOM)); /* NaN */
+#else /* defined(vax)||defined(tahoe) */
+ return(zero/zero);
+#endif /* defined(vax)||defined(tahoe) */
+ }
+
+ /* sqrt(INF) is INF */
+ if(!finite(x)) return(x);
+
+ /* scale x to [1,4) */
+ n=logb(x);
+ x=scalb(x,-n);
+ if((m=logb(x))!=0) x=scalb(x,-m); /* subnormal number */
+ m += n;
+ n = m/2;
+ if((n+n)!=m) {x *= 2; m -=1; n=m/2;}
+
+ /* generate sqrt(x) bit by bit (accumulating in q) */
+ q=1.0; s=4.0; x -= 1.0; r=1;
+ for(i=1;i<=k;i++) {
+ t=s+1; x *= 4; r /= 2;
+ if(t<=x) {
+ s=t+t+2, x -= t; q += r;}
+ else
+ s *= 2;
+ }
+
+ /* generate the last bit and determine the final rounding */
+ r/=2; x *= 4;
+ if(x==zero) goto end; 100+r; /* trigger inexact flag */
+ if(s<x) {
+ q+=r; x -=s; s += 2; s *= 2; x *= 4;
+ t = (x-s)-5;
+ b=1.0+3*r/4; if(b==1.0) goto end; /* b==1 : Round-to-zero */
+ b=1.0+r/4; if(b>1.0) t=1; /* b>1 : Round-to-(+INF) */
+ if(t>=0) q+=r; } /* else: Round-to-nearest */
+ else {
+ s *= 2; x *= 4;
+ t = (x-s)-1;
+ b=1.0+3*r/4; if(b==1.0) goto end;
+ b=1.0+r/4; if(b>1.0) t=1;
+ if(t>=0) q+=r; }
+
+end: return(scalb(q,n));
+}
+
+#if 0
+/* DREM(X,Y)
+ * RETURN X REM Y =X-N*Y, N=[X/Y] ROUNDED (ROUNDED TO EVEN IN THE HALF WAY CASE)
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * INTENDED FOR ASSEMBLY LANGUAGE
+ * CODED IN C BY K.C. NG, 3/23/85, 4/8/85.
+ *
+ * Warning: this code should not get compiled in unless ALL of
+ * the following machine-dependent routines are supplied.
+ *
+ * Required machine dependent functions (not on a VAX):
+ * swapINX(i): save inexact flag and reset it to "i"
+ * swapENI(e): save inexact enable and reset it to "e"
+ */
+
+double drem(x,y)
+double x,y;
+{
+
+#ifdef national /* order of words in floating point number */
+ static const n0=3,n1=2,n2=1,n3=0;
+#else /* VAX, SUN, ZILOG, TAHOE */
+ static const n0=0,n1=1,n2=2,n3=3;
+#endif
+
+ static const unsigned short mexp =0x7ff0, m25 =0x0190, m57 =0x0390;
+ static const double zero=0.0;
+ double hy,y1,t,t1;
+ short k;
+ long n;
+ int i,e;
+ unsigned short xexp,yexp, *px =(unsigned short *) &x ,
+ nx,nf, *py =(unsigned short *) &y ,
+ sign, *pt =(unsigned short *) &t ,
+ *pt1 =(unsigned short *) &t1 ;
+
+ xexp = px[n0] & mexp ; /* exponent of x */
+ yexp = py[n0] & mexp ; /* exponent of y */
+ sign = px[n0] &0x8000; /* sign of x */
+
+/* return NaN if x is NaN, or y is NaN, or x is INF, or y is zero */
+ if(x!=x) return(x); if(y!=y) return(y); /* x or y is NaN */
+ if( xexp == mexp ) return(zero/zero); /* x is INF */
+ if(y==zero) return(y/y);
+
+/* save the inexact flag and inexact enable in i and e respectively
+ * and reset them to zero
+ */
+ i=swapINX(0); e=swapENI(0);
+
+/* subnormal number */
+ nx=0;
+ if(yexp==0) {t=1.0,pt[n0]+=m57; y*=t; nx=m57;}
+
+/* if y is tiny (biased exponent <= 57), scale up y to y*2**57 */
+ if( yexp <= m57 ) {py[n0]+=m57; nx+=m57; yexp+=m57;}
+
+ nf=nx;
+ py[n0] &= 0x7fff;
+ px[n0] &= 0x7fff;
+
+/* mask off the least significant 27 bits of y */
+ t=y; pt[n3]=0; pt[n2]&=0xf800; y1=t;
+
+/* LOOP: argument reduction on x whenever x > y */
+loop:
+ while ( x > y )
+ {
+ t=y;
+ t1=y1;
+ xexp=px[n0]&mexp; /* exponent of x */
+ k=xexp-yexp-m25;
+ if(k>0) /* if x/y >= 2**26, scale up y so that x/y < 2**26 */
+ {pt[n0]+=k;pt1[n0]+=k;}
+ n=x/t; x=(x-n*t1)-n*(t-t1);
+ }
+ /* end while (x > y) */
+
+ if(nx!=0) {t=1.0; pt[n0]+=nx; x*=t; nx=0; goto loop;}
+
+/* final adjustment */
+
+ hy=y/2.0;
+ if(x>hy||((x==hy)&&n%2==1)) x-=y;
+ px[n0] ^= sign;
+ if(nf!=0) { t=1.0; pt[n0]-=nf; x*=t;}
+
+/* restore inexact flag and inexact enable */
+ swapINX(i); swapENI(e);
+
+ return(x);
+}
+#endif
+
+#if 0
+/* SQRT
+ * RETURN CORRECTLY ROUNDED (ACCORDING TO THE ROUNDING MODE) SQRT
+ * FOR IEEE DOUBLE PRECISION ONLY, INTENDED FOR ASSEMBLY LANGUAGE
+ * CODED IN C BY K.C. NG, 3/22/85.
+ *
+ * Warning: this code should not get compiled in unless ALL of
+ * the following machine-dependent routines are supplied.
+ *
+ * Required machine dependent functions:
+ * swapINX(i) ...return the status of INEXACT flag and reset it to "i"
+ * swapRM(r) ...return the current Rounding Mode and reset it to "r"
+ * swapENI(e) ...return the status of inexact enable and reset it to "e"
+ * addc(t) ...perform t=t+1 regarding t as a 64 bit unsigned integer
+ * subc(t) ...perform t=t-1 regarding t as a 64 bit unsigned integer
+ */
+
+static const unsigned long table[] = {
+0, 1204, 3062, 5746, 9193, 13348, 18162, 23592, 29598, 36145, 43202, 50740,
+58733, 67158, 75992, 85215, 83599, 71378, 60428, 50647, 41945, 34246, 27478,
+21581, 16499, 12183, 8588, 5674, 3403, 1742, 661, 130, };
+
+double newsqrt(x)
+double x;
+{
+ double y,z,t,addc(),subc()
+ double const b54=134217728.*134217728.; /* b54=2**54 */
+ long mx,scalx;
+ long const mexp=0x7ff00000;
+ int i,j,r,e,swapINX(),swapRM(),swapENI();
+ unsigned long *py=(unsigned long *) &y ,
+ *pt=(unsigned long *) &t ,
+ *px=(unsigned long *) &x ;
+#ifdef national /* ordering of word in a floating point number */
+ const int n0=1, n1=0;
+#else
+ const int n0=0, n1=1;
+#endif
+/* Rounding Mode: RN ...round-to-nearest
+ * RZ ...round-towards 0
+ * RP ...round-towards +INF
+ * RM ...round-towards -INF
+ */
+ const int RN=0,RZ=1,RP=2,RM=3;
+ /* machine dependent: work on a Zilog Z8070
+ * and a National 32081 & 16081
+ */
+
+/* exceptions */
+ if(x!=x||x==0.0) return(x); /* sqrt(NaN) is NaN, sqrt(+-0) = +-0 */
+ if(x<0) return((x-x)/(x-x)); /* sqrt(negative) is invalid */
+ if((mx=px[n0]&mexp)==mexp) return(x); /* sqrt(+INF) is +INF */
+
+/* save, reset, initialize */
+ e=swapENI(0); /* ...save and reset the inexact enable */
+ i=swapINX(0); /* ...save INEXACT flag */
+ r=swapRM(RN); /* ...save and reset the Rounding Mode to RN */
+ scalx=0;
+
+/* subnormal number, scale up x to x*2**54 */
+ if(mx==0) {x *= b54 ; scalx-=0x01b00000;}
+
+/* scale x to avoid intermediate over/underflow:
+ * if (x > 2**512) x=x/2**512; if (x < 2**-512) x=x*2**512 */
+ if(mx>0x5ff00000) {px[n0] -= 0x20000000; scalx+= 0x10000000;}
+ if(mx<0x1ff00000) {px[n0] += 0x20000000; scalx-= 0x10000000;}
+
+/* magic initial approximation to almost 8 sig. bits */
+ py[n0]=(px[n0]>>1)+0x1ff80000;
+ py[n0]=py[n0]-table[(py[n0]>>15)&31];
+
+/* Heron's rule once with correction to improve y to almost 18 sig. bits */
+ t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0;
+
+/* triple to almost 56 sig. bits; now y approx. sqrt(x) to within 1 ulp */
+ t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y;
+ t=z/(t+x) ; pt[n0]+=0x00100000; y+=t;
+
+/* twiddle last bit to force y correctly rounded */
+ swapRM(RZ); /* ...set Rounding Mode to round-toward-zero */
+ swapINX(0); /* ...clear INEXACT flag */
+ swapENI(e); /* ...restore inexact enable status */
+ t=x/y; /* ...chopped quotient, possibly inexact */
+ j=swapINX(i); /* ...read and restore inexact flag */
+ if(j==0) { if(t==y) goto end; else t=subc(t); } /* ...t=t-ulp */
+ b54+0.1; /* ..trigger inexact flag, sqrt(x) is inexact */
+ if(r==RN) t=addc(t); /* ...t=t+ulp */
+ else if(r==RP) { t=addc(t);y=addc(y);}/* ...t=t+ulp;y=y+ulp; */
+ y=y+t; /* ...chopped sum */
+ py[n0]=py[n0]-0x00100000; /* ...correctly rounded sqrt(x) */
+end: py[n0]=py[n0]+scalx; /* ...scale back y */
+ swapRM(r); /* ...restore Rounding Mode */
+ return(y);
+}
+#endif
diff --git a/lib/libmd/Makefile b/lib/libmd/Makefile
new file mode 100644
index 0000000..3264f0a
--- /dev/null
+++ b/lib/libmd/Makefile
@@ -0,0 +1,180 @@
+# $FreeBSD$
+
+LIB= md
+SRCS= md2c.c md4c.c md5c.c md2hl.c md4hl.c md5hl.c \
+ rmd160c.c rmd160hl.c \
+ sha0c.c sha0hl.c sha1c.c sha1hl.c
+MAN3+= md2.3 md4.3 md5.3 ripemd.3 sha.3
+MLINKS+=md2.3 MD2Init.3 md2.3 MD2Update.3 md2.3 MD2Final.3
+MLINKS+=md2.3 MD2End.3 md2.3 MD2File.3 md2.3 MD2Data.3
+MLINKS+=md4.3 MD4Init.3 md4.3 MD4Update.3 md4.3 MD4Final.3
+MLINKS+=md4.3 MD4End.3 md4.3 MD4File.3 md4.3 MD4Data.3
+MLINKS+=md5.3 MD5Init.3 md5.3 MD5Update.3 md5.3 MD5Final.3
+MLINKS+=md5.3 MD5End.3 md5.3 MD5File.3 md5.3 MD5Data.3
+MLINKS+=ripemd.3 RIPEMD160_Init.3 ripemd.3 RIPEMD160_Update.3
+MLINKS+=ripemd.3 RIPEMD160_Final.3 ripemd.3 RIPEMD160_Data.3
+MLINKS+=ripemd.3 RIPEMD160_End.3 ripemd.3 RIPEMD160_File.3
+MLINKS+=sha.3 SHA_Init.3 sha.3 SHA_Update.3 sha.3 SHA_Final.3
+MLINKS+=sha.3 SHA_End.3 sha.3 SHA_File.3 sha.3 SHA_Data.3
+MLINKS+=sha.3 SHA1_Init.3 sha.3 SHA1_Update.3 sha.3 SHA1_Final.3
+MLINKS+=sha.3 SHA1_End.3 sha.3 SHA1_File.3 sha.3 SHA1_Data.3
+CLEANFILES+= md[245]hl.c md[245].ref md[245].3 mddriver \
+ rmd160.ref rmd160hl.c rmddriver \
+ sha0.ref sha0hl.c sha1.ref sha1hl.c shadriver
+CFLAGS+= -I${.CURDIR}
+.PATH: ${.CURDIR}/${MACHINE_ARCH}
+
+.if ${OBJFORMAT} == "elf"
+.if exists(${MACHINE_ARCH}/sha.S)
+SRCS+= sha.S
+CFLAGS+= -DSHA1_ASM -DELF
+.endif
+.if exists(${MACHINE_ARCH}/rmd160.S)
+SRCS+= rmd160.S
+CFLAGS+= -DRMD160_ASM -DELF
+.endif
+.endif
+
+all: md2.3 md4.3 md5.3
+
+md2hl.c: mdXhl.c
+ (echo '#define LENGTH 16'; \
+ sed -e 's/mdX/md2/g' -e 's/MDX/MD2/g' ${.ALLSRC}) > ${.TARGET}
+
+md4hl.c: mdXhl.c
+ (echo '#define LENGTH 16'; \
+ sed -e 's/mdX/md4/g' -e 's/MDX/MD4/g' ${.ALLSRC}) > ${.TARGET}
+
+md5hl.c: mdXhl.c
+ (echo '#define LENGTH 16'; \
+ sed -e 's/mdX/md5/g' -e 's/MDX/MD5/g' ${.ALLSRC}) > ${.TARGET}
+
+sha0hl.c: mdXhl.c
+ (echo '#define LENGTH 20'; \
+ sed -e 's/mdX/sha/g' -e 's/MDX/SHA_/g' -e 's/SHA__/SHA_/g' \
+ ${.ALLSRC}) > ${.TARGET}
+
+sha1hl.c: mdXhl.c
+ (echo '#define LENGTH 20'; \
+ sed -e 's/mdX/sha/g' -e 's/MDX/SHA1_/g' -e 's/SHA1__/SHA1_/g' \
+ ${.ALLSRC}) > ${.TARGET}
+
+rmd160hl.c: mdXhl.c
+ (echo '#define LENGTH 20'; \
+ sed -e 's/mdX/ripemd/g' -e 's/MDX/RIPEMD160_/g' \
+ -e 's/RIPEMD160__/RIPEMD160_/g' \
+ ${.ALLSRC}) > ${.TARGET}
+
+md2.3: ${.CURDIR}/mdX.3
+ sed -e 's/mdX/md2/g' -e 's/MDX/MD2/g' ${.ALLSRC} > ${.TARGET}
+ cat ${.CURDIR}/md2.copyright >> ${.TARGET}
+
+md4.3: ${.CURDIR}/mdX.3
+ sed -e 's/mdX/md4/g' -e 's/MDX/MD4/g' ${.ALLSRC} > ${.TARGET}
+ cat ${.CURDIR}/md4.copyright >> ${.TARGET}
+
+md5.3: ${.CURDIR}/mdX.3
+ sed -e 's/mdX/md5/g' -e 's/MDX/MD5/g' ${.ALLSRC} > ${.TARGET}
+ cat ${.CURDIR}/md5.copyright >> ${.TARGET}
+
+md2.ref:
+ echo 'MD2 test suite:' > ${.TARGET}
+ @echo 'MD2 ("") = 8350e5a3e24c153df2275c9f80692773' >> ${.TARGET}
+ @echo 'MD2 ("a") = 32ec01ec4a6dac72c0ab96fb34c0b5d1' >> ${.TARGET}
+ @echo 'MD2 ("abc") = da853b0d3f88d99b30283a69e6ded6bb' >> ${.TARGET}
+ @echo 'MD2 ("message digest") = ab4f496bfb2a530b219ff33031fe06b0' >> ${.TARGET}
+ @echo 'MD2 ("abcdefghijklmnopqrstuvwxyz") = 4e8ddff3650292ab5a4108c3aa47940b' >> ${.TARGET}
+ @echo 'MD2 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = da33def2a42df13975352846c30338cd' >> ${.TARGET}
+ @echo 'MD2 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = d5976f79d83d3a0dc9806c3c66f3efd8' >> ${.TARGET}
+
+md4.ref:
+ echo 'MD4 test suite:' > ${.TARGET}
+ @echo 'MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0' >> ${.TARGET}
+ @echo 'MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24' >> ${.TARGET}
+ @echo 'MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d' >> ${.TARGET}
+ @echo 'MD4 ("message digest") = d9130a8164549fe818874806e1c7014b' >> ${.TARGET}
+ @echo 'MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9' >> ${.TARGET}
+ @echo 'MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = 043f8582f241db351ce627e153e7f0e4' >> ${.TARGET}
+ @echo 'MD4 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536' >> ${.TARGET}
+
+md5.ref:
+ echo 'MD5 test suite:' > ${.TARGET}
+ @echo 'MD5 ("") = d41d8cd98f00b204e9800998ecf8427e' >> ${.TARGET}
+ @echo 'MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661' >> ${.TARGET}
+ @echo 'MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72' >> ${.TARGET}
+ @echo 'MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0' >> ${.TARGET}
+ @echo 'MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b' >> ${.TARGET}
+ @echo 'MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f' >> ${.TARGET}
+ @echo 'MD5 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a' >> ${.TARGET}
+
+sha0.ref:
+ (echo 'SHA-0 test suite:'; \
+ echo 'SHA-0 ("") = f96cea198ad1dd5617ac084a3d92c6107708c0ef'; \
+ echo 'SHA-0 ("abc") = 0164b8a914cd2a5e74c4f7ff082c4d97f1edf880'; \
+ echo 'SHA-0 ("message digest") =' \
+ 'c1b0f222d150ebb9aa36a40cafdc8bcbed830b14'; \
+ echo 'SHA-0 ("abcdefghijklmnopqrstuvwxyz") =' \
+ 'b40ce07a430cfd3c033039b9fe9afec95dc1bdcd'; \
+ echo 'SHA-0 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =' \
+ '79e966f7a3a990df33e40e3d7f8f18d2caebadfa'; \
+ echo 'SHA-0 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") =' \
+ '4aa29d14d171522ece47bee8957e35a41f3e9cff' ) > ${.TARGET}
+
+sha1.ref:
+ (echo 'SHA-1 test suite:'; \
+ echo 'SHA-1 ("") = da39a3ee5e6b4b0d3255bfef95601890afd80709'; \
+ echo 'SHA-1 ("abc") = a9993e364706816aba3e25717850c26c9cd0d89d'; \
+ echo 'SHA-1 ("message digest") =' \
+ 'c12252ceda8be8994d5fa0290a47231c1d16aae3'; \
+ echo 'SHA-1 ("abcdefghijklmnopqrstuvwxyz") =' \
+ '32d10c7b8cf96570ca04ce37f2a19d84240d3a89'; \
+ echo 'SHA-1 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =' \
+ '761c457bf73b14d27e9e9265c46f4b4dda11f940'; \
+ echo 'SHA-1 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") =' \
+ '50abf5706a150990a08b2c5ea40fa0e585554732' ) > ${.TARGET}
+
+rmd160.ref:
+ (echo 'RIPEMD160 test suite:'; \
+ echo 'RIPEMD160 ("") = 9c1185a5c5e9fc54612808977ee8f548b2258d31'; \
+ echo 'RIPEMD160 ("abc") = 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc'; \
+ echo 'RIPEMD160 ("message digest") =' \
+ '5d0689ef49d2fae572b881b123a85ffa21595f36'; \
+ echo 'RIPEMD160 ("abcdefghijklmnopqrstuvwxyz") =' \
+ 'f71c27109c692c1b56bbdceb5b9d2865b3708dbc'; \
+ echo 'RIPEMD160 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =' \
+ 'b0e20b6e3116640286ed3a87a5713079b21f5189'; \
+ echo 'RIPEMD160 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") =' \
+ '9b752e45573d4b39f4dbd3323cab82bf63326bfb' ) > ${.TARGET}
+
+test: md2.ref md4.ref md5.ref sha0.ref rmd160.ref sha1.ref
+ @${ECHO} if any of these test fail, the code produces wrong results
+ @${ECHO} and should NOT be used.
+ ${CC} -static ${CFLAGS} ${LDFLAGS} -DMD=2 -o mddriver ${.CURDIR}/mddriver.c -L. -lmd
+ ./mddriver | cmp md2.ref -
+ @${ECHO} MD2 passed test
+ ${CC} -static ${CFLAGS} ${LDFLAGS} -DMD=4 -o mddriver ${.CURDIR}/mddriver.c -L. -lmd
+ ./mddriver | cmp md4.ref -
+ @${ECHO} MD4 passed test
+ ${CC} -static ${CFLAGS} ${LDFLAGS} -DMD=5 -o mddriver ${.CURDIR}/mddriver.c -L. -lmd
+ ./mddriver | cmp md5.ref -
+ @${ECHO} MD5 passed test
+ -rm -f mddriver
+ ${CC} -static ${CFLAGS} ${LDFLAGS} -o rmddriver ${.CURDIR}/rmddriver.c -L. -lmd
+ ./rmddriver | cmp rmd160.ref -
+ @${ECHO} RIPEMD160 passed test
+ -rm -f rmddriver
+ ${CC} -static ${CFLAGS} ${LDFLAGS} -DSHA=0 -o shadriver ${.CURDIR}/shadriver.c -L. -lmd
+ ./shadriver | cmp sha0.ref -
+ @${ECHO} SHA-0 passed test
+ ${CC} -static ${CFLAGS} ${LDFLAGS} -DSHA=1 -o shadriver ${.CURDIR}/shadriver.c -L. -lmd
+ ./shadriver | cmp sha1.ref -
+ @${ECHO} SHA-1 passed test
+ -rm -f shadriver
+
+beforeinstall:
+.for i in md2.h md4.h md5.h ripemd.h sha.h
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/$i \
+ ${DESTDIR}/usr/include
+.endfor
+
+.include <bsd.lib.mk>
diff --git a/lib/libmd/i386/rmd160.S b/lib/libmd/i386/rmd160.S
new file mode 100644
index 0000000..97193e9
--- /dev/null
+++ b/lib/libmd/i386/rmd160.S
@@ -0,0 +1,2018 @@
+/* Run the C pre-processor over this file with one of the following defined
+ * ELF - elf object files,
+ * OUT - a.out object files,
+ * BSDI - BSDI style a.out object files
+ * SOL - Solaris style elf
+ */
+
+#ifndef PIC
+#define TYPE(a,b) .type a,b
+#define SIZE(a,b) .size a,b
+
+#if defined(OUT) || defined(BSDI)
+#define ripemd160_block_x86 _ripemd160_block_x86
+
+#endif
+
+#ifdef OUT
+#define OK 1
+#define ALIGN 4
+#endif
+
+#ifdef BSDI
+#define OK 1
+#define ALIGN 4
+#undef SIZE
+#undef TYPE
+#define SIZE(a,b)
+#define TYPE(a,b)
+#endif
+
+#if defined(ELF) || defined(SOL)
+#define OK 1
+#define ALIGN 4
+#endif
+
+#ifndef OK
+You need to define one of
+ELF - elf systems - linux-elf, NetBSD and DG-UX
+OUT - a.out systems - linux-a.out and FreeBSD
+SOL - solaris systems, which are elf with strange comment lines
+BSDI - a.out with a very primative version of as.
+#endif
+
+/* Let the Assembler begin :-) */
+ /* Don't even think of reading this code */
+ /* It was automatically generated by rmd-586.pl */
+ /* Which is a perl program used to generate the x86 assember for */
+ /* any of elf, a.out, BSDI,Win32, or Solaris */
+ /* eric <eay@cryptsoft.com> */
+
+ .file "rmd-586.s"
+ .version "01.01"
+gcc2_compiled.:
+.text
+ .p2align ALIGN
+.globl ripemd160_block_x86
+ TYPE(ripemd160_block_x86,@function)
+ripemd160_block_x86:
+ pushl %esi
+ movl 16(%esp), %ecx
+ pushl %edi
+ movl 16(%esp), %esi
+ pushl %ebp
+ addl %esi, %ecx
+ pushl %ebx
+ subl $64, %ecx
+ subl $88, %esp
+ movl %ecx, (%esp)
+ movl 108(%esp), %edi
+.L000start:
+
+ movl (%esi), %eax
+ movl 4(%esi), %ebx
+ movl %eax, 4(%esp)
+ movl %ebx, 8(%esp)
+ movl 8(%esi), %eax
+ movl 12(%esi), %ebx
+ movl %eax, 12(%esp)
+ movl %ebx, 16(%esp)
+ movl 16(%esi), %eax
+ movl 20(%esi), %ebx
+ movl %eax, 20(%esp)
+ movl %ebx, 24(%esp)
+ movl 24(%esi), %eax
+ movl 28(%esi), %ebx
+ movl %eax, 28(%esp)
+ movl %ebx, 32(%esp)
+ movl 32(%esi), %eax
+ movl 36(%esi), %ebx
+ movl %eax, 36(%esp)
+ movl %ebx, 40(%esp)
+ movl 40(%esi), %eax
+ movl 44(%esi), %ebx
+ movl %eax, 44(%esp)
+ movl %ebx, 48(%esp)
+ movl 48(%esi), %eax
+ movl 52(%esi), %ebx
+ movl %eax, 52(%esp)
+ movl %ebx, 56(%esp)
+ movl 56(%esi), %eax
+ movl 60(%esi), %ebx
+ movl %eax, 60(%esp)
+ movl %ebx, 64(%esp)
+ addl $64, %esi
+ movl (%edi), %eax
+ movl %esi, 112(%esp)
+ movl 4(%edi), %ebx
+ movl 8(%edi), %ecx
+ movl 12(%edi), %edx
+ movl 16(%edi), %ebp
+ /* 0 */
+ movl %ecx, %esi
+ xorl %edx, %esi
+ movl 4(%esp), %edi
+ xorl %ebx, %esi
+ addl %edi, %eax
+ roll $10, %ecx
+ addl %esi, %eax
+ movl %ebx, %esi
+ roll $11, %eax
+ addl %ebp, %eax
+ /* 1 */
+ xorl %ecx, %esi
+ movl 8(%esp), %edi
+ xorl %eax, %esi
+ addl %esi, %ebp
+ movl %eax, %esi
+ roll $10, %ebx
+ addl %edi, %ebp
+ xorl %ebx, %esi
+ roll $14, %ebp
+ addl %edx, %ebp
+ /* 2 */
+ movl 12(%esp), %edi
+ xorl %ebp, %esi
+ addl %edi, %edx
+ roll $10, %eax
+ addl %esi, %edx
+ movl %ebp, %esi
+ roll $15, %edx
+ addl %ecx, %edx
+ /* 3 */
+ xorl %eax, %esi
+ movl 16(%esp), %edi
+ xorl %edx, %esi
+ addl %esi, %ecx
+ movl %edx, %esi
+ roll $10, %ebp
+ addl %edi, %ecx
+ xorl %ebp, %esi
+ roll $12, %ecx
+ addl %ebx, %ecx
+ /* 4 */
+ movl 20(%esp), %edi
+ xorl %ecx, %esi
+ addl %edi, %ebx
+ roll $10, %edx
+ addl %esi, %ebx
+ movl %ecx, %esi
+ roll $5, %ebx
+ addl %eax, %ebx
+ /* 5 */
+ xorl %edx, %esi
+ movl 24(%esp), %edi
+ xorl %ebx, %esi
+ addl %esi, %eax
+ movl %ebx, %esi
+ roll $10, %ecx
+ addl %edi, %eax
+ xorl %ecx, %esi
+ roll $8, %eax
+ addl %ebp, %eax
+ /* 6 */
+ movl 28(%esp), %edi
+ xorl %eax, %esi
+ addl %edi, %ebp
+ roll $10, %ebx
+ addl %esi, %ebp
+ movl %eax, %esi
+ roll $7, %ebp
+ addl %edx, %ebp
+ /* 7 */
+ xorl %ebx, %esi
+ movl 32(%esp), %edi
+ xorl %ebp, %esi
+ addl %esi, %edx
+ movl %ebp, %esi
+ roll $10, %eax
+ addl %edi, %edx
+ xorl %eax, %esi
+ roll $9, %edx
+ addl %ecx, %edx
+ /* 8 */
+ movl 36(%esp), %edi
+ xorl %edx, %esi
+ addl %edi, %ecx
+ roll $10, %ebp
+ addl %esi, %ecx
+ movl %edx, %esi
+ roll $11, %ecx
+ addl %ebx, %ecx
+ /* 9 */
+ xorl %ebp, %esi
+ movl 40(%esp), %edi
+ xorl %ecx, %esi
+ addl %esi, %ebx
+ movl %ecx, %esi
+ roll $10, %edx
+ addl %edi, %ebx
+ xorl %edx, %esi
+ roll $13, %ebx
+ addl %eax, %ebx
+ /* 10 */
+ movl 44(%esp), %edi
+ xorl %ebx, %esi
+ addl %edi, %eax
+ roll $10, %ecx
+ addl %esi, %eax
+ movl %ebx, %esi
+ roll $14, %eax
+ addl %ebp, %eax
+ /* 11 */
+ xorl %ecx, %esi
+ movl 48(%esp), %edi
+ xorl %eax, %esi
+ addl %esi, %ebp
+ movl %eax, %esi
+ roll $10, %ebx
+ addl %edi, %ebp
+ xorl %ebx, %esi
+ roll $15, %ebp
+ addl %edx, %ebp
+ /* 12 */
+ movl 52(%esp), %edi
+ xorl %ebp, %esi
+ addl %edi, %edx
+ roll $10, %eax
+ addl %esi, %edx
+ movl %ebp, %esi
+ roll $6, %edx
+ addl %ecx, %edx
+ /* 13 */
+ xorl %eax, %esi
+ movl 56(%esp), %edi
+ xorl %edx, %esi
+ addl %esi, %ecx
+ movl %edx, %esi
+ roll $10, %ebp
+ addl %edi, %ecx
+ xorl %ebp, %esi
+ roll $7, %ecx
+ addl %ebx, %ecx
+ /* 14 */
+ movl 60(%esp), %edi
+ xorl %ecx, %esi
+ addl %edi, %ebx
+ roll $10, %edx
+ addl %esi, %ebx
+ movl %ecx, %esi
+ roll $9, %ebx
+ addl %eax, %ebx
+ /* 15 */
+ xorl %edx, %esi
+ movl 64(%esp), %edi
+ xorl %ebx, %esi
+ addl %esi, %eax
+ movl $-1, %esi
+ roll $10, %ecx
+ addl %edi, %eax
+ movl 32(%esp), %edi
+ roll $8, %eax
+ addl %ebp, %eax
+ /* 16 */
+ addl %edi, %ebp
+ movl %ebx, %edi
+ subl %eax, %esi
+ andl %eax, %edi
+ andl %ecx, %esi
+ orl %esi, %edi
+ movl 20(%esp), %esi
+ roll $10, %ebx
+ leal 1518500249(%ebp,%edi,1),%ebp
+ movl $-1, %edi
+ roll $7, %ebp
+ addl %edx, %ebp
+ /* 17 */
+ addl %esi, %edx
+ movl %eax, %esi
+ subl %ebp, %edi
+ andl %ebp, %esi
+ andl %ebx, %edi
+ orl %edi, %esi
+ movl 56(%esp), %edi
+ roll $10, %eax
+ leal 1518500249(%edx,%esi,1),%edx
+ movl $-1, %esi
+ roll $6, %edx
+ addl %ecx, %edx
+ /* 18 */
+ addl %edi, %ecx
+ movl %ebp, %edi
+ subl %edx, %esi
+ andl %edx, %edi
+ andl %eax, %esi
+ orl %esi, %edi
+ movl 8(%esp), %esi
+ roll $10, %ebp
+ leal 1518500249(%ecx,%edi,1),%ecx
+ movl $-1, %edi
+ roll $8, %ecx
+ addl %ebx, %ecx
+ /* 19 */
+ addl %esi, %ebx
+ movl %edx, %esi
+ subl %ecx, %edi
+ andl %ecx, %esi
+ andl %ebp, %edi
+ orl %edi, %esi
+ movl 44(%esp), %edi
+ roll $10, %edx
+ leal 1518500249(%ebx,%esi,1),%ebx
+ movl $-1, %esi
+ roll $13, %ebx
+ addl %eax, %ebx
+ /* 20 */
+ addl %edi, %eax
+ movl %ecx, %edi
+ subl %ebx, %esi
+ andl %ebx, %edi
+ andl %edx, %esi
+ orl %esi, %edi
+ movl 28(%esp), %esi
+ roll $10, %ecx
+ leal 1518500249(%eax,%edi,1),%eax
+ movl $-1, %edi
+ roll $11, %eax
+ addl %ebp, %eax
+ /* 21 */
+ addl %esi, %ebp
+ movl %ebx, %esi
+ subl %eax, %edi
+ andl %eax, %esi
+ andl %ecx, %edi
+ orl %edi, %esi
+ movl 64(%esp), %edi
+ roll $10, %ebx
+ leal 1518500249(%ebp,%esi,1),%ebp
+ movl $-1, %esi
+ roll $9, %ebp
+ addl %edx, %ebp
+ /* 22 */
+ addl %edi, %edx
+ movl %eax, %edi
+ subl %ebp, %esi
+ andl %ebp, %edi
+ andl %ebx, %esi
+ orl %esi, %edi
+ movl 16(%esp), %esi
+ roll $10, %eax
+ leal 1518500249(%edx,%edi,1),%edx
+ movl $-1, %edi
+ roll $7, %edx
+ addl %ecx, %edx
+ /* 23 */
+ addl %esi, %ecx
+ movl %ebp, %esi
+ subl %edx, %edi
+ andl %edx, %esi
+ andl %eax, %edi
+ orl %edi, %esi
+ movl 52(%esp), %edi
+ roll $10, %ebp
+ leal 1518500249(%ecx,%esi,1),%ecx
+ movl $-1, %esi
+ roll $15, %ecx
+ addl %ebx, %ecx
+ /* 24 */
+ addl %edi, %ebx
+ movl %edx, %edi
+ subl %ecx, %esi
+ andl %ecx, %edi
+ andl %ebp, %esi
+ orl %esi, %edi
+ movl 4(%esp), %esi
+ roll $10, %edx
+ leal 1518500249(%ebx,%edi,1),%ebx
+ movl $-1, %edi
+ roll $7, %ebx
+ addl %eax, %ebx
+ /* 25 */
+ addl %esi, %eax
+ movl %ecx, %esi
+ subl %ebx, %edi
+ andl %ebx, %esi
+ andl %edx, %edi
+ orl %edi, %esi
+ movl 40(%esp), %edi
+ roll $10, %ecx
+ leal 1518500249(%eax,%esi,1),%eax
+ movl $-1, %esi
+ roll $12, %eax
+ addl %ebp, %eax
+ /* 26 */
+ addl %edi, %ebp
+ movl %ebx, %edi
+ subl %eax, %esi
+ andl %eax, %edi
+ andl %ecx, %esi
+ orl %esi, %edi
+ movl 24(%esp), %esi
+ roll $10, %ebx
+ leal 1518500249(%ebp,%edi,1),%ebp
+ movl $-1, %edi
+ roll $15, %ebp
+ addl %edx, %ebp
+ /* 27 */
+ addl %esi, %edx
+ movl %eax, %esi
+ subl %ebp, %edi
+ andl %ebp, %esi
+ andl %ebx, %edi
+ orl %edi, %esi
+ movl 12(%esp), %edi
+ roll $10, %eax
+ leal 1518500249(%edx,%esi,1),%edx
+ movl $-1, %esi
+ roll $9, %edx
+ addl %ecx, %edx
+ /* 28 */
+ addl %edi, %ecx
+ movl %ebp, %edi
+ subl %edx, %esi
+ andl %edx, %edi
+ andl %eax, %esi
+ orl %esi, %edi
+ movl 60(%esp), %esi
+ roll $10, %ebp
+ leal 1518500249(%ecx,%edi,1),%ecx
+ movl $-1, %edi
+ roll $11, %ecx
+ addl %ebx, %ecx
+ /* 29 */
+ addl %esi, %ebx
+ movl %edx, %esi
+ subl %ecx, %edi
+ andl %ecx, %esi
+ andl %ebp, %edi
+ orl %edi, %esi
+ movl 48(%esp), %edi
+ roll $10, %edx
+ leal 1518500249(%ebx,%esi,1),%ebx
+ movl $-1, %esi
+ roll $7, %ebx
+ addl %eax, %ebx
+ /* 30 */
+ addl %edi, %eax
+ movl %ecx, %edi
+ subl %ebx, %esi
+ andl %ebx, %edi
+ andl %edx, %esi
+ orl %esi, %edi
+ movl 36(%esp), %esi
+ roll $10, %ecx
+ leal 1518500249(%eax,%edi,1),%eax
+ movl $-1, %edi
+ roll $13, %eax
+ addl %ebp, %eax
+ /* 31 */
+ addl %esi, %ebp
+ movl %ebx, %esi
+ subl %eax, %edi
+ andl %eax, %esi
+ andl %ecx, %edi
+ orl %edi, %esi
+ movl $-1, %edi
+ roll $10, %ebx
+ leal 1518500249(%ebp,%esi,1),%ebp
+ subl %eax, %edi
+ roll $12, %ebp
+ addl %edx, %ebp
+ /* 32 */
+ movl 16(%esp), %esi
+ orl %ebp, %edi
+ addl %esi, %edx
+ xorl %ebx, %edi
+ movl $-1, %esi
+ roll $10, %eax
+ leal 1859775393(%edx,%edi,1),%edx
+ subl %ebp, %esi
+ roll $11, %edx
+ addl %ecx, %edx
+ /* 33 */
+ movl 44(%esp), %edi
+ orl %edx, %esi
+ addl %edi, %ecx
+ xorl %eax, %esi
+ movl $-1, %edi
+ roll $10, %ebp
+ leal 1859775393(%ecx,%esi,1),%ecx
+ subl %edx, %edi
+ roll $13, %ecx
+ addl %ebx, %ecx
+ /* 34 */
+ movl 60(%esp), %esi
+ orl %ecx, %edi
+ addl %esi, %ebx
+ xorl %ebp, %edi
+ movl $-1, %esi
+ roll $10, %edx
+ leal 1859775393(%ebx,%edi,1),%ebx
+ subl %ecx, %esi
+ roll $6, %ebx
+ addl %eax, %ebx
+ /* 35 */
+ movl 20(%esp), %edi
+ orl %ebx, %esi
+ addl %edi, %eax
+ xorl %edx, %esi
+ movl $-1, %edi
+ roll $10, %ecx
+ leal 1859775393(%eax,%esi,1),%eax
+ subl %ebx, %edi
+ roll $7, %eax
+ addl %ebp, %eax
+ /* 36 */
+ movl 40(%esp), %esi
+ orl %eax, %edi
+ addl %esi, %ebp
+ xorl %ecx, %edi
+ movl $-1, %esi
+ roll $10, %ebx
+ leal 1859775393(%ebp,%edi,1),%ebp
+ subl %eax, %esi
+ roll $14, %ebp
+ addl %edx, %ebp
+ /* 37 */
+ movl 64(%esp), %edi
+ orl %ebp, %esi
+ addl %edi, %edx
+ xorl %ebx, %esi
+ movl $-1, %edi
+ roll $10, %eax
+ leal 1859775393(%edx,%esi,1),%edx
+ subl %ebp, %edi
+ roll $9, %edx
+ addl %ecx, %edx
+ /* 38 */
+ movl 36(%esp), %esi
+ orl %edx, %edi
+ addl %esi, %ecx
+ xorl %eax, %edi
+ movl $-1, %esi
+ roll $10, %ebp
+ leal 1859775393(%ecx,%edi,1),%ecx
+ subl %edx, %esi
+ roll $13, %ecx
+ addl %ebx, %ecx
+ /* 39 */
+ movl 8(%esp), %edi
+ orl %ecx, %esi
+ addl %edi, %ebx
+ xorl %ebp, %esi
+ movl $-1, %edi
+ roll $10, %edx
+ leal 1859775393(%ebx,%esi,1),%ebx
+ subl %ecx, %edi
+ roll $15, %ebx
+ addl %eax, %ebx
+ /* 40 */
+ movl 12(%esp), %esi
+ orl %ebx, %edi
+ addl %esi, %eax
+ xorl %edx, %edi
+ movl $-1, %esi
+ roll $10, %ecx
+ leal 1859775393(%eax,%edi,1),%eax
+ subl %ebx, %esi
+ roll $14, %eax
+ addl %ebp, %eax
+ /* 41 */
+ movl 32(%esp), %edi
+ orl %eax, %esi
+ addl %edi, %ebp
+ xorl %ecx, %esi
+ movl $-1, %edi
+ roll $10, %ebx
+ leal 1859775393(%ebp,%esi,1),%ebp
+ subl %eax, %edi
+ roll $8, %ebp
+ addl %edx, %ebp
+ /* 42 */
+ movl 4(%esp), %esi
+ orl %ebp, %edi
+ addl %esi, %edx
+ xorl %ebx, %edi
+ movl $-1, %esi
+ roll $10, %eax
+ leal 1859775393(%edx,%edi,1),%edx
+ subl %ebp, %esi
+ roll $13, %edx
+ addl %ecx, %edx
+ /* 43 */
+ movl 28(%esp), %edi
+ orl %edx, %esi
+ addl %edi, %ecx
+ xorl %eax, %esi
+ movl $-1, %edi
+ roll $10, %ebp
+ leal 1859775393(%ecx,%esi,1),%ecx
+ subl %edx, %edi
+ roll $6, %ecx
+ addl %ebx, %ecx
+ /* 44 */
+ movl 56(%esp), %esi
+ orl %ecx, %edi
+ addl %esi, %ebx
+ xorl %ebp, %edi
+ movl $-1, %esi
+ roll $10, %edx
+ leal 1859775393(%ebx,%edi,1),%ebx
+ subl %ecx, %esi
+ roll $5, %ebx
+ addl %eax, %ebx
+ /* 45 */
+ movl 48(%esp), %edi
+ orl %ebx, %esi
+ addl %edi, %eax
+ xorl %edx, %esi
+ movl $-1, %edi
+ roll $10, %ecx
+ leal 1859775393(%eax,%esi,1),%eax
+ subl %ebx, %edi
+ roll $12, %eax
+ addl %ebp, %eax
+ /* 46 */
+ movl 24(%esp), %esi
+ orl %eax, %edi
+ addl %esi, %ebp
+ xorl %ecx, %edi
+ movl $-1, %esi
+ roll $10, %ebx
+ leal 1859775393(%ebp,%edi,1),%ebp
+ subl %eax, %esi
+ roll $7, %ebp
+ addl %edx, %ebp
+ /* 47 */
+ movl 52(%esp), %edi
+ orl %ebp, %esi
+ addl %edi, %edx
+ xorl %ebx, %esi
+ movl $-1, %edi
+ roll $10, %eax
+ leal 1859775393(%edx,%esi,1),%edx
+ movl %eax, %esi
+ roll $5, %edx
+ addl %ecx, %edx
+ /* 48 */
+ subl %eax, %edi
+ andl %edx, %esi
+ andl %ebp, %edi
+ orl %esi, %edi
+ movl 8(%esp), %esi
+ roll $10, %ebp
+ leal 2400959708(%ecx,%edi,),%ecx
+ movl $-1, %edi
+ addl %esi, %ecx
+ movl %ebp, %esi
+ roll $11, %ecx
+ addl %ebx, %ecx
+ /* 49 */
+ subl %ebp, %edi
+ andl %ecx, %esi
+ andl %edx, %edi
+ orl %esi, %edi
+ movl 40(%esp), %esi
+ roll $10, %edx
+ leal 2400959708(%ebx,%edi,),%ebx
+ movl $-1, %edi
+ addl %esi, %ebx
+ movl %edx, %esi
+ roll $12, %ebx
+ addl %eax, %ebx
+ /* 50 */
+ subl %edx, %edi
+ andl %ebx, %esi
+ andl %ecx, %edi
+ orl %esi, %edi
+ movl 48(%esp), %esi
+ roll $10, %ecx
+ leal 2400959708(%eax,%edi,),%eax
+ movl $-1, %edi
+ addl %esi, %eax
+ movl %ecx, %esi
+ roll $14, %eax
+ addl %ebp, %eax
+ /* 51 */
+ subl %ecx, %edi
+ andl %eax, %esi
+ andl %ebx, %edi
+ orl %esi, %edi
+ movl 44(%esp), %esi
+ roll $10, %ebx
+ leal 2400959708(%ebp,%edi,),%ebp
+ movl $-1, %edi
+ addl %esi, %ebp
+ movl %ebx, %esi
+ roll $15, %ebp
+ addl %edx, %ebp
+ /* 52 */
+ subl %ebx, %edi
+ andl %ebp, %esi
+ andl %eax, %edi
+ orl %esi, %edi
+ movl 4(%esp), %esi
+ roll $10, %eax
+ leal 2400959708(%edx,%edi,),%edx
+ movl $-1, %edi
+ addl %esi, %edx
+ movl %eax, %esi
+ roll $14, %edx
+ addl %ecx, %edx
+ /* 53 */
+ subl %eax, %edi
+ andl %edx, %esi
+ andl %ebp, %edi
+ orl %esi, %edi
+ movl 36(%esp), %esi
+ roll $10, %ebp
+ leal 2400959708(%ecx,%edi,),%ecx
+ movl $-1, %edi
+ addl %esi, %ecx
+ movl %ebp, %esi
+ roll $15, %ecx
+ addl %ebx, %ecx
+ /* 54 */
+ subl %ebp, %edi
+ andl %ecx, %esi
+ andl %edx, %edi
+ orl %esi, %edi
+ movl 52(%esp), %esi
+ roll $10, %edx
+ leal 2400959708(%ebx,%edi,),%ebx
+ movl $-1, %edi
+ addl %esi, %ebx
+ movl %edx, %esi
+ roll $9, %ebx
+ addl %eax, %ebx
+ /* 55 */
+ subl %edx, %edi
+ andl %ebx, %esi
+ andl %ecx, %edi
+ orl %esi, %edi
+ movl 20(%esp), %esi
+ roll $10, %ecx
+ leal 2400959708(%eax,%edi,),%eax
+ movl $-1, %edi
+ addl %esi, %eax
+ movl %ecx, %esi
+ roll $8, %eax
+ addl %ebp, %eax
+ /* 56 */
+ subl %ecx, %edi
+ andl %eax, %esi
+ andl %ebx, %edi
+ orl %esi, %edi
+ movl 56(%esp), %esi
+ roll $10, %ebx
+ leal 2400959708(%ebp,%edi,),%ebp
+ movl $-1, %edi
+ addl %esi, %ebp
+ movl %ebx, %esi
+ roll $9, %ebp
+ addl %edx, %ebp
+ /* 57 */
+ subl %ebx, %edi
+ andl %ebp, %esi
+ andl %eax, %edi
+ orl %esi, %edi
+ movl 16(%esp), %esi
+ roll $10, %eax
+ leal 2400959708(%edx,%edi,),%edx
+ movl $-1, %edi
+ addl %esi, %edx
+ movl %eax, %esi
+ roll $14, %edx
+ addl %ecx, %edx
+ /* 58 */
+ subl %eax, %edi
+ andl %edx, %esi
+ andl %ebp, %edi
+ orl %esi, %edi
+ movl 32(%esp), %esi
+ roll $10, %ebp
+ leal 2400959708(%ecx,%edi,),%ecx
+ movl $-1, %edi
+ addl %esi, %ecx
+ movl %ebp, %esi
+ roll $5, %ecx
+ addl %ebx, %ecx
+ /* 59 */
+ subl %ebp, %edi
+ andl %ecx, %esi
+ andl %edx, %edi
+ orl %esi, %edi
+ movl 64(%esp), %esi
+ roll $10, %edx
+ leal 2400959708(%ebx,%edi,),%ebx
+ movl $-1, %edi
+ addl %esi, %ebx
+ movl %edx, %esi
+ roll $6, %ebx
+ addl %eax, %ebx
+ /* 60 */
+ subl %edx, %edi
+ andl %ebx, %esi
+ andl %ecx, %edi
+ orl %esi, %edi
+ movl 60(%esp), %esi
+ roll $10, %ecx
+ leal 2400959708(%eax,%edi,),%eax
+ movl $-1, %edi
+ addl %esi, %eax
+ movl %ecx, %esi
+ roll $8, %eax
+ addl %ebp, %eax
+ /* 61 */
+ subl %ecx, %edi
+ andl %eax, %esi
+ andl %ebx, %edi
+ orl %esi, %edi
+ movl 24(%esp), %esi
+ roll $10, %ebx
+ leal 2400959708(%ebp,%edi,),%ebp
+ movl $-1, %edi
+ addl %esi, %ebp
+ movl %ebx, %esi
+ roll $6, %ebp
+ addl %edx, %ebp
+ /* 62 */
+ subl %ebx, %edi
+ andl %ebp, %esi
+ andl %eax, %edi
+ orl %esi, %edi
+ movl 28(%esp), %esi
+ roll $10, %eax
+ leal 2400959708(%edx,%edi,),%edx
+ movl $-1, %edi
+ addl %esi, %edx
+ movl %eax, %esi
+ roll $5, %edx
+ addl %ecx, %edx
+ /* 63 */
+ subl %eax, %edi
+ andl %edx, %esi
+ andl %ebp, %edi
+ orl %esi, %edi
+ movl 12(%esp), %esi
+ roll $10, %ebp
+ leal 2400959708(%ecx,%edi,),%ecx
+ movl $-1, %edi
+ addl %esi, %ecx
+ subl %ebp, %edi
+ roll $12, %ecx
+ addl %ebx, %ecx
+ /* 64 */
+ movl 20(%esp), %esi
+ orl %edx, %edi
+ addl %esi, %ebx
+ xorl %ecx, %edi
+ movl $-1, %esi
+ roll $10, %edx
+ leal 2840853838(%ebx,%edi,1),%ebx
+ subl %edx, %esi
+ roll $9, %ebx
+ addl %eax, %ebx
+ /* 65 */
+ movl 4(%esp), %edi
+ orl %ecx, %esi
+ addl %edi, %eax
+ xorl %ebx, %esi
+ movl $-1, %edi
+ roll $10, %ecx
+ leal 2840853838(%eax,%esi,1),%eax
+ subl %ecx, %edi
+ roll $15, %eax
+ addl %ebp, %eax
+ /* 66 */
+ movl 24(%esp), %esi
+ orl %ebx, %edi
+ addl %esi, %ebp
+ xorl %eax, %edi
+ movl $-1, %esi
+ roll $10, %ebx
+ leal 2840853838(%ebp,%edi,1),%ebp
+ subl %ebx, %esi
+ roll $5, %ebp
+ addl %edx, %ebp
+ /* 67 */
+ movl 40(%esp), %edi
+ orl %eax, %esi
+ addl %edi, %edx
+ xorl %ebp, %esi
+ movl $-1, %edi
+ roll $10, %eax
+ leal 2840853838(%edx,%esi,1),%edx
+ subl %eax, %edi
+ roll $11, %edx
+ addl %ecx, %edx
+ /* 68 */
+ movl 32(%esp), %esi
+ orl %ebp, %edi
+ addl %esi, %ecx
+ xorl %edx, %edi
+ movl $-1, %esi
+ roll $10, %ebp
+ leal 2840853838(%ecx,%edi,1),%ecx
+ subl %ebp, %esi
+ roll $6, %ecx
+ addl %ebx, %ecx
+ /* 69 */
+ movl 52(%esp), %edi
+ orl %edx, %esi
+ addl %edi, %ebx
+ xorl %ecx, %esi
+ movl $-1, %edi
+ roll $10, %edx
+ leal 2840853838(%ebx,%esi,1),%ebx
+ subl %edx, %edi
+ roll $8, %ebx
+ addl %eax, %ebx
+ /* 70 */
+ movl 12(%esp), %esi
+ orl %ecx, %edi
+ addl %esi, %eax
+ xorl %ebx, %edi
+ movl $-1, %esi
+ roll $10, %ecx
+ leal 2840853838(%eax,%edi,1),%eax
+ subl %ecx, %esi
+ roll $13, %eax
+ addl %ebp, %eax
+ /* 71 */
+ movl 44(%esp), %edi
+ orl %ebx, %esi
+ addl %edi, %ebp
+ xorl %eax, %esi
+ movl $-1, %edi
+ roll $10, %ebx
+ leal 2840853838(%ebp,%esi,1),%ebp
+ subl %ebx, %edi
+ roll $12, %ebp
+ addl %edx, %ebp
+ /* 72 */
+ movl 60(%esp), %esi
+ orl %eax, %edi
+ addl %esi, %edx
+ xorl %ebp, %edi
+ movl $-1, %esi
+ roll $10, %eax
+ leal 2840853838(%edx,%edi,1),%edx
+ subl %eax, %esi
+ roll $5, %edx
+ addl %ecx, %edx
+ /* 73 */
+ movl 8(%esp), %edi
+ orl %ebp, %esi
+ addl %edi, %ecx
+ xorl %edx, %esi
+ movl $-1, %edi
+ roll $10, %ebp
+ leal 2840853838(%ecx,%esi,1),%ecx
+ subl %ebp, %edi
+ roll $12, %ecx
+ addl %ebx, %ecx
+ /* 74 */
+ movl 16(%esp), %esi
+ orl %edx, %edi
+ addl %esi, %ebx
+ xorl %ecx, %edi
+ movl $-1, %esi
+ roll $10, %edx
+ leal 2840853838(%ebx,%edi,1),%ebx
+ subl %edx, %esi
+ roll $13, %ebx
+ addl %eax, %ebx
+ /* 75 */
+ movl 36(%esp), %edi
+ orl %ecx, %esi
+ addl %edi, %eax
+ xorl %ebx, %esi
+ movl $-1, %edi
+ roll $10, %ecx
+ leal 2840853838(%eax,%esi,1),%eax
+ subl %ecx, %edi
+ roll $14, %eax
+ addl %ebp, %eax
+ /* 76 */
+ movl 48(%esp), %esi
+ orl %ebx, %edi
+ addl %esi, %ebp
+ xorl %eax, %edi
+ movl $-1, %esi
+ roll $10, %ebx
+ leal 2840853838(%ebp,%edi,1),%ebp
+ subl %ebx, %esi
+ roll $11, %ebp
+ addl %edx, %ebp
+ /* 77 */
+ movl 28(%esp), %edi
+ orl %eax, %esi
+ addl %edi, %edx
+ xorl %ebp, %esi
+ movl $-1, %edi
+ roll $10, %eax
+ leal 2840853838(%edx,%esi,1),%edx
+ subl %eax, %edi
+ roll $8, %edx
+ addl %ecx, %edx
+ /* 78 */
+ movl 64(%esp), %esi
+ orl %ebp, %edi
+ addl %esi, %ecx
+ xorl %edx, %edi
+ movl $-1, %esi
+ roll $10, %ebp
+ leal 2840853838(%ecx,%edi,1),%ecx
+ subl %ebp, %esi
+ roll $5, %ecx
+ addl %ebx, %ecx
+ /* 79 */
+ movl 56(%esp), %edi
+ orl %edx, %esi
+ addl %edi, %ebx
+ xorl %ecx, %esi
+ movl 108(%esp), %edi
+ roll $10, %edx
+ leal 2840853838(%ebx,%esi,1),%ebx
+ movl %eax, 68(%esp)
+ roll $6, %ebx
+ addl %eax, %ebx
+ movl (%edi), %eax
+ movl %ebx, 72(%esp)
+ movl %ecx, 76(%esp)
+ movl 4(%edi), %ebx
+ movl %edx, 80(%esp)
+ movl 8(%edi), %ecx
+ movl %ebp, 84(%esp)
+ movl 12(%edi), %edx
+ movl 16(%edi), %ebp
+ /* 80 */
+ movl $-1, %edi
+ subl %edx, %edi
+ movl 24(%esp), %esi
+ orl %ecx, %edi
+ addl %esi, %eax
+ xorl %ebx, %edi
+ movl $-1, %esi
+ roll $10, %ecx
+ leal 1352829926(%eax,%edi,1),%eax
+ subl %ecx, %esi
+ roll $8, %eax
+ addl %ebp, %eax
+ /* 81 */
+ movl 60(%esp), %edi
+ orl %ebx, %esi
+ addl %edi, %ebp
+ xorl %eax, %esi
+ movl $-1, %edi
+ roll $10, %ebx
+ leal 1352829926(%ebp,%esi,1),%ebp
+ subl %ebx, %edi
+ roll $9, %ebp
+ addl %edx, %ebp
+ /* 82 */
+ movl 32(%esp), %esi
+ orl %eax, %edi
+ addl %esi, %edx
+ xorl %ebp, %edi
+ movl $-1, %esi
+ roll $10, %eax
+ leal 1352829926(%edx,%edi,1),%edx
+ subl %eax, %esi
+ roll $9, %edx
+ addl %ecx, %edx
+ /* 83 */
+ movl 4(%esp), %edi
+ orl %ebp, %esi
+ addl %edi, %ecx
+ xorl %edx, %esi
+ movl $-1, %edi
+ roll $10, %ebp
+ leal 1352829926(%ecx,%esi,1),%ecx
+ subl %ebp, %edi
+ roll $11, %ecx
+ addl %ebx, %ecx
+ /* 84 */
+ movl 40(%esp), %esi
+ orl %edx, %edi
+ addl %esi, %ebx
+ xorl %ecx, %edi
+ movl $-1, %esi
+ roll $10, %edx
+ leal 1352829926(%ebx,%edi,1),%ebx
+ subl %edx, %esi
+ roll $13, %ebx
+ addl %eax, %ebx
+ /* 85 */
+ movl 12(%esp), %edi
+ orl %ecx, %esi
+ addl %edi, %eax
+ xorl %ebx, %esi
+ movl $-1, %edi
+ roll $10, %ecx
+ leal 1352829926(%eax,%esi,1),%eax
+ subl %ecx, %edi
+ roll $15, %eax
+ addl %ebp, %eax
+ /* 86 */
+ movl 48(%esp), %esi
+ orl %ebx, %edi
+ addl %esi, %ebp
+ xorl %eax, %edi
+ movl $-1, %esi
+ roll $10, %ebx
+ leal 1352829926(%ebp,%edi,1),%ebp
+ subl %ebx, %esi
+ roll $15, %ebp
+ addl %edx, %ebp
+ /* 87 */
+ movl 20(%esp), %edi
+ orl %eax, %esi
+ addl %edi, %edx
+ xorl %ebp, %esi
+ movl $-1, %edi
+ roll $10, %eax
+ leal 1352829926(%edx,%esi,1),%edx
+ subl %eax, %edi
+ roll $5, %edx
+ addl %ecx, %edx
+ /* 88 */
+ movl 56(%esp), %esi
+ orl %ebp, %edi
+ addl %esi, %ecx
+ xorl %edx, %edi
+ movl $-1, %esi
+ roll $10, %ebp
+ leal 1352829926(%ecx,%edi,1),%ecx
+ subl %ebp, %esi
+ roll $7, %ecx
+ addl %ebx, %ecx
+ /* 89 */
+ movl 28(%esp), %edi
+ orl %edx, %esi
+ addl %edi, %ebx
+ xorl %ecx, %esi
+ movl $-1, %edi
+ roll $10, %edx
+ leal 1352829926(%ebx,%esi,1),%ebx
+ subl %edx, %edi
+ roll $7, %ebx
+ addl %eax, %ebx
+ /* 90 */
+ movl 64(%esp), %esi
+ orl %ecx, %edi
+ addl %esi, %eax
+ xorl %ebx, %edi
+ movl $-1, %esi
+ roll $10, %ecx
+ leal 1352829926(%eax,%edi,1),%eax
+ subl %ecx, %esi
+ roll $8, %eax
+ addl %ebp, %eax
+ /* 91 */
+ movl 36(%esp), %edi
+ orl %ebx, %esi
+ addl %edi, %ebp
+ xorl %eax, %esi
+ movl $-1, %edi
+ roll $10, %ebx
+ leal 1352829926(%ebp,%esi,1),%ebp
+ subl %ebx, %edi
+ roll $11, %ebp
+ addl %edx, %ebp
+ /* 92 */
+ movl 8(%esp), %esi
+ orl %eax, %edi
+ addl %esi, %edx
+ xorl %ebp, %edi
+ movl $-1, %esi
+ roll $10, %eax
+ leal 1352829926(%edx,%edi,1),%edx
+ subl %eax, %esi
+ roll $14, %edx
+ addl %ecx, %edx
+ /* 93 */
+ movl 44(%esp), %edi
+ orl %ebp, %esi
+ addl %edi, %ecx
+ xorl %edx, %esi
+ movl $-1, %edi
+ roll $10, %ebp
+ leal 1352829926(%ecx,%esi,1),%ecx
+ subl %ebp, %edi
+ roll $14, %ecx
+ addl %ebx, %ecx
+ /* 94 */
+ movl 16(%esp), %esi
+ orl %edx, %edi
+ addl %esi, %ebx
+ xorl %ecx, %edi
+ movl $-1, %esi
+ roll $10, %edx
+ leal 1352829926(%ebx,%edi,1),%ebx
+ subl %edx, %esi
+ roll $12, %ebx
+ addl %eax, %ebx
+ /* 95 */
+ movl 52(%esp), %edi
+ orl %ecx, %esi
+ addl %edi, %eax
+ xorl %ebx, %esi
+ movl $-1, %edi
+ roll $10, %ecx
+ leal 1352829926(%eax,%esi,1),%eax
+ movl %ecx, %esi
+ roll $6, %eax
+ addl %ebp, %eax
+ /* 96 */
+ subl %ecx, %edi
+ andl %eax, %esi
+ andl %ebx, %edi
+ orl %esi, %edi
+ movl 28(%esp), %esi
+ roll $10, %ebx
+ leal 1548603684(%ebp,%edi,),%ebp
+ movl $-1, %edi
+ addl %esi, %ebp
+ movl %ebx, %esi
+ roll $9, %ebp
+ addl %edx, %ebp
+ /* 97 */
+ subl %ebx, %edi
+ andl %ebp, %esi
+ andl %eax, %edi
+ orl %esi, %edi
+ movl 48(%esp), %esi
+ roll $10, %eax
+ leal 1548603684(%edx,%edi,),%edx
+ movl $-1, %edi
+ addl %esi, %edx
+ movl %eax, %esi
+ roll $13, %edx
+ addl %ecx, %edx
+ /* 98 */
+ subl %eax, %edi
+ andl %edx, %esi
+ andl %ebp, %edi
+ orl %esi, %edi
+ movl 16(%esp), %esi
+ roll $10, %ebp
+ leal 1548603684(%ecx,%edi,),%ecx
+ movl $-1, %edi
+ addl %esi, %ecx
+ movl %ebp, %esi
+ roll $15, %ecx
+ addl %ebx, %ecx
+ /* 99 */
+ subl %ebp, %edi
+ andl %ecx, %esi
+ andl %edx, %edi
+ orl %esi, %edi
+ movl 32(%esp), %esi
+ roll $10, %edx
+ leal 1548603684(%ebx,%edi,),%ebx
+ movl $-1, %edi
+ addl %esi, %ebx
+ movl %edx, %esi
+ roll $7, %ebx
+ addl %eax, %ebx
+ /* 100 */
+ subl %edx, %edi
+ andl %ebx, %esi
+ andl %ecx, %edi
+ orl %esi, %edi
+ movl 4(%esp), %esi
+ roll $10, %ecx
+ leal 1548603684(%eax,%edi,),%eax
+ movl $-1, %edi
+ addl %esi, %eax
+ movl %ecx, %esi
+ roll $12, %eax
+ addl %ebp, %eax
+ /* 101 */
+ subl %ecx, %edi
+ andl %eax, %esi
+ andl %ebx, %edi
+ orl %esi, %edi
+ movl 56(%esp), %esi
+ roll $10, %ebx
+ leal 1548603684(%ebp,%edi,),%ebp
+ movl $-1, %edi
+ addl %esi, %ebp
+ movl %ebx, %esi
+ roll $8, %ebp
+ addl %edx, %ebp
+ /* 102 */
+ subl %ebx, %edi
+ andl %ebp, %esi
+ andl %eax, %edi
+ orl %esi, %edi
+ movl 24(%esp), %esi
+ roll $10, %eax
+ leal 1548603684(%edx,%edi,),%edx
+ movl $-1, %edi
+ addl %esi, %edx
+ movl %eax, %esi
+ roll $9, %edx
+ addl %ecx, %edx
+ /* 103 */
+ subl %eax, %edi
+ andl %edx, %esi
+ andl %ebp, %edi
+ orl %esi, %edi
+ movl 44(%esp), %esi
+ roll $10, %ebp
+ leal 1548603684(%ecx,%edi,),%ecx
+ movl $-1, %edi
+ addl %esi, %ecx
+ movl %ebp, %esi
+ roll $11, %ecx
+ addl %ebx, %ecx
+ /* 104 */
+ subl %ebp, %edi
+ andl %ecx, %esi
+ andl %edx, %edi
+ orl %esi, %edi
+ movl 60(%esp), %esi
+ roll $10, %edx
+ leal 1548603684(%ebx,%edi,),%ebx
+ movl $-1, %edi
+ addl %esi, %ebx
+ movl %edx, %esi
+ roll $7, %ebx
+ addl %eax, %ebx
+ /* 105 */
+ subl %edx, %edi
+ andl %ebx, %esi
+ andl %ecx, %edi
+ orl %esi, %edi
+ movl 64(%esp), %esi
+ roll $10, %ecx
+ leal 1548603684(%eax,%edi,),%eax
+ movl $-1, %edi
+ addl %esi, %eax
+ movl %ecx, %esi
+ roll $7, %eax
+ addl %ebp, %eax
+ /* 106 */
+ subl %ecx, %edi
+ andl %eax, %esi
+ andl %ebx, %edi
+ orl %esi, %edi
+ movl 36(%esp), %esi
+ roll $10, %ebx
+ leal 1548603684(%ebp,%edi,),%ebp
+ movl $-1, %edi
+ addl %esi, %ebp
+ movl %ebx, %esi
+ roll $12, %ebp
+ addl %edx, %ebp
+ /* 107 */
+ subl %ebx, %edi
+ andl %ebp, %esi
+ andl %eax, %edi
+ orl %esi, %edi
+ movl 52(%esp), %esi
+ roll $10, %eax
+ leal 1548603684(%edx,%edi,),%edx
+ movl $-1, %edi
+ addl %esi, %edx
+ movl %eax, %esi
+ roll $7, %edx
+ addl %ecx, %edx
+ /* 108 */
+ subl %eax, %edi
+ andl %edx, %esi
+ andl %ebp, %edi
+ orl %esi, %edi
+ movl 20(%esp), %esi
+ roll $10, %ebp
+ leal 1548603684(%ecx,%edi,),%ecx
+ movl $-1, %edi
+ addl %esi, %ecx
+ movl %ebp, %esi
+ roll $6, %ecx
+ addl %ebx, %ecx
+ /* 109 */
+ subl %ebp, %edi
+ andl %ecx, %esi
+ andl %edx, %edi
+ orl %esi, %edi
+ movl 40(%esp), %esi
+ roll $10, %edx
+ leal 1548603684(%ebx,%edi,),%ebx
+ movl $-1, %edi
+ addl %esi, %ebx
+ movl %edx, %esi
+ roll $15, %ebx
+ addl %eax, %ebx
+ /* 110 */
+ subl %edx, %edi
+ andl %ebx, %esi
+ andl %ecx, %edi
+ orl %esi, %edi
+ movl 8(%esp), %esi
+ roll $10, %ecx
+ leal 1548603684(%eax,%edi,),%eax
+ movl $-1, %edi
+ addl %esi, %eax
+ movl %ecx, %esi
+ roll $13, %eax
+ addl %ebp, %eax
+ /* 111 */
+ subl %ecx, %edi
+ andl %eax, %esi
+ andl %ebx, %edi
+ orl %esi, %edi
+ movl 12(%esp), %esi
+ roll $10, %ebx
+ leal 1548603684(%ebp,%edi,),%ebp
+ movl $-1, %edi
+ addl %esi, %ebp
+ subl %eax, %edi
+ roll $11, %ebp
+ addl %edx, %ebp
+ /* 112 */
+ movl 64(%esp), %esi
+ orl %ebp, %edi
+ addl %esi, %edx
+ xorl %ebx, %edi
+ movl $-1, %esi
+ roll $10, %eax
+ leal 1836072691(%edx,%edi,1),%edx
+ subl %ebp, %esi
+ roll $9, %edx
+ addl %ecx, %edx
+ /* 113 */
+ movl 24(%esp), %edi
+ orl %edx, %esi
+ addl %edi, %ecx
+ xorl %eax, %esi
+ movl $-1, %edi
+ roll $10, %ebp
+ leal 1836072691(%ecx,%esi,1),%ecx
+ subl %edx, %edi
+ roll $7, %ecx
+ addl %ebx, %ecx
+ /* 114 */
+ movl 8(%esp), %esi
+ orl %ecx, %edi
+ addl %esi, %ebx
+ xorl %ebp, %edi
+ movl $-1, %esi
+ roll $10, %edx
+ leal 1836072691(%ebx,%edi,1),%ebx
+ subl %ecx, %esi
+ roll $15, %ebx
+ addl %eax, %ebx
+ /* 115 */
+ movl 16(%esp), %edi
+ orl %ebx, %esi
+ addl %edi, %eax
+ xorl %edx, %esi
+ movl $-1, %edi
+ roll $10, %ecx
+ leal 1836072691(%eax,%esi,1),%eax
+ subl %ebx, %edi
+ roll $11, %eax
+ addl %ebp, %eax
+ /* 116 */
+ movl 32(%esp), %esi
+ orl %eax, %edi
+ addl %esi, %ebp
+ xorl %ecx, %edi
+ movl $-1, %esi
+ roll $10, %ebx
+ leal 1836072691(%ebp,%edi,1),%ebp
+ subl %eax, %esi
+ roll $8, %ebp
+ addl %edx, %ebp
+ /* 117 */
+ movl 60(%esp), %edi
+ orl %ebp, %esi
+ addl %edi, %edx
+ xorl %ebx, %esi
+ movl $-1, %edi
+ roll $10, %eax
+ leal 1836072691(%edx,%esi,1),%edx
+ subl %ebp, %edi
+ roll $6, %edx
+ addl %ecx, %edx
+ /* 118 */
+ movl 28(%esp), %esi
+ orl %edx, %edi
+ addl %esi, %ecx
+ xorl %eax, %edi
+ movl $-1, %esi
+ roll $10, %ebp
+ leal 1836072691(%ecx,%edi,1),%ecx
+ subl %edx, %esi
+ roll $6, %ecx
+ addl %ebx, %ecx
+ /* 119 */
+ movl 40(%esp), %edi
+ orl %ecx, %esi
+ addl %edi, %ebx
+ xorl %ebp, %esi
+ movl $-1, %edi
+ roll $10, %edx
+ leal 1836072691(%ebx,%esi,1),%ebx
+ subl %ecx, %edi
+ roll $14, %ebx
+ addl %eax, %ebx
+ /* 120 */
+ movl 48(%esp), %esi
+ orl %ebx, %edi
+ addl %esi, %eax
+ xorl %edx, %edi
+ movl $-1, %esi
+ roll $10, %ecx
+ leal 1836072691(%eax,%edi,1),%eax
+ subl %ebx, %esi
+ roll $12, %eax
+ addl %ebp, %eax
+ /* 121 */
+ movl 36(%esp), %edi
+ orl %eax, %esi
+ addl %edi, %ebp
+ xorl %ecx, %esi
+ movl $-1, %edi
+ roll $10, %ebx
+ leal 1836072691(%ebp,%esi,1),%ebp
+ subl %eax, %edi
+ roll $13, %ebp
+ addl %edx, %ebp
+ /* 122 */
+ movl 52(%esp), %esi
+ orl %ebp, %edi
+ addl %esi, %edx
+ xorl %ebx, %edi
+ movl $-1, %esi
+ roll $10, %eax
+ leal 1836072691(%edx,%edi,1),%edx
+ subl %ebp, %esi
+ roll $5, %edx
+ addl %ecx, %edx
+ /* 123 */
+ movl 12(%esp), %edi
+ orl %edx, %esi
+ addl %edi, %ecx
+ xorl %eax, %esi
+ movl $-1, %edi
+ roll $10, %ebp
+ leal 1836072691(%ecx,%esi,1),%ecx
+ subl %edx, %edi
+ roll $14, %ecx
+ addl %ebx, %ecx
+ /* 124 */
+ movl 44(%esp), %esi
+ orl %ecx, %edi
+ addl %esi, %ebx
+ xorl %ebp, %edi
+ movl $-1, %esi
+ roll $10, %edx
+ leal 1836072691(%ebx,%edi,1),%ebx
+ subl %ecx, %esi
+ roll $13, %ebx
+ addl %eax, %ebx
+ /* 125 */
+ movl 4(%esp), %edi
+ orl %ebx, %esi
+ addl %edi, %eax
+ xorl %edx, %esi
+ movl $-1, %edi
+ roll $10, %ecx
+ leal 1836072691(%eax,%esi,1),%eax
+ subl %ebx, %edi
+ roll $13, %eax
+ addl %ebp, %eax
+ /* 126 */
+ movl 20(%esp), %esi
+ orl %eax, %edi
+ addl %esi, %ebp
+ xorl %ecx, %edi
+ movl $-1, %esi
+ roll $10, %ebx
+ leal 1836072691(%ebp,%edi,1),%ebp
+ subl %eax, %esi
+ roll $7, %ebp
+ addl %edx, %ebp
+ /* 127 */
+ movl 56(%esp), %edi
+ orl %ebp, %esi
+ addl %edi, %edx
+ xorl %ebx, %esi
+ movl 36(%esp), %edi
+ roll $10, %eax
+ leal 1836072691(%edx,%esi,1),%edx
+ movl $-1, %esi
+ roll $5, %edx
+ addl %ecx, %edx
+ /* 128 */
+ addl %edi, %ecx
+ movl %ebp, %edi
+ subl %edx, %esi
+ andl %edx, %edi
+ andl %eax, %esi
+ orl %esi, %edi
+ movl 28(%esp), %esi
+ roll $10, %ebp
+ leal 2053994217(%ecx,%edi,1),%ecx
+ movl $-1, %edi
+ roll $15, %ecx
+ addl %ebx, %ecx
+ /* 129 */
+ addl %esi, %ebx
+ movl %edx, %esi
+ subl %ecx, %edi
+ andl %ecx, %esi
+ andl %ebp, %edi
+ orl %edi, %esi
+ movl 20(%esp), %edi
+ roll $10, %edx
+ leal 2053994217(%ebx,%esi,1),%ebx
+ movl $-1, %esi
+ roll $5, %ebx
+ addl %eax, %ebx
+ /* 130 */
+ addl %edi, %eax
+ movl %ecx, %edi
+ subl %ebx, %esi
+ andl %ebx, %edi
+ andl %edx, %esi
+ orl %esi, %edi
+ movl 8(%esp), %esi
+ roll $10, %ecx
+ leal 2053994217(%eax,%edi,1),%eax
+ movl $-1, %edi
+ roll $8, %eax
+ addl %ebp, %eax
+ /* 131 */
+ addl %esi, %ebp
+ movl %ebx, %esi
+ subl %eax, %edi
+ andl %eax, %esi
+ andl %ecx, %edi
+ orl %edi, %esi
+ movl 16(%esp), %edi
+ roll $10, %ebx
+ leal 2053994217(%ebp,%esi,1),%ebp
+ movl $-1, %esi
+ roll $11, %ebp
+ addl %edx, %ebp
+ /* 132 */
+ addl %edi, %edx
+ movl %eax, %edi
+ subl %ebp, %esi
+ andl %ebp, %edi
+ andl %ebx, %esi
+ orl %esi, %edi
+ movl 48(%esp), %esi
+ roll $10, %eax
+ leal 2053994217(%edx,%edi,1),%edx
+ movl $-1, %edi
+ roll $14, %edx
+ addl %ecx, %edx
+ /* 133 */
+ addl %esi, %ecx
+ movl %ebp, %esi
+ subl %edx, %edi
+ andl %edx, %esi
+ andl %eax, %edi
+ orl %edi, %esi
+ movl 64(%esp), %edi
+ roll $10, %ebp
+ leal 2053994217(%ecx,%esi,1),%ecx
+ movl $-1, %esi
+ roll $14, %ecx
+ addl %ebx, %ecx
+ /* 134 */
+ addl %edi, %ebx
+ movl %edx, %edi
+ subl %ecx, %esi
+ andl %ecx, %edi
+ andl %ebp, %esi
+ orl %esi, %edi
+ movl 4(%esp), %esi
+ roll $10, %edx
+ leal 2053994217(%ebx,%edi,1),%ebx
+ movl $-1, %edi
+ roll $6, %ebx
+ addl %eax, %ebx
+ /* 135 */
+ addl %esi, %eax
+ movl %ecx, %esi
+ subl %ebx, %edi
+ andl %ebx, %esi
+ andl %edx, %edi
+ orl %edi, %esi
+ movl 24(%esp), %edi
+ roll $10, %ecx
+ leal 2053994217(%eax,%esi,1),%eax
+ movl $-1, %esi
+ roll $14, %eax
+ addl %ebp, %eax
+ /* 136 */
+ addl %edi, %ebp
+ movl %ebx, %edi
+ subl %eax, %esi
+ andl %eax, %edi
+ andl %ecx, %esi
+ orl %esi, %edi
+ movl 52(%esp), %esi
+ roll $10, %ebx
+ leal 2053994217(%ebp,%edi,1),%ebp
+ movl $-1, %edi
+ roll $6, %ebp
+ addl %edx, %ebp
+ /* 137 */
+ addl %esi, %edx
+ movl %eax, %esi
+ subl %ebp, %edi
+ andl %ebp, %esi
+ andl %ebx, %edi
+ orl %edi, %esi
+ movl 12(%esp), %edi
+ roll $10, %eax
+ leal 2053994217(%edx,%esi,1),%edx
+ movl $-1, %esi
+ roll $9, %edx
+ addl %ecx, %edx
+ /* 138 */
+ addl %edi, %ecx
+ movl %ebp, %edi
+ subl %edx, %esi
+ andl %edx, %edi
+ andl %eax, %esi
+ orl %esi, %edi
+ movl 56(%esp), %esi
+ roll $10, %ebp
+ leal 2053994217(%ecx,%edi,1),%ecx
+ movl $-1, %edi
+ roll $12, %ecx
+ addl %ebx, %ecx
+ /* 139 */
+ addl %esi, %ebx
+ movl %edx, %esi
+ subl %ecx, %edi
+ andl %ecx, %esi
+ andl %ebp, %edi
+ orl %edi, %esi
+ movl 40(%esp), %edi
+ roll $10, %edx
+ leal 2053994217(%ebx,%esi,1),%ebx
+ movl $-1, %esi
+ roll $9, %ebx
+ addl %eax, %ebx
+ /* 140 */
+ addl %edi, %eax
+ movl %ecx, %edi
+ subl %ebx, %esi
+ andl %ebx, %edi
+ andl %edx, %esi
+ orl %esi, %edi
+ movl 32(%esp), %esi
+ roll $10, %ecx
+ leal 2053994217(%eax,%edi,1),%eax
+ movl $-1, %edi
+ roll $12, %eax
+ addl %ebp, %eax
+ /* 141 */
+ addl %esi, %ebp
+ movl %ebx, %esi
+ subl %eax, %edi
+ andl %eax, %esi
+ andl %ecx, %edi
+ orl %edi, %esi
+ movl 44(%esp), %edi
+ roll $10, %ebx
+ leal 2053994217(%ebp,%esi,1),%ebp
+ movl $-1, %esi
+ roll $5, %ebp
+ addl %edx, %ebp
+ /* 142 */
+ addl %edi, %edx
+ movl %eax, %edi
+ subl %ebp, %esi
+ andl %ebp, %edi
+ andl %ebx, %esi
+ orl %esi, %edi
+ movl 60(%esp), %esi
+ roll $10, %eax
+ leal 2053994217(%edx,%edi,1),%edx
+ movl $-1, %edi
+ roll $15, %edx
+ addl %ecx, %edx
+ /* 143 */
+ addl %esi, %ecx
+ movl %ebp, %esi
+ subl %edx, %edi
+ andl %edx, %esi
+ andl %eax, %edi
+ orl %esi, %edi
+ movl %edx, %esi
+ roll $10, %ebp
+ leal 2053994217(%ecx,%edi,1),%ecx
+ xorl %ebp, %esi
+ roll $8, %ecx
+ addl %ebx, %ecx
+ /* 144 */
+ movl 52(%esp), %edi
+ xorl %ecx, %esi
+ addl %edi, %ebx
+ roll $10, %edx
+ addl %esi, %ebx
+ movl %ecx, %esi
+ roll $8, %ebx
+ addl %eax, %ebx
+ /* 145 */
+ xorl %edx, %esi
+ movl 64(%esp), %edi
+ xorl %ebx, %esi
+ addl %esi, %eax
+ movl %ebx, %esi
+ roll $10, %ecx
+ addl %edi, %eax
+ xorl %ecx, %esi
+ roll $5, %eax
+ addl %ebp, %eax
+ /* 146 */
+ movl 44(%esp), %edi
+ xorl %eax, %esi
+ addl %edi, %ebp
+ roll $10, %ebx
+ addl %esi, %ebp
+ movl %eax, %esi
+ roll $12, %ebp
+ addl %edx, %ebp
+ /* 147 */
+ xorl %ebx, %esi
+ movl 20(%esp), %edi
+ xorl %ebp, %esi
+ addl %esi, %edx
+ movl %ebp, %esi
+ roll $10, %eax
+ addl %edi, %edx
+ xorl %eax, %esi
+ roll $9, %edx
+ addl %ecx, %edx
+ /* 148 */
+ movl 8(%esp), %edi
+ xorl %edx, %esi
+ addl %edi, %ecx
+ roll $10, %ebp
+ addl %esi, %ecx
+ movl %edx, %esi
+ roll $12, %ecx
+ addl %ebx, %ecx
+ /* 149 */
+ xorl %ebp, %esi
+ movl 24(%esp), %edi
+ xorl %ecx, %esi
+ addl %esi, %ebx
+ movl %ecx, %esi
+ roll $10, %edx
+ addl %edi, %ebx
+ xorl %edx, %esi
+ roll $5, %ebx
+ addl %eax, %ebx
+ /* 150 */
+ movl 36(%esp), %edi
+ xorl %ebx, %esi
+ addl %edi, %eax
+ roll $10, %ecx
+ addl %esi, %eax
+ movl %ebx, %esi
+ roll $14, %eax
+ addl %ebp, %eax
+ /* 151 */
+ xorl %ecx, %esi
+ movl 32(%esp), %edi
+ xorl %eax, %esi
+ addl %esi, %ebp
+ movl %eax, %esi
+ roll $10, %ebx
+ addl %edi, %ebp
+ xorl %ebx, %esi
+ roll $6, %ebp
+ addl %edx, %ebp
+ /* 152 */
+ movl 28(%esp), %edi
+ xorl %ebp, %esi
+ addl %edi, %edx
+ roll $10, %eax
+ addl %esi, %edx
+ movl %ebp, %esi
+ roll $8, %edx
+ addl %ecx, %edx
+ /* 153 */
+ xorl %eax, %esi
+ movl 12(%esp), %edi
+ xorl %edx, %esi
+ addl %esi, %ecx
+ movl %edx, %esi
+ roll $10, %ebp
+ addl %edi, %ecx
+ xorl %ebp, %esi
+ roll $13, %ecx
+ addl %ebx, %ecx
+ /* 154 */
+ movl 56(%esp), %edi
+ xorl %ecx, %esi
+ addl %edi, %ebx
+ roll $10, %edx
+ addl %esi, %ebx
+ movl %ecx, %esi
+ roll $6, %ebx
+ addl %eax, %ebx
+ /* 155 */
+ xorl %edx, %esi
+ movl 60(%esp), %edi
+ xorl %ebx, %esi
+ addl %esi, %eax
+ movl %ebx, %esi
+ roll $10, %ecx
+ addl %edi, %eax
+ xorl %ecx, %esi
+ roll $5, %eax
+ addl %ebp, %eax
+ /* 156 */
+ movl 4(%esp), %edi
+ xorl %eax, %esi
+ addl %edi, %ebp
+ roll $10, %ebx
+ addl %esi, %ebp
+ movl %eax, %esi
+ roll $15, %ebp
+ addl %edx, %ebp
+ /* 157 */
+ xorl %ebx, %esi
+ movl 16(%esp), %edi
+ xorl %ebp, %esi
+ addl %esi, %edx
+ movl %ebp, %esi
+ roll $10, %eax
+ addl %edi, %edx
+ xorl %eax, %esi
+ roll $13, %edx
+ addl %ecx, %edx
+ /* 158 */
+ movl 40(%esp), %edi
+ xorl %edx, %esi
+ addl %edi, %ecx
+ roll $10, %ebp
+ addl %esi, %ecx
+ movl %edx, %esi
+ roll $11, %ecx
+ addl %ebx, %ecx
+ /* 159 */
+ xorl %ebp, %esi
+ movl 48(%esp), %edi
+ xorl %ecx, %esi
+ addl %esi, %ebx
+ roll $10, %edx
+ addl %edi, %ebx
+ movl 108(%esp), %edi
+ roll $11, %ebx
+ addl %eax, %ebx
+ movl 4(%edi), %esi
+ addl %esi, %edx
+ movl 76(%esp), %esi
+ addl %esi, %edx
+ movl 8(%edi), %esi
+ addl %esi, %ebp
+ movl 80(%esp), %esi
+ addl %esi, %ebp
+ movl 12(%edi), %esi
+ addl %esi, %eax
+ movl 84(%esp), %esi
+ addl %esi, %eax
+ movl 16(%edi), %esi
+ addl %esi, %ebx
+ movl 68(%esp), %esi
+ addl %esi, %ebx
+ movl (%edi), %esi
+ addl %esi, %ecx
+ movl 72(%esp), %esi
+ addl %esi, %ecx
+ movl %edx, (%edi)
+ movl %ebp, 4(%edi)
+ movl %eax, 8(%edi)
+ movl %ebx, 12(%edi)
+ movl %ecx, 16(%edi)
+ movl (%esp), %edi
+ movl 112(%esp), %esi
+ cmpl %esi, %edi
+ movl 108(%esp), %edi
+ jge .L000start
+ addl $88, %esp
+ popl %ebx
+ popl %ebp
+ popl %edi
+ popl %esi
+ ret
+.ripemd160_block_x86_end:
+ SIZE(ripemd160_block_x86,.ripemd160_block_x86_end-ripemd160_block_x86)
+.ident "desasm.pl"
+#endif /* not PIC */
diff --git a/lib/libmd/i386/sha.S b/lib/libmd/i386/sha.S
new file mode 100644
index 0000000..ae8f89e
--- /dev/null
+++ b/lib/libmd/i386/sha.S
@@ -0,0 +1,1951 @@
+/* -*- Fundamental -*- Emacs' assembler mode hoses this file */
+#ifndef PIC
+/* Run the C pre-processor over this file with one of the following defined
+ * ELF - elf object files,
+ * OUT - a.out object files,
+ * BSDI - BSDI style a.out object files
+ * SOL - Solaris style elf
+ */
+
+#define TYPE(a,b) .type a,b
+#define SIZE(a,b) .size a,b
+
+#if defined(OUT) || defined(BSDI)
+#define sha1_block_x86 _sha1_block_x86
+
+#endif
+
+#ifdef OUT
+#define OK 1
+#define ALIGN 4
+#endif
+
+#ifdef BSDI
+#define OK 1
+#define ALIGN 4
+#undef SIZE
+#undef TYPE
+#define SIZE(a,b)
+#define TYPE(a,b)
+#endif
+
+#if defined(ELF) || defined(SOL)
+#define OK 1
+#define ALIGN 4
+#endif
+
+#ifndef OK
+You need to define one of
+ELF - elf systems - linux-elf, NetBSD and DG-UX
+OUT - a.out systems - linux-a.out and FreeBSD
+SOL - solaris systems, which are elf with strange comment lines
+BSDI - a.out with a very primative version of as.
+#endif
+
+/* Let the Assembler begin :-) */
+ /* Don't even think of reading this code */
+ /* It was automatically generated by sha1-586.pl */
+ /* Which is a perl program used to generate the x86 assember for */
+ /* any of elf, a.out, BSDI,Win32, or Solaris */
+ /* eric <eay@cryptsoft.com> */
+
+ .file "sha1-586.s"
+ .version "01.01"
+gcc2_compiled.:
+.text
+ .p2align ALIGN
+.globl sha1_block_x86
+ TYPE(sha1_block_x86,@function)
+sha1_block_x86:
+ pushl %esi
+ pushl %ebp
+ movl 20(%esp), %eax
+ movl 16(%esp), %esi
+ addl %esi, %eax
+ movl 12(%esp), %ebp
+ pushl %ebx
+ subl $64, %eax
+ pushl %edi
+ movl 4(%ebp), %ebx
+ subl $72, %esp
+ movl 12(%ebp), %edx
+ movl 16(%ebp), %edi
+ movl 8(%ebp), %ecx
+ movl %eax, 68(%esp)
+ /* First we need to setup the X array */
+ movl (%esi), %eax
+.L000start:
+ /* First, load the words onto the stack in network byte order */
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, (%esp)
+ movl 4(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 4(%esp)
+ movl 8(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 8(%esp)
+ movl 12(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 12(%esp)
+ movl 16(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 16(%esp)
+ movl 20(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 20(%esp)
+ movl 24(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 24(%esp)
+ movl 28(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 28(%esp)
+ movl 32(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 32(%esp)
+ movl 36(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 36(%esp)
+ movl 40(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 40(%esp)
+ movl 44(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 44(%esp)
+ movl 48(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 48(%esp)
+ movl 52(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 52(%esp)
+ movl 56(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 56(%esp)
+ movl 60(%esi), %eax
+.byte 15
+.byte 200 /* bswapl %eax */
+ movl %eax, 60(%esp)
+ /* We now have the X array on the stack */
+ /* starting at sp-4 */
+ movl %esi, 64(%esp)
+
+ /* Start processing */
+ movl (%ebp), %eax
+ /* 00_15 0 */
+ movl %ecx, %esi
+ movl %eax, %ebp
+ xorl %edx, %esi
+ roll $5, %ebp
+ andl %ebx, %esi
+ addl %edi, %ebp
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ movl (%esp), %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ xorl %edx, %esi
+ leal 1518500249(%ebp,%edi,1),%ebp
+ movl %ebx, %edi
+ addl %ebp, %esi
+ xorl %ecx, %edi
+ movl %esi, %ebp
+ andl %eax, %edi
+ roll $5, %ebp
+ addl %edx, %ebp
+ movl 4(%esp), %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ xorl %ecx, %edi
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ leal 1518500249(%ebp,%edx,1),%ebp
+ addl %ebp, %edi
+ /* 00_15 2 */
+ movl %eax, %edx
+ movl %edi, %ebp
+ xorl %ebx, %edx
+ roll $5, %ebp
+ andl %esi, %edx
+ addl %ecx, %ebp
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ movl 8(%esp), %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ xorl %ebx, %edx
+ leal 1518500249(%ebp,%ecx,1),%ebp
+ movl %esi, %ecx
+ addl %ebp, %edx
+ xorl %eax, %ecx
+ movl %edx, %ebp
+ andl %edi, %ecx
+ roll $5, %ebp
+ addl %ebx, %ebp
+ movl 12(%esp), %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ xorl %eax, %ecx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ leal 1518500249(%ebp,%ebx,1),%ebp
+ addl %ebp, %ecx
+ /* 00_15 4 */
+ movl %edi, %ebx
+ movl %ecx, %ebp
+ xorl %esi, %ebx
+ roll $5, %ebp
+ andl %edx, %ebx
+ addl %eax, %ebp
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ movl 16(%esp), %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ xorl %esi, %ebx
+ leal 1518500249(%ebp,%eax,1),%ebp
+ movl %edx, %eax
+ addl %ebp, %ebx
+ xorl %edi, %eax
+ movl %ebx, %ebp
+ andl %ecx, %eax
+ roll $5, %ebp
+ addl %esi, %ebp
+ movl 20(%esp), %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ xorl %edi, %eax
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ leal 1518500249(%ebp,%esi,1),%ebp
+ addl %ebp, %eax
+ /* 00_15 6 */
+ movl %ecx, %esi
+ movl %eax, %ebp
+ xorl %edx, %esi
+ roll $5, %ebp
+ andl %ebx, %esi
+ addl %edi, %ebp
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ movl 24(%esp), %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ xorl %edx, %esi
+ leal 1518500249(%ebp,%edi,1),%ebp
+ movl %ebx, %edi
+ addl %ebp, %esi
+ xorl %ecx, %edi
+ movl %esi, %ebp
+ andl %eax, %edi
+ roll $5, %ebp
+ addl %edx, %ebp
+ movl 28(%esp), %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ xorl %ecx, %edi
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ leal 1518500249(%ebp,%edx,1),%ebp
+ addl %ebp, %edi
+ /* 00_15 8 */
+ movl %eax, %edx
+ movl %edi, %ebp
+ xorl %ebx, %edx
+ roll $5, %ebp
+ andl %esi, %edx
+ addl %ecx, %ebp
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ movl 32(%esp), %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ xorl %ebx, %edx
+ leal 1518500249(%ebp,%ecx,1),%ebp
+ movl %esi, %ecx
+ addl %ebp, %edx
+ xorl %eax, %ecx
+ movl %edx, %ebp
+ andl %edi, %ecx
+ roll $5, %ebp
+ addl %ebx, %ebp
+ movl 36(%esp), %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ xorl %eax, %ecx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ leal 1518500249(%ebp,%ebx,1),%ebp
+ addl %ebp, %ecx
+ /* 00_15 10 */
+ movl %edi, %ebx
+ movl %ecx, %ebp
+ xorl %esi, %ebx
+ roll $5, %ebp
+ andl %edx, %ebx
+ addl %eax, %ebp
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ movl 40(%esp), %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ xorl %esi, %ebx
+ leal 1518500249(%ebp,%eax,1),%ebp
+ movl %edx, %eax
+ addl %ebp, %ebx
+ xorl %edi, %eax
+ movl %ebx, %ebp
+ andl %ecx, %eax
+ roll $5, %ebp
+ addl %esi, %ebp
+ movl 44(%esp), %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ xorl %edi, %eax
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ leal 1518500249(%ebp,%esi,1),%ebp
+ addl %ebp, %eax
+ /* 00_15 12 */
+ movl %ecx, %esi
+ movl %eax, %ebp
+ xorl %edx, %esi
+ roll $5, %ebp
+ andl %ebx, %esi
+ addl %edi, %ebp
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ movl 48(%esp), %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ xorl %edx, %esi
+ leal 1518500249(%ebp,%edi,1),%ebp
+ movl %ebx, %edi
+ addl %ebp, %esi
+ xorl %ecx, %edi
+ movl %esi, %ebp
+ andl %eax, %edi
+ roll $5, %ebp
+ addl %edx, %ebp
+ movl 52(%esp), %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ xorl %ecx, %edi
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ leal 1518500249(%ebp,%edx,1),%ebp
+ addl %ebp, %edi
+ /* 00_15 14 */
+ movl %eax, %edx
+ movl %edi, %ebp
+ xorl %ebx, %edx
+ roll $5, %ebp
+ andl %esi, %edx
+ addl %ecx, %ebp
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ movl 56(%esp), %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ xorl %ebx, %edx
+ leal 1518500249(%ebp,%ecx,1),%ebp
+ movl %esi, %ecx
+ addl %ebp, %edx
+ xorl %eax, %ecx
+ movl %edx, %ebp
+ andl %edi, %ecx
+ roll $5, %ebp
+ addl %ebx, %ebp
+ movl 60(%esp), %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ xorl %eax, %ecx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ leal 1518500249(%ebp,%ebx,1),%ebp
+ addl %ebp, %ecx
+ /* 16_19 16 */
+ nop
+ movl (%esp), %ebp
+ movl 8(%esp), %ebx
+ xorl %ebp, %ebx
+ movl 32(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 52(%esp), %ebp
+ xorl %ebp, %ebx
+ movl %edi, %ebp
+.byte 209
+.byte 195 /* roll $1 %ebx */
+ xorl %esi, %ebp
+ movl %ebx, (%esp)
+ andl %edx, %ebp
+ leal 1518500249(%ebx,%eax,1),%ebx
+ xorl %esi, %ebp
+ movl %ecx, %eax
+ addl %ebp, %ebx
+ roll $5, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %eax, %ebx
+ movl 4(%esp), %eax
+ movl 12(%esp), %ebp
+ xorl %ebp, %eax
+ movl 36(%esp), %ebp
+ xorl %ebp, %eax
+ movl 56(%esp), %ebp
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ xorl %ebp, %eax
+.byte 209
+.byte 192 /* roll $1 %eax */
+ movl %edx, %ebp
+ xorl %edi, %ebp
+ movl %eax, 4(%esp)
+ andl %ecx, %ebp
+ leal 1518500249(%eax,%esi,1),%eax
+ xorl %edi, %ebp
+ movl %ebx, %esi
+ roll $5, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %esi, %eax
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %ebp, %eax
+ /* 16_19 18 */
+ movl 8(%esp), %ebp
+ movl 16(%esp), %esi
+ xorl %ebp, %esi
+ movl 40(%esp), %ebp
+ xorl %ebp, %esi
+ movl 60(%esp), %ebp
+ xorl %ebp, %esi
+ movl %ecx, %ebp
+.byte 209
+.byte 198 /* roll $1 %esi */
+ xorl %edx, %ebp
+ movl %esi, 8(%esp)
+ andl %ebx, %ebp
+ leal 1518500249(%esi,%edi,1),%esi
+ xorl %edx, %ebp
+ movl %eax, %edi
+ addl %ebp, %esi
+ roll $5, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %edi, %esi
+ movl 12(%esp), %edi
+ movl 20(%esp), %ebp
+ xorl %ebp, %edi
+ movl 44(%esp), %ebp
+ xorl %ebp, %edi
+ movl (%esp), %ebp
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ xorl %ebp, %edi
+.byte 209
+.byte 199 /* roll $1 %edi */
+ movl %ebx, %ebp
+ xorl %ecx, %ebp
+ movl %edi, 12(%esp)
+ andl %eax, %ebp
+ leal 1518500249(%edi,%edx,1),%edi
+ xorl %ecx, %ebp
+ movl %esi, %edx
+ roll $5, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %edx, %edi
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %ebp, %edi
+ /* 20_39 20 */
+ movl 16(%esp), %edx
+ movl 24(%esp), %ebp
+ xorl %ebp, %edx
+ movl 48(%esp), %ebp
+ xorl %ebp, %edx
+ movl 4(%esp), %ebp
+ xorl %ebp, %edx
+ movl %esi, %ebp
+.byte 209
+.byte 194 /* roll $1 %edx */
+ xorl %eax, %ebp
+ movl %edx, 16(%esp)
+ xorl %ebx, %ebp
+ leal 1859775393(%edx,%ecx,1),%edx
+ movl %edi, %ecx
+ roll $5, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ebp, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ecx, %edx
+ /* 20_39 21 */
+ movl 20(%esp), %ecx
+ movl 28(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 52(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 8(%esp), %ebp
+ xorl %ebp, %ecx
+ movl %edi, %ebp
+.byte 209
+.byte 193 /* roll $1 %ecx */
+ xorl %esi, %ebp
+ movl %ecx, 20(%esp)
+ xorl %eax, %ebp
+ leal 1859775393(%ecx,%ebx,1),%ecx
+ movl %edx, %ebx
+ roll $5, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebp, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebx, %ecx
+ /* 20_39 22 */
+ movl 24(%esp), %ebx
+ movl 32(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 56(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 12(%esp), %ebp
+ xorl %ebp, %ebx
+ movl %edx, %ebp
+.byte 209
+.byte 195 /* roll $1 %ebx */
+ xorl %edi, %ebp
+ movl %ebx, 24(%esp)
+ xorl %esi, %ebp
+ leal 1859775393(%ebx,%eax,1),%ebx
+ movl %ecx, %eax
+ roll $5, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %ebp, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %eax, %ebx
+ /* 20_39 23 */
+ movl 28(%esp), %eax
+ movl 36(%esp), %ebp
+ xorl %ebp, %eax
+ movl 60(%esp), %ebp
+ xorl %ebp, %eax
+ movl 16(%esp), %ebp
+ xorl %ebp, %eax
+ movl %ecx, %ebp
+.byte 209
+.byte 192 /* roll $1 %eax */
+ xorl %edx, %ebp
+ movl %eax, 28(%esp)
+ xorl %edi, %ebp
+ leal 1859775393(%eax,%esi,1),%eax
+ movl %ebx, %esi
+ roll $5, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %ebp, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %esi, %eax
+ /* 20_39 24 */
+ movl 32(%esp), %esi
+ movl 40(%esp), %ebp
+ xorl %ebp, %esi
+ movl (%esp), %ebp
+ xorl %ebp, %esi
+ movl 20(%esp), %ebp
+ xorl %ebp, %esi
+ movl %ebx, %ebp
+.byte 209
+.byte 198 /* roll $1 %esi */
+ xorl %ecx, %ebp
+ movl %esi, 32(%esp)
+ xorl %edx, %ebp
+ leal 1859775393(%esi,%edi,1),%esi
+ movl %eax, %edi
+ roll $5, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %ebp, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %edi, %esi
+ /* 20_39 25 */
+ movl 36(%esp), %edi
+ movl 44(%esp), %ebp
+ xorl %ebp, %edi
+ movl 4(%esp), %ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ xorl %ebp, %edi
+ movl %eax, %ebp
+.byte 209
+.byte 199 /* roll $1 %edi */
+ xorl %ebx, %ebp
+ movl %edi, 36(%esp)
+ xorl %ecx, %ebp
+ leal 1859775393(%edi,%edx,1),%edi
+ movl %esi, %edx
+ roll $5, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %ebp, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %edx, %edi
+ /* 20_39 26 */
+ movl 40(%esp), %edx
+ movl 48(%esp), %ebp
+ xorl %ebp, %edx
+ movl 8(%esp), %ebp
+ xorl %ebp, %edx
+ movl 28(%esp), %ebp
+ xorl %ebp, %edx
+ movl %esi, %ebp
+.byte 209
+.byte 194 /* roll $1 %edx */
+ xorl %eax, %ebp
+ movl %edx, 40(%esp)
+ xorl %ebx, %ebp
+ leal 1859775393(%edx,%ecx,1),%edx
+ movl %edi, %ecx
+ roll $5, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ebp, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ecx, %edx
+ /* 20_39 27 */
+ movl 44(%esp), %ecx
+ movl 52(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 12(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 32(%esp), %ebp
+ xorl %ebp, %ecx
+ movl %edi, %ebp
+.byte 209
+.byte 193 /* roll $1 %ecx */
+ xorl %esi, %ebp
+ movl %ecx, 44(%esp)
+ xorl %eax, %ebp
+ leal 1859775393(%ecx,%ebx,1),%ecx
+ movl %edx, %ebx
+ roll $5, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebp, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebx, %ecx
+ /* 20_39 28 */
+ movl 48(%esp), %ebx
+ movl 56(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 16(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 36(%esp), %ebp
+ xorl %ebp, %ebx
+ movl %edx, %ebp
+.byte 209
+.byte 195 /* roll $1 %ebx */
+ xorl %edi, %ebp
+ movl %ebx, 48(%esp)
+ xorl %esi, %ebp
+ leal 1859775393(%ebx,%eax,1),%ebx
+ movl %ecx, %eax
+ roll $5, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %ebp, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %eax, %ebx
+ /* 20_39 29 */
+ movl 52(%esp), %eax
+ movl 60(%esp), %ebp
+ xorl %ebp, %eax
+ movl 20(%esp), %ebp
+ xorl %ebp, %eax
+ movl 40(%esp), %ebp
+ xorl %ebp, %eax
+ movl %ecx, %ebp
+.byte 209
+.byte 192 /* roll $1 %eax */
+ xorl %edx, %ebp
+ movl %eax, 52(%esp)
+ xorl %edi, %ebp
+ leal 1859775393(%eax,%esi,1),%eax
+ movl %ebx, %esi
+ roll $5, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %ebp, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %esi, %eax
+ /* 20_39 30 */
+ movl 56(%esp), %esi
+ movl (%esp), %ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ xorl %ebp, %esi
+ movl 44(%esp), %ebp
+ xorl %ebp, %esi
+ movl %ebx, %ebp
+.byte 209
+.byte 198 /* roll $1 %esi */
+ xorl %ecx, %ebp
+ movl %esi, 56(%esp)
+ xorl %edx, %ebp
+ leal 1859775393(%esi,%edi,1),%esi
+ movl %eax, %edi
+ roll $5, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %ebp, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %edi, %esi
+ /* 20_39 31 */
+ movl 60(%esp), %edi
+ movl 4(%esp), %ebp
+ xorl %ebp, %edi
+ movl 28(%esp), %ebp
+ xorl %ebp, %edi
+ movl 48(%esp), %ebp
+ xorl %ebp, %edi
+ movl %eax, %ebp
+.byte 209
+.byte 199 /* roll $1 %edi */
+ xorl %ebx, %ebp
+ movl %edi, 60(%esp)
+ xorl %ecx, %ebp
+ leal 1859775393(%edi,%edx,1),%edi
+ movl %esi, %edx
+ roll $5, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %ebp, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %edx, %edi
+ /* 20_39 32 */
+ movl (%esp), %edx
+ movl 8(%esp), %ebp
+ xorl %ebp, %edx
+ movl 32(%esp), %ebp
+ xorl %ebp, %edx
+ movl 52(%esp), %ebp
+ xorl %ebp, %edx
+ movl %esi, %ebp
+.byte 209
+.byte 194 /* roll $1 %edx */
+ xorl %eax, %ebp
+ movl %edx, (%esp)
+ xorl %ebx, %ebp
+ leal 1859775393(%edx,%ecx,1),%edx
+ movl %edi, %ecx
+ roll $5, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ebp, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ecx, %edx
+ /* 20_39 33 */
+ movl 4(%esp), %ecx
+ movl 12(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 36(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 56(%esp), %ebp
+ xorl %ebp, %ecx
+ movl %edi, %ebp
+.byte 209
+.byte 193 /* roll $1 %ecx */
+ xorl %esi, %ebp
+ movl %ecx, 4(%esp)
+ xorl %eax, %ebp
+ leal 1859775393(%ecx,%ebx,1),%ecx
+ movl %edx, %ebx
+ roll $5, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebp, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebx, %ecx
+ /* 20_39 34 */
+ movl 8(%esp), %ebx
+ movl 16(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 40(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 60(%esp), %ebp
+ xorl %ebp, %ebx
+ movl %edx, %ebp
+.byte 209
+.byte 195 /* roll $1 %ebx */
+ xorl %edi, %ebp
+ movl %ebx, 8(%esp)
+ xorl %esi, %ebp
+ leal 1859775393(%ebx,%eax,1),%ebx
+ movl %ecx, %eax
+ roll $5, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %ebp, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %eax, %ebx
+ /* 20_39 35 */
+ movl 12(%esp), %eax
+ movl 20(%esp), %ebp
+ xorl %ebp, %eax
+ movl 44(%esp), %ebp
+ xorl %ebp, %eax
+ movl (%esp), %ebp
+ xorl %ebp, %eax
+ movl %ecx, %ebp
+.byte 209
+.byte 192 /* roll $1 %eax */
+ xorl %edx, %ebp
+ movl %eax, 12(%esp)
+ xorl %edi, %ebp
+ leal 1859775393(%eax,%esi,1),%eax
+ movl %ebx, %esi
+ roll $5, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %ebp, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %esi, %eax
+ /* 20_39 36 */
+ movl 16(%esp), %esi
+ movl 24(%esp), %ebp
+ xorl %ebp, %esi
+ movl 48(%esp), %ebp
+ xorl %ebp, %esi
+ movl 4(%esp), %ebp
+ xorl %ebp, %esi
+ movl %ebx, %ebp
+.byte 209
+.byte 198 /* roll $1 %esi */
+ xorl %ecx, %ebp
+ movl %esi, 16(%esp)
+ xorl %edx, %ebp
+ leal 1859775393(%esi,%edi,1),%esi
+ movl %eax, %edi
+ roll $5, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %ebp, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %edi, %esi
+ /* 20_39 37 */
+ movl 20(%esp), %edi
+ movl 28(%esp), %ebp
+ xorl %ebp, %edi
+ movl 52(%esp), %ebp
+ xorl %ebp, %edi
+ movl 8(%esp), %ebp
+ xorl %ebp, %edi
+ movl %eax, %ebp
+.byte 209
+.byte 199 /* roll $1 %edi */
+ xorl %ebx, %ebp
+ movl %edi, 20(%esp)
+ xorl %ecx, %ebp
+ leal 1859775393(%edi,%edx,1),%edi
+ movl %esi, %edx
+ roll $5, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %ebp, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %edx, %edi
+ /* 20_39 38 */
+ movl 24(%esp), %edx
+ movl 32(%esp), %ebp
+ xorl %ebp, %edx
+ movl 56(%esp), %ebp
+ xorl %ebp, %edx
+ movl 12(%esp), %ebp
+ xorl %ebp, %edx
+ movl %esi, %ebp
+.byte 209
+.byte 194 /* roll $1 %edx */
+ xorl %eax, %ebp
+ movl %edx, 24(%esp)
+ xorl %ebx, %ebp
+ leal 1859775393(%edx,%ecx,1),%edx
+ movl %edi, %ecx
+ roll $5, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ebp, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ecx, %edx
+ /* 20_39 39 */
+ movl 28(%esp), %ecx
+ movl 36(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 60(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 16(%esp), %ebp
+ xorl %ebp, %ecx
+ movl %edi, %ebp
+.byte 209
+.byte 193 /* roll $1 %ecx */
+ xorl %esi, %ebp
+ movl %ecx, 28(%esp)
+ xorl %eax, %ebp
+ leal 1859775393(%ecx,%ebx,1),%ecx
+ movl %edx, %ebx
+ roll $5, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebp, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebx, %ecx
+ /* 40_59 40 */
+ movl 32(%esp), %ebx
+ movl 40(%esp), %ebp
+ xorl %ebp, %ebx
+ movl (%esp), %ebp
+ xorl %ebp, %ebx
+ movl 20(%esp), %ebp
+ xorl %ebp, %ebx
+ movl %edx, %ebp
+.byte 209
+.byte 195 /* roll $1 %ebx */
+ orl %edi, %ebp
+ movl %ebx, 32(%esp)
+ andl %esi, %ebp
+ leal 2400959708(%ebx,%eax,1),%ebx
+ movl %edx, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ andl %edi, %eax
+ orl %eax, %ebp
+ movl %ecx, %eax
+ roll $5, %eax
+ addl %eax, %ebp
+ movl 36(%esp), %eax
+ addl %ebp, %ebx
+ movl 44(%esp), %ebp
+ xorl %ebp, %eax
+ movl 4(%esp), %ebp
+ xorl %ebp, %eax
+ movl 24(%esp), %ebp
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ xorl %ebp, %eax
+.byte 209
+.byte 192 /* roll $1 %eax */
+ movl %ecx, %ebp
+ movl %eax, 36(%esp)
+ orl %edx, %ebp
+ leal 2400959708(%eax,%esi,1),%eax
+ movl %ecx, %esi
+ andl %edi, %ebp
+ andl %edx, %esi
+ orl %esi, %ebp
+ movl %ebx, %esi
+ roll $5, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %esi, %ebp
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %ebp, %eax
+ /* 40_59 41 */
+ /* 40_59 42 */
+ movl 40(%esp), %esi
+ movl 48(%esp), %ebp
+ xorl %ebp, %esi
+ movl 8(%esp), %ebp
+ xorl %ebp, %esi
+ movl 28(%esp), %ebp
+ xorl %ebp, %esi
+ movl %ebx, %ebp
+.byte 209
+.byte 198 /* roll $1 %esi */
+ orl %ecx, %ebp
+ movl %esi, 40(%esp)
+ andl %edx, %ebp
+ leal 2400959708(%esi,%edi,1),%esi
+ movl %ebx, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ andl %ecx, %edi
+ orl %edi, %ebp
+ movl %eax, %edi
+ roll $5, %edi
+ addl %edi, %ebp
+ movl 44(%esp), %edi
+ addl %ebp, %esi
+ movl 52(%esp), %ebp
+ xorl %ebp, %edi
+ movl 12(%esp), %ebp
+ xorl %ebp, %edi
+ movl 32(%esp), %ebp
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ xorl %ebp, %edi
+.byte 209
+.byte 199 /* roll $1 %edi */
+ movl %eax, %ebp
+ movl %edi, 44(%esp)
+ orl %ebx, %ebp
+ leal 2400959708(%edi,%edx,1),%edi
+ movl %eax, %edx
+ andl %ecx, %ebp
+ andl %ebx, %edx
+ orl %edx, %ebp
+ movl %esi, %edx
+ roll $5, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %edx, %ebp
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %ebp, %edi
+ /* 40_59 43 */
+ /* 40_59 44 */
+ movl 48(%esp), %edx
+ movl 56(%esp), %ebp
+ xorl %ebp, %edx
+ movl 16(%esp), %ebp
+ xorl %ebp, %edx
+ movl 36(%esp), %ebp
+ xorl %ebp, %edx
+ movl %esi, %ebp
+.byte 209
+.byte 194 /* roll $1 %edx */
+ orl %eax, %ebp
+ movl %edx, 48(%esp)
+ andl %ebx, %ebp
+ leal 2400959708(%edx,%ecx,1),%edx
+ movl %esi, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ andl %eax, %ecx
+ orl %ecx, %ebp
+ movl %edi, %ecx
+ roll $5, %ecx
+ addl %ecx, %ebp
+ movl 52(%esp), %ecx
+ addl %ebp, %edx
+ movl 60(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 20(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 40(%esp), %ebp
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ xorl %ebp, %ecx
+.byte 209
+.byte 193 /* roll $1 %ecx */
+ movl %edi, %ebp
+ movl %ecx, 52(%esp)
+ orl %esi, %ebp
+ leal 2400959708(%ecx,%ebx,1),%ecx
+ movl %edi, %ebx
+ andl %eax, %ebp
+ andl %esi, %ebx
+ orl %ebx, %ebp
+ movl %edx, %ebx
+ roll $5, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebx, %ebp
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebp, %ecx
+ /* 40_59 45 */
+ /* 40_59 46 */
+ movl 56(%esp), %ebx
+ movl (%esp), %ebp
+ xorl %ebp, %ebx
+ movl 24(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 44(%esp), %ebp
+ xorl %ebp, %ebx
+ movl %edx, %ebp
+.byte 209
+.byte 195 /* roll $1 %ebx */
+ orl %edi, %ebp
+ movl %ebx, 56(%esp)
+ andl %esi, %ebp
+ leal 2400959708(%ebx,%eax,1),%ebx
+ movl %edx, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ andl %edi, %eax
+ orl %eax, %ebp
+ movl %ecx, %eax
+ roll $5, %eax
+ addl %eax, %ebp
+ movl 60(%esp), %eax
+ addl %ebp, %ebx
+ movl 4(%esp), %ebp
+ xorl %ebp, %eax
+ movl 28(%esp), %ebp
+ xorl %ebp, %eax
+ movl 48(%esp), %ebp
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ xorl %ebp, %eax
+.byte 209
+.byte 192 /* roll $1 %eax */
+ movl %ecx, %ebp
+ movl %eax, 60(%esp)
+ orl %edx, %ebp
+ leal 2400959708(%eax,%esi,1),%eax
+ movl %ecx, %esi
+ andl %edi, %ebp
+ andl %edx, %esi
+ orl %esi, %ebp
+ movl %ebx, %esi
+ roll $5, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %esi, %ebp
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %ebp, %eax
+ /* 40_59 47 */
+ /* 40_59 48 */
+ movl (%esp), %esi
+ movl 8(%esp), %ebp
+ xorl %ebp, %esi
+ movl 32(%esp), %ebp
+ xorl %ebp, %esi
+ movl 52(%esp), %ebp
+ xorl %ebp, %esi
+ movl %ebx, %ebp
+.byte 209
+.byte 198 /* roll $1 %esi */
+ orl %ecx, %ebp
+ movl %esi, (%esp)
+ andl %edx, %ebp
+ leal 2400959708(%esi,%edi,1),%esi
+ movl %ebx, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ andl %ecx, %edi
+ orl %edi, %ebp
+ movl %eax, %edi
+ roll $5, %edi
+ addl %edi, %ebp
+ movl 4(%esp), %edi
+ addl %ebp, %esi
+ movl 12(%esp), %ebp
+ xorl %ebp, %edi
+ movl 36(%esp), %ebp
+ xorl %ebp, %edi
+ movl 56(%esp), %ebp
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ xorl %ebp, %edi
+.byte 209
+.byte 199 /* roll $1 %edi */
+ movl %eax, %ebp
+ movl %edi, 4(%esp)
+ orl %ebx, %ebp
+ leal 2400959708(%edi,%edx,1),%edi
+ movl %eax, %edx
+ andl %ecx, %ebp
+ andl %ebx, %edx
+ orl %edx, %ebp
+ movl %esi, %edx
+ roll $5, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %edx, %ebp
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %ebp, %edi
+ /* 40_59 49 */
+ /* 40_59 50 */
+ movl 8(%esp), %edx
+ movl 16(%esp), %ebp
+ xorl %ebp, %edx
+ movl 40(%esp), %ebp
+ xorl %ebp, %edx
+ movl 60(%esp), %ebp
+ xorl %ebp, %edx
+ movl %esi, %ebp
+.byte 209
+.byte 194 /* roll $1 %edx */
+ orl %eax, %ebp
+ movl %edx, 8(%esp)
+ andl %ebx, %ebp
+ leal 2400959708(%edx,%ecx,1),%edx
+ movl %esi, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ andl %eax, %ecx
+ orl %ecx, %ebp
+ movl %edi, %ecx
+ roll $5, %ecx
+ addl %ecx, %ebp
+ movl 12(%esp), %ecx
+ addl %ebp, %edx
+ movl 20(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 44(%esp), %ebp
+ xorl %ebp, %ecx
+ movl (%esp), %ebp
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ xorl %ebp, %ecx
+.byte 209
+.byte 193 /* roll $1 %ecx */
+ movl %edi, %ebp
+ movl %ecx, 12(%esp)
+ orl %esi, %ebp
+ leal 2400959708(%ecx,%ebx,1),%ecx
+ movl %edi, %ebx
+ andl %eax, %ebp
+ andl %esi, %ebx
+ orl %ebx, %ebp
+ movl %edx, %ebx
+ roll $5, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebx, %ebp
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebp, %ecx
+ /* 40_59 51 */
+ /* 40_59 52 */
+ movl 16(%esp), %ebx
+ movl 24(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 48(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 4(%esp), %ebp
+ xorl %ebp, %ebx
+ movl %edx, %ebp
+.byte 209
+.byte 195 /* roll $1 %ebx */
+ orl %edi, %ebp
+ movl %ebx, 16(%esp)
+ andl %esi, %ebp
+ leal 2400959708(%ebx,%eax,1),%ebx
+ movl %edx, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ andl %edi, %eax
+ orl %eax, %ebp
+ movl %ecx, %eax
+ roll $5, %eax
+ addl %eax, %ebp
+ movl 20(%esp), %eax
+ addl %ebp, %ebx
+ movl 28(%esp), %ebp
+ xorl %ebp, %eax
+ movl 52(%esp), %ebp
+ xorl %ebp, %eax
+ movl 8(%esp), %ebp
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ xorl %ebp, %eax
+.byte 209
+.byte 192 /* roll $1 %eax */
+ movl %ecx, %ebp
+ movl %eax, 20(%esp)
+ orl %edx, %ebp
+ leal 2400959708(%eax,%esi,1),%eax
+ movl %ecx, %esi
+ andl %edi, %ebp
+ andl %edx, %esi
+ orl %esi, %ebp
+ movl %ebx, %esi
+ roll $5, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %esi, %ebp
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %ebp, %eax
+ /* 40_59 53 */
+ /* 40_59 54 */
+ movl 24(%esp), %esi
+ movl 32(%esp), %ebp
+ xorl %ebp, %esi
+ movl 56(%esp), %ebp
+ xorl %ebp, %esi
+ movl 12(%esp), %ebp
+ xorl %ebp, %esi
+ movl %ebx, %ebp
+.byte 209
+.byte 198 /* roll $1 %esi */
+ orl %ecx, %ebp
+ movl %esi, 24(%esp)
+ andl %edx, %ebp
+ leal 2400959708(%esi,%edi,1),%esi
+ movl %ebx, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ andl %ecx, %edi
+ orl %edi, %ebp
+ movl %eax, %edi
+ roll $5, %edi
+ addl %edi, %ebp
+ movl 28(%esp), %edi
+ addl %ebp, %esi
+ movl 36(%esp), %ebp
+ xorl %ebp, %edi
+ movl 60(%esp), %ebp
+ xorl %ebp, %edi
+ movl 16(%esp), %ebp
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ xorl %ebp, %edi
+.byte 209
+.byte 199 /* roll $1 %edi */
+ movl %eax, %ebp
+ movl %edi, 28(%esp)
+ orl %ebx, %ebp
+ leal 2400959708(%edi,%edx,1),%edi
+ movl %eax, %edx
+ andl %ecx, %ebp
+ andl %ebx, %edx
+ orl %edx, %ebp
+ movl %esi, %edx
+ roll $5, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %edx, %ebp
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %ebp, %edi
+ /* 40_59 55 */
+ /* 40_59 56 */
+ movl 32(%esp), %edx
+ movl 40(%esp), %ebp
+ xorl %ebp, %edx
+ movl (%esp), %ebp
+ xorl %ebp, %edx
+ movl 20(%esp), %ebp
+ xorl %ebp, %edx
+ movl %esi, %ebp
+.byte 209
+.byte 194 /* roll $1 %edx */
+ orl %eax, %ebp
+ movl %edx, 32(%esp)
+ andl %ebx, %ebp
+ leal 2400959708(%edx,%ecx,1),%edx
+ movl %esi, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ andl %eax, %ecx
+ orl %ecx, %ebp
+ movl %edi, %ecx
+ roll $5, %ecx
+ addl %ecx, %ebp
+ movl 36(%esp), %ecx
+ addl %ebp, %edx
+ movl 44(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 4(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 24(%esp), %ebp
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ xorl %ebp, %ecx
+.byte 209
+.byte 193 /* roll $1 %ecx */
+ movl %edi, %ebp
+ movl %ecx, 36(%esp)
+ orl %esi, %ebp
+ leal 2400959708(%ecx,%ebx,1),%ecx
+ movl %edi, %ebx
+ andl %eax, %ebp
+ andl %esi, %ebx
+ orl %ebx, %ebp
+ movl %edx, %ebx
+ roll $5, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebx, %ebp
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebp, %ecx
+ /* 40_59 57 */
+ /* 40_59 58 */
+ movl 40(%esp), %ebx
+ movl 48(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 8(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 28(%esp), %ebp
+ xorl %ebp, %ebx
+ movl %edx, %ebp
+.byte 209
+.byte 195 /* roll $1 %ebx */
+ orl %edi, %ebp
+ movl %ebx, 40(%esp)
+ andl %esi, %ebp
+ leal 2400959708(%ebx,%eax,1),%ebx
+ movl %edx, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ andl %edi, %eax
+ orl %eax, %ebp
+ movl %ecx, %eax
+ roll $5, %eax
+ addl %eax, %ebp
+ movl 44(%esp), %eax
+ addl %ebp, %ebx
+ movl 52(%esp), %ebp
+ xorl %ebp, %eax
+ movl 12(%esp), %ebp
+ xorl %ebp, %eax
+ movl 32(%esp), %ebp
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ xorl %ebp, %eax
+.byte 209
+.byte 192 /* roll $1 %eax */
+ movl %ecx, %ebp
+ movl %eax, 44(%esp)
+ orl %edx, %ebp
+ leal 2400959708(%eax,%esi,1),%eax
+ movl %ecx, %esi
+ andl %edi, %ebp
+ andl %edx, %esi
+ orl %esi, %ebp
+ movl %ebx, %esi
+ roll $5, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %esi, %ebp
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %ebp, %eax
+ /* 40_59 59 */
+ /* 20_39 60 */
+ movl 48(%esp), %esi
+ movl 56(%esp), %ebp
+ xorl %ebp, %esi
+ movl 16(%esp), %ebp
+ xorl %ebp, %esi
+ movl 36(%esp), %ebp
+ xorl %ebp, %esi
+ movl %ebx, %ebp
+.byte 209
+.byte 198 /* roll $1 %esi */
+ xorl %ecx, %ebp
+ movl %esi, 48(%esp)
+ xorl %edx, %ebp
+ leal 3395469782(%esi,%edi,1),%esi
+ movl %eax, %edi
+ roll $5, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %ebp, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %edi, %esi
+ /* 20_39 61 */
+ movl 52(%esp), %edi
+ movl 60(%esp), %ebp
+ xorl %ebp, %edi
+ movl 20(%esp), %ebp
+ xorl %ebp, %edi
+ movl 40(%esp), %ebp
+ xorl %ebp, %edi
+ movl %eax, %ebp
+.byte 209
+.byte 199 /* roll $1 %edi */
+ xorl %ebx, %ebp
+ movl %edi, 52(%esp)
+ xorl %ecx, %ebp
+ leal 3395469782(%edi,%edx,1),%edi
+ movl %esi, %edx
+ roll $5, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %ebp, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %edx, %edi
+ /* 20_39 62 */
+ movl 56(%esp), %edx
+ movl (%esp), %ebp
+ xorl %ebp, %edx
+ movl 24(%esp), %ebp
+ xorl %ebp, %edx
+ movl 44(%esp), %ebp
+ xorl %ebp, %edx
+ movl %esi, %ebp
+.byte 209
+.byte 194 /* roll $1 %edx */
+ xorl %eax, %ebp
+ movl %edx, 56(%esp)
+ xorl %ebx, %ebp
+ leal 3395469782(%edx,%ecx,1),%edx
+ movl %edi, %ecx
+ roll $5, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ebp, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ecx, %edx
+ /* 20_39 63 */
+ movl 60(%esp), %ecx
+ movl 4(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 28(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 48(%esp), %ebp
+ xorl %ebp, %ecx
+ movl %edi, %ebp
+.byte 209
+.byte 193 /* roll $1 %ecx */
+ xorl %esi, %ebp
+ movl %ecx, 60(%esp)
+ xorl %eax, %ebp
+ leal 3395469782(%ecx,%ebx,1),%ecx
+ movl %edx, %ebx
+ roll $5, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebp, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebx, %ecx
+ /* 20_39 64 */
+ movl (%esp), %ebx
+ movl 8(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 32(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 52(%esp), %ebp
+ xorl %ebp, %ebx
+ movl %edx, %ebp
+.byte 209
+.byte 195 /* roll $1 %ebx */
+ xorl %edi, %ebp
+ movl %ebx, (%esp)
+ xorl %esi, %ebp
+ leal 3395469782(%ebx,%eax,1),%ebx
+ movl %ecx, %eax
+ roll $5, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %ebp, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %eax, %ebx
+ /* 20_39 65 */
+ movl 4(%esp), %eax
+ movl 12(%esp), %ebp
+ xorl %ebp, %eax
+ movl 36(%esp), %ebp
+ xorl %ebp, %eax
+ movl 56(%esp), %ebp
+ xorl %ebp, %eax
+ movl %ecx, %ebp
+.byte 209
+.byte 192 /* roll $1 %eax */
+ xorl %edx, %ebp
+ movl %eax, 4(%esp)
+ xorl %edi, %ebp
+ leal 3395469782(%eax,%esi,1),%eax
+ movl %ebx, %esi
+ roll $5, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %ebp, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %esi, %eax
+ /* 20_39 66 */
+ movl 8(%esp), %esi
+ movl 16(%esp), %ebp
+ xorl %ebp, %esi
+ movl 40(%esp), %ebp
+ xorl %ebp, %esi
+ movl 60(%esp), %ebp
+ xorl %ebp, %esi
+ movl %ebx, %ebp
+.byte 209
+.byte 198 /* roll $1 %esi */
+ xorl %ecx, %ebp
+ movl %esi, 8(%esp)
+ xorl %edx, %ebp
+ leal 3395469782(%esi,%edi,1),%esi
+ movl %eax, %edi
+ roll $5, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %ebp, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %edi, %esi
+ /* 20_39 67 */
+ movl 12(%esp), %edi
+ movl 20(%esp), %ebp
+ xorl %ebp, %edi
+ movl 44(%esp), %ebp
+ xorl %ebp, %edi
+ movl (%esp), %ebp
+ xorl %ebp, %edi
+ movl %eax, %ebp
+.byte 209
+.byte 199 /* roll $1 %edi */
+ xorl %ebx, %ebp
+ movl %edi, 12(%esp)
+ xorl %ecx, %ebp
+ leal 3395469782(%edi,%edx,1),%edi
+ movl %esi, %edx
+ roll $5, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %ebp, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %edx, %edi
+ /* 20_39 68 */
+ movl 16(%esp), %edx
+ movl 24(%esp), %ebp
+ xorl %ebp, %edx
+ movl 48(%esp), %ebp
+ xorl %ebp, %edx
+ movl 4(%esp), %ebp
+ xorl %ebp, %edx
+ movl %esi, %ebp
+.byte 209
+.byte 194 /* roll $1 %edx */
+ xorl %eax, %ebp
+ movl %edx, 16(%esp)
+ xorl %ebx, %ebp
+ leal 3395469782(%edx,%ecx,1),%edx
+ movl %edi, %ecx
+ roll $5, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ebp, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ecx, %edx
+ /* 20_39 69 */
+ movl 20(%esp), %ecx
+ movl 28(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 52(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 8(%esp), %ebp
+ xorl %ebp, %ecx
+ movl %edi, %ebp
+.byte 209
+.byte 193 /* roll $1 %ecx */
+ xorl %esi, %ebp
+ movl %ecx, 20(%esp)
+ xorl %eax, %ebp
+ leal 3395469782(%ecx,%ebx,1),%ecx
+ movl %edx, %ebx
+ roll $5, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebp, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebx, %ecx
+ /* 20_39 70 */
+ movl 24(%esp), %ebx
+ movl 32(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 56(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 12(%esp), %ebp
+ xorl %ebp, %ebx
+ movl %edx, %ebp
+.byte 209
+.byte 195 /* roll $1 %ebx */
+ xorl %edi, %ebp
+ movl %ebx, 24(%esp)
+ xorl %esi, %ebp
+ leal 3395469782(%ebx,%eax,1),%ebx
+ movl %ecx, %eax
+ roll $5, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %ebp, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %eax, %ebx
+ /* 20_39 71 */
+ movl 28(%esp), %eax
+ movl 36(%esp), %ebp
+ xorl %ebp, %eax
+ movl 60(%esp), %ebp
+ xorl %ebp, %eax
+ movl 16(%esp), %ebp
+ xorl %ebp, %eax
+ movl %ecx, %ebp
+.byte 209
+.byte 192 /* roll $1 %eax */
+ xorl %edx, %ebp
+ movl %eax, 28(%esp)
+ xorl %edi, %ebp
+ leal 3395469782(%eax,%esi,1),%eax
+ movl %ebx, %esi
+ roll $5, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %ebp, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %esi, %eax
+ /* 20_39 72 */
+ movl 32(%esp), %esi
+ movl 40(%esp), %ebp
+ xorl %ebp, %esi
+ movl (%esp), %ebp
+ xorl %ebp, %esi
+ movl 20(%esp), %ebp
+ xorl %ebp, %esi
+ movl %ebx, %ebp
+.byte 209
+.byte 198 /* roll $1 %esi */
+ xorl %ecx, %ebp
+ movl %esi, 32(%esp)
+ xorl %edx, %ebp
+ leal 3395469782(%esi,%edi,1),%esi
+ movl %eax, %edi
+ roll $5, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %ebp, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %edi, %esi
+ /* 20_39 73 */
+ movl 36(%esp), %edi
+ movl 44(%esp), %ebp
+ xorl %ebp, %edi
+ movl 4(%esp), %ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ xorl %ebp, %edi
+ movl %eax, %ebp
+.byte 209
+.byte 199 /* roll $1 %edi */
+ xorl %ebx, %ebp
+ movl %edi, 36(%esp)
+ xorl %ecx, %ebp
+ leal 3395469782(%edi,%edx,1),%edi
+ movl %esi, %edx
+ roll $5, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %ebp, %edx
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %edx, %edi
+ /* 20_39 74 */
+ movl 40(%esp), %edx
+ movl 48(%esp), %ebp
+ xorl %ebp, %edx
+ movl 8(%esp), %ebp
+ xorl %ebp, %edx
+ movl 28(%esp), %ebp
+ xorl %ebp, %edx
+ movl %esi, %ebp
+.byte 209
+.byte 194 /* roll $1 %edx */
+ xorl %eax, %ebp
+ movl %edx, 40(%esp)
+ xorl %ebx, %ebp
+ leal 3395469782(%edx,%ecx,1),%edx
+ movl %edi, %ecx
+ roll $5, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ebp, %ecx
+.byte 209
+.byte 206 /* rorl $1 %esi */
+ addl %ecx, %edx
+ /* 20_39 75 */
+ movl 44(%esp), %ecx
+ movl 52(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 12(%esp), %ebp
+ xorl %ebp, %ecx
+ movl 32(%esp), %ebp
+ xorl %ebp, %ecx
+ movl %edi, %ebp
+.byte 209
+.byte 193 /* roll $1 %ecx */
+ xorl %esi, %ebp
+ movl %ecx, 44(%esp)
+ xorl %eax, %ebp
+ leal 3395469782(%ecx,%ebx,1),%ecx
+ movl %edx, %ebx
+ roll $5, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebp, %ebx
+.byte 209
+.byte 207 /* rorl $1 %edi */
+ addl %ebx, %ecx
+ /* 20_39 76 */
+ movl 48(%esp), %ebx
+ movl 56(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 16(%esp), %ebp
+ xorl %ebp, %ebx
+ movl 36(%esp), %ebp
+ xorl %ebp, %ebx
+ movl %edx, %ebp
+.byte 209
+.byte 195 /* roll $1 %ebx */
+ xorl %edi, %ebp
+ movl %ebx, 48(%esp)
+ xorl %esi, %ebp
+ leal 3395469782(%ebx,%eax,1),%ebx
+ movl %ecx, %eax
+ roll $5, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %ebp, %eax
+.byte 209
+.byte 202 /* rorl $1 %edx */
+ addl %eax, %ebx
+ /* 20_39 77 */
+ movl 52(%esp), %eax
+ movl 60(%esp), %ebp
+ xorl %ebp, %eax
+ movl 20(%esp), %ebp
+ xorl %ebp, %eax
+ movl 40(%esp), %ebp
+ xorl %ebp, %eax
+ movl %ecx, %ebp
+.byte 209
+.byte 192 /* roll $1 %eax */
+ xorl %edx, %ebp
+ movl %eax, 52(%esp)
+ xorl %edi, %ebp
+ leal 3395469782(%eax,%esi,1),%eax
+ movl %ebx, %esi
+ roll $5, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %ebp, %esi
+.byte 209
+.byte 201 /* rorl $1 %ecx */
+ addl %esi, %eax
+ /* 20_39 78 */
+ movl 56(%esp), %esi
+ movl (%esp), %ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ xorl %ebp, %esi
+ movl 44(%esp), %ebp
+ xorl %ebp, %esi
+ movl %ebx, %ebp
+.byte 209
+.byte 198 /* roll $1 %esi */
+ xorl %ecx, %ebp
+ movl %esi, 56(%esp)
+ xorl %edx, %ebp
+ leal 3395469782(%esi,%edi,1),%esi
+ movl %eax, %edi
+ roll $5, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %ebp, %edi
+.byte 209
+.byte 203 /* rorl $1 %ebx */
+ addl %edi, %esi
+ /* 20_39 79 */
+ movl 60(%esp), %edi
+ movl 4(%esp), %ebp
+ xorl %ebp, %edi
+ movl 28(%esp), %ebp
+ xorl %ebp, %edi
+ movl 48(%esp), %ebp
+ xorl %ebp, %edi
+ movl %eax, %ebp
+.byte 209
+.byte 199 /* roll $1 %edi */
+ xorl %ebx, %ebp
+ movl %edi, 60(%esp)
+ xorl %ecx, %ebp
+ leal 3395469782(%edi,%edx,1),%edi
+ movl %esi, %edx
+ roll $5, %edx
+ addl %ebp, %edx
+ movl 92(%esp), %ebp
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ addl %edx, %edi
+.byte 209
+.byte 200 /* rorl $1 %eax */
+ /* End processing */
+
+ movl 12(%ebp), %edx
+ addl %ebx, %edx
+ movl 4(%ebp), %ebx
+ addl %esi, %ebx
+ movl %eax, %esi
+ movl (%ebp), %eax
+ movl %edx, 12(%ebp)
+ addl %edi, %eax
+ movl 16(%ebp), %edi
+ addl %ecx, %edi
+ movl 8(%ebp), %ecx
+ addl %esi, %ecx
+ movl %eax, (%ebp)
+ movl 64(%esp), %esi
+ movl %ecx, 8(%ebp)
+ addl $64, %esi
+ movl 68(%esp), %eax
+ movl %edi, 16(%ebp)
+ cmpl %esi, %eax
+ movl %ebx, 4(%ebp)
+ jl .L001end
+ movl (%esi), %eax
+ jmp .L000start
+.L001end:
+ addl $72, %esp
+ popl %edi
+ popl %ebx
+ popl %ebp
+ popl %esi
+ ret
+.sha1_block_x86_end:
+ SIZE(sha1_block_x86,.sha1_block_x86_end-sha1_block_x86)
+.ident "desasm.pl"
+#endif
diff --git a/lib/libmd/md2.copyright b/lib/libmd/md2.copyright
new file mode 100644
index 0000000..acef7ba
--- /dev/null
+++ b/lib/libmd/md2.copyright
@@ -0,0 +1,17 @@
+.\" $FreeBSD$
+Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+rights reserved.
+.Pp
+License to copy and use this software is granted for
+non-commercial Internet Privacy-Enhanced Mail provided that it is
+identified as the "RSA Data Security, Inc. MD2 Message Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+.Pp
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+.Pp
+These notices must be retained in any copies of any part of this
+documentation and/or software.
diff --git a/lib/libmd/md2.h b/lib/libmd/md2.h
new file mode 100644
index 0000000..8215038
--- /dev/null
+++ b/lib/libmd/md2.h
@@ -0,0 +1,45 @@
+/* MD2.H - header file for MD2C.C
+ * $FreeBSD$
+ */
+
+/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+ rights reserved.
+
+ License to copy and use this software is granted for
+ non-commercial Internet Privacy-Enhanced Mail provided that it is
+ identified as the "RSA Data Security, Inc. MD2 Message Digest
+ Algorithm" in all material mentioning or referencing this software
+ or this function.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+ */
+
+#ifndef _MD2_H_
+#define _MD2_H_
+
+typedef struct MD2Context {
+ unsigned char state[16]; /* state */
+ unsigned char checksum[16]; /* checksum */
+ unsigned int count; /* number of bytes, modulo 16 */
+ unsigned char buffer[16]; /* input buffer */
+} MD2_CTX;
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+void MD2Init(MD2_CTX *);
+void MD2Update(MD2_CTX *, const unsigned char *, unsigned int);
+void MD2Pad(MD2_CTX *);
+void MD2Final(unsigned char [16], MD2_CTX *);
+char * MD2End(MD2_CTX *, char *);
+char * MD2File(const char *, char *);
+char * MD2Data(const unsigned char *, unsigned int, char *);
+__END_DECLS
+
+#endif /* _MD2_H_ */
diff --git a/lib/libmd/md2c.c b/lib/libmd/md2c.c
new file mode 100644
index 0000000..97edfbe
--- /dev/null
+++ b/lib/libmd/md2c.c
@@ -0,0 +1,208 @@
+/* MD2C.C - RSA Data Security, Inc., MD2 message-digest algorithm
+ * $FreeBSD$
+ */
+
+/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+ rights reserved.
+
+ License to copy and use this software is granted for
+ non-commercial Internet Privacy-Enhanced Mail provided that it is
+ identified as the "RSA Data Security, Inc. MD2 Message Digest
+ Algorithm" in all material mentioning or referencing this software
+ or this function.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+ */
+
+#include "md2.h"
+#include <string.h>
+#include <sys/types.h>
+
+
+typedef unsigned char *POINTER;
+typedef u_int16_t UINT2;
+typedef u_int32_t UINT4;
+
+#define PROTO_LIST(list) list
+
+static void MD2Transform PROTO_LIST
+ ((unsigned char [16], unsigned char [16], const unsigned char [16]));
+
+/* Permutation of 0..255 constructed from the digits of pi. It gives a
+ "random" nonlinear byte substitution operation.
+ */
+static unsigned char PI_SUBST[256] = {
+ 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
+ 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
+ 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
+ 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
+ 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
+ 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
+ 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
+ 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
+ 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
+ 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
+ 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
+ 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
+ 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
+ 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
+ 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
+ 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
+ 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
+ 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
+};
+
+static unsigned char *PADDING[] = {
+ (unsigned char *)"",
+ (unsigned char *)"\001",
+ (unsigned char *)"\002\002",
+ (unsigned char *)"\003\003\003",
+ (unsigned char *)"\004\004\004\004",
+ (unsigned char *)"\005\005\005\005\005",
+ (unsigned char *)"\006\006\006\006\006\006",
+ (unsigned char *)"\007\007\007\007\007\007\007",
+ (unsigned char *)"\010\010\010\010\010\010\010\010",
+ (unsigned char *)"\011\011\011\011\011\011\011\011\011",
+ (unsigned char *)"\012\012\012\012\012\012\012\012\012\012",
+ (unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013",
+ (unsigned char *)"\014\014\014\014\014\014\014\014\014\014\014\014",
+ (unsigned char *)
+ "\015\015\015\015\015\015\015\015\015\015\015\015\015",
+ (unsigned char *)
+ "\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
+ (unsigned char *)
+ "\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
+ (unsigned char *)
+ "\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020"
+};
+
+/* MD2 initialization. Begins an MD2 operation, writing a new context.
+ */
+void MD2Init (context)
+MD2_CTX *context; /* context */
+{
+ context->count = 0;
+ memset ((POINTER)context->state, 0, sizeof (context->state));
+ memset
+ ((POINTER)context->checksum, 0, sizeof (context->checksum));
+}
+
+/* MD2 block update operation. Continues an MD2 message-digest
+ operation, processing another message block, and updating the
+ context.
+ */
+void MD2Update (context, input, inputLen)
+MD2_CTX *context; /* context */
+const unsigned char *input; /* input block */
+unsigned int inputLen; /* length of input block */
+{
+ unsigned int i, index, partLen;
+
+ /* Update number of bytes mod 16 */
+ index = context->count;
+ context->count = (index + inputLen) & 0xf;
+
+ partLen = 16 - index;
+
+ /* Transform as many times as possible.
+ */
+ if (inputLen >= partLen) {
+ memcpy
+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD2Transform (context->state, context->checksum, context->buffer);
+
+ for (i = partLen; i + 15 < inputLen; i += 16)
+ MD2Transform (context->state, context->checksum, &input[i]);
+
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ memcpy
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
+ inputLen-i);
+}
+
+/* MD2 padding.
+ */
+void MD2Pad (context)
+MD2_CTX *context; /* context */
+{
+ unsigned int index, padLen;
+
+ /* Pad out to multiple of 16.
+ */
+ index = context->count;
+ padLen = 16 - index;
+ MD2Update (context, PADDING[padLen], padLen);
+
+ /* Extend with checksum */
+ MD2Update (context, context->checksum, 16);
+}
+
+/* MD2 finalization. Ends an MD2 message-digest operation, writing the
+ message digest and zeroizing the context.
+ */
+void MD2Final (digest, context)
+unsigned char digest[16]; /* message digest */
+MD2_CTX *context; /* context */
+{
+ /* Do padding */
+ MD2Pad (context);
+
+ /* Store state in digest */
+ memcpy ((POINTER)digest, (POINTER)context->state, 16);
+
+ /* Zeroize sensitive information.
+ */
+ memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD2 basic transformation. Transforms state and updates checksum
+ based on block.
+ */
+static void MD2Transform (state, checksum, block)
+unsigned char state[16];
+unsigned char checksum[16];
+const unsigned char block[16];
+{
+ unsigned int i, j, t;
+ unsigned char x[48];
+
+ /* Form encryption block from state, block, state ^ block.
+ */
+ memcpy ((POINTER)x, (POINTER)state, 16);
+ memcpy ((POINTER)x+16, (POINTER)block, 16);
+ for (i = 0; i < 16; i++)
+ x[i+32] = state[i] ^ block[i];
+
+ /* Encrypt block (18 rounds).
+ */
+ t = 0;
+ for (i = 0; i < 18; i++) {
+ for (j = 0; j < 48; j++)
+ t = x[j] ^= PI_SUBST[t];
+ t = (t + i) & 0xff;
+ }
+
+ /* Save new state */
+ memcpy ((POINTER)state, (POINTER)x, 16);
+
+ /* Update checksum.
+ */
+ t = checksum[15];
+ for (i = 0; i < 16; i++)
+ t = checksum[i] ^= PI_SUBST[block[i] ^ t];
+
+ /* Zeroize sensitive information.
+ */
+ memset ((POINTER)x, 0, sizeof (x));
+}
diff --git a/lib/libmd/md4.copyright b/lib/libmd/md4.copyright
new file mode 100644
index 0000000..e450207
--- /dev/null
+++ b/lib/libmd/md4.copyright
@@ -0,0 +1,20 @@
+.\" $FreeBSD$
+Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+.Pp
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD4 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+.Pp
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+.Pp
+These notices must be retained in any copies of any part of this
+documentation and/or software.
diff --git a/lib/libmd/md4.h b/lib/libmd/md4.h
new file mode 100644
index 0000000..5a648c8
--- /dev/null
+++ b/lib/libmd/md4.h
@@ -0,0 +1,47 @@
+/* MD4.H - header file for MD4C.C
+ * $FreeBSD$
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ rights reserved.
+
+ License to copy and use this software is granted provided that it
+ is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ Algorithm" in all material mentioning or referencing this software
+ or this function.
+ License is also granted to make and use derivative works provided
+ that such works are identified as "derived from the RSA Data
+ Security, Inc. MD4 Message-Digest Algorithm" in all material
+ mentioning or referencing the derived work.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+ */
+
+#ifndef _MD4_H_
+#define _MD4_H_
+/* MD4 context. */
+typedef struct MD4Context {
+ u_int32_t state[4]; /* state (ABCD) */
+ u_int32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+} MD4_CTX;
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+void MD4Init(MD4_CTX *);
+void MD4Update(MD4_CTX *, const unsigned char *, unsigned int);
+void MD4Pad(MD4_CTX *);
+void MD4Final(unsigned char [16], MD4_CTX *);
+char * MD4End(MD4_CTX *, char *);
+char * MD4File(const char *, char *);
+char * MD4Data(const unsigned char *, unsigned int, char *);
+__END_DECLS
+
+#endif /* _MD4_H_ */
diff --git a/lib/libmd/md4c.c b/lib/libmd/md4c.c
new file mode 100644
index 0000000..a51c739
--- /dev/null
+++ b/lib/libmd/md4c.c
@@ -0,0 +1,288 @@
+/* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm
+ * $FreeBSD$
+ */
+
+/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
+
+ License to copy and use this software is granted provided that it
+ is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ Algorithm" in all material mentioning or referencing this software
+ or this function.
+
+ License is also granted to make and use derivative works provided
+ that such works are identified as "derived from the RSA Data
+ Security, Inc. MD4 Message-Digest Algorithm" in all material
+ mentioning or referencing the derived work.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include "md4.h"
+
+typedef unsigned char *POINTER;
+typedef u_int16_t UINT2;
+typedef u_int32_t UINT4;
+
+#define PROTO_LIST(list) list
+
+/* Constants for MD4Transform routine.
+ */
+#define S11 3
+#define S12 7
+#define S13 11
+#define S14 19
+#define S21 3
+#define S22 5
+#define S23 9
+#define S24 13
+#define S31 3
+#define S32 9
+#define S33 11
+#define S34 15
+
+static void MD4Transform PROTO_LIST ((UINT4 [4], const unsigned char [64]));
+static void Encode PROTO_LIST
+ ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+ ((UINT4 *, const unsigned char *, unsigned int));
+
+static unsigned char PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G and H are basic MD4 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
+/* Rotation is separate from addition to prevent recomputation */
+#define FF(a, b, c, d, x, s) { \
+ (a) += F ((b), (c), (d)) + (x); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ }
+#define GG(a, b, c, d, x, s) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ }
+#define HH(a, b, c, d, x, s) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ }
+
+/* MD4 initialization. Begins an MD4 operation, writing a new context.
+ */
+void MD4Init (context)
+MD4_CTX *context; /* context */
+{
+ context->count[0] = context->count[1] = 0;
+
+ /* Load magic initialization constants.
+ */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/* MD4 block update operation. Continues an MD4 message-digest
+ operation, processing another message block, and updating the
+ context.
+ */
+void MD4Update (context, input, inputLen)
+MD4_CTX *context; /* context */
+const unsigned char *input; /* input block */
+unsigned int inputLen; /* length of input block */
+{
+ unsigned int i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4)inputLen << 3))
+ < ((UINT4)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4)inputLen >> 29);
+
+ partLen = 64 - index;
+ /* Transform as many times as possible.
+ */
+ if (inputLen >= partLen) {
+ memcpy
+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD4Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD4Transform (context->state, &input[i]);
+
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ memcpy
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
+ inputLen-i);
+}
+
+/* MD4 padding. */
+void MD4Pad (context)
+MD4_CTX *context; /* context */
+{
+ unsigned char bits[8];
+ unsigned int index, padLen;
+
+ /* Save number of bits */
+ Encode (bits, context->count, 8);
+
+ /* Pad out to 56 mod 64.
+ */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ MD4Update (context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ MD4Update (context, bits, 8);
+}
+
+/* MD4 finalization. Ends an MD4 message-digest operation, writing the
+ the message digest and zeroizing the context.
+ */
+void MD4Final (digest, context)
+unsigned char digest[16]; /* message digest */
+MD4_CTX *context; /* context */
+{
+ /* Do padding */
+ MD4Pad (context);
+
+ /* Store state in digest */
+ Encode (digest, context->state, 16);
+
+ /* Zeroize sensitive information.
+ */
+ memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD4 basic transformation. Transforms state based on block.
+ */
+static void MD4Transform (state, block)
+UINT4 state[4];
+const unsigned char block[64];
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode (x, block, 64);
+
+ /* Round 1 */
+ FF (a, b, c, d, x[ 0], S11); /* 1 */
+ FF (d, a, b, c, x[ 1], S12); /* 2 */
+ FF (c, d, a, b, x[ 2], S13); /* 3 */
+ FF (b, c, d, a, x[ 3], S14); /* 4 */
+ FF (a, b, c, d, x[ 4], S11); /* 5 */
+ FF (d, a, b, c, x[ 5], S12); /* 6 */
+ FF (c, d, a, b, x[ 6], S13); /* 7 */
+ FF (b, c, d, a, x[ 7], S14); /* 8 */
+ FF (a, b, c, d, x[ 8], S11); /* 9 */
+ FF (d, a, b, c, x[ 9], S12); /* 10 */
+ FF (c, d, a, b, x[10], S13); /* 11 */
+ FF (b, c, d, a, x[11], S14); /* 12 */
+ FF (a, b, c, d, x[12], S11); /* 13 */
+ FF (d, a, b, c, x[13], S12); /* 14 */
+ FF (c, d, a, b, x[14], S13); /* 15 */
+ FF (b, c, d, a, x[15], S14); /* 16 */
+
+ /* Round 2 */
+ GG (a, b, c, d, x[ 0], S21); /* 17 */
+ GG (d, a, b, c, x[ 4], S22); /* 18 */
+ GG (c, d, a, b, x[ 8], S23); /* 19 */
+ GG (b, c, d, a, x[12], S24); /* 20 */
+ GG (a, b, c, d, x[ 1], S21); /* 21 */
+ GG (d, a, b, c, x[ 5], S22); /* 22 */
+ GG (c, d, a, b, x[ 9], S23); /* 23 */
+ GG (b, c, d, a, x[13], S24); /* 24 */
+ GG (a, b, c, d, x[ 2], S21); /* 25 */
+ GG (d, a, b, c, x[ 6], S22); /* 26 */
+ GG (c, d, a, b, x[10], S23); /* 27 */
+ GG (b, c, d, a, x[14], S24); /* 28 */
+ GG (a, b, c, d, x[ 3], S21); /* 29 */
+ GG (d, a, b, c, x[ 7], S22); /* 30 */
+ GG (c, d, a, b, x[11], S23); /* 31 */
+ GG (b, c, d, a, x[15], S24); /* 32 */
+
+ /* Round 3 */
+ HH (a, b, c, d, x[ 0], S31); /* 33 */
+ HH (d, a, b, c, x[ 8], S32); /* 34 */
+ HH (c, d, a, b, x[ 4], S33); /* 35 */
+ HH (b, c, d, a, x[12], S34); /* 36 */
+ HH (a, b, c, d, x[ 2], S31); /* 37 */
+ HH (d, a, b, c, x[10], S32); /* 38 */
+ HH (c, d, a, b, x[ 6], S33); /* 39 */
+ HH (b, c, d, a, x[14], S34); /* 40 */
+ HH (a, b, c, d, x[ 1], S31); /* 41 */
+ HH (d, a, b, c, x[ 9], S32); /* 42 */
+ HH (c, d, a, b, x[ 5], S33); /* 43 */
+ HH (b, c, d, a, x[13], S34); /* 44 */
+ HH (a, b, c, d, x[ 3], S31); /* 45 */
+ HH (d, a, b, c, x[11], S32); /* 46 */
+ HH (c, d, a, b, x[ 7], S33); /* 47 */
+ HH (b, c, d, a, x[15], S34); /* 48 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information.
+ */
+ memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+ a multiple of 4.
+ */
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+ a multiple of 4.
+ */
+static void Decode (output, input, len)
+
+UINT4 *output;
+const unsigned char *input;
+unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
diff --git a/lib/libmd/md5.copyright b/lib/libmd/md5.copyright
new file mode 100644
index 0000000..b718bf8
--- /dev/null
+++ b/lib/libmd/md5.copyright
@@ -0,0 +1,21 @@
+.\" $FreeBSD$
+Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+.Pp
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+.Pp
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+.Pp
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+.Pp
+These notices must be retained in any copies of any part of this
+documentation and/or software.
diff --git a/lib/libmd/md5.h b/lib/libmd/md5.h
new file mode 100644
index 0000000..803a88f
--- /dev/null
+++ b/lib/libmd/md5.h
@@ -0,0 +1,4 @@
+#ifndef _MD5_H_
+#define _MD5_H_
+#include <sys/md5.h>
+#endif /* _MD5_H_ */
diff --git a/lib/libmd/md5c.c b/lib/libmd/md5c.c
new file mode 100644
index 0000000..8e25a6a
--- /dev/null
+++ b/lib/libmd/md5c.c
@@ -0,0 +1,342 @@
+/*
+ * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ *
+ * $FreeBSD$
+ *
+ * This code is the same as the code published by RSA Inc. It has been
+ * edited for clarity and style only.
+ */
+
+#include <sys/types.h>
+
+#ifdef KERNEL
+#include <sys/systm.h>
+#else
+#include <string.h>
+#endif
+
+#include <sys/md5.h>
+
+static void MD5Transform __P((u_int32_t [4], const unsigned char [64]));
+
+#ifdef KERNEL
+#define memset(x,y,z) bzero(x,z);
+#define memcpy(x,y,z) bcopy(y, x, z)
+#endif
+
+#ifdef i386
+#define Encode memcpy
+#define Decode memcpy
+#else /* i386 */
+
+/*
+ * Encodes input (u_int32_t) into output (unsigned char). Assumes len is
+ * a multiple of 4.
+ */
+
+static void
+Encode (output, input, len)
+ unsigned char *output;
+ u_int32_t *input;
+ unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+/*
+ * Decodes input (unsigned char) into output (u_int32_t). Assumes len is
+ * a multiple of 4.
+ */
+
+static void
+Decode (output, input, len)
+ u_int32_t *output;
+ const unsigned char *input;
+ unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((u_int32_t)input[j]) | (((u_int32_t)input[j+1]) << 8) |
+ (((u_int32_t)input[j+2]) << 16) | (((u_int32_t)input[j+3]) << 24);
+}
+#endif /* i386 */
+
+static unsigned char PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions. */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits. */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/*
+ * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+ * Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context. */
+
+void
+MD5Init (context)
+ MD5_CTX *context;
+{
+
+ context->count[0] = context->count[1] = 0;
+
+ /* Load magic initialization constants. */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/*
+ * MD5 block update operation. Continues an MD5 message-digest
+ * operation, processing another message block, and updating the
+ * context.
+ */
+
+void
+MD5Update (context, input, inputLen)
+ MD5_CTX *context;
+ const unsigned char *input;
+ unsigned int inputLen;
+{
+ unsigned int i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((context->count[0] += ((u_int32_t)inputLen << 3))
+ < ((u_int32_t)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((u_int32_t)inputLen >> 29);
+
+ partLen = 64 - index;
+
+ /* Transform as many times as possible. */
+ if (inputLen >= partLen) {
+ memcpy((void *)&context->buffer[index], (const void *)input,
+ partLen);
+ MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform (context->state, &input[i]);
+
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ memcpy ((void *)&context->buffer[index], (const void *)&input[i],
+ inputLen-i);
+}
+
+/*
+ * MD5 padding. Adds padding followed by original length.
+ */
+
+void
+MD5Pad (context)
+ MD5_CTX *context;
+{
+ unsigned char bits[8];
+ unsigned int index, padLen;
+
+ /* Save number of bits */
+ Encode (bits, context->count, 8);
+
+ /* Pad out to 56 mod 64. */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ MD5Update (context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ MD5Update (context, bits, 8);
+}
+
+/*
+ * MD5 finalization. Ends an MD5 message-digest operation, writing the
+ * the message digest and zeroizing the context.
+ */
+
+void
+MD5Final (digest, context)
+ unsigned char digest[16];
+ MD5_CTX *context;
+{
+ /* Do padding. */
+ MD5Pad (context);
+
+ /* Store state in digest */
+ Encode (digest, context->state, 16);
+
+ /* Zeroize sensitive information. */
+ memset ((void *)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block. */
+
+static void
+MD5Transform (state, block)
+ u_int32_t state[4];
+ const unsigned char block[64];
+{
+ u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode (x, block, 64);
+
+ /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information. */
+ memset ((void *)x, 0, sizeof (x));
+}
diff --git a/lib/libmd/mdX.3 b/lib/libmd/mdX.3
new file mode 100644
index 0000000..ebd8b30
--- /dev/null
+++ b/lib/libmd/mdX.3
@@ -0,0 +1,167 @@
+.\"
+.\" ----------------------------------------------------------------------------
+.\" "THE BEER-WARE LICENSE" (Revision 42):
+.\" <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you
+.\" can do whatever you want with this stuff. If we meet some day, and you think
+.\" this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+.\" ----------------------------------------------------------------------------
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 11, 1999
+.Dt MDX 3
+.Os FreeBSD 2
+.Sh NAME
+.Nm MDXInit ,
+.Nm MDXUpdate ,
+.Nm MDXPad ,
+.Nm MDXFinal ,
+.Nm MDXEnd ,
+.Nm MDXFile ,
+.Nm MDXData
+.Nd calculate the RSA Data Security, Inc., ``MDX'' message digest
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <mdX.h>
+.Ft void
+.Fn MDXInit "MDX_CTX *context"
+.Ft void
+.Fn MDXUpdate "MDX_CTX *context" "const unsigned char *data" "unsigned int len"
+.Ft void
+.Fn MDXPad "MDX_CTX *context"
+.Ft void
+.Fn MDXFinal "unsigned char digest[16]" "MDX_CTX *context"
+.Ft "char *"
+.Fn MDXEnd "MDX_CTX *context" "char *buf"
+.Ft "char *"
+.Fn MDXFile "const char *filename" "char *buf"
+.Ft "char *"
+.Fn MDXData "const unsigned char *data" "unsigned int len" "char *buf"
+.Sh DESCRIPTION
+The MDX functions calculate a 128-bit cryptographic checksum (digest)
+for any number of input bytes. A cryptographic checksum is a one-way
+hash-function, that is, you cannot find (except by exhaustive search)
+the input corresponding to a particular output. This net result is
+a ``fingerprint'' of the input-data, which doesn't disclose the actual
+input.
+.Pp
+MD2 is the slowest, MD4 is the fastest and MD5 is somewhere in the middle.
+MD2 can only be used for Privacy-Enhanced Mail.
+MD4 has now been broken; it should only be used where necessary for
+backward compatibility.
+MD5 has not yet (1999-02-11) been broken, but sufficient attacks have been
+made that its security is in some doubt. The attacks on both MD4 and MD5
+are both in the nature of finding ``collisions'' \- that is, multiple
+inputs which hash to the same value; it is still unlikely for an attacker
+to be able to determine the exact original input given a hash value.
+.Pp
+The
+.Fn MDXInit ,
+.Fn MDXUpdate ,
+and
+.Fn MDXFinal
+functions are the core functions. Allocate an MDX_CTX, initialize it with
+.Fn MDXInit ,
+run over the data with
+.Fn MDXUpdate ,
+and finally extract the result using
+.Fn MDXFinal .
+.Pp
+.Fn MDXPad
+can be used to pad message data in same way
+as done by
+.Fn MDXFinal
+without terminating calculation.
+.Pp
+.Fn MDXEnd
+is a wrapper for
+.Fn MDXFinal
+which converts the return value to a 33-character
+(including the terminating '\e0')
+.Tn ASCII
+string which represents the 128 bits in hexadecimal.
+.Pp
+.Fn MDXFile
+calculates the digest of a file, and uses
+.Fn MDXEnd
+to return the result.
+If the file cannot be opened, a null pointer is returned.
+.Fn MDXData
+calculates the digest of a chunk of data in memory, and uses
+.Fn MDXEnd
+to return the result.
+.Pp
+When using
+.Fn MDXEnd ,
+.Fn MDXFile ,
+or
+.Fn MDXData ,
+the
+.Ar buf
+argument can be a null pointer, in which case the returned string
+is allocated with
+.Xr malloc 3
+and subsequently must be explicitly deallocated using
+.Xr free 3
+after use.
+If the
+.Ar buf
+argument is non-null it must point to at least 33 characters of buffer space.
+.Sh SEE ALSO
+.Xr md2 3 ,
+.Xr md4 3 ,
+.Xr md5 3 ,
+.Xr sha 3
+.Rs
+.%A B. Kaliski
+.%T The MD2 Message-Digest Algorithm
+.%O RFC 1319
+.Re
+.Rs
+.%A R. Rivest
+.%T The MD4 Message-Digest Algorithm
+.%O RFC 1186
+.Re
+.Rs
+.%A R. Rivest
+.%T The MD5 Message-Digest Algorithm
+.%O RFC 1321
+.Re
+.Rs
+.%A RSA Laboratories
+.%T Frequently Asked Questions About today's Cryptography
+.%O \&<http://www.rsa.com/rsalabs/faq/>
+.Re
+.Rs
+.%A H. Dobbertin
+.%T Alf Swindles Ann
+.%J CryptoBytes
+.%N 1(3):5
+.%D 1995
+.Re
+.Rs
+.%A MJ. B. Robshaw
+.%T On Recent Results for MD2, MD4 and MD5
+.%J RSA Laboratories Bulletin
+.%N 4
+.%D November 12, 1996
+.Re
+.Sh AUTHORS
+The original MDX routines were developed by
+.Tn RSA
+Data Security, Inc., and published in the above references.
+This code is derived directly from these implementations by
+.An Poul-Henning Kamp Aq phk@login.dkuug.dk
+.Pp
+Phk ristede runen.
+.Sh HISTORY
+These functions appeared in
+.Fx 2.0 .
+.Sh BUGS
+No method is known to exist which finds two files having the same hash value,
+nor to find a file with a specific hash value.
+There is on the other hand no guarantee that such a method doesn't exist.
+.Pp
+MD2 has only been licensed for use in Privacy Enhanced Mail.
+Use MD4 or MD5 if that isn't what you're doing.
+.Sh COPYRIGHT
diff --git a/lib/libmd/mdXhl.c b/lib/libmd/mdXhl.c
new file mode 100644
index 0000000..0af7892
--- /dev/null
+++ b/lib/libmd/mdXhl.c
@@ -0,0 +1,71 @@
+/* mdXhl.c
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mdX.h"
+
+char *
+MDXEnd(MDX_CTX *ctx, char *buf)
+{
+ int i;
+ unsigned char digest[LENGTH];
+ static const char hex[]="0123456789abcdef";
+
+ if (!buf)
+ buf = malloc(2*LENGTH + 1);
+ if (!buf)
+ return 0;
+ MDXFinal(digest, ctx);
+ for (i = 0; i < LENGTH; i++) {
+ buf[i+i] = hex[digest[i] >> 4];
+ buf[i+i+1] = hex[digest[i] & 0x0f];
+ }
+ buf[i+i] = '\0';
+ return buf;
+}
+
+char *
+MDXFile(const char *filename, char *buf)
+{
+ unsigned char buffer[BUFSIZ];
+ MDX_CTX ctx;
+ int f,i,j;
+
+ MDXInit(&ctx);
+ f = open(filename,O_RDONLY);
+ if (f < 0) return 0;
+ while ((i = read(f,buffer,sizeof buffer)) > 0) {
+ MDXUpdate(&ctx,buffer,i);
+ }
+ j = errno;
+ close(f);
+ errno = j;
+ if (i < 0) return 0;
+ return MDXEnd(&ctx, buf);
+}
+
+char *
+MDXData (const unsigned char *data, unsigned int len, char *buf)
+{
+ MDX_CTX ctx;
+
+ MDXInit(&ctx);
+ MDXUpdate(&ctx,data,len);
+ return MDXEnd(&ctx, buf);
+}
diff --git a/lib/libmd/mddriver.c b/lib/libmd/mddriver.c
new file mode 100644
index 0000000..e58473c
--- /dev/null
+++ b/lib/libmd/mddriver.c
@@ -0,0 +1,70 @@
+/* MDDRIVER.C - test driver for MD2, MD4 and MD5
+ * $FreeBSD$
+ */
+
+/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+ rights reserved.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+ */
+
+/* The following makes MD default to MD5 if it has not already been
+ defined with C compiler flags.
+ */
+#ifndef MD
+#define MD 5
+#endif
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#if MD == 2
+#include "md2.h"
+#define MDData MD2Data
+#endif
+#if MD == 4
+#include "md4.h"
+#define MDData MD4Data
+#endif
+#if MD == 5
+#include "md5.h"
+#define MDData MD5Data
+#endif
+
+/* Digests a string and prints the result.
+ */
+static void MDString (string)
+char *string;
+{
+ char buf[33];
+
+ printf ("MD%d (\"%s\") = %s\n",
+ MD, string, MDData(string,strlen(string),buf));
+}
+
+/* Digests a reference suite of strings and prints the results.
+ */
+main()
+{
+ printf ("MD%d test suite:\n", MD);
+
+ MDString ("");
+ MDString ("a");
+ MDString ("abc");
+ MDString ("message digest");
+ MDString ("abcdefghijklmnopqrstuvwxyz");
+ MDString
+ ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+ MDString
+ ("1234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890");
+ return 0;
+}
diff --git a/lib/libmd/ripemd.3 b/lib/libmd/ripemd.3
new file mode 100644
index 0000000..12fa3df
--- /dev/null
+++ b/lib/libmd/ripemd.3
@@ -0,0 +1,110 @@
+.\"
+.\" ----------------------------------------------------------------------------
+.\" "THE BEER-WARE LICENSE" (Revision 42):
+.\" <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you
+.\" can do whatever you want with this stuff. If we meet some day, and you think
+.\" this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+.\" ----------------------------------------------------------------------------
+.\"
+.\" From: Id: mdX.3,v 1.14 1999/02/11 20:31:49 wollman Exp
+.\" $FreeBSD$
+.\"
+.Dd February 26, 1999
+.Dt RIPEMD 3
+.Os FreeBSD 4.0
+.Sh NAME
+.Nm RIPEMD160_Init ,
+.Nm RIPEMD160_Update ,
+.Nm RIPEMD160_Final ,
+.Nm RIPEMD160_End ,
+.Nm RIPEMD160_File ,
+.Nm RIPEMD160_Data
+.Nd calculate the RIPEMD160 message digest
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <ripemd.h>
+.Ft void
+.Fn RIPEMD160_Init "RIPEMD160_CTX *context"
+.Ft void
+.Fn RIPEMD160_Update "RIPEMD160_CTX *context" "const unsigned char *data" "unsigned int len"
+.Ft void
+.Fn RIPEMD160_Final "unsigned char digest[20]" "RIPEMD160_CTX *context"
+.Ft "char *"
+.Fn RIPEMD160_End "RIPEMD160_CTX *context" "char *buf"
+.Ft "char *"
+.Fn RIPEMD160_File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn RIPEMD160_Data "const unsigned char *data" "unsigned int len" "char *buf"
+.Sh DESCRIPTION
+The
+.Li RIPEMD160_
+functions calculate a 160-bit cryptographic checksum (digest)
+for any number of input bytes. A cryptographic checksum is a one-way
+hash function; that is, it is computationally impractical to find
+the input corresponding to a particular output. This net result is
+a ``fingerprint'' of the input-data, which doesn't disclose the actual
+input.
+.Pp
+The
+.Fn RIPEMD160_Init ,
+.Fn RIPEMD160_Update ,
+and
+.Fn RIPEMD160_Final
+functions are the core functions. Allocate an RIPEMD160_CTX, initialize it with
+.Fn RIPEMD160_Init ,
+run over the data with
+.Fn RIPEMD160_Update ,
+and finally extract the result using
+.Fn RIPEMD160_Final .
+.Pp
+.Fn RIPEMD160_End
+is a wrapper for
+.Fn RIPEMD160_Final
+which converts the return value to a 41-character
+(including the terminating '\e0')
+.Tn ASCII
+string which represents the 160 bits in hexadecimal.
+.Pp
+.Fn RIPEMD160_File
+calculates the digest of a file, and uses
+.Fn RIPEMD160_End
+to return the result.
+If the file cannot be opened, a null pointer is returned.
+.Fn RIPEMD160_Data
+calculates the digest of a chunk of data in memory, and uses
+.Fn RIPEMD160_End
+to return the result.
+.Pp
+When using
+.Fn RIPEMD160_End ,
+.Fn RIPEMD160_File ,
+or
+.Fn RIPEMD160_Data ,
+the
+.Ar buf
+argument can be a null pointer, in which case the returned string
+is allocated with
+.Xr malloc 3
+and subsequently must be explicitly deallocated using
+.Xr free 3
+after use.
+If the
+.Ar buf
+argument is non-null it must point to at least 41 characters of buffer space.
+.Sh SEE ALSO
+.Xr md2 3 ,
+.Xr md4 3 ,
+.Xr md5 3 ,
+.Xr sha 3
+.Sh AUTHORS
+The core hash routines were implemented by Eric Young based on the
+published
+.Tn RIPEMD160
+specification.
+.Sh HISTORY
+These functions appeared in
+.Fx 4.0 .
+.Sh BUGS
+No method is known to exist which finds two files having the same hash value,
+nor to find a file with a specific hash value.
+There is on the other hand no guarantee that such a method doesn't exist.
diff --git a/lib/libmd/ripemd.h b/lib/libmd/ripemd.h
new file mode 100644
index 0000000..1399d32
--- /dev/null
+++ b/lib/libmd/ripemd.h
@@ -0,0 +1,89 @@
+/* crypto/ripemd/ripemd.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RIPEMD_H
+#define HEADER_RIPEMD_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h> /* XXX switch to machine/ansi.h and __ types */
+
+#define RIPEMD160_CBLOCK 64
+#define RIPEMD160_LBLOCK 16
+#define RIPEMD160_BLOCK 16
+#define RIPEMD160_LAST_BLOCK 56
+#define RIPEMD160_LENGTH_BLOCK 8
+#define RIPEMD160_DIGEST_LENGTH 20
+
+typedef struct RIPEMD160state_st {
+ u_int32_t A,B,C,D,E;
+ u_int32_t Nl,Nh;
+ u_int32_t data[RIPEMD160_LBLOCK];
+ int num;
+} RIPEMD160_CTX;
+
+__BEGIN_DECLS
+void RIPEMD160_Init(RIPEMD160_CTX *c);
+void RIPEMD160_Update(RIPEMD160_CTX *c, const unsigned char *data,
+ size_t len);
+void RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c);
+char *RIPEMD160_End(RIPEMD160_CTX *, char *);
+char *RIPEMD160_File(const char *, char *);
+char *RIPEMD160_Data(const unsigned char *, unsigned int, char *);
+__END_DECLS
+
+#endif
diff --git a/lib/libmd/rmd160c.c b/lib/libmd/rmd160c.c
new file mode 100644
index 0000000..c31f9cd
--- /dev/null
+++ b/lib/libmd/rmd160c.c
@@ -0,0 +1,545 @@
+/* crypto/ripemd/rmd_dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if 0
+#include <machine/ansi.h> /* we use the __ variants of bit-sized types */
+#endif
+#include <machine/endian.h>
+
+#include "rmd_locl.h"
+
+/*
+ * The assembly-language code is not position-independent, so don't
+ * try to use it in a shared library.
+ */
+#ifdef PIC
+#undef RMD160_ASM
+#endif
+
+char *RMD160_version="RIPEMD160 part of SSLeay 0.9.0b 11-Oct-1998";
+
+#ifdef RMD160_ASM
+void ripemd160_block_x86(RIPEMD160_CTX *c, const u_int32_t *p,int num);
+#define ripemd160_block ripemd160_block_x86
+#else
+void ripemd160_block(RIPEMD160_CTX *c, const u_int32_t *p,int num);
+#endif
+
+void RIPEMD160_Init(c)
+RIPEMD160_CTX *c;
+ {
+ c->A=RIPEMD160_A;
+ c->B=RIPEMD160_B;
+ c->C=RIPEMD160_C;
+ c->D=RIPEMD160_D;
+ c->E=RIPEMD160_E;
+ c->Nl=0;
+ c->Nh=0;
+ c->num=0;
+ }
+
+void RIPEMD160_Update(c, data, len)
+RIPEMD160_CTX *c;
+const unsigned char *data;
+size_t len;
+ {
+ register u_int32_t *p;
+ int sw,sc;
+ u_int32_t l;
+
+ if (len == 0) return;
+
+ l=(c->Nl+(len<<3))&0xffffffffL;
+ if (l < c->Nl) /* overflow */
+ c->Nh++;
+ c->Nh+=(len>>29);
+ c->Nl=l;
+
+ if (c->num != 0)
+ {
+ p=c->data;
+ sw=c->num>>2;
+ sc=c->num&0x03;
+
+ if ((c->num+len) >= RIPEMD160_CBLOCK)
+ {
+ l= p[sw];
+ p_c2l(data,l,sc);
+ p[sw++]=l;
+ for (; sw<RIPEMD160_LBLOCK; sw++)
+ {
+ c2l(data,l);
+ p[sw]=l;
+ }
+ len-=(RIPEMD160_CBLOCK-c->num);
+
+ ripemd160_block(c,p,64);
+ c->num=0;
+ /* drop through and do the rest */
+ }
+ else
+ {
+ int ew,ec;
+
+ c->num+=(int)len;
+ if ((sc+len) < 4) /* ugly, add char's to a word */
+ {
+ l= p[sw];
+ p_c2l_p(data,l,sc,len);
+ p[sw]=l;
+ }
+ else
+ {
+ ew=(c->num>>2);
+ ec=(c->num&0x03);
+ l= p[sw];
+ p_c2l(data,l,sc);
+ p[sw++]=l;
+ for (; sw < ew; sw++)
+ { c2l(data,l); p[sw]=l; }
+ if (ec)
+ {
+ c2l_p(data,l,ec);
+ p[sw]=l;
+ }
+ }
+ return;
+ }
+ }
+ /* we now can process the input data in blocks of RIPEMD160_CBLOCK
+ * chars and save the leftovers to c->data. */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ if ((((unsigned long)data)%sizeof(u_int32_t)) == 0)
+ {
+ sw=(int)len/RIPEMD160_CBLOCK;
+ if (sw > 0)
+ {
+ sw*=RIPEMD160_CBLOCK;
+ ripemd160_block(c,(u_int32_t *)data,sw);
+ data+=sw;
+ len-=sw;
+ }
+ }
+#endif
+ p=c->data;
+ while (len >= RIPEMD160_CBLOCK)
+ {
+#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == BIG_ENDIAN
+ if (p != (u_int32_t *)data)
+ memcpy(p,data,RIPEMD160_CBLOCK);
+ data+=RIPEMD160_CBLOCK;
+#if BYTE_ORDER == BIG_ENDIAN
+ for (sw=(RIPEMD160_LBLOCK/4); sw; sw--)
+ {
+ Endian_Reverse32(p[0]);
+ Endian_Reverse32(p[1]);
+ Endian_Reverse32(p[2]);
+ Endian_Reverse32(p[3]);
+ p+=4;
+ }
+#endif
+#else
+ for (sw=(RIPEMD160_LBLOCK/4); sw; sw--)
+ {
+ c2l(data,l); *(p++)=l;
+ c2l(data,l); *(p++)=l;
+ c2l(data,l); *(p++)=l;
+ c2l(data,l); *(p++)=l;
+ }
+#endif
+ p=c->data;
+ ripemd160_block(c,p,64);
+ len-=RIPEMD160_CBLOCK;
+ }
+ sc=(int)len;
+ c->num=sc;
+ if (sc)
+ {
+ sw=sc>>2; /* words to copy */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ p[sw]=0;
+ memcpy(p,data,sc);
+#else
+ sc&=0x03;
+ for ( ; sw; sw--)
+ { c2l(data,l); *(p++)=l; }
+ c2l_p(data,l,sc);
+ *p=l;
+#endif
+ }
+ }
+
+void RIPEMD160_Transform(c,b)
+RIPEMD160_CTX *c;
+unsigned char *b;
+ {
+ u_int32_t p[16];
+#if BYTE_ORDER != LITTLE_ENDIAN
+ u_int32_t *q;
+ int i;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN
+ memcpy(p,b,64);
+#if BYTE_ORDER == BIG_ENDIAN
+ q=p;
+ for (i=(RIPEMD160_LBLOCK/4); i; i--)
+ {
+ Endian_Reverse32(q[0]);
+ Endian_Reverse32(q[1]);
+ Endian_Reverse32(q[2]);
+ Endian_Reverse32(q[3]);
+ q+=4;
+ }
+#endif
+#else
+ q=p;
+ for (i=(RIPEMD160_LBLOCK/4); i; i--)
+ {
+ u_int32_t l;
+ c2l(b,l); *(q++)=l;
+ c2l(b,l); *(q++)=l;
+ c2l(b,l); *(q++)=l;
+ c2l(b,l); *(q++)=l;
+ }
+#endif
+ ripemd160_block(c,p,64);
+ }
+
+#ifndef RMD160_ASM
+
+void ripemd160_block(ctx, X, num)
+RIPEMD160_CTX *ctx;
+const u_int32_t *X;
+int num;
+ {
+ register u_int32_t A,B,C,D,E;
+ u_int32_t a,b,c,d,e;
+
+ for (;;)
+ {
+ A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E;
+
+ RIP1(A,B,C,D,E,WL00,SL00);
+ RIP1(E,A,B,C,D,WL01,SL01);
+ RIP1(D,E,A,B,C,WL02,SL02);
+ RIP1(C,D,E,A,B,WL03,SL03);
+ RIP1(B,C,D,E,A,WL04,SL04);
+ RIP1(A,B,C,D,E,WL05,SL05);
+ RIP1(E,A,B,C,D,WL06,SL06);
+ RIP1(D,E,A,B,C,WL07,SL07);
+ RIP1(C,D,E,A,B,WL08,SL08);
+ RIP1(B,C,D,E,A,WL09,SL09);
+ RIP1(A,B,C,D,E,WL10,SL10);
+ RIP1(E,A,B,C,D,WL11,SL11);
+ RIP1(D,E,A,B,C,WL12,SL12);
+ RIP1(C,D,E,A,B,WL13,SL13);
+ RIP1(B,C,D,E,A,WL14,SL14);
+ RIP1(A,B,C,D,E,WL15,SL15);
+
+ RIP2(E,A,B,C,D,WL16,SL16,KL1);
+ RIP2(D,E,A,B,C,WL17,SL17,KL1);
+ RIP2(C,D,E,A,B,WL18,SL18,KL1);
+ RIP2(B,C,D,E,A,WL19,SL19,KL1);
+ RIP2(A,B,C,D,E,WL20,SL20,KL1);
+ RIP2(E,A,B,C,D,WL21,SL21,KL1);
+ RIP2(D,E,A,B,C,WL22,SL22,KL1);
+ RIP2(C,D,E,A,B,WL23,SL23,KL1);
+ RIP2(B,C,D,E,A,WL24,SL24,KL1);
+ RIP2(A,B,C,D,E,WL25,SL25,KL1);
+ RIP2(E,A,B,C,D,WL26,SL26,KL1);
+ RIP2(D,E,A,B,C,WL27,SL27,KL1);
+ RIP2(C,D,E,A,B,WL28,SL28,KL1);
+ RIP2(B,C,D,E,A,WL29,SL29,KL1);
+ RIP2(A,B,C,D,E,WL30,SL30,KL1);
+ RIP2(E,A,B,C,D,WL31,SL31,KL1);
+
+ RIP3(D,E,A,B,C,WL32,SL32,KL2);
+ RIP3(C,D,E,A,B,WL33,SL33,KL2);
+ RIP3(B,C,D,E,A,WL34,SL34,KL2);
+ RIP3(A,B,C,D,E,WL35,SL35,KL2);
+ RIP3(E,A,B,C,D,WL36,SL36,KL2);
+ RIP3(D,E,A,B,C,WL37,SL37,KL2);
+ RIP3(C,D,E,A,B,WL38,SL38,KL2);
+ RIP3(B,C,D,E,A,WL39,SL39,KL2);
+ RIP3(A,B,C,D,E,WL40,SL40,KL2);
+ RIP3(E,A,B,C,D,WL41,SL41,KL2);
+ RIP3(D,E,A,B,C,WL42,SL42,KL2);
+ RIP3(C,D,E,A,B,WL43,SL43,KL2);
+ RIP3(B,C,D,E,A,WL44,SL44,KL2);
+ RIP3(A,B,C,D,E,WL45,SL45,KL2);
+ RIP3(E,A,B,C,D,WL46,SL46,KL2);
+ RIP3(D,E,A,B,C,WL47,SL47,KL2);
+
+ RIP4(C,D,E,A,B,WL48,SL48,KL3);
+ RIP4(B,C,D,E,A,WL49,SL49,KL3);
+ RIP4(A,B,C,D,E,WL50,SL50,KL3);
+ RIP4(E,A,B,C,D,WL51,SL51,KL3);
+ RIP4(D,E,A,B,C,WL52,SL52,KL3);
+ RIP4(C,D,E,A,B,WL53,SL53,KL3);
+ RIP4(B,C,D,E,A,WL54,SL54,KL3);
+ RIP4(A,B,C,D,E,WL55,SL55,KL3);
+ RIP4(E,A,B,C,D,WL56,SL56,KL3);
+ RIP4(D,E,A,B,C,WL57,SL57,KL3);
+ RIP4(C,D,E,A,B,WL58,SL58,KL3);
+ RIP4(B,C,D,E,A,WL59,SL59,KL3);
+ RIP4(A,B,C,D,E,WL60,SL60,KL3);
+ RIP4(E,A,B,C,D,WL61,SL61,KL3);
+ RIP4(D,E,A,B,C,WL62,SL62,KL3);
+ RIP4(C,D,E,A,B,WL63,SL63,KL3);
+
+ RIP5(B,C,D,E,A,WL64,SL64,KL4);
+ RIP5(A,B,C,D,E,WL65,SL65,KL4);
+ RIP5(E,A,B,C,D,WL66,SL66,KL4);
+ RIP5(D,E,A,B,C,WL67,SL67,KL4);
+ RIP5(C,D,E,A,B,WL68,SL68,KL4);
+ RIP5(B,C,D,E,A,WL69,SL69,KL4);
+ RIP5(A,B,C,D,E,WL70,SL70,KL4);
+ RIP5(E,A,B,C,D,WL71,SL71,KL4);
+ RIP5(D,E,A,B,C,WL72,SL72,KL4);
+ RIP5(C,D,E,A,B,WL73,SL73,KL4);
+ RIP5(B,C,D,E,A,WL74,SL74,KL4);
+ RIP5(A,B,C,D,E,WL75,SL75,KL4);
+ RIP5(E,A,B,C,D,WL76,SL76,KL4);
+ RIP5(D,E,A,B,C,WL77,SL77,KL4);
+ RIP5(C,D,E,A,B,WL78,SL78,KL4);
+ RIP5(B,C,D,E,A,WL79,SL79,KL4);
+
+ a=A; b=B; c=C; d=D; e=E;
+ /* Do other half */
+ A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E;
+
+ RIP5(A,B,C,D,E,WR00,SR00,KR0);
+ RIP5(E,A,B,C,D,WR01,SR01,KR0);
+ RIP5(D,E,A,B,C,WR02,SR02,KR0);
+ RIP5(C,D,E,A,B,WR03,SR03,KR0);
+ RIP5(B,C,D,E,A,WR04,SR04,KR0);
+ RIP5(A,B,C,D,E,WR05,SR05,KR0);
+ RIP5(E,A,B,C,D,WR06,SR06,KR0);
+ RIP5(D,E,A,B,C,WR07,SR07,KR0);
+ RIP5(C,D,E,A,B,WR08,SR08,KR0);
+ RIP5(B,C,D,E,A,WR09,SR09,KR0);
+ RIP5(A,B,C,D,E,WR10,SR10,KR0);
+ RIP5(E,A,B,C,D,WR11,SR11,KR0);
+ RIP5(D,E,A,B,C,WR12,SR12,KR0);
+ RIP5(C,D,E,A,B,WR13,SR13,KR0);
+ RIP5(B,C,D,E,A,WR14,SR14,KR0);
+ RIP5(A,B,C,D,E,WR15,SR15,KR0);
+
+ RIP4(E,A,B,C,D,WR16,SR16,KR1);
+ RIP4(D,E,A,B,C,WR17,SR17,KR1);
+ RIP4(C,D,E,A,B,WR18,SR18,KR1);
+ RIP4(B,C,D,E,A,WR19,SR19,KR1);
+ RIP4(A,B,C,D,E,WR20,SR20,KR1);
+ RIP4(E,A,B,C,D,WR21,SR21,KR1);
+ RIP4(D,E,A,B,C,WR22,SR22,KR1);
+ RIP4(C,D,E,A,B,WR23,SR23,KR1);
+ RIP4(B,C,D,E,A,WR24,SR24,KR1);
+ RIP4(A,B,C,D,E,WR25,SR25,KR1);
+ RIP4(E,A,B,C,D,WR26,SR26,KR1);
+ RIP4(D,E,A,B,C,WR27,SR27,KR1);
+ RIP4(C,D,E,A,B,WR28,SR28,KR1);
+ RIP4(B,C,D,E,A,WR29,SR29,KR1);
+ RIP4(A,B,C,D,E,WR30,SR30,KR1);
+ RIP4(E,A,B,C,D,WR31,SR31,KR1);
+
+ RIP3(D,E,A,B,C,WR32,SR32,KR2);
+ RIP3(C,D,E,A,B,WR33,SR33,KR2);
+ RIP3(B,C,D,E,A,WR34,SR34,KR2);
+ RIP3(A,B,C,D,E,WR35,SR35,KR2);
+ RIP3(E,A,B,C,D,WR36,SR36,KR2);
+ RIP3(D,E,A,B,C,WR37,SR37,KR2);
+ RIP3(C,D,E,A,B,WR38,SR38,KR2);
+ RIP3(B,C,D,E,A,WR39,SR39,KR2);
+ RIP3(A,B,C,D,E,WR40,SR40,KR2);
+ RIP3(E,A,B,C,D,WR41,SR41,KR2);
+ RIP3(D,E,A,B,C,WR42,SR42,KR2);
+ RIP3(C,D,E,A,B,WR43,SR43,KR2);
+ RIP3(B,C,D,E,A,WR44,SR44,KR2);
+ RIP3(A,B,C,D,E,WR45,SR45,KR2);
+ RIP3(E,A,B,C,D,WR46,SR46,KR2);
+ RIP3(D,E,A,B,C,WR47,SR47,KR2);
+
+ RIP2(C,D,E,A,B,WR48,SR48,KR3);
+ RIP2(B,C,D,E,A,WR49,SR49,KR3);
+ RIP2(A,B,C,D,E,WR50,SR50,KR3);
+ RIP2(E,A,B,C,D,WR51,SR51,KR3);
+ RIP2(D,E,A,B,C,WR52,SR52,KR3);
+ RIP2(C,D,E,A,B,WR53,SR53,KR3);
+ RIP2(B,C,D,E,A,WR54,SR54,KR3);
+ RIP2(A,B,C,D,E,WR55,SR55,KR3);
+ RIP2(E,A,B,C,D,WR56,SR56,KR3);
+ RIP2(D,E,A,B,C,WR57,SR57,KR3);
+ RIP2(C,D,E,A,B,WR58,SR58,KR3);
+ RIP2(B,C,D,E,A,WR59,SR59,KR3);
+ RIP2(A,B,C,D,E,WR60,SR60,KR3);
+ RIP2(E,A,B,C,D,WR61,SR61,KR3);
+ RIP2(D,E,A,B,C,WR62,SR62,KR3);
+ RIP2(C,D,E,A,B,WR63,SR63,KR3);
+
+ RIP1(B,C,D,E,A,WR64,SR64);
+ RIP1(A,B,C,D,E,WR65,SR65);
+ RIP1(E,A,B,C,D,WR66,SR66);
+ RIP1(D,E,A,B,C,WR67,SR67);
+ RIP1(C,D,E,A,B,WR68,SR68);
+ RIP1(B,C,D,E,A,WR69,SR69);
+ RIP1(A,B,C,D,E,WR70,SR70);
+ RIP1(E,A,B,C,D,WR71,SR71);
+ RIP1(D,E,A,B,C,WR72,SR72);
+ RIP1(C,D,E,A,B,WR73,SR73);
+ RIP1(B,C,D,E,A,WR74,SR74);
+ RIP1(A,B,C,D,E,WR75,SR75);
+ RIP1(E,A,B,C,D,WR76,SR76);
+ RIP1(D,E,A,B,C,WR77,SR77);
+ RIP1(C,D,E,A,B,WR78,SR78);
+ RIP1(B,C,D,E,A,WR79,SR79);
+
+ D =ctx->B+c+D;
+ ctx->B=ctx->C+d+E;
+ ctx->C=ctx->D+e+A;
+ ctx->D=ctx->E+a+B;
+ ctx->E=ctx->A+b+C;
+ ctx->A=D;
+
+ X+=16;
+ num-=64;
+ if (num <= 0) break;
+ }
+ }
+#endif
+
+void RIPEMD160_Final(md, c)
+unsigned char *md;
+RIPEMD160_CTX *c;
+ {
+ register int i,j;
+ register u_int32_t l;
+ register u_int32_t *p;
+ static unsigned char end[4]={0x80,0x00,0x00,0x00};
+ unsigned char *cp=end;
+
+ /* c->num should definitly have room for at least one more byte. */
+ p=c->data;
+ j=c->num;
+ i=j>>2;
+
+ /* purify often complains about the following line as an
+ * Uninitialized Memory Read. While this can be true, the
+ * following p_c2l macro will reset l when that case is true.
+ * This is because j&0x03 contains the number of 'valid' bytes
+ * already in p[i]. If and only if j&0x03 == 0, the UMR will
+ * occur but this is also the only time p_c2l will do
+ * l= *(cp++) instead of l|= *(cp++)
+ * Many thanks to Alex Tang <altitude@cic.net> for pickup this
+ * 'potential bug' */
+#ifdef PURIFY
+ if ((j&0x03) == 0) p[i]=0;
+#endif
+ l=p[i];
+ p_c2l(cp,l,j&0x03);
+ p[i]=l;
+ i++;
+ /* i is the next 'undefined word' */
+ if (c->num >= RIPEMD160_LAST_BLOCK)
+ {
+ for (; i<RIPEMD160_LBLOCK; i++)
+ p[i]=0;
+ ripemd160_block(c,p,64);
+ i=0;
+ }
+ for (; i<(RIPEMD160_LBLOCK-2); i++)
+ p[i]=0;
+ p[RIPEMD160_LBLOCK-2]=c->Nl;
+ p[RIPEMD160_LBLOCK-1]=c->Nh;
+ ripemd160_block(c,p,64);
+ cp=md;
+ l=c->A; l2c(l,cp);
+ l=c->B; l2c(l,cp);
+ l=c->C; l2c(l,cp);
+ l=c->D; l2c(l,cp);
+ l=c->E; l2c(l,cp);
+
+ /* clear stuff, ripemd160_block may be leaving some stuff on the stack
+ * but I'm not worried :-) */
+ c->num=0;
+/* memset((char *)&c,0,sizeof(c));*/
+ }
+
+#ifdef undef
+int printit(l)
+unsigned long *l;
+ {
+ int i,ii;
+
+ for (i=0; i<2; i++)
+ {
+ for (ii=0; ii<8; ii++)
+ {
+ fprintf(stderr,"%08lx ",l[i*8+ii]);
+ }
+ fprintf(stderr,"\n");
+ }
+ }
+#endif
diff --git a/lib/libmd/rmd_locl.h b/lib/libmd/rmd_locl.h
new file mode 100644
index 0000000..49f054c
--- /dev/null
+++ b/lib/libmd/rmd_locl.h
@@ -0,0 +1,216 @@
+/* crypto/ripemd/rmd_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "ripemd.h"
+
+#undef c2nl
+#define c2nl(c,l) (l =(((u_int32_t)(*((c)++)))<<24), \
+ l|=(((u_int32_t)(*((c)++)))<<16), \
+ l|=(((u_int32_t)(*((c)++)))<< 8), \
+ l|=(((u_int32_t)(*((c)++))) ))
+
+#undef p_c2nl
+#define p_c2nl(c,l,n) { \
+ switch (n) { \
+ case 0: l =((u_int32_t)(*((c)++)))<<24; \
+ case 1: l|=((u_int32_t)(*((c)++)))<<16; \
+ case 2: l|=((u_int32_t)(*((c)++)))<< 8; \
+ case 3: l|=((u_int32_t)(*((c)++))); \
+ } \
+ }
+
+#undef c2nl_p
+/* NOTE the pointer is not incremented at the end of this */
+#define c2nl_p(c,l,n) { \
+ l=0; \
+ (c)+=n; \
+ switch (n) { \
+ case 3: l =((u_int32_t)(*(--(c))))<< 8; \
+ case 2: l|=((u_int32_t)(*(--(c))))<<16; \
+ case 1: l|=((u_int32_t)(*(--(c))))<<24; \
+ } \
+ }
+
+#undef p_c2nl_p
+#define p_c2nl_p(c,l,sc,len) { \
+ switch (sc) \
+ { \
+ case 0: l =((u_int32_t)(*((c)++)))<<24; \
+ if (--len == 0) break; \
+ case 1: l|=((u_int32_t)(*((c)++)))<<16; \
+ if (--len == 0) break; \
+ case 2: l|=((u_int32_t)(*((c)++)))<< 8; \
+ } \
+ }
+
+#undef nl2c
+#define nl2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff))
+
+#undef c2l
+#define c2l(c,l) (l =(((u_int32_t)(*((c)++))) ), \
+ l|=(((u_int32_t)(*((c)++)))<< 8), \
+ l|=(((u_int32_t)(*((c)++)))<<16), \
+ l|=(((u_int32_t)(*((c)++)))<<24))
+
+#undef p_c2l
+#define p_c2l(c,l,n) { \
+ switch (n) { \
+ case 0: l =((u_int32_t)(*((c)++))); \
+ case 1: l|=((u_int32_t)(*((c)++)))<< 8; \
+ case 2: l|=((u_int32_t)(*((c)++)))<<16; \
+ case 3: l|=((u_int32_t)(*((c)++)))<<24; \
+ } \
+ }
+
+#undef c2l_p
+/* NOTE the pointer is not incremented at the end of this */
+#define c2l_p(c,l,n) { \
+ l=0; \
+ (c)+=n; \
+ switch (n) { \
+ case 3: l =((u_int32_t)(*(--(c))))<<16; \
+ case 2: l|=((u_int32_t)(*(--(c))))<< 8; \
+ case 1: l|=((u_int32_t)(*(--(c)))); \
+ } \
+ }
+
+#undef p_c2l_p
+#define p_c2l_p(c,l,sc,len) { \
+ switch (sc) \
+ { \
+ case 0: l =((u_int32_t)(*((c)++))); \
+ if (--len == 0) break; \
+ case 1: l|=((u_int32_t)(*((c)++)))<< 8; \
+ if (--len == 0) break; \
+ case 2: l|=((u_int32_t)(*((c)++)))<<16; \
+ } \
+ }
+
+#undef l2c
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff))
+
+#undef ROTATE
+#if defined(WIN32)
+#define ROTATE(a,n) _lrotl(a,n)
+#else
+#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+#endif
+
+/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
+#if defined(WIN32)
+/* 5 instructions with rotate instruction, else 9 */
+#define Endian_Reverse32(a) \
+ { \
+ u_int32_t l=(a); \
+ (a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \
+ }
+#else
+/* 6 instructions with rotate instruction, else 8 */
+#define Endian_Reverse32(a) \
+ { \
+ u_int32_t l=(a); \
+ l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \
+ (a)=ROTATE(l,16L); \
+ }
+#endif
+
+#define F1(x,y,z) ((x)^(y)^(z))
+#define F2(x,y,z) (((x)&(y))|((~x)&z))
+#define F3(x,y,z) (((x)|(~y))^(z))
+#define F4(x,y,z) (((x)&(z))|((y)&(~(z))))
+#define F5(x,y,z) ((x)^((y)|(~(z))))
+
+#define RIPEMD160_A 0x67452301L
+#define RIPEMD160_B 0xEFCDAB89L
+#define RIPEMD160_C 0x98BADCFEL
+#define RIPEMD160_D 0x10325476L
+#define RIPEMD160_E 0xC3D2E1F0L
+
+#include "rmdconst.h"
+
+#define RIP1(a,b,c,d,e,w,s) { \
+ a+=F1(b,c,d)+X[w]; \
+ a=ROTATE(a,s)+e; \
+ c=ROTATE(c,10); }
+
+#define RIP2(a,b,c,d,e,w,s,K) { \
+ a+=F2(b,c,d)+X[w]+K; \
+ a=ROTATE(a,s)+e; \
+ c=ROTATE(c,10); }
+
+#define RIP3(a,b,c,d,e,w,s,K) { \
+ a+=F3(b,c,d)+X[w]+K; \
+ a=ROTATE(a,s)+e; \
+ c=ROTATE(c,10); }
+
+#define RIP4(a,b,c,d,e,w,s,K) { \
+ a+=F4(b,c,d)+X[w]+K; \
+ a=ROTATE(a,s)+e; \
+ c=ROTATE(c,10); }
+
+#define RIP5(a,b,c,d,e,w,s,K) { \
+ a+=F5(b,c,d)+X[w]+K; \
+ a=ROTATE(a,s)+e; \
+ c=ROTATE(c,10); }
+
diff --git a/lib/libmd/rmdconst.h b/lib/libmd/rmdconst.h
new file mode 100644
index 0000000..59c48de
--- /dev/null
+++ b/lib/libmd/rmdconst.h
@@ -0,0 +1,399 @@
+/* crypto/ripemd/rmdconst.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#define KL0 0x00000000L
+#define KL1 0x5A827999L
+#define KL2 0x6ED9EBA1L
+#define KL3 0x8F1BBCDCL
+#define KL4 0xA953FD4EL
+
+#define KR0 0x50A28BE6L
+#define KR1 0x5C4DD124L
+#define KR2 0x6D703EF3L
+#define KR3 0x7A6D76E9L
+#define KR4 0x00000000L
+
+#define WL00 0
+#define SL00 11
+#define WL01 1
+#define SL01 14
+#define WL02 2
+#define SL02 15
+#define WL03 3
+#define SL03 12
+#define WL04 4
+#define SL04 5
+#define WL05 5
+#define SL05 8
+#define WL06 6
+#define SL06 7
+#define WL07 7
+#define SL07 9
+#define WL08 8
+#define SL08 11
+#define WL09 9
+#define SL09 13
+#define WL10 10
+#define SL10 14
+#define WL11 11
+#define SL11 15
+#define WL12 12
+#define SL12 6
+#define WL13 13
+#define SL13 7
+#define WL14 14
+#define SL14 9
+#define WL15 15
+#define SL15 8
+
+#define WL16 7
+#define SL16 7
+#define WL17 4
+#define SL17 6
+#define WL18 13
+#define SL18 8
+#define WL19 1
+#define SL19 13
+#define WL20 10
+#define SL20 11
+#define WL21 6
+#define SL21 9
+#define WL22 15
+#define SL22 7
+#define WL23 3
+#define SL23 15
+#define WL24 12
+#define SL24 7
+#define WL25 0
+#define SL25 12
+#define WL26 9
+#define SL26 15
+#define WL27 5
+#define SL27 9
+#define WL28 2
+#define SL28 11
+#define WL29 14
+#define SL29 7
+#define WL30 11
+#define SL30 13
+#define WL31 8
+#define SL31 12
+
+#define WL32 3
+#define SL32 11
+#define WL33 10
+#define SL33 13
+#define WL34 14
+#define SL34 6
+#define WL35 4
+#define SL35 7
+#define WL36 9
+#define SL36 14
+#define WL37 15
+#define SL37 9
+#define WL38 8
+#define SL38 13
+#define WL39 1
+#define SL39 15
+#define WL40 2
+#define SL40 14
+#define WL41 7
+#define SL41 8
+#define WL42 0
+#define SL42 13
+#define WL43 6
+#define SL43 6
+#define WL44 13
+#define SL44 5
+#define WL45 11
+#define SL45 12
+#define WL46 5
+#define SL46 7
+#define WL47 12
+#define SL47 5
+
+#define WL48 1
+#define SL48 11
+#define WL49 9
+#define SL49 12
+#define WL50 11
+#define SL50 14
+#define WL51 10
+#define SL51 15
+#define WL52 0
+#define SL52 14
+#define WL53 8
+#define SL53 15
+#define WL54 12
+#define SL54 9
+#define WL55 4
+#define SL55 8
+#define WL56 13
+#define SL56 9
+#define WL57 3
+#define SL57 14
+#define WL58 7
+#define SL58 5
+#define WL59 15
+#define SL59 6
+#define WL60 14
+#define SL60 8
+#define WL61 5
+#define SL61 6
+#define WL62 6
+#define SL62 5
+#define WL63 2
+#define SL63 12
+
+#define WL64 4
+#define SL64 9
+#define WL65 0
+#define SL65 15
+#define WL66 5
+#define SL66 5
+#define WL67 9
+#define SL67 11
+#define WL68 7
+#define SL68 6
+#define WL69 12
+#define SL69 8
+#define WL70 2
+#define SL70 13
+#define WL71 10
+#define SL71 12
+#define WL72 14
+#define SL72 5
+#define WL73 1
+#define SL73 12
+#define WL74 3
+#define SL74 13
+#define WL75 8
+#define SL75 14
+#define WL76 11
+#define SL76 11
+#define WL77 6
+#define SL77 8
+#define WL78 15
+#define SL78 5
+#define WL79 13
+#define SL79 6
+
+#define WR00 5
+#define SR00 8
+#define WR01 14
+#define SR01 9
+#define WR02 7
+#define SR02 9
+#define WR03 0
+#define SR03 11
+#define WR04 9
+#define SR04 13
+#define WR05 2
+#define SR05 15
+#define WR06 11
+#define SR06 15
+#define WR07 4
+#define SR07 5
+#define WR08 13
+#define SR08 7
+#define WR09 6
+#define SR09 7
+#define WR10 15
+#define SR10 8
+#define WR11 8
+#define SR11 11
+#define WR12 1
+#define SR12 14
+#define WR13 10
+#define SR13 14
+#define WR14 3
+#define SR14 12
+#define WR15 12
+#define SR15 6
+
+#define WR16 6
+#define SR16 9
+#define WR17 11
+#define SR17 13
+#define WR18 3
+#define SR18 15
+#define WR19 7
+#define SR19 7
+#define WR20 0
+#define SR20 12
+#define WR21 13
+#define SR21 8
+#define WR22 5
+#define SR22 9
+#define WR23 10
+#define SR23 11
+#define WR24 14
+#define SR24 7
+#define WR25 15
+#define SR25 7
+#define WR26 8
+#define SR26 12
+#define WR27 12
+#define SR27 7
+#define WR28 4
+#define SR28 6
+#define WR29 9
+#define SR29 15
+#define WR30 1
+#define SR30 13
+#define WR31 2
+#define SR31 11
+
+#define WR32 15
+#define SR32 9
+#define WR33 5
+#define SR33 7
+#define WR34 1
+#define SR34 15
+#define WR35 3
+#define SR35 11
+#define WR36 7
+#define SR36 8
+#define WR37 14
+#define SR37 6
+#define WR38 6
+#define SR38 6
+#define WR39 9
+#define SR39 14
+#define WR40 11
+#define SR40 12
+#define WR41 8
+#define SR41 13
+#define WR42 12
+#define SR42 5
+#define WR43 2
+#define SR43 14
+#define WR44 10
+#define SR44 13
+#define WR45 0
+#define SR45 13
+#define WR46 4
+#define SR46 7
+#define WR47 13
+#define SR47 5
+
+#define WR48 8
+#define SR48 15
+#define WR49 6
+#define SR49 5
+#define WR50 4
+#define SR50 8
+#define WR51 1
+#define SR51 11
+#define WR52 3
+#define SR52 14
+#define WR53 11
+#define SR53 14
+#define WR54 15
+#define SR54 6
+#define WR55 0
+#define SR55 14
+#define WR56 5
+#define SR56 6
+#define WR57 12
+#define SR57 9
+#define WR58 2
+#define SR58 12
+#define WR59 13
+#define SR59 9
+#define WR60 9
+#define SR60 12
+#define WR61 7
+#define SR61 5
+#define WR62 10
+#define SR62 15
+#define WR63 14
+#define SR63 8
+
+#define WR64 12
+#define SR64 8
+#define WR65 15
+#define SR65 5
+#define WR66 10
+#define SR66 12
+#define WR67 4
+#define SR67 9
+#define WR68 1
+#define SR68 12
+#define WR69 5
+#define SR69 5
+#define WR70 8
+#define SR70 14
+#define WR71 7
+#define SR71 6
+#define WR72 6
+#define SR72 8
+#define WR73 2
+#define SR73 13
+#define WR74 13
+#define SR74 6
+#define WR75 14
+#define SR75 5
+#define WR76 0
+#define SR76 15
+#define WR77 3
+#define SR77 13
+#define WR78 9
+#define SR78 11
+#define WR79 11
+#define SR79 11
+
diff --git a/lib/libmd/rmddriver.c b/lib/libmd/rmddriver.c
new file mode 100644
index 0000000..4278a0f
--- /dev/null
+++ b/lib/libmd/rmddriver.c
@@ -0,0 +1,51 @@
+/* RIPEMD160DRIVER.C - test driver for RIPEMD160
+ * $FreeBSD$
+ */
+
+/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+ rights reserved.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include "ripemd.h"
+
+/* Digests a string and prints the result.
+ */
+static void RIPEMD160String (string)
+char *string;
+{
+ char buf[2*20+1];
+
+ printf ("RIPEMD160 (\"%s\") = %s\n",
+ string, RIPEMD160_Data(string,strlen(string),buf));
+}
+
+/* Digests a reference suite of strings and prints the results.
+ */
+main()
+{
+ printf ("RIPEMD160 test suite:\n");
+
+ RIPEMD160String ("");
+ RIPEMD160String ("abc");
+ RIPEMD160String ("message digest");
+ RIPEMD160String ("abcdefghijklmnopqrstuvwxyz");
+ RIPEMD160String
+ ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+ RIPEMD160String
+ ("1234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890");
+ return 0;
+}
diff --git a/lib/libmd/sha.3 b/lib/libmd/sha.3
new file mode 100644
index 0000000..5af126d
--- /dev/null
+++ b/lib/libmd/sha.3
@@ -0,0 +1,151 @@
+.\"
+.\" ----------------------------------------------------------------------------
+.\" "THE BEER-WARE LICENSE" (Revision 42):
+.\" <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you
+.\" can do whatever you want with this stuff. If we meet some day, and you think
+.\" this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+.\" ----------------------------------------------------------------------------
+.\"
+.\" From: Id: mdX.3,v 1.14 1999/02/11 20:31:49 wollman Exp
+.\" $FreeBSD$
+.\"
+.Dd February 25, 1999
+.Dt SHA 3
+.Os FreeBSD 4.0
+.Sh NAME
+.Nm SHA_Init ,
+.Nm SHA_Update ,
+.Nm SHA_Final ,
+.Nm SHA_End ,
+.Nm SHA_File ,
+.Nm SHA_Data ,
+.Nm SHA1_Init ,
+.Nm SHA1_Update ,
+.Nm SHA1_Final ,
+.Nm SHA1_End ,
+.Nm SHA1_File ,
+.Nm SHA1_Data
+.Nd calculate the FIPS 160 and 160-1 ``SHA'' message digests
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sha.h>
+.Ft void
+.Fn SHA_Init "SHA_CTX *context"
+.Ft void
+.Fn SHA_Update "SHA_CTX *context" "const unsigned char *data" "unsigned int len"
+.Ft void
+.Fn SHA_Final "unsigned char digest[20]" "SHA_CTX *context"
+.Ft "char *"
+.Fn SHA_End "SHA_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA_File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA_Data "const unsigned char *data" "unsigned int len" "char *buf"
+.Ft void
+.Fn SHA1_Init "SHA_CTX *context"
+.Ft void
+.Fn SHA1_Update "SHA_CTX *context" "const unsigned char *data" "unsigned int len"
+.Ft void
+.Fn SHA1_Final "unsigned char digest[20]" "SHA_CTX *context"
+.Ft "char *"
+.Fn SHA1_End "SHA_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA1_File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA1_Data "const unsigned char *data" "unsigned int len" "char *buf"
+.Sh DESCRIPTION
+The
+.Li SHA_
+and
+.Li SHA1_
+functions calculate a 160-bit cryptographic checksum (digest)
+for any number of input bytes. A cryptographic checksum is a one-way
+hash function; that is, it is computationally impractical to find
+the input corresponding to a particular output. This net result is
+a ``fingerprint'' of the input-data, which doesn't disclose the actual
+input.
+.Pp
+.Tn SHA
+.Pq \&or Tn SHA-0
+is the original Secure Hash Algorithm specified in
+.Tn FIPS
+160. It was quickly proven insecure, and has been superseded by
+.Tn SHA-1 .
+.Tn SHA-0
+is included for compatibility purposes only.
+.Pp
+The
+.Fn SHA1_Init ,
+.Fn SHA1_Update ,
+and
+.Fn SHA1_Final
+functions are the core functions. Allocate an SHA_CTX, initialize it with
+.Fn SHA1_Init ,
+run over the data with
+.Fn SHA1_Update ,
+and finally extract the result using
+.Fn SHA1_Final .
+.Pp
+.Fn SHA1_End
+is a wrapper for
+.Fn SHA1_Final
+which converts the return value to a 41-character
+(including the terminating '\e0')
+.Tn ASCII
+string which represents the 160 bits in hexadecimal.
+.Pp
+.Fn SHA1_File
+calculates the digest of a file, and uses
+.Fn SHA1_End
+to return the result.
+If the file cannot be opened, a null pointer is returned.
+.Fn SHA1_Data
+calculates the digest of a chunk of data in memory, and uses
+.Fn SHA1_End
+to return the result.
+.Pp
+When using
+.Fn SHA1_End ,
+.Fn SHA1_File ,
+or
+.Fn SHA1_Data ,
+the
+.Ar buf
+argument can be a null pointer, in which case the returned string
+is allocated with
+.Xr malloc 3
+and subsequently must be explicitly deallocated using
+.Xr free 3
+after use.
+If the
+.Ar buf
+argument is non-null it must point to at least 41 characters of buffer space.
+.Sh SEE ALSO
+.Xr md2 3 ,
+.Xr md4 3 ,
+.Xr md5 3 ,
+.Xr ripemd 3
+.Sh AUTHORS
+The core hash routines were implemented by Eric Young based on the
+published
+.Tn FIPS
+standards.
+.Sh HISTORY
+These functions appeared in
+.Fx 4.0 .
+.Sh BUGS
+No method is known to exist which finds two files having the same hash value,
+nor to find a file with a specific hash value.
+There is on the other hand no guarantee that such a method doesn't exist.
+.Pp
+The
+.Tn IA32
+(Intel) implementation of
+.Tn SHA-1
+makes heavy use of the
+.Ql bswapl
+instruction, which is not present on the original 80386. Attempts
+to use
+.Tn SHA-1
+on those processors will cause an illegal instruction trap.
+(Arguably, the kernel should simply emulate this instruction.)
diff --git a/lib/libmd/sha.h b/lib/libmd/sha.h
new file mode 100644
index 0000000..7380330
--- /dev/null
+++ b/lib/libmd/sha.h
@@ -0,0 +1,96 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SHA_H_
+#define _SHA_H_ 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h> /* XXX switch to machine/ansi.h and __ types */
+
+#define SHA_CBLOCK 64
+#define SHA_LBLOCK 16
+#define SHA_BLOCK 16
+#define SHA_LAST_BLOCK 56
+#define SHA_LENGTH_BLOCK 8
+#define SHA_DIGEST_LENGTH 20
+
+typedef struct SHAstate_st {
+ u_int32_t h0, h1, h2, h3, h4;
+ u_int32_t Nl, Nh;
+ u_int32_t data[SHA_LBLOCK];
+ int num;
+} SHA_CTX;
+#define SHA1_CTX SHA_CTX
+
+__BEGIN_DECLS
+void SHA_Init(SHA_CTX *c);
+void SHA_Update(SHA_CTX *c, const unsigned char *data, size_t len);
+void SHA_Final(unsigned char *md, SHA_CTX *c);
+char *SHA_End(SHA_CTX *, char *);
+char *SHA_File(const char *, char *);
+char *SHA_Data(const unsigned char *, unsigned int, char *);
+void SHA1_Init(SHA_CTX *c);
+void SHA1_Update(SHA_CTX *c, const unsigned char *data, size_t len);
+void SHA1_Final(unsigned char *md, SHA_CTX *c);
+char *SHA1_End(SHA_CTX *, char *);
+char *SHA1_File(const char *, char *);
+char *SHA1_Data(const unsigned char *, unsigned int, char *);
+__END_DECLS
+
+#endif /* !_SHA_H_ */
diff --git a/lib/libmd/sha0c.c b/lib/libmd/sha0c.c
new file mode 100644
index 0000000..19c2728
--- /dev/null
+++ b/lib/libmd/sha0c.c
@@ -0,0 +1,452 @@
+/* crypto/sha/sha_dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if 0
+#include <machine/ansi.h> /* we use the __ variants of bit-sized types */
+#endif
+#include <machine/endian.h>
+
+#define SHA_0
+#undef SHA_1
+#include "sha.h"
+#include "sha_locl.h"
+
+char *SHA_version="SHA part of SSLeay 0.9.0b 11-Oct-1998";
+
+/* Implemented from SHA-0 document - The Secure Hash Algorithm
+ */
+
+#define INIT_DATA_h0 (unsigned long)0x67452301L
+#define INIT_DATA_h1 (unsigned long)0xefcdab89L
+#define INIT_DATA_h2 (unsigned long)0x98badcfeL
+#define INIT_DATA_h3 (unsigned long)0x10325476L
+#define INIT_DATA_h4 (unsigned long)0xc3d2e1f0L
+
+#define K_00_19 0x5a827999L
+#define K_20_39 0x6ed9eba1L
+#define K_40_59 0x8f1bbcdcL
+#define K_60_79 0xca62c1d6L
+
+#ifndef NOPROTO
+ void sha_block(SHA_CTX *c, const u_int32_t *p, int num);
+#else
+ void sha_block();
+#endif
+
+#define M_c2nl c2nl
+#define M_p_c2nl p_c2nl
+#define M_c2nl_p c2nl_p
+#define M_p_c2nl_p p_c2nl_p
+#define M_nl2c nl2c
+
+void SHA_Init(c)
+SHA_CTX *c;
+ {
+ c->h0=INIT_DATA_h0;
+ c->h1=INIT_DATA_h1;
+ c->h2=INIT_DATA_h2;
+ c->h3=INIT_DATA_h3;
+ c->h4=INIT_DATA_h4;
+ c->Nl=0;
+ c->Nh=0;
+ c->num=0;
+ }
+
+void SHA_Update(c, data, len)
+SHA_CTX *c;
+const unsigned char *data;
+size_t len;
+ {
+ register u_int32_t *p;
+ int ew,ec,sw,sc;
+ u_int32_t l;
+
+ if (len == 0) return;
+
+ l=(c->Nl+(len<<3))&0xffffffffL;
+ if (l < c->Nl) /* overflow */
+ c->Nh++;
+ c->Nh+=(len>>29);
+ c->Nl=l;
+
+ if (c->num != 0)
+ {
+ p=c->data;
+ sw=c->num>>2;
+ sc=c->num&0x03;
+
+ if ((c->num+len) >= SHA_CBLOCK)
+ {
+ l= p[sw];
+ M_p_c2nl(data,l,sc);
+ p[sw++]=l;
+ for (; sw<SHA_LBLOCK; sw++)
+ {
+ M_c2nl(data,l);
+ p[sw]=l;
+ }
+ len-=(SHA_CBLOCK-c->num);
+
+ sha_block(c,p,64);
+ c->num=0;
+ /* drop through and do the rest */
+ }
+ else
+ {
+ c->num+=(int)len;
+ if ((sc+len) < 4) /* ugly, add char's to a word */
+ {
+ l= p[sw];
+ M_p_c2nl_p(data,l,sc,len);
+ p[sw]=l;
+ }
+ else
+ {
+ ew=(c->num>>2);
+ ec=(c->num&0x03);
+ l= p[sw];
+ M_p_c2nl(data,l,sc);
+ p[sw++]=l;
+ for (; sw < ew; sw++)
+ { M_c2nl(data,l); p[sw]=l; }
+ if (ec)
+ {
+ M_c2nl_p(data,l,ec);
+ p[sw]=l;
+ }
+ }
+ return;
+ }
+ }
+ /* We can only do the following code for assember, the reason
+ * being that the sha_block 'C' version changes the values
+ * in the 'data' array. The assember code avoids this and
+ * copies it to a local array. I should be able to do this for
+ * the C version as well....
+ */
+#if 1
+#if BYTE_ORDER == BIG_ENDIAN || defined(SHA_ASM)
+ if ((((unsigned int)data)%sizeof(u_int32_t)) == 0)
+ {
+ sw=len/SHA_CBLOCK;
+ if (sw)
+ {
+ sw*=SHA_CBLOCK;
+ sha_block(c,(u_int32_t *)data,sw);
+ data+=sw;
+ len-=sw;
+ }
+ }
+#endif
+#endif
+ /* we now can process the input data in blocks of SHA_CBLOCK
+ * chars and save the leftovers to c->data. */
+ p=c->data;
+ while (len >= SHA_CBLOCK)
+ {
+#if BYTE_ORDER == BIG_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN
+ if (p != (u_int32_t *)data)
+ memcpy(p,data,SHA_CBLOCK);
+ data+=SHA_CBLOCK;
+# if BYTE_ORDER == LITTLE_ENDIAN
+# ifndef SHA_ASM /* Will not happen */
+ for (sw=(SHA_LBLOCK/4); sw; sw--)
+ {
+ Endian_Reverse32(p[0]);
+ Endian_Reverse32(p[1]);
+ Endian_Reverse32(p[2]);
+ Endian_Reverse32(p[3]);
+ p+=4;
+ }
+ p=c->data;
+# endif
+# endif
+#else
+ for (sw=(SHA_BLOCK/4); sw; sw--)
+ {
+ M_c2nl(data,l); *(p++)=l;
+ M_c2nl(data,l); *(p++)=l;
+ M_c2nl(data,l); *(p++)=l;
+ M_c2nl(data,l); *(p++)=l;
+ }
+ p=c->data;
+#endif
+ sha_block(c,p,64);
+ len-=SHA_CBLOCK;
+ }
+ ec=(int)len;
+ c->num=ec;
+ ew=(ec>>2);
+ ec&=0x03;
+
+ for (sw=0; sw < ew; sw++)
+ { M_c2nl(data,l); p[sw]=l; }
+ M_c2nl_p(data,l,ec);
+ p[sw]=l;
+ }
+
+void SHA_Transform(c,b)
+SHA_CTX *c;
+unsigned char *b;
+ {
+ u_int32_t p[16];
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int32_t *q;
+ int i;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN
+ memcpy(p,b,64);
+#if BYTE_ORDER == LITTLE_ENDIAN
+ q=p;
+ for (i=(SHA_LBLOCK/4); i; i--)
+ {
+ Endian_Reverse32(q[0]);
+ Endian_Reverse32(q[1]);
+ Endian_Reverse32(q[2]);
+ Endian_Reverse32(q[3]);
+ q+=4;
+ }
+#endif
+#else
+ q=p;
+ for (i=(SHA_LBLOCK/4); i; i--)
+ {
+ u_int32_t l;
+ c2nl(b,l); *(q++)=l;
+ c2nl(b,l); *(q++)=l;
+ c2nl(b,l); *(q++)=l;
+ c2nl(b,l); *(q++)=l;
+ }
+#endif
+ sha_block(c,p,64);
+ }
+
+void sha_block(c, W, num)
+SHA_CTX *c;
+const u_int32_t *W;
+int num;
+ {
+ register u_int32_t A,B,C,D,E,T;
+ u_int32_t X[16];
+
+ A=c->h0;
+ B=c->h1;
+ C=c->h2;
+ D=c->h3;
+ E=c->h4;
+
+ for (;;)
+ {
+ BODY_00_15( 0,A,B,C,D,E,T,W);
+ BODY_00_15( 1,T,A,B,C,D,E,W);
+ BODY_00_15( 2,E,T,A,B,C,D,W);
+ BODY_00_15( 3,D,E,T,A,B,C,W);
+ BODY_00_15( 4,C,D,E,T,A,B,W);
+ BODY_00_15( 5,B,C,D,E,T,A,W);
+ BODY_00_15( 6,A,B,C,D,E,T,W);
+ BODY_00_15( 7,T,A,B,C,D,E,W);
+ BODY_00_15( 8,E,T,A,B,C,D,W);
+ BODY_00_15( 9,D,E,T,A,B,C,W);
+ BODY_00_15(10,C,D,E,T,A,B,W);
+ BODY_00_15(11,B,C,D,E,T,A,W);
+ BODY_00_15(12,A,B,C,D,E,T,W);
+ BODY_00_15(13,T,A,B,C,D,E,W);
+ BODY_00_15(14,E,T,A,B,C,D,W);
+ BODY_00_15(15,D,E,T,A,B,C,W);
+ BODY_16_19(16,C,D,E,T,A,B,W,W,W,W);
+ BODY_16_19(17,B,C,D,E,T,A,W,W,W,W);
+ BODY_16_19(18,A,B,C,D,E,T,W,W,W,W);
+ BODY_16_19(19,T,A,B,C,D,E,W,W,W,X);
+
+ BODY_20_31(20,E,T,A,B,C,D,W,W,W,X);
+ BODY_20_31(21,D,E,T,A,B,C,W,W,W,X);
+ BODY_20_31(22,C,D,E,T,A,B,W,W,W,X);
+ BODY_20_31(23,B,C,D,E,T,A,W,W,W,X);
+ BODY_20_31(24,A,B,C,D,E,T,W,W,X,X);
+ BODY_20_31(25,T,A,B,C,D,E,W,W,X,X);
+ BODY_20_31(26,E,T,A,B,C,D,W,W,X,X);
+ BODY_20_31(27,D,E,T,A,B,C,W,W,X,X);
+ BODY_20_31(28,C,D,E,T,A,B,W,W,X,X);
+ BODY_20_31(29,B,C,D,E,T,A,W,W,X,X);
+ BODY_20_31(30,A,B,C,D,E,T,W,X,X,X);
+ BODY_20_31(31,T,A,B,C,D,E,W,X,X,X);
+ BODY_32_39(32,E,T,A,B,C,D,X);
+ BODY_32_39(33,D,E,T,A,B,C,X);
+ BODY_32_39(34,C,D,E,T,A,B,X);
+ BODY_32_39(35,B,C,D,E,T,A,X);
+ BODY_32_39(36,A,B,C,D,E,T,X);
+ BODY_32_39(37,T,A,B,C,D,E,X);
+ BODY_32_39(38,E,T,A,B,C,D,X);
+ BODY_32_39(39,D,E,T,A,B,C,X);
+
+ BODY_40_59(40,C,D,E,T,A,B,X);
+ BODY_40_59(41,B,C,D,E,T,A,X);
+ BODY_40_59(42,A,B,C,D,E,T,X);
+ BODY_40_59(43,T,A,B,C,D,E,X);
+ BODY_40_59(44,E,T,A,B,C,D,X);
+ BODY_40_59(45,D,E,T,A,B,C,X);
+ BODY_40_59(46,C,D,E,T,A,B,X);
+ BODY_40_59(47,B,C,D,E,T,A,X);
+ BODY_40_59(48,A,B,C,D,E,T,X);
+ BODY_40_59(49,T,A,B,C,D,E,X);
+ BODY_40_59(50,E,T,A,B,C,D,X);
+ BODY_40_59(51,D,E,T,A,B,C,X);
+ BODY_40_59(52,C,D,E,T,A,B,X);
+ BODY_40_59(53,B,C,D,E,T,A,X);
+ BODY_40_59(54,A,B,C,D,E,T,X);
+ BODY_40_59(55,T,A,B,C,D,E,X);
+ BODY_40_59(56,E,T,A,B,C,D,X);
+ BODY_40_59(57,D,E,T,A,B,C,X);
+ BODY_40_59(58,C,D,E,T,A,B,X);
+ BODY_40_59(59,B,C,D,E,T,A,X);
+
+ BODY_60_79(60,A,B,C,D,E,T,X);
+ BODY_60_79(61,T,A,B,C,D,E,X);
+ BODY_60_79(62,E,T,A,B,C,D,X);
+ BODY_60_79(63,D,E,T,A,B,C,X);
+ BODY_60_79(64,C,D,E,T,A,B,X);
+ BODY_60_79(65,B,C,D,E,T,A,X);
+ BODY_60_79(66,A,B,C,D,E,T,X);
+ BODY_60_79(67,T,A,B,C,D,E,X);
+ BODY_60_79(68,E,T,A,B,C,D,X);
+ BODY_60_79(69,D,E,T,A,B,C,X);
+ BODY_60_79(70,C,D,E,T,A,B,X);
+ BODY_60_79(71,B,C,D,E,T,A,X);
+ BODY_60_79(72,A,B,C,D,E,T,X);
+ BODY_60_79(73,T,A,B,C,D,E,X);
+ BODY_60_79(74,E,T,A,B,C,D,X);
+ BODY_60_79(75,D,E,T,A,B,C,X);
+ BODY_60_79(76,C,D,E,T,A,B,X);
+ BODY_60_79(77,B,C,D,E,T,A,X);
+ BODY_60_79(78,A,B,C,D,E,T,X);
+ BODY_60_79(79,T,A,B,C,D,E,X);
+
+ c->h0=(c->h0+E)&0xffffffffL;
+ c->h1=(c->h1+T)&0xffffffffL;
+ c->h2=(c->h2+A)&0xffffffffL;
+ c->h3=(c->h3+B)&0xffffffffL;
+ c->h4=(c->h4+C)&0xffffffffL;
+
+ num-=64;
+ if (num <= 0) break;
+
+ A=c->h0;
+ B=c->h1;
+ C=c->h2;
+ D=c->h3;
+ E=c->h4;
+
+ W+=16;
+ }
+ }
+
+void SHA_Final(md, c)
+unsigned char *md;
+SHA_CTX *c;
+ {
+ register int i,j;
+ register u_int32_t l;
+ register u_int32_t *p;
+ static unsigned char end[4]={0x80,0x00,0x00,0x00};
+ unsigned char *cp=end;
+
+ /* c->num should definitly have room for at least one more byte. */
+ p=c->data;
+ j=c->num;
+ i=j>>2;
+#ifdef PURIFY
+ if ((j&0x03) == 0) p[i]=0;
+#endif
+ l=p[i];
+ M_p_c2nl(cp,l,j&0x03);
+ p[i]=l;
+ i++;
+ /* i is the next 'undefined word' */
+ if (c->num >= SHA_LAST_BLOCK)
+ {
+ for (; i<SHA_LBLOCK; i++)
+ p[i]=0;
+ sha_block(c,p,64);
+ i=0;
+ }
+ for (; i<(SHA_LBLOCK-2); i++)
+ p[i]=0;
+ p[SHA_LBLOCK-2]=c->Nh;
+ p[SHA_LBLOCK-1]=c->Nl;
+ sha_block(c,p,64);
+ cp=md;
+ l=c->h0; nl2c(l,cp);
+ l=c->h1; nl2c(l,cp);
+ l=c->h2; nl2c(l,cp);
+ l=c->h3; nl2c(l,cp);
+ l=c->h4; nl2c(l,cp);
+
+ /* clear stuff, sha_block may be leaving some stuff on the stack
+ * but I'm not worried :-) */
+ c->num=0;
+/* memset((char *)&c,0,sizeof(c));*/
+ }
+
diff --git a/lib/libmd/sha1c.c b/lib/libmd/sha1c.c
new file mode 100644
index 0000000..660cff9
--- /dev/null
+++ b/lib/libmd/sha1c.c
@@ -0,0 +1,486 @@
+/* crypto/sha/sha1dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if 0
+#include <machine/ansi.h> /* we use the __ variants of bit-sized types */
+#endif
+#include <machine/endian.h>
+
+#undef SHA_0
+#define SHA_1
+#include "sha.h"
+#include "sha_locl.h"
+
+/*
+ * The assembly-language code is not position-independent, so don't
+ * try to use it in a shared library.
+ */
+#ifdef PIC
+#undef SHA1_ASM
+#endif
+
+char *SHA1_version="SHA1 part of SSLeay 0.9.0b 11-Oct-1998";
+
+/* Implemented from SHA-1 document - The Secure Hash Algorithm
+ */
+
+#define INIT_DATA_h0 (unsigned long)0x67452301L
+#define INIT_DATA_h1 (unsigned long)0xefcdab89L
+#define INIT_DATA_h2 (unsigned long)0x98badcfeL
+#define INIT_DATA_h3 (unsigned long)0x10325476L
+#define INIT_DATA_h4 (unsigned long)0xc3d2e1f0L
+
+#define K_00_19 0x5a827999L
+#define K_20_39 0x6ed9eba1L
+#define K_40_59 0x8f1bbcdcL
+#define K_60_79 0xca62c1d6L
+
+#ifndef NOPROTO
+# ifdef SHA1_ASM
+ void sha1_block_x86(SHA_CTX *c, const u_int32_t *p, int num);
+# define sha1_block sha1_block_x86
+# else
+ void sha1_block(SHA_CTX *c, const u_int32_t *p, int num);
+# endif
+#else
+# ifdef SHA1_ASM
+ void sha1_block_x86();
+# define sha1_block sha1_block_x86
+# else
+ void sha1_block();
+# endif
+#endif
+
+
+#if BYTE_ORDER == LITTLE_ENDIAN && defined(SHA1_ASM)
+# define M_c2nl c2l
+# define M_p_c2nl p_c2l
+# define M_c2nl_p c2l_p
+# define M_p_c2nl_p p_c2l_p
+# define M_nl2c l2c
+#else
+# define M_c2nl c2nl
+# define M_p_c2nl p_c2nl
+# define M_c2nl_p c2nl_p
+# define M_p_c2nl_p p_c2nl_p
+# define M_nl2c nl2c
+#endif
+
+void SHA1_Init(c)
+SHA_CTX *c;
+ {
+ c->h0=INIT_DATA_h0;
+ c->h1=INIT_DATA_h1;
+ c->h2=INIT_DATA_h2;
+ c->h3=INIT_DATA_h3;
+ c->h4=INIT_DATA_h4;
+ c->Nl=0;
+ c->Nh=0;
+ c->num=0;
+ }
+
+void
+SHA1_Update(c, data, len)
+ SHA_CTX *c;
+ const unsigned char *data;
+ size_t len;
+{
+ register u_int32_t *p;
+ int ew,ec,sw,sc;
+ u_int32_t l;
+
+ if (len == 0) return;
+
+ l=(c->Nl+(len<<3))&0xffffffffL;
+ if (l < c->Nl) /* overflow */
+ c->Nh++;
+ c->Nh+=(len>>29);
+ c->Nl=l;
+
+ if (c->num != 0)
+ {
+ p=c->data;
+ sw=c->num>>2;
+ sc=c->num&0x03;
+
+ if ((c->num+len) >= SHA_CBLOCK)
+ {
+ l= p[sw];
+ M_p_c2nl(data,l,sc);
+ p[sw++]=l;
+ for (; sw<SHA_LBLOCK; sw++)
+ {
+ M_c2nl(data,l);
+ p[sw]=l;
+ }
+ len-=(SHA_CBLOCK-c->num);
+
+ sha1_block(c,p,64);
+ c->num=0;
+ /* drop through and do the rest */
+ }
+ else
+ {
+ c->num+=(int)len;
+ if ((sc+len) < 4) /* ugly, add char's to a word */
+ {
+ l= p[sw];
+ M_p_c2nl_p(data,l,sc,len);
+ p[sw]=l;
+ }
+ else
+ {
+ ew=(c->num>>2);
+ ec=(c->num&0x03);
+ l= p[sw];
+ M_p_c2nl(data,l,sc);
+ p[sw++]=l;
+ for (; sw < ew; sw++)
+ { M_c2nl(data,l); p[sw]=l; }
+ if (ec)
+ {
+ M_c2nl_p(data,l,ec);
+ p[sw]=l;
+ }
+ }
+ return;
+ }
+ }
+ /* We can only do the following code for assember, the reason
+ * being that the sha1_block 'C' version changes the values
+ * in the 'data' array. The assember code avoids this and
+ * copies it to a local array. I should be able to do this for
+ * the C version as well....
+ */
+#if 1
+#if BYTE_ORDER == BIG_ENDIAN || defined(SHA1_ASM)
+ if ((((unsigned int)data)%sizeof(u_int32_t)) == 0)
+ {
+ sw=len/SHA_CBLOCK;
+ if (sw)
+ {
+ sw*=SHA_CBLOCK;
+ sha1_block(c,(u_int32_t *)data,sw);
+ data+=sw;
+ len-=sw;
+ }
+ }
+#endif
+#endif
+ /* we now can process the input data in blocks of SHA_CBLOCK
+ * chars and save the leftovers to c->data. */
+ p=c->data;
+ while (len >= SHA_CBLOCK)
+ {
+#if BYTE_ORDER == BIG_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN
+ if (p != (u_int32_t *)data)
+ memcpy(p,data,SHA_CBLOCK);
+ data+=SHA_CBLOCK;
+# if BYTE_ORDER == LITTLE_ENDIAN
+# ifndef SHA1_ASM /* Will not happen */
+ for (sw=(SHA_LBLOCK/4); sw; sw--)
+ {
+ Endian_Reverse32(p[0]);
+ Endian_Reverse32(p[1]);
+ Endian_Reverse32(p[2]);
+ Endian_Reverse32(p[3]);
+ p+=4;
+ }
+ p=c->data;
+# endif
+# endif
+#else
+ for (sw=(SHA_BLOCK/4); sw; sw--)
+ {
+ M_c2nl(data,l); *(p++)=l;
+ M_c2nl(data,l); *(p++)=l;
+ M_c2nl(data,l); *(p++)=l;
+ M_c2nl(data,l); *(p++)=l;
+ }
+ p=c->data;
+#endif
+ sha1_block(c,p,64);
+ len-=SHA_CBLOCK;
+ }
+ ec=(int)len;
+ c->num=ec;
+ ew=(ec>>2);
+ ec&=0x03;
+
+ for (sw=0; sw < ew; sw++)
+ { M_c2nl(data,l); p[sw]=l; }
+ M_c2nl_p(data,l,ec);
+ p[sw]=l;
+ }
+
+void SHA1_Transform(c,b)
+SHA_CTX *c;
+unsigned char *b;
+ {
+ u_int32_t p[16];
+#if BYTE_ORDER != BIG_ENDIAN
+ u_int32_t *q;
+ int i;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN
+ memcpy(p,b,64);
+#if BYTE_ORDER == LITTLE_ENDIAN
+ q=p;
+ for (i=(SHA_LBLOCK/4); i; i--)
+ {
+ Endian_Reverse32(q[0]);
+ Endian_Reverse32(q[1]);
+ Endian_Reverse32(q[2]);
+ Endian_Reverse32(q[3]);
+ q+=4;
+ }
+#endif
+#else
+ q=p;
+ for (i=(SHA_LBLOCK/4); i; i--)
+ {
+ u_int32_t l;
+ c2nl(b,l); *(q++)=l;
+ c2nl(b,l); *(q++)=l;
+ c2nl(b,l); *(q++)=l;
+ c2nl(b,l); *(q++)=l;
+ }
+#endif
+ sha1_block(c,p,64);
+ }
+
+#ifndef SHA1_ASM
+
+void
+sha1_block(c, W, num)
+ SHA_CTX *c;
+ const u_int32_t *W;
+ int num;
+{
+ register u_int32_t A,B,C,D,E,T;
+ u_int32_t X[16];
+
+ A=c->h0;
+ B=c->h1;
+ C=c->h2;
+ D=c->h3;
+ E=c->h4;
+
+ for (;;)
+ {
+ BODY_00_15( 0,A,B,C,D,E,T,W);
+ BODY_00_15( 1,T,A,B,C,D,E,W);
+ BODY_00_15( 2,E,T,A,B,C,D,W);
+ BODY_00_15( 3,D,E,T,A,B,C,W);
+ BODY_00_15( 4,C,D,E,T,A,B,W);
+ BODY_00_15( 5,B,C,D,E,T,A,W);
+ BODY_00_15( 6,A,B,C,D,E,T,W);
+ BODY_00_15( 7,T,A,B,C,D,E,W);
+ BODY_00_15( 8,E,T,A,B,C,D,W);
+ BODY_00_15( 9,D,E,T,A,B,C,W);
+ BODY_00_15(10,C,D,E,T,A,B,W);
+ BODY_00_15(11,B,C,D,E,T,A,W);
+ BODY_00_15(12,A,B,C,D,E,T,W);
+ BODY_00_15(13,T,A,B,C,D,E,W);
+ BODY_00_15(14,E,T,A,B,C,D,W);
+ BODY_00_15(15,D,E,T,A,B,C,W);
+ BODY_16_19(16,C,D,E,T,A,B,W,W,W,W);
+ BODY_16_19(17,B,C,D,E,T,A,W,W,W,W);
+ BODY_16_19(18,A,B,C,D,E,T,W,W,W,W);
+ BODY_16_19(19,T,A,B,C,D,E,W,W,W,X);
+
+ BODY_20_31(20,E,T,A,B,C,D,W,W,W,X);
+ BODY_20_31(21,D,E,T,A,B,C,W,W,W,X);
+ BODY_20_31(22,C,D,E,T,A,B,W,W,W,X);
+ BODY_20_31(23,B,C,D,E,T,A,W,W,W,X);
+ BODY_20_31(24,A,B,C,D,E,T,W,W,X,X);
+ BODY_20_31(25,T,A,B,C,D,E,W,W,X,X);
+ BODY_20_31(26,E,T,A,B,C,D,W,W,X,X);
+ BODY_20_31(27,D,E,T,A,B,C,W,W,X,X);
+ BODY_20_31(28,C,D,E,T,A,B,W,W,X,X);
+ BODY_20_31(29,B,C,D,E,T,A,W,W,X,X);
+ BODY_20_31(30,A,B,C,D,E,T,W,X,X,X);
+ BODY_20_31(31,T,A,B,C,D,E,W,X,X,X);
+ BODY_32_39(32,E,T,A,B,C,D,X);
+ BODY_32_39(33,D,E,T,A,B,C,X);
+ BODY_32_39(34,C,D,E,T,A,B,X);
+ BODY_32_39(35,B,C,D,E,T,A,X);
+ BODY_32_39(36,A,B,C,D,E,T,X);
+ BODY_32_39(37,T,A,B,C,D,E,X);
+ BODY_32_39(38,E,T,A,B,C,D,X);
+ BODY_32_39(39,D,E,T,A,B,C,X);
+
+ BODY_40_59(40,C,D,E,T,A,B,X);
+ BODY_40_59(41,B,C,D,E,T,A,X);
+ BODY_40_59(42,A,B,C,D,E,T,X);
+ BODY_40_59(43,T,A,B,C,D,E,X);
+ BODY_40_59(44,E,T,A,B,C,D,X);
+ BODY_40_59(45,D,E,T,A,B,C,X);
+ BODY_40_59(46,C,D,E,T,A,B,X);
+ BODY_40_59(47,B,C,D,E,T,A,X);
+ BODY_40_59(48,A,B,C,D,E,T,X);
+ BODY_40_59(49,T,A,B,C,D,E,X);
+ BODY_40_59(50,E,T,A,B,C,D,X);
+ BODY_40_59(51,D,E,T,A,B,C,X);
+ BODY_40_59(52,C,D,E,T,A,B,X);
+ BODY_40_59(53,B,C,D,E,T,A,X);
+ BODY_40_59(54,A,B,C,D,E,T,X);
+ BODY_40_59(55,T,A,B,C,D,E,X);
+ BODY_40_59(56,E,T,A,B,C,D,X);
+ BODY_40_59(57,D,E,T,A,B,C,X);
+ BODY_40_59(58,C,D,E,T,A,B,X);
+ BODY_40_59(59,B,C,D,E,T,A,X);
+
+ BODY_60_79(60,A,B,C,D,E,T,X);
+ BODY_60_79(61,T,A,B,C,D,E,X);
+ BODY_60_79(62,E,T,A,B,C,D,X);
+ BODY_60_79(63,D,E,T,A,B,C,X);
+ BODY_60_79(64,C,D,E,T,A,B,X);
+ BODY_60_79(65,B,C,D,E,T,A,X);
+ BODY_60_79(66,A,B,C,D,E,T,X);
+ BODY_60_79(67,T,A,B,C,D,E,X);
+ BODY_60_79(68,E,T,A,B,C,D,X);
+ BODY_60_79(69,D,E,T,A,B,C,X);
+ BODY_60_79(70,C,D,E,T,A,B,X);
+ BODY_60_79(71,B,C,D,E,T,A,X);
+ BODY_60_79(72,A,B,C,D,E,T,X);
+ BODY_60_79(73,T,A,B,C,D,E,X);
+ BODY_60_79(74,E,T,A,B,C,D,X);
+ BODY_60_79(75,D,E,T,A,B,C,X);
+ BODY_60_79(76,C,D,E,T,A,B,X);
+ BODY_60_79(77,B,C,D,E,T,A,X);
+ BODY_60_79(78,A,B,C,D,E,T,X);
+ BODY_60_79(79,T,A,B,C,D,E,X);
+
+ c->h0=(c->h0+E)&0xffffffffL;
+ c->h1=(c->h1+T)&0xffffffffL;
+ c->h2=(c->h2+A)&0xffffffffL;
+ c->h3=(c->h3+B)&0xffffffffL;
+ c->h4=(c->h4+C)&0xffffffffL;
+
+ num-=64;
+ if (num <= 0) break;
+
+ A=c->h0;
+ B=c->h1;
+ C=c->h2;
+ D=c->h3;
+ E=c->h4;
+
+ W+=16;
+ }
+ }
+#endif
+
+void SHA1_Final(md, c)
+unsigned char *md;
+SHA_CTX *c;
+ {
+ register int i,j;
+ register u_int32_t l;
+ register u_int32_t *p;
+ static unsigned char end[4]={0x80,0x00,0x00,0x00};
+ unsigned char *cp=end;
+
+ /* c->num should definitly have room for at least one more byte. */
+ p=c->data;
+ j=c->num;
+ i=j>>2;
+#ifdef PURIFY
+ if ((j&0x03) == 0) p[i]=0;
+#endif
+ l=p[i];
+ M_p_c2nl(cp,l,j&0x03);
+ p[i]=l;
+ i++;
+ /* i is the next 'undefined word' */
+ if (c->num >= SHA_LAST_BLOCK)
+ {
+ for (; i<SHA_LBLOCK; i++)
+ p[i]=0;
+ sha1_block(c,p,64);
+ i=0;
+ }
+ for (; i<(SHA_LBLOCK-2); i++)
+ p[i]=0;
+ p[SHA_LBLOCK-2]=c->Nh;
+ p[SHA_LBLOCK-1]=c->Nl;
+#if BYTE_ORDER == LITTLE_ENDIAN && defined(SHA1_ASM)
+ Endian_Reverse32(p[SHA_LBLOCK-2]);
+ Endian_Reverse32(p[SHA_LBLOCK-1]);
+#endif
+ sha1_block(c,p,64);
+ cp=md;
+ l=c->h0; nl2c(l,cp);
+ l=c->h1; nl2c(l,cp);
+ l=c->h2; nl2c(l,cp);
+ l=c->h3; nl2c(l,cp);
+ l=c->h4; nl2c(l,cp);
+
+ /* clear stuff, sha1_block may be leaving some stuff on the stack
+ * but I'm not worried :-) */
+ c->num=0;
+/* memset((char *)&c,0,sizeof(c));*/
+ }
+
diff --git a/lib/libmd/sha_locl.h b/lib/libmd/sha_locl.h
new file mode 100644
index 0000000..461c9ea
--- /dev/null
+++ b/lib/libmd/sha_locl.h
@@ -0,0 +1,243 @@
+/* crypto/sha/sha_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifdef undef
+/* one or the other needs to be defined */
+#ifndef SHA_1 /* FIPE 180-1 */
+#define SHA_0 /* FIPS 180 */
+#endif
+#endif
+
+#define ULONG unsigned long
+#define UCHAR unsigned char
+#define UINT unsigned int
+
+#ifdef NOCONST
+#define const
+#endif
+
+#undef c2nl
+#define c2nl(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++))) ))
+
+#undef p_c2nl
+#define p_c2nl(c,l,n) { \
+ switch (n) { \
+ case 0: l =((unsigned long)(*((c)++)))<<24; \
+ case 1: l|=((unsigned long)(*((c)++)))<<16; \
+ case 2: l|=((unsigned long)(*((c)++)))<< 8; \
+ case 3: l|=((unsigned long)(*((c)++))); \
+ } \
+ }
+
+#undef c2nl_p
+/* NOTE the pointer is not incremented at the end of this */
+#define c2nl_p(c,l,n) { \
+ l=0; \
+ (c)+=n; \
+ switch (n) { \
+ case 3: l =((unsigned long)(*(--(c))))<< 8; \
+ case 2: l|=((unsigned long)(*(--(c))))<<16; \
+ case 1: l|=((unsigned long)(*(--(c))))<<24; \
+ } \
+ }
+
+#undef p_c2nl_p
+#define p_c2nl_p(c,l,sc,len) { \
+ switch (sc) \
+ { \
+ case 0: l =((unsigned long)(*((c)++)))<<24; \
+ if (--len == 0) break; \
+ case 1: l|=((unsigned long)(*((c)++)))<<16; \
+ if (--len == 0) break; \
+ case 2: l|=((unsigned long)(*((c)++)))<< 8; \
+ } \
+ }
+
+#undef nl2c
+#define nl2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff))
+
+#undef c2l
+#define c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<<24))
+
+#undef p_c2l
+#define p_c2l(c,l,n) { \
+ switch (n) { \
+ case 0: l =((unsigned long)(*((c)++))); \
+ case 1: l|=((unsigned long)(*((c)++)))<< 8; \
+ case 2: l|=((unsigned long)(*((c)++)))<<16; \
+ case 3: l|=((unsigned long)(*((c)++)))<<24; \
+ } \
+ }
+
+#undef c2l_p
+/* NOTE the pointer is not incremented at the end of this */
+#define c2l_p(c,l,n) { \
+ l=0; \
+ (c)+=n; \
+ switch (n) { \
+ case 3: l =((unsigned long)(*(--(c))))<<16; \
+ case 2: l|=((unsigned long)(*(--(c))))<< 8; \
+ case 1: l|=((unsigned long)(*(--(c)))); \
+ } \
+ }
+
+#undef p_c2l_p
+#define p_c2l_p(c,l,sc,len) { \
+ switch (sc) \
+ { \
+ case 0: l =((unsigned long)(*((c)++))); \
+ if (--len == 0) break; \
+ case 1: l|=((unsigned long)(*((c)++)))<< 8; \
+ if (--len == 0) break; \
+ case 2: l|=((unsigned long)(*((c)++)))<<16; \
+ } \
+ }
+
+#undef l2c
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff))
+
+#undef ROTATE
+#if defined(WIN32)
+#define ROTATE(a,n) _lrotl(a,n)
+#else
+#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+#endif
+
+/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
+#if defined(WIN32)
+/* 5 instructions with rotate instruction, else 9 */
+#define Endian_Reverse32(a) \
+ { \
+ unsigned long l=(a); \
+ (a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \
+ }
+#else
+/* 6 instructions with rotate instruction, else 8 */
+#define Endian_Reverse32(a) \
+ { \
+ unsigned long l=(a); \
+ l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \
+ (a)=ROTATE(l,16L); \
+ }
+#endif
+
+/* As pointed out by Wei Dai <weidai@eskimo.com>, F() below can be
+ * simplified to the code in F_00_19. Wei attributes these optimisations
+ * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
+ * #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
+ * I've just become aware of another tweak to be made, again from Wei Dai,
+ * in F_40_59, (x&a)|(y&a) -> (x|y)&a
+ */
+#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
+#define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
+#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d)))
+#define F_60_79(b,c,d) F_20_39(b,c,d)
+
+#ifdef SHA_0
+#undef Xupdate
+#define Xupdate(a,i,ia,ib,ic,id) X[(i)&0x0f]=(a)=\
+ (ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]);
+#endif
+#ifdef SHA_1
+#undef Xupdate
+#define Xupdate(a,i,ia,ib,ic,id) (a)=\
+ (ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]);\
+ X[(i)&0x0f]=(a)=ROTATE((a),1);
+#endif
+
+#define BODY_00_15(i,a,b,c,d,e,f,xa) \
+ (f)=xa[i]+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+#define BODY_16_19(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+ Xupdate(f,i,xa,xb,xc,xd); \
+ (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+#define BODY_20_31(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+ Xupdate(f,i,xa,xb,xc,xd); \
+ (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+#define BODY_32_39(i,a,b,c,d,e,f,xa) \
+ Xupdate(f,i,xa,xa,xa,xa); \
+ (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+#define BODY_40_59(i,a,b,c,d,e,f,xa) \
+ Xupdate(f,i,xa,xa,xa,xa); \
+ (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+#define BODY_60_79(i,a,b,c,d,e,f,xa) \
+ Xupdate(f,i,xa,xa,xa,xa); \
+ (f)=X[(i)&0x0f]+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
diff --git a/lib/libmd/shadriver.c b/lib/libmd/shadriver.c
new file mode 100644
index 0000000..454fac8
--- /dev/null
+++ b/lib/libmd/shadriver.c
@@ -0,0 +1,61 @@
+/* SHADRIVER.C - test driver for SHA-1 (and SHA-0)
+ * $FreeBSD$
+ */
+
+/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+ rights reserved.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+ */
+
+/* The following makes SHA default to SHA-1 if it has not already been
+ defined with C compiler flags.
+ */
+#ifndef SHA
+#define SHA 1
+#endif
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include "sha.h"
+#if SHA == 1
+#define SHA_Data SHA1_Data
+#endif
+
+/* Digests a string and prints the result.
+ */
+static void SHAString (string)
+char *string;
+{
+ char buf[2*20+1];
+
+ printf ("SHA-%d (\"%s\") = %s\n",
+ SHA, string, SHA_Data(string,strlen(string),buf));
+}
+
+/* Digests a reference suite of strings and prints the results.
+ */
+main()
+{
+ printf ("SHA-%d test suite:\n", SHA);
+
+ SHAString ("");
+ SHAString ("abc");
+ SHAString ("message digest");
+ SHAString ("abcdefghijklmnopqrstuvwxyz");
+ SHAString
+ ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+ SHAString
+ ("1234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890");
+ return 0;
+}
diff --git a/lib/libmenu/Makefile b/lib/libmenu/Makefile
new file mode 100644
index 0000000..11fb19d
--- /dev/null
+++ b/lib/libmenu/Makefile
@@ -0,0 +1,24 @@
+# Makefile for libmenu
+# $FreeBSD$
+
+NCURSES=${.CURDIR}/../../contrib/ncurses
+
+.PATH: ${NCURSES}/menu
+
+LIB= menu
+
+SRCS= m_attribs.c m_cursor.c m_driver.c m_format.c m_global.c m_hook.c \
+ m_item_cur.c m_item_nam.c m_item_new.c m_item_opt.c m_item_use.c \
+ m_item_val.c m_item_vis.c m_items.c m_new.c m_opts.c m_post.c \
+ m_req_name.c m_spacing.c m_userptr.c m_win.c
+
+CFLAGS+= -I${.CURDIR}/../libncurses -I${NCURSES}/menu -I${NCURSES}/include \
+ -Wall -DNDEBUG -DHAVE_CONFIG_H
+
+beforeinstall:
+.for i in menu.h eti.h
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 ${NCURSES}/menu/$i \
+ ${DESTDIR}/usr/include
+.endfor
+
+.include <bsd.lib.mk>
diff --git a/lib/libncp/CREDITS b/lib/libncp/CREDITS
new file mode 100644
index 0000000..4338055
--- /dev/null
+++ b/lib/libncp/CREDITS
@@ -0,0 +1,27 @@
+# $FreeBSD$
+
+In the development of NetWare client for FreeBSD next sources was used:
+
+ncpfs for Linux - written by Volker Lendecke (lendecke@math.uni-goettingen.de),
+ thanks to him for giving a permission to publish his code under BSD-style
+ license.
+
+"Interrupt List" from Ralf Brown,
+
+Many files from the /sys directory.
+
+NDK documentation from Novell Inc.
+
+
+Also thanks to thouse who gets time to testing, reporting problems and give
+a good suggestions (in alphabet order):
+
+Anatoly A. Orehovsky
+Andrew Petrenko
+Jesus Rodriguez
+Matthew N. Dodd
+Mike Pitt
+Vadim Mikhailov
+
+
+Author - Boris Popov <bp@butya.kz>, <bp@freebsd.org>
diff --git a/lib/libncp/Makefile b/lib/libncp/Makefile
new file mode 100644
index 0000000..39a0708
--- /dev/null
+++ b/lib/libncp/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+NCPLIB=${.CURDIR}
+
+LIB= ncp
+
+SHLIB_MAJOR= 1
+SHLIB_MINOR= 0
+
+NOMAN=
+
+SRCS= ncpl_subr.c ncpl_bind.c ncpl_queue.c ncpl_file.c ncpl_misc.c \
+ ncpl_net.c ncpl_rcfile.c ncpl_conn.c ncpl_nls.c ncpl_msg.c \
+ ncpl_rpc.c ncpl_crypt.c ipx.c sap.c
+
+.include <bsd.lib.mk>
diff --git a/lib/libncp/ipx.c b/lib/libncp/ipx.c
new file mode 100644
index 0000000..9284d08
--- /dev/null
+++ b/lib/libncp/ipx.c
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/route.h>
+
+/* IPX */
+#include <netipx/ipx.h>
+#include <netipx/ipx_if.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <netncp/ncp_lib.h>
+
+#define IPX_NODE_LEN 6
+
+typedef u_long IPXNet;
+typedef u_short IPXPort;
+typedef union ipx_host IPXNode;
+
+
+void
+ipx_fprint_node(FILE * file, IPXNode node){
+ fprintf(file, "%02X%02X%02X%02X%02X%02X",
+ (unsigned char) node.c_host[0],
+ (unsigned char) node.c_host[1],
+ (unsigned char) node.c_host[2],
+ (unsigned char) node.c_host[3],
+ (unsigned char) node.c_host[4],
+ (unsigned char) node.c_host[5]
+ );
+}
+
+void
+ipx_fprint_network(FILE * file, const IPXNet net){
+ fprintf(file, "%08X", (u_int32_t)ntohl(net));
+}
+
+void
+ipx_fprint_port(FILE * file, IPXPort port)
+{
+ fprintf(file, "%04X", ntohs(port));
+}
+
+void
+ipx_fprint_addr(FILE * file, struct ipx_addr *ipx)
+{
+ ipx_fprint_network(file, ipx_netlong(*ipx));
+ fprintf(file, ":");
+ ipx_fprint_node(file, ipx->x_host);
+ fprintf(file, ":");
+ ipx_fprint_port(file, ipx->x_port);
+}
+
+void
+ipx_print_node(IPXNode node)
+{
+ ipx_fprint_node(stdout, node);
+}
+
+void
+ipx_print_network(IPXNet net)
+{
+ ipx_fprint_network(stdout, net);
+}
+
+void
+ipx_print_port(IPXPort port)
+{
+ ipx_fprint_port(stdout, port);
+}
+
+void
+ipx_print_addr(struct ipx_addr *ipx)
+{
+ ipx_fprint_addr(stdout, ipx);
+}
+
+int
+ipx_sscanf_node(char *buf, unsigned char node[6])
+{
+ int i;
+ int n[6];
+
+ if ((i = sscanf(buf, "%2x%2x%2x%2x%2x%2x",
+ &(n[0]), &(n[1]), &(n[2]),
+ &(n[3]), &(n[4]), &(n[5]))) != 6)
+ {
+ return i;
+ }
+ for (i = 0; i < 6; i++)
+ {
+ node[i] = n[i];
+ }
+ return 6;
+}
+
+int
+ipx_sscanf_saddr(char *buf, struct sockaddr_ipx *target)
+{
+ char *p;
+ struct sockaddr_ipx addr;
+ unsigned long sipx_net;
+
+ addr.sipx_family = AF_IPX;
+/*!! addr.sipx_type = NCP_PTYPE;*/
+
+ if (sscanf(buf, "%lx", &sipx_net) != 1)
+ {
+ return 1;
+ }
+ ((union ipx_net_u*)(&addr.sipx_addr.x_net))->long_e = htonl(sipx_net);
+ if ((p = strchr(buf, ':')) == NULL){
+ return 1;
+ }
+ p += 1;
+ if (ipx_sscanf_node(p, addr.sipx_node) != 6)
+ {
+ return 1;
+ }
+ if ((p = strchr(p, ':')) == NULL)
+ {
+ return 1;
+ }
+ p += 1;
+ if (sscanf(p, "%hx", &addr.sipx_port) != 1)
+ {
+ return 1;
+ }
+ addr.sipx_port = htons(addr.sipx_port);
+ *target = addr;
+ return 0;
+}
+
+
+void ipx_assign_node(IPXNode *dest, IPXNode *src) {
+ memcpy(dest, src, IPX_NODE_LEN);
+}
+
+
+static void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));
+static int if_ipxscan __P((int addrcount, struct sockaddr_dl *sdl, struct if_msghdr *ifm,
+ struct ifa_msghdr *ifam,struct ipx_addr *addr));
+
+/*
+ * Find an IPX interface.
+ * ifname specifies interface name, if NULL search for all interfaces
+ * if ifname[0]='0', also all interfaces, but return its name
+ * addr on input preferred net address can be specified or 0 for any,
+ * on return contains full address (except port)
+ * returns 0 if interface was found
+ */
+int
+ipx_iffind(char *ifname,struct ipx_addr *addr){
+ char name[32];
+ int all=0, flags, foundit = 0, addrcount;
+ struct if_msghdr *ifm, *nextifm;
+ struct ifa_msghdr *ifam;
+ struct sockaddr_dl *sdl;
+ char *buf, *lim, *next;
+ size_t needed;
+ int mib[6];
+
+ if( ifname!=NULL ) {
+ strncpy(name,ifname,sizeof(name)-1);
+ if( name[0]==0 )
+ all=1;
+ } else
+ all = 1;
+
+ mib[0] = CTL_NET;
+ mib[1] = PF_ROUTE;
+ mib[2] = 0;
+ mib[3] = AF_IPX;
+ mib[4] = NET_RT_IFLIST;
+ mib[5] = 0;
+
+ if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+ return(1);
+ if ((buf = malloc(needed)) == NULL)
+ return(1);
+ if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
+ free(buf);
+ return(1);
+ }
+ lim = buf + needed;
+
+ next = buf;
+ while (next < lim) {
+ ifm = (struct if_msghdr *)next;
+ if (ifm->ifm_type == RTM_IFINFO) {
+ sdl = (struct sockaddr_dl *)(ifm + 1);
+ flags = ifm->ifm_flags;
+ } else {
+ fprintf(stderr, "if_ipxfind: out of sync parsing NET_RT_IFLIST\n");
+ fprintf(stderr, "expected %d, got %d\n", RTM_IFINFO, ifm->ifm_type);
+ fprintf(stderr, "msglen = %d\n", ifm->ifm_msglen);
+ fprintf(stderr, "buf:%p, next:%p, lim:%p\n", buf, next, lim);
+ free(buf);
+ return(1);
+ }
+
+ next += ifm->ifm_msglen;
+ ifam = NULL;
+ addrcount = 0;
+ while (next < lim) {
+ nextifm = (struct if_msghdr *)next;
+ if (nextifm->ifm_type != RTM_NEWADDR)
+ break;
+ if (ifam == NULL)
+ ifam = (struct ifa_msghdr *)nextifm;
+ addrcount++;
+ next += nextifm->ifm_msglen;
+ }
+
+ if (all) {
+ if ((flags & IFF_UP) == 0)
+ continue; /* not up */
+ strncpy(name, sdl->sdl_data, sdl->sdl_nlen);
+ name[sdl->sdl_nlen] = '\0';
+ } else {
+ if (strlen(name) != sdl->sdl_nlen)
+ continue; /* not same len */
+ if (strncmp(name, sdl->sdl_data, sdl->sdl_nlen) != 0)
+ continue; /* not same name */
+ }
+
+ foundit=if_ipxscan(addrcount, sdl, ifm, ifam, addr);
+ if( foundit ) {
+ if( ifname!=NULL && ifname[0]==0) {
+ strncpy(ifname,sdl->sdl_data, sdl->sdl_nlen);
+ ifname[sdl->sdl_nlen]=0;
+ }
+ break;
+ }
+ }
+ free(buf);
+
+ return foundit ? 0:1;
+}
+
+
+int
+if_ipxscan(addrcount, sdl, ifm, ifam, addr)
+ int addrcount;
+ struct sockaddr_dl *sdl;
+ struct if_msghdr *ifm;
+ struct ifa_msghdr *ifam;
+ struct ipx_addr *addr;
+{
+ struct rt_addrinfo info;
+ struct sockaddr_ipx *sipx;
+ int s;
+
+ if ((s = socket(AF_IPX, SOCK_DGRAM, 0)) < 0) {
+ perror("ifconfig: socket");
+ return 0;
+ }
+
+ while (addrcount > 0) {
+ info.rti_addrs = ifam->ifam_addrs;
+ /* Expand the compacted addresses */
+ rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam, &info);
+ addrcount--;
+ ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
+ if (info.rti_info[RTAX_IFA]->sa_family == AF_IPX) {
+ sipx = (struct sockaddr_ipx *)info.rti_info[RTAX_IFA];
+ if( ipx_nullnet(sipx->sipx_addr) ) continue;
+ if( ipx_nullnet(*addr) ||
+ ipx_neteq(sipx->sipx_addr,*addr) ) {
+ *addr=sipx->sipx_addr;
+ close(s);
+ return(1);
+ }
+ }
+ }
+ close(s);
+ return(0);
+}
+/*
+ * Expand the compacted form of addresses as returned via the
+ * configuration read via sysctl().
+ */
+
+#define ROUNDUP(a) \
+ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+
+static void
+rt_xaddrs(cp, cplim, rtinfo)
+ caddr_t cp, cplim;
+ struct rt_addrinfo *rtinfo;
+{
+ struct sockaddr *sa;
+ int i;
+
+ memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info));
+ for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
+ if ((rtinfo->rti_addrs & (1 << i)) == 0)
+ continue;
+ rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
+ ADVANCE(cp, sa);
+ }
+}
+
diff --git a/lib/libncp/ipxsap.h b/lib/libncp/ipxsap.h
new file mode 100644
index 0000000..2d8d7f0
--- /dev/null
+++ b/lib/libncp/ipxsap.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef _IPXSAP_H_
+#define _IPXSAP_H_
+
+#define IPX_SAP_GENERAL_QUERY 1
+#define IPX_SAP_GENERAL_RESPONSE 2
+#define IPX_SAP_NEAREST_QUERY 3
+#define IPX_SAP_NEAREST_RESPONSE 4
+
+
+#define IPX_SAP_MAX_ENTRIES 7
+#define IPX_SAP_SERVER_DOWN 16
+#define IPX_SAP_SERVER_NAME_LEN 48
+#define IPX_SAP_REQUEST_LEN 4
+
+/* Values for server_type */
+#define IPX_SAP_FILE_SERVER 4
+
+struct sap_query {
+ u_short query_type; /* net order */
+ u_short server_type; /* net order */
+};
+
+struct sap_entry {
+ u_short server_type;
+ u_char server_name[IPX_SAP_SERVER_NAME_LEN];
+ struct ipx_addr ipx;
+ u_short hops;
+};
+
+struct sap_packet {
+ u_short operation;
+ struct sap_entry sap_entries[1];
+};
+
+struct sap_rq {
+ struct sockaddr_ipx dest_addr;
+ int sock;
+ int entries;
+ struct sap_packet* buffer;
+};
+/*
+#define sap_name_equal(n1,n2) (strncmp(n1,n2,IPX_SAP_SERVER_NAME_LEN) == 0);
+#define sap_type_equal(t1,t2) (t1==IPX_SAP_GENERAL_RQ || t2==IPX_SAP_GENERAL_RQ || t1==t2);
+*/
+void sap_copy_name(char *dest,char *src);
+int sap_getsock(int *rsock);
+
+
+int sap_rq_init(struct sap_rq* out,int sock);
+int sap_rq_flush(struct sap_rq* out);
+void sap_rq_general(struct sap_rq* out,u_short ser_type);
+void sap_rq_gns_request(struct sap_rq* out,u_short ser_type);
+void sap_rq_response(struct sap_rq* out,u_short type,char *name,struct sockaddr_ipx* addr,u_short hops,int down_allow);
+void sap_rq_gns_response(struct sap_rq* out,u_short type,char * name,struct sockaddr_ipx* addr,u_short hops);
+void sap_rq_set_destination(struct sap_rq* out,struct ipx_addr *dest);
+
+int sap_find_nearest(int server_type, struct sockaddr_ipx *result,char *server_name);
+
+extern int (*sap_sendto_func)(void* buffer,int size,struct sockaddr_ipx* daddr,int sock);
+int ipx_iffind(char *ifname, struct ipx_addr *addr);
+
+#endif /* !_IPXSAP_H_ */
diff --git a/lib/libncp/ncp_mod.h b/lib/libncp/ncp_mod.h
new file mode 100644
index 0000000..4bdc39a
--- /dev/null
+++ b/lib/libncp/ncp_mod.h
@@ -0,0 +1,16 @@
+/*
+ * Describes all ncp_lib kernel functions
+ *
+ * $FreeBSD$
+ */
+#ifndef _NCP_MOD_H_
+#define _NCP_MOD_H_
+
+/* order of calls in syscall table relative to offset in system table */
+#define NCP_SE(callno) (callno+sysentoffset)
+#define NCP_CONNSCAN NCP_SE(0)
+#define NCP_CONNECT NCP_SE(1)
+#define NCP_INTFN NCP_SE(2)
+#define SNCP_REQUEST NCP_SE(3)
+
+#endif /* !_NCP_MOD_H_ */ \ No newline at end of file
diff --git a/lib/libncp/ncpl_bind.c b/lib/libncp/ncpl_bind.c
new file mode 100644
index 0000000..53c4c31
--- /dev/null
+++ b/lib/libncp/ncpl_bind.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <errno.h>
+#include <string.h>
+#include <netncp/ncp_lib.h>
+
+static void nw_passencrypt(char *old, char *new, char *out);
+
+int
+ncp_get_bindery_object_id(NWCONN_HANDLE connid, u_int16_t object_type,
+ const char *object_name, struct ncp_bindery_object *target)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 53);
+ ncp_add_word_hl(conn, object_type);
+ ncp_add_pstring(conn, object_name);
+
+ if ((error = ncp_request(connid, 23, conn)) != 0) {
+ return error;
+ }
+ if (conn->rpsize < 54) {
+ return EACCES;
+ }
+ target->object_id = ncp_reply_dword_hl(conn, 0);
+ target->object_type = ncp_reply_word_hl(conn, 4);
+ memcpy(target->object_name, ncp_reply_data(conn, 6), 48);
+ return 0;
+}
+
+int
+ncp_read_property_value(NWCONN_HANDLE connid, int object_type,
+ const char *object_name, int segment, const char *prop_name,
+ struct nw_property *target)
+{
+ int error;
+ struct ncp_buf conn;
+ ncp_init_request_s(&conn, 61);
+ ncp_add_word_hl(&conn, object_type);
+ ncp_add_pstring(&conn, object_name);
+ ncp_add_byte(&conn, segment);
+ ncp_add_pstring(&conn, prop_name);
+
+ if ((error = ncp_request(connid,23,&conn)) != 0) {
+ return error;
+ }
+ memcpy(&(target->value), ncp_reply_data(&conn, 0), 128);
+ target->more_flag = ncp_reply_byte(&conn, 128);
+ target->property_flag = ncp_reply_byte(&conn, 129);
+ return 0;
+}
+
+int
+ncp_scan_bindery_object(NWCONN_HANDLE connid, u_int32_t last_id,
+ u_int16_t object_type, char *search_string,
+ struct ncp_bindery_object *target)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 55);
+ ncp_add_dword_hl(conn, last_id);
+ ncp_add_word_hl(conn, object_type);
+ ncp_add_pstring(conn, search_string);
+ error = ncp_request(connid, 23, conn);
+ if (error) return error;
+ target->object_id = ncp_reply_dword_hl(conn, 0);
+ target->object_type = ncp_reply_word_hl(conn, 4);
+ memcpy(target->object_name, ncp_reply_data(conn, 6),NCP_BINDERY_NAME_LEN);
+ target->object_flags = ncp_reply_byte(conn, 54);
+ target->object_security = ncp_reply_byte(conn, 55);
+ target->object_has_prop = ncp_reply_byte(conn, 56);
+ return 0;
+}
+
+int
+ncp_get_bindery_object_name(NWCONN_HANDLE connid, u_int32_t object_id,
+ struct ncp_bindery_object *target)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 54);
+ ncp_add_dword_hl(conn, object_id);
+ if ((error = ncp_request(connid, 23, conn)) != 0)
+ return error;
+ target->object_id = ncp_reply_dword_hl(conn, 0);
+ target->object_type = ncp_reply_word_hl(conn, 4);
+ memcpy(target->object_name, ncp_reply_data(conn, 6), 48);
+ return 0;
+}
+
+int
+ncp_change_obj_passwd(NWCONN_HANDLE connid,
+ const struct ncp_bindery_object *object,
+ const u_char *key,
+ const u_char *oldpasswd,
+ const u_char *newpasswd)
+{
+ long id = htonl(object->object_id);
+ u_char cryptkey[8];
+ u_char newpwd[16]; /* new passwd as stored by server */
+ u_char oldpwd[16]; /* old passwd as stored by server */
+ u_char len;
+ DECLARE_RQ;
+
+ memcpy(cryptkey, key, 8);
+ nw_keyhash((u_char *)&id, oldpasswd, strlen(oldpasswd), oldpwd);
+ nw_keyhash((u_char *)&id, newpasswd, strlen(newpasswd), newpwd);
+ nw_encrypt(cryptkey, oldpwd, cryptkey);
+ nw_passencrypt(oldpwd, newpwd, newpwd);
+ nw_passencrypt(oldpwd + 8, newpwd + 8, newpwd + 8);
+ if ((len = strlen(newpasswd)) > 63) {
+ len = 63;
+ }
+ len = ((len ^ oldpwd[0] ^ oldpwd[1]) & 0x7f) | 0x40;
+
+ ncp_init_request_s(conn, 75);
+ ncp_add_mem(conn, cryptkey, 8);
+ ncp_add_word_hl(conn, object->object_type);
+ ncp_add_pstring(conn, object->object_name);
+ ncp_add_byte(conn, len);
+ ncp_add_mem(conn, newpwd, 16);
+ return ncp_request(connid, 23, conn);
+}
+
+/*
+ * target is a 8-byte buffer
+ */
+int
+ncp_get_encryption_key(NWCONN_HANDLE cH, char *target) {
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 23);
+
+ error = ncp_request(cH, 23, conn);
+ if (error)
+ return error;
+ if (conn->rpsize < 8)
+ return EACCES;
+ memcpy(target, ncp_reply_data(conn, 0), 8);
+ return 0;
+}
+
+int
+ncp_keyed_verify_password(NWCONN_HANDLE cH, char *key, char *passwd,
+ struct ncp_bindery_object *objinfo)
+{
+ u_long id = htonl(objinfo->object_id);
+ u_char cryptkey[8];
+ u_char buf[128];
+ DECLARE_RQ;
+
+ nw_keyhash((u_char *)&id, passwd, strlen(passwd), buf);
+ nw_encrypt(key, buf, cryptkey);
+
+ ncp_init_request_s(conn, 74);
+ ncp_add_mem(conn, cryptkey, sizeof(cryptkey));
+ ncp_add_word_hl(conn, objinfo->object_type);
+ ncp_add_pstring(conn, objinfo->object_name);
+
+ return ncp_request(cH, 23, conn);
+}
+
+static char passkeys[256 + 16] = {
+ 0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09,
+ 0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a,
+ 0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08,
+ 0x0d, 0x03, 0x0a, 0x04, 0x09, 0x0b, 0x05, 0x07,
+ 0x05, 0x02, 0x09, 0x0f, 0x0c, 0x04, 0x0d, 0x00,
+ 0x0e, 0x0a, 0x06, 0x08, 0x0b, 0x01, 0x03, 0x07,
+ 0x0f, 0x0d, 0x02, 0x06, 0x07, 0x08, 0x05, 0x09,
+ 0x00, 0x04, 0x0c, 0x03, 0x01, 0x0a, 0x0b, 0x0e,
+ 0x05, 0x0e, 0x02, 0x0b, 0x0d, 0x0a, 0x07, 0x00,
+ 0x08, 0x06, 0x04, 0x01, 0x0f, 0x0c, 0x03, 0x09,
+ 0x08, 0x02, 0x0f, 0x0a, 0x05, 0x09, 0x06, 0x0c,
+ 0x00, 0x0b, 0x01, 0x0d, 0x07, 0x03, 0x04, 0x0e,
+ 0x0e, 0x08, 0x00, 0x09, 0x04, 0x0b, 0x02, 0x07,
+ 0x0c, 0x03, 0x0a, 0x05, 0x0d, 0x01, 0x06, 0x0f,
+ 0x01, 0x04, 0x08, 0x0a, 0x0d, 0x0b, 0x07, 0x0e,
+ 0x05, 0x0f, 0x03, 0x09, 0x00, 0x02, 0x06, 0x0c,
+ 0x05, 0x03, 0x0c, 0x08, 0x0b, 0x02, 0x0e, 0x0a,
+ 0x04, 0x01, 0x0d, 0x00, 0x06, 0x07, 0x0f, 0x09,
+ 0x06, 0x00, 0x0b, 0x0e, 0x0d, 0x04, 0x0c, 0x0f,
+ 0x07, 0x02, 0x08, 0x0a, 0x01, 0x05, 0x03, 0x09,
+ 0x0b, 0x05, 0x0a, 0x0e, 0x0f, 0x01, 0x0c, 0x00,
+ 0x06, 0x04, 0x02, 0x09, 0x03, 0x0d, 0x07, 0x08,
+ 0x07, 0x02, 0x0a, 0x00, 0x0e, 0x08, 0x0f, 0x04,
+ 0x0c, 0x0b, 0x09, 0x01, 0x05, 0x0d, 0x03, 0x06,
+ 0x07, 0x04, 0x0f, 0x09, 0x05, 0x01, 0x0c, 0x0b,
+ 0x00, 0x03, 0x08, 0x0e, 0x02, 0x0a, 0x06, 0x0d,
+ 0x09, 0x04, 0x08, 0x00, 0x0a, 0x03, 0x01, 0x0c,
+ 0x05, 0x0f, 0x07, 0x02, 0x0b, 0x0e, 0x06, 0x0d,
+ 0x09, 0x05, 0x04, 0x07, 0x0e, 0x08, 0x03, 0x01,
+ 0x0d, 0x0b, 0x0c, 0x02, 0x00, 0x0f, 0x06, 0x0a,
+ 0x09, 0x0a, 0x0b, 0x0d, 0x05, 0x03, 0x0f, 0x00,
+ 0x01, 0x0c, 0x08, 0x07, 0x06, 0x04, 0x0e, 0x02,
+ 0x03, 0x0e, 0x0f, 0x02, 0x0d, 0x0c, 0x04, 0x05,
+ 0x09, 0x06, 0x00, 0x01, 0x0b, 0x07, 0x0a, 0x08
+};
+
+static void
+nw_passencrypt(char *old, char *new, char *out)
+{
+ char *p, v;
+ char copy[8];
+ int i, di, ax;
+
+#define HIGH(x) (((x) >> 4) & 0xf)
+#define LOW(x) ((x) & 0xf)
+ memcpy(copy, new, 8);
+
+ for (i = 0; i < 16; i++) {
+ for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++) {
+ v = copy[di] ^ *p;
+ copy[di] = (passkeys[HIGH(v) + ax + 0x10] << 4) |
+ passkeys[LOW(v) + ax];
+ }
+ v = old[7];
+ for (p = old + 7; p > old; p--) {
+ *p = HIGH(p[-1]) | ((*p) << 4);
+ }
+ *old = HIGH(v) | (*old) << 4;
+ bzero(out, 8);
+
+ for (di = 0; di < 16; di++) {
+ v = passkeys[di + 0x100];
+ v = (v & 1) ? HIGH(copy[v / 2]) : LOW(copy[v / 2]);
+ out[di / 2] |= ((di & 1) ? v << 4 : v);
+ }
+ memcpy(copy, out, 8);
+ }
+}
diff --git a/lib/libncp/ncpl_conn.c b/lib/libncp/ncpl_conn.c
new file mode 100644
index 0000000..7aaaa96
--- /dev/null
+++ b/lib/libncp/ncpl_conn.c
@@ -0,0 +1,519 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ *
+ * Current scheme to create/open connection:
+ * 1. ncp_li_init() - lookup -S [-U] options in command line
+ * 2. ncp_li_init() - try to find existing connection
+ * 3. ncp_li_init() - if no server name and no accessible connections - bail out
+ * 4. This is connection candidate, read .rc file, override with command line
+ * and go ahead
+ * Note: connection referenced only via ncp_login() call. Although it is
+ * possible to get connection handle in other way, it will be unwise to use
+ * it, since conn can be destroyed at any time.
+ *
+ */
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/mount.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+
+#include <netncp/ncp_lib.h>
+#include <netncp/ncp_rcfile.h>
+#include <nwfs/nwfs.h>
+
+static char *server_name; /* need a better way ! */
+
+
+
+int
+ncp_li_setserver(struct ncp_conn_loginfo *li, const char *arg) {
+ if (strlen(arg) >= NCP_BINDERY_NAME_LEN) {
+ ncp_error("server name '%s' too long", 0, arg);
+ return ENAMETOOLONG;
+ }
+ ncp_str_upper(strcpy(li->server, arg));
+ return 0;
+}
+
+int
+ncp_li_setuser(struct ncp_conn_loginfo *li, char *arg) {
+ if (arg && strlen(arg) >= NCP_BINDERY_NAME_LEN) {
+ ncp_error("user name '%s' too long", 0, arg);
+ return ENAMETOOLONG;
+ }
+ if (li->user)
+ free(li->user);
+ if (arg) {
+ li->user = strdup(arg);
+ if (li->user == NULL)
+ return ENOMEM;
+ ncp_str_upper(li->user);
+ } else
+ li->user = NULL;
+ return 0;
+}
+
+int
+ncp_li_setpassword(struct ncp_conn_loginfo *li, const char *passwd) {
+ if (passwd && strlen(passwd) >= 127) {
+ ncp_error("password too long", 0);
+ return ENAMETOOLONG;
+ }
+ if (li->password) {
+ bzero(li->password, strlen(li->password));
+ free(li->password);
+ }
+ if (passwd) {
+ li->password = strdup(passwd);
+ if (li->password == NULL)
+ return ENOMEM;
+ } else
+ li->password = NULL;
+ return 0;
+}
+/*
+ * Prescan command line for [-S server] [-U user] arguments
+ * and fill li structure with defaults
+ */
+int
+ncp_li_init(struct ncp_conn_loginfo *li, int argc, char *argv[]) {
+ int opt, error = 0;
+ char *arg;
+
+ bzero(li,sizeof(*li));
+ li->timeout = 15; /* these values should be large enough to handle */
+ li->retry_count = 4; /* slow servers, even on ethernet */
+ li->access_mode = 0;
+ li->password = NULL;
+ li->sig_level = 1;
+ li->objtype = NCP_BINDERY_USER;
+ li->owner = NCP_DEFAULT_OWNER;
+ li->group = NCP_DEFAULT_GROUP;
+ server_name = NULL;
+ if (argv == NULL) return 0;
+ while (error == 0 && (opt = ncp_getopt(argc, argv, ":S:U:")) != -1) {
+ arg = ncp_optarg;
+ switch (opt) {
+ case 'S':
+ error = ncp_li_setserver(li, arg);
+ break;
+ case 'U':
+ error = ncp_li_setuser(li, arg);
+ break;
+ }
+ }
+ ncp_optind = ncp_optreset = 1;
+ return error;
+}
+
+void
+ncp_li_done(struct ncp_conn_loginfo *li) {
+ if (li->user)
+ free(li->user);
+ if (li->password)
+ free(li->password);
+}
+
+/*
+ * Lookup existing connection based on li structure, if connection
+ * found, it will be referenced. Otherwise full login sequence performed.
+ */
+int
+ncp_li_login(struct ncp_conn_loginfo *li, int *aconnid) {
+ int connHandle, error;
+
+ if ((error = ncp_conn_scan(li, &connHandle)) == 0) {
+ *aconnid = connHandle;
+ return 0;
+ }
+ error = ncp_connect(li, &connHandle);
+ if (error) return errno;
+ error = ncp_login(connHandle, li->user, li->objtype, li->password);
+ if (error) {
+ ncp_disconnect(connHandle);
+ } else
+ *aconnid = connHandle;
+ return error;
+}
+
+/*
+ * read rc file as follows:
+ * 1. read [server] section
+ * 2. override with [server:user] section
+ * Since abcence of rcfile is not a bug, silently ignore that fact.
+ * rcfile never closed to reduce number of open/close operations.
+ */
+int
+ncp_li_readrc(struct ncp_conn_loginfo *li) {
+ int i, val, error;
+ char uname[NCP_BINDERY_NAME_LEN*2+1];
+ char *sect = NULL, *p;
+
+ /*
+ * if info from cmd line incomplete, try to find existing
+ * connection and fill server/user from it.
+ */
+ if (li->server[0] == 0 || li->user == NULL) {
+ int connHandle;
+ struct ncp_conn_stat cs;
+
+ if ((error = ncp_conn_scan(li, &connHandle)) != 0) {
+ ncp_error("no default connection found", errno);
+ return error;
+ }
+ ncp_conn_getinfo(connHandle, &cs);
+ ncp_li_setserver(li, cs.li.server);
+ ncp_li_setuser(li, cs.user);
+ ncp_li_setpassword(li, "");
+ ncp_disconnect(connHandle);
+ }
+ if (ncp_open_rcfile()) return 0;
+
+ for (i = 0; i < 2; i++) {
+ switch (i) {
+ case 0:
+ sect = li->server;
+ break;
+ case 1:
+ strcat(strcat(strcpy(uname,li->server),":"),li->user ? li->user : "default");
+ sect = uname;
+ break;
+ }
+ rc_getstringptr(ncp_rc, sect, "password", &p);
+ if (p)
+ ncp_li_setpassword(li, p);
+ rc_getint(ncp_rc,sect, "timeout", &li->timeout);
+ rc_getint(ncp_rc,sect, "retry_count", &li->retry_count);
+ rc_getint(ncp_rc,sect, "sig_level", &li->sig_level);
+ if (rc_getint(ncp_rc,sect,"access_mode",&val) == 0)
+ li->access_mode = val;
+ if(rc_getbool(ncp_rc,sect,"bindery",&val) == 0 && val) {
+ li->opt |= NCP_OPT_BIND;
+ }
+ }
+ return 0;
+}
+
+/*
+ * check for all uncompleted fields
+ */
+int
+ncp_li_check(struct ncp_conn_loginfo *li) {
+ int error = 0;
+ char *p;
+
+ do {
+ if (li->server[0] == 0) {
+ ncp_error("no server name specified", 0);
+ error = 1;
+ break;
+ }
+ error = ncp_find_fileserver(li,
+ (server_name==NULL) ? AF_IPX : AF_INET, server_name);
+ if (error) {
+ ncp_error("can't find server %s", error, li->server);
+ break;
+ }
+ if (li->user == NULL || li->user[0] == 0) {
+ ncp_error("no user name specified for server %s",
+ 0, li->server);
+ error = 1;
+ break;
+ }
+ if (li->password == NULL) {
+ p = getpass("Netware password:");
+ error = ncp_li_setpassword(li, p) ? 1 : 0;
+ }
+ } while (0);
+ return error;
+}
+
+int
+ncp_conn_cnt(void) {
+ int error, cnt = 0, len = sizeof(cnt);
+
+#if __FreeBSD_version < 400001
+ error = sysctlbyname("net.ipx.ncp.conn_cnt", &cnt, &len, NULL, 0);
+#else
+ error = sysctlbyname("net.ncp.conn_cnt", &cnt, &len, NULL, 0);
+#endif
+ if (error) cnt = 0;
+ return cnt;
+}
+
+/*
+ * Find an existing connection and reference it
+ */
+int
+ncp_conn_find(char *server,char *user) {
+ struct ncp_conn_args ca;
+ int connid, error;
+
+ if (server == NULL && user == NULL) {
+ error = ncp_conn_scan(NULL,&connid);
+ if (error) return -2;
+ return connid;
+ }
+ if (server == NULL)
+ return -2;
+ ncp_str_upper(server);
+ if (user) ncp_str_upper(user);
+ bzero(&ca, sizeof(ca));
+ ncp_li_setserver(&ca, server);
+ ncp_li_setuser(&ca, user);
+ error = ncp_conn_scan(&ca,&connid);
+ if (error)
+ connid = -1;
+ return connid;
+}
+
+int
+ncp_li_arg(struct ncp_conn_loginfo *li, int opt, char *arg) {
+ int error = 0, sig_level;
+ char *p, *cp;
+ struct group *gr;
+ struct passwd *pw;
+
+ switch(opt) {
+ case 'S': /* we already fill server/[user] pair */
+ case 'U':
+ break;
+ case 'A':
+ server_name = arg;
+ break;
+ case 'B':
+ li->opt |= NCP_OPT_BIND;
+ break;
+ case 'C':
+ li->opt |= NCP_OPT_NOUPCASEPASS;
+ break;
+ case 'I':
+ sig_level = atoi(arg);
+ if (sig_level < 0 || sig_level > 3) {
+ ncp_error("invalid NCP signature level option `%s'\
+ (must be a number between 0 and 3)", 0, arg);
+ error = 1;
+ }
+ li->sig_level = sig_level;
+ if (sig_level > 1) li->opt |= NCP_OPT_SIGN;
+ break;
+ case 'M':
+ li->access_mode = strtol(arg, NULL, 8);
+ break;
+ case 'N':
+ ncp_li_setpassword(li, "");
+ break;
+ case 'O':
+ p = strdup(arg);
+ cp = strchr(p, ':');
+ if (cp) {
+ *cp++ = '\0';
+ if (*cp) {
+ gr = getgrnam(cp);
+ if (gr) {
+ li->group = gr->gr_gid;
+ } else
+ ncp_error("Invalid group name %s, ignored",
+ 0, cp);
+ }
+ }
+ if (*p) {
+ pw = getpwnam(p);
+ if (pw) {
+ li->owner = pw->pw_uid;
+ } else
+ ncp_error("Invalid user name %s, ignored", 0, p);
+ }
+ endpwent();
+ free(p);
+ break;
+ case 'P':
+ li->opt |= NCP_OPT_PERMANENT;
+ break;
+ case 'R':
+ li->retry_count = atoi(arg);
+ break;
+ case 'W':
+ li->timeout = atoi(arg);
+ break;
+ }
+ return error;
+}
+
+void *
+ncp_conn_list(void) {
+ int error, cnt = 0, len;
+ void *p;
+
+ cnt = ncp_conn_cnt();
+ if (cnt == 0) return NULL;
+ len = cnt*(sizeof(struct ncp_conn_stat))+sizeof(int);
+ p = malloc(len);
+ if (p == NULL) return NULL;
+#if __FreeBSD_version < 400001
+ error = sysctlbyname("net.ipx.ncp.conn_stat", p, &len, NULL, 0);
+#else
+ error = sysctlbyname("net.ncp.conn_stat", p, &len, NULL, 0);
+#endif
+ if (error) {
+ free(p);
+ p = NULL;
+ }
+ return p;
+}
+
+
+int
+ncp_conn_setflags(int connid, u_int16_t mask, u_int16_t flags) {
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request(conn);
+ ncp_add_byte(conn, NCP_CONN_SETFLAGS);
+ ncp_add_word_lh(conn, mask);
+ ncp_add_word_lh(conn, flags);
+ if ((error = ncp_conn_request(connid, conn)) < 0)
+ return -1;
+ return error;
+}
+
+int
+ncp_login(int connHandle, const char *user, int objtype, const char *password) {
+ int error;
+ struct ncp_conn_login *p;
+ DECLARE_RQ;
+
+ ncp_init_request(conn);
+ ncp_add_byte(conn, NCP_CONN_LOGIN);
+ p = (struct ncp_conn_login *)&conn->packet[conn->rqsize];
+ (const char*)p->username = user;
+ p->objtype = objtype;
+ (const char*)p->password = password;
+ conn->rqsize += sizeof(*p);
+ if ((error = ncp_conn_request(connHandle, conn)) < 0)
+ return -1;
+ return error;
+}
+
+int
+ncp_connect_addr(struct sockaddr *sa, NWCONN_HANDLE *chp) {
+ int error;
+ struct ncp_conn_args li;
+
+ bzero(&li, sizeof(li));
+ bcopy(sa, &li.addr, sa->sa_len);
+ /*
+ * XXX Temporary !!!. server will be filled in kernel !!!
+ */
+ strcpy(li.server,ipx_ntoa(li.ipxaddr.sipx_addr));
+ error = ncp_connect(&li, chp);
+ return error;
+}
+
+int
+ncp_conn_getinfo(int connHandle, struct ncp_conn_stat *ps) {
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request(conn);
+ ncp_add_byte(conn, NCP_CONN_GETINFO);
+ if ((error = ncp_conn_request(connHandle, conn)) < 0)
+ return -1;
+ memcpy(ps, ncp_reply_data(conn,0), sizeof(*ps));
+ return error;
+}
+
+int
+ncp_conn_getuser(int connHandle, char **user) {
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request(conn);
+ ncp_add_byte(conn, NCP_CONN_GETUSER);
+ if ((error = ncp_conn_request(connHandle, conn)) < 0)
+ return -1;
+ *user = strdup(ncp_reply_data(conn,0));
+ return error;
+}
+
+int
+ncp_conn2ref(int connHandle, int *connRef) {
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request(conn);
+ ncp_add_byte(conn, NCP_CONN_CONN2REF);
+ if ((error = ncp_conn_request(connHandle, conn)) < 0)
+ return -1;
+ *connRef = *((int*)ncp_reply_data(conn,0));
+ return error;
+}
+
+int
+ncp_path2conn(char *path, int *connHandle) {
+ struct statfs st;
+ int d, error;
+
+ if ((error = statfs(path, &st)) != 0) return errno;
+ if (strcmp(st.f_fstypename,"nwfs") != 0) return EINVAL;
+ if ((d = open(path, O_RDONLY)) < 0) return errno;
+ if ((error = ioctl(d,NWFSIOC_GETCONN, connHandle)) != 0) return errno;
+ close(d);
+ return 0;
+}
+
+int
+ncp_conn_dup(NWCONN_HANDLE org, NWCONN_HANDLE *res) {
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request(conn);
+ ncp_add_byte(conn, NCP_CONN_DUP);
+ if ((error = ncp_conn_request(org, conn)) < 0)
+ return errno;
+ *res = *((int*)ncp_reply_data(conn, 0));
+ return 0;
+}
diff --git a/lib/libncp/ncpl_crypt.c b/lib/libncp/ncpl_crypt.c
new file mode 100644
index 0000000..00ce9bf
--- /dev/null
+++ b/lib/libncp/ncpl_crypt.c
@@ -0,0 +1,137 @@
+/*
+ * Routines in this file based on the work of Volker Lendecke,
+ * Adapted for ncplib by Boris Popov
+ * Please note that ncpl_crypt.c file should be indentical to this one
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <string.h>
+
+/*$*********************************************************
+ $*
+ $* This code has been taken from DDJ 11/93, from an
+ $* article by Pawel Szczerbina.
+ $*
+ $* Password encryption routines follow.
+ $* Converted to C from Barry Nance's Pascal
+ $* prog published in the March -93 issue of Byte.
+ $*
+ $* Adapted to be useable for ncpfs by
+ $* Volker Lendecke <lendecke@namu01.gwdg.de> in
+ $* October 1995.
+ $*
+ $********************************************************* */
+
+
+
+typedef unsigned char buf32[32];
+
+static unsigned char encrypttable[256] = {
+0x7, 0x8, 0x0, 0x8, 0x6, 0x4, 0xE, 0x4, 0x5, 0xC, 0x1, 0x7, 0xB, 0xF, 0xA, 0x8,
+0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9,
+0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6,
+0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0,
+0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD,
+0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE,
+0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7,
+0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1,
+0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4,
+0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2,
+0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3,
+0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0,
+0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8,
+0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3,
+0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0,
+0xC, 0x0, 0x3, 0x6, 0xF, 0x8, 0x7, 0xB, 0x2, 0xD, 0xC, 0x6, 0xA, 0xA, 0x8, 0xD
+};
+
+static buf32 encryptkeys = {
+ 0x48, 0x93, 0x46, 0x67, 0x98, 0x3D, 0xE6, 0x8D,
+ 0xB7, 0x10, 0x7A, 0x26, 0x5A, 0xB9, 0xB1, 0x35,
+ 0x6B, 0x0F, 0xD5, 0x70, 0xAE, 0xFB, 0xAD, 0x11,
+ 0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0
+};
+
+/*
+ * Create table-based 16-bytes hash from a 32-bytes array
+ */
+static void
+nw_hash(buf32 temp, unsigned char *target) {
+ short sum;
+ unsigned char b3;
+ int s, b2, i;
+
+ sum = 0;
+
+ for (b2 = 0; b2 <= 1; ++b2) {
+ for (s = 0; s <= 31; ++s) {
+ b3 = (temp[s] + sum) ^ (temp[(s + sum) & 31] - encryptkeys[s]);
+ sum += b3;
+ temp[s] = b3;
+ }
+ }
+
+ for (i = 0; i <= 15; ++i) {
+ target[i] = encrypttable[temp[2 * i]]
+ | (encrypttable[temp[2 * i + 1]] << 4);
+ }
+}
+
+
+/*
+ * Create a 16-bytes pattern from given buffer based on a four bytes key
+ */
+void
+nw_keyhash(const u_char *key, const u_char *buf, int buflen, u_char *target) {
+ int b2, d, s;
+ buf32 temp;
+
+ while (buflen > 0 && buf[buflen - 1] == 0)
+ buflen--;
+
+ bzero(temp, sizeof(temp));
+
+ d = 0;
+ while (buflen >= 32) {
+ for (s = 0; s <= 31; ++s)
+ temp[s] ^= buf[d++];
+ buflen -= 32;
+ }
+ b2 = d;
+ if (buflen > 0) {
+ for (s = 0; s <= 31; ++s) {
+ if (d + buflen == b2) {
+ temp[s] ^= encryptkeys[s];
+ b2 = d;
+ } else
+ temp[s] ^= buf[b2++];
+ }
+ }
+ for (s = 0; s <= 31; ++s)
+ temp[s] ^= key[s & 3];
+
+ nw_hash(temp, target);
+}
+
+/*
+ * Create an 8-bytes pattern from an 8-bytes key and 16-bytes of data
+ */
+void
+nw_encrypt(const u_char *fra, const u_char *buf, u_char *target) {
+ buf32 k;
+ int s;
+
+ nw_keyhash(fra, buf, 16, k);
+ nw_keyhash(fra + 4, buf, 16, k + 16);
+
+ for (s = 0; s < 16; s++)
+ k[s] ^= k[31 - s];
+
+ for (s = 0; s < 8; s++)
+ *target++ = k[s] ^ k[15 - s];
+}
+
+
diff --git a/lib/libncp/ncpl_file.c b/lib/libncp/ncpl_file.c
new file mode 100644
index 0000000..ab8bb76
--- /dev/null
+++ b/lib/libncp/ncpl_file.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <strings.h>
+
+#include <netncp/ncp_lib.h>
+#include <netncp/ncp_file.h>
+#include <nwfs/nwfs.h>
+
+int
+ncp_read(NWCONN_HANDLE connid, ncp_fh *fh, off_t offset, size_t count, char *target) {
+ int result;
+ struct ncp_rw rwrq;
+ DECLARE_RQ;
+
+ ncp_init_request(conn);
+ ncp_add_byte(conn, NCP_CONN_READ);
+ rwrq.nrw_fh = *fh;
+ rwrq.nrw_base = target;
+ rwrq.nrw_cnt = count;
+ rwrq.nrw_offset = offset;
+ ncp_add_mem(conn, &rwrq, sizeof(rwrq));
+ if ((result = ncp_conn_request(connid, conn)) < 0)
+ return -1;
+ return result;
+}
+
+int
+ncp_write(NWCONN_HANDLE connid, ncp_fh *fh, off_t offset, size_t count, char *source)
+{
+ int result;
+ struct ncp_rw rwrq;
+ DECLARE_RQ;
+
+ ncp_init_request(conn);
+ ncp_add_byte(conn, NCP_CONN_WRITE);
+ rwrq.nrw_fh = *fh;
+ rwrq.nrw_base = source;
+ rwrq.nrw_cnt = count;
+ rwrq.nrw_offset = offset;
+ ncp_add_mem(conn, &rwrq, sizeof(rwrq));
+
+ if ((result = ncp_conn_request(connid, conn)) < 0)
+ return -1;
+ return result;
+}
+
+int
+ncp_geteinfo(char *path, struct nw_entry_info *fi) {
+ int d, error;
+
+ if ((d = open(path, O_RDONLY)) < 0) return errno;
+ if ((error = ioctl(d, NWFSIOC_GETEINFO, fi)) != 0) return errno;
+ close(d);
+ return 0;
+}
+
+
+int
+ncp_AllocTempDirHandle(char *path, NWDIR_HANDLE *pdh) {
+ int d;
+
+ if ((d = open(path, O_RDONLY)) < 0) return errno;
+ *pdh = d;
+ return 0;
+}
+
+int
+ncp_DeallocateDirHandle(NWDIR_HANDLE dh) {
+ close(dh);
+ return 0;
+}
+
+int
+ncp_GetNSEntryInfo(NWDIR_HANDLE dh, struct nw_entry_info *fi, int *ns) {
+ int error;
+
+ if ((error = ioctl(dh, NWFSIOC_GETEINFO, fi)) != 0) return errno;
+ if ((error = ioctl(dh, NWFSIOC_GETNS, ns)) != 0) return errno;
+ return 0;
+}
+
+NWCCODE
+ncp_ScanForDeletedFiles(NWCONN_HANDLE cH, pnuint32 iterHandle,
+ pnuint32 volNum, pnuint32 dirBase, nuint8 ns,
+ NWDELETED_INFO *entryInfo)
+{
+ int error;
+ struct nw_entry_info *pfi;
+ DECLARE_RQ;
+#define UNITEDT(d,t) (((d) << 16) | (t))
+
+ bzero(entryInfo, sizeof(NWDELETED_INFO));
+ ncp_init_request(conn);
+ ncp_add_byte(conn, 16);
+ ncp_add_byte(conn, ns);
+ ncp_add_byte(conn, 0); /* data stream */
+ ncp_add_dword_lh(conn, IM_ALL & ~(IM_SPACE_ALLOCATED | IM_TOTAL_SIZE | IM_EA | IM_DIRECTORY));
+ ncp_add_dword_lh(conn, *iterHandle);
+
+ ncp_add_byte(conn, *volNum);
+ ncp_add_dword_lh(conn, *dirBase);
+ ncp_add_byte(conn, NCP_HF_DIRBASE); /* dirBase */
+ ncp_add_byte(conn, 0); /* no component */
+ if ((error = ncp_request(cH, 87, conn)) != 0) {
+ return error;
+ }
+ if (conn->rpsize < 0x61) {
+ return EBADRPC; /* EACCES ? */
+ }
+ *iterHandle = entryInfo->sequence = ncp_reply_dword_lh(conn, 0x00);
+ entryInfo->deletedTime = ncp_reply_word_lh(conn, 0x04);
+ entryInfo->deletedDateAndTime = UNITEDT(ncp_reply_word_lh(conn, 0x06), entryInfo->deletedTime);
+ entryInfo->deletorID = ncp_reply_dword_hl(conn, 0x08);
+ *volNum = ncp_reply_dword_lh(conn, 0x0C);
+ *dirBase = ncp_reply_dword_lh(conn, 0x10);
+ entryInfo->parent = ncp_reply_dword_lh(conn, 0x10);
+ pfi = (struct nw_entry_info*) ncp_reply_data(conn, 0x14);
+ entryInfo->nameLength = pfi->nameLen;
+ memcpy(entryInfo->name, pfi->entryName, pfi->nameLen);
+ return error;
+}
+
+NWCCODE
+ncp_PurgeDeletedFile(NWCONN_HANDLE cH, nuint32 iterHandle,
+ nuint32 volNum, nuint32 dirBase, nuint8 ns)
+{
+ DECLARE_RQ;
+
+ ncp_init_request(conn);
+ ncp_add_byte(conn, 18);
+ ncp_add_byte(conn, ns);
+ ncp_add_byte(conn, 0); /* reserved */
+ ncp_add_dword_lh(conn, iterHandle);
+ ncp_add_dword_lh(conn, volNum);
+ ncp_add_dword_lh(conn, dirBase);
+ return ncp_request(cH, 87, conn);
+}
+
+
+static void
+ncp_extract_entryInfo(char *data, NW_ENTRY_INFO *entry) {
+ u_char l;
+ const int info_struct_size = sizeof(NW_ENTRY_INFO) - 257;
+
+ memcpy(entry, data, info_struct_size);
+ data += info_struct_size;
+ l = *data++;
+ entry->nameLen = l;
+ memcpy(entry->entryName, data, l);
+ entry->entryName[l] = '\0';
+ return;
+}
+
+NWCCODE
+ncp_ScanNSEntryInfo(NWCONN_HANDLE cH,
+ nuint8 namSpc, nuint16 attrs, SEARCH_SEQUENCE *seq,
+ pnstr8 searchPattern, nuint32 retInfoMask, NW_ENTRY_INFO *entryInfo)
+{
+ int error, l;
+ DECLARE_RQ;
+
+ if (seq->searchDirNumber == -1) {
+ seq->searchDirNumber = 0;
+ ncp_init_request(conn);
+ ncp_add_byte(conn, 2);
+ ncp_add_byte(conn, namSpc);
+ ncp_add_byte(conn, 0);
+ ncp_add_handle_path(conn, seq->volNumber, seq->dirNumber,
+ NCP_HF_DIRBASE, NULL);
+ error = ncp_request(cH, 87, conn);
+ if (error) return error;
+ memcpy(seq, ncp_reply_data(conn, 0), 9);
+ }
+ ncp_init_request(conn);
+ ncp_add_byte(conn, 3);
+ ncp_add_byte(conn, namSpc);
+ ncp_add_byte(conn, 0); /* dataStream */
+ ncp_add_word_lh(conn, attrs); /* SearchAttributes */
+ ncp_add_dword_lh(conn, retInfoMask);
+ ncp_add_mem(conn, seq, sizeof(*seq));
+ l = strlen(searchPattern);
+ ncp_add_byte(conn, l);
+ ncp_add_mem(conn, searchPattern, l);
+ error = ncp_request(cH, 87, conn);
+ if (error) return error;
+ memcpy(seq, ncp_reply_data(conn, 0), sizeof(*seq));
+ ncp_extract_entryInfo(ncp_reply_data(conn, 10), entryInfo);
+ return 0;
+}
+
+int
+ncp_NSEntryInfo(NWCONN_HANDLE cH, nuint8 ns, nuint8 vol, nuint32 dirent,
+ NW_ENTRY_INFO *entryInfo)
+{
+ DECLARE_RQ;
+ int error;
+
+ ncp_init_request(conn);
+ ncp_add_byte(conn, 6);
+ ncp_add_byte(conn, ns);
+ ncp_add_byte(conn, ns); /* DestNameSpace */
+ ncp_add_word_lh(conn, htons(0xff00)); /* get all */
+ ncp_add_dword_lh(conn, IM_ALL);
+ ncp_add_handle_path(conn, vol, dirent, NCP_HF_DIRBASE, NULL);
+ error = ncp_request(cH, 87, conn);
+ if (error) return error;
+ ncp_extract_entryInfo(ncp_reply_data(conn, 0), entryInfo);
+ return 0;
+}
+
+NWCCODE
+NWGetVolumeName(NWCONN_HANDLE cH, u_char volume, char *name) {
+ int error, len;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 44);
+ ncp_add_byte(conn, volume);
+ error = ncp_request(cH, 22, conn);
+ if (error) return error;
+ len = ncp_reply_byte(conn, 29);
+ if (len == 0)
+ return ENOENT;
+ bcopy(ncp_reply_data(conn, 30), name, len);
+ name[len] = 0;
+ return 0;
+}
diff --git a/lib/libncp/ncpl_misc.c b/lib/libncp/ncpl_misc.c
new file mode 100644
index 0000000..737dd9f
--- /dev/null
+++ b/lib/libncp/ncpl_misc.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ * calls that don't fit to any other category
+ *
+ */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <stdio.h>
+#include <strings.h>
+
+#include <netncp/ncp_lib.h>
+
+static time_t
+ncp_nw_to_ctime(struct nw_time_buffer *source) {
+ struct tm u_time;
+
+ bzero(&u_time,sizeof(struct tm));
+ /*
+ * XXX: NW 4.x tracks daylight automatically
+ */
+ u_time.tm_isdst = -1;
+ u_time.tm_sec = source->second;
+ u_time.tm_min = source->minute;
+ u_time.tm_hour = source->hour;
+ u_time.tm_mday = source->day;
+ u_time.tm_mon = source->month - 1;
+ u_time.tm_year = source->year;
+
+ if (u_time.tm_year < 80) {
+ u_time.tm_year += 100;
+ }
+ return mktime(&u_time);
+}
+
+int
+ncp_get_file_server_information(NWCONN_HANDLE connid,
+ struct ncp_file_server_info *target)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 17);
+ if ((error = ncp_request(connid, 23, conn)) != 0)
+ return error;
+ memcpy(target, ncp_reply_data(conn, 0), sizeof(*target));
+ target->MaximumServiceConnections
+ = htons(target->MaximumServiceConnections);
+ target->ConnectionsInUse
+ = htons(target->ConnectionsInUse);
+ target->MaxConnectionsEverUsed
+ = htons(target->MaxConnectionsEverUsed);
+ target->NumberMountedVolumes
+ = htons(target->NumberMountedVolumes);
+ return 0;
+}
+
+int
+ncp_get_stations_logged_info(NWCONN_HANDLE connid, u_int32_t connection,
+ struct ncp_bindery_object *target, time_t *login_time)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 28);
+ ncp_add_dword_lh(conn, connection);
+
+ if ((error = ncp_request(connid, 23, conn)) != 0)
+ return error;
+ bzero(target, sizeof(*target));
+ target->object_id = ncp_reply_dword_hl(conn, 0);
+ target->object_type = ncp_reply_word_hl(conn, 4);
+ memcpy(target->object_name, ncp_reply_data(conn, 6),
+ sizeof(target->object_name));
+ *login_time = ncp_nw_to_ctime((struct nw_time_buffer *)ncp_reply_data(conn, 54));
+ return 0;
+}
+
+int
+ncp_get_internet_address(NWCONN_HANDLE connid, u_int32_t connection,
+ struct ipx_addr *target, u_int8_t * conn_type)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 26);
+ ncp_add_dword_lh(conn, connection);
+ error = ncp_request(connid, 23, conn);
+ if (error) return error;
+ bzero(target, sizeof(*target));
+ ipx_netlong(*target) = ncp_reply_dword_lh(conn, 0);
+ memcpy(&(target->x_host), ncp_reply_data(conn, 4), 6);
+ target->x_port = ncp_reply_word_lh(conn, 10);
+ *conn_type = ncp_reply_byte(conn, 12);
+ return 0;
+}
+
+NWCCODE
+NWGetObjectConnectionNumbers(NWCONN_HANDLE connHandle,
+ pnstr8 pObjName, nuint16 objType,
+ pnuint16 pNumConns, pnuint16 pConnHandleList,
+ nuint16 maxConns)
+{
+ int error, i, n;
+ nuint32 lastconn;
+ DECLARE_RQ;
+
+ lastconn = 0;
+ ncp_init_request_s(conn, 27);
+ ncp_add_dword_lh(conn, lastconn);
+ ncp_add_word_hl(conn, objType);
+ ncp_add_pstring(conn, pObjName);
+ if ((error = ncp_request(connHandle, 23, conn)) != 0) return error;
+ n = min(ncp_reply_byte(conn, 0), maxConns);
+ *pNumConns = n;
+ for (i = 0; i < n ; i++) {
+ *pConnHandleList++ = ncp_reply_dword_lh(conn, i * 4 + 1);
+ }
+ return 0;
+}
+
+void
+NWUnpackDateTime(nuint32 dateTime, NW_DATE *sDate, NW_TIME *sTime) {
+ NWUnpackDate(dateTime >> 16, sDate);
+ NWUnpackTime(dateTime & 0xffff, sTime);
+}
+
+void
+NWUnpackDate(nuint16 date, NW_DATE *sDate) {
+ sDate->day = date & 0x1f;
+ sDate->month = (date >> 5) & 0xf;
+ sDate->year = ((date >> 9) & 0x7f) + 1980;
+}
+
+void
+NWUnpackTime(nuint16 time, NW_TIME *sTime) {
+ sTime->seconds = time & 0x1f;
+ sTime->minutes = (time >> 5) & 0x3f;
+ sTime->hours = (time >> 11) & 0x1f;
+}
+
+nuint32
+NWPackDateTime(NW_DATE *sDate, NW_TIME *sTime) {
+ return 0;
+}
+
+nuint16
+NWPackDate(NW_DATE *sDate) {
+ return 0;
+}
+
+nuint16
+NWPackTime(NW_TIME *sTime) {
+ return 0;
+}
+
+time_t
+ncp_UnpackDateTime(nuint32 dateTime) {
+ struct tm u_time;
+ NW_DATE d;
+ NW_TIME t;
+
+ NWUnpackDateTime(dateTime, &d, &t);
+ bzero(&u_time,sizeof(struct tm));
+ u_time.tm_isdst = -1;
+ u_time.tm_sec = t.seconds;
+ u_time.tm_min = t.minutes;
+ u_time.tm_hour = t.hours;
+ u_time.tm_mday = d.day;
+ u_time.tm_mon = d.month - 1;
+ u_time.tm_year = d.year - 1900;
+
+ return mktime(&u_time);
+}
+
+int
+ncp_GetFileServerDateAndTime(NWCONN_HANDLE cH, time_t *target) {
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request(conn);
+ if ((error = ncp_request(cH, 20, conn)) != 0)
+ return error;
+ *target = ncp_nw_to_ctime((struct nw_time_buffer *) ncp_reply_data(conn, 0));
+ return 0;
+}
+
+int
+ncp_SetFileServerDateAndTime(NWCONN_HANDLE cH, time_t * source) {
+ int year;
+ struct tm *utime = localtime(source);
+ DECLARE_RQ;
+
+ year = utime->tm_year;
+ if (year > 99) {
+ year -= 100;
+ }
+ ncp_init_request_s(conn, 202);
+ ncp_add_byte(conn, year);
+ ncp_add_byte(conn, utime->tm_mon + 1);
+ ncp_add_byte(conn, utime->tm_mday);
+ ncp_add_byte(conn, utime->tm_hour);
+ ncp_add_byte(conn, utime->tm_min);
+ ncp_add_byte(conn, utime->tm_sec);
+ return ncp_request(cH, 23, conn);
+}
+
+NWCCODE
+NWDownFileServer(NWCONN_HANDLE cH, int force) {
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 211);
+ ncp_add_byte(conn, force ? 0 : 0xff);
+ return ncp_request(cH, 23, conn);
+}
+
+NWCCODE
+NWCloseBindery(NWCONN_HANDLE cH) {
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 68);
+ return ncp_request(cH, 23, conn);
+}
+
+NWCCODE
+NWOpenBindery(NWCONN_HANDLE cH) {
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 69);
+ return ncp_request(cH, 23, conn);
+}
+
+NWCCODE
+NWDisableTTS(NWCONN_HANDLE cH) {
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 207);
+ return ncp_request(cH, 23, conn);
+}
+
+NWCCODE
+NWEnableTTS(NWCONN_HANDLE cH) {
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 208);
+ return ncp_request(cH, 23, conn);
+}
+
+NWCCODE
+NWDisableFileServerLogin(NWCONN_HANDLE cH) {
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 203);
+ return ncp_request(cH, 23, conn);
+}
+
+NWCCODE
+NWEnableFileServerLogin(NWCONN_HANDLE cH) {
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 204);
+ return ncp_request(cH, 23, conn);
+}
diff --git a/lib/libncp/ncpl_msg.c b/lib/libncp/ncpl_msg.c
new file mode 100644
index 0000000..a65131b
--- /dev/null
+++ b/lib/libncp/ncpl_msg.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <strings.h>
+
+#include <netncp/ncp_lib.h>
+#include <netncp/ncp_nls.h>
+
+NWCCODE
+NWDisableBroadcasts(NWCONN_HANDLE connHandle) {
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 2);
+ return ncp_request(connHandle, 21, conn);
+}
+
+NWCCODE
+NWEnableBroadcasts(NWCONN_HANDLE connHandle) {
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 3);
+ return ncp_request(connHandle, 21, conn);
+}
+
+NWCCODE
+NWBroadcastToConsole(NWCONN_HANDLE connHandle, pnstr8 message) {
+ int l, error;
+ DECLARE_RQ;
+
+ l = strlen(message);
+ if (l > 60) return EMSGSIZE;
+ ncp_init_request_s(conn, 9);
+ ncp_add_byte(conn, l);
+ ncp_add_mem_nls(conn, message, l);
+ error = ncp_request(connHandle, 21, conn);
+ return error;
+}
+
+NWCCODE
+NWSendBroadcastMessage(NWCONN_HANDLE connHandle, pnstr8 message,
+ nuint16 connCount, pnuint16 connList, pnuint8 resultList)
+{
+ int l, i, error;
+ DECLARE_RQ;
+
+ l = strlen(message);
+ if (l > 255) return EMSGSIZE;
+ if (connCount > 350) return EINVAL;
+
+ ncp_init_request_s(conn, 0x0A);
+ ncp_add_word_lh(conn, connCount);
+ for (i = 0; i < connCount; i++)
+ ncp_add_dword_lh(conn, connList[i]);
+ ncp_add_byte(conn, l);
+ ncp_add_mem_nls(conn, message, l);
+ error = ncp_request(connHandle, 0x15, conn);
+ if (!error) {
+ l = ncp_reply_word_lh(conn, 0);
+ for (i = 0; i < l; i++)
+ resultList[i] = ncp_reply_dword_lh(conn, (i)*4 + 2);
+ return 0;
+ }
+ if (error != 0xfb) return error;
+ if (l > 58) return EMSGSIZE;
+ ncp_init_request_s(conn, 0);
+ ncp_add_byte(conn, connCount);
+ for (i = 0; i < connCount; i++)
+ ncp_add_byte(conn, connList[i]);
+ ncp_add_byte(conn, l);
+ ncp_add_mem_nls(conn, message, l);
+ error = ncp_request(connHandle, 0x15, conn);
+ if (error) return error;
+ i = ncp_reply_byte(conn, 0);
+ memcpy(resultList, ncp_reply_data(conn, 1), i);
+ return 0;
+}
+
+
+NWCCODE
+NWGetBroadcastMessage(NWCONN_HANDLE connHandle, pnstr8 message) {
+ int i, error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 0x0B);
+ error = ncp_request(connHandle, 0x15, conn);
+ if (error) {
+ if (error != 0x89fb) return error;
+ ncp_init_request_s(conn, 0x01);
+ if ((error = ncp_request(connHandle, 0x15, conn)) != 0)
+ return error;
+ }
+ i = ncp_reply_byte(conn, 0);
+ if (i == 0) return ENOENT;
+ memcpy(message, ncp_reply_data(conn, 1), i);
+ message[i] = 0;
+ ncp_nls_str_n2u(message, message);
+ return 0;
+}
diff --git a/lib/libncp/ncpl_net.c b/lib/libncp/ncpl_net.c
new file mode 100644
index 0000000..da21b66
--- /dev/null
+++ b/lib/libncp/ncpl_net.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/syscall.h>
+#include <ctype.h>
+#include <netinet/in.h>
+#include <netipx/ipx.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "ipxsap.h"
+#include <netncp/ncp_lib.h>
+#include "ncp_mod.h"
+
+static int ncp_find_server_in(struct ncp_conn_loginfo *li, int type, char *server_name);
+
+static int
+ncp_find_server_ipx(struct ncp_conn_loginfo *li, int type) {
+ char server[NCP_BINDERY_NAME_LEN + 1];
+ int error;
+ char nearest[NCP_BINDERY_NAME_LEN + 1];
+ struct nw_property prop;
+ struct ipx_addr *n_addr = (struct ipx_addr *) &prop;
+/* struct ncp_conn_loginfo ltmp;*/
+ int connid;
+
+ bzero(server, sizeof(server));
+ bzero(nearest, sizeof(nearest));
+
+ strcpy(server, li->server);
+ ncp_str_upper(server);
+
+ if ((error = sap_find_nearest(type, &li->ipxaddr, nearest)) != 0) {
+ return error;
+ }
+ /* if no server specified return info about nearest */
+ if (!li->server[0]) {
+ strcpy(li->server, nearest);
+ return 0;
+ }
+/* printf("%s\n",ipx_ntoa(li->ipxaddr.sipx_addr));*/
+ if (strcmp(server, nearest) == 0) {
+ return 0;
+ }
+ /* We have to ask the nearest server for our wanted server */
+ li->opt=0;
+ if ((error = ncp_connect(li, &connid)) != 0) {
+ return error;
+ }
+ if (ncp_read_property_value(connid, type, server, 1, "NET_ADDRESS", &prop) != 0) {
+ ncp_disconnect(connid);
+ return EHOSTUNREACH;
+ }
+ if ((error = ncp_disconnect(connid)) != 0) {
+ return error;
+ }
+ li->ipxaddr.sipx_family = AF_IPX;
+ li->ipxaddr.sipx_addr.x_net = n_addr->x_net;
+ li->ipxaddr.sipx_port = n_addr->x_port;
+ li->ipxaddr.sipx_addr.x_host = n_addr->x_host;
+ return 0;
+}
+
+static int
+ncp_find_server_in(struct ncp_conn_loginfo *li, int type, char *server_name) {
+ struct hostent* h;
+ int l;
+
+ h = gethostbyname(server_name);
+ if (!h) {
+ fprintf(stderr, "Get host address `%s': ", server_name);
+ herror(NULL);
+ return 1;
+ }
+ if (h->h_addrtype != AF_INET) {
+ fprintf(stderr, "Get host address `%s': Not AF_INET\n", server_name);
+ return 1;
+ }
+ if (h->h_length != 4) {
+ fprintf(stderr, "Get host address `%s': Bad address length\n", server_name);
+ return 1;
+ }
+ l = sizeof(struct sockaddr_in);
+ bzero(&li->inaddr, l);
+ li->inaddr.sin_len = l;
+ li->inaddr.sin_family = h->h_addrtype;
+ memcpy(&li->inaddr.sin_addr.s_addr, h->h_addr, 4);
+ li->inaddr.sin_port = htons(524); /* ncp */
+ return 0;
+}
+
+int
+ncp_find_server(struct ncp_conn_loginfo *li, int type, int af, char *name) {
+ int error = EHOSTUNREACH;
+
+ switch(af) {
+ case AF_IPX:
+ error = ncp_find_server_ipx(li, type);
+ break;
+ case AF_INET:
+ if (name)
+ error = ncp_find_server_in(li, type, name);
+ break;
+ default:
+ error = EPROTONOSUPPORT;
+ }
+ return error;
+}
+
+int
+ncp_find_fileserver(struct ncp_conn_loginfo *li, int af, char *name) {
+ return ncp_find_server(li, NCP_BINDERY_FSERVER, af, name);
+}
diff --git a/lib/libncp/ncpl_nls.c b/lib/libncp/ncpl_nls.c
new file mode 100644
index 0000000..f9e14f5
--- /dev/null
+++ b/lib/libncp/ncpl_nls.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Languages support. Currently is very primitive.
+ */
+#include <sys/types.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <strings.h>
+#include <locale.h>
+
+#include <netncp/ncp_lib.h>
+#include <netncp/ncp_cfg.h>
+#include <netncp/ncp_nls.h>
+
+#ifndef NCP_NLS_DEFAULT
+#define NCP_NLS_DEFAULT NCP_NLS_AS_IS
+#endif
+
+/*
+ * TODO: Make all tables dynamically loadable.
+ */
+#ifdef NCP_NLS_KOI2CP866
+/* Russian tables from easy-cyrillic:
+ * Copyright (C) 1993-1994 by Andrey A. Chernov, Moscow, Russia
+ */
+static u_int8_t alt2koi8[] = {
+ 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
+ 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
+ 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
+ 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa,
+ 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
+ 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe,
+ 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
+ 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda,
+ 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
+ 0x90, 0x91, 0x92, 0x81, 0x87, 0xb2, 0xb4, 0xa7,
+ 0xa6, 0xb5, 0xa1, 0xa8, 0xae, 0xad, 0xac, 0x83,
+ 0x84, 0x89, 0x88, 0x86, 0x80, 0x8a, 0xaf, 0xb0,
+ 0xab, 0xa5, 0xbb, 0xb8, 0xb1, 0xa0, 0xbe, 0xb9,
+ 0xba, 0xb6, 0xb7, 0xaa, 0xa9, 0xa2, 0xa4, 0xbd,
+ 0xbc, 0x85, 0x82, 0x8d, 0x8c, 0x8e, 0x8f, 0x8b,
+ 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde,
+ 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
+ 0xb3, 0xa3, 0x99, 0x98, 0x93, 0x9b, 0x9f, 0x97,
+ 0x9c, 0x95, 0x9e, 0x96, 0xbf, 0x9d, 0x94, 0x9a
+};
+
+static u_int8_t koi82alt[] = {
+ 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
+ 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
+ 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
+ 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0xc4, 0xb3, 0xda, 0xbf, 0xc0, 0xd9, 0xc3, 0xb4, /* 0x80 */
+ 0xc2, 0xc1, 0xc5, 0xdf, 0xdc, 0xdb, 0xdd, 0xde,
+ 0xb0, 0xb1, 0xb2, 0xf4, 0xfe, 0xf9, 0xfb, 0xf7,
+ 0xf3, 0xf2, 0xff, 0xf5, 0xf8, 0xfd, 0xfa, 0xf6,
+ 0xcd, 0xba, 0xd5, 0xf1, 0xd6, 0xc9, 0xb8, 0xb7,
+ 0xbb, 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6,
+ 0xc7, 0xcc, 0xb5, 0xf0, 0xb6, 0xb9, 0xd1, 0xd2,
+ 0xcb, 0xcf, 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0xfc,
+ 0xee, 0xa0, 0xa1, 0xe6, 0xa4, 0xa5, 0xe4, 0xa3,
+ 0xe5, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
+ 0xaf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0xa6, 0xa2,
+ 0xec, 0xeb, 0xa7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
+ 0x9e, 0x80, 0x81, 0x96, 0x84, 0x85, 0x94, 0x83,
+ 0x95, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
+ 0x8f, 0x9f, 0x90, 0x91, 0x92, 0x93, 0x86, 0x82, /* 0xf0 */
+ 0x9c, 0x9b, 0x87, 0x98, 0x9d, 0x99, 0x97, 0x9a
+};
+
+#endif
+
+static u_int8_t def2lower[256];
+static u_int8_t def2upper[256];
+
+/*
+ * List of available charsets
+ */
+struct ncp_nlsdesc {
+ int scheme;
+ char *name;
+ struct ncp_nlstables nls;
+};
+
+static struct ncp_nlsdesc ncp_nlslist[] = {
+ {NCP_NLS_AS_IS, NCP_NLS_AS_IS_NAME,
+ {def2lower, def2upper, NULL, NULL, 0}
+ },
+#ifdef NCP_NLS_KOI2CP866
+ {NCP_NLS_KOI_866, NCP_NLS_KOI_866_NAME,
+ {def2lower, def2upper, alt2koi8, koi82alt, 0}
+ },
+#endif
+ {NULL, 0}
+};
+
+struct ncp_nlstables ncp_nls;
+
+int
+ncp_nls_setlocale(char *name) {
+ int i;
+
+ ncp_nls.to_lower = def2lower;
+ ncp_nls.to_upper = def2upper;
+ if (setlocale(LC_CTYPE, name) == NULL) {
+ fprintf(stderr, "Can't set locale '%s'\n", name);
+ return EINVAL;
+ }
+ for (i = 0; i < 256; i++) {
+ ncp_nls.to_lower[i] = tolower(i);
+ ncp_nls.to_upper[i] = toupper(i);
+ }
+ return 0;
+}
+
+int
+ncp_nls_setrecode(int scheme) {
+ struct ncp_nlsdesc *nd;
+
+ if (scheme == 0) {
+#if NCP_NLS_DEFAULT
+ scheme = NCP_NLS_DEFAULT;
+#else
+ scheme = NCP_NLS_AS_IS;
+#endif
+ }
+ for (nd = ncp_nlslist; nd->name; nd++) {
+ if (nd->scheme != scheme) continue;
+ ncp_nls.u2n = nd->nls.u2n;
+ ncp_nls.n2u = nd->nls.n2u;
+ return ncp_nls_setlocale("");
+ }
+ fprintf(stderr, "Character conversion scheme %d was not compiled in\n", scheme);
+ return EINVAL;
+}
+
+int
+ncp_nls_setrecodebyname(char *name) {
+ struct ncp_nlsdesc *nd;
+
+ for (nd = ncp_nlslist; nd->name; nd++) {
+ if (strcmp(nd->name, name) != 0) continue;
+ ncp_nls.u2n = nd->nls.u2n;
+ ncp_nls.n2u = nd->nls.n2u;
+ return 0;
+ }
+ fprintf(stderr, "Character conversion scheme %s was not compiled in\n", name);
+ return EINVAL;
+}
+
+char *
+ncp_nls_str_n2u(char *dst, const char *src) {
+ char *p;
+
+ if (ncp_nls.n2u == NULL) {
+ return strcpy(dst, src);
+ }
+ p = dst;
+ while (*src)
+ *p++ = ncp_nls.n2u[(u_char)*(src++)];
+ *p = 0;
+ return dst;
+}
+
+char *
+ncp_nls_str_u2n(char *dst, const char *src) {
+ char *p;
+
+ if (ncp_nls.u2n == NULL) {
+ return strcpy(dst, src);
+ }
+ p = dst;
+ while (*src)
+ *p++ = ncp_nls.u2n[(u_char)*(src++)];
+ *p = 0;
+ return dst;
+}
+
+char *
+ncp_nls_mem_n2u(char *dst, const char *src, int size) {
+ char *p;
+
+ if (size == 0) return NULL;
+ if (ncp_nls.n2u == NULL) {
+ return memcpy(dst, src, size);
+ }
+ for(p = dst; size; size--, p++)
+ *p = ncp_nls.n2u[(u_char)*(src++)];
+ return dst;
+}
+
+char *
+ncp_nls_mem_u2n(char *dst, const char *src, int size) {
+ char *p;
+
+ if (size == 0) return NULL;
+ if (ncp_nls.u2n == NULL) {
+ return strcpy(dst, src);
+ }
+ for(p = dst; size; size--, p++)
+ *p = ncp_nls.u2n[(u_char)*(src++)];
+ return dst;
+}
+
+char *
+ncp_str_upper(char *s) {
+ char *p = s;
+ while (*s) {
+ *s = toupper(*s);
+ s++;
+ }
+ return p;
+}
diff --git a/lib/libncp/ncpl_queue.c b/lib/libncp/ncpl_queue.c
new file mode 100644
index 0000000..f4b42f5
--- /dev/null
+++ b/lib/libncp/ncpl_queue.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ * NetWare queue interface
+ *
+ */
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <netncp/ncp_lib.h>
+
+int
+ncp_create_queue_job_and_file(NWCONN_HANDLE connid, u_int32_t queue_id,
+ struct queue_job *job)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 121);
+ ncp_add_dword_hl(conn, queue_id);
+ ncp_add_mem(conn, &(job->j), sizeof(job->j));
+
+ if ((error = ncp_request(connid, 23, conn)) != 0)
+ return error;
+ memcpy(&(job->j), ncp_reply_data(conn, 0), 78);
+ ConvertToNWfromDWORD(job->j.JobFileHandle, &job->file_handle);
+ return 0;
+}
+
+int
+ncp_close_file_and_start_job(NWCONN_HANDLE connid, u_int32_t queue_id,
+ struct queue_job *job)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 127);
+ ncp_add_dword_hl(conn, queue_id);
+ ncp_add_dword_lh(conn, job->j.JobNumber);
+ error = ncp_request(connid, 23, conn);
+ return error;
+}
+
+int
+ncp_attach_to_queue(NWCONN_HANDLE connid, u_int32_t queue_id) {
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 111);
+ ncp_add_dword_hl(conn, queue_id);
+ error = ncp_request(connid, 23, conn);
+ return error;
+}
+
+int
+ncp_detach_from_queue(NWCONN_HANDLE connid, u_int32_t queue_id) {
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 112);
+ ncp_add_dword_hl(conn, queue_id);
+ error= ncp_request(connid, 23, conn);
+ return error;
+}
+
+int
+ncp_service_queue_job(NWCONN_HANDLE connid, u_int32_t queue_id,
+ u_int16_t job_type, struct queue_job *job)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 124);
+ ncp_add_dword_hl(conn, queue_id);
+ ncp_add_word_hl(conn, job_type);
+ if ((error = ncp_request(connid, 23, conn)) != 0) {
+ return error;
+ }
+ memcpy(&(job->j), ncp_reply_data(conn, 0), 78);
+ ConvertToNWfromDWORD(job->j.JobFileHandle, &job->file_handle);
+ return error;
+}
+
+int
+ncp_finish_servicing_job(NWCONN_HANDLE connid, u_int32_t queue_id,
+ u_int32_t job_number, u_int32_t charge_info)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 131);
+ ncp_add_dword_hl(conn, queue_id);
+ ncp_add_dword_lh(conn, job_number);
+ ncp_add_dword_hl(conn, charge_info);
+
+ error = ncp_request(connid, 23, conn);
+ return error;
+}
+
+int
+ncp_abort_servicing_job(NWCONN_HANDLE connid, u_int32_t queue_id,
+ u_int32_t job_number)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 132);
+ ncp_add_dword_hl(conn, queue_id);
+ ncp_add_dword_lh(conn, job_number);
+ error = ncp_request(connid, 23, conn);
+ return error;
+}
+
+int
+ncp_get_queue_length(NWCONN_HANDLE connid, u_int32_t queue_id,
+ u_int32_t *queue_length)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn, 125);
+ ncp_add_dword_hl(conn, queue_id);
+
+ if ((error = ncp_request(connid, 23, conn)) != 0)
+ return error;
+ if (conn->rpsize < 12) {
+ ncp_printf("ncp_reply_size %d < 12\n", conn->rpsize);
+ return EINVAL;
+ }
+ if (ncp_reply_dword_hl(conn,0) != queue_id) {
+ printf("Ouch! Server didn't reply with same queue id in ncp_get_queue_length!\n");
+ return EINVAL;
+ }
+ *queue_length = ncp_reply_dword_lh(conn,8);
+ return error;
+}
+
+int
+ncp_get_queue_job_ids(NWCONN_HANDLE connid, u_int32_t queue_id,
+ u_int32_t queue_section, u_int32_t *length1, u_int32_t *length2,
+ u_int32_t ids[])
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn,129);
+ ncp_add_dword_hl(conn, queue_id);
+ ncp_add_dword_lh(conn, queue_section);
+
+ if ((error = ncp_request(connid, 23, conn)) != 0)
+ return error;
+ if (conn->rpsize < 8) {
+ ncp_printf("ncp_reply_size %d < 8\n", conn->rpsize);
+ return EINVAL;
+ }
+ *length2 = ncp_reply_dword_lh(conn,4);
+ if (conn->rpsize < 8 + 4*(*length2)) {
+ ncp_printf("ncp_reply_size %d < %d\n", conn->rpsize, 8+4*(*length2));
+ return EINVAL;
+ }
+ if (ids) {
+ int count = min(*length1, *length2)*sizeof(u_int32_t);
+ int pos;
+
+ for (pos=0; pos<count; pos+=sizeof(u_int32_t)) {
+ *ids++ = ncp_reply_dword_lh(conn, 8+pos);
+ }
+ }
+ *length1 = ncp_reply_dword_lh(conn,0);
+ return error;
+}
+
+int
+ncp_get_queue_job_info(NWCONN_HANDLE connid, u_int32_t queue_id,
+ u_int32_t job_id, struct nw_queue_job_entry *jobdata)
+{
+ int error;
+ DECLARE_RQ;
+
+ ncp_init_request_s(conn,122);
+ ncp_add_dword_hl(conn, queue_id);
+ ncp_add_dword_lh(conn, job_id);
+
+ if ((error = ncp_request(connid, 23, conn)) != 0)
+ return error;
+
+ if (conn->rpsize < sizeof(struct nw_queue_job_entry)) {
+ ncp_printf("ncp_reply_size %d < %d\n", conn->rpsize,sizeof(struct nw_queue_job_entry));
+ return EINVAL;
+ }
+ memcpy(jobdata,ncp_reply_data(conn,0), sizeof(struct nw_queue_job_entry));
+ return error;
+}
diff --git a/lib/libncp/ncpl_rcfile.c b/lib/libncp/ncpl_rcfile.c
new file mode 100644
index 0000000..7a69071
--- /dev/null
+++ b/lib/libncp/ncpl_rcfile.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <unistd.h>
+
+#include <netncp/ncp_lib.h>
+#include <netncp/ncp_rcfile.h>
+#include <netncp/ncp_cfg.h>
+
+#define NWFS_CFG_FILE NCP_PREFIX"/etc/nwfs.conf"
+
+struct rcfile *ncp_rc = NULL;
+
+SLIST_HEAD(rcfile_head, rcfile);
+static struct rcfile_head pf_head = {NULL};
+
+int rc_merge(char *filename,struct rcfile **rcfile);
+static struct rcfile* rc_find(char *filename);
+static struct rcsection *rc_findsect(struct rcfile *rcp, char *sectname);
+static struct rcsection *rc_addsect(struct rcfile *rcp, char *sectname);
+static int rc_sect_free(struct rcsection *rsp);
+static struct rckey *rc_sect_findkey(struct rcsection *rsp, char *keyname);
+static struct rckey *rc_sect_addkey(struct rcsection *rsp, char *name, char *value);
+static void rc_key_free(struct rckey *p);
+static void rc_parse(struct rcfile *rcp);
+
+
+/*
+ * open rcfile and load its content, if already open - return previous handle
+ */
+int
+rc_open(char *filename,char *mode,struct rcfile **rcfile) {
+ struct rcfile *rcp;
+ FILE *f;
+
+ rcp = rc_find(filename);
+ if( rcp ) {
+ *rcfile = rcp;
+ return 0;
+ }
+ f = fopen (filename, mode);
+ if (f==NULL)
+ return errno;
+ rcp = malloc(sizeof(struct rcfile));
+ if (rcp==NULL) {
+ fclose(f);
+ return ENOMEM;
+ }
+ bzero(rcp, sizeof(struct rcfile));
+ rcp->rf_name = strdup (filename);
+ rcp->rf_f = f;
+ SLIST_INSERT_HEAD(&pf_head, rcp, rf_next);
+ rc_parse(rcp);
+ *rcfile = rcp;
+ return 0;
+}
+
+int
+rc_merge(char *filename,struct rcfile **rcfile) {
+ struct rcfile *rcp = *rcfile;
+ FILE *f, *t;
+
+ if (rcp == NULL) {
+ return rc_open(filename,"r",rcfile);
+ }
+ f = fopen (filename, "r");
+ if (f==NULL)
+ return errno;
+ t = rcp->rf_f;
+ rcp->rf_f = f;
+ rc_parse(rcp);
+ rcp->rf_f = t;
+ fclose(f);
+ return 0;
+}
+
+int
+rc_close(struct rcfile *rcp) {
+ struct rcsection *p,*n;
+
+ fclose(rcp->rf_f);
+ for(p = SLIST_FIRST(&rcp->rf_sect);p;) {
+ n = p;
+ p = SLIST_NEXT(p,rs_next);
+ rc_sect_free(n);
+ }
+ free(rcp->rf_name);
+ SLIST_REMOVE(&pf_head, rcp, rcfile, rf_next);
+ free(rcp);
+ return 0;
+}
+
+static struct rcfile*
+rc_find(char *filename) {
+ struct rcfile *p;
+
+ SLIST_FOREACH(p, &pf_head, rf_next)
+ if (strcmp (filename, p->rf_name)==0)
+ return p;
+ return 0;
+}
+
+static struct rcsection *
+rc_findsect(struct rcfile *rcp, char *sectname) {
+ struct rcsection *p;
+
+ SLIST_FOREACH(p, &rcp->rf_sect, rs_next)
+ if (strcmp(p->rs_name, sectname)==0)
+ return p;
+ return NULL;
+}
+
+static struct rcsection *
+rc_addsect(struct rcfile *rcp, char *sectname) {
+ struct rcsection *p;
+
+ p = rc_findsect(rcp, sectname);
+ if (p) return p;
+ p = malloc(sizeof(*p));
+ if (!p) return NULL;
+ p->rs_name = strdup(sectname);
+ SLIST_INIT(&p->rs_keys);
+ SLIST_INSERT_HEAD(&rcp->rf_sect, p, rs_next);
+ return p;
+}
+
+static int
+rc_sect_free(struct rcsection *rsp) {
+ struct rckey *p,*n;
+
+ for(p = SLIST_FIRST(&rsp->rs_keys);p;) {
+ n = p;
+ p = SLIST_NEXT(p,rk_next);
+ rc_key_free(n);
+ }
+ free(rsp->rs_name);
+ free(rsp);
+ return 0;
+}
+
+static struct rckey *
+rc_sect_findkey(struct rcsection *rsp, char *keyname) {
+ struct rckey *p;
+
+ SLIST_FOREACH(p, &rsp->rs_keys, rk_next)
+ if (strcmp(p->rk_name, keyname)==0)
+ return p;
+ return NULL;
+}
+
+static struct rckey *
+rc_sect_addkey(struct rcsection *rsp, char *name, char *value) {
+ struct rckey *p;
+
+ p = rc_sect_findkey(rsp, name);
+ if (p) {
+ free(p->rk_value);
+ } else {
+ p = malloc(sizeof(*p));
+ if (!p) return NULL;
+ SLIST_INSERT_HEAD(&rsp->rs_keys, p, rk_next);
+ p->rk_name = strdup(name);
+ }
+ p->rk_value = value ? strdup(value) : strdup("");
+ return p;
+}
+
+void
+rc_sect_delkey(struct rcsection *rsp, struct rckey *p) {
+
+ SLIST_REMOVE(&rsp->rs_keys,p,rckey,rk_next);
+ rc_key_free(p);
+ return;
+}
+
+static void
+rc_key_free(struct rckey *p){
+ free(p->rk_value);
+ free(p->rk_name);
+ free(p);
+}
+
+enum { stNewLine, stHeader, stSkipToEOL, stGetKey, stGetValue};
+
+static void
+rc_parse(struct rcfile *rcp) {
+ FILE *f = rcp->rf_f;
+ int state = stNewLine, c;
+ struct rcsection *rsp = NULL;
+ struct rckey *rkp = NULL;
+ char buf[2048];
+ char *next = buf, *last = &buf[sizeof(buf)-1];
+
+ while ((c = getc (f)) != EOF) {
+ if (c == '\r')
+ continue;
+ if (state == stNewLine) {
+ next = buf;
+ if (isspace(c))
+ continue; /* skip leading junk */
+ if (c == '[') {
+ state = stHeader;
+ rsp = NULL;
+ continue;
+ }
+ if (c == '#' || c == ';') {
+ state = stSkipToEOL;
+ } else { /* something meaningfull */
+ state = stGetKey;
+ }
+ }
+ if (state == stSkipToEOL || next == last) {/* ignore long lines */
+ if (c == '\n'){
+ state = stNewLine;
+ next = buf;
+ }
+ continue;
+ }
+ if (state == stHeader) {
+ if (c == ']') {
+ *next = 0;
+ next = buf;
+ rsp = rc_addsect(rcp, buf);
+ state = stSkipToEOL;
+ } else
+ *next++ = c;
+ continue;
+ }
+ if (state == stGetKey) {
+ if (c == ' ' || c == '\t')/* side effect: 'key name='*/
+ continue; /* become 'keyname=' */
+ if (c == '\n') { /* silently ignore ... */
+ state = stNewLine;
+ continue;
+ }
+ if (c != '=') {
+ *next++ = c;
+ continue;
+ }
+ *next = 0;
+ if (rsp == NULL) {
+ fprintf(stderr, "Key '%s' defined before section\n", buf);
+ state = stSkipToEOL;
+ continue;
+ }
+ rkp = rc_sect_addkey(rsp, buf, NULL);
+ next = buf;
+ state = stGetValue;
+ continue;
+ }
+ /* only stGetValue left */
+ if (state != stGetValue) {
+ fprintf(stderr, "Well, I can't parse file '%s'\n",rcp->rf_name);
+ state = stSkipToEOL;
+ }
+ if (c != '\n') {
+ *next++ = c;
+ continue;
+ }
+ *next = 0;
+ rkp->rk_value = strdup(buf);
+ state = stNewLine;
+ rkp = NULL;
+ } /* while */
+ if (c == EOF && state == stGetValue) {
+ *next = 0;
+ rkp->rk_value = strdup(buf);
+ }
+ return;
+}
+
+int
+rc_getstringptr(struct rcfile *rcp,char *section, char *key,char **dest) {
+ struct rcsection *rsp;
+ struct rckey *rkp;
+
+ *dest = NULL;
+ rsp = rc_findsect(rcp, section);
+ if (!rsp) return ENOENT;
+ rkp = rc_sect_findkey(rsp,key);
+ if (!rkp) return ENOENT;
+ *dest = rkp->rk_value;
+ return 0;
+}
+
+int
+rc_getstring(struct rcfile *rcp,char *section, char *key,int maxlen,char *dest) {
+ char *value;
+ int error;
+
+ error = rc_getstringptr(rcp, section, key, &value);
+ if (error) return error;
+ if (strlen(value) >= maxlen) {
+ fprintf(stderr, "line too long for key '%s' in section '%s', max = %d\n",key, section, maxlen);
+ return EINVAL;
+ }
+ strcpy(dest,value);
+ return 0;
+}
+
+int
+rc_getint(struct rcfile *rcp,char *section, char *key,int *value) {
+ struct rcsection *rsp;
+ struct rckey *rkp;
+
+ rsp = rc_findsect(rcp, section);
+ if (!rsp) return ENOENT;
+ rkp = rc_sect_findkey(rsp,key);
+ if (!rkp) return ENOENT;
+ errno = 0;
+ *value = strtol(rkp->rk_value,NULL,0);
+ if (errno) {
+ fprintf(stderr, "invalid int value '%s' for key '%s' in section '%s'\n",rkp->rk_value,key,section);
+ return errno;
+ }
+ return 0;
+}
+
+/*
+ * 1,yes,true
+ * 0,no,false
+ */
+int
+rc_getbool(struct rcfile *rcp,char *section, char *key,int *value) {
+ struct rcsection *rsp;
+ struct rckey *rkp;
+ char *p;
+
+ rsp = rc_findsect(rcp, section);
+ if (!rsp) return ENOENT;
+ rkp = rc_sect_findkey(rsp,key);
+ if (!rkp) return ENOENT;
+ p = rkp->rk_value;
+ while (*p && isspace(*p)) p++;
+ if (*p == '0' || strcasecmp(p,"no") == 0 || strcasecmp(p,"false") == 0) {
+ *value = 0;
+ return 0;
+ }
+ if (*p == '1' || strcasecmp(p,"yes") == 0 || strcasecmp(p,"true") == 0) {
+ *value = 1;
+ return 0;
+ }
+ fprintf(stderr, "invalid boolean value '%s' for key '%s' in section '%s' \n",p, key, section);
+ return EINVAL;
+}
+
+/*
+ * first read ~/.nwfsrc, next try to merge NWFS_CFG_FILE
+ */
+int
+ncp_open_rcfile(void) {
+ char *home, *fn;
+ int error;
+
+ home = getenv("HOME");
+ if (home) {
+ fn = malloc(strlen(home) + 20);
+ sprintf(fn, "%s/.nwfsrc", home);
+ error = rc_open(fn,"r",&ncp_rc);
+ free (fn);
+ }
+ error = rc_merge(NWFS_CFG_FILE, &ncp_rc);
+ if( ncp_rc == NULL ) {
+ printf("Warning: no cfg files found.\n");
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/lib/libncp/ncpl_rpc.c b/lib/libncp/ncpl_rpc.c
new file mode 100644
index 0000000..f2f9e54
--- /dev/null
+++ b/lib/libncp/ncpl_rpc.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * NetWare RPCs
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <stdio.h>
+#include <strings.h>
+#include <netncp/ncp_lib.h>
+
+struct ncp_rpc_rq {
+ nuint16 len; /* HL */
+ nuint8 subfn;
+ nuint32 reserved[4];
+ nuint8 flags[4];
+} __attribute__ ((packed));
+
+struct ncp_rpc_rp {
+ nuint32 rpccode;
+ nuint32 reserved[4];
+ nuint32 rpcval;
+} __attribute__ ((packed));
+
+static NWCCODE
+ncp_rpc(NWCONN_HANDLE cH, int rpcfn,
+ const nuint8* rpcarg, char* arg1, char *arg2,
+ nuint32* rpcval) {
+ NWCCODE error;
+ NW_FRAGMENT rq[4], rp;
+ struct ncp_rpc_rq rqh;
+ struct ncp_rpc_rp rph;
+
+ rqh.subfn = rpcfn;
+ if (rpcarg)
+ bcopy(rpcarg, rqh.reserved, 4 * 4 + 4);
+ else
+ bzero(rqh.reserved, 4 * 4 + 4);
+ rq[0].fragAddress = (char*)&rqh;
+ rq[0].fragSize = sizeof(rqh);
+ rq[1].fragAddress = arg1;
+ rq[1].fragSize = strlen(arg1) + 1;
+ rq[2].fragAddress = arg2;
+ rq[2].fragSize = arg2 ? (strlen(arg2) + 1) : 0;
+ rqh.len = htons(rq[2].fragSize + rq[1].fragSize + sizeof(rqh) - 2);
+ rp.fragAddress = (char*)&rph;
+ rp.fragSize = sizeof(rph);
+ error = NWRequest(cH, 131, 3, rq, 1, &rp);
+ if (error) return error;
+ if (rp.fragSize < 4) return EBADRPC;
+ error = rph.rpccode;
+ if (error) return error;
+ if (rpcval) {
+ if (rp.fragSize < 24)
+ return EBADRPC;
+ *rpcval = rph.rpcval;
+ }
+ return 0;
+}
+
+NWCCODE
+NWSMLoadNLM(NWCONN_HANDLE cH, pnstr8 cmd) {
+ return ncp_rpc(cH, 1, NULL, cmd, NULL, NULL);
+}
+
+NWCCODE
+NWSMUnloadNLM(NWCONN_HANDLE cH, pnstr8 cmd) {
+ return ncp_rpc(cH, 2, NULL, cmd, NULL, NULL);
+}
+
+NWCCODE
+NWSMMountVolume(NWCONN_HANDLE cH, pnstr8 volName, nuint32* volnum) {
+ return ncp_rpc(cH, 3, NULL, volName, NULL, volnum);
+}
+
+NWCCODE
+NWSMDismountVolumeByName(NWCONN_HANDLE cH, pnstr8 vol) {
+ return ncp_rpc(cH, 4, NULL, vol, NULL, NULL);
+}
+
+struct ncp_set_hdr {
+ nuint32 typeFlag; /* 0 - str, 1 - value */
+ nuint32 value;
+ nuint32 pad[20 - 4 - 4];
+} __attribute__ ((packed));
+
+NWCCODE
+NWSMSetDynamicCmdIntValue(NWCONN_HANDLE cH, pnstr8 setCommandName, nuint32 cmdValue) {
+ struct ncp_set_hdr rq;
+
+ memset(&rq, 0, sizeof(rq));
+ rq.typeFlag = 1;
+ rq.value = cmdValue;
+ return ncp_rpc(cH, 6, (char*)&rq, setCommandName, NULL, NULL);
+}
+
+NWCCODE
+NWSMSetDynamicCmdStrValue(NWCONN_HANDLE cH, pnstr8 setCommandName,
+ pnstr8 cmdValue) {
+ return ncp_rpc(cH, 6, NULL, setCommandName, cmdValue, NULL);
+}
+
+NWCCODE
+NWSMExecuteNCFFile(NWCONN_HANDLE cH, pnstr8 NCFFileName) {
+ return ncp_rpc(cH, 7, NULL, NCFFileName, NULL, NULL);
+}
diff --git a/lib/libncp/ncpl_subr.c b/lib/libncp/ncpl_subr.c
new file mode 100644
index 0000000..9b36e17
--- /dev/null
+++ b/lib/libncp/ncpl_subr.c
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/sysctl.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include <netncp/ncp_lib.h>
+#include <netncp/ncp_rcfile.h>
+#include <netncp/ncp_nls.h>
+/*#include <netncp/ncp_cfg.h>*/
+#include "ncp_mod.h"
+
+extern char *__progname;
+
+int sysentoffset;
+
+void
+ncp_add_word_lh(struct ncp_buf *conn, u_int16_t x) {
+ setwle(conn->packet, conn->rqsize, x);
+ conn->rqsize += 2;
+ return;
+}
+
+void
+ncp_add_dword_lh(struct ncp_buf *conn, u_int32_t x) {
+ setdle(conn->packet, conn->rqsize, x);
+ conn->rqsize += 4;
+ return;
+}
+
+void
+ncp_add_word_hl(struct ncp_buf *conn, u_int16_t x){
+ setwbe(conn->packet, conn->rqsize, x);
+ conn->rqsize += 2;
+ return;
+}
+
+void
+ncp_add_dword_hl(struct ncp_buf *conn, u_int32_t x) {
+ setdbe(conn->packet, conn->rqsize, x);
+ conn->rqsize += 4;
+ return;
+}
+
+void
+ncp_add_mem(struct ncp_buf *conn, const void *source, int size) {
+ memcpy(conn->packet+conn->rqsize, source, size);
+ conn->rqsize += size;
+ return;
+}
+
+void
+ncp_add_mem_nls(struct ncp_buf *conn, const void *source, int size) {
+ ncp_nls_mem_u2n(conn->packet+conn->rqsize, source, size);
+ conn->rqsize += size;
+ return;
+}
+
+void
+ncp_add_pstring(struct ncp_buf *conn, const char *s) {
+ int len = strlen(s);
+ if (len > 255) {
+ ncp_printf("ncp_add_pstring: string too long: %s\n", s);
+ len = 255;
+ }
+ ncp_add_byte(conn, len);
+ ncp_add_mem(conn, s, len);
+ return;
+}
+
+void
+ncp_add_handle_path(struct ncp_buf *conn, nuint32 volNumber, nuint32 dirNumber,
+ int handleFlag, const char *path)
+{
+ ncp_add_byte(conn, volNumber);
+ ncp_add_dword_lh(conn, dirNumber);
+ ncp_add_byte(conn, handleFlag);
+ if (path) {
+ ncp_add_byte(conn, 1); /* 1 component */
+ ncp_add_pstring(conn, path);
+ } else {
+ ncp_add_byte(conn, 0);
+ }
+}
+
+void
+ncp_init_request(struct ncp_buf *conn) {
+ conn->rqsize = 0;
+ conn->rpsize = 0;
+}
+
+void
+ncp_init_request_s(struct ncp_buf *conn, int subfn) {
+ ncp_init_request(conn);
+ ncp_add_word_lh(conn, 0);
+ ncp_add_byte(conn, subfn);
+}
+
+u_int16_t
+ncp_reply_word_hl(struct ncp_buf *conn, int offset) {
+ return getwbe(ncp_reply_data(conn, offset), 0);
+}
+
+u_int16_t
+ncp_reply_word_lh(struct ncp_buf *conn, int offset) {
+ return getwle(ncp_reply_data(conn, offset), 0);
+}
+
+u_int32_t
+ncp_reply_dword_hl(struct ncp_buf *conn, int offset) {
+ return getdbe(ncp_reply_data(conn, offset), 0);
+}
+
+u_int32_t
+ncp_reply_dword_lh(struct ncp_buf *conn, int offset) {
+ return getdle(ncp_reply_data(conn, offset), 0);
+}
+
+
+int
+ncp_connect(struct ncp_conn_args *li, int *connHandle) {
+ return syscall(NCP_CONNECT,li,connHandle);
+}
+
+int
+ncp_disconnect(int cH) {
+ DECLARE_RQ;
+
+ ncp_init_request(conn);
+ ncp_add_byte(conn, NCP_CONN_CONNCLOSE);
+ return ncp_conn_request(cH, conn);
+}
+
+int
+ncp_request(int connHandle,int function, struct ncp_buf *ncpbuf){
+ int err = syscall(SNCP_REQUEST,connHandle,function,ncpbuf);
+ return (err<0) ? errno : 0;
+}
+
+int
+ncp_conn_request(int connHandle, struct ncp_buf *ncpbuf){
+ return syscall(SNCP_REQUEST, connHandle, NCP_CONN, ncpbuf);
+}
+
+int
+ncp_conn_scan(struct ncp_conn_loginfo *li, int *connid) {
+ return syscall(NCP_CONNSCAN,li, connid);
+}
+
+NWCCODE
+NWRequest(NWCONN_HANDLE cH, nuint16 fn,
+ nuint16 nrq, NW_FRAGMENT* rq,
+ nuint16 nrp, NW_FRAGMENT* rp)
+{
+ int error;
+ struct ncp_conn_frag nf;
+ DECLARE_RQ;
+
+ ncp_init_request(conn);
+ ncp_add_byte(conn, NCP_CONN_FRAG);
+ nf.fn = fn;
+ nf.rqfcnt = nrq;
+ nf.rqf = rq;
+ nf.rpf = rp;
+ nf.rpfcnt = nrp;
+ ncp_add_mem(conn, &nf, sizeof(nf));
+ error = ncp_conn_request(cH, conn);
+ return error;
+}
+
+
+int
+ncp_initlib(void){
+ int error;
+ int len = sizeof(sysentoffset);
+ int kv, kvlen = sizeof(kv);
+ static int ncp_initialized;
+
+ if (ncp_initialized)
+ return 0;
+#if __FreeBSD_version < 400001
+ error = sysctlbyname("net.ipx.ncp.sysent", &sysentoffset, &len, NULL, 0);
+#else
+ error = sysctlbyname("net.ncp.sysent", &sysentoffset, &len, NULL, 0);
+#endif
+ if (error) {
+ fprintf(stderr, "%s: can't find kernel module\n", __FUNCTION__);
+ return error;
+ }
+#if __FreeBSD_version < 400001
+ error = sysctlbyname("net.ipx.ncp.version", &kv, &kvlen, NULL, 0);
+#else
+ error = sysctlbyname("net.ncp.version", &kv, &kvlen, NULL, 0);
+#endif
+ if (error) {
+ fprintf(stderr, "%s: kernel module is old, please recompile it.\n", __FUNCTION__);
+ return error;
+ }
+ if (NCP_VERSION != kv) {
+ fprintf(stderr, "%s: kernel module version(%d) don't match library(%d).\n", __FUNCTION__, kv, NCP_VERSION);
+ return EINVAL;
+ }
+ if ((error = ncp_nls_setrecode(0)) != 0) {
+ fprintf(stderr, "%s: can't initialise recode\n", __FUNCTION__);
+ return error;
+ }
+ if ((error = ncp_nls_setlocale("")) != 0) {
+ fprintf(stderr, "%s: can't initialise locale\n", __FUNCTION__);
+ return error;
+ }
+ ncp_initialized++;
+ return 0;
+}
+
+
+/*
+ */
+int ncp_opterr = 1, /* if error message should be printed */
+ ncp_optind = 1, /* index into parent argv vector */
+ ncp_optopt, /* character checked for validity */
+ ncp_optreset; /* reset getopt */
+char *ncp_optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define BADARG (int)':'
+#define EMSG ""
+
+int
+ncp_getopt(nargc, nargv, ostr)
+ int nargc;
+ char * const *nargv;
+ const char *ostr;
+{
+ extern char *__progname;
+ static char *place = EMSG; /* option letter processing */
+ char *oli; /* option letter list index */
+ int tmpind;
+
+ if (ncp_optreset || !*place) { /* update scanning pointer */
+ ncp_optreset = 0;
+ tmpind = ncp_optind;
+ while (1) {
+ if (tmpind >= nargc) {
+ place = EMSG;
+ return (-1);
+ }
+ if (*(place = nargv[tmpind]) != '-') {
+ tmpind++;
+ continue; /* lookup next option */
+ }
+ if (place[1] && *++place == '-') { /* found "--" */
+ ncp_optind = ++tmpind;
+ place = EMSG;
+ return (-1);
+ }
+ ncp_optind = tmpind;
+ break;
+ }
+ } /* option letter okay? */
+ if ((ncp_optopt = (int)*place++) == (int)':' ||
+ !(oli = strchr(ostr, ncp_optopt))) {
+ /*
+ * if the user didn't specify '-' as an option,
+ * assume it means -1.
+ */
+ if (ncp_optopt == (int)'-')
+ return (-1);
+ if (!*place)
+ ++ncp_optind;
+ if (ncp_opterr && *ostr != ':')
+ (void)fprintf(stderr,
+ "%s: illegal option -- %c\n", __progname, ncp_optopt);
+ return (BADCH);
+ }
+ if (*++oli != ':') { /* don't need argument */
+ ncp_optarg = NULL;
+ if (!*place)
+ ++ncp_optind;
+ }
+ else { /* need an argument */
+ if (*place) /* no white space */
+ ncp_optarg = place;
+ else if (nargc <= ++ncp_optind) { /* no arg */
+ place = EMSG;
+ if (*ostr == ':')
+ return (BADARG);
+ if (ncp_opterr)
+ (void)fprintf(stderr,
+ "%s: option requires an argument -- %c\n",
+ __progname, ncp_optopt);
+ return (BADCH);
+ }
+ else /* white space */
+ ncp_optarg = nargv[ncp_optind];
+ place = EMSG;
+ ++ncp_optind;
+ }
+ return (ncp_optopt); /* dump back option letter */
+}
+/*
+ * misc options parsing routines
+ */
+int
+ncp_args_parserc(struct ncp_args *na, char *sect, ncp_setopt_t *set_callback) {
+ int len, error;
+
+ for (; na->opt; na++) {
+ switch (na->at) {
+ case NCA_STR:
+ if (rc_getstringptr(ncp_rc,sect,na->name,&na->str) == 0) {
+ len = strlen(na->str);
+ if (len > na->ival) {
+ fprintf(stderr,"rc: Argument for option '%c' (%s) too long\n",na->opt,na->name);
+ return EINVAL;
+ }
+ set_callback(na);
+ }
+ break;
+ case NCA_BOOL:
+ error = rc_getbool(ncp_rc,sect,na->name,&na->ival);
+ if (error == ENOENT) break;
+ if (error) return EINVAL;
+ set_callback(na);
+ break;
+ case NCA_INT:
+ if (rc_getint(ncp_rc,sect,na->name,&na->ival) == 0) {
+ if (((na->flag & NAFL_HAVEMIN) &&
+ (na->ival < na->min)) ||
+ ((na->flag & NAFL_HAVEMAX) &&
+ (na->ival > na->max))) {
+ fprintf(stderr,"rc: Argument for option '%c' (%s) should be in [%d-%d] range\n",na->opt,na->name,na->min,na->max);
+ return EINVAL;
+ }
+ set_callback(na);
+ };
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+int
+ncp_args_parseopt(struct ncp_args *na, int opt, char *optarg, ncp_setopt_t *set_callback) {
+ int len;
+
+ for (; na->opt; na++) {
+ if (na->opt != opt) continue;
+ switch (na->at) {
+ case NCA_STR:
+ na->str = optarg;
+ if (optarg) {
+ len = strlen(na->str);
+ if (len > na->ival) {
+ fprintf(stderr,"opt: Argument for option '%c' (%s) too long\n",na->opt,na->name);
+ return EINVAL;
+ }
+ set_callback(na);
+ }
+ break;
+ case NCA_BOOL:
+ na->ival = 0;
+ set_callback(na);
+ break;
+ case NCA_INT:
+ errno = 0;
+ na->ival = strtol(optarg, NULL, 0);
+ if (errno) {
+ fprintf(stderr,"opt: Invalid integer value for option '%c' (%s).\n",na->opt,na->name);
+ return EINVAL;
+ }
+ if (((na->flag & NAFL_HAVEMIN) &&
+ (na->ival < na->min)) ||
+ ((na->flag & NAFL_HAVEMAX) &&
+ (na->ival > na->max))) {
+ fprintf(stderr,"opt: Argument for option '%c' (%s) should be in [%d-%d] range\n",na->opt,na->name,na->min,na->max);
+ return EINVAL;
+ }
+ set_callback(na);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+
+/*
+ * Print a (descriptive) error message
+ * error values:
+ * 0 - no specific error code available;
+ * -999..-1 - NDS error
+ * 1..32767 - system error
+ * the rest - requester error;
+ */
+void
+ncp_error(char *fmt, int error,...) {
+ va_list ap;
+
+ fprintf(stderr, "%s: ", __progname);
+ va_start(ap, error);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ if (error == -1)
+ error = errno;
+ if (error > -1000 && error < 0) {
+ fprintf(stderr, ": dserr = %d\n", error);
+ } else if (error & 0x8000) {
+ fprintf(stderr, ": nwerr = %04x\n", error);
+ } else if (error) {
+ fprintf(stderr, ": syserr = %s\n", strerror(error));
+ } else
+ fprintf(stderr, "\n");
+}
+
+char *
+ncp_printb(char *dest, int flags, const struct ncp_bitname *bnp) {
+ int first = 1;
+
+ strcpy(dest, "<");
+ for(; bnp->bn_bit; bnp++) {
+ if (flags & bnp->bn_bit) {
+ strcat(dest, bnp->bn_name);
+ first = 0;
+ }
+ if (!first && (flags & bnp[1].bn_bit))
+ strcat(dest, "|");
+ }
+ strcat(dest, ">");
+ return dest;
+}
diff --git a/lib/libncp/sap.c b/lib/libncp/sap.c
new file mode 100644
index 0000000..78531ab
--- /dev/null
+++ b/lib/libncp/sap.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 1999, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netipx/ipx.h>
+#include <errno.h>
+#include <unistd.h>
+#include "ipxsap.h"
+
+/*
+ * TODO: These should go to ipx headers
+ */
+#define ipx_set_net(x,y) ((x).x_net.s_net[0] = (y).x_net.s_net[0]); \
+ ((x).x_net.s_net[1]=(y).x_net.s_net[1])
+#define ipx_set_nullnet(x) ((x).x_net.s_net[0]=0); ((x).x_net.s_net[1]=0)
+#define ipx_set_nullhost(x) ((x).x_host.s_host[0] = 0); \
+ ((x).x_host.s_host[1] = 0); ((x).x_host.s_host[2] = 0)
+#define ipx_set_wildnet(x) ((x).x_net.s_net[0] = 0xFFFF); \
+ ((x).x_net.s_net[1]=0xFFFF)
+#define ipx_set_wildhost(x) ((x).x_host.s_host[0] = 0xFFFF); \
+ ((x).x_host.s_host[1] = 0xFFFF); ((x).x_host.s_host[2] = 0xFFFF);
+
+
+static struct sap_packet* sap_packet_alloc(int entries);
+static int sap_size(int entries, u_short operation);
+int (*sap_sendto_func)(void*,int,struct sockaddr_ipx*,int sock)=NULL;
+
+static int
+sap_sendto(void* buffer, int size, struct sockaddr_ipx* daddr, int sock)
+{
+ if (sap_sendto_func)
+ return sap_sendto_func(buffer,size,daddr,sock);
+ return sendto(sock, (char*)buffer, size, 0,
+ (struct sockaddr*)daddr, sizeof(*daddr));
+}
+
+static struct sap_packet*
+sap_packet_alloc(int entries)
+{
+ if (entries > IPX_SAP_MAX_ENTRIES)
+ return NULL;
+ return
+ (struct sap_packet*)malloc(sap_size(entries, IPX_SAP_GENERAL_RESPONSE));
+}
+
+static int
+sap_size(int entries, u_short operation)
+{
+ if (entries <= 0)
+ return 0;
+ switch (operation) {
+ case IPX_SAP_GENERAL_QUERY:
+ return entries == 1 ? IPX_SAP_REQUEST_LEN : 0;
+ case IPX_SAP_GENERAL_RESPONSE:
+ if (entries > IPX_SAP_MAX_ENTRIES)
+ return 0;
+ return sizeof(struct sap_packet) + (entries - 1) * sizeof(struct sap_entry);
+ case IPX_SAP_NEAREST_QUERY:
+ return entries == 1 ? IPX_SAP_REQUEST_LEN : 0;
+ case IPX_SAP_NEAREST_RESPONSE:
+ return entries == 1 ? sizeof(struct sap_packet) : 0;
+ default:
+ return 0;
+ }
+}
+
+void
+sap_copyname(char *dest, const char *src)
+{
+ bzero(dest, IPX_SAP_SERVER_NAME_LEN);
+ strncpy(dest, src, IPX_SAP_SERVER_NAME_LEN - 1);
+}
+
+int
+sap_rq_init(struct sap_rq* rq, int sock)
+{
+ rq->buffer = sap_packet_alloc(IPX_SAP_MAX_ENTRIES);
+ if (rq->buffer == NULL)
+ return 0;
+ rq->entries = 0;
+ rq->buffer->operation = htons(IPX_SAP_GENERAL_QUERY);
+ rq->dest_addr.sipx_family = AF_IPX;
+ rq->dest_addr.sipx_len = sizeof(struct sockaddr_ipx);
+ rq->sock = sock;
+ return 1;
+}
+
+int
+sap_rq_flush(struct sap_rq* rq)
+{
+ int result;
+
+ if (rq->entries == 0)
+ return 0;
+ result = sap_sendto(rq->buffer,
+ sap_size(rq->entries, ntohs(rq->buffer->operation)),
+ &rq->dest_addr, rq->sock);
+ rq->entries = 0;
+ return result;
+}
+
+void
+sap_rq_general_query(struct sap_rq* rq, u_short ser_type)
+{
+ struct sap_entry* sep;
+
+ sap_rq_flush(rq);
+ rq->buffer->operation = htons(IPX_SAP_GENERAL_QUERY);
+ sep = rq->buffer->sap_entries + rq->entries++;
+ sep->server_type = htons(ser_type);
+}
+
+void
+sap_rq_gns_request(struct sap_rq* rq, u_short ser_type)
+{
+ struct sap_entry* sep;
+
+ sap_rq_flush(rq);
+ rq->buffer->operation = htons(IPX_SAP_NEAREST_QUERY);
+ sep = rq->buffer->sap_entries + rq->entries++;
+ sep->server_type = htons(ser_type);
+}
+
+void
+sap_rq_general_response(struct sap_rq* rq,u_short type,char *name,struct sockaddr_ipx* addr, u_short hops,int down_allow)
+{
+ struct sap_entry* sep;
+
+ if (hops >= IPX_SAP_SERVER_DOWN && !down_allow) return;
+ if (rq->entries >= IPX_SAP_MAX_ENTRIES)
+ sap_rq_flush(rq);
+ if (rq->buffer->operation != htons(IPX_SAP_GENERAL_RESPONSE)){
+ sap_rq_flush(rq);
+ rq->buffer->operation = htons(IPX_SAP_GENERAL_RESPONSE);
+ }
+ sep = rq->buffer->sap_entries + rq->entries;
+ sep->server_type = htons(type);
+ sap_copyname(sep->server_name, name);
+ memcpy(&sep->ipx, &addr->sipx_addr, sizeof(struct ipx_addr));
+ sep->hops = htons(hops);
+ rq->entries++;
+}
+
+void
+sap_rq_gns_response(struct sap_rq* rq,u_short type,char *name,struct sockaddr_ipx* addr,u_short hops)
+{
+ struct sap_entry* sep;
+
+ if (hops >= IPX_SAP_SERVER_DOWN) return;
+ sap_rq_flush(rq);
+ rq->buffer->operation = htons(IPX_SAP_NEAREST_RESPONSE);
+ sep = rq->buffer->sap_entries + rq->entries;
+ sep->server_type = htons(type);
+ sap_copyname(sep->server_name, name);
+ memcpy(&sep->ipx, &addr->sipx_addr, sizeof(struct ipx_addr));
+ sep->hops = htons(hops);
+ rq->entries++;
+}
+
+void
+sap_rq_set_destination(struct sap_rq* rq,struct ipx_addr *dest)
+{
+ sap_rq_flush(rq);
+ memcpy(&rq->dest_addr.sipx_addr,dest,sizeof(struct ipx_addr));
+}
+
+int
+sap_getsock(int *rsock) {
+ struct sockaddr_ipx sap_addr;
+ int opt, sock, slen;
+
+ sock = socket(AF_IPX, SOCK_DGRAM, 0);
+ if (sock < 0)
+ return (errno);
+ slen = sizeof(sap_addr);
+ bzero(&sap_addr, slen);
+ sap_addr.sipx_family = AF_IPX;
+ sap_addr.sipx_len = slen;
+ if (bind(sock, (struct sockaddr*)&sap_addr, slen) == -1) {
+ close(sock);
+ return(errno);
+ }
+ opt = 1;
+ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) != 0){
+ close(sock);
+ return(errno);
+ }
+ *rsock = sock;
+ return(0);
+}
+
+static int
+sap_recv(int sock,void *buf,int len,int flags, int timeout){
+ fd_set rd, wr, ex;
+ struct timeval tv;
+ int result;
+
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&ex);
+ FD_SET(sock, &rd);
+
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+
+ if ((result = select(sock + 1, &rd, &wr, &ex, &tv)) == -1) {
+ return result;
+ }
+ if (FD_ISSET(sock, &rd)) {
+ result = recv(sock, buf, len, flags);
+ } else {
+ errno = ETIMEDOUT;
+ result = -1;
+ }
+ return result;
+}
+
+int
+sap_find_nearest(int server_type, struct sockaddr_ipx *daddr, char *server_name)
+{
+ struct ipx_addr addr;
+ char data[1024];
+ int sock, error, packets, len;
+ struct sap_packet *reply = (struct sap_packet*)&data;
+ struct sap_rq sap_rq;
+
+ error = sap_getsock(&sock);
+ if (error)
+ return error;
+ bzero(&addr, sizeof(addr));
+ /* BAD: we should enum all ifs (and nets ?) */
+ if (ipx_iffind(NULL, &addr) != 0) {
+ return (EPROTONOSUPPORT);
+ }
+ ipx_set_wildhost(addr);
+ addr.x_port = htons(IPXPORT_SAP);
+
+ if (!sap_rq_init(&sap_rq, sock)) {
+ close(sock);
+ return(ENOMEM);
+ }
+ sap_rq_set_destination(&sap_rq, &addr);
+ sap_rq_gns_request(&sap_rq, server_type);
+ sap_rq_flush(&sap_rq);
+ packets = 5;
+ do {
+ len = sap_recv(sock, data, sizeof(data), 0, 1);
+ if (len >= 66 &&
+ ntohs(reply->operation) == IPX_SAP_NEAREST_RESPONSE)
+ break;
+ if (len < 0)
+ packets--;
+ } while (packets > 0);
+
+ if (packets == 0) {
+ close(sock);
+ return ENETDOWN;
+ }
+
+ daddr->sipx_addr = reply->sap_entries[0].ipx;
+ daddr->sipx_family = AF_IPX;
+ daddr->sipx_len = sizeof(struct sockaddr_ipx);
+ sap_copyname(server_name, reply->sap_entries[0].server_name);
+ errno = 0;
+ close(sock);
+ return 0;
+}
diff --git a/lib/libncurses/Makefile b/lib/libncurses/Makefile
new file mode 100644
index 0000000..31ea17c
--- /dev/null
+++ b/lib/libncurses/Makefile
@@ -0,0 +1,520 @@
+# $FreeBSD$
+
+NCURSES=${.CURDIR}/../../contrib/ncurses
+
+LIB= ncurses
+SHLIB_MAJOR=5
+SHLIB_MINOR=0
+
+# Should be elsewhere
+AWK?= awk
+TERMINFODIR?= ${DESTDIR}/usr/share/misc
+
+NCURSES_MAJOR!=egrep 'NCURSES_MAJOR[ ]*=' ${NCURSES}/dist.mk | sed -e 's/^[^0-9]*//'
+NCURSES_MINOR!=egrep 'NCURSES_MINOR[ ]*=' ${NCURSES}/dist.mk | sed -e 's/^[^0-9]*//'
+NCURSES_PATCH!=egrep 'NCURSES_PATCH[ ]*=' ${NCURSES}/dist.mk | sed -e 's/^[^0-9]*//'
+
+# From autoconf (!)
+NCURSES_CONST=
+NCURSES_XNAMES= 0
+OSPEED_INCLUDES=\#include <termios.h>
+OSPEED_TYPE= speed_t
+BUILTIN_BOOL= 1
+BOOL_TYPE= 0
+TYPE_OF_BOOL= char
+TYPEOF_CHTYPE= long
+WIDEC_SHIFT= 8
+SHIFT_LIMIT= 32
+ONEUL= 1UL
+
+.PATH: ${NCURSES}/ncurses
+.PATH: ${NCURSES}/ncurses/base
+.PATH: ${NCURSES}/ncurses/tinfo
+.PATH: ${NCURSES}/ncurses/tty
+.PATH: ${NCURSES}/ncurses/trace
+.PATH: ${NCURSES}/include
+.PATH: ${NCURSES}/man
+
+INCS= -I. -I${.CURDIR} -I${NCURSES}/ncurses -I${NCURSES}/include
+CFLAGS+=${INCS} -Wall -DFREEBSD_NATIVE -DNDEBUG -DHAVE_CONFIG_H -DTERMIOS
+
+GENSRC= \
+ codes.c \
+ expanded.c \
+ fallback.c \
+ lib_gen.c \
+ lib_keyname.c \
+ names.c \
+ unctrl.c
+
+GENHDR= \
+ curses.h \
+ hashsize.h \
+ init_keytry.h \
+ nomacros.h \
+ parametrized.h \
+ term.h \
+ termcap.h \
+ unctrl.h
+
+# Installed
+HEADERS=curses.h term.h termcap.h unctrl.h
+
+# Components of names.c and codes.c
+NAMESRC=boolnames boolfnames numnames numfnames strnames strfnames
+CODESRC=boolcodes numcodes strcodes
+
+SRCS= ${GENHDR} ${GENSRC} \
+ access.c \
+ add_tries.c \
+ alloc_entry.c \
+ alloc_ttype.c \
+ captoinfo.c \
+ comp_captab.c \
+ comp_error.c \
+ comp_expand.c \
+ comp_hash.c \
+ comp_parse.c \
+ comp_scan.c \
+ define_key.c \
+ doalloc.c \
+ free_ttype.c \
+ getenv_num.c \
+ hardscroll.c \
+ hashmap.c \
+ home_terminfo.c \
+ init_keytry.c \
+ keybound.c \
+ keyok.c \
+ lib_acs.c \
+ lib_addch.c \
+ lib_addstr.c \
+ lib_baudrate.c \
+ lib_beep.c \
+ lib_bkgd.c \
+ lib_box.c \
+ lib_chgat.c \
+ lib_clear.c \
+ lib_clearok.c \
+ lib_clrbot.c \
+ lib_clreol.c \
+ lib_color.c \
+ lib_colorset.c \
+ lib_cur_term.c \
+ lib_data.c \
+ lib_delch.c \
+ lib_delwin.c \
+ lib_dft_fgbg.c \
+ lib_echo.c \
+ lib_endwin.c \
+ lib_erase.c \
+ lib_flash.c \
+ lib_freeall.c \
+ lib_getch.c \
+ lib_getstr.c \
+ lib_has_cap.c \
+ lib_hline.c \
+ lib_immedok.c \
+ lib_inchstr.c \
+ lib_initscr.c \
+ lib_insch.c \
+ lib_insdel.c \
+ lib_insstr.c \
+ lib_instr.c \
+ lib_isendwin.c \
+ lib_kernel.c \
+ lib_leaveok.c \
+ lib_longname.c \
+ lib_mouse.c \
+ lib_move.c \
+ lib_mvcur.c \
+ lib_mvwin.c \
+ lib_napms.c \
+ lib_newterm.c \
+ lib_newwin.c \
+ lib_nl.c \
+ lib_options.c \
+ lib_overlay.c \
+ lib_pad.c \
+ lib_print.c \
+ lib_printw.c \
+ lib_raw.c \
+ lib_redrawln.c \
+ lib_refresh.c \
+ lib_restart.c \
+ lib_scanw.c \
+ lib_screen.c \
+ lib_scroll.c \
+ lib_scrollok.c \
+ lib_scrreg.c \
+ lib_set_term.c \
+ lib_setup.c \
+ lib_slk.c \
+ lib_slkatr_set.c \
+ lib_slkatrof.c \
+ lib_slkatron.c \
+ lib_slkatrset.c \
+ lib_slkattr.c \
+ lib_slkclear.c \
+ lib_slkcolor.c \
+ lib_slkinit.c \
+ lib_slklab.c \
+ lib_slkrefr.c \
+ lib_slkset.c \
+ lib_slktouch.c \
+ lib_termcap.c \
+ lib_termname.c \
+ lib_ti.c \
+ lib_touch.c \
+ lib_tparm.c \
+ lib_tputs.c \
+ lib_trace.c \
+ lib_traceatr.c \
+ lib_tracebits.c \
+ lib_tracechr.c \
+ lib_tracedmp.c \
+ lib_tracemse.c \
+ lib_tstp.c \
+ lib_ttyflags.c \
+ lib_twait.c \
+ lib_ungetch.c \
+ lib_vidattr.c \
+ lib_vline.c \
+ lib_wattroff.c \
+ lib_wattron.c \
+ lib_winch.c \
+ lib_window.c \
+ memmove.c \
+ name_match.c \
+ nc_panel.c \
+ parse_entry.c \
+ read_entry.c \
+ resizeterm.c \
+ safe_sprintf.c \
+ setbuf.c \
+ sigaction.c \
+ trace_buf.c \
+ trace_tries.c \
+ trace_xnames.c \
+ tries.c \
+ tty_update.c \
+ vsscanf.c \
+ wresize.c \
+ write_entry.c \
+
+# From our old libtermcap.
+# Used instead of the hideous read_termcap.c abomination.
+SRCS+= termcap.c
+
+CLEANFILES+= ${GENSRC} ${GENHDR} keys.tries make_hash term.h.new \
+ make_keys MKterm.h.awk comp_captab.c \
+ namehdr nameftr codeftr ${NAMESRC} ${CODESRC}
+
+SYMLINKS+=libncurses.a ${LIBDIR}/libcurses.a
+SYMLINKS+=libncurses.a ${LIBDIR}/libtermcap.a
+SYMLINKS+=libncurses.a ${LIBDIR}/libtermlib.a
+SYMLINKS+=libncurses.a ${LIBDIR}/libmytinfo.a
+SYMLINKS+=libncurses.a ${LIBDIR}/libtinfo.a
+.if !defined(NOPIC)
+.if ${OBJFORMAT} == aout
+SYMLINKS+=libncurses.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ libcurses.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
+SYMLINKS+=libncurses.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ libtermcap.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
+SYMLINKS+=libncurses.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ libtermlib.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
+SYMLINKS+=libncurses.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ libmytinfo.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
+SYMLINKS+=libncurses.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ libtinfo.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
+.else
+# no need for major at all, it's an ld-time redirection only
+SYMLINKS+=libncurses.so ${SHLIBDIR}/libcurses.so
+SYMLINKS+=libncurses.so ${SHLIBDIR}/libtermcap.so
+SYMLINKS+=libncurses.so ${SHLIBDIR}/libtermlib.so
+SYMLINKS+=libncurses.so ${SHLIBDIR}/libmytinfo.so
+SYMLINKS+=libncurses.so ${SHLIBDIR}/libtinfo.so
+.endif
+.endif
+.if !defined(NOPROFILE)
+SYMLINKS+=libncurses_p.a ${LIBDIR}/libcurses_p.a
+SYMLINKS+=libncurses_p.a ${LIBDIR}/libtermcap_p.a
+SYMLINKS+=libncurses_p.a ${LIBDIR}/libtermlib_p.a
+SYMLINKS+=libncurses_p.a ${LIBDIR}/libmytinfo_p.a
+SYMLINKS+=libncurses_p.a ${LIBDIR}/libtinfo_p.a
+.endif
+
+beforeinstall: ${HEADERS}
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 ${HEADERS} \
+ ${DESTDIR}/usr/include
+ rm -f ${DESTDIR}/usr/include/ncurses.h
+ ln -s curses.h ${DESTDIR}/usr/include/ncurses.h
+
+# Generated source
+namehdr nameftr codeftr ${NAMESRC} ${CODESRC}: MKnames.awk Caps
+ ${AWK} -f ${NCURSES}/ncurses/tinfo/MKnames.awk ${NCURSES}/include/Caps
+
+.ORDER: namehdr ${NAMESRC} ${CODESRC} nameftr codeftr names.c codes.c
+
+names.c: namehdr ${NAMESRC} nameftr
+ cat namehdr ${NAMESRC} nameftr > $@
+
+codes.c: namehdr ${CODESRC} codeftr
+ cat namehdr ${CODESRC} codeftr > $@
+
+lib_gen.c: MKlib_gen.sh curses.h
+ sh ${NCURSES}/ncurses/base/MKlib_gen.sh "${CC} -E ${INCS}" \
+ "${AWK}" < curses.h >$@
+
+lib_keyname.c: keys.list MKkeyname.awk
+ ${AWK} -f ${NCURSES}/ncurses/base/MKkeyname.awk \
+ ${NCURSES}/ncurses/tinfo/keys.list > lib_keyname.c
+
+unctrl.c: MKunctrl.awk
+ echo | ${AWK} -f ${NCURSES}/ncurses/base/MKunctrl.awk > unctrl.c
+
+comp_captab.c: MKcaptab.awk Caps make_hash
+ sh ${NCURSES}/ncurses/tinfo/MKcaptab.awk "${AWK}" \
+ ${NCURSES}/include/Caps > comp_captab.c
+
+expanded.c: MKexpanded.sh
+ sh ${NCURSES}/ncurses/tty/MKexpanded.sh "${CC} -E" ${CFLAGS} >expanded.c
+
+fallback.c: MKfallback.sh
+ sh ${NCURSES}/ncurses/tinfo/MKfallback.sh > fallback.c
+
+# Generated headers
+nomacros.h: MKlib_gen.sh curses.h
+ sh ${NCURSES}/ncurses/base/MKlib_gen.sh "${CC} -E ${INCS}" \
+ "${AWK}" < curses.h | fgrep undef > $@
+
+init_keytry.h: keys.list make_keys
+ ./make_keys ${NCURSES}/ncurses/tinfo/keys.list > init_keytry.h
+
+hashsize.h: MKhashsize.sh Caps
+ sh ${NCURSES}/include/MKhashsize.sh ${NCURSES}/include/Caps > $@
+
+parametrized.h: MKparametrized.sh Caps
+ AWK=${AWK} sh ${NCURSES}/include/MKparametrized.sh \
+ ${NCURSES}/include/Caps > $@
+
+term.h: MKterm.h.awk edit_cfg.sh Caps
+ ${AWK} -f MKterm.h.awk ${NCURSES}/include/Caps > $@.new
+ sh ${NCURSES}/include/edit_cfg.sh ${.CURDIR}/ncurses_cfg.h $@.new
+ mv -f $@.new $@
+
+# Build tools
+build-tools: make_hash make_keys
+
+make_keys: make_keys.c names.c
+ ${CC} -o $@ ${CFLAGS} ${NCURSES}/ncurses/tinfo/make_keys.c
+
+make_hash: comp_hash.c hashsize.h
+ ${CC} -o $@ ${CFLAGS} -DMAIN_PROGRAM \
+ ${NCURSES}/ncurses/tinfo/comp_hash.c
+
+# ./configure generated
+MKterm.h.awk: MKterm.h.awk.in
+ sed <${NCURSES}/include/$@.in >$@ \
+ -e "/@NCURSES_MAJOR@/s//${NCURSES_MAJOR}/" \
+ -e "/@NCURSES_MINOR@/s//${NCURSES_MINOR}/" \
+ -e "/@NCURSES_CONST@/s//${NCURSES_CONST}/" \
+ -e "/@NCURSES_XNAMES@/s//${NCURSES_XNAMES}/"
+
+termcap.h: termcap.h.in
+ sed <${NCURSES}/include/$@.in >$@ \
+ -e "/@NCURSES_MAJOR@/s//${NCURSES_MAJOR}/" \
+ -e "/@NCURSES_MINOR@/s//${NCURSES_MINOR}/" \
+ -e "/@NCURSES_CONST@/s//${NCURSES_CONST}/" \
+ -e "/@OSPEED_INCLUDES@/s//${OSPEED_INCLUDES}/" \
+ -e "/@OSPEED_TYPE@/s//${OSPEED_TYPE}/"
+
+curses.h: curses.h.in
+ sed <${NCURSES}/include/$@.in >$@ \
+ -e "/@NCURSES_MAJOR@/s//${NCURSES_MAJOR}/" \
+ -e "/@NCURSES_MINOR@/s//${NCURSES_MINOR}/" \
+ -e "/@NCURSES_PATCH@/s//${NCURSES_PATCH}/" \
+ -e "/@NCURSES_CONST@/s//${NCURSES_CONST}/" \
+ -e "s/@cf_cv_builtin_bool@/${BUILTIN_BOOL}/g" \
+ -e "s/@cf_cv_cc_bool_type@/${BOOL_TYPE}/g" \
+ -e "s/@cf_cv_type_of_bool@/${TYPE_OF_BOOL}/g" \
+ -e "s/@cf_cv_typeof_chtype@/${TYPEOF_CHTYPE}/g" \
+ -e "s/@cf_cv_widec_shift@/${WIDEC_SHIFT}/g" \
+ -e "s/@cf_cv_shift_limit@/${SHIFT_LIMIT}/g" \
+ -e "s/@cf_cv_1UL@/${ONEUL}/g"
+
+unctrl.h: unctrl.h.in
+ sed <${NCURSES}/include/$@.in >$@ \
+ -e "/@NCURSES_MAJOR@/s//${NCURSES_MAJOR}/" \
+ -e "/@NCURSES_MINOR@/s//${NCURSES_MINOR}/"
+
+# MAN page gunk
+terminfo.5: MKterminfo.sh terminfo.head Caps
+ sh ${NCURSES}/man/MKterminfo.sh ${NCURSES}/man/terminfo.head \
+ ${NCURSES}/include/Caps ${NCURSES}/man/terminfo.tail >$@
+
+CLEANFILES+= terminfo.5
+MANFILTER= sed -e 's\#@DATADIR@\#${TERMINFODIR}/terminfo\#g'
+
+MAN3x= curs_addch.3x curs_addchstr.3x curs_addstr.3x curs_attr.3x \
+ curs_beep.3x curs_bkgd.3x curs_border.3x curs_clear.3x curs_color.3x \
+ curs_delch.3x curs_deleteln.3x curs_getch.3x curs_getstr.3x \
+ curs_getyx.3x curs_inch.3x curs_inchstr.3x curs_initscr.3x \
+ curs_inopts.3x curs_insch.3x curs_insstr.3x curs_instr.3x \
+ curs_kernel.3x curs_mouse.3x curs_move.3x curs_outopts.3x \
+ curs_overlay.3x curs_pad.3x curs_print.3x curs_printw.3x \
+ curs_refresh.3x curs_scanw.3x curs_scr_dump.3x curs_scroll.3x \
+ curs_slk.3x curs_termattrs.3x curs_termcap.3x curs_terminfo.3x \
+ curs_touch.3x curs_util.3x curs_window.3x define_key.3x \
+ dft_fgbg.3x keybound.3x keyok.3x ncurses.3x resizeterm.3x wresize.3x
+MAN5= term.5 terminfo.5
+MAN7= term.7
+
+# Generate the MAN3 list from MAN3x
+.for page in ${MAN3x}
+CLEANFILES+=${page:T:S/3x$/3/g}
+MAN3+=${page:T:S/3x$/3/g}
+all-man: ${page:T:S/3x$/3/g}
+${page:T:S/3x$/3/g}: ${page}
+ ln -s ${.ALLSRC} ${.TARGET}
+.endfor
+
+MLINKS+=curs_addch.3 addch.3 curs_addch.3 echochar.3 curs_addch.3 mvaddch.3 \
+ curs_addch.3 mvwaddch.3 curs_addch.3 waddch.3 curs_addch.3 wechochar.3
+MLINKS+=curs_addchstr.3 addchnstr.3 curs_addchstr.3 addchstr.3 \
+ curs_addchstr.3 mvaddchnstr.3 curs_addchstr.3 mvaddchstr.3 \
+ curs_addchstr.3 mvwaddchnstr.3 curs_addchstr.3 mvwaddchstr.3 \
+ curs_addchstr.3 waddchnstr.3 curs_addchstr.3 waddchstr.3
+MLINKS+=curs_addstr.3 addnstr.3 curs_addstr.3 addstr.3 \
+ curs_addstr.3 mvaddnstr.3 curs_addstr.3 mvaddstr.3 \
+ curs_addstr.3 mvwaddnstr.3 curs_addstr.3 mvwaddstr.3 \
+ curs_addstr.3 waddnstr.3 curs_addstr.3 waddstr.3
+MLINKS+=curs_attr.3 attr_get.3 curs_attr.3 attr_off.3 curs_attr.3 attr_on.3 \
+ curs_attr.3 attr_set.3 curs_attr.3 attroff.3 curs_attr.3 attron.3 \
+ curs_attr.3 attrset.3 curs_attr.3 chgat.3 curs_attr.3 color_set.3 \
+ curs_attr.3 mvchgat.3 curs_attr.3 mvwchgat.3 curs_attr.3 standend.3 \
+ curs_attr.3 standout.3 curs_attr.3 wattr_get.3 curs_attr.3 wattr_off.3 \
+ curs_attr.3 wattr_on.3 curs_attr.3 wattr_set.3 curs_attr.3 wattroff.3 \
+ curs_attr.3 wattron.3 curs_attr.3 wattrset.3 curs_attr.3 wchgat.3 \
+ curs_attr.3 wcolor_set.3 curs_attr.3 wstandend.3 \
+ curs_attr.3 wstandout.3
+MLINKS+=curs_beep.3 beep.3 curs_beep.3 flash.3
+MLINKS+=curs_bkgd.3 bkgd.3 curs_bkgd.3 bkgdset.3 curs_bkgd.3 getbkgd.3 \
+ curs_bkgd.3 wbkgd.3 curs_bkgd.3 wbkgdset.3
+MLINKS+=curs_border.3 border.3 curs_border.3 box.3 curs_border.3 hline.3 \
+ curs_border.3 mvhline.3 curs_border.3 mvwhline.3 \
+ curs_border.3 mvwvline.3 curs_border.3 vline.3 curs_border.3 wborder.3 \
+ curs_border.3 whline.3 curs_border.3 wvline.3
+MLINKS+=curs_clear.3 clear.3 curs_clear.3 clrtobot.3 curs_clear.3 clrtoeol.3 \
+ curs_clear.3 erase.3 curs_clear.3 wclear.3 curs_clear.3 wclrtobot.3 \
+ curs_clear.3 wclrtoeol.3 curs_clear.3 werase.3
+MLINKS+=curs_color.3 can_change_color.3 curs_color.3 color_content.3 \
+ curs_color.3 has_colors.3 curs_color.3 init_color.3 \
+ curs_color.3 init_pair.3 curs_color.3 pair_content.3 \
+ curs_color.3 start_color.3
+MLINKS+=curs_delch.3 delch.3 curs_delch.3 mvdelch.3 curs_delch.3 mvwdelch.3 \
+ curs_delch.3 wdelch.3
+MLINKS+=curs_deleteln.3 deleteln.3 curs_deleteln.3 insdelln.3 \
+ curs_deleteln.3 insertln.3 curs_deleteln.3 wdeleteln.3 \
+ curs_deleteln.3 winsdelln.3 curs_deleteln.3 winsertln.3
+MLINKS+=curs_getch.3 getch.3 curs_getch.3 has_key.3 curs_getch.3 mvgetch.3 \
+ curs_getch.3 mvwgetch.3 curs_getch.3 ungetch.3 curs_getch.3 wgetch.3
+MLINKS+=curs_getstr.3 getnstr.3 curs_getstr.3 getstr.3 \
+ curs_getstr.3 mvgetnstr.3 curs_getstr.3 mvgetstr.3 \
+ curs_getstr.3 mvwgetnstr.3 curs_getstr.3 mvwgetstr.3 \
+ curs_getstr.3 wgetnstr.3 curs_getstr.3 wgetstr.3
+MLINKS+=curs_getyx.3 getbegyx.3 curs_getyx.3 getmaxyx.3 \
+ curs_getyx.3 getparyx.3 curs_getyx.3 getyx.3
+MLINKS+=curs_inch.3 inch.3 curs_inch.3 mvinch.3 curs_inch.3 mvwinch.3 \
+ curs_inch.3 winch.3
+MLINKS+=curs_inchstr.3 inchnstr.3 curs_inchstr.3 inchstr.3 \
+ curs_inchstr.3 mvinchnstr.3 curs_inchstr.3 mvinchstr.3 \
+ curs_inchstr.3 mvwinchnstr.3 curs_inchstr.3 mvwinchstr.3 \
+ curs_inchstr.3 winchnstr.3 curs_inchstr.3 winchstr.3
+MLINKS+=curs_initscr.3 delscreen.3 curs_initscr.3 endwin.3 \
+ curs_initscr.3 initscr.3 curs_initscr.3 isendwin.3 \
+ curs_initscr.3 newterm.3 curs_initscr.3 set_term.3
+MLINKS+=curs_inopts.3 cbreak.3 curs_inopts.3 echo.3 curs_inopts.3 halfdelay.3 \
+ curs_inopts.3 intrflush.3 curs_inopts.3 keypad.3 curs_inopts.3 meta.3 \
+ curs_inopts.3 nocbreak.3 curs_inopts.3 nodelay.3 \
+ curs_inopts.3 noecho.3 curs_inopts.3 noqiflush.3 curs_inopts.3 noraw.3 \
+ curs_inopts.3 notimeout.3 curs_inopts.3 qiflush.3 curs_inopts.3 raw.3 \
+ curs_inopts.3 timeout.3 curs_inopts.3 typeahead.3 \
+ curs_inopts.3 wtimeout.3
+MLINKS+=curs_insch.3 insch.3 curs_insch.3 mvinsch.3 curs_insch.3 mvwinsch.3 \
+ curs_insch.3 winsch.3
+MLINKS+=curs_insstr.3 insnstr.3 curs_insstr.3 insstr.3 \
+ curs_insstr.3 mvinsnstr.3 curs_insstr.3 mvinsstr.3 \
+ curs_insstr.3 mvwinsnstr.3 curs_insstr.3 mvwinsstr.3 \
+ curs_insstr.3 winsnstr.3 curs_insstr.3 winsstr.3
+MLINKS+=curs_instr.3 innstr.3 curs_instr.3 instr.3 curs_instr.3 mvinnstr.3 \
+ curs_instr.3 mvinstr.3 curs_instr.3 mvwinnstr.3 \
+ curs_instr.3 mvwinstr.3 curs_instr.3 winnstr.3 curs_instr.3 winstr.3
+MLINKS+=curs_kernel.3 curs_set.3 curs_kernel.3 def_prog_mode.3 \
+ curs_kernel.3 def_shell_mode.3 curs_kernel.3 getsyx.3 \
+ curs_kernel.3 napms.3 curs_kernel.3 reset_prog_mode.3 \
+ curs_kernel.3 reset_shell_mode.3 curs_kernel.3 resetty.3 \
+ curs_kernel.3 ripoffline.3 curs_kernel.3 savetty.3 \
+ curs_kernel.3 setsyx.3
+MLINKS+=curs_mouse.3 getmouse.3 curs_mouse.3 mouseinterval.3 \
+ curs_mouse.3 mousemask.3 curs_mouse.3 ungetmouse.3 \
+ curs_mouse.3 wenclose.3 curs_mouse.3 wmouse_trafo.3
+MLINKS+=curs_move.3 move.3 curs_move.3 wmove.3
+MLINKS+=curs_outopts.3 clearok.3 curs_outopts.3 idcok.3 curs_outopts.3 idlok.3 \
+ curs_outopts.3 immedok.3 curs_outopts.3 leaveok.3 curs_outopts.3 nl.3 \
+ curs_outopts.3 nonl.3 curs_outopts.3 scrollok.3 \
+ curs_outopts.3 setscrreg.3 curs_outopts.3 wsetscrreg.3
+MLINKS+=curs_overlay.3 copywin.3 curs_overlay.3 overlay.3 \
+ curs_overlay.3 overwrite.3
+MLINKS+=curs_pad.3 newpad.3 curs_pad.3 pechochar.3 curs_pad.3 pnoutrefresh.3 \
+ curs_pad.3 prefresh.3 curs_pad.3 subpad.3
+MLINKS+=curs_print.3 mcprint.3
+MLINKS+=curs_printw.3 mvprintw.3 curs_printw.3 mvwprintw.3 \
+ curs_printw.3 printw.3 curs_printw.3 vw_printw.3 \
+ curs_printw.3 vwprintw.3 curs_printw.3 wprintw.3
+MLINKS+=curs_refresh.3 doupdate.3 curs_refresh.3 redrawwin.3 \
+ curs_refresh.3 refresh.3 curs_refresh.3 wnoutrefresh.3 \
+ curs_refresh.3 wredrawln.3 curs_refresh.3 wrefresh.3
+MLINKS+=curs_scanw.3 mvscanw.3 curs_scanw.3 mvwscanw.3 curs_scanw.3 scanw.3 \
+ curs_scanw.3 vw_scanw.3 curs_scanw.3 vwscanw.3 curs_scanw.3 wscanw.3
+MLINKS+=curs_scr_dump.3 scr_dump.3 curs_scr_dump.3 scr_init.3 \
+ curs_scr_dump.3 scr_restore.3 curs_scr_dump.3 scr_set.3
+MLINKS+=curs_scroll.3 scrl.3 curs_scroll.3 scroll.3 curs_scroll.3 wscrl.3
+MLINKS+=curs_slk.3 slk_attr.3 curs_slk.3 slk_attr_off.3 \
+ curs_slk.3 slk_attr_on.3 curs_slk.3 slk_attr_set.3 \
+ curs_slk.3 slk_attroff.3 curs_slk.3 slk_attron.3 \
+ curs_slk.3 slk_attrset.3 curs_slk.3 slk_clear.3 \
+ curs_slk.3 slk_color.3 curs_slk.3 slk_init.3 curs_slk.3 slk_label.3 \
+ curs_slk.3 slk_noutrefresh.3 curs_slk.3 slk_refresh.3 \
+ curs_slk.3 slk_restore.3 curs_slk.3 slk_set.3 curs_slk.3 slk_touch.3
+MLINKS+=curs_termattrs.3 baudrate.3 curs_termattrs.3 erasechar.3 \
+ curs_termattrs.3 has_ic.3 curs_termattrs.3 has_il.3 \
+ curs_termattrs.3 killchar.3 curs_termattrs.3 longname.3 \
+ curs_termattrs.3 termattrs.3 curs_termattrs.3 termname.3
+MLINKS+=curs_termcap.3 tgetent.3 curs_termcap.3 tgetflag.3 \
+ curs_termcap.3 tgetnum.3 curs_termcap.3 tgetstr.3 \
+ curs_termcap.3 tgoto.3 curs_termcap.3 tputs.3
+MLINKS+=curs_terminfo.3 del_curterm.3 curs_terminfo.3 mvcur.3 \
+ curs_terminfo.3 putp.3 curs_terminfo.3 restartterm.3 \
+ curs_terminfo.3 set_curterm.3 curs_terminfo.3 setterm.3 \
+ curs_terminfo.3 setupterm.3 curs_terminfo.3 tigetflag.3 \
+ curs_terminfo.3 tigetnum.3 curs_terminfo.3 tigetstr.3 \
+ curs_terminfo.3 tparm.3 curs_terminfo.3 tputs.3 \
+ curs_terminfo.3 vidattr.3 curs_terminfo.3 vidputs.3
+MLINKS+=curs_touch.3 is_linetouched.3 curs_touch.3 is_wintouched.3 \
+ curs_touch.3 touchline.3 curs_touch.3 touchwin.3 \
+ curs_touch.3 untouchwin.3 curs_touch.3 wtouchln.3
+MLINKS+=curs_util.3 delay_output.3 curs_util.3 filter.3 \
+ curs_util.3 flushinp.3 curs_util.3 getwin.3 \
+ curs_util.3 keyname.3 curs_util.3 putwin.3 \
+ curs_util.3 unctrl.3 curs_util.3 use_env.3
+MLINKS+=curs_window.3 delwin.3 curs_window.3 derwin.3 curs_window.3 dupwin.3 \
+ curs_window.3 mvderwin.3 curs_window.3 mvwin.3 curs_window.3 newwin.3 \
+ curs_window.3 subwin.3 curs_window.3 syncok.3 \
+ curs_window.3 wcursyncup.3 curs_window.3 wsyncdown.3 \
+ curs_window.3 wsyncup.3
+MLINKS+=dft_fgbg.3 use_default_colors.3
+
+.include <bsd.lib.mk>
+
+.SUFFIXES: .3x .3
diff --git a/lib/libncurses/ncurses_cfg.h b/lib/libncurses/ncurses_cfg.h
new file mode 100644
index 0000000..a14d5ba
--- /dev/null
+++ b/lib/libncurses/ncurses_cfg.h
@@ -0,0 +1,129 @@
+/* include/ncurses_cfg.h. Generated automatically by configure. */
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+ * copy of this software and associated documentation files (the *
+ * "Software"), to deal in the Software without restriction, including *
+ * without limitation the rights to use, copy, modify, merge, publish, *
+ * distribute, distribute with modifications, sublicense, and/or sell *
+ * copies of the Software, and to permit persons to whom the Software is *
+ * furnished to do so, subject to the following conditions: *
+ * *
+ * The above copyright notice and this permission notice shall be included *
+ * in all copies or substantial portions of the Software. *
+ * *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Thomas E. Dickey <dickey@clark.net> 1997 *
+ ****************************************************************************/
+/*
+ * Id: ncurses_cfg.hin,v 1.2 1998/02/11 12:13:46 tom Exp
+ *
+ * This is a template-file used to generate the "ncurses_cfg.h" file.
+ *
+ * Rather than list every definition, the configuration script substitutes
+ * the definitions that it finds using 'sed'. You need a patch (971222)
+ * to autoconf 2.12 to do this.
+ */
+#ifndef NC_CONFIG_H
+#define NC_CONFIG_H
+
+#define BSD_TPUTS 1
+#define CC_HAS_INLINE_FUNCS 1
+#define CC_HAS_PROTOS 1
+#define ETIP_NEEDS_ 1
+#define GCC_NORETURN __dead2
+#define GCC_PRINTF 1
+#define GCC_SCANF 1
+#define GCC_UNUSED __unused
+#define HAVE_BIG_CORE 1
+#define HAVE_BSD_CGETENT 1
+#define HAVE_DIRENT_H 1
+#define HAVE_ERRNO 1
+#define HAVE_FCNTL_H 1
+#define HAVE_FORM_H 1
+#define HAVE_GETCWD 1
+#define HAVE_GETTIMEOFDAY 1
+#define HAVE_GETTTYNAM 1
+#define HAVE_ISASCII 1
+#define HAVE_LIBFORM 1
+#define HAVE_LIBMENU 1
+#define HAVE_LIBPANEL 1
+#define HAVE_LIMITS_H 1
+#define HAVE_LINK 1
+#define HAVE_LOCALE_H 1
+#define HAVE_LONG_FILE_NAMES 1
+#define HAVE_MEMCCPY 1
+#define HAVE_MENU_H 1
+#define HAVE_NANOSLEEP 1
+#define HAVE_NC_ALLOC_H 1
+#define HAVE_PANEL_H 1
+#define HAVE_POLL 1
+#define HAVE_POLL_H 1
+#define HAVE_REGEX_H_FUNCS 1
+#define HAVE_REMOVE 1
+#define HAVE_SELECT 1
+#define HAVE_SETBUF 1
+#define HAVE_SETBUFFER 1
+#define HAVE_SETVBUF 1
+#define HAVE_SIGACTION 1
+#define HAVE_SIGVEC 1
+#define HAVE_SIZECHANGE 1
+#define HAVE_STRDUP 1
+#define HAVE_STRSTR 1
+#define HAVE_SYMLINK 1
+#define HAVE_SYS_IOCTL_H 1
+#define HAVE_SYS_PARAM_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_SYS_TIMES_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_TIME_SELECT 1
+#define HAVE_TCGETATTR 1
+#define HAVE_TCGETPGRP 1
+#define HAVE_TERMIOS_H 1
+#define HAVE_TIMES 1
+#define HAVE_TTYENT_H 1
+#define HAVE_TYPEINFO 1
+#define HAVE_UNISTD_H 1
+#define HAVE_USLEEP 1
+#define HAVE_VSNPRINTF 1
+#define HAVE_VSSCANF 1
+#define NCURSES_EXT_FUNCS 1
+#define NCURSES_NO_PADDING 1
+#define NDEBUG 1
+#define RETSIGTYPE void
+#define STDC_HEADERS 1
+#define SYSTEM_NAME "FreeBSD"
+#define TERMINFO_DIRS "/usr/share/misc/terminfo"
+#define TYPEOF_CHTYPE long
+#define USE_DATABASE 1
+#define USE_GETCAP 1
+#define USE_HASHMAP 1
+#define USE_SIGWINCH 1
+
+ /* The C compiler may not treat these properly but C++ has to */
+#ifdef __cplusplus
+#undef const
+#undef inline
+#else
+#if defined(lint) || defined(TRACE)
+#undef inline
+#define inline /* nothing */
+#endif
+#endif
+
+#endif /* NC_CONFIG_H */
diff --git a/lib/libncurses/pathnames.h b/lib/libncurses/pathnames.h
new file mode 100644
index 0000000..5cac36f
--- /dev/null
+++ b/lib/libncurses/pathnames.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 6/4/93
+ * $FreeBSD$
+ */
+
+#define _PATH_DEF ".termcap /usr/share/misc/termcap"
+#define _PATH_DEF_SEC "/usr/share/misc/termcap"
diff --git a/lib/libncurses/termcap.c b/lib/libncurses/termcap.c
new file mode 100644
index 0000000..9469bea
--- /dev/null
+++ b/lib/libncurses/termcap.c
@@ -0,0 +1,265 @@
+/* A portion of this file is from ncurses: */
+/***************************************************************************
+* COPYRIGHT NOTICE *
+****************************************************************************
+* ncurses is copyright (C) 1992-1995 *
+* Zeyd M. Ben-Halim *
+* zmbenhal@netcom.com *
+* Eric S. Raymond *
+* esr@snark.thyrsus.com *
+* *
+* Permission is hereby granted to reproduce and distribute ncurses *
+* by any means and for any fee, whether alone or as part of a *
+* larger distribution, in source or in binary form, PROVIDED *
+* this notice is included with any such distribution, and is not *
+* removed from any of its header files. Mention of ncurses in any *
+* applications linked with it is highly appreciated. *
+* *
+* ncurses comes AS IS with no warranty, implied or expressed. *
+* *
+***************************************************************************/
+
+#include <curses.priv.h>
+
+#include <string.h>
+#include <term.h>
+#include <tic.h>
+#include <term_entry.h>
+
+/* The rest is from BSD */
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char sccsid[] = "@(#)termcap.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include "pathnames.h"
+
+#define PBUFSIZ MAXPATHLEN /* max length of filename path */
+#define PVECSIZ 32 /* max number of names in path */
+#define TBUFSIZ 1024 /* max length of _nc_tgetent buffer */
+
+char _nc_termcap[TBUFSIZ + 1]; /* Last getcap, provided to tgetent() emul */
+
+/*
+ * termcap - routines for dealing with the terminal capability data base
+ *
+ * BUG: Should use a "last" pointer in tbuf, so that searching
+ * for capabilities alphabetically would not be a n**2/2
+ * process when large numbers of capabilities are given.
+ * Note: If we add a last pointer now we will screw up the
+ * tc capability. We really should compile termcap.
+ *
+ * Essentially all the work here is scanning and decoding escapes
+ * in string capabilities. We don't use stdio because the editor
+ * doesn't, and because living w/o it is not hard.
+ */
+
+/*
+ * Get an entry for terminal name in buffer _nc_termcap from the termcap
+ * file.
+ */
+int
+_nc_read_termcap_entry(const char *const name, TERMTYPE *const tp)
+{
+ ENTRY *ep;
+ register char *p;
+ register char *cp;
+ char *dummy;
+ char **fname;
+ char *home;
+ int i;
+ char pathbuf[PBUFSIZ]; /* holds raw path of filenames */
+ char *pathvec[PVECSIZ]; /* to point to names in pathbuf */
+ char **pvec; /* holds usable tail of path vector */
+ char *termpath;
+
+ _nc_termcap[0] = '\0'; /* in case */
+ dummy = NULL;
+ fname = pathvec;
+ pvec = pathvec;
+ p = pathbuf;
+ cp = getenv("TERMCAP");
+ /*
+ * TERMCAP can have one of two things in it. It can be the
+ * name of a file to use instead of /etc/termcap. In this
+ * case it better start with a "/". Or it can be an entry to
+ * use so we don't have to read the file. In this case it
+ * has to already have the newlines crunched out. If TERMCAP
+ * does not hold a file name then a path of names is searched
+ * instead. The path is found in the TERMPATH variable, or
+ * becomes "$HOME/.termcap /etc/termcap" if no TERMPATH exists.
+ */
+ if (!cp || *cp != '/') { /* no TERMCAP or it holds an entry */
+ if ( (termpath = getenv("TERMPATH")) )
+ strncpy(pathbuf, termpath, PBUFSIZ);
+ else {
+ if ( (home = getenv("HOME")) ) {/* set up default */
+ strncpy(pathbuf, home, PBUFSIZ - 1); /* $HOME first */
+ pathbuf[PBUFSIZ - 2] = '\0'; /* -2 because we add a slash */
+ p += strlen(pathbuf); /* path, looking in */
+ *p++ = '/';
+ } /* if no $HOME look in current directory */
+ strncpy(p, _PATH_DEF, PBUFSIZ - (p - pathbuf));
+ }
+ }
+ else /* user-defined name in TERMCAP */
+ strncpy(pathbuf, cp, PBUFSIZ); /* still can be tokenized */
+
+ /* For safety */
+ if (issetugid())
+ strcpy(pathbuf, _PATH_DEF_SEC);
+
+ pathbuf[PBUFSIZ - 1] = '\0';
+
+ *fname++ = pathbuf; /* tokenize path into vector of names */
+ while (*++p)
+ if (*p == ' ' || *p == ':') {
+ *p = '\0';
+ while (*++p)
+ if (*p != ' ' && *p != ':')
+ break;
+ if (*p == '\0')
+ break;
+ *fname++ = p;
+ if (fname >= pathvec + PVECSIZ) {
+ fname--;
+ break;
+ }
+ }
+ *fname = (char *) 0; /* mark end of vector */
+ if (cp && *cp && *cp != '/')
+ if (cgetset(cp) < 0)
+ return(-2);
+
+ i = cgetent(&dummy, pathvec, (char *)name);
+
+ if (i == 0) {
+ char *pd, *ps, *tok, *s, *tcs;
+ size_t len;
+
+ pd = _nc_termcap;
+ ps = dummy;
+ if ((tok = strchr(ps, ':')) == NULL) {
+ len = strlen(ps);
+ if (len >= TBUFSIZ)
+ i = -1;
+ else
+ strcpy(pd, ps);
+ goto done;
+ }
+ len = tok - ps + 1;
+ if (pd + len + 1 - _nc_termcap >= TBUFSIZ) {
+ i = -1;
+ goto done;
+ }
+ memcpy(pd, ps, len);
+ ps += len;
+ pd += len;
+ *pd = '\0';
+ tcs = pd - 1;
+ for (;;) {
+ while ((tok = strsep(&ps, ":")) != NULL &&
+ (*tok == '\0' || *tok == '\\' || !isgraph(*tok)))
+ ;
+ if (tok == NULL)
+ break;
+ for (s = tcs; s != NULL && s[1] != '\0';
+ s = strchr(s, ':')) {
+ s++;
+ if (s[0] == tok[0] && s[1] == tok[1])
+ goto skip_it;
+ }
+ len = strlen(tok);
+ if (pd + len + 1 - _nc_termcap >= TBUFSIZ) {
+ i = -1;
+ break;
+ }
+ memcpy(pd, tok, len);
+ pd += len;
+ *pd++ = ':';
+ *pd = '\0';
+ skip_it: ;
+ }
+ }
+done:
+ if (dummy)
+ free(dummy);
+
+
+/*
+ * From here on is ncurses-specific glue code
+ */
+
+ if (i < 0)
+ return(ERR);
+
+ _nc_set_source("TERMCAP");
+ _nc_read_entry_source((FILE *)NULL, _nc_termcap, FALSE, TRUE, NULLHOOK);
+
+ if (_nc_head == (ENTRY *)NULL)
+ return(ERR);
+
+ /* resolve all use references */
+ _nc_resolve_uses();
+
+ for_entry_list(ep)
+ if (_nc_name_match(ep->tterm.term_names, name, "|:"))
+ {
+ /*
+ * Make a local copy of the terminal capabilities. free
+ * all entry storage except the string table for the
+ * loaded type (which we disconnected from the list by
+ * NULLing out ep->tterm.str_table above).
+ */
+ memcpy(tp, &ep->tterm, sizeof(TERMTYPE));
+ ep->tterm.str_table = (char *)NULL;
+ _nc_free_entries(_nc_head);
+ _nc_head = _nc_tail = NULL; /* do not reuse! */
+
+ return 1; /* OK */
+ }
+
+ _nc_free_entries(_nc_head);
+ _nc_head = _nc_tail = NULL; /* do not reuse! */
+ return(0); /* not found */
+}
diff --git a/lib/libnetgraph/Makefile b/lib/libnetgraph/Makefile
new file mode 100644
index 0000000..342b2e5
--- /dev/null
+++ b/lib/libnetgraph/Makefile
@@ -0,0 +1,18 @@
+# $FreeBSD$
+# $Whistle: Makefile,v 1.4 1999/01/17 03:41:02 julian Exp $
+
+LIB= netgraph
+MAN3= netgraph.3
+
+SHLIB_MAJOR= 1
+#SHLIB_MINOR= 1
+
+SRCS= sock.c msg.c debug.c
+
+CFLAGS+= -g -Wall
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/netgraph.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libnetgraph/debug.c b/lib/libnetgraph/debug.c
new file mode 100644
index 0000000..b5bb56a
--- /dev/null
+++ b/lib/libnetgraph/debug.c
@@ -0,0 +1,301 @@
+
+/*
+ * debug.c
+ *
+ * Copyright (c) 1996-1999 Whistle Communications, Inc.
+ * All rights reserved.
+ *
+ * Subject to the following obligations and disclaimer of warranty, use and
+ * redistribution of this software, in source or object code forms, with or
+ * without modifications are expressly permitted by Whistle Communications;
+ * provided, however, that:
+ * 1. Any and all reproductions of the source or object code must include the
+ * copyright notice above and the following disclaimer of warranties; and
+ * 2. No rights are granted, in any manner or form, to use Whistle
+ * Communications, Inc. trademarks, including the mark "WHISTLE
+ * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
+ * such appears in the above copyright notice or in the software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
+ * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
+ * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
+ * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
+ * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
+ * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
+ * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
+ * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Archie Cobbs <archie@whistle.com>
+ *
+ * $FreeBSD$
+ * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+#include <stdarg.h>
+
+#include <netinet/in.h>
+#include <net/ethernet.h>
+#include <net/bpf.h>
+
+#include <netgraph/ng_message.h>
+#include <netgraph/ng_socket.h>
+
+#include "netgraph.h"
+#include "internal.h"
+
+#include <netgraph/ng_UI.h>
+#include <netgraph/ng_async.h>
+#include <netgraph/ng_bpf.h>
+#include <netgraph/ng_cisco.h>
+#include <netgraph/ng_echo.h>
+#include <netgraph/ng_ether.h>
+#include <netgraph/ng_frame_relay.h>
+#include <netgraph/ng_hole.h>
+#include <netgraph/ng_iface.h>
+#include <netgraph/ng_ksocket.h>
+#include <netgraph/ng_lmi.h>
+#include <netgraph/ng_ppp.h>
+#include <netgraph/ng_pppoe.h>
+#include <netgraph/ng_rfc1490.h>
+#include <netgraph/ng_socket.h>
+#include <netgraph/ng_tee.h>
+#include <netgraph/ng_tty.h>
+#include <netgraph/ng_vjc.h>
+#ifdef WHISTLE
+#include <machine/../isa/df_def.h>
+#include <machine/../isa/if_wfra.h>
+#include <machine/../isa/ipac.h>
+#include <netgraph/ng_df.h>
+#include <netgraph/ng_ipac.h>
+#include <netgraph/ng_mppc.h>
+#include <netgraph/ng_pptpgre.h>
+#include <netgraph/ng_tn.h>
+#endif
+
+/* Global debug level */
+int _gNgDebugLevel = 0;
+
+/* Debug printing functions */
+void (*_NgLog) (const char *fmt,...) = warn;
+void (*_NgLogx) (const char *fmt,...) = warnx;
+
+/* Internal functions */
+static const char *NgCookie(int cookie);
+
+/* Known typecookie list */
+struct ng_cookie {
+ int cookie;
+ const char *type;
+};
+
+#define COOKIE(c) { NGM_ ## c ## _COOKIE, #c }
+
+/* List of known cookies */
+static const struct ng_cookie cookies[] = {
+ COOKIE(UI),
+ COOKIE(ASYNC),
+ COOKIE(BPF),
+ COOKIE(CISCO),
+ COOKIE(ECHO),
+ COOKIE(ETHER),
+ COOKIE(FRAMERELAY),
+ COOKIE(GENERIC),
+ COOKIE(HOLE),
+ COOKIE(IFACE),
+ COOKIE(KSOCKET),
+ COOKIE(LMI),
+ COOKIE(PPP),
+ COOKIE(PPPOE),
+ COOKIE(RFC1490),
+ COOKIE(SOCKET),
+ COOKIE(TEE),
+ COOKIE(TTY),
+ COOKIE(VJC),
+#ifdef WHISTLE
+ COOKIE(DF),
+ COOKIE(IPAC),
+ COOKIE(MPPC),
+ COOKIE(PPTPGRE),
+ COOKIE(TN),
+ COOKIE(WFRA),
+#endif
+ { 0, NULL }
+};
+
+/*
+ * Set debug level, ie, verbosity, if "level" is non-negative.
+ * Returns old debug level.
+ */
+int
+NgSetDebug(int level)
+{
+ int old = _gNgDebugLevel;
+
+ if (level < 0)
+ level = old;
+ _gNgDebugLevel = level;
+ return (old);
+}
+
+/*
+ * Set debug logging functions.
+ */
+void
+NgSetErrLog(void (*log) (const char *fmt,...),
+ void (*logx) (const char *fmt,...))
+{
+ _NgLog = log;
+ _NgLogx = logx;
+}
+
+/*
+ * Display a netgraph sockaddr
+ */
+void
+_NgDebugSockaddr(const struct sockaddr_ng *sg)
+{
+ NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
+ sg->sg_family, sg->sg_len, sg->sg_data);
+}
+
+#define ARGS_BUFSIZE 1024
+
+/*
+ * Display a negraph message
+ */
+void
+_NgDebugMsg(const struct ng_mesg *msg, const char *path)
+{
+ u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
+ struct ng_mesg *const req = (struct ng_mesg *)buf;
+ struct ng_mesg *const bin = (struct ng_mesg *)req->data;
+ int arglen, debugSave, csock = -1;
+
+ /* Lower debugging to avoid infinite recursion */
+ debugSave = _gNgDebugLevel;
+ _gNgDebugLevel -= 4;
+
+ /* Display header stuff */
+ NGLOGX("NG_MESG :");
+ NGLOGX(" vers %d", msg->header.version);
+ NGLOGX(" arglen %d", msg->header.arglen);
+ NGLOGX(" flags %ld", msg->header.flags);
+ NGLOGX(" token %lu", (u_long)msg->header.token);
+ NGLOGX(" cookie %s (%d)",
+ NgCookie(msg->header.typecookie), msg->header.typecookie);
+
+ /* At lower debugging levels, skip ASCII translation */
+ if (_gNgDebugLevel <= 2)
+ goto fail2;
+
+ /* If path is not absolute, don't bother trying to use relative
+ address on a different socket for the ASCII translation */
+ if (strchr(path, ':') == NULL)
+ goto fail2;
+
+ /* Get a temporary socket */
+ if (NgMkSockNode(NULL, &csock, NULL) < 0)
+ goto fail;
+
+ /* Copy binary message into request message payload */
+ arglen = msg->header.arglen;
+ if (arglen > ARGS_BUFSIZE)
+ arglen = ARGS_BUFSIZE;
+ memcpy(bin, msg, sizeof(*msg) + arglen);
+ bin->header.arglen = arglen;
+
+ /* Ask the node to translate the binary message to ASCII for us */
+ if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
+ NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0)
+ goto fail;
+ if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0)
+ goto fail;
+
+ /* Display command string and arguments */
+ NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd);
+ NGLOGX(" args %s", bin->data);
+ goto done;
+
+fail:
+ /* Just display binary version */
+ NGLOGX(" [error decoding message: %s]", strerror(errno));
+fail2:
+ NGLOGX(" cmd %d", msg->header.cmd);
+ NGLOGX(" args (%d bytes)", msg->header.arglen);
+ _NgDebugBytes(msg->data, msg->header.arglen);
+
+done:
+ if (csock != -1)
+ (void)close(csock);
+ _gNgDebugLevel = debugSave;
+}
+
+/*
+ * Return the name of the node type corresponding to the cookie
+ */
+static const char *
+NgCookie(int cookie)
+{
+ int k;
+
+ for (k = 0; cookies[k].cookie != 0; k++) {
+ if (cookies[k].cookie == cookie)
+ return cookies[k].type;
+ }
+ return "??";
+}
+
+/*
+ * Dump bytes in hex
+ */
+void
+_NgDebugBytes(const u_char *ptr, int len)
+{
+ char buf[100];
+ int k, count;
+
+#define BYPERLINE 16
+
+ for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
+
+ /* Do hex */
+ snprintf(buf, sizeof(buf), "%04x: ", count);
+ for (k = 0; k < BYPERLINE; k++, count++)
+ if (count < len)
+ snprintf(buf + strlen(buf),
+ sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
+ else
+ snprintf(buf + strlen(buf),
+ sizeof(buf) - strlen(buf), " ");
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " ");
+ count -= BYPERLINE;
+
+ /* Do ASCII */
+ for (k = 0; k < BYPERLINE; k++, count++)
+ if (count < len)
+ snprintf(buf + strlen(buf),
+ sizeof(buf) - strlen(buf),
+ "%c", isprint(ptr[k]) ? ptr[k] : '.');
+ else
+ snprintf(buf + strlen(buf),
+ sizeof(buf) - strlen(buf), " ");
+ count -= BYPERLINE;
+
+ /* Print it */
+ NGLOGX("%s", buf);
+ }
+}
+
diff --git a/lib/libnetgraph/internal.h b/lib/libnetgraph/internal.h
new file mode 100644
index 0000000..d521cfa
--- /dev/null
+++ b/lib/libnetgraph/internal.h
@@ -0,0 +1,67 @@
+
+/*
+ * internal.h
+ *
+ * Copyright (c) 1996-1999 Whistle Communications, Inc.
+ * All rights reserved.
+ *
+ * Subject to the following obligations and disclaimer of warranty, use and
+ * redistribution of this software, in source or object code forms, with or
+ * without modifications are expressly permitted by Whistle Communications;
+ * provided, however, that:
+ * 1. Any and all reproductions of the source or object code must include the
+ * copyright notice above and the following disclaimer of warranties; and
+ * 2. No rights are granted, in any manner or form, to use Whistle
+ * Communications, Inc. trademarks, including the mark "WHISTLE
+ * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
+ * such appears in the above copyright notice or in the software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
+ * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
+ * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
+ * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
+ * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
+ * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
+ * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
+ * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Archie Cobbs <archie@whistle.com>
+ *
+ * $FreeBSD$
+ * $Whistle: internal.h,v 1.5 1999/01/20 00:57:22 archie Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <ctype.h>
+#include <err.h>
+
+extern int _gNgDebugLevel;
+
+extern void (*_NgLog)(const char *fmt, ...);
+extern void (*_NgLogx)(const char *fmt, ...);
+
+#define NGLOG (*_NgLog)
+#define NGLOGX (*_NgLogx)
+
+extern void _NgDebugSockaddr(const struct sockaddr_ng *sg);
+extern void _NgDebugMsg(const struct ng_mesg *msg, const char *path);
+extern void _NgDebugBytes(const u_char *ptr, int size);
+
diff --git a/lib/libnetgraph/msg.c b/lib/libnetgraph/msg.c
new file mode 100644
index 0000000..ece1787
--- /dev/null
+++ b/lib/libnetgraph/msg.c
@@ -0,0 +1,311 @@
+
+/*
+ * msg.c
+ *
+ * Copyright (c) 1996-1999 Whistle Communications, Inc.
+ * All rights reserved.
+ *
+ * Subject to the following obligations and disclaimer of warranty, use and
+ * redistribution of this software, in source or object code forms, with or
+ * without modifications are expressly permitted by Whistle Communications;
+ * provided, however, that:
+ * 1. Any and all reproductions of the source or object code must include the
+ * copyright notice above and the following disclaimer of warranties; and
+ * 2. No rights are granted, in any manner or form, to use Whistle
+ * Communications, Inc. trademarks, including the mark "WHISTLE
+ * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
+ * such appears in the above copyright notice or in the software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
+ * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
+ * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
+ * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
+ * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
+ * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
+ * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
+ * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Archie Cobbs <archie@whistle.com>
+ *
+ * $FreeBSD$
+ * $Whistle: msg.c,v 1.9 1999/01/20 00:57:23 archie Exp $
+ */
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <netgraph/ng_message.h>
+#include <netgraph/ng_socket.h>
+
+#include "netgraph.h"
+#include "internal.h"
+
+/* Next message token value */
+static int gMsgId;
+
+/* For delivering both messages and replies */
+static int NgDeliverMsg(int cs, const char *path,
+ const struct ng_mesg *hdr, const void *args, size_t arglen);
+
+/*
+ * Send a message to a node using control socket node "cs".
+ * Returns -1 if error and sets errno appropriately.
+ * If successful, returns the message ID (token) used.
+ */
+int
+NgSendMsg(int cs, const char *path,
+ int cookie, int cmd, const void *args, size_t arglen)
+{
+ struct ng_mesg msg;
+
+ /* Prepare message header */
+ memset(&msg, 0, sizeof(msg));
+ msg.header.version = NG_VERSION;
+ msg.header.typecookie = cookie;
+ msg.header.token = ++gMsgId;
+ msg.header.flags = NGF_ORIG;
+ msg.header.cmd = cmd;
+ snprintf(msg.header.cmdstr, NG_CMDSTRLEN + 1, "cmd%d", cmd);
+
+ /* Deliver message */
+ if (NgDeliverMsg(cs, path, &msg, args, arglen) < 0)
+ return (-1);
+ return(gMsgId);
+}
+
+/*
+ * Send a message given in ASCII format. We first ask the node to translate
+ * the command into binary, and then we send the binary.
+ */
+int
+NgSendAsciiMsg(int cs, const char *path, const char *fmt, ...)
+{
+ const int bufSize = 1024;
+ char replybuf[2 * sizeof(struct ng_mesg) + bufSize];
+ struct ng_mesg *const reply = (struct ng_mesg *)replybuf;
+ struct ng_mesg *const binary = (struct ng_mesg *)reply->data;
+ struct ng_mesg *ascii;
+ char *buf, *cmd, *args;
+ va_list fmtargs;
+
+ /* Parse out command and arguments */
+ va_start(fmtargs, fmt);
+ vasprintf(&buf, fmt, fmtargs);
+ va_end(fmtargs);
+ if (buf == NULL)
+ return (-1);
+
+ /* Parse out command, arguments */
+ for (cmd = buf; isspace(*cmd); cmd++)
+ ;
+ for (args = cmd; *args != '\0' && !isspace(*args); args++)
+ ;
+ if (*args != '\0') {
+ while (isspace(*args))
+ *args++ = '\0';
+ }
+
+ /* Get a bigger buffer to hold inner message header plus arg string */
+ if ((ascii = malloc(sizeof(struct ng_mesg)
+ + strlen(buf) + 1)) == NULL) {
+ free(buf);
+ return (-1);
+ }
+ memset(ascii, 0, sizeof(*ascii));
+
+ /* Build inner header (only need cmdstr, arglen, and data fields) */
+ strncpy(ascii->header.cmdstr, cmd, sizeof(ascii->header.cmdstr) - 1);
+ strcpy(ascii->data, args);
+ ascii->header.arglen = strlen(ascii->data) + 1;
+ free(buf);
+
+ /* Send node a request to convert ASCII to binary */
+ if (NgSendMsg(cs, path, NGM_GENERIC_COOKIE, NGM_ASCII2BINARY,
+ (u_char *)ascii, sizeof(*ascii) + ascii->header.arglen) < 0)
+ return (-1);
+
+ /* Get reply */
+ if (NgRecvMsg(cs, reply, sizeof(replybuf), NULL) < 0)
+ return (-1);
+
+ /* Now send binary version */
+ return NgDeliverMsg(cs,
+ path, binary, binary->data, binary->header.arglen);
+}
+
+/*
+ * Send a message that is a reply to a previously received message.
+ * Returns -1 and sets errno on error, otherwise returns zero.
+ */
+int
+NgSendReplyMsg(int cs, const char *path,
+ const struct ng_mesg *msg, const void *args, size_t arglen)
+{
+ struct ng_mesg rep;
+
+ /* Prepare message header */
+ rep = *msg;
+ rep.header.flags = NGF_RESP;
+
+ /* Deliver message */
+ return (NgDeliverMsg(cs, path, &rep, args, arglen));
+}
+
+/*
+ * Send a message to a node using control socket node "cs".
+ * Returns -1 if error and sets errno appropriately, otherwise zero.
+ */
+static int
+NgDeliverMsg(int cs, const char *path,
+ const struct ng_mesg *hdr, const void *args, size_t arglen)
+{
+ u_char sgbuf[NG_PATHLEN + 3];
+ struct sockaddr_ng *const sg = (struct sockaddr_ng *) sgbuf;
+ u_char *buf = NULL;
+ struct ng_mesg *msg;
+ int errnosv = 0;
+ int rtn = 0;
+
+ /* Sanity check */
+ if (args == NULL)
+ arglen = 0;
+
+ /* Get buffer */
+ if ((buf = malloc(sizeof(*msg) + arglen)) == NULL) {
+ errnosv = errno;
+ if (_gNgDebugLevel >= 1)
+ NGLOG("malloc");
+ rtn = -1;
+ goto done;
+ }
+ msg = (struct ng_mesg *) buf;
+
+ /* Finalize message */
+ *msg = *hdr;
+ msg->header.arglen = arglen;
+ memcpy(msg->data, args, arglen);
+
+ /* Prepare socket address */
+ sg->sg_family = AF_NETGRAPH;
+ snprintf(sg->sg_data, NG_PATHLEN + 1, "%s", path);
+ sg->sg_len = strlen(sg->sg_data) + 3;
+
+ /* Debugging */
+ if (_gNgDebugLevel >= 2) {
+ NGLOGX("SENDING %s:",
+ (msg->header.flags & NGF_RESP) ? "RESPONSE" : "MESSAGE");
+ _NgDebugSockaddr(sg);
+ _NgDebugMsg(msg, sg->sg_data);
+ }
+
+ /* Send it */
+ if (sendto(cs, msg, sizeof(*msg) + arglen,
+ 0, (struct sockaddr *) sg, sg->sg_len) < 0) {
+ errnosv = errno;
+ if (_gNgDebugLevel >= 1)
+ NGLOG("sendto(%s)", sg->sg_data);
+ rtn = -1;
+ goto done;
+ }
+
+done:
+ /* Done */
+ free(buf); /* OK if buf is NULL */
+ errno = errnosv;
+ return (rtn);
+}
+
+/*
+ * Receive a control message.
+ *
+ * On error, this returns -1 and sets errno.
+ * Otherwise, it returns the length of the received reply.
+ */
+int
+NgRecvMsg(int cs, struct ng_mesg *rep, size_t replen, char *path)
+{
+ u_char sgbuf[NG_PATHLEN + sizeof(struct sockaddr_ng)];
+ struct sockaddr_ng *const sg = (struct sockaddr_ng *) sgbuf;
+ int len, sglen = sizeof(sgbuf);
+ int errnosv;
+
+ /* Read reply */
+ len = recvfrom(cs, rep, replen, 0, (struct sockaddr *) sg, &sglen);
+ if (len < 0) {
+ errnosv = errno;
+ if (_gNgDebugLevel >= 1)
+ NGLOG("recvfrom");
+ goto errout;
+ }
+ if (path != NULL)
+ snprintf(path, NG_PATHLEN + 1, "%s", sg->sg_data);
+
+ /* Debugging */
+ if (_gNgDebugLevel >= 2) {
+ NGLOGX("RECEIVED %s:",
+ (rep->header.flags & NGF_RESP) ? "RESPONSE" : "MESSAGE");
+ _NgDebugSockaddr(sg);
+ _NgDebugMsg(rep, sg->sg_data);
+ }
+
+ /* Done */
+ return (len);
+
+errout:
+ errno = errnosv;
+ return (-1);
+}
+
+/*
+ * Receive a control message and convert the arguments to ASCII
+ */
+int
+NgRecvAsciiMsg(int cs, struct ng_mesg *reply, size_t replen, char *path)
+{
+ struct ng_mesg *msg, *ascii;
+ int bufSize, errnosv;
+ u_char *buf;
+
+ /* Allocate buffer */
+ bufSize = 2 * sizeof(*reply) + replen;
+ if ((buf = malloc(bufSize)) == NULL)
+ return (-1);
+ msg = (struct ng_mesg *)buf;
+ ascii = (struct ng_mesg *)msg->data;
+
+ /* Get binary message */
+ if (NgRecvMsg(cs, msg, bufSize, path) < 0)
+ goto fail;
+ memcpy(reply, msg, sizeof(*msg));
+
+ /* Ask originating node to convert the arguments to ASCII */
+ if (NgSendMsg(cs, path, NGM_GENERIC_COOKIE,
+ NGM_BINARY2ASCII, msg, sizeof(*msg) + msg->header.arglen) < 0)
+ goto fail;
+ if (NgRecvMsg(cs, msg, bufSize, NULL) < 0)
+ goto fail;
+
+ /* Copy result to client buffer */
+ if (sizeof(*ascii) + ascii->header.arglen > replen) {
+ errno = ERANGE;
+fail:
+ errnosv = errno;
+ free(buf);
+ errno = errnosv;
+ return (-1);
+ }
+ strncpy(reply->data, ascii->data, ascii->header.arglen);
+
+ /* Done */
+ free(buf);
+ return (0);
+}
+
diff --git a/lib/libnetgraph/netgraph.3 b/lib/libnetgraph/netgraph.3
new file mode 100644
index 0000000..6926f96
--- /dev/null
+++ b/lib/libnetgraph/netgraph.3
@@ -0,0 +1,267 @@
+.\" Copyright (c) 1996-1999 Whistle Communications, Inc.
+.\" All rights reserved.
+.\"
+.\" Subject to the following obligations and disclaimer of warranty, use and
+.\" redistribution of this software, in source or object code forms, with or
+.\" without modifications are expressly permitted by Whistle Communications;
+.\" provided, however, that:
+.\" 1. Any and all reproductions of the source or object code must include the
+.\" copyright notice above and the following disclaimer of warranties; and
+.\" 2. No rights are granted, in any manner or form, to use Whistle
+.\" Communications, Inc. trademarks, including the mark "WHISTLE
+.\" COMMUNICATIONS" on advertising, endorsements, or otherwise except as
+.\" such appears in the above copyright notice or in the software.
+.\"
+.\" THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
+.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
+.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
+.\" INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+.\" WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
+.\" REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
+.\" SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
+.\" IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
+.\" RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
+.\" WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+.\" PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
+.\" SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
+.\" OF SUCH DAMAGE.
+.\"
+.\" Author: Archie Cobbs <archie@whistle.com>
+.\"
+.\" $FreeBSD$
+.\" $Whistle: netgraph.3,v 1.7 1999/01/25 07:14:06 archie Exp $
+.\"
+.Dd January 19, 1999
+.Dt NETGRAPH 3
+.Os FreeBSD 3
+.Sh NAME
+.Nm NgMkSockNode ,
+.Nm NgNameNode ,
+.Nm NgSendMsg ,
+.Nm NgRecvMsg ,
+.Nm NgSendData ,
+.Nm NgRecvData ,
+.Nm NgSetDebug ,
+.Nm NgSetErrLog
+.Nd Netgraph user library
+.Sh SYNOPSIS
+.Fd #include <netgraph.h>
+.Ft int
+.Fn NgMkSockNode "const char *name" "int *csp" "int *dsp"
+.Ft int
+.Fn NgNameNode "int cs" "const char *path" "const char *fmt" "..."
+.Ft int
+.Fn NgSendMsg "int cs" "const char *path" "int cookie" "int cmd" "const void *arg" "size_t arglen"
+.Ft int
+.Fn NgSendAsciiMsg "int cs" "const char *path" "const char *fmt" "..."
+.Ft int
+.Fn NgSendMsgReply "int cs" "const char *path" "struct ng_mesg *msg" "const void *arg" "size_t arglen"
+.Ft int
+.Fn NgRecvMsg "int cs" "struct ng_mesg *rep" "size_t replen" "char *path"
+.Ft int
+.Fn NgRecvAsciiMsg "int cs" "struct ng_mesg *rep" "size_t replen" "char *path"
+.Ft int
+.Fn NgSendData "int ds" "const char *hook" "const u_char *buf" "size_t len"
+.Ft int
+.Fn NgRecvData "int ds" "u_char *buf" "size_t len" "char *hook"
+.Ft int
+.Fn NgSetDebug "int level"
+.Ft void
+.Fn NgSetErrLog "void (*log)(const char *fmt, ...)" "void (*logx)(const char *fmt, ...)"
+.Sh DESCRIPTION
+These functions facilitate user-mode program participation in the kernel
+.Xr netgraph 4
+graph-based networking system, by utilizing the netgraph
+.Em socket
+node type (see
+.Xr ng_socket 8 ")."
+.Pp
+.Fn NgMkSockNode
+should be called first, to create a new
+.Em socket
+type netgraph node with associated control and data sockets. If
+.Fa name
+is non-NULL, the node will have that global name assigned to it.
+.Fa "*csp"
+and
+.Fa "*dsp"
+will be set to the newly opened control and data sockets
+associated with the node; either
+.Fa "csp"
+or
+.Fa "dsp"
+may be NULL if only one socket is desired.
+.Pp
+.Fn NgNameNode
+assigns a global name to the node addressed by
+.Fa path .
+.Pp
+.Fn NgSendMsg
+sends a binary control message from the socket node associated
+with control socket
+.Fa cs
+to the node addressed by
+.Fa path .
+The
+.Fa cookie
+indicates how to interpret
+.Fa cmd ,
+which indicates a specific command.
+Extra argument data (if any) is specified by
+.Fa arg
+and
+.Fa arglen .
+The
+.Fa cookie ,
+.Fa cmd ,
+and argument data are defined by the header file corresponding
+to the type of the node being addressed.
+.Pp
+Use
+.Fn NgSendMsgReply
+to send reply to a previously received control message.
+The original message header should be pointed to by
+.Fa msg .
+.Pp
+.Fn NgSendAsciiMsg
+performs the same function as
+.Fn NgSendMsg ,
+but adds support for ASCII encoding of control messages.
+.Fn NgSendAsciiMsg
+formats its input a la
+.Xr printf 3
+and then sends the resulting ASCII string to the node in a
+.Dv NGM_ASCII2BINARY
+control message. The node returns a binary version of the
+message, which is then sent back to the node just as with
+.Fn NgSendMsg .
+Note that ASCII conversion may not be supported by all node types.
+.Pp
+.Fn NgRecvMsg
+reads the next control message received by the node associated with
+control socket
+.Fa cs .
+The message and any extra argument data must fit in
+.Fa replen
+bytes.
+If
+.Fa "path"
+is non-NULL, it must point to a buffer of at least
+.Dv "NG_PATHLEN + 1"
+bytes, which will be filled in (and NUL terminated) with the path to
+the node from which the message was received.
+.Pp
+.Fn NgRecvAsciiMsg
+works exactly like
+.Fn NgRecvMsg ,
+except that after the message is received, any binary arguments
+are converted to ASCII by sending a
+.Dv NGM_BINARY2ASCII
+request back to the originating node. The result is the same as
+.Fn NgRecvAsciiMsg ,
+with the exception that the reply arguments field will contain
+a NUL-terminated ASCII version of the arguments (and the reply
+header argument length field will be adjusted).
+.Pp
+.Fn NgSendData
+writes a data packet out on the specified hook of the node corresponding
+to data socket
+.Fa ds .
+The node must already be connected to some other node via that hook.
+.Pp
+.Fn NgRecvData
+reads the next data packet (of up to
+.Fa len
+bytes) received by the node corresponding to data socket
+.Fa ds
+and stores it in
+.Fa buf ,
+which must be large enough to hold the entire packet. If
+.Fa "hook"
+is non-NULL, it must point to a buffer of at least
+.Dv "NG_HOOKLEN + 1"
+bytes, which will be filled in (and NUL terminated) with the name of
+the hook on which the data was received.
+.Pp
+.Fn NgSetDebug
+and
+.Fn NgSetErrLog
+are used for debugging.
+.Fn NgSetDebug
+sets the debug level (if non-negative), and returns the old setting.
+Higher debug levels result in more verbosity. The default is zero.
+All debug and error messages are logged via the functions
+specified in the most recent call to
+.Fn NgSetErrLog .
+The default logging functions are
+.Xr vwarn 3
+and
+.Xr vwarnx 3 .
+.Pp
+At debug level 3, the library attempts to display control message arguments
+in ASCII format; however, this results in additional messages being
+sent which may interfere with debugging. At even higher levels,
+even these additional messagages will be displayed, etc.
+.Pp
+Note that
+.Xr select 2
+can be used on the data and the control sockets to detect the presence of
+incoming data and control messages, respectively.
+Data and control packets are always written and read atomically, i.e.,
+in one whole piece.
+.Pp
+User mode programs must be linked with the
+.Dv -lnetgraph
+flag to link in this library.
+.Sh INITIALIZATION
+To enable Netgraph in your kernel, either your kernel must be
+compiled with ``options NETGRAPH'' in the kernel configuration
+file, or else the
+.Xr netgraph 4
+and
+.Xr ng_socket 8
+KLD modules must have been loaded via
+.Xr kldload 8 .
+.Sh DIAGNOSTICS
+All functions except
+.Fn NgSetDebug
+and
+.Fn NgSetErrLog
+return -1 if there was an error and set errno accordingly.
+.Pp
+For
+.Fn NgSendAsciiMsg
+and
+.Fn NgRecvAsciiMsg ,
+the following additional errors are possible:
+.Bl -tag -width Er
+.It Bq Er ENOSYS
+The node type does not know how to encode or decode the control message.
+.It Bq Er ERANGE
+The encoded or decoded arguments were too long for the supplied buffer.
+.It Bq Er ENOENT
+An unknown structure field was seen in an ASCII control message.
+.It Bq Er EALREADY
+The same structure field was specified twice in an ASCII control message.
+.It Bq Er EINVAL
+ASCII control message parse error or illegal value.
+.It Bq Er E2BIG
+ASCII control message array or fixed width string buffer overflow.
+.El
+.Sh SEE ALSO
+.Xr netgraph 4 ,
+.Xr socket 2 ,
+.Xr select 2 ,
+.Xr warnx 3 ,
+.Xr ng_socket 8 .
+.Sh HISTORY
+The
+.Em netgraph
+system was designed and first implemented at Whistle Communications, Inc. in
+a version FreeBSD 2.2 customized for the Whistle InterJet.
+.Sh AUTHOR
+.An Archie Cobbs <archie@whistle.com>
diff --git a/lib/libnetgraph/netgraph.h b/lib/libnetgraph/netgraph.h
new file mode 100644
index 0000000..c5a87cb
--- /dev/null
+++ b/lib/libnetgraph/netgraph.h
@@ -0,0 +1,66 @@
+
+/*
+ * netgraph.h
+ *
+ * Copyright (c) 1996-1999 Whistle Communications, Inc.
+ * All rights reserved.
+ *
+ * Subject to the following obligations and disclaimer of warranty, use and
+ * redistribution of this software, in source or object code forms, with or
+ * without modifications are expressly permitted by Whistle Communications;
+ * provided, however, that:
+ * 1. Any and all reproductions of the source or object code must include the
+ * copyright notice above and the following disclaimer of warranties; and
+ * 2. No rights are granted, in any manner or form, to use Whistle
+ * Communications, Inc. trademarks, including the mark "WHISTLE
+ * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
+ * such appears in the above copyright notice or in the software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
+ * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
+ * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
+ * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
+ * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
+ * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
+ * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
+ * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Archie Cobbs <archie@whistle.com>
+ *
+ * $FreeBSD$
+ * $Whistle: netgraph.h,v 1.7 1999/01/20 00:57:23 archie Exp $
+ */
+
+#ifndef _NETGRAPH_H_
+#define _NETGRAPH_H_
+
+#include <sys/types.h>
+#include <netgraph/ng_message.h>
+
+__BEGIN_DECLS
+int NgMkSockNode(const char *, int *, int *);
+int NgNameNode(int, const char *, const char *, ...);
+int NgSendMsg(int, const char *, int, int, const void *, size_t);
+int NgSendAsciiMsg(int, const char *, const char *, ...);
+int NgSendReplyMsg(int, const char *,
+ const struct ng_mesg *, const void *, size_t);
+int NgRecvMsg(int, struct ng_mesg *, size_t, char *);
+int NgRecvAsciiMsg(int, struct ng_mesg *, size_t, char *);
+int NgSendData(int, const char *, const u_char *, size_t);
+int NgRecvData(int, u_char *, size_t, char *);
+int NgSetDebug(int);
+void NgSetErrLog(void (*)(const char *fmt, ...),
+ void (*)(const char *fmt, ...));
+__END_DECLS
+
+#endif
+
diff --git a/lib/libnetgraph/sock.c b/lib/libnetgraph/sock.c
new file mode 100644
index 0000000..b8bb9e6
--- /dev/null
+++ b/lib/libnetgraph/sock.c
@@ -0,0 +1,264 @@
+
+/*
+ * sock.c
+ *
+ * Copyright (c) 1996-1999 Whistle Communications, Inc.
+ * All rights reserved.
+ *
+ * Subject to the following obligations and disclaimer of warranty, use and
+ * redistribution of this software, in source or object code forms, with or
+ * without modifications are expressly permitted by Whistle Communications;
+ * provided, however, that:
+ * 1. Any and all reproductions of the source or object code must include the
+ * copyright notice above and the following disclaimer of warranties; and
+ * 2. No rights are granted, in any manner or form, to use Whistle
+ * Communications, Inc. trademarks, including the mark "WHISTLE
+ * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
+ * such appears in the above copyright notice or in the software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
+ * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
+ * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
+ * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
+ * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
+ * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
+ * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
+ * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Archie Cobbs <archie@whistle.com>
+ *
+ * $FreeBSD$
+ * $Whistle: sock.c,v 1.12 1999/01/20 00:57:23 archie Exp $
+ */
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <netgraph/ng_message.h>
+#include <netgraph/ng_socket.h>
+
+#include "netgraph.h"
+#include "internal.h"
+
+/*
+ * Create a socket type node and give it the supplied name.
+ * Return data and control sockets corresponding to the node.
+ * Returns -1 if error and sets errno.
+ */
+int
+NgMkSockNode(const char *name, int *csp, int *dsp)
+{
+ char namebuf[NG_NODELEN + 1];
+ int cs = -1; /* control socket */
+ int ds = -1; /* data socket */
+ int errnosv;
+
+ /* Empty name means no name */
+ if (name && *name == 0)
+ name = NULL;
+
+ /* Create control socket; this also creates the netgraph node */
+ if ((cs = socket(AF_NETGRAPH, SOCK_DGRAM, NG_CONTROL)) < 0) {
+ errnosv = errno;
+ if (_gNgDebugLevel >= 1)
+ NGLOG("socket");
+ goto errout;
+ }
+
+ /* Assign the node the desired name, if any */
+ if (name != NULL) {
+ u_char sbuf[NG_NODELEN + 3];
+ struct sockaddr_ng *const sg = (struct sockaddr_ng *) sbuf;
+
+ /* Assign name */
+ snprintf(sg->sg_data, NG_NODELEN + 1, "%s", name);
+ sg->sg_family = AF_NETGRAPH;
+ sg->sg_len = strlen(sg->sg_data) + 3;
+ if (bind(cs, (struct sockaddr *) sg, sg->sg_len) < 0) {
+ errnosv = errno;
+ if (_gNgDebugLevel >= 1)
+ NGLOG("bind(%s)", sg->sg_data);
+ goto errout;
+ }
+
+ /* Save node name */
+ snprintf(namebuf, sizeof(namebuf), "%s", name);
+ } else if (dsp != NULL) {
+ u_char rbuf[sizeof(struct ng_mesg) + sizeof(struct nodeinfo)];
+ struct ng_mesg *const resp = (struct ng_mesg *) rbuf;
+ struct nodeinfo *const ni = (struct nodeinfo *) resp->data;
+
+ /* Find out the node ID */
+ if (NgSendMsg(cs, ".", NGM_GENERIC_COOKIE,
+ NGM_NODEINFO, NULL, 0) < 0) {
+ errnosv = errno;
+ if (_gNgDebugLevel >= 1)
+ NGLOG("send nodeinfo");
+ goto errout;
+ }
+ if (NgRecvMsg(cs, resp, sizeof(rbuf), NULL) < 0) {
+ errnosv = errno;
+ if (_gNgDebugLevel >= 1)
+ NGLOG("recv nodeinfo");
+ goto errout;
+ }
+
+ /* Save node "name" */
+ snprintf(namebuf, sizeof(namebuf), "[%lx]", (u_long) ni->id);
+ }
+
+ /* Create data socket if desired */
+ if (dsp != NULL) {
+ u_char sbuf[NG_NODELEN + 4];
+ struct sockaddr_ng *const sg = (struct sockaddr_ng *) sbuf;
+
+ /* Create data socket, initially just "floating" */
+ if ((ds = socket(AF_NETGRAPH, SOCK_DGRAM, NG_DATA)) < 0) {
+ errnosv = errno;
+ if (_gNgDebugLevel >= 1)
+ NGLOG("socket");
+ goto errout;
+ }
+
+ /* Associate the data socket with the node */
+ snprintf(sg->sg_data, NG_NODELEN + 2, "%s:", namebuf);
+ sg->sg_family = AF_NETGRAPH;
+ sg->sg_len = strlen(sg->sg_data) + 3;
+ if (connect(ds, (struct sockaddr *) sg, sg->sg_len) < 0) {
+ errnosv = errno;
+ if (_gNgDebugLevel >= 1)
+ NGLOG("connect(%s)", sg->sg_data);
+ goto errout;
+ }
+ }
+
+ /* Return the socket(s) */
+ if (csp)
+ *csp = cs;
+ else
+ close(cs);
+ if (dsp)
+ *dsp = ds;
+ return (0);
+
+errout:
+ /* Failed */
+ if (cs >= 0)
+ close(cs);
+ if (ds >= 0)
+ close(ds);
+ errno = errnosv;
+ return (-1);
+}
+
+/*
+ * Assign a globally unique name to a node
+ * Returns -1 if error and sets errno.
+ */
+int
+NgNameNode(int cs, const char *path, const char *fmt, ...)
+{
+ struct ngm_name ngn;
+ va_list args;
+
+ /* Build message arg */
+ va_start(args, fmt);
+ vsnprintf(ngn.name, sizeof(ngn.name), fmt, args);
+ va_end(args);
+
+ /* Send message */
+ if (NgSendMsg(cs, path,
+ NGM_GENERIC_COOKIE, NGM_NAME, &ngn, sizeof(ngn)) < 0) {
+ if (_gNgDebugLevel >= 1)
+ NGLOGX("%s: failed", __FUNCTION__);
+ return (-1);
+ }
+
+ /* Done */
+ return (0);
+}
+
+/*
+ * Read a packet from a data socket
+ * Returns -1 if error and sets errno.
+ */
+int
+NgRecvData(int ds, u_char * buf, size_t len, char *hook)
+{
+ u_char frombuf[NG_HOOKLEN + sizeof(struct sockaddr_ng)];
+ struct sockaddr_ng *const from = (struct sockaddr_ng *) frombuf;
+ int fromlen = sizeof(frombuf);
+ int rtn, errnosv;
+
+ /* Read packet */
+ rtn = recvfrom(ds, buf, len, 0, (struct sockaddr *) from, &fromlen);
+ if (rtn < 0) {
+ errnosv = errno;
+ if (_gNgDebugLevel >= 1)
+ NGLOG("recvfrom");
+ errno = errnosv;
+ return (-1);
+ }
+
+ /* Copy hook name */
+ if (hook != NULL)
+ snprintf(hook, NG_HOOKLEN + 1, "%s", from->sg_data);
+
+ /* Debugging */
+ if (_gNgDebugLevel >= 2) {
+ NGLOGX("READ %s from hook \"%s\" (%d bytes)",
+ rtn ? "PACKET" : "EOF", from->sg_data, rtn);
+ if (_gNgDebugLevel >= 3)
+ _NgDebugBytes(buf, rtn);
+ }
+
+ /* Done */
+ return (rtn);
+}
+
+/*
+ * Write a packet to a data socket. The packet will be sent
+ * out the corresponding node on the specified hook.
+ * Returns -1 if error and sets errno.
+ */
+int
+NgSendData(int ds, const char *hook, const u_char * buf, size_t len)
+{
+ u_char sgbuf[NG_HOOKLEN + sizeof(struct sockaddr_ng)];
+ struct sockaddr_ng *const sg = (struct sockaddr_ng *) sgbuf;
+ int errnosv;
+
+ /* Set up destination hook */
+ sg->sg_family = AF_NETGRAPH;
+ snprintf(sg->sg_data, NG_HOOKLEN + 1, "%s", hook);
+ sg->sg_len = strlen(sg->sg_data) + 3;
+
+ /* Debugging */
+ if (_gNgDebugLevel >= 2) {
+ NGLOGX("WRITE PACKET to hook \"%s\" (%d bytes)", hook, len);
+ _NgDebugSockaddr(sg);
+ if (_gNgDebugLevel >= 3)
+ _NgDebugBytes(buf, len);
+ }
+
+ /* Send packet */
+ if (sendto(ds, buf, len, 0, (struct sockaddr *) sg, sg->sg_len) < 0) {
+ errnosv = errno;
+ if (_gNgDebugLevel >= 1)
+ NGLOG("sendto(%s)", sg->sg_data);
+ errno = errnosv;
+ return (-1);
+ }
+
+ /* Done */
+ return (0);
+}
+
diff --git a/lib/libopie/Makefile b/lib/libopie/Makefile
new file mode 100644
index 0000000..22b01eb
--- /dev/null
+++ b/lib/libopie/Makefile
@@ -0,0 +1,35 @@
+# Makefile for libopie
+#
+# $FreeBSD$
+#
+OPIE_DIST?= ${.CURDIR}/../../contrib/opie
+DIST_DIR= ${OPIE_DIST}/${.CURDIR:T}
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 1
+
+KEYFILE?= \"/etc/opiekeys\"
+
+.PATH: ${DIST_DIR} ${OPIE_DIST}/libmissing
+
+LIB= opie
+SRCS= atob8.c btoa8.c btoh.c challenge.c getsequence.c hash.c hashlen.c \
+ keycrunch.c lock.c lookup.c newseed.c parsechallenge.c passcheck.c \
+ passwd.c randomchallenge.c readpass.c unlock.c verify.c version.c \
+ btoe.c accessfile.c generator.c insecure.c getutmpentry.c \
+ readrec.c writerec.c login.c open.c logwtmp.c \
+ getutline.c pututline.c endutent.c setutent.c # from libmissing
+
+CFLAGS+=-I${.CURDIR} -I${OPIE_DIST} -I${DIST_DIR} \
+ -DKEY_FILE=${KEYFILE}
+
+LDADD+= -lmd
+DPADD+= ${LIBMD}
+
+MAN4= ${OPIE_DIST}/opie.4
+MAN5= ${OPIE_DIST}/opiekeys.5 ${OPIE_DIST}/opieaccess.5
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${OPIE_DIST}/opie.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libopie/config.h b/lib/libopie/config.h
new file mode 100644
index 0000000..bf91b2e
--- /dev/null
+++ b/lib/libopie/config.h
@@ -0,0 +1,379 @@
+/* config.h. Generated automatically by configure. */
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if on AIX 3.
+ System headers sometimes define this.
+ We just want to avoid a redefinition error message. */
+#ifndef _ALL_SOURCE
+/* #undef _ALL_SOURCE */
+#endif
+
+/* Define if using alloca.c. */
+/* #undef C_ALLOCA */
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define if you have alloca, as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define if on MINIX. */
+/* #undef _MINIX */
+
+/* Define if the system does not provide POSIX.1 features except
+ with this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define if you need to in order for stat and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Define as the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if you want the FTP daemon to support anonymous logins. */
+/* #undef DOANONYMOUS */
+
+/* The default value of the PATH environment variable */
+#define DEFAULT_PATH "/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin"
+
+/* Defined if the file /etc/default/login exists
+ (and, presumably, should be looked at by login) */
+/* #undef HAVE_ETC_DEFAULT_LOGIN */
+
+/* Defined to the name of a file that contains a list of files whose
+ permissions and ownerships should be changed on login. */
+/* #undef HAVE_LOGIN_PERMFILE */
+
+/* Defined to the name of a file that contains a list of environment
+ values that should be set on login. */
+/* #undef HAVE_LOGIN_ENVFILE */
+
+/* Defined if the file /etc/securetty exists
+ (and, presumably, should be looked at by login) */
+/* #undef HAVE_SECURETTY */
+
+/* Defined if the file /etc/shadow exists
+ (and, presumably, should be looked at for shadow passwords) */
+/* #undef HAVE_ETC_SHADOW */
+
+/* The path to the access file, if we're going to use it */
+/* #undef PATH_ACCESS_FILE */
+
+/* The path to the mail spool, if we know it */
+#define PATH_MAIL "/var/mail"
+
+/* The path to the utmp file, if we know it */
+#define PATH_UTMP_AC "/var/run/utmp"
+
+/* The path to the wtmp file, if we know it */
+#define PATH_WTMP_AC "/var/log/wtmp"
+
+/* The path to the wtmpx file, if we know it */
+/* #undef PATH_WTMPX_AC */
+
+/* Defined if the system's profile (/etc/profile) displays
+ the motd file */
+/* #undef HAVE_MOTD_IN_PROFILE */
+
+/* Defined if the system's profile (/etc/profile) informs the
+ user of new mail */
+/* #undef HAVE_MAILCHECK_IN_PROFILE */
+
+/* Define if you have a nonstandard gettimeofday() that takes one argument
+ instead of two. */
+/* #undef HAVE_ONE_ARG_GETTIMEOFDAY */
+
+/* Define if the system has the getenv function */
+#define HAVE_GETENV 1
+
+/* Define if the system has the setenv function */
+#define HAVE_SETENV 1
+
+/* Define if the system has the /var/adm/sulog file */
+/* #undef HAVE_SULOG */
+
+/* Define if the system has the unsetenv function */
+#define HAVE_UNSETENV 1
+
+/* Define if the compiler can handle ANSI-style argument lists */
+#define HAVE_ANSIDECL 1
+
+/* Define if the compiler can handle ANSI-style prototypes */
+#define HAVE_ANSIPROTO 1
+
+/* Define if the system has an ANSI-style printf (returns int instead of char *) */
+#define HAVE_ANSISPRINTF 1
+
+/* Define if the compiler can handle ANSI-style variable argument lists */
+#define HAVE_ANSISTDARG 1
+
+/* Define if the compiler can handle void argument lists to functions */
+#define HAVE_VOIDARG 1
+
+/* Define if the compiler can handle void return "values" from functions */
+#define HAVE_VOIDRET 1
+
+/* Define if the compiler can handle void pointers to our liking */
+#define HAVE_VOIDPTR 1
+
+/* Define if the /bin/ls command seems to support the -g flag */
+/* #undef HAVE_LS_G_FLAG */
+
+/* Define if there is a ut_pid field in struct utmp */
+/* #undef HAVE_UT_PID */
+
+/* Define if there is a ut_type field in struct utmp */
+/* #undef HAVE_UT_TYPE */
+
+/* Define if there is a ut_name field in struct utmp */
+#define HAVE_UT_NAME 1
+
+/* Define if there is a ut_host field in struct utmp */
+#define HAVE_UT_HOST 1
+
+/* Define if the system has getutline() */
+/* #undef HAVE_GETUTLINE */
+
+/* Defined if the system has SunOS C2 security shadow passwords */
+/* #undef HAVE_SUNOS_C2_SHADOW */
+
+/* Defined if you want to disable utmp support */
+/* #undef DISABLE_UTMP */
+
+/* Defined if you want to allow users to override the insecure checks */
+/* #undef INSECURE_OVERRIDE */
+
+/* Defined to the default hash value, always defined */
+#define MDX 5
+
+/* Defined if new-style prompts are to be used */
+#define NEW_PROMPTS 1
+
+/* Defined to the path of the OPIE lock directory */
+#define OPIE_LOCK_DIR "/var/spool/opielocks"
+
+/* Defined if users are to be asked to re-type secret pass phrases */
+/* #undef RETYPE */
+
+/* Defined if su should not switch to disabled accounts */
+/* #undef SU_STAR_CHECK */
+
+/* Defined if user locking is to be used */
+#define USER_LOCKING 1
+
+/* Define if you have the bcopy function. */
+/* #undef HAVE_BCOPY */
+
+/* Define if you have the bzero function. */
+/* #undef HAVE_BZERO */
+
+/* Define if you have the endspent function. */
+/* #undef HAVE_ENDSPENT */
+
+/* Define if you have the fpurge function. */
+#define HAVE_FPURGE 1
+
+/* Define if you have the getdtablesize function. */
+/* #undef HAVE_GETDTABLESIZE */
+
+/* Define if you have the getgroups function. */
+#define HAVE_GETGROUPS 1
+
+/* Define if you have the gethostname function. */
+/* #undef HAVE_GETHOSTNAME */
+
+/* Define if you have the getspnam function. */
+/* #undef HAVE_GETSPNAM */
+
+/* Define if you have the gettimeofday function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define if you have the getttynam function. */
+#define HAVE_GETTTYNAM 1
+
+/* Define if you have the getusershell function. */
+#define HAVE_GETUSERSHELL 1
+
+/* Define if you have the getutxline function. */
+/* #undef HAVE_GETUTXLINE */
+
+/* Define if you have the getwd function. */
+/* #undef HAVE_GETWD */
+
+/* Define if you have the index function. */
+/* #undef HAVE_INDEX */
+
+/* Define if you have the lstat function. */
+#define HAVE_LSTAT 1
+
+/* Define if you have the on_exit function. */
+/* #undef HAVE_ON_EXIT */
+
+/* Define if you have the pututxline function. */
+/* #undef HAVE_PUTUTXLINE */
+
+/* Define if you have the rindex function. */
+/* #undef HAVE_RINDEX */
+
+/* Define if you have the setgroups function. */
+#define HAVE_SETGROUPS 1
+
+/* Define if you have the setlogin function. */
+#define HAVE_SETLOGIN 1
+
+/* Define if you have the setpriority function. */
+#define HAVE_SETPRIORITY 1
+
+/* Define if you have the setregid function. */
+/* #undef HAVE_SETREGID */
+
+/* Define if you have the setresgid function. */
+/* #undef HAVE_SETRESGID */
+
+/* Define if you have the setresuid function. */
+/* #undef HAVE_SETRESUID */
+
+/* Define if you have the setreuid function. */
+/* #undef HAVE_SETREUID */
+
+/* Define if you have the setvbuf function. */
+#define HAVE_SETVBUF 1
+
+/* Define if you have the sigaddset function. */
+#define HAVE_SIGADDSET 1
+
+/* Define if you have the sigblock function. */
+/* #undef HAVE_SIGBLOCK */
+
+/* Define if you have the sigemptyset function. */
+#define HAVE_SIGEMPTYSET 1
+
+/* Define if you have the sigsetmask function. */
+/* #undef HAVE_SIGSETMASK */
+
+/* Define if you have the socket function. */
+#define HAVE_SOCKET 1
+
+/* Define if you have the strerror function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strftime function. */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the strncasecmp function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define if you have the strstr function. */
+#define HAVE_STRSTR 1
+
+/* Define if you have the ttyslot function. */
+#define HAVE_TTYSLOT 1
+
+/* Define if you have the usleep function. */
+#define HAVE_USLEEP 1
+
+/* Define if you have the <crypt.h> header file. */
+/* #undef HAVE_CRYPT_H */
+
+/* Define if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <lastlog.h> header file. */
+/* #undef HAVE_LASTLOG_H */
+
+/* Define if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <ndir.h> header file. */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <paths.h> header file. */
+#define HAVE_PATHS_H 1
+
+/* Define if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* Define if you have the <shadow.h> header file. */
+/* #undef HAVE_SHADOW_H */
+
+/* Define if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/dir.h> header file. */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/file.h> header file. */
+#define HAVE_SYS_FILE_H 1
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define if you have the <sys/ndir.h> header file. */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define if you have the <sys/signal.h> header file. */
+#define HAVE_SYS_SIGNAL_H 1
+
+/* Define if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define if you have the <sys/utsname.h> header file. */
+#define HAVE_SYS_UTSNAME_H 1
+
+/* Define if you have the <syslog.h> header file. */
+#define HAVE_SYSLOG_H 1
+
+/* Define if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <utmpx.h> header file. */
+/* #undef HAVE_UTMPX_H */
+
+/* Define if you have the crypt library (-lcrypt). */
+#define HAVE_LIBCRYPT 1
+
+/* Define if you have the nsl library (-lnsl). */
+/* #undef HAVE_LIBNSL */
+
+/* Define if you have the posix library (-lposix). */
+/* #undef HAVE_LIBPOSIX */
+
+/* Define if you have the socket library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
diff --git a/lib/libpam/Makefile b/lib/libpam/Makefile
new file mode 100644
index 0000000..8e99888
--- /dev/null
+++ b/lib/libpam/Makefile
@@ -0,0 +1,31 @@
+# Copyright 1998 Juniper Networks, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+# The modules must be built first, because they are built into the
+# static version of libpam.
+SUBDIR+= modules libpam
+
+.include <bsd.subdir.mk>
diff --git a/lib/libpam/Makefile.inc b/lib/libpam/Makefile.inc
new file mode 100644
index 0000000..2558a61
--- /dev/null
+++ b/lib/libpam/Makefile.inc
@@ -0,0 +1,28 @@
+# Copyright 1998 Juniper Networks, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+SHLIB_MAJOR= 1
+SHLIB_MINOR= 0
diff --git a/lib/libpam/libpam/Makefile b/lib/libpam/libpam/Makefile
new file mode 100644
index 0000000..f8143a5
--- /dev/null
+++ b/lib/libpam/libpam/Makefile
@@ -0,0 +1,123 @@
+# Copyright 1998 Juniper Networks, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+PAMDIR= ${.CURDIR}/../../../contrib/libpam
+MODOBJDIR= ../modules
+
+.PATH: ${PAMDIR}/libpam ${PAMDIR}/libpam_misc ${PAMDIR}/doc/man
+
+LIB= pam
+CFLAGS+= -I${PAMDIR}/libpam/include -I.
+CFLAGS+= -DDEFAULT_MODULE_PATH=\"${SHLIBDIR}/\"
+NOPROFILE= yes
+CLEANFILES+= security
+
+# Files from ${PAMDIR}/libpam:
+SRCS= pam_account.c pam_auth.c pam_data.c pam_delay.c \
+ pam_dispatch.c pam_end.c pam_env.c pam_handlers.c \
+ pam_item.c pam_log.c pam_misc.c pam_password.c \
+ pam_second.c pam_session.c pam_start.c \
+ pam_strerror.c
+HDRS1= _pam_compat.h _pam_macros.h _pam_types.h \
+ pam_appl.h pam_malloc.h pam_modules.h
+MAN3+= pam_authenticate.3 pam_chauthtok.3 pam_fail_delay.3 \
+ pam_open_session.3 pam_setcred.3 pam_start.3 \
+ pam_strerror.3
+MLINKS+= pam_open_session.3 pam_close_session.3 \
+ pam_start.3 pam_end.3
+MAN8+= pam.8
+MLINKS+= pam.8 pam.conf.5 pam.8 pam.d.5
+
+# Files from ${PAMDIR}/libpam_misc:
+SRCS+= help_env.c misc_conv.c xstrdup.c
+HDRS2= pam_misc.h
+
+# Files from ${.CURDIR}:
+SRCS+= pam_get_pass.c pam_prompt.c pam_std_option.c
+HDRS3= pam_mod_misc.h
+
+# Static PAM modules:
+STATIC_MODULES+= ${MODOBJDIR}/pam_cleartext_pass_ok/libpam_cleartext_pass_ok.a
+STATIC_MODULES+= ${MODOBJDIR}/pam_deny/libpam_deny.a
+.if defined(MAKE_KERBEROS4) && !defined(NOCRYPT)
+STATIC_MODULES+= ${MODOBJDIR}/pam_kerberosIV/libpam_kerberosIV.a
+.endif
+.if defined(MAKE_KERBEROS5) && !defined(NOCRYPT)
+STATIC_MODULES+= ${MODOBJDIR}/pam_kerberos5/libpam_kerberos5.a
+.endif
+STATIC_MODULES+= ${MODOBJDIR}/pam_permit/libpam_permit.a
+STATIC_MODULES+= ${MODOBJDIR}/pam_radius/libpam_radius.a
+STATIC_MODULES+= ${MODOBJDIR}/pam_skey/libpam_skey.a
+STATIC_MODULES+= ${MODOBJDIR}/pam_tacplus/libpam_tacplus.a
+STATIC_MODULES+= ${MODOBJDIR}/pam_unix/libpam_unix.a
+
+STATICOBJS+= pam_static_modules.o
+CLEANFILES+= pam_static.o
+
+_EXTRADEPEND: pam_static.c
+ ${MKDEPCMD} -f ${DEPENDFILE} -a ${MKDEP} \
+ ${CFLAGS:M-nostdinc*} ${CFLAGS:M-[BID]*} \
+ ${.ALLSRC}
+
+.if ${OBJFORMAT} == elf
+CLEANFILES+= setdef0.o _pam_static_modules.o setdef1.o \
+ setdef0.c setdef1.c setdefs.h
+
+pam_static_modules.o: setdef0.o pam_static.o _pam_static_modules.o setdef1.o
+ ${LD} -o ${.TARGET} -r ${.ALLSRC}
+
+setdef0.o: setdef0.c setdefs.h
+setdef1.o: setdef1.c setdefs.h
+
+setdef0.c setdef1.c setdefs.h: _pam_static_modules.o
+ gensetdefs ${.ALLSRC}
+
+_pam_static_modules.o: ${STATIC_MODULES}
+ ${LD} -o ${.TARGET} -r --whole-archive ${.ALLSRC}
+.else
+pam_static_modules.o: pam_static.o ${STATIC_MODULES}
+ ${LD} -o ${.TARGET} -r -Bforcearchive ${.ALLSRC}
+.endif
+
+all: security
+
+beforedepend: security
+
+beforeinstall:
+ cd ${PAMDIR}/libpam/include/security; \
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${HDRS1} ${DESTDIR}/usr/include/security
+ cd ${PAMDIR}/libpam_misc; \
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${HDRS2} ${DESTDIR}/usr/include/security
+ cd ${.CURDIR}; \
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${HDRS3} ${DESTDIR}/usr/include/security
+
+security:
+ ln -sf ${PAMDIR}/libpam_misc security
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/libpam/pam_get_pass.c b/lib/libpam/libpam/pam_get_pass.c
new file mode 100644
index 0000000..78ef75a
--- /dev/null
+++ b/lib/libpam/libpam/pam_get_pass.c
@@ -0,0 +1,93 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <security/pam_modules.h>
+#include "pam_mod_misc.h"
+
+static int pam_conv_pass(pam_handle_t *, const char *, int);
+
+static int
+pam_conv_pass(pam_handle_t *pamh, const char *prompt, int options)
+{
+ int retval;
+ const void *item;
+ const struct pam_conv *conv;
+ struct pam_message msg;
+ const struct pam_message *msgs[1];
+ struct pam_response *resp;
+
+ if ((retval = pam_get_item(pamh, PAM_CONV, &item)) !=
+ PAM_SUCCESS)
+ return retval;
+ conv = (const struct pam_conv *)item;
+ msg.msg_style = options & PAM_OPT_ECHO_PASS ?
+ PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF;
+ msg.msg = prompt;
+ msgs[0] = &msg;
+ if ((retval = conv->conv(1, msgs, &resp, conv->appdata_ptr)) !=
+ PAM_SUCCESS)
+ return retval;
+ if ((retval = pam_set_item(pamh, PAM_AUTHTOK, resp[0].resp)) !=
+ PAM_SUCCESS)
+ return retval;
+ memset(resp[0].resp, 0, strlen(resp[0].resp));
+ free(resp[0].resp);
+ free(resp);
+ return PAM_SUCCESS;
+}
+
+int
+pam_get_pass(pam_handle_t *pamh, const char **passp, const char *prompt,
+ int options)
+{
+ int retval;
+ const void *item = NULL;
+
+ /*
+ * Grab the already-entered password if we might want to use it.
+ */
+ if (options & (PAM_OPT_TRY_FIRST_PASS | PAM_OPT_USE_FIRST_PASS)) {
+ if ((retval = pam_get_item(pamh, PAM_AUTHTOK, &item)) !=
+ PAM_SUCCESS)
+ return retval;
+ }
+
+ if (item == NULL) {
+ /* The user hasn't entered a password yet. */
+ if (options & PAM_OPT_USE_FIRST_PASS)
+ return PAM_AUTH_ERR;
+ /* Use the conversation function to get a password. */
+ if ((retval = pam_conv_pass(pamh, prompt, options)) !=
+ PAM_SUCCESS ||
+ (retval = pam_get_item(pamh, PAM_AUTHTOK, &item)) !=
+ PAM_SUCCESS)
+ return retval;
+ }
+ *passp = (const char *)item;
+ return PAM_SUCCESS;
+}
diff --git a/lib/libpam/libpam/pam_mod_misc.h b/lib/libpam/libpam/pam_mod_misc.h
new file mode 100644
index 0000000..06f474d
--- /dev/null
+++ b/lib/libpam/libpam/pam_mod_misc.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef PAM_MOD_MISC_H
+#define PAM_MOD_MISC_H
+
+#include <sys/cdefs.h>
+
+/* Options */
+#define PAM_OPT_DEBUG 0x01
+#define PAM_OPT_NO_WARN 0x02
+#define PAM_OPT_USE_FIRST_PASS 0x04
+#define PAM_OPT_TRY_FIRST_PASS 0x08
+#define PAM_OPT_USE_MAPPED_PASS 0x10
+#define PAM_OPT_ECHO_PASS 0x20
+
+__BEGIN_DECLS
+int pam_get_pass(pam_handle_t *, const char **, const char *, int);
+int pam_prompt(pam_handle_t *, int, const char *, char **);
+int pam_std_option(int *, const char *);
+__END_DECLS
+
+#endif
diff --git a/lib/libpam/libpam/pam_prompt.c b/lib/libpam/libpam/pam_prompt.c
new file mode 100644
index 0000000..220616e
--- /dev/null
+++ b/lib/libpam/libpam/pam_prompt.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <security/pam_modules.h>
+#include "pam_mod_misc.h"
+
+/*
+ * Do a simple conversation which can consist of a message and/or a user
+ * response.
+ */
+int
+pam_prompt(pam_handle_t *pamh, int style, const char *prompt, char **user_msg)
+{
+ int retval;
+ const void *item;
+ const struct pam_conv *conv;
+ struct pam_message msg;
+ const struct pam_message *msgs[1];
+ struct pam_response *resp;
+
+ if ((retval = pam_get_item(pamh, PAM_CONV, &item)) !=
+ PAM_SUCCESS)
+ return retval;
+ conv = (const struct pam_conv *)item;
+ msg.msg_style = style;
+ msg.msg = prompt != NULL ? prompt : "";
+ msgs[0] = &msg;
+ if ((retval = conv->conv(1, msgs, &resp, conv->appdata_ptr)) !=
+ PAM_SUCCESS)
+ return retval;
+ if (user_msg != NULL)
+ *user_msg = resp[0].resp;
+ else if (resp[0].resp != NULL)
+ free(resp[0].resp);
+ free(resp);
+ return PAM_SUCCESS;
+}
diff --git a/lib/libpam/libpam/pam_std_option.c b/lib/libpam/libpam/pam_std_option.c
new file mode 100644
index 0000000..0c00908
--- /dev/null
+++ b/lib/libpam/libpam/pam_std_option.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <security/pam_modules.h>
+#include <string.h>
+#include "pam_mod_misc.h"
+
+/*
+ * If the given name is a standard option, set the corresponding flag in
+ * the options word and return 0. Else return -1.
+ */
+int
+pam_std_option(int *options, const char *name)
+{
+ struct opttab {
+ const char *name;
+ int value;
+ };
+ static struct opttab std_options[] = {
+ { "debug", PAM_OPT_DEBUG },
+ { "no_warn", PAM_OPT_NO_WARN },
+ { "use_first_pass", PAM_OPT_USE_FIRST_PASS },
+ { "try_first_pass", PAM_OPT_TRY_FIRST_PASS },
+ { "use_mapped_pass", PAM_OPT_USE_MAPPED_PASS },
+ { "echo_pass", PAM_OPT_ECHO_PASS },
+ { NULL, 0 }
+ };
+ struct opttab *p;
+
+ for (p = std_options; p->name != NULL; p++) {
+ if (strcmp(name, p->name) == 0) {
+ *options |= p->value;
+ return 0;
+ }
+ }
+ return -1;
+}
diff --git a/lib/libpam/libpam/security/pam_mod_misc.h b/lib/libpam/libpam/security/pam_mod_misc.h
new file mode 100644
index 0000000..06f474d
--- /dev/null
+++ b/lib/libpam/libpam/security/pam_mod_misc.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef PAM_MOD_MISC_H
+#define PAM_MOD_MISC_H
+
+#include <sys/cdefs.h>
+
+/* Options */
+#define PAM_OPT_DEBUG 0x01
+#define PAM_OPT_NO_WARN 0x02
+#define PAM_OPT_USE_FIRST_PASS 0x04
+#define PAM_OPT_TRY_FIRST_PASS 0x08
+#define PAM_OPT_USE_MAPPED_PASS 0x10
+#define PAM_OPT_ECHO_PASS 0x20
+
+__BEGIN_DECLS
+int pam_get_pass(pam_handle_t *, const char **, const char *, int);
+int pam_prompt(pam_handle_t *, int, const char *, char **);
+int pam_std_option(int *, const char *);
+__END_DECLS
+
+#endif
diff --git a/lib/libpam/modules/Makefile b/lib/libpam/modules/Makefile
new file mode 100644
index 0000000..8018dbd
--- /dev/null
+++ b/lib/libpam/modules/Makefile
@@ -0,0 +1,38 @@
+# Copyright 1998 Juniper Networks, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+SUBDIR+= pam_cleartext_pass_ok
+SUBDIR+= pam_deny
+.if defined(MAKE_KERBEROS4) && !defined(NOCRYPT)
+SUBDIR+= pam_kerberosIV
+.endif
+SUBDIR+= pam_permit
+SUBDIR+= pam_radius
+SUBDIR+= pam_skey
+SUBDIR+= pam_tacplus
+SUBDIR+= pam_unix
+
+.include <bsd.subdir.mk>
diff --git a/lib/libpam/modules/pam_cleartext_pass_ok/Makefile b/lib/libpam/modules/pam_cleartext_pass_ok/Makefile
new file mode 100644
index 0000000..2336ea3
--- /dev/null
+++ b/lib/libpam/modules/pam_cleartext_pass_ok/Makefile
@@ -0,0 +1,39 @@
+# Copyright 1998 Juniper Networks, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+PAMDIR= ${.CURDIR}/../../../../contrib/libpam
+
+LIB= pam_cleartext_pass_ok
+SHLIB_NAME= pam_cleartext_pass_ok.so
+SRCS= pam_cleartext_pass_ok.c
+CFLAGS+= -I${PAMDIR}/libpam/include
+CFLAGS+= -Wall
+DPADD+= ${LIBSKEY}
+LDADD+= -lskey -lgcc_pic
+INTERNALLIB= yes
+INTERNALSTATICLIB=yes
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_cleartext_pass_ok/pam_cleartext_pass_ok.c b/lib/libpam/modules/pam_cleartext_pass_ok/pam_cleartext_pass_ok.c
new file mode 100644
index 0000000..437225c
--- /dev/null
+++ b/lib/libpam/modules/pam_cleartext_pass_ok/pam_cleartext_pass_ok.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <skey.h>
+
+#define PAM_SM_AUTH
+#include <security/pam_modules.h>
+
+PAM_EXTERN int
+pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ int retval;
+ const void *item;
+ const char *user;
+ const char *tty;
+ const char *rhost;
+
+ if ((retval = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
+ return retval;
+ if ((retval = pam_get_item(pamh, PAM_TTY, &item)) != PAM_SUCCESS)
+ return retval;
+ tty = (const char *)item;
+ if ((retval = pam_get_item(pamh, PAM_RHOST, &item)) != PAM_SUCCESS)
+ return retval;
+ rhost = (const char *)item;
+ /*
+ * The cast in the next statement is necessary only because the
+ * declaration of skeyaccess is wrong.
+ */
+ return skeyaccess((char *)user, tty, rhost, NULL) ?
+ PAM_SUCCESS : PAM_AUTH_ERR;
+}
+
+PAM_EXTERN int
+pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+PAM_MODULE_ENTRY("pam_cleartext_pass_ok");
diff --git a/lib/libpam/modules/pam_deny/Makefile b/lib/libpam/modules/pam_deny/Makefile
new file mode 100644
index 0000000..17b1447
--- /dev/null
+++ b/lib/libpam/modules/pam_deny/Makefile
@@ -0,0 +1,41 @@
+# Copyright 1999 Max Khon.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+PAMDIR= ${.CURDIR}/../../../../contrib/libpam
+
+.PATH: ${PAMDIR}/modules/pam_deny
+
+LIB= pam_deny
+SHLIB_NAME= pam_deny.so
+SRCS= pam_deny.c
+CFLAGS+= -Wall
+CFLAGS+= -I${PAMDIR}/libpam/include
+DPADD+= ${LIBGCC_PIC}
+LDADD+= -lgcc_pic
+INTERNALLIB= yes
+INTERNALSTATICLIB=yes
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_kerberosIV/Makefile b/lib/libpam/modules/pam_kerberosIV/Makefile
new file mode 100644
index 0000000..ee4e6a6
--- /dev/null
+++ b/lib/libpam/modules/pam_kerberosIV/Makefile
@@ -0,0 +1,47 @@
+# Copyright 1998 Juniper Networks, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+PAMDIR= ${.CURDIR}/../../../../contrib/libpam
+
+LIB= pam_kerberosIV
+SHLIB_NAME= pam_kerberosIV.so
+SRCS= pam_kerberosIV.c klogin.c
+CFLAGS+= -Wall
+CFLAGS+= -I${PAMDIR}/libpam/include
+CFLAGS+= -I${.CURDIR}/../../libpam
+CFLAGS+= -DKERBEROS
+DPADD+= ${LIBKRB}
+LDADD+= -lkrb
+.if !defined(NOSECURE)
+DPADD+= ${LIBDES}
+LDADD+= -ldes
+.endif
+DPADD+= ${LIBGCC_PIC} ${LIBCOM_ERR}
+LDADD+= -lgcc_pic -lcom_err
+INTERNALLIB= yes
+INTERNALSTATICLIB=yes
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_kerberosIV/klogin.c b/lib/libpam/modules/pam_kerberosIV/klogin.c
new file mode 100644
index 0000000..7c61b84
--- /dev/null
+++ b/lib/libpam/modules/pam_kerberosIV/klogin.c
@@ -0,0 +1,204 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char sccsid[] = "@(#)klogin.c 8.3 (Berkeley) 4/2/94";
+#endif /* not lint */
+
+#ifdef KERBEROS
+#include <sys/param.h>
+#include <sys/syslog.h>
+#include <des.h>
+#include <krb.h>
+
+#include <err.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define INITIAL_TICKET "krbtgt"
+#define VERIFY_SERVICE "rcmd"
+
+extern int notickets;
+extern char *krbtkfile_env;
+
+/*
+ * Attempt to log the user in using Kerberos authentication
+ *
+ * return 0 on success (will be logged in)
+ * 1 if Kerberos failed (try local password in login)
+ */
+int
+klogin(pw, instance, localhost, password)
+ struct passwd *pw;
+ char *instance, *localhost, *password;
+{
+ int kerror;
+ char realm[REALM_SZ], savehost[MAXHOSTNAMELEN];
+ char tkt_location[MAXPATHLEN];
+ char *krb_get_phost();
+ extern int noticketsdontcomplain;
+
+#ifdef KLOGIN_PARANOID
+ AUTH_DAT authdata;
+ KTEXT_ST ticket;
+ struct hostent *hp;
+ unsigned long faddr;
+
+ noticketsdontcomplain = 0; /* enable warning message */
+#endif
+
+ /*
+ * Root logins don't use Kerberos.
+ * If we have a realm, try getting a ticket-granting ticket
+ * and using it to authenticate. Otherwise, return
+ * failure so that we can try the normal passwd file
+ * for a password. If that's ok, log the user in
+ * without issuing any tickets.
+ */
+ if (strcmp(pw->pw_name, "root") == 0 ||
+ krb_get_lrealm(realm, 0) != KSUCCESS)
+ return (1);
+
+ noticketsdontcomplain = 0; /* enable warning message */
+
+ /*
+ * get TGT for local realm
+ * tickets are stored in a file named TKT_ROOT plus uid
+ * except for user.root tickets.
+ */
+
+ if (strcmp(instance, "root") != 0)
+ (void)sprintf(tkt_location, "%s%d", TKT_ROOT, pw->pw_uid);
+ else {
+ (void)sprintf(tkt_location, "%s_root_%d", TKT_ROOT, pw->pw_uid);
+ krbtkfile_env = tkt_location;
+ }
+ (void)krb_set_tkt_string(tkt_location);
+
+ /*
+ * Set real as well as effective ID to 0 for the moment,
+ * to make the kerberos library do the right thing.
+ */
+ if (setuid(0) < 0) {
+ warnx("setuid");
+ return (1);
+ }
+ kerror = krb_get_pw_in_tkt(pw->pw_name, instance,
+ realm, INITIAL_TICKET, realm, DEFAULT_TKT_LIFE, password);
+
+ /*
+ * If we got a TGT, get a local "rcmd" ticket and check it so as to
+ * ensure that we are not talking to a bogus Kerberos server.
+ *
+ * There are 2 cases where we still allow a login:
+ * 1: the VERIFY_SERVICE doesn't exist in the KDC
+ * 2: local host has no srvtab, as (hopefully) indicated by a
+ * return value of RD_AP_UNDEC from krb_rd_req().
+ */
+ if (kerror != INTK_OK) {
+ if (kerror != INTK_BADPW && kerror != KDC_PR_UNKNOWN) {
+ syslog(LOG_ERR, "Kerberos intkt error: %s",
+ krb_err_txt[kerror]);
+ dest_tkt();
+ }
+ return (1);
+ }
+
+ if (chown(TKT_FILE, pw->pw_uid, pw->pw_gid) < 0)
+ syslog(LOG_ERR, "chown tkfile (%s): %m", TKT_FILE);
+
+ (void)strncpy(savehost, krb_get_phost(localhost), sizeof(savehost));
+ savehost[sizeof(savehost)-1] = NULL;
+
+#ifdef KLOGIN_PARANOID
+ /*
+ * if the "VERIFY_SERVICE" doesn't exist in the KDC for this host,
+ * still allow login with tickets, but log the error condition.
+ */
+
+ kerror = krb_mk_req(&ticket, VERIFY_SERVICE, savehost, realm, 33);
+ if (kerror == KDC_PR_UNKNOWN) {
+ syslog(LOG_NOTICE,
+ "warning: TGT not verified (%s); %s.%s not registered, or srvtab is wrong?",
+ krb_err_txt[kerror], VERIFY_SERVICE, savehost);
+ notickets = 0;
+ return (0);
+ }
+
+ if (kerror != KSUCCESS) {
+ warnx("unable to use TGT: (%s)", krb_err_txt[kerror]);
+ syslog(LOG_NOTICE, "unable to use TGT: (%s)",
+ krb_err_txt[kerror]);
+ dest_tkt();
+ return (1);
+ }
+
+ if (!(hp = gethostbyname(localhost))) {
+ syslog(LOG_ERR, "couldn't get local host address");
+ dest_tkt();
+ return (1);
+ }
+
+ memmove((void *)&faddr, (void *)hp->h_addr, sizeof(faddr));
+
+ kerror = krb_rd_req(&ticket, VERIFY_SERVICE, savehost, faddr,
+ &authdata, "");
+
+ if (kerror == KSUCCESS) {
+ notickets = 0;
+ return (0);
+ }
+
+ /* undecipherable: probably didn't have a srvtab on the local host */
+ if (kerror == RD_AP_UNDEC) {
+ syslog(LOG_NOTICE, "krb_rd_req: (%s)\n", krb_err_txt[kerror]);
+ dest_tkt();
+ return (1);
+ }
+ /* failed for some other reason */
+ warnx("unable to verify %s ticket: (%s)", VERIFY_SERVICE,
+ krb_err_txt[kerror]);
+ syslog(LOG_NOTICE, "couldn't verify %s ticket: %s", VERIFY_SERVICE,
+ krb_err_txt[kerror]);
+ dest_tkt();
+ return (1);
+#else
+ notickets = 0;
+ return (0);
+#endif
+}
+#endif
diff --git a/lib/libpam/modules/pam_kerberosIV/pam_kerberosIV.c b/lib/libpam/modules/pam_kerberosIV/pam_kerberosIV.c
new file mode 100644
index 0000000..403f8d6
--- /dev/null
+++ b/lib/libpam/modules/pam_kerberosIV/pam_kerberosIV.c
@@ -0,0 +1,108 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define PAM_SM_AUTH
+#include <security/pam_modules.h>
+
+#include "pam_mod_misc.h"
+
+#define PASSWORD_PROMPT "Password:"
+
+extern int klogin(struct passwd *, char *, char *, char *);
+
+/* Globals used by klogin.c */
+int notickets = 1;
+int noticketsdontcomplain = 1;
+char *krbtkfile_env;
+
+PAM_EXTERN int
+pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ int retval;
+ const char *user;
+ char *principal;
+ char *instance;
+ const char *password;
+ char localhost[MAXHOSTNAMELEN + 1];
+ struct passwd *pwd;
+ int options;
+ int i;
+
+ options = 0;
+ for (i = 0; i < argc; i++)
+ pam_std_option(&options, argv[i]);
+ if ((retval = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
+ return retval;
+ if ((retval = pam_get_pass(pamh, &password, PASSWORD_PROMPT,
+ options)) != PAM_SUCCESS)
+ return retval;
+ if (gethostname(localhost, sizeof localhost - 1) == -1)
+ return PAM_SYSTEM_ERR;
+ if ((principal = strdup(user)) == NULL)
+ return PAM_BUF_ERR;
+ if ((instance = strchr(principal, '.')) != NULL)
+ *instance++ = '\0';
+ else
+ instance = "";
+ if ((pwd = getpwnam(user)) != NULL &&
+ klogin(pwd, instance, localhost, (char *)password) == 0) {
+ if (!(flags & PAM_SILENT) && notickets &&
+ !noticketsdontcomplain)
+ pam_prompt(pamh, PAM_ERROR_MSG,
+ "Warning: no Kerberos tickets issued", NULL);
+ /*
+ * XXX - I think the ticket file really isn't supposed to
+ * be even created until pam_sm_setcred() is called.
+ */
+ if (krbtkfile_env != NULL)
+ setenv("KRBTKFILE", krbtkfile_env, 1);
+ retval = PAM_SUCCESS;
+ } else
+ retval = PAM_AUTH_ERR;
+ /*
+ * The PAM infrastructure will obliterate the cleartext
+ * password before returning to the application.
+ */
+ free(principal);
+ return retval;
+}
+
+PAM_EXTERN int
+pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+PAM_MODULE_ENTRY("pam_kerberosIV");
diff --git a/lib/libpam/modules/pam_login_access/login.access.5 b/lib/libpam/modules/pam_login_access/login.access.5
new file mode 100644
index 0000000..10788ed
--- /dev/null
+++ b/lib/libpam/modules/pam_login_access/login.access.5
@@ -0,0 +1,54 @@
+.\"
+.\" $FreeBSD$
+.\"
+.\" this is comment
+.Dd April 30, 1994
+.Dt LOGIN.ACCESS 5
+.Os FreeBSD 1.2
+.Sh NAME
+.Nm login.access
+.Nd login access control table
+.Sh DESCRIPTION
+The
+.Nm
+file specifies (user, host) combinations and/or (user, tty)
+combinations for which a login will be either accepted or refused.
+.Pp
+When someone logs in, the
+.Nm
+is scanned for the first entry that
+matches the (user, host) combination, or, in case of non-networked
+logins, the first entry that matches the (user, tty) combination. The
+permissions field of that table entry determines whether the login will
+be accepted or refused.
+.Pp
+Each line of the login access control table has three fields separated by a
+":" character: permission : users : origins
+.Pp
+The first field should be a "+" (access granted) or "-" (access denied)
+character. The second field should be a list of one or more login names,
+group names, or ALL (always matches). The third field should be a list
+of one or more tty names (for non-networked logins), host names, domain
+names (begin with "."), host addresses, internet network numbers (end
+with "."), ALL (always matches) or LOCAL (matches any string that does
+not contain a "." character). If you run NIS you can use @netgroupname
+in host or user patterns.
+.Pp
+The EXCEPT operator makes it possible to write very compact rules.
+.Pp
+The group file is searched only when a name does not match that of the
+logged-in user. Only groups are matched in which users are explicitly
+listed: the program does not look at a user's primary group id value.
+.Sh FILES
+.Bl -tag -width /etc/login.access -compact
+.It Pa /etc/login.access
+The
+.Nm
+file resides in
+.Pa /etc .
+.El
+.Sh SEE ALSO
+.Xr login 1 ,
+.Xr pam 8
+.Sh AUTHORS
+.An Guido van Rooij
diff --git a/lib/libpam/modules/pam_login_access/login_access.c b/lib/libpam/modules/pam_login_access/login_access.c
new file mode 100644
index 0000000..cfb24d2
--- /dev/null
+++ b/lib/libpam/modules/pam_login_access/login_access.c
@@ -0,0 +1,239 @@
+ /*
+ * This module implements a simple but effective form of login access
+ * control based on login names and on host (or domain) names, internet
+ * addresses (or network numbers), or on terminal line names in case of
+ * non-networked logins. Diagnostics are reported through syslog(3).
+ *
+ * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ */
+
+#ifdef LOGIN_ACCESS
+#ifndef lint
+static const char sccsid[] = "%Z% %M% %I% %E% %U%";
+#endif
+
+#include <stdio.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <grp.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "pathnames.h"
+
+ /* Delimiters for fields and for lists of users, ttys or hosts. */
+
+static char fs[] = ":"; /* field separator */
+static char sep[] = ", \t"; /* list-element separator */
+
+ /* Constants to be used in assignments only, not in comparisons... */
+
+#define YES 1
+#define NO 0
+
+static int list_match();
+static int user_match();
+static int from_match();
+static int string_match();
+
+/* login_access - match username/group and host/tty with access control file */
+
+int
+login_access(user, from)
+char *user;
+char *from;
+{
+ FILE *fp;
+ char line[BUFSIZ];
+ char *perm; /* becomes permission field */
+ char *users; /* becomes list of login names */
+ char *froms; /* becomes list of terminals or hosts */
+ int match = NO;
+ int end;
+ int lineno = 0; /* for diagnostics */
+
+ /*
+ * Process the table one line at a time and stop at the first match.
+ * Blank lines and lines that begin with a '#' character are ignored.
+ * Non-comment lines are broken at the ':' character. All fields are
+ * mandatory. The first field should be a "+" or "-" character. A
+ * non-existing table means no access control.
+ */
+
+ if ((fp = fopen(_PATH_LOGACCESS, "r")) != NULL) {
+ while (!match && fgets(line, sizeof(line), fp)) {
+ lineno++;
+ if (line[end = strlen(line) - 1] != '\n') {
+ syslog(LOG_ERR, "%s: line %d: missing newline or line too long",
+ _PATH_LOGACCESS, lineno);
+ continue;
+ }
+ if (line[0] == '#')
+ continue; /* comment line */
+ while (end > 0 && isspace(line[end - 1]))
+ end--;
+ line[end] = 0; /* strip trailing whitespace */
+ if (line[0] == 0) /* skip blank lines */
+ continue;
+ if (!(perm = strtok(line, fs))
+ || !(users = strtok((char *) 0, fs))
+ || !(froms = strtok((char *) 0, fs))
+ || strtok((char *) 0, fs)) {
+ syslog(LOG_ERR, "%s: line %d: bad field count", _PATH_LOGACCESS,
+ lineno);
+ continue;
+ }
+ if (perm[0] != '+' && perm[0] != '-') {
+ syslog(LOG_ERR, "%s: line %d: bad first field", _PATH_LOGACCESS,
+ lineno);
+ continue;
+ }
+ match = (list_match(froms, from, from_match)
+ && list_match(users, user, user_match));
+ }
+ (void) fclose(fp);
+ } else if (errno != ENOENT) {
+ syslog(LOG_ERR, "cannot open %s: %m", _PATH_LOGACCESS);
+ }
+ return (match == 0 || (line[0] == '+'));
+}
+
+/* list_match - match an item against a list of tokens with exceptions */
+
+static int list_match(list, item, match_fn)
+char *list;
+char *item;
+int (*match_fn) ();
+{
+ char *tok;
+ int match = NO;
+
+ /*
+ * Process tokens one at a time. We have exhausted all possible matches
+ * when we reach an "EXCEPT" token or the end of the list. If we do find
+ * a match, look for an "EXCEPT" list and recurse to determine whether
+ * the match is affected by any exceptions.
+ */
+
+ for (tok = strtok(list, sep); tok != 0; tok = strtok((char *) 0, sep)) {
+ if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */
+ break;
+ if ((match = (*match_fn)(tok, item)) != NULL) /* YES */
+ break;
+ }
+ /* Process exceptions to matches. */
+
+ if (match != NO) {
+ while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT"))
+ /* VOID */ ;
+ if (tok == 0 || list_match((char *) 0, item, match_fn) == NO)
+ return (match);
+ }
+ return (NO);
+}
+
+/* netgroup_match - match group against machine or user */
+
+static int netgroup_match(group, machine, user)
+gid_t group;
+char *machine;
+char *user;
+{
+#ifdef NIS
+ static char *mydomain = 0;
+
+ if (mydomain == 0)
+ yp_get_default_domain(&mydomain);
+ return (innetgr(group, machine, user, mydomain));
+#else
+ syslog(LOG_ERR, "NIS netgroup support not configured");
+ return 0;
+#endif
+}
+
+/* user_match - match a username against one token */
+
+static int user_match(tok, string)
+char *tok;
+char *string;
+{
+ struct group *group;
+ int i;
+
+ /*
+ * If a token has the magic value "ALL" the match always succeeds.
+ * Otherwise, return YES if the token fully matches the username, or if
+ * the token is a group that contains the username.
+ */
+
+ if (tok[0] == '@') { /* netgroup */
+ return (netgroup_match(tok + 1, (char *) 0, string));
+ } else if (string_match(tok, string)) { /* ALL or exact match */
+ return (YES);
+ } else if ((group = getgrnam(tok)) != NULL) {/* try group membership */
+ for (i = 0; group->gr_mem[i]; i++)
+ if (strcasecmp(string, group->gr_mem[i]) == 0)
+ return (YES);
+ }
+ return (NO);
+}
+
+/* from_match - match a host or tty against a list of tokens */
+
+static int from_match(tok, string)
+char *tok;
+char *string;
+{
+ int tok_len;
+ int str_len;
+
+ /*
+ * If a token has the magic value "ALL" the match always succeeds. Return
+ * YES if the token fully matches the string. If the token is a domain
+ * name, return YES if it matches the last fields of the string. If the
+ * token has the magic value "LOCAL", return YES if the string does not
+ * contain a "." character. If the token is a network number, return YES
+ * if it matches the head of the string.
+ */
+
+ if (tok[0] == '@') { /* netgroup */
+ return (netgroup_match(tok + 1, string, (char *) 0));
+ } else if (string_match(tok, string)) { /* ALL or exact match */
+ return (YES);
+ } else if (tok[0] == '.') { /* domain: match last fields */
+ if ((str_len = strlen(string)) > (tok_len = strlen(tok))
+ && strcasecmp(tok, string + str_len - tok_len) == 0)
+ return (YES);
+ } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */
+ if (strchr(string, '.') == 0)
+ return (YES);
+ } else if (tok[(tok_len = strlen(tok)) - 1] == '.' /* network */
+ && strncmp(tok, string, tok_len) == 0) {
+ return (YES);
+ }
+ return (NO);
+}
+
+/* string_match - match a string against one token */
+
+static int string_match(tok, string)
+char *tok;
+char *string;
+{
+
+ /*
+ * If the token has the magic value "ALL" the match always succeeds.
+ * Otherwise, return YES if the token fully matches the string.
+ */
+
+ if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */
+ return (YES);
+ } else if (strcasecmp(tok, string) == 0) { /* try exact match */
+ return (YES);
+ }
+ return (NO);
+}
+#endif /* LOGIN_ACCES */
diff --git a/lib/libpam/modules/pam_permit/Makefile b/lib/libpam/modules/pam_permit/Makefile
new file mode 100644
index 0000000..8863ff5
--- /dev/null
+++ b/lib/libpam/modules/pam_permit/Makefile
@@ -0,0 +1,42 @@
+# Copyright 1999 Max Khon.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+PAMDIR= ${.CURDIR}/../../../../contrib/libpam
+
+.PATH: ${PAMDIR}/modules/pam_permit
+
+LIB= pam_permit
+SHLIB_NAME= pam_permit.so
+SRCS= pam_permit.c
+CFLAGS+= -Wall
+CFLAGS+= -I${PAMDIR}/libpam/include
+CFLAGS+= -I${.CURDIR}/../../libpam
+DPADD+= ${LIBGCC_PIC}
+LDADD+= -lgcc_pic
+INTERNALLIB= yes
+INTERNALSTATICLIB=yes
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_radius/Makefile b/lib/libpam/modules/pam_radius/Makefile
new file mode 100644
index 0000000..48bd39a
--- /dev/null
+++ b/lib/libpam/modules/pam_radius/Makefile
@@ -0,0 +1,42 @@
+# Copyright 1998 Juniper Networks, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+PAMDIR= ${.CURDIR}/../../../../contrib/libpam
+
+LIB= pam_radius
+SHLIB_NAME= pam_radius.so
+SRCS= pam_radius.c
+CFLAGS+= -Wall
+CFLAGS+= -I${PAMDIR}/libpam/include
+CFLAGS+= -I${.CURDIR}/../../libpam
+DPADD+= ${LIBRADIUS} ${LIBGCC_PIC}
+LDADD+= -lradius -lgcc_pic
+INTERNALLIB= yes
+INTERNALSTATICLIB=yes
+
+MAN8= pam_radius.8
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_radius/pam_radius.8 b/lib/libpam/modules/pam_radius/pam_radius.8
new file mode 100644
index 0000000..ffaa074
--- /dev/null
+++ b/lib/libpam/modules/pam_radius/pam_radius.8
@@ -0,0 +1,128 @@
+.\" Copyright (c) 1999
+.\" Andrzej Bialecki <abial@FreeBSD.org>. All rights reserved.
+.\"
+.\" Copyright (c) 1992, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software donated to Berkeley by
+.\" Jan-Simon Pendry.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 2, 1999
+.Dt pam_radius 8
+.Os FreeBSD 3.3
+.Sh NAME
+.Nm pam_radius
+.Nd RADIUS authentication PAM module
+.Sh SYNOPSIS
+.Nm pam_radius.so
+.Op Cm use_first_pass
+.Op Cm try_first_pass
+.Op Cm echo_pass
+.Op Cm conf Ns No = Ns Ar pathname
+.Op Cm template_user Ns No = Ns Ar username
+.Sh DESCRIPTION
+The
+.Nm
+module provides authentication services based
+upon the RADIUS (Remote Authentication Dial In User Service) protocol
+for the PAM (Pluggable Authentication Module) framework.
+.Pp
+The
+.Nm
+module accepts these optional parameters:
+.Bl -tag -width Fl
+.It Cm use_first_pass
+causes
+.Nm
+to use a previously entered password instead of prompting for a new one.
+If no password has been entered then authentication fails.
+.It Cm try_first_pass
+causes
+.Nm
+to use a previously entered password, if one is available. If no
+password has been entered,
+.Nm
+prompts for one as usual.
+.It Cm echo_pass
+causes echoing to be left on if
+.Nm
+prompts for a password.
+.It Cm conf Ns No = Ns Ar pathname
+specifies a non-standard location for the RADIUS client configuration file
+(normally located in /etc/radius.conf).
+.It Cm template_user Ns No = Ns Ar username
+specifies a user whose
+.Xr passwd 5
+entry will be used as a template to create the session environment
+if the supplied username doesn't exist in local password database. The user
+will be authenticated with the supplied username and password, but his
+credentials to the system will be presented as the ones for
+.Ar username ,
+i.e., his login class, home directory, resource limits, etc. will be set to ones
+defined for
+.Ar username .
+.Pp
+If this option is omitted, and there is no username
+in the system databases equal to the supplied one (as determined by call to
+.Xr getpwnam 3 Ns ),
+the authentication will fail.
+.Sh FILES
+.Bl -tag -width /etc/radius.conf -compact
+.It Pa /etc/radius.conf
+The standard RADIUS client configuration file for
+.Nm
+.El
+.Sh SEE ALSO
+.Xr pam 8 ,
+.Xr passwd 5 ,
+.Xr radius.conf 5
+.Sh HISTORY
+The
+.Nm
+module first appeared in
+.Fx 3.1 .
+The
+.Nm
+manual page first appeared in
+.Fx 3.3 .
+.Sh AUTHORS
+The
+.Nm
+manual page was written by
+.An Andrzej Bialecki Aq abial@FreeBSD.org .
+.Pp
+The
+.Nm
+module was written by
+.An John D. Polstra Aq jdp@FreeBSD.org .
diff --git a/lib/libpam/modules/pam_radius/pam_radius.c b/lib/libpam/modules/pam_radius/pam_radius.c
new file mode 100644
index 0000000..c04d8f2
--- /dev/null
+++ b/lib/libpam/modules/pam_radius/pam_radius.c
@@ -0,0 +1,300 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <pwd.h>
+#include <radlib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#define PAM_SM_AUTH
+#include <security/pam_modules.h>
+
+#include "pam_mod_misc.h"
+
+#define MAX_CHALLENGE_MSGS 10
+#define PASSWORD_PROMPT "RADIUS password:"
+
+/* Option names, including the "=" sign. */
+#define OPT_CONF "conf="
+#define OPT_TMPL "template_user="
+
+static int build_access_request(struct rad_handle *, const char *,
+ const char *, const void *, size_t);
+static int do_accept(pam_handle_t *, struct rad_handle *);
+static int do_challenge(pam_handle_t *, struct rad_handle *,
+ const char *);
+
+/*
+ * Construct an access request, but don't send it. Returns 0 on success,
+ * -1 on failure.
+ */
+static int
+build_access_request(struct rad_handle *radh, const char *user,
+ const char *pass, const void *state, size_t state_len)
+{
+ char host[MAXHOSTNAMELEN];
+
+ if (rad_create_request(radh, RAD_ACCESS_REQUEST) == -1) {
+ syslog(LOG_CRIT, "rad_create_request: %s", rad_strerror(radh));
+ return -1;
+ }
+ if ((user != NULL &&
+ rad_put_string(radh, RAD_USER_NAME, user) == -1) ||
+ (pass != NULL &&
+ rad_put_string(radh, RAD_USER_PASSWORD, pass) == -1) ||
+ (gethostname(host, sizeof host) != -1 &&
+ rad_put_string(radh, RAD_NAS_IDENTIFIER, host) == -1)) {
+ syslog(LOG_CRIT, "rad_put_string: %s", rad_strerror(radh));
+ return -1;
+ }
+ if (state != NULL && rad_put_attr(radh, RAD_STATE, state,
+ state_len) == -1) {
+ syslog(LOG_CRIT, "rad_put_attr: %s", rad_strerror(radh));
+ return -1;
+ }
+ if (rad_put_int(radh, RAD_SERVICE_TYPE, RAD_AUTHENTICATE_ONLY) == -1) {
+ syslog(LOG_CRIT, "rad_put_int: %s", rad_strerror(radh));
+ return -1;
+ }
+ return 0;
+}
+
+static int
+do_accept(pam_handle_t *pamh, struct rad_handle *radh)
+{
+ int attrtype;
+ const void *attrval;
+ size_t attrlen;
+ char *s;
+
+ while ((attrtype = rad_get_attr(radh, &attrval, &attrlen)) > 0) {
+ if (attrtype == RAD_USER_NAME) {
+ s = rad_cvt_string(attrval, attrlen);
+ if (s == NULL) {
+ syslog(LOG_CRIT,
+ "rad_cvt_string: out of memory");
+ return -1;
+ }
+ pam_set_item(pamh, PAM_USER, s);
+ free(s);
+ }
+ }
+ if (attrtype == -1) {
+ syslog(LOG_CRIT, "rad_get_attr: %s", rad_strerror(radh));
+ return -1;
+ }
+ return 0;
+}
+
+static int
+do_challenge(pam_handle_t *pamh, struct rad_handle *radh, const char *user)
+{
+ int retval;
+ int attrtype;
+ const void *attrval;
+ size_t attrlen;
+ const void *state;
+ size_t statelen;
+ struct pam_message msgs[MAX_CHALLENGE_MSGS];
+ const struct pam_message *msg_ptrs[MAX_CHALLENGE_MSGS];
+ struct pam_response *resp;
+ int num_msgs;
+ const void *item;
+ const struct pam_conv *conv;
+
+ state = NULL;
+ statelen = 0;
+ num_msgs = 0;
+ while ((attrtype = rad_get_attr(radh, &attrval, &attrlen)) > 0) {
+ switch (attrtype) {
+
+ case RAD_STATE:
+ state = attrval;
+ statelen = attrlen;
+ break;
+
+ case RAD_REPLY_MESSAGE:
+ if (num_msgs >= MAX_CHALLENGE_MSGS) {
+ syslog(LOG_CRIT,
+ "Too many RADIUS challenge messages");
+ return PAM_SERVICE_ERR;
+ }
+ msgs[num_msgs].msg = rad_cvt_string(attrval, attrlen);
+ if (msgs[num_msgs].msg == NULL) {
+ syslog(LOG_CRIT,
+ "rad_cvt_string: out of memory");
+ return PAM_SERVICE_ERR;
+ }
+ msgs[num_msgs].msg_style = PAM_TEXT_INFO;
+ msg_ptrs[num_msgs] = &msgs[num_msgs];
+ num_msgs++;
+ break;
+ }
+ }
+ if (attrtype == -1) {
+ syslog(LOG_CRIT, "rad_get_attr: %s", rad_strerror(radh));
+ return PAM_SERVICE_ERR;
+ }
+ if (num_msgs == 0) {
+ msgs[num_msgs].msg = strdup("(null RADIUS challenge): ");
+ if (msgs[num_msgs].msg == NULL) {
+ syslog(LOG_CRIT, "Out of memory");
+ return PAM_SERVICE_ERR;
+ }
+ msgs[num_msgs].msg_style = PAM_TEXT_INFO;
+ msg_ptrs[num_msgs] = &msgs[num_msgs];
+ num_msgs++;
+ }
+ msgs[num_msgs-1].msg_style = PAM_PROMPT_ECHO_ON;
+ if ((retval = pam_get_item(pamh, PAM_CONV, &item)) != PAM_SUCCESS) {
+ syslog(LOG_CRIT, "do_challenge: cannot get PAM_CONV");
+ return retval;
+ }
+ conv = (const struct pam_conv *)item;
+ if ((retval = conv->conv(num_msgs, msg_ptrs, &resp,
+ conv->appdata_ptr)) != PAM_SUCCESS)
+ return retval;
+ if (build_access_request(radh, user, resp[num_msgs-1].resp, state,
+ statelen) == -1)
+ return PAM_SERVICE_ERR;
+ memset(resp[num_msgs-1].resp, 0, strlen(resp[num_msgs-1].resp));
+ free(resp[num_msgs-1].resp);
+ free(resp);
+ while (num_msgs > 0)
+ free((void *)msgs[--num_msgs].msg);
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int
+pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ struct rad_handle *radh;
+ const char *user;
+ const char *pass;
+ const char *conf_file = NULL;
+ const char *template_user = NULL;
+ int options = 0;
+ int retval;
+ int i;
+ int e;
+
+ for (i = 0; i < argc; i++) {
+ size_t len;
+
+ pam_std_option(&options, argv[i]);
+ if (strncmp(argv[i], OPT_CONF, (len = strlen(OPT_CONF))) == 0)
+ conf_file = argv[i] + len;
+ else if (strncmp(argv[i], OPT_TMPL,
+ (len = strlen(OPT_TMPL))) == 0)
+ template_user = argv[i] + len;
+ }
+ if ((retval = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
+ return retval;
+ if ((retval = pam_get_pass(pamh, &pass, PASSWORD_PROMPT,
+ options)) != PAM_SUCCESS)
+ return retval;
+
+ if ((radh = rad_open()) == NULL) {
+ syslog(LOG_CRIT, "rad_open failed");
+ return PAM_SERVICE_ERR;
+ }
+ if (rad_config(radh, conf_file) == -1) {
+ syslog(LOG_ALERT, "rad_config: %s", rad_strerror(radh));
+ rad_close(radh);
+ return PAM_SERVICE_ERR;
+ }
+ if (build_access_request(radh, user, pass, NULL, 0) == -1) {
+ rad_close(radh);
+ return PAM_SERVICE_ERR;
+ }
+ for ( ; ; ) {
+ switch (rad_send_request(radh)) {
+
+ case RAD_ACCESS_ACCEPT:
+ e = do_accept(pamh, radh);
+ rad_close(radh);
+ if (e == -1)
+ return PAM_SERVICE_ERR;
+ if (template_user != NULL) {
+ const void *item;
+ const char *user;
+
+ /*
+ * If the given user name doesn't exist in
+ * the local password database, change it
+ * to the value given in the "template_user"
+ * option.
+ */
+ retval = pam_get_item(pamh, PAM_USER, &item);
+ if (retval != PAM_SUCCESS)
+ return retval;
+ user = (const char *)item;
+ if (getpwnam(user) == NULL)
+ pam_set_item(pamh, PAM_USER,
+ template_user);
+ }
+ return PAM_SUCCESS;
+
+ case RAD_ACCESS_REJECT:
+ rad_close(radh);
+ return PAM_AUTH_ERR;
+
+ case RAD_ACCESS_CHALLENGE:
+ if ((retval = do_challenge(pamh, radh, user)) !=
+ PAM_SUCCESS) {
+ rad_close(radh);
+ return retval;
+ }
+ break;
+
+ case -1:
+ syslog(LOG_CRIT, "rad_send_request: %s",
+ rad_strerror(radh));
+ rad_close(radh);
+ return PAM_AUTHINFO_UNAVAIL;
+
+ default:
+ syslog(LOG_CRIT,
+ "rad_send_request: unexpected return value");
+ rad_close(radh);
+ return PAM_SERVICE_ERR;
+ }
+ }
+}
+
+PAM_EXTERN int
+pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+PAM_MODULE_ENTRY("pam_radius");
diff --git a/lib/libpam/modules/pam_skey/Makefile b/lib/libpam/modules/pam_skey/Makefile
new file mode 100644
index 0000000..bf6af9e
--- /dev/null
+++ b/lib/libpam/modules/pam_skey/Makefile
@@ -0,0 +1,40 @@
+# Copyright 1998 Juniper Networks, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+PAMDIR= ${.CURDIR}/../../../../contrib/libpam
+
+LIB= pam_skey
+SHLIB_NAME= pam_skey.so
+SRCS= pam_skey.c
+CFLAGS+= -Wall
+CFLAGS+= -I${PAMDIR}/libpam/include
+CFLAGS+= -I${.CURDIR}/../../libpam
+DPADD+= ${LIBSKEY} ${LIBGCC_PIC}
+LDADD+= -lskey -lgcc_pic
+INTERNALLIB= yes
+INTERNALSTATICLIB=yes
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_skey/pam_skey.c b/lib/libpam/modules/pam_skey/pam_skey.c
new file mode 100644
index 0000000..439591e
--- /dev/null
+++ b/lib/libpam/modules/pam_skey/pam_skey.c
@@ -0,0 +1,108 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <syslog.h> /* XXX */
+
+#include <stdio.h>
+#include <string.h>
+#include <skey.h>
+
+#define PAM_SM_AUTH
+#include <security/pam_modules.h>
+
+#include "pam_mod_misc.h"
+
+PAM_EXTERN int
+pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ int retval;
+ const char *user;
+ const char *response;
+ struct skey skey;
+ char challenge[128];
+ char prompt[128];
+ char resp_buf[128];
+ int options;
+ int i;
+ int e;
+
+ options = 0;
+ for (i = 0; i < argc; i++)
+ pam_std_option(&options, argv[i]);
+ /*
+ * It doesn't make sense to use a password that has already been
+ * typed in, since we haven't presented the challenge to the user
+ * yet.
+ */
+ options &= ~(PAM_OPT_USE_FIRST_PASS | PAM_OPT_TRY_FIRST_PASS);
+ if ((retval = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
+ return retval;
+ if (skeyinfo(&skey, user, challenge) != 0)
+ return PAM_AUTH_ERR;
+ snprintf(prompt, sizeof prompt, "%s\nPassword: ", challenge);
+ if ((retval = pam_get_pass(pamh, &response, prompt, options)) !=
+ PAM_SUCCESS)
+ return retval;
+ if (response[0] == '\0' && !(options & PAM_OPT_ECHO_PASS)) {
+ options |= PAM_OPT_ECHO_PASS;
+ snprintf(prompt, sizeof prompt,
+ "%s\nPassword [echo on]: ", challenge);
+ if ((retval = pam_get_pass(pamh, &response, prompt,
+ options)) != PAM_SUCCESS)
+ return retval;
+ }
+ /*
+ * Skeyinfo closed the database file, so we have to call skeylookup
+ * to open it again.
+ */
+ if ((e = skeylookup(&skey, user)) != 0) {
+ if (e == -1) {
+ syslog(LOG_ERR, "Error opening S/Key database");
+ return PAM_SERVICE_ERR;
+ } else
+ return PAM_AUTH_ERR;
+ }
+ /* We have to copy the response, because skeyverify mucks with it. */
+ snprintf(resp_buf, sizeof resp_buf, "%s", response);
+ /*
+ * Skeyverify is supposed to return -1 only if an error occurs.
+ * But it returns -1 even if the response string isn't in the form
+ * it expects. Thus we can't log an error and can only check for
+ * success or lack thereof.
+ */
+ return skeyverify(&skey, resp_buf) == 0 ? PAM_SUCCESS : PAM_AUTH_ERR;
+}
+
+PAM_EXTERN int
+pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+PAM_MODULE_ENTRY("pam_skey");
diff --git a/lib/libpam/modules/pam_ssh/pam_ssh.c b/lib/libpam/modules/pam_ssh/pam_ssh.c
new file mode 100644
index 0000000..8e22d3f
--- /dev/null
+++ b/lib/libpam/modules/pam_ssh/pam_ssh.c
@@ -0,0 +1,328 @@
+/*-
+ * Copyright (c) 1999 Andrew J. Korty
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+
+#include <sys/param.h>
+
+#include <fcntl.h>
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define PAM_SM_AUTH
+#define PAM_SM_SESSION
+#include <security/pam_modules.h>
+#include <security/pam_mod_misc.h>
+
+#include "includes.h"
+#include "rsa.h"
+#include "ssh.h"
+#include "authfd.h"
+
+#define MODULE_NAME "pam_ssh"
+#define NEED_PASSPHRASE "Need passphrase for %s (%s).\nEnter passphrase: "
+#define PATH_SSH_AGENT "__PREFIX__/bin/ssh-agent"
+
+
+void
+rsa_cleanup(pam_handle_t *pamh, void *data, int error_status)
+{
+ if (data)
+ RSA_free(data);
+}
+
+
+void
+ssh_cleanup(pam_handle_t *pamh, void *data, int error_status)
+{
+ if (data)
+ free(data);
+}
+
+
+typedef struct passwd PASSWD;
+
+PAM_EXTERN int
+pam_sm_authenticate(
+ pam_handle_t *pamh,
+ int flags,
+ int argc,
+ const char **argv)
+{
+ char *comment_priv; /* on private key */
+ char *comment_pub; /* on public key */
+ char *identity; /* user's identity file */
+ RSA *key; /* user's private key */
+ int options; /* module options */
+ const char *pass; /* passphrase */
+ char *prompt; /* passphrase prompt */
+ RSA *public_key; /* user's public key */
+ const PASSWD *pwent; /* user's passwd entry */
+ PASSWD *pwent_keep; /* our own copy */
+ int retval; /* from calls */
+ uid_t saved_uid; /* caller's uid */
+ const char *user; /* username */
+
+ options = 0;
+ while (argc--)
+ pam_std_option(&options, *argv++);
+ if ((retval = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
+ return retval;
+ if (!((pwent = getpwnam(user)) && pwent->pw_dir)) {
+ /* delay? */
+ return PAM_AUTH_ERR;
+ }
+ /* locate the user's private key file */
+ if (!asprintf(&identity, "%s/%s", pwent->pw_dir,
+ SSH_CLIENT_IDENTITY)) {
+ syslog(LOG_CRIT, "%s: %m", MODULE_NAME);
+ return PAM_SERVICE_ERR;
+ }
+ /*
+ * Fail unless we can load the public key. Change to the
+ * owner's UID to appease load_public_key().
+ */
+ key = RSA_new();
+ public_key = RSA_new();
+ saved_uid = getuid();
+ (void)setreuid(pwent->pw_uid, saved_uid);
+ retval = load_public_key(identity, public_key, &comment_pub);
+ (void)setuid(saved_uid);
+ if (!retval) {
+ free(identity);
+ return PAM_AUTH_ERR;
+ }
+ RSA_free(public_key);
+ /* build the passphrase prompt */
+ retval = asprintf(&prompt, NEED_PASSPHRASE, identity, comment_pub);
+ free(comment_pub);
+ if (!retval) {
+ syslog(LOG_CRIT, "%s: %m", MODULE_NAME);
+ free(identity);
+ return PAM_SERVICE_ERR;
+ }
+ /* pass prompt message to application and receive passphrase */
+ retval = pam_get_pass(pamh, &pass, prompt, options);
+ free(prompt);
+ if (retval != PAM_SUCCESS) {
+ free(identity);
+ return retval;
+ }
+ /*
+ * Try to decrypt the private key with the passphrase provided.
+ * If success, the user is authenticated.
+ */
+ (void)setreuid(pwent->pw_uid, saved_uid);
+ retval = load_private_key(identity, pass, key, &comment_priv);
+ free(identity);
+ (void)setuid(saved_uid);
+ if (!retval)
+ return PAM_AUTH_ERR;
+ /*
+ * Save the key and comment to pass to ssh-agent in the session
+ * phase.
+ */
+ if ((retval = pam_set_data(pamh, "ssh_private_key", key,
+ rsa_cleanup)) != PAM_SUCCESS) {
+ RSA_free(key);
+ free(comment_priv);
+ return retval;
+ }
+ if ((retval = pam_set_data(pamh, "ssh_key_comment", comment_priv,
+ ssh_cleanup)) != PAM_SUCCESS) {
+ free(comment_priv);
+ return retval;
+ }
+ /*
+ * Copy the passwd entry (in case successive calls are made)
+ * and save it for the session phase.
+ */
+ if (!(pwent_keep = malloc(sizeof *pwent))) {
+ syslog(LOG_CRIT, "%m");
+ return PAM_SERVICE_ERR;
+ }
+ (void)memcpy(pwent_keep, pwent, sizeof *pwent_keep);
+ if ((retval = pam_set_data(pamh, "ssh_passwd_entry", pwent_keep,
+ ssh_cleanup)) != PAM_SUCCESS) {
+ free(pwent_keep);
+ return retval;
+ }
+ return PAM_SUCCESS;
+}
+
+
+PAM_EXTERN int
+pam_sm_setcred(
+ pam_handle_t *pamh,
+ int flags,
+ int argc,
+ const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+
+typedef AuthenticationConnection AC;
+
+PAM_EXTERN int
+pam_sm_open_session(
+ pam_handle_t *pamh,
+ int flags,
+ int argc,
+ const char **argv)
+{
+ AC *ac; /* to ssh-agent */
+ char *comment; /* on private key */
+ char *env_end; /* end of env */
+ char *env_file; /* to store env */
+ FILE *env_fp; /* env_file handle */
+ RSA *key; /* user's private key */
+ FILE *pipe; /* ssh-agent handle */
+ const PASSWD *pwent; /* user's passwd entry */
+ int retval; /* from calls */
+ uid_t saved_uid; /* caller's uid */
+ const char *tty; /* tty or display name */
+ char hname[MAXHOSTNAMELEN]; /* local hostname */
+ char parse[BUFSIZ]; /* commands output */
+
+ /* dump output of ssh-agent in ~/.ssh */
+ if ((retval = pam_get_data(pamh, "ssh_passwd_entry",
+ (const void **)&pwent)) != PAM_SUCCESS)
+ return retval;
+ /* use the tty or X display name in the filename */
+ if ((retval = pam_get_item(pamh, PAM_TTY, (const void **)&tty))
+ != PAM_SUCCESS)
+ return retval;
+ if (*tty == ':' && gethostname(hname, sizeof hname) == 0) {
+ if (asprintf(&env_file, "%s/.ssh/agent-%s%s",
+ pwent->pw_dir, hname, tty) == -1) {
+ syslog(LOG_CRIT, "%s: %m", MODULE_NAME);
+ return PAM_SERVICE_ERR;
+ }
+ } else if (asprintf(&env_file, "%s/.ssh/agent-%s", pwent->pw_dir,
+ tty) == -1) {
+ syslog(LOG_CRIT, "%s: %m", MODULE_NAME);
+ return PAM_SERVICE_ERR;
+ }
+ /* save the filename so we can delete the file on session close */
+ if ((retval = pam_set_data(pamh, "ssh_agent_env", env_file,
+ ssh_cleanup)) != PAM_SUCCESS) {
+ free(env_file);
+ return retval;
+ }
+ /* start the agent as the user */
+ saved_uid = geteuid();
+ (void)seteuid(pwent->pw_uid);
+ env_fp = fopen(env_file, "w");
+ pipe = popen(PATH_SSH_AGENT, "r");
+ (void)seteuid(saved_uid);
+ if (!pipe) {
+ syslog(LOG_ERR, "%s: %s: %m", MODULE_NAME, PATH_SSH_AGENT);
+ if (env_fp)
+ (void)fclose(env_fp);
+ return PAM_SESSION_ERR;
+ }
+ while (fgets(parse, sizeof parse, pipe)) {
+ if (env_fp)
+ (void)fputs(parse, env_fp);
+ /*
+ * Save environment for application with pam_putenv()
+ * but also with putenv() for our own call to
+ * ssh_get_authentication_connection().
+ */
+ if (strchr(parse, '=') && (env_end = strchr(parse, ';'))) {
+ *env_end = '\0';
+ /* pass to the application ... */
+ if (!((retval = pam_putenv(pamh, parse)) ==
+ PAM_SUCCESS && putenv(parse) == 0)) {
+ (void)pclose(pipe);
+ if (env_fp)
+ (void)fclose(env_fp);
+ return PAM_SERVICE_ERR;
+ }
+ }
+ }
+ if (env_fp)
+ (void)fclose(env_fp);
+ retval = pclose(pipe);
+ if (retval > 0) {
+ syslog(LOG_ERR, "%s: %s exited with status %d",
+ MODULE_NAME, PATH_SSH_AGENT, WEXITSTATUS(retval));
+ return PAM_SESSION_ERR;
+ } else if (retval < 0) {
+ syslog(LOG_ERR, "%s: %s: %m", MODULE_NAME, PATH_SSH_AGENT);
+ return PAM_SESSION_ERR;
+ }
+ /* connect to the agent and hand off the private key */
+ if ((retval = pam_get_data(pamh, "ssh_private_key",
+ (const void **)&key)) != PAM_SUCCESS)
+ return retval;
+ if ((retval = pam_get_data(pamh, "ssh_key_comment",
+ (const void **)&comment)) != PAM_SUCCESS)
+ return retval;
+ if (!(ac = ssh_get_authentication_connection())) {
+ syslog(LOG_ERR, "%s: could not connect to agent",
+ MODULE_NAME);
+ return PAM_SESSION_ERR;
+ }
+ retval = ssh_add_identity(ac, key, comment);
+ ssh_close_authentication_connection(ac);
+ return retval ? PAM_SUCCESS : PAM_SESSION_ERR;
+}
+
+
+PAM_EXTERN int
+pam_sm_close_session(
+ pam_handle_t *pamh,
+ int flags,
+ int argc,
+ const char **argv)
+{
+ const char *env_file; /* ssh-agent environment */
+ int retval; /* from calls */
+
+ /* kill the agent */
+ if ((retval = system(PATH_SSH_AGENT " -k")) != 0) {
+ syslog(LOG_ERR, "%s: %s -k exited with status %d",
+ MODULE_NAME, PATH_SSH_AGENT, WEXITSTATUS(retval));
+ return PAM_SESSION_ERR;
+ }
+ /* retrieve environment filename, then remove the file */
+ if ((retval = pam_get_data(pamh, "ssh_agent_env",
+ (const void **)&env_file)) != PAM_SUCCESS)
+ return retval;
+ (void)unlink(env_file);
+ return PAM_SUCCESS;
+}
+
+
+PAM_MODULE_ENTRY(MODULE_NAME);
diff --git a/lib/libpam/modules/pam_tacplus/Makefile b/lib/libpam/modules/pam_tacplus/Makefile
new file mode 100644
index 0000000..6430ca8
--- /dev/null
+++ b/lib/libpam/modules/pam_tacplus/Makefile
@@ -0,0 +1,40 @@
+# Copyright 1998 Juniper Networks, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+PAMDIR= ${.CURDIR}/../../../../contrib/libpam
+
+LIB= pam_tacplus
+SHLIB_NAME= pam_tacplus.so
+SRCS= pam_tacplus.c
+CFLAGS+= -Wall
+CFLAGS+= -I${PAMDIR}/libpam/include
+CFLAGS+= -I${.CURDIR}/../../libpam
+DPADD+= ${LIBTACPLUS} ${LIBGCC_PIC}
+LDADD+= -ltacplus -lgcc_pic
+INTERNALLIB= yes
+INTERNALSTATICLIB=yes
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_tacplus/pam_tacplus.c b/lib/libpam/modules/pam_tacplus/pam_tacplus.c
new file mode 100644
index 0000000..0820071
--- /dev/null
+++ b/lib/libpam/modules/pam_tacplus/pam_tacplus.c
@@ -0,0 +1,258 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <taclib.h>
+#include <unistd.h>
+
+#define PAM_SM_AUTH
+#include <security/pam_modules.h>
+
+#include "pam_mod_misc.h"
+
+/* Option names, including the "=" sign. */
+#define OPT_CONF "conf="
+#define OPT_TMPL "template_user="
+
+typedef int (*set_func)(struct tac_handle *, const char *);
+
+static int do_item(pam_handle_t *, struct tac_handle *, int,
+ set_func, const char *);
+static char *get_msg(struct tac_handle *);
+static int set_msg(struct tac_handle *, const char *);
+
+static int
+do_item(pam_handle_t *pamh, struct tac_handle *tach, int item,
+ set_func func, const char *funcname)
+{
+ int retval;
+ const void *value;
+
+ if ((retval = pam_get_item(pamh, item, &value)) != PAM_SUCCESS)
+ return retval;
+ if (value != NULL && (*func)(tach, (const char *)value) == -1) {
+ syslog(LOG_CRIT, "%s: %s", funcname, tac_strerror(tach));
+ tac_close(tach);
+ return PAM_SERVICE_ERR;
+ }
+ return PAM_SUCCESS;
+}
+
+static char *
+get_msg(struct tac_handle *tach)
+{
+ char *msg;
+
+ if ((msg = tac_get_msg(tach)) == NULL) {
+ syslog(LOG_CRIT, "tac_get_msg: %s", tac_strerror(tach));
+ tac_close(tach);
+ return NULL;
+ }
+ return msg;
+}
+
+static int
+set_msg(struct tac_handle *tach, const char *msg)
+{
+ if (tac_set_msg(tach, msg) == -1) {
+ syslog(LOG_CRIT, "tac_set_msg: %s", tac_strerror(tach));
+ tac_close(tach);
+ return -1;
+ }
+ return 0;
+}
+
+PAM_EXTERN int
+pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ int retval;
+ struct tac_handle *tach;
+ const char *conf_file = NULL;
+ const char *template_user = NULL;
+ int options = 0;
+ int i;
+
+ for (i = 0; i < argc; i++) {
+ size_t len;
+
+ pam_std_option(&options, argv[i]);
+ if (strncmp(argv[i], OPT_CONF, (len = strlen(OPT_CONF))) == 0)
+ conf_file = argv[i] + len;
+ else if (strncmp(argv[i], OPT_TMPL,
+ (len = strlen(OPT_TMPL))) == 0)
+ template_user = argv[i] + len;
+ }
+
+ if ((tach = tac_open()) == NULL) {
+ syslog(LOG_CRIT, "tac_open failed");
+ return PAM_SERVICE_ERR;
+ }
+ if (tac_config(tach, conf_file) == -1) {
+ syslog(LOG_ALERT, "tac_config: %s", tac_strerror(tach));
+ tac_close(tach);
+ return PAM_SERVICE_ERR;
+ }
+ if (tac_create_authen(tach, TAC_AUTHEN_LOGIN, TAC_AUTHEN_TYPE_ASCII,
+ TAC_AUTHEN_SVC_LOGIN) == -1) {
+ syslog(LOG_CRIT, "tac_create_authen: %s", tac_strerror(tach));
+ tac_close(tach);
+ return PAM_SERVICE_ERR;
+ }
+ if ((retval = do_item(pamh, tach, PAM_USER,
+ tac_set_user, "tac_set_user")) != PAM_SUCCESS)
+ return retval;
+ if ((retval = do_item(pamh, tach, PAM_TTY,
+ tac_set_port, "tac_set_port")) != PAM_SUCCESS)
+ return retval;
+ if ((retval = do_item(pamh, tach, PAM_RHOST,
+ tac_set_rem_addr, "tac_set_rem_addr")) != PAM_SUCCESS)
+ return retval;
+ for ( ; ; ) {
+ char *srvr_msg;
+ size_t msg_len;
+ const char *user_msg;
+ char *data_msg;
+ int sflags;
+ int status;
+ int echo;
+
+ if ((sflags = tac_send_authen(tach)) == -1) {
+ syslog(LOG_CRIT, "tac_send_authen: %s",
+ tac_strerror(tach));
+ tac_close(tach);
+ return PAM_AUTHINFO_UNAVAIL;
+ }
+ status = TAC_AUTHEN_STATUS(sflags);
+ echo = TAC_AUTHEN_NOECHO(sflags) ? 0 : PAM_OPT_ECHO_PASS;
+ switch (status) {
+
+ case TAC_AUTHEN_STATUS_PASS:
+ tac_close(tach);
+ if (template_user != NULL) {
+ const void *item;
+ const char *user;
+
+ /*
+ * If the given user name doesn't exist in
+ * the local password database, change it
+ * to the value given in the "template_user"
+ * option.
+ */
+ retval = pam_get_item(pamh, PAM_USER, &item);
+ if (retval != PAM_SUCCESS)
+ return retval;
+ user = (const char *)item;
+ if (getpwnam(user) == NULL)
+ pam_set_item(pamh, PAM_USER,
+ template_user);
+ }
+ return PAM_SUCCESS;
+
+ case TAC_AUTHEN_STATUS_FAIL:
+ tac_close(tach);
+ return PAM_AUTH_ERR;
+
+ case TAC_AUTHEN_STATUS_GETUSER:
+ case TAC_AUTHEN_STATUS_GETPASS:
+ if ((srvr_msg = get_msg(tach)) == NULL)
+ return PAM_SERVICE_ERR;
+ if (status == TAC_AUTHEN_STATUS_GETUSER)
+ retval = pam_get_user(pamh, &user_msg,
+ srvr_msg[0] != '\0' ? srvr_msg : NULL);
+ else if (status == TAC_AUTHEN_STATUS_GETPASS)
+ retval = pam_get_pass(pamh, &user_msg,
+ srvr_msg[0] != '\0' ? srvr_msg :
+ "Password:", options | echo);
+ free(srvr_msg);
+ if (retval != PAM_SUCCESS) {
+ /* XXX - send a TACACS+ abort packet */
+ tac_close(tach);
+ return retval;
+ }
+ if (set_msg(tach, user_msg) == -1)
+ return PAM_SERVICE_ERR;
+ break;
+
+ case TAC_AUTHEN_STATUS_GETDATA:
+ if ((srvr_msg = get_msg(tach)) == NULL)
+ return PAM_SERVICE_ERR;
+ retval = pam_prompt(pamh,
+ (options|echo) & PAM_OPT_ECHO_PASS ?
+ PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF,
+ srvr_msg[0] != '\0' ? srvr_msg : "Data:",
+ &data_msg);
+ free(srvr_msg);
+ if (retval != PAM_SUCCESS) {
+ /* XXX - send a TACACS+ abort packet */
+ tac_close(tach);
+ return retval;
+ }
+ retval = set_msg(tach, data_msg);
+ memset(data_msg, 0, strlen(data_msg));
+ free(data_msg);
+ if (retval == -1)
+ return PAM_SERVICE_ERR;
+ break;
+
+ case TAC_AUTHEN_STATUS_ERROR:
+ srvr_msg = (char *)tac_get_data(tach, &msg_len);
+ if (srvr_msg != NULL && msg_len != 0) {
+ syslog(LOG_CRIT, "tac_send_authen:"
+ " server detected error: %s", srvr_msg);
+ free(srvr_msg);
+ } else
+ syslog(LOG_CRIT,
+ "tac_send_authen: server detected error");
+ tac_close(tach);
+ return PAM_AUTHINFO_UNAVAIL;
+ break;
+
+ case TAC_AUTHEN_STATUS_RESTART:
+ case TAC_AUTHEN_STATUS_FOLLOW:
+ default:
+ syslog(LOG_CRIT,
+ "tac_send_authen: unexpected status %#x", status);
+ tac_close(tach);
+ return PAM_AUTHINFO_UNAVAIL;
+ }
+ }
+}
+
+PAM_EXTERN int
+pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+PAM_MODULE_ENTRY("pam_tacplus");
diff --git a/lib/libpam/modules/pam_unix/Makefile b/lib/libpam/modules/pam_unix/Makefile
new file mode 100644
index 0000000..7ef7ce3
--- /dev/null
+++ b/lib/libpam/modules/pam_unix/Makefile
@@ -0,0 +1,40 @@
+# Copyright 1998 Juniper Networks, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+PAMDIR= ${.CURDIR}/../../../../contrib/libpam
+
+LIB= pam_unix
+SHLIB_NAME= pam_unix.so
+SRCS= pam_unix.c
+CFLAGS+= -Wall
+CFLAGS+= -I${PAMDIR}/libpam/include
+CFLAGS+= -I${.CURDIR}/../../libpam
+DPADD+= ${LIBUTIL} ${LIBGCC_PIC} ${LIBCRYPT}
+LDADD+= -lutil -lgcc_pic -lcrypt
+INTERNALLIB= yes
+INTERNALSTATICLIB=yes
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_unix/pam_unix.c b/lib/libpam/modules/pam_unix/pam_unix.c
new file mode 100644
index 0000000..329b784
--- /dev/null
+++ b/lib/libpam/modules/pam_unix/pam_unix.c
@@ -0,0 +1,164 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <login_cap.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#define PAM_SM_AUTH
+#define PAM_SM_ACCOUNT
+#include <security/pam_modules.h>
+
+#include "pam_mod_misc.h"
+
+#define PASSWORD_PROMPT "Password:"
+
+/*
+ * authentication management
+ */
+
+PAM_EXTERN int
+pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ int retval;
+ const char *user;
+ const char *password;
+ struct passwd *pwd;
+ char *encrypted;
+ int options;
+ int i;
+
+ options = 0;
+ for (i = 0; i < argc; i++)
+ pam_std_option(&options, argv[i]);
+ if ((retval = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
+ return retval;
+ if ((retval = pam_get_pass(pamh, &password, PASSWORD_PROMPT,
+ options)) != PAM_SUCCESS)
+ return retval;
+ if ((pwd = getpwnam(user)) != NULL) {
+ encrypted = crypt(password, pwd->pw_passwd);
+ if (password[0] == '\0' && pwd->pw_passwd[0] != '\0')
+ encrypted = ":";
+
+ retval = strcmp(encrypted, pwd->pw_passwd) == 0 ?
+ PAM_SUCCESS : PAM_AUTH_ERR;
+ } else {
+ /*
+ * User unknown. Encrypt anyway so that it takes the
+ * same amount of time.
+ */
+ crypt(password, "xx");
+ retval = PAM_AUTH_ERR;
+ }
+ /*
+ * The PAM infrastructure will obliterate the cleartext
+ * password before returning to the application.
+ */
+ return retval;
+}
+
+PAM_EXTERN int
+pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+/*
+ * account management
+ *
+ * check pw_change and pw_expire fields
+ */
+PAM_EXTERN
+int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ const char *user;
+ struct passwd *pw;
+ struct timeval tp;
+ time_t warntime;
+ login_cap_t *lc = NULL;
+ char buf[128];
+ int retval;
+
+ retval = pam_get_item(pamh, PAM_USER, (const void **)&user);
+ if (retval != PAM_SUCCESS || user == NULL)
+ /* some implementations return PAM_SUCCESS here */
+ return PAM_USER_UNKNOWN;
+
+ if ((pw = getpwnam(user)) == NULL)
+ return PAM_USER_UNKNOWN;
+
+ retval = PAM_SUCCESS;
+ lc = login_getpwclass(pw);
+
+ if (pw->pw_change || pw->pw_expire)
+ gettimeofday(&tp, NULL);
+
+#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */
+
+ warntime = login_getcaptime(lc, "warnpassword", DEFAULT_WARN,
+ DEFAULT_WARN);
+
+ if (pw->pw_change) {
+ if (tp.tv_sec >= pw->pw_change)
+ /* some implementations return PAM_AUTHTOK_EXPIRED */
+ retval = PAM_NEW_AUTHTOK_REQD;
+ else if (pw->pw_change - tp.tv_sec < warntime) {
+ snprintf(buf, sizeof(buf),
+ "Warning: your password expires on %s",
+ ctime(&pw->pw_change));
+ pam_prompt(pamh, PAM_ERROR_MSG, buf, NULL);
+ }
+ }
+
+ warntime = login_getcaptime(lc, "warnexpire", DEFAULT_WARN,
+ DEFAULT_WARN);
+
+ if (pw->pw_expire) {
+ if (tp.tv_sec >= pw->pw_expire)
+ retval = PAM_ACCT_EXPIRED;
+ else if (pw->pw_expire - tp.tv_sec < warntime) {
+ snprintf(buf, sizeof(buf),
+ "Warning: your account expires on %s",
+ ctime(&pw->pw_expire));
+ pam_prompt(pamh, PAM_ERROR_MSG, buf, NULL);
+ }
+ }
+
+ login_close(lc);
+ return retval;
+}
+
+PAM_MODULE_ENTRY("pam_unix");
diff --git a/lib/libpanel/Makefile b/lib/libpanel/Makefile
new file mode 100644
index 0000000..f878817
--- /dev/null
+++ b/lib/libpanel/Makefile
@@ -0,0 +1,19 @@
+# Makefile for libpanel
+# $FreeBSD$
+
+NCURSES=${.CURDIR}/../../contrib/ncurses
+
+.PATH: ${NCURSES}/panel
+
+LIB= panel
+
+SRCS= panel.c
+
+CFLAGS+= -I${.CURDIR}/../libncurses -I${NCURSES}/panel -I${NCURSES}/include \
+ -Wall -DNDEBUG -DHAVE_CONFIG_H
+
+beforeinstall:
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${NCURSES}/panel/panel.h ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libpcap/Makefile b/lib/libpcap/Makefile
new file mode 100644
index 0000000..1218280
--- /dev/null
+++ b/lib/libpcap/Makefile
@@ -0,0 +1,42 @@
+# Makefile for libpcap
+# $FreeBSD$
+
+LIB= pcap
+SRCS= grammar.y tokdefs.h pcap-bpf.c \
+ pcap.c inet.c gencode.c optimize.c nametoaddr.c \
+ etherent.c savefile.c bpf_filter.c bpf_image.c \
+ scanner.l version.c
+MAN3= pcap.3
+CLEANFILES=tokdefs.h version.c
+
+DEFS= -DHAVE_SYS_IOCCOM_H=1 -DHAVE_SYS_SOCKIO_H=1 \
+ -DHAVE_ETHER_HOSTTON=1 -DHAVE_STRERROR=1 \
+ -DHAVE_SOCKADDR_SA_LEN=1 -DLBL_ALIGN=1
+
+CFLAGS+=-I. -Dyylval=pcap_lval ${DEFS}
+
+SHLIB_MAJOR=2
+SHLIB_MINOR=3
+
+#
+# Magic to grab sources out of src/contrib
+#
+PCAP_DISTDIR?=${.CURDIR}/../../contrib/libpcap
+CFLAGS+=-I${PCAP_DISTDIR} -I${PCAP_DISTDIR}/lbl
+.PATH: ${PCAP_DISTDIR}
+.PATH: ${PCAP_DISTDIR}/bpf/net
+
+version.c: ${PCAP_DISTDIR}/VERSION
+ @rm -f $@
+ sed 's/.*/char pcap_version[] = "&";/' ${PCAP_DISTDIR}/VERSION > $@
+
+beforeinstall:
+.for i in pcap.h pcap-int.h pcap-namedb.h
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${PCAP_DISTDIR}/$i \
+ ${DESTDIR}/usr/include
+.endfor
+
+tokdefs.h: grammar.h
+ ln -sf grammar.h tokdefs.h
+
+.include <bsd.lib.mk>
diff --git a/lib/libpthread/Makefile b/lib/libpthread/Makefile
new file mode 100644
index 0000000..e79d5c5
--- /dev/null
+++ b/lib/libpthread/Makefile
@@ -0,0 +1,45 @@
+# $FreeBSD$
+#
+# All library objects contain rcsid strings by default; they may be
+# excluded as a space-saving measure. To produce a library that does
+# not contain these strings, delete -DLIBC_RCS and -DSYSLIBC_RCS
+# from CFLAGS below. To remove these strings from just the system call
+# stubs, remove just -DSYSLIBC_RCS from CFLAGS.
+LIB=c_r
+SHLIB_MAJOR= 4
+SHLIB_MINOR= 0
+CFLAGS+=-DLIBC_RCS -DSYSLIBC_RCS -I${.CURDIR}/../libc/include
+CFLAGS+=-DPTHREAD_KERNEL -D_THREAD_SAFE -I${.CURDIR}/uthread
+CFLAGS+=-I${.CURDIR}/../../include
+
+# Uncomment this if you want libc_r to contain debug information for
+# thread locking.
+CFLAGS+=-D_LOCK_DEBUG
+
+# enable extra internal consistancy checks
+# CFLAGS+=-D_PTHREADS_INVARIANTS
+
+AINC= -I${.CURDIR}/../libc/${MACHINE_ARCH} -I${.CURDIR}/uthread
+PRECIOUSLIB= yes
+
+#
+# This is a list of syscalls that are renamed as _thread_sys_{syscall}
+# so that libc_r can provide replacement functions.
+#
+HIDDEN_SYSCALLS= accept.o bind.o close.o connect.o dup.o dup2.o \
+ execve.o fchflags.o fchmod.o fchown.o fcntl.o \
+ flock.o fpathconf.o fstat.o fstatfs.o fsync.o getdirentries.o \
+ getlogin.o getpeername.o getsockname.o getsockopt.o ioctl.o listen.o \
+ msync.o nanosleep.o nfssvc.o open.o poll.o read.o readv.o recvfrom.o \
+ recvmsg.o sched_yield.o select.o sendmsg.o sendto.o \
+ setsockopt.o shutdown.o sigaction.o sigaltstack.o \
+ signanosleep.o sigpending.o sigprocmask.o sigreturn.o sigsetmask.o \
+ sigsuspend.o socket.o \
+ socketpair.o wait4.o write.o writev.o
+
+.include "${.CURDIR}/../libc/Makefile.inc"
+.include "${.CURDIR}/man/Makefile.inc"
+.include "${.CURDIR}/uthread/Makefile.inc"
+.include "${.CURDIR}/sys/Makefile.inc"
+
+.include <bsd.lib.mk>
diff --git a/lib/libpthread/arch/alpha/alpha/_atomic_lock.S b/lib/libpthread/arch/alpha/alpha/_atomic_lock.S
new file mode 100644
index 0000000..1cfb52f
--- /dev/null
+++ b/lib/libpthread/arch/alpha/alpha/_atomic_lock.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ * copyright Douglas Santry 1996
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the above copyright is retained
+ * in the source form.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Douglas Santry AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Douglas Santry OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include "SYS.h"
+
+/*
+ * Atomicly lock a location with an identifier provided the location
+ * is not currently locked.
+ *
+ * long _atomic_lock(long *);
+ * v0 will contain the return value (zero if lock obtained).
+ */
+LEAF(_atomic_lock,0)
+ LDGP(pv)
+
+0: ldq_l v0, 0(a0) /* read existing lock value */
+ mov 1, t0 /* locked value to store */
+ stq_c t0, 0(a0) /* attempt to store, status in t0 */
+ beq t0, 1f /* branch foward to optimise prediction */
+ mb /* sync with other processors */
+ RET /* return with v0==0 if lock obtained */
+1: br 0b /* loop to try again */
+END(_atomic_lock)
diff --git a/lib/libpthread/arch/i386/i386/_atomic_lock.S b/lib/libpthread/arch/i386/i386/_atomic_lock.S
new file mode 100644
index 0000000..afaec71
--- /dev/null
+++ b/lib/libpthread/arch/i386/i386/_atomic_lock.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ * copyright Douglas Santry 1996
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the above copyright is retained
+ * in the source form.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Douglas Santry AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Douglas Santry OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+/*
+ * Atomicly lock a location with an identifier provided the location
+ * is not currently locked.
+ *
+ * long _atomic_lock(long *);
+ * eax will contain the return value (zero if lock obtained).
+ */
+ENTRY(_atomic_lock)
+ movl 4(%esp), %ecx
+ movl $1, %eax
+ xchg %eax, (%ecx)
+ ret
+
diff --git a/lib/libpthread/man/Makefile.inc b/lib/libpthread/man/Makefile.inc
new file mode 100644
index 0000000..b4c9370
--- /dev/null
+++ b/lib/libpthread/man/Makefile.inc
@@ -0,0 +1,44 @@
+# $FreeBSD$
+
+# POSIX thread man files
+
+.PATH: ${.CURDIR}/man
+
+MAN3+= pthread_cleanup_pop.3 \
+ pthread_cleanup_push.3 \
+ pthread_cond_broadcast.3 \
+ pthread_cond_destroy.3 \
+ pthread_cond_init.3 \
+ pthread_cond_signal.3 \
+ pthread_cond_timedwait.3 \
+ pthread_cond_wait.3 \
+ pthread_cancel.3 \
+ pthread_create.3 \
+ pthread_detach.3 \
+ pthread_equal.3 \
+ pthread_exit.3 \
+ pthread_getspecific.3 \
+ pthread_join.3 \
+ pthread_key_create.3 \
+ pthread_key_delete.3 \
+ pthread_mutex_destroy.3 \
+ pthread_mutex_init.3 \
+ pthread_mutex_lock.3 \
+ pthread_mutex_trylock.3 \
+ pthread_mutex_unlock.3 \
+ pthread_once.3 \
+ pthread_rwlock_destroy.3 \
+ pthread_rwlock_init.3 \
+ pthread_rwlock_rdlock.3 \
+ pthread_rwlock_unlock.3 \
+ pthread_rwlock_wrlock.3 \
+ pthread_rwlockattr_destroy.3 \
+ pthread_rwlockattr_getpshared.3 \
+ pthread_rwlockattr_init.3 \
+ pthread_rwlockattr_setpshared.3 \
+ pthread_self.3 \
+ pthread_setspecific.3 \
+ pthread_testcancel.3
+
+MLINKS+= pthread_cancel.3 pthread_setcancelstate.3 \
+ pthread_cancel.3 pthread_getcancelstate.3
diff --git a/lib/libpthread/man/pthread_cancel.3 b/lib/libpthread/man/pthread_cancel.3
new file mode 100644
index 0000000..5d02554
--- /dev/null
+++ b/lib/libpthread/man/pthread_cancel.3
@@ -0,0 +1,73 @@
+.\" $FreeBSD$
+.Dd January 17, 1999
+.Dt PTHREAD_CANCEL 3
+.Os
+.Sh NAME
+.Nm pthread_cancel
+.Nd cancel execution of a thread
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cancel "pthread_t thread"
+.Sh DESCRIPTION
+The
+.Fn pthread_cancel
+function requests that
+.Fa thread
+be canceled. The target thread's cancelability state and type determines
+when the cancellation takes effect. When the cancellation is acted on,
+the cancellation cleanup handlers for
+.Fa thread
+are called. When the last cancellation cleanup handler returns,
+the thread-specific data destructor functions will be called for
+.Fa thread .
+When the last destructor function returns,
+.Fa thread
+will be terminated.
+.Pp
+The cancellation processing in the target thread runs asynchronously with
+respect to the calling thread returning from
+.Fn pthread_cancel .
+.Pp
+A status of
+.Dv PTHREAD_CANCELED
+is made available to any threads joining with the target. The symbolic
+constant
+.Dv PTHREAD_CANCELED
+expands to a constant expression of type
+.Ft "(void *)" ,
+whose value matches no pointer to an object in memory nor the value
+.Dv NULL .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cancel
+functions will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_cancel
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ESRCH
+No thread could be found corresponding to that specified by the given
+thread ID.
+.El
+.Sh SEE ALSO
+.Xr pthread_cleanup_pop 3 ,
+.Xr pthread_cleanup_push 3 ,
+.Xr pthread_exit 3 ,
+.Xr pthread_join 3 ,
+.Xr pthread_setcancelstate 3 ,
+.Xr pthread_setcanceltype 3 ,
+.Xr pthread_testcancel 3
+.Sh STANDARDS
+.Fn pthread_cancel
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
+.Sh AUTHORS
+This man page was written by
+.An David Leonard Aq d@openbsd.org
+for the
+.Ox
+implementation of
+.Fn pthread_cancel .
diff --git a/lib/libpthread/man/pthread_cleanup_pop.3 b/lib/libpthread/man/pthread_cleanup_pop.3
new file mode 100644
index 0000000..faae8ba
--- /dev/null
+++ b/lib/libpthread/man/pthread_cleanup_pop.3
@@ -0,0 +1,62 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 30, 1998
+.Dt PTHREAD_CLEANUP_POP 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cleanup_pop
+.Nd call the first cleanup routine
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft void
+.Fn pthread_cleanup_pop "int execute"
+.Sh DESCRIPTION
+The
+.Fn pthread_cleanup_pop
+function pops the top cleanup routine off of the current threads cleanup
+routine stack, and, if
+.Fa execute
+is non-zero, it will execute the function. If there is no cleanup routine
+then
+.Fn pthread_cleanup_pop
+does nothing.
+.Sh RETURN VALUES
+.Fn pthread_cleanup_pop
+does not return any value.
+.Sh ERRORS
+None
+.Sh SEE ALSO
+.Xr pthread_cleanup_push 3 ,
+.Xr pthread_exit 3
+.Sh STANDARDS
+.Fn pthread_cleanup_pop
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_cleanup_push.3 b/lib/libpthread/man/pthread_cleanup_push.3
new file mode 100644
index 0000000..4f260af
--- /dev/null
+++ b/lib/libpthread/man/pthread_cleanup_push.3
@@ -0,0 +1,65 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 30, 1998
+.Dt PTHREAD_CLEANUP_PUSH 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cleanup_push
+.Nd add a cleanup function for thread exit
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft void
+.Fn pthread_cleanup_push "void (*cleanup_routine)(void *)" "void *arg"
+.Sh DESCRIPTION
+The
+.Fn pthread_cleanup_push
+function adds
+.Fa cleanup_routine
+to the top of the stack of cleanup handlers that
+get called when the current thread exits.
+.Pp
+When
+.Fn pthread_cleanup_push
+is called, it is passed
+.Fa arg
+as its only argument.
+.Sh RETURN VALUES
+.Fn pthread_cleanup_push
+does not return any value.
+.Sh ERRORS
+None
+.Sh SEE ALSO
+.Xr pthread_cleanup_pop 3 ,
+.Xr pthread_exit 3
+.Sh STANDARDS
+.Fn pthread_cleanup_push
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_cond_broadcast.3 b/lib/libpthread/man/pthread_cond_broadcast.3
new file mode 100644
index 0000000..6112695
--- /dev/null
+++ b/lib/libpthread/man/pthread_cond_broadcast.3
@@ -0,0 +1,70 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1998
+.Dt PTHREAD_COND_BROADCAST 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cond_broadcast
+.Nd unblock all threads waiting for a condition variable
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cond_broadcast "pthread_cond_t *cond"
+.Sh DESCRIPTION
+The
+.Fn pthread_cond_broadcast
+function unblocks all threads waiting for the condition variable
+.Fa cond .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cond_broadcast
+function will return zero, otherwise an error number will be returned
+to indicate the error.
+.Sh ERRORS
+.Fn pthread_cond_broadcast
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa cond
+is invalid.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_cond_destroy 3 ,
+.Xr pthread_cond_init 3 ,
+.Xr pthread_cond_signal 3 ,
+.Xr pthread_cond_timedwait 3 ,
+.Xr pthread_cond_wait 3
+.Sh STANDARDS
+.Fn pthread_cond_broadcast
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_cond_destroy.3 b/lib/libpthread/man/pthread_cond_destroy.3
new file mode 100644
index 0000000..a9c4a9d
--- /dev/null
+++ b/lib/libpthread/man/pthread_cond_destroy.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1998
+.Dt PTHREAD_COND_DESTROY 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cond_destroy
+.Nd destroy a condition variable
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cond_destroy "pthread_cond_t *cond"
+.Sh DESCRIPTION
+The
+.Fn pthread_cond_destroy
+function frees the resources allocated by the condition variable
+.Fa cond .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cond_destroy
+function will return zero, otherwise an error number will be returned
+to indicate the error.
+.Sh ERRORS
+.Fn pthread_cond_destroy
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa cond
+is invalid.
+.It Bq Er EBUSY
+The variable
+.Fa cond
+is locked by another thread.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_cond_broadcast 3 ,
+.Xr pthread_cond_init 3 ,
+.Xr pthread_cond_signal 3 ,
+.Xr pthread_cond_timedwait 3 ,
+.Xr pthread_cond_wait 3
+.Sh STANDARDS
+.Fn pthread_cond_destroy
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_cond_init.3 b/lib/libpthread/man/pthread_cond_init.3
new file mode 100644
index 0000000..2783672
--- /dev/null
+++ b/lib/libpthread/man/pthread_cond_init.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1998
+.Dt PTHREAD_COND_INIT 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cond_init
+.Nd create a condition variable
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cond_init "pthread_cond_t *cond" "const pthread_condattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_cond_init
+function creates a new condition variable, with attributes specified with
+.Fa attr .
+If
+.Fa attr
+is NULL the default attributes are used.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cond_init
+function will return zero and put the new condition variable id into
+.Fa cond ,
+otherwise an error number will be returned to indicate the error.
+.Sh ERRORS
+.Fn pthread_cond_init
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.It Bq Er ENOMEM
+The process cannot allocate enough memory to create another condition
+variable.
+.It Bq Er EAGAIN
+The temporarily lacks the resources to create another condition variable.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_cond_broadcast 3 ,
+.Xr pthread_cond_destroy 3 ,
+.Xr pthread_cond_signal 3 ,
+.Xr pthread_cond_timedwait 3 ,
+.Xr pthread_cond_wait 3
+.Sh STANDARDS
+.Fn pthread_cond_init
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_cond_signal.3 b/lib/libpthread/man/pthread_cond_signal.3
new file mode 100644
index 0000000..e3a22f8
--- /dev/null
+++ b/lib/libpthread/man/pthread_cond_signal.3
@@ -0,0 +1,70 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1998
+.Dt PTHREAD_COND_SIGNAL 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cond_signal
+.Nd unblock a thread waiting for a condition variable
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cond_signal "pthread_cond_t *cond"
+.Sh DESCRIPTION
+The
+.Fn pthread_cond_signal
+function unblocks one thread waiting for the condition variable
+.Fa cond .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cond_signal
+function will return zero, otherwise an error number will be returned
+to indicate the error.
+.Sh ERRORS
+.Fn pthread_cond_signal
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa cond
+is invalid.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_cond_broadcast 3 ,
+.Xr pthread_cond_destroy 3 ,
+.Xr pthread_cond_init 3 ,
+.Xr pthread_cond_timedwait 3 ,
+.Xr pthread_cond_wait 3
+.Sh STANDARDS
+.Fn pthread_cond_signal
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_cond_timedwait.3 b/lib/libpthread/man/pthread_cond_timedwait.3
new file mode 100644
index 0000000..40cf5ec
--- /dev/null
+++ b/lib/libpthread/man/pthread_cond_timedwait.3
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1998
+.Dt PTHREAD_COND_TIMEDWAIT 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cond_timedwait
+.Nd wait on a condition variable for a specific amount of time
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cond_timedwait "pthread_cond_t *cond" "pthread_mutex_t *mutex" "const struct timespec *abstime"
+.Sh DESCRIPTION
+The
+.Fn pthread_cond_timedwait
+function atomically blocks the current thread waiting on the condition
+variable specified by
+.Fa cond ,
+and unblocks the mutex specified by
+.Fa mutex .
+The waiting thread unblocks only after another thread calls
+.Xr pthread_cond_signal 3 ,
+or
+.Xr pthread_cond_broadcast 3
+with the same condition variable, or if the system time reaches the
+time specified in
+.Fa abstime ,
+and the current thread requires the lock on
+.Fa mutex .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cond_timedwait
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_cond_timedwait
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa cond ,
+.Fa mutex
+or
+.Fa abstime
+is invalid.
+.It Bq Er ETIMEDOUT
+The system time has reached or exceeded the time specified in
+.Fa abstime .
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_cond_broadcast 3 ,
+.Xr pthread_cond_destroy 3 ,
+.Xr pthread_cond_init 3 ,
+.Xr pthread_cond_signal 3 ,
+.Xr pthread_cond_wait 3
+.Sh STANDARDS
+.Fn pthread_cond_timedwait
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_cond_wait.3 b/lib/libpthread/man/pthread_cond_wait.3
new file mode 100644
index 0000000..7e6da6c
--- /dev/null
+++ b/lib/libpthread/man/pthread_cond_wait.3
@@ -0,0 +1,81 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 28, 1998
+.Dt PTHREAD_COND_WAIT 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_cond_wait
+.Nd wait on a condition variable
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_cond_wait "pthread_cond_t *cond" "pthread_mutex_t *mutex"
+.Sh DESCRIPTION
+The
+.Fn pthread_cond_wait
+function atomically blocks the current thread waiting on the condition
+variable specified by
+.Fa cond ,
+and unblocks the mutex specified by
+.Fa mutex .
+The waiting thread unblocks only after another thread calls
+.Xr pthread_cond_signal 3 , or
+.Xr pthread_cond_broadcast 3
+with the same condition variable, and the current thread requires the lock
+on
+.Fa mutex .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_cond_wait
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_cond_wait
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa cond
+or the value specified by
+.Fa mutex
+is invalid.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_cond_broadcast 3 ,
+.Xr pthread_cond_destroy 3 ,
+.Xr pthread_cond_init 3 ,
+.Xr pthread_cond_signal 3 ,
+.Xr pthread_cond_timedwait 3
+.Sh STANDARDS
+.Fn pthread_cond_wait
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_create.3 b/lib/libpthread/man/pthread_create.3
new file mode 100644
index 0000000..cdc28a5
--- /dev/null
+++ b/lib/libpthread/man/pthread_create.3
@@ -0,0 +1,114 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_CREATE 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_create
+.Nd create a new thread
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_create "pthread_t *thread" "const pthread_attr_t *attr" "void *(*start_routine)(void *)" "void *arg"
+.Sh DESCRIPTION
+The
+.Fn pthread_create
+function is used to create a new thread, with attributes specified by
+.Fa attr ,
+within a process. If
+.Fa attr
+is NULL, the default attributes are used. If the attributes specified by
+.Fa attr
+are modified later, the thread's attributes are not affected. Upon
+successful completion
+.Fn pthread_create
+will store the ID of the created thread in the location specified by
+.Fa thread .
+.Pp
+The thread is created executing
+.Fa start_routine
+with
+.Fa arg
+as its sole argument. If the
+.Fa start_routine
+returns, the effect is as if there was an implicit call to
+.Fn pthread_exit
+using the return value of
+.Fa start_routine
+as the exit status. Note that the thread in which
+.Fn main
+was originally invoked differs from this. When it returns from
+.Fn main ,
+the effect is as if there was an implicit call to
+.Fn exit
+using the return value of
+.Fn main
+as the exit status.
+.Pp
+The signal state of the new thread is initialized as:
+.Bl -bullet -offset indent
+.It
+The signal mask is inherited from the creating thread.
+.It
+The set of signals pending for the new thread is empty.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_create
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_create
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The system lacked the necessary resources to create another thread, or
+the system-imposed limit on the total number of threads in a process
+[PTHREAD_THREADS_MAX] would be exceeded.
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr fork 2 ,
+.Xr pthread_cleanup_pop 3 ,
+.Xr pthread_cleanup_push 3 ,
+.Xr pthread_exit 3 ,
+.Xr pthread_join 3
+.Sh STANDARDS
+.Fn pthread_create
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_detach.3 b/lib/libpthread/man/pthread_detach.3
new file mode 100644
index 0000000..a3fffc6
--- /dev/null
+++ b/lib/libpthread/man/pthread_detach.3
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1996-1998 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_DETACH 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_detach
+.Nd detach a thread
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_detach "pthread_t thread"
+.Sh DESCRIPTION
+The
+.Fn pthread_detach
+function is used to indicate to the implementation that storage for the
+thread
+.Fa thread
+can be reclaimed when the thread terminates. If
+.Fa thread
+has not terminated,
+.Fn pthread_detach
+will not cause it to terminate. The effect of multiple
+.Fn pthread_detach
+calls on the same target thread is unspecified.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_detach
+function will return zero. Otherwise an error number will be returned to
+indicate the error. Note that the function does not change the value
+of errno as it did for some drafts of the standard. These early drafts
+also passed a pointer to pthread_t as the argument. Beware!
+.Sh ERRORS
+.Fn pthread_detach
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The implementation has detected that the value specified by
+.Fa thread
+does not refer to a joinable thread.
+.It Bq Er ESRCH
+No thread could be found corresponding to that specified by the given
+thread ID,
+.Fa thread .
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_join 3
+.Sh STANDARDS
+.Fn pthread_detach
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_equal.3 b/lib/libpthread/man/pthread_equal.3
new file mode 100644
index 0000000..5d443b3
--- /dev/null
+++ b/lib/libpthread/man/pthread_equal.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_EQUAL 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_equal
+.Nd compare thread IDs
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_equal "pthread_t t1" "pthread_t t2"
+.Sh DESCRIPTION
+The
+.Fn pthread_equal
+function compares the thread IDs
+.Fa t1
+and
+.Fa t2 .
+.Sh RETURN VALUES
+The
+.Fn pthread_equal
+function will non-zero if the thread IDs
+.Fa t1
+and
+.Fa t2
+correspond to the same thread, otherwise it will return zero.
+.Sh ERRORS
+None.
+.Pp
+.Sh SEE ALSO
+.Xr pthread_create 3 ,
+.Xr pthread_exit 3
+.Sh STANDARDS
+.Fn pthread_equal
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_exit.3 b/lib/libpthread/man/pthread_exit.3
new file mode 100644
index 0000000..ff452ca
--- /dev/null
+++ b/lib/libpthread/man/pthread_exit.3
@@ -0,0 +1,101 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_EXIT 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_exit
+.Nd terminate the calling thread
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft void
+.Fn pthread_exit "void *value_ptr"
+.Sh DESCRIPTION
+The
+.Fn pthread_exit
+function terminates the calling thread and makes the value
+.Fa value_ptr
+available to any successful join with the terminating thread. Any
+cancellation cleanup handlers that have been pushed and are not yet popped
+are popped in the reverse order that they were pushed and then executed.
+After all cancellation handlers have been executed, if the thread has any
+thread-specific data, appropriate destructor functions are called in an
+unspecified order. Thread termination does not release any application
+visible process resources, including, but not limited to, mutexes and
+file descriptors, nor does it perform any process level cleanup
+actions, including, but not limited to, calling
+.Fn atexit
+routines that may exist.
+.Pp
+An implicit call to
+.Fn pthread_exit
+is made when a thread other than the thread in which
+.Fn main
+was first invoked returns from the start routine that was used to create
+it. The function's return value serves as the thread's exit status.
+.Pp
+The behavior of
+.Fn pthread_exit
+is undefied if called from a cancellation handler or destructor function
+that was invoked as the result of an implicit or explicit call to
+.Fn pthread_exit .
+.Pp
+After a thread has terminated, the result of access to local (auto)
+variables of the thread is undefined. Thus, references to local variables
+of the exiting thread should not be used for the
+.Fn pthread_exit
+.Fa value_ptr
+parameter value.
+.Pp
+The process will exit with an exit status of 0 after the last thread has
+been terminated. The behavior is as if the implementation called
+.Fn exit
+with a zero argument at thread termination time.
+.Pp
+.Sh RETURN VALUES
+The
+.Fn pthread_exit
+function cannot return to its caller.
+.Sh ERRORS
+None.
+.Pp
+.Sh SEE ALSO
+.Xr _exit 2 ,
+.Xr exit 3 ,
+.Xr pthread_create 3 ,
+.Xr pthread_join 3
+.Sh STANDARDS
+.Fn pthread_exit
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_getspecific.3 b/lib/libpthread/man/pthread_getspecific.3
new file mode 100644
index 0000000..a562541
--- /dev/null
+++ b/lib/libpthread/man/pthread_getspecific.3
@@ -0,0 +1,82 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_GETSPECIFIC 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_getspecific
+.Nd get a thread-specific data value
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft void *
+.Fn pthread_getspecific "pthread_key_t key"
+.Sh DESCRIPTION
+The
+.Fn pthread_getspecific
+function returns the value currently bound to the specified
+.Fa key
+on behalf of the calling thread.
+.Pp
+The effect of calling
+.Fn pthread_getspecific
+with a
+.Fa key
+value not obtained from
+.Fn pthread_key_create
+or after
+.Fa key
+has been deleted with
+.Fn pthread_key_delete
+is undefined.
+.Pp
+.Fn pthread_getspecific
+may be called from a thread-specific data destructor function.
+.Sh RETURN VALUES
+The
+.Fn pthread_getspecific
+function will return the thread-specific data value associated with the given
+.Fa key .
+If no thread-specific data value is associated with
+.Fa key ,
+then the value NULL is returned.
+.Sh ERRORS
+None.
+.Sh SEE ALSO
+.Xr pthread_key_create 3 ,
+.Xr pthread_key_delete 3 ,
+.Xr pthread_setspecific 3
+.Sh STANDARDS
+.Fn pthread_getspecific
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_join.3 b/lib/libpthread/man/pthread_join.3
new file mode 100644
index 0000000..e32ad40
--- /dev/null
+++ b/lib/libpthread/man/pthread_join.3
@@ -0,0 +1,102 @@
+.\" Copyright (c) 1996-1998 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_JOIN 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_join
+.Nd wait for thread termination
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_join "pthread_t thread" "void **value_ptr"
+.Sh DESCRIPTION
+The
+.Fn pthread_join
+function suspends execution of the calling thread until the target
+.Fa thread
+terminates unless the target
+.Fa thread
+has already terminated.
+.Pp
+On return from a successful
+.Fn pthread_join
+call with a non-NULL
+.Fa value_ptr
+argument, the value passed to
+.Fn pthread_exit
+by the terminating thread is stored in the location referenced by
+.Fa value_ptr .
+When a
+.Fn pthread_join
+returns successfully, the target thread has been terminated. The results
+of multiple simultaneous calls to
+.Fn pthread_join
+specifying the same target thread are undefined. If the thread calling
+.Fn pthread_join
+is cancelled, then the target thread is not detached.
+.Pp
+A thread that has exited but remains unjoined counts against
+[_POSIX_THREAD_THREADS_MAX].
+.Pp
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_join
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_join
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The implementation has detected that the value specified by
+.Fa thread
+does not refer to a joinable thread.
+.It Bq Er ESRCH
+No thread could be found corresponding to that specified by the given
+thread ID,
+.Fa thread .
+.It Bq Er EDEADLK
+A deadlock was detected or the value of
+.Fa thread
+specifies the calling thread.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr wait 2 ,
+.Xr pthread_create 3
+.Sh STANDARDS
+.Fn pthread_join
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_key_create.3 b/lib/libpthread/man/pthread_key_create.3
new file mode 100644
index 0000000..76fc187
--- /dev/null
+++ b/lib/libpthread/man/pthread_key_create.3
@@ -0,0 +1,100 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_KEY_CREATE 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_key_create
+.Nd thread-specific data key creation
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_key_create "pthread_key_t *key" "void (*destructor)(void *)"
+.Sh DESCRIPTION
+The
+.Fn pthread_key_create
+function creates a thread-specific data key visible to all threads in the
+process. Key values provided by
+.Fn pthread_key_create
+are opaque objects used to locate thread-specific data. Although the same
+key value may be used by different threads, the values bound to the key
+by
+.Fn pthread_setspecific
+are maintained on a per-thread basis and persist for the life of the calling
+thread.
+.Pp
+Upon key creation, the value NULL is associated with the new key in all
+active threads. Upon thread creation, the value NULL is associated with all
+defined keys in the new thread.
+.Pp
+An optional destructor function may be associated with each key value. At
+thread exit, if a key value has a non-NULL destructor pointer, and the
+thread has a non-NULL value associated with the key, the function pointed
+to is called with the current associated value as its sole argument. The
+order of destructor calls is unspecified if more than one destructor exists
+for a thread when it exits.
+.Pp
+If, after all the destructors have been called for all non-NULL values
+with associated destructors, there are still some non-NULL values with
+associated destructors, then the process is repeated. If, after at least
+[PTHREAD_DESTRUCTOR_ITERATIONS] iterations of destructor calls for
+outstanding non-NULL values, there are still some non-NULL values with
+associated destructors, the implementation stops calling destructors.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_key_create
+function will store the newly created key value at the location specified by
+.Fa key
+and returns zero. Otherwise an error number will be returned to indicate
+the error.
+.Sh ERRORS
+.Fn pthread_key_create
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The system lacked the necessary resources to create another thread-specific
+data key, or the system-imposed limit on the total number of keys per process
+[PTHREAD_KEYS_MAX] would be exceeded.
+.It Bq Er ENOMEM
+Insufficient memory exists to create the key.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_getspecific 3 ,
+.Xr pthread_key_delete 3 ,
+.Xr pthread_setspecific 3
+.Sh STANDARDS
+.Fn pthread_key_create
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_key_delete.3 b/lib/libpthread/man/pthread_key_delete.3
new file mode 100644
index 0000000..39fb19e
--- /dev/null
+++ b/lib/libpthread/man/pthread_key_delete.3
@@ -0,0 +1,94 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_KEY_DELETE 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_key_delete
+.Nd delete a thread-specific data key
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_key_delete "pthread_key_t key"
+.Sh DESCRIPTION
+The
+.Fn pthread_key_delete
+function deletes a thread-specific data key previously returned by
+.Fn pthread_key_create .
+The thread-specific data values associated with
+.Fa key
+need not be NULL at the time that
+.Fn pthread_key_delete
+is called. It is the responsibility of the application to free any
+application storage or perform any cleanup actions for data structures
+related to the deleted key or associated thread-specific data in any threads;
+this cleanup can be done either before or after
+.Fn pthread_key_delete
+is called. Any attempt to use
+.Fa key
+following the call to
+.Fn pthread_key_delete
+results in undefined behavior.
+.Pp
+The
+.Fn pthread_key_delete
+function is callable from within destructor functions. Destructor functions
+are not invoked by
+.Fn pthread_key_delete .
+Any destructor function that may have been associated with
+.Fa key
+will no longer be called upon thread exit.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_key_delete
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_key_delete
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa key
+value is invalid.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_getspecific 3 ,
+.Xr pthread_key_create 3 ,
+.Xr pthread_setspecific 3
+.Sh STANDARDS
+.Fn pthread_key_delete
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_mutex_destroy.3 b/lib/libpthread/man/pthread_mutex_destroy.3
new file mode 100644
index 0000000..517d6eb
--- /dev/null
+++ b/lib/libpthread/man/pthread_mutex_destroy.3
@@ -0,0 +1,72 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 29, 1998
+.Dt PTHREAD_MUTEX_DESTROY 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_mutex_destroy
+.Nd free resources allocated for a mutex
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_mutex_destroy "pthread_mutex_t *mutex"
+.Sh DESCRIPTION
+The
+.Fn pthread_mutex_destroy
+function frees the resources allocated for
+.Fa mutex .
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_mutex_destroy
+will return zero, otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_mutex_destroy
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa mutex
+is invalid.
+.It Bq Er EBUSY
+.Fa Mutex
+is locked by another thread.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_mutex_init 3 ,
+.Xr pthread_mutex_lock 3 ,
+.Xr pthread_mutex_trylock 3 ,
+.Xr pthread_mutex_unlock 3
+.Sh STANDARDS
+.Fn pthread_mutex_destroy
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_mutex_init.3 b/lib/libpthread/man/pthread_mutex_init.3
new file mode 100644
index 0000000..926b034
--- /dev/null
+++ b/lib/libpthread/man/pthread_mutex_init.3
@@ -0,0 +1,77 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 29, 1998
+.Dt PTHREAD_MUTEX_INIT 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_mutex_init
+.Nd create a mutex
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_mutex_init "pthread_mutex_t *mutex" "const pthread_mutexattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_mutex_init
+function creates a new mutex, with attributes specified with
+.Fa attr .
+If
+.Fa attr
+is NULL the default attributes are used.
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_mutex_init
+will return zero and put the new mutex id into
+.Fa mutex ,
+otherwise an error number will be returned to indicate the error.
+.Sh ERRORS
+.Fn pthread_mutex_init
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.It Bq Er ENOMEM
+The process cannot allocate enough memory to create another mutex.
+.It Bq Er EAGAIN
+The temporarily lacks the resources to create another mutex.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_mutex_destroy 3 ,
+.Xr pthread_mutex_lock 3 ,
+.Xr pthread_mutex_trylock 3 ,
+.Xr pthread_mutex_unlock 3
+.Sh STANDARDS
+.Fn pthread_mutex_init
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_mutex_lock.3 b/lib/libpthread/man/pthread_mutex_lock.3
new file mode 100644
index 0000000..3647373
--- /dev/null
+++ b/lib/libpthread/man/pthread_mutex_lock.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 30, 1998
+.Dt PTHREAD_MUTEX_LOCK 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_mutex_lock
+.Nd lock a mutex
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_mutex_lock "pthread_mutex_t *mutex"
+.Sh DESCRIPTION
+The
+.Fn pthread_mutex_lock
+function locks
+.Fa mutex .
+If the mutex is already locked, the calling thread will block until the
+mutex becomes available.
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_mutex_lock
+will return zero, otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_mutex_lock
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa mutex
+is invalid.
+.It Bq Er EDEADLK
+A deadlock would occur if the thread blocked waiting for
+.Fa mutex .
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_mutex_destroy 3 ,
+.Xr pthread_mutex_init 3 ,
+.Xr pthread_mutex_trylock 3 ,
+.Xr pthread_mutex_unlock 3
+.Sh STANDARDS
+.Fn pthread_mutex_lock
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_mutex_trylock.3 b/lib/libpthread/man/pthread_mutex_trylock.3
new file mode 100644
index 0000000..30faaa8
--- /dev/null
+++ b/lib/libpthread/man/pthread_mutex_trylock.3
@@ -0,0 +1,75 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 30, 1998
+.Dt PTHREAD_MUTEX_TRYLOCK 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_mutex_trylock
+.Nd attempt to lock a mutex without blocking
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_mutex_trylock "pthread_mutex_t *mutex"
+.Sh DESCRIPTION
+The
+.Fn pthread_mutex_trylock
+function locks
+.Fa mutex .
+If the mutex is already locked,
+.Fn pthread_mutex_trylock
+will not block waiting for the mutex, but will return an error condition.
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_mutex_trylock
+will return zero, otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_mutex_trylock
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa mutex
+is invalid.
+.It Bq Er EBUSY
+.Fa Mutex
+is already locked.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_mutex_destroy 3 ,
+.Xr pthread_mutex_init 3 ,
+.Xr pthread_mutex_lock 3 ,
+.Xr pthread_mutex_unlock 3
+.Sh STANDARDS
+.Fn pthread_mutex_trylock
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_mutex_unlock.3 b/lib/libpthread/man/pthread_mutex_unlock.3
new file mode 100644
index 0000000..27a4c33
--- /dev/null
+++ b/lib/libpthread/man/pthread_mutex_unlock.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 30, 1998
+.Dt PTHREAD_MUTEX_UNLOCK 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_mutex_unlock
+.Nd unlock a mutex
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_mutex_unlock "pthread_mutex_t *mutex"
+.Sh DESCRIPTION
+If the current thread holds the lock on
+.Fa mutex ,
+then the
+.Fn pthread_mutex_unlock
+function unlocks
+.Fa mutex .
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_mutex_unlock
+will return zero, otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_mutex_trylock
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa mutex
+is invalid.
+.It Bq Er EPERM
+The current thread does not hold a lock on
+.Fa mutex .
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_mutex_destroy 3 ,
+.Xr pthread_mutex_init 3 ,
+.Xr pthread_mutex_lock 3 ,
+.Xr pthread_mutex_trylock 3
+.Sh STANDARDS
+.Fn pthread_mutex_unlock
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_once.3 b/lib/libpthread/man/pthread_once.3
new file mode 100644
index 0000000..2dcea49
--- /dev/null
+++ b/lib/libpthread/man/pthread_once.3
@@ -0,0 +1,102 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_ONCE 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_once
+.Nd dynamic package initialization
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Pp
+pthread_once
+.Fa once_control
+= PTHREAD_ONCE_INIT;
+.Ft int
+.Fn pthread_once "pthread_once_t *once_control" "void (*init_routine)(void)"
+.Sh DESCRIPTION
+The first call to
+.Fn pthread_once
+by any thread in a process, with a given
+.Fa once_control ,
+will call the
+.Fn init_routine
+with no arguments. Subsequent calls to
+.Fn pthread_once
+with the same
+.Fa once_control
+will not call the
+.Fn init_routine .
+On return from
+.Fn pthread_once ,
+it is guaranteed that
+.Fn init_routine
+has completed. The
+.Fa once_control
+parameter is used to determine whether the associated initialization
+routine has been called.
+.Pp
+The function
+.Fn pthread_once
+is not a cancellation point. However, if
+.Fn init_routine
+is a cancellation point and is cancelled, the effect on
+.Fa once_control is as if
+.Fn pthread_once
+was never called.
+.Pp
+The constant
+.Fa PTHREAD_ONCE_INIT
+is defined by header
+.Aq Pa pthread.h .
+.Pp
+The behavior of
+.Fn pthread_once
+is undefined if
+.Fa once_control
+has automatic storage duration or is not initialized by
+.Fa PTHREAD_ONCE_INIT .
+.Pp
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_once
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+None.
+.Pp
+.Sh STANDARDS
+.Fn pthread_once
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_rwlock_destroy.3 b/lib/libpthread/man/pthread_rwlock_destroy.3
new file mode 100644
index 0000000..14691c4
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlock_destroy.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_DESTROY 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_destroy
+.Nd destroy a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_destroy "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_destroy
+function is used to destroy a read/write lock previously created with
+.Fn pthread_rwlock_init .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_destroy
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_destroy
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_destroy
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The caller does not have the privilege to perform the operation.
+.El
+.Pp
+The
+.Fn pthread_rwlock_destroy
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The system has detected an attempt to destroy the object referenced by
+.Fa lock
+while it is locked.
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_destroy
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlock_init.3 b/lib/libpthread/man/pthread_rwlock_init.3
new file mode 100644
index 0000000..306af61
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlock_init.3
@@ -0,0 +1,99 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_INIT 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_init
+.Nd initialize a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_init "pthread_rwlock_t *lock" "const pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_init
+function is used to initialize a read/write lock, with attributes
+specified by
+.Fa attr .
+If
+.Fa attr
+is NULL, the default read/write lock attributes are used.
+.Pp
+The results of calling
+.Fn pthread_rwlock_init
+with an already initialized lock are undefined.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_init
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_destroy 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_init
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_init
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The system lacked the necessary resources (other than memory) to
+initialize the lock.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock.
+.It Bq Er EPERM
+The caller does not have sufficient privilege to perform the
+operation.
+.El
+.Pp
+The
+.Fn pthread_rwlock_init
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The system has detected an attempt to re-initialize the object
+referenced by
+.Fa lock ,
+a previously initialized but not yet destroyed read/write lock.
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_init
+function first appeared in
+.Fx 3.0 .
+.Sh BUGS
+The PTHREAD_PROCESS_SHARED attribute is not supported.
diff --git a/lib/libpthread/man/pthread_rwlock_rdlock.3 b/lib/libpthread/man/pthread_rwlock_rdlock.3
new file mode 100644
index 0000000..bea219d
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlock_rdlock.3
@@ -0,0 +1,122 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_RDLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_rdlock ,
+.Nm pthread_rwlock_tryrdlock
+.Nd acquire a read/write lock for reading
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_rdlock "pthread_rwlock_t *lock"
+.Ft int
+.Fn pthread_rwlock_tryrdlock "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_rdlock
+function acquires a read lock on
+.Fa lock
+provided that
+.Fa lock
+is not presently held for writing and no writer threads are
+presently blocked on the lock. If the read lock cannot be
+immediately acquired, the calling thread blocks until it can
+acquire the lock.
+.Pp
+The
+.Fn pthread_rwlock_tryrdlock
+function performs the same action, but does not block if the lock
+cannot be immediately obtained (i.e. the lock is held for writing
+or there are waiting writers).
+.Pp
+A thread may hold multiple concurrent read locks. If so,
+.Fn pthread_rwlock_unlock
+must be called once for each lock obtained.
+.Pp
+The results of acquiring a read lock while the calling thread holds
+a write lock are undefined.
+.Sh IMPLEMENTATION NOTES
+To prevent writer starvation, writers are favored over readers.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlock_trywrlock 3 ,
+.Xr pthread_rwlock_unlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions are expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_tryrdlock
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The lock could not be acquired because a writer holds the lock or
+was blocked on it.
+.El
+.Pp
+The
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The lock could not be acquired because the maximum number of read locks
+against
+.Fa lock
+has been exceeded.
+.It Bq Er EDEADLK
+The current thread already owns
+.Fa lock
+for writing.
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock (applies to
+statically initialized locks only).
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_rdlock
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlock_unlock.3 b/lib/libpthread/man/pthread_rwlock_unlock.3
new file mode 100644
index 0000000..7ad52b2
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlock_unlock.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_UNLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_unlock
+.Nd release a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_unlock "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_unlock
+function is used to release the read/write lock previously obtained by
+.Fn pthread_rwlock_rdlock ,
+.Fn pthread_rwlock_wrlock ,
+.Fn pthread_rwlock_tryrdlock ,
+or
+.Fn pthread_rwlock_trywrlock .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_unlock
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Pp
+The results are undefined if
+.Fa lock
+is not held by the calling thread.
+.Sh SEE ALSO
+.Xr pthread_rwlock_rdlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_unlock
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_unlock
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er EPERM
+The current thread does not own the read/write lock.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_unlock
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlock_wrlock.3 b/lib/libpthread/man/pthread_rwlock_wrlock.3
new file mode 100644
index 0000000..b6a2312
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlock_wrlock.3
@@ -0,0 +1,102 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_WRLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_wrlock ,
+.Nm pthread_rwlock_trywrlock
+.Nd acquire a read/write lock for writing
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_wrlock "pthread_rwlock_t *lock"
+.Ft int
+.Fn pthread_rwlock_trywrlock "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_wrlock
+function blocks until a write lock can be acquired against
+.Fa lock .
+The
+.Fn pthread_rwlock_trywrlock
+function performs the same action, but does not block if the lock
+cannot be immediately obtained.
+.Pp
+The results are undefined if the calling thread already holds the
+lock at the time the call is made.
+.Sh IMPLEMENTATION NOTES
+To prevent writer starvation, writers are favored over readers.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_trywrlock 3 ,
+.Xr pthread_rwlock_unlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions are expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_trywrlock
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The calling thread is not able to acquire the lock without blocking.
+.El
+.Pp
+The
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EDEADLK
+The calling thread already owns the read/write lock (for reading
+or writing).
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock (applies to
+statically initialized locks only).
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_wrlock
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlockattr_destroy.3 b/lib/libpthread/man/pthread_rwlockattr_destroy.3
new file mode 100644
index 0000000..2d67041
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlockattr_destroy.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_DESTROY 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_destroy
+.Nd destroy a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_destroy "pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_destroy
+function is used to destroy a read/write lock attribute object
+previously created with
+.Fn pthread_rwlockattr_init .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_destroy
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlockattr_init 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_destroy
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_destroy
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_destroy
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlockattr_getpshared.3 b/lib/libpthread/man/pthread_rwlockattr_getpshared.3
new file mode 100644
index 0000000..d2028dc
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlockattr_getpshared.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 22, 1999
+.Dt PTHREAD_RWLOCKATTR_GETPSHARED 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_getpshared
+.Nd get the process shared attribute
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_getpshared "const pthread_rwlockattr_t *attr" "int *pshared"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_getpshared
+function is used to get the process shared setting of a read/write
+lock attribute object. The setting is returned via
+.Fa pshared ,
+and may be one of two values:
+.Bl -hang -offset flag -width 123456789012345678901234
+.It Ar PTHREAD_PROCESS_SHARED
+Any thread of any process that has access to the memory where the
+read/write lock resides can manipulate the lock.
+.It Ar PTHREAD_PROCESS_PRIVATE
+Only threads created within the same process as the thread that
+initialized the read/write lock can manipulate the lock. This is
+the default value.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_getpshared
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_getpshared
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_getpshared
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_getpshared
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlockattr_init.3 b/lib/libpthread/man/pthread_rwlockattr_init.3
new file mode 100644
index 0000000..ac19126
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlockattr_init.3
@@ -0,0 +1,67 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_INIT 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_init
+.Nd initialize a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_init "pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_init
+function is used to initialize a read/write lock attributes object.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_init
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_destroy 3 ,
+.Xr pthread_rwlockattr_getpshared 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_init
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_init
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the attribute object.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_init
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlockattr_setpshared.3 b/lib/libpthread/man/pthread_rwlockattr_setpshared.3
new file mode 100644
index 0000000..b98e081
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlockattr_setpshared.3
@@ -0,0 +1,86 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_SETPSHARED 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_setpshared
+.Nd set the process shared attribute
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_setpshared "pthread_rwlockattr_t *attr" "int *pshared"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_setpshared
+function sets the process shared attribute of
+.Fa attr
+to the value referenced by
+.Fa pshared .
+.Fa pshared
+may be one of two values:
+.Bl -hang -offset flag -width 123456789012345678901234
+.It Ar PTHREAD_PROCESS_SHARED
+Any thread of any process that has access to the memory where the
+read/write lock resides can manipulate the lock.
+.It Ar PTHREAD_PROCESS_PRIVATE
+Only threads created within the same process as the thread that
+initialized the read/write lock can manipulate the lock. This is
+the default value.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_setpshared
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_setpshared
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_setpshared
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+or
+.Fa pshared
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_setpshared
+function first appeared in
+.Fx 3.0 .
+.Sh BUGS
+The PTHREAD_PROCESS_SHARED attribute is not supported.
diff --git a/lib/libpthread/man/pthread_self.3 b/lib/libpthread/man/pthread_self.3
new file mode 100644
index 0000000..be524b9
--- /dev/null
+++ b/lib/libpthread/man/pthread_self.3
@@ -0,0 +1,61 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_SELF 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_self
+.Nd get the calling thread's ID
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft pthread_t
+.Fn pthread_self "void"
+.Sh DESCRIPTION
+The
+.Fn pthread_self
+function returns the thread ID of the calling thread.
+.Sh RETURN VALUES
+The
+.Fn pthread_self
+function returns the thread ID of the calling thread.
+.Sh ERRORS
+None.
+.Pp
+.Sh SEE ALSO
+.Xr pthread_create 3 ,
+.Xr pthread_equal 3
+.Sh STANDARDS
+.Fn pthread_self
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_setspecific.3 b/lib/libpthread/man/pthread_setspecific.3
new file mode 100644
index 0000000..89a416f
--- /dev/null
+++ b/lib/libpthread/man/pthread_setspecific.3
@@ -0,0 +1,93 @@
+.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by John Birrell.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 4, 1996
+.Dt PTHREAD_SETSPECIFIC 3
+.Os BSD 4
+.Sh NAME
+.Nm pthread_setspecific
+.Nd set a thread-specific data value
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_setspecific "pthread_key_t key" "const void *value"
+.Sh DESCRIPTION
+The
+.Fn pthread_setspecific
+function associates a thread-specific value with a
+.Fa key
+obtained via a previous call to
+.Fn pthread_key_create .
+Different threads man bind different values to the same key. These values are
+typically pointers to blocks of dynamically allocated memory that have been
+reserved for use by the calling thread.
+.Pp
+The effect of calling
+.Fn pthread_setspecific
+with a key value not obtained from
+.Fn pthread_key_create
+or after
+.Fa key
+has been deleted with
+.Fn pthread_key_delete
+is undefined.
+.Pp
+.Fn pthread_setspecific
+may be called from a thread-specific data destructor function, however this
+may result in lost storage or infinite loops.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_setspecific
+function will return zero. Otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_setspecific
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+Insufficient memory exists to associate the value with the
+.Fa key .
+.It Bq Er EINVAL
+The
+.Fa key
+value is invalid.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr pthread_getspecific 3 ,
+.Xr pthread_key_create 3 ,
+.Xr pthread_key_delete 3
+.Sh STANDARDS
+.Fn pthread_setspecific
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
diff --git a/lib/libpthread/man/pthread_testcancel.3 b/lib/libpthread/man/pthread_testcancel.3
new file mode 100644
index 0000000..670c47c
--- /dev/null
+++ b/lib/libpthread/man/pthread_testcancel.3
@@ -0,0 +1,187 @@
+.\" $FreeBSD$
+.Dd January 17, 1999
+.Dt PTHREAD_TESTCANCEL 3
+.Os
+.Sh NAME
+.Nm pthread_setcancelstate ,
+.Nm pthread_setcanceltype ,
+.Nm pthread_testcancel
+.Nd set cancelability state
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_setcancelstate "int state" "int *oldstate"
+.Ft int
+.Fn pthread_setcanceltype "int type" "int *oldtype"
+.Ft void
+.Fn pthread_testcancel "void"
+.Sh DESCRIPTION
+The
+.Fn pthread_setcancelstate
+function atomically both sets the calling thread's cancelability state
+to the indicated
+.Fa state
+and returns the previous cancelability state at the location referenced by
+.Fa oldstate .
+Legal values for
+.Fa state
+are
+.Dv PTHREAD_CANCEL_ENABLE
+and
+.Dv PTHREAD_CANCEL_DISABLE .
+.Pp
+The
+.Fn pthread_setcanceltype
+function atomically both sets the calling thread's cancelability type
+to the indicated
+.Fa type
+and returns the previous cancelability type at the location referenced by
+.Fa oldtype .
+Legal values for
+.Fa type
+are
+.Dv PTHREAD_CANCEL_DEFERRED
+and
+.Dv PTHREAD_CANCEL_ASYNCHRONOUS .
+.Pp
+The cancelability state and type of any newly created threads, including the
+thread in which
+.Fn main
+was first invoked, are
+.Dv PTHREAD_CANCEL_ENABLE
+and
+.Dv PTHREAD_CANCEL_DEFERRED
+respectively.
+.Pp
+The
+.Fn pthread_testcancel
+function creates a cancellation point in the calling thread. The
+.Fn pthread_testcancel
+function has no effect if cancelability is disabled.
+.Pp
+.Ss Cancelability States
+The cancelability state of a thread determines the action taken upon
+receipt of a cancellation request. The thread may control cancellation in
+a number of ways.
+.Pp
+Each thread maintains its own
+.Dq cancelability state
+which may be encoded in two bits:
+.Bl -hang
+.It Em Cancelability Enable
+When cancelability is
+.Dv PTHREAD_CANCEL_DISABLE ,
+cancellation requests against the target thread are held pending.
+.It Em Cancelability Type
+When cancelability is enabled and the cancelability type is
+.Dv PTHREAD_CANCEL_ASYNCHRONOUS ,
+new or pending cancellation requests may be acted upon at any time.
+When cancelability is enabled and the cancelability type is
+.Dv PTHREAD_CANCEL_DEFERRED ,
+cancellation requests are held pending until a cancellation point (see
+below) is reached. If cancelability is disabled, the setting of the
+cancelability type has no immediate effect as all cancellation requests
+are held pending; however, once cancelability is enabled again the new
+type will be in effect.
+.El
+.Ss Cancellation Points
+Cancellation points will occur when a thread is executing the following
+functions:
+.Fn close ,
+.Fn creat ,
+.Fn fcntl ,
+.Fn fsync ,
+.Fn msync ,
+.Fn nanosleep ,
+.Fn open ,
+.Fn pause ,
+.Fn pthread_cond_timedwait ,
+.Fn pthread_cond_wait ,
+.Fn pthread_join ,
+.Fn pthread_testcancel ,
+.Fn read ,
+.Fn sigwaitinfo ,
+.Fn sigsuspend ,
+.Fn sigwait ,
+.Fn sleep ,
+.Fn system ,
+.Fn tcdrain ,
+.Fn wait ,
+.Fn waitpid ,
+.Fn write .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_setcancelstate
+and
+.Fn pthread_setcanceltype
+functions will return zero. Otherwise, an error number shall be returned to
+indicate the error.
+.Pp
+The
+.Fn pthread_setcancelstate
+and
+.Fn pthread_setcanceltype
+functions are used to control the points at which a thread may be
+asynchronously canceled. For cancellation control to be usable in modular
+fashion, some rules must be followed.
+.Pp
+For purposes of this discussion, consider an object to be a generalization
+of a procedure. It is a set of procedures and global variables written as
+a unit and called by clients not known by the object. Objects may depend
+on other objects.
+.Pp
+First, cancelability should only be disabled on entry to an object, never
+explicitly enabled. On exit from an object, the cancelability state should
+always be restored to its value on entry to the object.
+.Pp
+This follows from a modularity argument: if the client of an object (or the
+client of an object that uses that object) has disabled cancelability, it is
+because the client doesn't want to have to worry about how to clean up if the
+thread is canceled while executing some sequence of actions. If an object
+is called in such a state and it enables cancelability and a cancellation
+request is pending for that thread, then the thread will be canceled,
+contrary to the wish of the client that disabled.
+.Pp
+Second, the cancelability type may be explicitly set to either
+.Em deferred
+or
+.Em asynchronous
+upon entry to an object. But as with the cancelability state, on exit from
+an object that cancelability type should always be restored to its value on
+entry to the object.
+.Pp
+Finally, only functions that are cancel-safe may be called from a thread that
+is asynchronously cancelable.
+.Sh ERRORS
+The function
+.Fn pthread_setcancelstate
+may fail with:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The specified state is not
+.Dv PTHREAD_CANCEL_ENABLE
+or
+.Dv PTHREAD_CANCEL_DISABLE .
+.El
+.Pp
+The function
+.Fn pthread_setcanceltype
+may fail with:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The specified state is not
+.Dv PTHREAD_CANCEL_DEFERRED
+or
+.Dv PTHREAD_CANCEL_ASYNCHRONOUS .
+.El
+.Sh SEE ALSO
+.Xr pthread_cancel 3
+.Sh STANDARDS
+.Fn pthread_testcancel
+conforms to ISO/IEC 9945-1 ANSI/IEEE
+.Pq Dq Tn POSIX
+Std 1003.1 Second Edition 1996-07-12.
+.Sh AUTHORS
+This man page was written by
+.An David Leonard <d@openbsd.org>
+for the OpenBSD implementation of pthread_cancel.
diff --git a/lib/libpthread/sys/Makefile.inc b/lib/libpthread/sys/Makefile.inc
new file mode 100644
index 0000000..e608afa
--- /dev/null
+++ b/lib/libpthread/sys/Makefile.inc
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/sys ${.CURDIR}/arch/${MACHINE_ARCH}
+
+SRCS+= uthread_error.c _atomic_lock.S
+
diff --git a/lib/libpthread/sys/thr_error.c b/lib/libpthread/sys/thr_error.c
new file mode 100644
index 0000000..0d08ae8
--- /dev/null
+++ b/lib/libpthread/sys/thr_error.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell
+ * and Chris Provenzano.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+extern int errno;
+
+int * __error()
+{
+ int *p_errno;
+ if (_thread_run == _thread_initial) {
+ p_errno = &errno;
+ } else {
+ p_errno = &_thread_run->error;
+ }
+ return(p_errno);
+}
+#endif
diff --git a/lib/libpthread/test/Makefile b/lib/libpthread/test/Makefile
new file mode 100644
index 0000000..90ee5ad
--- /dev/null
+++ b/lib/libpthread/test/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+#
+# Tests for libc_r functionality.
+#
+
+SUBDIR= mutex sigsuspend sigwait
+
+.include <bsd.subdir.mk>
diff --git a/lib/libpthread/thread/Makefile.inc b/lib/libpthread/thread/Makefile.inc
new file mode 100644
index 0000000..4697305
--- /dev/null
+++ b/lib/libpthread/thread/Makefile.inc
@@ -0,0 +1,117 @@
+# $FreeBSD$
+
+# uthread sources
+.PATH: ${.CURDIR}/uthread
+
+SRCS+= \
+ uthread_accept.c \
+ uthread_attr_destroy.c \
+ uthread_attr_init.c \
+ uthread_attr_getdetachstate.c \
+ uthread_attr_getinheritsched.c \
+ uthread_attr_getschedparam.c \
+ uthread_attr_getschedpolicy.c \
+ uthread_attr_getscope.c \
+ uthread_attr_getstackaddr.c \
+ uthread_attr_getstacksize.c \
+ uthread_attr_setcreatesuspend_np.c \
+ uthread_attr_setdetachstate.c \
+ uthread_attr_setinheritsched.c \
+ uthread_attr_setschedparam.c \
+ uthread_attr_setschedpolicy.c \
+ uthread_attr_setscope.c \
+ uthread_attr_setstackaddr.c \
+ uthread_attr_setstacksize.c \
+ uthread_autoinit.cc \
+ uthread_bind.c \
+ uthread_cancel.c \
+ uthread_clean.c \
+ uthread_close.c \
+ uthread_cond.c \
+ uthread_condattr_destroy.c \
+ uthread_condattr_init.c \
+ uthread_connect.c \
+ uthread_create.c \
+ uthread_detach.c \
+ uthread_dup.c \
+ uthread_dup2.c \
+ uthread_equal.c \
+ uthread_execve.c \
+ uthread_exit.c \
+ uthread_fchflags.c \
+ uthread_fchmod.c \
+ uthread_fchown.c \
+ uthread_fcntl.c \
+ uthread_fd.c \
+ uthread_file.c \
+ uthread_find_thread.c \
+ uthread_flock.c \
+ uthread_fork.c \
+ uthread_fstat.c \
+ uthread_fstatfs.c \
+ uthread_fsync.c \
+ uthread_gc.c \
+ uthread_getdirentries.c \
+ uthread_getpeername.c \
+ uthread_getprio.c \
+ uthread_getschedparam.c \
+ uthread_getsockname.c \
+ uthread_getsockopt.c \
+ uthread_info.c \
+ uthread_init.c \
+ uthread_ioctl.c \
+ uthread_join.c \
+ uthread_kern.c \
+ uthread_kill.c \
+ uthread_listen.c \
+ uthread_mattr_init.c \
+ uthread_mattr_kind_np.c \
+ uthread_msync.c \
+ uthread_multi_np.c \
+ uthread_mutex.c \
+ uthread_mutex_prioceiling.c \
+ uthread_mutex_protocol.c \
+ uthread_mutexattr_destroy.c \
+ uthread_nanosleep.c \
+ uthread_once.c \
+ uthread_open.c \
+ uthread_pipe.c \
+ uthread_poll.c \
+ uthread_priority_queue.c \
+ uthread_read.c \
+ uthread_readv.c \
+ uthread_recvfrom.c \
+ uthread_recvmsg.c \
+ uthread_resume_np.c \
+ uthread_rwlock.c \
+ uthread_rwlockattr.c \
+ uthread_select.c \
+ uthread_self.c \
+ uthread_sendmsg.c \
+ uthread_sendto.c \
+ uthread_seterrno.c \
+ uthread_setprio.c \
+ uthread_setschedparam.c \
+ uthread_setsockopt.c \
+ uthread_shutdown.c \
+ uthread_sig.c \
+ uthread_sigaction.c \
+ uthread_sigblock.c \
+ uthread_sigmask.c \
+ uthread_sigpending.c \
+ uthread_sigprocmask.c \
+ uthread_sigsetmask.c \
+ uthread_sigsuspend.c \
+ uthread_sigwait.c \
+ uthread_single_np.c \
+ uthread_socket.c \
+ uthread_socketpair.c \
+ uthread_spec.c \
+ uthread_spinlock.c \
+ uthread_suspend_np.c \
+ uthread_switch_np.c \
+ uthread_vfork.c \
+ uthread_wait4.c \
+ uthread_write.c \
+ uthread_writev.c \
+ uthread_yield.c
diff --git a/lib/libpthread/thread/thr_attr_destroy.c b/lib/libpthread/thread/thr_attr_destroy.c
new file mode 100644
index 0000000..dfe668e
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_destroy.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_destroy(pthread_attr_t *attr)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL)
+ /* Invalid argument: */
+ ret = EINVAL;
+ else {
+ /* Free the memory allocated to the attribute object: */
+ free(*attr);
+
+ /*
+ * Leave the attribute pointer NULL now that the memory
+ * has been freed:
+ */
+ *attr = NULL;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_getdetachstate.c b/lib/libpthread/thread/thr_attr_getdetachstate.c
new file mode 100644
index 0000000..fee1e8b
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_getdetachstate.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || detachstate == NULL)
+ ret = EINVAL;
+ else {
+ /* Check if the detached flag is set: */
+ if ((*attr)->flags & PTHREAD_DETACHED)
+ /* Return detached: */
+ *detachstate = PTHREAD_CREATE_DETACHED;
+ else
+ /* Return joinable: */
+ *detachstate = PTHREAD_CREATE_JOINABLE;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_getinheritsched.c b/lib/libpthread/thread/thr_attr_getinheritsched.c
new file mode 100644
index 0000000..7e243ed
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_getinheritsched.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_getinheritsched(const pthread_attr_t *attr, int *sched_inherit)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL))
+ ret = EINVAL;
+ else
+ *sched_inherit = (*attr)->sched_inherit;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_getschedparam.c b/lib/libpthread/thread/thr_attr_getschedparam.c
new file mode 100644
index 0000000..46586ff
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_getschedparam.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (param == NULL))
+ ret = EINVAL;
+ else
+ param->sched_priority = (*attr)->prio;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_getschedpolicy.c b/lib/libpthread/thread/thr_attr_getschedpolicy.c
new file mode 100644
index 0000000..19f835c
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_getschedpolicy.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (policy == NULL))
+ ret = EINVAL;
+ else
+ *policy = (*attr)->sched_policy;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_getscope.c b/lib/libpthread/thread/thr_attr_getscope.c
new file mode 100644
index 0000000..176f01b
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_getscope.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (contentionscope == NULL))
+ /* Return an invalid argument: */
+ ret = EINVAL;
+
+ else
+ *contentionscope = (*attr)->flags & PTHREAD_SCOPE_SYSTEM ?
+ PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_getstackaddr.c b/lib/libpthread/thread/thr_attr_getstackaddr.c
new file mode 100644
index 0000000..1fee4a5
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_getstackaddr.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || stackaddr == NULL)
+ ret = EINVAL;
+ else {
+ /* Return the stack address: */
+ *stackaddr = (*attr)->stackaddr_attr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_getstacksize.c b/lib/libpthread/thread/thr_attr_getstacksize.c
new file mode 100644
index 0000000..5c7a9e0
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_getstacksize.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || stacksize == NULL)
+ ret = EINVAL;
+ else {
+ /* Return the stack size: */
+ *stacksize = (*attr)->stacksize_attr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_init.c b/lib/libpthread/thread/thr_attr_init.c
new file mode 100644
index 0000000..dbe3091
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_init.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_init(pthread_attr_t *attr)
+{
+ int ret;
+ pthread_attr_t pattr;
+
+ /* Allocate memory for the attribute object: */
+ if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL)
+ /* Insufficient memory: */
+ ret = ENOMEM;
+ else {
+ /* Initialise the attribute object with the defaults: */
+ memcpy(pattr, &pthread_attr_default, sizeof(struct pthread_attr));
+
+ /* Return a pointer to the attribute object: */
+ *attr = pattr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_setcreatesuspend_np.c b/lib/libpthread/thread/thr_attr_setcreatesuspend_np.c
new file mode 100644
index 0000000..d230397
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_setcreatesuspend_np.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setcreatesuspend_np(pthread_attr_t *attr)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->suspend = PTHREAD_CREATE_SUSPENDED;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_setdetachstate.c b/lib/libpthread/thread/thr_attr_setdetachstate.c
new file mode 100644
index 0000000..36a846a
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_setdetachstate.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL ||
+ (detachstate != PTHREAD_CREATE_DETACHED &&
+ detachstate != PTHREAD_CREATE_JOINABLE))
+ ret = EINVAL;
+ else {
+ /* Check if detached state: */
+ if (detachstate == PTHREAD_CREATE_DETACHED)
+ /* Set the detached flag: */
+ (*attr)->flags |= PTHREAD_DETACHED;
+ else
+ /* Reset the detached flag: */
+ (*attr)->flags &= ~PTHREAD_DETACHED;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_setinheritsched.c b/lib/libpthread/thread/thr_attr_setinheritsched.c
new file mode 100644
index 0000000..eb2384b
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_setinheritsched.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setinheritsched(pthread_attr_t *attr, int sched_inherit)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL))
+ ret = EINVAL;
+ else
+ (*attr)->sched_inherit = sched_inherit;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_setschedparam.c b/lib/libpthread/thread/thr_attr_setschedparam.c
new file mode 100644
index 0000000..17b93b4
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_setschedparam.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param *param)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (param == NULL))
+ ret = EINVAL;
+ else
+ (*attr)->prio = param->sched_priority;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_setschedpolicy.c b/lib/libpthread/thread/thr_attr_setschedpolicy.c
new file mode 100644
index 0000000..640cb38
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_setschedpolicy.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) || (policy < SCHED_FIFO) ||
+ (policy > SCHED_RR))
+ ret = EINVAL;
+ else
+ (*attr)->sched_policy = policy;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_setscope.c b/lib/libpthread/thread/thr_attr_setscope.c
new file mode 100644
index 0000000..84239d7
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_setscope.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
+{
+ int ret = 0;
+
+ if ((attr == NULL) || (*attr == NULL) ||
+ (contentionscope != PTHREAD_SCOPE_PROCESS) ||
+ (contentionscope != PTHREAD_SCOPE_SYSTEM))
+ /* Return an invalid argument: */
+ ret = EINVAL;
+
+ else if (contentionscope == PTHREAD_SCOPE_SYSTEM)
+ /* We don't support system wide contention: */
+#ifdef NOT_YET
+ ret = ENOTSUP;
+#else
+ ret = EOPNOTSUPP;
+#endif
+
+ else
+ (*attr)->flags |= contentionscope;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_setstackaddr.c b/lib/libpthread/thread/thr_attr_setstackaddr.c
new file mode 100644
index 0000000..7eb8c5d
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_setstackaddr.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || stackaddr == NULL)
+ ret = EINVAL;
+ else {
+ /* Save the stack address: */
+ (*attr)->stackaddr_attr = stackaddr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_attr_setstacksize.c b/lib/libpthread/thread/thr_attr_setstacksize.c
new file mode 100644
index 0000000..2a2d854
--- /dev/null
+++ b/lib/libpthread/thread/thr_attr_setstacksize.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
+{
+ int ret;
+
+ /* Check for invalid arguments: */
+ if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN)
+ ret = EINVAL;
+ else {
+ /* Save the stack size: */
+ (*attr)->stacksize_attr = stacksize;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_cancel.c b/lib/libpthread/thread/thr_cancel.c
new file mode 100644
index 0000000..de7c491
--- /dev/null
+++ b/lib/libpthread/thread/thr_cancel.c
@@ -0,0 +1,188 @@
+/*
+ * David Leonard <d@openbsd.org>, 1999. Public domain.
+ * $FreeBSD$
+ */
+
+#include <sys/errno.h>
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_cancel(pthread_t pthread)
+{
+ int ret;
+
+ if ((ret = _find_thread(pthread)) != 0) {
+ /* NOTHING */
+ } else if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK) {
+ ret = 0;
+ } else {
+ /* Protect the scheduling queues: */
+ _thread_kern_sig_defer();
+
+ if (((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) != 0) ||
+ (((pthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) == 0) &&
+ ((pthread->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0)))
+ /* Just mark it for cancellation: */
+ pthread->cancelflags |= PTHREAD_CANCELLING;
+ else {
+ /*
+ * Check if we need to kick it back into the
+ * run queue:
+ */
+ switch (pthread->state) {
+ case PS_RUNNING:
+ /* No need to resume: */
+ pthread->cancelflags |= PTHREAD_CANCELLING;
+ break;
+
+ case PS_SPINBLOCK:
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Remove these threads from the work queue: */
+ if ((pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ != 0)
+ PTHREAD_WORKQ_REMOVE(pthread);
+ /* Fall through: */
+ case PS_SIGTHREAD:
+ case PS_SLEEP_WAIT:
+ case PS_WAIT_WAIT:
+ case PS_SIGSUSPEND:
+ case PS_SIGWAIT:
+ case PS_SUSPENDED:
+ /* Interrupt and resume: */
+ pthread->interrupted = 1;
+ pthread->cancelflags |= PTHREAD_CANCELLING;
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ break;
+
+ case PS_MUTEX_WAIT:
+ case PS_COND_WAIT:
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ case PS_JOIN:
+ /*
+ * Threads in these states may be in queues.
+ * In order to preserve queue integrity, the
+ * cancelled thread must remove itself from the
+ * queue. Mark the thread as interrupted and
+ * needing cancellation, and set the state to
+ * running. When the thread resumes, it will
+ * exit after removing itself from the queue.
+ */
+ pthread->interrupted = 1;
+ pthread->cancelflags |= PTHREAD_CANCEL_NEEDED;
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ break;
+
+ case PS_DEAD:
+ case PS_DEADLOCK:
+ case PS_STATE_MAX:
+ /* Ignore - only here to silence -Wall: */
+ break;
+ }
+ }
+
+ /* Unprotect the scheduling queues: */
+ _thread_kern_sig_undefer();
+
+ ret = 0;
+ }
+ return (ret);
+}
+
+int
+pthread_setcancelstate(int state, int *oldstate)
+{
+ int ostate;
+ int ret;
+
+ ostate = _thread_run->cancelflags & PTHREAD_CANCEL_DISABLE;
+
+ switch (state) {
+ case PTHREAD_CANCEL_ENABLE:
+ if (oldstate != NULL)
+ *oldstate = ostate;
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_DISABLE;
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)
+ pthread_testcancel();
+ ret = 0;
+ break;
+ case PTHREAD_CANCEL_DISABLE:
+ if (oldstate != NULL)
+ *oldstate = ostate;
+ _thread_run->cancelflags |= PTHREAD_CANCEL_DISABLE;
+ ret = 0;
+ break;
+ default:
+ ret = EINVAL;
+ }
+
+ return (ret);
+}
+
+int
+pthread_setcanceltype(int type, int *oldtype)
+{
+ int otype;
+ int ret;
+
+ otype = _thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS;
+ switch (type) {
+ case PTHREAD_CANCEL_ASYNCHRONOUS:
+ if (oldtype != NULL)
+ *oldtype = otype;
+ _thread_run->cancelflags |= PTHREAD_CANCEL_ASYNCHRONOUS;
+ pthread_testcancel();
+ ret = 0;
+ break;
+ case PTHREAD_CANCEL_DEFERRED:
+ if (oldtype != NULL)
+ *oldtype = otype;
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_ASYNCHRONOUS;
+ ret = 0;
+ break;
+ default:
+ ret = EINVAL;
+ }
+
+ return (ret);
+}
+
+void
+pthread_testcancel(void)
+{
+ if (((_thread_run->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) &&
+ ((_thread_run->cancelflags & PTHREAD_CANCELLING) != 0)) {
+ /*
+ * It is possible for this thread to be swapped out
+ * while performing cancellation; do not allow it
+ * to be cancelled again.
+ */
+ _thread_run->cancelflags &= ~PTHREAD_CANCELLING;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ PANIC("cancel");
+ }
+}
+
+void
+_thread_enter_cancellation_point(void)
+{
+
+ /* Look for a cancellation before we block: */
+ pthread_testcancel();
+ _thread_run->cancelflags |= PTHREAD_AT_CANCEL_POINT;
+}
+
+void
+_thread_leave_cancellation_point(void)
+{
+
+ _thread_run->cancelflags &= ~PTHREAD_AT_CANCEL_POINT;
+ /* Look for a cancellation after we unblock: */
+ pthread_testcancel();
+}
diff --git a/lib/libpthread/thread/thr_clean.c b/lib/libpthread/thread/thr_clean.c
new file mode 100644
index 0000000..bba5500
--- /dev/null
+++ b/lib/libpthread/thread/thr_clean.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#include <stdlib.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+void
+pthread_cleanup_push(void (*routine) (void *), void *routine_arg)
+{
+ struct pthread_cleanup *new;
+
+ if ((new = (struct pthread_cleanup *) malloc(sizeof(struct pthread_cleanup))) != NULL) {
+ new->routine = routine;
+ new->routine_arg = routine_arg;
+ new->next = _thread_run->cleanup;
+
+ _thread_run->cleanup = new;
+ }
+}
+
+void
+pthread_cleanup_pop(int execute)
+{
+ struct pthread_cleanup *old;
+
+ if ((old = _thread_run->cleanup) != NULL) {
+ _thread_run->cleanup = old->next;
+ if (execute) {
+ old->routine(old->routine_arg);
+ }
+ free(old);
+ }
+}
+
+#endif
diff --git a/lib/libpthread/thread/thr_close.c b/lib/libpthread/thread/thr_close.c
new file mode 100644
index 0000000..2580fce
--- /dev/null
+++ b/lib/libpthread/thread/thr_close.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+close(int fd)
+{
+ int flags;
+ int ret;
+ struct stat sb;
+ struct fd_table_entry *entry;
+
+ _thread_enter_cancellation_point();
+
+ if ((fd == _thread_kern_pipe[0]) || (fd == _thread_kern_pipe[1])) {
+ /*
+ * Don't allow silly programs to close the kernel pipe.
+ */
+ errno = EBADF;
+ ret = -1;
+ }
+ /*
+ * Lock the file descriptor while the file is closed and get
+ * the file descriptor status:
+ */
+ else if (((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) &&
+ ((ret = _thread_sys_fstat(fd, &sb)) == 0)) {
+ /*
+ * Check if the file should be left as blocking.
+ *
+ * This is so that the file descriptors shared with a parent
+ * process aren't left set to non-blocking if the child
+ * closes them prior to exit. An example where this causes
+ * problems with /bin/sh is when a child closes stdin.
+ *
+ * Setting a file as blocking causes problems if a threaded
+ * parent accesses the file descriptor before the child exits.
+ * Once the threaded parent receives a SIGCHLD then it resets
+ * all of its files to non-blocking, and so it is then safe
+ * to access them.
+ *
+ * Pipes are not set to blocking when they are closed, as
+ * the parent and child will normally close the file
+ * descriptor of the end of the pipe that they are not
+ * using, which would then cause any reads to block
+ * indefinitely.
+ */
+ if ((S_ISREG(sb.st_mode) || S_ISCHR(sb.st_mode)) && (_thread_fd_table[fd]->flags & O_NONBLOCK) == 0) {
+ /* Get the current flags: */
+ flags = _thread_sys_fcntl(fd, F_GETFL, NULL);
+ /* Clear the nonblocking file descriptor flag: */
+ _thread_sys_fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+ }
+
+ /* XXX: Assumes well behaved threads. */
+ /* XXX: Defer real close to avoid race condition */
+ entry = _thread_fd_table[fd];
+ _thread_fd_table[fd] = NULL;
+ free(entry);
+
+ /* Close the file descriptor: */
+ ret = _thread_sys_close(fd);
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_cond.c b/lib/libpthread/thread/thr_cond.c
new file mode 100644
index 0000000..3e215af
--- /dev/null
+++ b/lib/libpthread/thread/thr_cond.c
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/*
+ * Prototypes
+ */
+static inline pthread_t cond_queue_deq(pthread_cond_t);
+static inline void cond_queue_remove(pthread_cond_t, pthread_t);
+static inline void cond_queue_enq(pthread_cond_t, pthread_t);
+
+/* Reinitialize a condition variable to defaults. */
+int
+_cond_reinit(pthread_cond_t * cond)
+{
+ int ret = 0;
+
+ if (cond == NULL)
+ ret = EINVAL;
+ else if (*cond == NULL)
+ ret = pthread_cond_init(cond, NULL);
+ else {
+ /*
+ * Initialize the condition variable structure:
+ */
+ TAILQ_INIT(&(*cond)->c_queue);
+ (*cond)->c_flags = COND_FLAGS_INITED;
+ (*cond)->c_type = COND_TYPE_FAST;
+ (*cond)->c_mutex = NULL;
+ memset(&(*cond)->lock, 0, sizeof((*cond)->lock));
+ }
+ return (ret);
+}
+
+int
+pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t * cond_attr)
+{
+ enum pthread_cond_type type;
+ pthread_cond_t pcond;
+ int rval = 0;
+
+ if (cond == NULL)
+ rval = EINVAL;
+ else {
+ /*
+ * Check if a pointer to a condition variable attribute
+ * structure was passed by the caller:
+ */
+ if (cond_attr != NULL && *cond_attr != NULL) {
+ /* Default to a fast condition variable: */
+ type = (*cond_attr)->c_type;
+ } else {
+ /* Default to a fast condition variable: */
+ type = COND_TYPE_FAST;
+ }
+
+ /* Process according to condition variable type: */
+ switch (type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ /* Nothing to do here. */
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ /* Check for no errors: */
+ if (rval == 0) {
+ if ((pcond = (pthread_cond_t)
+ malloc(sizeof(struct pthread_cond))) == NULL) {
+ rval = ENOMEM;
+ } else {
+ /*
+ * Initialise the condition variable
+ * structure:
+ */
+ TAILQ_INIT(&pcond->c_queue);
+ pcond->c_flags |= COND_FLAGS_INITED;
+ pcond->c_type = type;
+ pcond->c_mutex = NULL;
+ memset(&pcond->lock,0,sizeof(pcond->lock));
+ *cond = pcond;
+ }
+ }
+ }
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_destroy(pthread_cond_t * cond)
+{
+ int rval = 0;
+
+ if (cond == NULL || *cond == NULL)
+ rval = EINVAL;
+ else {
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /*
+ * Free the memory allocated for the condition
+ * variable structure:
+ */
+ free(*cond);
+
+ /*
+ * NULL the caller's pointer now that the condition
+ * variable has been destroyed:
+ */
+ *cond = NULL;
+ }
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
+{
+ int rval = 0;
+
+ if (cond == NULL)
+ rval = EINVAL;
+
+ /*
+ * If the condition variable is statically initialized,
+ * perform the dynamic initialization:
+ */
+ else if (*cond != NULL ||
+ (rval = pthread_cond_init(cond,NULL)) == 0) {
+
+ _thread_enter_cancellation_point();
+
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /*
+ * If the condvar was statically allocated, properly
+ * initialize the tail queue.
+ */
+ if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) {
+ TAILQ_INIT(&(*cond)->c_queue);
+ (*cond)->c_flags |= COND_FLAGS_INITED;
+ }
+
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ if ((mutex == NULL) || (((*cond)->c_mutex != NULL) &&
+ ((*cond)->c_mutex != *mutex))) {
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /* Return invalid argument error: */
+ rval = EINVAL;
+ } else {
+ /* Reset the timeout and interrupted flags: */
+ _thread_run->timeout = 0;
+ _thread_run->interrupted = 0;
+
+ /*
+ * Queue the running thread for the condition
+ * variable:
+ */
+ cond_queue_enq(*cond, _thread_run);
+
+ /* Remember the mutex that is being used: */
+ (*cond)->c_mutex = *mutex;
+
+ /* Wait forever: */
+ _thread_run->wakeup_time.tv_sec = -1;
+
+ /* Unlock the mutex: */
+ if ((rval = _mutex_cv_unlock(mutex)) != 0) {
+ /*
+ * Cannot unlock the mutex, so remove
+ * the running thread from the condition
+ * variable queue:
+ */
+ cond_queue_remove(*cond, _thread_run);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) ==
+ NULL)
+ (*cond)->c_mutex = NULL;
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+ }
+ else {
+ /*
+ * Schedule the next thread and unlock
+ * the condition variable structure:
+ */
+ _thread_kern_sched_state_unlock(PS_COND_WAIT,
+ &(*cond)->lock, __FILE__, __LINE__);
+
+ if (_thread_run->interrupted != 0) {
+ /*
+ * Lock the condition variable
+ * while removing the thread.
+ */
+ _SPINLOCK(&(*cond)->lock);
+
+ cond_queue_remove(*cond,
+ _thread_run);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) == NULL)
+ (*cond)->c_mutex = NULL;
+
+ _SPINUNLOCK(&(*cond)->lock);
+ }
+
+ /*
+ * Note that even though this thread may have
+ * been canceled, POSIX requires that the mutex
+ * be reaquired prior to cancellation.
+ */
+ rval = _mutex_cv_lock(mutex);
+ }
+ }
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+
+ _thread_leave_cancellation_point();
+ }
+
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
+ const struct timespec * abstime)
+{
+ int rval = 0;
+
+ if (cond == NULL || abstime == NULL)
+ rval = EINVAL;
+
+ if (abstime->tv_sec < 0 ||
+ abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /*
+ * If the condition variable is statically initialized,
+ * perform the dynamic initialization:
+ */
+ if (*cond != NULL ||
+ (rval = pthread_cond_init(cond,NULL)) == 0) {
+
+ _thread_enter_cancellation_point();
+
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /*
+ * If the condvar was statically allocated, properly
+ * initialize the tail queue.
+ */
+ if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) {
+ TAILQ_INIT(&(*cond)->c_queue);
+ (*cond)->c_flags |= COND_FLAGS_INITED;
+ }
+
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ if ((mutex == NULL) || (((*cond)->c_mutex != NULL) &&
+ ((*cond)->c_mutex != *mutex))) {
+ /* Return invalid argument error: */
+ rval = EINVAL;
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+ } else {
+ /* Set the wakeup time: */
+ _thread_run->wakeup_time.tv_sec =
+ abstime->tv_sec;
+ _thread_run->wakeup_time.tv_nsec =
+ abstime->tv_nsec;
+
+ /* Reset the timeout and interrupted flags: */
+ _thread_run->timeout = 0;
+ _thread_run->interrupted = 0;
+
+ /*
+ * Queue the running thread for the condition
+ * variable:
+ */
+ cond_queue_enq(*cond, _thread_run);
+
+ /* Remember the mutex that is being used: */
+ (*cond)->c_mutex = *mutex;
+
+ /* Unlock the mutex: */
+ if ((rval = _mutex_cv_unlock(mutex)) != 0) {
+ /*
+ * Cannot unlock the mutex, so remove
+ * the running thread from the condition
+ * variable queue:
+ */
+ cond_queue_remove(*cond, _thread_run);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) == NULL)
+ (*cond)->c_mutex = NULL;
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+ } else {
+ /*
+ * Schedule the next thread and unlock
+ * the condition variable structure:
+ */
+ _thread_kern_sched_state_unlock(PS_COND_WAIT,
+ &(*cond)->lock, __FILE__, __LINE__);
+
+ /*
+ * Check if the wait timedout or was
+ * interrupted (canceled):
+ */
+ if ((_thread_run->timeout == 0) &&
+ (_thread_run->interrupted == 0)) {
+ /* Lock the mutex: */
+ rval = _mutex_cv_lock(mutex);
+
+ } else {
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /*
+ * The wait timed out; remove
+ * the thread from the condition
+ * variable queue:
+ */
+ cond_queue_remove(*cond,
+ _thread_run);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) == NULL)
+ (*cond)->c_mutex = NULL;
+
+ /* Unock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /* Return a timeout error: */
+ rval = ETIMEDOUT;
+
+ /*
+ * Lock the mutex and ignore any
+ * errors. Note that even though
+ * this thread may have been
+ * canceled, POSIX requires that
+ * the mutex be reaquired prior
+ * to cancellation.
+ */
+ (void)_mutex_cv_lock(mutex);
+ }
+ }
+ }
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+
+ _thread_leave_cancellation_point();
+ }
+
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_signal(pthread_cond_t * cond)
+{
+ int rval = 0;
+ pthread_t pthread;
+
+ if (cond == NULL || *cond == NULL)
+ rval = EINVAL;
+ else {
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ if ((pthread = cond_queue_deq(*cond)) != NULL)
+ /* Allow the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Check for no more waiters: */
+ if (TAILQ_FIRST(&(*cond)->c_queue) == NULL)
+ (*cond)->c_mutex = NULL;
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (rval);
+}
+
+int
+pthread_cond_broadcast(pthread_cond_t * cond)
+{
+ int rval = 0;
+ pthread_t pthread;
+
+ if (cond == NULL || *cond == NULL)
+ rval = EINVAL;
+ else {
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the condition variable structure: */
+ _SPINLOCK(&(*cond)->lock);
+
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ /*
+ * Enter a loop to bring all threads off the
+ * condition queue:
+ */
+ while ((pthread = cond_queue_deq(*cond)) != NULL) {
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ }
+
+ /* There are no more waiting threads: */
+ (*cond)->c_mutex = NULL;
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
+ }
+
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (rval);
+}
+
+/*
+ * Dequeue a waiting thread from the head of a condition queue in
+ * descending priority order.
+ */
+static inline pthread_t
+cond_queue_deq(pthread_cond_t cond)
+{
+ pthread_t pthread;
+
+ while ((pthread = TAILQ_FIRST(&cond->c_queue)) != NULL) {
+ TAILQ_REMOVE(&cond->c_queue, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_CONDQ;
+ if ((pthread->timeout == 0) && (pthread->interrupted == 0))
+ /*
+ * Only exit the loop when we find a thread
+ * that hasn't timed out or been canceled;
+ * those threads are already running and don't
+ * need their run state changed.
+ */
+ break;
+ }
+
+ return(pthread);
+}
+
+/*
+ * Remove a waiting thread from a condition queue in descending priority
+ * order.
+ */
+static inline void
+cond_queue_remove(pthread_cond_t cond, pthread_t pthread)
+{
+ /*
+ * Because pthread_cond_timedwait() can timeout as well
+ * as be signaled by another thread, it is necessary to
+ * guard against removing the thread from the queue if
+ * it isn't in the queue.
+ */
+ if (pthread->flags & PTHREAD_FLAGS_IN_CONDQ) {
+ TAILQ_REMOVE(&cond->c_queue, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_CONDQ;
+ }
+}
+
+/*
+ * Enqueue a waiting thread to a condition queue in descending priority
+ * order.
+ */
+static inline void
+cond_queue_enq(pthread_cond_t cond, pthread_t pthread)
+{
+ pthread_t tid = TAILQ_LAST(&cond->c_queue, cond_head);
+
+ /*
+ * For the common case of all threads having equal priority,
+ * we perform a quick check against the priority of the thread
+ * at the tail of the queue.
+ */
+ if ((tid == NULL) || (pthread->active_priority <= tid->active_priority))
+ TAILQ_INSERT_TAIL(&cond->c_queue, pthread, qe);
+ else {
+ tid = TAILQ_FIRST(&cond->c_queue);
+ while (pthread->active_priority <= tid->active_priority)
+ tid = TAILQ_NEXT(tid, qe);
+ TAILQ_INSERT_BEFORE(tid, pthread, qe);
+ }
+ pthread->flags |= PTHREAD_FLAGS_IN_CONDQ;
+}
+#endif
diff --git a/lib/libpthread/thread/thr_condattr_destroy.c b/lib/libpthread/thread/thr_condattr_destroy.c
new file mode 100644
index 0000000..ad91228
--- /dev/null
+++ b/lib/libpthread/thread/thr_condattr_destroy.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_condattr_destroy(pthread_condattr_t *attr)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ ret = EINVAL;
+ } else {
+ free(*attr);
+ *attr = NULL;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_condattr_init.c b/lib/libpthread/thread/thr_condattr_init.c
new file mode 100644
index 0000000..3379898
--- /dev/null
+++ b/lib/libpthread/thread/thr_condattr_init.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_condattr_init(pthread_condattr_t *attr)
+{
+ int ret;
+ pthread_condattr_t pattr;
+
+ if ((pattr = (pthread_condattr_t)
+ malloc(sizeof(struct pthread_cond_attr))) == NULL) {
+ ret = ENOMEM;
+ } else {
+ memcpy(pattr, &pthread_condattr_default,
+ sizeof(struct pthread_cond_attr));
+ *attr = pattr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_create.c b/lib/libpthread/thread/thr_create.c
new file mode 100644
index 0000000..8621c05
--- /dev/null
+++ b/lib/libpthread/thread/thr_create.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/mman.h>
+#ifdef _THREAD_SAFE
+#include <machine/reg.h>
+#include <pthread.h>
+#include "pthread_private.h"
+#include "libc_private.h"
+
+static u_int64_t next_uniqueid = 1;
+
+#define OFF(f) offsetof(struct pthread, f)
+int _thread_next_offset = OFF(tle.tqe_next);
+int _thread_uniqueid_offset = OFF(uniqueid);
+int _thread_state_offset = OFF(state);
+int _thread_name_offset = OFF(name);
+int _thread_sig_saved_offset = OFF(sig_saved);
+int _thread_saved_sigcontext_offset = OFF(saved_sigcontext);
+int _thread_saved_jmp_buf_offset = OFF(saved_jmp_buf);
+#undef OFF
+
+int _thread_PS_RUNNING_value = PS_RUNNING;
+int _thread_PS_DEAD_value = PS_DEAD;
+
+int
+pthread_create(pthread_t * thread, const pthread_attr_t * attr,
+ void *(*start_routine) (void *), void *arg)
+{
+ int f_gc = 0;
+ int ret = 0;
+ pthread_t gc_thread;
+ pthread_t new_thread;
+ pthread_attr_t pattr;
+ void *stack;
+
+ /*
+ * Locking functions in libc are required when there are
+ * threads other than the initial thread.
+ */
+ __isthreaded = 1;
+
+ /* Allocate memory for the thread structure: */
+ if ((new_thread = (pthread_t) malloc(sizeof(struct pthread))) == NULL) {
+ /* Insufficient memory to create a thread: */
+ ret = EAGAIN;
+ } else {
+ /* Check if default thread attributes are required: */
+ if (attr == NULL || *attr == NULL) {
+ /* Use the default thread attributes: */
+ pattr = &pthread_attr_default;
+ } else {
+ pattr = *attr;
+ }
+ /* Check if a stack was specified in the thread attributes: */
+ if ((stack = pattr->stackaddr_attr) != NULL) {
+ }
+ /* Allocate memory for a default-size stack: */
+ else if (pattr->stacksize_attr == PTHREAD_STACK_DEFAULT) {
+ struct stack *spare_stack;
+
+ /* Allocate or re-use a default-size stack. */
+
+ /*
+ * Use the garbage collector mutex for synchronization
+ * of the spare stack list.
+ */
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ if ((spare_stack = SLIST_FIRST(&_stackq)) != NULL) {
+ /* Use the spare stack. */
+ SLIST_REMOVE_HEAD(&_stackq, qe);
+
+ /* Unlock the garbage collector mutex. */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
+
+ stack = sizeof(struct stack)
+ + (void *) spare_stack
+ - PTHREAD_STACK_DEFAULT;
+ } else {
+ /* Unlock the garbage collector mutex. */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
+
+ /* Allocate a new stack. */
+ stack = _next_stack + PTHREAD_STACK_GUARD;
+ /*
+ * Even if stack allocation fails, we don't want
+ * to try to use this location again, so
+ * unconditionally decrement _next_stack. Under
+ * normal operating conditions, the most likely
+ * reason for an mmap() error is a stack
+ * overflow of the adjacent thread stack.
+ */
+ _next_stack -= (PTHREAD_STACK_DEFAULT
+ + PTHREAD_STACK_GUARD);
+
+ /* Red zone: */
+ if (mmap(_next_stack, PTHREAD_STACK_GUARD, 0,
+ MAP_ANON, -1, 0) == MAP_FAILED) {
+ ret = EAGAIN;
+ free(new_thread);
+ }
+ /* Stack: */
+ else if (mmap(stack,
+ PTHREAD_STACK_DEFAULT,
+ PROT_READ | PROT_WRITE,
+ MAP_STACK,
+ -1, 0) == MAP_FAILED) {
+ ret = EAGAIN;
+ munmap(_next_stack,
+ PTHREAD_STACK_GUARD);
+ free(new_thread);
+ }
+ }
+ }
+ /*
+ * The user wants a stack of a particular size. Lets hope they
+ * really know what they want, and simply malloc the stack.
+ */
+ else if ((stack = (void *) malloc(pattr->stacksize_attr))
+ == NULL) {
+ /* Insufficient memory to create a thread: */
+ ret = EAGAIN;
+ free(new_thread);
+ }
+
+ /* Check for errors: */
+ if (ret != 0) {
+ } else {
+ /* Initialise the thread structure: */
+ memset(new_thread, 0, sizeof(struct pthread));
+ new_thread->slice_usec = -1;
+ new_thread->sig_saved = 0;
+ new_thread->stack = stack;
+ new_thread->start_routine = start_routine;
+ new_thread->arg = arg;
+
+ new_thread->cancelflags = PTHREAD_CANCEL_ENABLE |
+ PTHREAD_CANCEL_DEFERRED;
+
+ /*
+ * Write a magic value to the thread structure
+ * to help identify valid ones:
+ */
+ new_thread->magic = PTHREAD_MAGIC;
+
+ /* Initialise the thread for signals: */
+ new_thread->sigmask = _thread_run->sigmask;
+
+ /* Initialise the jump buffer: */
+ setjmp(new_thread->saved_jmp_buf);
+
+ /*
+ * Set up new stack frame so that it looks like it
+ * returned from a longjmp() to the beginning of
+ * _thread_start().
+ */
+#if defined(__FreeBSD__)
+#if defined(__alpha__)
+ new_thread->saved_jmp_buf[0]._jb[2] = (long) _thread_start;
+ new_thread->saved_jmp_buf[0]._jb[4 + R_RA] = 0;
+ new_thread->saved_jmp_buf[0]._jb[4 + R_T12] = (long) _thread_start;
+#else
+ new_thread->saved_jmp_buf[0]._jb[0] = (long) _thread_start;
+#endif
+#elif defined(__NetBSD__)
+#if defined(__alpha__)
+ new_thread->saved_jmp_buf[2] = (long) _thread_start;
+ new_thread->saved_jmp_buf[4 + R_RA] = 0;
+ new_thread->saved_jmp_buf[4 + R_T12] = (long) _thread_start;
+#else
+ new_thread->saved_jmp_buf[0] = (long) _thread_start;
+#endif
+#else
+#error "Don't recognize this operating system!"
+#endif
+
+ /* The stack starts high and builds down: */
+#if defined(__FreeBSD__)
+#if defined(__alpha__)
+ new_thread->saved_jmp_buf[0]._jb[4 + R_SP] = (long) new_thread->stack + pattr->stacksize_attr - sizeof(double);
+#else
+ new_thread->saved_jmp_buf[0]._jb[2] = (int) (new_thread->stack + pattr->stacksize_attr - sizeof(double));
+#endif
+#elif defined(__NetBSD__)
+#if defined(__alpha__)
+ new_thread->saved_jmp_buf[4 + R_SP] = (long) new_thread->stack + pattr->stacksize_attr - sizeof(double);
+#else
+ new_thread->saved_jmp_buf[2] = (long) new_thread->stack + pattr->stacksize_attr - sizeof(double);
+#endif
+#else
+#error "Don't recognize this operating system!"
+#endif
+
+ /* Copy the thread attributes: */
+ memcpy(&new_thread->attr, pattr, sizeof(struct pthread_attr));
+
+ /*
+ * Check if this thread is to inherit the scheduling
+ * attributes from its parent:
+ */
+ if (new_thread->attr.flags & PTHREAD_INHERIT_SCHED) {
+ /* Copy the scheduling attributes: */
+ new_thread->base_priority
+ = _thread_run->base_priority;
+ new_thread->attr.prio
+ = _thread_run->base_priority;
+ new_thread->attr.sched_policy
+ = _thread_run->attr.sched_policy;
+ } else {
+ /*
+ * Use just the thread priority, leaving the
+ * other scheduling attributes as their
+ * default values:
+ */
+ new_thread->base_priority
+ = new_thread->attr.prio;
+ }
+ new_thread->active_priority = new_thread->base_priority;
+ new_thread->inherited_priority = 0;
+
+ /* Initialise the join queue for the new thread: */
+ TAILQ_INIT(&(new_thread->join_queue));
+
+ /* Initialize the mutex queue: */
+ TAILQ_INIT(&new_thread->mutexq);
+
+ /* Initialise hooks in the thread structure: */
+ new_thread->specific_data = NULL;
+ new_thread->cleanup = NULL;
+ new_thread->flags = 0;
+ new_thread->poll_data.nfds = 0;
+ new_thread->poll_data.fds = NULL;
+
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /*
+ * Initialise the unique id which GDB uses to
+ * track threads.
+ */
+ new_thread->uniqueid = next_uniqueid++;
+
+ /*
+ * Check if the garbage collector thread
+ * needs to be started.
+ */
+ f_gc = (TAILQ_FIRST(&_thread_list) == _thread_initial);
+
+ /* Add the thread to the linked list of all threads: */
+ TAILQ_INSERT_HEAD(&_thread_list, new_thread, tle);
+
+ if (pattr->suspend == PTHREAD_CREATE_SUSPENDED) {
+ new_thread->state = PS_SUSPENDED;
+ PTHREAD_WAITQ_INSERT(new_thread);
+ } else {
+ new_thread->state = PS_RUNNING;
+ PTHREAD_PRIOQ_INSERT_TAIL(new_thread);
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding
+ * if necessary.
+ */
+ _thread_kern_sig_undefer();
+
+ /* Return a pointer to the thread structure: */
+ (*thread) = new_thread;
+
+ /* Schedule the new user thread: */
+ _thread_kern_sched(NULL);
+
+ /*
+ * Start a garbage collector thread
+ * if necessary.
+ */
+ if (f_gc && pthread_create(&gc_thread,NULL,
+ _thread_gc,NULL) != 0)
+ PANIC("Can't create gc thread");
+ }
+ }
+
+ /* Return the status: */
+ return (ret);
+}
+
+void
+_thread_start(void)
+{
+ /* We just left the scheduler via longjmp: */
+ _thread_kern_in_sched = 0;
+
+ /* Run the current thread's start routine with argument: */
+ pthread_exit(_thread_run->start_routine(_thread_run->arg));
+
+ /* This point should never be reached. */
+ PANIC("Thread has resumed after exit");
+}
+#endif
diff --git a/lib/libpthread/thread/thr_detach.c b/lib/libpthread/thread/thr_detach.c
new file mode 100644
index 0000000..164c7df
--- /dev/null
+++ b/lib/libpthread/thread/thr_detach.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_detach(pthread_t pthread)
+{
+ int rval = 0;
+ int status;
+ pthread_t next_thread;
+
+ /* Check for invalid calling parameters: */
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+
+ /* Check if the thread has not been detached: */
+ else if ((pthread->attr.flags & PTHREAD_DETACHED) == 0) {
+ /* Flag the thread as detached: */
+ pthread->attr.flags |= PTHREAD_DETACHED;
+
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Enter a loop to bring all threads off the join queue: */
+ while ((next_thread = TAILQ_FIRST(&pthread->join_queue)) != NULL) {
+ /* Remove the thread from the queue: */
+ TAILQ_REMOVE(&pthread->join_queue, next_thread, qe);
+
+ /* Make the thread run: */
+ PTHREAD_NEW_STATE(next_thread,PS_RUNNING);
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding if a
+ * scheduling signal occurred while in the critical region.
+ */
+ _thread_kern_sig_undefer();
+ } else
+ /* Return an error: */
+ rval = EINVAL;
+
+ /* Return the completion status: */
+ return (rval);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_equal.c b/lib/libpthread/thread/thr_equal.c
new file mode 100644
index 0000000..e03ba4a
--- /dev/null
+++ b/lib/libpthread/thread/thr_equal.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_equal(pthread_t t1, pthread_t t2)
+{
+ /* Compare the two thread pointers: */
+ return (t1 == t2);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_exit.c b/lib/libpthread/thread/thr_exit.c
new file mode 100644
index 0000000..abe4b27
--- /dev/null
+++ b/lib/libpthread/thread/thr_exit.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+void _exit(int status)
+{
+ int flags;
+ int i;
+ struct itimerval itimer;
+
+ /* Disable the interval timer: */
+ itimer.it_interval.tv_sec = 0;
+ itimer.it_interval.tv_usec = 0;
+ itimer.it_value.tv_sec = 0;
+ itimer.it_value.tv_usec = 0;
+ setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL);
+
+ /* Close the pthread kernel pipe: */
+ _thread_sys_close(_thread_kern_pipe[0]);
+ _thread_sys_close(_thread_kern_pipe[1]);
+
+ /*
+ * Enter a loop to set all file descriptors to blocking
+ * if they were not created as non-blocking:
+ */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /* Check if this file descriptor is in use: */
+ if (_thread_fd_table[i] != NULL &&
+ !(_thread_fd_table[i]->flags & O_NONBLOCK)) {
+ /* Get the current flags: */
+ flags = _thread_sys_fcntl(i, F_GETFL, NULL);
+ /* Clear the nonblocking file descriptor flag: */
+ _thread_sys_fcntl(i, F_SETFL, flags & ~O_NONBLOCK);
+ }
+ }
+
+ /* Call the _exit syscall: */
+ _thread_sys__exit(status);
+}
+
+void
+_thread_exit(char *fname, int lineno, char *string)
+{
+ char s[256];
+
+ /* Prepare an error message string: */
+ strcpy(s, "Fatal error '");
+ strcat(s, string);
+ strcat(s, "' at line ? ");
+ strcat(s, "in file ");
+ strcat(s, fname);
+ strcat(s, " (errno = ?");
+ strcat(s, ")\n");
+
+ /* Write the string to the standard error file descriptor: */
+ _thread_sys_write(2, s, strlen(s));
+
+ /* Force this process to exit: */
+ /* XXX - Do we want abort to be conditional on _PTHREADS_INVARIANTS? */
+#if defined(_PTHREADS_INVARIANTS)
+ abort();
+#else
+ _exit(1);
+#endif
+}
+
+/*
+ * Only called when a thread is cancelled. It may be more useful
+ * to call it from pthread_exit() if other ways of asynchronous or
+ * abnormal thread termination can be found.
+ */
+void
+_thread_exit_cleanup(void)
+{
+ /*
+ * POSIX states that cancellation/termination of a thread should
+ * not release any visible resources (such as mutexes) and that
+ * it is the applications responsibility. Resources that are
+ * internal to the threads library, including file and fd locks,
+ * are not visible to the application and need to be released.
+ */
+ /* Unlock all owned fd locks: */
+ _thread_fd_unlock_owned(_thread_run);
+
+ /* Unlock all owned file locks: */
+ _funlock_owned(_thread_run);
+
+ /* Unlock all private mutexes: */
+ _mutex_unlock_private(_thread_run);
+
+ /*
+ * This still isn't quite correct because we don't account
+ * for held spinlocks (see libc/stdlib/malloc.c).
+ */
+}
+
+void
+pthread_exit(void *status)
+{
+ pthread_t pthread;
+
+ /* Check if this thread is already in the process of exiting: */
+ if ((_thread_run->flags & PTHREAD_EXITING) != 0) {
+ char msg[128];
+ snprintf(msg, sizeof(msg), "Thread %p has called pthread_exit() from a destructor. POSIX 1003.1 1996 s16.2.5.2 does not allow this!",_thread_run);
+ PANIC(msg);
+ }
+
+ /* Flag this thread as exiting: */
+ _thread_run->flags |= PTHREAD_EXITING;
+
+ /* Save the return value: */
+ _thread_run->ret = status;
+
+ while (_thread_run->cleanup != NULL) {
+ pthread_cleanup_pop(1);
+ }
+
+ if (_thread_run->attr.cleanup_attr != NULL) {
+ _thread_run->attr.cleanup_attr(_thread_run->attr.arg_attr);
+ }
+ /* Check if there is thread specific data: */
+ if (_thread_run->specific_data != NULL) {
+ /* Run the thread-specific data destructors: */
+ _thread_cleanupspecific();
+ }
+
+ /* Free thread-specific poll_data structure, if allocated: */
+ if (_thread_run->poll_data.fds != NULL) {
+ free(_thread_run->poll_data.fds);
+ _thread_run->poll_data.fds = NULL;
+ }
+
+ /*
+ * Defer signals to protect the scheduling queues from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Check if there are any threads joined to this one: */
+ while ((pthread = TAILQ_FIRST(&(_thread_run->join_queue))) != NULL) {
+ /* Remove the thread from the queue: */
+ TAILQ_REMOVE(&_thread_run->join_queue, pthread, qe);
+
+ /* Wake the joined thread and let it detach this thread: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding if necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ /*
+ * Lock the garbage collector mutex to ensure that the garbage
+ * collector is not using the dead thread list.
+ */
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* Add this thread to the list of dead threads. */
+ TAILQ_INSERT_HEAD(&_dead_list, _thread_run, dle);
+
+ /*
+ * Defer signals to protect the scheduling queues from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Remove this thread from the thread list: */
+ TAILQ_REMOVE(&_thread_list, _thread_run, tle);
+
+ /*
+ * Undefer and handle pending signals, yielding if necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ /*
+ * Signal the garbage collector thread that there is something
+ * to clean up.
+ */
+ if (pthread_cond_signal(&_gc_cond) != 0)
+ PANIC("Cannot signal gc cond");
+
+ /*
+ * Mark the thread as dead so it will not return if it
+ * gets context switched out when the mutex is unlocked.
+ */
+ PTHREAD_SET_STATE(_thread_run, PS_DEAD);
+
+ /* Unlock the garbage collector mutex: */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* This this thread will never be re-scheduled. */
+ _thread_kern_sched(NULL);
+
+ /* This point should not be reached. */
+ PANIC("Dead thread has resumed");
+}
+#endif
diff --git a/lib/libpthread/thread/thr_fcntl.c b/lib/libpthread/thread/thr_fcntl.c
new file mode 100644
index 0000000..878554c
--- /dev/null
+++ b/lib/libpthread/thread/thr_fcntl.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+fcntl(int fd, int cmd,...)
+{
+ int flags = 0;
+ int nonblock;
+ int oldfd;
+ int ret;
+ va_list ap;
+
+ _thread_enter_cancellation_point();
+
+ /* Lock the file descriptor: */
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ /* Initialise the variable argument list: */
+ va_start(ap, cmd);
+
+ /* Process according to file control command type: */
+ switch (cmd) {
+ /* Duplicate a file descriptor: */
+ case F_DUPFD:
+ /*
+ * Get the file descriptor that the caller wants to
+ * use:
+ */
+ oldfd = va_arg(ap, int);
+
+ /* Initialise the file descriptor table entry: */
+ if ((ret = _thread_sys_fcntl(fd, cmd, oldfd)) < 0) {
+ }
+ /* Initialise the file descriptor table entry: */
+ else if (_thread_fd_table_init(ret) != 0) {
+ /* Quietly close the file: */
+ _thread_sys_close(ret);
+
+ /* Reset the file descriptor: */
+ ret = -1;
+ } else {
+ /*
+ * Save the file open flags so that they can
+ * be checked later:
+ */
+ _thread_fd_table[ret]->flags = _thread_fd_table[fd]->flags;
+ }
+ break;
+ case F_SETFD:
+ flags = va_arg(ap, int);
+ ret = _thread_sys_fcntl(fd, cmd, flags);
+ break;
+ case F_GETFD:
+ ret = _thread_sys_fcntl(fd, cmd, 0);
+ break;
+ case F_GETFL:
+ ret = _thread_fd_table[fd]->flags;
+ break;
+ case F_SETFL:
+ /*
+ * Get the file descriptor flags passed by the
+ * caller:
+ */
+ flags = va_arg(ap, int);
+
+ /*
+ * Check if the user wants a non-blocking file
+ * descriptor:
+ */
+ nonblock = flags & O_NONBLOCK;
+
+ /* Set the file descriptor flags: */
+ if ((ret = _thread_sys_fcntl(fd, cmd, flags | O_NONBLOCK)) != 0) {
+
+ /* Get the flags so that we behave like the kernel: */
+ } else if ((flags = _thread_sys_fcntl(fd,
+ F_GETFL, 0)) == -1) {
+ /* Error getting flags: */
+ ret = -1;
+
+ /*
+ * Check if the file descriptor is non-blocking
+ * with respect to the user:
+ */
+ } else if (nonblock)
+ /* A non-blocking descriptor: */
+ _thread_fd_table[fd]->flags = flags | O_NONBLOCK;
+ else
+ /* Save the flags: */
+ _thread_fd_table[fd]->flags = flags & ~O_NONBLOCK;
+ break;
+ default:
+ /* Might want to make va_arg use a union */
+ ret = _thread_sys_fcntl(fd, cmd, va_arg(ap, void *));
+ break;
+ }
+
+ /* Free variable arguments: */
+ va_end(ap);
+
+ /* Unlock the file descriptor: */
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ _thread_leave_cancellation_point();
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_find_thread.c b/lib/libpthread/thread/thr_find_thread.c
new file mode 100644
index 0000000..d4a3bbd
--- /dev/null
+++ b/lib/libpthread/thread/thr_find_thread.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Find a thread in the linked list of active threads: */
+int
+_find_thread(pthread_t pthread)
+{
+ pthread_t pthread1;
+
+ /* Check if the caller has specified an invalid thread: */
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
+ /* Invalid thread: */
+ return(EINVAL);
+
+ /*
+ * Defer signals to protect the thread list from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Search for the specified thread: */
+ TAILQ_FOREACH(pthread1, &_thread_list, tle) {
+ if (pthread == pthread1)
+ break;
+ }
+
+ /* Undefer and handle pending signals, yielding if necessary: */
+ _thread_kern_sig_undefer();
+
+ /* Return zero if the thread exists: */
+ return ((pthread1 != NULL) ? 0:ESRCH);
+}
+
+/* Find a thread in the linked list of dead threads: */
+int
+_find_dead_thread(pthread_t pthread)
+{
+ pthread_t pthread1;
+
+ /* Check if the caller has specified an invalid thread: */
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
+ /* Invalid thread: */
+ return(EINVAL);
+
+ /*
+ * Lock the garbage collector mutex to ensure that the garbage
+ * collector is not using the dead thread list.
+ */
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* Search for the specified thread: */
+ TAILQ_FOREACH(pthread1, &_dead_list, dle) {
+ if (pthread1 == pthread)
+ break;
+ }
+
+ /* Unlock the garbage collector mutex: */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* Return zero if the thread exists: */
+ return ((pthread1 != NULL) ? 0:ESRCH);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_fork.c b/lib/libpthread/thread/thr_fork.c
new file mode 100644
index 0000000..b8d72dc
--- /dev/null
+++ b/lib/libpthread/thread/thr_fork.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+pid_t
+fork(void)
+{
+ int i, flags;
+ pid_t ret;
+ pthread_t pthread;
+ pthread_t pthread_save;
+
+ /*
+ * Defer signals to protect the scheduling queues from access
+ * by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Fork a new process: */
+ if ((ret = _thread_sys_fork()) != 0) {
+ /* Parent process or error. Nothing to do here. */
+ } else {
+ /* Close the pthread kernel pipe: */
+ _thread_sys_close(_thread_kern_pipe[0]);
+ _thread_sys_close(_thread_kern_pipe[1]);
+
+ /* Reset signals pending for the running thread: */
+ sigemptyset(&_thread_run->sigpend);
+
+ /*
+ * Create a pipe that is written to by the signal handler to
+ * prevent signals being missed in calls to
+ * _thread_sys_select:
+ */
+ if (_thread_sys_pipe(_thread_kern_pipe) != 0) {
+ /* Cannot create pipe, so abort: */
+ PANIC("Cannot create pthread kernel pipe for forked process");
+ }
+ /* Get the flags for the read pipe: */
+ else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[0], F_GETFL, NULL)) == -1) {
+ /* Abort this application: */
+ abort();
+ }
+ /* Make the read pipe non-blocking: */
+ else if (_thread_sys_fcntl(_thread_kern_pipe[0], F_SETFL, flags | O_NONBLOCK) == -1) {
+ /* Abort this application: */
+ abort();
+ }
+ /* Get the flags for the write pipe: */
+ else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[1], F_GETFL, NULL)) == -1) {
+ /* Abort this application: */
+ abort();
+ }
+ /* Make the write pipe non-blocking: */
+ else if (_thread_sys_fcntl(_thread_kern_pipe[1], F_SETFL, flags | O_NONBLOCK) == -1) {
+ /* Abort this application: */
+ abort();
+ }
+ /* Reinitialize the GC mutex: */
+ else if (_mutex_reinit(&_gc_mutex) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot initialize GC mutex for forked process");
+ }
+ /* Reinitialize the GC condition variable: */
+ else if (_cond_reinit(&_gc_cond) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot initialize GC condvar for forked process");
+ }
+ /* Initialize the ready queue: */
+ else if (_pq_init(&_readyq) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot initialize priority ready queue.");
+ } else {
+ /*
+ * Enter a loop to remove all threads other than
+ * the running thread from the thread list:
+ */
+ pthread = TAILQ_FIRST(&_thread_list);
+ while (pthread != NULL) {
+ /* Save the thread to be freed: */
+ pthread_save = pthread;
+
+ /*
+ * Advance to the next thread before
+ * destroying the current thread:
+ */
+ pthread = TAILQ_NEXT(pthread, dle);
+
+ /* Make sure this isn't the running thread: */
+ if (pthread_save != _thread_run) {
+ /* Remove this thread from the list: */
+ TAILQ_REMOVE(&_thread_list,
+ pthread_save, tle);
+
+ if (pthread_save->attr.stackaddr_attr ==
+ NULL && pthread_save->stack != NULL)
+ if (pthread_save->attr.stacksize_attr
+ == PTHREAD_STACK_DEFAULT) {
+ /*
+ * Default-size stack. Cache
+ * it:
+ */
+ struct stack *spare_stack;
+
+ spare_stack
+ = (pthread_save->stack
+ + PTHREAD_STACK_DEFAULT
+ - sizeof(struct stack));
+ SLIST_INSERT_HEAD(
+ &_stackq,
+ spare_stack,
+ qe);
+ } else
+ /*
+ * Free the stack of
+ * the dead thread:
+ */
+ free(pthread_save->stack);
+
+ if (pthread_save->specific_data != NULL)
+ free(pthread_save->specific_data);
+
+ if (pthread_save->poll_data.fds != NULL)
+ free(pthread_save->poll_data.fds);
+
+ free(pthread_save);
+ }
+ }
+
+ /* Treat the current thread as the initial thread: */
+ _thread_initial = _thread_run;
+
+ /* Re-init the dead thread list: */
+ TAILQ_INIT(&_dead_list);
+
+ /* Re-init the waiting and work queues. */
+ TAILQ_INIT(&_waitingq);
+ TAILQ_INIT(&_workq);
+
+ /* Re-init the threads mutex queue: */
+ TAILQ_INIT(&_thread_run->mutexq);
+
+ /* No spinlocks yet: */
+ _spinblock_count = 0;
+
+ /* Don't queue signals yet: */
+ _queue_signals = 0;
+
+ /* Initialize signal handling: */
+ _thread_sig_init();
+
+ /* Initialize the scheduling switch hook routine: */
+ _sched_switch_hook = NULL;
+
+ /* Clear out any locks in the file descriptor table: */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ if (_thread_fd_table[i] != NULL) {
+ /* Initialise the file locks: */
+ memset(&_thread_fd_table[i]->lock, 0,
+ sizeof(_thread_fd_table[i]->lock));
+ _thread_fd_table[i]->r_owner = NULL;
+ _thread_fd_table[i]->w_owner = NULL;
+ _thread_fd_table[i]->r_fname = NULL;
+ _thread_fd_table[i]->w_fname = NULL;
+ _thread_fd_table[i]->r_lineno = 0;;
+ _thread_fd_table[i]->w_lineno = 0;;
+ _thread_fd_table[i]->r_lockcount = 0;;
+ _thread_fd_table[i]->w_lockcount = 0;;
+
+ /* Initialise the read/write queues: */
+ TAILQ_INIT(&_thread_fd_table[i]->r_queue);
+ TAILQ_INIT(&_thread_fd_table[i]->w_queue);
+ }
+ }
+ }
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding if necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ /* Return the process ID: */
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_fsync.c b/lib/libpthread/thread/thr_fsync.c
new file mode 100644
index 0000000..21c3b56
--- /dev/null
+++ b/lib/libpthread/thread/thr_fsync.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+fsync(int fd)
+{
+ int ret;
+
+ _thread_enter_cancellation_point();
+ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
+ ret = _thread_sys_fsync(fd);
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_gc.c b/lib/libpthread/thread/thr_gc.c
new file mode 100644
index 0000000..d748049
--- /dev/null
+++ b/lib/libpthread/thread/thr_gc.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ * Garbage collector thread. Frees memory allocated for dead threads.
+ *
+ */
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <pthread.h>
+#include "pthread_private.h"
+
+pthread_addr_t
+_thread_gc(pthread_addr_t arg)
+{
+ int f_debug;
+ int f_done = 0;
+ int ret;
+ sigset_t mask;
+ pthread_t pthread;
+ pthread_t pthread_cln;
+ pthread_t pthread_nxt;
+ pthread_t pthread_prv;
+ struct timespec abstime;
+ void *p_stack;
+
+ /* Block all signals */
+ sigfillset (&mask);
+ sigprocmask (SIG_BLOCK, &mask, NULL);
+
+ /* Mark this thread as a library thread (not a user thread). */
+ _thread_run->flags |= PTHREAD_FLAGS_PRIVATE;
+
+ /* Set a debug flag based on an environment variable. */
+ f_debug = (getenv("LIBC_R_DEBUG") != NULL);
+
+ /* Set the name of this thread. */
+ pthread_set_name_np(_thread_run,"GC");
+
+ while (!f_done) {
+ /* Check if debugging this application. */
+ if (f_debug)
+ /* Dump thread info to file. */
+ _thread_dump_info();
+
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Check if this is the last running thread: */
+ if (TAILQ_FIRST(&_thread_list) == _thread_run &&
+ TAILQ_NEXT(_thread_run, tle) == NULL)
+ /*
+ * This is the last thread, so it can exit
+ * now.
+ */
+ f_done = 1;
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ /*
+ * Lock the garbage collector mutex which ensures that
+ * this thread sees another thread exit:
+ */
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
+
+ /* No stack of thread structure to free yet: */
+ p_stack = NULL;
+ pthread_cln = NULL;
+
+ /*
+ * Enter a loop to search for the first dead thread that
+ * has memory to free.
+ */
+ for (pthread = TAILQ_FIRST(&_dead_list);
+ p_stack == NULL && pthread_cln == NULL && pthread != NULL;
+ pthread = TAILQ_NEXT(pthread, dle)) {
+ /* Check if the initial thread: */
+ if (pthread == _thread_initial) {
+ /* Don't destroy the initial thread. */
+ }
+ /*
+ * Check if this thread has detached:
+ */
+ else if ((pthread->attr.flags &
+ PTHREAD_DETACHED) != 0) {
+ /* Remove this thread from the dead list: */
+ TAILQ_REMOVE(&_dead_list, pthread, dle);
+
+ /*
+ * Check if the stack was not specified by
+ * the caller to pthread_create and has not
+ * been destroyed yet:
+ */
+ if (pthread->attr.stackaddr_attr == NULL &&
+ pthread->stack != NULL) {
+ if (pthread->attr.stacksize_attr
+ == PTHREAD_STACK_DEFAULT) {
+ /*
+ * Default-size stack. Cache
+ * it:
+ */
+ struct stack *spare_stack;
+
+ spare_stack
+ = (pthread->stack
+ + PTHREAD_STACK_DEFAULT
+ - sizeof(struct stack));
+ SLIST_INSERT_HEAD(&_stackq,
+ spare_stack,
+ qe);
+ } else {
+ /*
+ * Non-standard stack size.
+ * free() it outside the locks.
+ */
+ p_stack = pthread->stack;
+ }
+ }
+
+ /*
+ * Point to the thread structure that must
+ * be freed outside the locks:
+ */
+ pthread_cln = pthread;
+
+ } else {
+ /*
+ * This thread has not detached, so do
+ * not destroy it.
+ *
+ * Check if the stack was not specified by
+ * the caller to pthread_create and has not
+ * been destroyed yet:
+ */
+ if (pthread->attr.stackaddr_attr == NULL &&
+ pthread->stack != NULL) {
+ if (pthread->attr.stacksize_attr
+ == PTHREAD_STACK_DEFAULT) {
+ /*
+ * Default-size stack. Cache
+ * it:
+ */
+ struct stack *spare_stack;
+
+ spare_stack
+ = (pthread->stack
+ + PTHREAD_STACK_DEFAULT
+ - sizeof(struct stack));
+ SLIST_INSERT_HEAD(&_stackq,
+ spare_stack,
+ qe);
+ } else {
+ /*
+ * Non-standard stack size.
+ * free() it outside the locks:
+ */
+ p_stack = pthread->stack;
+ }
+
+ /*
+ * NULL the stack pointer now
+ * that the memory has been freed:
+ */
+ pthread->stack = NULL;
+ }
+ }
+ }
+
+ /*
+ * Check if this is not the last thread and there is no
+ * memory to free this time around.
+ */
+ if (!f_done && p_stack == NULL && pthread_cln == NULL) {
+ /* Get the current time. */
+ if (clock_gettime(CLOCK_REALTIME,&abstime) != 0)
+ PANIC("gc cannot get time");
+
+ /*
+ * Do a backup poll in 10 seconds if no threads
+ * die before then.
+ */
+ abstime.tv_sec += 10;
+
+ /*
+ * Wait for a signal from a dying thread or a
+ * timeout (for a backup poll).
+ */
+ if ((ret = pthread_cond_timedwait(&_gc_cond,
+ &_gc_mutex, &abstime)) != 0 && ret != ETIMEDOUT)
+ PANIC("gc cannot wait for a signal");
+ }
+
+ /* Unlock the garbage collector mutex: */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
+
+ /*
+ * If there is memory to free, do it now. The call to
+ * free() might block, so this must be done outside the
+ * locks.
+ */
+ if (p_stack != NULL)
+ free(p_stack);
+ if (pthread_cln != NULL)
+ /*
+ * Free the memory allocated for the thread
+ * structure.
+ */
+ free(pthread_cln);
+ }
+ return (NULL);
+}
diff --git a/lib/libpthread/thread/thr_getprio.c b/lib/libpthread/thread/thr_getprio.c
new file mode 100644
index 0000000..2f94b86
--- /dev/null
+++ b/lib/libpthread/thread/thr_getprio.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_getprio(pthread_t pthread)
+{
+ int policy, ret;
+ struct sched_param param;
+
+ if ((ret = pthread_getschedparam(pthread, &policy, &param)) == 0)
+ ret = param.sched_priority;
+ else {
+ /* Invalid thread: */
+ errno = ret;
+ ret = -1;
+ }
+
+ /* Return the thread priority or an error status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_getschedparam.c b/lib/libpthread/thread/thr_getschedparam.c
new file mode 100644
index 0000000..09d8c1b
--- /dev/null
+++ b/lib/libpthread/thread/thr_getschedparam.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_getschedparam(pthread_t pthread, int *policy,
+ struct sched_param *param)
+{
+ int ret;
+
+ if ((param == NULL) || (policy == NULL))
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+
+ /* Find the thread in the list of active threads: */
+ else if ((ret = _find_thread(pthread)) == 0) {
+ /* Return the threads base priority and scheduling policy: */
+ param->sched_priority = pthread->base_priority;
+ *policy = pthread->attr.sched_policy;
+ }
+
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_info.c b/lib/libpthread/thread/thr_info.c
new file mode 100644
index 0000000..06b556e
--- /dev/null
+++ b/lib/libpthread/thread/thr_info.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include <errno.h>
+#include "pthread_private.h"
+
+struct s_thread_info {
+ enum pthread_state state;
+ char *name;
+};
+
+/* Static variables: */
+static const struct s_thread_info thread_info[] = {
+ {PS_RUNNING , "Running"},
+ {PS_SIGTHREAD , "Waiting on signal thread"},
+ {PS_MUTEX_WAIT , "Waiting on a mutex"},
+ {PS_COND_WAIT , "Waiting on a condition variable"},
+ {PS_FDLR_WAIT , "Waiting for a file read lock"},
+ {PS_FDLW_WAIT , "Waiting for a file write lock"},
+ {PS_FDR_WAIT , "Waiting for read"},
+ {PS_FDW_WAIT , "Waiting for write"},
+ {PS_FILE_WAIT , "Waiting for FILE lock"},
+ {PS_POLL_WAIT , "Waiting on poll"},
+ {PS_SELECT_WAIT , "Waiting on select"},
+ {PS_SLEEP_WAIT , "Sleeping"},
+ {PS_WAIT_WAIT , "Waiting process"},
+ {PS_SIGSUSPEND , "Suspended, waiting for a signal"},
+ {PS_SIGWAIT , "Waiting for a signal"},
+ {PS_SPINBLOCK , "Waiting for a spinlock"},
+ {PS_JOIN , "Waiting to join"},
+ {PS_SUSPENDED , "Suspended"},
+ {PS_DEAD , "Dead"},
+ {PS_DEADLOCK , "Deadlocked"},
+ {PS_STATE_MAX , "Not a real state!"}
+};
+
+void
+_thread_dump_info(void)
+{
+ char s[512];
+ int fd;
+ int i;
+ int j;
+ pthread_t pthread;
+ char tmpfile[128];
+ pq_list_t *pq_list;
+
+ for (i = 0; i < 100000; i++) {
+ snprintf(tmpfile, sizeof(tmpfile), "/tmp/uthread.dump.%u.%i",
+ getpid(), i);
+ /* Open the dump file for append and create it if necessary: */
+ if ((fd = _thread_sys_open(tmpfile, O_RDWR | O_CREAT | O_EXCL,
+ 0666)) < 0) {
+ /* Can't open the dump file. */
+ if (errno == EEXIST)
+ continue;
+ /*
+ * We only need to continue in case of
+ * EEXIT error. Most other error
+ * codes means that we will fail all
+ * the times.
+ */
+ return;
+ } else {
+ break;
+ }
+ }
+ if (i==100000) {
+ /* all 100000 possibilities are in use :( */
+ return;
+ } else {
+ /* Output a header for active threads: */
+ strcpy(s, "\n\n=============\nACTIVE THREADS\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report each thread in the global list: */
+ TAILQ_FOREACH(pthread, &_thread_list, tle) {
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
+ break;
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->base_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Check if this is the running thread: */
+ if (pthread == _thread_run) {
+ /* Output a record for the running thread: */
+ strcpy(s, "This is the running thread\n");
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ /* Check if this is the initial thread: */
+ if (pthread == _thread_initial) {
+ /* Output a record for the initial thread: */
+ strcpy(s, "This is the initial thread\n");
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ /* Process according to thread state: */
+ switch (pthread->state) {
+ /* File descriptor read lock wait: */
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ /* Write the lock details: */
+ snprintf(s, sizeof(s), "fd %d[%s:%d]",
+ pthread->data.fd.fd,
+ pthread->data.fd.fname,
+ pthread->data.fd.branch);
+ _thread_sys_write(fd, s, strlen(s));
+ snprintf(s, sizeof(s), "owner %pr/%pw\n",
+ _thread_fd_table[pthread->data.fd.fd]->r_owner,
+ _thread_fd_table[pthread->data.fd.fd]->w_owner);
+ _thread_sys_write(fd, s, strlen(s));
+ break;
+ case PS_SIGWAIT:
+ snprintf(s, sizeof(s), "sigmask (hi)");
+ _thread_sys_write(fd, s, strlen(s));
+ for (i = _SIG_WORDS - 1; i >= 0; i--) {
+ snprintf(s, sizeof(s), "%08x\n",
+ pthread->sigmask.__bits[i]);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ snprintf(s, sizeof(s), "(lo)\n");
+ _thread_sys_write(fd, s, strlen(s));
+ break;
+
+ /*
+ * Trap other states that are not explicitly
+ * coded to dump information:
+ */
+ default:
+ /* Nothing to do here. */
+ break;
+ }
+ }
+
+ /* Output a header for ready threads: */
+ strcpy(s, "\n\n=============\nREADY THREADS\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report each thread in the ready queue: */
+ TAILQ_FOREACH (pq_list, &_readyq.pq_queue, pl_link) {
+ TAILQ_FOREACH(pthread, &pq_list->pl_head, pqe) {
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
+ break;
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->base_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ }
+
+ /* Output a header for waiting threads: */
+ strcpy(s, "\n\n=============\nWAITING THREADS\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report each thread in the waiting queue: */
+ TAILQ_FOREACH (pthread, &_waitingq, pqe) {
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
+ break;
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->base_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+
+ /* Output a header for threads in the work queue: */
+ strcpy(s, "\n\n=============\nTHREADS IN WORKQ\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report each thread in the waiting queue: */
+ TAILQ_FOREACH (pthread, &_workq, qe) {
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
+ break;
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->base_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+
+ /* Check if there are no dead threads: */
+ if (TAILQ_FIRST(&_dead_list) == NULL) {
+ /* Output a record: */
+ strcpy(s, "\n\nTHERE ARE NO DEAD THREADS\n");
+ _thread_sys_write(fd, s, strlen(s));
+ } else {
+ /* Output a header for dead threads: */
+ strcpy(s, "\n\nDEAD THREADS\n\n");
+ _thread_sys_write(fd, s, strlen(s));
+
+ /*
+ * Enter a loop to report each thread in the global
+ * dead thread list:
+ */
+ TAILQ_FOREACH(pthread, &_dead_list, dle) {
+ /* Output a record for the current thread: */
+ snprintf(s, sizeof(s),
+ "Thread %p prio %3d [%s:%d]\n",
+ pthread, pthread->base_priority,
+ pthread->fname,pthread->lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ }
+
+ /* Output a header for file descriptors: */
+ snprintf(s, sizeof(s), "\n\n=============\nFILE DESCRIPTOR TABLE (table size %d)\n\n",_thread_dtablesize);
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Enter a loop to report file descriptor lock usage: */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /*
+ * Check if memory is allocated for this file
+ * descriptor:
+ */
+ if (_thread_fd_table[i] != NULL) {
+ /* Report the file descriptor lock status: */
+ snprintf(s, sizeof(s),
+ "fd[%3d] read owner %p count %d [%s:%d]\n write owner %p count %d [%s:%d]\n",
+ i,
+ _thread_fd_table[i]->r_owner,
+ _thread_fd_table[i]->r_lockcount,
+ _thread_fd_table[i]->r_fname,
+ _thread_fd_table[i]->r_lineno,
+ _thread_fd_table[i]->w_owner,
+ _thread_fd_table[i]->w_lockcount,
+ _thread_fd_table[i]->w_fname,
+ _thread_fd_table[i]->w_lineno);
+ _thread_sys_write(fd, s, strlen(s));
+ }
+ }
+
+ /* Close the dump file: */
+ _thread_sys_close(fd);
+ }
+ return;
+}
+
+/* Set the thread name for debug: */
+void
+pthread_set_name_np(pthread_t thread, char *name)
+{
+ /* Check if the caller has specified a valid thread: */
+ if (thread != NULL && thread->magic == PTHREAD_MAGIC)
+ thread->name = strdup(name);
+ return;
+}
+#endif
diff --git a/lib/libpthread/thread/thr_init.c b/lib/libpthread/thread/thr_init.c
new file mode 100644
index 0000000..bab7e5b
--- /dev/null
+++ b/lib/libpthread/thread/thr_init.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/* Allocate space for global thread variables here: */
+#define GLOBAL_PTHREAD_PRIVATE
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <poll.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/ttycom.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/mman.h>
+#ifdef _THREAD_SAFE
+#include <machine/reg.h>
+#include <pthread.h>
+#include "pthread_private.h"
+
+#ifdef GCC_2_8_MADE_THREAD_AWARE
+typedef void *** (*dynamic_handler_allocator)();
+extern void __set_dynamic_handler_allocator(dynamic_handler_allocator);
+
+static pthread_key_t except_head_key;
+
+typedef struct {
+ void **__dynamic_handler_chain;
+ void *top_elt[2];
+} except_struct;
+
+static void ***dynamic_allocator_handler_fn()
+{
+ except_struct *dh = (except_struct *)pthread_getspecific(except_head_key);
+
+ if(dh == NULL) {
+ dh = (except_struct *)malloc( sizeof(except_struct) );
+ memset(dh, '\0', sizeof(except_struct));
+ dh->__dynamic_handler_chain= dh->top_elt;
+ pthread_setspecific(except_head_key, (void *)dh);
+ }
+ return &dh->__dynamic_handler_chain;
+}
+#endif /* GCC_2_8_MADE_THREAD_AWARE */
+
+/*
+ * Threaded process initialization
+ */
+void
+_thread_init(void)
+{
+ int fd;
+ int flags;
+ int i;
+ size_t len;
+ int mib[2];
+ struct clockinfo clockinfo;
+ struct sigaction act;
+
+ /* Check if this function has already been called: */
+ if (_thread_initial)
+ /* Only initialise the threaded application once. */
+ return;
+
+ /*
+ * Check for the special case of this process running as
+ * or in place of init as pid = 1:
+ */
+ if (getpid() == 1) {
+ /*
+ * Setup a new session for this process which is
+ * assumed to be running as root.
+ */
+ if (setsid() == -1)
+ PANIC("Can't set session ID");
+ if (revoke(_PATH_CONSOLE) != 0)
+ PANIC("Can't revoke console");
+ if ((fd = _thread_sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
+ PANIC("Can't open console");
+ if (setlogin("root") == -1)
+ PANIC("Can't set login to root");
+ if (_thread_sys_ioctl(fd,TIOCSCTTY, (char *) NULL) == -1)
+ PANIC("Can't set controlling terminal");
+ if (_thread_sys_dup2(fd,0) == -1 ||
+ _thread_sys_dup2(fd,1) == -1 ||
+ _thread_sys_dup2(fd,2) == -1)
+ PANIC("Can't dup2");
+ }
+
+ /* Get the standard I/O flags before messing with them : */
+ for (i = 0; i < 3; i++)
+ if (((_pthread_stdio_flags[i] =
+ _thread_sys_fcntl(i,F_GETFL, NULL)) == -1) &&
+ (errno != EBADF))
+ PANIC("Cannot get stdio flags");
+
+ /*
+ * Create a pipe that is written to by the signal handler to prevent
+ * signals being missed in calls to _select:
+ */
+ if (_thread_sys_pipe(_thread_kern_pipe) != 0) {
+ /* Cannot create pipe, so abort: */
+ PANIC("Cannot create kernel pipe");
+ }
+ /* Get the flags for the read pipe: */
+ else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[0], F_GETFL, NULL)) == -1) {
+ /* Abort this application: */
+ PANIC("Cannot get kernel read pipe flags");
+ }
+ /* Make the read pipe non-blocking: */
+ else if (_thread_sys_fcntl(_thread_kern_pipe[0], F_SETFL, flags | O_NONBLOCK) == -1) {
+ /* Abort this application: */
+ PANIC("Cannot make kernel read pipe non-blocking");
+ }
+ /* Get the flags for the write pipe: */
+ else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[1], F_GETFL, NULL)) == -1) {
+ /* Abort this application: */
+ PANIC("Cannot get kernel write pipe flags");
+ }
+ /* Make the write pipe non-blocking: */
+ else if (_thread_sys_fcntl(_thread_kern_pipe[1], F_SETFL, flags | O_NONBLOCK) == -1) {
+ /* Abort this application: */
+ PANIC("Cannot get kernel write pipe flags");
+ }
+ /* Allocate and initialize the ready queue: */
+ else if (_pq_alloc(&_readyq, PTHREAD_MIN_PRIORITY, PTHREAD_MAX_PRIORITY) != 0) {
+ /* Abort this application: */
+ PANIC("Cannot allocate priority ready queue.");
+ }
+ /* Allocate memory for the thread structure of the initial thread: */
+ else if ((_thread_initial = (pthread_t) malloc(sizeof(struct pthread))) == NULL) {
+ /*
+ * Insufficient memory to initialise this application, so
+ * abort:
+ */
+ PANIC("Cannot allocate memory for initial thread");
+ } else {
+ /* Zero the global kernel thread structure: */
+ memset(&_thread_kern_thread, 0, sizeof(struct pthread));
+ _thread_kern_thread.flags = PTHREAD_FLAGS_PRIVATE;
+ memset(_thread_initial, 0, sizeof(struct pthread));
+
+ /* Initialize the waiting and work queues: */
+ TAILQ_INIT(&_waitingq);
+ TAILQ_INIT(&_workq);
+
+ /* Initialize the scheduling switch hook routine: */
+ _sched_switch_hook = NULL;
+
+ /* Initialize the thread stack cache: */
+ SLIST_INIT(&_stackq);
+
+ /* Create the red zone for the main stack. */
+ if (mmap((void *) USRSTACK
+ - PTHREAD_STACK_INITIAL,
+ PTHREAD_STACK_GUARD, 0, MAP_ANON,
+ -1, 0) == MAP_FAILED) {
+ PANIC("Cannot allocate red zone for initial thread");
+ }
+
+ /*
+ * Write a magic value to the thread structure
+ * to help identify valid ones:
+ */
+ _thread_initial->magic = PTHREAD_MAGIC;
+
+ /* Set the initial cancel state */
+ _thread_initial->cancelflags = PTHREAD_CANCEL_ENABLE |
+ PTHREAD_CANCEL_DEFERRED;
+
+ /* Default the priority of the initial thread: */
+ _thread_initial->base_priority = PTHREAD_DEFAULT_PRIORITY;
+ _thread_initial->active_priority = PTHREAD_DEFAULT_PRIORITY;
+ _thread_initial->inherited_priority = 0;
+
+ /* Initialise the state of the initial thread: */
+ _thread_initial->state = PS_RUNNING;
+
+ /* Initialise the queue: */
+ TAILQ_INIT(&(_thread_initial->join_queue));
+
+ /* Initialize the owned mutex queue and count: */
+ TAILQ_INIT(&(_thread_initial->mutexq));
+ _thread_initial->priority_mutex_count = 0;
+
+ /* Initialise the rest of the fields: */
+ _thread_initial->poll_data.nfds = 0;
+ _thread_initial->poll_data.fds = NULL;
+ _thread_initial->sig_defer_count = 0;
+ _thread_initial->yield_on_sig_undefer = 0;
+ _thread_initial->specific_data = NULL;
+ _thread_initial->cleanup = NULL;
+ _thread_initial->flags = 0;
+ _thread_initial->error = 0;
+ TAILQ_INIT(&_thread_list);
+ TAILQ_INSERT_HEAD(&_thread_list, _thread_initial, tle);
+ _thread_run = _thread_initial;
+
+ /* Initialise the global signal action structure: */
+ sigfillset(&act.sa_mask);
+ act.sa_handler = (void (*) ()) _thread_sig_handler;
+ act.sa_flags = 0;
+
+ /* Initialize signal handling: */
+ _thread_sig_init();
+
+ /* Enter a loop to get the existing signal status: */
+ for (i = 1; i < NSIG; i++) {
+ /* Check for signals which cannot be trapped: */
+ if (i == SIGKILL || i == SIGSTOP) {
+ }
+
+ /* Get the signal handler details: */
+ else if (_thread_sys_sigaction(i, NULL,
+ &_thread_sigact[i - 1]) != 0) {
+ /*
+ * Abort this process if signal
+ * initialisation fails:
+ */
+ PANIC("Cannot read signal handler info");
+ }
+ }
+
+ /*
+ * Install the signal handler for the most important
+ * signals that the user-thread kernel needs. Actually
+ * SIGINFO isn't really needed, but it is nice to have.
+ */
+ if (_thread_sys_sigaction(_SCHED_SIGNAL, &act, NULL) != 0 ||
+ _thread_sys_sigaction(SIGINFO, &act, NULL) != 0 ||
+ _thread_sys_sigaction(SIGCHLD, &act, NULL) != 0) {
+ /*
+ * Abort this process if signal initialisation fails:
+ */
+ PANIC("Cannot initialise signal handler");
+ }
+
+ /* Get the kernel clockrate: */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_CLOCKRATE;
+ len = sizeof (struct clockinfo);
+ if (sysctl(mib, 2, &clockinfo, &len, NULL, 0) == 0)
+ _clock_res_nsec = clockinfo.tick * 1000;
+
+ /* Get the table size: */
+ if ((_thread_dtablesize = getdtablesize()) < 0) {
+ /*
+ * Cannot get the system defined table size, so abort
+ * this process.
+ */
+ PANIC("Cannot get dtablesize");
+ }
+ /* Allocate memory for the file descriptor table: */
+ if ((_thread_fd_table = (struct fd_table_entry **) malloc(sizeof(struct fd_table_entry *) * _thread_dtablesize)) == NULL) {
+ /* Avoid accesses to file descriptor table on exit: */
+ _thread_dtablesize = 0;
+
+ /*
+ * Cannot allocate memory for the file descriptor
+ * table, so abort this process.
+ */
+ PANIC("Cannot allocate memory for file descriptor table");
+ }
+ /* Allocate memory for the pollfd table: */
+ if ((_thread_pfd_table = (struct pollfd *) malloc(sizeof(struct pollfd) * _thread_dtablesize)) == NULL) {
+ /*
+ * Cannot allocate memory for the file descriptor
+ * table, so abort this process.
+ */
+ PANIC("Cannot allocate memory for pollfd table");
+ } else {
+ /*
+ * Enter a loop to initialise the file descriptor
+ * table:
+ */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /* Initialise the file descriptor table: */
+ _thread_fd_table[i] = NULL;
+ }
+
+ /* Initialize stdio file descriptor table entries: */
+ for (i = 0; i < 3; i++) {
+ if ((_thread_fd_table_init(i) != 0) &&
+ (errno != EBADF))
+ PANIC("Cannot initialize stdio file "
+ "descriptor table entry");
+ }
+ }
+ }
+
+#ifdef GCC_2_8_MADE_THREAD_AWARE
+ /* Create the thread-specific data for the exception linked list. */
+ if(pthread_key_create(&except_head_key, NULL) != 0)
+ PANIC("Failed to create thread specific execption head");
+
+ /* Setup the gcc exception handler per thread. */
+ __set_dynamic_handler_allocator( dynamic_allocator_handler_fn );
+#endif /* GCC_2_8_MADE_THREAD_AWARE */
+
+ /* Initialise the garbage collector mutex and condition variable. */
+ if (pthread_mutex_init(&_gc_mutex,NULL) != 0 ||
+ pthread_cond_init(&_gc_cond,NULL) != 0)
+ PANIC("Failed to initialise garbage collector mutex or condvar");
+
+ gettimeofday(&kern_inc_prio_time, NULL);
+
+ return;
+}
+
+/*
+ * Special start up code for NetBSD/Alpha
+ */
+#if defined(__NetBSD__) && defined(__alpha__)
+int
+main(int argc, char *argv[], char *env);
+
+int
+_thread_main(int argc, char *argv[], char *env)
+{
+ _thread_init();
+ return (main(argc, argv, env));
+}
+#endif
+#else
+/*
+ * A stub for non-threaded programs.
+ */
+void
+_thread_init(void)
+{
+}
+#endif
diff --git a/lib/libpthread/thread/thr_join.c b/lib/libpthread/thread/thr_join.c
new file mode 100644
index 0000000..155dc64
--- /dev/null
+++ b/lib/libpthread/thread/thr_join.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_join(pthread_t pthread, void **thread_return)
+{
+ int ret = 0;
+ pthread_t pthread1 = NULL;
+
+ _thread_enter_cancellation_point();
+
+ /* Check if the caller has specified an invalid thread: */
+ if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) {
+ /* Invalid thread: */
+ _thread_leave_cancellation_point();
+ return(EINVAL);
+ }
+
+ /* Check if the caller has specified itself: */
+ if (pthread == _thread_run) {
+ /* Avoid a deadlock condition: */
+ _thread_leave_cancellation_point();
+ return(EDEADLK);
+ }
+
+ /*
+ * Find the thread in the list of active threads or in the
+ * list of dead threads:
+ */
+ if (_find_thread(pthread) == 0 ||
+ _find_dead_thread(pthread) == 0)
+ pthread1 = pthread;
+
+ if (pthread1 == NULL)
+ /* Return an error: */
+ ret = ESRCH;
+
+ /* Check if this thread has been detached: */
+ else if ((pthread->attr.flags & PTHREAD_DETACHED) != 0)
+ /* Return an error: */
+ ret = ESRCH;
+
+ /* Check if the thread is not dead: */
+ else if (pthread->state != PS_DEAD) {
+ /* Clear the interrupted flag: */
+ _thread_run->interrupted = 0;
+
+ /*
+ * Protect against being context switched out while
+ * adding this thread to the join queue.
+ */
+ _thread_kern_sig_defer();
+
+ /* Add the running thread to the join queue: */
+ TAILQ_INSERT_TAIL(&(pthread->join_queue), _thread_run, qe);
+
+ /* Schedule the next thread: */
+ _thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__);
+
+ if (_thread_run->interrupted != 0)
+ TAILQ_REMOVE(&(pthread->join_queue), _thread_run, qe);
+
+ _thread_kern_sig_undefer();
+
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+
+ /* Check if the thread is not detached: */
+ if ((pthread->attr.flags & PTHREAD_DETACHED) == 0) {
+ /* Check if the return value is required: */
+ if (thread_return)
+ /* Return the thread's return value: */
+ *thread_return = pthread->ret;
+ }
+ else
+ /* Return an error: */
+ ret = ESRCH;
+
+ /* Check if the return value is required: */
+ } else if (thread_return != NULL)
+ /* Return the thread's return value: */
+ *thread_return = pthread->ret;
+
+ _thread_leave_cancellation_point();
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c
new file mode 100644
index 0000000..b3fbc3a
--- /dev/null
+++ b/lib/libpthread/thread/thr_kern.c
@@ -0,0 +1,1135 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <errno.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <setjmp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Static function prototype definitions: */
+static void
+_thread_kern_poll(int wait_reqd);
+
+static void
+dequeue_signals(void);
+
+static inline void
+thread_run_switch_hook(pthread_t thread_out, pthread_t thread_in);
+
+void
+_thread_kern_sched(ucontext_t * scp)
+{
+#ifndef __alpha__
+ char *fdata;
+#endif
+ pthread_t pthread, pthread_h = NULL;
+ struct itimerval itimer;
+ struct timespec ts, ts1;
+ struct timeval tv, tv1;
+ int set_timer = 0;
+
+ /*
+ * Flag the pthread kernel as executing scheduler code
+ * to avoid a scheduler signal from interrupting this
+ * execution and calling the scheduler again.
+ */
+ _thread_kern_in_sched = 1;
+
+ /* Check if this function was called from the signal handler: */
+ if (scp != NULL) {
+ /*
+ * Copy the signal context to the current thread's jump
+ * buffer:
+ */
+ memcpy(&_thread_run->saved_sigcontext, scp, sizeof(_thread_run->saved_sigcontext));
+
+#ifndef __alpha__
+ /* Point to the floating point data in the running thread: */
+ fdata = _thread_run->saved_fp;
+
+ /* Save the floating point data: */
+__asm__("fnsave %0": :"m"(*fdata));
+#endif
+
+ /* Flag the signal context as the last state saved: */
+ _thread_run->sig_saved = 1;
+ }
+ /* Save the state of the current thread: */
+ else if (setjmp(_thread_run->saved_jmp_buf) != 0) {
+ /*
+ * This point is reached when a longjmp() is called to
+ * restore the state of a thread.
+ *
+ * This is the normal way out of the scheduler.
+ */
+ _thread_kern_in_sched = 0;
+
+ if (((_thread_run->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0) &&
+ ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)) {
+ /*
+ * Cancellations override signals.
+ *
+ * Stick a cancellation point at the start of
+ * each async-cancellable thread's resumption.
+ *
+ * We allow threads woken at cancel points to do their
+ * own checks.
+ */
+ pthread_testcancel();
+ }
+
+ if (_sched_switch_hook != NULL) {
+ /* Run the installed switch hook: */
+ thread_run_switch_hook(_last_user_thread, _thread_run);
+ }
+
+ return;
+ } else
+ /* Flag the jump buffer was the last state saved: */
+ _thread_run->sig_saved = 0;
+
+ /* If the currently running thread is a user thread, save it: */
+ if ((_thread_run->flags & PTHREAD_FLAGS_PRIVATE) == 0)
+ _last_user_thread = _thread_run;
+
+ /*
+ * Enter a scheduling loop that finds the next thread that is
+ * ready to run. This loop completes when there are no more threads
+ * in the global list or when a thread has its state restored by
+ * either a sigreturn (if the state was saved as a sigcontext) or a
+ * longjmp (if the state was saved by a setjmp).
+ */
+ while (!(TAILQ_EMPTY(&_thread_list))) {
+ /* Get the current time of day: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
+
+ /*
+ * Protect the scheduling queues from access by the signal
+ * handler.
+ */
+ _queue_signals = 1;
+
+ if (_thread_run != &_thread_kern_thread) {
+
+ /*
+ * This thread no longer needs to yield the CPU.
+ */
+ _thread_run->yield_on_sig_undefer = 0;
+
+ /*
+ * Save the current time as the time that the thread
+ * became inactive:
+ */
+ _thread_run->last_inactive.tv_sec = tv.tv_sec;
+ _thread_run->last_inactive.tv_usec = tv.tv_usec;
+
+ /*
+ * Place the currently running thread into the
+ * appropriate queue(s).
+ */
+ switch (_thread_run->state) {
+ case PS_DEAD:
+ case PS_STATE_MAX: /* to silence -Wall */
+ /*
+ * Dead threads are not placed in any queue:
+ */
+ break;
+
+ case PS_RUNNING:
+ /*
+ * Runnable threads can't be placed in the
+ * priority queue until after waiting threads
+ * are polled (to preserve round-robin
+ * scheduling).
+ */
+ if ((_thread_run->slice_usec != -1) &&
+ (_thread_run->attr.sched_policy != SCHED_FIFO)) {
+ /*
+ * Accumulate the number of microseconds that
+ * this thread has run for:
+ */
+ _thread_run->slice_usec +=
+ (_thread_run->last_inactive.tv_sec -
+ _thread_run->last_active.tv_sec) * 1000000 +
+ _thread_run->last_inactive.tv_usec -
+ _thread_run->last_active.tv_usec;
+
+ /* Check for time quantum exceeded: */
+ if (_thread_run->slice_usec > TIMESLICE_USEC)
+ _thread_run->slice_usec = -1;
+ }
+ break;
+
+ /*
+ * States which do not depend on file descriptor I/O
+ * operations or timeouts:
+ */
+ case PS_DEADLOCK:
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ case PS_JOIN:
+ case PS_MUTEX_WAIT:
+ case PS_SIGSUSPEND:
+ case PS_SIGTHREAD:
+ case PS_SIGWAIT:
+ case PS_SUSPENDED:
+ case PS_WAIT_WAIT:
+ /* No timeouts for these states: */
+ _thread_run->wakeup_time.tv_sec = -1;
+ _thread_run->wakeup_time.tv_nsec = -1;
+
+ /* Restart the time slice: */
+ _thread_run->slice_usec = -1;
+
+ /* Insert into the waiting queue: */
+ PTHREAD_WAITQ_INSERT(_thread_run);
+ break;
+
+ /* States which can timeout: */
+ case PS_COND_WAIT:
+ case PS_SLEEP_WAIT:
+ /* Restart the time slice: */
+ _thread_run->slice_usec = -1;
+
+ /* Insert into the waiting queue: */
+ PTHREAD_WAITQ_INSERT(_thread_run);
+ break;
+
+ /* States that require periodic work: */
+ case PS_SPINBLOCK:
+ /* No timeouts for this state: */
+ _thread_run->wakeup_time.tv_sec = -1;
+ _thread_run->wakeup_time.tv_nsec = -1;
+
+ /* Increment spinblock count: */
+ _spinblock_count++;
+
+ /* fall through */
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Restart the time slice: */
+ _thread_run->slice_usec = -1;
+
+ /* Insert into the waiting queue: */
+ PTHREAD_WAITQ_INSERT(_thread_run);
+
+ /* Insert into the work queue: */
+ PTHREAD_WORKQ_INSERT(_thread_run);
+ break;
+ }
+ }
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ /*
+ * Poll file descriptors to update the state of threads
+ * waiting on file I/O where data may be available:
+ */
+ _thread_kern_poll(0);
+
+ /* Protect the scheduling queues: */
+ _queue_signals = 1;
+
+ /*
+ * Wake up threads that have timedout. This has to be
+ * done after polling in case a thread does a poll or
+ * select with zero time.
+ */
+ PTHREAD_WAITQ_SETACTIVE();
+ while (((pthread = TAILQ_FIRST(&_waitingq)) != NULL) &&
+ (pthread->wakeup_time.tv_sec != -1) &&
+ (((pthread->wakeup_time.tv_sec == 0) &&
+ (pthread->wakeup_time.tv_nsec == 0)) ||
+ (pthread->wakeup_time.tv_sec < ts.tv_sec) ||
+ ((pthread->wakeup_time.tv_sec == ts.tv_sec) &&
+ (pthread->wakeup_time.tv_nsec <= ts.tv_nsec)))) {
+ switch (pthread->state) {
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Return zero file descriptors ready: */
+ pthread->data.poll_data->nfds = 0;
+ /* fall through */
+ default:
+ /*
+ * Remove this thread from the waiting queue
+ * (and work queue if necessary) and place it
+ * in the ready queue.
+ */
+ PTHREAD_WAITQ_CLEARACTIVE();
+ if (pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread, PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ break;
+ }
+ /*
+ * Flag the timeout in the thread structure:
+ */
+ pthread->timeout = 1;
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+
+ /*
+ * Check if there is a current runnable thread that isn't
+ * already in the ready queue:
+ */
+ if ((_thread_run != &_thread_kern_thread) &&
+ (_thread_run->state == PS_RUNNING) &&
+ ((_thread_run->flags & PTHREAD_FLAGS_IN_PRIOQ) == 0)) {
+ if (_thread_run->slice_usec == -1) {
+ /*
+ * The thread exceeded its time
+ * quantum or it yielded the CPU;
+ * place it at the tail of the
+ * queue for its priority.
+ */
+ PTHREAD_PRIOQ_INSERT_TAIL(_thread_run);
+ } else {
+ /*
+ * The thread hasn't exceeded its
+ * interval. Place it at the head
+ * of the queue for its priority.
+ */
+ PTHREAD_PRIOQ_INSERT_HEAD(_thread_run);
+ }
+ }
+
+ /*
+ * Get the highest priority thread in the ready queue.
+ */
+ pthread_h = PTHREAD_PRIOQ_FIRST();
+
+ /* Check if there are no threads ready to run: */
+ if (pthread_h == NULL) {
+ /*
+ * Lock the pthread kernel by changing the pointer to
+ * the running thread to point to the global kernel
+ * thread structure:
+ */
+ _thread_run = &_thread_kern_thread;
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ /*
+ * There are no threads ready to run, so wait until
+ * something happens that changes this condition:
+ */
+ _thread_kern_poll(1);
+ }
+ else {
+ /* Remove the thread from the ready queue: */
+ PTHREAD_PRIOQ_REMOVE(pthread_h);
+
+ /* Get first thread on the waiting list: */
+ pthread = TAILQ_FIRST(&_waitingq);
+
+ /* Check to see if there is more than one thread: */
+ if (pthread_h != TAILQ_FIRST(&_thread_list) ||
+ TAILQ_NEXT(pthread_h, tle) != NULL)
+ set_timer = 1;
+ else
+ set_timer = 0;
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ /*
+ * Check for signals queued while the scheduling
+ * queues were protected:
+ */
+ while (_sigq_check_reqd != 0) {
+ /* Clear before handling queued signals: */
+ _sigq_check_reqd = 0;
+
+ /* Protect the scheduling queues again: */
+ _queue_signals = 1;
+
+ dequeue_signals();
+
+ /*
+ * Check for a higher priority thread that
+ * became runnable due to signal handling.
+ */
+ if (((pthread = PTHREAD_PRIOQ_FIRST()) != NULL) &&
+ (pthread->active_priority > pthread_h->active_priority)) {
+ /*
+ * Insert the lower priority thread
+ * at the head of its priority list:
+ */
+ PTHREAD_PRIOQ_INSERT_HEAD(pthread_h);
+
+ /* Remove the thread from the ready queue: */
+ PTHREAD_PRIOQ_REMOVE(pthread);
+
+ /* There's a new thread in town: */
+ pthread_h = pthread;
+ }
+
+ /* Get first thread on the waiting list: */
+ pthread = TAILQ_FIRST(&_waitingq);
+
+ /*
+ * Check to see if there is more than one
+ * thread:
+ */
+ if (pthread_h != TAILQ_FIRST(&_thread_list) ||
+ TAILQ_NEXT(pthread_h, tle) != NULL)
+ set_timer = 1;
+ else
+ set_timer = 0;
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+ }
+
+ /* Make the selected thread the current thread: */
+ _thread_run = pthread_h;
+
+ /*
+ * Save the current time as the time that the thread
+ * became active:
+ */
+ _thread_run->last_active.tv_sec = tv.tv_sec;
+ _thread_run->last_active.tv_usec = tv.tv_usec;
+
+ /*
+ * Define the maximum time before a scheduling signal
+ * is required:
+ */
+ itimer.it_value.tv_sec = 0;
+ itimer.it_value.tv_usec = TIMESLICE_USEC;
+
+ /*
+ * The interval timer is not reloaded when it
+ * times out. The interval time needs to be
+ * calculated every time.
+ */
+ itimer.it_interval.tv_sec = 0;
+ itimer.it_interval.tv_usec = 0;
+
+ /* Get first thread on the waiting list: */
+ if ((pthread != NULL) &&
+ (pthread->wakeup_time.tv_sec != -1)) {
+ /*
+ * Calculate the time until this thread
+ * is ready, allowing for the clock
+ * resolution:
+ */
+ ts1.tv_sec = pthread->wakeup_time.tv_sec
+ - ts.tv_sec;
+ ts1.tv_nsec = pthread->wakeup_time.tv_nsec
+ - ts.tv_nsec + _clock_res_nsec;
+
+ /*
+ * Check for underflow of the nanosecond field:
+ */
+ while (ts1.tv_nsec < 0) {
+ /*
+ * Allow for the underflow of the
+ * nanosecond field:
+ */
+ ts1.tv_sec--;
+ ts1.tv_nsec += 1000000000;
+ }
+ /*
+ * Check for overflow of the nanosecond field:
+ */
+ while (ts1.tv_nsec >= 1000000000) {
+ /*
+ * Allow for the overflow of the
+ * nanosecond field:
+ */
+ ts1.tv_sec++;
+ ts1.tv_nsec -= 1000000000;
+ }
+ /*
+ * Convert the timespec structure to a
+ * timeval structure:
+ */
+ TIMESPEC_TO_TIMEVAL(&tv1, &ts1);
+
+ /*
+ * Check if the thread will be ready
+ * sooner than the earliest ones found
+ * so far:
+ */
+ if (timercmp(&tv1, &itimer.it_value, <)) {
+ /*
+ * Update the time value:
+ */
+ itimer.it_value.tv_sec = tv1.tv_sec;
+ itimer.it_value.tv_usec = tv1.tv_usec;
+ }
+ }
+
+ /*
+ * Check if this thread is running for the first time
+ * or running again after using its full time slice
+ * allocation:
+ */
+ if (_thread_run->slice_usec == -1) {
+ /* Reset the accumulated time slice period: */
+ _thread_run->slice_usec = 0;
+ }
+
+ /* Check if there is more than one thread: */
+ if (set_timer != 0) {
+ /*
+ * Start the interval timer for the
+ * calculated time interval:
+ */
+ if (setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL) != 0) {
+ /*
+ * Cannot initialise the timer, so
+ * abort this process:
+ */
+ PANIC("Cannot set scheduling timer");
+ }
+ }
+
+ /* Check if a signal context was saved: */
+ if (_thread_run->sig_saved == 1) {
+#ifndef __alpha__
+ /*
+ * Point to the floating point data in the
+ * running thread:
+ */
+ fdata = _thread_run->saved_fp;
+
+ /* Restore the floating point state: */
+ __asm__("frstor %0": :"m"(*fdata));
+#endif
+ /*
+ * Do a sigreturn to restart the thread that
+ * was interrupted by a signal:
+ */
+ _thread_kern_in_sched = 0;
+
+ /*
+ * If we had a context switch, run any
+ * installed switch hooks.
+ */
+ if ((_sched_switch_hook != NULL) &&
+ (_last_user_thread != _thread_run)) {
+ thread_run_switch_hook(_last_user_thread,
+ _thread_run);
+ }
+ _thread_sys_sigreturn(&_thread_run->saved_sigcontext);
+ } else {
+ /*
+ * Do a longjmp to restart the thread that
+ * was context switched out (by a longjmp to
+ * a different thread):
+ */
+ longjmp(_thread_run->saved_jmp_buf, 1);
+ }
+
+ /* This point should not be reached. */
+ PANIC("Thread has returned from sigreturn or longjmp");
+ }
+ }
+
+ /* There are no more threads, so exit this process: */
+ exit(0);
+}
+
+void
+_thread_kern_sched_state(enum pthread_state state, char *fname, int lineno)
+{
+ /*
+ * Flag the pthread kernel as executing scheduler code
+ * to avoid a scheduler signal from interrupting this
+ * execution and calling the scheduler again.
+ */
+ _thread_kern_in_sched = 1;
+
+ /*
+ * Prevent the signal handler from fiddling with this thread
+ * before its state is set and is placed into the proper queue.
+ */
+ _queue_signals = 1;
+
+ /* Change the state of the current thread: */
+ _thread_run->state = state;
+ _thread_run->fname = fname;
+ _thread_run->lineno = lineno;
+
+ /* Schedule the next thread that is ready: */
+ _thread_kern_sched(NULL);
+ return;
+}
+
+void
+_thread_kern_sched_state_unlock(enum pthread_state state,
+ spinlock_t *lock, char *fname, int lineno)
+{
+ /*
+ * Flag the pthread kernel as executing scheduler code
+ * to avoid a scheduler signal from interrupting this
+ * execution and calling the scheduler again.
+ */
+ _thread_kern_in_sched = 1;
+
+ /*
+ * Prevent the signal handler from fiddling with this thread
+ * before its state is set and it is placed into the proper
+ * queue(s).
+ */
+ _queue_signals = 1;
+
+ /* Change the state of the current thread: */
+ _thread_run->state = state;
+ _thread_run->fname = fname;
+ _thread_run->lineno = lineno;
+
+ _SPINUNLOCK(lock);
+
+ /* Schedule the next thread that is ready: */
+ _thread_kern_sched(NULL);
+ return;
+}
+
+static void
+_thread_kern_poll(int wait_reqd)
+{
+ int count = 0;
+ int i, found;
+ int kern_pipe_added = 0;
+ int nfds = 0;
+ int timeout_ms = 0;
+ struct pthread *pthread;
+ struct timespec ts;
+ struct timeval tv;
+
+ /* Check if the caller wants to wait: */
+ if (wait_reqd == 0) {
+ timeout_ms = 0;
+ }
+ else {
+ /* Get the current time of day: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
+
+ _queue_signals = 1;
+ pthread = TAILQ_FIRST(&_waitingq);
+ _queue_signals = 0;
+
+ if ((pthread == NULL) || (pthread->wakeup_time.tv_sec == -1)) {
+ /*
+ * Either there are no threads in the waiting queue,
+ * or there are no threads that can timeout.
+ */
+ timeout_ms = INFTIM;
+ }
+ else {
+ /*
+ * Calculate the time left for the next thread to
+ * timeout allowing for the clock resolution:
+ */
+ timeout_ms = ((pthread->wakeup_time.tv_sec - ts.tv_sec) *
+ 1000) + ((pthread->wakeup_time.tv_nsec - ts.tv_nsec +
+ _clock_res_nsec) / 1000000);
+ /*
+ * Don't allow negative timeouts:
+ */
+ if (timeout_ms < 0)
+ timeout_ms = 0;
+ }
+ }
+
+ /* Protect the scheduling queues: */
+ _queue_signals = 1;
+
+ /*
+ * Check to see if the signal queue needs to be walked to look
+ * for threads awoken by a signal while in the scheduler.
+ */
+ if (_sigq_check_reqd != 0) {
+ /* Reset flag before handling queued signals: */
+ _sigq_check_reqd = 0;
+
+ dequeue_signals();
+ }
+
+ /*
+ * Check for a thread that became runnable due to a signal:
+ */
+ if (PTHREAD_PRIOQ_FIRST() != NULL) {
+ /*
+ * Since there is at least one runnable thread,
+ * disable the wait.
+ */
+ timeout_ms = 0;
+ }
+
+ /*
+ * Form the poll table:
+ */
+ nfds = 0;
+ if (timeout_ms != 0) {
+ /* Add the kernel pipe to the poll table: */
+ _thread_pfd_table[nfds].fd = _thread_kern_pipe[0];
+ _thread_pfd_table[nfds].events = POLLRDNORM;
+ _thread_pfd_table[nfds].revents = 0;
+ nfds++;
+ kern_pipe_added = 1;
+ }
+
+ PTHREAD_WAITQ_SETACTIVE();
+ TAILQ_FOREACH(pthread, &_workq, qe) {
+ switch (pthread->state) {
+ case PS_SPINBLOCK:
+ /*
+ * If the lock is available, let the thread run.
+ */
+ if (pthread->data.spinlock->access_lock == 0) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ /* One less thread in a spinblock state: */
+ _spinblock_count--;
+ /*
+ * Since there is at least one runnable
+ * thread, disable the wait.
+ */
+ timeout_ms = 0;
+ }
+ break;
+
+ /* File descriptor read wait: */
+ case PS_FDR_WAIT:
+ /* Limit number of polled files to table size: */
+ if (nfds < _thread_dtablesize) {
+ _thread_pfd_table[nfds].events = POLLRDNORM;
+ _thread_pfd_table[nfds].fd = pthread->data.fd.fd;
+ nfds++;
+ }
+ break;
+
+ /* File descriptor write wait: */
+ case PS_FDW_WAIT:
+ /* Limit number of polled files to table size: */
+ if (nfds < _thread_dtablesize) {
+ _thread_pfd_table[nfds].events = POLLWRNORM;
+ _thread_pfd_table[nfds].fd = pthread->data.fd.fd;
+ nfds++;
+ }
+ break;
+
+ /* File descriptor poll or select wait: */
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ /* Limit number of polled files to table size: */
+ if (pthread->data.poll_data->nfds + nfds <
+ _thread_dtablesize) {
+ for (i = 0; i < pthread->data.poll_data->nfds; i++) {
+ _thread_pfd_table[nfds + i].fd =
+ pthread->data.poll_data->fds[i].fd;
+ _thread_pfd_table[nfds + i].events =
+ pthread->data.poll_data->fds[i].events;
+ }
+ nfds += pthread->data.poll_data->nfds;
+ }
+ break;
+
+ /* Other states do not depend on file I/O. */
+ default:
+ break;
+ }
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+
+ /*
+ * Wait for a file descriptor to be ready for read, write, or
+ * an exception, or a timeout to occur:
+ */
+ count = _thread_sys_poll(_thread_pfd_table, nfds, timeout_ms);
+
+ if (kern_pipe_added != 0)
+ /*
+ * Remove the pthread kernel pipe file descriptor
+ * from the pollfd table:
+ */
+ nfds = 1;
+ else
+ nfds = 0;
+
+ /*
+ * Check if it is possible that there are bytes in the kernel
+ * read pipe waiting to be read:
+ */
+ if (count < 0 || ((kern_pipe_added != 0) &&
+ (_thread_pfd_table[0].revents & POLLRDNORM))) {
+ /*
+ * If the kernel read pipe was included in the
+ * count:
+ */
+ if (count > 0) {
+ /* Decrement the count of file descriptors: */
+ count--;
+ }
+
+ if (_sigq_check_reqd != 0) {
+ /* Reset flag before handling signals: */
+ _sigq_check_reqd = 0;
+
+ dequeue_signals();
+ }
+ }
+
+ /*
+ * Check if any file descriptors are ready:
+ */
+ if (count > 0) {
+ /*
+ * Enter a loop to look for threads waiting on file
+ * descriptors that are flagged as available by the
+ * _poll syscall:
+ */
+ PTHREAD_WAITQ_SETACTIVE();
+ TAILQ_FOREACH(pthread, &_workq, qe) {
+ switch (pthread->state) {
+ case PS_SPINBLOCK:
+ /*
+ * If the lock is available, let the thread run.
+ */
+ if (pthread->data.spinlock->access_lock == 0) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+
+ /*
+ * One less thread in a spinblock state:
+ */
+ _spinblock_count--;
+ }
+ break;
+
+ /* File descriptor read wait: */
+ case PS_FDR_WAIT:
+ if ((nfds < _thread_dtablesize) &&
+ (_thread_pfd_table[nfds].revents & POLLRDNORM)) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ }
+ nfds++;
+ break;
+
+ /* File descriptor write wait: */
+ case PS_FDW_WAIT:
+ if ((nfds < _thread_dtablesize) &&
+ (_thread_pfd_table[nfds].revents & POLLWRNORM)) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ }
+ nfds++;
+ break;
+
+ /* File descriptor poll or select wait: */
+ case PS_POLL_WAIT:
+ case PS_SELECT_WAIT:
+ if (pthread->data.poll_data->nfds + nfds <
+ _thread_dtablesize) {
+ /*
+ * Enter a loop looking for I/O
+ * readiness:
+ */
+ found = 0;
+ for (i = 0; i < pthread->data.poll_data->nfds; i++) {
+ if (_thread_pfd_table[nfds + i].revents != 0) {
+ pthread->data.poll_data->fds[i].revents =
+ _thread_pfd_table[nfds + i].revents;
+ found++;
+ }
+ }
+
+ /* Increment before destroying: */
+ nfds += pthread->data.poll_data->nfds;
+
+ if (found != 0) {
+ pthread->data.poll_data->nfds = found;
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+ }
+ }
+ else
+ nfds += pthread->data.poll_data->nfds;
+ break;
+
+ /* Other states do not depend on file I/O. */
+ default:
+ break;
+ }
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+ }
+ else if (_spinblock_count != 0) {
+ /*
+ * Enter a loop to look for threads waiting on a spinlock
+ * that is now available.
+ */
+ PTHREAD_WAITQ_SETACTIVE();
+ TAILQ_FOREACH(pthread, &_workq, qe) {
+ if (pthread->state == PS_SPINBLOCK) {
+ /*
+ * If the lock is available, let the thread run.
+ */
+ if (pthread->data.spinlock->access_lock == 0) {
+ PTHREAD_WAITQ_CLEARACTIVE();
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
+
+ /*
+ * One less thread in a spinblock state:
+ */
+ _spinblock_count--;
+ }
+ }
+ }
+ PTHREAD_WAITQ_CLEARACTIVE();
+ }
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+
+ while (_sigq_check_reqd != 0) {
+ /* Handle queued signals: */
+ _sigq_check_reqd = 0;
+
+ /* Protect the scheduling queues: */
+ _queue_signals = 1;
+
+ dequeue_signals();
+
+ /* Unprotect the scheduling queues: */
+ _queue_signals = 0;
+ }
+
+ /* Nothing to return. */
+ return;
+}
+
+void
+_thread_kern_set_timeout(struct timespec * timeout)
+{
+ struct timespec current_time;
+ struct timeval tv;
+
+ /* Reset the timeout flag for the running thread: */
+ _thread_run->timeout = 0;
+
+ /* Check if the thread is to wait forever: */
+ if (timeout == NULL) {
+ /*
+ * Set the wakeup time to something that can be recognised as
+ * different to an actual time of day:
+ */
+ _thread_run->wakeup_time.tv_sec = -1;
+ _thread_run->wakeup_time.tv_nsec = -1;
+ }
+ /* Check if no waiting is required: */
+ else if (timeout->tv_sec == 0 && timeout->tv_nsec == 0) {
+ /* Set the wake up time to 'immediately': */
+ _thread_run->wakeup_time.tv_sec = 0;
+ _thread_run->wakeup_time.tv_nsec = 0;
+ } else {
+ /* Get the current time: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &current_time);
+
+ /* Calculate the time for the current thread to wake up: */
+ _thread_run->wakeup_time.tv_sec = current_time.tv_sec + timeout->tv_sec;
+ _thread_run->wakeup_time.tv_nsec = current_time.tv_nsec + timeout->tv_nsec;
+
+ /* Check if the nanosecond field needs to wrap: */
+ if (_thread_run->wakeup_time.tv_nsec >= 1000000000) {
+ /* Wrap the nanosecond field: */
+ _thread_run->wakeup_time.tv_sec += 1;
+ _thread_run->wakeup_time.tv_nsec -= 1000000000;
+ }
+ }
+ return;
+}
+
+void
+_thread_kern_sig_defer(void)
+{
+ /* Allow signal deferral to be recursive. */
+ _thread_run->sig_defer_count++;
+}
+
+void
+_thread_kern_sig_undefer(void)
+{
+ pthread_t pthread;
+ int need_resched = 0;
+
+ /*
+ * Perform checks to yield only if we are about to undefer
+ * signals.
+ */
+ if (_thread_run->sig_defer_count > 1) {
+ /* Decrement the signal deferral count. */
+ _thread_run->sig_defer_count--;
+ }
+ else if (_thread_run->sig_defer_count == 1) {
+ /* Reenable signals: */
+ _thread_run->sig_defer_count = 0;
+
+ /*
+ * Check if there are queued signals:
+ */
+ while (_sigq_check_reqd != 0) {
+ /* Defer scheduling while we process queued signals: */
+ _thread_run->sig_defer_count = 1;
+
+ /* Clear the flag before checking the signal queue: */
+ _sigq_check_reqd = 0;
+
+ /* Dequeue and handle signals: */
+ dequeue_signals();
+
+ /*
+ * Avoiding an unnecessary check to reschedule, check
+ * to see if signal handling caused a higher priority
+ * thread to become ready.
+ */
+ if ((need_resched == 0) &&
+ (((pthread = PTHREAD_PRIOQ_FIRST()) != NULL) &&
+ (pthread->active_priority > _thread_run->active_priority))) {
+ need_resched = 1;
+ }
+
+ /* Reenable signals: */
+ _thread_run->sig_defer_count = 0;
+ }
+
+ /* Yield the CPU if necessary: */
+ if (need_resched || _thread_run->yield_on_sig_undefer != 0) {
+ _thread_run->yield_on_sig_undefer = 0;
+ _thread_kern_sched(NULL);
+ }
+ }
+}
+
+static void
+dequeue_signals(void)
+{
+ char bufr[128];
+ int i, num;
+ pthread_t pthread;
+
+ /*
+ * Enter a loop to read and handle queued signals from the
+ * pthread kernel pipe:
+ */
+ while (((num = _thread_sys_read(_thread_kern_pipe[0], bufr,
+ sizeof(bufr))) > 0) || (num == -1 && errno == EINTR)) {
+ /*
+ * The buffer read contains one byte per signal and
+ * each byte is the signal number.
+ */
+ for (i = 0; i < num; i++) {
+ if ((int) bufr[i] == _SCHED_SIGNAL) {
+ /*
+ * Scheduling signals shouldn't ever be
+ * queued; just ignore it for now.
+ */
+ }
+ else {
+ /* Handle this signal: */
+ pthread = _thread_sig_handle((int) bufr[i],
+ NULL);
+ if (pthread != NULL)
+ _thread_sig_deliver(pthread,
+ (int) bufr[i]);
+ }
+ }
+ }
+ if ((num < 0) && (errno != EAGAIN)) {
+ /*
+ * The only error we should expect is if there is
+ * no data to read.
+ */
+ PANIC("Unable to read from thread kernel pipe");
+ }
+}
+
+static inline void
+thread_run_switch_hook(pthread_t thread_out, pthread_t thread_in)
+{
+ pthread_t tid_out = thread_out;
+ pthread_t tid_in = thread_in;
+
+ if ((tid_out != NULL) &&
+ (tid_out->flags & PTHREAD_FLAGS_PRIVATE) != 0)
+ tid_out = NULL;
+ if ((tid_in != NULL) &&
+ (tid_in->flags & PTHREAD_FLAGS_PRIVATE) != 0)
+ tid_in = NULL;
+
+ if ((_sched_switch_hook != NULL) && (tid_out != tid_in)) {
+ /* Run the scheduler switch hook: */
+ _sched_switch_hook(tid_out, tid_in);
+ }
+}
+#endif
diff --git a/lib/libpthread/thread/thr_kill.c b/lib/libpthread/thread/thr_kill.c
new file mode 100644
index 0000000..4bf1761
--- /dev/null
+++ b/lib/libpthread/thread/thr_kill.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <signal.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_kill(pthread_t pthread, int sig)
+{
+ int ret;
+
+ /* Check for invalid signal numbers: */
+ if (sig < 0 || sig >= NSIG)
+ /* Invalid signal: */
+ ret = EINVAL;
+ /*
+ * Ensure the thread is in the list of active threads, and the
+ * signal is valid (signal 0 specifies error checking only) and
+ * not being ignored:
+ */
+ else if (((ret = _find_thread(pthread)) == 0) && (sig > 0) &&
+ (_thread_sigact[sig - 1].sa_handler != SIG_IGN)) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ _thread_sig_send(pthread, sig);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_mattr_init.c b/lib/libpthread/thread/thr_mattr_init.c
new file mode 100644
index 0000000..63d4401
--- /dev/null
+++ b/lib/libpthread/thread/thr_mattr_init.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996 Jeffrey Hsu <hsu@freebsd.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_mutexattr_init(pthread_mutexattr_t *attr)
+{
+ int ret;
+ pthread_mutexattr_t pattr;
+
+ if ((pattr = (pthread_mutexattr_t)
+ malloc(sizeof(struct pthread_mutex_attr))) == NULL) {
+ ret = ENOMEM;
+ } else {
+ memcpy(pattr, &pthread_mutexattr_default,
+ sizeof(struct pthread_mutex_attr));
+ *attr = pattr;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_mattr_kind_np.c b/lib/libpthread/thread/thr_mattr_kind_np.c
new file mode 100644
index 0000000..8b3b8cb
--- /dev/null
+++ b/lib/libpthread/thread/thr_mattr_kind_np.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1996 Jeffrey Hsu <hsu@freebsd.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->m_type = kind;
+ ret = 0;
+ }
+ return(ret);
+}
+
+int
+pthread_mutexattr_getkind_np(pthread_mutexattr_t attr)
+{
+ int ret;
+ if (attr == NULL) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ ret = attr->m_type;
+ }
+ return(ret);
+}
+
+int
+pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL || type >= MUTEX_TYPE_MAX) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->m_type = type;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_msync.c b/lib/libpthread/thread/thr_msync.c
new file mode 100644
index 0000000..209286d
--- /dev/null
+++ b/lib/libpthread/thread/thr_msync.c
@@ -0,0 +1,40 @@
+/*
+ * David Leonard <d@openbsd.org>, 1999. Public Domain.
+ *
+ * $OpenBSD: uthread_msync.c,v 1.2 1999/06/09 07:16:17 d Exp $
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+msync(addr, len, flags)
+ void *addr;
+ size_t len;
+ int flags;
+{
+ int ret;
+
+ /*
+ * XXX This is quite pointless unless we know how to get the
+ * file descriptor associated with the memory, and lock it for
+ * write. The only real use of this wrapper is to guarantee
+ * a cancellation point, as per the standard. sigh.
+ */
+
+ /* This is a cancellation point: */
+ _thread_enter_cancellation_point();
+
+ ret = _thread_sys_msync(addr, len, flags);
+
+ /* No longer in a cancellation point: */
+ _thread_leave_cancellation_point();
+
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_multi_np.c b/lib/libpthread/thread/thr_multi_np.c
new file mode 100644
index 0000000..39dd948
--- /dev/null
+++ b/lib/libpthread/thread/thr_multi_np.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_multi_np()
+{
+ /* Return to multi-threaded scheduling mode: */
+ _thread_single = NULL;
+ return(0);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_mutex.c b/lib/libpthread/thread/thr_mutex.c
new file mode 100644
index 0000000..c625ef2
--- /dev/null
+++ b/lib/libpthread/thread/thr_mutex.c
@@ -0,0 +1,1406 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+#if defined(_PTHREADS_INVARIANTS)
+#define _MUTEX_INIT_LINK(m) do { \
+ (m)->m_qe.tqe_prev = NULL; \
+ (m)->m_qe.tqe_next = NULL; \
+} while (0)
+#define _MUTEX_ASSERT_IS_OWNED(m) do { \
+ if ((m)->m_qe.tqe_prev == NULL) \
+ PANIC("mutex is not on list"); \
+} while (0)
+#define _MUTEX_ASSERT_NOT_OWNED(m) do { \
+ if (((m)->m_qe.tqe_prev != NULL) || \
+ ((m)->m_qe.tqe_next != NULL)) \
+ PANIC("mutex is on list"); \
+} while (0)
+#else
+#define _MUTEX_INIT_LINK(m)
+#define _MUTEX_ASSERT_IS_OWNED(m)
+#define _MUTEX_ASSERT_NOT_OWNED(m)
+#endif
+
+/*
+ * Prototypes
+ */
+static inline int mutex_self_trylock(pthread_mutex_t);
+static inline int mutex_self_lock(pthread_mutex_t);
+static inline int mutex_unlock_common(pthread_mutex_t *, int);
+static void mutex_priority_adjust(pthread_mutex_t);
+static void mutex_rescan_owned (pthread_t, pthread_mutex_t);
+static inline pthread_t mutex_queue_deq(pthread_mutex_t);
+static inline void mutex_queue_remove(pthread_mutex_t, pthread_t);
+static inline void mutex_queue_enq(pthread_mutex_t, pthread_t);
+
+
+static spinlock_t static_init_lock = _SPINLOCK_INITIALIZER;
+
+/* Reinitialize a mutex to defaults. */
+int
+_mutex_reinit(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+ else if (*mutex == NULL)
+ ret = pthread_mutex_init(mutex, NULL);
+ else {
+ /*
+ * Initialize the mutex structure:
+ */
+ (*mutex)->m_type = PTHREAD_MUTEX_DEFAULT;
+ (*mutex)->m_protocol = PTHREAD_PRIO_NONE;
+ TAILQ_INIT(&(*mutex)->m_queue);
+ (*mutex)->m_owner = NULL;
+ (*mutex)->m_data.m_count = 0;
+ (*mutex)->m_flags &= MUTEX_FLAGS_PRIVATE;
+ (*mutex)->m_flags |= MUTEX_FLAGS_INITED;
+ (*mutex)->m_refcount = 0;
+ (*mutex)->m_prio = 0;
+ (*mutex)->m_saved_prio = 0;
+ _MUTEX_INIT_LINK(*mutex);
+ memset(&(*mutex)->lock, 0, sizeof((*mutex)->lock));
+ }
+ return (ret);
+}
+
+int
+pthread_mutex_init(pthread_mutex_t * mutex,
+ const pthread_mutexattr_t * mutex_attr)
+{
+ enum pthread_mutextype type;
+ int protocol;
+ int ceiling;
+ pthread_mutex_t pmutex;
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+
+ /* Check if default mutex attributes: */
+ else if (mutex_attr == NULL || *mutex_attr == NULL) {
+ /* Default to a (error checking) POSIX mutex: */
+ type = PTHREAD_MUTEX_ERRORCHECK;
+ protocol = PTHREAD_PRIO_NONE;
+ ceiling = PTHREAD_MAX_PRIORITY;
+ }
+
+ /* Check mutex type: */
+ else if (((*mutex_attr)->m_type < PTHREAD_MUTEX_ERRORCHECK) ||
+ ((*mutex_attr)->m_type >= MUTEX_TYPE_MAX))
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+
+ /* Check mutex protocol: */
+ else if (((*mutex_attr)->m_protocol < PTHREAD_PRIO_NONE) ||
+ ((*mutex_attr)->m_protocol > PTHREAD_MUTEX_RECURSIVE))
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+
+ else {
+ /* Use the requested mutex type and protocol: */
+ type = (*mutex_attr)->m_type;
+ protocol = (*mutex_attr)->m_protocol;
+ ceiling = (*mutex_attr)->m_ceiling;
+ }
+
+ /* Check no errors so far: */
+ if (ret == 0) {
+ if ((pmutex = (pthread_mutex_t)
+ malloc(sizeof(struct pthread_mutex))) == NULL)
+ ret = ENOMEM;
+ else {
+ /* Reset the mutex flags: */
+ pmutex->m_flags = 0;
+
+ /* Process according to mutex type: */
+ switch (type) {
+ /* case PTHREAD_MUTEX_DEFAULT: */
+ case PTHREAD_MUTEX_ERRORCHECK:
+ case PTHREAD_MUTEX_NORMAL:
+ /* Nothing to do here. */
+ break;
+
+ /* Single UNIX Spec 2 recursive mutex: */
+ case PTHREAD_MUTEX_RECURSIVE:
+ /* Reset the mutex count: */
+ pmutex->m_data.m_count = 0;
+ break;
+
+ /* Trap invalid mutex types: */
+ default:
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ break;
+ }
+ if (ret == 0) {
+ /* Initialise the rest of the mutex: */
+ TAILQ_INIT(&pmutex->m_queue);
+ pmutex->m_flags |= MUTEX_FLAGS_INITED;
+ pmutex->m_owner = NULL;
+ pmutex->m_type = type;
+ pmutex->m_protocol = protocol;
+ pmutex->m_refcount = 0;
+ if (protocol == PTHREAD_PRIO_PROTECT)
+ pmutex->m_prio = ceiling;
+ else
+ pmutex->m_prio = 0;
+ pmutex->m_saved_prio = 0;
+ _MUTEX_INIT_LINK(pmutex);
+ memset(&pmutex->lock, 0, sizeof(pmutex->lock));
+ *mutex = pmutex;
+ } else {
+ free(pmutex);
+ *mutex = NULL;
+ }
+ }
+ }
+ /* Return the completion status: */
+ return(ret);
+}
+
+int
+pthread_mutex_destroy(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL || *mutex == NULL)
+ ret = EINVAL;
+ else {
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
+ * Check to see if this mutex is in use:
+ */
+ if (((*mutex)->m_owner != NULL) ||
+ (TAILQ_FIRST(&(*mutex)->m_queue) != NULL) ||
+ ((*mutex)->m_refcount != 0)) {
+ ret = EBUSY;
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&(*mutex)->lock);
+ }
+ else {
+ /*
+ * Free the memory allocated for the mutex
+ * structure:
+ */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ free(*mutex);
+
+ /*
+ * Leave the caller's pointer NULL now that
+ * the mutex has been destroyed:
+ */
+ *mutex = NULL;
+ }
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+static int
+init_static (pthread_mutex_t *mutex)
+{
+ int ret;
+
+ _SPINLOCK(&static_init_lock);
+
+ if (*mutex == NULL)
+ ret = pthread_mutex_init(mutex, NULL);
+ else
+ ret = 0;
+
+ _SPINUNLOCK(&static_init_lock);
+
+ return(ret);
+}
+
+int
+pthread_mutex_trylock(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+
+ /*
+ * If the mutex is statically initialized, perform the dynamic
+ * initialization:
+ */
+ else if (*mutex != NULL || (ret = init_static(mutex)) == 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
+ * If the mutex was statically allocated, properly
+ * initialize the tail queue.
+ */
+ if (((*mutex)->m_flags & MUTEX_FLAGS_INITED) == 0) {
+ TAILQ_INIT(&(*mutex)->m_queue);
+ _MUTEX_INIT_LINK(*mutex);
+ (*mutex)->m_flags |= MUTEX_FLAGS_INITED;
+ }
+
+ /* Process according to mutex type: */
+ switch ((*mutex)->m_protocol) {
+ /* Default POSIX mutex: */
+ case PTHREAD_PRIO_NONE:
+ /* Check if this mutex is not locked: */
+ if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for the running thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_trylock(*mutex);
+ else
+ /* Return a busy error: */
+ ret = EBUSY;
+ break;
+
+ /* POSIX priority inheritence mutex: */
+ case PTHREAD_PRIO_INHERIT:
+ /* Check if this mutex is not locked: */
+ if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for the running thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Track number of priority mutexes owned: */
+ _thread_run->priority_mutex_count++;
+
+ /*
+ * The mutex takes on the attributes of the
+ * running thread when there are no waiters.
+ */
+ (*mutex)->m_prio = _thread_run->active_priority;
+ (*mutex)->m_saved_prio =
+ _thread_run->inherited_priority;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_trylock(*mutex);
+ else
+ /* Return a busy error: */
+ ret = EBUSY;
+ break;
+
+ /* POSIX priority protection mutex: */
+ case PTHREAD_PRIO_PROTECT:
+ /* Check for a priority ceiling violation: */
+ if (_thread_run->active_priority > (*mutex)->m_prio)
+ ret = EINVAL;
+
+ /* Check if this mutex is not locked: */
+ else if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for the running thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Track number of priority mutexes owned: */
+ _thread_run->priority_mutex_count++;
+
+ /*
+ * The running thread inherits the ceiling
+ * priority of the mutex and executes at that
+ * priority.
+ */
+ _thread_run->active_priority = (*mutex)->m_prio;
+ (*mutex)->m_saved_prio =
+ _thread_run->inherited_priority;
+ _thread_run->inherited_priority =
+ (*mutex)->m_prio;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_trylock(*mutex);
+ else
+ /* Return a busy error: */
+ ret = EBUSY;
+ break;
+
+ /* Trap invalid mutex types: */
+ default:
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ break;
+ }
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&(*mutex)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+int
+pthread_mutex_lock(pthread_mutex_t * mutex)
+{
+ int ret = 0;
+
+ if (mutex == NULL)
+ ret = EINVAL;
+
+ /*
+ * If the mutex is statically initialized, perform the dynamic
+ * initialization:
+ */
+ else if (*mutex != NULL || (ret = init_static(mutex)) == 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
+ * If the mutex was statically allocated, properly
+ * initialize the tail queue.
+ */
+ if (((*mutex)->m_flags & MUTEX_FLAGS_INITED) == 0) {
+ TAILQ_INIT(&(*mutex)->m_queue);
+ (*mutex)->m_flags |= MUTEX_FLAGS_INITED;
+ _MUTEX_INIT_LINK(*mutex);
+ }
+
+ /* Reset the interrupted flag: */
+ _thread_run->interrupted = 0;
+
+ /* Process according to mutex type: */
+ switch ((*mutex)->m_protocol) {
+ /* Default POSIX mutex: */
+ case PTHREAD_PRIO_NONE:
+ if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for this thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_lock(*mutex);
+ else {
+ /*
+ * Join the queue of threads waiting to lock
+ * the mutex:
+ */
+ mutex_queue_enq(*mutex, _thread_run);
+
+ /*
+ * Keep a pointer to the mutex this thread
+ * is waiting on:
+ */
+ _thread_run->data.mutex = *mutex;
+
+ /*
+ * Unlock the mutex structure and schedule the
+ * next thread:
+ */
+ _thread_kern_sched_state_unlock(PS_MUTEX_WAIT,
+ &(*mutex)->lock, __FILE__, __LINE__);
+
+ /* Lock the mutex structure again: */
+ _SPINLOCK(&(*mutex)->lock);
+ }
+ break;
+
+ /* POSIX priority inheritence mutex: */
+ case PTHREAD_PRIO_INHERIT:
+ /* Check if this mutex is not locked: */
+ if ((*mutex)->m_owner == NULL) {
+ /* Lock the mutex for this thread: */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Track number of priority mutexes owned: */
+ _thread_run->priority_mutex_count++;
+
+ /*
+ * The mutex takes on attributes of the
+ * running thread when there are no waiters.
+ */
+ (*mutex)->m_prio = _thread_run->active_priority;
+ (*mutex)->m_saved_prio =
+ _thread_run->inherited_priority;
+ _thread_run->inherited_priority =
+ (*mutex)->m_prio;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_lock(*mutex);
+ else {
+ /*
+ * Join the queue of threads waiting to lock
+ * the mutex:
+ */
+ mutex_queue_enq(*mutex, _thread_run);
+
+ /*
+ * Keep a pointer to the mutex this thread
+ * is waiting on:
+ */
+ _thread_run->data.mutex = *mutex;
+
+ if (_thread_run->active_priority >
+ (*mutex)->m_prio)
+ /* Adjust priorities: */
+ mutex_priority_adjust(*mutex);
+
+ /*
+ * Unlock the mutex structure and schedule the
+ * next thread:
+ */
+ _thread_kern_sched_state_unlock(PS_MUTEX_WAIT,
+ &(*mutex)->lock, __FILE__, __LINE__);
+
+ /* Lock the mutex structure again: */
+ _SPINLOCK(&(*mutex)->lock);
+ }
+ break;
+
+ /* POSIX priority protection mutex: */
+ case PTHREAD_PRIO_PROTECT:
+ /* Check for a priority ceiling violation: */
+ if (_thread_run->active_priority > (*mutex)->m_prio)
+ ret = EINVAL;
+
+ /* Check if this mutex is not locked: */
+ else if ((*mutex)->m_owner == NULL) {
+ /*
+ * Lock the mutex for the running
+ * thread:
+ */
+ (*mutex)->m_owner = _thread_run;
+
+ /* Track number of priority mutexes owned: */
+ _thread_run->priority_mutex_count++;
+
+ /*
+ * The running thread inherits the ceiling
+ * priority of the mutex and executes at that
+ * priority:
+ */
+ _thread_run->active_priority = (*mutex)->m_prio;
+ (*mutex)->m_saved_prio =
+ _thread_run->inherited_priority;
+ _thread_run->inherited_priority =
+ (*mutex)->m_prio;
+
+ /* Add to the list of owned mutexes: */
+ _MUTEX_ASSERT_NOT_OWNED(*mutex);
+ TAILQ_INSERT_TAIL(&_thread_run->mutexq,
+ (*mutex), m_qe);
+ } else if ((*mutex)->m_owner == _thread_run)
+ ret = mutex_self_lock(*mutex);
+ else {
+ /*
+ * Join the queue of threads waiting to lock
+ * the mutex:
+ */
+ mutex_queue_enq(*mutex, _thread_run);
+
+ /*
+ * Keep a pointer to the mutex this thread
+ * is waiting on:
+ */
+ _thread_run->data.mutex = *mutex;
+
+ /* Clear any previous error: */
+ _thread_run->error = 0;
+
+ /*
+ * Unlock the mutex structure and schedule the
+ * next thread:
+ */
+ _thread_kern_sched_state_unlock(PS_MUTEX_WAIT,
+ &(*mutex)->lock, __FILE__, __LINE__);
+
+ /* Lock the mutex structure again: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /*
+ * The threads priority may have changed while
+ * waiting for the mutex causing a ceiling
+ * violation.
+ */
+ ret = _thread_run->error;
+ _thread_run->error = 0;
+ }
+ break;
+
+ /* Trap invalid mutex types: */
+ default:
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ break;
+ }
+
+ /*
+ * Check to see if this thread was interrupted and
+ * is still in the mutex queue of waiting threads:
+ */
+ if (_thread_run->interrupted != 0)
+ mutex_queue_remove(*mutex, _thread_run);
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&(*mutex)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+
+ if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
+ _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
+ _thread_exit_cleanup();
+ pthread_exit(PTHREAD_CANCELED);
+ }
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+int
+pthread_mutex_unlock(pthread_mutex_t * mutex)
+{
+ return (mutex_unlock_common(mutex, /* add reference */ 0));
+}
+
+int
+_mutex_cv_unlock(pthread_mutex_t * mutex)
+{
+ return (mutex_unlock_common(mutex, /* add reference */ 1));
+}
+
+int
+_mutex_cv_lock(pthread_mutex_t * mutex)
+{
+ int ret;
+ if ((ret = pthread_mutex_lock(mutex)) == 0)
+ (*mutex)->m_refcount--;
+ return (ret);
+}
+
+static inline int
+mutex_self_trylock(pthread_mutex_t mutex)
+{
+ int ret = 0;
+
+ switch (mutex->m_type) {
+
+ /* case PTHREAD_MUTEX_DEFAULT: */
+ case PTHREAD_MUTEX_ERRORCHECK:
+ case PTHREAD_MUTEX_NORMAL:
+ /*
+ * POSIX specifies that mutexes should return EDEADLK if a
+ * recursive lock is detected.
+ */
+ ret = EBUSY;
+ break;
+
+ case PTHREAD_MUTEX_RECURSIVE:
+ /* Increment the lock count: */
+ mutex->m_data.m_count++;
+ break;
+
+ default:
+ /* Trap invalid mutex types; */
+ ret = EINVAL;
+ }
+
+ return(ret);
+}
+
+static inline int
+mutex_self_lock(pthread_mutex_t mutex)
+{
+ int ret = 0;
+
+ switch (mutex->m_type) {
+ /* case PTHREAD_MUTEX_DEFAULT: */
+ case PTHREAD_MUTEX_ERRORCHECK:
+ /*
+ * POSIX specifies that mutexes should return EDEADLK if a
+ * recursive lock is detected.
+ */
+ ret = EDEADLK;
+ break;
+
+ case PTHREAD_MUTEX_NORMAL:
+ /*
+ * What SS2 define as a 'normal' mutex. Intentionally
+ * deadlock on attempts to get a lock you already own.
+ */
+ _thread_kern_sched_state_unlock(PS_DEADLOCK,
+ &mutex->lock, __FILE__, __LINE__);
+ break;
+
+ case PTHREAD_MUTEX_RECURSIVE:
+ /* Increment the lock count: */
+ mutex->m_data.m_count++;
+ break;
+
+ default:
+ /* Trap invalid mutex types; */
+ ret = EINVAL;
+ }
+
+ return(ret);
+}
+
+static inline int
+mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
+{
+ int ret = 0;
+
+ if (mutex == NULL || *mutex == NULL) {
+ ret = EINVAL;
+ } else {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Lock the mutex structure: */
+ _SPINLOCK(&(*mutex)->lock);
+
+ /* Process according to mutex type: */
+ switch ((*mutex)->m_protocol) {
+ /* Default POSIX mutex: */
+ case PTHREAD_PRIO_NONE:
+ /*
+ * Check if the running thread is not the owner of the
+ * mutex:
+ */
+ if ((*mutex)->m_owner != _thread_run) {
+ /*
+ * Return an invalid argument error for no
+ * owner and a permission error otherwise:
+ */
+ ret = (*mutex)->m_owner == NULL ? EINVAL : EPERM;
+ }
+ else if (((*mutex)->m_type == PTHREAD_MUTEX_RECURSIVE) &&
+ ((*mutex)->m_data.m_count > 1)) {
+ /* Decrement the count: */
+ (*mutex)->m_data.m_count--;
+ } else {
+ /*
+ * Clear the count in case this is recursive
+ * mutex.
+ */
+ (*mutex)->m_data.m_count = 0;
+
+ /* Remove the mutex from the threads queue. */
+ _MUTEX_ASSERT_IS_OWNED(*mutex);
+ TAILQ_REMOVE(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+ _MUTEX_INIT_LINK(*mutex);
+
+ /*
+ * Get the next thread from the queue of
+ * threads waiting on the mutex:
+ */
+ if (((*mutex)->m_owner =
+ mutex_queue_deq(*mutex)) != NULL) {
+ /*
+ * Allow the new owner of the mutex to
+ * run:
+ */
+ PTHREAD_NEW_STATE((*mutex)->m_owner,
+ PS_RUNNING);
+
+ /*
+ * Add the mutex to the threads list of
+ * owned mutexes:
+ */
+ TAILQ_INSERT_TAIL(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+
+ /*
+ * The owner is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
+ }
+ }
+ break;
+
+ /* POSIX priority inheritence mutex: */
+ case PTHREAD_PRIO_INHERIT:
+ /*
+ * Check if the running thread is not the owner of the
+ * mutex:
+ */
+ if ((*mutex)->m_owner != _thread_run) {
+ /*
+ * Return an invalid argument error for no
+ * owner and a permission error otherwise:
+ */
+ ret = (*mutex)->m_owner == NULL ? EINVAL : EPERM;
+ }
+ else if (((*mutex)->m_type == PTHREAD_MUTEX_RECURSIVE) &&
+ ((*mutex)->m_data.m_count > 1)) {
+ /* Decrement the count: */
+ (*mutex)->m_data.m_count--;
+ } else {
+ /*
+ * Clear the count in case this is recursive
+ * mutex.
+ */
+ (*mutex)->m_data.m_count = 0;
+
+ /*
+ * Restore the threads inherited priority and
+ * recompute the active priority (being careful
+ * not to override changes in the threads base
+ * priority subsequent to locking the mutex).
+ */
+ _thread_run->inherited_priority =
+ (*mutex)->m_saved_prio;
+ _thread_run->active_priority =
+ MAX(_thread_run->inherited_priority,
+ _thread_run->base_priority);
+
+ /*
+ * This thread now owns one less priority mutex.
+ */
+ _thread_run->priority_mutex_count--;
+
+ /* Remove the mutex from the threads queue. */
+ _MUTEX_ASSERT_IS_OWNED(*mutex);
+ TAILQ_REMOVE(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+ _MUTEX_INIT_LINK(*mutex);
+
+ /*
+ * Get the next thread from the queue of threads
+ * waiting on the mutex:
+ */
+ if (((*mutex)->m_owner =
+ mutex_queue_deq(*mutex)) == NULL)
+ /* This mutex has no priority. */
+ (*mutex)->m_prio = 0;
+ else {
+ /*
+ * Track number of priority mutexes owned:
+ */
+ (*mutex)->m_owner->priority_mutex_count++;
+
+ /*
+ * Add the mutex to the threads list
+ * of owned mutexes:
+ */
+ TAILQ_INSERT_TAIL(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+
+ /*
+ * The owner is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
+
+ /*
+ * Set the priority of the mutex. Since
+ * our waiting threads are in descending
+ * priority order, the priority of the
+ * mutex becomes the active priority of
+ * the thread we just dequeued.
+ */
+ (*mutex)->m_prio =
+ (*mutex)->m_owner->active_priority;
+
+ /*
+ * Save the owning threads inherited
+ * priority:
+ */
+ (*mutex)->m_saved_prio =
+ (*mutex)->m_owner->inherited_priority;
+
+ /*
+ * The owning threads inherited priority
+ * now becomes his active priority (the
+ * priority of the mutex).
+ */
+ (*mutex)->m_owner->inherited_priority =
+ (*mutex)->m_prio;
+
+ /*
+ * Allow the new owner of the mutex to
+ * run:
+ */
+ PTHREAD_NEW_STATE((*mutex)->m_owner,
+ PS_RUNNING);
+ }
+ }
+ break;
+
+ /* POSIX priority ceiling mutex: */
+ case PTHREAD_PRIO_PROTECT:
+ /*
+ * Check if the running thread is not the owner of the
+ * mutex:
+ */
+ if ((*mutex)->m_owner != _thread_run) {
+ /*
+ * Return an invalid argument error for no
+ * owner and a permission error otherwise:
+ */
+ ret = (*mutex)->m_owner == NULL ? EINVAL : EPERM;
+ }
+ else if (((*mutex)->m_type == PTHREAD_MUTEX_RECURSIVE) &&
+ ((*mutex)->m_data.m_count > 1)) {
+ /* Decrement the count: */
+ (*mutex)->m_data.m_count--;
+ } else {
+ /*
+ * Clear the count in case this is recursive
+ * mutex.
+ */
+ (*mutex)->m_data.m_count = 0;
+
+ /*
+ * Restore the threads inherited priority and
+ * recompute the active priority (being careful
+ * not to override changes in the threads base
+ * priority subsequent to locking the mutex).
+ */
+ _thread_run->inherited_priority =
+ (*mutex)->m_saved_prio;
+ _thread_run->active_priority =
+ MAX(_thread_run->inherited_priority,
+ _thread_run->base_priority);
+
+ /*
+ * This thread now owns one less priority mutex.
+ */
+ _thread_run->priority_mutex_count--;
+
+ /* Remove the mutex from the threads queue. */
+ _MUTEX_ASSERT_IS_OWNED(*mutex);
+ TAILQ_REMOVE(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+ _MUTEX_INIT_LINK(*mutex);
+
+ /*
+ * Enter a loop to find a waiting thread whose
+ * active priority will not cause a ceiling
+ * violation:
+ */
+ while ((((*mutex)->m_owner =
+ mutex_queue_deq(*mutex)) != NULL) &&
+ ((*mutex)->m_owner->active_priority >
+ (*mutex)->m_prio)) {
+ /*
+ * Either the mutex ceiling priority
+ * been lowered and/or this threads
+ * priority has been raised subsequent
+ * to this thread being queued on the
+ * waiting list.
+ */
+ (*mutex)->m_owner->error = EINVAL;
+ PTHREAD_NEW_STATE((*mutex)->m_owner,
+ PS_RUNNING);
+ /*
+ * The thread is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
+ }
+
+ /* Check for a new owner: */
+ if ((*mutex)->m_owner != NULL) {
+ /*
+ * Track number of priority mutexes owned:
+ */
+ (*mutex)->m_owner->priority_mutex_count++;
+
+ /*
+ * Add the mutex to the threads list
+ * of owned mutexes:
+ */
+ TAILQ_INSERT_TAIL(&(*mutex)->m_owner->mutexq,
+ (*mutex), m_qe);
+
+ /*
+ * The owner is no longer waiting for
+ * this mutex:
+ */
+ (*mutex)->m_owner->data.mutex = NULL;
+
+ /*
+ * Save the owning threads inherited
+ * priority:
+ */
+ (*mutex)->m_saved_prio =
+ (*mutex)->m_owner->inherited_priority;
+
+ /*
+ * The owning thread inherits the
+ * ceiling priority of the mutex and
+ * executes at that priority:
+ */
+ (*mutex)->m_owner->inherited_priority =
+ (*mutex)->m_prio;
+ (*mutex)->m_owner->active_priority =
+ (*mutex)->m_prio;
+
+ /*
+ * Allow the new owner of the mutex to
+ * run:
+ */
+ PTHREAD_NEW_STATE((*mutex)->m_owner,
+ PS_RUNNING);
+ }
+ }
+ break;
+
+ /* Trap invalid mutex types: */
+ default:
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ break;
+ }
+
+ if ((ret == 0) && (add_reference != 0)) {
+ /* Increment the reference count: */
+ (*mutex)->m_refcount++;
+ }
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&(*mutex)->lock);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+
+
+/*
+ * This function is called when a change in base priority occurs for
+ * a thread that is holding or waiting for a priority protection or
+ * inheritence mutex. A change in a threads base priority can effect
+ * changes to active priorities of other threads and to the ordering
+ * of mutex locking by waiting threads.
+ *
+ * This must be called while thread scheduling is deferred.
+ */
+void
+_mutex_notify_priochange(pthread_t pthread)
+{
+ /* Adjust the priorites of any owned priority mutexes: */
+ if (pthread->priority_mutex_count > 0) {
+ /*
+ * Rescan the mutexes owned by this thread and correct
+ * their priorities to account for this threads change
+ * in priority. This has the side effect of changing
+ * the threads active priority.
+ */
+ mutex_rescan_owned(pthread, /* rescan all owned */ NULL);
+ }
+
+ /*
+ * If this thread is waiting on a priority inheritence mutex,
+ * check for priority adjustments. A change in priority can
+ * also effect a ceiling violation(*) for a thread waiting on
+ * a priority protection mutex; we don't perform the check here
+ * as it is done in pthread_mutex_unlock.
+ *
+ * (*) It should be noted that a priority change to a thread
+ * _after_ taking and owning a priority ceiling mutex
+ * does not affect ownership of that mutex; the ceiling
+ * priority is only checked before mutex ownership occurs.
+ */
+ if (pthread->state == PS_MUTEX_WAIT) {
+ /* Lock the mutex structure: */
+ _SPINLOCK(&pthread->data.mutex->lock);
+
+ /*
+ * Check to make sure this thread is still in the same state
+ * (the spinlock above can yield the CPU to another thread):
+ */
+ if (pthread->state == PS_MUTEX_WAIT) {
+ /*
+ * Remove and reinsert this thread into the list of
+ * waiting threads to preserve decreasing priority
+ * order.
+ */
+ mutex_queue_remove(pthread->data.mutex, pthread);
+ mutex_queue_enq(pthread->data.mutex, pthread);
+
+ if (pthread->data.mutex->m_protocol ==
+ PTHREAD_PRIO_INHERIT) {
+ /* Adjust priorities: */
+ mutex_priority_adjust(pthread->data.mutex);
+ }
+ }
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&pthread->data.mutex->lock);
+ }
+}
+
+/*
+ * Called when a new thread is added to the mutex waiting queue or
+ * when a threads priority changes that is already in the mutex
+ * waiting queue.
+ */
+static void
+mutex_priority_adjust(pthread_mutex_t mutex)
+{
+ pthread_t pthread_next, pthread = mutex->m_owner;
+ int temp_prio;
+ pthread_mutex_t m = mutex;
+
+ /*
+ * Calculate the mutex priority as the maximum of the highest
+ * active priority of any waiting threads and the owning threads
+ * active priority(*).
+ *
+ * (*) Because the owning threads current active priority may
+ * reflect priority inherited from this mutex (and the mutex
+ * priority may have changed) we must recalculate the active
+ * priority based on the threads saved inherited priority
+ * and its base priority.
+ */
+ pthread_next = TAILQ_FIRST(&m->m_queue); /* should never be NULL */
+ temp_prio = MAX(pthread_next->active_priority,
+ MAX(m->m_saved_prio, pthread->base_priority));
+
+ /* See if this mutex really needs adjusting: */
+ if (temp_prio == m->m_prio)
+ /* No need to propagate the priority: */
+ return;
+
+ /* Set new priority of the mutex: */
+ m->m_prio = temp_prio;
+
+ while (m != NULL) {
+ /*
+ * Save the threads priority before rescanning the
+ * owned mutexes:
+ */
+ temp_prio = pthread->active_priority;
+
+ /*
+ * Fix the priorities for all the mutexes this thread has
+ * locked since taking this mutex. This also has a
+ * potential side-effect of changing the threads priority.
+ */
+ mutex_rescan_owned(pthread, m);
+
+ /*
+ * If the thread is currently waiting on a mutex, check
+ * to see if the threads new priority has affected the
+ * priority of the mutex.
+ */
+ if ((temp_prio != pthread->active_priority) &&
+ (pthread->state == PS_MUTEX_WAIT) &&
+ (pthread->data.mutex->m_protocol == PTHREAD_PRIO_INHERIT)) {
+ /* Grab the mutex this thread is waiting on: */
+ m = pthread->data.mutex;
+
+ /*
+ * The priority for this thread has changed. Remove
+ * and reinsert this thread into the list of waiting
+ * threads to preserve decreasing priority order.
+ */
+ mutex_queue_remove(m, pthread);
+ mutex_queue_enq(m, pthread);
+
+ /* Grab the waiting thread with highest priority: */
+ pthread_next = TAILQ_FIRST(&m->m_queue);
+
+ /*
+ * Calculate the mutex priority as the maximum of the
+ * highest active priority of any waiting threads and
+ * the owning threads active priority.
+ */
+ temp_prio = MAX(pthread_next->active_priority,
+ MAX(m->m_saved_prio, m->m_owner->base_priority));
+
+ if (temp_prio != m->m_prio) {
+ /*
+ * The priority needs to be propagated to the
+ * mutex this thread is waiting on and up to
+ * the owner of that mutex.
+ */
+ m->m_prio = temp_prio;
+ pthread = m->m_owner;
+ }
+ else
+ /* We're done: */
+ m = NULL;
+
+ }
+ else
+ /* We're done: */
+ m = NULL;
+ }
+}
+
+static void
+mutex_rescan_owned (pthread_t pthread, pthread_mutex_t mutex)
+{
+ int active_prio, inherited_prio;
+ pthread_mutex_t m;
+ pthread_t pthread_next;
+
+ /*
+ * Start walking the mutexes the thread has taken since
+ * taking this mutex.
+ */
+ if (mutex == NULL) {
+ /*
+ * A null mutex means start at the beginning of the owned
+ * mutex list.
+ */
+ m = TAILQ_FIRST(&pthread->mutexq);
+
+ /* There is no inherited priority yet. */
+ inherited_prio = 0;
+ }
+ else {
+ /*
+ * The caller wants to start after a specific mutex. It
+ * is assumed that this mutex is a priority inheritence
+ * mutex and that its priority has been correctly
+ * calculated.
+ */
+ m = TAILQ_NEXT(mutex, m_qe);
+
+ /* Start inheriting priority from the specified mutex. */
+ inherited_prio = mutex->m_prio;
+ }
+ active_prio = MAX(inherited_prio, pthread->base_priority);
+
+ while (m != NULL) {
+ /*
+ * We only want to deal with priority inheritence
+ * mutexes. This might be optimized by only placing
+ * priority inheritence mutexes into the owned mutex
+ * list, but it may prove to be useful having all
+ * owned mutexes in this list. Consider a thread
+ * exiting while holding mutexes...
+ */
+ if (m->m_protocol == PTHREAD_PRIO_INHERIT) {
+ /*
+ * Fix the owners saved (inherited) priority to
+ * reflect the priority of the previous mutex.
+ */
+ m->m_saved_prio = inherited_prio;
+
+ if ((pthread_next = TAILQ_FIRST(&m->m_queue)) != NULL)
+ /* Recalculate the priority of the mutex: */
+ m->m_prio = MAX(active_prio,
+ pthread_next->active_priority);
+ else
+ m->m_prio = active_prio;
+
+ /* Recalculate new inherited and active priorities: */
+ inherited_prio = m->m_prio;
+ active_prio = MAX(m->m_prio, pthread->base_priority);
+ }
+
+ /* Advance to the next mutex owned by this thread: */
+ m = TAILQ_NEXT(m, m_qe);
+ }
+
+ /*
+ * Fix the threads inherited priority and recalculate its
+ * active priority.
+ */
+ pthread->inherited_priority = inherited_prio;
+ active_prio = MAX(inherited_prio, pthread->base_priority);
+
+ if (active_prio != pthread->active_priority) {
+ /*
+ * If this thread is in the priority queue, it must be
+ * removed and reinserted for its new priority.
+ */
+ if (pthread->flags & PTHREAD_FLAGS_IN_PRIOQ) {
+ /*
+ * Remove the thread from the priority queue
+ * before changing its priority:
+ */
+ PTHREAD_PRIOQ_REMOVE(pthread);
+
+ /*
+ * POSIX states that if the priority is being
+ * lowered, the thread must be inserted at the
+ * head of the queue for its priority if it owns
+ * any priority protection or inheritence mutexes.
+ */
+ if ((active_prio < pthread->active_priority) &&
+ (pthread->priority_mutex_count > 0)) {
+ /* Set the new active priority. */
+ pthread->active_priority = active_prio;
+
+ PTHREAD_PRIOQ_INSERT_HEAD(pthread);
+ }
+ else {
+ /* Set the new active priority. */
+ pthread->active_priority = active_prio;
+
+ PTHREAD_PRIOQ_INSERT_TAIL(pthread);
+ }
+ }
+ else {
+ /* Set the new active priority. */
+ pthread->active_priority = active_prio;
+ }
+ }
+}
+
+void
+_mutex_unlock_private(pthread_t pthread)
+{
+ struct pthread_mutex *m, *m_next;
+
+ for (m = TAILQ_FIRST(&pthread->mutexq); m != NULL; m = m_next) {
+ m_next = TAILQ_NEXT(m, m_qe);
+ if ((m->m_flags & MUTEX_FLAGS_PRIVATE) != 0)
+ pthread_mutex_unlock(&m);
+ }
+}
+
+/*
+ * Dequeue a waiting thread from the head of a mutex queue in descending
+ * priority order.
+ */
+static inline pthread_t
+mutex_queue_deq(pthread_mutex_t mutex)
+{
+ pthread_t pthread;
+
+ while ((pthread = TAILQ_FIRST(&mutex->m_queue)) != NULL) {
+ TAILQ_REMOVE(&mutex->m_queue, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_MUTEXQ;
+
+ /*
+ * Only exit the loop if the thread hasn't been
+ * cancelled.
+ */
+ if (pthread->interrupted == 0)
+ break;
+ }
+
+ return(pthread);
+}
+
+/*
+ * Remove a waiting thread from a mutex queue in descending priority order.
+ */
+static inline void
+mutex_queue_remove(pthread_mutex_t mutex, pthread_t pthread)
+{
+ if ((pthread->flags & PTHREAD_FLAGS_IN_MUTEXQ) != 0) {
+ TAILQ_REMOVE(&mutex->m_queue, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_MUTEXQ;
+ }
+}
+
+/*
+ * Enqueue a waiting thread to a queue in descending priority order.
+ */
+static inline void
+mutex_queue_enq(pthread_mutex_t mutex, pthread_t pthread)
+{
+ pthread_t tid = TAILQ_LAST(&mutex->m_queue, mutex_head);
+
+ /*
+ * For the common case of all threads having equal priority,
+ * we perform a quick check against the priority of the thread
+ * at the tail of the queue.
+ */
+ if ((tid == NULL) || (pthread->active_priority <= tid->active_priority))
+ TAILQ_INSERT_TAIL(&mutex->m_queue, pthread, qe);
+ else {
+ tid = TAILQ_FIRST(&mutex->m_queue);
+ while (pthread->active_priority <= tid->active_priority)
+ tid = TAILQ_NEXT(tid, qe);
+ TAILQ_INSERT_BEFORE(tid, pthread, qe);
+ }
+ pthread->flags |= PTHREAD_FLAGS_IN_MUTEXQ;
+}
+
+#endif
diff --git a/lib/libpthread/thread/thr_mutex_prioceiling.c b/lib/libpthread/thread/thr_mutex_prioceiling.c
new file mode 100644
index 0000000..c193c82
--- /dev/null
+++ b/lib/libpthread/thread/thr_mutex_prioceiling.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_mutexattr_getprioceiling(pthread_mutexattr_t *mattr, int *prioceiling)
+{
+ int ret = 0;
+
+ if ((mattr == NULL) || (*mattr == NULL))
+ ret = EINVAL;
+ else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT)
+ ret = EINVAL;
+ else
+ *prioceiling = (*mattr)->m_ceiling;
+
+ return(ret);
+}
+
+int
+pthread_mutexattr_setprioceiling(pthread_mutexattr_t *mattr, int prioceiling)
+{
+ int ret = 0;
+
+ if ((mattr == NULL) || (*mattr == NULL))
+ ret = EINVAL;
+ else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT)
+ ret = EINVAL;
+ else
+ (*mattr)->m_ceiling = prioceiling;
+
+ return(ret);
+}
+
+int
+pthread_mutex_getprioceiling(pthread_mutex_t *mutex,
+ int *prioceiling)
+{
+ int ret;
+
+ if ((mutex == NULL) || (*mutex == NULL))
+ ret = EINVAL;
+ else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT)
+ ret = EINVAL;
+ else
+ ret = (*mutex)->m_prio;
+
+ return(ret);
+}
+
+int
+pthread_mutex_setprioceiling(pthread_mutex_t *mutex,
+ int prioceiling, int *old_ceiling)
+{
+ int ret = 0;
+
+ if ((mutex == NULL) || (*mutex == NULL))
+ ret = EINVAL;
+ else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT)
+ ret = EINVAL;
+ else {
+ /* Lock the mutex: */
+ if ((ret = pthread_mutex_lock(mutex)) == 0) {
+ /* Return the old ceiling and set the new ceiling: */
+ *old_ceiling = (*mutex)->m_prio;
+ (*mutex)->m_prio = prioceiling;
+
+ /* Unlock the mutex: */
+ ret = pthread_mutex_unlock(mutex);
+ }
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_mutex_protocol.c b/lib/libpthread/thread/thr_mutex_protocol.c
new file mode 100644
index 0000000..9847ae5
--- /dev/null
+++ b/lib/libpthread/thread/thr_mutex_protocol.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_mutexattr_getprotocol(pthread_mutexattr_t *mattr, int *protocol)
+{
+ int ret = 0;
+
+ if ((mattr == NULL) || (*mattr == NULL))
+ ret = EINVAL;
+ else
+ *protocol = (*mattr)->m_protocol;
+
+ return(ret);
+}
+
+int
+pthread_mutexattr_setprotocol(pthread_mutexattr_t *mattr, int protocol)
+{
+ int ret = 0;
+
+ if ((mattr == NULL) || (*mattr == NULL) ||
+ (protocol < PTHREAD_PRIO_NONE) || (protocol > PTHREAD_PRIO_PROTECT))
+ ret = EINVAL;
+ else {
+ (*mattr)->m_protocol = protocol;
+ (*mattr)->m_ceiling = PTHREAD_MAX_PRIORITY;
+ }
+ return(ret);
+}
+
+#endif
diff --git a/lib/libpthread/thread/thr_mutexattr_destroy.c b/lib/libpthread/thread/thr_mutexattr_destroy.c
new file mode 100644
index 0000000..9afebad
--- /dev/null
+++ b/lib/libpthread/thread/thr_mutexattr_destroy.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL) {
+ ret = EINVAL;
+ } else {
+ free(*attr);
+ *attr = NULL;
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_nanosleep.c b/lib/libpthread/thread/thr_nanosleep.c
new file mode 100644
index 0000000..e4772b4
--- /dev/null
+++ b/lib/libpthread/thread/thr_nanosleep.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdio.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+nanosleep(const struct timespec * time_to_sleep,
+ struct timespec * time_remaining)
+{
+ int ret = 0;
+ struct timespec current_time;
+ struct timespec current_time1;
+ struct timespec remaining_time;
+ struct timeval tv;
+
+ _thread_enter_cancellation_point();
+ /* Check if the time to sleep is legal: */
+ if (time_to_sleep == NULL || time_to_sleep->tv_sec < 0 ||
+ time_to_sleep->tv_nsec < 0 || time_to_sleep->tv_nsec >= 1000000000) {
+ /* Return an EINVAL error : */
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ /* Get the current time: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &current_time);
+
+ /* Calculate the time for the current thread to wake up: */
+ _thread_run->wakeup_time.tv_sec = current_time.tv_sec + time_to_sleep->tv_sec;
+ _thread_run->wakeup_time.tv_nsec = current_time.tv_nsec + time_to_sleep->tv_nsec;
+
+ /* Check if the nanosecond field has overflowed: */
+ if (_thread_run->wakeup_time.tv_nsec >= 1000000000) {
+ /* Wrap the nanosecond field: */
+ _thread_run->wakeup_time.tv_sec += 1;
+ _thread_run->wakeup_time.tv_nsec -= 1000000000;
+ }
+ _thread_run->interrupted = 0;
+
+ /* Reschedule the current thread to sleep: */
+ _thread_kern_sched_state(PS_SLEEP_WAIT, __FILE__, __LINE__);
+
+ /* Get the current time: */
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &current_time1);
+
+ /* Calculate the remaining time to sleep: */
+ remaining_time.tv_sec = time_to_sleep->tv_sec + current_time.tv_sec - current_time1.tv_sec;
+ remaining_time.tv_nsec = time_to_sleep->tv_nsec + current_time.tv_nsec - current_time1.tv_nsec;
+
+ /* Check if the nanosecond field has underflowed: */
+ if (remaining_time.tv_nsec < 0) {
+ /* Handle the underflow: */
+ remaining_time.tv_sec -= 1;
+ remaining_time.tv_nsec += 1000000000;
+ }
+
+ /* Check if the nanosecond field has overflowed: */
+ if (remaining_time.tv_nsec >= 1000000000) {
+ /* Handle the overflow: */
+ remaining_time.tv_sec += 1;
+ remaining_time.tv_nsec -= 1000000000;
+ }
+
+ /* Check if the sleep was longer than the required time: */
+ if (remaining_time.tv_sec < 0) {
+ /* Reset the time left: */
+ remaining_time.tv_sec = 0;
+ remaining_time.tv_nsec = 0;
+ }
+
+ /* Check if the time remaining is to be returned: */
+ if (time_remaining != NULL) {
+ /* Return the actual time slept: */
+ time_remaining->tv_sec = remaining_time.tv_sec;
+ time_remaining->tv_nsec = remaining_time.tv_nsec;
+ }
+
+ /* Check if the sleep was interrupted: */
+ if (_thread_run->interrupted) {
+ /* Return an EINTR error : */
+ errno = EINTR;
+ ret = -1;
+ }
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_once.c b/lib/libpthread/thread/thr_once.c
new file mode 100644
index 0000000..ea56d82
--- /dev/null
+++ b/lib/libpthread/thread/thr_once.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_once(pthread_once_t * once_control, void (*init_routine) (void))
+{
+ if (once_control->state == PTHREAD_NEEDS_INIT) {
+ pthread_mutex_lock(&(once_control->mutex));
+ if (once_control->state == PTHREAD_NEEDS_INIT) {
+ init_routine();
+ once_control->state = PTHREAD_DONE_INIT;
+ }
+ pthread_mutex_unlock(&(once_control->mutex));
+ }
+ return (0);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_open.c b/lib/libpthread/thread/thr_open.c
new file mode 100644
index 0000000..4e9993e
--- /dev/null
+++ b/lib/libpthread/thread/thr_open.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+open(const char *path, int flags,...)
+{
+ int fd;
+ int mode = 0;
+ va_list ap;
+
+ _thread_enter_cancellation_point();
+
+ /* Check if the file is being created: */
+ if (flags & O_CREAT) {
+ /* Get the creation mode: */
+ va_start(ap, flags);
+ mode = va_arg(ap, int);
+ va_end(ap);
+ }
+ /* Open the file: */
+ if ((fd = _thread_sys_open(path, flags, mode)) < 0) {
+ }
+ /* Initialise the file descriptor table entry: */
+ else if (_thread_fd_table_init(fd) != 0) {
+ /* Quietly close the file: */
+ _thread_sys_close(fd);
+
+ /* Reset the file descriptor: */
+ fd = -1;
+ }
+
+ _thread_leave_cancellation_point();
+
+ /* Return the file descriptor or -1 on error: */
+ return (fd);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_poll.c b/lib/libpthread/thread/thr_poll.c
new file mode 100644
index 0000000..01916ad
--- /dev/null
+++ b/lib/libpthread/thread/thr_poll.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+
+int
+poll(struct pollfd *fds, unsigned int nfds, int timeout)
+{
+ struct timespec ts;
+ int numfds = nfds;
+ int i, ret = 0, found = 0;
+ struct pthread_poll_data data;
+
+ if (numfds > _thread_dtablesize) {
+ numfds = _thread_dtablesize;
+ }
+ /* Check if a timeout was specified: */
+ if (timeout == INFTIM) {
+ /* Wait for ever: */
+ _thread_kern_set_timeout(NULL);
+ } else if (timeout > 0) {
+ /* Convert the timeout in msec to a timespec: */
+ ts.tv_sec = timeout / 1000;
+ ts.tv_nsec = (timeout % 1000) * 1000;
+
+ /* Set the wake up time: */
+ _thread_kern_set_timeout(&ts);
+ } else if (timeout < 0) {
+ /* a timeout less than zero but not == INFTIM is invalid */
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (((ret = _thread_sys_poll(fds, numfds, 0)) == 0) && (timeout != 0)) {
+ data.nfds = numfds;
+ data.fds = fds;
+
+ /*
+ * Clear revents in case of a timeout which leaves fds
+ * unchanged:
+ */
+ for (i = 0; i < numfds; i++) {
+ fds[i].revents = 0;
+ }
+
+ _thread_run->data.poll_data = &data;
+ _thread_run->interrupted = 0;
+ _thread_kern_sched_state(PS_POLL_WAIT, __FILE__, __LINE__);
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ } else {
+ ret = data.nfds;
+ }
+ }
+
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_priority_queue.c b/lib/libpthread/thread/thr_priority_queue.c
new file mode 100644
index 0000000..5bd8a8c
--- /dev/null
+++ b/lib/libpthread/thread/thr_priority_queue.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <stdlib.h>
+#include <sys/queue.h>
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Prototypes: */
+static void pq_insert_prio_list(pq_queue_t *pq, int prio);
+
+#if defined(_PTHREADS_INVARIANTS)
+
+static int _pq_active = 0;
+
+#define _PQ_IN_SCHEDQ (PTHREAD_FLAGS_IN_PRIOQ | PTHREAD_FLAGS_IN_WAITQ | PTHREAD_FLAGS_IN_WORKQ)
+
+#define _PQ_SET_ACTIVE() _pq_active = 1
+#define _PQ_CLEAR_ACTIVE() _pq_active = 0
+#define _PQ_ASSERT_ACTIVE(msg) do { \
+ if (_pq_active == 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_INACTIVE(msg) do { \
+ if (_pq_active != 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_IN_WAITQ(thrd, msg) do { \
+ if (((thrd)->flags & PTHREAD_FLAGS_IN_WAITQ) == 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_IN_PRIOQ(thrd, msg) do { \
+ if (((thrd)->flags & PTHREAD_FLAGS_IN_PRIOQ) == 0) \
+ PANIC(msg); \
+} while (0)
+#define _PQ_ASSERT_NOT_QUEUED(thrd, msg) do { \
+ if ((thrd)->flags & _PQ_IN_SCHEDQ) \
+ PANIC(msg); \
+} while (0)
+
+#else
+
+#define _PQ_SET_ACTIVE()
+#define _PQ_CLEAR_ACTIVE()
+#define _PQ_ASSERT_ACTIVE(msg)
+#define _PQ_ASSERT_INACTIVE(msg)
+#define _PQ_ASSERT_IN_WAITQ(thrd, msg)
+#define _PQ_ASSERT_IN_PRIOQ(thrd, msg)
+#define _PQ_ASSERT_NOT_QUEUED(thrd, msg)
+#define _PQ_CHECK_PRIO()
+
+#endif
+
+
+int
+_pq_alloc(pq_queue_t *pq, int minprio, int maxprio)
+{
+ int i, ret = 0;
+ int prioslots = maxprio - minprio + 1;
+
+ if (pq == NULL)
+ ret = -1;
+
+ /* Create the priority queue with (maxprio - minprio + 1) slots: */
+ else if ((pq->pq_lists =
+ (pq_list_t *) malloc(sizeof(pq_list_t) * prioslots)) == NULL)
+ ret = -1;
+
+ else {
+ /* Remember the queue size: */
+ pq->pq_size = prioslots;
+
+ ret = _pq_init(pq);
+
+ }
+ return (ret);
+}
+
+int
+_pq_init(pq_queue_t *pq)
+{
+ int i, ret = 0;
+
+ if ((pq == NULL) || (pq->pq_lists == NULL))
+ ret = -1;
+
+ else {
+ /* Initialize the queue for each priority slot: */
+ for (i = 0; i < pq->pq_size; i++) {
+ TAILQ_INIT(&pq->pq_lists[i].pl_head);
+ pq->pq_lists[i].pl_prio = i;
+ pq->pq_lists[i].pl_queued = 0;
+ }
+
+ /* Initialize the priority queue: */
+ TAILQ_INIT(&pq->pq_queue);
+ _PQ_CLEAR_ACTIVE();
+ }
+ return (ret);
+}
+
+void
+_pq_remove(pq_queue_t *pq, pthread_t pthread)
+{
+ int prio = pthread->active_priority;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_remove: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_IN_PRIOQ(pthread, "_pq_remove: Not in priority queue");
+
+ /*
+ * Remove this thread from priority list. Note that if
+ * the priority list becomes empty, it is not removed
+ * from the priority queue because another thread may be
+ * added to the priority list (resulting in a needless
+ * removal/insertion). Priority lists are only removed
+ * from the priority queue when _pq_first is called.
+ */
+ TAILQ_REMOVE(&pq->pq_lists[prio].pl_head, pthread, pqe);
+
+ /* This thread is now longer in the priority queue. */
+ pthread->flags &= ~PTHREAD_FLAGS_IN_PRIOQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+
+void
+_pq_insert_head(pq_queue_t *pq, pthread_t pthread)
+{
+ int prio = pthread->active_priority;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_insert_head: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_NOT_QUEUED(pthread,
+ "_pq_insert_head: Already in priority queue");
+
+ TAILQ_INSERT_HEAD(&pq->pq_lists[prio].pl_head, pthread, pqe);
+ if (pq->pq_lists[prio].pl_queued == 0)
+ /* Insert the list into the priority queue: */
+ pq_insert_prio_list(pq, prio);
+
+ /* Mark this thread as being in the priority queue. */
+ pthread->flags |= PTHREAD_FLAGS_IN_PRIOQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+
+void
+_pq_insert_tail(pq_queue_t *pq, pthread_t pthread)
+{
+ int prio = pthread->active_priority;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_insert_tail: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_NOT_QUEUED(pthread,
+ "_pq_insert_tail: Already in priority queue");
+
+ TAILQ_INSERT_TAIL(&pq->pq_lists[prio].pl_head, pthread, pqe);
+ if (pq->pq_lists[prio].pl_queued == 0)
+ /* Insert the list into the priority queue: */
+ pq_insert_prio_list(pq, prio);
+
+ /* Mark this thread as being in the priority queue. */
+ pthread->flags |= PTHREAD_FLAGS_IN_PRIOQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+
+pthread_t
+_pq_first(pq_queue_t *pq)
+{
+ pq_list_t *pql;
+ pthread_t pthread = NULL;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_pq_first: pq_active");
+ _PQ_SET_ACTIVE();
+
+ while (((pql = TAILQ_FIRST(&pq->pq_queue)) != NULL) &&
+ (pthread == NULL)) {
+ if ((pthread = TAILQ_FIRST(&pql->pl_head)) == NULL) {
+ /*
+ * The priority list is empty; remove the list
+ * from the queue.
+ */
+ TAILQ_REMOVE(&pq->pq_queue, pql, pl_link);
+
+ /* Mark the list as not being in the queue: */
+ pql->pl_queued = 0;
+ }
+ }
+
+ _PQ_CLEAR_ACTIVE();
+ return (pthread);
+}
+
+
+static void
+pq_insert_prio_list(pq_queue_t *pq, int prio)
+{
+ pq_list_t *pql;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_ACTIVE("pq_insert_prio_list: pq_active");
+
+ /*
+ * The priority queue is in descending priority order. Start at
+ * the beginning of the queue and find the list before which the
+ * new list should be inserted.
+ */
+ pql = TAILQ_FIRST(&pq->pq_queue);
+ while ((pql != NULL) && (pql->pl_prio > prio))
+ pql = TAILQ_NEXT(pql, pl_link);
+
+ /* Insert the list: */
+ if (pql == NULL)
+ TAILQ_INSERT_TAIL(&pq->pq_queue, &pq->pq_lists[prio], pl_link);
+ else
+ TAILQ_INSERT_BEFORE(pql, &pq->pq_lists[prio], pl_link);
+
+ /* Mark this list as being in the queue: */
+ pq->pq_lists[prio].pl_queued = 1;
+}
+
+#if defined(_PTHREADS_INVARIANTS)
+void
+_waitq_insert(pthread_t pthread)
+{
+ pthread_t tid;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_waitq_insert: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_NOT_QUEUED(pthread, "_waitq_insert: Already in queue");
+
+ if (pthread->wakeup_time.tv_sec == -1)
+ TAILQ_INSERT_TAIL(&_waitingq, pthread, pqe);
+ else {
+ tid = TAILQ_FIRST(&_waitingq);
+ while ((tid != NULL) && (tid->wakeup_time.tv_sec != -1) &&
+ ((tid->wakeup_time.tv_sec < pthread->wakeup_time.tv_sec) ||
+ ((tid->wakeup_time.tv_sec == pthread->wakeup_time.tv_sec) &&
+ (tid->wakeup_time.tv_nsec <= pthread->wakeup_time.tv_nsec))))
+ tid = TAILQ_NEXT(tid, pqe);
+ if (tid == NULL)
+ TAILQ_INSERT_TAIL(&_waitingq, pthread, pqe);
+ else
+ TAILQ_INSERT_BEFORE(tid, pthread, pqe);
+ }
+ pthread->flags |= PTHREAD_FLAGS_IN_WAITQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+void
+_waitq_remove(pthread_t pthread)
+{
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ _PQ_ASSERT_INACTIVE("_waitq_remove: pq_active");
+ _PQ_SET_ACTIVE();
+ _PQ_ASSERT_IN_WAITQ(pthread, "_waitq_remove: Not in queue");
+
+ TAILQ_REMOVE(&_waitingq, pthread, pqe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_WAITQ;
+
+ _PQ_CLEAR_ACTIVE();
+}
+
+void
+_waitq_setactive(void)
+{
+ _PQ_ASSERT_INACTIVE("_waitq_setactive: pq_active");
+ _PQ_SET_ACTIVE();
+}
+
+void
+_waitq_clearactive(void)
+{
+ _PQ_ASSERT_ACTIVE("_waitq_clearactive: ! pq_active");
+ _PQ_CLEAR_ACTIVE();
+}
+#endif
+#endif
diff --git a/lib/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h
new file mode 100644
index 0000000..4326bf6
--- /dev/null
+++ b/lib/libpthread/thread/thr_private.h
@@ -0,0 +1,1182 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Private thread definitions for the uthread kernel.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PTHREAD_PRIVATE_H
+#define _PTHREAD_PRIVATE_H
+
+/*
+ * Evaluate the storage class specifier.
+ */
+#ifdef GLOBAL_PTHREAD_PRIVATE
+#define SCLASS
+#else
+#define SCLASS extern
+#endif
+
+/*
+ * Include files.
+ */
+#include <setjmp.h>
+#include <signal.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sched.h>
+#include <spinlock.h>
+#include <pthread_np.h>
+
+/*
+ * Kernel fatal error handler macro.
+ */
+#define PANIC(string) _thread_exit(__FILE__,__LINE__,string)
+
+/* Output debug messages like this: */
+#define stdout_debug(_x) _thread_sys_write(1,_x,strlen(_x));
+#define stderr_debug(_x) _thread_sys_write(2,_x,strlen(_x));
+
+
+/*
+ * Priority queue manipulation macros (using pqe link):
+ */
+#define PTHREAD_PRIOQ_INSERT_HEAD(thrd) _pq_insert_head(&_readyq,thrd)
+#define PTHREAD_PRIOQ_INSERT_TAIL(thrd) _pq_insert_tail(&_readyq,thrd)
+#define PTHREAD_PRIOQ_REMOVE(thrd) _pq_remove(&_readyq,thrd)
+#define PTHREAD_PRIOQ_FIRST() _pq_first(&_readyq)
+
+/*
+ * Waiting queue manipulation macros (using pqe link):
+ */
+#if defined(_PTHREADS_INVARIANTS)
+#define PTHREAD_WAITQ_REMOVE(thrd) _waitq_remove(thrd)
+#define PTHREAD_WAITQ_INSERT(thrd) _waitq_insert(thrd)
+#define PTHREAD_WAITQ_CLEARACTIVE() _waitq_clearactive()
+#define PTHREAD_WAITQ_SETACTIVE() _waitq_setactive()
+#else
+#define PTHREAD_WAITQ_REMOVE(thrd) TAILQ_REMOVE(&_waitingq,thrd,pqe)
+#define PTHREAD_WAITQ_INSERT(thrd) do { \
+ if ((thrd)->wakeup_time.tv_sec == -1) \
+ TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe); \
+ else { \
+ pthread_t tid = TAILQ_FIRST(&_waitingq); \
+ while ((tid != NULL) && (tid->wakeup_time.tv_sec != -1) && \
+ ((tid->wakeup_time.tv_sec < (thrd)->wakeup_time.tv_sec) || \
+ ((tid->wakeup_time.tv_sec == (thrd)->wakeup_time.tv_sec) && \
+ (tid->wakeup_time.tv_nsec <= (thrd)->wakeup_time.tv_nsec)))) \
+ tid = TAILQ_NEXT(tid, pqe); \
+ if (tid == NULL) \
+ TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe); \
+ else \
+ TAILQ_INSERT_BEFORE(tid,thrd,pqe); \
+ } \
+} while (0)
+#define PTHREAD_WAITQ_CLEARACTIVE()
+#define PTHREAD_WAITQ_SETACTIVE()
+#endif
+
+/*
+ * Work queue manipulation macros (using qe link):
+ */
+#define PTHREAD_WORKQ_INSERT(thrd) do { \
+ TAILQ_INSERT_TAIL(&_workq,thrd,qe); \
+ (thrd)->flags |= PTHREAD_FLAGS_IN_WORKQ; \
+} while (0)
+#define PTHREAD_WORKQ_REMOVE(thrd) do { \
+ TAILQ_REMOVE(&_workq,thrd,qe); \
+ (thrd)->flags &= ~PTHREAD_FLAGS_IN_WORKQ; \
+} while (0)
+
+
+/*
+ * State change macro without scheduling queue change:
+ */
+#define PTHREAD_SET_STATE(thrd, newstate) do { \
+ (thrd)->state = newstate; \
+ (thrd)->fname = __FILE__; \
+ (thrd)->lineno = __LINE__; \
+} while (0)
+
+/*
+ * State change macro with scheduling queue change - This must be
+ * called with preemption deferred (see thread_kern_sched_[un]defer).
+ */
+#if defined(_PTHREADS_INVARIANTS)
+#define PTHREAD_NEW_STATE(thrd, newstate) do { \
+ if (_thread_kern_new_state != 0) \
+ PANIC("Recursive PTHREAD_NEW_STATE"); \
+ _thread_kern_new_state = 1; \
+ if ((thrd)->state != newstate) { \
+ if ((thrd)->state == PS_RUNNING) { \
+ PTHREAD_PRIOQ_REMOVE(thrd); \
+ PTHREAD_WAITQ_INSERT(thrd); \
+ } else if (newstate == PS_RUNNING) { \
+ PTHREAD_WAITQ_REMOVE(thrd); \
+ PTHREAD_PRIOQ_INSERT_TAIL(thrd); \
+ } \
+ } \
+ _thread_kern_new_state = 0; \
+ PTHREAD_SET_STATE(thrd, newstate); \
+} while (0)
+#else
+#define PTHREAD_NEW_STATE(thrd, newstate) do { \
+ if ((thrd)->state != newstate) { \
+ if ((thrd)->state == PS_RUNNING) { \
+ PTHREAD_PRIOQ_REMOVE(thrd); \
+ PTHREAD_WAITQ_INSERT(thrd); \
+ } else if (newstate == PS_RUNNING) { \
+ PTHREAD_WAITQ_REMOVE(thrd); \
+ PTHREAD_PRIOQ_INSERT_TAIL(thrd); \
+ } \
+ } \
+ PTHREAD_SET_STATE(thrd, newstate); \
+} while (0)
+#endif
+
+/*
+ * Define the signals to be used for scheduling.
+ */
+#if defined(_PTHREADS_COMPAT_SCHED)
+#define _ITIMER_SCHED_TIMER ITIMER_VIRTUAL
+#define _SCHED_SIGNAL SIGVTALRM
+#else
+#define _ITIMER_SCHED_TIMER ITIMER_PROF
+#define _SCHED_SIGNAL SIGPROF
+#endif
+
+/*
+ * Priority queues.
+ *
+ * XXX It'd be nice if these were contained in uthread_priority_queue.[ch].
+ */
+typedef struct pq_list {
+ TAILQ_HEAD(, pthread) pl_head; /* list of threads at this priority */
+ TAILQ_ENTRY(pq_list) pl_link; /* link for queue of priority lists */
+ int pl_prio; /* the priority of this list */
+ int pl_queued; /* is this in the priority queue */
+} pq_list_t;
+
+typedef struct pq_queue {
+ TAILQ_HEAD(, pq_list) pq_queue; /* queue of priority lists */
+ pq_list_t *pq_lists; /* array of all priority lists */
+ int pq_size; /* number of priority lists */
+} pq_queue_t;
+
+
+/*
+ * TailQ initialization values.
+ */
+#define TAILQ_INITIALIZER { NULL, NULL }
+
+/*
+ * Mutex definitions.
+ */
+union pthread_mutex_data {
+ void *m_ptr;
+ int m_count;
+};
+
+struct pthread_mutex {
+ enum pthread_mutextype m_type;
+ int m_protocol;
+ TAILQ_HEAD(mutex_head, pthread) m_queue;
+ struct pthread *m_owner;
+ union pthread_mutex_data m_data;
+ long m_flags;
+ int m_refcount;
+
+ /*
+ * Used for priority inheritence and protection.
+ *
+ * m_prio - For priority inheritence, the highest active
+ * priority (threads locking the mutex inherit
+ * this priority). For priority protection, the
+ * ceiling priority of this mutex.
+ * m_saved_prio - mutex owners inherited priority before
+ * taking the mutex, restored when the owner
+ * unlocks the mutex.
+ */
+ int m_prio;
+ int m_saved_prio;
+
+ /*
+ * Link for list of all mutexes a thread currently owns.
+ */
+ TAILQ_ENTRY(pthread_mutex) m_qe;
+
+ /*
+ * Lock for accesses to this structure.
+ */
+ spinlock_t lock;
+};
+
+/*
+ * Flags for mutexes.
+ */
+#define MUTEX_FLAGS_PRIVATE 0x01
+#define MUTEX_FLAGS_INITED 0x02
+#define MUTEX_FLAGS_BUSY 0x04
+
+/*
+ * Static mutex initialization values.
+ */
+#define PTHREAD_MUTEX_STATIC_INITIALIZER \
+ { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, TAILQ_INITIALIZER, \
+ NULL, { NULL }, MUTEX_FLAGS_PRIVATE, 0, 0, 0, TAILQ_INITIALIZER, \
+ _SPINLOCK_INITIALIZER }
+
+struct pthread_mutex_attr {
+ enum pthread_mutextype m_type;
+ int m_protocol;
+ int m_ceiling;
+ long m_flags;
+};
+
+/*
+ * Condition variable definitions.
+ */
+enum pthread_cond_type {
+ COND_TYPE_FAST,
+ COND_TYPE_MAX
+};
+
+struct pthread_cond {
+ enum pthread_cond_type c_type;
+ TAILQ_HEAD(cond_head, pthread) c_queue;
+ pthread_mutex_t c_mutex;
+ void *c_data;
+ long c_flags;
+
+ /*
+ * Lock for accesses to this structure.
+ */
+ spinlock_t lock;
+};
+
+struct pthread_cond_attr {
+ enum pthread_cond_type c_type;
+ long c_flags;
+};
+
+/*
+ * Flags for condition variables.
+ */
+#define COND_FLAGS_PRIVATE 0x01
+#define COND_FLAGS_INITED 0x02
+#define COND_FLAGS_BUSY 0x04
+
+/*
+ * Static cond initialization values.
+ */
+#define PTHREAD_COND_STATIC_INITIALIZER \
+ { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \
+ 0, _SPINLOCK_INITIALIZER }
+
+/*
+ * Cleanup definitions.
+ */
+struct pthread_cleanup {
+ struct pthread_cleanup *next;
+ void (*routine) ();
+ void *routine_arg;
+};
+
+struct pthread_attr {
+ int sched_policy;
+ int sched_inherit;
+ int sched_interval;
+ int prio;
+ int suspend;
+ int flags;
+ void *arg_attr;
+ void (*cleanup_attr) ();
+ void *stackaddr_attr;
+ size_t stacksize_attr;
+};
+
+/*
+ * Thread creation state attributes.
+ */
+#define PTHREAD_CREATE_RUNNING 0
+#define PTHREAD_CREATE_SUSPENDED 1
+
+/*
+ * Miscellaneous definitions.
+ */
+#define PTHREAD_STACK_DEFAULT 65536
+/* Size of red zone at the end of each stack. */
+#define PTHREAD_STACK_GUARD PAGE_SIZE
+
+/*
+ * Maximum size of initial thread's stack. This perhaps deserves to be larger
+ * than the stacks of other threads, since many applications are likely to run
+ * almost entirely on this stack.
+ */
+#define PTHREAD_STACK_INITIAL 0x100000
+/* Address immediately beyond the beginning of the initial thread stack. */
+#define PTHREAD_DEFAULT_PRIORITY 64
+#define PTHREAD_MAX_PRIORITY 126
+#define PTHREAD_MIN_PRIORITY 0
+#define _POSIX_THREAD_ATTR_STACKSIZE
+
+/*
+ * Clock resolution in nanoseconds.
+ */
+#define CLOCK_RES_NSEC 10000000
+
+/*
+ * Time slice period in microseconds.
+ */
+#define TIMESLICE_USEC 100000
+
+struct pthread_key {
+ spinlock_t lock;
+ volatile int allocated;
+ volatile int count;
+ void (*destructor) ();
+};
+
+struct pthread_rwlockattr {
+ int pshared;
+};
+
+struct pthread_rwlock {
+ pthread_mutex_t lock; /* monitor lock */
+ int state; /* 0 = idle >0 = # of readers -1 = writer */
+ pthread_cond_t read_signal;
+ pthread_cond_t write_signal;
+ int blocked_writers;
+};
+
+/*
+ * Thread states.
+ */
+enum pthread_state {
+ PS_RUNNING,
+ PS_SIGTHREAD,
+ PS_MUTEX_WAIT,
+ PS_COND_WAIT,
+ PS_FDLR_WAIT,
+ PS_FDLW_WAIT,
+ PS_FDR_WAIT,
+ PS_FDW_WAIT,
+ PS_FILE_WAIT,
+ PS_POLL_WAIT,
+ PS_SELECT_WAIT,
+ PS_SLEEP_WAIT,
+ PS_WAIT_WAIT,
+ PS_SIGSUSPEND,
+ PS_SIGWAIT,
+ PS_SPINBLOCK,
+ PS_JOIN,
+ PS_SUSPENDED,
+ PS_DEAD,
+ PS_DEADLOCK,
+ PS_STATE_MAX
+};
+
+
+/*
+ * File descriptor locking definitions.
+ */
+#define FD_READ 0x1
+#define FD_WRITE 0x2
+#define FD_RDWR (FD_READ | FD_WRITE)
+
+/*
+ * File descriptor table structure.
+ */
+struct fd_table_entry {
+ /*
+ * Lock for accesses to this file descriptor table
+ * entry. This is passed to _spinlock() to provide atomic
+ * access to this structure. It does *not* represent the
+ * state of the lock on the file descriptor.
+ */
+ spinlock_t lock;
+ TAILQ_HEAD(, pthread) r_queue; /* Read queue. */
+ TAILQ_HEAD(, pthread) w_queue; /* Write queue. */
+ struct pthread *r_owner; /* Ptr to thread owning read lock. */
+ struct pthread *w_owner; /* Ptr to thread owning write lock. */
+ char *r_fname; /* Ptr to read lock source file name */
+ int r_lineno; /* Read lock source line number. */
+ char *w_fname; /* Ptr to write lock source file name */
+ int w_lineno; /* Write lock source line number. */
+ int r_lockcount; /* Count for FILE read locks. */
+ int w_lockcount; /* Count for FILE write locks. */
+ int flags; /* Flags used in open. */
+};
+
+struct pthread_poll_data {
+ int nfds;
+ struct pollfd *fds;
+};
+
+union pthread_wait_data {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ const sigset_t *sigwait; /* Waiting on a signal in sigwait */
+ struct {
+ short fd; /* Used when thread waiting on fd */
+ short branch; /* Line number, for debugging. */
+ char *fname; /* Source file name for debugging.*/
+ } fd;
+ struct pthread_poll_data * poll_data;
+ spinlock_t *spinlock;
+};
+
+/*
+ * Thread structure.
+ */
+struct pthread {
+ /*
+ * Magic value to help recognize a valid thread structure
+ * from an invalid one:
+ */
+#define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115)
+ u_int32_t magic;
+ char *name;
+ u_int64_t uniqueid; /* for gdb */
+
+ /*
+ * Lock for accesses to this thread structure.
+ */
+ spinlock_t lock;
+
+ /* Queue entry for list of all threads: */
+ TAILQ_ENTRY(pthread) tle;
+
+ /* Queue entry for list of dead threads: */
+ TAILQ_ENTRY(pthread) dle;
+
+ /*
+ * Thread start routine, argument, stack pointer and thread
+ * attributes.
+ */
+ void *(*start_routine)(void *);
+ void *arg;
+ void *stack;
+ struct pthread_attr attr;
+
+#if (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(__i386__)
+ /*
+ * Saved floating point registers on systems where they are not
+ * saved in the signal context.
+ */
+ char saved_fp[108];
+#endif
+
+ /*
+ * Saved signal context used in call to sigreturn by
+ * _thread_kern_sched if sig_saved is TRUE.
+ */
+ ucontext_t saved_sigcontext;
+
+ /*
+ * Saved jump buffer used in call to longjmp by _thread_kern_sched
+ * if sig_saved is FALSE.
+ */
+ jmp_buf saved_jmp_buf;
+
+ /*
+ * TRUE if the last state saved was a signal context. FALSE if the
+ * last state saved was a jump buffer.
+ */
+ int sig_saved;
+
+ /*
+ * Cancelability flags - the lower 2 bits are used by cancel
+ * definitions in pthread.h
+ */
+#define PTHREAD_AT_CANCEL_POINT 0x0004
+#define PTHREAD_CANCELLING 0x0008
+#define PTHREAD_CANCEL_NEEDED 0x0010
+ int cancelflags;
+
+ /*
+ * Current signal mask and pending signals.
+ */
+ sigset_t sigmask;
+ sigset_t sigpend;
+
+ /* Thread state: */
+ enum pthread_state state;
+
+ /* Time that this thread was last made active. */
+ struct timeval last_active;
+
+ /* Time that this thread was last made inactive. */
+ struct timeval last_inactive;
+
+ /*
+ * Number of microseconds accumulated by this thread when
+ * time slicing is active.
+ */
+ long slice_usec;
+
+ /*
+ * Incremental priority accumulated by thread while it is ready to
+ * run but is denied being run.
+ */
+ int inc_prio;
+
+ /*
+ * Time to wake up thread. This is used for sleeping threads and
+ * for any operation which may time out (such as select).
+ */
+ struct timespec wakeup_time;
+
+ /* TRUE if operation has timed out. */
+ int timeout;
+
+ /*
+ * Error variable used instead of errno. The function __error()
+ * returns a pointer to this.
+ */
+ int error;
+
+ /* Join queue head and link for waiting threads: */
+ TAILQ_HEAD(join_head, pthread) join_queue;
+
+ /*
+ * The current thread can belong to only one scheduling queue at
+ * a time (ready or waiting queue). It can also belong to (only)
+ * one of:
+ *
+ * o A queue of threads waiting for a mutex
+ * o A queue of threads waiting for a condition variable
+ * o A queue of threads waiting for another thread to terminate
+ * (the join queue above)
+ * o A queue of threads waiting for a file descriptor lock
+ * o A queue of threads needing work done by the kernel thread
+ * (waiting for a spinlock or file I/O)
+ *
+ * Use pqe for the scheduling queue link (both ready and waiting),
+ * and qe for other links.
+ */
+
+ /* Priority queue entry for this thread: */
+ TAILQ_ENTRY(pthread) pqe;
+
+ /* Queue entry for this thread: */
+ TAILQ_ENTRY(pthread) qe;
+
+ /* Wait data. */
+ union pthread_wait_data data;
+
+ /*
+ * Allocated for converting select into poll.
+ */
+ struct pthread_poll_data poll_data;
+
+ /*
+ * Set to TRUE if a blocking operation was
+ * interrupted by a signal:
+ */
+ int interrupted;
+
+ /* Signal number when in state PS_SIGWAIT: */
+ int signo;
+
+ /*
+ * Set to non-zero when this thread has deferred signals.
+ * We allow for recursive deferral.
+ */
+ int sig_defer_count;
+
+ /*
+ * Set to TRUE if this thread should yield after undeferring
+ * signals.
+ */
+ int yield_on_sig_undefer;
+
+ /* Miscellaneous flags; only set with signals deferred. */
+ int flags;
+#define PTHREAD_FLAGS_PRIVATE 0x0001
+#define PTHREAD_EXITING 0x0002
+#define PTHREAD_FLAGS_IN_CONDQ 0x0004 /* in condition queue using qe link*/
+#define PTHREAD_FLAGS_IN_WORKQ 0x0008 /* in work queue using qe link */
+#define PTHREAD_FLAGS_IN_WAITQ 0x0010 /* in waiting queue using pqe link */
+#define PTHREAD_FLAGS_IN_PRIOQ 0x0020 /* in priority queue using pqe link */
+#define PTHREAD_FLAGS_IN_MUTEXQ 0x0040 /* in mutex queue using qe link */
+#define PTHREAD_FLAGS_IN_FILEQ 0x0080 /* in file lock queue using qe link */
+#define PTHREAD_FLAGS_IN_FDQ 0x0100 /* in fd lock queue using qe link */
+#define PTHREAD_FLAGS_TRACE 0x0200 /* for debugging purposes */
+
+ /*
+ * Base priority is the user setable and retrievable priority
+ * of the thread. It is only affected by explicit calls to
+ * set thread priority and upon thread creation via a thread
+ * attribute or default priority.
+ */
+ char base_priority;
+
+ /*
+ * Inherited priority is the priority a thread inherits by
+ * taking a priority inheritence or protection mutex. It
+ * is not affected by base priority changes. Inherited
+ * priority defaults to and remains 0 until a mutex is taken
+ * that is being waited on by any other thread whose priority
+ * is non-zero.
+ */
+ char inherited_priority;
+
+ /*
+ * Active priority is always the maximum of the threads base
+ * priority and inherited priority. When there is a change
+ * in either the base or inherited priority, the active
+ * priority must be recalculated.
+ */
+ char active_priority;
+
+ /* Number of priority ceiling or protection mutexes owned. */
+ int priority_mutex_count;
+
+ /*
+ * Queue of currently owned mutexes.
+ */
+ TAILQ_HEAD(, pthread_mutex) mutexq;
+
+ void *ret;
+ const void **specific_data;
+ int specific_data_count;
+
+ /* Cleanup handlers Link List */
+ struct pthread_cleanup *cleanup;
+ char *fname; /* Ptr to source file name */
+ int lineno; /* Source line number. */
+};
+
+/* Spare thread stack. */
+struct stack {
+ SLIST_ENTRY(stack) qe; /* Queue entry for this stack. */
+};
+
+/*
+ * Global variables for the uthread kernel.
+ */
+
+/* Kernel thread structure used when there are no running threads: */
+SCLASS struct pthread _thread_kern_thread;
+
+/* Ptr to the thread structure for the running thread: */
+SCLASS struct pthread * volatile _thread_run
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= &_thread_kern_thread;
+#else
+;
+#endif
+
+/* Ptr to the thread structure for the last user thread to run: */
+SCLASS struct pthread * volatile _last_user_thread
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= &_thread_kern_thread;
+#else
+;
+#endif
+
+/*
+ * Ptr to the thread running in single-threaded mode or NULL if
+ * running multi-threaded (default POSIX behaviour).
+ */
+SCLASS struct pthread * volatile _thread_single
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL;
+#else
+;
+#endif
+
+/* List of all threads: */
+SCLASS TAILQ_HEAD(, pthread) _thread_list
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= TAILQ_HEAD_INITIALIZER(_thread_list);
+#else
+;
+#endif
+
+/*
+ * Array of kernel pipe file descriptors that are used to ensure that
+ * no signals are missed in calls to _select.
+ */
+SCLASS int _thread_kern_pipe[2]
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= {
+ -1,
+ -1
+};
+#else
+;
+#endif
+SCLASS int volatile _queue_signals
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0;
+#else
+;
+#endif
+SCLASS int _thread_kern_in_sched
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0;
+#else
+;
+#endif
+
+/* Last time that an incremental priority update was performed: */
+SCLASS struct timeval kern_inc_prio_time
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= { 0, 0 };
+#else
+;
+#endif
+
+/* Dead threads: */
+SCLASS TAILQ_HEAD(, pthread) _dead_list
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= TAILQ_HEAD_INITIALIZER(_dead_list);
+#else
+;
+#endif
+
+/* Initial thread: */
+SCLASS struct pthread *_thread_initial
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL;
+#else
+;
+#endif
+
+/* Default thread attributes: */
+SCLASS struct pthread_attr pthread_attr_default
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY, PTHREAD_CREATE_RUNNING,
+ PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, PTHREAD_STACK_DEFAULT };
+#else
+;
+#endif
+
+/* Default mutex attributes: */
+SCLASS struct pthread_mutex_attr pthread_mutexattr_default
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 };
+#else
+;
+#endif
+
+/* Default condition variable attributes: */
+SCLASS struct pthread_cond_attr pthread_condattr_default
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= { COND_TYPE_FAST, 0 };
+#else
+;
+#endif
+
+/*
+ * Standard I/O file descriptors need special flag treatment since
+ * setting one to non-blocking does all on *BSD. Sigh. This array
+ * is used to store the initial flag settings.
+ */
+SCLASS int _pthread_stdio_flags[3];
+
+/* File table information: */
+SCLASS struct fd_table_entry **_thread_fd_table
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL;
+#else
+;
+#endif
+
+/* Table for polling file descriptors: */
+SCLASS struct pollfd *_thread_pfd_table
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL;
+#else
+;
+#endif
+
+SCLASS const int dtablecount
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 4096/sizeof(struct fd_table_entry);
+#else
+;
+#endif
+SCLASS int _thread_dtablesize /* Descriptor table size. */
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0;
+#else
+;
+#endif
+
+SCLASS int _clock_res_nsec /* Clock resolution in nsec. */
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= CLOCK_RES_NSEC;
+#else
+;
+#endif
+
+/* Garbage collector mutex and condition variable. */
+SCLASS pthread_mutex_t _gc_mutex
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL
+#endif
+;
+SCLASS pthread_cond_t _gc_cond
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL
+#endif
+;
+
+/*
+ * Array of signal actions for this process.
+ */
+SCLASS struct sigaction _thread_sigact[NSIG];
+
+/*
+ * Pending signals for this process.
+ */
+SCLASS sigset_t _process_sigpending;
+
+/*
+ * Scheduling queues:
+ */
+SCLASS pq_queue_t _readyq;
+SCLASS TAILQ_HEAD(, pthread) _waitingq;
+
+/*
+ * Work queue:
+ */
+SCLASS TAILQ_HEAD(, pthread) _workq;
+
+/* Tracks the number of threads blocked while waiting for a spinlock. */
+SCLASS volatile int _spinblock_count
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0
+#endif
+;
+
+/* Indicates that the signal queue needs to be checked. */
+SCLASS volatile int _sigq_check_reqd
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0
+#endif
+;
+
+/* Thread switch hook. */
+SCLASS pthread_switch_routine_t _sched_switch_hook
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= NULL
+#endif
+;
+
+/*
+ * Spare stack queue. Stacks of default size are cached in order to reduce
+ * thread creation time. Spare stacks are used in LIFO order to increase cache
+ * locality.
+ */
+SCLASS SLIST_HEAD(, stack) _stackq;
+
+/* Base address of next unallocated default-size stack. Stacks are allocated
+ * contiguously, starting below the beginning of the main stack. When a new
+ * stack is created, a guard page is created just above it in order to (usually)
+ * detect attempts by the adjacent stack to trounce the next thread stack. */
+SCLASS void * _next_stack
+#ifdef GLOBAL_PTHREAD_PRIVATE
+/* main stack top - main stack size - stack size - (red zone + main stack red zone) */
+= (void *) USRSTACK - PTHREAD_STACK_INITIAL - PTHREAD_STACK_DEFAULT - (2 * PTHREAD_STACK_GUARD)
+#endif
+;
+
+/* Used for _PTHREADS_INVARIANTS checking. */
+SCLASS int _thread_kern_new_state
+#ifdef GLOBAL_PTHREAD_PRIVATE
+= 0
+#endif
+;
+
+/* Undefine the storage class specifier: */
+#undef SCLASS
+
+#ifdef _LOCK_DEBUG
+#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock_debug(_fd, _type, \
+ _ts, __FILE__, __LINE__)
+#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock_debug(_fd, _type, \
+ __FILE__, __LINE__)
+#else
+#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock(_fd, _type, _ts)
+#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock(_fd, _type)
+#endif
+
+/*
+ * Function prototype definitions.
+ */
+__BEGIN_DECLS
+char *__ttyname_basic(int);
+char *__ttyname_r_basic(int, char *, size_t);
+char *ttyname_r(int, char *, size_t);
+int _find_dead_thread(pthread_t);
+int _find_thread(pthread_t);
+void _funlock_owned(pthread_t);
+int _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t);
+int _thread_fd_lock(int, int, struct timespec *);
+int _thread_fd_lock_debug(int, int, struct timespec *,char *fname,int lineno);
+void _dispatch_signals(void);
+int _mutex_cv_lock(pthread_mutex_t *);
+int _mutex_cv_unlock(pthread_mutex_t *);
+void _mutex_notify_priochange(pthread_t);
+int _mutex_reinit(pthread_mutex_t *);
+void _mutex_unlock_private(pthread_t);
+int _cond_reinit(pthread_cond_t *);
+int _pq_alloc(struct pq_queue *, int, int);
+int _pq_init(struct pq_queue *);
+void _pq_remove(struct pq_queue *pq, struct pthread *);
+void _pq_insert_head(struct pq_queue *pq, struct pthread *);
+void _pq_insert_tail(struct pq_queue *pq, struct pthread *);
+struct pthread *_pq_first(struct pq_queue *pq);
+#if defined(_PTHREADS_INVARIANTS)
+void _waitq_insert(pthread_t pthread);
+void _waitq_remove(pthread_t pthread);
+void _waitq_setactive(void);
+void _waitq_clearactive(void);
+#endif
+void _thread_exit(char *, int, char *);
+void _thread_exit_cleanup(void);
+void _thread_fd_unlock(int, int);
+void _thread_fd_unlock_debug(int, int, char *, int);
+void _thread_fd_unlock_owned(pthread_t);
+void *_thread_cleanup(pthread_t);
+void _thread_cleanupspecific(void);
+void _thread_dump_info(void);
+void _thread_init(void);
+void _thread_kern_sched(ucontext_t *);
+void _thread_kern_sched_state(enum pthread_state,char *fname,int lineno);
+void _thread_kern_sched_state_unlock(enum pthread_state state,
+ spinlock_t *lock, char *fname, int lineno);
+void _thread_kern_set_timeout(struct timespec *);
+void _thread_kern_sig_defer(void);
+void _thread_kern_sig_undefer(void);
+void _thread_sig_handler(int, int, ucontext_t *);
+pthread_t _thread_sig_handle(int, ucontext_t *);
+void _thread_sig_init(void);
+void _thread_sig_send(pthread_t pthread, int sig);
+void _thread_sig_deliver(pthread_t pthread, int sig);
+void _thread_start(void);
+void _thread_start_sig_handler(void);
+void _thread_seterrno(pthread_t,int);
+int _thread_fd_table_init(int fd);
+pthread_addr_t _thread_gc(pthread_addr_t);
+void _thread_enter_cancellation_point(void);
+void _thread_leave_cancellation_point(void);
+void _thread_cancellation_point(void);
+
+/* #include <signal.h> */
+int _thread_sys_sigaction(int, const struct sigaction *, struct sigaction *);
+int _thread_sys_sigpending(sigset_t *);
+int _thread_sys_sigprocmask(int, const sigset_t *, sigset_t *);
+int _thread_sys_sigsuspend(const sigset_t *);
+int _thread_sys_siginterrupt(int, int);
+int _thread_sys_sigpause(int);
+int _thread_sys_sigreturn(ucontext_t *);
+int _thread_sys_sigstack(const struct sigstack *, struct sigstack *);
+int _thread_sys_sigvec(int, struct sigvec *, struct sigvec *);
+void _thread_sys_psignal(unsigned int, const char *);
+void (*_thread_sys_signal(int, void (*)(int)))(int);
+
+/* #include <sys/stat.h> */
+#ifdef _SYS_STAT_H_
+int _thread_sys_fchmod(int, mode_t);
+int _thread_sys_fstat(int, struct stat *);
+int _thread_sys_fchflags(int, u_long);
+#endif
+
+/* #include <sys/mount.h> */
+#ifdef _SYS_MOUNT_H_
+int _thread_sys_fstatfs(int, struct statfs *);
+#endif
+int _thread_sys_pipe(int *);
+
+/* #include <sys/socket.h> */
+#ifdef _SYS_SOCKET_H_
+int _thread_sys_accept(int, struct sockaddr *, int *);
+int _thread_sys_bind(int, const struct sockaddr *, int);
+int _thread_sys_connect(int, const struct sockaddr *, int);
+int _thread_sys_getpeername(int, struct sockaddr *, int *);
+int _thread_sys_getsockname(int, struct sockaddr *, int *);
+int _thread_sys_getsockopt(int, int, int, void *, int *);
+int _thread_sys_listen(int, int);
+int _thread_sys_setsockopt(int, int, int, const void *, int);
+int _thread_sys_shutdown(int, int);
+int _thread_sys_socket(int, int, int);
+int _thread_sys_socketpair(int, int, int, int *);
+ssize_t _thread_sys_recv(int, void *, size_t, int);
+ssize_t _thread_sys_recvfrom(int, void *, size_t, int, struct sockaddr *, int *);
+ssize_t _thread_sys_recvmsg(int, struct msghdr *, int);
+ssize_t _thread_sys_send(int, const void *, size_t, int);
+ssize_t _thread_sys_sendmsg(int, const struct msghdr *, int);
+ssize_t _thread_sys_sendto(int, const void *,size_t, int, const struct sockaddr *, int);
+#endif
+
+/* #include <stdio.h> */
+#ifdef _STDIO_H_
+FILE *_thread_sys_fdopen(int, const char *);
+FILE *_thread_sys_fopen(const char *, const char *);
+FILE *_thread_sys_freopen(const char *, const char *, FILE *);
+FILE *_thread_sys_popen(const char *, const char *);
+FILE *_thread_sys_tmpfile(void);
+char *_thread_sys_ctermid(char *);
+char *_thread_sys_cuserid(char *);
+char *_thread_sys_fgetln(FILE *, size_t *);
+char *_thread_sys_fgets(char *, int, FILE *);
+char *_thread_sys_gets(char *);
+char *_thread_sys_tempnam(const char *, const char *);
+char *_thread_sys_tmpnam(char *);
+int _thread_sys_fclose(FILE *);
+int _thread_sys_feof(FILE *);
+int _thread_sys_ferror(FILE *);
+int _thread_sys_fflush(FILE *);
+int _thread_sys_fgetc(FILE *);
+int _thread_sys_fgetpos(FILE *, fpos_t *);
+int _thread_sys_fileno(FILE *);
+int _thread_sys_fprintf(FILE *, const char *, ...);
+int _thread_sys_fpurge(FILE *);
+int _thread_sys_fputc(int, FILE *);
+int _thread_sys_fputs(const char *, FILE *);
+int _thread_sys_fscanf(FILE *, const char *, ...);
+int _thread_sys_fseek(FILE *, long, int);
+int _thread_sys_fsetpos(FILE *, const fpos_t *);
+int _thread_sys_getc(FILE *);
+int _thread_sys_getchar(void);
+int _thread_sys_getw(FILE *);
+int _thread_sys_pclose(FILE *);
+int _thread_sys_printf(const char *, ...);
+int _thread_sys_putc(int, FILE *);
+int _thread_sys_putchar(int);
+int _thread_sys_puts(const char *);
+int _thread_sys_putw(int, FILE *);
+int _thread_sys_remove(const char *);
+int _thread_sys_rename (const char *, const char *);
+int _thread_sys_scanf(const char *, ...);
+int _thread_sys_setlinebuf(FILE *);
+int _thread_sys_setvbuf(FILE *, char *, int, size_t);
+int _thread_sys_snprintf(char *, size_t, const char *, ...);
+int _thread_sys_sprintf(char *, const char *, ...);
+int _thread_sys_sscanf(const char *, const char *, ...);
+int _thread_sys_ungetc(int, FILE *);
+int _thread_sys_vfprintf(FILE *, const char *, _BSD_VA_LIST_);
+int _thread_sys_vprintf(const char *, _BSD_VA_LIST_);
+int _thread_sys_vscanf(const char *, _BSD_VA_LIST_);
+int _thread_sys_vsnprintf(char *, size_t, const char *, _BSD_VA_LIST_);
+int _thread_sys_vsprintf(char *, const char *, _BSD_VA_LIST_);
+int _thread_sys_vsscanf(const char *, const char *, _BSD_VA_LIST_);
+long _thread_sys_ftell(FILE *);
+size_t _thread_sys_fread(void *, size_t, size_t, FILE *);
+size_t _thread_sys_fwrite(const void *, size_t, size_t, FILE *);
+void _thread_sys_clearerr(FILE *);
+void _thread_sys_perror(const char *);
+void _thread_sys_rewind(FILE *);
+void _thread_sys_setbuf(FILE *, char *);
+void _thread_sys_setbuffer(FILE *, char *, int);
+#endif
+
+/* #include <unistd.h> */
+#ifdef _UNISTD_H_
+char *_thread_sys_ttyname(int);
+int _thread_sys_close(int);
+int _thread_sys_dup(int);
+int _thread_sys_dup2(int, int);
+int _thread_sys_exect(const char *, char * const *, char * const *);
+int _thread_sys_execve(const char *, char * const *, char * const *);
+int _thread_sys_fchdir(int);
+int _thread_sys_fchown(int, uid_t, gid_t);
+int _thread_sys_fsync(int);
+int _thread_sys_ftruncate(int, off_t);
+int _thread_sys_pause(void);
+int _thread_sys_pipe(int *);
+int _thread_sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+off_t _thread_sys_lseek(int, off_t, int);
+pid_t _thread_sys_fork(void);
+pid_t _thread_sys_tcgetpgrp(int);
+ssize_t _thread_sys_read(int, void *, size_t);
+ssize_t _thread_sys_write(int, const void *, size_t);
+void _thread_sys__exit(int);
+#endif
+
+/* #include <fcntl.h> */
+#ifdef _SYS_FCNTL_H_
+int _thread_sys_creat(const char *, mode_t);
+int _thread_sys_fcntl(int, int, ...);
+int _thread_sys_flock(int, int);
+int _thread_sys_open(const char *, int, ...);
+#endif
+
+/* #include <sys/ioctl.h> */
+#ifdef _SYS_IOCTL_H_
+int _thread_sys_ioctl(int, unsigned long, ...);
+#endif
+
+/* #include <dirent.h> */
+#ifdef _DIRENT_H_
+DIR *___thread_sys_opendir2(const char *, int);
+DIR *_thread_sys_opendir(const char *);
+int _thread_sys_alphasort(const void *, const void *);
+int _thread_sys_scandir(const char *, struct dirent ***,
+ int (*)(struct dirent *), int (*)(const void *, const void *));
+int _thread_sys_closedir(DIR *);
+int _thread_sys_getdirentries(int, char *, int, long *);
+long _thread_sys_telldir(const DIR *);
+struct dirent *_thread_sys_readdir(DIR *);
+void _thread_sys_rewinddir(DIR *);
+void _thread_sys_seekdir(DIR *, long);
+#endif
+
+/* #include <sys/uio.h> */
+#ifdef _SYS_UIO_H_
+ssize_t _thread_sys_readv(int, const struct iovec *, int);
+ssize_t _thread_sys_writev(int, const struct iovec *, int);
+#endif
+
+/* #include <sys/wait.h> */
+#ifdef WNOHANG
+pid_t _thread_sys_wait(int *);
+pid_t _thread_sys_waitpid(pid_t, int *, int);
+pid_t _thread_sys_wait3(int *, int, struct rusage *);
+pid_t _thread_sys_wait4(pid_t, int *, int, struct rusage *);
+#endif
+
+/* #include <poll.h> */
+#ifdef _SYS_POLL_H_
+int _thread_sys_poll(struct pollfd *, unsigned, int);
+#endif
+/* #include <sys/mman.h> */
+int _thread_sys_msync(void *, size_t, int);
+__END_DECLS
+
+#endif /* !_PTHREAD_PRIVATE_H */
diff --git a/lib/libpthread/thread/thr_read.c b/lib/libpthread/thread/thr_read.c
new file mode 100644
index 0000000..8cbb5be
--- /dev/null
+++ b/lib/libpthread/thread/thr_read.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+read(int fd, void *buf, size_t nbytes)
+{
+ int ret;
+ int type;
+
+ _thread_enter_cancellation_point();
+
+ /* POSIX says to do just this: */
+ if (nbytes == 0) {
+ _thread_leave_cancellation_point();
+ return (0);
+ }
+
+ /* Lock the file descriptor for read: */
+ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ /* Get the read/write mode type: */
+ type = _thread_fd_table[fd]->flags & O_ACCMODE;
+
+ /* Check if the file is not open for read: */
+ if (type != O_RDONLY && type != O_RDWR) {
+ /* File is not open for read: */
+ errno = EBADF;
+ _FD_UNLOCK(fd, FD_READ);
+ _thread_leave_cancellation_point();
+ return (-1);
+ }
+
+ /* Perform a non-blocking read syscall: */
+ while ((ret = _thread_sys_read(fd, buf, nbytes)) < 0) {
+ if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0 &&
+ (errno == EWOULDBLOCK || errno == EAGAIN)) {
+ _thread_run->data.fd.fd = fd;
+ _thread_kern_set_timeout(NULL);
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDR_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ _FD_UNLOCK(fd, FD_READ);
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_readv.c b/lib/libpthread/thread/thr_readv.c
new file mode 100644
index 0000000..a1a862d
--- /dev/null
+++ b/lib/libpthread/thread/thr_readv.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+readv(int fd, const struct iovec * iov, int iovcnt)
+{
+ int ret;
+ int type;
+
+ /* Lock the file descriptor for read: */
+ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+ /* Get the read/write mode type: */
+ type = _thread_fd_table[fd]->flags & O_ACCMODE;
+
+ /* Check if the file is not open for read: */
+ if (type != O_RDONLY && type != O_RDWR) {
+ /* File is not open for read: */
+ errno = EBADF;
+ _FD_UNLOCK(fd, FD_READ);
+ return (-1);
+ }
+
+ /* Perform a non-blocking readv syscall: */
+ while ((ret = _thread_sys_readv(fd, iov, iovcnt)) < 0) {
+ if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0 &&
+ (errno == EWOULDBLOCK || errno == EAGAIN)) {
+ _thread_run->data.fd.fd = fd;
+ _thread_kern_set_timeout(NULL);
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDR_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ _FD_UNLOCK(fd, FD_READ);
+ }
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_resume_np.c b/lib/libpthread/thread/thr_resume_np.c
new file mode 100644
index 0000000..98ec718
--- /dev/null
+++ b/lib/libpthread/thread/thr_resume_np.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Resume a thread: */
+int
+pthread_resume_np(pthread_t thread)
+{
+ int ret;
+
+ /* Find the thread in the list of active threads: */
+ if ((ret = _find_thread(thread)) == 0) {
+ /* The thread exists. Is it suspended? */
+ if (thread->state != PS_SUSPENDED) {
+ /*
+ * Defer signals to protect the scheduling queues
+ * from access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Allow the thread to run. */
+ PTHREAD_NEW_STATE(thread,PS_RUNNING);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_rwlock.c b/lib/libpthread/thread/thr_rwlock.c
new file mode 100644
index 0000000..648e8a3
--- /dev/null
+++ b/lib/libpthread/thread/thr_rwlock.c
@@ -0,0 +1,335 @@
+/*-
+ * Copyright (c) 1998 Alex Nash
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifdef _THREAD_SAFE
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* maximum number of times a read lock may be obtained */
+#define MAX_READ_LOCKS (INT_MAX - 1)
+
+static int init_static (pthread_rwlock_t *rwlock);
+
+static spinlock_t static_init_lock = _SPINLOCK_INITIALIZER;
+
+static int
+init_static (pthread_rwlock_t *rwlock)
+{
+ int ret;
+
+ _SPINLOCK(&static_init_lock);
+
+ if (*rwlock == NULL)
+ ret = pthread_rwlock_init(rwlock, NULL);
+ else
+ ret = 0;
+
+ _SPINUNLOCK(&static_init_lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
+{
+ int ret;
+
+ if (rwlock == NULL)
+ ret = EINVAL;
+ else {
+ pthread_rwlock_t prwlock;
+
+ prwlock = *rwlock;
+
+ pthread_mutex_destroy(&prwlock->lock);
+ pthread_cond_destroy(&prwlock->read_signal);
+ pthread_cond_destroy(&prwlock->write_signal);
+ free(prwlock);
+
+ *rwlock = NULL;
+
+ ret = 0;
+ }
+
+ return(ret);
+}
+
+int
+pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ /* allocate rwlock object */
+ prwlock = (pthread_rwlock_t)malloc(sizeof(struct pthread_rwlock));
+
+ if (prwlock == NULL)
+ return(ENOMEM);
+
+ /* initialize the lock */
+ if ((ret = pthread_mutex_init(&prwlock->lock, NULL)) != 0)
+ free(prwlock);
+ else {
+ /* initialize the read condition signal */
+ ret = pthread_cond_init(&prwlock->read_signal, NULL);
+
+ if (ret != 0) {
+ pthread_mutex_destroy(&prwlock->lock);
+ free(prwlock);
+ } else {
+ /* initialize the write condition signal */
+ ret = pthread_cond_init(&prwlock->write_signal, NULL);
+
+ if (ret != 0) {
+ pthread_cond_destroy(&prwlock->read_signal);
+ pthread_mutex_destroy(&prwlock->lock);
+ free(prwlock);
+ } else {
+ /* success */
+ prwlock->state = 0;
+ prwlock->blocked_writers = 0;
+
+ *rwlock = prwlock;
+ }
+ }
+ }
+
+ return(ret);
+}
+
+int
+pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ /* give writers priority over readers */
+ while (prwlock->blocked_writers || prwlock->state < 0) {
+ ret = pthread_cond_wait(&prwlock->read_signal, &prwlock->lock);
+
+ if (ret != 0) {
+ /* can't do a whole lot if this fails */
+ pthread_mutex_unlock(&prwlock->lock);
+ return(ret);
+ }
+ }
+
+ /* check lock count */
+ if (prwlock->state == MAX_READ_LOCKS)
+ ret = EAGAIN;
+ else
+ ++prwlock->state; /* indicate we are locked for reading */
+
+ /*
+ * Something is really wrong if this call fails. Returning
+ * error won't do because we've already obtained the read
+ * lock. Decrementing 'state' is no good because we probably
+ * don't have the monitor lock.
+ */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ /* give writers priority over readers */
+ if (prwlock->blocked_writers || prwlock->state < 0)
+ ret = EWOULDBLOCK;
+ else if (prwlock->state == MAX_READ_LOCKS)
+ ret = EAGAIN; /* too many read locks acquired */
+ else
+ ++prwlock->state; /* indicate we are locked for reading */
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ if (prwlock->state != 0)
+ ret = EWOULDBLOCK;
+ else
+ /* indicate we are locked for writing */
+ prwlock->state = -1;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ if (prwlock == NULL)
+ return(EINVAL);
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ if (prwlock->state > 0) {
+ if (--prwlock->state == 0 && prwlock->blocked_writers)
+ ret = pthread_cond_signal(&prwlock->write_signal);
+ } else if (prwlock->state < 0) {
+ prwlock->state = 0;
+
+ if (prwlock->blocked_writers)
+ ret = pthread_cond_signal(&prwlock->write_signal);
+ else
+ ret = pthread_cond_broadcast(&prwlock->read_signal);
+ } else
+ ret = EINVAL;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ while (prwlock->state != 0) {
+ ++prwlock->blocked_writers;
+
+ ret = pthread_cond_wait(&prwlock->write_signal, &prwlock->lock);
+
+ if (ret != 0) {
+ --prwlock->blocked_writers;
+ pthread_mutex_unlock(&prwlock->lock);
+ return(ret);
+ }
+
+ --prwlock->blocked_writers;
+ }
+
+ /* indicate we are locked for writing */
+ prwlock->state = -1;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+#endif /* _THREAD_SAFE */
diff --git a/lib/libpthread/thread/thr_rwlockattr.c b/lib/libpthread/thread/thr_rwlockattr.c
new file mode 100644
index 0000000..7a56bca
--- /dev/null
+++ b/lib/libpthread/thread/thr_rwlockattr.c
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 1998 Alex Nash
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifdef _THREAD_SAFE
+#include <errno.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr)
+{
+ pthread_rwlockattr_t prwlockattr;
+
+ if (rwlockattr == NULL)
+ return(EINVAL);
+
+ prwlockattr = *rwlockattr;
+
+ if (prwlockattr == NULL)
+ return(EINVAL);
+
+ free(prwlockattr);
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *rwlockattr,
+ int *pshared)
+{
+ *pshared = (*rwlockattr)->pshared;
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr)
+{
+ pthread_rwlockattr_t prwlockattr;
+
+ if (rwlockattr == NULL)
+ return(EINVAL);
+
+ prwlockattr = (pthread_rwlockattr_t)
+ malloc(sizeof(struct pthread_rwlockattr));
+
+ if (prwlockattr == NULL)
+ return(ENOMEM);
+
+ prwlockattr->pshared = PTHREAD_PROCESS_PRIVATE;
+ *rwlockattr = prwlockattr;
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_setpshared (pthread_rwlockattr_t *rwlockattr, int pshared)
+{
+ /* Only PTHREAD_PROCESS_PRIVATE is supported. */
+ if (pshared != PTHREAD_PROCESS_PRIVATE)
+ return(EINVAL);
+
+ (*rwlockattr)->pshared = pshared;
+
+ return(0);
+}
+
+#endif /* _THREAD_SAFE */
diff --git a/lib/libpthread/thread/thr_select.c b/lib/libpthread/thread/thr_select.c
new file mode 100644
index 0000000..9bfae89
--- /dev/null
+++ b/lib/libpthread/thread/thr_select.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <unistd.h>
+#include <errno.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+select(int numfds, fd_set * readfds, fd_set * writefds,
+ fd_set * exceptfds, struct timeval * timeout)
+{
+ struct timespec ts;
+ int i, ret = 0, f_wait = 1;
+ int pfd_index, got_one = 0, fd_count = 0;
+ struct pthread_poll_data data;
+
+ if (numfds > _thread_dtablesize) {
+ numfds = _thread_dtablesize;
+ }
+ /* Check if a timeout was specified: */
+ if (timeout) {
+ if (timeout->tv_sec < 0 ||
+ timeout->tv_usec < 0 || timeout->tv_usec >= 1000000) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /* Convert the timeval to a timespec: */
+ TIMEVAL_TO_TIMESPEC(timeout, &ts);
+
+ /* Set the wake up time: */
+ _thread_kern_set_timeout(&ts);
+ if (ts.tv_sec == 0 && ts.tv_nsec == 0)
+ f_wait = 0;
+ } else {
+ /* Wait for ever: */
+ _thread_kern_set_timeout(NULL);
+ }
+
+ /* Count the number of file descriptors to be polled: */
+ if (readfds || writefds || exceptfds) {
+ for (i = 0; i < numfds; i++) {
+ if ((readfds && FD_ISSET(i, readfds)) ||
+ (exceptfds && FD_ISSET(i, exceptfds)) ||
+ (writefds && FD_ISSET(i, writefds))) {
+ fd_count++;
+ }
+ }
+ }
+
+ /*
+ * Allocate memory for poll data if it hasn't already been
+ * allocated or if previously allocated memory is insufficient.
+ */
+ if ((_thread_run->poll_data.fds == NULL) ||
+ (_thread_run->poll_data.nfds < fd_count)) {
+ data.fds = (struct pollfd *) realloc(_thread_run->poll_data.fds,
+ sizeof(struct pollfd) * MAX(128, fd_count));
+ if (data.fds == NULL) {
+ errno = ENOMEM;
+ ret = -1;
+ }
+ else {
+ /*
+ * Note that the threads poll data always
+ * indicates what is allocated, not what is
+ * currently being polled.
+ */
+ _thread_run->poll_data.fds = data.fds;
+ _thread_run->poll_data.nfds = MAX(128, fd_count);
+ }
+ }
+ if (ret == 0) {
+ /* Setup the wait data. */
+ data.fds = _thread_run->poll_data.fds;
+ data.nfds = fd_count;
+
+ /*
+ * Setup the array of pollfds. Optimize this by
+ * running the loop in reverse and stopping when
+ * the number of selected file descriptors is reached.
+ */
+ for (i = numfds - 1, pfd_index = fd_count - 1;
+ (i >= 0) && (pfd_index >= 0); i--) {
+ data.fds[pfd_index].events = 0;
+ if (readfds && FD_ISSET(i, readfds)) {
+ data.fds[pfd_index].events = POLLRDNORM;
+ }
+ if (exceptfds && FD_ISSET(i, exceptfds)) {
+ data.fds[pfd_index].events |= POLLRDBAND;
+ }
+ if (writefds && FD_ISSET(i, writefds)) {
+ data.fds[pfd_index].events |= POLLWRNORM;
+ }
+ if (data.fds[pfd_index].events != 0) {
+ /*
+ * Set the file descriptor to be polled and
+ * clear revents in case of a timeout which
+ * leaves fds unchanged:
+ */
+ data.fds[pfd_index].fd = i;
+ data.fds[pfd_index].revents = 0;
+ pfd_index--;
+ }
+ }
+ if (((ret = _thread_sys_poll(data.fds, data.nfds, 0)) == 0) &&
+ (f_wait != 0)) {
+ _thread_run->data.poll_data = &data;
+ _thread_run->interrupted = 0;
+ _thread_kern_sched_state(PS_SELECT_WAIT, __FILE__, __LINE__);
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ data.nfds = 0;
+ ret = -1;
+ } else
+ ret = data.nfds;
+ }
+ }
+
+ if (ret >= 0) {
+ numfds = 0;
+ for (i = 0; i < fd_count; i++) {
+ /*
+ * Check the results of the poll and clear
+ * this file descriptor from the fdset if
+ * the requested event wasn't ready.
+ */
+ got_one = 0;
+ if (readfds != NULL) {
+ if (FD_ISSET(data.fds[i].fd, readfds)) {
+ if (data.fds[i].revents & (POLLIN |
+ POLLRDNORM))
+ got_one = 1;
+ else
+ FD_CLR(data.fds[i].fd, readfds);
+ }
+ }
+ if (writefds != NULL) {
+ if (FD_ISSET(data.fds[i].fd, writefds)) {
+ if (data.fds[i].revents & (POLLOUT |
+ POLLWRNORM | POLLWRBAND))
+ got_one = 1;
+ else
+ FD_CLR(data.fds[i].fd,
+ writefds);
+ }
+ }
+ if (exceptfds != NULL) {
+ if (FD_ISSET(data.fds[i].fd, exceptfds)) {
+ if (data.fds[i].revents & (POLLRDBAND |
+ POLLPRI | POLLHUP | POLLERR |
+ POLLNVAL))
+ got_one = 1;
+ else
+ FD_CLR(data.fds[i].fd,
+ exceptfds);
+ }
+ }
+ if (got_one)
+ numfds++;
+ }
+ ret = numfds;
+ }
+
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_self.c b/lib/libpthread/thread/thr_self.c
new file mode 100644
index 0000000..81ec427
--- /dev/null
+++ b/lib/libpthread/thread/thr_self.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+pthread_t
+pthread_self(void)
+{
+ /* Return the running thread pointer: */
+ return (_thread_run);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_seterrno.c b/lib/libpthread/thread/thr_seterrno.c
new file mode 100644
index 0000000..1934aac
--- /dev/null
+++ b/lib/libpthread/thread/thr_seterrno.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/*
+ * This function needs to reference the global error variable which is
+ * normally hidden from the user.
+ */
+#ifdef errno
+#undef errno;
+#endif
+extern int errno;
+
+void
+_thread_seterrno(pthread_t thread, int error)
+{
+ /* Check for the initial thread: */
+ if (thread == _thread_initial)
+ /* The initial thread always uses the global error variable: */
+ errno = error;
+ else
+ /*
+ * Threads other than the initial thread always use the error
+ * field in the thread structureL
+ */
+ thread->error = error;
+}
+#endif
diff --git a/lib/libpthread/thread/thr_setprio.c b/lib/libpthread/thread/thr_setprio.c
new file mode 100644
index 0000000..5f7b44a
--- /dev/null
+++ b/lib/libpthread/thread/thr_setprio.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_setprio(pthread_t pthread, int prio)
+{
+ int ret, policy;
+ struct sched_param param;
+
+ if ((ret = pthread_getschedparam(pthread, &policy, &param)) == 0) {
+ param.sched_priority = prio;
+ ret = pthread_setschedparam(pthread, policy, &param);
+ }
+
+ /* Return the error status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_setschedparam.c b/lib/libpthread/thread/thr_setschedparam.c
new file mode 100644
index 0000000..57e24e8
--- /dev/null
+++ b/lib/libpthread/thread/thr_setschedparam.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <sys/param.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_setschedparam(pthread_t pthread, int policy,
+ const struct sched_param *param)
+{
+ int old_prio, in_readyq = 0, ret = 0;
+
+ if ((param == NULL) || (param->sched_priority < PTHREAD_MIN_PRIORITY) ||
+ (param->sched_priority > PTHREAD_MAX_PRIORITY) ||
+ (policy < SCHED_FIFO) || (policy > SCHED_RR))
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+
+ /* Find the thread in the list of active threads: */
+ else if ((ret = _find_thread(pthread)) == 0) {
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ if (param->sched_priority != pthread->base_priority) {
+ /*
+ * Remove the thread from its current priority
+ * queue before any adjustments are made to its
+ * active priority:
+ */
+ if ((pthread->flags & PTHREAD_FLAGS_IN_PRIOQ) != 0) {
+ in_readyq = 1;
+ old_prio = pthread->active_priority;
+ PTHREAD_PRIOQ_REMOVE(pthread);
+ }
+
+ /* Set the thread base priority: */
+ pthread->base_priority = param->sched_priority;
+
+ /* Recalculate the active priority: */
+ pthread->active_priority = MAX(pthread->base_priority,
+ pthread->inherited_priority);
+
+ if (in_readyq) {
+ if ((pthread->priority_mutex_count > 0) &&
+ (old_prio > pthread->active_priority)) {
+ /*
+ * POSIX states that if the priority is
+ * being lowered, the thread must be
+ * inserted at the head of the queue for
+ * its priority if it owns any priority
+ * protection or inheritence mutexes.
+ */
+ PTHREAD_PRIOQ_INSERT_HEAD(pthread);
+ }
+ else
+ PTHREAD_PRIOQ_INSERT_TAIL(pthread);
+ }
+
+ /*
+ * Check for any mutex priority adjustments. This
+ * includes checking for a priority mutex on which
+ * this thread is waiting.
+ */
+ _mutex_notify_priochange(pthread);
+ }
+
+ /* Set the scheduling policy: */
+ pthread->attr.sched_policy = policy;
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_sig.c b/lib/libpthread/thread/thr_sig.c
new file mode 100644
index 0000000..b744659
--- /dev/null
+++ b/lib/libpthread/thread/thr_sig.c
@@ -0,0 +1,584 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Prototypes: */
+static void _thread_sig_check_state(pthread_t pthread, int sig);
+
+/* Static variables: */
+static spinlock_t signal_lock = _SPINLOCK_INITIALIZER;
+static unsigned int pending_sigs[NSIG];
+static unsigned int handled_sigs[NSIG];
+static int volatile check_pending = 0;
+
+/* Initialize signal handling facility: */
+void
+_thread_sig_init(void)
+{
+ int i;
+
+ /* Clear pending and handled signal counts: */
+ for (i = 1; i < NSIG; i++) {
+ pending_sigs[i - 1] = 0;
+ handled_sigs[i - 1] = 0;
+ }
+
+ /* Clear the lock: */
+ signal_lock.access_lock = 0;
+
+ /* Clear the process pending signals: */
+ sigemptyset(&_process_sigpending);
+}
+
+void
+_thread_sig_handler(int sig, int code, ucontext_t * scp)
+{
+ pthread_t pthread;
+ int i;
+ char c;
+
+ /* Check if an interval timer signal: */
+ if (sig == _SCHED_SIGNAL) {
+ if (_thread_kern_in_sched != 0) {
+ /*
+ * The scheduler is already running; ignore this
+ * signal.
+ */
+ }
+ /*
+ * Check if the scheduler interrupt has come when
+ * the currently running thread has deferred thread
+ * signals.
+ */
+ else if (_thread_run->sig_defer_count > 0)
+ _thread_run->yield_on_sig_undefer = 1;
+
+ else {
+ /*
+ * Schedule the next thread. This function is not
+ * expected to return because it will do a longjmp
+ * instead.
+ */
+ _thread_kern_sched(scp);
+
+ /*
+ * This point should not be reached, so abort the
+ * process:
+ */
+ PANIC("Returned to signal function from scheduler");
+ }
+ }
+ /*
+ * Check if the kernel has been interrupted while the scheduler
+ * is accessing the scheduling queues or if there is a currently
+ * running thread that has deferred signals.
+ */
+ else if ((_queue_signals != 0) || ((_thread_kern_in_sched == 0) &&
+ (_thread_run->sig_defer_count > 0))) {
+ /* Cast the signal number to a character variable: */
+ c = sig;
+
+ /*
+ * Write the signal number to the kernel pipe so that it will
+ * be ready to read when this signal handler returns.
+ */
+ _thread_sys_write(_thread_kern_pipe[1], &c, 1);
+
+ /* Indicate that there are queued signals in the pipe. */
+ _sigq_check_reqd = 1;
+ }
+ else {
+ if (_atomic_lock(&signal_lock.access_lock)) {
+ /* There is another signal handler running: */
+ pending_sigs[sig - 1]++;
+ check_pending = 1;
+ }
+ else {
+ /* It's safe to handle the signal now. */
+ pthread = _thread_sig_handle(sig, scp);
+
+ /* Reset the pending and handled count back to 0: */
+ pending_sigs[sig - 1] = 0;
+ handled_sigs[sig - 1] = 0;
+
+ if (pthread == NULL)
+ signal_lock.access_lock = 0;
+ else {
+ sigaddset(&pthread->sigmask, sig);
+ signal_lock.access_lock = 0;
+ _thread_sig_deliver(pthread, sig);
+ sigdelset(&pthread->sigmask, sig);
+ }
+ }
+
+ /* Enter a loop to process pending signals: */
+ while ((check_pending != 0) &&
+ (_atomic_lock(&signal_lock.access_lock) == 0)) {
+ check_pending = 0;
+ for (i = 1; i < NSIG; i++) {
+ if (pending_sigs[i - 1] > handled_sigs[i - 1]) {
+ pending_sigs[i - 1] = handled_sigs[i - 1];
+ pthread = _thread_sig_handle(i, scp);
+ if (pthread != NULL) {
+ sigaddset(&pthread->sigmask, i);
+ signal_lock.access_lock = 0;
+ _thread_sig_deliver(pthread, i);
+ sigdelset(&pthread->sigmask, i);
+ if (_atomic_lock(&signal_lock.access_lock)) {
+ check_pending = 1;
+ return;
+ }
+ }
+ }
+ }
+ signal_lock.access_lock = 0;
+ }
+ }
+}
+
+pthread_t
+_thread_sig_handle(int sig, ucontext_t * scp)
+{
+ int i;
+ pthread_t pthread, pthread_next;
+ pthread_t suspended_thread, signaled_thread;
+
+ /* Check if the signal requires a dump of thread information: */
+ if (sig == SIGINFO)
+ /* Dump thread information to file: */
+ _thread_dump_info();
+
+ /* Check if an interval timer signal: */
+ else if (sig == _SCHED_SIGNAL) {
+ /*
+ * This shouldn't ever occur (should this panic?).
+ */
+ } else {
+ /* Check if a child has terminated: */
+ if (sig == SIGCHLD) {
+ /*
+ * Go through the file list and set all files
+ * to non-blocking again in case the child
+ * set some of them to block. Sigh.
+ */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /* Check if this file is used: */
+ if (_thread_fd_table[i] != NULL) {
+ /*
+ * Set the file descriptor to
+ * non-blocking:
+ */
+ _thread_sys_fcntl(i, F_SETFL,
+ _thread_fd_table[i]->flags |
+ O_NONBLOCK);
+ }
+ }
+ /*
+ * Enter a loop to wake up all threads waiting
+ * for a process to complete:
+ */
+ for (pthread = TAILQ_FIRST(&_waitingq);
+ pthread != NULL; pthread = pthread_next) {
+ /*
+ * Grab the next thread before possibly
+ * destroying the link entry:
+ */
+ pthread_next = TAILQ_NEXT(pthread, pqe);
+
+ /*
+ * If this thread is waiting for a child
+ * process to complete, wake it up:
+ */
+ if (pthread->state == PS_WAIT_WAIT) {
+ /* Make the thread runnable: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ }
+ }
+ }
+
+ /*
+ * POSIX says that pending SIGCONT signals are
+ * discarded when one of these signals occurs.
+ */
+ if (sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU) {
+ /*
+ * Enter a loop to discard pending SIGCONT
+ * signals:
+ */
+ TAILQ_FOREACH(pthread, &_thread_list, tle) {
+ sigdelset(&pthread->sigpend,SIGCONT);
+ }
+ }
+
+ /*
+ * Enter a loop to look for threads that have the
+ * signal unmasked. POSIX specifies that a thread
+ * in a sigwait will get the signal over any other
+ * threads. Second preference will be threads in
+ * in a sigsuspend. If none of the above, then the
+ * signal is delivered to the first thread we find.
+ */
+ suspended_thread = NULL;
+ signaled_thread = NULL;
+ for (pthread = TAILQ_FIRST(&_waitingq);
+ pthread != NULL; pthread = pthread_next) {
+ /*
+ * Grab the next thread before possibly destroying
+ * the link entry.
+ */
+ pthread_next = TAILQ_NEXT(pthread, pqe);
+
+ if ((pthread->state == PS_SIGWAIT) &&
+ sigismember(pthread->data.sigwait, sig)) {
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+
+ /*
+ * POSIX doesn't doesn't specify which thread
+ * will get the signal if there are multiple
+ * waiters, so we give it to the first thread
+ * we find.
+ *
+ * Do not attempt to deliver this signal
+ * to other threads.
+ */
+ return (NULL);
+ }
+ else if (!sigismember(&pthread->sigmask, sig)) {
+ if (pthread->state == PS_SIGSUSPEND) {
+ if (suspended_thread == NULL)
+ suspended_thread = pthread;
+ } else if (signaled_thread == NULL)
+ signaled_thread = pthread;
+ }
+ }
+
+ /*
+ * If we didn't find a thread in the waiting queue,
+ * check the all threads queue:
+ */
+ if (suspended_thread == NULL && signaled_thread == NULL) {
+ /*
+ * Enter a loop to look for other threads capable
+ * of receiving the signal:
+ */
+ TAILQ_FOREACH(pthread, &_thread_list, tle) {
+ if (!sigismember(&pthread->sigmask, sig)) {
+ signaled_thread = pthread;
+ break;
+ }
+ }
+ }
+
+ /* Check if the signal is not being ignored: */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) {
+ if (suspended_thread == NULL &&
+ signaled_thread == NULL)
+ /*
+ * Add it to the set of signals pending
+ * on the process:
+ */
+ sigaddset(&_process_sigpending, sig);
+ else {
+ /*
+ * We only deliver the signal to one thread;
+ * give preference to the suspended thread:
+ */
+ if (suspended_thread != NULL)
+ pthread = suspended_thread;
+ else
+ pthread = signaled_thread;
+
+ /*
+ * Perform any state changes due to signal
+ * arrival:
+ */
+ _thread_sig_check_state(pthread, sig);
+ return (pthread);
+ }
+ }
+ }
+
+ /* Returns nothing. */
+ return (NULL);
+}
+
+/* Perform thread specific actions in response to a signal: */
+static void
+_thread_sig_check_state(pthread_t pthread, int sig)
+{
+ /*
+ * Process according to thread state:
+ */
+ switch (pthread->state) {
+ /*
+ * States which do not change when a signal is trapped:
+ */
+ case PS_COND_WAIT:
+ case PS_DEAD:
+ case PS_DEADLOCK:
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ case PS_JOIN:
+ case PS_MUTEX_WAIT:
+ case PS_RUNNING:
+ case PS_STATE_MAX:
+ case PS_SIGTHREAD:
+ case PS_SPINBLOCK:
+ case PS_SUSPENDED:
+ /* Increment the pending signal count. */
+ sigaddset(&pthread->sigpend,sig);
+ break;
+
+ case PS_SIGWAIT:
+ /* Wake up the thread if the signal is blocked. */
+ if (sigismember(pthread->data.sigwait, sig)) {
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ } else
+ /* Increment the pending signal count. */
+ sigaddset(&pthread->sigpend,sig);
+ break;
+
+
+ /*
+ * The wait state is a special case due to the handling of
+ * SIGCHLD signals.
+ */
+ case PS_WAIT_WAIT:
+ /*
+ * Check for signals other than the death of a child
+ * process:
+ */
+ if (sig != SIGCHLD)
+ /* Flag the operation as interrupted: */
+ pthread->interrupted = 1;
+
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ break;
+
+ /*
+ * States that are interrupted by the occurrence of a signal
+ * other than the scheduling alarm:
+ */
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ case PS_POLL_WAIT:
+ case PS_SLEEP_WAIT:
+ case PS_SELECT_WAIT:
+ if ((_thread_sigact[sig - 1].sa_flags & SA_RESTART) == 0) {
+ /* Flag the operation as interrupted: */
+ pthread->interrupted = 1;
+
+ if (pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ PTHREAD_WORKQ_REMOVE(pthread);
+
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ }
+ break;
+
+ case PS_SIGSUSPEND:
+ /*
+ * Only wake up the thread if there is a handler installed
+ * for the signal.
+ */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_DFL) {
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ }
+ break;
+ }
+}
+
+/* Send a signal to a specific thread (ala pthread_kill): */
+void
+_thread_sig_send(pthread_t pthread, int sig)
+{
+ /*
+ * Check that the signal is not being ignored:
+ */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) {
+ if (pthread->state == PS_SIGWAIT &&
+ sigismember(pthread->data.sigwait, sig)) {
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ } else if (pthread->state != PS_SIGWAIT &&
+ !sigismember(&pthread->sigmask, sig)) {
+ /* Perform any state changes due to signal arrival: */
+ _thread_sig_check_state(pthread, sig);
+
+ /* Call the installed signal handler: */
+ _thread_sig_deliver(pthread, sig);
+ }
+ else {
+ /* Increment the pending signal count. */
+ sigaddset(&pthread->sigpend,sig);
+ }
+ }
+}
+
+/* Dispatch pending signals to the running thread: */
+void
+_dispatch_signals()
+{
+ sigset_t sigset, mask;
+ int i;
+
+ /*
+ * Check if there are pending signals for the running
+ * thread or process that aren't blocked:
+ */
+ sigset = _thread_run->sigpend;
+ SIGSETOR(sigset, _process_sigpending);
+ SIGSETNAND(sigset, _thread_run->sigmask);
+ if (SIGNOTEMPTY(sigset)) {
+ /*
+ * Enter a loop to calculate deliverable pending signals
+ * before actually delivering them. The pending signals
+ * must be removed from the pending signal sets before
+ * calling the signal handler because the handler may
+ * call library routines that again check for and deliver
+ * pending signals.
+ */
+ for (i = 1; i < NSIG; i++) {
+ /*
+ * Check that a custom handler is installed
+ * and if the signal is not blocked:
+ */
+ if (_thread_sigact[i - 1].sa_handler != SIG_DFL &&
+ _thread_sigact[i - 1].sa_handler != SIG_IGN &&
+ sigismember(&sigset, i)) {
+ if (sigismember(&_thread_run->sigpend,i))
+ /* Clear the thread pending signal: */
+ sigdelset(&_thread_run->sigpend,i);
+ else
+ /* Clear the process pending signal: */
+ sigdelset(&_process_sigpending,i);
+ }
+ else
+ /* Remove the signal if it can't be handled: */
+ sigdelset(&sigset, i);
+ }
+
+ /* Now deliver the signals: */
+ for (i = 1; i < NSIG; i++) {
+ if (sigismember(&sigset, i))
+ /* Deliver the signal to the running thread: */
+ _thread_sig_deliver(_thread_run, i);
+ }
+ }
+}
+
+/* Deliver a signal to a thread: */
+void
+_thread_sig_deliver(pthread_t pthread, int sig)
+{
+ sigset_t mask;
+ pthread_t pthread_saved;
+
+ /*
+ * Check that a custom handler is installed
+ * and if the signal is not blocked:
+ */
+ if (_thread_sigact[sig - 1].sa_handler != SIG_DFL &&
+ _thread_sigact[sig - 1].sa_handler != SIG_IGN) {
+ /* Save the current thread: */
+ pthread_saved = _thread_run;
+
+ /* Save the threads signal mask: */
+ mask = pthread->sigmask;
+
+ /*
+ * Add the current signal and signal handler
+ * mask to the threads current signal mask:
+ */
+ SIGSETOR(pthread->sigmask, _thread_sigact[sig - 1].sa_mask);
+ sigaddset(&pthread->sigmask, sig);
+
+ /* Current thread inside critical region? */
+ if (_thread_run->sig_defer_count > 0)
+ pthread->sig_defer_count++;
+
+ _thread_run = pthread;
+
+ /*
+ * Dispatch the signal via the custom signal
+ * handler:
+ */
+ (*(_thread_sigact[sig - 1].sa_handler))(sig);
+
+ _thread_run = pthread_saved;
+
+ /* Current thread inside critical region? */
+ if (_thread_run->sig_defer_count > 0)
+ pthread->sig_defer_count--;
+
+ /* Restore the threads signal mask: */
+ pthread->sigmask = mask;
+ }
+}
+#endif
diff --git a/lib/libpthread/thread/thr_sigaction.c b/lib/libpthread/thread/thr_sigaction.c
new file mode 100644
index 0000000..7fa8ebf
--- /dev/null
+++ b/lib/libpthread/thread/thr_sigaction.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigaction(int sig, const struct sigaction * act, struct sigaction * oact)
+{
+ int ret = 0;
+ struct sigaction gact;
+
+ /* Check if the signal number is out of range: */
+ if (sig < 1 || sig > NSIG) {
+ /* Return an invalid argument: */
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ /*
+ * Check if the existing signal action structure contents are
+ * to be returned:
+ */
+ if (oact != NULL) {
+ /* Return the existing signal action contents: */
+ oact->sa_handler = _thread_sigact[sig - 1].sa_handler;
+ oact->sa_mask = _thread_sigact[sig - 1].sa_mask;
+ oact->sa_flags = _thread_sigact[sig - 1].sa_flags;
+ }
+
+ /* Check if a signal action was supplied: */
+ if (act != NULL) {
+ /* Set the new signal handler: */
+ _thread_sigact[sig - 1].sa_mask = act->sa_mask;
+ _thread_sigact[sig - 1].sa_flags = act->sa_flags;
+ _thread_sigact[sig - 1].sa_handler = act->sa_handler;
+ }
+
+ /*
+ * Check if the kernel needs to be advised of a change
+ * in signal action:
+ */
+ if (act != NULL && sig != _SCHED_SIGNAL && sig != SIGCHLD &&
+ sig != SIGINFO) {
+ /* Initialise the global signal action structure: */
+ gact.sa_mask = act->sa_mask;
+ gact.sa_flags = 0;
+
+ /* Ensure the scheduling signal is masked: */
+ sigaddset(&gact.sa_mask, _SCHED_SIGNAL);
+
+ /*
+ * Check if the signal handler is being set to
+ * the default or ignore handlers:
+ */
+ if (act->sa_handler == SIG_DFL ||
+ act->sa_handler == SIG_IGN)
+ /* Specify the built in handler: */
+ gact.sa_handler = act->sa_handler;
+ else
+ /*
+ * Specify the thread kernel signal
+ * handler:
+ */
+ gact.sa_handler = (void (*) ()) _thread_sig_handler;
+
+ /* Change the signal action in the kernel: */
+ if (_thread_sys_sigaction(sig,&gact,NULL) != 0)
+ ret = -1;
+ }
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_sigmask.c b/lib/libpthread/thread/thr_sigmask.c
new file mode 100644
index 0000000..b880d9c
--- /dev/null
+++ b/lib/libpthread/thread/thr_sigmask.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <errno.h>
+#include <signal.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
+{
+ int ret = 0;
+
+ /* Check if the existing signal process mask is to be returned: */
+ if (oset != NULL) {
+ /* Return the current mask: */
+ *oset = _thread_run->sigmask;
+ }
+ /* Check if a new signal set was provided by the caller: */
+ if (set != NULL) {
+ /* Process according to what to do: */
+ switch (how) {
+ /* Block signals: */
+ case SIG_BLOCK:
+ /* Add signals to the existing mask: */
+ SIGSETOR(_thread_run->sigmask, *set);
+ break;
+
+ /* Unblock signals: */
+ case SIG_UNBLOCK:
+ /* Clear signals from the existing mask: */
+ SIGSETNAND(_thread_run->sigmask, *set);
+ break;
+
+ /* Set the signal process mask: */
+ case SIG_SETMASK:
+ /* Set the new mask: */
+ _thread_run->sigmask = *set;
+ break;
+
+ /* Trap invalid actions: */
+ default:
+ /* Return an invalid argument: */
+ errno = EINVAL;
+ ret = -1;
+ break;
+ }
+
+ /*
+ * Dispatch signals to the running thread that are pending
+ * and now unblocked:
+ */
+ _dispatch_signals();
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_sigpending.c b/lib/libpthread/thread/thr_sigpending.c
new file mode 100644
index 0000000..2d61e21
--- /dev/null
+++ b/lib/libpthread/thread/thr_sigpending.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigpending(sigset_t * set)
+{
+ int ret = 0;
+
+ /* Check for a null signal set pointer: */
+ if (set == NULL) {
+ /* Return an invalid argument: */
+ ret = EINVAL;
+ }
+ else {
+ *set = _thread_run->sigpend;
+ }
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_sigprocmask.c b/lib/libpthread/thread/thr_sigprocmask.c
new file mode 100644
index 0000000..592a61e
--- /dev/null
+++ b/lib/libpthread/thread/thr_sigprocmask.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <signal.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigprocmask(int how, const sigset_t * set, sigset_t * oset)
+{
+ int ret = 0;
+
+ /* Check if the existing signal process mask is to be returned: */
+ if (oset != NULL) {
+ /* Return the current mask: */
+ *oset = _thread_run->sigmask;
+ }
+ /* Check if a new signal set was provided by the caller: */
+ if (set != NULL) {
+ /* Process according to what to do: */
+ switch (how) {
+ /* Block signals: */
+ case SIG_BLOCK:
+ /* Add signals to the existing mask: */
+ SIGSETOR(_thread_run->sigmask, *set);
+ break;
+
+ /* Unblock signals: */
+ case SIG_UNBLOCK:
+ /* Clear signals from the existing mask: */
+ SIGSETNAND(_thread_run->sigmask, *set);
+ break;
+
+ /* Set the signal process mask: */
+ case SIG_SETMASK:
+ /* Set the new mask: */
+ _thread_run->sigmask = *set;
+ break;
+
+ /* Trap invalid actions: */
+ default:
+ /* Return an invalid argument: */
+ errno = EINVAL;
+ ret = -1;
+ break;
+ }
+
+ /*
+ * Dispatch signals to the running thread that are pending
+ * and now unblocked:
+ */
+ _dispatch_signals();
+ }
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_sigsuspend.c b/lib/libpthread/thread/thr_sigsuspend.c
new file mode 100644
index 0000000..ac06ff7
--- /dev/null
+++ b/lib/libpthread/thread/thr_sigsuspend.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigsuspend(const sigset_t * set)
+{
+ int ret = -1;
+ sigset_t oset;
+
+ /* Check if a new signal set was provided by the caller: */
+ if (set != NULL) {
+ /* Save the current signal mask: */
+ oset = _thread_run->sigmask;
+
+ /* Change the caller's mask: */
+ _thread_run->sigmask = *set;
+
+ /* Wait for a signal: */
+ _thread_kern_sched_state(PS_SIGSUSPEND, __FILE__, __LINE__);
+
+ /* Always return an interrupted error: */
+ errno = EINTR;
+
+ /* Restore the signal mask: */
+ _thread_run->sigmask = oset;
+ } else {
+ /* Return an invalid argument error: */
+ errno = EINVAL;
+ }
+
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_sigwait.c b/lib/libpthread/thread/thr_sigwait.c
new file mode 100644
index 0000000..faa227e
--- /dev/null
+++ b/lib/libpthread/thread/thr_sigwait.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <sys/param.h>
+#include <sys/signalvar.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sigwait(const sigset_t * set, int *sig)
+{
+ int ret = 0;
+ int i;
+ sigset_t tempset, waitset;
+ struct sigaction act;
+
+ _thread_enter_cancellation_point();
+ /*
+ * Specify the thread kernel signal handler.
+ */
+ act.sa_handler = (void (*) ()) _thread_sig_handler;
+ act.sa_flags = SA_RESTART;
+ act.sa_mask = *set;
+
+ /* Ensure the scheduling signal is masked: */
+ sigaddset(&act.sa_mask, _SCHED_SIGNAL);
+
+ /*
+ * Initialize the set of signals that will be waited on:
+ */
+ waitset = *set;
+
+ /* These signals can't be waited on. */
+ sigdelset(&waitset, SIGKILL);
+ sigdelset(&waitset, SIGSTOP);
+ sigdelset(&waitset, _SCHED_SIGNAL);
+ sigdelset(&waitset, SIGCHLD);
+ sigdelset(&waitset, SIGINFO);
+
+ /* Check to see if a pending signal is in the wait mask. */
+ tempset = _thread_run->sigpend;
+ SIGSETOR(tempset, _process_sigpending);
+ SIGSETAND(tempset, waitset);
+ if (SIGNOTEMPTY(tempset)) {
+ /* Enter a loop to find a pending signal: */
+ for (i = 1; i < NSIG; i++) {
+ if (sigismember (&tempset, i))
+ break;
+ }
+
+ /* Clear the pending signal: */
+ if (sigismember(&_thread_run->sigpend,i))
+ sigdelset(&_thread_run->sigpend,i);
+ else
+ sigdelset(&_process_sigpending,i);
+
+ /* Return the signal number to the caller: */
+ *sig = i;
+
+ _thread_leave_cancellation_point();
+ return (0);
+ }
+
+ /*
+ * Enter a loop to find the signals that are SIG_DFL. For
+ * these signals we must install a dummy signal handler in
+ * order for the kernel to pass them in to us. POSIX says
+ * that the _application_ must explicitly install a dummy
+ * handler for signals that are SIG_IGN in order to sigwait
+ * on them. Note that SIG_IGN signals are left in the
+ * mask because a subsequent sigaction could enable an
+ * ignored signal.
+ */
+ for (i = 1; i < NSIG; i++) {
+ if (sigismember(&waitset, i) &&
+ (_thread_sigact[i - 1].sa_handler == SIG_DFL)) {
+ if (_thread_sys_sigaction(i,&act,NULL) != 0)
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ /*
+ * Save the wait signal mask. The wait signal
+ * mask is independent of the threads signal mask
+ * and requires separate storage.
+ */
+ _thread_run->data.sigwait = &waitset;
+
+ /* Wait for a signal: */
+ _thread_kern_sched_state(PS_SIGWAIT, __FILE__, __LINE__);
+
+ /* Return the signal number to the caller: */
+ *sig = _thread_run->signo;
+
+ /*
+ * Probably unnecessary, but since it's in a union struct
+ * we don't know how it could be used in the future.
+ */
+ _thread_run->data.sigwait = NULL;
+ }
+
+ /* Restore the sigactions: */
+ act.sa_handler = SIG_DFL;
+ for (i = 1; i < NSIG; i++) {
+ if (sigismember(&waitset, i) &&
+ (_thread_sigact[i - 1].sa_handler == SIG_DFL)) {
+ if (_thread_sys_sigaction(i,&act,NULL) != 0)
+ ret = -1;
+ }
+ }
+
+ _thread_leave_cancellation_point();
+ /* Return the completion status: */
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_single_np.c b/lib/libpthread/thread/thr_single_np.c
new file mode 100644
index 0000000..d6ecb48
--- /dev/null
+++ b/lib/libpthread/thread/thr_single_np.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <string.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int pthread_single_np()
+{
+ /* Enter single-threaded (non-POSIX) scheduling mode: */
+ _thread_single = _thread_run;
+ return(0);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_spec.c b/lib/libpthread/thread/thr_spec.c
new file mode 100644
index 0000000..f1e9f5c
--- /dev/null
+++ b/lib/libpthread/thread/thr_spec.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Static variables: */
+static struct pthread_key key_table[PTHREAD_KEYS_MAX];
+
+int
+pthread_key_create(pthread_key_t * key, void (*destructor) (void *))
+{
+ for ((*key) = 0; (*key) < PTHREAD_KEYS_MAX; (*key)++) {
+ /* Lock the key table entry: */
+ _SPINLOCK(&key_table[*key].lock);
+
+ if (key_table[(*key)].allocated == 0) {
+ key_table[(*key)].allocated = 1;
+ key_table[(*key)].destructor = destructor;
+
+ /* Unlock the key table entry: */
+ _SPINUNLOCK(&key_table[*key].lock);
+ return (0);
+ }
+
+ /* Unlock the key table entry: */
+ _SPINUNLOCK(&key_table[*key].lock);
+ }
+ return (EAGAIN);
+}
+
+int
+pthread_key_delete(pthread_key_t key)
+{
+ int ret = 0;
+
+ if (key < PTHREAD_KEYS_MAX) {
+ /* Lock the key table entry: */
+ _SPINLOCK(&key_table[key].lock);
+
+ if (key_table[key].allocated)
+ key_table[key].allocated = 0;
+ else
+ ret = EINVAL;
+
+ /* Unlock the key table entry: */
+ _SPINUNLOCK(&key_table[key].lock);
+ } else
+ ret = EINVAL;
+ return (ret);
+}
+
+void
+_thread_cleanupspecific(void)
+{
+ void *data;
+ int key;
+ int itr;
+ void (*destructor)( void *);
+
+ for (itr = 0; itr < PTHREAD_DESTRUCTOR_ITERATIONS; itr++) {
+ for (key = 0; key < PTHREAD_KEYS_MAX; key++) {
+ if (_thread_run->specific_data_count) {
+ /* Lock the key table entry: */
+ _SPINLOCK(&key_table[key].lock);
+ destructor = NULL;
+
+ if (key_table[key].allocated) {
+ if (_thread_run->specific_data[key]) {
+ data = (void *) _thread_run->specific_data[key];
+ _thread_run->specific_data[key] = NULL;
+ _thread_run->specific_data_count--;
+ destructor = key_table[key].destructor;
+ }
+ }
+
+ /* Unlock the key table entry: */
+ _SPINUNLOCK(&key_table[key].lock);
+
+ /*
+ * If there is a destructore, call it
+ * with the key table entry unlocked:
+ */
+ if (destructor)
+ destructor(data);
+ } else {
+ free(_thread_run->specific_data);
+ _thread_run->specific_data = NULL;
+ return;
+ }
+ }
+ }
+ free(_thread_run->specific_data);
+ _thread_run->specific_data = NULL;
+}
+
+static inline const void **
+pthread_key_allocate_data(void)
+{
+ const void **new_data;
+ if ((new_data = (const void **) malloc(sizeof(void *) * PTHREAD_KEYS_MAX)) != NULL) {
+ memset((void *) new_data, 0, sizeof(void *) * PTHREAD_KEYS_MAX);
+ }
+ return (new_data);
+}
+
+int
+pthread_setspecific(pthread_key_t key, const void *value)
+{
+ pthread_t pthread;
+ int ret = 0;
+
+ /* Point to the running thread: */
+ pthread = _thread_run;
+
+ if ((pthread->specific_data) ||
+ (pthread->specific_data = pthread_key_allocate_data())) {
+ if (key < PTHREAD_KEYS_MAX) {
+ if (key_table[key].allocated) {
+ if (pthread->specific_data[key] == NULL) {
+ if (value != NULL)
+ pthread->specific_data_count++;
+ } else {
+ if (value == NULL)
+ pthread->specific_data_count--;
+ }
+ pthread->specific_data[key] = value;
+ ret = 0;
+ } else
+ ret = EINVAL;
+ } else
+ ret = EINVAL;
+ } else
+ ret = ENOMEM;
+ return (ret);
+}
+
+void *
+pthread_getspecific(pthread_key_t key)
+{
+ pthread_t pthread;
+ void *data;
+
+ /* Point to the running thread: */
+ pthread = _thread_run;
+
+ /* Check if there is specific data: */
+ if (pthread->specific_data != NULL && key < PTHREAD_KEYS_MAX) {
+ /* Check if this key has been used before: */
+ if (key_table[key].allocated) {
+ /* Return the value: */
+ data = (void *) pthread->specific_data[key];
+ } else {
+ /*
+ * This key has not been used before, so return NULL
+ * instead:
+ */
+ data = NULL;
+ }
+ } else
+ /* No specific data has been created, so just return NULL: */
+ data = NULL;
+ return (data);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_spinlock.c b/lib/libpthread/thread/thr_spinlock.c
new file mode 100644
index 0000000..4e94ffc
--- /dev/null
+++ b/lib/libpthread/thread/thr_spinlock.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <sched.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+#include "pthread_private.h"
+
+extern char *__progname;
+
+/*
+ * Lock a location for the running thread. Yield to allow other
+ * threads to run if this thread is blocked because the lock is
+ * not available. Note that this function does not sleep. It
+ * assumes that the lock will be available very soon.
+ */
+void
+_spinlock(spinlock_t *lck)
+{
+ /*
+ * Try to grab the lock and loop if another thread grabs
+ * it before we do.
+ */
+ while(_atomic_lock(&lck->access_lock)) {
+ /* Block the thread until the lock. */
+ _thread_run->data.spinlock = lck;
+ _thread_kern_sched_state(PS_SPINBLOCK, __FILE__, __LINE__);
+ }
+
+ /* The running thread now owns the lock: */
+ lck->lock_owner = (long) _thread_run;
+}
+
+/*
+ * Lock a location for the running thread. Yield to allow other
+ * threads to run if this thread is blocked because the lock is
+ * not available. Note that this function does not sleep. It
+ * assumes that the lock will be available very soon.
+ *
+ * This function checks if the running thread has already locked the
+ * location, warns if this occurs and creates a thread dump before
+ * returning.
+ */
+void
+_spinlock_debug(spinlock_t *lck, char *fname, int lineno)
+{
+ int cnt = 0;
+
+ /*
+ * Try to grab the lock and loop if another thread grabs
+ * it before we do.
+ */
+ while(_atomic_lock(&lck->access_lock)) {
+ cnt++;
+ if (cnt > 100) {
+ char str[256];
+ snprintf(str, sizeof(str), "%s - Warning: Thread %p attempted to lock %p from %s (%d) was left locked from %s (%d)\n", __progname, _thread_run, lck, fname, lineno, lck->fname, lck->lineno);
+ _thread_sys_write(2,str,strlen(str));
+ sleep(1);
+ cnt = 0;
+ }
+
+ /* Block the thread until the lock. */
+ _thread_run->data.spinlock = lck;
+ _thread_kern_sched_state(PS_SPINBLOCK, fname, lineno);
+ }
+
+ /* The running thread now owns the lock: */
+ lck->lock_owner = (long) _thread_run;
+ lck->fname = fname;
+ lck->lineno = lineno;
+}
diff --git a/lib/libpthread/thread/thr_suspend_np.c b/lib/libpthread/thread/thr_suspend_np.c
new file mode 100644
index 0000000..ea9b1f8
--- /dev/null
+++ b/lib/libpthread/thread/thr_suspend_np.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* Suspend a thread: */
+int
+pthread_suspend_np(pthread_t thread)
+{
+ int ret;
+
+ /* Find the thread in the list of active threads: */
+ if ((ret = _find_thread(thread)) == 0) {
+ /* The thread exists. Is it running? */
+ if (thread->state != PS_RUNNING &&
+ thread->state != PS_SUSPENDED) {
+ /* The thread operation has been interrupted */
+ _thread_seterrno(thread,EINTR);
+ thread->interrupted = 1;
+ }
+
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /* Suspend the thread. */
+ PTHREAD_NEW_STATE(thread,PS_SUSPENDED);
+
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+ }
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_switch_np.c b/lib/libpthread/thread/thr_switch_np.c
new file mode 100644
index 0000000..9b83545
--- /dev/null
+++ b/lib/libpthread/thread/thr_switch_np.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Daniel Eischen.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include <pthread_np.h>
+#include "pthread_private.h"
+
+
+int
+pthread_switch_add_np(pthread_switch_routine_t routine)
+{
+ int ret = 0;
+
+ if (routine == NULL)
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ else
+ /* Shouldn't need a lock to protect this assigment. */
+ _sched_switch_hook = routine;
+
+ return(ret);
+}
+
+int
+pthread_switch_delete_np(pthread_switch_routine_t routine)
+{
+ int ret = 0;
+
+ if (routine != _sched_switch_hook)
+ /* Return an invalid argument error: */
+ ret = EINVAL;
+ else
+ /* Shouldn't need a lock to protect this assigment. */
+ _sched_switch_hook = NULL;
+
+ return(ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_vfork.c b/lib/libpthread/thread/thr_vfork.c
new file mode 100644
index 0000000..bbfcf00
--- /dev/null
+++ b/lib/libpthread/thread/thr_vfork.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+
+int
+vfork(void)
+{
+ return (fork());
+}
+#endif
diff --git a/lib/libpthread/thread/thr_wait4.c b/lib/libpthread/thread/thr_wait4.c
new file mode 100644
index 0000000..4a58a70
--- /dev/null
+++ b/lib/libpthread/thread/thr_wait4.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <errno.h>
+#include <sys/wait.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+pid_t
+wait4(pid_t pid, int *istat, int options, struct rusage * rusage)
+{
+ pid_t ret;
+
+ _thread_enter_cancellation_point();
+ _thread_kern_sig_defer();
+
+ /* Perform a non-blocking wait4 syscall: */
+ while ((ret = _thread_sys_wait4(pid, istat, options | WNOHANG, rusage)) == 0 && (options & WNOHANG) == 0) {
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ /* Schedule the next thread while this one waits: */
+ _thread_kern_sched_state(PS_WAIT_WAIT, __FILE__, __LINE__);
+
+ /* Check if this call was interrupted by a signal: */
+ if (_thread_run->interrupted) {
+ errno = EINTR;
+ ret = -1;
+ break;
+ }
+ }
+
+ _thread_kern_sig_undefer();
+ _thread_leave_cancellation_point();
+
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_write.c b/lib/libpthread/thread/thr_write.c
new file mode 100644
index 0000000..40c4cc5
--- /dev/null
+++ b/lib/libpthread/thread/thr_write.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+write(int fd, const void *buf, size_t nbytes)
+{
+ int blocking;
+ int type;
+ ssize_t n;
+ ssize_t num = 0;
+ ssize_t ret;
+
+ _thread_enter_cancellation_point();
+ /* POSIX says to do just this: */
+ if (nbytes == 0) {
+ _thread_leave_cancellation_point();
+ return (0);
+ }
+
+ /* Lock the file descriptor for write: */
+ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ /* Get the read/write mode type: */
+ type = _thread_fd_table[fd]->flags & O_ACCMODE;
+
+ /* Check if the file is not open for write: */
+ if (type != O_WRONLY && type != O_RDWR) {
+ /* File is not open for write: */
+ errno = EBADF;
+ _FD_UNLOCK(fd, FD_WRITE);
+ _thread_leave_cancellation_point();
+ return (-1);
+ }
+
+ /* Check if file operations are to block */
+ blocking = ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0);
+
+ /*
+ * Loop while no error occurs and until the expected number
+ * of bytes are written if performing a blocking write:
+ */
+ while (ret == 0) {
+ /* Perform a non-blocking write syscall: */
+ n = _thread_sys_write(fd, buf + num, nbytes - num);
+
+ /* Check if one or more bytes were written: */
+ if (n > 0)
+ /*
+ * Keep a count of the number of bytes
+ * written:
+ */
+ num += n;
+
+ /*
+ * If performing a blocking write, check if the
+ * write would have blocked or if some bytes
+ * were written but there are still more to
+ * write:
+ */
+ if (blocking && ((n < 0 && (errno == EWOULDBLOCK ||
+ errno == EAGAIN)) || (n >= 0 && num < nbytes))) {
+ _thread_run->data.fd.fd = fd;
+ _thread_kern_set_timeout(NULL);
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDW_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
+ /* Return an error: */
+ ret = -1;
+ }
+
+ /*
+ * If performing a non-blocking write or if an
+ * error occurred, just return whatever the write
+ * syscall did:
+ */
+ } else if (!blocking || n < 0) {
+ /* A non-blocking call might return zero: */
+ ret = n;
+ break;
+
+ /* Check if the write has completed: */
+ } else if (num >= nbytes)
+ /* Return the number of bytes written: */
+ ret = num;
+ }
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+ _thread_leave_cancellation_point();
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_writev.c b/lib/libpthread/thread/thr_writev.c
new file mode 100644
index 0000000..375f599
--- /dev/null
+++ b/lib/libpthread/thread/thr_writev.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+ssize_t
+writev(int fd, const struct iovec * iov, int iovcnt)
+{
+ int blocking;
+ int idx = 0;
+ int type;
+ ssize_t cnt;
+ ssize_t n;
+ ssize_t num = 0;
+ ssize_t ret;
+ struct iovec liov[20];
+ struct iovec *p_iov = liov;
+
+ /* Check if the array size exceeds to compiled in size: */
+ if (iovcnt > (sizeof(liov) / sizeof(struct iovec))) {
+ /* Allocate memory for the local array: */
+ if ((p_iov = (struct iovec *)
+ malloc(iovcnt * sizeof(struct iovec))) == NULL) {
+ /* Insufficient memory: */
+ errno = ENOMEM;
+ return (-1);
+ }
+ }
+
+ /* Copy the caller's array so that it can be modified locally: */
+ memcpy(p_iov,iov,iovcnt * sizeof(struct iovec));
+
+ /* Lock the file descriptor for write: */
+ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
+ /* Get the read/write mode type: */
+ type = _thread_fd_table[fd]->flags & O_ACCMODE;
+
+ /* Check if the file is not open for write: */
+ if (type != O_WRONLY && type != O_RDWR) {
+ /* File is not open for write: */
+ errno = EBADF;
+ _FD_UNLOCK(fd, FD_WRITE);
+ return (-1);
+ }
+
+ /* Check if file operations are to block */
+ blocking = ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0);
+
+ /*
+ * Loop while no error occurs and until the expected number
+ * of bytes are written if performing a blocking write:
+ */
+ while (ret == 0) {
+ /* Perform a non-blocking write syscall: */
+ n = _thread_sys_writev(fd, &p_iov[idx], iovcnt - idx);
+
+ /* Check if one or more bytes were written: */
+ if (n > 0) {
+ /*
+ * Keep a count of the number of bytes
+ * written:
+ */
+ num += n;
+
+ /*
+ * Enter a loop to check if a short write
+ * occurred and move the index to the
+ * array entry where the short write
+ * ended:
+ */
+ cnt = n;
+ while (cnt > 0 && idx < iovcnt) {
+ /*
+ * If the residual count exceeds
+ * the size of this vector, then
+ * it was completely written:
+ */
+ if (cnt >= p_iov[idx].iov_len)
+ /*
+ * Decrement the residual
+ * count and increment the
+ * index to the next array
+ * entry:
+ */
+ cnt -= p_iov[idx++].iov_len;
+ else {
+ /*
+ * This entry was only
+ * partially written, so
+ * adjust it's length
+ * and base pointer ready
+ * for the next write:
+ */
+ p_iov[idx].iov_len -= cnt;
+ p_iov[idx].iov_base += cnt;
+ cnt = 0;
+ }
+ }
+ } else if (n == 0) {
+ /*
+ * Avoid an infinite loop if the last iov_len is
+ * 0.
+ */
+ while (idx < iovcnt && p_iov[idx].iov_len == 0)
+ idx++;
+
+ if (idx == iovcnt) {
+ ret = num;
+ break;
+ }
+ }
+
+ /*
+ * If performing a blocking write, check if the
+ * write would have blocked or if some bytes
+ * were written but there are still more to
+ * write:
+ */
+ if (blocking && ((n < 0 && (errno == EWOULDBLOCK ||
+ errno == EAGAIN)) || (n >= 0 && idx < iovcnt))) {
+ _thread_run->data.fd.fd = fd;
+ _thread_kern_set_timeout(NULL);
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDW_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
+ /* Return an error: */
+ ret = -1;
+ }
+
+ /*
+ * If performing a non-blocking write or if an
+ * error occurred, just return whatever the write
+ * syscall did:
+ */
+ } else if (!blocking || n < 0) {
+ /* A non-blocking call might return zero: */
+ ret = n;
+ break;
+
+ /* Check if the write has completed: */
+ } else if (idx == iovcnt)
+ /* Return the number of bytes written: */
+ ret = num;
+ }
+ _FD_UNLOCK(fd, FD_RDWR);
+ }
+
+ /* If memory was allocated for the array, free it: */
+ if (p_iov != liov)
+ free(p_iov);
+
+ return (ret);
+}
+#endif
diff --git a/lib/libpthread/thread/thr_yield.c b/lib/libpthread/thread/thr_yield.c
new file mode 100644
index 0000000..064dd82
--- /dev/null
+++ b/lib/libpthread/thread/thr_yield.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by John Birrell.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+sched_yield(void)
+{
+ /* Reset the accumulated time slice value for the current thread: */
+ _thread_run->slice_usec = -1;
+
+ /* Schedule the next thread: */
+ _thread_kern_sched(NULL);
+
+ /* Always return no error. */
+ return(0);
+}
+
+/* Draft 4 yield */
+void
+pthread_yield(void)
+{
+ /* Reset the accumulated time slice value for the current thread: */
+ _thread_run->slice_usec = -1;
+
+ /* Schedule the next thread: */
+ _thread_kern_sched(NULL);
+
+ /* Nothing to return. */
+ return;
+}
+#endif
diff --git a/lib/libradius/Makefile b/lib/libradius/Makefile
new file mode 100644
index 0000000..ec8bdf7
--- /dev/null
+++ b/lib/libradius/Makefile
@@ -0,0 +1,41 @@
+# Copyright 1998 Juniper Networks, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+LIB= radius
+SRCS= radlib.c
+CFLAGS+= -Wall
+DPADD+= ${LIBMD}
+LDADD+= -lmd
+SHLIB_MAJOR= 1
+SHLIB_MINOR= 0
+MAN3+= libradius.3
+MAN5+= radius.conf.5
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/radlib.h ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libradius/libradius.3 b/lib/libradius/libradius.3
new file mode 100644
index 0000000..cd06e7e
--- /dev/null
+++ b/lib/libradius/libradius.3
@@ -0,0 +1,387 @@
+.\" Copyright 1998 Juniper Networks, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd October 30, 1999
+.Dt LIBRADIUS 3
+.Os FreeBSD
+.Sh NAME
+.Nm libradius
+.Nd RADIUS client library
+.Sh SYNOPSIS
+.Fd #include <radlib.h>
+.Ft struct rad_handle *
+.Fn rad_acct_open "void"
+.Ft int
+.Fn rad_add_server "struct rad_handle *h" "const char *host" "int port" "const char *secret" "int timeout" "int max_tries"
+.Ft struct rad_handle *
+.Fn rad_auth_open "void"
+.Ft void
+.Fn rad_close "struct rad_handle *h"
+.Ft int
+.Fn rad_config "struct rad_handle *h" "const char *file"
+.Ft int
+.Fn rad_continue_send_request "struct rad_handle *h" "int selected" "int *fd" "struct timeval *tv"
+.Ft int
+.Fn rad_create_request "struct rad_handle *h" "int code"
+.Ft struct in_addr
+.Fn rad_cvt_addr "const void *data"
+.Ft u_int32_t
+.Fn rad_cvt_int "const void *data"
+.Ft char *
+.Fn rad_cvt_string "const void *data" "size_t len"
+.Ft int
+.Fn rad_get_attr "struct rad_handle *h" "const void **data" "size_t *len"
+.Ft int
+.Fn rad_init_send_request "struct rad_handle *h" "int *fd" "struct timeval *tv"
+.Ft int
+.Fn rad_put_addr "struct rad_handle *h" "int type" "struct in_addr addr"
+.Ft int
+.Fn rad_put_attr "struct rad_handle *h" "int type" "const void *data" "size_t len"
+.Ft int
+.Fn rad_put_int "struct rad_handle *h" "int type" "u_int32_t value"
+.Ft int
+.Fn rad_put_string "struct rad_handle *h" "int type" "const char *str"
+.Ft int
+.Fn rad_send_request "struct rad_handle *h"
+.Ft const char *
+.Fn rad_strerror "struct rad_handle *h"
+.Sh DESCRIPTION
+The
+.Nm
+library implements the client side of the Remote Authentication Dial
+In User Service (RADIUS). RADIUS, defined in RFCs 2138 and 2139,
+allows clients to perform authentication and accounting by means of
+network requests to remote servers.
+.Sh INITIALIZATION
+To use the library, an application must first call
+.Fn rad_auth_open
+or
+.Fn rad_acct_open
+to obtain a
+.Va struct rad_handle * ,
+which provides the context for subsequent operations.
+The former function is used for RADIUS authentication and the
+latter is used for RADIUS accounting.
+Calls to
+.Fn rad_auth_open
+and
+.Fn rad_acct_open
+always succeed unless insufficient virtual memory is available. If
+the necessary memory cannot be allocated, the functions return
+.Dv NULL .
+For compatibility with earlier versions of this library,
+.Fn rad_open
+is provided as a synonym for
+.Fn rad_auth_open .
+.Pp
+Before issuing any RADIUS requests, the library must be made aware
+of the servers it can contact. The easiest way to configure the
+library is to call
+.Fn rad_config .
+.Fn rad_config
+causes the library to read a configuration file whose format is
+described in
+.Xr radius.conf 5 .
+The pathname of the configuration file is passed as the
+.Va file
+argument to
+.Fn rad_config .
+This argument may also be given as
+.Dv NULL ,
+in which case the standard configuration file
+.Pa /etc/radius.conf
+is used.
+.Fn rad_config
+returns 0 on success, or -1 if an error occurs.
+.Pp
+The library can also be configured programmatically by calls to
+.Fn rad_add_server .
+The
+.Va host
+parameter specifies the server host, either as a fully qualified
+domain name or as a dotted-quad IP address in text form.
+The
+.Va port
+parameter specifies the UDP port to contact on the server. If
+.Va port
+is given as 0, the library looks up the
+.Ql radius/udp
+or
+.Ql radacct/udp
+service in the network services database, and uses the port found
+there. If no entry is found, the library uses the standard RADIUS
+ports, 1812 for authentication and 1813 for accounting.
+The shared secret for the server host is passed to the
+.Va secret
+parameter.
+It may be any NUL-terminated string of bytes. The RADIUS protocol
+ignores all but the leading 128 bytes of the shared secret.
+The timeout for receiving replies from the server is passed to the
+.Va timeout
+parameter, in units of seconds. The maximum number of repeated
+requests to make before giving up is passed into the
+.Va max_tries
+parameter.
+.Fn rad_add_server
+returns 0 on success, or -1 if an error occurs.
+.Pp
+.Fn rad_add_server
+may be called multiple times, and it may be used together with
+.Fn rad_config .
+At most 10 servers may be specified.
+When multiple servers are given, they are tried in round-robin
+fashion until a valid response is received, or until each server's
+.Va max_tries
+limit has been reached.
+.Sh CREATING A RADIUS REQUEST
+A RADIUS request consists of a code specifying the kind of request,
+and zero or more attributes which provide additional information. To
+begin constructing a new request, call
+.Fn rad_create_request .
+In addition to the usual
+.Va struct rad_handle * ,
+this function takes a
+.Va code
+parameter which specifies the type of the request. Most often this
+will be
+.Dv RAD_ACCESS_REQUEST .
+.Fn rad_create_request
+returns 0 on success, or -1 on if an error occurs.
+.Pp
+After the request has been created with
+.Fn rad_create_request ,
+attributes can be attached to it. This is done through calls to
+.Fn rad_put_addr ,
+.Fn rad_put_int ,
+and
+.Fn rad_put_string .
+Each accepts a
+.Va type
+parameter identifying the attribute, and a value which may be
+an Internet address, an integer, or a NUL-terminated string,
+respectively.
+.Pp
+The library also provides a function
+.Fn rad_put_attr
+which can be used to supply a raw, uninterpreted attribute. The
+.Va data
+argument points to an array of bytes, and the
+.Va len
+argument specifies its length.
+.Pp
+The
+.Fn rad_put_X
+functions return 0 on success, or -1 if an error occurs.
+.Sh SENDING THE REQUEST AND RECEIVING THE RESPONSE
+After the RADIUS request has been constructed, it is sent either by means of
+.Fn rad_send_request
+or by a combination of calls to
+.Fn rad_init_send_request
+and
+.Fn rad_continue_send_request .
+.Pp
+The
+.Fn rad_send_request
+function sends the request and waits for a valid reply,
+retrying the defined servers in round-robin fashion as necessary.
+If a valid response is received,
+.Fn rad_send_request
+returns the RADIUS code which specifies the type of the response.
+This will typically be
+.Dv RAD_ACCESS_ACCEPT ,
+.Dv RAD_ACCESS_REJECT ,
+or
+.Dv RAD_ACCESS_CHALLENGE .
+If no valid response is received,
+.Fn rad_send_request
+returns -1.
+.Pp
+As an alternative, if you do not wish to block waiting for a response,
+.Fn rad_init_send_request
+and
+.Fn rad_continue_send_request
+may be used instead. If a reply is received from the RADIUS server or a
+timeout occurs, these functions return a value as described for
+.Fn rad_send_request .
+Otherwise, a value of zero is returned and the values pointed to by
+.Ar fd
+and
+.Ar tv
+are set to the descriptor and timeout that should be passed to
+.Xr select 2 .
+.Pp
+.Fn rad_init_send_request
+must be called first, followed by repeated calls to
+.Fn rad_continue_send_request
+as long as a return value of zero is given.
+Between each call, the application should call
+.Xr select 2 ,
+passing
+.Ar *fd
+as a read descriptor and timing out after the interval specified by
+.Ar tv .
+When select returns,
+.Fn rad_continue_send_request
+should be called with
+.Ar selected
+set to a non-zero value if
+.Xr select 2
+indicated that the descriptor is readable.
+.Pp
+Like RADIUS requests, each response may contain zero or more
+attributes. After a response has been received successfully by
+.Fn rad_send_request
+or
+.Fn rad_continue_send_request ,
+its attributes can be extracted one by one using
+.Fn rad_get_attr .
+Each time
+.Fn rad_get_attr
+is called, it gets the next attribute from the current response, and
+stores a pointer to the data and the length of the data via the
+reference parameters
+.Va data
+and
+.Va len ,
+respectively. Note that the data resides in the response itself,
+and must not be modified.
+A successful call to
+.Fn rad_get_attr
+returns the RADIUS attribute type.
+If no more attributes remain in the current response,
+.Fn rad_get_attr
+returns 0.
+If an error such as a malformed attribute is detected, -1 is
+returned.
+.Pp
+The common types of attributes can be decoded using
+.Fn rad_cvt_addr ,
+.Fn rad_cvt_int ,
+and
+.Fn rad_cvt_string .
+These functions accept a pointer to the attribute data, which should
+have been obtained using
+.Fn rad_get_attr .
+In the case of
+.Fn rad_cvt_string ,
+the length
+.Va len
+must also be given. These functions interpret the attribute as an
+Internet address, an integer, or a string, respectively, and return
+its value.
+.Fn rad_cvt_string
+returns its value as a NUL-terminated string in dynamically
+allocated memory. The application should free the string using
+.Xr free 3
+when it is no longer needed.
+.Pp
+If insufficient virtual memory is available,
+.Fn rad_cvt_string
+returns
+.Dv NULL .
+.Fn rad_cvt_addr
+and
+.Fn rad_cvt_int
+cannot fail.
+.Sh OBTAINING ERROR MESSAGES
+Those functions which accept a
+.Va struct rad_handle *
+argument record an error message if they fail. The error message
+can be retrieved by calling
+.Fn rad_strerror .
+The message text is overwritten on each new error for the given
+.Va struct rad_handle * .
+Thus the message must be copied if it is to be preserved through
+subsequent library calls using the same handle.
+.Sh CLEANUP
+To free the resources used by the RADIUS library, call
+.Fn rad_close .
+.Sh RETURN VALUES
+The following functions return a non-negative value on success. If
+they detect an error, they return -1 and record an error message
+which can be retrieved using
+.Fn rad_strerror .
+.Pp
+.Bl -item -offset indent -compact
+.It
+.Fn rad_add_server
+.It
+.Fn rad_config
+.It
+.Fn rad_create_request
+.It
+.Fn rad_get_attr
+.It
+.Fn rad_put_addr
+.It
+.Fn rad_put_attr
+.It
+.Fn rad_put_int
+.It
+.Fn rad_put_string
+.It
+.Fn rad_init_send_request
+.It
+.Fn rad_continue_send_request
+.It
+.Fn rad_send_request
+.El
+.Pp
+The following functions return a
+.No non- Ns Dv NULL
+pointer on success. If they are unable to allocate sufficient
+virtual memory, they return
+.Dv NULL ,
+without recording an error message.
+.Pp
+.Bl -item -offset indent -compact
+.It
+.Fn rad_acct_open
+.It
+.Fn rad_auth_open
+.It
+.Fn rad_cvt_string
+.El
+.Sh FILES
+.Pa /etc/radius.conf
+.Sh SEE ALSO
+.Xr radius.conf 5
+.Rs
+.%A C. Rigney, et al
+.%T Remote Authentication Dial In User Service (RADIUS)
+.%O RFC 2138
+.Re
+.Rs
+.%A C. Rigney
+.%T RADIUS Accounting
+.%O RFC 2139
+.Re
+.Sh AUTHORS
+This software was originally written by
+.An John Polstra ,
+and donated to the FreeBSD project by Juniper Networks, Inc.
+Oleg Semyonov subsequently added the ability to perform RADIUS
+accounting.
diff --git a/lib/libradius/radius.conf.5 b/lib/libradius/radius.conf.5
new file mode 100644
index 0000000..f05f1b7
--- /dev/null
+++ b/lib/libradius/radius.conf.5
@@ -0,0 +1,167 @@
+.\" Copyright 1998 Juniper Networks, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd October 30, 1999
+.Dt RADIUS.CONF 5
+.Os FreeBSD
+.Sh NAME
+.Nm radius.conf
+.Nd RADIUS client configuration file
+.Sh SYNOPSIS
+.Pa /etc/radius.conf
+.Sh DESCRIPTION
+.Nm
+contains the information necessary to configure the RADIUS client
+library. It is parsed by
+.Xr rad_config 3 .
+The file contains one or more lines of text, each describing a
+single RADIUS server which will be used by the library. Leading
+white space is ignored, as are empty lines and lines containing
+only comments.
+.Pp
+A RADIUS server is described by three to five fields on a line:
+.Pp
+.Bl -item -offset indent -compact
+.It
+Service type
+.It
+Server host
+.It
+Shared secret
+.It
+Timeout
+.It
+Retries
+.El
+.Pp
+The fields are separated by white space. The
+.Ql #
+character at the beginning of a field begins a comment, which extends
+to the end of the line. A field may be enclosed in double quotes,
+in which case it may contain white space and/or begin with the
+.Ql #
+character. Within a quoted string, the double quote character can
+be represented by
+.Ql \e\&" ,
+and the backslash can be represented by
+.Ql \e\e .
+No other escape sequences are supported.
+.Pp
+.Pp
+The first field gives the service type, either
+.Ql auth
+for RADIUS authentication or
+.Ql acct
+for RADIUS accounting. If a single server provides both services, two
+lines are required in the file. Earlier versions of this file did
+not include a service type. For backward compatibility, if the first
+field is not
+.Ql auth
+or
+.Ql acct
+the library behaves as if
+.Ql auth
+were specified, and interprets the fields in the line as if they
+were fields two through five.
+.Pp
+The second field specifies
+the server host, either as a fully qualified domain name or as a
+dotted-quad IP address. The host may optionally be followed by a
+.Ql \&:
+and a numeric port number, without intervening white space. If the
+port specification is omitted, it defaults to the
+.Ql radius
+or
+.Ql radacct
+service in the
+.Pa /etc/services
+file for service types
+.Ql auth
+and
+.Ql acct ,
+respectively.
+If no such entry is present, the standard ports 1812 and 1813 are
+used.
+.Pp
+The third field contains the shared secret, which should be known
+only to the client and server hosts. It is an arbitrary string of
+characters, though it must be enclosed in double quotes if it
+contains white space. The shared secret may be
+any length, but the RADIUS protocol uses only the first 128
+characters. N.B., some popular RADIUS servers have bugs which
+prevent them from working properly with secrets longer than 16
+characters.
+.Pp
+The fourth field contains a decimal integer specifying the timeout in
+seconds for receiving a valid reply from the server. If this field
+is omitted, it defaults to 3 seconds.
+.Pp
+The fifth field contains a decimal integer specifying the maximum
+number of attempts that will be made to authenticate with the server
+before giving up. If omitted, it defaults to 3 attempts. Note,
+this is the total number of attempts and not the number of retries.
+.Pp
+Up to 10 RADIUS servers may be specified for each service type.
+The servers are tried in
+round-robin fashion, until a valid response is received or the
+maximum number of tries has been reached for all servers.
+.Pp
+The standard location for this file is
+.Pa /etc/radius.conf .
+But an alternate pathname may be specified in the call to
+.Xr rad_config 3 .
+Since the file contains sensitive information in the form of the
+shared secrets, it should not be readable except by root.
+.Sh FILES
+.Pa /etc/radius.conf
+.Sh EXAMPLES
+.Bd -literal
+# A simple entry using all the defaults:
+acct radius1.domain.com OurLittleSecret
+
+# A server still using the obsolete RADIUS port, with increased
+# timeout and maximum tries:
+auth auth.domain.com:1645 "I can't see you" 5 4
+
+# A server specified by its IP address:
+auth 192.168.27.81 $X*#..38947ax-+=
+.Ed
+.Sh SEE ALSO
+.Xr libradius 3
+.Rs
+.%A C. Rigney, et al
+.%T Remote Authentication Dial In User Service (RADIUS)
+.%O RFC 2138
+.Re
+.Rs
+.%A C. Rigney
+.%T RADIUS Accounting
+.%O RFC 2139
+.Re
+.Sh AUTHORS
+This documentation was written by
+.An John Polstra ,
+and donated to the FreeBSD project by Juniper Networks, Inc.
diff --git a/lib/libradius/radlib.c b/lib/libradius/radlib.c
new file mode 100644
index 0000000..1860fed
--- /dev/null
+++ b/lib/libradius/radlib.c
@@ -0,0 +1,864 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <md5.h>
+#include <netdb.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "radlib_private.h"
+
+static void clear_password(struct rad_handle *);
+static void generr(struct rad_handle *, const char *, ...)
+ __printflike(2, 3);
+static void insert_scrambled_password(struct rad_handle *, int);
+static void insert_request_authenticator(struct rad_handle *, int);
+static int is_valid_response(struct rad_handle *, int,
+ const struct sockaddr_in *);
+static int put_password_attr(struct rad_handle *, int,
+ const void *, size_t);
+static int put_raw_attr(struct rad_handle *, int,
+ const void *, size_t);
+static int split(char *, char *[], int, char *, size_t);
+
+static void
+clear_password(struct rad_handle *h)
+{
+ if (h->pass_len != 0) {
+ memset(h->pass, 0, h->pass_len);
+ h->pass_len = 0;
+ h->pass_pos = 0;
+ }
+}
+
+static void
+generr(struct rad_handle *h, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vsnprintf(h->errmsg, ERRSIZE, format, ap);
+ va_end(ap);
+}
+
+static void
+insert_scrambled_password(struct rad_handle *h, int srv)
+{
+ MD5_CTX ctx;
+ unsigned char md5[16];
+ const struct rad_server *srvp;
+ int padded_len;
+ int pos;
+
+ srvp = &h->servers[srv];
+ padded_len = h->pass_len == 0 ? 16 : (h->pass_len+15) & ~0xf;
+
+ memcpy(md5, &h->request[POS_AUTH], LEN_AUTH);
+ for (pos = 0; pos < padded_len; pos += 16) {
+ int i;
+
+ /* Calculate the new scrambler */
+ MD5Init(&ctx);
+ MD5Update(&ctx, srvp->secret, strlen(srvp->secret));
+ MD5Update(&ctx, md5, 16);
+ MD5Final(md5, &ctx);
+
+ /*
+ * Mix in the current chunk of the password, and copy
+ * the result into the right place in the request. Also
+ * modify the scrambler in place, since we will use this
+ * in calculating the scrambler for next time.
+ */
+ for (i = 0; i < 16; i++)
+ h->request[h->pass_pos + pos + i] =
+ md5[i] ^= h->pass[pos + i];
+ }
+}
+
+static void
+insert_request_authenticator(struct rad_handle *h, int srv)
+{
+ MD5_CTX ctx;
+ const struct rad_server *srvp;
+
+ srvp = &h->servers[srv];
+
+ /* Create the request authenticator */
+ MD5Init(&ctx);
+ MD5Update(&ctx, &h->request[POS_CODE], POS_AUTH - POS_CODE);
+ MD5Update(&ctx, memset(&h->request[POS_AUTH], 0, LEN_AUTH), LEN_AUTH);
+ MD5Update(&ctx, &h->request[POS_ATTRS], h->req_len - POS_ATTRS);
+ MD5Update(&ctx, srvp->secret, strlen(srvp->secret));
+ MD5Final(&h->request[POS_AUTH], &ctx);
+}
+
+/*
+ * Return true if the current response is valid for a request to the
+ * specified server.
+ */
+static int
+is_valid_response(struct rad_handle *h, int srv,
+ const struct sockaddr_in *from)
+{
+ MD5_CTX ctx;
+ unsigned char md5[16];
+ const struct rad_server *srvp;
+ int len;
+
+ srvp = &h->servers[srv];
+
+ /* Check the source address */
+ if (from->sin_family != srvp->addr.sin_family ||
+ from->sin_addr.s_addr != srvp->addr.sin_addr.s_addr ||
+ from->sin_port != srvp->addr.sin_port)
+ return 0;
+
+ /* Check the message length */
+ if (h->resp_len < POS_ATTRS)
+ return 0;
+ len = h->response[POS_LENGTH] << 8 | h->response[POS_LENGTH+1];
+ if (len > h->resp_len)
+ return 0;
+
+ /* Check the response authenticator */
+ MD5Init(&ctx);
+ MD5Update(&ctx, &h->response[POS_CODE], POS_AUTH - POS_CODE);
+ MD5Update(&ctx, &h->request[POS_AUTH], LEN_AUTH);
+ MD5Update(&ctx, &h->response[POS_ATTRS], len - POS_ATTRS);
+ MD5Update(&ctx, srvp->secret, strlen(srvp->secret));
+ MD5Final(md5, &ctx);
+ if (memcmp(&h->response[POS_AUTH], md5, sizeof md5) != 0)
+ return 0;
+
+ return 1;
+}
+
+static int
+put_password_attr(struct rad_handle *h, int type, const void *value, size_t len)
+{
+ int padded_len;
+ int pad_len;
+
+ if (h->pass_pos != 0) {
+ generr(h, "Multiple User-Password attributes specified");
+ return -1;
+ }
+ if (len > PASSSIZE)
+ len = PASSSIZE;
+ padded_len = len == 0 ? 16 : (len+15) & ~0xf;
+ pad_len = padded_len - len;
+
+ /*
+ * Put in a place-holder attribute containing all zeros, and
+ * remember where it is so we can fill it in later.
+ */
+ clear_password(h);
+ put_raw_attr(h, type, h->pass, padded_len);
+ h->pass_pos = h->req_len - padded_len;
+
+ /* Save the cleartext password, padded as necessary */
+ memcpy(h->pass, value, len);
+ h->pass_len = len;
+ memset(h->pass + len, 0, pad_len);
+ return 0;
+}
+
+static int
+put_raw_attr(struct rad_handle *h, int type, const void *value, size_t len)
+{
+ if (len > 253) {
+ generr(h, "Attribute too long");
+ return -1;
+ }
+ if (h->req_len + 2 + len > MSGSIZE) {
+ generr(h, "Maximum message length exceeded");
+ return -1;
+ }
+ h->request[h->req_len++] = type;
+ h->request[h->req_len++] = len + 2;
+ memcpy(&h->request[h->req_len], value, len);
+ h->req_len += len;
+ return 0;
+}
+
+int
+rad_add_server(struct rad_handle *h, const char *host, int port,
+ const char *secret, int timeout, int tries)
+{
+ struct rad_server *srvp;
+
+ if (h->num_servers >= MAXSERVERS) {
+ generr(h, "Too many RADIUS servers specified");
+ return -1;
+ }
+ srvp = &h->servers[h->num_servers];
+
+ memset(&srvp->addr, 0, sizeof srvp->addr);
+ srvp->addr.sin_len = sizeof srvp->addr;
+ srvp->addr.sin_family = AF_INET;
+ if (!inet_aton(host, &srvp->addr.sin_addr)) {
+ struct hostent *hent;
+
+ if ((hent = gethostbyname(host)) == NULL) {
+ generr(h, "%s: host not found", host);
+ return -1;
+ }
+ memcpy(&srvp->addr.sin_addr, hent->h_addr,
+ sizeof srvp->addr.sin_addr);
+ }
+ if (port != 0)
+ srvp->addr.sin_port = htons(port);
+ else {
+ struct servent *sent;
+
+ if (h->type == RADIUS_AUTH)
+ srvp->addr.sin_port =
+ (sent = getservbyname("radius", "udp")) != NULL ?
+ sent->s_port : htons(RADIUS_PORT);
+ else
+ srvp->addr.sin_port =
+ (sent = getservbyname("radacct", "udp")) != NULL ?
+ sent->s_port : htons(RADACCT_PORT);
+ }
+ if ((srvp->secret = strdup(secret)) == NULL) {
+ generr(h, "Out of memory");
+ return -1;
+ }
+ srvp->timeout = timeout;
+ srvp->max_tries = tries;
+ srvp->num_tries = 0;
+ h->num_servers++;
+ return 0;
+}
+
+void
+rad_close(struct rad_handle *h)
+{
+ int srv;
+
+ if (h->fd != -1)
+ close(h->fd);
+ for (srv = 0; srv < h->num_servers; srv++) {
+ memset(h->servers[srv].secret, 0,
+ strlen(h->servers[srv].secret));
+ free(h->servers[srv].secret);
+ }
+ clear_password(h);
+ free(h);
+}
+
+int
+rad_config(struct rad_handle *h, const char *path)
+{
+ FILE *fp;
+ char buf[MAXCONFLINE];
+ int linenum;
+ int retval;
+
+ if (path == NULL)
+ path = PATH_RADIUS_CONF;
+ if ((fp = fopen(path, "r")) == NULL) {
+ generr(h, "Cannot open \"%s\": %s", path, strerror(errno));
+ return -1;
+ }
+ retval = 0;
+ linenum = 0;
+ while (fgets(buf, sizeof buf, fp) != NULL) {
+ int len;
+ char *fields[5];
+ int nfields;
+ char msg[ERRSIZE];
+ char *type;
+ char *host;
+ char *port_str;
+ char *secret;
+ char *timeout_str;
+ char *maxtries_str;
+ char *end;
+ char *wanttype;
+ unsigned long timeout;
+ unsigned long maxtries;
+ int port;
+ int i;
+
+ linenum++;
+ len = strlen(buf);
+ /* We know len > 0, else fgets would have returned NULL. */
+ if (buf[len - 1] != '\n') {
+ if (len == sizeof buf - 1)
+ generr(h, "%s:%d: line too long", path,
+ linenum);
+ else
+ generr(h, "%s:%d: missing newline", path,
+ linenum);
+ retval = -1;
+ break;
+ }
+ buf[len - 1] = '\0';
+
+ /* Extract the fields from the line. */
+ nfields = split(buf, fields, 5, msg, sizeof msg);
+ if (nfields == -1) {
+ generr(h, "%s:%d: %s", path, linenum, msg);
+ retval = -1;
+ break;
+ }
+ if (nfields == 0)
+ continue;
+ /*
+ * The first field should contain "auth" or "acct" for
+ * authentication or accounting, respectively. But older
+ * versions of the file didn't have that field. Default
+ * it to "auth" for backward compatibility.
+ */
+ if (strcmp(fields[0], "auth") != 0 &&
+ strcmp(fields[0], "acct") != 0) {
+ if (nfields >= 5) {
+ generr(h, "%s:%d: invalid service type", path,
+ linenum);
+ retval = -1;
+ break;
+ }
+ nfields++;
+ for (i = nfields; --i > 0; )
+ fields[i] = fields[i - 1];
+ fields[0] = "auth";
+ }
+ if (nfields < 3) {
+ generr(h, "%s:%d: missing shared secret", path,
+ linenum);
+ retval = -1;
+ break;
+ }
+ type = fields[0];
+ host = fields[1];
+ secret = fields[2];
+ timeout_str = fields[3];
+ maxtries_str = fields[4];
+
+ /* Ignore the line if it is for the wrong service type. */
+ wanttype = h->type == RADIUS_AUTH ? "auth" : "acct";
+ if (strcmp(type, wanttype) != 0)
+ continue;
+
+ /* Parse and validate the fields. */
+ host = strtok(host, ":");
+ port_str = strtok(NULL, ":");
+ if (port_str != NULL) {
+ port = strtoul(port_str, &end, 10);
+ if (*end != '\0') {
+ generr(h, "%s:%d: invalid port", path,
+ linenum);
+ retval = -1;
+ break;
+ }
+ } else
+ port = 0;
+ if (timeout_str != NULL) {
+ timeout = strtoul(timeout_str, &end, 10);
+ if (*end != '\0') {
+ generr(h, "%s:%d: invalid timeout", path,
+ linenum);
+ retval = -1;
+ break;
+ }
+ } else
+ timeout = TIMEOUT;
+ if (maxtries_str != NULL) {
+ maxtries = strtoul(maxtries_str, &end, 10);
+ if (*end != '\0') {
+ generr(h, "%s:%d: invalid maxtries", path,
+ linenum);
+ retval = -1;
+ break;
+ }
+ } else
+ maxtries = MAXTRIES;
+
+ if (rad_add_server(h, host, port, secret, timeout, maxtries) ==
+ -1) {
+ strcpy(msg, h->errmsg);
+ generr(h, "%s:%d: %s", path, linenum, msg);
+ retval = -1;
+ break;
+ }
+ }
+ /* Clear out the buffer to wipe a possible copy of a shared secret */
+ memset(buf, 0, sizeof buf);
+ fclose(fp);
+ return retval;
+}
+
+/*
+ * rad_init_send_request() must have previously been called.
+ * Returns:
+ * 0 The application should select on *fd with a timeout of tv before
+ * calling rad_continue_send_request again.
+ * < 0 Failure
+ * > 0 Success
+ */
+int
+rad_continue_send_request(struct rad_handle *h, int selected, int *fd,
+ struct timeval *tv)
+{
+ int n;
+
+ if (selected) {
+ struct sockaddr_in from;
+ int fromlen;
+
+ fromlen = sizeof from;
+ h->resp_len = recvfrom(h->fd, h->response,
+ MSGSIZE, MSG_WAITALL, (struct sockaddr *)&from, &fromlen);
+ if (h->resp_len == -1) {
+ generr(h, "recvfrom: %s", strerror(errno));
+ return -1;
+ }
+ if (is_valid_response(h, h->srv, &from)) {
+ h->resp_len = h->response[POS_LENGTH] << 8 |
+ h->response[POS_LENGTH+1];
+ h->resp_pos = POS_ATTRS;
+ return h->response[POS_CODE];
+ }
+ }
+
+ if (h->try == h->total_tries) {
+ generr(h, "No valid RADIUS responses received");
+ return -1;
+ }
+
+ /*
+ * Scan round-robin to the next server that has some
+ * tries left. There is guaranteed to be one, or we
+ * would have exited this loop by now.
+ */
+ while (h->servers[h->srv].num_tries >= h->servers[h->srv].max_tries)
+ if (++h->srv >= h->num_servers)
+ h->srv = 0;
+
+ if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST)
+ /* Insert the request authenticator into the request */
+ insert_request_authenticator(h, h->srv);
+ else
+ /* Insert the scrambled password into the request */
+ if (h->pass_pos != 0)
+ insert_scrambled_password(h, h->srv);
+
+ /* Send the request */
+ n = sendto(h->fd, h->request, h->req_len, 0,
+ (const struct sockaddr *)&h->servers[h->srv].addr,
+ sizeof h->servers[h->srv].addr);
+ if (n != h->req_len) {
+ if (n == -1)
+ generr(h, "sendto: %s", strerror(errno));
+ else
+ generr(h, "sendto: short write");
+ return -1;
+ }
+
+ h->try++;
+ h->servers[h->srv].num_tries++;
+ tv->tv_sec = h->servers[h->srv].timeout;
+ tv->tv_usec = 0;
+ *fd = h->fd;
+
+ return 0;
+}
+
+int
+rad_create_request(struct rad_handle *h, int code)
+{
+ int i;
+
+ h->request[POS_CODE] = code;
+ h->request[POS_IDENT] = ++h->ident;
+ /* Create a random authenticator */
+ for (i = 0; i < LEN_AUTH; i += 2) {
+ long r;
+ r = random();
+ h->request[POS_AUTH+i] = r;
+ h->request[POS_AUTH+i+1] = r >> 8;
+ }
+ h->req_len = POS_ATTRS;
+ clear_password(h);
+ return 0;
+}
+
+struct in_addr
+rad_cvt_addr(const void *data)
+{
+ struct in_addr value;
+
+ memcpy(&value.s_addr, data, sizeof value.s_addr);
+ return value;
+}
+
+u_int32_t
+rad_cvt_int(const void *data)
+{
+ u_int32_t value;
+
+ memcpy(&value, data, sizeof value);
+ return ntohl(value);
+}
+
+char *
+rad_cvt_string(const void *data, size_t len)
+{
+ char *s;
+
+ s = malloc(len + 1);
+ if (s != NULL) {
+ memcpy(s, data, len);
+ s[len] = '\0';
+ }
+ return s;
+}
+
+/*
+ * Returns the attribute type. If none are left, returns 0. On failure,
+ * returns -1.
+ */
+int
+rad_get_attr(struct rad_handle *h, const void **value, size_t *len)
+{
+ int type;
+
+ if (h->resp_pos >= h->resp_len)
+ return 0;
+ if (h->resp_pos + 2 > h->resp_len) {
+ generr(h, "Malformed attribute in response");
+ return -1;
+ }
+ type = h->response[h->resp_pos++];
+ *len = h->response[h->resp_pos++] - 2;
+ if (h->resp_pos + *len > h->resp_len) {
+ generr(h, "Malformed attribute in response");
+ return -1;
+ }
+ *value = &h->response[h->resp_pos];
+ h->resp_pos += *len;
+ return type;
+}
+
+/*
+ * Returns -1 on error, 0 to indicate no event and >0 for success
+ */
+int
+rad_init_send_request(struct rad_handle *h, int *fd, struct timeval *tv)
+{
+ int srv;
+
+ /* Make sure we have a socket to use */
+ if (h->fd == -1) {
+ struct sockaddr_in sin;
+
+ if ((h->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
+ generr(h, "Cannot create socket: %s", strerror(errno));
+ return -1;
+ }
+ memset(&sin, 0, sizeof sin);
+ sin.sin_len = sizeof sin;
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ sin.sin_port = htons(0);
+ if (bind(h->fd, (const struct sockaddr *)&sin,
+ sizeof sin) == -1) {
+ generr(h, "bind: %s", strerror(errno));
+ close(h->fd);
+ h->fd = -1;
+ return -1;
+ }
+ }
+
+ if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST) {
+ /* Make sure no password given */
+ if (h->pass_pos || h->chap_pass) {
+ generr(h, "User or Chap Password in accounting request");
+ return -1;
+ }
+ } else {
+ /* Make sure the user gave us a password */
+ if (h->pass_pos == 0 && !h->chap_pass) {
+ generr(h, "No User or Chap Password attributes given");
+ return -1;
+ }
+ if (h->pass_pos != 0 && h->chap_pass) {
+ generr(h, "Both User and Chap Password attributes given");
+ return -1;
+ }
+ }
+
+ /* Fill in the length field in the message */
+ h->request[POS_LENGTH] = h->req_len >> 8;
+ h->request[POS_LENGTH+1] = h->req_len;
+
+ /*
+ * Count the total number of tries we will make, and zero the
+ * counter for each server.
+ */
+ h->total_tries = 0;
+ for (srv = 0; srv < h->num_servers; srv++) {
+ h->total_tries += h->servers[srv].max_tries;
+ h->servers[srv].num_tries = 0;
+ }
+ if (h->total_tries == 0) {
+ generr(h, "No RADIUS servers specified");
+ return -1;
+ }
+
+ h->try = h->srv = 0;
+
+ return rad_continue_send_request(h, 0, fd, tv);
+}
+
+/*
+ * Create and initialize a rad_handle structure, and return it to the
+ * caller. Can fail only if the necessary memory cannot be allocated.
+ * In that case, it returns NULL.
+ */
+struct rad_handle *
+rad_auth_open(void)
+{
+ struct rad_handle *h;
+
+ h = (struct rad_handle *)malloc(sizeof(struct rad_handle));
+ if (h != NULL) {
+ srandomdev();
+ h->fd = -1;
+ h->num_servers = 0;
+ h->ident = random();
+ h->errmsg[0] = '\0';
+ memset(h->pass, 0, sizeof h->pass);
+ h->pass_len = 0;
+ h->pass_pos = 0;
+ h->chap_pass = 0;
+ h->type = RADIUS_AUTH;
+ }
+ return h;
+}
+
+struct rad_handle *
+rad_acct_open(void)
+{
+ struct rad_handle *h;
+
+ h = rad_open();
+ if (h != NULL)
+ h->type = RADIUS_ACCT;
+ return h;
+}
+
+struct rad_handle *
+rad_open(void)
+{
+ return rad_auth_open();
+}
+
+int
+rad_put_addr(struct rad_handle *h, int type, struct in_addr addr)
+{
+ return rad_put_attr(h, type, &addr.s_addr, sizeof addr.s_addr);
+}
+
+int
+rad_put_attr(struct rad_handle *h, int type, const void *value, size_t len)
+{
+ int result;
+
+ if (type == RAD_USER_PASSWORD)
+ result = put_password_attr(h, type, value, len);
+ else {
+ result = put_raw_attr(h, type, value, len);
+ if (result == 0 && type == RAD_CHAP_PASSWORD)
+ h->chap_pass = 1;
+ }
+
+ return result;
+}
+
+int
+rad_put_int(struct rad_handle *h, int type, u_int32_t value)
+{
+ u_int32_t nvalue;
+
+ nvalue = htonl(value);
+ return rad_put_attr(h, type, &nvalue, sizeof nvalue);
+}
+
+int
+rad_put_string(struct rad_handle *h, int type, const char *str)
+{
+ return rad_put_attr(h, type, str, strlen(str));
+}
+
+/*
+ * Returns the response type code on success, or -1 on failure.
+ */
+int
+rad_send_request(struct rad_handle *h)
+{
+ struct timeval timelimit;
+ struct timeval tv;
+ int fd;
+ int n;
+
+ n = rad_init_send_request(h, &fd, &tv);
+
+ if (n != 0)
+ return n;
+
+ gettimeofday(&timelimit, NULL);
+ timeradd(&tv, &timelimit, &timelimit);
+
+ for ( ; ; ) {
+ fd_set readfds;
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+
+ n = select(fd + 1, &readfds, NULL, NULL, &tv);
+
+ if (n == -1) {
+ generr(h, "select: %s", strerror(errno));
+ return -1;
+ }
+
+ if (!FD_ISSET(fd, &readfds)) {
+ /* Compute a new timeout */
+ gettimeofday(&tv, NULL);
+ timersub(&timelimit, &tv, &tv);
+ if (tv.tv_sec > 0 || (tv.tv_sec == 0 && tv.tv_usec > 0))
+ /* Continue the select */
+ continue;
+ }
+
+ n = rad_continue_send_request(h, n, &fd, &tv);
+
+ if (n != 0)
+ return n;
+
+ gettimeofday(&timelimit, NULL);
+ timeradd(&tv, &timelimit, &timelimit);
+ }
+}
+
+const char *
+rad_strerror(struct rad_handle *h)
+{
+ return h->errmsg;
+}
+
+/*
+ * Destructively split a string into fields separated by white space.
+ * `#' at the beginning of a field begins a comment that extends to the
+ * end of the string. Fields may be quoted with `"'. Inside quoted
+ * strings, the backslash escapes `\"' and `\\' are honored.
+ *
+ * Pointers to up to the first maxfields fields are stored in the fields
+ * array. Missing fields get NULL pointers.
+ *
+ * The return value is the actual number of fields parsed, and is always
+ * <= maxfields.
+ *
+ * On a syntax error, places a message in the msg string, and returns -1.
+ */
+static int
+split(char *str, char *fields[], int maxfields, char *msg, size_t msglen)
+{
+ char *p;
+ int i;
+ static const char ws[] = " \t";
+
+ for (i = 0; i < maxfields; i++)
+ fields[i] = NULL;
+ p = str;
+ i = 0;
+ while (*p != '\0') {
+ p += strspn(p, ws);
+ if (*p == '#' || *p == '\0')
+ break;
+ if (i >= maxfields) {
+ snprintf(msg, msglen, "line has too many fields");
+ return -1;
+ }
+ if (*p == '"') {
+ char *dst;
+
+ dst = ++p;
+ fields[i] = dst;
+ while (*p != '"') {
+ if (*p == '\\') {
+ p++;
+ if (*p != '"' && *p != '\\' &&
+ *p != '\0') {
+ snprintf(msg, msglen,
+ "invalid `\\' escape");
+ return -1;
+ }
+ }
+ if (*p == '\0') {
+ snprintf(msg, msglen,
+ "unterminated quoted string");
+ return -1;
+ }
+ *dst++ = *p++;
+ }
+ *dst = '\0';
+ p++;
+ if (*fields[i] == '\0') {
+ snprintf(msg, msglen,
+ "empty quoted string not permitted");
+ return -1;
+ }
+ if (*p != '\0' && strspn(p, ws) == 0) {
+ snprintf(msg, msglen, "quoted string not"
+ " followed by white space");
+ return -1;
+ }
+ } else {
+ fields[i] = p;
+ p += strcspn(p, ws);
+ if (*p != '\0')
+ *p++ = '\0';
+ }
+ i++;
+ }
+ return i;
+}
diff --git a/lib/libradius/radlib.h b/lib/libradius/radlib.h
new file mode 100644
index 0000000..ccf3006
--- /dev/null
+++ b/lib/libradius/radlib.h
@@ -0,0 +1,183 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _RADLIB_H_
+#define _RADLIB_H_
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+/* Message types */
+#define RAD_ACCESS_REQUEST 1
+#define RAD_ACCESS_ACCEPT 2
+#define RAD_ACCESS_REJECT 3
+#define RAD_ACCOUNTING_REQUEST 4
+#define RAD_ACCOUNTING_RESPONSE 5
+#define RAD_ACCESS_CHALLENGE 11
+
+/* Attribute types and values */
+#define RAD_USER_NAME 1 /* String */
+#define RAD_USER_PASSWORD 2 /* String */
+#define RAD_CHAP_PASSWORD 3 /* String */
+#define RAD_NAS_IP_ADDRESS 4 /* IP address */
+#define RAD_NAS_PORT 5 /* Integer */
+#define RAD_SERVICE_TYPE 6 /* Integer */
+ #define RAD_LOGIN 1
+ #define RAD_FRAMED 2
+ #define RAD_CALLBACK_LOGIN 3
+ #define RAD_CALLBACK_FRAMED 4
+ #define RAD_OUTBOUND 5
+ #define RAD_ADMINISTRATIVE 6
+ #define RAD_NAS_PROMPT 7
+ #define RAD_AUTHENTICATE_ONLY 8
+ #define RAD_CALLBACK_NAS_PROMPT 9
+#define RAD_FRAMED_PROTOCOL 7 /* Integer */
+ #define RAD_PPP 1
+ #define RAD_SLIP 2
+ #define RAD_ARAP 3 /* Appletalk */
+ #define RAD_GANDALF 4
+ #define RAD_XYLOGICS 5
+#define RAD_FRAMED_IP_ADDRESS 8 /* IP address */
+#define RAD_FRAMED_IP_NETMASK 9 /* IP address */
+#define RAD_FRAMED_ROUTING 10 /* Integer */
+#define RAD_FILTER_ID 11 /* String */
+#define RAD_FRAMED_MTU 12 /* Integer */
+#define RAD_FRAMED_COMPRESSION 13 /* Integer */
+ #define RAD_COMP_NONE 0
+ #define RAD_COMP_VJ 1
+ #define RAD_COMP_IPXHDR 2
+#define RAD_LOGIN_IP_HOST 14 /* IP address */
+#define RAD_LOGIN_SERVICE 15 /* Integer */
+#define RAD_LOGIN_TCP_PORT 16 /* Integer */
+ /* unassiged 17 */
+#define RAD_REPLY_MESSAGE 18 /* String */
+#define RAD_CALLBACK_NUMBER 19 /* String */
+#define RAD_CALLBACK_ID 20 /* String */
+ /* unassiged 21 */
+#define RAD_FRAMED_ROUTE 22 /* String */
+#define RAD_FRAMED_IPX_NETWORK 23 /* IP address */
+#define RAD_STATE 24 /* String */
+#define RAD_CLASS 25 /* Integer */
+#define RAD_VENDOR_SPECIFIC 26 /* Integer */
+#define RAD_SESSION_TIMEOUT 27 /* Integer */
+#define RAD_IDLE_TIMEOUT 28 /* Integer */
+#define RAD_TERMINATION_ACTION 29 /* Integer */
+#define RAD_CALLED_STATION_ID 30 /* String */
+#define RAD_CALLING_STATION_ID 31 /* String */
+#define RAD_NAS_IDENTIFIER 32 /* Integer */
+#define RAD_PROXY_STATE 33 /* Integer */
+#define RAD_LOGIN_LAT_SERVICE 34 /* Integer */
+#define RAD_LOGIN_LAT_NODE 35 /* Integer */
+#define RAD_LOGIN_LAT_GROUP 36 /* Integer */
+#define RAD_FRAMED_APPLETALK_LINK 37 /* Integer */
+#define RAD_FRAMED_APPLETALK_NETWORK 38 /* Integer */
+#define RAD_FRAMED_APPLETALK_ZONE 39 /* Integer */
+ /* reserved for accounting 40-59 */
+#define RAD_CHAP_CHALLENGE 60 /* String */
+#define RAD_NAS_PORT_TYPE 61 /* Integer */
+ #define RAD_ASYNC 0
+ #define RAD_SYNC 1
+ #define RAD_ISDN_SYNC 2
+ #define RAD_ISDN_ASYNC_V120 3
+ #define RAD_ISDN_ASYNC_V110 4
+ #define RAD_VIRTUAL 5
+#define RAD_PORT_LIMIT 62 /* Integer */
+#define RAD_LOGIN_LAT_PORT 63 /* Integer */
+#define RAD_CONNECT_INFO 77 /* String */
+
+/* Accounting attribute types and values */
+#define RAD_ACCT_STATUS_TYPE 40 /* Integer */
+ #define RAD_START 1
+ #define RAD_STOP 2
+ #define RAD_ACCOUNTING_ON 7
+ #define RAD_ACCOUNTING_OFF 8
+#define RAD_ACCT_DELAY_TIME 41 /* Integer */
+#define RAD_ACCT_INPUT_OCTETS 42 /* Integer */
+#define RAD_ACCT_OUTPUT_OCTETS 43 /* Integer */
+#define RAD_ACCT_SESSION_ID 44 /* String */
+#define RAD_ACCT_AUTHENTIC 45 /* Integer */
+ #define RAD_AUTH_RADIUS 1
+ #define RAD_AUTH_LOCAL 2
+ #define RAD_AUTH_REMOTE 3
+#define RAD_ACCT_SESSION_TIME 46 /* Integer */
+#define RAD_ACCT_INPUT_PACKETS 47 /* Integer */
+#define RAD_ACCT_OUTPUT_PACKETS 48 /* Integer */
+#define RAD_ACCT_TERMINATE_CAUSE 49 /* Integer */
+ #define RAD_TERM_USER_REQUEST 1
+ #define RAD_TERM_LOST_CARRIER 2
+ #define RAD_TERM_LOST_SERVICE 3
+ #define RAD_TERM_IDLE_TIMEOUT 4
+ #define RAD_TERM_SESSION_TIMEOUT 5
+ #define RAD_TERM_ADMIN_RESET 6
+ #define RAD_TERM_ADMIN_REBOOT 7
+ #define RAD_TERM_PORT_ERROR 8
+ #define RAD_TERM_NAS_ERROR 9
+ #define RAD_TERM_NAS_REQUEST 10
+ #define RAD_TERM_NAS_REBOOT 11
+ #define RAD_TERM_PORT_UNNEEDED 12
+ #define RAD_TERM_PORT_PREEMPTED 13
+ #define RAD_TERM_PORT_SUSPENDED 14
+ #define RAD_TERM_SERVICE_UNAVAILABLE 15
+ #define RAD_TERM_CALLBACK 16
+ #define RAD_TERM_USER_ERROR 17
+ #define RAD_TERM_HOST_REQUEST 18
+#define RAD_ACCT_MULTI_SESSION_ID 50 /* String */
+#define RAD_ACCT_LINK_COUNT 51 /* Integer */
+
+struct rad_handle;
+struct timeval;
+
+__BEGIN_DECLS
+struct rad_handle *rad_acct_open(void);
+int rad_add_server(struct rad_handle *,
+ const char *, int, const char *, int, int);
+struct rad_handle *rad_auth_open(void);
+void rad_close(struct rad_handle *);
+int rad_config(struct rad_handle *, const char *);
+int rad_continue_send_request(struct rad_handle *, int,
+ int *, struct timeval *);
+int rad_create_request(struct rad_handle *, int);
+struct in_addr rad_cvt_addr(const void *);
+u_int32_t rad_cvt_int(const void *);
+char *rad_cvt_string(const void *, size_t);
+int rad_get_attr(struct rad_handle *, const void **,
+ size_t *);
+int rad_init_send_request(struct rad_handle *, int *,
+ struct timeval *);
+struct rad_handle *rad_open(void); /* Deprecated, == rad_auth_open */
+int rad_put_addr(struct rad_handle *, int, struct in_addr);
+int rad_put_attr(struct rad_handle *, int,
+ const void *, size_t);
+int rad_put_int(struct rad_handle *, int, u_int32_t);
+int rad_put_string(struct rad_handle *, int,
+ const char *);
+int rad_send_request(struct rad_handle *);
+const char *rad_strerror(struct rad_handle *);
+__END_DECLS
+
+#endif /* _RADLIB_H_ */
diff --git a/lib/libradius/radlib_private.h b/lib/libradius/radlib_private.h
new file mode 100644
index 0000000..af16970
--- /dev/null
+++ b/lib/libradius/radlib_private.h
@@ -0,0 +1,92 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef RADLIB_PRIVATE_H
+#define RADLIB_PRIVATE_H
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#include "radlib.h"
+
+/* Handle types */
+#define RADIUS_AUTH 0 /* RADIUS authentication, default */
+#define RADIUS_ACCT 1 /* RADIUS accounting */
+
+/* Defaults */
+#define MAXTRIES 3
+#define PATH_RADIUS_CONF "/etc/radius.conf"
+#define RADIUS_PORT 1812
+#define RADACCT_PORT 1813
+#define TIMEOUT 3 /* In seconds */
+
+/* Limits */
+#define ERRSIZE 128 /* Maximum error message length */
+#define MAXCONFLINE 1024 /* Maximum config file line length */
+#define MAXSERVERS 10 /* Maximum number of servers to try */
+#define MSGSIZE 4096 /* Maximum RADIUS message */
+#define PASSSIZE 128 /* Maximum significant password chars */
+
+/* Positions of fields in RADIUS messages */
+#define POS_CODE 0 /* Message code */
+#define POS_IDENT 1 /* Identifier */
+#define POS_LENGTH 2 /* Message length */
+#define POS_AUTH 4 /* Authenticator */
+#define LEN_AUTH 16 /* Length of authenticator */
+#define POS_ATTRS 20 /* Start of attributes */
+
+struct rad_server {
+ struct sockaddr_in addr; /* Address of server */
+ char *secret; /* Shared secret */
+ int timeout; /* Timeout in seconds */
+ int max_tries; /* Number of tries before giving up */
+ int num_tries; /* Number of tries so far */
+};
+
+struct rad_handle {
+ int fd; /* Socket file descriptor */
+ struct rad_server servers[MAXSERVERS]; /* Servers to contact */
+ int num_servers; /* Number of valid server entries */
+ int ident; /* Current identifier value */
+ char errmsg[ERRSIZE]; /* Most recent error message */
+ unsigned char request[MSGSIZE]; /* Request to send */
+ int req_len; /* Length of request */
+ char pass[PASSSIZE]; /* Cleartext password */
+ int pass_len; /* Length of cleartext password */
+ int pass_pos; /* Position of scrambled password */
+ char chap_pass; /* Have we got a CHAP_PASSWORD ? */
+ unsigned char response[MSGSIZE]; /* Response received */
+ int resp_len; /* Length of response */
+ int resp_pos; /* Current position scanning attrs */
+ int total_tries; /* How many requests we'll send */
+ int try; /* How many requests we've sent */
+ int srv; /* Server number we did last */
+ int type; /* Handle type */
+};
+
+#endif
diff --git a/lib/libresolv/Makefile b/lib/libresolv/Makefile
new file mode 100644
index 0000000..118b757
--- /dev/null
+++ b/lib/libresolv/Makefile
@@ -0,0 +1,39 @@
+# @(#)Makefile 8.1 (Berkeley) 6/4/93
+
+LIB= resolv
+INTERNALLIB= yes # Do not build or install ${LIB}*.a
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 0
+
+SRCS= fakelib.c
+
+.if ${OBJFORMAT} != aout
+NOPIC= true
+.endif
+
+#
+# Before complaining about this, please *double-check* that you have
+# updated the ldconfig path in /etc/rc to include /usr/lib/compat that
+# was added in src/etc/rc rev 1.98.
+# This is so that programs that use autoconf will not "detect" -lresolv
+# and continue to propagate the bogosity. The ldconfig path fix will
+# enable you to run programs that were linked with -lresolv.
+#
+# libresolv on FreeBSD-2.x **never did anything**!!
+#
+beforeinstall:
+ rm -f ${DESTDIR}${LIBDIR}/lib${LIB}.a \
+ ${DESTDIR}${LIBDIR}/lib${LIB}_p.a \
+ ${DESTDIR}${ORIG_SHLIBDIR}/lib${LIB}.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ ${DESTDIR}/usr/lib/compat/lib${LIB}.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ ${DESTDIR}/usr/lib/compat/lib${LIB}.so.${SHLIB_MAJOR} \
+ ${DESTDIR}/usr/lib/compat/lib${LIB}.so
+
+.include <bsd.lib.mk>
+
+# This must follow the .include in case SHLIBDIR is defined there.
+ORIG_SHLIBDIR:= ${SHLIBDIR}
+
+# The ldconfig line in/etc/rc doesn't depend on ${LIBDIR} or ${SHLIBDIR},
+# so neither does this.
+SHLIBDIR= /usr/lib/compat/aout
diff --git a/lib/libresolv/fakelib.c b/lib/libresolv/fakelib.c
new file mode 100644
index 0000000..0f7b46f
--- /dev/null
+++ b/lib/libresolv/fakelib.c
@@ -0,0 +1 @@
+static int ___fake_library___;
diff --git a/lib/librpcsvc/Makefile b/lib/librpcsvc/Makefile
new file mode 100644
index 0000000..077a33e
--- /dev/null
+++ b/lib/librpcsvc/Makefile
@@ -0,0 +1,36 @@
+# from: @(#)Makefile 5.10 (Berkeley) 6/24/90
+# $FreeBSD$
+
+.PATH: ${DESTDIR}/usr/include/rpcsvc
+
+LIB= rpcsvc
+
+RPCSRCS= klm_prot.x mount.x nfs_prot.x nlm_prot.x rex.x rnusers.x \
+ rquota.x rstat.x rwall.x sm_inter.x spray.x yppasswd.x ypxfrd.x \
+ ypupdate_prot.x
+
+OTHERSRCS= rnusers.c rstat.c rwall.c yp_passwd.c yp_update.c
+SECRPCSRCS= secretkey.c xcrypt.c
+
+RPCCOM = rpcgen -C
+
+INCDIRS= -I${DESTDIR}/usr/include/rpcsvc -I${DESTDIR}/usr/include
+
+CFLAGS+= -DYP ${INCDIRS}
+
+GENSRCS= ${RPCSRCS:R:S/$/_xdr.c/g}
+SRCS+= ${GENSRCS} ${OTHERSRCS} ${SECRPCSRCS}
+
+CLEANFILES+= ${GENSRCS}
+
+NOMAN= noman
+
+.include <bsd.lib.mk>
+
+.SUFFIXES: .x _xdr.c
+
+.x_xdr.c:
+ ${RPCCOM} -c ${.IMPSRC} -o ${.TARGET}
+
+OBJS= ${RPCSRCS:R:S/$/_xdr.o/g} ${SECRPCSRCS:R:S/$/.o/g} \
+ ${OTHERSRCS:R:S/$/.o/g}
diff --git a/lib/librpcsvc/rnusers.c b/lib/librpcsvc/rnusers.c
new file mode 100644
index 0000000..3a4629f
--- /dev/null
+++ b/lib/librpcsvc/rnusers.c
@@ -0,0 +1,68 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rnusers.c 1.2 91/03/11 TIRPC 1.0; from 1.7 89/03/24 SMI";
+#endif
+
+/*
+ * rnusers.c
+ *
+ * "High" level programmatic interface to rnusers RPC service.
+ *
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpcsvc/rnusers.h>
+
+int
+rusers(host, up)
+ char *host;
+ struct utmpidlearr *up;
+{
+ return (callrpc(host, RUSERSPROG, RUSERSVERS_IDLE, RUSERSPROC_NAMES,
+ xdr_void, (char *) NULL,
+ xdr_utmpidlearr, (char *) up));
+}
+
+int
+rnusers(host)
+ char *host;
+{
+ int nusers;
+
+ if (callrpc(host, RUSERSPROG, RUSERSVERS_ORIG, RUSERSPROC_NUM,
+ xdr_void, (char *) NULL,
+ xdr_u_long, (char *) &nusers) != 0)
+ return (-1);
+ else
+ return (nusers);
+}
+
diff --git a/lib/librpcsvc/rstat.c b/lib/librpcsvc/rstat.c
new file mode 100644
index 0000000..6851c75
--- /dev/null
+++ b/lib/librpcsvc/rstat.c
@@ -0,0 +1,67 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rstat.c 1.2 91/03/11 TIRPC 1.0; from 1.6 89/03/24 SMI";
+#endif
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+/*
+ * "High" level programmatic interface to rstat RPC service.
+ */
+#include <rpc/rpc.h>
+#include <rpcsvc/rstat.h>
+
+int
+rstat(host, statp)
+ char *host;
+ struct statstime *statp;
+{
+ return (callrpc(host, RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS,
+ xdr_void, (char *) NULL,
+ xdr_statstime, (char *) statp));
+}
+
+int
+havedisk(host)
+ char *host;
+{
+ long have;
+
+ if (callrpc(host, RSTATPROG, RSTATVERS_SWTCH, RSTATPROC_HAVEDISK,
+ xdr_void, (char *) NULL,
+ xdr_long, (char *) &have) != 0)
+ return (-1);
+ else
+ return (have);
+}
+
diff --git a/lib/librpcsvc/rwall.c b/lib/librpcsvc/rwall.c
new file mode 100644
index 0000000..97de86e
--- /dev/null
+++ b/lib/librpcsvc/rwall.c
@@ -0,0 +1,52 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rwall.c 1.2 91/03/11 TIRPC 1.0; from 1.3 89/03/24 SMI";
+#endif
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+/*
+ * "High" level programmatic interface to rwall RPC service.
+ */
+#include <rpc/rpc.h>
+#include <rpcsvc/rwall.h>
+
+int
+rwall(host, msg)
+ char *host;
+ char *msg;
+{
+ return (callrpc(host, WALLPROG, WALLVERS, WALLPROC_WALL,
+ xdr_wrapstring, (char *) &msg,
+ xdr_void, (char *) NULL));
+}
diff --git a/lib/librpcsvc/secretkey.c b/lib/librpcsvc/secretkey.c
new file mode 100644
index 0000000..374372b
--- /dev/null
+++ b/lib/librpcsvc/secretkey.c
@@ -0,0 +1,85 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)secretkey.c 1.8 91/03/11 Copyr 1986 Sun Micro";
+#endif
+
+/*
+ * secretkey.c
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+/*
+ * Secret key lookup routines
+ */
+#include <stdio.h>
+#include <pwd.h>
+#include <rpc/rpc.h>
+#include <rpc/key_prot.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#include <string.h>
+
+extern int xdecrypt __P(( char *, char * ));
+
+/*
+ * Get somebody's encrypted secret key from the database, using the given
+ * passwd to decrypt it.
+ */
+int
+getsecretkey(netname, secretkey, passwd)
+ char *netname;
+ char *secretkey;
+ char *passwd;
+{
+ char lookup[3 * HEXKEYBYTES];
+ char *p;
+
+ if (secretkey == NULL)
+ return (0);
+ if (!getpublicandprivatekey(netname, lookup))
+ return (0);
+ p = strchr(lookup, ':');
+ if (p == NULL) {
+ return (0);
+ }
+ p++;
+ if (!xdecrypt(p, passwd)) {
+ return (0);
+ }
+ if (memcmp(p, p + HEXKEYBYTES, KEYCHECKSUMSIZE) != 0) {
+ secretkey[0] = '\0';
+ return (1);
+ }
+ p[HEXKEYBYTES] = '\0';
+ (void) strncpy(secretkey, p, HEXKEYBYTES);
+ secretkey[HEXKEYBYTES] = '\0';
+ return (1);
+}
diff --git a/lib/librpcsvc/xcrypt.c b/lib/librpcsvc/xcrypt.c
new file mode 100644
index 0000000..f2b54a5
--- /dev/null
+++ b/lib/librpcsvc/xcrypt.c
@@ -0,0 +1,192 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Hex encryption/decryption and utility routines
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/cdefs.h>
+#include <rpc/des_crypt.h>
+
+#ifndef lint
+/*from: static char sccsid[] = "@(#)xcrypt.c 2.2 88/08/10 4.0 RPCSRC"; */
+static const char rcsid[] = "$FreeBSD$";
+#endif
+
+static char hex[]; /* forward */
+static char hexval __P(( char ));
+static void bin2hex __P(( int, unsigned char *, char * ));
+static void hex2bin __P(( int, char *, char * ));
+void passwd2des __P(( char *, char * ));
+
+/*
+ * Encrypt a secret key given passwd
+ * The secret key is passed and returned in hex notation.
+ * Its length must be a multiple of 16 hex digits (64 bits).
+ */
+int
+xencrypt(secret, passwd)
+ char *secret;
+ char *passwd;
+{
+ char key[8];
+ char ivec[8];
+ char *buf;
+ int err;
+ int len;
+
+ len = strlen(secret) / 2;
+ buf = malloc((unsigned)len);
+
+ hex2bin(len, secret, buf);
+ passwd2des(passwd, key);
+ bzero(ivec, 8);
+
+ err = cbc_crypt(key, buf, len, DES_ENCRYPT | DES_HW, ivec);
+ if (DES_FAILED(err)) {
+ free(buf);
+ return (0);
+ }
+ bin2hex(len, (unsigned char *) buf, secret);
+ free(buf);
+ return (1);
+}
+
+/*
+ * Decrypt secret key using passwd
+ * The secret key is passed and returned in hex notation.
+ * Once again, the length is a multiple of 16 hex digits
+ */
+int
+xdecrypt(secret, passwd)
+ char *secret;
+ char *passwd;
+{
+ char key[8];
+ char ivec[8];
+ char *buf;
+ int err;
+ int len;
+
+ len = strlen(secret) / 2;
+ buf = malloc((unsigned)len);
+
+ hex2bin(len, secret, buf);
+ passwd2des(passwd, key);
+ bzero(ivec, 8);
+
+ err = cbc_crypt(key, buf, len, DES_DECRYPT | DES_HW, ivec);
+ if (DES_FAILED(err)) {
+ free(buf);
+ return (0);
+ }
+ bin2hex(len, (unsigned char *) buf, secret);
+ free(buf);
+ return (1);
+}
+
+
+/*
+ * Turn password into DES key
+ */
+void
+passwd2des(pw, key)
+ char *pw;
+ char *key;
+{
+ int i;
+
+ bzero(key, 8);
+ for (i = 0; *pw; i = (i+1)%8) {
+ key[i] ^= *pw++ << 1;
+ }
+ des_setparity(key);
+}
+
+
+
+/*
+ * Hex to binary conversion
+ */
+static void
+hex2bin(len, hexnum, binnum)
+ int len;
+ char *hexnum;
+ char *binnum;
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ *binnum++ = 16 * hexval(hexnum[2*i]) + hexval(hexnum[2*i+1]);
+ }
+}
+
+/*
+ * Binary to hex conversion
+ */
+static void
+bin2hex(len, binnum, hexnum)
+ int len;
+ unsigned char *binnum;
+ char *hexnum;
+{
+ int i;
+ unsigned val;
+
+ for (i = 0; i < len; i++) {
+ val = binnum[i];
+ hexnum[i*2] = hex[val >> 4];
+ hexnum[i*2+1] = hex[val & 0xf];
+ }
+ hexnum[len*2] = 0;
+}
+
+static char hex[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
+};
+
+static char
+hexval(c)
+ char c;
+{
+ if (c >= '0' && c <= '9') {
+ return (c - '0');
+ } else if (c >= 'a' && c <= 'z') {
+ return (c - 'a' + 10);
+ } else if (c >= 'A' && c <= 'Z') {
+ return (c - 'A' + 10);
+ } else {
+ return (-1);
+ }
+}
diff --git a/lib/librpcsvc/yp_passwd.c b/lib/librpcsvc/yp_passwd.c
new file mode 100644
index 0000000..f3d42b7
--- /dev/null
+++ b/lib/librpcsvc/yp_passwd.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1995, 1996
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdlib.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#include <rpcsvc/yppasswd.h>
+#include <netinet/in.h>
+
+#ifndef LINT
+static const char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * XXX <rpcsvc/yppasswd.h> does a typedef that makes 'yppasswd'
+ * a type of struct yppasswd. This leads to a namespace collision:
+ * gcc will not let you have a type called yppasswd and a function
+ * called yppasswd(). In order to get around this, we call the
+ * actual function _yppasswd() and put a macro called yppasswd()
+ * in yppasswd.h which calls the underlying function, thereby
+ * fooling gcc.
+ */
+
+int _yppasswd(oldpass, newpw)
+ char *oldpass;
+ struct x_passwd *newpw;
+{
+ char *server;
+ char *domain;
+ int rval, result;
+ struct yppasswd yppasswd;
+
+ yppasswd.newpw = *newpw;
+ yppasswd.oldpass = oldpass;
+
+ if (yp_get_default_domain(&domain))
+ return (-1);
+
+ if (yp_master(domain, "passwd.byname", &server))
+ return(-1);
+
+ rval = getrpcport(server, YPPASSWDPROG,
+ YPPASSWDPROC_UPDATE, IPPROTO_UDP);
+
+ if (rval == 0 || rval >= IPPORT_RESERVED) {
+ free(server);
+ return(-1);
+ }
+
+ rval = callrpc(server, YPPASSWDPROG, YPPASSWDVERS, YPPASSWDPROC_UPDATE,
+ xdr_yppasswd, (char *)&yppasswd, xdr_int, &result);
+
+ free(server);
+ if (rval || result)
+ return(-1);
+ else
+ return(0);
+}
diff --git a/lib/librpcsvc/yp_update.c b/lib/librpcsvc/yp_update.c
new file mode 100644
index 0000000..ba49c0c
--- /dev/null
+++ b/lib/librpcsvc/yp_update.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 1995, 1996
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * ypupdate client-side library function.
+ *
+ * Written by Bill Paul <wpaul@ctr.columbia.edu>
+ * Center for Telecommunications Research
+ * Columbia University, New York City
+ *
+ * $FreeBSD$
+ */
+
+#include <stdlib.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#include <rpcsvc/ypupdate_prot.h>
+#include <rpc/key_prot.h>
+
+#ifndef lint
+static const char rcsid[] = "$FreeBSD$";
+#endif
+
+#ifndef WINDOW
+#define WINDOW (60*60)
+#endif
+
+#ifndef TIMEOUT
+#define TIMEOUT 300
+#endif
+
+int
+yp_update(domain, map, ypop, key, keylen, data, datalen)
+ char *domain;
+ char *map;
+ unsigned int ypop;
+ char *key;
+ int keylen;
+ char *data;
+ int datalen;
+{
+ char *master;
+ int rval;
+ unsigned int res;
+ struct ypupdate_args upargs;
+ struct ypdelete_args delargs;
+ CLIENT *clnt;
+ char netname[MAXNETNAMELEN+1];
+ des_block des_key;
+ struct timeval timeout;
+
+ /* Get the master server name for 'domain.' */
+ if ((rval = yp_master(domain, map, &master)))
+ return(rval);
+
+ /* Check that ypupdated is running there. */
+ if (getrpcport(master, YPU_PROG, YPU_VERS, ypop))
+ return(YPERR_DOMAIN);
+
+ /* Get a handle. */
+ if ((clnt = clnt_create(master, YPU_PROG, YPU_VERS, "tcp")) == NULL)
+ return(YPERR_RPC);
+
+ /*
+ * Assemble netname of server.
+ * NOTE: It's difficult to discern from the documentation, but
+ * when you make a Secure RPC call, the netname you pass should
+ * be the netname of the guy on the other side, not your own
+ * netname. This is how the client side knows what public key
+ * to use for the initial exchange. Passing your own netname
+ * only works if the server on the other side is running under
+ * your UID.
+ */
+ if (!host2netname(netname, master, domain)) {
+ clnt_destroy(clnt);
+ return(YPERR_BADARGS);
+ }
+
+ /* Make up a DES session key. */
+ key_gendes(&des_key);
+
+ /* Set up DES authentication. */
+ if ((clnt->cl_auth = (AUTH *)authdes_create(netname, WINDOW, NULL,
+ &des_key)) == NULL) {
+ clnt_destroy(clnt);
+ return(YPERR_RESRC);
+ }
+
+ /* Set a timeout for clnt_call(). */
+ timeout.tv_usec = 0;
+ timeout.tv_sec = TIMEOUT;
+
+ /*
+ * Make the call. Note that we use clnt_call() here rather than
+ * the rpcgen-erated client stubs. We could use those stubs, but
+ * then we'd have to do some gymnastics to get at the error
+ * information to figure out what error code to send back to the
+ * caller. With clnt_call(), we get the error status returned to
+ * us right away, and we only have to exert a small amount of
+ * extra effort.
+ */
+ switch(ypop) {
+ case YPOP_CHANGE:
+ upargs.mapname = map;
+ upargs.key.yp_buf_len = keylen;
+ upargs.key.yp_buf_val = key;
+ upargs.datum.yp_buf_len = datalen;
+ upargs.datum.yp_buf_val = data;
+
+ if ((rval = clnt_call(clnt, YPU_CHANGE, xdr_ypupdate_args,
+ &upargs, xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
+ if (rval == RPC_AUTHERROR)
+ res = YPERR_ACCESS;
+ else
+ res = YPERR_RPC;
+ }
+
+ break;
+ case YPOP_INSERT:
+ upargs.mapname = map;
+ upargs.key.yp_buf_len = keylen;
+ upargs.key.yp_buf_val = key;
+ upargs.datum.yp_buf_len = datalen;
+ upargs.datum.yp_buf_val = data;
+
+ if ((rval = clnt_call(clnt, YPU_INSERT, xdr_ypupdate_args,
+ &upargs, xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
+ if (rval == RPC_AUTHERROR)
+ res = YPERR_ACCESS;
+ else
+ res = YPERR_RPC;
+ }
+
+ break;
+ case YPOP_DELETE:
+ delargs.mapname = map;
+ delargs.key.yp_buf_len = keylen;
+ delargs.key.yp_buf_val = key;
+
+ if ((rval = clnt_call(clnt, YPU_DELETE, xdr_ypdelete_args,
+ &delargs, xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
+ if (rval == RPC_AUTHERROR)
+ res = YPERR_ACCESS;
+ else
+ res = YPERR_RPC;
+ }
+
+ break;
+ case YPOP_STORE:
+ upargs.mapname = map;
+ upargs.key.yp_buf_len = keylen;
+ upargs.key.yp_buf_val = key;
+ upargs.datum.yp_buf_len = datalen;
+ upargs.datum.yp_buf_val = data;
+
+ if ((rval = clnt_call(clnt, YPU_STORE, xdr_ypupdate_args,
+ &upargs, xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
+ if (rval == RPC_AUTHERROR)
+ res = YPERR_ACCESS;
+ else
+ res = YPERR_RPC;
+ }
+
+ break;
+ default:
+ res = YPERR_BADARGS;
+ break;
+ }
+
+ /* All done: tear down the connection. */
+ auth_destroy(clnt->cl_auth);
+ clnt_destroy(clnt);
+ free(master);
+
+ return(res);
+}
diff --git a/lib/libskey/Makefile b/lib/libskey/Makefile
new file mode 100644
index 0000000..4ad0fe3
--- /dev/null
+++ b/lib/libskey/Makefile
@@ -0,0 +1,25 @@
+# @(#)Makefile 5.4 (Berkeley) 5/7/91
+
+LIB= skey
+SRCS= skeyaccess.c put.c skey_crypt.c skey_getpass.c skeylogin.c skeysubr.c
+MAN1= skey.1
+MAN3= skey.3
+MLINKS= skey.3 skeylookup.3 skey.3 skeyverify.3 skey.3 skeychallenge.3 \
+ skey.3 skeyinfo.3 skey.3 skeyaccess.3 skey.3 skey_getpass.3 \
+ skey.3 skey_crypt.3
+MAN5= skey.access.5
+
+CFLAGS+=-DPERMIT_CONSOLE -D_SKEY_INTERNAL -I${.CURDIR}
+CFLAGS+=-W -Wall
+.if ${MACHINE_ARCH} == "i386"
+CFLAGS+=-Werror
+.endif
+
+DPADD+= ${LIBCRYPT} ${LIBMD}
+LDADD+= -lcrypt -lmd
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/skey.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libskey/mdx.h b/lib/libskey/mdx.h
new file mode 100644
index 0000000..567d541
--- /dev/null
+++ b/lib/libskey/mdx.h
@@ -0,0 +1,19 @@
+#ifdef MD5
+/* S/Key can use MD5 now, if defined... */
+#include <md5.h>
+
+#define MDXFinal MD5Final
+#define MDXInit MD5Init
+#define MDXUpdate MD5Update
+#define MDX_CTX MD5_CTX
+#else
+
+/* By default, use MD4 for compatibility */
+#include <md4.h>
+
+#define MDXFinal MD4Final
+#define MDXInit MD4Init
+#define MDXUpdate MD4Update
+#define MDX_CTX MD4_CTX
+
+#endif
diff --git a/lib/libskey/pathnames.h b/lib/libskey/pathnames.h
new file mode 100644
index 0000000..ca91fcc
--- /dev/null
+++ b/lib/libskey/pathnames.h
@@ -0,0 +1,6 @@
+/* $FreeBSD$ (FreeBSD) */
+
+#include <paths.h>
+
+#define _PATH_SKEYACCESS "/etc/skey.access"
+#define _PATH_SKEYFILE "/etc/skeykeys"
diff --git a/lib/libskey/put.c b/lib/libskey/put.c
new file mode 100644
index 0000000..e57d9ca
--- /dev/null
+++ b/lib/libskey/put.c
@@ -0,0 +1,2293 @@
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+#include "skey.h"
+
+static unsigned long extract __P((char *s,int start,int length));
+static void standard __P((char *word));
+static void insert __P((char *s, int x, int start, int length));
+static int wsrch __P((char *w,int low,int high));
+
+/* Dictionary for integer-word translations */
+static char Wp[2048][4] = {
+"A",
+"ABE",
+"ACE",
+"ACT",
+"AD",
+"ADA",
+"ADD",
+"AGO",
+"AID",
+"AIM",
+"AIR",
+"ALL",
+"ALP",
+"AM",
+"AMY",
+"AN",
+"ANA",
+"AND",
+"ANN",
+"ANT",
+"ANY",
+"APE",
+"APS",
+"APT",
+"ARC",
+"ARE",
+"ARK",
+"ARM",
+"ART",
+"AS",
+"ASH",
+"ASK",
+"AT",
+"ATE",
+"AUG",
+"AUK",
+"AVE",
+"AWE",
+"AWK",
+"AWL",
+"AWN",
+"AX",
+"AYE",
+"BAD",
+"BAG",
+"BAH",
+"BAM",
+"BAN",
+"BAR",
+"BAT",
+"BAY",
+"BE",
+"BED",
+"BEE",
+"BEG",
+"BEN",
+"BET",
+"BEY",
+"BIB",
+"BID",
+"BIG",
+"BIN",
+"BIT",
+"BOB",
+"BOG",
+"BON",
+"BOO",
+"BOP",
+"BOW",
+"BOY",
+"BUB",
+"BUD",
+"BUG",
+"BUM",
+"BUN",
+"BUS",
+"BUT",
+"BUY",
+"BY",
+"BYE",
+"CAB",
+"CAL",
+"CAM",
+"CAN",
+"CAP",
+"CAR",
+"CAT",
+"CAW",
+"COD",
+"COG",
+"COL",
+"CON",
+"COO",
+"COP",
+"COT",
+"COW",
+"COY",
+"CRY",
+"CUB",
+"CUE",
+"CUP",
+"CUR",
+"CUT",
+"DAB",
+"DAD",
+"DAM",
+"DAN",
+"DAR",
+"DAY",
+"DEE",
+"DEL",
+"DEN",
+"DES",
+"DEW",
+"DID",
+"DIE",
+"DIG",
+"DIN",
+"DIP",
+"DO",
+"DOE",
+"DOG",
+"DON",
+"DOT",
+"DOW",
+"DRY",
+"DUB",
+"DUD",
+"DUE",
+"DUG",
+"DUN",
+"EAR",
+"EAT",
+"ED",
+"EEL",
+"EGG",
+"EGO",
+"ELI",
+"ELK",
+"ELM",
+"ELY",
+"EM",
+"END",
+"EST",
+"ETC",
+"EVA",
+"EVE",
+"EWE",
+"EYE",
+"FAD",
+"FAN",
+"FAR",
+"FAT",
+"FAY",
+"FED",
+"FEE",
+"FEW",
+"FIB",
+"FIG",
+"FIN",
+"FIR",
+"FIT",
+"FLO",
+"FLY",
+"FOE",
+"FOG",
+"FOR",
+"FRY",
+"FUM",
+"FUN",
+"FUR",
+"GAB",
+"GAD",
+"GAG",
+"GAL",
+"GAM",
+"GAP",
+"GAS",
+"GAY",
+"GEE",
+"GEL",
+"GEM",
+"GET",
+"GIG",
+"GIL",
+"GIN",
+"GO",
+"GOT",
+"GUM",
+"GUN",
+"GUS",
+"GUT",
+"GUY",
+"GYM",
+"GYP",
+"HA",
+"HAD",
+"HAL",
+"HAM",
+"HAN",
+"HAP",
+"HAS",
+"HAT",
+"HAW",
+"HAY",
+"HE",
+"HEM",
+"HEN",
+"HER",
+"HEW",
+"HEY",
+"HI",
+"HID",
+"HIM",
+"HIP",
+"HIS",
+"HIT",
+"HO",
+"HOB",
+"HOC",
+"HOE",
+"HOG",
+"HOP",
+"HOT",
+"HOW",
+"HUB",
+"HUE",
+"HUG",
+"HUH",
+"HUM",
+"HUT",
+"I",
+"ICY",
+"IDA",
+"IF",
+"IKE",
+"ILL",
+"INK",
+"INN",
+"IO",
+"ION",
+"IQ",
+"IRA",
+"IRE",
+"IRK",
+"IS",
+"IT",
+"ITS",
+"IVY",
+"JAB",
+"JAG",
+"JAM",
+"JAN",
+"JAR",
+"JAW",
+"JAY",
+"JET",
+"JIG",
+"JIM",
+"JO",
+"JOB",
+"JOE",
+"JOG",
+"JOT",
+"JOY",
+"JUG",
+"JUT",
+"KAY",
+"KEG",
+"KEN",
+"KEY",
+"KID",
+"KIM",
+"KIN",
+"KIT",
+"LA",
+"LAB",
+"LAC",
+"LAD",
+"LAG",
+"LAM",
+"LAP",
+"LAW",
+"LAY",
+"LEA",
+"LED",
+"LEE",
+"LEG",
+"LEN",
+"LEO",
+"LET",
+"LEW",
+"LID",
+"LIE",
+"LIN",
+"LIP",
+"LIT",
+"LO",
+"LOB",
+"LOG",
+"LOP",
+"LOS",
+"LOT",
+"LOU",
+"LOW",
+"LOY",
+"LUG",
+"LYE",
+"MA",
+"MAC",
+"MAD",
+"MAE",
+"MAN",
+"MAO",
+"MAP",
+"MAT",
+"MAW",
+"MAY",
+"ME",
+"MEG",
+"MEL",
+"MEN",
+"MET",
+"MEW",
+"MID",
+"MIN",
+"MIT",
+"MOB",
+"MOD",
+"MOE",
+"MOO",
+"MOP",
+"MOS",
+"MOT",
+"MOW",
+"MUD",
+"MUG",
+"MUM",
+"MY",
+"NAB",
+"NAG",
+"NAN",
+"NAP",
+"NAT",
+"NAY",
+"NE",
+"NED",
+"NEE",
+"NET",
+"NEW",
+"NIB",
+"NIL",
+"NIP",
+"NIT",
+"NO",
+"NOB",
+"NOD",
+"NON",
+"NOR",
+"NOT",
+"NOV",
+"NOW",
+"NU",
+"NUN",
+"NUT",
+"O",
+"OAF",
+"OAK",
+"OAR",
+"OAT",
+"ODD",
+"ODE",
+"OF",
+"OFF",
+"OFT",
+"OH",
+"OIL",
+"OK",
+"OLD",
+"ON",
+"ONE",
+"OR",
+"ORB",
+"ORE",
+"ORR",
+"OS",
+"OTT",
+"OUR",
+"OUT",
+"OVA",
+"OW",
+"OWE",
+"OWL",
+"OWN",
+"OX",
+"PA",
+"PAD",
+"PAL",
+"PAM",
+"PAN",
+"PAP",
+"PAR",
+"PAT",
+"PAW",
+"PAY",
+"PEA",
+"PEG",
+"PEN",
+"PEP",
+"PER",
+"PET",
+"PEW",
+"PHI",
+"PI",
+"PIE",
+"PIN",
+"PIT",
+"PLY",
+"PO",
+"POD",
+"POE",
+"POP",
+"POT",
+"POW",
+"PRO",
+"PRY",
+"PUB",
+"PUG",
+"PUN",
+"PUP",
+"PUT",
+"QUO",
+"RAG",
+"RAM",
+"RAN",
+"RAP",
+"RAT",
+"RAW",
+"RAY",
+"REB",
+"RED",
+"REP",
+"RET",
+"RIB",
+"RID",
+"RIG",
+"RIM",
+"RIO",
+"RIP",
+"ROB",
+"ROD",
+"ROE",
+"RON",
+"ROT",
+"ROW",
+"ROY",
+"RUB",
+"RUE",
+"RUG",
+"RUM",
+"RUN",
+"RYE",
+"SAC",
+"SAD",
+"SAG",
+"SAL",
+"SAM",
+"SAN",
+"SAP",
+"SAT",
+"SAW",
+"SAY",
+"SEA",
+"SEC",
+"SEE",
+"SEN",
+"SET",
+"SEW",
+"SHE",
+"SHY",
+"SIN",
+"SIP",
+"SIR",
+"SIS",
+"SIT",
+"SKI",
+"SKY",
+"SLY",
+"SO",
+"SOB",
+"SOD",
+"SON",
+"SOP",
+"SOW",
+"SOY",
+"SPA",
+"SPY",
+"SUB",
+"SUD",
+"SUE",
+"SUM",
+"SUN",
+"SUP",
+"TAB",
+"TAD",
+"TAG",
+"TAN",
+"TAP",
+"TAR",
+"TEA",
+"TED",
+"TEE",
+"TEN",
+"THE",
+"THY",
+"TIC",
+"TIE",
+"TIM",
+"TIN",
+"TIP",
+"TO",
+"TOE",
+"TOG",
+"TOM",
+"TON",
+"TOO",
+"TOP",
+"TOW",
+"TOY",
+"TRY",
+"TUB",
+"TUG",
+"TUM",
+"TUN",
+"TWO",
+"UN",
+"UP",
+"US",
+"USE",
+"VAN",
+"VAT",
+"VET",
+"VIE",
+"WAD",
+"WAG",
+"WAR",
+"WAS",
+"WAY",
+"WE",
+"WEB",
+"WED",
+"WEE",
+"WET",
+"WHO",
+"WHY",
+"WIN",
+"WIT",
+"WOK",
+"WON",
+"WOO",
+"WOW",
+"WRY",
+"WU",
+"YAM",
+"YAP",
+"YAW",
+"YE",
+"YEA",
+"YES",
+"YET",
+"YOU",
+"ABED",
+"ABEL",
+"ABET",
+"ABLE",
+"ABUT",
+"ACHE",
+"ACID",
+"ACME",
+"ACRE",
+"ACTA",
+"ACTS",
+"ADAM",
+"ADDS",
+"ADEN",
+"AFAR",
+"AFRO",
+"AGEE",
+"AHEM",
+"AHOY",
+"AIDA",
+"AIDE",
+"AIDS",
+"AIRY",
+"AJAR",
+"AKIN",
+"ALAN",
+"ALEC",
+"ALGA",
+"ALIA",
+"ALLY",
+"ALMA",
+"ALOE",
+"ALSO",
+"ALTO",
+"ALUM",
+"ALVA",
+"AMEN",
+"AMES",
+"AMID",
+"AMMO",
+"AMOK",
+"AMOS",
+"AMRA",
+"ANDY",
+"ANEW",
+"ANNA",
+"ANNE",
+"ANTE",
+"ANTI",
+"AQUA",
+"ARAB",
+"ARCH",
+"AREA",
+"ARGO",
+"ARID",
+"ARMY",
+"ARTS",
+"ARTY",
+"ASIA",
+"ASKS",
+"ATOM",
+"AUNT",
+"AURA",
+"AUTO",
+"AVER",
+"AVID",
+"AVIS",
+"AVON",
+"AVOW",
+"AWAY",
+"AWRY",
+"BABE",
+"BABY",
+"BACH",
+"BACK",
+"BADE",
+"BAIL",
+"BAIT",
+"BAKE",
+"BALD",
+"BALE",
+"BALI",
+"BALK",
+"BALL",
+"BALM",
+"BAND",
+"BANE",
+"BANG",
+"BANK",
+"BARB",
+"BARD",
+"BARE",
+"BARK",
+"BARN",
+"BARR",
+"BASE",
+"BASH",
+"BASK",
+"BASS",
+"BATE",
+"BATH",
+"BAWD",
+"BAWL",
+"BEAD",
+"BEAK",
+"BEAM",
+"BEAN",
+"BEAR",
+"BEAT",
+"BEAU",
+"BECK",
+"BEEF",
+"BEEN",
+"BEER",
+"BEET",
+"BELA",
+"BELL",
+"BELT",
+"BEND",
+"BENT",
+"BERG",
+"BERN",
+"BERT",
+"BESS",
+"BEST",
+"BETA",
+"BETH",
+"BHOY",
+"BIAS",
+"BIDE",
+"BIEN",
+"BILE",
+"BILK",
+"BILL",
+"BIND",
+"BING",
+"BIRD",
+"BITE",
+"BITS",
+"BLAB",
+"BLAT",
+"BLED",
+"BLEW",
+"BLOB",
+"BLOC",
+"BLOT",
+"BLOW",
+"BLUE",
+"BLUM",
+"BLUR",
+"BOAR",
+"BOAT",
+"BOCA",
+"BOCK",
+"BODE",
+"BODY",
+"BOGY",
+"BOHR",
+"BOIL",
+"BOLD",
+"BOLO",
+"BOLT",
+"BOMB",
+"BONA",
+"BOND",
+"BONE",
+"BONG",
+"BONN",
+"BONY",
+"BOOK",
+"BOOM",
+"BOON",
+"BOOT",
+"BORE",
+"BORG",
+"BORN",
+"BOSE",
+"BOSS",
+"BOTH",
+"BOUT",
+"BOWL",
+"BOYD",
+"BRAD",
+"BRAE",
+"BRAG",
+"BRAN",
+"BRAY",
+"BRED",
+"BREW",
+"BRIG",
+"BRIM",
+"BROW",
+"BUCK",
+"BUDD",
+"BUFF",
+"BULB",
+"BULK",
+"BULL",
+"BUNK",
+"BUNT",
+"BUOY",
+"BURG",
+"BURL",
+"BURN",
+"BURR",
+"BURT",
+"BURY",
+"BUSH",
+"BUSS",
+"BUST",
+"BUSY",
+"BYTE",
+"CADY",
+"CAFE",
+"CAGE",
+"CAIN",
+"CAKE",
+"CALF",
+"CALL",
+"CALM",
+"CAME",
+"CANE",
+"CANT",
+"CARD",
+"CARE",
+"CARL",
+"CARR",
+"CART",
+"CASE",
+"CASH",
+"CASK",
+"CAST",
+"CAVE",
+"CEIL",
+"CELL",
+"CENT",
+"CERN",
+"CHAD",
+"CHAR",
+"CHAT",
+"CHAW",
+"CHEF",
+"CHEN",
+"CHEW",
+"CHIC",
+"CHIN",
+"CHOU",
+"CHOW",
+"CHUB",
+"CHUG",
+"CHUM",
+"CITE",
+"CITY",
+"CLAD",
+"CLAM",
+"CLAN",
+"CLAW",
+"CLAY",
+"CLOD",
+"CLOG",
+"CLOT",
+"CLUB",
+"CLUE",
+"COAL",
+"COAT",
+"COCA",
+"COCK",
+"COCO",
+"CODA",
+"CODE",
+"CODY",
+"COED",
+"COIL",
+"COIN",
+"COKE",
+"COLA",
+"COLD",
+"COLT",
+"COMA",
+"COMB",
+"COME",
+"COOK",
+"COOL",
+"COON",
+"COOT",
+"CORD",
+"CORE",
+"CORK",
+"CORN",
+"COST",
+"COVE",
+"COWL",
+"CRAB",
+"CRAG",
+"CRAM",
+"CRAY",
+"CREW",
+"CRIB",
+"CROW",
+"CRUD",
+"CUBA",
+"CUBE",
+"CUFF",
+"CULL",
+"CULT",
+"CUNY",
+"CURB",
+"CURD",
+"CURE",
+"CURL",
+"CURT",
+"CUTS",
+"DADE",
+"DALE",
+"DAME",
+"DANA",
+"DANE",
+"DANG",
+"DANK",
+"DARE",
+"DARK",
+"DARN",
+"DART",
+"DASH",
+"DATA",
+"DATE",
+"DAVE",
+"DAVY",
+"DAWN",
+"DAYS",
+"DEAD",
+"DEAF",
+"DEAL",
+"DEAN",
+"DEAR",
+"DEBT",
+"DECK",
+"DEED",
+"DEEM",
+"DEER",
+"DEFT",
+"DEFY",
+"DELL",
+"DENT",
+"DENY",
+"DESK",
+"DIAL",
+"DICE",
+"DIED",
+"DIET",
+"DIME",
+"DINE",
+"DING",
+"DINT",
+"DIRE",
+"DIRT",
+"DISC",
+"DISH",
+"DISK",
+"DIVE",
+"DOCK",
+"DOES",
+"DOLE",
+"DOLL",
+"DOLT",
+"DOME",
+"DONE",
+"DOOM",
+"DOOR",
+"DORA",
+"DOSE",
+"DOTE",
+"DOUG",
+"DOUR",
+"DOVE",
+"DOWN",
+"DRAB",
+"DRAG",
+"DRAM",
+"DRAW",
+"DREW",
+"DRUB",
+"DRUG",
+"DRUM",
+"DUAL",
+"DUCK",
+"DUCT",
+"DUEL",
+"DUET",
+"DUKE",
+"DULL",
+"DUMB",
+"DUNE",
+"DUNK",
+"DUSK",
+"DUST",
+"DUTY",
+"EACH",
+"EARL",
+"EARN",
+"EASE",
+"EAST",
+"EASY",
+"EBEN",
+"ECHO",
+"EDDY",
+"EDEN",
+"EDGE",
+"EDGY",
+"EDIT",
+"EDNA",
+"EGAN",
+"ELAN",
+"ELBA",
+"ELLA",
+"ELSE",
+"EMIL",
+"EMIT",
+"EMMA",
+"ENDS",
+"ERIC",
+"EROS",
+"EVEN",
+"EVER",
+"EVIL",
+"EYED",
+"FACE",
+"FACT",
+"FADE",
+"FAIL",
+"FAIN",
+"FAIR",
+"FAKE",
+"FALL",
+"FAME",
+"FANG",
+"FARM",
+"FAST",
+"FATE",
+"FAWN",
+"FEAR",
+"FEAT",
+"FEED",
+"FEEL",
+"FEET",
+"FELL",
+"FELT",
+"FEND",
+"FERN",
+"FEST",
+"FEUD",
+"FIEF",
+"FIGS",
+"FILE",
+"FILL",
+"FILM",
+"FIND",
+"FINE",
+"FINK",
+"FIRE",
+"FIRM",
+"FISH",
+"FISK",
+"FIST",
+"FITS",
+"FIVE",
+"FLAG",
+"FLAK",
+"FLAM",
+"FLAT",
+"FLAW",
+"FLEA",
+"FLED",
+"FLEW",
+"FLIT",
+"FLOC",
+"FLOG",
+"FLOW",
+"FLUB",
+"FLUE",
+"FOAL",
+"FOAM",
+"FOGY",
+"FOIL",
+"FOLD",
+"FOLK",
+"FOND",
+"FONT",
+"FOOD",
+"FOOL",
+"FOOT",
+"FORD",
+"FORE",
+"FORK",
+"FORM",
+"FORT",
+"FOSS",
+"FOUL",
+"FOUR",
+"FOWL",
+"FRAU",
+"FRAY",
+"FRED",
+"FREE",
+"FRET",
+"FREY",
+"FROG",
+"FROM",
+"FUEL",
+"FULL",
+"FUME",
+"FUND",
+"FUNK",
+"FURY",
+"FUSE",
+"FUSS",
+"GAFF",
+"GAGE",
+"GAIL",
+"GAIN",
+"GAIT",
+"GALA",
+"GALE",
+"GALL",
+"GALT",
+"GAME",
+"GANG",
+"GARB",
+"GARY",
+"GASH",
+"GATE",
+"GAUL",
+"GAUR",
+"GAVE",
+"GAWK",
+"GEAR",
+"GELD",
+"GENE",
+"GENT",
+"GERM",
+"GETS",
+"GIBE",
+"GIFT",
+"GILD",
+"GILL",
+"GILT",
+"GINA",
+"GIRD",
+"GIRL",
+"GIST",
+"GIVE",
+"GLAD",
+"GLEE",
+"GLEN",
+"GLIB",
+"GLOB",
+"GLOM",
+"GLOW",
+"GLUE",
+"GLUM",
+"GLUT",
+"GOAD",
+"GOAL",
+"GOAT",
+"GOER",
+"GOES",
+"GOLD",
+"GOLF",
+"GONE",
+"GONG",
+"GOOD",
+"GOOF",
+"GORE",
+"GORY",
+"GOSH",
+"GOUT",
+"GOWN",
+"GRAB",
+"GRAD",
+"GRAY",
+"GREG",
+"GREW",
+"GREY",
+"GRID",
+"GRIM",
+"GRIN",
+"GRIT",
+"GROW",
+"GRUB",
+"GULF",
+"GULL",
+"GUNK",
+"GURU",
+"GUSH",
+"GUST",
+"GWEN",
+"GWYN",
+"HAAG",
+"HAAS",
+"HACK",
+"HAIL",
+"HAIR",
+"HALE",
+"HALF",
+"HALL",
+"HALO",
+"HALT",
+"HAND",
+"HANG",
+"HANK",
+"HANS",
+"HARD",
+"HARK",
+"HARM",
+"HART",
+"HASH",
+"HAST",
+"HATE",
+"HATH",
+"HAUL",
+"HAVE",
+"HAWK",
+"HAYS",
+"HEAD",
+"HEAL",
+"HEAR",
+"HEAT",
+"HEBE",
+"HECK",
+"HEED",
+"HEEL",
+"HEFT",
+"HELD",
+"HELL",
+"HELM",
+"HERB",
+"HERD",
+"HERE",
+"HERO",
+"HERS",
+"HESS",
+"HEWN",
+"HICK",
+"HIDE",
+"HIGH",
+"HIKE",
+"HILL",
+"HILT",
+"HIND",
+"HINT",
+"HIRE",
+"HISS",
+"HIVE",
+"HOBO",
+"HOCK",
+"HOFF",
+"HOLD",
+"HOLE",
+"HOLM",
+"HOLT",
+"HOME",
+"HONE",
+"HONK",
+"HOOD",
+"HOOF",
+"HOOK",
+"HOOT",
+"HORN",
+"HOSE",
+"HOST",
+"HOUR",
+"HOVE",
+"HOWE",
+"HOWL",
+"HOYT",
+"HUCK",
+"HUED",
+"HUFF",
+"HUGE",
+"HUGH",
+"HUGO",
+"HULK",
+"HULL",
+"HUNK",
+"HUNT",
+"HURD",
+"HURL",
+"HURT",
+"HUSH",
+"HYDE",
+"HYMN",
+"IBIS",
+"ICON",
+"IDEA",
+"IDLE",
+"IFFY",
+"INCA",
+"INCH",
+"INTO",
+"IONS",
+"IOTA",
+"IOWA",
+"IRIS",
+"IRMA",
+"IRON",
+"ISLE",
+"ITCH",
+"ITEM",
+"IVAN",
+"JACK",
+"JADE",
+"JAIL",
+"JAKE",
+"JANE",
+"JAVA",
+"JEAN",
+"JEFF",
+"JERK",
+"JESS",
+"JEST",
+"JIBE",
+"JILL",
+"JILT",
+"JIVE",
+"JOAN",
+"JOBS",
+"JOCK",
+"JOEL",
+"JOEY",
+"JOHN",
+"JOIN",
+"JOKE",
+"JOLT",
+"JOVE",
+"JUDD",
+"JUDE",
+"JUDO",
+"JUDY",
+"JUJU",
+"JUKE",
+"JULY",
+"JUNE",
+"JUNK",
+"JUNO",
+"JURY",
+"JUST",
+"JUTE",
+"KAHN",
+"KALE",
+"KANE",
+"KANT",
+"KARL",
+"KATE",
+"KEEL",
+"KEEN",
+"KENO",
+"KENT",
+"KERN",
+"KERR",
+"KEYS",
+"KICK",
+"KILL",
+"KIND",
+"KING",
+"KIRK",
+"KISS",
+"KITE",
+"KLAN",
+"KNEE",
+"KNEW",
+"KNIT",
+"KNOB",
+"KNOT",
+"KNOW",
+"KOCH",
+"KONG",
+"KUDO",
+"KURD",
+"KURT",
+"KYLE",
+"LACE",
+"LACK",
+"LACY",
+"LADY",
+"LAID",
+"LAIN",
+"LAIR",
+"LAKE",
+"LAMB",
+"LAME",
+"LAND",
+"LANE",
+"LANG",
+"LARD",
+"LARK",
+"LASS",
+"LAST",
+"LATE",
+"LAUD",
+"LAVA",
+"LAWN",
+"LAWS",
+"LAYS",
+"LEAD",
+"LEAF",
+"LEAK",
+"LEAN",
+"LEAR",
+"LEEK",
+"LEER",
+"LEFT",
+"LEND",
+"LENS",
+"LENT",
+"LEON",
+"LESK",
+"LESS",
+"LEST",
+"LETS",
+"LIAR",
+"LICE",
+"LICK",
+"LIED",
+"LIEN",
+"LIES",
+"LIEU",
+"LIFE",
+"LIFT",
+"LIKE",
+"LILA",
+"LILT",
+"LILY",
+"LIMA",
+"LIMB",
+"LIME",
+"LIND",
+"LINE",
+"LINK",
+"LINT",
+"LION",
+"LISA",
+"LIST",
+"LIVE",
+"LOAD",
+"LOAF",
+"LOAM",
+"LOAN",
+"LOCK",
+"LOFT",
+"LOGE",
+"LOIS",
+"LOLA",
+"LONE",
+"LONG",
+"LOOK",
+"LOON",
+"LOOT",
+"LORD",
+"LORE",
+"LOSE",
+"LOSS",
+"LOST",
+"LOUD",
+"LOVE",
+"LOWE",
+"LUCK",
+"LUCY",
+"LUGE",
+"LUKE",
+"LULU",
+"LUND",
+"LUNG",
+"LURA",
+"LURE",
+"LURK",
+"LUSH",
+"LUST",
+"LYLE",
+"LYNN",
+"LYON",
+"LYRA",
+"MACE",
+"MADE",
+"MAGI",
+"MAID",
+"MAIL",
+"MAIN",
+"MAKE",
+"MALE",
+"MALI",
+"MALL",
+"MALT",
+"MANA",
+"MANN",
+"MANY",
+"MARC",
+"MARE",
+"MARK",
+"MARS",
+"MART",
+"MARY",
+"MASH",
+"MASK",
+"MASS",
+"MAST",
+"MATE",
+"MATH",
+"MAUL",
+"MAYO",
+"MEAD",
+"MEAL",
+"MEAN",
+"MEAT",
+"MEEK",
+"MEET",
+"MELD",
+"MELT",
+"MEMO",
+"MEND",
+"MENU",
+"MERT",
+"MESH",
+"MESS",
+"MICE",
+"MIKE",
+"MILD",
+"MILE",
+"MILK",
+"MILL",
+"MILT",
+"MIMI",
+"MIND",
+"MINE",
+"MINI",
+"MINK",
+"MINT",
+"MIRE",
+"MISS",
+"MIST",
+"MITE",
+"MITT",
+"MOAN",
+"MOAT",
+"MOCK",
+"MODE",
+"MOLD",
+"MOLE",
+"MOLL",
+"MOLT",
+"MONA",
+"MONK",
+"MONT",
+"MOOD",
+"MOON",
+"MOOR",
+"MOOT",
+"MORE",
+"MORN",
+"MORT",
+"MOSS",
+"MOST",
+"MOTH",
+"MOVE",
+"MUCH",
+"MUCK",
+"MUDD",
+"MUFF",
+"MULE",
+"MULL",
+"MURK",
+"MUSH",
+"MUST",
+"MUTE",
+"MUTT",
+"MYRA",
+"MYTH",
+"NAGY",
+"NAIL",
+"NAIR",
+"NAME",
+"NARY",
+"NASH",
+"NAVE",
+"NAVY",
+"NEAL",
+"NEAR",
+"NEAT",
+"NECK",
+"NEED",
+"NEIL",
+"NELL",
+"NEON",
+"NERO",
+"NESS",
+"NEST",
+"NEWS",
+"NEWT",
+"NIBS",
+"NICE",
+"NICK",
+"NILE",
+"NINA",
+"NINE",
+"NOAH",
+"NODE",
+"NOEL",
+"NOLL",
+"NONE",
+"NOOK",
+"NOON",
+"NORM",
+"NOSE",
+"NOTE",
+"NOUN",
+"NOVA",
+"NUDE",
+"NULL",
+"NUMB",
+"OATH",
+"OBEY",
+"OBOE",
+"ODIN",
+"OHIO",
+"OILY",
+"OINT",
+"OKAY",
+"OLAF",
+"OLDY",
+"OLGA",
+"OLIN",
+"OMAN",
+"OMEN",
+"OMIT",
+"ONCE",
+"ONES",
+"ONLY",
+"ONTO",
+"ONUS",
+"ORAL",
+"ORGY",
+"OSLO",
+"OTIS",
+"OTTO",
+"OUCH",
+"OUST",
+"OUTS",
+"OVAL",
+"OVEN",
+"OVER",
+"OWLY",
+"OWNS",
+"QUAD",
+"QUIT",
+"QUOD",
+"RACE",
+"RACK",
+"RACY",
+"RAFT",
+"RAGE",
+"RAID",
+"RAIL",
+"RAIN",
+"RAKE",
+"RANK",
+"RANT",
+"RARE",
+"RASH",
+"RATE",
+"RAVE",
+"RAYS",
+"READ",
+"REAL",
+"REAM",
+"REAR",
+"RECK",
+"REED",
+"REEF",
+"REEK",
+"REEL",
+"REID",
+"REIN",
+"RENA",
+"REND",
+"RENT",
+"REST",
+"RICE",
+"RICH",
+"RICK",
+"RIDE",
+"RIFT",
+"RILL",
+"RIME",
+"RING",
+"RINK",
+"RISE",
+"RISK",
+"RITE",
+"ROAD",
+"ROAM",
+"ROAR",
+"ROBE",
+"ROCK",
+"RODE",
+"ROIL",
+"ROLL",
+"ROME",
+"ROOD",
+"ROOF",
+"ROOK",
+"ROOM",
+"ROOT",
+"ROSA",
+"ROSE",
+"ROSS",
+"ROSY",
+"ROTH",
+"ROUT",
+"ROVE",
+"ROWE",
+"ROWS",
+"RUBE",
+"RUBY",
+"RUDE",
+"RUDY",
+"RUIN",
+"RULE",
+"RUNG",
+"RUNS",
+"RUNT",
+"RUSE",
+"RUSH",
+"RUSK",
+"RUSS",
+"RUST",
+"RUTH",
+"SACK",
+"SAFE",
+"SAGE",
+"SAID",
+"SAIL",
+"SALE",
+"SALK",
+"SALT",
+"SAME",
+"SAND",
+"SANE",
+"SANG",
+"SANK",
+"SARA",
+"SAUL",
+"SAVE",
+"SAYS",
+"SCAN",
+"SCAR",
+"SCAT",
+"SCOT",
+"SEAL",
+"SEAM",
+"SEAR",
+"SEAT",
+"SEED",
+"SEEK",
+"SEEM",
+"SEEN",
+"SEES",
+"SELF",
+"SELL",
+"SEND",
+"SENT",
+"SETS",
+"SEWN",
+"SHAG",
+"SHAM",
+"SHAW",
+"SHAY",
+"SHED",
+"SHIM",
+"SHIN",
+"SHOD",
+"SHOE",
+"SHOT",
+"SHOW",
+"SHUN",
+"SHUT",
+"SICK",
+"SIDE",
+"SIFT",
+"SIGH",
+"SIGN",
+"SILK",
+"SILL",
+"SILO",
+"SILT",
+"SINE",
+"SING",
+"SINK",
+"SIRE",
+"SITE",
+"SITS",
+"SITU",
+"SKAT",
+"SKEW",
+"SKID",
+"SKIM",
+"SKIN",
+"SKIT",
+"SLAB",
+"SLAM",
+"SLAT",
+"SLAY",
+"SLED",
+"SLEW",
+"SLID",
+"SLIM",
+"SLIT",
+"SLOB",
+"SLOG",
+"SLOT",
+"SLOW",
+"SLUG",
+"SLUM",
+"SLUR",
+"SMOG",
+"SMUG",
+"SNAG",
+"SNOB",
+"SNOW",
+"SNUB",
+"SNUG",
+"SOAK",
+"SOAR",
+"SOCK",
+"SODA",
+"SOFA",
+"SOFT",
+"SOIL",
+"SOLD",
+"SOME",
+"SONG",
+"SOON",
+"SOOT",
+"SORE",
+"SORT",
+"SOUL",
+"SOUR",
+"SOWN",
+"STAB",
+"STAG",
+"STAN",
+"STAR",
+"STAY",
+"STEM",
+"STEW",
+"STIR",
+"STOW",
+"STUB",
+"STUN",
+"SUCH",
+"SUDS",
+"SUIT",
+"SULK",
+"SUMS",
+"SUNG",
+"SUNK",
+"SURE",
+"SURF",
+"SWAB",
+"SWAG",
+"SWAM",
+"SWAN",
+"SWAT",
+"SWAY",
+"SWIM",
+"SWUM",
+"TACK",
+"TACT",
+"TAIL",
+"TAKE",
+"TALE",
+"TALK",
+"TALL",
+"TANK",
+"TASK",
+"TATE",
+"TAUT",
+"TEAL",
+"TEAM",
+"TEAR",
+"TECH",
+"TEEM",
+"TEEN",
+"TEET",
+"TELL",
+"TEND",
+"TENT",
+"TERM",
+"TERN",
+"TESS",
+"TEST",
+"THAN",
+"THAT",
+"THEE",
+"THEM",
+"THEN",
+"THEY",
+"THIN",
+"THIS",
+"THUD",
+"THUG",
+"TICK",
+"TIDE",
+"TIDY",
+"TIED",
+"TIER",
+"TILE",
+"TILL",
+"TILT",
+"TIME",
+"TINA",
+"TINE",
+"TINT",
+"TINY",
+"TIRE",
+"TOAD",
+"TOGO",
+"TOIL",
+"TOLD",
+"TOLL",
+"TONE",
+"TONG",
+"TONY",
+"TOOK",
+"TOOL",
+"TOOT",
+"TORE",
+"TORN",
+"TOTE",
+"TOUR",
+"TOUT",
+"TOWN",
+"TRAG",
+"TRAM",
+"TRAY",
+"TREE",
+"TREK",
+"TRIG",
+"TRIM",
+"TRIO",
+"TROD",
+"TROT",
+"TROY",
+"TRUE",
+"TUBA",
+"TUBE",
+"TUCK",
+"TUFT",
+"TUNA",
+"TUNE",
+"TUNG",
+"TURF",
+"TURN",
+"TUSK",
+"TWIG",
+"TWIN",
+"TWIT",
+"ULAN",
+"UNIT",
+"URGE",
+"USED",
+"USER",
+"USES",
+"UTAH",
+"VAIL",
+"VAIN",
+"VALE",
+"VARY",
+"VASE",
+"VAST",
+"VEAL",
+"VEDA",
+"VEIL",
+"VEIN",
+"VEND",
+"VENT",
+"VERB",
+"VERY",
+"VETO",
+"VICE",
+"VIEW",
+"VINE",
+"VISE",
+"VOID",
+"VOLT",
+"VOTE",
+"WACK",
+"WADE",
+"WAGE",
+"WAIL",
+"WAIT",
+"WAKE",
+"WALE",
+"WALK",
+"WALL",
+"WALT",
+"WAND",
+"WANE",
+"WANG",
+"WANT",
+"WARD",
+"WARM",
+"WARN",
+"WART",
+"WASH",
+"WAST",
+"WATS",
+"WATT",
+"WAVE",
+"WAVY",
+"WAYS",
+"WEAK",
+"WEAL",
+"WEAN",
+"WEAR",
+"WEED",
+"WEEK",
+"WEIR",
+"WELD",
+"WELL",
+"WELT",
+"WENT",
+"WERE",
+"WERT",
+"WEST",
+"WHAM",
+"WHAT",
+"WHEE",
+"WHEN",
+"WHET",
+"WHOA",
+"WHOM",
+"WICK",
+"WIFE",
+"WILD",
+"WILL",
+"WIND",
+"WINE",
+"WING",
+"WINK",
+"WINO",
+"WIRE",
+"WISE",
+"WISH",
+"WITH",
+"WOLF",
+"WONT",
+"WOOD",
+"WOOL",
+"WORD",
+"WORE",
+"WORK",
+"WORM",
+"WORN",
+"WOVE",
+"WRIT",
+"WYNN",
+"YALE",
+"YANG",
+"YANK",
+"YARD",
+"YARN",
+"YAWL",
+"YAWN",
+"YEAH",
+"YEAR",
+"YELL",
+"YOGA",
+"YOKE"
+};
+
+/* Encode 8 bytes in 'c' as a string of English words.
+ * Returns a pointer to a static buffer
+ */
+char *
+btoe(engout,c)
+char *c, *engout;
+{
+ char cp[9]; /* add in room for the parity 2 bits*/
+ int p,i ;
+
+ engout[0] = '\0';
+ memcpy(cp, c,8);
+ /* compute parity */
+ for(p = 0,i = 0; i < 64;i += 2)
+ p += extract(cp,i,2);
+
+ cp[8] = (char)p << 6;
+ strncat(engout,&Wp[extract(cp, 0,11)][0],4);
+ strcat(engout," ");
+ strncat(engout,&Wp[extract(cp,11,11)][0],4);
+ strcat(engout," ");
+ strncat(engout,&Wp[extract(cp,22,11)][0],4);
+ strcat(engout," ");
+ strncat(engout,&Wp[extract(cp,33,11)][0],4);
+ strcat(engout," ");
+ strncat(engout,&Wp[extract(cp,44,11)][0],4);
+ strcat(engout," ");
+ strncat(engout,&Wp[extract(cp,55,11)][0],4);
+#ifdef notdef
+ printf("engout is %s\n\r",engout);
+#endif
+ return(engout);
+}
+
+/* convert English to binary
+ * returns 1 OK - all good words and parity is OK
+ * 0 word not in data base
+ * -1 badly formed in put ie > 4 char word
+ * -2 words OK but parity is wrong
+ */
+int
+etob(out, e)
+char *out;
+char *e;
+{
+ char *word, *cp;
+ int i, v,l, low,high;
+ unsigned int p;
+ char b[9];
+ char input[36];
+
+ if(e == NULL)
+ return -1;
+
+ strncpy(input,e,sizeof(input));
+ cp = input;
+ memset(b, 0, sizeof(b));
+ memset(out, 0, 8);
+ for(i=0,p=0;i<6;i++,p+=11){
+ while ((word = strsep(&cp, " ")) != NULL && *word == '\0')
+ ;
+ if (word == NULL)
+ return -1;
+ l = strlen(word);
+ if(l > 4 || l < 1){
+ return -1;
+ } else if(l < 4){
+ low = 0;
+ high = 570;
+ } else {
+ low = 571;
+ high = 2047;
+ }
+ standard(word);
+ if( (v = wsrch(word,low,high)) < 0 )
+ return 0;
+ insert(b,v,(int)p,11);
+ }
+
+ /* now check the parity of what we got */
+ for(p = 0, i = 0; i < 64; i +=2)
+ p += extract(b, i, 2);
+
+ if( (p & 3) != extract(b, 64,2) )
+ return -2;
+
+ memcpy(out,b,8);
+
+ return 1;
+}
+/* Display 8 bytes as a series of 16-bit hex digits */
+char *
+put8(out,s)
+char *out;
+char *s;
+{
+ sprintf(out,"%02X%02X %02X%02X %02X%02X %02X%02X",
+ s[0] & 0xff,s[1] & 0xff,s[2] & 0xff,
+ s[3] & 0xff,s[4] & 0xff,s[5] & 0xff,
+ s[6] & 0xff,s[7] & 0xff);
+ return out;
+}
+#ifdef notdef
+/* Encode 8 bytes in 'cp' as stream of ascii letters.
+ * Provided as a possible alternative to btoe()
+ */
+char *
+btoc(cp)
+char *cp;
+{
+ int i;
+ static char out[31];
+
+ /* code out put by characters 6 bits each added to 0x21 (!)*/
+ for(i=0;i <= 10;i++){
+ /* last one is only 4 bits not 6*/
+ out[i] = '!'+ extract(cp,6*i,i >= 10 ? 4:6);
+ }
+ out[i] = '\0';
+ return(out);
+}
+#endif
+
+/* Internal subroutines for word encoding/decoding */
+
+/* Dictionary binary search */
+static int
+wsrch(w,low,high)
+char *w;
+int low, high;
+{
+ int i,j;
+
+ for(;;){
+ i = (low + high)/2;
+ if((j = strncmp(w,Wp[i],4)) == 0)
+ return i; /* Found it */
+ if(high == low+1){
+ /* Avoid effects of integer truncation in /2 */
+ if(strncmp(w,Wp[high],4) == 0)
+ return high;
+ else
+ return -1;
+ }
+ if(low >= high)
+ return -1; /* I don't *think* this can happen...*/
+ if(j < 0)
+ high = i; /* Search lower half */
+ else
+ low = i; /* Search upper half */
+ }
+}
+static void
+insert(s, x, start, length)
+char *s;
+int x;
+int start, length;
+{
+ unsigned char cl;
+ unsigned char cc;
+ unsigned char cr;
+ unsigned long y;
+ int shift;
+
+ assert(length <= 11);
+ assert(start >= 0);
+ assert(length >= 0);
+ assert(start +length <= 66);
+
+ shift = ((8 -(( start + length) % 8))%8);
+ y = (long) x << shift;
+ cl = (y >> 16) & 0xff;
+ cc = (y >> 8) & 0xff;
+ cr = y & 0xff;
+ if(shift + length > 16){
+ s[start /8] |= cl;
+ s[start/8 +1] |= cc;
+ s[start/8 +2] |= cr;
+ } else if(shift +length > 8){
+ s[start/8] |= cc;
+ s[start/8 + 1] |= cr;
+ } else {
+ s[start/8] |= cr;
+ }
+}
+
+static void
+standard(word)
+register char *word;
+{
+ while(*word){
+ if(!isascii(*word))
+ break;
+ if(islower(*word))
+ *word = toupper(*word);
+ if(*word == '1')
+ *word = 'L';
+ if(*word == '0')
+ *word = 'O';
+ if(*word == '5')
+ *word = 'S';
+ word++;
+ }
+}
+
+/* Extract 'length' bits from the char array 's' starting with bit 'start' */
+static unsigned long
+extract(s, start, length)
+char *s;
+int start, length;
+{
+ unsigned char cl;
+ unsigned char cc;
+ unsigned char cr;
+ unsigned long x;
+
+ assert(length <= 11);
+ assert(start >= 0);
+ assert(length >= 0);
+ assert(start +length <= 66);
+
+ cl = s[start/8];
+ cc = s[start/8 +1];
+ cr = s[start/8 +2];
+ x = ((long)(cl<<8 | cc) <<8 | cr) ;
+ x = x >> (24 - (length + (start %8)));
+ x =( x & (0xffff >> (16-length) ) );
+ return(x);
+}
+
diff --git a/lib/libskey/skey.1 b/lib/libskey/skey.1
new file mode 100644
index 0000000..6038d61
--- /dev/null
+++ b/lib/libskey/skey.1
@@ -0,0 +1,60 @@
+.ll 6i
+.pl 10.5i
+.\" @(#)skey.1 1.1 10/28/93
+.\" $FreeBSD$
+.\"
+.lt 6.0i
+.TH KEY 1 "28 October 1993"
+.AT 3
+.SH NAME
+S/key \- A procedure to use one time passwords for accessing computer systems.
+.SH DESCRIPTION
+.I S/key
+is a procedure for using one time password to authenticate access to
+computer systems. It uses 64 bits of information transformed by the
+MD4 algorithm. The user supplies the 64 bits in the form of 6 English
+words that are generated by a secure computer.
+Example use of the S/key program
+.I key
+.sp
+ Usage example:
+.sp 0
+ >key 99 th91334
+.sp 0
+ Enter password: <your secret password is entered here>
+.sp 0
+ OMEN US HORN OMIT BACK AHOY
+.sp 0
+ >
+.sp
+The programs that are part of the S/Key system are keyinit, key, and
+keyinfo. Keyinit is used to get your ID set up, key is
+used to get the one time password each time,
+keyinfo is used to extract information from the S/Key database.
+.sp
+When you run "keyinit" you inform the system of your
+secret password. Running "key" then generates the
+one-time passwords, and also requires your secret
+password. If however, you misspell your password
+while running "key", you will get a list of passwords
+that will not work, and no indication about the problem.
+.sp
+Password sequence numbers count backward from 99. If you
+don't know this, the syntax for "key" will be confusing.
+.sp
+You can enter the passwords using small letters, even
+though the "key" program gives them in caps.
+.sp
+Macintosh and a general purpose PC use
+are available.
+.sp
+Under FreeBSD, you can control, with /etc/skey.access, from which
+hosts and/or networks the use of S/Key passwords is obligated.
+.LP
+.SH SEE ALSO
+.BR keyinit(1),
+.BR key(1),
+.BR keyinfo(1)
+.BR skey.access(5)
+.SH AUTHOR
+Phil Karn, Neil M. Haller, John S. Walden, Scott Chasin
diff --git a/lib/libskey/skey.3 b/lib/libskey/skey.3
new file mode 100644
index 0000000..060fc7d
--- /dev/null
+++ b/lib/libskey/skey.3
@@ -0,0 +1,161 @@
+.\" Copyright (c) 1996
+.\" David L. Nugent. All Rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 22, 1996
+.Dt SKEY 3
+.Os
+.Sh NAME
+.Nm skeylookup ,
+.Nm skeyverify ,
+.Nm skeychallenge ,
+.Nm skeyinfo ,
+.Nm skeyaccess ,
+.Nm skey_getpass ,
+.Nm skey_crypt
+.Nd Library routines for S/Key password control table access
+.Sh SYNOPSIS
+.Fd #include <stdio.h>
+.Fd #include <skey.h>
+.Ft int
+.Fn skeylookup "struct skey *mp" "const char *name"
+.Ft int
+.Fn skeyverify "struct skey *mp" "char *response"
+.Ft int
+.Fn skeychallenge "struct skey *mp" "const char *name" "char *challenge"
+.Ft int
+.Fn skeyinfo "struct skey *mp" "const char *name" "char *ss"
+.Ft int
+.Fn skeyaccess "char *user" "const char *port" "const char *host" "const char *addr"
+.Ft char *
+.Fn skey_getpass "const char *prompt" "struct passwd *pwd" "int pwok"
+.Ft const char *
+.Fn skey_crypt "char *pp" "char *salt" "struct passwd *pwd" "int pwok"
+.Sh DESCRIPTION
+These routes support the S/Key one time password system used for
+accessing computer systems.
+See
+.Xr skey 1
+for more information about the S/Key system itself.
+.Pp
+.Pp
+.Fn skeylookup
+finds an entry in the one-time password database.
+On success (an entry is found corresponding to the given name),
+they skey structure passed by the caller is filled and 0 is
+returned, with the file read/write pointer positioned at the
+beginning of the record found.
+If no entry is found corresponding to the given name, the file
+read/write pointer is positioned at end of file and the routine
+returns 1.
+If the database cannot be opened or an access error occurs,
+.Fn skeylookup
+returns -1.
+.Pp
+The
+.Fn skeyinfo
+function looks up skey info for user 'name'.
+If successful, the caller's skey structure is filled and
+.Fn skeyinfo
+returns 0.
+If an optional challenge string buffer is given, it is updated.
+If unsuccessful (e.g. if the name is unknown, or the database
+cannot be accessed) -1 is returned.
+.Pp
+.Fn skeychallenge
+returns an skey challenge string for 'name'.
+If successful, the caller's skey structure is filled, and
+the function returns 0, with the file read/write pointer
+left at the start of the record.
+If unsuccessful (ie. the name was not found), the function
+returns -1 and the database is closed.
+.Pp
+.Fn skeyverify
+verifies a response to an s/key challenge.
+If this function returns 0, the verify was successful and
+the database was updated.
+If 1 is returned, the verify failed and the database remains
+unchanged.
+If -1 is returned, some sort of error occurred with the database,
+and the database is left unchanged.
+The s/key database is always closed by this call.
+.Pp
+The
+.Fn skey_getpass
+function may be used to read regular or s/key passwords.
+The prompt to use is passed to the function, along with the
+full (secure) struct passwd for the user to be verified.
+.Fn skey_getpass
+uses the standard library getpass on the first attempt at
+retrieving the user's password, and if that is blank, turns
+echo back on and retrieves the S/Key password.
+In either case, the entered string is returned back to the
+caller.
+.Pp
+The
+.Fn skey_crypt
+is a wrapper function for the standard library
+.Xr crypt 3 ,
+which returns the encrypted UNIX password if either the given
+s/key or regular passwords are ok.
+.Fn skey_crypt
+first attempts verification of the given password via the skey
+method, and will return the encrypted password from the
+passwd structure if it can be verified, as though the user had
+actually entered the correct UNIX password.
+If s/key password verification does not work, then the password
+is encrypted in the usual way and the result passed back to the
+caller.
+If the passwd structure pointer is NULL,
+.Fn skey_crypt
+returns a non-NULL string which could not possibly be a valid
+UNIX password (namely, a string containing ":").
+.Pp
+The
+.Fn skeyaccess
+function determines whether traditional UNIX (non-S/Key) passwords
+are permitted for any combination of user name, group member,
+terminal port, host name, and network. If UNIX passwords are allowed,
+.Fn skeyaccess
+returns a non-zero value. If UNIX passwords are not allowed, it
+returns 0. See
+.Xr skey.access 5
+for more information on the layout and structure of the
+skey.access configuration file which this function uses.
+.Sh RETURN VALUES
+See above.
+.Sh SEE ALSO
+.Xr skey 1 ,
+.Xr skey.access 5
+.Sh BUGS
+No advisory locking is done on the s/key database to guard against
+simultaneous access from multiple processes.
+This is not normally a problem when keys are added to or updated
+in the file, but may be problematic when keys are removed.
+.Sh AUTHORS
+.An Phil Karn ,
+.An Neil M. Haller ,
+.An John S. Walden ,
+.An Scott Chasin
diff --git a/lib/libskey/skey.access.5 b/lib/libskey/skey.access.5
new file mode 100644
index 0000000..caeb56d
--- /dev/null
+++ b/lib/libskey/skey.access.5
@@ -0,0 +1,136 @@
+.\" $FreeBSD$
+.\"
+.TH SKEY.ACCESS 5
+.SH NAME
+skey.access \- S/Key password control table
+.SH DESCRIPTION
+The S/Key password control table (\fI/etc/skey.access\fR) is used by
+\fIlogin\fR-like programs to determine when UNIX passwords may be used
+to access the system.
+.IP \(bu
+When the table does not exist, there are no password restrictions. The
+user may enter the UNIX password or the S/Key one.
+.IP \(bu
+When the table does exist, UNIX passwords are permitted only when
+explicitly specified.
+.IP \(bu
+For the sake of sanity, UNIX passwords are always permitted on the
+systems console.
+.SH "TABLE FORMAT"
+The format of the table is one rule per line. Rules are matched in
+order. The search terminates when the first matching rule is found, or
+when the end of the table is reached.
+.PP
+Rules have the form:
+.sp
+.in +5
+permit condition condition...
+.br
+deny condition condition...
+.in
+.PP
+where
+.I permit
+and
+.I deny
+may be followed by zero or more conditions. Comments begin with a `#\'
+character, and extend through the end of the line. Empty lines or
+lines with only comments are ignored.
+.PP
+A rule is matched when all conditions are satisfied. A rule without
+conditions is always satisfied. For example, the last entry could
+be a line with just the word
+.I deny
+on it.
+.SH CONDITIONS
+.IP "hostname wzv.win.tue.nl"
+True when the login comes from host wzv.win.tue.nl.
+See the WARNINGS section below.
+.IP "internet 131.155.210.0 255.255.255.0"
+True when the remote host has an internet address in network
+131.155.210. The general form of a net/mask rule is:
+.sp
+.ti +5
+internet net mask
+.sp
+The expression is true when the host has an internet address for which
+the bitwise and of
+.I address
+and
+.I mask
+equals
+.IR net.
+See the WARNINGS section below.
+.IP "port ttya"
+True when the login terminal is equal to
+.IR /dev/ttya .
+Remember that UNIX passwords are always permitted with logins on the
+system console.
+.IP "user uucp"
+True when the user attempts to log in as
+.IR uucp .
+.IP "group wheel"
+True when the user attempts to log in as a member of the
+.I wheel
+group.
+.SH COMPATIBILITY
+For the sake of backwards compatibility, the
+.I internet
+keyword may be omitted from net/mask patterns.
+.SH WARNINGS
+When the S/Key control table (\fI/etc/skey.access\fR)
+exists, users without S/Key passwords will be able to login only
+where its rules allow the use of UNIX passwords. In particular, this
+means that an invocation of \fIlogin(1)\fR in a pseudo-tty (e.g. from
+within \fIxterm(1)\fR or \fIscreen(1)\fR) will be treated as a login
+that is neither from the console nor from the network, mandating the use
+of an S/Key password. Such an invocation of \fIlogin(1)\fR will necessarily
+fail for those users who do not have an S/Key password.
+.PP
+Several rule types depend on host name or address information obtained
+through the network. What follows is a list of conceivable attacks to
+force the system to permit UNIX passwords.
+.IP "Host address spoofing (source routing)"
+An intruder configures a local interface to an address in a trusted
+network and connects to the victim using that source address. Given
+the wrong client address, the victim draws the wrong conclusion from
+rules based on host addresses or from rules based on host names derived
+from addresses.
+.sp
+Remedies: (1) do not permit UNIX passwords with network logins; (2)
+use network software that discards source routing information (e.g.
+a tcp wrapper).
+.PP
+Almost every network server must look up the client host name using the
+client network address. The next obvious attack therefore is:
+.IP "Host name spoofing (bad PTR record)"
+An intruder manipulates the name server system so that the client
+network address resolves to the name of a trusted host. Given the
+wrong host name, the victim draws the wrong conclusion from rules based
+on host names, or from rules based on addresses derived from host
+names.
+.sp
+Remedies: (1) do not permit UNIX passwords with network logins; (2) use
+network software that verifies that the hostname resolves to the client
+network address (e.g. a tcp wrapper).
+.PP
+Some applications, such as the UNIX login program, must look up the
+client network address using the client host name. In addition to the
+previous two attacks, this opens up yet another possibility:
+.IP "Host address spoofing (extra A record)"
+An intruder manipulates the name server system so that the client host
+name (also) resolves to a trusted address.
+.sp
+Remedies: (1) do not permit UNIX passwords with network logins; (2)
+the skeyaccess() routines ignore network addresses that appear to
+belong to someone else.
+.SH DIAGNOSTICS
+Syntax errors are reported to the syslogd. When an error is found
+the rule is skipped.
+.SH FILES
+/etc/skey.access, password control table
+.SH AUTHOR
+.nf
+Wietse Venema
+Eindhoven University of Technology
+The Netherlands
diff --git a/lib/libskey/skey.h b/lib/libskey/skey.h
new file mode 100644
index 0000000..e62d507
--- /dev/null
+++ b/lib/libskey/skey.h
@@ -0,0 +1,60 @@
+#ifndef _SKEY_H_
+#define _SKEY_H_
+
+#include <sys/cdefs.h>
+
+/* Server-side data structure for reading keys file during login */
+struct skey {
+ FILE *keyfile;
+ char buf[256];
+ char *logname;
+ int n;
+ char *seed;
+ char *val;
+ long recstart; /*needed so reread of buffer is efficient*/
+};
+
+#ifdef _SKEY_INTERNAL
+/* Client-side structure for scanning data stream for challenge */
+struct mc {
+ char buf[256];
+ int skip;
+ int cnt;
+};
+
+#define atob8 _sk_atob8
+#define btoa8 _sk_btoa8
+#define btoe _sk_btoe
+#define etob _sk_etob
+#define f _sk_f
+#define htoi _sk_htoi
+#define keycrunch _sk_keycrunch
+#define put8 _sk_put8
+#define readpass _sk_readpass
+#define rip _sk_rip
+#define sevenbit _sk_sevenbit
+
+void f __P((char *x));
+int keycrunch __P((char *result,const char *seed,const char *passwd));
+char *btoe __P((char *engout,char *c));
+char *put8 __P((char *out,char *s));
+int atob8 __P((char *out, char *in));
+int btoa8 __P((char *out, char *in));
+int htoi __P((char c));
+int etob __P((char *out,char *e));
+void sevenbit __P((char *s));
+char *readpass __P((char *buf, int n));
+void rip __P((char *buf));
+#endif /* _SKEY_INTERNAL */
+
+/* Simplified application programming interface. */
+#include <pwd.h>
+int skeylookup __P((struct skey *mp, const char *name));
+int skeyverify __P((struct skey *mp, char *response));
+int skeychallenge __P((struct skey *mp, const char *name, char *challenge));
+int skeyinfo __P((struct skey *mp, const char* name, char *ss));
+int skeyaccess __P((char *user, const char *port, const char *host, const char *addr));
+char *skey_getpass __P((const char *prompt, struct passwd * pwd, int pwok));
+const char *skey_crypt __P((char *pp, char *salt, struct passwd *pwd, int pwok));
+
+#endif /* _SKEY_H_ */
diff --git a/lib/libskey/skey_crypt.c b/lib/libskey/skey_crypt.c
new file mode 100644
index 0000000..4e3a141
--- /dev/null
+++ b/lib/libskey/skey_crypt.c
@@ -0,0 +1,38 @@
+/* Author: Wietse Venema, Eindhoven University of Technology. */
+
+#include <string.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <unistd.h>
+
+#include "skey.h"
+
+/* skey_crypt - return encrypted UNIX passwd if s/key or regular password ok */
+
+const char *skey_crypt(pp, salt, pwd, pwok)
+char *pp;
+char *salt;
+struct passwd *pwd;
+int pwok;
+{
+ struct skey skey;
+ char *p;
+
+ /* Try s/key authentication even when the UNIX password is permitted. */
+
+ if (pwd != 0 && skeyinfo(&skey, pwd->pw_name, (char *) 0) == 0
+ && skeyverify(&skey, pp) == 0) {
+ /* s/key authentication succeeded */
+ return (pwd->pw_passwd);
+ }
+
+ /* When s/key authentication does not work, always invoke crypt(). */
+
+ p = crypt(pp, salt);
+ if (pwok && pwd != 0 && strcmp(p, pwd->pw_passwd) == 0)
+ return (pwd->pw_passwd);
+
+ /* The user does not exist or entered bad input. */
+
+ return (":");
+}
diff --git a/lib/libskey/skey_getpass.c b/lib/libskey/skey_getpass.c
new file mode 100644
index 0000000..c3f5432
--- /dev/null
+++ b/lib/libskey/skey_getpass.c
@@ -0,0 +1,37 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <skey.h>
+
+/* skey_getpass - read regular or s/key password */
+
+char *skey_getpass(prompt, pwd, pwok)
+const char *prompt;
+struct passwd *pwd;
+int pwok;
+{
+ static char buf[128];
+ struct skey skey;
+ char *pass;
+ int sflag;
+
+ /* Attempt an s/key challenge. */
+ sflag = (pwd == NULL || skeyinfo(&skey, pwd->pw_name, buf));
+ if (!sflag) {
+ printf("%s\n", buf);
+ if (!pwok)
+ printf("(s/key required)\n");
+ }
+
+ pass = getpass(prompt);
+
+ /* Give S/Key users a chance to do it with echo on. */
+ if (!sflag && !feof(stdin) && *pass == '\0') {
+ fputs(" (turning echo on)\n", stdout);
+ fputs(prompt, stdout);
+ fflush(stdout);
+ fgets(buf, sizeof(buf), stdin);
+ rip(buf);
+ return (buf);
+ } else
+ return (pass);
+}
diff --git a/lib/libskey/skeyaccess.c b/lib/libskey/skeyaccess.c
new file mode 100644
index 0000000..b5796ab
--- /dev/null
+++ b/lib/libskey/skeyaccess.c
@@ -0,0 +1,487 @@
+ /*
+ * Figure out if UNIX passwords are permitted for any combination of user
+ * name, group member, terminal port, host_name or network:
+ *
+ * Programmatic interface: skeyaccess(user, port, host, addr)
+ *
+ * All arguments are null-terminated strings. Specify a null character pointer
+ * where information is not available.
+ *
+ * When no address information is given this code performs the host (internet)
+ * address lookup itself. It rejects addresses that appear to belong to
+ * someone else.
+ *
+ * When compiled with -DPERMIT_CONSOLE always permits UNIX passwords with
+ * console logins, no matter what the configuration file says.
+ *
+ * To build a stand-alone test version, compile with -DTEST and run it off an
+ * skey.access file in the current directory:
+ *
+ * Command-line interface: ./skeyaccess user port [host_or_ip_addr]
+ *
+ * Errors are reported via syslogd.
+ *
+ * Author: Wietse Venema, Eindhoven University of Technology.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <grp.h>
+#include <ctype.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/param.h>
+
+#include "pathnames.h"
+
+ /*
+ * Token input with one-deep pushback.
+ */
+static char *prev_token = 0; /* push-back buffer */
+static char *line_pointer = NULL;
+static char *first_token __P((char *, int, FILE *));
+static int line_number;
+static void unget_token __P((char *));
+static char *get_token __P((void));
+static char *need_token __P((void));
+static char *need_internet_addr __P((void));
+
+ /*
+ * Various forms of token matching.
+ */
+#define match_host_name(l) match_token((l)->host_name)
+#define match_port(l) match_token((l)->port)
+#define match_user(l) match_token((l)->user)
+struct login_info;
+static int match_internet_addr __P((struct login_info *));
+static int match_group __P((struct login_info *));
+static int match_token __P((char *));
+static int is_internet_addr __P((char *));
+static struct in_addr *convert_internet_addr __P((char *));
+static struct in_addr *lookup_internet_addr __P((char *));
+
+#define MAX_ADDR 32
+#define PERMIT 1
+#define DENY 0
+
+#ifndef CONSOLE
+#define CONSOLE "console"
+#endif
+#ifndef VTY_PREFIX
+#define VTY_PREFIX "ttyv"
+#endif
+
+struct login_info {
+ char *host_name; /* host name */
+ struct in_addr *internet_addr; /* null terminated list */
+ char *user; /* user name */
+ char *port; /* login port */
+};
+
+static int _skeyaccess __P((FILE *, struct login_info *));
+int skeyaccess __P((char *, char *, char *, char *));
+
+/* skeyaccess - find out if UNIX passwords are permitted */
+
+int skeyaccess(user, port, host, addr)
+char *user;
+char *port;
+char *host;
+char *addr;
+{
+ FILE *fp;
+ struct login_info login_info;
+ int result;
+
+ /*
+ * Assume no restriction on the use of UNIX passwords when the s/key
+ * acces table does not exist.
+ */
+ if ((fp = fopen(_PATH_SKEYACCESS, "r")) == 0) {
+#ifdef TEST
+ fprintf(stderr, "No file %s, thus no access control\n", _PATH_SKEYACCESS);
+#endif
+ return (PERMIT);
+ }
+
+ /*
+ * Bundle up the arguments in a structure so we won't have to drag around
+ * boring long argument lists.
+ *
+ * Look up the host address when only the name is given. We try to reject
+ * addresses that belong to someone else.
+ */
+ login_info.user = user;
+ login_info.port = port;
+
+ if (host != 0 && !is_internet_addr(host)) {
+ login_info.host_name = host;
+ } else {
+ login_info.host_name = 0;
+ }
+
+ if (addr != 0 && is_internet_addr(addr)) {
+ login_info.internet_addr = convert_internet_addr(addr);
+ } else if (host != 0) {
+ if (is_internet_addr(host)) {
+ login_info.internet_addr = convert_internet_addr(host);
+ } else {
+ login_info.internet_addr = lookup_internet_addr(host);
+ }
+ } else {
+ login_info.internet_addr = 0;
+ }
+
+ /*
+ * Print what we think the user wants us to do.
+ */
+#ifdef TEST
+ printf("port: %s\n", login_info.port);
+ printf("user: %s\n", login_info.user);
+ printf("host: %s\n", login_info.host_name ? login_info.host_name : "none");
+ printf("addr: ");
+ if (login_info.internet_addr == 0) {
+ printf("none\n");
+ } else {
+ int i;
+
+ for (i = 0; login_info.internet_addr[i].s_addr; i++)
+ printf("%s%s", login_info.internet_addr[i].s_addr == -1 ?
+ "(see error log)" : inet_ntoa(login_info.internet_addr[i]),
+ login_info.internet_addr[i + 1].s_addr ? " " : "\n");
+ }
+#endif
+ result = _skeyaccess(fp, &login_info);
+ fclose(fp);
+ return (result);
+}
+
+/* _skeyaccess - find out if UNIX passwords are permitted */
+
+static int _skeyaccess(fp, login_info)
+FILE *fp;
+struct login_info *login_info;
+{
+ char buf[BUFSIZ];
+ char *tok;
+ int match;
+ int permission=DENY;
+
+#ifdef PERMIT_CONSOLE
+ if (login_info->port != 0 &&
+ (strcmp(login_info->port, CONSOLE) == 0 ||
+ strncmp(login_info->port, VTY_PREFIX, sizeof(VTY_PREFIX) - 1) == 0
+ )
+ )
+ return (1);
+#endif
+
+ /*
+ * Scan the s/key access table until we find an entry that matches. If no
+ * match is found, assume that UNIX passwords are disallowed.
+ */
+ match = 0;
+ while (match == 0 && (tok = first_token(buf, sizeof(buf), fp))) {
+ if (strncasecmp(tok, "permit", 4) == 0) {
+ permission = PERMIT;
+ } else if (strncasecmp(tok, "deny", 4) == 0) {
+ permission = DENY;
+ } else {
+ syslog(LOG_ERR, "%s: line %d: bad permission: %s",
+ _PATH_SKEYACCESS, line_number, tok);
+ continue; /* error */
+ }
+
+ /*
+ * Process all conditions in this entry until we find one that fails.
+ */
+ match = 1;
+ while (match != 0 && (tok = get_token())) {
+ if (strcasecmp(tok, "hostname") == 0) {
+ match = match_host_name(login_info);
+ } else if (strcasecmp(tok, "port") == 0) {
+ match = match_port(login_info);
+ } else if (strcasecmp(tok, "user") == 0) {
+ match = match_user(login_info);
+ } else if (strcasecmp(tok, "group") == 0) {
+ match = match_group(login_info);
+ } else if (strcasecmp(tok, "internet") == 0) {
+ match = match_internet_addr(login_info);
+ } else if (is_internet_addr(tok)) {
+ unget_token(tok);
+ match = match_internet_addr(login_info);
+ } else {
+ syslog(LOG_ERR, "%s: line %d: bad condition: %s",
+ _PATH_SKEYACCESS, line_number, tok);
+ match = 0;
+ }
+ }
+ }
+ return (match ? permission : DENY);
+}
+
+/* match_internet_addr - match internet network address */
+
+static int match_internet_addr(login_info)
+struct login_info *login_info;
+{
+ char * tok;
+ u_int32_t pattern;
+ u_int32_t mask;
+ struct in_addr *addrp;
+
+ if (login_info->internet_addr == 0)
+ return (0);
+ if ((tok = need_internet_addr()) == 0)
+ return (0);
+ pattern = inet_addr(tok);
+ if ((tok = need_internet_addr()) == 0)
+ return (0);
+ mask = inet_addr(tok);
+
+ /*
+ * See if any of the addresses matches a pattern in the control file. We
+ * have already tried to drop addresses that belong to someone else.
+ */
+
+ for (addrp = login_info->internet_addr; addrp->s_addr; addrp++)
+ if (addrp->s_addr != INADDR_NONE && (addrp->s_addr & mask) == pattern)
+ return (1);
+ return (0);
+}
+
+/* match_group - match username against group */
+
+static int match_group(login_info)
+struct login_info *login_info;
+{
+ struct group *group;
+ char *tok;
+ char **memp;
+
+ if ((tok = need_token()) && (group = getgrnam(tok))) {
+ for (memp = group->gr_mem; *memp; memp++)
+ if (strcmp(login_info->user, *memp) == 0)
+ return (1);
+ }
+ return (0); /* XXX endgrent() */
+}
+
+/* match_token - get and match token */
+
+static int match_token(str)
+char *str;
+{
+ char *tok;
+
+ return (str && (tok = need_token()) && strcasecmp(str, tok) == 0);
+}
+
+/* first_token - read line and return first token */
+
+static char *first_token(buf, len, fp)
+char *buf;
+int len;
+FILE *fp;
+{
+ char *cp;
+
+ prev_token = 0;
+ for (;;) {
+ if (fgets(buf, len, fp) == 0)
+ return (0);
+ line_number++;
+ buf[strcspn(buf, "\r\n#")] = 0;
+#ifdef TEST
+ if (buf[0])
+ printf("rule: %s\n", buf);
+#endif
+ line_pointer = buf;
+ while ((cp = strsep(&line_pointer, " \t")) != NULL && *cp == '\0')
+ ;
+ if (cp != NULL)
+ return (cp);
+ }
+}
+
+/* unget_token - push back last token */
+
+static void unget_token(cp)
+char *cp;
+{
+ prev_token = cp;
+}
+
+/* get_token - retrieve next token from buffer */
+
+static char *get_token()
+{
+ char *cp;
+
+ if ( (cp = prev_token) ) {
+ prev_token = 0;
+ } else {
+ while ((cp = strsep(&line_pointer, " \t")) != NULL && *cp == '\0')
+ ;
+ }
+ return (cp);
+}
+
+/* need_token - complain if next token is not available */
+
+static char *need_token()
+{
+ char *cp;
+
+ if ((cp = get_token()) == 0)
+ syslog(LOG_ERR, "%s: line %d: premature end of rule",
+ _PATH_SKEYACCESS, line_number);
+ return (cp);
+}
+
+/* need_internet_addr - complain if next token is not an internet address */
+
+static char *need_internet_addr()
+{
+ char *cp;
+
+ if ((cp = get_token()) == 0) {
+ syslog(LOG_ERR, "%s: line %d: internet address expected",
+ _PATH_SKEYACCESS, line_number);
+ return (0);
+ } else if (!is_internet_addr(cp)) {
+ syslog(LOG_ERR, "%s: line %d: bad internet address: %s",
+ _PATH_SKEYACCESS, line_number, cp);
+ return (0);
+ } else {
+ return (cp);
+ }
+}
+
+/* is_internet_addr - determine if string is a dotted quad decimal address */
+
+static int is_internet_addr(str)
+char *str;
+{
+ int in_run = 0;
+ int runs = 0;
+
+ /* Count the number of runs of characters between the dots. */
+
+ while (*str) {
+ if (*str == '.') {
+ in_run = 0;
+ } else {
+ if (!isdigit(*str))
+ return (0);
+ if (in_run == 0) {
+ in_run = 1;
+ runs++;
+ }
+ }
+ str++;
+ }
+ return (runs == 4);
+}
+
+/* lookup_internet_addr - look up internet addresses with extreme prejudice */
+
+static struct in_addr *lookup_internet_addr(host)
+char *host;
+{
+ struct hostent *hp;
+ static struct in_addr list[MAX_ADDR + 1];
+ char buf[MAXHOSTNAMELEN + 1];
+ int length;
+ int i;
+
+ if ((hp = gethostbyname(host)) == 0 || hp->h_addrtype != AF_INET)
+ return (0);
+
+ /*
+ * Save a copy of the results before gethostbyaddr() clobbers them.
+ */
+
+ for (i = 0; i < MAX_ADDR && hp->h_addr_list[i]; i++)
+ memcpy((char *) &list[i],
+ hp->h_addr_list[i], (size_t)hp->h_length);
+ list[i].s_addr = 0;
+
+ strncpy(buf, hp->h_name, MAXHOSTNAMELEN);
+ buf[MAXHOSTNAMELEN] = 0;
+ length = hp->h_length;
+
+ /*
+ * Wipe addresses that appear to belong to someone else. We will get
+ * false alarms when when the hostname comes from DNS, while its
+ * addresses are listed under different names in local databases.
+ */
+#define NEQ(x,y) (strcasecmp((x),(y)) != 0)
+#define NEQ3(x,y,n) (strncasecmp((x),(y), (n)) != 0)
+
+ while (--i >= 0) {
+ if ((hp = gethostbyaddr((char *) &list[i], length, AF_INET)) == 0) {
+ syslog(LOG_ERR, "address %s not registered for host %s",
+ inet_ntoa(list[i]), buf);
+ list[i].s_addr = (u_int32_t) -1;
+ }
+ if (NEQ(buf, hp->h_name) && NEQ3(buf, "localhost.", 10)) {
+ syslog(LOG_ERR, "address %s registered for host %s and %s",
+ inet_ntoa(list[i]), hp->h_name, buf);
+ list[i].s_addr = (u_int32_t) -1;
+ }
+ }
+ return (list);
+}
+
+/* convert_internet_addr - convert string to internet address */
+
+static struct in_addr *convert_internet_addr(string)
+char *string;
+{
+ static struct in_addr list[2];
+
+ list[0].s_addr = inet_addr(string);
+ list[1].s_addr = 0;
+ return (list);
+}
+
+#ifdef TEST
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+ struct hostent *hp;
+ char host[MAXHOSTNAMELEN + 1];
+ int verdict;
+ char *user;
+ char *port;
+
+ if (argc != 3 && argc != 4) {
+ fprintf(stderr, "usage: %s user port [host_or_ip_address]\n", argv[0]);
+ exit(0);
+ }
+ if (_PATH_SKEYACCESS[0] != '/')
+ printf("Warning: this program uses control file: %s\n", KEYACCESS);
+ openlog("login", LOG_PID, LOG_AUTH);
+
+ user = argv[1];
+ port = argv[2];
+ if (argv[3]) {
+ strncpy(host, (hp = gethostbyname(argv[3])) ?
+ hp->h_name : argv[3], MAXHOSTNAMELEN);
+ host[MAXHOSTNAMELEN] = 0;
+ }
+ verdict = skeyaccess(user, port, argv[3] ? host : (char *) 0, (char *) 0);
+ printf("UNIX passwords %spermitted\n", verdict ? "" : "NOT ");
+ return (0);
+}
+
+#endif
diff --git a/lib/libskey/skeylogin.c b/lib/libskey/skeylogin.c
new file mode 100644
index 0000000..75e6245
--- /dev/null
+++ b/lib/libskey/skeylogin.c
@@ -0,0 +1,342 @@
+/* Login code for S/KEY Authentication. S/KEY is a trademark
+ * of Bellcore.
+ *
+ * Mink is the former name of the S/KEY authentication system.
+ * Many references for mink may still be found in this program.
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <errno.h>
+
+#include "skey.h"
+#include "pathnames.h"
+
+static char *skipspace __P((char *));
+
+#define setpriority(x,y,z) /* nothing */
+
+static const char *month[12] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+/* Look up skey info for user 'name'. If successful, fill in the caller's
+ * skey structure and return 0. If unsuccessful (e.g., if name is unknown)
+ * return -1. If an optional challenge string buffer is given, update it.
+ *
+ * The file read/write pointer is left at the start of the
+ * record.
+ */
+int
+skeyinfo(mp,name,ss)
+struct skey *mp;
+const char *name;
+char *ss;
+{
+ int rval;
+
+ rval = skeylookup(mp,name);
+ switch(rval){
+ case -1: /* File error */
+ return -1;
+ case 0: /* Lookup succeeded */
+ if (ss != 0) {
+ sprintf(ss, "s/key %d %s",mp->n - 1,mp->seed);
+ fclose(mp->keyfile);
+ }
+ return 0;
+ case 1: /* User not found */
+ fclose(mp->keyfile);
+ return -1;
+ }
+ return -1; /* Can't happen */
+}
+
+/* Return a skey challenge string for user 'name'. If successful,
+ * fill in the caller's skey structure and return 0. If unsuccessful
+ * (e.g., if name is unknown) return -1.
+ *
+ * The file read/write pointer is left at the start of the
+ * record.
+ */
+int
+skeychallenge(mp,name, ss)
+struct skey *mp;
+const char *name;
+char *ss;
+{
+ int rval;
+
+ rval = skeylookup(mp,name);
+ switch(rval){
+ case -1: /* File error */
+ return -1;
+ case 0: /* Lookup succeeded, issue challenge */
+ sprintf(ss, "s/key %d %s",mp->n - 1,mp->seed);
+ return 0;
+ case 1: /* User not found */
+ fclose(mp->keyfile);
+ return -1;
+ }
+ return -1; /* Can't happen */
+}
+
+/* Find an entry in the One-time Password database.
+ * Return codes:
+ * -1: error in opening database
+ * 0: entry found, file R/W pointer positioned at beginning of record
+ * 1: entry not found, file R/W pointer positioned at EOF
+ */
+int
+skeylookup(mp,name)
+struct skey *mp;
+const char *name;
+{
+ int found;
+ size_t len;
+ long recstart = 0;
+ char *cp, *p;
+ struct stat statbuf;
+ mode_t oldmask;
+
+ /* See if the _PATH_SKEYFILE exists, and create it if not */
+ if(stat(_PATH_SKEYFILE,&statbuf) == -1 && errno == ENOENT){
+ oldmask = umask(S_IRWXG|S_IRWXO);
+ mp->keyfile = fopen(_PATH_SKEYFILE,"w+");
+ (void)umask(oldmask);
+ } else {
+ /* Otherwise open normally for update */
+ mp->keyfile = fopen(_PATH_SKEYFILE,"r+");
+ }
+ if(mp->keyfile == NULL)
+ return -1;
+
+ /* Look up user name in database */
+ len = strlen(name);
+ if( len > 8 ) len = 8; /* Added 8/2/91 - nmh */
+ found = 0;
+ while(!feof(mp->keyfile)){
+ recstart = ftell(mp->keyfile);
+ mp->recstart = recstart;
+ if(fgets(mp->buf,sizeof(mp->buf),mp->keyfile) != mp->buf){
+ break;
+ }
+ rip(mp->buf);
+ if(mp->buf[0] == '#')
+ continue; /* Comment */
+ p = mp->buf;
+ while ((cp = strsep(&p, " \t")) != NULL && *cp == '\0')
+ ;
+ if((mp->logname = cp) == NULL)
+ continue;
+ while ((cp = strsep(&p, " \t")) != NULL && *cp == '\0')
+ ;
+ if(cp == NULL)
+ continue;
+ mp->n = atoi(cp);
+ while ((cp = strsep(&p, " \t")) != NULL && *cp == '\0')
+ ;
+ if((mp->seed = cp) == NULL)
+ continue;
+ while ((cp = strsep(&p, " \t")) != NULL && *cp == '\0')
+ ;
+ if((mp->val = cp) == NULL)
+ continue;
+ if(strlen(mp->logname) == len
+ && strncmp(mp->logname,name,len) == 0){
+ found = 1;
+ break;
+ }
+ }
+ if(found){
+ fseek(mp->keyfile,recstart,0);
+ return 0;
+ } else
+ return 1;
+}
+/* Verify response to a s/key challenge.
+ *
+ * Return codes:
+ * -1: Error of some sort; database unchanged
+ * 0: Verify successful, database updated
+ * 1: Verify failed, database unchanged
+ *
+ * The database file is always closed by this call.
+ */
+int
+skeyverify(mp,response)
+struct skey *mp;
+char *response;
+{
+ char key[8];
+ char fkey[8];
+ char filekey[8];
+ time_t now;
+ struct tm *tm;
+ char tbuf[27], fbuf[20];
+ char *cp, *p;
+
+ time(&now);
+ tm = localtime(&now);
+/* can't use %b here, because it can be in national form */
+ strftime(fbuf, sizeof(fbuf), "%d,%Y %T", tm);
+ snprintf(tbuf, sizeof(tbuf), " %s %s", month[tm->tm_mon], fbuf);
+
+ if(response == NULL){
+ fclose(mp->keyfile);
+ return -1;
+ }
+ rip(response);
+
+ /* Convert response to binary */
+ if(etob(key,response) != 1 && atob8(key,response) != 0){
+ /* Neither english words or ascii hex */
+ fclose(mp->keyfile);
+ return -1;
+ }
+
+ /* Compute fkey = f(key) */
+ memcpy(fkey,key,sizeof(key));
+ f(fkey);
+ /* in order to make the window of update as short as possible
+ we must do the comparison here and if OK write it back
+ other wise the same password can be used twice to get in
+ to the system
+ */
+
+ setpriority(PRIO_PROCESS, 0, -4);
+
+ /* reread the file record NOW*/
+
+ fseek(mp->keyfile,mp->recstart,0);
+ if(fgets(mp->buf,sizeof(mp->buf),mp->keyfile) != mp->buf){
+ setpriority(PRIO_PROCESS, 0, 0);
+ fclose(mp->keyfile);
+ return -1;
+ }
+ rip(mp->buf);
+ p = mp->buf;
+ while ((cp = strsep(&p, " \t")) != NULL && *cp == '\0')
+ ;
+ mp->logname = cp;
+ while ((cp = strsep(&p, " \t")) != NULL && *cp == '\0')
+ ;
+ while ((cp = strsep(&p, " \t")) != NULL && *cp == '\0')
+ ;
+ mp->seed = cp;
+ while ((cp = strsep(&p, " \t")) != NULL && *cp == '\0')
+ ;
+ mp->val = cp;
+ /* And convert file value to hex for comparison */
+ atob8(filekey,mp->val);
+
+ /* Do actual comparison */
+ if(memcmp(filekey,fkey,8) != 0){
+ /* Wrong response */
+ setpriority(PRIO_PROCESS, 0, 0);
+ fclose(mp->keyfile);
+ return 1;
+ }
+
+ /* Update key in database by overwriting entire record. Note
+ * that we must write exactly the same number of bytes as in
+ * the original record (note fixed width field for N)
+ */
+ btoa8(mp->val,key);
+ mp->n--;
+ fseek(mp->keyfile,mp->recstart,0);
+ fprintf(mp->keyfile,"%s %04d %-16s %s %-21s\n",mp->logname,mp->n,mp->seed,
+ mp->val, tbuf);
+
+ fclose(mp->keyfile);
+
+ setpriority(PRIO_PROCESS, 0, 0);
+ return 0;
+}
+
+
+/* Convert 8-byte hex-ascii string to binary array
+ * Returns 0 on success, -1 on error
+ */
+int
+atob8(out,in)
+register char *out,*in;
+{
+ register int i;
+ register int val;
+
+ if(in == NULL || out == NULL)
+ return -1;
+
+ for(i=0;i<8;i++){
+ if((in = skipspace(in)) == NULL)
+ return -1;
+ if((val = htoi(*in++)) == -1)
+ return -1;
+ *out = val << 4;
+
+ if((in = skipspace(in)) == NULL)
+ return -1;
+ if((val = htoi(*in++)) == -1)
+ return -1;
+ *out++ |= val;
+ }
+ return 0;
+}
+
+static
+char *
+skipspace(cp)
+register char *cp;
+{
+ while(*cp == ' ' || *cp == '\t')
+ cp++;
+
+ if(*cp == '\0')
+ return NULL;
+ else
+ return cp;
+}
+
+/* Convert 8-byte binary array to hex-ascii string */
+int
+btoa8(out,in)
+register char *out,*in;
+{
+ register int i;
+
+ if(in == NULL || out == NULL)
+ return -1;
+
+ for(i=0;i<8;i++){
+ sprintf(out,"%02x",*in++ & 0xff);
+ out += 2;
+ }
+ return 0;
+}
+
+
+/* Convert hex digit to binary integer */
+int
+htoi(c)
+register char c;
+{
+ if('0' <= c && c <= '9')
+ return c - '0';
+ if('a' <= c && c <= 'f')
+ return 10 + c - 'a';
+ if('A' <= c && c <= 'F')
+ return 10 + c - 'A';
+ return -1;
+}
diff --git a/lib/libskey/skeysubr.c b/lib/libskey/skeysubr.c
new file mode 100644
index 0000000..8128444
--- /dev/null
+++ b/lib/libskey/skeysubr.c
@@ -0,0 +1,133 @@
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <signal.h>
+
+#include "skey.h"
+#include "mdx.h"
+
+/* Crunch a key:
+ * concatenate the seed and the password, run through MDX and
+ * collapse to 64 bits. This is defined as the user's starting key.
+ */
+int
+keycrunch(result,seed,passwd)
+char *result; /* 8-byte result */
+const char *seed; /* Seed, any length */
+const char *passwd; /* Password, any length */
+{
+ char *buf;
+ MDX_CTX md;
+ u_long results[4];
+ unsigned int buflen;
+
+ buflen = strlen(seed) + strlen(passwd);
+ if((buf = malloc(buflen+1)) == NULL)
+ return -1;
+ strcpy(buf,seed);
+ strcat(buf,passwd);
+
+ /* Crunch the key through MD[45] */
+ sevenbit(buf);
+ MDXInit(&md);
+ MDXUpdate(&md,(unsigned char *)buf,buflen);
+ MDXFinal((unsigned char *)results,&md);
+ free(buf);
+
+ results[0] ^= results[2];
+ results[1] ^= results[3];
+
+ memcpy(result,(char *)results,8);
+
+ return 0;
+}
+
+/* The one-way function f(). Takes 8 bytes and returns 8 bytes in place */
+void
+f(x)
+char *x;
+{
+ MDX_CTX md;
+ u_long results[4];
+
+ MDXInit(&md);
+ MDXUpdate(&md,(unsigned char *)x,8);
+ MDXFinal((unsigned char *)results,&md);
+ /* Fold 128 to 64 bits */
+ results[0] ^= results[2];
+ results[1] ^= results[3];
+
+ memcpy(x,(char *)results,8);
+}
+
+/* Strip trailing cr/lf from a line of text */
+void
+rip(buf)
+char *buf;
+{
+ buf[strcspn(buf, "\r\n")] = 0;
+}
+
+static struct termios saved_ttymode;
+
+static void interrupt __P((int));
+
+static void interrupt(sig)
+int sig;
+{
+ tcsetattr(0, TCSANOW, &saved_ttymode);
+ err(1, "interrupted by signal %s", sys_siglist[sig]);
+}
+
+char *
+readpass(buf,n)
+char *buf;
+int n;
+{
+ struct termios noecho_ttymode;
+ void (*oldsig) __P((int));
+
+ /* Save normal line editing modes */
+ tcgetattr(0, &saved_ttymode);
+ if ((oldsig = signal(SIGINT, SIG_IGN)) != SIG_IGN)
+ signal(SIGINT, interrupt);
+
+ /* Turn off echoing */
+ tcgetattr(0, &noecho_ttymode);
+ noecho_ttymode.c_lflag &= ~ECHO;
+ tcsetattr(0, TCSANOW, &noecho_ttymode);
+ fgets(buf,n,stdin);
+ rip(buf);
+
+ /* Restore previous tty modes */
+ tcsetattr(0, TCSANOW, &saved_ttymode);
+ if (oldsig != SIG_IGN)
+ signal(SIGINT, oldsig);
+
+ /*
+ after the secret key is taken from the keyboard, the line feed is
+ written to standard error instead of standard output. That means that
+ anyone using the program from a terminal won't notice, but capturing
+ standard output will get the key words without a newline in front of
+ them.
+ */
+ fprintf(stderr, "\n");
+ fflush(stderr);
+ sevenbit(buf);
+
+ return buf;
+}
+
+void
+sevenbit(s)
+char *s;
+{
+ /* make sure there are only 7 bit code in the line*/
+ while(*s){
+ *s &= 0x7f;
+ s++;
+ }
+}
diff --git a/lib/libss/Makefile b/lib/libss/Makefile
new file mode 100644
index 0000000..8cd34b1
--- /dev/null
+++ b/lib/libss/Makefile
@@ -0,0 +1,39 @@
+# $FreeBSD$
+
+LIB= ss
+SHLIB_MAJOR= 3
+SHLIB_MINOR= 0
+
+SRCS= data.c error.c execute_cmd.c help.c invocation.c list_rqs.c \
+ listen.c pager.c parse.c prompt.c request_tbl.c requests.c \
+ ss_err.c ss_err.h std_rqs.c
+CFLAGS+= -I. -I${.CURDIR} -DPOSIX -DIN_LIBSS
+CLEANFILES+= ss_err.c ss_err.h std_rqs.c
+.if exists(${.OBJDIR}/../libcom_err)
+LIBDESTDIR= ${.OBJDIR}/../libcom_err
+.else
+LIBDESTDIR= ${.CURDIR}/../libcom_err
+.endif
+DPADD= ${LIBDESTDIR}/libcom_err.a
+LDADD= -L${LIBDESTDIR} -lcom_err
+
+hdrs: ss_err.h
+
+.ORDER: ss_err.c ss_err.h
+ss_err.c ss_err.h: ${.CURDIR}/ss_err.et
+ test -e ss_err.et || ln -s ${.CURDIR}/ss_err.et .
+ compile_et ss_err.et
+ -test -h ss_err.et && rm -f ss_err.et
+
+std_rqs.c: ${.CURDIR}/std_rqs.ct
+ test -e std_rqs.ct || ln -s ${.CURDIR}/std_rqs.ct .
+ mk_cmds std_rqs.ct
+ -test -h std_rqs.ct && rm -f std_rqs.ct
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/ss.h \
+ ss_err.h ${DESTDIR}/usr/include/ss
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/copyright.h \
+ ${DESTDIR}/usr/include/ss/mit-sipb-copyright.h
+
+.include <bsd.lib.mk>
diff --git a/lib/libss/copyright.h b/lib/libss/copyright.h
new file mode 100644
index 0000000..e0d1572
--- /dev/null
+++ b/lib/libss/copyright.h
@@ -0,0 +1,19 @@
+/*
+
+Copyright 1987, 1989 by the Student Information Processing Board
+ of the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this software
+and its documentation for any purpose and without fee is
+hereby granted, provided that the above copyright notice
+appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation,
+and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+M.I.T. and the M.I.T. S.I.P.B. make no representations about
+the suitability of this software for any purpose. It is
+provided "as is" without express or implied warranty.
+
+*/
+
diff --git a/lib/libss/data.c b/lib/libss/data.c
new file mode 100644
index 0000000..45e49d7
--- /dev/null
+++ b/lib/libss/data.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright 1987, 1988, 1989 Massachusetts Institute of Technology
+ * (Student Information Processing Board)
+ *
+ * For copyright info, see copyright.h.
+ */
+
+#include <stdio.h>
+#include "ss_internal.h"
+#include "copyright.h"
+
+static const char copyright[] =
+ "Copyright 1987, 1988, 1989 by the Massachusetts Institute of Technology";
+
+ss_data **_ss_table = (ss_data **)NULL;
+char *_ss_pager_name = (char *)NULL;
diff --git a/lib/libss/error.c b/lib/libss/error.c
new file mode 100644
index 0000000..3cc1ffa
--- /dev/null
+++ b/lib/libss/error.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright 1987, 1988, 1989 by MIT Student Information Processing
+ * Board
+ *
+ * For copyright information, see copyright.h.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * Our standalone dpANS environment on the RT doesn't include any
+ * header files.
+ */
+#if defined(__STDC__) && !defined(ibm032)
+#include <stdarg.h>
+#define STDARG
+#else
+#include <varargs.h>
+#define ss_error ss_error_external
+#endif
+
+#include "copyright.h"
+#include <com_err.h>
+#include "ss_internal.h"
+
+#undef ss_error
+
+extern void com_err_va __P(( ));
+
+char * ss_name(sci_idx)
+ int sci_idx;
+{
+ register char *ret_val;
+ register ss_data *infop;
+
+ infop = ss_info(sci_idx);
+ if (infop->current_request == (char const *)NULL) {
+ ret_val = malloc((unsigned)
+ (strlen(infop->subsystem_name)+1)
+ * sizeof(char));
+ if (ret_val == (char *)NULL)
+ return((char *)NULL);
+ strcpy(ret_val, infop->subsystem_name);
+ return(ret_val);
+ }
+ else {
+ register char *cp;
+ register char const *cp1;
+ ret_val = malloc((unsigned)sizeof(char) *
+ (strlen(infop->subsystem_name)+
+ strlen(infop->current_request)+
+ 4));
+ cp = ret_val;
+ cp1 = infop->subsystem_name;
+ while (*cp1)
+ *cp++ = *cp1++;
+ *cp++ = ' ';
+ *cp++ = '(';
+ cp1 = infop->current_request;
+ while (*cp1)
+ *cp++ = *cp1++;
+ *cp++ = ')';
+ *cp = '\0';
+ return(ret_val);
+ }
+}
+
+#ifdef STDARG
+void ss_error (int sci_idx, long code, const char * fmt, ...)
+#else
+void ss_error (va_alist)
+ va_dcl
+#endif
+{
+ register char *whoami;
+ va_list pvar;
+#ifndef STDARG
+ int sci_idx;
+ long code;
+ char * fmt;
+ va_start (pvar);
+ sci_idx = va_arg (pvar, int);
+ code = va_arg (pvar, long);
+ fmt = va_arg (pvar, char *);
+#else
+ va_start (pvar, fmt);
+#endif
+ whoami = ss_name (sci_idx);
+ com_err_va (whoami, code, fmt, pvar);
+ free (whoami);
+ va_end(pvar);
+}
+
+void ss_perror (sci_idx, code, msg) /* for compatibility */
+ int sci_idx;
+ long code;
+ char const *msg;
+{
+ ss_error (sci_idx, code, "%s", msg);
+}
diff --git a/lib/libss/execute_cmd.c b/lib/libss/execute_cmd.c
new file mode 100644
index 0000000..1bb0129
--- /dev/null
+++ b/lib/libss/execute_cmd.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright 1987, 1988, 1989 by Massachusetts Institute of Technology
+ *
+ * For copyright info, see copyright.h.
+ */
+
+#include "ss_internal.h"
+#include "copyright.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef lint
+static char const rcsid[] =
+ "Header: execute_cmd.c,v 1.7 89/01/25 08:27:43 raeburn Exp ";
+#endif
+
+/*
+ * get_request(tbl, idx)
+ *
+ * Function:
+ * Gets the idx'th request from the request table pointed to
+ * by tbl.
+ * Arguments:
+ * tbl (ss_request_table *)
+ * pointer to request table
+ * idx (int)
+ * index into table
+ * Returns:
+ * (ss_request_entry *)
+ * pointer to request table entry
+ * Notes:
+ * Has been replaced by a macro.
+ */
+
+#ifdef __SABER__
+/* sigh. saber won't deal with pointer-to-const-struct */
+static struct _ss_request_entry * get_request (tbl, idx)
+ ss_request_table * tbl;
+ int idx;
+{
+ struct _ss_request_table *tbl1 = (struct _ss_request_table *) tbl;
+ struct _ss_request_entry *e = (struct _ss_request_entry *) tbl1->requests;
+ return e + idx;
+}
+#else
+#define get_request(tbl,idx) ((tbl) -> requests + (idx))
+#endif
+
+/*
+ * check_request_table(rqtbl, argc, argv, sci_idx)
+ *
+ * Function:
+ * If the command string in argv[0] is in the request table, execute
+ * the commands and return error code 0. Otherwise, return error
+ * code ss_et_command_not_found.
+ * Arguments:
+ * rqtbl (ss_request_table *)
+ * pointer to request table
+ * argc (int)
+ * number of elements in argv[]
+ * argv (char *[])
+ * argument string array
+ * sci_idx (int)
+ * ss-internal index for subsystem control info structure
+ * Returns:
+ * (int)
+ * zero if command found, ss_et_command_not_found otherwise
+ * Notes:
+ */
+
+static int check_request_table (rqtbl, argc, argv, sci_idx)
+ register ss_request_table *rqtbl;
+ int argc;
+ char *argv[];
+ int sci_idx;
+{
+#ifdef __SABER__
+ struct _ss_request_entry *request;
+#else
+ register ss_request_entry *request;
+#endif
+ register ss_data *info;
+ register char const * const * name;
+ char *string = argv[0];
+ int i;
+
+ info = ss_info(sci_idx);
+ info->argc = argc;
+ info->argv = argv;
+ for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) {
+ for (name = request->command_names; *name; name++)
+ if (!strcmp(*name, string)) {
+ info->current_request = request->command_names[0];
+ (request->function)(argc, (const char *const *) argv,
+ sci_idx,info->info_ptr);
+ info->current_request = (char *)NULL;
+ return(0);
+ }
+ }
+ return(SS_ET_COMMAND_NOT_FOUND);
+}
+
+/*
+ * really_execute_command(sci_idx, argc, argv)
+ *
+ * Function:
+ * Fills in the argc, argv values in the subsystem entry and
+ * call the appropriate routine.
+ * Arguments:
+ * sci_idx (int)
+ * ss-internal index for subsystem control info structure
+ * argc (int)
+ * number of arguments in argument list
+ * argv (char **[])
+ * pointer to parsed argument list (may be reallocated
+ * on abbrev expansion)
+ *
+ * Returns:
+ * (int)
+ * Zero if successful, ss_et_command_not_found otherwise.
+ * Notes:
+ */
+
+static int really_execute_command (sci_idx, argc, argv)
+ int sci_idx;
+ int argc;
+ char **argv[];
+{
+ register ss_request_table **rqtbl;
+ register ss_data *info;
+
+ info = ss_info(sci_idx);
+
+ for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) {
+ if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0)
+ return(0);
+ }
+ return(SS_ET_COMMAND_NOT_FOUND);
+}
+
+/*
+ * ss_execute_command(sci_idx, argv)
+ *
+ * Function:
+ * Executes a parsed command list within the subsystem.
+ * Arguments:
+ * sci_idx (int)
+ * ss-internal index for subsystem control info structure
+ * argv (char *[])
+ * parsed argument list
+ * Returns:
+ * (int)
+ * Zero if successful, ss_et_command_not_found otherwise.
+ * Notes:
+ */
+
+int
+ss_execute_command(sci_idx, argv)
+ int sci_idx;
+ register char *argv[];
+{
+ register int i, argc;
+ char **argp;
+
+ argc = 0;
+ for (argp = argv; *argp; argp++)
+ argc++;
+ argp = (char **)malloc((argc+1)*sizeof(char *));
+ for (i = 0; i <= argc; i++)
+ argp[i] = argv[i];
+ i = really_execute_command(sci_idx, argc, &argp);
+ free(argp);
+ return(i);
+}
+
+/*
+ * ss_execute_line(sci_idx, line_ptr)
+ *
+ * Function:
+ * Parses and executes a command line within a subsystem.
+ * Arguments:
+ * sci_idx (int)
+ * ss-internal index for subsystem control info structure
+ * line_ptr (char *)
+ * Pointer to command line to be parsed.
+ * Returns:
+ * (int)
+ * Error code.
+ * Notes:
+ */
+
+int ss_execute_line (sci_idx, line_ptr)
+ int sci_idx;
+ char *line_ptr;
+{
+ char **argv;
+ int argc;
+
+ /* flush leading whitespace */
+ while (line_ptr[0] == ' ' || line_ptr[0] == '\t')
+ line_ptr++;
+
+ /* check if it should be sent to operating system for execution */
+ if (*line_ptr == '!') {
+ if (ss_info(sci_idx)->flags.escape_disabled)
+ return SS_ET_ESCAPE_DISABLED;
+ else {
+ line_ptr++;
+ system(line_ptr);
+ return 0;
+ }
+ }
+
+ /* parse it */
+ argv = ss_parse(sci_idx, line_ptr, &argc);
+ if (argc == 0)
+ return 0;
+
+ /* look it up in the request tables, execute if found */
+ return really_execute_command (sci_idx, argc, &argv);
+}
diff --git a/lib/libss/help.c b/lib/libss/help.c
new file mode 100644
index 0000000..078224d
--- /dev/null
+++ b/lib/libss/help.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright 1987, 1988 by MIT Student Information Processing Board
+ *
+ * For copyright info, see copyright.h.
+ */
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/wait.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "ss_internal.h"
+#include "copyright.h"
+
+extern int errno;
+
+void ss_help (argc, argv, sci_idx, info_ptr)
+ int argc;
+ char const * const *argv;
+ int sci_idx;
+ pointer info_ptr;
+{
+ char buffer[MAXPATHLEN];
+ char const *request_name;
+ int code;
+ int fd, child;
+ register int idx;
+ register ss_data *info;
+
+ request_name = ss_current_request(sci_idx, &code);
+ if (code != 0) {
+ ss_perror(sci_idx, code, "");
+ return; /* no ss_abort_line, if invalid invocation */
+ }
+ if (argc == 1) {
+ ss_list_requests(argc, argv, sci_idx, info_ptr);
+ return;
+ }
+ else if (argc != 2) {
+ /* should do something better than this */
+ sprintf(buffer, "usage:\n\t%s [topic|command]\nor\t%s\n",
+ request_name, request_name);
+ ss_perror(sci_idx, 0, buffer);
+ return;
+ }
+ info = ss_info(sci_idx);
+ if (info->info_dirs == (char **)NULL) {
+ ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
+ return;
+ }
+ if (info->info_dirs[0] == (char *)NULL) {
+ ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
+ return;
+ }
+ for (idx = 0; info->info_dirs[idx] != (char *)NULL; idx++) {
+ (void) strcpy(buffer, info->info_dirs[idx]);
+ (void) strcat(buffer, "/");
+ (void) strcat(buffer, argv[1]);
+ (void) strcat(buffer, ".info");
+ if ((fd = open(&buffer[0], O_RDONLY, 0)) >= 0) goto got_it;
+ }
+ if ((fd = open(&buffer[0], O_RDONLY, 0)) < 0) {
+ char buf[MAXPATHLEN];
+ strcpy(buf, "No info found for ");
+ strcat(buf, argv[1]);
+ ss_perror(sci_idx, 0, buf);
+ return;
+ }
+got_it:
+ switch (child = fork()) {
+ case -1:
+ ss_perror(sci_idx, errno, "Can't fork for pager");
+ return;
+ case 0:
+ (void) dup2(fd, 0); /* put file on stdin */
+ ss_page_stdin();
+ default:
+ (void) close(fd); /* what can we do if it fails? */
+#ifndef POSIX
+ while (wait((union wait *)NULL) != child)
+#else
+ while (wait((int *)NULL) != child)
+#endif
+ {
+ /* do nothing if wrong pid */
+ };
+ }
+}
+
+void ss_add_info_dir(sci_idx, info_dir, code_ptr)
+ int sci_idx;
+ char *info_dir;
+ int *code_ptr;
+{
+ register ss_data *info;
+ DIR *d;
+ int n_dirs;
+ register char **dirs;
+
+ info = ss_info(sci_idx);
+ if (info_dir == NULL && *info_dir) {
+ *code_ptr = SS_ET_NO_INFO_DIR;
+ return;
+ }
+ if ((d = opendir(info_dir)) == (DIR *)NULL) {
+ *code_ptr = errno;
+ return;
+ }
+ closedir(d);
+ dirs = info->info_dirs;
+ for (n_dirs = 0; dirs[n_dirs] != (char *)NULL; n_dirs++)
+ ; /* get number of non-NULL dir entries */
+ dirs = (char **)reallocf((char *)dirs,
+ (unsigned)(n_dirs + 2)*sizeof(char *));
+ if (dirs == (char **)NULL) {
+ info->info_dirs = (char **)NULL;
+ *code_ptr = errno;
+ return;
+ }
+ info->info_dirs = dirs;
+ dirs[n_dirs + 1] = (char *)NULL;
+ dirs[n_dirs] = malloc((unsigned)strlen(info_dir)+1);
+ strcpy(dirs[n_dirs], info_dir);
+ *code_ptr = 0;
+}
+
+void ss_delete_info_dir(sci_idx, info_dir, code_ptr)
+ int sci_idx;
+ char *info_dir;
+ int *code_ptr;
+{
+ register char **i_d;
+ register char **info_dirs;
+
+ info_dirs = ss_info(sci_idx)->info_dirs;
+ for (i_d = info_dirs; *i_d; i_d++) {
+ if (!strcmp(*i_d, info_dir)) {
+ while (*i_d) {
+ *i_d = *(i_d+1);
+ i_d++;
+ }
+ *code_ptr = 0;
+ return;
+ }
+ }
+ *code_ptr = SS_ET_NO_INFO_DIR;
+}
diff --git a/lib/libss/invocation.c b/lib/libss/invocation.c
new file mode 100644
index 0000000..f56c01a
--- /dev/null
+++ b/lib/libss/invocation.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 1987, 1988 by MIT Student Information Processing Board
+ *
+ * For copyright information, see copyright.h.
+ */
+
+#include <stdlib.h>
+#include "ss_internal.h"
+#include "copyright.h"
+#define size sizeof(ss_data *)
+
+#ifndef lint
+static char const rcsid[] =
+ "Header: invocation.c,v 1.6 89/01/25 07:45:47 raeburn Exp ";
+#endif
+
+int ss_create_invocation(subsystem_name, version_string, info_ptr,
+ request_table_ptr, code_ptr)
+ char *subsystem_name, *version_string;
+ char *info_ptr;
+ ss_request_table *request_table_ptr;
+ int *code_ptr;
+{
+ register int sci_idx;
+ register ss_data *new_table;
+ register ss_data **table;
+
+ *code_ptr = 0;
+ table = _ss_table;
+ new_table = (ss_data *) malloc(sizeof(ss_data));
+
+ if (table == (ss_data **) NULL) {
+ table = (ss_data **) malloc(2 * size);
+ table[0] = table[1] = (ss_data *)NULL;
+ }
+ initialize_ss_error_table ();
+
+ for (sci_idx = 1; table[sci_idx] != (ss_data *)NULL; sci_idx++)
+ ;
+ table = (ss_data **) reallocf((char *)table,
+ ((unsigned)sci_idx+2)*size);
+ table[sci_idx+1] = (ss_data *) NULL;
+ table[sci_idx] = new_table;
+
+ new_table->subsystem_name = subsystem_name;
+ new_table->subsystem_version = version_string;
+ new_table->argv = (char **)NULL;
+ new_table->current_request = (char *)NULL;
+ new_table->info_dirs = (char **)malloc(sizeof(char *));
+ *new_table->info_dirs = (char *)NULL;
+ new_table->info_ptr = info_ptr;
+ new_table->prompt = malloc((unsigned)strlen(subsystem_name)+4);
+ strcpy(new_table->prompt, subsystem_name);
+ strcat(new_table->prompt, ": ");
+#ifdef silly
+ new_table->abbrev_info = ss_abbrev_initialize("/etc/passwd", code_ptr);
+#else
+ new_table->abbrev_info = NULL;
+#endif
+ new_table->flags.escape_disabled = 0;
+ new_table->flags.abbrevs_disabled = 0;
+ new_table->rqt_tables =
+ (ss_request_table **) calloc(2, sizeof(ss_request_table *));
+ *(new_table->rqt_tables) = request_table_ptr;
+ *(new_table->rqt_tables+1) = (ss_request_table *) NULL;
+ _ss_table = table;
+ return(sci_idx);
+}
+
+void
+ss_delete_invocation(sci_idx)
+ int sci_idx;
+{
+ register ss_data *t;
+ int ignored_code;
+
+ t = ss_info(sci_idx);
+ free(t->prompt);
+ free((char *)t->rqt_tables);
+ while(t->info_dirs[0] != (char *)NULL)
+ ss_delete_info_dir(sci_idx, t->info_dirs[0], &ignored_code);
+ free((char *)t->info_dirs);
+ free((char *)t);
+}
diff --git a/lib/libss/list_rqs.c b/lib/libss/list_rqs.c
new file mode 100644
index 0000000..14e7748
--- /dev/null
+++ b/lib/libss/list_rqs.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 1987, 1988 by MIT Student Information Processing Board
+ *
+ * For copyright information, see copyright.h.
+ */
+#include "copyright.h"
+#include "ss_internal.h"
+#include <signal.h>
+#include <setjmp.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#ifdef lint /* "lint returns a value which is sometimes ignored" */
+#define DONT_USE(x) x=x;
+#else /* !lint */
+#define DONT_USE(x) ;
+#endif /* lint */
+
+static char const twentyfive_spaces[26] =
+ " ";
+static char const NL[2] = "\n";
+
+void
+ss_list_requests(argc, argv, sci_idx, info_ptr)
+ int argc;
+ char **argv;
+ int sci_idx;
+ pointer info_ptr;
+{
+ register ss_request_entry *entry;
+ register char const * const *name;
+ register int spacing;
+ register ss_request_table **table;
+
+ char buffer[BUFSIZ];
+ FILE *output;
+ int fd;
+ int mask;
+#ifdef POSIX
+ void (*func)();
+#else
+ int (*func)();
+#endif
+#ifdef POSIX
+ int waitb;
+#else
+ union wait waitb;
+#endif
+
+ DONT_USE(argc);
+ DONT_USE(argv);
+
+ mask = sigblock(sigmask(SIGINT));
+ func = signal(SIGINT, SIG_IGN);
+ fd = ss_pager_create();
+ output = fdopen(fd, "w");
+ sigsetmask(mask);
+
+ fprintf (output, "Available %s requests:\n\n",
+ ss_info (sci_idx) -> subsystem_name);
+
+ for (table = ss_info(sci_idx)->rqt_tables; *table; table++) {
+ entry = (*table)->requests;
+ for (; entry->command_names; entry++) {
+ spacing = -2;
+ buffer[0] = '\0';
+ if (entry->flags & SS_OPT_DONT_LIST)
+ continue;
+ for (name = entry->command_names; *name; name++) {
+ register int len = strlen(*name);
+ strncat(buffer, *name, len);
+ spacing += len + 2;
+ if (name[1]) {
+ strcat(buffer, ", ");
+ }
+ }
+ if (spacing > 23) {
+ strcat(buffer, NL);
+ fputs(buffer, output);
+ spacing = 0;
+ buffer[0] = '\0';
+ }
+ strncat(buffer, twentyfive_spaces, 25-spacing);
+ strcat(buffer, entry->info_string);
+ strcat(buffer, NL);
+ fputs(buffer, output);
+ }
+ }
+ fclose(output);
+#ifndef NO_FORK
+ wait(&waitb);
+#endif
+ (void) signal(SIGINT, func);
+}
diff --git a/lib/libss/listen.c b/lib/libss/listen.c
new file mode 100644
index 0000000..f9686f9
--- /dev/null
+++ b/lib/libss/listen.c
@@ -0,0 +1,163 @@
+
+
+/*
+ * Listener loop for subsystem library libss.a.
+ *
+ * Header: /afs/rel-eng.athena.mit.edu/project/release/current/source/athena/athena.lib/ss/RCS/listen.c,v 1.2 90/07/12 12:28:58 epeisach Exp
+ *
+ * Copyright 1987, 1988 by MIT Student Information Processing Board
+ *
+ * For copyright information, see copyright.h.
+ */
+
+#include "copyright.h"
+#include "ss_internal.h"
+#include <stdio.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <sys/param.h>
+#if defined(BSD) && !defined(POSIX)
+#include <sgtty.h>
+#endif
+#ifdef POSIX
+#include <termios.h>
+#endif
+
+#ifndef lint
+static char const rcs_id[] =
+ "Header: /afs/rel-eng.athena.mit.edu/project/release/current/source/athena/athena.lib/ss/RCS/listen.c,v 1.2 90/07/12 12:28:58 epeisach Exp ";
+#endif
+
+#ifdef POSIX
+#define sigtype void
+#else
+#define sigtype int
+#endif POSIX
+
+extern char *index();
+
+static ss_data *current_info;
+static jmp_buf listen_jmpb;
+
+static sigtype print_prompt()
+{
+ /* put input into a reasonable mode */
+#if defined(BSD) && !defined(POSIX)
+ struct sgttyb ttyb;
+ if (ioctl(fileno(stdin), TIOCGETP, &ttyb) != -1) {
+ if (ttyb.sg_flags & (CBREAK|RAW)) {
+ ttyb.sg_flags &= ~(CBREAK|RAW);
+ (void) ioctl(0, TIOCSETP, &ttyb);
+ }
+#endif
+#ifdef POSIX
+ struct termios tio;
+ if (tcgetattr(fileno(stdin), &tio) != -1) {
+ tio.c_oflag |= (OPOST|ONLCR);
+ tio.c_iflag &= ~(IGNCR|INLCR);
+ tio.c_iflag |= (ICRNL);
+ tio.c_lflag |= (ICANON);
+ (void) tcsetattr(0, TCSADRAIN, &tio);
+ }
+#endif
+ (void) fputs(current_info->prompt, stdout);
+ (void) fflush(stdout);
+}
+
+static sigtype listen_int_handler()
+{
+ putc('\n', stdout);
+ longjmp(listen_jmpb, 1);
+}
+
+int ss_listen (sci_idx)
+ int sci_idx;
+{
+ register char *cp;
+ register sigtype (*sig_cont)();
+ register ss_data *info;
+ sigtype (*sig_int)(), (*old_sig_cont)();
+ char input[BUFSIZ];
+ char buffer[BUFSIZ];
+ char *end = buffer;
+ int mask;
+ int code;
+ jmp_buf old_jmpb;
+ ss_data *old_info = current_info;
+ static sigtype print_prompt();
+
+ current_info = info = ss_info(sci_idx);
+ sig_cont = (sigtype (*)())0;
+ info->abort = 0;
+ mask = sigblock(sigmask(SIGINT));
+ bcopy(listen_jmpb, old_jmpb, sizeof(jmp_buf));
+ sig_int = signal(SIGINT, listen_int_handler);
+ setjmp(listen_jmpb);
+ (void) sigsetmask(mask);
+ while(!info->abort) {
+ print_prompt();
+ *end = '\0';
+ old_sig_cont = sig_cont;
+ sig_cont = signal(SIGCONT, print_prompt);
+#ifdef mips
+ /* The mips compiler breaks on determining the types,
+ we help */
+ if ( (sigtype *) sig_cont == (sigtype *) print_prompt)
+#else
+ if ( sig_cont == print_prompt)
+#endif
+ sig_cont = old_sig_cont;
+ if (fgets(input, BUFSIZ, stdin) != input) {
+ code = SS_ET_EOF;
+ goto egress;
+ }
+ cp = index(input, '\n');
+ if (cp) {
+ *cp = '\0';
+ if (cp == input)
+ continue;
+ }
+ (void) signal(SIGCONT, sig_cont);
+ for (end = input; *end; end++)
+ ;
+
+ code = ss_execute_line (sci_idx, input);
+ if (code == SS_ET_COMMAND_NOT_FOUND) {
+ register char *c = input;
+ while (*c == ' ' || *c == '\t')
+ c++;
+ cp = index (c, ' ');
+ if (cp)
+ *cp = '\0';
+ cp = index (c, '\t');
+ if (cp)
+ *cp = '\0';
+ ss_error (sci_idx, 0,
+ "Unknown request \"%s\". Type \"?\" for a request list.",
+ c);
+ }
+ }
+ code = 0;
+egress:
+ (void) signal(SIGINT, sig_int);
+ bcopy(old_jmpb, listen_jmpb, sizeof(jmp_buf));
+ current_info = old_info;
+ return code;
+}
+
+void ss_abort_subsystem(sci_idx, code)
+ int sci_idx, code;
+{
+ ss_info(sci_idx)->abort = 1;
+ ss_info(sci_idx)->exit_status = code;
+
+}
+
+void ss_quit(argc, argv, sci_idx, infop)
+ int argc;
+ char **argv;
+ int sci_idx;
+ pointer infop;
+{
+ ss_abort_subsystem(sci_idx, 0);
+}
diff --git a/lib/libss/pager.c b/lib/libss/pager.c
new file mode 100644
index 0000000..b419725
--- /dev/null
+++ b/lib/libss/pager.c
@@ -0,0 +1,91 @@
+/*
+ * Pager: Routines to create a "more" running out of a particular file
+ * descriptor.
+ *
+ * Copyright 1987, 1988 by MIT Student Information Processing Board
+ *
+ * For copyright information, see copyright.h.
+ */
+
+#include "ss_internal.h"
+#include "copyright.h"
+#include <stdio.h>
+#include <sys/file.h>
+#include <signal.h>
+#include <unistd.h>
+
+static char MORE[] = "more";
+extern char *_ss_pager_name;
+extern char *getenv();
+extern int errno;
+
+/*
+ * this needs a *lot* of work....
+ *
+ * run in same process
+ * handle SIGINT sensibly
+ * allow finer control -- put-page-break-here
+ */
+void ss_page_stdin();
+
+#ifndef NO_FORK
+int ss_pager_create()
+{
+ int filedes[2];
+
+ if (pipe(filedes) != 0)
+ return(-1);
+
+ switch(fork()) {
+ case -1:
+ return(-1);
+ case 0:
+ /*
+ * Child; dup read half to 0, close all but 0, 1, and 2
+ */
+ if (dup2(filedes[0], 0) == -1)
+ exit(1);
+ ss_page_stdin();
+ default:
+ /*
+ * Parent: close "read" side of pipe, return
+ * "write" side.
+ */
+ (void) close(filedes[0]);
+ return(filedes[1]);
+ }
+}
+#else /* don't fork */
+int ss_pager_create()
+{
+ int fd;
+ fd = open("/dev/tty", O_WRONLY, 0);
+ return fd;
+}
+#endif
+
+void ss_page_stdin()
+{
+ int i;
+ for (i = 3; i < 32; i++)
+ (void) close(i);
+ (void) signal(SIGINT, SIG_DFL);
+ {
+ register int mask = sigblock(0);
+ mask &= ~sigmask(SIGINT);
+ sigsetmask(mask);
+ }
+ if (_ss_pager_name == (char *)NULL) {
+ if ((_ss_pager_name = getenv("PAGER")) == (char *)NULL)
+ _ss_pager_name = MORE;
+ }
+ (void) execlp(_ss_pager_name, _ss_pager_name, (char *) NULL);
+ {
+ /* minimal recovery if pager program isn't found */
+ char buf[80];
+ register int n;
+ while ((n = read(0, buf, 80)) > 0)
+ write(1, buf, n);
+ }
+ exit(errno);
+}
diff --git a/lib/libss/parse.c b/lib/libss/parse.c
new file mode 100644
index 0000000..878677e
--- /dev/null
+++ b/lib/libss/parse.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright 1987, 1988 by MIT Student Information Processing Board
+ *
+ * For copyright info, see copyright.h.
+ */
+
+#include <stdlib.h>
+#include "ss_internal.h"
+#include "copyright.h"
+
+#ifndef lint
+static char const rcsid[] =
+ "Header: parse.c,v 1.1 89/01/25 07:53:13 raeburn Exp ";
+#endif
+
+enum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING };
+
+/*
+ * parse(line_ptr, argc_ptr)
+ *
+ * Function:
+ * Parses line, dividing at whitespace, into tokens, returns
+ * the "argc" and "argv" values.
+ * Arguments:
+ * line_ptr (char *)
+ * Pointer to text string to be parsed.
+ * argc_ptr (int *)
+ * Where to put the "argc" (number of tokens) value.
+ * Returns:
+ * argv (char **)
+ * Series of pointers to parsed tokens.
+ */
+
+#define NEW_ARGV(old,n) (char **)reallocf((char *)old,\
+ (unsigned)(n+2)*sizeof(char*))
+
+char **ss_parse (sci_idx, line_ptr, argc_ptr)
+ int sci_idx;
+ register char *line_ptr;
+ int *argc_ptr;
+{
+ register char **argv, *cp;
+ register int argc;
+ register enum parse_mode parse_mode;
+
+ argv = (char **) malloc (sizeof(char *));
+ if (argv == (char **)NULL) {
+ ss_error(sci_idx, errno, "Can't allocate storage");
+ return(argv);
+ }
+ *argv = (char *)NULL;
+
+ argc = 0;
+
+ parse_mode = WHITESPACE; /* flushing whitespace */
+ cp = line_ptr; /* cp is for output */
+ while (1) {
+#ifdef DEBUG
+ {
+ printf ("character `%c', mode %d\n", *line_ptr, parse_mode);
+ }
+#endif
+ while (parse_mode == WHITESPACE) {
+ if (*line_ptr == '\0')
+ goto end_of_line;
+ if (*line_ptr == ' ' || *line_ptr == '\t') {
+ line_ptr++;
+ continue;
+ }
+ if (*line_ptr == '"') {
+ /* go to quoted-string mode */
+ parse_mode = QUOTED_STRING;
+ cp = line_ptr++;
+ argv = NEW_ARGV (argv, argc);
+ argv[argc++] = cp;
+ argv[argc] = NULL;
+ }
+ else {
+ /* random-token mode */
+ parse_mode = TOKEN;
+ cp = line_ptr;
+ argv = NEW_ARGV (argv, argc);
+ argv[argc++] = line_ptr;
+ argv[argc] = NULL;
+ }
+ }
+ while (parse_mode == TOKEN) {
+ if (*line_ptr == '\0') {
+ *cp++ = '\0';
+ goto end_of_line;
+ }
+ else if (*line_ptr == ' ' || *line_ptr == '\t') {
+ *cp++ = '\0';
+ line_ptr++;
+ parse_mode = WHITESPACE;
+ }
+ else if (*line_ptr == '"') {
+ line_ptr++;
+ parse_mode = QUOTED_STRING;
+ }
+ else {
+ *cp++ = *line_ptr++;
+ }
+ }
+ while (parse_mode == QUOTED_STRING) {
+ if (*line_ptr == '\0') {
+ ss_error (sci_idx, 0,
+ "Unbalanced quotes in command line");
+ free (argv);
+ return NULL;
+ }
+ else if (*line_ptr == '"') {
+ if (*++line_ptr == '"') {
+ *cp++ = '"';
+ line_ptr++;
+ }
+ else {
+ parse_mode = TOKEN;
+ }
+ }
+ else {
+ *cp++ = *line_ptr++;
+ }
+ }
+ }
+end_of_line:
+ *argc_ptr = argc;
+#ifdef DEBUG
+ {
+ int i;
+ printf ("argc = %d\n", argc);
+ for (i = 0; i <= argc; i++)
+ printf ("\targv[%2d] = `%s'\n", i,
+ argv[i] ? argv[i] : "<NULL>");
+ }
+#endif
+ return(argv);
+}
diff --git a/lib/libss/prompt.c b/lib/libss/prompt.c
new file mode 100644
index 0000000..3e207b0
--- /dev/null
+++ b/lib/libss/prompt.c
@@ -0,0 +1,31 @@
+/*
+ * prompt.c: Routines for retrieving and setting a prompt.
+ *
+ * Header: prompt.c,v 1.2 89/01/18 18:27:02 raeburn Exp
+ *
+ * Copyright 1987, 1988 by MIT Student Information Processing Board
+ *
+ * For copyright information, see copyright.h.
+ */
+
+#include "copyright.h"
+#include <stdio.h>
+#include "ss_internal.h"
+
+static const char rcsid[] =
+ "Header: prompt.c,v 1.2 89/01/18 18:27:02 raeburn Exp ";
+
+void
+ss_set_prompt(sci_idx, new_prompt)
+ int sci_idx;
+ char *new_prompt;
+{
+ ss_info(sci_idx)->prompt = new_prompt;
+}
+
+char *
+ss_get_prompt(sci_idx)
+ int sci_idx;
+{
+ return(ss_info(sci_idx)->prompt);
+}
diff --git a/lib/libss/request_tbl.c b/lib/libss/request_tbl.c
new file mode 100644
index 0000000..1564689
--- /dev/null
+++ b/lib/libss/request_tbl.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1987, 1988 by MIT Student Information Processing Board
+ *
+ * For copyright information, see copyright.h.
+ */
+
+#include <stdlib.h>
+#include "copyright.h"
+#include "ss_internal.h"
+
+#define ssrt ss_request_table /* for some readable code... */
+
+void
+ss_add_request_table(sci_idx, rqtbl_ptr, position, code_ptr)
+ int sci_idx;
+ ssrt *rqtbl_ptr;
+ int position; /* 1 -> becomes second... */
+ int *code_ptr;
+{
+ register ss_data *info;
+ register int i, size;
+
+ info = ss_info(sci_idx);
+ for (size=0; info->rqt_tables[size] != (ssrt *)NULL; size++)
+ ;
+ /* size == C subscript of NULL == #elements */
+ size += 2; /* new element, and NULL */
+ info->rqt_tables = (ssrt **)reallocf((char *)info->rqt_tables,
+ (unsigned)size*sizeof(ssrt));
+ if (info->rqt_tables == (ssrt **)NULL) {
+ *code_ptr = errno;
+ return;
+ }
+ if (position > size - 2)
+ position = size - 2;
+
+ if (size > 1)
+ for (i = size - 2; i >= position; i--)
+ info->rqt_tables[i+1] = info->rqt_tables[i];
+
+ info->rqt_tables[position] = rqtbl_ptr;
+ info->rqt_tables[size-1] = (ssrt *)NULL;
+ *code_ptr = 0;
+}
+
+void
+ss_delete_request_table(sci_idx, rqtbl_ptr, code_ptr)
+ int sci_idx;
+ ssrt *rqtbl_ptr;
+ int *code_ptr;
+{
+ register ss_data *info;
+ register ssrt **rt1, **rt2;
+
+ *code_ptr = SS_ET_TABLE_NOT_FOUND;
+ info = ss_info(sci_idx);
+ rt1 = info->rqt_tables;
+ for (rt2 = rt1; *rt1; rt1++) {
+ if (*rt1 != rqtbl_ptr) {
+ *rt2++ = *rt1;
+ *code_ptr = 0;
+ }
+ }
+ *rt2 = (ssrt *)NULL;
+ return;
+}
diff --git a/lib/libss/requests.c b/lib/libss/requests.c
new file mode 100644
index 0000000..7aaf4f5
--- /dev/null
+++ b/lib/libss/requests.c
@@ -0,0 +1,52 @@
+/*
+ * Various minor routines...
+ *
+ * Copyright 1987, 1988, 1989 by MIT
+ *
+ * For copyright information, see copyright.h.
+ */
+
+#include "copyright.h"
+#include <stdio.h>
+#include "ss_internal.h"
+
+#define DECLARE(name) name(argc,argv,sci_idx)int argc,sci_idx;char **argv;
+
+/*
+ * ss_self_identify -- assigned by default to the "." request
+ */
+void
+DECLARE(ss_self_identify)
+{
+ register ss_data *info = ss_info(sci_idx);
+ printf("%s version %s\n", info->subsystem_name,
+ info->subsystem_version);
+}
+
+/*
+ * ss_subsystem_name -- print name of subsystem
+ */
+void
+DECLARE(ss_subsystem_name)
+{
+ printf("%s\n", ss_info(sci_idx)->subsystem_name);
+}
+
+/*
+ * ss_subsystem_version -- print version of subsystem
+ */
+void
+DECLARE(ss_subsystem_version)
+{
+ printf("%s\n", ss_info(sci_idx)->subsystem_version);
+}
+
+/*
+ * ss_unimplemented -- routine not implemented (should be
+ * set up as (dont_list,dont_summarize))
+ */
+void
+DECLARE(ss_unimplemented)
+{
+ ss_perror(sci_idx, SS_ET_UNIMPLEMENTED, "");
+}
diff --git a/lib/libss/ss.h b/lib/libss/ss.h
new file mode 100644
index 0000000..a727d8e
--- /dev/null
+++ b/lib/libss/ss.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1987, 1988 by MIT Student Information Processing Board
+ *
+ * For copyright information, see mit-sipb-copyright.h.
+ */
+
+#ifndef _ss_h
+#define _ss_h __FILE__
+
+#if 0
+#include <ss/mit-sipb-copyright.h>
+#endif
+#ifndef IN_MK_CMDS
+# ifdef IN_LIBSS
+# include "ss_err.h"
+# else
+# include <ss/ss_err.h>
+# endif
+#endif
+
+extern int errno;
+
+#ifdef __STDC__
+#define __SS_CONST const
+#define __SS_PROTO (int, const char * const *, int, void *)
+#else
+#define __SS_CONST
+#define __SS_PROTO ()
+#endif
+
+typedef __SS_CONST struct _ss_request_entry {
+ __SS_CONST char * __SS_CONST *command_names; /* whatever */
+ void (* __SS_CONST function) __SS_PROTO; /* foo */
+ __SS_CONST char * __SS_CONST info_string; /* NULL */
+ int flags; /* 0 */
+} ss_request_entry;
+
+typedef __SS_CONST struct _ss_request_table {
+ int version;
+ ss_request_entry *requests;
+} ss_request_table;
+
+#define SS_RQT_TBL_V2 2
+
+typedef struct _ss_rp_options { /* DEFAULT VALUES */
+ int version; /* SS_RP_V1 */
+ void (*unknown) __SS_PROTO; /* call for unknown command */
+ int allow_suspend;
+ int catch_int;
+} ss_rp_options;
+
+#define SS_RP_V1 1
+
+#define SS_OPT_DONT_LIST 0x0001
+#define SS_OPT_DONT_SUMMARIZE 0x0002
+
+void ss_help __SS_PROTO;
+char *ss_current_request();
+char *ss_name();
+#ifdef __STDC__
+void ss_error (int, long, char const *, ...);
+void ss_perror (int, long, char const *);
+#else
+void ss_error ();
+void ss_perror ();
+#endif
+void ss_abort_subsystem();
+extern ss_request_table ss_std_requests;
+#endif /* _ss_h */
diff --git a/lib/libss/ss_err.et b/lib/libss/ss_err.et
new file mode 100644
index 0000000..80e9dfa
--- /dev/null
+++ b/lib/libss/ss_err.et
@@ -0,0 +1,39 @@
+ error_table ss
+
+ec SS_ET_SUBSYSTEM_ABORTED,
+ "Subsystem aborted"
+
+ec SS_ET_VERSION_MISMATCH,
+ "Version mismatch"
+
+ec SS_ET_NULL_INV,
+ "No current invocation"
+
+ec SS_ET_NO_INFO_DIR,
+ "No info directory"
+
+ec SS_ET_COMMAND_NOT_FOUND,
+ "Command not found"
+
+ec SS_ET_LINE_ABORTED,
+ "Command line aborted"
+
+ec SS_ET_EOF,
+ "End-of-file reached"
+
+ec SS_ET_PERMISSION_DENIED,
+ "Permission denied"
+
+ec SS_ET_TABLE_NOT_FOUND,
+ "Request table not found"
+
+ec SS_ET_NO_HELP_FILE,
+ "No info available"
+
+ec SS_ET_ESCAPE_DISABLED,
+ "Shell escapes are disabled"
+
+ec SS_ET_UNIMPLEMENTED,
+ "Sorry, this request is not yet implemented"
+
+ end
diff --git a/lib/libss/ss_internal.h b/lib/libss/ss_internal.h
new file mode 100644
index 0000000..240e6ab
--- /dev/null
+++ b/lib/libss/ss_internal.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 1987, 1988 by MIT Student Information Processing Board
+ *
+ * For copyright information, see copyright.h.
+ */
+
+#ifndef _ss_ss_internal_h
+#define _ss_ss_internal_h __FILE__
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __STDC__
+
+#define PROTOTYPE(p) p
+typedef void * pointer;
+
+#else
+
+#define const
+#define volatile
+#define PROTOTYPE(p) ()
+typedef char * pointer;
+
+#endif /* not __STDC__ */
+
+#include "ss.h"
+
+#if defined(__GNUC__)
+#define LOCAL_ALLOC(x) __builtin_alloca(x)
+#define LOCAL_FREE(x)
+#else
+#if defined(vax)
+#define LOCAL_ALLOC(x) alloca(x)
+#define LOCAL_FREE(x)
+extern pointer alloca PROTOTYPE((unsigned));
+#else
+#if defined(__HIGHC__) /* Barf! */
+pragma on(alloca);
+#define LOCAL_ALLOC(x) alloca(x)
+#define LOCAL_FREE(x)
+extern pointer alloca PROTOTYPE((unsigned));
+#else
+/* no alloca? */
+#define LOCAL_ALLOC(x) malloc(x)
+#define LOCAL_FREE(x) free(x)
+#endif
+#endif
+#endif /* LOCAL_ALLOC stuff */
+
+typedef char BOOL;
+
+typedef struct _ss_abbrev_entry {
+ char *name; /* abbrev name */
+ char **abbrev; /* new tokens to insert */
+ char beginning_of_line : 1;
+} ss_abbrev_entry;
+
+typedef struct _ss_abbrev_list {
+ int n_abbrevs;
+ ss_abbrev_entry *first_abbrev;
+} ss_abbrev_list;
+
+typedef struct {
+/* char *path; */
+ ss_abbrev_list abbrevs[127];
+} ss_abbrev_info;
+
+typedef struct _ss_data { /* init values */
+ /* this subsystem */
+ char *subsystem_name;
+ char *subsystem_version;
+ /* current request info */
+ int argc;
+ char **argv; /* arg list */
+ char const *current_request; /* primary name */
+ /* info directory for 'help' */
+ char **info_dirs;
+ /* to be extracted by subroutines */
+ pointer info_ptr; /* (void *) NULL */
+ /* for ss_listen processing */
+ char *prompt;
+ ss_request_table **rqt_tables;
+ ss_abbrev_info *abbrev_info;
+ struct {
+ unsigned char escape_disabled : 1,
+ abbrevs_disabled : 1;
+ } flags;
+ /* to get out */
+ int abort; /* exit subsystem */
+ int exit_status;
+} ss_data;
+
+#define CURRENT_SS_VERSION 1
+
+#define ss_info(sci_idx) (_ss_table[sci_idx])
+#define ss_current_request(sci_idx,code_ptr) \
+ (*code_ptr=0,ss_info(sci_idx)->current_request)
+void ss_unknown_function();
+void ss_delete_info_dir();
+int ss_execute_line();
+char **ss_parse();
+ss_abbrev_info *ss_abbrev_initialize PROTOTYPE((char *, int *));
+void ss_page_stdin();
+
+extern ss_data **_ss_table;
+extern char *ss_et_msgs[];
+
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
+extern pointer malloc PROTOTYPE((unsigned));
+extern pointer realloc PROTOTYPE((pointer, unsigned));
+extern pointer calloc PROTOTYPE((unsigned, unsigned));
+extern int exit PROTOTYPE((int));
+#endif
+
+#endif /* _ss_internal_h */
diff --git a/lib/libss/std_rqs.ct b/lib/libss/std_rqs.ct
new file mode 100644
index 0000000..500288a
--- /dev/null
+++ b/lib/libss/std_rqs.ct
@@ -0,0 +1,46 @@
+ command_table ss_std_requests;
+
+ request ss_self_identify, "Identify the subsystem.",
+ ".",
+ (dont_list, dont_summarize);
+
+ request ss_help, "Display info on command or topic.",
+ help;
+
+ unimplemented
+ ss_list_help,
+ "List topics for which help is available.",
+ list_help, lh;
+
+ request ss_list_requests, "List available commands.",
+ list_requests, lr, "?";
+
+ request ss_quit, "Leave the subsystem.",
+ quit, q;
+
+ unimplemented
+ ss_abbrev,
+ "Enable/disable abbreviation processing of request lines.",
+ abbrev, ab;
+
+ unimplemented
+ ss_execute,
+ "Execute a UNIX command line.",
+ execute, e;
+
+ unimplemented
+ ss_summarize_requests,
+ "Produce a list of the most commonly used requests.",
+ "?";
+
+ request ss_subsystem_name,
+ "Return the name of this subsystem.",
+ subsystem_name,
+ (dont_list);
+
+ request ss_subsystem_version,
+ "Return the version of this subsystem.",
+ subsystem_version,
+ (dont_list);
+
+ end;
diff --git a/lib/libstand/Makefile b/lib/libstand/Makefile
new file mode 100644
index 0000000..3e2aef4
--- /dev/null
+++ b/lib/libstand/Makefile
@@ -0,0 +1,124 @@
+# $FreeBSD$
+#
+# Originally from $NetBSD: Makefile,v 1.21 1997/10/26 22:08:38 lukem Exp $
+#
+# Notes:
+# - We don't use the libc strerror/sys_errlist because the string table is
+# quite large.
+#
+
+LIB= stand
+NOPROFILE= YES
+NOPIC= YES
+MAN3= libstand.3
+
+# Mostly OK, some of the libc imports are a bit noisy
+CFLAGS+= -Wall
+
+.if ${MACHINE_ARCH} == "alpha"
+CFLAGS+= -mno-fp-regs
+.endif
+
+# standalone components and stuff we have modified locally
+SRCS+= __main.c assert.c bcd.c bswap.c environment.c getopt.c gets.c \
+ globals.c pager.c printf.c strdup.c strerror.c strtol.c random.c \
+ sbrk.c twiddle.c zalloc.c zalloc_malloc.c
+
+# private (pruned) versions of libc string functions
+SRCS+= strcasecmp.c
+
+# string functions from libc
+.PATH: ${.CURDIR}/../libc/string
+.if ${MACHINE_ARCH} == "i386"
+SRCS+= bcmp.c bcopy.c bzero.c ffs.c index.c memccpy.c memchr.c memcmp.c \
+ memcpy.c memmove.c memset.c qdivrem.c rindex.c strcat.c strchr.c \
+ strcmp.c strcpy.c strcspn.c strlen.c strncat.c strncmp.c strncpy.c \
+ strpbrk.c strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c
+.endif
+.if ${MACHINE_ARCH} == "alpha"
+.PATH: ${.CURDIR}/../libc/alpha/string
+SRCS+= bcmp.c bcopy.S bzero.S ffs.S index.c memccpy.c memchr.c memcmp.c \
+ memcpy.S memmove.S memset.c rindex.c strcat.c strchr.c \
+ strcmp.c strcpy.c strcspn.c strlen.c \
+ strncat.c strncmp.c strncpy.c strpbrk.c strrchr.c strsep.c \
+ strspn.c strstr.c strtok.c swab.c
+
+.PATH: ${.CURDIR}/../libc/alpha/net
+SRCS+= htons.S ntohs.S htonl.S ntohl.S
+
+SRCS+= __divqu.S __divq.S __divlu.S __divl.S
+SRCS+= __remqu.S __remq.S __remlu.S __reml.S
+
+CLEANFILES+= __divqu.S __divq.S __divlu.S __divl.S
+CLEANFILES+= __remqu.S __remq.S __remlu.S __reml.S
+
+
+__divqu.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__divqu -DOP=div -DS=false -DWORDSIZE=64 \
+ ${.ALLSRC} > ${.TARGET}
+
+__divq.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__divq -DOP=div -DS=true -DWORDSIZE=64 \
+ ${.ALLSRC} > ${.TARGET}
+
+__divlu.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__divlu -DOP=div -DS=false -DWORDSIZE=32 \
+ ${.ALLSRC} > ${.TARGET}
+
+__divl.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__divl -DOP=div -DS=true -DWORDSIZE=32 \
+ ${.ALLSRC} > ${.TARGET}
+
+__remqu.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__remqu -DOP=rem -DS=false -DWORDSIZE=64 \
+ ${.ALLSRC} > ${.TARGET}
+
+__remq.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__remq -DOP=rem -DS=true -DWORDSIZE=64 \
+ ${.ALLSRC} > ${.TARGET}
+
+__remlu.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__remlu -DOP=rem -DS=false -DWORDSIZE=32 \
+ ${.ALLSRC} > ${.TARGET}
+
+__reml.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4
+ m4 -DNAME=__reml -DOP=rem -DS=true -DWORDSIZE=32 \
+ ${.ALLSRC} > ${.TARGET}
+.endif
+
+# network support from libc
+.PATH: ${.CURDIR}/../libc/net
+SRCS+= inet_ntoa.c inet_addr.c
+
+# _setjmp/_longjmp
+.PATH: ${.CURDIR}/${MACHINE_ARCH}
+SRCS+= _setjmp.S
+# really only required for i386
+CFLAGS+=-I${.CURDIR}/../libc/${MACHINE_ARCH}
+
+# decompression functionality from libz
+.PATH: ${.CURDIR}/../libz
+CFLAGS+=-DHAVE_MEMCPY
+SRCS+= adler32.c crc32.c infblock.c infcodes.c inffast.c inflate.c \
+ inftrees.c infutil.c zutil.c
+
+# io routines
+SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \
+ fstat.c close.c lseek.c open.c read.c write.c
+
+# network routines
+SRCS+= arp.c ether.c in_cksum.c net.c netif.c rpc.c
+
+# network info services:
+SRCS+= bootp.c rarp.c bootparam.c
+
+# boot filesystems
+SRCS+= ufs.c nfs.c cd9660.c tftp.c zipfs.c
+SRCS+= netif.c nfs.c
+SRCS+= dosfs.c
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/stand.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libstand/__main.c b/lib/libstand/__main.c
new file mode 100644
index 0000000..be23105
--- /dev/null
+++ b/lib/libstand/__main.c
@@ -0,0 +1,40 @@
+/* $NetBSD: __main.c,v 1.4 1996/03/14 18:52:03 christos Exp $ */
+
+/*
+ * Copyright (c) 1993 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+
+void __main(void);
+
+void
+__main()
+{
+}
diff --git a/lib/libstand/alpha/_setjmp.S b/lib/libstand/alpha/_setjmp.S
new file mode 100644
index 0000000..96be5ec
--- /dev/null
+++ b/lib/libstand/alpha/_setjmp.S
@@ -0,0 +1,116 @@
+/* $NetBSD: _setjmp.S,v 1.2 1996/10/17 03:08:03 cgd Exp $ */
+/* $FreeBSD$ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ * _longjmp(a,v)
+ * will generate a "return(v)" from
+ * the last call to
+ * _setjmp(a)
+ * by restoring registers from the stack,
+ * The previous signal state is NOT restored.
+ */
+
+ .set noreorder
+
+LEAF(_setjmp, 1)
+ LDGP(pv)
+ stq ra, (2 * 8)(a0) /* sc_pc = return address */
+ stq s0, (( 9 + 4) * 8)(a0) /* saved bits of sc_regs */
+ stq s1, ((10 + 4) * 8)(a0)
+ stq s2, ((11 + 4) * 8)(a0)
+ stq s3, ((12 + 4) * 8)(a0)
+ stq s4, ((13 + 4) * 8)(a0)
+ stq s5, ((14 + 4) * 8)(a0)
+ stq s6, ((15 + 4) * 8)(a0)
+ stq ra, ((26 + 4) * 8)(a0)
+ stq sp, ((30 + 4) * 8)(a0)
+ ldiq t0, 0xacedbadd /* sigcontext magic number */
+ stq t0, ((31 + 4) * 8)(a0) /* magic in sc_regs[31] */
+ /* Too bad we can't check if we actually used FP */
+ ldiq t0, 1
+ stq t0, (36 * 8)(a0) /* say we've used FP. */
+ stt fs0, ((2 + 37) * 8)(a0) /* saved bits of sc_fpregs */
+ stt fs1, ((3 + 37) * 8)(a0)
+ stt fs2, ((4 + 37) * 8)(a0)
+ stt fs3, ((5 + 37) * 8)(a0)
+ stt fs4, ((6 + 37) * 8)(a0)
+ stt fs5, ((7 + 37) * 8)(a0)
+ stt fs6, ((8 + 37) * 8)(a0)
+ stt fs7, ((9 + 37) * 8)(a0)
+ mf_fpcr ft0 /* get FP control reg */
+ stt ft0, (69 * 8)(a0) /* and store it in sc_fpcr */
+ stq zero, (70 * 8)(a0) /* FP software control XXX */
+ stq zero, (71 * 8)(a0) /* sc_reserved[0] */
+ stq zero, (72 * 8)(a0) /* sc_reserved[1] */
+ stq zero, (73 * 8)(a0) /* sc_xxx[0] */
+ stq zero, (74 * 8)(a0) /* sc_xxx[1] */
+ stq zero, (75 * 8)(a0) /* sc_xxx[2] */
+ stq zero, (76 * 8)(a0) /* sc_xxx[3] */
+ stq zero, (77 * 8)(a0) /* sc_xxx[4] */
+ stq zero, (78 * 8)(a0) /* sc_xxx[5] */
+ stq zero, (79 * 8)(a0) /* sc_xxx[6] */
+ stq zero, (80 * 8)(a0) /* sc_xxx[7] */
+
+ mov zero, v0 /* return zero */
+ RET
+END(_setjmp)
+
+LEAF(_longjmp, 2)
+ LDGP(pv)
+
+ ldq ra, (2 * 8)(a0) /* sc_pc = return address */
+ ldq s0, (( 9 + 4) * 8)(a0) /* saved bits of sc_regs */
+ ldq s1, ((10 + 4) * 8)(a0)
+ ldq s2, ((11 + 4) * 8)(a0)
+ ldq s3, ((12 + 4) * 8)(a0)
+ ldq s4, ((13 + 4) * 8)(a0)
+ ldq s5, ((14 + 4) * 8)(a0)
+ ldq s6, ((15 + 4) * 8)(a0)
+ /* ldq ra, ((26 + 4) * 8)(a0) set above */
+ ldq sp, ((30 + 4) * 8)(a0)
+ ldt fs0, ((2 + 37) * 8)(a0) /* saved bits of sc_fpregs */
+ ldt fs1, ((3 + 37) * 8)(a0)
+ ldt fs2, ((4 + 37) * 8)(a0)
+ ldt fs3, ((5 + 37) * 8)(a0)
+ ldt fs4, ((6 + 37) * 8)(a0)
+ ldt fs5, ((7 + 37) * 8)(a0)
+ ldt fs6, ((8 + 37) * 8)(a0)
+ ldt fs7, ((9 + 37) * 8)(a0)
+ ldt ft0, (69 * 8)(a0) /* get sc_fpcr */
+ mt_fpcr ft0 /* and restore it. */
+
+ mov a1, v0 /* return second arg */
+ RET
+
+END(_longjmp)
diff --git a/lib/libstand/arp.c b/lib/libstand/arp.c
new file mode 100644
index 0000000..4736b51
--- /dev/null
+++ b/lib/libstand/arp.c
@@ -0,0 +1,310 @@
+/* $NetBSD: arp.c,v 1.18 1997/07/07 15:52:49 drochner Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Header: arp.c,v 1.5 93/07/15 05:52:26 leres Exp (LBL)
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <netinet/in_systm.h>
+
+#include <string.h>
+
+#include "stand.h"
+#include "net.h"
+
+/* Cache stuff */
+#define ARP_NUM 8 /* need at most 3 arp entries */
+
+struct arp_list {
+ struct in_addr addr;
+ u_char ea[6];
+} arp_list[ARP_NUM] = {
+ /* XXX - net order `INADDR_BROADCAST' must be a constant */
+ { {0xffffffff}, BA }
+};
+int arp_num = 1;
+
+/* Local forwards */
+static ssize_t arpsend(struct iodesc *, void *, size_t);
+static ssize_t arprecv(struct iodesc *, void *, size_t, time_t);
+
+/* Broadcast an ARP packet, asking who has addr on interface d */
+u_char *
+arpwhohas(d, addr)
+ register struct iodesc *d;
+ struct in_addr addr;
+{
+ register int i;
+ register struct ether_arp *ah;
+ register struct arp_list *al;
+ struct {
+ struct ether_header eh;
+ struct {
+ struct ether_arp arp;
+ u_char pad[18]; /* 60 - sizeof(...) */
+ } data;
+ } wbuf;
+ struct {
+ struct ether_header eh;
+ struct {
+ struct ether_arp arp;
+ u_char pad[24]; /* extra space */
+ } data;
+ } rbuf;
+
+ /* Try for cached answer first */
+ for (i = 0, al = arp_list; i < arp_num; ++i, ++al)
+ if (addr.s_addr == al->addr.s_addr)
+ return (al->ea);
+
+ /* Don't overflow cache */
+ if (arp_num > ARP_NUM - 1) {
+ arp_num = 1; /* recycle */
+ printf("arpwhohas: overflowed arp_list!\n");
+ }
+
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("arpwhohas: send request for %s\n", inet_ntoa(addr));
+#endif
+
+ bzero((char*)&wbuf.data, sizeof(wbuf.data));
+ ah = &wbuf.data.arp;
+ ah->arp_hrd = htons(ARPHRD_ETHER);
+ ah->arp_pro = htons(ETHERTYPE_IP);
+ ah->arp_hln = sizeof(ah->arp_sha); /* hardware address length */
+ ah->arp_pln = sizeof(ah->arp_spa); /* protocol address length */
+ ah->arp_op = htons(ARPOP_REQUEST);
+ MACPY(d->myea, ah->arp_sha);
+ bcopy(&d->myip, ah->arp_spa, sizeof(ah->arp_spa));
+ /* Leave zeros in arp_tha */
+ bcopy(&addr, ah->arp_tpa, sizeof(ah->arp_tpa));
+
+ /* Store ip address in cache (incomplete entry). */
+ al->addr = addr;
+
+ i = sendrecv(d,
+ arpsend, &wbuf.data, sizeof(wbuf.data),
+ arprecv, &rbuf.data, sizeof(rbuf.data));
+ if (i == -1) {
+ panic("arp: no response for %s\n",
+ inet_ntoa(addr));
+ }
+
+ /* Store ethernet address in cache */
+ ah = &rbuf.data.arp;
+#ifdef ARP_DEBUG
+ if (debug) {
+ printf("arp: response from %s\n",
+ ether_sprintf(rbuf.eh.ether_shost));
+ printf("arp: cacheing %s --> %s\n",
+ inet_ntoa(addr), ether_sprintf(ah->arp_sha));
+ }
+#endif
+ MACPY(ah->arp_sha, al->ea);
+ ++arp_num;
+
+ return (al->ea);
+}
+
+static ssize_t
+arpsend(d, pkt, len)
+ register struct iodesc *d;
+ register void *pkt;
+ register size_t len;
+{
+
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("arpsend: called\n");
+#endif
+
+ return (sendether(d, pkt, len, bcea, ETHERTYPE_ARP));
+}
+
+/*
+ * Returns 0 if this is the packet we're waiting for
+ * else -1 (and errno == 0)
+ */
+static ssize_t
+arprecv(d, pkt, len, tleft)
+ register struct iodesc *d;
+ register void *pkt;
+ register size_t len;
+ time_t tleft;
+{
+ register ssize_t n;
+ register struct ether_arp *ah;
+ u_int16_t etype; /* host order */
+
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("arprecv: ");
+#endif
+
+ n = readether(d, pkt, len, tleft, &etype);
+ errno = 0; /* XXX */
+ if (n == -1 || n < sizeof(struct ether_arp)) {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("bad len=%d\n", n);
+#endif
+ return (-1);
+ }
+
+ if (etype != ETHERTYPE_ARP) {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("not arp type=%d\n", etype);
+#endif
+ return (-1);
+ }
+
+ /* Ethernet address now checked in readether() */
+
+ ah = (struct ether_arp *)pkt;
+ if (ah->arp_hrd != htons(ARPHRD_ETHER) ||
+ ah->arp_pro != htons(ETHERTYPE_IP) ||
+ ah->arp_hln != sizeof(ah->arp_sha) ||
+ ah->arp_pln != sizeof(ah->arp_spa) )
+ {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("bad hrd/pro/hln/pln\n");
+#endif
+ return (-1);
+ }
+
+ if (ah->arp_op == htons(ARPOP_REQUEST)) {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("is request\n");
+#endif
+ arp_reply(d, ah);
+ return (-1);
+ }
+
+ if (ah->arp_op != htons(ARPOP_REPLY)) {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("not ARP reply\n");
+#endif
+ return (-1);
+ }
+
+ /* Is the reply from the source we want? */
+ if (bcmp(&arp_list[arp_num].addr,
+ ah->arp_spa, sizeof(ah->arp_spa)))
+ {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("unwanted address\n");
+#endif
+ return (-1);
+ }
+ /* We don't care who the reply was sent to. */
+
+ /* We have our answer. */
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("got it\n");
+#endif
+ return (n);
+}
+
+/*
+ * Convert an ARP request into a reply and send it.
+ * Notes: Re-uses buffer. Pad to length = 46.
+ */
+void
+arp_reply(d, pkt)
+ register struct iodesc *d;
+ register void *pkt; /* the request */
+{
+ struct ether_arp *arp = pkt;
+
+ if (arp->arp_hrd != htons(ARPHRD_ETHER) ||
+ arp->arp_pro != htons(ETHERTYPE_IP) ||
+ arp->arp_hln != sizeof(arp->arp_sha) ||
+ arp->arp_pln != sizeof(arp->arp_spa) )
+ {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("arp_reply: bad hrd/pro/hln/pln\n");
+#endif
+ return;
+ }
+
+ if (arp->arp_op != htons(ARPOP_REQUEST)) {
+#ifdef ARP_DEBUG
+ if (debug)
+ printf("arp_reply: not request!\n");
+#endif
+ return;
+ }
+
+ /* If we are not the target, ignore the request. */
+ if (bcmp(arp->arp_tpa, &d->myip, sizeof(arp->arp_tpa)))
+ return;
+
+#ifdef ARP_DEBUG
+ if (debug) {
+ printf("arp_reply: to %s\n", ether_sprintf(arp->arp_sha));
+ }
+#endif
+
+ arp->arp_op = htons(ARPOP_REPLY);
+ /* source becomes target */
+ bcopy(arp->arp_sha, arp->arp_tha, sizeof(arp->arp_tha));
+ bcopy(arp->arp_spa, arp->arp_tpa, sizeof(arp->arp_tpa));
+ /* here becomes source */
+ bcopy(d->myea, arp->arp_sha, sizeof(arp->arp_sha));
+ bcopy(&d->myip, arp->arp_spa, sizeof(arp->arp_spa));
+
+ /*
+ * No need to get fancy here. If the send fails, the
+ * requestor will just ask again.
+ */
+ (void) sendether(d, pkt, sizeof(*arp) + 18,
+ arp->arp_tha, ETHERTYPE_ARP);
+}
diff --git a/lib/libstand/assert.c b/lib/libstand/assert.c
new file mode 100644
index 0000000..4811528
--- /dev/null
+++ b/lib/libstand/assert.c
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 1998 Michael Smith.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stand.h>
+#include <assert.h>
+
+void
+__assert(const char *file, int line, const char *expression)
+{
+ printf("assertion \"%s\" failed: file \"%s\", line %d\n", expression, file, line);
+ exit();
+}
diff --git a/lib/libstand/bcd.c b/lib/libstand/bcd.c
new file mode 100644
index 0000000..540ed5f
--- /dev/null
+++ b/lib/libstand/bcd.c
@@ -0,0 +1,35 @@
+/*
+ * Some data-tables that are often used.
+ * Cannot be copyrighted.
+ */
+
+#include <sys/libkern.h>
+
+u_char const bcd2bin_data[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0, 0,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 0, 0, 0, 0, 0, 0,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 0, 0, 0, 0, 0, 0,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 0, 0, 0, 0, 0, 0,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, 0, 0,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
+};
+
+u_char const bin2bcd_data[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99
+};
+
+/* This is actually used with radix [2..36] */
+char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
diff --git a/lib/libstand/bootp.c b/lib/libstand/bootp.c
new file mode 100644
index 0000000..35ccf7a
--- /dev/null
+++ b/lib/libstand/bootp.c
@@ -0,0 +1,396 @@
+/* $NetBSD: bootp.c,v 1.14 1998/02/16 11:10:54 drochner Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Header: bootp.c,v 1.4 93/09/11 03:13:51 leres Exp (LBL)
+ */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <string.h>
+
+#define BOOTP_DEBUGxx
+#define SUPPORT_DHCP
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+#include "bootp.h"
+
+
+struct in_addr servip;
+
+static n_long nmask, smask;
+
+static time_t bot;
+
+static char vm_rfc1048[4] = VM_RFC1048;
+#ifdef BOOTP_VEND_CMU
+static char vm_cmu[4] = VM_CMU;
+#endif
+
+/* Local forwards */
+static ssize_t bootpsend(struct iodesc *, void *, size_t);
+static ssize_t bootprecv(struct iodesc *, void *, size_t, time_t);
+static int vend_rfc1048(u_char *, u_int);
+#ifdef BOOTP_VEND_CMU
+static void vend_cmu(u_char *);
+#endif
+
+#ifdef SUPPORT_DHCP
+static char expected_dhcpmsgtype = -1, dhcp_ok;
+struct in_addr dhcp_serverip;
+#endif
+
+/* Fetch required bootp infomation */
+void
+bootp(sock)
+ int sock;
+{
+ struct iodesc *d;
+ register struct bootp *bp;
+ struct {
+ u_char header[HEADER_SIZE];
+ struct bootp wbootp;
+ } wbuf;
+ struct {
+ u_char header[HEADER_SIZE];
+ struct bootp rbootp;
+ } rbuf;
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("bootp: socket=%d\n", sock);
+#endif
+ if (!bot)
+ bot = getsecs();
+
+ if (!(d = socktodesc(sock))) {
+ printf("bootp: bad socket. %d\n", sock);
+ return;
+ }
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("bootp: d=%lx\n", (long)d);
+#endif
+
+ bp = &wbuf.wbootp;
+ bzero(bp, sizeof(*bp));
+
+ bp->bp_op = BOOTREQUEST;
+ bp->bp_htype = 1; /* 10Mb Ethernet (48 bits) */
+ bp->bp_hlen = 6;
+ bp->bp_xid = htonl(d->xid);
+ MACPY(d->myea, bp->bp_chaddr);
+ strncpy(bp->bp_file, bootfile, sizeof(bp->bp_file));
+ bcopy(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048));
+#ifdef SUPPORT_DHCP
+ bp->bp_vend[4] = TAG_DHCP_MSGTYPE;
+ bp->bp_vend[5] = 1;
+ bp->bp_vend[6] = DHCPDISCOVER;
+ bp->bp_vend[7] = TAG_END;
+#else
+ bp->bp_vend[4] = TAG_END;
+#endif
+
+ d->myip.s_addr = INADDR_ANY;
+ d->myport = htons(IPPORT_BOOTPC);
+ d->destip.s_addr = INADDR_BROADCAST;
+ d->destport = htons(IPPORT_BOOTPS);
+
+#ifdef SUPPORT_DHCP
+ expected_dhcpmsgtype = DHCPOFFER;
+ dhcp_ok = 0;
+#endif
+
+ if(sendrecv(d,
+ bootpsend, bp, sizeof(*bp),
+ bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
+ == -1) {
+ printf("bootp: no reply\n");
+ return;
+ }
+
+#ifdef SUPPORT_DHCP
+ if(dhcp_ok) {
+ u_int32_t leasetime;
+ bp->bp_vend[6] = DHCPREQUEST;
+ bp->bp_vend[7] = TAG_REQ_ADDR;
+ bp->bp_vend[8] = 4;
+ bcopy(&rbuf.rbootp.bp_yiaddr, &bp->bp_vend[9], 4);
+ bp->bp_vend[13] = TAG_SERVERID;
+ bp->bp_vend[14] = 4;
+ bcopy(&dhcp_serverip.s_addr, &bp->bp_vend[15], 4);
+ bp->bp_vend[19] = TAG_LEASETIME;
+ bp->bp_vend[20] = 4;
+ leasetime = htonl(300);
+ bcopy(&leasetime, &bp->bp_vend[21], 4);
+ bp->bp_vend[25] = TAG_END;
+
+ expected_dhcpmsgtype = DHCPACK;
+
+ if(sendrecv(d,
+ bootpsend, bp, sizeof(*bp),
+ bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
+ == -1) {
+ printf("DHCPREQUEST failed\n");
+ return;
+ }
+ }
+#endif
+
+ myip = d->myip = rbuf.rbootp.bp_yiaddr;
+ servip = rbuf.rbootp.bp_siaddr;
+ if(rootip.s_addr == INADDR_ANY) rootip = servip;
+ bcopy(rbuf.rbootp.bp_file, bootfile, sizeof(bootfile));
+ bootfile[sizeof(bootfile) - 1] = '\0';
+
+ if (IN_CLASSA(myip.s_addr))
+ nmask = htonl(IN_CLASSA_NET);
+ else if (IN_CLASSB(myip.s_addr))
+ nmask = htonl(IN_CLASSB_NET);
+ else
+ nmask = htonl(IN_CLASSC_NET);
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("'native netmask' is %s\n", intoa(nmask));
+#endif
+
+ /* Check subnet mask against net mask; toss if bogus */
+ if ((nmask & smask) != nmask) {
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("subnet mask (%s) bad\n", intoa(smask));
+#endif
+ smask = 0;
+ }
+
+ /* Get subnet (or natural net) mask */
+ netmask = nmask;
+ if (smask)
+ netmask = smask;
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("mask: %s\n", intoa(netmask));
+#endif
+
+ /* We need a gateway if root is on a different net */
+ if (!SAMENET(myip, rootip, netmask)) {
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("need gateway for root ip\n");
+#endif
+ }
+
+ /* Toss gateway if on a different net */
+ if (!SAMENET(myip, gateip, netmask)) {
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("gateway ip (%s) bad\n", inet_ntoa(gateip));
+#endif
+ gateip.s_addr = 0;
+ }
+
+ /* Bump xid so next request will be unique. */
+ ++d->xid;
+}
+
+/* Transmit a bootp request */
+static ssize_t
+bootpsend(d, pkt, len)
+ register struct iodesc *d;
+ register void *pkt;
+ register size_t len;
+{
+ register struct bootp *bp;
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("bootpsend: d=%lx called.\n", (long)d);
+#endif
+
+ bp = pkt;
+ bp->bp_secs = htons((u_short)(getsecs() - bot));
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("bootpsend: calling sendudp\n");
+#endif
+
+ return (sendudp(d, pkt, len));
+}
+
+static ssize_t
+bootprecv(d, pkt, len, tleft)
+register struct iodesc *d;
+register void *pkt;
+register size_t len;
+time_t tleft;
+{
+ register ssize_t n;
+ register struct bootp *bp;
+
+#ifdef BOOTP_DEBUGx
+ if (debug)
+ printf("bootp_recvoffer: called\n");
+#endif
+
+ n = readudp(d, pkt, len, tleft);
+ if (n == -1 || n < sizeof(struct bootp) - BOOTP_VENDSIZE)
+ goto bad;
+
+ bp = (struct bootp *)pkt;
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("bootprecv: checked. bp = 0x%lx, n = %d\n",
+ (long)bp, (int)n);
+#endif
+ if (bp->bp_xid != htonl(d->xid)) {
+#ifdef BOOTP_DEBUG
+ if (debug) {
+ printf("bootprecv: expected xid 0x%lx, got 0x%x\n",
+ d->xid, ntohl(bp->bp_xid));
+ }
+#endif
+ goto bad;
+ }
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("bootprecv: got one!\n");
+#endif
+
+ /* Suck out vendor info */
+ if (bcmp(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048)) == 0) {
+ if(vend_rfc1048(bp->bp_vend, sizeof(bp->bp_vend)) != 0)
+ goto bad;
+ }
+#ifdef BOOTP_VEND_CMU
+ else if (bcmp(vm_cmu, bp->bp_vend, sizeof(vm_cmu)) == 0)
+ vend_cmu(bp->bp_vend);
+#endif
+ else
+ printf("bootprecv: unknown vendor 0x%lx\n", (long)bp->bp_vend);
+
+ return(n);
+bad:
+ errno = 0;
+ return (-1);
+}
+
+static int
+vend_rfc1048(cp, len)
+ register u_char *cp;
+ u_int len;
+{
+ register u_char *ep;
+ register int size;
+ register u_char tag;
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("vend_rfc1048 bootp info. len=%d\n", len);
+#endif
+ ep = cp + len;
+
+ /* Step over magic cookie */
+ cp += sizeof(int);
+
+ while (cp < ep) {
+ tag = *cp++;
+ size = *cp++;
+ if (tag == TAG_END)
+ break;
+
+ if (tag == TAG_SUBNET_MASK) {
+ bcopy(cp, &smask, sizeof(smask));
+ }
+ if (tag == TAG_GATEWAY) {
+ bcopy(cp, &gateip.s_addr, sizeof(gateip.s_addr));
+ }
+ if (tag == TAG_SWAPSERVER) {
+ /* let it override bp_siaddr */
+ bcopy(cp, &rootip.s_addr, sizeof(swapip.s_addr));
+ }
+ if (tag == TAG_ROOTPATH) {
+ strncpy(rootpath, (char *)cp, sizeof(rootpath));
+ rootpath[size] = '\0';
+ }
+ if (tag == TAG_HOSTNAME) {
+ strncpy(hostname, (char *)cp, sizeof(hostname));
+ hostname[size] = '\0';
+ }
+#ifdef SUPPORT_DHCP
+ if (tag == TAG_DHCP_MSGTYPE) {
+ if(*cp != expected_dhcpmsgtype)
+ return(-1);
+ dhcp_ok = 1;
+ }
+ if (tag == TAG_SERVERID) {
+ bcopy(cp, &dhcp_serverip.s_addr,
+ sizeof(dhcp_serverip.s_addr));
+ }
+#endif
+ cp += size;
+ }
+ return(0);
+}
+
+#ifdef BOOTP_VEND_CMU
+static void
+vend_cmu(cp)
+ u_char *cp;
+{
+ register struct cmu_vend *vp;
+
+#ifdef BOOTP_DEBUG
+ if (debug)
+ printf("vend_cmu bootp info.\n");
+#endif
+ vp = (struct cmu_vend *)cp;
+
+ if (vp->v_smask.s_addr != 0) {
+ smask = vp->v_smask.s_addr;
+ }
+ if (vp->v_dgate.s_addr != 0) {
+ gateip = vp->v_dgate;
+ }
+}
+#endif
diff --git a/lib/libstand/bootp.h b/lib/libstand/bootp.h
new file mode 100644
index 0000000..7435e3c
--- /dev/null
+++ b/lib/libstand/bootp.h
@@ -0,0 +1,137 @@
+/* $NetBSD: bootp.h,v 1.4 1997/09/06 13:55:57 drochner Exp $ */
+
+/*
+ * Bootstrap Protocol (BOOTP). RFC951 and RFC1048.
+ *
+ * This file specifies the "implementation-independent" BOOTP protocol
+ * information which is common to both client and server.
+ *
+ * Copyright 1988 by Carnegie Mellon.
+ *
+ * Permission to use, copy, modify, and distribute this program for any
+ * purpose and without fee is hereby granted, provided that this copyright
+ * and permission notice appear on all copies and supporting documentation,
+ * the name of Carnegie Mellon not be used in advertising or publicity
+ * pertaining to distribution of the program without specific prior
+ * permission, and notice be given in supporting documentation that copying
+ * and distribution is by permission of Carnegie Mellon and Stanford
+ * University. Carnegie Mellon makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+
+struct bootp {
+ unsigned char bp_op; /* packet opcode type */
+ unsigned char bp_htype; /* hardware addr type */
+ unsigned char bp_hlen; /* hardware addr length */
+ unsigned char bp_hops; /* gateway hops */
+ unsigned int bp_xid; /* transaction ID */
+ unsigned short bp_secs; /* seconds since boot began */
+ unsigned short bp_flags;
+ struct in_addr bp_ciaddr; /* client IP address */
+ struct in_addr bp_yiaddr; /* 'your' IP address */
+ struct in_addr bp_siaddr; /* server IP address */
+ struct in_addr bp_giaddr; /* gateway IP address */
+ unsigned char bp_chaddr[16]; /* client hardware address */
+ unsigned char bp_sname[64]; /* server host name */
+ unsigned char bp_file[128]; /* boot file name */
+#ifdef SUPPORT_DHCP
+#define BOOTP_VENDSIZE 312
+#else
+#define BOOTP_VENDSIZE 64
+#endif
+ unsigned char bp_vend[BOOTP_VENDSIZE]; /* vendor-specific area */
+};
+
+/*
+ * UDP port numbers, server and client.
+ */
+#define IPPORT_BOOTPS 67
+#define IPPORT_BOOTPC 68
+
+#define BOOTREPLY 2
+#define BOOTREQUEST 1
+
+
+/*
+ * Vendor magic cookie (v_magic) for CMU
+ */
+#define VM_CMU "CMU"
+
+/*
+ * Vendor magic cookie (v_magic) for RFC1048
+ */
+#define VM_RFC1048 { 99, 130, 83, 99 }
+
+
+
+/*
+ * RFC1048 tag values used to specify what information is being supplied in
+ * the vendor field of the packet.
+ */
+
+#define TAG_PAD ((unsigned char) 0)
+#define TAG_SUBNET_MASK ((unsigned char) 1)
+#define TAG_TIME_OFFSET ((unsigned char) 2)
+#define TAG_GATEWAY ((unsigned char) 3)
+#define TAG_TIME_SERVER ((unsigned char) 4)
+#define TAG_NAME_SERVER ((unsigned char) 5)
+#define TAG_DOMAIN_SERVER ((unsigned char) 6)
+#define TAG_LOG_SERVER ((unsigned char) 7)
+#define TAG_COOKIE_SERVER ((unsigned char) 8)
+#define TAG_LPR_SERVER ((unsigned char) 9)
+#define TAG_IMPRESS_SERVER ((unsigned char) 10)
+#define TAG_RLP_SERVER ((unsigned char) 11)
+#define TAG_HOSTNAME ((unsigned char) 12)
+#define TAG_BOOTSIZE ((unsigned char) 13)
+#define TAG_DUMPFILE ((unsigned char) 14)
+#define TAG_DOMAINNAME ((unsigned char) 15)
+#define TAG_SWAPSERVER ((unsigned char) 16)
+#define TAG_ROOTPATH ((unsigned char) 17)
+
+#ifdef SUPPORT_DHCP
+#define TAG_REQ_ADDR ((unsigned char) 50)
+#define TAG_LEASETIME ((unsigned char) 51)
+#define TAG_OVERLOAD ((unsigned char) 52)
+#define TAG_DHCP_MSGTYPE ((unsigned char) 53)
+#define TAG_SERVERID ((unsigned char) 54)
+#define TAG_PARAM_REQ ((unsigned char) 55)
+#define TAG_MSG ((unsigned char) 56)
+#define TAG_MAXSIZE ((unsigned char) 57)
+#define TAG_T1 ((unsigned char) 58)
+#define TAG_T2 ((unsigned char) 59)
+#define TAG_CLASSID ((unsigned char) 60)
+#define TAG_CLIENTID ((unsigned char) 61)
+#endif
+
+#define TAG_END ((unsigned char) 255)
+
+#ifdef SUPPORT_DHCP
+#define DHCPDISCOVER 1
+#define DHCPOFFER 2
+#define DHCPREQUEST 3
+#define DHCPDECLINE 4
+#define DHCPACK 5
+#define DHCPNAK 6
+#define DHCPRELEASE 7
+#endif
+
+/*
+ * "vendor" data permitted for CMU bootp clients.
+ */
+
+struct cmu_vend {
+ unsigned char v_magic[4]; /* magic number */
+ unsigned int v_flags; /* flags/opcodes, etc. */
+ struct in_addr v_smask; /* Subnet mask */
+ struct in_addr v_dgate; /* Default gateway */
+ struct in_addr v_dns1, v_dns2; /* Domain name servers */
+ struct in_addr v_ins1, v_ins2; /* IEN-116 name servers */
+ struct in_addr v_ts1, v_ts2; /* Time servers */
+ unsigned char v_unused[25]; /* currently unused */
+};
+
+
+/* v_flags values */
+#define VF_SMASK 1 /* Subnet mask field contains valid data */
diff --git a/lib/libstand/bootparam.c b/lib/libstand/bootparam.c
new file mode 100644
index 0000000..6d64e7a
--- /dev/null
+++ b/lib/libstand/bootparam.c
@@ -0,0 +1,449 @@
+/* $NetBSD: bootparam.c,v 1.11 1997/06/26 19:11:32 drochner Exp $ */
+
+/*
+ * Copyright (c) 1995 Gordon W. Ross
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * 4. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gordon W. Ross
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * RPC/bootparams
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <string.h>
+
+#include "rpcv2.h"
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+#include "rpc.h"
+#include "bootparam.h"
+
+#ifdef DEBUG_RPC
+#define RPC_PRINTF(a) printf a
+#else
+#define RPC_PRINTF(a)
+#endif
+
+struct in_addr bp_server_addr; /* net order */
+n_short bp_server_port; /* net order */
+
+/*
+ * RPC definitions for bootparamd
+ */
+#define BOOTPARAM_PROG 100026
+#define BOOTPARAM_VERS 1
+#define BOOTPARAM_WHOAMI 1
+#define BOOTPARAM_GETFILE 2
+
+/*
+ * Inet address in RPC messages
+ * (Note, really four ints, NOT chars. Blech.)
+ */
+struct xdr_inaddr {
+ u_int32_t atype;
+ int32_t addr[4];
+};
+
+int xdr_inaddr_encode(char **p, struct in_addr ia);
+int xdr_inaddr_decode(char **p, struct in_addr *ia);
+
+int xdr_string_encode(char **p, char *str, int len);
+int xdr_string_decode(char **p, char *str, int *len_p);
+
+
+/*
+ * RPC: bootparam/whoami
+ * Given client IP address, get:
+ * client name (hostname)
+ * domain name (domainname)
+ * gateway address
+ *
+ * The hostname and domainname are set here for convenience.
+ *
+ * Note - bpsin is initialized to the broadcast address,
+ * and will be replaced with the bootparam server address
+ * after this call is complete. Have to use PMAP_PROC_CALL
+ * to make sure we get responses only from a servers that
+ * know about us (don't want to broadcast a getport call).
+ */
+int
+bp_whoami(sockfd)
+ int sockfd;
+{
+ /* RPC structures for PMAPPROC_CALLIT */
+ struct args {
+ u_int32_t prog;
+ u_int32_t vers;
+ u_int32_t proc;
+ u_int32_t arglen;
+ struct xdr_inaddr xina;
+ } *args;
+ struct repl {
+ u_int16_t _pad;
+ u_int16_t port;
+ u_int32_t encap_len;
+ /* encapsulated data here */
+ n_long capsule[64];
+ } *repl;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct repl d;
+ } rdata;
+ char *send_tail, *recv_head;
+ struct iodesc *d;
+ int len, x;
+
+ RPC_PRINTF(("bp_whoami: myip=%s\n", inet_ntoa(myip)));
+
+ if (!(d = socktodesc(sockfd))) {
+ RPC_PRINTF(("bp_whoami: bad socket. %d\n", sockfd));
+ return (-1);
+ }
+ args = &sdata.d;
+ repl = &rdata.d;
+
+ /*
+ * Build request args for PMAPPROC_CALLIT.
+ */
+ args->prog = htonl(BOOTPARAM_PROG);
+ args->vers = htonl(BOOTPARAM_VERS);
+ args->proc = htonl(BOOTPARAM_WHOAMI);
+ args->arglen = htonl(sizeof(struct xdr_inaddr));
+ send_tail = (char*) &args->xina;
+
+ /*
+ * append encapsulated data (client IP address)
+ */
+ if (xdr_inaddr_encode(&send_tail, myip))
+ return (-1);
+
+ /* RPC: portmap/callit */
+ d->myport = htons(--rpc_port);
+ d->destip.s_addr = INADDR_BROADCAST; /* XXX: subnet bcast? */
+ /* rpc_call will set d->destport */
+
+ len = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_CALLIT,
+ args, send_tail - (char*)args,
+ repl, sizeof(*repl));
+ if (len < 8) {
+ printf("bootparamd: 'whoami' call failed\n");
+ return (-1);
+ }
+
+ /* Save bootparam server address (from IP header). */
+ rpc_fromaddr(repl, &bp_server_addr, &bp_server_port);
+
+ /*
+ * Note that bp_server_port is now 111 due to the
+ * indirect call (using PMAPPROC_CALLIT), so get the
+ * actual port number from the reply data.
+ */
+ bp_server_port = repl->port;
+
+ RPC_PRINTF(("bp_whoami: server at %s:%d\n",
+ inet_ntoa(bp_server_addr), ntohs(bp_server_port)));
+
+ /* We have just done a portmap call, so cache the portnum. */
+ rpc_pmap_putcache(bp_server_addr,
+ BOOTPARAM_PROG,
+ BOOTPARAM_VERS,
+ (int)ntohs(bp_server_port));
+
+ /*
+ * Parse the encapsulated results from bootparam/whoami
+ */
+ x = ntohl(repl->encap_len);
+ if (len < x) {
+ printf("bp_whoami: short reply, %d < %d\n", len, x);
+ return (-1);
+ }
+ recv_head = (char*) repl->capsule;
+
+ /* client name */
+ hostnamelen = MAXHOSTNAMELEN-1;
+ if (xdr_string_decode(&recv_head, hostname, &hostnamelen)) {
+ RPC_PRINTF(("bp_whoami: bad hostname\n"));
+ return (-1);
+ }
+
+ /* domain name */
+ domainnamelen = MAXHOSTNAMELEN-1;
+ if (xdr_string_decode(&recv_head, domainname, &domainnamelen)) {
+ RPC_PRINTF(("bp_whoami: bad domainname\n"));
+ return (-1);
+ }
+
+ /* gateway address */
+ if (xdr_inaddr_decode(&recv_head, &gateip)) {
+ RPC_PRINTF(("bp_whoami: bad gateway\n"));
+ return (-1);
+ }
+
+ /* success */
+ return(0);
+}
+
+
+/*
+ * RPC: bootparam/getfile
+ * Given client name and file "key", get:
+ * server name
+ * server IP address
+ * server pathname
+ */
+int
+bp_getfile(sockfd, key, serv_addr, pathname)
+ int sockfd;
+ char *key;
+ char *pathname;
+ struct in_addr *serv_addr;
+{
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ n_long d[64];
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ n_long d[128];
+ } rdata;
+ char serv_name[FNAME_SIZE];
+ char *send_tail, *recv_head;
+ /* misc... */
+ struct iodesc *d;
+ int sn_len, path_len, rlen;
+
+ if (!(d = socktodesc(sockfd))) {
+ RPC_PRINTF(("bp_getfile: bad socket. %d\n", sockfd));
+ return (-1);
+ }
+
+ send_tail = (char*) sdata.d;
+ recv_head = (char*) rdata.d;
+
+ /*
+ * Build request message.
+ */
+
+ /* client name (hostname) */
+ if (xdr_string_encode(&send_tail, hostname, hostnamelen)) {
+ RPC_PRINTF(("bp_getfile: bad client\n"));
+ return (-1);
+ }
+
+ /* key name (root or swap) */
+ if (xdr_string_encode(&send_tail, key, strlen(key))) {
+ RPC_PRINTF(("bp_getfile: bad key\n"));
+ return (-1);
+ }
+
+ /* RPC: bootparam/getfile */
+ d->myport = htons(--rpc_port);
+ d->destip = bp_server_addr;
+ /* rpc_call will set d->destport */
+
+ rlen = rpc_call(d,
+ BOOTPARAM_PROG, BOOTPARAM_VERS, BOOTPARAM_GETFILE,
+ sdata.d, send_tail - (char*)sdata.d,
+ rdata.d, sizeof(rdata.d));
+ if (rlen < 4) {
+ RPC_PRINTF(("bp_getfile: short reply\n"));
+ errno = EBADRPC;
+ return (-1);
+ }
+ recv_head = (char*) rdata.d;
+
+ /*
+ * Parse result message.
+ */
+
+ /* server name */
+ sn_len = FNAME_SIZE-1;
+ if (xdr_string_decode(&recv_head, serv_name, &sn_len)) {
+ RPC_PRINTF(("bp_getfile: bad server name\n"));
+ return (-1);
+ }
+
+ /* server IP address (mountd/NFS) */
+ if (xdr_inaddr_decode(&recv_head, serv_addr)) {
+ RPC_PRINTF(("bp_getfile: bad server addr\n"));
+ return (-1);
+ }
+
+ /* server pathname */
+ path_len = MAXPATHLEN-1;
+ if (xdr_string_decode(&recv_head, pathname, &path_len)) {
+ RPC_PRINTF(("bp_getfile: bad server path\n"));
+ return (-1);
+ }
+
+ /* success */
+ return(0);
+}
+
+
+/*
+ * eXternal Data Representation routines.
+ * (but with non-standard args...)
+ */
+
+
+int
+xdr_string_encode(pkt, str, len)
+ char **pkt;
+ char *str;
+ int len;
+{
+ u_int32_t *lenp;
+ char *datap;
+ int padlen = (len + 3) & ~3; /* padded length */
+
+ /* The data will be int aligned. */
+ lenp = (u_int32_t*) *pkt;
+ *pkt += sizeof(*lenp);
+ *lenp = htonl(len);
+
+ datap = *pkt;
+ *pkt += padlen;
+ bcopy(str, datap, len);
+
+ return (0);
+}
+
+int
+xdr_string_decode(pkt, str, len_p)
+ char **pkt;
+ char *str;
+ int *len_p; /* bufsize - 1 */
+{
+ u_int32_t *lenp;
+ char *datap;
+ int slen; /* string length */
+ int plen; /* padded length */
+
+ /* The data will be int aligned. */
+ lenp = (u_int32_t*) *pkt;
+ *pkt += sizeof(*lenp);
+ slen = ntohl(*lenp);
+ plen = (slen + 3) & ~3;
+
+ if (slen > *len_p)
+ slen = *len_p;
+ datap = *pkt;
+ *pkt += plen;
+ bcopy(datap, str, slen);
+
+ str[slen] = '\0';
+ *len_p = slen;
+
+ return (0);
+}
+
+
+int
+xdr_inaddr_encode(pkt, ia)
+ char **pkt;
+ struct in_addr ia; /* network order */
+{
+ struct xdr_inaddr *xi;
+ u_char *cp;
+ int32_t *ip;
+ union {
+ n_long l; /* network order */
+ u_char c[4];
+ } uia;
+
+ /* The data will be int aligned. */
+ xi = (struct xdr_inaddr *) *pkt;
+ *pkt += sizeof(*xi);
+ xi->atype = htonl(1);
+ uia.l = ia.s_addr;
+ cp = uia.c;
+ ip = xi->addr;
+ /*
+ * Note: the htonl() calls below DO NOT
+ * imply that uia.l is in host order.
+ * In fact this needs it in net order.
+ */
+ *ip++ = htonl((unsigned int)*cp++);
+ *ip++ = htonl((unsigned int)*cp++);
+ *ip++ = htonl((unsigned int)*cp++);
+ *ip++ = htonl((unsigned int)*cp++);
+
+ return (0);
+}
+
+int
+xdr_inaddr_decode(pkt, ia)
+ char **pkt;
+ struct in_addr *ia; /* network order */
+{
+ struct xdr_inaddr *xi;
+ u_char *cp;
+ int32_t *ip;
+ union {
+ n_long l; /* network order */
+ u_char c[4];
+ } uia;
+
+ /* The data will be int aligned. */
+ xi = (struct xdr_inaddr *) *pkt;
+ *pkt += sizeof(*xi);
+ if (xi->atype != htonl(1)) {
+ RPC_PRINTF(("xdr_inaddr_decode: bad addrtype=%d\n",
+ ntohl(xi->atype)));
+ return(-1);
+ }
+
+ cp = uia.c;
+ ip = xi->addr;
+ /*
+ * Note: the ntohl() calls below DO NOT
+ * imply that uia.l is in host order.
+ * In fact this needs it in net order.
+ */
+ *cp++ = ntohl(*ip++);
+ *cp++ = ntohl(*ip++);
+ *cp++ = ntohl(*ip++);
+ *cp++ = ntohl(*ip++);
+ ia->s_addr = uia.l;
+
+ return (0);
+}
diff --git a/lib/libstand/bootparam.h b/lib/libstand/bootparam.h
new file mode 100644
index 0000000..6f0c773
--- /dev/null
+++ b/lib/libstand/bootparam.h
@@ -0,0 +1,5 @@
+/* $NetBSD: bootparam.h,v 1.3 1998/01/05 19:19:41 perry Exp $ */
+
+int bp_whoami(int sock);
+int bp_getfile(int sock, char *key, struct in_addr *addrp, char *path);
+
diff --git a/lib/libstand/bswap.c b/lib/libstand/bswap.c
new file mode 100644
index 0000000..1951509
--- /dev/null
+++ b/lib/libstand/bswap.c
@@ -0,0 +1,37 @@
+/*
+ * Written by Manuel Bouyer <bouyer@netbsd.org>.
+ * Public domain.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$NetBSD: bswap32.c,v 1.1 1997/10/09 15:42:33 bouyer Exp $";
+static char *rcsid = "$NetBSD: bswap64.c,v 1.1 1997/10/09 15:42:33 bouyer Exp $";
+#endif
+
+#include <sys/types.h>
+
+#undef bswap32
+#undef bswap64
+
+u_int32_t
+bswap32(x)
+ u_int32_t x;
+{
+ return ((x << 24) & 0xff000000 ) |
+ ((x << 8) & 0x00ff0000 ) |
+ ((x >> 8) & 0x0000ff00 ) |
+ ((x >> 24) & 0x000000ff );
+}
+
+u_int64_t
+bswap64(x)
+ u_int64_t x;
+{
+ u_int32_t *p = (u_int32_t*)&x;
+ u_int32_t t;
+ t = bswap32(p[0]);
+ p[0] = bswap32(p[1]);
+ p[1] = t;
+ return x;
+}
+
diff --git a/lib/libstand/cd9660.c b/lib/libstand/cd9660.c
new file mode 100644
index 0000000..0930582
--- /dev/null
+++ b/lib/libstand/cd9660.c
@@ -0,0 +1,401 @@
+/* $NetBSD: cd9660.c,v 1.5 1997/06/26 19:11:33 drochner Exp $ */
+
+/*
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Stand-alone ISO9660 file reading package.
+ *
+ * Note: This doesn't support Rock Ridge extensions, extended attributes,
+ * blocksizes other than 2048 bytes, multi-extent files, etc.
+ */
+#include <sys/param.h>
+#include <string.h>
+#include <isofs/cd9660/iso.h>
+
+#include "stand.h"
+
+static int cd9660_open(const char *path, struct open_file *f);
+static int cd9660_close(struct open_file *f);
+static int cd9660_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static int cd9660_write(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t cd9660_seek(struct open_file *f, off_t offset, int where);
+static int cd9660_stat(struct open_file *f, struct stat *sb);
+
+struct fs_ops cd9660_fsops = {
+ "cd9660", cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek, cd9660_stat
+};
+
+struct file {
+ off_t off; /* Current offset within file */
+ daddr_t bno; /* Starting block number */
+ off_t size; /* Size of file */
+};
+
+struct ptable_ent {
+ char namlen [ISODCL( 1, 1)]; /* 711 */
+ char extlen [ISODCL( 2, 2)]; /* 711 */
+ char block [ISODCL( 3, 6)]; /* 732 */
+ char parent [ISODCL( 7, 8)]; /* 722 */
+ char name [1];
+};
+#define PTFIXSZ 8
+#define PTSIZE(pp) roundup(PTFIXSZ + isonum_711((pp)->namlen), 2)
+
+#define cdb2devb(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE / DEV_BSIZE)
+
+/* XXX these should be in the system headers */
+static __inline int
+isonum_722(p)
+ u_char *p;
+{
+ return (*p << 8)|p[1];
+}
+
+static __inline int
+isonum_732(p)
+ u_char *p;
+{
+ return (*p << 24)|(p[1] << 16)|(p[2] << 8)|p[3];
+}
+
+
+
+static int
+pnmatch(path, pp)
+ const char *path;
+ struct ptable_ent *pp;
+{
+ char *cp;
+ int i;
+
+ cp = pp->name;
+ for (i = isonum_711(pp->namlen); --i >= 0; path++, cp++) {
+ if (toupper(*path) == *cp)
+ continue;
+ return 0;
+ }
+ if (*path != '/')
+ return 0;
+ return 1;
+}
+
+static int
+dirmatch(path, dp)
+ const char *path;
+ struct iso_directory_record *dp;
+{
+ char *cp;
+ int i;
+
+ /* This needs to be a regular file */
+ if (dp->flags[0] & 6)
+ return 0;
+
+ cp = dp->name;
+ for (i = isonum_711(dp->name_len); --i >= 0; path++, cp++) {
+ if (!*path)
+ break;
+ if (toupper(*path) == *cp)
+ continue;
+ return 0;
+ }
+ if (*path)
+ return 0;
+ /*
+ * Allow stripping of trailing dots and the version number.
+ * Note that this will find the first instead of the last version
+ * of a file.
+ */
+ if (i >= 0 && (*cp == ';' || *cp == '.')) {
+ /* This is to prevent matching of numeric extensions */
+ if (*cp == '.' && cp[1] != ';')
+ return 0;
+ while (--i >= 0)
+ if (*++cp != ';' && (*cp < '0' || *cp > '9'))
+ return 0;
+ }
+ return 1;
+}
+
+static int
+cd9660_open(path, f)
+ const char *path;
+ struct open_file *f;
+{
+ struct file *fp = 0;
+ void *buf;
+ struct iso_primary_descriptor *vd;
+ size_t buf_size, read, psize, dsize;
+ daddr_t bno;
+ int parent, ent;
+ struct ptable_ent *pp;
+ struct iso_directory_record *dp = 0;
+ int rc;
+
+ /* First find the volume descriptor */
+ buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE);
+ vd = buf;
+ for (bno = 16;; bno++) {
+ twiddle();
+ rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno),
+ ISO_DEFAULT_BLOCK_SIZE, buf, &read);
+ if (rc)
+ goto out;
+ if (read != ISO_DEFAULT_BLOCK_SIZE) {
+ rc = EIO;
+ goto out;
+ }
+ rc = EINVAL;
+ if (bcmp(vd->id, ISO_STANDARD_ID, sizeof vd->id) != 0)
+ goto out;
+ if (isonum_711(vd->type) == ISO_VD_END)
+ goto out;
+ if (isonum_711(vd->type) == ISO_VD_PRIMARY)
+ break;
+ }
+ if (isonum_723(vd->logical_block_size) != ISO_DEFAULT_BLOCK_SIZE)
+ goto out;
+
+ /* Now get the path table and lookup the directory of the file */
+ bno = isonum_732(vd->type_m_path_table);
+ psize = isonum_733(vd->path_table_size);
+
+ if (psize > ISO_DEFAULT_BLOCK_SIZE) {
+ free(buf);
+ buf = malloc(buf_size = roundup(psize, ISO_DEFAULT_BLOCK_SIZE));
+ }
+
+ twiddle();
+ rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno),
+ buf_size, buf, &read);
+ if (rc)
+ goto out;
+ if (read != buf_size) {
+ rc = EIO;
+ goto out;
+ }
+
+ parent = 1;
+ pp = (struct ptable_ent *)buf;
+ ent = 1;
+ bno = isonum_732(pp->block) + isonum_711(pp->extlen);
+
+ rc = ENOENT;
+ while (*path) {
+ if ((void *)pp >= buf + psize)
+ break;
+ if (isonum_722(pp->parent) != parent)
+ break;
+ if (!pnmatch(path, pp)) {
+ pp = (struct ptable_ent *)((void *)pp + PTSIZE(pp));
+ ent++;
+ continue;
+ }
+ path += isonum_711(pp->namlen) + 1;
+ parent = ent;
+ bno = isonum_732(pp->block) + isonum_711(pp->extlen);
+ while ((void *)pp < buf + psize) {
+ if (isonum_722(pp->parent) == parent)
+ break;
+ pp = (struct ptable_ent *)((void *)pp + PTSIZE(pp));
+ ent++;
+ }
+ }
+
+ /* Now bno has the start of the directory that supposedly contains the file */
+ bno--;
+ dsize = 1; /* Something stupid, but > 0 XXX */
+ for (psize = 0; psize < dsize;) {
+ if (!(psize % ISO_DEFAULT_BLOCK_SIZE)) {
+ bno++;
+ twiddle();
+ rc = f->f_dev->dv_strategy(f->f_devdata, F_READ,
+ cdb2devb(bno),
+ ISO_DEFAULT_BLOCK_SIZE,
+ buf, &read);
+ if (rc)
+ goto out;
+ if (read != ISO_DEFAULT_BLOCK_SIZE) {
+ rc = EIO;
+ goto out;
+ }
+ dp = (struct iso_directory_record *)buf;
+ }
+ if (!isonum_711(dp->length)) {
+ if ((void *)dp == buf)
+ psize += ISO_DEFAULT_BLOCK_SIZE;
+ else
+ psize = roundup(psize, ISO_DEFAULT_BLOCK_SIZE);
+ continue;
+ }
+ if (dsize == 1)
+ dsize = isonum_733(dp->size);
+ if (dirmatch(path, dp))
+ break;
+ psize += isonum_711(dp->length);
+ dp = (struct iso_directory_record *)((void *)dp + isonum_711(dp->length));
+ }
+
+ if (psize >= dsize) {
+ rc = ENOENT;
+ goto out;
+ }
+
+ /* allocate file system specific data structure */
+ fp = malloc(sizeof(struct file));
+ bzero(fp, sizeof(struct file));
+ f->f_fsdata = (void *)fp;
+
+ fp->off = 0;
+ fp->bno = isonum_733(dp->extent);
+ fp->size = isonum_733(dp->size);
+ free(buf);
+
+ return 0;
+
+out:
+ if (fp)
+ free(fp);
+ free(buf);
+
+ return rc;
+}
+
+static int
+cd9660_close(f)
+ struct open_file *f;
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ f->f_fsdata = 0;
+ free(fp);
+
+ return 0;
+}
+
+static int
+cd9660_read(f, start, size, resid)
+ struct open_file *f;
+ void *start;
+ size_t size;
+ size_t *resid;
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ int rc = 0;
+ daddr_t bno;
+ char buf[ISO_DEFAULT_BLOCK_SIZE];
+ char *dp;
+ size_t read, off;
+
+ while (size) {
+ if (fp->off < 0 || fp->off >= fp->size)
+ break;
+ bno = fp->off / ISO_DEFAULT_BLOCK_SIZE + fp->bno;
+ if (fp->off & (ISO_DEFAULT_BLOCK_SIZE - 1)
+ || size < ISO_DEFAULT_BLOCK_SIZE)
+ dp = buf;
+ else
+ dp = start;
+ twiddle();
+ rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno),
+ ISO_DEFAULT_BLOCK_SIZE, dp, &read);
+ if (rc)
+ return rc;
+ if (read != ISO_DEFAULT_BLOCK_SIZE)
+ return EIO;
+ if (dp == buf) {
+ off = fp->off & (ISO_DEFAULT_BLOCK_SIZE - 1);
+ if (read > off + size)
+ read = off + size;
+ read -= off;
+ bcopy(buf + off, start, read);
+ start += read;
+ fp->off += read;
+ size -= read;
+ } else {
+ start += ISO_DEFAULT_BLOCK_SIZE;
+ fp->off += ISO_DEFAULT_BLOCK_SIZE;
+ size -= ISO_DEFAULT_BLOCK_SIZE;
+ }
+ }
+ if (resid)
+ *resid = size;
+ return rc;
+}
+
+static int
+cd9660_write(f, start, size, resid)
+ struct open_file *f;
+ void *start;
+ size_t size;
+ size_t *resid;
+{
+ return EROFS;
+}
+
+static off_t
+cd9660_seek(f, offset, where)
+ struct open_file *f;
+ off_t offset;
+ int where;
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ switch (where) {
+ case SEEK_SET:
+ fp->off = offset;
+ break;
+ case SEEK_CUR:
+ fp->off += offset;
+ break;
+ case SEEK_END:
+ fp->off = fp->size - offset;
+ break;
+ default:
+ return -1;
+ }
+ return fp->off;
+}
+
+static int
+cd9660_stat(f, sb)
+ struct open_file *f;
+ struct stat *sb;
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ /* only importatn stuff */
+ sb->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
+ sb->st_uid = sb->st_gid = 0;
+ sb->st_size = fp->size;
+ return 0;
+}
diff --git a/lib/libstand/close.c b/lib/libstand/close.c
new file mode 100644
index 0000000..aca6a65
--- /dev/null
+++ b/lib/libstand/close.c
@@ -0,0 +1,96 @@
+/* $NetBSD: close.c,v 1.7 1997/01/22 00:38:09 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)close.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "stand.h"
+
+int
+close(fd)
+ int fd;
+{
+ register struct open_file *f = &files[fd];
+ int err1 = 0, err2 = 0;
+
+ if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
+ errno = EBADF;
+ return (-1);
+ }
+ if (!(f->f_flags & F_RAW) && f->f_ops)
+ err1 = (f->f_ops->fo_close)(f);
+ if (!(f->f_flags & F_NODEV) && f->f_dev)
+ err2 = (f->f_dev->dv_close)(f);
+ if (f->f_devdata != NULL)
+ devclose(f);
+ f->f_flags = 0;
+ if (err1) {
+ errno = err1;
+ return (-1);
+ }
+ if (err2) {
+ errno = err2;
+ return (-1);
+ }
+ return (0);
+}
diff --git a/lib/libstand/closeall.c b/lib/libstand/closeall.c
new file mode 100644
index 0000000..8da450a
--- /dev/null
+++ b/lib/libstand/closeall.c
@@ -0,0 +1,77 @@
+/* $NetBSD: closeall.c,v 1.1 1996/01/13 22:25:36 leo Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)close.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "stand.h"
+
+void
+closeall()
+{
+ int i;
+
+ for (i = 0; i < SOPEN_MAX; i++)
+ if (files[i].f_flags != 0)
+ (void)close(i);
+}
diff --git a/lib/libstand/dev.c b/lib/libstand/dev.c
new file mode 100644
index 0000000..c5b9c27
--- /dev/null
+++ b/lib/libstand/dev.c
@@ -0,0 +1,62 @@
+/* $NetBSD: dev.c,v 1.4 1994/10/30 21:48:23 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)dev.c 8.1 (Berkeley) 6/11/93
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+
+#include "stand.h"
+
+int
+nodev()
+{
+ return (ENXIO);
+}
+
+void
+nullsys()
+{
+}
+
+/* ARGSUSED */
+int
+noioctl(f, cmd, data)
+ struct open_file *f;
+ u_long cmd;
+ void *data;
+{
+ return (EINVAL);
+}
diff --git a/lib/libstand/dev_net.c b/lib/libstand/dev_net.c
new file mode 100644
index 0000000..cfa9fbf
--- /dev/null
+++ b/lib/libstand/dev_net.c
@@ -0,0 +1,268 @@
+/* $NetBSD: dev_net.c,v 1.12 1997/12/10 20:38:37 gwr Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Gordon W. Ross.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This module implements a "raw device" interface suitable for
+ * use by the stand-alone I/O library NFS code. This interface
+ * does not support any "block" access, and exists only for the
+ * purpose of initializing the network interface, getting boot
+ * parameters, and performing the NFS mount.
+ *
+ * At open time, this does:
+ *
+ * find interface - netif_open()
+ * RARP for IP address - rarp_getipaddress()
+ * RPC/bootparams - callrpc(d, RPC_BOOTPARAMS, ...)
+ * RPC/mountd - nfs_mount(sock, ip, path)
+ *
+ * the root file handle from mountd is saved in a global
+ * for use by the NFS open code (NFS/lookup).
+ */
+
+#include <machine/stdarg.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+#include "nfs.h"
+#include "bootparam.h"
+#include "dev_net.h"
+
+static int netdev_sock = -1;
+static int netdev_opens;
+
+static int net_getparams(int sock);
+
+static void net_print(int verbose);
+
+struct devsw netdev = {
+ "net",
+ DEVT_NET,
+ net_init,
+ net_strategy,
+ net_open,
+ net_close,
+ noioctl
+ net_print,
+};
+
+/*
+ * Print stuff about our net 'device'.
+ */
+static void
+net_print(int verbose)
+{
+ pager_output(" net: network interface");
+ /* XXX much more verbose stuff here */
+}
+
+/*
+ * Called by devopen after it sets f->f_dev to our devsw entry.
+ * This opens the low-level device and sets f->f_devdata.
+ * This is declared with variable arguments...
+ */
+int
+net_open(struct open_file *f, void *vdev)
+{
+ char *devname; /* Device part of file name (or NULL). */
+ int error = 0;
+
+ devname = vdev;
+
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_open: %s\n", devname);
+#endif
+
+ /* On first open, do netif open, mount, etc. */
+ if (netdev_opens == 0) {
+ /* Find network interface. */
+ if (netdev_sock < 0) {
+ netdev_sock = netif_open(devname);
+ if (netdev_sock < 0) {
+ printf("net_open: netif_open() failed\n");
+ return (ENXIO);
+ }
+ if (debug)
+ printf("net_open: netif_open() succeeded\n");
+ }
+ if (rootip.s_addr == 0) {
+ /* Get root IP address, and path, etc. */
+ error = net_getparams(netdev_sock);
+ if (error) {
+ /* getparams makes its own noise */
+ netif_close(netdev_sock);
+ netdev_sock = -1;
+ return (error);
+ }
+ }
+ }
+ netdev_opens++;
+ return (error);
+}
+
+int
+net_close(f)
+ struct open_file *f;
+{
+
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_close: opens=%d\n", netdev_opens);
+#endif
+
+ /* On last close, do netif close, etc. */
+ f->f_devdata = NULL;
+ /* Extra close call? */
+ if (netdev_opens <= 0)
+ return (0);
+ netdev_opens--;
+ /* Not last close? */
+ if (netdev_opens > 0)
+ return(0);
+ rootip.s_addr = 0;
+ if (netdev_sock >= 0) {
+ if (debug)
+ printf("net_close: calling netif_close()\n");
+ netif_close(netdev_sock);
+ netdev_sock = -1;
+ }
+ return (0);
+}
+
+int
+net_ioctl()
+{
+ return EIO;
+}
+
+int
+net_strategy()
+{
+ return EIO;
+}
+
+
+/*
+ * Get info for NFS boot: our IP address, our hostname,
+ * server IP address, and our root path on the server.
+ * There are two ways to do this: The old, Sun way,
+ * and the more modern, BOOTP way. (RFC951, RFC1048)
+ *
+ * The default is to use the Sun bootparams RPC
+ * (because that is what the kernel will do).
+ * MD code can make try_bootp initialied data,
+ * which will override this common definition.
+ */
+#ifdef SUPPORT_BOOTP
+int try_bootp;
+int bootp(int sock);
+#endif
+
+static int
+net_getparams(sock)
+ int sock;
+{
+ char buf[MAXHOSTNAMELEN];
+ n_long smask;
+
+#ifdef SUPPORT_BOOTP
+ /*
+ * Try to get boot info using BOOTP. If we succeed, then
+ * the server IP address, gateway, and root path will all
+ * be initialized. If any remain uninitialized, we will
+ * use RARP and RPC/bootparam (the Sun way) to get them.
+ */
+ if (try_bootp)
+ bootp(sock);
+ if (myip.s_addr != 0)
+ return (0);
+ if (debug)
+ printf("net_open: BOOTP failed, trying RARP/RPC...\n");
+#endif
+
+ /*
+ * Use RARP to get our IP address. This also sets our
+ * netmask to the "natural" default for our address.
+ */
+ if (rarp_getipaddress(sock)) {
+ printf("net_open: RARP failed\n");
+ return (EIO);
+ }
+ printf("net_open: client addr: %s\n", inet_ntoa(myip));
+
+ /* Get our hostname, server IP address, gateway. */
+ if (bp_whoami(sock)) {
+ printf("net_open: bootparam/whoami RPC failed\n");
+ return (EIO);
+ }
+ printf("net_open: client name: %s\n", hostname);
+
+ /*
+ * Ignore the gateway from whoami (unreliable).
+ * Use the "gateway" parameter instead.
+ */
+ smask = 0;
+ gateip.s_addr = 0;
+ if (bp_getfile(sock, "gateway", &gateip, buf) == 0) {
+ /* Got it! Parse the netmask. */
+ smask = ip_convertaddr(buf);
+ }
+ if (smask) {
+ netmask = smask;
+ printf("net_open: subnet mask: %s\n", intoa(netmask));
+ }
+ if (gateip.s_addr)
+ printf("net_open: net gateway: %s\n", inet_ntoa(gateip));
+
+ /* Get the root server and pathname. */
+ if (bp_getfile(sock, "root", &rootip, rootpath)) {
+ printf("net_open: bootparam/getfile RPC failed\n");
+ return (EIO);
+ }
+
+ printf("net_open: server addr: %s\n", inet_ntoa(rootip));
+ printf("net_open: server path: %s\n", rootpath);
+
+ return (0);
+}
diff --git a/lib/libstand/dev_net.h b/lib/libstand/dev_net.h
new file mode 100644
index 0000000..f728c4f
--- /dev/null
+++ b/lib/libstand/dev_net.h
@@ -0,0 +1,7 @@
+/* $NetBSD: dev_net.h,v 1.3 1997/03/15 18:12:14 is Exp $ */
+
+int net_open(struct open_file *, ...);
+int net_close(struct open_file *);
+int net_ioctl();
+int net_strategy();
+
diff --git a/lib/libstand/dosfs.c b/lib/libstand/dosfs.c
new file mode 100644
index 0000000..2910cb2
--- /dev/null
+++ b/lib/libstand/dosfs.c
@@ -0,0 +1,695 @@
+/*
+ * Copyright (c) 1996, 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Readonly filesystem for Microsoft FAT12/FAT16/FAT32 filesystems,
+ * also supports VFAT.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "stand.h"
+
+#include "dosfs.h"
+
+
+static int dos_open(const char *path, struct open_file *fd);
+static int dos_close(struct open_file *fd);
+static int dos_read(struct open_file *fd, void *buf, size_t size, size_t *resid);
+static off_t dos_seek(struct open_file *fd, off_t offset, int whence);
+static int dos_stat(struct open_file *fd, struct stat *sb);
+
+struct fs_ops dosfs_fsops = {
+ "dosfs", dos_open, dos_close, dos_read, null_write, dos_seek, dos_stat
+};
+
+#define SECSIZ 512 /* sector size */
+#define SSHIFT 9 /* SECSIZ shift */
+#define DEPSEC 16 /* directory entries per sector */
+#define DSHIFT 4 /* DEPSEC shift */
+#define LOCLUS 2 /* lowest cluster number */
+
+/* DOS "BIOS Parameter Block" */
+typedef struct {
+ u_char secsiz[2]; /* sector size */
+ u_char spc; /* sectors per cluster */
+ u_char ressec[2]; /* reserved sectors */
+ u_char fats; /* FATs */
+ u_char dirents[2]; /* root directory entries */
+ u_char secs[2]; /* total sectors */
+ u_char media; /* media descriptor */
+ u_char spf[2]; /* sectors per FAT */
+ u_char spt[2]; /* sectors per track */
+ u_char heads[2]; /* drive heads */
+ u_char hidsec[4]; /* hidden sectors */
+ u_char lsecs[4]; /* huge sectors */
+ u_char lspf[4]; /* huge sectors per FAT */
+ u_char xflg[2]; /* flags */
+ u_char vers[2]; /* filesystem version */
+ u_char rdcl[4]; /* root directory start cluster */
+ u_char infs[2]; /* filesystem info sector */
+ u_char bkbs[2]; /* backup boot sector */
+} DOS_BPB;
+
+/* Initial portion of DOS boot sector */
+typedef struct {
+ u_char jmp[3]; /* usually 80x86 'jmp' opcode */
+ u_char oem[8]; /* OEM name and version */
+ DOS_BPB bpb; /* BPB */
+} DOS_BS;
+
+/* Supply missing "." and ".." root directory entries */
+static const char *const dotstr[2] = {".", ".."};
+static DOS_DE dot[2] = {
+ {". ", " ", FA_DIR, {0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
+ {0, 0}, {0x21, 0}, {0, 0}, {0, 0, 0, 0}},
+ {".. ", " ", FA_DIR, {0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
+ {0, 0}, {0x21, 0}, {0, 0}, {0, 0, 0, 0}}
+};
+
+/* The usual conversion macros to avoid multiplication and division */
+#define bytsec(n) ((n) >> SSHIFT)
+#define secbyt(s) ((s) << SSHIFT)
+#define entsec(e) ((e) >> DSHIFT)
+#define bytblk(fs, n) ((n) >> (fs)->bshift)
+#define blkbyt(fs, b) ((b) << (fs)->bshift)
+#define secblk(fs, s) ((s) >> ((fs)->bshift - SSHIFT))
+#define blksec(fs, b) ((b) << ((fs)->bshift - SSHIFT))
+
+/* Convert cluster number to offset within filesystem */
+#define blkoff(fs, b) (secbyt((fs)->lsndta) + blkbyt(fs, (b) - LOCLUS))
+
+/* Convert cluster number to logical sector number */
+#define blklsn(fs, b) ((fs)->lsndta + blksec(fs, (b) - LOCLUS))
+
+/* Convert cluster number to offset within FAT */
+#define fatoff(sz, c) ((sz) == 12 ? (c) + ((c) >> 1) : \
+ (sz) == 16 ? (c) << 1 : \
+ (c) << 2)
+
+/* Does cluster number reference a valid data cluster? */
+#define okclus(fs, c) ((c) >= LOCLUS && (c) <= (fs)->xclus)
+
+/* Get start cluster from directory entry */
+#define stclus(sz, de) ((sz) != 32 ? cv2((de)->clus) : \
+ ((u_int)cv2((de)->dex.h_clus) << 16) | \
+ cv2((de)->clus))
+
+static int dosunmount(DOS_FS *);
+static int parsebs(DOS_FS *, DOS_BS *);
+static int namede(DOS_FS *, const char *, DOS_DE **);
+static int lookup(DOS_FS *, u_int, const char *, DOS_DE **);
+static void cp_xdnm(u_char *, DOS_XDE *);
+static void cp_sfn(u_char *, DOS_DE *);
+static off_t fsize(DOS_FS *, DOS_DE *);
+static int fatcnt(DOS_FS *, u_int);
+static int fatget(DOS_FS *, u_int *);
+static int fatend(u_int, u_int);
+static int ioread(DOS_FS *, u_int, void *, u_int);
+static int iobuf(DOS_FS *, u_int);
+static int ioget(struct open_file *, u_int, void *, u_int);
+
+/*
+ * Mount DOS filesystem
+ */
+static int
+dos_mount(DOS_FS *fs, struct open_file *fd)
+{
+ int err;
+
+ bzero(fs, sizeof(DOS_FS));
+ fs->fd = fd;
+ if ((err = !(fs->buf = malloc(SECSIZ)) ? errno : 0) ||
+ (err = ioget(fs->fd, 0, fs->buf, 1)) ||
+ (err = parsebs(fs, (DOS_BS *)fs->buf))) {
+ (void)dosunmount(fs);
+ return(err);
+ }
+ return 0;
+}
+
+/*
+ * Unmount mounted filesystem
+ */
+static int
+dos_unmount(DOS_FS *fs)
+{
+ int err;
+
+ if (fs->links)
+ return(EBUSY);
+ if ((err = dosunmount(fs)))
+ return(err);
+ return 0;
+}
+
+/*
+ * Common code shared by dos_mount() and dos_unmount()
+ */
+static int
+dosunmount(DOS_FS *fs)
+{
+ if (fs->buf)
+ free(fs->buf);
+ free(fs);
+ return(0);
+}
+
+/*
+ * Open DOS file
+ */
+static int
+dos_open(const char *path, struct open_file *fd)
+{
+ DOS_DE *de;
+ DOS_FILE *f;
+ DOS_FS *fs;
+ u_int size, clus;
+ int err = 0;
+
+ /* Allocate mount structure, associate with open */
+ fs = malloc(sizeof(DOS_FS));
+
+ if ((err = dos_mount(fs, fd)))
+ goto out;
+
+ if ((err = namede(fs, path, &de)))
+ goto out;
+
+ clus = stclus(fs->fatsz, de);
+ size = cv4(de->size);
+
+ if ((!(de->attr & FA_DIR) && (!clus != !size)) ||
+ ((de->attr & FA_DIR) && size) ||
+ (clus && !okclus(fs, clus))) {
+ err = EINVAL;
+ goto out;
+ }
+ f = malloc(sizeof(DOS_FILE));
+ bzero(f, sizeof(DOS_FILE));
+ f->fs = fs;
+ fs->links++;
+ f->de = *de;
+ fd->f_fsdata = (void *)f;
+
+ out:
+ return(err);
+}
+
+/*
+ * Read from file
+ */
+static int
+dos_read(struct open_file *fd, void *buf, size_t nbyte, size_t *resid)
+{
+ off_t size;
+ u_int nb, off, clus, c, cnt, n;
+ DOS_FILE *f = (DOS_FILE *)fd->f_fsdata;
+ int err = 0;
+
+ nb = (u_int)nbyte;
+ if ((size = fsize(f->fs, &f->de)) == -1)
+ return EINVAL;
+ if (nb > (n = size - f->offset))
+ nb = n;
+ off = f->offset;
+ if ((clus = stclus(f->fs->fatsz, &f->de)))
+ off &= f->fs->bsize - 1;
+ c = f->c;
+ cnt = nb;
+ while (cnt) {
+ n = 0;
+ if (!c) {
+ if ((c = clus))
+ n = bytblk(f->fs, f->offset);
+ } else if (!off)
+ n++;
+ while (n--) {
+ if ((err = fatget(f->fs, &c)))
+ goto out;
+ if (!okclus(f->fs, c)) {
+ err = EINVAL;
+ goto out;
+ }
+ }
+ if (!clus || (n = f->fs->bsize - off) > cnt)
+ n = cnt;
+ if ((err = ioread(f->fs, (c ? blkoff(f->fs, c) :
+ secbyt(f->fs->lsndir)) + off,
+ buf, n)))
+ goto out;
+ f->offset += n;
+ f->c = c;
+ off = 0;
+ buf += n;
+ cnt -= n;
+ }
+ out:
+ if (resid)
+ *resid = nbyte - nb + cnt;
+ return(err);
+}
+
+/*
+ * Reposition within file
+ */
+static off_t
+dos_seek(struct open_file *fd, off_t offset, int whence)
+{
+ off_t off;
+ u_int size;
+ DOS_FILE *f = (DOS_FILE *)fd->f_fsdata;
+
+ size = cv4(f->de.size);
+ switch (whence) {
+ case SEEK_SET:
+ off = 0;
+ break;
+ case SEEK_CUR:
+ off = f->offset;
+ break;
+ case SEEK_END:
+ off = size;
+ break;
+ default:
+ return(-1);
+ }
+ off += offset;
+ if (off < 0 || off > size)
+ return(-1);
+ f->offset = (u_int)off;
+ f->c = 0;
+ return(off);
+}
+
+/*
+ * Close open file
+ */
+static int
+dos_close(struct open_file *fd)
+{
+ DOS_FILE *f = (DOS_FILE *)fd->f_fsdata;
+ DOS_FS *fs = f->fs;
+
+ f->fs->links--;
+ free(f);
+ dos_unmount(fs);
+ return 0;
+}
+
+/*
+ * Return some stat information on a file.
+ */
+static int
+dos_stat(struct open_file *fd, struct stat *sb)
+{
+ DOS_FILE *f = (DOS_FILE *)fd->f_fsdata;
+
+ /* only important stuff */
+ sb->st_mode = f->de.attr & FA_DIR ? S_IFDIR | 0555 : S_IFREG | 0444;
+ sb->st_nlink = 1;
+ sb->st_uid = 0;
+ sb->st_gid = 0;
+ if ((sb->st_size = fsize(f->fs, &f->de)) == -1)
+ return EINVAL;
+ return (0);
+}
+
+/*
+ * Parse DOS boot sector
+ */
+static int
+parsebs(DOS_FS *fs, DOS_BS *bs)
+{
+ u_int sc;
+
+ if ((bs->jmp[0] != 0x69 &&
+ bs->jmp[0] != 0xe9 &&
+ (bs->jmp[0] != 0xeb || bs->jmp[2] != 0x90)) ||
+ bs->bpb.media < 0xf0)
+ return EINVAL;
+ if (cv2(bs->bpb.secsiz) != SECSIZ)
+ return EINVAL;
+ if (!(fs->spc = bs->bpb.spc) || fs->spc & (fs->spc - 1))
+ return EINVAL;
+ fs->bsize = secbyt(fs->spc);
+ fs->bshift = ffs(fs->bsize) - 1;
+ if ((fs->spf = cv2(bs->bpb.spf))) {
+ if (bs->bpb.fats != 2)
+ return EINVAL;
+ if (!(fs->dirents = cv2(bs->bpb.dirents)))
+ return EINVAL;
+ } else {
+ if (!(fs->spf = cv4(bs->bpb.lspf)))
+ return EINVAL;
+ if (!bs->bpb.fats || bs->bpb.fats > 16)
+ return EINVAL;
+ if ((fs->rdcl = cv4(bs->bpb.rdcl)) < LOCLUS)
+ return EINVAL;
+ }
+ if (!(fs->lsnfat = cv2(bs->bpb.ressec)))
+ return EINVAL;
+ fs->lsndir = fs->lsnfat + fs->spf * bs->bpb.fats;
+ fs->lsndta = fs->lsndir + entsec(fs->dirents);
+ if (!(sc = cv2(bs->bpb.secs)) && !(sc = cv4(bs->bpb.lsecs)))
+ return EINVAL;
+ if (fs->lsndta > sc)
+ return EINVAL;
+ if ((fs->xclus = secblk(fs, sc - fs->lsndta) + 1) < LOCLUS)
+ return EINVAL;
+ fs->fatsz = fs->dirents ? fs->xclus < 0xff6 ? 12 : 16 : 32;
+ sc = (secbyt(fs->spf) << 1) / (fs->fatsz >> 2) - 1;
+ if (fs->xclus > sc)
+ fs->xclus = sc;
+ return 0;
+}
+
+/*
+ * Return directory entry from path
+ */
+static int
+namede(DOS_FS *fs, const char *path, DOS_DE **dep)
+{
+ char name[256];
+ DOS_DE *de;
+ char *s;
+ size_t n;
+ int err;
+
+ err = 0;
+ de = dot;
+ if (*path == '/')
+ path++;
+ while (*path) {
+ if (!(s = strchr(path, '/')))
+ s = strchr(path, 0);
+ if ((n = s - path) > 255)
+ return ENAMETOOLONG;
+ memcpy(name, path, n);
+ name[n] = 0;
+ path = s;
+ if (!(de->attr & FA_DIR))
+ return ENOTDIR;
+ if ((err = lookup(fs, stclus(fs->fatsz, de), name, &de)))
+ return err;
+ if (*path == '/')
+ path++;
+ }
+ *dep = de;
+ return 0;
+}
+
+/*
+ * Lookup path segment
+ */
+static int
+lookup(DOS_FS *fs, u_int clus, const char *name, DOS_DE **dep)
+{
+ static DOS_DIR dir[DEPSEC];
+ u_char lfn[261];
+ u_char sfn[13];
+ u_int nsec, lsec, xdn, chk, sec, ent, x;
+ int err, ok, i;
+
+ if (!clus)
+ for (ent = 0; ent < 2; ent++)
+ if (!strcasecmp(name, dotstr[ent])) {
+ *dep = dot + ent;
+ return 0;
+ }
+ if (!clus && fs->fatsz == 32)
+ clus = fs->rdcl;
+ nsec = !clus ? entsec(fs->dirents) : fs->spc;
+ lsec = 0;
+ xdn = chk = 0;
+ for (;;) {
+ if (!clus && !lsec)
+ lsec = fs->lsndir;
+ else if (okclus(fs, clus))
+ lsec = blklsn(fs, clus);
+ else
+ return EINVAL;
+ for (sec = 0; sec < nsec; sec++) {
+ if ((err = ioget(fs->fd, lsec + sec, dir, 1)))
+ return err;
+ for (ent = 0; ent < DEPSEC; ent++) {
+ if (!*dir[ent].de.name)
+ return ENOENT;
+ if (*dir[ent].de.name != 0xe5) {
+ if ((dir[ent].de.attr & FA_MASK) == FA_XDE) {
+ x = dir[ent].xde.seq;
+ if (x & 0x40 || (x + 1 == xdn &&
+ dir[ent].xde.chk == chk)) {
+ if (x & 0x40) {
+ chk = dir[ent].xde.chk;
+ x &= ~0x40;
+ }
+ if (x >= 1 && x <= 20) {
+ cp_xdnm(lfn, &dir[ent].xde);
+ xdn = x;
+ continue;
+ }
+ }
+ } else if (!(dir[ent].de.attr & FA_LABEL)) {
+ if ((ok = xdn == 1)) {
+ for (x = 0, i = 0; i < 11; i++)
+ x = ((((x & 1) << 7) | (x >> 1)) +
+ dir[ent].de.name[i]) & 0xff;
+ ok = chk == x &&
+ !strcasecmp(name, (const char *)lfn);
+ }
+ if (!ok) {
+ cp_sfn(sfn, &dir[ent].de);
+ ok = !strcasecmp(name, (const char *)sfn);
+ }
+ if (ok) {
+ *dep = &dir[ent].de;
+ return 0;
+ }
+ }
+ }
+ xdn = 0;
+ }
+ }
+ if (!clus)
+ break;
+ if ((err = fatget(fs, &clus)))
+ return err;
+ if (fatend(fs->fatsz, clus))
+ break;
+ }
+ return ENOENT;
+}
+
+/*
+ * Copy name from extended directory entry
+ */
+static void
+cp_xdnm(u_char *lfn, DOS_XDE *xde)
+{
+ static struct {
+ u_int off;
+ u_int dim;
+ } ix[3] = {
+ {offsetof(DOS_XDE, name1), sizeof(xde->name1) / 2},
+ {offsetof(DOS_XDE, name2), sizeof(xde->name2) / 2},
+ {offsetof(DOS_XDE, name3), sizeof(xde->name3) / 2}
+ };
+ u_char *p;
+ u_int n, x, c;
+
+ lfn += 13 * ((xde->seq & ~0x40) - 1);
+ for (n = 0; n < 3; n++)
+ for (p = (u_char *)xde + ix[n].off, x = ix[n].dim; x;
+ p += 2, x--) {
+ if ((c = cv2(p)) && (c < 32 || c > 127))
+ c = '?';
+ if (!(*lfn++ = c))
+ return;
+ }
+ if (xde->seq & 0x40)
+ *lfn = 0;
+}
+
+/*
+ * Copy short filename
+ */
+static void
+cp_sfn(u_char *sfn, DOS_DE *de)
+{
+ u_char *p;
+ int j, i;
+
+ p = sfn;
+ if (*de->name != ' ') {
+ for (j = 7; de->name[j] == ' '; j--);
+ for (i = 0; i <= j; i++)
+ *p++ = de->name[i];
+ if (*de->ext != ' ') {
+ *p++ = '.';
+ for (j = 2; de->ext[j] == ' '; j--);
+ for (i = 0; i <= j; i++)
+ *p++ = de->ext[i];
+ }
+ }
+ *p = 0;
+ if (*sfn == 5)
+ *sfn = 0xe5;
+}
+
+/*
+ * Return size of file in bytes
+ */
+static off_t
+fsize(DOS_FS *fs, DOS_DE *de)
+{
+ u_long size;
+ u_int c;
+ int n;
+
+ if (!(size = cv4(de->size)) && de->attr & FA_DIR) {
+ if (!(c = cv2(de->clus)))
+ size = fs->dirents * sizeof(DOS_DE);
+ else {
+ if ((n = fatcnt(fs, c)) == -1)
+ return n;
+ size = blkbyt(fs, n);
+ }
+ }
+ return size;
+}
+
+/*
+ * Count number of clusters in chain
+ */
+static int
+fatcnt(DOS_FS *fs, u_int c)
+{
+ int n;
+
+ for (n = 0; okclus(fs, c); n++)
+ if (fatget(fs, &c))
+ return -1;
+ return fatend(fs->fatsz, c) ? n : -1;
+}
+
+/*
+ * Get next cluster in cluster chain
+ */
+static int
+fatget(DOS_FS *fs, u_int *c)
+{
+ u_char buf[4];
+ u_int x;
+ int err;
+
+ err = ioread(fs, secbyt(fs->lsnfat) + fatoff(fs->fatsz, *c), buf,
+ fs->fatsz != 32 ? 2 : 4);
+ if (err)
+ return err;
+ x = fs->fatsz != 32 ? cv2(buf) : cv4(buf);
+ *c = fs->fatsz == 12 ? *c & 1 ? x >> 4 : x & 0xfff : x;
+ return 0;
+}
+
+/*
+ * Is cluster an end-of-chain marker?
+ */
+static int
+fatend(u_int sz, u_int c)
+{
+ return c > (sz == 12 ? 0xff7U : sz == 16 ? 0xfff7U : 0xffffff7);
+}
+
+/*
+ * Offset-based I/O primitive
+ */
+static int
+ioread(DOS_FS *fs, u_int offset, void *buf, u_int nbyte)
+{
+ char *s;
+ u_int off, n;
+ int err;
+
+ s = buf;
+ if ((off = offset & (SECSIZ - 1))) {
+ offset -= off;
+ if ((err = iobuf(fs, bytsec(offset))))
+ return err;
+ offset += SECSIZ;
+ if ((n = SECSIZ - off) > nbyte)
+ n = nbyte;
+ memcpy(s, fs->buf + off, n);
+ s += n;
+ nbyte -= n;
+ }
+ n = nbyte & (SECSIZ - 1);
+ if (nbyte -= n) {
+ if ((err = ioget(fs->fd, bytsec(offset), s, bytsec(nbyte))))
+ return err;
+ offset += nbyte;
+ s += nbyte;
+ }
+ if (n) {
+ if ((err = iobuf(fs, bytsec(offset))))
+ return err;
+ memcpy(s, fs->buf, n);
+ }
+ return 0;
+}
+
+/*
+ * Buffered sector-based I/O primitive
+ */
+static int
+iobuf(DOS_FS *fs, u_int lsec)
+{
+ int err;
+
+ if (fs->bufsec != lsec) {
+ if ((err = ioget(fs->fd, lsec, fs->buf, 1)))
+ return err;
+ fs->bufsec = lsec;
+ }
+ return 0;
+}
+
+/*
+ * Sector-based I/O primitive
+ */
+static int
+ioget(struct open_file *fd, u_int lsec, void *buf, u_int nsec)
+{
+ int err;
+
+ if ((err = (fd->f_dev->dv_strategy)(fd->f_devdata, F_READ, lsec,
+ secbyt(nsec), buf, NULL)))
+ return(err);
+ return(0);
+}
diff --git a/lib/libstand/dosfs.h b/lib/libstand/dosfs.h
new file mode 100644
index 0000000..e44b6b5
--- /dev/null
+++ b/lib/libstand/dosfs.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 1996, 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DOSIO_H
+#define DOSIO_H
+
+/*
+ * DOS file attributes
+ */
+
+#define FA_RDONLY 001 /* read-only */
+#define FA_HIDDEN 002 /* hidden file */
+#define FA_SYSTEM 004 /* system file */
+#define FA_LABEL 010 /* volume label */
+#define FA_DIR 020 /* directory */
+#define FA_ARCH 040 /* archive (file modified) */
+#define FA_XDE 017 /* extended directory entry */
+#define FA_MASK 077 /* all attributes */
+
+/*
+ * Macros to convert DOS-format 16-bit and 32-bit quantities
+ */
+
+#define cv2(p) ((u_int16_t)(p)[0] | \
+ ((u_int16_t)(p)[1] << 010))
+#define cv4(p) ((u_int32_t)(p)[0] | \
+ ((u_int32_t)(p)[1] << 010) | \
+ ((u_int32_t)(p)[2] << 020) | \
+ ((u_int32_t)(p)[3] << 030))
+
+/*
+ * Directory, filesystem, and file structures.
+ */
+
+typedef struct {
+ u_char x_case; /* case */
+ u_char c_hsec; /* created: secs/100 */
+ u_char c_time[2]; /* created: time */
+ u_char c_date[2]; /* created: date */
+ u_char a_date[2]; /* accessed: date */
+ u_char h_clus[2]; /* clus[hi] */
+} DOS_DEX;
+
+typedef struct {
+ u_char name[8]; /* name */
+ u_char ext[3]; /* extension */
+ u_char attr; /* attributes */
+ DOS_DEX dex; /* VFAT/FAT32 only */
+ u_char time[2]; /* modified: time */
+ u_char date[2]; /* modified: date */
+ u_char clus[2]; /* starting cluster */
+ u_char size[4]; /* size */
+} DOS_DE;
+
+typedef struct {
+ u_char seq; /* flags */
+ u_char name1[5][2]; /* 1st name area */
+ u_char attr; /* (see fat_de) */
+ u_char res; /* reserved */
+ u_char chk; /* checksum */
+ u_char name2[6][2]; /* 2nd name area */
+ u_char clus[2]; /* (see fat_de) */
+ u_char name3[2][2]; /* 3rd name area */
+} DOS_XDE;
+
+typedef union {
+ DOS_DE de; /* standard directory entry */
+ DOS_XDE xde; /* extended directory entry */
+} DOS_DIR;
+
+typedef struct {
+ struct open_file *fd; /* file descriptor */
+ u_char *buf; /* buffer */
+ u_int bufsec; /* buffered sector */
+ u_int links; /* active links to structure */
+ u_int spc; /* sectors per cluster */
+ u_int bsize; /* cluster size in bytes */
+ u_int bshift; /* cluster conversion shift */
+ u_int dirents; /* root directory entries */
+ u_int spf; /* sectors per fat */
+ u_int rdcl; /* root directory start cluster */
+ u_int lsnfat; /* start of fat */
+ u_int lsndir; /* start of root dir */
+ u_int lsndta; /* start of data area */
+ u_int fatsz; /* FAT entry size */
+ u_int xclus; /* maximum cluster number */
+} DOS_FS;
+
+typedef struct {
+ DOS_FS *fs; /* associated filesystem */
+ DOS_DE de; /* directory entry */
+ u_int offset; /* current offset */
+ u_int c; /* last cluster read */
+} DOS_FILE;
+
+#endif /* !DOSIO_H */
diff --git a/lib/libstand/environment.c b/lib/libstand/environment.c
new file mode 100644
index 0000000..f2ca120
--- /dev/null
+++ b/lib/libstand/environment.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 1998 Michael Smith.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+/*
+ * Manage an environment-like space in which string variables may be stored.
+ * Provide support for some method-like operations for setting/retrieving
+ * variables in order to allow some type strength.
+ */
+
+#include "stand.h"
+
+#include <string.h>
+
+static void env_discard(struct env_var *ev);
+
+struct env_var *environ = NULL;
+
+/*
+ * Look up (name) and return it's env_var structure.
+ */
+struct env_var *
+env_getenv(const char *name)
+{
+ struct env_var *ev;
+
+ for (ev = environ; ev != NULL; ev = ev->ev_next)
+ if (!strcmp(ev->ev_name, name))
+ break;
+ return(ev);
+}
+
+/*
+ * Some notes:
+ *
+ * If the EV_VOLATILE flag is set, a copy of the variable is made.
+ * If EV_DYNAMIC is set, the the variable has been allocated with
+ * malloc and ownership transferred to the environment.
+ * If (value) is NULL, the variable is set but has no value.
+ */
+int
+env_setenv(const char *name, int flags, void *value, ev_sethook_t sethook,
+ ev_unsethook_t unsethook)
+{
+ struct env_var *ev, *curr, *last;
+
+ if ((ev = env_getenv(name)) != NULL) {
+ /*
+ * If there's a set hook, let it do the work (unless we are working
+ * for one already.
+ */
+ if ((ev->ev_sethook != NULL) && !(flags & EV_NOHOOK))
+ return(ev->ev_sethook(ev, flags, value));
+ } else {
+
+ /*
+ * New variable; create and sort into list
+ */
+ ev = malloc(sizeof(struct env_var));
+ ev->ev_name = strdup(name);
+ ev->ev_value = NULL;
+ /* hooks can only be set when the variable is instantiated */
+ ev->ev_sethook = sethook;
+ ev->ev_unsethook = unsethook;
+
+ /* Sort into list */
+ ev->ev_prev = NULL;
+ ev->ev_next = NULL;
+ /* Search for the record to insert before */
+ for (last = NULL, curr = environ;
+ curr != NULL;
+ last = curr, curr = curr->ev_next) {
+
+ if (strcmp(ev->ev_name, curr->ev_name) < 0) {
+ if (curr->ev_prev) {
+ curr->ev_prev->ev_next = ev;
+ } else {
+ environ = ev;
+ }
+ ev->ev_next = curr;
+ ev->ev_prev = curr->ev_prev;
+ curr->ev_prev = ev;
+ break;
+ }
+ }
+ if (curr == NULL) {
+ if (last == NULL) {
+ environ = ev;
+ } else {
+ last->ev_next = ev;
+ ev->ev_prev = last;
+ }
+ }
+ }
+
+ /* If there is data in the variable, discard it */
+ if (ev->ev_value != NULL)
+ free(ev->ev_value);
+
+ /* If we have a new value, use it */
+ if (flags & EV_VOLATILE) {
+ ev->ev_value = strdup(value);
+ } else {
+ ev->ev_value = value;
+ }
+
+ /* Keep the flag components that are relevant */
+ ev->ev_flags = flags & (EV_DYNAMIC);
+
+ return(0);
+}
+
+char *
+getenv(const char *name)
+{
+ struct env_var *ev;
+
+ /* Set but no value gives empty string */
+ if ((ev = env_getenv(name)) != NULL) {
+ if (ev->ev_value != NULL)
+ return(ev->ev_value);
+ return("");
+ }
+ return(NULL);
+}
+
+int
+setenv(const char *name, char *value, int overwrite)
+{
+ /* No guarantees about state, always assume volatile */
+ if (overwrite || (env_getenv(name) == NULL))
+ return(env_setenv(name, EV_VOLATILE, value, NULL, NULL));
+ return(0);
+}
+
+int
+putenv(const char *string)
+{
+ char *value, *copy;
+ int result;
+
+ copy = strdup(string);
+ if ((value = strchr(copy, '=')) != NULL)
+ *(value++) = 0;
+ result = setenv(copy, value, 1);
+ free(copy);
+ return(result);
+}
+
+int
+unsetenv(const char *name)
+{
+ struct env_var *ev;
+ int err;
+
+ err = 0;
+ if ((ev = env_getenv(name)) == NULL) {
+ err = ENOENT;
+ } else {
+ if (ev->ev_unsethook != NULL)
+ err = ev->ev_unsethook(ev);
+ if (err == 0) {
+ env_discard(ev);
+ }
+ }
+ return(err);
+}
+
+static void
+env_discard(struct env_var *ev)
+{
+ if (ev->ev_prev)
+ ev->ev_prev->ev_next = ev->ev_next;
+ if (ev->ev_next)
+ ev->ev_next->ev_prev = ev->ev_prev;
+ if (environ == ev)
+ environ = ev->ev_next;
+ free(ev->ev_name);
+ if (ev->ev_flags & EV_DYNAMIC)
+ free(ev->ev_value);
+ free(ev);
+}
+
+int
+env_noset(struct env_var *ev, int flags, void *value)
+{
+ return(EPERM);
+}
+
+int
+env_nounset(struct env_var *ev)
+{
+ return(EPERM);
+}
diff --git a/lib/libstand/ether.c b/lib/libstand/ether.c
new file mode 100644
index 0000000..871dad4
--- /dev/null
+++ b/lib/libstand/ether.c
@@ -0,0 +1,151 @@
+/* $NetBSD: ether.c,v 1.11 1997/07/07 15:52:50 drochner Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL)
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+
+/* Caller must leave room for ethernet header in front!! */
+ssize_t
+sendether(d, pkt, len, dea, etype)
+ struct iodesc *d;
+ void *pkt;
+ size_t len;
+ u_char *dea;
+ int etype;
+{
+ register ssize_t n;
+ register struct ether_header *eh;
+
+#ifdef ETHER_DEBUG
+ if (debug)
+ printf("sendether: called\n");
+#endif
+
+ eh = (struct ether_header *)pkt - 1;
+ len += sizeof(*eh);
+
+ MACPY(d->myea, eh->ether_shost); /* by byte */
+ MACPY(dea, eh->ether_dhost); /* by byte */
+ eh->ether_type = htons(etype);
+
+ n = netif_put(d, eh, len);
+ if (n == -1 || n < sizeof(*eh))
+ return (-1);
+
+ n -= sizeof(*eh);
+ return (n);
+}
+
+/*
+ * Get a packet of any Ethernet type, with our address or
+ * the broadcast address. Save the Ether type in arg 5.
+ * NOTE: Caller must leave room for the Ether header.
+ */
+ssize_t
+readether(d, pkt, len, tleft, etype)
+ register struct iodesc *d;
+ register void *pkt;
+ register size_t len;
+ time_t tleft;
+ register u_int16_t *etype;
+{
+ register ssize_t n;
+ register struct ether_header *eh;
+
+#ifdef ETHER_DEBUG
+ if (debug)
+ printf("readether: called\n");
+#endif
+
+ eh = (struct ether_header *)pkt - 1;
+ len += sizeof(*eh);
+
+ n = netif_get(d, eh, len, tleft);
+ if (n == -1 || n < sizeof(*eh))
+ return (-1);
+
+ /* Validate Ethernet address. */
+ if (bcmp(d->myea, eh->ether_dhost, 6) != 0 &&
+ bcmp(bcea, eh->ether_dhost, 6) != 0) {
+#ifdef ETHER_DEBUG
+ if (debug)
+ printf("readether: not ours (ea=%s)\n",
+ ether_sprintf(eh->ether_dhost));
+#endif
+ return (-1);
+ }
+ *etype = ntohs(eh->ether_type);
+
+ n -= sizeof(*eh);
+ return (n);
+}
+
+/*
+ * Convert Ethernet address to printable (loggable) representation.
+ */
+static char digits[] = "0123456789abcdef";
+char *
+ether_sprintf(ap)
+ register u_char *ap;
+{
+ register int i;
+ static char etherbuf[18];
+ register char *cp = etherbuf;
+
+ for (i = 0; i < 6; i++) {
+ *cp++ = digits[*ap >> 4];
+ *cp++ = digits[*ap++ & 0xf];
+ *cp++ = ':';
+ }
+ *--cp = 0;
+ return (etherbuf);
+}
diff --git a/lib/libstand/fstat.c b/lib/libstand/fstat.c
new file mode 100644
index 0000000..aa8b898
--- /dev/null
+++ b/lib/libstand/fstat.c
@@ -0,0 +1,60 @@
+/* $NetBSD: fstat.c,v 1.1 1996/01/13 22:25:38 leo Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)stat.c 8.1 (Berkeley) 6/11/93
+ */
+
+#include "stand.h"
+
+int
+fstat(fd, sb)
+ int fd;
+ struct stat *sb;
+{
+ register struct open_file *f = &files[fd];
+
+ if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
+ errno = EBADF;
+ return (-1);
+ }
+
+ /* operation not defined on raw devices */
+ if (f->f_flags & F_RAW) {
+ errno = EOPNOTSUPP;
+ return (-1);
+ }
+
+ errno = (f->f_ops->fo_stat)(f, sb);
+ return (0);
+}
diff --git a/lib/libstand/getopt.c b/lib/libstand/getopt.c
new file mode 100644
index 0000000..f788fe0
--- /dev/null
+++ b/lib/libstand/getopt.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include "stand.h"
+#include <string.h>
+
+int opterr = 1, /* if error message should be printed */
+ optind = 1, /* index into parent argv vector */
+ optopt, /* character checked for validity */
+ optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define BADARG (int)':'
+#define EMSG ""
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt(nargc, nargv, ostr)
+ int nargc;
+ char * const *nargv;
+ const char *ostr;
+{
+ static char *place = EMSG; /* option letter processing */
+ char *oli; /* option letter list index */
+
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc || *(place = nargv[optind]) != '-') {
+ place = EMSG;
+ return (-1);
+ }
+ if (place[1] && *++place == '-') { /* found "--" */
+ ++optind;
+ place = EMSG;
+ return (-1);
+ }
+ } /* option letter okay? */
+ if ((optopt = (int)*place++) == (int)':' ||
+ !(oli = strchr(ostr, optopt))) {
+ /*
+ * if the user didn't specify '-' as an option,
+ * assume it means -1.
+ */
+ if (optopt == (int)'-')
+ return (-1);
+ if (!*place)
+ ++optind;
+ if (opterr && *ostr != ':')
+ (void)printf("illegal option -- %c\n", optopt);
+ return (BADCH);
+ }
+ if (*++oli != ':') { /* don't need argument */
+ optarg = NULL;
+ if (!*place)
+ ++optind;
+ }
+ else { /* need an argument */
+ if (*place) /* no white space */
+ optarg = place;
+ else if (nargc <= ++optind) { /* no arg */
+ place = EMSG;
+ if (*ostr == ':')
+ return (BADARG);
+ if (opterr)
+ (void)printf("option requires an argument -- %c\n", optopt);
+ return (BADCH);
+ }
+ else /* white space */
+ optarg = nargv[optind];
+ place = EMSG;
+ ++optind;
+ }
+ return (optopt); /* dump back option letter */
+}
diff --git a/lib/libstand/gets.c b/lib/libstand/gets.c
new file mode 100644
index 0000000..dc26a99
--- /dev/null
+++ b/lib/libstand/gets.c
@@ -0,0 +1,113 @@
+/* $NetBSD: gets.c,v 1.6 1995/10/11 21:16:57 pk Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)gets.c 8.1 (Berkeley) 6/11/93
+ */
+
+#include "stand.h"
+
+/* gets() with constrained input length */
+
+void
+ngets(char *buf, int n)
+{
+ register int c;
+ register char *lp;
+
+ for (lp = buf;;)
+ switch (c = getchar() & 0177) {
+ case '\n':
+ case '\r':
+ *lp = '\0';
+ putchar('\n');
+ return;
+ case '\b':
+ case '\177':
+ if (lp > buf) {
+ lp--;
+ putchar('\b');
+ putchar(' ');
+ putchar('\b');
+ }
+ break;
+ case 'r'&037: {
+ register char *p;
+
+ putchar('\n');
+ for (p = buf; p < lp; ++p)
+ putchar(*p);
+ break;
+ }
+ case 'u'&037:
+ case 'w'&037:
+ lp = buf;
+ putchar('\n');
+ break;
+ default:
+ if ((n < 1) || ((lp - buf) < n)) {
+ *lp++ = c;
+ putchar(c);
+ }
+ }
+ /*NOTREACHED*/
+}
+
+int
+fgetstr(char *buf, int size, int fd)
+{
+ char c;
+ int err, len;
+
+ size--; /* leave space for terminator */
+ len = 0;
+ while (size != 0) {
+ err = read(fd, &c, sizeof(c));
+ if (err < 0) /* read error */
+ return(-1);
+ if (err == 0) { /* EOF */
+ if (len == 0)
+ return(-1); /* nothing to read */
+ break;
+ }
+ if ((c == '\r') || /* line terminators */
+ (c == '\n'))
+ break;
+ *buf++ = c; /* keep char */
+ size--;
+ len++;
+ }
+ *buf = 0;
+ return(len);
+}
+
diff --git a/lib/libstand/globals.c b/lib/libstand/globals.c
new file mode 100644
index 0000000..c35021c
--- /dev/null
+++ b/lib/libstand/globals.c
@@ -0,0 +1,33 @@
+/* $NetBSD: globals.c,v 1.3 1995/09/18 21:19:27 pk Exp $ */
+
+/*
+ * globals.c:
+ *
+ * global variables should be separate, so nothing else
+ * must be included extraneously.
+ */
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include "stand.h"
+#include "net.h"
+
+u_char bcea[6] = BA; /* broadcast ethernet address */
+
+char rootpath[FNAME_SIZE] = "/"; /* root mount path */
+char bootfile[FNAME_SIZE]; /* bootp says to boot this */
+char hostname[FNAME_SIZE]; /* our hostname */
+int hostnamelen;
+char domainname[FNAME_SIZE]; /* our DNS domain */
+int domainnamelen;
+char ifname[IFNAME_SIZE]; /* name of interface (e.g. "le0") */
+struct in_addr myip; /* my ip address */
+struct in_addr nameip; /* DNS server ip address */
+struct in_addr rootip; /* root ip address */
+struct in_addr swapip; /* swap ip address */
+struct in_addr gateip; /* swap ip address */
+n_long netmask = 0xffffff00; /* subnet or net mask */
+int errno; /* our old friend */
+
diff --git a/lib/libstand/gzipfs.c b/lib/libstand/gzipfs.c
new file mode 100644
index 0000000..b0e3007
--- /dev/null
+++ b/lib/libstand/gzipfs.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 1998 Michael Smith.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include "stand.h"
+
+#include <sys/stat.h>
+#include <string.h>
+#include <zlib.h>
+
+#define Z_BUFSIZE 2048 /* XXX larger? */
+
+struct z_file
+{
+ int zf_rawfd;
+ z_stream zf_zstream;
+ char zf_buf[Z_BUFSIZE];
+};
+
+static int zf_fill(struct z_file *z);
+static int zf_open(const char *path, struct open_file *f);
+static int zf_close(struct open_file *f);
+static int zf_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t zf_seek(struct open_file *f, off_t offset, int where);
+static int zf_stat(struct open_file *f, struct stat *sb);
+
+struct fs_ops zipfs_fsops = {
+ "zip",
+ zf_open,
+ zf_close,
+ zf_read,
+ null_write,
+ zf_seek,
+ zf_stat
+};
+
+#if 0
+void *
+calloc(int items, size_t size)
+{
+ return(malloc(items * size));
+}
+#endif
+
+static int
+zf_fill(struct z_file *zf)
+{
+ int result;
+ int req;
+
+ req = Z_BUFSIZE - zf->zf_zstream.avail_in;
+ result = 0;
+
+ /* If we need more */
+ if (req > 0) {
+ /* move old data to bottom of buffer */
+ if (req < Z_BUFSIZE)
+ bcopy(zf->zf_buf + req, zf->zf_buf, Z_BUFSIZE - req);
+
+ /* read to fill buffer and update availibility data */
+ result = read(zf->zf_rawfd, zf->zf_buf + zf->zf_zstream.avail_in, req);
+ zf->zf_zstream.next_in = zf->zf_buf;
+ if (result >= 0)
+ zf->zf_zstream.avail_in += result;
+ }
+ return(result);
+}
+
+/*
+ * Adapted from get_byte/check_header in libz
+ *
+ * Returns 0 if the header is OK, nonzero if not.
+ */
+static int
+get_byte(struct z_file *zf)
+{
+ if ((zf->zf_zstream.avail_in == 0) && (zf_fill(zf) == -1))
+ return(-1);
+ zf->zf_zstream.avail_in--;
+ return(*(zf->zf_zstream.next_in)++);
+}
+
+static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define RESERVED 0xE0 /* bits 5..7: reserved */
+
+static int
+check_header(struct z_file *zf)
+{
+ int method; /* method byte */
+ int flags; /* flags byte */
+ uInt len;
+ int c;
+
+ /* Check the gzip magic header */
+ for (len = 0; len < 2; len++) {
+ c = get_byte(zf);
+ if (c != gz_magic[len]) {
+ return(1);
+ }
+ }
+ method = get_byte(zf);
+ flags = get_byte(zf);
+ if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+ return(1);
+ }
+
+ /* Discard time, xflags and OS code: */
+ for (len = 0; len < 6; len++) (void)get_byte(zf);
+
+ if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+ len = (uInt)get_byte(zf);
+ len += ((uInt)get_byte(zf))<<8;
+ /* len is garbage if EOF but the loop below will quit anyway */
+ while (len-- != 0 && get_byte(zf) != -1) ;
+ }
+ if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+ while ((c = get_byte(zf)) != 0 && c != -1) ;
+ }
+ if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
+ while ((c = get_byte(zf)) != 0 && c != -1) ;
+ }
+ if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
+ for (len = 0; len < 2; len++) c = get_byte(zf);
+ }
+ /* if there's data left, we're in business */
+ return((c == -1) ? 1 : 0);
+}
+
+static int
+zf_open(const char *fname, struct open_file *f)
+{
+ static char *zfname;
+ int rawfd;
+ struct z_file *zf;
+ char *cp;
+ int error;
+ struct stat sb;
+
+ /* Have to be in "just read it" mode */
+ if (f->f_flags != F_READ)
+ return(EPERM);
+
+ /* If the name already ends in .gz, ignore it */
+ if ((cp = strrchr(fname, '.')) && !strcmp(cp, ".gz"))
+ return(ENOENT);
+
+ /* Construct new name */
+ zfname = malloc(strlen(fname) + 4);
+ sprintf(zfname, "%s.gz", fname);
+
+ /* Try to open the compressed datafile */
+ rawfd = open(zfname, O_RDONLY);
+ free(zfname);
+ if (rawfd == -1)
+ return(ENOENT);
+
+ if (fstat(rawfd, &sb) < 0) {
+ printf("zf_open: stat failed\n");
+ close(rawfd);
+ return(ENOENT);
+ }
+ if (!S_ISREG(sb.st_mode)) {
+ printf("zf_open: not a file\n");
+ close(rawfd);
+ return(EISDIR); /* best guess */
+ }
+
+ /* Allocate a z_file structure, populate it */
+ zf = malloc(sizeof(struct z_file));
+ bzero(zf, sizeof(struct z_file));
+ zf->zf_rawfd = rawfd;
+
+ /* Verify that the file is gzipped (XXX why do this afterwards?) */
+ if (check_header(zf)) {
+ close(zf->zf_rawfd);
+ inflateEnd(&(zf->zf_zstream));
+ free(zf);
+ return(EFTYPE);
+ }
+
+ /* Initialise the inflation engine */
+ if ((error = inflateInit2(&(zf->zf_zstream), -15)) != Z_OK) {
+ printf("zf_open: inflateInit returned %d : %s\n", error, zf->zf_zstream.msg);
+ close(zf->zf_rawfd);
+ free(zf);
+ return(EIO);
+ }
+
+ /* Looks OK, we'll take it */
+ f->f_fsdata = zf;
+ return(0);
+}
+
+static int
+zf_close(struct open_file *f)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+
+ inflateEnd(&(zf->zf_zstream));
+ close(zf->zf_rawfd);
+ free(zf);
+ return(0);
+}
+
+static int
+zf_read(struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+ int error;
+
+ zf->zf_zstream.next_out = buf; /* where and how much */
+ zf->zf_zstream.avail_out = size;
+
+ while (zf->zf_zstream.avail_out) {
+ if ((zf->zf_zstream.avail_in == 0) && (zf_fill(zf) == -1)) {
+ printf("zf_read: fill error\n");
+ return(-1);
+ }
+ if (zf->zf_zstream.avail_in == 0) { /* oops, unexpected EOF */
+ printf("zf_read: unexpected EOF\n");
+ break;
+ }
+
+ error = inflate(&zf->zf_zstream, Z_SYNC_FLUSH); /* decompression pass */
+ if (error == Z_STREAM_END) { /* EOF, all done */
+ break;
+ }
+ if (error != Z_OK) { /* argh, decompression error */
+ printf("inflate: %s\n", zf->zf_zstream.msg);
+ errno = EIO;
+ return(-1);
+ }
+ }
+ if (resid != NULL)
+ *resid = zf->zf_zstream.avail_out;
+ return(0);
+}
+
+static off_t
+zf_seek(struct open_file *f, off_t offset, int where)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+ off_t target;
+ char discard[16];
+
+ switch (where) {
+ case SEEK_SET:
+ target = offset;
+ break;
+ case SEEK_CUR:
+ target = offset + zf->zf_zstream.total_out;
+ break;
+ default:
+ target = -1;
+ }
+
+ /* Can we get there from here? */
+ if (target < zf->zf_zstream.total_out) {
+ errno = EOFFSET;
+ return -1;
+ }
+
+ /* skip forwards if required */
+ while (target > zf->zf_zstream.total_out) {
+ if (zf_read(f, discard, min(sizeof(discard), target - zf->zf_zstream.total_out), NULL) == -1)
+ return(-1);
+ }
+ /* This is where we are (be honest if we overshot) */
+ return (zf->zf_zstream.total_out);
+}
+
+
+static int
+zf_stat(struct open_file *f, struct stat *sb)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+ int result;
+
+ /* stat as normal, but indicate that size is unknown */
+ if ((result = fstat(zf->zf_rawfd, sb)) == 0)
+ sb->st_size = -1;
+ return(result);
+}
+
+
+
diff --git a/lib/libstand/i386/_setjmp.S b/lib/libstand/i386/_setjmp.S
new file mode 100644
index 0000000..fc75db7
--- /dev/null
+++ b/lib/libstand/i386/_setjmp.S
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$FreeBSD$"
+#endif /* LIBC_RCS and not lint */
+
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ * _longjmp(a,v)
+ * will generate a "return(v)" from the last call to
+ * _setjmp(a)
+ * by restoring registers from the environment 'a'.
+ * The previous signal state is NOT restored.
+ */
+
+#include "DEFS.h"
+
+ENTRY(_setjmp)
+ movl 4(%esp),%eax
+ movl 0(%esp),%edx
+ movl %edx, 0(%eax) /* rta */
+ movl %ebx, 4(%eax)
+ movl %esp, 8(%eax)
+ movl %ebp,12(%eax)
+ movl %esi,16(%eax)
+ movl %edi,20(%eax)
+ xorl %eax,%eax
+ ret
+
+ENTRY(_longjmp)
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ movl 0(%edx),%ecx
+ movl 4(%edx),%ebx
+ movl 8(%edx),%esp
+ movl 12(%edx),%ebp
+ movl 16(%edx),%esi
+ movl 20(%edx),%edi
+ testl %eax,%eax
+ jnz 1f
+ incl %eax
+1: movl %ecx,0(%esp)
+ ret
diff --git a/lib/libstand/if_ether.h b/lib/libstand/if_ether.h
new file mode 100644
index 0000000..a9bc891
--- /dev/null
+++ b/lib/libstand/if_ether.h
@@ -0,0 +1,263 @@
+/* $NetBSD: if_ether.h,v 1.25 1997/01/17 17:06:06 mikel Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)if_ether.h 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Ethernet address - 6 octets
+ * this is only used by the ethers(3) functions.
+ */
+struct ether_addr {
+ u_int8_t ether_addr_octet[6];
+};
+
+/*
+ * Structure of a 10Mb/s Ethernet header.
+ */
+#define ETHER_ADDR_LEN 6
+
+struct ether_header {
+ u_int8_t ether_dhost[ETHER_ADDR_LEN];
+ u_int8_t ether_shost[ETHER_ADDR_LEN];
+ u_int16_t ether_type;
+};
+
+#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
+#define ETHERTYPE_IP 0x0800 /* IP protocol */
+#define ETHERTYPE_ARP 0x0806 /* address resolution protocol */
+#define ETHERTYPE_REVARP 0x8035 /* reverse addr resolution protocol */
+
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
+
+#define ETHERMTU 1500
+#define ETHERMIN (60-14)
+
+#ifdef _KERNEL
+/*
+ * Macro to map an IP multicast address to an Ethernet multicast address.
+ * The high-order 25 bits of the Ethernet address are statically assigned,
+ * and the low-order 23 bits are taken from the low end of the IP address.
+ */
+#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
+ /* struct in_addr *ipaddr; */ \
+ /* u_int8_t enaddr[ETHER_ADDR_LEN]; */ \
+{ \
+ (enaddr)[0] = 0x01; \
+ (enaddr)[1] = 0x00; \
+ (enaddr)[2] = 0x5e; \
+ (enaddr)[3] = ((u_int8_t *)ipaddr)[1] & 0x7f; \
+ (enaddr)[4] = ((u_int8_t *)ipaddr)[2]; \
+ (enaddr)[5] = ((u_int8_t *)ipaddr)[3]; \
+}
+#endif
+
+/*
+ * Ethernet Address Resolution Protocol.
+ *
+ * See RFC 826 for protocol description. Structure below is adapted
+ * to resolving internet addresses. Field names used correspond to
+ * RFC 826.
+ */
+struct ether_arp {
+ struct arphdr ea_hdr; /* fixed-size header */
+ u_int8_t arp_sha[ETHER_ADDR_LEN]; /* sender hardware address */
+ u_int8_t arp_spa[4]; /* sender protocol address */
+ u_int8_t arp_tha[ETHER_ADDR_LEN]; /* target hardware address */
+ u_int8_t arp_tpa[4]; /* target protocol address */
+};
+#define arp_hrd ea_hdr.ar_hrd
+#define arp_pro ea_hdr.ar_pro
+#define arp_hln ea_hdr.ar_hln
+#define arp_pln ea_hdr.ar_pln
+#define arp_op ea_hdr.ar_op
+
+/*
+ * Structure shared between the ethernet driver modules and
+ * the address resolution code. For example, each ec_softc or il_softc
+ * begins with this structure.
+ */
+struct arpcom {
+ struct ifnet ac_if; /* network-visible interface */
+ u_int8_t ac_enaddr[ETHER_ADDR_LEN]; /* ethernet hardware address */
+ char ac__pad[2]; /* be nice to m68k ports */
+ LIST_HEAD(, ether_multi) ac_multiaddrs; /* list of ether multicast addrs */
+ int ac_multicnt; /* length of ac_multiaddrs list */
+};
+
+struct llinfo_arp {
+ LIST_ENTRY(llinfo_arp) la_list;
+ struct rtentry *la_rt;
+ struct mbuf *la_hold; /* last packet until resolved/timeout */
+ long la_asked; /* last time we QUERIED for this addr */
+#define la_timer la_rt->rt_rmx.rmx_expire /* deletion time in seconds */
+};
+
+struct sockaddr_inarp {
+ u_int8_t sin_len;
+ u_int8_t sin_family;
+ u_int16_t sin_port;
+ struct in_addr sin_addr;
+ struct in_addr sin_srcaddr;
+ u_int16_t sin_tos;
+ u_int16_t sin_other;
+#define SIN_PROXY 1
+};
+
+/*
+ * IP and ethernet specific routing flags
+ */
+#define RTF_USETRAILERS RTF_PROTO1 /* use trailers */
+#define RTF_ANNOUNCE RTF_PROTO2 /* announce new arp entry */
+
+#ifdef _KERNEL
+u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN];
+u_int8_t ether_ipmulticast_min[ETHER_ADDR_LEN];
+u_int8_t ether_ipmulticast_max[ETHER_ADDR_LEN];
+struct ifqueue arpintrq;
+
+void arpwhohas(struct arpcom *, struct in_addr *);
+void arpintr(void);
+int arpresolve(struct arpcom *,
+ struct rtentry *, struct mbuf *, struct sockaddr *, u_char *);
+void arp_ifinit(struct arpcom *, struct ifaddr *);
+void arp_rtrequest(int, struct rtentry *, struct sockaddr *);
+
+int ether_addmulti(struct ifreq *, struct arpcom *);
+int ether_delmulti(struct ifreq *, struct arpcom *);
+#endif /* _KERNEL */
+
+/*
+ * Ethernet multicast address structure. There is one of these for each
+ * multicast address or range of multicast addresses that we are supposed
+ * to listen to on a particular interface. They are kept in a linked list,
+ * rooted in the interface's arpcom structure. (This really has nothing to
+ * do with ARP, or with the Internet address family, but this appears to be
+ * the minimally-disrupting place to put it.)
+ */
+struct ether_multi {
+ u_int8_t enm_addrlo[ETHER_ADDR_LEN]; /* low or only address of range */
+ u_int8_t enm_addrhi[ETHER_ADDR_LEN]; /* high or only address of range */
+ struct arpcom *enm_ac; /* back pointer to arpcom */
+ u_int enm_refcount; /* no. claims to this addr/range */
+ LIST_ENTRY(ether_multi) enm_list;
+};
+
+/*
+ * Structure used by macros below to remember position when stepping through
+ * all of the ether_multi records.
+ */
+struct ether_multistep {
+ struct ether_multi *e_enm;
+};
+
+/*
+ * Macro for looking up the ether_multi record for a given range of Ethernet
+ * multicast addresses connected to a given arpcom structure. If no matching
+ * record is found, "enm" returns NULL.
+ */
+#define ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm) \
+ /* u_int8_t addrlo[ETHER_ADDR_LEN]; */ \
+ /* u_int8_t addrhi[ETHER_ADDR_LEN]; */ \
+ /* struct arpcom *ac; */ \
+ /* struct ether_multi *enm; */ \
+{ \
+ for ((enm) = (ac)->ac_multiaddrs.lh_first; \
+ (enm) != NULL && \
+ (bcmp((enm)->enm_addrlo, (addrlo), ETHER_ADDR_LEN) != 0 || \
+ bcmp((enm)->enm_addrhi, (addrhi), ETHER_ADDR_LEN) != 0); \
+ (enm) = (enm)->enm_list.le_next); \
+}
+
+/*
+ * Macro to step through all of the ether_multi records, one at a time.
+ * The current position is remembered in "step", which the caller must
+ * provide. ETHER_FIRST_MULTI(), below, must be called to initialize "step"
+ * and get the first record. Both macros return a NULL "enm" when there
+ * are no remaining records.
+ */
+#define ETHER_NEXT_MULTI(step, enm) \
+ /* struct ether_multistep step; */ \
+ /* struct ether_multi *enm; */ \
+{ \
+ if (((enm) = (step).e_enm) != NULL) \
+ (step).e_enm = (enm)->enm_list.le_next; \
+}
+
+#define ETHER_FIRST_MULTI(step, ac, enm) \
+ /* struct ether_multistep step; */ \
+ /* struct arpcom *ac; */ \
+ /* struct ether_multi *enm; */ \
+{ \
+ (step).e_enm = (ac)->ac_multiaddrs.lh_first; \
+ ETHER_NEXT_MULTI((step), (enm)); \
+}
+
+#ifdef _KERNEL
+void arp_rtrequest(int, struct rtentry *, struct sockaddr *);
+int arpresolve(struct arpcom *, struct rtentry *, struct mbuf *,
+ struct sockaddr *, u_char *);
+void arpintr(void);
+int arpioctl(u_long, caddr_t);
+void arp_ifinit(struct arpcom *, struct ifaddr *);
+void revarpinput(struct mbuf *);
+void in_revarpinput(struct mbuf *);
+void revarprequest(struct ifnet *);
+int revarpwhoarewe(struct ifnet *, struct in_addr *, struct in_addr *);
+int revarpwhoami(struct in_addr *, struct ifnet *);
+int db_show_arptab(void);
+#endif
+
+/*
+ * Prototype ethers(3) functions.
+ */
+#ifndef _KERNEL
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+char * ether_ntoa(struct ether_addr *);
+struct ether_addr *
+ ether_aton(char *);
+int ether_ntohost(char *, struct ether_addr *);
+int ether_hostton(char *, struct ether_addr *);
+int ether_line(char *, struct ether_addr *, char *);
+__END_DECLS
+#endif
diff --git a/lib/libstand/in_cksum.c b/lib/libstand/in_cksum.c
new file mode 100644
index 0000000..d9b8964
--- /dev/null
+++ b/lib/libstand/in_cksum.c
@@ -0,0 +1,83 @@
+/* $NetBSD: in_cksum.c,v 1.3 1995/04/22 13:53:48 cgd Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Header: in_cksum.c,v 1.1 92/09/11 01:15:55 leres Exp (LBL)
+ */
+
+#include <sys/types.h>
+
+/*
+ * Checksum routine for Internet Protocol family headers.
+ * This routine is very heavily used in the network
+ * code and should be modified for each CPU to be as fast as possible.
+ * In particular, it should not be this one.
+ */
+int
+in_cksum(p, len)
+ register void *p;
+ register int len;
+{
+ register int sum = 0, oddbyte = 0, v = 0;
+ register u_char *cp = p;
+
+ /* we assume < 2^16 bytes being summed */
+ while (len > 0) {
+ if (oddbyte) {
+ sum += v + *cp++;
+ len--;
+ }
+ if (((long)cp & 1) == 0) {
+ while ((len -= 2) >= 0) {
+ sum += *(u_short *)cp;
+ cp += 2;
+ }
+ } else {
+ while ((len -= 2) >= 0) {
+ sum += *cp++ << 8;
+ sum += *cp++;
+ }
+ }
+ if ((oddbyte = len & 1) != 0)
+ v = *cp << 8;
+ }
+ if (oddbyte)
+ sum += v;
+ sum = (sum >> 16) + (sum & 0xffff); /* add in accumulated carries */
+ sum += sum >> 16; /* add potential last carry */
+ return (0xffff & ~sum);
+}
diff --git a/lib/libstand/inet_ntoa.c b/lib/libstand/inet_ntoa.c
new file mode 100644
index 0000000..c7efb0a
--- /dev/null
+++ b/lib/libstand/inet_ntoa.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "stand.h"
+
+/*
+ * Convert network-format internet address
+ * to base 256 d.d.d.d representation.
+ */
+char *
+inet_ntoa(in)
+ struct in_addr in;
+{
+ static const char fmt[] = "%u.%u.%u.%u";
+ static char ret[sizeof "255.255.255.255"];
+ unsigned char *src = (unsigned char *) &in;
+
+ sprintf(ret, fmt, src[0], src[1], src[2], src[3]);
+ return (ret);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_ntoa
+__weak_reference(__inet_ntoa, inet_ntoa);
diff --git a/lib/libstand/ioctl.c b/lib/libstand/ioctl.c
new file mode 100644
index 0000000..1b0f353
--- /dev/null
+++ b/lib/libstand/ioctl.c
@@ -0,0 +1,89 @@
+/* $NetBSD: ioctl.c,v 1.4 1994/10/30 21:48:24 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ioctl.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "stand.h"
+
+int
+ioctl(fd, cmd, arg)
+ int fd;
+ u_long cmd;
+ char *arg;
+{
+ register struct open_file *f = &files[fd];
+
+ if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
+ errno = EBADF;
+ return (-1);
+ }
+ if (f->f_flags & F_RAW) {
+ errno = (f->f_dev->dv_ioctl)(f, cmd, arg);
+ if (errno)
+ return (-1);
+ return (0);
+ }
+ errno = EIO;
+ return (-1);
+}
diff --git a/lib/libstand/iodesc.h b/lib/libstand/iodesc.h
new file mode 100644
index 0000000..690c65b
--- /dev/null
+++ b/lib/libstand/iodesc.h
@@ -0,0 +1,54 @@
+/* $NetBSD: iodesc.h,v 1.4 1995/09/23 03:31:50 gwr Exp $ */
+
+/*
+ * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __SYS_LIBNETBOOT_IODESC_H
+#define __SYS_LIBNETBOOT_IODESC_H
+
+struct iodesc {
+ struct in_addr destip; /* dest. ip addr, net order */
+ struct in_addr myip; /* local ip addr, net order */
+ u_short destport; /* dest. port, net order */
+ u_short myport; /* local port, net order */
+ u_long xid; /* transaction identification */
+ u_char myea[6]; /* my ethernet address */
+ struct netif *io_netif;
+};
+
+#endif /* __SYS_LIBNETBOOT_IODESC_H */
diff --git a/lib/libstand/libstand.3 b/lib/libstand/libstand.3
new file mode 100644
index 0000000..99fbb54
--- /dev/null
+++ b/lib/libstand/libstand.3
@@ -0,0 +1,474 @@
+.\" Copyright (c) Michael Smith
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR Ohttp://wafu.netgate.net/tama/unix/indexe.htmlTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 22, 1998
+.Dt LIBSTAND 3
+.Os FreeBSD 3.0
+.Sh NAME
+.Nm libstand
+.Nd support library for standalone executables
+.Sh SYNOPSIS
+.Fd #include <stand.h>
+.Sh DESCRIPTION
+.Nm
+provides a set of supporting functions for standalone
+applications, mimicking where possible the standard BSD programming
+environment. The following sections group these functions by kind.
+Unless specifically described here, see the corresponding section 3
+manpages for the given functions.
+.Sh STRING FUNCTIONS
+String functions are available as documented in
+.Xr string 3
+and
+.Xr bstring 3 .
+.Sh MEMORY ALLOCATION
+.Bl -hang -width 10n
+.It Fn "void *malloc" "size_t size"
+.Pp
+Allocate
+.Fa size
+bytes of memory from the heap using a best-fit algorithm.
+.It Fn "void free" "void *ptr"
+.Pp
+Free the allocated object at
+.Fa ptr .
+.It Fn "void setheap" "void *start" "void *limit"
+.Pp
+Initialise the heap. This function must be called before calling
+.Fn alloc
+for the first time. The region between
+.Fa start
+and
+.Fa limit
+will be used for the heap; attempting to allocate beyond this will result
+in a panic.
+.It Fn "char *sbrk" "int junk"
+.Pp
+Provides the behaviour of
+.Fn sbrk 0 ,
+ie. returns the highest point that the heap has reached. This value can
+be used during testing to determine the actual heap usage. The
+.Fa junk
+argument is ignored.
+.El
+.Sh ENVIRONMENT
+A set of functions are provided for manipulating a flat variable space similar
+to the traditional shell-supported evironment. Major enhancements are support
+for set/unset hook functions.
+.Bl -hang -width 10n
+.It Fn "char *getenv" "const char *name"
+.It Fn "int setenv" "const char *name" "char *value" "int overwrite"
+.It Fn "int putenv" "const char *string"
+.It Fn "int unsetenv" "const char *name"
+.Pp
+These functions behave similarly to their standard library counterparts.
+.It Fn "struct env_var *env_getenv" "const char *name"
+.Pp
+Looks up a variable in the environment and returns its entire
+data structure.
+.It Fn "int env_setenv" "const char *name" "int flags" "char *value" "ev_sethook_t sethook" "ev_unsethook_t unsethook"
+.Pp
+Creates a new or sets an existing environment variable called
+.Fa name .
+If creating a new variable, the
+.Fa sethook
+and
+.Fa unsethook
+arguments may be specified.
+.Pp
+The set hook is invoked whenever an attempt
+is made to set the variable, unless the EV_NOHOOK flag is set. Typically
+a set hook will validate the
+.Fa value
+argument, and then call
+.Fn env_setenv
+again with EV_NOHOOK set to actually save the value. The predefined function
+.Fn env_noset
+may be specified to refuse all attempts to set a variable.
+.Pp
+The unset hook is invoked when an attempt is made to unset a variable. If it
+returns zero, the variable will be unset. The predefined function
+.Fa env_nounset
+may be used to prevent a variable being unset.
+.El
+.Sh STANDARD LIBRARY SUPPORT
+.Bl -hang -width 10n
+.It Fn "int getopt" "int argc" "char * const *argv" "cont char *optstring"
+.It Fn "long strtol" "const char *nptr" "char **endptr" "int base"
+.It Fn "void srandom" "unsigned long seed"
+.It Fn "unsigned long random" "void"
+.It Fn "char *strerror" "int error"
+.Pp
+Returns error messages for the subset of errno values supported by
+.Nm No .
+.It Fn "assert" "expression"
+.Pp
+Requires
+.Fd #include <assert.h>
+.It Fn "int setjmp" "jmp_buf env"
+.It Fn "void longjmp" "jmp_buf env" "int val"
+.Pp
+Defined as
+.Fn _setjmp
+and
+.Fn _lonjmp
+respectively as there is no signal state to manipulate. Requires
+.Fd #include <setjmp.h>
+.El
+.Sh CHARACTER I/O
+.Bl -hang -width 10n
+.It Fn "void gets" "char *buf"
+.Pp
+Read characters from the console into
+.Fa buf .
+All of the standard cautions apply to this function.
+.It Fn "void ngets" "char *buf" "size_t size"
+.Pp
+Read at most
+.Fa size
+- 1 characters from the console into
+.Fa buf .
+If
+.Fa size
+is less than 1, the function's behaviour is as for
+.Fn gets .
+.It Fn "int fgetstr" "char *buf" "int size" "int fd"
+.Pp
+Read a line of at most
+.Fa size
+characters into
+.Fa buf .
+Line terminating characters are stripped, and the buffer is always nul
+terminated. Returns the number of characters in
+.Fa buf
+if successful, or -1 if a read error occurs.
+.It Fn "int printf" "const char *fmt" "..."
+.It Fn "void vprintf" "const char *fmt" "va_list ap"
+.It Fn "int sprintf" "char *buf" "const char *fmt" "..."
+.It Fn "void vsprintf" "char *buf" "const char *fmt" "va_list ap"
+.Pp
+The *printf functions implement a subset of the standard
+.Fn printf
+family functionality and some extensions. The following standard conversions
+are supported: c,d,n,o,p,s,u,x. The following modifiers are supported:
++,-,#,*,0,field width,precision,l.
+.Pp
+The
+.Li b
+conversion is provided to decode error registers. Its usage is:
+.Pp
+.Bd -offset indent
+printf(
+.Qq reg=%b\en ,
+regval,
+.Qq <base><arg>*
+);
+.Ed
+
+where <base> is the output expressed as a control character, eg. \e10 gives
+octal, \e20 gives hex. Each <arg> is a sequence of characters, the first of
+which gives the bit number to be inspected (origin 1) and the next characters
+(up to a character less than 32) give the text to be displayed if the bit is set.
+Thus
+.Pp
+.Bd -offset indent
+printf(
+.Qq reg=%b\en
+3
+.Qq \e10\e2BITTWO\e1BITONE\en
+);
+.Ed
+
+would give the output
+.Pp
+.Bd -offset indent
+reg=3<BITTWO,BITONE>
+.Ed
+.Pp
+The
+.Li D
+conversion provides a hexdump facility, eg.
+.Pp
+.Bd -offset indent -literal
+printf(
+.Qq %6D ,
+ptr,
+.Qq \:
+); gives
+.Qq XX:XX:XX:XX:XX:XX
+.Ed
+.Bd -offset indent -literal
+printf(
+.Qq %*D ,
+len,
+ptr,
+.Qq "\ "
+); gives
+.Qq XX XX XX ...
+.Ed
+.El
+.Sh CHARACTER TESTS AND CONVERSIONS
+.Bl -hang -width 10n
+.It Fn "int isupper" "int c"
+.It Fn "int islower" "int c"
+.It Fn "int isspace" "int c"
+.It Fn "int isdigit" "int c"
+.It Fn "int isxdigit" "int c"
+.It Fn "int isascii" "int c"
+.It Fn "int isalpha" "int c"
+.It Fn "int toupper" "int c"
+.It Fn "int tolower" "int c"
+.El
+.Sh FILE I/O
+.Bl -hang -width 10n
+.It Fn "int open" "const char *path" "int flags"
+.Pp
+Similar to the behaviour as specified in
+.Xr open 2 ,
+except that file creation is not supported, so the mode parameter is not
+required. The
+.Fa flags
+argument may be one of O_RDONLY, O_WRONLY and O_RDWR (although no filesystems
+currently support writing).
+.It Fn "int close" "int fd"
+.It Fn "void closeall" "void"
+.Pp
+Close all open files.
+.It Fn "ssize_t read" "int fd" "void *buf" "size_t len"
+.It Fn "ssize_t write" "int fd" "void *buf" "size_t len"
+.Pp
+(No filesystems currently support writing.)
+.It Fn "off_t lseek" "int fd" "off_t offset" "int whence"
+.Pp
+Files being automatically uncompressed during reading cannot seek backwards
+from the current point.
+.It Fn "int stat" "const char *path" "struct stat *sb"
+.It Fn "int fstat" "int fd" "struct stat *sb"
+.Pp
+The
+.Fn stat
+and
+.Fn fstat
+functions only fill out the following fields in the
+.Fa sb
+structure: st_mode,st_nlink,st_uid,st_gid,st_size. The
+.Nm tftp
+filesystem cannot provide meaningful values for this call, and the
+.Nm cd9660
+filesystem always reports files having uid/gid of zero.
+.El
+.Sh PAGER
+.Nm
+supplies a simple internal pager to ease reading the output of large commands.
+.Bl -hang -width 10n
+.It Fn "void pager_open"
+.Pp
+Initialises the pager and tells it that the next line output will be the top of the
+display. The environment variable LINES is consulted to determine the number of
+lines to be displayed before pausing.
+.It Fn "void pager_close" "void"
+.Pp
+Closes the pager.
+.It Fn "void pager_output" "char *lines"
+.Pp
+Sends the lines in the nul-terminated buffer at
+.Fa lines
+to the pager. Newline characters are counted in order to determine the number
+of lines being output (wrapped lines are not accounted for).
+.Fn pager_output
+will return zero when all of the lines have been output, or nonzero if the
+display was paused and the user elected to quit.
+.It Fn "int pager_file" "char *fname"
+.Pp
+Attempts to open and display the file
+.Fa fname.
+ Returns -1 on error, 0 at EOF, or 1 if the user elects to quit while reading.
+.El
+.Sh MISC
+.Bl -hang -width 10n
+.It Fn "void twiddle" "void"
+.Pp
+Successive calls emit the characters in the sequence |,/,-,\\ followed by a
+backspace in order to provide reassurance to the user.
+.El
+.Sh REQUIRED LOW-LEVEL SUPPORT
+The following resources are consumed by
+.Nm
+- stack, heap, console and devices.
+.Pp
+The stack must be established before
+.Nm
+functions can be invoked. Stack requirements vary depending on the functions
+and filesystems used by the consumer and the support layer functions detailed
+below.
+.Pp
+The heap must be established before calling
+.Fn alloc
+or
+.Fn open
+by calling
+.Fn setheap .
+Heap usage will vary depending on the number of simultaneously open files,
+as well as client behaviour. Automatic decompression will allocate more
+than 64K of data per open file.
+.Pp
+Console access is performed via the
+.Fn getchar ,
+.Fn putchar
+and
+.Fn ischar
+functions detailed below.
+.Pp
+Device access is initiated via
+.Fn devopen
+and is performed through the
+.Fn dv_strategy ,
+.Fn dv_ioctl
+and
+.Fn dv_close
+functions in the device switch structure that
+.Fn devopen
+returns.
+.Pp
+The consumer must provide the following support functions:
+.Bl -hang -width 10n
+.It Fn "int getchar" "void"
+.Pp
+Return a character from the console, used by
+.Fn gets ,
+.Fn ngets
+and pager functions.
+.It Fn "int ischar" "void"
+.Pp
+Returns nonzero if a character is waiting from the console.
+.It Fn "void putchar" "int"
+.Pp
+Write a character to the console, used by
+.Fn gets ,
+.Fn ngets ,
+.Fn *printf ,
+.Fn panic
+and
+.Fn twiddle
+and thus by many other functions for debugging and informational output.
+.It Fn "int devopen" "struct open_file *of" "const char *name" "char **file"
+.Pp
+Open the appropriate device for the file named in
+.Fa name ,
+returning in
+.Fa file
+a pointer to the remaining body of
+.Fa name
+which does not refer to the device. The
+.Va f_dev
+field in
+.Fa of
+will be set to point to the
+.Dv devsw
+structure for the opened device if successful. Device identifiers must
+always precede the path component, but may otherwise be arbitrarily formatted.
+Used by
+.Fn open
+and thus for all device-related I/O.
+.It Fn "int devclose" "struct open_file *of"
+Close the device allocated for
+.Fa of .
+The device driver itself will already have been called for the close; this call
+should clean up any allocation made by devopen only.
+.It Fn "void panic" "const char *msg" "..."
+.Pp
+Signal a fatal and unrecoverable error condition. The
+.Fa msg ...
+arguments are as for
+.Fn printf .
+.El
+.Sh INTERNAL FILESYSTEMS
+Internal filesystems are enabled by the consumer exporting the array
+.Dv struct fs_ops *file_system[], which should be initialised with pointers
+to
+.Dv struct fs_ops
+structures. The following filesystem handlers are supplied by
+.Nm No ,
+the consumer may supply other filesystems of their own:
+.Bl -hang -width "cd9660_fsops "
+.It ufs_fsops
+The BSD UFS.
+.It tftp_fsops
+File access via TFTP.
+.It nfs_fsops
+File access via NFS.
+.It cd9660_fsops
+ISO 9660 (CD-ROM) filesystem.
+.It zipfs_fsops
+Stacked filesystem supporting gzipped files. When trying the zipfs filesystem,
+.Nm
+appends
+.Li .gz
+to the end of the filename, and then tries to locate the file using the other
+filesystems. Placement of this filesystem in the
+.Dv file_system[]
+array determines whether gzipped files will be opened in preference to non-gzipped
+files. It is only possible to seek a gzipped file forwards, and
+.Fn stat
+and
+.Fn fstat
+on gzipped files will report an invalid length.
+.El
+.Pp
+The array of
+.Dv struct fs_ops
+pointers should be terminated with a NULL.
+.Sh DEVICES
+Devices are exported by the supporting code via the array
+.Dv struct devsw *devsw[]
+which is a NULL terminated array of pointers to device switch structures.
+.Sh BUGS
+.Pp
+The lack of detailed memory usage data is unhelpful.
+.Sh HISTORY
+.Nm
+contains contributions from many sources, including:
+.Bl -bullet -compact
+.It
+.Nm libsa
+from
+.Nx
+.It
+.Nm libc
+and
+.Nm libkern
+from
+.Fx 3.0 .
+.It
+.Nm zalloc
+from
+.An Matthew Dillon Aq dillon@backplane.com
+.El
+.Pp
+The reorganisation and port to
+.Fx 3.0 ,
+the environment functions and this manpage were written by
+.An Mike Smith Aq msmith@freebsd.org .
diff --git a/lib/libstand/lseek.c b/lib/libstand/lseek.c
new file mode 100644
index 0000000..0894912
--- /dev/null
+++ b/lib/libstand/lseek.c
@@ -0,0 +1,102 @@
+/* $NetBSD: lseek.c,v 1.4 1997/01/22 00:38:10 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)lseek.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "stand.h"
+
+off_t
+lseek(fd, offset, where)
+ int fd;
+ off_t offset;
+ int where;
+{
+ register struct open_file *f = &files[fd];
+
+ if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
+ errno = EBADF;
+ return (-1);
+ }
+
+ if (f->f_flags & F_RAW) {
+ /*
+ * On RAW devices, update internal offset.
+ */
+ switch (where) {
+ case SEEK_SET:
+ f->f_offset = offset;
+ break;
+ case SEEK_CUR:
+ f->f_offset += offset;
+ break;
+ case SEEK_END:
+ default:
+ errno = EOFFSET;
+ return (-1);
+ }
+ return (f->f_offset);
+ }
+
+ return (f->f_ops->fo_seek)(f, offset, where);
+}
diff --git a/lib/libstand/net.c b/lib/libstand/net.c
new file mode 100644
index 0000000..978bd70
--- /dev/null
+++ b/lib/libstand/net.c
@@ -0,0 +1,503 @@
+/* $NetBSD: net.c,v 1.20 1997/12/26 22:41:30 scottr Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL)
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <string.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#include "stand.h"
+#include "net.h"
+
+/* Caller must leave room for ethernet, ip and udp headers in front!! */
+ssize_t
+sendudp(d, pkt, len)
+ register struct iodesc *d;
+ register void *pkt;
+ register size_t len;
+{
+ register ssize_t cc;
+ register struct ip *ip;
+ register struct udphdr *uh;
+ register u_char *ea;
+
+#ifdef NET_DEBUG
+ if (debug) {
+ printf("sendudp: d=%lx called.\n", (long)d);
+ if (d) {
+ printf("saddr: %s:%d",
+ inet_ntoa(d->myip), ntohs(d->myport));
+ printf(" daddr: %s:%d\n",
+ inet_ntoa(d->destip), ntohs(d->destport));
+ }
+ }
+#endif
+
+ uh = (struct udphdr *)pkt - 1;
+ ip = (struct ip *)uh - 1;
+ len += sizeof(*ip) + sizeof(*uh);
+
+ bzero(ip, sizeof(*ip) + sizeof(*uh));
+
+ ip->ip_v = IPVERSION; /* half-char */
+ ip->ip_hl = sizeof(*ip) >> 2; /* half-char */
+ ip->ip_len = htons(len);
+ ip->ip_p = IPPROTO_UDP; /* char */
+ ip->ip_ttl = IP_TTL; /* char */
+ ip->ip_src = d->myip;
+ ip->ip_dst = d->destip;
+ ip->ip_sum = in_cksum(ip, sizeof(*ip)); /* short, but special */
+
+ uh->uh_sport = d->myport;
+ uh->uh_dport = d->destport;
+ uh->uh_ulen = htons(len - sizeof(*ip));
+
+#ifndef UDP_NO_CKSUM
+ {
+ register struct udpiphdr *ui;
+ struct ip tip;
+
+ /* Calculate checksum (must save and restore ip header) */
+ tip = *ip;
+ ui = (struct udpiphdr *)ip;
+ bzero(&ui->ui_x1, sizeof(ui->ui_x1));
+ ui->ui_len = uh->uh_ulen;
+ uh->uh_sum = in_cksum(ui, len);
+ *ip = tip;
+ }
+#endif
+
+ if (ip->ip_dst.s_addr == INADDR_BROADCAST || ip->ip_src.s_addr == 0 ||
+ netmask == 0 || SAMENET(ip->ip_src, ip->ip_dst, netmask))
+ ea = arpwhohas(d, ip->ip_dst);
+ else
+ ea = arpwhohas(d, gateip);
+
+ cc = sendether(d, ip, len, ea, ETHERTYPE_IP);
+ if (cc == -1)
+ return (-1);
+ if (cc != len)
+ panic("sendudp: bad write (%d != %d)", cc, len);
+ return (cc - (sizeof(*ip) + sizeof(*uh)));
+}
+
+/*
+ * Receive a UDP packet and validate it is for us.
+ * Caller leaves room for the headers (Ether, IP, UDP)
+ */
+ssize_t
+readudp(d, pkt, len, tleft)
+ register struct iodesc *d;
+ register void *pkt;
+ register size_t len;
+ time_t tleft;
+{
+ register ssize_t n;
+ register size_t hlen;
+ register struct ip *ip;
+ register struct udphdr *uh;
+ u_int16_t etype; /* host order */
+
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: called\n");
+#endif
+
+ uh = (struct udphdr *)pkt - 1;
+ ip = (struct ip *)uh - 1;
+
+ n = readether(d, ip, len + sizeof(*ip) + sizeof(*uh), tleft, &etype);
+ if (n == -1 || n < sizeof(*ip) + sizeof(*uh))
+ return -1;
+
+ /* Ethernet address checks now in readether() */
+
+ /* Need to respond to ARP requests. */
+ if (etype == ETHERTYPE_ARP) {
+ struct arphdr *ah = (void *)ip;
+ if (ah->ar_op == htons(ARPOP_REQUEST)) {
+ /* Send ARP reply */
+ arp_reply(d, ah);
+ }
+ return -1;
+ }
+
+ if (etype != ETHERTYPE_IP) {
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: not IP. ether_type=%x\n", etype);
+#endif
+ return -1;
+ }
+
+ /* Check ip header */
+ if (ip->ip_v != IPVERSION ||
+ ip->ip_p != IPPROTO_UDP) { /* half char */
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: IP version or not UDP. ip_v=%d ip_p=%d\n", ip->ip_v, ip->ip_p);
+#endif
+ return -1;
+ }
+
+ hlen = ip->ip_hl << 2;
+ if (hlen < sizeof(*ip) ||
+ in_cksum(ip, hlen) != 0) {
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: short hdr or bad cksum.\n");
+#endif
+ return -1;
+ }
+ if (n < ntohs(ip->ip_len)) {
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: bad length %d < %d.\n",
+ (int)n, ntohs(ip->ip_len));
+#endif
+ return -1;
+ }
+ if (d->myip.s_addr && ip->ip_dst.s_addr != d->myip.s_addr) {
+#ifdef NET_DEBUG
+ if (debug) {
+ printf("readudp: bad saddr %s != ", inet_ntoa(d->myip));
+ printf("%s\n", inet_ntoa(ip->ip_dst));
+ }
+#endif
+ return -1;
+ }
+
+ /* If there were ip options, make them go away */
+ if (hlen != sizeof(*ip)) {
+ bcopy(((u_char *)ip) + hlen, uh, len - hlen);
+ ip->ip_len = htons(sizeof(*ip));
+ n -= hlen - sizeof(*ip);
+ }
+ if (uh->uh_dport != d->myport) {
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: bad dport %d != %d\n",
+ d->myport, ntohs(uh->uh_dport));
+#endif
+ return -1;
+ }
+
+#ifndef UDP_NO_CKSUM
+ if (uh->uh_sum) {
+ register struct udpiphdr *ui;
+ struct ip tip;
+
+ n = ntohs(uh->uh_ulen) + sizeof(*ip);
+ if (n > RECV_SIZE - ETHER_SIZE) {
+ printf("readudp: huge packet, udp len %d\n", (int)n);
+ return -1;
+ }
+
+ /* Check checksum (must save and restore ip header) */
+ tip = *ip;
+ ui = (struct udpiphdr *)ip;
+ bzero(&ui->ui_x1, sizeof(ui->ui_x1));
+ ui->ui_len = uh->uh_ulen;
+ if (in_cksum(ui, n) != 0) {
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: bad cksum\n");
+#endif
+ *ip = tip;
+ return -1;
+ }
+ *ip = tip;
+ }
+#endif
+ if (ntohs(uh->uh_ulen) < sizeof(*uh)) {
+#ifdef NET_DEBUG
+ if (debug)
+ printf("readudp: bad udp len %d < %d\n",
+ ntohs(uh->uh_ulen), (int)sizeof(*uh));
+#endif
+ return -1;
+ }
+
+ n -= sizeof(*ip) + sizeof(*uh);
+ return (n);
+}
+
+/*
+ * Send a packet and wait for a reply, with exponential backoff.
+ *
+ * The send routine must return the actual number of bytes written,
+ * or -1 on error.
+ *
+ * The receive routine can indicate success by returning the number of
+ * bytes read; it can return 0 to indicate EOF; it can return -1 with a
+ * non-zero errno to indicate failure; finally, it can return -1 with a
+ * zero errno to indicate it isn't done yet.
+ */
+ssize_t
+sendrecv(d, sproc, sbuf, ssize, rproc, rbuf, rsize)
+ register struct iodesc *d;
+ register ssize_t (*sproc)(struct iodesc *, void *, size_t);
+ register void *sbuf;
+ register size_t ssize;
+ register ssize_t (*rproc)(struct iodesc *, void *, size_t, time_t);
+ register void *rbuf;
+ register size_t rsize;
+{
+ register ssize_t cc;
+ register time_t t, tmo, tlast;
+ long tleft;
+
+#ifdef NET_DEBUG
+ if (debug)
+ printf("sendrecv: called\n");
+#endif
+
+ tmo = MINTMO;
+ tlast = tleft = 0;
+ t = getsecs();
+ for (;;) {
+ if (tleft <= 0) {
+ if (tmo >= MAXTMO) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ cc = (*sproc)(d, sbuf, ssize);
+ if (cc != -1 && cc < ssize)
+ panic("sendrecv: short write! (%d < %d)",
+ cc, ssize);
+
+ tleft = tmo;
+ tmo <<= 1;
+ if (tmo > MAXTMO)
+ tmo = MAXTMO;
+
+ if (cc == -1) {
+ /* Error on transmit; wait before retrying */
+ while ((getsecs() - t) < tmo);
+ tleft = 0;
+ continue;
+ }
+
+ tlast = t;
+ }
+
+ /* Try to get a packet and process it. */
+ cc = (*rproc)(d, rbuf, rsize, tleft);
+ /* Return on data, EOF or real error. */
+ if (cc != -1 || errno != 0)
+ return (cc);
+
+ /* Timed out or didn't get the packet we're waiting for */
+ t = getsecs();
+ tleft -= t - tlast;
+ tlast = t;
+ }
+}
+
+/*
+ * Like inet_addr() in the C library, but we only accept base-10.
+ * Return values are in network order.
+ */
+n_long
+inet_addr(cp)
+ char *cp;
+{
+ register u_long val;
+ register int n;
+ register char c;
+ u_int parts[4];
+ register u_int *pp = parts;
+
+ for (;;) {
+ /*
+ * Collect number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, other=decimal.
+ */
+ val = 0;
+ while ((c = *cp) != '\0') {
+ if (c >= '0' && c <= '9') {
+ val = (val * 10) + (c - '0');
+ cp++;
+ continue;
+ }
+ break;
+ }
+ if (*cp == '.') {
+ /*
+ * Internet format:
+ * a.b.c.d
+ * a.b.c (with c treated as 16-bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3 || val > 0xff)
+ goto bad;
+ *pp++ = val, cp++;
+ } else
+ break;
+ }
+ /*
+ * Check for trailing characters.
+ */
+ if (*cp != '\0')
+ goto bad;
+
+ /*
+ * Concoct the address according to
+ * the number of parts specified.
+ */
+ n = pp - parts + 1;
+ switch (n) {
+
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffff)
+ goto bad;
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ goto bad;
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ goto bad;
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+
+ return (htonl(val));
+ bad:
+ return (htonl(INADDR_NONE));
+}
+
+char *
+inet_ntoa(ia)
+ struct in_addr ia;
+{
+ return (intoa(ia.s_addr));
+}
+
+/* Similar to inet_ntoa() */
+char *
+intoa(addr)
+ register n_long addr;
+{
+ register char *cp;
+ register u_int byte;
+ register int n;
+ static char buf[17]; /* strlen(".255.255.255.255") + 1 */
+
+ NTOHL(addr);
+ cp = &buf[sizeof buf];
+ *--cp = '\0';
+
+ n = 4;
+ do {
+ byte = addr & 0xff;
+ *--cp = byte % 10 + '0';
+ byte /= 10;
+ if (byte > 0) {
+ *--cp = byte % 10 + '0';
+ byte /= 10;
+ if (byte > 0)
+ *--cp = byte + '0';
+ }
+ *--cp = '.';
+ addr >>= 8;
+ } while (--n > 0);
+
+ return (cp+1);
+}
+
+static char *
+number(s, n)
+ char *s;
+ int *n;
+{
+ for (*n = 0; isdigit(*s); s++)
+ *n = (*n * 10) + *s - '0';
+ return s;
+}
+
+n_long
+ip_convertaddr(p)
+ char *p;
+{
+#define IP_ANYADDR 0
+ n_long addr = 0, n;
+
+ if (p == (char *)0 || *p == '\0')
+ return IP_ANYADDR;
+ p = number(p, &n);
+ addr |= (n << 24) & 0xff000000;
+ if (*p == '\0' || *p++ != '.')
+ return IP_ANYADDR;
+ p = number(p, &n);
+ addr |= (n << 16) & 0xff0000;
+ if (*p == '\0' || *p++ != '.')
+ return IP_ANYADDR;
+ p = number(p, &n);
+ addr |= (n << 8) & 0xff00;
+ if (*p == '\0' || *p++ != '.')
+ return IP_ANYADDR;
+ p = number(p, &n);
+ addr |= n & 0xff;
+ if (*p != '\0')
+ return IP_ANYADDR;
+
+ return htonl(addr);
+}
diff --git a/lib/libstand/net.h b/lib/libstand/net.h
new file mode 100644
index 0000000..6f6d443
--- /dev/null
+++ b/lib/libstand/net.h
@@ -0,0 +1,122 @@
+/* $NetBSD: net.h,v 1.10 1995/10/20 00:46:30 cgd Exp $ */
+
+/*
+ * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define NETIF_DEBUG 1
+
+#ifndef _KERNEL /* XXX - see <netinet/in.h> */
+#undef __IPADDR
+#define __IPADDR(x) htonl((u_int32_t)(x))
+#endif
+
+#include "iodesc.h"
+
+#define BA { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
+
+/* Returns true if n_long's on the same net */
+#define SAMENET(a1, a2, m) ((a1.s_addr & m) == (a2.s_addr & m))
+
+#define MACPY(s, d) bcopy((char *)s, (char *)d, 6)
+
+#define MAXTMO 20 /* seconds */
+#define MINTMO 2 /* seconds */
+
+#define FNAME_SIZE 128
+#define IFNAME_SIZE 16
+#define RECV_SIZE 1536 /* XXX delete this */
+
+/*
+ * How much room to leave for headers:
+ * 14: struct ether_header
+ * 20: struct ip
+ * 8: struct udphdr
+ * That's 42 but let's pad it out to 48 bytes.
+ */
+#define ETHER_SIZE 14
+#define HEADER_SIZE 48
+
+extern u_char bcea[6];
+extern char rootpath[FNAME_SIZE];
+extern char bootfile[FNAME_SIZE];
+extern char hostname[FNAME_SIZE];
+extern int hostnamelen;
+extern char domainname[FNAME_SIZE];
+extern int domainnamelen;
+extern char ifname[IFNAME_SIZE];
+
+/* All of these are in network order. */
+extern struct in_addr myip;
+extern struct in_addr rootip;
+extern struct in_addr swapip;
+extern struct in_addr gateip;
+extern struct in_addr nameip;
+extern n_long netmask;
+
+extern int debug; /* defined in the machdep sources */
+
+extern struct iodesc sockets[SOPEN_MAX];
+
+/* ARP/RevARP functions: */
+u_char *arpwhohas(struct iodesc *, struct in_addr);
+void arp_reply(struct iodesc *, void *);
+int rarp_getipaddress(int);
+
+/* Link functions: */
+ssize_t sendether(struct iodesc *d, void *pkt, size_t len,
+ u_char *dea, int etype);
+ssize_t readether(struct iodesc *d, void *pkt, size_t len,
+ time_t tleft, u_int16_t *etype);
+
+ssize_t sendudp(struct iodesc *, void *, size_t);
+ssize_t readudp(struct iodesc *, void *, size_t, time_t);
+ssize_t sendrecv(struct iodesc *,
+ ssize_t (*)(struct iodesc *, void *, size_t),
+ void *, size_t,
+ ssize_t (*)(struct iodesc *, void *, size_t, time_t),
+ void *, size_t);
+
+/* Utilities: */
+char *ether_sprintf(u_char *);
+int in_cksum(void *, int);
+char *inet_ntoa(struct in_addr);
+char *intoa(n_long); /* similar to inet_ntoa */
+n_long inet_addr(char *);
+
+/* Machine-dependent functions: */
+time_t getsecs(void);
diff --git a/lib/libstand/netif.c b/lib/libstand/netif.c
new file mode 100644
index 0000000..bc1b7bd
--- /dev/null
+++ b/lib/libstand/netif.c
@@ -0,0 +1,332 @@
+/* $NetBSD: netif.c,v 1.10 1997/09/06 13:57:14 drochner Exp $ */
+
+/*
+ * Copyright (c) 1993 Adam Glass
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Adam Glass.
+ * 4. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/mount.h>
+#include <string.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+
+struct iodesc sockets[SOPEN_MAX];
+#ifdef NETIF_DEBUG
+int netif_debug = 0;
+#endif
+
+/*
+ * netif_init:
+ *
+ * initialize the generic network interface layer
+ */
+
+void
+netif_init()
+{
+ struct netif_driver *drv;
+ int d, i;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("netif_init: called\n");
+#endif
+ for (d = 0; netif_drivers[d]; d++) {
+ drv = netif_drivers[d];
+ for (i = 0; i < drv->netif_nifs; i++)
+ drv->netif_ifs[i].dif_used = 0;
+ }
+}
+
+int
+netif_match(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+ struct netif_driver *drv = nif->nif_driver;
+
+#if 0
+ if (netif_debug)
+ printf("%s%d: netif_match (%d)\n", drv->netif_bname,
+ nif->nif_unit, nif->nif_sel);
+#endif
+ return drv->netif_match(nif, machdep_hint);
+}
+
+struct netif *
+netif_select(machdep_hint)
+ void *machdep_hint;
+{
+ int d, u, unit_done, s;
+ struct netif_driver *drv;
+ struct netif cur_if;
+ static struct netif best_if;
+ int best_val;
+ int val;
+
+ best_val = 0;
+ best_if.nif_driver = NULL;
+
+ for (d = 0; netif_drivers[d] != NULL; d++) {
+ cur_if.nif_driver = netif_drivers[d];
+ drv = cur_if.nif_driver;
+
+ for (u = 0; u < drv->netif_nifs; u++) {
+ cur_if.nif_unit = u;
+ unit_done = 0;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("\t%s%d:", drv->netif_bname,
+ cur_if.nif_unit);
+#endif
+
+ for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) {
+ cur_if.nif_sel = s;
+
+ if (drv->netif_ifs[u].dif_used & (1 << s)) {
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf(" [%d used]", s);
+#endif
+ continue;
+ }
+
+ val = netif_match(&cur_if, machdep_hint);
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf(" [%d -> %d]", s, val);
+#endif
+ if (val > best_val) {
+ best_val = val;
+ best_if = cur_if;
+ }
+ }
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("\n");
+#endif
+ }
+ }
+
+ if (best_if.nif_driver == NULL)
+ return NULL;
+
+ best_if.nif_driver->
+ netif_ifs[best_if.nif_unit].dif_used |= (1 << best_if.nif_sel);
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("netif_select: %s%d(%d) wins\n",
+ best_if.nif_driver->netif_bname,
+ best_if.nif_unit, best_if.nif_sel);
+#endif
+ return &best_if;
+}
+
+int
+netif_probe(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+ struct netif_driver *drv = nif->nif_driver;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit);
+#endif
+ return drv->netif_probe(nif, machdep_hint);
+}
+
+void
+netif_attach(nif, desc, machdep_hint)
+ struct netif *nif;
+ struct iodesc *desc;
+ void *machdep_hint;
+{
+ struct netif_driver *drv = nif->nif_driver;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit);
+#endif
+ desc->io_netif = nif;
+#ifdef PARANOID
+ if (drv->netif_init == NULL)
+ panic("%s%d: no netif_init support\n", drv->netif_bname,
+ nif->nif_unit);
+#endif
+ drv->netif_init(desc, machdep_hint);
+ bzero(drv->netif_ifs[nif->nif_unit].dif_stats,
+ sizeof(struct netif_stats));
+}
+
+void
+netif_detach(nif)
+ struct netif *nif;
+{
+ struct netif_driver *drv = nif->nif_driver;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit);
+#endif
+#ifdef PARANOID
+ if (drv->netif_end == NULL)
+ panic("%s%d: no netif_end support\n", drv->netif_bname,
+ nif->nif_unit);
+#endif
+ drv->netif_end(nif);
+}
+
+ssize_t
+netif_get(desc, pkt, len, timo)
+ struct iodesc *desc;
+ void *pkt;
+ size_t len;
+ time_t timo;
+{
+#ifdef NETIF_DEBUG
+ struct netif *nif = desc->io_netif;
+#endif
+ struct netif_driver *drv = desc->io_netif->nif_driver;
+ ssize_t rv;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_get\n", drv->netif_bname, nif->nif_unit);
+#endif
+#ifdef PARANOID
+ if (drv->netif_get == NULL)
+ panic("%s%d: no netif_get support\n", drv->netif_bname,
+ nif->nif_unit);
+#endif
+ rv = drv->netif_get(desc, pkt, len, timo);
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_get returning %d\n", drv->netif_bname,
+ nif->nif_unit, (int)rv);
+#endif
+ return rv;
+}
+
+ssize_t
+netif_put(desc, pkt, len)
+ struct iodesc *desc;
+ void *pkt;
+ size_t len;
+{
+#ifdef NETIF_DEBUG
+ struct netif *nif = desc->io_netif;
+#endif
+ struct netif_driver *drv = desc->io_netif->nif_driver;
+ ssize_t rv;
+
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit);
+#endif
+#ifdef PARANOID
+ if (drv->netif_put == NULL)
+ panic("%s%d: no netif_put support\n", drv->netif_bname,
+ nif->nif_unit);
+#endif
+ rv = drv->netif_put(desc, pkt, len);
+#ifdef NETIF_DEBUG
+ if (netif_debug)
+ printf("%s%d: netif_put returning %d\n", drv->netif_bname,
+ nif->nif_unit, (int)rv);
+#endif
+ return rv;
+}
+
+struct iodesc *
+socktodesc(sock)
+ int sock;
+{
+ if (sock >= SOPEN_MAX) {
+ errno = EBADF;
+ return (NULL);
+ }
+ return (&sockets[sock]);
+}
+
+int
+netif_open(machdep_hint)
+ void *machdep_hint;
+{
+ int fd;
+ register struct iodesc *s;
+ struct netif *nif;
+
+ /* find a free socket */
+ for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++)
+ if (s->io_netif == (struct netif *)0)
+ goto fnd;
+ errno = EMFILE;
+ return (-1);
+
+fnd:
+ bzero(s, sizeof(*s));
+ netif_init();
+ nif = netif_select(machdep_hint);
+ if (!nif)
+ panic("netboot: no interfaces left untried");
+ if (netif_probe(nif, machdep_hint)) {
+ printf("netboot: couldn't probe %s%d\n",
+ nif->nif_driver->netif_bname, nif->nif_unit);
+ errno = EINVAL;
+ return(-1);
+ }
+ netif_attach(nif, s, machdep_hint);
+
+ return(fd);
+}
+
+int
+netif_close(sock)
+ int sock;
+{
+ if (sock >= SOPEN_MAX) {
+ errno = EBADF;
+ return(-1);
+ }
+ netif_detach(sockets[sock].io_netif);
+ sockets[sock].io_netif = (struct netif *)0;
+
+ return(0);
+}
diff --git a/lib/libstand/netif.h b/lib/libstand/netif.h
new file mode 100644
index 0000000..0609310
--- /dev/null
+++ b/lib/libstand/netif.h
@@ -0,0 +1,65 @@
+/* $NetBSD: netif.h,v 1.4 1995/09/14 23:45:30 pk Exp $ */
+
+#ifndef __SYS_LIBNETBOOT_NETIF_H
+#define __SYS_LIBNETBOOT_NETIF_H
+#include "iodesc.h"
+
+#define NENTS(x) sizeof(x)/sizeof(x[0])
+
+struct netif_driver {
+ char *netif_bname;
+ int (*netif_match)(struct netif *, void *);
+ int (*netif_probe)(struct netif *, void *);
+ void (*netif_init)(struct iodesc *, void *);
+ int (*netif_get)(struct iodesc *, void *, size_t, time_t);
+ int (*netif_put)(struct iodesc *, void *, size_t);
+ void (*netif_end)(struct netif *);
+ struct netif_dif *netif_ifs;
+ int netif_nifs;
+};
+
+struct netif_dif {
+ int dif_unit;
+ int dif_nsel;
+ struct netif_stats *dif_stats;
+ void *dif_private;
+ /* the following fields are used internally by the netif layer */
+ u_long dif_used;
+};
+
+struct netif_stats {
+ int collisions;
+ int collision_error;
+ int missed;
+ int sent;
+ int received;
+ int deferred;
+ int overflow;
+};
+
+struct netif {
+ struct netif_driver *nif_driver;
+ int nif_unit;
+ int nif_sel;
+ void *nif_devdata;
+};
+
+extern struct netif_driver *netif_drivers[]; /* machdep */
+extern int n_netif_drivers;
+
+extern int netif_debug;
+
+void netif_init(void);
+struct netif *netif_select(void *);
+int netif_probe(struct netif *, void *);
+void netif_attach(struct netif *, struct iodesc *, void *);
+void netif_detach(struct netif *);
+ssize_t netif_get(struct iodesc *, void *, size_t, time_t);
+ssize_t netif_put(struct iodesc *, void *, size_t);
+
+int netif_open(void *);
+int netif_close(int);
+
+struct iodesc *socktodesc(int);
+
+#endif /* __SYS_LIBNETBOOT_NETIF_H */
diff --git a/lib/libstand/nfs.c b/lib/libstand/nfs.c
new file mode 100644
index 0000000..7b0e783
--- /dev/null
+++ b/lib/libstand/nfs.c
@@ -0,0 +1,659 @@
+/* $NetBSD: nfs.c,v 1.2 1998/01/24 12:43:09 drochner Exp $ */
+
+/*-
+ * Copyright (c) 1993 John Brezak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include "rpcv2.h"
+#include "nfsv2.h"
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+#include "rpc.h"
+
+#define NFS_DEBUGxx
+
+/* Define our own NFS attributes without NQNFS stuff. */
+struct nfsv2_fattrs {
+ n_long fa_type;
+ n_long fa_mode;
+ n_long fa_nlink;
+ n_long fa_uid;
+ n_long fa_gid;
+ n_long fa_size;
+ n_long fa_blocksize;
+ n_long fa_rdev;
+ n_long fa_blocks;
+ n_long fa_fsid;
+ n_long fa_fileid;
+ struct nfsv2_time fa_atime;
+ struct nfsv2_time fa_mtime;
+ struct nfsv2_time fa_ctime;
+};
+
+
+struct nfs_read_args {
+ u_char fh[NFS_FHSIZE];
+ n_long off;
+ n_long len;
+ n_long xxx; /* XXX what's this for? */
+};
+
+/* Data part of nfs rpc reply (also the largest thing we receive) */
+#define NFSREAD_SIZE 1024
+struct nfs_read_repl {
+ n_long errno;
+ struct nfsv2_fattrs fa;
+ n_long count;
+ u_char data[NFSREAD_SIZE];
+};
+
+#ifndef NFS_NOSYMLINK
+struct nfs_readlnk_repl {
+ n_long errno;
+ n_long len;
+ char path[NFS_MAXPATHLEN];
+};
+#endif
+
+struct nfs_iodesc {
+ struct iodesc *iodesc;
+ off_t off;
+ u_char fh[NFS_FHSIZE];
+ struct nfsv2_fattrs fa; /* all in network order */
+};
+
+/*
+ * XXX interactions with tftp? See nfswrapper.c for a confusing
+ * issue.
+ */
+int nfs_open(const char *path, struct open_file *f);
+static int nfs_close(struct open_file *f);
+static int nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static int nfs_write(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t nfs_seek(struct open_file *f, off_t offset, int where);
+static int nfs_stat(struct open_file *f, struct stat *sb);
+
+struct fs_ops nfs_fsops = {
+ "nfs", nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat
+};
+
+
+/*
+ * Fetch the root file handle (call mount daemon)
+ * Return zero or error number.
+ */
+int
+nfs_getrootfh(d, path, fhp)
+ register struct iodesc *d;
+ char *path;
+ u_char *fhp;
+{
+ register int len;
+ struct args {
+ n_long len;
+ char path[FNAME_SIZE];
+ } *args;
+ struct repl {
+ n_long errno;
+ u_char fh[NFS_FHSIZE];
+ } *repl;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct repl d;
+ } rdata;
+ size_t cc;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_getrootfh: %s\n", path);
+#endif
+
+ args = &sdata.d;
+ repl = &rdata.d;
+
+ bzero(args, sizeof(*args));
+ len = strlen(path);
+ if (len > sizeof(args->path))
+ len = sizeof(args->path);
+ args->len = htonl(len);
+ bcopy(path, args->path, len);
+ len = 4 + roundup(len, 4);
+
+ cc = rpc_call(d, RPCPROG_MNT, RPCMNT_VER1, RPCMNT_MOUNT,
+ args, len, repl, sizeof(*repl));
+ if (cc == -1) {
+ /* errno was set by rpc_call */
+ return (errno);
+ }
+ if (cc < 4)
+ return (EBADRPC);
+ if (repl->errno)
+ return (ntohl(repl->errno));
+ bcopy(repl->fh, fhp, sizeof(repl->fh));
+ return (0);
+}
+
+/*
+ * Lookup a file. Store handle and attributes.
+ * Return zero or error number.
+ */
+int
+nfs_lookupfh(d, name, newfd)
+ struct nfs_iodesc *d;
+ const char *name;
+ struct nfs_iodesc *newfd;
+{
+ register int len, rlen;
+ struct args {
+ u_char fh[NFS_FHSIZE];
+ n_long len;
+ char name[FNAME_SIZE];
+ } *args;
+ struct repl {
+ n_long errno;
+ u_char fh[NFS_FHSIZE];
+ struct nfsv2_fattrs fa;
+ } *repl;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct repl d;
+ } rdata;
+ ssize_t cc;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("lookupfh: called\n");
+#endif
+
+ args = &sdata.d;
+ repl = &rdata.d;
+
+ bzero(args, sizeof(*args));
+ bcopy(d->fh, args->fh, sizeof(args->fh));
+ len = strlen(name);
+ if (len > sizeof(args->name))
+ len = sizeof(args->name);
+ bcopy(name, args->name, len);
+ args->len = htonl(len);
+ len = 4 + roundup(len, 4);
+ len += NFS_FHSIZE;
+
+ rlen = sizeof(*repl);
+
+ cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_LOOKUP,
+ args, len, repl, rlen);
+ if (cc == -1)
+ return (errno); /* XXX - from rpc_call */
+ if (cc < 4)
+ return (EIO);
+ if (repl->errno) {
+ /* saerrno.h now matches NFS error numbers. */
+ return (ntohl(repl->errno));
+ }
+ bcopy( repl->fh, &newfd->fh, sizeof(newfd->fh));
+ bcopy(&repl->fa, &newfd->fa, sizeof(newfd->fa));
+ return (0);
+}
+
+#ifndef NFS_NOSYMLINK
+/*
+ * Get the destination of a symbolic link.
+ */
+int
+nfs_readlink(d, buf)
+ struct nfs_iodesc *d;
+ char *buf;
+{
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ u_char fh[NFS_FHSIZE];
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct nfs_readlnk_repl d;
+ } rdata;
+ ssize_t cc;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("readlink: called\n");
+#endif
+
+ bcopy(d->fh, sdata.fh, NFS_FHSIZE);
+ cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READLINK,
+ sdata.fh, NFS_FHSIZE,
+ &rdata.d, sizeof(rdata.d));
+ if (cc == -1)
+ return (errno);
+
+ if (cc < 4)
+ return (EIO);
+
+ if (rdata.d.errno)
+ return (ntohl(rdata.d.errno));
+
+ rdata.d.len = ntohl(rdata.d.len);
+ if (rdata.d.len > NFS_MAXPATHLEN)
+ return (ENAMETOOLONG);
+
+ bcopy(rdata.d.path, buf, rdata.d.len);
+ buf[rdata.d.len] = 0;
+ return (0);
+}
+#endif
+
+/*
+ * Read data from a file.
+ * Return transfer count or -1 (and set errno)
+ */
+ssize_t
+nfs_readdata(d, off, addr, len)
+ struct nfs_iodesc *d;
+ off_t off;
+ void *addr;
+ size_t len;
+{
+ struct nfs_read_args *args;
+ struct nfs_read_repl *repl;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct nfs_read_args d;
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct nfs_read_repl d;
+ } rdata;
+ size_t cc;
+ long x;
+ int hlen, rlen;
+
+ args = &sdata.d;
+ repl = &rdata.d;
+
+ bcopy(d->fh, args->fh, NFS_FHSIZE);
+ args->off = htonl((n_long)off);
+ if (len > NFSREAD_SIZE)
+ len = NFSREAD_SIZE;
+ args->len = htonl((n_long)len);
+ args->xxx = htonl((n_long)0);
+ hlen = sizeof(*repl) - NFSREAD_SIZE;
+
+ cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READ,
+ args, sizeof(*args),
+ repl, sizeof(*repl));
+ if (cc == -1) {
+ /* errno was already set by rpc_call */
+ return (-1);
+ }
+ if (cc < hlen) {
+ errno = EBADRPC;
+ return (-1);
+ }
+ if (repl->errno) {
+ errno = ntohl(repl->errno);
+ return (-1);
+ }
+ rlen = cc - hlen;
+ x = ntohl(repl->count);
+ if (rlen < x) {
+ printf("nfsread: short packet, %d < %ld\n", rlen, x);
+ errno = EBADRPC;
+ return(-1);
+ }
+ bcopy(repl->data, addr, x);
+ return (x);
+}
+
+/*
+ * Open a file.
+ * return zero or error number
+ */
+int
+nfs_open(upath, f)
+ const char *upath;
+ struct open_file *f;
+{
+ static struct nfs_iodesc nfs_root_node;
+ struct iodesc *desc;
+ struct nfs_iodesc *currfd;
+#ifndef NFS_NOSYMLINK
+ struct nfs_iodesc *newfd;
+ struct nfsv2_fattrs *fa;
+ register char *cp, *ncp;
+ register int c;
+ char namebuf[NFS_MAXPATHLEN + 1];
+ char linkbuf[NFS_MAXPATHLEN + 1];
+ int nlinks = 0;
+#endif
+ int error;
+ char *path;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_open: %s (rootpath=%s)\n", path, rootpath);
+#endif
+ if (!rootpath[0]) {
+ printf("no rootpath, no nfs\n");
+ return (ENXIO);
+ }
+
+ if (!(desc = socktodesc(*(int *)(f->f_devdata))))
+ return(EINVAL);
+
+ /* Bind to a reserved port. */
+ desc->myport = htons(--rpc_port);
+ desc->destip = rootip;
+ if ((error = nfs_getrootfh(desc, rootpath, nfs_root_node.fh)))
+ return (error);
+ nfs_root_node.iodesc = desc;
+
+#ifndef NFS_NOSYMLINK
+ /* Fake up attributes for the root dir. */
+ fa = &nfs_root_node.fa;
+ fa->fa_type = htonl(NFDIR);
+ fa->fa_mode = htonl(0755);
+ fa->fa_nlink = htonl(2);
+
+ currfd = &nfs_root_node;
+ newfd = 0;
+
+ cp = path = strdup(upath);
+ if (path == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+ while (*cp) {
+ /*
+ * Remove extra separators
+ */
+ while (*cp == '/')
+ cp++;
+
+ if (*cp == '\0')
+ break;
+ /*
+ * Check that current node is a directory.
+ */
+ if (currfd->fa.fa_type != htonl(NFDIR)) {
+ error = ENOTDIR;
+ goto out;
+ }
+
+ /* allocate file system specific data structure */
+ newfd = malloc(sizeof(*newfd));
+ newfd->iodesc = currfd->iodesc;
+ newfd->off = 0;
+
+ /*
+ * Get next component of path name.
+ */
+ {
+ register int len = 0;
+
+ ncp = cp;
+ while ((c = *cp) != '\0' && c != '/') {
+ if (++len > NFS_MAXNAMLEN) {
+ error = ENOENT;
+ goto out;
+ }
+ cp++;
+ }
+ *cp = '\0';
+ }
+
+ /* lookup a file handle */
+ error = nfs_lookupfh(currfd, ncp, newfd);
+ *cp = c;
+ if (error)
+ goto out;
+
+ /*
+ * Check for symbolic link
+ */
+ if (newfd->fa.fa_type == htonl(NFLNK)) {
+ int link_len, len;
+
+ error = nfs_readlink(newfd, linkbuf);
+ if (error)
+ goto out;
+
+ link_len = strlen(linkbuf);
+ len = strlen(cp);
+
+ if (link_len + len > MAXPATHLEN
+ || ++nlinks > MAXSYMLINKS) {
+ error = ENOENT;
+ goto out;
+ }
+
+ bcopy(cp, &namebuf[link_len], len + 1);
+ bcopy(linkbuf, namebuf, link_len);
+
+ /*
+ * If absolute pathname, restart at root.
+ * If relative pathname, restart at parent directory.
+ */
+ cp = namebuf;
+ if (*cp == '/') {
+ if (currfd != &nfs_root_node)
+ free(currfd);
+ currfd = &nfs_root_node;
+ }
+
+ free(newfd);
+ newfd = 0;
+
+ continue;
+ }
+
+ if (currfd != &nfs_root_node)
+ free(currfd);
+ currfd = newfd;
+ newfd = 0;
+ }
+
+ error = 0;
+
+out:
+ if (newfd)
+ free(newfd);
+ if (path)
+ free(path);
+#else
+ /* allocate file system specific data structure */
+ currfd = malloc(sizeof(*currfd));
+ currfd->iodesc = desc;
+ currfd->off = 0;
+
+ error = nfs_lookupfh(&nfs_root_node, upath, currfd);
+#endif
+ if (!error) {
+ f->f_fsdata = (void *)currfd;
+ return (0);
+ }
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_open: %s lookupfh failed: %s\n",
+ path, strerror(error));
+#endif
+#ifndef NFS_NOSYMLINK
+ if (currfd != &nfs_root_node)
+#endif
+ free(currfd);
+
+ return (error);
+}
+
+int
+nfs_close(f)
+ struct open_file *f;
+{
+ register struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_close: fp=0x%lx\n", (u_long)fp);
+#endif
+
+ if (fp)
+ free(fp);
+ f->f_fsdata = (void *)0;
+
+ return (0);
+}
+
+/*
+ * read a portion of a file
+ */
+int
+nfs_read(f, buf, size, resid)
+ struct open_file *f;
+ void *buf;
+ size_t size;
+ size_t *resid; /* out */
+{
+ register struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
+ register ssize_t cc;
+ register char *addr = buf;
+
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_read: size=%lu off=%d\n", (u_long)size,
+ (int)fp->off);
+#endif
+ while ((int)size > 0) {
+ twiddle();
+ cc = nfs_readdata(fp, fp->off, (void *)addr, size);
+ /* XXX maybe should retry on certain errors */
+ if (cc == -1) {
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_read: read: %s", strerror(errno));
+#endif
+ return (errno); /* XXX - from nfs_readdata */
+ }
+ if (cc == 0) {
+#ifdef NFS_DEBUG
+ if (debug)
+ printf("nfs_read: hit EOF unexpectantly");
+#endif
+ goto ret;
+ }
+ fp->off += cc;
+ addr += cc;
+ size -= cc;
+ }
+ret:
+ if (resid)
+ *resid = size;
+
+ return (0);
+}
+
+/*
+ * Not implemented.
+ */
+int
+nfs_write(f, buf, size, resid)
+ struct open_file *f;
+ void *buf;
+ size_t size;
+ size_t *resid; /* out */
+{
+ return (EROFS);
+}
+
+off_t
+nfs_seek(f, offset, where)
+ struct open_file *f;
+ off_t offset;
+ int where;
+{
+ register struct nfs_iodesc *d = (struct nfs_iodesc *)f->f_fsdata;
+ n_long size = ntohl(d->fa.fa_size);
+
+ switch (where) {
+ case SEEK_SET:
+ d->off = offset;
+ break;
+ case SEEK_CUR:
+ d->off += offset;
+ break;
+ case SEEK_END:
+ d->off = size - offset;
+ break;
+ default:
+ return (-1);
+ }
+
+ return (d->off);
+}
+
+/* NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5 */
+int nfs_stat_types[8] = {
+ 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, 0 };
+
+int
+nfs_stat(f, sb)
+ struct open_file *f;
+ struct stat *sb;
+{
+ struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
+ register n_long ftype, mode;
+
+ ftype = ntohl(fp->fa.fa_type);
+ mode = ntohl(fp->fa.fa_mode);
+ mode |= nfs_stat_types[ftype & 7];
+
+ sb->st_mode = mode;
+ sb->st_nlink = ntohl(fp->fa.fa_nlink);
+ sb->st_uid = ntohl(fp->fa.fa_uid);
+ sb->st_gid = ntohl(fp->fa.fa_gid);
+ sb->st_size = ntohl(fp->fa.fa_size);
+
+ return (0);
+}
diff --git a/lib/libstand/nfsv2.h b/lib/libstand/nfsv2.h
new file mode 100644
index 0000000..1d7d9d4
--- /dev/null
+++ b/lib/libstand/nfsv2.h
@@ -0,0 +1,166 @@
+/* $NetBSD: nfsv2.h,v 1.2 1996/02/26 23:05:23 gwr Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)nfsv2.h 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * nfs definitions as per the version 2 specs
+ */
+
+/*
+ * Constants as defined in the Sun NFS Version 2 spec.
+ * "NFS: Network File System Protocol Specification" RFC1094
+ */
+
+#define NFS_PORT 2049
+#define NFS_PROG 100003
+#define NFS_VER2 2
+#define NFS_MAXDGRAMDATA 8192
+#define NFS_MAXDATA 32768
+#define NFS_MAXPATHLEN 1024
+#define NFS_MAXNAMLEN 255
+#define NFS_FHSIZE 32
+#define NFS_MAXPKTHDR 404
+#define NFS_MAXPACKET (NFS_MAXPKTHDR+NFS_MAXDATA)
+#define NFS_MINPACKET 20
+#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */
+
+/* Stat numbers for rpc returns */
+#define NFS_OK 0
+#define NFSERR_PERM 1
+#define NFSERR_NOENT 2
+#define NFSERR_IO 5
+#define NFSERR_NXIO 6
+#define NFSERR_ACCES 13
+#define NFSERR_EXIST 17
+#define NFSERR_NODEV 19
+#define NFSERR_NOTDIR 20
+#define NFSERR_ISDIR 21
+#define NFSERR_FBIG 27
+#define NFSERR_NOSPC 28
+#define NFSERR_ROFS 30
+#define NFSERR_NAMETOL 63
+#define NFSERR_NOTEMPTY 66
+#define NFSERR_DQUOT 69
+#define NFSERR_STALE 70
+#define NFSERR_WFLUSH 99
+
+/* Sizes in bytes of various nfs rpc components */
+#define NFSX_FH 32
+#define NFSX_UNSIGNED 4
+#define NFSX_FATTR 68
+#define NFSX_SATTR 32
+#define NFSX_STATFS 20
+#define NFSX_COOKIE 4
+
+/* nfs rpc procedure numbers */
+#define NFSPROC_NULL 0
+#define NFSPROC_GETATTR 1
+#define NFSPROC_SETATTR 2
+#define NFSPROC_NOOP 3
+#define NFSPROC_ROOT NFSPROC_NOOP /* Obsolete */
+#define NFSPROC_LOOKUP 4
+#define NFSPROC_READLINK 5
+#define NFSPROC_READ 6
+#define NFSPROC_WRITECACHE NFSPROC_NOOP /* Obsolete */
+#define NFSPROC_WRITE 8
+#define NFSPROC_CREATE 9
+#define NFSPROC_REMOVE 10
+#define NFSPROC_RENAME 11
+#define NFSPROC_LINK 12
+#define NFSPROC_SYMLINK 13
+#define NFSPROC_MKDIR 14
+#define NFSPROC_RMDIR 15
+#define NFSPROC_READDIR 16
+#define NFSPROC_STATFS 17
+
+#define NFS_NPROCS 18
+
+
+/* File types */
+typedef enum {
+ NFNON=0,
+ NFREG=1,
+ NFDIR=2,
+ NFBLK=3,
+ NFCHR=4,
+ NFLNK=5
+} nfstype;
+
+/* Structs for common parts of the rpc's */
+struct nfsv2_time {
+ n_long nfs_sec;
+ n_long nfs_usec;
+};
+
+/*
+ * File attributes and setable attributes.
+ */
+struct nfsv2_fattr {
+ n_long fa_type;
+ n_long fa_mode;
+ n_long fa_nlink;
+ n_long fa_uid;
+ n_long fa_gid;
+ n_long fa_size;
+ n_long fa_blocksize;
+ n_long fa_rdev;
+ n_long fa_blocks;
+ n_long fa_fsid;
+ n_long fa_fileid;
+ struct nfsv2_time fa_atime;
+ struct nfsv2_time fa_mtime;
+ struct nfsv2_time fa_ctime;
+};
+
+struct nfsv2_sattr {
+ n_long sa_mode;
+ n_long sa_uid;
+ n_long sa_gid;
+ n_long sa_size;
+ struct nfsv2_time sa_atime;
+ struct nfsv2_time sa_mtime;
+};
+
+struct nfsv2_statfs {
+ n_long sf_tsize;
+ n_long sf_bsize;
+ n_long sf_blocks;
+ n_long sf_bfree;
+ n_long sf_bavail;
+};
diff --git a/lib/libstand/nullfs.c b/lib/libstand/nullfs.c
new file mode 100644
index 0000000..4a1e6e4
--- /dev/null
+++ b/lib/libstand/nullfs.c
@@ -0,0 +1,105 @@
+/* $NetBSD: nullfs.c,v 1.1 1996/01/13 22:25:39 leo Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)open.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "stand.h"
+
+/*
+ * Null filesystem
+ */
+int null_open (const char *path, struct open_file *f)
+{
+ errno = EIO;
+ return -1;
+}
+
+int null_close(struct open_file *f)
+{
+ return 0;
+}
+
+ssize_t null_read (struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ errno = EIO;
+ return -1;
+}
+
+ssize_t null_write (struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ errno = EIO;
+ return -1;
+}
+
+off_t null_seek (struct open_file *f, off_t offset, int where)
+{
+ errno = EIO;
+ return -1;
+}
+
+int null_stat (struct open_file *f, struct stat *sb)
+{
+ errno = EIO;
+ return -1;
+}
diff --git a/lib/libstand/open.c b/lib/libstand/open.c
new file mode 100644
index 0000000..3a9127c
--- /dev/null
+++ b/lib/libstand/open.c
@@ -0,0 +1,137 @@
+/* $NetBSD: open.c,v 1.16 1997/01/28 09:41:03 pk Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)open.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "stand.h"
+
+struct open_file files[SOPEN_MAX];
+
+static int
+o_gethandle(void)
+{
+ int fd;
+
+ for (fd = 0; fd < SOPEN_MAX; fd++)
+ if (files[fd].f_flags == 0)
+ return(fd);
+ return(-1);
+}
+
+
+int
+open(const char *fname, int mode)
+{
+ struct open_file *f;
+ int fd, i, error, besterror;
+ const char *file;
+
+ if ((fd = o_gethandle()) == -1) {
+ errno = EMFILE;
+ return(-1);
+ }
+
+ f = &files[fd];
+ f->f_flags = mode + 1;
+ f->f_dev = (struct devsw *)0;
+ f->f_ops = (struct fs_ops *)0;
+ f->f_offset = 0;
+ f->f_devdata = NULL;
+ file = (char *)0;
+ error = devopen(f, fname, &file);
+ if (error ||
+ (((f->f_flags & F_NODEV) == 0) && f->f_dev == (struct devsw *)0))
+ goto err;
+
+ /* see if we opened a raw device; otherwise, 'file' is the file name. */
+ if (file == (char *)0 || *file == '\0') {
+ f->f_flags |= F_RAW;
+ return (fd);
+ }
+
+ /* pass file name to the different filesystem open routines */
+ besterror = ENOENT;
+ for (i = 0; file_system[i] != NULL; i++) {
+
+ error = ((*file_system[i]).fo_open)(file, f);
+ if (error == 0) {
+
+ f->f_ops = file_system[i];
+ return (fd);
+ }
+ if (error != EINVAL)
+ besterror = error;
+ }
+ error = besterror;
+
+ if ((f->f_flags & F_NODEV) == 0)
+ f->f_dev->dv_close(f);
+ if (error)
+ devclose(f);
+
+ err:
+ f->f_flags = 0;
+ errno = error;
+ return (-1);
+}
diff --git a/lib/libstand/pager.c b/lib/libstand/pager.c
new file mode 100644
index 0000000..387fdc3
--- /dev/null
+++ b/lib/libstand/pager.c
@@ -0,0 +1,160 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/*
+ * Simple paged-output and paged-viewing functions
+ */
+
+#include "stand.h"
+#include <string.h>
+
+static int p_maxlines = -1;
+static int p_freelines;
+
+static char *pager_prompt1 = " --more-- <space> page down <enter> line down <q> quit ";
+static char *pager_blank = " ";
+
+/*
+ * 'open' the pager
+ */
+void
+pager_open(void)
+{
+ int nlines;
+ char *cp, *lp;
+
+ nlines = 24; /* sensible default */
+ if ((cp = getenv("LINES")) != NULL) {
+ nlines = strtol(cp, &lp, 0);
+ }
+
+ p_maxlines = nlines - 1;
+ if (p_maxlines < 1)
+ p_maxlines = 1;
+ p_freelines = p_maxlines;
+}
+
+/*
+ * 'close' the pager
+ */
+void
+pager_close(void)
+{
+ p_maxlines = -1;
+}
+
+/*
+ * Emit lines to the pager; may not return until the user
+ * has responded to the prompt.
+ *
+ * Will return nonzero if the user enters 'q' or 'Q' at the prompt.
+ *
+ * XXX note that this watches outgoing newlines (and eats them), but
+ * does not handle wrap detection (req. count of columns).
+ */
+
+int
+pager_output(const char *cp)
+{
+ int action;
+
+ if (cp == NULL)
+ return(0);
+
+ for (;;) {
+ if (*cp == 0)
+ return(0);
+
+ putchar(*cp); /* always emit character */
+
+ if (*(cp++) == '\n') { /* got a newline? */
+ p_freelines--;
+ if (p_freelines <= 0) {
+ printf(pager_prompt1);
+ action = 0;
+ while (action == 0) {
+ switch(getchar()) {
+ case '\r':
+ case '\n':
+ p_freelines = 1;
+ action = 1;
+ break;
+ case ' ':
+ p_freelines = p_maxlines;
+ action = 1;
+ break;
+ case 'q':
+ case 'Q':
+ action = 2;
+ break;
+ default:
+ break;
+ }
+ }
+ printf("\r%s\r", pager_blank);
+ if (action == 2)
+ return(1);
+ }
+ }
+ }
+}
+
+/*
+ * Display from (fd).
+ */
+int
+pager_file(const char *fname)
+{
+ char buf[80];
+ size_t hmuch;
+ int fd;
+ int result;
+
+ if ((fd = open(fname, O_RDONLY)) == -1) {
+ printf("can't open '%s': %s\n", fname, strerror(errno));
+ return(-1);
+ }
+
+ for (;;) {
+ hmuch = read(fd, buf, sizeof(buf) - 1);
+ if (hmuch == -1) {
+ result = -1;
+ break;
+ }
+ if (hmuch == 0) {
+ result = 0;
+ break;
+ }
+ buf[hmuch] = 0;
+ if (pager_output(buf)) {
+ result = 1;
+ break;
+ }
+ }
+ close(fd);
+ return(result);
+}
diff --git a/lib/libstand/printf.c b/lib/libstand/printf.c
new file mode 100644
index 0000000..3e16b6f
--- /dev/null
+++ b/lib/libstand/printf.c
@@ -0,0 +1,361 @@
+/*-
+ * Copyright (c) 1986, 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+
+/*
+ * Standaloneified version of the FreeBSD kernel printf family.
+ */
+
+#include <sys/types.h>
+#include "stand.h"
+
+/*
+ * Note that stdarg.h and the ANSI style va_start macro is used for both
+ * ANSI and traditional C compilers.
+ */
+#include <machine/stdarg.h>
+
+static char *ksprintn (u_long num, int base, int *len);
+static int kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap);
+
+int
+printf(const char *fmt, ...)
+{
+ va_list ap;
+ int retval;
+
+ va_start(ap, fmt);
+ retval = kvprintf(fmt, putchar, NULL, 10, ap);
+ va_end(ap);
+ return retval;
+}
+
+void
+vprintf(const char *fmt, va_list ap)
+{
+
+ kvprintf(fmt, putchar, NULL, 10, ap);
+}
+
+int
+sprintf(char *buf, const char *cfmt, ...)
+{
+ int retval;
+ va_list ap;
+
+ va_start(ap, cfmt);
+ retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
+ buf[retval] = '\0';
+ va_end(ap);
+ return retval;
+}
+
+void
+vsprintf(char *buf, const char *cfmt, va_list ap)
+{
+ int retval;
+
+ retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
+ buf[retval] = '\0';
+}
+
+/*
+ * Put a number (base <= 16) in a buffer in reverse order; return an
+ * optional length and a pointer to the NULL terminated (preceded?)
+ * buffer.
+ */
+static char *
+ksprintn(ul, base, lenp)
+ register u_long ul;
+ register int base, *lenp;
+{ /* A long in base 8, plus NULL. */
+ static char buf[sizeof(long) * NBBY / 3 + 2];
+ register char *p;
+
+ p = buf;
+ do {
+ *++p = hex2ascii(ul % base);
+ } while (ul /= base);
+ if (lenp)
+ *lenp = p - buf;
+ return (p);
+}
+
+/*
+ * Scaled down version of printf(3).
+ *
+ * Two additional formats:
+ *
+ * The format %b is supported to decode error registers.
+ * Its usage is:
+ *
+ * printf("reg=%b\n", regval, "<base><arg>*");
+ *
+ * where <base> is the output base expressed as a control character, e.g.
+ * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
+ * the first of which gives the bit number to be inspected (origin 1), and
+ * the next characters (up to a control character, i.e. a character <= 32),
+ * give the name of the register. Thus:
+ *
+ * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
+ *
+ * would produce output:
+ *
+ * reg=3<BITTWO,BITONE>
+ *
+ * XXX: %D -- Hexdump, takes pointer and separator string:
+ * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
+ * ("%*D", len, ptr, " " -> XX XX XX XX ...
+ */
+static int
+kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap)
+{
+#define PCHAR(c) {int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; }
+ char *p, *q, *d;
+ u_char *up;
+ int ch, n;
+ u_long ul;
+ int base, lflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
+ int dwidth;
+ char padc;
+ int retval = 0;
+
+ if (!func)
+ d = (char *) arg;
+ else
+ d = NULL;
+
+ if (fmt == NULL)
+ fmt = "(fmt null)\n";
+
+ if (radix < 2 || radix > 36)
+ radix = 10;
+
+ for (;;) {
+ padc = ' ';
+ width = 0;
+ while ((ch = (u_char)*fmt++) != '%') {
+ if (ch == '\0')
+ return retval;
+ PCHAR(ch);
+ }
+ lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
+ sign = 0; dot = 0; dwidth = 0;
+reswitch: switch (ch = (u_char)*fmt++) {
+ case '.':
+ dot = 1;
+ goto reswitch;
+ case '#':
+ sharpflag = 1;
+ goto reswitch;
+ case '+':
+ sign = 1;
+ goto reswitch;
+ case '-':
+ ladjust = 1;
+ goto reswitch;
+ case '%':
+ PCHAR(ch);
+ break;
+ case '*':
+ if (!dot) {
+ width = va_arg(ap, int);
+ if (width < 0) {
+ ladjust = !ladjust;
+ width = -width;
+ }
+ } else {
+ dwidth = va_arg(ap, int);
+ }
+ goto reswitch;
+ case '0':
+ if (!dot) {
+ padc = '0';
+ goto reswitch;
+ }
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ for (n = 0;; ++fmt) {
+ n = n * 10 + ch - '0';
+ ch = *fmt;
+ if (ch < '0' || ch > '9')
+ break;
+ }
+ if (dot)
+ dwidth = n;
+ else
+ width = n;
+ goto reswitch;
+ case 'b':
+ ul = va_arg(ap, int);
+ p = va_arg(ap, char *);
+ for (q = ksprintn(ul, *p++, NULL); *q;)
+ PCHAR(*q--);
+
+ if (!ul)
+ break;
+
+ for (tmp = 0; *p;) {
+ n = *p++;
+ if (ul & (1 << (n - 1))) {
+ PCHAR(tmp ? ',' : '<');
+ for (; (n = *p) > ' '; ++p)
+ PCHAR(n);
+ tmp = 1;
+ } else
+ for (; *p > ' '; ++p)
+ continue;
+ }
+ if (tmp)
+ PCHAR('>');
+ break;
+ case 'c':
+ PCHAR(va_arg(ap, int));
+ break;
+ case 'D':
+ up = va_arg(ap, u_char *);
+ p = va_arg(ap, char *);
+ if (!width)
+ width = 16;
+ while(width--) {
+ PCHAR(hex2ascii(*up >> 4));
+ PCHAR(hex2ascii(*up & 0x0f));
+ up++;
+ if (width)
+ for (q=p;*q;q++)
+ PCHAR(*q);
+ }
+ break;
+ case 'd':
+ ul = lflag ? va_arg(ap, long) : va_arg(ap, int);
+ sign = 1;
+ base = 10;
+ goto number;
+ case 'l':
+ lflag = 1;
+ goto reswitch;
+ case 'n':
+ ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
+ base = radix;
+ goto number;
+ case 'o':
+ ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
+ base = 8;
+ goto number;
+ case 'p':
+ ul = (u_long)va_arg(ap, void *);
+ base = 16;
+ sharpflag = 1;
+ goto number;
+ case 's':
+ p = va_arg(ap, char *);
+ if (p == NULL)
+ p = "(null)";
+ if (!dot)
+ n = strlen (p);
+ else
+ for (n = 0; n < dwidth && p[n]; n++)
+ continue;
+
+ width -= n;
+
+ if (!ladjust && width > 0)
+ while (width--)
+ PCHAR(padc);
+ while (n--)
+ PCHAR(*p++);
+ if (ladjust && width > 0)
+ while (width--)
+ PCHAR(padc);
+ break;
+ case 'u':
+ ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
+ base = 10;
+ goto number;
+ case 'x':
+ ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
+ base = 16;
+number: if (sign && (long)ul < 0L) {
+ neg = 1;
+ ul = -(long)ul;
+ }
+ p = ksprintn(ul, base, &tmp);
+ if (sharpflag && ul != 0) {
+ if (base == 8)
+ tmp++;
+ else if (base == 16)
+ tmp += 2;
+ }
+ if (neg)
+ tmp++;
+
+ if (!ladjust && width && (width -= tmp) > 0)
+ while (width--)
+ PCHAR(padc);
+ if (neg)
+ PCHAR('-');
+ if (sharpflag && ul != 0) {
+ if (base == 8) {
+ PCHAR('0');
+ } else if (base == 16) {
+ PCHAR('0');
+ PCHAR('x');
+ }
+ }
+
+ while (*p)
+ PCHAR(*p--);
+
+ if (ladjust && width && (width -= tmp) > 0)
+ while (width--)
+ PCHAR(padc);
+
+ break;
+ default:
+ PCHAR('%');
+ if (lflag)
+ PCHAR('l');
+ PCHAR(ch);
+ break;
+ }
+ }
+#undef PCHAR
+}
+
diff --git a/lib/libstand/qdivrem.c b/lib/libstand/qdivrem.c
new file mode 100644
index 0000000..a8231f0
--- /dev/null
+++ b/lib/libstand/qdivrem.c
@@ -0,0 +1,303 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ * From: Id: qdivrem.c,v 1.7 1997/11/07 09:20:40 phk Exp
+ */
+
+/*
+ * Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed),
+ * section 4.3.1, pp. 257--259.
+ */
+
+#include "quad.h"
+
+#define B (1 << HALF_BITS) /* digit base */
+
+/* Combine two `digits' to make a single two-digit number. */
+#define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b))
+
+/* select a type for digits in base B: use unsigned short if they fit */
+#if ULONG_MAX == 0xffffffff && USHRT_MAX >= 0xffff
+typedef unsigned short digit;
+#else
+typedef u_long digit;
+#endif
+
+/*
+ * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
+ * `fall out' the left (there never will be any such anyway).
+ * We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS.
+ */
+static void
+shl(register digit *p, register int len, register int sh)
+{
+ register int i;
+
+ for (i = 0; i < len; i++)
+ p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh));
+ p[i] = LHALF(p[i] << sh);
+}
+
+/*
+ * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
+ *
+ * We do this in base 2-sup-HALF_BITS, so that all intermediate products
+ * fit within u_long. As a consequence, the maximum length dividend and
+ * divisor are 4 `digits' in this base (they are shorter if they have
+ * leading zeros).
+ */
+u_quad_t
+__qdivrem(uq, vq, arq)
+ u_quad_t uq, vq, *arq;
+{
+ union uu tmp;
+ digit *u, *v, *q;
+ register digit v1, v2;
+ u_long qhat, rhat, t;
+ int m, n, d, j, i;
+ digit uspace[5], vspace[5], qspace[5];
+
+ /*
+ * Take care of special cases: divide by zero, and u < v.
+ */
+ if (vq == 0) {
+ /* divide by zero. */
+ static volatile const unsigned int zero = 0;
+
+ tmp.ul[H] = tmp.ul[L] = 1 / zero;
+ if (arq)
+ *arq = uq;
+ return (tmp.q);
+ }
+ if (uq < vq) {
+ if (arq)
+ *arq = uq;
+ return (0);
+ }
+ u = &uspace[0];
+ v = &vspace[0];
+ q = &qspace[0];
+
+ /*
+ * Break dividend and divisor into digits in base B, then
+ * count leading zeros to determine m and n. When done, we
+ * will have:
+ * u = (u[1]u[2]...u[m+n]) sub B
+ * v = (v[1]v[2]...v[n]) sub B
+ * v[1] != 0
+ * 1 < n <= 4 (if n = 1, we use a different division algorithm)
+ * m >= 0 (otherwise u < v, which we already checked)
+ * m + n = 4
+ * and thus
+ * m = 4 - n <= 2
+ */
+ tmp.uq = uq;
+ u[0] = 0;
+ u[1] = HHALF(tmp.ul[H]);
+ u[2] = LHALF(tmp.ul[H]);
+ u[3] = HHALF(tmp.ul[L]);
+ u[4] = LHALF(tmp.ul[L]);
+ tmp.uq = vq;
+ v[1] = HHALF(tmp.ul[H]);
+ v[2] = LHALF(tmp.ul[H]);
+ v[3] = HHALF(tmp.ul[L]);
+ v[4] = LHALF(tmp.ul[L]);
+ for (n = 4; v[1] == 0; v++) {
+ if (--n == 1) {
+ u_long rbj; /* r*B+u[j] (not root boy jim) */
+ digit q1, q2, q3, q4;
+
+ /*
+ * Change of plan, per exercise 16.
+ * r = 0;
+ * for j = 1..4:
+ * q[j] = floor((r*B + u[j]) / v),
+ * r = (r*B + u[j]) % v;
+ * We unroll this completely here.
+ */
+ t = v[2]; /* nonzero, by definition */
+ q1 = u[1] / t;
+ rbj = COMBINE(u[1] % t, u[2]);
+ q2 = rbj / t;
+ rbj = COMBINE(rbj % t, u[3]);
+ q3 = rbj / t;
+ rbj = COMBINE(rbj % t, u[4]);
+ q4 = rbj / t;
+ if (arq)
+ *arq = rbj % t;
+ tmp.ul[H] = COMBINE(q1, q2);
+ tmp.ul[L] = COMBINE(q3, q4);
+ return (tmp.q);
+ }
+ }
+
+ /*
+ * By adjusting q once we determine m, we can guarantee that
+ * there is a complete four-digit quotient at &qspace[1] when
+ * we finally stop.
+ */
+ for (m = 4 - n; u[1] == 0; u++)
+ m--;
+ for (i = 4 - m; --i >= 0;)
+ q[i] = 0;
+ q += 4 - m;
+
+ /*
+ * Here we run Program D, translated from MIX to C and acquiring
+ * a few minor changes.
+ *
+ * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
+ */
+ d = 0;
+ for (t = v[1]; t < B / 2; t <<= 1)
+ d++;
+ if (d > 0) {
+ shl(&u[0], m + n, d); /* u <<= d */
+ shl(&v[1], n - 1, d); /* v <<= d */
+ }
+ /*
+ * D2: j = 0.
+ */
+ j = 0;
+ v1 = v[1]; /* for D3 -- note that v[1..n] are constant */
+ v2 = v[2]; /* for D3 */
+ do {
+ register digit uj0, uj1, uj2;
+
+ /*
+ * D3: Calculate qhat (\^q, in TeX notation).
+ * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
+ * let rhat = (u[j]*B + u[j+1]) mod v[1].
+ * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
+ * decrement qhat and increase rhat correspondingly.
+ * Note that if rhat >= B, v[2]*qhat < rhat*B.
+ */
+ uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */
+ uj1 = u[j + 1]; /* for D3 only */
+ uj2 = u[j + 2]; /* for D3 only */
+ if (uj0 == v1) {
+ qhat = B;
+ rhat = uj1;
+ goto qhat_too_big;
+ } else {
+ u_long nn = COMBINE(uj0, uj1);
+ qhat = nn / v1;
+ rhat = nn % v1;
+ }
+ while (v2 * qhat > COMBINE(rhat, uj2)) {
+ qhat_too_big:
+ qhat--;
+ if ((rhat += v1) >= B)
+ break;
+ }
+ /*
+ * D4: Multiply and subtract.
+ * The variable `t' holds any borrows across the loop.
+ * We split this up so that we do not require v[0] = 0,
+ * and to eliminate a final special case.
+ */
+ for (t = 0, i = n; i > 0; i--) {
+ t = u[i + j] - v[i] * qhat - t;
+ u[i + j] = LHALF(t);
+ t = (B - HHALF(t)) & (B - 1);
+ }
+ t = u[j] - t;
+ u[j] = LHALF(t);
+ /*
+ * D5: test remainder.
+ * There is a borrow if and only if HHALF(t) is nonzero;
+ * in that (rare) case, qhat was too large (by exactly 1).
+ * Fix it by adding v[1..n] to u[j..j+n].
+ */
+ if (HHALF(t)) {
+ qhat--;
+ for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
+ t += u[i + j] + v[i];
+ u[i + j] = LHALF(t);
+ t = HHALF(t);
+ }
+ u[j] = LHALF(u[j] + t);
+ }
+ q[j] = qhat;
+ } while (++j <= m); /* D7: loop on j. */
+
+ /*
+ * If caller wants the remainder, we have to calculate it as
+ * u[m..m+n] >> d (this is at most n digits and thus fits in
+ * u[m+1..m+n], but we may need more source digits).
+ */
+ if (arq) {
+ if (d) {
+ for (i = m + n; i > m; --i)
+ u[i] = (u[i] >> d) |
+ LHALF(u[i - 1] << (HALF_BITS - d));
+ u[i] = 0;
+ }
+ tmp.ul[H] = COMBINE(uspace[1], uspace[2]);
+ tmp.ul[L] = COMBINE(uspace[3], uspace[4]);
+ *arq = tmp.q;
+ }
+
+ tmp.ul[H] = COMBINE(qspace[1], qspace[2]);
+ tmp.ul[L] = COMBINE(qspace[3], qspace[4]);
+ return (tmp.q);
+}
+
+/*
+ * Divide two unsigned quads.
+ */
+
+u_quad_t
+__udivdi3(a, b)
+ u_quad_t a, b;
+{
+
+ return (__qdivrem(a, b, (u_quad_t *)0));
+}
+
+/*
+ * Return remainder after dividing two unsigned quads.
+ */
+u_quad_t
+__umoddi3(a, b)
+ u_quad_t a, b;
+{
+ u_quad_t r;
+
+ (void)__qdivrem(a, b, &r);
+ return (r);
+}
diff --git a/lib/libstand/quad.h b/lib/libstand/quad.h
new file mode 100644
index 0000000..14f5754
--- /dev/null
+++ b/lib/libstand/quad.h
@@ -0,0 +1,116 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)quad.h 8.1 (Berkeley) 6/4/93
+ * $FreeBSD$
+ */
+
+/*
+ * Quad arithmetic.
+ *
+ * This library makes the following assumptions:
+ *
+ * - The type long long (aka quad_t) exists.
+ *
+ * - A quad variable is exactly twice as long as `long'.
+ *
+ * - The machine's arithmetic is two's complement.
+ *
+ * This library can provide 128-bit arithmetic on a machine with 128-bit
+ * quads and 64-bit longs, for instance, or 96-bit arithmetic on machines
+ * with 48-bit longs.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <limits.h>
+
+/*
+ * Depending on the desired operation, we view a `long long' (aka quad_t) in
+ * one or more of the following formats.
+ */
+union uu {
+ quad_t q; /* as a (signed) quad */
+ quad_t uq; /* as an unsigned quad */
+ long sl[2]; /* as two signed longs */
+ u_long ul[2]; /* as two unsigned longs */
+};
+
+/*
+ * Define high and low longwords.
+ */
+#define H _QUAD_HIGHWORD
+#define L _QUAD_LOWWORD
+
+/*
+ * Total number of bits in a quad_t and in the pieces that make it up.
+ * These are used for shifting, and also below for halfword extraction
+ * and assembly.
+ */
+#define QUAD_BITS (sizeof(quad_t) * CHAR_BIT)
+#define LONG_BITS (sizeof(long) * CHAR_BIT)
+#define HALF_BITS (sizeof(long) * CHAR_BIT / 2)
+
+/*
+ * Extract high and low shortwords from longword, and move low shortword of
+ * longword to upper half of long, i.e., produce the upper longword of
+ * ((quad_t)(x) << (number_of_bits_in_long/2)). (`x' must actually be u_long.)
+ *
+ * These are used in the multiply code, to split a longword into upper
+ * and lower halves, and to reassemble a product as a quad_t, shifted left
+ * (sizeof(long)*CHAR_BIT/2).
+ */
+#define HHALF(x) ((x) >> HALF_BITS)
+#define LHALF(x) ((x) & ((1 << HALF_BITS) - 1))
+#define LHUP(x) ((x) << HALF_BITS)
+
+quad_t __divdi3 __P((quad_t a, quad_t b));
+quad_t __moddi3 __P((quad_t a, quad_t b));
+u_quad_t __qdivrem __P((u_quad_t u, u_quad_t v, u_quad_t *rem));
+u_quad_t __udivdi3 __P((u_quad_t a, u_quad_t b));
+u_quad_t __umoddi3 __P((u_quad_t a, u_quad_t b));
+
+/*
+ * XXX
+ * Compensate for gcc 1 vs gcc 2. Gcc 1 defines ?sh?di3's second argument
+ * as u_quad_t, while gcc 2 correctly uses int. Unfortunately, we still use
+ * both compilers.
+ */
+#if __GNUC__ >= 2
+typedef unsigned int qshift_t;
+#else
+typedef u_quad_t qshift_t;
+#endif
diff --git a/lib/libstand/random.c b/lib/libstand/random.c
new file mode 100644
index 0000000..35ddea1
--- /dev/null
+++ b/lib/libstand/random.c
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)random.c 8.1 (Berkeley) 6/10/93
+ * $FreeBSD$
+ */
+
+#include <sys/libkern.h>
+
+static u_long randseed = 1;
+
+void
+srandom(seed)
+ u_long seed;
+{
+ randseed = seed;
+}
+
+/*
+ * Pseudo-random number generator for randomizing the profiling clock,
+ * and whatever else we might use it for. The result is uniform on
+ * [0, 2^31 - 1].
+ */
+u_long
+random()
+{
+ register long x, hi, lo, t;
+
+ /*
+ * Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1).
+ * From "Random number generators: good ones are hard to find",
+ * Park and Miller, Communications of the ACM, vol. 31, no. 10,
+ * October 1988, p. 1195.
+ */
+ x = randseed;
+ hi = x / 127773;
+ lo = x % 127773;
+ t = 16807 * lo - 2836 * hi;
+ if (t <= 0)
+ t += 0x7fffffff;
+ randseed = t;
+ return (t);
+}
diff --git a/lib/libstand/rarp.c b/lib/libstand/rarp.c
new file mode 100644
index 0000000..898e475
--- /dev/null
+++ b/lib/libstand/rarp.c
@@ -0,0 +1,225 @@
+/* $NetBSD: rarp.c,v 1.16 1997/07/07 15:52:52 drochner Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Header: arp.c,v 1.5 93/07/15 05:52:26 leres Exp (LBL)
+ */
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <netinet/in_systm.h>
+
+#include <string.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+
+
+static ssize_t rarpsend(struct iodesc *, void *, size_t);
+static ssize_t rarprecv(struct iodesc *, void *, size_t, time_t);
+
+/*
+ * Ethernet (Reverse) Address Resolution Protocol (see RFC 903, and 826).
+ */
+int
+rarp_getipaddress(sock)
+ int sock;
+{
+ struct iodesc *d;
+ register struct ether_arp *ap;
+ struct {
+ u_char header[ETHER_SIZE];
+ struct {
+ struct ether_arp arp;
+ u_char pad[18]; /* 60 - sizeof(arp) */
+ } data;
+ } wbuf;
+ struct {
+ u_char header[ETHER_SIZE];
+ struct {
+ struct ether_arp arp;
+ u_char pad[24]; /* extra space */
+ } data;
+ } rbuf;
+
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("rarp: socket=%d\n", sock);
+#endif
+ if (!(d = socktodesc(sock))) {
+ printf("rarp: bad socket. %d\n", sock);
+ return (-1);
+ }
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("rarp: d=%x\n", (u_int)d);
+#endif
+
+ bzero((char*)&wbuf.data, sizeof(wbuf.data));
+ ap = &wbuf.data.arp;
+ ap->arp_hrd = htons(ARPHRD_ETHER);
+ ap->arp_pro = htons(ETHERTYPE_IP);
+ ap->arp_hln = sizeof(ap->arp_sha); /* hardware address length */
+ ap->arp_pln = sizeof(ap->arp_spa); /* protocol address length */
+ ap->arp_op = htons(ARPOP_REVREQUEST);
+ bcopy(d->myea, ap->arp_sha, 6);
+ bcopy(d->myea, ap->arp_tha, 6);
+
+ if (sendrecv(d,
+ rarpsend, &wbuf.data, sizeof(wbuf.data),
+ rarprecv, &rbuf.data, sizeof(rbuf.data)) < 0)
+ {
+ printf("No response for RARP request\n");
+ return (-1);
+ }
+
+ ap = &rbuf.data.arp;
+ bcopy(ap->arp_tpa, (char *)&myip, sizeof(myip));
+#if 0
+ /* XXX - Can NOT assume this is our root server! */
+ bcopy(ap->arp_spa, (char *)&rootip, sizeof(rootip));
+#endif
+
+ /* Compute our "natural" netmask. */
+ if (IN_CLASSA(myip.s_addr))
+ netmask = IN_CLASSA_NET;
+ else if (IN_CLASSB(myip.s_addr))
+ netmask = IN_CLASSB_NET;
+ else
+ netmask = IN_CLASSC_NET;
+
+ d->myip = myip;
+ return (0);
+}
+
+/*
+ * Broadcast a RARP request (i.e. who knows who I am)
+ */
+static ssize_t
+rarpsend(d, pkt, len)
+ register struct iodesc *d;
+ register void *pkt;
+ register size_t len;
+{
+
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("rarpsend: called\n");
+#endif
+
+ return (sendether(d, pkt, len, bcea, ETHERTYPE_REVARP));
+}
+
+/*
+ * Returns 0 if this is the packet we're waiting for
+ * else -1 (and errno == 0)
+ */
+static ssize_t
+rarprecv(d, pkt, len, tleft)
+ register struct iodesc *d;
+ register void *pkt;
+ register size_t len;
+ time_t tleft;
+{
+ register ssize_t n;
+ register struct ether_arp *ap;
+ u_int16_t etype; /* host order */
+
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("rarprecv: ");
+#endif
+
+ n = readether(d, pkt, len, tleft, &etype);
+ errno = 0; /* XXX */
+ if (n == -1 || n < sizeof(struct ether_arp)) {
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("bad len=%d\n", n);
+#endif
+ return (-1);
+ }
+
+ if (etype != ETHERTYPE_REVARP) {
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("bad type=0x%x\n", etype);
+#endif
+ return (-1);
+ }
+
+ ap = (struct ether_arp *)pkt;
+ if (ap->arp_hrd != htons(ARPHRD_ETHER) ||
+ ap->arp_pro != htons(ETHERTYPE_IP) ||
+ ap->arp_hln != sizeof(ap->arp_sha) ||
+ ap->arp_pln != sizeof(ap->arp_spa) )
+ {
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("bad hrd/pro/hln/pln\n");
+#endif
+ return (-1);
+ }
+
+ if (ap->arp_op != htons(ARPOP_REVREPLY)) {
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("bad op=0x%x\n", ntohs(ap->arp_op));
+#endif
+ return (-1);
+ }
+
+ /* Is the reply for our Ethernet address? */
+ if (bcmp(ap->arp_tha, d->myea, 6)) {
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("unwanted address\n");
+#endif
+ return (-1);
+ }
+
+ /* We have our answer. */
+#ifdef RARP_DEBUG
+ if (debug)
+ printf("got it\n");
+#endif
+ return (n);
+}
diff --git a/lib/libstand/read.c b/lib/libstand/read.c
new file mode 100644
index 0000000..5b14a75
--- /dev/null
+++ b/lib/libstand/read.c
@@ -0,0 +1,96 @@
+/* $NetBSD: read.c,v 1.8 1997/01/22 00:38:12 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)read.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include "stand.h"
+
+ssize_t
+read(fd, dest, bcount)
+ int fd;
+ void *dest;
+ size_t bcount;
+{
+ register struct open_file *f = &files[fd];
+ size_t resid;
+
+ if ((unsigned)fd >= SOPEN_MAX || !(f->f_flags & F_READ)) {
+ errno = EBADF;
+ return (-1);
+ }
+ if (f->f_flags & F_RAW) {
+ twiddle();
+ errno = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ btodb(f->f_offset), bcount, dest, &resid);
+ if (errno)
+ return (-1);
+ f->f_offset += resid;
+ return (resid);
+ }
+ resid = bcount;
+ if ((errno = (f->f_ops->fo_read)(f, dest, bcount, &resid)))
+ return (-1);
+ return (ssize_t)(bcount - resid);
+}
diff --git a/lib/libstand/rpc.c b/lib/libstand/rpc.c
new file mode 100644
index 0000000..9f0fa32
--- /dev/null
+++ b/lib/libstand/rpc.c
@@ -0,0 +1,440 @@
+/* $NetBSD: rpc.c,v 1.18 1998/01/23 19:27:45 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Header: rpc.c,v 1.12 93/09/28 08:31:56 leres Exp (LBL)
+ */
+
+/*
+ * RPC functions used by NFS and bootparams.
+ * Note that bootparams requires the ability to find out the
+ * address of the server from which its response has come.
+ * This is supported by keeping the IP/UDP headers in the
+ * buffer space provided by the caller. (See rpc_fromaddr)
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <string.h>
+
+#include "rpcv2.h"
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+#include "rpc.h"
+
+struct auth_info {
+ int32_t authtype; /* auth type */
+ u_int32_t authlen; /* auth length */
+};
+
+struct auth_unix {
+ int32_t ua_time;
+ int32_t ua_hostname; /* null */
+ int32_t ua_uid;
+ int32_t ua_gid;
+ int32_t ua_gidlist; /* null */
+};
+
+struct rpc_call {
+ u_int32_t rp_xid; /* request transaction id */
+ int32_t rp_direction; /* call direction (0) */
+ u_int32_t rp_rpcvers; /* rpc version (2) */
+ u_int32_t rp_prog; /* program */
+ u_int32_t rp_vers; /* version */
+ u_int32_t rp_proc; /* procedure */
+};
+
+struct rpc_reply {
+ u_int32_t rp_xid; /* request transaction id */
+ int32_t rp_direction; /* call direction (1) */
+ int32_t rp_astatus; /* accept status (0: accepted) */
+ union {
+ u_int32_t rpu_errno;
+ struct {
+ struct auth_info rok_auth;
+ u_int32_t rok_status;
+ } rpu_rok;
+ } rp_u;
+};
+
+/* Local forwards */
+static ssize_t recvrpc(struct iodesc *, void *, size_t, time_t);
+static int rpc_getport(struct iodesc *, n_long, n_long);
+
+int rpc_xid;
+int rpc_port = 0x400; /* predecrement */
+
+/*
+ * Make a rpc call; return length of answer
+ * Note: Caller must leave room for headers.
+ */
+ssize_t
+rpc_call(d, prog, vers, proc, sdata, slen, rdata, rlen)
+ register struct iodesc *d;
+ register n_long prog, vers, proc;
+ register void *sdata;
+ register size_t slen;
+ register void *rdata;
+ register size_t rlen;
+{
+ register ssize_t cc;
+ struct auth_info *auth;
+ struct rpc_call *call;
+ struct rpc_reply *reply;
+ char *send_head, *send_tail;
+ char *recv_head, *recv_tail;
+ n_long x;
+ int port; /* host order */
+
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("rpc_call: prog=0x%x vers=%d proc=%d\n",
+ prog, vers, proc);
+#endif
+
+ port = rpc_getport(d, prog, vers);
+ if (port == -1)
+ return (-1);
+
+ d->destport = htons(port);
+
+ /*
+ * Prepend authorization stuff and headers.
+ * Note, must prepend things in reverse order.
+ */
+ send_head = sdata;
+ send_tail = (char *)sdata + slen;
+
+ /* Auth verifier is always auth_null */
+ send_head -= sizeof(*auth);
+ auth = (struct auth_info *)send_head;
+ auth->authtype = htonl(RPCAUTH_NULL);
+ auth->authlen = 0;
+
+#if 1
+ /* Auth credentials: always auth unix (as root) */
+ send_head -= sizeof(struct auth_unix);
+ bzero(send_head, sizeof(struct auth_unix));
+ send_head -= sizeof(*auth);
+ auth = (struct auth_info *)send_head;
+ auth->authtype = htonl(RPCAUTH_UNIX);
+ auth->authlen = htonl(sizeof(struct auth_unix));
+#else
+ /* Auth credentials: always auth_null (XXX OK?) */
+ send_head -= sizeof(*auth);
+ auth = send_head;
+ auth->authtype = htonl(RPCAUTH_NULL);
+ auth->authlen = 0;
+#endif
+
+ /* RPC call structure. */
+ send_head -= sizeof(*call);
+ call = (struct rpc_call *)send_head;
+ rpc_xid++;
+ call->rp_xid = htonl(rpc_xid);
+ call->rp_direction = htonl(RPC_CALL);
+ call->rp_rpcvers = htonl(RPC_VER2);
+ call->rp_prog = htonl(prog);
+ call->rp_vers = htonl(vers);
+ call->rp_proc = htonl(proc);
+
+ /* Make room for the rpc_reply header. */
+ recv_head = rdata;
+ recv_tail = (char *)rdata + rlen;
+ recv_head -= sizeof(*reply);
+
+ cc = sendrecv(d,
+ sendudp, send_head, send_tail - send_head,
+ recvrpc, recv_head, recv_tail - recv_head);
+
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("callrpc: cc=%ld rlen=%lu\n", (long)cc, (u_long)rlen);
+#endif
+ if (cc == -1)
+ return (-1);
+
+ if (cc <= sizeof(*reply)) {
+ errno = EBADRPC;
+ return (-1);
+ }
+
+ recv_tail = recv_head + cc;
+
+ /*
+ * Check the RPC reply status.
+ * The xid, dir, astatus were already checked.
+ */
+ reply = (struct rpc_reply *)recv_head;
+ auth = &reply->rp_u.rpu_rok.rok_auth;
+ x = ntohl(auth->authlen);
+ if (x != 0) {
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("callrpc: reply auth != NULL\n");
+#endif
+ errno = EBADRPC;
+ return(-1);
+ }
+ x = ntohl(reply->rp_u.rpu_rok.rok_status);
+ if (x != 0) {
+ printf("callrpc: error = %ld\n", (long)x);
+ errno = EBADRPC;
+ return(-1);
+ }
+ recv_head += sizeof(*reply);
+
+ return (ssize_t)(recv_tail - recv_head);
+}
+
+/*
+ * Returns true if packet is the one we're waiting for.
+ * This just checks the XID, direction, acceptance.
+ * Remaining checks are done by callrpc
+ */
+static ssize_t
+recvrpc(d, pkt, len, tleft)
+ register struct iodesc *d;
+ register void *pkt;
+ register size_t len;
+ time_t tleft;
+{
+ register struct rpc_reply *reply;
+ ssize_t n;
+ int x;
+
+ errno = 0;
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("recvrpc: called len=%lu\n", (u_long)len);
+#endif
+
+ n = readudp(d, pkt, len, tleft);
+ if (n <= (4 * 4))
+ return -1;
+
+ reply = (struct rpc_reply *)pkt;
+
+ x = ntohl(reply->rp_xid);
+ if (x != rpc_xid) {
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("recvrpc: rp_xid %d != xid %d\n", x, rpc_xid);
+#endif
+ return -1;
+ }
+
+ x = ntohl(reply->rp_direction);
+ if (x != RPC_REPLY) {
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("recvrpc: rp_direction %d != REPLY\n", x);
+#endif
+ return -1;
+ }
+
+ x = ntohl(reply->rp_astatus);
+ if (x != RPC_MSGACCEPTED) {
+ errno = ntohl(reply->rp_u.rpu_errno);
+ printf("recvrpc: reject, astat=%d, errno=%d\n", x, errno);
+ return -1;
+ }
+
+ /* Return data count (thus indicating success) */
+ return (n);
+}
+
+/*
+ * Given a pointer to a reply just received,
+ * dig out the IP address/port from the headers.
+ */
+void
+rpc_fromaddr(pkt, addr, port)
+ void *pkt;
+ struct in_addr *addr;
+ u_short *port;
+{
+ struct hackhdr {
+ /* Tail of IP header: just IP addresses */
+ n_long ip_src;
+ n_long ip_dst;
+ /* UDP header: */
+ u_int16_t uh_sport; /* source port */
+ u_int16_t uh_dport; /* destination port */
+ int16_t uh_ulen; /* udp length */
+ u_int16_t uh_sum; /* udp checksum */
+ /* RPC reply header: */
+ struct rpc_reply rpc;
+ } *hhdr;
+
+ hhdr = ((struct hackhdr *)pkt) - 1;
+ addr->s_addr = hhdr->ip_src;
+ *port = hhdr->uh_sport;
+}
+
+/*
+ * RPC Portmapper cache
+ */
+#define PMAP_NUM 8 /* need at most 5 pmap entries */
+
+int rpc_pmap_num;
+struct pmap_list {
+ struct in_addr addr; /* server, net order */
+ u_int prog; /* host order */
+ u_int vers; /* host order */
+ int port; /* host order */
+} rpc_pmap_list[PMAP_NUM];
+
+/* return port number in host order, or -1 */
+int
+rpc_pmap_getcache(addr, prog, vers)
+ struct in_addr addr; /* server, net order */
+ u_int prog; /* host order */
+ u_int vers; /* host order */
+{
+ struct pmap_list *pl;
+
+ for (pl = rpc_pmap_list; pl < &rpc_pmap_list[rpc_pmap_num]; pl++) {
+ if (pl->addr.s_addr == addr.s_addr &&
+ pl->prog == prog && pl->vers == vers )
+ {
+ return (pl->port);
+ }
+ }
+ return (-1);
+}
+
+void
+rpc_pmap_putcache(addr, prog, vers, port)
+ struct in_addr addr; /* server, net order */
+ u_int prog; /* host order */
+ u_int vers; /* host order */
+ int port; /* host order */
+{
+ struct pmap_list *pl;
+
+ /* Don't overflow cache... */
+ if (rpc_pmap_num >= PMAP_NUM) {
+ /* ... just re-use the last entry. */
+ rpc_pmap_num = PMAP_NUM - 1;
+#ifdef RPC_DEBUG
+ printf("rpc_pmap_putcache: cache overflow\n");
+#endif
+ }
+
+ pl = &rpc_pmap_list[rpc_pmap_num];
+ rpc_pmap_num++;
+
+ /* Cache answer */
+ pl->addr = addr;
+ pl->prog = prog;
+ pl->vers = vers;
+ pl->port = port;
+}
+
+
+/*
+ * Request a port number from the port mapper.
+ * Returns the port in host order.
+ */
+int
+rpc_getport(d, prog, vers)
+ register struct iodesc *d;
+ n_long prog; /* host order */
+ n_long vers; /* host order */
+{
+ struct args {
+ n_long prog; /* call program */
+ n_long vers; /* call version */
+ n_long proto; /* call protocol */
+ n_long port; /* call port (unused) */
+ } *args;
+ struct res {
+ n_long port;
+ } *res;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct args d;
+ } sdata;
+ struct {
+ n_long h[RPC_HEADER_WORDS];
+ struct res d;
+ n_long pad;
+ } rdata;
+ ssize_t cc;
+ int port;
+
+#ifdef RPC_DEBUG
+ if (debug)
+ printf("getport: prog=0x%x vers=%d\n", prog, vers);
+#endif
+
+ /* This one is fixed forever. */
+ if (prog == PMAPPROG)
+ return (PMAPPORT);
+
+ /* Try for cached answer first */
+ port = rpc_pmap_getcache(d->destip, prog, vers);
+ if (port != -1)
+ return (port);
+
+ args = &sdata.d;
+ args->prog = htonl(prog);
+ args->vers = htonl(vers);
+ args->proto = htonl(IPPROTO_UDP);
+ args->port = 0;
+ res = &rdata.d;
+
+ cc = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_GETPORT,
+ args, sizeof(*args), res, sizeof(*res));
+ if (cc < sizeof(*res)) {
+ printf("getport: %s", strerror(errno));
+ errno = EBADRPC;
+ return (-1);
+ }
+ port = (int)ntohl(res->port);
+
+ rpc_pmap_putcache(d->destip, prog, vers, port);
+
+ return (port);
+}
diff --git a/lib/libstand/rpc.h b/lib/libstand/rpc.h
new file mode 100644
index 0000000..1b6c60d
--- /dev/null
+++ b/lib/libstand/rpc.h
@@ -0,0 +1,68 @@
+/* $NetBSD: rpc.h,v 1.8 1996/09/26 23:22:03 cgd Exp $ */
+
+/*
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* XXX defines we can't easily get from system includes */
+#define PMAPPORT 111
+#define PMAPPROG 100000
+#define PMAPVERS 2
+#define PMAPPROC_NULL 0
+#define PMAPPROC_SET 1
+#define PMAPPROC_UNSET 2
+#define PMAPPROC_GETPORT 3
+#define PMAPPROC_DUMP 4
+#define PMAPPROC_CALLIT 5
+
+/* RPC functions: */
+ssize_t rpc_call(struct iodesc *, n_long, n_long, n_long,
+ void *, size_t, void *, size_t);
+void rpc_fromaddr(void *, struct in_addr *, u_short *);
+int rpc_pmap_getcache(struct in_addr, u_int, u_int);
+void rpc_pmap_putcache(struct in_addr, u_int, u_int, int);
+
+extern int rpc_port; /* decrement before bind */
+
+/*
+ * How much space to leave in front of RPC requests.
+ * In 32-bit words (alignment) we have:
+ * 12: Ether + IP + UDP + padding
+ * 6: RPC call header
+ * 7: Auth UNIX
+ * 2: Auth NULL
+ */
+#define RPC_HEADER_WORDS 28
diff --git a/lib/libstand/rpcv2.h b/lib/libstand/rpcv2.h
new file mode 100644
index 0000000..e4d2dbe
--- /dev/null
+++ b/lib/libstand/rpcv2.h
@@ -0,0 +1,89 @@
+/* $NetBSD: rpcv2.h,v 1.1 1996/02/26 23:05:32 gwr Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)rpcv2.h 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Definitions for Sun RPC Version 2, from
+ * "RPC: Remote Procedure Call Protocol Specification" RFC1057
+ */
+
+/* Version # */
+#define RPC_VER2 2
+
+/* Authentication */
+#define RPCAUTH_NULL 0
+#define RPCAUTH_UNIX 1
+#define RPCAUTH_SHORT 2
+#define RPCAUTH_MAXSIZ 400
+#define RPCAUTH_UNIXGIDS 16
+
+/* Rpc Constants */
+#define RPC_CALL 0
+#define RPC_REPLY 1
+#define RPC_MSGACCEPTED 0
+#define RPC_MSGDENIED 1
+#define RPC_PROGUNAVAIL 1
+#define RPC_PROGMISMATCH 2
+#define RPC_PROCUNAVAIL 3
+#define RPC_GARBAGE 4 /* I like this one */
+#define RPC_MISMATCH 0
+#define RPC_AUTHERR 1
+
+/* Authentication failures */
+#define AUTH_BADCRED 1
+#define AUTH_REJECTCRED 2
+#define AUTH_BADVERF 3
+#define AUTH_REJECTVERF 4
+#define AUTH_TOOWEAK 5 /* Give em wheaties */
+
+/* Sizes of rpc header parts */
+#define RPC_SIZ 24
+#define RPC_REPLYSIZ 28
+
+/* RPC Prog definitions */
+#define RPCPROG_MNT 100005
+#define RPCMNT_VER1 1
+#define RPCMNT_MOUNT 1
+#define RPCMNT_DUMP 2
+#define RPCMNT_UMOUNT 3
+#define RPCMNT_UMNTALL 4
+#define RPCMNT_EXPORT 5
+#define RPCMNT_NAMELEN 255
+#define RPCMNT_PATHLEN 1024
+#define RPCPROG_NFS 100003
diff --git a/lib/libstand/saioctl.h b/lib/libstand/saioctl.h
new file mode 100644
index 0000000..bf7df4c
--- /dev/null
+++ b/lib/libstand/saioctl.h
@@ -0,0 +1,52 @@
+/* $NetBSD: saioctl.h,v 1.2 1994/10/26 05:45:04 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)saioctl.h 8.1 (Berkeley) 6/11/93
+ */
+
+/* ioctl's -- for disks just now */
+#define SAIOHDR (('d'<<8)|1) /* next i/o includes header */
+#define SAIOCHECK (('d'<<8)|2) /* next i/o checks data */
+#define SAIOHCHECK (('d'<<8)|3) /* next i/o checks header & data */
+#define SAIONOBAD (('d'<<8)|4) /* inhibit bad sector forwarding */
+#define SAIODOBAD (('d'<<8)|5) /* enable bad sector forwarding */
+#define SAIOECCLIM (('d'<<8)|6) /* set limit to ecc correction, bits */
+#define SAIOECCUNL (('d'<<8)|7) /* use standard ecc procedures */
+#define SAIORETRIES (('d'<<8)|8) /* set retry count for unit */
+#define SAIODEVDATA (('d'<<8)|9) /* get pointer to pack label */
+#define SAIOSSI (('d'<<8)|10) /* set skip sector inhibit */
+#define SAIONOSSI (('d'<<8)|11) /* inhibit skip sector handling */
+#define SAIOSSDEV (('d'<<8)|12) /* is device skip sector type? */
+#define SAIODEBUG (('d'<<8)|13) /* enable/disable debugging */
+#define SAIOGBADINFO (('d'<<8)|14) /* get bad-sector table */
diff --git a/lib/libstand/sbrk.c b/lib/libstand/sbrk.c
new file mode 100644
index 0000000..fce03cf
--- /dev/null
+++ b/lib/libstand/sbrk.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 1998 Michael Smith
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Minimal sbrk() emulation required for malloc support.
+ */
+
+#include <string.h>
+#include "stand.h"
+
+static size_t maxheap, heapsize = 0;
+static void *heapbase;
+
+void
+setheap(void *base, void *top)
+{
+ heapbase = base;
+ maxheap = top - base;
+}
+
+char *
+sbrk(int incr)
+{
+ char *ret;
+
+ if ((heapsize + incr) <= maxheap) {
+ ret = heapbase + heapsize;
+ bzero(ret, incr);
+ heapsize += incr;
+ return(ret);
+ }
+ errno = ENOMEM;
+ return((char *)-1);
+}
+
diff --git a/lib/libstand/stand.h b/lib/libstand/stand.h
new file mode 100644
index 0000000..78832e7
--- /dev/null
+++ b/lib/libstand/stand.h
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 1998 Michael Smith.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ * From $NetBSD: stand.h,v 1.22 1997/06/26 19:17:40 drochner Exp $
+ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)stand.h 8.1 (Berkeley) 6/11/93
+ */
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/stat.h>
+
+#define CHK(fmt, args...) printf("%s(%d): " fmt "\n", __FUNCTION__, __LINE__ , ##args)
+#define PCHK(fmt, args...) {printf("%s(%d): " fmt "\n", __FUNCTION__, __LINE__ , ##args); getchar();}
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* Avoid unwanted userlandish components */
+#define KERNEL
+#include <sys/errno.h>
+#undef KERNEL
+
+/* special stand error codes */
+#define EADAPT (ELAST+1) /* bad adaptor */
+#define ECTLR (ELAST+2) /* bad controller */
+#define EUNIT (ELAST+3) /* bad unit */
+#define ESLICE (ELAST+4) /* bad slice */
+#define EPART (ELAST+5) /* bad partition */
+#define ERDLAB (ELAST+6) /* can't read disk label */
+#define EUNLAB (ELAST+7) /* unlabeled disk */
+#define EOFFSET (ELAST+8) /* relative seek not supported */
+#define ESALAST (ELAST+8) /* */
+
+struct open_file;
+
+/*
+ * This structure is used to define file system operations in a file system
+ * independent way.
+ *
+ * XXX note that filesystem providers should export a pointer to their fs_ops
+ * struct, so that consumers can reference this and thus include the
+ * filesystems that they require.
+ */
+struct fs_ops {
+ const char *fs_name;
+ int (*fo_open)(const char *path, struct open_file *f);
+ int (*fo_close)(struct open_file *f);
+ int (*fo_read)(struct open_file *f, void *buf,
+ size_t size, size_t *resid);
+ int (*fo_write)(struct open_file *f, void *buf,
+ size_t size, size_t *resid);
+ off_t (*fo_seek)(struct open_file *f, off_t offset, int where);
+ int (*fo_stat)(struct open_file *f, struct stat *sb);
+};
+
+/*
+ * libstand-supplied filesystems
+ */
+extern struct fs_ops ufs_fsops;
+extern struct fs_ops tftp_fsops;
+extern struct fs_ops nfs_fsops;
+extern struct fs_ops cd9660_fsops;
+extern struct fs_ops zipfs_fsops;
+extern struct fs_ops dosfs_fsops;
+
+/* where values for lseek(2) */
+#define SEEK_SET 0 /* set file offset to offset */
+#define SEEK_CUR 1 /* set file offset to current plus offset */
+#define SEEK_END 2 /* set file offset to EOF plus offset */
+
+/*
+ * Device switch
+ */
+struct devsw {
+ const char dv_name[8];
+ int dv_type; /* opaque type constant, arch-dependant */
+ int (*dv_init)(void); /* early probe call */
+ int (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, void *buf, size_t *rsize);
+ int (*dv_open)(struct open_file *f, ...);
+ int (*dv_close)(struct open_file *f);
+ int (*dv_ioctl)(struct open_file *f, u_long cmd, void *data);
+ void (*dv_print)(int verbose); /* print device information */
+};
+
+extern int errno;
+
+struct open_file {
+ int f_flags; /* see F_* below */
+ struct devsw *f_dev; /* pointer to device operations */
+ void *f_devdata; /* device specific data */
+ struct fs_ops *f_ops; /* pointer to file system operations */
+ void *f_fsdata; /* file system specific data */
+ off_t f_offset; /* current file offset (F_RAW) */
+};
+
+#define SOPEN_MAX 8
+extern struct open_file files[];
+
+/* f_flags values */
+#define F_READ 0x0001 /* file opened for reading */
+#define F_WRITE 0x0002 /* file opened for writing */
+#define F_RAW 0x0004 /* raw device open - no file system */
+#define F_NODEV 0x0008 /* network open - no device */
+
+#define isupper(c) ((c) >= 'A' && (c) <= 'Z')
+#define islower(c) ((c) >= 'a' && (c) <= 'z')
+#define isspace(c) ((c) == ' ' || ((c) >= 0x9 && (c) <= 0xd))
+#define isdigit(c) ((c) >= '0' && (c) <= '9')
+#define isxdigit(c) (isdigit(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
+#define isascii(c) ((c) >= 0 || (c <= 0x7f))
+#define isalpha(c) (isupper(c) || (islower(c)))
+
+static __inline int toupper(int c)
+{
+ return islower(c) ? c - 'a' + 'A' : c;
+}
+
+static __inline int tolower(int c)
+{
+ return isupper(c) ? c - 'A' + 'a' : c;
+}
+
+/* sbrk emulation */
+extern void setheap(void *base, void *top);
+extern char *sbrk(int incr);
+
+/* Matt Dillon's zalloc/zmalloc */
+extern void *malloc(size_t bytes);
+extern void free(void *ptr);
+/*#define free(p) {CHK("free %p", p); free(p);} */ /* use for catching guard violations */
+extern void *calloc(size_t n1, size_t n2);
+extern void *realloc(void *ptr, size_t size);
+extern void *reallocf(void *ptr, size_t size);
+extern void mallocstats(void);
+#ifdef __alpha__
+extern void free_region(void *start, void *end);
+#endif
+
+/* disklabel support (undocumented, may be junk) */
+struct disklabel;
+extern char *getdisklabel(const char *, struct disklabel *);
+extern int dkcksum(struct disklabel *);
+
+extern int printf(const char *fmt, ...);
+extern void vprintf(const char *fmt, _BSD_VA_LIST_);
+extern int sprintf(char *buf, const char *cfmt, ...);
+extern void vsprintf(char *buf, const char *cfmt, _BSD_VA_LIST_);
+
+extern void twiddle(void);
+
+extern void ngets(char *, int);
+#define gets(x) ngets((x), 0)
+extern int fgetstr(char *buf, int size, int fd);
+
+extern int open(const char *, int);
+#define O_RDONLY 0x0
+#define O_WRONLY 0x1 /* writing not (yet?) supported */
+#define O_RDWR 0x2
+extern int close(int);
+extern void closeall(void);
+extern ssize_t read(int, void *, size_t);
+extern ssize_t write(int, void *, size_t);
+extern off_t lseek(int, off_t, int);
+extern int stat(const char *, struct stat *);
+
+extern void srandom(u_long seed);
+extern u_long random(void);
+
+/* imports from stdlib, locally modified */
+extern long strtol(const char *, char **, int);
+extern char * strerror(int err);
+extern char *optarg; /* getopt(3) external variables */
+extern int optind, opterr, optopt, optreset;
+extern int getopt(int, char * const [], const char *);
+
+/* pager.c */
+extern void pager_open(void);
+extern void pager_close(void);
+extern int pager_output(const char *lines);
+extern int pager_file(const char *fname);
+
+/* No signal state to preserve */
+#define setjmp _setjmp
+#define longjmp _longjmp
+
+/* environment.c */
+#define EV_DYNAMIC (1<<0) /* value was dynamically allocated, free if changed/unset */
+#define EV_VOLATILE (1<<1) /* value is volatile, make a copy of it */
+#define EV_NOHOOK (1<<2) /* don't call hook when setting */
+
+struct env_var;
+typedef char *(ev_format_t)(struct env_var *ev);
+typedef int (ev_sethook_t)(struct env_var *ev, int flags, void *value);
+typedef int (ev_unsethook_t)(struct env_var *ev);
+
+struct env_var
+{
+ char *ev_name;
+ int ev_flags;
+ void *ev_value;
+ ev_sethook_t *ev_sethook;
+ ev_unsethook_t *ev_unsethook;
+ struct env_var *ev_next, *ev_prev;
+};
+extern struct env_var *environ;
+
+extern struct env_var *env_getenv(const char *name);
+extern int env_setenv(const char *name, int flags, void *value,
+ ev_sethook_t sethook, ev_unsethook_t unsethook);
+extern char *getenv(const char *name);
+extern int setenv(const char *name, char *value, int overwrite);
+extern int putenv(const char *string);
+extern int unsetenv(const char *name);
+
+extern ev_sethook_t env_noset; /* refuse set operation */
+extern ev_unsethook_t env_nounset; /* refuse unset operation */
+
+/* BCD conversions (undocumented) */
+extern u_char const bcd2bin_data[];
+extern u_char const bin2bcd_data[];
+extern char const hex2ascii_data[];
+
+#define bcd2bin(bcd) (bcd2bin_data[bcd])
+#define bin2bcd(bin) (bin2bcd_data[bin])
+#define hex2ascii(hex) (hex2ascii_data[hex])
+
+/* min/max (undocumented) */
+static __inline int imax(int a, int b) { return (a > b ? a : b); }
+static __inline int imin(int a, int b) { return (a < b ? a : b); }
+static __inline long lmax(long a, long b) { return (a > b ? a : b); }
+static __inline long lmin(long a, long b) { return (a < b ? a : b); }
+static __inline u_int max(u_int a, u_int b) { return (a > b ? a : b); }
+static __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); }
+static __inline quad_t qmax(quad_t a, quad_t b) { return (a > b ? a : b); }
+static __inline quad_t qmin(quad_t a, quad_t b) { return (a < b ? a : b); }
+static __inline u_long ulmax(u_long a, u_long b) { return (a > b ? a : b); }
+static __inline u_long ulmin(u_long a, u_long b) { return (a < b ? a : b); }
+
+/* swaps (undocumented, useful?) */
+#ifdef __i386__
+extern u_int32_t bswap32(u_int32_t x);
+extern u_int64_t bswap64(u_int32_t x);
+#endif
+
+/* null functions for device/filesystem switches (undocumented) */
+extern int nodev(void);
+extern int noioctl(struct open_file *, u_long, void *);
+extern void nullsys(void);
+
+extern int null_open(const char *path, struct open_file *f);
+extern int null_close(struct open_file *f);
+extern ssize_t null_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+extern ssize_t null_write(struct open_file *f, void *buf, size_t size, size_t *resid);
+extern off_t null_seek(struct open_file *f, off_t offset, int where);
+extern int null_stat(struct open_file *f, struct stat *sb);
+
+/*
+ * Machine dependent functions and data, must be provided or stubbed by
+ * the consumer
+ */
+extern int getchar(void);
+extern int ischar(void);
+extern void putchar(int);
+extern int devopen(struct open_file *, const char *, const char **);
+extern int devclose(struct open_file *f);
+extern void panic(const char *, ...) __dead2;
+extern struct fs_ops *file_system[];
+extern struct devsw *devsw[];
+
+#if 0
+
+static inline void *
+malloc_debug(size_t size, const char *file, int line)
+{
+ void *p;
+ printf("%s:%d malloc(%ld)", file, line, size);
+ p = malloc(size);
+ printf("=%p\n", p);
+ return p;
+}
+
+static inline void
+free_debug(void *p, const char *file, int line)
+{
+ printf("%s:%d free(%p)\n", file, line, p);
+ free(p);
+}
+
+#define malloc(x) malloc_debug(x, __FILE__, __LINE__)
+#define free(x) free_debug(x, __FILE__, __LINE__)
+
+#endif
diff --git a/lib/libstand/stat.c b/lib/libstand/stat.c
new file mode 100644
index 0000000..bdc97d5
--- /dev/null
+++ b/lib/libstand/stat.c
@@ -0,0 +1,53 @@
+/* $NetBSD: stat.c,v 1.4 1996/01/13 22:25:43 leo Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)stat.c 8.1 (Berkeley) 6/11/93
+ */
+
+#include "stand.h"
+
+int
+stat(str, sb)
+ const char *str;
+ struct stat *sb;
+{
+ int fd, rv;
+
+ fd = open(str, O_RDONLY);
+ if (fd < 0)
+ return (-1);
+ rv = fstat(fd, sb);
+ (void)close(fd);
+ return (rv);
+}
diff --git a/lib/libstand/strcasecmp.c b/lib/libstand/strcasecmp.c
new file mode 100644
index 0000000..247484d
--- /dev/null
+++ b/lib/libstand/strcasecmp.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <string.h>
+#include "stand.h"
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+int
+strcasecmp(s1, s2)
+ const char *s1, *s2;
+{
+ register const u_char
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ while (tolower(*us1) == tolower(*us2++))
+ if (*us1++ == '\0')
+ return (0);
+ return (tolower(*us1) - tolower(*--us2));
+}
+
+int
+strncasecmp(s1, s2, n)
+ const char *s1, *s2;
+ register size_t n;
+{
+ if (n != 0) {
+ register const u_char
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ do {
+ if (tolower(*us1) != tolower(*us2++))
+ return (tolower(*us1) - tolower(*--us2));
+ if (*us1++ == '\0')
+ break;
+ } while (--n != 0);
+ }
+ return (0);
+}
diff --git a/lib/libstand/strdup.c b/lib/libstand/strdup.c
new file mode 100644
index 0000000..ee46e7d
--- /dev/null
+++ b/lib/libstand/strdup.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strdup.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "stand.h"
+#include <stddef.h>
+#include <string.h>
+
+char *
+strdup(str)
+ const char *str;
+{
+ size_t len;
+ char *copy = NULL;
+
+ if (str != NULL) {
+ len = strlen(str) + 1;
+ if ((copy = malloc(len)) == NULL)
+ return (NULL);
+ memcpy(copy, str, len);
+ }
+ return (copy);
+}
diff --git a/lib/libstand/strerror.c b/lib/libstand/strerror.c
new file mode 100644
index 0000000..e84a4d427
--- /dev/null
+++ b/lib/libstand/strerror.c
@@ -0,0 +1,88 @@
+/* $NetBSD: strerror.c,v 1.12 1997/01/25 00:37:50 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "stand.h"
+
+static struct
+{
+ int err;
+ char *msg;
+} errtab[] = {
+ {0, "no error"},
+ /* standard errors */
+ {EPERM, "operation not permitted"},
+ {ENOENT, "no such file or directory"},
+ {EIO, "input/output error"},
+ {ENXIO, "device not configured"},
+ {ENOEXEC, "exec format error"},
+ {EBADF, "bad file descriptor"},
+ {ENOMEM, "cannot allocate memory"},
+ {ENODEV, "operation not supported by device"},
+ {ENOTDIR, "not a directory"},
+ {EISDIR, "is a directory"},
+ {EINVAL, "invalid argument"},
+ {EMFILE, "too many open files"},
+ {EFBIG, "file too large"},
+ {EROFS, "read-only filesystem"},
+ {EOPNOTSUPP, "operation not supported"},
+ {ETIMEDOUT, "operation timed out"},
+ {ESTALE, "stale NFS file handle"},
+ {EBADRPC, "RPC struct is bad"},
+ {EFTYPE, "inappropriate file type or format"},
+
+ {EADAPT, "bad adaptor number"},
+ {ECTLR, "bad controller number"},
+ {EUNIT, "bad unit number"},
+ {ESLICE, "bad slice number"},
+ {EPART, "bad partition"},
+ {ERDLAB, "can't read disk label"},
+ {EUNLAB, "disk unlabelled"},
+ {EOFFSET, "illegal seek"},
+ {0, NULL}
+};
+
+
+char *
+strerror(int err)
+{
+ static char msg[32];
+ int i;
+
+ for (i = 0; errtab[i].msg != NULL; i++)
+ if (errtab[i].err == err)
+ return(errtab[i].msg);
+ sprintf(msg, "unknown error (%d)", err);
+ return(msg);
+}
diff --git a/lib/libstand/strtol.c b/lib/libstand/strtol.c
new file mode 100644
index 0000000..02c5920
--- /dev/null
+++ b/lib/libstand/strtol.c
@@ -0,0 +1,133 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "stand.h"
+#include <limits.h>
+
+/*
+ * Convert a string to a long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+long
+strtol(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ register int base;
+{
+ register const char *s;
+ register unsigned long acc;
+ register unsigned char c;
+ register unsigned long cutoff;
+ register int neg = 0, any, cutlim;
+
+ /* Be sensible about NULL strings */
+ if (nptr == NULL)
+ nptr = "";
+ s = nptr;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for longs is
+ * [-2147483648..2147483647] and the input base is 10,
+ * cutoff will be set to 214748364 and cutlim to either
+ * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+ * a value > 214748364, or equal but the next digit is > 7 (or 8),
+ * the number is too big, and we will return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+ cutlim = cutoff % (unsigned long)base;
+ cutoff /= (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LONG_MIN : LONG_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/lib/libstand/tftp.c b/lib/libstand/tftp.c
new file mode 100644
index 0000000..a6695e9
--- /dev/null
+++ b/lib/libstand/tftp.c
@@ -0,0 +1,407 @@
+/* $NetBSD: tftp.c,v 1.4 1997/09/17 16:57:07 drochner Exp $ */
+
+/*
+ * Copyright (c) 1996
+ * Matthias Drochner. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Matthias Drochner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * Simple TFTP implementation for libsa.
+ * Assumes:
+ * - socket descriptor (int) at open_file->f_devdata
+ * - server host IP in global servip
+ * Restrictions:
+ * - read only
+ * - lseek only with SEEK_SET or SEEK_CUR
+ * - no big time differences between transfers (<tftp timeout)
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <netinet/udp.h>
+#include <netinet/in_systm.h>
+#include <arpa/tftp.h>
+
+#include <string.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+
+#include "tftp.h"
+
+static int tftp_open(const char *path, struct open_file *f);
+static int tftp_close(struct open_file *f);
+static int tftp_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static int tftp_write(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t tftp_seek(struct open_file *f, off_t offset, int where);
+static int tftp_stat(struct open_file *f, struct stat *sb);
+
+struct fs_ops tftp_fsops = {
+ "tftp", tftp_open, tftp_close, tftp_read, tftp_write, tftp_seek, tftp_stat
+};
+
+extern struct in_addr servip;
+
+static int tftpport = 2000;
+
+#define RSPACE 520 /* max data packet, rounded up */
+
+struct tftp_handle {
+ struct iodesc *iodesc;
+ int currblock; /* contents of lastdata */
+ int islastblock; /* flag */
+ int validsize;
+ int off;
+ char *path; /* saved for re-requests */
+ struct {
+ u_char header[HEADER_SIZE];
+ struct tftphdr t;
+ u_char space[RSPACE];
+ } lastdata;
+};
+
+static int tftperrors[8] = {
+ 0, /* ??? */
+ ENOENT,
+ EPERM,
+ ENOSPC,
+ EINVAL, /* ??? */
+ EINVAL, /* ??? */
+ EEXIST,
+ EINVAL /* ??? */
+};
+
+static ssize_t
+recvtftp(d, pkt, len, tleft)
+ register struct iodesc *d;
+ register void *pkt;
+ register ssize_t len;
+ time_t tleft;
+{
+ struct tftphdr *t;
+
+ len = readudp(d, pkt, len, tleft);
+
+ if (len < 8)
+ return (-1);
+
+ t = (struct tftphdr *) pkt;
+ switch (ntohs(t->th_opcode)) {
+ case DATA: {
+ int got;
+
+ if (htons(t->th_block) != d->xid) {
+ /*
+ * Expected block?
+ */
+ return (-1);
+ }
+ if (d->xid == 1) {
+ /*
+ * First data packet from new port.
+ */
+ register struct udphdr *uh;
+ uh = (struct udphdr *) pkt - 1;
+ d->destport = uh->uh_sport;
+ } /* else check uh_sport has not changed??? */
+ got = len - (t->th_data - (char *) t);
+ return got;
+ }
+ case ERROR:
+ if ((unsigned) ntohs(t->th_code) >= 8) {
+ printf("illegal tftp error %d\n", ntohs(t->th_code));
+ errno = EIO;
+ } else {
+#ifdef DEBUG
+ printf("tftp-error %d\n", ntohs(t->th_code));
+#endif
+ errno = tftperrors[ntohs(t->th_code)];
+ }
+ return (-1);
+ default:
+#ifdef DEBUG
+ printf("tftp type %d not handled\n", ntohs(t->th_opcode));
+#endif
+ return (-1);
+ }
+}
+
+/* send request, expect first block (or error) */
+static int
+tftp_makereq(h)
+ struct tftp_handle *h;
+{
+ struct {
+ u_char header[HEADER_SIZE];
+ struct tftphdr t;
+ u_char space[FNAME_SIZE + 6];
+ } wbuf;
+ char *wtail;
+ int l;
+ ssize_t res;
+ struct tftphdr *t;
+
+ wbuf.t.th_opcode = htons((u_short) RRQ);
+ wtail = wbuf.t.th_stuff;
+ l = strlen(h->path);
+ bcopy(h->path, wtail, l + 1);
+ wtail += l + 1;
+ bcopy("octet", wtail, 6);
+ wtail += 6;
+
+ t = &h->lastdata.t;
+
+ /* h->iodesc->myport = htons(--tftpport); */
+ h->iodesc->myport = htons(tftpport + (getsecs() & 0x3ff));
+ h->iodesc->destport = htons(IPPORT_TFTP);
+ h->iodesc->xid = 1; /* expected block */
+
+ res = sendrecv(h->iodesc, sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
+ recvtftp, t, sizeof(*t) + RSPACE);
+
+ if (res == -1)
+ return (errno);
+
+ h->currblock = 1;
+ h->validsize = res;
+ h->islastblock = 0;
+ if (res < SEGSIZE)
+ h->islastblock = 1; /* very short file */
+ return (0);
+}
+
+/* ack block, expect next */
+static int
+tftp_getnextblock(h)
+ struct tftp_handle *h;
+{
+ struct {
+ u_char header[HEADER_SIZE];
+ struct tftphdr t;
+ } wbuf;
+ char *wtail;
+ int res;
+ struct tftphdr *t;
+
+ wbuf.t.th_opcode = htons((u_short) ACK);
+ wtail = (char *) &wbuf.t.th_block;
+ wbuf.t.th_block = htons((u_short) h->currblock);
+ wtail += 2;
+
+ t = &h->lastdata.t;
+
+ h->iodesc->xid = h->currblock + 1; /* expected block */
+
+ res = sendrecv(h->iodesc, sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
+ recvtftp, t, sizeof(*t) + RSPACE);
+
+ if (res == -1) /* 0 is OK! */
+ return (errno);
+
+ h->currblock++;
+ h->validsize = res;
+ if (res < SEGSIZE)
+ h->islastblock = 1; /* EOF */
+ return (0);
+}
+
+static int
+tftp_open(path, f)
+ const char *path;
+ struct open_file *f;
+{
+ struct tftp_handle *tftpfile;
+ struct iodesc *io;
+ int res;
+
+ tftpfile = (struct tftp_handle *) malloc(sizeof(*tftpfile));
+ if (!tftpfile)
+ return (ENOMEM);
+
+ tftpfile->iodesc = io = socktodesc(*(int *) (f->f_devdata));
+ io->destip = servip;
+ tftpfile->off = 0;
+ tftpfile->path = strdup(path);
+ if (tftpfile->path == NULL) {
+ free(tftpfile);
+ return(ENOMEM);
+ }
+
+ res = tftp_makereq(tftpfile, path);
+
+ if (res) {
+ free(tftpfile->path);
+ free(tftpfile);
+ return (res);
+ }
+ f->f_fsdata = (void *) tftpfile;
+ return (0);
+}
+
+static int
+tftp_read(f, addr, size, resid)
+ struct open_file *f;
+ void *addr;
+ size_t size;
+ size_t *resid; /* out */
+{
+ struct tftp_handle *tftpfile;
+ static int tc = 0;
+ tftpfile = (struct tftp_handle *) f->f_fsdata;
+
+ while (size > 0) {
+ int needblock, count;
+
+ if (!(tc++ % 16))
+ twiddle();
+
+ needblock = tftpfile->off / SEGSIZE + 1;
+
+ if (tftpfile->currblock > needblock) /* seek backwards */
+ tftp_makereq(tftpfile); /* no error check, it worked
+ * for open */
+
+ while (tftpfile->currblock < needblock) {
+ int res;
+
+ res = tftp_getnextblock(tftpfile);
+ if (res) { /* no answer */
+#ifdef DEBUG
+ printf("tftp: read error\n");
+#endif
+ return (res);
+ }
+ if (tftpfile->islastblock)
+ break;
+ }
+
+ if (tftpfile->currblock == needblock) {
+ int offinblock, inbuffer;
+
+ offinblock = tftpfile->off % SEGSIZE;
+
+ inbuffer = tftpfile->validsize - offinblock;
+ if (inbuffer < 0) {
+#ifdef DEBUG
+ printf("tftp: invalid offset %d\n",
+ tftpfile->off);
+#endif
+ return (EINVAL);
+ }
+ count = (size < inbuffer ? size : inbuffer);
+ bcopy(tftpfile->lastdata.t.th_data + offinblock,
+ addr, count);
+
+ addr += count;
+ tftpfile->off += count;
+ size -= count;
+
+ if ((tftpfile->islastblock) && (count == inbuffer))
+ break; /* EOF */
+ } else {
+#ifdef DEBUG
+ printf("tftp: block %d not found\n", needblock);
+#endif
+ return (EINVAL);
+ }
+
+ }
+
+ if (resid)
+ *resid = size;
+ return (0);
+}
+
+static int
+tftp_close(f)
+ struct open_file *f;
+{
+ struct tftp_handle *tftpfile;
+ tftpfile = (struct tftp_handle *) f->f_fsdata;
+
+ /* let it time out ... */
+
+ if (tftpfile) {
+ free(tftpfile->path);
+ free(tftpfile);
+ }
+ return (0);
+}
+
+static int
+tftp_write(f, start, size, resid)
+ struct open_file *f;
+ void *start;
+ size_t size;
+ size_t *resid; /* out */
+{
+ return (EROFS);
+}
+
+static int
+tftp_stat(f, sb)
+ struct open_file *f;
+ struct stat *sb;
+{
+ struct tftp_handle *tftpfile;
+ tftpfile = (struct tftp_handle *) f->f_fsdata;
+
+ sb->st_mode = 0444;
+ sb->st_nlink = 1;
+ sb->st_uid = 0;
+ sb->st_gid = 0;
+ sb->st_size = -1;
+ return (0);
+}
+
+static off_t
+tftp_seek(f, offset, where)
+ struct open_file *f;
+ off_t offset;
+ int where;
+{
+ struct tftp_handle *tftpfile;
+ tftpfile = (struct tftp_handle *) f->f_fsdata;
+
+ switch (where) {
+ case SEEK_SET:
+ tftpfile->off = offset;
+ break;
+ case SEEK_CUR:
+ tftpfile->off += offset;
+ break;
+ default:
+ errno = EOFFSET;
+ return (-1);
+ }
+ return (tftpfile->off);
+}
diff --git a/lib/libstand/tftp.h b/lib/libstand/tftp.h
new file mode 100644
index 0000000..cbbbbd7
--- /dev/null
+++ b/lib/libstand/tftp.h
@@ -0,0 +1,36 @@
+/* $NetBSD: tftp.h,v 1.1.1.1 1997/03/14 02:40:31 perry Exp $ */
+
+/*
+ * Copyright (c) 1996
+ * Matthias Drochner. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Matthias Drochner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#define IPPORT_TFTP 69
diff --git a/lib/libstand/twiddle.c b/lib/libstand/twiddle.c
new file mode 100644
index 0000000..7a9a669
--- /dev/null
+++ b/lib/libstand/twiddle.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1986, 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include "stand.h"
+
+/* Extra functions from NetBSD standalone printf.c */
+
+void
+twiddle()
+{
+ static int pos;
+
+ putchar("|/-\\"[pos++ & 3]);
+ putchar('\b');
+}
diff --git a/lib/libstand/ufs.c b/lib/libstand/ufs.c
new file mode 100644
index 0000000..8511422
--- /dev/null
+++ b/lib/libstand/ufs.c
@@ -0,0 +1,717 @@
+/* $NetBSD: ufs.c,v 1.20 1998/03/01 07:15:39 ross Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *
+ * Copyright (c) 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: David Golub
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * Stand-alone file reading package.
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/dir.h>
+#include <ufs/ffs/fs.h>
+#include "stand.h"
+#include "string.h"
+
+#ifdef __alpha__
+#define COMPAT_UFS /* DUX has old format file systems */
+#endif
+
+static int ufs_open(const char *path, struct open_file *f);
+static int ufs_close(struct open_file *f);
+static int ufs_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t ufs_seek(struct open_file *f, off_t offset, int where);
+static int ufs_stat(struct open_file *f, struct stat *sb);
+
+struct fs_ops ufs_fsops = {
+ "ufs", ufs_open, ufs_close, ufs_read, null_write, ufs_seek, ufs_stat
+};
+
+/*
+ * In-core open file.
+ */
+struct file {
+ off_t f_seekp; /* seek pointer */
+ struct fs *f_fs; /* pointer to super-block */
+ struct dinode f_di; /* copy of on-disk inode */
+ int f_nindir[NIADDR];
+ /* number of blocks mapped by
+ indirect block at level i */
+ char *f_blk[NIADDR]; /* buffer for indirect block at
+ level i */
+ size_t f_blksize[NIADDR];
+ /* size of buffer */
+ daddr_t f_blkno[NIADDR];/* disk address of block in buffer */
+ char *f_buf; /* buffer for data block */
+ size_t f_buf_size; /* size of data block */
+ daddr_t f_buf_blkno; /* block number of data block */
+};
+
+static int read_inode(ino_t, struct open_file *);
+static int block_map(struct open_file *, daddr_t, daddr_t *);
+static int buf_read_file(struct open_file *, char **, size_t *);
+static int search_directory(char *, struct open_file *, ino_t *);
+#ifdef COMPAT_UFS
+static void ffs_oldfscompat(struct fs *);
+#endif
+
+/*
+ * Read a new inode into a file structure.
+ */
+static int
+read_inode(inumber, f)
+ ino_t inumber;
+ struct open_file *f;
+{
+ register struct file *fp = (struct file *)f->f_fsdata;
+ register struct fs *fs = fp->f_fs;
+ char *buf;
+ size_t rsize;
+ int rc;
+
+ if (fs == NULL)
+ panic("fs == NULL");
+
+ /*
+ * Read inode and save it.
+ */
+ buf = malloc(fs->fs_bsize);
+ twiddle();
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ fsbtodb(fs, ino_to_fsba(fs, inumber)), fs->fs_bsize,
+ buf, &rsize);
+ if (rc)
+ goto out;
+ if (rsize != fs->fs_bsize) {
+ rc = EIO;
+ goto out;
+ }
+
+ {
+ register struct dinode *dp;
+
+ dp = (struct dinode *)buf;
+ fp->f_di = dp[ino_to_fsbo(fs, inumber)];
+ }
+
+ /*
+ * Clear out the old buffers
+ */
+ {
+ register int level;
+
+ for (level = 0; level < NIADDR; level++)
+ fp->f_blkno[level] = -1;
+ fp->f_buf_blkno = -1;
+ }
+out:
+ free(buf);
+ return (rc);
+}
+
+/*
+ * Given an offset in a file, find the disk block number that
+ * contains that block.
+ */
+static int
+block_map(f, file_block, disk_block_p)
+ struct open_file *f;
+ daddr_t file_block;
+ daddr_t *disk_block_p; /* out */
+{
+ register struct file *fp = (struct file *)f->f_fsdata;
+ register struct fs *fs = fp->f_fs;
+ int level;
+ int idx;
+ daddr_t ind_block_num;
+ daddr_t *ind_p;
+ int rc;
+
+ /*
+ * Index structure of an inode:
+ *
+ * di_db[0..NDADDR-1] hold block numbers for blocks
+ * 0..NDADDR-1
+ *
+ * di_ib[0] index block 0 is the single indirect block
+ * holds block numbers for blocks
+ * NDADDR .. NDADDR + NINDIR(fs)-1
+ *
+ * di_ib[1] index block 1 is the double indirect block
+ * holds block numbers for INDEX blocks for blocks
+ * NDADDR + NINDIR(fs) ..
+ * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
+ *
+ * di_ib[2] index block 2 is the triple indirect block
+ * holds block numbers for double-indirect
+ * blocks for blocks
+ * NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
+ * NDADDR + NINDIR(fs) + NINDIR(fs)**2
+ * + NINDIR(fs)**3 - 1
+ */
+
+ if (file_block < NDADDR) {
+ /* Direct block. */
+ *disk_block_p = fp->f_di.di_db[file_block];
+ return (0);
+ }
+
+ file_block -= NDADDR;
+
+ /*
+ * nindir[0] = NINDIR
+ * nindir[1] = NINDIR**2
+ * nindir[2] = NINDIR**3
+ * etc
+ */
+ for (level = 0; level < NIADDR; level++) {
+ if (file_block < fp->f_nindir[level])
+ break;
+ file_block -= fp->f_nindir[level];
+ }
+ if (level == NIADDR) {
+ /* Block number too high */
+ return (EFBIG);
+ }
+
+ ind_block_num = fp->f_di.di_ib[level];
+
+ for (; level >= 0; level--) {
+ if (ind_block_num == 0) {
+ *disk_block_p = 0; /* missing */
+ return (0);
+ }
+
+ if (fp->f_blkno[level] != ind_block_num) {
+ if (fp->f_blk[level] == (char *)0)
+ fp->f_blk[level] =
+ malloc(fs->fs_bsize);
+ twiddle();
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ fsbtodb(fp->f_fs, ind_block_num),
+ fs->fs_bsize,
+ fp->f_blk[level],
+ &fp->f_blksize[level]);
+ if (rc)
+ return (rc);
+ if (fp->f_blksize[level] != fs->fs_bsize)
+ return (EIO);
+ fp->f_blkno[level] = ind_block_num;
+ }
+
+ ind_p = (daddr_t *)fp->f_blk[level];
+
+ if (level > 0) {
+ idx = file_block / fp->f_nindir[level - 1];
+ file_block %= fp->f_nindir[level - 1];
+ } else
+ idx = file_block;
+
+ ind_block_num = ind_p[idx];
+ }
+
+ *disk_block_p = ind_block_num;
+
+ return (0);
+}
+
+/*
+ * Read a portion of a file into an internal buffer. Return
+ * the location in the buffer and the amount in the buffer.
+ */
+static int
+buf_read_file(f, buf_p, size_p)
+ struct open_file *f;
+ char **buf_p; /* out */
+ size_t *size_p; /* out */
+{
+ register struct file *fp = (struct file *)f->f_fsdata;
+ register struct fs *fs = fp->f_fs;
+ long off;
+ register daddr_t file_block;
+ daddr_t disk_block;
+ size_t block_size;
+ int rc;
+
+ off = blkoff(fs, fp->f_seekp);
+ file_block = lblkno(fs, fp->f_seekp);
+ block_size = dblksize(fs, &fp->f_di, file_block);
+
+ if (file_block != fp->f_buf_blkno) {
+ rc = block_map(f, file_block, &disk_block);
+ if (rc)
+ return (rc);
+
+ if (fp->f_buf == (char *)0)
+ fp->f_buf = malloc(fs->fs_bsize);
+
+ if (disk_block == 0) {
+ bzero(fp->f_buf, block_size);
+ fp->f_buf_size = block_size;
+ } else {
+ twiddle();
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ fsbtodb(fs, disk_block),
+ block_size, fp->f_buf, &fp->f_buf_size);
+ if (rc)
+ return (rc);
+ }
+
+ fp->f_buf_blkno = file_block;
+ }
+
+ /*
+ * Return address of byte in buffer corresponding to
+ * offset, and size of remainder of buffer after that
+ * byte.
+ */
+ *buf_p = fp->f_buf + off;
+ *size_p = block_size - off;
+
+ /*
+ * But truncate buffer at end of file.
+ */
+ if (*size_p > fp->f_di.di_size - fp->f_seekp)
+ *size_p = fp->f_di.di_size - fp->f_seekp;
+
+ return (0);
+}
+
+/*
+ * Search a directory for a name and return its
+ * i_number.
+ */
+static int
+search_directory(name, f, inumber_p)
+ char *name;
+ struct open_file *f;
+ ino_t *inumber_p; /* out */
+{
+ register struct file *fp = (struct file *)f->f_fsdata;
+ register struct direct *dp;
+ struct direct *edp;
+ char *buf;
+ size_t buf_size;
+ int namlen, length;
+ int rc;
+
+ length = strlen(name);
+
+ fp->f_seekp = 0;
+ while (fp->f_seekp < fp->f_di.di_size) {
+ rc = buf_read_file(f, &buf, &buf_size);
+ if (rc)
+ return (rc);
+
+ dp = (struct direct *)buf;
+ edp = (struct direct *)(buf + buf_size);
+ while (dp < edp) {
+ if (dp->d_ino == (ino_t)0)
+ goto next;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ if (fp->f_fs->fs_maxsymlinklen <= 0)
+ namlen = dp->d_type;
+ else
+#endif
+ namlen = dp->d_namlen;
+ if (namlen == length &&
+ !strcmp(name, dp->d_name)) {
+ /* found entry */
+ *inumber_p = dp->d_ino;
+ return (0);
+ }
+ next:
+ dp = (struct direct *)((char *)dp + dp->d_reclen);
+ }
+ fp->f_seekp += buf_size;
+ }
+ return (ENOENT);
+}
+
+/*
+ * Open a file.
+ */
+static int
+ufs_open(upath, f)
+ const char *upath;
+ struct open_file *f;
+{
+ register char *cp, *ncp;
+ register int c;
+ ino_t inumber, parent_inumber;
+ struct file *fp;
+ struct fs *fs;
+ int rc;
+ size_t buf_size;
+ int nlinks = 0;
+ char namebuf[MAXPATHLEN+1];
+ char *buf = NULL;
+ char *path = NULL;
+
+ /* allocate file system specific data structure */
+ fp = malloc(sizeof(struct file));
+ bzero(fp, sizeof(struct file));
+ f->f_fsdata = (void *)fp;
+
+ /* allocate space and read super block */
+ fs = malloc(SBSIZE);
+ fp->f_fs = fs;
+ twiddle();
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ SBLOCK, SBSIZE, (char *)fs, &buf_size);
+ if (rc)
+ goto out;
+
+ if (buf_size != SBSIZE || fs->fs_magic != FS_MAGIC ||
+ fs->fs_bsize > MAXBSIZE || fs->fs_bsize < sizeof(struct fs)) {
+ rc = EINVAL;
+ goto out;
+ }
+#ifdef COMPAT_UFS
+ ffs_oldfscompat(fs);
+#endif
+
+ /*
+ * Calculate indirect block levels.
+ */
+ {
+ register int mult;
+ register int level;
+
+ mult = 1;
+ for (level = 0; level < NIADDR; level++) {
+ mult *= NINDIR(fs);
+ fp->f_nindir[level] = mult;
+ }
+ }
+
+ inumber = ROOTINO;
+ if ((rc = read_inode(inumber, f)) != 0)
+ goto out;
+
+ cp = path = strdup(upath);
+ if (path == NULL) {
+ rc = ENOMEM;
+ goto out;
+ }
+ while (*cp) {
+
+ /*
+ * Remove extra separators
+ */
+ while (*cp == '/')
+ cp++;
+ if (*cp == '\0')
+ break;
+
+ /*
+ * Check that current node is a directory.
+ */
+ if ((fp->f_di.di_mode & IFMT) != IFDIR) {
+ rc = ENOTDIR;
+ goto out;
+ }
+
+ /*
+ * Get next component of path name.
+ */
+ {
+ register int len = 0;
+
+ ncp = cp;
+ while ((c = *cp) != '\0' && c != '/') {
+ if (++len > MAXNAMLEN) {
+ rc = ENOENT;
+ goto out;
+ }
+ cp++;
+ }
+ *cp = '\0';
+ }
+
+ /*
+ * Look up component in current directory.
+ * Save directory inumber in case we find a
+ * symbolic link.
+ */
+ parent_inumber = inumber;
+ rc = search_directory(ncp, f, &inumber);
+ *cp = c;
+ if (rc)
+ goto out;
+
+ /*
+ * Open next component.
+ */
+ if ((rc = read_inode(inumber, f)) != 0)
+ goto out;
+
+ /*
+ * Check for symbolic link.
+ */
+ if ((fp->f_di.di_mode & IFMT) == IFLNK) {
+ int link_len = fp->f_di.di_size;
+ int len;
+
+ len = strlen(cp);
+
+ if (link_len + len > MAXPATHLEN ||
+ ++nlinks > MAXSYMLINKS) {
+ rc = ENOENT;
+ goto out;
+ }
+
+ bcopy(cp, &namebuf[link_len], len + 1);
+
+ if (link_len < fs->fs_maxsymlinklen) {
+ bcopy(fp->f_di.di_shortlink, namebuf,
+ (unsigned) link_len);
+ } else {
+ /*
+ * Read file for symbolic link
+ */
+ size_t buf_size;
+ daddr_t disk_block;
+ register struct fs *fs = fp->f_fs;
+
+ if (!buf)
+ buf = malloc(fs->fs_bsize);
+ rc = block_map(f, (daddr_t)0, &disk_block);
+ if (rc)
+ goto out;
+
+ twiddle();
+ rc = (f->f_dev->dv_strategy)(f->f_devdata,
+ F_READ, fsbtodb(fs, disk_block),
+ fs->fs_bsize, buf, &buf_size);
+ if (rc)
+ goto out;
+
+ bcopy((char *)buf, namebuf, (unsigned)link_len);
+ }
+
+ /*
+ * If relative pathname, restart at parent directory.
+ * If absolute pathname, restart at root.
+ */
+ cp = namebuf;
+ if (*cp != '/')
+ inumber = parent_inumber;
+ else
+ inumber = (ino_t)ROOTINO;
+
+ if ((rc = read_inode(inumber, f)) != 0)
+ goto out;
+ }
+ }
+
+ /*
+ * Found terminal component.
+ */
+ rc = 0;
+out:
+ if (buf)
+ free(buf);
+ if (path)
+ free(path);
+ if (rc) {
+ if (fp->f_buf)
+ free(fp->f_buf);
+ free(fp->f_fs);
+ free(fp);
+ }
+ return (rc);
+}
+
+static int
+ufs_close(f)
+ struct open_file *f;
+{
+ register struct file *fp = (struct file *)f->f_fsdata;
+ int level;
+
+ f->f_fsdata = (void *)0;
+ if (fp == (struct file *)0)
+ return (0);
+
+ for (level = 0; level < NIADDR; level++) {
+ if (fp->f_blk[level])
+ free(fp->f_blk[level]);
+ }
+ if (fp->f_buf)
+ free(fp->f_buf);
+ free(fp->f_fs);
+ free(fp);
+ return (0);
+}
+
+/*
+ * Copy a portion of a file into kernel memory.
+ * Cross block boundaries when necessary.
+ */
+static int
+ufs_read(f, start, size, resid)
+ struct open_file *f;
+ void *start;
+ size_t size;
+ size_t *resid; /* out */
+{
+ register struct file *fp = (struct file *)f->f_fsdata;
+ register size_t csize;
+ char *buf;
+ size_t buf_size;
+ int rc = 0;
+ register char *addr = start;
+
+ while (size != 0) {
+ if (fp->f_seekp >= fp->f_di.di_size)
+ break;
+
+ rc = buf_read_file(f, &buf, &buf_size);
+ if (rc)
+ break;
+
+ csize = size;
+ if (csize > buf_size)
+ csize = buf_size;
+
+ bcopy(buf, addr, csize);
+
+ fp->f_seekp += csize;
+ addr += csize;
+ size -= csize;
+ }
+ if (resid)
+ *resid = size;
+ return (rc);
+}
+
+static off_t
+ufs_seek(f, offset, where)
+ struct open_file *f;
+ off_t offset;
+ int where;
+{
+ register struct file *fp = (struct file *)f->f_fsdata;
+
+ switch (where) {
+ case SEEK_SET:
+ fp->f_seekp = offset;
+ break;
+ case SEEK_CUR:
+ fp->f_seekp += offset;
+ break;
+ case SEEK_END:
+ fp->f_seekp = fp->f_di.di_size - offset;
+ break;
+ default:
+ return (-1);
+ }
+ return (fp->f_seekp);
+}
+
+static int
+ufs_stat(f, sb)
+ struct open_file *f;
+ struct stat *sb;
+{
+ register struct file *fp = (struct file *)f->f_fsdata;
+
+ /* only important stuff */
+ sb->st_mode = fp->f_di.di_mode;
+ sb->st_uid = fp->f_di.di_uid;
+ sb->st_gid = fp->f_di.di_gid;
+ sb->st_size = fp->f_di.di_size;
+ return (0);
+}
+
+#ifdef COMPAT_UFS
+/*
+ * Sanity checks for old file systems.
+ *
+ * XXX - goes away some day.
+ */
+static void
+ffs_oldfscompat(fs)
+ struct fs *fs;
+{
+ int i;
+
+ fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */
+ fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */
+ if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */
+ fs->fs_nrpos = 8; /* XXX */
+ if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */
+ quad_t sizepb = fs->fs_bsize; /* XXX */
+ /* XXX */
+ fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */
+ for (i = 0; i < NIADDR; i++) { /* XXX */
+ sizepb *= NINDIR(fs); /* XXX */
+ fs->fs_maxfilesize += sizepb; /* XXX */
+ } /* XXX */
+ fs->fs_qbmask = ~fs->fs_bmask; /* XXX */
+ fs->fs_qfmask = ~fs->fs_fmask; /* XXX */
+ } /* XXX */
+}
+#endif
diff --git a/lib/libstand/write.c b/lib/libstand/write.c
new file mode 100644
index 0000000..7c30926
--- /dev/null
+++ b/lib/libstand/write.c
@@ -0,0 +1,96 @@
+/* $NetBSD: write.c,v 1.7 1996/06/21 20:29:30 pk Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)write.c 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Author: Alessandro Forin
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include "stand.h"
+
+ssize_t
+write(fd, dest, bcount)
+ int fd;
+ void *dest;
+ size_t bcount;
+{
+ register struct open_file *f = &files[fd];
+ size_t resid;
+
+ if ((unsigned)fd >= SOPEN_MAX || !(f->f_flags & F_WRITE)) {
+ errno = EBADF;
+ return (-1);
+ }
+ if (f->f_flags & F_RAW) {
+ twiddle();
+ errno = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE,
+ btodb(f->f_offset), bcount, dest, &resid);
+ if (errno)
+ return (-1);
+ f->f_offset += resid;
+ return (resid);
+ }
+ resid = bcount;
+ if ((errno = (f->f_ops->fo_write)(f, dest, bcount, &resid)))
+ return (-1);
+ return (0);
+}
diff --git a/lib/libstand/zalloc.c b/lib/libstand/zalloc.c
new file mode 100644
index 0000000..16a4163
--- /dev/null
+++ b/lib/libstand/zalloc.c
@@ -0,0 +1,302 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * LIB/MEMORY/ZALLOC.C - self contained low-overhead memory pool/allocation
+ * subsystem
+ *
+ * This subsystem implements memory pools and memory allocation
+ * routines.
+ *
+ * Pools are managed via a linked list of 'free' areas. Allocating
+ * memory creates holes in the freelist, freeing memory fills them.
+ * Since the freelist consists only of free memory areas, it is possible
+ * to allocate the entire pool without incuring any structural overhead.
+ *
+ * The system works best when allocating similarly-sized chunks of
+ * memory. Care must be taken to avoid fragmentation when
+ * allocating/deallocating dissimilar chunks.
+ *
+ * When a memory pool is first allocated, the entire pool is marked as
+ * allocated. This is done mainly because we do not want to modify any
+ * portion of a pool's data area until we are given permission. The
+ * caller must explicitly deallocate portions of the pool to make them
+ * available.
+ *
+ * z[n]xalloc() works like z[n]alloc() but the allocation is made from
+ * within the specified address range. If the segment could not be
+ * allocated, NULL is returned. WARNING! The address range will be
+ * aligned to an 8 or 16 byte boundry depending on the cpu so if you
+ * give an unaligned address range, unexpected results may occur.
+ *
+ * If a standard allocation fails, the reclaim function will be called
+ * to recover some space. This usually causes other portions of the
+ * same pool to be released. Memory allocations at this low level
+ * should not block but you can do that too in your reclaim function
+ * if you want. Reclaim does not function when z[n]xalloc() is used,
+ * only for z[n]alloc().
+ *
+ * Allocation and frees of 0 bytes are valid operations.
+ */
+
+#include "zalloc_defs.h"
+
+/*
+ * znalloc() - allocate memory (without zeroing) from pool. Call reclaim
+ * and retry if appropriate, return NULL if unable to allocate
+ * memory.
+ */
+
+void *
+znalloc(MemPool *mp, iaddr_t bytes)
+{
+ /*
+ * align according to pool object size (can be 0). This is
+ * inclusive of the MEMNODE_SIZE_MASK minimum alignment.
+ *
+ */
+ bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK;
+
+ if (bytes == 0)
+ return((void *)-1);
+
+ /*
+ * locate freelist entry big enough to hold the object. If all objects
+ * are the same size, this is a constant-time function.
+ */
+
+ if (bytes <= mp->mp_Size - mp->mp_Used) {
+ MemNode **pmn;
+ MemNode *mn;
+
+ for (pmn = &mp->mp_First; (mn=*pmn) != NULL; pmn = &mn->mr_Next) {
+ if (bytes > mn->mr_Bytes)
+ continue;
+
+ /*
+ * Cut a chunk of memory out of the beginning of this
+ * block and fixup the link appropriately.
+ */
+
+ {
+ char *ptr = (char *)mn;
+
+ if (mn->mr_Bytes == bytes) {
+ *pmn = mn->mr_Next;
+ } else {
+ mn = (MemNode *)((char *)mn + bytes);
+ mn->mr_Next = ((MemNode *)ptr)->mr_Next;
+ mn->mr_Bytes = ((MemNode *)ptr)->mr_Bytes - bytes;
+ *pmn = mn;
+ }
+ mp->mp_Used += bytes;
+ return(ptr);
+ }
+ }
+ }
+
+ /*
+ * Memory pool is full, return NULL.
+ */
+
+ return(NULL);
+}
+
+/*
+ * zfree() - free previously allocated memory
+ */
+
+void
+zfree(MemPool *mp, void *ptr, iaddr_t bytes)
+{
+ /*
+ * align according to pool object size (can be 0). This is
+ * inclusive of the MEMNODE_SIZE_MASK minimum alignment.
+ */
+ bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK;
+
+ if (bytes == 0)
+ return;
+
+ /*
+ * panic if illegal pointer
+ */
+
+ if ((char *)ptr < (char *)mp->mp_Base ||
+ (char *)ptr + bytes > (char *)mp->mp_End ||
+ ((iaddr_t)ptr & MEMNODE_SIZE_MASK) != 0)
+ panic("zfree(%p,%d): wild pointer", ptr, bytes);
+
+ /*
+ * free the segment
+ */
+
+ {
+ MemNode **pmn;
+ MemNode *mn;
+
+ mp->mp_Used -= bytes;
+
+ for (pmn = &mp->mp_First; (mn = *pmn) != NULL; pmn = &mn->mr_Next) {
+ /*
+ * If area between last node and current node
+ * - check range
+ * - check merge with next area
+ * - check merge with previous area
+ */
+ if ((char *)ptr <= (char *)mn) {
+ /*
+ * range check
+ */
+ if ((char *)ptr + bytes > (char *)mn)
+ panic("zfree(%p,%d): corrupt memlist1",ptr, bytes);
+
+ /*
+ * merge against next area or create independant area
+ */
+
+ if ((char *)ptr + bytes == (char *)mn) {
+ ((MemNode *)ptr)->mr_Next = mn->mr_Next;
+ ((MemNode *)ptr)->mr_Bytes= bytes + mn->mr_Bytes;
+ } else {
+ ((MemNode *)ptr)->mr_Next = mn;
+ ((MemNode *)ptr)->mr_Bytes= bytes;
+ }
+ *pmn = mn = (MemNode *)ptr;
+
+ /*
+ * merge against previous area (if there is a previous
+ * area).
+ */
+
+ if (pmn != &mp->mp_First) {
+ if ((char*)pmn + ((MemNode*)pmn)->mr_Bytes == (char*)ptr) {
+ ((MemNode *)pmn)->mr_Next = mn->mr_Next;
+ ((MemNode *)pmn)->mr_Bytes += mn->mr_Bytes;
+ mn = (MemNode *)pmn;
+ }
+ }
+ return;
+ /* NOT REACHED */
+ }
+ if ((char *)ptr < (char *)mn + mn->mr_Bytes)
+ panic("zfree(%p,%d): corrupt memlist2", ptr, bytes);
+ }
+ /*
+ * We are beyond the last MemNode, append new MemNode. Merge against
+ * previous area if possible.
+ */
+ if (pmn == &mp->mp_First ||
+ (char *)pmn + ((MemNode *)pmn)->mr_Bytes != (char *)ptr
+ ) {
+ ((MemNode *)ptr)->mr_Next = NULL;
+ ((MemNode *)ptr)->mr_Bytes = bytes;
+ *pmn = (MemNode *)ptr;
+ mn = (MemNode *)ptr;
+ } else {
+ ((MemNode *)pmn)->mr_Bytes += bytes;
+ mn = (MemNode *)pmn;
+ }
+ }
+}
+
+/*
+ * zextendPool() - extend memory pool to cover additional space.
+ *
+ * Note: the added memory starts out as allocated, you
+ * must free it to make it available to the memory subsystem.
+ *
+ * Note: mp_Size may not reflect (mp_End - mp_Base) range
+ * due to other parts of the system doing their own sbrk()
+ * calls.
+ */
+
+void
+zextendPool(MemPool *mp, void *base, iaddr_t bytes)
+{
+ if (mp->mp_Size == 0) {
+ mp->mp_Base = base;
+ mp->mp_Used = bytes;
+ mp->mp_End = (char *)base + bytes;
+ } else {
+ void *pend = (char *)mp->mp_Base + mp->mp_Size;
+
+ if (base < mp->mp_Base) {
+ /* mp->mp_Size += (char *)mp->mp_Base - (char *)base; */
+ mp->mp_Used += (char *)mp->mp_Base - (char *)base;
+ mp->mp_Base = base;
+ }
+ base = (char *)base + bytes;
+ if (base > pend) {
+ /* mp->mp_Size += (char *)base - (char *)pend; */
+ mp->mp_Used += (char *)base - (char *)pend;
+ mp->mp_End = (char *)base;
+ }
+ }
+ mp->mp_Size += bytes;
+}
+
+#ifdef ZALLOCDEBUG
+
+void
+zallocstats(MemPool *mp)
+{
+ int abytes = 0;
+ int hbytes = 0;
+ int fcount = 0;
+ MemNode *mn;
+
+ printf("%d bytes reserved", (int) mp->mp_Size);
+
+ mn = mp->mp_First;
+
+ if ((void *)mn != (void *)mp->mp_Base) {
+ abytes += (char *)mn - (char *)mp->mp_Base;
+ }
+
+ while (mn) {
+ if ((char *)mn + mn->mr_Bytes != mp->mp_End) {
+ hbytes += mn->mr_Bytes;
+ ++fcount;
+ }
+ if (mn->mr_Next)
+ abytes += (char *)mn->mr_Next - ((char *)mn + mn->mr_Bytes);
+ mn = mn->mr_Next;
+ }
+ printf(" %d bytes allocated\n%d fragments (%d bytes fragmented)\n",
+ abytes,
+ fcount,
+ hbytes
+ );
+}
+
+#endif
+
diff --git a/lib/libstand/zalloc_defs.h b/lib/libstand/zalloc_defs.h
new file mode 100644
index 0000000..00696d6
--- /dev/null
+++ b/lib/libstand/zalloc_defs.h
@@ -0,0 +1,87 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * DEFS.H
+ */
+
+#define USEGUARD /* use stard/end guard bytes */
+#define USEENDGUARD
+#define DMALLOCDEBUG /* add debugging code to gather stats */
+#define ZALLOCDEBUG
+
+#include <string.h>
+#include "stand.h"
+
+#ifdef __i386__
+typedef unsigned int iaddr_t; /* unsigned int same size as pointer */
+typedef int saddr_t; /* signed int same size as pointer */
+#endif
+#ifdef __alpha__
+typedef unsigned long iaddr_t; /* unsigned int same size as pointer */
+typedef long saddr_t; /* signed int same size as pointer */
+#endif
+
+#include "zalloc_mem.h"
+
+#define Prototype extern
+#define Library extern
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+/*
+ * block extension for sbrk()
+ */
+
+#define BLKEXTEND (4 * 1024)
+#define BLKEXTENDMASK (BLKEXTEND - 1)
+
+/*
+ * required malloc alignment. Use sizeof(long double) for architecture
+ * independance.
+ *
+ * Note: if we implement a more sophisticated realloc, we should ensure that
+ * MALLOCALIGN is at least as large as MemNode.
+ */
+
+typedef struct Guard {
+ size_t ga_Bytes;
+ size_t ga_Magic; /* must be at least 32 bits */
+} Guard;
+
+#define MATYPE long double
+#define MALLOCALIGN ((sizeof(MATYPE) > sizeof(Guard)) ? sizeof(MATYPE) : sizeof(Guard))
+#define GAMAGIC 0x55FF44FD
+
+#include "zalloc_protos.h"
+
diff --git a/lib/libstand/zalloc_malloc.c b/lib/libstand/zalloc_malloc.c
new file mode 100644
index 0000000..83e5290
--- /dev/null
+++ b/lib/libstand/zalloc_malloc.c
@@ -0,0 +1,197 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk
+ */
+
+#include "zalloc_defs.h"
+
+static MemPool MallocPool;
+
+#ifdef DMALLOCDEBUG
+static int MallocMax;
+static int MallocCount;
+
+void mallocstats(void);
+#endif
+
+#ifdef malloc
+#undef malloc
+#undef free
+#endif
+
+#ifdef __alpha__
+void
+free_region(void *start, void *end)
+{
+ zextendPool(&MallocPool, start, (caddr_t)end - (caddr_t)start);
+ zfree(&MallocPool, start, (caddr_t)end - (caddr_t)start);
+}
+#endif
+
+void *
+malloc(size_t bytes)
+{
+ Guard *res;
+
+#ifdef USEENDGUARD
+ bytes += MALLOCALIGN + 1;
+#else
+ bytes += MALLOCALIGN;
+#endif
+
+ while ((res = znalloc(&MallocPool, bytes)) == NULL) {
+ int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK;
+ char *base;
+
+ if ((base = sbrk(incr)) == (char *)-1)
+ return(NULL);
+ zextendPool(&MallocPool, base, incr);
+ zfree(&MallocPool, base, incr);
+ }
+#ifdef DMALLOCDEBUG
+ if (++MallocCount > MallocMax)
+ MallocMax = MallocCount;
+#endif
+#ifdef USEGUARD
+ res->ga_Magic = GAMAGIC;
+#endif
+ res->ga_Bytes = bytes;
+#ifdef USEENDGUARD
+ *((char *)res + bytes - 1) = -2;
+#endif
+ return((char *)res + MALLOCALIGN);
+}
+
+void
+free(void *ptr)
+{
+ size_t bytes;
+
+ if (ptr != NULL) {
+ Guard *res = (void *)((char *)ptr - MALLOCALIGN);
+
+#ifdef USEGUARD
+ if (res->ga_Magic != GAMAGIC)
+ panic("free: guard1 fail @ %p", ptr);
+ res->ga_Magic = -1;
+#endif
+#ifdef USEENDGUARD
+ if (*((char *)res + res->ga_Bytes - 1) != -2)
+ panic("free: guard2 fail @ %p + %d", ptr, res->ga_Bytes - MALLOCALIGN);
+ *((char *)res + res->ga_Bytes - 1) = -1;
+#endif
+
+ bytes = res->ga_Bytes;
+ zfree(&MallocPool, res, bytes);
+#ifdef DMALLOCDEBUG
+ --MallocCount;
+#endif
+ }
+}
+
+
+void *
+calloc(size_t n1, size_t n2)
+{
+ iaddr_t bytes = (iaddr_t)n1 * (iaddr_t)n2;
+ void *res;
+
+ if ((res = malloc(bytes)) != NULL) {
+ bzero(res, bytes);
+#ifdef DMALLOCDEBUG
+ if (++MallocCount > MallocMax)
+ MallocMax = MallocCount;
+#endif
+ }
+ return(res);
+}
+
+/*
+ * realloc() - I could be fancier here and free the old buffer before
+ * allocating the new one (saving potential fragmentation
+ * and potential buffer copies). But I don't bother.
+ */
+
+void *
+realloc(void *ptr, size_t size)
+{
+ void *res;
+ size_t old;
+
+ if ((res = malloc(size)) != NULL) {
+ if (ptr) {
+ old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN;
+ if (old < size)
+ bcopy(ptr, res, old);
+ else
+ bcopy(ptr, res, size);
+ free(ptr);
+ } else {
+#ifdef DMALLOCDEBUG
+ if (++MallocCount > MallocMax)
+ MallocMax = MallocCount;
+#ifdef EXITSTATS
+ if (DidAtExit == 0) {
+ DidAtExit = 1;
+ atexit(mallocstats);
+ }
+#endif
+#endif
+ }
+ }
+ return(res);
+}
+
+void *
+reallocf(void *ptr, size_t size)
+{
+ void *res;
+
+ if ((res = realloc(ptr, size)) == NULL)
+ free(ptr);
+ return(res);
+}
+
+#ifdef DMALLOCDEBUG
+
+void
+mallocstats(void)
+{
+ printf("Active Allocations: %d/%d\n", MallocCount, MallocMax);
+#ifdef ZALLOCDEBUG
+ zallocstats(&MallocPool);
+#endif
+}
+
+#endif
+
diff --git a/lib/libstand/zalloc_mem.h b/lib/libstand/zalloc_mem.h
new file mode 100644
index 0000000..c872da1
--- /dev/null
+++ b/lib/libstand/zalloc_mem.h
@@ -0,0 +1,55 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * H/MEM.H
+ *
+ * Basic memory pool / memory node structures.
+ */
+
+typedef struct MemNode {
+ struct MemNode *mr_Next;
+ iaddr_t mr_Bytes;
+} MemNode;
+
+typedef struct MemPool {
+ void *mp_Base;
+ void *mp_End;
+ MemNode *mp_First;
+ iaddr_t mp_Size;
+ iaddr_t mp_Used;
+} MemPool;
+
+#define MEMNODE_SIZE_MASK ((sizeof(MemNode) <= 8) ? 7 : 15)
+
+#define ZNOTE_FREE 0
+#define ZNOTE_REUSE 1
+
diff --git a/lib/libstand/zalloc_protos.h b/lib/libstand/zalloc_protos.h
new file mode 100644
index 0000000..c90bd5a
--- /dev/null
+++ b/lib/libstand/zalloc_protos.h
@@ -0,0 +1,35 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+Library void *znalloc(struct MemPool *mpool, iaddr_t bytes);
+Library void zfree(struct MemPool *mpool, void *ptr, iaddr_t bytes);
+Library void zextendPool(MemPool *mp, void *base, iaddr_t bytes);
+Library void zallocstats(struct MemPool *mp);
diff --git a/lib/libstand/zipfs.c b/lib/libstand/zipfs.c
new file mode 100644
index 0000000..b0e3007
--- /dev/null
+++ b/lib/libstand/zipfs.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 1998 Michael Smith.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include "stand.h"
+
+#include <sys/stat.h>
+#include <string.h>
+#include <zlib.h>
+
+#define Z_BUFSIZE 2048 /* XXX larger? */
+
+struct z_file
+{
+ int zf_rawfd;
+ z_stream zf_zstream;
+ char zf_buf[Z_BUFSIZE];
+};
+
+static int zf_fill(struct z_file *z);
+static int zf_open(const char *path, struct open_file *f);
+static int zf_close(struct open_file *f);
+static int zf_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t zf_seek(struct open_file *f, off_t offset, int where);
+static int zf_stat(struct open_file *f, struct stat *sb);
+
+struct fs_ops zipfs_fsops = {
+ "zip",
+ zf_open,
+ zf_close,
+ zf_read,
+ null_write,
+ zf_seek,
+ zf_stat
+};
+
+#if 0
+void *
+calloc(int items, size_t size)
+{
+ return(malloc(items * size));
+}
+#endif
+
+static int
+zf_fill(struct z_file *zf)
+{
+ int result;
+ int req;
+
+ req = Z_BUFSIZE - zf->zf_zstream.avail_in;
+ result = 0;
+
+ /* If we need more */
+ if (req > 0) {
+ /* move old data to bottom of buffer */
+ if (req < Z_BUFSIZE)
+ bcopy(zf->zf_buf + req, zf->zf_buf, Z_BUFSIZE - req);
+
+ /* read to fill buffer and update availibility data */
+ result = read(zf->zf_rawfd, zf->zf_buf + zf->zf_zstream.avail_in, req);
+ zf->zf_zstream.next_in = zf->zf_buf;
+ if (result >= 0)
+ zf->zf_zstream.avail_in += result;
+ }
+ return(result);
+}
+
+/*
+ * Adapted from get_byte/check_header in libz
+ *
+ * Returns 0 if the header is OK, nonzero if not.
+ */
+static int
+get_byte(struct z_file *zf)
+{
+ if ((zf->zf_zstream.avail_in == 0) && (zf_fill(zf) == -1))
+ return(-1);
+ zf->zf_zstream.avail_in--;
+ return(*(zf->zf_zstream.next_in)++);
+}
+
+static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define RESERVED 0xE0 /* bits 5..7: reserved */
+
+static int
+check_header(struct z_file *zf)
+{
+ int method; /* method byte */
+ int flags; /* flags byte */
+ uInt len;
+ int c;
+
+ /* Check the gzip magic header */
+ for (len = 0; len < 2; len++) {
+ c = get_byte(zf);
+ if (c != gz_magic[len]) {
+ return(1);
+ }
+ }
+ method = get_byte(zf);
+ flags = get_byte(zf);
+ if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+ return(1);
+ }
+
+ /* Discard time, xflags and OS code: */
+ for (len = 0; len < 6; len++) (void)get_byte(zf);
+
+ if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+ len = (uInt)get_byte(zf);
+ len += ((uInt)get_byte(zf))<<8;
+ /* len is garbage if EOF but the loop below will quit anyway */
+ while (len-- != 0 && get_byte(zf) != -1) ;
+ }
+ if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+ while ((c = get_byte(zf)) != 0 && c != -1) ;
+ }
+ if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
+ while ((c = get_byte(zf)) != 0 && c != -1) ;
+ }
+ if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
+ for (len = 0; len < 2; len++) c = get_byte(zf);
+ }
+ /* if there's data left, we're in business */
+ return((c == -1) ? 1 : 0);
+}
+
+static int
+zf_open(const char *fname, struct open_file *f)
+{
+ static char *zfname;
+ int rawfd;
+ struct z_file *zf;
+ char *cp;
+ int error;
+ struct stat sb;
+
+ /* Have to be in "just read it" mode */
+ if (f->f_flags != F_READ)
+ return(EPERM);
+
+ /* If the name already ends in .gz, ignore it */
+ if ((cp = strrchr(fname, '.')) && !strcmp(cp, ".gz"))
+ return(ENOENT);
+
+ /* Construct new name */
+ zfname = malloc(strlen(fname) + 4);
+ sprintf(zfname, "%s.gz", fname);
+
+ /* Try to open the compressed datafile */
+ rawfd = open(zfname, O_RDONLY);
+ free(zfname);
+ if (rawfd == -1)
+ return(ENOENT);
+
+ if (fstat(rawfd, &sb) < 0) {
+ printf("zf_open: stat failed\n");
+ close(rawfd);
+ return(ENOENT);
+ }
+ if (!S_ISREG(sb.st_mode)) {
+ printf("zf_open: not a file\n");
+ close(rawfd);
+ return(EISDIR); /* best guess */
+ }
+
+ /* Allocate a z_file structure, populate it */
+ zf = malloc(sizeof(struct z_file));
+ bzero(zf, sizeof(struct z_file));
+ zf->zf_rawfd = rawfd;
+
+ /* Verify that the file is gzipped (XXX why do this afterwards?) */
+ if (check_header(zf)) {
+ close(zf->zf_rawfd);
+ inflateEnd(&(zf->zf_zstream));
+ free(zf);
+ return(EFTYPE);
+ }
+
+ /* Initialise the inflation engine */
+ if ((error = inflateInit2(&(zf->zf_zstream), -15)) != Z_OK) {
+ printf("zf_open: inflateInit returned %d : %s\n", error, zf->zf_zstream.msg);
+ close(zf->zf_rawfd);
+ free(zf);
+ return(EIO);
+ }
+
+ /* Looks OK, we'll take it */
+ f->f_fsdata = zf;
+ return(0);
+}
+
+static int
+zf_close(struct open_file *f)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+
+ inflateEnd(&(zf->zf_zstream));
+ close(zf->zf_rawfd);
+ free(zf);
+ return(0);
+}
+
+static int
+zf_read(struct open_file *f, void *buf, size_t size, size_t *resid)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+ int error;
+
+ zf->zf_zstream.next_out = buf; /* where and how much */
+ zf->zf_zstream.avail_out = size;
+
+ while (zf->zf_zstream.avail_out) {
+ if ((zf->zf_zstream.avail_in == 0) && (zf_fill(zf) == -1)) {
+ printf("zf_read: fill error\n");
+ return(-1);
+ }
+ if (zf->zf_zstream.avail_in == 0) { /* oops, unexpected EOF */
+ printf("zf_read: unexpected EOF\n");
+ break;
+ }
+
+ error = inflate(&zf->zf_zstream, Z_SYNC_FLUSH); /* decompression pass */
+ if (error == Z_STREAM_END) { /* EOF, all done */
+ break;
+ }
+ if (error != Z_OK) { /* argh, decompression error */
+ printf("inflate: %s\n", zf->zf_zstream.msg);
+ errno = EIO;
+ return(-1);
+ }
+ }
+ if (resid != NULL)
+ *resid = zf->zf_zstream.avail_out;
+ return(0);
+}
+
+static off_t
+zf_seek(struct open_file *f, off_t offset, int where)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+ off_t target;
+ char discard[16];
+
+ switch (where) {
+ case SEEK_SET:
+ target = offset;
+ break;
+ case SEEK_CUR:
+ target = offset + zf->zf_zstream.total_out;
+ break;
+ default:
+ target = -1;
+ }
+
+ /* Can we get there from here? */
+ if (target < zf->zf_zstream.total_out) {
+ errno = EOFFSET;
+ return -1;
+ }
+
+ /* skip forwards if required */
+ while (target > zf->zf_zstream.total_out) {
+ if (zf_read(f, discard, min(sizeof(discard), target - zf->zf_zstream.total_out), NULL) == -1)
+ return(-1);
+ }
+ /* This is where we are (be honest if we overshot) */
+ return (zf->zf_zstream.total_out);
+}
+
+
+static int
+zf_stat(struct open_file *f, struct stat *sb)
+{
+ struct z_file *zf = (struct z_file *)f->f_fsdata;
+ int result;
+
+ /* stat as normal, but indicate that size is unknown */
+ if ((result = fstat(zf->zf_rawfd, sb)) == 0)
+ sb->st_size = -1;
+ return(result);
+}
+
+
+
diff --git a/lib/libtacplus/Makefile b/lib/libtacplus/Makefile
new file mode 100644
index 0000000..798a8e0
--- /dev/null
+++ b/lib/libtacplus/Makefile
@@ -0,0 +1,41 @@
+# Copyright 1998 Juniper Networks, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+LIB= tacplus
+SRCS= taclib.c
+CFLAGS+= -Wall
+DPADD+= ${LIBMD}
+LDADD+= -lmd
+SHLIB_MAJOR= 1
+SHLIB_MINOR= 0
+MAN3+= libtacplus.3
+MAN5+= tacplus.conf.5
+
+beforeinstall:
+ ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/taclib.h ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libtacplus/libtacplus.3 b/lib/libtacplus/libtacplus.3
new file mode 100644
index 0000000..146a235
--- /dev/null
+++ b/lib/libtacplus/libtacplus.3
@@ -0,0 +1,347 @@
+.\" Copyright 1998 Juniper Networks, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 2, 1998
+.Dt LIBTACPLUS 3
+.Os FreeBSD
+.Sh NAME
+.Nm libtacplus
+.Nd TACACS+ client library
+.Sh SYNOPSIS
+.Fd #include <taclib.h>
+.Ft int
+.Fn tac_add_server "struct tac_handle *h" "const char *host" "int port" "const char *secret" "int timeout" "int flags"
+.Ft void
+.Fn tac_close "struct tac_handle *h"
+.Ft int
+.Fn tac_config "struct tac_handle *h" "const char *path"
+.Ft int
+.Fn tac_create_authen "struct tac_handle *h" "int action" "int type" "int service"
+.Ft void *
+.Fn tac_get_data "struct tac_handle *h" "size_t *len"
+.Ft char *
+.Fn tac_get_msg "struct tac_handle *h"
+.Ft struct tac_handle *
+.Fn tac_open "void"
+.Ft int
+.Fn tac_send_authen "struct tac_handle *h"
+.Ft int
+.Fn tac_set_data "struct tac_handle *h" "const void *data" "size_t data_len"
+.Ft int
+.Fn tac_set_msg "struct tac_handle *h" "const char *msg"
+.Ft int
+.Fn tac_set_port "struct tac_handle *h" "const char *port"
+.Ft int
+.Fn tac_set_priv "struct tac_handle *h" "int priv"
+.Ft int
+.Fn tac_set_rem_addr "struct tac_handle *h" "const char *addr"
+.Ft int
+.Fn tac_set_user "struct tac_handle *h" "const char *user"
+.Ft const char *
+.Fn tac_strerror "struct tac_handle *h"
+.Sh DESCRIPTION
+The
+.Nm
+library implements the client side of the TACACS+ network access
+control protocol. TACACS+ allows clients to perform authentication,
+authorization, and accounting by means of network requests to remote
+servers. This library currently supports only the authentication
+portion of the protocol.
+.Sh INITIALIZATION
+To use the library, an application must first call
+.Fn tac_open
+to obtain a
+.Va struct tac_handle * ,
+which provides context for subsequent operations.
+Calls to
+.Fn tac_open
+always succeed unless insufficient virtual memory is available. If
+the necessary memory cannot be allocated,
+.Fn tac_open
+returns
+.Dv NULL .
+.Pp
+Before issuing any TACACS+ requests, the library must be made aware
+of the servers it can contact. The easiest way to configure the
+library is to call
+.Fn tac_config .
+.Fn tac_config
+causes the library to read a configuration file whose format is
+described in
+.Xr tacplus.conf 5 .
+The pathname of the configuration file is passed as the
+.Va file
+argument to
+.Fn tac_config .
+This argument may also be given as
+.Dv NULL ,
+in which case the standard configuration file
+.Pa /etc/tacplus.conf
+is used.
+.Fn tac_config
+returns 0 on success, or -1 if an error occurs.
+.Pp
+The library can also be configured programmatically by calls to
+.Fn tac_add_server .
+The
+.Va host
+parameter specifies the server host, either as a fully qualified
+domain name or as a dotted-quad IP address in text form.
+The
+.Va port
+parameter specifies the TCP port to contact on the server. If
+.Va port
+is given as 0, the library uses port 49, the standard TACACS+ port.
+The shared secret for the server host is passed to the
+.Va secret
+parameter. It may be any null-terminated string of bytes.
+The timeout for receiving replies from the server is passed to the
+.Va timeout
+parameter, in units of seconds.
+The
+.Va flags
+parameter is a bit mask of flags to specify various characteristics of
+the server. It may contain:
+.Pp
+.Bl -tag -width Fl
+.It Dv TAC_SRVR_SINGLE_CONNECT
+Causes the library to attempt to negotiate single connection mode
+when communicating with the server. In single connection mode, the
+original TCP connection is held open for multiple TACACS+ sessions.
+Older servers do not support this mode, and some of them become
+confused if the client attempts to negotiate it.
+.El
+.Pp
+.Fn tac_add_server
+returns 0 on success, or -1 if an error occurs.
+.Pp
+.Fn tac_add_server
+may be called multiple times, and it may be used together with
+.Fn tac_config .
+At most 10 servers may be specified.
+When multiple servers are given, they are tried in round-robin
+fashion until a working, accessible server is found. Once the
+library finds such a server, it continues to use it as long as it
+works.
+.Sh CREATING A TACACS+ AUTHENTICATION REQUEST
+To begin constructing a new authentication request, call
+.Fn tac_create_authen .
+The
+.Va action ,
+.Va type ,
+and
+.Va service
+arguments must be be set to appropriate values as defined in the
+TACACS+ protocol specification. The
+.Aq taclib.h
+header file contains symbolic constants for these values.
+.Pp
+After creating a request with
+.Fn tac_create_authen ,
+various optional parameters may be attached to it through calls to
+.Fn tac_set_data ,
+.Fn tac_set_port ,
+.Fn tac_set_priv ,
+.Fn tac_set_rem_addr ,
+and
+.Fn tac_set_user .
+The library creates its own copies of any strings provided to these
+functions, so that it is not necessary for the caller to preserve
+them. By default, each of these parameters is empty except for the
+privilege level, which defaults to
+.Ql USER
+privilege.
+.Sh SENDING THE AUTHENTICATION REQUEST AND RECEIVING THE RESPONSE
+After the TACACS+ request has been constructed, it is sent by means
+of
+.Fn tac_send_authen .
+This function connects to a server if not already connected, sends
+the request, and waits for a reply. On failure,
+.Fn tac_send_authen
+returns -1. Otherwise, it returns the TACACS+ status code and flags,
+packed into an integer value. The status can be extracted using the
+macro
+.Fn TAC_AUTHEN_STATUS .
+Possible status codes, defined in
+.Aq taclib.h ,
+include:
+.Pp
+.Bl -item -compact -offset indent
+.It
+.Dv TAC_AUTHEN_STATUS_PASS
+.It
+.Dv TAC_AUTHEN_STATUS_FAIL
+.It
+.Dv TAC_AUTHEN_STATUS_GETDATA
+.It
+.Dv TAC_AUTHEN_STATUS_GETUSER
+.It
+.Dv TAC_AUTHEN_STATUS_GETPASS
+.It
+.Dv TAC_AUTHEN_STATUS_RESTART
+.It
+.Dv TAC_AUTHEN_STATUS_ERROR
+.It
+.Dv TAC_AUTHEN_STATUS_FOLLOW
+.El
+.Pp
+The only flag is the no-echo flag, which can be tested using the
+macro
+.Fn TAC_AUTHEN_NOECHO .
+.Sh EXTRACTING INFORMATION FROM THE SERVER'S RESPONSE
+An authentication response packet from the server may contain a
+server message, a data string, or both. After a successful call to
+.Fn tac_send_authen ,
+this information may be retrieved from the response by calling
+.Fn tac_get_msg
+and
+.Fn tac_get_data .
+These functions return dynamically-allocated copies of the
+information from the packet. The caller is responsible for freeing
+the copies when it no longer needs them. The data returned from
+these functions is guaranteed to be terminated by a null byte.
+.Pp
+In the case of
+.Fn tac_get_data ,
+the
+.Va len
+argument points to a location into which the library will store the
+actual length of the received data, not including the null
+terminator. This argument may be given as
+.Dv NULL
+if the caller is not interested in the length.
+.Sh SENDING AUTHENTICATION CONTINUE PACKETS
+If
+.Fn tac_send_authen
+returns a value containing one of the status codes
+.Dv TAC_AUTHEN_STATUS_GETDATA ,
+.Dv TAC_AUTHEN_STATUS_GETUSER ,
+or
+.Dv TAC_AUTHEN_STATUS_GETPASS ,
+then the client must provide additional information to the server by
+means of a TACACS+ CONTINUE packet. To do so, the application must
+first set the packet's user message and/or data fields using
+.Fn tac_set_msg
+and
+.Fn tac_set_data .
+The client then sends the CONTINUE packet with
+.Fn tac_send_authen .
+N.B.,
+.Fn tac_create_authen
+should
+.Em not
+be called to construct a CONTINUE packet; it is used only for the
+initial authentication request.
+.Pp
+When it receives the CONTINUE packet, the server may again request
+more information by returning
+.Dv TAC_AUTHEN_STATUS_GETDATA ,
+.Dv TAC_AUTHEN_STATUS_GETUSER ,
+or
+.Dv TAC_AUTHEN_STATUS_GETPASS .
+The application should send further CONTINUEs until some other
+status is received from the server.
+.Sh OBTAINING ERROR MESSAGES
+Those functions which accept a
+.Va struct tac_handle *
+argument record an error message if they fail. The error message
+can be retrieved by calling
+.Fn tac_strerror .
+The message text is overwritten on each new error for the given
+.Va struct tac_handle * .
+Thus the message must be copied if it is to be preserved through
+subsequent library calls using the same handle.
+.Sh CLEANUP
+To free the resources used by the TACACS+ library, call
+.Fn tac_close .
+.Sh RETURN VALUES
+The following functions return a non-negative value on success. If
+they detect an error, they return -1 and record an error message
+which can be retrieved using
+.Fn tac_strerror .
+.Pp
+.Bl -item -offset indent -compact
+.It
+.Fn tac_add_server
+.It
+.Fn tac_config
+.It
+.Fn tac_create_authen
+.It
+.Fn tac_send_authen
+.It
+.Fn tac_set_data
+.It
+.Fn tac_set_msg
+.It
+.Fn tac_set_port
+.It
+.Fn tac_set_priv
+.It
+.Fn tac_set_rem_addr
+.It
+.Fn tac_set_user
+.El
+.Pp
+The following functions return a
+.No non- Ns Dv NULL
+pointer on success. If they are unable to allocate sufficient
+virtual memory, they return
+.Dv NULL
+and record an error message which can be retrieved using
+.Fn tac_strerror .
+.Pp
+.Bl -item -offset indent -compact
+.It
+.Fn tac_get_data
+.It
+.Fn tac_get_msg
+.El
+.Pp
+The following functions return a
+.No non- Ns Dv NULL
+pointer on success. If they are unable to allocate sufficient
+virtual memory, they return
+.Dv NULL ,
+without recording an error message.
+.Pp
+.Bl -item -offset indent -compact
+.It
+.Fn tac_open
+.El
+.Sh FILES
+.Pa /etc/tacplus.conf
+.Sh SEE ALSO
+.Xr tacplus.conf 5
+.Rs
+.%A D. Carrel and Lol Grant
+.%T The TACACS+ Protocol, Version 1.78
+.%O draft-grant-tacacs-02.txt (Internet Draft)
+.Re
+.Sh AUTHORS
+This software was written by
+.An John Polstra ,
+and donated to the FreeBSD project by Juniper Networks, Inc.
diff --git a/lib/libtacplus/taclib.c b/lib/libtacplus/taclib.c
new file mode 100644
index 0000000..bd2e663
--- /dev/null
+++ b/lib/libtacplus/taclib.c
@@ -0,0 +1,1053 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <md5.h>
+#include <netdb.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "taclib_private.h"
+
+static int add_str_8(struct tac_handle *, u_int8_t *,
+ struct clnt_str *);
+static int add_str_16(struct tac_handle *, u_int16_t *,
+ struct clnt_str *);
+static int authen_version(int, int);
+static void close_connection(struct tac_handle *);
+static int conn_server(struct tac_handle *);
+static void crypt_msg(struct tac_handle *, struct tac_msg *);
+static void *dup_str(struct tac_handle *, const struct srvr_str *,
+ size_t *);
+static int establish_connection(struct tac_handle *);
+static void free_str(struct clnt_str *);
+static void generr(struct tac_handle *, const char *, ...)
+ __printflike(2, 3);
+static void gen_session_id(struct tac_msg *);
+static int get_srvr_end(struct tac_handle *);
+static int get_srvr_str(struct tac_handle *, struct srvr_str *,
+ size_t);
+static void init_clnt_str(struct clnt_str *);
+static void init_srvr_str(struct srvr_str *);
+static int read_timed(struct tac_handle *, void *, size_t,
+ const struct timeval *);
+static int recv_msg(struct tac_handle *);
+static int save_str(struct tac_handle *, struct clnt_str *,
+ const void *, size_t);
+static int send_msg(struct tac_handle *);
+static int split(char *, char *[], int, char *, size_t);
+static void *xmalloc(struct tac_handle *, size_t);
+static char *xstrdup(struct tac_handle *, const char *);
+
+/*
+ * Append some optional data to the current request, and store its
+ * length into the 8-bit field referenced by "fld". Returns 0 on
+ * success, or -1 on failure.
+ *
+ * This function also frees the "cs" string data and initializes it
+ * for the next time.
+ */
+static int
+add_str_8(struct tac_handle *h, u_int8_t *fld, struct clnt_str *cs)
+{
+ u_int16_t len;
+
+ if (add_str_16(h, &len, cs) == -1)
+ return -1;
+ len = ntohs(len);
+ if (len > 0xff) {
+ generr(h, "Field too long");
+ return -1;
+ }
+ *fld = len;
+ return 0;
+}
+
+/*
+ * Append some optional data to the current request, and store its
+ * length into the 16-bit field (network byte order) referenced by
+ * "fld". Returns 0 on success, or -1 on failure.
+ *
+ * This function also frees the "cs" string data and initializes it
+ * for the next time.
+ */
+static int
+add_str_16(struct tac_handle *h, u_int16_t *fld, struct clnt_str *cs)
+{
+ size_t len;
+
+ len = cs->len;
+ if (cs->data == NULL)
+ len = 0;
+ if (len != 0) {
+ int offset;
+
+ if (len > 0xffff) {
+ generr(h, "Field too long");
+ return -1;
+ }
+ offset = ntohl(h->request.length);
+ if (offset + len > BODYSIZE) {
+ generr(h, "Message too long");
+ return -1;
+ }
+ memcpy(h->request.u.body + offset, cs->data, len);
+ h->request.length = htonl(offset + len);
+ }
+ *fld = htons(len);
+ free_str(cs);
+ return 0;
+}
+
+static int
+authen_version(int action, int type)
+{
+ int minor;
+
+ switch (action) {
+
+ case TAC_AUTHEN_LOGIN:
+ switch (type) {
+
+ case TAC_AUTHEN_TYPE_PAP:
+ case TAC_AUTHEN_TYPE_CHAP:
+ case TAC_AUTHEN_TYPE_MSCHAP:
+ case TAC_AUTHEN_TYPE_ARAP:
+ minor = 1;
+ break;
+
+ default:
+ minor = 0;
+ break;
+ }
+ break;
+
+ case TAC_AUTHEN_SENDAUTH:
+ minor = 1;
+ break;
+
+ default:
+ minor = 0;
+ break;
+ };
+
+ return TAC_VER_MAJOR << 4 | minor;
+}
+
+static void
+close_connection(struct tac_handle *h)
+{
+ if (h->fd != -1) {
+ close(h->fd);
+ h->fd = -1;
+ }
+}
+
+static int
+conn_server(struct tac_handle *h)
+{
+ const struct tac_server *srvp = &h->servers[h->cur_server];
+ int flags;
+
+ if ((h->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+ generr(h, "Cannot create socket: %s", strerror(errno));
+ return -1;
+ }
+ if ((flags = fcntl(h->fd, F_GETFL, 0)) == -1 ||
+ fcntl(h->fd, F_SETFL, flags | O_NONBLOCK) == -1) {
+ generr(h, "Cannot set non-blocking mode on socket: %s",
+ strerror(errno));
+ close(h->fd);
+ h->fd = -1;
+ return -1;
+ }
+ if (connect(h->fd, (struct sockaddr *)&srvp->addr,
+ sizeof srvp->addr) == 0)
+ return 0;
+
+ if (errno == EINPROGRESS) {
+ fd_set wfds;
+ struct timeval tv;
+ int nfds;
+ struct sockaddr peer;
+ int peerlen;
+ int err;
+ int errlen;
+
+ /* Wait for the connection to complete. */
+ FD_ZERO(&wfds);
+ FD_SET(h->fd, &wfds);
+ tv.tv_sec = srvp->timeout;
+ tv.tv_usec = 0;
+ nfds = select(h->fd + 1, NULL, &wfds, NULL, &tv);
+ if (nfds == -1) {
+ generr(h, "select: %s", strerror(errno));
+ close(h->fd);
+ h->fd = -1;
+ return -1;
+ }
+ if (nfds == 0) {
+ generr(h, "connect: timed out");
+ close(h->fd);
+ h->fd = -1;
+ return -1;
+ }
+
+ /* See whether we are connected now. */
+ peerlen = sizeof peer;
+ if (getpeername(h->fd, &peer, &peerlen) == 0)
+ return 0;
+
+ if (errno != ENOTCONN) {
+ generr(h, "getpeername: %s", strerror(errno));
+ close(h->fd);
+ h->fd = -1;
+ return -1;
+ }
+
+ /* Find out why the connect failed. */
+ errlen = sizeof err;
+ getsockopt(h->fd, SOL_SOCKET, SO_ERROR, &err, &errlen);
+ errno = err;
+ }
+ generr(h, "connect: %s", strerror(errno));
+ close(h->fd);
+ h->fd = -1;
+ return -1;
+}
+
+/*
+ * Encrypt or decrypt a message. The operations are symmetrical.
+ */
+static void
+crypt_msg(struct tac_handle *h, struct tac_msg *msg)
+{
+ const char *secret;
+ MD5_CTX base_ctx;
+ MD5_CTX ctx;
+ unsigned char md5[16];
+ int chunk;
+ int msg_len;
+
+ secret = h->servers[h->cur_server].secret;
+ if (secret[0] == '\0')
+ msg->flags |= TAC_UNENCRYPTED;
+ if (msg->flags & TAC_UNENCRYPTED)
+ return;
+
+ msg_len = ntohl(msg->length);
+
+ MD5Init(&base_ctx);
+ MD5Update(&base_ctx, msg->session_id, sizeof msg->session_id);
+ MD5Update(&base_ctx, secret, strlen(secret));
+ MD5Update(&base_ctx, &msg->version, sizeof msg->version);
+ MD5Update(&base_ctx, &msg->seq_no, sizeof msg->seq_no);
+
+ ctx = base_ctx;
+ for (chunk = 0; chunk < msg_len; chunk += sizeof md5) {
+ int chunk_len;
+ int i;
+
+ MD5Final(md5, &ctx);
+
+ if ((chunk_len = msg_len - chunk) > sizeof md5)
+ chunk_len = sizeof md5;
+ for (i = 0; i < chunk_len; i++)
+ msg->u.body[chunk + i] ^= md5[i];
+
+ ctx = base_ctx;
+ MD5Update(&ctx, md5, sizeof md5);
+ }
+}
+
+/*
+ * Return a dynamically allocated copy of the given server string.
+ * The copy is null-terminated. If "len" is non-NULL, the length of
+ * the string (excluding the terminating null byte) is stored via it.
+ * Returns NULL on failure. Empty strings are still allocated even
+ * though they have no content.
+ */
+static void *
+dup_str(struct tac_handle *h, const struct srvr_str *ss, size_t *len)
+{
+ unsigned char *p;
+
+ if ((p = (unsigned char *)xmalloc(h, ss->len + 1)) == NULL)
+ return NULL;
+ if (ss->data != NULL && ss->len != 0)
+ memcpy(p, ss->data, ss->len);
+ p[ss->len] = '\0';
+ if (len != NULL)
+ *len = ss->len;
+ return p;
+}
+
+static int
+establish_connection(struct tac_handle *h)
+{
+ int i;
+
+ if (h->fd >= 0) /* Already connected. */
+ return 0;
+ if (h->num_servers == 0) {
+ generr(h, "No TACACS+ servers specified");
+ return -1;
+ }
+ /*
+ * Try the servers round-robin. We begin with the one that
+ * worked for us the last time. That way, once we find a good
+ * server, we won't waste any more time trying the bad ones.
+ */
+ for (i = 0; i < h->num_servers; i++) {
+ if (conn_server(h) == 0) {
+ h->single_connect = (h->servers[h->cur_server].flags &
+ TAC_SRVR_SINGLE_CONNECT) != 0;
+ return 0;
+ }
+ if (++h->cur_server >= h->num_servers) /* Wrap around */
+ h->cur_server = 0;
+ }
+ /* Just return whatever error was last reported by conn_server(). */
+ return -1;
+}
+
+/*
+ * Free a client string, obliterating its contents first for security.
+ */
+static void
+free_str(struct clnt_str *cs)
+{
+ if (cs->data != NULL) {
+ memset(cs->data, 0, cs->len);
+ free(cs->data);
+ cs->data = NULL;
+ cs->len = 0;
+ }
+}
+
+static void
+generr(struct tac_handle *h, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vsnprintf(h->errmsg, ERRSIZE, format, ap);
+ va_end(ap);
+}
+
+static void
+gen_session_id(struct tac_msg *msg)
+{
+ int r;
+
+ r = random();
+ msg->session_id[0] = r >> 8;
+ msg->session_id[1] = r;
+ r = random();
+ msg->session_id[2] = r >> 8;
+ msg->session_id[3] = r;
+}
+
+/*
+ * Verify that we are exactly at the end of the response message.
+ * Returns 0 on success, -1 on failure.
+ */
+static int
+get_srvr_end(struct tac_handle *h)
+{
+ if (h->srvr_pos != ntohl(h->response.length)) {
+ generr(h, "Invalid length field in response from server");
+ return -1;
+ }
+ return 0;
+}
+
+static int
+get_srvr_str(struct tac_handle *h, struct srvr_str *ss, size_t len)
+{
+ if (h->srvr_pos + len > ntohl(h->response.length)) {
+ generr(h, "Invalid length field in response from server");
+ return -1;
+ }
+ ss->data = len != 0 ? h->response.u.body + h->srvr_pos : NULL;
+ ss->len = len;
+ h->srvr_pos += len;
+ return 0;
+}
+
+static void
+init_clnt_str(struct clnt_str *cs)
+{
+ cs->data = NULL;
+ cs->len = 0;
+}
+
+static void
+init_srvr_str(struct srvr_str *ss)
+{
+ ss->data = NULL;
+ ss->len = 0;
+}
+
+static int
+read_timed(struct tac_handle *h, void *buf, size_t len,
+ const struct timeval *deadline)
+{
+ char *ptr;
+
+ ptr = (char *)buf;
+ while (len > 0) {
+ int n;
+
+ n = read(h->fd, ptr, len);
+ if (n == -1) {
+ struct timeval tv;
+ int nfds;
+
+ if (errno != EAGAIN) {
+ generr(h, "Network read error: %s",
+ strerror(errno));
+ return -1;
+ }
+
+ /* Wait until we can read more data. */
+ gettimeofday(&tv, NULL);
+ timersub(deadline, &tv, &tv);
+ if (tv.tv_sec >= 0) {
+ fd_set rfds;
+
+ FD_ZERO(&rfds);
+ FD_SET(h->fd, &rfds);
+ nfds =
+ select(h->fd + 1, &rfds, NULL, NULL, &tv);
+ if (nfds == -1) {
+ generr(h, "select: %s",
+ strerror(errno));
+ return -1;
+ }
+ } else
+ nfds = 0;
+ if (nfds == 0) {
+ generr(h, "Network read timed out");
+ return -1;
+ }
+ } else if (n == 0) {
+ generr(h, "unexpected EOF from server");
+ return -1;
+ } else {
+ ptr += n;
+ len -= n;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Receive a response from the server and decrypt it. Returns 0 on
+ * success, or -1 on failure.
+ */
+static int
+recv_msg(struct tac_handle *h)
+{
+ struct timeval deadline;
+ struct tac_msg *msg;
+ size_t len;
+
+ msg = &h->response;
+ gettimeofday(&deadline, NULL);
+ deadline.tv_sec += h->servers[h->cur_server].timeout;
+
+ /* Read the message header and make sure it is reasonable. */
+ if (read_timed(h, msg, HDRSIZE, &deadline) == -1)
+ return -1;
+ if (memcmp(msg->session_id, h->request.session_id,
+ sizeof msg->session_id) != 0) {
+ generr(h, "Invalid session ID in received message");
+ return -1;
+ }
+ if (msg->type != h->request.type) {
+ generr(h, "Invalid type in received message");
+ return -1;
+ }
+ len = ntohl(msg->length);
+ if (len > BODYSIZE) {
+ generr(h, "Received message too large");
+ return -1;
+ }
+ if (msg->seq_no != ++h->last_seq_no) {
+ generr(h, "Invalid sequence number in received message");
+ return -1;
+ }
+
+ /* Read the message body. */
+ if (read_timed(h, msg->u.body, len, &deadline) == -1)
+ return -1;
+
+ /* Decrypt it. */
+ crypt_msg(h, msg);
+
+ /*
+ * Turn off single-connection mode if the server isn't amenable
+ * to it.
+ */
+ if (!(msg->flags & TAC_SINGLE_CONNECT))
+ h->single_connect = 0;
+ return 0;
+}
+
+static int
+save_str(struct tac_handle *h, struct clnt_str *cs, const void *data,
+ size_t len)
+{
+ free_str(cs);
+ if (data != NULL && len != 0) {
+ if ((cs->data = xmalloc(h, len)) == NULL)
+ return -1;
+ cs->len = len;
+ memcpy(cs->data, data, len);
+ }
+ return 0;
+}
+
+/*
+ * Send the current request, after encrypting it. Returns 0 on success,
+ * or -1 on failure.
+ */
+static int
+send_msg(struct tac_handle *h)
+{
+ struct timeval deadline;
+ struct tac_msg *msg;
+ char *ptr;
+ int len;
+
+ if (h->last_seq_no & 1) {
+ generr(h, "Attempt to send message out of sequence");
+ return -1;
+ }
+
+ msg = &h->request;
+ msg->seq_no = ++h->last_seq_no;
+ if (msg->seq_no == 1)
+ gen_session_id(msg);
+ crypt_msg(h, msg);
+
+ if (establish_connection(h) == -1)
+ return -1;
+
+ if (h->single_connect)
+ msg->flags |= TAC_SINGLE_CONNECT;
+ else
+ msg->flags &= ~TAC_SINGLE_CONNECT;
+ gettimeofday(&deadline, NULL);
+ deadline.tv_sec += h->servers[h->cur_server].timeout;
+ len = HDRSIZE + ntohl(msg->length);
+ ptr = (char *)msg;
+ while (len > 0) {
+ int n;
+
+ n = write(h->fd, ptr, len);
+ if (n == -1) {
+ struct timeval tv;
+ int nfds;
+
+ if (errno != EAGAIN) {
+ generr(h, "Network write error: %s",
+ strerror(errno));
+ return -1;
+ }
+
+ /* Wait until we can write more data. */
+ gettimeofday(&tv, NULL);
+ timersub(&deadline, &tv, &tv);
+ if (tv.tv_sec >= 0) {
+ fd_set wfds;
+
+ FD_ZERO(&wfds);
+ FD_SET(h->fd, &wfds);
+ nfds =
+ select(h->fd + 1, NULL, &wfds, NULL, &tv);
+ if (nfds == -1) {
+ generr(h, "select: %s",
+ strerror(errno));
+ return -1;
+ }
+ } else
+ nfds = 0;
+ if (nfds == 0) {
+ generr(h, "Network write timed out");
+ return -1;
+ }
+ } else {
+ ptr += n;
+ len -= n;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Destructively split a string into fields separated by white space.
+ * `#' at the beginning of a field begins a comment that extends to the
+ * end of the string. Fields may be quoted with `"'. Inside quoted
+ * strings, the backslash escapes `\"' and `\\' are honored.
+ *
+ * Pointers to up to the first maxfields fields are stored in the fields
+ * array. Missing fields get NULL pointers.
+ *
+ * The return value is the actual number of fields parsed, and is always
+ * <= maxfields.
+ *
+ * On a syntax error, places a message in the msg string, and returns -1.
+ */
+static int
+split(char *str, char *fields[], int maxfields, char *msg, size_t msglen)
+{
+ char *p;
+ int i;
+ static const char ws[] = " \t";
+
+ for (i = 0; i < maxfields; i++)
+ fields[i] = NULL;
+ p = str;
+ i = 0;
+ while (*p != '\0') {
+ p += strspn(p, ws);
+ if (*p == '#' || *p == '\0')
+ break;
+ if (i >= maxfields) {
+ snprintf(msg, msglen, "line has too many fields");
+ return -1;
+ }
+ if (*p == '"') {
+ char *dst;
+
+ dst = ++p;
+ fields[i] = dst;
+ while (*p != '"') {
+ if (*p == '\\') {
+ p++;
+ if (*p != '"' && *p != '\\' &&
+ *p != '\0') {
+ snprintf(msg, msglen,
+ "invalid `\\' escape");
+ return -1;
+ }
+ }
+ if (*p == '\0') {
+ snprintf(msg, msglen,
+ "unterminated quoted string");
+ return -1;
+ }
+ *dst++ = *p++;
+ }
+ *dst = '\0';
+ p++;
+ if (*p != '\0' && strspn(p, ws) == 0) {
+ snprintf(msg, msglen, "quoted string not"
+ " followed by white space");
+ return -1;
+ }
+ } else {
+ fields[i] = p;
+ p += strcspn(p, ws);
+ if (*p != '\0')
+ *p++ = '\0';
+ }
+ i++;
+ }
+ return i;
+}
+
+int
+tac_add_server(struct tac_handle *h, const char *host, int port,
+ const char *secret, int timeout, int flags)
+{
+ struct tac_server *srvp;
+
+ if (h->num_servers >= MAXSERVERS) {
+ generr(h, "Too many RADIUS servers specified");
+ return -1;
+ }
+ srvp = &h->servers[h->num_servers];
+
+ memset(&srvp->addr, 0, sizeof srvp->addr);
+ srvp->addr.sin_len = sizeof srvp->addr;
+ srvp->addr.sin_family = AF_INET;
+ if (!inet_aton(host, &srvp->addr.sin_addr)) {
+ struct hostent *hent;
+
+ if ((hent = gethostbyname(host)) == NULL) {
+ generr(h, "%s: host not found", host);
+ return -1;
+ }
+ memcpy(&srvp->addr.sin_addr, hent->h_addr,
+ sizeof srvp->addr.sin_addr);
+ }
+ srvp->addr.sin_port = htons(port != 0 ? port : TACPLUS_PORT);
+ if ((srvp->secret = xstrdup(h, secret)) == NULL)
+ return -1;
+ srvp->timeout = timeout;
+ srvp->flags = flags;
+ h->num_servers++;
+ return 0;
+}
+
+void
+tac_close(struct tac_handle *h)
+{
+ int srv;
+
+ if (h->fd != -1)
+ close(h->fd);
+ for (srv = 0; srv < h->num_servers; srv++) {
+ memset(h->servers[srv].secret, 0,
+ strlen(h->servers[srv].secret));
+ free(h->servers[srv].secret);
+ }
+ free_str(&h->user);
+ free_str(&h->port);
+ free_str(&h->rem_addr);
+ free_str(&h->data);
+ free_str(&h->user_msg);
+ free(h);
+}
+
+int
+tac_config(struct tac_handle *h, const char *path)
+{
+ FILE *fp;
+ char buf[MAXCONFLINE];
+ int linenum;
+ int retval;
+
+ if (path == NULL)
+ path = PATH_TACPLUS_CONF;
+ if ((fp = fopen(path, "r")) == NULL) {
+ generr(h, "Cannot open \"%s\": %s", path, strerror(errno));
+ return -1;
+ }
+ retval = 0;
+ linenum = 0;
+ while (fgets(buf, sizeof buf, fp) != NULL) {
+ int len;
+ char *fields[4];
+ int nfields;
+ char msg[ERRSIZE];
+ char *host;
+ char *port_str;
+ char *secret;
+ char *timeout_str;
+ char *options_str;
+ char *end;
+ unsigned long timeout;
+ int port;
+ int options;
+
+ linenum++;
+ len = strlen(buf);
+ /* We know len > 0, else fgets would have returned NULL. */
+ if (buf[len - 1] != '\n') {
+ if (len == sizeof buf - 1)
+ generr(h, "%s:%d: line too long", path,
+ linenum);
+ else
+ generr(h, "%s:%d: missing newline", path,
+ linenum);
+ retval = -1;
+ break;
+ }
+ buf[len - 1] = '\0';
+
+ /* Extract the fields from the line. */
+ nfields = split(buf, fields, 4, msg, sizeof msg);
+ if (nfields == -1) {
+ generr(h, "%s:%d: %s", path, linenum, msg);
+ retval = -1;
+ break;
+ }
+ if (nfields == 0)
+ continue;
+ if (nfields < 2) {
+ generr(h, "%s:%d: missing shared secret", path,
+ linenum);
+ retval = -1;
+ break;
+ }
+ host = fields[0];
+ secret = fields[1];
+ timeout_str = fields[2];
+ options_str = fields[3];
+
+ /* Parse and validate the fields. */
+ host = strtok(host, ":");
+ port_str = strtok(NULL, ":");
+ if (port_str != NULL) {
+ port = strtoul(port_str, &end, 10);
+ if (port_str[0] == '\0' || *end != '\0') {
+ generr(h, "%s:%d: invalid port", path,
+ linenum);
+ retval = -1;
+ break;
+ }
+ } else
+ port = 0;
+ if (timeout_str != NULL) {
+ timeout = strtoul(timeout_str, &end, 10);
+ if (timeout_str[0] == '\0' || *end != '\0') {
+ generr(h, "%s:%d: invalid timeout", path,
+ linenum);
+ retval = -1;
+ break;
+ }
+ } else
+ timeout = TIMEOUT;
+ options = 0;
+ if (options_str != NULL) {
+ if (strcmp(options_str, "single-connection") == 0)
+ options |= TAC_SRVR_SINGLE_CONNECT;
+ else {
+ generr(h, "%s:%d: invalid option \"%s\"",
+ path, linenum, options_str);
+ retval = -1;
+ break;
+ }
+ };
+
+ if (tac_add_server(h, host, port, secret, timeout,
+ options) == -1) {
+ char msg[ERRSIZE];
+
+ strcpy(msg, h->errmsg);
+ generr(h, "%s:%d: %s", path, linenum, msg);
+ retval = -1;
+ break;
+ }
+ }
+ /* Clear out the buffer to wipe a possible copy of a shared secret */
+ memset(buf, 0, sizeof buf);
+ fclose(fp);
+ return retval;
+}
+
+int
+tac_create_authen(struct tac_handle *h, int action, int type, int service)
+{
+ struct tac_msg *msg;
+ struct tac_authen_start *as;
+
+ h->last_seq_no = 0;
+
+ msg = &h->request;
+ msg->type = TAC_AUTHEN;
+ msg->version = authen_version(action, type);
+ msg->flags = 0;
+
+ as = &msg->u.authen_start;
+ as->action = action;
+ as->priv_lvl = TAC_PRIV_LVL_USER;
+ as->authen_type = type;
+ as->service = service;
+
+ free_str(&h->user);
+ free_str(&h->port);
+ free_str(&h->rem_addr);
+ free_str(&h->data);
+ free_str(&h->user_msg);
+
+ /* XXX - more to do */
+ return 0;
+}
+
+void *
+tac_get_data(struct tac_handle *h, size_t *len)
+{
+ return dup_str(h, &h->srvr_data, len);
+}
+
+char *
+tac_get_msg(struct tac_handle *h)
+{
+ return (char *)dup_str(h, &h->srvr_msg, NULL);
+}
+
+/*
+ * Create and initialize a tac_handle structure, and return it to the
+ * caller. Can fail only if the necessary memory cannot be allocated.
+ * In that case, it returns NULL.
+ */
+struct tac_handle *
+tac_open(void)
+{
+ struct tac_handle *h;
+
+ h = (struct tac_handle *)malloc(sizeof(struct tac_handle));
+ if (h != NULL) {
+ h->fd = -1;
+ h->num_servers = 0;
+ h->cur_server = 0;
+ h->errmsg[0] = '\0';
+ init_clnt_str(&h->user);
+ init_clnt_str(&h->port);
+ init_clnt_str(&h->rem_addr);
+ init_clnt_str(&h->data);
+ init_clnt_str(&h->user_msg);
+ init_srvr_str(&h->srvr_msg);
+ init_srvr_str(&h->srvr_data);
+ srandomdev();
+ }
+ return h;
+}
+
+int
+tac_send_authen(struct tac_handle *h)
+{
+ struct tac_authen_reply *ar;
+
+ if (h->last_seq_no == 0) { /* Authentication START packet */
+ struct tac_authen_start *as;
+
+ as = &h->request.u.authen_start;
+ h->request.length =
+ htonl(offsetof(struct tac_authen_start, rest[0]));
+ if (add_str_8(h, &as->user_len, &h->user) == -1 ||
+ add_str_8(h, &as->port_len, &h->port) == -1 ||
+ add_str_8(h, &as->rem_addr_len, &h->rem_addr) == -1 ||
+ add_str_8(h, &as->data_len, &h->data) == -1)
+ return -1;
+ } else { /* Authentication CONTINUE packet */
+ struct tac_authen_cont *ac;
+
+ ac = &h->request.u.authen_cont;
+ ac->flags = 0;
+ h->request.length =
+ htonl(offsetof(struct tac_authen_cont, rest[0]));
+ if (add_str_16(h, &ac->user_msg_len, &h->user_msg) == -1 ||
+ add_str_16(h, &ac->data_len, &h->data) == -1)
+ return -1;
+ }
+
+ /* Send the message and retrieve the reply. */
+ if (send_msg(h) == -1 || recv_msg(h) == -1)
+ return -1;
+
+ /* Scan the optional fields in the reply. */
+ ar = &h->response.u.authen_reply;
+ h->srvr_pos = offsetof(struct tac_authen_reply, rest[0]);
+ if (get_srvr_str(h, &h->srvr_msg, ntohs(ar->msg_len)) == -1 ||
+ get_srvr_str(h, &h->srvr_data, ntohs(ar->data_len)) == -1 ||
+ get_srvr_end(h) == -1)
+ return -1;
+
+ if (!h->single_connect &&
+ ar->status != TAC_AUTHEN_STATUS_GETDATA &&
+ ar->status != TAC_AUTHEN_STATUS_GETUSER &&
+ ar->status != TAC_AUTHEN_STATUS_GETPASS)
+ close_connection(h);
+
+ return ar->flags << 8 | ar->status;
+}
+
+int
+tac_set_rem_addr(struct tac_handle *h, const char *addr)
+{
+ return save_str(h, &h->rem_addr, addr, addr != NULL ? strlen(addr) : 0);
+}
+
+int
+tac_set_data(struct tac_handle *h, const void *data, size_t data_len)
+{
+ return save_str(h, &h->data, data, data_len);
+}
+
+int
+tac_set_msg(struct tac_handle *h, const char *msg)
+{
+ return save_str(h, &h->user_msg, msg, msg != NULL ? strlen(msg) : 0);
+}
+
+int
+tac_set_port(struct tac_handle *h, const char *port)
+{
+ return save_str(h, &h->port, port, port != NULL ? strlen(port) : 0);
+}
+
+int
+tac_set_priv(struct tac_handle *h, int priv)
+{
+ if (!(TAC_PRIV_LVL_MIN <= priv && priv <= TAC_PRIV_LVL_MAX)) {
+ generr(h, "Attempt to set invalid privilege level");
+ return -1;
+ }
+ h->request.u.authen_start.priv_lvl = priv;
+ return 0;
+}
+
+int
+tac_set_user(struct tac_handle *h, const char *user)
+{
+ return save_str(h, &h->user, user, user != NULL ? strlen(user) : 0);
+}
+
+const char *
+tac_strerror(struct tac_handle *h)
+{
+ return h->errmsg;
+}
+
+static void *
+xmalloc(struct tac_handle *h, size_t size)
+{
+ void *r;
+
+ if ((r = malloc(size)) == NULL)
+ generr(h, "Out of memory");
+ return r;
+}
+
+static char *
+xstrdup(struct tac_handle *h, const char *s)
+{
+ char *r;
+
+ if ((r = strdup(s)) == NULL)
+ generr(h, "Out of memory");
+ return r;
+}
diff --git a/lib/libtacplus/taclib.h b/lib/libtacplus/taclib.h
new file mode 100644
index 0000000..0da1b08
--- /dev/null
+++ b/lib/libtacplus/taclib.h
@@ -0,0 +1,105 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _TACLIB_H_
+#define _TACLIB_H_
+
+#include <sys/types.h>
+
+struct tac_handle;
+
+/* Flags for tac_add_server(). */
+#define TAC_SRVR_SINGLE_CONNECT 0x04 /* Keep connection open for multiple
+ sessions. */
+
+/* Disassembly of tac_send_authen() return value. */
+#define TAC_AUTHEN_STATUS(s) ((s) & 0xff)
+#define TAC_AUTHEN_NOECHO(s) ((s) & (1<<8))
+
+/* Privilege levels */
+#define TAC_PRIV_LVL_MIN 0x00
+#define TAC_PRIV_LVL_USER 0x01
+#define TAC_PRIV_LVL_ROOT 0x0f
+#define TAC_PRIV_LVL_MAX 0x0f
+
+/* Authentication actions */
+#define TAC_AUTHEN_LOGIN 0x01
+#define TAC_AUTHEN_CHPASS 0x02
+#define TAC_AUTHEN_SENDPASS 0x03
+#define TAC_AUTHEN_SENDAUTH 0x04
+
+/* Authentication types */
+#define TAC_AUTHEN_TYPE_ASCII 0x01
+#define TAC_AUTHEN_TYPE_PAP 0x02
+#define TAC_AUTHEN_TYPE_CHAP 0x03
+#define TAC_AUTHEN_TYPE_ARAP 0x04
+#define TAC_AUTHEN_TYPE_MSCHAP 0x05
+
+/* Authentication services */
+#define TAC_AUTHEN_SVC_NONE 0x00
+#define TAC_AUTHEN_SVC_LOGIN 0x01
+#define TAC_AUTHEN_SVC_ENABLE 0x02
+#define TAC_AUTHEN_SVC_PPP 0x03
+#define TAC_AUTHEN_SVC_ARAP 0x04
+#define TAC_AUTHEN_SVC_PT 0x05
+#define TAC_AUTHEN_SVC_RCMD 0x06
+#define TAC_AUTHEN_SVC_X25 0x07
+#define TAC_AUTHEN_SVC_NASI 0x08
+#define TAC_AUTHEN_SVC_FWPROXY 0x09
+
+/* Authentication reply status codes */
+#define TAC_AUTHEN_STATUS_PASS 0x01
+#define TAC_AUTHEN_STATUS_FAIL 0x02
+#define TAC_AUTHEN_STATUS_GETDATA 0x03
+#define TAC_AUTHEN_STATUS_GETUSER 0x04
+#define TAC_AUTHEN_STATUS_GETPASS 0x05
+#define TAC_AUTHEN_STATUS_RESTART 0x06
+#define TAC_AUTHEN_STATUS_ERROR 0x07
+#define TAC_AUTHEN_STATUS_FOLLOW 0x21
+
+__BEGIN_DECLS
+int tac_add_server(struct tac_handle *,
+ const char *, int, const char *, int, int);
+void tac_close(struct tac_handle *);
+int tac_config(struct tac_handle *, const char *);
+int tac_create_authen(struct tac_handle *, int, int, int);
+void *tac_get_data(struct tac_handle *, size_t *);
+char *tac_get_msg(struct tac_handle *);
+struct tac_handle *tac_open(void);
+int tac_send_authen(struct tac_handle *);
+int tac_set_data(struct tac_handle *,
+ const void *, size_t);
+int tac_set_msg(struct tac_handle *, const char *);
+int tac_set_port(struct tac_handle *, const char *);
+int tac_set_priv(struct tac_handle *, int);
+int tac_set_rem_addr(struct tac_handle *, const char *);
+int tac_set_user(struct tac_handle *, const char *);
+const char *tac_strerror(struct tac_handle *);
+__END_DECLS
+
+#endif /* _TACLIB_H_ */
diff --git a/lib/libtacplus/taclib_private.h b/lib/libtacplus/taclib_private.h
new file mode 100644
index 0000000..830fc92
--- /dev/null
+++ b/lib/libtacplus/taclib_private.h
@@ -0,0 +1,152 @@
+/*-
+ * Copyright 1998 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef TACLIB_PRIVATE_H
+#define TACLIB_PRIVATE_H
+
+#include "taclib.h"
+
+/* Defaults */
+#define PATH_TACPLUS_CONF "/etc/tacplus.conf"
+#define TACPLUS_PORT 49
+#define TIMEOUT 3 /* In seconds */
+
+/* Limits */
+#define BODYSIZE 8150 /* Maximum message body size */
+#define ERRSIZE 128 /* Maximum error message length */
+#define MAXCONFLINE 1024 /* Maximum config file line length */
+#define MAXSERVERS 10 /* Maximum number of servers to try */
+
+/* Protocol constants. */
+#define HDRSIZE 12 /* Size of message header */
+
+/* Protocol version number */
+#define TAC_VER_MAJOR 0xc /* Major version number */
+
+/* Protocol packet types */
+#define TAC_AUTHEN 0x01 /* Authentication */
+#define TAC_AUTHOR 0x02 /* Authorization */
+#define TAC_ACCT 0x03 /* Accouting */
+
+/* Protocol header flags */
+#define TAC_UNENCRYPTED 0x01
+#define TAC_SINGLE_CONNECT 0x04
+
+struct tac_server {
+ struct sockaddr_in addr; /* Address of server */
+ char *secret; /* Shared secret */
+ int timeout; /* Timeout in seconds */
+ int flags;
+};
+
+/*
+ * An optional string of bytes specified by the client for inclusion in
+ * a request. The data is always a dynamically allocated copy that
+ * belongs to the library. It is copied into the request packet just
+ * before sending the request.
+ */
+struct clnt_str {
+ void *data;
+ size_t len;
+};
+
+/*
+ * An optional string of bytes from a server response. The data resides
+ * in the response packet itself, and must not be freed.
+ */
+struct srvr_str {
+ const void *data;
+ size_t len;
+};
+
+struct tac_authen_start {
+ u_int8_t action;
+ u_int8_t priv_lvl;
+ u_int8_t authen_type;
+ u_int8_t service;
+ u_int8_t user_len;
+ u_int8_t port_len;
+ u_int8_t rem_addr_len;
+ u_int8_t data_len;
+ unsigned char rest[1];
+};
+
+struct tac_authen_reply {
+ u_int8_t status;
+ u_int8_t flags;
+ u_int16_t msg_len;
+ u_int16_t data_len;
+ unsigned char rest[1];
+};
+
+struct tac_authen_cont {
+ u_int16_t user_msg_len;
+ u_int16_t data_len;
+ u_int8_t flags;
+ unsigned char rest[1];
+};
+
+struct tac_msg {
+ u_int8_t version;
+ u_int8_t type;
+ u_int8_t seq_no;
+ u_int8_t flags;
+ u_int8_t session_id[4];
+ u_int32_t length;
+ union {
+ struct tac_authen_start authen_start;
+ struct tac_authen_reply authen_reply;
+ struct tac_authen_cont authen_cont;
+ unsigned char body[BODYSIZE];
+ } u;
+};
+
+struct tac_handle {
+ int fd; /* Socket file descriptor */
+ struct tac_server servers[MAXSERVERS]; /* Servers to contact */
+ int num_servers; /* Number of valid server entries */
+ int cur_server; /* Server we are currently using */
+ int single_connect; /* Use a single connection */
+ int last_seq_no;
+ char errmsg[ERRSIZE]; /* Most recent error message */
+
+ struct clnt_str user;
+ struct clnt_str port;
+ struct clnt_str rem_addr;
+ struct clnt_str data;
+ struct clnt_str user_msg;
+
+ struct tac_msg request;
+ struct tac_msg response;
+
+ int srvr_pos; /* Scan position in response body */
+ struct srvr_str srvr_msg;
+ struct srvr_str srvr_data;
+};
+
+#endif
diff --git a/lib/libtacplus/tacplus.conf.5 b/lib/libtacplus/tacplus.conf.5
new file mode 100644
index 0000000..4cb2772
--- /dev/null
+++ b/lib/libtacplus/tacplus.conf.5
@@ -0,0 +1,114 @@
+.\" Copyright 1998 Juniper Networks, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 29, 1998
+.Dt TACPLUS.CONF 5
+.Os FreeBSD
+.Sh NAME
+.Nm tacplus.conf
+.Nd TACACS+ client configuration file
+.Sh SYNOPSIS
+.Pa /etc/tacplus.conf
+.Sh DESCRIPTION
+.Nm
+contains the information necessary to configure the TACACS+ client
+library. It is parsed by
+.Xr tac_config 3 .
+The file contains one or more lines of text, each describing a
+single TACACS+ server which is to be used by the library. Leading
+white space is ignored, as are empty lines and lines containing
+only comments.
+.Pp
+A TACACS+ server is described by two to four fields on a line. The
+fields are separated by white space. The
+.Ql #
+character at the beginning of a field begins a comment, which extends
+to the end of the line. A field may be enclosed in double quotes,
+in which case it may contain white space and/or begin with the
+.Ql #
+character. Within a quoted string, the double quote character can
+be represented by
+.Ql \e\&" ,
+and the backslash can be represented by
+.Ql \e\e .
+No other escape sequences are supported.
+.Pp
+The first field specifies
+the server host, either as a fully qualified domain name or as a
+dotted-quad IP address. The host may optionally be followed by a
+.Ql \&:
+and a numeric port number, without intervening white space. If the
+port specification is omitted, it defaults to 49, the standard TACACS+
+port.
+.Pp
+The second field contains the shared secret, which should be known
+only to the client and server hosts. It is an arbitrary string
+of characters, though it must be enclosed in double quotes if it
+contains white space or is empty. An empty secret disables the
+normal encryption mechanism, causing all data to cross the network in
+cleartext.
+.Pp
+The third field contains a decimal integer specifying the timeout
+in seconds for communicating with the server. The timeout applies
+separately to each connect, write, and read operation. If this field
+is omitted, it defaults to 3 seconds.
+.Pp
+The optional fourth field may contain the string
+.Ql single-connection .
+If this option is included, the library will attempt to negotiate
+with the server to keep the TCP connection open for multiple
+sessions. Some older TACACS+ servers become confused if this option
+is specified.
+.Pp
+Up to 10 TACACS+ servers may be specified. The servers are tried in
+order, until a valid response is received or the list is exhausted.
+.Pp
+The standard location for this file is
+.Pa /etc/tacplus.conf .
+An alternate pathname may be specified in the call to
+.Xr tac_config 3 .
+Since the file contains sensitive information in the form of the
+shared secrets, it should not be readable except by root.
+.Sh FILES
+.Pa /etc/tacplus.conf
+.Sh EXAMPLES
+.Bd -literal
+# A simple entry using all the defaults:
+tacserver.domain.com OurLittleSecret
+
+# A server using a non-standard port, with an increased timeout and
+# the "single-connection" option.
+auth.domain.com:4333 "Don't tell!!" 15 single-connection
+
+# A server specified by its IP address:
+192.168.27.81 $X*#..38947ax-+=
+.Ed
+.Sh SEE ALSO
+.Xr libtacplus 3
+.Sh AUTHORS
+This documentation was written by
+.An John Polstra ,
+and donated to the FreeBSD project by Juniper Networks, Inc.
diff --git a/lib/libtelnet/Makefile b/lib/libtelnet/Makefile
new file mode 100644
index 0000000..9e79174
--- /dev/null
+++ b/lib/libtelnet/Makefile
@@ -0,0 +1,18 @@
+# From: @(#)Makefile 8.2 (Berkeley) 12/15/93
+# $FreeBSD$
+
+LIB= telnet
+SRCS= genget.c getent.c misc.c
+CFLAGS+= -DHAS_CGETENT
+NOPIC= true
+
+#
+# Remove obsolete shared libraries, if any. We don't bother moving them
+# to/usr/lib/compat, since they were only used by telnet, telnetd and
+# tn3270.
+#
+beforeinstall:
+ rm -f ${DESTDIR}${SHLIBDIR}/lib${LIB}.so.2.0
+
+.include <bsd.lib.mk>
+
diff --git a/lib/libtelnet/genget.c b/lib/libtelnet/genget.c
new file mode 100644
index 0000000..29c7519
--- /dev/null
+++ b/lib/libtelnet/genget.c
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)genget.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+
+#include <ctype.h>
+
+#define LOWER(x) (isupper(x) ? tolower(x) : (x))
+/*
+ * The prefix function returns 0 if *s1 is not a prefix
+ * of *s2. If *s1 exactly matches *s2, the negative of
+ * the length is returned. If *s1 is a prefix of *s2,
+ * the length of *s1 is returned.
+ */
+ int
+isprefix(s1, s2)
+ register char *s1, *s2;
+{
+ char *os1;
+ register char c1, c2;
+
+ if (*s1 == '\0')
+ return(-1);
+ os1 = s1;
+ c1 = *s1;
+ c2 = *s2;
+ while (LOWER(c1) == LOWER(c2)) {
+ if (c1 == '\0')
+ break;
+ c1 = *++s1;
+ c2 = *++s2;
+ }
+ return(*s1 ? 0 : (*s2 ? (s1 - os1) : (os1 - s1)));
+}
+
+static char *ambiguous; /* special return value for command routines */
+
+ char **
+genget(name, table, stlen)
+ char *name; /* name to match */
+ char **table; /* name entry in table */
+ int stlen;
+{
+ register char **c, **found;
+ register int n;
+
+ if (name == 0)
+ return 0;
+
+ found = 0;
+ for (c = table; *c != 0; c = (char **)((char *)c + stlen)) {
+ if ((n = isprefix(name, *c)) == 0)
+ continue;
+ if (n < 0) /* exact match */
+ return(c);
+ if (found)
+ return(&ambiguous);
+ found = c;
+ }
+ return(found);
+}
+
+/*
+ * Function call version of Ambiguous()
+ */
+ int
+Ambiguous(s)
+ char *s;
+{
+ return((char **)s == &ambiguous);
+}
diff --git a/lib/libtelnet/getent.c b/lib/libtelnet/getent.c
new file mode 100644
index 0000000..0956a2a
--- /dev/null
+++ b/lib/libtelnet/getent.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)getent.c 8.2 (Berkeley) 12/15/93";
+#endif /* not lint */
+
+#include <stdlib.h>
+
+static char *area;
+
+/*ARGSUSED*/
+int
+getent(cp, name)
+char *cp, *name;
+{
+#ifdef HAS_CGETENT
+ char *dba[2];
+
+ dba[0] = "/etc/gettytab";
+ dba[1] = 0;
+ return((cgetent(&area, dba, name) == 0) ? 1 : 0);
+#else
+ return(0);
+#endif
+}
+
+#ifndef SOLARIS
+/*ARGSUSED*/
+char *
+Getstr(id, cpp)
+char *id, **cpp;
+{
+# ifdef HAS_CGETENT
+ char *answer;
+ return((cgetstr(area, id, &answer) > 0) ? answer : 0);
+# else
+ return(0);
+# endif
+}
+#endif
diff --git a/lib/libtelnet/misc-proto.h b/lib/libtelnet/misc-proto.h
new file mode 100644
index 0000000..e5f334a
--- /dev/null
+++ b/lib/libtelnet/misc-proto.h
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)misc-proto.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * Copyright (C) 1990 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef __MISC_PROTO__
+#define __MISC_PROTO__
+
+#if !defined(P)
+#ifdef __STDC__
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+#endif
+
+void auth_encrypt_init P((char *, char *, char *, int));
+void auth_encrypt_connect P((int));
+void printd P((unsigned char *, int));
+
+/*
+ * These functions are imported from the application
+ */
+int net_write P((unsigned char *, int));
+void net_encrypt P((void));
+int telnet_spin P((void));
+char *telnet_getenv P((char *));
+char *telnet_gets P((char *, char *, int, int));
+#endif
diff --git a/lib/libtelnet/misc.c b/lib/libtelnet/misc.c
new file mode 100644
index 0000000..d4242b6
--- /dev/null
+++ b/lib/libtelnet/misc.c
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "misc.h"
+
+char *RemoteHostName;
+char *LocalHostName;
+char *UserNameRequested = 0;
+int ConnectedCount = 0;
+
+ void
+auth_encrypt_init(local, remote, name, server)
+ char *local;
+ char *remote;
+ char *name;
+ int server;
+{
+ RemoteHostName = remote;
+ LocalHostName = local;
+#if defined(AUTHENTICATION)
+ auth_init(name, server);
+#endif
+ if (UserNameRequested) {
+ free(UserNameRequested);
+ UserNameRequested = 0;
+ }
+}
+
+ void
+auth_encrypt_user(name)
+ char *name;
+{
+ extern char *strdup();
+
+ if (UserNameRequested)
+ free(UserNameRequested);
+ UserNameRequested = name ? strdup(name) : 0;
+}
+
+ void
+auth_encrypt_connect(cnt)
+ int cnt;
+{
+}
+
+ void
+printd(data, cnt)
+ unsigned char *data;
+ int cnt;
+{
+ if (cnt > 16)
+ cnt = 16;
+ while (cnt-- > 0) {
+ printf(" %02x", *data);
+ ++data;
+ }
+}
diff --git a/lib/libtelnet/misc.h b/lib/libtelnet/misc.h
new file mode 100644
index 0000000..41ffa7f
--- /dev/null
+++ b/lib/libtelnet/misc.h
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)misc.h 8.1 (Berkeley) 6/4/93
+ */
+
+extern char *UserNameRequested;
+extern char *LocalHostName;
+extern char *RemoteHostName;
+extern int ConnectedCount;
+extern int ReservedPort;
+
+#include "misc-proto.h"
diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile
new file mode 100644
index 0000000..48db2a1
--- /dev/null
+++ b/lib/libutil/Makefile
@@ -0,0 +1,44 @@
+# @(#)Makefile 8.1 (Berkeley) 6/4/93
+# $FreeBSD$
+
+LIB= util
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 2
+CFLAGS+=-Wall -DLIBC_SCCS -I${.CURDIR} -I${.CURDIR}/../../sys
+SRCS= login.c login_tty.c logout.c logwtmp.c pty.c setproctitle.c \
+ login_cap.c login_class.c login_auth.c login_times.c login_ok.c \
+ _secure_path.c uucplock.c property.c auth.c realhostname.c
+MAN3+= login.3 login_auth.3 login_tty.3 logout.3 logwtmp.3 pty.3 \
+ setproctitle.3 login_cap.3 login_class.3 login_times.3 login_ok.3 \
+ _secure_path.3 uucplock.3 property.3 auth.3 realhostname.3 \
+ trimdomain.3
+MAN5+= login.conf.5 auth.conf.5
+MLINKS+= property.3 properties_read.3 property.3 properties_free.3
+MLINKS+= property.3 property_find.3
+MLINKS+= auth.3 auth_getval.3
+MLINKS+= pty.3 openpty.3 pty.3 forkpty.3
+MLINKS+=login_cap.3 login_getclassbyname.3 login_cap.3 login_close.3 \
+ login_cap.3 login_getclass.3 login_cap.3 login_getuserclass.3 \
+ login_cap.3 login_getcapstr.3 login_cap.3 login_getcaplist.3 \
+ login_cap.3 login_getstyle.3 login_cap.3 login_getcaptime.3 \
+ login_cap.3 login_getcapnum.3 login_cap.3 login_getcapsize.3 \
+ login_cap.3 login_getcapbool.3 login_cap.3 login_getpath.3 \
+ login_cap.3 login_getpwclass.3
+MLINKS+=login_class.3 setusercontext.3 login_class.3 setclasscontext.3 \
+ login_class.3 setclassenvironment.3 login_class.3 setclassresources.3
+MLINKS+=login_times.3 parse_lt.3 login_times.3 in_ltm.3 \
+ login_times.3 in_lt.3 login_times.3 in_ltms.3 \
+ login_times.3 in_lts.3
+MLINKS+=login_ok.3 auth_ttyok.3 login_ok.3 auth_hostok.3 \
+ login_ok.3 auth_timeok.3
+MLINKS+=login_auth.3 auth_checknologin.3 login_auth.3 auth_cat.3
+MLINKS+=uucplock.3 uu_lock.3 uucplock.3 uu_lock_txfr.3 \
+ uucplock.3 uu_unlock.3 uucplock.3 uu_lockerr.3
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/libutil.h \
+ ${DESTDIR}/usr/include
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/login_cap.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libutil/_secure_path.3 b/lib/libutil/_secure_path.3
new file mode 100644
index 0000000..e962669
--- /dev/null
+++ b/lib/libutil/_secure_path.3
@@ -0,0 +1,73 @@
+.\" Copyright (c) 1997 David Nugent <davidn@blaze.net.au>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, is permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice immediately at the beginning of the file, without modification,
+.\" this list of conditions, and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. This work was done expressly for inclusion into FreeBSD. Other use
+.\" is permitted provided this notation is included.
+.\" 4. Absolutely no warranty of function or purpose is made by the author
+.\" David Nugent.
+.\" 5. Modifications may be freely made to this file providing the above
+.\" conditions are met.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1997
+.Os FreeBSD
+.Dt _SECURE_PATH 3
+.Sh NAME
+.Nm _secure_path
+.Nd determine if a file appears to be secure
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <libutil.h>
+.Ft int
+.Fn _secure_path "const char *path" "uid_t uid" "gid_t gid"
+.Pp
+.Sh DESCRIPTION
+This function does some basic security checking on a given path.
+It is intended to be used by processes running with root privileges
+in order to decide whether or not to trust the contents of a given
+file.
+It uses a method often used to detect system compromise.
+.Pp
+A file is considered
+.Sq secure
+if it meets the following conditions:
+.Bl -enum
+.It
+The file exists, and is a regular file (not a symlink, device
+special or named pipe, etc.),
+.It
+Is not world writable.
+.It
+Is owned by the given uid or uid 0, if uid is not -1,
+.It
+Is not group wriable or it has group ownership by the given
+gid, if gid is not -1.
+.El
+.Sh RETURN VALUES
+This function returns zero if the file exists and may be
+considered secure, -2 if the file does not exist, and
+-1 otherwise to indicate a security failure.
+.Xr syslog 3
+is used to log any failure of this function, including the
+reason, at LOG_ERR priority.
+.Sh BUGS
+The checks carried out are rudimentary and no attempt is made
+to eliminate race conditions between use of this function and
+access to the file referenced.
+.Sh SEE ALSO
+.Xr lstat 2 ,
+.Xr syslog 3 .
+.Sh HISTORY
+Code from which this function was derived was contributed to the
+.Fx
+project by Berkeley Software Design, Inc.
diff --git a/lib/libutil/_secure_path.c b/lib/libutil/_secure_path.c
new file mode 100644
index 0000000..c27003c
--- /dev/null
+++ b/lib/libutil/_secure_path.c
@@ -0,0 +1,72 @@
+/*-
+ * Based on code copyright (c) 1995,1997 by
+ * Berkeley Software Design, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. This work was done expressly for inclusion into FreeBSD. Other use
+ * is permitted provided this notation is included.
+ * 4. Absolutely no warranty of function or purpose is made by the authors.
+ * 5. Modifications may be freely made to this file providing the above
+ * conditions are met.
+ *
+ * $FreeBSD$
+ */
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <syslog.h>
+#include <errno.h>
+#include <libutil.h>
+
+/*
+ * Check for common security problems on a given path
+ * It must be:
+ * 1. A regular file, and exists
+ * 2. Owned and writaable only by root (or given owner)
+ * 3. Group ownership is given group or is non-group writable
+ *
+ * Returns: -2 if file does not exist,
+ * -1 if security test failure
+ * 0 otherwise
+ */
+
+int
+_secure_path(const char *path, uid_t uid, gid_t gid)
+{
+ int r = -1;
+ struct stat sb;
+ const char *msg = NULL;
+
+ if (lstat(path, &sb) < 0) {
+ if (errno == ENOENT) /* special case */
+ r = -2; /* if it is just missing, skip the log entry */
+ else
+ msg = "%s: cannot stat %s: %m";
+ }
+ else if (!S_ISREG(sb.st_mode))
+ msg = "%s: %s is not a regular file";
+ else if (sb.st_mode & S_IWOTH)
+ msg = "%s: %s is world writable";
+ else if (uid != -1 && sb.st_uid != uid && sb.st_uid != 0) {
+ if (uid == 0)
+ msg = "%s: %s is not owned by root";
+ else
+ msg = "%s: %s is not owned by uid %d";
+ } else if (gid != -1 && sb.st_gid != gid && (sb.st_mode & S_IWGRP))
+ msg = "%s: %s is group writeable by non-authorised groups";
+ else
+ r = 0;
+ if (msg != NULL)
+ syslog(LOG_ERR, msg, "_secure_path", path, uid);
+ return r;
+}
diff --git a/lib/libutil/auth.3 b/lib/libutil/auth.3
new file mode 100644
index 0000000..67a63b7
--- /dev/null
+++ b/lib/libutil/auth.3
@@ -0,0 +1,61 @@
+.\"
+.\" Copyright (c) 1998 Jordan Hubbard
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" "
+.Dd October 7, 1998
+.Os
+.Dt AUTH_GETVAL 3
+.Sh NAME
+.Nm auth_getval
+.Nd functions for reading values from
+.Pa /etc/auth.conf
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <libutil.h>
+.Ft char *
+.Fn auth_getval "const char *name"
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+
+The function
+.Fn auth_getval
+returns the value assocated with the field called
+.Fa name
+or NULL if no such field is found or the auth file cannot be opened.
+.Sh SEE ALSO
+.Xr properties_read 3 ,
+.Xr properties_free 3 ,
+.Xr property_find 3 ,
+.Xr auth.conf 5
+.Sh FILES
+.Pa /etc/auth.conf
+contains the name=value pairs looked up by
+.Fn auth_getval .
diff --git a/lib/libutil/auth.c b/lib/libutil/auth.c
new file mode 100644
index 0000000..05c3917
--- /dev/null
+++ b/lib/libutil/auth.c
@@ -0,0 +1,71 @@
+/*
+ *
+ * Simple authentication database handling code.
+ *
+ * Copyright (c) 1998
+ * Jordan Hubbard. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * verbatim and that no modifications are made prior to this
+ * point in the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR HIS PETS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id*
+ *
+ */
+
+#include <unistd.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <paths.h>
+#include <fcntl.h>
+#include <libutil.h>
+
+static properties P;
+
+static int
+initauthconf(const char *path)
+{
+ int fd;
+
+ if (!P) {
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ syslog(LOG_ERR, "initauthconf: unable to open file: %s", path);
+ return 1;
+ }
+ P = properties_read(fd);
+ close(fd);
+ if (!P) {
+ syslog(LOG_ERR, "initauthconf: unable to parse file: %s", path);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+char *
+auth_getval(const char *name)
+{
+ if (!P && initauthconf(_PATH_AUTHCONF))
+ return NULL;
+ else
+ return property_find(P, name);
+}
diff --git a/lib/libutil/auth.conf.5 b/lib/libutil/auth.conf.5
new file mode 100644
index 0000000..fe64632
--- /dev/null
+++ b/lib/libutil/auth.conf.5
@@ -0,0 +1,33 @@
+.\" Copyright (c) 1998 Jordan Hubbard
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, is permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice immediately at the beginning of the file, without modification,
+.\" this list of conditions, and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd October 7, 1998
+.Dt AUTH.CONF 5
+.Os FreeBSD
+.Sh NAME
+.Nm auth.conf
+.Nd authentication capability database
+.Sh SYNOPSIS
+.Pa /etc/auth.conf
+.Sh DESCRIPTION
+.Nm auth.conf
+contains various attributes important to the authentication
+code, most notably
+.Xr kerberos 5
+for the time being. This documentation will be updated as the
+.Pa /etc/auth.conf
+file, which is very new, evolves.
+.Sh SEE ALSO
+.Xr auth_getval 3
diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h
new file mode 100644
index 0000000..f41c665
--- /dev/null
+++ b/lib/libutil/libutil.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1995 Peter Wemm <peter@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. This work was done expressly for inclusion into FreeBSD. Other use
+ * is permitted provided this notation is included.
+ * 4. Absolutely no warranty of function or purpose is made by the author
+ * Peter Wemm.
+ * 5. Modifications may be freely made to this file providing the above
+ * conditions are met.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LIBUTIL_H_
+#define _LIBUTIL_H_
+
+#include <sys/cdefs.h>
+
+/* for properties.c */
+typedef struct _property {
+ struct _property *next;
+ char *name;
+ char *value;
+} *properties;
+
+/* Avoid pulling in all the include files for no need */
+struct termios;
+struct winsize;
+struct utmp;
+struct in_addr;
+
+__BEGIN_DECLS
+void setproctitle __P((const char *_fmt, ...)) __printf0like(1, 2);
+void login __P((struct utmp *_ut));
+int login_tty __P((int _fd));
+int logout __P((char *_line));
+void logwtmp __P((const char *_line, const char *_name, const char *_host));
+void trimdomain __P((char *_fullhost, int _hostsize));
+int openpty __P((int *_amaster, int *_aslave, char *_name,
+ struct termios *_termp, struct winsize *_winp));
+int forkpty __P((int *_amaster, char *_name,
+ struct termios *_termp, struct winsize *_winp));
+const char *uu_lockerr __P((int _uu_lockresult));
+int uu_lock __P((const char *_ttyname));
+int uu_unlock __P((const char *_ttyname));
+int uu_lock_txfr __P((const char *_ttyname, pid_t _pid));
+int _secure_path __P((const char *_path, uid_t _uid, gid_t _gid));
+properties properties_read __P((int fd));
+void properties_free __P((properties list));
+char *property_find __P((properties list, const char *name));
+char *auth_getval __P((const char *name));
+int realhostname __P((char *host, size_t hsize, const struct in_addr *ip));
+__END_DECLS
+
+#define UU_LOCK_INUSE (1)
+#define UU_LOCK_OK (0)
+#define UU_LOCK_OPEN_ERR (-1)
+#define UU_LOCK_READ_ERR (-2)
+#define UU_LOCK_CREAT_ERR (-3)
+#define UU_LOCK_WRITE_ERR (-4)
+#define UU_LOCK_LINK_ERR (-5)
+#define UU_LOCK_TRY_ERR (-6)
+#define UU_LOCK_OWNER_ERR (-7)
+
+/* return values from realhostname() */
+#define HOSTNAME_FOUND (0)
+#define HOSTNAME_INCORRECTNAME (1)
+#define HOSTNAME_INVALIDADDR (2)
+#define HOSTNAME_INVALIDNAME (3)
+
+#endif /* !_LIBUTIL_H_ */
diff --git a/lib/libutil/login.3 b/lib/libutil/login.3
new file mode 100644
index 0000000..c8f592c
--- /dev/null
+++ b/lib/libutil/login.3
@@ -0,0 +1,69 @@
+.\"
+.\" Copyright (c) 1996 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" "
+.Dd December 29, 1996
+.Os
+.Dt LOGIN 3
+.Sh NAME
+.Nm login
+.Nd "log a new login record to the utmp and wtmp files"
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <utmp.h>
+.Fd #include <libutil.h>
+.Ft void
+.Fn login "struct utmp *ut"
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+The function
+.Fn login
+records the
+.Ar ut
+entry being passed into the appropriate slot of the
+.Xr utmp 5
+file (according to the controlling terminal of the calling process),
+and appends it to the
+.Xr wtmp 5
+file. The calling process must have permission to write to both files.
+.Sh RETURN VALUES
+None.
+.Sh SEE ALSO
+.Xr logout 3 ,
+.Xr ttyslot 3 ,
+.Xr utmp 5 ,
+.Xr wtmp 5
+.Sh BUGS
+The interface provided by
+.Fn login
+is rather crude. The caller must know about the details of a
+.Va struct utmp .
+Some better abstraction needs to be worked out.
diff --git a/lib/libutil/login.c b/lib/libutil/login.c
new file mode 100644
index 0000000..322c9a6
--- /dev/null
+++ b/lib/libutil/login.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)login.c 8.1 (Berkeley) 6/4/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <utmp.h>
+#include <libutil.h>
+
+void
+login(ut)
+ struct utmp *ut;
+{
+ register int fd;
+ int tty;
+
+ tty = ttyslot();
+ if (tty > 0 && (fd = open(_PATH_UTMP, O_WRONLY|O_CREAT, 0644)) >= 0) {
+ (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), L_SET);
+ (void)write(fd, ut, sizeof(struct utmp));
+ (void)close(fd);
+ }
+ if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
+ (void)write(fd, ut, sizeof(struct utmp));
+ (void)close(fd);
+ }
+}
diff --git a/lib/libutil/login.conf.5 b/lib/libutil/login.conf.5
new file mode 100644
index 0000000..0b86490
--- /dev/null
+++ b/lib/libutil/login.conf.5
@@ -0,0 +1,366 @@
+.\" Copyright (c) 1996 David Nugent <davidn@blaze.net.au>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, is permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice immediately at the beginning of the file, without modification,
+.\" this list of conditions, and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. This work was done expressly for inclusion into FreeBSD. Other use
+.\" is permitted provided this notation is included.
+.\" 4. Absolutely no warranty of function or purpose is made by the author
+.\" David Nugent.
+.\" 5. Modifications may be freely made to this file providing the above
+.\" conditions are met.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd November 22, 1996
+.Dt LOGIN.CONF 5
+.Os FreeBSD
+.Sh NAME
+.Nm login.conf
+.Nd login class capability database
+.Sh SYNOPSIS
+.Pa /etc/login.conf ,
+.Pa ~/.login_conf
+.Sh DESCRIPTION
+.Nm login.conf
+contains various attributes and capabilities of login classes.
+A login class (an optional annotation against each record in the user
+account database,
+.Pa /etc/master.passwd )
+determines session accounting, resource limits and user environment settings.
+It is used by various programs in the system to set up a user's login
+environment and to enforce policy, accounting and administrative restrictions.
+It also provides the means by which users are able to be
+authenticated to the system and the types of authentication available.
+.Pp
+A special record "default" in the system user class capability database
+.Pa /etc/login.conf
+is used automatically for any
+non-root user without a valid login class in
+.Pa /etc/master.passwd .
+A user with a uid of 0 without a valid login class will use the record
+"root" if it exists, or "default" if not.
+.Pp
+In FreeBSD, users may individually create a file called
+.Pa .login_conf
+in their home directory using the same format, consisting of a single
+entry with a record id of "me".
+If present, this file is used by
+.Xr login 1
+to set user-defined environment settings which override those specified
+in the system login capabilities database.
+Only a subset of login capabilities may be overridden, typically those
+which do not involve authentication, resource limits and accounting.
+.Pp
+Records in a class capabilities database consist of a number of
+colon-separated fields.
+The first entry for each record gives one or more names that a record is
+to be known by, each separated by a '|' character.
+The first name is the most common abbreviation.
+The last name given should be a long name that is more descriptive
+of the capability entry, and all others are synonyms.
+All names but the last should be in lower case and contain no blanks;
+the last name may contain upper case characters and blanks for
+readability.
+.Pp
+See
+.Xr getcap 3
+for a more in-depth description of the format of a capability database.
+.Sh CAPABILITIES
+Fields within each record in the database follow the
+.Xr getcap 3
+conventions for boolean, type string
+.Ql \&=
+and type numeric
+.Ql \&# ,
+although type numeric is depreciated in favour of the string format and
+either form is accepted for a numeric datum.
+Values fall into the following categories:
+.Bl -tag -width "program"
+.It file
+Path name to a data file
+.It program
+Path name to an executable file
+.It list
+A list of values (or pairs of values) separated by commas or spaces
+.It path
+A space or comma separated list of path names, following the usual csh
+conventions (leading tilde with and without username being expanded to
+home directories etc.)
+.It number
+A numeric value, either decimal (default), hexadecimal (with leading 0x),
+or octal (with a leading 0).
+With a numeric type, only one numeric value is allowed.
+Numeric types may also be specified in string format (ie. the capability
+tag being delimited from the value by '=' instead of '#').
+Whichever method is used, then all records in the database must use the
+same method to allow values to be correctly overridden in interpolated
+records.
+.It size
+A number which expresses a size.
+The default interpretation of a value is the number of bytes, but a
+suffix may specify alternate units:
+.Bl -tag -offset indent -compact -width xxxx
+.It b
+explicitly selects 512-byte blocks
+.It k
+selects kilobytes (1024 bytes)
+.It m
+specifies a multiplier of 1 megabyte (1048576 bytes),
+.It g
+specifies units of gigabytes, and
+.It t
+represents terabytes.
+.El
+A size value is a numeric quantity and case of the suffix is not significant.
+Concatenated values are added together.
+.It time
+A period of time, by default in seconds.
+A prefix may specify a different unit:
+.Bl -tag -offset indent -compact -width xxxx
+.It y
+indicates the number of 365 day years,
+.It w
+indicates the number of weeks,
+.It d
+the number of days,
+.It h
+the number of hours,
+.It m
+the number of minutes, and
+.It s
+the number of seconds.
+.El
+Concatenated values are added together.
+For example, 2 hours and 40 minutes may be written either as
+9600s, 160m or 2h40m.
+.El
+.Pp
+The usual convention to interpolate capability entries using the special
+.Em tc=value
+notation may be used.
+.Pp
+.Sh RESOURCE LIMITS
+.Bl -column coredumpsize indent indent
+.Sy Name Type Notes Description
+.It cputime time CPU usage limit.
+.It filesize size Maximum file size limit.
+.It datasize size Maximum data size limit.
+.It stacksize size Maximum stack size limit.
+.It coredumpsize size Maximum coredump size limit.
+.It memoryuse size Maximum of core memory use size limit.
+.It memorylocked size Maximum locked in core memory size limit.
+.It maxproc number Maximum number of processes.
+.It openfiles number Maximum number of open files per process.
+.El
+.Pp
+These resource limit entries actually specify both the maximum
+and current limits (see
+.Xr getrlimit 2 ).
+The current (soft) limit is the one normally used, although the user is permitted
+to increase the current limit to the maximum (hard) limit.
+The maximum and current limits may be specified individually by appending a
+-max or -cur to the capability name.
+.Pp
+.Sh ENVIRONMENT
+.Bl -column ignorenologin indent xbinxxusrxbin
+.Sy Name Type Notes Description
+.It charset string Set $MM_CHARSET environment variable to the specified
+value.
+.It hushlogin bool false Same as having a ~/.hushlogin file.
+.It ignorenologin bool false Login not prevented by nologin.
+.It lang string Set $LANG environment variable to the specified value.
+.It manpath path Default search path for manpages.
+.It nologin file If the file exists it will be displayed and
+the login session will be terminated.
+.It path path /bin /usr/bin Default search path.
+.It priority number Initial priority (nice) level.
+.It requirehome bool false Require a valid home directory to login.
+.It setenv list A comma-separated list of environment variables and
+values to which they are to be set.
+.It shell prog Session shell to execute rather than the
+shell specified in the passwd file. The SHELL environment variable will
+contain the shell specified in the password file.
+.It term string su Default terminal type if not able to determine from
+other means.
+.It timezone string Default value of $TZ environment variable.
+.It umask number 022 Initial umask. Should always have a leading 0 to
+ensure octal interpretation.
+.It welcome file /etc/motd File containing welcome message.
+.El
+.Pp
+.Sh AUTHENTICATION
+.Bl -column minpasswordlen indent indent
+.Sy Name Type Notes Description
+.It minpasswordlen number 6 The minimum length a local password may be.
+.\" .It approve program Program to approve login.
+.It copyright file File containing additional copyright information
+.\".It widepasswords bool false Use the wide password format. The wide password
+.\" format allows up to 128 significant characters in the password.
+.It host.allow list List of remote host wildcards from which users in
+the class may access.
+.It host.deny list List of remote host wildcards from which users in
+the class may not access.
+.It times.allow list List of time periods during which
+logins are allowed.
+.It times.deny list List of time periods during which logins are
+disallowed.
+.It ttys.allow list List of ttys and ttygroups which users
+in the class may use for access.
+.It ttys.deny list List of ttys and ttygroups which users
+in the class may not use for access.
+.El
+.Pp
+These fields are intended to be used by
+.Xr passwd 1
+and other programs in the login authentication system.
+.Pp
+Capabilities that set environment variables are scanned for both
+.Ql \&~
+and
+.Ql \&$
+characters, which are substituted for a user's home directory and name
+respectively.
+To pass these characters literally into the environment variable, escape
+the character by preceding it with a backslash '\\'.
+.Pp
+The
+.Em host.allow
+and
+.Em host.deny
+entries are comma separated lists used for checking remote access to the system,
+and consist of a list of hostnames and/or IP addresses against which remote
+network logins are checked.
+Items in these lists may contain wildcards in the form used by shell programs
+for wildcard matching (See
+.Xr fnmatch 3
+for details on the implementation).
+The check on hosts is made against both the remote system's Internet address
+and hostname (if available).
+If both lists are empty or not specified, then logins from any remote host
+are allowed.
+If host.allow contains one or more hosts, then only remote systems matching
+any of the items in that list are allowed to log in.
+If host.deny contains one or more hosts, then a login from any matching hosts
+will be disallowed.
+.Pp
+The
+.Em times.allow
+and
+.Em times.deny
+entries consist of a comma-separated list of time periods during which the users
+in a class are allowed to be logged in.
+These are expressed as one or more day codes followed by a start and end times
+expressed in 24 hour format, separated by a hyphen or dash.
+For example, MoThSa0200-1300 translates to Monday, Thursday and Saturday between
+the hours of 2 am and 1 p.m..
+If both of these time lists are empty, users in the class are allowed access at
+any time.
+If
+.Em times.allow
+is specified, then logins are only allowed during the periods given.
+If
+.Em times.deny
+is specified, then logins are denied during the periods given, regardless of whether
+one of the periods specified in
+.Em times.allow
+applies.
+.Pp
+Note that
+.Xr login 1
+enforces only that the actual login falls within periods allowed by these entries.
+Further enforcement over the life of a session requires a separate daemon to
+monitor transitions from an allowed period to a non-allowed one.
+.Pp
+The
+.Em ttys.allow
+and
+.Em ttys.deny
+entries contain a comma-separated list of tty devices (without the /dev/ prefix)
+that a user in a class may use to access the system, and/or a list of ttygroups
+(See
+.Xr getttyent 3
+and
+.Xr ttys 5
+for information on ttygroups).
+If neither entry exists, then the choice of login device used by the user is
+unrestricted.
+If only
+.Em ttys.allow
+is specified, then the user is restricted only to ttys in the given
+group or device list.
+If only
+.Em ttys.deny
+is specified, then the user is prevented from using the specified devices or
+devices in the group.
+If both lists are given and are non-empty, the user is restricted to those
+devices allowed by ttys.allow that are not available by ttys.deny.
+.Sh ACCOUNTING LIMITS
+.Bl -column host.accounted indent indent
+.Sy Name Type Notes Description
+.It accounted bool false Enable session time accounting for all users
+in this class.
+.It autodelete time Time after expiry when account is auto-deleted.
+.It bootfull bool false Enable 'boot only if ttygroup is full' strategy
+when terminating sessions.
+.It daytime time Maximum login time per day.
+.It expireperiod time Time for expiry allocation.
+.It graceexpire time Grace days for expired account.
+.It gracetime time Additional grace login time allowed.
+.It host.accounted list List of remote host wildcards from which
+login sessions will be accounted.
+.It host.exempt list List of remote host wildcards from which
+login session accounting is exempted.
+.It idletime time Maximum idle time before logout.
+.It monthtime time Maximum login time per month.
+.It passwordtime time Used by
+.Xr passwd 1
+to set next password expiry date.
+.It refreshtime time New time allowed on account refresh.
+.It refreshperiod str How often account time is refreshed.
+.It sessiontime time Maximum login time per session.
+.It sessionlimit number Maximum number of concurrent
+login sessions on ttys in any group.
+.It ttys.accounted list List of ttys and ttygroups for which
+login accounting is active.
+.It ttys.exempt list List of ttys and ttygroups for which login accounting
+is exempt.
+.It warnexpire time Advance notice for pending account expiry.
+.It warnpassword time Advance notice for pending password expiry.
+.It warntime time Advance notice for pending out-of-time.
+.It weektime time Maximum login time per week.
+.El
+.Pp
+These fields are used by the time accounting system, which regulates,
+controls and records user login access.
+.Pp
+The
+.Em ttys.accounted
+and
+.Em ttys.exempt
+fields operate in a similar manner to
+.Em ttys.allow
+and
+.Em ttys.deny
+as explained
+above.
+Similarly with the
+.Em host.accounted
+and
+.Em host.exempt
+lists.
+.Sh SEE ALSO
+.Xr login 1 ,
+.Xr getcap 3 ,
+.Xr getttyent 3 ,
+.Xr login_cap 3 ,
+.Xr login_class 3 ,
+.Xr passwd 5 ,
+.Xr ttys 5
diff --git a/lib/libutil/login_auth.3 b/lib/libutil/login_auth.3
new file mode 100644
index 0000000..e521275
--- /dev/null
+++ b/lib/libutil/login_auth.3
@@ -0,0 +1,70 @@
+.\" Copyright (c) 1995 David Nugent <davidn@blaze.net.au>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, is permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice immediately at the beginning of the file, without modification,
+.\" this list of conditions, and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. This work was done expressly for inclusion into FreeBSD. Other use
+.\" is permitted provided this notation is included.
+.\" 4. Absolutely no warranty of function or purpose is made by the author
+.\" David Nugent.
+.\" 5. Modifications may be freely made to this file providing the above
+.\" conditions are met.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 29, 1996
+.Os FreeBSD
+.Dt LOGIN_AUTH 3
+.Sh NAME
+.\" .Nm authenticate
+.\" .Nm auth_script
+.\" .Nm auth_env
+.\" .Nm auth_scan
+.\" .Nm auth_rmfiles
+.Nm auth_checknologin ,
+.Nm auth_cat
+.\" .Nm auth_ttyok
+.\" .Nm auth_hostok
+.\" .Nm auth_timesok
+.Nd authentication style support library for login class capabilities database.
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <login_cap.h>
+.\" .Ft int
+.\". Fn authenticate "const char *name" "const char *classname" "const char *style" "const char *service"
+.\" .Ft int
+.\" .Fn auth_script "const char * path" ...
+.\" .Ft void
+.\" .Fn auth_env "void"
+.\" .Ft int
+.\" .Fn auth_scan "int ok"
+.\" .Ft void
+.\" .Fn auth_rmfiles "void"
+.Ft void
+.Fn auth_checknologin "login_cap_t *lc"
+.Ft int
+.Fn auth_cat "const char *file"
+.\" .Ft int
+.\" .Fn auth_ttyok "login_cap_t *lc" "const char *tty"
+.\" .Ft int
+.\" .Fn auth_hostok "login_cap_t *lc" "const char *hostname" "char const *ip"
+.\" .Ft int
+.\" .Fn auth_timesok "login_cap_t *lc" "time_t now"
+.Sh DESCRIPTION
+This set of functions support the login class authorisation style interface provided
+by
+.Xr login.conf 5 .
+.\" .Sh RETURN VALUES
+.Sh SEE ALSO
+.Xr getcap 3 ,
+.Xr login_cap 3 ,
+.Xr login_class 3 ,
+.Xr login.conf 5 ,
+.Xr termcap 5
diff --git a/lib/libutil/login_auth.c b/lib/libutil/login_auth.c
new file mode 100644
index 0000000..1fb21ca
--- /dev/null
+++ b/lib/libutil/login_auth.c
@@ -0,0 +1,107 @@
+/*-
+ * Copyright (c) 1996 by
+ * Sean Eric Fagan <sef@kithrup.com>
+ * David Nugent <davidn@blaze.net.au>
+ * All rights reserved.
+ *
+ * Portions copyright (c) 1995,1997 by
+ * Berkeley Software Design, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. This work was done expressly for inclusion into FreeBSD. Other use
+ * is permitted provided this notation is included.
+ * 4. Absolutely no warranty of function or purpose is made by the authors.
+ * 5. Modifications may be freely made to this file providing the above
+ * conditions are met.
+ *
+ * Low-level routines relating to the user capabilities database
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <login_cap.h>
+#include <stdarg.h>
+#include <paths.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <err.h>
+#include <libutil.h>
+
+
+/*
+ * auth_checknologin()
+ * Checks for the existance of a nologin file in the login_cap
+ * capability <lc>. If there isn't one specified, then it checks
+ * to see if this class should just ignore nologin files. Lastly,
+ * it tries to print out the default nologin file, and, if such
+ * exists, it exits.
+ */
+
+void
+auth_checknologin(login_cap_t *lc)
+{
+ char *file;
+
+ /* Do we ignore a nologin file? */
+ if (login_getcapbool(lc, "ignorenologin", 0))
+ return;
+
+ /* Note that <file> will be "" if there is no nologin capability */
+ if ((file = login_getcapstr(lc, "nologin", "", NULL)) == NULL)
+ exit(1);
+
+ /*
+ * *file is true IFF there was a "nologin" capability
+ * Note that auth_cat() returns 1 only if the specified
+ * file exists, and is readable. E.g., /.nologin exists.
+ */
+ if ((*file && auth_cat(file)) || auth_cat(_PATH_NOLOGIN))
+ exit(1);
+}
+
+
+/*
+ * auth_cat()
+ * Checks for the readability of <file>; if it can be opened for
+ * reading, it prints it out to stdout, and then exits. Otherwise,
+ * it returns 0 (meaning no nologin file).
+ */
+
+int
+auth_cat(const char *file)
+{
+ int fd, count;
+ char buf[BUFSIZ];
+
+ if ((fd = open(file, O_RDONLY)) < 0)
+ return 0;
+ while ((count = read(fd, buf, sizeof(buf))) > 0)
+ (void)write(fileno(stdout), buf, count);
+ close(fd);
+ sleep(5); /* wait an arbitrary time to drain */
+ return 1;
+}
diff --git a/lib/libutil/login_cap.3 b/lib/libutil/login_cap.3
new file mode 100644
index 0000000..7377d19
--- /dev/null
+++ b/lib/libutil/login_cap.3
@@ -0,0 +1,398 @@
+.\" Copyright (c) 1995 David Nugent <davidn@blaze.net.au>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, is permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice immediately at the beginning of the file, without modification,
+.\" this list of conditions, and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. This work was done expressly for inclusion into FreeBSD. Other use
+.\" is permitted provided this notation is included.
+.\" 4. Absolutely no warranty of function or purpose is made by the author
+.\" David Nugent.
+.\" 5. Modifications may be freely made to this file providing the above
+.\" conditions are met.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 27, 1996
+.Os FreeBSD
+.Dt LOGIN_CAP 3
+.Sh NAME
+.Nm login_getclassbyname ,
+.Nm login_close ,
+.Nm login_getclass ,
+.Nm login_getpwclass ,
+.Nm login_getuserclass ,
+.Nm login_getcapstr ,
+.Nm login_getcaplist ,
+.Nm login_getcaptime ,
+.Nm login_getcapnum ,
+.Nm login_getcapsize ,
+.Nm login_getcapbool ,
+.Nm login_getstyle
+.Nd functions for accessing the login class capabilities database.
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <login_cap.h>
+.Ft void
+.Fn login_close "login_cap_t * lc"
+.Ft login_cap_t *
+.Fn login_getclassbyname "const char *nam" "const struct passwd *pwd"
+.Ft login_cap_t *
+.Fn login_getclass "const char *nam"
+.Ft login_cap_t *
+.Fn login_getpwclass "const struct passwd *pwd"
+.Ft login_cap_t *
+.Fn login_getuserclass "const struct passwd *pwd"
+.Ft char *
+.Fn login_getcapstr "login_cap_t *lc" "const char *cap" "char *def" "char *error"
+.Ft char **
+.Fn login_getcaplist "login_cap_t *lc" "const char *cap" "const char *chars"
+.Ft char *
+.Fn login_getpath "login_cap_t *lc" "const char *cap" "char *error"
+.Ft rlim_t
+.Fn login_getcaptime "login_cap_t *lc" "const char *cap" "rlim_t def" "rlim_t error"
+.Ft rlim_t
+.Fn login_getcapnum "login_cap_t *lc" "const char *cap" "rlim_t def" "rlim_t error"
+.Ft rlim_t
+.Fn login_getcapsize "login_cap_t *lc" "const char *cap" "rlim_t def" "rlim_t error"
+.Ft int
+.Fn login_getcapbool "login_cap_t *lc" "const char *cap" "int def"
+.Ft char *
+.Fn login_getstyle "login_cap_t *lc" "char *style" "const char *auth"
+.Pp
+.Sh DESCRIPTION
+These functions represent a programming interface to the login
+classes database provided in
+.Xr login.conf 5 .
+This database contains capabilities, attributes and default environment
+and accounting settings for users and programs running as specific users,
+as determined by the login class field within entries in
+.Pa /etc/master.passwd .
+.Pp
+Entries in
+.Xr login.conf 5
+consist of colon
+.Ql \&:
+separated fields, the first field in each record being one or more
+identifiers for the record (which must be unique for the entire database),
+each separated by a '|', and may optionally include a description as
+the last 'name'.
+Remaining fields in the record consist of keyword/data pairs.
+Long lines may be continued with a backslash within empty entries,
+with the second and subsequent lines optionally indented for readability.
+This is similar to the format used in
+.Xr termcap 5 ,
+except that keywords are not limited to two significant characters,
+and are usually longer for improved readability.
+As with termcap entries, multiple records can be linked together
+(one record including another) using a field containing tc=<recordid>.
+The result is that the entire record referenced by <recordid> replaces
+the tc= field at the point at which it occurs.
+See
+.Xr getcap 3
+for further details on the format and use of a capabilities database.
+.Pp
+The
+.Nm login_cap
+interface provides a convenient means of retrieving login class
+records with all tc= references expanded.
+A program will typically call one of
+.Fn login_getclass ,
+.Fn login_getpwclass ,
+.Fn login_getuserclass
+or
+.Fn login_getclassbyname
+according to its requirements.
+Each of these functions returns a login capabilities structure,
+.Ft login_cap_t ,
+which may subsequently be used to interrogate the database for
+specific values using the rest of the API.
+Once the login_cap_t is of no further use, the
+.Fn login_close
+function should be called to free all resources used.
+.Pp
+The structure of login_cap_t is defined in login_cap.h, as:
+.Bd -literal -offset indent
+typedef struct {
+ char *lc_class;
+ char *lc_cap;
+ char *lc_style;
+} login_cap_t;
+.Ed
+.Pp
+The
+.Ar lc_class
+member contains a pointer to the name of the login class
+retrieved.
+This may not necessarily be the same as the one requested,
+either directly via
+.Fn login_getclassbyname ,
+indirectly via a user's login record using
+.Fn login_getpwclass ,
+by class name using
+.Fn login_getclass ,
+or
+.Fn login_getuserclass .
+If the referenced user has no login class specified in
+.Pa /etc/master.passwd ,
+the class name is NULL or an empty string. If the class
+specified does not exist in the database, each of these
+functions will search for a record with an id of "default",
+with that name returned in the
+.Ar lc_class
+field.
+In addition, if the referenced user has a UID of 0 (normally,
+"root", although the user name is not considered) then
+.Fn login_getpwclass
+will search for a record with an id of "root" before it searches
+for the record with the id of "default".
+.Pp
+The
+.Ar lc_cap
+field is used internally by the library to contain the
+expanded login capabilities record.
+Programs with unusual requirements may wish to use this
+with the lower-level
+.Fn getcap
+style functions to access the record directly.
+.Pp
+The
+.Ar lc_style
+field is set by the
+.Fn login_getstyle
+function to the authorisation style, according to the requirements
+of the program handling a login itself.
+.Pp
+As noted above, the
+.Fn get*class
+functions return a login_cap_t object which is used to access
+the matching or default record in the capabilities database.
+.Fn getclassbyname
+accepts two arguments: the first one is the record identifier of the
+record to be retrieved, the second is an optional directory name.
+If the first
+.Ar name
+argument is NULL, an empty string, or a class that does not exist
+in the supplemental or system login class database, then the system
+.Em default
+record is returned instead.
+If the second
+.Ar dir
+parameter is NULL, then only the system login class database is
+used, but when not NULL, the named directory is searched for
+a login database file called ".login_conf", and capability records
+contained within it may override the system defaults.
+This scheme allows users to override some login settings from
+those in the system login class database by creating class records
+for their own private class with a record id of `me'.
+In the context of a
+.Em login ,
+it should be noted that some options cannot by overridden by
+users for two reasons; many options, such as resource settings
+and default process priorities, require root privileges
+in order to take effect, and other fields in the user's file are
+not be consulted at all during the early phases of login for
+security or administrative reasons.
+See
+.Xr login.conf 5
+for more information on which settings a user is able to override.
+Typically, these are limited purely to the user's default login
+environment which might otherwise have been overridden in shell
+startup scripts in any case.
+The user's
+.Pa .login_conf
+merely provides a convenient way for a user to set up their preferred
+login environment before the shell is invoked on login.
+.Pp
+If the specified record is NULL, empty or does not exist, and the
+system has no "default" record available to fall back to, there is a
+memory allocation error or for some reason
+.Xr cgetent 3
+is unable to access the login capabilities database, this function
+returns NULL.
+.Pp
+The functions
+.Fn login_getpwclass ,
+.Fn login_getclass
+and
+.Fn login_getuserclass
+retrieve the applicable login class record for the user's passwd
+entry or class name by calling
+.Fn login_getclassbyname .
+On failure, NULL is returned.
+The difference between these functions is that
+.Fn login_getuserclass
+includes the user's overriding
+.Pa .login_conf
+that exists in the user's home directory, and
+.Fn login_getpwclass
+and
+.Fn login_getclass
+restrict lookup only to the system login class database in
+.Pa /etc/login.conf .
+As explained earlier,
+.Fn login_getpwclass
+only differs from
+.Fn login_getclass
+in that it allows the default class for user 'root' as "root"
+if none has been specified in the password database.
+Otherwise, if the passwd pointer is NULL, or the user record
+has no login class, then the system "default" entry is retrieved.
+.Pp
+Once a program no longer wishes to use a login_cap_t object,
+.Fn login_close
+may be called to free all resources used by the login class.
+.Fn login_close
+may be passed a NULL pointer with no harmful side-effects.
+.Pp
+The remaining functions may be used to retrieve individual
+capability records.
+Each function takes a login_cap_t object as its first parameter,
+a capability tag as the second, and remaining parameters being
+default and error values that are returned if the capability is
+not found.
+The type of the additional parameters passed and returned depend
+on the
+.Em type
+of capability each deals with, be it a simple string, a list,
+a time value, a file or memory size value, a path (consisting of
+a colon-separated list of directories) or a boolean flag.
+The manpage for
+.Xr login.conf 5
+deals in specific tags and their type.
+.Pp
+Note that with all functions in this group, you should not call
+.Xr free 3
+on any pointers returned.
+Memory allocated during retrieval or processing of capability
+tags is automatically reused by subsequent calls to functions
+in this group, or deallocated on calling
+.Fn login_close .
+.Bl -tag -width "login_getcaplist()"
+.It Fn login_getcapstr
+This function returns a simple string capability.
+If the string is not found, then the value in
+.Ar def
+is returned as the default value, or if an error
+occurs, the value in the
+.Ar error
+parameter is returned.
+.It Fn login_getcaplist
+This function returns the value corresponding to the named
+capability tag as a list of values in a NULL terminated
+array.
+Within the login class database, some tags are of type
+.Em list ,
+which consist of one or more comma- or space separated
+values.
+Usually, this function is not called directly from an
+application, but is used indirectly via
+.Fn login_getstyle .
+.It Fn login_getpath
+This function returns a list of directories separated by colons
+.Ql &: .
+Capability tags for which this function is called consist of a list of
+directories separated by spaces.
+.It Fn login_getcaptime
+This function returns a
+.Em time value
+associated with a particular capability tag with the value expressed
+in seconds (the default), minutes, hours, days, weeks or (365 day)
+years or any combination of these.
+A suffix determines the units used: S for seconds, M for minutes,
+H for hours, D for days, W for weeks and Y for 365 day years.
+Case of the units suffix is ignored.
+.Pp
+Time values are normally used for setting resource, accounting and
+session limits.
+If supported by the operating system and compiler (which is true of
+FreeBSD), the value returned is a quad (long long), of type
+.Em rlim_t .
+A value "inf" or "infinity" may be used to express an infinite
+value, in which case RLIM_INFINITY is returned.
+.It Fn login_getcapnum
+This function returns a numeric value for a tag, expressed either as
+tag=<value> or the standard
+.Fn cgetnum
+format tag#<value>.
+The first format should be used in preference to the second, the
+second format is provided for compatibility and consistency with the
+.Xr getcap 3
+database format where numeric types use the
+.Ql \&#
+as the delimiter for numeric values.
+If in the first format, then the value given may be "inf" or
+"infinity" which results in a return value of RLIM_INFINITY.
+If the given capability tag cannot be found, the
+.Ar def
+parameter is returned, and if an error occurs, the
+.Ar error
+parameter is returned.
+.It Fn login_getcapsize
+.Fn login_getcapsize
+returns a value representing a size (typically, file or memory)
+which may be expressed as bytes (the default), 512 byte blocks,
+kilobytes, megabytes, gigabytes, and on systems that support the
+.Ar long long
+type, terabytes.
+The suffix used determines the units, and multiple values and
+units may be used in combination (e.g. 1m500k = 1.5 megabytes).
+A value with no suffix is interpreted as bytes, B as 512-byte
+blocks, K as kilobytes, M as megabytes, G as gigabytes and T as
+terrabytes.
+Case is ignored.
+The error value is returned if there is a login capabilities database
+error, if an invalid suffix is used, or if a numeric value cannot be
+interpreted.
+.It Fn login_getcapbool
+This function returns a boolean value tied to a particular flag.
+It returns 0 if the given capability tag is not present or is
+negated by the presence of a "tag@" (See
+.Xr getcap 3
+for more information on boolean flags), and returns 1 if the tag
+is found.
+.It Fn login_getstyle
+This function is used by the login authorisation system to determine
+the style of login available in a particular case.
+The function accepts three parameters, the login_cap entry itself and
+two optional parameters, and authorisation type 'auth' and 'style', and
+applies these to determine the authorisation style that best suites
+these rules.
+.Bl -bullet -indent offset
+.It
+If 'auth' is neither NULL nor an empty string, look for a tag of type
+"auth-<auth>" in the capability record.
+If not present, then look for the default tag "auth=".
+.It
+If no valid authorisation list was found from the previous step, then
+default to "passwd" as the authorisation list.
+.It
+If 'style' is not NULL or empty, look for it in the list of authorisation
+methods found from the pprevious step.
+If 'style' is NULL or an empty string, then default to "passwd"
+authorisation.
+.It
+If 'style' is found in the chosen list of authorisation methods, then
+return that, otherwise return NULL.
+.El
+.Pp
+This scheme allows the administrator to determine the types of
+authorisation methods accepted by the system, depending on the
+means by which the access occurs.
+For example, the administrator may require skey or kerberos as
+the authentication method used for access to the system via the
+network, and standard methods via direct dialup or console
+logins, significantly reducing the risk of password discovery
+by "snooping" network packets.
+.El
+.Sh SEE ALSO
+.Xr getcap 3 ,
+.Xr login_class 3 ,
+.Xr login.conf 5 ,
+.Xr termcap 5
diff --git a/lib/libutil/login_cap.c b/lib/libutil/login_cap.c
new file mode 100644
index 0000000..af27766
--- /dev/null
+++ b/lib/libutil/login_cap.c
@@ -0,0 +1,799 @@
+/*-
+ * Copyright (c) 1996 by
+ * Sean Eric Fagan <sef@kithrup.com>
+ * David Nugent <davidn@blaze.net.au>
+ * All rights reserved.
+ *
+ * Portions copyright (c) 1995,1997
+ * Berkeley Software Design, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. This work was done expressly for inclusion into FreeBSD. Other use
+ * is permitted provided this notation is included.
+ * 4. Absolutely no warranty of function or purpose is made by the authors.
+ * 5. Modifications may be freely made to this file providing the above
+ * conditions are met.
+ *
+ * Low-level routines relating to the user capabilities database
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/param.h>
+#include <pwd.h>
+#include <libutil.h>
+#include <syslog.h>
+#include <login_cap.h>
+
+/*
+ * allocstr()
+ * Manage a single static pointer for handling a local char* buffer,
+ * resizing as necessary to contain the string.
+ *
+ * allocarray()
+ * Manage a static array for handling a group of strings, resizing
+ * when necessary.
+ */
+
+static int lc_object_count = 0;
+
+static size_t internal_stringsz = 0;
+static char * internal_string = NULL;
+static size_t internal_arraysz = 0;
+static char ** internal_array = NULL;
+
+static char *
+allocstr(char *str)
+{
+ char *p;
+
+ size_t sz = strlen(str) + 1; /* realloc() only if necessary */
+ if (sz <= internal_stringsz)
+ p = strcpy(internal_string, str);
+ else if ((p = realloc(internal_string, sz)) != NULL) {
+ internal_stringsz = sz;
+ internal_string = strcpy(p, str);
+ }
+ return p;
+}
+
+
+static char **
+allocarray(size_t sz)
+{
+ char **p;
+
+ if (sz <= internal_arraysz)
+ p = internal_array;
+ else if ((p = realloc(internal_array, sz * sizeof(char*))) != NULL) {
+ internal_arraysz = sz;
+ internal_array = p;
+ }
+ return p;
+}
+
+
+/*
+ * arrayize()
+ * Turn a simple string <str> seperated by any of
+ * the set of <chars> into an array. The last element
+ * of the array will be NULL, as is proper.
+ * Free using freearraystr()
+ */
+
+static char **
+arrayize(char *str, const char *chars, int *size)
+{
+ int i;
+ char *ptr;
+ char **res = NULL;
+
+ /* count the sub-strings */
+ for (i = 0, ptr = str; *ptr; i++) {
+ int count = strcspn(ptr, chars);
+ ptr += count;
+ if (*ptr)
+ ++ptr;
+ }
+
+ /* alloc the array */
+ if ((ptr = allocstr(str)) != NULL) {
+ if ((res = allocarray(++i)) == NULL)
+ free(str);
+ else {
+ /* now split the string */
+ i = 0;
+ while (*ptr) {
+ int count = strcspn(ptr, chars);
+ res[i++] = ptr;
+ ptr += count;
+ if (*ptr)
+ *ptr++ = '\0';
+ }
+ res[i] = NULL;
+ }
+ }
+
+ if (size)
+ *size = i;
+
+ return res;
+}
+
+
+/*
+ * login_close()
+ * Frees up all resources relating to a login class
+ *
+ */
+
+void
+login_close(login_cap_t * lc)
+{
+ if (lc) {
+ free(lc->lc_style);
+ free(lc->lc_class);
+ free(lc);
+ if (--lc_object_count == 0) {
+ free(internal_string);
+ free(internal_array);
+ internal_array = NULL;
+ internal_arraysz = 0;
+ internal_string = NULL;
+ internal_stringsz = 0;
+ cgetclose();
+ }
+ }
+}
+
+
+/*
+ * login_getclassbyname() get the login class by its name.
+ * If the name given is NULL or empty, the default class
+ * LOGIN_DEFCLASS (ie. "default") is fetched. If the
+ * 'dir' argument contains a non-NULL non-empty string,
+ * then the file _FILE_LOGIN_CONF is picked up from that
+ * directory instead of the system login database.
+ * Return a filled-out login_cap_t structure, including
+ * class name, and the capability record buffer.
+ */
+
+login_cap_t *
+login_getclassbyname(char const *name, const struct passwd *pwd)
+{
+ login_cap_t *lc;
+
+ if ((lc = malloc(sizeof(login_cap_t))) != NULL) {
+ int r, i = 0;
+ uid_t euid = 0;
+ gid_t egid = 0;
+ const char *msg = NULL;
+ const char *dir = (pwd == NULL) ? NULL : pwd->pw_dir;
+ char userpath[MAXPATHLEN];
+
+ static char *login_dbarray[] = { NULL, NULL, NULL };
+
+ /* Switch to user mode before checking/reading its ~/.login_conf */
+ /* - some NFSes have root read access disabled. */
+ if (dir) {
+ euid = geteuid();
+ egid = getegid();
+ (void)setegid(pwd->pw_gid);
+ (void)seteuid(pwd->pw_uid);
+ }
+
+ if (dir && snprintf(userpath, MAXPATHLEN, "%s/%s", dir,
+ _FILE_LOGIN_CONF) < MAXPATHLEN) {
+ login_dbarray[i] = userpath;
+ if (_secure_path(userpath, pwd->pw_uid, pwd->pw_gid) != -1)
+ i++; /* only use 'secure' data */
+ }
+ if (_secure_path(_PATH_LOGIN_CONF, 0, 0) != -1)
+ login_dbarray[i++] = _PATH_LOGIN_CONF;
+ login_dbarray[i] = NULL;
+
+ memset(lc, 0, sizeof(login_cap_t));
+ lc->lc_cap = lc->lc_class = lc->lc_style = NULL;
+
+ if (name == NULL || *name == '\0')
+ name = LOGIN_DEFCLASS;
+
+ switch (cgetent(&lc->lc_cap, login_dbarray, (char*)name)) {
+ case -1: /* Failed, entry does not exist */
+ if (strcmp(name, LOGIN_MECLASS) == 0)
+ break; /* Don't retry default on 'me' */
+ if (i == 0)
+ r = -1;
+ else if ((r = open(login_dbarray[0], O_RDONLY)) >= 0)
+ close(r);
+ /*
+ * If there's at least one login class database,
+ * and we aren't searching for a default class
+ * then complain about a non-existent class.
+ */
+ if (r >= 0 || strcmp(name, LOGIN_DEFCLASS) != 0)
+ syslog(LOG_ERR, "login_getclass: unknown class '%s'", name);
+ /* fall-back to default class */
+ name = LOGIN_DEFCLASS;
+ msg = "%s: no default/fallback class '%s'";
+ if (cgetent(&lc->lc_cap, login_dbarray, (char*)name) != 0 && r >= 0)
+ break;
+ /* Fallthru - just return system defaults */
+ case 0: /* success! */
+ if ((lc->lc_class = strdup(name)) != NULL) {
+ if (dir) {
+ (void)seteuid(euid);
+ (void)setegid(egid);
+ }
+ ++lc_object_count;
+ return lc;
+ }
+ msg = "%s: strdup: %m";
+ break;
+ case -2:
+ msg = "%s: retrieving class information: %m";
+ break;
+ case -3:
+ msg = "%s: 'tc=' reference loop '%s'";
+ break;
+ case 1:
+ msg = "couldn't resolve 'tc=' reference in '%s'";
+ break;
+ default:
+ msg = "%s: unexpected cgetent() error '%s': %m";
+ break;
+ }
+ if (dir) {
+ (void)seteuid(euid);
+ (void)setegid(egid);
+ }
+ if (msg != NULL)
+ syslog(LOG_ERR, msg, "login_getclass", name);
+ free(lc);
+ }
+
+ return NULL;
+}
+
+
+
+/*
+ * login_getclass()
+ * Get the login class for the system (only) login class database.
+ * Return a filled-out login_cap_t structure, including
+ * class name, and the capability record buffer.
+ */
+
+login_cap_t *
+login_getclass(const char *cls)
+{
+ return login_getclassbyname(cls, NULL);
+}
+
+
+/*
+ * login_getclass()
+ * Get the login class for a given password entry from
+ * the system (only) login class database.
+ * If the password entry's class field is not set, or
+ * the class specified does not exist, then use the
+ * default of LOGIN_DEFCLASS (ie. "default").
+ * Return a filled-out login_cap_t structure, including
+ * class name, and the capability record buffer.
+ */
+
+login_cap_t *
+login_getpwclass(const struct passwd *pwd)
+{
+ const char *cls = NULL;
+
+ if (pwd != NULL) {
+ cls = pwd->pw_class;
+ if (cls == NULL || *cls == '\0')
+ cls = (pwd->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS;
+ }
+ return login_getclassbyname(cls, pwd);
+}
+
+
+/*
+ * login_getuserclass()
+ * Get the login class for a given password entry, allowing user
+ * overrides via ~/.login_conf.
+ */
+
+login_cap_t *
+login_getuserclass(const struct passwd *pwd)
+{
+ return login_getclassbyname(LOGIN_MECLASS, pwd);
+}
+
+
+
+/*
+ * login_getcapstr()
+ * Given a login_cap entry, and a capability name, return the
+ * value defined for that capability, a defualt if not found, or
+ * an error string on error.
+ */
+
+char *
+login_getcapstr(login_cap_t *lc, const char *cap, char *def, char *error)
+{
+ char *res;
+ int ret;
+
+ if (lc == NULL || cap == NULL || lc->lc_cap == NULL || *cap == '\0')
+ return def;
+
+ if ((ret = cgetstr(lc->lc_cap, (char *)cap, &res)) == -1)
+ return def;
+ return (ret >= 0) ? res : error;
+}
+
+
+/*
+ * login_getcaplist()
+ * Given a login_cap entry, and a capability name, return the
+ * value defined for that capability split into an array of
+ * strings.
+ */
+
+char **
+login_getcaplist(login_cap_t *lc, const char *cap, const char *chars)
+{
+ char *lstring;
+
+ if (chars == NULL)
+ chars = ", \t";
+ if ((lstring = login_getcapstr(lc, (char*)cap, NULL, NULL)) != NULL)
+ return arrayize(lstring, chars, NULL);
+ return NULL;
+}
+
+
+/*
+ * login_getpath()
+ * From the login_cap_t <lc>, get the capability <cap> which is
+ * formatted as either a space or comma delimited list of paths
+ * and append them all into a string and separate by semicolons.
+ * If there is an error of any kind, return <error>.
+ */
+
+char *
+login_getpath(login_cap_t *lc, const char *cap, char * error)
+{
+ char *str;
+
+ if ((str = login_getcapstr(lc, (char*)cap, NULL, NULL)) == NULL)
+ str = error;
+ else {
+ char *ptr = str;
+
+ while (*ptr) {
+ int count = strcspn(ptr, ", \t");
+ ptr += count;
+ if (*ptr)
+ *ptr++ = ':';
+ }
+ }
+ return str;
+}
+
+
+static int
+isinfinite(const char *s)
+{
+ static const char *infs[] = {
+ "infinity",
+ "inf",
+ "unlimited",
+ "unlimit",
+ "-1",
+ NULL
+ };
+ const char **i = &infs[0];
+
+ while (*i != NULL) {
+ if (strcasecmp(s, *i) == 0)
+ return 1;
+ ++i;
+ }
+ return 0;
+}
+
+
+static u_quad_t
+rmultiply(u_quad_t n1, u_quad_t n2)
+{
+ u_quad_t m, r;
+ int b1, b2;
+
+ static int bpw = 0;
+
+ /* Handle simple cases */
+ if (n1 == 0 || n2 == 0)
+ return 0;
+ if (n1 == 1)
+ return n2;
+ if (n2 == 1)
+ return n1;
+
+ /*
+ * sizeof() returns number of bytes needed for storage.
+ * This may be different from the actual number of useful bits.
+ */
+ if (!bpw) {
+ bpw = sizeof(u_quad_t) * 8;
+ while (((u_quad_t)1 << (bpw-1)) == 0)
+ --bpw;
+ }
+
+ /*
+ * First check the magnitude of each number. If the sum of the
+ * magnatude is way to high, reject the number. (If this test
+ * is not done then the first multiply below may overflow.)
+ */
+ for (b1 = bpw; (((u_quad_t)1 << (b1-1)) & n1) == 0; --b1)
+ ;
+ for (b2 = bpw; (((u_quad_t)1 << (b2-1)) & n2) == 0; --b2)
+ ;
+ if (b1 + b2 - 2 > bpw) {
+ errno = ERANGE;
+ return (UQUAD_MAX);
+ }
+
+ /*
+ * Decompose the multiplication to be:
+ * h1 = n1 & ~1
+ * h2 = n2 & ~1
+ * l1 = n1 & 1
+ * l2 = n2 & 1
+ * (h1 + l1) * (h2 + l2)
+ * (h1 * h2) + (h1 * l2) + (l1 * h2) + (l1 * l2)
+ *
+ * Since h1 && h2 do not have the low bit set, we can then say:
+ *
+ * (h1>>1 * h2>>1 * 4) + ...
+ *
+ * So if (h1>>1 * h2>>1) > (1<<(bpw - 2)) then the result will
+ * overflow.
+ *
+ * Finally, if MAX - ((h1 * l2) + (l1 * h2) + (l1 * l2)) < (h1*h2)
+ * then adding in residual amout will cause an overflow.
+ */
+
+ m = (n1 >> 1) * (n2 >> 1);
+ if (m >= ((u_quad_t)1 << (bpw-2))) {
+ errno = ERANGE;
+ return (UQUAD_MAX);
+ }
+ m *= 4;
+
+ r = (n1 & n2 & 1)
+ + (n2 & 1) * (n1 & ~(u_quad_t)1)
+ + (n1 & 1) * (n2 & ~(u_quad_t)1);
+
+ if ((u_quad_t)(m + r) < m) {
+ errno = ERANGE;
+ return (UQUAD_MAX);
+ }
+ m += r;
+
+ return (m);
+}
+
+
+/*
+ * login_getcaptime()
+ * From the login_cap_t <lc>, get the capability <cap>, which is
+ * formatted as a time (e.g., "<cap>=10h3m2s"). If <cap> is not
+ * present in <lc>, return <def>; if there is an error of some kind,
+ * return <error>.
+ */
+
+rlim_t
+login_getcaptime(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error)
+{
+ char *res, *ep, *oval;
+ int r;
+ rlim_t tot;
+
+ errno = 0;
+ if (lc == NULL || lc->lc_cap == NULL)
+ return def;
+
+ /*
+ * Look for <cap> in lc_cap.
+ * If it's not there (-1), return <def>.
+ * If there's an error, return <error>.
+ */
+
+ if ((r = cgetstr(lc->lc_cap, (char *)cap, &res)) == -1)
+ return def;
+ else if (r < 0) {
+ errno = ERANGE;
+ return error;
+ }
+
+ /* "inf" and "infinity" are special cases */
+ if (isinfinite(res))
+ return RLIM_INFINITY;
+
+ /*
+ * Now go through the string, turning something like 1h2m3s into
+ * an integral value. Whee.
+ */
+
+ errno = 0;
+ tot = 0;
+ oval = res;
+ while (*res) {
+ rlim_t tim = strtoq(res, &ep, 0);
+ rlim_t mult = 1;
+
+ if (ep == NULL || ep == res || errno != 0) {
+ invalid:
+ syslog(LOG_WARNING, "login_getcaptime: class '%s' bad value %s=%s",
+ lc->lc_class, cap, oval);
+ errno = ERANGE;
+ return error;
+ }
+ /* Look for suffixes */
+ switch (*ep++) {
+ case 0:
+ ep--;
+ break; /* end of string */
+ case 's': case 'S': /* seconds */
+ break;
+ case 'm': case 'M': /* minutes */
+ mult = 60;
+ break;
+ case 'h': case 'H': /* hours */
+ mult = 60L * 60L;
+ break;
+ case 'd': case 'D': /* days */
+ mult = 60L * 60L * 24L;
+ break;
+ case 'w': case 'W': /* weeks */
+ mult = 60L * 60L * 24L * 7L;
+ break;
+ case 'y': case 'Y': /* 365-day years */
+ mult = 60L * 60L * 24L * 365L;
+ break;
+ default:
+ goto invalid;
+ }
+ res = ep;
+ tot += rmultiply(tim, mult);
+ if (errno)
+ goto invalid;
+ }
+
+ return tot;
+}
+
+
+/*
+ * login_getcapnum()
+ * From the login_cap_t <lc>, extract the numerical value <cap>.
+ * If it is not present, return <def> for a default, and return
+ * <error> if there is an error.
+ * Like login_getcaptime(), only it only converts to a number, not
+ * to a time; "infinity" and "inf" are 'special.'
+ */
+
+rlim_t
+login_getcapnum(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error)
+{
+ char *ep, *res;
+ int r;
+ rlim_t val;
+
+ if (lc == NULL || lc->lc_cap == NULL)
+ return def;
+
+ /*
+ * For BSDI compatibility, try for the tag=<val> first
+ */
+ if ((r = cgetstr(lc->lc_cap, (char *)cap, &res)) == -1) {
+ long lval;
+ /* string capability not present, so try for tag#<val> as numeric */
+ if ((r = cgetnum(lc->lc_cap, (char *)cap, &lval)) == -1)
+ return def; /* Not there, so return default */
+ else if (r >= 0)
+ return (rlim_t)lval;
+ }
+
+ if (r < 0) {
+ errno = ERANGE;
+ return error;
+ }
+
+ if (isinfinite(res))
+ return RLIM_INFINITY;
+
+ errno = 0;
+ val = strtoq(res, &ep, 0);
+ if (ep == NULL || ep == res || errno != 0) {
+ syslog(LOG_WARNING, "login_getcapnum: class '%s' bad value %s=%s",
+ lc->lc_class, cap, res);
+ errno = ERANGE;
+ return error;
+ }
+
+ return val;
+}
+
+
+
+/*
+ * login_getcapsize()
+ * From the login_cap_t <lc>, extract the capability <cap>, which is
+ * formatted as a size (e.g., "<cap>=10M"); it can also be "infinity".
+ * If not present, return <def>, or <error> if there is an error of
+ * some sort.
+ */
+
+rlim_t
+login_getcapsize(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error)
+{
+ char *ep, *res, *oval;
+ int r;
+ rlim_t tot;
+
+ if (lc == NULL || lc->lc_cap == NULL)
+ return def;
+
+ if ((r = cgetstr(lc->lc_cap, (char *)cap, &res)) == -1)
+ return def;
+ else if (r < 0) {
+ errno = ERANGE;
+ return error;
+ }
+
+ if (isinfinite(res))
+ return RLIM_INFINITY;
+
+ errno = 0;
+ tot = 0;
+ oval = res;
+ while (*res) {
+ rlim_t siz = strtoq(res, &ep, 0);
+ rlim_t mult = 1;
+
+ if (ep == NULL || ep == res || errno != 0) {
+ invalid:
+ syslog(LOG_WARNING, "login_getcapsize: class '%s' bad value %s=%s",
+ lc->lc_class, cap, oval);
+ errno = ERANGE;
+ return error;
+ }
+ switch (*ep++) {
+ case 0: /* end of string */
+ ep--;
+ break;
+ case 'b': case 'B': /* 512-byte blocks */
+ mult = 512;
+ break;
+ case 'k': case 'K': /* 1024-byte Kilobytes */
+ mult = 1024;
+ break;
+ case 'm': case 'M': /* 1024-k kbytes */
+ mult = 1024 * 1024;
+ break;
+ case 'g': case 'G': /* 1Gbyte */
+ mult = 1024 * 1024 * 1024;
+ break;
+ case 't': case 'T': /* 1TBte */
+ mult = 1024LL * 1024LL * 1024LL * 1024LL;
+ break;
+ default:
+ goto invalid;
+ }
+ res = ep;
+ tot += rmultiply(siz, mult);
+ if (errno)
+ goto invalid;
+ }
+
+ return tot;
+}
+
+
+/*
+ * login_getcapbool()
+ * From the login_cap_t <lc>, check for the existance of the capability
+ * of <cap>. Return <def> if <lc>->lc_cap is NULL, otherwise return
+ * the whether or not <cap> exists there.
+ */
+
+int
+login_getcapbool(login_cap_t *lc, const char *cap, int def)
+{
+ if (lc == NULL || lc->lc_cap == NULL)
+ return def;
+ return (cgetcap(lc->lc_cap, (char *)cap, ':') != NULL);
+}
+
+
+/*
+ * login_getstyle()
+ * Given a login_cap entry <lc>, and optionally a type of auth <auth>,
+ * and optionally a style <style>, find the style that best suits these
+ * rules:
+ * 1. If <auth> is non-null, look for an "auth-<auth>=" string
+ * in the capability; if not present, default to "auth=".
+ * 2. If there is no auth list found from (1), default to
+ * "passwd" as an authorization list.
+ * 3. If <style> is non-null, look for <style> in the list of
+ * authorization methods found from (2); if <style> is NULL, default
+ * to LOGIN_DEFSTYLE ("passwd").
+ * 4. If the chosen style is found in the chosen list of authorization
+ * methods, return that; otherwise, return NULL.
+ * E.g.:
+ * login_getstyle(lc, NULL, "ftp");
+ * login_getstyle(lc, "login", NULL);
+ * login_getstyle(lc, "skey", "network");
+ */
+
+char *
+login_getstyle(login_cap_t *lc, char *style, const char *auth)
+{
+ int i;
+ char **authtypes = NULL;
+ char *auths= NULL;
+ char realauth[64];
+
+ static char *defauthtypes[] = { LOGIN_DEFSTYLE, NULL };
+
+ if (auth != NULL && *auth != '\0') {
+ if (snprintf(realauth, sizeof realauth, "auth-%s", auth) < sizeof realauth)
+ authtypes = login_getcaplist(lc, realauth, NULL);
+ }
+
+ if (authtypes == NULL)
+ authtypes = login_getcaplist(lc, "auth", NULL);
+
+ if (authtypes == NULL)
+ authtypes = defauthtypes;
+
+ /*
+ * We have at least one authtype now; auths is a comma-seperated
+ * (or space-separated) list of authentication types. We have to
+ * convert from this to an array of char*'s; authtypes then gets this.
+ */
+ i = 0;
+ if (style != NULL && *style != '\0') {
+ while (authtypes[i] != NULL && strcmp(style, authtypes[i]) != 0)
+ i++;
+ }
+
+ lc->lc_style = NULL;
+ if (authtypes[i] != NULL && (auths = strdup(authtypes[i])) != NULL)
+ lc->lc_style = auths;
+
+ if (lc->lc_style != NULL)
+ lc->lc_style = strdup(lc->lc_style);
+
+ return lc->lc_style;
+}
diff --git a/lib/libutil/login_cap.h b/lib/libutil/login_cap.h
new file mode 100644
index 0000000..f4b3825
--- /dev/null
+++ b/lib/libutil/login_cap.h
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 1996 by
+ * Sean Eric Fagan <sef@kithrup.com>
+ * David Nugent <davidn@blaze.net.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. This work was done expressly for inclusion into FreeBSD. Other use
+ * is permitted provided this notation is included.
+ * 4. Absolutely no warranty of function or purpose is made by the authors.
+ * 5. Modifications may be freely made to this file providing the above
+ * conditions are met.
+ *
+ * Low-level routines relating to the user capabilities database
+ *
+ * Was login_cap.h,v 1.9 1997/05/07 20:00:01 eivind Exp
+ * $FreeBSD$
+ */
+
+#ifndef _LOGIN_CAP_H_
+#define _LOGIN_CAP_H_
+
+#define LOGIN_DEFCLASS "default"
+#define LOGIN_DEFROOTCLASS "root"
+#define LOGIN_MECLASS "me"
+#define LOGIN_DEFSTYLE "passwd"
+#define LOGIN_DEFSERVICE "login"
+#define LOGIN_DEFUMASK 022
+#define LOGIN_DEFPRI 0
+#define _PATH_LOGIN_CONF "/etc/login.conf"
+#define _FILE_LOGIN_CONF ".login_conf"
+#define _PATH_AUTHPROG "/usr/libexec/login_"
+
+#define LOGIN_SETGROUP 0x0001 /* set group */
+#define LOGIN_SETLOGIN 0x0002 /* set login (via setlogin) */
+#define LOGIN_SETPATH 0x0004 /* set path */
+#define LOGIN_SETPRIORITY 0x0008 /* set priority */
+#define LOGIN_SETRESOURCES 0x0010 /* set resources (cputime, etc.) */
+#define LOGIN_SETUMASK 0x0020 /* set umask, obviously */
+#define LOGIN_SETUSER 0x0040 /* set user (via setuid) */
+#define LOGIN_SETENV 0x0080 /* set user environment */
+#define LOGIN_SETALL 0x00ff /* set everything */
+
+#define BI_AUTH "authorize" /* accepted authentication */
+#define BI_REJECT "reject" /* rejected authentication */
+#define BI_CHALLENG "reject challenge" /* reject with a challenge */
+#define BI_SILENT "reject silent" /* reject silently */
+#define BI_REMOVE "remove" /* remove file on error */
+#define BI_ROOTOKAY "authorize root" /* root authenticated */
+#define BI_SECURE "authorize secure" /* okay on non-secure line */
+#define BI_SETENV "setenv" /* set environment variable */
+#define BI_VALUE "value" /* set local variable */
+
+#define AUTH_OKAY 0x01 /* user authenticated */
+#define AUTH_ROOTOKAY 0x02 /* root login okay */
+#define AUTH_SECURE 0x04 /* secure login */
+#define AUTH_SILENT 0x08 /* silent rejection */
+#define AUTH_CHALLENGE 0x10 /* a chellenge was given */
+
+#define AUTH_ALLOW (AUTH_OKAY | AUTH_ROOTOKAY | AUTH_SECURE)
+
+typedef struct login_cap {
+ char *lc_class;
+ char *lc_cap;
+ char *lc_style;
+} login_cap_t;
+
+typedef struct login_time {
+ u_short lt_start; /* Start time */
+ u_short lt_end; /* End time */
+#define LTM_NONE 0x00
+#define LTM_SUN 0x01
+#define LTM_MON 0x02
+#define LTM_TUE 0x04
+#define LTM_WED 0x08
+#define LTM_THU 0x10
+#define LTM_FRI 0x20
+#define LTM_SAT 0x40
+#define LTM_ANY 0x7F
+#define LTM_WK 0x3E
+#define LTM_WD 0x41
+ u_char lt_dow; /* Days of week */
+} login_time_t;
+
+#define LC_MAXTIMES 64
+
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+struct passwd;
+
+void login_close __P((login_cap_t *));
+login_cap_t *login_getclassbyname __P((const char *, const struct passwd *));
+login_cap_t *login_getclass __P((const char *));
+login_cap_t *login_getpwclass __P((const struct passwd *));
+login_cap_t *login_getuserclass __P((const struct passwd *));
+
+char *login_getcapstr __P((login_cap_t*, const char *, char *, char *));
+char **login_getcaplist __P((login_cap_t *, const char *, const char *));
+char *login_getstyle __P((login_cap_t *, char *, const char *));
+rlim_t login_getcaptime __P((login_cap_t *, const char *, rlim_t, rlim_t));
+rlim_t login_getcapnum __P((login_cap_t *, const char *, rlim_t, rlim_t));
+rlim_t login_getcapsize __P((login_cap_t *, const char *, rlim_t, rlim_t));
+char *login_getpath __P((login_cap_t *, const char *, char *));
+int login_getcapbool __P((login_cap_t *, const char *, int));
+
+int setclasscontext __P((const char*, unsigned int));
+int setusercontext __P((login_cap_t*, const struct passwd*, uid_t, unsigned int));
+void setclassresources __P((login_cap_t *));
+void setclassenvironment __P((login_cap_t *, const struct passwd *, int));
+
+/* Most of these functions are deprecated */
+int auth_approve __P((login_cap_t*, const char*, const char*));
+int auth_check __P((const char *, const char *, const char *, const char *, int *));
+void auth_env __P((void));
+char *auth_mkvalue __P((const char *n));
+int auth_response __P((const char *, const char *, const char *, const char *, int *, const char *, const char *));
+void auth_rmfiles __P((void));
+int auth_scan __P((int));
+int auth_script __P((const char*, ...));
+int auth_script_data __P((const char *, int, const char *, ...));
+char *auth_valud __P((const char *));
+int auth_setopt __P((const char *, const char *));
+void auth_clropts __P((void));
+
+void auth_checknologin __P((login_cap_t*));
+int auth_cat __P((const char*));
+
+int auth_ttyok __P((login_cap_t*, const char *));
+int auth_hostok __P((login_cap_t*, const char *, char const *));
+int auth_timeok __P((login_cap_t*, time_t));
+
+struct tm;
+
+login_time_t parse_lt __P((const char *));
+int in_ltm __P((const login_time_t *, struct tm *, time_t *));
+int in_ltms __P((const login_time_t *, struct tm *, time_t *));
+
+/* helper functions */
+
+int login_strinlist __P((char **, char const *, int));
+int login_str2inlist __P((char **, const char *, const char *, int));
+login_time_t * login_timelist __P((login_cap_t *, char const *, int *, login_time_t **));
+int login_ttyok __P((login_cap_t *, const char *, const char *, const char *));
+int login_hostok __P((login_cap_t *, const char *, const char *, const char *, const char *));
+
+__END_DECLS
+
+#endif /* _LOGIN_CAP_H_ */
diff --git a/lib/libutil/login_class.3 b/lib/libutil/login_class.3
new file mode 100644
index 0000000..edbaa89
--- /dev/null
+++ b/lib/libutil/login_class.3
@@ -0,0 +1,188 @@
+.\" Copyright (c) 1995 David Nugent <davidn@blaze.net.au>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, is permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice immediately at the beginning of the file, without modification,
+.\" this list of conditions, and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. This work was done expressly for inclusion into FreeBSD. Other use
+.\" is permitted provided this notation is included.
+.\" 4. Absolutely no warranty of function or purpose is made by the author
+.\" David Nugent.
+.\" 5. Modifications may be freely made to this file providing the above
+.\" conditions are met.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 28, 1996
+.Os FreeBSD
+.Dt LOGIN_CLASS 3
+.Sh NAME
+.Nm setclasscontext ,
+.Nm setusercontext ,
+.Nm setclassresources ,
+.Nm setclassenvironment
+.Nd functions for using the login class capabilities database.
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <login_cap.h>
+.Ft int
+.Fn setclasscontext "const char *classname" "unsigned int flags"
+.Ft int
+.Fn setusercontext "login_cap_t *lc" "const struct passwd *pwd" "uid_t uid" "unsigned int flags"
+.Ft void
+.Fn setclassresources "login_cap_t *lc"
+.Ft void
+.Fn setclassenvironment "login_cap_t *lc" "const struct passwd *pwd" "int paths"
+.Pp
+.Sh DESCRIPTION
+These functions provide a higher level interface to the login class
+database than those documented in
+.Xr login_cap 3 .
+These functions are used to set resource limits, environment and
+accounting settings for users on logging into the system and when
+selecting an appropriate set of environment and resource settings
+for system daemons based on login classes.
+These functions may only be called if the current process is
+running with root privileges.
+If the LOGIN_SETLOGIN flag is used this function calls
+.Xr setlogin 2 ,
+and due care must be taken as detailed in the manpage for that
+function and this affects all processes running in the same session
+and not just the current process.
+.Pp
+.Fn setclasscontext
+sets various class context values (resource limits, umask and
+process priorities) based on values for a specific named class.
+.Pp
+The function
+.Fn setusercontext
+sets class context values based on a given login_cap_t
+object, a specific passwd record (if login_cap_t is NULL),
+sets the current session's login and the current process
+user and group ownership.
+Each of these functions is selectable via bit-flags passed
+in the
+.Ar flags
+parameter, which is comprised of one or more of the following:
+.Bl -tag -width LOGIN_SETRESOURCES
+.It LOGIN_SETLOGIN
+Set the login associated with the current session to the user
+specified in the passwd structure.
+.Xr setlogin 2 .
+The
+.Ar pwd
+parameter must not be NULL if this option is used.
+.It LOGIN_SETUSER
+Set ownship of the current process to the uid specified in the
+.Ar uid
+parameter using
+.Xr setuid 2 .
+.It LOGIN_SETGROUP
+Set group ownership of the current process to the group id
+specified in the passwd structure using
+.Xr setgid 2 ,
+and calls
+.Xr initgroups 3
+to set up the group access list for the current process.
+The
+.Ar pwd
+parameter must not be NULL if this option is used.
+.It LOGIN_SETRESOURCES
+Set resource limits for the current process based on values
+specified in the system login class database.
+Class capability tags used, with and without -cur (soft limit)
+or -max (hard limit) suffixes and the corresponding resource
+setting:
+.Bd -literal
+cputime RLIMIT_CPU
+filesize RLIMIT_FSIZE
+datasize RLIMIT_DATA
+stacksize RLIMIT_STACK
+coredumpsize RLIMIT_CORE
+memoryuse RLIMIT_RSS
+memorylocked RLIMIT_MEMLOCK
+maxproc RLIMIT_NPROC
+openfiles RLIMIT_NOFILE
+sbsize RLIMIT_SBSIZE
+.Ed
+.It LOGIN_SETPRIORITY
+Set the scheduling priority for the current process based on the
+value specified in the system login class database.
+Class capability tags used:
+.Bd -literal
+priority
+.Ed
+.It LOGIN_SETUMASK
+Set the umask for the current process to a value in the user or
+system login class database.
+Class capability tags used:
+.Bd -literal
+umask
+.Ed
+.It LOGIN_SETPATH
+Set the "path" and "manpath" environment variables based on values
+in the user or system login class database.
+Class capability tags used with the corresponding environment
+variables set:
+.Bd -literal
+path PATH
+manpath MANPATH
+.Ed
+.It LOGIN_SETENV
+Set various environment variables based on values in the user or
+system login class database.
+Class capability tags used with the corresponding environment
+variables set:
+.Bd -literal
+lang LANG
+charset MM_CHARSET
+timezone TZ
+term TERM
+.Ed
+.Pp
+Additional environment variables may be set using the list type
+capability "setenv=var1 val1,var2 val2..,varN valN".
+.It LOGIN_SETALL
+Enables all of the above settings.
+.El
+.Pp
+Note that when setting environment variables and a valid passwd
+pointer is provided in the
+.Ar pwd
+parameter, the characters
+.Ql \&~
+and
+.Ql \&$
+are substituted for the user's home directory and login name
+respectively.
+.Pp
+The
+.Fn setclassresources
+and
+.Fn setclassenvironment
+functions are subsets of the setcontext functions above, but may
+be useful in isolation.
+.Sh RETURN VALUES
+.Fn setclasscontext
+and
+.Fn setusercontext
+return -1 if an error occurred, or 0 on success.
+If an error occurs when attempting to set the user, login, group
+or resources, a message is reported to
+.Xr syslog 3 ,
+with LOG_ERR priority and directed to the currently active facility.
+.Sh SEE ALSO
+.Xr setgid 2 ,
+.Xr setlogin 2 ,
+.Xr setuid 2 ,
+.Xr getcap 3 ,
+.Xr initgroups 3 ,
+.Xr login_cap 3 ,
+.Xr login.conf 5 ,
+.Xr termcap 5
diff --git a/lib/libutil/login_class.c b/lib/libutil/login_class.c
new file mode 100644
index 0000000..2cd65bd
--- /dev/null
+++ b/lib/libutil/login_class.c
@@ -0,0 +1,411 @@
+/*-
+ * Copyright (c) 1996 by
+ * Sean Eric Fagan <sef@kithrup.com>
+ * David Nugent <davidn@blaze.net.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. This work was done expressly for inclusion into FreeBSD. Other use
+ * is permitted provided this notation is included.
+ * 4. Absolutely no warranty of function or purpose is made by the authors.
+ * 5. Modifications may be freely made to this file providing the above
+ * conditions are met.
+ *
+ * High-level routines relating to use of the user capabilities database
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <syslog.h>
+#include <login_cap.h>
+#include <paths.h>
+#include <sys/rtprio.h>
+
+
+#undef UNKNOWN
+#define UNKNOWN "su"
+
+
+static struct login_res {
+ const char *what;
+ rlim_t (*who)(login_cap_t *, const char *, rlim_t, rlim_t);
+ int why;
+} resources[] = {
+ { "cputime", login_getcaptime, RLIMIT_CPU },
+ { "filesize", login_getcapsize, RLIMIT_FSIZE },
+ { "datasize", login_getcapsize, RLIMIT_DATA },
+ { "stacksize", login_getcapsize, RLIMIT_STACK },
+ { "memoryuse", login_getcapsize, RLIMIT_RSS },
+ { "memorylocked", login_getcapsize, RLIMIT_MEMLOCK },
+ { "maxproc", login_getcapnum, RLIMIT_NPROC },
+ { "openfiles", login_getcapnum, RLIMIT_NOFILE },
+ { "coredumpsize", login_getcapsize, RLIMIT_CORE },
+ { "sbsize", login_getcapnum, RLIMIT_SBSIZE },
+ { NULL, 0, 0 }
+};
+
+
+void
+setclassresources(login_cap_t *lc)
+{
+ struct login_res *lr;
+
+ if (lc == NULL)
+ return;
+
+ for (lr = resources; lr->what != NULL; ++lr) {
+ struct rlimit rlim;
+
+ /*
+ * The login.conf file can have <limit>, <limit>-max, and
+ * <limit>-cur entries.
+ * What we do is get the current current- and maximum- limits.
+ * Then, we try to get an entry for <limit> from the capability,
+ * using the current and max limits we just got as the
+ * default/error values.
+ * *Then*, we try looking for <limit>-cur and <limit>-max,
+ * again using the appropriate values as the default/error
+ * conditions.
+ */
+
+ if (getrlimit(lr->why, &rlim) != 0)
+ syslog(LOG_ERR, "getting %s resource limit: %m", lr->what);
+ else {
+ char name_cur[40];
+ char name_max[40];
+ rlim_t rcur = rlim.rlim_cur;
+ rlim_t rmax = rlim.rlim_max;
+
+ sprintf(name_cur, "%s-cur", lr->what);
+ sprintf(name_max, "%s-max", lr->what);
+
+ rcur = (*lr->who)(lc, lr->what, rcur, rcur);
+ rmax = (*lr->who)(lc, lr->what, rmax, rmax);
+ rlim.rlim_cur = (*lr->who)(lc, name_cur, rcur, rcur);
+ rlim.rlim_max = (*lr->who)(lc, name_max, rmax, rmax);
+
+ if (setrlimit(lr->why, &rlim) == -1)
+ syslog(LOG_WARNING, "set class '%s' resource limit %s: %m", lc->lc_class, lr->what);
+ }
+ }
+}
+
+
+
+static struct login_vars {
+ const char *tag;
+ const char *var;
+ const char *def;
+} pathvars[] = {
+ { "path", "PATH", NULL },
+ { "cdpath", "CDPATH", NULL },
+ { "manpath", "MANPATH", NULL },
+ { NULL, NULL, NULL }
+}, envars[] = {
+ { "lang", "LANG", NULL },
+ { "charset", "MM_CHARSET", NULL },
+ { "timezone", "TZ", NULL },
+ { "term", "TERM", UNKNOWN },
+ { NULL, NULL, NULL }
+};
+
+static char *
+substvar(char * var, const struct passwd * pwd, int hlen, int pch, int nlen)
+{
+ char *np = NULL;
+
+ if (var != NULL) {
+ int tildes = 0;
+ int dollas = 0;
+ char *p;
+
+ if (pwd != NULL) {
+ /* Count the number of ~'s in var to substitute */
+ p = var;
+ for (p = var; (p = strchr(p, '~')) != NULL; p++)
+ ++tildes;
+ /* Count the number of $'s in var to substitute */
+ p = var;
+ for (p = var; (p = strchr(p, '$')) != NULL; p++)
+ ++dollas;
+ }
+
+ np = malloc(strlen(var) + (dollas * nlen)
+ - dollas + (tildes * (pch+hlen))
+ - tildes + 1);
+
+ if (np != NULL) {
+ p = strcpy(np, var);
+
+ if (pwd != NULL) {
+ /*
+ * This loop does user username and homedir substitutions
+ * for unescaped $ (username) and ~ (homedir)
+ */
+ while (*(p += strcspn(p, "~$")) != '\0') {
+ int l = strlen(p);
+
+ if (p > np && *(p-1) == '\\') /* Escaped: */
+ memmove(p - 1, p, l + 1); /* Slide-out the backslash */
+ else if (*p == '~') {
+ int v = pch && *(p+1) != '/'; /* Avoid double // */
+ memmove(p + hlen + v, p + 1, l); /* Subst homedir */
+ memmove(p, pwd->pw_dir, hlen);
+ if (v)
+ p[hlen] = '/';
+ p += hlen + v;
+ }
+ else /* if (*p == '$') */ {
+ memmove(p + nlen, p + 1, l); /* Subst username */
+ memmove(p, pwd->pw_name, nlen);
+ p += nlen;
+ }
+ }
+ }
+ }
+ }
+
+ return np;
+}
+
+
+void
+setclassenvironment(login_cap_t *lc, const struct passwd * pwd, int paths)
+{
+ struct login_vars *vars = paths ? pathvars : envars;
+ int hlen = pwd ? strlen(pwd->pw_dir) : 0;
+ int nlen = pwd ? strlen(pwd->pw_name) : 0;
+ char pch = 0;
+
+ if (hlen && pwd->pw_dir[hlen-1] != '/')
+ ++pch;
+
+ while (vars->tag != NULL) {
+ char * var = paths ? login_getpath(lc, vars->tag, NULL)
+ : login_getcapstr(lc, vars->tag, NULL, NULL);
+
+ char * np = substvar(var, pwd, hlen, pch, nlen);
+
+ if (np != NULL) {
+ setenv(vars->var, np, 1);
+ free(np);
+ } else if (vars->def != NULL) {
+ setenv(vars->var, vars->def, 0);
+ }
+ ++vars;
+ }
+
+ /*
+ * If we're not processing paths, then see if there is a setenv list by
+ * which the admin and/or user may set an arbitrary set of env vars.
+ */
+ if (!paths) {
+ char **set_env = login_getcaplist(lc, "setenv", ",");
+
+ if (set_env != NULL) {
+ while (*set_env != NULL) {
+ char *p = strchr(*set_env, '=');
+
+ if (p != NULL) { /* Discard invalid entries */
+ char *np;
+
+ *p++ = '\0';
+ if ((np = substvar(p, pwd, hlen, pch, nlen)) != NULL) {
+ setenv(*set_env, np, 1);
+ free(np);
+ }
+ }
+ ++set_env;
+ }
+ }
+ }
+}
+
+
+/*
+ * setclasscontext()
+ *
+ * For the login class <class>, set various class context values
+ * (limits, mainly) to the values for that class. Which values are
+ * set are controlled by <flags> -- see <login_class.h> for the
+ * possible values.
+ *
+ * setclasscontext() can only set resources, priority, and umask.
+ */
+
+int
+setclasscontext(const char *classname, unsigned int flags)
+{
+ int rc;
+ login_cap_t *lc;
+
+ lc = login_getclassbyname(classname, NULL);
+
+ flags &= LOGIN_SETRESOURCES | LOGIN_SETPRIORITY |
+ LOGIN_SETUMASK | LOGIN_SETPATH;
+
+ rc = lc ? setusercontext(lc, NULL, 0, flags) : -1;
+ login_close(lc);
+ return rc;
+}
+
+
+
+/*
+ * Private functionw which takes care of processing
+ */
+
+static mode_t
+setlogincontext(login_cap_t *lc, const struct passwd *pwd,
+ mode_t mymask, unsigned long flags)
+{
+ if (lc) {
+ /* Set resources */
+ if (flags & LOGIN_SETRESOURCES)
+ setclassresources(lc);
+ /* See if there's a umask override */
+ if (flags & LOGIN_SETUMASK)
+ mymask = (mode_t)login_getcapnum(lc, "umask", mymask, mymask);
+ /* Set paths */
+ if (flags & LOGIN_SETPATH)
+ setclassenvironment(lc, pwd, 1);
+ /* Set environment */
+ if (flags & LOGIN_SETENV)
+ setclassenvironment(lc, pwd, 0);
+ }
+ return mymask;
+}
+
+
+
+/*
+ * setusercontext()
+ *
+ * Given a login class <lc> and a user in <pwd>, with a uid <uid>,
+ * set the context as in setclasscontext(). <flags> controls which
+ * values are set.
+ *
+ * The difference between setclasscontext() and setusercontext() is
+ * that the former sets things up for an already-existing process,
+ * while the latter sets things up from a root context. Such as might
+ * be called from login(1).
+ *
+ */
+
+int
+setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned int flags)
+{
+ quad_t p;
+ mode_t mymask;
+ login_cap_t *llc = NULL;
+#ifndef __NETBSD_SYSCALLS
+ struct rtprio rtp;
+#endif
+
+ if (lc == NULL) {
+ if (pwd != NULL && (lc = login_getpwclass(pwd)) != NULL)
+ llc = lc; /* free this when we're done */
+ }
+
+ if (flags & LOGIN_SETPATH)
+ pathvars[0].def = uid ? _PATH_DEFPATH : _PATH_STDPATH;
+
+ /* we need a passwd entry to set these */
+ if (pwd == NULL)
+ flags &= ~(LOGIN_SETGROUP | LOGIN_SETLOGIN);
+
+ /* Set the process priority */
+ if (flags & LOGIN_SETPRIORITY) {
+ p = login_getcapnum(lc, "priority", LOGIN_DEFPRI, LOGIN_DEFPRI);
+
+ if(p > PRIO_MAX) {
+#ifndef __NETBSD_SYSCALLS
+ rtp.type = RTP_PRIO_IDLE;
+ rtp.prio = p - PRIO_MAX - 1;
+ p = (rtp.prio > RTP_PRIO_MAX) ? 31 : p;
+ if(rtprio(RTP_SET, 0, &rtp))
+ syslog(LOG_WARNING, "rtprio '%s' (%s): %m",
+ pwd->pw_name, lc ? lc->lc_class : LOGIN_DEFCLASS);
+#endif
+ } else if(p < PRIO_MIN) {
+#ifndef __NETBSD_SYSCALLS
+ rtp.type = RTP_PRIO_REALTIME;
+ rtp.prio = abs(p - PRIO_MIN + RTP_PRIO_MAX);
+ p = (rtp.prio > RTP_PRIO_MAX) ? 1 : p;
+ if(rtprio(RTP_SET, 0, &rtp))
+ syslog(LOG_WARNING, "rtprio '%s' (%s): %m",
+ pwd->pw_name, lc ? lc->lc_class : LOGIN_DEFCLASS);
+#endif
+ } else {
+ if (setpriority(PRIO_PROCESS, 0, (int)p) != 0)
+ syslog(LOG_WARNING, "setpriority '%s' (%s): %m",
+ pwd->pw_name, lc ? lc->lc_class : LOGIN_DEFCLASS);
+ }
+ }
+
+ /* Setup the user's group permissions */
+ if (flags & LOGIN_SETGROUP) {
+ if (setgid(pwd->pw_gid) != 0) {
+ syslog(LOG_ERR, "setgid(%lu): %m", (u_long)pwd->pw_gid);
+ login_close(llc);
+ return -1;
+ }
+ if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) {
+ syslog(LOG_ERR, "initgroups(%s,%lu): %m", pwd->pw_name,
+ (u_long)pwd->pw_gid);
+ login_close(llc);
+ return -1;
+ }
+ }
+
+ /* Set the sessions login */
+ if ((flags & LOGIN_SETLOGIN) && setlogin(pwd->pw_name) != 0) {
+ syslog(LOG_ERR, "setlogin(%s): %m", pwd->pw_name);
+ login_close(llc);
+ return -1;
+ }
+
+ mymask = (flags & LOGIN_SETUMASK) ? umask(LOGIN_DEFUMASK) : 0;
+ mymask = setlogincontext(lc, pwd, mymask, flags);
+ login_close(llc);
+
+ /* This needs to be done after anything that needs root privs */
+ if ((flags & LOGIN_SETUSER) && setuid(uid) != 0) {
+ syslog(LOG_ERR, "setuid(%lu): %m", (u_long)uid);
+ return -1; /* Paranoia again */
+ }
+
+ /*
+ * Now, we repeat some of the above for the user's private entries
+ */
+ if ((lc = login_getuserclass(pwd)) != NULL) {
+ mymask = setlogincontext(lc, pwd, mymask, flags);
+ login_close(lc);
+ }
+
+ /* Finally, set any umask we've found */
+ if (flags & LOGIN_SETUMASK)
+ umask(mymask);
+
+ return 0;
+}
+
diff --git a/lib/libutil/login_ok.3 b/lib/libutil/login_ok.3
new file mode 100644
index 0000000..a19362d
--- /dev/null
+++ b/lib/libutil/login_ok.3
@@ -0,0 +1,138 @@
+.\" Copyright (c) 1995 David Nugent <davidn@blaze.net.au>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, is permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice immediately at the beginning of the file, without modification,
+.\" this list of conditions, and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. This work was done expressly for inclusion into FreeBSD. Other use
+.\" is permitted provided this notation is included.
+.\" 4. Absolutely no warranty of function or purpose is made by the author
+.\" David Nugent.
+.\" 5. Modifications may be freely made to this file providing the above
+.\" conditions are met.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd January 2, 1997
+.Os FreeBSD
+.Dt LOGIN_OK 3
+.Sh NAME
+.Nm auth_ttyok ,
+.Nm auth_hostok ,
+.Nm auth_timeok
+.Nd functions for checking login class based login restrictions
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <time.h>
+.Fd #include <login_cap.h>
+.Ft int
+.Fn auth_ttyok "login_cap_t *lc" "const char *tty"
+.Ft int
+.Fn auth_hostok "login_cap_t *lc" "const char *host" "char const *ip"
+.Ft int
+.Fn auth_timeok "login_cap_t *lc" "time_t t"
+.Sh DESCRIPTION
+This set of functions checks to see if login is allowed based on login
+class capability entries in the login database,
+.Xr login.conf 5 .
+.Pp
+.Fn auth_ttyok
+checks to see if the named tty is available to users of a specific
+class, and is either in the
+.Em ttys.allow
+access list, and not in
+the
+.Em ttys.deny
+access list.
+An empty
+.Em ttys.allow
+list (or if no such capability exists for
+the give login class) logins via any tty device are allowed unless
+the
+.Em ttys.deny
+list exists and is non-empty, and the device or its
+tty group (see
+.Xr ttys 5 )
+is not in the list.
+Access to ttys may be allowed or restricted specifically by tty device
+name, a device name which includes a wildcard (e.g. ttyD* or cuaD*),
+or may name a ttygroup, when group=<name> tags have been assigned in
+.Pa /etc/ttys .
+Matching of ttys and ttygroups is case sensitive.
+Passing a
+.Dv NULL
+or empty string as the
+.Ar tty
+parameter causes the function to return a non-zero value.
+.Pp
+.Fn auth_hostok
+checks for any host restrictions for remote logins.
+The function checks on both a host name and IP address (given in its
+text form, typically n.n.n.n) against the
+.Em host.allow
+and
+.Em host.deny
+login class capabilities.
+As with ttys and their groups, wildcards and character classes may be
+used in the host allow and deny capability records.
+The
+.Xr fnmatch 3
+function is used for matching, and the matching on hostnames is case
+insensitive.
+Note that this function expects that the hostname is fully expanded
+(i.e. the local domain name added if necessary) and the IP address
+is in its canonical form.
+No hostname or address lookups are attempted.
+.Pp
+It is possible to call this function with either the hostname or
+the IP address missing (i.e.
+.Dv NULL )
+and matching will be performed
+only on the basis of the parameter given.
+Passing
+.Dv NULL
+or empty strings in both parameters will result in
+a non-zero return value.
+.Pp
+The
+.Fn auth_timeok
+function checks to see that a given time value is within the
+.Em times.allow
+login class capability and not within the
+.Em times.deny
+access lists.
+An empty or non-existent
+.Em times.allow
+list allows access at any
+time, except if a given time is falls within a period in the
+.Em times.deny
+list.
+The format of time period records contained in both
+.Em times.allow
+and
+.Em times.deny
+capability fields is explained in detail in the
+.Xr login_times 3
+manual page.
+.Sh RETURN VALUES
+A non-zero return value from any of these functions indicates that
+login access is granted.
+A zero return value means either that the item being tested is not
+in the
+.Em allow
+access list, or is within the
+.Em deny
+access list.
+.Sh SEE ALSO
+.Xr getcap 3 ,
+.Xr login_cap 3 ,
+.Xr login_class 3 ,
+.Xr login_times 3 ,
+.Xr login.conf 5 ,
+.Xr termcap 5
diff --git a/lib/libutil/login_ok.c b/lib/libutil/login_ok.c
new file mode 100644
index 0000000..365528b
--- /dev/null
+++ b/lib/libutil/login_ok.c
@@ -0,0 +1,250 @@
+/*-
+ * Copyright (c) 1996 by
+ * David Nugent <davidn@blaze.net.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. This work was done expressly for inclusion into FreeBSD. Other use
+ * is permitted provided this notation is included.
+ * 4. Absolutely no warranty of function or purpose is made by the authors.
+ * 5. Modifications may be freely made to this file providing the above
+ * conditions are met.
+ *
+ * Support allow/deny lists in login class capabilities
+ *
+ * $FreeBSD$
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <ttyent.h>
+#include <fnmatch.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/param.h>
+#include <login_cap.h>
+
+
+/* -- support functions -- */
+
+/*
+ * login_strinlist()
+ * This function is intentionally public - reused by TAS.
+ * Returns TRUE (non-zero) if a string matches a pattern
+ * in a given array of patterns. 'flags' is passed directly
+ * to fnmatch(3).
+ */
+
+int
+login_strinlist(char **list, char const *str, int flags)
+{
+ int rc = 0;
+
+ if (str != NULL && *str != '\0') {
+ int i = 0;
+
+ while (rc == 0 && list[i] != NULL)
+ rc = fnmatch(list[i++], str, flags) == 0;
+ }
+ return rc;
+}
+
+
+/*
+ * login_str2inlist()
+ * Locate either or two strings in a given list
+ */
+
+int
+login_str2inlist(char **ttlst, const char *str1, const char *str2, int flags)
+{
+ int rc = 0;
+
+ if (login_strinlist(ttlst, str1, flags))
+ rc = 1;
+ else if (login_strinlist(ttlst, str2, flags))
+ rc = 1;
+ return rc;
+}
+
+
+/*
+ * login_timelist()
+ * This function is intentinoally public - reused by TAS.
+ * Returns an allocated list of time periods given an array
+ * of time periods in ascii form.
+ */
+
+login_time_t *
+login_timelist(login_cap_t *lc, char const *cap, int *ltno,
+ login_time_t **ltptr)
+{
+ int j = 0;
+ struct login_time *lt = NULL;
+ char **tl;
+
+ if ((tl = login_getcaplist(lc, cap, NULL)) != NULL) {
+
+ while (tl[j++] != NULL)
+ ;
+ if (*ltno >= j)
+ lt = *ltptr;
+ else if ((lt = realloc(*ltptr, j)) != NULL) {
+ *ltno = j;
+ *ltptr = lt;
+ }
+ if (lt != NULL) {
+ int i = 0;
+
+ for (--j; i < j; i++)
+ lt[i] = parse_lt(tl[i]);
+ lt[i].lt_dow = LTM_NONE;
+ }
+ }
+ return lt;
+}
+
+
+/*
+ * login_ttyok()
+ * This function is a variation of auth_ttyok(), but it checks two
+ * arbitrary capability lists not necessarily related to access.
+ * This hook is provided for the accounted/exclude accounting lists.
+ */
+
+int
+login_ttyok(login_cap_t *lc, const char *tty, const char *allowcap,
+ const char *denycap)
+{
+ int rc = 1;
+
+ if (lc != NULL && tty != NULL && *tty != '\0') {
+ struct ttyent *te;
+ char *grp;
+ char **ttl;
+
+ te = getttynam(tty); /* Need group name */
+ grp = te ? te->ty_group : NULL;
+ ttl = login_getcaplist(lc, allowcap, NULL);
+
+ if (ttl != NULL && !login_str2inlist(ttl, tty, grp, 0))
+ rc = 0; /* tty or ttygroup not in allow list */
+ else {
+
+ ttl = login_getcaplist(lc, denycap, NULL);
+ if (ttl != NULL && login_str2inlist(ttl, tty, grp, 0))
+ rc = 0; /* tty or ttygroup in deny list */
+ }
+ }
+
+ return rc;
+}
+
+
+/*
+ * auth_ttyok()
+ * Determine whether or not login on a tty is accessible for
+ * a login class
+ */
+
+int
+auth_ttyok(login_cap_t *lc, const char * tty)
+{
+ return login_ttyok(lc, tty, "ttys.allow", "ttys.deny");
+}
+
+
+/*
+ * login_hostok()
+ * This function is a variation of auth_hostok(), but it checks two
+ * arbitrary capability lists not necessarily related to access.
+ * This hook is provided for the accounted/exclude accounting lists.
+ */
+
+int
+login_hostok(login_cap_t *lc, const char *host, const char *ip,
+ const char *allowcap, const char *denycap)
+{
+ int rc = 1; /* Default is ok */
+
+ if (lc != NULL &&
+ ((host != NULL && *host != '\0') || (ip != NULL && *ip != '\0'))) {
+ char **hl;
+
+ hl = login_getcaplist(lc, allowcap, NULL);
+ if (hl != NULL && !login_str2inlist(hl, host, ip, FNM_CASEFOLD))
+ rc = 0; /* host or IP not in allow list */
+ else {
+
+ hl = login_getcaplist(lc, "host.deny", NULL);
+ if (hl != NULL && login_str2inlist(hl, host, ip, FNM_CASEFOLD))
+ rc = 0; /* host or IP in deny list */
+ }
+ }
+
+ return rc;
+}
+
+
+/*
+ * auth_hostok()
+ * Determine whether or not login from a host is ok
+ */
+
+int
+auth_hostok(login_cap_t *lc, const char *host, const char *ip)
+{
+ return login_hostok(lc, host, ip, "host.allow", "host.deny");
+}
+
+
+/*
+ * auth_timeok()
+ * Determine whether or not login is ok at a given time
+ */
+
+int
+auth_timeok(login_cap_t *lc, time_t t)
+{
+ int rc = 1; /* Default is ok */
+
+ if (lc != NULL && t != (time_t)0 && t != (time_t)-1) {
+ struct tm *tptr;
+
+ static int ltimesno = 0;
+ static struct login_time *ltimes = NULL;
+
+ if ((tptr = localtime(&t)) != NULL) {
+ struct login_time *lt;
+
+ lt = login_timelist(lc, "times.allow", &ltimesno, &ltimes);
+ if (lt != NULL && in_ltms(lt, tptr, NULL) == -1)
+ rc = 0; /* not in allowed times list */
+ else {
+
+ lt = login_timelist(lc, "times.deny", &ltimesno, &ltimes);
+ if (lt != NULL && in_ltms(lt, tptr, NULL) != -1)
+ rc = 0; /* in deny times list */
+ }
+ if (ltimes) {
+ free(ltimes);
+ ltimes = NULL;
+ ltimesno = 0;
+ }
+ }
+ }
+
+ return rc;
+}
diff --git a/lib/libutil/login_times.3 b/lib/libutil/login_times.3
new file mode 100644
index 0000000..f80bd83
--- /dev/null
+++ b/lib/libutil/login_times.3
@@ -0,0 +1,155 @@
+.\" Copyright (c) 1995 David Nugent <davidn@blaze.net.au>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, is permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice immediately at the beginning of the file, without modification,
+.\" this list of conditions, and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. This work was done expressly for inclusion into FreeBSD. Other use
+.\" is permitted provided this notation is included.
+.\" 4. Absolutely no warranty of function or purpose is made by the author
+.\" David Nugent.
+.\" 5. Modifications may be freely made to this file providing the above
+.\" conditions are met.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd January 2, 1997
+.Os FreeBSD
+.Dt LOGIN_TIMES 3
+.Sh NAME
+.Nm parse_lt ,
+.Nm in_ltm ,
+.Nm in_ltms
+.Nd functions for parsing and checking login time periods
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <time.h>
+.Fd #include <login_cap.h>
+.Ft login_time_t
+.Fn parse_lt "const char *str"
+.Ft int
+.Fn in_ltm "const login_time_t *lt" "struct tm *t" "time_t *ends"
+.Ft int
+.Fn in_ltms "const login_time_t *lt" "struct tm *t" "time_t *ends"
+.Sh DESCRIPTION
+This set of functions may be used for parsing and checking login and
+session times against a predefined list of allowed login times as
+used in
+.Xr login.conf 5 .
+.Pp
+The format of allowed and disallowed session times specified in the
+.Ar times.allow
+and
+.Ar times.deny
+capability fields in a login class are comprised of a prefix which
+specifies one or more 2- or 3-character day codes, followed by
+a start and end time in 24 hour format separated by a hyphen.
+Day codes may be concatenated together to select specific days, or
+the special mnemonics "Any" and "All" (for any/all days of the week),
+"Wk" for any day of the week (excluding Saturdays and Sundays) and
+"Wd" for any weekend day may be used.
+.Pp
+For example, the following time period:
+.Dl MoThFrSa1400-2200
+is interpreted as Monday, Thursday through Saturday between the hours
+of 2pm and 10pm.
+.Dl Wd0600-1800
+means Saturday and Sunday, between the hours of 6am through 6pm, and
+.Dl Any0400-1600
+means any day of the week, between 4am and 4pm.
+.Pp
+Note that all time periods reference system local time.
+.Pp
+The
+.Fn parse_lt
+function converts the ASCII representation of a time period into
+a structure of type
+.Ft login_time_t .
+This is defined as:
+.Bd -literal
+typedef struct login_time
+{
+ u_short lt_start; /* Start time */
+ u_short lt_end; /* End time */
+ u_char lt_dow; /* Days of week */
+} login_time_t;
+.Ed
+.Pp
+The
+.Ar lt_start
+and
+.Ar lt_end
+fields contain the number of minutes past midnight at which the
+described period begins and ends.
+The
+.Ar lt_dow
+field is a bit field, containing one bit for each day of the week
+and one bit unused.
+A series
+.Em LTM_*
+macros may be used for testing bits individually and in combination.
+If no bits are set in this field - ie. it contains the value
+.Em LTM_NONE
+- then the entire period is assumed invalid.
+This is used as a convention to mark the termination of an array
+of login_time_t values.
+If
+.Fn parse_lt
+returns a
+.Ar login_time_t
+with
+.Ar lt_dow
+equal to
+.Em LTM_NONE
+then a parsing error was encountered.
+.Pp
+The remaining functions provide the ability to test a given time_t or
+struct tm value against a specific time period or array of time
+periods.
+.Fn in_ltm
+determines whether the given time described by the struct tm
+passed as the second parameter falls within the period described
+by the first parameter.
+A boolean value is returned, indicating whether or not the time
+specified falls within the period.
+If the time does fall within the time period, and the third
+parameter to the function is not NULL, the time at which the
+period ends relative to the time passed is returned.
+.Pp
+The
+.Fn in_ltms
+function is similar to
+.Fn in_ltm
+except that the first parameter must be a pointer to an array
+of login_time_t objects, which is up to LC_MAXTIMES (64)
+elements in length, and terminated by an element with its
+.Ar lt_dow
+field set to
+.Em LTM_NONE.
+.Sh RETURN VALUES
+.Fn parse_lt
+returns a filled in structure of type login_time_t containing the
+parsed time period.
+If a parsing error occurs, the lt_dow field is set to
+.Em LTM_NONE
+(i.e. 0).
+.Pp
+.Fn in_ltm
+returns non-zero if the given time falls within the period described
+by the login_time_t passed as the first parameter.
+.Pp
+.Fn in_ltms
+returns the index of the first time period found in which the given
+time falls, or -1 if none of them apply.
+.Sh SEE ALSO
+.Xr getcap 3 ,
+.Xr login_cap 3 ,
+.Xr login_class 3 ,
+.Xr login.conf 5 ,
+.Xr termcap 5
diff --git a/lib/libutil/login_times.c b/lib/libutil/login_times.c
new file mode 100644
index 0000000..af58974
--- /dev/null
+++ b/lib/libutil/login_times.c
@@ -0,0 +1,161 @@
+/*-
+ * Copyright (c) 1996 by
+ * David Nugent <davidn@blaze.net.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. This work was done expressly for inclusion into FreeBSD. Other use
+ * is permitted provided this notation is included.
+ * 4. Absolutely no warranty of function or purpose is made by the authors.
+ * 5. Modifications may be freely made to this file providing the above
+ * conditions are met.
+ *
+ * Login period parsing and comparison functions.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+
+#include <sys/types.h>
+#include <login_cap.h>
+
+static struct
+{
+ const char *dw;
+ u_char cn;
+ u_char fl;
+} dws[] =
+{
+ { "su", 2, LTM_SUN }, { "mo", 2, LTM_MON }, { "tu", 2, LTM_TUE },
+ { "we", 2, LTM_WED }, { "th", 2, LTM_THU }, { "fr", 2, LTM_FRI },
+ { "sa", 2, LTM_SAT }, { "any",3, LTM_ANY }, { "all",3, LTM_ANY },
+ { "wk", 2, LTM_WK }, { "wd", 2, LTM_WD }, { NULL, 0, 0 }
+};
+
+static char *
+parse_time(char * ptr, u_short * t)
+{
+ u_short val;
+
+ for (val = 0; *ptr && isdigit(*ptr); ptr++)
+ val = (u_short)(val * 10 + (*ptr - '0'));
+
+ *t = (u_short)((val / 100) * 60 + (val % 100));
+
+ return ptr;
+}
+
+
+login_time_t
+parse_lt(const char * str)
+{
+ login_time_t t;
+
+ memset(&t, 0, sizeof t);
+ t.lt_dow = LTM_NONE;
+ if (str && *str && strcmp(str, "Never") != 0 && strcmp(str, "None") != 0) {
+ int i;
+ login_time_t m = t;
+ char *p;
+ char buf[64];
+
+ /* Make local copy and force lowercase to simplify parsing */
+ p = strncpy(buf, str, sizeof buf);
+ buf[sizeof buf - 1] = '\0';
+ for (i = 0; buf[i]; i++)
+ buf[i] = (char)tolower(buf[i]);
+
+ while (isalpha(*p)) {
+
+ i = 0;
+ while (dws[i].dw && strncmp(p, dws[i].dw, dws[i].cn) != 0)
+ i++;
+ if (dws[i].dw == NULL)
+ break;
+ m.lt_dow |= dws[i].fl;
+ p += dws[i].cn;
+ }
+
+ if (m.lt_dow == LTM_NONE) /* No (valid) prefix, assume any */
+ m.lt_dow |= LTM_ANY;
+
+ if (isdigit(*p))
+ p = parse_time(p, &m.lt_start);
+ else
+ m.lt_start = 0;
+ if (*p == '-')
+ p = parse_time(++p, &m.lt_end);
+ else
+ m.lt_end = 1440;
+
+ t = m;
+ }
+ return t;
+}
+
+
+int
+in_ltm(const login_time_t * ltm, struct tm * tt, time_t * ends)
+{
+ int rc = 0;
+
+ if (tt != NULL) {
+ /* First, examine the day of the week */
+ if ((u_char)(0x01 << tt->tm_wday) & ltm->lt_dow) {
+ /* Convert `current' time to minute of the day */
+ u_short now = (u_short)((tt->tm_hour * 60) + tt->tm_min);
+
+ if (tt->tm_sec > 30)
+ ++now;
+ if (now >= ltm->lt_start && now < ltm->lt_end) {
+ rc = 2;
+ if (ends != NULL) {
+ /* If requested, return ending time for this period */
+ tt->tm_hour = (int)(ltm->lt_end / 60);
+ tt->tm_min = (int)(ltm->lt_end % 60);
+ *ends = mktime(tt);
+ }
+ }
+ }
+ }
+ return rc;
+}
+
+
+int
+in_lt(const login_time_t * ltm, time_t * t)
+{
+ return in_ltm(ltm, localtime(t), t);
+}
+
+int
+in_ltms(const login_time_t * ltm, struct tm * tm, time_t * t)
+{
+ int i = 0;
+
+ while (i < LC_MAXTIMES && ltm[i].lt_dow != LTM_NONE) {
+ if (in_ltm(ltm + i, tm, t))
+ return i;
+ i++;
+ }
+ return -1;
+}
+
+int
+in_lts(const login_time_t * ltm, time_t * t)
+{
+ return in_ltms(ltm, localtime(t), t);
+}
+
diff --git a/lib/libutil/login_tty.3 b/lib/libutil/login_tty.3
new file mode 100644
index 0000000..2cde93f
--- /dev/null
+++ b/lib/libutil/login_tty.3
@@ -0,0 +1,66 @@
+.\"
+.\" Copyright (c) 1996 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" "
+.Dd December 29, 1996
+.Os
+.Dt LOGIN_TTY 3
+.Sh NAME
+.Nm login_tty
+.Nd prepare a tty for a new login session
+.Sh SYNOPSIS
+.Fd #include <libutil.h>
+.Ft int
+.Fn login_tty "int fd"
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+The function
+.Fn login_tty
+prepares a terminal for a new login session. The file descriptor
+.Ar fd
+passed to
+.Fn login_tty
+must be opened for reading and writing on a terminal device. It will be
+made the controlling terminal for the calling process, after allocating
+a new session with
+.Xr setsid 2 .
+This terminal device will also be made the standard input, standard output,
+and standard error output of the calling process.
+.Sh RETURN VALUES
+.Fn Login_tty
+returns -1 if it could not make the device referenced by
+.Ar fd
+the controlling terminal of the calling process, and 0 otherwise.
+.Sh SEE ALSO
+.Xr dup2 2 ,
+.Xr ioctl 2 ,
+.Xr setsid 2 ,
+.Xr tty 4
diff --git a/lib/libutil/login_tty.c b/lib/libutil/login_tty.c
new file mode 100644
index 0000000..eb32fc7
--- /dev/null
+++ b/lib/libutil/login_tty.c
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)login_tty.c 8.1 (Berkeley) 6/4/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <libutil.h>
+
+int
+login_tty(fd)
+ int fd;
+{
+ (void) setsid();
+ if (ioctl(fd, TIOCSCTTY, (char *)NULL) == -1)
+ return (-1);
+ (void) dup2(fd, 0);
+ (void) dup2(fd, 1);
+ (void) dup2(fd, 2);
+ if (fd > 2)
+ (void) close(fd);
+ return (0);
+}
diff --git a/lib/libutil/logout.3 b/lib/libutil/logout.3
new file mode 100644
index 0000000..580550f
--- /dev/null
+++ b/lib/libutil/logout.3
@@ -0,0 +1,71 @@
+.\"
+.\" Copyright (c) 1996 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" "
+.Dd December 29, 1996
+.Os
+.Dt LOGOUT 3
+.Sh NAME
+.Nm logout
+.Nd remove an entry from the utmp file
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <libutil.h>
+.Ft int
+.Fn logout "char *line"
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+The function
+.Fn logout
+searches the
+.Xr utmp 5
+file for the slot described by
+.Ar line
+(usually a tty name). If such a slot could be found, it will be updated
+with a record where the
+.Em name
+and
+.Em host
+fields are empty, and the time stamp field is updated to the current time.
+.Sh RETURN VALUES
+.Fn Logout
+returns 1 if the slot described by
+.Ar line
+has been found and updated, 0 otherwise.
+.Sh SEE ALSO
+.Xr login 3 ,
+.Xr utmp 5 ,
+.Xr wtmp 5
+.Sh BUGS
+The calling interface of
+.Fn logout
+is inconsistent with that of
+.Xr login 3 .
diff --git a/lib/libutil/logout.c b/lib/libutil/logout.c
new file mode 100644
index 0000000..5b9a821
--- /dev/null
+++ b/lib/libutil/logout.c
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)logout.c 8.1 (Berkeley) 6/4/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <fcntl.h>
+#include <utmp.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libutil.h>
+
+typedef struct utmp UTMP;
+
+int
+logout(line)
+ register char *line;
+{
+ register int fd;
+ UTMP ut;
+ int rval;
+
+ if ((fd = open(_PATH_UTMP, O_RDWR, 0)) < 0)
+ return(0);
+ rval = 0;
+ while (read(fd, &ut, sizeof(UTMP)) == sizeof(UTMP)) {
+ if (!ut.ut_name[0] || strncmp(ut.ut_line, line, UT_LINESIZE))
+ continue;
+ bzero(ut.ut_name, UT_NAMESIZE);
+ bzero(ut.ut_host, UT_HOSTSIZE);
+ (void)time(&ut.ut_time);
+ (void)lseek(fd, -(off_t)sizeof(UTMP), L_INCR);
+ (void)write(fd, &ut, sizeof(UTMP));
+ rval = 1;
+ }
+ (void)close(fd);
+ return(rval);
+}
diff --git a/lib/libutil/logwtmp.3 b/lib/libutil/logwtmp.3
new file mode 100644
index 0000000..b7d3d0a
--- /dev/null
+++ b/lib/libutil/logwtmp.3
@@ -0,0 +1,73 @@
+.\"
+.\" Copyright (c) 1996 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" "
+.Dd December 29, 1996
+.Os
+.Dt LOGWTMP 3
+.Sh NAME
+.Nm logwtmp
+.Nd append a new record to the wtmp file
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <libutil.h>
+.Ft void
+.Fn logwtmp "const char *line" "const char *name" "const char *host"
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+The function
+.Fn logwtmp
+tries to append a new record to the
+.Xr wtmp 5
+file, using the provided arguments
+.Ar line ,
+.Ar name ,
+and
+.Ar host ,
+and the current time.
+.Pp
+If the length of the hostname string
+.Ar host
+is longer than what would fit into the hostname field of the
+.Xr wtmp 5
+file, it will first be attempted to convert it into a numerical IP
+address using
+.Xr gethostbyname 3 .
+Failing this, the hostname will be recorded as
+.Qq invalid hostname .
+.Pp
+The calling process must have permission to write to both files.
+.Sh RETURN VALUES
+None.
+.Sh SEE ALSO
+.Xr gethostbyname 3 ,
+.Xr login 3 ,
+.Xr wtmp 5
diff --git a/lib/libutil/logwtmp.c b/lib/libutil/logwtmp.c
new file mode 100644
index 0000000..fd05b55
--- /dev/null
+++ b/lib/libutil/logwtmp.c
@@ -0,0 +1,149 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)logwtmp.c 8.1 (Berkeley) 6/4/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <libutil.h>
+#include <netdb.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <utmp.h>
+
+void
+trimdomain(char *fullhost, int hostsize)
+{
+ static char domain[MAXHOSTNAMELEN];
+ static int first = 1;
+ static size_t dlen;
+ char *s, *end;
+ int spn, ok;
+
+ if (first) {
+ first = 0;
+ if (gethostname(domain, sizeof(domain) - 1) == 0 &&
+ (s = strchr(domain, '.')))
+ memmove(domain, s + 1, strlen(s + 1) + 1);
+ else
+ domain[0] = '\0';
+ dlen = strlen(domain);
+ }
+
+ if (domain[0] != '\0') {
+ s = fullhost;
+ end = s + hostsize + 1;
+ for (; (s = memchr(s, '.', end - s)) != NULL; s++)
+ if (!strncasecmp(s + 1, domain, dlen)) {
+ if (s[dlen + 1] == '\0') {
+ *s = '\0'; /* Found - lose the domain */
+ break;
+ } else if (s[dlen + 1] == ':') { /* $DISPLAY ? */
+ ok = dlen + 2;
+ spn = strspn(s + ok, "0123456789");
+ if (spn > 0 && ok + spn - dlen <= end - s) {
+ ok += spn;
+ if (s[ok] == '\0') {
+ /* host.domain:nn */
+ memmove(s, s + dlen + 1, ok - dlen);
+ break;
+ } else if (s[ok] == '.') {
+ ok++;
+ spn = strspn(s + ok, "0123456789");
+ if (spn > 0 && s[ok + spn] == '\0' &&
+ ok + spn - dlen <= end - s) {
+ /* host.domain:nn.nn */
+ memmove(s, s + dlen + 1, ok + spn - dlen);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+logwtmp(line, name, host)
+ const char *line;
+ const char *name;
+ const char *host;
+{
+ struct utmp ut;
+ struct stat buf;
+ char fullhost[MAXHOSTNAMELEN];
+ int fd;
+
+ strncpy(fullhost, host, sizeof(fullhost) - 1);
+ fullhost[sizeof(fullhost) - 1] = '\0';
+ trimdomain(fullhost, UT_HOSTSIZE);
+ host = fullhost;
+
+ if (strlen(host) > UT_HOSTSIZE) {
+ struct hostent *hp = gethostbyname(host);
+
+ if (hp != NULL) {
+ struct in_addr in;
+
+ memmove(&in, hp->h_addr, sizeof(in));
+ host = inet_ntoa(in);
+ } else
+ host = "invalid hostname";
+ }
+
+ if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0)
+ return;
+ if (fstat(fd, &buf) == 0) {
+ (void) strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+ (void) strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+ (void) strncpy(ut.ut_host, host, sizeof(ut.ut_host));
+ (void) time(&ut.ut_time);
+ if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
+ sizeof(struct utmp))
+ (void) ftruncate(fd, buf.st_size);
+ }
+ (void) close(fd);
+}
diff --git a/lib/libutil/property.3 b/lib/libutil/property.3
new file mode 100644
index 0000000..0a0457d
--- /dev/null
+++ b/lib/libutil/property.3
@@ -0,0 +1,97 @@
+.\"
+.\" Copyright (c) 1998 Jordan Hubbard
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" "
+.Dd October 7, 1998
+.Os
+.Dt PROPERTIES 3
+.Sh NAME
+.Nm properties_read ,
+.Nm propery_find ,
+.Nm properties_free
+.Nd functions to allow creating simple property lists from ASCII file data.
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <libutil.h>
+.Ft properties
+.Fn properties_read "int fd"
+.Ft char *
+.Fn property_find "properties list" "const char *name"
+.Ft void
+.Fn properties_free "properties list"
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+.nf
+typedef struct _properties {
+ struct _properties *next;
+ char *name;
+ char *value;
+} *properties;
+.fi
+
+The function
+.Fn properties_read
+reads
+.Fa name = value
+pairs from the file descriptor passed in
+.Fa fd
+and returns the head of a new property list, assuming that the
+file's contents have been parsed properly, or NULL in case
+of error.
+.Pp
+.Fn property_find
+Returns the associated value string for the property named
+.Fa name
+if found, otherwise NULL.
+.Pp
+.Fn properties_free
+is used to free the structure returned by
+.Fn properties_read
+when it is no longer needed.
+.Pp
+.Sh FILE FORMAT
+Each property in the file is assumed to have the format of
+.Fa name = value
+where
+.Fa name
+is an alphanumeric string (and any punctuation not including the `=' character)
+and
+.Fa value
+is an arbitary string of text terminated by a newline character. If newlines
+are desired, the entire value should be enclosed in { } (curly-bracket)
+characters. Any line beginning with a # or ; character is assumed to
+be a comment and will be ignored.
+.Sh SEE ALSO
+.Xr auth_getval 3
+.Sh BUGS
+Simplistic.
+.Sh AUTHORS
+.An Jordan Hubbard
diff --git a/lib/libutil/property.c b/lib/libutil/property.c
new file mode 100644
index 0000000..23714a0
--- /dev/null
+++ b/lib/libutil/property.c
@@ -0,0 +1,224 @@
+/*
+ *
+ * Simple property list handling code.
+ *
+ * Copyright (c) 1998
+ * Jordan Hubbard. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * verbatim and that no modifications are made prior to this
+ * point in the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR HIS PETS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <ctype.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <err.h>
+#include <sys/types.h>
+#include <libutil.h>
+
+#define MAX_NAME 64
+#define MAX_VALUE 512
+
+static properties
+property_alloc(char *name, char *value)
+{
+ properties n;
+
+ n = (properties)malloc(sizeof(struct _property));
+ n->next = NULL;
+ n->name = name ? strdup(name) : NULL;
+ n->value = value ? strdup(value) : NULL;
+ return n;
+}
+
+properties
+properties_read(int fd)
+{
+ properties head, ptr;
+ char hold_n[MAX_NAME + 1];
+ char hold_v[MAX_VALUE + 1];
+ char buf[BUFSIZ * 4];
+ int bp, n, v, max;
+ enum { LOOK, COMMENT, NAME, VALUE, MVALUE, COMMIT, FILL, STOP } state;
+ int ch = 0, blevel = 0;
+
+ n = v = bp = max = 0;
+ head = ptr = NULL;
+ state = LOOK;
+ while (state != STOP) {
+ if (state != COMMIT) {
+ if (bp == max)
+ state = FILL;
+ else
+ ch = buf[bp++];
+ }
+ switch(state) {
+ case FILL:
+ if ((max = read(fd, buf, sizeof buf)) <= 0) {
+ state = STOP;
+ break;
+ }
+ else {
+ state = LOOK;
+ ch = buf[0];
+ bp = 1;
+ }
+ /* Fall through deliberately since we already have a character and state == LOOK */
+
+ case LOOK:
+ if (isspace(ch))
+ continue;
+ /* Allow shell or lisp style comments */
+ else if (ch == '#' || ch == ';') {
+ state = COMMENT;
+ continue;
+ }
+ else if (isalnum(ch) || ch == '_') {
+ if (n >= MAX_NAME) {
+ n = 0;
+ state = COMMENT;
+ }
+ else {
+ hold_n[n++] = ch;
+ state = NAME;
+ }
+ }
+ else
+ state = COMMENT; /* Ignore the rest of the line */
+ break;
+
+ case COMMENT:
+ if (ch == '\n')
+ state = LOOK;
+ break;
+
+ case NAME:
+ if (ch == '\n' || !ch) {
+ hold_n[n] = '\0';
+ hold_v[0] = '\0';
+ v = n = 0;
+ state = COMMIT;
+ }
+ else if (isspace(ch))
+ continue;
+ else if (ch == '=') {
+ hold_n[n] = '\0';
+ v = n = 0;
+ state = VALUE;
+ }
+ else
+ hold_n[n++] = ch;
+ break;
+
+ case VALUE:
+ if (v == 0 && isspace(ch))
+ continue;
+ else if (ch == '{') {
+ state = MVALUE;
+ ++blevel;
+ }
+ else if (ch == '\n' || !ch) {
+ hold_v[v] = '\0';
+ v = n = 0;
+ state = COMMIT;
+ }
+ else {
+ if (v >= MAX_VALUE) {
+ state = COMMENT;
+ v = n = 0;
+ break;
+ }
+ else
+ hold_v[v++] = ch;
+ }
+ break;
+
+ case MVALUE:
+ /* multiline value */
+ if (v >= MAX_VALUE) {
+ warn("properties_read: value exceeds max length");
+ state = COMMENT;
+ n = v = 0;
+ }
+ else if (ch == '}' && !--blevel) {
+ hold_v[v] = '\0';
+ v = n = 0;
+ state = COMMIT;
+ }
+ else {
+ hold_v[v++] = ch;
+ if (ch == '{')
+ ++blevel;
+ }
+ break;
+
+ case COMMIT:
+ if (!head)
+ head = ptr = property_alloc(hold_n, hold_v);
+ else {
+ ptr->next = property_alloc(hold_n, hold_v);
+ ptr = ptr->next;
+ }
+ state = LOOK;
+ v = n = 0;
+ break;
+
+ case STOP:
+ /* we don't handle this here, but this prevents warnings */
+ break;
+ }
+ }
+ return head;
+}
+
+char *
+property_find(properties list, const char *name)
+{
+ if (!list || !name || !name[0])
+ return NULL;
+ while (list) {
+ if (!strcmp(list->name, name))
+ return list->value;
+ list = list->next;
+ }
+ return NULL;
+}
+
+void
+properties_free(properties list)
+{
+ properties tmp;
+
+ while (list) {
+ tmp = list->next;
+ if (list->name)
+ free(list->name);
+ if (list->value)
+ free(list->value);
+ free(list);
+ list = tmp;
+ }
+}
diff --git a/lib/libutil/pty.3 b/lib/libutil/pty.3
new file mode 100644
index 0000000..e209fde
--- /dev/null
+++ b/lib/libutil/pty.3
@@ -0,0 +1,144 @@
+.\"
+.\" Copyright (c) 1996 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" "
+.Dd December 29, 1996
+.Os
+.Dt PTY 3
+.Sh NAME
+.Nm openpty ,
+.Nm forkpty
+.Nd auxiliary functions to obtain a pseudo-terminal
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/ioctl.h>
+.Fd #include <termios.h>
+.Fd #include <libutil.h>
+.Ft int
+.Fn openpty "int *amaster" "int *aslave" "char *name" "struct termios *termp" "struct winsize *winp"
+.Ft int
+.Fn forkpty "int *amaster" "char *name" "struct termios *termp" "struct winsize *winp"
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+The function
+.Fn openpty
+attempts to obtain the next available pseudo-terminal from the system (see
+.Xr pty 4 ) .
+If it successfully finds one, it subsequently tries to change the
+ownership of the slave device to the real UID of the current process,
+the group membership to the group
+.Dq tty
+(if such a group exists in the system), the access permissions for
+reading and writing by the owner, and for writing by the group, and to
+invalidate any current use of the line by calling
+.Xr revoke 2 .
+.Pp
+If the argument
+.Fa name
+is not
+.Dv NULL ,
+.Fn openpty
+copies the pathname of the slave pty to this area. The caller is
+responsible for allocating the required space in this array.
+.Pp
+If the arguments
+.Fa termp
+or
+.Fa winp
+are not
+.Dv NULL ,
+.Fn openpty
+initializes the termios and window size settings from the structures
+these arguments point to, respectively.
+.Pp
+Upon return, the open file descriptors for the master and slave side
+of the pty are returned in the locations pointed to by
+.Fa amaster
+and
+.Fa aslave ,
+respectively.
+.Pp
+.Fn Forkpty
+first calls
+.Fn openpty
+to obtain the next available pseudo-terminal from the system. Upon success,
+it forks off a new process. In the child process, it closes the descriptor
+for the master side of the pty, and calls
+.Xr login_tty 3
+for the slave pty. In the parent process, it closes the descriptor for the
+slave side of the pty. The arguments
+.Fa amaster ,
+.Fa name ,
+.Fa termp ,
+and
+.Fa winp
+have the same meaning as described for
+.Fn openpty .
+.Sh RETURN VALUES
+.Fn Openpty
+returns 0 on success, or -1 on failure.
+.Pp
+.Fn Forkpty
+returns -1 on failure, 0 in the slave process, and the process ID of the
+slave process in the parent process.
+.Sh ERRORS
+On failure,
+.Fn openpty
+will set the global variable
+.Dv errno
+to
+.Er ENOENT .
+.Pp
+In addition to this,
+.Fn forkpty
+may set it to any value as described for
+.Xr fork 2 .
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr chown 2 ,
+.Xr fork 2 ,
+.Xr getuid 2 ,
+.Xr open 2 ,
+.Xr revoke 2 ,
+.Xr login_tty 3 ,
+.Xr pty 4 ,
+.Xr termios 4 ,
+.Xr group 5
+.Sh BUGS
+The calling process must have an effective UID of super-user in order
+to perform all the intended actions. No notification will occur if
+.Fn openpty
+or
+.Fn forkpty
+failed to proceed with one of the described steps, as long as they could
+at least allocate the pty at all (and create the new process in the case
+of
+.Fn forkpty ) .
diff --git a/lib/libutil/pty.c b/lib/libutil/pty.c
new file mode 100644
index 0000000..0b5e4ab
--- /dev/null
+++ b/lib/libutil/pty.c
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)pty.c 8.3 (Berkeley) 5/16/94";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <libutil.h>
+
+int
+openpty(amaster, aslave, name, termp, winp)
+ int *amaster, *aslave;
+ char *name;
+ struct termios *termp;
+ struct winsize *winp;
+{
+ char line[] = "/dev/ptyXX";
+ register const char *cp1, *cp2;
+ register int master, slave, ttygid;
+ struct group *gr;
+
+ if ((gr = getgrnam("tty")) != NULL)
+ ttygid = gr->gr_gid;
+ else
+ ttygid = -1;
+
+ for (cp1 = "pqrsPQRS"; *cp1; cp1++) {
+ line[8] = *cp1;
+ for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) {
+ line[5] = 'p';
+ line[9] = *cp2;
+ if ((master = open(line, O_RDWR, 0)) == -1) {
+ if (errno == ENOENT)
+ return (-1); /* out of ptys */
+ } else {
+ line[5] = 't';
+ (void) chown(line, getuid(), ttygid);
+ (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
+ (void) revoke(line);
+ if ((slave = open(line, O_RDWR, 0)) != -1) {
+ *amaster = master;
+ *aslave = slave;
+ if (name)
+ strcpy(name, line);
+ if (termp)
+ (void) tcsetattr(slave,
+ TCSAFLUSH, termp);
+ if (winp)
+ (void) ioctl(slave, TIOCSWINSZ,
+ (char *)winp);
+ return (0);
+ }
+ (void) close(master);
+ }
+ }
+ }
+ errno = ENOENT; /* out of ptys */
+ return (-1);
+}
+
+int
+forkpty(amaster, name, termp, winp)
+ int *amaster;
+ char *name;
+ struct termios *termp;
+ struct winsize *winp;
+{
+ int master, slave, pid;
+
+ if (openpty(&master, &slave, name, termp, winp) == -1)
+ return (-1);
+ switch (pid = fork()) {
+ case -1:
+ return (-1);
+ case 0:
+ /*
+ * child
+ */
+ (void) close(master);
+ login_tty(slave);
+ return (0);
+ }
+ /*
+ * parent
+ */
+ *amaster = master;
+ (void) close(slave);
+ return (pid);
+}
diff --git a/lib/libutil/pw_util.c b/lib/libutil/pw_util.c
new file mode 100644
index 0000000..207da8f
--- /dev/null
+++ b/lib/libutil/pw_util.c
@@ -0,0 +1,262 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static const char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* not lint */
+
+/*
+ * This file is used by all the "password" programs; vipw(8), chpass(1),
+ * and passwd(1).
+ */
+
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pw_util.h"
+
+extern char *tempname;
+static pid_t editpid = -1;
+static int lockfd;
+char *mppath = _PATH_PWD;
+char *masterpasswd = _PATH_MASTERPASSWD;
+
+void
+pw_cont(sig)
+ int sig;
+{
+
+ if (editpid != -1)
+ kill(editpid, sig);
+}
+
+void
+pw_init()
+{
+ struct rlimit rlim;
+
+ /* Unlimited resource limits. */
+ rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
+ (void)setrlimit(RLIMIT_CPU, &rlim);
+ (void)setrlimit(RLIMIT_FSIZE, &rlim);
+ (void)setrlimit(RLIMIT_STACK, &rlim);
+ (void)setrlimit(RLIMIT_DATA, &rlim);
+ (void)setrlimit(RLIMIT_RSS, &rlim);
+
+ /* Don't drop core (not really necessary, but GP's). */
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ (void)setrlimit(RLIMIT_CORE, &rlim);
+
+ /* Turn off signals. */
+ (void)signal(SIGALRM, SIG_IGN);
+ (void)signal(SIGHUP, SIG_IGN);
+ (void)signal(SIGINT, SIG_IGN);
+ (void)signal(SIGPIPE, SIG_IGN);
+ (void)signal(SIGQUIT, SIG_IGN);
+ (void)signal(SIGTERM, SIG_IGN);
+ (void)signal(SIGCONT, pw_cont);
+
+ /* Create with exact permissions. */
+ (void)umask(0);
+}
+
+int
+pw_lock()
+{
+ /*
+ * If the master password file doesn't exist, the system is hosed.
+ * Might as well try to build one. Set the close-on-exec bit so
+ * that users can't get at the encrypted passwords while editing.
+ * Open should allow flock'ing the file; see 4.4BSD. XXX
+ */
+ for (;;) {
+ struct stat st;
+
+ lockfd = open(masterpasswd, O_RDONLY, 0);
+ if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1)
+ err(1, "%s", masterpasswd);
+ if (flock(lockfd, LOCK_EX|LOCK_NB))
+ errx(1, "the password db file is busy");
+
+ /*
+ * If the password file was replaced while we were trying to
+ * get the lock, our hardlink count will be 0 and we have to
+ * close and retry.
+ */
+ if (fstat(lockfd, &st) < 0)
+ errx(1, "fstat() failed");
+ if (st.st_nlink != 0)
+ break;
+ close(lockfd);
+ lockfd = -1;
+ }
+ return (lockfd);
+}
+
+int
+pw_tmp()
+{
+ static char path[MAXPATHLEN];
+ int fd;
+ char *p;
+
+ strncpy(path, masterpasswd, MAXPATHLEN - 1);
+ path[MAXPATHLEN] = '\0';
+
+ if ((p = strrchr(path, '/')))
+ ++p;
+ else
+ p = path;
+ strcpy(p, "pw.XXXXXX");
+ if ((fd = mkstemp(path)) == -1)
+ err(1, "%s", path);
+ tempname = path;
+ return (fd);
+}
+
+int
+pw_mkdb(username)
+char *username;
+{
+ int pstat;
+ pid_t pid;
+
+ (void)fflush(stderr);
+ if (!(pid = fork())) {
+ if(!username) {
+ warnx("rebuilding the database...");
+ execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath,
+ tempname, NULL);
+ } else {
+ warnx("updating the database...");
+ execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath,
+ "-u", username, tempname, NULL);
+ }
+ pw_error(_PATH_PWD_MKDB, 1, 1);
+ }
+ pid = waitpid(pid, &pstat, 0);
+ if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
+ return (0);
+ warnx("done");
+ return (1);
+}
+
+void
+pw_edit(notsetuid)
+ int notsetuid;
+{
+ int pstat;
+ char *p, *editor;
+
+ if (!(editor = getenv("EDITOR")))
+ editor = _PATH_VI;
+ if ((p = strrchr(editor, '/')))
+ ++p;
+ else
+ p = editor;
+
+ if (!(editpid = fork())) {
+ if (notsetuid) {
+ (void)setgid(getgid());
+ (void)setuid(getuid());
+ }
+ errno = 0;
+ execlp(editor, p, tempname, NULL);
+ _exit(errno);
+ }
+ for (;;) {
+ editpid = waitpid(editpid, (int *)&pstat, WUNTRACED);
+ errno = WEXITSTATUS(pstat);
+ if (editpid == -1)
+ pw_error(editor, 1, 1);
+ else if (WIFSTOPPED(pstat))
+ raise(WSTOPSIG(pstat));
+ else if (WIFEXITED(pstat) && errno == 0)
+ break;
+ else
+ pw_error(editor, 1, 1);
+ }
+ editpid = -1;
+}
+
+void
+pw_prompt()
+{
+ int c, first;
+
+ (void)printf("re-edit the password file? [y]: ");
+ (void)fflush(stdout);
+ first = c = getchar();
+ while (c != '\n' && c != EOF)
+ c = getchar();
+ if (first == 'n')
+ pw_error(NULL, 0, 0);
+}
+
+void
+pw_error(name, err, eval)
+ char *name;
+ int err, eval;
+{
+#ifdef YP
+ extern int _use_yp;
+#endif /* YP */
+ if (err)
+ warn(name);
+#ifdef YP
+ if (_use_yp)
+ warnx("NIS information unchanged");
+ else
+#endif /* YP */
+ warnx("%s: unchanged", masterpasswd);
+ (void)unlink(tempname);
+ exit(eval);
+}
diff --git a/lib/libutil/realhostname.3 b/lib/libutil/realhostname.3
new file mode 100644
index 0000000..1f2e6a9
--- /dev/null
+++ b/lib/libutil/realhostname.3
@@ -0,0 +1,106 @@
+.\" Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 6, 1999
+.Os
+.Dt REALHOSTNAME 3
+.Sh NAME
+.Nm realhostname
+.Nd "convert an IP number to the real host name"
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <netinet/in.h>
+.Fd #include <libutil.h>
+.Ft int
+.Fn realhostname "char *host" "size_t hsize" "const struct in_addr *ip"
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+The function
+.Fn realhostname
+converts
+.Ar ip
+to the corresponding host name. This is done by resolving
+.Ar ip
+to a host name and then ensuring that the host name resolves
+back to
+.Ar ip .
+.Pp
+.Ar host
+must point to a buffer of at least
+.Ar hsize
+bytes, and will always be written to by this function.
+.Pp
+If the name resolution doesn't work both ways or if the host name is longer
+than
+.Ar hsize
+bytes,
+.Xr inet_ntoa 3
+is used to convert
+.Ar ip
+to an ASCII form.
+.Pp
+If the string written to
+.Ar host
+is
+.Ar hsize
+bytes long,
+.Ar host
+will not be NUL terminated.
+.Sh RETURN VALUES
+.Fn realhostname
+will return one of the following constants which are defined in
+.Pa libutil.h :
+.Pp
+.Bl -tag -width XXX -offset XXX
+.It Li HOSTNAME_FOUND
+A valid host name was found.
+.It Li HOSTNAME_INCORRECTNAME
+A host name was found, but it did not resolve back to the passed
+.Ar ip .
+.Ar host
+now contains the numeric value of
+.Ar ip .
+.It Li HOSTNAME_INVALIDADDR
+.Ar ip
+could not be resolved.
+.Ar host
+now contains the numeric value of
+.Ar ip .
+.It Li HOSTNAME_INVALIDNAME
+A host name was found, but it could not be resolved back to any ip number.
+.Ar host
+now contains the numeric value of
+.Ar ip .
+.El
+.Sh SEE ALSO
+.Xr gethostbyaddr 3 ,
+.Xr gethostbyname 3 ,
+.Xr inet_ntoa 3
diff --git a/lib/libutil/realhostname.c b/lib/libutil/realhostname.c
new file mode 100644
index 0000000..fa7f4b1
--- /dev/null
+++ b/lib/libutil/realhostname.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "libutil.h"
+
+int
+realhostname(char *host, size_t hsize, const struct in_addr *ip)
+{
+ int result;
+ struct hostent *hp;
+
+ result = HOSTNAME_INVALIDADDR;
+ hp = gethostbyaddr((char *)ip, sizeof(*ip), AF_INET);
+
+ if (hp != NULL && strlen(hp->h_name) <= hsize) {
+ char lookup[MAXHOSTNAMELEN];
+
+ strncpy(lookup, hp->h_name, sizeof(lookup) - 1);
+ lookup[sizeof(lookup) - 1] = '\0';
+ hp = gethostbyname(lookup);
+ if (hp == NULL)
+ result = HOSTNAME_INVALIDNAME;
+ else for (; ; hp->h_addr_list++) {
+ if (hp->h_addr_list[0] == NULL) {
+ result = HOSTNAME_INCORRECTNAME;
+ break;
+ }
+ if (!memcmp(*hp->h_addr_list, ip, sizeof(*ip))) {
+ strncpy(host, lookup, hsize);
+ return HOSTNAME_FOUND;
+ }
+ }
+ }
+
+ strncpy(host, inet_ntoa(*ip), hsize);
+
+ return result;
+}
diff --git a/lib/libutil/setproctitle.3 b/lib/libutil/setproctitle.3
new file mode 100644
index 0000000..10eae65
--- /dev/null
+++ b/lib/libutil/setproctitle.3
@@ -0,0 +1,101 @@
+.\" Copyright (c) 1995 Peter Wemm <peter@freebsd.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, is permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice immediately at the beginning of the file, without modification,
+.\" this list of conditions, and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. This work was done expressly for inclusion into FreeBSD. Other use
+.\" is permitted provided this notation is included.
+.\" 4. Absolutely no warranty of function or purpose is made by the author
+.\" Peter Wemm.
+.\" 5. Modifications may be freely made to this file providing the above
+.\" conditions are met.
+.\"
+.\" $FreeBSD$
+.\"
+.\" The following requests are required for all man pages.
+.Dd December 16, 1995
+.Os FreeBSD
+.Dt SETPROCTITLE 3
+.Sh NAME
+.Nm setproctitle
+.Nd set the process title for
+.Xr ps 1
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <libutil.h>
+.Ft void
+.Fn setproctitle "const char *fmt" "..."
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+The
+.Fn setproctitle
+library routine sets the process title that appears on the
+.Xr ps 1
+command.
+.Pp
+The title is set from the executable's name, followed by the
+result of a
+.Xr printf 3
+style expansion of the arguments as specified by the
+.Va fmt
+argument.
+.Pp
+If
+.Va fmt
+is NULL, the process title is restored.
+.Sh EXAMPLES
+To set the title on a daemon to indicate its activity:
+.Bd -literal -offset indent
+setproctitle("talking to %s", inet_ntoa(addr));
+.Ed
+.Sh SEE ALSO
+.Xr ps 1 ,
+.Xr w 1 ,
+.Xr kvm 3 ,
+.Xr kvm_getargv 3 ,
+.Xr printf 3
+.Sh STANDARDS
+.Fn setproctitle
+is implicitly non-standard. Other methods of causing the
+.Xr ps 1
+command line to change, including copying over the argv[0] string are
+also implicitly non-portable. It is preferable to use an operating system
+supplied
+.Fn setproctitle
+if present.
+.Pp
+Unfortunately, it is possible that there are other calling conventions
+to other versions of
+.Fn setproctitle ,
+although none have been found by the author as yet. This is believed to be
+the predominant convention.
+.Pp
+It is thought that the implementation is compatible with other systems,
+including
+.Nx
+and
+.Tn BSD/OS .
+.Sh HISTORY
+.Fn setproctitle
+first appeared in
+.Fx 2.2 .
+Other operating systems have
+similar functions.
+.Sh AUTHORS
+.An Peter Wemm Aq peter@FreeBSD.org
+stole the idea from the
+.Sy "Sendmail 8.7.3"
+source code by
+.An Eric Allman Aq eric@sendmail.org .
diff --git a/lib/libutil/setproctitle.c b/lib/libutil/setproctitle.c
new file mode 100644
index 0000000..37b9fab
--- /dev/null
+++ b/lib/libutil/setproctitle.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1995 Peter Wemm <peter@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Absolutely no warranty of function or purpose is made by the author
+ * Peter Wemm.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/sysctl.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * Older FreeBSD 2.0, 2.1 and 2.2 had different ps_strings structures and
+ * in different locations.
+ * 1: old_ps_strings at the very top of the stack.
+ * 2: old_ps_strings at SPARE_USRSPACE below the top of the stack.
+ * 3: ps_strings at the very top of the stack.
+ * This attempts to support a kernel built in the #2 and #3 era.
+ */
+
+struct old_ps_strings {
+ char *old_ps_argvstr;
+ int old_ps_nargvstr;
+ char *old_ps_envstr;
+ int old_ps_nenvstr;
+};
+#define OLD_PS_STRINGS ((struct old_ps_strings *) \
+ (USRSTACK - SPARE_USRSPACE - sizeof(struct old_ps_strings)))
+
+#if defined(__STDC__) /* from other parts of sendmail */
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+
+#define SPT_BUFSIZE 2048 /* from other parts of sendmail */
+extern char * __progname; /* is this defined in a .h anywhere? */
+
+void
+#if defined(__STDC__)
+setproctitle(const char *fmt, ...)
+#else
+setproctitle(fmt, va_alist)
+ const char *fmt;
+ va_dcl
+#endif
+{
+ static struct ps_strings *ps_strings;
+ static char buf[SPT_BUFSIZE];
+ static char obuf[SPT_BUFSIZE];
+ static char **oargv, *kbuf;
+ static int oargc = -1;
+ static char *nargv[2] = { buf, NULL };
+ char **nargvp;
+ int nargc;
+ va_list ap;
+ size_t len;
+ unsigned long ul_ps_strings;
+ int oid[4];
+
+#if defined(__STDC__)
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+
+ if (fmt) {
+ buf[sizeof(buf) - 1] = '\0';
+
+ /* print program name heading for grep */
+ (void) snprintf(buf, sizeof(buf), "%s: ", __progname);
+
+ /*
+ * can't use return from sprintf, as that is the count of how
+ * much it wanted to write, not how much it actually did.
+ */
+
+ len = strlen(buf);
+
+ /* print the argument string */
+ (void) vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
+
+ nargvp = nargv;
+ nargc = 1;
+ kbuf = buf;
+ } else if (*obuf != '\0') {
+ /* Idea from NetBSD - reset the title on fmt == NULL */
+ nargvp = oargv;
+ nargc = oargc;
+ kbuf = obuf;
+ } else
+ /* Nothing to restore */
+ return;
+
+ va_end(ap);
+
+ /* Set the title into the kernel cached command line */
+ oid[0] = CTL_KERN;
+ oid[1] = KERN_PROC;
+ oid[2] = KERN_PROC_ARGS;
+ oid[3] = getpid();
+ sysctl(oid, 4, 0, 0, kbuf, strlen(kbuf) + 1);
+
+ if (ps_strings == NULL) {
+ len = sizeof(ul_ps_strings);
+ if (sysctlbyname("kern.ps_strings", &ul_ps_strings, &len, NULL,
+ 0) == -1)
+ ul_ps_strings = PS_STRINGS;
+ ps_strings = (struct ps_strings *)ul_ps_strings;
+ }
+
+ /* PS_STRINGS points to zeroed memory on a style #2 kernel */
+ if (ps_strings->ps_argvstr) {
+ /* style #3 */
+ if (oargc == -1) {
+ /* Record our original args */
+ oargc = ps_strings->ps_nargvstr;
+ oargv = ps_strings->ps_argvstr;
+ for (nargc = len = 0; nargc < oargc; nargc++) {
+ snprintf(obuf + len, sizeof(obuf) - len, "%s%s",
+ len ? " " : "", oargv[nargc]);
+ if (len)
+ len++;
+ len += strlen(oargv[nargc]);
+ if (len >= sizeof(obuf))
+ break;
+ }
+ }
+ ps_strings->ps_nargvstr = nargc;
+ ps_strings->ps_argvstr = nargvp;
+ } else {
+ /* style #2 - we can only restore our first arg :-( */
+ if (*obuf == '\0')
+ strncpy(obuf, OLD_PS_STRINGS->old_ps_argvstr,
+ sizeof(obuf) - 1);
+ OLD_PS_STRINGS->old_ps_nargvstr = 1;
+ OLD_PS_STRINGS->old_ps_argvstr = nargvp[0];
+ }
+}
diff --git a/lib/libutil/stat_flags.c b/lib/libutil/stat_flags.c
new file mode 100644
index 0000000..5235eb3
--- /dev/null
+++ b/lib/libutil/stat_flags.c
@@ -0,0 +1,174 @@
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)stat_flags.c 8.1 (Berkeley) 5/31/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stddef.h>
+#include <string.h>
+
+#define SAPPEND(s) { \
+ if (prefix != NULL) \
+ (void)strcat(string, prefix); \
+ (void)strcat(string, s); \
+ prefix = ","; \
+}
+
+/*
+ * flags_to_string --
+ * Convert stat flags to a comma-separated string. If no flags
+ * are set, return the default string.
+ */
+char *
+flags_to_string(flags, def)
+ u_long flags;
+ char *def;
+{
+ static char string[128];
+ char *prefix;
+
+ string[0] = '\0';
+ prefix = NULL;
+ if (flags & UF_APPEND)
+ SAPPEND("uappnd");
+ if (flags & UF_IMMUTABLE)
+ SAPPEND("uchg");
+#ifdef UF_NOUNLINK
+ if (flags & UF_NOUNLINK)
+ SAPPEND("uunlnk");
+#endif
+ if (flags & UF_NODUMP)
+ SAPPEND("nodump");
+ if (flags & UF_OPAQUE)
+ SAPPEND("opaque");
+ if (flags & SF_APPEND)
+ SAPPEND("sappnd");
+ if (flags & SF_ARCHIVED)
+ SAPPEND("arch");
+ if (flags & SF_IMMUTABLE)
+ SAPPEND("schg");
+#ifdef SF_NOUNLINK
+ if (flags & SF_NOUNLINK)
+ SAPPEND("sunlnk");
+#endif
+ return (prefix == NULL && def != NULL ? def : string);
+}
+
+#define TEST(a, b, f) { \
+ if (!memcmp(a, b, sizeof(b))) { \
+ if (clear) { \
+ if (clrp) \
+ *clrp |= (f); \
+ } else if (setp) \
+ *setp |= (f); \
+ break; \
+ } \
+}
+
+/*
+ * string_to_flags --
+ * Take string of arguments and return stat flags. Return 0 on
+ * success, 1 on failure. On failure, stringp is set to point
+ * to the offending token.
+ */
+int
+string_to_flags(stringp, setp, clrp)
+ char **stringp;
+ u_long *setp, *clrp;
+{
+ int clear;
+ char *string, *p;
+
+ if (setp)
+ *setp = 0;
+ if (clrp)
+ *clrp = 0;
+ string = *stringp;
+ while ((p = strsep(&string, "\t ,")) != NULL) {
+ clear = 0;
+ *stringp = p;
+ if (*p == '\0')
+ continue;
+ if (p[0] == 'n' && p[1] == 'o') {
+ clear = 1;
+ p += 2;
+ }
+ switch (p[0]) {
+ case 'a':
+ TEST(p, "arch", SF_ARCHIVED);
+ TEST(p, "archived", SF_ARCHIVED);
+ return (1);
+ case 'd':
+ clear = !clear;
+ TEST(p, "dump", UF_NODUMP);
+ return (1);
+ case 'o':
+ TEST(p, "opaque", UF_OPAQUE);
+ return (1);
+ case 's':
+ TEST(p, "sappnd", SF_APPEND);
+ TEST(p, "sappend", SF_APPEND);
+ TEST(p, "schg", SF_IMMUTABLE);
+ TEST(p, "schange", SF_IMMUTABLE);
+ TEST(p, "simmutable", SF_IMMUTABLE);
+#ifdef SF_NOUNLINK
+ TEST(p, "sunlnk", SF_NOUNLINK);
+ TEST(p, "sunlink", SF_NOUNLINK);
+#endif
+ return (1);
+ case 'u':
+ TEST(p, "uappnd", UF_APPEND);
+ TEST(p, "uappend", UF_APPEND);
+ TEST(p, "uchg", UF_IMMUTABLE);
+ TEST(p, "uchange", UF_IMMUTABLE);
+ TEST(p, "uimmutable", UF_IMMUTABLE);
+#ifdef UF_NOUNLINK
+ TEST(p, "uunlnk", UF_NOUNLINK);
+ TEST(p, "uunlink", UF_NOUNLINK);
+#endif
+ /* FALLTHROUGH */
+ default:
+ return (1);
+ }
+ }
+ return (0);
+}
diff --git a/lib/libutil/trimdomain.3 b/lib/libutil/trimdomain.3
new file mode 100644
index 0000000..e4d70b8
--- /dev/null
+++ b/lib/libutil/trimdomain.3
@@ -0,0 +1,86 @@
+.\" Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 7, 1999
+.Os
+.Dt TRIMDOMAIN 3
+.Sh NAME
+.Nm trimdomain
+.Nd "trim the current domain name from a host name"
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <libutil.h>
+.Ft void
+.Fn trimdomain "char *fullhost" "int hostsize"
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+The function
+.Fn trimdomain
+removes the current domain name from the passed
+.Ar fullhost
+name by writing a
+.Dv NUL
+character over the first period of the passed name. The current domain
+name is determined by calling
+.Xr gethostname 3
+and removing everything up to the first period. The name is determined
+the first time this function is called and is cached for future use.
+.Pp
+.Fn trimdomain
+will only trim the domain name if the passed
+.Ar fullname
+ends with the current domain name and if the length of the resulting host
+name does not exceed
+.Ar hostsize .
+.Pp
+If the passed
+.Ar fullname
+is actually a
+.Dv DISPLAY
+specification of the form
+.Sm off
+.Ar host No . Ar domain No : Ns
+.Sm on
+.Ar \&nn Oo
+.No . Ns Ar \&nn
+.Oc
+and the domain name is the same as the local domain name,
+.Fn trimdomain
+will remove the embedded domain name, copying the screen and display
+numbers to the end of the base host name and resulting in
+.Ar host No : Ns Ar \&nn Oo
+.No . Ns Ar \&nn
+.Oc .
+.Sh RETURN VALUES
+.Fn trimdomain
+does not return a value.
+.Sh SEE ALSO
+.Xr gethostname 3
diff --git a/lib/libutil/uucplock.3 b/lib/libutil/uucplock.3
new file mode 100644
index 0000000..99534a6
--- /dev/null
+++ b/lib/libutil/uucplock.3
@@ -0,0 +1,183 @@
+.\"
+.\" Copyright (c) 1996 Brian Somers <brian@awfulhak.demon.co.uk>
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" "
+.Dd March 30, 1997
+.Os
+.Dt UUCPLOCK 3
+.Sh NAME
+.Nm uu_lock ,
+.Nm uu_unlock ,
+.Nm uu_lockerr
+.Nd acquire and release control of a serial device
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <libutil.h>
+.Ft int
+.Fn uu_lock "const char *ttyname"
+.Ft int
+.Fn uu_lock_txfr "const char *ttyname" "pid_t pid"
+.Ft int
+.Fn uu_unlock "const char *ttyname"
+.Ft const char *
+.Fn uu_lockerr "int uu_lockresult"
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+The
+.Fn uu_lock
+function attempts to create a lock file called
+.Pa /var/spool/lock/LCK..
+with a suffix given by the passed
+.Fa ttyname .
+If the file already exists, it is expected to contain the process
+id of the locking program.
+.Pp
+If the file does not already exist, or the owning process given by
+the process id found in the lock file is no longer running,
+.Fn uu_lock
+will write its own process id into the file and return success.
+.Pp
+.Fn uu_lock_txfr
+transfers lock ownership to another process.
+.Fn uu_lock
+must have previously been successful.
+.Pp
+.Fn uu_unlock
+removes the lockfile created by
+.Fn uu_lock
+for the given
+.Fa ttyname .
+Care should be taken that
+.Fn uu_lock
+was successful before calling
+.Fn uu_unlock .
+.Pp
+.Fn uu_lockerr
+returns an error string representing the error
+.Fa uu_lockresult ,
+as returned from
+.Fn uu_lock .
+.Sh RETURN VALUES
+.Fn uu_unlock
+returns 0 on success and -1 on failure.
+.Pp
+.Fn uu_lock
+may return any of the following values:
+.Pp
+.Dv UU_LOCK_INUSE:
+The lock is in use by another process.
+.Pp
+.Dv UU_LOCK_OK:
+The lock was successfully created.
+.Pp
+.Dv UU_LOCK_OPEN_ERR:
+The lock file could not be opened via
+.Xr open 2 .
+.Pp
+.Dv UU_LOCK_READ_ERR:
+The lock file could not be read via
+.Xr read 2 .
+.Pp
+.Dv UU_LOCK_CREAT_ERR:
+Can't create temporary lock file via
+.Xr creat 2 .
+.Pp
+.Dv UU_LOCK_WRITE_ERR:
+The current process id could not be written to the lock file via a call to
+.Xr write 2 .
+.Pp
+.Dv UU_LOCK_LINK_ERR:
+Can't link temporary lock file via
+.Xr link 2 .
+.Pp
+.Dv UU_LOCK_TRY_ERR:
+Locking attempts are failed after 5 tries.
+.Pp
+If a value of
+.Dv UU_LOCK_OK
+is passed to
+.Fn uu_lockerr ,
+an empty string is returned.
+Otherwise, a string specifying
+the reason for failure is returned.
+.Fn uu_lockerr
+uses the current value of
+.Va errno
+to determine the exact error. Care should be made not to allow
+.Va errno
+to be changed between calls to
+.Fn uu_lock
+and
+.Fn uu_lockerr .
+.Pp
+.Fn uu_lock_txfr
+may return any of the following values:
+.Pp
+.Dv UU_LOCK_OK:
+The transfer was successful. The specified process now holds the device
+lock.
+.Pp
+.Dv UU_LOCK_OWNER_ERR:
+The current process does not already own a lock on the specified device.
+.Pp
+.Dv UU_LOCK_WRITE_ERR:
+The new process id could not be written to the lock file via a call to
+.Xr write 2 .
+.Sh ERRORS
+If
+.Fn uu_lock
+returns one of the error values above, the global value
+.Va errno
+can be used to determine the cause. Refer to the respective manual pages
+for further details.
+.Pp
+.Fn uu_unlock
+will set the global variable
+.Va errno
+to reflect the reason that the lock file could not be removed.
+Refer to the description of
+.Xr unlink 2
+for further details.
+.Sh SEE ALSO
+.Xr lseek 2 ,
+.Xr open 2 ,
+.Xr read 2 ,
+.Xr write 2
+.Sh BUGS
+It is possible that a stale lock is not recognised as such if a new
+processes is assigned the same processes id as the program that left
+the stale lock.
+.Pp
+The calling process must have write permissions to the
+.Pa /var/spool/lock
+directory. There is no mechanism in place to ensure that the
+permissions of this directory are the same as those of the
+serial devices that might be locked.
diff --git a/lib/libutil/uucplock.c b/lib/libutil/uucplock.c
new file mode 100644
index 0000000..012016a
--- /dev/null
+++ b/lib/libutil/uucplock.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#ifndef lint
+static const char sccsid[] = "@(#)uucplock.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <paths.h>
+#include <string.h>
+#include "libutil.h"
+
+#define MAXTRIES 5
+
+#define LOCKTMP "LCKTMP..%d"
+#define LOCKFMT "LCK..%s"
+
+#define GORET(level, val) { err = errno; uuerr = (val); \
+ goto __CONCAT(ret, level); }
+
+/* Forward declarations */
+static int put_pid (int fd, pid_t pid);
+static pid_t get_pid (int fd,int *err);
+
+/*
+ * uucp style locking routines
+ */
+
+int
+uu_lock(const char *ttyname)
+{
+ int fd, tmpfd, i;
+ pid_t pid, pid_old;
+ char lckname[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN],
+ lcktmpname[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN];
+ int err, uuerr;
+
+ pid = getpid();
+ (void)snprintf(lcktmpname, sizeof(lcktmpname), _PATH_UUCPLOCK LOCKTMP,
+ pid);
+ (void)snprintf(lckname, sizeof(lckname), _PATH_UUCPLOCK LOCKFMT,
+ ttyname);
+ if ((tmpfd = creat(lcktmpname, 0664)) < 0)
+ GORET(0, UU_LOCK_CREAT_ERR);
+
+ for (i = 0; i < MAXTRIES; i++) {
+ if (link (lcktmpname, lckname) < 0) {
+ if (errno != EEXIST)
+ GORET(1, UU_LOCK_LINK_ERR);
+ /*
+ * file is already locked
+ * check to see if the process holding the lock
+ * still exists
+ */
+ if ((fd = open(lckname, O_RDONLY)) < 0)
+ GORET(1, UU_LOCK_OPEN_ERR);
+
+ if ((pid_old = get_pid (fd, &err)) == -1)
+ GORET(2, UU_LOCK_READ_ERR);
+
+ close(fd);
+
+ if (kill(pid_old, 0) == 0 || errno != ESRCH)
+ GORET(1, UU_LOCK_INUSE);
+ /*
+ * The process that locked the file isn't running, so
+ * we'll lock it ourselves
+ */
+ (void)unlink(lckname);
+ } else {
+ if (!put_pid (tmpfd, pid))
+ GORET(3, UU_LOCK_WRITE_ERR);
+ break;
+ }
+ }
+ GORET(1, (i >= MAXTRIES) ? UU_LOCK_TRY_ERR : UU_LOCK_OK);
+
+ret3:
+ (void)unlink(lckname);
+ goto ret1;
+ret2:
+ (void)close(fd);
+ret1:
+ (void)close(tmpfd);
+ (void)unlink(lcktmpname);
+ret0:
+ errno = err;
+ return uuerr;
+}
+
+int
+uu_lock_txfr(const char *ttyname, pid_t pid)
+{
+ int fd, err;
+ char lckname[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN];
+
+ snprintf(lckname, sizeof(lckname), _PATH_UUCPLOCK LOCKFMT, ttyname);
+
+ if ((fd = open(lckname, O_RDWR)) < 0)
+ return UU_LOCK_OWNER_ERR;
+ if (get_pid(fd, &err) != getpid())
+ return UU_LOCK_OWNER_ERR;
+ lseek(fd, 0, SEEK_SET);
+ if (put_pid(fd, pid))
+ return UU_LOCK_WRITE_ERR;
+ close(fd);
+
+ return UU_LOCK_OK;
+}
+
+int
+uu_unlock(const char *ttyname)
+{
+ char tbuf[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN];
+
+ (void)snprintf(tbuf, sizeof(tbuf), _PATH_UUCPLOCK LOCKFMT, ttyname);
+ return unlink(tbuf);
+}
+
+const char *
+uu_lockerr(int uu_lockresult)
+{
+ static char errbuf[128];
+ char *fmt;
+
+ switch (uu_lockresult) {
+ case UU_LOCK_INUSE:
+ return "device in use";
+ case UU_LOCK_OK:
+ return "";
+ case UU_LOCK_OPEN_ERR:
+ fmt = "open error: %s";
+ break;
+ case UU_LOCK_READ_ERR:
+ fmt = "read error: %s";
+ break;
+ case UU_LOCK_CREAT_ERR:
+ fmt = "creat error: %s";
+ break;
+ case UU_LOCK_WRITE_ERR:
+ fmt = "write error: %s";
+ break;
+ case UU_LOCK_LINK_ERR:
+ fmt = "link error: %s";
+ break;
+ case UU_LOCK_TRY_ERR:
+ fmt = "too many tries: %s";
+ break;
+ case UU_LOCK_OWNER_ERR:
+ fmt = "not locking process: %s";
+ break;
+ default:
+ fmt = "undefined error: %s";
+ break;
+ }
+
+ (void)snprintf(errbuf, sizeof(errbuf), fmt, strerror(errno));
+ return errbuf;
+}
+
+static int
+put_pid(int fd, pid_t pid)
+{
+ char buf[32];
+ int len;
+
+ len = sprintf (buf, "%10d\n", (int)pid);
+ return write (fd, buf, len) == len;
+}
+
+static pid_t
+get_pid(int fd, int *err)
+{
+ int bytes_read;
+ char buf[32];
+ pid_t pid;
+
+ bytes_read = read (fd, buf, sizeof (buf) - 1);
+ if (bytes_read > 0) {
+ buf[bytes_read] = '\0';
+ pid = strtol (buf, (char **) NULL, 10);
+ } else {
+ pid = -1;
+ *err = bytes_read ? errno : EINVAL;
+ }
+ return pid;
+}
+
+/* end of uucplock.c */
diff --git a/lib/libvgl/Makefile b/lib/libvgl/Makefile
new file mode 100644
index 0000000..11b0b75
--- /dev/null
+++ b/lib/libvgl/Makefile
@@ -0,0 +1,35 @@
+# $FreeBSD$
+LIB= vgl
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 0
+CFLAGS+=-Wall -I${.CURDIR}
+SRCS= main.c simple.c bitmap.c text.c mouse.c keyboard.c
+MAN3= vgl.3
+MLINKS+= vgl.3 VGLBitmapCopy.3 \
+ vgl.3 VGLBitmapPutChar.3 \
+ vgl.3 VGLBitmapString.3 \
+ vgl.3 VGLBlankDisplay.3 \
+ vgl.3 VGLBox.3 \
+ vgl.3 VGLCheckSwitch.3 \
+ vgl.3 VGLClear.3 \
+ vgl.3 VGLEllipse.3 \
+ vgl.3 VGLEnd.3 \
+ vgl.3 VGLFilledBox.3 \
+ vgl.3 VGLFilledEllipse.3 \
+ vgl.3 VGLInit.3 \
+ vgl.3 VGLLine.3 \
+ vgl.3 VGLMouseInit.3 \
+ vgl.3 VGLMouseMode.3 \
+ vgl.3 VGLMouseSetImage.3 \
+ vgl.3 VGLMouseSetStdImage.3 \
+ vgl.3 VGLMouseStatus.3 \
+ vgl.3 VGLSetBorder.3 \
+ vgl.3 VGLSetPalette.3 \
+ vgl.3 VGLSetPaletteIndex.3 \
+ vgl.3 VGLTextSetFontFile.3
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/vgl.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libvgl/bitmap.c b/lib/libvgl/bitmap.c
new file mode 100644
index 0000000..2714e89
--- /dev/null
+++ b/lib/libvgl/bitmap.c
@@ -0,0 +1,364 @@
+/*-
+ * Copyright (c) 1991-1997 Søren Schmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <signal.h>
+#include <machine/console.h>
+#include "vgl.h"
+
+#define min(x, y) (((x) < (y)) ? (x) : (y))
+
+static byte mask[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
+static int color2bit[16] = {0x00000000, 0x00000001, 0x00000100, 0x00000101,
+ 0x00010000, 0x00010001, 0x00010100, 0x00010101,
+ 0x01000000, 0x01000001, 0x01000100, 0x01000101,
+ 0x01010000, 0x01010001, 0x01010100, 0x01010101};
+
+static void
+WriteVerticalLine(VGLBitmap *dst, int x, int y, int width, byte *line)
+{
+ int i, pos, last, planepos, start_offset, end_offset, offset;
+ int len;
+ unsigned int word = 0;
+ byte *address;
+ byte *VGLPlane[4];
+
+ switch (dst->Type) {
+ case VIDBUF4:
+ case VIDBUF4S:
+ start_offset = (x & 0x07);
+ end_offset = (x + width) & 0x07;
+ i = (width + start_offset) / 8;
+ if (end_offset)
+ i++;
+ VGLPlane[0] = VGLBuf;
+ VGLPlane[1] = VGLPlane[0] + i;
+ VGLPlane[2] = VGLPlane[1] + i;
+ VGLPlane[3] = VGLPlane[2] + i;
+ pos = 0;
+ planepos = 0;
+ last = 8 - start_offset;
+ while (pos < width) {
+ word = 0;
+ while (pos < last && pos < width)
+ word = (word<<1) | color2bit[line[pos++]&0x0f];
+ VGLPlane[0][planepos] = word;
+ VGLPlane[1][planepos] = word>>8;
+ VGLPlane[2][planepos] = word>>16;
+ VGLPlane[3][planepos] = word>>24;
+ planepos++;
+ last += 8;
+ }
+ planepos--;
+ if (end_offset) {
+ word <<= (8 - end_offset);
+ VGLPlane[0][planepos] = word;
+ VGLPlane[1][planepos] = word>>8;
+ VGLPlane[2][planepos] = word>>16;
+ VGLPlane[3][planepos] = word>>24;
+ }
+ if (start_offset || end_offset)
+ width+=8;
+ width /= 8;
+ outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */
+ outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */
+ for (i=0; i<4; i++) {
+ outb(0x3c4, 0x02);
+ outb(0x3c5, 0x01<<i);
+ outb(0x3ce, 0x04);
+ outb(0x3cf, i);
+ pos = VGLAdpInfo.va_line_width*y + x/8;
+ if (dst->Type == VIDBUF4) {
+ if (end_offset)
+ VGLPlane[i][planepos] |= dst->Bitmap[pos+planepos] & mask[end_offset];
+ if (start_offset)
+ VGLPlane[i][0] |= dst->Bitmap[pos] & ~mask[start_offset];
+ bcopy(&VGLPlane[i][0], dst->Bitmap + pos, width);
+ } else { /* VIDBUF4S */
+ if (end_offset) {
+ offset = VGLSetSegment(pos + planepos);
+ VGLPlane[i][planepos] |= dst->Bitmap[offset] & mask[end_offset];
+ }
+ offset = VGLSetSegment(pos);
+ if (start_offset)
+ VGLPlane[i][0] |= dst->Bitmap[offset] & ~mask[start_offset];
+ for (last = width; ; ) {
+ len = min(VGLAdpInfo.va_window_size - offset, last);
+ bcopy(&VGLPlane[i][width - last], dst->Bitmap + offset, len);
+ pos += len;
+ last -= len;
+ if (last <= 0)
+ break;
+ offset = VGLSetSegment(pos);
+ }
+ }
+ }
+ break;
+ case VIDBUF8X:
+ address = dst->Bitmap + VGLAdpInfo.va_line_width * y + x/4;
+ for (i=0; i<4; i++) {
+ outb(0x3c4, 0x02);
+ outb(0x3c5, 0x01 << ((x + i)%4));
+ for (planepos=0, pos=i; pos<width; planepos++, pos+=4)
+ address[planepos] = line[pos];
+ if ((x + i)%4 == 3)
+ ++address;
+ }
+ break;
+ case VIDBUF8S:
+ pos = dst->VXsize * y + x;
+ while (width > 0) {
+ offset = VGLSetSegment(pos);
+ i = min(VGLAdpInfo.va_window_size - offset, width);
+ bcopy(line, dst->Bitmap + offset, i);
+ line += i;
+ pos += i;
+ width -= i;
+ }
+ break;
+ case VIDBUF8:
+ case MEMBUF:
+ address = dst->Bitmap + dst->VXsize * y + x;
+ bcopy(line, address, width);
+ break;
+
+ default:
+ }
+}
+
+static void
+ReadVerticalLine(VGLBitmap *src, int x, int y, int width, byte *line)
+{
+ int i, bit, pos, count, planepos, start_offset, end_offset, offset;
+ int width2, len;
+ byte *address;
+ byte *VGLPlane[4];
+
+ switch (src->Type) {
+ case VIDBUF4S:
+ start_offset = (x & 0x07);
+ end_offset = (x + width) & 0x07;
+ count = (width + start_offset) / 8;
+ if (end_offset)
+ count++;
+ VGLPlane[0] = VGLBuf;
+ VGLPlane[1] = VGLPlane[0] + count;
+ VGLPlane[2] = VGLPlane[1] + count;
+ VGLPlane[3] = VGLPlane[2] + count;
+ for (i=0; i<4; i++) {
+ outb(0x3ce, 0x04);
+ outb(0x3cf, i);
+ pos = VGLAdpInfo.va_line_width*y + x/8;
+ for (width2 = count; width2 > 0; ) {
+ offset = VGLSetSegment(pos);
+ len = min(VGLAdpInfo.va_window_size - offset, width2);
+ bcopy(src->Bitmap + offset, &VGLPlane[i][count - width2], len);
+ pos += len;
+ width2 -= len;
+ }
+ }
+ goto read_planar;
+ case VIDBUF4:
+ address = src->Bitmap + VGLAdpInfo.va_line_width * y + x/8;
+ start_offset = (x & 0x07);
+ end_offset = (x + width) & 0x07;
+ count = (width + start_offset) / 8;
+ if (end_offset)
+ count++;
+ VGLPlane[0] = VGLBuf;
+ VGLPlane[1] = VGLPlane[0] + count;
+ VGLPlane[2] = VGLPlane[1] + count;
+ VGLPlane[3] = VGLPlane[2] + count;
+ for (i=0; i<4; i++) {
+ outb(0x3ce, 0x04);
+ outb(0x3cf, i);
+ bcopy(address, &VGLPlane[i][0], count);
+ }
+read_planar:
+ pos = 0;
+ planepos = 0;
+ bit = 7 - start_offset;
+ while (pos < width) {
+ for (; bit >= 0 && pos < width; bit--, pos++) {
+ line[pos] = (VGLPlane[0][planepos] & (1<<bit) ? 1 : 0) |
+ ((VGLPlane[1][planepos] & (1<<bit) ? 1 : 0) << 1) |
+ ((VGLPlane[2][planepos] & (1<<bit) ? 1 : 0) << 2) |
+ ((VGLPlane[3][planepos] & (1<<bit) ? 1 : 0) << 3);
+ }
+ planepos++;
+ bit = 7;
+ }
+ break;
+ case VIDBUF8X:
+ address = src->Bitmap + VGLAdpInfo.va_line_width * y + x/4;
+ for (i=0; i<4; i++) {
+ outb(0x3ce, 0x04);
+ outb(0x3cf, (x + i)%4);
+ for (planepos=0, pos=i; pos<width; planepos++, pos+=4)
+ line[pos] = address[planepos];
+ if ((x + i)%4 == 3)
+ ++address;
+ }
+ break;
+ case VIDBUF8S:
+ pos = src->VXsize * y + x;
+ while (width > 0) {
+ offset = VGLSetSegment(pos);
+ i = min(VGLAdpInfo.va_window_size - offset, width);
+ bcopy(src->Bitmap + offset, line, i);
+ line += i;
+ pos += i;
+ width -= i;
+ }
+ break;
+ case VIDBUF8:
+ case MEMBUF:
+ address = src->Bitmap + src->VXsize * y + x;
+ bcopy(address, line, width);
+ break;
+ default:
+ }
+}
+
+int
+__VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy,
+ VGLBitmap *dst, int dstx, int dsty, int width, int hight)
+{
+ int srcline, dstline;
+
+ if (srcx>src->VXsize || srcy>src->VYsize
+ || dstx>dst->VXsize || dsty>dst->VYsize)
+ return -1;
+ if (srcx < 0) {
+ width=width+srcx; dstx-=srcx; srcx=0;
+ }
+ if (srcy < 0) {
+ hight=hight+srcy; dsty-=srcy; srcy=0;
+ }
+ if (dstx < 0) {
+ width=width+dstx; srcx-=dstx; dstx=0;
+ }
+ if (dsty < 0) {
+ hight=hight+dsty; srcy-=dsty; dsty=0;
+ }
+ if (srcx+width > src->VXsize)
+ width=src->VXsize-srcx;
+ if (srcy+hight > src->VYsize)
+ hight=src->VYsize-srcy;
+ if (dstx+width > dst->VXsize)
+ width=dst->VXsize-dstx;
+ if (dsty+hight > dst->VYsize)
+ hight=dst->VYsize-dsty;
+ if (width < 0 || hight < 0)
+ return -1;
+ if (src->Type == MEMBUF) {
+ for (srcline=srcy, dstline=dsty; srcline<srcy+hight; srcline++, dstline++) {
+ WriteVerticalLine(dst, dstx, dstline, width,
+ (src->Bitmap+(srcline*src->VXsize)+srcx));
+ }
+ }
+ else if (dst->Type == MEMBUF) {
+ for (srcline=srcy, dstline=dsty; srcline<srcy+hight; srcline++, dstline++) {
+ ReadVerticalLine(src, srcx, srcline, width,
+ (dst->Bitmap+(dstline*dst->VXsize)+dstx));
+ }
+ }
+ else {
+ byte buffer[2048]; /* XXX */
+ byte *p;
+
+ if (width > sizeof(buffer)) {
+ p = malloc(width);
+ if (p == NULL)
+ return 1;
+ } else {
+ p = buffer;
+ }
+ for (srcline=srcy, dstline=dsty; srcline<srcy+hight; srcline++, dstline++) {
+ ReadVerticalLine(src, srcx, srcline, width, p);
+ WriteVerticalLine(dst, dstx, dstline, width, p);
+ }
+ if (width > sizeof(buffer))
+ free(p);
+ }
+ return 0;
+}
+
+int
+VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy,
+ VGLBitmap *dst, int dstx, int dsty, int width, int hight)
+{
+ int error;
+
+ VGLMouseFreeze(dstx, dsty, width, hight, 0);
+ error = __VGLBitmapCopy(src, srcx, srcy, dst, dstx, dsty, width, hight);
+ VGLMouseUnFreeze();
+ return error;
+}
+
+VGLBitmap
+*VGLBitmapCreate(int type, int xsize, int ysize, byte *bits)
+{
+ VGLBitmap *object;
+
+ if (type != MEMBUF)
+ return NULL;
+ if (xsize < 0 || ysize < 0)
+ return NULL;
+ object = (VGLBitmap *)malloc(sizeof(*object));
+ if (object == NULL)
+ return NULL;
+ object->Type = type;
+ object->Xsize = xsize;
+ object->Ysize = ysize;
+ object->VXsize = xsize;
+ object->VYsize = ysize;
+ object->Xorigin = 0;
+ object->Yorigin = 0;
+ object->Bitmap = bits;
+ return object;
+}
+
+void
+VGLBitmapDestroy(VGLBitmap *object)
+{
+ if (object->Bitmap)
+ free(object->Bitmap);
+ free(object);
+}
+
+int
+VGLBitmapAllocateBits(VGLBitmap *object)
+{
+ object->Bitmap = (byte *)malloc(object->VXsize*object->VYsize);
+ if (object->Bitmap == NULL)
+ return -1;
+ return 0;
+}
diff --git a/lib/libvgl/keyboard.c b/lib/libvgl/keyboard.c
new file mode 100644
index 0000000..690da32
--- /dev/null
+++ b/lib/libvgl/keyboard.c
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 1997 Søren Schmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <sys/time.h>
+#include <machine/console.h>
+#include "vgl.h"
+
+static struct termios VGLKeyboardTty;
+static int VGLKeyboardMode = -1;
+
+int
+VGLKeyboardInit(int mode)
+{
+ static struct termios term;
+
+ ioctl(0, KDGKBMODE, &VGLKeyboardMode);
+ tcgetattr(0, &VGLKeyboardTty);
+
+ term = VGLKeyboardTty;
+ cfmakeraw(&term);
+ term.c_iflag = IGNPAR | IGNBRK;
+ term.c_oflag = 0;
+ term.c_cflag = CREAD | CS8;
+ term.c_lflag &= ~(ICANON | ECHO | ISIG);
+ term.c_cc[VTIME] = 0;
+ term.c_cc[VMIN] = 0;
+ cfsetispeed(&term, 9600);
+ cfsetospeed(&term, 9600);
+ tcsetattr(0, TCSANOW, &term);
+
+ switch (mode) {
+ case VGL_RAWKEYS:
+ ioctl(0, KDSKBMODE, K_RAW);
+ break;
+ case VGL_CODEKEYS:
+ ioctl(0, KDSKBMODE, K_CODE);
+ break;
+ case VGL_XLATEKEYS:
+ ioctl(0, KDSKBMODE, K_XLATE);
+ break;
+ }
+ return 0;
+}
+
+void
+VGLKeyboardEnd()
+{
+ if (VGLKeyboardMode != -1) {
+ ioctl(0, KDSKBMODE, VGLKeyboardMode);
+ tcsetattr(0, TCSANOW, &VGLKeyboardTty);
+ }
+}
+
+int
+VGLKeyboardGetCh()
+{
+ unsigned char ch = 0;
+
+ read (0, &ch, 1);
+ return (int)ch;
+}
diff --git a/lib/libvgl/main.c b/lib/libvgl/main.c
new file mode 100644
index 0000000..8211842
--- /dev/null
+++ b/lib/libvgl/main.c
@@ -0,0 +1,477 @@
+/*-
+ * Copyright (c) 1991-1997 Søren Schmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/signal.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <machine/console.h>
+#include "vgl.h"
+
+#define min(x, y) (((x) < (y)) ? (x) : (y))
+#define max(x, y) (((x) > (y)) ? (x) : (y))
+
+VGLBitmap *VGLDisplay;
+video_info_t VGLModeInfo;
+video_adapter_info_t VGLAdpInfo;
+byte *VGLBuf;
+
+static int VGLMode;
+static int VGLOldMode;
+static size_t VGLBufSize;
+static byte *VGLMem = MAP_FAILED;
+static int VGLSwitchPending;
+static int VGLOnDisplay;
+static unsigned int VGLCurWindow;
+static int VGLInitDone = 0;
+
+void
+VGLEnd()
+{
+struct vt_mode smode;
+
+ if (!VGLInitDone)
+ return;
+ VGLInitDone = 0;
+
+ signal(SIGUSR1, SIG_IGN);
+
+ if (VGLMem != MAP_FAILED) {
+ VGLClear(VGLDisplay, 0);
+ munmap(VGLMem, VGLAdpInfo.va_window_size);
+ }
+
+ if (VGLOldMode >= M_VESA_BASE) {
+ /* ugly, but necessary */
+ ioctl(0, _IO('V', VGLOldMode - M_VESA_BASE), 0);
+ if (VGLOldMode == M_VESA_800x600) {
+ int size[3];
+ size[0] = 80;
+ size[1] = 25;
+ size[2] = 16;
+ ioctl(0, KDRASTER, size);
+ }
+ } else {
+ ioctl(0, _IO('S', VGLOldMode), 0);
+ }
+ ioctl(0, KDDISABIO, 0);
+ ioctl(0, KDSETMODE, KD_TEXT);
+ smode.mode = VT_AUTO;
+ ioctl(0, VT_SETMODE, &smode);
+ if (VGLBuf)
+ free(VGLBuf);
+ VGLBuf = NULL;
+ free(VGLDisplay);
+ VGLDisplay = NULL;
+ VGLKeyboardEnd();
+}
+
+static void
+VGLAbort()
+{
+ VGLEnd();
+ exit(0);
+}
+
+static void
+VGLSwitch()
+{
+ if (!VGLOnDisplay)
+ VGLOnDisplay = 1;
+ else
+ VGLOnDisplay = 0;
+ VGLSwitchPending = 1;
+ signal(SIGUSR1, VGLSwitch);
+}
+
+int
+VGLInit(int mode)
+{
+ struct vt_mode smode;
+ int adptype;
+
+ if (VGLInitDone)
+ return -1;
+
+ signal(SIGUSR1, VGLSwitch);
+ signal(SIGINT, VGLAbort);
+ signal(SIGTERM, VGLAbort);
+ signal(SIGSEGV, VGLAbort);
+ signal(SIGBUS, VGLAbort);
+
+ VGLOnDisplay = 1;
+ VGLSwitchPending = 0;
+
+ if (ioctl(0, CONS_GET, &VGLOldMode) || ioctl(0, CONS_CURRENT, &adptype))
+ return -1;
+ if (IOCGROUP(mode) == 'V') /* XXX: this is ugly */
+ VGLModeInfo.vi_mode = (mode & 0x0ff) + M_VESA_BASE;
+ else
+ VGLModeInfo.vi_mode = mode & 0x0ff;
+ if (ioctl(0, CONS_MODEINFO, &VGLModeInfo)) /* FBIO_MODEINFO */
+ return -1;
+
+ VGLDisplay = (VGLBitmap *)malloc(sizeof(VGLBitmap));
+ if (VGLDisplay == NULL)
+ return -2;
+
+ if (ioctl(0, KDENABIO, 0)) {
+ free(VGLDisplay);
+ return -3;
+ }
+
+ VGLInitDone = 1;
+
+ /*
+ * vi_mem_model specifies the memory model of the current video mode
+ * in -CURRENT.
+ */
+ switch (VGLModeInfo.vi_mem_model) {
+ case V_INFO_MM_PLANAR:
+ /* we can handle EGA/VGA planner modes only */
+ if (VGLModeInfo.vi_depth != 4 || VGLModeInfo.vi_planes != 4
+ || (adptype != KD_EGA && adptype != KD_VGA)) {
+ VGLEnd();
+ return -4;
+ }
+ VGLDisplay->Type = VIDBUF4;
+ break;
+ case V_INFO_MM_PACKED:
+ /* we can do only 256 color packed modes */
+ if (VGLModeInfo.vi_depth != 8) {
+ VGLEnd();
+ return -4;
+ }
+ VGLDisplay->Type = VIDBUF8;
+ break;
+ case V_INFO_MM_VGAX:
+ VGLDisplay->Type = VIDBUF8X;
+ break;
+ default:
+ VGLEnd();
+ return -4;
+ }
+
+ ioctl(0, VT_WAITACTIVE, 0);
+ ioctl(0, KDSETMODE, KD_GRAPHICS);
+ if (ioctl(0, mode, 0)) {
+ VGLEnd();
+ return -5;
+ }
+ if (ioctl(0, CONS_ADPINFO, &VGLAdpInfo)) { /* FBIO_ADPINFO */
+ VGLEnd();
+ return -6;
+ }
+
+ /*
+ * Calculate the shadow screen buffer size. In -CURRENT, va_buffer_size
+ * always holds the entire frame buffer size, wheather it's in the linear
+ * mode or windowed mode.
+ * VGLBufSize = VGLAdpInfo.va_buffer_size;
+ * In -STABLE, va_buffer_size holds the frame buffer size, only if
+ * the linear frame buffer mode is supported. Otherwise the field is zero.
+ * We shall calculate the minimal size in this case:
+ * VGLAdpInfo.va_line_width*VGLModeInfo.vi_height*VGLModeInfo.vi_planes
+ * or
+ * VGLAdpInfo.va_window_size*VGLModeInfo.vi_planes;
+ * Use whichever is larger.
+ */
+ if (VGLAdpInfo.va_buffer_size != 0)
+ VGLBufSize = VGLAdpInfo.va_buffer_size;
+ else
+ VGLBufSize = max(VGLAdpInfo.va_line_width*VGLModeInfo.vi_height,
+ VGLAdpInfo.va_window_size)*VGLModeInfo.vi_planes;
+ VGLBuf = malloc(VGLBufSize);
+ if (VGLBuf == NULL) {
+ VGLEnd();
+ return -7;
+ }
+
+#ifdef LIBVGL_DEBUG
+ fprintf(stderr, "VGLBufSize:0x%x\n", VGLBufSize);
+#endif
+
+ /* see if we are in the windowed buffer mode or in the linear buffer mode */
+ if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) {
+ if (VGLDisplay->Type == VIDBUF4)
+ VGLDisplay->Type = VIDBUF4S;
+ else if (VGLDisplay->Type == VIDBUF8)
+ VGLDisplay->Type = VIDBUF8S;
+ }
+
+ VGLMode = mode;
+ VGLCurWindow = 0;
+
+ VGLDisplay->Xsize = VGLModeInfo.vi_width;
+ VGLDisplay->Ysize = VGLModeInfo.vi_height;
+ VGLDisplay->VXsize = VGLAdpInfo.va_line_width
+ *8/(VGLModeInfo.vi_depth/VGLModeInfo.vi_planes);
+ VGLDisplay->VYsize = VGLBufSize/VGLModeInfo.vi_planes/VGLAdpInfo.va_line_width;
+ VGLDisplay->Xorigin = 0;
+ VGLDisplay->Yorigin = 0;
+
+ VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE,
+ MAP_FILE, 0, 0);
+ if (VGLMem == MAP_FAILED) {
+ VGLEnd();
+ return -7;
+ }
+ VGLDisplay->Bitmap = VGLMem;
+
+ VGLSavePalette();
+
+#ifdef LIBVGL_DEBUG
+ fprintf(stderr, "va_line_width:%d\n", VGLAdpInfo.va_line_width);
+ fprintf(stderr, "VGLXsize:%d, Ysize:%d, VXsize:%d, VYsize:%d\n",
+ VGLDisplay->Xsize, VGLDisplay->Ysize,
+ VGLDisplay->VXsize, VGLDisplay->VYsize);
+#endif
+
+ smode.mode = VT_PROCESS;
+ smode.waitv = 0;
+ smode.relsig = SIGUSR1;
+ smode.acqsig = SIGUSR1;
+ smode.frsig = SIGINT;
+ if (ioctl(0, VT_SETMODE, &smode)) {
+ VGLEnd();
+ return -9;
+ }
+ VGLTextSetFontFile((byte*)0);
+ VGLClear(VGLDisplay, 0);
+ return 0;
+}
+
+void
+VGLCheckSwitch()
+{
+ while (VGLSwitchPending) {
+ unsigned int offset;
+ unsigned int len;
+ int i;
+
+ VGLSwitchPending = 0;
+ if (VGLOnDisplay) {
+ ioctl(0, KDENABIO, 0);
+ ioctl(0, KDSETMODE, KD_GRAPHICS);
+ ioctl(0, VGLMode, 0);
+ VGLCurWindow = 0;
+ VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE,
+ MAP_FILE, 0, 0);
+
+ /* XXX: what if mmap() has failed! */
+ VGLDisplay->Type = VIDBUF8; /* XXX */
+ switch (VGLModeInfo.vi_mem_model) {
+ case V_INFO_MM_PLANAR:
+ if (VGLModeInfo.vi_depth == 4 && VGLModeInfo.vi_planes == 4) {
+ if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size)
+ VGLDisplay->Type = VIDBUF4S;
+ else
+ VGLDisplay->Type = VIDBUF4;
+ } else {
+ /* shouldn't be happening */
+ }
+ break;
+ case V_INFO_MM_PACKED:
+ if (VGLModeInfo.vi_depth == 8) {
+ if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size)
+ VGLDisplay->Type = VIDBUF8S;
+ else
+ VGLDisplay->Type = VIDBUF8;
+ } else {
+ /* shouldn't be happening */
+ }
+ break;
+ case V_INFO_MM_VGAX:
+ VGLDisplay->Type = VIDBUF8X;
+ break;
+ default:
+ /* shouldn't be happening */
+ break;
+ }
+
+ VGLDisplay->Bitmap = VGLMem;
+ VGLDisplay->Xsize = VGLModeInfo.vi_width;
+ VGLDisplay->Ysize = VGLModeInfo.vi_height;
+ VGLSetVScreenSize(VGLDisplay, VGLDisplay->VXsize, VGLDisplay->VYsize);
+ VGLPanScreen(VGLDisplay, VGLDisplay->Xorigin, VGLDisplay->Yorigin);
+ switch (VGLDisplay->Type) {
+ case VIDBUF4S:
+ outb(0x3c6, 0xff);
+ outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */
+ outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */
+ for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes;
+ offset += len) {
+ VGLSetSegment(offset);
+ len = min(VGLBufSize/VGLModeInfo.vi_planes - offset,
+ VGLAdpInfo.va_window_size);
+ for (i = 0; i < VGLModeInfo.vi_planes; i++) {
+ outb(0x3c4, 0x02);
+ outb(0x3c5, 0x01<<i);
+ bcopy(&VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset],
+ VGLMem, len);
+ }
+ }
+ break;
+ case VIDBUF4:
+ case VIDBUF8X:
+ outb(0x3c6, 0xff);
+ outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */
+ outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */
+ for (i = 0; i < VGLModeInfo.vi_planes; i++) {
+ outb(0x3c4, 0x02);
+ outb(0x3c5, 0x01<<i);
+ bcopy(&VGLBuf[i*VGLAdpInfo.va_window_size], VGLMem,
+ VGLAdpInfo.va_window_size);
+ }
+ break;
+ case VIDBUF8:
+ case VIDBUF8S:
+ for (offset = 0; offset < VGLBufSize; offset += len) {
+ VGLSetSegment(offset);
+ len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size);
+ bcopy(&VGLBuf[offset], VGLMem, len);
+ }
+ break;
+ }
+ VGLRestorePalette();
+ ioctl(0, VT_RELDISP, VT_ACKACQ);
+ }
+ else {
+ switch (VGLDisplay->Type) {
+ case VIDBUF4S:
+ for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes;
+ offset += len) {
+ VGLSetSegment(offset);
+ len = min(VGLBufSize/VGLModeInfo.vi_planes - offset,
+ VGLAdpInfo.va_window_size);
+ for (i = 0; i < VGLModeInfo.vi_planes; i++) {
+ outb(0x3ce, 0x04);
+ outb(0x3cf, i);
+ bcopy(VGLMem, &VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset],
+ len);
+ }
+ }
+ break;
+ case VIDBUF4:
+ case VIDBUF8X:
+ /*
+ * NOTE: the saved buffer is NOT in the MEMBUF format which
+ * the ordinary memory bitmap object is stored in. XXX
+ */
+ for (i = 0; i < VGLModeInfo.vi_planes; i++) {
+ outb(0x3ce, 0x04);
+ outb(0x3cf, i);
+ bcopy(VGLMem, &VGLBuf[i*VGLAdpInfo.va_window_size],
+ VGLAdpInfo.va_window_size);
+ }
+ break;
+ case VIDBUF8:
+ case VIDBUF8S:
+ for (offset = 0; offset < VGLBufSize; offset += len) {
+ VGLSetSegment(offset);
+ len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size);
+ bcopy(VGLMem, &VGLBuf[offset], len);
+ }
+ break;
+ }
+ VGLMem = MAP_FAILED;
+ munmap(VGLDisplay->Bitmap, VGLAdpInfo.va_window_size);
+ ioctl(0, VGLOldMode, 0);
+ ioctl(0, KDSETMODE, KD_TEXT);
+ ioctl(0, KDDISABIO, 0);
+ ioctl(0, VT_RELDISP, VT_TRUE);
+ VGLDisplay->Bitmap = VGLBuf;
+ VGLDisplay->Type = MEMBUF;
+ VGLDisplay->Xsize = VGLDisplay->VXsize;
+ VGLDisplay->Ysize = VGLDisplay->VYsize;
+ while (!VGLOnDisplay) pause();
+ }
+ }
+}
+
+int
+VGLSetSegment(unsigned int offset)
+{
+ if (offset/VGLAdpInfo.va_window_size != VGLCurWindow) {
+ ioctl(0, CONS_SETWINORG, offset); /* FBIO_SETWINORG */
+ VGLCurWindow = offset/VGLAdpInfo.va_window_size;
+ }
+ return (offset%VGLAdpInfo.va_window_size);
+}
+
+int
+VGLSetVScreenSize(VGLBitmap *object, int VXsize, int VYsize)
+{
+ if (VXsize < object->Xsize || VYsize < object->Ysize)
+ return -1;
+ if (object->Type == MEMBUF)
+ return -1;
+ if (ioctl(0, FBIO_SETLINEWIDTH, &VXsize))
+ return -1;
+ ioctl(0, CONS_ADPINFO, &VGLAdpInfo); /* FBIO_ADPINFO */
+ object->VXsize = VGLAdpInfo.va_line_width
+ *8/(VGLModeInfo.vi_depth/VGLModeInfo.vi_planes);
+ object->VYsize = VGLBufSize/VGLModeInfo.vi_planes/VGLAdpInfo.va_line_width;
+ if (VYsize < object->VYsize)
+ object->VYsize = VYsize;
+
+#ifdef LIBVGL_DEBUG
+ fprintf(stderr, "new size: VGLXsize:%d, Ysize:%d, VXsize:%d, VYsize:%d\n",
+ object->Xsize, object->Ysize, object->VXsize, object->VYsize);
+#endif
+
+ return 0;
+}
+
+int
+VGLPanScreen(VGLBitmap *object, int x, int y)
+{
+ video_display_start_t origin;
+
+ if (x < 0 || x + object->Xsize > object->VXsize
+ || y < 0 || y + object->Ysize > object->VYsize)
+ return -1;
+ if (object->Type == MEMBUF)
+ return 0;
+ origin.x = x;
+ origin.y = y;
+ if (ioctl(0, FBIO_SETDISPSTART, &origin))
+ return -1;
+ object->Xorigin = x;
+ object->Yorigin = y;
+
+#ifdef LIBVGL_DEBUG
+ fprintf(stderr, "new origin: (%d, %d)\n", x, y);
+#endif
+
+ return 0;
+}
diff --git a/lib/libvgl/mouse.c b/lib/libvgl/mouse.c
new file mode 100644
index 0000000..390ec6c
--- /dev/null
+++ b/lib/libvgl/mouse.c
@@ -0,0 +1,283 @@
+/*-
+ * Copyright (c) 1991-1997 Søren Schmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/signal.h>
+#include <machine/console.h>
+#include "vgl.h"
+
+#define X 0xff
+static byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
+ X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
+ X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
+ X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
+ X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
+ X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,
+ X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
+ X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
+ 0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,0,
+ 0,0,0,X,X,X,X,X,0,0,0,0,0,0,0,0,
+ 0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
+ 0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+};
+static byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
+ 0,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
+ 0,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
+ 0,X,X,0,X,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+};
+#undef X
+static VGLBitmap VGLMouseStdAndMask =
+ VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask);
+static VGLBitmap VGLMouseStdOrMask =
+ VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask);
+static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask;
+static byte map[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
+static VGLBitmap VGLMouseSave =
+ VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map);
+static int VGLMouseVisible = 0;
+static int VGLMouseFrozen = 0;
+static int VGLMouseShown = 0;
+static int VGLMouseXpos = 0;
+static int VGLMouseYpos = 0;
+static int VGLMouseButtons = 0;
+
+void
+VGLMousePointerShow()
+{
+ byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
+ VGLBitmap buffer =
+ VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf);
+ byte crtcidx, crtcval, gdcidx, gdcval;
+ int pos;
+
+ if (!VGLMouseVisible) {
+ VGLMouseVisible = 1;
+ crtcidx = inb(0x3c4);
+ crtcval = inb(0x3c5);
+ gdcidx = inb(0x3ce);
+ gdcval = inb(0x3cf);
+ __VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos,
+ &VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
+ bcopy(VGLMouseSave.Bitmap, buffer.Bitmap, MOUSE_IMG_SIZE*MOUSE_IMG_SIZE);
+ for (pos = 0; pos < MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++)
+ buffer.Bitmap[pos]=(buffer.Bitmap[pos]&~(VGLMouseAndMask->Bitmap[pos])) |
+ VGLMouseOrMask->Bitmap[pos];
+ __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay,
+ VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
+ outb(0x3c4, crtcidx);
+ outb(0x3c5, crtcval);
+ outb(0x3ce, gdcidx);
+ outb(0x3cf, gdcval);
+ }
+}
+
+void
+VGLMousePointerHide()
+{
+ byte crtcidx, crtcval, gdcidx, gdcval;
+
+ if (VGLMouseVisible) {
+ VGLMouseVisible = 0;
+ crtcidx = inb(0x3c4);
+ crtcval = inb(0x3c5);
+ gdcidx = inb(0x3ce);
+ gdcval = inb(0x3cf);
+ __VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay,
+ VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
+ outb(0x3c4, crtcidx);
+ outb(0x3c5, crtcval);
+ outb(0x3ce, gdcidx);
+ outb(0x3cf, gdcval);
+ }
+}
+
+void
+VGLMouseMode(int mode)
+{
+ if (mode == VGL_MOUSESHOW) {
+ if (VGLMouseShown == VGL_MOUSEHIDE) {
+ VGLMousePointerShow();
+ VGLMouseShown = VGL_MOUSESHOW;
+ }
+ }
+ else {
+ if (VGLMouseShown == VGL_MOUSESHOW) {
+ VGLMousePointerHide();
+ VGLMouseShown = VGL_MOUSEHIDE;
+ }
+ }
+}
+
+void
+VGLMouseAction(int dummy)
+{
+ struct mouse_info mouseinfo;
+
+ if (VGLMouseFrozen) {
+ VGLMouseFrozen++;
+ return;
+ }
+ mouseinfo.operation = MOUSE_GETINFO;
+ ioctl(0, CONS_MOUSECTL, &mouseinfo);
+ if (VGLMouseShown == VGL_MOUSESHOW)
+ VGLMousePointerHide();
+ VGLMouseXpos = mouseinfo.u.data.x;
+ VGLMouseYpos = mouseinfo.u.data.y;
+ VGLMouseButtons = mouseinfo.u.data.buttons;
+ if (VGLMouseShown == VGL_MOUSESHOW)
+ VGLMousePointerShow();
+}
+
+void
+VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask)
+{
+ if (VGLMouseShown == VGL_MOUSESHOW)
+ VGLMousePointerHide();
+ VGLMouseAndMask = AndMask;
+ VGLMouseOrMask = OrMask;
+ if (VGLMouseShown == VGL_MOUSESHOW)
+ VGLMousePointerShow();
+}
+
+void
+VGLMouseSetStdImage()
+{
+ if (VGLMouseShown == VGL_MOUSESHOW)
+ VGLMousePointerHide();
+ VGLMouseAndMask = &VGLMouseStdAndMask;
+ VGLMouseOrMask = &VGLMouseStdOrMask;
+ if (VGLMouseShown == VGL_MOUSESHOW)
+ VGLMousePointerShow();
+}
+
+int
+VGLMouseInit(int mode)
+{
+ struct mouse_info mouseinfo;
+ int error;
+
+ VGLMouseSetStdImage();
+ mouseinfo.operation = MOUSE_MODE;
+ mouseinfo.u.mode.signal = SIGUSR2;
+ if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo)))
+ return error;
+ signal(SIGUSR2, VGLMouseAction);
+ mouseinfo.operation = MOUSE_GETINFO;
+ ioctl(0, CONS_MOUSECTL, &mouseinfo);
+ VGLMouseXpos = mouseinfo.u.data.x;
+ VGLMouseYpos = mouseinfo.u.data.y;
+ VGLMouseButtons = mouseinfo.u.data.buttons;
+ VGLMouseMode(mode);
+ return 0;
+}
+
+int
+VGLMouseStatus(int *x, int *y, char *buttons)
+{
+ signal(SIGUSR2, SIG_IGN);
+ *x = VGLMouseXpos;
+ *y = VGLMouseYpos;
+ *buttons = VGLMouseButtons;
+ signal(SIGUSR2, VGLMouseAction);
+ return VGLMouseShown;
+}
+
+int
+VGLMouseFreeze(int x, int y, int width, int hight, byte color)
+{
+ if (!VGLMouseFrozen) {
+ VGLMouseFrozen = 1;
+ if (width > 1 || hight > 1) { /* bitmap */
+ if (VGLMouseShown == 1) {
+ int overlap;
+
+ if (x > VGLMouseXpos)
+ overlap = (VGLMouseXpos + MOUSE_IMG_SIZE) - x;
+ else
+ overlap = (x + width) - VGLMouseXpos;
+ if (overlap > 0) {
+ if (y > VGLMouseYpos)
+ overlap = (VGLMouseYpos + MOUSE_IMG_SIZE) - y;
+ else
+ overlap = (y + hight) - VGLMouseYpos;
+ if (overlap > 0)
+ VGLMousePointerHide();
+ }
+ }
+ }
+ else { /* bit */
+ if (VGLMouseShown &&
+ x >= VGLMouseXpos && x < VGLMouseXpos + MOUSE_IMG_SIZE &&
+ y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE) {
+ VGLMouseSave.Bitmap[(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)] =
+ (color);
+ if (VGLMouseAndMask->Bitmap
+ [(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) {
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+void
+VGLMouseUnFreeze()
+{
+ if (VGLMouseFrozen > 1) {
+ VGLMouseFrozen = 0;
+ VGLMouseAction(0);
+ }
+ else {
+ VGLMouseFrozen = 0;
+ if (VGLMouseShown == VGL_MOUSESHOW && !VGLMouseVisible)
+ VGLMousePointerShow();
+ }
+}
diff --git a/lib/libvgl/simple.c b/lib/libvgl/simple.c
new file mode 100644
index 0000000..0dfc237
--- /dev/null
+++ b/lib/libvgl/simple.c
@@ -0,0 +1,403 @@
+/*-
+ * Copyright (c) 1991-1997 Søren Schmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <signal.h>
+#include <machine/console.h>
+#include "vgl.h"
+
+static byte VGLSavePaletteRed[256];
+static byte VGLSavePaletteGreen[256];
+static byte VGLSavePaletteBlue[256];
+
+#define ABS(a) (((a)<0) ? -(a) : (a))
+#define SGN(a) (((a)<0) ? -1 : 1)
+#define min(x, y) (((x) < (y)) ? (x) : (y))
+#define max(x, y) (((x) > (y)) ? (x) : (y))
+
+void
+VGLSetXY(VGLBitmap *object, int x, int y, byte color)
+{
+ int offset;
+
+ VGLCheckSwitch();
+ if (x>=0 && x<object->VXsize && y>=0 && y<object->VYsize) {
+ if (!VGLMouseFreeze(x, y, 1, 1, color)) {
+ switch (object->Type) {
+ case MEMBUF:
+ case VIDBUF8:
+ object->Bitmap[y*object->VXsize+x]=(color);
+ break;
+ case VIDBUF8S:
+ object->Bitmap[VGLSetSegment(y*object->VXsize+x)]=(color);
+ break;
+ case VIDBUF8X:
+ outb(0x3c4, 0x02);
+ outb(0x3c5, 0x01 << (x&0x3));
+ object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)] = (color);
+ break;
+ case VIDBUF4S:
+ offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8);
+ goto set_planar;
+ case VIDBUF4:
+ offset = y*VGLAdpInfo.va_line_width + x/8;
+set_planar:
+ outb(0x3c4, 0x02); outb(0x3c5, 0x0f);
+ outb(0x3ce, 0x00); outb(0x3cf, color & 0x0f); /* set/reset */
+ outb(0x3ce, 0x01); outb(0x3cf, 0x0f); /* set/reset enable */
+ outb(0x3ce, 0x08); outb(0x3cf, 0x80 >> (x%8)); /* bit mask */
+ object->Bitmap[offset] |= color;
+ }
+ }
+ VGLMouseUnFreeze();
+ }
+}
+
+byte
+VGLGetXY(VGLBitmap *object, int x, int y)
+{
+ int offset;
+#if 0
+ int i;
+ byte color;
+ byte mask;
+#endif
+
+ VGLCheckSwitch();
+ if (x<0 || x>=object->VXsize || y<0 || y>=object->VYsize)
+ return 0;
+ switch (object->Type) {
+ case MEMBUF:
+ case VIDBUF8:
+ return object->Bitmap[((y*object->VXsize)+x)];
+ case VIDBUF8S:
+ return object->Bitmap[VGLSetSegment(y*object->VXsize+x)];
+ case VIDBUF8X:
+ outb(0x3ce, 0x04); outb(0x3cf, x & 0x3);
+ return object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)];
+ case VIDBUF4S:
+ offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8);
+ goto get_planar;
+ case VIDBUF4:
+ offset = y*VGLAdpInfo.va_line_width + x/8;
+get_planar:
+#if 1
+ return (object->Bitmap[offset]&(0x80>>(x%8))) ? 1 : 0; /* XXX */
+#else
+ color = 0;
+ mask = 0x80 >> (x%8);
+ for (i = 0; i < VGLModeInfo.vi_planes; i++) {
+ outb(0x3ce, 0x04); outb(0x3cf, i);
+ color |= (object->Bitmap[offset] & mask) ? (1 << i) : 0;
+ }
+ return color;
+#endif
+ }
+ return 0;
+}
+
+void
+VGLLine(VGLBitmap *object, int x1, int y1, int x2, int y2, byte color)
+{
+ int d, x, y, ax, ay, sx, sy, dx, dy;
+
+ dx = x2-x1; ax = ABS(dx)<<1; sx = SGN(dx); x = x1;
+ dy = y2-y1; ay = ABS(dy)<<1; sy = SGN(dy); y = y1;
+
+ if (ax>ay) { /* x dominant */
+ d = ay-(ax>>1);
+ for (;;) {
+ VGLSetXY(object, x, y, color);
+ if (x==x2)
+ break;
+ if (d>=0) {
+ y += sy; d -= ax;
+ }
+ x += sx; d += ay;
+ }
+ }
+ else { /* y dominant */
+ d = ax-(ay>>1);
+ for (;;) {
+ VGLSetXY(object, x, y, color);
+ if (y==y2)
+ break;
+ if (d>=0) {
+ x += sx; d -= ay;
+ }
+ y += sy; d += ax;
+ }
+ }
+}
+
+void
+VGLBox(VGLBitmap *object, int x1, int y1, int x2, int y2, byte color)
+{
+ VGLLine(object, x1, y1, x2, y1, color);
+ VGLLine(object, x2, y1, x2, y2, color);
+ VGLLine(object, x2, y2, x1, y2, color);
+ VGLLine(object, x1, y2, x1, y1, color);
+}
+
+void
+VGLFilledBox(VGLBitmap *object, int x1, int y1, int x2, int y2, byte color)
+{
+ int y;
+
+ for (y=y1; y<=y2; y++) VGLLine(object, x1, y, x2, y, color);
+}
+
+void
+inline set4pixels(VGLBitmap *object, int x, int y, int xc, int yc, byte color)
+{
+ if (x!=0) {
+ VGLSetXY(object, xc+x, yc+y, color);
+ VGLSetXY(object, xc-x, yc+y, color);
+ if (y!=0) {
+ VGLSetXY(object, xc+x, yc-y, color);
+ VGLSetXY(object, xc-x, yc-y, color);
+ }
+ }
+ else {
+ VGLSetXY(object, xc, yc+y, color);
+ if (y!=0)
+ VGLSetXY(object, xc, yc-y, color);
+ }
+}
+
+void
+VGLEllipse(VGLBitmap *object, int xc, int yc, int a, int b, byte color)
+{
+ int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b;
+ int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b;
+
+ while (dx<dy) {
+ set4pixels(object, x, y, xc, yc, color);
+ if (d>0) {
+ y--; dy-=asq2; d-=dy;
+ }
+ x++; dx+=bsq2; d+=bsq+dx;
+ }
+ d+=(3*(asq-bsq)/2-(dx+dy))/2;
+ while (y>=0) {
+ set4pixels(object, x, y, xc, yc, color);
+ if (d<0) {
+ x++; dx+=bsq2; d+=dx;
+ }
+ y--; dy-=asq2; d+=asq-dy;
+ }
+}
+
+void
+inline set2lines(VGLBitmap *object, int x, int y, int xc, int yc, byte color)
+{
+ if (x!=0) {
+ VGLLine(object, xc+x, yc+y, xc-x, yc+y, color);
+ if (y!=0)
+ VGLLine(object, xc+x, yc-y, xc-x, yc-y, color);
+ }
+ else {
+ VGLLine(object, xc, yc+y, xc, yc-y, color);
+ }
+}
+
+void
+VGLFilledEllipse(VGLBitmap *object, int xc, int yc, int a, int b, byte color)
+{
+ int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b;
+ int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b;
+
+ while (dx<dy) {
+ set2lines(object, x, y, xc, yc, color);
+ if (d>0) {
+ y--; dy-=asq2; d-=dy;
+ }
+ x++; dx+=bsq2; d+=bsq+dx;
+ }
+ d+=(3*(asq-bsq)/2-(dx+dy))/2;
+ while (y>=0) {
+ set2lines(object, x, y, xc, yc, color);
+ if (d<0) {
+ x++; dx+=bsq2; d+=dx;
+ }
+ y--; dy-=asq2; d+=asq-dy;
+ }
+}
+
+void
+VGLClear(VGLBitmap *object, byte color)
+{
+ int offset;
+ int len;
+
+ VGLCheckSwitch();
+ VGLMouseFreeze(0, 0, object->Xsize, object->Ysize, color);
+ switch (object->Type) {
+ case MEMBUF:
+ case VIDBUF8:
+ memset(object->Bitmap, color, object->VXsize*object->VYsize);
+ break;
+
+ case VIDBUF8S:
+ for (offset = 0; offset < object->VXsize*object->VYsize; ) {
+ VGLSetSegment(offset);
+ len = min(object->VXsize*object->VYsize - offset,
+ VGLAdpInfo.va_window_size);
+ memset(object->Bitmap, color, len);
+ offset += len;
+ }
+ break;
+
+ case VIDBUF8X:
+ /* XXX works only for Xsize % 4 = 0 */
+ outb(0x3c6, 0xff);
+ outb(0x3c4, 0x02); outb(0x3c5, 0x0f);
+ memset(object->Bitmap, color, VGLAdpInfo.va_line_width*object->VYsize);
+ break;
+
+ case VIDBUF4:
+ case VIDBUF4S:
+ /* XXX works only for Xsize % 8 = 0 */
+ outb(0x3c4, 0x02); outb(0x3c5, 0x0f);
+ outb(0x3ce, 0x05); outb(0x3cf, 0x02); /* mode 2 */
+ outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */
+ outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */
+ for (offset = 0; offset < VGLAdpInfo.va_line_width*object->VYsize; ) {
+ VGLSetSegment(offset);
+ len = min(object->VXsize*object->VYsize - offset,
+ VGLAdpInfo.va_window_size);
+ memset(object->Bitmap, color, len);
+ offset += len;
+ }
+ outb(0x3ce, 0x05); outb(0x3cf, 0x00);
+ break;
+ }
+ VGLMouseUnFreeze();
+}
+
+void
+VGLRestorePalette()
+{
+ int i;
+
+ outb(0x3C6, 0xFF);
+ inb(0x3DA);
+ outb(0x3C8, 0x00);
+ for (i=0; i<256; i++) {
+ outb(0x3C9, VGLSavePaletteRed[i]);
+ inb(0x84);
+ outb(0x3C9, VGLSavePaletteGreen[i]);
+ inb(0x84);
+ outb(0x3C9, VGLSavePaletteBlue[i]);
+ inb(0x84);
+ }
+ inb(0x3DA);
+ outb(0x3C0, 0x20);
+}
+
+void
+VGLSavePalette()
+{
+ int i;
+
+ outb(0x3C6, 0xFF);
+ inb(0x3DA);
+ outb(0x3C7, 0x00);
+ for (i=0; i<256; i++) {
+ VGLSavePaletteRed[i] = inb(0x3C9);
+ inb(0x84);
+ VGLSavePaletteGreen[i] = inb(0x3C9);
+ inb(0x84);
+ VGLSavePaletteBlue[i] = inb(0x3C9);
+ inb(0x84);
+ }
+ inb(0x3DA);
+ outb(0x3C0, 0x20);
+}
+
+void
+VGLSetPalette(byte *red, byte *green, byte *blue)
+{
+ int i;
+
+ for (i=0; i<256; i++) {
+ VGLSavePaletteRed[i] = red[i];
+ VGLSavePaletteGreen[i] = green[i];
+ VGLSavePaletteBlue[i] = blue[i];
+ }
+ VGLCheckSwitch();
+ outb(0x3C6, 0xFF);
+ inb(0x3DA);
+ outb(0x3C8, 0x00);
+ for (i=0; i<256; i++) {
+ outb(0x3C9, VGLSavePaletteRed[i]);
+ inb(0x84);
+ outb(0x3C9, VGLSavePaletteGreen[i]);
+ inb(0x84);
+ outb(0x3C9, VGLSavePaletteBlue[i]);
+ inb(0x84);
+ }
+ inb(0x3DA);
+ outb(0x3C0, 0x20);
+}
+
+void
+VGLSetPaletteIndex(byte color, byte red, byte green, byte blue)
+{
+ VGLSavePaletteRed[color] = red;
+ VGLSavePaletteGreen[color] = green;
+ VGLSavePaletteBlue[color] = blue;
+ VGLCheckSwitch();
+ outb(0x3C6, 0xFF);
+ inb(0x3DA);
+ outb(0x3C8, color);
+ outb(0x3C9, red); outb(0x3C9, green); outb(0x3C9, blue);
+ inb(0x3DA);
+ outb(0x3C0, 0x20);
+}
+
+void
+VGLSetBorder(byte color)
+{
+ VGLCheckSwitch();
+ inb(0x3DA);
+ outb(0x3C0,0x11); outb(0x3C0, color);
+ inb(0x3DA);
+ outb(0x3C0, 0x20);
+}
+
+void
+VGLBlankDisplay(int blank)
+{
+ byte val;
+
+ VGLCheckSwitch();
+ outb(0x3C4, 0x01); val = inb(0x3C5); outb(0x3C4, 0x01);
+ outb(0x3C5, ((blank) ? (val |= 0x20) : (val &= 0xDF)));
+}
diff --git a/lib/libvgl/text.c b/lib/libvgl/text.c
new file mode 100644
index 0000000..09b0964
--- /dev/null
+++ b/lib/libvgl/text.c
@@ -0,0 +1,244 @@
+/*-
+ * Copyright (c) 1991-1997 Søren Schmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <machine/console.h>
+#include "vgl.h"
+
+static VGLText *VGLTextFont = 0;
+
+extern byte VGLFont[];
+
+int
+VGLTextSetFontFile(char *filename)
+{
+FILE *fd;
+
+ if (VGLTextFont) {
+ if (VGLTextFont->BitmapArray)
+ free (VGLTextFont->BitmapArray);
+ free(VGLTextFont);
+ }
+
+ if ((VGLTextFont=(VGLText*)malloc(sizeof(VGLText))) == (VGLText*)0)
+ return 1;
+
+ if (filename==NULL) {
+ VGLTextFont->Width = 8;
+ VGLTextFont->Height = 8;
+ VGLTextFont->BitmapArray = VGLFont;
+ }
+ else {
+ if ((fd=fopen(filename, "r"))==(FILE*)0)
+ return 1;
+ fread(&VGLTextFont->Width, 1 , 1, fd);
+ fread(&VGLTextFont->Height, 1 , 1, fd);
+ VGLTextFont->BitmapArray =
+ (byte*)malloc(256*((VGLTextFont->Width + 7)/8)*VGLTextFont->Height);
+ fread(VGLTextFont->BitmapArray, 1,
+ (256*VGLTextFont->Width* VGLTextFont->Height), fd);
+ fclose(fd);
+ }
+ return 0;
+}
+
+void
+VGLBitmapPutChar(VGLBitmap *Object, int x, int y, byte ch,
+ byte fgcol, byte bgcol, int fill, int dir)
+{
+ int lin, bit;
+
+ for(lin = 0; lin < VGLTextFont->Height; lin++) {
+ for(bit = 0; bit < VGLTextFont->Width; bit++) {
+ if (VGLTextFont->BitmapArray[((ch*VGLTextFont->Height)+lin)]&(1<<bit))
+ switch (dir) {
+ case 0:
+ VGLSetXY(Object, (x+7-bit), (y+lin), fgcol);
+ break;
+ case 1:
+ VGLSetXY(Object, (x+lin), (y-7+bit), fgcol);
+ break;
+ case 2:
+ VGLSetXY(Object, (x-7+bit), (y-lin), fgcol);
+ break;
+ case 3:
+ VGLSetXY(Object, (x-lin), (y+7-bit), fgcol);
+ break;
+ case 4:
+ VGLSetXY(Object, (x+lin+7-bit), (y+lin+bit), fgcol);
+ break;
+ }
+ else if (fill)
+ switch (dir) {
+ case 0:
+ VGLSetXY(Object, (x+7-bit), (y+lin), bgcol);
+ break;
+ case 1:
+ VGLSetXY(Object, (x+lin), (y-7+bit), bgcol);
+ break;
+ case 2:
+ VGLSetXY(Object, (x-7+bit), (y-lin), bgcol);
+ break;
+ case 3:
+ VGLSetXY(Object, (x-lin), (y+7-bit), bgcol);
+ break;
+ case 4:
+ VGLSetXY(Object, (x+lin+7-bit), (y+lin+bit), bgcol);
+ break;
+ }
+ }
+ }
+}
+
+void
+VGLBitmapString(VGLBitmap *Object, int x, int y, char *str,
+ byte fgcol, byte bgcol, int fill, int dir)
+{
+ int pos;
+
+ for (pos=0; pos<strlen(str); pos++) {
+ switch (dir) {
+ case 0:
+ VGLBitmapPutChar(Object, x+(pos*VGLTextFont->Width), y,
+ str[pos], fgcol, bgcol, fill, dir);
+ break;
+ case 1:
+ VGLBitmapPutChar(Object, x, y-(pos*VGLTextFont->Width),
+ str[pos], fgcol, bgcol, fill, dir);
+ break;
+ case 2:
+ VGLBitmapPutChar(Object, x-(pos*VGLTextFont->Width), y,
+ str[pos], fgcol, bgcol, fill, dir);
+ break;
+ case 3:
+ VGLBitmapPutChar(Object, x, y+(pos*VGLTextFont->Width),
+ str[pos], fgcol, bgcol, fill, dir);
+ break;
+ case 4:
+ VGLBitmapPutChar(Object, x+(pos*VGLTextFont->Width),
+ y-(pos*VGLTextFont->Width),
+ str[pos], fgcol, bgcol, fill, dir);
+ break;
+ }
+ }
+}
+
+byte VGLFont[] = {
+0,0,0,0,0,0,0,0,126,129,165,129,189,153,129,126,126,255,219,255,195,231,
+255,126,108,254,254,254,124,56,16,0,16,56,124,254,124,56,16,0,56,124,56,
+254,254,124,56,124,16,16,56,124,254,124,56,124,0,0,24,60,60,24,0,0,255,
+255,231,195,195,231,255,255,0,60,102,66,66,102,60,0,255,195,153,189,189,
+153,195,255,15,7,15,125,204,204,204,120,60,102,102,102,60,24,126,24,63,
+51,63,48,48,112,240,224,127,99,127,99,99,103,230,192,153,90,60,231,231,
+60,90,153,128,224,248,254,248,224,128,0,2,14,62,254,62,14,2,0,24,60,126,
+24,24,126,60,24,102,102,102,102,102,0,102,0,127,219,219,123,27,27,27,0,
+62,99,56,108,108,56,204,120,0,0,0,0,126,126,126,0,24,60,126,24,126,60,24,
+255,24,60,126,24,24,24,24,0,24,24,24,24,126,60,24,0,0,24,12,254,12,24,0,
+0,0,48,96,254,96,48,0,0,0,0,192,192,192,254,0,0,0,36,102,255,102,36,0,0,
+0,24,60,126,255,255,0,0,0,255,255,126,60,24,0,0,0,0,0,0,0,0,0,0,48,120,
+120,48,48,0,48,0,108,108,108,0,0,0,0,0,108,108,254,108,254,108,108,0,48,
+124,192,120,12,248,48,0,0,198,204,24,48,102,198,0,56,108,56,118,220,204,
+118,0,96,96,192,0,0,0,0,0,24,48,96,96,96,48,24,0,96,48,24,24,24,48,96,0,
+0,102,60,255,60,102,0,0,0,48,48,252,48,48,0,0,0,0,0,0,0,48,48,96,0,0,0,
+252,0,0,0,0,0,0,0,0,0,48,48,0,6,12,24,48,96,192,128,0,124,198,206,222,246,
+230,124,0,48,112,48,48,48,48,252,0,120,204,12,56,96,204,252,0,120,204,12,
+56,12,204,120,0,28,60,108,204,254,12,30,0,252,192,248,12,12,204,120,0,56,
+96,192,248,204,204,120,0,252,204,12,24,48,48,48,0,120,204,204,120,204,204,
+120,0,120,204,204,124,12,24,112,0,0,48,48,0,0,48,48,0,0,48,48,0,0,48,48,
+96,24,48,96,192,96,48,24,0,0,0,252,0,0,252,0,0,96,48,24,12,24,48,96,0,120,
+204,12,24,48,0,48,0,124,198,222,222,222,192,120,0,48,120,204,204,252,204,
+204,0,252,102,102,124,102,102,252,0,60,102,192,192,192,102,60,0,248,108,
+102,102,102,108,248,0,254,98,104,120,104,98,254,0,254,98,104,120,104,96,
+240,0,60,102,192,192,206,102,62,0,204,204,204,252,204,204,204,0,120,48,
+48,48,48,48,120,0,30,12,12,12,204,204,120,0,230,102,108,120,108,102,230,
+0,240,96,96,96,98,102,254,0,198,238,254,254,214,198,198,0,198,230,246,222,
+206,198,198,0,56,108,198,198,198,108,56,0,252,102,102,124,96,96,240,0,120,
+204,204,204,220,120,28,0,252,102,102,124,108,102,230,0,120,204,224,112,
+28,204,120,0,252,180,48,48,48,48,120,0,204,204,204,204,204,204,252,0,204,
+204,204,204,204,120,48,0,198,198,198,214,254,238,198,0,198,198,108,56,56,
+108,198,0,204,204,204,120,48,48,120,0,254,198,140,24,50,102,254,0,120,96,
+96,96,96,96,120,0,192,96,48,24,12,6,2,0,120,24,24,24,24,24,120,0,16,56,
+108,198,0,0,0,0,0,0,0,0,0,0,0,255,48,48,24,0,0,0,0,0,0,0,120,12,124,204,
+118,0,224,96,96,124,102,102,220,0,0,0,120,204,192,204,120,0,28,12,12,124,
+204,204,118,0,0,0,120,204,252,192,120,0,56,108,96,240,96,96,240,0,0,0,118,
+204,204,124,12,248,224,96,108,118,102,102,230,0,48,0,112,48,48,48,120,0,
+12,0,12,12,12,204,204,120,224,96,102,108,120,108,230,0,112,48,48,48,48,
+48,120,0,0,0,204,254,254,214,198,0,0,0,248,204,204,204,204,0,0,0,120,204,
+204,204,120,0,0,0,220,102,102,124,96,240,0,0,118,204,204,124,12,30,0,0,
+220,118,102,96,240,0,0,0,124,192,120,12,248,0,16,48,124,48,48,52,24,0,0,
+0,204,204,204,204,118,0,0,0,204,204,204,120,48,0,0,0,198,214,254,254,108,
+0,0,0,198,108,56,108,198,0,0,0,204,204,204,124,12,248,0,0,252,152,48,100,
+252,0,28,48,48,224,48,48,28,0,24,24,24,0,24,24,24,0,224,48,48,28,48,48,
+224,0,118,220,0,0,0,0,0,0,0,16,56,108,198,198,254,0,0,0,0,0,0,0,0,0,0,0,
+60,126,255,126,24,0,170,85,85,170,170,85,85,170,68,68,68,68,31,4,4,4,124,
+64,64,64,31,16,16,16,56,68,68,56,30,17,20,19,64,64,64,124,31,16,16,16,56,
+108,56,0,0,0,0,0,0,0,24,24,24,24,126,0,68,100,76,68,16,16,16,31,68,68,40,
+16,31,4,4,4,24,24,24,24,248,0,0,0,0,0,0,0,248,24,24,24,0,0,0,0,31,24,24,
+24,24,24,24,24,31,0,0,0,24,24,24,24,255,24,24,24,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,24,24,24,
+24,31,24,24,24,24,24,24,24,248,24,24,24,24,24,24,24,255,0,0,0,0,0,0,0,255,
+24,24,24,24,24,24,24,24,24,24,24,0,12,48,96,24,12,126,0,0,48,12,6,24,48,
+126,0,0,0,3,62,54,54,108,0,0,0,4,126,16,126,64,0,0,28,48,48,48,48,126,0,
+0,0,0,24,0,0,0,0,0,0,0,0,0,0,0,0,48,0,48,48,120,120,48,0,0,0,16,124,192,
+192,124,16,0,56,96,96,240,96,252,0,0,195,60,102,102,60,195,0,0,204,204,
+120,48,252,48,0,24,24,24,0,24,24,24,0,126,192,124,198,124,6,252,0,198,0,
+0,0,0,0,0,0,124,130,186,162,186,130,124,0,28,6,30,34,31,63,0,0,0,51,102,
+204,102,51,0,0,0,254,6,0,0,0,0,0,0,0,0,0,0,0,0,0,124,130,186,178,170,130,
+124,0,254,0,0,0,0,0,0,0,56,108,56,0,0,0,0,0,0,16,124,16,0,124,0,0,28,54,
+6,24,62,0,0,0,30,2,14,2,30,0,0,0,24,48,0,0,0,0,0,0,0,0,204,204,204,204,
+118,192,126,202,202,126,10,10,10,0,0,0,0,24,0,0,0,0,0,0,0,0,0,0,24,48,6,
+14,6,6,6,0,0,0,14,17,17,17,14,31,0,0,0,204,102,51,102,204,0,0,96,224,102,
+108,51,103,15,3,96,224,102,108,54,106,4,14,240,32,150,108,51,103,15,3,48,
+0,48,96,192,204,120,0,24,12,48,120,204,252,204,0,96,192,48,120,204,252,
+204,0,120,132,48,120,204,252,204,0,102,152,48,120,204,252,204,0,204,0,48,
+120,204,252,204,0,48,72,48,120,204,252,204,0,62,120,152,156,248,152,158,
+0,60,102,192,192,192,102,28,48,48,24,254,98,120,98,254,0,24,48,254,98,120,
+98,254,0,56,68,254,98,120,98,254,0,102,0,254,98,120,98,254,0,96,48,120,
+48,48,48,120,0,24,48,120,48,48,48,120,0,120,132,120,48,48,48,120,0,204,
+0,120,48,48,48,120,0,120,108,102,246,102,108,120,0,102,152,230,246,222,
+206,198,0,48,24,124,198,198,198,124,0,24,48,124,198,198,198,124,0,56,68,
+124,198,198,198,124,0,102,152,124,198,198,198,124,0,198,0,124,198,198,198,
+124,0,0,198,108,56,56,108,198,0,6,124,206,154,178,230,120,192,96,48,204,
+204,204,204,252,0,24,48,204,204,204,204,252,0,120,132,204,204,204,204,252,
+0,204,0,204,204,204,204,252,0,24,48,204,204,120,48,120,0,96,120,108,120,
+96,96,96,0,120,204,196,220,198,198,220,192,48,24,120,12,124,204,118,0,24,
+48,120,12,124,204,118,0,120,132,120,12,124,204,118,0,102,152,120,12,124,
+204,118,0,204,0,120,12,124,204,118,0,48,72,56,12,124,204,118,0,0,0,236,
+50,126,176,110,0,0,0,60,102,192,102,28,48,48,24,120,204,252,192,120,0,24,
+48,120,204,252,192,120,0,120,132,120,204,252,192,120,0,204,0,120,204,252,
+192,120,0,96,48,0,112,48,48,120,0,24,48,0,112,48,48,120,0,112,136,0,112,
+48,48,120,0,204,0,0,112,48,48,120,0,108,56,108,12,108,204,120,0,102,152,
+248,204,204,204,204,0,96,48,0,124,198,198,124,0,24,48,0,124,198,198,124,
+0,56,68,0,124,198,198,124,0,102,152,0,124,198,198,124,0,198,0,0,124,198,
+198,124,0,0,0,24,0,126,0,24,0,0,0,6,124,222,246,124,192,96,48,0,204,204,
+204,118,0,24,48,0,204,204,204,118,0,48,72,0,204,204,204,118,0,204,0,0,204,
+204,204,118,0,24,48,204,204,204,124,12,248,224,120,108,102,108,120,224,
+0,204,0,204,204,204,124,12,248
+};
diff --git a/lib/libvgl/vgl.3 b/lib/libvgl/vgl.3
new file mode 100644
index 0000000..adc349b
--- /dev/null
+++ b/lib/libvgl/vgl.3
@@ -0,0 +1,405 @@
+.\" Copyright (c) 1997 Søren Schmidt
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer,
+.\" in this position and unchanged.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\" derived from this software withough specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.Dd November 7, 1999
+.Dt VGL 3
+.Os FreeBSD 3.0
+.Sh NAME
+.Nm VGLBitmapAllocateBits ,
+.Nm VGLBitmapCopy ,
+.Nm VGLBitmapCreate ,
+.Nm VGLBitmapDestroy ,
+.Nm VGLBitmapPutChar ,
+.Nm VGLBitmapString ,
+.Nm VGLBlankDisplay ,
+.Nm VGLBox ,
+.Nm VGLCheckSwitch ,
+.Nm VGLClear ,
+.Nm VGLEllipse ,
+.Nm VGLEnd ,
+.Nm VGLFilledBox ,
+.Nm VGLFilledEllipse ,
+.Nm VGLGetXY ,
+.Nm VGLInit ,
+.Nm VGLLine ,
+.Nm VGLKeyboardInit ,
+.Nm VGLKeyboardEnd ,
+.Nm VGLKeyboardGetCh ,
+.Nm VGLMouseInit ,
+.Nm VGLMouseMode ,
+.Nm VGLMouseSetImage ,
+.Nm VGLMouseSetStdImage ,
+.Nm VGLMouseStatus ,
+.Nm VGLPanScreen ,
+.Nm VGLSetBorder ,
+.Nm VGLSetPalette ,
+.Nm VGLSetPaletteIndex ,
+.Nm VGLSetVScreenSize ,
+.Nm VGLSetXY ,
+.Nm VGLTextSetFontFile
+.Nd Video Graphics Library functions (libvgl)
+.Sh SYNOPSIS
+.Fd #include <vgl.h>
+.Ft int
+.Fn VGLInit "int mode"
+.Ft void
+.Fn VGLEnd "void"
+.Ft void
+.Fn VGLCheckSwitch "void"
+.Ft int
+.Fn VGLTextSetFontFile "char *filename"
+.Ft int
+.Fn VGLKeyboardInit "int code"
+.Ft void
+.Fn VGLKeyboardEnd "void"
+.Ft int
+.Fn VGLKeyboardGetCh "void"
+.Ft int
+.Fn VGLMouseInit "int mode"
+.Ft void
+.Fn VGLMouseMode "int mode"
+.Ft int
+.Fn VGLMouseStatus "int *x" "int *y" "char *buttons"
+.Ft void
+.Fn VGLMouseSetImage "VGLBitmap *AndMask" "VGLBitmap *OrMask"
+.Ft void
+.Fn VGLMouseSetStdImage "void"
+.Ft byte
+.Fn VGLGetXY "VGLBitmap *object" "int x" "int y"
+.Ft void
+.Fn VGLSetXY "VGLBitmap *object" "int x" "int y" "byte color"
+.Ft void
+.Fn VGLLine "VGLBitmap *object" "int x1" "int y1" "int x2" "int y2" "byte color"
+.Ft void
+.Fn VGLBox "VGLBitmap *object" "int x1" "int y1" "int x2" "int y2" "byte color"
+.Ft void
+.Fn VGLFilledBox "VGLBitmap *object" "int x1" "int y1" "int x2" "int y2" "byte color"
+.Ft void
+.Fn VGLEllipse "VGLBitmap *object" "int xc" "int yc" "int a" "int b" "byte color"
+.Ft void
+.Fn VGLFilledEllipse "VGLBitmap *object" "int xc" "int yc" "int a" "int b" "byte color"
+.Ft VGLBitmap *
+.Fn VGLBitmapCreate "int type" "int xsize" "int ysize" "byte *bits"
+.Ft void
+.Fn VGLBitmapDestroy "VGLBitmap *object"
+.Ft int
+.Fn VGLBitmapAllocateBits "VGLBitmap *object"
+.Ft int
+.Fn VGLBitmapCopy "VGLBitmap *src" "int srcx" "int srcy" "VGLBitmap *dst" "int dstx" "int dsty" "int width" "int hight"
+.Ft void
+.Fn VGLBitmapPutChar "VGLBitmap *Object" "int x" "int y" "byte ch" "byte fgcol" "byte bgcol" "int fill" "int dir"
+.Ft void
+.Fn VGLBitmapString "VGLBitmap *Object" "int x" "int y" "char *str" "byte fgcol" "byte bgcol" "int fill" "int dir"
+.Ft void
+.Fn VGLClear "VGLBitmap *object" "byte color"
+.Ft void
+.Fn VGLSetPalette "byte *red" "byte *green" "byte *blue"
+.Ft void
+.Fn VGLSetPaletteIndex "byte color" "byte red" "byte green" "byte blue"
+.Ft void
+.Fn VGLSetBorder "byte color"
+.Ft int
+.Fn VGLSetVScreenSize "VGLBitmap *object" "int vxsize" "int vysize"
+.Ft int
+.Fn VGLPanSreen "VGLBitmap *object" "int x" "int y"
+.Ft void
+.Fn VGLBlankDisplay "int blank"
+.Sh DESCRIPTION
+.Nm Libvgl
+is a library that enables the programmer access to the graphics
+modes supported by the console driver (syscons). The library takes care of
+programming the actual video hardware, and provides a number of simple
+functions to do various graphic operations. There is also support for a
+mouse via the standard mouse system in
+.Fx ,
+see
+.Xr mouse 4 ,
+including the ability to transparently have a mouse pointer superimposed on
+the graphic image currently being worked on.
+The library takes care of screen switching by storing the current image in
+memory before switching to another virtual console, and restoring when the
+user switches back. This allows several graphic applications at once, but
+on different virtual consoles.
+
+Below is a short description of the various functions:
+.Pp
+.Fn VGLInit
+initialize the library and set up the graphic mode
+.Em mode .
+.Pp
+.Fn VGLEnd
+terminate graphic mode, and restore the screenmode that was active before
+.Fn VGLInit
+was called.
+.Pp
+.Fn VGLCheckSwitch
+if the program goes into longer periods of processing without doing
+any graphics output, calling this function occasionally will allow
+the system to switch screens.
+.Pp
+.Fn VGLTextSetFontFile
+instruct the char/string functions to use the font in file
+.Em filename
+instead of the builtin font.
+.Pp
+.Fn VGLKeyboardInit
+set up the keyboard in the ``raw'' I/O mode and
+specify the key code to be used.
+.Em code
+must be
+.Em VGL_XLATEKEYS ,
+.Em VGL_CODEKEYS ,
+or
+.Em VGL_RAWKEYS .
+When
+.Em VGL_XLATEKEYS
+is specified, the keyboard translate the raw keyboard scan code into
+a character code.
+If
+.Em VGL_RAWKEYS
+is used, the raw keyboard scan code is read as is.
+.Em VGL_CODEKEYS
+is the intermediate key code; each key is assigned a unique code whereas
+more than one raw scan code may be generated when a key is pressed.
+.Pp
+.Fn VGLKeyboardEnd
+when you have finished using the keyboard, call this function.
+.Pp
+.Fn VGLKeyboardGetCh
+read one byte from the keyboard. As the keyboard I/O is in the ``raw''
+input mode, the function will not block even if there is no input data,
+and returns 0.
+.Pp
+.Fn VGLMouseInit
+initialize the mouse. The optional on-screen mouse pointer is shown if the
+argument is
+.Em VGL_MOUSESHOW .
+.Pp
+.Fn VGLMouseMode
+either shows the mouse pointer if the argument is
+.Em VGL_MOUSESHOW ,
+or hides the mouse pointer if the argument is
+.Em VGL_MOUSEHIDE .
+.Pp
+.Fn VGLMouseStatus
+returns the current mouse pointer coordinates and button state in
+.Em x , y ,
+buttons. The return value reflects if the mouse pointer
+is currently shown on screen or not.
+.Pp
+.Fn VGLMouseSetImage
+with this function it is possible to change the image of the mouse pointer
+on screen.
+.Pp
+.Fn VGLMouseSetStdImage
+this function restores the mouse pointer to the standard arrow.
+.Pp
+.Fn VGLGetXY
+retrieves the color of the pixel located at
+.Em x , y ,
+coordinates of the
+.Em object
+argument, and returns it as a byte value.
+.Pp
+.Fn VGLSetXY
+sets the color of the pixel located at
+.Em x , y ,
+coordinates of the
+.Em object
+argument to
+.Em color
+byte value.
+.Pp
+.Fn VGLLine
+draw a line from
+.Em x1 , y1
+to
+.Em x2 , y2
+in color
+.Em color .
+.Pp
+.Fn VGLBox
+draw a box with upper left hand corner at
+.Em x1 , y1
+and lower right hand corner at
+.Em x2 , y2
+in color
+.Em color .
+.Pp
+.Fn VGLFilledBox
+draw a filled (solid) box with upper left hand corner at
+.Em x1 , y1
+and lower right hand corner at
+.Em x2 , y2
+in color
+.Em color .
+.Pp
+.Fn VGLEllipse
+draw an ellipse centered at
+.Em xc , yc
+make it
+.Em a
+pixels wide, and
+.Em b
+pixels high in color
+.Em color .
+.Pp
+.Fn VGLFilledEllipse
+draw a filled (solid) ellipse centered at
+.Em xc , yc
+make it
+.Em a
+pixels wide, and
+.Em b
+pixels high in color
+.Em color .
+.Pp
+.Fn VGLBitmapCreate
+create a bitmap object and initialize it with the specified
+values and bit data.
+.Em type
+must be
+.Em MEMBUF
+for the in-memory bitmap.
+.Em bits
+may be NULL so that bitmap data may be associated later.
+.Pp
+There also is a macro,
+.Fn VGLBITMAP_INITIALIZER "type" "xsize" "ysize" "bits"
+to initialize a statically declared bitmap object.
+.Pp
+.Fn VGLBitmapDestroy
+free the bitmap data and the bitmap object.
+.Pp
+.Fn VGLBitmapAllocateBits
+allocate a bit data buffer for the specified object.
+.Pp
+.Fn VGLBitmapCopy
+copy a rectangle of pixels from bitmap
+.Em src
+upper left hand corner at
+.Em srcx , srcy
+to bitmap
+.Em dst
+at
+.Em dstx , dsty
+of the size
+.Em width , height .
+.Pp
+.Fn VGLBitmapPutChar
+write the character
+.Em ch
+at position
+.Em x , y
+in foreground color
+.Em fgcol .
+If
+.Em fill
+is != 0, use the color
+.Em bgcol
+as background otherwise the background is transparent.
+The character is drawn in the direction specified by the argument
+.Em dir .
+.Pp
+.Fn VGLBitmapString
+write the string
+.Em str
+at position
+.Em x , y
+in foreground color
+.Em fgcol .
+If
+.Em fill
+is != 0, use the color
+.Em bgcol
+as background otherwise the background is transparent.
+The string is drawn in the direction specified by the argument
+.Em dir .
+.Pp
+.Fn VGLClear
+clears the entire bitmap to color
+.Em color .
+.Pp
+.Fn VGLSetPalette
+this function sets the palette used, the arguments
+.Em red , green , blue
+should point to byte arrays of 256 positions each.
+.Pp
+.Fn VGLSetPaletteIndex
+set the palette index
+.Em color
+to the specified RGB value.
+.Pp
+.Fn VGLSetBorder
+set the border color to color
+.Em color .
+.Pp
+.Fn VGLSetVScreenSize
+change the virtual screen size of the display. Note that this
+function must be called when our vty is in the foreground.
+And
+.Em object
+must be
+.Em VGLDisplay .
+Passing a in-memory bitmap to this function results in error.
+.Pp
+The desired virtual screen width may not be achievable because
+of the video card hardware. In such case the video driver (and
+underlaying video BIOS) may choose the next largest values.
+Always examine
+.Em object->VXsize
+and
+.Em VYsize
+after calling this function, in order to see how the virtual screen
+is actually set up.
+.Pp
+In order to set up the largest possible virtual screen, you may
+call this function with arbitrary large values.
+.Pp
+.Dl VGLSetVScreenSize(10000, 10000);
+.Pp
+.Fn VGLPanSreen
+change the origin of the displayed screen in the virtual screen.
+Note that this function must be called when our vty is in the
+foreground.
+.Em object
+must be
+.Em VGLDisplay .
+Passing a in-memory bitmap to this function results in error.
+.Pp
+.Fn VGLBlankDisplay
+blank the display if the argment
+.Em blank
+!= 0. This can be done to shut off the screen during display updates that
+the user should first see when it's done.
+.Sh AUTHORS
+.An Søren Schmidt Aq sos@FreeBSD.org
+.Sh HISTORY
+The
+.Nm vgl
+library appeared in
+.Fx 3.0 .
diff --git a/lib/libvgl/vgl.h b/lib/libvgl/vgl.h
new file mode 100644
index 0000000..54c58bf
--- /dev/null
+++ b/lib/libvgl/vgl.h
@@ -0,0 +1,142 @@
+/*-
+ * Copyright (c) 1991-1997 Søren Schmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <machine/cpufunc.h>
+
+typedef unsigned char byte;
+typedef struct {
+ byte Type;
+ int Xsize, Ysize;
+ int VXsize, VYsize;
+ int Xorigin, Yorigin;
+ byte *Bitmap;
+} VGLBitmap;
+
+#define VGLBITMAP_INITIALIZER(t, x, y, bits) \
+ { (t), (x), (y), (x), (y), 0, 0, (bits) }
+
+/*
+ * Defined Type's
+ */
+#define MEMBUF 0
+#define VIDBUF4 1
+#define VIDBUF8 2
+#define VIDBUF8X 3
+#define VIDBUF8S 4
+#define VIDBUF4S 5
+#define NOBUF 255
+
+typedef struct VGLText {
+ byte Width, Height;
+ byte *BitmapArray;
+} VGLText;
+
+typedef struct VGLObject {
+ int Id;
+ int Type;
+ int Status;
+ int Xpos, Ypos;
+ int Xhot, Yhot;
+ VGLBitmap *Image;
+ VGLBitmap *Mask;
+ int (*CallBackFunction)();
+} VGLObject;
+
+#define MOUSE_IMG_SIZE 16
+#define VGL_MOUSEHIDE 0
+#define VGL_MOUSESHOW 1
+#define VGL_MOUSEFREEZE 0
+#define VGL_MOUSEUNFREEZE 1
+#define VGL_DIR_RIGHT 0
+#define VGL_DIR_UP 1
+#define VGL_DIR_LEFT 2
+#define VGL_DIR_DOWN 3
+#define VGL_RAWKEYS 1
+#define VGL_CODEKEYS 2
+#define VGL_XLATEKEYS 3
+
+extern video_adapter_info_t VGLAdpInfo;
+extern video_info_t VGLModeInfo;
+extern VGLBitmap *VGLDisplay;
+extern byte *VGLBuf;
+
+/*
+ * Prototypes
+ */
+/* bitmap.c */
+int __VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy, VGLBitmap *dst, int dstx, int dsty, int width, int hight);
+int VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy, VGLBitmap *dst, int dstx, int dsty, int width, int hight);
+VGLBitmap *VGLBitmapCreate(int type, int xsize, int ysize, byte *bits);
+void VGLBitmapDestroy(VGLBitmap *object);
+int VGLBitmapAllocateBits(VGLBitmap *object);
+/* keyboard.c */
+int VGLKeyboardInit(int mode);
+void VGLKeyboardEnd(void);
+int VGLKeyboardGetCh(void);
+/* main.c */
+void VGLEnd(void);
+int VGLInit(int mode);
+void VGLCheckSwitch(void);
+int VGLSetVScreenSize(VGLBitmap *object, int VXsize, int VYsize);
+int VGLPanScreen(VGLBitmap *object, int x, int y);
+int VGLSetSegment(unsigned int offset);
+/* mouse.c */
+void VGLMousePointerShow(void);
+void VGLMousePointerHide(void);
+void VGLMouseMode(int mode);
+void VGLMouseAction(int dummy);
+void VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask);
+void VGLMouseSetStdImage(void);
+int VGLMouseInit(int mode);
+int VGLMouseStatus(int *x, int *y, char *buttons);
+int VGLMouseFreeze(int x, int y, int width, int hight, byte color);
+void VGLMouseUnFreeze(void);
+/* simple.c */
+void VGLSetXY(VGLBitmap *object, int x, int y, byte color);
+byte VGLGetXY(VGLBitmap *object, int x, int y);
+void VGLLine(VGLBitmap *object, int x1, int y1, int x2, int y2, byte color);
+void VGLBox(VGLBitmap *object, int x1, int y1, int x2, int y2, byte color);
+void VGLFilledBox(VGLBitmap *object, int x1, int y1, int x2, int y2, byte color);
+void VGLEllipse(VGLBitmap *object, int xc, int yc, int a, int b, byte color);
+void VGLFilledEllipse(VGLBitmap *object, int xc, int yc, int a, int b, byte color);
+void VGLClear(VGLBitmap *object, byte color);
+void VGLRestorePalette(void);
+void VGLSavePalette(void);
+void VGLSetPalette(byte *red, byte *green, byte *blue);
+void VGLSetPaletteIndex(byte color, byte red, byte green, byte blue);
+void VGLSetBorder(byte color);
+void VGLBlankDisplay(int blank);
+/* text.c */
+int VGLTextSetFontFile(char *filename);
+void VGLBitmapPutChar(VGLBitmap *Object, int x, int y, byte ch, byte fgcol, byte bgcol, int fill, int dir);
+void VGLBitmapString(VGLBitmap *Object, int x, int y, char *str, byte fgcol, byte bgcol, int fill, int dir);
diff --git a/lib/libwrap/Makefile b/lib/libwrap/Makefile
new file mode 100644
index 0000000..8380067
--- /dev/null
+++ b/lib/libwrap/Makefile
@@ -0,0 +1,29 @@
+#
+# $FreeBSD$
+#
+
+MAINTAINER=markm@FreeBSD.org
+
+LIB= wrap
+MAN3= hosts_access.3
+MAN5= hosts_access.5 hosts_options.5
+
+.PATH: ${.CURDIR}/../../contrib/tcp_wrappers
+
+CFLAGS+=-DFACILITY=LOG_AUTH -DHOSTS_ACCESS -DNETGROUP -DDAEMON_UMASK=022 \
+ -DREAL_DAEMON_DIR=\"/usr/libexec\" -DPROCESS_OPTIONS \
+ -DSEVERITY=LOG_INFO -DRFC931_TIMEOUT=10 \
+ -DHOSTS_DENY=\"/etc/hosts.deny\" -DHOSTS_ALLOW=\"/etc/hosts.allow\" \
+ -DSYS_ERRLIST_DEFINED -DALWAYS_HOSTNAME
+
+SRCS= clean_exit.c diag.c eval.c fix_options.c fromhost.c \
+ hosts_access.c hosts_ctl.c misc.c myvsyslog.c options.c \
+ percent_m.c percent_x.c refuse.c rfc931.c shell_cmd.c \
+ socket.c tli.c update.c workarounds.c libvars.c
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/../../contrib/tcp_wrappers/tcpd.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/libwrap/libvars.c b/lib/libwrap/libvars.c
new file mode 100644
index 0000000..5935c83
--- /dev/null
+++ b/lib/libwrap/libvars.c
@@ -0,0 +1,2 @@
+int allow_severity;
+int deny_severity;
diff --git a/lib/libxpg4/Makefile b/lib/libxpg4/Makefile
new file mode 100644
index 0000000..c831475
--- /dev/null
+++ b/lib/libxpg4/Makefile
@@ -0,0 +1,9 @@
+LIB= xpg4
+SRCS= setlocale.c setrunelocale.c big5.c euc.c mskanji.c utf2.c runetype.c \
+ tolower.c toupper.c
+CFLAGS+= -Wall -DXPG4 -I${.CURDIR}/../libc/locale
+.PATH: ${.CURDIR}/../libc/locale
+
+NOMAN= YES
+
+.include <bsd.lib.mk>
diff --git a/lib/liby/Makefile b/lib/liby/Makefile
new file mode 100644
index 0000000..8c816a9
--- /dev/null
+++ b/lib/liby/Makefile
@@ -0,0 +1,36 @@
+# $FreeBSD$
+
+LIB= y
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 0
+
+SRCS= main.c yyerror.c
+
+.if ${OBJFORMAT} != aout
+NOPIC= true
+.endif
+
+#
+# Before complaining about this, please *double-check* that you have
+# updated the ldconfig path in /etc/rc to include /usr/lib/compat that
+# was added in src/etc/rc rev 1.98.
+# This is so that `ld' will not continue to generate binaries linked
+# shared against liby, so that in a future release we can move this
+# off to a compat dist (like compat22).
+#
+beforeinstall:
+ rm -f ${DESTDIR}/usr/lib/compat/lib${LIB}.so \
+ ${DESTDIR}${ORIG_SHLIBDIR}/lib${LIB}.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ ${DESTDIR}/usr/lib/compat/lib${LIB}.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ ${DESTDIR}/usr/lib/compat/lib${LIB}.so.${SHLIB_MAJOR}
+
+.include <bsd.lib.mk>
+
+# This must follow the .include in case SHLIBDIR is defined there.
+ORIG_SHLIBDIR:= ${SHLIBDIR}
+
+.if ${OBJFORMAT} == aout
+# The ldconfig line in/etc/rc doesn't depend on ${LIBDIR} or ${SHLIBDIR},
+# so neither does this.
+SHLIBDIR= /usr/lib/compat/aout
+.endif
diff --git a/lib/liby/main.c b/lib/liby/main.c
new file mode 100644
index 0000000..4b4e67a
--- /dev/null
+++ b/lib/liby/main.c
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+int
+main(void)
+{
+ exit(yyparse());
+}
diff --git a/lib/liby/yyerror.c b/lib/liby/yyerror.c
new file mode 100644
index 0000000..b21a7a8
--- /dev/null
+++ b/lib/liby/yyerror.c
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)yyerror.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <stdio.h>
+
+int
+yyerror(msg)
+char *msg;
+{
+ (void)fprintf(stderr, "%s\n", msg);
+ return(0);
+}
diff --git a/lib/libz/ChangeLog b/lib/libz/ChangeLog
new file mode 100644
index 0000000..57386a26
--- /dev/null
+++ b/lib/libz/ChangeLog
@@ -0,0 +1,471 @@
+
+ ChangeLog file for zlib
+
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+ occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+ (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+ See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean" (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+ . zutil.c, zutil.h: added "const" for zmem*
+ . Make_vms.com: fixed some typos
+ . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+ . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+ . msdos/Makefile.*: use model-dependent name for the built zlib library
+ . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+ new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- replace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+ See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+ completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+ (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+ compression ratio on some files. This also allows inlining _tr_tally for
+ matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+ on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+ the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+ them at run time (thanks to Ken Raeburn for this suggestion). To create
+ trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+ gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occuring only with compression level 0 (thanks to
+ Andy Buckler for finding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+ (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+ (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+ inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+ contrib/asm386/ by Gilles Vollant <info@winimage.com>
+ 386 asm code replacing longest_match().
+ contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+ A C++ I/O streams interface to the zlib gz* functions
+ contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
+ Another C++ I/O streams interface
+ contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+ A very simple tar.gz file extractor using zlib
+ contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+ How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+ level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+ (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+ bit, so the decompressor could decompress all the correct data but went
+ on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+ small and medium models; this makes the library incompatible with previous
+ versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+ avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+ Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+ and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+ -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+ warning C4746: 'inflate_mask' : unsized array treated as '__far'
+ (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+ not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+ (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+ typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+ was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+ pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+ is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+ (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+ TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+ (one's complement) is now done inside crc32(). WARNING: this is
+ incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+ not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+ Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+ if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+ user-provided history buffer. This is supported only in deflateInit2
+ and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
diff --git a/lib/libz/FAQ b/lib/libz/FAQ
new file mode 100644
index 0000000..0feb6d3
--- /dev/null
+++ b/lib/libz/FAQ
@@ -0,0 +1,72 @@
+
+ Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page
+http://www.cdrom.com/pub/infozip/zlib/ which may have more recent information.
+
+
+1) I need a Windows DLL
+2) I need a Visual Basic interface to zlib
+3) compress() returns Z_BUF_ERROR
+4) deflate or inflate returns Z_BUF_ERROR
+5) Where is the zlib documentation (man pages, etc...)?
+6) Why don't you use GNU autoconf, libtool, etc...?
+7) There is a bug in zlib.
+8) I get "undefined reference to gzputc"
+
+
+
+1) I need a Windows DLL
+
+ The zlib sources can be compiled without change to produce a DLL.
+ If you want a precompiled DLL, see http://www.winimage.com/zLibDll
+
+
+2) I need a Visual Basic interface to zlib
+
+ See http://www.tcfb.com/dowseware/cmp-z-it.zip
+ http://web2.airmail.net/markn/articles/zlibtool/zlibtool.htm
+ and contrib/visual-basic.txt
+
+3) compress() returns Z_BUF_ERROR
+
+ Make sure that before the call of compress, the length of the
+ compressed buffer is equal to the total size of the compressed buffer
+ and not zero. For Visual Basic, check that this parameter is passed
+ by reference ("as any"), not by value ("as long").
+
+
+4) deflate or inflate returns Z_BUF_ERROR
+
+ Make sure that before the call avail_in and avail_out are not zero.
+
+
+5) Where is the zlib documentation (man pages, etc...)?
+
+ It's in zlib.h for the moment. Volunteers to transform this
+ to man pages, please contact jloup@gzip.org. Examples of zlib usage
+ are in the files example.c and minigzip.c.
+
+
+6) Why don't you use GNU autoconf, libtool, etc...?
+
+ Because we would like to keep zlib as a very small and simple package.
+ zlib is rather portable and doesn't need much configuration.
+
+
+7) There is a bug in zlib.
+
+ Most of the time, such problems are due to an incorrect usage
+ of zlib. Please try to reproduce the problem with a small
+ program and send us the corresponding source at zlib@quest.jpl.nasa.gov
+ Do not send multi-megabyte data files without prior agreement.
+
+
+8) I get "undefined reference to gzputc"
+
+ If "make test" produces something like
+ example.o(.text+0x174):
+ check that you don't have old files libz.* in /usr/lib, /usr/local/lib
+ or /usr/X11R6/lib. Remove old versions then do "make install".
+
diff --git a/lib/libz/Makefile b/lib/libz/Makefile
new file mode 100644
index 0000000..250e005
--- /dev/null
+++ b/lib/libz/Makefile
@@ -0,0 +1,37 @@
+#
+# $FreeBSD$
+#
+
+MAINTAINER=peter@FreeBSD.org
+
+LIB= z
+MAN3= zlib.3
+
+#CFLAGS+= -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS+= -g -DDEBUG
+#CFLAGS+= -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+# -Wstrict-prototypes -Wmissing-prototypes
+
+CLEANFILES+= example.o example foo.gz minigzip.o minigzip
+
+SRCS = adler32.c compress.c crc32.c gzio.c uncompr.c deflate.c trees.c \
+ zutil.c inflate.c infblock.c inftrees.c infcodes.c infutil.c inffast.c
+
+beforeinstall:
+.for hdr in zconf.h zlib.h
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/${hdr} \
+ ${DESTDIR}/usr/include
+.endfor
+
+minigzip: all minigzip.o
+ $(CC) -o minigzip minigzip.o -L. -lz
+
+example: all example.o
+ $(CC) -o example example.o -L. -lz
+
+test: example minigzip
+ (export LD_LIBRARY_PATH=. ; ./example )
+ (export LD_LIBRARY_PATH=. ; \
+ echo hello world | ./minigzip | ./minigzip -d )
+
+.include <bsd.lib.mk>
diff --git a/lib/libz/README b/lib/libz/README
new file mode 100644
index 0000000..8ff4587
--- /dev/null
+++ b/lib/libz/README
@@ -0,0 +1,148 @@
+zlib 1.1.3 is a general purpose data compression library. All the code
+is thread safe. The data format used by the zlib library
+is described by RFCs (Request for Comments) 1950 to 1952 in the files
+ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
+format) and rfc1952.txt (gzip format). These documents are also available in
+other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
+example of the library is given in the file example.c which also tests that
+the library is working correctly. Another example is given in the file
+minigzip.c. The compression library itself is composed of all source files
+except example.c and minigzip.c.
+
+To compile all files and run the test program, follow the instructions
+given at the top of Makefile. In short "make test; make install"
+should work for most machines. For Unix: "configure; make test; make install"
+For MSDOS, use one of the special makefiles such as Makefile.msc.
+For VMS, use Make_vms.com or descrip.mms.
+
+Questions about zlib should be sent to <zlib@quest.jpl.nasa.gov>, or to
+Gilles Vollant <info@winimage.com> for the Windows DLL version.
+The zlib home page is http://www.cdrom.com/pub/infozip/zlib/
+The official zlib ftp site is ftp://ftp.cdrom.com/pub/infozip/zlib/
+Before reporting a problem, please check those sites to verify that
+you have the latest version of zlib; otherwise get the latest version and
+check whether the problem still exists or not.
+
+Mark Nelson <markn@tiny.com> wrote an article about zlib for the Jan. 1997
+issue of Dr. Dobb's Journal; a copy of the article is available in
+http://web2.airmail.net/markn/articles/zlibtool/zlibtool.htm
+
+The changes made in version 1.1.3 are documented in the file ChangeLog.
+The main changes since 1.1.2 are:
+
+- fix "an inflate input buffer bug that shows up on rare but persistent
+ occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+ (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+ See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+plus many changes for portability.
+
+Unsupported third party contributions are provided in directory "contrib".
+
+A Java implementation of zlib is available in the Java Development Kit 1.1
+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
+See the zlib home page http://www.cdrom.com/pub/infozip/zlib/ for details.
+
+A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
+is in the CPAN (Comprehensive Perl Archive Network) sites, such as:
+ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib*
+
+A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
+is available in Python 1.5 and later versions, see
+http://www.python.org/doc/lib/module-zlib.html
+
+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
+is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
+
+An experimental package to read and write files in .zip format,
+written on top of zlib by Gilles Vollant <info@winimage.com>, is
+available at http://www.winimage.com/zLibDll/unzip.html
+and also in the contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
+ and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
+ The zlib DLL support was initially done by Alessandro Iacopetti and is
+ now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
+ home page at http://www.winimage.com/zLibDll
+
+ From Visual Basic, you can call the DLL functions which do not take
+ a structure as argument: compress, uncompress and all gz* functions.
+ See contrib/visual-basic.txt for more information, or get
+ http://www.tcfb.com/dowseware/cmp-z-it.zip
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization.
+ With -O, one libpng test fails. The test works in 32 bit mode (with
+ the -n32 compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
+ it works when compiled with cc.
+
+- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
+ is necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
+ with other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
+
+- For Turbo C the small model is supported only with reduced performance to
+ avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
+
+- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
+ Per Harald Myrvang <perm@stud.cs.uit.no>
+
+
+Acknowledgments:
+
+ The deflate format used by zlib was defined by Phil Katz. The deflate
+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib;
+ they are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-1998 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind. The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes.
diff --git a/lib/libz/adler32.c b/lib/libz/adler32.c
new file mode 100644
index 0000000..8d42f87
--- /dev/null
+++ b/lib/libz/adler32.c
@@ -0,0 +1,48 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $FreeBSD$ */
+
+#include "zlib.h"
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ uInt len;
+{
+ unsigned long s1 = adler & 0xffff;
+ unsigned long s2 = (adler >> 16) & 0xffff;
+ int k;
+
+ if (buf == Z_NULL) return 1L;
+
+ while (len > 0) {
+ k = len < NMAX ? len : NMAX;
+ len -= k;
+ while (k >= 16) {
+ DO16(buf);
+ buf += 16;
+ k -= 16;
+ }
+ if (k != 0) do {
+ s1 += *buf++;
+ s2 += s1;
+ } while (--k);
+ s1 %= BASE;
+ s2 %= BASE;
+ }
+ return (s2 << 16) | s1;
+}
diff --git a/lib/libz/algorithm.txt b/lib/libz/algorithm.txt
new file mode 100644
index 0000000..cdc830b
--- /dev/null
+++ b/lib/libz/algorithm.txt
@@ -0,0 +1,213 @@
+1. Compression algorithm (deflate)
+
+The deflation algorithm used by gzip (also zip and zlib) is a variation of
+LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
+the input data. The second occurrence of a string is replaced by a
+pointer to the previous string, in the form of a pair (distance,
+length). Distances are limited to 32K bytes, and lengths are limited
+to 258 bytes. When a string does not occur anywhere in the previous
+32K bytes, it is emitted as a sequence of literal bytes. (In this
+description, `string' must be taken as an arbitrary sequence of bytes,
+and is not restricted to printable characters.)
+
+Literals or match lengths are compressed with one Huffman tree, and
+match distances are compressed with another tree. The trees are stored
+in a compact form at the start of each block. The blocks can have any
+size (except that the compressed data for one block must fit in
+available memory). A block is terminated when deflate() determines that
+it would be useful to start another block with fresh trees. (This is
+somewhat similar to the behavior of LZW-based _compress_.)
+
+Duplicated strings are found using a hash table. All input strings of
+length 3 are inserted in the hash table. A hash index is computed for
+the next 3 bytes. If the hash chain for this index is not empty, all
+strings in the chain are compared with the current input string, and
+the longest match is selected.
+
+The hash chains are searched starting with the most recent strings, to
+favor small distances and thus take advantage of the Huffman encoding.
+The hash chains are singly linked. There are no deletions from the
+hash chains, the algorithm simply discards matches that are too old.
+
+To avoid a worst-case situation, very long hash chains are arbitrarily
+truncated at a certain length, determined by a runtime option (level
+parameter of deflateInit). So deflate() does not always find the longest
+possible match but generally finds a match which is long enough.
+
+deflate() also defers the selection of matches with a lazy evaluation
+mechanism. After a match of length N has been found, deflate() searches for
+a longer match at the next input byte. If a longer match is found, the
+previous match is truncated to a length of one (thus producing a single
+literal byte) and the process of lazy evaluation begins again. Otherwise,
+the original match is kept, and the next match search is attempted only N
+steps later.
+
+The lazy match evaluation is also subject to a runtime parameter. If
+the current match is long enough, deflate() reduces the search for a longer
+match, thus speeding up the whole process. If compression ratio is more
+important than speed, deflate() attempts a complete second search even if
+the first match is already long enough.
+
+The lazy match evaluation is not performed for the fastest compression
+modes (level parameter 1 to 3). For these fast modes, new strings
+are inserted in the hash table only when no match was found, or
+when the match is not too long. This degrades the compression ratio
+but saves time since there are both fewer insertions and fewer searches.
+
+
+2. Decompression algorithm (inflate)
+
+2.1 Introduction
+
+The real question is, given a Huffman tree, how to decode fast. The most
+important realization is that shorter codes are much more common than
+longer codes, so pay attention to decoding the short codes fast, and let
+the long codes take longer to decode.
+
+inflate() sets up a first level table that covers some number of bits of
+input less than the length of longest code. It gets that many bits from the
+stream, and looks it up in the table. The table will tell if the next
+code is that many bits or less and how many, and if it is, it will tell
+the value, else it will point to the next level table for which inflate()
+grabs more bits and tries to decode a longer code.
+
+How many bits to make the first lookup is a tradeoff between the time it
+takes to decode and the time it takes to build the table. If building the
+table took no time (and if you had infinite memory), then there would only
+be a first level table to cover all the way to the longest code. However,
+building the table ends up taking a lot longer for more bits since short
+codes are replicated many times in such a table. What inflate() does is
+simply to make the number of bits in the first table a variable, and set it
+for the maximum speed.
+
+inflate() sends new trees relatively often, so it is possibly set for a
+smaller first level table than an application that has only one tree for
+all the data. For inflate, which has 286 possible codes for the
+literal/length tree, the size of the first table is nine bits. Also the
+distance trees have 30 possible values, and the size of the first table is
+six bits. Note that for each of those cases, the table ended up one bit
+longer than the ``average'' code length, i.e. the code length of an
+approximately flat code which would be a little more than eight bits for
+286 symbols and a little less than five bits for 30 symbols. It would be
+interesting to see if optimizing the first level table for other
+applications gave values within a bit or two of the flat code size.
+
+
+2.2 More details on the inflate table lookup
+
+Ok, you want to know what this cleverly obfuscated inflate tree actually
+looks like. You are correct that it's not a Huffman tree. It is simply a
+lookup table for the first, let's say, nine bits of a Huffman symbol. The
+symbol could be as short as one bit or as long as 15 bits. If a particular
+symbol is shorter than nine bits, then that symbol's translation is duplicated
+in all those entries that start with that symbol's bits. For example, if the
+symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a
+symbol is nine bits long, it appears in the table once.
+
+If the symbol is longer than nine bits, then that entry in the table points
+to another similar table for the remaining bits. Again, there are duplicated
+entries as needed. The idea is that most of the time the symbol will be short
+and there will only be one table look up. (That's whole idea behind data
+compression in the first place.) For the less frequent long symbols, there
+will be two lookups. If you had a compression method with really long
+symbols, you could have as many levels of lookups as is efficient. For
+inflate, two is enough.
+
+So a table entry either points to another table (in which case nine bits in
+the above example are gobbled), or it contains the translation for the symbol
+and the number of bits to gobble. Then you start again with the next
+ungobbled bit.
+
+You may wonder: why not just have one lookup table for how ever many bits the
+longest symbol is? The reason is that if you do that, you end up spending
+more time filling in duplicate symbol entries than you do actually decoding.
+At least for deflate's output that generates new trees every several 10's of
+kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
+would take too long if you're only decoding several thousand symbols. At the
+other extreme, you could make a new table for every bit in the code. In fact,
+that's essentially a Huffman tree. But then you spend two much time
+traversing the tree while decoding, even for short symbols.
+
+So the number of bits for the first lookup table is a trade of the time to
+fill out the table vs. the time spent looking at the second level and above of
+the table.
+
+Here is an example, scaled down:
+
+The code being decoded, with 10 symbols, from 1 to 6 bits long:
+
+A: 0
+B: 10
+C: 1100
+D: 11010
+E: 11011
+F: 11100
+G: 11101
+H: 11110
+I: 111110
+J: 111111
+
+Let's make the first table three bits long (eight entries):
+
+000: A,1
+001: A,1
+010: A,1
+011: A,1
+100: B,2
+101: B,2
+110: -> table X (gobble 3 bits)
+111: -> table Y (gobble 3 bits)
+
+Each entry is what the bits decode to and how many bits that is, i.e. how
+many bits to gobble. Or the entry points to another table, with the number of
+bits to gobble implicit in the size of the table.
+
+Table X is two bits long since the longest code starting with 110 is five bits
+long:
+
+00: C,1
+01: C,1
+10: D,2
+11: E,2
+
+Table Y is three bits long since the longest code starting with 111 is six
+bits long:
+
+000: F,2
+001: F,2
+010: G,2
+011: G,2
+100: H,2
+101: H,2
+110: I,3
+111: J,3
+
+So what we have here are three tables with a total of 20 entries that had to
+be constructed. That's compared to 64 entries for a single table. Or
+compared to 16 entries for a Huffman tree (six two entry tables and one four
+entry table). Assuming that the code ideally represents the probability of
+the symbols, it takes on the average 1.25 lookups per symbol. That's compared
+to one lookup for the single table, or 1.66 lookups per symbol for the
+Huffman tree.
+
+There, I think that gives you a picture of what's going on. For inflate, the
+meaning of a particular symbol is often more than just a letter. It can be a
+byte (a "literal"), or it can be either a length or a distance which
+indicates a base value and a number of bits to fetch after the code that is
+added to the base value. Or it might be the special end-of-block code. The
+data structures created in inftrees.c try to encode all that information
+compactly in the tables.
+
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+
+
+References:
+
+[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
+Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
+pp. 337-343.
+
+``DEFLATE Compressed Data Format Specification'' available in
+ftp://ds.internic.net/rfc/rfc1951.txt
diff --git a/lib/libz/compress.c b/lib/libz/compress.c
new file mode 100644
index 0000000..4ff6bc1
--- /dev/null
+++ b/lib/libz/compress.c
@@ -0,0 +1,68 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $FreeBSD$ */
+
+#include "zlib.h"
+
+/* ===========================================================================
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+ int level;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = deflateInit(&stream, level);
+ if (err != Z_OK) return err;
+
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = deflateEnd(&stream);
+ return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
diff --git a/lib/libz/crc32.c b/lib/libz/crc32.c
new file mode 100644
index 0000000..3f8ce1d
--- /dev/null
+++ b/lib/libz/crc32.c
@@ -0,0 +1,162 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $FreeBSD$ */
+
+#include "zlib.h"
+
+#define local static
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local int crc_table_empty = 1;
+local uLongf crc_table[256];
+local void make_crc_table OF((void));
+
+/*
+ Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The table is simply the CRC of all possible eight bit values. This is all
+ the information needed to generate CRC's on data a byte at a time for all
+ combinations of CRC register values and incoming bytes.
+*/
+local void make_crc_table()
+{
+ uLong c;
+ int n, k;
+ uLong poly; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* make exclusive-or pattern from polynomial (0xedb88320L) */
+ poly = 0L;
+ for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
+ poly |= 1L << (31 - p[n]);
+
+ for (n = 0; n < 256; n++)
+ {
+ c = (uLong)n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[n] = c;
+ }
+ crc_table_empty = 0;
+}
+#else
+/* ========================================================================
+ * Table of CRC-32's of all single-byte values (made by make_crc_table)
+ */
+local const uLongf crc_table[256] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+ 0x2d02ef8dL
+};
+#endif
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const uLongf * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty) make_crc_table();
+#endif
+ return (const uLongf *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf) DO1(buf); DO1(buf);
+#define DO4(buf) DO2(buf); DO2(buf);
+#define DO8(buf) DO4(buf); DO4(buf);
+
+/* ========================================================================= */
+uLong ZEXPORT crc32(crc, buf, len)
+ uLong crc;
+ const Bytef *buf;
+ uInt len;
+{
+ if (buf == Z_NULL) return 0L;
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif
+ crc = crc ^ 0xffffffffL;
+ while (len >= 8)
+ {
+ DO8(buf);
+ len -= 8;
+ }
+ if (len) do {
+ DO1(buf);
+ } while (--len);
+ return crc ^ 0xffffffffL;
+}
diff --git a/lib/libz/deflate.c b/lib/libz/deflate.c
new file mode 100644
index 0000000..10bb235
--- /dev/null
+++ b/lib/libz/deflate.c
@@ -0,0 +1,1350 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process depends on being able to identify portions
+ * of the input text which are identical to earlier input (within a
+ * sliding window trailing behind the input currently being processed).
+ *
+ * The most straightforward technique turns out to be the fastest for
+ * most input files: try all possible matches and select the longest.
+ * The key feature of this algorithm is that insertions into the string
+ * dictionary are very simple and thus fast, and deletions are avoided
+ * completely. Insertions are performed at each input character, whereas
+ * string matches are performed only when the previous match ends. So it
+ * is preferable to spend more time in matches to allow very fast string
+ * insertions and avoid deletions. The matching algorithm for small
+ * strings is inspired from that of Rabin & Karp. A brute force approach
+ * is used to find longer strings when a small match has been found.
+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ * (by Leonid Broukhis).
+ * A previous version of this file used a more sophisticated algorithm
+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
+ * time, but has a larger average cost, uses more memory and is patented.
+ * However the F&G algorithm may be faster for some highly redundant
+ * files if the parameter max_chain_length (described below) is too large.
+ *
+ * ACKNOWLEDGEMENTS
+ *
+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ * I found it in 'freeze' written by Leonid Broukhis.
+ * Thanks to many people for bug reports and testing.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ * Available in ftp://ds.internic.net/rfc/rfc1951.txt
+ *
+ * A description of the Rabin and Karp algorithm is given in the book
+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ * Fiala,E.R., and Greene,D.H.
+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $FreeBSD$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+ " deflate 1.1.3 Copyright 1995-1998 Jean-loup Gailly ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ * Function prototypes.
+ */
+typedef enum {
+ need_more, /* block not completed, need more input or more output */
+ block_done, /* block flush performed */
+ finish_started, /* finish started, need only more output at next deflate */
+ finish_done /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast OF((deflate_state *s, int flush));
+local block_state deflate_slow OF((deflate_state *s, int flush));
+local void lm_init OF((deflate_state *s));
+local void putShortMSB OF((deflate_state *s, uInt b));
+local void flush_pending OF((z_streamp strm));
+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+ void match_init OF((void)); /* asm code initialization */
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG
+local void check_match OF((deflate_state *s, IPos start, IPos match,
+ int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+# define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+ ush good_length; /* reduce lazy search above this match length */
+ ush max_lazy; /* do not perform lazy search above this match length */
+ ush nice_length; /* quit search above this match length */
+ ush max_chain;
+ compress_func func;
+} config;
+
+local const config configuration_table[10] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
+/* 2 */ {4, 5, 16, 8, deflate_fast},
+/* 3 */ {4, 6, 32, 32, deflate_fast},
+
+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
+/* 5 */ {8, 16, 32, 32, deflate_slow},
+/* 6 */ {8, 16, 128, 128, deflate_slow},
+/* 7 */ {8, 32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
+ * input characters, so that a running hash key can be computed from the
+ * previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
+ * input characters and the first MIN_MATCH bytes of str are valid
+ * (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+ z_streamp strm;
+ int level;
+ const char *version;
+ int stream_size;
+{
+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+ Z_DEFAULT_STRATEGY, version, stream_size);
+ /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+ version, stream_size)
+ z_streamp strm;
+ int level;
+ int method;
+ int windowBits;
+ int memLevel;
+ int strategy;
+ const char *version;
+ int stream_size;
+{
+ deflate_state *s;
+ int noheader = 0;
+ static const char* my_version = ZLIB_VERSION;
+
+ ushf *overlay;
+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
+ * output size for (length,distance) codes is <= 24 bits.
+ */
+
+ if (version == Z_NULL || version[0] != my_version[0] ||
+ stream_size != sizeof(z_stream)) {
+ return Z_VERSION_ERROR;
+ }
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->msg = Z_NULL;
+ if (strm->zalloc == Z_NULL) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == Z_NULL) strm->zfree = zcfree;
+
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#ifdef FASTEST
+ level = 1;
+#endif
+
+ if (windowBits < 0) { /* undocumented feature: suppress zlib header */
+ noheader = 1;
+ windowBits = -windowBits;
+ }
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+ windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+ strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+ return Z_STREAM_ERROR;
+ }
+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+ if (s == Z_NULL) return Z_MEM_ERROR;
+ strm->state = (struct internal_state FAR *)s;
+ s->strm = strm;
+
+ s->noheader = noheader;
+ s->w_bits = windowBits;
+ s->w_size = 1 << s->w_bits;
+ s->w_mask = s->w_size - 1;
+
+ s->hash_bits = memLevel + 7;
+ s->hash_size = 1 << s->hash_bits;
+ s->hash_mask = s->hash_size - 1;
+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+ s->pending_buf = (uchf *) overlay;
+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+ s->pending_buf == Z_NULL) {
+ strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+ deflateEnd (strm);
+ return Z_MEM_ERROR;
+ }
+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+ s->level = level;
+ s->strategy = strategy;
+ s->method = (Byte)method;
+
+ return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+ z_streamp strm;
+ const Bytef *dictionary;
+ uInt dictLength;
+{
+ deflate_state *s;
+ uInt length = dictLength;
+ uInt n;
+ IPos hash_head = 0;
+
+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+ strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
+
+ s = strm->state;
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+ if (length < MIN_MATCH) return Z_OK;
+ if (length > MAX_DIST(s)) {
+ length = MAX_DIST(s);
+#ifndef USE_DICT_HEAD
+ dictionary += dictLength - length; /* use the tail of the dictionary */
+#endif
+ }
+ zmemcpy(s->window, dictionary, length);
+ s->strstart = length;
+ s->block_start = (long)length;
+
+ /* Insert all strings in the hash table (except for the last two bytes).
+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
+ * call of fill_window.
+ */
+ s->ins_h = s->window[0];
+ UPDATE_HASH(s, s->ins_h, s->window[1]);
+ for (n = 0; n <= length - MIN_MATCH; n++) {
+ INSERT_STRING(s, n, hash_head);
+ }
+ if (hash_head) hash_head = 0; /* to make compiler happy */
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->total_in = strm->total_out = 0;
+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+ strm->data_type = Z_UNKNOWN;
+
+ s = (deflate_state *)strm->state;
+ s->pending = 0;
+ s->pending_out = s->pending_buf;
+
+ if (s->noheader < 0) {
+ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
+ }
+ s->status = s->noheader ? BUSY_STATE : INIT_STATE;
+ strm->adler = 1;
+ s->last_flush = Z_NO_FLUSH;
+
+ _tr_init(s);
+ lm_init(s);
+
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+ z_streamp strm;
+ int level;
+ int strategy;
+{
+ deflate_state *s;
+ compress_func func;
+ int err = Z_OK;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+
+ if (level == Z_DEFAULT_COMPRESSION) {
+ level = 6;
+ }
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+ return Z_STREAM_ERROR;
+ }
+ func = configuration_table[s->level].func;
+
+ if (func != configuration_table[level].func && strm->total_in != 0) {
+ /* Flush the last buffer: */
+ err = deflate(strm, Z_PARTIAL_FLUSH);
+ }
+ if (s->level != level) {
+ s->level = level;
+ s->max_lazy_match = configuration_table[level].max_lazy;
+ s->good_match = configuration_table[level].good_length;
+ s->nice_match = configuration_table[level].nice_length;
+ s->max_chain_length = configuration_table[level].max_chain;
+ }
+ s->strategy = strategy;
+ return err;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+ deflate_state *s;
+ uInt b;
+{
+ put_byte(s, (Byte)(b >> 8));
+ put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+ z_streamp strm;
+{
+ unsigned len = strm->state->pending;
+
+ if (len > strm->avail_out) len = strm->avail_out;
+ if (len == 0) return;
+
+ zmemcpy(strm->next_out, strm->state->pending_out, len);
+ strm->next_out += len;
+ strm->state->pending_out += len;
+ strm->total_out += len;
+ strm->avail_out -= len;
+ strm->state->pending -= len;
+ if (strm->state->pending == 0) {
+ strm->state->pending_out = strm->state->pending_buf;
+ }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+ z_streamp strm;
+ int flush;
+{
+ int old_flush; /* value of flush param for previous deflate call */
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ flush > Z_FINISH || flush < 0) {
+ return Z_STREAM_ERROR;
+ }
+ s = strm->state;
+
+ if (strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
+ ERR_RETURN(strm, Z_STREAM_ERROR);
+ }
+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+ s->strm = strm; /* just in case */
+ old_flush = s->last_flush;
+ s->last_flush = flush;
+
+ /* Write the zlib header */
+ if (s->status == INIT_STATE) {
+
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ uInt level_flags = (s->level-1) >> 1;
+
+ if (level_flags > 3) level_flags = 3;
+ header |= (level_flags << 6);
+ if (s->strstart != 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ s->status = BUSY_STATE;
+ putShortMSB(s, header);
+
+ /* Save the adler32 of the preset dictionary: */
+ if (s->strstart != 0) {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ strm->adler = 1L;
+ }
+
+ /* Flush as much pending output as possible */
+ if (s->pending != 0) {
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ /* Since avail_out is 0, deflate will be called again with
+ * more output space, but possibly with both pending and
+ * avail_in equal to zero. There won't be anything to do,
+ * but this is not an error situation so make sure we
+ * return OK instead of BUF_ERROR at next call of deflate:
+ */
+ s->last_flush = -1;
+ return Z_OK;
+ }
+
+ /* Make sure there is something to do and avoid duplicate consecutive
+ * flushes. For repeated and useless calls with Z_FINISH, we keep
+ * returning Z_STREAM_END instead of Z_BUFF_ERROR.
+ */
+ } else if (strm->avail_in == 0 && flush <= old_flush &&
+ flush != Z_FINISH) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* User must not provide more input after the first FINISH: */
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* Start a new block or continue the current one.
+ */
+ if (strm->avail_in != 0 || s->lookahead != 0 ||
+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+ block_state bstate;
+
+ bstate = (*(configuration_table[s->level].func))(s, flush);
+
+ if (bstate == finish_started || bstate == finish_done) {
+ s->status = FINISH_STATE;
+ }
+ if (bstate == need_more || bstate == finish_started) {
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+ }
+ return Z_OK;
+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+ * of deflate should use the same flush parameter to make sure
+ * that the flush is complete. So we don't have to output an
+ * empty block here, this will be done at next call. This also
+ * ensures that for a very small output buffer, we emit at most
+ * one empty block.
+ */
+ }
+ if (bstate == block_done) {
+ if (flush == Z_PARTIAL_FLUSH) {
+ _tr_align(s);
+ } else { /* FULL_FLUSH or SYNC_FLUSH */
+ _tr_stored_block(s, (char*)0, 0L, 0);
+ /* For a full flush, this empty block will be recognized
+ * as a special marker by inflate_sync().
+ */
+ if (flush == Z_FULL_FLUSH) {
+ CLEAR_HASH(s); /* forget history */
+ }
+ }
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+ return Z_OK;
+ }
+ }
+ }
+ Assert(strm->avail_out > 0, "bug2");
+
+ if (flush != Z_FINISH) return Z_OK;
+ if (s->noheader) return Z_STREAM_END;
+
+ /* Write the zlib trailer (adler32) */
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ flush_pending(strm);
+ /* If avail_out is zero, the application will call deflate again
+ * to flush the rest.
+ */
+ s->noheader = -1; /* write the trailer only once! */
+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+ z_streamp strm;
+{
+ int status;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+ status = strm->state->status;
+ if (status != INIT_STATE && status != BUSY_STATE &&
+ status != FINISH_STATE) {
+ return Z_STREAM_ERROR;
+ }
+
+ /* Deallocate in reverse order of allocations: */
+ TRY_FREE(strm, strm->state->pending_buf);
+ TRY_FREE(strm, strm->state->head);
+ TRY_FREE(strm, strm->state->prev);
+ TRY_FREE(strm, strm->state->window);
+
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+
+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+ z_streamp dest;
+ z_streamp source;
+{
+#ifdef MAXSEG_64K
+ return Z_STREAM_ERROR;
+#else
+ deflate_state *ds;
+ deflate_state *ss;
+ ushf *overlay;
+
+
+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+ return Z_STREAM_ERROR;
+ }
+
+ ss = source->state;
+
+ *dest = *source;
+
+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+ if (ds == Z_NULL) return Z_MEM_ERROR;
+ dest->state = (struct internal_state FAR *) ds;
+ *ds = *ss;
+ ds->strm = dest;
+
+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+ ds->pending_buf = (uchf *) overlay;
+
+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+ ds->pending_buf == Z_NULL) {
+ deflateEnd (dest);
+ return Z_MEM_ERROR;
+ }
+ /* following zmemcpy do not work for 16-bit MSDOS */
+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+ ds->l_desc.dyn_tree = ds->dyn_ltree;
+ ds->d_desc.dyn_tree = ds->dyn_dtree;
+ ds->bl_desc.dyn_tree = ds->bl_tree;
+
+ return Z_OK;
+#endif
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read. All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+ z_streamp strm;
+ Bytef *buf;
+ unsigned size;
+{
+ unsigned len = strm->avail_in;
+
+ if (len > size) len = size;
+ if (len == 0) return 0;
+
+ strm->avail_in -= len;
+
+ if (!strm->state->noheader) {
+ strm->adler = adler32(strm->adler, strm->next_in, len);
+ }
+ zmemcpy(buf, strm->next_in, len);
+ strm->next_in += len;
+ strm->total_in += len;
+
+ return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+ deflate_state *s;
+{
+ s->window_size = (ulg)2L*s->w_size;
+
+ CLEAR_HASH(s);
+
+ /* Set the default configuration parameters:
+ */
+ s->max_lazy_match = configuration_table[s->level].max_lazy;
+ s->good_match = configuration_table[s->level].good_length;
+ s->nice_match = configuration_table[s->level].nice_length;
+ s->max_chain_length = configuration_table[s->level].max_chain;
+
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ s->ins_h = 0;
+#ifdef ASMV
+ match_init(); /* initialize the asm code */
+#endif
+}
+
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+#ifndef FASTEST
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ int best_len = s->prev_length; /* best match length so far */
+ int nice_match = s->nice_match; /* stop if match long enough */
+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+ s->strstart - (IPos)MAX_DIST(s) : NIL;
+ /* Stop when cur_match becomes <= limit. To simplify the code,
+ * we prevent matches with the string of window index 0.
+ */
+ Posf *prev = s->prev;
+ uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+ /* Compare two bytes at a time. Note: this is not always beneficial.
+ * Try with and without -DUNALIGNED_OK to check.
+ */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+ register ush scan_start = *(ushf*)scan;
+ register ush scan_end = *(ushf*)(scan+best_len-1);
+#else
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Byte scan_end1 = scan[best_len-1];
+ register Byte scan_end = scan[best_len];
+#endif
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ /* Do not waste too much time if we already have a good match: */
+ if (s->prev_length >= s->good_match) {
+ chain_length >>= 2;
+ }
+ /* Do not look for matches beyond the end of the input. This is necessary
+ * to make deflate deterministic.
+ */
+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ do {
+ Assert(cur_match < s->strstart, "no future");
+ match = s->window + cur_match;
+
+ /* Skip to next match if the match length cannot increase
+ * or if the match length is less than 2:
+ */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+ /* This code assumes sizeof(unsigned short) == 2. Do not use
+ * UNALIGNED_OK if your compiler uses a different size.
+ */
+ if (*(ushf*)(match+best_len-1) != scan_end ||
+ *(ushf*)match != scan_start) continue;
+
+ /* It is not necessary to compare scan[2] and match[2] since they are
+ * always equal when the other bytes match, given that the hash keys
+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
+ * lookahead only every 4th comparison; the 128th check will be made
+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+ * necessary to put more guard bytes at the end of the window, or
+ * to check more often for insufficient lookahead.
+ */
+ Assert(scan[2] == match[2], "scan[2]?");
+ scan++, match++;
+ do {
+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ scan < strend);
+ /* The funny "do {}" generates better code on most compilers */
+
+ /* Here, scan <= window+strstart+257 */
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+ if (*scan == *match) scan++;
+
+ len = (MAX_MATCH - 1) - (int)(strend-scan);
+ scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+ if (match[best_len] != scan_end ||
+ match[best_len-1] != scan_end1 ||
+ *match != *scan ||
+ *++match != scan[1]) continue;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match++;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+ scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+ if (len > best_len) {
+ s->match_start = cur_match;
+ best_len = len;
+ if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+ scan_end = *(ushf*)(scan+best_len-1);
+#else
+ scan_end1 = scan[best_len-1];
+ scan_end = scan[best_len];
+#endif
+ }
+ } while ((cur_match = prev[cur_match & wmask]) > limit
+ && --chain_length != 0);
+
+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+ return s->lookahead;
+}
+
+#else /* FASTEST */
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 only
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ Assert(cur_match < s->strstart, "no future");
+
+ match = s->window + cur_match;
+
+ /* Return failure if the match length is less than 2:
+ */
+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match += 2;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+
+ if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+ s->match_start = cur_match;
+ return len <= s->lookahead ? len : s->lookahead;
+}
+#endif /* FASTEST */
+#endif /* ASMV */
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+ deflate_state *s;
+ IPos start, match;
+ int length;
+{
+ /* check that the match is indeed a match */
+ if (zmemcmp(s->window + match,
+ s->window + start, length) != EQUAL) {
+ fprintf(stderr, " start %u, match %u, length %d\n",
+ start, match, length);
+ do {
+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+ } while (--length != 0);
+ z_error("invalid match");
+ }
+ if (z_verbose > 1) {
+ fprintf(stderr,"\\[%d,%d]", start-match, length);
+ do { putc(s->window[start++], stderr); } while (--length != 0);
+ }
+}
+#else
+# define check_match(s, start, match, length)
+#endif
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ * At least one byte has been read, or avail_in == 0; reads are
+ * performed for at least two bytes (required for the zip translate_eol
+ * option -- not supported here).
+ */
+local void fill_window(s)
+ deflate_state *s;
+{
+ register unsigned n, m;
+ register Posf *p;
+ unsigned more; /* Amount of free space at the end of the window. */
+ uInt wsize = s->w_size;
+
+ do {
+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+ /* Deal with !@#$% 64K limit: */
+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+ more = wsize;
+
+ } else if (more == (unsigned)(-1)) {
+ /* Very unlikely, but possible on 16 bit machine if strstart == 0
+ * and lookahead == 1 (input done one byte at time)
+ */
+ more--;
+
+ /* If the window is almost full and there is insufficient lookahead,
+ * move the upper half to the lower one to make room in the upper half.
+ */
+ } else if (s->strstart >= wsize+MAX_DIST(s)) {
+
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+ s->match_start -= wsize;
+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
+ s->block_start -= (long) wsize;
+
+ /* Slide the hash table (could be avoided with 32 bit values
+ at the expense of memory usage). We slide even when level == 0
+ to keep the hash table consistent if we switch back to level > 0
+ later. (Using level 0 permanently is not an optimal usage of
+ zlib, so we don't care about this pathological case.)
+ */
+ n = s->hash_size;
+ p = &s->head[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ } while (--n);
+
+ n = wsize;
+#ifndef FASTEST
+ p = &s->prev[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ /* If n is not on any hash chain, prev[n] is garbage but
+ * its value will never be used.
+ */
+ } while (--n);
+#endif
+ more += wsize;
+ }
+ if (s->strm->avail_in == 0) return;
+
+ /* If there was no sliding:
+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+ * more == window_size - lookahead - strstart
+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+ * => more >= window_size - 2*WSIZE + 2
+ * In the BIG_MEM or MMAP case (not yet supported),
+ * window_size == input_size + MIN_LOOKAHEAD &&
+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+ * Otherwise, window_size == 2*WSIZE so more >= 2.
+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+ */
+ Assert(more >= 2, "more < 2");
+
+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+ s->lookahead += n;
+
+ /* Initialize the hash value now that we have some input: */
+ if (s->lookahead >= MIN_MATCH) {
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ }
+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+ * but this is not important since only literal bytes will be emitted.
+ */
+
+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+ _tr_flush_block(s, (s->block_start >= 0L ? \
+ (charf *)&s->window[(unsigned)s->block_start] : \
+ (charf *)Z_NULL), \
+ (ulg)((long)s->strstart - s->block_start), \
+ (eof)); \
+ s->block_start = s->strstart; \
+ flush_pending(s->strm); \
+ Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+ FLUSH_BLOCK_ONLY(s, eof); \
+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+ * to pending_buf_size, and each stored block has a 5 byte header:
+ */
+ ulg max_block_size = 0xffff;
+ ulg max_start;
+
+ if (max_block_size > s->pending_buf_size - 5) {
+ max_block_size = s->pending_buf_size - 5;
+ }
+
+ /* Copy as much as possible from input to output: */
+ for (;;) {
+ /* Fill the window as much as possible: */
+ if (s->lookahead <= 1) {
+
+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+ s->block_start >= (long)s->w_size, "slide too late");
+
+ fill_window(s);
+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+ Assert(s->block_start >= 0L, "block gone");
+
+ s->strstart += s->lookahead;
+ s->lookahead = 0;
+
+ /* Emit a stored block if pending_buf will be full: */
+ max_start = s->block_start + max_block_size;
+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+ /* strstart == 0 is possible when wraparound on 16-bit machine */
+ s->lookahead = (uInt)(s->strstart - max_start);
+ s->strstart = (uInt)max_start;
+ FLUSH_BLOCK(s, 0);
+ }
+ /* Flush if we may have to slide, otherwise block_start may become
+ * negative and the data will be gone:
+ */
+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+ FLUSH_BLOCK(s, 0);
+ }
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of the hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ * At this point we have always match_length < MIN_MATCH
+ */
+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ if (s->strategy != Z_HUFFMAN_ONLY) {
+ s->match_length = longest_match (s, hash_head);
+ }
+ /* longest_match() sets match_start */
+ }
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->match_start, s->match_length);
+
+ _tr_tally_dist(s, s->strstart - s->match_start,
+ s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+
+ /* Insert new strings in the hash table only if the match length
+ * is not too large. This saves time but degrades compression.
+ */
+#ifndef FASTEST
+ if (s->match_length <= s->max_insert_length &&
+ s->lookahead >= MIN_MATCH) {
+ s->match_length--; /* string at strstart already in hash table */
+ do {
+ s->strstart++;
+ INSERT_STRING(s, s->strstart, hash_head);
+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+ * always MIN_MATCH bytes ahead.
+ */
+ } while (--s->match_length != 0);
+ s->strstart++;
+ } else
+#endif
+ {
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+ * matter since it will be recomputed at next deflate call.
+ */
+ }
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ /* Process the input block. */
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ */
+ s->prev_length = s->match_length, s->prev_match = s->match_start;
+ s->match_length = MIN_MATCH-1;
+
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+ s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ if (s->strategy != Z_HUFFMAN_ONLY) {
+ s->match_length = longest_match (s, hash_head);
+ }
+ /* longest_match() sets match_start */
+
+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
+ (s->match_length == MIN_MATCH &&
+ s->strstart - s->match_start > TOO_FAR))) {
+
+ /* If prev_match is also MIN_MATCH, match_start is garbage
+ * but we will ignore the current match anyway.
+ */
+ s->match_length = MIN_MATCH-1;
+ }
+ }
+ /* If there was a match at the previous step and the current
+ * match is not better, output the previous match:
+ */
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+ /* Do not insert strings in hash table beyond this. */
+
+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+ s->prev_length - MIN_MATCH, bflush);
+
+ /* Insert in hash table all strings up to the end of the match.
+ * strstart-1 and strstart are already inserted. If there is not
+ * enough lookahead, the last two strings are not inserted in
+ * the hash table.
+ */
+ s->lookahead -= s->prev_length-1;
+ s->prev_length -= 2;
+ do {
+ if (++s->strstart <= max_insert) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+ } while (--s->prev_length != 0);
+ s->match_available = 0;
+ s->match_length = MIN_MATCH-1;
+ s->strstart++;
+
+ if (bflush) FLUSH_BLOCK(s, 0);
+
+ } else if (s->match_available) {
+ /* If there was no match at the previous position, output a
+ * single literal. If there was a match but the current match
+ * is longer, truncate the previous match to a single literal.
+ */
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ if (bflush) {
+ FLUSH_BLOCK_ONLY(s, 0);
+ }
+ s->strstart++;
+ s->lookahead--;
+ if (s->strm->avail_out == 0) return need_more;
+ } else {
+ /* There is no previous match to compare with, wait for
+ * the next step to decide.
+ */
+ s->match_available = 1;
+ s->strstart++;
+ s->lookahead--;
+ }
+ }
+ Assert (flush != Z_NO_FLUSH, "no flush?");
+ if (s->match_available) {
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ s->match_available = 0;
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
diff --git a/lib/libz/deflate.h b/lib/libz/deflate.h
new file mode 100644
index 0000000..9985288
--- /dev/null
+++ b/lib/libz/deflate.h
@@ -0,0 +1,318 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-1998 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $FreeBSD$ */
+
+#ifndef _DEFLATE_H
+#define _DEFLATE_H
+
+#include "zutil.h"
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS 256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES 30
+/* number of distance codes */
+
+#define BL_CODES 19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE 42
+#define BUSY_STATE 113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+ union {
+ ush freq; /* frequency count */
+ ush code; /* bit string */
+ } fc;
+ union {
+ ush dad; /* father node in Huffman tree */
+ ush len; /* length of bit string */
+ } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad dl.dad
+#define Len dl.len
+
+typedef struct static_tree_desc_s static_tree_desc;
+
+typedef struct tree_desc_s {
+ ct_data *dyn_tree; /* the dynamic tree */
+ int max_code; /* largest code with non zero frequency */
+ static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ int status; /* as the name implies */
+ Bytef *pending_buf; /* output still pending */
+ ulg pending_buf_size; /* size of pending_buf */
+ Bytef *pending_out; /* next pending byte to output to the stream */
+ int pending; /* nb of bytes in the pending buffer */
+ int noheader; /* suppress zlib header and adler32 */
+ Byte data_type; /* UNKNOWN, BINARY or ASCII */
+ Byte method; /* STORED (for zip only) or DEFLATED */
+ int last_flush; /* value of flush param for previous deflate call */
+
+ /* used by deflate.c: */
+
+ uInt w_size; /* LZ77 window size (32K by default) */
+ uInt w_bits; /* log2(w_size) (8..16) */
+ uInt w_mask; /* w_size - 1 */
+
+ Bytef *window;
+ /* Sliding window. Input bytes are read into the second half of the window,
+ * and move to the first half later to keep a dictionary of at least wSize
+ * bytes. With this organization, matches are limited to a distance of
+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
+ * performed with a length multiple of the block size. Also, it limits
+ * the window size to 64K, which is quite useful on MSDOS.
+ * To do: use the user input buffer as sliding window.
+ */
+
+ ulg window_size;
+ /* Actual size of window: 2*wSize, except when the user input buffer
+ * is directly used as sliding window.
+ */
+
+ Posf *prev;
+ /* Link to older string with same hash index. To limit the size of this
+ * array to 64K, this link is maintained only for the last 32K strings.
+ * An index in this array is thus a window index modulo 32K.
+ */
+
+ Posf *head; /* Heads of the hash chains or NIL. */
+
+ uInt ins_h; /* hash index of string to be inserted */
+ uInt hash_size; /* number of elements in hash table */
+ uInt hash_bits; /* log2(hash_size) */
+ uInt hash_mask; /* hash_size-1 */
+
+ uInt hash_shift;
+ /* Number of bits by which ins_h must be shifted at each input
+ * step. It must be such that after MIN_MATCH steps, the oldest
+ * byte no longer takes part in the hash key, that is:
+ * hash_shift * MIN_MATCH >= hash_bits
+ */
+
+ long block_start;
+ /* Window position at the beginning of the current output block. Gets
+ * negative when the window is moved backwards.
+ */
+
+ uInt match_length; /* length of best match */
+ IPos prev_match; /* previous match */
+ int match_available; /* set if previous match exists */
+ uInt strstart; /* start of string to insert */
+ uInt match_start; /* start of matching string */
+ uInt lookahead; /* number of valid bytes ahead in window */
+
+ uInt prev_length;
+ /* Length of the best match at previous step. Matches not greater than this
+ * are discarded. This is used in the lazy match evaluation.
+ */
+
+ uInt max_chain_length;
+ /* To speed up deflation, hash chains are never searched beyond this
+ * length. A higher limit improves compression ratio but degrades the
+ * speed.
+ */
+
+ uInt max_lazy_match;
+ /* Attempt to find a better match only when the current match is strictly
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
+ */
+# define max_insert_length max_lazy_match
+ /* Insert new strings in the hash table only if the match length is not
+ * greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+ int level; /* compression level (1..9) */
+ int strategy; /* favor or force Huffman coding*/
+
+ uInt good_match;
+ /* Use a faster search when the previous match is longer than this */
+
+ int nice_match; /* Stop searching when current match exceeds this */
+
+ /* used by trees.c: */
+ /* Didn't use ct_data typedef below to supress compiler warning */
+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
+
+ struct tree_desc_s l_desc; /* desc. for literal tree */
+ struct tree_desc_s d_desc; /* desc. for distance tree */
+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
+
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
+ int heap_len; /* number of elements in the heap */
+ int heap_max; /* element of largest frequency */
+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ * The same heap array is used to build all trees.
+ */
+
+ uch depth[2*L_CODES+1];
+ /* Depth of each subtree used as tie breaker for trees of equal frequency
+ */
+
+ uchf *l_buf; /* buffer for literals or lengths */
+
+ uInt lit_bufsize;
+ /* Size of match buffer for literals/lengths. There are 4 reasons for
+ * limiting lit_bufsize to 64K:
+ * - frequencies can be kept in 16 bit counters
+ * - if compression is not successful for the first block, all input
+ * data is still in the window so we can still emit a stored block even
+ * when input comes from standard input. (This can also be done for
+ * all blocks if lit_bufsize is not greater than 32K.)
+ * - if compression is not successful for a file smaller than 64K, we can
+ * even emit a stored file instead of a stored block (saving 5 bytes).
+ * This is applicable only for zip (not gzip or zlib).
+ * - creating new Huffman trees less frequently may not provide fast
+ * adaptation to changes in the input data statistics. (Take for
+ * example a binary file with poorly compressible code followed by
+ * a highly compressible string table.) Smaller buffer sizes give
+ * fast adaptation but have of course the overhead of transmitting
+ * trees more frequently.
+ * - I can't count above 4
+ */
+
+ uInt last_lit; /* running index in l_buf */
+
+ ushf *d_buf;
+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
+ * the same number of elements. To use different lengths, an extra flag
+ * array would be necessary.
+ */
+
+ ulg opt_len; /* bit length of current block with optimal trees */
+ ulg static_len; /* bit length of current block with static trees */
+ uInt matches; /* number of string matches in current block */
+ int last_eob_len; /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
+#endif
+
+ ush bi_buf;
+ /* Output buffer. bits are inserted starting at the bottom (least
+ * significant bits).
+ */
+ int bi_valid;
+ /* Number of valid bits in bi_buf. All bits above the last valid bit
+ * are always zero.
+ */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+ /* in trees.c */
+void _tr_init OF((deflate_state *s));
+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+void _tr_align OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+
+#define d_code(dist) \
+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+ extern uch _length_code[];
+ extern uch _dist_code[];
+#else
+ extern const uch _length_code[];
+ extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+ { uch cc = (c); \
+ s->d_buf[s->last_lit] = 0; \
+ s->l_buf[s->last_lit++] = cc; \
+ s->dyn_ltree[cc].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+# define _tr_tally_dist(s, distance, length, flush) \
+ { uch len = (length); \
+ ush dist = (distance); \
+ s->d_buf[s->last_lit] = dist; \
+ s->l_buf[s->last_lit++] = len; \
+ dist--; \
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+ s->dyn_dtree[d_code(dist)].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+ flush = _tr_tally(s, distance, length)
+#endif
+
+#endif
diff --git a/lib/libz/example.c b/lib/libz/example.c
new file mode 100644
index 0000000..045751f
--- /dev/null
+++ b/lib/libz/example.c
@@ -0,0 +1,556 @@
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $FreeBSD$ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+#else
+ extern void exit OF((int));
+#endif
+
+#if defined(VMS) || defined(RISCOS)
+# define TESTFILE "foo-gz"
+#else
+# define TESTFILE "foo.gz"
+#endif
+
+#define CHECK_ERR(err, msg) { \
+ if (err != Z_OK) { \
+ fprintf(stderr, "%s error: %d\n", msg, err); \
+ exit(1); \
+ } \
+}
+
+const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+const char dictionary[] = "hello";
+uLong dictId; /* Adler32 value of the dictionary */
+
+void test_compress OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_gzio OF((const char *out, const char *in,
+ Byte *uncompr, int uncomprLen));
+void test_deflate OF((Byte *compr, uLong comprLen));
+void test_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_flush OF((Byte *compr, uLong *comprLen));
+void test_sync OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate OF((Byte *compr, uLong comprLen));
+void test_dict_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+int main OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ uLong len = strlen(hello)+1;
+
+ err = compress(compr, &comprLen, (const Bytef*)hello, len);
+ CHECK_ERR(err, "compress");
+
+ strcpy((char*)uncompr, "garbage");
+
+ err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+ CHECK_ERR(err, "uncompress");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad uncompress\n");
+ exit(1);
+ } else {
+ printf("uncompress(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(out, in, uncompr, uncomprLen)
+ const char *out; /* compressed output file */
+ const char *in; /* compressed input file */
+ Byte *uncompr;
+ int uncomprLen;
+{
+ int err;
+ int len = strlen(hello)+1;
+ gzFile file;
+ z_off_t pos;
+
+ file = gzopen(out, "wb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ gzputc(file, 'h');
+ if (gzputs(file, "ello") != 4) {
+ fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (gzprintf(file, ", %s!", "hello") != 8) {
+ fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+ gzclose(file);
+
+ file = gzopen(in, "rb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ }
+ strcpy((char*)uncompr, "garbage");
+
+ uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen);
+ if (uncomprLen != len) {
+ fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+ exit(1);
+ } else {
+ printf("gzread(): %s\n", (char *)uncompr);
+ }
+
+ pos = gzseek(file, -8L, SEEK_CUR);
+ if (pos != 6 || gztell(file) != pos) {
+ fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+ (long)pos, (long)gztell(file));
+ exit(1);
+ }
+
+ if (gzgetc(file) != ' ') {
+ fprintf(stderr, "gzgetc error\n");
+ exit(1);
+ }
+
+ gzgets(file, (char*)uncompr, uncomprLen);
+ uncomprLen = strlen((char*)uncompr);
+ if (uncomprLen != 6) { /* "hello!" */
+ fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello+7)) {
+ fprintf(stderr, "bad gzgets after gzseek\n");
+ exit(1);
+ } else {
+ printf("gzgets() after gzseek: %s\n", (char *)uncompr);
+ }
+
+ gzclose(file);
+}
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ int len = strlen(hello)+1;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (Bytef*)hello;
+ c_stream.next_out = compr;
+
+ while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) {
+ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ }
+ /* Finish the stream, still forcing small buffers: */
+ for (;;) {
+ c_stream.avail_out = 1;
+ err = deflate(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "deflate");
+ }
+
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 0;
+ d_stream.next_out = uncompr;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+ d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate\n");
+ exit(1);
+ } else {
+ printf("inflate(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_SPEED);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ /* At this point, uncompr is still mostly zeroes, so it should compress
+ * very well:
+ */
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ if (c_stream.avail_in != 0) {
+ fprintf(stderr, "deflate not greedy\n");
+ exit(1);
+ }
+
+ /* Feed in already compressed data and switch to no compression: */
+ deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+ c_stream.next_in = compr;
+ c_stream.avail_in = (uInt)comprLen/2;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ /* Switch back to compressing mode: */
+ deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ for (;;) {
+ d_stream.next_out = uncompr; /* discard the output */
+ d_stream.avail_out = (uInt)uncomprLen;
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "large inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+ fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+ exit(1);
+ } else {
+ printf("large_inflate(): OK\n");
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+ Byte *compr;
+ uLong *comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ int len = strlen(hello)+1;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (Bytef*)hello;
+ c_stream.next_out = compr;
+ c_stream.avail_in = 3;
+ c_stream.avail_out = (uInt)*comprLen;
+ err = deflate(&c_stream, Z_FULL_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ compr[3]++; /* force an error in first compressed block */
+ c_stream.avail_in = len - 3;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ CHECK_ERR(err, "deflate");
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+
+ *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 2; /* just read the zlib header */
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ inflate(&d_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "inflate");
+
+ d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
+ err = inflateSync(&d_stream); /* but skip the damaged part */
+ CHECK_ERR(err, "inflateSync");
+
+ err = inflate(&d_stream, Z_FINISH);
+ if (err != Z_DATA_ERROR) {
+ fprintf(stderr, "inflate should report DATA_ERROR\n");
+ /* Because of incorrect adler32 */
+ exit(1);
+ }
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ err = deflateSetDictionary(&c_stream,
+ (const Bytef*)dictionary, sizeof(dictionary));
+ CHECK_ERR(err, "deflateSetDictionary");
+
+ dictId = c_stream.adler;
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ c_stream.next_in = (Bytef*)hello;
+ c_stream.avail_in = (uInt)strlen(hello)+1;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ for (;;) {
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ if (err == Z_NEED_DICT) {
+ if (d_stream.adler != dictId) {
+ fprintf(stderr, "unexpected dictionary");
+ exit(1);
+ }
+ err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+ sizeof(dictionary));
+ }
+ CHECK_ERR(err, "inflate with dict");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate with dict\n");
+ exit(1);
+ } else {
+ printf("inflate with dictionary: %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Usage: example [output.gz [input.gz]]
+ */
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ Byte *compr, *uncompr;
+ uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+ uLong uncomprLen = comprLen;
+ static const char* myVersion = ZLIB_VERSION;
+
+ if (zlibVersion()[0] != myVersion[0]) {
+ fprintf(stderr, "incompatible zlib version\n");
+ exit(1);
+
+ } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+ fprintf(stderr, "warning: different zlib version\n");
+ }
+
+ compr = (Byte*)calloc((uInt)comprLen, 1);
+ uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
+ /* compr and uncompr are cleared to avoid reading uninitialized
+ * data and to ensure that uncompr compresses well.
+ */
+ if (compr == Z_NULL || uncompr == Z_NULL) {
+ printf("out of memory\n");
+ exit(1);
+ }
+ test_compress(compr, comprLen, uncompr, uncomprLen);
+
+ test_gzio((argc > 1 ? argv[1] : TESTFILE),
+ (argc > 2 ? argv[2] : TESTFILE),
+ uncompr, (int)uncomprLen);
+
+ test_deflate(compr, comprLen);
+ test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+ test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_flush(compr, &comprLen);
+ test_sync(compr, comprLen, uncompr, uncomprLen);
+ comprLen = uncomprLen;
+
+ test_dict_deflate(compr, comprLen);
+ test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ exit(0);
+ return 0; /* to avoid warning */
+}
diff --git a/lib/libz/gzio.c b/lib/libz/gzio.c
new file mode 100644
index 0000000..8c5d521
--- /dev/null
+++ b/lib/libz/gzio.c
@@ -0,0 +1,875 @@
+/* gzio.c -- IO on .gz files
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Compile this file with -DNO_DEFLATE to avoid the compression code.
+ */
+
+/* @(#) $FreeBSD$ */
+
+#include <stdio.h>
+
+#include "zutil.h"
+
+struct internal_state {int dummy;}; /* for buggy compilers */
+
+#ifndef Z_BUFSIZE
+# ifdef MAXSEG_64K
+# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
+# else
+# define Z_BUFSIZE 16384
+# endif
+#endif
+#ifndef Z_PRINTF_BUFSIZE
+# define Z_PRINTF_BUFSIZE 4096
+#endif
+
+#define ALLOC(size) malloc(size)
+#define TRYFREE(p) {if (p) free(p);}
+
+static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define RESERVED 0xE0 /* bits 5..7: reserved */
+
+typedef struct gz_stream {
+ z_stream stream;
+ int z_err; /* error code for last stream operation */
+ int z_eof; /* set if end of input file */
+ FILE *file; /* .gz file */
+ Byte *inbuf; /* input buffer */
+ Byte *outbuf; /* output buffer */
+ uLong crc; /* crc32 of uncompressed data */
+ char *msg; /* error message */
+ char *path; /* path name for debugging only */
+ int transparent; /* 1 if input file is not a .gz file */
+ char mode; /* 'w' or 'r' */
+ long startpos; /* start of compressed data in file (header skipped) */
+} gz_stream;
+
+
+local gzFile gz_open OF((const char *path, const char *mode, int fd));
+local int do_flush OF((gzFile file, int flush));
+local int get_byte OF((gz_stream *s));
+local void check_header OF((gz_stream *s));
+local int destroy OF((gz_stream *s));
+local void putLong OF((FILE *file, uLong x));
+local uLong getLong OF((gz_stream *s));
+
+/* ===========================================================================
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb"). The file is given either by file descriptor
+ or path name (if fd == -1).
+ gz_open return NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR).
+*/
+local gzFile gz_open (path, mode, fd)
+ const char *path;
+ const char *mode;
+ int fd;
+{
+ int err;
+ int level = Z_DEFAULT_COMPRESSION; /* compression level */
+ int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
+ char *p = (char*)mode;
+ gz_stream *s;
+ char fmode[80]; /* copy of mode, without the compression level */
+ char *m = fmode;
+
+ if (!path || !mode) return Z_NULL;
+
+ s = (gz_stream *)ALLOC(sizeof(gz_stream));
+ if (!s) return Z_NULL;
+
+ s->stream.zalloc = (alloc_func)0;
+ s->stream.zfree = (free_func)0;
+ s->stream.opaque = (voidpf)0;
+ s->stream.next_in = s->inbuf = Z_NULL;
+ s->stream.next_out = s->outbuf = Z_NULL;
+ s->stream.avail_in = s->stream.avail_out = 0;
+ s->file = NULL;
+ s->z_err = Z_OK;
+ s->z_eof = 0;
+ s->crc = crc32(0L, Z_NULL, 0);
+ s->msg = NULL;
+ s->transparent = 0;
+
+ s->path = (char*)ALLOC(strlen(path)+1);
+ if (s->path == NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ strcpy(s->path, path); /* do this early for debugging */
+
+ s->mode = '\0';
+ do {
+ if (*p == 'r') s->mode = 'r';
+ if (*p == 'w' || *p == 'a') s->mode = 'w';
+ if (*p >= '0' && *p <= '9') {
+ level = *p - '0';
+ } else if (*p == 'f') {
+ strategy = Z_FILTERED;
+ } else if (*p == 'h') {
+ strategy = Z_HUFFMAN_ONLY;
+ } else {
+ *m++ = *p; /* copy the mode */
+ }
+ } while (*p++ && m != fmode + sizeof(fmode));
+ if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
+
+ if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+ err = Z_STREAM_ERROR;
+#else
+ err = deflateInit2(&(s->stream), level,
+ Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
+ /* windowBits is passed < 0 to suppress zlib header */
+
+ s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+#endif
+ if (err != Z_OK || s->outbuf == Z_NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ } else {
+ s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
+
+ err = inflateInit2(&(s->stream), -MAX_WBITS);
+ /* windowBits is passed < 0 to tell that there is no zlib header.
+ * Note that in this case inflate *requires* an extra "dummy" byte
+ * after the compressed stream in order to complete decompression and
+ * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
+ * present after the compressed stream.
+ */
+ if (err != Z_OK || s->inbuf == Z_NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+
+ errno = 0;
+ s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
+
+ if (s->file == NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ if (s->mode == 'w') {
+ /* Write a very simple .gz header:
+ */
+ fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
+ Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
+ s->startpos = 10L;
+ /* We use 10L instead of ftell(s->file) to because ftell causes an
+ * fflush on some systems. This version of the library doesn't use
+ * startpos anyway in write mode, so this initialization is not
+ * necessary.
+ */
+ } else {
+ check_header(s); /* skip the .gz header */
+ s->startpos = (ftell(s->file) - s->stream.avail_in);
+ }
+
+ return (gzFile)s;
+}
+
+/* ===========================================================================
+ Opens a gzip (.gz) file for reading or writing.
+*/
+gzFile ZEXPORT gzopen (path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open (path, mode, -1);
+}
+
+/* ===========================================================================
+ Associate a gzFile with the file descriptor fd. fd is not dup'ed here
+ to mimic the behavio(u)r of fdopen.
+*/
+gzFile ZEXPORT gzdopen (fd, mode)
+ int fd;
+ const char *mode;
+{
+ char name[20];
+
+ if (fd < 0) return (gzFile)Z_NULL;
+ sprintf(name, "<fd:%d>", fd); /* for debugging */
+
+ return gz_open (name, mode, fd);
+}
+
+/* ===========================================================================
+ * Update the compression level and strategy
+ */
+int ZEXPORT gzsetparams (file, level, strategy)
+ gzFile file;
+ int level;
+ int strategy;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ /* Make room to allow flushing */
+ if (s->stream.avail_out == 0) {
+
+ s->stream.next_out = s->outbuf;
+ if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+ s->z_err = Z_ERRNO;
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+
+ return deflateParams (&(s->stream), level, strategy);
+}
+
+/* ===========================================================================
+ Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+ for end of file.
+ IN assertion: the stream s has been sucessfully opened for reading.
+*/
+local int get_byte(s)
+ gz_stream *s;
+{
+ if (s->z_eof) return EOF;
+ if (s->stream.avail_in == 0) {
+ errno = 0;
+ s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+ if (s->stream.avail_in == 0) {
+ s->z_eof = 1;
+ if (ferror(s->file)) s->z_err = Z_ERRNO;
+ return EOF;
+ }
+ s->stream.next_in = s->inbuf;
+ }
+ s->stream.avail_in--;
+ return *(s->stream.next_in)++;
+}
+
+/* ===========================================================================
+ Check the gzip header of a gz_stream opened for reading. Set the stream
+ mode to transparent if the gzip magic header is not present; set s->err
+ to Z_DATA_ERROR if the magic header is present but the rest of the header
+ is incorrect.
+ IN assertion: the stream s has already been created sucessfully;
+ s->stream.avail_in is zero for the first time, but may be non-zero
+ for concatenated .gz files.
+*/
+local void check_header(s)
+ gz_stream *s;
+{
+ int method; /* method byte */
+ int flags; /* flags byte */
+ uInt len;
+ int c;
+
+ /* Check the gzip magic header */
+ for (len = 0; len < 2; len++) {
+ c = get_byte(s);
+ if (c != gz_magic[len]) {
+ if (len != 0) s->stream.avail_in++, s->stream.next_in--;
+ if (c != EOF) {
+ s->stream.avail_in++, s->stream.next_in--;
+ s->transparent = 1;
+ }
+ s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
+ return;
+ }
+ }
+ method = get_byte(s);
+ flags = get_byte(s);
+ if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+ s->z_err = Z_DATA_ERROR;
+ return;
+ }
+
+ /* Discard time, xflags and OS code: */
+ for (len = 0; len < 6; len++) (void)get_byte(s);
+
+ if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+ len = (uInt)get_byte(s);
+ len += ((uInt)get_byte(s))<<8;
+ /* len is garbage if EOF but the loop below will quit anyway */
+ while (len-- != 0 && get_byte(s) != EOF) ;
+ }
+ if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+ while ((c = get_byte(s)) != 0 && c != EOF) ;
+ }
+ if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
+ while ((c = get_byte(s)) != 0 && c != EOF) ;
+ }
+ if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
+ for (len = 0; len < 2; len++) (void)get_byte(s);
+ }
+ s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
+}
+
+ /* ===========================================================================
+ * Cleanup then free the given gz_stream. Return a zlib error code.
+ Try freeing in the reverse order of allocations.
+ */
+local int destroy (s)
+ gz_stream *s;
+{
+ int err = Z_OK;
+
+ if (!s) return Z_STREAM_ERROR;
+
+ TRYFREE(s->msg);
+
+ if (s->stream.state != NULL) {
+ if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+ err = Z_STREAM_ERROR;
+#else
+ err = deflateEnd(&(s->stream));
+#endif
+ } else if (s->mode == 'r') {
+ err = inflateEnd(&(s->stream));
+ }
+ }
+ if (s->file != NULL && fclose(s->file)) {
+#ifdef ESPIPE
+ if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
+#endif
+ err = Z_ERRNO;
+ }
+ if (s->z_err < 0) err = s->z_err;
+
+ TRYFREE(s->inbuf);
+ TRYFREE(s->outbuf);
+ TRYFREE(s->path);
+ TRYFREE(s);
+ return err;
+}
+
+/* ===========================================================================
+ Reads the given number of uncompressed bytes from the compressed file.
+ gzread returns the number of bytes actually read (0 for end of file).
+*/
+int ZEXPORT gzread (file, buf, len)
+ gzFile file;
+ voidp buf;
+ unsigned len;
+{
+ gz_stream *s = (gz_stream*)file;
+ Bytef *start = (Bytef*)buf; /* starting point for crc computation */
+ Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
+
+ if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
+
+ if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
+ if (s->z_err == Z_STREAM_END) return 0; /* EOF */
+
+ next_out = (Byte*)buf;
+ s->stream.next_out = (Bytef*)buf;
+ s->stream.avail_out = len;
+
+ while (s->stream.avail_out != 0) {
+
+ if (s->transparent) {
+ /* Copy first the lookahead bytes: */
+ uInt n = s->stream.avail_in;
+ if (n > s->stream.avail_out) n = s->stream.avail_out;
+ if (n > 0) {
+ zmemcpy(s->stream.next_out, s->stream.next_in, n);
+ next_out += n;
+ s->stream.next_out = next_out;
+ s->stream.next_in += n;
+ s->stream.avail_out -= n;
+ s->stream.avail_in -= n;
+ }
+ if (s->stream.avail_out > 0) {
+ s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
+ s->file);
+ }
+ len -= s->stream.avail_out;
+ s->stream.total_in += (uLong)len;
+ s->stream.total_out += (uLong)len;
+ if (len == 0) s->z_eof = 1;
+ return (int)len;
+ }
+ if (s->stream.avail_in == 0 && !s->z_eof) {
+
+ errno = 0;
+ s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+ if (s->stream.avail_in == 0) {
+ s->z_eof = 1;
+ if (ferror(s->file)) {
+ s->z_err = Z_ERRNO;
+ break;
+ }
+ }
+ s->stream.next_in = s->inbuf;
+ }
+ s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
+
+ if (s->z_err == Z_STREAM_END) {
+ /* Check CRC and original size */
+ s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+ start = s->stream.next_out;
+
+ if (getLong(s) != s->crc) {
+ s->z_err = Z_DATA_ERROR;
+ } else {
+ (void)getLong(s);
+ /* The uncompressed length returned by above getlong() may
+ * be different from s->stream.total_out) in case of
+ * concatenated .gz files. Check for such files:
+ */
+ check_header(s);
+ if (s->z_err == Z_OK) {
+ uLong total_in = s->stream.total_in;
+ uLong total_out = s->stream.total_out;
+
+ inflateReset(&(s->stream));
+ s->stream.total_in = total_in;
+ s->stream.total_out = total_out;
+ s->crc = crc32(0L, Z_NULL, 0);
+ }
+ }
+ }
+ if (s->z_err != Z_OK || s->z_eof) break;
+ }
+ s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+
+ return (int)(len - s->stream.avail_out);
+}
+
+
+/* ===========================================================================
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+int ZEXPORT gzgetc(file)
+ gzFile file;
+{
+ unsigned char c;
+
+ return gzread(file, &c, 1) == 1 ? c : -1;
+}
+
+
+/* ===========================================================================
+ Reads bytes from the compressed file until len-1 characters are
+ read, or a newline character is read and transferred to buf, or an
+ end-of-file condition is encountered. The string is then terminated
+ with a null character.
+ gzgets returns buf, or Z_NULL in case of error.
+
+ The current implementation is not optimized at all.
+*/
+char * ZEXPORT gzgets(file, buf, len)
+ gzFile file;
+ char *buf;
+ int len;
+{
+ char *b = buf;
+ if (buf == Z_NULL || len <= 0) return Z_NULL;
+
+ while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
+ *buf = '\0';
+ return b == buf && len > 0 ? Z_NULL : b;
+}
+
+
+#ifndef NO_DEFLATE
+/* ===========================================================================
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of bytes actually written (0 in case of error).
+*/
+int ZEXPORT gzwrite (file, buf, len)
+ gzFile file;
+ const voidp buf;
+ unsigned len;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ s->stream.next_in = (Bytef*)buf;
+ s->stream.avail_in = len;
+
+ while (s->stream.avail_in != 0) {
+
+ if (s->stream.avail_out == 0) {
+
+ s->stream.next_out = s->outbuf;
+ if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+ s->z_err = Z_ERRNO;
+ break;
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+ s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
+ if (s->z_err != Z_OK) break;
+ }
+ s->crc = crc32(s->crc, (const Bytef *)buf, len);
+
+ return (int)(len - s->stream.avail_in);
+}
+
+/* ===========================================================================
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error).
+*/
+#ifdef STDC
+#include <stdarg.h>
+
+int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
+{
+ char buf[Z_PRINTF_BUFSIZE];
+ va_list va;
+ int len;
+
+ va_start(va, format);
+#ifdef HAS_vsnprintf
+ (void)vsnprintf(buf, sizeof(buf), format, va);
+#else
+ (void)vsprintf(buf, format, va);
+#endif
+ va_end(va);
+ len = strlen(buf); /* some *sprintf don't return the nb of bytes written */
+ if (len <= 0) return 0;
+
+ return gzwrite(file, buf, (unsigned)len);
+}
+#else /* not ANSI C */
+
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+ gzFile file;
+ const char *format;
+ int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+ char buf[Z_PRINTF_BUFSIZE];
+ int len;
+
+#ifdef HAS_snprintf
+ snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#else
+ sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#endif
+ len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */
+ if (len <= 0) return 0;
+
+ return gzwrite(file, buf, len);
+}
+#endif
+
+/* ===========================================================================
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+int ZEXPORT gzputc(file, c)
+ gzFile file;
+ int c;
+{
+ unsigned char cc = (unsigned char) c; /* required for big endian systems */
+
+ return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
+}
+
+
+/* ===========================================================================
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+int ZEXPORT gzputs(file, s)
+ gzFile file;
+ const char *s;
+{
+ return gzwrite(file, (char*)s, (unsigned)strlen(s));
+}
+
+
+/* ===========================================================================
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function.
+*/
+local int do_flush (file, flush)
+ gzFile file;
+ int flush;
+{
+ uInt len;
+ int done = 0;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ s->stream.avail_in = 0; /* should be zero already anyway */
+
+ for (;;) {
+ len = Z_BUFSIZE - s->stream.avail_out;
+
+ if (len != 0) {
+ if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
+ s->z_err = Z_ERRNO;
+ return Z_ERRNO;
+ }
+ s->stream.next_out = s->outbuf;
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+ if (done) break;
+ s->z_err = deflate(&(s->stream), flush);
+
+ /* Ignore the second of two consecutive flushes: */
+ if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
+
+ /* deflate has finished flushing only when it hasn't used up
+ * all the available space in the output buffer:
+ */
+ done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
+
+ if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
+ }
+ return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+
+int ZEXPORT gzflush (file, flush)
+ gzFile file;
+ int flush;
+{
+ gz_stream *s = (gz_stream*)file;
+ int err = do_flush (file, flush);
+
+ if (err) return err;
+ fflush(s->file);
+ return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+#endif /* NO_DEFLATE */
+
+/* ===========================================================================
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error.
+ SEEK_END is not implemented, returns error.
+ In this version of the library, gzseek can be extremely slow.
+*/
+z_off_t ZEXPORT gzseek (file, offset, whence)
+ gzFile file;
+ z_off_t offset;
+ int whence;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || whence == SEEK_END ||
+ s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
+ return -1L;
+ }
+
+ if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+ return -1L;
+#else
+ if (whence == SEEK_SET) {
+ offset -= s->stream.total_in;
+ }
+ if (offset < 0) return -1L;
+
+ /* At this point, offset is the number of zero bytes to write. */
+ if (s->inbuf == Z_NULL) {
+ s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
+ zmemzero(s->inbuf, Z_BUFSIZE);
+ }
+ while (offset > 0) {
+ uInt size = Z_BUFSIZE;
+ if (offset < Z_BUFSIZE) size = (uInt)offset;
+
+ size = gzwrite(file, s->inbuf, size);
+ if (size == 0) return -1L;
+
+ offset -= size;
+ }
+ return (z_off_t)s->stream.total_in;
+#endif
+ }
+ /* Rest of function is for reading only */
+
+ /* compute absolute position */
+ if (whence == SEEK_CUR) {
+ offset += s->stream.total_out;
+ }
+ if (offset < 0) return -1L;
+
+ if (s->transparent) {
+ /* map to fseek */
+ s->stream.avail_in = 0;
+ s->stream.next_in = s->inbuf;
+ if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
+
+ s->stream.total_in = s->stream.total_out = (uLong)offset;
+ return offset;
+ }
+
+ /* For a negative seek, rewind and use positive seek */
+ if ((uLong)offset >= s->stream.total_out) {
+ offset -= s->stream.total_out;
+ } else if (gzrewind(file) < 0) {
+ return -1L;
+ }
+ /* offset is now the number of bytes to skip. */
+
+ if (offset != 0 && s->outbuf == Z_NULL) {
+ s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+ }
+ while (offset > 0) {
+ int size = Z_BUFSIZE;
+ if (offset < Z_BUFSIZE) size = (int)offset;
+
+ size = gzread(file, s->outbuf, (uInt)size);
+ if (size <= 0) return -1L;
+ offset -= size;
+ }
+ return (z_off_t)s->stream.total_out;
+}
+
+/* ===========================================================================
+ Rewinds input file.
+*/
+int ZEXPORT gzrewind (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'r') return -1;
+
+ s->z_err = Z_OK;
+ s->z_eof = 0;
+ s->stream.avail_in = 0;
+ s->stream.next_in = s->inbuf;
+ s->crc = crc32(0L, Z_NULL, 0);
+
+ if (s->startpos == 0) { /* not a compressed file */
+ rewind(s->file);
+ return 0;
+ }
+
+ (void) inflateReset(&s->stream);
+ return fseek(s->file, s->startpos, SEEK_SET);
+}
+
+/* ===========================================================================
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+*/
+z_off_t ZEXPORT gztell (file)
+ gzFile file;
+{
+ return gzseek(file, 0L, SEEK_CUR);
+}
+
+/* ===========================================================================
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+int ZEXPORT gzeof (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ return (s == NULL || s->mode != 'r') ? 0 : s->z_eof;
+}
+
+/* ===========================================================================
+ Outputs a long in LSB order to the given file
+*/
+local void putLong (file, x)
+ FILE *file;
+ uLong x;
+{
+ int n;
+ for (n = 0; n < 4; n++) {
+ fputc((int)(x & 0xff), file);
+ x >>= 8;
+ }
+}
+
+/* ===========================================================================
+ Reads a long in LSB order from the given gz_stream. Sets z_err in case
+ of error.
+*/
+local uLong getLong (s)
+ gz_stream *s;
+{
+ uLong x = (uLong)get_byte(s);
+ int c;
+
+ x += ((uLong)get_byte(s))<<8;
+ x += ((uLong)get_byte(s))<<16;
+ c = get_byte(s);
+ if (c == EOF) s->z_err = Z_DATA_ERROR;
+ x += ((uLong)c)<<24;
+ return x;
+}
+
+/* ===========================================================================
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state.
+*/
+int ZEXPORT gzclose (file)
+ gzFile file;
+{
+ int err;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) return Z_STREAM_ERROR;
+
+ if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+ return Z_STREAM_ERROR;
+#else
+ err = do_flush (file, Z_FINISH);
+ if (err != Z_OK) return destroy((gz_stream*)file);
+
+ putLong (s->file, s->crc);
+ putLong (s->file, s->stream.total_in);
+#endif
+ }
+ return destroy((gz_stream*)file);
+}
+
+/* ===========================================================================
+ Returns the error message for the last error which occured on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occured in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+const char* ZEXPORT gzerror (file, errnum)
+ gzFile file;
+ int *errnum;
+{
+ char *m;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) {
+ *errnum = Z_STREAM_ERROR;
+ return (const char*)ERR_MSG(Z_STREAM_ERROR);
+ }
+ *errnum = s->z_err;
+ if (*errnum == Z_OK) return (const char*)"";
+
+ m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
+
+ if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
+
+ TRYFREE(s->msg);
+ s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
+ strcpy(s->msg, s->path);
+ strcat(s->msg, ": ");
+ strcat(s->msg, m);
+ return (const char*)s->msg;
+}
diff --git a/lib/libz/infblock.c b/lib/libz/infblock.c
new file mode 100644
index 0000000..f4920fa
--- /dev/null
+++ b/lib/libz/infblock.c
@@ -0,0 +1,398 @@
+/* infblock.c -- interpret and process block types to last block
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* Table for deflate from PKZIP's appnote.txt. */
+local const uInt border[] = { /* Order of the bit length code lengths */
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/*
+ Notes beyond the 1.93a appnote.txt:
+
+ 1. Distance pointers never point before the beginning of the output
+ stream.
+ 2. Distance pointers can point back across blocks, up to 32k away.
+ 3. There is an implied maximum of 7 bits for the bit length table and
+ 15 bits for the actual data.
+ 4. If only one code exists, then it is encoded using one bit. (Zero
+ would be more efficient, but perhaps a little confusing.) If two
+ codes exist, they are coded using one bit each (0 and 1).
+ 5. There is no way of sending zero distance codes--a dummy must be
+ sent if there are none. (History: a pre 2.0 version of PKZIP would
+ store blocks with no distance codes, but this was discovered to be
+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
+ zero distance codes, which is sent as one code of zero bits in
+ length.
+ 6. There are up to 286 literal/length codes. Code 256 represents the
+ end-of-block. Note however that the static length tree defines
+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
+ cannot be used though, since there is no length base or extra bits
+ defined for them. Similarily, there are up to 30 distance codes.
+ However, static trees define 32 codes (all 5 bits) to fill out the
+ Huffman codes, but the last two had better not show up in the data.
+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
+ The exception is that a single code would not be complete (see #4).
+ 8. The five bits following the block type is really the number of
+ literal codes sent minus 257.
+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+ (1+6+6). Therefore, to output three times the length, you output
+ three codes (1+1+1), whereas to output four times the same length,
+ you only need two codes (1+3). Hmm.
+ 10. In the tree reconstruction algorithm, Code = Code + Increment
+ only if BitLength(i) is not zero. (Pretty obvious.)
+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
+ 12. Note: length code 284 can represent 227-258, but length code 285
+ really is 258. The last length deserves its own, short code
+ since it gets used a lot in very redundant files. The length
+ 258 is special since 258 - 3 (the min match length) is 255.
+ 13. The literal/length and distance code bit lengths are read as a
+ single stream of lengths. It is possible (and advantageous) for
+ a repeat code (16, 17, or 18) to go across the boundary between
+ the two sets of lengths.
+ */
+
+
+void inflate_blocks_reset(s, z, c)
+inflate_blocks_statef *s;
+z_streamp z;
+uLongf *c;
+{
+ if (c != Z_NULL)
+ *c = s->check;
+ if (s->mode == BTREE || s->mode == DTREE)
+ ZFREE(z, s->sub.trees.blens);
+ if (s->mode == CODES)
+ inflate_codes_free(s->sub.decode.codes, z);
+ s->mode = TYPE;
+ s->bitk = 0;
+ s->bitb = 0;
+ s->read = s->write = s->window;
+ if (s->checkfn != Z_NULL)
+ z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
+ Tracev((stderr, "inflate: blocks reset\n"));
+}
+
+
+inflate_blocks_statef *inflate_blocks_new(z, c, w)
+z_streamp z;
+check_func c;
+uInt w;
+{
+ inflate_blocks_statef *s;
+
+ if ((s = (inflate_blocks_statef *)ZALLOC
+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
+ return s;
+ if ((s->hufts =
+ (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
+ {
+ ZFREE(z, s);
+ return Z_NULL;
+ }
+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
+ {
+ ZFREE(z, s->hufts);
+ ZFREE(z, s);
+ return Z_NULL;
+ }
+ s->end = s->window + w;
+ s->checkfn = c;
+ s->mode = TYPE;
+ Tracev((stderr, "inflate: blocks allocated\n"));
+ inflate_blocks_reset(s, z, Z_NULL);
+ return s;
+}
+
+
+int inflate_blocks(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+ uInt t; /* temporary storage */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+
+ /* copy input/output information to locals (UPDATE macro restores) */
+ LOAD
+
+ /* process input based on current state */
+ while (1) switch (s->mode)
+ {
+ case TYPE:
+ NEEDBITS(3)
+ t = (uInt)b & 7;
+ s->last = t & 1;
+ switch (t >> 1)
+ {
+ case 0: /* stored */
+ Tracev((stderr, "inflate: stored block%s\n",
+ s->last ? " (last)" : ""));
+ DUMPBITS(3)
+ t = k & 7; /* go to byte boundary */
+ DUMPBITS(t)
+ s->mode = LENS; /* get length of stored block */
+ break;
+ case 1: /* fixed */
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ s->last ? " (last)" : ""));
+ {
+ uInt bl, bd;
+ inflate_huft *tl, *td;
+
+ inflate_trees_fixed(&bl, &bd, &tl, &td, z);
+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
+ if (s->sub.decode.codes == Z_NULL)
+ {
+ r = Z_MEM_ERROR;
+ LEAVE
+ }
+ }
+ DUMPBITS(3)
+ s->mode = CODES;
+ break;
+ case 2: /* dynamic */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ s->last ? " (last)" : ""));
+ DUMPBITS(3)
+ s->mode = TABLE;
+ break;
+ case 3: /* illegal */
+ DUMPBITS(3)
+ s->mode = BAD;
+ z->msg = (char*)"invalid block type";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+ break;
+ case LENS:
+ NEEDBITS(32)
+ if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
+ {
+ s->mode = BAD;
+ z->msg = (char*)"invalid stored block lengths";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+ s->sub.left = (uInt)b & 0xffff;
+ b = k = 0; /* dump bits */
+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
+ s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
+ break;
+ case STORED:
+ if (n == 0)
+ LEAVE
+ NEEDOUT
+ t = s->sub.left;
+ if (t > n) t = n;
+ if (t > m) t = m;
+ zmemcpy(q, p, t);
+ p += t; n -= t;
+ q += t; m -= t;
+ if ((s->sub.left -= t) != 0)
+ break;
+ Tracev((stderr, "inflate: stored end, %lu total out\n",
+ z->total_out + (q >= s->read ? q - s->read :
+ (s->end - s->read) + (q - s->window))));
+ s->mode = s->last ? DRY : TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14)
+ s->sub.trees.table = t = (uInt)b & 0x3fff;
+#ifndef PKZIP_BUG_WORKAROUND
+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+ {
+ s->mode = BAD;
+ z->msg = (char*)"too many length or distance symbols";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+#endif
+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
+ {
+ r = Z_MEM_ERROR;
+ LEAVE
+ }
+ DUMPBITS(14)
+ s->sub.trees.index = 0;
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ s->mode = BTREE;
+ case BTREE:
+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+ {
+ NEEDBITS(3)
+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
+ DUMPBITS(3)
+ }
+ while (s->sub.trees.index < 19)
+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
+ s->sub.trees.bb = 7;
+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
+ &s->sub.trees.tb, s->hufts, z);
+ if (t != Z_OK)
+ {
+ ZFREE(z, s->sub.trees.blens);
+ r = t;
+ if (r == Z_DATA_ERROR)
+ s->mode = BAD;
+ LEAVE
+ }
+ s->sub.trees.index = 0;
+ Tracev((stderr, "inflate: bits tree ok\n"));
+ s->mode = DTREE;
+ case DTREE:
+ while (t = s->sub.trees.table,
+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+ {
+ inflate_huft *h;
+ uInt i, j, c;
+
+ t = s->sub.trees.bb;
+ NEEDBITS(t)
+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
+ t = h->bits;
+ c = h->base;
+ if (c < 16)
+ {
+ DUMPBITS(t)
+ s->sub.trees.blens[s->sub.trees.index++] = c;
+ }
+ else /* c == 16..18 */
+ {
+ i = c == 18 ? 7 : c - 14;
+ j = c == 18 ? 11 : 3;
+ NEEDBITS(t + i)
+ DUMPBITS(t)
+ j += (uInt)b & inflate_mask[i];
+ DUMPBITS(i)
+ i = s->sub.trees.index;
+ t = s->sub.trees.table;
+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+ (c == 16 && i < 1))
+ {
+ ZFREE(z, s->sub.trees.blens);
+ s->mode = BAD;
+ z->msg = (char*)"invalid bit length repeat";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
+ do {
+ s->sub.trees.blens[i++] = c;
+ } while (--j);
+ s->sub.trees.index = i;
+ }
+ }
+ s->sub.trees.tb = Z_NULL;
+ {
+ uInt bl, bd;
+ inflate_huft *tl, *td;
+ inflate_codes_statef *c;
+
+ bl = 9; /* must be <= 9 for lookahead assumptions */
+ bd = 6; /* must be <= 9 for lookahead assumptions */
+ t = s->sub.trees.table;
+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
+ s->sub.trees.blens, &bl, &bd, &tl, &td,
+ s->hufts, z);
+ ZFREE(z, s->sub.trees.blens);
+ if (t != Z_OK)
+ {
+ if (t == (uInt)Z_DATA_ERROR)
+ s->mode = BAD;
+ r = t;
+ LEAVE
+ }
+ Tracev((stderr, "inflate: trees ok\n"));
+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
+ {
+ r = Z_MEM_ERROR;
+ LEAVE
+ }
+ s->sub.decode.codes = c;
+ }
+ s->mode = CODES;
+ case CODES:
+ UPDATE
+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
+ return inflate_flush(s, z, r);
+ r = Z_OK;
+ inflate_codes_free(s->sub.decode.codes, z);
+ LOAD
+ Tracev((stderr, "inflate: codes end, %lu total out\n",
+ z->total_out + (q >= s->read ? q - s->read :
+ (s->end - s->read) + (q - s->window))));
+ if (!s->last)
+ {
+ s->mode = TYPE;
+ break;
+ }
+ s->mode = DRY;
+ case DRY:
+ FLUSH
+ if (s->read != s->write)
+ LEAVE
+ s->mode = DONE;
+ case DONE:
+ r = Z_STREAM_END;
+ LEAVE
+ case BAD:
+ r = Z_DATA_ERROR;
+ LEAVE
+ default:
+ r = Z_STREAM_ERROR;
+ LEAVE
+ }
+}
+
+
+int inflate_blocks_free(s, z)
+inflate_blocks_statef *s;
+z_streamp z;
+{
+ inflate_blocks_reset(s, z, Z_NULL);
+ ZFREE(z, s->window);
+ ZFREE(z, s->hufts);
+ ZFREE(z, s);
+ Tracev((stderr, "inflate: blocks freed\n"));
+ return Z_OK;
+}
+
+
+void inflate_set_dictionary(s, d, n)
+inflate_blocks_statef *s;
+const Bytef *d;
+uInt n;
+{
+ zmemcpy(s->window, d, n);
+ s->read = s->write = s->window + n;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
+ * IN assertion: s != Z_NULL
+ */
+int inflate_blocks_sync_point(s)
+inflate_blocks_statef *s;
+{
+ return s->mode == LENS;
+}
diff --git a/lib/libz/infblock.h b/lib/libz/infblock.h
new file mode 100644
index 0000000..bd25c80
--- /dev/null
+++ b/lib/libz/infblock.h
@@ -0,0 +1,39 @@
+/* infblock.h -- header to use infblock.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_blocks_state;
+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+
+extern inflate_blocks_statef * inflate_blocks_new OF((
+ z_streamp z,
+ check_func c, /* check function */
+ uInt w)); /* window size */
+
+extern int inflate_blocks OF((
+ inflate_blocks_statef *,
+ z_streamp ,
+ int)); /* initial return code */
+
+extern void inflate_blocks_reset OF((
+ inflate_blocks_statef *,
+ z_streamp ,
+ uLongf *)); /* check value on output */
+
+extern int inflate_blocks_free OF((
+ inflate_blocks_statef *,
+ z_streamp));
+
+extern void inflate_set_dictionary OF((
+ inflate_blocks_statef *s,
+ const Bytef *d, /* dictionary */
+ uInt n)); /* dictionary length */
+
+extern int inflate_blocks_sync_point OF((
+ inflate_blocks_statef *s));
diff --git a/lib/libz/infcodes.c b/lib/libz/infcodes.c
new file mode 100644
index 0000000..d4e5ee9
--- /dev/null
+++ b/lib/libz/infcodes.c
@@ -0,0 +1,257 @@
+/* infcodes.c -- process literals and length/distance pairs
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infblock.h"
+#include "infcodes.h"
+#include "infutil.h"
+#include "inffast.h"
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+ START, /* x: set up for LEN */
+ LEN, /* i: get length/literal/eob next */
+ LENEXT, /* i: getting length extra (have base) */
+ DIST, /* i: get distance next */
+ DISTEXT, /* i: getting distance extra */
+ COPY, /* o: copying bytes in window, waiting for space */
+ LIT, /* o: got literal, waiting for output space */
+ WASH, /* o: got eob, possibly still output waiting */
+ END, /* x: got eob and all data flushed */
+ BADCODE} /* x: got error */
+inflate_codes_mode;
+
+/* inflate codes private state */
+struct inflate_codes_state {
+
+ /* mode */
+ inflate_codes_mode mode; /* current inflate_codes mode */
+
+ /* mode dependent information */
+ uInt len;
+ union {
+ struct {
+ inflate_huft *tree; /* pointer into tree */
+ uInt need; /* bits needed */
+ } code; /* if LEN or DIST, where in tree */
+ uInt lit; /* if LIT, literal */
+ struct {
+ uInt get; /* bits to get for extra */
+ uInt dist; /* distance back to copy from */
+ } copy; /* if EXT or COPY, where and how much */
+ } sub; /* submode */
+
+ /* mode independent information */
+ Byte lbits; /* ltree bits decoded per branch */
+ Byte dbits; /* dtree bits decoder per branch */
+ inflate_huft *ltree; /* literal/length/eob tree */
+ inflate_huft *dtree; /* distance tree */
+
+};
+
+
+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+z_streamp z;
+{
+ inflate_codes_statef *c;
+
+ if ((c = (inflate_codes_statef *)
+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
+ {
+ c->mode = START;
+ c->lbits = (Byte)bl;
+ c->dbits = (Byte)bd;
+ c->ltree = tl;
+ c->dtree = td;
+ Tracev((stderr, "inflate: codes new\n"));
+ }
+ return c;
+}
+
+
+int inflate_codes(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+ uInt j; /* temporary storage */
+ inflate_huft *t; /* temporary pointer */
+ uInt e; /* extra bits or operation */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+ Bytef *f; /* pointer to copy strings from */
+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
+
+ /* copy input/output information to locals (UPDATE macro restores) */
+ LOAD
+
+ /* process input and output based on current state */
+ while (1) switch (c->mode)
+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+ case START: /* x: set up for LEN */
+#ifndef SLOW
+ if (m >= 258 && n >= 10)
+ {
+ UPDATE
+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
+ LOAD
+ if (r != Z_OK)
+ {
+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
+ break;
+ }
+ }
+#endif /* !SLOW */
+ c->sub.code.need = c->lbits;
+ c->sub.code.tree = c->ltree;
+ c->mode = LEN;
+ case LEN: /* i: get length/literal/eob next */
+ j = c->sub.code.need;
+ NEEDBITS(j)
+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+ DUMPBITS(t->bits)
+ e = (uInt)(t->exop);
+ if (e == 0) /* literal */
+ {
+ c->sub.lit = t->base;
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", t->base));
+ c->mode = LIT;
+ break;
+ }
+ if (e & 16) /* length */
+ {
+ c->sub.copy.get = e & 15;
+ c->len = t->base;
+ c->mode = LENEXT;
+ break;
+ }
+ if ((e & 64) == 0) /* next table */
+ {
+ c->sub.code.need = e;
+ c->sub.code.tree = t + t->base;
+ break;
+ }
+ if (e & 32) /* end of block */
+ {
+ Tracevv((stderr, "inflate: end of block\n"));
+ c->mode = WASH;
+ break;
+ }
+ c->mode = BADCODE; /* invalid code */
+ z->msg = (char*)"invalid literal/length code";
+ r = Z_DATA_ERROR;
+ LEAVE
+ case LENEXT: /* i: getting length extra (have base) */
+ j = c->sub.copy.get;
+ NEEDBITS(j)
+ c->len += (uInt)b & inflate_mask[j];
+ DUMPBITS(j)
+ c->sub.code.need = c->dbits;
+ c->sub.code.tree = c->dtree;
+ Tracevv((stderr, "inflate: length %u\n", c->len));
+ c->mode = DIST;
+ case DIST: /* i: get distance next */
+ j = c->sub.code.need;
+ NEEDBITS(j)
+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+ DUMPBITS(t->bits)
+ e = (uInt)(t->exop);
+ if (e & 16) /* distance */
+ {
+ c->sub.copy.get = e & 15;
+ c->sub.copy.dist = t->base;
+ c->mode = DISTEXT;
+ break;
+ }
+ if ((e & 64) == 0) /* next table */
+ {
+ c->sub.code.need = e;
+ c->sub.code.tree = t + t->base;
+ break;
+ }
+ c->mode = BADCODE; /* invalid code */
+ z->msg = (char*)"invalid distance code";
+ r = Z_DATA_ERROR;
+ LEAVE
+ case DISTEXT: /* i: getting distance extra */
+ j = c->sub.copy.get;
+ NEEDBITS(j)
+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
+ DUMPBITS(j)
+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
+ c->mode = COPY;
+ case COPY: /* o: copying bytes in window, waiting for space */
+#ifndef __TURBOC__ /* Turbo C bug for following expression */
+ f = (uInt)(q - s->window) < c->sub.copy.dist ?
+ s->end - (c->sub.copy.dist - (q - s->window)) :
+ q - c->sub.copy.dist;
+#else
+ f = q - c->sub.copy.dist;
+ if ((uInt)(q - s->window) < c->sub.copy.dist)
+ f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
+#endif
+ while (c->len)
+ {
+ NEEDOUT
+ OUTBYTE(*f++)
+ if (f == s->end)
+ f = s->window;
+ c->len--;
+ }
+ c->mode = START;
+ break;
+ case LIT: /* o: got literal, waiting for output space */
+ NEEDOUT
+ OUTBYTE(c->sub.lit)
+ c->mode = START;
+ break;
+ case WASH: /* o: got eob, possibly more output */
+ if (k > 7) /* return unused byte, if any */
+ {
+ Assert(k < 16, "inflate_codes grabbed too many bytes")
+ k -= 8;
+ n++;
+ p--; /* can always return one */
+ }
+ FLUSH
+ if (s->read != s->write)
+ LEAVE
+ c->mode = END;
+ case END:
+ r = Z_STREAM_END;
+ LEAVE
+ case BADCODE: /* x: got error */
+ r = Z_DATA_ERROR;
+ LEAVE
+ default:
+ r = Z_STREAM_ERROR;
+ LEAVE
+ }
+#ifdef NEED_DUMMY_RETURN
+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
+#endif
+}
+
+
+void inflate_codes_free(c, z)
+inflate_codes_statef *c;
+z_streamp z;
+{
+ ZFREE(z, c);
+ Tracev((stderr, "inflate: codes free\n"));
+}
diff --git a/lib/libz/infcodes.h b/lib/libz/infcodes.h
new file mode 100644
index 0000000..6c750d8
--- /dev/null
+++ b/lib/libz/infcodes.h
@@ -0,0 +1,27 @@
+/* infcodes.h -- header to use infcodes.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_codes_state;
+typedef struct inflate_codes_state FAR inflate_codes_statef;
+
+extern inflate_codes_statef *inflate_codes_new OF((
+ uInt, uInt,
+ inflate_huft *, inflate_huft *,
+ z_streamp ));
+
+extern int inflate_codes OF((
+ inflate_blocks_statef *,
+ z_streamp ,
+ int));
+
+extern void inflate_codes_free OF((
+ inflate_codes_statef *,
+ z_streamp ));
+
diff --git a/lib/libz/inffast.c b/lib/libz/inffast.c
new file mode 100644
index 0000000..61a78ee
--- /dev/null
+++ b/lib/libz/inffast.c
@@ -0,0 +1,170 @@
+/* inffast.c -- process literals and length/distance pairs fast
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infblock.h"
+#include "infcodes.h"
+#include "infutil.h"
+#include "inffast.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* macros for bit input with no checking and for returning unused bytes */
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
+
+/* Called with number of bytes left to write in window at least 258
+ (the maximum string length) and number of input bytes available
+ at least ten. The ten bytes are six bytes for the longest length/
+ distance pair plus four bytes for overloading the bit buffer. */
+
+int inflate_fast(bl, bd, tl, td, s, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+inflate_blocks_statef *s;
+z_streamp z;
+{
+ inflate_huft *t; /* temporary pointer */
+ uInt e; /* extra bits or operation */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+ uInt ml; /* mask for literal/length tree */
+ uInt md; /* mask for distance tree */
+ uInt c; /* bytes to copy */
+ uInt d; /* distance back to copy from */
+ Bytef *r; /* copy source pointer */
+
+ /* load input, output, bit values */
+ LOAD
+
+ /* initialize masks */
+ ml = inflate_mask[bl];
+ md = inflate_mask[bd];
+
+ /* do until not enough input or output space for fast loop */
+ do { /* assume called with m >= 258 && n >= 10 */
+ /* get literal/length code */
+ GRABBITS(20) /* max bits for literal/length code */
+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
+ {
+ DUMPBITS(t->bits)
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+ "inflate: * literal '%c'\n" :
+ "inflate: * literal 0x%02x\n", t->base));
+ *q++ = (Byte)t->base;
+ m--;
+ continue;
+ }
+ do {
+ DUMPBITS(t->bits)
+ if (e & 16)
+ {
+ /* get extra bits for length */
+ e &= 15;
+ c = t->base + ((uInt)b & inflate_mask[e]);
+ DUMPBITS(e)
+ Tracevv((stderr, "inflate: * length %u\n", c));
+
+ /* decode distance base of block to copy */
+ GRABBITS(15); /* max bits for distance code */
+ e = (t = td + ((uInt)b & md))->exop;
+ do {
+ DUMPBITS(t->bits)
+ if (e & 16)
+ {
+ /* get extra bits to add to distance base */
+ e &= 15;
+ GRABBITS(e) /* get extra bits (up to 13) */
+ d = t->base + ((uInt)b & inflate_mask[e]);
+ DUMPBITS(e)
+ Tracevv((stderr, "inflate: * distance %u\n", d));
+
+ /* do the copy */
+ m -= c;
+ if ((uInt)(q - s->window) >= d) /* offset before dest */
+ { /* just copy */
+ r = q - d;
+ *q++ = *r++; c--; /* minimum count is three, */
+ *q++ = *r++; c--; /* so unroll loop a little */
+ }
+ else /* else offset after destination */
+ {
+ e = d - (uInt)(q - s->window); /* bytes from offset to end */
+ r = s->end - e; /* pointer to offset */
+ if (c > e) /* if source crosses, */
+ {
+ c -= e; /* copy to end of window */
+ do {
+ *q++ = *r++;
+ } while (--e);
+ r = s->window; /* copy rest from start of window */
+ }
+ }
+ do { /* copy all or what's left */
+ *q++ = *r++;
+ } while (--c);
+ break;
+ }
+ else if ((e & 64) == 0)
+ {
+ t += t->base;
+ e = (t += ((uInt)b & inflate_mask[e]))->exop;
+ }
+ else
+ {
+ z->msg = (char*)"invalid distance code";
+ UNGRAB
+ UPDATE
+ return Z_DATA_ERROR;
+ }
+ } while (1);
+ break;
+ }
+ if ((e & 64) == 0)
+ {
+ t += t->base;
+ if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
+ {
+ DUMPBITS(t->bits)
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+ "inflate: * literal '%c'\n" :
+ "inflate: * literal 0x%02x\n", t->base));
+ *q++ = (Byte)t->base;
+ m--;
+ break;
+ }
+ }
+ else if (e & 32)
+ {
+ Tracevv((stderr, "inflate: * end of block\n"));
+ UNGRAB
+ UPDATE
+ return Z_STREAM_END;
+ }
+ else
+ {
+ z->msg = (char*)"invalid literal/length code";
+ UNGRAB
+ UPDATE
+ return Z_DATA_ERROR;
+ }
+ } while (1);
+ } while (m >= 258 && n >= 10);
+
+ /* not enough input or output--restore pointers and return */
+ UNGRAB
+ UPDATE
+ return Z_OK;
+}
diff --git a/lib/libz/inffast.h b/lib/libz/inffast.h
new file mode 100644
index 0000000..8facec5
--- /dev/null
+++ b/lib/libz/inffast.h
@@ -0,0 +1,17 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+extern int inflate_fast OF((
+ uInt,
+ uInt,
+ inflate_huft *,
+ inflate_huft *,
+ inflate_blocks_statef *,
+ z_streamp ));
diff --git a/lib/libz/inffixed.h b/lib/libz/inffixed.h
new file mode 100644
index 0000000..77f7e76
--- /dev/null
+++ b/lib/libz/inffixed.h
@@ -0,0 +1,151 @@
+/* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by the maketree.c program
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+local uInt fixed_bl = 9;
+local uInt fixed_bd = 5;
+local inflate_huft fixed_tl[] = {
+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
+ };
+local inflate_huft fixed_td[] = {
+ {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
+ {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
+ {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
+ {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
+ {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
+ {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
+ {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
+ {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
+ };
diff --git a/lib/libz/inflate.c b/lib/libz/inflate.c
new file mode 100644
index 0000000..32e9b8d
--- /dev/null
+++ b/lib/libz/inflate.c
@@ -0,0 +1,366 @@
+/* inflate.c -- zlib interface to inflate modules
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+
+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
+
+typedef enum {
+ METHOD, /* waiting for method byte */
+ FLAG, /* waiting for flag byte */
+ DICT4, /* four dictionary check bytes to go */
+ DICT3, /* three dictionary check bytes to go */
+ DICT2, /* two dictionary check bytes to go */
+ DICT1, /* one dictionary check byte to go */
+ DICT0, /* waiting for inflateSetDictionary */
+ BLOCKS, /* decompressing blocks */
+ CHECK4, /* four check bytes to go */
+ CHECK3, /* three check bytes to go */
+ CHECK2, /* two check bytes to go */
+ CHECK1, /* one check byte to go */
+ DONE, /* finished check, done */
+ BAD} /* got an error--stay here */
+inflate_mode;
+
+/* inflate private state */
+struct internal_state {
+
+ /* mode */
+ inflate_mode mode; /* current inflate mode */
+
+ /* mode dependent information */
+ union {
+ uInt method; /* if FLAGS, method byte */
+ struct {
+ uLong was; /* computed check value */
+ uLong need; /* stream check value */
+ } check; /* if CHECK, check values to compare */
+ uInt marker; /* if BAD, inflateSync's marker bytes count */
+ } sub; /* submode */
+
+ /* mode independent information */
+ int nowrap; /* flag for no wrapper */
+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
+ inflate_blocks_statef
+ *blocks; /* current inflate_blocks state */
+
+};
+
+
+int ZEXPORT inflateReset(z)
+z_streamp z;
+{
+ if (z == Z_NULL || z->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ z->total_in = z->total_out = 0;
+ z->msg = Z_NULL;
+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
+ inflate_blocks_reset(z->state->blocks, z, Z_NULL);
+ Tracev((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+
+int ZEXPORT inflateEnd(z)
+z_streamp z;
+{
+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
+ return Z_STREAM_ERROR;
+ if (z->state->blocks != Z_NULL)
+ inflate_blocks_free(z->state->blocks, z);
+ ZFREE(z, z->state);
+ z->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+
+int ZEXPORT inflateInit2_(z, w, version, stream_size)
+z_streamp z;
+int w;
+const char *version;
+int stream_size;
+{
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != sizeof(z_stream))
+ return Z_VERSION_ERROR;
+
+ /* initialize state */
+ if (z == Z_NULL)
+ return Z_STREAM_ERROR;
+ z->msg = Z_NULL;
+ if (z->zalloc == Z_NULL)
+ {
+ z->zalloc = zcalloc;
+ z->opaque = (voidpf)0;
+ }
+ if (z->zfree == Z_NULL) z->zfree = zcfree;
+ if ((z->state = (struct internal_state FAR *)
+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
+ return Z_MEM_ERROR;
+ z->state->blocks = Z_NULL;
+
+ /* handle undocumented nowrap option (no zlib header or check) */
+ z->state->nowrap = 0;
+ if (w < 0)
+ {
+ w = - w;
+ z->state->nowrap = 1;
+ }
+
+ /* set window size */
+ if (w < 8 || w > 15)
+ {
+ inflateEnd(z);
+ return Z_STREAM_ERROR;
+ }
+ z->state->wbits = (uInt)w;
+
+ /* create inflate_blocks state */
+ if ((z->state->blocks =
+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
+ == Z_NULL)
+ {
+ inflateEnd(z);
+ return Z_MEM_ERROR;
+ }
+ Tracev((stderr, "inflate: allocated\n"));
+
+ /* reset state */
+ inflateReset(z);
+ return Z_OK;
+}
+
+
+int ZEXPORT inflateInit_(z, version, stream_size)
+z_streamp z;
+const char *version;
+int stream_size;
+{
+ return inflateInit2_(z, DEF_WBITS, version, stream_size);
+}
+
+
+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
+
+int ZEXPORT inflate(z, f)
+z_streamp z;
+int f;
+{
+ int r;
+ uInt b;
+
+ if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
+ return Z_STREAM_ERROR;
+ f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
+ r = Z_BUF_ERROR;
+ while (1) switch (z->state->mode)
+ {
+ case METHOD:
+ NEEDBYTE
+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
+ {
+ z->state->mode = BAD;
+ z->msg = (char*)"unknown compression method";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
+ {
+ z->state->mode = BAD;
+ z->msg = (char*)"invalid window size";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ z->state->mode = FLAG;
+ case FLAG:
+ NEEDBYTE
+ b = NEXTBYTE;
+ if (((z->state->sub.method << 8) + b) % 31)
+ {
+ z->state->mode = BAD;
+ z->msg = (char*)"incorrect header check";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ Tracev((stderr, "inflate: zlib header ok\n"));
+ if (!(b & PRESET_DICT))
+ {
+ z->state->mode = BLOCKS;
+ break;
+ }
+ z->state->mode = DICT4;
+ case DICT4:
+ NEEDBYTE
+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+ z->state->mode = DICT3;
+ case DICT3:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+ z->state->mode = DICT2;
+ case DICT2:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+ z->state->mode = DICT1;
+ case DICT1:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE;
+ z->adler = z->state->sub.check.need;
+ z->state->mode = DICT0;
+ return Z_NEED_DICT;
+ case DICT0:
+ z->state->mode = BAD;
+ z->msg = (char*)"need dictionary";
+ z->state->sub.marker = 0; /* can try inflateSync */
+ return Z_STREAM_ERROR;
+ case BLOCKS:
+ r = inflate_blocks(z->state->blocks, z, r);
+ if (r == Z_DATA_ERROR)
+ {
+ z->state->mode = BAD;
+ z->state->sub.marker = 0; /* can try inflateSync */
+ break;
+ }
+ if (r == Z_OK)
+ r = f;
+ if (r != Z_STREAM_END)
+ return r;
+ r = f;
+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
+ if (z->state->nowrap)
+ {
+ z->state->mode = DONE;
+ break;
+ }
+ z->state->mode = CHECK4;
+ case CHECK4:
+ NEEDBYTE
+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+ z->state->mode = CHECK3;
+ case CHECK3:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+ z->state->mode = CHECK2;
+ case CHECK2:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+ z->state->mode = CHECK1;
+ case CHECK1:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE;
+
+ if (z->state->sub.check.was != z->state->sub.check.need)
+ {
+ z->state->mode = BAD;
+ z->msg = (char*)"incorrect data check";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ Tracev((stderr, "inflate: zlib check ok\n"));
+ z->state->mode = DONE;
+ case DONE:
+ return Z_STREAM_END;
+ case BAD:
+ return Z_DATA_ERROR;
+ default:
+ return Z_STREAM_ERROR;
+ }
+#ifdef NEED_DUMMY_RETURN
+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
+#endif
+}
+
+
+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
+z_streamp z;
+const Bytef *dictionary;
+uInt dictLength;
+{
+ uInt length = dictLength;
+
+ if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
+ return Z_STREAM_ERROR;
+
+ if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
+ z->adler = 1L;
+
+ if (length >= ((uInt)1<<z->state->wbits))
+ {
+ length = (1<<z->state->wbits)-1;
+ dictionary += dictLength - length;
+ }
+ inflate_set_dictionary(z->state->blocks, dictionary, length);
+ z->state->mode = BLOCKS;
+ return Z_OK;
+}
+
+
+int ZEXPORT inflateSync(z)
+z_streamp z;
+{
+ uInt n; /* number of bytes to look at */
+ Bytef *p; /* pointer to bytes */
+ uInt m; /* number of marker bytes found in a row */
+ uLong r, w; /* temporaries to save total_in and total_out */
+
+ /* set up */
+ if (z == Z_NULL || z->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ if (z->state->mode != BAD)
+ {
+ z->state->mode = BAD;
+ z->state->sub.marker = 0;
+ }
+ if ((n = z->avail_in) == 0)
+ return Z_BUF_ERROR;
+ p = z->next_in;
+ m = z->state->sub.marker;
+
+ /* search */
+ while (n && m < 4)
+ {
+ static const Byte mark[4] = {0, 0, 0xff, 0xff};
+ if (*p == mark[m])
+ m++;
+ else if (*p)
+ m = 0;
+ else
+ m = 4 - m;
+ p++, n--;
+ }
+
+ /* restore */
+ z->total_in += p - z->next_in;
+ z->next_in = p;
+ z->avail_in = n;
+ z->state->sub.marker = m;
+
+ /* return no joy or set up to restart on a new block */
+ if (m != 4)
+ return Z_DATA_ERROR;
+ r = z->total_in; w = z->total_out;
+ inflateReset(z);
+ z->total_in = r; z->total_out = w;
+ z->state->mode = BLOCKS;
+ return Z_OK;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
+ * but removes the length bytes of the resulting empty stored block. When
+ * decompressing, PPP checks that at the end of input packet, inflate is
+ * waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(z)
+z_streamp z;
+{
+ if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
+ return Z_STREAM_ERROR;
+ return inflate_blocks_sync_point(z->state->blocks);
+}
diff --git a/lib/libz/inftrees.c b/lib/libz/inftrees.c
new file mode 100644
index 0000000..ef1e0b6
--- /dev/null
+++ b/lib/libz/inftrees.c
@@ -0,0 +1,455 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#if !defined(BUILDFIXED) && !defined(STDC)
+# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
+#endif
+
+const char inflate_copyright[] =
+ " inflate 1.1.3 Copyright 1995-1998 Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+struct internal_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+
+local int huft_build OF((
+ uIntf *, /* code lengths in bits */
+ uInt, /* number of codes */
+ uInt, /* number of "simple" codes */
+ const uIntf *, /* list of base values for non-simple codes */
+ const uIntf *, /* list of extra bits for non-simple codes */
+ inflate_huft * FAR*,/* result: starting table */
+ uIntf *, /* maximum lookup bits (returns actual) */
+ inflate_huft *, /* space for trees */
+ uInt *, /* hufts used in space */
+ uIntf * )); /* space for values */
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ /* see note #13 above about 258 */
+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577};
+local const uInt cpdext[30] = { /* Extra bits for distance codes */
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+ 12, 12, 13, 13};
+
+/*
+ Huffman code decoding is performed using a multi-level table lookup.
+ The fastest way to decode is to simply build a lookup table whose
+ size is determined by the longest code. However, the time it takes
+ to build this table can also be a factor if the data being decoded
+ is not very long. The most common codes are necessarily the
+ shortest codes, so those codes dominate the decoding time, and hence
+ the speed. The idea is you can have a shorter table that decodes the
+ shorter, more probable codes, and then point to subsidiary tables for
+ the longer codes. The time it costs to decode the longer codes is
+ then traded against the time it takes to make longer tables.
+
+ This results of this trade are in the variables lbits and dbits
+ below. lbits is the number of bits the first level table for literal/
+ length codes can decode in one step, and dbits is the same thing for
+ the distance codes. Subsequent tables are also less than or equal to
+ those sizes. These values may be adjusted either when all of the
+ codes are shorter than that, in which case the longest code length in
+ bits is used, or when the shortest code is *longer* than the requested
+ table size, in which case the length of the shortest code in bits is
+ used.
+
+ There are two different values for the two tables, since they code a
+ different number of possibilities each. The literal/length table
+ codes 286 possible values, or in a flat code, a little over eight
+ bits. The distance table codes 30 possible values, or a little less
+ than five bits, flat. The optimum values for speed end up being
+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+ The optimum values may differ though from machine to machine, and
+ possibly even between compilers. Your mileage may vary.
+ */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
+#define BMAX 15 /* maximum bit length of any code */
+
+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
+uInt n; /* number of codes (assumed <= 288) */
+uInt s; /* number of simple-valued codes (0..s-1) */
+const uIntf *d; /* list of base values for non-simple codes */
+const uIntf *e; /* list of extra bits for non-simple codes */
+inflate_huft * FAR *t; /* result: starting table */
+uIntf *m; /* maximum lookup bits, returns actual */
+inflate_huft *hp; /* space for trees */
+uInt *hn; /* hufts used in space */
+uIntf *v; /* working area: values in order of bit length */
+/* Given a list of code lengths and a maximum table size, make a set of
+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
+ if the given code set is incomplete (the tables are still built in this
+ case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
+ lengths), or Z_MEM_ERROR if not enough memory. */
+{
+
+ uInt a; /* counter for codes of length k */
+ uInt c[BMAX+1]; /* bit length count table */
+ uInt f; /* i repeats in table every f entries */
+ int g; /* maximum code length */
+ int h; /* table level */
+ register uInt i; /* counter, current code */
+ register uInt j; /* counter */
+ register int k; /* number of bits in current code */
+ int l; /* bits per table (returned in m) */
+ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
+ register uIntf *p; /* pointer into c[], b[], or v[] */
+ inflate_huft *q; /* points to current table */
+ struct inflate_huft_s r; /* table entry for structure assignment */
+ inflate_huft *u[BMAX]; /* table stack */
+ register int w; /* bits before this table == (l * h) */
+ uInt x[BMAX+1]; /* bit offsets, then code stack */
+ uIntf *xp; /* pointer into x */
+ int y; /* number of dummy codes added */
+ uInt z; /* number of entries in current table */
+
+
+ /* Generate counts for each bit length */
+ p = c;
+#define C0 *p++ = 0;
+#define C2 C0 C0 C0 C0
+#define C4 C2 C2 C2 C2
+ C4 /* clear c[]--assume BMAX+1 is 16 */
+ p = b; i = n;
+ do {
+ c[*p++]++; /* assume all entries <= BMAX */
+ } while (--i);
+ if (c[0] == n) /* null input--all zero length codes */
+ {
+ *t = (inflate_huft *)Z_NULL;
+ *m = 0;
+ return Z_OK;
+ }
+
+
+ /* Find minimum and maximum length, bound *m by those */
+ l = *m;
+ for (j = 1; j <= BMAX; j++)
+ if (c[j])
+ break;
+ k = j; /* minimum code length */
+ if ((uInt)l < j)
+ l = j;
+ for (i = BMAX; i; i--)
+ if (c[i])
+ break;
+ g = i; /* maximum code length */
+ if ((uInt)l > i)
+ l = i;
+ *m = l;
+
+
+ /* Adjust last length count to fill out codes, if needed */
+ for (y = 1 << j; j < i; j++, y <<= 1)
+ if ((y -= c[j]) < 0)
+ return Z_DATA_ERROR;
+ if ((y -= c[i]) < 0)
+ return Z_DATA_ERROR;
+ c[i] += y;
+
+
+ /* Generate starting offsets into the value table for each length */
+ x[1] = j = 0;
+ p = c + 1; xp = x + 2;
+ while (--i) { /* note that i == g from above */
+ *xp++ = (j += *p++);
+ }
+
+
+ /* Make a table of values in order of bit lengths */
+ p = b; i = 0;
+ do {
+ if ((j = *p++) != 0)
+ v[x[j]++] = i;
+ } while (++i < n);
+ n = x[g]; /* set n to length of v */
+
+
+ /* Generate the Huffman codes and for each, make the table entries */
+ x[0] = i = 0; /* first Huffman code is zero */
+ p = v; /* grab values in bit order */
+ h = -1; /* no tables yet--level -1 */
+ w = -l; /* bits decoded == (l * h) */
+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
+ q = (inflate_huft *)Z_NULL; /* ditto */
+ z = 0; /* ditto */
+
+ /* go through the bit lengths (k already is bits in shortest code) */
+ for (; k <= g; k++)
+ {
+ a = c[k];
+ while (a--)
+ {
+ /* here i is the Huffman code of length k bits for value *p */
+ /* make tables up to required level */
+ while (k > w + l)
+ {
+ h++;
+ w += l; /* previous table always l bits */
+
+ /* compute minimum size table less than or equal to l bits */
+ z = g - w;
+ z = z > (uInt)l ? l : z; /* table size upper limit */
+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
+ { /* too few codes for k-w bit table */
+ f -= a + 1; /* deduct codes from patterns left */
+ xp = c + k;
+ if (j < z)
+ while (++j < z) /* try smaller tables up to z bits */
+ {
+ if ((f <<= 1) <= *++xp)
+ break; /* enough codes to use up j bits */
+ f -= *xp; /* else deduct codes from patterns */
+ }
+ }
+ z = 1 << j; /* table entries for j-bit table */
+
+ /* allocate new table */
+ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
+ return Z_MEM_ERROR; /* not enough memory */
+ u[h] = q = hp + *hn;
+ *hn += z;
+
+ /* connect to last table, if there is one */
+ if (h)
+ {
+ x[h] = i; /* save pattern for backing up */
+ r.bits = (Byte)l; /* bits to dump before this table */
+ r.exop = (Byte)j; /* bits in this table */
+ j = i >> (w - l);
+ r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
+ u[h-1][j] = r; /* connect to last table */
+ }
+ else
+ *t = q; /* first table is returned result */
+ }
+
+ /* set up table entry in r */
+ r.bits = (Byte)(k - w);
+ if (p >= v + n)
+ r.exop = 128 + 64; /* out of values--invalid code */
+ else if (*p < s)
+ {
+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
+ r.base = *p++; /* simple code is just the value */
+ }
+ else
+ {
+ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
+ r.base = d[*p++ - s];
+ }
+
+ /* fill code-like entries with r */
+ f = 1 << (k - w);
+ for (j = i >> w; j < z; j += f)
+ q[j] = r;
+
+ /* backwards increment the k-bit code i */
+ for (j = 1 << (k - 1); i & j; j >>= 1)
+ i ^= j;
+ i ^= j;
+
+ /* backup over finished tables */
+ mask = (1 << w) - 1; /* needed on HP, cc -O bug */
+ while ((i & mask) != x[h])
+ {
+ h--; /* don't need to update q */
+ w -= l;
+ mask = (1 << w) - 1;
+ }
+ }
+ }
+
+
+ /* Return Z_BUF_ERROR if we were given an incomplete table */
+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+}
+
+
+int inflate_trees_bits(c, bb, tb, hp, z)
+uIntf *c; /* 19 code lengths */
+uIntf *bb; /* bits tree desired/actual depth */
+inflate_huft * FAR *tb; /* bits tree result */
+inflate_huft *hp; /* space for trees */
+z_streamp z; /* for messages */
+{
+ int r;
+ uInt hn = 0; /* hufts used in space */
+ uIntf *v; /* work area for huft_build */
+
+ if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
+ return Z_MEM_ERROR;
+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
+ tb, bb, hp, &hn, v);
+ if (r == Z_DATA_ERROR)
+ z->msg = (char*)"oversubscribed dynamic bit lengths tree";
+ else if (r == Z_BUF_ERROR || *bb == 0)
+ {
+ z->msg = (char*)"incomplete dynamic bit lengths tree";
+ r = Z_DATA_ERROR;
+ }
+ ZFREE(z, v);
+ return r;
+}
+
+
+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
+uInt nl; /* number of literal/length codes */
+uInt nd; /* number of distance codes */
+uIntf *c; /* that many (total) code lengths */
+uIntf *bl; /* literal desired/actual bit depth */
+uIntf *bd; /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+inflate_huft *hp; /* space for trees */
+z_streamp z; /* for messages */
+{
+ int r;
+ uInt hn = 0; /* hufts used in space */
+ uIntf *v; /* work area for huft_build */
+
+ /* allocate work area */
+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+ return Z_MEM_ERROR;
+
+ /* build literal/length tree */
+ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
+ if (r != Z_OK || *bl == 0)
+ {
+ if (r == Z_DATA_ERROR)
+ z->msg = (char*)"oversubscribed literal/length tree";
+ else if (r != Z_MEM_ERROR)
+ {
+ z->msg = (char*)"incomplete literal/length tree";
+ r = Z_DATA_ERROR;
+ }
+ ZFREE(z, v);
+ return r;
+ }
+
+ /* build distance tree */
+ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
+ if (r != Z_OK || (*bd == 0 && nl > 257))
+ {
+ if (r == Z_DATA_ERROR)
+ z->msg = (char*)"oversubscribed distance tree";
+ else if (r == Z_BUF_ERROR) {
+#ifdef PKZIP_BUG_WORKAROUND
+ r = Z_OK;
+ }
+#else
+ z->msg = (char*)"incomplete distance tree";
+ r = Z_DATA_ERROR;
+ }
+ else if (r != Z_MEM_ERROR)
+ {
+ z->msg = (char*)"empty distance tree with lengths";
+ r = Z_DATA_ERROR;
+ }
+ ZFREE(z, v);
+ return r;
+#endif
+ }
+
+ /* done */
+ ZFREE(z, v);
+ return Z_OK;
+}
+
+
+/* build fixed tables only once--keep them here */
+#ifdef BUILDFIXED
+local int fixed_built = 0;
+#define FIXEDH 544 /* number of hufts used by fixed tables */
+local inflate_huft fixed_mem[FIXEDH];
+local uInt fixed_bl;
+local uInt fixed_bd;
+local inflate_huft *fixed_tl;
+local inflate_huft *fixed_td;
+#else
+#include "inffixed.h"
+#endif
+
+
+int inflate_trees_fixed(bl, bd, tl, td, z)
+uIntf *bl; /* literal desired/actual bit depth */
+uIntf *bd; /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+z_streamp z; /* for memory allocation */
+{
+#ifdef BUILDFIXED
+ /* build fixed tables if not already */
+ if (!fixed_built)
+ {
+ int k; /* temporary variable */
+ uInt f = 0; /* number of hufts used in fixed_mem */
+ uIntf *c; /* length list for huft_build */
+ uIntf *v; /* work area for huft_build */
+
+ /* allocate memory */
+ if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+ return Z_MEM_ERROR;
+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+ {
+ ZFREE(z, c);
+ return Z_MEM_ERROR;
+ }
+
+ /* literal table */
+ for (k = 0; k < 144; k++)
+ c[k] = 8;
+ for (; k < 256; k++)
+ c[k] = 9;
+ for (; k < 280; k++)
+ c[k] = 7;
+ for (; k < 288; k++)
+ c[k] = 8;
+ fixed_bl = 9;
+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
+ fixed_mem, &f, v);
+
+ /* distance table */
+ for (k = 0; k < 30; k++)
+ c[k] = 5;
+ fixed_bd = 5;
+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
+ fixed_mem, &f, v);
+
+ /* done */
+ ZFREE(z, v);
+ ZFREE(z, c);
+ fixed_built = 1;
+ }
+#endif
+ *bl = fixed_bl;
+ *bd = fixed_bd;
+ *tl = fixed_tl;
+ *td = fixed_td;
+ return Z_OK;
+}
diff --git a/lib/libz/inftrees.h b/lib/libz/inftrees.h
new file mode 100644
index 0000000..85853e0
--- /dev/null
+++ b/lib/libz/inftrees.h
@@ -0,0 +1,58 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
+
+typedef struct inflate_huft_s FAR inflate_huft;
+
+struct inflate_huft_s {
+ union {
+ struct {
+ Byte Exop; /* number of extra bits or operation */
+ Byte Bits; /* number of bits in this code or subcode */
+ } what;
+ uInt pad; /* pad structure to a power of 2 (4 bytes for */
+ } word; /* 16-bit, 8 bytes for 32-bit int's) */
+ uInt base; /* literal, length base, distance base,
+ or table offset */
+};
+
+/* Maximum size of dynamic tree. The maximum found in a long but non-
+ exhaustive search was 1004 huft structures (850 for length/literals
+ and 154 for distances, the latter actually the result of an
+ exhaustive search). The actual maximum is not known, but the
+ value below is more than safe. */
+#define MANY 1440
+
+extern int inflate_trees_bits OF((
+ uIntf *, /* 19 code lengths */
+ uIntf *, /* bits tree desired/actual depth */
+ inflate_huft * FAR *, /* bits tree result */
+ inflate_huft *, /* space for trees */
+ z_streamp)); /* for messages */
+
+extern int inflate_trees_dynamic OF((
+ uInt, /* number of literal/length codes */
+ uInt, /* number of distance codes */
+ uIntf *, /* that many (total) code lengths */
+ uIntf *, /* literal desired/actual bit depth */
+ uIntf *, /* distance desired/actual bit depth */
+ inflate_huft * FAR *, /* literal/length tree result */
+ inflate_huft * FAR *, /* distance tree result */
+ inflate_huft *, /* space for trees */
+ z_streamp)); /* for messages */
+
+extern int inflate_trees_fixed OF((
+ uIntf *, /* literal desired/actual bit depth */
+ uIntf *, /* distance desired/actual bit depth */
+ inflate_huft * FAR *, /* literal/length tree result */
+ inflate_huft * FAR *, /* distance tree result */
+ z_streamp)); /* for memory allocation */
diff --git a/lib/libz/infutil.c b/lib/libz/infutil.c
new file mode 100644
index 0000000..824dab5
--- /dev/null
+++ b/lib/libz/infutil.c
@@ -0,0 +1,87 @@
+/* inflate_util.c -- data and routines common to blocks and codes
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* And'ing with mask[n] masks the lower n bits */
+uInt inflate_mask[17] = {
+ 0x0000,
+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+
+/* copy as much as possible from the sliding window to the output area */
+int inflate_flush(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+ uInt n;
+ Bytef *p;
+ Bytef *q;
+
+ /* local copies of source and destination pointers */
+ p = z->next_out;
+ q = s->read;
+
+ /* compute number of bytes to copy as far as end of window */
+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
+ if (n > z->avail_out) n = z->avail_out;
+ if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+ /* update counters */
+ z->avail_out -= n;
+ z->total_out += n;
+
+ /* update check information */
+ if (s->checkfn != Z_NULL)
+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+ /* copy as far as end of window */
+ zmemcpy(p, q, n);
+ p += n;
+ q += n;
+
+ /* see if more to copy at beginning of window */
+ if (q == s->end)
+ {
+ /* wrap pointers */
+ q = s->window;
+ if (s->write == s->end)
+ s->write = s->window;
+
+ /* compute bytes to copy */
+ n = (uInt)(s->write - q);
+ if (n > z->avail_out) n = z->avail_out;
+ if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+ /* update counters */
+ z->avail_out -= n;
+ z->total_out += n;
+
+ /* update check information */
+ if (s->checkfn != Z_NULL)
+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+ /* copy */
+ zmemcpy(p, q, n);
+ p += n;
+ q += n;
+ }
+
+ /* update pointers */
+ z->next_out = p;
+ s->read = q;
+
+ /* done */
+ return r;
+}
diff --git a/lib/libz/infutil.h b/lib/libz/infutil.h
new file mode 100644
index 0000000..99d1135
--- /dev/null
+++ b/lib/libz/infutil.h
@@ -0,0 +1,98 @@
+/* infutil.h -- types and macros common to blocks and codes
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+#ifndef _INFUTIL_H
+#define _INFUTIL_H
+
+typedef enum {
+ TYPE, /* get type bits (3, including end bit) */
+ LENS, /* get lengths for stored */
+ STORED, /* processing stored block */
+ TABLE, /* get table lengths */
+ BTREE, /* get bit lengths tree for a dynamic block */
+ DTREE, /* get length, distance trees for a dynamic block */
+ CODES, /* processing fixed or dynamic block */
+ DRY, /* output remaining window bytes */
+ DONE, /* finished last block, done */
+ BAD} /* got a data error--stuck here */
+inflate_block_mode;
+
+/* inflate blocks semi-private state */
+struct inflate_blocks_state {
+
+ /* mode */
+ inflate_block_mode mode; /* current inflate_block mode */
+
+ /* mode dependent information */
+ union {
+ uInt left; /* if STORED, bytes left to copy */
+ struct {
+ uInt table; /* table lengths (14 bits) */
+ uInt index; /* index into blens (or border) */
+ uIntf *blens; /* bit lengths of codes */
+ uInt bb; /* bit length tree depth */
+ inflate_huft *tb; /* bit length decoding tree */
+ } trees; /* if DTREE, decoding info for trees */
+ struct {
+ inflate_codes_statef
+ *codes;
+ } decode; /* if CODES, current state */
+ } sub; /* submode */
+ uInt last; /* true if this block is the last block */
+
+ /* mode independent information */
+ uInt bitk; /* bits in bit buffer */
+ uLong bitb; /* bit buffer */
+ inflate_huft *hufts; /* single malloc for tree space */
+ Bytef *window; /* sliding window */
+ Bytef *end; /* one byte after sliding window */
+ Bytef *read; /* window read pointer */
+ Bytef *write; /* window write pointer */
+ check_func checkfn; /* check function */
+ uLong check; /* check on output */
+
+};
+
+
+/* defines for inflate input/output */
+/* update pointers and return */
+#define UPDBITS {s->bitb=b;s->bitk=k;}
+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
+#define UPDOUT {s->write=q;}
+#define UPDATE {UPDBITS UPDIN UPDOUT}
+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
+/* get bytes and bits */
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
+#define NEXTBYTE (n--,*p++)
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define DUMPBITS(j) {b>>=(j);k-=(j);}
+/* output bytes */
+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+/* load local pointers */
+#define LOAD {LOADIN LOADOUT}
+
+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
+extern uInt inflate_mask[17];
+
+/* copy as much as possible from the sliding window to the output area */
+extern int inflate_flush OF((
+ inflate_blocks_statef *,
+ z_streamp ,
+ int));
+
+struct internal_state {int dummy;}; /* for buggy compilers */
+
+#endif
diff --git a/lib/libz/maketree.c b/lib/libz/maketree.c
new file mode 100644
index 0000000..949d786
--- /dev/null
+++ b/lib/libz/maketree.c
@@ -0,0 +1,85 @@
+/* maketree.c -- make inffixed.h table for decoding fixed codes
+ * Copyright (C) 1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* This program is included in the distribution for completeness.
+ You do not need to compile or run this program since inffixed.h
+ is already included in the distribution. To use this program
+ you need to compile zlib with BUILDFIXED defined and then compile
+ and link this program with the zlib library. Then the output of
+ this program can be piped to inffixed.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "zutil.h"
+#include "inftrees.h"
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* generate initialization table for an inflate_huft structure array */
+void maketree(uInt b, inflate_huft *t)
+{
+ int i, e;
+
+ i = 0;
+ while (1)
+ {
+ e = t[i].exop;
+ if (e && (e & (16+64)) == 0) /* table pointer */
+ {
+ fprintf(stderr, "maketree: cannot initialize sub-tables!\n");
+ exit(1);
+ }
+ if (i % 4 == 0)
+ printf("\n ");
+ printf(" {{{%u,%u}},%u}", t[i].exop, t[i].bits, t[i].base);
+ if (++i == (1<<b))
+ break;
+ putchar(',');
+ }
+ puts("");
+}
+
+/* create the fixed tables in C initialization syntax */
+void main(void)
+{
+ int r;
+ uInt bl, bd;
+ inflate_huft *tl, *td;
+ z_stream z;
+
+ z.zalloc = zcalloc;
+ z.opaque = (voidpf)0;
+ z.zfree = zcfree;
+ r = inflate_trees_fixed(&bl, &bd, &tl, &td, &z);
+ if (r)
+ {
+ fprintf(stderr, "inflate_trees_fixed error %d\n", r);
+ return;
+ }
+ puts("/* inffixed.h -- table for decoding fixed codes");
+ puts(" * Generated automatically by the maketree.c program");
+ puts(" */");
+ puts("");
+ puts("/* WARNING: this file should *not* be used by applications. It is");
+ puts(" part of the implementation of the compression library and is");
+ puts(" subject to change. Applications should only use zlib.h.");
+ puts(" */");
+ puts("");
+ printf("local uInt fixed_bl = %d;\n", bl);
+ printf("local uInt fixed_bd = %d;\n", bd);
+ printf("local inflate_huft fixed_tl[] = {");
+ maketree(bl, tl);
+ puts(" };");
+ printf("local inflate_huft fixed_td[] = {");
+ maketree(bd, td);
+ puts(" };");
+}
diff --git a/lib/libz/minigzip.c b/lib/libz/minigzip.c
new file mode 100644
index 0000000..ba4b2dc
--- /dev/null
+++ b/lib/libz/minigzip.c
@@ -0,0 +1,330 @@
+/* minigzip.c -- simulate gzip using the zlib compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * minigzip is a minimal implementation of the gzip utility. This is
+ * only an example of using zlib and isn't meant to replace the
+ * full-featured gzip. No attempt is made to deal with file systems
+ * limiting names to 14 or 8+3 characters, etc... Error checking is
+ * very limited. So use minigzip only for testing; use gzip for the
+ * real thing. On MSDOS, use only on file names without extension
+ * or in pipe mode.
+ */
+
+/* @(#) $FreeBSD$ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+#else
+ extern void exit OF((int));
+#endif
+
+#ifdef USE_MMAP
+# include <sys/types.h>
+# include <sys/mman.h>
+# include <sys/stat.h>
+#endif
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32)
+# include <fcntl.h>
+# include <io.h>
+# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+# define SET_BINARY_MODE(file)
+#endif
+
+#ifdef VMS
+# define unlink delete
+# define GZ_SUFFIX "-gz"
+#endif
+#ifdef RISCOS
+# define unlink remove
+# define GZ_SUFFIX "-gz"
+# define fileno(file) file->__file
+#endif
+#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fileno */
+#endif
+
+#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
+ extern int unlink OF((const char *));
+#endif
+
+#ifndef GZ_SUFFIX
+# define GZ_SUFFIX ".gz"
+#endif
+#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
+
+#define BUFLEN 16384
+#define MAX_NAME_LEN 1024
+
+#ifdef MAXSEG_64K
+# define local static
+ /* Needed for systems with limitation on stack size. */
+#else
+# define local
+#endif
+
+char *prog;
+
+void error OF((const char *msg));
+void gz_compress OF((FILE *in, gzFile out));
+#ifdef USE_MMAP
+int gz_compress_mmap OF((FILE *in, gzFile out));
+#endif
+void gz_uncompress OF((gzFile in, FILE *out));
+void file_compress OF((char *file, char *mode));
+void file_uncompress OF((char *file));
+int main OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Display error message and exit
+ */
+void error(msg)
+ const char *msg;
+{
+ fprintf(stderr, "%s: %s\n", prog, msg);
+ exit(1);
+}
+
+/* ===========================================================================
+ * Compress input to output then close both files.
+ */
+
+void gz_compress(in, out)
+ FILE *in;
+ gzFile out;
+{
+ local char buf[BUFLEN];
+ int len;
+ int err;
+
+#ifdef USE_MMAP
+ /* Try first compressing with mmap. If mmap fails (minigzip used in a
+ * pipe), use the normal fread loop.
+ */
+ if (gz_compress_mmap(in, out) == Z_OK) return;
+#endif
+ for (;;) {
+ len = fread(buf, 1, sizeof(buf), in);
+ if (ferror(in)) {
+ perror("fread");
+ exit(1);
+ }
+ if (len == 0) break;
+
+ if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
+ }
+ fclose(in);
+ if (gzclose(out) != Z_OK) error("failed gzclose");
+}
+
+#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
+
+/* Try compressing the input file at once using mmap. Return Z_OK if
+ * if success, Z_ERRNO otherwise.
+ */
+int gz_compress_mmap(in, out)
+ FILE *in;
+ gzFile out;
+{
+ int len;
+ int err;
+ int ifd = fileno(in);
+ caddr_t buf; /* mmap'ed buffer for the entire input file */
+ off_t buf_len; /* length of the input file */
+ struct stat sb;
+
+ /* Determine the size of the file, needed for mmap: */
+ if (fstat(ifd, &sb) < 0) return Z_ERRNO;
+ buf_len = sb.st_size;
+ if (buf_len <= 0) return Z_ERRNO;
+
+ /* Now do the actual mmap: */
+ buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
+ if (buf == (caddr_t)(-1)) return Z_ERRNO;
+
+ /* Compress the whole file at once: */
+ len = gzwrite(out, (char *)buf, (unsigned)buf_len);
+
+ if (len != (int)buf_len) error(gzerror(out, &err));
+
+ munmap(buf, buf_len);
+ fclose(in);
+ if (gzclose(out) != Z_OK) error("failed gzclose");
+ return Z_OK;
+}
+#endif /* USE_MMAP */
+
+/* ===========================================================================
+ * Uncompress input to output then close both files.
+ */
+void gz_uncompress(in, out)
+ gzFile in;
+ FILE *out;
+{
+ local char buf[BUFLEN];
+ int len;
+ int err;
+
+ for (;;) {
+ len = gzread(in, buf, sizeof(buf));
+ if (len < 0) error (gzerror(in, &err));
+ if (len == 0) break;
+
+ if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
+ error("failed fwrite");
+ }
+ }
+ if (fclose(out)) error("failed fclose");
+
+ if (gzclose(in) != Z_OK) error("failed gzclose");
+}
+
+
+/* ===========================================================================
+ * Compress the given file: create a corresponding .gz file and remove the
+ * original.
+ */
+void file_compress(file, mode)
+ char *file;
+ char *mode;
+{
+ local char outfile[MAX_NAME_LEN];
+ FILE *in;
+ gzFile out;
+
+ strcpy(outfile, file);
+ strcat(outfile, GZ_SUFFIX);
+
+ in = fopen(file, "rb");
+ if (in == NULL) {
+ perror(file);
+ exit(1);
+ }
+ out = gzopen(outfile, mode);
+ if (out == NULL) {
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
+ exit(1);
+ }
+ gz_compress(in, out);
+
+ unlink(file);
+}
+
+
+/* ===========================================================================
+ * Uncompress the given file and remove the original.
+ */
+void file_uncompress(file)
+ char *file;
+{
+ local char buf[MAX_NAME_LEN];
+ char *infile, *outfile;
+ FILE *out;
+ gzFile in;
+ int len = strlen(file);
+
+ strcpy(buf, file);
+
+ if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
+ infile = file;
+ outfile = buf;
+ outfile[len-3] = '\0';
+ } else {
+ outfile = file;
+ infile = buf;
+ strcat(infile, GZ_SUFFIX);
+ }
+ in = gzopen(infile, "rb");
+ if (in == NULL) {
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
+ exit(1);
+ }
+ out = fopen(outfile, "wb");
+ if (out == NULL) {
+ perror(file);
+ exit(1);
+ }
+
+ gz_uncompress(in, out);
+
+ unlink(infile);
+}
+
+
+/* ===========================================================================
+ * Usage: minigzip [-d] [-f] [-h] [-1 to -9] [files...]
+ * -d : decompress
+ * -f : compress with Z_FILTERED
+ * -h : compress with Z_HUFFMAN_ONLY
+ * -1 to -9 : compression level
+ */
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int uncompr = 0;
+ gzFile file;
+ char *bname, outmode[20];
+
+ strcpy(outmode, "wb6 ");
+
+ prog = argv[0];
+ bname = strrchr(argv[0], '/');
+ if (bname)
+ bname++;
+ else
+ bname = argv[0];
+ argc--, argv++;
+
+ if (!strcmp(bname, "gunzip") || !strcmp(bname, "zcat"))
+ uncompr = 1;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "-c") == 0)
+ ; /* Just for compatability with gzip */
+ else if (strcmp(*argv, "-d") == 0)
+ uncompr = 1;
+ else if (strcmp(*argv, "-f") == 0)
+ outmode[3] = 'f';
+ else if (strcmp(*argv, "-h") == 0)
+ outmode[3] = 'h';
+ else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
+ (*argv)[2] == 0)
+ outmode[2] = (*argv)[1];
+ else
+ break;
+ argc--, argv++;
+ }
+ if (argc == 0) {
+ SET_BINARY_MODE(stdin);
+ SET_BINARY_MODE(stdout);
+ if (uncompr) {
+ file = gzdopen(fileno(stdin), "rb");
+ if (file == NULL) error("can't gzdopen stdin");
+ gz_uncompress(file, stdout);
+ } else {
+ file = gzdopen(fileno(stdout), outmode);
+ if (file == NULL) error("can't gzdopen stdout");
+ gz_compress(stdin, file);
+ }
+ } else {
+ do {
+ if (uncompr) {
+ file_uncompress(*argv);
+ } else {
+ file_compress(*argv, outmode);
+ }
+ } while (argv++, --argc);
+ }
+ exit(0);
+ return 0; /* to avoid warning */
+}
diff --git a/lib/libz/trees.c b/lib/libz/trees.c
new file mode 100644
index 0000000..bd70440
--- /dev/null
+++ b/lib/libz/trees.c
@@ -0,0 +1,1214 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-1998 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process uses several Huffman trees. The more
+ * common source values are represented by shorter bit sequences.
+ *
+ * Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values). The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ * Storer, James A.
+ * Data Compression: Methods and Theory, pp. 49-50.
+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
+ *
+ * Sedgewick, R.
+ * Algorithms, p290.
+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $FreeBSD$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+# include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6 16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10 17
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
+
+#define REPZ_11_138 18
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+# include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+ const ct_data *static_tree; /* static tree or NULL */
+ const intf *extra_bits; /* extra bits for each code or NULL */
+ int extra_base; /* base index for extra_bits */
+ int elems; /* max number of elements in the tree */
+ int max_length; /* max bit length for the codes */
+};
+
+local static_tree_desc static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc static_d_desc =
+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
+
+local static_tree_desc static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block OF((deflate_state *s));
+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree OF((deflate_state *s, tree_desc *desc));
+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local int build_bl_tree OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+ int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+ ct_data *dtree));
+local void set_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup OF((deflate_state *s));
+local void bi_flush OF((deflate_state *s));
+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
+ int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+ /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+# define send_code(s, c, tree) \
+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+ send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+ put_byte(s, (uch)((w) & 0xff)); \
+ put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+ deflate_state *s;
+ int value; /* value to send */
+ int length; /* number of bits */
+{
+ Tracevv((stderr," l %2d v %4x ", length, value));
+ Assert(length > 0 && length <= 15, "invalid length");
+ s->bits_sent += (ulg)length;
+
+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+ * unused bits in value.
+ */
+ if (s->bi_valid > (int)Buf_size - length) {
+ s->bi_buf |= (value << s->bi_valid);
+ put_short(s, s->bi_buf);
+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+ s->bi_valid += length - Buf_size;
+ } else {
+ s->bi_buf |= value << s->bi_valid;
+ s->bi_valid += length;
+ }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = value;\
+ s->bi_buf |= (val << s->bi_valid);\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+ s->bi_valid += len - Buf_size;\
+ } else {\
+ s->bi_buf |= (value) << s->bi_valid;\
+ s->bi_valid += len;\
+ }\
+}
+#endif /* DEBUG */
+
+
+#define MAX(a,b) (a >= b ? a : b)
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+ static int static_init_done = 0;
+ int n; /* iterates over tree elements */
+ int bits; /* bit counter */
+ int length; /* length value */
+ int code; /* code value */
+ int dist; /* distance index */
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ if (static_init_done) return;
+
+ /* For some embedded targets, global variables are not initialized: */
+ static_l_desc.static_tree = static_ltree;
+ static_l_desc.extra_bits = extra_lbits;
+ static_d_desc.static_tree = static_dtree;
+ static_d_desc.extra_bits = extra_dbits;
+ static_bl_desc.extra_bits = extra_blbits;
+
+ /* Initialize the mapping length (0..255) -> length code (0..28) */
+ length = 0;
+ for (code = 0; code < LENGTH_CODES-1; code++) {
+ base_length[code] = length;
+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
+ _length_code[length++] = (uch)code;
+ }
+ }
+ Assert (length == 256, "tr_static_init: length != 256");
+ /* Note that the length 255 (match length 258) can be represented
+ * in two different ways: code 284 + 5 bits or code 285, so we
+ * overwrite length_code[255] to use the best encoding:
+ */
+ _length_code[length-1] = (uch)code;
+
+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+ dist = 0;
+ for (code = 0 ; code < 16; code++) {
+ base_dist[code] = dist;
+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
+ _dist_code[dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: dist != 256");
+ dist >>= 7; /* from now on, all distances are divided by 128 */
+ for ( ; code < D_CODES; code++) {
+ base_dist[code] = dist << 7;
+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+ _dist_code[256 + dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+ /* Construct the codes of the static literal tree */
+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+ n = 0;
+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+ /* Codes 286 and 287 do not exist, but we must include them in the
+ * tree construction to get a canonical Huffman tree (longest code
+ * all ones)
+ */
+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+ /* The static distance tree is trivial: */
+ for (n = 0; n < D_CODES; n++) {
+ static_dtree[n].Len = 5;
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+ }
+ static_init_done = 1;
+
+# ifdef GEN_TREES_H
+ gen_trees_header();
+# endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+# ifndef DEBUG
+# include <stdio.h>
+# endif
+
+# define SEPARATOR(i, last, width) \
+ ((i) == (last)? "\n};\n\n" : \
+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+ FILE *header = fopen("trees.h", "w");
+ int i;
+
+ Assert (header != NULL, "Can't open trees.h");
+ fprintf(header,
+ "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+ for (i = 0; i < L_CODES+2; i++) {
+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+ }
+
+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+ }
+
+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+ for (i = 0; i < DIST_CODE_LEN; i++) {
+ fprintf(header, "%2u%s", _dist_code[i],
+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
+ }
+
+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+ fprintf(header, "%2u%s", _length_code[i],
+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+ }
+
+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+ for (i = 0; i < LENGTH_CODES; i++) {
+ fprintf(header, "%1u%s", base_length[i],
+ SEPARATOR(i, LENGTH_CODES-1, 20));
+ }
+
+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "%5u%s", base_dist[i],
+ SEPARATOR(i, D_CODES-1, 10));
+ }
+
+ fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(s)
+ deflate_state *s;
+{
+ tr_static_init();
+
+ s->l_desc.dyn_tree = s->dyn_ltree;
+ s->l_desc.stat_desc = &static_l_desc;
+
+ s->d_desc.dyn_tree = s->dyn_dtree;
+ s->d_desc.stat_desc = &static_d_desc;
+
+ s->bl_desc.dyn_tree = s->bl_tree;
+ s->bl_desc.stat_desc = &static_bl_desc;
+
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+ s->compressed_len = 0L;
+ s->bits_sent = 0L;
+#endif
+
+ /* Initialize the first block of the first file: */
+ init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+ deflate_state *s;
+{
+ int n; /* iterates over tree elements */
+
+ /* Initialize the trees. */
+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+ s->dyn_ltree[END_BLOCK].Freq = 1;
+ s->opt_len = s->static_len = 0L;
+ s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+ top = s->heap[SMALLEST]; \
+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+ pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+ (tree[n].Freq < tree[m].Freq || \
+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+ deflate_state *s;
+ ct_data *tree; /* the tree to restore */
+ int k; /* node to move down */
+{
+ int v = s->heap[k];
+ int j = k << 1; /* left son of k */
+ while (j <= s->heap_len) {
+ /* Set j to the smallest of the two sons: */
+ if (j < s->heap_len &&
+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+ j++;
+ }
+ /* Exit if v is smaller than both sons */
+ if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+ /* Exchange v with the smallest son */
+ s->heap[k] = s->heap[j]; k = j;
+
+ /* And continue down the tree, setting j to the left son of k */
+ j <<= 1;
+ }
+ s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ * above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ * array bl_count contains the frequencies for each bit length.
+ * The length opt_len is updated; static_len is also updated if stree is
+ * not null.
+ */
+local void gen_bitlen(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ int max_code = desc->max_code;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ const intf *extra = desc->stat_desc->extra_bits;
+ int base = desc->stat_desc->extra_base;
+ int max_length = desc->stat_desc->max_length;
+ int h; /* heap index */
+ int n, m; /* iterate over the tree elements */
+ int bits; /* bit length */
+ int xbits; /* extra bits */
+ ush f; /* frequency */
+ int overflow = 0; /* number of elements with bit length too large */
+
+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+ /* In a first pass, compute the optimal bit lengths (which may
+ * overflow in the case of the bit length tree).
+ */
+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+ n = s->heap[h];
+ bits = tree[tree[n].Dad].Len + 1;
+ if (bits > max_length) bits = max_length, overflow++;
+ tree[n].Len = (ush)bits;
+ /* We overwrite tree[n].Dad which is no longer needed */
+
+ if (n > max_code) continue; /* not a leaf node */
+
+ s->bl_count[bits]++;
+ xbits = 0;
+ if (n >= base) xbits = extra[n-base];
+ f = tree[n].Freq;
+ s->opt_len += (ulg)f * (bits + xbits);
+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+ }
+ if (overflow == 0) return;
+
+ Trace((stderr,"\nbit length overflow\n"));
+ /* This happens for example on obj2 and pic of the Calgary corpus */
+
+ /* Find the first bit length which could increase: */
+ do {
+ bits = max_length-1;
+ while (s->bl_count[bits] == 0) bits--;
+ s->bl_count[bits]--; /* move one leaf down the tree */
+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+ s->bl_count[max_length]--;
+ /* The brother of the overflow item also moves one step up,
+ * but this does not affect bl_count[max_length]
+ */
+ overflow -= 2;
+ } while (overflow > 0);
+
+ /* Now recompute all bit lengths, scanning in increasing frequency.
+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+ * lengths instead of fixing only the wrong ones. This idea is taken
+ * from 'ar' written by Haruhiko Okumura.)
+ */
+ for (bits = max_length; bits != 0; bits--) {
+ n = s->bl_count[bits];
+ while (n != 0) {
+ m = s->heap[--h];
+ if (m > max_code) continue;
+ if (tree[m].Len != (unsigned) bits) {
+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+ s->opt_len += ((long)bits - (long)tree[m].Len)
+ *(long)tree[m].Freq;
+ tree[m].Len = (ush)bits;
+ }
+ n--;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ * zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+ ct_data *tree; /* the tree to decorate */
+ int max_code; /* largest code with non zero frequency */
+ ushf *bl_count; /* number of codes at each bit length */
+{
+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+ ush code = 0; /* running code value */
+ int bits; /* bit index */
+ int n; /* code index */
+
+ /* The distribution counts are first used to generate the code values
+ * without bit reversal.
+ */
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+ }
+ /* Check that the bit counts in bl_count are consistent. The last code
+ * must be all ones.
+ */
+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+ "inconsistent bit counts");
+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+ for (n = 0; n <= max_code; n++) {
+ int len = tree[n].Len;
+ if (len == 0) continue;
+ /* Now reverse the bits */
+ tree[n].Code = bi_reverse(next_code[len]++, len);
+
+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+ }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ * and corresponding code. The length opt_len is updated; static_len is
+ * also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ int elems = desc->stat_desc->elems;
+ int n, m; /* iterate over heap elements */
+ int max_code = -1; /* largest code with non zero frequency */
+ int node; /* new node being created */
+
+ /* Construct the initial heap, with least frequent element in
+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+ * heap[0] is not used.
+ */
+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++) {
+ if (tree[n].Freq != 0) {
+ s->heap[++(s->heap_len)] = max_code = n;
+ s->depth[n] = 0;
+ } else {
+ tree[n].Len = 0;
+ }
+ }
+
+ /* The pkzip format requires that at least one distance code exists,
+ * and that at least one bit should be sent even if there is only one
+ * possible code. So to avoid special checks later on we force at least
+ * two codes of non zero frequency.
+ */
+ while (s->heap_len < 2) {
+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+ tree[node].Freq = 1;
+ s->depth[node] = 0;
+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+ /* node is 0 or 1 so it does not have extra bits */
+ }
+ desc->max_code = max_code;
+
+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+ * establish sub-heaps of increasing lengths:
+ */
+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+ /* Construct the Huffman tree by repeatedly combining the least two
+ * frequent nodes.
+ */
+ node = elems; /* next internal node of the tree */
+ do {
+ pqremove(s, tree, n); /* n = node of least frequency */
+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+ s->heap[--(s->heap_max)] = m;
+
+ /* Create a new node father of n and m */
+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
+ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
+ tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+ if (tree == s->bl_tree) {
+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+ }
+#endif
+ /* and insert the new node in the heap */
+ s->heap[SMALLEST] = node++;
+ pqdownheap(s, tree, SMALLEST);
+
+ } while (s->heap_len >= 2);
+
+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+ /* At this point, the fields freq and dad are set. We can now
+ * generate the bit lengths.
+ */
+ gen_bitlen(s, (tree_desc *)desc);
+
+ /* The field len is now set, we can generate the bit codes */
+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ if (nextlen == 0) max_count = 138, min_count = 3;
+ tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ s->bl_tree[curlen].Freq += count;
+ } else if (curlen != 0) {
+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+ s->bl_tree[REP_3_6].Freq++;
+ } else if (count <= 10) {
+ s->bl_tree[REPZ_3_10].Freq++;
+ } else {
+ s->bl_tree[REPZ_11_138].Freq++;
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ /* tree[max_code+1].Len = -1; */ /* guard already set */
+ if (nextlen == 0) max_count = 138, min_count = 3;
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+ } else if (curlen != 0) {
+ if (curlen != prevlen) {
+ send_code(s, curlen, s->bl_tree); count--;
+ }
+ Assert(count >= 3 && count <= 6, " 3_6?");
+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+ } else if (count <= 10) {
+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+ } else {
+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+ deflate_state *s;
+{
+ int max_blindex; /* index of last bit length code of non zero freq */
+
+ /* Determine the bit length frequencies for literal and distance trees */
+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+ /* Build the bit length tree: */
+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
+ /* opt_len now includes the length of the tree representations, except
+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+ */
+
+ /* Determine the number of bit length codes to send. The pkzip format
+ * requires that at least 4 bit length codes be sent. (appnote.txt says
+ * 3 but the actual value used is 4.)
+ */
+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+ }
+ /* Update opt_len to include the bit length tree and counts */
+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+ s->opt_len, s->static_len));
+
+ return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+ deflate_state *s;
+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+ int rank; /* index in bl_order */
+
+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+ "too many codes");
+ Tracev((stderr, "\nbl counts: "));
+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+ send_bits(s, dcodes-1, 5);
+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
+ for (rank = 0; rank < blcodes; rank++) {
+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+ }
+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
+#ifdef DEBUG
+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+ s->compressed_len += (stored_len + 4) << 3;
+#endif
+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(s)
+ deflate_state *s;
+{
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+ bi_flush(s);
+ /* Of the 10 bits for the empty block, we have already sent
+ * (10 - bi_valid) bits. The lookahead for the last real code (before
+ * the EOB of the previous block) was thus at least one plus the length
+ * of the EOB plus what we have just sent of the empty static block.
+ */
+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L;
+#endif
+ bi_flush(s);
+ }
+ s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void _tr_flush_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block, or NULL if too old */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+ int max_blindex = 0; /* index of last bit length code of non zero freq */
+
+ /* Build the Huffman trees unless a stored block is forced */
+ if (s->level > 0) {
+
+ /* Check if the file is ascii or binary */
+ if (s->data_type == Z_UNKNOWN) set_data_type(s);
+
+ /* Construct the literal and distance trees */
+ build_tree(s, (tree_desc *)(&(s->l_desc)));
+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+
+ build_tree(s, (tree_desc *)(&(s->d_desc)));
+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+ /* At this point, opt_len and static_len are the total bit lengths of
+ * the compressed block data, excluding the tree representations.
+ */
+
+ /* Build the bit length tree for the above two trees, and get the index
+ * in bl_order of the last bit length code to send.
+ */
+ max_blindex = build_bl_tree(s);
+
+ /* Determine the best encoding. Compute first the block length in bytes*/
+ opt_lenb = (s->opt_len+3+7)>>3;
+ static_lenb = (s->static_len+3+7)>>3;
+
+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+ s->last_lit));
+
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+ } else {
+ Assert(buf != (char*)0, "lost buf");
+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+ }
+
+#ifdef FORCE_STORED
+ if (buf != (char*)0) { /* force stored block */
+#else
+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+ /* 4: two words for the lengths */
+#endif
+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+ * Otherwise we can't have processed more than WSIZE input bytes since
+ * the last block flush, because compression would have been
+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+ * transform a block into a stored block.
+ */
+ _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+ } else if (static_lenb >= 0) { /* force static trees */
+#else
+ } else if (static_lenb == opt_lenb) {
+#endif
+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
+ compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->static_len;
+#endif
+ } else {
+ send_bits(s, (DYN_TREES<<1)+eof, 3);
+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+ max_blindex+1);
+ compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->opt_len;
+#endif
+ }
+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+ /* The above check is made mod 2^32, for files larger than 512 MB
+ * and uLong implemented on 32 bits.
+ */
+ init_block(s);
+
+ if (eof) {
+ bi_windup(s);
+#ifdef DEBUG
+ s->compressed_len += 7; /* align on byte boundary */
+#endif
+ }
+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+ s->compressed_len-7*eof));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (s, dist, lc)
+ deflate_state *s;
+ unsigned dist; /* distance of matched string */
+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+ s->d_buf[s->last_lit] = (ush)dist;
+ s->l_buf[s->last_lit++] = (uch)lc;
+ if (dist == 0) {
+ /* lc is the unmatched char */
+ s->dyn_ltree[lc].Freq++;
+ } else {
+ s->matches++;
+ /* Here, lc is the match length - MIN_MATCH */
+ dist--; /* dist = match distance - 1 */
+ Assert((ush)dist < (ush)MAX_DIST(s) &&
+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
+
+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+ s->dyn_dtree[d_code(dist)].Freq++;
+ }
+
+#ifdef TRUNCATE_BLOCK
+ /* Try to guess if it is profitable to stop the current block here */
+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+ /* Compute an upper bound for the compressed length */
+ ulg out_length = (ulg)s->last_lit*8L;
+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
+ int dcode;
+ for (dcode = 0; dcode < D_CODES; dcode++) {
+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
+ (5L+extra_dbits[dcode]);
+ }
+ out_length >>= 3;
+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+ s->last_lit, in_length, out_length,
+ 100L - out_length*100L/in_length));
+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+ }
+#endif
+ return (s->last_lit == s->lit_bufsize-1);
+ /* We avoid equality with lit_bufsize because of wraparound at 64K
+ * on 16 bit machines and because stored blocks are restricted to
+ * 64K-1 bytes.
+ */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+ deflate_state *s;
+ ct_data *ltree; /* literal tree */
+ ct_data *dtree; /* distance tree */
+{
+ unsigned dist; /* distance of matched string */
+ int lc; /* match length or unmatched char (if dist == 0) */
+ unsigned lx = 0; /* running index in l_buf */
+ unsigned code; /* the code to send */
+ int extra; /* number of extra bits to send */
+
+ if (s->last_lit != 0) do {
+ dist = s->d_buf[lx];
+ lc = s->l_buf[lx++];
+ if (dist == 0) {
+ send_code(s, lc, ltree); /* send a literal byte */
+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+ } else {
+ /* Here, lc is the match length - MIN_MATCH */
+ code = _length_code[lc];
+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
+ extra = extra_lbits[code];
+ if (extra != 0) {
+ lc -= base_length[code];
+ send_bits(s, lc, extra); /* send the extra length bits */
+ }
+ dist--; /* dist is now the match distance - 1 */
+ code = d_code(dist);
+ Assert (code < D_CODES, "bad d_code");
+
+ send_code(s, code, dtree); /* send the distance code */
+ extra = extra_dbits[code];
+ if (extra != 0) {
+ dist -= base_dist[code];
+ send_bits(s, dist, extra); /* send the extra distance bits */
+ }
+ } /* literal or match pair ? */
+
+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
+
+ } while (lx < s->last_lit);
+
+ send_code(s, END_BLOCK, ltree);
+ s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to ASCII or BINARY, using a crude approximation:
+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ */
+local void set_data_type(s)
+ deflate_state *s;
+{
+ int n = 0;
+ unsigned ascii_freq = 0;
+ unsigned bin_freq = 0;
+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
+ s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+ unsigned code; /* the value to invert */
+ int len; /* its bit length */
+{
+ register unsigned res = 0;
+ do {
+ res |= code & 1;
+ code >>= 1, res <<= 1;
+ } while (--len > 0);
+ return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+ deflate_state *s;
+{
+ if (s->bi_valid == 16) {
+ put_short(s, s->bi_buf);
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ } else if (s->bi_valid >= 8) {
+ put_byte(s, (Byte)s->bi_buf);
+ s->bi_buf >>= 8;
+ s->bi_valid -= 8;
+ }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+ deflate_state *s;
+{
+ if (s->bi_valid > 8) {
+ put_short(s, s->bi_buf);
+ } else if (s->bi_valid > 0) {
+ put_byte(s, (Byte)s->bi_buf);
+ }
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef DEBUG
+ s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+ deflate_state *s;
+ charf *buf; /* the input data */
+ unsigned len; /* its length */
+ int header; /* true if block header must be written */
+{
+ bi_windup(s); /* align on byte boundary */
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+
+ if (header) {
+ put_short(s, (ush)len);
+ put_short(s, (ush)~len);
+#ifdef DEBUG
+ s->bits_sent += 2*16;
+#endif
+ }
+#ifdef DEBUG
+ s->bits_sent += (ulg)len<<3;
+#endif
+ while (len--) {
+ put_byte(s, *buf++);
+ }
+}
diff --git a/lib/libz/trees.h b/lib/libz/trees.h
new file mode 100644
index 0000000..72facf9
--- /dev/null
+++ b/lib/libz/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch _dist_code[DIST_CODE_LEN] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
+};
+
diff --git a/lib/libz/uncompr.c b/lib/libz/uncompr.c
new file mode 100644
index 0000000..25472c0
--- /dev/null
+++ b/lib/libz/uncompr.c
@@ -0,0 +1,58 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $FreeBSD$ */
+
+#include "zlib.h"
+
+/* ===========================================================================
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+
+ err = inflateInit(&stream);
+ if (err != Z_OK) return err;
+
+ err = inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ inflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = inflateEnd(&stream);
+ return err;
+}
diff --git a/lib/libz/zconf.h b/lib/libz/zconf.h
new file mode 100644
index 0000000..a294f58
--- /dev/null
+++ b/lib/libz/zconf.h
@@ -0,0 +1,281 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $FreeBSD$ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+# define deflateInit_ z_deflateInit_
+# define deflate z_deflate
+# define deflateEnd z_deflateEnd
+# define inflateInit_ z_inflateInit_
+# define inflate z_inflate
+# define inflateEnd z_inflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateCopy z_deflateCopy
+# define deflateReset z_deflateReset
+# define deflateParams z_deflateParams
+# define inflateInit2_ z_inflateInit2_
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateReset z_inflateReset
+# define compress z_compress
+# define compress2 z_compress2
+# define uncompress z_uncompress
+# define adler32 z_adler32
+# define crc32 z_crc32
+# define get_crc_table z_get_crc_table
+
+# define Byte z_Byte
+# define uInt z_uInt
+# define uLong z_uLong
+# define Bytef z_Bytef
+# define charf z_charf
+# define intf z_intf
+# define uIntf z_uIntf
+# define uLongf z_uLongf
+# define voidpf z_voidpf
+# define voidp z_voidp
+#endif
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+# define WIN32
+#endif
+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
+# ifndef __32BIT__
+# define __32BIT__
+# endif
+#endif
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#if defined(MSDOS) && !defined(__32BIT__)
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
+# define STDC
+#endif
+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
+# ifndef STDC
+# define STDC
+# endif
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const
+# endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Old Borland C incorrectly complains about missing returns: */
+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
+# define NEED_DUMMY_RETURN
+#endif
+
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+#endif
+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
+# ifndef __32BIT__
+# define SMALL_MEDIUM
+# define FAR _far
+# endif
+#endif
+
+/* Compile with -DZLIB_DLL for Windows DLL support */
+#if defined(ZLIB_DLL)
+# if defined(_WINDOWS) || defined(WINDOWS)
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR _cdecl _export
+# endif
+# endif
+# if defined (__BORLANDC__)
+# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
+# include <windows.h>
+# define ZEXPORT __declspec(dllexport) WINAPI
+# define ZEXPORTRVA __declspec(dllexport) WINAPIV
+# else
+# if defined (_Windows) && defined (__DLL__)
+# define ZEXPORT _export
+# define ZEXPORTVA _export
+# endif
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# if defined (ZLIB_DLL)
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+#endif
+
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <sys/types.h> /* for off_t */
+# include <unistd.h> /* for SEEK_* and off_t */
+#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+/*
+ * This is hard-configured for FreeBSD, since zlib doesn't actually support
+ * using the system off_t for offsets unless off_t is no longer than long.
+ */
+#define z_off_t long
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+# pragma map(deflateInit_,"DEIN")
+# pragma map(deflateInit2_,"DEIN2")
+# pragma map(deflateEnd,"DEEND")
+# pragma map(inflateInit_,"ININ")
+# pragma map(inflateInit2_,"ININ2")
+# pragma map(inflateEnd,"INEND")
+# pragma map(inflateSync,"INSY")
+# pragma map(inflateSetDictionary,"INSEDI")
+# pragma map(inflate_blocks,"INBL")
+# pragma map(inflate_blocks_new,"INBLNE")
+# pragma map(inflate_blocks_free,"INBLFR")
+# pragma map(inflate_blocks_reset,"INBLRE")
+# pragma map(inflate_codes_free,"INCOFR")
+# pragma map(inflate_codes,"INCO")
+# pragma map(inflate_fast,"INFA")
+# pragma map(inflate_flush,"INFLU")
+# pragma map(inflate_mask,"INMA")
+# pragma map(inflate_set_dictionary,"INSEDI2")
+# pragma map(inflate_copyright,"INCOPY")
+# pragma map(inflate_trees_bits,"INTRBI")
+# pragma map(inflate_trees_dynamic,"INTRDY")
+# pragma map(inflate_trees_fixed,"INTRFI")
+# pragma map(inflate_trees_free,"INTRFR")
+#endif
+
+#endif /* _ZCONF_H */
diff --git a/lib/libz/zlib.3 b/lib/libz/zlib.3
new file mode 100644
index 0000000..21c7f10
--- /dev/null
+++ b/lib/libz/zlib.3
@@ -0,0 +1,109 @@
+.\" $FreeBSD$
+.\"
+.TH ZLIB 3 "9 July 1998"
+.SH NAME
+zlib \- compression/decompression library
+.SH SYNOPSIS
+[see
+.I zlib.h
+for full description]
+.SH DESCRIPTION
+The
+.I zlib
+library is a general purpose data compression library.
+The code is thread safe.
+It provides in-memory compression and decompression functions,
+including integrity checks of the uncompressed data.
+This version of the library supports only one compression method (deflation)
+but other algorithms will be added later and will have the same stream interface.
+.LP
+Compression can be done in a single step if the buffers are large enough
+(for example if an input file is mmap'ed),
+or can be done by repeated calls of the compression function.
+In the latter case,
+the application must provide more input and/or consume the output
+(providing more output space) before each call.
+.LP
+The library also supports reading and writing files in
+.I gzip
+(.gz) format
+with an interface similar to that of stdio.
+.LP
+The library does not install any signal handler. The decoder checks
+the consistency of the compressed data, so the library should never
+crash even in case of corrupted input.
+.LP
+All functions of the compression library are documented in the file
+.IR zlib.h.
+The distribution source includes examples of use of the library
+the files
+.I example.c
+and
+.IR minigzip.c .
+.LP
+A Java implementation of
+.IR zlib
+is available in the Java Development Kit 1.1
+.IP
+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
+.LP
+A Perl interface to
+.IR zlib ,
+written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
+is available at CPAN (Comprehensive Perl Archive Network) sites,
+such as:
+.IP
+ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib*
+.LP
+A Python interface to
+.IR zlib
+written by A.M. Kuchling <amk@magnet.com>
+is available from the Python Software Association sites, such as:
+.IP
+ftp://ftp.python.org/pub/python/contrib/Encoding/zlib*.tar.gz
+.SH "SEE ALSO"
+Questions about zlib should be sent to:
+.IP
+zlib@quest.jpl.nasa.gov
+or, if this fails, to the author addresses given below.
+The zlib home page is:
+.IP
+http://www.cdrom.com/pub/infozip/zlib/
+.LP
+The data format used by the zlib library is described by RFC
+(Request for Comments) 1950 to 1952 in the files:
+.IP
+ftp://ds.internic.net/rfc/rfc1950.txt (zlib format)
+.br
+rfc1951.txt (deflate format)
+.br
+rfc1952.txt (gzip format)
+.LP
+These documents are also available in other formats from:
+.IP
+ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+.SH AUTHORS
+Version 1.1.3
+Copyright (C) 1995-1998 Jean-loup Gailly (jloup@gzip.org)
+and Mark Adler (madler@alumni.caltech.edu).
+.LP
+This software is provided "as-is,"
+without any express or implied warranty.
+In no event will the authors be held liable for any damages
+arising from the use of this software.
+See the distribution directory with respect to requirements
+governing redistribution.
+The deflate format used by
+.I zlib
+was defined by Phil Katz.
+The deflate and
+.I zlib
+specifications were written by L. Peter Deutsch.
+Thanks to all the people who reported problems and suggested various
+improvements in
+.IR zlib ;
+who are too numerous to cite here.
+.LP
+UNIX manual page by R. P. C. Rodgers,
+U.S. National Library of Medicine (rodgers@nlm.nih.gov).
+.\" end of man page
diff --git a/lib/libz/zlib.h b/lib/libz/zlib.h
new file mode 100644
index 0000000..49f56b4
--- /dev/null
+++ b/lib/libz/zlib.h
@@ -0,0 +1,893 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.1.3, July 9th, 1998
+
+ Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.1.3"
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed
+ data. This version of the library supports only one compression method
+ (deflation) but other algorithms will be added later and will have the same
+ stream interface.
+
+ Compression can be done in a single step if the buffers are large
+ enough (for example if an input file is mmap'ed), or can be done by
+ repeated calls of the compression function. In the latter case, the
+ application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never
+ crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total nb of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total nb of bytes output so far */
+
+ char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: ascii or binary */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ The application must update next_in and avail_in when avail_in has
+ dropped to zero. It must update next_out and avail_out when avail_out
+ has dropped to zero. The application must initialize zalloc, zfree and
+ opaque before calling the init function. All other fields are set by the
+ compression library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this
+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
+ have their offset normalized to zero. The default allocation function
+ provided by this library ensures this (see zutil.c). To reduce memory
+ requirements and avoid any allocation of 64K objects, at the expense of
+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or
+ progress reports. After compression, total_in holds the total size of
+ the uncompressed data and may be saved for use in the decompressor
+ (particularly if the decompressor wants to decompress everything in
+ a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+/* Allowed flush values; see deflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_ASCII 1
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is
+ not compatible with the zlib.h header file used by the application.
+ This check is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller.
+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+ use default allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
+ all (the input data is simply copied a block at a time).
+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+ compression (currently equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION).
+ msg is set to null if there is no error message. deflateInit does not
+ perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce some
+ output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications).
+ Some output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating avail_in or avail_out accordingly; avail_out
+ should never be zero before the call. The application can consume the
+ compressed output when it wants, for example when the output buffer is full
+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+ and with zero avail_out, it must be called again after making room in the
+ output buffer because there might be more output pending.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In particular
+ avail_in is zero after the call if enough output space has been provided
+ before the call.) Flushing may degrade compression for some compression
+ algorithms and so it should be used only when necessary.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ the compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out).
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there
+ was enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the
+ stream are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least
+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
+ Z_STREAM_END, then it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update data_type if it can make a good guess about
+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect
+ the compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero).
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case,
+ msg may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+ value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller. msg is set to null if there is no error
+ message. inflateInit does not perform any decompression apart from reading
+ the zlib header if present: this will be done by inflate(). (So next_in and
+ avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may some
+ introduce some output latency (reading input without producing any output)
+ except when forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing
+ will resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there
+ is no more input data or no more space in the output buffer (see below
+ about the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating the next_* and avail_* values accordingly.
+ The application can consume the uncompressed output when it wants, for
+ example when the output buffer is full (avail_out == 0), or after each
+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+ must be called again after making room in the output buffer because there
+ might be more output pending.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
+ output as possible to the output buffer. The flushing behavior of inflate is
+ not specified for values of the flush parameter other than Z_SYNC_FLUSH
+ and Z_FINISH, but the current implementation actually flushes as much output
+ as possible anyway.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step
+ (a single call of inflate), the parameter flush should be set to
+ Z_FINISH. In this case all pending input is processed and all pending
+ output is flushed; avail_out must be large enough to hold all the
+ uncompressed data. (The size of the uncompressed data may have been saved
+ by the compressor for this purpose.) The next operation on this stream must
+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+ is never required, but can be used to inform inflate that a faster routine
+ may be used for the single inflate() call.
+
+ If a preset dictionary is needed at this point (see inflateSetDictionary
+ below), inflate sets strm-adler to the adler32 checksum of the
+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
+ it sets strm->adler to the adler32 checksum of all output produced
+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
+ an error code as described below. At the end of the stream, inflate()
+ checks that its computed adler32 checksum is equal to that saved by the
+ compressor and returns Z_STREAM_END only if the checksum is correct.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect
+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not
+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
+ case, the application may then call inflateSync to look for a good
+ compression block.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by
+ the caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but
+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
+ for optimal speed. The default value is 8. See zconf.h for total memory
+ usage as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match). Filtered data consists mostly of small values with a
+ somewhat random distribution. In this case, the compression algorithm is
+ tuned to compress them better. The effect of Z_FILTERED is to force more
+ Huffman coding and less string matching; it is somewhat intermediate
+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
+ the compression ratio but not the correctness of the compressed output even
+ if it is not set appropriately.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+ method). msg is set to null if there is no error message. deflateInit2 does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. This function must be called
+ immediately after deflateInit, deflateInit2 or deflateReset, before any
+ call of deflate. The compressor and decompressor must use exactly the same
+ dictionary (see inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size in
+ deflate or deflate2. Thus the strings most likely to be useful should be
+ put at the end of the dictionary, not at the front.
+
+ Upon return of this function, strm->adler is set to the Adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The Adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.)
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if the compression method is bsort). deflateSetDictionary does not
+ perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and
+ can consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state.
+ The stream will keep the same compression level and any other attributes
+ that may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different
+ strategy. If the compression level is changed, the input available so far
+ is compressed with the old level (and may be flushed); the new level will
+ take effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to
+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+ if strm->avail_out was zero.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. If a compressed stream with a larger window size is given as
+ input, inflate() will return with the error code Z_DATA_ERROR instead of
+ trying to allocate a larger window.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
+ memLevel). msg is set to null if there is no error message. inflateInit2
+ does not perform any decompression apart from reading the zlib header if
+ present: this will be done by inflate(). (So next_in and avail_in may be
+ modified, but next_out and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate
+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the Adler32 value returned by this call of
+ inflate. The compressor and decompressor must use exactly the same
+ dictionary (see deflateSetDictionary).
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect Adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a full flush point (see above the
+ description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+ case, the application may save the current current value of total_in which
+ indicates where valid compressed data was found. In the error case, the
+ application may repeatedly call inflateSync, providing more input each time,
+ until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state.
+ The stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the
+ basic stream-oriented functions. To simplify the interface, some
+ default options are assumed (compression level and memory usage,
+ standard memory allocation functions). The source code of these
+ utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be at least 0.1% larger than
+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
+ compressed buffer.
+ This function can be used to compress a whole file at once if the
+ input file is mmap'ed.
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+/*
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb") but can also include a compression level
+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+ Huffman only compression as in "wb1h". (See the description
+ of deflateInit2 for more information about the strategy parameter.)
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression.
+
+ gzopen returns NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR). */
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen() associates a gzFile with the file descriptor fd. File
+ descriptors are obtained from calls like open, dup, creat, pipe or
+ fileno (in the file has been previously opened with fopen).
+ The mode parameter is as in gzopen.
+ The next call of gzclose on the returned gzFile will also close the
+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+ gzdopen returns NULL if there was insufficient memory to allocate
+ the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file.
+ If the input file was not in gzip format, gzread copies the given number
+ of bytes into the buffer.
+ gzread returns the number of uncompressed bytes actually read (0 for
+ end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ const voidp buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes actually written
+ (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or
+ a newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. The string is then terminated with a null
+ character.
+ gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function. The return value is the zlib
+ error number (see function gzerror below). gzflush returns Z_OK if
+ the flush parameter is Z_FINISH and all output could be flushed.
+ gzflush should be called only when strictly necessary because it can
+ degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+/*
+ Sets the starting position for the next gzread or gzwrite on the
+ given compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+/*
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state. The return value is the zlib
+ error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occurred in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the
+ compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is NULL, this function returns
+ the required initial value for the checksum.
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster. Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running crc with the bytes buf[0..len-1] and return the updated
+ crc. If buf is NULL, this function returns the required initial value
+ for the crc. Pre- and post-conditioning (one's complement) is performed
+ within this function so it shouldn't be done by the application.
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char * ZEXPORT zError OF((int err));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZLIB_H */
diff --git a/lib/libz/zutil.c b/lib/libz/zutil.c
new file mode 100644
index 0000000..8419dbc
--- /dev/null
+++ b/lib/libz/zutil.c
@@ -0,0 +1,225 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $FreeBSD$ */
+
+#include "zutil.h"
+
+struct internal_state {int dummy;}; /* for buggy compilers */
+
+#ifndef STDC
+extern void exit OF((int));
+#endif
+
+const char *z_errmsg[10] = {
+"need dictionary", /* Z_NEED_DICT 2 */
+"stream end", /* Z_STREAM_END 1 */
+"", /* Z_OK 0 */
+"file error", /* Z_ERRNO (-1) */
+"stream error", /* Z_STREAM_ERROR (-2) */
+"data error", /* Z_DATA_ERROR (-3) */
+"insufficient memory", /* Z_MEM_ERROR (-4) */
+"buffer error", /* Z_BUF_ERROR (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+ return ZLIB_VERSION;
+}
+
+#ifdef DEBUG
+
+# ifndef verbose
+# define verbose 0
+# endif
+int z_verbose = verbose;
+
+void z_error (m)
+ char *m;
+{
+ fprintf(stderr, "%s\n", m);
+ exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+ int err;
+{
+ return ERR_MSG(err);
+}
+
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+ Bytef* dest;
+ const Bytef* source;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = *source++; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+ const Bytef* s1;
+ const Bytef* s2;
+ uInt len;
+{
+ uInt j;
+
+ for (j = 0; j < len; j++) {
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+ }
+ return 0;
+}
+
+void zmemzero(dest, len)
+ Bytef* dest;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = 0; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+#endif
+
+#ifdef __TURBOC__
+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
+/* Small and medium model in Turbo C are for now limited to near allocation
+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
+ */
+# define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+ voidpf org_ptr;
+ voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ voidpf buf = opaque; /* just to make some compilers happy */
+ ulg bsize = (ulg)items*size;
+
+ /* If we allocate less than 65520 bytes, we assume that farmalloc
+ * will return a usable pointer which doesn't have to be normalized.
+ */
+ if (bsize < 65520L) {
+ buf = farmalloc(bsize);
+ if (*(ush*)&buf != 0) return buf;
+ } else {
+ buf = farmalloc(bsize + 16L);
+ }
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+ table[next_ptr].org_ptr = buf;
+
+ /* Normalize the pointer to seg:0 */
+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+ *(ush*)&buf = 0;
+ table[next_ptr++].new_ptr = buf;
+ return buf;
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ int n;
+ if (*(ush*)&ptr != 0) { /* object < 64K */
+ farfree(ptr);
+ return;
+ }
+ /* Find the original pointer */
+ for (n = 0; n < next_ptr; n++) {
+ if (ptr != table[n].new_ptr) continue;
+
+ farfree(table[n].org_ptr);
+ while (++n < next_ptr) {
+ table[n-1] = table[n];
+ }
+ next_ptr--;
+ return;
+ }
+ ptr = opaque; /* just to make some compilers happy */
+ Assert(0, "zcfree: ptr not found");
+}
+#endif
+#endif /* __TURBOC__ */
+
+
+#if defined(M_I86) && !defined(__32BIT__)
+/* Microsoft C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+# define _halloc halloc
+# define _hfree hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ return _halloc((long)items, size);
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ _hfree(ptr);
+}
+
+#endif /* MSC */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp calloc OF((uInt items, uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+ voidpf opaque;
+ unsigned items;
+ unsigned size;
+{
+ if (opaque) items += size - size; /* make compiler happy */
+ return (voidpf)calloc(items, size);
+}
+
+void zcfree (opaque, ptr)
+ voidpf opaque;
+ voidpf ptr;
+{
+ free(ptr);
+ if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/lib/libz/zutil.h b/lib/libz/zutil.h
new file mode 100644
index 0000000..378703d
--- /dev/null
+++ b/lib/libz/zutil.h
@@ -0,0 +1,220 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $FreeBSD$ */
+
+#ifndef _Z_UTIL_H
+#define _Z_UTIL_H
+
+#include "zlib.h"
+
+#ifdef STDC
+# include <stddef.h>
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+ extern int errno;
+#else
+# include <errno.h>
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+ return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+ /* common constants */
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+#ifdef MSDOS
+# define OS_CODE 0x00
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
+# endif
+#endif
+
+#ifdef OS2
+# define OS_CODE 0x06
+#endif
+
+#ifdef WIN32 /* Window 95 & Windows NT */
+# define OS_CODE 0x0b
+#endif
+
+#if defined(VAXC) || defined(VMS)
+# define OS_CODE 0x02
+# define F_OPEN(name, mode) \
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#ifdef AMIGA
+# define OS_CODE 0x01
+#endif
+
+#if defined(ATARI) || defined(atarist)
+# define OS_CODE 0x05
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+# define OS_CODE 0x07
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+# define OS_CODE 0x0F
+#endif
+
+#ifdef TOPS20
+# define OS_CODE 0x0a
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600))
+# define fdopen(fd,type) _fdopen(fd,type)
+#endif
+
+
+ /* Common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 0x03 /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+# define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+ /* functions */
+
+#ifdef HAVE_STRERROR
+ extern char *strerror OF((int));
+# define zstrerror(errnum) strerror(errnum)
+#else
+# define zstrerror(errnum) ""
+#endif
+
+#if defined(pyr)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+# define zmemcpy _fmemcpy
+# define zmemcmp _fmemcmp
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
+# else
+# define zmemcpy memcpy
+# define zmemcmp memcmp
+# define zmemzero(dest, len) memset(dest, 0, len)
+# endif
+#else
+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# include <stdio.h>
+ extern int z_verbose;
+ extern void z_error OF((char *m));
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+
+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
+ uInt len));
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void zcfree OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* _Z_UTIL_H */
diff --git a/lib/msun/Makefile b/lib/msun/Makefile
new file mode 100644
index 0000000..4281b14
--- /dev/null
+++ b/lib/msun/Makefile
@@ -0,0 +1,171 @@
+# @(#)Makefile 5.1beta 93/09/24
+# $FreeBSD$
+#
+# ====================================================
+# Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+#
+# Developed at SunPro, a Sun Microsystems, Inc. business.
+# Permission to use, copy, modify, and distribute this
+# software is freely granted, provided that this notice
+# is preserved.
+# ====================================================
+#
+#
+
+#
+# There are two options in making libm at fdlibm compile time:
+# _IEEE_LIBM --- IEEE libm; smaller, and somewhat faster
+# _MULTI_LIBM --- Support multi-standard at runtime by
+# imposing wrapper functions defined in
+# fdlibm.h:
+# _IEEE_MODE -- IEEE
+# _XOPEN_MODE -- X/OPEN
+# _POSIX_MODE -- POSIX/ANSI
+# _SVID3_MODE -- SVID
+#
+# Here is how to set up CFLAGS to create the desired libm at
+# compile time:
+#
+# CFLAGS = -D_IEEE_LIBM ... IEEE libm (recommended)
+# CFLAGS = -D_SVID3_MODE ... Multi-standard supported
+# libm with SVID as the
+# default standard
+# CFLAGS = -D_XOPEN_MODE ... Multi-standard supported
+# libm with XOPEN as the
+# default standard
+# CFLAGS = -D_POSIX_MODE ... Multi-standard supported
+# libm with POSIX as the
+# default standard
+# CFLAGS = ... Multi-standard supported
+# libm with IEEE as the
+# default standard
+#
+
+.if ${MACHINE_ARCH} == "alpha"
+.PATH: ${.CURDIR)/alpha
+ARCH= alpha
+ARCH_SRCS = s_copysign.S s_copysignf.S
+# XXX Comment from NetBSD/Alpha:
+# XXX LINT SIGFPEs in e_exp.c's strtod(). FP underflow/denorm software
+# handling is broken (doesn't exist!) on the Alpha port.
+# Stock gcc 2.7.2.1 doesn't understand these options.
+#CFLAGS += -mtrap-precision=i -mfp-trap-mode=su
+.elif ${MACHINE_ARCH} == "i386"
+ARCH= i387
+ARCH_PREFIX= ${ARCH}_
+ARCH_SRCS = e_acos.S e_asin.S e_atan2.S e_exp.S e_fmod.S e_log.S e_log10.S \
+ e_remainder.S e_scalb.S e_sqrt.S s_atan.S s_ceil.S s_copysign.S \
+ s_cos.S s_finite.S s_floor.S s_ilogb.S s_logb.S \
+ s_rint.S s_scalbn.S s_significand.S s_sin.S s_tan.S
+.elif ${MACHINE_ARCH} == "m68k"
+.PATH: ${.CURDIR}/mc68881
+ARCH_SRCS = e_acos.S e_asin.S e_atanh.S e_cosh.S e_exp.S e_fmod.S e_log.S \
+ e_log10.S e_remainder.S e_scalb.S e_sinh.S e_sqrt.S s_atan.S \
+ s_ceil.S s_copysign.S s_cos.S s_expm1.S s_finite.S s_floor.S \
+ s_log1p.S s_logb.S s_rint.S s_scalbn.S s_sin.S s_tan.S s_tanh.S
+.endif
+
+# Broken
+# ARCH_SRCS+= s_log1p.S
+
+.PATH: ${.CURDIR}/man
+.PATH: ${.CURDIR}/src
+
+CFLAGS+= -D_IEEE_LIBM -D_ARCH_INDIRECT=${ARCH_PREFIX}
+
+LIB= m
+COMMON_SRCS = e_acos.c e_acosf.c e_acosh.c e_acoshf.c e_asin.c e_asinf.c \
+ e_atan2.c e_atan2f.c e_atanh.c e_atanhf.c e_cosh.c e_coshf.c e_exp.c \
+ e_expf.c e_fmod.c e_fmodf.c e_gamma.c e_gamma_r.c e_gammaf.c \
+ e_gammaf_r.c e_hypot.c e_hypotf.c e_j0.c e_j0f.c e_j1.c e_j1f.c \
+ e_jn.c e_jnf.c e_lgamma.c e_lgamma_r.c e_lgammaf.c e_lgammaf_r.c \
+ e_log.c e_log10.c e_log10f.c e_logf.c e_pow.c e_powf.c e_rem_pio2.c \
+ e_rem_pio2f.c e_remainder.c e_remainderf.c e_scalb.c e_scalbf.c \
+ e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c \
+ get_hw_float.c \
+ k_cos.c k_cosf.c k_rem_pio2.c k_rem_pio2f.c k_sin.c k_sinf.c \
+ k_standard.c k_tan.c k_tanf.c \
+ s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_cbrt.c s_cbrtf.c s_ceil.c \
+ s_ceilf.c s_copysign.c s_copysignf.c s_cos.c s_cosf.c s_erf.c s_erff.c \
+ s_expm1.c s_expm1f.c s_fabsf.c s_finite.c s_finitef.c \
+ s_floor.c s_floorf.c s_frexpf.c s_ilogb.c s_ilogbf.c \
+ s_isnanf.c s_ldexpf.c s_lib_version.c s_log1p.c \
+ s_log1pf.c s_logb.c s_logbf.c s_matherr.c s_modff.c \
+ s_nextafter.c s_nextafterf.c s_rint.c s_rintf.c s_scalbn.c s_scalbnf.c \
+ s_signgam.c s_significand.c s_significandf.c s_sin.c s_sinf.c s_tan.c \
+ s_tanf.c s_tanh.c s_tanhf.c \
+ w_acos.c w_acosf.c w_acosh.c w_acoshf.c w_asin.c w_asinf.c w_atan2.c \
+ w_atan2f.c w_atanh.c w_atanhf.c w_cabs.c w_cabsf.c w_cosh.c w_coshf.c \
+ w_drem.c w_dremf.c w_exp.c w_expf.c w_fmod.c w_fmodf.c w_gamma.c \
+ w_gamma_r.c w_gammaf.c w_gammaf_r.c w_hypot.c w_hypotf.c w_j0.c \
+ w_j0f.c w_j1.c w_j1f.c w_jn.c w_jnf.c w_lgamma.c w_lgamma_r.c \
+ w_lgammaf.c w_lgammaf_r.c w_log.c w_log10.c w_log10f.c w_logf.c \
+ w_pow.c w_powf.c w_remainder.c w_remainderf.c w_scalb.c w_scalbf.c \
+ w_sinh.c w_sinhf.c w_sqrt.c w_sqrtf.c \
+ w_y0.c w_y0f.c w_y1.c w_y1f.c w_yn.c w_ynf.c
+
+# FreeBSD's C library supplies these functions:
+#COMMON_SRCS+= s_fabs.c s_frexp.c s_isnan.c s_ldexp.c s_modf.c
+
+CLEANFILES+= ${RENAMED_ARCH_SRCS}
+RENAMED_ARCH_SRCS= ${ARCH_SRCS:S/^/${ARCH_PREFIX}/g}
+SRCS= ${COMMON_SRCS} ${RENAMED_ARCH_SRCS}
+
+# Generate rules to rename arch-specific sources to avoid conflicts.
+# The path to the arch-specific sources is given explicitly instead of
+# with `.PATH: ${.CURDIR}/${ARCH}' since otherwise bsd.lib.mk would
+# use .S.o rules instead of .c.o rules for the conflicting prefixes
+# (except after `make depend' it uses the correct rules!).
+.for i in ${ARCH_SRCS}
+${ARCH_PREFIX}${i}: ${.CURDIR}/${ARCH}/${i}
+ cp ${.ALLSRC} ${.TARGET}
+.endfor
+
+MANSRC= ${.CURDIR}/man
+
+MAN3+= acos.3 acosh.3 asin.3 asinh.3 atan.3 atan2.3 atanh.3 ceil.3 \
+ cos.3 cosh.3 erf.3 exp.3 fabs.3 floor.3 fmod.3 hypot.3 ieee.3 \
+ ieee_test.3 j0.3 lgamma.3 math.3 rint.3 sin.3 sinh.3 sqrt.3 \
+ tan.3 tanh.3
+
+MLINKS+=acos.3 acosf.3
+MLINKS+=acosh.3 acoshf.3
+MLINKS+=asin.3 asinf.3
+MLINKS+=asinh.3 asinhf.3
+MLINKS+=atan.3 atanf.3
+MLINKS+=atanh.3 atanhf.3
+MLINKS+=atan2.3 atan2f.3
+MLINKS+=ceil.3 ceilf.3
+MLINKS+=cos.3 cosf.3
+MLINKS+=cosh.3 coshf.3
+MLINKS+=erf.3 erfc.3 erf.3 erff.3 erf.3 erfcf.3
+MLINKS+=exp.3 expm1.3 exp.3 log.3 exp.3 log10.3 exp.3 log1p.3 exp.3 pow.3 \
+ exp.3 expf.3 exp.3 exp2.3 exp.3 exp2f.3 exp.3 exp10.3 exp.3 exp10f.3 \
+ exp.3 expm1f.3 exp.3 logf.3 exp.3 log2.3 exp.3 log2f.3 exp.3 powf.3 \
+ exp.3 log10f.3 exp.3 log1pf.3
+MLINKS+=fabs.3 fabsf.3
+MLINKS+=floor.3 floorf.3
+MLINKS+=fmod.3 fmodf.3
+MLINKS+=hypot.3 cabs.3 hypot.3 cabsf.3 hypot.3 hypotf.3
+MLINKS+=ieee.3 copysign.3 ieee.3 copysignf.3 ieee.3 finite.3 ieee.3 finitef.3 \
+ ieee.3 ilogb.3 ieee.3 ilogbf.3 ieee.3 nextafter.3 ieee.3 nextafterf.3 \
+ ieee.3 remainder.3 ieee.3 remainderf.3 ieee.3 scalbn.3 ieee.3 scalbnf.3
+MLINKS+=ieee_test.3 logb.3 ieee_test.3 logbf.3
+MLINKS+=ieee_test.3 scalb.3 ieee_test.3 scalbf.3
+MLINKS+=ieee_test.3 significand.3 ieee_test.3 significandf.3
+MLINKS+=j0.3 j1.3 j0.3 jn.3 j0.3 y0.3 j0.3 y1.3 j0.3 y1f.3 j0.3 yn.3
+MLINKS+=j0.3 j0f.3 j0.3 j1f.3 j0.3 jnf.3 j0.3 y0f.3 j0.3 ynf.3
+MLINKS+=lgamma.3 gamma.3 lgamma.3 lgammaf.3 lgamma.3 gammaf.3
+MLINKS+=rint.3 rintf.3
+MLINKS+=sin.3 sinf.3
+MLINKS+=sinh.3 sinhf.3
+MLINKS+=sqrt.3 cbrt.3 sqrt.3 cbrtf.3 sqrt.3 sqrtf.3
+MLINKS+=tan.3 tanf.3
+MLINKS+=tanh.3 tanhf.3
+
+# XXX we should have only one math.h, and a rule for installing .h's...
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/src/math.h \
+ ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/msun/alpha/s_copysign.S b/lib/msun/alpha/s_copysign.S
new file mode 100644
index 0000000..2a724e2
--- /dev/null
+++ b/lib/msun/alpha/s_copysign.S
@@ -0,0 +1,45 @@
+/* $FreeBSD$ */
+/* From: NetBSD: s_copysign.S,v 1.3 1997/07/30 23:58:38 jtc Exp */
+
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by J.T. Conklin.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+LEAF(copysign, 2)
+ cpys fa1, fa0, fv0
+ RET
+END(copysign)
diff --git a/lib/msun/alpha/s_copysignf.S b/lib/msun/alpha/s_copysignf.S
new file mode 100644
index 0000000..d8a42a4
--- /dev/null
+++ b/lib/msun/alpha/s_copysignf.S
@@ -0,0 +1,45 @@
+/* $FreeBSD$ */
+/* From: NetBSD: s_copysignf.S,v 1.3 1997/07/30 23:58:41 jtc Exp */
+
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by J.T. Conklin.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+LEAF(copysignf, 2)
+ cpys fa1, fa0, fv0
+ RET
+END(copysignf)
diff --git a/lib/msun/bsdsrc/b_exp.c b/lib/msun/bsdsrc/b_exp.c
new file mode 100644
index 0000000..fa6ea75
--- /dev/null
+++ b/lib/msun/bsdsrc/b_exp.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)exp.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* EXP(X)
+ * RETURN THE EXPONENTIAL OF X
+ * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS)
+ * CODED IN C BY K.C. NG, 1/19/85;
+ * REVISED BY K.C. NG on 2/6/85, 2/15/85, 3/7/85, 3/24/85, 4/16/85, 6/14/86.
+ *
+ * Required system supported functions:
+ * scalb(x,n)
+ * copysign(x,y)
+ * finite(x)
+ *
+ * Method:
+ * 1. Argument Reduction: given the input x, find r and integer k such
+ * that
+ * x = k*ln2 + r, |r| <= 0.5*ln2 .
+ * r will be represented as r := z+c for better accuracy.
+ *
+ * 2. Compute exp(r) by
+ *
+ * exp(r) = 1 + r + r*R1/(2-R1),
+ * where
+ * R1 = x - x^2*(p1+x^2*(p2+x^2*(p3+x^2*(p4+p5*x^2)))).
+ *
+ * 3. exp(x) = 2^k * exp(r) .
+ *
+ * Special cases:
+ * exp(INF) is INF, exp(NaN) is NaN;
+ * exp(-INF)= 0;
+ * for finite argument, only exp(0)=1 is exact.
+ *
+ * Accuracy:
+ * exp(x) returns the exponential of x nearly rounded. In a test run
+ * with 1,156,000 random arguments on a VAX, the maximum observed
+ * error was 0.869 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+vc(lnhuge, 9.4961163736712506989E1 ,ec1d,43bd,9010,a73e, 7, .BDEC1DA73E9010)
+vc(lntiny,-9.5654310917272452386E1 ,4f01,c3bf,33af,d72e, 7,-.BF4F01D72E33AF)
+vc(invln2, 1.4426950408889634148E0 ,aa3b,40b8,17f1,295c, 1, .B8AA3B295C17F1)
+vc(p1, 1.6666666666666602251E-1 ,aaaa,3f2a,a9f1,aaaa, -2, .AAAAAAAAAAA9F1)
+vc(p2, -2.7777777777015591216E-3 ,0b60,bc36,ec94,b5f5, -8,-.B60B60B5F5EC94)
+vc(p3, 6.6137563214379341918E-5 ,b355,398a,f15f,792e, -13, .8AB355792EF15F)
+vc(p4, -1.6533902205465250480E-6 ,ea0e,b6dd,5f84,2e93, -19,-.DDEA0E2E935F84)
+vc(p5, 4.1381367970572387085E-8 ,bb4b,3431,2683,95f5, -24, .B1BB4B95F52683)
+
+#ifdef vccast
+#define ln2hi vccast(ln2hi)
+#define ln2lo vccast(ln2lo)
+#define lnhuge vccast(lnhuge)
+#define lntiny vccast(lntiny)
+#define invln2 vccast(invln2)
+#define p1 vccast(p1)
+#define p2 vccast(p2)
+#define p3 vccast(p3)
+#define p4 vccast(p4)
+#define p5 vccast(p5)
+#endif
+
+ic(p1, 1.6666666666666601904E-1, -3, 1.555555555553E)
+ic(p2, -2.7777777777015593384E-3, -9, -1.6C16C16BEBD93)
+ic(p3, 6.6137563214379343612E-5, -14, 1.1566AAF25DE2C)
+ic(p4, -1.6533902205465251539E-6, -20, -1.BBD41C5D26BF1)
+ic(p5, 4.1381367970572384604E-8, -25, 1.6376972BEA4D0)
+ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10,-33, 1.A39EF35793C76)
+ic(lnhuge, 7.1602103751842355450E2, 9, 1.6602B15B7ECF2)
+ic(lntiny,-7.5137154372698068983E2, 9, -1.77AF8EBEAE354)
+ic(invln2, 1.4426950408889633870E0, 0, 1.71547652B82FE)
+
+double exp(x)
+double x;
+{
+ double z,hi,lo,c;
+ int k;
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ if( x <= lnhuge ) {
+ if( x >= lntiny ) {
+
+ /* argument reduction : x --> x - k*ln2 */
+
+ k=invln2*x+copysign(0.5,x); /* k=NINT(x/ln2) */
+
+ /* express x-k*ln2 as hi-lo and let x=hi-lo rounded */
+
+ hi=x-k*ln2hi;
+ x=hi-(lo=k*ln2lo);
+
+ /* return 2^k*[1+x+x*c/(2+c)] */
+ z=x*x;
+ c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5))));
+ return scalb(1.0+(hi-(lo-(x*c)/(2.0-c))),k);
+
+ }
+ /* end of x > lntiny */
+
+ else
+ /* exp(-big#) underflows to zero */
+ if(finite(x)) return(scalb(1.0,-5000));
+
+ /* exp(-INF) is zero */
+ else return(0.0);
+ }
+ /* end of x < lnhuge */
+
+ else
+ /* exp(INF) is INF, exp(+big#) overflows to INF */
+ return( finite(x) ? scalb(1.0,5000) : x);
+}
+
+/* returns exp(r = x + c) for |c| < |x| with no overlap. */
+
+double __exp__D(x, c)
+double x, c;
+{
+ double z,hi,lo, t;
+ int k;
+
+#if !defined(vax)&&!defined(tahoe)
+ if (x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ if ( x <= lnhuge ) {
+ if ( x >= lntiny ) {
+
+ /* argument reduction : x --> x - k*ln2 */
+ z = invln2*x;
+ k = z + copysign(.5, x);
+
+ /* express (x+c)-k*ln2 as hi-lo and let x=hi-lo rounded */
+
+ hi=(x-k*ln2hi); /* Exact. */
+ x= hi - (lo = k*ln2lo-c);
+ /* return 2^k*[1+x+x*c/(2+c)] */
+ z=x*x;
+ c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5))));
+ c = (x*c)/(2.0-c);
+
+ return scalb(1.+(hi-(lo - c)), k);
+ }
+ /* end of x > lntiny */
+
+ else
+ /* exp(-big#) underflows to zero */
+ if(finite(x)) return(scalb(1.0,-5000));
+
+ /* exp(-INF) is zero */
+ else return(0.0);
+ }
+ /* end of x < lnhuge */
+
+ else
+ /* exp(INF) is INF, exp(+big#) overflows to INF */
+ return( finite(x) ? scalb(1.0,5000) : x);
+}
diff --git a/lib/msun/bsdsrc/b_log.c b/lib/msun/bsdsrc/b_log.c
new file mode 100644
index 0000000..908b8544
--- /dev/null
+++ b/lib/msun/bsdsrc/b_log.c
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log.c 8.2 (Berkeley) 11/30/93";
+#endif /* not lint */
+
+#include <math.h>
+#include <errno.h>
+
+#include "mathimpl.h"
+
+/* Table-driven natural logarithm.
+ *
+ * This code was derived, with minor modifications, from:
+ * Peter Tang, "Table-Driven Implementation of the
+ * Logarithm in IEEE Floating-Point arithmetic." ACM Trans.
+ * Math Software, vol 16. no 4, pp 378-400, Dec 1990).
+ *
+ * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256,
+ * where F = j/128 for j an integer in [0, 128].
+ *
+ * log(2^m) = log2_hi*m + log2_tail*m
+ * since m is an integer, the dominant term is exact.
+ * m has at most 10 digits (for subnormal numbers),
+ * and log2_hi has 11 trailing zero bits.
+ *
+ * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h
+ * logF_hi[] + 512 is exact.
+ *
+ * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ...
+ * the leading term is calculated to extra precision in two
+ * parts, the larger of which adds exactly to the dominant
+ * m and F terms.
+ * There are two cases:
+ * 1. when m, j are non-zero (m | j), use absolute
+ * precision for the leading term.
+ * 2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1).
+ * In this case, use a relative precision of 24 bits.
+ * (This is done differently in the original paper)
+ *
+ * Special cases:
+ * 0 return signalling -Inf
+ * neg return signalling NaN
+ * +Inf return +Inf
+*/
+
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+#define TRUNC(x) x = (double) (float) (x)
+#else
+#define _IEEE 1
+#define endian (((*(int *) &one)) ? 1 : 0)
+#define TRUNC(x) *(((int *) &x) + endian) &= 0xf8000000
+#define infnan(x) 0.0
+#endif
+
+#define N 128
+
+/* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128.
+ * Used for generation of extend precision logarithms.
+ * The constant 35184372088832 is 2^45, so the divide is exact.
+ * It ensures correct reading of logF_head, even for inaccurate
+ * decimal-to-binary conversion routines. (Everybody gets the
+ * right answer for integers less than 2^53.)
+ * Values for log(F) were generated using error < 10^-57 absolute
+ * with the bc -l package.
+*/
+static double A1 = .08333333333333178827;
+static double A2 = .01250000000377174923;
+static double A3 = .002232139987919447809;
+static double A4 = .0004348877777076145742;
+
+static double logF_head[N+1] = {
+ 0.,
+ .007782140442060381246,
+ .015504186535963526694,
+ .023167059281547608406,
+ .030771658666765233647,
+ .038318864302141264488,
+ .045809536031242714670,
+ .053244514518837604555,
+ .060624621816486978786,
+ .067950661908525944454,
+ .075223421237524235039,
+ .082443669210988446138,
+ .089612158689760690322,
+ .096729626458454731618,
+ .103796793681567578460,
+ .110814366340264314203,
+ .117783035656430001836,
+ .124703478501032805070,
+ .131576357788617315236,
+ .138402322859292326029,
+ .145182009844575077295,
+ .151916042025732167530,
+ .158605030176659056451,
+ .165249572895390883786,
+ .171850256926518341060,
+ .178407657472689606947,
+ .184922338493834104156,
+ .191394852999565046047,
+ .197825743329758552135,
+ .204215541428766300668,
+ .210564769107350002741,
+ .216873938300523150246,
+ .223143551314024080056,
+ .229374101064877322642,
+ .235566071312860003672,
+ .241719936886966024758,
+ .247836163904594286577,
+ .253915209980732470285,
+ .259957524436686071567,
+ .265963548496984003577,
+ .271933715484010463114,
+ .277868451003087102435,
+ .283768173130738432519,
+ .289633292582948342896,
+ .295464212893421063199,
+ .301261330578199704177,
+ .307025035294827830512,
+ .312755710004239517729,
+ .318453731118097493890,
+ .324119468654316733591,
+ .329753286372579168528,
+ .335355541920762334484,
+ .340926586970454081892,
+ .346466767346100823488,
+ .351976423156884266063,
+ .357455888922231679316,
+ .362905493689140712376,
+ .368325561158599157352,
+ .373716409793814818840,
+ .379078352934811846353,
+ .384411698910298582632,
+ .389716751140440464951,
+ .394993808240542421117,
+ .400243164127459749579,
+ .405465108107819105498,
+ .410659924985338875558,
+ .415827895143593195825,
+ .420969294644237379543,
+ .426084395310681429691,
+ .431173464818130014464,
+ .436236766774527495726,
+ .441274560805140936281,
+ .446287102628048160113,
+ .451274644139630254358,
+ .456237433481874177232,
+ .461175715122408291790,
+ .466089729924533457960,
+ .470979715219073113985,
+ .475845904869856894947,
+ .480688529345570714212,
+ .485507815781602403149,
+ .490303988045525329653,
+ .495077266798034543171,
+ .499827869556611403822,
+ .504556010751912253908,
+ .509261901790523552335,
+ .513945751101346104405,
+ .518607764208354637958,
+ .523248143765158602036,
+ .527867089620485785417,
+ .532464798869114019908,
+ .537041465897345915436,
+ .541597282432121573947,
+ .546132437597407260909,
+ .550647117952394182793,
+ .555141507540611200965,
+ .559615787935399566777,
+ .564070138285387656651,
+ .568504735352689749561,
+ .572919753562018740922,
+ .577315365035246941260,
+ .581691739635061821900,
+ .586049045003164792433,
+ .590387446602107957005,
+ .594707107746216934174,
+ .599008189645246602594,
+ .603290851438941899687,
+ .607555250224322662688,
+ .611801541106615331955,
+ .616029877215623855590,
+ .620240409751204424537,
+ .624433288012369303032,
+ .628608659422752680256,
+ .632766669570628437213,
+ .636907462236194987781,
+ .641031179420679109171,
+ .645137961373620782978,
+ .649227946625615004450,
+ .653301272011958644725,
+ .657358072709030238911,
+ .661398482245203922502,
+ .665422632544505177065,
+ .669430653942981734871,
+ .673422675212350441142,
+ .677398823590920073911,
+ .681359224807238206267,
+ .685304003098281100392,
+ .689233281238557538017,
+ .693147180560117703862
+};
+
+static double logF_tail[N+1] = {
+ 0.,
+ -.00000000000000543229938420049,
+ .00000000000000172745674997061,
+ -.00000000000001323017818229233,
+ -.00000000000001154527628289872,
+ -.00000000000000466529469958300,
+ .00000000000005148849572685810,
+ -.00000000000002532168943117445,
+ -.00000000000005213620639136504,
+ -.00000000000001819506003016881,
+ .00000000000006329065958724544,
+ .00000000000008614512936087814,
+ -.00000000000007355770219435028,
+ .00000000000009638067658552277,
+ .00000000000007598636597194141,
+ .00000000000002579999128306990,
+ -.00000000000004654729747598444,
+ -.00000000000007556920687451336,
+ .00000000000010195735223708472,
+ -.00000000000017319034406422306,
+ -.00000000000007718001336828098,
+ .00000000000010980754099855238,
+ -.00000000000002047235780046195,
+ -.00000000000008372091099235912,
+ .00000000000014088127937111135,
+ .00000000000012869017157588257,
+ .00000000000017788850778198106,
+ .00000000000006440856150696891,
+ .00000000000016132822667240822,
+ -.00000000000007540916511956188,
+ -.00000000000000036507188831790,
+ .00000000000009120937249914984,
+ .00000000000018567570959796010,
+ -.00000000000003149265065191483,
+ -.00000000000009309459495196889,
+ .00000000000017914338601329117,
+ -.00000000000001302979717330866,
+ .00000000000023097385217586939,
+ .00000000000023999540484211737,
+ .00000000000015393776174455408,
+ -.00000000000036870428315837678,
+ .00000000000036920375082080089,
+ -.00000000000009383417223663699,
+ .00000000000009433398189512690,
+ .00000000000041481318704258568,
+ -.00000000000003792316480209314,
+ .00000000000008403156304792424,
+ -.00000000000034262934348285429,
+ .00000000000043712191957429145,
+ -.00000000000010475750058776541,
+ -.00000000000011118671389559323,
+ .00000000000037549577257259853,
+ .00000000000013912841212197565,
+ .00000000000010775743037572640,
+ .00000000000029391859187648000,
+ -.00000000000042790509060060774,
+ .00000000000022774076114039555,
+ .00000000000010849569622967912,
+ -.00000000000023073801945705758,
+ .00000000000015761203773969435,
+ .00000000000003345710269544082,
+ -.00000000000041525158063436123,
+ .00000000000032655698896907146,
+ -.00000000000044704265010452446,
+ .00000000000034527647952039772,
+ -.00000000000007048962392109746,
+ .00000000000011776978751369214,
+ -.00000000000010774341461609578,
+ .00000000000021863343293215910,
+ .00000000000024132639491333131,
+ .00000000000039057462209830700,
+ -.00000000000026570679203560751,
+ .00000000000037135141919592021,
+ -.00000000000017166921336082431,
+ -.00000000000028658285157914353,
+ -.00000000000023812542263446809,
+ .00000000000006576659768580062,
+ -.00000000000028210143846181267,
+ .00000000000010701931762114254,
+ .00000000000018119346366441110,
+ .00000000000009840465278232627,
+ -.00000000000033149150282752542,
+ -.00000000000018302857356041668,
+ -.00000000000016207400156744949,
+ .00000000000048303314949553201,
+ -.00000000000071560553172382115,
+ .00000000000088821239518571855,
+ -.00000000000030900580513238244,
+ -.00000000000061076551972851496,
+ .00000000000035659969663347830,
+ .00000000000035782396591276383,
+ -.00000000000046226087001544578,
+ .00000000000062279762917225156,
+ .00000000000072838947272065741,
+ .00000000000026809646615211673,
+ -.00000000000010960825046059278,
+ .00000000000002311949383800537,
+ -.00000000000058469058005299247,
+ -.00000000000002103748251144494,
+ -.00000000000023323182945587408,
+ -.00000000000042333694288141916,
+ -.00000000000043933937969737844,
+ .00000000000041341647073835565,
+ .00000000000006841763641591466,
+ .00000000000047585534004430641,
+ .00000000000083679678674757695,
+ -.00000000000085763734646658640,
+ .00000000000021913281229340092,
+ -.00000000000062242842536431148,
+ -.00000000000010983594325438430,
+ .00000000000065310431377633651,
+ -.00000000000047580199021710769,
+ -.00000000000037854251265457040,
+ .00000000000040939233218678664,
+ .00000000000087424383914858291,
+ .00000000000025218188456842882,
+ -.00000000000003608131360422557,
+ -.00000000000050518555924280902,
+ .00000000000078699403323355317,
+ -.00000000000067020876961949060,
+ .00000000000016108575753932458,
+ .00000000000058527188436251509,
+ -.00000000000035246757297904791,
+ -.00000000000018372084495629058,
+ .00000000000088606689813494916,
+ .00000000000066486268071468700,
+ .00000000000063831615170646519,
+ .00000000000025144230728376072,
+ -.00000000000017239444525614834
+};
+
+double
+#ifdef _ANSI_SOURCE
+log(double x)
+#else
+log(x) double x;
+#endif
+{
+ int m, j;
+ double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0;
+ volatile double u1;
+
+ /* Catch special cases */
+ if (x <= 0)
+ if (_IEEE && x == zero) /* log(0) = -Inf */
+ return (-one/zero);
+ else if (_IEEE) /* log(neg) = NaN */
+ return (zero/zero);
+ else if (x == zero) /* NOT REACHED IF _IEEE */
+ return (infnan(-ERANGE));
+ else
+ return (infnan(EDOM));
+ else if (!finite(x))
+ if (_IEEE) /* x = NaN, Inf */
+ return (x+x);
+ else
+ return (infnan(ERANGE));
+
+ /* Argument reduction: 1 <= g < 2; x/2^m = g; */
+ /* y = F*(1 + f/F) for |f| <= 2^-8 */
+
+ m = logb(x);
+ g = ldexp(x, -m);
+ if (_IEEE && m == -1022) {
+ j = logb(g), m += j;
+ g = ldexp(g, -j);
+ }
+ j = N*(g-1) + .5;
+ F = (1.0/N) * j + 1; /* F*128 is an integer in [128, 512] */
+ f = g - F;
+
+ /* Approximate expansion for log(1+f/F) ~= u + q */
+ g = 1/(2*F+f);
+ u = 2*f*g;
+ v = u*u;
+ q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
+
+ /* case 1: u1 = u rounded to 2^-43 absolute. Since u < 2^-8,
+ * u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits.
+ * It also adds exactly to |m*log2_hi + log_F_head[j] | < 750
+ */
+ if (m | j)
+ u1 = u + 513, u1 -= 513;
+
+ /* case 2: |1-x| < 1/256. The m- and j- dependent terms are zero;
+ * u1 = u to 24 bits.
+ */
+ else
+ u1 = u, TRUNC(u1);
+ u2 = (2.0*(f - F*u1) - u1*f) * g;
+ /* u1 + u2 = 2f/(2F+f) to extra precision. */
+
+ /* log(x) = log(2^m*F*(1+f/F)) = */
+ /* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q); */
+ /* (exact) + (tiny) */
+
+ u1 += m*logF_head[N] + logF_head[j]; /* exact */
+ u2 = (u2 + logF_tail[j]) + q; /* tiny */
+ u2 += logF_tail[N]*m;
+ return (u1 + u2);
+}
+
+/*
+ * Extra precision variant, returning struct {double a, b;};
+ * log(x) = a+b to 63 bits, with a is rounded to 26 bits.
+ */
+struct Double
+#ifdef _ANSI_SOURCE
+__log__D(double x)
+#else
+__log__D(x) double x;
+#endif
+{
+ int m, j;
+ double F, f, g, q, u, v, u2, one = 1.0;
+ volatile double u1;
+ struct Double r;
+
+ /* Argument reduction: 1 <= g < 2; x/2^m = g; */
+ /* y = F*(1 + f/F) for |f| <= 2^-8 */
+
+ m = logb(x);
+ g = ldexp(x, -m);
+ if (_IEEE && m == -1022) {
+ j = logb(g), m += j;
+ g = ldexp(g, -j);
+ }
+ j = N*(g-1) + .5;
+ F = (1.0/N) * j + 1;
+ f = g - F;
+
+ g = 1/(2*F+f);
+ u = 2*f*g;
+ v = u*u;
+ q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
+ if (m | j)
+ u1 = u + 513, u1 -= 513;
+ else
+ u1 = u, TRUNC(u1);
+ u2 = (2.0*(f - F*u1) - u1*f) * g;
+
+ u1 += m*logF_head[N] + logF_head[j];
+
+ u2 += logF_tail[j]; u2 += q;
+ u2 += logF_tail[N]*m;
+ r.a = u1 + u2; /* Only difference is here */
+ TRUNC(r.a);
+ r.b = (u1 - r.a) + u2;
+ return (r);
+}
diff --git a/lib/msun/bsdsrc/b_tgamma.c b/lib/msun/bsdsrc/b_tgamma.c
new file mode 100644
index 0000000..5d270f0
--- /dev/null
+++ b/lib/msun/bsdsrc/b_tgamma.c
@@ -0,0 +1,336 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)gamma.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * This code by P. McIlroy, Oct 1992;
+ *
+ * The financial support of UUNET Communications Services is greatfully
+ * acknowledged.
+ */
+
+#include <math.h>
+#include "mathimpl.h"
+#include <errno.h>
+
+/* METHOD:
+ * x < 0: Use reflection formula, G(x) = pi/(sin(pi*x)*x*G(x))
+ * At negative integers, return +Inf, and set errno.
+ *
+ * x < 6.5:
+ * Use argument reduction G(x+1) = xG(x) to reach the
+ * range [1.066124,2.066124]. Use a rational
+ * approximation centered at the minimum (x0+1) to
+ * ensure monotonicity.
+ *
+ * x >= 6.5: Use the asymptotic approximation (Stirling's formula)
+ * adjusted for equal-ripples:
+ *
+ * log(G(x)) ~= (x-.5)*(log(x)-1) + .5(log(2*pi)-1) + 1/x*P(1/(x*x))
+ *
+ * Keep extra precision in multiplying (x-.5)(log(x)-1), to
+ * avoid premature round-off.
+ *
+ * Special values:
+ * non-positive integer: Set overflow trap; return +Inf;
+ * x > 171.63: Set overflow trap; return +Inf;
+ * NaN: Set invalid trap; return NaN
+ *
+ * Accuracy: Gamma(x) is accurate to within
+ * x > 0: error provably < 0.9ulp.
+ * Maximum observed in 1,000,000 trials was .87ulp.
+ * x < 0:
+ * Maximum observed error < 4ulp in 1,000,000 trials.
+ */
+
+static double neg_gam __P((double));
+static double small_gam __P((double));
+static double smaller_gam __P((double));
+static struct Double large_gam __P((double));
+static struct Double ratfun_gam __P((double, double));
+
+/*
+ * Rational approximation, A0 + x*x*P(x)/Q(x), on the interval
+ * [1.066.., 2.066..] accurate to 4.25e-19.
+ */
+#define LEFT -.3955078125 /* left boundary for rat. approx */
+#define x0 .461632144968362356785 /* xmin - 1 */
+
+#define a0_hi 0.88560319441088874992
+#define a0_lo -.00000000000000004996427036469019695
+#define P0 6.21389571821820863029017800727e-01
+#define P1 2.65757198651533466104979197553e-01
+#define P2 5.53859446429917461063308081748e-03
+#define P3 1.38456698304096573887145282811e-03
+#define P4 2.40659950032711365819348969808e-03
+#define Q0 1.45019531250000000000000000000e+00
+#define Q1 1.06258521948016171343454061571e+00
+#define Q2 -2.07474561943859936441469926649e-01
+#define Q3 -1.46734131782005422506287573015e-01
+#define Q4 3.07878176156175520361557573779e-02
+#define Q5 5.12449347980666221336054633184e-03
+#define Q6 -1.76012741431666995019222898833e-03
+#define Q7 9.35021023573788935372153030556e-05
+#define Q8 6.13275507472443958924745652239e-06
+/*
+ * Constants for large x approximation (x in [6, Inf])
+ * (Accurate to 2.8*10^-19 absolute)
+ */
+#define lns2pi_hi 0.418945312500000
+#define lns2pi_lo -.000006779295327258219670263595
+#define Pa0 8.33333333333333148296162562474e-02
+#define Pa1 -2.77777777774548123579378966497e-03
+#define Pa2 7.93650778754435631476282786423e-04
+#define Pa3 -5.95235082566672847950717262222e-04
+#define Pa4 8.41428560346653702135821806252e-04
+#define Pa5 -1.89773526463879200348872089421e-03
+#define Pa6 5.69394463439411649408050664078e-03
+#define Pa7 -1.44705562421428915453880392761e-02
+
+static const double zero = 0., one = 1.0, tiny = 1e-300;
+static int endian;
+/*
+ * TRUNC sets trailing bits in a floating-point number to zero.
+ * is a temporary variable.
+ */
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+#define TRUNC(x) x = (double) (float) (x)
+#else
+#define _IEEE 1
+#define TRUNC(x) *(((int *) &x) + endian) &= 0xf8000000
+#define infnan(x) 0.0
+#endif
+
+double
+gamma(x)
+ double x;
+{
+ struct Double u;
+ endian = (*(int *) &one) ? 1 : 0;
+
+ if (x >= 6) {
+ if(x > 171.63)
+ return(one/zero);
+ u = large_gam(x);
+ return(__exp__D(u.a, u.b));
+ } else if (x >= 1.0 + LEFT + x0)
+ return (small_gam(x));
+ else if (x > 1.e-17)
+ return (smaller_gam(x));
+ else if (x > -1.e-17) {
+ if (x == 0.0)
+ if (!_IEEE) return (infnan(ERANGE));
+ else return (one/x);
+ one+1e-20; /* Raise inexact flag. */
+ return (one/x);
+ } else if (!finite(x)) {
+ if (_IEEE) /* x = NaN, -Inf */
+ return (x*x);
+ else
+ return (infnan(EDOM));
+ } else
+ return (neg_gam(x));
+}
+/*
+ * Accurate to max(ulp(1/128) absolute, 2^-66 relative) error.
+ */
+static struct Double
+large_gam(x)
+ double x;
+{
+ double z, p;
+ int i;
+ struct Double t, u, v;
+
+ z = one/(x*x);
+ p = Pa0+z*(Pa1+z*(Pa2+z*(Pa3+z*(Pa4+z*(Pa5+z*(Pa6+z*Pa7))))));
+ p = p/x;
+
+ u = __log__D(x);
+ u.a -= one;
+ v.a = (x -= .5);
+ TRUNC(v.a);
+ v.b = x - v.a;
+ t.a = v.a*u.a; /* t = (x-.5)*(log(x)-1) */
+ t.b = v.b*u.a + x*u.b;
+ /* return t.a + t.b + lns2pi_hi + lns2pi_lo + p */
+ t.b += lns2pi_lo; t.b += p;
+ u.a = lns2pi_hi + t.b; u.a += t.a;
+ u.b = t.a - u.a;
+ u.b += lns2pi_hi; u.b += t.b;
+ return (u);
+}
+/*
+ * Good to < 1 ulp. (provably .90 ulp; .87 ulp on 1,000,000 runs.)
+ * It also has correct monotonicity.
+ */
+static double
+small_gam(x)
+ double x;
+{
+ double y, ym1, t, x1;
+ struct Double yy, r;
+ y = x - one;
+ ym1 = y - one;
+ if (y <= 1.0 + (LEFT + x0)) {
+ yy = ratfun_gam(y - x0, 0);
+ return (yy.a + yy.b);
+ }
+ r.a = y;
+ TRUNC(r.a);
+ yy.a = r.a - one;
+ y = ym1;
+ yy.b = r.b = y - yy.a;
+ /* Argument reduction: G(x+1) = x*G(x) */
+ for (ym1 = y-one; ym1 > LEFT + x0; y = ym1--, yy.a--) {
+ t = r.a*yy.a;
+ r.b = r.a*yy.b + y*r.b;
+ r.a = t;
+ TRUNC(r.a);
+ r.b += (t - r.a);
+ }
+ /* Return r*gamma(y). */
+ yy = ratfun_gam(y - x0, 0);
+ y = r.b*(yy.a + yy.b) + r.a*yy.b;
+ y += yy.a*r.a;
+ return (y);
+}
+/*
+ * Good on (0, 1+x0+LEFT]. Accurate to 1ulp.
+ */
+static double
+smaller_gam(x)
+ double x;
+{
+ double t, d;
+ struct Double r, xx;
+ if (x < x0 + LEFT) {
+ t = x, TRUNC(t);
+ d = (t+x)*(x-t);
+ t *= t;
+ xx.a = (t + x), TRUNC(xx.a);
+ xx.b = x - xx.a; xx.b += t; xx.b += d;
+ t = (one-x0); t += x;
+ d = (one-x0); d -= t; d += x;
+ x = xx.a + xx.b;
+ } else {
+ xx.a = x, TRUNC(xx.a);
+ xx.b = x - xx.a;
+ t = x - x0;
+ d = (-x0 -t); d += x;
+ }
+ r = ratfun_gam(t, d);
+ d = r.a/x, TRUNC(d);
+ r.a -= d*xx.a; r.a -= d*xx.b; r.a += r.b;
+ return (d + r.a/x);
+}
+/*
+ * returns (z+c)^2 * P(z)/Q(z) + a0
+ */
+static struct Double
+ratfun_gam(z, c)
+ double z, c;
+{
+ int i;
+ double p, q;
+ struct Double r, t;
+
+ q = Q0 +z*(Q1+z*(Q2+z*(Q3+z*(Q4+z*(Q5+z*(Q6+z*(Q7+z*Q8)))))));
+ p = P0 + z*(P1 + z*(P2 + z*(P3 + z*P4)));
+
+ /* return r.a + r.b = a0 + (z+c)^2*p/q, with r.a truncated to 26 bits. */
+ p = p/q;
+ t.a = z, TRUNC(t.a); /* t ~= z + c */
+ t.b = (z - t.a) + c;
+ t.b *= (t.a + z);
+ q = (t.a *= t.a); /* t = (z+c)^2 */
+ TRUNC(t.a);
+ t.b += (q - t.a);
+ r.a = p, TRUNC(r.a); /* r = P/Q */
+ r.b = p - r.a;
+ t.b = t.b*p + t.a*r.b + a0_lo;
+ t.a *= r.a; /* t = (z+c)^2*(P/Q) */
+ r.a = t.a + a0_hi, TRUNC(r.a);
+ r.b = ((a0_hi-r.a) + t.a) + t.b;
+ return (r); /* r = a0 + t */
+}
+
+static double
+neg_gam(x)
+ double x;
+{
+ int sgn = 1;
+ struct Double lg, lsine;
+ double y, z;
+
+ y = floor(x + .5);
+ if (y == x) /* Negative integer. */
+ if(!_IEEE)
+ return (infnan(ERANGE));
+ else
+ return (one/zero);
+ z = fabs(x - y);
+ y = .5*ceil(x);
+ if (y == ceil(y))
+ sgn = -1;
+ if (z < .25)
+ z = sin(M_PI*z);
+ else
+ z = cos(M_PI*(0.5-z));
+ /* Special case: G(1-x) = Inf; G(x) may be nonzero. */
+ if (x < -170) {
+ if (x < -190)
+ return ((double)sgn*tiny*tiny);
+ y = one - x; /* exact: 128 < |x| < 255 */
+ lg = large_gam(y);
+ lsine = __log__D(M_PI/z); /* = TRUNC(log(u)) + small */
+ lg.a -= lsine.a; /* exact (opposite signs) */
+ lg.b -= lsine.b;
+ y = -(lg.a + lg.b);
+ z = (y + lg.a) + lg.b;
+ y = __exp__D(y, z);
+ if (sgn < 0) y = -y;
+ return (y);
+ }
+ y = one-x;
+ if (one-y == x)
+ y = gamma(y);
+ else /* 1-x is inexact */
+ y = -x*gamma(-x);
+ if (sgn < 0) y = -y;
+ return (M_PI / (y*z));
+}
diff --git a/lib/msun/bsdsrc/mathimpl.h b/lib/msun/bsdsrc/mathimpl.h
new file mode 100644
index 0000000..6a2a37d
--- /dev/null
+++ b/lib/msun/bsdsrc/mathimpl.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)mathimpl.h 8.1 (Berkeley) 6/4/93
+ */
+
+#include <sys/cdefs.h>
+#include <math.h>
+
+#if defined(vax)||defined(tahoe)
+
+/* Deal with different ways to concatenate in cpp */
+# ifdef __STDC__
+# define cat3(a,b,c) a ## b ## c
+# else
+# define cat3(a,b,c) a/**/b/**/c
+# endif
+
+/* Deal with vax/tahoe byte order issues */
+# ifdef vax
+# define cat3t(a,b,c) cat3(a,b,c)
+# else
+# define cat3t(a,b,c) cat3(a,c,b)
+# endif
+
+# define vccast(name) (*(const double *)(cat3(name,,x)))
+
+ /*
+ * Define a constant to high precision on a Vax or Tahoe.
+ *
+ * Args are the name to define, the decimal floating point value,
+ * four 16-bit chunks of the float value in hex
+ * (because the vax and tahoe differ in float format!), the power
+ * of 2 of the hex-float exponent, and the hex-float mantissa.
+ * Most of these arguments are not used at compile time; they are
+ * used in a post-check to make sure the constants were compiled
+ * correctly.
+ *
+ * People who want to use the constant will have to do their own
+ * #define foo vccast(foo)
+ * since CPP cannot do this for them from inside another macro (sigh).
+ * We define "vccast" if this needs doing.
+ */
+# define vc(name, value, x1,x2,x3,x4, bexp, xval) \
+ const static long cat3(name,,x)[] = {cat3t(0x,x1,x2), cat3t(0x,x3,x4)};
+
+# define ic(name, value, bexp, xval) ;
+
+#else /* vax or tahoe */
+
+ /* Hooray, we have an IEEE machine */
+# undef vccast
+# define vc(name, value, x1,x2,x3,x4, bexp, xval) ;
+
+# define ic(name, value, bexp, xval) \
+ const static double name = value;
+
+#endif /* defined(vax)||defined(tahoe) */
+
+
+/*
+ * Functions internal to the math package, yet not static.
+ */
+extern double __exp__E();
+extern double __log__L();
+
+struct Double {double a, b;};
+double __exp__D __P((double, double));
+struct Double __log__D __P((double));
diff --git a/lib/msun/i387/e_acos.S b/lib/msun/i387/e_acos.S
new file mode 100644
index 0000000..bd1499c
--- /dev/null
+++ b/lib/msun/i387/e_acos.S
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+/*
+ * acos(x) = atan2(sqrt(1 - x^2, x).
+ * Actually evaluate (1 - x^2) as (1 - x) * (1 + x) to avoid loss of
+ * precision when |x| is nearly 1.
+ */
+ENTRY(__ieee754_acos)
+ fldl 4(%esp) /* x */
+ fld1
+ fld %st(0)
+ fsub %st(2) /* 1 - x */
+ fxch %st(1)
+ fadd %st(2) /* 1 + x */
+ fmulp %st(1) /* (1 - x) * (1 + x) */
+ fsqrt
+ fxch %st(1)
+ fpatan
+ ret
diff --git a/lib/msun/i387/e_asin.S b/lib/msun/i387/e_asin.S
new file mode 100644
index 0000000..1876cfd
--- /dev/null
+++ b/lib/msun/i387/e_asin.S
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+/*
+ * asin(x) = atan2(x, sqrt(1 - x^2).
+ * Actually evaluate (1 - x^2) as (1 - x) * (1 + x) to avoid loss of
+ * precision when |x| is nearly 1.
+ */
+ENTRY(__ieee754_asin)
+ fldl 4(%esp) /* x */
+ fld1
+ fld %st(0)
+ fsub %st(2) /* 1 - x */
+ fxch %st(1)
+ fadd %st(2) /* 1 + x */
+ fmulp %st(1) /* (1 - x) * (1 + x) */
+ fsqrt
+ fpatan
+ ret
diff --git a/lib/msun/i387/e_atan2.S b/lib/msun/i387/e_atan2.S
new file mode 100644
index 0000000..456de56
--- /dev/null
+++ b/lib/msun/i387/e_atan2.S
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1994 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(__ieee754_atan2)
+ fldl 4(%esp)
+ fldl 12(%esp)
+ fpatan
+ ret
diff --git a/lib/msun/i387/e_exp.S b/lib/msun/i387/e_exp.S
new file mode 100644
index 0000000..6e0dd39
--- /dev/null
+++ b/lib/msun/i387/e_exp.S
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+/* e^x = 2^(x * log2(e)) */
+ENTRY(__ieee754_exp)
+ /*
+ * If x is +-Inf, then the subtraction would give Inf-Inf = NaN.
+ * Avoid this. Also avoid it if x is NaN for convenience.
+ */
+ movl 8(%esp),%eax
+ andl $0x7fffffff,%eax
+ cmpl $0x7ff00000,%eax
+ jae x_Inf_or_NaN
+
+ fldl 4(%esp)
+
+ /*
+ * Ensure that the rounding mode is to nearest (to give the smallest
+ * possible fraction) and that the precision is as high as possible.
+ * We may as well mask interrupts if we switch the mode.
+ */
+ fstcw 4(%esp)
+ movl 4(%esp),%eax
+ andl $0x0300,%eax
+ cmpl $0x0300,%eax /* RC == 0 && PC == 3? */
+ je 1f /* jump if mode is good */
+ movl $0x137f,8(%esp)
+ fldcw 8(%esp)
+1:
+ fldl2e
+ fmulp /* x * log2(e) */
+ fstl %st(1)
+ frndint /* int(x * log2(e)) */
+ fstl %st(2)
+ fsubrp /* fract(x * log2(e)) */
+ f2xm1 /* 2^(fract(x * log2(e))) - 1 */
+ fld1
+ faddp /* 2^(fract(x * log2(e))) */
+ fscale /* e^x */
+ fstpl %st(1)
+ je 1f
+ fldcw 4(%esp)
+1:
+ ret
+
+x_Inf_or_NaN:
+ /*
+ * Return 0 if x is -Inf. Otherwise just return x, although the
+ * C version would return (x + x) (Real Indefinite) if x is a NaN.
+ */
+ cmpl $0xfff00000,8(%esp)
+ jne x_not_minus_Inf
+ cmpl $0,4(%esp)
+ jne x_not_minus_Inf
+ fldz
+ ret
+
+x_not_minus_Inf:
+ fldl 4(%esp)
+ ret
diff --git a/lib/msun/i387/e_fmod.S b/lib/msun/i387/e_fmod.S
new file mode 100644
index 0000000..0ce2450
--- /dev/null
+++ b/lib/msun/i387/e_fmod.S
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(__ieee754_fmod)
+ fldl 12(%esp)
+ fldl 4(%esp)
+1: fprem
+ fstsw %ax
+ sahf
+ jp 1b
+ fstpl %st(1)
+ ret
diff --git a/lib/msun/i387/e_log.S b/lib/msun/i387/e_log.S
new file mode 100644
index 0000000..79a58c1
--- /dev/null
+++ b/lib/msun/i387/e_log.S
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(__ieee754_log)
+ fldln2
+ fldl 4(%esp)
+ fyl2x
+ ret
diff --git a/lib/msun/i387/e_log10.S b/lib/msun/i387/e_log10.S
new file mode 100644
index 0000000..c7f9bc4
--- /dev/null
+++ b/lib/msun/i387/e_log10.S
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(__ieee754_log10)
+ fldlg2
+ fldl 4(%esp)
+ fyl2x
+ ret
diff --git a/lib/msun/i387/e_remainder.S b/lib/msun/i387/e_remainder.S
new file mode 100644
index 0000000..cf0808b
--- /dev/null
+++ b/lib/msun/i387/e_remainder.S
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(__ieee754_remainder)
+ fldl 12(%esp)
+ fldl 4(%esp)
+1: fprem1
+ fstsw %ax
+ sahf
+ jp 1b
+ fstpl %st(1)
+ ret
diff --git a/lib/msun/i387/e_scalb.S b/lib/msun/i387/e_scalb.S
new file mode 100644
index 0000000..fc8bb77
--- /dev/null
+++ b/lib/msun/i387/e_scalb.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1994 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(__ieee754_scalb)
+ fldl 12(%esp)
+ fldl 4(%esp)
+ fscale
+ fstp %st(1)
+ ret
diff --git a/lib/msun/i387/e_sqrt.S b/lib/msun/i387/e_sqrt.S
new file mode 100644
index 0000000..f0403f0
--- /dev/null
+++ b/lib/msun/i387/e_sqrt.S
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(__ieee754_sqrt)
+ fldl 4(%esp)
+ fsqrt
+ ret
diff --git a/lib/msun/i387/s_atan.S b/lib/msun/i387/s_atan.S
new file mode 100644
index 0000000..1150cce
--- /dev/null
+++ b/lib/msun/i387/s_atan.S
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(atan)
+ fldl 4(%esp)
+ fld1
+ fpatan
+ ret
diff --git a/lib/msun/i387/s_ceil.S b/lib/msun/i387/s_ceil.S
new file mode 100644
index 0000000..e805d85
--- /dev/null
+++ b/lib/msun/i387/s_ceil.S
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(ceil)
+ pushl %ebp
+ movl %esp,%ebp
+ subl $8,%esp
+
+ fstcw -4(%ebp) /* store fpu control word */
+ movw -4(%ebp),%dx
+ orw $0x0800,%dx /* round towards +oo */
+ andw $0xfbff,%dx
+ movw %dx,-8(%ebp)
+ fldcw -8(%ebp) /* load modfied control word */
+
+ fldl 8(%ebp); /* round */
+ frndint
+
+ fldcw -4(%ebp) /* restore original control word */
+
+ leave
+ ret
diff --git a/lib/msun/i387/s_copysign.S b/lib/msun/i387/s_copysign.S
new file mode 100644
index 0000000..ec28b45
--- /dev/null
+++ b/lib/msun/i387/s_copysign.S
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(copysign)
+ movl 16(%esp),%edx
+ andl $0x80000000,%edx
+ movl 8(%esp),%eax
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,8(%esp)
+ fldl 4(%esp)
+ ret
diff --git a/lib/msun/i387/s_cos.S b/lib/msun/i387/s_cos.S
new file mode 100644
index 0000000..a73ba06
--- /dev/null
+++ b/lib/msun/i387/s_cos.S
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1994 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(cos)
+ fldl 4(%esp)
+ fcos
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 1f
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 2b
+ fstp %st(1)
+ fcos
+ ret
diff --git a/lib/msun/i387/s_finite.S b/lib/msun/i387/s_finite.S
new file mode 100644
index 0000000..b27b7d1
--- /dev/null
+++ b/lib/msun/i387/s_finite.S
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(finite)
+ movl 8(%esp),%eax
+ andl $0x7ff00000, %eax
+ cmpl $0x7ff00000, %eax
+ setneb %al
+ andl $0x000000ff, %eax
+ ret
diff --git a/lib/msun/i387/s_floor.S b/lib/msun/i387/s_floor.S
new file mode 100644
index 0000000..66c1d9f9
--- /dev/null
+++ b/lib/msun/i387/s_floor.S
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(floor)
+ pushl %ebp
+ movl %esp,%ebp
+ subl $8,%esp
+
+ fstcw -4(%ebp) /* store fpu control word */
+ movw -4(%ebp),%dx
+ orw $0x0400,%dx /* round towards -oo */
+ andw $0xf7ff,%dx
+ movw %dx,-8(%ebp)
+ fldcw -8(%ebp) /* load modfied control word */
+
+ fldl 8(%ebp); /* round */
+ frndint
+
+ fldcw -4(%ebp) /* restore original control word */
+
+ leave
+ ret
diff --git a/lib/msun/i387/s_ilogb.S b/lib/msun/i387/s_ilogb.S
new file mode 100644
index 0000000..c0c0eaf
--- /dev/null
+++ b/lib/msun/i387/s_ilogb.S
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1994 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(ilogb)
+ pushl %ebp
+ movl %esp,%ebp
+ subl $4,%esp
+
+ fldl 8(%ebp)
+ fxtract
+ fstpl %st
+
+ fistpl -4(%ebp)
+ movl -4(%ebp),%eax
+
+ leave
+ ret
diff --git a/lib/msun/i387/s_log1p.S b/lib/msun/i387/s_log1p.S
new file mode 100644
index 0000000..24b2821
--- /dev/null
+++ b/lib/msun/i387/s_log1p.S
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+/*
+ * The fyl2xp1 instruction has such a limited range:
+ * -(1 - (sqrt(2) / 2)) <= x <= sqrt(2) - 1
+ * it's not worth trying to use it.
+ *
+ * Also, I'm not sure fyl2xp1's extra precision will
+ * matter once the result is converted from extended
+ * real (80 bits) back to double real (64 bits).
+ */
+ENTRY(log1p)
+ fldln2
+ fldl 4(%esp)
+ fld1
+ faddp
+ fyl2x
+ ret
diff --git a/lib/msun/i387/s_logb.S b/lib/msun/i387/s_logb.S
new file mode 100644
index 0000000..ef9d56e
--- /dev/null
+++ b/lib/msun/i387/s_logb.S
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(logb)
+ fldl 4(%esp)
+ fxtract
+ fstpl %st
+ ret
diff --git a/lib/msun/i387/s_rint.S b/lib/msun/i387/s_rint.S
new file mode 100644
index 0000000..79da080
--- /dev/null
+++ b/lib/msun/i387/s_rint.S
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(rint)
+ fldl 4(%esp)
+ frndint
+ ret
diff --git a/lib/msun/i387/s_scalbn.S b/lib/msun/i387/s_scalbn.S
new file mode 100644
index 0000000..c00e1fb
--- /dev/null
+++ b/lib/msun/i387/s_scalbn.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1994 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(scalbn)
+ fildl 12(%esp)
+ fldl 4(%esp)
+ fscale
+ fstp %st(1)
+ ret
diff --git a/lib/msun/i387/s_significand.S b/lib/msun/i387/s_significand.S
new file mode 100644
index 0000000..7210f9b
--- /dev/null
+++ b/lib/msun/i387/s_significand.S
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(significand)
+ fldl 4(%esp)
+ fxtract
+ fstpl %st(1)
+ ret
diff --git a/lib/msun/i387/s_sin.S b/lib/msun/i387/s_sin.S
new file mode 100644
index 0000000..d152352
--- /dev/null
+++ b/lib/msun/i387/s_sin.S
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1994 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(sin)
+ fldl 4(%esp)
+ fsin
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 1f
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 2b
+ fstp %st(1)
+ fsin
+ ret
diff --git a/lib/msun/i387/s_tan.S b/lib/msun/i387/s_tan.S
new file mode 100644
index 0000000..d0cbc0a
--- /dev/null
+++ b/lib/msun/i387/s_tan.S
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1994 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$FreeBSD$")
+
+ENTRY(tan)
+ fldl 4(%esp)
+ fptan
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 1f
+ fstp %st(0)
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fstsw %ax
+ andw $0x400,%ax
+ jnz 2b
+ fstp %st(1)
+ fptan
+ fstp %st(0)
+ ret
diff --git a/lib/msun/man/acos.3 b/lib/msun/man/acos.3
new file mode 100644
index 0000000..71418b8
--- /dev/null
+++ b/lib/msun/man/acos.3
@@ -0,0 +1,96 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)acos.3 5.1 (Berkeley) 5/2/91
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1991
+.Dt ACOS 3
+.Os
+.Sh NAME
+.Nm acos ,
+.Nm acosf
+.Nd arc cosine functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn acos "double x"
+.Ft float
+.Fn acosf "float x"
+.Sh DESCRIPTION
+The
+.Fn acos
+and the
+.Fn acosf
+functions compute the principal value of the arc cosine of
+.Fa x .
+A domain error occurs for arguments not in the range [-1, +1].
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn acos
+and the
+.Fn acosf
+functions return the arc cosine in the range
+.Bq 0 , \*(Pi
+radians.
+On the
+.Tn VAX
+and
+.Tn Tahoe ,
+if:
+.Bd -unfilled -offset indent
+.Pf \&| Ns Ar x Ns \&| > 1 ,
+.Ed
+.Pp
+.Fn acos x
+sets the global variable
+.Va errno
+to
+.Dv EDOM
+and a reserved operand fault is generated.
+.Sh SEE ALSO
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn acos
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/acosh.3 b/lib/msun/man/acosh.3
new file mode 100644
index 0000000..b7d9f7b
--- /dev/null
+++ b/lib/msun/man/acosh.3
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)acosh.3 5.2 (Berkeley) 5/6/91
+.\" $FreeBSD$
+.\"
+.Dd May 6, 1991
+.Dt ACOSH 3
+.Os BSD 4.3
+.Sh NAME
+.Nm acosh ,
+.Nm acoshf
+.Nd inverse hyperbolic cosine functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn acosh "double x"
+.Ft float
+.Fn acoshf "float x"
+.Sh DESCRIPTION
+The
+.Fn acosh
+and the
+.Fn acoshf
+functions compute the inverse hyperbolic cosine
+of the real
+argument
+.Ar x .
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn acosh
+and the
+.Fn acoshf
+functions
+return the inverse hyperbolic cosine of
+.Ar x .
+On the
+.Tn VAX
+and
+.Tn Tahoe ,
+if the argument is less than one
+.Fn acosh
+sets the global variable
+.Va errno
+to
+.Er EDOM
+and
+causes a reserved operand fault.
+.Sh SEE ALSO
+.Xr asinh 3 ,
+.Xr atanh 3 ,
+.Xr exp 3 ,
+.Xr math 3
+.Sh HISTORY
+The
+.Fn acosh
+function appeared in
+.Bx 4.3 .
diff --git a/lib/msun/man/asin.3 b/lib/msun/man/asin.3
new file mode 100644
index 0000000..1e4b2c1
--- /dev/null
+++ b/lib/msun/man/asin.3
@@ -0,0 +1,98 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)asin.3 5.1 (Berkeley) 5/2/91
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1991
+.Dt ASIN 3
+.Os
+.Sh NAME
+.Nm asin ,
+.Nm asinf
+.Nd arc sine functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn asin "double x"
+.Ft float
+.Fn asinf "float x"
+.Sh DESCRIPTION
+The
+.Fn asin
+and the
+.Fn asinf
+functions compute the principal value of the arc sine of
+.Fa x .
+A domain error occurs for arguments not in the range [-1, +1].
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn asin
+and the
+.Fn asinf
+functions return the arc sine in the range
+.Bk -words
+.Bq -\*(Pi/2, +\*(Pi/2
+.Ek
+radians.
+On the
+.Tn VAX ,
+and Tahoe ,
+if:
+.Bd -unfilled -offset indent
+.Pf \&| Ns Ar x Ns \&| > 1
+.Ed
+.Pp
+the
+global variable
+.Va errno
+is set to
+.Er EDOM
+and
+a reserved operand fault generated.
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn asin
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/asinh.3 b/lib/msun/man/asinh.3
new file mode 100644
index 0000000..eb3f2f3
--- /dev/null
+++ b/lib/msun/man/asinh.3
@@ -0,0 +1,76 @@
+.\" Copyright (c) 1985, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)asinh.3 6.4 (Berkeley) 5/6/91
+.\" $FreeBSD$
+.\"
+.Dd May 6, 1991
+.Dt ASINH 3
+.Os BSD 4.3
+.Sh NAME
+.Nm asinh ,
+.Nm asinhf
+.Nd inverse hyperbolic sine functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn asinh "double x"
+.Ft float
+.Fn asinhf "float x"
+.Sh DESCRIPTION
+The
+.Fn asinh
+and the
+.Fn asinhf
+functions compute the inverse hyperbolic sine
+of the real
+argument
+.Ar x .
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn asinh
+and the
+.Fn asinhf
+functions
+return the inverse hyperbolic sine of
+.Ar x .
+.Sh SEE ALSO
+.Xr acosh 3 ,
+.Xr atanh 3 ,
+.Xr exp 3 ,
+.Xr math 3
+.Sh HISTORY
+The
+.Fn asinh
+function appeared in
+.Bx 4.3 .
diff --git a/lib/msun/man/atan.3 b/lib/msun/man/atan.3
new file mode 100644
index 0000000..e26d012
--- /dev/null
+++ b/lib/msun/man/atan.3
@@ -0,0 +1,82 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)atan.3 5.1 (Berkeley) 5/2/91
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1991
+.Dt ATAN 3
+.Os
+.Sh NAME
+.Nm atan ,
+.Nm atanf
+.Nd arc tangent functions of one variable
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn atan "double x"
+.Ft float
+.Fn atanf "float x"
+.Sh DESCRIPTION
+The
+.Fn atan
+and the
+.Fn atanf
+functions compute the principal value of the arc tangent of
+.Fa x .
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn atan
+and the
+.Fn atanf
+function returns the arc tangent in the range
+.Bk -words
+.Bq -\*(Pi/2 , +\*(Pi/2
+.Ek
+radians.
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn atan
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/atan2.3 b/lib/msun/man/atan2.3
new file mode 100644
index 0000000..36f1c0c
--- /dev/null
+++ b/lib/msun/man/atan2.3
@@ -0,0 +1,196 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)atan2.3 5.1 (Berkeley) 5/2/91
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1991
+.Dt ATAN2 3
+.Os
+.Sh NAME
+.Nm atan2 ,
+.Nm atan2f
+.Nd arc tangent functions of two variables
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn atan2 "double y" "double x"
+.Ft float
+.Fn atan2f "float y" "float x"
+.Sh DESCRIPTION
+The
+.Fn atan2
+and the
+.Fn atan2f
+functions compute the principal value of the arc tangent of
+.Fa y/ Ns Ar x ,
+using the signs of both arguments to determine the quadrant of
+the return value.
+.Sh RETURN VALUES
+The
+.Fn atan2
+and the
+.Fn atan2f
+functions, if successful,
+return the arc tangent of
+.Fa y/ Ns Ar x
+in the range
+.Bk -words
+.Bq \&- Ns \*(Pi , \&+ Ns \*(Pi
+.Ek
+radians.
+If both
+.Fa x
+and
+.Fa y
+are zero, the global variable
+.Va errno
+is set to
+.Er EDOM .
+On the
+.Tn VAX :
+.Bl -column atan_(y,x)_:=____ sign(y)_(Pi_atan2(Xy_xX))___
+.It Fn atan2 y x No := Ta
+.Fn atan y/x Ta
+if
+.Ar x
+> 0,
+.It Ta sign( Ns Ar y Ns )*(\*(Pi -
+.Fn atan "\\*(Bay/x\\*(Ba" ) Ta
+if
+.Ar x
+< 0,
+.It Ta
+.No 0 Ta
+if x = y = 0, or
+.It Ta
+.Pf sign( Ar y Ns )*\\*(Pi/2 Ta
+if
+.Ar x
+= 0 \*(!=
+.Ar y .
+.El
+.Sh NOTES
+The function
+.Fn atan2
+defines "if x > 0,"
+.Fn atan2 0 0
+= 0 on a
+.Tn VAX
+despite that previously
+.Fn atan2 0 0
+may have generated an error message.
+The reasons for assigning a value to
+.Fn atan2 0 0
+are these:
+.Bl -enum -offset indent
+.It
+Programs that test arguments to avoid computing
+.Fn atan2 0 0
+must be indifferent to its value.
+Programs that require it to be invalid are vulnerable
+to diverse reactions to that invalidity on diverse computer systems.
+.It
+The
+.Fn atan2
+function is used mostly to convert from rectangular (x,y)
+to polar
+.if n\
+(r,theta)
+.if t\
+(r,\(*h)
+coordinates that must satisfy x =
+.if n\
+r\(**cos theta
+.if t\
+r\(**cos\(*h
+and y =
+.if n\
+r\(**sin theta.
+.if t\
+r\(**sin\(*h.
+These equations are satisfied when (x=0,y=0)
+is mapped to
+.if n \
+(r=0,theta=0)
+.if t \
+(r=0,\(*h=0)
+on a VAX. In general, conversions to polar coordinates
+should be computed thus:
+.Bd -unfilled -offset indent
+.if n \{\
+r := hypot(x,y); ... := sqrt(x\(**x+y\(**y)
+theta := atan2(y,x).
+.\}
+.if t \{\
+r := hypot(x,y); ... := \(sr(x\u\s82\s10\d+y\u\s82\s10\d)
+\(*h := atan2(y,x).
+.\}
+.Ed
+.It
+The foregoing formulas need not be altered to cope in a
+reasonable way with signed zeros and infinities
+on a machine that conforms to
+.Tn IEEE 754 ;
+the versions of
+.Xr hypot 3
+and
+.Fn atan2
+provided for
+such a machine are designed to handle all cases.
+That is why
+.Fn atan2 \(+-0 \-0
+= \(+-\*(Pi
+for instance.
+In general the formulas above are equivalent to these:
+.Bd -unfilled -offset indent
+.if n \
+r := sqrt(x\(**x+y\(**y); if r = 0 then x := copysign(1,x);
+.if t \
+r := \(sr(x\(**x+y\(**y);\0\0if r = 0 then x := copysign(1,x);
+.Ed
+.El
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn atan2
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/atanh.3 b/lib/msun/man/atanh.3
new file mode 100644
index 0000000..6e770b4
--- /dev/null
+++ b/lib/msun/man/atanh.3
@@ -0,0 +1,90 @@
+.\" Copyright (c) 1985, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)atanh.3 5.2 (Berkeley) 5/6/91
+.\" $FreeBSD$
+.\"
+.Dd May 6, 1991
+.Dt ATANH 3
+.Os BSD 4.3
+.Sh NAME
+.Nm atanh ,
+.Nm atanhf
+.Nd inverse hyperbolic tangent functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn atanh "double x"
+.Ft float
+.Fn atanhf "float x"
+.Sh DESCRIPTION
+The
+.Fn atanh
+and the
+.Fn atanhf
+functions compute the inverse hyperbolic tangent
+of the real
+argument
+.Ar x .
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn atanh
+and the
+.Fn atanhf
+functions
+return the inverse hyperbolic tangent of
+.Ar x
+if successful.
+On the
+.Tn VAX
+and
+.Tn Tahoe ,
+if the argument has absolute value
+bigger than or equal to 1,
+.Fn atanh
+sets the global variable
+.Va errno
+to
+.Er EDOM
+and
+a reserved operand fault is generated.
+.Sh SEE ALSO
+.Xr acosh 3 ,
+.Xr asinh 3 ,
+.Xr exp 3 ,
+.Xr math 3
+.Sh HISTORY
+The
+.Fn atanh
+function appeared in
+.Bx 4.3 .
diff --git a/lib/msun/man/ceil.3 b/lib/msun/man/ceil.3
new file mode 100644
index 0000000..93f4595
--- /dev/null
+++ b/lib/msun/man/ceil.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)ceil.3 5.1 (Berkeley) 5/2/91
+.\" $FreeBSD$
+.\"
+.Dd March 10, 1994
+.Dt CEIL 3
+.Os
+.Sh NAME
+.Nm ceil ,
+.Nm ceilf
+.Nd round to smallest integral value >= x
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn ceil "double x"
+.Ft float
+.Fn ceilf "float x"
+.Sh DESCRIPTION
+The
+.Fn ceil
+and the
+.Fn ceilf
+functions return the smallest integral value
+(represented as a double precision number)
+greater than or equal to
+.Fa x .
+.Sh SEE ALSO
+.Xr abs 3 ,
+.Xr fabs 3 ,
+.Xr floor 3 ,
+.Xr ieee 3 ,
+.Xr math 3 ,
+.Xr rint 3
+.Sh STANDARDS
+The
+.Fn ceil
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/cos.3 b/lib/msun/man/cos.3
new file mode 100644
index 0000000..c6b1084
--- /dev/null
+++ b/lib/msun/man/cos.3
@@ -0,0 +1,81 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)cos.3 5.1 (Berkeley) 5/2/91
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1991
+.Dt COS 3
+.Os
+.Sh NAME
+.Nm cos ,
+.Nm cosf
+.Nd cosine functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn cos "double x"
+.Ft float
+.Fn cosf "float x"
+.Sh DESCRIPTION
+The
+.Fn cos
+and the
+.Fn cosf
+functions compute the cosine of
+.Fa x
+(measured in radians).
+A large magnitude argument may yield a result with little or no
+significance.
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn cos
+and the
+.Fn cosf
+functions return the cosine value.
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn cos
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/cosh.3 b/lib/msun/man/cosh.3
new file mode 100644
index 0000000..799ba97
--- /dev/null
+++ b/lib/msun/man/cosh.3
@@ -0,0 +1,82 @@
+.\" Copyright (c) 1989, 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)cosh.3 5.1 (Berkeley) 5/2/91
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1991
+.Dt COSH 3
+.Os
+.Sh NAME
+.Nm cosh ,
+.Nm coshf
+.Nd hyperbolic cosine functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn cosh "double x"
+.Ft float
+.Fn coshf "float x"
+.Sh DESCRIPTION
+The
+.Fn cosh
+and the
+.Fn coshf
+functions compute the hyperbolic cosine of
+.Fa x .
+.Sh RETURN VALUES
+The
+.Fn cosh
+and the
+.Fn coshf
+functions return the hyperbolic cosine unless the magnitude
+of
+.Fa x
+is too large; in this event, the global variable
+.Va errno
+is set to
+.Er ERANGE .
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn cosh
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/erf.3 b/lib/msun/man/erf.3
new file mode 100644
index 0000000..95240b6
--- /dev/null
+++ b/lib/msun/man/erf.3
@@ -0,0 +1,93 @@
+.\" Copyright (c) 1985, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)erf.3 6.4 (Berkeley) 4/20/91
+.\" $FreeBSD$
+.\"
+.Dd April 20, 1991
+.Dt ERF 3
+.Os BSD 4.3
+.Sh NAME
+.Nm erf ,
+.Nm erff ,
+.Nm erfc ,
+.Nm erfcf
+.Nd error function operators
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn erf "double x"
+.Ft float
+.Fn erff "float x"
+.Ft double
+.Fn erfc "double x"
+.Ft float
+.Fn erfcf "float x"
+.Sh DESCRIPTION
+These functions calculate the error function of
+.Fa x .
+.Pp
+The
+.Fn erf
+and the
+.Fn erff
+functions calculate the error function of x; where
+.Bd -filled -offset indent
+.if n \{\
+erf(x) = 2/sqrt(pi)\(**\|integral from 0 to x of exp(\-t\(**t) dt. \}
+.if t \{\
+erf\|(x) :=
+(2/\(sr\(*p)\|\(is\d\s8\z0\s10\u\u\s8x\s10\d\|exp(\-t\u\s82\s10\d)\|dt. \}
+.Ed
+.Pp
+The
+.Fn erfc
+and the
+.Fn erfcf
+functions calculate the complementary error function of
+.Fa x ;
+that is
+.Fn erfc
+subtracts the result of the error function
+.Fn erf x
+from 1.0.
+This is useful, since for large
+.Fa x
+places disappear.
+.Sh SEE ALSO
+.Xr math 3
+.Sh HISTORY
+The
+.Fn erf
+and
+.Fn erfc
+functions appeared in
+.Bx 4.3 .
diff --git a/lib/msun/man/exp.3 b/lib/msun/man/exp.3
new file mode 100644
index 0000000..dc60be6
--- /dev/null
+++ b/lib/msun/man/exp.3
@@ -0,0 +1,323 @@
+.\" Copyright (c) 1985, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)exp.3 6.12 (Berkeley) 7/31/91
+.\" $FreeBSD$
+.\"
+.Dd July 31, 1991
+.Dt EXP 3
+.Os BSD 4
+.Sh NAME
+.Nm exp ,
+.Nm expf ,
+.Nm exp2 ,
+.Nm exp2f ,
+.Nm exp10 ,
+.Nm exp10f ,
+.Nm expm1 ,
+.Nm expm1f ,
+.Nm log ,
+.Nm logf ,
+.Nm log10 ,
+.Nm log10f ,
+.Nm log1p ,
+.Nm log1pf ,
+.Nm pow ,
+.Nm powf
+.Nd exponential, logarithm, power functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn exp "double x"
+.Ft float
+.Fn expf "float x"
+.Ft double
+.Fn expm1 "double x"
+.Ft float
+.Fn expm1f "float x"
+.Ft double
+.Fn log "double x"
+.Ft float
+.Fn logf "float x"
+.Ft double
+.Fn log10 "double x"
+.Ft float
+.Fn log10f "float x"
+.Ft double
+.Fn log1p "double x"
+.Ft float
+.Fn log1pf "float x"
+.Ft double
+.Fn pow "double x" "double y"
+.Ft float
+.Fn powf "float x" "float y"
+.Sh DESCRIPTION
+The
+.Fn exp
+and the
+.Fn expf
+functions compute the exponential value of the given argument
+.Fa x .
+.Pp
+The
+.Fn expm1
+and the
+.Fn expm1f
+functions compute the value exp(x)\-1 accurately even for tiny argument
+.Fa x .
+.Pp
+The
+.Fn log
+and the
+.Fn logf
+functions compute the value of the natural logarithm of argument
+.Fa x.
+.Pp
+The
+.Fn log10
+and the
+.Fn log10f
+functions compute the value of the logarithm of argument
+.Fa x
+to base 10.
+.Pp
+The
+.Fn log1p
+and the
+.Fn log1pf
+functions compute
+the value of log(1+x) accurately even for tiny argument
+.Fa x .
+.Pp
+The
+.Fn pow
+and the
+.Fn powf
+functions compute the value
+of
+.Ar x
+to the exponent
+.Ar y .
+.Sh ERROR (due to Roundoff etc.)
+.Fn exp x ,
+.Fn log x ,
+.Fn expm1 x
+and
+.Fn log1p x
+are accurate to within
+an
+.Em ulp ,
+and
+.Fn log10 x
+to within about 2
+.Em ulps ;
+an
+.Em ulp
+is one
+.Em Unit
+in the
+.Em Last
+.Em Place .
+The error in
+.Fn pow x y
+is below about 2
+.Em ulps
+when its
+magnitude is moderate, but increases as
+.Fn pow x y
+approaches
+the over/underflow thresholds until almost as many bits could be
+lost as are occupied by the floating\-point format's exponent
+field; that is 8 bits for
+.Tn "VAX D"
+and 11 bits for IEEE 754 Double.
+No such drastic loss has been exposed by testing; the worst
+errors observed have been below 20
+.Em ulps
+for
+.Tn "VAX D" ,
+300
+.Em ulps
+for
+.Tn IEEE
+754 Double.
+Moderate values of
+.Fn pow
+are accurate enough that
+.Fn pow integer integer
+is exact until it is bigger than 2**56 on a
+.Tn VAX ,
+2**53 for
+.Tn IEEE
+754.
+.Sh RETURN VALUES
+These functions will return the appropriate computation unless an error
+occurs or an argument is out of range.
+The functions
+.Fn exp ,
+.Fn expm1 ,
+.Fn pow
+detect if the computed value will overflow,
+set the global variable
+.Va errno to
+.Er ERANGE
+and cause a reserved operand fault on a
+.Tn VAX
+or
+.Tn Tahoe .
+The functions
+.Fn pow x y
+checks to see if
+.Fa x
+< 0 and
+.Fa y
+is not an integer, in the event this is true,
+the global variable
+.Va errno
+is set to
+.Er EDOM
+and on the
+.Tn VAX
+and
+.Tn Tahoe
+generate a reserved operand fault.
+On a
+.Tn VAX
+and
+.Tn Tahoe ,
+.Va errno
+is set to
+.Er EDOM
+and the reserved operand is returned
+by log unless
+.Fa x
+> 0, by
+.Fn log1p
+unless
+.Fa x
+> \-1.
+.Sh NOTES
+The functions exp(x)\-1 and log(1+x) are called
+expm1 and logp1 in
+.Tn BASIC
+on the Hewlett\-Packard
+.Tn HP Ns \-71B
+and
+.Tn APPLE
+Macintosh,
+.Tn EXP1
+and
+.Tn LN1
+in Pascal, exp1 and log1 in C
+on
+.Tn APPLE
+Macintoshes, where they have been provided to make
+sure financial calculations of ((1+x)**n\-1)/x, namely
+expm1(n\(**log1p(x))/x, will be accurate when x is tiny.
+They also provide accurate inverse hyperbolic functions.
+.Pp
+The function
+.Fn pow x 0
+returns x**0 = 1 for all x including x = 0,
+.if n \
+Infinity
+.if t \
+\(if
+(not found on a
+.Tn VAX ) ,
+and
+.Em NaN
+(the reserved
+operand on a
+.Tn VAX ) . Previous implementations of pow may
+have defined x**0 to be undefined in some or all of these
+cases. Here are reasons for returning x**0 = 1 always:
+.Bl -enum -width indent
+.It
+Any program that already tests whether x is zero (or
+infinite or \*(Na) before computing x**0 cannot care
+whether 0**0 = 1 or not. Any program that depends
+upon 0**0 to be invalid is dubious anyway since that
+expression's meaning and, if invalid, its consequences
+vary from one computer system to another.
+.It
+Some Algebra texts (e.g. Sigler's) define x**0 = 1 for
+all x, including x = 0.
+This is compatible with the convention that accepts a[0]
+as the value of polynomial
+.Bd -literal -offset indent
+p(x) = a[0]\(**x**0 + a[1]\(**x**1 + a[2]\(**x**2 +...+ a[n]\(**x**n
+.Ed
+.Pp
+at x = 0 rather than reject a[0]\(**0**0 as invalid.
+.It
+Analysts will accept 0**0 = 1 despite that x**y can
+approach anything or nothing as x and y approach 0
+independently.
+The reason for setting 0**0 = 1 anyway is this:
+.Bd -filled -offset indent
+If x(z) and y(z) are
+.Em any
+functions analytic (expandable
+in power series) in z around z = 0, and if there
+x(0) = y(0) = 0, then x(z)**y(z) \(-> 1 as z \(-> 0.
+.Ed
+.It
+If 0**0 = 1, then
+.if n \
+infinity**0 = 1/0**0 = 1 too; and
+.if t \
+\(if**0 = 1/0**0 = 1 too; and
+then \*(Na**0 = 1 too because x**0 = 1 for all finite
+and infinite x, i.e., independently of x.
+.El
+.Sh SEE ALSO
+.Xr math 3
+.Sh HISTORY
+A
+.Fn exp ,
+.Fn log
+and
+.Fn pow
+functions
+appeared in
+.At v6 .
+A
+.Fn log10
+function
+appeared in
+.At v7 .
+The
+.Fn log1p
+and
+.Fn expm1
+functions appeared in
+.Bx 4.3 .
diff --git a/lib/msun/man/fabs.3 b/lib/msun/man/fabs.3
new file mode 100644
index 0000000..551b41d
--- /dev/null
+++ b/lib/msun/man/fabs.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" @(#)fabs.3 5.1 (Berkeley) 5/2/91
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)fabs.3 5.1 (Berkeley) 5/2/91
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1991
+.Dt FABS 3
+.Os
+.Sh NAME
+.Nm fabs ,
+.Nm fabsf
+.Nd floating-point absolute value functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn fabs "double x"
+.Ft float
+.Fn fabsf "float x"
+.Sh DESCRIPTION
+The
+.Fn fabs
+and the
+.Fn fabsf
+functions compute the absolute value of a floating-point number
+.Fa x .
+.Sh RETURN VALUES
+The
+.Fn fabs
+and the
+.Fn fabsf
+functions return the absolute value of
+.Fa x .
+.Sh SEE ALSO
+.Xr abs 3 ,
+.Xr ceil 3 ,
+.Xr floor 3 ,
+.Xr ieee 3 ,
+.Xr math 3 ,
+.Xr rint 3
+.Sh STANDARDS
+The
+.Fn fabs
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/floor.3 b/lib/msun/man/floor.3
new file mode 100644
index 0000000..4371fd5
--- /dev/null
+++ b/lib/msun/man/floor.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1985, 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)floor.3 6.5 (Berkeley) 4/19/91
+.\" $FreeBSD$
+.\"
+.Dd March 10, 1994
+.Dt FLOOR 3
+.Os
+.Sh NAME
+.Nm floor ,
+.Nm floorf
+.Nd round to largest integral value <= x
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn floor "double x"
+.Ft float
+.Fn floorf "float x"
+.Sh DESCRIPTION
+The
+.Fn floor
+and the
+.Fn floorf
+function returns the largest integral value
+(represented as a double precision number)
+less than or equal to
+.Fa x .
+.Sh SEE ALSO
+.Xr abs 3 ,
+.Xr ceil 3 ,
+.Xr fabs 3 ,
+.Xr ieee 3 ,
+.Xr math 3 ,
+.Xr rint 3
+.Sh STANDARDS
+The
+.Fn floor
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/fmod.3 b/lib/msun/man/fmod.3
new file mode 100644
index 0000000..849b1d7
--- /dev/null
+++ b/lib/msun/man/fmod.3
@@ -0,0 +1,85 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)fmod.3 5.1 (Berkeley) 5/2/91
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1991
+.Dt FMOD 3
+.Os
+.Sh NAME
+.Nm fmod ,
+.Nm fmodf
+.Nd floating-point remainder functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn fmod "double x" "double y"
+.Ft float
+.Fn fmodf "float x" "float y"
+.Sh DESCRIPTION
+The
+.Fn fmod
+and the
+.Fn fmodf
+functions compute the floating-point remainder of
+.Fa x Ns / Fa y .
+.Sh RETURN VALUES
+The
+.Fn fmod
+and the
+.Fn fmodf
+functions return the value
+.Sm off
+.Fa x - Em i * Fa y ,
+.Sm on
+for some integer
+.Em i
+such that, if
+.Fa y
+is non-zero, the result has the same sign as
+.Fa x
+and magnitude less than the magnitude of
+.Fa y .
+If
+.Fa y
+is zero, whether a domain error occurs or the
+.Fn fmod
+and the
+.Fn fmodf
+function returns zero is implementation-defined.
+.Sh SEE ALSO
+.Xr math 3
+.Sh STANDARDS
+The
+.Fn fmod
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/hypot.3 b/lib/msun/man/hypot.3
new file mode 100644
index 0000000..c65064a
--- /dev/null
+++ b/lib/msun/man/hypot.3
@@ -0,0 +1,134 @@
+.\" Copyright (c) 1985, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)hypot.3 6.7 (Berkeley) 5/6/91
+.\" $FreeBSD$
+.\"
+.Dd May 6, 1991
+.Dt HYPOT 3
+.Os BSD 4
+.Sh NAME
+.Nm hypot ,
+.Nm hypotf ,
+.Nm cabs ,
+.Nm cabsf
+.Nd euclidean distance and complex absolute value functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn hypot "double x" "double y"
+.Ft float
+.Fn hypotf "float x" "float y"
+.Fd struct {double x, y;} z;
+.Ft double
+.Fn cabs z
+.Fd struct {float x, y;} z;
+.Ft float
+.Fn cabsf z
+.Sh DESCRIPTION
+The
+.Fn hypot ,
+.Fn hypotf ,
+.Fn cabs
+and
+.Fn cabsf
+functions
+compute the
+sqrt(x*x+y*y)
+in such a way that underflow will not happen, and overflow
+occurs only if the final result deserves it.
+.Pp
+.Fn hypot "\*(If" "v"
+=
+.Fn hypot "v" "\*(If"
+= +\*(If for all
+.Ar v ,
+including \*(Na.
+.Sh ERROR (due to Roundoff, etc.)
+Below 0.97
+.Em ulps .
+Consequently
+.Fn hypot "5.0" "12.0"
+= 13.0
+exactly;
+in general, hypot and cabs return an integer whenever an
+integer might be expected.
+.Pp
+The same cannot be said for the shorter and faster version of hypot
+and cabs that is provided in the comments in cabs.c; its error can
+exceed 1.2
+.Em ulps .
+.Sh NOTES
+As might be expected,
+.Fn hypot "v" "\*(Na"
+and
+.Fn hypot "\*(Na" "v"
+are \*(Na for all
+.Em finite
+.Ar v ;
+with "reserved operand" in place of "\*(Na", the
+same is true on a
+.Tn VAX .
+But programmers on machines other than a
+.Tn VAX
+(if has no \*(If)
+might be surprised at first to discover that
+.Fn hypot "\(+-\*(If" "\*(Na"
+= +\*(If.
+This is intentional; it happens because
+.Fn hypot "\*(If" "v"
+= +\*(If
+for
+.Em all
+.Ar v ,
+finite or infinite.
+Hence
+.Fn hypot "\*(If" "v"
+is independent of
+.Ar v .
+Unlike the reserved operand fault on a
+.Tn VAX ,
+the
+.Tn IEEE
+\*(Na is designed to
+disappear when it turns out to be irrelevant, as it does in
+.Fn hypot "\*(If" "\*(Na" .
+.Sh SEE ALSO
+.Xr math 3 ,
+.Xr sqrt 3
+.Sh HISTORY
+Both a
+.Fn hypot
+function and a
+.Fn cabs
+function
+appeared in
+.At v7 .
diff --git a/lib/msun/man/ieee.3 b/lib/msun/man/ieee.3
new file mode 100644
index 0000000..1056fef
--- /dev/null
+++ b/lib/msun/man/ieee.3
@@ -0,0 +1,182 @@
+.\" Copyright (c) 1985, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)ieee.3 6.4 (Berkeley) 5/6/91
+.\" $FreeBSD$
+.\"
+.Dd Feb 25, 1994
+.Dt IEEE 3
+.Os
+.Sh NAME
+.Nm copysign ,
+.Nm copysignf ,
+.Nm finite ,
+.Nm finitef ,
+.Nm ilogb ,
+.Nm ilogbf ,
+.Nm nextafter ,
+.Nm nextafterf ,
+.Nm remainder ,
+.Nm remainderf ,
+.Nm scalbn ,
+.Nm scalbnf
+.Nd Functions for IEEE arithmetic
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn copysign "double x" "double y"
+.Ft float
+.Fn copysignf "float x" "float y"
+.Ft int
+.Fn finite "double x"
+.Ft int
+.Fn finitef "float x"
+.Ft int
+.Fn ilogb "double x"
+.Ft int
+.Fn ilogbf "float x"
+.Ft double
+.Fn nextafter "double x" "double y"
+.Ft float
+.Fn nextafterf "float x" "float y"
+.Ft double
+.Fn remainder "double x" "double y"
+.Ft float
+.Fn remainderf "float x" "float y"
+.Ft double
+.Fn scalbn "double x" "int n"
+.Ft float
+.Fn scalbnf "float x" "int n"
+.Sh DESCRIPTION
+These functions are required or recommended by
+.St -ieee754 .
+.Pp
+.Fn copysign
+and
+.Fn copysignf
+return
+.Fa x
+with its sign changed to
+.Fa y Ns 's.
+.Pp
+.Fn finite
+and
+.Fn finitef
+return the value 1 just when
+\-\*(If \*(Lt
+.Fa x
+\*(Lt +\*(If;
+otherwise a
+zero is returned
+(when
+.Pf \\*(Ba Ns Fa x Ns \\*(Ba
+= \*(If or
+.Fa x
+is \*(Na
+.Pp
+.Fn ilogb
+and
+.Fn ilogbf
+return
+.Fa x Ns 's exponent
+.Fa n ,
+in integer format.
+.Fn ilogb \*(Pm\*(If
+returns
+.Dv INT_MAX
+and
+.Fn ilogb 0
+returns
+.Dv INT_MIN .
+.Pp
+.Fn nextafter
+and
+.Fn nextafterf
+return the next machine representable number from
+.Fa x
+in direction
+.Fa y .
+.Pp
+.Fn remainder
+and
+.Fn remainderf
+return the remainder
+.Fa r
+:=
+.Fa x
+\-
+.Fa n\(**y
+where
+.Fa n
+is the integer nearest the exact value of
+.Bk -words
+.Fa x Ns / Ns Fa y ;
+.Ek
+moreover if
+.Pf \\*(Ba Fa n
+\-
+.Sm off
+.Fa x No / Fa y No \\*(Ba
+.Sm on
+=
+1/2
+then
+.Fa n
+is even. Consequently
+the remainder is computed exactly and
+.Sm off
+.Pf \\*(Ba Fa r No \\*(Ba
+.Sm on
+\*(Le
+.Sm off
+.Pf \\*(Ba Fa y No \\*(Ba/2.
+.Sm on
+But
+.Fn remainder x 0
+and
+.Fn remainder \*(If 0
+are invalid operations that produce a \*(Na.
+.Pp
+.Fn scalbn
+and
+.Fn scalbnf
+return
+.Fa x Ns \(**(2** Ns Fa n )
+computed by exponent manipulation.
+.Sh SEE ALSO
+.Xr math 3
+.Sh HISTORY
+The
+.Nm ieee
+functions appeared in
+.Bx 4.3 .
+.Sh STANDARDS
+.St -ieee754
diff --git a/lib/msun/man/ieee_test.3 b/lib/msun/man/ieee_test.3
new file mode 100644
index 0000000..7ff2059
--- /dev/null
+++ b/lib/msun/man/ieee_test.3
@@ -0,0 +1,107 @@
+.\" Copyright (c) 1985, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)ieee.3 6.4 (Berkeley) 5/6/91
+.\" $FreeBSD$
+.\"
+.Dd March 10, 1994
+.Dt IEEE_TEST 3
+.Os
+.Sh NAME
+.Nm logb ,
+.Nm logbf ,
+.Nm scalb ,
+.Nm scalbf ,
+.Nm significand ,
+.Nm significandf
+.Nd IEEE test functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn logb "double x"
+.Ft float
+.Fn logbf "float x"
+.Ft double
+.Fn scalb "double x" "double n"
+.Ft float
+.Fn scalbf "float x" "float n"
+.Ft double
+.Fn significand "double x"
+.Ft float
+.Fn significandf "float x"
+.Sh DESCRIPTION
+These functions allow users to test conformance to
+.St -ieee754 .
+Their use is not otherwise recommended.
+.Pp
+.Fn logb x
+and
+.Fn logbf x
+return
+.Fa x Ns 's exponent
+.Fa n ,
+a signed integer converted to double\-precision floating\-point.
+.Fn logb \*(Pm\*(If
+= +\*(If;
+.Fn logb 0
+= -\*(If with a division by zero exception.
+.Pp
+.Fn scalbn x n
+and
+.Fn scalbnf x n
+return
+.Fa x Ns \(**(2** Ns Fa n )
+computed by exponent manipulation.
+.Pp
+.Fn significand x
+and
+.Fn significandf x
+return
+.Fa sig ,
+where
+.Fa x
+:=
+.Fa sig No \(** 2** Ns Fa n
+with 1 \(<=
+.Fa sig
+< 2.
+.Fn significand x
+and
+.Fn significandf x
+are not defined when
+.Fa x
+is 0, \*(Pm\*(If, or \*(Na.
+.Sh SEE ALSO
+.Xr ieee 3 ,
+.Xr math 3
+
+.Sh STANDARDS
+.St -ieee754
diff --git a/lib/msun/man/j0.3 b/lib/msun/man/j0.3
new file mode 100644
index 0000000..8dbbb5b
--- /dev/null
+++ b/lib/msun/man/j0.3
@@ -0,0 +1,155 @@
+.\" Copyright (c) 1985, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)j0.3 6.7 (Berkeley) 4/19/91
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1991
+.Dt J0 3
+.Os BSD 4
+.Sh NAME
+.Nm j0 ,
+.Nm j0f ,
+.Nm j1 ,
+.Nm j1f ,
+.Nm jn ,
+.Nm jnf ,
+.Nm y0 ,
+.Nm y0f ,
+.Nm y1 ,
+.Nm y1f ,
+.Nm yn ,
+.Nm ynf
+.Nd Bessel functions of first and second kind
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn j0 "double x"
+.Ft float
+.Fn j0f "float x"
+.Ft double
+.Fn j1 "double x"
+.Ft float
+.Fn j1f "float x"
+.Ft double
+.Fn jn "int n" "double x"
+.Ft float
+.Fn jnf "int n" "float x"
+.Ft double
+.Fn y0 "double x"
+.Ft float
+.Fn y0f "float x"
+.Ft double
+.Fn y1 "double x"
+.Ft float
+.Fn y1f "float x"
+.Ft double
+.Fn yn "int n" "double x"
+.Ft float
+.Fn ynf "int n" "float x"
+.Sh DESCRIPTION
+The functions
+.Fn j0 ,
+.Fn j0f ,
+.Fn j1
+and
+.Fn j1f
+compute the
+.Em Bessel function of the first kind of the order
+0 and the
+.Em order
+1, respectively,
+for the
+real value
+.Fa x ;
+the functions
+.Fn jn
+and
+.Fn jnf
+compute the
+.Em Bessel function of the first kind of the integer
+.Em order
+.Fa n
+for the real value
+.Fa x .
+.Pp
+The functions
+.Fn y0 ,
+.Fn y0f ,
+.Fn y1 ,
+and
+.Fn y1f
+compute the linearly independent
+.Em Bessel function of the second kind of the order
+0 and the
+.Em order
+1, respectively,
+for the
+positive
+.Em real
+value
+.Fa x ;
+the functions
+.Fn yn
+and
+.Fn ynf
+compute the
+.Em Bessel function of the second kind for the integer
+.Em order
+.Fa n
+for the positive
+.Em real
+value
+.Fa x .
+.Sh RETURN VALUES
+If these functions are successful,
+the computed value is returned. On the
+.Tn VAX
+and
+.Tn Tahoe
+architectures,
+for the Bessel functions of the second kind,
+a negative
+or zero
+.Fa x
+value
+results in an error; the global
+variable
+.Va errno
+is set to
+.Er EDOM
+and a reserve operand fault is generated.
+.Sh SEE ALSO
+.Xr math 3
+.Sh HISTORY
+This set of functions
+appeared in
+.At v7 .
diff --git a/lib/msun/man/lgamma.3 b/lib/msun/man/lgamma.3
new file mode 100644
index 0000000..b7eeca0
--- /dev/null
+++ b/lib/msun/man/lgamma.3
@@ -0,0 +1,139 @@
+.\" Copyright (c) 1985, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)lgamma.3 6.6 (Berkeley) 12/3/92
+.\" $FreeBSD$
+.\"
+.Dd December 3, 1992
+.Dt LGAMMA 3
+.Os BSD 4.3
+.Sh NAME
+.Nm lgamma ,
+.Nm lgammaf ,
+.Nm gamma ,
+.Nm gammaf
+.Nd log gamma functions, gamma functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft extern int
+.Fa signgam ;
+.sp
+.Ft double
+.Fn lgamma "double x"
+.Ft float
+.Fn lgammaf "float x"
+.Ft double
+.Fn gamma "double x"
+.Ft float
+.Fn gammaf "float x"
+.Sh DESCRIPTION
+.Fn lgamma x
+and
+.Fn lgammaf x
+.if t \{\
+return ln\||\(*G(x)| where
+.Bd -unfilled -offset indent
+\(*G(x) = \(is\d\s8\z0\s10\u\u\s8\(if\s10\d t\u\s8x\-1\s10\d e\u\s8\-t\s10\d dt for x > 0 and
+.br
+\(*G(x) = \(*p/(\(*G(1\-x)\|sin(\(*px)) for x < 1.
+.Ed
+.\}
+.if n \
+return ln\||\(*G(x)|.
+.Pp
+The external integer
+.Fa signgam
+returns the sign of \(*G(x).
+.Pp
+.Fn gamma x
+and
+.Fn gammaf x
+return \(*G(x), with no effect on
+.Fa signgam .
+.Sh IDIOSYNCRASIES
+Do not use the expression
+.Dq Li signgam\(**exp(lgamma(x))
+to compute g := \(*G(x).
+Instead use a program like this (in C):
+.Bd -literal -offset indent
+lg = lgamma(x); g = signgam\(**exp(lg);
+.Ed
+.Pp
+Only after
+.Fn lgamma
+or
+.Fn lgammaf
+has returned can signgam be correct.
+.Pp
+For arguments in its range,
+.Fn gamma
+and
+.Fn gammaf
+is preferred, as for positive arguments
+it is accurate to within one unit in the last place.
+Exponentiation of
+.Fn lgamma
+will lose up to 10 significant bits.
+.Sh RETURN VALUES
+.Fn gamma ,
+.Fn gammaf ,
+.Fn lgamma ,
+and
+.Fn lgammaf
+return appropriate values unless an argument is out of range.
+Overflow will occur for sufficiently large positive values, and
+non-positive integers.
+On the
+.Tn VAX,
+the reserved operator is returned,
+and
+.Va errno
+is set to
+.Er ERANGE
+For large non-integer negative values,
+.Fn gamma
+will underflow.
+.Sh SEE ALSO
+.Xr math 3
+.Sh HISTORY
+The
+.Nm lgamma
+function appeared in
+.Bx 4.3 .
+The
+.Nm gamma
+function appeared in
+.Bx 4.4 .
+The name
+.Fn gamma
+was originally dedicated to the
+.Fn lgamma
+function, so some old code may no longer be compatible.
diff --git a/lib/msun/man/math.3 b/lib/msun/man/math.3
new file mode 100644
index 0000000..e2231de
--- /dev/null
+++ b/lib/msun/man/math.3
@@ -0,0 +1,644 @@
+.\" Copyright (c) 1985 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)math.3 6.10 (Berkeley) 5/6/91
+.\" $FreeBSD$
+.\"
+.TH MATH 3M "May 6, 1991"
+.UC 4
+.ds up \fIulp\fR
+.ds nn \fINaN\fR
+.de If
+.if n \\
+\\$1Infinity\\$2
+.if t \\
+\\$1\\(if\\$2
+..
+.SH NAME
+math \- introduction to mathematical library functions
+.SH DESCRIPTION
+These functions constitute the C math library,
+.I libm.
+The link editor searches this library under the \*(lq\-lm\*(rq option.
+Declarations for these functions may be obtained from the include file
+.RI < math.h >.
+.\" The Fortran math library is described in ``man 3f intro''.
+.SH "LIST OF FUNCTIONS"
+Each of the following double functions has a float counterpart with the
+name ending in f, as an example the float counterpart of double acos(double
+x) is float acosf(float x).
+.sp 2
+.nf
+.ta \w'copysign'u+2n +\w'infnan.3m'u+10n +\w'inverse trigonometric func'u
+\fIName\fP \fIAppears on Page\fP \fIDescription\fP \fIError Bound (ULPs)\fP
+.ta \w'copysign'u+4n +\w'infnan.3m'u+4n +\w'inverse trigonometric function'u+6nC
+.sp 5p
+acos sin.3m inverse trigonometric function 3
+acosh asinh.3m inverse hyperbolic function 3
+asin sin.3m inverse trigonometric function 3
+asinh asinh.3m inverse hyperbolic function 3
+atan sin.3m inverse trigonometric function 1
+atanh asinh.3m inverse hyperbolic function 3
+atan2 sin.3m inverse trigonometric function 2
+cabs hypot.3m complex absolute value 1
+cbrt sqrt.3m cube root 1
+ceil floor.3m integer no less than 0
+copysign ieee.3m copy sign bit 0
+cos sin.3m trigonometric function 1
+cosh sinh.3m hyperbolic function 3
+erf erf.3m error function ???
+erfc erf.3m complementary error function ???
+exp exp.3m exponential 1
+expm1 exp.3m exp(x)\-1 1
+fabs floor.3m absolute value 0
+floor floor.3m integer no greater than 0
+hypot hypot.3m Euclidean distance 1
+ilogb ieee.3m exponent extraction 0
+j0 j0.3m bessel function ???
+j1 j0.3m bessel function ???
+jn j0.3m bessel function ???
+lgamma lgamma.3m log gamma function; (formerly gamma.3m)
+log exp.3m natural logarithm 1
+log10 exp.3m logarithm to base 10 3
+log1p exp.3m log(1+x) 1
+pow exp.3m exponential x**y 60\-500
+remainder ieee.3m remainder 0
+rint floor.3m round to nearest integer 0
+scalbn ieee.3m exponent adjustment 0
+sin sin.3m trigonometric function 1
+sinh sinh.3m hyperbolic function 3
+sqrt sqrt.3m square root 1
+tan sin.3m trigonometric function 3
+tanh sinh.3m hyperbolic function 3
+y0 j0.3m bessel function ???
+y1 j0.3m bessel function ???
+yn j0.3m bessel function ???
+.ta
+.fi
+.SH NOTES
+In 4.3 BSD, distributed from the University of California
+in late 1985, most of the foregoing functions come in two
+versions, one for the double\-precision "D" format in the
+DEC VAX\-11 family of computers, another for double\-precision
+arithmetic conforming to the IEEE Standard 754 for Binary
+Floating\-Point Arithmetic. The two versions behave very
+similarly, as should be expected from programs more accurate
+and robust than was the norm when UNIX was born. For
+instance, the programs are accurate to within the numbers
+of \*(ups tabulated above; an \*(up is one \fIU\fRnit in the \fIL\fRast
+\fIP\fRlace. And the programs have been cured of anomalies that
+afflicted the older math library \fIlibm\fR in which incidents like
+the following had been reported:
+.RS
+sqrt(\-1.0) = 0.0 and log(\-1.0) = \-1.7e38.
+.br
+cos(1.0e\-11) > cos(0.0) > 1.0.
+.br
+pow(x,1.0)
+.if n \
+!=
+.if t \
+\(!=
+x when x = 2.0, 3.0, 4.0, ..., 9.0.
+.br
+pow(\-1.0,1.0e10) trapped on Integer Overflow.
+.br
+sqrt(1.0e30) and sqrt(1.0e\-30) were very slow.
+.RE
+However the two versions do differ in ways that have to be
+explained, to which end the following notes are provided.
+.PP
+\fBDEC VAX\-11 D_floating\-point:\fR
+.PP
+This is the format for which the original math library \fIlibm\fR
+was developed, and to which this manual is still principally
+dedicated. It is \fIthe\fR double\-precision format for the PDP\-11
+and the earlier VAX\-11 machines; VAX\-11s after 1983 were
+provided with an optional "G" format closer to the IEEE
+double\-precision format. The earlier DEC MicroVAXs have no
+D format, only G double\-precision. (Why? Why not?)
+.PP
+Properties of D_floating\-point:
+.RS
+Wordsize: 64 bits, 8 bytes. Radix: Binary.
+.br
+Precision: 56
+.if n \
+sig.
+.if t \
+significant
+bits, roughly like 17
+.if n \
+sig.
+.if t \
+significant
+decimals.
+.RS
+If x and x' are consecutive positive D_floating\-point
+numbers (they differ by 1 \*(up), then
+.br
+1.3e\-17 < 0.5**56 < (x'\-x)/x \(<= 0.5**55 < 2.8e\-17.
+.RE
+.nf
+.ta \w'Range:'u+1n +\w'Underflow threshold'u+1n +\w'= 2.0**127'u+1n
+Range: Overflow threshold = 2.0**127 = 1.7e38.
+ Underflow threshold = 0.5**128 = 2.9e\-39.
+ NOTE: THIS RANGE IS COMPARATIVELY NARROW.
+.ta
+.fi
+.RS
+Overflow customarily stops computation.
+.br
+Underflow is customarily flushed quietly to zero.
+.br
+CAUTION:
+.RS
+It is possible to have x
+.if n \
+!=
+.if t \
+\(!=
+y and yet
+x\-y = 0 because of underflow. Similarly
+x > y > 0 cannot prevent either x\(**y = 0
+or y/x = 0 from happening without warning.
+.RE
+.RE
+Zero is represented ambiguously.
+.RS
+Although 2**55 different representations of zero are accepted by
+the hardware, only the obvious representation is ever produced.
+There is no \-0 on a VAX.
+.RE
+.If
+is not part of the VAX architecture.
+.br
+Reserved operands:
+.RS
+of the 2**55 that the hardware
+recognizes, only one of them is ever produced.
+Any floating\-point operation upon a reserved
+operand, even a MOVF or MOVD, customarily stops
+computation, so they are not much used.
+.RE
+Exceptions:
+.RS
+Divisions by zero and operations that
+overflow are invalid operations that customarily
+stop computation or, in earlier machines, produce
+reserved operands that will stop computation.
+.RE
+Rounding:
+.RS
+Every rational operation (+, \-, \(**, /) on a
+VAX (but not necessarily on a PDP\-11), if not an
+over/underflow nor division by zero, is rounded to
+within half an \*(up, and when the rounding error is
+exactly half an \*(up then rounding is away from 0.
+.RE
+.RE
+.PP
+Except for its narrow range, D_floating\-point is one of the
+better computer arithmetics designed in the 1960's.
+Its properties are reflected fairly faithfully in the elementary
+functions for a VAX distributed in 4.3 BSD.
+They over/underflow only if their results have to lie out of range
+or very nearly so, and then they behave much as any rational
+arithmetic operation that over/underflowed would behave.
+Similarly, expressions like log(0) and atanh(1) behave
+like 1/0; and sqrt(\-3) and acos(3) behave like 0/0;
+they all produce reserved operands and/or stop computation!
+The situation is described in more detail in manual pages.
+.RS
+.ll -0.5i
+\fIThis response seems excessively punitive, so it is destined
+to be replaced at some time in the foreseeable future by a
+more flexible but still uniform scheme being developed to
+handle all floating\-point arithmetic exceptions neatly.
+.\" See infnan(3M) for the present state of affairs.\fR
+.ll +0.5i
+.RE
+.PP
+How do the functions in 4.3 BSD's new \fIlibm\fR for UNIX
+compare with their counterparts in DEC's VAX/VMS library?
+Some of the VMS functions are a little faster, some are
+a little more accurate, some are more puritanical about
+exceptions (like pow(0.0,0.0) and atan2(0.0,0.0)),
+and most occupy much more memory than their counterparts in
+\fIlibm\fR.
+The VMS codes interpolate in large table to achieve
+speed and accuracy; the \fIlibm\fR codes use tricky formulas
+compact enough that all of them may some day fit into a ROM.
+.PP
+More important, DEC regards the VMS codes as proprietary
+and guards them zealously against unauthorized use. But the
+\fIlibm\fR codes in 4.3 BSD are intended for the public domain;
+they may be copied freely provided their provenance is always
+acknowledged, and provided users assist the authors in their
+researches by reporting experience with the codes.
+Therefore no user of UNIX on a machine whose arithmetic resembles
+VAX D_floating\-point need use anything worse than the new \fIlibm\fR.
+.PP
+\fBIEEE STANDARD 754 Floating\-Point Arithmetic:\fR
+.PP
+This standard is on its way to becoming more widely adopted
+than any other design for computer arithmetic.
+VLSI chips that conform to some version of that standard have been
+produced by a host of manufacturers, among them ...
+.nf
+.ta 0.5i +\w'Intel i8070, i80287'u+6n
+ Intel i8087, i80287 National Semiconductor 32081
+ Motorola 68881 Weitek WTL-1032, ... , -1165
+ Zilog Z8070 Western Electric (AT&T) WE32106.
+.ta
+.fi
+Other implementations range from software, done thoroughly
+in the Apple Macintosh, through VLSI in the Hewlett\-Packard
+9000 series, to the ELXSI 6400 running ECL at 3 Megaflops.
+Several other companies have adopted the formats
+of IEEE 754 without, alas, adhering to the standard's way
+of handling rounding and exceptions like over/underflow.
+The DEC VAX G_floating\-point format is very similar to the IEEE
+754 Double format, so similar that the C programs for the
+IEEE versions of most of the elementary functions listed
+above could easily be converted to run on a MicroVAX, though
+nobody has volunteered to do that yet.
+.PP
+The codes in 4.3 BSD's \fIlibm\fR for machines that conform to
+IEEE 754 are intended primarily for the National Semi. 32081
+and WTL 1164/65. To use these codes with the Intel or Zilog
+chips, or with the Apple Macintosh or ELXSI 6400, is to
+forego the use of better codes provided (perhaps freely) by
+those companies and designed by some of the authors of the
+codes above.
+Except for \fIatan\fR, \fIcabs\fR, \fIcbrt\fR, \fIerf\fR,
+\fIerfc\fR, \fIhypot\fR, \fIj0\-jn\fR, \fIlgamma\fR, \fIpow\fR
+and \fIy0\-yn\fR,
+the Motorola 68881 has all the functions in \fIlibm\fR on chip,
+and faster and more accurate;
+it, Apple, the i8087, Z8070 and WE32106 all use 64
+.if n \
+sig.
+.if t \
+significant
+bits.
+The main virtue of 4.3 BSD's
+\fIlibm\fR codes is that they are intended for the public domain;
+they may be copied freely provided their provenance is always
+acknowledged, and provided users assist the authors in their
+researches by reporting experience with the codes.
+Therefore no user of UNIX on a machine that conforms to
+IEEE 754 need use anything worse than the new \fIlibm\fR.
+.PP
+Properties of IEEE 754 Double\-Precision:
+.RS
+Wordsize: 64 bits, 8 bytes. Radix: Binary.
+.br
+Precision: 53
+.if n \
+sig.
+.if t \
+significant
+bits, roughly like 16
+.if n \
+sig.
+.if t \
+significant
+decimals.
+.RS
+If x and x' are consecutive positive Double\-Precision
+numbers (they differ by 1 \*(up), then
+.br
+1.1e\-16 < 0.5**53 < (x'\-x)/x \(<= 0.5**52 < 2.3e\-16.
+.RE
+.nf
+.ta \w'Range:'u+1n +\w'Underflow threshold'u+1n +\w'= 2.0**1024'u+1n
+Range: Overflow threshold = 2.0**1024 = 1.8e308
+ Underflow threshold = 0.5**1022 = 2.2e\-308
+.ta
+.fi
+.RS
+Overflow goes by default to a signed
+.If "" .
+.br
+Underflow is \fIGradual,\fR rounding to the nearest
+integer multiple of 0.5**1074 = 4.9e\-324.
+.RE
+Zero is represented ambiguously as +0 or \-0.
+.RS
+Its sign transforms correctly through multiplication or
+division, and is preserved by addition of zeros
+with like signs; but x\-x yields +0 for every
+finite x. The only operations that reveal zero's
+sign are division by zero and copysign(x,\(+-0).
+In particular, comparison (x > y, x \(>= y, etc.)
+cannot be affected by the sign of zero; but if
+finite x = y then
+.If
+\&= 1/(x\-y)
+.if n \
+!=
+.if t \
+\(!=
+\-1/(y\-x) =
+.If \- .
+.RE
+.If
+is signed.
+.RS
+it persists when added to itself
+or to any finite number. Its sign transforms
+correctly through multiplication and division, and
+.If (finite)/\(+- \0=\0\(+-0
+(nonzero)/0 =
+.If \(+- .
+But
+.if n \
+Infinity\-Infinity, Infinity\(**0 and Infinity/Infinity
+.if t \
+\(if\-\(if, \(if\(**0 and \(if/\(if
+are, like 0/0 and sqrt(\-3),
+invalid operations that produce \*(nn. ...
+.RE
+Reserved operands:
+.RS
+there are 2**53\-2 of them, all
+called \*(nn (\fIN\fRot \fIa N\fRumber).
+Some, called Signaling \*(nns, trap any floating\-point operation
+performed upon them; they are used to mark missing
+or uninitialized values, or nonexistent elements
+of arrays. The rest are Quiet \*(nns; they are
+the default results of Invalid Operations, and
+propagate through subsequent arithmetic operations.
+If x
+.if n \
+!=
+.if t \
+\(!=
+x then x is \*(nn; every other predicate
+(x > y, x = y, x < y, ...) is FALSE if \*(nn is involved.
+.br
+NOTE: Trichotomy is violated by \*(nn.
+.RS
+Besides being FALSE, predicates that entail ordered
+comparison, rather than mere (in)equality,
+signal Invalid Operation when \*(nn is involved.
+.RE
+.RE
+Rounding:
+.RS
+Every algebraic operation (+, \-, \(**, /,
+.if n \
+sqrt)
+.if t \
+\(sr)
+is rounded by default to within half an \*(up, and
+when the rounding error is exactly half an \*(up then
+the rounded value's least significant bit is zero.
+This kind of rounding is usually the best kind,
+sometimes provably so; for instance, for every
+x = 1.0, 2.0, 3.0, 4.0, ..., 2.0**52, we find
+(x/3.0)\(**3.0 == x and (x/10.0)\(**10.0 == x and ...
+despite that both the quotients and the products
+have been rounded. Only rounding like IEEE 754
+can do that. But no single kind of rounding can be
+proved best for every circumstance, so IEEE 754
+provides rounding towards zero or towards
+.If +
+or towards
+.If \-
+at the programmer's option. And the
+same kinds of rounding are specified for
+Binary\-Decimal Conversions, at least for magnitudes
+between roughly 1.0e\-10 and 1.0e37.
+.RE
+Exceptions:
+.RS
+IEEE 754 recognizes five kinds of floating\-point exceptions,
+listed below in declining order of probable importance.
+.RS
+.nf
+.ta \w'Invalid Operation'u+6n +\w'Gradual Underflow'u+2n
+Exception Default Result
+.tc \(ru
+
+.tc
+Invalid Operation \*(nn, or FALSE
+.if n \{\
+Overflow \(+-Infinity
+Divide by Zero \(+-Infinity \}
+.if t \{\
+Overflow \(+-\(if
+Divide by Zero \(+-\(if \}
+Underflow Gradual Underflow
+Inexact Rounded value
+.ta
+.fi
+.RE
+NOTE: An Exception is not an Error unless handled
+badly. What makes a class of exceptions exceptional
+is that no single default response can be satisfactory
+in every instance. On the other hand, if a default
+response will serve most instances satisfactorily,
+the unsatisfactory instances cannot justify aborting
+computation every time the exception occurs.
+.RE
+.PP
+For each kind of floating\-point exception, IEEE 754
+provides a Flag that is raised each time its exception
+is signaled, and stays raised until the program resets
+it. Programs may also test, save and restore a flag.
+Thus, IEEE 754 provides three ways by which programs
+may cope with exceptions for which the default result
+might be unsatisfactory:
+.IP 1) \w'\0\0\0\0'u
+Test for a condition that might cause an exception
+later, and branch to avoid the exception.
+.IP 2) \w'\0\0\0\0'u
+Test a flag to see whether an exception has occurred
+since the program last reset its flag.
+.IP 3) \w'\0\0\0\0'u
+Test a result to see whether it is a value that only
+an exception could have produced.
+.RS
+CAUTION: The only reliable ways to discover
+whether Underflow has occurred are to test whether
+products or quotients lie closer to zero than the
+underflow threshold, or to test the Underflow
+flag. (Sums and differences cannot underflow in
+IEEE 754; if x
+.if n \
+!=
+.if t \
+\(!=
+y then x\-y is correct to
+full precision and certainly nonzero regardless of
+how tiny it may be.) Products and quotients that
+underflow gradually can lose accuracy gradually
+without vanishing, so comparing them with zero
+(as one might on a VAX) will not reveal the loss.
+Fortunately, if a gradually underflowed value is
+destined to be added to something bigger than the
+underflow threshold, as is almost always the case,
+digits lost to gradual underflow will not be missed
+because they would have been rounded off anyway.
+So gradual underflows are usually \fIprovably\fR ignorable.
+The same cannot be said of underflows flushed to 0.
+.RE
+.PP
+At the option of an implementor conforming to IEEE 754,
+other ways to cope with exceptions may be provided:
+.IP 4) \w'\0\0\0\0'u
+ABORT. This mechanism classifies an exception in
+advance as an incident to be handled by means
+traditionally associated with error\-handling
+statements like "ON ERROR GO TO ...". Different
+languages offer different forms of this statement,
+but most share the following characteristics:
+.IP \(em \w'\0\0\0\0'u
+No means is provided to substitute a value for
+the offending operation's result and resume
+computation from what may be the middle of an
+expression. An exceptional result is abandoned.
+.IP \(em \w'\0\0\0\0'u
+In a subprogram that lacks an error\-handling
+statement, an exception causes the subprogram to
+abort within whatever program called it, and so
+on back up the chain of calling subprograms until
+an error\-handling statement is encountered or the
+whole task is aborted and memory is dumped.
+.IP 5) \w'\0\0\0\0'u
+STOP. This mechanism, requiring an interactive
+debugging environment, is more for the programmer
+than the program. It classifies an exception in
+advance as a symptom of a programmer's error; the
+exception suspends execution as near as it can to
+the offending operation so that the programmer can
+look around to see how it happened. Quite often
+the first several exceptions turn out to be quite
+unexceptionable, so the programmer ought ideally
+to be able to resume execution after each one as if
+execution had not been stopped.
+.IP 6) \w'\0\0\0\0'u
+\&... Other ways lie beyond the scope of this document.
+.RE
+.PP
+The crucial problem for exception handling is the problem of
+Scope, and the problem's solution is understood, but not
+enough manpower was available to implement it fully in time
+to be distributed in 4.3 BSD's \fIlibm\fR. Ideally, each
+elementary function should act as if it were indivisible, or
+atomic, in the sense that ...
+.IP i) \w'iii)'u+2n
+No exception should be signaled that is not deserved by
+the data supplied to that function.
+.IP ii) \w'iii)'u+2n
+Any exception signaled should be identified with that
+function rather than with one of its subroutines.
+.IP iii) \w'iii)'u+2n
+The internal behavior of an atomic function should not
+be disrupted when a calling program changes from
+one to another of the five or so ways of handling
+exceptions listed above, although the definition
+of the function may be correlated intentionally
+with exception handling.
+.PP
+Ideally, every programmer should be able \fIconveniently\fR to
+turn a debugged subprogram into one that appears atomic to
+its users. But simulating all three characteristics of an
+atomic function is still a tedious affair, entailing hosts
+of tests and saves\-restores; work is under way to ameliorate
+the inconvenience.
+.PP
+Meanwhile, the functions in \fIlibm\fR are only approximately
+atomic. They signal no inappropriate exception except
+possibly ...
+.RS
+Over/Underflow
+.RS
+when a result, if properly computed, might have lain barely within range, and
+.RE
+Inexact in \fIcabs\fR, \fIcbrt\fR, \fIhypot\fR, \fIlog10\fR and \fIpow\fR
+.RS
+when it happens to be exact, thanks to fortuitous cancellation of errors.
+.RE
+.RE
+Otherwise, ...
+.RS
+Invalid Operation is signaled only when
+.RS
+any result but \*(nn would probably be misleading.
+.RE
+Overflow is signaled only when
+.RS
+the exact result would be finite but beyond the overflow threshold.
+.RE
+Divide\-by\-Zero is signaled only when
+.RS
+a function takes exactly infinite values at finite operands.
+.RE
+Underflow is signaled only when
+.RS
+the exact result would be nonzero but tinier than the underflow threshold.
+.RE
+Inexact is signaled only when
+.RS
+greater range or precision would be needed to represent the exact result.
+.RE
+.RE
+.SH BUGS
+When signals are appropriate, they are emitted by certain
+operations within the codes, so a subroutine\-trace may be
+needed to identify the function with its signal in case
+method 5) above is in use. And the codes all take the
+IEEE 754 defaults for granted; this means that a decision to
+trap all divisions by zero could disrupt a code that would
+otherwise get correct results despite division by zero.
+.SH SEE ALSO
+\fBfpgetround\fR(3),
+\fBfpsetround\fR(3),
+\fBfpgetprec\fR(3),
+\fBfpsetprec\fR(3),
+\fBfpgetmask\fR(3),
+\fBfpsetmask\fR(3),
+\fBfpgetsticky\fR(3),
+\fBfpresetsticky\fR(3) - IEEE floating point interface
+.SH NOTES
+An explanation of IEEE 754 and its proposed extension p854
+was published in the IEEE magazine MICRO in August 1984 under
+the title "A Proposed Radix\- and Word\-length\-independent
+Standard for Floating\-point Arithmetic" by W. J. Cody et al.
+The manuals for Pascal, C and BASIC on the Apple Macintosh
+document the features of IEEE 754 pretty well.
+Articles in the IEEE magazine COMPUTER vol. 14 no. 3 (Mar.
+1981), and in the ACM SIGNUM Newsletter Special Issue of
+Oct. 1979, may be helpful although they pertain to
+superseded drafts of the standard.
diff --git a/lib/msun/man/rint.3 b/lib/msun/man/rint.3
new file mode 100644
index 0000000..c8e320d
--- /dev/null
+++ b/lib/msun/man/rint.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1985, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)rint.3 5.1 (Berkeley) 5/2/91
+.\" $FreeBSD$
+.\"
+.Dd March 10, 1994
+.Dt RINT 3
+.Os
+.Sh NAME
+.Nm rint ,
+.Nm rintf
+.Nd round to integral value in floating-point format
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn rint "double x"
+.Ft float
+.Fn rintf "float x"
+.Sh DESCRIPTION
+The
+.Fn rint
+and the
+.Fn rintf
+functions return the integral value (represented as a double or float
+precision number) nearest to
+.Fa x
+according to the prevailing rounding mode.
+.Sh SEE ALSO
+.Xr abs 3 ,
+.Xr ceil 3 ,
+.Xr fabs 3 ,
+.Xr floor 3 ,
+.Xr ieee 3 ,
+.Xr math 3
+.Sh HISTORY
+A
+.Fn rint
+function appeared in
+.At v6 .
diff --git a/lib/msun/man/sin.3 b/lib/msun/man/sin.3
new file mode 100644
index 0000000..82e873b
--- /dev/null
+++ b/lib/msun/man/sin.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" @(#)sin.3 6.7 (Berkeley) 4/19/91
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)sin.3 6.7 (Berkeley) 4/19/91
+.\" $FreeBSD$
+.\"
+.Dd April 19, 1991
+.Dt SIN 3
+.Os
+.Sh NAME
+.Nm sin ,
+.Nm sinf
+.Nd sine functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn sin "double x"
+.Ft float
+.Fn sinf "float x"
+.Sh DESCRIPTION
+The
+.Fn sin
+and the
+.Fn sinf
+functions compute the sine of
+.Fa x
+(measured in radians).
+A large magnitude argument may yield a result with little
+or no significance.
+.Sh RETURN VALUES
+The
+.Fn sin
+and the
+.Fn sinf
+functions return the sine value.
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sinh 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn sin
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/sinh.3 b/lib/msun/man/sinh.3
new file mode 100644
index 0000000..d445a1f
--- /dev/null
+++ b/lib/msun/man/sinh.3
@@ -0,0 +1,82 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)sinh.3 6.6 (Berkeley) 4/19/91
+.\" $FreeBSD$
+.Dd April 19, 1991
+.Dt SINH 3
+.Os
+.Sh NAME
+.Nm sinh ,
+.Nm sinhf
+.Nd hyperbolic sine function
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn sinh "double x"
+.Ft float
+.Fn sinhf "float x"
+.Sh DESCRIPTION
+The
+.Fn sinh
+and the
+.Fn sinhf
+functions compute the hyperbolic sine of
+.Fa x .
+.Sh RETURN VALUES
+The
+.Fn sinh
+and the
+.Fn sinhf
+functions return the hyperbolic sine value unless
+the magnitude
+of
+.Fa x
+is too large; in this event, the global variable
+.Va errno
+is set to
+.Er ERANGE .
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr tan 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn sinh
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/sqrt.3 b/lib/msun/man/sqrt.3
new file mode 100644
index 0000000..41c16b3
--- /dev/null
+++ b/lib/msun/man/sqrt.3
@@ -0,0 +1,134 @@
+.\" Copyright (c) 1985, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)sqrt.3 6.4 (Berkeley) 5/6/91
+.\" $FreeBSD$
+.\"
+.Dd May 6, 1991
+.Dt SQRT 3
+.Os
+.Sh NAME
+.Nm cbrt ,
+.Nm cbrtf ,
+.Nm sqrt ,
+.Nm sqrtf
+.Nd cube root and square root functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn cbrt "double x"
+.Ft float
+.Fn cbrtf "float x"
+.Ft double
+.Fn sqrt "double x"
+.Ft float
+.Fn sqrtf "float x"
+.Sh DESCRIPTION
+The
+.Fn cbrt
+and the
+.Fn cbrtf
+functions compute
+the cube root of
+.Ar x .
+.Pp
+The
+.Fn sqrt
+and the
+.Fn sqrtf
+functions compute the
+non-negative square root of x.
+.Sh RETURN VALUES
+The
+.Fn cbrt
+and the
+.Fn cbrtf
+functions return the requested cube root.
+The
+.Fn sqrt
+and the
+.Fn sqrtf
+functions return the requested square root
+unless an error occurs.
+On the
+.Tn VAX
+or
+.Tn Tahoe
+processor an attempt to take the
+.Fn sqrt
+of negative
+.Fa x
+causes an error; in this event,
+the global variable
+.Va errno
+is set to
+.Dv EDOM
+and a reserved operand fault is generated.
+.Sh ERROR (due to Roundoff etc.)
+The
+.Fn cbrt
+function
+is accurate to within 0.7
+.Em ulps .
+.Pp
+The
+.Fn sqrt
+function on a
+.Tn VAX
+is accurate to within 0.501
+.Em ulps .
+Sqrt on a machine that conforms to
+.Tn IEEE
+754 is correctly rounded
+in accordance with the rounding mode in force; the error is less than
+half an
+.Em ulp
+in the default mode (round\-to\-nearest).
+An
+.Em ulp
+is one
+.Em U Ns nit
+in the
+.Em L Ns ast
+.Em P Ns lace
+carried.
+.Sh SEE ALSO
+.Xr math 3
+.Sh STANDARDS
+The
+.Nm sqrt
+function conforms to
+.St -ansiC .
+.Sh HISTORY
+The
+.Nm cbrt
+function appeared in
+.Bx 4.3 .
diff --git a/lib/msun/man/tan.3 b/lib/msun/man/tan.3
new file mode 100644
index 0000000..642e243
--- /dev/null
+++ b/lib/msun/man/tan.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)tan.3 5.1 (Berkeley) 5/2/91
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1991
+.Dt TAN 3
+.Os
+.Sh NAME
+.Nm tan ,
+.Nm tanf
+.Nd tangent functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn tan "double x"
+.Ft float
+.Fn tanf "float x"
+.Sh DESCRIPTION
+The
+.Fn tan
+and the
+.Fn tanf
+functions compute the tangent of
+.Fa x
+(measured in radians).
+A large magnitude argument may yield a result
+with little or no significance.
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn tan
+function returns the tangent value.
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tanh 3
+.Sh STANDARDS
+The
+.Fn tan
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/man/tanh.3 b/lib/msun/man/tanh.3
new file mode 100644
index 0000000..0145bb7
--- /dev/null
+++ b/lib/msun/man/tanh.3
@@ -0,0 +1,78 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)tanh.3 5.1 (Berkeley) 5/2/91
+.\" $FreeBSD$
+.\"
+.Dd May 2, 1991
+.Dt TANH 3
+.Os
+.Sh NAME
+.Nm tanh ,
+.Nm tanhf
+.Nd hyperbolic tangent functions
+.Sh SYNOPSIS
+.Fd #include <math.h>
+.Ft double
+.Fn tanh "double x"
+.Ft float
+.Fn tanhf "float x"
+.Sh DESCRIPTION
+The
+.Fn tanh
+and the
+.Fn tanhf
+functions compute the hyperbolic tangent of
+.Fa x .
+For a discussion of error due to roundoff, see
+.Xr math 3 .
+.Sh RETURN VALUES
+The
+.Fn tanh
+and the
+.Fn tanhf
+functions return the hyperbolic tangent value.
+.Sh SEE ALSO
+.Xr acos 3 ,
+.Xr asin 3 ,
+.Xr atan 3 ,
+.Xr atan2 3 ,
+.Xr cos 3 ,
+.Xr cosh 3 ,
+.Xr math 3 ,
+.Xr sin 3 ,
+.Xr sinh 3 ,
+.Xr tan 3
+.Sh STANDARDS
+The
+.Fn tanh
+function conforms to
+.St -ansiC .
diff --git a/lib/msun/src/e_acos.c b/lib/msun/src/e_acos.c
new file mode 100644
index 0000000..7bdb79c
--- /dev/null
+++ b/lib/msun/src/e_acos.c
@@ -0,0 +1,111 @@
+/* @(#)e_acos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_acos(x)
+ * Method :
+ * acos(x) = pi/2 - asin(x)
+ * acos(-x) = pi/2 + asin(x)
+ * For |x|<=0.5
+ * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c)
+ * For x>0.5
+ * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
+ * = 2asin(sqrt((1-x)/2))
+ * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z)
+ * = 2f + (2c + 2s*z*R(z))
+ * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
+ * for f so that f+c ~ sqrt(z).
+ * For x<-0.5
+ * acos(x) = pi - 2asin(sqrt((1-|x|)/2))
+ * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ * Function needed: __ieee754_sqrt
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one= 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
+pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+#ifdef __STDC__
+ double __generic___ieee754_acos(double x)
+#else
+ double __generic___ieee754_acos(x)
+ double x;
+#endif
+{
+ double z,p,q,r,w,s,c,df;
+ int32_t hx,ix;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x3ff00000) { /* |x| >= 1 */
+ u_int32_t lx;
+ GET_LOW_WORD(lx,x);
+ if(((ix-0x3ff00000)|lx)==0) { /* |x|==1 */
+ if(hx>0) return 0.0; /* acos(1) = 0 */
+ else return pi+2.0*pio2_lo; /* acos(-1)= pi */
+ }
+ return (x-x)/(x-x); /* acos(|x|>1) is NaN */
+ }
+ if(ix<0x3fe00000) { /* |x| < 0.5 */
+ if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
+ z = x*x;
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ r = p/q;
+ return pio2_hi - (x - (pio2_lo-x*r));
+ } else if (hx<0) { /* x < -0.5 */
+ z = (one+x)*0.5;
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ s = __ieee754_sqrt(z);
+ r = p/q;
+ w = r*s-pio2_lo;
+ return pi - 2.0*(s+w);
+ } else { /* x > 0.5 */
+ z = (one-x)*0.5;
+ s = __ieee754_sqrt(z);
+ df = s;
+ SET_LOW_WORD(df,0);
+ c = (z-df*df)/(s+df);
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ r = p/q;
+ w = r*s+c;
+ return 2.0*(df+w);
+ }
+}
diff --git a/lib/msun/src/e_acosf.c b/lib/msun/src/e_acosf.c
new file mode 100644
index 0000000..b249710
--- /dev/null
+++ b/lib/msun/src/e_acosf.c
@@ -0,0 +1,89 @@
+/* e_acosf.c -- float version of e_acos.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0000000000e+00, /* 0x3F800000 */
+pi = 3.1415925026e+00, /* 0x40490fda */
+pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */
+pio2_lo = 7.5497894159e-08, /* 0x33a22168 */
+pS0 = 1.6666667163e-01, /* 0x3e2aaaab */
+pS1 = -3.2556581497e-01, /* 0xbea6b090 */
+pS2 = 2.0121252537e-01, /* 0x3e4e0aa8 */
+pS3 = -4.0055535734e-02, /* 0xbd241146 */
+pS4 = 7.9153501429e-04, /* 0x3a4f7f04 */
+pS5 = 3.4793309169e-05, /* 0x3811ef08 */
+qS1 = -2.4033949375e+00, /* 0xc019d139 */
+qS2 = 2.0209457874e+00, /* 0x4001572d */
+qS3 = -6.8828397989e-01, /* 0xbf303361 */
+qS4 = 7.7038154006e-02; /* 0x3d9dc62e */
+
+#ifdef __STDC__
+ float __ieee754_acosf(float x)
+#else
+ float __ieee754_acosf(x)
+ float x;
+#endif
+{
+ float z,p,q,r,w,s,c,df;
+ int32_t hx,ix;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix==0x3f800000) { /* |x|==1 */
+ if(hx>0) return 0.0; /* acos(1) = 0 */
+ else return pi+(float)2.0*pio2_lo; /* acos(-1)= pi */
+ } else if(ix>0x3f800000) { /* |x| >= 1 */
+ return (x-x)/(x-x); /* acos(|x|>1) is NaN */
+ }
+ if(ix<0x3f000000) { /* |x| < 0.5 */
+ if(ix<=0x23000000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
+ z = x*x;
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ r = p/q;
+ return pio2_hi - (x - (pio2_lo-x*r));
+ } else if (hx<0) { /* x < -0.5 */
+ z = (one+x)*(float)0.5;
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ s = __ieee754_sqrtf(z);
+ r = p/q;
+ w = r*s-pio2_lo;
+ return pi - (float)2.0*(s+w);
+ } else { /* x > 0.5 */
+ int32_t idf;
+ z = (one-x)*(float)0.5;
+ s = __ieee754_sqrtf(z);
+ df = s;
+ GET_FLOAT_WORD(idf,df);
+ SET_FLOAT_WORD(df,idf&0xfffff000);
+ c = (z-df*df)/(s+df);
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ r = p/q;
+ w = r*s+c;
+ return (float)2.0*(df+w);
+ }
+}
diff --git a/lib/msun/src/e_acosh.c b/lib/msun/src/e_acosh.c
new file mode 100644
index 0000000..434e879
--- /dev/null
+++ b/lib/msun/src/e_acosh.c
@@ -0,0 +1,69 @@
+/* @(#)e_acosh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_acosh(x)
+ * Method :
+ * Based on
+ * acosh(x) = log [ x + sqrt(x*x-1) ]
+ * we have
+ * acosh(x) := log(x)+ln2, if x is large; else
+ * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
+ * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
+ *
+ * Special cases:
+ * acosh(x) is NaN with signal if x<1.
+ * acosh(NaN) is NaN without signal.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.0,
+ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */
+
+#ifdef __STDC__
+ double __ieee754_acosh(double x)
+#else
+ double __ieee754_acosh(x)
+ double x;
+#endif
+{
+ double t;
+ int32_t hx;
+ u_int32_t lx;
+ EXTRACT_WORDS(hx,lx,x);
+ if(hx<0x3ff00000) { /* x < 1 */
+ return (x-x)/(x-x);
+ } else if(hx >=0x41b00000) { /* x > 2**28 */
+ if(hx >=0x7ff00000) { /* x is inf of NaN */
+ return x+x;
+ } else
+ return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */
+ } else if(((hx-0x3ff00000)|lx)==0) {
+ return 0.0; /* acosh(1) = 0 */
+ } else if (hx > 0x40000000) { /* 2**28 > x > 2 */
+ t=x*x;
+ return __ieee754_log(2.0*x-one/(x+__ieee754_sqrt(t-one)));
+ } else { /* 1<x<2 */
+ t = x-one;
+ return log1p(t+__ieee754_sqrt(2.0*t+t*t));
+ }
+}
diff --git a/lib/msun/src/e_acoshf.c b/lib/msun/src/e_acoshf.c
new file mode 100644
index 0000000..ad0e3a3
--- /dev/null
+++ b/lib/msun/src/e_acoshf.c
@@ -0,0 +1,57 @@
+/* e_acoshf.c -- float version of e_acosh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0,
+ln2 = 6.9314718246e-01; /* 0x3f317218 */
+
+#ifdef __STDC__
+ float __ieee754_acoshf(float x)
+#else
+ float __ieee754_acoshf(x)
+ float x;
+#endif
+{
+ float t;
+ int32_t hx;
+ GET_FLOAT_WORD(hx,x);
+ if(hx<0x3f800000) { /* x < 1 */
+ return (x-x)/(x-x);
+ } else if(hx >=0x4d800000) { /* x > 2**28 */
+ if(hx >=0x7f800000) { /* x is inf of NaN */
+ return x+x;
+ } else
+ return __ieee754_logf(x)+ln2; /* acosh(huge)=log(2x) */
+ } else if (hx==0x3f800000) {
+ return 0.0; /* acosh(1) = 0 */
+ } else if (hx > 0x40000000) { /* 2**28 > x > 2 */
+ t=x*x;
+ return __ieee754_logf((float)2.0*x-one/(x+__ieee754_sqrtf(t-one)));
+ } else { /* 1<x<2 */
+ t = x-one;
+ return log1pf(t+__ieee754_sqrtf((float)2.0*t+t*t));
+ }
+}
diff --git a/lib/msun/src/e_asin.c b/lib/msun/src/e_asin.c
new file mode 100644
index 0000000..de7af9e
--- /dev/null
+++ b/lib/msun/src/e_asin.c
@@ -0,0 +1,120 @@
+/* @(#)e_asin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_asin(x)
+ * Method :
+ * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
+ * we approximate asin(x) on [0,0.5] by
+ * asin(x) = x + x*x^2*R(x^2)
+ * where
+ * R(x^2) is a rational approximation of (asin(x)-x)/x^3
+ * and its remez error is bounded by
+ * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
+ *
+ * For x in [0.5,1]
+ * asin(x) = pi/2-2*asin(sqrt((1-x)/2))
+ * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
+ * then for x>0.98
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
+ * For x<=0.98, let pio4_hi = pio2_hi/2, then
+ * f = hi part of s;
+ * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
+ * and
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
+ * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ */
+
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+huge = 1.000e+300,
+pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
+ /* coefficient for R(x^2) */
+pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+#ifdef __STDC__
+ double __generic___ieee754_asin(double x)
+#else
+ double __generic___ieee754_asin(x)
+ double x;
+#endif
+{
+ double t=0.0,w,p,q,c,r,s;
+ int32_t hx,ix;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>= 0x3ff00000) { /* |x|>= 1 */
+ u_int32_t lx;
+ GET_LOW_WORD(lx,x);
+ if(((ix-0x3ff00000)|lx)==0)
+ /* asin(1)=+-pi/2 with inexact */
+ return x*pio2_hi+x*pio2_lo;
+ return (x-x)/(x-x); /* asin(|x|>1) is NaN */
+ } else if (ix<0x3fe00000) { /* |x|<0.5 */
+ if(ix<0x3e400000) { /* if |x| < 2**-27 */
+ if(huge+x>one) return x;/* return x with inexact if x!=0*/
+ } else
+ t = x*x;
+ p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+ q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+ w = p/q;
+ return x+x*w;
+ }
+ /* 1> |x|>= 0.5 */
+ w = one-fabs(x);
+ t = w*0.5;
+ p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+ q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+ s = __ieee754_sqrt(t);
+ if(ix>=0x3FEF3333) { /* if |x| > 0.975 */
+ w = p/q;
+ t = pio2_hi-(2.0*(s+s*w)-pio2_lo);
+ } else {
+ w = s;
+ SET_LOW_WORD(w,0);
+ c = (t-w*w)/(s+w);
+ r = p/q;
+ p = 2.0*s*r-(pio2_lo-2.0*c);
+ q = pio4_hi-2.0*w;
+ t = pio4_hi-(p-q);
+ }
+ if(hx>0) return t; else return -t;
+}
diff --git a/lib/msun/src/e_asinf.c b/lib/msun/src/e_asinf.c
new file mode 100644
index 0000000..2f1e2e2
--- /dev/null
+++ b/lib/msun/src/e_asinf.c
@@ -0,0 +1,92 @@
+/* e_asinf.c -- float version of e_asin.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0000000000e+00, /* 0x3F800000 */
+huge = 1.000e+30,
+pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */
+pio2_lo = 7.5497894159e-08, /* 0x33a22168 */
+pio4_hi = 7.8539818525e-01, /* 0x3f490fdb */
+ /* coefficient for R(x^2) */
+pS0 = 1.6666667163e-01, /* 0x3e2aaaab */
+pS1 = -3.2556581497e-01, /* 0xbea6b090 */
+pS2 = 2.0121252537e-01, /* 0x3e4e0aa8 */
+pS3 = -4.0055535734e-02, /* 0xbd241146 */
+pS4 = 7.9153501429e-04, /* 0x3a4f7f04 */
+pS5 = 3.4793309169e-05, /* 0x3811ef08 */
+qS1 = -2.4033949375e+00, /* 0xc019d139 */
+qS2 = 2.0209457874e+00, /* 0x4001572d */
+qS3 = -6.8828397989e-01, /* 0xbf303361 */
+qS4 = 7.7038154006e-02; /* 0x3d9dc62e */
+
+#ifdef __STDC__
+ float __ieee754_asinf(float x)
+#else
+ float __ieee754_asinf(x)
+ float x;
+#endif
+{
+ float t=0.0,w,p,q,c,r,s;
+ int32_t hx,ix;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix==0x3f800000) {
+ /* asin(1)=+-pi/2 with inexact */
+ return x*pio2_hi+x*pio2_lo;
+ } else if(ix> 0x3f800000) { /* |x|>= 1 */
+ return (x-x)/(x-x); /* asin(|x|>1) is NaN */
+ } else if (ix<0x3f000000) { /* |x|<0.5 */
+ if(ix<0x32000000) { /* if |x| < 2**-27 */
+ if(huge+x>one) return x;/* return x with inexact if x!=0*/
+ } else
+ t = x*x;
+ p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+ q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+ w = p/q;
+ return x+x*w;
+ }
+ /* 1> |x|>= 0.5 */
+ w = one-fabsf(x);
+ t = w*(float)0.5;
+ p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+ q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+ s = __ieee754_sqrtf(t);
+ if(ix>=0x3F79999A) { /* if |x| > 0.975 */
+ w = p/q;
+ t = pio2_hi-((float)2.0*(s+s*w)-pio2_lo);
+ } else {
+ int32_t iw;
+ w = s;
+ GET_FLOAT_WORD(iw,w);
+ SET_FLOAT_WORD(w,iw&0xfffff000);
+ c = (t-w*w)/(s+w);
+ r = p/q;
+ p = (float)2.0*s*r-(pio2_lo-(float)2.0*c);
+ q = pio4_hi-(float)2.0*w;
+ t = pio4_hi-(p-q);
+ }
+ if(hx>0) return t; else return -t;
+}
diff --git a/lib/msun/src/e_atan2.c b/lib/msun/src/e_atan2.c
new file mode 100644
index 0000000..b07d543
--- /dev/null
+++ b/lib/msun/src/e_atan2.c
@@ -0,0 +1,130 @@
+/* @(#)e_atan2.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_atan2(y,x)
+ * Method :
+ * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
+ * 2. Reduce x to positive by (if x and y are unexceptional):
+ * ARG (x+iy) = arctan(y/x) ... if x > 0,
+ * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
+ *
+ * Special cases:
+ *
+ * ATAN2((anything), NaN ) is NaN;
+ * ATAN2(NAN , (anything) ) is NaN;
+ * ATAN2(+-0, +(anything but NaN)) is +-0 ;
+ * ATAN2(+-0, -(anything but NaN)) is +-pi ;
+ * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
+ * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
+ * ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
+ * ATAN2(+-INF,+INF ) is +-pi/4 ;
+ * ATAN2(+-INF,-INF ) is +-3pi/4;
+ * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+tiny = 1.0e-300,
+zero = 0.0,
+pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
+pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
+pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
+pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
+
+#ifdef __STDC__
+ double __generic___ieee754_atan2(double y, double x)
+#else
+ double __generic___ieee754_atan2(y,x)
+ double y,x;
+#endif
+{
+ double z;
+ int32_t k,m,hx,hy,ix,iy;
+ u_int32_t lx,ly;
+
+ EXTRACT_WORDS(hx,lx,x);
+ ix = hx&0x7fffffff;
+ EXTRACT_WORDS(hy,ly,y);
+ iy = hy&0x7fffffff;
+ if(((ix|((lx|-lx)>>31))>0x7ff00000)||
+ ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */
+ return x+y;
+ if(((hx-0x3ff00000)|lx)==0) return atan(y); /* x=1.0 */
+ m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */
+
+ /* when y = 0 */
+ if((iy|ly)==0) {
+ switch(m) {
+ case 0:
+ case 1: return y; /* atan(+-0,+anything)=+-0 */
+ case 2: return pi+tiny;/* atan(+0,-anything) = pi */
+ case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
+ }
+ }
+ /* when x = 0 */
+ if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* when x is INF */
+ if(ix==0x7ff00000) {
+ if(iy==0x7ff00000) {
+ switch(m) {
+ case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
+ case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
+ case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
+ case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
+ }
+ } else {
+ switch(m) {
+ case 0: return zero ; /* atan(+...,+INF) */
+ case 1: return -zero ; /* atan(-...,+INF) */
+ case 2: return pi+tiny ; /* atan(+...,-INF) */
+ case 3: return -pi-tiny ; /* atan(-...,-INF) */
+ }
+ }
+ }
+ /* when y is INF */
+ if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* compute y/x */
+ k = (iy-ix)>>20;
+ if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */
+ else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */
+ else z=atan(fabs(y/x)); /* safe to do y/x */
+ switch (m) {
+ case 0: return z ; /* atan(+,+) */
+ case 1: {
+ u_int32_t zh;
+ GET_HIGH_WORD(zh,z);
+ SET_HIGH_WORD(z,zh ^ 0x80000000);
+ }
+ return z ; /* atan(-,+) */
+ case 2: return pi-(z-pi_lo);/* atan(+,-) */
+ default: /* case 3 */
+ return (z-pi_lo)-pi;/* atan(-,-) */
+ }
+}
diff --git a/lib/msun/src/e_atan2f.c b/lib/msun/src/e_atan2f.c
new file mode 100644
index 0000000..6e6c181
--- /dev/null
+++ b/lib/msun/src/e_atan2f.c
@@ -0,0 +1,105 @@
+/* e_atan2f.c -- float version of e_atan2.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+tiny = 1.0e-30,
+zero = 0.0,
+pi_o_4 = 7.8539818525e-01, /* 0x3f490fdb */
+pi_o_2 = 1.5707963705e+00, /* 0x3fc90fdb */
+pi = 3.1415925026e+00, /* 0x40490fda */
+pi_lo = 1.5099578832e-07; /* 0x34222168 */
+
+#ifdef __STDC__
+ float __ieee754_atan2f(float y, float x)
+#else
+ float __ieee754_atan2f(y,x)
+ float y,x;
+#endif
+{
+ float z;
+ int32_t k,m,hx,hy,ix,iy;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ GET_FLOAT_WORD(hy,y);
+ iy = hy&0x7fffffff;
+ if((ix>0x7f800000)||
+ (iy>0x7f800000)) /* x or y is NaN */
+ return x+y;
+ if(hx==0x3f800000) return atanf(y); /* x=1.0 */
+ m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */
+
+ /* when y = 0 */
+ if(iy==0) {
+ switch(m) {
+ case 0:
+ case 1: return y; /* atan(+-0,+anything)=+-0 */
+ case 2: return pi+tiny;/* atan(+0,-anything) = pi */
+ case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
+ }
+ }
+ /* when x = 0 */
+ if(ix==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* when x is INF */
+ if(ix==0x7f800000) {
+ if(iy==0x7f800000) {
+ switch(m) {
+ case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
+ case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
+ case 2: return (float)3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
+ case 3: return (float)-3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
+ }
+ } else {
+ switch(m) {
+ case 0: return zero ; /* atan(+...,+INF) */
+ case 1: return -zero ; /* atan(-...,+INF) */
+ case 2: return pi+tiny ; /* atan(+...,-INF) */
+ case 3: return -pi-tiny ; /* atan(-...,-INF) */
+ }
+ }
+ }
+ /* when y is INF */
+ if(iy==0x7f800000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* compute y/x */
+ k = (iy-ix)>>23;
+ if(k > 60) z=pi_o_2+(float)0.5*pi_lo; /* |y/x| > 2**60 */
+ else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */
+ else z=atanf(fabsf(y/x)); /* safe to do y/x */
+ switch (m) {
+ case 0: return z ; /* atan(+,+) */
+ case 1: {
+ u_int32_t zh;
+ GET_FLOAT_WORD(zh,z);
+ SET_FLOAT_WORD(z,zh ^ 0x80000000);
+ }
+ return z ; /* atan(-,+) */
+ case 2: return pi-(z-pi_lo);/* atan(+,-) */
+ default: /* case 3 */
+ return (z-pi_lo)-pi;/* atan(-,-) */
+ }
+}
diff --git a/lib/msun/src/e_atanh.c b/lib/msun/src/e_atanh.c
new file mode 100644
index 0000000..97a79f0
--- /dev/null
+++ b/lib/msun/src/e_atanh.c
@@ -0,0 +1,74 @@
+/* @(#)e_atanh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_atanh(x)
+ * Method :
+ * 1.Reduced x to positive by atanh(-x) = -atanh(x)
+ * 2.For x>=0.5
+ * 1 2x x
+ * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
+ * 2 1 - x 1 - x
+ *
+ * For x<0.5
+ * atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
+ *
+ * Special cases:
+ * atanh(x) is NaN if |x| > 1 with signal;
+ * atanh(NaN) is that NaN with no signal;
+ * atanh(+-1) is +-INF with signal.
+ *
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one = 1.0, huge = 1e300;
+#else
+static double one = 1.0, huge = 1e300;
+#endif
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_atanh(double x)
+#else
+ double __ieee754_atanh(x)
+ double x;
+#endif
+{
+ double t;
+ int32_t hx,ix;
+ u_int32_t lx;
+ EXTRACT_WORDS(hx,lx,x);
+ ix = hx&0x7fffffff;
+ if ((ix|((lx|(-lx))>>31))>0x3ff00000) /* |x|>1 */
+ return (x-x)/(x-x);
+ if(ix==0x3ff00000)
+ return x/zero;
+ if(ix<0x3e300000&&(huge+x)>zero) return x; /* x<2**-28 */
+ SET_HIGH_WORD(x,ix);
+ if(ix<0x3fe00000) { /* x < 0.5 */
+ t = x+x;
+ t = 0.5*log1p(t+t*x/(one-x));
+ } else
+ t = 0.5*log1p((x+x)/(one-x));
+ if(hx>=0) return t; else return -t;
+}
diff --git a/lib/msun/src/e_atanhf.c b/lib/msun/src/e_atanhf.c
new file mode 100644
index 0000000..dc55b3b
--- /dev/null
+++ b/lib/msun/src/e_atanhf.c
@@ -0,0 +1,58 @@
+/* e_atanhf.c -- float version of e_atanh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one = 1.0, huge = 1e30;
+#else
+static float one = 1.0, huge = 1e30;
+#endif
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_atanhf(float x)
+#else
+ float __ieee754_atanhf(x)
+ float x;
+#endif
+{
+ float t;
+ int32_t hx,ix;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if (ix>0x3f800000) /* |x|>1 */
+ return (x-x)/(x-x);
+ if(ix==0x3f800000)
+ return x/zero;
+ if(ix<0x31800000&&(huge+x)>zero) return x; /* x<2**-28 */
+ SET_FLOAT_WORD(x,ix);
+ if(ix<0x3f000000) { /* x < 0.5 */
+ t = x+x;
+ t = (float)0.5*log1pf(t+t*x/(one-x));
+ } else
+ t = (float)0.5*log1pf((x+x)/(one-x));
+ if(hx>=0) return t; else return -t;
+}
diff --git a/lib/msun/src/e_cosh.c b/lib/msun/src/e_cosh.c
new file mode 100644
index 0000000..47723c5
--- /dev/null
+++ b/lib/msun/src/e_cosh.c
@@ -0,0 +1,93 @@
+/* @(#)e_cosh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_cosh(x)
+ * Method :
+ * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
+ * 1. Replace x by |x| (cosh(x) = cosh(-x)).
+ * 2.
+ * [ exp(x) - 1 ]^2
+ * 0 <= x <= ln2/2 : cosh(x) := 1 + -------------------
+ * 2*exp(x)
+ *
+ * exp(x) + 1/exp(x)
+ * ln2/2 <= x <= 22 : cosh(x) := -------------------
+ * 2
+ * 22 <= x <= lnovft : cosh(x) := exp(x)/2
+ * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2)
+ * ln2ovft < x : cosh(x) := huge*huge (overflow)
+ *
+ * Special cases:
+ * cosh(x) is |x| if x is +INF, -INF, or NaN.
+ * only cosh(0)=1 is exact for finite x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one = 1.0, half=0.5, huge = 1.0e300;
+#else
+static double one = 1.0, half=0.5, huge = 1.0e300;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_cosh(double x)
+#else
+ double __ieee754_cosh(x)
+ double x;
+#endif
+{
+ double t,w;
+ int32_t ix;
+ u_int32_t lx;
+
+ /* High word of |x|. */
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7ff00000) return x*x;
+
+ /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
+ if(ix<0x3fd62e43) {
+ t = expm1(fabs(x));
+ w = one+t;
+ if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */
+ return one+(t*t)/(w+w);
+ }
+
+ /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
+ if (ix < 0x40360000) {
+ t = __ieee754_exp(fabs(x));
+ return half*t+half/t;
+ }
+
+ /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
+ if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x));
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ GET_LOW_WORD(lx,x);
+ if (ix<0x408633CE ||
+ ((ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d))) {
+ w = __ieee754_exp(half*fabs(x));
+ t = half*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, cosh(x) overflow */
+ return huge*huge;
+}
diff --git a/lib/msun/src/e_coshf.c b/lib/msun/src/e_coshf.c
new file mode 100644
index 0000000..9ea0416
--- /dev/null
+++ b/lib/msun/src/e_coshf.c
@@ -0,0 +1,71 @@
+/* e_coshf.c -- float version of e_cosh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one = 1.0, half=0.5, huge = 1.0e30;
+#else
+static float one = 1.0, half=0.5, huge = 1.0e30;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_coshf(float x)
+#else
+ float __ieee754_coshf(x)
+ float x;
+#endif
+{
+ float t,w;
+ int32_t ix;
+
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7f800000) return x*x;
+
+ /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
+ if(ix<0x3eb17218) {
+ t = expm1f(fabsf(x));
+ w = one+t;
+ if (ix<0x24000000) return w; /* cosh(tiny) = 1 */
+ return one+(t*t)/(w+w);
+ }
+
+ /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
+ if (ix < 0x41b00000) {
+ t = __ieee754_expf(fabsf(x));
+ return half*t+half/t;
+ }
+
+ /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
+ if (ix < 0x42b17180) return half*__ieee754_expf(fabsf(x));
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ if (ix<=0x42b2d4fc) {
+ w = __ieee754_expf(half*fabsf(x));
+ t = half*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, cosh(x) overflow */
+ return huge*huge;
+}
diff --git a/lib/msun/src/e_exp.c b/lib/msun/src/e_exp.c
new file mode 100644
index 0000000..2fc04c6
--- /dev/null
+++ b/lib/msun/src/e_exp.c
@@ -0,0 +1,167 @@
+/* @(#)e_exp.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_exp(x)
+ * Returns the exponential of x.
+ *
+ * Method
+ * 1. Argument reduction:
+ * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
+ * Given x, find r and integer k such that
+ *
+ * x = k*ln2 + r, |r| <= 0.5*ln2.
+ *
+ * Here r will be represented as r = hi-lo for better
+ * accuracy.
+ *
+ * 2. Approximation of exp(r) by a special rational function on
+ * the interval [0,0.34658]:
+ * Write
+ * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
+ * We use a special Reme algorithm on [0,0.34658] to generate
+ * a polynomial of degree 5 to approximate R. The maximum error
+ * of this polynomial approximation is bounded by 2**-59. In
+ * other words,
+ * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
+ * (where z=r*r, and the values of P1 to P5 are listed below)
+ * and
+ * | 5 | -59
+ * | 2.0+P1*z+...+P5*z - R(z) | <= 2
+ * | |
+ * The computation of exp(r) thus becomes
+ * 2*r
+ * exp(r) = 1 + -------
+ * R - r
+ * r*R1(r)
+ * = 1 + r + ----------- (for better accuracy)
+ * 2 - R1(r)
+ * where
+ * 2 4 10
+ * R1(r) = r - (P1*r + P2*r + ... + P5*r ).
+ *
+ * 3. Scale back to obtain exp(x):
+ * From step 1, we have
+ * exp(x) = 2^k * exp(r)
+ *
+ * Special cases:
+ * exp(INF) is INF, exp(NaN) is NaN;
+ * exp(-INF) is 0, and
+ * for finite argument, only exp(0)=1 is exact.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ * For IEEE double
+ * if x > 7.09782712893383973096e+02 then exp(x) overflow
+ * if x < -7.45133219101941108420e+02 then exp(x) underflow
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.0,
+halF[2] = {0.5,-0.5,},
+huge = 1.0e+300,
+twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/
+o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
+u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */
+ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
+ -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */
+ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
+ -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */
+invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
+P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
+
+
+#ifdef __STDC__
+ double __generic___ieee754_exp(double x) /* default IEEE double exp */
+#else
+ double __generic___ieee754_exp(x) /* default IEEE double exp */
+ double x;
+#endif
+{
+ double y,hi=0.0,lo=0.0,c,t;
+ int32_t k=0,xsb;
+ u_int32_t hx;
+
+ GET_HIGH_WORD(hx,x);
+ xsb = (hx>>31)&1; /* sign bit of x */
+ hx &= 0x7fffffff; /* high word of |x| */
+
+ /* filter out non-finite argument */
+ if(hx >= 0x40862E42) { /* if |x|>=709.78... */
+ if(hx>=0x7ff00000) {
+ u_int32_t lx;
+ GET_LOW_WORD(lx,x);
+ if(((hx&0xfffff)|lx)!=0)
+ return x+x; /* NaN */
+ else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */
+ }
+ if(x > o_threshold) return huge*huge; /* overflow */
+ if(x < u_threshold) return twom1000*twom1000; /* underflow */
+ }
+
+ /* argument reduction */
+ if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
+ if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
+ hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
+ } else {
+ k = invln2*x+halF[xsb];
+ t = k;
+ hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */
+ lo = t*ln2LO[0];
+ }
+ x = hi - lo;
+ }
+ else if(hx < 0x3e300000) { /* when |x|<2**-28 */
+ if(huge+x>one) return one+x;/* trigger inexact */
+ }
+ else k = 0;
+
+ /* x is now in primary range */
+ t = x*x;
+ c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+ if(k==0) return one-((x*c)/(c-2.0)-x);
+ else y = one-((lo-(x*c)/(2.0-c))-hi);
+ if(k >= -1021) {
+ u_int32_t hy;
+ GET_HIGH_WORD(hy,y);
+ SET_HIGH_WORD(y,hy+(k<<20)); /* add k to y's exponent */
+ return y;
+ } else {
+ u_int32_t hy;
+ GET_HIGH_WORD(hy,y);
+ SET_HIGH_WORD(y,hy+((k+1000)<<20)); /* add k to y's exponent */
+ return y*twom1000;
+ }
+}
diff --git a/lib/msun/src/e_expf.c b/lib/msun/src/e_expf.c
new file mode 100644
index 0000000..8f37f6f
--- /dev/null
+++ b/lib/msun/src/e_expf.c
@@ -0,0 +1,103 @@
+/* e_expf.c -- float version of e_exp.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0,
+halF[2] = {0.5,-0.5,},
+huge = 1.0e+30,
+twom100 = 7.8886090522e-31, /* 2**-100=0x0d800000 */
+o_threshold= 8.8721679688e+01, /* 0x42b17180 */
+u_threshold= -1.0397208405e+02, /* 0xc2cff1b5 */
+ln2HI[2] ={ 6.9313812256e-01, /* 0x3f317180 */
+ -6.9313812256e-01,}, /* 0xbf317180 */
+ln2LO[2] ={ 9.0580006145e-06, /* 0x3717f7d1 */
+ -9.0580006145e-06,}, /* 0xb717f7d1 */
+invln2 = 1.4426950216e+00, /* 0x3fb8aa3b */
+P1 = 1.6666667163e-01, /* 0x3e2aaaab */
+P2 = -2.7777778450e-03, /* 0xbb360b61 */
+P3 = 6.6137559770e-05, /* 0x388ab355 */
+P4 = -1.6533901999e-06, /* 0xb5ddea0e */
+P5 = 4.1381369442e-08; /* 0x3331bb4c */
+
+#ifdef __STDC__
+ float __ieee754_expf(float x) /* default IEEE double exp */
+#else
+ float __ieee754_expf(x) /* default IEEE double exp */
+ float x;
+#endif
+{
+ float y,hi=0.0,lo=0.0,c,t;
+ int32_t k=0,xsb;
+ u_int32_t hx;
+
+ GET_FLOAT_WORD(hx,x);
+ xsb = (hx>>31)&1; /* sign bit of x */
+ hx &= 0x7fffffff; /* high word of |x| */
+
+ /* filter out non-finite argument */
+ if(hx >= 0x42b17218) { /* if |x|>=88.721... */
+ if(hx>0x7f800000)
+ return x+x; /* NaN */
+ if(hx==0x7f800000)
+ return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */
+ if(x > o_threshold) return huge*huge; /* overflow */
+ if(x < u_threshold) return twom100*twom100; /* underflow */
+ }
+
+ /* argument reduction */
+ if(hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
+ if(hx < 0x3F851592) { /* and |x| < 1.5 ln2 */
+ hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
+ } else {
+ k = invln2*x+halF[xsb];
+ t = k;
+ hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */
+ lo = t*ln2LO[0];
+ }
+ x = hi - lo;
+ }
+ else if(hx < 0x31800000) { /* when |x|<2**-28 */
+ if(huge+x>one) return one+x;/* trigger inexact */
+ }
+ else k = 0;
+
+ /* x is now in primary range */
+ t = x*x;
+ c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+ if(k==0) return one-((x*c)/(c-(float)2.0)-x);
+ else y = one-((lo-(x*c)/((float)2.0-c))-hi);
+ if(k >= -125) {
+ u_int32_t hy;
+ GET_FLOAT_WORD(hy,y);
+ SET_FLOAT_WORD(y,hy+(k<<23)); /* add k to y's exponent */
+ return y;
+ } else {
+ u_int32_t hy;
+ GET_FLOAT_WORD(hy,y);
+ SET_FLOAT_WORD(y,hy+((k+100)<<23)); /* add k to y's exponent */
+ return y*twom100;
+ }
+}
diff --git a/lib/msun/src/e_fmod.c b/lib/msun/src/e_fmod.c
new file mode 100644
index 0000000..f168630
--- /dev/null
+++ b/lib/msun/src/e_fmod.c
@@ -0,0 +1,140 @@
+/* @(#)e_fmod.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * __ieee754_fmod(x,y)
+ * Return x mod y in exact arithmetic
+ * Method: shift and subtract
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one = 1.0, Zero[] = {0.0, -0.0,};
+#else
+static double one = 1.0, Zero[] = {0.0, -0.0,};
+#endif
+
+#ifdef __STDC__
+ double __generic___ieee754_fmod(double x, double y)
+#else
+ double __generic___ieee754_fmod(x,y)
+ double x,y ;
+#endif
+{
+ int32_t n,hx,hy,hz,ix,iy,sx,i;
+ u_int32_t lx,ly,lz;
+
+ EXTRACT_WORDS(hx,lx,x);
+ EXTRACT_WORDS(hy,ly,y);
+ sx = hx&0x80000000; /* sign of x */
+ hx ^=sx; /* |x| */
+ hy &= 0x7fffffff; /* |y| */
+
+ /* purge off exception values */
+ if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
+ ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */
+ return (x*y)/(x*y);
+ if(hx<=hy) {
+ if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
+ if(lx==ly)
+ return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/
+ }
+
+ /* determine ix = ilogb(x) */
+ if(hx<0x00100000) { /* subnormal x */
+ if(hx==0) {
+ for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
+ } else {
+ for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
+ }
+ } else ix = (hx>>20)-1023;
+
+ /* determine iy = ilogb(y) */
+ if(hy<0x00100000) { /* subnormal y */
+ if(hy==0) {
+ for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
+ } else {
+ for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
+ }
+ } else iy = (hy>>20)-1023;
+
+ /* set up {hx,lx}, {hy,ly} and align y to x */
+ if(ix >= -1022)
+ hx = 0x00100000|(0x000fffff&hx);
+ else { /* subnormal x, shift x to normal */
+ n = -1022-ix;
+ if(n<=31) {
+ hx = (hx<<n)|(lx>>(32-n));
+ lx <<= n;
+ } else {
+ hx = lx<<(n-32);
+ lx = 0;
+ }
+ }
+ if(iy >= -1022)
+ hy = 0x00100000|(0x000fffff&hy);
+ else { /* subnormal y, shift y to normal */
+ n = -1022-iy;
+ if(n<=31) {
+ hy = (hy<<n)|(ly>>(32-n));
+ ly <<= n;
+ } else {
+ hy = ly<<(n-32);
+ ly = 0;
+ }
+ }
+
+ /* fix point fmod */
+ n = ix - iy;
+ while(n--) {
+ hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
+ else {
+ if((hz|lz)==0) /* return sign(x)*0 */
+ return Zero[(u_int32_t)sx>>31];
+ hx = hz+hz+(lz>>31); lx = lz+lz;
+ }
+ }
+ hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ if(hz>=0) {hx=hz;lx=lz;}
+
+ /* convert back to floating value and restore the sign */
+ if((hx|lx)==0) /* return sign(x)*0 */
+ return Zero[(u_int32_t)sx>>31];
+ while(hx<0x00100000) { /* normalize x */
+ hx = hx+hx+(lx>>31); lx = lx+lx;
+ iy -= 1;
+ }
+ if(iy>= -1022) { /* normalize output */
+ hx = ((hx-0x00100000)|((iy+1023)<<20));
+ INSERT_WORDS(x,hx|sx,lx);
+ } else { /* subnormal output */
+ n = -1022 - iy;
+ if(n<=20) {
+ lx = (lx>>n)|((u_int32_t)hx<<(32-n));
+ hx >>= n;
+ } else if (n<=31) {
+ lx = (hx<<(32-n))|(lx>>n); hx = sx;
+ } else {
+ lx = hx>>(n-32); hx = sx;
+ }
+ INSERT_WORDS(x,hx|sx,lx);
+ x *= one; /* create necessary signal */
+ }
+ return x; /* exact output */
+}
diff --git a/lib/msun/src/e_fmodf.c b/lib/msun/src/e_fmodf.c
new file mode 100644
index 0000000..01d85d0
--- /dev/null
+++ b/lib/msun/src/e_fmodf.c
@@ -0,0 +1,113 @@
+/* e_fmodf.c -- float version of e_fmod.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * __ieee754_fmodf(x,y)
+ * Return x mod y in exact arithmetic
+ * Method: shift and subtract
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one = 1.0, Zero[] = {0.0, -0.0,};
+#else
+static float one = 1.0, Zero[] = {0.0, -0.0,};
+#endif
+
+#ifdef __STDC__
+ float __ieee754_fmodf(float x, float y)
+#else
+ float __ieee754_fmodf(x,y)
+ float x,y ;
+#endif
+{
+ int32_t n,hx,hy,hz,ix,iy,sx,i;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_FLOAT_WORD(hy,y);
+ sx = hx&0x80000000; /* sign of x */
+ hx ^=sx; /* |x| */
+ hy &= 0x7fffffff; /* |y| */
+
+ /* purge off exception values */
+ if(hy==0||(hx>=0x7f800000)|| /* y=0,or x not finite */
+ (hy>0x7f800000)) /* or y is NaN */
+ return (x*y)/(x*y);
+ if(hx<hy) return x; /* |x|<|y| return x */
+ if(hx==hy)
+ return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/
+
+ /* determine ix = ilogb(x) */
+ if(hx<0x00800000) { /* subnormal x */
+ for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1;
+ } else ix = (hx>>23)-127;
+
+ /* determine iy = ilogb(y) */
+ if(hy<0x00800000) { /* subnormal y */
+ for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1;
+ } else iy = (hy>>23)-127;
+
+ /* set up {hx,lx}, {hy,ly} and align y to x */
+ if(ix >= -126)
+ hx = 0x00800000|(0x007fffff&hx);
+ else { /* subnormal x, shift x to normal */
+ n = -126-ix;
+ hx = hx<<n;
+ }
+ if(iy >= -126)
+ hy = 0x00800000|(0x007fffff&hy);
+ else { /* subnormal y, shift y to normal */
+ n = -126-iy;
+ hy = hy<<n;
+ }
+
+ /* fix point fmod */
+ n = ix - iy;
+ while(n--) {
+ hz=hx-hy;
+ if(hz<0){hx = hx+hx;}
+ else {
+ if(hz==0) /* return sign(x)*0 */
+ return Zero[(u_int32_t)sx>>31];
+ hx = hz+hz;
+ }
+ }
+ hz=hx-hy;
+ if(hz>=0) {hx=hz;}
+
+ /* convert back to floating value and restore the sign */
+ if(hx==0) /* return sign(x)*0 */
+ return Zero[(u_int32_t)sx>>31];
+ while(hx<0x00800000) { /* normalize x */
+ hx = hx+hx;
+ iy -= 1;
+ }
+ if(iy>= -126) { /* normalize output */
+ hx = ((hx-0x00800000)|((iy+127)<<23));
+ SET_FLOAT_WORD(x,hx|sx);
+ } else { /* subnormal output */
+ n = -126 - iy;
+ hx >>= n;
+ SET_FLOAT_WORD(x,hx|sx);
+ x *= one; /* create necessary signal */
+ }
+ return x; /* exact output */
+}
diff --git a/lib/msun/src/e_gamma.c b/lib/msun/src/e_gamma.c
new file mode 100644
index 0000000..bad4569
--- /dev/null
+++ b/lib/msun/src/e_gamma.c
@@ -0,0 +1,37 @@
+/* @(#)e_gamma.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_gamma(x)
+ * Return the logarithm of the Gamma function of x.
+ *
+ * Method: call __ieee754_gamma_r
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+extern int signgam;
+
+#ifdef __STDC__
+ double __ieee754_gamma(double x)
+#else
+ double __ieee754_gamma(x)
+ double x;
+#endif
+{
+ return __ieee754_gamma_r(x,&signgam);
+}
diff --git a/lib/msun/src/e_gamma_r.c b/lib/msun/src/e_gamma_r.c
new file mode 100644
index 0000000..7d5197f
--- /dev/null
+++ b/lib/msun/src/e_gamma_r.c
@@ -0,0 +1,35 @@
+/* @(#)er_gamma.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_gamma_r(x, signgamp)
+ * Reentrant version of the logarithm of the Gamma function
+ * with user provide pointer for the sign of Gamma(x).
+ *
+ * Method: See __ieee754_lgamma_r
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __ieee754_gamma_r(double x, int *signgamp)
+#else
+ double __ieee754_gamma_r(x,signgamp)
+ double x; int *signgamp;
+#endif
+{
+ return __ieee754_lgamma_r(x,signgamp);
+}
diff --git a/lib/msun/src/e_gammaf.c b/lib/msun/src/e_gammaf.c
new file mode 100644
index 0000000..f05ebef
--- /dev/null
+++ b/lib/msun/src/e_gammaf.c
@@ -0,0 +1,39 @@
+/* e_gammaf.c -- float version of e_gamma.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_gammaf(x)
+ * Return the logarithm of the Gamma function of x.
+ *
+ * Method: call __ieee754_gammaf_r
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+extern int signgam;
+
+#ifdef __STDC__
+ float __ieee754_gammaf(float x)
+#else
+ float __ieee754_gammaf(x)
+ float x;
+#endif
+{
+ return __ieee754_gammaf_r(x,&signgam);
+}
diff --git a/lib/msun/src/e_gammaf_r.c b/lib/msun/src/e_gammaf_r.c
new file mode 100644
index 0000000..6847aa7
--- /dev/null
+++ b/lib/msun/src/e_gammaf_r.c
@@ -0,0 +1,38 @@
+/* e_gammaf_r.c -- float version of e_gamma_r.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_gammaf_r(x, signgamp)
+ * Reentrant version of the logarithm of the Gamma function
+ * with user provide pointer for the sign of Gamma(x).
+ *
+ * Method: See __ieee754_lgammaf_r
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float __ieee754_gammaf_r(float x, int *signgamp)
+#else
+ float __ieee754_gammaf_r(x,signgamp)
+ float x; int *signgamp;
+#endif
+{
+ return __ieee754_lgammaf_r(x,signgamp);
+}
diff --git a/lib/msun/src/e_hypot.c b/lib/msun/src/e_hypot.c
new file mode 100644
index 0000000..40af9c7
--- /dev/null
+++ b/lib/msun/src/e_hypot.c
@@ -0,0 +1,128 @@
+/* @(#)e_hypot.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_hypot(x,y)
+ *
+ * Method :
+ * If (assume round-to-nearest) z=x*x+y*y
+ * has error less than sqrt(2)/2 ulp, than
+ * sqrt(z) has error less than 1 ulp (exercise).
+ *
+ * So, compute sqrt(x*x+y*y) with some care as
+ * follows to get the error below 1 ulp:
+ *
+ * Assume x>y>0;
+ * (if possible, set rounding to round-to-nearest)
+ * 1. if x > 2y use
+ * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
+ * where x1 = x with lower 32 bits cleared, x2 = x-x1; else
+ * 2. if x <= 2y use
+ * t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
+ * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
+ * y1= y with lower 32 bits chopped, y2 = y-y1.
+ *
+ * NOTE: scaling may be necessary if some argument is too
+ * large or too tiny
+ *
+ * Special cases:
+ * hypot(x,y) is INF if x or y is +INF or -INF; else
+ * hypot(x,y) is NAN if x or y is NAN.
+ *
+ * Accuracy:
+ * hypot(x,y) returns sqrt(x^2+y^2) with error less
+ * than 1 ulps (units in the last place)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __ieee754_hypot(double x, double y)
+#else
+ double __ieee754_hypot(x,y)
+ double x, y;
+#endif
+{
+ double a=x,b=y,t1,t2,y1,y2,w;
+ int32_t j,k,ha,hb;
+
+ GET_HIGH_WORD(ha,x);
+ ha &= 0x7fffffff;
+ GET_HIGH_WORD(hb,y);
+ hb &= 0x7fffffff;
+ if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
+ SET_HIGH_WORD(a,ha); /* a <- |a| */
+ SET_HIGH_WORD(b,hb); /* b <- |b| */
+ if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
+ k=0;
+ if(ha > 0x5f300000) { /* a>2**500 */
+ if(ha >= 0x7ff00000) { /* Inf or NaN */
+ u_int32_t low;
+ w = a+b; /* for sNaN */
+ GET_LOW_WORD(low,a);
+ if(((ha&0xfffff)|low)==0) w = a;
+ GET_LOW_WORD(low,b);
+ if(((hb^0x7ff00000)|low)==0) w = b;
+ return w;
+ }
+ /* scale a and b by 2**-600 */
+ ha -= 0x25800000; hb -= 0x25800000; k += 600;
+ SET_HIGH_WORD(a,ha);
+ SET_HIGH_WORD(b,hb);
+ }
+ if(hb < 0x20b00000) { /* b < 2**-500 */
+ if(hb <= 0x000fffff) { /* subnormal b or 0 */
+ u_int32_t low;
+ GET_LOW_WORD(low,b);
+ if((hb|low)==0) return a;
+ t1=0;
+ SET_HIGH_WORD(t1,0x7fd00000); /* t1=2^1022 */
+ b *= t1;
+ a *= t1;
+ k -= 1022;
+ } else { /* scale a and b by 2^600 */
+ ha += 0x25800000; /* a *= 2^600 */
+ hb += 0x25800000; /* b *= 2^600 */
+ k -= 600;
+ SET_HIGH_WORD(a,ha);
+ SET_HIGH_WORD(b,hb);
+ }
+ }
+ /* medium size a and b */
+ w = a-b;
+ if (w>b) {
+ t1 = 0;
+ SET_HIGH_WORD(t1,ha);
+ t2 = a-t1;
+ w = __ieee754_sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
+ } else {
+ a = a+a;
+ y1 = 0;
+ SET_HIGH_WORD(y1,hb);
+ y2 = b - y1;
+ t1 = 0;
+ SET_HIGH_WORD(t1,ha+0x00100000);
+ t2 = a - t1;
+ w = __ieee754_sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
+ }
+ if(k!=0) {
+ u_int32_t high;
+ t1 = 1.0;
+ GET_HIGH_WORD(high,t1);
+ SET_HIGH_WORD(t1,high+(k<<20));
+ return t1*w;
+ } else return w;
+}
diff --git a/lib/msun/src/e_hypotf.c b/lib/msun/src/e_hypotf.c
new file mode 100644
index 0000000..52b2288
--- /dev/null
+++ b/lib/msun/src/e_hypotf.c
@@ -0,0 +1,87 @@
+/* e_hypotf.c -- float version of e_hypot.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float __ieee754_hypotf(float x, float y)
+#else
+ float __ieee754_hypot(x,y)
+ float x, y;
+#endif
+{
+ float a=x,b=y,t1,t2,y1,y2,w;
+ int32_t j,k,ha,hb;
+
+ GET_FLOAT_WORD(ha,x);
+ ha &= 0x7fffffff;
+ GET_FLOAT_WORD(hb,y);
+ hb &= 0x7fffffff;
+ if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
+ SET_FLOAT_WORD(a,ha); /* a <- |a| */
+ SET_FLOAT_WORD(b,hb); /* b <- |b| */
+ if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */
+ k=0;
+ if(ha > 0x58800000) { /* a>2**50 */
+ if(ha >= 0x7f800000) { /* Inf or NaN */
+ w = a+b; /* for sNaN */
+ if(ha == 0x7f800000) w = a;
+ if(hb == 0x7f800000) w = b;
+ return w;
+ }
+ /* scale a and b by 2**-68 */
+ ha -= 0x22000000; hb -= 0x22000000; k += 68;
+ SET_FLOAT_WORD(a,ha);
+ SET_FLOAT_WORD(b,hb);
+ }
+ if(hb < 0x26800000) { /* b < 2**-50 */
+ if(hb <= 0x007fffff) { /* subnormal b or 0 */
+ if(hb==0) return a;
+ SET_FLOAT_WORD(t1,0x7e800000); /* t1=2^126 */
+ b *= t1;
+ a *= t1;
+ k -= 126;
+ } else { /* scale a and b by 2^68 */
+ ha += 0x22000000; /* a *= 2^68 */
+ hb += 0x22000000; /* b *= 2^68 */
+ k -= 68;
+ SET_FLOAT_WORD(a,ha);
+ SET_FLOAT_WORD(b,hb);
+ }
+ }
+ /* medium size a and b */
+ w = a-b;
+ if (w>b) {
+ SET_FLOAT_WORD(t1,ha&0xfffff000);
+ t2 = a-t1;
+ w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
+ } else {
+ a = a+a;
+ SET_FLOAT_WORD(y1,hb&0xfffff000);
+ y2 = b - y1;
+ SET_FLOAT_WORD(t1,ha+0x00800000);
+ t2 = a - t1;
+ w = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
+ }
+ if(k!=0) {
+ SET_FLOAT_WORD(t1,0x3f800000+(k<<23));
+ return t1*w;
+ } else return w;
+}
diff --git a/lib/msun/src/e_j0.c b/lib/msun/src/e_j0.c
new file mode 100644
index 0000000..1747d78
--- /dev/null
+++ b/lib/msun/src/e_j0.c
@@ -0,0 +1,487 @@
+/* @(#)e_j0.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_j0(x), __ieee754_y0(x)
+ * Bessel function of the first and second kinds of order zero.
+ * Method -- j0(x):
+ * 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ...
+ * 2. Reduce x to |x| since j0(x)=j0(-x), and
+ * for x in (0,2)
+ * j0(x) = 1-z/4+ z^2*R0/S0, where z = x*x;
+ * (precision: |j0-1+z/4-z^2R0/S0 |<2**-63.67 )
+ * for x in (2,inf)
+ * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0))
+ * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
+ * as follow:
+ * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+ * = 1/sqrt(2) * (cos(x) + sin(x))
+ * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * (To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.)
+ *
+ * 3 Special cases
+ * j0(nan)= nan
+ * j0(0) = 1
+ * j0(inf) = 0
+ *
+ * Method -- y0(x):
+ * 1. For x<2.
+ * Since
+ * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...)
+ * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function.
+ * We use the following function to approximate y0,
+ * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2
+ * where
+ * U(z) = u00 + u01*z + ... + u06*z^6
+ * V(z) = 1 + v01*z + ... + v04*z^4
+ * with absolute approximation error bounded by 2**-72.
+ * Note: For tiny x, U/V = u0 and j0(x)~1, hence
+ * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27)
+ * 2. For x>=2.
+ * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0))
+ * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
+ * by the method mentioned above.
+ * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static double pzero(double), qzero(double);
+#else
+static double pzero(), qzero();
+#endif
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+huge = 1e300,
+one = 1.0,
+invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+ /* R0/S0 on [0, 2.00] */
+R02 = 1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */
+R03 = -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */
+R04 = 1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */
+R05 = -4.61832688532103189199e-09, /* 0xBE33D5E7, 0x73D63FCE */
+S01 = 1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */
+S02 = 1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */
+S03 = 5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */
+S04 = 1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_j0(double x)
+#else
+ double __ieee754_j0(x)
+ double x;
+#endif
+{
+ double z, s,c,ss,cc,r,u,v;
+ int32_t hx,ix;
+
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) return one/(x*x);
+ x = fabs(x);
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ s = sin(x);
+ c = cos(x);
+ ss = s-c;
+ cc = s+c;
+ if(ix<0x7fe00000) { /* make sure x+x not overflow */
+ z = -cos(x+x);
+ if ((s*c)<zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /*
+ * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+ * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+ */
+ if(ix>0x48000000) z = (invsqrtpi*cc)/sqrt(x);
+ else {
+ u = pzero(x); v = qzero(x);
+ z = invsqrtpi*(u*cc-v*ss)/sqrt(x);
+ }
+ return z;
+ }
+ if(ix<0x3f200000) { /* |x| < 2**-13 */
+ if(huge+x>one) { /* raise inexact if x != 0 */
+ if(ix<0x3e400000) return one; /* |x|<2**-27 */
+ else return one - 0.25*x*x;
+ }
+ }
+ z = x*x;
+ r = z*(R02+z*(R03+z*(R04+z*R05)));
+ s = one+z*(S01+z*(S02+z*(S03+z*S04)));
+ if(ix < 0x3FF00000) { /* |x| < 1.00 */
+ return one + z*(-0.25+(r/s));
+ } else {
+ u = 0.5*x;
+ return((one+u)*(one-u)+z*(r/s));
+ }
+}
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+u00 = -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */
+u01 = 1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */
+u02 = -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */
+u03 = 3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */
+u04 = -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */
+u05 = 1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */
+u06 = -3.98205194132103398453e-11, /* 0xBDC5E43D, 0x693FB3C8 */
+v01 = 1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */
+v02 = 7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */
+v03 = 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */
+v04 = 4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */
+
+#ifdef __STDC__
+ double __ieee754_y0(double x)
+#else
+ double __ieee754_y0(x)
+ double x;
+#endif
+{
+ double z, s,c,ss,cc,u,v;
+ int32_t hx,ix,lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+ ix = 0x7fffffff&hx;
+ /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */
+ if(ix>=0x7ff00000) return one/(x+x*x);
+ if((ix|lx)==0) return -one/zero;
+ if(hx<0) return zero/zero;
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
+ * where x0 = x-pi/4
+ * Better formula:
+ * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+ * = 1/sqrt(2) * (sin(x) + cos(x))
+ * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.
+ */
+ s = sin(x);
+ c = cos(x);
+ ss = s-c;
+ cc = s+c;
+ /*
+ * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+ * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+ */
+ if(ix<0x7fe00000) { /* make sure x+x not overflow */
+ z = -cos(x+x);
+ if ((s*c)<zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ if(ix>0x48000000) z = (invsqrtpi*ss)/sqrt(x);
+ else {
+ u = pzero(x); v = qzero(x);
+ z = invsqrtpi*(u*ss+v*cc)/sqrt(x);
+ }
+ return z;
+ }
+ if(ix<=0x3e400000) { /* x < 2**-27 */
+ return(u00 + tpi*__ieee754_log(x));
+ }
+ z = x*x;
+ u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
+ v = one+z*(v01+z*(v02+z*(v03+z*v04)));
+ return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x)));
+}
+
+/* The asymptotic expansions of pzero is
+ * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x.
+ * For x >= 2, We approximate pzero by
+ * pzero(x) = 1 + (R/S)
+ * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10
+ * S = 1 + pS0*s^2 + ... + pS4*s^10
+ * and
+ * | pzero(x)-1-R/S | <= 2 ** ( -60.26)
+ */
+#ifdef __STDC__
+static const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+ -7.03124999999900357484e-02, /* 0xBFB1FFFF, 0xFFFFFD32 */
+ -8.08167041275349795626e+00, /* 0xC02029D0, 0xB44FA779 */
+ -2.57063105679704847262e+02, /* 0xC0701102, 0x7B19E863 */
+ -2.48521641009428822144e+03, /* 0xC0A36A6E, 0xCD4DCAFC */
+ -5.25304380490729545272e+03, /* 0xC0B4850B, 0x36CC643D */
+};
+#ifdef __STDC__
+static const double pS8[5] = {
+#else
+static double pS8[5] = {
+#endif
+ 1.16534364619668181717e+02, /* 0x405D2233, 0x07A96751 */
+ 3.83374475364121826715e+03, /* 0x40ADF37D, 0x50596938 */
+ 4.05978572648472545552e+04, /* 0x40E3D2BB, 0x6EB6B05F */
+ 1.16752972564375915681e+05, /* 0x40FC810F, 0x8F9FA9BD */
+ 4.76277284146730962675e+04, /* 0x40E74177, 0x4F2C49DC */
+};
+
+#ifdef __STDC__
+static const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ -1.14125464691894502584e-11, /* 0xBDA918B1, 0x47E495CC */
+ -7.03124940873599280078e-02, /* 0xBFB1FFFF, 0xE69AFBC6 */
+ -4.15961064470587782438e+00, /* 0xC010A370, 0xF90C6BBF */
+ -6.76747652265167261021e+01, /* 0xC050EB2F, 0x5A7D1783 */
+ -3.31231299649172967747e+02, /* 0xC074B3B3, 0x6742CC63 */
+ -3.46433388365604912451e+02, /* 0xC075A6EF, 0x28A38BD7 */
+};
+#ifdef __STDC__
+static const double pS5[5] = {
+#else
+static double pS5[5] = {
+#endif
+ 6.07539382692300335975e+01, /* 0x404E6081, 0x0C98C5DE */
+ 1.05125230595704579173e+03, /* 0x40906D02, 0x5C7E2864 */
+ 5.97897094333855784498e+03, /* 0x40B75AF8, 0x8FBE1D60 */
+ 9.62544514357774460223e+03, /* 0x40C2CCB8, 0xFA76FA38 */
+ 2.40605815922939109441e+03, /* 0x40A2CC1D, 0xC70BE864 */
+};
+
+#ifdef __STDC__
+static const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#else
+static double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ -2.54704601771951915620e-09, /* 0xBE25E103, 0x6FE1AA86 */
+ -7.03119616381481654654e-02, /* 0xBFB1FFF6, 0xF7C0E24B */
+ -2.40903221549529611423e+00, /* 0xC00345B2, 0xAEA48074 */
+ -2.19659774734883086467e+01, /* 0xC035F74A, 0x4CB94E14 */
+ -5.80791704701737572236e+01, /* 0xC04D0A22, 0x420A1A45 */
+ -3.14479470594888503854e+01, /* 0xC03F72AC, 0xA892D80F */
+};
+#ifdef __STDC__
+static const double pS3[5] = {
+#else
+static double pS3[5] = {
+#endif
+ 3.58560338055209726349e+01, /* 0x4041ED92, 0x84077DD3 */
+ 3.61513983050303863820e+02, /* 0x40769839, 0x464A7C0E */
+ 1.19360783792111533330e+03, /* 0x4092A66E, 0x6D1061D6 */
+ 1.12799679856907414432e+03, /* 0x40919FFC, 0xB8C39B7E */
+ 1.73580930813335754692e+02, /* 0x4065B296, 0xFC379081 */
+};
+
+#ifdef __STDC__
+static const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ -8.87534333032526411254e-08, /* 0xBE77D316, 0xE927026D */
+ -7.03030995483624743247e-02, /* 0xBFB1FF62, 0x495E1E42 */
+ -1.45073846780952986357e+00, /* 0xBFF73639, 0x8A24A843 */
+ -7.63569613823527770791e+00, /* 0xC01E8AF3, 0xEDAFA7F3 */
+ -1.11931668860356747786e+01, /* 0xC02662E6, 0xC5246303 */
+ -3.23364579351335335033e+00, /* 0xC009DE81, 0xAF8FE70F */
+};
+#ifdef __STDC__
+static const double pS2[5] = {
+#else
+static double pS2[5] = {
+#endif
+ 2.22202997532088808441e+01, /* 0x40363865, 0x908B5959 */
+ 1.36206794218215208048e+02, /* 0x4061069E, 0x0EE8878F */
+ 2.70470278658083486789e+02, /* 0x4070E786, 0x42EA079B */
+ 1.53875394208320329881e+02, /* 0x40633C03, 0x3AB6FAFF */
+ 1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */
+};
+
+#ifdef __STDC__
+ static double pzero(double x)
+#else
+ static double pzero(x)
+ double x;
+#endif
+{
+#ifdef __STDC__
+ const double *p,*q;
+#else
+ double *p,*q;
+#endif
+ double z,r,s;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x40200000) {p = pR8; q= pS8;}
+ else if(ix>=0x40122E8B){p = pR5; q= pS5;}
+ else if(ix>=0x4006DB6D){p = pR3; q= pS3;}
+ else if(ix>=0x40000000){p = pR2; q= pS2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+ return one+ r/s;
+}
+
+
+/* For x >= 8, the asymptotic expansions of qzero is
+ * -1/8 s + 75/1024 s^3 - ..., where s = 1/x.
+ * We approximate pzero by
+ * qzero(x) = s*(-1.25 + (R/S))
+ * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10
+ * S = 1 + qS0*s^2 + ... + qS5*s^12
+ * and
+ * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22)
+ */
+#ifdef __STDC__
+static const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+ 7.32421874999935051953e-02, /* 0x3FB2BFFF, 0xFFFFFE2C */
+ 1.17682064682252693899e+01, /* 0x40278952, 0x5BB334D6 */
+ 5.57673380256401856059e+02, /* 0x40816D63, 0x15301825 */
+ 8.85919720756468632317e+03, /* 0x40C14D99, 0x3E18F46D */
+ 3.70146267776887834771e+04, /* 0x40E212D4, 0x0E901566 */
+};
+#ifdef __STDC__
+static const double qS8[6] = {
+#else
+static double qS8[6] = {
+#endif
+ 1.63776026895689824414e+02, /* 0x406478D5, 0x365B39BC */
+ 8.09834494656449805916e+03, /* 0x40BFA258, 0x4E6B0563 */
+ 1.42538291419120476348e+05, /* 0x41016652, 0x54D38C3F */
+ 8.03309257119514397345e+05, /* 0x412883DA, 0x83A52B43 */
+ 8.40501579819060512818e+05, /* 0x4129A66B, 0x28DE0B3D */
+ -3.43899293537866615225e+05, /* 0xC114FD6D, 0x2C9530C5 */
+};
+
+#ifdef __STDC__
+static const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ 1.84085963594515531381e-11, /* 0x3DB43D8F, 0x29CC8CD9 */
+ 7.32421766612684765896e-02, /* 0x3FB2BFFF, 0xD172B04C */
+ 5.83563508962056953777e+00, /* 0x401757B0, 0xB9953DD3 */
+ 1.35111577286449829671e+02, /* 0x4060E392, 0x0A8788E9 */
+ 1.02724376596164097464e+03, /* 0x40900CF9, 0x9DC8C481 */
+ 1.98997785864605384631e+03, /* 0x409F17E9, 0x53C6E3A6 */
+};
+#ifdef __STDC__
+static const double qS5[6] = {
+#else
+static double qS5[6] = {
+#endif
+ 8.27766102236537761883e+01, /* 0x4054B1B3, 0xFB5E1543 */
+ 2.07781416421392987104e+03, /* 0x40A03BA0, 0xDA21C0CE */
+ 1.88472887785718085070e+04, /* 0x40D267D2, 0x7B591E6D */
+ 5.67511122894947329769e+04, /* 0x40EBB5E3, 0x97E02372 */
+ 3.59767538425114471465e+04, /* 0x40E19118, 0x1F7A54A0 */
+ -5.35434275601944773371e+03, /* 0xC0B4EA57, 0xBEDBC609 */
+};
+
+#ifdef __STDC__
+static const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#else
+static double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ 4.37741014089738620906e-09, /* 0x3E32CD03, 0x6ADECB82 */
+ 7.32411180042911447163e-02, /* 0x3FB2BFEE, 0x0E8D0842 */
+ 3.34423137516170720929e+00, /* 0x400AC0FC, 0x61149CF5 */
+ 4.26218440745412650017e+01, /* 0x40454F98, 0x962DAEDD */
+ 1.70808091340565596283e+02, /* 0x406559DB, 0xE25EFD1F */
+ 1.66733948696651168575e+02, /* 0x4064D77C, 0x81FA21E0 */
+};
+#ifdef __STDC__
+static const double qS3[6] = {
+#else
+static double qS3[6] = {
+#endif
+ 4.87588729724587182091e+01, /* 0x40486122, 0xBFE343A6 */
+ 7.09689221056606015736e+02, /* 0x40862D83, 0x86544EB3 */
+ 3.70414822620111362994e+03, /* 0x40ACF04B, 0xE44DFC63 */
+ 6.46042516752568917582e+03, /* 0x40B93C6C, 0xD7C76A28 */
+ 2.51633368920368957333e+03, /* 0x40A3A8AA, 0xD94FB1C0 */
+ -1.49247451836156386662e+02, /* 0xC062A7EB, 0x201CF40F */
+};
+
+#ifdef __STDC__
+static const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ 1.50444444886983272379e-07, /* 0x3E84313B, 0x54F76BDB */
+ 7.32234265963079278272e-02, /* 0x3FB2BEC5, 0x3E883E34 */
+ 1.99819174093815998816e+00, /* 0x3FFFF897, 0xE727779C */
+ 1.44956029347885735348e+01, /* 0x402CFDBF, 0xAAF96FE5 */
+ 3.16662317504781540833e+01, /* 0x403FAA8E, 0x29FBDC4A */
+ 1.62527075710929267416e+01, /* 0x403040B1, 0x71814BB4 */
+};
+#ifdef __STDC__
+static const double qS2[6] = {
+#else
+static double qS2[6] = {
+#endif
+ 3.03655848355219184498e+01, /* 0x403E5D96, 0xF7C07AED */
+ 2.69348118608049844624e+02, /* 0x4070D591, 0xE4D14B40 */
+ 8.44783757595320139444e+02, /* 0x408A6645, 0x22B3BF22 */
+ 8.82935845112488550512e+02, /* 0x408B977C, 0x9C5CC214 */
+ 2.12666388511798828631e+02, /* 0x406A9553, 0x0E001365 */
+ -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */
+};
+
+#ifdef __STDC__
+ static double qzero(double x)
+#else
+ static double qzero(x)
+ double x;
+#endif
+{
+#ifdef __STDC__
+ const double *p,*q;
+#else
+ double *p,*q;
+#endif
+ double s,r,z;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x40200000) {p = qR8; q= qS8;}
+ else if(ix>=0x40122E8B){p = qR5; q= qS5;}
+ else if(ix>=0x4006DB6D){p = qR3; q= qS3;}
+ else if(ix>=0x40000000){p = qR2; q= qS2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+ return (-.125 + r/s)/x;
+}
diff --git a/lib/msun/src/e_j0f.c b/lib/msun/src/e_j0f.c
new file mode 100644
index 0000000..ad27122
--- /dev/null
+++ b/lib/msun/src/e_j0f.c
@@ -0,0 +1,444 @@
+/* e_j0f.c -- float version of e_j0.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static float pzerof(float), qzerof(float);
+#else
+static float pzerof(), qzerof();
+#endif
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+huge = 1e30,
+one = 1.0,
+invsqrtpi= 5.6418961287e-01, /* 0x3f106ebb */
+tpi = 6.3661974669e-01, /* 0x3f22f983 */
+ /* R0/S0 on [0, 2.00] */
+R02 = 1.5625000000e-02, /* 0x3c800000 */
+R03 = -1.8997929874e-04, /* 0xb947352e */
+R04 = 1.8295404516e-06, /* 0x35f58e88 */
+R05 = -4.6183270541e-09, /* 0xb19eaf3c */
+S01 = 1.5619102865e-02, /* 0x3c7fe744 */
+S02 = 1.1692678527e-04, /* 0x38f53697 */
+S03 = 5.1354652442e-07, /* 0x3509daa6 */
+S04 = 1.1661400734e-09; /* 0x30a045e8 */
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_j0f(float x)
+#else
+ float __ieee754_j0f(x)
+ float x;
+#endif
+{
+ float z, s,c,ss,cc,r,u,v;
+ int32_t hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7f800000) return one/(x*x);
+ x = fabsf(x);
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ s = sinf(x);
+ c = cosf(x);
+ ss = s-c;
+ cc = s+c;
+ if(ix<0x7f000000) { /* make sure x+x not overflow */
+ z = -cosf(x+x);
+ if ((s*c)<zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /*
+ * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+ * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+ */
+ if(ix>0x80000000) z = (invsqrtpi*cc)/sqrtf(x);
+ else {
+ u = pzerof(x); v = qzerof(x);
+ z = invsqrtpi*(u*cc-v*ss)/sqrtf(x);
+ }
+ return z;
+ }
+ if(ix<0x39000000) { /* |x| < 2**-13 */
+ if(huge+x>one) { /* raise inexact if x != 0 */
+ if(ix<0x32000000) return one; /* |x|<2**-27 */
+ else return one - (float)0.25*x*x;
+ }
+ }
+ z = x*x;
+ r = z*(R02+z*(R03+z*(R04+z*R05)));
+ s = one+z*(S01+z*(S02+z*(S03+z*S04)));
+ if(ix < 0x3F800000) { /* |x| < 1.00 */
+ return one + z*((float)-0.25+(r/s));
+ } else {
+ u = (float)0.5*x;
+ return((one+u)*(one-u)+z*(r/s));
+ }
+}
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+u00 = -7.3804296553e-02, /* 0xbd9726b5 */
+u01 = 1.7666645348e-01, /* 0x3e34e80d */
+u02 = -1.3818567619e-02, /* 0xbc626746 */
+u03 = 3.4745343146e-04, /* 0x39b62a69 */
+u04 = -3.8140706238e-06, /* 0xb67ff53c */
+u05 = 1.9559013964e-08, /* 0x32a802ba */
+u06 = -3.9820518410e-11, /* 0xae2f21eb */
+v01 = 1.2730483897e-02, /* 0x3c509385 */
+v02 = 7.6006865129e-05, /* 0x389f65e0 */
+v03 = 2.5915085189e-07, /* 0x348b216c */
+v04 = 4.4111031494e-10; /* 0x2ff280c2 */
+
+#ifdef __STDC__
+ float __ieee754_y0f(float x)
+#else
+ float __ieee754_y0f(x)
+ float x;
+#endif
+{
+ float z, s,c,ss,cc,u,v;
+ int32_t hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = 0x7fffffff&hx;
+ /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */
+ if(ix>=0x7f800000) return one/(x+x*x);
+ if(ix==0) return -one/zero;
+ if(hx<0) return zero/zero;
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
+ * where x0 = x-pi/4
+ * Better formula:
+ * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+ * = 1/sqrt(2) * (sin(x) + cos(x))
+ * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.
+ */
+ s = sinf(x);
+ c = cosf(x);
+ ss = s-c;
+ cc = s+c;
+ /*
+ * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+ * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+ */
+ if(ix<0x7f000000) { /* make sure x+x not overflow */
+ z = -cosf(x+x);
+ if ((s*c)<zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ if(ix>0x80000000) z = (invsqrtpi*ss)/sqrtf(x);
+ else {
+ u = pzerof(x); v = qzerof(x);
+ z = invsqrtpi*(u*ss+v*cc)/sqrtf(x);
+ }
+ return z;
+ }
+ if(ix<=0x32000000) { /* x < 2**-27 */
+ return(u00 + tpi*__ieee754_logf(x));
+ }
+ z = x*x;
+ u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
+ v = one+z*(v01+z*(v02+z*(v03+z*v04)));
+ return(u/v + tpi*(__ieee754_j0f(x)*__ieee754_logf(x)));
+}
+
+/* The asymptotic expansions of pzero is
+ * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x.
+ * For x >= 2, We approximate pzero by
+ * pzero(x) = 1 + (R/S)
+ * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10
+ * S = 1 + pS0*s^2 + ... + pS4*s^10
+ * and
+ * | pzero(x)-1-R/S | <= 2 ** ( -60.26)
+ */
+#ifdef __STDC__
+static const float pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static float pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.0000000000e+00, /* 0x00000000 */
+ -7.0312500000e-02, /* 0xbd900000 */
+ -8.0816707611e+00, /* 0xc1014e86 */
+ -2.5706311035e+02, /* 0xc3808814 */
+ -2.4852163086e+03, /* 0xc51b5376 */
+ -5.2530439453e+03, /* 0xc5a4285a */
+};
+#ifdef __STDC__
+static const float pS8[5] = {
+#else
+static float pS8[5] = {
+#endif
+ 1.1653436279e+02, /* 0x42e91198 */
+ 3.8337448730e+03, /* 0x456f9beb */
+ 4.0597855469e+04, /* 0x471e95db */
+ 1.1675296875e+05, /* 0x47e4087c */
+ 4.7627726562e+04, /* 0x473a0bba */
+};
+#ifdef __STDC__
+static const float pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static float pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ -1.1412546255e-11, /* 0xad48c58a */
+ -7.0312492549e-02, /* 0xbd8fffff */
+ -4.1596107483e+00, /* 0xc0851b88 */
+ -6.7674766541e+01, /* 0xc287597b */
+ -3.3123129272e+02, /* 0xc3a59d9b */
+ -3.4643338013e+02, /* 0xc3ad3779 */
+};
+#ifdef __STDC__
+static const float pS5[5] = {
+#else
+static float pS5[5] = {
+#endif
+ 6.0753936768e+01, /* 0x42730408 */
+ 1.0512523193e+03, /* 0x44836813 */
+ 5.9789707031e+03, /* 0x45bad7c4 */
+ 9.6254453125e+03, /* 0x461665c8 */
+ 2.4060581055e+03, /* 0x451660ee */
+};
+
+#ifdef __STDC__
+static const float pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#else
+static float pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ -2.5470459075e-09, /* 0xb12f081b */
+ -7.0311963558e-02, /* 0xbd8fffb8 */
+ -2.4090321064e+00, /* 0xc01a2d95 */
+ -2.1965976715e+01, /* 0xc1afba52 */
+ -5.8079170227e+01, /* 0xc2685112 */
+ -3.1447946548e+01, /* 0xc1fb9565 */
+};
+#ifdef __STDC__
+static const float pS3[5] = {
+#else
+static float pS3[5] = {
+#endif
+ 3.5856033325e+01, /* 0x420f6c94 */
+ 3.6151397705e+02, /* 0x43b4c1ca */
+ 1.1936077881e+03, /* 0x44953373 */
+ 1.1279968262e+03, /* 0x448cffe6 */
+ 1.7358093262e+02, /* 0x432d94b8 */
+};
+
+#ifdef __STDC__
+static const float pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static float pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ -8.8753431271e-08, /* 0xb3be98b7 */
+ -7.0303097367e-02, /* 0xbd8ffb12 */
+ -1.4507384300e+00, /* 0xbfb9b1cc */
+ -7.6356959343e+00, /* 0xc0f4579f */
+ -1.1193166733e+01, /* 0xc1331736 */
+ -3.2336456776e+00, /* 0xc04ef40d */
+};
+#ifdef __STDC__
+static const float pS2[5] = {
+#else
+static float pS2[5] = {
+#endif
+ 2.2220300674e+01, /* 0x41b1c32d */
+ 1.3620678711e+02, /* 0x430834f0 */
+ 2.7047027588e+02, /* 0x43873c32 */
+ 1.5387539673e+02, /* 0x4319e01a */
+ 1.4657617569e+01, /* 0x416a859a */
+};
+
+#ifdef __STDC__
+ static float pzerof(float x)
+#else
+ static float pzerof(x)
+ float x;
+#endif
+{
+#ifdef __STDC__
+ const float *p,*q;
+#else
+ float *p,*q;
+#endif
+ float z,r,s;
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x41000000) {p = pR8; q= pS8;}
+ else if(ix>=0x40f71c58){p = pR5; q= pS5;}
+ else if(ix>=0x4036db68){p = pR3; q= pS3;}
+ else if(ix>=0x40000000){p = pR2; q= pS2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+ return one+ r/s;
+}
+
+
+/* For x >= 8, the asymptotic expansions of qzero is
+ * -1/8 s + 75/1024 s^3 - ..., where s = 1/x.
+ * We approximate pzero by
+ * qzero(x) = s*(-1.25 + (R/S))
+ * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10
+ * S = 1 + qS0*s^2 + ... + qS5*s^12
+ * and
+ * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22)
+ */
+#ifdef __STDC__
+static const float qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static float qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.0000000000e+00, /* 0x00000000 */
+ 7.3242187500e-02, /* 0x3d960000 */
+ 1.1768206596e+01, /* 0x413c4a93 */
+ 5.5767340088e+02, /* 0x440b6b19 */
+ 8.8591972656e+03, /* 0x460a6cca */
+ 3.7014625000e+04, /* 0x471096a0 */
+};
+#ifdef __STDC__
+static const float qS8[6] = {
+#else
+static float qS8[6] = {
+#endif
+ 1.6377603149e+02, /* 0x4323c6aa */
+ 8.0983447266e+03, /* 0x45fd12c2 */
+ 1.4253829688e+05, /* 0x480b3293 */
+ 8.0330925000e+05, /* 0x49441ed4 */
+ 8.4050156250e+05, /* 0x494d3359 */
+ -3.4389928125e+05, /* 0xc8a7eb69 */
+};
+
+#ifdef __STDC__
+static const float qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static float qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ 1.8408595828e-11, /* 0x2da1ec79 */
+ 7.3242180049e-02, /* 0x3d95ffff */
+ 5.8356351852e+00, /* 0x40babd86 */
+ 1.3511157227e+02, /* 0x43071c90 */
+ 1.0272437744e+03, /* 0x448067cd */
+ 1.9899779053e+03, /* 0x44f8bf4b */
+};
+#ifdef __STDC__
+static const float qS5[6] = {
+#else
+static float qS5[6] = {
+#endif
+ 8.2776611328e+01, /* 0x42a58da0 */
+ 2.0778142090e+03, /* 0x4501dd07 */
+ 1.8847289062e+04, /* 0x46933e94 */
+ 5.6751113281e+04, /* 0x475daf1d */
+ 3.5976753906e+04, /* 0x470c88c1 */
+ -5.3543427734e+03, /* 0xc5a752be */
+};
+
+#ifdef __STDC__
+static const float qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#else
+static float qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ 4.3774099900e-09, /* 0x3196681b */
+ 7.3241114616e-02, /* 0x3d95ff70 */
+ 3.3442313671e+00, /* 0x405607e3 */
+ 4.2621845245e+01, /* 0x422a7cc5 */
+ 1.7080809021e+02, /* 0x432acedf */
+ 1.6673394775e+02, /* 0x4326bbe4 */
+};
+#ifdef __STDC__
+static const float qS3[6] = {
+#else
+static float qS3[6] = {
+#endif
+ 4.8758872986e+01, /* 0x42430916 */
+ 7.0968920898e+02, /* 0x44316c1c */
+ 3.7041481934e+03, /* 0x4567825f */
+ 6.4604252930e+03, /* 0x45c9e367 */
+ 2.5163337402e+03, /* 0x451d4557 */
+ -1.4924745178e+02, /* 0xc3153f59 */
+};
+
+#ifdef __STDC__
+static const float qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static float qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ 1.5044444979e-07, /* 0x342189db */
+ 7.3223426938e-02, /* 0x3d95f62a */
+ 1.9981917143e+00, /* 0x3fffc4bf */
+ 1.4495602608e+01, /* 0x4167edfd */
+ 3.1666231155e+01, /* 0x41fd5471 */
+ 1.6252708435e+01, /* 0x4182058c */
+};
+#ifdef __STDC__
+static const float qS2[6] = {
+#else
+static float qS2[6] = {
+#endif
+ 3.0365585327e+01, /* 0x41f2ecb8 */
+ 2.6934811401e+02, /* 0x4386ac8f */
+ 8.4478375244e+02, /* 0x44533229 */
+ 8.8293585205e+02, /* 0x445cbbe5 */
+ 2.1266638184e+02, /* 0x4354aa98 */
+ -5.3109550476e+00, /* 0xc0a9f358 */
+};
+
+#ifdef __STDC__
+ static float qzerof(float x)
+#else
+ static float qzerof(x)
+ float x;
+#endif
+{
+#ifdef __STDC__
+ const float *p,*q;
+#else
+ float *p,*q;
+#endif
+ float s,r,z;
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x41000000) {p = qR8; q= qS8;}
+ else if(ix>=0x40f71c58){p = qR5; q= qS5;}
+ else if(ix>=0x4036db68){p = qR3; q= qS3;}
+ else if(ix>=0x40000000){p = qR2; q= qS2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+ return (-(float).125 + r/s)/x;
+}
diff --git a/lib/msun/src/e_j1.c b/lib/msun/src/e_j1.c
new file mode 100644
index 0000000..6d60a785
--- /dev/null
+++ b/lib/msun/src/e_j1.c
@@ -0,0 +1,486 @@
+/* @(#)e_j1.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_j1(x), __ieee754_y1(x)
+ * Bessel function of the first and second kinds of order zero.
+ * Method -- j1(x):
+ * 1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ...
+ * 2. Reduce x to |x| since j1(x)=-j1(-x), and
+ * for x in (0,2)
+ * j1(x) = x/2 + x*z*R0/S0, where z = x*x;
+ * (precision: |j1/x - 1/2 - R0/S0 |<2**-61.51 )
+ * for x in (2,inf)
+ * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1))
+ * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
+ * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
+ * as follow:
+ * cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = -1/sqrt(2) * (sin(x) + cos(x))
+ * (To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.)
+ *
+ * 3 Special cases
+ * j1(nan)= nan
+ * j1(0) = 0
+ * j1(inf) = 0
+ *
+ * Method -- y1(x):
+ * 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN
+ * 2. For x<2.
+ * Since
+ * y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...)
+ * therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function.
+ * We use the following function to approximate y1,
+ * y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2
+ * where for x in [0,2] (abs err less than 2**-65.89)
+ * U(z) = U0[0] + U0[1]*z + ... + U0[4]*z^4
+ * V(z) = 1 + v0[0]*z + ... + v0[4]*z^5
+ * Note: For tiny x, 1/x dominate y1 and hence
+ * y1(tiny) = -2/pi/tiny, (choose tiny<2**-54)
+ * 3. For x>=2.
+ * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
+ * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
+ * by method mentioned above.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static double pone(double), qone(double);
+#else
+static double pone(), qone();
+#endif
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+huge = 1e300,
+one = 1.0,
+invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+ /* R0/S0 on [0,2] */
+r00 = -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */
+r01 = 1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */
+r02 = -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */
+r03 = 4.96727999609584448412e-08, /* 0x3E6AAAFA, 0x46CA0BD9 */
+s01 = 1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */
+s02 = 1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */
+s03 = 1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */
+s04 = 5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */
+s05 = 1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_j1(double x)
+#else
+ double __ieee754_j1(x)
+ double x;
+#endif
+{
+ double z, s,c,ss,cc,r,u,v,y;
+ int32_t hx,ix;
+
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) return one/x;
+ y = fabs(x);
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ s = sin(y);
+ c = cos(y);
+ ss = -s-c;
+ cc = s-c;
+ if(ix<0x7fe00000) { /* make sure y+y not overflow */
+ z = cos(y+y);
+ if ((s*c)>zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /*
+ * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
+ * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
+ */
+ if(ix>0x48000000) z = (invsqrtpi*cc)/sqrt(y);
+ else {
+ u = pone(y); v = qone(y);
+ z = invsqrtpi*(u*cc-v*ss)/sqrt(y);
+ }
+ if(hx<0) return -z;
+ else return z;
+ }
+ if(ix<0x3e400000) { /* |x|<2**-27 */
+ if(huge+x>one) return 0.5*x;/* inexact if x!=0 necessary */
+ }
+ z = x*x;
+ r = z*(r00+z*(r01+z*(r02+z*r03)));
+ s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
+ r *= x;
+ return(x*0.5+r/s);
+}
+
+#ifdef __STDC__
+static const double U0[5] = {
+#else
+static double U0[5] = {
+#endif
+ -1.96057090646238940668e-01, /* 0xBFC91866, 0x143CBC8A */
+ 5.04438716639811282616e-02, /* 0x3FA9D3C7, 0x76292CD1 */
+ -1.91256895875763547298e-03, /* 0xBF5F55E5, 0x4844F50F */
+ 2.35252600561610495928e-05, /* 0x3EF8AB03, 0x8FA6B88E */
+ -9.19099158039878874504e-08, /* 0xBE78AC00, 0x569105B8 */
+};
+#ifdef __STDC__
+static const double V0[5] = {
+#else
+static double V0[5] = {
+#endif
+ 1.99167318236649903973e-02, /* 0x3F94650D, 0x3F4DA9F0 */
+ 2.02552581025135171496e-04, /* 0x3F2A8C89, 0x6C257764 */
+ 1.35608801097516229404e-06, /* 0x3EB6C05A, 0x894E8CA6 */
+ 6.22741452364621501295e-09, /* 0x3E3ABF1D, 0x5BA69A86 */
+ 1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */
+};
+
+#ifdef __STDC__
+ double __ieee754_y1(double x)
+#else
+ double __ieee754_y1(x)
+ double x;
+#endif
+{
+ double z, s,c,ss,cc,u,v;
+ int32_t hx,ix,lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+ ix = 0x7fffffff&hx;
+ /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
+ if(ix>=0x7ff00000) return one/(x+x*x);
+ if((ix|lx)==0) return -one/zero;
+ if(hx<0) return zero/zero;
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ s = sin(x);
+ c = cos(x);
+ ss = -s-c;
+ cc = s-c;
+ if(ix<0x7fe00000) { /* make sure x+x not overflow */
+ z = cos(x+x);
+ if ((s*c)>zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0))
+ * where x0 = x-3pi/4
+ * Better formula:
+ * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = -1/sqrt(2) * (cos(x) + sin(x))
+ * To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.
+ */
+ if(ix>0x48000000) z = (invsqrtpi*ss)/sqrt(x);
+ else {
+ u = pone(x); v = qone(x);
+ z = invsqrtpi*(u*ss+v*cc)/sqrt(x);
+ }
+ return z;
+ }
+ if(ix<=0x3c900000) { /* x < 2**-54 */
+ return(-tpi/x);
+ }
+ z = x*x;
+ u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
+ v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
+ return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x));
+}
+
+/* For x >= 8, the asymptotic expansions of pone is
+ * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x.
+ * We approximate pone by
+ * pone(x) = 1 + (R/S)
+ * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10
+ * S = 1 + ps0*s^2 + ... + ps4*s^10
+ * and
+ * | pone(x)-1-R/S | <= 2 ** ( -60.06)
+ */
+
+#ifdef __STDC__
+static const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+ 1.17187499999988647970e-01, /* 0x3FBDFFFF, 0xFFFFFCCE */
+ 1.32394806593073575129e+01, /* 0x402A7A9D, 0x357F7FCE */
+ 4.12051854307378562225e+02, /* 0x4079C0D4, 0x652EA590 */
+ 3.87474538913960532227e+03, /* 0x40AE457D, 0xA3A532CC */
+ 7.91447954031891731574e+03, /* 0x40BEEA7A, 0xC32782DD */
+};
+#ifdef __STDC__
+static const double ps8[5] = {
+#else
+static double ps8[5] = {
+#endif
+ 1.14207370375678408436e+02, /* 0x405C8D45, 0x8E656CAC */
+ 3.65093083420853463394e+03, /* 0x40AC85DC, 0x964D274F */
+ 3.69562060269033463555e+04, /* 0x40E20B86, 0x97C5BB7F */
+ 9.76027935934950801311e+04, /* 0x40F7D42C, 0xB28F17BB */
+ 3.08042720627888811578e+04, /* 0x40DE1511, 0x697A0B2D */
+};
+
+#ifdef __STDC__
+static const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ 1.31990519556243522749e-11, /* 0x3DAD0667, 0xDAE1CA7D */
+ 1.17187493190614097638e-01, /* 0x3FBDFFFF, 0xE2C10043 */
+ 6.80275127868432871736e+00, /* 0x401B3604, 0x6E6315E3 */
+ 1.08308182990189109773e+02, /* 0x405B13B9, 0x452602ED */
+ 5.17636139533199752805e+02, /* 0x40802D16, 0xD052D649 */
+ 5.28715201363337541807e+02, /* 0x408085B8, 0xBB7E0CB7 */
+};
+#ifdef __STDC__
+static const double ps5[5] = {
+#else
+static double ps5[5] = {
+#endif
+ 5.92805987221131331921e+01, /* 0x404DA3EA, 0xA8AF633D */
+ 9.91401418733614377743e+02, /* 0x408EFB36, 0x1B066701 */
+ 5.35326695291487976647e+03, /* 0x40B4E944, 0x5706B6FB */
+ 7.84469031749551231769e+03, /* 0x40BEA4B0, 0xB8A5BB15 */
+ 1.50404688810361062679e+03, /* 0x40978030, 0x036F5E51 */
+};
+
+#ifdef __STDC__
+static const double pr3[6] = {
+#else
+static double pr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ 3.02503916137373618024e-09, /* 0x3E29FC21, 0xA7AD9EDD */
+ 1.17186865567253592491e-01, /* 0x3FBDFFF5, 0x5B21D17B */
+ 3.93297750033315640650e+00, /* 0x400F76BC, 0xE85EAD8A */
+ 3.51194035591636932736e+01, /* 0x40418F48, 0x9DA6D129 */
+ 9.10550110750781271918e+01, /* 0x4056C385, 0x4D2C1837 */
+ 4.85590685197364919645e+01, /* 0x4048478F, 0x8EA83EE5 */
+};
+#ifdef __STDC__
+static const double ps3[5] = {
+#else
+static double ps3[5] = {
+#endif
+ 3.47913095001251519989e+01, /* 0x40416549, 0xA134069C */
+ 3.36762458747825746741e+02, /* 0x40750C33, 0x07F1A75F */
+ 1.04687139975775130551e+03, /* 0x40905B7C, 0x5037D523 */
+ 8.90811346398256432622e+02, /* 0x408BD67D, 0xA32E31E9 */
+ 1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */
+};
+
+#ifdef __STDC__
+static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ 1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */
+ 1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */
+ 2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */
+ 1.22426109148261232917e+01, /* 0x40287C37, 0x7F71A964 */
+ 1.76939711271687727390e+01, /* 0x4031B1A8, 0x177F8EE2 */
+ 5.07352312588818499250e+00, /* 0x40144B49, 0xA574C1FE */
+};
+#ifdef __STDC__
+static const double ps2[5] = {
+#else
+static double ps2[5] = {
+#endif
+ 2.14364859363821409488e+01, /* 0x40356FBD, 0x8AD5ECDC */
+ 1.25290227168402751090e+02, /* 0x405F5293, 0x14F92CD5 */
+ 2.32276469057162813669e+02, /* 0x406D08D8, 0xD5A2DBD9 */
+ 1.17679373287147100768e+02, /* 0x405D6B7A, 0xDA1884A9 */
+ 8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */
+};
+
+#ifdef __STDC__
+ static double pone(double x)
+#else
+ static double pone(x)
+ double x;
+#endif
+{
+#ifdef __STDC__
+ const double *p,*q;
+#else
+ double *p,*q;
+#endif
+ double z,r,s;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x40200000) {p = pr8; q= ps8;}
+ else if(ix>=0x40122E8B){p = pr5; q= ps5;}
+ else if(ix>=0x4006DB6D){p = pr3; q= ps3;}
+ else if(ix>=0x40000000){p = pr2; q= ps2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+ return one+ r/s;
+}
+
+
+/* For x >= 8, the asymptotic expansions of qone is
+ * 3/8 s - 105/1024 s^3 - ..., where s = 1/x.
+ * We approximate pone by
+ * qone(x) = s*(0.375 + (R/S))
+ * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10
+ * S = 1 + qs1*s^2 + ... + qs6*s^12
+ * and
+ * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13)
+ */
+
+#ifdef __STDC__
+static const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+ -1.02539062499992714161e-01, /* 0xBFBA3FFF, 0xFFFFFDF3 */
+ -1.62717534544589987888e+01, /* 0xC0304591, 0xA26779F7 */
+ -7.59601722513950107896e+02, /* 0xC087BCD0, 0x53E4B576 */
+ -1.18498066702429587167e+04, /* 0xC0C724E7, 0x40F87415 */
+ -4.84385124285750353010e+04, /* 0xC0E7A6D0, 0x65D09C6A */
+};
+#ifdef __STDC__
+static const double qs8[6] = {
+#else
+static double qs8[6] = {
+#endif
+ 1.61395369700722909556e+02, /* 0x40642CA6, 0xDE5BCDE5 */
+ 7.82538599923348465381e+03, /* 0x40BE9162, 0xD0D88419 */
+ 1.33875336287249578163e+05, /* 0x4100579A, 0xB0B75E98 */
+ 7.19657723683240939863e+05, /* 0x4125F653, 0x72869C19 */
+ 6.66601232617776375264e+05, /* 0x412457D2, 0x7719AD5C */
+ -2.94490264303834643215e+05, /* 0xC111F969, 0x0EA5AA18 */
+};
+
+#ifdef __STDC__
+static const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ -2.08979931141764104297e-11, /* 0xBDB6FA43, 0x1AA1A098 */
+ -1.02539050241375426231e-01, /* 0xBFBA3FFF, 0xCB597FEF */
+ -8.05644828123936029840e+00, /* 0xC0201CE6, 0xCA03AD4B */
+ -1.83669607474888380239e+02, /* 0xC066F56D, 0x6CA7B9B0 */
+ -1.37319376065508163265e+03, /* 0xC09574C6, 0x6931734F */
+ -2.61244440453215656817e+03, /* 0xC0A468E3, 0x88FDA79D */
+};
+#ifdef __STDC__
+static const double qs5[6] = {
+#else
+static double qs5[6] = {
+#endif
+ 8.12765501384335777857e+01, /* 0x405451B2, 0xFF5A11B2 */
+ 1.99179873460485964642e+03, /* 0x409F1F31, 0xE77BF839 */
+ 1.74684851924908907677e+04, /* 0x40D10F1F, 0x0D64CE29 */
+ 4.98514270910352279316e+04, /* 0x40E8576D, 0xAABAD197 */
+ 2.79480751638918118260e+04, /* 0x40DB4B04, 0xCF7C364B */
+ -4.71918354795128470869e+03, /* 0xC0B26F2E, 0xFCFFA004 */
+};
+
+#ifdef __STDC__
+static const double qr3[6] = {
+#else
+static double qr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ -5.07831226461766561369e-09, /* 0xBE35CFA9, 0xD38FC84F */
+ -1.02537829820837089745e-01, /* 0xBFBA3FEB, 0x51AEED54 */
+ -4.61011581139473403113e+00, /* 0xC01270C2, 0x3302D9FF */
+ -5.78472216562783643212e+01, /* 0xC04CEC71, 0xC25D16DA */
+ -2.28244540737631695038e+02, /* 0xC06C87D3, 0x4718D55F */
+ -2.19210128478909325622e+02, /* 0xC06B66B9, 0x5F5C1BF6 */
+};
+#ifdef __STDC__
+static const double qs3[6] = {
+#else
+static double qs3[6] = {
+#endif
+ 4.76651550323729509273e+01, /* 0x4047D523, 0xCCD367E4 */
+ 6.73865112676699709482e+02, /* 0x40850EEB, 0xC031EE3E */
+ 3.38015286679526343505e+03, /* 0x40AA684E, 0x448E7C9A */
+ 5.54772909720722782367e+03, /* 0x40B5ABBA, 0xA61D54A6 */
+ 1.90311919338810798763e+03, /* 0x409DBC7A, 0x0DD4DF4B */
+ -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */
+};
+
+#ifdef __STDC__
+static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */
+ -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */
+ -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */
+ -1.96636162643703720221e+01, /* 0xC033A9E2, 0xC168907F */
+ -4.23253133372830490089e+01, /* 0xC04529A3, 0xDE104AAA */
+ -2.13719211703704061733e+01, /* 0xC0355F36, 0x39CF6E52 */
+};
+#ifdef __STDC__
+static const double qs2[6] = {
+#else
+static double qs2[6] = {
+#endif
+ 2.95333629060523854548e+01, /* 0x403D888A, 0x78AE64FF */
+ 2.52981549982190529136e+02, /* 0x406F9F68, 0xDB821CBA */
+ 7.57502834868645436472e+02, /* 0x4087AC05, 0xCE49A0F7 */
+ 7.39393205320467245656e+02, /* 0x40871B25, 0x48D4C029 */
+ 1.55949003336666123687e+02, /* 0x40637E5E, 0x3C3ED8D4 */
+ -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */
+};
+
+#ifdef __STDC__
+ static double qone(double x)
+#else
+ static double qone(x)
+ double x;
+#endif
+{
+#ifdef __STDC__
+ const double *p,*q;
+#else
+ double *p,*q;
+#endif
+ double s,r,z;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x40200000) {p = qr8; q= qs8;}
+ else if(ix>=0x40122E8B){p = qr5; q= qs5;}
+ else if(ix>=0x4006DB6D){p = qr3; q= qs3;}
+ else if(ix>=0x40000000){p = qr2; q= qs2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+ return (.375 + r/s)/x;
+}
diff --git a/lib/msun/src/e_j1f.c b/lib/msun/src/e_j1f.c
new file mode 100644
index 0000000..2d4b93a
--- /dev/null
+++ b/lib/msun/src/e_j1f.c
@@ -0,0 +1,444 @@
+/* e_j1f.c -- float version of e_j1.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static float ponef(float), qonef(float);
+#else
+static float ponef(), qonef();
+#endif
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+huge = 1e30,
+one = 1.0,
+invsqrtpi= 5.6418961287e-01, /* 0x3f106ebb */
+tpi = 6.3661974669e-01, /* 0x3f22f983 */
+ /* R0/S0 on [0,2] */
+r00 = -6.2500000000e-02, /* 0xbd800000 */
+r01 = 1.4070566976e-03, /* 0x3ab86cfd */
+r02 = -1.5995563444e-05, /* 0xb7862e36 */
+r03 = 4.9672799207e-08, /* 0x335557d2 */
+s01 = 1.9153760746e-02, /* 0x3c9ce859 */
+s02 = 1.8594678841e-04, /* 0x3942fab6 */
+s03 = 1.1771846857e-06, /* 0x359dffc2 */
+s04 = 5.0463624390e-09, /* 0x31ad6446 */
+s05 = 1.2354227016e-11; /* 0x2d59567e */
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_j1f(float x)
+#else
+ float __ieee754_j1f(x)
+ float x;
+#endif
+{
+ float z, s,c,ss,cc,r,u,v,y;
+ int32_t hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7f800000) return one/x;
+ y = fabsf(x);
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ s = sinf(y);
+ c = cosf(y);
+ ss = -s-c;
+ cc = s-c;
+ if(ix<0x7f000000) { /* make sure y+y not overflow */
+ z = cosf(y+y);
+ if ((s*c)>zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /*
+ * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
+ * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
+ */
+ if(ix>0x80000000) z = (invsqrtpi*cc)/sqrtf(y);
+ else {
+ u = ponef(y); v = qonef(y);
+ z = invsqrtpi*(u*cc-v*ss)/sqrtf(y);
+ }
+ if(hx<0) return -z;
+ else return z;
+ }
+ if(ix<0x32000000) { /* |x|<2**-27 */
+ if(huge+x>one) return (float)0.5*x;/* inexact if x!=0 necessary */
+ }
+ z = x*x;
+ r = z*(r00+z*(r01+z*(r02+z*r03)));
+ s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
+ r *= x;
+ return(x*(float)0.5+r/s);
+}
+
+#ifdef __STDC__
+static const float U0[5] = {
+#else
+static float U0[5] = {
+#endif
+ -1.9605709612e-01, /* 0xbe48c331 */
+ 5.0443872809e-02, /* 0x3d4e9e3c */
+ -1.9125689287e-03, /* 0xbafaaf2a */
+ 2.3525259166e-05, /* 0x37c5581c */
+ -9.1909917899e-08, /* 0xb3c56003 */
+};
+#ifdef __STDC__
+static const float V0[5] = {
+#else
+static float V0[5] = {
+#endif
+ 1.9916731864e-02, /* 0x3ca3286a */
+ 2.0255257550e-04, /* 0x3954644b */
+ 1.3560879779e-06, /* 0x35b602d4 */
+ 6.2274145840e-09, /* 0x31d5f8eb */
+ 1.6655924903e-11, /* 0x2d9281cf */
+};
+
+#ifdef __STDC__
+ float __ieee754_y1f(float x)
+#else
+ float __ieee754_y1f(x)
+ float x;
+#endif
+{
+ float z, s,c,ss,cc,u,v;
+ int32_t hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = 0x7fffffff&hx;
+ /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
+ if(ix>=0x7f800000) return one/(x+x*x);
+ if(ix==0) return -one/zero;
+ if(hx<0) return zero/zero;
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ s = sinf(x);
+ c = cosf(x);
+ ss = -s-c;
+ cc = s-c;
+ if(ix<0x7f000000) { /* make sure x+x not overflow */
+ z = cosf(x+x);
+ if ((s*c)>zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0))
+ * where x0 = x-3pi/4
+ * Better formula:
+ * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = -1/sqrt(2) * (cos(x) + sin(x))
+ * To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.
+ */
+ if(ix>0x48000000) z = (invsqrtpi*ss)/sqrtf(x);
+ else {
+ u = ponef(x); v = qonef(x);
+ z = invsqrtpi*(u*ss+v*cc)/sqrtf(x);
+ }
+ return z;
+ }
+ if(ix<=0x24800000) { /* x < 2**-54 */
+ return(-tpi/x);
+ }
+ z = x*x;
+ u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
+ v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
+ return(x*(u/v) + tpi*(__ieee754_j1f(x)*__ieee754_logf(x)-one/x));
+}
+
+/* For x >= 8, the asymptotic expansions of pone is
+ * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x.
+ * We approximate pone by
+ * pone(x) = 1 + (R/S)
+ * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10
+ * S = 1 + ps0*s^2 + ... + ps4*s^10
+ * and
+ * | pone(x)-1-R/S | <= 2 ** ( -60.06)
+ */
+
+#ifdef __STDC__
+static const float pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static float pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.0000000000e+00, /* 0x00000000 */
+ 1.1718750000e-01, /* 0x3df00000 */
+ 1.3239480972e+01, /* 0x4153d4ea */
+ 4.1205184937e+02, /* 0x43ce06a3 */
+ 3.8747453613e+03, /* 0x45722bed */
+ 7.9144794922e+03, /* 0x45f753d6 */
+};
+#ifdef __STDC__
+static const float ps8[5] = {
+#else
+static float ps8[5] = {
+#endif
+ 1.1420736694e+02, /* 0x42e46a2c */
+ 3.6509309082e+03, /* 0x45642ee5 */
+ 3.6956207031e+04, /* 0x47105c35 */
+ 9.7602796875e+04, /* 0x47bea166 */
+ 3.0804271484e+04, /* 0x46f0a88b */
+};
+
+#ifdef __STDC__
+static const float pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static float pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ 1.3199052094e-11, /* 0x2d68333f */
+ 1.1718749255e-01, /* 0x3defffff */
+ 6.8027510643e+00, /* 0x40d9b023 */
+ 1.0830818176e+02, /* 0x42d89dca */
+ 5.1763616943e+02, /* 0x440168b7 */
+ 5.2871520996e+02, /* 0x44042dc6 */
+};
+#ifdef __STDC__
+static const float ps5[5] = {
+#else
+static float ps5[5] = {
+#endif
+ 5.9280597687e+01, /* 0x426d1f55 */
+ 9.9140142822e+02, /* 0x4477d9b1 */
+ 5.3532670898e+03, /* 0x45a74a23 */
+ 7.8446904297e+03, /* 0x45f52586 */
+ 1.5040468750e+03, /* 0x44bc0180 */
+};
+
+#ifdef __STDC__
+static const float pr3[6] = {
+#else
+static float pr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ 3.0250391081e-09, /* 0x314fe10d */
+ 1.1718686670e-01, /* 0x3defffab */
+ 3.9329774380e+00, /* 0x407bb5e7 */
+ 3.5119403839e+01, /* 0x420c7a45 */
+ 9.1055007935e+01, /* 0x42b61c2a */
+ 4.8559066772e+01, /* 0x42423c7c */
+};
+#ifdef __STDC__
+static const float ps3[5] = {
+#else
+static float ps3[5] = {
+#endif
+ 3.4791309357e+01, /* 0x420b2a4d */
+ 3.3676245117e+02, /* 0x43a86198 */
+ 1.0468714600e+03, /* 0x4482dbe3 */
+ 8.9081134033e+02, /* 0x445eb3ed */
+ 1.0378793335e+02, /* 0x42cf936c */
+};
+
+#ifdef __STDC__
+static const float pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static float pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ 1.0771083225e-07, /* 0x33e74ea8 */
+ 1.1717621982e-01, /* 0x3deffa16 */
+ 2.3685150146e+00, /* 0x401795c0 */
+ 1.2242610931e+01, /* 0x4143e1bc */
+ 1.7693971634e+01, /* 0x418d8d41 */
+ 5.0735230446e+00, /* 0x40a25a4d */
+};
+#ifdef __STDC__
+static const float ps2[5] = {
+#else
+static float ps2[5] = {
+#endif
+ 2.1436485291e+01, /* 0x41ab7dec */
+ 1.2529022980e+02, /* 0x42fa9499 */
+ 2.3227647400e+02, /* 0x436846c7 */
+ 1.1767937469e+02, /* 0x42eb5bd7 */
+ 8.3646392822e+00, /* 0x4105d590 */
+};
+
+#ifdef __STDC__
+ static float ponef(float x)
+#else
+ static float ponef(x)
+ float x;
+#endif
+{
+#ifdef __STDC__
+ const float *p,*q;
+#else
+ float *p,*q;
+#endif
+ float z,r,s;
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x41000000) {p = pr8; q= ps8;}
+ else if(ix>=0x40f71c58){p = pr5; q= ps5;}
+ else if(ix>=0x4036db68){p = pr3; q= ps3;}
+ else if(ix>=0x40000000){p = pr2; q= ps2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+ return one+ r/s;
+}
+
+
+/* For x >= 8, the asymptotic expansions of qone is
+ * 3/8 s - 105/1024 s^3 - ..., where s = 1/x.
+ * We approximate pone by
+ * qone(x) = s*(0.375 + (R/S))
+ * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10
+ * S = 1 + qs1*s^2 + ... + qs6*s^12
+ * and
+ * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13)
+ */
+
+#ifdef __STDC__
+static const float qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static float qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.0000000000e+00, /* 0x00000000 */
+ -1.0253906250e-01, /* 0xbdd20000 */
+ -1.6271753311e+01, /* 0xc1822c8d */
+ -7.5960174561e+02, /* 0xc43de683 */
+ -1.1849806641e+04, /* 0xc639273a */
+ -4.8438511719e+04, /* 0xc73d3683 */
+};
+#ifdef __STDC__
+static const float qs8[6] = {
+#else
+static float qs8[6] = {
+#endif
+ 1.6139537048e+02, /* 0x43216537 */
+ 7.8253862305e+03, /* 0x45f48b17 */
+ 1.3387534375e+05, /* 0x4802bcd6 */
+ 7.1965775000e+05, /* 0x492fb29c */
+ 6.6660125000e+05, /* 0x4922be94 */
+ -2.9449025000e+05, /* 0xc88fcb48 */
+};
+
+#ifdef __STDC__
+static const float qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static float qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ -2.0897993405e-11, /* 0xadb7d219 */
+ -1.0253904760e-01, /* 0xbdd1fffe */
+ -8.0564479828e+00, /* 0xc100e736 */
+ -1.8366960144e+02, /* 0xc337ab6b */
+ -1.3731937256e+03, /* 0xc4aba633 */
+ -2.6124443359e+03, /* 0xc523471c */
+};
+#ifdef __STDC__
+static const float qs5[6] = {
+#else
+static float qs5[6] = {
+#endif
+ 8.1276550293e+01, /* 0x42a28d98 */
+ 1.9917987061e+03, /* 0x44f8f98f */
+ 1.7468484375e+04, /* 0x468878f8 */
+ 4.9851425781e+04, /* 0x4742bb6d */
+ 2.7948074219e+04, /* 0x46da5826 */
+ -4.7191835938e+03, /* 0xc5937978 */
+};
+
+#ifdef __STDC__
+static const float qr3[6] = {
+#else
+static float qr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ -5.0783124372e-09, /* 0xb1ae7d4f */
+ -1.0253783315e-01, /* 0xbdd1ff5b */
+ -4.6101160049e+00, /* 0xc0938612 */
+ -5.7847221375e+01, /* 0xc267638e */
+ -2.2824453735e+02, /* 0xc3643e9a */
+ -2.1921012878e+02, /* 0xc35b35cb */
+};
+#ifdef __STDC__
+static const float qs3[6] = {
+#else
+static float qs3[6] = {
+#endif
+ 4.7665153503e+01, /* 0x423ea91e */
+ 6.7386511230e+02, /* 0x4428775e */
+ 3.3801528320e+03, /* 0x45534272 */
+ 5.5477290039e+03, /* 0x45ad5dd5 */
+ 1.9031191406e+03, /* 0x44ede3d0 */
+ -1.3520118713e+02, /* 0xc3073381 */
+};
+
+#ifdef __STDC__
+static const float qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static float qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ -1.7838172539e-07, /* 0xb43f8932 */
+ -1.0251704603e-01, /* 0xbdd1f475 */
+ -2.7522056103e+00, /* 0xc0302423 */
+ -1.9663616180e+01, /* 0xc19d4f16 */
+ -4.2325313568e+01, /* 0xc2294d1f */
+ -2.1371921539e+01, /* 0xc1aaf9b2 */
+};
+#ifdef __STDC__
+static const float qs2[6] = {
+#else
+static float qs2[6] = {
+#endif
+ 2.9533363342e+01, /* 0x41ec4454 */
+ 2.5298155212e+02, /* 0x437cfb47 */
+ 7.5750280762e+02, /* 0x443d602e */
+ 7.3939318848e+02, /* 0x4438d92a */
+ 1.5594900513e+02, /* 0x431bf2f2 */
+ -4.9594988823e+00, /* 0xc09eb437 */
+};
+
+#ifdef __STDC__
+ static float qonef(float x)
+#else
+ static float qonef(x)
+ float x;
+#endif
+{
+#ifdef __STDC__
+ const float *p,*q;
+#else
+ float *p,*q;
+#endif
+ float s,r,z;
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x40200000) {p = qr8; q= qs8;}
+ else if(ix>=0x40f71c58){p = qr5; q= qs5;}
+ else if(ix>=0x4036db68){p = qr3; q= qs3;}
+ else if(ix>=0x40000000){p = qr2; q= qs2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+ return ((float).375 + r/s)/x;
+}
diff --git a/lib/msun/src/e_jn.c b/lib/msun/src/e_jn.c
new file mode 100644
index 0000000..cfe26e8
--- /dev/null
+++ b/lib/msun/src/e_jn.c
@@ -0,0 +1,281 @@
+/* @(#)e_jn.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * __ieee754_jn(n, x), __ieee754_yn(n, x)
+ * floating point Bessel's function of the 1st and 2nd kind
+ * of order n
+ *
+ * Special cases:
+ * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
+ * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
+ * Note 2. About jn(n,x), yn(n,x)
+ * For n=0, j0(x) is called,
+ * for n=1, j1(x) is called,
+ * for n<x, forward recursion us used starting
+ * from values of j0(x) and j1(x).
+ * for n>x, a continued fraction approximation to
+ * j(n,x)/j(n-1,x) is evaluated and then backward
+ * recursion is used starting from a supposed value
+ * for j(n,x). The resulting value of j(0,x) is
+ * compared with the actual value to correct the
+ * supposed value of j(n,x).
+ *
+ * yn(n,x) is similar in all respects, except
+ * that forward recursion is used for all
+ * values of n>1.
+ *
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
+one = 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */
+
+#ifdef __STDC__
+static const double zero = 0.00000000000000000000e+00;
+#else
+static double zero = 0.00000000000000000000e+00;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_jn(int n, double x)
+#else
+ double __ieee754_jn(n,x)
+ int n; double x;
+#endif
+{
+ int32_t i,hx,ix,lx, sgn;
+ double a, b, temp, di;
+ double z, w;
+
+ /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
+ * Thus, J(-n,x) = J(n,-x)
+ */
+ EXTRACT_WORDS(hx,lx,x);
+ ix = 0x7fffffff&hx;
+ /* if J(n,NaN) is NaN */
+ if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x;
+ if(n<0){
+ n = -n;
+ x = -x;
+ hx ^= 0x80000000;
+ }
+ if(n==0) return(__ieee754_j0(x));
+ if(n==1) return(__ieee754_j1(x));
+ sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */
+ x = fabs(x);
+ if((ix|lx)==0||ix>=0x7ff00000) /* if x is 0 or inf */
+ b = zero;
+ else if((double)n<=x) {
+ /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
+ if(ix>=0x52D00000) { /* x > 2**302 */
+ /* (x >> n**2)
+ * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Let s=sin(x), c=cos(x),
+ * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+ *
+ * n sin(xn)*sqt2 cos(xn)*sqt2
+ * ----------------------------------
+ * 0 s-c c+s
+ * 1 -s-c -c+s
+ * 2 -s+c -c-s
+ * 3 s+c c-s
+ */
+ switch(n&3) {
+ case 0: temp = cos(x)+sin(x); break;
+ case 1: temp = -cos(x)+sin(x); break;
+ case 2: temp = -cos(x)-sin(x); break;
+ case 3: temp = cos(x)-sin(x); break;
+ }
+ b = invsqrtpi*temp/sqrt(x);
+ } else {
+ a = __ieee754_j0(x);
+ b = __ieee754_j1(x);
+ for(i=1;i<n;i++){
+ temp = b;
+ b = b*((double)(i+i)/x) - a; /* avoid underflow */
+ a = temp;
+ }
+ }
+ } else {
+ if(ix<0x3e100000) { /* x < 2**-29 */
+ /* x is tiny, return the first Taylor expansion of J(n,x)
+ * J(n,x) = 1/n!*(x/2)^n - ...
+ */
+ if(n>33) /* underflow */
+ b = zero;
+ else {
+ temp = x*0.5; b = temp;
+ for (a=one,i=2;i<=n;i++) {
+ a *= (double)i; /* a = n! */
+ b *= temp; /* b = (x/2)^n */
+ }
+ b = b/a;
+ }
+ } else {
+ /* use backward recurrence */
+ /* x x^2 x^2
+ * J(n,x)/J(n-1,x) = ---- ------ ------ .....
+ * 2n - 2(n+1) - 2(n+2)
+ *
+ * 1 1 1
+ * (for large x) = ---- ------ ------ .....
+ * 2n 2(n+1) 2(n+2)
+ * -- - ------ - ------ -
+ * x x x
+ *
+ * Let w = 2n/x and h=2/x, then the above quotient
+ * is equal to the continued fraction:
+ * 1
+ * = -----------------------
+ * 1
+ * w - -----------------
+ * 1
+ * w+h - ---------
+ * w+2h - ...
+ *
+ * To determine how many terms needed, let
+ * Q(0) = w, Q(1) = w(w+h) - 1,
+ * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
+ * When Q(k) > 1e4 good for single
+ * When Q(k) > 1e9 good for double
+ * When Q(k) > 1e17 good for quadruple
+ */
+ /* determine k */
+ double t,v;
+ double q0,q1,h,tmp; int32_t k,m;
+ w = (n+n)/(double)x; h = 2.0/(double)x;
+ q0 = w; z = w+h; q1 = w*z - 1.0; k=1;
+ while(q1<1.0e9) {
+ k += 1; z += h;
+ tmp = z*q1 - q0;
+ q0 = q1;
+ q1 = tmp;
+ }
+ m = n+n;
+ for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t);
+ a = t;
+ b = one;
+ /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
+ * Hence, if n*(log(2n/x)) > ...
+ * single 8.8722839355e+01
+ * double 7.09782712893383973096e+02
+ * long double 1.1356523406294143949491931077970765006170e+04
+ * then recurrent value may overflow and the result is
+ * likely underflow to zero
+ */
+ tmp = n;
+ v = two/x;
+ tmp = tmp*__ieee754_log(fabs(v*tmp));
+ if(tmp<7.09782712893383973096e+02) {
+ for(i=n-1,di=(double)(i+i);i>0;i--){
+ temp = b;
+ b *= di;
+ b = b/x - a;
+ a = temp;
+ di -= two;
+ }
+ } else {
+ for(i=n-1,di=(double)(i+i);i>0;i--){
+ temp = b;
+ b *= di;
+ b = b/x - a;
+ a = temp;
+ di -= two;
+ /* scale b to avoid spurious overflow */
+ if(b>1e100) {
+ a /= b;
+ t /= b;
+ b = one;
+ }
+ }
+ }
+ b = (t*__ieee754_j0(x)/b);
+ }
+ }
+ if(sgn==1) return -b; else return b;
+}
+
+#ifdef __STDC__
+ double __ieee754_yn(int n, double x)
+#else
+ double __ieee754_yn(n,x)
+ int n; double x;
+#endif
+{
+ int32_t i,hx,ix,lx;
+ int32_t sign;
+ double a, b, temp;
+
+ EXTRACT_WORDS(hx,lx,x);
+ ix = 0x7fffffff&hx;
+ /* if Y(n,NaN) is NaN */
+ if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x;
+ if((ix|lx)==0) return -one/zero;
+ if(hx<0) return zero/zero;
+ sign = 1;
+ if(n<0){
+ n = -n;
+ sign = 1 - ((n&1)<<1);
+ }
+ if(n==0) return(__ieee754_y0(x));
+ if(n==1) return(sign*__ieee754_y1(x));
+ if(ix==0x7ff00000) return zero;
+ if(ix>=0x52D00000) { /* x > 2**302 */
+ /* (x >> n**2)
+ * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Let s=sin(x), c=cos(x),
+ * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+ *
+ * n sin(xn)*sqt2 cos(xn)*sqt2
+ * ----------------------------------
+ * 0 s-c c+s
+ * 1 -s-c -c+s
+ * 2 -s+c -c-s
+ * 3 s+c c-s
+ */
+ switch(n&3) {
+ case 0: temp = sin(x)-cos(x); break;
+ case 1: temp = -sin(x)-cos(x); break;
+ case 2: temp = -sin(x)+cos(x); break;
+ case 3: temp = sin(x)+cos(x); break;
+ }
+ b = invsqrtpi*temp/sqrt(x);
+ } else {
+ u_int32_t high;
+ a = __ieee754_y0(x);
+ b = __ieee754_y1(x);
+ /* quit if b is -inf */
+ GET_HIGH_WORD(high,b);
+ for(i=1;i<n&&high!=0xfff00000;i++){
+ temp = b;
+ b = ((double)(i+i)/x)*b - a;
+ GET_HIGH_WORD(high,b);
+ a = temp;
+ }
+ }
+ if(sign>0) return b; else return -b;
+}
diff --git a/lib/msun/src/e_jnf.c b/lib/msun/src/e_jnf.c
new file mode 100644
index 0000000..03ed930
--- /dev/null
+++ b/lib/msun/src/e_jnf.c
@@ -0,0 +1,212 @@
+/* e_jnf.c -- float version of e_jn.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+invsqrtpi= 5.6418961287e-01, /* 0x3f106ebb */
+two = 2.0000000000e+00, /* 0x40000000 */
+one = 1.0000000000e+00; /* 0x3F800000 */
+
+#ifdef __STDC__
+static const float zero = 0.0000000000e+00;
+#else
+static float zero = 0.0000000000e+00;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_jnf(int n, float x)
+#else
+ float __ieee754_jnf(n,x)
+ int n; float x;
+#endif
+{
+ int32_t i,hx,ix, sgn;
+ float a, b, temp, di;
+ float z, w;
+
+ /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
+ * Thus, J(-n,x) = J(n,-x)
+ */
+ GET_FLOAT_WORD(hx,x);
+ ix = 0x7fffffff&hx;
+ /* if J(n,NaN) is NaN */
+ if(ix>0x7f800000) return x+x;
+ if(n<0){
+ n = -n;
+ x = -x;
+ hx ^= 0x80000000;
+ }
+ if(n==0) return(__ieee754_j0f(x));
+ if(n==1) return(__ieee754_j1f(x));
+ sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */
+ x = fabsf(x);
+ if(ix==0||ix>=0x7f800000) /* if x is 0 or inf */
+ b = zero;
+ else if((float)n<=x) {
+ /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
+ a = __ieee754_j0f(x);
+ b = __ieee754_j1f(x);
+ for(i=1;i<n;i++){
+ temp = b;
+ b = b*((float)(i+i)/x) - a; /* avoid underflow */
+ a = temp;
+ }
+ } else {
+ if(ix<0x30800000) { /* x < 2**-29 */
+ /* x is tiny, return the first Taylor expansion of J(n,x)
+ * J(n,x) = 1/n!*(x/2)^n - ...
+ */
+ if(n>33) /* underflow */
+ b = zero;
+ else {
+ temp = x*(float)0.5; b = temp;
+ for (a=one,i=2;i<=n;i++) {
+ a *= (float)i; /* a = n! */
+ b *= temp; /* b = (x/2)^n */
+ }
+ b = b/a;
+ }
+ } else {
+ /* use backward recurrence */
+ /* x x^2 x^2
+ * J(n,x)/J(n-1,x) = ---- ------ ------ .....
+ * 2n - 2(n+1) - 2(n+2)
+ *
+ * 1 1 1
+ * (for large x) = ---- ------ ------ .....
+ * 2n 2(n+1) 2(n+2)
+ * -- - ------ - ------ -
+ * x x x
+ *
+ * Let w = 2n/x and h=2/x, then the above quotient
+ * is equal to the continued fraction:
+ * 1
+ * = -----------------------
+ * 1
+ * w - -----------------
+ * 1
+ * w+h - ---------
+ * w+2h - ...
+ *
+ * To determine how many terms needed, let
+ * Q(0) = w, Q(1) = w(w+h) - 1,
+ * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
+ * When Q(k) > 1e4 good for single
+ * When Q(k) > 1e9 good for double
+ * When Q(k) > 1e17 good for quadruple
+ */
+ /* determine k */
+ float t,v;
+ float q0,q1,h,tmp; int32_t k,m;
+ w = (n+n)/(float)x; h = (float)2.0/(float)x;
+ q0 = w; z = w+h; q1 = w*z - (float)1.0; k=1;
+ while(q1<(float)1.0e9) {
+ k += 1; z += h;
+ tmp = z*q1 - q0;
+ q0 = q1;
+ q1 = tmp;
+ }
+ m = n+n;
+ for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t);
+ a = t;
+ b = one;
+ /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
+ * Hence, if n*(log(2n/x)) > ...
+ * single 8.8722839355e+01
+ * double 7.09782712893383973096e+02
+ * long double 1.1356523406294143949491931077970765006170e+04
+ * then recurrent value may overflow and the result is
+ * likely underflow to zero
+ */
+ tmp = n;
+ v = two/x;
+ tmp = tmp*__ieee754_logf(fabsf(v*tmp));
+ if(tmp<(float)8.8721679688e+01) {
+ for(i=n-1,di=(float)(i+i);i>0;i--){
+ temp = b;
+ b *= di;
+ b = b/x - a;
+ a = temp;
+ di -= two;
+ }
+ } else {
+ for(i=n-1,di=(float)(i+i);i>0;i--){
+ temp = b;
+ b *= di;
+ b = b/x - a;
+ a = temp;
+ di -= two;
+ /* scale b to avoid spurious overflow */
+ if(b>(float)1e10) {
+ a /= b;
+ t /= b;
+ b = one;
+ }
+ }
+ }
+ b = (t*__ieee754_j0f(x)/b);
+ }
+ }
+ if(sgn==1) return -b; else return b;
+}
+
+#ifdef __STDC__
+ float __ieee754_ynf(int n, float x)
+#else
+ float __ieee754_ynf(n,x)
+ int n; float x;
+#endif
+{
+ int32_t i,hx,ix,ib;
+ int32_t sign;
+ float a, b, temp;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = 0x7fffffff&hx;
+ /* if Y(n,NaN) is NaN */
+ if(ix>0x7f800000) return x+x;
+ if(ix==0) return -one/zero;
+ if(hx<0) return zero/zero;
+ sign = 1;
+ if(n<0){
+ n = -n;
+ sign = 1 - ((n&1)<<1);
+ }
+ if(n==0) return(__ieee754_y0f(x));
+ if(n==1) return(sign*__ieee754_y1f(x));
+ if(ix==0x7f800000) return zero;
+
+ a = __ieee754_y0f(x);
+ b = __ieee754_y1f(x);
+ /* quit if b is -inf */
+ GET_FLOAT_WORD(ib,b);
+ for(i=1;i<n&&ib!=0xff800000;i++){
+ temp = b;
+ b = ((float)(i+i)/x)*b - a;
+ GET_FLOAT_WORD(ib,b);
+ a = temp;
+ }
+ if(sign>0) return b; else return -b;
+}
diff --git a/lib/msun/src/e_lgamma.c b/lib/msun/src/e_lgamma.c
new file mode 100644
index 0000000..ca25a43
--- /dev/null
+++ b/lib/msun/src/e_lgamma.c
@@ -0,0 +1,36 @@
+/* @(#)e_lgamma.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_lgamma(x)
+ * Return the logarithm of the Gamma function of x.
+ *
+ * Method: call __ieee754_lgamma_r
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+extern int signgam;
+
+#ifdef __STDC__
+ double __ieee754_lgamma(double x)
+#else
+ double __ieee754_lgamma(x)
+ double x;
+#endif
+{
+ return __ieee754_lgamma_r(x,&signgam);
+}
diff --git a/lib/msun/src/e_lgamma_r.c b/lib/msun/src/e_lgamma_r.c
new file mode 100644
index 0000000..a664655
--- /dev/null
+++ b/lib/msun/src/e_lgamma_r.c
@@ -0,0 +1,312 @@
+/* @(#)er_lgamma.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_lgamma_r(x, signgamp)
+ * Reentrant version of the logarithm of the Gamma function
+ * with user provide pointer for the sign of Gamma(x).
+ *
+ * Method:
+ * 1. Argument Reduction for 0 < x <= 8
+ * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may
+ * reduce x to a number in [1.5,2.5] by
+ * lgamma(1+s) = log(s) + lgamma(s)
+ * for example,
+ * lgamma(7.3) = log(6.3) + lgamma(6.3)
+ * = log(6.3*5.3) + lgamma(5.3)
+ * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
+ * 2. Polynomial approximation of lgamma around its
+ * minimun ymin=1.461632144968362245 to maintain monotonicity.
+ * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
+ * Let z = x-ymin;
+ * lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
+ * where
+ * poly(z) is a 14 degree polynomial.
+ * 2. Rational approximation in the primary interval [2,3]
+ * We use the following approximation:
+ * s = x-2.0;
+ * lgamma(x) = 0.5*s + s*P(s)/Q(s)
+ * with accuracy
+ * |P/Q - (lgamma(x)-0.5s)| < 2**-61.71
+ * Our algorithms are based on the following observation
+ *
+ * zeta(2)-1 2 zeta(3)-1 3
+ * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ...
+ * 2 3
+ *
+ * where Euler = 0.5771... is the Euler constant, which is very
+ * close to 0.5.
+ *
+ * 3. For x>=8, we have
+ * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....
+ * (better formula:
+ * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)
+ * Let z = 1/x, then we approximation
+ * f(z) = lgamma(x) - (x-0.5)(log(x)-1)
+ * by
+ * 3 5 11
+ * w = w0 + w1*z + w2*z + w3*z + ... + w6*z
+ * where
+ * |w - f(z)| < 2**-58.74
+ *
+ * 4. For negative x, since (G is gamma function)
+ * -x*G(-x)*G(x) = pi/sin(pi*x),
+ * we have
+ * G(x) = pi/(sin(pi*x)*(-x)*G(-x))
+ * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0
+ * Hence, for x<0, signgam = sign(sin(pi*x)) and
+ * lgamma(x) = log(|Gamma(x)|)
+ * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);
+ * Note: one should avoid compute pi*(-x) directly in the
+ * computation of sin(pi*(-x)).
+ *
+ * 5. Special Cases
+ * lgamma(2+s) ~ s*(1-Euler) for tiny s
+ * lgamma(1)=lgamma(2)=0
+ * lgamma(x) ~ -log(x) for tiny x
+ * lgamma(0) = lgamma(inf) = inf
+ * lgamma(-integer) = +-inf
+ *
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two52= 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
+a0 = 7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */
+a1 = 3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */
+a2 = 6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */
+a3 = 2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */
+a4 = 7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */
+a5 = 2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */
+a6 = 1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */
+a7 = 5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */
+a8 = 2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */
+a9 = 1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */
+a10 = 2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */
+a11 = 4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */
+tc = 1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */
+tf = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */
+/* tt = -(tail of tf) */
+tt = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */
+t0 = 4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */
+t1 = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */
+t2 = 6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */
+t3 = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */
+t4 = 1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */
+t5 = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */
+t6 = 6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */
+t7 = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */
+t8 = 2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */
+t9 = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */
+t10 = 8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */
+t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */
+t12 = 3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */
+t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */
+t14 = 3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */
+u0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
+u1 = 6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */
+u2 = 1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */
+u3 = 9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */
+u4 = 2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */
+u5 = 1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */
+v1 = 2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */
+v2 = 2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */
+v3 = 7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */
+v4 = 1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */
+v5 = 3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */
+s0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
+s1 = 2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */
+s2 = 3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */
+s3 = 1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */
+s4 = 2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */
+s5 = 1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */
+s6 = 3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */
+r1 = 1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */
+r2 = 7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */
+r3 = 1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */
+r4 = 1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */
+r5 = 7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */
+r6 = 7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */
+w0 = 4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */
+w1 = 8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */
+w2 = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */
+w3 = 7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */
+w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */
+w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */
+w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */
+
+#ifdef __STDC__
+static const double zero= 0.00000000000000000000e+00;
+#else
+static double zero= 0.00000000000000000000e+00;
+#endif
+
+#ifdef __STDC__
+ static double sin_pi(double x)
+#else
+ static double sin_pi(x)
+ double x;
+#endif
+{
+ double y,z;
+ int n,ix;
+
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+
+ if(ix<0x3fd00000) return __kernel_sin(pi*x,zero,0);
+ y = -x; /* x is assume negative */
+
+ /*
+ * argument reduction, make sure inexact flag not raised if input
+ * is an integer
+ */
+ z = floor(y);
+ if(z!=y) { /* inexact anyway */
+ y *= 0.5;
+ y = 2.0*(y - floor(y)); /* y = |x| mod 2.0 */
+ n = (int) (y*4.0);
+ } else {
+ if(ix>=0x43400000) {
+ y = zero; n = 0; /* y must be even */
+ } else {
+ if(ix<0x43300000) z = y+two52; /* exact */
+ GET_LOW_WORD(n,z);
+ n &= 1;
+ y = n;
+ n<<= 2;
+ }
+ }
+ switch (n) {
+ case 0: y = __kernel_sin(pi*y,zero,0); break;
+ case 1:
+ case 2: y = __kernel_cos(pi*(0.5-y),zero); break;
+ case 3:
+ case 4: y = __kernel_sin(pi*(one-y),zero,0); break;
+ case 5:
+ case 6: y = -__kernel_cos(pi*(y-1.5),zero); break;
+ default: y = __kernel_sin(pi*(y-2.0),zero,0); break;
+ }
+ return -y;
+}
+
+
+#ifdef __STDC__
+ double __ieee754_lgamma_r(double x, int *signgamp)
+#else
+ double __ieee754_lgamma_r(x,signgamp)
+ double x; int *signgamp;
+#endif
+{
+ double t,y,z,nadj,p,p1,p2,p3,q,r,w;
+ int i,hx,lx,ix;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ /* purge off +-inf, NaN, +-0, and negative arguments */
+ *signgamp = 1;
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) return x*x;
+ if((ix|lx)==0) return one/zero;
+ if(ix<0x3b900000) { /* |x|<2**-70, return -log(|x|) */
+ if(hx<0) {
+ *signgamp = -1;
+ return -__ieee754_log(-x);
+ } else return -__ieee754_log(x);
+ }
+ if(hx<0) {
+ if(ix>=0x43300000) /* |x|>=2**52, must be -integer */
+ return one/zero;
+ t = sin_pi(x);
+ if(t==zero) return one/zero; /* -integer */
+ nadj = __ieee754_log(pi/fabs(t*x));
+ if(t<zero) *signgamp = -1;
+ x = -x;
+ }
+
+ /* purge off 1 and 2 */
+ if((((ix-0x3ff00000)|lx)==0)||(((ix-0x40000000)|lx)==0)) r = 0;
+ /* for x < 2.0 */
+ else if(ix<0x40000000) {
+ if(ix<=0x3feccccc) { /* lgamma(x) = lgamma(x+1)-log(x) */
+ r = -__ieee754_log(x);
+ if(ix>=0x3FE76944) {y = one-x; i= 0;}
+ else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;}
+ else {y = x; i=2;}
+ } else {
+ r = zero;
+ if(ix>=0x3FFBB4C3) {y=2.0-x;i=0;} /* [1.7316,2] */
+ else if(ix>=0x3FF3B4C4) {y=x-tc;i=1;} /* [1.23,1.73] */
+ else {y=x-one;i=2;}
+ }
+ switch(i) {
+ case 0:
+ z = y*y;
+ p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
+ p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
+ p = y*p1+p2;
+ r += (p-0.5*y); break;
+ case 1:
+ z = y*y;
+ w = z*y;
+ p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */
+ p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
+ p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
+ p = z*p1-(tt-w*(p2+y*p3));
+ r += (tf + p); break;
+ case 2:
+ p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
+ p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
+ r += (-0.5*y + p1/p2);
+ }
+ }
+ else if(ix<0x40200000) { /* x < 8.0 */
+ i = (int)x;
+ t = zero;
+ y = x-(double)i;
+ p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
+ q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
+ r = half*y+p/q;
+ z = one; /* lgamma(1+s) = log(s) + lgamma(s) */
+ switch(i) {
+ case 7: z *= (y+6.0); /* FALLTHRU */
+ case 6: z *= (y+5.0); /* FALLTHRU */
+ case 5: z *= (y+4.0); /* FALLTHRU */
+ case 4: z *= (y+3.0); /* FALLTHRU */
+ case 3: z *= (y+2.0); /* FALLTHRU */
+ r += __ieee754_log(z); break;
+ }
+ /* 8.0 <= x < 2**58 */
+ } else if (ix < 0x43900000) {
+ t = __ieee754_log(x);
+ z = one/x;
+ y = z*z;
+ w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
+ r = (x-half)*(t-one)+w;
+ } else
+ /* 2**58 <= x <= inf */
+ r = x*(__ieee754_log(x)-one);
+ if(hx<0) r = nadj - r;
+ return r;
+}
diff --git a/lib/msun/src/e_lgammaf.c b/lib/msun/src/e_lgammaf.c
new file mode 100644
index 0000000..dde3f95
--- /dev/null
+++ b/lib/msun/src/e_lgammaf.c
@@ -0,0 +1,39 @@
+/* e_lgammaf.c -- float version of e_lgamma.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_lgammaf(x)
+ * Return the logarithm of the Gamma function of x.
+ *
+ * Method: call __ieee754_lgammaf_r
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+extern int signgam;
+
+#ifdef __STDC__
+ float __ieee754_lgammaf(float x)
+#else
+ float __ieee754_lgammaf(x)
+ float x;
+#endif
+{
+ return __ieee754_lgammaf_r(x,&signgam);
+}
diff --git a/lib/msun/src/e_lgammaf_r.c b/lib/msun/src/e_lgammaf_r.c
new file mode 100644
index 0000000..0e57888
--- /dev/null
+++ b/lib/msun/src/e_lgammaf_r.c
@@ -0,0 +1,248 @@
+/* e_lgammaf_r.c -- float version of e_lgamma_r.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+two23= 8.3886080000e+06, /* 0x4b000000 */
+half= 5.0000000000e-01, /* 0x3f000000 */
+one = 1.0000000000e+00, /* 0x3f800000 */
+pi = 3.1415927410e+00, /* 0x40490fdb */
+a0 = 7.7215664089e-02, /* 0x3d9e233f */
+a1 = 3.2246702909e-01, /* 0x3ea51a66 */
+a2 = 6.7352302372e-02, /* 0x3d89f001 */
+a3 = 2.0580807701e-02, /* 0x3ca89915 */
+a4 = 7.3855509982e-03, /* 0x3bf2027e */
+a5 = 2.8905137442e-03, /* 0x3b3d6ec6 */
+a6 = 1.1927076848e-03, /* 0x3a9c54a1 */
+a7 = 5.1006977446e-04, /* 0x3a05b634 */
+a8 = 2.2086278477e-04, /* 0x39679767 */
+a9 = 1.0801156895e-04, /* 0x38e28445 */
+a10 = 2.5214456400e-05, /* 0x37d383a2 */
+a11 = 4.4864096708e-05, /* 0x383c2c75 */
+tc = 1.4616321325e+00, /* 0x3fbb16c3 */
+tf = -1.2148628384e-01, /* 0xbdf8cdcd */
+/* tt = -(tail of tf) */
+tt = 6.6971006518e-09, /* 0x31e61c52 */
+t0 = 4.8383611441e-01, /* 0x3ef7b95e */
+t1 = -1.4758771658e-01, /* 0xbe17213c */
+t2 = 6.4624942839e-02, /* 0x3d845a15 */
+t3 = -3.2788541168e-02, /* 0xbd064d47 */
+t4 = 1.7970675603e-02, /* 0x3c93373d */
+t5 = -1.0314224288e-02, /* 0xbc28fcfe */
+t6 = 6.1005386524e-03, /* 0x3bc7e707 */
+t7 = -3.6845202558e-03, /* 0xbb7177fe */
+t8 = 2.2596477065e-03, /* 0x3b141699 */
+t9 = -1.4034647029e-03, /* 0xbab7f476 */
+t10 = 8.8108185446e-04, /* 0x3a66f867 */
+t11 = -5.3859531181e-04, /* 0xba0d3085 */
+t12 = 3.1563205994e-04, /* 0x39a57b6b */
+t13 = -3.1275415677e-04, /* 0xb9a3f927 */
+t14 = 3.3552918467e-04, /* 0x39afe9f7 */
+u0 = -7.7215664089e-02, /* 0xbd9e233f */
+u1 = 6.3282704353e-01, /* 0x3f2200f4 */
+u2 = 1.4549225569e+00, /* 0x3fba3ae7 */
+u3 = 9.7771751881e-01, /* 0x3f7a4bb2 */
+u4 = 2.2896373272e-01, /* 0x3e6a7578 */
+u5 = 1.3381091878e-02, /* 0x3c5b3c5e */
+v1 = 2.4559779167e+00, /* 0x401d2ebe */
+v2 = 2.1284897327e+00, /* 0x4008392d */
+v3 = 7.6928514242e-01, /* 0x3f44efdf */
+v4 = 1.0422264785e-01, /* 0x3dd572af */
+v5 = 3.2170924824e-03, /* 0x3b52d5db */
+s0 = -7.7215664089e-02, /* 0xbd9e233f */
+s1 = 2.1498242021e-01, /* 0x3e5c245a */
+s2 = 3.2577878237e-01, /* 0x3ea6cc7a */
+s3 = 1.4635047317e-01, /* 0x3e15dce6 */
+s4 = 2.6642270386e-02, /* 0x3cda40e4 */
+s5 = 1.8402845599e-03, /* 0x3af135b4 */
+s6 = 3.1947532989e-05, /* 0x3805ff67 */
+r1 = 1.3920053244e+00, /* 0x3fb22d3b */
+r2 = 7.2193557024e-01, /* 0x3f38d0c5 */
+r3 = 1.7193385959e-01, /* 0x3e300f6e */
+r4 = 1.8645919859e-02, /* 0x3c98bf54 */
+r5 = 7.7794247773e-04, /* 0x3a4beed6 */
+r6 = 7.3266842264e-06, /* 0x36f5d7bd */
+w0 = 4.1893854737e-01, /* 0x3ed67f1d */
+w1 = 8.3333335817e-02, /* 0x3daaaaab */
+w2 = -2.7777778450e-03, /* 0xbb360b61 */
+w3 = 7.9365057172e-04, /* 0x3a500cfd */
+w4 = -5.9518753551e-04, /* 0xba1c065c */
+w5 = 8.3633989561e-04, /* 0x3a5b3dd2 */
+w6 = -1.6309292987e-03; /* 0xbad5c4e8 */
+
+#ifdef __STDC__
+static const float zero= 0.0000000000e+00;
+#else
+static float zero= 0.0000000000e+00;
+#endif
+
+#ifdef __STDC__
+ static float sin_pif(float x)
+#else
+ static float sin_pif(x)
+ float x;
+#endif
+{
+ float y,z;
+ int n,ix;
+
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+
+ if(ix<0x3e800000) return __kernel_sinf(pi*x,zero,0);
+ y = -x; /* x is assume negative */
+
+ /*
+ * argument reduction, make sure inexact flag not raised if input
+ * is an integer
+ */
+ z = floorf(y);
+ if(z!=y) { /* inexact anyway */
+ y *= (float)0.5;
+ y = (float)2.0*(y - floorf(y)); /* y = |x| mod 2.0 */
+ n = (int) (y*(float)4.0);
+ } else {
+ if(ix>=0x4b800000) {
+ y = zero; n = 0; /* y must be even */
+ } else {
+ if(ix<0x4b000000) z = y+two23; /* exact */
+ GET_FLOAT_WORD(n,z);
+ n &= 1;
+ y = n;
+ n<<= 2;
+ }
+ }
+ switch (n) {
+ case 0: y = __kernel_sinf(pi*y,zero,0); break;
+ case 1:
+ case 2: y = __kernel_cosf(pi*((float)0.5-y),zero); break;
+ case 3:
+ case 4: y = __kernel_sinf(pi*(one-y),zero,0); break;
+ case 5:
+ case 6: y = -__kernel_cosf(pi*(y-(float)1.5),zero); break;
+ default: y = __kernel_sinf(pi*(y-(float)2.0),zero,0); break;
+ }
+ return -y;
+}
+
+
+#ifdef __STDC__
+ float __ieee754_lgammaf_r(float x, int *signgamp)
+#else
+ float __ieee754_lgammaf_r(x,signgamp)
+ float x; int *signgamp;
+#endif
+{
+ float t,y,z,nadj,p,p1,p2,p3,q,r,w;
+ int i,hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+
+ /* purge off +-inf, NaN, +-0, and negative arguments */
+ *signgamp = 1;
+ ix = hx&0x7fffffff;
+ if(ix>=0x7f800000) return x*x;
+ if(ix==0) return one/zero;
+ if(ix<0x1c800000) { /* |x|<2**-70, return -log(|x|) */
+ if(hx<0) {
+ *signgamp = -1;
+ return -__ieee754_logf(-x);
+ } else return -__ieee754_logf(x);
+ }
+ if(hx<0) {
+ if(ix>=0x4b000000) /* |x|>=2**23, must be -integer */
+ return one/zero;
+ t = sin_pif(x);
+ if(t==zero) return one/zero; /* -integer */
+ nadj = __ieee754_logf(pi/fabsf(t*x));
+ if(t<zero) *signgamp = -1;
+ x = -x;
+ }
+
+ /* purge off 1 and 2 */
+ if (ix==0x3f800000||ix==0x40000000) r = 0;
+ /* for x < 2.0 */
+ else if(ix<0x40000000) {
+ if(ix<=0x3f666666) { /* lgamma(x) = lgamma(x+1)-log(x) */
+ r = -__ieee754_logf(x);
+ if(ix>=0x3f3b4a20) {y = one-x; i= 0;}
+ else if(ix>=0x3e6d3308) {y= x-(tc-one); i=1;}
+ else {y = x; i=2;}
+ } else {
+ r = zero;
+ if(ix>=0x3fdda618) {y=(float)2.0-x;i=0;} /* [1.7316,2] */
+ else if(ix>=0x3F9da620) {y=x-tc;i=1;} /* [1.23,1.73] */
+ else {y=x-one;i=2;}
+ }
+ switch(i) {
+ case 0:
+ z = y*y;
+ p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
+ p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
+ p = y*p1+p2;
+ r += (p-(float)0.5*y); break;
+ case 1:
+ z = y*y;
+ w = z*y;
+ p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */
+ p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
+ p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
+ p = z*p1-(tt-w*(p2+y*p3));
+ r += (tf + p); break;
+ case 2:
+ p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
+ p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
+ r += (-(float)0.5*y + p1/p2);
+ }
+ }
+ else if(ix<0x41000000) { /* x < 8.0 */
+ i = (int)x;
+ t = zero;
+ y = x-(float)i;
+ p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
+ q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
+ r = half*y+p/q;
+ z = one; /* lgamma(1+s) = log(s) + lgamma(s) */
+ switch(i) {
+ case 7: z *= (y+(float)6.0); /* FALLTHRU */
+ case 6: z *= (y+(float)5.0); /* FALLTHRU */
+ case 5: z *= (y+(float)4.0); /* FALLTHRU */
+ case 4: z *= (y+(float)3.0); /* FALLTHRU */
+ case 3: z *= (y+(float)2.0); /* FALLTHRU */
+ r += __ieee754_logf(z); break;
+ }
+ /* 8.0 <= x < 2**58 */
+ } else if (ix < 0x5c800000) {
+ t = __ieee754_logf(x);
+ z = one/x;
+ y = z*z;
+ w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
+ r = (x-half)*(t-one)+w;
+ } else
+ /* 2**58 <= x <= inf */
+ r = x*(__ieee754_logf(x)-one);
+ if(hx<0) r = nadj - r;
+ return r;
+}
diff --git a/lib/msun/src/e_log.c b/lib/msun/src/e_log.c
new file mode 100644
index 0000000..6ebeb91
--- /dev/null
+++ b/lib/msun/src/e_log.c
@@ -0,0 +1,146 @@
+/* @(#)e_log.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_log(x)
+ * Return the logrithm of x
+ *
+ * Method :
+ * 1. Argument Reduction: find k and f such that
+ * x = 2^k * (1+f),
+ * where sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ * 2. Approximation of log(1+f).
+ * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ * = 2s + s*R
+ * We use a special Reme algorithm on [0,0.1716] to generate
+ * a polynomial of degree 14 to approximate R The maximum error
+ * of this polynomial approximation is bounded by 2**-58.45. In
+ * other words,
+ * 2 4 6 8 10 12 14
+ * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s
+ * (the values of Lg1 to Lg7 are listed in the program)
+ * and
+ * | 2 14 | -58.45
+ * | Lg1*s +...+Lg7*s - R(z) | <= 2
+ * | |
+ * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ * In order to guarantee error in log below 1ulp, we compute log
+ * by
+ * log(1+f) = f - s*(f - R) (if f is not too large)
+ * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
+ *
+ * 3. Finally, log(x) = k*ln2 + log(1+f).
+ * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ * Here ln2 is split into two floating point number:
+ * ln2_hi + ln2_lo,
+ * where n*ln2_hi is always exact for |n| < 2000.
+ *
+ * Special cases:
+ * log(x) is NaN with signal if x < 0 (including -INF) ;
+ * log(+INF) is +INF; log(0) is -INF with signal;
+ * log(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
+ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
+two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */
+Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __generic___ieee754_log(double x)
+#else
+ double __generic___ieee754_log(x)
+ double x;
+#endif
+{
+ double hfsq,f,s,z,R,w,t1,t2,dk;
+ int32_t k,hx,i,j;
+ u_int32_t lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ k=0;
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+ if (((hx&0x7fffffff)|lx)==0)
+ return -two54/zero; /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 54; x *= two54; /* subnormal number, scale up x */
+ GET_HIGH_WORD(hx,x);
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ k += (hx>>20)-1023;
+ hx &= 0x000fffff;
+ i = (hx+0x95f64)&0x100000;
+ SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
+ k += (i>>20);
+ f = x-1.0;
+ if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */
+ if(f==zero) if(k==0) return zero; else {dk=(double)k;
+ return dk*ln2_hi+dk*ln2_lo;}
+ R = f*f*(0.5-0.33333333333333333*f);
+ if(k==0) return f-R; else {dk=(double)k;
+ return dk*ln2_hi-((R-dk*ln2_lo)-f);}
+ }
+ s = f/(2.0+f);
+ dk = (double)k;
+ z = s*s;
+ i = hx-0x6147a;
+ w = z*z;
+ j = 0x6b851-hx;
+ t1= w*(Lg2+w*(Lg4+w*Lg6));
+ t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+ i |= j;
+ R = t2+t1;
+ if(i>0) {
+ hfsq=0.5*f*f;
+ if(k==0) return f-(hfsq-s*(hfsq+R)); else
+ return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
+ } else {
+ if(k==0) return f-s*(f-R); else
+ return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
+ }
+}
diff --git a/lib/msun/src/e_log10.c b/lib/msun/src/e_log10.c
new file mode 100644
index 0000000..5c02df8
--- /dev/null
+++ b/lib/msun/src/e_log10.c
@@ -0,0 +1,98 @@
+/* @(#)e_log10.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_log10(x)
+ * Return the base 10 logarithm of x
+ *
+ * Method :
+ * Let log10_2hi = leading 40 bits of log10(2) and
+ * log10_2lo = log10(2) - log10_2hi,
+ * ivln10 = 1/log(10) rounded.
+ * Then
+ * n = ilogb(x),
+ * if(n<0) n = n+1;
+ * x = scalbn(x,-n);
+ * log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x))
+ *
+ * Note 1:
+ * To guarantee log10(10**n)=n, where 10**n is normal, the rounding
+ * mode must set to Round-to-Nearest.
+ * Note 2:
+ * [1/log(10)] rounded to 53 bits has error .198 ulps;
+ * log10 is monotonic at all binary break points.
+ *
+ * Special cases:
+ * log10(x) is NaN with signal if x < 0;
+ * log10(+INF) is +INF with no signal; log10(0) is -INF with signal;
+ * log10(NaN) is that NaN with no signal;
+ * log10(10**N) = N for N=0,1,...,22.
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+ivln10 = 4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */
+log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
+log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __generic___ieee754_log10(double x)
+#else
+ double __generic___ieee754_log10(x)
+ double x;
+#endif
+{
+ double y,z;
+ int32_t i,k,hx;
+ u_int32_t lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ k=0;
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+ if (((hx&0x7fffffff)|lx)==0)
+ return -two54/zero; /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 54; x *= two54; /* subnormal number, scale up x */
+ GET_HIGH_WORD(hx,x);
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ k += (hx>>20)-1023;
+ i = ((u_int32_t)k&0x80000000)>>31;
+ hx = (hx&0x000fffff)|((0x3ff-i)<<20);
+ y = (double)(k+i);
+ SET_HIGH_WORD(x,hx);
+ z = y*log10_2lo + ivln10*__ieee754_log(x);
+ return z+y*log10_2hi;
+}
diff --git a/lib/msun/src/e_log10f.c b/lib/msun/src/e_log10f.c
new file mode 100644
index 0000000..8b11d38
--- /dev/null
+++ b/lib/msun/src/e_log10f.c
@@ -0,0 +1,67 @@
+/* e_log10f.c -- float version of e_log10.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+two25 = 3.3554432000e+07, /* 0x4c000000 */
+ivln10 = 4.3429449201e-01, /* 0x3ede5bd9 */
+log10_2hi = 3.0102920532e-01, /* 0x3e9a2080 */
+log10_2lo = 7.9034151668e-07; /* 0x355427db */
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_log10f(float x)
+#else
+ float __ieee754_log10f(x)
+ float x;
+#endif
+{
+ float y,z;
+ int32_t i,k,hx;
+
+ GET_FLOAT_WORD(hx,x);
+
+ k=0;
+ if (hx < 0x00800000) { /* x < 2**-126 */
+ if ((hx&0x7fffffff)==0)
+ return -two25/zero; /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 25; x *= two25; /* subnormal number, scale up x */
+ GET_FLOAT_WORD(hx,x);
+ }
+ if (hx >= 0x7f800000) return x+x;
+ k += (hx>>23)-127;
+ i = ((u_int32_t)k&0x80000000)>>31;
+ hx = (hx&0x007fffff)|((0x7f-i)<<23);
+ y = (float)(k+i);
+ SET_FLOAT_WORD(x,hx);
+ z = y*log10_2lo + ivln10*__ieee754_logf(x);
+ return z+y*log10_2hi;
+}
diff --git a/lib/msun/src/e_logf.c b/lib/msun/src/e_logf.c
new file mode 100644
index 0000000..4a286a6
--- /dev/null
+++ b/lib/msun/src/e_logf.c
@@ -0,0 +1,97 @@
+/* e_logf.c -- float version of e_log.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
+ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
+two25 = 3.355443200e+07, /* 0x4c000000 */
+Lg1 = 6.6666668653e-01, /* 3F2AAAAB */
+Lg2 = 4.0000000596e-01, /* 3ECCCCCD */
+Lg3 = 2.8571429849e-01, /* 3E924925 */
+Lg4 = 2.2222198546e-01, /* 3E638E29 */
+Lg5 = 1.8183572590e-01, /* 3E3A3325 */
+Lg6 = 1.5313838422e-01, /* 3E1CD04F */
+Lg7 = 1.4798198640e-01; /* 3E178897 */
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_logf(float x)
+#else
+ float __ieee754_logf(x)
+ float x;
+#endif
+{
+ float hfsq,f,s,z,R,w,t1,t2,dk;
+ int32_t k,ix,i,j;
+
+ GET_FLOAT_WORD(ix,x);
+
+ k=0;
+ if (ix < 0x00800000) { /* x < 2**-126 */
+ if ((ix&0x7fffffff)==0)
+ return -two25/zero; /* log(+-0)=-inf */
+ if (ix<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 25; x *= two25; /* subnormal number, scale up x */
+ GET_FLOAT_WORD(ix,x);
+ }
+ if (ix >= 0x7f800000) return x+x;
+ k += (ix>>23)-127;
+ ix &= 0x007fffff;
+ i = (ix+(0x95f64<<3))&0x800000;
+ SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */
+ k += (i>>23);
+ f = x-(float)1.0;
+ if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */
+ if(f==zero) if(k==0) return zero; else {dk=(float)k;
+ return dk*ln2_hi+dk*ln2_lo;}
+ R = f*f*((float)0.5-(float)0.33333333333333333*f);
+ if(k==0) return f-R; else {dk=(float)k;
+ return dk*ln2_hi-((R-dk*ln2_lo)-f);}
+ }
+ s = f/((float)2.0+f);
+ dk = (float)k;
+ z = s*s;
+ i = ix-(0x6147a<<3);
+ w = z*z;
+ j = (0x6b851<<3)-ix;
+ t1= w*(Lg2+w*(Lg4+w*Lg6));
+ t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+ i |= j;
+ R = t2+t1;
+ if(i>0) {
+ hfsq=(float)0.5*f*f;
+ if(k==0) return f-(hfsq-s*(hfsq+R)); else
+ return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
+ } else {
+ if(k==0) return f-s*(f-R); else
+ return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
+ }
+}
diff --git a/lib/msun/src/e_pow.c b/lib/msun/src/e_pow.c
new file mode 100644
index 0000000..18ba4fa
--- /dev/null
+++ b/lib/msun/src/e_pow.c
@@ -0,0 +1,312 @@
+/* @(#)e_pow.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_pow(x,y) return x**y
+ *
+ * n
+ * Method: Let x = 2 * (1+f)
+ * 1. Compute and return log2(x) in two pieces:
+ * log2(x) = w1 + w2,
+ * where w1 has 53-24 = 29 bit trailing zeros.
+ * 2. Perform y*log2(x) = n+y' by simulating muti-precision
+ * arithmetic, where |y'|<=0.5.
+ * 3. Return x**y = 2**n*exp(y'*log2)
+ *
+ * Special cases:
+ * 1. (anything) ** 0 is 1
+ * 2. (anything) ** 1 is itself
+ * 3. (anything) ** NAN is NAN
+ * 4. NAN ** (anything except 0) is NAN
+ * 5. +-(|x| > 1) ** +INF is +INF
+ * 6. +-(|x| > 1) ** -INF is +0
+ * 7. +-(|x| < 1) ** +INF is +0
+ * 8. +-(|x| < 1) ** -INF is +INF
+ * 9. +-1 ** +-INF is NAN
+ * 10. +0 ** (+anything except 0, NAN) is +0
+ * 11. -0 ** (+anything except 0, NAN, odd integer) is +0
+ * 12. +0 ** (-anything except 0, NAN) is +INF
+ * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
+ * 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
+ * 15. +INF ** (+anything except 0,NAN) is +INF
+ * 16. +INF ** (-anything except 0,NAN) is +0
+ * 17. -INF ** (anything) = -0 ** (-anything)
+ * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
+ * 19. (-anything except 0 and inf) ** (non-integer) is NAN
+ *
+ * Accuracy:
+ * pow(x,y) returns x**y nearly rounded. In particular
+ * pow(integer,integer)
+ * always returns the correct integer provided it is
+ * representable.
+ *
+ * Constants :
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+bp[] = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
+dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
+zero = 0.0,
+one = 1.0,
+two = 2.0,
+two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */
+huge = 1.0e300,
+tiny = 1.0e-300,
+ /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
+L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
+L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
+L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
+L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
+L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
+P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
+lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
+lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
+ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
+cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
+cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
+cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
+ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
+ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
+ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
+
+#ifdef __STDC__
+ double __ieee754_pow(double x, double y)
+#else
+ double __ieee754_pow(x,y)
+ double x, y;
+#endif
+{
+ double z,ax,z_h,z_l,p_h,p_l;
+ double y1,t1,t2,r,s,t,u,v,w;
+ int32_t i,j,k,yisint,n;
+ int32_t hx,hy,ix,iy;
+ u_int32_t lx,ly;
+
+ EXTRACT_WORDS(hx,lx,x);
+ EXTRACT_WORDS(hy,ly,y);
+ ix = hx&0x7fffffff; iy = hy&0x7fffffff;
+
+ /* y==zero: x**0 = 1 */
+ if((iy|ly)==0) return one;
+
+ /* +-NaN return x+y */
+ if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
+ iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
+ return x+y;
+
+ /* determine if y is an odd int when x < 0
+ * yisint = 0 ... y is not an integer
+ * yisint = 1 ... y is an odd int
+ * yisint = 2 ... y is an even int
+ */
+ yisint = 0;
+ if(hx<0) {
+ if(iy>=0x43400000) yisint = 2; /* even integer y */
+ else if(iy>=0x3ff00000) {
+ k = (iy>>20)-0x3ff; /* exponent */
+ if(k>20) {
+ j = ly>>(52-k);
+ if((j<<(52-k))==ly) yisint = 2-(j&1);
+ } else if(ly==0) {
+ j = iy>>(20-k);
+ if((j<<(20-k))==iy) yisint = 2-(j&1);
+ }
+ }
+ }
+
+ /* special value of y */
+ if(ly==0) {
+ if (iy==0x7ff00000) { /* y is +-inf */
+ if(((ix-0x3ff00000)|lx)==0)
+ return y - y; /* inf**+-1 is NaN */
+ else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
+ return (hy>=0)? y: zero;
+ else /* (|x|<1)**-,+inf = inf,0 */
+ return (hy<0)?-y: zero;
+ }
+ if(iy==0x3ff00000) { /* y is +-1 */
+ if(hy<0) return one/x; else return x;
+ }
+ if(hy==0x40000000) return x*x; /* y is 2 */
+ if(hy==0x3fe00000) { /* y is 0.5 */
+ if(hx>=0) /* x >= +0 */
+ return __ieee754_sqrt(x);
+ }
+ }
+
+ ax = fabs(x);
+ /* special value of x */
+ if(lx==0) {
+ if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
+ z = ax; /*x is +-0,+-inf,+-1*/
+ if(hy<0) z = one/z; /* z = (1/|x|) */
+ if(hx<0) {
+ if(((ix-0x3ff00000)|yisint)==0) {
+ z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+ } else if(yisint==1)
+ z = -z; /* (x<0)**odd = -(|x|**odd) */
+ }
+ return z;
+ }
+ }
+
+ /* (x<0)**(non-int) is NaN */
+ /* CYGNUS LOCAL: This used to be
+ if((((hx>>31)+1)|yisint)==0) return (x-x)/(x-x);
+ but ANSI C says a right shift of a signed negative quantity is
+ implementation defined. */
+ if(((((u_int32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x);
+
+ /* |y| is huge */
+ if(iy>0x41e00000) { /* if |y| > 2**31 */
+ if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */
+ if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
+ if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
+ }
+ /* over/underflow if x is not close to one */
+ if(ix<0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
+ if(ix>0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
+ /* now |1-x| is tiny <= 2**-20, suffice to compute
+ log(x) by x-x^2/2+x^3/3-x^4/4 */
+ t = x-1; /* t has 20 trailing zeros */
+ w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
+ u = ivln2_h*t; /* ivln2_h has 21 sig. bits */
+ v = t*ivln2_l-w*ivln2;
+ t1 = u+v;
+ SET_LOW_WORD(t1,0);
+ t2 = v-(t1-u);
+ } else {
+ double s2,s_h,s_l,t_h,t_l;
+ n = 0;
+ /* take care subnormal number */
+ if(ix<0x00100000)
+ {ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); }
+ n += ((ix)>>20)-0x3ff;
+ j = ix&0x000fffff;
+ /* determine interval */
+ ix = j|0x3ff00000; /* normalize ix */
+ if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */
+ else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */
+ else {k=0;n+=1;ix -= 0x00100000;}
+ SET_HIGH_WORD(ax,ix);
+
+ /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+ u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
+ v = one/(ax+bp[k]);
+ s = u*v;
+ s_h = s;
+ SET_LOW_WORD(s_h,0);
+ /* t_h=ax+bp[k] High */
+ t_h = zero;
+ SET_HIGH_WORD(t_h,((ix>>1)|0x20000000)+0x00080000+(k<<18));
+ t_l = ax - (t_h-bp[k]);
+ s_l = v*((u-s_h*t_h)-s_h*t_l);
+ /* compute log(ax) */
+ s2 = s*s;
+ r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+ r += s_l*(s_h+s);
+ s2 = s_h*s_h;
+ t_h = 3.0+s2+r;
+ SET_LOW_WORD(t_h,0);
+ t_l = r-((t_h-3.0)-s2);
+ /* u+v = s*(1+...) */
+ u = s_h*t_h;
+ v = s_l*t_h+t_l*s;
+ /* 2/(3log2)*(s+...) */
+ p_h = u+v;
+ SET_LOW_WORD(p_h,0);
+ p_l = v-(p_h-u);
+ z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
+ z_l = cp_l*p_h+p_l*cp+dp_l[k];
+ /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+ t = (double)n;
+ t1 = (((z_h+z_l)+dp_h[k])+t);
+ SET_LOW_WORD(t1,0);
+ t2 = z_l-(((t1-t)-dp_h[k])-z_h);
+ }
+
+ s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
+ if(((((u_int32_t)hx>>31)-1)|(yisint-1))==0)
+ s = -one;/* (-ve)**(odd int) */
+
+ /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+ y1 = y;
+ SET_LOW_WORD(y1,0);
+ p_l = (y-y1)*t1+y*t2;
+ p_h = y1*t1;
+ z = p_l+p_h;
+ EXTRACT_WORDS(j,i,z);
+ if (j>=0x40900000) { /* z >= 1024 */
+ if(((j-0x40900000)|i)!=0) /* if z > 1024 */
+ return s*huge*huge; /* overflow */
+ else {
+ if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */
+ }
+ } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */
+ if(((j-0xc090cc00)|i)!=0) /* z < -1075 */
+ return s*tiny*tiny; /* underflow */
+ else {
+ if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */
+ }
+ }
+ /*
+ * compute 2**(p_h+p_l)
+ */
+ i = j&0x7fffffff;
+ k = (i>>20)-0x3ff;
+ n = 0;
+ if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */
+ n = j+(0x00100000>>(k+1));
+ k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */
+ t = zero;
+ SET_HIGH_WORD(t,n&~(0x000fffff>>k));
+ n = ((n&0x000fffff)|0x00100000)>>(20-k);
+ if(j<0) n = -n;
+ p_h -= t;
+ }
+ t = p_l+p_h;
+ SET_LOW_WORD(t,0);
+ u = t*lg2_h;
+ v = (p_l-(t-p_h))*lg2+t*lg2_l;
+ z = u+v;
+ w = v-(z-u);
+ t = z*z;
+ t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+ r = (z*t1)/(t1-two)-(w+z*w);
+ z = one-(r-z);
+ GET_HIGH_WORD(j,z);
+ j += (n<<20);
+ if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */
+ else SET_HIGH_WORD(z,j);
+ return s*z;
+}
diff --git a/lib/msun/src/e_powf.c b/lib/msun/src/e_powf.c
new file mode 100644
index 0000000..34f5d47
--- /dev/null
+++ b/lib/msun/src/e_powf.c
@@ -0,0 +1,253 @@
+/* e_powf.c -- float version of e_pow.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+bp[] = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */
+dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */
+zero = 0.0,
+one = 1.0,
+two = 2.0,
+two24 = 16777216.0, /* 0x4b800000 */
+huge = 1.0e30,
+tiny = 1.0e-30,
+ /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1 = 6.0000002384e-01, /* 0x3f19999a */
+L2 = 4.2857143283e-01, /* 0x3edb6db7 */
+L3 = 3.3333334327e-01, /* 0x3eaaaaab */
+L4 = 2.7272811532e-01, /* 0x3e8ba305 */
+L5 = 2.3066075146e-01, /* 0x3e6c3255 */
+L6 = 2.0697501302e-01, /* 0x3e53f142 */
+P1 = 1.6666667163e-01, /* 0x3e2aaaab */
+P2 = -2.7777778450e-03, /* 0xbb360b61 */
+P3 = 6.6137559770e-05, /* 0x388ab355 */
+P4 = -1.6533901999e-06, /* 0xb5ddea0e */
+P5 = 4.1381369442e-08, /* 0x3331bb4c */
+lg2 = 6.9314718246e-01, /* 0x3f317218 */
+lg2_h = 6.93145752e-01, /* 0x3f317200 */
+lg2_l = 1.42860654e-06, /* 0x35bfbe8c */
+ovt = 4.2995665694e-08, /* -(128-log2(ovfl+.5ulp)) */
+cp = 9.6179670095e-01, /* 0x3f76384f =2/(3ln2) */
+cp_h = 9.6179199219e-01, /* 0x3f763800 =head of cp */
+cp_l = 4.7017383622e-06, /* 0x369dc3a0 =tail of cp_h */
+ivln2 = 1.4426950216e+00, /* 0x3fb8aa3b =1/ln2 */
+ivln2_h = 1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/
+ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
+
+#ifdef __STDC__
+ float __ieee754_powf(float x, float y)
+#else
+ float __ieee754_powf(x,y)
+ float x, y;
+#endif
+{
+ float z,ax,z_h,z_l,p_h,p_l;
+ float y1,t1,t2,r,s,t,u,v,w;
+ int32_t i,j,k,yisint,n;
+ int32_t hx,hy,ix,iy,is;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_FLOAT_WORD(hy,y);
+ ix = hx&0x7fffffff; iy = hy&0x7fffffff;
+
+ /* y==zero: x**0 = 1 */
+ if(iy==0) return one;
+
+ /* +-NaN return x+y */
+ if(ix > 0x7f800000 ||
+ iy > 0x7f800000)
+ return x+y;
+
+ /* determine if y is an odd int when x < 0
+ * yisint = 0 ... y is not an integer
+ * yisint = 1 ... y is an odd int
+ * yisint = 2 ... y is an even int
+ */
+ yisint = 0;
+ if(hx<0) {
+ if(iy>=0x4b800000) yisint = 2; /* even integer y */
+ else if(iy>=0x3f800000) {
+ k = (iy>>23)-0x7f; /* exponent */
+ j = iy>>(23-k);
+ if((j<<(23-k))==iy) yisint = 2-(j&1);
+ }
+ }
+
+ /* special value of y */
+ if (iy==0x7f800000) { /* y is +-inf */
+ if (ix==0x3f800000)
+ return y - y; /* inf**+-1 is NaN */
+ else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */
+ return (hy>=0)? y: zero;
+ else /* (|x|<1)**-,+inf = inf,0 */
+ return (hy<0)?-y: zero;
+ }
+ if(iy==0x3f800000) { /* y is +-1 */
+ if(hy<0) return one/x; else return x;
+ }
+ if(hy==0x40000000) return x*x; /* y is 2 */
+ if(hy==0x3f000000) { /* y is 0.5 */
+ if(hx>=0) /* x >= +0 */
+ return __ieee754_sqrtf(x);
+ }
+
+ ax = fabsf(x);
+ /* special value of x */
+ if(ix==0x7f800000||ix==0||ix==0x3f800000){
+ z = ax; /*x is +-0,+-inf,+-1*/
+ if(hy<0) z = one/z; /* z = (1/|x|) */
+ if(hx<0) {
+ if(((ix-0x3f800000)|yisint)==0) {
+ z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+ } else if(yisint==1)
+ z = -z; /* (x<0)**odd = -(|x|**odd) */
+ }
+ return z;
+ }
+
+ /* (x<0)**(non-int) is NaN */
+ if(((((u_int32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x);
+
+ /* |y| is huge */
+ if(iy>0x4d000000) { /* if |y| > 2**27 */
+ /* over/underflow if x is not close to one */
+ if(ix<0x3f7ffff8) return (hy<0)? huge*huge:tiny*tiny;
+ if(ix>0x3f800007) return (hy>0)? huge*huge:tiny*tiny;
+ /* now |1-x| is tiny <= 2**-20, suffice to compute
+ log(x) by x-x^2/2+x^3/3-x^4/4 */
+ t = x-1; /* t has 20 trailing zeros */
+ w = (t*t)*((float)0.5-t*((float)0.333333333333-t*(float)0.25));
+ u = ivln2_h*t; /* ivln2_h has 16 sig. bits */
+ v = t*ivln2_l-w*ivln2;
+ t1 = u+v;
+ GET_FLOAT_WORD(is,t1);
+ SET_FLOAT_WORD(t1,is&0xfffff000);
+ t2 = v-(t1-u);
+ } else {
+ float s2,s_h,s_l,t_h,t_l;
+ n = 0;
+ /* take care subnormal number */
+ if(ix<0x00800000)
+ {ax *= two24; n -= 24; GET_FLOAT_WORD(ix,ax); }
+ n += ((ix)>>23)-0x7f;
+ j = ix&0x007fffff;
+ /* determine interval */
+ ix = j|0x3f800000; /* normalize ix */
+ if(j<=0x1cc471) k=0; /* |x|<sqrt(3/2) */
+ else if(j<0x5db3d7) k=1; /* |x|<sqrt(3) */
+ else {k=0;n+=1;ix -= 0x00800000;}
+ SET_FLOAT_WORD(ax,ix);
+
+ /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+ u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
+ v = one/(ax+bp[k]);
+ s = u*v;
+ s_h = s;
+ GET_FLOAT_WORD(is,s_h);
+ SET_FLOAT_WORD(s_h,is&0xfffff000);
+ /* t_h=ax+bp[k] High */
+ SET_FLOAT_WORD(t_h,((ix>>1)|0x20000000)+0x0040000+(k<<21));
+ t_l = ax - (t_h-bp[k]);
+ s_l = v*((u-s_h*t_h)-s_h*t_l);
+ /* compute log(ax) */
+ s2 = s*s;
+ r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+ r += s_l*(s_h+s);
+ s2 = s_h*s_h;
+ t_h = (float)3.0+s2+r;
+ GET_FLOAT_WORD(is,t_h);
+ SET_FLOAT_WORD(t_h,is&0xfffff000);
+ t_l = r-((t_h-(float)3.0)-s2);
+ /* u+v = s*(1+...) */
+ u = s_h*t_h;
+ v = s_l*t_h+t_l*s;
+ /* 2/(3log2)*(s+...) */
+ p_h = u+v;
+ GET_FLOAT_WORD(is,p_h);
+ SET_FLOAT_WORD(p_h,is&0xfffff000);
+ p_l = v-(p_h-u);
+ z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
+ z_l = cp_l*p_h+p_l*cp+dp_l[k];
+ /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+ t = (float)n;
+ t1 = (((z_h+z_l)+dp_h[k])+t);
+ GET_FLOAT_WORD(is,t1);
+ SET_FLOAT_WORD(t1,is&0xfffff000);
+ t2 = z_l-(((t1-t)-dp_h[k])-z_h);
+ }
+
+ s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
+ if(((((u_int32_t)hx>>31)-1)|(yisint-1))==0)
+ s = -one; /* (-ve)**(odd int) */
+
+ /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+ GET_FLOAT_WORD(is,y);
+ SET_FLOAT_WORD(y1,is&0xfffff000);
+ p_l = (y-y1)*t1+y*t2;
+ p_h = y1*t1;
+ z = p_l+p_h;
+ GET_FLOAT_WORD(j,z);
+ if (j>0x43000000) /* if z > 128 */
+ return s*huge*huge; /* overflow */
+ else if (j==0x43000000) { /* if z == 128 */
+ if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */
+ }
+ else if ((j&0x7fffffff)>0x43160000) /* z <= -150 */
+ return s*tiny*tiny; /* underflow */
+ else if (j==0xc3160000){ /* z == -150 */
+ if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */
+ }
+ /*
+ * compute 2**(p_h+p_l)
+ */
+ i = j&0x7fffffff;
+ k = (i>>23)-0x7f;
+ n = 0;
+ if(i>0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */
+ n = j+(0x00800000>>(k+1));
+ k = ((n&0x7fffffff)>>23)-0x7f; /* new k for n */
+ SET_FLOAT_WORD(t,n&~(0x007fffff>>k));
+ n = ((n&0x007fffff)|0x00800000)>>(23-k);
+ if(j<0) n = -n;
+ p_h -= t;
+ }
+ t = p_l+p_h;
+ GET_FLOAT_WORD(is,t);
+ SET_FLOAT_WORD(t,is&0xfffff000);
+ u = t*lg2_h;
+ v = (p_l-(t-p_h))*lg2+t*lg2_l;
+ z = u+v;
+ w = v-(z-u);
+ t = z*z;
+ t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+ r = (z*t1)/(t1-two)-(w+z*w);
+ z = one-(r-z);
+ GET_FLOAT_WORD(j,z);
+ j += (n<<23);
+ if((j>>23)<=0) z = scalbnf(z,n); /* subnormal output */
+ else SET_FLOAT_WORD(z,j);
+ return s*z;
+}
diff --git a/lib/msun/src/e_rem_pio2.c b/lib/msun/src/e_rem_pio2.c
new file mode 100644
index 0000000..0d182de
--- /dev/null
+++ b/lib/msun/src/e_rem_pio2.c
@@ -0,0 +1,183 @@
+/* @(#)e_rem_pio2.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_rem_pio2(x,y)
+ *
+ * return the remainder of x rem pi/2 in y[0]+y[1]
+ * use __kernel_rem_pio2()
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+/*
+ * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
+ */
+#ifdef __STDC__
+static const int32_t two_over_pi[] = {
+#else
+static int32_t two_over_pi[] = {
+#endif
+0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
+0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
+0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
+0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
+0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
+0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
+0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
+0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
+0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
+0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
+0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
+};
+
+#ifdef __STDC__
+static const int32_t npio2_hw[] = {
+#else
+static int32_t npio2_hw[] = {
+#endif
+0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
+0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
+0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
+0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
+0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
+0x404858EB, 0x404921FB,
+};
+
+/*
+ * invpio2: 53 bits of 2/pi
+ * pio2_1: first 33 bit of pi/2
+ * pio2_1t: pi/2 - pio2_1
+ * pio2_2: second 33 bit of pi/2
+ * pio2_2t: pi/2 - (pio2_1+pio2_2)
+ * pio2_3: third 33 bit of pi/2
+ * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
+ */
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
+pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
+pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
+pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
+pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
+pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
+
+#ifdef __STDC__
+ int32_t __ieee754_rem_pio2(double x, double *y)
+#else
+ int32_t __ieee754_rem_pio2(x,y)
+ double x,y[];
+#endif
+{
+ double z,w,t,r,fn;
+ double tx[3];
+ int32_t e0,i,j,nx,n,ix,hx;
+ u_int32_t low;
+
+ GET_HIGH_WORD(hx,x); /* high word of x */
+ ix = hx&0x7fffffff;
+ if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */
+ {y[0] = x; y[1] = 0; return 0;}
+ if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */
+ if(hx>0) {
+ z = x - pio2_1;
+ if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
+ y[0] = z - pio2_1t;
+ y[1] = (z-y[0])-pio2_1t;
+ } else { /* near pi/2, use 33+33+53 bit pi */
+ z -= pio2_2;
+ y[0] = z - pio2_2t;
+ y[1] = (z-y[0])-pio2_2t;
+ }
+ return 1;
+ } else { /* negative x */
+ z = x + pio2_1;
+ if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
+ y[0] = z + pio2_1t;
+ y[1] = (z-y[0])+pio2_1t;
+ } else { /* near pi/2, use 33+33+53 bit pi */
+ z += pio2_2;
+ y[0] = z + pio2_2t;
+ y[1] = (z-y[0])+pio2_2t;
+ }
+ return -1;
+ }
+ }
+ if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
+ t = fabs(x);
+ n = (int32_t) (t*invpio2+half);
+ fn = (double)n;
+ r = t-fn*pio2_1;
+ w = fn*pio2_1t; /* 1st round good to 85 bit */
+ if(n<32&&ix!=npio2_hw[n-1]) {
+ y[0] = r-w; /* quick check no cancellation */
+ } else {
+ u_int32_t high;
+ j = ix>>20;
+ y[0] = r-w;
+ GET_HIGH_WORD(high,y[0]);
+ i = j-((high>>20)&0x7ff);
+ if(i>16) { /* 2nd iteration needed, good to 118 */
+ t = r;
+ w = fn*pio2_2;
+ r = t-w;
+ w = fn*pio2_2t-((t-r)-w);
+ y[0] = r-w;
+ GET_HIGH_WORD(high,y[0]);
+ i = j-((high>>20)&0x7ff);
+ if(i>49) { /* 3rd iteration need, 151 bits acc */
+ t = r; /* will cover all possible cases */
+ w = fn*pio2_3;
+ r = t-w;
+ w = fn*pio2_3t-((t-r)-w);
+ y[0] = r-w;
+ }
+ }
+ }
+ y[1] = (r-y[0])-w;
+ if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+ else return n;
+ }
+ /*
+ * all other (large) arguments
+ */
+ if(ix>=0x7ff00000) { /* x is inf or NaN */
+ y[0]=y[1]=x-x; return 0;
+ }
+ /* set z = scalbn(|x|,ilogb(x)-23) */
+ GET_LOW_WORD(low,x);
+ SET_LOW_WORD(z,low);
+ e0 = (ix>>20)-1046; /* e0 = ilogb(z)-23; */
+ SET_HIGH_WORD(z, ix - ((int32_t)(e0<<20)));
+ for(i=0;i<2;i++) {
+ tx[i] = (double)((int32_t)(z));
+ z = (z-tx[i])*two24;
+ }
+ tx[2] = z;
+ nx = 3;
+ while(tx[nx-1]==zero) nx--; /* skip zero term */
+ n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
+ if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+ return n;
+}
diff --git a/lib/msun/src/e_rem_pio2f.c b/lib/msun/src/e_rem_pio2f.c
new file mode 100644
index 0000000..cf9cecc
--- /dev/null
+++ b/lib/msun/src/e_rem_pio2f.c
@@ -0,0 +1,196 @@
+/* e_rem_pio2f.c -- float version of e_rem_pio2.c
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_rem_pio2f(x,y)
+ *
+ * return the remainder of x rem pi/2 in y[0]+y[1]
+ * use __kernel_rem_pio2f()
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+/*
+ * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
+ */
+#ifdef __STDC__
+static const int32_t two_over_pi[] = {
+#else
+static int32_t two_over_pi[] = {
+#endif
+0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC,
+0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62,
+0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63,
+0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A,
+0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09,
+0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29,
+0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44,
+0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41,
+0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C,
+0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8,
+0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11,
+0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF,
+0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E,
+0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5,
+0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92,
+0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08,
+0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0,
+0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3,
+0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85,
+0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80,
+0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA,
+0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B,
+};
+
+/* This array is like the one in e_rem_pio2.c, but the numbers are
+ single precision and the last 8 bits are forced to 0. */
+#ifdef __STDC__
+static const int32_t npio2_hw[] = {
+#else
+static int32_t npio2_hw[] = {
+#endif
+0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
+0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
+0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
+0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
+0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
+0x4242c700, 0x42490f00
+};
+
+/*
+ * invpio2: 24 bits of 2/pi
+ * pio2_1: first 17 bit of pi/2
+ * pio2_1t: pi/2 - pio2_1
+ * pio2_2: second 17 bit of pi/2
+ * pio2_2t: pi/2 - (pio2_1+pio2_2)
+ * pio2_3: third 17 bit of pi/2
+ * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
+ */
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+zero = 0.0000000000e+00, /* 0x00000000 */
+half = 5.0000000000e-01, /* 0x3f000000 */
+two8 = 2.5600000000e+02, /* 0x43800000 */
+invpio2 = 6.3661980629e-01, /* 0x3f22f984 */
+pio2_1 = 1.5707855225e+00, /* 0x3fc90f80 */
+pio2_1t = 1.0804334124e-05, /* 0x37354443 */
+pio2_2 = 1.0804273188e-05, /* 0x37354400 */
+pio2_2t = 6.0770999344e-11, /* 0x2e85a308 */
+pio2_3 = 6.0770943833e-11, /* 0x2e85a300 */
+pio2_3t = 6.1232342629e-17; /* 0x248d3132 */
+
+#ifdef __STDC__
+ int32_t __ieee754_rem_pio2f(float x, float *y)
+#else
+ int32_t __ieee754_rem_pio2f(x,y)
+ float x,y[];
+#endif
+{
+ float z,w,t,r,fn;
+ float tx[3];
+ int32_t e0,i,j,nx,n,ix,hx;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */
+ {y[0] = x; y[1] = 0; return 0;}
+ if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */
+ if(hx>0) {
+ z = x - pio2_1;
+ if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
+ y[0] = z - pio2_1t;
+ y[1] = (z-y[0])-pio2_1t;
+ } else { /* near pi/2, use 24+24+24 bit pi */
+ z -= pio2_2;
+ y[0] = z - pio2_2t;
+ y[1] = (z-y[0])-pio2_2t;
+ }
+ return 1;
+ } else { /* negative x */
+ z = x + pio2_1;
+ if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
+ y[0] = z + pio2_1t;
+ y[1] = (z-y[0])+pio2_1t;
+ } else { /* near pi/2, use 24+24+24 bit pi */
+ z += pio2_2;
+ y[0] = z + pio2_2t;
+ y[1] = (z-y[0])+pio2_2t;
+ }
+ return -1;
+ }
+ }
+ if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */
+ t = fabsf(x);
+ n = (int32_t) (t*invpio2+half);
+ fn = (float)n;
+ r = t-fn*pio2_1;
+ w = fn*pio2_1t; /* 1st round good to 40 bit */
+ if(n<32&&(ix&0xffffff00)!=npio2_hw[n-1]) {
+ y[0] = r-w; /* quick check no cancellation */
+ } else {
+ u_int32_t high;
+ j = ix>>23;
+ y[0] = r-w;
+ GET_FLOAT_WORD(high,y[0]);
+ i = j-((high>>23)&0xff);
+ if(i>8) { /* 2nd iteration needed, good to 57 */
+ t = r;
+ w = fn*pio2_2;
+ r = t-w;
+ w = fn*pio2_2t-((t-r)-w);
+ y[0] = r-w;
+ GET_FLOAT_WORD(high,y[0]);
+ i = j-((high>>23)&0xff);
+ if(i>25) { /* 3rd iteration need, 74 bits acc */
+ t = r; /* will cover all possible cases */
+ w = fn*pio2_3;
+ r = t-w;
+ w = fn*pio2_3t-((t-r)-w);
+ y[0] = r-w;
+ }
+ }
+ }
+ y[1] = (r-y[0])-w;
+ if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+ else return n;
+ }
+ /*
+ * all other (large) arguments
+ */
+ if(ix>=0x7f800000) { /* x is inf or NaN */
+ y[0]=y[1]=x-x; return 0;
+ }
+ /* set z = scalbn(|x|,ilogb(x)-7) */
+ e0 = (ix>>23)-134; /* e0 = ilogb(z)-7; */
+ SET_FLOAT_WORD(z, ix - ((int32_t)(e0<<23)));
+ for(i=0;i<2;i++) {
+ tx[i] = (float)((int32_t)(z));
+ z = (z-tx[i])*two8;
+ }
+ tx[2] = z;
+ nx = 3;
+ while(tx[nx-1]==zero) nx--; /* skip zero term */
+ n = __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi);
+ if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+ return n;
+}
diff --git a/lib/msun/src/e_remainder.c b/lib/msun/src/e_remainder.c
new file mode 100644
index 0000000..c41d392
--- /dev/null
+++ b/lib/msun/src/e_remainder.c
@@ -0,0 +1,80 @@
+/* @(#)e_remainder.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_remainder(x,p)
+ * Return :
+ * returns x REM p = x - [x/p]*p as if in infinite
+ * precise arithmetic, where [x/p] is the (infinite bit)
+ * integer nearest x/p (in half way case choose the even one).
+ * Method :
+ * Based on fmod() return x-[x/p]chopped*p exactlp.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+
+#ifdef __STDC__
+ double __generic___ieee754_remainder(double x, double p)
+#else
+ double __generic___ieee754_remainder(x,p)
+ double x,p;
+#endif
+{
+ int32_t hx,hp;
+ u_int32_t sx,lx,lp;
+ double p_half;
+
+ EXTRACT_WORDS(hx,lx,x);
+ EXTRACT_WORDS(hp,lp,p);
+ sx = hx&0x80000000;
+ hp &= 0x7fffffff;
+ hx &= 0x7fffffff;
+
+ /* purge off exception values */
+ if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */
+ if((hx>=0x7ff00000)|| /* x not finite */
+ ((hp>=0x7ff00000)&& /* p is NaN */
+ (((hp-0x7ff00000)|lp)!=0)))
+ return (x*p)/(x*p);
+
+
+ if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */
+ if (((hx-hp)|(lx-lp))==0) return zero*x;
+ x = fabs(x);
+ p = fabs(p);
+ if (hp<0x00200000) {
+ if(x+x>p) {
+ x-=p;
+ if(x+x>=p) x -= p;
+ }
+ } else {
+ p_half = 0.5*p;
+ if(x>p_half) {
+ x-=p;
+ if(x>=p_half) x -= p;
+ }
+ }
+ GET_HIGH_WORD(hx,x);
+ SET_HIGH_WORD(x,hx^sx);
+ return x;
+}
diff --git a/lib/msun/src/e_remainderf.c b/lib/msun/src/e_remainderf.c
new file mode 100644
index 0000000..d5f670e
--- /dev/null
+++ b/lib/msun/src/e_remainderf.c
@@ -0,0 +1,73 @@
+/* e_remainderf.c -- float version of e_remainder.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+
+#ifdef __STDC__
+ float __ieee754_remainderf(float x, float p)
+#else
+ float __ieee754_remainderf(x,p)
+ float x,p;
+#endif
+{
+ int32_t hx,hp;
+ u_int32_t sx;
+ float p_half;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_FLOAT_WORD(hp,p);
+ sx = hx&0x80000000;
+ hp &= 0x7fffffff;
+ hx &= 0x7fffffff;
+
+ /* purge off exception values */
+ if(hp==0) return (x*p)/(x*p); /* p = 0 */
+ if((hx>=0x7f800000)|| /* x not finite */
+ ((hp>0x7f800000))) /* p is NaN */
+ return (x*p)/(x*p);
+
+
+ if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p); /* now x < 2p */
+ if ((hx-hp)==0) return zero*x;
+ x = fabsf(x);
+ p = fabsf(p);
+ if (hp<0x01000000) {
+ if(x+x>p) {
+ x-=p;
+ if(x+x>=p) x -= p;
+ }
+ } else {
+ p_half = (float)0.5*p;
+ if(x>p_half) {
+ x-=p;
+ if(x>=p_half) x -= p;
+ }
+ }
+ GET_FLOAT_WORD(hx,x);
+ SET_FLOAT_WORD(x,hx^sx);
+ return x;
+}
diff --git a/lib/msun/src/e_scalb.c b/lib/msun/src/e_scalb.c
new file mode 100644
index 0000000..14f167e
--- /dev/null
+++ b/lib/msun/src/e_scalb.c
@@ -0,0 +1,55 @@
+/* @(#)e_scalb.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * __ieee754_scalb(x, fn) is provide for
+ * passing various standard test suite. One
+ * should use scalbn() instead.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef _SCALB_INT
+#ifdef __STDC__
+ double __generic___ieee754_scalb(double x, int fn)
+#else
+ double __generic___ieee754_scalb(x,fn)
+ double x; int fn;
+#endif
+#else
+#ifdef __STDC__
+ double __generic___ieee754_scalb(double x, double fn)
+#else
+ double __generic___ieee754_scalb(x,fn)
+ double x, fn;
+#endif
+#endif
+{
+#ifdef _SCALB_INT
+ return scalbn(x,fn);
+#else
+ if (isnan(x)||isnan(fn)) return x*fn;
+ if (!finite(fn)) {
+ if(fn>0.0) return x*fn;
+ else return x/(-fn);
+ }
+ if (rint(fn)!=fn) return (fn-fn)/(fn-fn);
+ if ( fn > 65000.0) return scalbn(x, 65000);
+ if (-fn > 65000.0) return scalbn(x,-65000);
+ return scalbn(x,(int)fn);
+#endif
+}
diff --git a/lib/msun/src/e_scalbf.c b/lib/msun/src/e_scalbf.c
new file mode 100644
index 0000000..c678570
--- /dev/null
+++ b/lib/msun/src/e_scalbf.c
@@ -0,0 +1,52 @@
+/* e_scalbf.c -- float version of e_scalb.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef _SCALB_INT
+#ifdef __STDC__
+ float __ieee754_scalbf(float x, int fn)
+#else
+ float __ieee754_scalbf(x,fn)
+ float x; int fn;
+#endif
+#else
+#ifdef __STDC__
+ float __ieee754_scalbf(float x, float fn)
+#else
+ float __ieee754_scalbf(x,fn)
+ float x, fn;
+#endif
+#endif
+{
+#ifdef _SCALB_INT
+ return scalbnf(x,fn);
+#else
+ if (isnanf(x)||isnanf(fn)) return x*fn;
+ if (!finitef(fn)) {
+ if(fn>(float)0.0) return x*fn;
+ else return x/(-fn);
+ }
+ if (rintf(fn)!=fn) return (fn-fn)/(fn-fn);
+ if ( fn > (float)65000.0) return scalbnf(x, 65000);
+ if (-fn > (float)65000.0) return scalbnf(x,-65000);
+ return scalbnf(x,(int)fn);
+#endif
+}
diff --git a/lib/msun/src/e_sinh.c b/lib/msun/src/e_sinh.c
new file mode 100644
index 0000000..2ac7891
--- /dev/null
+++ b/lib/msun/src/e_sinh.c
@@ -0,0 +1,86 @@
+/* @(#)e_sinh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_sinh(x)
+ * Method :
+ * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+ * 1. Replace x by |x| (sinh(-x) = -sinh(x)).
+ * 2.
+ * E + E/(E+1)
+ * 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x)
+ * 2
+ *
+ * 22 <= x <= lnovft : sinh(x) := exp(x)/2
+ * lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2)
+ * ln2ovft < x : sinh(x) := x*shuge (overflow)
+ *
+ * Special cases:
+ * sinh(x) is |x| if x is +INF, -INF, or NaN.
+ * only sinh(0)=0 is exact for finite x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one = 1.0, shuge = 1.0e307;
+#else
+static double one = 1.0, shuge = 1.0e307;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_sinh(double x)
+#else
+ double __ieee754_sinh(x)
+ double x;
+#endif
+{
+ double t,w,h;
+ int32_t ix,jx;
+ u_int32_t lx;
+
+ /* High word of |x|. */
+ GET_HIGH_WORD(jx,x);
+ ix = jx&0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7ff00000) return x+x;
+
+ h = 0.5;
+ if (jx<0) h = -h;
+ /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
+ if (ix < 0x40360000) { /* |x|<22 */
+ if (ix<0x3e300000) /* |x|<2**-28 */
+ if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
+ t = expm1(fabs(x));
+ if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one));
+ return h*(t+t/(t+one));
+ }
+
+ /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
+ if (ix < 0x40862E42) return h*__ieee754_exp(fabs(x));
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ GET_LOW_WORD(lx,x);
+ if (ix<0x408633CE || ((ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d))) {
+ w = __ieee754_exp(0.5*fabs(x));
+ t = h*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, sinh(x) overflow */
+ return x*shuge;
+}
diff --git a/lib/msun/src/e_sinhf.c b/lib/msun/src/e_sinhf.c
new file mode 100644
index 0000000..fc417de
--- /dev/null
+++ b/lib/msun/src/e_sinhf.c
@@ -0,0 +1,68 @@
+/* e_sinhf.c -- float version of e_sinh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one = 1.0, shuge = 1.0e37;
+#else
+static float one = 1.0, shuge = 1.0e37;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_sinhf(float x)
+#else
+ float __ieee754_sinhf(x)
+ float x;
+#endif
+{
+ float t,w,h;
+ int32_t ix,jx;
+
+ GET_FLOAT_WORD(jx,x);
+ ix = jx&0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7f800000) return x+x;
+
+ h = 0.5;
+ if (jx<0) h = -h;
+ /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
+ if (ix < 0x41b00000) { /* |x|<22 */
+ if (ix<0x31800000) /* |x|<2**-28 */
+ if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
+ t = expm1f(fabsf(x));
+ if(ix<0x3f800000) return h*((float)2.0*t-t*t/(t+one));
+ return h*(t+t/(t+one));
+ }
+
+ /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
+ if (ix < 0x42b17180) return h*__ieee754_expf(fabsf(x));
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ if (ix<=0x42b2d4fc) {
+ w = __ieee754_expf((float)0.5*fabsf(x));
+ t = h*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, sinh(x) overflow */
+ return x*shuge;
+}
diff --git a/lib/msun/src/e_sqrt.c b/lib/msun/src/e_sqrt.c
new file mode 100644
index 0000000..bea3b20
--- /dev/null
+++ b/lib/msun/src/e_sqrt.c
@@ -0,0 +1,453 @@
+/* @(#)e_sqrt.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __ieee754_sqrt(x)
+ * Return correctly rounded sqrt.
+ * ------------------------------------------
+ * | Use the hardware sqrt if you have one |
+ * ------------------------------------------
+ * Method:
+ * Bit by bit method using integer arithmetic. (Slow, but portable)
+ * 1. Normalization
+ * Scale x to y in [1,4) with even powers of 2:
+ * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
+ * sqrt(x) = 2^k * sqrt(y)
+ * 2. Bit by bit computation
+ * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
+ * i 0
+ * i+1 2
+ * s = 2*q , and y = 2 * ( y - q ). (1)
+ * i i i i
+ *
+ * To compute q from q , one checks whether
+ * i+1 i
+ *
+ * -(i+1) 2
+ * (q + 2 ) <= y. (2)
+ * i
+ * -(i+1)
+ * If (2) is false, then q = q ; otherwise q = q + 2 .
+ * i+1 i i+1 i
+ *
+ * With some algebric manipulation, it is not difficult to see
+ * that (2) is equivalent to
+ * -(i+1)
+ * s + 2 <= y (3)
+ * i i
+ *
+ * The advantage of (3) is that s and y can be computed by
+ * i i
+ * the following recurrence formula:
+ * if (3) is false
+ *
+ * s = s , y = y ; (4)
+ * i+1 i i+1 i
+ *
+ * otherwise,
+ * -i -(i+1)
+ * s = s + 2 , y = y - s - 2 (5)
+ * i+1 i i+1 i i
+ *
+ * One may easily use induction to prove (4) and (5).
+ * Note. Since the left hand side of (3) contain only i+2 bits,
+ * it does not necessary to do a full (53-bit) comparison
+ * in (3).
+ * 3. Final rounding
+ * After generating the 53 bits result, we compute one more bit.
+ * Together with the remainder, we can decide whether the
+ * result is exact, bigger than 1/2ulp, or less than 1/2ulp
+ * (it will never equal to 1/2ulp).
+ * The rounding mode can be detected by checking whether
+ * huge + tiny is equal to huge, and whether huge - tiny is
+ * equal to huge for some floating point number "huge" and "tiny".
+ *
+ * Special cases:
+ * sqrt(+-0) = +-0 ... exact
+ * sqrt(inf) = inf
+ * sqrt(-ve) = NaN ... with invalid signal
+ * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
+ *
+ * Other methods : see the appended file at the end of the program below.
+ *---------------
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one = 1.0, tiny=1.0e-300;
+#else
+static double one = 1.0, tiny=1.0e-300;
+#endif
+
+#ifdef __STDC__
+ double __generic___ieee754_sqrt(double x)
+#else
+ double __generic___ieee754_sqrt(x)
+ double x;
+#endif
+{
+ double z;
+ int32_t sign = (int)0x80000000;
+ int32_t ix0,s0,q,m,t,i;
+ u_int32_t r,t1,s1,ix1,q1;
+
+ EXTRACT_WORDS(ix0,ix1,x);
+
+ /* take care of Inf and NaN */
+ if((ix0&0x7ff00000)==0x7ff00000) {
+ return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
+ sqrt(-inf)=sNaN */
+ }
+ /* take care of zero */
+ if(ix0<=0) {
+ if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
+ else if(ix0<0)
+ return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
+ }
+ /* normalize x */
+ m = (ix0>>20);
+ if(m==0) { /* subnormal x */
+ while(ix0==0) {
+ m -= 21;
+ ix0 |= (ix1>>11); ix1 <<= 21;
+ }
+ for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
+ m -= i-1;
+ ix0 |= (ix1>>(32-i));
+ ix1 <<= i;
+ }
+ m -= 1023; /* unbias exponent */
+ ix0 = (ix0&0x000fffff)|0x00100000;
+ if(m&1){ /* odd m, double x to make it even */
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ }
+ m >>= 1; /* m = [m/2] */
+
+ /* generate sqrt(x) bit by bit */
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
+ r = 0x00200000; /* r = moving bit from right to left */
+
+ while(r!=0) {
+ t = s0+r;
+ if(t<=ix0) {
+ s0 = t+r;
+ ix0 -= t;
+ q += r;
+ }
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ r>>=1;
+ }
+
+ r = sign;
+ while(r!=0) {
+ t1 = s1+r;
+ t = s0;
+ if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
+ s1 = t1+r;
+ if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1;
+ ix0 -= t;
+ if (ix1 < t1) ix0 -= 1;
+ ix1 -= t1;
+ q1 += r;
+ }
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ r>>=1;
+ }
+
+ /* use floating add to find out rounding direction */
+ if((ix0|ix1)!=0) {
+ z = one-tiny; /* trigger inexact flag */
+ if (z>=one) {
+ z = one+tiny;
+ if (q1==(u_int32_t)0xffffffff) { q1=0; q += 1;}
+ else if (z>one) {
+ if (q1==(u_int32_t)0xfffffffe) q+=1;
+ q1+=2;
+ } else
+ q1 += (q1&1);
+ }
+ }
+ ix0 = (q>>1)+0x3fe00000;
+ ix1 = q1>>1;
+ if ((q&1)==1) ix1 |= sign;
+ ix0 += (m <<20);
+ INSERT_WORDS(z,ix0,ix1);
+ return z;
+}
+
+/*
+Other methods (use floating-point arithmetic)
+-------------
+(This is a copy of a drafted paper by Prof W. Kahan
+and K.C. Ng, written in May, 1986)
+
+ Two algorithms are given here to implement sqrt(x)
+ (IEEE double precision arithmetic) in software.
+ Both supply sqrt(x) correctly rounded. The first algorithm (in
+ Section A) uses newton iterations and involves four divisions.
+ The second one uses reciproot iterations to avoid division, but
+ requires more multiplications. Both algorithms need the ability
+ to chop results of arithmetic operations instead of round them,
+ and the INEXACT flag to indicate when an arithmetic operation
+ is executed exactly with no roundoff error, all part of the
+ standard (IEEE 754-1985). The ability to perform shift, add,
+ subtract and logical AND operations upon 32-bit words is needed
+ too, though not part of the standard.
+
+A. sqrt(x) by Newton Iteration
+
+ (1) Initial approximation
+
+ Let x0 and x1 be the leading and the trailing 32-bit words of
+ a floating point number x (in IEEE double format) respectively
+
+ 1 11 52 ...widths
+ ------------------------------------------------------
+ x: |s| e | f |
+ ------------------------------------------------------
+ msb lsb msb lsb ...order
+
+
+ ------------------------ ------------------------
+ x0: |s| e | f1 | x1: | f2 |
+ ------------------------ ------------------------
+
+ By performing shifts and subtracts on x0 and x1 (both regarded
+ as integers), we obtain an 8-bit approximation of sqrt(x) as
+ follows.
+
+ k := (x0>>1) + 0x1ff80000;
+ y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
+ Here k is a 32-bit integer and T1[] is an integer array containing
+ correction terms. Now magically the floating value of y (y's
+ leading 32-bit word is y0, the value of its trailing word is 0)
+ approximates sqrt(x) to almost 8-bit.
+
+ Value of T1:
+ static int T1[32]= {
+ 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592,
+ 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215,
+ 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581,
+ 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,};
+
+ (2) Iterative refinement
+
+ Apply Heron's rule three times to y, we have y approximates
+ sqrt(x) to within 1 ulp (Unit in the Last Place):
+
+ y := (y+x/y)/2 ... almost 17 sig. bits
+ y := (y+x/y)/2 ... almost 35 sig. bits
+ y := y-(y-x/y)/2 ... within 1 ulp
+
+
+ Remark 1.
+ Another way to improve y to within 1 ulp is:
+
+ y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x)
+ y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x)
+
+ 2
+ (x-y )*y
+ y := y + 2* ---------- ...within 1 ulp
+ 2
+ 3y + x
+
+
+ This formula has one division fewer than the one above; however,
+ it requires more multiplications and additions. Also x must be
+ scaled in advance to avoid spurious overflow in evaluating the
+ expression 3y*y+x. Hence it is not recommended uless division
+ is slow. If division is very slow, then one should use the
+ reciproot algorithm given in section B.
+
+ (3) Final adjustment
+
+ By twiddling y's last bit it is possible to force y to be
+ correctly rounded according to the prevailing rounding mode
+ as follows. Let r and i be copies of the rounding mode and
+ inexact flag before entering the square root program. Also we
+ use the expression y+-ulp for the next representable floating
+ numbers (up and down) of y. Note that y+-ulp = either fixed
+ point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+ mode.
+
+ I := FALSE; ... reset INEXACT flag I
+ R := RZ; ... set rounding mode to round-toward-zero
+ z := x/y; ... chopped quotient, possibly inexact
+ If(not I) then { ... if the quotient is exact
+ if(z=y) {
+ I := i; ... restore inexact flag
+ R := r; ... restore rounded mode
+ return sqrt(x):=y.
+ } else {
+ z := z - ulp; ... special rounding
+ }
+ }
+ i := TRUE; ... sqrt(x) is inexact
+ If (r=RN) then z=z+ulp ... rounded-to-nearest
+ If (r=RP) then { ... round-toward-+inf
+ y = y+ulp; z=z+ulp;
+ }
+ y := y+z; ... chopped sum
+ y0:=y0-0x00100000; ... y := y/2 is correctly rounded.
+ I := i; ... restore inexact flag
+ R := r; ... restore rounded mode
+ return sqrt(x):=y.
+
+ (4) Special cases
+
+ Square root of +inf, +-0, or NaN is itself;
+ Square root of a negative number is NaN with invalid signal.
+
+
+B. sqrt(x) by Reciproot Iteration
+
+ (1) Initial approximation
+
+ Let x0 and x1 be the leading and the trailing 32-bit words of
+ a floating point number x (in IEEE double format) respectively
+ (see section A). By performing shifs and subtracts on x0 and y0,
+ we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.
+
+ k := 0x5fe80000 - (x0>>1);
+ y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits
+
+ Here k is a 32-bit integer and T2[] is an integer array
+ containing correction terms. Now magically the floating
+ value of y (y's leading 32-bit word is y0, the value of
+ its trailing word y1 is set to zero) approximates 1/sqrt(x)
+ to almost 7.8-bit.
+
+ Value of T2:
+ static int T2[64]= {
+ 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866,
+ 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
+ 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
+ 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
+ 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
+ 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
+ 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
+ 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,};
+
+ (2) Iterative refinement
+
+ Apply Reciproot iteration three times to y and multiply the
+ result by x to get an approximation z that matches sqrt(x)
+ to about 1 ulp. To be exact, we will have
+ -1ulp < sqrt(x)-z<1.0625ulp.
+
+ ... set rounding mode to Round-to-nearest
+ y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x)
+ y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x)
+ ... special arrangement for better accuracy
+ z := x*y ... 29 bits to sqrt(x), with z*y<1
+ z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x)
+
+ Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that
+ (a) the term z*y in the final iteration is always less than 1;
+ (b) the error in the final result is biased upward so that
+ -1 ulp < sqrt(x) - z < 1.0625 ulp
+ instead of |sqrt(x)-z|<1.03125ulp.
+
+ (3) Final adjustment
+
+ By twiddling y's last bit it is possible to force y to be
+ correctly rounded according to the prevailing rounding mode
+ as follows. Let r and i be copies of the rounding mode and
+ inexact flag before entering the square root program. Also we
+ use the expression y+-ulp for the next representable floating
+ numbers (up and down) of y. Note that y+-ulp = either fixed
+ point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+ mode.
+
+ R := RZ; ... set rounding mode to round-toward-zero
+ switch(r) {
+ case RN: ... round-to-nearest
+ if(x<= z*(z-ulp)...chopped) z = z - ulp; else
+ if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
+ break;
+ case RZ:case RM: ... round-to-zero or round-to--inf
+ R:=RP; ... reset rounding mod to round-to-+inf
+ if(x<z*z ... rounded up) z = z - ulp; else
+ if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
+ break;
+ case RP: ... round-to-+inf
+ if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
+ if(x>z*z ...chopped) z = z+ulp;
+ break;
+ }
+
+ Remark 3. The above comparisons can be done in fixed point. For
+ example, to compare x and w=z*z chopped, it suffices to compare
+ x1 and w1 (the trailing parts of x and w), regarding them as
+ two's complement integers.
+
+ ...Is z an exact square root?
+ To determine whether z is an exact square root of x, let z1 be the
+ trailing part of z, and also let x0 and x1 be the leading and
+ trailing parts of x.
+
+ If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0
+ I := 1; ... Raise Inexact flag: z is not exact
+ else {
+ j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2
+ k := z1 >> 26; ... get z's 25-th and 26-th
+ fraction bits
+ I := i or (k&j) or ((k&(j+j+1))!=(x1&3));
+ }
+ R:= r ... restore rounded mode
+ return sqrt(x):=z.
+
+ If multiplication is cheaper then the foregoing red tape, the
+ Inexact flag can be evaluated by
+
+ I := i;
+ I := (z*z!=x) or I.
+
+ Note that z*z can overwrite I; this value must be sensed if it is
+ True.
+
+ Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
+ zero.
+
+ --------------------
+ z1: | f2 |
+ --------------------
+ bit 31 bit 0
+
+ Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
+ or even of logb(x) have the following relations:
+
+ -------------------------------------------------
+ bit 27,26 of z1 bit 1,0 of x1 logb(x)
+ -------------------------------------------------
+ 00 00 odd and even
+ 01 01 even
+ 10 10 odd
+ 10 00 even
+ 11 01 even
+ -------------------------------------------------
+
+ (4) Special cases (see (4) of Section A).
+
+ */
+
diff --git a/lib/msun/src/e_sqrtf.c b/lib/msun/src/e_sqrtf.c
new file mode 100644
index 0000000..b7e7d61
--- /dev/null
+++ b/lib/msun/src/e_sqrtf.c
@@ -0,0 +1,97 @@
+/* e_sqrtf.c -- float version of e_sqrt.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one = 1.0, tiny=1.0e-30;
+#else
+static float one = 1.0, tiny=1.0e-30;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_sqrtf(float x)
+#else
+ float __ieee754_sqrtf(x)
+ float x;
+#endif
+{
+ float z;
+ int32_t sign = (int)0x80000000;
+ int32_t ix,s,q,m,t,i;
+ u_int32_t r;
+
+ GET_FLOAT_WORD(ix,x);
+
+ /* take care of Inf and NaN */
+ if((ix&0x7f800000)==0x7f800000) {
+ return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
+ sqrt(-inf)=sNaN */
+ }
+ /* take care of zero */
+ if(ix<=0) {
+ if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */
+ else if(ix<0)
+ return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
+ }
+ /* normalize x */
+ m = (ix>>23);
+ if(m==0) { /* subnormal x */
+ for(i=0;(ix&0x00800000)==0;i++) ix<<=1;
+ m -= i-1;
+ }
+ m -= 127; /* unbias exponent */
+ ix = (ix&0x007fffff)|0x00800000;
+ if(m&1) /* odd m, double x to make it even */
+ ix += ix;
+ m >>= 1; /* m = [m/2] */
+
+ /* generate sqrt(x) bit by bit */
+ ix += ix;
+ q = s = 0; /* q = sqrt(x) */
+ r = 0x01000000; /* r = moving bit from right to left */
+
+ while(r!=0) {
+ t = s+r;
+ if(t<=ix) {
+ s = t+r;
+ ix -= t;
+ q += r;
+ }
+ ix += ix;
+ r>>=1;
+ }
+
+ /* use floating add to find out rounding direction */
+ if(ix!=0) {
+ z = one-tiny; /* trigger inexact flag */
+ if (z>=one) {
+ z = one+tiny;
+ if (z>one)
+ q += 2;
+ else
+ q += (q&1);
+ }
+ }
+ ix = (q>>1)+0x3f000000;
+ ix += (m <<23);
+ SET_FLOAT_WORD(z,ix);
+ return z;
+}
diff --git a/lib/msun/src/get_hw_float.c b/lib/msun/src/get_hw_float.c
new file mode 100644
index 0000000..ffa9d70
--- /dev/null
+++ b/lib/msun/src/get_hw_float.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1997 Bruce D. Evans
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+int __get_hw_float __P((void));
+
+static int hw_float = -1;
+
+int
+__get_hw_float()
+{
+ size_t len;
+ int mib[2];
+
+ if (hw_float == -1) {
+ len = sizeof(hw_float);
+ mib[0] = CTL_HW;
+ mib[1] = HW_FLOATINGPT;
+ if (__sysctl(mib, 2, &hw_float, &len, (void *)0, 0) == -1)
+ hw_float = 0; /* shouldn't happen; assume the worst */
+ }
+ return (hw_float);
+}
diff --git a/lib/msun/src/k_cos.c b/lib/msun/src/k_cos.c
new file mode 100644
index 0000000..1694c3f
--- /dev/null
+++ b/lib/msun/src/k_cos.c
@@ -0,0 +1,96 @@
+/* @(#)k_cos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * __kernel_cos( x, y )
+ * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ *
+ * Algorithm
+ * 1. Since cos(-x) = cos(x), we need only to consider positive x.
+ * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
+ * 3. cos(x) is approximated by a polynomial of degree 14 on
+ * [0,pi/4]
+ * 4 14
+ * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
+ * where the remez error is
+ *
+ * | 2 4 6 8 10 12 14 | -58
+ * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2
+ * | |
+ *
+ * 4 6 8 10 12 14
+ * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then
+ * cos(x) = 1 - x*x/2 + r
+ * since cos(x+y) ~ cos(x) - sin(x)*y
+ * ~ cos(x) - x*y,
+ * a correction term is necessary in cos(x) and hence
+ * cos(x+y) = 1 - (x*x/2 - (r - x*y))
+ * For better accuracy when x > 0.3, let qx = |x|/4 with
+ * the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
+ * Then
+ * cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)).
+ * Note that 1-qx and (x*x/2-qx) is EXACT here, and the
+ * magnitude of the latter is at least a quarter of x*x/2,
+ * thus, reducing the rounding error in the subtraction.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
+C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
+C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
+C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
+C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
+C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
+
+#ifdef __STDC__
+ double __kernel_cos(double x, double y)
+#else
+ double __kernel_cos(x, y)
+ double x,y;
+#endif
+{
+ double a,hz,z,r,qx;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff; /* ix = |x|'s high word*/
+ if(ix<0x3e400000) { /* if x < 2**27 */
+ if(((int)x)==0) return one; /* generate inexact */
+ }
+ z = x*x;
+ r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
+ if(ix < 0x3FD33333) /* if |x| < 0.3 */
+ return one - (0.5*z - (z*r - x*y));
+ else {
+ if(ix > 0x3fe90000) { /* x > 0.78125 */
+ qx = 0.28125;
+ } else {
+ INSERT_WORDS(qx,ix-0x00200000,0); /* x/4 */
+ }
+ hz = 0.5*z-qx;
+ a = one-qx;
+ return a - (hz - (z*r-x*y));
+ }
+}
diff --git a/lib/msun/src/k_cosf.c b/lib/msun/src/k_cosf.c
new file mode 100644
index 0000000..fb49a6b
--- /dev/null
+++ b/lib/msun/src/k_cosf.c
@@ -0,0 +1,64 @@
+/* k_cosf.c -- float version of k_cos.c
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0000000000e+00, /* 0x3f800000 */
+C1 = 4.1666667908e-02, /* 0x3d2aaaab */
+C2 = -1.3888889225e-03, /* 0xbab60b61 */
+C3 = 2.4801587642e-05, /* 0x37d00d01 */
+C4 = -2.7557314297e-07, /* 0xb493f27c */
+C5 = 2.0875723372e-09, /* 0x310f74f6 */
+C6 = -1.1359647598e-11; /* 0xad47d74e */
+
+#ifdef __STDC__
+ float __kernel_cosf(float x, float y)
+#else
+ float __kernel_cosf(x, y)
+ float x,y;
+#endif
+{
+ float a,hz,z,r,qx;
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff; /* ix = |x|'s high word*/
+ if(ix<0x32000000) { /* if x < 2**27 */
+ if(((int)x)==0) return one; /* generate inexact */
+ }
+ z = x*x;
+ r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
+ if(ix < 0x3e99999a) /* if |x| < 0.3 */
+ return one - ((float)0.5*z - (z*r - x*y));
+ else {
+ if(ix > 0x3f480000) { /* x > 0.78125 */
+ qx = (float)0.28125;
+ } else {
+ SET_FLOAT_WORD(qx,ix-0x01000000); /* x/4 */
+ }
+ hz = (float)0.5*z-qx;
+ a = one-qx;
+ return a - (hz - (z*r-x*y));
+ }
+}
diff --git a/lib/msun/src/k_rem_pio2.c b/lib/msun/src/k_rem_pio2.c
new file mode 100644
index 0000000..8971a84
--- /dev/null
+++ b/lib/msun/src/k_rem_pio2.c
@@ -0,0 +1,320 @@
+/* @(#)k_rem_pio2.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
+ * double x[],y[]; int e0,nx,prec; int ipio2[];
+ *
+ * __kernel_rem_pio2 return the last three digits of N with
+ * y = x - N*pi/2
+ * so that |y| < pi/2.
+ *
+ * The method is to compute the integer (mod 8) and fraction parts of
+ * (2/pi)*x without doing the full multiplication. In general we
+ * skip the part of the product that are known to be a huge integer (
+ * more accurately, = 0 mod 8 ). Thus the number of operations are
+ * independent of the exponent of the input.
+ *
+ * (2/pi) is represented by an array of 24-bit integers in ipio2[].
+ *
+ * Input parameters:
+ * x[] The input value (must be positive) is broken into nx
+ * pieces of 24-bit integers in double precision format.
+ * x[i] will be the i-th 24 bit of x. The scaled exponent
+ * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
+ * match x's up to 24 bits.
+ *
+ * Example of breaking a double positive z into x[0]+x[1]+x[2]:
+ * e0 = ilogb(z)-23
+ * z = scalbn(z,-e0)
+ * for i = 0,1,2
+ * x[i] = floor(z)
+ * z = (z-x[i])*2**24
+ *
+ *
+ * y[] ouput result in an array of double precision numbers.
+ * The dimension of y[] is:
+ * 24-bit precision 1
+ * 53-bit precision 2
+ * 64-bit precision 2
+ * 113-bit precision 3
+ * The actual value is the sum of them. Thus for 113-bit
+ * precison, one may have to do something like:
+ *
+ * long double t,w,r_head, r_tail;
+ * t = (long double)y[2] + (long double)y[1];
+ * w = (long double)y[0];
+ * r_head = t+w;
+ * r_tail = w - (r_head - t);
+ *
+ * e0 The exponent of x[0]
+ *
+ * nx dimension of x[]
+ *
+ * prec an integer indicating the precision:
+ * 0 24 bits (single)
+ * 1 53 bits (double)
+ * 2 64 bits (extended)
+ * 3 113 bits (quad)
+ *
+ * ipio2[]
+ * integer array, contains the (24*i)-th to (24*i+23)-th
+ * bit of 2/pi after binary point. The corresponding
+ * floating value is
+ *
+ * ipio2[i] * 2^(-24(i+1)).
+ *
+ * External function:
+ * double scalbn(), floor();
+ *
+ *
+ * Here is the description of some local variables:
+ *
+ * jk jk+1 is the initial number of terms of ipio2[] needed
+ * in the computation. The recommended value is 2,3,4,
+ * 6 for single, double, extended,and quad.
+ *
+ * jz local integer variable indicating the number of
+ * terms of ipio2[] used.
+ *
+ * jx nx - 1
+ *
+ * jv index for pointing to the suitable ipio2[] for the
+ * computation. In general, we want
+ * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
+ * is an integer. Thus
+ * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
+ * Hence jv = max(0,(e0-3)/24).
+ *
+ * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
+ *
+ * q[] double array with integral value, representing the
+ * 24-bits chunk of the product of x and 2/pi.
+ *
+ * q0 the corresponding exponent of q[0]. Note that the
+ * exponent for q[i] would be q0-24*i.
+ *
+ * PIo2[] double precision array, obtained by cutting pi/2
+ * into 24 bits chunks.
+ *
+ * f[] ipio2[] in floating point
+ *
+ * iq[] integer array by breaking up q[] in 24-bits chunk.
+ *
+ * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
+ *
+ * ih integer. If >0 it indicates q[] is >= 0.5, hence
+ * it also indicates the *sign* of the result.
+ *
+ */
+
+
+/*
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
+#else
+static int init_jk[] = {2,3,4,6};
+#endif
+
+#ifdef __STDC__
+static const double PIo2[] = {
+#else
+static double PIo2[] = {
+#endif
+ 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
+ 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
+ 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
+ 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
+ 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
+ 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
+ 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
+ 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
+};
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+zero = 0.0,
+one = 1.0,
+two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
+
+#ifdef __STDC__
+ int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int32_t *ipio2)
+#else
+ int __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
+ double x[], y[]; int e0,nx,prec; int32_t ipio2[];
+#endif
+{
+ int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
+ double z,fw,f[20],fq[20],q[20];
+
+ /* initialize jk*/
+ jk = init_jk[prec];
+ jp = jk;
+
+ /* determine jx,jv,q0, note that 3>q0 */
+ jx = nx-1;
+ jv = (e0-3)/24; if(jv<0) jv=0;
+ q0 = e0-24*(jv+1);
+
+ /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
+ j = jv-jx; m = jx+jk;
+ for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
+
+ /* compute q[0],q[1],...q[jk] */
+ for (i=0;i<=jk;i++) {
+ for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
+ }
+
+ jz = jk;
+recompute:
+ /* distill q[] into iq[] reversingly */
+ for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
+ fw = (double)((int32_t)(twon24* z));
+ iq[i] = (int32_t)(z-two24*fw);
+ z = q[j-1]+fw;
+ }
+
+ /* compute n */
+ z = scalbn(z,q0); /* actual value of z */
+ z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
+ n = (int32_t) z;
+ z -= (double)n;
+ ih = 0;
+ if(q0>0) { /* need iq[jz-1] to determine n */
+ i = (iq[jz-1]>>(24-q0)); n += i;
+ iq[jz-1] -= i<<(24-q0);
+ ih = iq[jz-1]>>(23-q0);
+ }
+ else if(q0==0) ih = iq[jz-1]>>23;
+ else if(z>=0.5) ih=2;
+
+ if(ih>0) { /* q > 0.5 */
+ n += 1; carry = 0;
+ for(i=0;i<jz ;i++) { /* compute 1-q */
+ j = iq[i];
+ if(carry==0) {
+ if(j!=0) {
+ carry = 1; iq[i] = 0x1000000- j;
+ }
+ } else iq[i] = 0xffffff - j;
+ }
+ if(q0>0) { /* rare case: chance is 1 in 12 */
+ switch(q0) {
+ case 1:
+ iq[jz-1] &= 0x7fffff; break;
+ case 2:
+ iq[jz-1] &= 0x3fffff; break;
+ }
+ }
+ if(ih==2) {
+ z = one - z;
+ if(carry!=0) z -= scalbn(one,q0);
+ }
+ }
+
+ /* check if recomputation is needed */
+ if(z==zero) {
+ j = 0;
+ for (i=jz-1;i>=jk;i--) j |= iq[i];
+ if(j==0) { /* need recomputation */
+ for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */
+
+ for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */
+ f[jx+i] = (double) ipio2[jv+i];
+ for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
+ q[i] = fw;
+ }
+ jz += k;
+ goto recompute;
+ }
+ }
+
+ /* chop off zero terms */
+ if(z==0.0) {
+ jz -= 1; q0 -= 24;
+ while(iq[jz]==0) { jz--; q0-=24;}
+ } else { /* break z into 24-bit if necessary */
+ z = scalbn(z,-q0);
+ if(z>=two24) {
+ fw = (double)((int32_t)(twon24*z));
+ iq[jz] = (int32_t)(z-two24*fw);
+ jz += 1; q0 += 24;
+ iq[jz] = (int32_t) fw;
+ } else iq[jz] = (int32_t) z ;
+ }
+
+ /* convert integer "bit" chunk to floating-point value */
+ fw = scalbn(one,q0);
+ for(i=jz;i>=0;i--) {
+ q[i] = fw*(double)iq[i]; fw*=twon24;
+ }
+
+ /* compute PIo2[0,...,jp]*q[jz,...,0] */
+ for(i=jz;i>=0;i--) {
+ for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
+ fq[jz-i] = fw;
+ }
+
+ /* compress fq[] into y[] */
+ switch(prec) {
+ case 0:
+ fw = 0.0;
+ for (i=jz;i>=0;i--) fw += fq[i];
+ y[0] = (ih==0)? fw: -fw;
+ break;
+ case 1:
+ case 2:
+ fw = 0.0;
+ for (i=jz;i>=0;i--) fw += fq[i];
+ y[0] = (ih==0)? fw: -fw;
+ fw = fq[0]-fw;
+ for (i=1;i<=jz;i++) fw += fq[i];
+ y[1] = (ih==0)? fw: -fw;
+ break;
+ case 3: /* painful */
+ for (i=jz;i>0;i--) {
+ fw = fq[i-1]+fq[i];
+ fq[i] += fq[i-1]-fw;
+ fq[i-1] = fw;
+ }
+ for (i=jz;i>1;i--) {
+ fw = fq[i-1]+fq[i];
+ fq[i] += fq[i-1]-fw;
+ fq[i-1] = fw;
+ }
+ for (fw=0.0,i=jz;i>=2;i--) fw += fq[i];
+ if(ih==0) {
+ y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
+ } else {
+ y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
+ }
+ }
+ return n&7;
+}
diff --git a/lib/msun/src/k_rem_pio2f.c b/lib/msun/src/k_rem_pio2f.c
new file mode 100644
index 0000000..0014497
--- /dev/null
+++ b/lib/msun/src/k_rem_pio2f.c
@@ -0,0 +1,213 @@
+/* k_rem_pio2f.c -- float version of k_rem_pio2.c
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+/* In the float version, the input parameter x contains 8 bit
+ integers, not 24 bit integers. 113 bit precision is not supported. */
+
+#ifdef __STDC__
+static const int init_jk[] = {4,7,9}; /* initial value for jk */
+#else
+static int init_jk[] = {4,7,9};
+#endif
+
+#ifdef __STDC__
+static const float PIo2[] = {
+#else
+static float PIo2[] = {
+#endif
+ 1.5703125000e+00, /* 0x3fc90000 */
+ 4.5776367188e-04, /* 0x39f00000 */
+ 2.5987625122e-05, /* 0x37da0000 */
+ 7.5437128544e-08, /* 0x33a20000 */
+ 6.0026650317e-11, /* 0x2e840000 */
+ 7.3896444519e-13, /* 0x2b500000 */
+ 5.3845816694e-15, /* 0x27c20000 */
+ 5.6378512969e-18, /* 0x22d00000 */
+ 8.3009228831e-20, /* 0x1fc40000 */
+ 3.2756352257e-22, /* 0x1bc60000 */
+ 6.3331015649e-25, /* 0x17440000 */
+};
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+zero = 0.0,
+one = 1.0,
+two8 = 2.5600000000e+02, /* 0x43800000 */
+twon8 = 3.9062500000e-03; /* 0x3b800000 */
+
+#ifdef __STDC__
+ int __kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const int32_t *ipio2)
+#else
+ int __kernel_rem_pio2f(x,y,e0,nx,prec,ipio2)
+ float x[], y[]; int e0,nx,prec; int32_t ipio2[];
+#endif
+{
+ int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
+ float z,fw,f[20],fq[20],q[20];
+
+ /* initialize jk*/
+ jk = init_jk[prec];
+ jp = jk;
+
+ /* determine jx,jv,q0, note that 3>q0 */
+ jx = nx-1;
+ jv = (e0-3)/8; if(jv<0) jv=0;
+ q0 = e0-8*(jv+1);
+
+ /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
+ j = jv-jx; m = jx+jk;
+ for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (float) ipio2[j];
+
+ /* compute q[0],q[1],...q[jk] */
+ for (i=0;i<=jk;i++) {
+ for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
+ }
+
+ jz = jk;
+recompute:
+ /* distill q[] into iq[] reversingly */
+ for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
+ fw = (float)((int32_t)(twon8* z));
+ iq[i] = (int32_t)(z-two8*fw);
+ z = q[j-1]+fw;
+ }
+
+ /* compute n */
+ z = scalbnf(z,q0); /* actual value of z */
+ z -= (float)8.0*floorf(z*(float)0.125); /* trim off integer >= 8 */
+ n = (int32_t) z;
+ z -= (float)n;
+ ih = 0;
+ if(q0>0) { /* need iq[jz-1] to determine n */
+ i = (iq[jz-1]>>(8-q0)); n += i;
+ iq[jz-1] -= i<<(8-q0);
+ ih = iq[jz-1]>>(7-q0);
+ }
+ else if(q0==0) ih = iq[jz-1]>>8;
+ else if(z>=(float)0.5) ih=2;
+
+ if(ih>0) { /* q > 0.5 */
+ n += 1; carry = 0;
+ for(i=0;i<jz ;i++) { /* compute 1-q */
+ j = iq[i];
+ if(carry==0) {
+ if(j!=0) {
+ carry = 1; iq[i] = 0x100- j;
+ }
+ } else iq[i] = 0xff - j;
+ }
+ if(q0>0) { /* rare case: chance is 1 in 12 */
+ switch(q0) {
+ case 1:
+ iq[jz-1] &= 0x7f; break;
+ case 2:
+ iq[jz-1] &= 0x3f; break;
+ }
+ }
+ if(ih==2) {
+ z = one - z;
+ if(carry!=0) z -= scalbnf(one,q0);
+ }
+ }
+
+ /* check if recomputation is needed */
+ if(z==zero) {
+ j = 0;
+ for (i=jz-1;i>=jk;i--) j |= iq[i];
+ if(j==0) { /* need recomputation */
+ for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */
+
+ for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */
+ f[jx+i] = (float) ipio2[jv+i];
+ for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
+ q[i] = fw;
+ }
+ jz += k;
+ goto recompute;
+ }
+ }
+
+ /* chop off zero terms */
+ if(z==(float)0.0) {
+ jz -= 1; q0 -= 8;
+ while(iq[jz]==0) { jz--; q0-=8;}
+ } else { /* break z into 8-bit if necessary */
+ z = scalbnf(z,-q0);
+ if(z>=two8) {
+ fw = (float)((int32_t)(twon8*z));
+ iq[jz] = (int32_t)(z-two8*fw);
+ jz += 1; q0 += 8;
+ iq[jz] = (int32_t) fw;
+ } else iq[jz] = (int32_t) z ;
+ }
+
+ /* convert integer "bit" chunk to floating-point value */
+ fw = scalbnf(one,q0);
+ for(i=jz;i>=0;i--) {
+ q[i] = fw*(float)iq[i]; fw*=twon8;
+ }
+
+ /* compute PIo2[0,...,jp]*q[jz,...,0] */
+ for(i=jz;i>=0;i--) {
+ for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
+ fq[jz-i] = fw;
+ }
+
+ /* compress fq[] into y[] */
+ switch(prec) {
+ case 0:
+ fw = 0.0;
+ for (i=jz;i>=0;i--) fw += fq[i];
+ y[0] = (ih==0)? fw: -fw;
+ break;
+ case 1:
+ case 2:
+ fw = 0.0;
+ for (i=jz;i>=0;i--) fw += fq[i];
+ y[0] = (ih==0)? fw: -fw;
+ fw = fq[0]-fw;
+ for (i=1;i<=jz;i++) fw += fq[i];
+ y[1] = (ih==0)? fw: -fw;
+ break;
+ case 3: /* painful */
+ for (i=jz;i>0;i--) {
+ fw = fq[i-1]+fq[i];
+ fq[i] += fq[i-1]-fw;
+ fq[i-1] = fw;
+ }
+ for (i=jz;i>1;i--) {
+ fw = fq[i-1]+fq[i];
+ fq[i] += fq[i-1]-fw;
+ fq[i-1] = fw;
+ }
+ for (fw=0.0,i=jz;i>=2;i--) fw += fq[i];
+ if(ih==0) {
+ y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
+ } else {
+ y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
+ }
+ }
+ return n&7;
+}
diff --git a/lib/msun/src/k_sin.c b/lib/msun/src/k_sin.c
new file mode 100644
index 0000000..df2dc26
--- /dev/null
+++ b/lib/msun/src/k_sin.c
@@ -0,0 +1,79 @@
+/* @(#)k_sin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __kernel_sin( x, y, iy)
+ * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
+ *
+ * Algorithm
+ * 1. Since sin(-x) = -sin(x), we need only to consider positive x.
+ * 2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0.
+ * 3. sin(x) is approximated by a polynomial of degree 13 on
+ * [0,pi/4]
+ * 3 13
+ * sin(x) ~ x + S1*x + ... + S6*x
+ * where
+ *
+ * |sin(x) 2 4 6 8 10 12 | -58
+ * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2
+ * | x |
+ *
+ * 4. sin(x+y) = sin(x) + sin'(x')*y
+ * ~ sin(x) + (1-x*x/2)*y
+ * For better accuracy, let
+ * 3 2 2 2 2
+ * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
+ * then 3 2
+ * sin(x) = x + (S1*x + (x *(r-y/2)+y))
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
+S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
+S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
+S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
+S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
+S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
+
+#ifdef __STDC__
+ double __kernel_sin(double x, double y, int iy)
+#else
+ double __kernel_sin(x, y, iy)
+ double x,y; int iy; /* iy=0 if y is zero */
+#endif
+{
+ double z,r,v;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff; /* high word of x */
+ if(ix<0x3e400000) /* |x| < 2**-27 */
+ {if((int)x==0) return x;} /* generate inexact */
+ z = x*x;
+ v = z*x;
+ r = S2+z*(S3+z*(S4+z*(S5+z*S6)));
+ if(iy==0) return x+v*(S1+z*r);
+ else return x-((z*(half*y-v*r)-y)-v*S1);
+}
diff --git a/lib/msun/src/k_sinf.c b/lib/msun/src/k_sinf.c
new file mode 100644
index 0000000..ab81d4d
--- /dev/null
+++ b/lib/msun/src/k_sinf.c
@@ -0,0 +1,54 @@
+/* k_sinf.c -- float version of k_sin.c
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+half = 5.0000000000e-01,/* 0x3f000000 */
+S1 = -1.6666667163e-01, /* 0xbe2aaaab */
+S2 = 8.3333337680e-03, /* 0x3c088889 */
+S3 = -1.9841270114e-04, /* 0xb9500d01 */
+S4 = 2.7557314297e-06, /* 0x3638ef1b */
+S5 = -2.5050759689e-08, /* 0xb2d72f34 */
+S6 = 1.5896910177e-10; /* 0x2f2ec9d3 */
+
+#ifdef __STDC__
+ float __kernel_sinf(float x, float y, int iy)
+#else
+ float __kernel_sinf(x, y, iy)
+ float x,y; int iy; /* iy=0 if y is zero */
+#endif
+{
+ float z,r,v;
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff; /* high word of x */
+ if(ix<0x32000000) /* |x| < 2**-27 */
+ {if((int)x==0) return x;} /* generate inexact */
+ z = x*x;
+ v = z*x;
+ r = S2+z*(S3+z*(S4+z*(S5+z*S6)));
+ if(iy==0) return x+v*(S1+z*r);
+ else return x-((z*(half*y-v*r)-y)-v*S1);
+}
diff --git a/lib/msun/src/k_standard.c b/lib/msun/src/k_standard.c
new file mode 100644
index 0000000..2b62052
--- /dev/null
+++ b/lib/msun/src/k_standard.c
@@ -0,0 +1,782 @@
+/* @(#)k_standard.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+#include <errno.h>
+
+#ifndef _USE_WRITE
+#include <stdio.h> /* fputs(), stderr */
+#define WRITE2(u,v) fputs(u, stderr)
+#else /* !defined(_USE_WRITE) */
+#include <unistd.h> /* write */
+#define WRITE2(u,v) write(2, u, v)
+#undef fflush
+#endif /* !defined(_USE_WRITE) */
+
+#ifdef __STDC__
+static const double zero = 0.0; /* used as const */
+#else
+static double zero = 0.0; /* used as const */
+#endif
+
+/*
+ * Standard conformance (non-IEEE) on exception cases.
+ * Mapping:
+ * 1 -- acos(|x|>1)
+ * 2 -- asin(|x|>1)
+ * 3 -- atan2(+-0,+-0)
+ * 4 -- hypot overflow
+ * 5 -- cosh overflow
+ * 6 -- exp overflow
+ * 7 -- exp underflow
+ * 8 -- y0(0)
+ * 9 -- y0(-ve)
+ * 10-- y1(0)
+ * 11-- y1(-ve)
+ * 12-- yn(0)
+ * 13-- yn(-ve)
+ * 14-- lgamma(finite) overflow
+ * 15-- lgamma(-integer)
+ * 16-- log(0)
+ * 17-- log(x<0)
+ * 18-- log10(0)
+ * 19-- log10(x<0)
+ * 20-- pow(0.0,0.0)
+ * 21-- pow(x,y) overflow
+ * 22-- pow(x,y) underflow
+ * 23-- pow(0,negative)
+ * 24-- pow(neg,non-integral)
+ * 25-- sinh(finite) overflow
+ * 26-- sqrt(negative)
+ * 27-- fmod(x,0)
+ * 28-- remainder(x,0)
+ * 29-- acosh(x<1)
+ * 30-- atanh(|x|>1)
+ * 31-- atanh(|x|=1)
+ * 32-- scalb overflow
+ * 33-- scalb underflow
+ * 34-- j0(|x|>X_TLOSS)
+ * 35-- y0(x>X_TLOSS)
+ * 36-- j1(|x|>X_TLOSS)
+ * 37-- y1(x>X_TLOSS)
+ * 38-- jn(|x|>X_TLOSS, n)
+ * 39-- yn(x>X_TLOSS, n)
+ * 40-- gamma(finite) overflow
+ * 41-- gamma(-integer)
+ * 42-- pow(NaN,0.0)
+ */
+
+
+#ifdef __STDC__
+ double __kernel_standard(double x, double y, int type)
+#else
+ double __kernel_standard(x,y,type)
+ double x,y; int type;
+#endif
+{
+ struct exception exc;
+#ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */
+#define HUGE_VAL inf
+ double inf = 0.0;
+
+ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */
+#endif
+
+#ifdef _USE_WRITE
+ (void) fflush(stdout);
+#endif
+ exc.arg1 = x;
+ exc.arg2 = y;
+ switch(type) {
+ case 1:
+ case 101:
+ /* acos(|x|>1) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "acos" : "acosf";
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if(_LIB_VERSION == _SVID_) {
+ (void) WRITE2("acos: DOMAIN error\n", 19);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 2:
+ case 102:
+ /* asin(|x|>1) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "asin" : "asinf";
+ exc.retval = zero;
+ if(_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if(_LIB_VERSION == _SVID_) {
+ (void) WRITE2("asin: DOMAIN error\n", 19);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 3:
+ case 103:
+ /* atan2(+-0,+-0) */
+ exc.arg1 = y;
+ exc.arg2 = x;
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "atan2" : "atan2f";
+ exc.retval = zero;
+ if(_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if(_LIB_VERSION == _SVID_) {
+ (void) WRITE2("atan2: DOMAIN error\n", 20);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 4:
+ case 104:
+ /* hypot(finite,finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "hypot" : "hypotf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ break;
+ case 5:
+ case 105:
+ /* cosh(finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "cosh" : "coshf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ break;
+ case 6:
+ case 106:
+ /* exp(finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "exp" : "expf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ break;
+ case 7:
+ case 107:
+ /* exp(finite) underflow */
+ exc.type = UNDERFLOW;
+ exc.name = type < 100 ? "exp" : "expf";
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ break;
+ case 8:
+ case 108:
+ /* y0(0) = -inf */
+ exc.type = DOMAIN; /* should be SING for IEEE */
+ exc.name = type < 100 ? "y0" : "y0f";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("y0: DOMAIN error\n", 17);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 9:
+ case 109:
+ /* y0(x<0) = NaN */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "y0" : "y0f";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("y0: DOMAIN error\n", 17);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 10:
+ case 110:
+ /* y1(0) = -inf */
+ exc.type = DOMAIN; /* should be SING for IEEE */
+ exc.name = type < 100 ? "y1" : "y1f";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("y1: DOMAIN error\n", 17);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 11:
+ case 111:
+ /* y1(x<0) = NaN */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "y1" : "y1f";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("y1: DOMAIN error\n", 17);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 12:
+ case 112:
+ /* yn(n,0) = -inf */
+ exc.type = DOMAIN; /* should be SING for IEEE */
+ exc.name = type < 100 ? "yn" : "ynf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("yn: DOMAIN error\n", 17);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 13:
+ case 113:
+ /* yn(x<0) = NaN */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "yn" : "ynf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("yn: DOMAIN error\n", 17);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 14:
+ case 114:
+ /* lgamma(finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "lgamma" : "lgammaf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ break;
+ case 15:
+ case 115:
+ /* lgamma(-integer) or lgamma(0) */
+ exc.type = SING;
+ exc.name = type < 100 ? "lgamma" : "lgammaf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("lgamma: SING error\n", 19);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 16:
+ case 116:
+ /* log(0) */
+ exc.type = SING;
+ exc.name = type < 100 ? "log" : "logf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("log: SING error\n", 16);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 17:
+ case 117:
+ /* log(x<0) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "log" : "logf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("log: DOMAIN error\n", 18);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 18:
+ case 118:
+ /* log10(0) */
+ exc.type = SING;
+ exc.name = type < 100 ? "log10" : "log10f";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("log10: SING error\n", 18);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 19:
+ case 119:
+ /* log10(x<0) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "log10" : "log10f";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("log10: DOMAIN error\n", 20);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 20:
+ case 120:
+ /* pow(0.0,0.0) */
+ /* error only if _LIB_VERSION == _SVID_ */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "pow" : "powf";
+ exc.retval = zero;
+ if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
+ else if (!matherr(&exc)) {
+ (void) WRITE2("pow(0,0): DOMAIN error\n", 23);
+ errno = EDOM;
+ }
+ break;
+ case 21:
+ case 121:
+ /* pow(x,y) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "pow" : "powf";
+ if (_LIB_VERSION == _SVID_) {
+ exc.retval = HUGE;
+ y *= 0.5;
+ if(x<zero&&rint(y)!=y) exc.retval = -HUGE;
+ } else {
+ exc.retval = HUGE_VAL;
+ y *= 0.5;
+ if(x<zero&&rint(y)!=y) exc.retval = -HUGE_VAL;
+ }
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ break;
+ case 22:
+ case 122:
+ /* pow(x,y) underflow */
+ exc.type = UNDERFLOW;
+ exc.name = type < 100 ? "pow" : "powf";
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ break;
+ case 23:
+ case 123:
+ /* 0**neg */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "pow" : "powf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = zero;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 24:
+ case 124:
+ /* neg**non-integral */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "pow" : "powf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = zero;
+ else
+ exc.retval = zero/zero; /* X/Open allow NaN */
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 25:
+ case 125:
+ /* sinh(finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "sinh" : "sinhf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = ( (x>zero) ? HUGE : -HUGE);
+ else
+ exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ break;
+ case 26:
+ case 126:
+ /* sqrt(x<0) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "sqrt" : "sqrtf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = zero;
+ else
+ exc.retval = zero/zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("sqrt: DOMAIN error\n", 19);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 27:
+ case 127:
+ /* fmod(x,0) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "fmod" : "fmodf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = x;
+ else
+ exc.retval = zero/zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("fmod: DOMAIN error\n", 20);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 28:
+ case 128:
+ /* remainder(x,0) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "remainder" : "remainderf";
+ exc.retval = zero/zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("remainder: DOMAIN error\n", 24);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 29:
+ case 129:
+ /* acosh(x<1) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "acosh" : "acoshf";
+ exc.retval = zero/zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("acosh: DOMAIN error\n", 20);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 30:
+ case 130:
+ /* atanh(|x|>1) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "atanh" : "atanhf";
+ exc.retval = zero/zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("atanh: DOMAIN error\n", 20);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 31:
+ case 131:
+ /* atanh(|x|=1) */
+ exc.type = SING;
+ exc.name = type < 100 ? "atanh" : "atanhf";
+ exc.retval = x/zero; /* sign(x)*inf */
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("atanh: SING error\n", 18);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 32:
+ case 132:
+ /* scalb overflow; SVID also returns +-HUGE_VAL */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "scalb" : "scalbf";
+ exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ break;
+ case 33:
+ case 133:
+ /* scalb underflow */
+ exc.type = UNDERFLOW;
+ exc.name = type < 100 ? "scalb" : "scalbf";
+ exc.retval = copysign(zero,x);
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ break;
+ case 34:
+ case 134:
+ /* j0(|x|>X_TLOSS) */
+ exc.type = TLOSS;
+ exc.name = type < 100 ? "j0" : "j0f";
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2(exc.name, 2);
+ (void) WRITE2(": TLOSS error\n", 14);
+ }
+ errno = ERANGE;
+ }
+ break;
+ case 35:
+ case 135:
+ /* y0(x>X_TLOSS) */
+ exc.type = TLOSS;
+ exc.name = type < 100 ? "y0" : "y0f";
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2(exc.name, 2);
+ (void) WRITE2(": TLOSS error\n", 14);
+ }
+ errno = ERANGE;
+ }
+ break;
+ case 36:
+ case 136:
+ /* j1(|x|>X_TLOSS) */
+ exc.type = TLOSS;
+ exc.name = type < 100 ? "j1" : "j1f";
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2(exc.name, 2);
+ (void) WRITE2(": TLOSS error\n", 14);
+ }
+ errno = ERANGE;
+ }
+ break;
+ case 37:
+ case 137:
+ /* y1(x>X_TLOSS) */
+ exc.type = TLOSS;
+ exc.name = type < 100 ? "y1" : "y1f";
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2(exc.name, 2);
+ (void) WRITE2(": TLOSS error\n", 14);
+ }
+ errno = ERANGE;
+ }
+ break;
+ case 38:
+ case 138:
+ /* jn(|x|>X_TLOSS) */
+ exc.type = TLOSS;
+ exc.name = type < 100 ? "jn" : "jnf";
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2(exc.name, 2);
+ (void) WRITE2(": TLOSS error\n", 14);
+ }
+ errno = ERANGE;
+ }
+ break;
+ case 39:
+ case 139:
+ /* yn(x>X_TLOSS) */
+ exc.type = TLOSS;
+ exc.name = type < 100 ? "yn" : "ynf";
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2(exc.name, 2);
+ (void) WRITE2(": TLOSS error\n", 14);
+ }
+ errno = ERANGE;
+ }
+ break;
+ case 40:
+ case 140:
+ /* gamma(finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "gamma" : "gammaf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ break;
+ case 41:
+ case 141:
+ /* gamma(-integer) or gamma(0) */
+ exc.type = SING;
+ exc.name = type < 100 ? "gamma" : "gammaf";
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("gamma: SING error\n", 18);
+ }
+ errno = EDOM;
+ }
+ break;
+ case 42:
+ case 142:
+ /* pow(NaN,0.0) */
+ /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "pow" : "powf";
+ exc.retval = x;
+ if (_LIB_VERSION == _IEEE_ ||
+ _LIB_VERSION == _POSIX_) exc.retval = 1.0;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ break;
+ }
+ return exc.retval;
+}
diff --git a/lib/msun/src/k_tan.c b/lib/msun/src/k_tan.c
new file mode 100644
index 0000000..d03c387
--- /dev/null
+++ b/lib/msun/src/k_tan.c
@@ -0,0 +1,131 @@
+/* @(#)k_tan.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* __kernel_tan( x, y, k )
+ * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input k indicates whether tan (if k=1) or
+ * -1/tan (if k= -1) is returned.
+ *
+ * Algorithm
+ * 1. Since tan(-x) = -tan(x), we need only to consider positive x.
+ * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0.
+ * 3. tan(x) is approximated by a odd polynomial of degree 27 on
+ * [0,0.67434]
+ * 3 27
+ * tan(x) ~ x + T1*x + ... + T13*x
+ * where
+ *
+ * |tan(x) 2 4 26 | -59.2
+ * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2
+ * | x |
+ *
+ * Note: tan(x+y) = tan(x) + tan'(x)*y
+ * ~ tan(x) + (1+x*x)*y
+ * Therefore, for better accuracy in computing tan(x+y), let
+ * 3 2 2 2 2
+ * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
+ * then
+ * 3 2
+ * tan(x+y) = x + (T1*x + (x *(r+y)+y))
+ *
+ * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
+ * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
+ * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
+ */
+
+#include "math.h"
+#include "math_private.h"
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+pio4 = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
+pio4lo= 3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */
+T[] = {
+ 3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */
+ 1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */
+ 5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */
+ 2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */
+ 8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */
+ 3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */
+ 1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */
+ 5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */
+ 2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */
+ 7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */
+ 7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */
+ -1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */
+ 2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */
+};
+
+#ifdef __STDC__
+ double __kernel_tan(double x, double y, int iy)
+#else
+ double __kernel_tan(x, y, iy)
+ double x,y; int iy;
+#endif
+{
+ double z,r,v,w,s;
+ int32_t ix,hx;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff; /* high word of |x| */
+ if(ix<0x3e300000) /* x < 2**-28 */
+ {if((int)x==0) { /* generate inexact */
+ u_int32_t low;
+ GET_LOW_WORD(low,x);
+ if(((ix|low)|(iy+1))==0) return one/fabs(x);
+ else return (iy==1)? x: -one/x;
+ }
+ }
+ if(ix>=0x3FE59428) { /* |x|>=0.6744 */
+ if(hx<0) {x = -x; y = -y;}
+ z = pio4-x;
+ w = pio4lo-y;
+ x = z+w; y = 0.0;
+ }
+ z = x*x;
+ w = z*z;
+ /* Break x^5*(T[1]+x^2*T[2]+...) into
+ * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
+ * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
+ */
+ r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11]))));
+ v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12])))));
+ s = z*x;
+ r = y + z*(s*(r+v)+y);
+ r += T[0]*s;
+ w = x+r;
+ if(ix>=0x3FE59428) {
+ v = (double)iy;
+ return (double)(1-((hx>>30)&2))*(v-2.0*(x-(w*w/(w+v)-r)));
+ }
+ if(iy==1) return w;
+ else { /* if allow error up to 2 ulp,
+ simply return -1.0/(x+r) here */
+ /* compute -1.0/(x+r) accurately */
+ double a,t;
+ z = w;
+ SET_LOW_WORD(z,0);
+ v = r-(z - x); /* z+v = r+x */
+ t = a = -1.0/w; /* a = -1.0/w */
+ SET_LOW_WORD(t,0);
+ s = 1.0+t*z;
+ return t+a*(s+t*v);
+ }
+}
diff --git a/lib/msun/src/k_tanf.c b/lib/msun/src/k_tanf.c
new file mode 100644
index 0000000..bb03b9f
--- /dev/null
+++ b/lib/msun/src/k_tanf.c
@@ -0,0 +1,101 @@
+/* k_tanf.c -- float version of k_tan.c
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0000000000e+00, /* 0x3f800000 */
+pio4 = 7.8539812565e-01, /* 0x3f490fda */
+pio4lo= 3.7748947079e-08, /* 0x33222168 */
+T[] = {
+ 3.3333334327e-01, /* 0x3eaaaaab */
+ 1.3333334029e-01, /* 0x3e088889 */
+ 5.3968254477e-02, /* 0x3d5d0dd1 */
+ 2.1869488060e-02, /* 0x3cb327a4 */
+ 8.8632395491e-03, /* 0x3c11371f */
+ 3.5920790397e-03, /* 0x3b6b6916 */
+ 1.4562094584e-03, /* 0x3abede48 */
+ 5.8804126456e-04, /* 0x3a1a26c8 */
+ 2.4646313977e-04, /* 0x398137b9 */
+ 7.8179444245e-05, /* 0x38a3f445 */
+ 7.1407252108e-05, /* 0x3895c07a */
+ -1.8558637748e-05, /* 0xb79bae5f */
+ 2.5907305826e-05, /* 0x37d95384 */
+};
+
+#ifdef __STDC__
+ float __kernel_tanf(float x, float y, int iy)
+#else
+ float __kernel_tanf(x, y, iy)
+ float x,y; int iy;
+#endif
+{
+ float z,r,v,w,s;
+ int32_t ix,hx;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff; /* high word of |x| */
+ if(ix<0x31800000) /* x < 2**-28 */
+ {if((int)x==0) { /* generate inexact */
+ if((ix|(iy+1))==0) return one/fabsf(x);
+ else return (iy==1)? x: -one/x;
+ }
+ }
+ if(ix>=0x3f2ca140) { /* |x|>=0.6744 */
+ if(hx<0) {x = -x; y = -y;}
+ z = pio4-x;
+ w = pio4lo-y;
+ x = z+w; y = 0.0;
+ }
+ z = x*x;
+ w = z*z;
+ /* Break x^5*(T[1]+x^2*T[2]+...) into
+ * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
+ * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
+ */
+ r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11]))));
+ v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12])))));
+ s = z*x;
+ r = y + z*(s*(r+v)+y);
+ r += T[0]*s;
+ w = x+r;
+ if(ix>=0x3f2ca140) {
+ v = (float)iy;
+ return (float)(1-((hx>>30)&2))*(v-(float)2.0*(x-(w*w/(w+v)-r)));
+ }
+ if(iy==1) return w;
+ else { /* if allow error up to 2 ulp,
+ simply return -1.0/(x+r) here */
+ /* compute -1.0/(x+r) accurately */
+ float a,t;
+ int32_t i;
+ z = w;
+ GET_FLOAT_WORD(i,z);
+ SET_FLOAT_WORD(z,i&0xfffff000);
+ v = r-(z - x); /* z+v = r+x */
+ t = a = -(float)1.0/w; /* a = -1.0/w */
+ GET_FLOAT_WORD(i,t);
+ SET_FLOAT_WORD(t,i&0xfffff000);
+ s = (float)1.0+t*z;
+ return t+a*(s+t*v);
+ }
+}
diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h
new file mode 100644
index 0000000..6d51877
--- /dev/null
+++ b/lib/msun/src/math.h
@@ -0,0 +1,277 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * from: @(#)fdlibm.h 5.1 93/09/24
+ * $FreeBSD$
+ */
+
+#ifndef _MATH_H_
+#define _MATH_H_
+
+/*
+ * ANSI/POSIX
+ */
+extern char __infinity[];
+#define HUGE_VAL (*(double *) __infinity)
+
+/*
+ * XOPEN/SVID
+ */
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
+#define M_E 2.7182818284590452354 /* e */
+#define M_LOG2E 1.4426950408889634074 /* log 2e */
+#define M_LOG10E 0.43429448190325182765 /* log 10e */
+#define M_LN2 0.69314718055994530942 /* log e2 */
+#define M_LN10 2.30258509299404568402 /* log e10 */
+#define M_PI 3.14159265358979323846 /* pi */
+#define M_PI_2 1.57079632679489661923 /* pi/2 */
+#define M_PI_4 0.78539816339744830962 /* pi/4 */
+#define M_1_PI 0.31830988618379067154 /* 1/pi */
+#define M_2_PI 0.63661977236758134308 /* 2/pi */
+#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
+#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
+#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
+
+#define MAXFLOAT ((float)3.40282346638528860e+38)
+extern int signgam;
+
+#if !defined(_XOPEN_SOURCE)
+enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix};
+
+#define _LIB_VERSION_TYPE enum fdversion
+#define _LIB_VERSION _fdlib_version
+
+/* if global variable _LIB_VERSION is not desirable, one may
+ * change the following to be a constant by:
+ * #define _LIB_VERSION_TYPE const enum version
+ * In that case, after one initializes the value _LIB_VERSION (see
+ * s_lib_version.c) during compile time, it cannot be modified
+ * in the middle of a program
+ */
+extern _LIB_VERSION_TYPE _LIB_VERSION;
+
+#define _IEEE_ fdlibm_ieee
+#define _SVID_ fdlibm_svid
+#define _XOPEN_ fdlibm_xopen
+#define _POSIX_ fdlibm_posix
+
+#ifndef __cplusplus
+struct exception {
+ int type;
+ char *name;
+ double arg1;
+ double arg2;
+ double retval;
+};
+#endif
+
+#define HUGE MAXFLOAT
+
+/*
+ * set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
+ * (one may replace the following line by "#include <values.h>")
+ */
+
+#define X_TLOSS 1.41484755040568800000e+16
+
+#define DOMAIN 1
+#define SING 2
+#define OVERFLOW 3
+#define UNDERFLOW 4
+#define TLOSS 5
+#define PLOSS 6
+
+#endif /* !_XOPEN_SOURCE */
+#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */
+
+
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+/*
+ * ANSI/POSIX
+ */
+extern double acos __P((double));
+extern double asin __P((double));
+extern double atan __P((double));
+extern double atan2 __P((double, double));
+extern double cos __P((double));
+extern double sin __P((double));
+extern double tan __P((double));
+
+extern double cosh __P((double));
+extern double sinh __P((double));
+extern double tanh __P((double));
+
+extern double exp __P((double));
+extern double frexp __P((double, int *));
+extern double ldexp __P((double, int));
+extern double log __P((double));
+extern double log10 __P((double));
+extern double modf __P((double, double *));
+
+extern double pow __P((double, double));
+extern double sqrt __P((double));
+
+extern double ceil __P((double));
+extern double fabs __P((double));
+extern double floor __P((double));
+extern double fmod __P((double, double));
+
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
+extern double erf __P((double));
+extern double erfc __P((double));
+extern double gamma __P((double));
+extern double hypot __P((double, double));
+extern int isinf __P((double));
+extern int isnan __P((double));
+extern int finite __P((double));
+extern double j0 __P((double));
+extern double j1 __P((double));
+extern double jn __P((int, double));
+extern double lgamma __P((double));
+extern double y0 __P((double));
+extern double y1 __P((double));
+extern double yn __P((int, double));
+
+#if !defined(_XOPEN_SOURCE)
+extern double acosh __P((double));
+extern double asinh __P((double));
+extern double atanh __P((double));
+extern double cbrt __P((double));
+extern double logb __P((double));
+extern double nextafter __P((double, double));
+extern double remainder __P((double, double));
+extern double scalb __P((double, double));
+
+#ifndef __cplusplus
+extern int matherr __P((struct exception *));
+#endif
+
+/*
+ * IEEE Test Vector
+ */
+extern double significand __P((double));
+
+/*
+ * Functions callable from C, intended to support IEEE arithmetic.
+ */
+extern double copysign __P((double, double));
+extern int ilogb __P((double));
+extern double rint __P((double));
+extern double scalbn __P((double, int));
+
+/*
+ * BSD math library entry points
+ */
+extern double cabs();
+extern double drem __P((double, double));
+extern double expm1 __P((double));
+extern double log1p __P((double));
+
+/*
+ * Reentrant version of gamma & lgamma; passes signgam back by reference
+ * as the second argument; user must allocate space for signgam.
+ */
+#ifdef _REENTRANT
+extern double gamma_r __P((double, int *));
+extern double lgamma_r __P((double, int *));
+#endif /* _REENTRANT */
+
+
+/* float versions of ANSI/POSIX functions */
+extern float acosf __P((float));
+extern float asinf __P((float));
+extern float atanf __P((float));
+extern float atan2f __P((float, float));
+extern float cosf __P((float));
+extern float sinf __P((float));
+extern float tanf __P((float));
+
+extern float coshf __P((float));
+extern float sinhf __P((float));
+extern float tanhf __P((float));
+
+extern float expf __P((float));
+extern float frexpf __P((float, int *));
+extern float ldexpf __P((float, int));
+extern float logf __P((float));
+extern float log10f __P((float));
+extern float modff __P((float, float *));
+
+extern float powf __P((float, float));
+extern float sqrtf __P((float));
+
+extern float ceilf __P((float));
+extern float fabsf __P((float));
+extern float floorf __P((float));
+extern float fmodf __P((float, float));
+
+extern float erff __P((float));
+extern float erfcf __P((float));
+extern float gammaf __P((float));
+extern float hypotf __P((float, float));
+extern int isnanf __P((float));
+extern int finitef __P((float));
+extern float j0f __P((float));
+extern float j1f __P((float));
+extern float jnf __P((int, float));
+extern float lgammaf __P((float));
+extern float y0f __P((float));
+extern float y1f __P((float));
+extern float ynf __P((int, float));
+
+extern float acoshf __P((float));
+extern float asinhf __P((float));
+extern float atanhf __P((float));
+extern float cbrtf __P((float));
+extern float logbf __P((float));
+extern float nextafterf __P((float, float));
+extern float remainderf __P((float, float));
+extern float scalbf __P((float, float));
+
+/*
+ * float version of IEEE Test Vector
+ */
+extern float significandf __P((float));
+
+/*
+ * Float versions of functions callable from C, intended to support
+ * IEEE arithmetic.
+ */
+extern float copysignf __P((float, float));
+extern int ilogbf __P((float));
+extern float rintf __P((float));
+extern float scalbnf __P((float, int));
+
+/*
+ * float versions of BSD math library entry points
+ */
+extern float cabsf ();
+extern float dremf __P((float, float));
+extern float expm1f __P((float));
+extern float log1pf __P((float));
+
+/*
+ * Float versions of reentrant version of gamma & lgamma; passes
+ * signgam back by reference as the second argument; user must
+ * allocate space for signgam.
+ */
+#ifdef _REENTRANT
+extern float gammaf_r __P((float, int *));
+extern float lgammaf_r __P((float, int *));
+#endif /* _REENTRANT */
+
+#endif /* !_XOPEN_SOURCE */
+#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */
+__END_DECLS
+
+#endif /* _MATH_H_ */
diff --git a/lib/msun/src/math_private.h b/lib/msun/src/math_private.h
new file mode 100644
index 0000000..668d499
--- /dev/null
+++ b/lib/msun/src/math_private.h
@@ -0,0 +1,250 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * from: @(#)fdlibm.h 5.1 93/09/24
+ * $FreeBSD$
+ */
+
+#ifndef _MATH_PRIVATE_H_
+#define _MATH_PRIVATE_H_
+
+#include <machine/endian.h>
+#include <sys/types.h>
+
+/* The original fdlibm code used statements like:
+ n0 = ((*(int*)&one)>>29)^1; * index of high word *
+ ix0 = *(n0+(int*)&x); * high word of x *
+ ix1 = *((1-n0)+(int*)&x); * low word of x *
+ to dig two 32 bit words out of the 64 bit IEEE floating point
+ value. That is non-ANSI, and, moreover, the gcc instruction
+ scheduler gets it wrong. We instead use the following macros.
+ Unlike the original code, we determine the endianness at compile
+ time, not at run time; I don't see much benefit to selecting
+ endianness at run time. */
+
+/* A union which permits us to convert between a double and two 32 bit
+ ints. */
+
+#if BYTE_ORDER == BIG_ENDIAN
+
+typedef union
+{
+ double value;
+ struct
+ {
+ u_int32_t msw;
+ u_int32_t lsw;
+ } parts;
+} ieee_double_shape_type;
+
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+typedef union
+{
+ double value;
+ struct
+ {
+ u_int32_t lsw;
+ u_int32_t msw;
+ } parts;
+} ieee_double_shape_type;
+
+#endif
+
+/* Get two 32 bit ints from a double. */
+
+#define EXTRACT_WORDS(ix0,ix1,d) \
+do { \
+ ieee_double_shape_type ew_u; \
+ ew_u.value = (d); \
+ (ix0) = ew_u.parts.msw; \
+ (ix1) = ew_u.parts.lsw; \
+} while (0)
+
+/* Get the more significant 32 bit int from a double. */
+
+#define GET_HIGH_WORD(i,d) \
+do { \
+ ieee_double_shape_type gh_u; \
+ gh_u.value = (d); \
+ (i) = gh_u.parts.msw; \
+} while (0)
+
+/* Get the less significant 32 bit int from a double. */
+
+#define GET_LOW_WORD(i,d) \
+do { \
+ ieee_double_shape_type gl_u; \
+ gl_u.value = (d); \
+ (i) = gl_u.parts.lsw; \
+} while (0)
+
+/* Set a double from two 32 bit ints. */
+
+#define INSERT_WORDS(d,ix0,ix1) \
+do { \
+ ieee_double_shape_type iw_u; \
+ iw_u.parts.msw = (ix0); \
+ iw_u.parts.lsw = (ix1); \
+ (d) = iw_u.value; \
+} while (0)
+
+/* Set the more significant 32 bits of a double from an int. */
+
+#define SET_HIGH_WORD(d,v) \
+do { \
+ ieee_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ sh_u.parts.msw = (v); \
+ (d) = sh_u.value; \
+} while (0)
+
+/* Set the less significant 32 bits of a double from an int. */
+
+#define SET_LOW_WORD(d,v) \
+do { \
+ ieee_double_shape_type sl_u; \
+ sl_u.value = (d); \
+ sl_u.parts.lsw = (v); \
+ (d) = sl_u.value; \
+} while (0)
+
+/* A union which permits us to convert between a float and a 32 bit
+ int. */
+
+typedef union
+{
+ float value;
+ /* FIXME: Assumes 32 bit int. */
+ unsigned int word;
+} ieee_float_shape_type;
+
+/* Get a 32 bit int from a float. */
+
+#define GET_FLOAT_WORD(i,d) \
+do { \
+ ieee_float_shape_type gf_u; \
+ gf_u.value = (d); \
+ (i) = gf_u.word; \
+} while (0)
+
+/* Set a float from a 32 bit int. */
+
+#define SET_FLOAT_WORD(d,i) \
+do { \
+ ieee_float_shape_type sf_u; \
+ sf_u.word = (i); \
+ (d) = sf_u.value; \
+} while (0)
+
+/* ieee style elementary functions */
+extern double __ieee754_sqrt __P((double));
+extern double __ieee754_acos __P((double));
+extern double __ieee754_acosh __P((double));
+extern double __ieee754_log __P((double));
+extern double __ieee754_atanh __P((double));
+extern double __ieee754_asin __P((double));
+extern double __ieee754_atan2 __P((double,double));
+extern double __ieee754_exp __P((double));
+extern double __ieee754_cosh __P((double));
+extern double __ieee754_fmod __P((double,double));
+extern double __ieee754_pow __P((double,double));
+extern double __ieee754_lgamma_r __P((double,int *));
+extern double __ieee754_gamma_r __P((double,int *));
+extern double __ieee754_lgamma __P((double));
+extern double __ieee754_gamma __P((double));
+extern double __ieee754_log10 __P((double));
+extern double __ieee754_sinh __P((double));
+extern double __ieee754_hypot __P((double,double));
+extern double __ieee754_j0 __P((double));
+extern double __ieee754_j1 __P((double));
+extern double __ieee754_y0 __P((double));
+extern double __ieee754_y1 __P((double));
+extern double __ieee754_jn __P((int,double));
+extern double __ieee754_yn __P((int,double));
+extern double __ieee754_remainder __P((double,double));
+extern int __ieee754_rem_pio2 __P((double,double*));
+extern double __ieee754_scalb __P((double,double));
+
+/* fdlibm kernel function */
+extern double __kernel_standard __P((double,double,int));
+extern double __kernel_sin __P((double,double,int));
+extern double __kernel_cos __P((double,double));
+extern double __kernel_tan __P((double,double,int));
+extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*));
+
+
+/* ieee style elementary float functions */
+extern float __ieee754_sqrtf __P((float));
+extern float __ieee754_acosf __P((float));
+extern float __ieee754_acoshf __P((float));
+extern float __ieee754_logf __P((float));
+extern float __ieee754_atanhf __P((float));
+extern float __ieee754_asinf __P((float));
+extern float __ieee754_atan2f __P((float,float));
+extern float __ieee754_expf __P((float));
+extern float __ieee754_coshf __P((float));
+extern float __ieee754_fmodf __P((float,float));
+extern float __ieee754_powf __P((float,float));
+extern float __ieee754_lgammaf_r __P((float,int *));
+extern float __ieee754_gammaf_r __P((float,int *));
+extern float __ieee754_lgammaf __P((float));
+extern float __ieee754_gammaf __P((float));
+extern float __ieee754_log10f __P((float));
+extern float __ieee754_sinhf __P((float));
+extern float __ieee754_hypotf __P((float,float));
+extern float __ieee754_j0f __P((float));
+extern float __ieee754_j1f __P((float));
+extern float __ieee754_y0f __P((float));
+extern float __ieee754_y1f __P((float));
+extern float __ieee754_jnf __P((int,float));
+extern float __ieee754_ynf __P((int,float));
+extern float __ieee754_remainderf __P((float,float));
+extern int __ieee754_rem_pio2f __P((float,float*));
+extern float __ieee754_scalbf __P((float,float));
+
+/* float versions of fdlibm kernel functions */
+extern float __kernel_sinf __P((float,float,int));
+extern float __kernel_cosf __P((float,float));
+extern float __kernel_tanf __P((float,float,int));
+extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const int*));
+
+#ifdef __alpha__
+#define __generic___ieee754_acos __ieee754_acos
+#define __generic___ieee754_asin __ieee754_asin
+#define __generic___ieee754_atan2 __ieee754_atan2
+#define __generic___ieee754_exp __ieee754_exp
+#define __generic___ieee754_fmod __ieee754_fmod
+#define __generic___ieee754_log __ieee754_log
+#define __generic___ieee754_log10 __ieee754_log10
+#define __generic___ieee754_remainder __ieee754_remainder
+#define __generic___ieee754_scalb __ieee754_scalb
+#define __generic___ieee754_sqrt __ieee754_sqrt
+#define __generic_atan atan
+#define __generic_ceil ceil
+#define __generic_copysign copysign
+#define __generic_cos cos
+#define __generic_finite finite
+#define __generic_floor floor
+#define __generic_ilogb ilogb
+#define __generic_log1p log1p
+#define __generic_logb logb
+#define __generic_rint rint
+#define __generic_scalbn scalbn
+#define __generic_significand significand
+#define __generic_sin sin
+#define __generic_tan tan
+#endif
+
+#endif /* _MATH_PRIVATE_H_ */
diff --git a/lib/msun/src/s_asinh.c b/lib/msun/src/s_asinh.c
new file mode 100644
index 0000000..c1dbde8
--- /dev/null
+++ b/lib/msun/src/s_asinh.c
@@ -0,0 +1,65 @@
+/* @(#)s_asinh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* asinh(x)
+ * Method :
+ * Based on
+ * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
+ * we have
+ * asinh(x) := x if 1+x*x=1,
+ * := sign(x)*(log(x)+ln2)) for large |x|, else
+ * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
+ * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+ln2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+huge= 1.00000000000000000000e+300;
+
+#ifdef __STDC__
+ double asinh(double x)
+#else
+ double asinh(x)
+ double x;
+#endif
+{
+ double t,w;
+ int32_t hx,ix;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) return x+x; /* x is inf or NaN */
+ if(ix< 0x3e300000) { /* |x|<2**-28 */
+ if(huge+x>one) return x; /* return x inexact except 0 */
+ }
+ if(ix>0x41b00000) { /* |x| > 2**28 */
+ w = __ieee754_log(fabs(x))+ln2;
+ } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */
+ t = fabs(x);
+ w = __ieee754_log(2.0*t+one/(__ieee754_sqrt(x*x+one)+t));
+ } else { /* 2.0 > |x| > 2**-28 */
+ t = x*x;
+ w =log1p(fabs(x)+t/(one+__ieee754_sqrt(one+t)));
+ }
+ if(hx>0) return w; else return -w;
+}
diff --git a/lib/msun/src/s_asinhf.c b/lib/msun/src/s_asinhf.c
new file mode 100644
index 0000000..9910b2a
--- /dev/null
+++ b/lib/msun/src/s_asinhf.c
@@ -0,0 +1,57 @@
+/* s_asinhf.c -- float version of s_asinh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0000000000e+00, /* 0x3F800000 */
+ln2 = 6.9314718246e-01, /* 0x3f317218 */
+huge= 1.0000000000e+30;
+
+#ifdef __STDC__
+ float asinhf(float x)
+#else
+ float asinhf(x)
+ float x;
+#endif
+{
+ float t,w;
+ int32_t hx,ix;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7f800000) return x+x; /* x is inf or NaN */
+ if(ix< 0x31800000) { /* |x|<2**-28 */
+ if(huge+x>one) return x; /* return x inexact except 0 */
+ }
+ if(ix>0x4d800000) { /* |x| > 2**28 */
+ w = __ieee754_logf(fabsf(x))+ln2;
+ } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */
+ t = fabsf(x);
+ w = __ieee754_logf((float)2.0*t+one/(__ieee754_sqrtf(x*x+one)+t));
+ } else { /* 2.0 > |x| > 2**-28 */
+ t = x*x;
+ w =log1pf(fabsf(x)+t/(one+__ieee754_sqrtf(one+t)));
+ }
+ if(hx>0) return w; else return -w;
+}
diff --git a/lib/msun/src/s_atan.c b/lib/msun/src/s_atan.c
new file mode 100644
index 0000000..029fbc2
--- /dev/null
+++ b/lib/msun/src/s_atan.c
@@ -0,0 +1,139 @@
+/* @(#)s_atan.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* atan(x)
+ * Method
+ * 1. Reduce x to positive by atan(x) = -atan(-x).
+ * 2. According to the integer k=4t+0.25 chopped, t=x, the argument
+ * is further reduced to one of the following intervals and the
+ * arctangent of t is evaluated by the corresponding formula:
+ *
+ * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
+ * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
+ * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
+ * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
+ * [39/16,INF] atan(x) = atan(INF) + atan( -1/t )
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double atanhi[] = {
+#else
+static double atanhi[] = {
+#endif
+ 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
+ 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
+ 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
+ 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
+};
+
+#ifdef __STDC__
+static const double atanlo[] = {
+#else
+static double atanlo[] = {
+#endif
+ 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
+ 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
+ 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
+ 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
+};
+
+#ifdef __STDC__
+static const double aT[] = {
+#else
+static double aT[] = {
+#endif
+ 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
+ -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
+ 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
+ -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
+ 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
+ -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
+ 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
+ -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
+ 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
+ -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
+ 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
+};
+
+#ifdef __STDC__
+ static const double
+#else
+ static double
+#endif
+one = 1.0,
+huge = 1.0e300;
+
+#ifdef __STDC__
+ double __generic_atan(double x)
+#else
+ double __generic_atan(x)
+ double x;
+#endif
+{
+ double w,s1,s2,z;
+ int32_t ix,hx,id;
+
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x44100000) { /* if |x| >= 2^66 */
+ u_int32_t low;
+ GET_LOW_WORD(low,x);
+ if(ix>0x7ff00000||
+ (ix==0x7ff00000&&(low!=0)))
+ return x+x; /* NaN */
+ if(hx>0) return atanhi[3]+atanlo[3];
+ else return -atanhi[3]-atanlo[3];
+ } if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
+ if (ix < 0x3e200000) { /* |x| < 2^-29 */
+ if(huge+x>one) return x; /* raise inexact */
+ }
+ id = -1;
+ } else {
+ x = fabs(x);
+ if (ix < 0x3ff30000) { /* |x| < 1.1875 */
+ if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */
+ id = 0; x = (2.0*x-one)/(2.0+x);
+ } else { /* 11/16<=|x|< 19/16 */
+ id = 1; x = (x-one)/(x+one);
+ }
+ } else {
+ if (ix < 0x40038000) { /* |x| < 2.4375 */
+ id = 2; x = (x-1.5)/(one+1.5*x);
+ } else { /* 2.4375 <= |x| < 2^66 */
+ id = 3; x = -1.0/x;
+ }
+ }}
+ /* end of argument reduction */
+ z = x*x;
+ w = z*z;
+ /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
+ s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
+ s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
+ if (id<0) return x - x*(s1+s2);
+ else {
+ z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+ return (hx<0)? -z:z;
+ }
+}
diff --git a/lib/msun/src/s_atanf.c b/lib/msun/src/s_atanf.c
new file mode 100644
index 0000000..ff702f6
--- /dev/null
+++ b/lib/msun/src/s_atanf.c
@@ -0,0 +1,119 @@
+/* s_atanf.c -- float version of s_atan.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float atanhi[] = {
+#else
+static float atanhi[] = {
+#endif
+ 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */
+ 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */
+ 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */
+ 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */
+};
+
+#ifdef __STDC__
+static const float atanlo[] = {
+#else
+static float atanlo[] = {
+#endif
+ 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */
+ 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */
+ 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */
+ 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */
+};
+
+#ifdef __STDC__
+static const float aT[] = {
+#else
+static float aT[] = {
+#endif
+ 3.3333334327e-01, /* 0x3eaaaaaa */
+ -2.0000000298e-01, /* 0xbe4ccccd */
+ 1.4285714924e-01, /* 0x3e124925 */
+ -1.1111110449e-01, /* 0xbde38e38 */
+ 9.0908870101e-02, /* 0x3dba2e6e */
+ -7.6918758452e-02, /* 0xbd9d8795 */
+ 6.6610731184e-02, /* 0x3d886b35 */
+ -5.8335702866e-02, /* 0xbd6ef16b */
+ 4.9768779427e-02, /* 0x3d4bda59 */
+ -3.6531571299e-02, /* 0xbd15a221 */
+ 1.6285819933e-02, /* 0x3c8569d7 */
+};
+
+#ifdef __STDC__
+ static const float
+#else
+ static float
+#endif
+one = 1.0,
+huge = 1.0e30;
+
+#ifdef __STDC__
+ float atanf(float x)
+#else
+ float atanf(x)
+ float x;
+#endif
+{
+ float w,s1,s2,z;
+ int32_t ix,hx,id;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x50800000) { /* if |x| >= 2^34 */
+ if(ix>0x7f800000)
+ return x+x; /* NaN */
+ if(hx>0) return atanhi[3]+atanlo[3];
+ else return -atanhi[3]-atanlo[3];
+ } if (ix < 0x3ee00000) { /* |x| < 0.4375 */
+ if (ix < 0x31000000) { /* |x| < 2^-29 */
+ if(huge+x>one) return x; /* raise inexact */
+ }
+ id = -1;
+ } else {
+ x = fabsf(x);
+ if (ix < 0x3f980000) { /* |x| < 1.1875 */
+ if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */
+ id = 0; x = ((float)2.0*x-one)/((float)2.0+x);
+ } else { /* 11/16<=|x|< 19/16 */
+ id = 1; x = (x-one)/(x+one);
+ }
+ } else {
+ if (ix < 0x401c0000) { /* |x| < 2.4375 */
+ id = 2; x = (x-(float)1.5)/(one+(float)1.5*x);
+ } else { /* 2.4375 <= |x| < 2^66 */
+ id = 3; x = -(float)1.0/x;
+ }
+ }}
+ /* end of argument reduction */
+ z = x*x;
+ w = z*z;
+ /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
+ s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
+ s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
+ if (id<0) return x - x*(s1+s2);
+ else {
+ z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+ return (hx<0)? -z:z;
+ }
+}
diff --git a/lib/msun/src/s_cbrt.c b/lib/msun/src/s_cbrt.c
new file mode 100644
index 0000000..93edad7
--- /dev/null
+++ b/lib/msun/src/s_cbrt.c
@@ -0,0 +1,93 @@
+/* @(#)s_cbrt.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+/* cbrt(x)
+ * Return cube root of x
+ */
+#ifdef __STDC__
+static const u_int32_t
+#else
+static u_int32_t
+#endif
+ B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
+ B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+C = 5.42857142857142815906e-01, /* 19/35 = 0x3FE15F15, 0xF15F15F1 */
+D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
+E = 1.41428571428571436819e+00, /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */
+F = 1.60714285714285720630e+00, /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */
+G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */
+
+#ifdef __STDC__
+ double cbrt(double x)
+#else
+ double cbrt(x)
+ double x;
+#endif
+{
+ int32_t hx;
+ double r,s,t=0.0,w;
+ u_int32_t sign;
+ u_int32_t high,low;
+
+ GET_HIGH_WORD(hx,x);
+ sign=hx&0x80000000; /* sign= sign(x) */
+ hx ^=sign;
+ if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
+ GET_LOW_WORD(low,x);
+ if((hx|low)==0)
+ return(x); /* cbrt(0) is itself */
+
+ SET_HIGH_WORD(x,hx); /* x <- |x| */
+ /* rough cbrt to 5 bits */
+ if(hx<0x00100000) /* subnormal number */
+ {SET_HIGH_WORD(t,0x43500000); /* set t= 2**54 */
+ t*=x; GET_HIGH_WORD(high,t); SET_HIGH_WORD(t,high/3+B2);
+ }
+ else
+ SET_HIGH_WORD(t,hx/3+B1);
+
+
+ /* new cbrt to 23 bits, may be implemented in single precision */
+ r=t*t/x;
+ s=C+r*t;
+ t*=G+F/(s+E+D/s);
+
+ /* chopped to 20 bits and make it larger than cbrt(x) */
+ GET_HIGH_WORD(high,t);
+ INSERT_WORDS(t,high+0x00000001,0);
+
+
+ /* one step newton iteration to 53 bits with error less than 0.667 ulps */
+ s=t*t; /* t*t is exact */
+ r=x/s;
+ w=t+t;
+ r=(r-t)/(w+r); /* r-s is exact */
+ t=t+t*r;
+
+ /* retore the sign bit */
+ GET_HIGH_WORD(high,t);
+ SET_HIGH_WORD(t,high|sign);
+ return(t);
+}
diff --git a/lib/msun/src/s_cbrtf.c b/lib/msun/src/s_cbrtf.c
new file mode 100644
index 0000000..c1c2fa1
--- /dev/null
+++ b/lib/msun/src/s_cbrtf.c
@@ -0,0 +1,83 @@
+/* s_cbrtf.c -- float version of s_cbrt.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+/* cbrtf(x)
+ * Return cube root of x
+ */
+#ifdef __STDC__
+static const unsigned
+#else
+static unsigned
+#endif
+ B1 = 709958130, /* B1 = (84+2/3-0.03306235651)*2**23 */
+ B2 = 642849266; /* B2 = (76+2/3-0.03306235651)*2**23 */
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+C = 5.4285717010e-01, /* 19/35 = 0x3f0af8b0 */
+D = -7.0530611277e-01, /* -864/1225 = 0xbf348ef1 */
+E = 1.4142856598e+00, /* 99/70 = 0x3fb50750 */
+F = 1.6071428061e+00, /* 45/28 = 0x3fcdb6db */
+G = 3.5714286566e-01; /* 5/14 = 0x3eb6db6e */
+
+#ifdef __STDC__
+ float cbrtf(float x)
+#else
+ float cbrtf(x)
+ float x;
+#endif
+{
+ float r,s,t;
+ int32_t hx;
+ u_int32_t sign;
+ u_int32_t high;
+
+ GET_FLOAT_WORD(hx,x);
+ sign=hx&0x80000000; /* sign= sign(x) */
+ hx ^=sign;
+ if(hx>=0x7f800000) return(x+x); /* cbrt(NaN,INF) is itself */
+ if(hx==0)
+ return(x); /* cbrt(0) is itself */
+
+ SET_FLOAT_WORD(x,hx); /* x <- |x| */
+ /* rough cbrt to 5 bits */
+ if(hx<0x00800000) /* subnormal number */
+ {SET_FLOAT_WORD(t,0x4b800000); /* set t= 2**24 */
+ t*=x; GET_FLOAT_WORD(high,t); SET_FLOAT_WORD(t,high/3+B2);
+ }
+ else
+ SET_FLOAT_WORD(t,hx/3+B1);
+
+
+ /* new cbrt to 23 bits */
+ r=t*t/x;
+ s=C+r*t;
+ t*=G+F/(s+E+D/s);
+
+ /* retore the sign bit */
+ GET_FLOAT_WORD(high,t);
+ SET_FLOAT_WORD(t,high|sign);
+ return(t);
+}
diff --git a/lib/msun/src/s_ceil.c b/lib/msun/src/s_ceil.c
new file mode 100644
index 0000000..2c59c78
--- /dev/null
+++ b/lib/msun/src/s_ceil.c
@@ -0,0 +1,80 @@
+/* @(#)s_ceil.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * ceil(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to ceil(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double huge = 1.0e300;
+#else
+static double huge = 1.0e300;
+#endif
+
+#ifdef __STDC__
+ double __generic_ceil(double x)
+#else
+ double __generic_ceil(x)
+ double x;
+#endif
+{
+ int32_t i0,i1,j0;
+ u_int32_t i,j;
+ EXTRACT_WORDS(i0,i1,x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0<0) {i0=0x80000000;i1=0;}
+ else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
+ }
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0>0) i0 += (0x00100000)>>j0;
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0>0) {
+ if(j0==20) i0+=1;
+ else {
+ j = i1 + (1<<(52-j0));
+ if(j<i1) i0+=1; /* got a carry */
+ i1 = j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ INSERT_WORDS(x,i0,i1);
+ return x;
+}
diff --git a/lib/msun/src/s_ceilf.c b/lib/msun/src/s_ceilf.c
new file mode 100644
index 0000000..06993ad
--- /dev/null
+++ b/lib/msun/src/s_ceilf.c
@@ -0,0 +1,61 @@
+/* s_ceilf.c -- float version of s_ceil.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float huge = 1.0e30;
+#else
+static float huge = 1.0e30;
+#endif
+
+#ifdef __STDC__
+ float ceilf(float x)
+#else
+ float ceilf(x)
+ float x;
+#endif
+{
+ int32_t i0,j0;
+ u_int32_t i;
+
+ GET_FLOAT_WORD(i0,x);
+ j0 = ((i0>>23)&0xff)-0x7f;
+ if(j0<23) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0<0) {i0=0x80000000;}
+ else if(i0!=0) { i0=0x3f800000;}
+ }
+ } else {
+ i = (0x007fffff)>>j0;
+ if((i0&i)==0) return x; /* x is integral */
+ if(huge+x>(float)0.0) { /* raise inexact flag */
+ if(i0>0) i0 += (0x00800000)>>j0;
+ i0 &= (~i);
+ }
+ }
+ } else {
+ if(j0==0x80) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ }
+ SET_FLOAT_WORD(x,i0);
+ return x;
+}
diff --git a/lib/msun/src/s_copysign.c b/lib/msun/src/s_copysign.c
new file mode 100644
index 0000000..4f758d2
--- /dev/null
+++ b/lib/msun/src/s_copysign.c
@@ -0,0 +1,38 @@
+/* @(#)s_copysign.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * copysign(double x, double y)
+ * copysign(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __generic_copysign(double x, double y)
+#else
+ double __generic_copysign(x,y)
+ double x,y;
+#endif
+{
+ u_int32_t hx,hy;
+ GET_HIGH_WORD(hx,x);
+ GET_HIGH_WORD(hy,y);
+ SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
+ return x;
+}
diff --git a/lib/msun/src/s_copysignf.c b/lib/msun/src/s_copysignf.c
new file mode 100644
index 0000000..ae0980f
--- /dev/null
+++ b/lib/msun/src/s_copysignf.c
@@ -0,0 +1,41 @@
+/* s_copysignf.c -- float version of s_copysign.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * copysignf(float x, float y)
+ * copysignf(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float copysignf(float x, float y)
+#else
+ float copysignf(x,y)
+ float x,y;
+#endif
+{
+ u_int32_t ix,iy;
+ GET_FLOAT_WORD(ix,x);
+ GET_FLOAT_WORD(iy,y);
+ SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000));
+ return x;
+}
diff --git a/lib/msun/src/s_cos.c b/lib/msun/src/s_cos.c
new file mode 100644
index 0000000..707af78
--- /dev/null
+++ b/lib/msun/src/s_cos.c
@@ -0,0 +1,82 @@
+/* @(#)s_cos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* cos(x)
+ * Return cosine function of x.
+ *
+ * kernel function:
+ * __kernel_sin ... sine function on [-pi/4,pi/4]
+ * __kernel_cos ... cosine function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2 ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __generic_cos(double x)
+#else
+ double __generic_cos(x)
+ double x;
+#endif
+{
+ double y[2],z=0.0;
+ int32_t n, ix;
+
+ /* High word of x. */
+ GET_HIGH_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3fe921fb) return __kernel_cos(x,z);
+
+ /* cos(Inf or NaN) is NaN */
+ else if (ix>=0x7ff00000) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2(x,y);
+ switch(n&3) {
+ case 0: return __kernel_cos(y[0],y[1]);
+ case 1: return -__kernel_sin(y[0],y[1],1);
+ case 2: return -__kernel_cos(y[0],y[1]);
+ default:
+ return __kernel_sin(y[0],y[1],1);
+ }
+ }
+}
diff --git a/lib/msun/src/s_cosf.c b/lib/msun/src/s_cosf.c
new file mode 100644
index 0000000..4091350
--- /dev/null
+++ b/lib/msun/src/s_cosf.c
@@ -0,0 +1,59 @@
+/* s_cosf.c -- float version of s_cos.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one=1.0;
+#else
+static float one=1.0;
+#endif
+
+#ifdef __STDC__
+ float cosf(float x)
+#else
+ float cosf(x)
+ float x;
+#endif
+{
+ float y[2],z=0.0;
+ int32_t n,ix;
+
+ GET_FLOAT_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3f490fd8) return __kernel_cosf(x,z);
+
+ /* cos(Inf or NaN) is NaN */
+ else if (ix>=0x7f800000) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2f(x,y);
+ switch(n&3) {
+ case 0: return __kernel_cosf(y[0],y[1]);
+ case 1: return -__kernel_sinf(y[0],y[1],1);
+ case 2: return -__kernel_cosf(y[0],y[1]);
+ default:
+ return __kernel_sinf(y[0],y[1],1);
+ }
+ }
+}
diff --git a/lib/msun/src/s_erf.c b/lib/msun/src/s_erf.c
new file mode 100644
index 0000000..bfe5b12
--- /dev/null
+++ b/lib/msun/src/s_erf.c
@@ -0,0 +1,314 @@
+/* @(#)s_erf.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* double erf(double x)
+ * double erfc(double x)
+ * x
+ * 2 |\
+ * erf(x) = --------- | exp(-t*t)dt
+ * sqrt(pi) \|
+ * 0
+ *
+ * erfc(x) = 1-erf(x)
+ * Note that
+ * erf(-x) = -erf(x)
+ * erfc(-x) = 2 - erfc(x)
+ *
+ * Method:
+ * 1. For |x| in [0, 0.84375]
+ * erf(x) = x + x*R(x^2)
+ * erfc(x) = 1 - erf(x) if x in [-.84375,0.25]
+ * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375]
+ * where R = P/Q where P is an odd poly of degree 8 and
+ * Q is an odd poly of degree 10.
+ * -57.90
+ * | R - (erf(x)-x)/x | <= 2
+ *
+ *
+ * Remark. The formula is derived by noting
+ * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ * and that
+ * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ * is close to one. The interval is chosen because the fix
+ * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
+ * near 0.6174), and by some experiment, 0.84375 is chosen to
+ * guarantee the error is less than one ulp for erf.
+ *
+ * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and
+ * c = 0.84506291151 rounded to single (24 bits)
+ * erf(x) = sign(x) * (c + P1(s)/Q1(s))
+ * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0
+ * 1+(c+P1(s)/Q1(s)) if x < 0
+ * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06
+ * Remark: here we use the taylor series expansion at x=1.
+ * erf(1+s) = erf(1) + s*Poly(s)
+ * = 0.845.. + P1(s)/Q1(s)
+ * That is, we use rational approximation to approximate
+ * erf(1+s) - (c = (single)0.84506291151)
+ * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ * where
+ * P1(s) = degree 6 poly in s
+ * Q1(s) = degree 6 poly in s
+ *
+ * 3. For x in [1.25,1/0.35(~2.857143)],
+ * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)
+ * erf(x) = 1 - erfc(x)
+ * where
+ * R1(z) = degree 7 poly in z, (z=1/x^2)
+ * S1(z) = degree 8 poly in z
+ *
+ * 4. For x in [1/0.35,28]
+ * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
+ * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0
+ * = 2.0 - tiny (if x <= -6)
+ * erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6, else
+ * erf(x) = sign(x)*(1.0 - tiny)
+ * where
+ * R2(z) = degree 6 poly in z, (z=1/x^2)
+ * S2(z) = degree 7 poly in z
+ *
+ * Note1:
+ * To compute exp(-x*x-0.5625+R/S), let s be a single
+ * precision number and s := x; then
+ * -x*x = -s*s + (s-x)*(s+x)
+ * exp(-x*x-0.5626+R/S) =
+ * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
+ * Note2:
+ * Here 4 and 5 make use of the asymptotic series
+ * exp(-x*x)
+ * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
+ * x*sqrt(pi)
+ * We use rational approximation to approximate
+ * g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625
+ * Here is the error bound for R1/S1 and R2/S2
+ * |R1/S1 - f(x)| < 2**(-62.57)
+ * |R2/S2 - f(x)| < 2**(-61.52)
+ *
+ * 5. For inf > x >= 28
+ * erf(x) = sign(x) *(1 - tiny) (raise inexact)
+ * erfc(x) = tiny*tiny (raise underflow) if x > 0
+ * = 2 - tiny if x<0
+ *
+ * 7. Special case:
+ * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
+ * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
+ * erfc/erf(NaN) is NaN
+ */
+
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+tiny = 1e-300,
+half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
+ /* c = (float)0.84506291151 */
+erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */
+/*
+ * Coefficients for approximation to erf on [0,0.84375]
+ */
+efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */
+efx8= 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */
+pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */
+pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */
+pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */
+pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */
+pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */
+qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */
+qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */
+qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */
+qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */
+qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */
+/*
+ * Coefficients for approximation to erf in [0.84375,1.25]
+ */
+pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */
+pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */
+pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */
+pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */
+pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */
+pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */
+pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */
+qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */
+qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */
+qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */
+qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */
+qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */
+qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */
+/*
+ * Coefficients for approximation to erfc in [1.25,1/0.35]
+ */
+ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */
+ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */
+ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */
+ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */
+ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */
+ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */
+ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */
+ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */
+sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */
+sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */
+sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */
+sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */
+sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */
+sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */
+sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */
+sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */
+/*
+ * Coefficients for approximation to erfc in [1/.35,28]
+ */
+rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */
+rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */
+rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */
+rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */
+rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */
+rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */
+rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */
+sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */
+sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */
+sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */
+sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */
+sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */
+sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */
+sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */
+
+#ifdef __STDC__
+ double erf(double x)
+#else
+ double erf(x)
+ double x;
+#endif
+{
+ int32_t hx,ix,i;
+ double R,S,P,Q,s,y,z,r;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) { /* erf(nan)=nan */
+ i = ((u_int32_t)hx>>31)<<1;
+ return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */
+ }
+
+ if(ix < 0x3feb0000) { /* |x|<0.84375 */
+ if(ix < 0x3e300000) { /* |x|<2**-28 */
+ if (ix < 0x00800000)
+ return 0.125*(8.0*x+efx8*x); /*avoid underflow */
+ return x + efx*x;
+ }
+ z = x*x;
+ r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+ s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+ y = r/s;
+ return x + x*y;
+ }
+ if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */
+ s = fabs(x)-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+ if(hx>=0) return erx + P/Q; else return -erx - P/Q;
+ }
+ if (ix >= 0x40180000) { /* inf>|x|>=6 */
+ if(hx>=0) return one-tiny; else return tiny-one;
+ }
+ x = fabs(x);
+ s = one/(x*x);
+ if(ix< 0x4006DB6E) { /* |x| < 1/0.35 */
+ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+ ra5+s*(ra6+s*ra7))))));
+ S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+ sa5+s*(sa6+s*(sa7+s*sa8)))))));
+ } else { /* |x| >= 1/0.35 */
+ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+ rb5+s*rb6)))));
+ S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+ sb5+s*(sb6+s*sb7))))));
+ }
+ z = x;
+ SET_LOW_WORD(z,0);
+ r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S);
+ if(hx>=0) return one-r/x; else return r/x-one;
+}
+
+#ifdef __STDC__
+ double erfc(double x)
+#else
+ double erfc(x)
+ double x;
+#endif
+{
+ int32_t hx,ix;
+ double R,S,P,Q,s,y,z,r;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) { /* erfc(nan)=nan */
+ /* erfc(+-inf)=0,2 */
+ return (double)(((u_int32_t)hx>>31)<<1)+one/x;
+ }
+
+ if(ix < 0x3feb0000) { /* |x|<0.84375 */
+ if(ix < 0x3c700000) /* |x|<2**-56 */
+ return one-x;
+ z = x*x;
+ r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+ s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+ y = r/s;
+ if(hx < 0x3fd00000) { /* x<1/4 */
+ return one-(x+x*y);
+ } else {
+ r = x*y;
+ r += (x-half);
+ return half - r ;
+ }
+ }
+ if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */
+ s = fabs(x)-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+ if(hx>=0) {
+ z = one-erx; return z - P/Q;
+ } else {
+ z = erx+P/Q; return one+z;
+ }
+ }
+ if (ix < 0x403c0000) { /* |x|<28 */
+ x = fabs(x);
+ s = one/(x*x);
+ if(ix< 0x4006DB6D) { /* |x| < 1/.35 ~ 2.857143*/
+ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+ ra5+s*(ra6+s*ra7))))));
+ S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+ sa5+s*(sa6+s*(sa7+s*sa8)))))));
+ } else { /* |x| >= 1/.35 ~ 2.857143 */
+ if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */
+ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+ rb5+s*rb6)))));
+ S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+ sb5+s*(sb6+s*sb7))))));
+ }
+ z = x;
+ SET_LOW_WORD(z,0);
+ r = __ieee754_exp(-z*z-0.5625)*
+ __ieee754_exp((z-x)*(z+x)+R/S);
+ if(hx>0) return r/x; else return two-r/x;
+ } else {
+ if(hx>0) return tiny*tiny; else return two-tiny;
+ }
+}
diff --git a/lib/msun/src/s_erff.c b/lib/msun/src/s_erff.c
new file mode 100644
index 0000000..e9cc409
--- /dev/null
+++ b/lib/msun/src/s_erff.c
@@ -0,0 +1,223 @@
+/* s_erff.c -- float version of s_erf.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+tiny = 1e-30,
+half= 5.0000000000e-01, /* 0x3F000000 */
+one = 1.0000000000e+00, /* 0x3F800000 */
+two = 2.0000000000e+00, /* 0x40000000 */
+ /* c = (subfloat)0.84506291151 */
+erx = 8.4506291151e-01, /* 0x3f58560b */
+/*
+ * Coefficients for approximation to erf on [0,0.84375]
+ */
+efx = 1.2837916613e-01, /* 0x3e0375d4 */
+efx8= 1.0270333290e+00, /* 0x3f8375d4 */
+pp0 = 1.2837916613e-01, /* 0x3e0375d4 */
+pp1 = -3.2504209876e-01, /* 0xbea66beb */
+pp2 = -2.8481749818e-02, /* 0xbce9528f */
+pp3 = -5.7702702470e-03, /* 0xbbbd1489 */
+pp4 = -2.3763017452e-05, /* 0xb7c756b1 */
+qq1 = 3.9791721106e-01, /* 0x3ecbbbce */
+qq2 = 6.5022252500e-02, /* 0x3d852a63 */
+qq3 = 5.0813062117e-03, /* 0x3ba68116 */
+qq4 = 1.3249473704e-04, /* 0x390aee49 */
+qq5 = -3.9602282413e-06, /* 0xb684e21a */
+/*
+ * Coefficients for approximation to erf in [0.84375,1.25]
+ */
+pa0 = -2.3621185683e-03, /* 0xbb1acdc6 */
+pa1 = 4.1485610604e-01, /* 0x3ed46805 */
+pa2 = -3.7220788002e-01, /* 0xbebe9208 */
+pa3 = 3.1834661961e-01, /* 0x3ea2fe54 */
+pa4 = -1.1089469492e-01, /* 0xbde31cc2 */
+pa5 = 3.5478305072e-02, /* 0x3d1151b3 */
+pa6 = -2.1663755178e-03, /* 0xbb0df9c0 */
+qa1 = 1.0642088205e-01, /* 0x3dd9f331 */
+qa2 = 5.4039794207e-01, /* 0x3f0a5785 */
+qa3 = 7.1828655899e-02, /* 0x3d931ae7 */
+qa4 = 1.2617121637e-01, /* 0x3e013307 */
+qa5 = 1.3637083583e-02, /* 0x3c5f6e13 */
+qa6 = 1.1984500103e-02, /* 0x3c445aa3 */
+/*
+ * Coefficients for approximation to erfc in [1.25,1/0.35]
+ */
+ra0 = -9.8649440333e-03, /* 0xbc21a093 */
+ra1 = -6.9385856390e-01, /* 0xbf31a0b7 */
+ra2 = -1.0558626175e+01, /* 0xc128f022 */
+ra3 = -6.2375331879e+01, /* 0xc2798057 */
+ra4 = -1.6239666748e+02, /* 0xc322658c */
+ra5 = -1.8460508728e+02, /* 0xc3389ae7 */
+ra6 = -8.1287437439e+01, /* 0xc2a2932b */
+ra7 = -9.8143291473e+00, /* 0xc11d077e */
+sa1 = 1.9651271820e+01, /* 0x419d35ce */
+sa2 = 1.3765776062e+02, /* 0x4309a863 */
+sa3 = 4.3456588745e+02, /* 0x43d9486f */
+sa4 = 6.4538726807e+02, /* 0x442158c9 */
+sa5 = 4.2900814819e+02, /* 0x43d6810b */
+sa6 = 1.0863500214e+02, /* 0x42d9451f */
+sa7 = 6.5702495575e+00, /* 0x40d23f7c */
+sa8 = -6.0424413532e-02, /* 0xbd777f97 */
+/*
+ * Coefficients for approximation to erfc in [1/.35,28]
+ */
+rb0 = -9.8649431020e-03, /* 0xbc21a092 */
+rb1 = -7.9928326607e-01, /* 0xbf4c9dd4 */
+rb2 = -1.7757955551e+01, /* 0xc18e104b */
+rb3 = -1.6063638306e+02, /* 0xc320a2ea */
+rb4 = -6.3756646729e+02, /* 0xc41f6441 */
+rb5 = -1.0250950928e+03, /* 0xc480230b */
+rb6 = -4.8351919556e+02, /* 0xc3f1c275 */
+sb1 = 3.0338060379e+01, /* 0x41f2b459 */
+sb2 = 3.2579251099e+02, /* 0x43a2e571 */
+sb3 = 1.5367296143e+03, /* 0x44c01759 */
+sb4 = 3.1998581543e+03, /* 0x4547fdbb */
+sb5 = 2.5530502930e+03, /* 0x451f90ce */
+sb6 = 4.7452853394e+02, /* 0x43ed43a7 */
+sb7 = -2.2440952301e+01; /* 0xc1b38712 */
+
+#ifdef __STDC__
+ float erff(float x)
+#else
+ float erff(x)
+ float x;
+#endif
+{
+ int32_t hx,ix,i;
+ float R,S,P,Q,s,y,z,r;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7f800000) { /* erf(nan)=nan */
+ i = ((u_int32_t)hx>>31)<<1;
+ return (float)(1-i)+one/x; /* erf(+-inf)=+-1 */
+ }
+
+ if(ix < 0x3f580000) { /* |x|<0.84375 */
+ if(ix < 0x31800000) { /* |x|<2**-28 */
+ if (ix < 0x04000000)
+ /*avoid underflow */
+ return (float)0.125*((float)8.0*x+efx8*x);
+ return x + efx*x;
+ }
+ z = x*x;
+ r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+ s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+ y = r/s;
+ return x + x*y;
+ }
+ if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */
+ s = fabsf(x)-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+ if(hx>=0) return erx + P/Q; else return -erx - P/Q;
+ }
+ if (ix >= 0x40c00000) { /* inf>|x|>=6 */
+ if(hx>=0) return one-tiny; else return tiny-one;
+ }
+ x = fabsf(x);
+ s = one/(x*x);
+ if(ix< 0x4036DB6E) { /* |x| < 1/0.35 */
+ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+ ra5+s*(ra6+s*ra7))))));
+ S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+ sa5+s*(sa6+s*(sa7+s*sa8)))))));
+ } else { /* |x| >= 1/0.35 */
+ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+ rb5+s*rb6)))));
+ S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+ sb5+s*(sb6+s*sb7))))));
+ }
+ GET_FLOAT_WORD(ix,x);
+ SET_FLOAT_WORD(z,ix&0xfffff000);
+ r = __ieee754_expf(-z*z-(float)0.5625)*__ieee754_expf((z-x)*(z+x)+R/S);
+ if(hx>=0) return one-r/x; else return r/x-one;
+}
+
+#ifdef __STDC__
+ float erfcf(float x)
+#else
+ float erfcf(x)
+ float x;
+#endif
+{
+ int32_t hx,ix;
+ float R,S,P,Q,s,y,z,r;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7f800000) { /* erfc(nan)=nan */
+ /* erfc(+-inf)=0,2 */
+ return (float)(((u_int32_t)hx>>31)<<1)+one/x;
+ }
+
+ if(ix < 0x3f580000) { /* |x|<0.84375 */
+ if(ix < 0x23800000) /* |x|<2**-56 */
+ return one-x;
+ z = x*x;
+ r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+ s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+ y = r/s;
+ if(hx < 0x3e800000) { /* x<1/4 */
+ return one-(x+x*y);
+ } else {
+ r = x*y;
+ r += (x-half);
+ return half - r ;
+ }
+ }
+ if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */
+ s = fabsf(x)-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+ if(hx>=0) {
+ z = one-erx; return z - P/Q;
+ } else {
+ z = erx+P/Q; return one+z;
+ }
+ }
+ if (ix < 0x41e00000) { /* |x|<28 */
+ x = fabsf(x);
+ s = one/(x*x);
+ if(ix< 0x4036DB6D) { /* |x| < 1/.35 ~ 2.857143*/
+ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+ ra5+s*(ra6+s*ra7))))));
+ S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+ sa5+s*(sa6+s*(sa7+s*sa8)))))));
+ } else { /* |x| >= 1/.35 ~ 2.857143 */
+ if(hx<0&&ix>=0x40c00000) return two-tiny;/* x < -6 */
+ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+ rb5+s*rb6)))));
+ S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+ sb5+s*(sb6+s*sb7))))));
+ }
+ GET_FLOAT_WORD(ix,x);
+ SET_FLOAT_WORD(z,ix&0xfffff000);
+ r = __ieee754_expf(-z*z-(float)0.5625)*
+ __ieee754_expf((z-x)*(z+x)+R/S);
+ if(hx>0) return r/x; else return two-r/x;
+ } else {
+ if(hx>0) return tiny*tiny; else return two-tiny;
+ }
+}
diff --git a/lib/msun/src/s_expm1.c b/lib/msun/src/s_expm1.c
new file mode 100644
index 0000000..adc879b
--- /dev/null
+++ b/lib/msun/src/s_expm1.c
@@ -0,0 +1,228 @@
+/* @(#)s_expm1.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* expm1(x)
+ * Returns exp(x)-1, the exponential of x minus 1.
+ *
+ * Method
+ * 1. Argument reduction:
+ * Given x, find r and integer k such that
+ *
+ * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658
+ *
+ * Here a correction term c will be computed to compensate
+ * the error in r when rounded to a floating-point number.
+ *
+ * 2. Approximating expm1(r) by a special rational function on
+ * the interval [0,0.34658]:
+ * Since
+ * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
+ * we define R1(r*r) by
+ * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
+ * That is,
+ * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
+ * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
+ * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
+ * We use a special Reme algorithm on [0,0.347] to generate
+ * a polynomial of degree 5 in r*r to approximate R1. The
+ * maximum error of this polynomial approximation is bounded
+ * by 2**-61. In other words,
+ * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
+ * where Q1 = -1.6666666666666567384E-2,
+ * Q2 = 3.9682539681370365873E-4,
+ * Q3 = -9.9206344733435987357E-6,
+ * Q4 = 2.5051361420808517002E-7,
+ * Q5 = -6.2843505682382617102E-9;
+ * (where z=r*r, and the values of Q1 to Q5 are listed below)
+ * with error bounded by
+ * | 5 | -61
+ * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
+ * | |
+ *
+ * expm1(r) = exp(r)-1 is then computed by the following
+ * specific way which minimize the accumulation rounding error:
+ * 2 3
+ * r r [ 3 - (R1 + R1*r/2) ]
+ * expm1(r) = r + --- + --- * [--------------------]
+ * 2 2 [ 6 - r*(3 - R1*r/2) ]
+ *
+ * To compensate the error in the argument reduction, we use
+ * expm1(r+c) = expm1(r) + c + expm1(r)*c
+ * ~ expm1(r) + c + r*c
+ * Thus c+r*c will be added in as the correction terms for
+ * expm1(r+c). Now rearrange the term to avoid optimization
+ * screw up:
+ * ( 2 2 )
+ * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r )
+ * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
+ * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 )
+ * ( )
+ *
+ * = r - E
+ * 3. Scale back to obtain expm1(x):
+ * From step 1, we have
+ * expm1(x) = either 2^k*[expm1(r)+1] - 1
+ * = or 2^k*[expm1(r) + (1-2^-k)]
+ * 4. Implementation notes:
+ * (A). To save one multiplication, we scale the coefficient Qi
+ * to Qi*2^i, and replace z by (x^2)/2.
+ * (B). To achieve maximum accuracy, we compute expm1(x) by
+ * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
+ * (ii) if k=0, return r-E
+ * (iii) if k=-1, return 0.5*(r-E)-0.5
+ * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E)
+ * else return 1.0+2.0*(r-E);
+ * (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
+ * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else
+ * (vii) return 2^k(1-((E+2^-k)-r))
+ *
+ * Special cases:
+ * expm1(INF) is INF, expm1(NaN) is NaN;
+ * expm1(-INF) is -1, and
+ * for finite argument, only expm1(0)=0 is exact.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ * For IEEE double
+ * if x > 7.09782712893383973096e+02 then expm1(x) overflow
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.0,
+huge = 1.0e+300,
+tiny = 1.0e-300,
+o_threshold = 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */
+ln2_hi = 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */
+ln2_lo = 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */
+invln2 = 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */
+ /* scaled coefficients related to expm1 */
+Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */
+Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
+Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
+Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
+Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
+
+#ifdef __STDC__
+ double expm1(double x)
+#else
+ double expm1(x)
+ double x;
+#endif
+{
+ double y,hi,lo,c,t,e,hxs,hfx,r1;
+ int32_t k,xsb;
+ u_int32_t hx;
+
+ GET_HIGH_WORD(hx,x);
+ xsb = hx&0x80000000; /* sign bit of x */
+ if(xsb==0) y=x; else y= -x; /* y = |x| */
+ hx &= 0x7fffffff; /* high word of |x| */
+
+ /* filter out huge and non-finite argument */
+ if(hx >= 0x4043687A) { /* if |x|>=56*ln2 */
+ if(hx >= 0x40862E42) { /* if |x|>=709.78... */
+ if(hx>=0x7ff00000) {
+ u_int32_t low;
+ GET_LOW_WORD(low,x);
+ if(((hx&0xfffff)|low)!=0)
+ return x+x; /* NaN */
+ else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
+ }
+ if(x > o_threshold) return huge*huge; /* overflow */
+ }
+ if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */
+ if(x+tiny<0.0) /* raise inexact */
+ return tiny-one; /* return -1 */
+ }
+ }
+
+ /* argument reduction */
+ if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
+ if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
+ if(xsb==0)
+ {hi = x - ln2_hi; lo = ln2_lo; k = 1;}
+ else
+ {hi = x + ln2_hi; lo = -ln2_lo; k = -1;}
+ } else {
+ k = invln2*x+((xsb==0)?0.5:-0.5);
+ t = k;
+ hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
+ lo = t*ln2_lo;
+ }
+ x = hi - lo;
+ c = (hi-x)-lo;
+ }
+ else if(hx < 0x3c900000) { /* when |x|<2**-54, return x */
+ t = huge+x; /* return x with inexact flags when x!=0 */
+ return x - (t-(huge+x));
+ }
+ else k = 0;
+
+ /* x is now in primary range */
+ hfx = 0.5*x;
+ hxs = x*hfx;
+ r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
+ t = 3.0-r1*hfx;
+ e = hxs*((r1-t)/(6.0 - x*t));
+ if(k==0) return x - (x*e-hxs); /* c is 0 */
+ else {
+ e = (x*(e-c)-c);
+ e -= hxs;
+ if(k== -1) return 0.5*(x-e)-0.5;
+ if(k==1)
+ if(x < -0.25) return -2.0*(e-(x+0.5));
+ else return one+2.0*(x-e);
+ if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */
+ u_int32_t high;
+ y = one-(e-x);
+ GET_HIGH_WORD(high,y);
+ SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */
+ return y-one;
+ }
+ t = one;
+ if(k<20) {
+ u_int32_t high;
+ SET_HIGH_WORD(t,0x3ff00000 - (0x200000>>k)); /* t=1-2^-k */
+ y = t-(e-x);
+ GET_HIGH_WORD(high,y);
+ SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */
+ } else {
+ u_int32_t high;
+ SET_HIGH_WORD(t,((0x3ff-k)<<20)); /* 2^-k */
+ y = x-(e+t);
+ y += one;
+ GET_HIGH_WORD(high,y);
+ SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */
+ }
+ }
+ return y;
+}
diff --git a/lib/msun/src/s_expm1f.c b/lib/msun/src/s_expm1f.c
new file mode 100644
index 0000000..0fc0699
--- /dev/null
+++ b/lib/msun/src/s_expm1f.c
@@ -0,0 +1,133 @@
+/* s_expm1f.c -- float version of s_expm1.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0,
+huge = 1.0e+30,
+tiny = 1.0e-30,
+o_threshold = 8.8721679688e+01,/* 0x42b17180 */
+ln2_hi = 6.9313812256e-01,/* 0x3f317180 */
+ln2_lo = 9.0580006145e-06,/* 0x3717f7d1 */
+invln2 = 1.4426950216e+00,/* 0x3fb8aa3b */
+ /* scaled coefficients related to expm1 */
+Q1 = -3.3333335072e-02, /* 0xbd088889 */
+Q2 = 1.5873016091e-03, /* 0x3ad00d01 */
+Q3 = -7.9365076090e-05, /* 0xb8a670cd */
+Q4 = 4.0082177293e-06, /* 0x36867e54 */
+Q5 = -2.0109921195e-07; /* 0xb457edbb */
+
+#ifdef __STDC__
+ float expm1f(float x)
+#else
+ float expm1f(x)
+ float x;
+#endif
+{
+ float y,hi,lo,c,t,e,hxs,hfx,r1;
+ int32_t k,xsb;
+ u_int32_t hx;
+
+ GET_FLOAT_WORD(hx,x);
+ xsb = hx&0x80000000; /* sign bit of x */
+ if(xsb==0) y=x; else y= -x; /* y = |x| */
+ hx &= 0x7fffffff; /* high word of |x| */
+
+ /* filter out huge and non-finite argument */
+ if(hx >= 0x4195b844) { /* if |x|>=27*ln2 */
+ if(hx >= 0x42b17218) { /* if |x|>=88.721... */
+ if(hx>0x7f800000)
+ return x+x; /* NaN */
+ if(hx==0x7f800000)
+ return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
+ if(x > o_threshold) return huge*huge; /* overflow */
+ }
+ if(xsb!=0) { /* x < -27*ln2, return -1.0 with inexact */
+ if(x+tiny<(float)0.0) /* raise inexact */
+ return tiny-one; /* return -1 */
+ }
+ }
+
+ /* argument reduction */
+ if(hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
+ if(hx < 0x3F851592) { /* and |x| < 1.5 ln2 */
+ if(xsb==0)
+ {hi = x - ln2_hi; lo = ln2_lo; k = 1;}
+ else
+ {hi = x + ln2_hi; lo = -ln2_lo; k = -1;}
+ } else {
+ k = invln2*x+((xsb==0)?(float)0.5:(float)-0.5);
+ t = k;
+ hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
+ lo = t*ln2_lo;
+ }
+ x = hi - lo;
+ c = (hi-x)-lo;
+ }
+ else if(hx < 0x33000000) { /* when |x|<2**-25, return x */
+ t = huge+x; /* return x with inexact flags when x!=0 */
+ return x - (t-(huge+x));
+ }
+ else k = 0;
+
+ /* x is now in primary range */
+ hfx = (float)0.5*x;
+ hxs = x*hfx;
+ r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
+ t = (float)3.0-r1*hfx;
+ e = hxs*((r1-t)/((float)6.0 - x*t));
+ if(k==0) return x - (x*e-hxs); /* c is 0 */
+ else {
+ e = (x*(e-c)-c);
+ e -= hxs;
+ if(k== -1) return (float)0.5*(x-e)-(float)0.5;
+ if(k==1)
+ if(x < (float)-0.25) return -(float)2.0*(e-(x+(float)0.5));
+ else return one+(float)2.0*(x-e);
+ if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */
+ int32_t i;
+ y = one-(e-x);
+ GET_FLOAT_WORD(i,y);
+ SET_FLOAT_WORD(y,i+(k<<23)); /* add k to y's exponent */
+ return y-one;
+ }
+ t = one;
+ if(k<23) {
+ int32_t i;
+ SET_FLOAT_WORD(t,0x3f800000 - (0x1000000>>k)); /* t=1-2^-k */
+ y = t-(e-x);
+ GET_FLOAT_WORD(i,y);
+ SET_FLOAT_WORD(y,i+(k<<23)); /* add k to y's exponent */
+ } else {
+ int32_t i;
+ SET_FLOAT_WORD(t,((0x7f-k)<<23)); /* 2^-k */
+ y = x-(e+t);
+ y += one;
+ GET_FLOAT_WORD(i,y);
+ SET_FLOAT_WORD(y,i+(k<<23)); /* add k to y's exponent */
+ }
+ }
+ return y;
+}
diff --git a/lib/msun/src/s_fabs.c b/lib/msun/src/s_fabs.c
new file mode 100644
index 0000000..74e5913
--- /dev/null
+++ b/lib/msun/src/s_fabs.c
@@ -0,0 +1,35 @@
+/* @(#)s_fabs.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * fabs(x) returns the absolute value of x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double fabs(double x)
+#else
+ double fabs(x)
+ double x;
+#endif
+{
+ u_int32_t high;
+ GET_HIGH_WORD(high,x);
+ SET_HIGH_WORD(x,high&0x7fffffff);
+ return x;
+}
diff --git a/lib/msun/src/s_fabsf.c b/lib/msun/src/s_fabsf.c
new file mode 100644
index 0000000..b14ae6e
--- /dev/null
+++ b/lib/msun/src/s_fabsf.c
@@ -0,0 +1,38 @@
+/* s_fabsf.c -- float version of s_fabs.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * fabsf(x) returns the absolute value of x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float fabsf(float x)
+#else
+ float fabsf(x)
+ float x;
+#endif
+{
+ u_int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ SET_FLOAT_WORD(x,ix&0x7fffffff);
+ return x;
+}
diff --git a/lib/msun/src/s_finite.c b/lib/msun/src/s_finite.c
new file mode 100644
index 0000000..88e3298
--- /dev/null
+++ b/lib/msun/src/s_finite.c
@@ -0,0 +1,35 @@
+/* @(#)s_finite.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * finite(x) returns 1 is x is finite, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __generic_finite(double x)
+#else
+ int __generic_finite(x)
+ double x;
+#endif
+{
+ int32_t hx;
+ GET_HIGH_WORD(hx,x);
+ return (int)((u_int32_t)((hx&0x7fffffff)-0x7ff00000)>>31);
+}
diff --git a/lib/msun/src/s_finitef.c b/lib/msun/src/s_finitef.c
new file mode 100644
index 0000000..07038db
--- /dev/null
+++ b/lib/msun/src/s_finitef.c
@@ -0,0 +1,38 @@
+/* s_finitef.c -- float version of s_finite.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * finitef(x) returns 1 is x is finite, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int finitef(float x)
+#else
+ int finitef(x)
+ float x;
+#endif
+{
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ return (int)((u_int32_t)((ix&0x7fffffff)-0x7f800000)>>31);
+}
diff --git a/lib/msun/src/s_floor.c b/lib/msun/src/s_floor.c
new file mode 100644
index 0000000..85ace77
--- /dev/null
+++ b/lib/msun/src/s_floor.c
@@ -0,0 +1,81 @@
+/* @(#)s_floor.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * floor(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to floor(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double huge = 1.0e300;
+#else
+static double huge = 1.0e300;
+#endif
+
+#ifdef __STDC__
+ double __generic_floor(double x)
+#else
+ double __generic_floor(x)
+ double x;
+#endif
+{
+ int32_t i0,i1,j0;
+ u_int32_t i,j;
+ EXTRACT_WORDS(i0,i1,x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0>=0) {i0=i1=0;}
+ else if(((i0&0x7fffffff)|i1)!=0)
+ { i0=0xbff00000;i1=0;}
+ }
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0<0) i0 += (0x00100000)>>j0;
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0<0) {
+ if(j0==20) i0+=1;
+ else {
+ j = i1+(1<<(52-j0));
+ if(j<i1) i0 +=1 ; /* got a carry */
+ i1=j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ INSERT_WORDS(x,i0,i1);
+ return x;
+}
diff --git a/lib/msun/src/s_floorf.c b/lib/msun/src/s_floorf.c
new file mode 100644
index 0000000..116ec1d
--- /dev/null
+++ b/lib/msun/src/s_floorf.c
@@ -0,0 +1,70 @@
+/* s_floorf.c -- float version of s_floor.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * floorf(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to floorf(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float huge = 1.0e30;
+#else
+static float huge = 1.0e30;
+#endif
+
+#ifdef __STDC__
+ float floorf(float x)
+#else
+ float floorf(x)
+ float x;
+#endif
+{
+ int32_t i0,j0;
+ u_int32_t i;
+ GET_FLOAT_WORD(i0,x);
+ j0 = ((i0>>23)&0xff)-0x7f;
+ if(j0<23) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0>=0) {i0=0;}
+ else if((i0&0x7fffffff)!=0)
+ { i0=0xbf800000;}
+ }
+ } else {
+ i = (0x007fffff)>>j0;
+ if((i0&i)==0) return x; /* x is integral */
+ if(huge+x>(float)0.0) { /* raise inexact flag */
+ if(i0<0) i0 += (0x00800000)>>j0;
+ i0 &= (~i);
+ }
+ }
+ } else {
+ if(j0==0x80) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ }
+ SET_FLOAT_WORD(x,i0);
+ return x;
+}
diff --git a/lib/msun/src/s_frexp.c b/lib/msun/src/s_frexp.c
new file mode 100644
index 0000000..178479d
--- /dev/null
+++ b/lib/msun/src/s_frexp.c
@@ -0,0 +1,59 @@
+/* @(#)s_frexp.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * for non-zero x
+ * x = frexp(arg,&exp);
+ * return a double fp quantity x such that 0.5 <= |x| <1.0
+ * and the corresponding binary exponent "exp". That is
+ * arg = x*2^exp.
+ * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg
+ * with *exp=0.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
+
+#ifdef __STDC__
+ double frexp(double x, int *eptr)
+#else
+ double frexp(x, eptr)
+ double x; int *eptr;
+#endif
+{
+ int32_t hx, ix, lx;
+ EXTRACT_WORDS(hx,lx,x);
+ ix = 0x7fffffff&hx;
+ *eptr = 0;
+ if(ix>=0x7ff00000||((ix|lx)==0)) return x; /* 0,inf,nan */
+ if (ix<0x00100000) { /* subnormal */
+ x *= two54;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ *eptr = -54;
+ }
+ *eptr += (ix>>20)-1022;
+ hx = (hx&0x800fffff)|0x3fe00000;
+ SET_HIGH_WORD(x,hx);
+ return x;
+}
diff --git a/lib/msun/src/s_frexpf.c b/lib/msun/src/s_frexpf.c
new file mode 100644
index 0000000..fbec667
--- /dev/null
+++ b/lib/msun/src/s_frexpf.c
@@ -0,0 +1,52 @@
+/* s_frexpf.c -- float version of s_frexp.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+two25 = 3.3554432000e+07; /* 0x4c000000 */
+
+#ifdef __STDC__
+ float frexpf(float x, int *eptr)
+#else
+ float frexpf(x, eptr)
+ float x; int *eptr;
+#endif
+{
+ int32_t hx,ix;
+ GET_FLOAT_WORD(hx,x);
+ ix = 0x7fffffff&hx;
+ *eptr = 0;
+ if(ix>=0x7f800000||(ix==0)) return x; /* 0,inf,nan */
+ if (ix<0x00800000) { /* subnormal */
+ x *= two25;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ *eptr = -25;
+ }
+ *eptr += (ix>>23)-126;
+ hx = (hx&0x807fffff)|0x3f000000;
+ *(int*)&x = hx;
+ return x;
+}
diff --git a/lib/msun/src/s_ilogb.c b/lib/msun/src/s_ilogb.c
new file mode 100644
index 0000000..d2c8265
--- /dev/null
+++ b/lib/msun/src/s_ilogb.c
@@ -0,0 +1,50 @@
+/* @(#)s_ilogb.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* ilogb(double x)
+ * return the binary exponent of non-zero x
+ * ilogb(0) = 0x80000001
+ * ilogb(inf/NaN) = 0x7fffffff (no signal is raised)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __generic_ilogb(double x)
+#else
+ int __generic_ilogb(x)
+ double x;
+#endif
+{
+ int32_t hx,lx,ix;
+
+ EXTRACT_WORDS(hx,lx,x);
+ hx &= 0x7fffffff;
+ if(hx<0x00100000) {
+ if((hx|lx)==0)
+ return 0x80000001; /* ilogb(0) = 0x80000001 */
+ else /* subnormal x */
+ if(hx==0) {
+ for (ix = -1043; lx>0; lx<<=1) ix -=1;
+ } else {
+ for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
+ }
+ return ix;
+ }
+ else if (hx<0x7ff00000) return (hx>>20)-1023;
+ else return 0x7fffffff;
+}
diff --git a/lib/msun/src/s_ilogbf.c b/lib/msun/src/s_ilogbf.c
new file mode 100644
index 0000000..a912d1a
--- /dev/null
+++ b/lib/msun/src/s_ilogbf.c
@@ -0,0 +1,43 @@
+/* s_ilogbf.c -- float version of s_ilogb.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int ilogbf(float x)
+#else
+ int ilogbf(x)
+ float x;
+#endif
+{
+ int32_t hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+ hx &= 0x7fffffff;
+ if(hx<0x00800000) {
+ if(hx==0)
+ return 0x80000001; /* ilogb(0) = 0x80000001 */
+ else /* subnormal x */
+ for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1;
+ return ix;
+ }
+ else if (hx<0x7f800000) return (hx>>23)-127;
+ else return 0x7fffffff;
+}
diff --git a/lib/msun/src/s_isnan.c b/lib/msun/src/s_isnan.c
new file mode 100644
index 0000000..18cfcf2
--- /dev/null
+++ b/lib/msun/src/s_isnan.c
@@ -0,0 +1,38 @@
+/* @(#)s_isnan.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * isnan(x) returns 1 is x is nan, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int isnan(double x)
+#else
+ int isnan(x)
+ double x;
+#endif
+{
+ int32_t hx,lx;
+ EXTRACT_WORDS(hx,lx,x);
+ hx &= 0x7fffffff;
+ hx |= (u_int32_t)(lx|(-lx))>>31;
+ hx = 0x7ff00000 - hx;
+ return (int)((u_int32_t)(hx))>>31;
+}
diff --git a/lib/msun/src/s_isnanf.c b/lib/msun/src/s_isnanf.c
new file mode 100644
index 0000000..0e48718
--- /dev/null
+++ b/lib/msun/src/s_isnanf.c
@@ -0,0 +1,40 @@
+/* s_isnanf.c -- float version of s_isnan.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * isnanf(x) returns 1 is x is nan, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int isnanf(float x)
+#else
+ int isnanf(x)
+ float x;
+#endif
+{
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+ ix = 0x7f800000 - ix;
+ return (int)(((u_int32_t)(ix))>>31);
+}
diff --git a/lib/msun/src/s_ldexp.c b/lib/msun/src/s_ldexp.c
new file mode 100644
index 0000000..4631701
--- /dev/null
+++ b/lib/msun/src/s_ldexp.c
@@ -0,0 +1,32 @@
+/* @(#)s_ldexp.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+#include <errno.h>
+
+#ifdef __STDC__
+ double ldexp(double value, int exp)
+#else
+ double ldexp(value, exp)
+ double value; int exp;
+#endif
+{
+ if(!finite(value)||value==0.0) return value;
+ value = scalbn(value,exp);
+ if(!finite(value)||value==0.0) errno = ERANGE;
+ return value;
+}
diff --git a/lib/msun/src/s_ldexpf.c b/lib/msun/src/s_ldexpf.c
new file mode 100644
index 0000000..5091873
--- /dev/null
+++ b/lib/msun/src/s_ldexpf.c
@@ -0,0 +1,35 @@
+/* s_ldexpf.c -- float version of s_ldexp.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+#include <errno.h>
+
+#ifdef __STDC__
+ float ldexpf(float value, int exp)
+#else
+ float ldexpf(value, exp)
+ float value; int exp;
+#endif
+{
+ if(!finitef(value)||value==(float)0.0) return value;
+ value = scalbnf(value,exp);
+ if(!finitef(value)||value==(float)0.0) errno = ERANGE;
+ return value;
+}
diff --git a/lib/msun/src/s_lib_version.c b/lib/msun/src/s_lib_version.c
new file mode 100644
index 0000000..29269d3
--- /dev/null
+++ b/lib/msun/src/s_lib_version.c
@@ -0,0 +1,39 @@
+/* @(#)s_lib_ver.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * MACRO for standards
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+/*
+ * define and initialize _LIB_VERSION
+ */
+#ifdef _POSIX_MODE
+_LIB_VERSION_TYPE _LIB_VERSION = _POSIX_;
+#else
+#ifdef _XOPEN_MODE
+_LIB_VERSION_TYPE _LIB_VERSION = _XOPEN_;
+#else
+#ifdef _SVID3_MODE
+_LIB_VERSION_TYPE _LIB_VERSION = _SVID_;
+#else /* default _IEEE_MODE */
+_LIB_VERSION_TYPE _LIB_VERSION = _IEEE_;
+#endif
+#endif
+#endif
diff --git a/lib/msun/src/s_log1p.c b/lib/msun/src/s_log1p.c
new file mode 100644
index 0000000..0a60f95
--- /dev/null
+++ b/lib/msun/src/s_log1p.c
@@ -0,0 +1,173 @@
+/* @(#)s_log1p.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* double log1p(double x)
+ *
+ * Method :
+ * 1. Argument Reduction: find k and f such that
+ * 1+x = 2^k * (1+f),
+ * where sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ * Note. If k=0, then f=x is exact. However, if k!=0, then f
+ * may not be representable exactly. In that case, a correction
+ * term is need. Let u=1+x rounded. Let c = (1+x)-u, then
+ * log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),
+ * and add back the correction term c/u.
+ * (Note: when x > 2**53, one can simply return log(x))
+ *
+ * 2. Approximation of log1p(f).
+ * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ * = 2s + s*R
+ * We use a special Reme algorithm on [0,0.1716] to generate
+ * a polynomial of degree 14 to approximate R The maximum error
+ * of this polynomial approximation is bounded by 2**-58.45. In
+ * other words,
+ * 2 4 6 8 10 12 14
+ * R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s +Lp6*s +Lp7*s
+ * (the values of Lp1 to Lp7 are listed in the program)
+ * and
+ * | 2 14 | -58.45
+ * | Lp1*s +...+Lp7*s - R(z) | <= 2
+ * | |
+ * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ * In order to guarantee error in log below 1ulp, we compute log
+ * by
+ * log1p(f) = f - (hfsq - s*(hfsq+R)).
+ *
+ * 3. Finally, log1p(x) = k*ln2 + log1p(f).
+ * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ * Here ln2 is split into two floating point number:
+ * ln2_hi + ln2_lo,
+ * where n*ln2_hi is always exact for |n| < 2000.
+ *
+ * Special cases:
+ * log1p(x) is NaN with signal if x < -1 (including -INF) ;
+ * log1p(+INF) is +INF; log1p(-1) is -INF with signal;
+ * log1p(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ *
+ * Note: Assuming log() return accurate answer, the following
+ * algorithm can be used to compute log1p(x) to within a few ULP:
+ *
+ * u = 1+x;
+ * if(u==1.0) return x ; else
+ * return log(u)*(x/(u-1.0));
+ *
+ * See HP-15C Advanced Functions Handbook, p.193.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
+ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
+two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */
+Lp1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
+Lp2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
+Lp3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
+Lp4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
+Lp5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
+Lp6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
+Lp7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double log1p(double x)
+#else
+ double log1p(x)
+ double x;
+#endif
+{
+ double hfsq,f,c,s,z,R,u;
+ int32_t k,hx,hu,ax;
+
+ GET_HIGH_WORD(hx,x);
+ ax = hx&0x7fffffff;
+
+ k = 1;
+ if (hx < 0x3FDA827A) { /* x < 0.41422 */
+ if(ax>=0x3ff00000) { /* x <= -1.0 */
+ if(x==-1.0) return -two54/zero; /* log1p(-1)=+inf */
+ else return (x-x)/(x-x); /* log1p(x<-1)=NaN */
+ }
+ if(ax<0x3e200000) { /* |x| < 2**-29 */
+ if(two54+x>zero /* raise inexact */
+ &&ax<0x3c900000) /* |x| < 2**-54 */
+ return x;
+ else
+ return x - x*x*0.5;
+ }
+ if(hx>0||hx<=((int32_t)0xbfd2bec3)) {
+ k=0;f=x;hu=1;} /* -0.2929<x<0.41422 */
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ if(k!=0) {
+ if(hx<0x43400000) {
+ u = 1.0+x;
+ GET_HIGH_WORD(hu,u);
+ k = (hu>>20)-1023;
+ c = (k>0)? 1.0-(u-x):x-(u-1.0);/* correction term */
+ c /= u;
+ } else {
+ u = x;
+ GET_HIGH_WORD(hu,u);
+ k = (hu>>20)-1023;
+ c = 0;
+ }
+ hu &= 0x000fffff;
+ if(hu<0x6a09e) {
+ SET_HIGH_WORD(u,hu|0x3ff00000); /* normalize u */
+ } else {
+ k += 1;
+ SET_HIGH_WORD(u,hu|0x3fe00000); /* normalize u/2 */
+ hu = (0x00100000-hu)>>2;
+ }
+ f = u-1.0;
+ }
+ hfsq=0.5*f*f;
+ if(hu==0) { /* |f| < 2**-20 */
+ if(f==zero) if(k==0) return zero;
+ else {c += k*ln2_lo; return k*ln2_hi+c;}
+ R = hfsq*(1.0-0.66666666666666666*f);
+ if(k==0) return f-R; else
+ return k*ln2_hi-((R-(k*ln2_lo+c))-f);
+ }
+ s = f/(2.0+f);
+ z = s*s;
+ R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7))))));
+ if(k==0) return f-(hfsq-s*(hfsq+R)); else
+ return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f);
+}
diff --git a/lib/msun/src/s_log1pf.c b/lib/msun/src/s_log1pf.c
new file mode 100644
index 0000000..2923d01
--- /dev/null
+++ b/lib/msun/src/s_log1pf.c
@@ -0,0 +1,112 @@
+/* s_log1pf.c -- float version of s_log1p.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
+ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
+two25 = 3.355443200e+07, /* 0x4c000000 */
+Lp1 = 6.6666668653e-01, /* 3F2AAAAB */
+Lp2 = 4.0000000596e-01, /* 3ECCCCCD */
+Lp3 = 2.8571429849e-01, /* 3E924925 */
+Lp4 = 2.2222198546e-01, /* 3E638E29 */
+Lp5 = 1.8183572590e-01, /* 3E3A3325 */
+Lp6 = 1.5313838422e-01, /* 3E1CD04F */
+Lp7 = 1.4798198640e-01; /* 3E178897 */
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float log1pf(float x)
+#else
+ float log1pf(x)
+ float x;
+#endif
+{
+ float hfsq,f,c,s,z,R,u;
+ int32_t k,hx,hu,ax;
+
+ GET_FLOAT_WORD(hx,x);
+ ax = hx&0x7fffffff;
+
+ k = 1;
+ if (hx < 0x3ed413d7) { /* x < 0.41422 */
+ if(ax>=0x3f800000) { /* x <= -1.0 */
+ if(x==(float)-1.0) return -two25/zero; /* log1p(-1)=+inf */
+ else return (x-x)/(x-x); /* log1p(x<-1)=NaN */
+ }
+ if(ax<0x31000000) { /* |x| < 2**-29 */
+ if(two25+x>zero /* raise inexact */
+ &&ax<0x24800000) /* |x| < 2**-54 */
+ return x;
+ else
+ return x - x*x*(float)0.5;
+ }
+ if(hx>0||hx<=((int32_t)0xbe95f61f)) {
+ k=0;f=x;hu=1;} /* -0.2929<x<0.41422 */
+ }
+ if (hx >= 0x7f800000) return x+x;
+ if(k!=0) {
+ if(hx<0x5a000000) {
+ u = (float)1.0+x;
+ GET_FLOAT_WORD(hu,u);
+ k = (hu>>23)-127;
+ /* correction term */
+ c = (k>0)? (float)1.0-(u-x):x-(u-(float)1.0);
+ c /= u;
+ } else {
+ u = x;
+ GET_FLOAT_WORD(hu,u);
+ k = (hu>>23)-127;
+ c = 0;
+ }
+ hu &= 0x007fffff;
+ if(hu<0x3504f7) {
+ SET_FLOAT_WORD(u,hu|0x3f800000);/* normalize u */
+ } else {
+ k += 1;
+ SET_FLOAT_WORD(u,hu|0x3f000000); /* normalize u/2 */
+ hu = (0x00800000-hu)>>2;
+ }
+ f = u-(float)1.0;
+ }
+ hfsq=(float)0.5*f*f;
+ if(hu==0) { /* |f| < 2**-20 */
+ if(f==zero) if(k==0) return zero;
+ else {c += k*ln2_lo; return k*ln2_hi+c;}
+ R = hfsq*((float)1.0-(float)0.66666666666666666*f);
+ if(k==0) return f-R; else
+ return k*ln2_hi-((R-(k*ln2_lo+c))-f);
+ }
+ s = f/((float)2.0+f);
+ z = s*s;
+ R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7))))));
+ if(k==0) return f-(hfsq-s*(hfsq+R)); else
+ return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f);
+}
diff --git a/lib/msun/src/s_logb.c b/lib/msun/src/s_logb.c
new file mode 100644
index 0000000..8b724f4
--- /dev/null
+++ b/lib/msun/src/s_logb.c
@@ -0,0 +1,42 @@
+/* @(#)s_logb.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * double logb(x)
+ * IEEE 754 logb. Included to pass IEEE test suite. Not recommend.
+ * Use ilogb instead.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __generic_logb(double x)
+#else
+ double __generic_logb(x)
+ double x;
+#endif
+{
+ int32_t lx,ix;
+ EXTRACT_WORDS(ix,lx,x);
+ ix &= 0x7fffffff; /* high |x| */
+ if((ix|lx)==0) return -1.0/fabs(x);
+ if(ix>=0x7ff00000) return x*x;
+ if((ix>>=20)==0) /* IEEE 754 logb */
+ return -1022.0;
+ else
+ return (double) (ix-1023);
+}
diff --git a/lib/msun/src/s_logbf.c b/lib/msun/src/s_logbf.c
new file mode 100644
index 0000000..1d34543
--- /dev/null
+++ b/lib/msun/src/s_logbf.c
@@ -0,0 +1,39 @@
+/* s_logbf.c -- float version of s_logb.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float logbf(float x)
+#else
+ float logbf(x)
+ float x;
+#endif
+{
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff; /* high |x| */
+ if(ix==0) return (float)-1.0/fabsf(x);
+ if(ix>=0x7f800000) return x*x;
+ if((ix>>=23)==0) /* IEEE 754 logb */
+ return -126.0;
+ else
+ return (float) (ix-127);
+}
diff --git a/lib/msun/src/s_matherr.c b/lib/msun/src/s_matherr.c
new file mode 100644
index 0000000..3f7a827
--- /dev/null
+++ b/lib/msun/src/s_matherr.c
@@ -0,0 +1,30 @@
+/* @(#)s_matherr.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int matherr(struct exception *x)
+#else
+ int matherr(x)
+ struct exception *x;
+#endif
+{
+ int n=0;
+ if(x->arg1!=x->arg1) return 0;
+ return n;
+}
diff --git a/lib/msun/src/s_modf.c b/lib/msun/src/s_modf.c
new file mode 100644
index 0000000..50a261d
--- /dev/null
+++ b/lib/msun/src/s_modf.c
@@ -0,0 +1,83 @@
+/* @(#)s_modf.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * modf(double x, double *iptr)
+ * return fraction part of x, and return x's integral part in *iptr.
+ * Method:
+ * Bit twiddling.
+ *
+ * Exception:
+ * No exception.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one = 1.0;
+#else
+static double one = 1.0;
+#endif
+
+#ifdef __STDC__
+ double modf(double x, double *iptr)
+#else
+ double modf(x, iptr)
+ double x,*iptr;
+#endif
+{
+ int32_t i0,i1,j0;
+ u_int32_t i;
+ EXTRACT_WORDS(i0,i1,x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */
+ if(j0<20) { /* integer part in high x */
+ if(j0<0) { /* |x|<1 */
+ INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */
+ return x;
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) { /* x is integral */
+ u_int32_t high;
+ *iptr = x;
+ GET_HIGH_WORD(high,x);
+ INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
+ return x;
+ } else {
+ INSERT_WORDS(*iptr,i0&(~i),0);
+ return x - *iptr;
+ }
+ }
+ } else if (j0>51) { /* no fraction part */
+ u_int32_t high;
+ *iptr = x*one;
+ GET_HIGH_WORD(high,x);
+ INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
+ return x;
+ } else { /* fraction part in low x */
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) { /* x is integral */
+ u_int32_t high;
+ *iptr = x;
+ GET_HIGH_WORD(high,x);
+ INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
+ return x;
+ } else {
+ INSERT_WORDS(*iptr,i0,i1&(~i));
+ return x - *iptr;
+ }
+ }
+}
diff --git a/lib/msun/src/s_modff.c b/lib/msun/src/s_modff.c
new file mode 100644
index 0000000..bedb49f
--- /dev/null
+++ b/lib/msun/src/s_modff.c
@@ -0,0 +1,64 @@
+/* s_modff.c -- float version of s_modf.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one = 1.0;
+#else
+static float one = 1.0;
+#endif
+
+#ifdef __STDC__
+ float modff(float x, float *iptr)
+#else
+ float modff(x, iptr)
+ float x,*iptr;
+#endif
+{
+ int32_t i0,j0;
+ u_int32_t i;
+ GET_FLOAT_WORD(i0,x);
+ j0 = ((i0>>23)&0xff)-0x7f; /* exponent of x */
+ if(j0<23) { /* integer part in x */
+ if(j0<0) { /* |x|<1 */
+ SET_FLOAT_WORD(*iptr,i0&0x80000000); /* *iptr = +-0 */
+ return x;
+ } else {
+ i = (0x007fffff)>>j0;
+ if((i0&i)==0) { /* x is integral */
+ u_int32_t ix;
+ *iptr = x;
+ GET_FLOAT_WORD(ix,x);
+ SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */
+ return x;
+ } else {
+ SET_FLOAT_WORD(*iptr,i0&(~i));
+ return x - *iptr;
+ }
+ }
+ } else { /* no fraction part */
+ u_int32_t ix;
+ *iptr = x*one;
+ GET_FLOAT_WORD(ix,x);
+ SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */
+ return x;
+ }
+}
diff --git a/lib/msun/src/s_nextafter.c b/lib/msun/src/s_nextafter.c
new file mode 100644
index 0000000..a54b823
--- /dev/null
+++ b/lib/msun/src/s_nextafter.c
@@ -0,0 +1,79 @@
+/* @(#)s_nextafter.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* IEEE functions
+ * nextafter(x,y)
+ * return the next machine floating-point number of x in the
+ * direction toward y.
+ * Special cases:
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double nextafter(double x, double y)
+#else
+ double nextafter(x,y)
+ double x,y;
+#endif
+{
+ int32_t hx,hy,ix,iy;
+ u_int32_t lx,ly;
+
+ EXTRACT_WORDS(hx,lx,x);
+ EXTRACT_WORDS(hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = hy&0x7fffffff; /* |y| */
+
+ if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */
+ ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */
+ return x+y;
+ if(x==y) return x; /* x=y, return x */
+ if((ix|lx)==0) { /* x == 0 */
+ INSERT_WORDS(x,hy&0x80000000,1); /* return +-minsubnormal */
+ y = x*x;
+ if(y==x) return y; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { /* x < y, x += ulp */
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ } else { /* x < 0 */
+ if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { /* x > y, x += ulp */
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ }
+ hy = hx&0x7ff00000;
+ if(hy>=0x7ff00000) return x+x; /* overflow */
+ if(hy<0x00100000) { /* underflow */
+ y = x*x;
+ if(y!=x) { /* raise underflow flag */
+ INSERT_WORDS(y,hx,lx);
+ return y;
+ }
+ }
+ INSERT_WORDS(x,hx,lx);
+ return x;
+}
diff --git a/lib/msun/src/s_nextafterf.c b/lib/msun/src/s_nextafterf.c
new file mode 100644
index 0000000..d976a20
--- /dev/null
+++ b/lib/msun/src/s_nextafterf.c
@@ -0,0 +1,70 @@
+/* s_nextafterf.c -- float version of s_nextafter.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float nextafterf(float x, float y)
+#else
+ float nextafterf(x,y)
+ float x,y;
+#endif
+{
+ int32_t hx,hy,ix,iy;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_FLOAT_WORD(hy,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = hy&0x7fffffff; /* |y| */
+
+ if((ix>0x7f800000) || /* x is nan */
+ (iy>0x7f800000)) /* y is nan */
+ return x+y;
+ if(x==y) return x; /* x=y, return x */
+ if(ix==0) { /* x == 0 */
+ SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */
+ y = x*x;
+ if(y==x) return y; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if(hx>hy) { /* x > y, x -= ulp */
+ hx -= 1;
+ } else { /* x < y, x += ulp */
+ hx += 1;
+ }
+ } else { /* x < 0 */
+ if(hy>=0||hx>hy){ /* x < y, x -= ulp */
+ hx -= 1;
+ } else { /* x > y, x += ulp */
+ hx += 1;
+ }
+ }
+ hy = hx&0x7f800000;
+ if(hy>=0x7f800000) return x+x; /* overflow */
+ if(hy<0x00800000) { /* underflow */
+ y = x*x;
+ if(y!=x) { /* raise underflow flag */
+ SET_FLOAT_WORD(y,hx);
+ return y;
+ }
+ }
+ SET_FLOAT_WORD(x,hx);
+ return x;
+}
diff --git a/lib/msun/src/s_rint.c b/lib/msun/src/s_rint.c
new file mode 100644
index 0000000..aa41452
--- /dev/null
+++ b/lib/msun/src/s_rint.c
@@ -0,0 +1,93 @@
+/* @(#)s_rint.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * rint(x)
+ * Return x rounded to integral value according to the prevailing
+ * rounding mode.
+ * Method:
+ * Using floating addition.
+ * Exception:
+ * Inexact flag raised if x not equal to rint(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+/*
+ * TWO23 is long double instead of double to avoid a bug in gcc. Without
+ * this, gcc thinks that TWO23[sx]+x and w-TWO23[sx] already have double
+ * precision and doesn't clip them to double precision when they are
+ * assigned and returned. Use long double even in the !__STDC__ case in
+ * case this is compiled with gcc -traditional.
+ */
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+TWO52[2]={
+ 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+};
+
+#ifdef __STDC__
+ double __generic_rint(double x)
+#else
+ double __generic_rint(x)
+ double x;
+#endif
+{
+ int32_t i0,j0,sx;
+ u_int32_t i,i1;
+ double w,t;
+ EXTRACT_WORDS(i0,i1,x);
+ sx = (i0>>31)&1;
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) {
+ if(((i0&0x7fffffff)|i1)==0) return x;
+ i1 |= (i0&0x0fffff);
+ i0 &= 0xfffe0000;
+ i0 |= ((i1|-i1)>>12)&0x80000;
+ SET_HIGH_WORD(x,i0);
+ w = TWO52[sx]+x;
+ t = w-TWO52[sx];
+ GET_HIGH_WORD(i0,t);
+ SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
+ return t;
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ i>>=1;
+ if(((i0&i)|i1)!=0) {
+ if(j0==19) i1 = 0x40000000; else
+ i0 = (i0&(~i))|((0x20000)>>j0);
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ i>>=1;
+ if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
+ }
+ INSERT_WORDS(x,i0,i1);
+ w = TWO52[sx]+x;
+ return w-TWO52[sx];
+}
diff --git a/lib/msun/src/s_rintf.c b/lib/msun/src/s_rintf.c
new file mode 100644
index 0000000..3bb8b1c
--- /dev/null
+++ b/lib/msun/src/s_rintf.c
@@ -0,0 +1,77 @@
+/* s_rintf.c -- float version of s_rint.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+/*
+ * TWO23 is double instead of float to avoid a bug in gcc. Without
+ * this, gcc thinks that TWO23[sx]+x and w-TWO23[sx] already have float
+ * precision and doesn't clip them to float precision when they are
+ * assigned and returned.
+ */
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+TWO23[2]={
+ 8.3886080000e+06, /* 0x4b000000 */
+ -8.3886080000e+06, /* 0xcb000000 */
+};
+
+#ifdef __STDC__
+ float rintf(float x)
+#else
+ float rintf(x)
+ float x;
+#endif
+{
+ int32_t i0,j0,sx;
+ u_int32_t i,i1;
+ float w,t;
+ GET_FLOAT_WORD(i0,x);
+ sx = (i0>>31)&1;
+ j0 = ((i0>>23)&0xff)-0x7f;
+ if(j0<23) {
+ if(j0<0) {
+ if((i0&0x7fffffff)==0) return x;
+ i1 = (i0&0x07fffff);
+ i0 &= 0xfff00000;
+ i0 |= ((i1|-i1)>>9)&0x400000;
+ SET_FLOAT_WORD(x,i0);
+ w = TWO23[sx]+x;
+ t = w-TWO23[sx];
+ GET_FLOAT_WORD(i0,t);
+ SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
+ return t;
+ } else {
+ i = (0x007fffff)>>j0;
+ if((i0&i)==0) return x; /* x is integral */
+ i>>=1;
+ if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
+ }
+ } else {
+ if(j0==0x80) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ }
+ SET_FLOAT_WORD(x,i0);
+ w = TWO23[sx]+x;
+ return w-TWO23[sx];
+}
diff --git a/lib/msun/src/s_scalbn.c b/lib/msun/src/s_scalbn.c
new file mode 100644
index 0000000..b69bdcd
--- /dev/null
+++ b/lib/msun/src/s_scalbn.c
@@ -0,0 +1,66 @@
+/* @(#)s_scalbn.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * scalbn (double x, int n)
+ * scalbn(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
+huge = 1.0e+300,
+tiny = 1.0e-300;
+
+#ifdef __STDC__
+ double __generic_scalbn (double x, int n)
+#else
+ double __generic_scalbn (x,n)
+ double x; int n;
+#endif
+{
+ int32_t k,hx,lx;
+ EXTRACT_WORDS(hx,lx,x);
+ k = (hx&0x7ff00000)>>20; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+ x *= two54;
+ GET_HIGH_WORD(hx,x);
+ k = ((hx&0x7ff00000)>>20) - 54;
+ if (n< -50000) return tiny*x; /*underflow*/
+ }
+ if (k==0x7ff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */
+ if (k > 0) /* normal result */
+ {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
+ if (k <= -54)
+ if (n > 50000) /* in case integer overflow in n+k */
+ return huge*copysign(huge,x); /*overflow*/
+ else return tiny*copysign(tiny,x); /*underflow*/
+ k += 54; /* subnormal result */
+ SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
+ return x*twom54;
+}
diff --git a/lib/msun/src/s_scalbnf.c b/lib/msun/src/s_scalbnf.c
new file mode 100644
index 0000000..7dd7595
--- /dev/null
+++ b/lib/msun/src/s_scalbnf.c
@@ -0,0 +1,62 @@
+/* s_scalbnf.c -- float version of s_scalbn.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+two25 = 3.355443200e+07, /* 0x4c000000 */
+twom25 = 2.9802322388e-08, /* 0x33000000 */
+huge = 1.0e+30,
+tiny = 1.0e-30;
+
+#ifdef __STDC__
+ float scalbnf (float x, int n)
+#else
+ float scalbn (x,n)
+ float x; int n;
+#endif
+{
+ int32_t k,ix;
+ GET_FLOAT_WORD(ix,x);
+ k = (ix&0x7f800000)>>23; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((ix&0x7fffffff)==0) return x; /* +-0 */
+ x *= two25;
+ GET_FLOAT_WORD(ix,x);
+ k = ((ix&0x7f800000)>>23) - 25;
+ if (n< -50000) return tiny*x; /*underflow*/
+ }
+ if (k==0xff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (k > 0xfe) return huge*copysignf(huge,x); /* overflow */
+ if (k > 0) /* normal result */
+ {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
+ if (k <= -25)
+ if (n > 50000) /* in case integer overflow in n+k */
+ return huge*copysignf(huge,x); /*overflow*/
+ else return tiny*copysignf(tiny,x); /*underflow*/
+ k += 25; /* subnormal result */
+ SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
+ return x*twom25;
+}
diff --git a/lib/msun/src/s_signgam.c b/lib/msun/src/s_signgam.c
new file mode 100644
index 0000000..d67d591
--- /dev/null
+++ b/lib/msun/src/s_signgam.c
@@ -0,0 +1,3 @@
+#include "math.h"
+#include "math_private.h"
+int signgam = 0;
diff --git a/lib/msun/src/s_significand.c b/lib/msun/src/s_significand.c
new file mode 100644
index 0000000..64d4623
--- /dev/null
+++ b/lib/msun/src/s_significand.c
@@ -0,0 +1,34 @@
+/* @(#)s_signif.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * significand(x) computes just
+ * scalb(x, (double) -ilogb(x)),
+ * for exercising the fraction-part(F) IEEE 754-1985 test vector.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __generic_significand(double x)
+#else
+ double __generic_significand(x)
+ double x;
+#endif
+{
+ return __ieee754_scalb(x,(double) -ilogb(x));
+}
diff --git a/lib/msun/src/s_significandf.c b/lib/msun/src/s_significandf.c
new file mode 100644
index 0000000..73cfa71
--- /dev/null
+++ b/lib/msun/src/s_significandf.c
@@ -0,0 +1,31 @@
+/* s_significandf.c -- float version of s_significand.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float significandf(float x)
+#else
+ float significandf(x)
+ float x;
+#endif
+{
+ return __ieee754_scalbf(x,(float) -ilogbf(x));
+}
diff --git a/lib/msun/src/s_sin.c b/lib/msun/src/s_sin.c
new file mode 100644
index 0000000..e6b099e
--- /dev/null
+++ b/lib/msun/src/s_sin.c
@@ -0,0 +1,82 @@
+/* @(#)s_sin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* sin(x)
+ * Return sine function of x.
+ *
+ * kernel function:
+ * __kernel_sin ... sine function on [-pi/4,pi/4]
+ * __kernel_cos ... cose function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2 ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __generic_sin(double x)
+#else
+ double __generic_sin(x)
+ double x;
+#endif
+{
+ double y[2],z=0.0;
+ int32_t n, ix;
+
+ /* High word of x. */
+ GET_HIGH_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
+
+ /* sin(Inf or NaN) is NaN */
+ else if (ix>=0x7ff00000) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2(x,y);
+ switch(n&3) {
+ case 0: return __kernel_sin(y[0],y[1],1);
+ case 1: return __kernel_cos(y[0],y[1]);
+ case 2: return -__kernel_sin(y[0],y[1],1);
+ default:
+ return -__kernel_cos(y[0],y[1]);
+ }
+ }
+}
diff --git a/lib/msun/src/s_sinf.c b/lib/msun/src/s_sinf.c
new file mode 100644
index 0000000..ba3adff
--- /dev/null
+++ b/lib/msun/src/s_sinf.c
@@ -0,0 +1,53 @@
+/* s_sinf.c -- float version of s_sin.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float sinf(float x)
+#else
+ float sinf(x)
+ float x;
+#endif
+{
+ float y[2],z=0.0;
+ int32_t n, ix;
+
+ GET_FLOAT_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3f490fd8) return __kernel_sinf(x,z,0);
+
+ /* sin(Inf or NaN) is NaN */
+ else if (ix>=0x7f800000) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2f(x,y);
+ switch(n&3) {
+ case 0: return __kernel_sinf(y[0],y[1],1);
+ case 1: return __kernel_cosf(y[0],y[1]);
+ case 2: return -__kernel_sinf(y[0],y[1],1);
+ default:
+ return -__kernel_cosf(y[0],y[1]);
+ }
+ }
+}
diff --git a/lib/msun/src/s_tan.c b/lib/msun/src/s_tan.c
new file mode 100644
index 0000000..e02584e
--- /dev/null
+++ b/lib/msun/src/s_tan.c
@@ -0,0 +1,76 @@
+/* @(#)s_tan.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* tan(x)
+ * Return tangent function of x.
+ *
+ * kernel function:
+ * __kernel_tan ... tangent function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2 ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __generic_tan(double x)
+#else
+ double __generic_tan(x)
+ double x;
+#endif
+{
+ double y[2],z=0.0;
+ int32_t n, ix;
+
+ /* High word of x. */
+ GET_HIGH_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1);
+
+ /* tan(Inf or NaN) is NaN */
+ else if (ix>=0x7ff00000) return x-x; /* NaN */
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2(x,y);
+ return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even
+ -1 -- n odd */
+ }
+}
diff --git a/lib/msun/src/s_tanf.c b/lib/msun/src/s_tanf.c
new file mode 100644
index 0000000..65ab1bf
--- /dev/null
+++ b/lib/msun/src/s_tanf.c
@@ -0,0 +1,48 @@
+/* s_tanf.c -- float version of s_tan.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float tanf(float x)
+#else
+ float tanf(x)
+ float x;
+#endif
+{
+ float y[2],z=0.0;
+ int32_t n, ix;
+
+ GET_FLOAT_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3f490fda) return __kernel_tanf(x,z,1);
+
+ /* tan(Inf or NaN) is NaN */
+ else if (ix>=0x7f800000) return x-x; /* NaN */
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2f(x,y);
+ return __kernel_tanf(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even
+ -1 -- n odd */
+ }
+}
diff --git a/lib/msun/src/s_tanh.c b/lib/msun/src/s_tanh.c
new file mode 100644
index 0000000..4f58fcf
--- /dev/null
+++ b/lib/msun/src/s_tanh.c
@@ -0,0 +1,86 @@
+/* @(#)s_tanh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* Tanh(x)
+ * Return the Hyperbolic Tangent of x
+ *
+ * Method :
+ * x -x
+ * e - e
+ * 0. tanh(x) is defined to be -----------
+ * x -x
+ * e + e
+ * 1. reduce x to non-negative by tanh(-x) = -tanh(x).
+ * 2. 0 <= x <= 2**-55 : tanh(x) := x*(one+x)
+ * -t
+ * 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x)
+ * t + 2
+ * 2
+ * 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t=expm1(2x)
+ * t + 2
+ * 22.0 < x <= INF : tanh(x) := 1.
+ *
+ * Special cases:
+ * tanh(NaN) is NaN;
+ * only tanh(0)=0 is exact for finite argument.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one=1.0, two=2.0, tiny = 1.0e-300;
+#else
+static double one=1.0, two=2.0, tiny = 1.0e-300;
+#endif
+
+#ifdef __STDC__
+ double tanh(double x)
+#else
+ double tanh(x)
+ double x;
+#endif
+{
+ double t,z;
+ int32_t jx,ix;
+
+ /* High word of |x|. */
+ GET_HIGH_WORD(jx,x);
+ ix = jx&0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7ff00000) {
+ if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */
+ else return one/x-one; /* tanh(NaN) = NaN */
+ }
+
+ /* |x| < 22 */
+ if (ix < 0x40360000) { /* |x|<22 */
+ if (ix<0x3c800000) /* |x|<2**-55 */
+ return x*(one+x); /* tanh(small) = small */
+ if (ix>=0x3ff00000) { /* |x|>=1 */
+ t = expm1(two*fabs(x));
+ z = one - two/(t+two);
+ } else {
+ t = expm1(-two*fabs(x));
+ z= -t/(t+two);
+ }
+ /* |x| > 22, return +-1 */
+ } else {
+ z = one - tiny; /* raised inexact flag */
+ }
+ return (jx>=0)? z: -z;
+}
diff --git a/lib/msun/src/s_tanhf.c b/lib/msun/src/s_tanhf.c
new file mode 100644
index 0000000..cdfd5f6
--- /dev/null
+++ b/lib/msun/src/s_tanhf.c
@@ -0,0 +1,64 @@
+/* s_tanhf.c -- float version of s_tanh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one=1.0, two=2.0, tiny = 1.0e-30;
+#else
+static float one=1.0, two=2.0, tiny = 1.0e-30;
+#endif
+
+#ifdef __STDC__
+ float tanhf(float x)
+#else
+ float tanhf(x)
+ float x;
+#endif
+{
+ float t,z;
+ int32_t jx,ix;
+
+ GET_FLOAT_WORD(jx,x);
+ ix = jx&0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7f800000) {
+ if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */
+ else return one/x-one; /* tanh(NaN) = NaN */
+ }
+
+ /* |x| < 22 */
+ if (ix < 0x41b00000) { /* |x|<22 */
+ if (ix<0x24000000) /* |x|<2**-55 */
+ return x*(one+x); /* tanh(small) = small */
+ if (ix>=0x3f800000) { /* |x|>=1 */
+ t = expm1f(two*fabsf(x));
+ z = one - two/(t+two);
+ } else {
+ t = expm1f(-two*fabsf(x));
+ z= -t/(t+two);
+ }
+ /* |x| > 22, return +-1 */
+ } else {
+ z = one - tiny; /* raised inexact flag */
+ }
+ return (jx>=0)? z: -z;
+}
diff --git a/lib/msun/src/w_acos.c b/lib/msun/src/w_acos.c
new file mode 100644
index 0000000..3e8c6e5
--- /dev/null
+++ b/lib/msun/src/w_acos.c
@@ -0,0 +1,43 @@
+/* @(#)w_acos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrap_acos(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ double acos(double x) /* wrapper acos */
+#else
+ double acos(x) /* wrapper acos */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_acos(x);
+#else
+ double z;
+ z = __ieee754_acos(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(fabs(x)>1.0) {
+ return __kernel_standard(x,x,1); /* acos(|x|>1) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_acosf.c b/lib/msun/src/w_acosf.c
new file mode 100644
index 0000000..c2292c6
--- /dev/null
+++ b/lib/msun/src/w_acosf.c
@@ -0,0 +1,47 @@
+/* w_acosf.c -- float version of w_acos.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrap_acosf(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ float acosf(float x) /* wrapper acosf */
+#else
+ float acosf(x) /* wrapper acosf */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_acosf(x);
+#else
+ float z;
+ z = __ieee754_acosf(x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
+ if(fabsf(x)>(float)1.0) {
+ /* acosf(|x|>1) */
+ return (float)__kernel_standard((double)x,(double)x,101);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_acosh.c b/lib/msun/src/w_acosh.c
new file mode 100644
index 0000000..197d6d7
--- /dev/null
+++ b/lib/msun/src/w_acosh.c
@@ -0,0 +1,42 @@
+/* @(#)w_acosh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper acosh(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double acosh(double x) /* wrapper acosh */
+#else
+ double acosh(x) /* wrapper acosh */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_acosh(x);
+#else
+ double z;
+ z = __ieee754_acosh(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(x<1.0) {
+ return __kernel_standard(x,x,29); /* acosh(x<1) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_acoshf.c b/lib/msun/src/w_acoshf.c
new file mode 100644
index 0000000..0879889
--- /dev/null
+++ b/lib/msun/src/w_acoshf.c
@@ -0,0 +1,47 @@
+/* w_acoshf.c -- float version of w_acosh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper acoshf(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float acoshf(float x) /* wrapper acoshf */
+#else
+ float acoshf(x) /* wrapper acoshf */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_acoshf(x);
+#else
+ float z;
+ z = __ieee754_acoshf(x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
+ if(x<(float)1.0) {
+ /* acosh(x<1) */
+ return (float)__kernel_standard((double)x,(double)x,129);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_asin.c b/lib/msun/src/w_asin.c
new file mode 100644
index 0000000..d5b2523
--- /dev/null
+++ b/lib/msun/src/w_asin.c
@@ -0,0 +1,44 @@
+/* @(#)w_asin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper asin(x)
+ */
+
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ double asin(double x) /* wrapper asin */
+#else
+ double asin(x) /* wrapper asin */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_asin(x);
+#else
+ double z;
+ z = __ieee754_asin(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(fabs(x)>1.0) {
+ return __kernel_standard(x,x,2); /* asin(|x|>1) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_asinf.c b/lib/msun/src/w_asinf.c
new file mode 100644
index 0000000..6972cb9
--- /dev/null
+++ b/lib/msun/src/w_asinf.c
@@ -0,0 +1,48 @@
+/* w_asinf.c -- float version of w_asin.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper asinf(x)
+ */
+
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ float asinf(float x) /* wrapper asinf */
+#else
+ float asinf(x) /* wrapper asinf */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_asinf(x);
+#else
+ float z;
+ z = __ieee754_asinf(x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
+ if(fabsf(x)>(float)1.0) {
+ /* asinf(|x|>1) */
+ return (float)__kernel_standard((double)x,(double)x,102);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_atan2.c b/lib/msun/src/w_atan2.c
new file mode 100644
index 0000000..8f4c826
--- /dev/null
+++ b/lib/msun/src/w_atan2.c
@@ -0,0 +1,43 @@
+/* @(#)w_atan2.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper atan2(y,x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ double atan2(double y, double x) /* wrapper atan2 */
+#else
+ double atan2(y,x) /* wrapper atan2 */
+ double y,x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_atan2(y,x);
+#else
+ double z;
+ z = __ieee754_atan2(y,x);
+ if(_LIB_VERSION == _IEEE_||isnan(x)||isnan(y)) return z;
+ if(x==0.0&&y==0.0) {
+ return __kernel_standard(y,x,3); /* atan2(+-0,+-0) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_atan2f.c b/lib/msun/src/w_atan2f.c
new file mode 100644
index 0000000..45e5a14
--- /dev/null
+++ b/lib/msun/src/w_atan2f.c
@@ -0,0 +1,47 @@
+/* w_atan2f.c -- float version of w_atan2.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper atan2f(y,x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ float atan2f(float y, float x) /* wrapper atan2f */
+#else
+ float atan2f(y,x) /* wrapper atan2 */
+ float y,x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_atan2f(y,x);
+#else
+ float z;
+ z = __ieee754_atan2f(y,x);
+ if(_LIB_VERSION == _IEEE_||isnanf(x)||isnanf(y)) return z;
+ if(x==(float)0.0&&y==(float)0.0) {
+ /* atan2f(+-0,+-0) */
+ return (float)__kernel_standard((double)y,(double)x,103);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_atanh.c b/lib/msun/src/w_atanh.c
new file mode 100644
index 0000000..d96c9b7
--- /dev/null
+++ b/lib/msun/src/w_atanh.c
@@ -0,0 +1,47 @@
+/* @(#)w_atanh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper atanh(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ double atanh(double x) /* wrapper atanh */
+#else
+ double atanh(x) /* wrapper atanh */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_atanh(x);
+#else
+ double z,y;
+ z = __ieee754_atanh(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ y = fabs(x);
+ if(y>=1.0) {
+ if(y>1.0)
+ return __kernel_standard(x,x,30); /* atanh(|x|>1) */
+ else
+ return __kernel_standard(x,x,31); /* atanh(|x|==1) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_atanhf.c b/lib/msun/src/w_atanhf.c
new file mode 100644
index 0000000..9da087b
--- /dev/null
+++ b/lib/msun/src/w_atanhf.c
@@ -0,0 +1,52 @@
+/* w_atanhf.c -- float version of w_atanh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper atanhf(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ float atanhf(float x) /* wrapper atanhf */
+#else
+ float atanhf(x) /* wrapper atanhf */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_atanhf(x);
+#else
+ float z,y;
+ z = __ieee754_atanhf(x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
+ y = fabsf(x);
+ if(y>=(float)1.0) {
+ if(y>(float)1.0)
+ /* atanhf(|x|>1) */
+ return (float)__kernel_standard((double)x,(double)x,130);
+ else
+ /* atanhf(|x|==1) */
+ return (float)__kernel_standard((double)x,(double)x,131);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_cabs.c b/lib/msun/src/w_cabs.c
new file mode 100644
index 0000000..b140515
--- /dev/null
+++ b/lib/msun/src/w_cabs.c
@@ -0,0 +1,27 @@
+/*
+ * cabs() wrapper for hypot().
+ *
+ * Written by J.T. Conklin, <jtc@wimsey.com>
+ * Placed into the Public Domain, 1994.
+ */
+
+#include <math.h>
+
+struct complex {
+ double x;
+ double y;
+};
+
+double
+cabs(z)
+ struct complex z;
+{
+ return hypot(z.x, z.y);
+}
+
+double
+z_abs(z)
+ struct complex *z;
+{
+ return hypot(z->x, z->y);
+}
diff --git a/lib/msun/src/w_cabsf.c b/lib/msun/src/w_cabsf.c
new file mode 100644
index 0000000..6336d6d
--- /dev/null
+++ b/lib/msun/src/w_cabsf.c
@@ -0,0 +1,21 @@
+/*
+ * cabsf() wrapper for hypotf().
+ *
+ * Written by J.T. Conklin, <jtc@wimsey.com>
+ * Placed into the Public Domain, 1994.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+struct complex {
+ float x;
+ float y;
+};
+
+float
+cabsf(z)
+ struct complex z;
+{
+ return hypotf(z.x, z.y);
+}
diff --git a/lib/msun/src/w_cosh.c b/lib/msun/src/w_cosh.c
new file mode 100644
index 0000000..f20d4c5
--- /dev/null
+++ b/lib/msun/src/w_cosh.c
@@ -0,0 +1,42 @@
+/* @(#)w_cosh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper cosh(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double cosh(double x) /* wrapper cosh */
+#else
+ double cosh(x) /* wrapper cosh */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_cosh(x);
+#else
+ double z;
+ z = __ieee754_cosh(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(fabs(x)>7.10475860073943863426e+02) {
+ return __kernel_standard(x,x,5); /* cosh overflow */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_coshf.c b/lib/msun/src/w_coshf.c
new file mode 100644
index 0000000..61e74f8
--- /dev/null
+++ b/lib/msun/src/w_coshf.c
@@ -0,0 +1,46 @@
+/* w_coshf.c -- float version of w_cosh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper coshf(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float coshf(float x) /* wrapper coshf */
+#else
+ float coshf(x) /* wrapper coshf */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_coshf(x);
+#else
+ float z;
+ z = __ieee754_coshf(x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
+ if(fabsf(x)>(float)8.9415985107e+01) {
+ /* cosh overflow */
+ return (float)__kernel_standard((double)x,(double)x,105);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_drem.c b/lib/msun/src/w_drem.c
new file mode 100644
index 0000000..0f68409
--- /dev/null
+++ b/lib/msun/src/w_drem.c
@@ -0,0 +1,15 @@
+/*
+ * drem() wrapper for remainder().
+ *
+ * Written by J.T. Conklin, <jtc@wimsey.com>
+ * Placed into the Public Domain, 1994.
+ */
+
+#include <math.h>
+
+double
+drem(x, y)
+ double x, y;
+{
+ return remainder(x, y);
+}
diff --git a/lib/msun/src/w_dremf.c b/lib/msun/src/w_dremf.c
new file mode 100644
index 0000000..92079a9
--- /dev/null
+++ b/lib/msun/src/w_dremf.c
@@ -0,0 +1,16 @@
+/*
+ * dremf() wrapper for remainderf().
+ *
+ * Written by J.T. Conklin, <jtc@wimsey.com>
+ * Placed into the Public Domain, 1994.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+float
+dremf(x, y)
+ float x, y;
+{
+ return remainderf(x, y);
+}
diff --git a/lib/msun/src/w_exp.c b/lib/msun/src/w_exp.c
new file mode 100644
index 0000000..7d1e74b
--- /dev/null
+++ b/lib/msun/src/w_exp.c
@@ -0,0 +1,53 @@
+/* @(#)w_exp.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper exp(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
+u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */
+
+#ifdef __STDC__
+ double exp(double x) /* wrapper exp */
+#else
+ double exp(x) /* wrapper exp */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_exp(x);
+#else
+ double z;
+ z = __ieee754_exp(x);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if(finite(x)) {
+ if(x>o_threshold)
+ return __kernel_standard(x,x,6); /* exp overflow */
+ else if(x<u_threshold)
+ return __kernel_standard(x,x,7); /* exp underflow */
+ }
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_expf.c b/lib/msun/src/w_expf.c
new file mode 100644
index 0000000..07bd13b
--- /dev/null
+++ b/lib/msun/src/w_expf.c
@@ -0,0 +1,58 @@
+/* w_expf.c -- float version of w_exp.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper expf(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+o_threshold= 8.8721679688e+01, /* 0x42b17180 */
+u_threshold= -1.0397208405e+02; /* 0xc2cff1b5 */
+
+#ifdef __STDC__
+ float expf(float x) /* wrapper expf */
+#else
+ float expf(x) /* wrapper expf */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_expf(x);
+#else
+ float z;
+ z = __ieee754_expf(x);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if(finitef(x)) {
+ if(x>o_threshold)
+ /* exp overflow */
+ return (float)__kernel_standard((double)x,(double)x,106);
+ else if(x<u_threshold)
+ /* exp underflow */
+ return (float)__kernel_standard((double)x,(double)x,107);
+ }
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_fmod.c b/lib/msun/src/w_fmod.c
new file mode 100644
index 0000000..4ee45a1
--- /dev/null
+++ b/lib/msun/src/w_fmod.c
@@ -0,0 +1,43 @@
+/* @(#)w_fmod.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper fmod(x,y)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ double fmod(double x, double y) /* wrapper fmod */
+#else
+ double fmod(x,y) /* wrapper fmod */
+ double x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_fmod(x,y);
+#else
+ double z;
+ z = __ieee754_fmod(x,y);
+ if(_LIB_VERSION == _IEEE_ ||isnan(y)||isnan(x)) return z;
+ if(y==0.0) {
+ return __kernel_standard(x,y,27); /* fmod(x,0) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_fmodf.c b/lib/msun/src/w_fmodf.c
new file mode 100644
index 0000000..b948ee1
--- /dev/null
+++ b/lib/msun/src/w_fmodf.c
@@ -0,0 +1,47 @@
+/* w_fmodf.c -- float version of w_fmod.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper fmodf(x,y)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ float fmodf(float x, float y) /* wrapper fmodf */
+#else
+ float fmodf(x,y) /* wrapper fmodf */
+ float x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_fmodf(x,y);
+#else
+ float z;
+ z = __ieee754_fmodf(x,y);
+ if(_LIB_VERSION == _IEEE_ ||isnanf(y)||isnanf(x)) return z;
+ if(y==(float)0.0) {
+ /* fmodf(x,0) */
+ return (float)__kernel_standard((double)x,(double)y,127);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_gamma.c b/lib/msun/src/w_gamma.c
new file mode 100644
index 0000000..fb3d127
--- /dev/null
+++ b/lib/msun/src/w_gamma.c
@@ -0,0 +1,49 @@
+/* @(#)w_gamma.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* double gamma(double x)
+ * Return the logarithm of the Gamma function of x.
+ *
+ * Method: call gamma_r
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+extern int signgam;
+
+#ifdef __STDC__
+ double gamma(double x)
+#else
+ double gamma(x)
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_gamma_r(x,&signgam);
+#else
+ double y;
+ y = __ieee754_gamma_r(x,&signgam);
+ if(_LIB_VERSION == _IEEE_) return y;
+ if(!finite(y)&&finite(x)) {
+ if(floor(x)==x&&x<=0.0)
+ return __kernel_standard(x,x,41); /* gamma pole */
+ else
+ return __kernel_standard(x,x,40); /* gamma overflow */
+ } else
+ return y;
+#endif
+}
diff --git a/lib/msun/src/w_gamma_r.c b/lib/msun/src/w_gamma_r.c
new file mode 100644
index 0000000..2f10023
--- /dev/null
+++ b/lib/msun/src/w_gamma_r.c
@@ -0,0 +1,46 @@
+/* @(#)wr_gamma.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper double gamma_r(double x, int *signgamp)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ double gamma_r(double x, int *signgamp) /* wrapper lgamma_r */
+#else
+ double gamma_r(x,signgamp) /* wrapper lgamma_r */
+ double x; int *signgamp;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_gamma_r(x,signgamp);
+#else
+ double y;
+ y = __ieee754_gamma_r(x,signgamp);
+ if(_LIB_VERSION == _IEEE_) return y;
+ if(!finite(y)&&finite(x)) {
+ if(floor(x)==x&&x<=0.0)
+ return __kernel_standard(x,x,41); /* gamma pole */
+ else
+ return __kernel_standard(x,x,40); /* gamma overflow */
+ } else
+ return y;
+#endif
+}
diff --git a/lib/msun/src/w_gammaf.c b/lib/msun/src/w_gammaf.c
new file mode 100644
index 0000000..0e579c7
--- /dev/null
+++ b/lib/msun/src/w_gammaf.c
@@ -0,0 +1,48 @@
+/* w_gammaf.c -- float version of w_gamma.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+extern int signgam;
+
+#ifdef __STDC__
+ float gammaf(float x)
+#else
+ float gammaf(x)
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_gammaf_r(x,&signgam);
+#else
+ float y;
+ y = __ieee754_gammaf_r(x,&signgam);
+ if(_LIB_VERSION == _IEEE_) return y;
+ if(!finitef(y)&&finitef(x)) {
+ if(floorf(x)==x&&x<=(float)0.0)
+ /* gammaf pole */
+ return (float)__kernel_standard((double)x,(double)x,141);
+ else
+ /* gammaf overflow */
+ return (float)__kernel_standard((double)x,(double)x,140);
+ } else
+ return y;
+#endif
+}
diff --git a/lib/msun/src/w_gammaf_r.c b/lib/msun/src/w_gammaf_r.c
new file mode 100644
index 0000000..aa71d69
--- /dev/null
+++ b/lib/msun/src/w_gammaf_r.c
@@ -0,0 +1,51 @@
+/* w_gammaf_r.c -- float version of w_gamma_r.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper float gammaf_r(float x, int *signgamp)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ float gammaf_r(float x, int *signgamp) /* wrapper lgammaf_r */
+#else
+ float gammaf_r(x,signgamp) /* wrapper lgammaf_r */
+ float x; int *signgamp;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_gammaf_r(x,signgamp);
+#else
+ float y;
+ y = __ieee754_gammaf_r(x,signgamp);
+ if(_LIB_VERSION == _IEEE_) return y;
+ if(!finitef(y)&&finitef(x)) {
+ if(floorf(x)==x&&x<=(float)0.0)
+ /* gammaf pole */
+ return (float)__kernel_standard((double)x,(double)x,141);
+ else
+ /* gamma overflow */
+ return (float)__kernel_standard((double)x,(double)x,140);
+ } else
+ return y;
+#endif
+}
diff --git a/lib/msun/src/w_hypot.c b/lib/msun/src/w_hypot.c
new file mode 100644
index 0000000..6486c8d
--- /dev/null
+++ b/lib/msun/src/w_hypot.c
@@ -0,0 +1,43 @@
+/* @(#)w_hypot.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper hypot(x,y)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ double hypot(double x, double y)/* wrapper hypot */
+#else
+ double hypot(x,y) /* wrapper hypot */
+ double x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_hypot(x,y);
+#else
+ double z;
+ z = __ieee754_hypot(x,y);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if((!finite(z))&&finite(x)&&finite(y))
+ return __kernel_standard(x,y,4); /* hypot overflow */
+ else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_hypotf.c b/lib/msun/src/w_hypotf.c
new file mode 100644
index 0000000..77c055d
--- /dev/null
+++ b/lib/msun/src/w_hypotf.c
@@ -0,0 +1,47 @@
+/* w_hypotf.c -- float version of w_hypot.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper hypotf(x,y)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ float hypotf(float x, float y) /* wrapper hypotf */
+#else
+ float hypotf(x,y) /* wrapper hypotf */
+ float x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_hypotf(x,y);
+#else
+ float z;
+ z = __ieee754_hypotf(x,y);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if((!finitef(z))&&finitef(x)&&finitef(y))
+ /* hypot overflow */
+ return (float)__kernel_standard((double)x,(double)y,104);
+ else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_j0.c b/lib/msun/src/w_j0.c
new file mode 100644
index 0000000..e1a4f85
--- /dev/null
+++ b/lib/msun/src/w_j0.c
@@ -0,0 +1,41 @@
+/* @(#)w_j0.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper j0(double x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double j0(double x) /* wrapper j0 */
+#else
+ double j0(x) /* wrapper j0 */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_j0(x);
+#else
+ double z = __ieee754_j0(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(fabs(x)>X_TLOSS) {
+ return __kernel_standard(x,x,34); /* j0(|x|>X_TLOSS) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_j0f.c b/lib/msun/src/w_j0f.c
new file mode 100644
index 0000000..2c6df51
--- /dev/null
+++ b/lib/msun/src/w_j0f.c
@@ -0,0 +1,45 @@
+/* w_j0f.c -- float version of w_j0.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper j0f(float x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float j0f(float x) /* wrapper j0f */
+#else
+ float j0f(x) /* wrapper j0f */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_j0f(x);
+#else
+ float z = __ieee754_j0f(x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
+ if(fabsf(x)>(float)X_TLOSS) {
+ /* j0f(|x|>X_TLOSS) */
+ return (float)__kernel_standard((double)x,(double)x,134);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_j1.c b/lib/msun/src/w_j1.c
new file mode 100644
index 0000000..86f1a3f
--- /dev/null
+++ b/lib/msun/src/w_j1.c
@@ -0,0 +1,42 @@
+/* @(#)w_j1.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper of j1
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double j1(double x) /* wrapper j1 */
+#else
+ double j1(x) /* wrapper j1 */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_j1(x);
+#else
+ double z;
+ z = __ieee754_j1(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z;
+ if(fabs(x)>X_TLOSS) {
+ return __kernel_standard(x,x,36); /* j1(|x|>X_TLOSS) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_j1f.c b/lib/msun/src/w_j1f.c
new file mode 100644
index 0000000..8ef1478
--- /dev/null
+++ b/lib/msun/src/w_j1f.c
@@ -0,0 +1,46 @@
+/* w_j1f.c -- float version of w_j1.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper of j1f
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float j1f(float x) /* wrapper j1f */
+#else
+ float j1f(x) /* wrapper j1f */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_j1f(x);
+#else
+ float z;
+ z = __ieee754_j1f(x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z;
+ if(fabsf(x)>(float)X_TLOSS) {
+ /* j1(|x|>X_TLOSS) */
+ return (float)__kernel_standard((double)x,(double)x,136);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_jn.c b/lib/msun/src/w_jn.c
new file mode 100644
index 0000000..0b087e5
--- /dev/null
+++ b/lib/msun/src/w_jn.c
@@ -0,0 +1,42 @@
+/* @(#)w_jn.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper jn(int n, double x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double jn(int n, double x) /* wrapper jn */
+#else
+ double jn(n,x) /* wrapper jn */
+ double x; int n;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_jn(n,x);
+#else
+ double z;
+ z = __ieee754_jn(n,x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z;
+ if(fabs(x)>X_TLOSS) {
+ return __kernel_standard((double)n,x,38); /* jn(|x|>X_TLOSS,n) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_jnf.c b/lib/msun/src/w_jnf.c
new file mode 100644
index 0000000..9ce1bed
--- /dev/null
+++ b/lib/msun/src/w_jnf.c
@@ -0,0 +1,42 @@
+/* w_jnf.c -- float version of w_jn.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float jnf(int n, float x) /* wrapper jnf */
+#else
+ float jnf(n,x) /* wrapper jnf */
+ float x; int n;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_jnf(n,x);
+#else
+ float z;
+ z = __ieee754_jnf(n,x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z;
+ if(fabsf(x)>(float)X_TLOSS) {
+ /* jn(|x|>X_TLOSS,n) */
+ return (float)__kernel_standard((double)n,(double)x,138);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_lgamma.c b/lib/msun/src/w_lgamma.c
new file mode 100644
index 0000000..3ee3999
--- /dev/null
+++ b/lib/msun/src/w_lgamma.c
@@ -0,0 +1,49 @@
+/* @(#)w_lgamma.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/* double lgamma(double x)
+ * Return the logarithm of the Gamma function of x.
+ *
+ * Method: call __ieee754_lgamma_r
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+extern int signgam;
+
+#ifdef __STDC__
+ double lgamma(double x)
+#else
+ double lgamma(x)
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_lgamma_r(x,&signgam);
+#else
+ double y;
+ y = __ieee754_lgamma_r(x,&signgam);
+ if(_LIB_VERSION == _IEEE_) return y;
+ if(!finite(y)&&finite(x)) {
+ if(floor(x)==x&&x<=0.0)
+ return __kernel_standard(x,x,15); /* lgamma pole */
+ else
+ return __kernel_standard(x,x,14); /* lgamma overflow */
+ } else
+ return y;
+#endif
+}
diff --git a/lib/msun/src/w_lgamma_r.c b/lib/msun/src/w_lgamma_r.c
new file mode 100644
index 0000000..80fd27e
--- /dev/null
+++ b/lib/msun/src/w_lgamma_r.c
@@ -0,0 +1,46 @@
+/* @(#)wr_lgamma.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper double lgamma_r(double x, int *signgamp)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ double lgamma_r(double x, int *signgamp) /* wrapper lgamma_r */
+#else
+ double lgamma_r(x,signgamp) /* wrapper lgamma_r */
+ double x; int *signgamp;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_lgamma_r(x,signgamp);
+#else
+ double y;
+ y = __ieee754_lgamma_r(x,signgamp);
+ if(_LIB_VERSION == _IEEE_) return y;
+ if(!finite(y)&&finite(x)) {
+ if(floor(x)==x&&x<=0.0)
+ return __kernel_standard(x,x,15); /* lgamma pole */
+ else
+ return __kernel_standard(x,x,14); /* lgamma overflow */
+ } else
+ return y;
+#endif
+}
diff --git a/lib/msun/src/w_lgammaf.c b/lib/msun/src/w_lgammaf.c
new file mode 100644
index 0000000..7a237ca
--- /dev/null
+++ b/lib/msun/src/w_lgammaf.c
@@ -0,0 +1,48 @@
+/* w_lgammaf.c -- float version of w_lgamma.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+extern int signgam;
+
+#ifdef __STDC__
+ float lgammaf(float x)
+#else
+ float lgammaf(x)
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_lgammaf_r(x,&signgam);
+#else
+ float y;
+ y = __ieee754_lgammaf_r(x,&signgam);
+ if(_LIB_VERSION == _IEEE_) return y;
+ if(!finitef(y)&&finitef(x)) {
+ if(floorf(x)==x&&x<=(float)0.0)
+ /* lgamma pole */
+ return (float)__kernel_standard((double)x,(double)x,115);
+ else
+ /* lgamma overflow */
+ return (float)__kernel_standard((double)x,(double)x,114);
+ } else
+ return y;
+#endif
+}
diff --git a/lib/msun/src/w_lgammaf_r.c b/lib/msun/src/w_lgammaf_r.c
new file mode 100644
index 0000000..2646669
--- /dev/null
+++ b/lib/msun/src/w_lgammaf_r.c
@@ -0,0 +1,51 @@
+/* w_lgammaf_r.c -- float version of w_lgamma_r.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper float lgammaf_r(float x, int *signgamp)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ float lgammaf_r(float x, int *signgamp) /* wrapper lgammaf_r */
+#else
+ float lgammaf_r(x,signgamp) /* wrapper lgammaf_r */
+ float x; int *signgamp;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_lgammaf_r(x,signgamp);
+#else
+ float y;
+ y = __ieee754_lgammaf_r(x,signgamp);
+ if(_LIB_VERSION == _IEEE_) return y;
+ if(!finitef(y)&&finitef(x)) {
+ if(floorf(x)==x&&x<=(float)0.0)
+ /* lgamma pole */
+ return (float)__kernel_standard((double)x,(double)x,115);
+ else
+ /* lgamma overflow */
+ return (float)__kernel_standard((double)x,(double)x,114);
+ } else
+ return y;
+#endif
+}
diff --git a/lib/msun/src/w_log.c b/lib/msun/src/w_log.c
new file mode 100644
index 0000000..7150aaa
--- /dev/null
+++ b/lib/msun/src/w_log.c
@@ -0,0 +1,43 @@
+/* @(#)w_log.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper log(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ double log(double x) /* wrapper log */
+#else
+ double log(x) /* wrapper log */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_log(x);
+#else
+ double z;
+ z = __ieee754_log(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0) return z;
+ if(x==0.0)
+ return __kernel_standard(x,x,16); /* log(0) */
+ else
+ return __kernel_standard(x,x,17); /* log(x<0) */
+#endif
+}
diff --git a/lib/msun/src/w_log10.c b/lib/msun/src/w_log10.c
new file mode 100644
index 0000000..e6cdca1
--- /dev/null
+++ b/lib/msun/src/w_log10.c
@@ -0,0 +1,46 @@
+/* @(#)w_log10.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper log10(X)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ double log10(double x) /* wrapper log10 */
+#else
+ double log10(x) /* wrapper log10 */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_log10(x);
+#else
+ double z;
+ z = __ieee754_log10(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(x<=0.0) {
+ if(x==0.0)
+ return __kernel_standard(x,x,18); /* log10(0) */
+ else
+ return __kernel_standard(x,x,19); /* log10(x<0) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_log10f.c b/lib/msun/src/w_log10f.c
new file mode 100644
index 0000000..b5f1247
--- /dev/null
+++ b/lib/msun/src/w_log10f.c
@@ -0,0 +1,51 @@
+/* w_log10f.c -- float version of w_log10.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper log10f(X)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ float log10f(float x) /* wrapper log10f */
+#else
+ float log10f(x) /* wrapper log10f */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_log10f(x);
+#else
+ float z;
+ z = __ieee754_log10f(x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
+ if(x<=(float)0.0) {
+ if(x==(float)0.0)
+ /* log10(0) */
+ return (float)__kernel_standard((double)x,(double)x,118);
+ else
+ /* log10(x<0) */
+ return (float)__kernel_standard((double)x,(double)x,119);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_logf.c b/lib/msun/src/w_logf.c
new file mode 100644
index 0000000..dee641b
--- /dev/null
+++ b/lib/msun/src/w_logf.c
@@ -0,0 +1,48 @@
+/* w_logf.c -- float version of w_log.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper logf(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ float logf(float x) /* wrapper logf */
+#else
+ float logf(x) /* wrapper logf */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_logf(x);
+#else
+ float z;
+ z = __ieee754_logf(x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x) || x > (float)0.0) return z;
+ if(x==(float)0.0)
+ /* logf(0) */
+ return (float)__kernel_standard((double)x,(double)x,116);
+ else
+ /* logf(x<0) */
+ return (float)__kernel_standard((double)x,(double)x,117);
+#endif
+}
diff --git a/lib/msun/src/w_pow.c b/lib/msun/src/w_pow.c
new file mode 100644
index 0000000..571897c
--- /dev/null
+++ b/lib/msun/src/w_pow.c
@@ -0,0 +1,61 @@
+
+
+/* @(#)w_pow.c 5.2 93/10/01 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * wrapper pow(x,y) return x**y
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ double pow(double x, double y) /* wrapper pow */
+#else
+ double pow(x,y) /* wrapper pow */
+ double x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_pow(x,y);
+#else
+ double z;
+ z=__ieee754_pow(x,y);
+ if(_LIB_VERSION == _IEEE_|| isnan(y)) return z;
+ if(isnan(x)) {
+ if(y==0.0)
+ return __kernel_standard(x,y,42); /* pow(NaN,0.0) */
+ else
+ return z;
+ }
+ if(x==0.0){
+ if(y==0.0)
+ return __kernel_standard(x,y,20); /* pow(0.0,0.0) */
+ if(finite(y)&&y<0.0)
+ return __kernel_standard(x,y,23); /* pow(0.0,negative) */
+ return z;
+ }
+ if(!finite(z)) {
+ if(finite(x)&&finite(y)) {
+ if(isnan(z))
+ return __kernel_standard(x,y,24); /* pow neg**non-int */
+ else
+ return __kernel_standard(x,y,21); /* pow overflow */
+ }
+ }
+ if(z==0.0&&finite(x)&&finite(y))
+ return __kernel_standard(x,y,22); /* pow underflow */
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_powf.c b/lib/msun/src/w_powf.c
new file mode 100644
index 0000000..24a2cf4
--- /dev/null
+++ b/lib/msun/src/w_powf.c
@@ -0,0 +1,72 @@
+/* w_powf.c -- float version of w_pow.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper powf(x,y) return x**y
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#ifdef __STDC__
+ float powf(float x, float y) /* wrapper powf */
+#else
+ float powf(x,y) /* wrapper powf */
+ float x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_powf(x,y);
+#else
+ float z;
+ z=__ieee754_powf(x,y);
+ if(_LIB_VERSION == _IEEE_|| isnanf(y)) return z;
+ if(isnanf(x)) {
+ if(y==(float)0.0)
+ /* powf(NaN,0.0) */
+ return (float)__kernel_standard((double)x,(double)y,142);
+ else
+ return z;
+ }
+ if(x==(float)0.0){
+ if(y==(float)0.0)
+ /* powf(0.0,0.0) */
+ return (float)__kernel_standard((double)x,(double)y,120);
+ if(finitef(y)&&y<(float)0.0)
+ /* powf(0.0,negative) */
+ return (float)__kernel_standard((double)x,(double)y,123);
+ return z;
+ }
+ if(!finitef(z)) {
+ if(finitef(x)&&finitef(y)) {
+ if(isnanf(z))
+ /* powf neg**non-int */
+ return (float)__kernel_standard((double)x,(double)y,124);
+ else
+ /* powf overflow */
+ return (float)__kernel_standard((double)x,(double)y,121);
+ }
+ }
+ if(z==(float)0.0&&finitef(x)&&finitef(y))
+ /* powf underflow */
+ return (float)__kernel_standard((double)x,(double)y,122);
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_remainder.c b/lib/msun/src/w_remainder.c
new file mode 100644
index 0000000..7d40df4
--- /dev/null
+++ b/lib/msun/src/w_remainder.c
@@ -0,0 +1,42 @@
+/* @(#)w_remainder.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper remainder(x,p)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double remainder(double x, double y) /* wrapper remainder */
+#else
+ double remainder(x,y) /* wrapper remainder */
+ double x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_remainder(x,y);
+#else
+ double z;
+ z = __ieee754_remainder(x,y);
+ if(_LIB_VERSION == _IEEE_ || isnan(y)) return z;
+ if(y==0.0)
+ return __kernel_standard(x,y,28); /* remainder(x,0) */
+ else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_remainderf.c b/lib/msun/src/w_remainderf.c
new file mode 100644
index 0000000..9cc28d4
--- /dev/null
+++ b/lib/msun/src/w_remainderf.c
@@ -0,0 +1,46 @@
+/* w_remainderf.c -- float version of w_remainder.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper remainderf(x,p)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float remainderf(float x, float y) /* wrapper remainder */
+#else
+ float remainderf(x,y) /* wrapper remainder */
+ float x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_remainderf(x,y);
+#else
+ float z;
+ z = __ieee754_remainderf(x,y);
+ if(_LIB_VERSION == _IEEE_ || isnanf(y)) return z;
+ if(y==(float)0.0)
+ /* remainder(x,0) */
+ return (float)__kernel_standard((double)x,(double)y,128);
+ else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_scalb.c b/lib/msun/src/w_scalb.c
new file mode 100644
index 0000000..c12b5e8
--- /dev/null
+++ b/lib/msun/src/w_scalb.c
@@ -0,0 +1,60 @@
+/* @(#)w_scalb.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper scalb(double x, double fn) is provide for
+ * passing various standard test suite. One
+ * should use scalbn() instead.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#include <errno.h>
+
+#ifdef __STDC__
+#ifdef _SCALB_INT
+ double scalb(double x, int fn) /* wrapper scalb */
+#else
+ double scalb(double x, double fn) /* wrapper scalb */
+#endif
+#else
+ double scalb(x,fn) /* wrapper scalb */
+#ifdef _SCALB_INT
+ double x; int fn;
+#else
+ double x,fn;
+#endif
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_scalb(x,fn);
+#else
+ double z;
+ z = __ieee754_scalb(x,fn);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if(!(finite(z)||isnan(z))&&finite(x)) {
+ return __kernel_standard(x,(double)fn,32); /* scalb overflow */
+ }
+ if(z==0.0&&z!=x) {
+ return __kernel_standard(x,(double)fn,33); /* scalb underflow */
+ }
+#ifndef _SCALB_INT
+ if(!finite(fn)) errno = ERANGE;
+#endif
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_scalbf.c b/lib/msun/src/w_scalbf.c
new file mode 100644
index 0000000..3578503
--- /dev/null
+++ b/lib/msun/src/w_scalbf.c
@@ -0,0 +1,65 @@
+/* w_scalbf.c -- float version of w_scalb.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper scalbf(float x, float fn) is provide for
+ * passing various standard test suite. One
+ * should use scalbn() instead.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#include <errno.h>
+
+#ifdef __STDC__
+#ifdef _SCALB_INT
+ float scalbf(float x, int fn) /* wrapper scalbf */
+#else
+ float scalbf(float x, float fn) /* wrapper scalbf */
+#endif
+#else
+ float scalbf(x,fn) /* wrapper scalbf */
+#ifdef _SCALB_INT
+ float x; int fn;
+#else
+ float x,fn;
+#endif
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_scalbf(x,fn);
+#else
+ float z;
+ z = __ieee754_scalbf(x,fn);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if(!(finitef(z)||isnanf(z))&&finitef(x)) {
+ /* scalbf overflow */
+ return (float)__kernel_standard((double)x,(double)fn,132);
+ }
+ if(z==(float)0.0&&z!=x) {
+ /* scalbf underflow */
+ return (float)__kernel_standard((double)x,(double)fn,133);
+ }
+#ifndef _SCALB_INT
+ if(!finitef(fn)) errno = ERANGE;
+#endif
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_sinh.c b/lib/msun/src/w_sinh.c
new file mode 100644
index 0000000..7ed5ec7
--- /dev/null
+++ b/lib/msun/src/w_sinh.c
@@ -0,0 +1,42 @@
+/* @(#)w_sinh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper sinh(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double sinh(double x) /* wrapper sinh */
+#else
+ double sinh(x) /* wrapper sinh */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_sinh(x);
+#else
+ double z;
+ z = __ieee754_sinh(x);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if(!finite(z)&&finite(x)) {
+ return __kernel_standard(x,x,25); /* sinh overflow */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_sinhf.c b/lib/msun/src/w_sinhf.c
new file mode 100644
index 0000000..345440d
--- /dev/null
+++ b/lib/msun/src/w_sinhf.c
@@ -0,0 +1,46 @@
+/* w_sinhf.c -- float version of w_sinh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper sinhf(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float sinhf(float x) /* wrapper sinhf */
+#else
+ float sinhf(x) /* wrapper sinhf */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_sinhf(x);
+#else
+ float z;
+ z = __ieee754_sinhf(x);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if(!finitef(z)&&finitef(x)) {
+ /* sinhf overflow */
+ return (float)__kernel_standard((double)x,(double)x,125);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_sqrt.c b/lib/msun/src/w_sqrt.c
new file mode 100644
index 0000000..f9b08a4
--- /dev/null
+++ b/lib/msun/src/w_sqrt.c
@@ -0,0 +1,42 @@
+/* @(#)w_sqrt.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper sqrt(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double sqrt(double x) /* wrapper sqrt */
+#else
+ double sqrt(x) /* wrapper sqrt */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_sqrt(x);
+#else
+ double z;
+ z = __ieee754_sqrt(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(x<0.0) {
+ return __kernel_standard(x,x,26); /* sqrt(negative) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_sqrtf.c b/lib/msun/src/w_sqrtf.c
new file mode 100644
index 0000000..1b50a18
--- /dev/null
+++ b/lib/msun/src/w_sqrtf.c
@@ -0,0 +1,46 @@
+/* w_sqrtf.c -- float version of w_sqrt.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper sqrtf(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float sqrtf(float x) /* wrapper sqrtf */
+#else
+ float sqrt(x) /* wrapper sqrtf */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_sqrtf(x);
+#else
+ float z;
+ z = __ieee754_sqrtf(x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
+ if(x<(float)0.0) {
+ /* sqrtf(negative) */
+ return (float)__kernel_standard((double)x,(double)x,126);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_y0.c b/lib/msun/src/w_y0.c
new file mode 100644
index 0000000..d2da8ce
--- /dev/null
+++ b/lib/msun/src/w_y0.c
@@ -0,0 +1,50 @@
+/* from: @(#)w_j0.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper y0(double x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double y0(double x) /* wrapper y0 */
+#else
+ double y0(x) /* wrapper y0 */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_y0(x);
+#else
+ double z;
+ z = __ieee754_y0(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z;
+ if(x <= 0.0){
+ if(x==0.0)
+ /* d= -one/(x-x); */
+ return __kernel_standard(x,x,8);
+ else
+ /* d = zero/(x-x); */
+ return __kernel_standard(x,x,9);
+ }
+ if(x>X_TLOSS) {
+ return __kernel_standard(x,x,35); /* y0(x>X_TLOSS) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_y0f.c b/lib/msun/src/w_y0f.c
new file mode 100644
index 0000000..a716441
--- /dev/null
+++ b/lib/msun/src/w_y0f.c
@@ -0,0 +1,54 @@
+/* w_y0f.c -- float version of w_y0.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper y0f(float x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float y0f(float x) /* wrapper y0f */
+#else
+ float y0f(x) /* wrapper y0f */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_y0f(x);
+#else
+ float z;
+ z = __ieee754_y0f(x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z;
+ if(x <= (float)0.0){
+ if(x==(float)0.0)
+ /* d= -one/(x-x); */
+ return (float)__kernel_standard((double)x,(double)x,108);
+ else
+ /* d = zero/(x-x); */
+ return (float)__kernel_standard((double)x,(double)x,109);
+ }
+ if(x>(float)X_TLOSS) {
+ /* y0(x>X_TLOSS) */
+ return (float)__kernel_standard((double)x,(double)x,135);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_y1.c b/lib/msun/src/w_y1.c
new file mode 100644
index 0000000..cde47aa
--- /dev/null
+++ b/lib/msun/src/w_y1.c
@@ -0,0 +1,50 @@
+/* from: @(#)w_j1.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper of y1
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double y1(double x) /* wrapper y1 */
+#else
+ double y1(x) /* wrapper y1 */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_y1(x);
+#else
+ double z;
+ z = __ieee754_y1(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z;
+ if(x <= 0.0){
+ if(x==0.0)
+ /* d= -one/(x-x); */
+ return __kernel_standard(x,x,10);
+ else
+ /* d = zero/(x-x); */
+ return __kernel_standard(x,x,11);
+ }
+ if(x>X_TLOSS) {
+ return __kernel_standard(x,x,37); /* y1(x>X_TLOSS) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_y1f.c b/lib/msun/src/w_y1f.c
new file mode 100644
index 0000000..0b8f332
--- /dev/null
+++ b/lib/msun/src/w_y1f.c
@@ -0,0 +1,54 @@
+/* w_y1f.c -- float version of w_y1.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper of y1f
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float y1f(float x) /* wrapper y1f */
+#else
+ float y1f(x) /* wrapper y1f */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_y1f(x);
+#else
+ float z;
+ z = __ieee754_y1f(x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z;
+ if(x <= (float)0.0){
+ if(x==(float)0.0)
+ /* d= -one/(x-x); */
+ return (float)__kernel_standard((double)x,(double)x,110);
+ else
+ /* d = zero/(x-x); */
+ return (float)__kernel_standard((double)x,(double)x,111);
+ }
+ if(x>(float)X_TLOSS) {
+ /* y1(x>X_TLOSS) */
+ return (float)__kernel_standard((double)x,(double)x,137);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_yn.c b/lib/msun/src/w_yn.c
new file mode 100644
index 0000000..2323d26
--- /dev/null
+++ b/lib/msun/src/w_yn.c
@@ -0,0 +1,50 @@
+/* from: @(#)w_jn.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+/*
+ * wrapper yn(int n, double x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double yn(int n, double x) /* wrapper yn */
+#else
+ double yn(n,x) /* wrapper yn */
+ double x; int n;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_yn(n,x);
+#else
+ double z;
+ z = __ieee754_yn(n,x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z;
+ if(x <= 0.0){
+ if(x==0.0)
+ /* d= -one/(x-x); */
+ return __kernel_standard((double)n,x,12);
+ else
+ /* d = zero/(x-x); */
+ return __kernel_standard((double)n,x,13);
+ }
+ if(x>X_TLOSS) {
+ return __kernel_standard((double)n,x,39); /* yn(x>X_TLOSS,n) */
+ } else
+ return z;
+#endif
+}
diff --git a/lib/msun/src/w_ynf.c b/lib/msun/src/w_ynf.c
new file mode 100644
index 0000000..f7a2498
--- /dev/null
+++ b/lib/msun/src/w_ynf.c
@@ -0,0 +1,50 @@
+/* w_ynf.c -- float version of w_yn.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD$";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float ynf(int n, float x) /* wrapper ynf */
+#else
+ float ynf(n,x) /* wrapper ynf */
+ float x; int n;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_ynf(n,x);
+#else
+ float z;
+ z = __ieee754_ynf(n,x);
+ if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z;
+ if(x <= (float)0.0){
+ if(x==(float)0.0)
+ /* d= -one/(x-x); */
+ return (float)__kernel_standard((double)n,(double)x,112);
+ else
+ /* d = zero/(x-x); */
+ return (float)__kernel_standard((double)n,(double)x,113);
+ }
+ if(x>(float)X_TLOSS) {
+ /* yn(x>X_TLOSS,n) */
+ return (float)__kernel_standard((double)n,(double)x,139);
+ } else
+ return z;
+#endif
+}
diff --git a/lib/ncurses/form/Makefile b/lib/ncurses/form/Makefile
new file mode 100644
index 0000000..83dfbc6
--- /dev/null
+++ b/lib/ncurses/form/Makefile
@@ -0,0 +1,23 @@
+# Makefile for libform
+# $FreeBSD$
+
+NCURSES=${.CURDIR}/../../contrib/ncurses
+
+.PATH: ${NCURSES}/form
+.PATH: ${NCURSES}/menu
+
+LIB= form
+
+SRCS= fty_regex.c fty_num.c fty_int.c fty_ipv4.c fty_enum.c fty_alpha.c \
+ fty_alnum.c \
+ frm_data.c frm_win.c frm_user.c frm_opts.c frm_hook.c frm_req_name.c \
+ fld_user.c fld_type.c fld_stat.c fld_def.c frm_def.c frm_driver.c
+
+CFLAGS+=-I${.CURDIR}/../libncurses -I${NCURSES}/form -I${NCURSES}/menu \
+ -I${NCURSES}/include -Wall -DNDEBUG -DHAVE_CONFIG_H
+
+beforeinstall:
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${NCURSES}/form/form.h ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
diff --git a/lib/ncurses/menu/Makefile b/lib/ncurses/menu/Makefile
new file mode 100644
index 0000000..11fb19d
--- /dev/null
+++ b/lib/ncurses/menu/Makefile
@@ -0,0 +1,24 @@
+# Makefile for libmenu
+# $FreeBSD$
+
+NCURSES=${.CURDIR}/../../contrib/ncurses
+
+.PATH: ${NCURSES}/menu
+
+LIB= menu
+
+SRCS= m_attribs.c m_cursor.c m_driver.c m_format.c m_global.c m_hook.c \
+ m_item_cur.c m_item_nam.c m_item_new.c m_item_opt.c m_item_use.c \
+ m_item_val.c m_item_vis.c m_items.c m_new.c m_opts.c m_post.c \
+ m_req_name.c m_spacing.c m_userptr.c m_win.c
+
+CFLAGS+= -I${.CURDIR}/../libncurses -I${NCURSES}/menu -I${NCURSES}/include \
+ -Wall -DNDEBUG -DHAVE_CONFIG_H
+
+beforeinstall:
+.for i in menu.h eti.h
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 ${NCURSES}/menu/$i \
+ ${DESTDIR}/usr/include
+.endfor
+
+.include <bsd.lib.mk>
diff --git a/lib/ncurses/ncurses/Makefile b/lib/ncurses/ncurses/Makefile
new file mode 100644
index 0000000..31ea17c
--- /dev/null
+++ b/lib/ncurses/ncurses/Makefile
@@ -0,0 +1,520 @@
+# $FreeBSD$
+
+NCURSES=${.CURDIR}/../../contrib/ncurses
+
+LIB= ncurses
+SHLIB_MAJOR=5
+SHLIB_MINOR=0
+
+# Should be elsewhere
+AWK?= awk
+TERMINFODIR?= ${DESTDIR}/usr/share/misc
+
+NCURSES_MAJOR!=egrep 'NCURSES_MAJOR[ ]*=' ${NCURSES}/dist.mk | sed -e 's/^[^0-9]*//'
+NCURSES_MINOR!=egrep 'NCURSES_MINOR[ ]*=' ${NCURSES}/dist.mk | sed -e 's/^[^0-9]*//'
+NCURSES_PATCH!=egrep 'NCURSES_PATCH[ ]*=' ${NCURSES}/dist.mk | sed -e 's/^[^0-9]*//'
+
+# From autoconf (!)
+NCURSES_CONST=
+NCURSES_XNAMES= 0
+OSPEED_INCLUDES=\#include <termios.h>
+OSPEED_TYPE= speed_t
+BUILTIN_BOOL= 1
+BOOL_TYPE= 0
+TYPE_OF_BOOL= char
+TYPEOF_CHTYPE= long
+WIDEC_SHIFT= 8
+SHIFT_LIMIT= 32
+ONEUL= 1UL
+
+.PATH: ${NCURSES}/ncurses
+.PATH: ${NCURSES}/ncurses/base
+.PATH: ${NCURSES}/ncurses/tinfo
+.PATH: ${NCURSES}/ncurses/tty
+.PATH: ${NCURSES}/ncurses/trace
+.PATH: ${NCURSES}/include
+.PATH: ${NCURSES}/man
+
+INCS= -I. -I${.CURDIR} -I${NCURSES}/ncurses -I${NCURSES}/include
+CFLAGS+=${INCS} -Wall -DFREEBSD_NATIVE -DNDEBUG -DHAVE_CONFIG_H -DTERMIOS
+
+GENSRC= \
+ codes.c \
+ expanded.c \
+ fallback.c \
+ lib_gen.c \
+ lib_keyname.c \
+ names.c \
+ unctrl.c
+
+GENHDR= \
+ curses.h \
+ hashsize.h \
+ init_keytry.h \
+ nomacros.h \
+ parametrized.h \
+ term.h \
+ termcap.h \
+ unctrl.h
+
+# Installed
+HEADERS=curses.h term.h termcap.h unctrl.h
+
+# Components of names.c and codes.c
+NAMESRC=boolnames boolfnames numnames numfnames strnames strfnames
+CODESRC=boolcodes numcodes strcodes
+
+SRCS= ${GENHDR} ${GENSRC} \
+ access.c \
+ add_tries.c \
+ alloc_entry.c \
+ alloc_ttype.c \
+ captoinfo.c \
+ comp_captab.c \
+ comp_error.c \
+ comp_expand.c \
+ comp_hash.c \
+ comp_parse.c \
+ comp_scan.c \
+ define_key.c \
+ doalloc.c \
+ free_ttype.c \
+ getenv_num.c \
+ hardscroll.c \
+ hashmap.c \
+ home_terminfo.c \
+ init_keytry.c \
+ keybound.c \
+ keyok.c \
+ lib_acs.c \
+ lib_addch.c \
+ lib_addstr.c \
+ lib_baudrate.c \
+ lib_beep.c \
+ lib_bkgd.c \
+ lib_box.c \
+ lib_chgat.c \
+ lib_clear.c \
+ lib_clearok.c \
+ lib_clrbot.c \
+ lib_clreol.c \
+ lib_color.c \
+ lib_colorset.c \
+ lib_cur_term.c \
+ lib_data.c \
+ lib_delch.c \
+ lib_delwin.c \
+ lib_dft_fgbg.c \
+ lib_echo.c \
+ lib_endwin.c \
+ lib_erase.c \
+ lib_flash.c \
+ lib_freeall.c \
+ lib_getch.c \
+ lib_getstr.c \
+ lib_has_cap.c \
+ lib_hline.c \
+ lib_immedok.c \
+ lib_inchstr.c \
+ lib_initscr.c \
+ lib_insch.c \
+ lib_insdel.c \
+ lib_insstr.c \
+ lib_instr.c \
+ lib_isendwin.c \
+ lib_kernel.c \
+ lib_leaveok.c \
+ lib_longname.c \
+ lib_mouse.c \
+ lib_move.c \
+ lib_mvcur.c \
+ lib_mvwin.c \
+ lib_napms.c \
+ lib_newterm.c \
+ lib_newwin.c \
+ lib_nl.c \
+ lib_options.c \
+ lib_overlay.c \
+ lib_pad.c \
+ lib_print.c \
+ lib_printw.c \
+ lib_raw.c \
+ lib_redrawln.c \
+ lib_refresh.c \
+ lib_restart.c \
+ lib_scanw.c \
+ lib_screen.c \
+ lib_scroll.c \
+ lib_scrollok.c \
+ lib_scrreg.c \
+ lib_set_term.c \
+ lib_setup.c \
+ lib_slk.c \
+ lib_slkatr_set.c \
+ lib_slkatrof.c \
+ lib_slkatron.c \
+ lib_slkatrset.c \
+ lib_slkattr.c \
+ lib_slkclear.c \
+ lib_slkcolor.c \
+ lib_slkinit.c \
+ lib_slklab.c \
+ lib_slkrefr.c \
+ lib_slkset.c \
+ lib_slktouch.c \
+ lib_termcap.c \
+ lib_termname.c \
+ lib_ti.c \
+ lib_touch.c \
+ lib_tparm.c \
+ lib_tputs.c \
+ lib_trace.c \
+ lib_traceatr.c \
+ lib_tracebits.c \
+ lib_tracechr.c \
+ lib_tracedmp.c \
+ lib_tracemse.c \
+ lib_tstp.c \
+ lib_ttyflags.c \
+ lib_twait.c \
+ lib_ungetch.c \
+ lib_vidattr.c \
+ lib_vline.c \
+ lib_wattroff.c \
+ lib_wattron.c \
+ lib_winch.c \
+ lib_window.c \
+ memmove.c \
+ name_match.c \
+ nc_panel.c \
+ parse_entry.c \
+ read_entry.c \
+ resizeterm.c \
+ safe_sprintf.c \
+ setbuf.c \
+ sigaction.c \
+ trace_buf.c \
+ trace_tries.c \
+ trace_xnames.c \
+ tries.c \
+ tty_update.c \
+ vsscanf.c \
+ wresize.c \
+ write_entry.c \
+
+# From our old libtermcap.
+# Used instead of the hideous read_termcap.c abomination.
+SRCS+= termcap.c
+
+CLEANFILES+= ${GENSRC} ${GENHDR} keys.tries make_hash term.h.new \
+ make_keys MKterm.h.awk comp_captab.c \
+ namehdr nameftr codeftr ${NAMESRC} ${CODESRC}
+
+SYMLINKS+=libncurses.a ${LIBDIR}/libcurses.a
+SYMLINKS+=libncurses.a ${LIBDIR}/libtermcap.a
+SYMLINKS+=libncurses.a ${LIBDIR}/libtermlib.a
+SYMLINKS+=libncurses.a ${LIBDIR}/libmytinfo.a
+SYMLINKS+=libncurses.a ${LIBDIR}/libtinfo.a
+.if !defined(NOPIC)
+.if ${OBJFORMAT} == aout
+SYMLINKS+=libncurses.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ libcurses.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
+SYMLINKS+=libncurses.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ libtermcap.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
+SYMLINKS+=libncurses.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ libtermlib.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
+SYMLINKS+=libncurses.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ libmytinfo.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
+SYMLINKS+=libncurses.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+ libtinfo.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
+.else
+# no need for major at all, it's an ld-time redirection only
+SYMLINKS+=libncurses.so ${SHLIBDIR}/libcurses.so
+SYMLINKS+=libncurses.so ${SHLIBDIR}/libtermcap.so
+SYMLINKS+=libncurses.so ${SHLIBDIR}/libtermlib.so
+SYMLINKS+=libncurses.so ${SHLIBDIR}/libmytinfo.so
+SYMLINKS+=libncurses.so ${SHLIBDIR}/libtinfo.so
+.endif
+.endif
+.if !defined(NOPROFILE)
+SYMLINKS+=libncurses_p.a ${LIBDIR}/libcurses_p.a
+SYMLINKS+=libncurses_p.a ${LIBDIR}/libtermcap_p.a
+SYMLINKS+=libncurses_p.a ${LIBDIR}/libtermlib_p.a
+SYMLINKS+=libncurses_p.a ${LIBDIR}/libmytinfo_p.a
+SYMLINKS+=libncurses_p.a ${LIBDIR}/libtinfo_p.a
+.endif
+
+beforeinstall: ${HEADERS}
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 ${HEADERS} \
+ ${DESTDIR}/usr/include
+ rm -f ${DESTDIR}/usr/include/ncurses.h
+ ln -s curses.h ${DESTDIR}/usr/include/ncurses.h
+
+# Generated source
+namehdr nameftr codeftr ${NAMESRC} ${CODESRC}: MKnames.awk Caps
+ ${AWK} -f ${NCURSES}/ncurses/tinfo/MKnames.awk ${NCURSES}/include/Caps
+
+.ORDER: namehdr ${NAMESRC} ${CODESRC} nameftr codeftr names.c codes.c
+
+names.c: namehdr ${NAMESRC} nameftr
+ cat namehdr ${NAMESRC} nameftr > $@
+
+codes.c: namehdr ${CODESRC} codeftr
+ cat namehdr ${CODESRC} codeftr > $@
+
+lib_gen.c: MKlib_gen.sh curses.h
+ sh ${NCURSES}/ncurses/base/MKlib_gen.sh "${CC} -E ${INCS}" \
+ "${AWK}" < curses.h >$@
+
+lib_keyname.c: keys.list MKkeyname.awk
+ ${AWK} -f ${NCURSES}/ncurses/base/MKkeyname.awk \
+ ${NCURSES}/ncurses/tinfo/keys.list > lib_keyname.c
+
+unctrl.c: MKunctrl.awk
+ echo | ${AWK} -f ${NCURSES}/ncurses/base/MKunctrl.awk > unctrl.c
+
+comp_captab.c: MKcaptab.awk Caps make_hash
+ sh ${NCURSES}/ncurses/tinfo/MKcaptab.awk "${AWK}" \
+ ${NCURSES}/include/Caps > comp_captab.c
+
+expanded.c: MKexpanded.sh
+ sh ${NCURSES}/ncurses/tty/MKexpanded.sh "${CC} -E" ${CFLAGS} >expanded.c
+
+fallback.c: MKfallback.sh
+ sh ${NCURSES}/ncurses/tinfo/MKfallback.sh > fallback.c
+
+# Generated headers
+nomacros.h: MKlib_gen.sh curses.h
+ sh ${NCURSES}/ncurses/base/MKlib_gen.sh "${CC} -E ${INCS}" \
+ "${AWK}" < curses.h | fgrep undef > $@
+
+init_keytry.h: keys.list make_keys
+ ./make_keys ${NCURSES}/ncurses/tinfo/keys.list > init_keytry.h
+
+hashsize.h: MKhashsize.sh Caps
+ sh ${NCURSES}/include/MKhashsize.sh ${NCURSES}/include/Caps > $@
+
+parametrized.h: MKparametrized.sh Caps
+ AWK=${AWK} sh ${NCURSES}/include/MKparametrized.sh \
+ ${NCURSES}/include/Caps > $@
+
+term.h: MKterm.h.awk edit_cfg.sh Caps
+ ${AWK} -f MKterm.h.awk ${NCURSES}/include/Caps > $@.new
+ sh ${NCURSES}/include/edit_cfg.sh ${.CURDIR}/ncurses_cfg.h $@.new
+ mv -f $@.new $@
+
+# Build tools
+build-tools: make_hash make_keys
+
+make_keys: make_keys.c names.c
+ ${CC} -o $@ ${CFLAGS} ${NCURSES}/ncurses/tinfo/make_keys.c
+
+make_hash: comp_hash.c hashsize.h
+ ${CC} -o $@ ${CFLAGS} -DMAIN_PROGRAM \
+ ${NCURSES}/ncurses/tinfo/comp_hash.c
+
+# ./configure generated
+MKterm.h.awk: MKterm.h.awk.in
+ sed <${NCURSES}/include/$@.in >$@ \
+ -e "/@NCURSES_MAJOR@/s//${NCURSES_MAJOR}/" \
+ -e "/@NCURSES_MINOR@/s//${NCURSES_MINOR}/" \
+ -e "/@NCURSES_CONST@/s//${NCURSES_CONST}/" \
+ -e "/@NCURSES_XNAMES@/s//${NCURSES_XNAMES}/"
+
+termcap.h: termcap.h.in
+ sed <${NCURSES}/include/$@.in >$@ \
+ -e "/@NCURSES_MAJOR@/s//${NCURSES_MAJOR}/" \
+ -e "/@NCURSES_MINOR@/s//${NCURSES_MINOR}/" \
+ -e "/@NCURSES_CONST@/s//${NCURSES_CONST}/" \
+ -e "/@OSPEED_INCLUDES@/s//${OSPEED_INCLUDES}/" \
+ -e "/@OSPEED_TYPE@/s//${OSPEED_TYPE}/"
+
+curses.h: curses.h.in
+ sed <${NCURSES}/include/$@.in >$@ \
+ -e "/@NCURSES_MAJOR@/s//${NCURSES_MAJOR}/" \
+ -e "/@NCURSES_MINOR@/s//${NCURSES_MINOR}/" \
+ -e "/@NCURSES_PATCH@/s//${NCURSES_PATCH}/" \
+ -e "/@NCURSES_CONST@/s//${NCURSES_CONST}/" \
+ -e "s/@cf_cv_builtin_bool@/${BUILTIN_BOOL}/g" \
+ -e "s/@cf_cv_cc_bool_type@/${BOOL_TYPE}/g" \
+ -e "s/@cf_cv_type_of_bool@/${TYPE_OF_BOOL}/g" \
+ -e "s/@cf_cv_typeof_chtype@/${TYPEOF_CHTYPE}/g" \
+ -e "s/@cf_cv_widec_shift@/${WIDEC_SHIFT}/g" \
+ -e "s/@cf_cv_shift_limit@/${SHIFT_LIMIT}/g" \
+ -e "s/@cf_cv_1UL@/${ONEUL}/g"
+
+unctrl.h: unctrl.h.in
+ sed <${NCURSES}/include/$@.in >$@ \
+ -e "/@NCURSES_MAJOR@/s//${NCURSES_MAJOR}/" \
+ -e "/@NCURSES_MINOR@/s//${NCURSES_MINOR}/"
+
+# MAN page gunk
+terminfo.5: MKterminfo.sh terminfo.head Caps
+ sh ${NCURSES}/man/MKterminfo.sh ${NCURSES}/man/terminfo.head \
+ ${NCURSES}/include/Caps ${NCURSES}/man/terminfo.tail >$@
+
+CLEANFILES+= terminfo.5
+MANFILTER= sed -e 's\#@DATADIR@\#${TERMINFODIR}/terminfo\#g'
+
+MAN3x= curs_addch.3x curs_addchstr.3x curs_addstr.3x curs_attr.3x \
+ curs_beep.3x curs_bkgd.3x curs_border.3x curs_clear.3x curs_color.3x \
+ curs_delch.3x curs_deleteln.3x curs_getch.3x curs_getstr.3x \
+ curs_getyx.3x curs_inch.3x curs_inchstr.3x curs_initscr.3x \
+ curs_inopts.3x curs_insch.3x curs_insstr.3x curs_instr.3x \
+ curs_kernel.3x curs_mouse.3x curs_move.3x curs_outopts.3x \
+ curs_overlay.3x curs_pad.3x curs_print.3x curs_printw.3x \
+ curs_refresh.3x curs_scanw.3x curs_scr_dump.3x curs_scroll.3x \
+ curs_slk.3x curs_termattrs.3x curs_termcap.3x curs_terminfo.3x \
+ curs_touch.3x curs_util.3x curs_window.3x define_key.3x \
+ dft_fgbg.3x keybound.3x keyok.3x ncurses.3x resizeterm.3x wresize.3x
+MAN5= term.5 terminfo.5
+MAN7= term.7
+
+# Generate the MAN3 list from MAN3x
+.for page in ${MAN3x}
+CLEANFILES+=${page:T:S/3x$/3/g}
+MAN3+=${page:T:S/3x$/3/g}
+all-man: ${page:T:S/3x$/3/g}
+${page:T:S/3x$/3/g}: ${page}
+ ln -s ${.ALLSRC} ${.TARGET}
+.endfor
+
+MLINKS+=curs_addch.3 addch.3 curs_addch.3 echochar.3 curs_addch.3 mvaddch.3 \
+ curs_addch.3 mvwaddch.3 curs_addch.3 waddch.3 curs_addch.3 wechochar.3
+MLINKS+=curs_addchstr.3 addchnstr.3 curs_addchstr.3 addchstr.3 \
+ curs_addchstr.3 mvaddchnstr.3 curs_addchstr.3 mvaddchstr.3 \
+ curs_addchstr.3 mvwaddchnstr.3 curs_addchstr.3 mvwaddchstr.3 \
+ curs_addchstr.3 waddchnstr.3 curs_addchstr.3 waddchstr.3
+MLINKS+=curs_addstr.3 addnstr.3 curs_addstr.3 addstr.3 \
+ curs_addstr.3 mvaddnstr.3 curs_addstr.3 mvaddstr.3 \
+ curs_addstr.3 mvwaddnstr.3 curs_addstr.3 mvwaddstr.3 \
+ curs_addstr.3 waddnstr.3 curs_addstr.3 waddstr.3
+MLINKS+=curs_attr.3 attr_get.3 curs_attr.3 attr_off.3 curs_attr.3 attr_on.3 \
+ curs_attr.3 attr_set.3 curs_attr.3 attroff.3 curs_attr.3 attron.3 \
+ curs_attr.3 attrset.3 curs_attr.3 chgat.3 curs_attr.3 color_set.3 \
+ curs_attr.3 mvchgat.3 curs_attr.3 mvwchgat.3 curs_attr.3 standend.3 \
+ curs_attr.3 standout.3 curs_attr.3 wattr_get.3 curs_attr.3 wattr_off.3 \
+ curs_attr.3 wattr_on.3 curs_attr.3 wattr_set.3 curs_attr.3 wattroff.3 \
+ curs_attr.3 wattron.3 curs_attr.3 wattrset.3 curs_attr.3 wchgat.3 \
+ curs_attr.3 wcolor_set.3 curs_attr.3 wstandend.3 \
+ curs_attr.3 wstandout.3
+MLINKS+=curs_beep.3 beep.3 curs_beep.3 flash.3
+MLINKS+=curs_bkgd.3 bkgd.3 curs_bkgd.3 bkgdset.3 curs_bkgd.3 getbkgd.3 \
+ curs_bkgd.3 wbkgd.3 curs_bkgd.3 wbkgdset.3
+MLINKS+=curs_border.3 border.3 curs_border.3 box.3 curs_border.3 hline.3 \
+ curs_border.3 mvhline.3 curs_border.3 mvwhline.3 \
+ curs_border.3 mvwvline.3 curs_border.3 vline.3 curs_border.3 wborder.3 \
+ curs_border.3 whline.3 curs_border.3 wvline.3
+MLINKS+=curs_clear.3 clear.3 curs_clear.3 clrtobot.3 curs_clear.3 clrtoeol.3 \
+ curs_clear.3 erase.3 curs_clear.3 wclear.3 curs_clear.3 wclrtobot.3 \
+ curs_clear.3 wclrtoeol.3 curs_clear.3 werase.3
+MLINKS+=curs_color.3 can_change_color.3 curs_color.3 color_content.3 \
+ curs_color.3 has_colors.3 curs_color.3 init_color.3 \
+ curs_color.3 init_pair.3 curs_color.3 pair_content.3 \
+ curs_color.3 start_color.3
+MLINKS+=curs_delch.3 delch.3 curs_delch.3 mvdelch.3 curs_delch.3 mvwdelch.3 \
+ curs_delch.3 wdelch.3
+MLINKS+=curs_deleteln.3 deleteln.3 curs_deleteln.3 insdelln.3 \
+ curs_deleteln.3 insertln.3 curs_deleteln.3 wdeleteln.3 \
+ curs_deleteln.3 winsdelln.3 curs_deleteln.3 winsertln.3
+MLINKS+=curs_getch.3 getch.3 curs_getch.3 has_key.3 curs_getch.3 mvgetch.3 \
+ curs_getch.3 mvwgetch.3 curs_getch.3 ungetch.3 curs_getch.3 wgetch.3
+MLINKS+=curs_getstr.3 getnstr.3 curs_getstr.3 getstr.3 \
+ curs_getstr.3 mvgetnstr.3 curs_getstr.3 mvgetstr.3 \
+ curs_getstr.3 mvwgetnstr.3 curs_getstr.3 mvwgetstr.3 \
+ curs_getstr.3 wgetnstr.3 curs_getstr.3 wgetstr.3
+MLINKS+=curs_getyx.3 getbegyx.3 curs_getyx.3 getmaxyx.3 \
+ curs_getyx.3 getparyx.3 curs_getyx.3 getyx.3
+MLINKS+=curs_inch.3 inch.3 curs_inch.3 mvinch.3 curs_inch.3 mvwinch.3 \
+ curs_inch.3 winch.3
+MLINKS+=curs_inchstr.3 inchnstr.3 curs_inchstr.3 inchstr.3 \
+ curs_inchstr.3 mvinchnstr.3 curs_inchstr.3 mvinchstr.3 \
+ curs_inchstr.3 mvwinchnstr.3 curs_inchstr.3 mvwinchstr.3 \
+ curs_inchstr.3 winchnstr.3 curs_inchstr.3 winchstr.3
+MLINKS+=curs_initscr.3 delscreen.3 curs_initscr.3 endwin.3 \
+ curs_initscr.3 initscr.3 curs_initscr.3 isendwin.3 \
+ curs_initscr.3 newterm.3 curs_initscr.3 set_term.3
+MLINKS+=curs_inopts.3 cbreak.3 curs_inopts.3 echo.3 curs_inopts.3 halfdelay.3 \
+ curs_inopts.3 intrflush.3 curs_inopts.3 keypad.3 curs_inopts.3 meta.3 \
+ curs_inopts.3 nocbreak.3 curs_inopts.3 nodelay.3 \
+ curs_inopts.3 noecho.3 curs_inopts.3 noqiflush.3 curs_inopts.3 noraw.3 \
+ curs_inopts.3 notimeout.3 curs_inopts.3 qiflush.3 curs_inopts.3 raw.3 \
+ curs_inopts.3 timeout.3 curs_inopts.3 typeahead.3 \
+ curs_inopts.3 wtimeout.3
+MLINKS+=curs_insch.3 insch.3 curs_insch.3 mvinsch.3 curs_insch.3 mvwinsch.3 \
+ curs_insch.3 winsch.3
+MLINKS+=curs_insstr.3 insnstr.3 curs_insstr.3 insstr.3 \
+ curs_insstr.3 mvinsnstr.3 curs_insstr.3 mvinsstr.3 \
+ curs_insstr.3 mvwinsnstr.3 curs_insstr.3 mvwinsstr.3 \
+ curs_insstr.3 winsnstr.3 curs_insstr.3 winsstr.3
+MLINKS+=curs_instr.3 innstr.3 curs_instr.3 instr.3 curs_instr.3 mvinnstr.3 \
+ curs_instr.3 mvinstr.3 curs_instr.3 mvwinnstr.3 \
+ curs_instr.3 mvwinstr.3 curs_instr.3 winnstr.3 curs_instr.3 winstr.3
+MLINKS+=curs_kernel.3 curs_set.3 curs_kernel.3 def_prog_mode.3 \
+ curs_kernel.3 def_shell_mode.3 curs_kernel.3 getsyx.3 \
+ curs_kernel.3 napms.3 curs_kernel.3 reset_prog_mode.3 \
+ curs_kernel.3 reset_shell_mode.3 curs_kernel.3 resetty.3 \
+ curs_kernel.3 ripoffline.3 curs_kernel.3 savetty.3 \
+ curs_kernel.3 setsyx.3
+MLINKS+=curs_mouse.3 getmouse.3 curs_mouse.3 mouseinterval.3 \
+ curs_mouse.3 mousemask.3 curs_mouse.3 ungetmouse.3 \
+ curs_mouse.3 wenclose.3 curs_mouse.3 wmouse_trafo.3
+MLINKS+=curs_move.3 move.3 curs_move.3 wmove.3
+MLINKS+=curs_outopts.3 clearok.3 curs_outopts.3 idcok.3 curs_outopts.3 idlok.3 \
+ curs_outopts.3 immedok.3 curs_outopts.3 leaveok.3 curs_outopts.3 nl.3 \
+ curs_outopts.3 nonl.3 curs_outopts.3 scrollok.3 \
+ curs_outopts.3 setscrreg.3 curs_outopts.3 wsetscrreg.3
+MLINKS+=curs_overlay.3 copywin.3 curs_overlay.3 overlay.3 \
+ curs_overlay.3 overwrite.3
+MLINKS+=curs_pad.3 newpad.3 curs_pad.3 pechochar.3 curs_pad.3 pnoutrefresh.3 \
+ curs_pad.3 prefresh.3 curs_pad.3 subpad.3
+MLINKS+=curs_print.3 mcprint.3
+MLINKS+=curs_printw.3 mvprintw.3 curs_printw.3 mvwprintw.3 \
+ curs_printw.3 printw.3 curs_printw.3 vw_printw.3 \
+ curs_printw.3 vwprintw.3 curs_printw.3 wprintw.3
+MLINKS+=curs_refresh.3 doupdate.3 curs_refresh.3 redrawwin.3 \
+ curs_refresh.3 refresh.3 curs_refresh.3 wnoutrefresh.3 \
+ curs_refresh.3 wredrawln.3 curs_refresh.3 wrefresh.3
+MLINKS+=curs_scanw.3 mvscanw.3 curs_scanw.3 mvwscanw.3 curs_scanw.3 scanw.3 \
+ curs_scanw.3 vw_scanw.3 curs_scanw.3 vwscanw.3 curs_scanw.3 wscanw.3
+MLINKS+=curs_scr_dump.3 scr_dump.3 curs_scr_dump.3 scr_init.3 \
+ curs_scr_dump.3 scr_restore.3 curs_scr_dump.3 scr_set.3
+MLINKS+=curs_scroll.3 scrl.3 curs_scroll.3 scroll.3 curs_scroll.3 wscrl.3
+MLINKS+=curs_slk.3 slk_attr.3 curs_slk.3 slk_attr_off.3 \
+ curs_slk.3 slk_attr_on.3 curs_slk.3 slk_attr_set.3 \
+ curs_slk.3 slk_attroff.3 curs_slk.3 slk_attron.3 \
+ curs_slk.3 slk_attrset.3 curs_slk.3 slk_clear.3 \
+ curs_slk.3 slk_color.3 curs_slk.3 slk_init.3 curs_slk.3 slk_label.3 \
+ curs_slk.3 slk_noutrefresh.3 curs_slk.3 slk_refresh.3 \
+ curs_slk.3 slk_restore.3 curs_slk.3 slk_set.3 curs_slk.3 slk_touch.3
+MLINKS+=curs_termattrs.3 baudrate.3 curs_termattrs.3 erasechar.3 \
+ curs_termattrs.3 has_ic.3 curs_termattrs.3 has_il.3 \
+ curs_termattrs.3 killchar.3 curs_termattrs.3 longname.3 \
+ curs_termattrs.3 termattrs.3 curs_termattrs.3 termname.3
+MLINKS+=curs_termcap.3 tgetent.3 curs_termcap.3 tgetflag.3 \
+ curs_termcap.3 tgetnum.3 curs_termcap.3 tgetstr.3 \
+ curs_termcap.3 tgoto.3 curs_termcap.3 tputs.3
+MLINKS+=curs_terminfo.3 del_curterm.3 curs_terminfo.3 mvcur.3 \
+ curs_terminfo.3 putp.3 curs_terminfo.3 restartterm.3 \
+ curs_terminfo.3 set_curterm.3 curs_terminfo.3 setterm.3 \
+ curs_terminfo.3 setupterm.3 curs_terminfo.3 tigetflag.3 \
+ curs_terminfo.3 tigetnum.3 curs_terminfo.3 tigetstr.3 \
+ curs_terminfo.3 tparm.3 curs_terminfo.3 tputs.3 \
+ curs_terminfo.3 vidattr.3 curs_terminfo.3 vidputs.3
+MLINKS+=curs_touch.3 is_linetouched.3 curs_touch.3 is_wintouched.3 \
+ curs_touch.3 touchline.3 curs_touch.3 touchwin.3 \
+ curs_touch.3 untouchwin.3 curs_touch.3 wtouchln.3
+MLINKS+=curs_util.3 delay_output.3 curs_util.3 filter.3 \
+ curs_util.3 flushinp.3 curs_util.3 getwin.3 \
+ curs_util.3 keyname.3 curs_util.3 putwin.3 \
+ curs_util.3 unctrl.3 curs_util.3 use_env.3
+MLINKS+=curs_window.3 delwin.3 curs_window.3 derwin.3 curs_window.3 dupwin.3 \
+ curs_window.3 mvderwin.3 curs_window.3 mvwin.3 curs_window.3 newwin.3 \
+ curs_window.3 subwin.3 curs_window.3 syncok.3 \
+ curs_window.3 wcursyncup.3 curs_window.3 wsyncdown.3 \
+ curs_window.3 wsyncup.3
+MLINKS+=dft_fgbg.3 use_default_colors.3
+
+.include <bsd.lib.mk>
+
+.SUFFIXES: .3x .3
diff --git a/lib/ncurses/ncurses/ncurses_cfg.h b/lib/ncurses/ncurses/ncurses_cfg.h
new file mode 100644
index 0000000..a14d5ba
--- /dev/null
+++ b/lib/ncurses/ncurses/ncurses_cfg.h
@@ -0,0 +1,129 @@
+/* include/ncurses_cfg.h. Generated automatically by configure. */
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+ * copy of this software and associated documentation files (the *
+ * "Software"), to deal in the Software without restriction, including *
+ * without limitation the rights to use, copy, modify, merge, publish, *
+ * distribute, distribute with modifications, sublicense, and/or sell *
+ * copies of the Software, and to permit persons to whom the Software is *
+ * furnished to do so, subject to the following conditions: *
+ * *
+ * The above copyright notice and this permission notice shall be included *
+ * in all copies or substantial portions of the Software. *
+ * *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Thomas E. Dickey <dickey@clark.net> 1997 *
+ ****************************************************************************/
+/*
+ * Id: ncurses_cfg.hin,v 1.2 1998/02/11 12:13:46 tom Exp
+ *
+ * This is a template-file used to generate the "ncurses_cfg.h" file.
+ *
+ * Rather than list every definition, the configuration script substitutes
+ * the definitions that it finds using 'sed'. You need a patch (971222)
+ * to autoconf 2.12 to do this.
+ */
+#ifndef NC_CONFIG_H
+#define NC_CONFIG_H
+
+#define BSD_TPUTS 1
+#define CC_HAS_INLINE_FUNCS 1
+#define CC_HAS_PROTOS 1
+#define ETIP_NEEDS_ 1
+#define GCC_NORETURN __dead2
+#define GCC_PRINTF 1
+#define GCC_SCANF 1
+#define GCC_UNUSED __unused
+#define HAVE_BIG_CORE 1
+#define HAVE_BSD_CGETENT 1
+#define HAVE_DIRENT_H 1
+#define HAVE_ERRNO 1
+#define HAVE_FCNTL_H 1
+#define HAVE_FORM_H 1
+#define HAVE_GETCWD 1
+#define HAVE_GETTIMEOFDAY 1
+#define HAVE_GETTTYNAM 1
+#define HAVE_ISASCII 1
+#define HAVE_LIBFORM 1
+#define HAVE_LIBMENU 1
+#define HAVE_LIBPANEL 1
+#define HAVE_LIMITS_H 1
+#define HAVE_LINK 1
+#define HAVE_LOCALE_H 1
+#define HAVE_LONG_FILE_NAMES 1
+#define HAVE_MEMCCPY 1
+#define HAVE_MENU_H 1
+#define HAVE_NANOSLEEP 1
+#define HAVE_NC_ALLOC_H 1
+#define HAVE_PANEL_H 1
+#define HAVE_POLL 1
+#define HAVE_POLL_H 1
+#define HAVE_REGEX_H_FUNCS 1
+#define HAVE_REMOVE 1
+#define HAVE_SELECT 1
+#define HAVE_SETBUF 1
+#define HAVE_SETBUFFER 1
+#define HAVE_SETVBUF 1
+#define HAVE_SIGACTION 1
+#define HAVE_SIGVEC 1
+#define HAVE_SIZECHANGE 1
+#define HAVE_STRDUP 1
+#define HAVE_STRSTR 1
+#define HAVE_SYMLINK 1
+#define HAVE_SYS_IOCTL_H 1
+#define HAVE_SYS_PARAM_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_SYS_TIMES_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_TIME_SELECT 1
+#define HAVE_TCGETATTR 1
+#define HAVE_TCGETPGRP 1
+#define HAVE_TERMIOS_H 1
+#define HAVE_TIMES 1
+#define HAVE_TTYENT_H 1
+#define HAVE_TYPEINFO 1
+#define HAVE_UNISTD_H 1
+#define HAVE_USLEEP 1
+#define HAVE_VSNPRINTF 1
+#define HAVE_VSSCANF 1
+#define NCURSES_EXT_FUNCS 1
+#define NCURSES_NO_PADDING 1
+#define NDEBUG 1
+#define RETSIGTYPE void
+#define STDC_HEADERS 1
+#define SYSTEM_NAME "FreeBSD"
+#define TERMINFO_DIRS "/usr/share/misc/terminfo"
+#define TYPEOF_CHTYPE long
+#define USE_DATABASE 1
+#define USE_GETCAP 1
+#define USE_HASHMAP 1
+#define USE_SIGWINCH 1
+
+ /* The C compiler may not treat these properly but C++ has to */
+#ifdef __cplusplus
+#undef const
+#undef inline
+#else
+#if defined(lint) || defined(TRACE)
+#undef inline
+#define inline /* nothing */
+#endif
+#endif
+
+#endif /* NC_CONFIG_H */
diff --git a/lib/ncurses/ncurses/pathnames.h b/lib/ncurses/ncurses/pathnames.h
new file mode 100644
index 0000000..5cac36f
--- /dev/null
+++ b/lib/ncurses/ncurses/pathnames.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 6/4/93
+ * $FreeBSD$
+ */
+
+#define _PATH_DEF ".termcap /usr/share/misc/termcap"
+#define _PATH_DEF_SEC "/usr/share/misc/termcap"
diff --git a/lib/ncurses/ncurses/termcap.c b/lib/ncurses/ncurses/termcap.c
new file mode 100644
index 0000000..9469bea
--- /dev/null
+++ b/lib/ncurses/ncurses/termcap.c
@@ -0,0 +1,265 @@
+/* A portion of this file is from ncurses: */
+/***************************************************************************
+* COPYRIGHT NOTICE *
+****************************************************************************
+* ncurses is copyright (C) 1992-1995 *
+* Zeyd M. Ben-Halim *
+* zmbenhal@netcom.com *
+* Eric S. Raymond *
+* esr@snark.thyrsus.com *
+* *
+* Permission is hereby granted to reproduce and distribute ncurses *
+* by any means and for any fee, whether alone or as part of a *
+* larger distribution, in source or in binary form, PROVIDED *
+* this notice is included with any such distribution, and is not *
+* removed from any of its header files. Mention of ncurses in any *
+* applications linked with it is highly appreciated. *
+* *
+* ncurses comes AS IS with no warranty, implied or expressed. *
+* *
+***************************************************************************/
+
+#include <curses.priv.h>
+
+#include <string.h>
+#include <term.h>
+#include <tic.h>
+#include <term_entry.h>
+
+/* The rest is from BSD */
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char sccsid[] = "@(#)termcap.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include "pathnames.h"
+
+#define PBUFSIZ MAXPATHLEN /* max length of filename path */
+#define PVECSIZ 32 /* max number of names in path */
+#define TBUFSIZ 1024 /* max length of _nc_tgetent buffer */
+
+char _nc_termcap[TBUFSIZ + 1]; /* Last getcap, provided to tgetent() emul */
+
+/*
+ * termcap - routines for dealing with the terminal capability data base
+ *
+ * BUG: Should use a "last" pointer in tbuf, so that searching
+ * for capabilities alphabetically would not be a n**2/2
+ * process when large numbers of capabilities are given.
+ * Note: If we add a last pointer now we will screw up the
+ * tc capability. We really should compile termcap.
+ *
+ * Essentially all the work here is scanning and decoding escapes
+ * in string capabilities. We don't use stdio because the editor
+ * doesn't, and because living w/o it is not hard.
+ */
+
+/*
+ * Get an entry for terminal name in buffer _nc_termcap from the termcap
+ * file.
+ */
+int
+_nc_read_termcap_entry(const char *const name, TERMTYPE *const tp)
+{
+ ENTRY *ep;
+ register char *p;
+ register char *cp;
+ char *dummy;
+ char **fname;
+ char *home;
+ int i;
+ char pathbuf[PBUFSIZ]; /* holds raw path of filenames */
+ char *pathvec[PVECSIZ]; /* to point to names in pathbuf */
+ char **pvec; /* holds usable tail of path vector */
+ char *termpath;
+
+ _nc_termcap[0] = '\0'; /* in case */
+ dummy = NULL;
+ fname = pathvec;
+ pvec = pathvec;
+ p = pathbuf;
+ cp = getenv("TERMCAP");
+ /*
+ * TERMCAP can have one of two things in it. It can be the
+ * name of a file to use instead of /etc/termcap. In this
+ * case it better start with a "/". Or it can be an entry to
+ * use so we don't have to read the file. In this case it
+ * has to already have the newlines crunched out. If TERMCAP
+ * does not hold a file name then a path of names is searched
+ * instead. The path is found in the TERMPATH variable, or
+ * becomes "$HOME/.termcap /etc/termcap" if no TERMPATH exists.
+ */
+ if (!cp || *cp != '/') { /* no TERMCAP or it holds an entry */
+ if ( (termpath = getenv("TERMPATH")) )
+ strncpy(pathbuf, termpath, PBUFSIZ);
+ else {
+ if ( (home = getenv("HOME")) ) {/* set up default */
+ strncpy(pathbuf, home, PBUFSIZ - 1); /* $HOME first */
+ pathbuf[PBUFSIZ - 2] = '\0'; /* -2 because we add a slash */
+ p += strlen(pathbuf); /* path, looking in */
+ *p++ = '/';
+ } /* if no $HOME look in current directory */
+ strncpy(p, _PATH_DEF, PBUFSIZ - (p - pathbuf));
+ }
+ }
+ else /* user-defined name in TERMCAP */
+ strncpy(pathbuf, cp, PBUFSIZ); /* still can be tokenized */
+
+ /* For safety */
+ if (issetugid())
+ strcpy(pathbuf, _PATH_DEF_SEC);
+
+ pathbuf[PBUFSIZ - 1] = '\0';
+
+ *fname++ = pathbuf; /* tokenize path into vector of names */
+ while (*++p)
+ if (*p == ' ' || *p == ':') {
+ *p = '\0';
+ while (*++p)
+ if (*p != ' ' && *p != ':')
+ break;
+ if (*p == '\0')
+ break;
+ *fname++ = p;
+ if (fname >= pathvec + PVECSIZ) {
+ fname--;
+ break;
+ }
+ }
+ *fname = (char *) 0; /* mark end of vector */
+ if (cp && *cp && *cp != '/')
+ if (cgetset(cp) < 0)
+ return(-2);
+
+ i = cgetent(&dummy, pathvec, (char *)name);
+
+ if (i == 0) {
+ char *pd, *ps, *tok, *s, *tcs;
+ size_t len;
+
+ pd = _nc_termcap;
+ ps = dummy;
+ if ((tok = strchr(ps, ':')) == NULL) {
+ len = strlen(ps);
+ if (len >= TBUFSIZ)
+ i = -1;
+ else
+ strcpy(pd, ps);
+ goto done;
+ }
+ len = tok - ps + 1;
+ if (pd + len + 1 - _nc_termcap >= TBUFSIZ) {
+ i = -1;
+ goto done;
+ }
+ memcpy(pd, ps, len);
+ ps += len;
+ pd += len;
+ *pd = '\0';
+ tcs = pd - 1;
+ for (;;) {
+ while ((tok = strsep(&ps, ":")) != NULL &&
+ (*tok == '\0' || *tok == '\\' || !isgraph(*tok)))
+ ;
+ if (tok == NULL)
+ break;
+ for (s = tcs; s != NULL && s[1] != '\0';
+ s = strchr(s, ':')) {
+ s++;
+ if (s[0] == tok[0] && s[1] == tok[1])
+ goto skip_it;
+ }
+ len = strlen(tok);
+ if (pd + len + 1 - _nc_termcap >= TBUFSIZ) {
+ i = -1;
+ break;
+ }
+ memcpy(pd, tok, len);
+ pd += len;
+ *pd++ = ':';
+ *pd = '\0';
+ skip_it: ;
+ }
+ }
+done:
+ if (dummy)
+ free(dummy);
+
+
+/*
+ * From here on is ncurses-specific glue code
+ */
+
+ if (i < 0)
+ return(ERR);
+
+ _nc_set_source("TERMCAP");
+ _nc_read_entry_source((FILE *)NULL, _nc_termcap, FALSE, TRUE, NULLHOOK);
+
+ if (_nc_head == (ENTRY *)NULL)
+ return(ERR);
+
+ /* resolve all use references */
+ _nc_resolve_uses();
+
+ for_entry_list(ep)
+ if (_nc_name_match(ep->tterm.term_names, name, "|:"))
+ {
+ /*
+ * Make a local copy of the terminal capabilities. free
+ * all entry storage except the string table for the
+ * loaded type (which we disconnected from the list by
+ * NULLing out ep->tterm.str_table above).
+ */
+ memcpy(tp, &ep->tterm, sizeof(TERMTYPE));
+ ep->tterm.str_table = (char *)NULL;
+ _nc_free_entries(_nc_head);
+ _nc_head = _nc_tail = NULL; /* do not reuse! */
+
+ return 1; /* OK */
+ }
+
+ _nc_free_entries(_nc_head);
+ _nc_head = _nc_tail = NULL; /* do not reuse! */
+ return(0); /* not found */
+}
diff --git a/lib/ncurses/panel/Makefile b/lib/ncurses/panel/Makefile
new file mode 100644
index 0000000..f878817
--- /dev/null
+++ b/lib/ncurses/panel/Makefile
@@ -0,0 +1,19 @@
+# Makefile for libpanel
+# $FreeBSD$
+
+NCURSES=${.CURDIR}/../../contrib/ncurses
+
+.PATH: ${NCURSES}/panel
+
+LIB= panel
+
+SRCS= panel.c
+
+CFLAGS+= -I${.CURDIR}/../libncurses -I${NCURSES}/panel -I${NCURSES}/include \
+ -Wall -DNDEBUG -DHAVE_CONFIG_H
+
+beforeinstall:
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${NCURSES}/panel/panel.h ${DESTDIR}/usr/include
+
+.include <bsd.lib.mk>
OpenPOWER on IntegriCloud